patch to make KMS faster

Arjan van de Ven arjan at infradead.org
Sat Mar 14 16:20:18 PDT 2009


The patch below makes portions of the KMS code run asynchronous, making
the effect on start time a lot less...

comments?

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 94a7688..e24726b 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -458,7 +458,17 @@ void drm_connector_init(struct drm_device *dev,
 	INIT_LIST_HEAD(&connector->modes);
 	connector->edid_blob_ptr = NULL;
 
-	list_add_tail(&connector->head, &dev->mode_config.connector_list);
+	/*
+	 * we want LVDS to be in front; if it exists it's the primary screen
+	 * to initialize
+	 */
+
+	if (connector_type == DRM_MODE_CONNECTOR_LVDS)
+		list_add(&connector->head, &dev->mode_config.connector_list);
+	else
+		list_add_tail(&connector->head,
+				&dev->mode_config.connector_list);
+
 	dev->mode_config.num_connector++;
 
 	drm_connector_attach_property(connector,
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 1c3a8c5..12e54d1 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -29,6 +29,8 @@
  *      Jesse Barnes <jesse.barnes at intel.com>
  */
 
+#include <linux/async.h>
+
 #include "drmP.h"
 #include "drm_crtc.h"
 #include "drm_crtc_helper.h"
@@ -137,6 +139,23 @@ int drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX,
 }
 EXPORT_SYMBOL(drm_helper_probe_connector_modes);
 
+int drm_helper_probe_connector_modes_fast(struct drm_device *dev, uint32_t maxX,
+				      uint32_t maxY)
+{
+	struct drm_connector *connector;
+	int count = 0;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		count += drm_helper_probe_single_connector_modes(connector,
+								 maxX, maxY);
+		if (count > 0)
+			break;
+	}
+
+	return count;
+}
+EXPORT_SYMBOL(drm_helper_probe_connector_modes_fast);
+
 static void drm_helper_add_std_modes(struct drm_device *dev,
 				     struct drm_connector *connector)
 {
@@ -882,6 +901,24 @@ bool drm_helper_plugged_event(struct drm_device *dev)
 	/* FIXME: send hotplug event */
 	return true;
 }
+
+static void async_notify_fb_changed(void *data, async_cookie_t cookie)
+{
+	struct drm_device *dev = data;
+	dev->mode_config.funcs->fb_changed(dev);
+}
+
+static void async_probe_hard(void *data, async_cookie_t cookie)
+{
+	struct drm_device *dev = data;
+	/* Need to wait for async_notify_fb_changed to be done */
+	async_synchronize_cookie(cookie);
+	drm_helper_probe_connector_modes(dev,
+					dev->mode_config.max_width,
+					dev->mode_config.max_height);
+}
+
+
 /**
  * drm_initial_config - setup a sane initial connector configuration
  * @dev: DRM device
@@ -902,7 +939,7 @@ bool drm_helper_initial_config(struct drm_device *dev, bool can_grow)
 	struct drm_connector *connector;
 	int count = 0;
 
-	count = drm_helper_probe_connector_modes(dev,
+	count = drm_helper_probe_connector_modes_fast(dev,
 						 dev->mode_config.max_width,
 						 dev->mode_config.max_height);
 
@@ -921,7 +958,9 @@ bool drm_helper_initial_config(struct drm_device *dev, bool can_grow)
 	drm_setup_crtcs(dev);
 
 	/* alert the driver fb layer */
-	dev->mode_config.funcs->fb_changed(dev);
+	async_schedule(async_notify_fb_changed, dev);
+	/* probe further outputs */
+	async_schedule(async_probe_hard, dev);
 
 	return 0;
 }


-- 
Arjan van de Ven 	Intel Open Source Technology Centre
For development, discussion and tips for power savings, 
visit http://www.lesswatts.org


More information about the xorg-devel mailing list