xf86-video-amdgpu: Branch 'master' - 10 commits

Michel Dänzer daenzer at kemper.freedesktop.org
Mon Oct 5 00:42:35 PDT 2015


 src/amdgpu_dri2.c     |    2 
 src/amdgpu_drv.h      |    1 
 src/amdgpu_kms.c      |   71 +++++++++---
 src/amdgpu_probe.c    |   58 ++++++++--
 src/amdgpu_probe.h    |    6 +
 src/amdgpu_video.c    |   56 ++++------
 src/drmmode_display.c |  280 +++++++++++++++++++++++++++++++++++++++++++-------
 src/drmmode_display.h |    4 
 8 files changed, 376 insertions(+), 102 deletions(-)

New commits:
commit db3bb2061b9ac16b0922d9afae99874820356a04
Author: Tom St Denis <tom.stdenis at amd.com>
Date:   Tue Sep 29 13:07:04 2015 -0400

    Clean up allocation in AMDGPUInitVideo()
    
    The allocation of the adapters should use the correct sizeof (even if
    allocating an array of pointers).
    
    Signed-off-by: Tom St Denis <tom.stdenis at amd.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/src/amdgpu_video.c b/src/amdgpu_video.c
index 74e7c84..af34e10 100644
--- a/src/amdgpu_video.c
+++ b/src/amdgpu_video.c
@@ -136,7 +136,7 @@ void AMDGPUInitVideo(ScreenPtr pScreen)
 
 	num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
 	newAdaptors =
-	    malloc((num_adaptors + 2) * sizeof(XF86VideoAdaptorPtr *));
+	    malloc((num_adaptors + 2) * sizeof(*newAdaptors));
 	if (newAdaptors == NULL)
 		return;
 
commit 94caf7ac777134b8396aa762a506053179bbb4c6
Author: Tom St Denis <tom.stdenis at amd.com>
Date:   Thu Oct 1 13:08:41 2015 -0400

    Avoid leaking memory on output.
    
    Based on radeon commit 63dc36dc49f93cb00111b497ab6805194bc9d240
    
    and 2nd patch:
    
    Proper leak fix, previous leak fix was bogus.
    
    Based on radeon commit b8ec9ed4fe86952763b963c86f0af0dcae69aa6c
    
    Signed-off-by: Tom St Denis <tom.stdenis at amd.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 4cb1ba4..7328bfd 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1498,6 +1498,10 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r
 			drmmode_output = output->driver_private;
 			drmmode_output->output_id = mode_res->connectors[num];
 			drmmode_output->mode_output = koutput;
+			for (i = 0; i < koutput->count_encoders; i++) {
+				drmModeFreeEncoder(kencoders[i]);
+			}
+			free(kencoders);
 			return 1;
 		}
 	}
commit f035faec041cb5df65c78effa58eb50197cedf88
Author: Tom St Denis <tom.stdenis at amd.com>
Date:   Thu Oct 1 12:56:05 2015 -0400

    add support for DP 1.2 display hotplug
    
    Based on radeon commit 2f11dcd43966cf2ee26e61960fd72e6644f5e037
    
    > This allows for dynamic creation of conneectors when the
    > kernel tells us.
    >
    > v2: fix dpms off crash
    
    Signed-off-by: Tom St Denis <tom.stdenis at amd.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h
index 82dd05b..ff3bc02 100644
--- a/src/amdgpu_drv.h
+++ b/src/amdgpu_drv.h
@@ -145,6 +145,7 @@ typedef enum {
 	OPTION_DRI,
 	OPTION_SHADOW_PRIMARY,
 	OPTION_TEAR_FREE,
+	OPTION_DELETE_DP12,
 } AMDGPUOpts;
 
 #define AMDGPU_VSYNC_TIMEOUT	20000	/* Maximum wait for VSYNC (in usecs) */
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 5ee53fb..19ee1b1 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -70,6 +70,7 @@ const OptionInfoRec AMDGPUOptions_KMS[] = {
 	{OPTION_DRI, "DRI", OPTV_INTEGER, {0}, FALSE},
 	{OPTION_SHADOW_PRIMARY, "ShadowPrimary", OPTV_BOOLEAN, {0}, FALSE},
 	{OPTION_TEAR_FREE, "TearFree", OPTV_BOOLEAN, {0}, FALSE},
+	{OPTION_DELETE_DP12, "DeleteUnusedDP12Displays", OPTV_BOOLEAN, {0}, FALSE},
 	{-1, NULL, OPTV_NONE, {0}, FALSE}
 };
 
@@ -825,6 +826,10 @@ Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 			   info->allowPageFlip ? "en" : "dis");
 	}
 
