diff options
| author | Jayant Shekhar <jshekhar@codeaurora.org> | 2014-04-23 20:27:16 +0530 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:29:23 -0700 |
| commit | d7e1e5c8c0836e516f6e87b3549bab83cec34f2f (patch) | |
| tree | a1d830a5f21be8034734c6b477d5915348570140 /drivers/video/fbdev | |
| parent | 206478bf63ddec5a5568b45a85f0912f90066141 (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.h | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.c | 53 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_hwio.h | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pipe.c | 35 |
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 |
