diff options
author | Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> | 2017-01-27 11:02:30 +0200 |
---|---|---|
committer | Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> | 2017-01-30 10:25:13 +0200 |
commit | 9751bafc43d599262d9de7e6d988804dc5f5d4aa (patch) | |
tree | fb4511c9ae47816199ddd003328105204e034d59 /drivers/gpu/drm/i915/intel_color.c | |
parent | 2fcb206654e8b3826424ffa7ef65bd74cc65ff16 (diff) | |
download | op-kernel-dev-9751bafc43d599262d9de7e6d988804dc5f5d4aa.zip op-kernel-dev-9751bafc43d599262d9de7e6d988804dc5f5d4aa.tar.gz |
drm/i915/glk: Program pipe gamma and degamma tables
The gamma tables in Geminilake were changed. There is no split-gamma
mode. Instead, there is a dedicated degamma table that is enabled
whenever pipe CSC is enabled.
The dedicated gamma table has 16 bit precision but doesn't support
separate channels. Since that doesn't match the per-channel format of
the degamma LUT property, for now only a linear table is loaded and the
property ignored.
v2: Remove empty line. (Ville)
Reuse broadwell code. (Ville)
v3: Don't write PIPE_CSC_MODE. (Ville)
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170127090230.20302-1-ander.conselvan.de.oliveira@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/intel_color.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_color.c | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 82a3bc9..0627eee 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -380,7 +380,9 @@ static void bdw_load_gamma_lut(struct drm_crtc_state *state, u32 offset) WARN_ON(offset & ~PAL_PREC_INDEX_VALUE_MASK); I915_WRITE(PREC_PAL_INDEX(pipe), - PAL_PREC_SPLIT_MODE | PAL_PREC_AUTO_INCREMENT | offset); + (offset ? PAL_PREC_SPLIT_MODE : 0) | + PAL_PREC_AUTO_INCREMENT | + offset); if (state->gamma_lut) { struct drm_color_lut *lut = @@ -443,6 +445,57 @@ static void broadwell_load_luts(struct drm_crtc_state *state) I915_WRITE(PREC_PAL_INDEX(pipe), 0); } +static void glk_load_degamma_lut(struct drm_crtc_state *state) +{ + struct drm_i915_private *dev_priv = to_i915(state->crtc->dev); + enum pipe pipe = to_intel_crtc(state->crtc)->pipe; + const uint32_t lut_size = 33; + uint32_t i; + + /* + * When setting the auto-increment bit, the hardware seems to + * ignore the index bits, so we need to reset it to index 0 + * separately. + */ + I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0); + I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT); + + /* + * FIXME: The pipe degamma table in geminilake doesn't support + * different values per channel, so this just loads a linear table. + */ + for (i = 0; i < lut_size; i++) { + uint32_t v = (i * ((1 << 16) - 1)) / (lut_size - 1); + + I915_WRITE(PRE_CSC_GAMC_DATA(pipe), v); + } + + /* Clamp values > 1.0. */ + while (i++ < 35) + I915_WRITE(PRE_CSC_GAMC_DATA(pipe), (1 << 16) - 1); +} + +static void glk_load_luts(struct drm_crtc_state *state) +{ + struct drm_crtc *crtc = state->crtc; + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_crtc_state *intel_state = to_intel_crtc_state(state); + enum pipe pipe = to_intel_crtc(crtc)->pipe; + + if (crtc_state_is_legacy(state)) { + haswell_load_luts(state); + return; + } + + glk_load_degamma_lut(state); + bdw_load_gamma_lut(state, 0); + + intel_state->gamma_mode = GAMMA_MODE_MODE_10BIT; + I915_WRITE(GAMMA_MODE(pipe), GAMMA_MODE_MODE_10BIT); + POSTING_READ(GAMMA_MODE(pipe)); +} + /* Loads the palette/gamma unit for the CRTC on CherryView. */ static void cherryview_load_luts(struct drm_crtc_state *state) { @@ -561,6 +614,9 @@ void intel_color_init(struct drm_crtc *crtc) IS_BROXTON(dev_priv)) { dev_priv->display.load_csc_matrix = i9xx_load_csc_matrix; dev_priv->display.load_luts = broadwell_load_luts; + } else if (IS_GEMINILAKE(dev_priv)) { + dev_priv->display.load_csc_matrix = i9xx_load_csc_matrix; + dev_priv->display.load_luts = glk_load_luts; } else { dev_priv->display.load_luts = i9xx_load_luts; } |