+	if (xf86ReturnOptValBool(info->Options, OPTION_DELETE_DP12, FALSE)) {
+		info->drmmode.delete_dp_12_displays = TRUE;
+	}
+
 	if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) ==
 	    FALSE) {
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 7f4e0c9..4cb1ba4 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -431,7 +431,7 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 
 static void
 drmmode_crtc_scanout_destroy(drmmode_ptr drmmode,
-                             struct drmmode_scanout *scanout)
+			     struct drmmode_scanout *scanout)
 {
 
 	if (scanout->pixmap) {
@@ -471,8 +471,8 @@ drmmode_scanout_free(ScrnInfoPtr scrn)
 
 static void *
 drmmode_crtc_scanout_allocate(xf86CrtcPtr crtc,
-                              struct drmmode_scanout *scanout,
-                              int width, int height)
+			      struct drmmode_scanout *scanout,
+			      int width, int height)
 {
 	ScrnInfoPtr pScrn = crtc->scrn;
 	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
@@ -520,8 +520,8 @@ drmmode_crtc_scanout_allocate(xf86CrtcPtr crtc,
 
 static PixmapPtr
 drmmode_crtc_scanout_create(xf86CrtcPtr crtc,
-                            struct drmmode_scanout *scanout,
-                            void *data, int width, int height)
+			    struct drmmode_scanout *scanout,
+			    void *data, int width, int height)
 {
 	ScrnInfoPtr pScrn = crtc->scrn;
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
@@ -548,7 +548,7 @@ drmmode_crtc_scanout_create(xf86CrtcPtr crtc,
 						 scanout->bo);
 	if (scanout->pixmap == NULL) {
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		           "Couldn't allocate shadow pixmap for rotated CRTC\n");
+			   "Couldn't allocate shadow pixmap for rotated CRTC\n");
 	}
 	return scanout->pixmap;
 
@@ -1337,56 +1337,114 @@ const char *output_names[] = { "None",
 
 #define NUM_OUTPUT_NAMES (sizeof(output_names) / sizeof(output_names[0]))
 
+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];
+		drmmode_output_private_ptr drmmode_output;
+		drmmode_output = output->driver_private;
+		if (drmmode_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,
-		    int *num_dvi, int *num_hdmi)
+		    drmModePropertyBlobPtr path_blob, int *num_dvi, int *num_hdmi)
 {
-	if (koutput->connector_type >= NUM_OUTPUT_NAMES)
-		snprintf(name, 32, "Unknown%d-%d", koutput->connector_type, koutput->connector_type_id - 1);
+	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 {
+		if (koutput->connector_type >= NUM_OUTPUT_NAMES)
+			snprintf(name, 32, "Unknown%d-%d", koutput->connector_type, koutput->connector_type_id - 1);
 #ifdef AMDGPU_PIXMAP_SHARING
-	else if (pScrn->is_gpu)
-		snprintf(name, 32, "%s-%d-%d", output_names[koutput->connector_type],
-			 pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1, koutput->connector_type_id - 1);
+		else if (pScrn->is_gpu)
+			snprintf(name, 32, "%s-%d-%d", output_names[koutput->connector_type],
+				 pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1, koutput->connector_type_id - 1);
 #endif
-	else {
-		/* need to do smart conversion here for compat with non-kms ATI driver */
-		if (koutput->connector_type_id == 1) {
-			switch(koutput->connector_type) {
-			case DRM_MODE_CONNECTOR_DVII:
-			case DRM_MODE_CONNECTOR_DVID:
-			case DRM_MODE_CONNECTOR_DVIA:
-				snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], *num_dvi);
-				(*num_dvi)++;
-				break;
-			case DRM_MODE_CONNECTOR_HDMIA:
-			case DRM_MODE_CONNECTOR_HDMIB:
-				snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], *num_hdmi);
-				(*num_hdmi)++;
-				break;
-			case DRM_MODE_CONNECTOR_VGA:
-			case DRM_MODE_CONNECTOR_DisplayPort:
+		else {
+			/* need to do smart conversion here for compat with non-kms ATI driver */
+			if (koutput->connector_type_id == 1) {
+				switch(koutput->connector_type) {
+				case DRM_MODE_CONNECTOR_DVII:
+				case DRM_MODE_CONNECTOR_DVID:
+				case DRM_MODE_CONNECTOR_DVIA:
+					snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], *num_dvi);
+					(*num_dvi)++;
+					break;
+				case DRM_MODE_CONNECTOR_HDMIA:
+				case DRM_MODE_CONNECTOR_HDMIB:
+					snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], *num_hdmi);
+					(*num_hdmi)++;
+					break;
+				case DRM_MODE_CONNECTOR_VGA:
+				case DRM_MODE_CONNECTOR_DisplayPort:
+					snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1);
+					break;
+				default:
+					snprintf(name, 32, "%s", output_names[koutput->connector_type]);
+					break;
+				}
+			} else {
 				snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1);
-				break;
-			default:
-				snprintf(name, 32, "%s", output_names[koutput->connector_type]);
-				break;
 			}
-		} else {
-			snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1);
 		}
 	}
 }
 
 
 static unsigned int
-drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, int *num_dvi, int *num_hdmi)
+drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, int *num_dvi, int *num_hdmi, int dynamic)
 {
+	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
 	xf86OutputPtr output;
 	drmModeConnectorPtr koutput;
 	drmModeEncoderPtr *kencoders = NULL;
 	drmmode_output_private_ptr drmmode_output;
 	drmModePropertyPtr props;
+	drmModePropertyBlobPtr path_blob = NULL;
 	char name[32];
 	int i;
 	const char *s;
@@ -1397,6 +1455,18 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r
 	if (!koutput)
 		return 0;
 
+	for (i = 0; i < koutput->count_props; i++) {
+		props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
+		if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
+			if (!strcmp(props->name, "PATH")) {
+				path_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
+				drmModeFreeProperty(props);
+				break;
+			}
+			drmModeFreeProperty(props);
+		}
+	}
+
 	kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders);
 	if (!kencoders) {
 		goto out_free_encoders;
@@ -1410,7 +1480,27 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r
 		}
 	}
 
