[Intel-gfx] [PATCH] drm/i915: add Intel specific initial config function

Jesse Barnes jbarnes at virtuousgeek.org
Fri Apr 3 01:36:44 CEST 2009


Fixed version against the updated can_grow patch I sent to Dave.

From 57865c555c65eb3c9be46b06e76e934c7d151e88 Mon Sep 17 00:00:00 2001
From: Jesse Barnes <jbarnes at virtuousgeek.org>
Date: Thu, 2 Apr 2009 14:55:19 -0700
Subject: [PATCH] drm/i915: add i915 specific initial configuration function

Pushing the initial configuration down into the driver makes it easier
to add platform specific default configuration algorithms, and and speed
up the boot process.

This patch adds an i915 specific initial config function which defaults
to using LVDS as the primary head, if present.  It also adds a new i915
module parameter, "primary", which can be used to specify an alternate
primary head to be used for the fb console, and panic and lastclose
configuration.  It takes a simple string indicating the preferred
connector, e.g.  "VGA-1" or "DVI-1".

Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
---
 drivers/gpu/drm/drm_crtc.c           |    6 +++-
 drivers/gpu/drm/drm_crtc_helper.c    |    3 +-
 drivers/gpu/drm/i915/i915_dma.c      |    2 +-
 drivers/gpu/drm/i915/i915_drv.h      |    1 +
 drivers/gpu/drm/i915/intel_display.c |   64 ++++++++++++++++++++++++++++++++++
 include/drm/drm_crtc_helper.h        |    1 +
 6 files changed, 74 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 94a7688..403e00d 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1283,10 +1283,14 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
 	out_resp->connector_id = connector->base.id;
 	out_resp->connector_type = connector->connector_type;
 	out_resp->connector_type_id = connector->connector_type_id;
+
+	/* These values should have been fetched by fill_modes from the EDID */
 	out_resp->mm_width = connector->display_info.width_mm;
 	out_resp->mm_height = connector->display_info.height_mm;
 	out_resp->subpixel = connector->display_info.subpixel_order;
-	out_resp->connection = connector->status;
+
+	/* Go see if it's there */
+	out_resp->connection = connector->funcs->detect(connector);
 	if (connector->encoder)
 		out_resp->encoder_id = connector->encoder->base.id;
 	else
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index e59746a..6f5cf94 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -391,7 +391,7 @@ out:
 	return best_score;
 }
 
-static void drm_setup_crtcs(struct drm_device *dev)
+void drm_setup_crtcs(struct drm_device *dev)
 {
 	struct drm_crtc **crtcs;
 	struct drm_display_mode **modes;
@@ -452,6 +452,7 @@ static void drm_setup_crtcs(struct drm_device *dev)
 	kfree(modes);
 	kfree(enabled);
 }
+EXPORT_SYMBOL(drm_setup_crtcs);
 
 /**
  * drm_encoder_crtc_ok - can a given crtc drive a given encoder?
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index c23b3a9..4e3262b 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1042,7 +1042,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
 
 	intel_modeset_init(dev);
 
-	drm_helper_initial_config(dev);
+	intel_initial_config(dev);
 
 	return 0;
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 317b122..e9de2c2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -680,6 +680,7 @@ static inline void opregion_enable_asle(struct drm_device *dev) { return; }
 /* modesetting */
 extern void intel_modeset_init(struct drm_device *dev);
 extern void intel_modeset_cleanup(struct drm_device *dev);
+extern void intel_initial_config(struct drm_device *dev);
 
 /**
  * Lock test for when it's just for synchronization of ring access.
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 64773ce..325d43b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2044,3 +2044,67 @@ struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
 
 	return &intel_output->enc;
 }
+
+static char *i915_primary;
+module_param_named(primary, i915_primary, charp, 0400);
+
+/**
+ * intel_initial_config - set up an initial configuration
+ * @dev: DRM device
+ *
+ * Create an initial configuration for use by the framebuffer driver.
+ * The main aim of this config is to make sure that kernel messages
+ * are visible.  This config will be used by both the framebuffer driver
+ * to create an initial console and by the panic & lastclose code to
+ * restore a usable configuration if something bad happens.
+ *
+ * Many platforms have a "primary" head, e.g. a laptop panel.  If possible,
+ * use the primary head as the default config.
+ *
+ * Allow the user to override the default with the "primary" module option.
+ *
+ * If the primary head (either the autodetected one or the user specified one)
+ * isn't available, fall back to the core, which will just try to light up
+ * as much as possible.
+ */
+void intel_initial_config(struct drm_device *dev)
+{
+	struct drm_connector *connector, *primary_head = NULL;
+	char *primary_name = "LVDS-1";
+	int width, height;
+
+	if (i915_primary)
+		primary_name = i915_primary;
+
+	width = dev->mode_config.max_width;
+	height = dev->mode_config.max_height;
+
+	/* First, find the "primary" head */
+	DRM_DEBUG("looking for primary head \"%s\"\n", primary_name);
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		if (!strcmp(drm_get_connector_name(connector), primary_name)) {
+			primary_head = connector;
+			break;
+		}
+	}
+
+	if (!primary_head)
+		goto fallback;
+
+	if (!drm_helper_probe_single_connector_modes(primary_head, width,
+						     height)) {
+		DRM_DEBUG("primary head \"%s\" has no modes, falling back\n",
+			  primary_name);
+		goto fallback;
+	}
+
+	drm_setup_crtcs(dev);
+	dev->mode_config.funcs->fb_changed(dev);
+
+	return;
+
+fallback:
+	DRM_DEBUG("primary head \"%s\" not found, using default\n",
+		  primary_name);
+	drm_helper_initial_config(dev);
+}
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index b672184..21cb8cb 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -94,6 +94,7 @@ extern void drm_helper_disable_unused_functions(struct drm_device *dev);
 extern int drm_helper_hotplug_stage_two(struct drm_device *dev);
 extern bool drm_helper_initial_config(struct drm_device *dev);
 extern int drm_crtc_helper_set_config(struct drm_mode_set *set);
+extern void drm_setup_crtcs(struct drm_device *dev);
 extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
 				     struct drm_display_mode *mode,
 				     int x, int y,
-- 
1.6.0.6



-- 
Jesse Barnes, Intel Open Source Technology Center



More information about the Intel-gfx mailing list