xf86-video-intel: 5 commits - src/sna/kgem.c src/sna/sna_display.c src/uxa/intel_display.c src/uxa/intel_driver.c src/uxa/intel.h

Chris Wilson ickle at kemper.freedesktop.org
Sun Sep 7 10:46:58 PDT 2014


 src/sna/kgem.c          |    9 +
 src/sna/sna_display.c   |   40 ++++-
 src/uxa/intel.h         |    1 
 src/uxa/intel_display.c |  365 ++++++++++++++++++++++++++++++++++++++----------
 src/uxa/intel_driver.c  |    4 
 5 files changed, 341 insertions(+), 78 deletions(-)

New commits:
commit 908520a7dacade8b6716e7c30549847464a33a81
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Sep 3 10:43:21 2014 +1000

    uxa: add MST support.
    
    This adds MST support to the UXA paths in the driver.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    [ickle: Restore current output naming scheme]

diff --git a/src/uxa/intel.h b/src/uxa/intel.h
index 409635d..eebe08f 100644
--- a/src/uxa/intel.h
+++ b/src/uxa/intel.h
@@ -408,6 +408,7 @@ extern void intel_mode_remove_fb(intel_screen_private *intel);
 extern void intel_mode_close(intel_screen_private *intel);
 extern void intel_mode_fini(intel_screen_private *intel);
 extern int intel_mode_read_drm_events(intel_screen_private *intel);