-	drmmode_create_name(pScrn, koutput, name, num_dvi, num_hdmi);
+	drmmode_create_name(pScrn, koutput, name, path_blob, num_dvi, num_hdmi);
+	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;
+
+			drmmode_output = output->driver_private;
+			drmmode_output->output_id = mode_res->connectors[num];
+			drmmode_output->mode_output = koutput;
+			return 1;
+		}
+	}
 
 	if (xf86IsEntityShared(pScrn->entityList[0])) {
 		if ((s =
@@ -1468,6 +1558,11 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r
 		}
 	}
 
+	if (dynamic) {
+		output->randr_output = RROutputCreate(xf86ScrnToScreen(pScrn), output->name, strlen(output->name), output);
+		drmmode_output_create_resources(output);
+	}
+
 	return 1;
 out_free_encoders:
 	if (kencoders) {
@@ -1778,7 +1873,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
 	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
 		       "Initializing outputs ...\n");
 	for (i = 0; i < mode_res->count_connectors; i++)
-		crtcs_needed += drmmode_output_init(pScrn, drmmode, mode_res, i, &num_dvi, &num_hdmi);
+		crtcs_needed += drmmode_output_init(pScrn, drmmode, mode_res, i, &num_dvi, &num_hdmi, 0);
 
 	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
 		       "%d crtcs needed for screen.\n", crtcs_needed);
@@ -2022,6 +2117,77 @@ Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn)
 	return TRUE;
 }
 
+
+void
+amdgpu_mode_hotplug(ScrnInfoPtr scrn, drmmode_ptr drmmode)
+{
+	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+	drmModeResPtr mode_res;
+	int i, j;
+	Bool found;
+	Bool changed = FALSE;
+
+	mode_res = drmModeGetResources(drmmode->fd);
+	if (!mode_res)
+		goto out;
+
+restart_destroy:
+	for (i = 0; i < config->num_output; i++) {
+		xf86OutputPtr output = config->output[i];
+		drmmode_output_private_ptr drmmode_output = output->driver_private;
+		found = FALSE;
+		for (j = 0; j < mode_res->count_connectors; j++) {
+			if (mode_res->connectors[j] == drmmode_output->output_id) {
+				found = TRUE;
+				break;
+			}
+		}
+		if (found)
+			continue;
+
+		drmModeFreeConnector(drmmode_output->mode_output);
+		drmmode_output->mode_output = NULL;
+		drmmode_output->output_id = -1;
+
+		changed = TRUE;
+		if (drmmode->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];
+			drmmode_output_private_ptr drmmode_output;
+
+			drmmode_output = output->driver_private;
+			if (mode_res->connectors[i] == drmmode_output->output_id) {
+				found = TRUE;
+				break;
+			}
+		}
+		if (found)
+			continue;
+
+		changed = TRUE;
+		drmmode_output_init(scrn, drmmode, mode_res, i, NULL, NULL, 1);
+	}
+
+	if (changed) {
+		RRSetChanged(xf86ScrnToScreen(scrn));
+		RRTellChanged(xf86ScrnToScreen(scrn));
+	}
+
+	drmModeFreeResources(mode_res);
+out:
+	RRGetInfo(xf86ScrnToScreen(scrn), TRUE);
+}
+
 #ifdef HAVE_LIBUDEV
 static void drmmode_handle_uevents(int fd, void *closure)
 {
@@ -2032,7 +2198,7 @@ static void drmmode_handle_uevents(int fd, void *closure)
 	if (!dev)
 		return;
 
-	RRGetInfo(xf86ScrnToScreen(scrn), TRUE);
+	amdgpu_mode_hotplug(scrn, drmmode);
 	udev_device_unref(dev);
 }
 #endif
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 9c95c14..177dfc7 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -52,6 +52,8 @@ typedef struct {
 #endif
 	drmEventContext event_context;
 	int count_crtcs;
+
+	Bool delete_dp_12_displays;
 } drmmode_rec, *drmmode_ptr;
 
 typedef struct {
commit aee72b29210d79dbf41bde6eef16d7fe817e6cf4
Author: Tom St Denis <tom.stdenis at amd.com>
Date:   Thu Oct 1 12:29:36 2015 -0400

    move output name creation to its own function
    
    Based on radeon commit c88424d1f4aaa78b569e5d44f0b4a47de2f422f4
    
    > The secondary indent is deliberate to make the next patch more
    > parseable for mst support.
    
    Signed-off-by:  Tom St Denis <tom.stdenis at amd.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index e4b79b6..7f4e0c9 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1337,6 +1337,47 @@ const char *output_names[] = { "None",
 
 #define NUM_OUTPUT_NAMES (sizeof(output_names) / sizeof(output_names[0]))
 
+static void
+drmmode_create_name(ScrnInfoPtr pScrn, drmModeConnectorPtr koutput, char *name,
+		    int *num_dvi, int *num_hdmi)
+{
+	if (koutput->connector_type >= NUM_OUTPUT_NAMES)
+		snprintf(name, 32, "Unknown%d-%d", koutput->connector_type, koutput->connector_type_id - 1);
+#ifdef AMDGPU_PIXMAP_SHARING
+	else if (pScrn->is_gpu)
+		snprintf(name, 32, "%s-%d-%d", output_names[koutput->connector_type],
+			 pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1, koutput->connector_type_id - 1);
+#endif
+	else {
+		/* need to do smart conversion here for compat with non-kms ATI driver */
+		if (koutput->connector_type_id == 1) {
+			switch(koutput->connector_type) {
+			case DRM_MODE_CONNECTOR_DVII:
+			case DRM_MODE_CONNECTOR_DVID:
+			case DRM_MODE_CONNECTOR_DVIA:
+				snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], *num_dvi);
+				(*num_dvi)++;
+				break;
+			case DRM_MODE_CONNECTOR_HDMIA:
+			case DRM_MODE_CONNECTOR_HDMIB:
+				snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], *num_hdmi);
+				(*num_hdmi)++;
+				break;
+			case DRM_MODE_CONNECTOR_VGA:
+			case DRM_MODE_CONNECTOR_DisplayPort:
+				snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1);
+				break;
+			default:
+				snprintf(name, 32, "%s", output_names[koutput->connector_type]);
+				break;
+			}
+		} else {
+			snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1);
+		}
+	}
+}
+
+
 static unsigned int
 drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, int *num_dvi, int *num_hdmi)
 {
@@ -1369,20 +1410,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r
 		}
 	}
 
