Source-Changes-HG archive

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

[src/trunk]: src/sys/external/bsd/drm2/dist/drm/nouveau Allow nvkm_client_map...



details:   https://anonhg.NetBSD.org/src/rev/a418eeab0358
branches:  trunk
changeset: 835397:a418eeab0358
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Mon Aug 27 14:47:53 2018 +0000

description:
Allow nvkm_client_map to map subregions.

Linux ioremap does not care about overlapping mapped regions, but
bus_space_map does.  Since nouveau ioremaps the entire register space
of BAR 0, and separately some subregions of it, we need to convey the
bus addresses in question to it in order to bus_space_subregion.

Kinda kludgey, but we don't care about running this in userland or
anything.

While here: initialize object->map.tag.  Not physically necessary on
x86 as long as the x86_io_mem_tag is nonull, so this won't fix any
symptoms on x86, but it is wrong to leave it null.

diffstat:

 sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/driver.h                                |   5 +-
 sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/object.h                                |   3 +-
 sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/client.h                           |   9 ++-
 sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/device.h                           |   3 +-
 sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c                                        |  16 +++-
 sys/external/bsd/drm2/dist/drm/nouveau/nouveau_nvif.c                                       |  37 +++++++++-
 sys/external/bsd/drm2/dist/drm/nouveau/nvif/nouveau_nvif_object.c                           |   8 +-
 sys/external/bsd/drm2/dist/drm/nouveau/nvkm/engine/device/nouveau_nvkm_engine_device_base.c |   5 +-
 8 files changed, 72 insertions(+), 14 deletions(-)

diffs (243 lines):

diff -r 7efbb1bb43b1 -r a418eeab0358 sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/driver.h
--- a/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/driver.h      Mon Aug 27 14:47:29 2018 +0000
+++ b/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/driver.h      Mon Aug 27 14:47:53 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: driver.h,v 1.4 2018/08/27 07:35:56 riastradh Exp $     */
+/*     $NetBSD: driver.h,v 1.5 2018/08/27 14:47:53 riastradh Exp $     */
 
 #ifndef __NVIF_DRIVER_H__
 #define __NVIF_DRIVER_H__
@@ -20,7 +20,8 @@
        int (*map)(void *priv, bus_space_tag_t tag, u64 handle, u32 size,
            bus_space_handle_t *handlep, void __iomem **ptrp);
        void (*unmap)(void *priv, bus_space_tag_t tag,
-           bus_space_handle_t handle, u32 size);
+           bus_space_handle_t handle, bus_addr_t addr, void __iomem *ptr,
+           u32 size);
 #else
        void __iomem *(*map)(void *priv, u64 handle, u32 size);
        void (*unmap)(void *priv, void __iomem *ptr, u32 size);
diff -r 7efbb1bb43b1 -r a418eeab0358 sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/object.h
--- a/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/object.h      Mon Aug 27 14:47:29 2018 +0000
+++ b/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/object.h      Mon Aug 27 14:47:53 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: object.h,v 1.6 2018/08/27 14:47:29 riastradh Exp $     */
+/*     $NetBSD: object.h,v 1.7 2018/08/27 14:47:53 riastradh Exp $     */
 
 #ifndef __NVIF_OBJECT_H__
 #define __NVIF_OBJECT_H__
@@ -25,6 +25,7 @@
 #ifdef __NetBSD__
                bus_space_tag_t tag;
                bus_space_handle_t handle;
+               bus_addr_t addr;
 #endif
                void __iomem *ptr;
                u32 size;
diff -r 7efbb1bb43b1 -r a418eeab0358 sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/client.h
--- a/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/client.h Mon Aug 27 14:47:29 2018 +0000
+++ b/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/client.h Mon Aug 27 14:47:53 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: client.h,v 1.4 2018/08/27 07:36:07 riastradh Exp $     */
+/*     $NetBSD: client.h,v 1.5 2018/08/27 14:47:53 riastradh Exp $     */
 
 #ifndef __NVKM_CLIENT_H__
 #define __NVKM_CLIENT_H__
@@ -24,6 +24,13 @@
        int (*ntfy)(const void *, u32, const void *, u32);
 
        struct nvkm_vm *vm;
