Merge "msm: mdss: Check for handoff pending before IOMMU min BW voting"
This commit is contained in:
commit
f5d6d71727
3 changed files with 110 additions and 23 deletions
|
@ -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>;
|
||||
|
|
|
@ -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,
|
||||
|
@ -370,6 +369,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;
|
||||
|
@ -390,6 +393,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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1243,6 +1260,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 || mdata->handoff_pending)
|
||||
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
|
||||
|
@ -1253,9 +1318,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);
|
||||
|
@ -1265,8 +1328,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);
|
||||
}
|
||||
|
@ -1346,9 +1408,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++;
|
||||
|
@ -1357,12 +1417,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");
|
||||
|
@ -1981,7 +2036,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:
|
||||
|
@ -2002,7 +2056,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:
|
||||
|
@ -4479,6 +4532,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
|
||||
|
|
Loading…
Add table
Reference in a new issue