diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_color.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_color.c | 124 |
1 files changed, 90 insertions, 34 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 945bb03bdd4d..172d398081ee 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -638,10 +638,17 @@ static void ilk_load_luts(const struct intel_crtc_state *crtc_state) struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut; - if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) + switch (crtc_state->gamma_mode) { + case GAMMA_MODE_MODE_8BIT: ilk_load_lut_8(crtc, gamma_lut); - else + break; + case GAMMA_MODE_MODE_10BIT: ilk_load_lut_10(crtc, gamma_lut); + break; + default: + MISSING_CASE(crtc_state->gamma_mode); + break; + } } static int ivb_lut_10_size(u32 prec_index) @@ -745,21 +752,27 @@ static void ivb_load_luts(const struct intel_crtc_state *crtc_state) struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut; const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut; + const struct drm_property_blob *blob = gamma_lut ?: degamma_lut; - if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) { - ilk_load_lut_8(crtc, gamma_lut); - } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) { + switch (crtc_state->gamma_mode) { + case GAMMA_MODE_MODE_8BIT: + ilk_load_lut_8(crtc, blob); + break; + case GAMMA_MODE_MODE_SPLIT: ivb_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE | PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_ext_max(crtc_state); ivb_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE | PAL_PREC_INDEX_VALUE(512)); - } else { - const struct drm_property_blob *blob = gamma_lut ?: degamma_lut; - + break; + case GAMMA_MODE_MODE_10BIT: ivb_load_lut_10(crtc, blob, PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_ext_max(crtc_state); + break; + default: + MISSING_CASE(crtc_state->gamma_mode); + break; } } @@ -768,21 +781,28 @@ static void bdw_load_luts(const struct intel_crtc_state *crtc_state) struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut; const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut; + const struct drm_property_blob *blob = gamma_lut ?: degamma_lut; - if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) { - ilk_load_lut_8(crtc, gamma_lut); - } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) { + switch (crtc_state->gamma_mode) { + case GAMMA_MODE_MODE_8BIT: + ilk_load_lut_8(crtc, blob); + break; + case GAMMA_MODE_MODE_SPLIT: bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE | PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_ext_max(crtc_state); bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE | PAL_PREC_INDEX_VALUE(512)); - } else { - const struct drm_property_blob *blob = gamma_lut ?: degamma_lut; + break; + case GAMMA_MODE_MODE_10BIT: bdw_load_lut_10(crtc, blob, PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_ext_max(crtc_state); + break; + default: + MISSING_CASE(crtc_state->gamma_mode); + break; } } @@ -818,12 +838,14 @@ static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state) * as compared to just 16 to achieve this. */ intel_de_write(dev_priv, PRE_CSC_GAMC_DATA(pipe), - lut[i].green); + lut[i].green); } /* Clamp values > 1.0. */ while (i++ < 35) intel_de_write(dev_priv, PRE_CSC_GAMC_DATA(pipe), 1 << 16); + + intel_de_write(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0); } static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_state) @@ -851,6 +873,8 @@ static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_stat /* Clamp values > 1.0. */ while (i++ < 35) intel_de_write(dev_priv, PRE_CSC_GAMC_DATA(pipe), 1 << 16); + + intel_de_write(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0); } static void glk_load_luts(const struct intel_crtc_state *crtc_state) @@ -871,11 +895,17 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state) else glk_load_degamma_lut_linear(crtc_state); - if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) { + switch (crtc_state->gamma_mode) { + case GAMMA_MODE_MODE_8BIT: ilk_load_lut_8(crtc, gamma_lut); - } else { + break; + case GAMMA_MODE_MODE_10BIT: bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_ext_max(crtc_state); + break; + default: + MISSING_CASE(crtc_state->gamma_mode); + break; } } @@ -1007,9 +1037,13 @@ static void icl_load_luts(const struct intel_crtc_state *crtc_state) icl_program_gamma_superfine_segment(crtc_state); icl_program_gamma_multi_segment(crtc_state); break; - default: + case GAMMA_MODE_MODE_10BIT: bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_ext_max(crtc_state); + break; + default: + MISSING_CASE(crtc_state->gamma_mode); + break; } intel_dsb_commit(crtc_state); @@ -1026,13 +1060,6 @@ static u32 chv_cgm_degamma_udw(const struct drm_color_lut *color) return drm_color_lut_extract(color->red, 14); } -static void chv_cgm_gamma_pack(struct drm_color_lut *entry, u32 ldw, u32 udw) -{ - entry->green = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_GREEN_MASK, ldw), 10); - entry->blue = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_BLUE_MASK, ldw), 10); - entry->red = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_RED_MASK, udw), 10); -} - static void chv_load_cgm_degamma(struct intel_crtc *crtc, const struct drm_property_blob *blob) { @@ -1060,6 +1087,13 @@ static u32 chv_cgm_gamma_udw(const struct drm_color_lut *color) return drm_color_lut_extract(color->red, 10); } +static void chv_cgm_gamma_pack(struct drm_color_lut *entry, u32 ldw, u32 udw) +{ + entry->green = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_GREEN_MASK, ldw), 10); + entry->blue = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_BLUE_MASK, ldw), 10); + entry->red = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_RED_MASK, udw), 10); +} + static void chv_load_cgm_gamma(struct intel_crtc *crtc, const struct drm_property_blob *blob) { @@ -1733,7 +1767,7 @@ bool intel_color_lut_equal(struct drm_property_blob *blob1, break; default: MISSING_CASE(gamma_mode); - return false; + return false; } return true; @@ -1913,23 +1947,34 @@ static void ilk_read_luts(struct intel_crtc_state *crtc_state) if ((crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) == 0) return; - if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) + switch (crtc_state->gamma_mode) { + case GAMMA_MODE_MODE_8BIT: crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc); - else + break; + case GAMMA_MODE_MODE_10BIT: crtc_state->hw.gamma_lut = ilk_read_lut_10(crtc); + break; + default: + MISSING_CASE(crtc_state->gamma_mode); + break; + } } -static struct drm_property_blob *glk_read_lut_10(struct intel_crtc *crtc, +/* On BDW+ the index auto increment mode actually works */ +static struct drm_property_blob *bdw_read_lut_10(struct intel_crtc *crtc, u32 prec_index) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); int i, hw_lut_size = ivb_lut_10_size(prec_index); + int lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size; enum pipe pipe = crtc->pipe; struct drm_property_blob *blob; struct drm_color_lut *lut; + drm_WARN_ON(&dev_priv->drm, lut_size != hw_lut_size); + blob = drm_property_create_blob(&dev_priv->drm, - sizeof(struct drm_color_lut) * hw_lut_size, + sizeof(struct drm_color_lut) * lut_size, NULL); if (IS_ERR(blob)) return NULL; @@ -1939,7 +1984,7 @@ static struct drm_property_blob *glk_read_lut_10(struct intel_crtc *crtc, intel_de_write(dev_priv, PREC_PAL_INDEX(pipe), prec_index | PAL_PREC_AUTO_INCREMENT); - for (i = 0; i < hw_lut_size; i++) { + for (i = 0; i < lut_size; i++) { u32 val = intel_de_read(dev_priv, PREC_PAL_DATA(pipe)); ilk_lut_10_pack(&lut[i], val); @@ -1957,10 +2002,17 @@ static void glk_read_luts(struct intel_crtc_state *crtc_state) if (!crtc_state->gamma_enable) return; - if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) + switch (crtc_state->gamma_mode) { + case GAMMA_MODE_MODE_8BIT: crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc); - else - crtc_state->hw.gamma_lut = glk_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0)); + break; + case GAMMA_MODE_MODE_10BIT: + crtc_state->hw.gamma_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0)); + break; + default: + MISSING_CASE(crtc_state->gamma_mode); + break; + } } static struct drm_property_blob * @@ -2012,11 +2064,15 @@ static void icl_read_luts(struct intel_crtc_state *crtc_state) case GAMMA_MODE_MODE_8BIT: crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc); break; + case GAMMA_MODE_MODE_10BIT: + crtc_state->hw.gamma_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0)); + break; case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED: crtc_state->hw.gamma_lut = icl_read_lut_multi_segment(crtc); break; default: - crtc_state->hw.gamma_lut = glk_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0)); + MISSING_CASE(crtc_state->gamma_mode); + break; } } |