+
+#ifdef __NetBSD__
+       bus_space_tag_t mmiot;
+       bus_space_handle_t mmioh;
+       bus_addr_t mmioaddr;
+       bus_size_t mmiosz;
+#endif
 };
 
 extern const rb_tree_ops_t nvkm_client_dmatree_ops;
diff -r 7efbb1bb43b1 -r a418eeab0358 sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/device.h
--- a/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/device.h Mon Aug 27 14:47:29 2018 +0000
+++ b/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/device.h Mon Aug 27 14:47:53 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: device.h,v 1.5 2018/08/27 13:43:52 riastradh Exp $     */
+/*     $NetBSD: device.h,v 1.6 2018/08/27 14:47:53 riastradh Exp $     */
 
 #ifndef __NVKM_DEVICE_H__
 #define __NVKM_DEVICE_H__
@@ -77,6 +77,7 @@
 #ifdef __NetBSD__
        bus_space_tag_t mmiot;
        bus_space_handle_t mmioh;
+       bus_addr_t mmioaddr;
        bus_size_t mmiosz;
 #else
        void __iomem *pri;
diff -r 7efbb1bb43b1 -r a418eeab0358 sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c
--- a/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c      Mon Aug 27 14:47:29 2018 +0000
+++ b/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c      Mon Aug 27 14:47:53 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nouveau_drm.c,v 1.13 2018/08/27 14:19:08 riastradh Exp $       */
+/*     $NetBSD: nouveau_drm.c,v 1.14 2018/08/27 14:47:53 riastradh Exp $       */
 
 /*
  * Copyright 2012 Red Hat Inc.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_drm.c,v 1.13 2018/08/27 14:19:08 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_drm.c,v 1.14 2018/08/27 14:47:53 riastradh Exp $");
 
 #include <linux/console.h>
 #include <linux/delay.h>
@@ -467,6 +467,18 @@
                nvxx_client(&drm->client.base)->vm = drm->client.vm;
        }
 
+#ifdef __NetBSD__
+    {
+       /* XXX Kludge to make register subregion mapping work.  */
+       struct nvkm_client *client = nvxx_client(&drm->client.base);
+       struct nvkm_device *device = nvxx_device(&drm->device);
+       client->mmiot = device->mmiot;
+       client->mmioh = device->mmioh;
+       client->mmioaddr = device->mmioaddr;
+       client->mmiosz = device->mmiosz;
+    }
+#endif
+
        ret = nouveau_ttm_init(drm);
        if (ret)
                goto fail_ttm;
diff -r 7efbb1bb43b1 -r a418eeab0358 sys/external/bsd/drm2/dist/drm/nouveau/nouveau_nvif.c
--- a/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_nvif.c     Mon Aug 27 14:47:29 2018 +0000
+++ b/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_nvif.c     Mon Aug 27 14:47:53 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nouveau_nvif.c,v 1.3 2018/08/27 07:35:56 riastradh Exp $       */
+/*     $NetBSD: nouveau_nvif.c,v 1.4 2018/08/27 14:47:53 riastradh Exp $       */
 
 /*
  * Copyright 2014 Red Hat Inc.
@@ -29,7 +29,7 @@
  ******************************************************************************/
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_nvif.c,v 1.3 2018/08/27 07:35:56 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_nvif.c,v 1.4 2018/08/27 14:47:53 riastradh Exp $");
 
 #include <core/client.h>
 #include <core/notify.h>
