From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jesse Barnes Subject: [PATCH 1/2] drm/i915: wrap crtc enable/disable Date: Fri, 13 Dec 2013 11:26:52 -0800 Message-ID: <1386962813-2058-2-git-send-email-jbarnes@virtuousgeek.org> References: <1386962813-2058-1-git-send-email-jbarnes@virtuousgeek.org> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from alt-proxy31.mail.unifiedlayer.com (alt-proxy31.mail.unifiedlayer.com [74.220.221.129]) by gabe.freedesktop.org (Postfix) with SMTP id A6807FBB15 for ; Fri, 13 Dec 2013 11:26:58 -0800 (PST) Received: from [67.161.37.189] (port=48333 helo=localhost.localdomain) by box514.bluehost.com with esmtpsa (UNKNOWN:CAMELLIA256-SHA:256) (Exim 4.80) (envelope-from ) id 1VrYO1-000754-Nr for intel-gfx@lists.freedesktop.org; Fri, 13 Dec 2013 12:26:57 -0700 In-Reply-To: <1386962813-2058-1-git-send-email-jbarnes@virtuousgeek.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org To: intel-gfx@lists.freedesktop.org List-Id: intel-gfx@lists.freedesktop.org This allows us to hide queuing of enable/disable later. --- drivers/gpu/drm/i915/i915_drv.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 4 +- drivers/gpu/drm/i915/intel_display.c | 83 +++++++++++++++++++++++++++++------- drivers/gpu/drm/i915/intel_drv.h | 1 + 4 files changed, 71 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index af9fe02..8438e4e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -543,7 +543,7 @@ static int i915_drm_freeze(struct drm_device *dev) */ mutex_lock(&dev->mode_config.mutex); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - dev_priv->display.crtc_disable(crtc); + intel_queue_crtc_disable(crtc); mutex_unlock(&dev->mode_config.mutex); DRM_ERROR("disabled crtcs\n"); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index efc57fe..a1088fd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -407,8 +407,8 @@ struct drm_i915_display_funcs { int (*crtc_mode_set)(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb); - void (*crtc_enable)(struct drm_crtc *crtc); - void (*crtc_disable)(struct drm_crtc *crtc); + void (*_crtc_enable)(struct drm_crtc *crtc); + void (*_crtc_disable)(struct drm_crtc *crtc); void (*off)(struct drm_crtc *crtc); void (*write_eld)(struct drm_connector *connector, struct drm_crtc *crtc, diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e5c1850..006ec10 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1725,6 +1725,46 @@ static void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv) I915_WRITE(_TRANSA_CHICKEN2, val); } +static void intel_crtc_disable_work(struct work_struct *work) +{ + struct intel_crtc *intel_crtc = container_of(work, struct intel_crtc, + disable_work); +} + +void intel_queue_crtc_disable(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + queue_work(dev_priv->wq, &intel_crtc->disable_work); +} + +static void intel_crtc_enable_work(struct work_struct *work) +{ + struct intel_crtc *intel_crtc = container_of(work, struct intel_crtc, + enable_work); +} + +static void intel_queue_crtc_enable(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + queue_work(dev_priv->wq, &intel_crtc->enable_work); +} + +static void intel_sync_crtc(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + flush_work(&intel_crtc->disable_work); + flush_work(&intel_crtc->enable_work); +} + /** * intel_enable_pipe - enable a pipe, asserting requirements * @dev_priv: i915 private structure @@ -4288,7 +4328,6 @@ static void intel_crtc_update_sarea(struct drm_crtc *crtc, void intel_crtc_update_dpms(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; struct intel_encoder *intel_encoder; bool enable = false; @@ -4296,9 +4335,9 @@ void intel_crtc_update_dpms(struct drm_crtc *crtc) enable |= intel_encoder->connectors_active; if (enable) - dev_priv->display.crtc_enable(crtc); + intel_queue_crtc_enable(crtc); else - dev_priv->display.crtc_disable(crtc); + intel_queue_crtc_disable(crtc); intel_crtc_update_sarea(crtc, enable); } @@ -4313,7 +4352,7 @@ static void intel_crtc_disable(struct drm_crtc *crtc) /* crtc should still be enabled when we disable it. */ WARN_ON(!crtc->enabled); - dev_priv->display.crtc_disable(crtc); + dev_priv->display._crtc_disable(crtc); intel_crtc->eld_vld = false; intel_crtc_update_sarea(crtc, false); dev_priv->display.off(crtc); @@ -7519,6 +7558,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, goto fail; } + intel_sync_crtc(crtc); + /* we only need to pin inside GTT if cursor is non-phy */ mutex_lock(&dev->struct_mutex); if (!dev_priv->info->cursor_needs_physical) { @@ -7604,6 +7645,8 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) intel_crtc->cursor_x = clamp_t(int, x, SHRT_MIN, SHRT_MAX); intel_crtc->cursor_y = clamp_t(int, y, SHRT_MIN, SHRT_MAX); + intel_sync_crtc(crtc); + if (intel_crtc->active) intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL); @@ -8602,6 +8645,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, if (work == NULL) return -ENOMEM; + /* Complete any pending CRTC enable/disable */ + intel_sync_crtc(crtc); + work->event = event; work->crtc = crtc; work->old_fb_obj = to_intel_framebuffer(old_fb)->obj; @@ -9608,8 +9654,10 @@ static int __intel_set_mode(struct drm_crtc *crtc, intel_crtc_disable(&intel_crtc->base); for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) { - if (intel_crtc->base.enabled) - dev_priv->display.crtc_disable(&intel_crtc->base); + if (intel_crtc->base.enabled) { + intel_queue_crtc_disable(&intel_crtc->base); + intel_sync_crtc(&intel_crtc->base); + } } /* crtc->mode is already used by the ->mode_set callbacks, hence we need @@ -9641,7 +9689,7 @@ static int __intel_set_mode(struct drm_crtc *crtc, /* Now enable the clocks, plane, pipe, and connectors that we set up. */ for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) - dev_priv->display.crtc_enable(&intel_crtc->base); + intel_queue_crtc_enable(&intel_crtc->base); if (modeset_pipes) { /* Store real post-adjustment hardware mode. */ @@ -10145,6 +10193,9 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); + + INIT_WORK(intel_crtc->enable_work, intel_crtc_enable_work); + INIT_WORK(intel_crtc->disable_work, intel_crtc_disable_work); } enum pipe intel_get_pipe_from_connector(struct intel_connector *connector) @@ -10540,29 +10591,29 @@ static void intel_init_display(struct drm_device *dev) if (HAS_DDI(dev)) { dev_priv->display.get_pipe_config = haswell_get_pipe_config; dev_priv->display.crtc_mode_set = haswell_crtc_mode_set; - dev_priv->display.crtc_enable = haswell_crtc_enable; - dev_priv->display.crtc_disable = haswell_crtc_disable; + dev_priv->display._crtc_enable = haswell_crtc_enable; + dev_priv->display._crtc_disable = haswell_crtc_disable; dev_priv->display.off = haswell_crtc_off; dev_priv->display.update_plane = ironlake_update_plane; } else if (HAS_PCH_SPLIT(dev)) { dev_priv->display.get_pipe_config = ironlake_get_pipe_config; dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set; - dev_priv->display.crtc_enable = ironlake_crtc_enable; - dev_priv->display.crtc_disable = ironlake_crtc_disable; + dev_priv->display._crtc_enable = ironlake_crtc_enable; + dev_priv->display._crtc_disable = ironlake_crtc_disable; dev_priv->display.off = ironlake_crtc_off; dev_priv->display.update_plane = ironlake_update_plane; } else if (IS_VALLEYVIEW(dev)) { dev_priv->display.get_pipe_config = i9xx_get_pipe_config; dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; - dev_priv->display.crtc_enable = valleyview_crtc_enable; - dev_priv->display.crtc_disable = i9xx_crtc_disable; + dev_priv->display._crtc_enable = valleyview_crtc_enable; + dev_priv->display._crtc_disable = i9xx_crtc_disable; dev_priv->display.off = i9xx_crtc_off; dev_priv->display.update_plane = i9xx_update_plane; } else { dev_priv->display.get_pipe_config = i9xx_get_pipe_config; dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; - dev_priv->display.crtc_enable = i9xx_crtc_enable; - dev_priv->display.crtc_disable = i9xx_crtc_disable; + dev_priv->display._crtc_enable = i9xx_crtc_enable; + dev_priv->display._crtc_disable = i9xx_crtc_disable; dev_priv->display.off = i9xx_crtc_off; dev_priv->display.update_plane = i9xx_update_plane; } @@ -10953,7 +11004,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc) * ... */ plane = crtc->plane; crtc->plane = !plane; - dev_priv->display.crtc_disable(&crtc->base); + intel_queue_crtc_disable(&crtc->base); crtc->plane = plane; /* ... and break all links. */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ea62673..bfae2ef 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -707,6 +707,7 @@ void hsw_enable_ips(struct intel_crtc *crtc); void hsw_disable_ips(struct intel_crtc *crtc); void intel_display_set_init_power(struct drm_device *dev, bool enable); int valleyview_get_vco(struct drm_i915_private *dev_priv); +void intel_queue_crtc_disable(struct drm_crtc *crtc); /* intel_dp.c */ void intel_dp_init(struct drm_device *dev, int output_reg, enum port port); -- 1.8.4.2