[Intel-gfx] [PATCH 38/43] drm/i915: Disable unused CRTCs
Chris Wilson
chris at chris-wilson.co.uk
Fri May 25 14:33:17 CEST 2012
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 <chris at chris-wilson.co.uk>
---
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
More information about the Intel-gfx
mailing list