[Intel-gfx] [PATCH 26/43] drm: add initial_config function to fb helper and add i915 support

Chris Wilson chris at chris-wilson.co.uk
Fri May 25 14:33:05 CEST 2012


From: Jesse Barnes <jbarnes at virtuousgeek.org>

Rather than building a config which may or may not work, let the driver
build an initial fb config.  This allows the driver to use the BIOS boot
configuration for example, displaying kernel messages and the initial fb
console on the same outputs the BIOS lit up at boot time.  If that
fails, the driver can still fall back the same way as the core.

Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
---
 drivers/gpu/drm/drm_fb_helper.c |   29 +++++++++++++++++-------
 drivers/gpu/drm/i915/intel_fb.c |   47 +++++++++++++++++++++++++++++++++++++++
 include/drm/drm_fb_helper.h     |    4 ++++
 3 files changed, 72 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 6e19dd1..02f04d4 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1255,16 +1255,29 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
 
 	drm_enable_connectors(fb_helper, enabled);
 
-	ret = drm_target_cloned(fb_helper, modes, enabled, width, height);
-	if (!ret) {
-		ret = drm_target_preferred(fb_helper, modes, enabled, width, height);
-		if (!ret)
-			DRM_ERROR("Unable to find initial modes\n");
-	}
+	if (fb_helper->funcs->initial_config) {
+		fb_helper->funcs->initial_config(fb_helper, crtcs, modes,
+						 enabled, width, height);
+	} else {
+		/* clean out all the encoder/crtc combos */
+		list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+				    head)
+			encoder->crtc = NULL;
+
+		ret = drm_target_cloned(fb_helper, modes, enabled, width,
+					height);
+		if (!ret) {
+			ret = drm_target_preferred(fb_helper, modes, enabled,
+						   width, height);
+			if (!ret)
+				DRM_ERROR("Unable to find initial modes\n");
+		}
 
-	DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n", width, height);
+		DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n",
+			      width, height);
 
-	drm_pick_crtcs(fb_helper, crtcs, modes, 0, width, height);
+		drm_pick_crtcs(fb_helper, crtcs, modes, 0, width, height);
+	}
 
 	/* need to set the modesets up here for use later */
 	/* fill out the connector<->crtc mappings into the modesets */
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 9be61b5..0388677 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -203,10 +203,57 @@ static int intel_fb_find_or_create_single(struct drm_fb_helper *helper,
 	return new_fb;
 }
 
+static struct drm_fb_helper_crtc *intel_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc)
+{
+	int i;
+
+	for (i = 0; i < fb_helper->crtc_count; i++)
+		if (fb_helper->crtc_info[i].mode_set.crtc == crtc)
+			return &fb_helper->crtc_info[i];
+
+	return NULL;
+}
+
+static void intel_fb_initial_config(struct drm_fb_helper *fb_helper,
+				    struct drm_fb_helper_crtc **crtcs,
+				    struct drm_display_mode **modes,
+				    bool *enabled, int width, int height)
+{
+	struct drm_connector *connector;
+	struct drm_encoder *encoder;
+	int i;
+
+	for (i = 0; i < fb_helper->connector_count; i++) {
+		connector = fb_helper->connector_info[i]->connector;
+
+		if (!enabled[i]) {
+			DRM_DEBUG_KMS("connector %d not enabled, skipping\n",
+				      connector->base.id);
+			continue;
+		}
+
+		encoder = connector->encoder;
+		if (!encoder || !encoder->crtc) {
+			DRM_DEBUG_KMS("connector %d has no encoder or crtc, skipping\n",
+				      connector->base.id);
+			continue;
+		}
+
+		modes[i] = &encoder->crtc->mode;
+		crtcs[i] = intel_fb_helper_crtc(fb_helper, encoder->crtc);
+		DRM_DEBUG_KMS("fb crtc info: %p\n", crtcs[i]);
+		DRM_DEBUG_KMS("connector %s on crtc %d: %s\n",
+			      drm_get_connector_name(connector),
+			      encoder->crtc->base.id,
+			      modes[i] ? modes[i]->name : "off");
+	}
+}
+
 static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
 	.gamma_set = intel_crtc_fb_gamma_set,
 	.gamma_get = intel_crtc_fb_gamma_get,
 	.fb_probe = intel_fb_find_or_create_single,
+	.initial_config = intel_fb_initial_config,
 };
 
 static void intel_fbdev_destroy(struct drm_device *dev,
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 5120b01..dd98012 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -56,6 +56,10 @@ struct drm_fb_helper_funcs {
 
 	int (*fb_probe)(struct drm_fb_helper *helper,
 			struct drm_fb_helper_surface_size *sizes);
+	void (*initial_config)(struct drm_fb_helper *fb_helper,
+			       struct drm_fb_helper_crtc **crtcs,
+			       struct drm_display_mode **modes,
+			       bool *enabled, int width, int height);
 };
 
 struct drm_fb_helper_connector {
-- 
1.7.10




More information about the Intel-gfx mailing list