Apart from the already handled data bus (MAS_MDP_Pn<->DDR), there's
another path that needs to be handled to ensure MDSS functions properly,
namely the "reg bus", a.k.a the CPU-MDSS interconnect.

Gating that path may have a variety of effects, from none to otherwise
inexplicable DSI timeouts.

Provide a way for MDSS driver to vote on this bus.

A note regarding vote values. Newer platforms have corresponding
bandwidth values in the vendor DT files. For the older platforms there
was a static vote in the mdss_mdp and rotator drivers. I choose to be
conservative here and choose this value as a default.

Co-developed-by: Konrad Dybcio <konrad.dyb...@linaro.org>
Signed-off-by: Konrad Dybcio <konrad.dyb...@linaro.org>
Signed-off-by: Dmitry Baryshkov <dmitry.barysh...@linaro.org>
---
 drivers/gpu/drm/msm/msm_mdss.c | 49 +++++++++++++++++++++++++++++++---
 drivers/gpu/drm/msm/msm_mdss.h |  1 +
 2 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c
index eeca281e9d6d..18b07619d6fc 100644
--- a/drivers/gpu/drm/msm/msm_mdss.c
+++ b/drivers/gpu/drm/msm/msm_mdss.c
@@ -28,6 +28,8 @@
 
 #define MIN_IB_BW      400000000UL /* Min ib vote 400MB */
 
