Merge "msm: mdss: Check for handoff pending before IOMMU min BW voting"

This commit is contained in:
Linux Build Service Account 2016-12-21 07:30:02 -08:00 committed by Gerrit - the friendly Code Review server
commit f5d6d71727
3 changed files with 110 additions and 23 deletions
Documentation/devicetree/bindings/fb
drivers/video/fbdev/msm

View file

@ -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>;

View file

@ -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;

View file

@ -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