summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDhaval Patel <pdhaval@quicinc.com>2016-10-25 21:13:19 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-10-25 21:13:19 -0700
commit46deae1c0c4d857b747c8de8fbf52d31d2728111 (patch)
tree39d17046cf92c094a4c3920c79798b5d2d280f7a
parent232de097d2bf16bbe3e402bb1cc96a02d2aff4b6 (diff)
parent3e418c7ba48ccb1f4be79216ceb7dd009d44ea65 (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.txt26
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_catalog.c158
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_catalog.h2
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;
};
/**