return 0;
}
-static void msm_mdss_setup_ubwc_dec_20(struct msm_mdss *msm_mdss)
+static void msm_mdss_4x_setup_ubwc(struct msm_mdss *msm_mdss)
{
const struct qcom_ubwc_cfg_data *data = msm_mdss->mdss_data;
- u32 value = MDSS_UBWC_STATIC_UBWC_SWIZZLE(data->ubwc_swizzle) |
+ u32 value = MDSS_UBWC_STATIC_UBWC_SWIZZLE(data->ubwc_swizzle & 0x1) |
MDSS_UBWC_STATIC_HIGHEST_BANK_BIT(data->highest_bank_bit - 13);
- if (data->ubwc_bank_spread)
- value |= MDSS_UBWC_STATIC_UBWC_BANK_SPREAD;
-
if (data->ubwc_enc_version == UBWC_1_0)
value |= MDSS_UBWC_STATIC_UBWC_MIN_ACC_LEN(1);
writel_relaxed(value, msm_mdss->mmio + REG_MDSS_UBWC_STATIC);
}
-static void msm_mdss_setup_ubwc_dec_30(struct msm_mdss *msm_mdss)
+static void msm_mdss_5x_setup_ubwc(struct msm_mdss *msm_mdss)
{
const struct qcom_ubwc_cfg_data *data = msm_mdss->mdss_data;
u32 value = MDSS_UBWC_STATIC_UBWC_SWIZZLE(data->ubwc_swizzle & 0x1) |
writel_relaxed(value, msm_mdss->mmio + REG_MDSS_UBWC_STATIC);
}
-static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss *msm_mdss)
+static void msm_mdss_6x_setup_ubwc(struct msm_mdss *msm_mdss)
{
const struct qcom_ubwc_cfg_data *data = msm_mdss->mdss_data;
u32 value = MDSS_UBWC_STATIC_UBWC_SWIZZLE(data->ubwc_swizzle) |
MDSS_UBWC_STATIC_HIGHEST_BANK_BIT(data->highest_bank_bit - 13);
+ u32 ver, prediction_mode;
if (data->ubwc_bank_spread)
value |= MDSS_UBWC_STATIC_UBWC_BANK_SPREAD;
if (data->macrotile_mode)
value |= MDSS_UBWC_STATIC_MACROTILE_MODE;
- writel_relaxed(value, msm_mdss->mmio + REG_MDSS_UBWC_STATIC);
-
- if (data->ubwc_enc_version == UBWC_3_0) {
- writel_relaxed(1, msm_mdss->mmio + REG_MDSS_UBWC_CTRL_2);
- writel_relaxed(0, msm_mdss->mmio + REG_MDSS_UBWC_PREDICTION_MODE);
- } else {
- if (data->ubwc_dec_version == UBWC_4_3)
- writel_relaxed(3, msm_mdss->mmio + REG_MDSS_UBWC_CTRL_2);
- else
- writel_relaxed(2, msm_mdss->mmio + REG_MDSS_UBWC_CTRL_2);
- writel_relaxed(1, msm_mdss->mmio + REG_MDSS_UBWC_PREDICTION_MODE);
- }
-}
-
-static void msm_mdss_setup_ubwc_dec_50(struct msm_mdss *msm_mdss)
-{
- const struct qcom_ubwc_cfg_data *data = msm_mdss->mdss_data;
- u32 value = MDSS_UBWC_STATIC_UBWC_SWIZZLE(data->ubwc_swizzle) |
- MDSS_UBWC_STATIC_HIGHEST_BANK_BIT(data->highest_bank_bit - 13);
-
- if (data->ubwc_bank_spread)
- value |= MDSS_UBWC_STATIC_UBWC_BANK_SPREAD;
-
- if (data->macrotile_mode)
- value |= MDSS_UBWC_STATIC_MACROTILE_MODE;
+ if (data->ubwc_enc_version == UBWC_1_0)
+ value |= MDSS_UBWC_STATIC_UBWC_MIN_ACC_LEN(1);
writel_relaxed(value, msm_mdss->mmio + REG_MDSS_UBWC_STATIC);
- if (data->ubwc_dec_version == UBWC_6_0)
- writel_relaxed(5, msm_mdss->mmio + REG_MDSS_UBWC_CTRL_2);
+ if (data->ubwc_enc_version < UBWC_4_0)
+ prediction_mode = 0;
else
- writel_relaxed(4, msm_mdss->mmio + REG_MDSS_UBWC_CTRL_2);
-
- writel_relaxed(1, msm_mdss->mmio + REG_MDSS_UBWC_PREDICTION_MODE);
+ prediction_mode = 1;
+
+ if (data->ubwc_enc_version >= UBWC_6_0)
+ ver = 5;
+ else if (data->ubwc_enc_version >= UBWC_5_0)
+ ver = 4;
+ else if (data->ubwc_enc_version >= UBWC_4_3)
+ ver = 3;
+ else if (data->ubwc_enc_version >= UBWC_4_0)
+ ver = 2;
+ else if (data->ubwc_enc_version >= UBWC_3_0)
+ ver = 1;
+ else /* UBWC 1.0 and 2.0 */
+ ver = 0;
+
+ writel_relaxed(ver, msm_mdss->mmio + REG_MDSS_UBWC_CTRL_2);
+ writel_relaxed(prediction_mode, msm_mdss->mmio + REG_MDSS_UBWC_PREDICTION_MODE);
}
+#define MDSS_HW_VER(major, minor, step) \
+ ((((major) & 0xf) << 28) | \
+ (((minor) & 0xfff) << 16) | \
+ ((step) & 0xffff))
+
static int msm_mdss_enable(struct msm_mdss *msm_mdss)
{
int ret, i;
+ u32 hw_rev;
/*
* Several components have AXI clocks that can only be turned on if
if (msm_mdss->is_mdp5 || !msm_mdss->mdss_data)
return 0;
- /*
- * ubwc config is part of the "mdss" region which is not accessible
- * from the rest of the driver. hardcode known configurations here
- *
- * Decoder version can be read from the UBWC_DEC_HW_VERSION reg,
- * UBWC_n and the rest of params comes from hw data.
- */
- switch (msm_mdss->mdss_data->ubwc_dec_version) {
- case 0: /* no UBWC */
- case UBWC_1_0:
- /* do nothing */
- break;
- case UBWC_2_0:
- msm_mdss_setup_ubwc_dec_20(msm_mdss);
- break;
- case UBWC_3_0:
- msm_mdss_setup_ubwc_dec_30(msm_mdss);
- break;
- case UBWC_4_0:
- case UBWC_4_3:
- msm_mdss_setup_ubwc_dec_40(msm_mdss);
- break;
- case UBWC_5_0:
- msm_mdss_setup_ubwc_dec_50(msm_mdss);
- break;
- case UBWC_6_0:
- msm_mdss_setup_ubwc_dec_50(msm_mdss);
- break;
- default:
- dev_err(msm_mdss->dev, "Unsupported UBWC decoder version %x\n",
- msm_mdss->mdss_data->ubwc_dec_version);
- dev_err(msm_mdss->dev, "HW_REV: 0x%x\n",
- readl_relaxed(msm_mdss->mmio + REG_MDSS_HW_VERSION));
- dev_err(msm_mdss->dev, "UBWC_DEC_HW_VERSION: 0x%x\n",
- readl_relaxed(msm_mdss->mmio + REG_MDSS_UBWC_DEC_HW_VERSION));
- break;
- }
+ hw_rev = readl_relaxed(msm_mdss->mmio + REG_MDSS_HW_VERSION);
+
+ if (hw_rev >= MDSS_HW_VER(6, 0, 0))
+ msm_mdss_6x_setup_ubwc(msm_mdss);
+ else if (hw_rev >= MDSS_HW_VER(5, 0, 0))
+ msm_mdss_5x_setup_ubwc(msm_mdss);
+ else if (hw_rev >= MDSS_HW_VER(4, 0, 0))
+ msm_mdss_4x_setup_ubwc(msm_mdss);
+ /* else UBWC 1.0 or none, no params to program */
return ret;
}