diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_mdss.c')
| -rw-r--r-- | drivers/gpu/drm/msm/msm_mdss.c | 115 |
1 files changed, 41 insertions, 74 deletions
diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c index 90c3fa0681a0..4a6acd468bc8 100644 --- a/drivers/gpu/drm/msm/msm_mdss.c +++ b/drivers/gpu/drm/msm/msm_mdss.c @@ -166,22 +166,19 @@ static int _msm_mdss_irq_domain_add(struct msm_mdss *msm_mdss) 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) | @@ -199,11 +196,12 @@ static void msm_mdss_setup_ubwc_dec_30(struct msm_mdss *msm_mdss) 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; @@ -211,45 +209,42 @@ static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss *msm_mdss) 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 @@ -283,43 +278,15 @@ static int msm_mdss_enable(struct msm_mdss *msm_mdss) 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; } |
