From: Stéphane Marchesin <marcheu@xxxxxxxxxxxx> This is a partial revert of: drm/i915: read out the modeset hw state at load and resume time which fixes modeset on boot on alex on 3.8. BUG=chromium-os:38961 TEST=boot alex with 3.8, see a picture Change-Id: Id6efac800f4007ded759d237af5643d94ad839c3 --- drivers/gpu/drm/i915/intel_display.c | 105 ++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0bc822e..cc2db39 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7514,6 +7514,60 @@ free_work: return ret; } +static void intel_sanitize_modesetting(struct drm_device *dev, + int pipe, int plane) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + u32 reg, val; + int i; + + /* Clear any frame start delays used for debugging left by the BIOS */ + for_each_pipe(i) { + reg = PIPECONF(i); + I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); + } + + if (HAS_PCH_SPLIT(dev)) + return; + + /* Who knows what state these registers were left in by the BIOS or + * grub? + * + * If we leave the registers in a conflicting state (e.g. with the + * display plane reading from the other pipe than the one we intend + * to use) then when we attempt to teardown the active mode, we will + * not disable the pipes and planes in the correct order -- leaving + * a plane reading from a disabled pipe and possibly leading to + * undefined behaviour. + */ + + reg = DSPCNTR(plane); + val = I915_READ(reg); + + if ((val & DISPLAY_PLANE_ENABLE) == 0) + return; + if (!!(val & DISPPLANE_SEL_PIPE_MASK) == pipe) + return; + + /* This display plane is active and attached to the other CPU pipe. */ + pipe = !pipe; + + /* Disable the plane and wait for it to stop reading from the pipe. */ + intel_disable_plane(dev_priv, plane, pipe); + intel_disable_pipe(dev_priv, pipe); +} + +static void intel_crtc_reset(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + /* We need to fix up any BIOS configuration that conflicts with + * our expectations. + */ + intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); +} + static struct drm_crtc_helper_funcs intel_helper_funcs = { .mode_set_base_atomic = intel_pipe_set_base_atomic, .load_lut = intel_crtc_load_lut, @@ -8296,6 +8350,7 @@ out_config: } static const struct drm_crtc_funcs intel_crtc_funcs = { + .reset = intel_crtc_reset, .cursor_set = intel_crtc_cursor_set, .cursor_move = intel_crtc_cursor_move, .gamma_set = intel_crtc_gamma_set, @@ -9040,25 +9095,6 @@ static void intel_enable_pipe_a(struct drm_device *dev) } -static bool -intel_check_plane_mapping(struct intel_crtc *crtc) -{ - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - u32 reg, val; - - if (dev_priv->num_pipe == 1) - return true; - - reg = DSPCNTR(!crtc->plane); - val = I915_READ(reg); - - if ((val & DISPLAY_PLANE_ENABLE) && - (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe)) - return false; - - return true; -} - static void intel_sanitize_crtc(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; @@ -9069,37 +9105,6 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc) reg = PIPECONF(crtc->cpu_transcoder); I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); - /* We need to sanitize the plane -> pipe mapping first because this will - * disable the crtc (and hence change the state) if it is wrong. Note - * that gen4+ has a fixed plane -> pipe mapping. */ - if (INTEL_INFO(dev)->gen < 4 && !intel_check_plane_mapping(crtc)) { - struct intel_connector *connector; - bool plane; - - DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n", - crtc->base.base.id); - - /* Pipe has the wrong plane attached and the plane is active. - * Temporarily change the plane mapping and disable everything - * ... */ - plane = crtc->plane; - crtc->plane = !plane; - dev_priv->display.crtc_disable(&crtc->base); - crtc->plane = plane; - - /* ... and break all links. */ - list_for_each_entry(connector, &dev->mode_config.connector_list, - base.head) { - if (connector->encoder->base.crtc != &crtc->base) - continue; - - intel_connector_break_all_links(connector); - } - - WARN_ON(crtc->active); - crtc->base.enabled = false; - } - if (dev_priv->quirks & QUIRK_PIPEA_FORCE && crtc->pipe == PIPE_A && !crtc->active) { /* BIOS forgot to enable pipe A, this mostly happens after -- 1.8.3.2 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx