* Copyright (c) 2018, The Linux Foundation
  */
 
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/interconnect.h>
        }
 }
 
+#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;
 
        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;
 }