-	if (koutput->connector_type >= NUM_OUTPUT_NAMES)
-		snprintf(name, 32, "Unknown%d-%d", koutput->connector_type,
-			 koutput->connector_type_id - 1);
-#ifdef AMDGPU_PIXMAP_SHARING
-	else if (pScrn->is_gpu)
-		snprintf(name, 32, "%s-%d-%d",
-			 output_names[koutput->connector_type],
-			 pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1,
-			 koutput->connector_type_id - 1);
-#endif
-	else
-		snprintf(name, 32, "%s-%d",
-			 output_names[koutput->connector_type],
-			 koutput->connector_type_id - 1);
+	drmmode_create_name(pScrn, koutput, name, num_dvi, num_hdmi);
 
 	if (xf86IsEntityShared(pScrn->entityList[0])) {
 		if ((s =
commit 0846abeace649d27a5f2c17373e717f92d246797
Author: Tom St Denis <tom.stdenis at amd.com>
Date:   Thu Oct 1 12:13:21 2015 -0400

    stop caching mode resources
    
    Based on radeon commit 32b003cb7657e07d5af6338ad44d768eda87fd33
    
    > This is step one towards MST connector hotplug support,
    > it stop caching the mode resources structure, and
    > just passes a pointer to it around.
    
    With a few tweaks to match the state of the AMDGPU tree.
    
    Signed-off-by: Tom St Denis <tom.stdenis at amd.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index 0d9323b..1370551 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -1419,7 +1419,7 @@ Bool amdgpu_dri2_screen_init(ScreenPtr pScreen)
 	dri2_info.DestroyBuffer = amdgpu_dri2_destroy_buffer;
 	dri2_info.CopyRegion = amdgpu_dri2_copy_region;
 
-	if (info->drmmode.mode_res->count_crtcs > 2) {
+	if (info->drmmode.count_crtcs > 2) {
 #ifdef DRM_CAP_VBLANK_HIGH_CRTC
 		uint64_t cap_value;
 
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 611d8e1..5ee53fb 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -832,7 +832,7 @@ Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 		goto fail;
 	}
 
-	if (info->drmmode.mode_res->count_crtcs == 1)
+	if (info->drmmode.count_crtcs == 1)
 		pAMDGPUEnt->HasCRTC2 = FALSE;
 	else
 		pAMDGPUEnt->HasCRTC2 = TRUE;
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 0af5044..e4b79b6 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -954,7 +954,8 @@ void drmmode_crtc_hw_id(xf86CrtcPtr crtc)
 		drmmode_crtc->hw_id = -1;
 }
 
-static unsigned int drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
+static unsigned int
+drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num)
 {
 	xf86CrtcPtr crtc;
 	drmmode_crtc_private_ptr drmmode_crtc;
@@ -966,7 +967,7 @@ static unsigned int drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, in
 
 	drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
 	drmmode_crtc->mode_crtc =
-	    drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]);
+	    drmModeGetCrtc(drmmode->fd, mode_res->crtcs[num]);
 	drmmode_crtc->drmmode = drmmode;
 	crtc->driver_private = drmmode_crtc;
 	drmmode_crtc_hw_id(crtc);
@@ -1337,7 +1338,7 @@ const char *output_names[] = { "None",
 #define NUM_OUTPUT_NAMES (sizeof(output_names) / sizeof(output_names[0]))
 
 static unsigned int
-drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
+drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, int *num_dvi, int *num_hdmi)
 {
 	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
 	xf86OutputPtr output;
@@ -1351,7 +1352,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
 
 	koutput =
 	    drmModeGetConnector(drmmode->fd,
-				drmmode->mode_res->connectors[num]);
+				mode_res->connectors[num]);
 	if (!koutput)
 		return 0;
 
@@ -1407,7 +1408,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
 		goto out_free_encoders;
 	}
 
-	drmmode_output->output_id = drmmode->mode_res->connectors[num];
+	drmmode_output->output_id = mode_res->connectors[num];
 	drmmode_output->mode_output = koutput;
 	drmmode_output->mode_encoders = kencoders;
 	drmmode_output->drmmode = drmmode;
@@ -1476,7 +1477,7 @@ uint32_t find_clones(ScrnInfoPtr scrn, xf86OutputPtr output)
 	return index_mask;
 }
 
