[Intel-gfx] [PATCH] CHROMIUM: Partial revert of 24929352481f085c5f85d4d4cbc919ddf106d381
james.ausmus at intel.com
james.ausmus at intel.com
Fri Aug 16 02:30:49 CEST 2013
From: Stéphane Marchesin <marcheu at chromium.org>
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
More information about the Intel-gfx
mailing list