summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Salido-Moreno <adrianm@codeaurora.org>2013-02-07 01:54:14 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:14:36 -0700
commit33d436fa13eeb151c22e130dbd64e42cb07b9e65 (patch)
treec13474c6a8d00511c02d1dc2f9dc0fab6cd237ca
parent55eecf45c211ebfe197451d2019427e2f41f8ff9 (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>
-rw-r--r--Documentation/devicetree/bindings/fb/mdss-mdp.txt14
-rw-r--r--drivers/video/fbdev/msm/mdss.h7
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c93
3 files changed, 96 insertions, 18 deletions
diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
index ac0355d2f1d0..24a0ca99088f 100644
--- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
@@ -76,6 +76,16 @@ Required properties
should reflect the number of mixers that can
drive data to a writeback block.
+Optional properties:
+- qcom,vbif-settings : Array with key-value pairs of constant VBIF register
+ settings used to setup MDSS QoS for optimum performance.
+ The key used should be offset from "vbif_phys" register
+ defined in reg property.
+- qcom,mdp-settings : Array with key-value pairs of constant MDP register
+ settings used to setup MDSS QoS for best performance.
+ The key used should be offset from "mdp_phys" register
+ defined in reg property.
+
Optional subnodes:
Child nodes representing the frame buffer virtual devices.
@@ -94,6 +104,10 @@ Example:
interrupts = <0 72 0>;
vdd-supply = <&gdsc_mdss>;
+ qcom,vbif-settings = <0x0004 0x00000001>,
+ <0x00D8 0x00000707>;
+ qcom,mdp-settings = <0x02E0 0x000000AA>,
+ <0x02E4 0x00000055>;
qcom,mdss-pipe-vig-off = <0x00001200 0x00001600
0x00001A00>;
qcom,mdss-pipe-rgb-off = <0x00001E00 0x00002200
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");