From 795f672b88ba4a616a10fb1bd9e0098edf108eb7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 3 Apr 2019 22:16:33 +0300 Subject: [PATCH] drm/i915: Expose full 1024 LUT entries on ivb+ MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit On ivb+ we can select between the regular 10bit LUT mode with 1024 entries, and the split mode where the LUT is split into seprate degamma and gamma halves (each with 512 entries). Currently we expose the split gamma size of 512 as the GAMMA/DEGAMMA_LUT_SIZE. When using only degamma or gamma (not both) we are wasting half of the hardware LUT entries. Let's flip that around so that we expose the full 1024 entries and just throw away half of the user provided entries when using the split gamma mode. Cc: Matt Roper Suggested-by: Matt Roper Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190401200231.2333-8-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/i915_pci.c | 2 +- drivers/gpu/drm/i915/intel_color.c | 75 +++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 81d14dc2fa61..6ffb85ddac53 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -125,7 +125,7 @@ #define ILK_COLORS \ .color = { .gamma_lut_size = 1024 } #define IVB_COLORS \ - .color = { .degamma_lut_size = 512, .gamma_lut_size = 512 } + .color = { .degamma_lut_size = 1024, .gamma_lut_size = 1024 } #define CHV_COLORS \ .color = { .degamma_lut_size = 65, .gamma_lut_size = 257, \ .degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \ diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index efcf9e2d0b56..60f21a1fdbbe 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -538,6 +538,14 @@ static void ilk_load_luts(const struct intel_crtc_state *crtc_state) ilk_load_lut_10(crtc, gamma_lut); } +static int ivb_lut_10_size(u32 prec_index) +{ + if (prec_index & PAL_PREC_SPLIT_MODE) + return 512; + else + return 1024; +} + /* * IVB/HSW Bspec / PAL_PREC_INDEX: * "Restriction : Index auto increment mode is not @@ -545,31 +553,21 @@ static void ilk_load_luts(const struct intel_crtc_state *crtc_state) */ static void ivb_load_lut_10(struct intel_crtc *crtc, const struct drm_property_blob *blob, - u32 prec_index, bool duplicate) + u32 prec_index) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + int hw_lut_size = ivb_lut_10_size(prec_index); const struct drm_color_lut *lut = blob->data; int i, lut_size = drm_color_lut_size(blob); enum pipe pipe = crtc->pipe; - /* - * We advertise the split gamma sizes. When not using split - * gamma we just duplicate each entry. - * - * TODO: expose the full LUT to userspace - */ - if (duplicate) { - for (i = 0; i < lut_size; i++) { - I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++); - I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); - I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++); - I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); - } - } else { - for (i = 0; i < lut_size; i++) { - I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++); - I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); - } + for (i = 0; i < hw_lut_size; i++) { + /* We discard half the user entries in split gamma mode */ + const struct drm_color_lut *entry = + &lut[i * (lut_size - 1) / (hw_lut_size - 1)]; + + I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++); + I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry)); } /* @@ -582,9 +580,10 @@ static void ivb_load_lut_10(struct intel_crtc *crtc, /* On BDW+ the index auto increment mode actually works */ static void bdw_load_lut_10(struct intel_crtc *crtc, const struct drm_property_blob *blob, - u32 prec_index, bool duplicate) + u32 prec_index) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + int hw_lut_size = ivb_lut_10_size(prec_index); const struct drm_color_lut *lut = blob->data; int i, lut_size = drm_color_lut_size(blob); enum pipe pipe = crtc->pipe; @@ -592,20 +591,12 @@ static void bdw_load_lut_10(struct intel_crtc *crtc, I915_WRITE(PREC_PAL_INDEX(pipe), prec_index | PAL_PREC_AUTO_INCREMENT); - /* - * We advertise the split gamma sizes. When not using split - * gamma we just duplicate each entry. - * - * TODO: expose the full LUT to userspace - */ - if (duplicate) { - for (i = 0; i < lut_size; i++) { - I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); - I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); - } - } else { - for (i = 0; i < lut_size; i++) - I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); + for (i = 0; i < hw_lut_size; i++) { + /* We discard half the user entries in split gamma mode */ + const struct drm_color_lut *entry = + &lut[i * (lut_size - 1) / (hw_lut_size - 1)]; + + I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry)); } /* @@ -647,15 +638,15 @@ static void ivb_load_luts(const struct intel_crtc_state *crtc_state) i9xx_load_luts(crtc_state); } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) { ivb_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE | - PAL_PREC_INDEX_VALUE(0), false); + PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_10_max(crtc); ivb_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE | - PAL_PREC_INDEX_VALUE(512), false); + PAL_PREC_INDEX_VALUE(512)); } else { const struct drm_property_blob *blob = gamma_lut ?: degamma_lut; ivb_load_lut_10(crtc, blob, - PAL_PREC_INDEX_VALUE(0), true); + PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_10_max(crtc); } } @@ -670,15 +661,15 @@ static void bdw_load_luts(const struct intel_crtc_state *crtc_state) i9xx_load_luts(crtc_state); } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) { bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE | - PAL_PREC_INDEX_VALUE(0), false); + PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_10_max(crtc); bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE | - PAL_PREC_INDEX_VALUE(512), false); + PAL_PREC_INDEX_VALUE(512)); } else { const struct drm_property_blob *blob = gamma_lut ?: degamma_lut; bdw_load_lut_10(crtc, blob, - PAL_PREC_INDEX_VALUE(0), true); + PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_10_max(crtc); } } @@ -770,7 +761,7 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state) if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) { i9xx_load_luts(crtc_state); } else { - bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0), false); + bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_10_max(crtc); } } @@ -787,7 +778,7 @@ static void icl_load_luts(const struct intel_crtc_state *crtc_state) GAMMA_MODE_MODE_8BIT) { i9xx_load_luts(crtc_state); } else { - bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0), false); + bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_10_max(crtc); } } -- 2.11.0