+#define DEFAULT_REG_BW 153600 /* Used in mdss fbdev driver */
+
 struct msm_mdss {
        struct device *dev;
 
@@ -42,6 +44,7 @@ struct msm_mdss {
        const struct msm_mdss_data *mdss_data;
        struct icc_path *mdp_path[2];
        u32 num_mdp_paths;
+       struct icc_path *reg_bus_path;
 };
 
 static int msm_mdss_parse_data_bus_icc_path(struct device *dev,
@@ -49,6 +52,7 @@ static int msm_mdss_parse_data_bus_icc_path(struct device 
*dev,
 {
        struct icc_path *path0;
        struct icc_path *path1;
+       struct icc_path *reg_bus_path;
 
        path0 = devm_of_icc_get(dev, "mdp0-mem");
        if (IS_ERR_OR_NULL(path0))
@@ -63,6 +67,10 @@ static int msm_mdss_parse_data_bus_icc_path(struct device 
*dev,
                msm_mdss->num_mdp_paths++;
        }
 
+       reg_bus_path = of_icc_get(dev, "cpu-cfg");
+       if (!IS_ERR_OR_NULL(reg_bus_path))
+               msm_mdss->reg_bus_path = reg_bus_path;
+
        return 0;
 }
 
@@ -229,6 +237,13 @@ static int msm_mdss_enable(struct msm_mdss *msm_mdss)
        for (i = 0; i < msm_mdss->num_mdp_paths; i++)
                icc_set_bw(msm_mdss->mdp_path[i], 0, Bps_to_icc(MIN_IB_BW));
 
+       if (msm_mdss->mdss_data && msm_mdss->mdss_data->reg_bus_bw)
+               icc_set_bw(msm_mdss->reg_bus_path, 0,
+                          msm_mdss->mdss_data->reg_bus_bw);
+       else
+               icc_set_bw(msm_mdss->reg_bus_path, 0,
+                          DEFAULT_REG_BW);
+
        ret = clk_bulk_prepare_enable(msm_mdss->num_clocks, msm_mdss->clocks);
        if (ret) {
                dev_err(msm_mdss->dev, "clock enable failed, ret:%d\n", ret);
@@ -286,6 +301,9 @@ static int msm_mdss_disable(struct msm_mdss *msm_mdss)
        for (i = 0; i < msm_mdss->num_mdp_paths; i++)
                icc_set_bw(msm_mdss->mdp_path[i], 0, 0);
 
+       if (msm_mdss->reg_bus_path)
+               icc_set_bw(msm_mdss->reg_bus_path, 0, 0);
+
        return 0;
 }
 
@@ -372,6 +390,8 @@ static struct msm_mdss *msm_mdss_init(struct 
platform_device *pdev, bool is_mdp5
        if (!msm_mdss)
                return ERR_PTR(-ENOMEM);
 
+       msm_mdss->mdss_data = of_device_get_match_data(&pdev->dev);
+
        msm_mdss->mmio = devm_platform_ioremap_resource_byname(pdev, is_mdp5 ? 
"mdss_phys" : "mdss");
        if (IS_ERR(msm_mdss->mmio))
                return ERR_CAST(msm_mdss->mmio);
@@ -462,8 +482,6 @@ static int mdss_probe(struct platform_device *pdev)
        if (IS_ERR(mdss))
                return PTR_ERR(mdss);
 
-       mdss->mdss_data = of_device_get_match_data(&pdev->dev);
-
        platform_set_drvdata(pdev, mdss);
 
        /*
@@ -495,11 +513,13 @@ static const struct msm_mdss_data msm8998_data = {
        .ubwc_enc_version = UBWC_1_0,
        .ubwc_dec_version = UBWC_1_0,
        .highest_bank_bit = 2,
+       .reg_bus_bw = 76800,
 };
 
 static const struct msm_mdss_data qcm2290_data = {
        /* no UBWC */
        .highest_bank_bit = 0x2,
+       .reg_bus_bw = 76800,
 };
 
 static const struct msm_mdss_data sc7180_data = {
@@ -507,6 +527,7 @@ static const struct msm_mdss_data sc7180_data = {
        .ubwc_dec_version = UBWC_2_0,
        .ubwc_static = 0x1e,
        .highest_bank_bit = 0x3,
+       .reg_bus_bw = 76800,
 };
 
 static const struct msm_mdss_data sc7280_data = {
@@ -516,6 +537,7 @@ static const struct msm_mdss_data sc7280_data = {
        .ubwc_static = 1,
        .highest_bank_bit = 1,
        .macrotile_mode = 1,
+       .reg_bus_bw = 74000,
 };
 
 static const struct msm_mdss_data sc8180x_data = {
@@ -523,6 +545,7 @@ static const struct msm_mdss_data sc8180x_data = {
        .ubwc_dec_version = UBWC_3_0,
        .highest_bank_bit = 3,
        .macrotile_mode = 1,
+       .reg_bus_bw = 76800,
 };
 
 static const struct msm_mdss_data sc8280xp_data = {
@@ -532,12 +555,14 @@ static const struct msm_mdss_data sc8280xp_data = {
        .ubwc_static = 1,
        .highest_bank_bit = 3,
        .macrotile_mode = 1,
+       .reg_bus_bw = 76800,
 };
 
 static const struct msm_mdss_data sdm845_data = {
        .ubwc_enc_version = UBWC_2_0,
        .ubwc_dec_version = UBWC_2_0,
        .highest_bank_bit = 2,
+       .reg_bus_bw = 76800,
 };
 
 static const struct msm_mdss_data sm6350_data = {
@@ -546,12 +571,14 @@ static const struct msm_mdss_data sm6350_data = {
        .ubwc_swizzle = 6,
        .ubwc_static = 0x1e,
        .highest_bank_bit = 1,
+       .reg_bus_bw = 76800,
 };
 
 static const struct msm_mdss_data sm8150_data = {
        .ubwc_enc_version = UBWC_3_0,
        .ubwc_dec_version = UBWC_3_0,
        .highest_bank_bit = 2,
+       .reg_bus_bw = 76800,
 };
 
 static const struct msm_mdss_data sm6115_data = {
@@ -560,6 +587,7 @@ static const struct msm_mdss_data sm6115_data = {
        .ubwc_swizzle = 7,
        .ubwc_static = 0x11f,
        .highest_bank_bit = 0x1,
+       .reg_bus_bw = 76800,
 };
 
 static const struct msm_mdss_data sm6125_data = {
@@ -577,6 +605,18 @@ static const struct msm_mdss_data sm8250_data = {
        /* TODO: highest_bank_bit = 2 for LP_DDR4 */
        .highest_bank_bit = 3,
        .macrotile_mode = 1,
+       .reg_bus_bw = 76800,
+};
+
+static const struct msm_mdss_data sm8350_data = {
+       .ubwc_enc_version = UBWC_4_0,
+       .ubwc_dec_version = UBWC_4_0,
+       .ubwc_swizzle = 6,
+       .ubwc_static = 1,
+       /* TODO: highest_bank_bit = 2 for LP_DDR4 */
+       .highest_bank_bit = 3,
+       .macrotile_mode = 1,
+       .reg_bus_bw = 74000,
 };
 
 static const struct msm_mdss_data sm8550_data = {
@@ -587,6 +627,7 @@ static const struct msm_mdss_data sm8550_data = {
        /* TODO: highest_bank_bit = 2 for LP_DDR4 */
        .highest_bank_bit = 3,
        .macrotile_mode = 1,
+       .reg_bus_bw = 57000,
 };
 static const struct of_device_id mdss_dt_match[] = {
        { .compatible = "qcom,mdss" },
@@ -603,8 +644,8 @@ static const struct of_device_id mdss_dt_match[] = {
        { .compatible = "qcom,sm6375-mdss", .data = &sm6350_data },
        { .compatible = "qcom,sm8150-mdss", .data = &sm8150_data },
        { .compatible = "qcom,sm8250-mdss", .data = &sm8250_data },
-       { .compatible = "qcom,sm8350-mdss", .data = &sm8250_data },
-       { .compatible = "qcom,sm8450-mdss", .data = &sm8250_data },
+       { .compatible = "qcom,sm8350-mdss", .data = &sm8350_data },
+       { .compatible = "qcom,sm8450-mdss", .data = &sm8350_data },
        { .compatible = "qcom,sm8550-mdss", .data = &sm8550_data },
        {}
 };
diff --git a/drivers/gpu/drm/msm/msm_mdss.h b/drivers/gpu/drm/msm/msm_mdss.h
index 02bbab42adbc..3afef4b1786d 100644
--- a/drivers/gpu/drm/msm/msm_mdss.h
+++ b/drivers/gpu/drm/msm/msm_mdss.h
@@ -14,6 +14,7 @@ struct msm_mdss_data {
        u32 ubwc_static;
        u32 highest_bank_bit;
        u32 macrotile_mode;
+       u32 reg_bus_bw;
 };
 
 #define UBWC_1_0 0x10000000
-- 
2.39.2

Reply via email to