From mboxrd@z Thu Jan 1 00:00:00 1970 From: Chris Wilson Subject: [PATCH 4/5] drm/i915: Synchronize userspace palette LUT (i.e. gamma) changes to vblank Date: Wed, 18 Apr 2012 17:57:43 +0100 Message-ID: <1334768264-27785-5-git-send-email-chris@chris-wilson.co.uk> References: <1334768264-27785-1-git-send-email-chris@chris-wilson.co.uk> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from fireflyinternet.com (smtp.fireflyinternet.com [109.228.6.236]) by gabe.freedesktop.org (Postfix) with ESMTP id 8B61EA08BF for ; Wed, 18 Apr 2012 09:58:15 -0700 (PDT) In-Reply-To: <1334768264-27785-1-git-send-email-chris@chris-wilson.co.uk> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces+gcfxdi-intel-gfx=m.gmane.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+gcfxdi-intel-gfx=m.gmane.org@lists.freedesktop.org To: intel-gfx@lists.freedesktop.org List-Id: intel-gfx@lists.freedesktop.org Adam Jackson was watching the screensaver fade out and expressed a desire for the gamma updates to be synchronized to vblank to avoid the unsightly tears. Reported-by: Adam Jackson Cc: Adam Jackson Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 44 ++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index edc5c9b..35901eb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -47,6 +47,7 @@ bool intel_pipe_has_type(struct drm_crtc *crtc, int type); static void intel_increase_pllclock(struct drm_crtc *crtc); static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); +static void __intel_crtc_load_lut(struct intel_crtc *crtc, void *data); typedef struct { /* given values */ @@ -2811,7 +2812,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) * On ILK+ LUT must be loaded before the pipe is running but with * clocks enabled */ - intel_crtc_load_lut(crtc); + __intel_crtc_load_lut(to_intel_crtc(crtc), NULL); intel_enable_pipe(dev_priv, pipe, is_pch_port); intel_enable_plane(dev_priv, plane, pipe); @@ -4724,31 +4725,43 @@ void intel_write_eld(struct drm_encoder *encoder, dev_priv->display.write_eld(connector, crtc); } -/** Loads the palette/gamma unit for the CRTC with the prepared values */ -void intel_crtc_load_lut(struct drm_crtc *crtc) +static void __intel_crtc_load_lut(struct intel_crtc *crtc, + void *data) { - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int palreg = PALETTE(intel_crtc->pipe); + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + int reg; int i; - /* The clocks have to be on to load the palette. */ - if (!crtc->enabled || !intel_crtc->active) + if (!crtc->base.enabled || !crtc->active) return; /* use legacy palette for Ironlake */ - if (HAS_PCH_SPLIT(dev)) - palreg = LGC_PALETTE(intel_crtc->pipe); + reg = PALETTE(crtc->pipe); + if (HAS_PCH_SPLIT(crtc->base.dev)) + reg = LGC_PALETTE(crtc->pipe); for (i = 0; i < 256; i++) { - I915_WRITE(palreg + 4 * i, - (intel_crtc->lut_r[i] << 16) | - (intel_crtc->lut_g[i] << 8) | - intel_crtc->lut_b[i]); + I915_WRITE(reg + 4 * i, + crtc->lut_r[i] << 16 | + crtc->lut_g[i] << 8 | + crtc->lut_b[i]); } } +/** Loads the palette/gamma unit for the CRTC with the prepared values */ +void intel_crtc_load_lut(struct drm_crtc *crtc) +{ + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + /* The clocks have to be on to load the palette. */ + if (!crtc->enabled || !intel_crtc->active) + return; + + if (intel_crtc_add_vblank_task(intel_crtc, true, + __intel_crtc_load_lut, NULL)) + __intel_crtc_load_lut(intel_crtc, NULL); +} + static void i845_update_cursor(struct drm_crtc *crtc, u32 base) { struct drm_device *dev = crtc->dev; @@ -5036,6 +5049,7 @@ static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, int end = (start + size > 256) ? 256 : start + size, i; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + /* We race here with setting the lut and reading it during vblank. */ for (i = start; i < end; i++) { intel_crtc->lut_r[i] = red[i] >> 8; intel_crtc->lut_g[i] = green[i] >> 8; -- 1.7.10