From 93766aa09f053d09b508df0fa1aabeff9a67438b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Rechi=20Vita?= Date: Wed, 9 Sep 2015 13:52:43 -0400 Subject: [PATCH 2/2] Revert "drm/i915: Use the disable callback for disabling planes." MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 27321ae88c70104df1ade701e079932b54360885. The reverted commit introduces a regression in both the EC-200 (Celeron N2807) and the ASUS-E202SA (Atom Cherryview), where the screen will remain black during the whole boot process, until any input action is performed on X (keypress, cursor movement etc). Signed-off-by: João Paulo Rechi Vita Conflicts: drivers/gpu/drm/i915/intel_display.c --- drivers/gpu/drm/i915/i915_drv.h | 5 -- drivers/gpu/drm/i915/intel_display.c | 90 ++++++++++++++++++++++++++++++------ 2 files changed, 76 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index fd1de45..48d7126 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -238,11 +238,6 @@ enum hpd_pin { #define for_each_crtc(dev, crtc) \ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) -#define for_each_intel_plane(dev, intel_plane) \ - list_for_each_entry(intel_plane, \ - &dev->mode_config.plane_list, \ - base.head) - #define for_each_intel_crtc(dev, intel_crtc) \ list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0ec2d99..5ac983e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2237,6 +2237,32 @@ static void intel_enable_primary_hw_plane(struct drm_plane *plane, crtc->x, crtc->y); } +/** + * intel_disable_primary_hw_plane - disable the primary hardware plane + * @plane: plane to be disabled + * @crtc: crtc for the plane + * + * Disable @plane on @crtc, making sure that the pipe is running first. + */ +static void intel_disable_primary_hw_plane(struct drm_plane *plane, + struct drm_crtc *crtc) +{ + struct drm_device *dev = plane->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + if (WARN_ON(!intel_crtc->active)) + return; + + if (!intel_crtc->primary_enabled) + return; + + intel_crtc->primary_enabled = false; + + dev_priv->display.update_primary_plane(crtc, plane->fb, + crtc->x, crtc->y); +} + static bool need_vtd_wa(struct drm_device *dev) { #ifdef CONFIG_INTEL_IOMMU @@ -4598,6 +4624,38 @@ static void intel_enable_sprite_planes(struct drm_crtc *crtc) } } +/* + * Disable a plane internally without actually modifying the plane's state. + * This will allow us to easily restore the plane later by just reprogramming + * its state. + */ +static void disable_plane_internal(struct drm_plane *plane) +{ + struct intel_plane *intel_plane = to_intel_plane(plane); + struct drm_plane_state *state = + plane->funcs->atomic_duplicate_state(plane); + struct intel_plane_state *intel_state = to_intel_plane_state(state); + + intel_state->visible = false; + intel_plane->commit_plane(plane, intel_state); + + intel_plane_destroy_state(plane, state); +} + +static void intel_disable_sprite_planes(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + enum pipe pipe = to_intel_crtc(crtc)->pipe; + struct drm_plane *plane; + struct intel_plane *intel_plane; + + drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { + intel_plane = to_intel_plane(plane); + if (plane->fb && intel_plane->pipe == pipe) + disable_plane_internal(plane); + } +} + void hsw_enable_ips(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; @@ -4851,7 +4909,6 @@ static void intel_crtc_disable_planes(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_plane *intel_plane; int pipe = intel_crtc->pipe; if (!intel_crtc->active) @@ -4863,14 +4920,9 @@ static void intel_crtc_disable_planes(struct drm_crtc *crtc) intel_crtc_dpms_overlay_disable(intel_crtc); intel_crtc->primary_enabled = false; - for_each_intel_plane(dev, intel_plane) { - if (intel_plane->pipe == pipe) { - struct drm_crtc *from = intel_plane->base.crtc; - - intel_plane->disable_plane(&intel_plane->base, - from ?: crtc, true); - } - } + intel_crtc_update_cursor(crtc, false); + intel_disable_sprite_planes(crtc); + intel_disable_primary_hw_plane(crtc->primary, crtc); /* * FIXME: Once we grow proper nuclear flip support out of this we need @@ -13327,14 +13379,24 @@ intel_commit_primary_plane(struct drm_plane *plane, crtc->y = src->y1 >> 16; if (intel_crtc->active) { - intel_crtc->primary_enabled = state->visible; - - if (state->visible) + if (state->visible) { /* FIXME: kill this fastboot hack */ intel_update_pipe_size(intel_crtc); - dev_priv->display.update_primary_plane(crtc, plane->fb, - crtc->x, crtc->y); + intel_crtc->primary_enabled = true; + + dev_priv->display.update_primary_plane(crtc, plane->fb, + crtc->x, crtc->y); + } else { + /* + * If clipping results in a non-visible primary plane, + * we'll disable the primary plane. Note that this is + * a bit different than what happens if userspace + * explicitly disables the plane by passing fb=0 + * because plane->fb still gets set and pinned. + */ + intel_disable_primary_hw_plane(plane, crtc); + } } } -- 2.1.4