Module Name:    src
Committed By:   riastradh
Date:           Mon Aug 27 15:32:06 UTC 2018

Modified Files:
        src/sys/external/bsd/drm2/dist/include/drm: drmP.h
        src/sys/external/bsd/drm2/drm: drm_memory.c
        src/sys/external/bsd/drm2/pci: drm_pci.c

Log Message:
Tread carefully around DMA subregions.

Not all platforms support it.

- If we want to limit to 32-bit DMA, just use a known 32-bit DMA tag.
- If we want to limit to >32-bit DMA, but the host only has a known
  32-bit DMA tag, then just use that anyway.
- If we want to limit to >32-bit DMA, but the host doesn't support
  bus_dmatag_subregion, then just use the 32-bit DMA tag anyway.

Gives powerpc, sparc a chance of working.


To generate a diff of this commit:
cvs rdiff -u -r1.30 -r1.31 src/sys/external/bsd/drm2/dist/include/drm/drmP.h
cvs rdiff -u -r1.12 -r1.13 src/sys/external/bsd/drm2/drm/drm_memory.c
cvs rdiff -u -r1.28 -r1.29 src/sys/external/bsd/drm2/pci/drm_pci.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/external/bsd/drm2/dist/include/drm/drmP.h
diff -u src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.30 src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.31
--- src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.30	Mon Aug 27 15:28:03 2018
+++ src/sys/external/bsd/drm2/dist/include/drm/drmP.h	Mon Aug 27 15:32:06 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: drmP.h,v 1.30 2018/08/27 15:28:03 riastradh Exp $	*/
+/*	$NetBSD: drmP.h,v 1.31 2018/08/27 15:32:06 riastradh Exp $	*/
 
 /*
  * Internal Header for the Direct Rendering Manager
@@ -920,6 +920,7 @@ struct drm_device {
 	struct drm_bus_map *bus_maps;
 	unsigned bus_nmaps;
 	bus_dma_tag_t bus_dmat;	/* bus's full DMA tag, for internal use */
+	bus_dma_tag_t bus_dmat32;	/* bus's 32-bit DMA tag */
 	bus_dma_tag_t dmat;	/* DMA tag for driver, may be subregion */
 	bool dmat_subregion_p;
 	bus_addr_t dmat_subregion_min;

Index: src/sys/external/bsd/drm2/drm/drm_memory.c
diff -u src/sys/external/bsd/drm2/drm/drm_memory.c:1.12 src/sys/external/bsd/drm2/drm/drm_memory.c:1.13
--- src/sys/external/bsd/drm2/drm/drm_memory.c:1.12	Mon Aug 27 06:58:20 2018
+++ src/sys/external/bsd/drm2/drm/drm_memory.c	Mon Aug 27 15:32:06 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_memory.c,v 1.12 2018/08/27 06:58:20 riastradh Exp $	*/
+/*	$NetBSD: drm_memory.c,v 1.13 2018/08/27 15:32:06 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_memory.c,v 1.12 2018/08/27 06:58:20 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_memory.c,v 1.13 2018/08/27 15:32:06 riastradh Exp $");
 
 #if defined(__i386__) || defined(__x86_64__)
 
@@ -290,6 +290,21 @@ drm_limit_dma_space(struct drm_device *d
 	}
 
 	/*
+	 * If our limit contains the 32-bit space but for some reason
+	 * we can't use a subregion, either because the bus doesn't
+	 * support >32-bit DMA or because bus_dma(9) on this platform
+	 * lacks bus_dmatag_subregion, just use the 32-bit space.
+	 */
+	if (min_addr == 0 && max_addr >= UINT32_C(0xffffffff) &&
+	    dev->bus_dmat == dev->bus_dmat32) {
+dma32:		dev->dmat = dev->bus_dmat32;
+		dev->dmat_subregion_p = false;
+		dev->dmat_subregion_min = 0;
+		dev->dmat_subregion_max = UINT32_C(0xffffffff);
+		return 0;
+	}
+
+	/*
 	 * Create a DMA tag for a subregion from the bus's DMA tag.  If
 	 * that fails, restore dev->dmat to the whole region so that we
 	 * need not worry about dev->dmat being uninitialized (not that
@@ -300,8 +315,19 @@ drm_limit_dma_space(struct drm_device *d
 	ret = -bus_dmatag_subregion(dev->bus_dmat, min_addr, max_addr,
 	    &dev->dmat, BUS_DMA_WAITOK);
 	if (ret) {
+		/*
+		 * bus_dmatag_subregion may fail.  If so, and if the
+		 * subregion contains the 32-bit space, just use the
+		 * 32-bit DMA tag.
+		 */
+		if (ret == -EOPNOTSUPP && dev->bus_dmat32 &&
+		    min_addr == 0 && max_addr >= UINT32_C(0xffffffff))
+			goto dma32;
+		/* XXX Back out?  */
 		dev->dmat = dev->bus_dmat;
 		dev->dmat_subregion_p = false;
+		dev->dmat_subregion_min = 0;
+		dev->dmat_subregion_max = __type_max(bus_addr_t);
 		return ret;
 	}
 

Index: src/sys/external/bsd/drm2/pci/drm_pci.c
diff -u src/sys/external/bsd/drm2/pci/drm_pci.c:1.28 src/sys/external/bsd/drm2/pci/drm_pci.c:1.29
--- src/sys/external/bsd/drm2/pci/drm_pci.c:1.28	Mon Aug 27 15:31:27 2018
+++ src/sys/external/bsd/drm2/pci/drm_pci.c	Mon Aug 27 15:32:06 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_pci.c,v 1.28 2018/08/27 15:31:27 riastradh Exp $	*/
+/*	$NetBSD: drm_pci.c,v 1.29 2018/08/27 15:32:06 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_pci.c,v 1.28 2018/08/27 15:31:27 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_pci.c,v 1.29 2018/08/27 15:32:06 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/errno.h>
@@ -96,10 +96,12 @@ drm_pci_attach(device_t self, const stru
 
 	/* Set up the bus space and bus DMA tags.  */
 	dev->bst = pa->pa_memt;
-	/* XXX Let the driver say something about 32-bit vs 64-bit DMA?  */
 	dev->bus_dmat = (pci_dma64_available(pa)? pa->pa_dmat64 : pa->pa_dmat);
+	dev->bus_dmat32 = pa->pa_dmat;
 	dev->dmat = dev->bus_dmat;
 	dev->dmat_subregion_p = false;
+	dev->dmat_subregion_min = 0;
+	dev->dmat_subregion_max = __type_max(bus_addr_t);
 
 	/* Find all the memory maps.  */
 	CTASSERT(PCI_NUM_RESOURCES < (SIZE_MAX / sizeof(dev->bus_maps[0])));

Reply via email to