-static void drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
+static void drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, drmModeResPtr mode_res)
 {
 	int i, j;
 	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -1491,8 +1492,8 @@ static void drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
 		for (j = 0; j < drmmode_output->mode_output->count_encoders;
 		     j++) {
 			int k;
-			for (k = 0; k < drmmode->mode_res->count_encoders; k++) {
-				if (drmmode->mode_res->encoders[k] ==
+			for (k = 0; k < mode_res->count_encoders; k++) {
+				if (mode_res->encoders[k] ==
 				    drmmode_output->
 				    mode_encoders[j]->encoder_id)
 					drmmode_output->enc_mask |= (1 << k);
@@ -1730,32 +1731,34 @@ static void drm_wakeup_handler(pointer data, int err, pointer p)
 Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
 {
 	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
-	int i;
+	int i, num_dvi = 0, num_hdmi = 0;
 	unsigned int crtcs_needed = 0;
+	drmModeResPtr mode_res;
 
 	xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
 
 	drmmode->scrn = pScrn;
 	drmmode->cpp = cpp;
-	drmmode->mode_res = drmModeGetResources(drmmode->fd);
-	if (!drmmode->mode_res)
+	mode_res = drmModeGetResources(drmmode->fd);
+	if (!mode_res)
 		return FALSE;
 
-	xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width,
-			     drmmode->mode_res->max_height);
+	drmmode->count_crtcs = mode_res->count_crtcs;
+	xf86CrtcSetSizeRange(pScrn, 320, 200, mode_res->max_width,
+			     mode_res->max_height);
 
 	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
 		       "Initializing outputs ...\n");
-	for (i = 0; i < drmmode->mode_res->count_connectors; i++)
-		crtcs_needed += drmmode_output_init(pScrn, drmmode, i);
+	for (i = 0; i < mode_res->count_connectors; i++)
+		crtcs_needed += drmmode_output_init(pScrn, drmmode, mode_res, i, &num_dvi, &num_hdmi);
 
 	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
 		       "%d crtcs needed for screen.\n", crtcs_needed);
 
-	for (i = 0; i < drmmode->mode_res->count_crtcs; i++)
+	for (i = 0; i < mode_res->count_crtcs; i++)
 		if (!xf86IsEntityShared(pScrn->entityList[0]) ||
 		    (crtcs_needed && !(pAMDGPUEnt->assigned_crtcs & (1 << i))))
-			crtcs_needed -= drmmode_crtc_init(pScrn, drmmode, i);
+			crtcs_needed -= drmmode_crtc_init(pScrn, drmmode, mode_res, i);
 
 	/* All ZaphodHeads outputs provided with matching crtcs? */
 	if (xf86IsEntityShared(pScrn->entityList[0]) && (crtcs_needed > 0))
@@ -1764,7 +1767,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
 			   crtcs_needed);
 
 	/* workout clones */
-	drmmode_clones_init(pScrn, drmmode);
+	drmmode_clones_init(pScrn, drmmode, mode_res);
 
 #ifdef AMDGPU_PIXMAP_SHARING
 	xf86ProviderSetup(pScrn, NULL, "amdgpu");
@@ -1776,6 +1779,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
 	drmmode->event_context.vblank_handler = amdgpu_drm_queue_handler;
 	drmmode->event_context.page_flip_handler = amdgpu_drm_queue_handler;
 
+	drmModeFreeResources(mode_res);
 	return TRUE;
 }
 
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index f029998..9c95c14 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -43,7 +43,6 @@
 typedef struct {
 	int fd;
 	unsigned fb_id;
-	drmModeResPtr mode_res;
 	drmModeFBPtr mode_fb;
 	int cpp;
 	ScrnInfoPtr scrn;
@@ -52,6 +51,7 @@ typedef struct {
 	InputHandlerProc uevent_handler;
 #endif
 	drmEventContext event_context;
+	int count_crtcs;
 } drmmode_rec, *drmmode_ptr;
 
 typedef struct {
commit 4ca8f957e0b417b099f625470db98a54531a731d
Author: Tom St Denis <tom.stdenis at amd.com>
Date:   Thu Oct 1 13:16:15 2015 -0400

    Silence type mismatch warning.
    
    Signed-off-by: Tom St Denis <tom.stdenis at amd.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 426b865..611d8e1 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -1055,7 +1055,7 @@ Bool AMDGPUScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
 	MessageType from;
 	Bool value;
 	int driLevel;
-	char *s;
+	const char *s;
 	void *front_ptr;
 
 	pScrn->fbOffset = 0;
commit a79735ab1499c1f7814036d1b19ff465705c5f45
Author: Tom St Denis <tom.stdenis at amd.com>
Date:   Thu Oct 1 10:51:07 2015 -0400

    Add support for server managed fds
    
    Based on radeon commit ed0cfbb4fe77146b0b38f777bc28f3a4ea6da07f
    
    and 2nd patch:
    
    Fix building on older servers without xf86platformBus.h
    
    Based on radeon commit b50da3b96c212086cb58501dbe988d64f1f35b6d
    
    Signed-off-by: Tom St Denis <tom.stdenis at amd.com>
    
    [ Michel Dänzer: Fixed up amdgpu_kernel_open_fd() not to need
      AMDGPUEntPriv(), which doesn't work yet at that point ]
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 89650b0..426b865 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -126,7 +126,11 @@ static void AMDGPUFreeRec(ScrnInfoPtr pScrn)
 		pAMDGPUEnt->fd_ref--;
 		if (!pAMDGPUEnt->fd_ref) {
 			amdgpu_device_deinitialize(pAMDGPUEnt->pDev);
-			drmClose(pAMDGPUEnt->fd);
+#ifdef XF86_PDEV_SERVER_FD
+			if (!(pAMDGPUEnt->platform_dev &&
+			      pAMDGPUEnt->platform_dev->flags & XF86_PDEV_SERVER_FD))
+#endif
+				drmClose(pAMDGPUEnt->fd);
 			pAMDGPUEnt->fd = 0;
 		}
 	}
@@ -937,6 +941,41 @@ void AMDGPUUnblank(ScrnInfoPtr pScrn)
 	}
 }
 
+static Bool amdgpu_set_drm_master(ScrnInfoPtr pScrn)
+{
+	AMDGPUInfoPtr info  = AMDGPUPTR(pScrn);
+	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
+	int err;
+
+#ifdef XF86_PDEV_SERVER_FD
+	if (pAMDGPUEnt->platform_dev &&
+	    (pAMDGPUEnt->platform_dev->flags & XF86_PDEV_SERVER_FD))
+		return TRUE;
+#endif
+
+	err = drmSetMaster(info->dri2.drm_fd);
+	if (err)
+		ErrorF("Unable to retrieve master\n");
+
+	return err == 0;
+}
+
+static void amdgpu_drop_drm_master(ScrnInfoPtr pScrn)
+{
+	AMDGPUInfoPtr  info  = AMDGPUPTR(pScrn);
+	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
+
+#ifdef XF86_PDEV_SERVER_FD
+	if (pAMDGPUEnt->platform_dev &&
+	    (pAMDGPUEnt->platform_dev->flags & XF86_PDEV_SERVER_FD))
+		return;
+#endif
+
+	drmDropMaster(info->dri2.drm_fd);
+}
+
+
+
 static Bool AMDGPUSaveScreen_KMS(ScreenPtr pScreen, int mode)
 {
 	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
@@ -980,8 +1019,7 @@ static Bool AMDGPUCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL)
 	DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn);
 
 	amdgpu_sync_close(pScreen);
