[Intel-gfx] [PATCH 2/2] drm/i915: Add module parameter to en-/disable hw color correction.
Daniel Vetter
daniel at ffwll.ch
Tue Sep 26 05:05:07 UTC 2017
On Fri, Sep 15, 2017 at 05:48:25PM +0200, Mario Kleiner wrote:
> The new module parameter enable_hw_color_correction defaults to
> true, to retain the current behaviour. If set to false, it will
> disable all hardware color correction, like gamma/degamma and
> csc.
>
> This is useful for debugging gamma table / csc precision problems,
> and to ensure unmodified pixel passthrough from framebuffer to
> outputs, e.g., for scientific applications which critically depend
> on perfect pixel passthrough. While i hope this switch generally
> won't be needed, it provides extra peace-of-mind - an "airbag" for
> color correction trouble.
>
> Tested on Ironlake, IvyBridge, Haswell, Skylake.
>
> One unexpected result during testing was that while this works on
> all tested gpu's with a 8 bpc XR24 framebuffer as primary plane,
> if a 10 bpc XR30 fb is active, then hw gamma tables seem to get
> automatically bypassed on at least the tested IvyBridge and later
> (but not on the tested Ironlake), regardless of hw programming,
> at least for the legacy 256->8 bit luts and the 1024->10 bit
> precision luts. However, the type of selected - but bypassed -
> hw gamma table still determines output precision, ie. even an
> auto-bypassed legacy 256 slot 8 bit lut in XR30 fb mode still
> restricts the effective output precision to 8 bit, while an
> auto-bypassed precision lut doesn't restrict precision.
Instead of a modparam I think the right thing to fix here is the driver
setup. Enabling the legacy gamma table is indeed documented to restrict
the pipe to 8bpc (the 2 additional bits for 10bpc are just padded).
Having driver options for "pls give me non-broken behaviour" doesn't make
any sense to me.
-Daniel
>
> Iow. this patch is needed even with XR30 fb's for actual 10
> bit precision output, even though the hw seems to sort of ignore
> the tested gamma tables for XR30 fb's.
>
> Signed-off-by: Mario Kleiner <mario.kleiner.de at gmail.com>
> ---
> drivers/gpu/drm/i915/i915_params.c | 5 +++++
> drivers/gpu/drm/i915/i915_params.h | 3 ++-
> drivers/gpu/drm/i915/intel_display.c | 26 +++++++++++++++++---------
> drivers/gpu/drm/i915/intel_sprite.c | 21 ++++++++++++++++-----
> 4 files changed, 40 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
> index 07ec3a96457c..8f6a176a97e1 100644
> --- a/drivers/gpu/drm/i915/i915_params.c
> +++ b/drivers/gpu/drm/i915/i915_params.c
> @@ -66,6 +66,7 @@ struct i915_params i915 __read_mostly = {
> .enable_dpcd_backlight = false,
> .enable_gvt = false,
> .enable_dithering = -1,
> + .enable_hw_color_correction = true,
> };
>
> module_param_named(modeset, i915.modeset, int, 0400);
> @@ -262,3 +263,7 @@ MODULE_PARM_DESC(enable_gvt,
> module_param_named(enable_dithering, i915.enable_dithering, int, 0644);
> MODULE_PARM_DESC(enable_dithering,
> "Enable dithering (-1=auto [default], 0=force off on all outputs, 1=force on on all outputs)");
> +
> +module_param_named(enable_hw_color_correction, i915.enable_hw_color_correction, bool, 0644);
> +MODULE_PARM_DESC(enable_hw_color_correction,
> + "Enable hardware color correction like gamma luts and csc (default: true)");
> diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
> index 7e365cd4fc91..f5c9163d2675 100644
> --- a/drivers/gpu/drm/i915/i915_params.h
> +++ b/drivers/gpu/drm/i915/i915_params.h
> @@ -69,7 +69,8 @@
> func(bool, nuclear_pageflip); \
> func(bool, enable_dp_mst); \
> func(bool, enable_dpcd_backlight); \
> - func(bool, enable_gvt)
> + func(bool, enable_gvt); \
> + func(bool, enable_hw_color_correction)
>
> #define MEMBER(T, member) T member
> struct i915_params {
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index bea471a96820..1e1b157353a9 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3184,13 +3184,17 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
> unsigned int rotation = plane_state->base.rotation;
> u32 dspcntr;
>
> - dspcntr = DISPLAY_PLANE_ENABLE | DISPPLANE_GAMMA_ENABLE;
> + dspcntr = DISPLAY_PLANE_ENABLE;
> +
> + if (i915.enable_hw_color_correction)
> + dspcntr |= DISPPLANE_GAMMA_ENABLE;
>
> if (IS_G4X(dev_priv) || IS_GEN5(dev_priv) ||
> IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv))
> dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
>
> - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
> + if ((IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) &&
> + i915.enable_hw_color_correction)
> dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
>
> if (INTEL_GEN(dev_priv) < 4)
> @@ -3514,7 +3518,8 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
>
> plane_ctl = PLANE_CTL_ENABLE;
>
> - if (!IS_GEMINILAKE(dev_priv) && !IS_CANNONLAKE(dev_priv)) {
> + if (!IS_GEMINILAKE(dev_priv) && !IS_CANNONLAKE(dev_priv) &&
> + i915.enable_hw_color_correction) {
> plane_ctl |=
> PLANE_CTL_PIPE_GAMMA_ENABLE |
> PLANE_CTL_PIPE_CSC_ENABLE |
> @@ -3571,7 +3576,8 @@ static void skylake_update_primary_plane(struct intel_plane *plane,
>
> spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>
> - if (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) {
> + if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
> + i915.enable_hw_color_correction) {
> I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
> PLANE_COLOR_PIPE_GAMMA_ENABLE |
> PLANE_COLOR_PIPE_CSC_ENABLE |
> @@ -9431,7 +9437,7 @@ static u32 i845_cursor_ctl(const struct intel_crtc_state *crtc_state,
> const struct drm_framebuffer *fb = plane_state->base.fb;
>
> return CURSOR_ENABLE |
> - CURSOR_GAMMA_ENABLE |
> + (i915.enable_hw_color_correction ? CURSOR_GAMMA_ENABLE : 0) |
> CURSOR_FORMAT_ARGB |
> CURSOR_STRIDE(fb->pitches[0]);
> }
> @@ -9544,12 +9550,14 @@ static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state,
> struct drm_i915_private *dev_priv =
> to_i915(plane_state->base.plane->dev);
> struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> - u32 cntl;
> + u32 cntl = 0;
>
> - cntl = MCURSOR_GAMMA_ENABLE;
> + if (i915.enable_hw_color_correction) {
> + cntl = MCURSOR_GAMMA_ENABLE;
>
> - if (HAS_DDI(dev_priv))
> - cntl |= CURSOR_PIPE_CSC_ENABLE;
> + if (HAS_DDI(dev_priv))
> + cntl |= CURSOR_PIPE_CSC_ENABLE;
> + }
>
> cntl |= MCURSOR_PIPE_SELECT(crtc->pipe);
>
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 524933b01483..6e6a7377a7bc 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -258,7 +258,8 @@ skl_update_plane(struct intel_plane *plane,
>
> spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>
> - if (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) {
> + if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
> + i915.enable_hw_color_correction) {
> I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
> PLANE_COLOR_PIPE_GAMMA_ENABLE |
> PLANE_COLOR_PIPE_CSC_ENABLE |
> @@ -371,7 +372,10 @@ static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
> const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
> u32 sprctl;
>
> - sprctl = SP_ENABLE | SP_GAMMA_ENABLE;
> + sprctl = SP_ENABLE;
> +
> + if (i915.enable_hw_color_correction)
> + sprctl |= SP_GAMMA_ENABLE;
>
> switch (fb->format->format) {
> case DRM_FORMAT_YUYV:
> @@ -511,12 +515,16 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
> const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
> u32 sprctl;
>
> - sprctl = SPRITE_ENABLE | SPRITE_GAMMA_ENABLE;
> + sprctl = SPRITE_ENABLE;
> +
> + if (i915.enable_hw_color_correction)
> + sprctl |= SPRITE_GAMMA_ENABLE;
>
> if (IS_IVYBRIDGE(dev_priv))
> sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
>
> - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
> + if ((IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) &&
> + i915.enable_hw_color_correction)
> sprctl |= SPRITE_PIPE_CSC_ENABLE;
>
> switch (fb->format->format) {
> @@ -651,7 +659,10 @@ static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
> const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
> u32 dvscntr;
>
> - dvscntr = DVS_ENABLE | DVS_GAMMA_ENABLE;
> + dvscntr = DVS_ENABLE;
> +
> + if (i915.enable_hw_color_correction)
> + dvscntr |= DVS_GAMMA_ENABLE;
>
> if (IS_GEN6(dev_priv))
> dvscntr |= DVS_TRICKLE_FEED_DISABLE;
> --
> 2.13.0.rc1.294.g07d810a77f
>
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
More information about the Intel-gfx
mailing list