diff options
| author | Dhaval Patel <pdhaval@quicinc.com> | 2016-10-25 21:13:19 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-10-25 21:13:19 -0700 |
| commit | 46deae1c0c4d857b747c8de8fbf52d31d2728111 (patch) | |
| tree | 39d17046cf92c094a4c3920c79798b5d2d280f7a | |
| parent | 232de097d2bf16bbe3e402bb1cc96a02d2aff4b6 (diff) | |
| parent | 3e418c7ba48ccb1f4be79216ceb7dd009d44ea65 (diff) | |
Merge "drm/msm/sde: add vbif parsing to hardware catalog" into dev/msm-4.4-drm_kms
| -rw-r--r-- | Documentation/devicetree/bindings/display/msm/sde.txt | 26 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_catalog.c | 158 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_catalog.h | 2 |
3 files changed, 184 insertions, 2 deletions
diff --git a/Documentation/devicetree/bindings/display/msm/sde.txt b/Documentation/devicetree/bindings/display/msm/sde.txt index 141d79222f67..3854f0e1ce5c 100644 --- a/Documentation/devicetree/bindings/display/msm/sde.txt +++ b/Documentation/devicetree/bindings/display/msm/sde.txt @@ -159,6 +159,10 @@ Optional properties: - qcom,sde-cdm-off: Array of offset addresses for the available cdm blocks. These offsets will be calculated from register "mdp_phys" defined in reg property. +- qcom,sde-vbif-off: Array of offset addresses for the available + vbif blocks. These offsets will be calculated from + register "vbif_phys" defined in reg property. +- qcom,sde-vbif-size: A u32 value indicates the vbif block address range. - qcom,sde-te-off: A u32 offset indicates the te block offset on pingpong. This offset is 0x0 by default. - qcom,sde-te2-off: A u32 offset indicates the te2 block offset on pingpong. @@ -173,7 +177,18 @@ Optional properties: - qcom,sde-dspp-dither-off: A u32 offset indicates the dither block offset on dssp. - qcom,sde-dspp-hist-off: A u32 offset indicates the hist block offset on dssp. - qcom,sde-dspp-ad-off: A u32 offset indicates the ad block offset on dssp. - +- qcom,sde-vbif-id: Array of vbif ids corresponding to the + offsets defined in property: qcom,sde-vbif-off. +- qcom,sde-vbif-default-ot-rd-limit: A u32 value indicates the default read OT limit +- qcom,sde-vbif-default-ot-wr-limit: A u32 value indicates the default write OT limit +- qcom,sde-vbif-dynamic-ot-rd-limit: A series of 2 cell property, with a format + of (pps, OT limit), where pps is pixel per second and + OT limit is the read limit to apply if the given + pps is not exceeded. +- qcom,sde-vbif-dynamic-ot-wr-limit: A series of 2 cell property, with a format + of (pps, OT limit), where pps is pixel per second and + OT limit is the write limit to apply if the given + pps is not exceeded. - qcom,sde-wb-id: Array of writeback ids corresponding to the offsets defined in property: qcom,sde-wb-off. Bus Scaling Data: @@ -318,6 +333,15 @@ Example: qcom,sde-wb-id = <2>; + qcom,sde-vbif-off = <0 0>; + qcom,sde-vbif-id = <0 1>; + qcom,sde-vbif-default-ot-rd-limit = <32>; + qcom,sde-vbif-default-ot-wr-limit = <16>; + qcom,sde-vbif-dynamic-ot-rd-limit = <62208000 2>, + <124416000 4>, <248832000 16>; + qcom,sde-vbif-dynamic-ot-wr-limit = <62208000 2>, + <124416000 4>, <248832000 16>; + qcom,platform-supply-entries { #address-cells = <1>; #size-cells = <0>; diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c index ec7c02b2ec6d..f438a2e591df 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c @@ -68,6 +68,9 @@ #define LINE_LM_OFFSET 5 #define LINE_MODE_WB_OFFSET 2 +/* maximum XIN halt timeout in usec */ +#define VBIF_XIN_HALT_TIMEOUT 0x4000 + /************************************************************* * DTSI PROPERTY INDEX *************************************************************/ @@ -149,6 +152,16 @@ enum { WB_XIN_ID, }; +enum { + VBIF_OFF, + VBIF_LEN, + VBIF_ID, + VBIF_DEFAULT_OT_RD_LIMIT, + VBIF_DEFAULT_OT_WR_LIMIT, + VBIF_DYNAMIC_OT_RD_LIMIT, + VBIF_DYNAMIC_OT_WR_LIMIT, +}; + /************************************************************* * dts property definition *************************************************************/ @@ -264,6 +277,20 @@ static struct sde_prop_type wb_prop[] = { {WB_XIN_ID, "qcom,sde-wb-xin-id", false, PROP_TYPE_U32_ARRAY}, }; +static struct sde_prop_type vbif_prop[] = { + {VBIF_OFF, "qcom,sde-vbif-off", true, PROP_TYPE_U32_ARRAY}, + {VBIF_LEN, "qcom,sde-vbif-size", false, PROP_TYPE_U32}, + {VBIF_ID, "qcom,sde-vbif-id", false, PROP_TYPE_U32_ARRAY}, + {VBIF_DEFAULT_OT_RD_LIMIT, "qcom,sde-vbif-default-ot-rd-limit", false, + PROP_TYPE_U32}, + {VBIF_DEFAULT_OT_WR_LIMIT, "qcom,sde-vbif-default-ot-wr-limit", false, + PROP_TYPE_U32}, + {VBIF_DYNAMIC_OT_RD_LIMIT, "qcom,sde-vbif-dynamic-ot-rd-limit", false, + PROP_TYPE_U32_ARRAY}, + {VBIF_DYNAMIC_OT_WR_LIMIT, "qcom,sde-vbif-dynamic-ot-wr-limit", false, + PROP_TYPE_U32_ARRAY}, +}; + /************************************************************* * static API list *************************************************************/ @@ -975,6 +1002,128 @@ end: return rc; } +static int sde_vbif_parse_dt(struct device_node *np, + struct sde_mdss_cfg *sde_cfg) +{ + int rc, prop_count[MAX_BLOCKS], i, j, k; + u32 prop_value[MAX_BLOCKS][MAX_SDE_HW_BLK] = { { 0 } }; + u32 bit_value[MAX_BLOCKS][MAX_SDE_HW_BLK][MAX_BIT_OFFSET] + = { { { 0 } } }; + u32 off_count, vbif_len, rd_len = 0, wr_len = 0; + struct sde_vbif_cfg *vbif; + + if (!sde_cfg) { + SDE_ERROR("invalid argument\n"); + rc = -EINVAL; + goto end; + } + + rc = _validate_dt_entry(np, vbif_prop, ARRAY_SIZE(vbif_prop), + prop_count, &off_count); + if (rc) + goto end; + + rc = _validate_dt_entry(np, &vbif_prop[VBIF_DYNAMIC_OT_RD_LIMIT], 1, + &prop_count[VBIF_DYNAMIC_OT_RD_LIMIT], &rd_len); + if (rc) + goto end; + + rc = _validate_dt_entry(np, &vbif_prop[VBIF_DYNAMIC_OT_WR_LIMIT], 1, + &prop_count[VBIF_DYNAMIC_OT_WR_LIMIT], &wr_len); + if (rc) + goto end; + + sde_cfg->vbif_count = off_count; + + rc = _read_dt_entry(np, vbif_prop, ARRAY_SIZE(vbif_prop), prop_count, + prop_value, bit_value); + if (rc) + goto end; + + vbif_len = prop_value[VBIF_LEN][0]; + if (!vbif_len) + vbif_len = DEFAULT_SDE_HW_BLOCK_LEN; + + for (i = 0; i < off_count; i++) { + vbif = sde_cfg->vbif + i; + vbif->base = prop_value[VBIF_OFF][i]; + vbif->len = vbif_len; + vbif->id = VBIF_0 + prop_value[VBIF_ID][i]; + + SDE_DEBUG("vbif:%d\n", vbif->id - VBIF_0); + + vbif->xin_halt_timeout = VBIF_XIN_HALT_TIMEOUT; + + vbif->default_ot_rd_limit = + prop_value[VBIF_DEFAULT_OT_RD_LIMIT][0]; + SDE_DEBUG("default_ot_rd_limit=%u\n", + vbif->default_ot_rd_limit); + + vbif->default_ot_wr_limit = + prop_value[VBIF_DEFAULT_OT_WR_LIMIT][0]; + SDE_DEBUG("default_ot_wr_limit=%u\n", + vbif->default_ot_wr_limit); + + vbif->dynamic_ot_rd_tbl.count = + prop_count[VBIF_DYNAMIC_OT_RD_LIMIT] / 2; + SDE_DEBUG("dynamic_ot_rd_tbl.count=%u\n", + vbif->dynamic_ot_rd_tbl.count); + if (vbif->dynamic_ot_rd_tbl.count) { + vbif->dynamic_ot_rd_tbl.cfg = kcalloc( + vbif->dynamic_ot_rd_tbl.count, + sizeof(struct sde_vbif_dynamic_ot_cfg), + GFP_KERNEL); + if (!vbif->dynamic_ot_rd_tbl.cfg) { + rc = -ENOMEM; + goto end; + } + } + + for (j = 0, k = 0; j < vbif->dynamic_ot_rd_tbl.count; j++) { + vbif->dynamic_ot_rd_tbl.cfg[j].pps = (u64) + prop_value[VBIF_DYNAMIC_OT_RD_LIMIT][k++]; + vbif->dynamic_ot_rd_tbl.cfg[j].ot_limit = + prop_value[VBIF_DYNAMIC_OT_RD_LIMIT][k++]; + SDE_DEBUG("dynamic_ot_rd_tbl[%d].cfg=<%llu %u>\n", j, + vbif->dynamic_ot_rd_tbl.cfg[j].pps, + vbif->dynamic_ot_rd_tbl.cfg[j].ot_limit); + } + + vbif->dynamic_ot_wr_tbl.count = + prop_count[VBIF_DYNAMIC_OT_WR_LIMIT] / 2; + SDE_DEBUG("dynamic_ot_wr_tbl.count=%u\n", + vbif->dynamic_ot_wr_tbl.count); + if (vbif->dynamic_ot_wr_tbl.count) { + vbif->dynamic_ot_wr_tbl.cfg = kcalloc( + vbif->dynamic_ot_wr_tbl.count, + sizeof(struct sde_vbif_dynamic_ot_cfg), + GFP_KERNEL); + if (!vbif->dynamic_ot_wr_tbl.cfg) { + rc = -ENOMEM; + goto end; + } + } + + for (j = 0, k = 0; j < vbif->dynamic_ot_wr_tbl.count; j++) { + vbif->dynamic_ot_wr_tbl.cfg[j].pps = (u64) + prop_value[VBIF_DYNAMIC_OT_WR_LIMIT][k++]; + vbif->dynamic_ot_wr_tbl.cfg[j].ot_limit = + prop_value[VBIF_DYNAMIC_OT_WR_LIMIT][k++]; + SDE_DEBUG("dynamic_ot_wr_tbl[%d].cfg=<%llu %u>\n", j, + vbif->dynamic_ot_wr_tbl.cfg[j].pps, + vbif->dynamic_ot_wr_tbl.cfg[j].ot_limit); + } + + if (vbif->default_ot_rd_limit || vbif->default_ot_wr_limit || + vbif->dynamic_ot_rd_tbl.count || + vbif->dynamic_ot_wr_tbl.count) + set_bit(SDE_VBIF_QOS_OTLIM, &vbif->features); + } + +end: + return rc; +} + static int sde_pp_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) { int rc, prop_count[MAX_BLOCKS], i; @@ -1141,6 +1290,11 @@ static void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg) for (i = 0; i < sde_cfg->pingpong_count; i++) kfree(sde_cfg->pingpong[i].sblk); + + for (i = 0; i < sde_cfg->vbif_count; i++) { + kfree(sde_cfg->vbif[i].dynamic_ot_rd_tbl.cfg); + kfree(sde_cfg->vbif[i].dynamic_ot_wr_tbl.cfg); + } } /************************************************************* @@ -1196,6 +1350,10 @@ struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev, u32 hw_rev) if (rc) goto end; + rc = sde_vbif_parse_dt(np, sde_cfg); + if (rc) + goto end; + sde_hardware_caps(sde_cfg, hw_rev); return sde_cfg; diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h index 6e0a52d2bb71..ee09798b5e57 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h @@ -567,7 +567,7 @@ struct sde_vbif_dynamic_ot_cfg { */ struct sde_vbif_dynamic_ot_tbl { u32 count; - const struct sde_vbif_dynamic_ot_cfg *cfg; + struct sde_vbif_dynamic_ot_cfg *cfg; }; /** |
