We need to turn off any CRTCs that may have been left on by the BIOS but
that we are not wrapping for KMS.

Signed-off-by: Chris Wilson <[email protected]>
---
 drivers/gpu/drm/i915/intel_fb.c |   75 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 72 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index e69567d..d234571 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -288,6 +288,69 @@ static void intel_fbdev_destroy(struct drm_device *dev,
        }
 }
 
+static bool
+_drm_is_crtc_connected(struct drm_device *dev, struct drm_crtc *crtc)
+{
+       struct drm_connector *connector;
+
+       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+               if (connector->encoder == NULL)
+                       continue;
+
+               if (connector->status != connector_status_connected)
+                       continue;
+
+               if (connector->encoder->crtc == crtc)
+                       return true;
+       }
+
+       return false;
+}
+
+static void
+_drm_encoder_disable(struct drm_encoder *encoder)
+{
+       struct drm_encoder_helper_funcs *encoder_funcs = 
encoder->helper_private;
+
+       if (encoder_funcs->disable)
+               (*encoder_funcs->disable)(encoder);
+       else
+               (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
+}
+
+static void
+_drm_crtc_disable(struct drm_crtc *crtc)
+{
+       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+
+       if (crtc_funcs->disable)
+               (*crtc_funcs->disable)(crtc);
+       else
+               (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
+
+       crtc->enabled = false;
+       crtc->fb = NULL;
+}
+
+static void
+_drm_disconnect_crtc(struct drm_device *dev, struct drm_crtc *crtc)
+{
+       struct drm_connector *connector;
+
+       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+               if (connector->encoder == NULL)
+                       continue;
+
+               if (connector->encoder->crtc == crtc) {
+                       _drm_encoder_disable(connector->encoder);
+                       connector->encoder->crtc = NULL;
+                       connector->encoder = NULL;
+               }
+       }
+
+       _drm_crtc_disable(crtc);
+}
+
 /*
  * Try to read the BIOS display configuration and use it for the initial
  * fb configuration.
@@ -325,8 +388,12 @@ void intel_fbdev_init_bios(struct drm_device *dev)
                u32 val, bpp, depth, offset;
                int pitch, width, height, size;
 
-               if (!intel_crtc->active) {
+               if (!intel_crtc->active || !_drm_is_crtc_connected(dev, crtc)) {
+disable_pipe:
                        DRM_DEBUG_KMS("pipe %d not active, skipping\n", pipe);
+                       intel_crtc->active = true; /* force disabling */
+                       _drm_disconnect_crtc(dev, crtc);
+                       intel_crtc->active = false; /* BUG_ON? */
                        continue;
                }
 
@@ -335,7 +402,7 @@ void intel_fbdev_init_bios(struct drm_device *dev)
                if (INTEL_INFO(dev)->gen >= 4) {
                        if (val & DISPPLANE_TILED) {
                                DRM_DEBUG_KMS("tiled BIOS fb?\n");
-                               continue; /* unexpected! */
+                               goto disable_pipe; /* unexpected! */
                        }
                }
 
@@ -364,7 +431,7 @@ void intel_fbdev_init_bios(struct drm_device *dev)
                        DRM_DEBUG_KMS("pipe %d has depth/bpp mismatch: "
                                      "(%d/%d vs %d/%d), skipping\n",
                                      pipe, bpp, depth, last_bpp, last_depth);
-                       continue;
+                       goto disable_pipe;
                }
 
                last_bpp = bpp;
@@ -469,6 +536,8 @@ out_free_ifbdev:
 out_fail:
        /* otherwise disable all the possible crtcs before KMS */
        drm_helper_disable_unused_functions(dev);
+       if (HAS_PCH_SPLIT(dev))
+               ironlake_init_pch_refclk(dev);
 }
 
 int intel_fbdev_init(struct drm_device *dev)
-- 
1.7.10

_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to