From 1baa44c0dfc6404f65d9f728987f4a74488e4cbd Mon Sep 17 00:00:00 2001 From: Kalyan Thota Date: Tue, 19 Apr 2016 12:35:49 +0530 Subject: [PATCH 1/2] 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 Signed-off-by: Harsh Sahu --- .../devicetree/bindings/fb/mdss-mdp.txt | 25 +++-- drivers/video/fbdev/msm/mdss.h | 6 +- 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; + } } /* @@ -1219,6 +1236,54 @@ unsigned long mdss_mdp_get_clk_rate(u32 clk_idx, bool locked) return clk_rate; } +/** + * 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 From 6d0127467c52e965abcde233b12a046017ca0bf2 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Devarakonda Date: Mon, 20 Jun 2016 19:30:06 +0530 Subject: [PATCH 2/2] msm: mdss: Check for handoff pending before IOMMU min BW voting While voting for minimum BW for IOMMU operations, check for handoff pending flag. If the continuous splash screen hasn't finished handoff, do not vote for BW. Change-Id: Icc10819680b6e5170a322bdf75a98e3c24dde67d Signed-off-by: Krishna Chaitanya Devarakonda --- drivers/video/fbdev/msm/mdss_mdp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index c3b641cee142..12e44c681011 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -1252,7 +1252,7 @@ static int mdss_bus_rt_bw_vote(bool enable) int rc = 0; bool changed = false; - if (!mdata->hw_rt_bus_hdl) + if (!mdata->hw_rt_bus_hdl || mdata->handoff_pending) return 0; if (enable) {