+extern void intel_mode_hotplug(intel_screen_private *intel);
 
 typedef void (*intel_drm_handler_proc)(ScrnInfoPtr scrn,
                                        xf86CrtcPtr crtc,
diff --git a/src/uxa/intel_display.c b/src/uxa/intel_display.c
index 7cdb85f..c5f0620 100644
--- a/src/uxa/intel_display.c
+++ b/src/uxa/intel_display.c
@@ -94,6 +94,8 @@ struct intel_mode {
 	void *pageflip_data;
 	intel_pageflip_handler_proc pageflip_handler;
 	intel_pageflip_abort_proc pageflip_abort;
+
+	Bool delete_dp_12_displays;
 };
 
 struct intel_pageflip {
@@ -130,7 +132,7 @@ struct intel_output {
 	struct intel_mode *mode;
 	int output_id;
 	drmModeConnectorPtr mode_output;
-	drmModeEncoderPtr mode_encoder;
+	drmModeEncoderPtr *mode_encoders;
 	drmModePropertyBlobPtr edid_blob;
 	int num_props;
 	struct intel_property *props;
@@ -145,6 +147,8 @@ struct intel_output {
 	int backlight_active_level;
 	xf86OutputPtr output;
 	struct list link;
+	int enc_mask;
+	int enc_clone_mask;
 };
 
 static void
@@ -331,6 +335,9 @@ intel_crtc_apply(xf86CrtcPtr crtc)
 			continue;
 
 		intel_output = output->driver_private;
+		if (!intel_output->mode_output)
+			return FALSE;
+
 		output_ids[output_count] =
 			intel_output->mode_output->connector_id;
 		output_count++;
@@ -808,6 +815,11 @@ intel_output_attach_edid(xf86OutputPtr output)
 	xf86MonPtr mon = NULL;
 	int i;
 
+	if (!koutput) {
+		xf86OutputSetEDID(output, mon);
+		return;
+	}
+
 	/* look for an EDID property */
 	for (i = 0; i < koutput->count_props; i++) {
 		drmModePropertyPtr props;
@@ -897,6 +909,9 @@ intel_output_get_modes(xf86OutputPtr output)
 
 	intel_output_attach_edid(output);
 
+	if (!koutput)
+		return Modes;
+
 	/* modes should already be available */
 	for (i = 0; i < koutput->count_modes; i++) {
 		DisplayModePtr Mode;
@@ -949,7 +964,10 @@ intel_output_destroy(xf86OutputPtr output)
 		free(intel_output->props[i].atoms);
 	}
 	free(intel_output->props);
-
+	for (i = 0; i < intel_output->mode_output->count_encoders; i++) {
+		drmModeFreeEncoder(intel_output->mode_encoders[i]);
+	}
+	free(intel_output->mode_encoders);
 	drmModeFreeConnector(intel_output->mode_output);
 	intel_output->mode_output = NULL;
 
@@ -989,6 +1007,9 @@ intel_output_dpms(xf86OutputPtr output, int dpms)
 	struct intel_mode *mode = intel_output->mode;
 	int i;
 
+	if (!koutput)
+		return;
+
 	for (i = 0; i < koutput->count_props; i++) {
 		drmModePropertyPtr props;
 
@@ -1338,51 +1359,153 @@ static const char *output_names[] = {
 	"eDP",
 };
 
+static xf86OutputPtr find_output(ScrnInfoPtr pScrn, int id)
+{
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	int i;
+	for (i = 0; i < xf86_config->num_output; i++) {
+		xf86OutputPtr output = xf86_config->output[i];
+		struct intel_output *intel_output;
+
+		intel_output = output->driver_private;
+		if (intel_output->output_id == id)
+			return output;
+	}
+	return NULL;
+}
+
+static int parse_path_blob(drmModePropertyBlobPtr path_blob, int *conn_base_id, char **path)
+{
+	char *conn;
+	char conn_id[5];
+	int id, len;
+	char *blob_data;
+
+	if (!path_blob)
+		return -1;
+
+	blob_data = path_blob->data;
+	/* we only handle MST paths for now */
+	if (strncmp(blob_data, "mst:", 4))
+		return -1;
+
+	conn = strchr(blob_data + 4, '-');
+	if (!conn)
+		return -1;
+	len = conn - (blob_data + 4);
+	if (len + 1 > 5)
+		return -1;
+	memcpy(conn_id, blob_data + 4, len);
+	conn_id[len] = '\0';
+	id = strtoul(conn_id, NULL, 10);
+
+	*conn_base_id = id;
+
+	*path = conn + 1;
+	return 0;
+}
+
+static void
+drmmode_create_name(ScrnInfoPtr pScrn, drmModeConnectorPtr koutput, char *name,
+		    drmModePropertyBlobPtr path_blob)
+{
+	xf86OutputPtr output;
+	int conn_id;
+	char *extra_path;
+
+	output = NULL;
+	if (parse_path_blob(path_blob, &conn_id, &extra_path) == 0)
+		output = find_output(pScrn, conn_id);
+	if (output) {
+		snprintf(name, 32, "%s-%s", output->name, extra_path);
+	} else {
+		const char *output_name;
+
+		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);
+	}
+}
+
 static void
-intel_output_init(ScrnInfoPtr scrn, struct intel_mode *mode, drmModeResPtr mode_res, int num)
+intel_output_init(ScrnInfoPtr scrn, struct intel_mode *mode, drmModeResPtr mode_res, int num, int dynamic)
 {
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
 	xf86OutputPtr output;
 	drmModeConnectorPtr koutput;
-	drmModeEncoderPtr kencoder;
+	drmModeEncoderPtr *kencoders = NULL;
 	struct intel_output *intel_output;
-	const char *output_name;
 	char name[32];
+	drmModePropertyPtr props;
+	drmModePropertyBlobPtr path_blob = NULL;
+	int i;
 
 	koutput = drmModeGetConnector(mode->fd,
 				      mode_res->connectors[num]);
 	if (!koutput)
 		return;
+	for (i = 0; i < koutput->count_props; i++) {
+		props = drmModeGetProperty(mode->fd, koutput->props[i]);
+		if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
+			if (!strcmp(props->name, "PATH")) {
+				path_blob = drmModeGetPropertyBlob(mode->fd, koutput->prop_values[i]);
 
-	kencoder = drmModeGetEncoder(mode->fd, koutput->encoders[0]);
-	if (!kencoder) {
-		drmModeFreeConnector(koutput);
-		return;
+				drmModeFreeProperty(props);
+				break;
+			}
+			drmModeFreeProperty(props);
+		}
 	}
 
-	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);
+	drmmode_create_name(scrn, koutput, name, path_blob);
+	if (path_blob)
+		drmModeFreePropertyBlob(path_blob);
+
+	if (path_blob && dynamic) {
+		/* See if we have an output with this name already
+		 * and hook stuff up.
+		 */
+		for (i = 0; i < xf86_config->num_output; i++) {
+			output = xf86_config->output[i];
+
+			if (strncmp(output->name, name, 32))
+				continue;
+
+			intel_output = output->driver_private;
+			intel_output->output_id = mode_res->connectors[num];
+			intel_output->mode_output = koutput;
+			return;
+		}
+	}
+	kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders);
+	if (!kencoders) {
+		goto out_free_encoders;
+	}
+
+	for (i = 0; i < koutput->count_encoders; i++) {
+		kencoders[i] = drmModeGetEncoder(mode->fd, koutput->encoders[i]);
+		if (!kencoders[i])
+			goto out_free_encoders;
+	}
 
 	output = xf86OutputCreate (scrn, &intel_output_funcs, name);
 	if (!output) {
-		drmModeFreeEncoder(kencoder);
-		drmModeFreeConnector(koutput);
-		return;
+		goto out_free_encoders;
 	}
 
 	intel_output = calloc(sizeof(struct intel_output), 1);
 	if (!intel_output) {
 		xf86OutputDestroy(output);
-		drmModeFreeConnector(koutput);
-		drmModeFreeEncoder(kencoder);
-		return;
+		goto out_free_encoders;
 	}
 
 	intel_output->output_id = mode_res->connectors[num];
 	intel_output->mode_output = koutput;
-	intel_output->mode_encoder = kencoder;
+	intel_output->mode_encoders = kencoders;
 	intel_output->mode = mode;
 
 	output->mm_width = koutput->mmWidth;
@@ -1394,11 +1517,23 @@ intel_output_init(ScrnInfoPtr scrn, struct intel_mode *mode, drmModeResPtr mode_
 	if (is_panel(koutput->connector_type))
 		intel_output_backlight_init(output);
 
-	output->possible_crtcs = kencoder->possible_crtcs;
+	output->possible_crtcs = 0x7f;
+	for (i = 0; i < koutput->count_encoders; i++) {
+		output->possible_crtcs &= kencoders[i]->possible_crtcs;
+	}
 	output->interlaceAllowed = TRUE;
 
 	intel_output->output = output;
 	list_add(&intel_output->link, &mode->outputs);
+	return;
+
+out_free_encoders:
+	if (kencoders) {
+		for (i = 0; i < koutput->count_encoders; i++)
+			drmModeFreeEncoder(kencoders[i]);
+		free(kencoders);
+	}
+	drmModeFreeConnector(koutput);
 }
 
 static Bool
@@ -1962,57 +2097,63 @@ intel_mode_read_drm_events(struct intel_screen_private *intel)
 	return drmHandleEvent(mode->fd, &mode->event_context);
 }
 
-static drmModeEncoderPtr
-intel_get_kencoder(struct intel_mode *mode, drmModeResPtr mode_res, int num)
-{
-	struct intel_output *iterator;
-	int id = mode_res->encoders[num];
-
-	list_for_each_entry(iterator, &mode->outputs, link)
-		if (iterator->mode_encoder->encoder_id == id)
-			return iterator->mode_encoder;
-
-	return NULL;
-}
-
 /*
  * Libdrm's possible_clones is a mask of encoders, Xorg's possible_clones is a
  * mask of outputs. This function sets Xorg's possible_clones based on the
  * values read from libdrm.
  */
-static void
-intel_compute_possible_clones(ScrnInfoPtr scrn, struct intel_mode *mode, drmModeResPtr mode_res)
+static uint32_t find_clones(ScrnInfoPtr scrn, xf86OutputPtr output)
 {
-	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
-	struct intel_output *intel_output, *clone;
-	drmModeEncoderPtr cloned_encoder;
-	uint32_t mask;
-	int i, j, k;
-	CARD32 possible_clones;
+	struct intel_output *intel_output = output->driver_private, *clone_drmout;
+	int i;
+	xf86OutputPtr clone_output;
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+	int index_mask = 0;
 
-	for (i = 0; i < config->num_output; i++) {
-		possible_clones = 0;
-		intel_output = config->output[i]->driver_private;
+	if (intel_output->enc_clone_mask == 0)
+		return index_mask;
 
-		mask = intel_output->mode_encoder->possible_clones;
-		for (j = 0; mask != 0; j++, mask >>= 1) {
+	for (i = 0; i < xf86_config->num_output; i++) {
+		clone_output = xf86_config->output[i];
+		clone_drmout = clone_output->driver_private;
+		if (output == clone_output)
+			continue;
 
-			if ((mask & 1) == 0)
-				continue;
+		if (clone_drmout->enc_mask == 0)
+			continue;
+		if (intel_output->enc_clone_mask == clone_drmout->enc_mask)
+			index_mask |= (1 << i);
+	}
+	return index_mask;
+}
+static void
+intel_compute_possible_clones(ScrnInfoPtr scrn, struct intel_mode *mode, drmModeResPtr mode_res)
+{
+	int i, j;
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
 
-			cloned_encoder = intel_get_kencoder(mode, mode_res, j);
-			if (!cloned_encoder)
-				continue;
+	for (i = 0; i < xf86_config->num_output; i++) {
+		xf86OutputPtr output = xf86_config->output[i];
+		struct intel_output *intel_output;
 
-			for (k = 0; k < config->num_output; k++) {
-				clone = config->output[k]->driver_private;
-				if (clone->mode_encoder->encoder_id ==
-				    cloned_encoder->encoder_id)
-					possible_clones |= (1 << k);
+		intel_output = output->driver_private;
+		intel_output->enc_clone_mask = 0xff;
+		/* and all the possible encoder clones for this output together */
+		for (j = 0; j < intel_output->mode_output->count_encoders; j++)
+		{
+			int k;
+			for (k = 0; k < mode_res->count_encoders; k++) {
+				if (mode_res->encoders[k] == intel_output->mode_encoders[j]->encoder_id)
+					intel_output->enc_mask |= (1 << k);
 			}
+
+			intel_output->enc_clone_mask &= intel_output->mode_encoders[j]->possible_clones;
 		}
+	}
 
-		config->output[i]->possible_clones = possible_clones;
+	for (i = 0; i < xf86_config->num_output; i++) {
+		xf86OutputPtr output = xf86_config->output[i];
+		output->possible_clones = find_clones(scrn, output);
 	}
 }
 
@@ -2051,7 +2192,7 @@ Bool intel_mode_pre_init(ScrnInfoPtr scrn, int fd, int cpp)
 		intel_crtc_init(scrn, mode, mode_res, i);
 
 	for (i = 0; i < mode_res->count_connectors; i++)
-		intel_output_init(scrn, mode, mode_res, i);
+		intel_output_init(scrn, mode, mode_res, i, 0);
 
 	intel_compute_possible_clones(scrn, mode, mode_res);
 
@@ -2080,6 +2221,10 @@ Bool intel_mode_pre_init(ScrnInfoPtr scrn, int fd, int cpp)
 		intel->use_pageflipping = TRUE;
 	}
 
+	if (xf86ReturnOptValBool(intel->Options, OPTION_DELETE_DP12, FALSE)) {
+		mode->delete_dp_12_displays = TRUE;
+	}
+
 	intel->modes = mode;
 	drmModeFreeResources(mode_res);
 	return TRUE;
@@ -2332,3 +2477,76 @@ cleanup_dst:
 cleanup_src:
 	(*pScreen->DestroyPixmap)(src);
 }
+
+void
+intel_mode_hotplug(struct intel_screen_private *intel)
+{
+	ScrnInfoPtr scrn = intel->scrn;
+	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+	drmModeResPtr mode_res;
+	int i, j;
+	Bool found;
+	Bool changed = FALSE;
+	struct intel_mode *mode = intel->modes;
+	mode_res = drmModeGetResources(intel->drmSubFD);
+	if (!mode_res)
+		goto out;
+
+restart_destroy:
+	for (i = 0; i < config->num_output; i++) {
+		xf86OutputPtr output = config->output[i];
+		struct intel_output *intel_output;
+
+		intel_output = output->driver_private;
+		found = FALSE;
+		for (j = 0; j < mode_res->count_connectors; j++) {
+			if (mode_res->connectors[j] == intel_output->output_id) {
+				found = TRUE;
+				break;
+			}
+		}
+		if (found)
+			continue;
+
+		drmModeFreeConnector(intel_output->mode_output);
+		intel_output->mode_output = NULL;
+		intel_output->output_id = -1;
+
+		changed = TRUE;
+		if (mode->delete_dp_12_displays) {
+			RROutputDestroy(output->randr_output);
+			xf86OutputDestroy(output);
+			goto restart_destroy;
+		}
+	}
+
+	/* find new output ids we don't have outputs for */
+	for (i = 0; i < mode_res->count_connectors; i++) {
+		found = FALSE;
+
+		for (j = 0; j < config->num_output; j++) {
+			xf86OutputPtr output = config->output[j];
+			struct intel_output *intel_output;
+
+			intel_output = output->driver_private;
+			if (mode_res->connectors[i] == intel_output->output_id) {
+				found = TRUE;
+				break;
+			}
+		}
+		if (found)
+			continue;
+
+		changed = TRUE;
+		intel_output_init(scrn, intel->modes, mode_res, i, 1);
+	}
+
+	if (changed) {
+		RRSetChanged(xf86ScrnToScreen(scrn));
+		RRTellChanged(xf86ScrnToScreen(scrn));
+	}
+
+	drmModeFreeResources(mode_res);
+out:
+	RRGetInfo(xf86ScrnToScreen(scrn), TRUE);
+}
diff --git a/src/uxa/intel_driver.c b/src/uxa/intel_driver.c
index a7ca906..7877eb5 100644
--- a/src/uxa/intel_driver.c
+++ b/src/uxa/intel_driver.c
@@ -779,7 +779,9 @@ I830HandleUEvents(int fd, void *closure)
 
 	if (memcmp(&s.st_rdev, &udev_devnum, sizeof (dev_t)) == 0 &&
 			hotplug && atoi(hotplug) == 1)
-		RRGetInfo(xf86ScrnToScreen(scrn), TRUE);
+	{
+		intel_mode_hotplug(intel);
+	}
 
 	udev_device_unref(dev);
 }
commit b64a8f0e3e850e698a66e93fde36f846b39ea8cb
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Sep 3 10:43:20 2014 +1000

    uxa: drop mode_res caching.
    
    This will cause problems with MST displays which need to update the
    connector list after topology changes.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/uxa/intel_display.c b/src/uxa/intel_display.c
index 0b83140..7cdb85f 100644
--- a/src/uxa/intel_display.c
+++ b/src/uxa/intel_display.c
@@ -80,7 +80,6 @@ static struct list intel_drm_queue;
 struct intel_mode {
 	int fd;
 	uint32_t fb_id;
-	drmModeResPtr mode_res;
 	int cpp;
 
 	drmEventContext event_context;
@@ -706,7 +705,7 @@ static const xf86CrtcFuncsRec intel_crtc_funcs = {
 };
 
 static void
-intel_crtc_init(ScrnInfoPtr scrn, struct intel_mode *mode, int num)
+intel_crtc_init(ScrnInfoPtr scrn, struct intel_mode *mode, drmModeResPtr mode_res, int num)
 {
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 	xf86CrtcPtr crtc;
@@ -723,7 +722,7 @@ intel_crtc_init(ScrnInfoPtr scrn, struct intel_mode *mode, int num)
 	}
 
 	intel_crtc->mode_crtc = drmModeGetCrtc(mode->fd,
-					       mode->mode_res->crtcs[num]);
+					       mode_res->crtcs[num]);
 	if (intel_crtc->mode_crtc == NULL) {
 		free(intel_crtc);
 		return;
@@ -1340,7 +1339,7 @@ static const char *output_names[] = {
 };
 
 static void
-intel_output_init(ScrnInfoPtr scrn, struct intel_mode *mode, int num)
+intel_output_init(ScrnInfoPtr scrn, struct intel_mode *mode, drmModeResPtr mode_res, int num)
 {
 	xf86OutputPtr output;
 	drmModeConnectorPtr koutput;
@@ -1350,7 +1349,7 @@ intel_output_init(ScrnInfoPtr scrn, struct intel_mode *mode, int num)
 	char name[32];
 
 	koutput = drmModeGetConnector(mode->fd,
-				      mode->mode_res->connectors[num]);
+				      mode_res->connectors[num]);
 	if (!koutput)
 		return;
 
@@ -1381,7 +1380,7 @@ intel_output_init(ScrnInfoPtr scrn, struct intel_mode *mode, int num)
 		return;
 	}
 
-	intel_output->output_id = mode->mode_res->connectors[num];
+	intel_output->output_id = mode_res->connectors[num];
 	intel_output->mode_output = koutput;
 	intel_output->mode_encoder = kencoder;
 	intel_output->mode = mode;
@@ -1964,10 +1963,10 @@ intel_mode_read_drm_events(struct intel_screen_private *intel)
 }
 
 static drmModeEncoderPtr
-intel_get_kencoder(struct intel_mode *mode, int num)
+intel_get_kencoder(struct intel_mode *mode, drmModeResPtr mode_res, int num)
 {
 	struct intel_output *iterator;
-	int id = mode->mode_res->encoders[num];
+	int id = mode_res->encoders[num];
 
 	list_for_each_entry(iterator, &mode->outputs, link)
 		if (iterator->mode_encoder->encoder_id == id)
@@ -1982,7 +1981,7 @@ intel_get_kencoder(struct intel_mode *mode, int num)
  * values read from libdrm.
  */
 static void
-intel_compute_possible_clones(ScrnInfoPtr scrn, struct intel_mode *mode)
+intel_compute_possible_clones(ScrnInfoPtr scrn, struct intel_mode *mode, drmModeResPtr mode_res)
 {
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
 	struct intel_output *intel_output, *clone;
@@ -2001,7 +2000,7 @@ intel_compute_possible_clones(ScrnInfoPtr scrn, struct intel_mode *mode)
 			if ((mask & 1) == 0)
 				continue;
 
-			cloned_encoder = intel_get_kencoder(mode, j);
+			cloned_encoder = intel_get_kencoder(mode, mode_res, j);
 			if (!cloned_encoder)
 				continue;
 
@@ -2024,6 +2023,7 @@ Bool intel_mode_pre_init(ScrnInfoPtr scrn, int fd, int cpp)
 	struct intel_mode *mode;
 	unsigned int i;
 	int has_flipping;
+	drmModeResPtr mode_res;
 
 	mode = calloc(1, sizeof *mode);
 	if (!mode)
@@ -2037,23 +2037,23 @@ Bool intel_mode_pre_init(ScrnInfoPtr scrn, int fd, int cpp)
 	xf86CrtcConfigInit(scrn, &intel_xf86crtc_config_funcs);
 
 	mode->cpp = cpp;
-	mode->mode_res = drmModeGetResources(mode->fd);
-	if (!mode->mode_res) {
+	mode_res = drmModeGetResources(mode->fd);
+	if (!mode_res) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
 			   "failed to get resources: %s\n", strerror(errno));
 		free(mode);
 		return FALSE;
 	}
 
-	xf86CrtcSetSizeRange(scrn, 320, 200, mode->mode_res->max_width,
-			     mode->mode_res->max_height);
-	for (i = 0; i < mode->mode_res->count_crtcs; i++)
-		intel_crtc_init(scrn, mode, i);
+	xf86CrtcSetSizeRange(scrn, 320, 200, mode_res->max_width,
+			     mode_res->max_height);
+	for (i = 0; i < mode_res->count_crtcs; i++)
+		intel_crtc_init(scrn, mode, mode_res, i);
 
-	for (i = 0; i < mode->mode_res->count_connectors; i++)
-		intel_output_init(scrn, mode, i);
+	for (i = 0; i < mode_res->count_connectors; i++)
+		intel_output_init(scrn, mode, mode_res, i);
 
-	intel_compute_possible_clones(scrn, mode);
+	intel_compute_possible_clones(scrn, mode, mode_res);
 
 #ifdef INTEL_PIXMAP_SHARING
 	xf86ProviderSetup(scrn, NULL, "Intel");
@@ -2081,6 +2081,7 @@ Bool intel_mode_pre_init(ScrnInfoPtr scrn, int fd, int cpp)
 	}
 
 	intel->modes = mode;
+	drmModeFreeResources(mode_res);
 	return TRUE;
 }
 
