diff options
| author | Adrian Salido-Moreno <adrianm@codeaurora.org> | 2013-02-07 01:54:14 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:14:36 -0700 |
| commit | 33d436fa13eeb151c22e130dbd64e42cb07b9e65 (patch) | |
| tree | c13474c6a8d00511c02d1dc2f9dc0fab6cd237ca /drivers/video/fbdev | |
| parent | 55eecf45c211ebfe197451d2019427e2f41f8ff9 (diff) | |
msm: mdss: program vbif and QoS settings from device tree
MDSS VBIF and QoS settings can differ across targets, move the setup of
these settings to device tree to allow different settings to be set
depending on specific targets.
Change-Id: Idf7dca0f19a3a694d3da3f2af662077bac445636
Signed-off-by: Adrian Salido-Moreno <adrianm@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
| -rw-r--r-- | drivers/video/fbdev/msm/mdss.h | 7 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.c | 93 |
2 files changed, 82 insertions, 18 deletions
diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h index e5e680cfd94b..64efa5b2b116 100644 --- a/drivers/video/fbdev/msm/mdss.h +++ b/drivers/video/fbdev/msm/mdss.h @@ -52,6 +52,11 @@ struct mdss_iommu_map_type { int domain_idx; }; +struct mdss_hw_settings { + char __iomem *reg; + u32 val; +}; + struct mdss_data_type { u32 rev; u32 mdp_rev; @@ -86,6 +91,8 @@ struct mdss_data_type { u32 smp_mb_cnt; u32 smp_mb_size; + struct mdss_hw_settings *hw_settings; + struct mdss_mdp_pipe *vig_pipes; struct mdss_mdp_pipe *rgb_pipes; struct mdss_mdp_pipe *dma_pipes; diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index 76c754477f36..4978fc2e359b 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -777,20 +777,18 @@ static int mdss_mdp_debug_init(struct mdss_data_type *mdata) static int mdss_hw_init(struct mdss_data_type *mdata) { - char *base = mdata->vbif_base; - mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false); - /* Setup VBIF QoS settings*/ - MDSS_MDP_REG_WRITE(0x2E0, 0x000000AA); - MDSS_MDP_REG_WRITE(0x2E4, 0x00000055); - writel_relaxed(0x00000001, base + 0x004); - writel_relaxed(0x00000707, base + 0x0D8); - writel_relaxed(0x00000030, base + 0x0F0); - writel_relaxed(0x00000001, base + 0x124); - writel_relaxed(0x00000FFF, base + 0x178); - writel_relaxed(0x0FFF0FFF, base + 0x17C); - writel_relaxed(0x22222222, base + 0x160); - writel_relaxed(0x00002222, base + 0x164); + mdata->rev = MDSS_MDP_REG_READ(MDSS_REG_HW_VERSION); + mdata->mdp_rev = MDSS_MDP_REG_READ(MDSS_MDP_REG_HW_VERSION); + + if (mdata->hw_settings) { + struct mdss_hw_settings *hws = mdata->hw_settings; + + while (hws->reg) { + writel_relaxed(hws->val, hws->reg); + hws++; + } + } mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false); pr_debug("MDP hw init done\n"); @@ -821,11 +819,6 @@ static u32 mdss_mdp_res_init(struct mdss_data_type *mdata) INIT_DELAYED_WORK(&mdata->clk_ctrl_worker, mdss_mdp_clk_ctrl_workqueue_handler); - mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false); - mdata->rev = MDSS_MDP_REG_READ(MDSS_REG_HW_VERSION); - mdata->mdp_rev = MDSS_MDP_REG_READ(MDSS_MDP_REG_HW_VERSION); - mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false); - mdata->smp_mb_cnt = MDSS_MDP_SMP_MMB_BLOCKS; mdata->smp_mb_size = MDSS_MDP_SMP_MMB_SIZE; @@ -960,10 +953,74 @@ probe_done: return rc; } +static void mdss_mdp_parse_dt_regs_array(const u32 *arr, char __iomem *hw_base, + struct mdss_hw_settings *hws, int count) +{ + u32 len, reg; + int i; + + if (!arr) + return; + + for (i = 0, len = count * 2; i < len; i += 2) { + reg = be32_to_cpu(arr[i]); + hws->reg = hw_base + reg; + hws->val = be32_to_cpu(arr[i + 1]); + pr_debug("reg: 0x%04x=0x%08x\n", reg, hws->val); + hws++; + } +} + +int mdss_mdp_parse_dt_hw_settings(struct platform_device *pdev) +{ + struct mdss_data_type *mdata = platform_get_drvdata(pdev); + struct mdss_hw_settings *hws; + const u32 *vbif_arr, *mdp_arr; + int vbif_len, mdp_len; + + vbif_arr = of_get_property(pdev->dev.of_node, "qcom,vbif-settings", + &vbif_len); + if (!vbif_arr || (mdp_len & 1)) { + pr_warn("MDSS VBIF settings not found\n"); + vbif_len = 0; + } + vbif_len /= 2 * sizeof(u32); + + mdp_arr = of_get_property(pdev->dev.of_node, "qcom,mdp-settings", + &mdp_len); + if (!mdp_arr || (mdp_len & 1)) { + pr_warn("MDSS MDP settings not found\n"); + mdp_len = 0; + } + mdp_len /= 2 * sizeof(u32); + + if ((mdp_len + vbif_len) == 0) + return 0; + + hws = devm_kzalloc(&pdev->dev, sizeof(*hws) * (vbif_len + mdp_len + 1), + GFP_KERNEL); + if (!hws) + return -ENOMEM; + + mdss_mdp_parse_dt_regs_array(vbif_arr, mdata->vbif_base, hws, vbif_len); + mdss_mdp_parse_dt_regs_array(mdp_arr, mdata->mdp_base, + hws + vbif_len, mdp_len); + + mdata->hw_settings = hws; + + return 0; +} + static int mdss_mdp_parse_dt(struct platform_device *pdev) { int rc; + rc = mdss_mdp_parse_dt_hw_settings(pdev); + if (rc) { + pr_err("Error in device tree : hw settings\n"); + return rc; + } + rc = mdss_mdp_parse_dt_pipe(pdev); if (rc) { pr_err("Error in device tree : pipes\n"); |
