xf86-video-intel: 5 commits - src/intel_display.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Aug 4 02:08:13 PDT 2010


 src/intel_display.c |  156 ++++++++++++++++++++++++----------------------------
 1 file changed, 73 insertions(+), 83 deletions(-)

New commits:
commit 622e600069ab0efd22586c7a71eecbd4baf21c40
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Aug 4 09:57:12 2010 +0100

    display: Cache whether we have probed for an EDID
    
    Remember for the detection cycle whether we have already probed for the
    EDID -- as this can be slow.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/intel_display.c b/src/intel_display.c
index 1539976..061d222 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -82,6 +82,7 @@ struct intel_output {
 	int output_id;
 	drmModeConnectorPtr mode_output;
 	drmModeEncoderPtr mode_encoder;
+	Bool have_edid;
 	drmModePropertyBlobPtr edid_blob;
 	int num_props;
 	struct intel_property *props;
@@ -676,6 +677,8 @@ intel_output_detect(xf86OutputPtr output)
 	struct intel_mode *mode = intel_output->mode;
 	xf86OutputStatus status;
 
+	intel_output->have_edid = FALSE;
+
 	drmModeFreeConnector(intel_output->mode_output);
 	intel_output->mode_output =
 		drmModeGetConnector(mode->fd, intel_output->output_id);
@@ -767,40 +770,41 @@ intel_output_get_modes(xf86OutputPtr output)
 	struct intel_output *intel_output = output->driver_private;
 	drmModeConnectorPtr koutput = intel_output->mode_output;
 	struct intel_mode *mode = intel_output->mode;
-	int i;
 	DisplayModePtr Modes = NULL, Mode;
-	drmModePropertyPtr props;
 	drmModeModeInfo *mode_ptr;
+	int i;
 
-	/* look for an EDID property */
-	for (i = 0; i < koutput->count_props; i++) {
-		props = drmModeGetProperty(mode->fd, koutput->props[i]);
-		if (!props)
-			continue;
+	if (!intel_output->have_edid) {
+		/* look for an EDID property */
+		for (i = 0; i < koutput->count_props; i++) {
+			drmModePropertyPtr props;
+
+			props = drmModeGetProperty(mode->fd, koutput->props[i]);
+			if (!props)
+				continue;
+
+			if ((props->flags & DRM_MODE_PROP_BLOB) &&
+			    strcmp(props->name, "EDID") == 0) {
+				drmModeFreePropertyBlob(intel_output->edid_blob);
+				intel_output->edid_blob =
+					drmModeGetPropertyBlob(mode->fd,
+							       koutput->prop_values[i]);
+			}
 
-		if (!(props->flags & DRM_MODE_PROP_BLOB)) {
 			drmModeFreeProperty(props);
-			continue;
 		}
 
-		if (!strcmp(props->name, "EDID")) {
-			drmModeFreePropertyBlob(intel_output->edid_blob);
-			intel_output->edid_blob =
-				drmModeGetPropertyBlob(mode->fd,
-						       koutput->prop_values[i]);
-		}
-		drmModeFreeProperty(props);
+		if (intel_output->edid_blob)
+			xf86OutputSetEDID(output,
+					  xf86InterpretEDID(output->scrn->scrnIndex,
+							    intel_output->edid_blob->data));
+		else
+			xf86OutputSetEDID(output,
+					  xf86InterpretEDID(output->scrn->scrnIndex,
+							    NULL));
+		intel_output->have_edid = TRUE;
 	}
 
-	if (intel_output->edid_blob)
-		xf86OutputSetEDID(output,
-				  xf86InterpretEDID(output->scrn->scrnIndex,
-						    intel_output->edid_blob->data));
-	else
-		xf86OutputSetEDID(output,
-				  xf86InterpretEDID(output->scrn->scrnIndex,
-						    NULL));
-
 	/* modes should already be available */
 	for (i = 0; i < koutput->count_modes; i++) {
 		Mode = xnfalloc(sizeof(DisplayModeRec));
commit a6a707ca13097b85b319283b3a174b1986056ab8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Aug 4 09:54:28 2010 +0100

    display: Embed the lvds size into the connector
    
    Remove one very common allocation.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/intel_display.c b/src/intel_display.c
index e39bccb..1539976 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -77,11 +77,6 @@ struct intel_property {
 	Atom *atoms;
 };
 
-struct fixed_panel_lvds {
-	int hdisplay;
-	int vdisplay;
-};
-
 struct intel_output {
 	struct intel_mode *mode;
 	int output_id;
@@ -91,6 +86,11 @@ struct intel_output {
 	int num_props;
 	struct intel_property *props;
 	void *private_data;
+
+	Bool has_lvds_limits;
+	int lvds_hdisplay;
+	int lvds_vdisplay;
+
 	int dpms_mode;
 	const char *backlight_iface;
 	int backlight_active_level;
@@ -700,19 +700,18 @@ intel_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
 {
 	struct intel_output *intel_output = output->driver_private;
 	drmModeConnectorPtr koutput = intel_output->mode_output;
-	struct fixed_panel_lvds *p_lvds = intel_output->private_data;
 
 	/*
 	 * If the connector type is LVDS, we will use the panel limit to
 	 * verfiy whether the mode is valid.
 	 */
-	if ((koutput->connector_type == DRM_MODE_CONNECTOR_LVDS) && p_lvds) {
-		if (pModes->HDisplay > p_lvds->hdisplay ||
-		    pModes->VDisplay > p_lvds->vdisplay)
+	if (koutput->connector_type == DRM_MODE_CONNECTOR_LVDS &&
+	    intel_output->has_lvds_limits) {
+		if (pModes->HDisplay > intel_output->lvds_hdisplay ||
+		    pModes->VDisplay > intel_output->lvds_vdisplay)
 			return MODE_PANEL;
-		else
-			return MODE_OK;
 	}
+
 	return MODE_OK;
 }
 
@@ -771,7 +770,6 @@ intel_output_get_modes(xf86OutputPtr output)
 	int i;
 	DisplayModePtr Modes = NULL, Mode;
 	drmModePropertyPtr props;
-	struct fixed_panel_lvds *p_lvds;
 	drmModeModeInfo *mode_ptr;
 
 	/* look for an EDID property */
@@ -817,21 +815,20 @@ intel_output_get_modes(xf86OutputPtr output)
 	 * get the panel limit.
 	 * If it is incorrect, please fix me.
 	 */
-	p_lvds = intel_output->private_data;
-	if ((koutput->connector_type ==  DRM_MODE_CONNECTOR_LVDS) && p_lvds) {
-		p_lvds->hdisplay = 0;
-		p_lvds->vdisplay = 0;
+	intel_output->has_lvds_limits = FALSE;
+	if (koutput->connector_type == DRM_MODE_CONNECTOR_LVDS) {
 		for (i = 0; i < koutput->count_modes; i++) {
+
 			mode_ptr = &koutput->modes[i];
-			if ((mode_ptr->hdisplay >= p_lvds->hdisplay) &&
-			    (mode_ptr->vdisplay >= p_lvds->vdisplay)) {
-				p_lvds->hdisplay = mode_ptr->hdisplay;
-				p_lvds->vdisplay = mode_ptr->vdisplay;
-			}
+			if (mode_ptr->hdisplay > intel_output->lvds_hdisplay)
+				intel_output->lvds_hdisplay = mode_ptr->hdisplay;
+			if (mode_ptr->vdisplay > intel_output->lvds_vdisplay)
+				intel_output->lvds_vdisplay = mode_ptr->vdisplay;
 		}
-		if (!p_lvds->hdisplay || !p_lvds->vdisplay)
-			xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
-				   "Incorrect KMS mode.\n");
+
+		intel_output->has_lvds_limits =
+			intel_output->lvds_hdisplay &&
+			intel_output->lvds_vdisplay;
 	}
 
 	if (koutput->connector_type ==  DRM_MODE_CONNECTOR_LVDS)
@@ -858,11 +855,6 @@ intel_output_destroy(xf86OutputPtr output)
 	drmModeFreeConnector(intel_output->mode_output);
 	intel_output->mode_output = NULL;
 
-	if (intel_output->private_data) {
-		free(intel_output->private_data);
-		intel_output->private_data = NULL;
-	}
-
 	list_del(&intel_output->link);
 	free(intel_output);
 
@@ -1284,29 +1276,19 @@ intel_output_init(ScrnInfoPtr scrn, struct intel_mode *mode, int num)
 		drmModeFreeEncoder(kencoder);
 		return;
 	}
-	/*
-	 * If the connector type of the output device is LVDS, we will
-	 * allocate the private_data to store the panel limit.
-	 * For example: hdisplay, vdisplay
-	 */
-	intel_output->private_data = NULL;
-	if (koutput->connector_type ==  DRM_MODE_CONNECTOR_LVDS) {
-		intel_output->private_data = calloc(sizeof(struct fixed_panel_lvds), 1);
-		if (!intel_output->private_data)
-			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-				   "Can't allocate private memory for LVDS.\n");
-	}
+
 	intel_output->output_id = mode->mode_res->connectors[num];
 	intel_output->mode_output = koutput;
 	intel_output->mode_encoder = kencoder;
 	intel_output->mode = mode;
+
 	output->mm_width = koutput->mmWidth;
 	output->mm_height = koutput->mmHeight;
 
 	output->subpixel_order = subpixel_conv_table[koutput->subpixel];
 	output->driver_private = intel_output;
 
-	if (koutput->connector_type ==  DRM_MODE_CONNECTOR_LVDS)
+	if (koutput->connector_type == DRM_MODE_CONNECTOR_LVDS)
 		intel_output_backlight_init(output);
 
 	output->possible_crtcs = kencoder->possible_crtcs;
commit 6c7d105ccae32fba49a07a03b726cc3fe2de3d27
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Aug 4 09:51:34 2010 +0100

    display: Handle cursor error paths.
    
    Check that the cursor was allocated before freeing.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/intel_display.c b/src/intel_display.c
index bdf5b6c..e39bccb 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -468,7 +468,6 @@ intel_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
 	struct intel_crtc *intel_crtc = crtc->driver_private;
 	int ret;
 
-	/* cursor should be mapped already */
 	ret = dri_bo_subdata(intel_crtc->cursor, 0, 64*64*4, image);
 	if (ret)
 		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
@@ -612,8 +611,11 @@ intel_crtc_destroy(xf86CrtcPtr crtc)
 {
 	struct intel_crtc *intel_crtc = crtc->driver_private;
 
-	drm_intel_bo_unreference(intel_crtc->cursor);
-	intel_crtc->cursor = NULL;
+	if (intel_crtc->cursor) {
+		drmModeSetCursor(intel_crtc->mode->fd, crtc_id(intel_crtc), 0, 64, 64);
+		drm_intel_bo_unreference(intel_crtc->cursor);
+		intel_crtc->cursor = NULL;
+	}
 
 	list_del(&intel_crtc->link);
 	free(intel_crtc);
@@ -661,7 +663,6 @@ intel_crtc_init(ScrnInfoPtr scrn, struct intel_mode *mode, int num)
 	intel_crtc->cursor = drm_intel_bo_alloc(intel->bufmgr, "ARGB cursor",
 						HWCURSOR_SIZE_ARGB,
 						GTT_PAGE_SIZE);
-	drm_intel_bo_disable_reuse(intel_crtc->cursor);
 
 	intel_crtc->crtc = crtc;
 	list_add(&intel_crtc->link, &mode->crtcs);
commit 38f940dfea494d3093236f065392c431be06ae6e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Aug 4 09:50:14 2010 +0100

    display: Tidy backlight initialisation
    
    Mostly whitespace and a single error-code fix.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/intel_display.c b/src/intel_display.c
index e4961ea..bdf5b6c 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -171,9 +171,6 @@ intel_output_backlight_get(xf86OutputPtr output)
 	char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN];
 	int fd, level;
 
-	if (! intel_output->backlight_iface)
-		return -1;
-
 	sprintf(path, "%s/%s/actual_brightness",
 		BACKLIGHT_CLASS, intel_output->backlight_iface);
 	fd = open(path, O_RDONLY);
@@ -212,7 +209,7 @@ intel_output_backlight_get_max(xf86OutputPtr output)
 	if (fd == -1) {
 		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to open %s "
 			   "for backlight control: %s\n", path, strerror(errno));
-		return 0;
+		return -1;
 	}
 
 	memset(val, 0, sizeof(val));
@@ -225,7 +222,7 @@ intel_output_backlight_get_max(xf86OutputPtr output)
 
 	max = atoi(val);
 	if (max <= 0)
-		max  = -1;
+		max = -1;
 	return max;
 }
 
@@ -233,16 +230,17 @@ static void
 intel_output_backlight_init(xf86OutputPtr output)
 {
 	struct intel_output *intel_output = output->driver_private;
-	char path[BACKLIGHT_PATH_LEN];
-	struct stat buf;
 	int i;
 
 	for (i = 0; backlight_interfaces[i] != NULL; i++) {
+		char path[BACKLIGHT_PATH_LEN];
+		struct stat buf;
+
 		sprintf(path, "%s/%s", BACKLIGHT_CLASS, backlight_interfaces[i]);
 		if (!stat(path, &buf)) {
 			intel_output->backlight_iface = backlight_interfaces[i];
-			intel_output->backlight_max = intel_output_backlight_get_max(output);
 			intel_output->backlight_active_level = intel_output_backlight_get(output);
+			intel_output->backlight_max = intel_output_backlight_get_max(output);
 			if (intel_output->backlight_max > 0) {
 				xf86DrvMsg(output->scrn->scrnIndex, X_INFO,
 					   "found backlight control interface %s\n", path);
@@ -849,20 +847,20 @@ intel_output_destroy(xf86OutputPtr output)
 
 	if (intel_output->edid_blob)
 		drmModeFreePropertyBlob(intel_output->edid_blob);
+
 	for (i = 0; i < intel_output->num_props; i++) {
 		drmModeFreeProperty(intel_output->props[i].mode_prop);
 		free(intel_output->props[i].atoms);
 	}
 	free(intel_output->props);
+
 	drmModeFreeConnector(intel_output->mode_output);
 	intel_output->mode_output = NULL;
+
 	if (intel_output->private_data) {
 		free(intel_output->private_data);
 		intel_output->private_data = NULL;
 	}
-	if (intel_output->backlight_iface)
-		intel_output_backlight_set(output,
-					   intel_output->backlight_active_level);
 
 	list_del(&intel_output->link);
 	free(intel_output);
@@ -918,6 +916,7 @@ intel_output_dpms(xf86OutputPtr output, int dpms)
 			drmModeFreeProperty(props);
 			return;
 		}
+
 		drmModeFreeProperty(props);
 	}
 }
commit 2b7263b771d94401cb4ea6cbf4dc7a295eeda7c0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Aug 4 09:46:01 2010 +0100

    display: Check for buffer overrun in output name lookup.
    
    The kernel may know about more types than we do, so protect ourselves
    from reading from beyond the end of the string array.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/intel_display.c b/src/intel_display.c
index 276cd46..e4961ea 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -1250,6 +1250,7 @@ intel_output_init(ScrnInfoPtr scrn, struct intel_mode *mode, int num)
 	drmModeConnectorPtr koutput;
 	drmModeEncoderPtr kencoder;
 	struct intel_output *intel_output;
+	const char *output_name;
 	char name[32];
 
 	koutput = drmModeGetConnector(mode->fd,
@@ -1263,8 +1264,11 @@ intel_output_init(ScrnInfoPtr scrn, struct intel_mode *mode, int num)
 		return;
 	}
 
-	snprintf(name, 32, "%s%d", output_names[koutput->connector_type],
-		 koutput->connector_type_id);
+	if (koutput->connector_type < ARRAY_SIZE(output_names))
+		output_name = output_names[koutput->connector_type];
+	else
+		output_name = "UNKNOWN";
+	snprintf(name, 32, "%s%d", output_name, koutput->connector_type_id);
 
 	output = xf86OutputCreate (scrn, &intel_output_funcs, name);
 	if (!output) {


More information about the xorg-commit mailing list