Module Name:    src
Committed By:   jmorse
Date:           Tue Jan 26 08:01:27 UTC 2010

Modified Files:
        src/sys/external/bsd/drm/dist/bsd-core: drmP.h drm_bufs.c drm_memory.c

Log Message:
PR/42262: Support drm drivers (intel G33/G45) submapping pci resources


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 src/sys/external/bsd/drm/dist/bsd-core/drmP.h
cvs rdiff -u -r1.6 -r1.7 src/sys/external/bsd/drm/dist/bsd-core/drm_bufs.c \
    src/sys/external/bsd/drm/dist/bsd-core/drm_memory.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/drm/dist/bsd-core/drmP.h
diff -u src/sys/external/bsd/drm/dist/bsd-core/drmP.h:1.15 src/sys/external/bsd/drm/dist/bsd-core/drmP.h:1.16
--- src/sys/external/bsd/drm/dist/bsd-core/drmP.h:1.15	Sun Dec  6 22:51:25 2009
+++ src/sys/external/bsd/drm/dist/bsd-core/drmP.h	Tue Jan 26 08:01:26 2010
@@ -658,6 +658,18 @@
 
 typedef TAILQ_HEAD(drm_map_list, drm_local_map) drm_map_list_t;
 
+#if defined(__NetBSD__)
+typedef struct {
+	int			mapped;
+	int			maptype;
+	bus_addr_t		base;
+	bus_size_t		size;
+	bus_space_handle_t	bsh;
+	int			flags;
+	void *			vaddr;
+} pci_map_data_t;
+#endif
+
 typedef struct drm_local_map {
 	unsigned long	offset;	 /* Physical address (0 for SAREA)*/
 	unsigned long	size;	 /* Physical size (bytes)	    */
@@ -675,7 +687,7 @@
 	bus_space_handle_t bsh;
 	drm_dma_handle_t *dmah;
 #if defined(__NetBSD__)
-	int *cnt;
+	pci_map_data_t *fullmap;
 	bus_size_t mapsize;
 #endif
 	TAILQ_ENTRY(drm_local_map) link;
@@ -792,18 +804,6 @@
 /* Length for the array of resource pointers for drm_get_resource_*. */
 #define DRM_MAX_PCI_RESOURCE	6
 
-#if defined(__NetBSD__)
-typedef struct {
-	int			mapped;
-	int			maptype;
-	bus_addr_t		base;
-	bus_size_t		size;
-	bus_space_handle_t	bsh;
-	int			flags;
-	void *			vaddr;
-} pci_map_data_t;
-#endif
-
 /** 
  * DRM device functions structure
  */

Index: src/sys/external/bsd/drm/dist/bsd-core/drm_bufs.c
diff -u src/sys/external/bsd/drm/dist/bsd-core/drm_bufs.c:1.6 src/sys/external/bsd/drm/dist/bsd-core/drm_bufs.c:1.7
--- src/sys/external/bsd/drm/dist/bsd-core/drm_bufs.c:1.6	Wed Sep  2 01:36:41 2009
+++ src/sys/external/bsd/drm/dist/bsd-core/drm_bufs.c	Tue Jan 26 08:01:26 2010
@@ -159,16 +159,25 @@
 	map->size = size;
 	map->type = type;
 	map->flags = flags;
-#ifdef __NetBSD__
-	map->cnt = NULL;
+#if defined(__NetBSD__)
+	map->fullmap = NULL;
 	map->mapsize = 0;
 #endif
 
 	switch (map->type) {
 	case _DRM_REGISTERS:
 		map->handle = drm_ioremap(dev, map);
+		if (map->handle == NULL) {
+			DRM_ERROR("drm_addmap couldn't ioremap registers with "
+				"base %lX, size %lX\n",
+				(long) offset, (long) size);
+			DRM_LOCK();
+			return EINVAL;
+		}
+
 		if (!(map->flags & _DRM_WRITE_COMBINING))
 			break;
+
 		/* FALLTHROUGH */
 	case _DRM_FRAME_BUFFER:
 		if (drm_mtrr_add(map->offset, map->size, DRM_MTRR_WC) == 0)
Index: src/sys/external/bsd/drm/dist/bsd-core/drm_memory.c
diff -u src/sys/external/bsd/drm/dist/bsd-core/drm_memory.c:1.6 src/sys/external/bsd/drm/dist/bsd-core/drm_memory.c:1.7
--- src/sys/external/bsd/drm/dist/bsd-core/drm_memory.c:1.6	Wed Sep  2 01:36:41 2009
+++ src/sys/external/bsd/drm/dist/bsd-core/drm_memory.c	Tue Jan 26 08:01:26 2010
@@ -85,29 +85,55 @@
 static void *
 drm_netbsd_ioremap(struct drm_device *dev, drm_local_map_t *map, int wc)
 {
+	bus_space_handle_t h;
 	int i, reg, reason;
 	for(i = 0; i<DRM_MAX_PCI_RESOURCE; i++) {
 		reg = PCI_MAPREG_START + i*4;
+
+		/* Does the requested mapping lie within this resource? */
 		if ((dev->pci_map_data[i].maptype == PCI_MAPREG_TYPE_MEM ||
 		     dev->pci_map_data[i].maptype ==
                       (PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT)) &&
-		    dev->pci_map_data[i].base == map->offset             &&
-		    dev->pci_map_data[i].size >= map->size)
+		    map->offset >= dev->pci_map_data[i].base             &&
+		    map->offset + map->size <= dev->pci_map_data[i].base +
+                                              dev->pci_map_data[i].size)
 		{
 			map->bst = dev->pa.pa_memt;
-			map->cnt = &(dev->pci_map_data[i].mapped);
-			map->mapsize = dev->pci_map_data[i].size;
+			map->fullmap = &(dev->pci_map_data[i]);
+			map->mapsize = map->size;
 			dev->pci_map_data[i].mapped++;
+
+			/* If we've already mapped this resource in, handle
+			 * submapping if needed, give caller a bus_space handle
+			 * and pointer for the offest they asked for */
 			if (dev->pci_map_data[i].mapped > 1)
 			{
-				map->bsh = dev->pci_map_data[i].bsh;
-				return dev->pci_map_data[i].vaddr;
+				if ((reason = bus_space_subregion(
+						dev->pa.pa_memt,
+						dev->pci_map_data[i].bsh,
+						map->offset - dev->pci_map_data[i].base,
+						map->size, &h)) != 0)  {
+					DRM_DEBUG("ioremap failed to "
+						"bus_space_subregion: %d\n",
+						reason);
+					return NULL;
+				}
+				map->bsh = h;
+				map->handle = bus_space_vaddr(dev->pa.pa_memt,
+									h);
+				return map->handle;
 			}
+
+			/* Map in entirety of resource - full size and handle
+			 * go in pci_map_data, specific mapping in callers
+			 * drm_local_map_t */
 			DRM_DEBUG("ioremap%s: flags %d\n", wc ? "_wc" : "",
 				  dev->pci_map_data[i].flags);
-			if ((reason = bus_space_map(map->bst, map->offset,
+			if ((reason = bus_space_map(map->bst,
+					dev->pci_map_data[i].base,
 					dev->pci_map_data[i].size,
-					dev->pci_map_data[i].flags, &map->bsh)))
+					dev->pci_map_data[i].flags,
+					&dev->pci_map_data[i].bsh)))
 			{
 				dev->pci_map_data[i].mapped--;
 #if NAGP_I810 > 0 /* XXX horrible kludge: agp might have mapped it */
@@ -118,13 +144,29 @@
 					  reason);
 				return NULL;
 			}
-			dev->pci_map_data[i].bsh = map->bsh;
-			dev->pci_map_data[i].vaddr =
-				 	bus_space_vaddr(map->bst, map->bsh);
+
+			dev->pci_map_data[i].vaddr = bus_space_vaddr(map->bst,
+						dev->pci_map_data[i].bsh);
+
+			/* Caller might have requested a submapping of that */
+			if ((reason = bus_space_subregion(
+					dev->pa.pa_memt,
+					dev->pci_map_data[i].bsh,
+					map->offset - dev->pci_map_data[i].base,
+					map->size, &h)) != 0)  {
+				DRM_DEBUG("ioremap failed to "
+					"bus_space_subregion: %d\n",
+					reason);
+				return NULL;
+			}
+
 			DRM_DEBUG("ioremap mem found for %lx, %lx: %p\n",
 				map->offset, map->size,
 				dev->agp_map_data[i].vaddr);
-			return dev->pci_map_data[i].vaddr;
+
+			map->bsh = h;
+			map->handle = bus_space_vaddr(dev->pa.pa_memt, h);
+			return map->handle;
 		}
 	}
 	/* failed to find a valid mapping; all hope isn't lost though */
@@ -133,7 +175,7 @@
 		    dev->agp_map_data[i].base == map->offset &&
 		    dev->agp_map_data[i].size >= map->size) {
 			map->bst = dev->pa.pa_memt;
-			map->cnt = &(dev->agp_map_data[i].mapped);
+			map->fullmap = &(dev->agp_map_data[i]);
 			map->mapsize = dev->agp_map_data[i].size;
 			dev->agp_map_data[i].mapped++;
 			map->bsh = dev->agp_map_data[i].bsh;
@@ -148,7 +190,7 @@
 			dev->agp_map_data[i].size = map->size;
 			dev->agp_map_data[i].flags = BUS_SPACE_MAP_LINEAR;
 			dev->agp_map_data[i].maptype = PCI_MAPREG_TYPE_MEM;
-			map->cnt = &(dev->agp_map_data[i].mapped);
+			map->fullmap = &(dev->agp_map_data[i]);
 			map->mapsize = dev->agp_map_data[i].size;
 
 			DRM_DEBUG("ioremap%s: flags %d\n", wc ? "_wc" : "",
@@ -201,14 +243,16 @@
 #if defined(__FreeBSD__)
 	pmap_unmapdev((vm_offset_t) map->handle, map->size);
 #elif   defined(__NetBSD__)
-	if (map->cnt == NULL) {
+	if (map->fullmap == NULL) {
 		DRM_INFO("drm_ioremapfree called for unknown map\n");
 		return;
 	}
-	if (*(map->cnt) > 0) {
-		(*(map->cnt))--;
-		if(*(map->cnt) == 0)
-			bus_space_unmap(map->bst, map->bsh, map->mapsize);
+
+	if (map->fullmap->mapped > 0) {
+		map->fullmap->mapped--;
+		if(map->fullmap->mapped == 0)
+			bus_space_unmap(map->bst, map->fullmap->bsh,
+					map->fullmap->size);
 	}
 #endif
 }

Reply via email to