Loading Documentation/devicetree/bindings/display/msm/sde.txt +16 −0 Original line number Diff line number Diff line Loading @@ -322,6 +322,19 @@ Optional properties: - qcom,sde-cdp-setting: Array of 2 cell property, with a format of <read enable, write enable> for cdp use cases in order of <real_time>, and <non_real_time>. - qcom,sde-inline-rot-xin: An integer array of xin-ids related to inline rotation. - qcom,sde-inline-rot-xin-type: A string array indicating the type of xin, namely sspp or wb. Number of entries should match the number of xin-ids defined in property: qcom,sde-inline-rot-xin - qcom,sde-inline-rot-clk-ctrl: Array of offsets describing clk control offsets for dynamic clock gating. 1st value in the array represents offset of the control register. 2nd value represents bit offset within control register. Number of offsets defined should match the number of xin-ids defined in property: qcom,sde-inline-rot-xin Bus Scaling Subnodes: - qcom,sde-reg-bus: Property to provide Bus scaling for register access for Loading Loading @@ -593,6 +606,9 @@ Example: }; qcom,sde-inline-rotator = <&mdss_rotator 0>; qcom,sde-inline-rot-xin = <10 11>; qcom,sde-inline-rot-xin-type = "sspp", "wb"; qcom,sde-inline-rot-clk-ctrl = <0x2bc 0x8>, <0x2bc 0xc>; qcom,platform-supply-entries { #address-cells = <1>; Loading arch/arm64/boot/dts/qcom/sdm845-sde.dtsi +7 −0 Original line number Diff line number Diff line Loading @@ -168,7 +168,14 @@ qcom,sde-qos-lut-cwb = <0 0x75300000 0x00000000>; qcom,sde-cdp-setting = <1 1>, <1 0>; qcom,sde-inline-rotator = <&mdss_rotator 0>; qcom,sde-inline-rot-xin = <10 11>; qcom,sde-inline-rot-xin-type = "sspp", "wb"; /* offsets are relative to "mdp_phys + qcom,sde-off */ qcom,sde-inline-rot-clk-ctrl = <0x2bc 0x8>, <0x2bc 0xc>; qcom,sde-reg-dma-off = <0>; qcom,sde-reg-dma-version = <0x1>; Loading drivers/gpu/drm/msm/sde/sde_hw_catalog.c +99 −1 Original line number Diff line number Diff line Loading @@ -302,6 +302,13 @@ enum { REG_DMA_PROP_MAX }; enum { INLINE_ROT_XIN, INLINE_ROT_XIN_TYPE, INLINE_ROT_CLK_CTRL, INLINE_ROT_PROP_MAX }; /************************************************************* * dts property definition *************************************************************/ Loading Loading @@ -546,6 +553,15 @@ static struct sde_prop_type reg_dma_prop[REG_DMA_PROP_MAX] = { PROP_TYPE_U32}, }; static struct sde_prop_type inline_rot_prop[INLINE_ROT_PROP_MAX] = { {INLINE_ROT_XIN, "qcom,sde-inline-rot-xin", false, PROP_TYPE_U32_ARRAY}, {INLINE_ROT_XIN_TYPE, "qcom,sde-inline-rot-xin-type", false, PROP_TYPE_STRING_ARRAY}, {INLINE_ROT_CLK_CTRL, "qcom,sde-inline-rot-clk-ctrl", false, PROP_TYPE_BIT_OFFSET_ARRAY}, }; /************************************************************* * static API list *************************************************************/ Loading Loading @@ -1650,6 +1666,87 @@ static void _sde_dspp_setup_blocks(struct sde_mdss_cfg *sde_cfg, } } static void _sde_inline_rot_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg, struct sde_rot_cfg *rot) { int rc, prop_count[INLINE_ROT_PROP_MAX], i, j, index; struct sde_prop_value *prop_value = NULL; bool prop_exists[INLINE_ROT_PROP_MAX]; u32 off_count, sspp_count = 0, wb_count = 0; const char *type; prop_value = kzalloc(INLINE_ROT_PROP_MAX * sizeof(struct sde_prop_value), GFP_KERNEL); if (!prop_value) return; rc = _validate_dt_entry(np, inline_rot_prop, ARRAY_SIZE(inline_rot_prop), prop_count, &off_count); if (rc) goto end; rc = _read_dt_entry(np, inline_rot_prop, ARRAY_SIZE(inline_rot_prop), prop_count, prop_exists, prop_value); if (rc) goto end; for (i = 0; i < off_count; i++) { rot->vbif_cfg[i].xin_id = PROP_VALUE_ACCESS(prop_value, INLINE_ROT_XIN, i); of_property_read_string_index(np, inline_rot_prop[INLINE_ROT_XIN_TYPE].prop_name, i, &type); if (!strcmp(type, "sspp")) { rot->vbif_cfg[i].num = INLINE_ROT0_SSPP + sspp_count; rot->vbif_cfg[i].is_read = true; rot->vbif_cfg[i].clk_ctrl = SDE_CLK_CTRL_INLINE_ROT0_SSPP + sspp_count; sspp_count++; } else if (!strcmp(type, "wb")) { rot->vbif_cfg[i].num = INLINE_ROT0_WB + wb_count; rot->vbif_cfg[i].is_read = false; rot->vbif_cfg[i].clk_ctrl = SDE_CLK_CTRL_INLINE_ROT0_WB + wb_count; wb_count++; } else { SDE_ERROR("invalid rotator vbif type:%s\n", type); goto end; } index = rot->vbif_cfg[i].clk_ctrl; if (index < 0 || index >= SDE_CLK_CTRL_MAX) { SDE_ERROR("invalid clk_ctrl enum:%d\n", index); goto end; } for (j = 0; j < sde_cfg->mdp_count; j++) { sde_cfg->mdp[j].clk_ctrls[index].reg_off = PROP_BITVALUE_ACCESS(prop_value, INLINE_ROT_CLK_CTRL, i, 0); sde_cfg->mdp[j].clk_ctrls[index].bit_off = PROP_BITVALUE_ACCESS(prop_value, INLINE_ROT_CLK_CTRL, i, 1); } SDE_DEBUG("rot- xin:%d, num:%d, rd:%d, clk:%d:0x%x/%d\n", rot->vbif_cfg[i].xin_id, rot->vbif_cfg[i].num, rot->vbif_cfg[i].is_read, rot->vbif_cfg[i].clk_ctrl, sde_cfg->mdp[0].clk_ctrls[index].reg_off, sde_cfg->mdp[0].clk_ctrls[index].bit_off); } rot->vbif_idx = VBIF_RT; rot->xin_count = off_count; end: kfree(prop_value); } static int sde_rot_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) { Loading Loading @@ -1695,10 +1792,11 @@ static int sde_rot_parse_dt(struct device_node *np, rot->slice_size = llcc_get_slice_size(slice); rot->pdev = pdev; llcc_slice_putd(slice); sde_cfg->rot_count++; SDE_DEBUG("rot:%d scid:%d slice_size:%zukb\n", rot->id, rot->scid, rot->slice_size); _sde_inline_rot_parse_dt(np, sde_cfg, rot); sde_cfg->rot_count++; } } else { rot->pdev = NULL; Loading drivers/gpu/drm/msm/sde/sde_hw_catalog.h +23 −0 Original line number Diff line number Diff line Loading @@ -488,6 +488,8 @@ enum sde_clk_ctrl_type { SDE_CLK_CTRL_WB0, SDE_CLK_CTRL_WB1, SDE_CLK_CTRL_WB2, SDE_CLK_CTRL_INLINE_ROT0_SSPP, SDE_CLK_CTRL_INLINE_ROT0_WB, SDE_CLK_CTRL_MAX, }; Loading Loading @@ -647,6 +649,20 @@ struct sde_wb_cfg { enum sde_clk_ctrl_type clk_ctrl; }; /** * struct sde_rot_vbif_cfg - inline rotator vbif configs * @xin_id xin client id * @num enum identifying this block * @is_read indicates read/write client * @clk_ctrl index to clk control */ struct sde_rot_vbif_cfg { u32 xin_id; u32 num; bool is_read; enum sde_clk_ctrl_type clk_ctrl; }; /** * struct sde_rot_cfg - information of rotator blocks * @id enum identifying this block Loading @@ -656,12 +672,19 @@ struct sde_wb_cfg { * @pdev private device handle * @scid subcache identifier * @slice_size subcache slice size * @vbif_idx vbif identifier * @xin_count number of xin clients * @vbif_cfg vbif settings related to rotator */ struct sde_rot_cfg { SDE_HW_BLK_INFO; void *pdev; int scid; size_t slice_size; u32 vbif_idx; u32 xin_count; struct sde_rot_vbif_cfg vbif_cfg[MAX_BLOCKS]; }; /** Loading drivers/gpu/drm/msm/sde/sde_hw_mdss.h +7 −0 Original line number Diff line number Diff line Loading @@ -283,6 +283,13 @@ enum sde_rot { ROT_MAX }; enum sde_inline_rot { INLINE_ROT_NONE, INLINE_ROT0_SSPP, INLINE_ROT0_WB, INLINE_ROT_MAX }; /** * SDE HW,Component order color map */ Loading Loading
Documentation/devicetree/bindings/display/msm/sde.txt +16 −0 Original line number Diff line number Diff line Loading @@ -322,6 +322,19 @@ Optional properties: - qcom,sde-cdp-setting: Array of 2 cell property, with a format of <read enable, write enable> for cdp use cases in order of <real_time>, and <non_real_time>. - qcom,sde-inline-rot-xin: An integer array of xin-ids related to inline rotation. - qcom,sde-inline-rot-xin-type: A string array indicating the type of xin, namely sspp or wb. Number of entries should match the number of xin-ids defined in property: qcom,sde-inline-rot-xin - qcom,sde-inline-rot-clk-ctrl: Array of offsets describing clk control offsets for dynamic clock gating. 1st value in the array represents offset of the control register. 2nd value represents bit offset within control register. Number of offsets defined should match the number of xin-ids defined in property: qcom,sde-inline-rot-xin Bus Scaling Subnodes: - qcom,sde-reg-bus: Property to provide Bus scaling for register access for Loading Loading @@ -593,6 +606,9 @@ Example: }; qcom,sde-inline-rotator = <&mdss_rotator 0>; qcom,sde-inline-rot-xin = <10 11>; qcom,sde-inline-rot-xin-type = "sspp", "wb"; qcom,sde-inline-rot-clk-ctrl = <0x2bc 0x8>, <0x2bc 0xc>; qcom,platform-supply-entries { #address-cells = <1>; Loading
arch/arm64/boot/dts/qcom/sdm845-sde.dtsi +7 −0 Original line number Diff line number Diff line Loading @@ -168,7 +168,14 @@ qcom,sde-qos-lut-cwb = <0 0x75300000 0x00000000>; qcom,sde-cdp-setting = <1 1>, <1 0>; qcom,sde-inline-rotator = <&mdss_rotator 0>; qcom,sde-inline-rot-xin = <10 11>; qcom,sde-inline-rot-xin-type = "sspp", "wb"; /* offsets are relative to "mdp_phys + qcom,sde-off */ qcom,sde-inline-rot-clk-ctrl = <0x2bc 0x8>, <0x2bc 0xc>; qcom,sde-reg-dma-off = <0>; qcom,sde-reg-dma-version = <0x1>; Loading
drivers/gpu/drm/msm/sde/sde_hw_catalog.c +99 −1 Original line number Diff line number Diff line Loading @@ -302,6 +302,13 @@ enum { REG_DMA_PROP_MAX }; enum { INLINE_ROT_XIN, INLINE_ROT_XIN_TYPE, INLINE_ROT_CLK_CTRL, INLINE_ROT_PROP_MAX }; /************************************************************* * dts property definition *************************************************************/ Loading Loading @@ -546,6 +553,15 @@ static struct sde_prop_type reg_dma_prop[REG_DMA_PROP_MAX] = { PROP_TYPE_U32}, }; static struct sde_prop_type inline_rot_prop[INLINE_ROT_PROP_MAX] = { {INLINE_ROT_XIN, "qcom,sde-inline-rot-xin", false, PROP_TYPE_U32_ARRAY}, {INLINE_ROT_XIN_TYPE, "qcom,sde-inline-rot-xin-type", false, PROP_TYPE_STRING_ARRAY}, {INLINE_ROT_CLK_CTRL, "qcom,sde-inline-rot-clk-ctrl", false, PROP_TYPE_BIT_OFFSET_ARRAY}, }; /************************************************************* * static API list *************************************************************/ Loading Loading @@ -1650,6 +1666,87 @@ static void _sde_dspp_setup_blocks(struct sde_mdss_cfg *sde_cfg, } } static void _sde_inline_rot_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg, struct sde_rot_cfg *rot) { int rc, prop_count[INLINE_ROT_PROP_MAX], i, j, index; struct sde_prop_value *prop_value = NULL; bool prop_exists[INLINE_ROT_PROP_MAX]; u32 off_count, sspp_count = 0, wb_count = 0; const char *type; prop_value = kzalloc(INLINE_ROT_PROP_MAX * sizeof(struct sde_prop_value), GFP_KERNEL); if (!prop_value) return; rc = _validate_dt_entry(np, inline_rot_prop, ARRAY_SIZE(inline_rot_prop), prop_count, &off_count); if (rc) goto end; rc = _read_dt_entry(np, inline_rot_prop, ARRAY_SIZE(inline_rot_prop), prop_count, prop_exists, prop_value); if (rc) goto end; for (i = 0; i < off_count; i++) { rot->vbif_cfg[i].xin_id = PROP_VALUE_ACCESS(prop_value, INLINE_ROT_XIN, i); of_property_read_string_index(np, inline_rot_prop[INLINE_ROT_XIN_TYPE].prop_name, i, &type); if (!strcmp(type, "sspp")) { rot->vbif_cfg[i].num = INLINE_ROT0_SSPP + sspp_count; rot->vbif_cfg[i].is_read = true; rot->vbif_cfg[i].clk_ctrl = SDE_CLK_CTRL_INLINE_ROT0_SSPP + sspp_count; sspp_count++; } else if (!strcmp(type, "wb")) { rot->vbif_cfg[i].num = INLINE_ROT0_WB + wb_count; rot->vbif_cfg[i].is_read = false; rot->vbif_cfg[i].clk_ctrl = SDE_CLK_CTRL_INLINE_ROT0_WB + wb_count; wb_count++; } else { SDE_ERROR("invalid rotator vbif type:%s\n", type); goto end; } index = rot->vbif_cfg[i].clk_ctrl; if (index < 0 || index >= SDE_CLK_CTRL_MAX) { SDE_ERROR("invalid clk_ctrl enum:%d\n", index); goto end; } for (j = 0; j < sde_cfg->mdp_count; j++) { sde_cfg->mdp[j].clk_ctrls[index].reg_off = PROP_BITVALUE_ACCESS(prop_value, INLINE_ROT_CLK_CTRL, i, 0); sde_cfg->mdp[j].clk_ctrls[index].bit_off = PROP_BITVALUE_ACCESS(prop_value, INLINE_ROT_CLK_CTRL, i, 1); } SDE_DEBUG("rot- xin:%d, num:%d, rd:%d, clk:%d:0x%x/%d\n", rot->vbif_cfg[i].xin_id, rot->vbif_cfg[i].num, rot->vbif_cfg[i].is_read, rot->vbif_cfg[i].clk_ctrl, sde_cfg->mdp[0].clk_ctrls[index].reg_off, sde_cfg->mdp[0].clk_ctrls[index].bit_off); } rot->vbif_idx = VBIF_RT; rot->xin_count = off_count; end: kfree(prop_value); } static int sde_rot_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) { Loading Loading @@ -1695,10 +1792,11 @@ static int sde_rot_parse_dt(struct device_node *np, rot->slice_size = llcc_get_slice_size(slice); rot->pdev = pdev; llcc_slice_putd(slice); sde_cfg->rot_count++; SDE_DEBUG("rot:%d scid:%d slice_size:%zukb\n", rot->id, rot->scid, rot->slice_size); _sde_inline_rot_parse_dt(np, sde_cfg, rot); sde_cfg->rot_count++; } } else { rot->pdev = NULL; Loading
drivers/gpu/drm/msm/sde/sde_hw_catalog.h +23 −0 Original line number Diff line number Diff line Loading @@ -488,6 +488,8 @@ enum sde_clk_ctrl_type { SDE_CLK_CTRL_WB0, SDE_CLK_CTRL_WB1, SDE_CLK_CTRL_WB2, SDE_CLK_CTRL_INLINE_ROT0_SSPP, SDE_CLK_CTRL_INLINE_ROT0_WB, SDE_CLK_CTRL_MAX, }; Loading Loading @@ -647,6 +649,20 @@ struct sde_wb_cfg { enum sde_clk_ctrl_type clk_ctrl; }; /** * struct sde_rot_vbif_cfg - inline rotator vbif configs * @xin_id xin client id * @num enum identifying this block * @is_read indicates read/write client * @clk_ctrl index to clk control */ struct sde_rot_vbif_cfg { u32 xin_id; u32 num; bool is_read; enum sde_clk_ctrl_type clk_ctrl; }; /** * struct sde_rot_cfg - information of rotator blocks * @id enum identifying this block Loading @@ -656,12 +672,19 @@ struct sde_wb_cfg { * @pdev private device handle * @scid subcache identifier * @slice_size subcache slice size * @vbif_idx vbif identifier * @xin_count number of xin clients * @vbif_cfg vbif settings related to rotator */ struct sde_rot_cfg { SDE_HW_BLK_INFO; void *pdev; int scid; size_t slice_size; u32 vbif_idx; u32 xin_count; struct sde_rot_vbif_cfg vbif_cfg[MAX_BLOCKS]; }; /** Loading
drivers/gpu/drm/msm/sde/sde_hw_mdss.h +7 −0 Original line number Diff line number Diff line Loading @@ -283,6 +283,13 @@ enum sde_rot { ROT_MAX }; enum sde_inline_rot { INLINE_ROT_NONE, INLINE_ROT0_SSPP, INLINE_ROT0_WB, INLINE_ROT_MAX }; /** * SDE HW,Component order color map */ Loading