-
-	drmDropMaster(info->dri2.drm_fd);
+	amdgpu_drop_drm_master(pScrn);
 
 	drmmode_fini(pScrn, &info->drmmode);
 	if (info->dri2.enabled) {
@@ -1019,7 +1057,6 @@ Bool AMDGPUScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
 	int driLevel;
 	char *s;
 	void *front_ptr;
-	int ret;
 
 	pScrn->fbOffset = 0;
 
@@ -1030,11 +1067,9 @@ Bool AMDGPUScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
 		return FALSE;
 	miSetPixmapDepths();
 
-	ret = drmSetMaster(info->dri2.drm_fd);
-	if (ret) {
-		ErrorF("Unable to retrieve master\n");
+	if (!amdgpu_set_drm_master(pScrn))
 		return FALSE;
-	}
+
 	info->directRenderingEnabled = FALSE;
 	if (info->shadow_fb == FALSE)
 		info->directRenderingEnabled = amdgpu_dri2_screen_init(pScreen);
@@ -1254,14 +1289,11 @@ Bool AMDGPUEnterVT_KMS(VT_FUNC_ARGS_DECL)
 {
 	SCRN_INFO_PTR(arg);
 	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
-	int ret;
 
 	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
 		       "AMDGPUEnterVT_KMS\n");
 
-	ret = drmSetMaster(info->dri2.drm_fd);
-	if (ret)
-		ErrorF("Unable to retrieve master\n");
+	amdgpu_set_drm_master(pScrn);
 
 	pScrn->vtSema = TRUE;
 
@@ -1274,12 +1306,11 @@ Bool AMDGPUEnterVT_KMS(VT_FUNC_ARGS_DECL)
 void AMDGPULeaveVT_KMS(VT_FUNC_ARGS_DECL)
 {
 	SCRN_INFO_PTR(arg);
-	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
 
 	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
 		       "AMDGPULeaveVT_KMS\n");
 
-	drmDropMaster(info->dri2.drm_fd);
+	amdgpu_drop_drm_master(pScrn);
 
 	xf86RotateFreeShadow(pScrn);
 	drmmode_scanout_free(pScrn);
diff --git a/src/amdgpu_probe.c b/src/amdgpu_probe.c
index 957eb98..7a1a556 100644
--- a/src/amdgpu_probe.c
+++ b/src/amdgpu_probe.c
@@ -112,11 +112,21 @@ static Bool amdgpu_kernel_mode_enabled(ScrnInfoPtr pScrn,
 	return TRUE;
 }
 
-static int amdgpu_kernel_open_fd(ScrnInfoPtr pScrn, struct pci_device *dev)
+static int amdgpu_kernel_open_fd(ScrnInfoPtr pScrn, struct pci_device *dev,
+				 struct xf86_platform_device *platform_dev)
 {
 	char *busid;
 	int fd;
 
+#ifdef XF86_PDEV_SERVER_FD
+	if (platform_dev) {
+		fd = xf86_get_platform_device_int_attrib(platform_dev,
+							 ODEV_ATTRIB_FD, -1);
+		if (fd != -1)
+			return fd;
+	}
+#endif
+
 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,9,99,901,0)
 	XNFasprintf(&busid, "pci:%04x:%02x:%02x.%d",
 		    dev->domain, dev->bus, dev->dev, dev->func);
@@ -153,7 +163,7 @@ static Bool amdgpu_open_drm_master(ScrnInfoPtr pScrn)
 		return TRUE;
 	}
 
-	info->dri2.drm_fd = amdgpu_kernel_open_fd(pScrn, info->PciInfo);
+	info->dri2.drm_fd = amdgpu_kernel_open_fd(pScrn, info->PciInfo, NULL);
 	if (info->dri2.drm_fd == -1)
 		return FALSE;
 
