summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKalyan Thota <kalyant@codeaurora.org>2016-04-19 12:35:49 +0530
committerHarsh Sahu <hsahu@codeaurora.org>2016-11-29 12:37:15 -0800
commit1baa44c0dfc6404f65d9f728987f4a74488e4cbd (patch)
tree844b3f5184d00014a22a8aa9d786b24b2f4ba207
parent47d0c2b4a71dcbb37eb9557fdb1b041f3103bd09 (diff)
msm: mdss: add support for hw_rt bus client for mdss
Some targets expect a minimum vote on the bus during SMMU and TZ operations. Add a new bus client in mdss driver which will be used to request the additional vote. Change-Id: I0b84479bf892def42c0b59a684a850d8d5c01257 Signed-off-by: Kalyan Thota <kalyant@codeaurora.org> Signed-off-by: Harsh Sahu <hsahu@codeaurora.org>
-rw-r--r--Documentation/devicetree/bindings/fb/mdss-mdp.txt25
-rw-r--r--drivers/video/fbdev/msm/mdss.h6
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c102
3 files changed, 110 insertions, 23 deletions
diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
index 389c2c32fd5b..7a98e4e8fdd2 100644
--- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
@@ -239,6 +239,10 @@ Bus Scaling Data:
- qcom,max-mixer-width: Specify maximum MDP mixer width that the device supports.
This is a mandatory property, if not specified then
mdp probe will fail.
+- qcom,mdss-reg-bus: Subnode to provide Bus scaling for register access for
+ MDP and DSI Blocks.
+- qcom,mdss-rot-reg-bus: Subnode to provide Bus scaling for register access for
+ Rotator Block.
Optional properties:
- batfet-supply : Phandle for battery FET regulator device node.
@@ -531,14 +535,13 @@ Fudge Factors: Fudge factors are used to boost demand for
- qcom,max-pipe-width: This value specifies the maximum MDP SSPP width
the device supports. If not specified, a default value
of 2048 will be applied.
-- qcom,mdss-reg-bus: Property to provide Bus scaling for register access for
- MDP and DSI Blocks.
-
-- qcom,mdss-rot-reg-bus: Property to provide Bus scaling for register access for
- Rotator Block.
Optional subnodes:
-- mdss_fb: Child nodes representing the frame buffer virtual devices.
+- mdss_fb: Child nodes representing the frame buffer virtual devices.
+
+- qcom,mdss-hw-rt-bus: Subnode to request min vote on the bus.
+ Some targets expect min vote on the bus during SMMU
+ and TZ operations. Use this handle to request the vote needed.
Subnode properties:
- compatible : Must be "qcom,mdss-fb"
@@ -851,6 +854,16 @@ Example:
<1 590 0 320000>;
};
+ qcom,mdss-hw-rt {
+ /* hw-rt Bus Scale Settings */
+ qcom,msm-bus,name = "mdss_hw_rt";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <22 512 0 0>,
+ <22 512 0 1000>;
+ };
+
smmu_mdp_sec: qcom,smmu_mdp_sec_cb {
compatible = "qcom,smmu_mdp_sec";
iommus = <&mdp_smmu 1>;
diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h
index 5a24a1995af9..39b404a0af24 100644
--- a/drivers/video/fbdev/msm/mdss.h
+++ b/drivers/video/fbdev/msm/mdss.h
@@ -159,7 +159,6 @@ enum mdss_hw_quirk {
MDSS_QUIRK_DSC_RIGHT_ONLY_PU,
MDSS_QUIRK_DSC_2SLICE_PU_THRPUT,
MDSS_QUIRK_DMA_BI_DIR,
- MDSS_QUIRK_MIN_BUS_VOTE,
MDSS_QUIRK_FMT_PACK_PATTERN,
MDSS_QUIRK_NEED_SECURE_MAP,
MDSS_QUIRK_SRC_SPLIT_ALWAYS,
@@ -368,6 +367,10 @@ struct mdss_data_type {
u32 rot_block_size;
+ /* HW RT bus (AXI) */
+ u32 hw_rt_bus_hdl;
+ u32 hw_rt_bus_ref_cnt;
+
/* data bus (AXI) */
u32 bus_hdl;
u32 bus_ref_cnt;
@@ -388,6 +391,7 @@ struct mdss_data_type {
u32 ao_bw_uc_idx; /* active only idx */
struct msm_bus_scale_pdata *bus_scale_table;
struct msm_bus_scale_pdata *reg_bus_scale_table;
+ struct msm_bus_scale_pdata *hw_rt_bus_scale_table;
u32 max_bw_low;
u32 max_bw_high;
u32 max_bw_per_pipe;
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c
index e137a8b050b0..c3b641cee142 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp.c
@@ -491,6 +491,18 @@ static int mdss_mdp_bus_scale_register(struct mdss_data_type *mdata)
mdata->reg_bus_hdl);
}
+ if (mdata->hw_rt_bus_scale_table && !mdata->hw_rt_bus_hdl) {
+ mdata->hw_rt_bus_hdl =
+ msm_bus_scale_register_client(
+ mdata->hw_rt_bus_scale_table);
+ if (!mdata->hw_rt_bus_hdl)
+ /* Continue without reg_bus scaling */
+ pr_warn("hw_rt_bus client register failed\n");
+ else
+ pr_debug("register hw_rt_bus=%x\n",
+ mdata->hw_rt_bus_hdl);
+ }
+
/*
* Following call will not result in actual vote rather update the
* current index and ab/ib value. When continuous splash is enabled,
@@ -512,6 +524,11 @@ static void mdss_mdp_bus_scale_unregister(struct mdss_data_type *mdata)
msm_bus_scale_unregister_client(mdata->reg_bus_hdl);
mdata->reg_bus_hdl = 0;
}
+
+ if (mdata->hw_rt_bus_hdl) {
+ msm_bus_scale_unregister_client(mdata->hw_rt_bus_hdl);
+ mdata->hw_rt_bus_hdl = 0;
+ }
}
/*
@@ -1220,6 +1237,54 @@ unsigned long mdss_mdp_get_clk_rate(u32 clk_idx, bool locked)
}
/**
+ * mdss_bus_rt_bw_vote() -- place bus bandwidth request
+ * @enable: value of enable or disable
+ *
+ * hw_rt table has two entries, 0 and Min Vote (1Mhz)
+ * while attaching SMMU and for few TZ operations which
+ * happen at very early stage, we will request Min Vote
+ * thru this handle.
+ *
+ */
+static int mdss_bus_rt_bw_vote(bool enable)
+{
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ int rc = 0;
+ bool changed = false;
+
+ if (!mdata->hw_rt_bus_hdl)
+ return 0;
+
+ if (enable) {
+ if (mdata->hw_rt_bus_ref_cnt == 0)
+ changed = true;
+ mdata->hw_rt_bus_ref_cnt++;
+ } else {
+ if (mdata->hw_rt_bus_ref_cnt != 0) {
+ mdata->hw_rt_bus_ref_cnt--;
+ if (mdata->hw_rt_bus_ref_cnt == 0)
+ changed = true;
+ } else {
+ pr_warn("%s: bus bw votes are not balanced\n",
+ __func__);
+ }
+ }
+
+ pr_debug("%pS: task:%s bw_cnt=%d changed=%d enable=%d\n",
+ __builtin_return_address(0), current->group_leader->comm,
+ mdata->hw_rt_bus_ref_cnt, changed, enable);
+
+ if (changed) {
+ rc = msm_bus_scale_client_update_request(mdata->hw_rt_bus_hdl,
+ enable ? 1 : 0);
+ if (rc)
+ pr_err("%s: Bus bandwidth vote failed\n", __func__);
+ }
+
+ return rc;
+}
+
+/**
* __mdss_mdp_reg_access_clk_enable - Enable minimum MDSS clocks required
* for register access
*/
@@ -1229,9 +1294,7 @@ static inline void __mdss_mdp_reg_access_clk_enable(
if (enable) {
mdss_update_reg_bus_vote(mdata->reg_bus_clt,
VOTE_INDEX_LOW);
- if (mdss_has_quirk(mdata, MDSS_QUIRK_MIN_BUS_VOTE))
- mdss_bus_scale_set_quota(MDSS_HW_RT,
- SZ_1M, SZ_1M);
+ mdss_bus_rt_bw_vote(true);
mdss_mdp_clk_update(MDSS_CLK_MNOC_AHB, 1);
mdss_mdp_clk_update(MDSS_CLK_AHB, 1);
mdss_mdp_clk_update(MDSS_CLK_AXI, 1);
@@ -1241,8 +1304,7 @@ static inline void __mdss_mdp_reg_access_clk_enable(
mdss_mdp_clk_update(MDSS_CLK_AXI, 0);
mdss_mdp_clk_update(MDSS_CLK_AHB, 0);
mdss_mdp_clk_update(MDSS_CLK_MNOC_AHB, 0);
- if (mdss_has_quirk(mdata, MDSS_QUIRK_MIN_BUS_VOTE))
- mdss_bus_scale_set_quota(MDSS_HW_RT, 0, 0);
+ mdss_bus_rt_bw_vote(false);
mdss_update_reg_bus_vote(mdata->reg_bus_clt,
VOTE_INDEX_DISABLE);
}
@@ -1322,9 +1384,7 @@ int mdss_iommu_ctrl(int enable)
* finished handoff, as it may still be working with phys addr
*/
if (!mdata->iommu_attached && !mdata->handoff_pending) {
- if (mdss_has_quirk(mdata, MDSS_QUIRK_MIN_BUS_VOTE))
- mdss_bus_scale_set_quota(MDSS_HW_RT,
- SZ_1M, SZ_1M);
+ mdss_bus_rt_bw_vote(true);
rc = mdss_smmu_attach(mdata);
}
mdata->iommu_ref_cnt++;
@@ -1333,12 +1393,7 @@ int mdss_iommu_ctrl(int enable)
mdata->iommu_ref_cnt--;
if (mdata->iommu_ref_cnt == 0) {
rc = mdss_smmu_detach(mdata);
- if (mdss_has_quirk(mdata,
- MDSS_QUIRK_MIN_BUS_VOTE) &&
- (!mdata->sec_disp_en ||
- !mdata->sec_cam_en))
- mdss_bus_scale_set_quota(MDSS_HW_RT,
- 0, 0);
+ mdss_bus_rt_bw_vote(false);
}
} else {
pr_err("unbalanced iommu ref\n");
@@ -1957,7 +2012,6 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
mdss_mdp_init_default_prefill_factors(mdata);
set_bit(MDSS_QOS_OTLIM, mdata->mdss_qos_map);
mdss_set_quirk(mdata, MDSS_QUIRK_DMA_BI_DIR);
- mdss_set_quirk(mdata, MDSS_QUIRK_MIN_BUS_VOTE);
mdss_set_quirk(mdata, MDSS_QUIRK_NEED_SECURE_MAP);
break;
case MDSS_MDP_HW_REV_115:
@@ -1978,7 +2032,6 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
mdss_mdp_init_default_prefill_factors(mdata);
set_bit(MDSS_QOS_OTLIM, mdata->mdss_qos_map);
mdss_set_quirk(mdata, MDSS_QUIRK_DMA_BI_DIR);
- mdss_set_quirk(mdata, MDSS_QUIRK_MIN_BUS_VOTE);
mdss_set_quirk(mdata, MDSS_QUIRK_NEED_SECURE_MAP);
break;
case MDSS_MDP_HW_REV_300:
@@ -4452,6 +4505,23 @@ static int mdss_mdp_parse_dt_bus_scale(struct platform_device *pdev)
pr_debug("mdss-reg-bus not found\n");
}
+ node = of_get_child_by_name(pdev->dev.of_node, "qcom,mdss-hw-rt-bus");
+ if (node) {
+ mdata->hw_rt_bus_scale_table =
+ msm_bus_pdata_from_node(pdev, node);
+ if (IS_ERR_OR_NULL(mdata->hw_rt_bus_scale_table)) {
+ rc = PTR_ERR(mdata->hw_rt_bus_scale_table);
+ if (!rc)
+ pr_err("hw_rt_bus_scale failed rc=%d\n", rc);
+ rc = 0;
+ mdata->hw_rt_bus_scale_table = NULL;
+ }
+ } else {
+ rc = 0;
+ mdata->hw_rt_bus_scale_table = NULL;
+ pr_debug("mdss-hw-rt-bus not found\n");
+ }
+
return rc;
}
#endif