drm/msm/mdss: generate MDSS data for MDP5 platforms
authorDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Thu, 8 Feb 2024 15:01:08 +0000 (17:01 +0200)
committerDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Mon, 19 Feb 2024 11:39:39 +0000 (13:39 +0200)
Older (mdp5) platforms do not use per-SoC compatible strings. Instead
they use a single compat entry 'qcom,mdss'. To facilitate migrating
these platforms to the DPU driver provide a way to generate the MDSS /
UBWC data at runtime, when the DPU driver asks for it.

It is not possible to generate this data structure at the probe time,
since some platforms might not have MDP_CLK enabled, which makes reading
HW_REV register useless and prone to possible crashes.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Patchwork: https://patchwork.freedesktop.org/patch/577502/
Link: https://lore.kernel.org/r/20240208-fd-migrate-mdp5-v4-1-945d08ef3fa8@linaro.org
drivers/gpu/drm/msm/msm_mdss.c

index 35423d1..6565723 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (c) 2018, The Linux Foundation
  */
 
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/interconnect.h>
@@ -213,6 +214,49 @@ static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss *msm_mdss)
        }
 }
 
+#define MDSS_HW_MAJ_MIN                GENMASK(31, 16)
+
+#define MDSS_HW_MSM8996                0x1007
+#define MDSS_HW_MSM8937                0x100e
+#define MDSS_HW_MSM8953                0x1010
+#define MDSS_HW_MSM8998                0x3000
+#define MDSS_HW_SDM660         0x3002
+#define MDSS_HW_SDM630         0x3003
+
+/*
+ * MDP5 platforms use generic qcom,mdp5 compat string, so we have to generate this data
+ */
+static const struct msm_mdss_data *msm_mdss_generate_mdp5_mdss_data(struct msm_mdss *mdss)
+{
+       struct msm_mdss_data *data;
+       u32 hw_rev;
+
+       data = devm_kzalloc(mdss->dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return NULL;
+
+       hw_rev = readl_relaxed(mdss->mmio + HW_REV);
+       hw_rev = FIELD_GET(MDSS_HW_MAJ_MIN, hw_rev);
+
+       if (hw_rev == MDSS_HW_MSM8996 ||
+           hw_rev == MDSS_HW_MSM8937 ||
+           hw_rev == MDSS_HW_MSM8953 ||
+           hw_rev == MDSS_HW_MSM8998 ||
+           hw_rev == MDSS_HW_SDM660 ||
+           hw_rev == MDSS_HW_SDM630) {
+               data->ubwc_dec_version = UBWC_1_0;
+               data->ubwc_enc_version = UBWC_1_0;
+       }
+
+       if (hw_rev == MDSS_HW_MSM8996 ||
+           hw_rev == MDSS_HW_MSM8998)
+               data->highest_bank_bit = 2;
+       else
+               data->highest_bank_bit = 1;
+
+       return data;
+}
+
 const struct msm_mdss_data *msm_mdss_get_mdss_data(struct device *dev)
 {
        struct msm_mdss *mdss;
@@ -222,6 +266,13 @@ const struct msm_mdss_data *msm_mdss_get_mdss_data(struct device *dev)
 
        mdss = dev_get_drvdata(dev);
 
+       /*
+        * We could not do it at the probe time, since hw revision register was
+        * not readable. Fill data structure now for the MDP5 platforms.
+        */
+       if (!mdss->mdss_data && mdss->is_mdp5)
+               mdss->mdss_data = msm_mdss_generate_mdp5_mdss_data(mdss);
+
        return mdss->mdss_data;
 }