@@ -280,7 +290,11 @@ static Bool AMDGPUDriverFunc(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data)
 		flag = (CARD32 *) data;
 		(*flag) = 0;
 		return TRUE;
-	default:
+#if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(1,15,99,0,0)
+	case SUPPORTS_SERVER_FDS:
+		return TRUE;
+#endif
+       default:
 		return FALSE;
 	}
 }
@@ -343,7 +357,7 @@ amdgpu_platform_probe(DriverPtr pDriver,
 		pPriv->ptr = xnfcalloc(sizeof(AMDGPUEntRec), 1);
 		pAMDGPUEnt = pPriv->ptr;
 		pAMDGPUEnt->HasSecondary = FALSE;
-		pAMDGPUEnt->fd = amdgpu_kernel_open_fd(pScrn, dev->pdev);
+		pAMDGPUEnt->fd = amdgpu_kernel_open_fd(pScrn, dev->pdev, dev);
 		if (pAMDGPUEnt->fd < 0)
 			goto error_fd;
 
@@ -361,6 +375,7 @@ amdgpu_platform_probe(DriverPtr pDriver,
 		pAMDGPUEnt = pPriv->ptr;
 		pAMDGPUEnt->HasSecondary = TRUE;
 	}
+	pAMDGPUEnt->platform_dev = dev;
 
 	xf86SetEntityInstanceForScreen(pScrn, pEnt->index,
 				       xf86GetNumEntityInstances(pEnt->
diff --git a/src/amdgpu_probe.h b/src/amdgpu_probe.h
index 2a1b5ab..6c187ce 100644
--- a/src/amdgpu_probe.h
+++ b/src/amdgpu_probe.h
@@ -37,12 +37,17 @@
 #define _AMDGPU_PROBE_H_ 1
 
 #include <stdint.h>
+#include "xorg-server.h"
 #include "xf86str.h"
 #include "xf86DDC.h"
 #include "randrstr.h"
 
 #include "xf86Crtc.h"
 
+#ifdef XSERVER_PLATFORM_BUS
+#include "xf86platformBus.h"
+#endif
+
 #include <amdgpu.h>
 
 #include "compat-api.h"
@@ -82,6 +87,7 @@ typedef struct {
 	unsigned long fd_wakeup_registered;	/* server generation for which fd has been registered for wakeup handling */
 	int fd_wakeup_ref;
 	unsigned int assigned_crtcs;
+	struct xf86_platform_device *platform_dev;
 } AMDGPUEntRec, *AMDGPUEntPtr;
 
 extern const OptionInfoRec *AMDGPUOptionsWeak(void);
commit b93934a9ed5e92f3a6eac6554c5c4fa2967a6dd0
Author: Tom St Denis <tom.stdenis at amd.com>
Date:   Thu Oct 1 10:05:36 2015 -0400

    Add amdgpu_open_drm_master helper function
    
    Based on radeon commit 3d7861fe112f25874319d4cdc12b745fbcd359cf
    
    > This is a preparation patch for adding server-managed-fd support without it
    > turning into a goto fest.
    
    With appropriate modifications because the open call stack is different
    in the amdgpu tree.
    
    Signed-off-by: Tom St Denis <tom.stdenis at amd.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/src/amdgpu_probe.c b/src/amdgpu_probe.c
index ead248e..957eb98 100644
--- a/src/amdgpu_probe.c
+++ b/src/amdgpu_probe.c
@@ -43,6 +43,7 @@
 
 #include "amdgpu_probe.h"
 #include "amdgpu_version.h"
+#include "amdgpu_drv.h"
 #include "amdpciids.h"
 
 #include "xf86.h"
@@ -114,8 +115,6 @@ static Bool amdgpu_kernel_mode_enabled(ScrnInfoPtr pScrn,
 static int amdgpu_kernel_open_fd(ScrnInfoPtr pScrn, struct pci_device *dev)
 {
 	char *busid;
-	drmSetVersion sv;
-	int err;
 	int fd;
 
 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,9,99,901,0)
@@ -135,6 +134,28 @@ static int amdgpu_kernel_open_fd(ScrnInfoPtr pScrn, struct pci_device *dev)
 		return fd;
 	}
 	free(busid);
+	return fd;
+}
+
+static Bool amdgpu_open_drm_master(ScrnInfoPtr pScrn)
+{
+	AMDGPUInfoPtr  info   = AMDGPUPTR(pScrn);
+	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
+	drmSetVersion sv;
+	int err;
+
+	if (pAMDGPUEnt->fd) {
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			   " reusing fd for second head\n");
+
+		info->drmmode.fd = info->dri2.drm_fd = pAMDGPUEnt->fd;
+		pAMDGPUEnt->fd_ref++;
+		return TRUE;
+	}
+
+	info->dri2.drm_fd = amdgpu_kernel_open_fd(pScrn, info->PciInfo);
+	if (info->dri2.drm_fd == -1)
+		return FALSE;
 
 	/* Check that what we opened was a master or a master-capable FD,
 	 * by setting the version of the interface we'll use to talk to it.
@@ -144,15 +165,15 @@ static int amdgpu_kernel_open_fd(ScrnInfoPtr pScrn, struct pci_device *dev)
 	sv.drm_di_minor = 1;
 	sv.drm_dd_major = -1;
 	sv.drm_dd_minor = -1;
-	err = drmSetInterfaceVersion(fd, &sv);
+	err = drmSetInterfaceVersion(info->dri2.drm_fd, &sv);
 	if (err != 0) {
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 			   "[drm] failed to set drm interface version.\n");
-		drmClose(fd);
-		return -1;
+		drmClose(info->dri2.drm_fd);
+		return FALSE;
 	}
 
-	return fd;
+	return TRUE;
 }
 
 static Bool amdgpu_get_scrninfo(int entity_num, void *pci_dev)
@@ -208,9 +229,9 @@ static Bool amdgpu_get_scrninfo(int entity_num, void *pci_dev)
 		pAMDGPUEnt = pPriv->ptr;
 		pAMDGPUEnt->HasSecondary = FALSE;
 
-		pAMDGPUEnt->fd = amdgpu_kernel_open_fd(pScrn, pci_dev);
-		if (pAMDGPUEnt->fd < 0)
+		if (amdgpu_open_drm_master(pScrn)) {
 			goto error_fd;
+		}
 
 		pAMDGPUEnt->fd_ref = 1;
 
commit f5c3fd0b57cf9e392bf591110568637937a1d338
Author: Tom St Denis <tom.stdenis at amd.com>
Date:   Thu Oct 1 09:13:57 2015 -0400

    Cleaning up for server-fd support
    
    Based on radeon commit a63342ad15408071437c80b411d14196f3288aed
    
    > radeon_open_drm_master get rid of unnecessary goto
    
    Signed-off-by: Tom St Denis <tom.stdenis at amd.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 3d92518..89650b0 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -619,9 +619,8 @@ static void amdgpu_reference_drm_fd(ScrnInfoPtr pScrn)
 	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
 	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
 
-	info->dri2.drm_fd = pAMDGPUEnt->fd;
+	info->drmmode.fd = info->dri2.drm_fd = pAMDGPUEnt->fd;
 	pAMDGPUEnt->fd_ref++;
-	info->drmmode.fd = info->dri2.drm_fd;
 }
 
 static Bool amdgpu_get_tile_config(ScrnInfoPtr pScrn)
commit 3055724aef76a624718f26d5f0f9e9d567ffbcfb
Author: Tom St Denis <tom.stdenis at amd.com>
Date:   Thu Sep 24 13:08:31 2015 -0400

    Simplify pick best crtc to fold two loops into one
    
    This patch folds the two for loops from amdgpu_pick_best_crtc() into
    one to reduce the LOC and make the routine easier to read.
    
    Signed-off-by: Tom St Denis <tom.stdenis at amd.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/src/amdgpu_video.c b/src/amdgpu_video.c
index 95a75e9..74e7c84 100644
--- a/src/amdgpu_video.c
+++ b/src/amdgpu_video.c
@@ -75,7 +75,7 @@ amdgpu_pick_best_crtc(ScrnInfoPtr pScrn, Bool consider_disabled,
 		      int x1, int x2, int y1, int y2)
 {
 	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-	int coverage, best_coverage, c;
+	int coverage, best_coverage, c, cd;
 	BoxRec box, crtc_box, cover_box;
 	RROutputPtr primary_output = NULL;
 	xf86CrtcPtr best_crtc = NULL, primary_crtc = NULL;
@@ -99,38 +99,30 @@ amdgpu_pick_best_crtc(ScrnInfoPtr pScrn, Bool consider_disabled,
 	if (primary_output && primary_output->crtc)
 		primary_crtc = primary_output->crtc->devPrivate;
 
-	/* first consider only enabled CRTCs */
-	for (c = 0; c < xf86_config->num_crtc; c++) {
-		xf86CrtcPtr crtc = xf86_config->crtc[c];
-
-		if (!amdgpu_crtc_is_enabled(crtc))
-			continue;
-
-		amdgpu_crtc_box(crtc, &crtc_box);
-		amdgpu_box_intersect(&cover_box, &crtc_box, &box);
-		coverage = amdgpu_box_area(&cover_box);
-		if (coverage > best_coverage ||
-		    (coverage == best_coverage && crtc == primary_crtc)) {
-			best_crtc = crtc;
-			best_coverage = coverage;
-		}
-	}
-	if (best_crtc || !consider_disabled)
-		return best_crtc;
-
-	/* if we found nothing, repeat the search including disabled CRTCs */
-	for (c = 0; c < xf86_config->num_crtc; c++) {
-		xf86CrtcPtr crtc = xf86_config->crtc[c];
-
-		amdgpu_crtc_box(crtc, &crtc_box);
-		amdgpu_box_intersect(&cover_box, &crtc_box, &box);
-		coverage = amdgpu_box_area(&cover_box);
-		if (coverage > best_coverage ||
-		    (coverage == best_coverage && crtc == primary_crtc)) {
-			best_crtc = crtc;
-			best_coverage = coverage;
+	/* first consider only enabled CRTCs
+	 * then on second pass consider disabled ones
+	 */
+	for (cd = 0; cd < (consider_disabled ? 2 : 1); cd++) {
+		for (c = 0; c < xf86_config->num_crtc; c++) {
+			xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+			if (!cd && !amdgpu_crtc_is_enabled(crtc))
+				continue;
+
+			amdgpu_crtc_box(crtc, &crtc_box);
+			amdgpu_box_intersect(&cover_box, &crtc_box, &box);
+			coverage = amdgpu_box_area(&cover_box);
+			if (coverage > best_coverage ||
+			    (coverage == best_coverage &&
+			     crtc == primary_crtc)) {
+				best_crtc = crtc;
+				best_coverage = coverage;
+			}
 		}
+		if (best_crtc)
+			break;
 	}
+
 	return best_crtc;
 }
 


More information about the xorg-commit mailing list