@@ -50,8 +50,25 @@
 nvkm_client_map(void *priv, bus_space_tag_t tag, u64 busaddr, u32 size,
     bus_space_handle_t *handlep, void __iomem **ptrp)
 {
+       struct nvkm_client *client = nvxx_client(priv);
        int ret;
 
+       if (tag == client->mmiot &&
+           client->mmioaddr <= busaddr &&
+           busaddr - client->mmioaddr <= client->mmiosz) {
+               const bus_size_t offset = busaddr - client->mmioaddr;
+               if (size > client->mmiosz - offset) {
+                       DRM_ERROR("Invalid register access\n");
+                       return -EFAULT;
+               }
+               ret = -bus_space_subregion(client->mmiot, client->mmioh,
+                   offset, size, handlep);
+               if (ret)
+                       return ret;
+               *ptrp = bus_space_vaddr(tag, *handlep);
+               return 0;
+       }
+
        ret = -bus_space_map(tag, busaddr, size, BUS_SPACE_MAP_LINEAR,
            handlep);
        if (ret)
@@ -62,8 +79,22 @@
 
 static void
 nvkm_client_unmap(void *priv, bus_space_tag_t tag, bus_space_handle_t handle,
-    u32 size)
+    bus_addr_t busaddr, void __iomem *ptr, u32 size)
 {
+       struct nvkm_client *client = nvxx_client(priv);
+
+       KASSERTMSG(ptr == bus_space_vaddr(tag, handle),
+           "nvkm_client ptr %p != %p [bus_space_vaddr(%p, %"PRIxVADDR")]",
+           ptr, bus_space_vaddr(tag, handle), tag, handle);
+
+       if (tag == client->mmiot &&
+           client->mmioaddr <= busaddr &&
+           busaddr - client->mmioaddr <= client->mmiosz) {
+               const bus_size_t offset = busaddr - client->mmioaddr;
+               KASSERT(size <= client->mmiosz - offset);
+               /* Nothing to do to release a subregion.  */
+               return;
+       }
 
        bus_space_unmap(tag, handle, size);
 }
diff -r 7efbb1bb43b1 -r a418eeab0358 sys/external/bsd/drm2/dist/drm/nouveau/nvif/nouveau_nvif_object.c
--- a/sys/external/bsd/drm2/dist/drm/nouveau/nvif/nouveau_nvif_object.c Mon Aug 27 14:47:29 2018 +0000
+++ b/sys/external/bsd/drm2/dist/drm/nouveau/nvif/nouveau_nvif_object.c Mon Aug 27 14:47:53 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nouveau_nvif_object.c,v 1.3 2018/08/27 07:35:56 riastradh Exp $        */
+/*     $NetBSD: nouveau_nvif_object.c,v 1.4 2018/08/27 14:47:53 riastradh Exp $        */
 
 /*
  * Copyright 2014 Red Hat Inc.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_nvif_object.c,v 1.3 2018/08/27 07:35:56 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_nvif_object.c,v 1.4 2018/08/27 14:47:53 riastradh Exp $");
 
 #include <nvif/object.h>
 #include <nvif/client.h>
@@ -185,6 +185,8 @@
                if (object->map.ptr) {
                        client->driver->unmap(client, object->map.tag,
                                                      object->map.handle,
+                                                     object->map.addr,
+                                                     object->map.ptr,
                                                      object->map.size);
                        object->map.ptr = NULL;
                }
@@ -216,6 +218,8 @@
        if (ret == 0) {
                object->map.size = args.map.length;
 #ifdef __NetBSD__
+               object->map.tag = args.map.tag;
+               object->map.addr = args.map.handle;
                ret = client->driver->map(client, args.map.tag,
                    args.map.handle, object->map.size, &object->map.handle,
                    &object->map.ptr);
diff -r 7efbb1bb43b1 -r a418eeab0358 sys/external/bsd/drm2/dist/drm/nouveau/nvkm/engine/device/nouveau_nvkm_engine_device_base.c
--- a/sys/external/bsd/drm2/dist/drm/nouveau/nvkm/engine/device/nouveau_nvkm_engine_device_base.c       Mon Aug 27 14:47:29 2018 +0000
+++ b/sys/external/bsd/drm2/dist/drm/nouveau/nvkm/engine/device/nouveau_nvkm_engine_device_base.c       Mon Aug 27 14:47:53 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nouveau_nvkm_engine_device_base.c,v 1.6 2018/08/27 13:43:52 riastradh Exp $    */
+/*     $NetBSD: nouveau_nvkm_engine_device_base.c,v 1.7 2018/08/27 14:47:53 riastradh Exp $    */
 
 /*
  * Copyright 2012 Red Hat Inc.
@@ -24,7 +24,7 @@
  * Authors: Ben Skeggs
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_engine_device_base.c,v 1.6 2018/08/27 13:43:52 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_engine_device_base.c,v 1.7 2018/08/27 14:47:53 riastradh Exp $");
 
 #include "priv.h"
 #include "acpi.h"
@@ -2570,6 +2570,7 @@
                }
                device->mmiot = mmiot;
                device->mmioh = mmioh;
+               device->mmioaddr = mmio_base;
                device->mmiosz = mmio_size;
 #else
                device->pri = ioremap(mmio_base, mmio_size);



Home | Main Index | Thread Index | Old Index