Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/external/bsd/drm/dist/bsd-core PR/42262: Support drm dri...



details:   https://anonhg.NetBSD.org/src/rev/2a72ff0b9642
branches:  trunk
changeset: 751149:2a72ff0b9642
user:      jmorse <jmorse%NetBSD.org@localhost>
date:      Tue Jan 26 08:01:26 2010 +0000

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

diffstat:

 sys/external/bsd/drm/dist/bsd-core/drmP.h       |  26 +++---
 sys/external/bsd/drm/dist/bsd-core/drm_bufs.c   |  13 +++-
 sys/external/bsd/drm/dist/bsd-core/drm_memory.c |  82 +++++++++++++++++++-----
 3 files changed, 87 insertions(+), 34 deletions(-)

diffs (222 lines):

diff -r a66e85d8a894 -r 2a72ff0b9642 sys/external/bsd/drm/dist/bsd-core/drmP.h
--- a/sys/external/bsd/drm/dist/bsd-core/drmP.h Tue Jan 26 07:58:16 2010 +0000
+++ b/sys/external/bsd/drm/dist/bsd-core/drmP.h Tue Jan 26 08:01:26 2010 +0000
@@ -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
  */
diff -r a66e85d8a894 -r 2a72ff0b9642 sys/external/bsd/drm/dist/bsd-core/drm_bufs.c
--- a/sys/external/bsd/drm/dist/bsd-core/drm_bufs.c     Tue Jan 26 07:58:16 2010 +0000
+++ b/sys/external/bsd/drm/dist/bsd-core/drm_bufs.c     Tue Jan 26 08:01:26 2010 +0000
@@ -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)
diff -r a66e85d8a894 -r 2a72ff0b9642 sys/external/bsd/drm/dist/bsd-core/drm_memory.c
--- a/sys/external/bsd/drm/dist/bsd-core/drm_memory.c   Tue Jan 26 07:58:16 2010 +0000
+++ b/sys/external/bsd/drm/dist/bsd-core/drm_memory.c   Tue Jan 26 08:01:26 2010 +0000
@@ -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
 }



Home | Main Index | Thread Index | Old Index