commit aca0bf6387c159a3d54dbbe52dd65fd92df98216
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Sep 7 13:32:12 2014 +0100

    sna/gen2: Fallback to kernel batch w/a rather than incur a stall
    
    If we have no pinned batches available, use the kernel w/a if available
    rather than stall waiting for an active batch.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 6d4e074..aff0893 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3118,6 +3118,15 @@ out_16384:
 		if (bo)
 			return bo;
 
+		/* Nothing available for reuse, rely on the kernel wa */
+		if (kgem->has_pinned_batches) {
+			bo = kgem_create_linear(kgem, size, CREATE_CACHED | CREATE_TEMPORARY);
+			if (bo) {
+				kgem->batch_flags &= ~LOCAL_I915_EXEC_IS_PINNED;
+				return bo;
+			}
+		}
+
 		if (size < 16384) {
 			bo = list_first_entry(&kgem->pinned_batches[size > 4096],
 					      struct kgem_bo,
commit 57bf3d5f0fb4429b0991ad6f22000348820f5bd1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Sep 7 17:22:31 2014 +0100

    sna: Disable the fb on switching away from X
    
    Currently we turn off the CRTCs when switching away from X in order to
    not leak our framebuffer. With the new drm_plane support, we can simply
    unset the framebuffer, which should be a lighterweight operation than
    disabling the CRTC.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 2ba249a..46fd81f 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -6245,6 +6245,39 @@ void sna_mode_check(struct sna *sna)
 	update_flush_interval(sna);
 }
 
+static bool
+sna_crtc_hide_planes(struct sna *sna, struct sna_crtc *crtc)
+{
+#define LOCAL_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct local_mode_set_plane)
+	struct local_mode_set_plane {
+		uint32_t plane_id;
+		uint32_t crtc_id;
+		uint32_t fb_id; /* fb object contains surface format type */
+		uint32_t flags;
+
+		/* Signed dest location allows it to be partially off screen */
+		int32_t crtc_x, crtc_y;
+		uint32_t crtc_w, crtc_h;
+
+		/* Source values are 16.16 fixed point */
+		uint32_t src_x, src_y;
+		uint32_t src_h, src_w;
+	} s;
+
+	if (crtc->primary.id == 0)
+		return false;
+
+	memset(&s, 0, sizeof(s));
+	s.plane_id = crtc->primary.id;
+	if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s))
+		return false;
+
+	s.plane_id = crtc->sprite.id;
+	(void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s);
+
+	return true;
+}
+
 void sna_mode_reset(struct sna *sna)
 {
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
@@ -6257,7 +6290,8 @@ void sna_mode_reset(struct sna *sna)
 
 	sna_hide_cursors(sna->scrn);
 	for (i = 0; i < sna->mode.num_real_crtc; i++)
-		sna_crtc_disable(config->crtc[i]);
+		if (!sna_crtc_hide_planes(sna, to_sna_crtc(config->crtc[i])))
+			sna_crtc_disable(config->crtc[i]);
 	assert(sna->mode.front_active == 0);
 
 	for (i = 0; i < sna->mode.num_real_crtc; i++) {
commit c17d3b5d5cdbda510a2b6955c3a171457ecde7e5
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Sep 7 17:20:29 2014 +0100

    sna: Compute clones on final ordering
    
    The clones are indices into the output arrays, so recompute the clones
    if we reorder the outputs.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index c972e31..2ba249a 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -3874,6 +3874,7 @@ static void sort_config_outputs(struct sna *sna)
 {
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
 	qsort(config->output, sna->mode.num_real_output, sizeof(*config->output), output_rank);
+	sna_mode_compute_possible_outputs(sna);
 }
 
 static void sort_randr_outputs(struct sna *sna, ScreenPtr screen)
@@ -3999,7 +4000,6 @@ void sna_mode_discover(struct sna *sna)
 	if (changed) {
 		DBG(("%s: outputs changed, broadcasting\n", __FUNCTION__));
 
-		sna_mode_compute_possible_outputs(sna);
 		sna_mode_set_primary(sna);
 
 		/* Reorder user visible listing */
@@ -5671,8 +5671,6 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
 
 		sna->mode.num_real_output = xf86_config->num_output;
 
-		sna_mode_compute_possible_outputs(sna);
-
 		sna->mode.max_crtc_width  = res->max_width;
 		sna->mode.max_crtc_height = res->max_height;
 


More information about the xorg-commit mailing list