summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev
diff options
context:
space:
mode:
authorJayant Shekhar <jshekhar@codeaurora.org>2014-04-23 20:27:16 +0530
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:29:23 -0700
commitd7e1e5c8c0836e516f6e87b3549bab83cec34f2f (patch)
treea1d830a5f21be8034734c6b477d5915348570140 /drivers/video/fbdev
parent206478bf63ddec5a5568b45a85f0912f90066141 (diff)
msm: mdss: Add support for VBIF QoS remapper
Each MDP source pipe can generate 4 levels of priority and those priorities are remapped before reaching the AXI bus. These re-mapper settings depends on the chip-set and the nature of the control path source pipe is used in. Ex. re-mapper value for DMA pipe used in DSI, real-time control path, will be different than DMA pipe used in rotator, non-real-time control path. Provide support to implement this configuration. Change-Id: I254f76dd47e3c41adde9894a23232e2f83e6b79c Signed-off-by: Jayant Shekhar <jshekhar@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
-rw-r--r--drivers/video/fbdev/msm/mdss.h3
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c53
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_hwio.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pipe.c35
4 files changed, 93 insertions, 0 deletions
diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h
index 33585536d283..f91cb6b62a53 100644
--- a/drivers/video/fbdev/msm/mdss.h
+++ b/drivers/video/fbdev/msm/mdss.h
@@ -153,6 +153,9 @@ struct mdss_data_type {
u32 max_bw_low;
u32 max_bw_high;
u32 max_bw_per_pipe;
+ u32 *vbif_rt_qos;
+ u32 *vbif_nrt_qos;
+ u32 npriority_lvl;
struct mdss_fudge_factor ab_factor;
struct mdss_fudge_factor ib_factor;
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c
index 5d59fb2edf3d..faad4d05b397 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp.c
@@ -2279,6 +2279,57 @@ static int mdss_mdp_parse_dt_prefill(struct platform_device *pdev)
return 0;
}
+static void mdss_mdp_parse_vbif_qos(struct platform_device *pdev)
+{
+ struct mdss_data_type *mdata = platform_get_drvdata(pdev);
+ int rc;
+
+ mdata->npriority_lvl = mdss_mdp_parse_dt_prop_len(pdev,
+ "qcom,mdss-vbif-qos-rt-setting");
+ if (mdata->npriority_lvl == MDSS_VBIF_QOS_REMAP_ENTRIES) {
+ mdata->vbif_rt_qos = kzalloc(sizeof(u32) *
+ mdata->npriority_lvl, GFP_KERNEL);
+ if (!mdata->vbif_rt_qos) {
+ pr_err("no memory for real time qos_priority\n");
+ return;
+ }
+
+ rc = mdss_mdp_parse_dt_handler(pdev,
+ "qcom,mdss-vbif-qos-rt-setting",
+ mdata->vbif_rt_qos, mdata->npriority_lvl);
+ if (rc) {
+ pr_debug("rt setting not found\n");
+ return;
+ }
+ } else {
+ mdata->npriority_lvl = 0;
+ pr_debug("Invalid or no vbif qos rt setting\n");
+ return;
+ }
+
+ mdata->npriority_lvl = mdss_mdp_parse_dt_prop_len(pdev,
+ "qcom,mdss-vbif-qos-nrt-setting");
+ if (mdata->npriority_lvl == MDSS_VBIF_QOS_REMAP_ENTRIES) {
+ mdata->vbif_nrt_qos = kzalloc(sizeof(u32) *
+ mdata->npriority_lvl, GFP_KERNEL);
+ if (!mdata->vbif_nrt_qos) {
+ pr_err("no memory for non real time qos_priority\n");
+ return;
+ }
+
+ rc = mdss_mdp_parse_dt_handler(pdev,
+ "qcom,mdss-vbif-qos-nrt-setting", mdata->vbif_nrt_qos,
+ mdata->npriority_lvl);
+ if (rc) {
+ pr_debug("nrt setting not found\n");
+ return;
+ }
+ } else {
+ mdata->npriority_lvl = 0;
+ pr_debug("Invalid or no vbif qos nrt seting\n");
+ }
+}
+
static int mdss_mdp_parse_dt_misc(struct platform_device *pdev)
{
struct mdss_data_type *mdata = platform_get_drvdata(pdev);
@@ -2398,6 +2449,8 @@ static int mdss_mdp_parse_dt_misc(struct platform_device *pdev)
pr_debug("clock levels not found\n");
}
+ mdss_mdp_parse_vbif_qos(pdev);
+
return 0;
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_hwio.h b/drivers/video/fbdev/msm/mdss_mdp_hwio.h
index b4e4b0870efa..3deeeb8d62ae 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_hwio.h
+++ b/drivers/video/fbdev/msm/mdss_mdp_hwio.h
@@ -605,4 +605,6 @@ enum mdss_mdp_pingpong_index {
#define MMSS_VBIF_AXI_HALT_CTRL0 0x208
#define MMSS_VBIF_AXI_HALT_CTRL1 0x20C
+#define MDSS_VBIF_QOS_REMAP_BASE 0x020
+#define MDSS_VBIF_QOS_REMAP_ENTRIES 0x4
#endif
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
index d57d03cd00c9..f899c7f558bb 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
@@ -515,6 +515,37 @@ int mdss_mdp_pipe_map(struct mdss_mdp_pipe *pipe)
return 0;
}
+/**
+ * mdss_mdp_qos_vbif_remapper_setup - Program the VBIF QoS remapper
+ * registers based on real or non real time clients
+ * @mdata: Pointer to the global mdss data structure.
+ * @pipe: Pointer to source pipe struct to get xin id's.
+ * @is_realtime: To determine if pipe's client is real or
+ * non real time.
+ */
+static void mdss_mdp_qos_vbif_remapper_setup(struct mdss_data_type *mdata,
+ struct mdss_mdp_pipe *pipe, bool is_realtime)
+{
+ u32 mask, reg_val, i, vbif_qos;
+
+ if (mdata->npriority_lvl == 0)
+ return;
+
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+ for (i = 0; i < mdata->npriority_lvl; i++) {
+ reg_val = readl_relaxed(mdata->vbif_base +
+ MDSS_VBIF_QOS_REMAP_BASE + i*4);
+ mask = 0x3 << (pipe->xin_id * 2);
+ reg_val &= ~(mask);
+ vbif_qos = is_realtime ?
+ mdata->vbif_rt_qos[i] : mdata->vbif_nrt_qos[i];
+ reg_val |= vbif_qos << (pipe->xin_id * 2);
+ writel_relaxed(reg_val, mdata->vbif_base +
+ MDSS_VBIF_QOS_REMAP_BASE + i*4);
+ }
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+}
+
static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer,
u32 type, u32 off, struct mdss_mdp_pipe *left_blend_pipe)
{
@@ -523,6 +554,7 @@ static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer,
struct mdss_mdp_pipe *pipe_pool = NULL;
u32 npipes;
bool pipe_share = false;
+ bool is_realtime;
u32 i, reg_val, force_off_mask;
if (!mixer || !mixer->ctl || !mixer->ctl->mdata)
@@ -598,6 +630,9 @@ static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer,
mutex_init(&pipe->pp_res.hist.hist_mutex);
spin_lock_init(&pipe->pp_res.hist.hist_lock);
kref_init(&pipe->kref);
+ is_realtime = !((mixer->ctl->intf_num == MDSS_MDP_NO_INTF)
+ || mixer->rotator_mode);
+ mdss_mdp_qos_vbif_remapper_setup(mdata, pipe, is_realtime);
} else if (pipe_share) {
/*
* when there is no dedicated wfd blk, DMA pipe can be