diff options
| author | Kalyan Thota <kalyant@codeaurora.org> | 2016-04-19 12:35:49 +0530 |
|---|---|---|
| committer | Harsh Sahu <hsahu@codeaurora.org> | 2016-11-29 12:37:15 -0800 |
| commit | 1baa44c0dfc6404f65d9f728987f4a74488e4cbd (patch) | |
| tree | 844b3f5184d00014a22a8aa9d786b24b2f4ba207 | |
| parent | 47d0c2b4a71dcbb37eb9557fdb1b041f3103bd09 (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.txt | 25 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss.h | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.c | 102 |
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 |
