diff options
| author | Alan Kwong <akwong@codeaurora.org> | 2016-10-12 00:27:07 -0400 |
|---|---|---|
| committer | Alan Kwong <akwong@codeaurora.org> | 2016-10-24 19:38:27 -0400 |
| commit | 3e418c7ba48ccb1f4be79216ceb7dd009d44ea65 (patch) | |
| tree | aeb9a9d7d8e587becbf2805afdbbc70e05d22ec6 /drivers/gpu | |
| parent | 8e3226a2fa93a42eac91227c0f95ff5f55b1cfc3 (diff) | |
drm/msm/sde: add vbif parsing to hardware catalog
Add vbif parsing to hardware catalog. Default and dynamic
OT limits are defined for each vbif block.
Change-Id: I12336c2f390b5acd2aeec691e1176d814b1cb768
Signed-off-by: Alan Kwong <akwong@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
| -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 |
2 files changed, 159 insertions, 1 deletions
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; }; /** |
