Ben Skeggs
2015-Nov-26 07:13 UTC
[Nouveau] [libdrm 01/13] nouveau: move more abi16-specific logic into abi16.c
From: Ben Skeggs <bskeggs at redhat.com> Signed-off-by: Ben Skeggs <bskeggs at redhat.com> --- nouveau/abi16.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++----- nouveau/nouveau.c | 56 +++++++------------------------------------------ nouveau/private.h | 7 ++----- 3 files changed, 67 insertions(+), 58 deletions(-) diff --git a/nouveau/abi16.c b/nouveau/abi16.c index 59bc436..8f24ba2 100644 --- a/nouveau/abi16.c +++ b/nouveau/abi16.c @@ -33,7 +33,7 @@ #include "private.h" -drm_private int +static int abi16_chan_nv04(struct nouveau_object *obj) { struct nouveau_device *dev = (struct nouveau_device *)obj->parent; @@ -57,7 +57,7 @@ abi16_chan_nv04(struct nouveau_object *obj) return 0; } -drm_private int +static int abi16_chan_nvc0(struct nouveau_object *obj) { struct nouveau_device *dev = (struct nouveau_device *)obj->parent; @@ -78,7 +78,7 @@ abi16_chan_nvc0(struct nouveau_object *obj) return 0; } -drm_private int +static int abi16_chan_nve0(struct nouveau_object *obj) { struct nouveau_device *dev = (struct nouveau_device *)obj->parent; @@ -104,7 +104,7 @@ abi16_chan_nve0(struct nouveau_object *obj) return 0; } -drm_private int +static int abi16_engobj(struct nouveau_object *obj) { struct drm_nouveau_grobj_alloc req = { @@ -125,7 +125,7 @@ abi16_engobj(struct nouveau_object *obj) return 0; } -drm_private int +static int abi16_ntfy(struct nouveau_object *obj) { struct nv04_notify *ntfy = obj->data; @@ -149,6 +149,58 @@ abi16_ntfy(struct nouveau_object *obj) } drm_private void +abi16_delete(struct nouveau_object *obj) +{ + struct nouveau_device *dev + nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS); + if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) { + struct drm_nouveau_channel_free req; + req.channel = obj->handle; + drmCommandWrite(dev->fd, DRM_NOUVEAU_CHANNEL_FREE, + &req, sizeof(req)); + } else { + struct drm_nouveau_gpuobj_free req; + req.channel = obj->parent->handle; + req.handle = obj->handle; + drmCommandWrite(dev->fd, DRM_NOUVEAU_GPUOBJ_FREE, + &req, sizeof(req)); + } +} + +drm_private bool +abi16_object(struct nouveau_object *obj, int (**func)(struct nouveau_object *)) +{ + struct nouveau_object *parent = obj->parent; + + if ((parent->length != 0 && parent->oclass == NOUVEAU_DEVICE_CLASS)) { + if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) { + struct nouveau_device *dev = (void *)parent; + if (dev->chipset < 0xc0) + *func = abi16_chan_nv04; + else + if (dev->chipset < 0xe0) + *func = abi16_chan_nvc0; + else + *func = abi16_chan_nve0; + return true; + } + } else + if ((parent->length != 0 && + parent->oclass == NOUVEAU_FIFO_CHANNEL_CLASS)) { + if (obj->oclass == NOUVEAU_NOTIFIER_CLASS) { + *func = abi16_ntfy; + return true; + } + + *func = abi16_engobj; + return false; + } + + *func = NULL; + return false; +} + +drm_private void abi16_bo_info(struct nouveau_bo *bo, struct drm_nouveau_gem_info *info) { struct nouveau_bo_priv *nvbo = nouveau_bo(bo); diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c index 97fd77b..8a0be2f 100644 --- a/nouveau/nouveau.c +++ b/nouveau/nouveau.c @@ -135,6 +135,7 @@ nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev) nvdev->gart_limit_percent = 80; DRMINITLISTHEAD(&nvdev->bo_list); nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS; + nvdev->base.object.length = ~0; nvdev->base.lib_version = 0x01000000; nvdev->base.chipset = chipset; nvdev->base.vram_size = vram; @@ -251,8 +252,8 @@ nouveau_object_new(struct nouveau_object *parent, uint64_t handle, uint32_t oclass, void *data, uint32_t length, struct nouveau_object **pobj) { - struct nouveau_device *dev; struct nouveau_object *obj; + int (*func)(struct nouveau_object *); int ret = -EINVAL; if (length == 0) @@ -267,37 +268,9 @@ nouveau_object_new(struct nouveau_object *parent, uint64_t handle, memcpy(obj->data, data, length); *(struct nouveau_object **)obj->data = obj; - dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS); - switch (parent->oclass) { - case NOUVEAU_DEVICE_CLASS: - switch (obj->oclass) { - case NOUVEAU_FIFO_CHANNEL_CLASS: - { - if (dev->chipset < 0xc0) - ret = abi16_chan_nv04(obj); - else - if (dev->chipset < 0xe0) - ret = abi16_chan_nvc0(obj); - else - ret = abi16_chan_nve0(obj); - } - break; - default: - break; - } - break; - case NOUVEAU_FIFO_CHANNEL_CLASS: - switch (obj->oclass) { - case NOUVEAU_NOTIFIER_CLASS: - ret = abi16_ntfy(obj); - break; - default: - ret = abi16_engobj(obj); - break; - } - default: - break; - } + abi16_object(obj, &func); + if (func) + ret = func(obj); if (ret) { free(obj); @@ -312,24 +285,11 @@ void nouveau_object_del(struct nouveau_object **pobj) { struct nouveau_object *obj = *pobj; - struct nouveau_device *dev; if (obj) { - dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS); - if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) { - struct drm_nouveau_channel_free req; - req.channel = obj->handle; - drmCommandWrite(dev->fd, DRM_NOUVEAU_CHANNEL_FREE, - &req, sizeof(req)); - } else { - struct drm_nouveau_gpuobj_free req; - req.channel = obj->parent->handle; - req.handle = obj->handle; - drmCommandWrite(dev->fd, DRM_NOUVEAU_GPUOBJ_FREE, - &req, sizeof(req)); - } + abi16_delete(obj); + free(obj); + *pobj = NULL; } - free(obj); - *pobj = NULL; } void * diff --git a/nouveau/private.h b/nouveau/private.h index e9439f3..5f352a4 100644 --- a/nouveau/private.h +++ b/nouveau/private.h @@ -114,11 +114,8 @@ int nouveau_device_open_existing(struct nouveau_device **, int, int, drm_context_t); /* abi16.c */ -drm_private int abi16_chan_nv04(struct nouveau_object *); -drm_private int abi16_chan_nvc0(struct nouveau_object *); -drm_private int abi16_chan_nve0(struct nouveau_object *); -drm_private int abi16_engobj(struct nouveau_object *); -drm_private int abi16_ntfy(struct nouveau_object *); +drm_private bool abi16_object(struct nouveau_object *, int (**)(struct nouveau_object *)); +drm_private void abi16_delete(struct nouveau_object *); drm_private void abi16_bo_info(struct nouveau_bo *, struct drm_nouveau_gem_info *); drm_private int abi16_bo_init(struct nouveau_bo *, uint32_t alignment, union nouveau_bo_config *); -- 2.6.3
Ben Skeggs
2015-Nov-26 07:13 UTC
[Nouveau] [libdrm 02/13] nouveau: move object functions up, to avoid future foward decls
From: Ben Skeggs <bskeggs at redhat.com> Signed-off-by: Ben Skeggs <bskeggs at redhat.com> --- nouveau/nouveau.c | 112 +++++++++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c index 8a0be2f..8035c6a 100644 --- a/nouveau/nouveau.c +++ b/nouveau/nouveau.c @@ -59,6 +59,62 @@ debug_init(char *args) } #endif +int +nouveau_object_new(struct nouveau_object *parent, uint64_t handle, + uint32_t oclass, void *data, uint32_t length, + struct nouveau_object **pobj) +{ + struct nouveau_object *obj; + int (*func)(struct nouveau_object *); + int ret = -EINVAL; + + if (length == 0) + length = sizeof(struct nouveau_object *); + obj = malloc(sizeof(*obj) + length); + obj->parent = parent; + obj->handle = handle; + obj->oclass = oclass; + obj->length = length; + obj->data = obj + 1; + if (data) + memcpy(obj->data, data, length); + *(struct nouveau_object **)obj->data = obj; + + abi16_object(obj, &func); + if (func) + ret = func(obj); + + if (ret) { + free(obj); + return ret; + } + + *pobj = obj; + return 0; +} + +void +nouveau_object_del(struct nouveau_object **pobj) +{ + struct nouveau_object *obj = *pobj; + if (obj) { + abi16_delete(obj); + free(obj); + *pobj = NULL; + } +} + +void * +nouveau_object_find(struct nouveau_object *obj, uint32_t pclass) +{ + while (obj && obj->oclass != pclass) { + obj = obj->parent; + if (pclass == NOUVEAU_PARENT_CLASS) + break; + } + return obj; +} + /* this is the old libdrm's version of nouveau_device_wrap(), the symbol * is kept here to prevent AIGLX from crashing if the DDX is linked against * the new libdrm, but the DRI driver against the old @@ -247,62 +303,6 @@ nouveau_client_del(struct nouveau_client **pclient) } } -int -nouveau_object_new(struct nouveau_object *parent, uint64_t handle, - uint32_t oclass, void *data, uint32_t length, - struct nouveau_object **pobj) -{ - struct nouveau_object *obj; - int (*func)(struct nouveau_object *); - int ret = -EINVAL; - - if (length == 0) - length = sizeof(struct nouveau_object *); - obj = malloc(sizeof(*obj) + length); - obj->parent = parent; - obj->handle = handle; - obj->oclass = oclass; - obj->length = length; - obj->data = obj + 1; - if (data) - memcpy(obj->data, data, length); - *(struct nouveau_object **)obj->data = obj; - - abi16_object(obj, &func); - if (func) - ret = func(obj); - - if (ret) { - free(obj); - return ret; - } - - *pobj = obj; - return 0; -} - -void -nouveau_object_del(struct nouveau_object **pobj) -{ - struct nouveau_object *obj = *pobj; - if (obj) { - abi16_delete(obj); - free(obj); - *pobj = NULL; - } -} - -void * -nouveau_object_find(struct nouveau_object *obj, uint32_t pclass) -{ - while (obj && obj->oclass != pclass) { - obj = obj->parent; - if (pclass == NOUVEAU_PARENT_CLASS) - break; - } - return obj; -} - static void nouveau_bo_del(struct nouveau_bo *bo) { -- 2.6.3
Ben Skeggs
2015-Nov-26 07:14 UTC
[Nouveau] [libdrm 03/13] nouveau: make it possible to init object in pre-allocated memory
From: Ben Skeggs <bskeggs at redhat.com> Required for an upcoming patch, not exposed to library clients. Signed-off-by: Ben Skeggs <bskeggs at redhat.com> --- nouveau/nouveau.c | 64 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c index 8035c6a..eb741c7 100644 --- a/nouveau/nouveau.c +++ b/nouveau/nouveau.c @@ -59,31 +59,63 @@ debug_init(char *args) } #endif -int -nouveau_object_new(struct nouveau_object *parent, uint64_t handle, - uint32_t oclass, void *data, uint32_t length, - struct nouveau_object **pobj) +static void +nouveau_object_fini(struct nouveau_object *obj) +{ + if (obj->data) { + abi16_delete(obj); + free(obj->data); + obj->data = NULL; + return; + } +} + +static int +nouveau_object_init(struct nouveau_object *parent, uint32_t handle, + int32_t oclass, void *data, uint32_t size, + struct nouveau_object *obj) { - struct nouveau_object *obj; int (*func)(struct nouveau_object *); - int ret = -EINVAL; + int ret = -ENOSYS; - if (length == 0) - length = sizeof(struct nouveau_object *); - obj = malloc(sizeof(*obj) + length); obj->parent = parent; obj->handle = handle; obj->oclass = oclass; - obj->length = length; - obj->data = obj + 1; - if (data) - memcpy(obj->data, data, length); - *(struct nouveau_object **)obj->data = obj; + obj->length = 0; + obj->data = NULL; abi16_object(obj, &func); - if (func) + if (func) { + obj->length = size ? size : sizeof(struct nouveau_object *); + if (!(obj->data = malloc(obj->length))) + return -ENOMEM; + if (data) + memcpy(obj->data, data, obj->length); + *(struct nouveau_object **)obj->data = obj; + ret = func(obj); + } + + if (ret) { + nouveau_object_fini(obj); + return ret; + } + + return 0; +} + +int +nouveau_object_new(struct nouveau_object *parent, uint64_t handle, + uint32_t oclass, void *data, uint32_t length, + struct nouveau_object **pobj) +{ + struct nouveau_object *obj; + int ret; + + if (!(obj = malloc(sizeof(*obj)))) + return -ENOMEM; + ret = nouveau_object_init(parent, handle, oclass, data, length, obj); if (ret) { free(obj); return ret; @@ -98,7 +130,7 @@ nouveau_object_del(struct nouveau_object **pobj) { struct nouveau_object *obj = *pobj; if (obj) { - abi16_delete(obj); + nouveau_object_fini(obj); free(obj); *pobj = NULL; } -- 2.6.3
Ben Skeggs
2015-Nov-26 07:14 UTC
[Nouveau] [libdrm 04/13] nouveau: add interface to call an object's methods
From: Ben Skeggs <bskeggs at redhat.com> This will expose functionality supported by newer kernel interfaces, giving access to things such as ZBC controls, perfmon, etc. Signed-off-by: Ben Skeggs <bskeggs at redhat.com> --- nouveau/nouveau-symbol-check | 1 + nouveau/nouveau.c | 7 +++++++ nouveau/nouveau.h | 2 ++ 3 files changed, 10 insertions(+) diff --git a/nouveau/nouveau-symbol-check b/nouveau/nouveau-symbol-check index 0fef563..7330170 100755 --- a/nouveau/nouveau-symbol-check +++ b/nouveau/nouveau-symbol-check @@ -33,6 +33,7 @@ nouveau_device_wrap nouveau_getparam nouveau_object_del nouveau_object_find +nouveau_object_mthd nouveau_object_new nouveau_pushbuf_bufctx nouveau_pushbuf_data diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c index eb741c7..1871e8c 100644 --- a/nouveau/nouveau.c +++ b/nouveau/nouveau.c @@ -59,6 +59,13 @@ debug_init(char *args) } #endif +int +nouveau_object_mthd(struct nouveau_object *obj, + uint32_t mthd, void *data, uint32_t size) +{ + return -ENODEV; +} + static void nouveau_object_fini(struct nouveau_object *obj) { diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h index 4adda0e..4c95409 100644 --- a/nouveau/nouveau.h +++ b/nouveau/nouveau.h @@ -67,6 +67,8 @@ int nouveau_object_new(struct nouveau_object *parent, uint64_t handle, uint32_t oclass, void *data, uint32_t length, struct nouveau_object **); void nouveau_object_del(struct nouveau_object **); +int nouveau_object_mthd(struct nouveau_object *, uint32_t mthd, + void *data, uint32_t size); void *nouveau_object_find(struct nouveau_object *, uint32_t parent_class); struct nouveau_device { -- 2.6.3
Ben Skeggs
2015-Nov-26 07:14 UTC
[Nouveau] [libdrm 05/13] nouveau: add interfaces to query information about supported classes
From: Ben Skeggs <bskeggs at redhat.com> This will expose functionality supported by newer kernel interfaces. Current userspace uses the chipset to determine which classes are likely exposed, which generally works pretty well, but isn't as flexible as it could be. Unfortunately, the G98:GF100 video code in Mesa is still relying on the kernel exposing incorrect vdec classes on some chipsets. The ABI16 kernel interfaces have a workaround for this in place, but that will no longer be available once libdrm supports NVIF. To prevent a regression when NVIF support is added, if there's no kernel support for NVIF, libdrm will magic up a class list containing correct vdec classes anyway instead of failing with -ENODEV. Signed-off-by: Ben Skeggs <bskeggs at redhat.com> --- nouveau/abi16.c | 28 ++++++++++++++++++++++++++++ nouveau/nouveau-symbol-check | 3 +++ nouveau/nouveau.c | 41 +++++++++++++++++++++++++++++++++++++++++ nouveau/nouveau.h | 17 +++++++++++++++++ nouveau/private.h | 1 + 5 files changed, 90 insertions(+) diff --git a/nouveau/abi16.c b/nouveau/abi16.c index 8f24ba2..34e9fb1 100644 --- a/nouveau/abi16.c +++ b/nouveau/abi16.c @@ -29,6 +29,7 @@ #include <stdlib.h> #include <stdint.h> #include <stddef.h> +#include <errno.h> #include "private.h" @@ -148,6 +149,33 @@ abi16_ntfy(struct nouveau_object *obj) return 0; } +drm_private int +abi16_sclass(struct nouveau_object *obj, struct nouveau_sclass **psclass) +{ + struct nouveau_sclass *sclass; + struct nouveau_device *dev; + + if (!(sclass = *psclass = calloc(8, sizeof(*sclass)))) + return -ENOMEM; + + switch (obj->oclass) { + case NOUVEAU_FIFO_CHANNEL_CLASS: + dev = (struct nouveau_device *)obj->parent; + if (dev->chipset >= 0x98 && + dev->chipset != 0xa0 && + dev->chipset < 0xc0) { + *sclass++ = (struct nouveau_sclass){ 0x85b1, -1, -1 }; + *sclass++ = (struct nouveau_sclass){ 0x85b2, -1, -1 }; + *sclass++ = (struct nouveau_sclass){ 0x85b3, -1, -1 }; + } + break; + default: + break; + } + + return sclass - *psclass; +} + drm_private void abi16_delete(struct nouveau_object *obj) { diff --git a/nouveau/nouveau-symbol-check b/nouveau/nouveau-symbol-check index 7330170..38b6ec5 100755 --- a/nouveau/nouveau-symbol-check +++ b/nouveau/nouveau-symbol-check @@ -33,8 +33,11 @@ nouveau_device_wrap nouveau_getparam nouveau_object_del nouveau_object_find +nouveau_object_mclass nouveau_object_mthd nouveau_object_new +nouveau_object_sclass_get +nouveau_object_sclass_put nouveau_pushbuf_bufctx nouveau_pushbuf_data nouveau_pushbuf_del diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c index 1871e8c..0017303 100644 --- a/nouveau/nouveau.c +++ b/nouveau/nouveau.c @@ -66,6 +66,47 @@ nouveau_object_mthd(struct nouveau_object *obj, return -ENODEV; } +void +nouveau_object_sclass_put(struct nouveau_sclass **psclass) +{ + free(*psclass); + *psclass = NULL; +} + +int +nouveau_object_sclass_get(struct nouveau_object *obj, + struct nouveau_sclass **psclass) +{ + return abi16_sclass(obj, psclass); +} + +int +nouveau_object_mclass(struct nouveau_object *obj, + const struct nouveau_mclass *mclass) +{ + struct nouveau_sclass *sclass; + int ret = -ENODEV; + int cnt, i, j; + + cnt = nouveau_object_sclass_get(obj, &sclass); + if (cnt < 0) + return cnt; + + for (i = 0; ret < 0 && mclass[i].oclass; i++) { + for (j = 0; j < cnt; j++) { + if (mclass[i].oclass == sclass[j].oclass && + mclass[i].version >= sclass[j].minver && + mclass[i].version <= sclass[j].maxver) { + ret = i; + break; + } + } + } + + nouveau_object_sclass_put(&sclass); + return ret; +} + static void nouveau_object_fini(struct nouveau_object *obj) { diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h index 4c95409..9f774ab 100644 --- a/nouveau/nouveau.h +++ b/nouveau/nouveau.h @@ -63,12 +63,29 @@ struct nv04_notify { uint32_t length; }; +struct nouveau_sclass { + int32_t oclass; + int minver; + int maxver; +}; + +struct nouveau_mclass { + int32_t oclass; + int version; + void *data; +}; + int nouveau_object_new(struct nouveau_object *parent, uint64_t handle, uint32_t oclass, void *data, uint32_t length, struct nouveau_object **); void nouveau_object_del(struct nouveau_object **); int nouveau_object_mthd(struct nouveau_object *, uint32_t mthd, void *data, uint32_t size); +int nouveau_object_sclass_get(struct nouveau_object *, + struct nouveau_sclass **); +void nouveau_object_sclass_put(struct nouveau_sclass **); +int nouveau_object_mclass(struct nouveau_object *, + const struct nouveau_mclass *); void *nouveau_object_find(struct nouveau_object *, uint32_t parent_class); struct nouveau_device { diff --git a/nouveau/private.h b/nouveau/private.h index 5f352a4..83060f9 100644 --- a/nouveau/private.h +++ b/nouveau/private.h @@ -116,6 +116,7 @@ nouveau_device_open_existing(struct nouveau_device **, int, int, drm_context_t); /* abi16.c */ drm_private bool abi16_object(struct nouveau_object *, int (**)(struct nouveau_object *)); drm_private void abi16_delete(struct nouveau_object *); +drm_private int abi16_sclass(struct nouveau_object *, struct nouveau_sclass **); drm_private void abi16_bo_info(struct nouveau_bo *, struct drm_nouveau_gem_info *); drm_private int abi16_bo_init(struct nouveau_bo *, uint32_t alignment, union nouveau_bo_config *); -- 2.6.3
Ben Skeggs
2015-Nov-26 07:14 UTC
[Nouveau] [libdrm 06/13] nouveau: introduce object to represent the kernel client
From: Ben Skeggs <bskeggs at redhat.com> Because NVIF intentionally lacks some of the paths necessary to be compatible with various mistakes we've made over the years, libdrm needs to know whether a client has been updated and that it's safe to make use of the new kernel interfaces. Clients still using nouveau_device_open()/wrap() will be forced to make use of ABI16 instead of NVIF. Signed-off-by: Ben Skeggs <bskeggs at redhat.com> --- nouveau/nouveau-symbol-check | 2 ++ nouveau/nouveau.c | 35 +++++++++++++++++++++++++++++++++++ nouveau/nouveau.h | 19 +++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/nouveau/nouveau-symbol-check b/nouveau/nouveau-symbol-check index 38b6ec5..e360b92 100755 --- a/nouveau/nouveau-symbol-check +++ b/nouveau/nouveau-symbol-check @@ -30,6 +30,8 @@ nouveau_device_del nouveau_device_open nouveau_device_open_existing nouveau_device_wrap +nouveau_drm_del +nouveau_drm_new nouveau_getparam nouveau_object_del nouveau_object_find diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c index 0017303..9f82fde 100644 --- a/nouveau/nouveau.c +++ b/nouveau/nouveau.c @@ -195,6 +195,41 @@ nouveau_object_find(struct nouveau_object *obj, uint32_t pclass) return obj; } +void +nouveau_drm_del(struct nouveau_drm **pdrm) +{ + free(*pdrm); + *pdrm = NULL; +} + +int +nouveau_drm_new(int fd, struct nouveau_drm **pdrm) +{ + struct nouveau_drm *drm; + drmVersionPtr ver; + +#ifdef DEBUG + debug_init(getenv("NOUVEAU_LIBDRM_DEBUG")); +#endif + + if (!(drm = *pdrm = calloc(1, sizeof(*drm)))) + return -ENOMEM; + drm->fd = fd; + + if (!(ver = drmGetVersion(fd))) { + nouveau_drm_del(pdrm); + return -EINVAL; + } + + drm->drm_version = (ver->version_major << 24) | + (ver->version_minor << 8) | + ver->version_patchlevel; + drm->lib_version = 0x01000300; + drm->nvif = false; + drmFreeVersion(ver); + return 0; +} + /* this is the old libdrm's version of nouveau_device_wrap(), the symbol * is kept here to prevent AIGLX from crashing if the DDX is linked against * the new libdrm, but the DRI driver against the old diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h index 9f774ab..58e662f 100644 --- a/nouveau/nouveau.h +++ b/nouveau/nouveau.h @@ -22,6 +22,25 @@ struct nouveau_object { void *data; }; +struct nouveau_drm { + struct nouveau_object client; + int fd; + uint32_t drm_version; + uint32_t lib_version; + bool nvif; +}; + +static inline struct nouveau_drm * +nouveau_drm(struct nouveau_object *obj) +{ + while (obj && obj->parent) + obj = obj->parent; + return (struct nouveau_drm *)obj; +} + +int nouveau_drm_new(int fd, struct nouveau_drm **); +void nouveau_drm_del(struct nouveau_drm **); + struct nouveau_fifo { struct nouveau_object *object; uint32_t channel; -- 2.6.3
Ben Skeggs
2015-Nov-26 07:14 UTC
[Nouveau] [libdrm 07/13] nouveau: stack legacy nouveau_device on top of nouveau_drm
From: Ben Skeggs <bskeggs at redhat.com> Signed-off-by: Ben Skeggs <bskeggs at redhat.com> --- nouveau/nouveau.c | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c index 9f82fde..e304a1b 100644 --- a/nouveau/nouveau.c +++ b/nouveau/nouveau.c @@ -244,39 +244,36 @@ nouveau_device_open_existing(struct nouveau_device **pdev, int close, int fd, int nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev) { - struct nouveau_device_priv *nvdev = calloc(1, sizeof(*nvdev)); - struct nouveau_device *dev = &nvdev->base; + struct nouveau_drm *drm; + struct nouveau_device_priv *nvdev; + struct nouveau_device *dev; uint64_t chipset, vram, gart, bousage; - drmVersionPtr ver; int ret; char *tmp; -#ifdef DEBUG - debug_init(getenv("NOUVEAU_LIBDRM_DEBUG")); -#endif - - if (!nvdev) + if (!(nvdev = calloc(1, sizeof(*nvdev)))) return -ENOMEM; + dev = &nvdev->base; + ret = pthread_mutex_init(&nvdev->lock, NULL); if (ret) { free(nvdev); return ret; } - nvdev->base.fd = fd; - - ver = drmGetVersion(fd); - if (ver) dev->drm_version = (ver->version_major << 24) | - (ver->version_minor << 8) | - ver->version_patchlevel; - drmFreeVersion(ver); - - if ( dev->drm_version != 0x00000010 && - (dev->drm_version < 0x01000000 || - dev->drm_version >= 0x02000000)) { + ret = nouveau_drm_new(fd, &drm); + if (ret) { nouveau_device_del(&dev); - return -EINVAL; + return ret; } + drm->nvif = false; + + nvdev->base.object.parent = &drm->client; + nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS; + nvdev->base.object.length = ~0; + nvdev->base.fd = drm->fd; + nvdev->base.drm_version = drm->drm_version; + nvdev->base.lib_version = drm->lib_version; ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_CHIPSET_ID, &chipset); if (ret == 0) @@ -305,9 +302,6 @@ nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev) else nvdev->gart_limit_percent = 80; DRMINITLISTHEAD(&nvdev->bo_list); - nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS; - nvdev->base.object.length = ~0; - nvdev->base.lib_version = 0x01000000; nvdev->base.chipset = chipset; nvdev->base.vram_size = vram; nvdev->base.gart_size = gart; @@ -337,10 +331,12 @@ nouveau_device_del(struct nouveau_device **pdev) { struct nouveau_device_priv *nvdev = nouveau_device(*pdev); if (nvdev) { - if (nvdev->close) - drmClose(nvdev->base.fd); + struct nouveau_drm *drm = nouveau_drm(&nvdev->base.object); free(nvdev->client); + nouveau_drm_del(&drm); pthread_mutex_destroy(&nvdev->lock); + if (nvdev->close) + drmClose(nvdev->base.fd); free(nvdev); *pdev = NULL; } -- 2.6.3
Ben Skeggs
2015-Nov-26 07:14 UTC
[Nouveau] [libdrm 08/13] nouveau: make use of nouveau_drm::fd instead of nouveau_device::fd
From: Ben Skeggs <bskeggs at redhat.com> The latter is deprecated, and will not be valid for newer clients. Signed-off-by: Ben Skeggs <bskeggs at redhat.com> --- nouveau/abi16.c | 32 +++++++++++++++----------------- nouveau/nouveau-symbol-check | 1 - nouveau/nouveau.c | 43 +++++++++++++++++++++---------------------- nouveau/nouveau.h | 1 - nouveau/pushbuf.c | 7 ++++--- 5 files changed, 40 insertions(+), 44 deletions(-) diff --git a/nouveau/abi16.c b/nouveau/abi16.c index 34e9fb1..5ba2690 100644 --- a/nouveau/abi16.c +++ b/nouveau/abi16.c @@ -37,7 +37,7 @@ static int abi16_chan_nv04(struct nouveau_object *obj) { - struct nouveau_device *dev = (struct nouveau_device *)obj->parent; + struct nouveau_drm *drm = nouveau_drm(obj); struct nv04_fifo *nv04 = obj->data; struct drm_nouveau_channel_alloc req = { .fb_ctxdma_handle = nv04->vram, @@ -45,7 +45,7 @@ abi16_chan_nv04(struct nouveau_object *obj) }; int ret; - ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC, + ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_CHANNEL_ALLOC, &req, sizeof(req)); if (ret) return ret; @@ -61,12 +61,12 @@ abi16_chan_nv04(struct nouveau_object *obj) static int abi16_chan_nvc0(struct nouveau_object *obj) { - struct nouveau_device *dev = (struct nouveau_device *)obj->parent; + struct nouveau_drm *drm = nouveau_drm(obj); struct drm_nouveau_channel_alloc req = {}; struct nvc0_fifo *nvc0 = obj->data; int ret; - ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC, + ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_CHANNEL_ALLOC, &req, sizeof(req)); if (ret) return ret; @@ -82,7 +82,7 @@ abi16_chan_nvc0(struct nouveau_object *obj) static int abi16_chan_nve0(struct nouveau_object *obj) { - struct nouveau_device *dev = (struct nouveau_device *)obj->parent; + struct nouveau_drm *drm = nouveau_drm(obj); struct drm_nouveau_channel_alloc req = {}; struct nve0_fifo *nve0 = obj->data; int ret; @@ -92,7 +92,7 @@ abi16_chan_nve0(struct nouveau_object *obj) req.tt_ctxdma_handle = nve0->engine; } - ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC, + ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_CHANNEL_ALLOC, &req, sizeof(req)); if (ret) return ret; @@ -108,16 +108,15 @@ abi16_chan_nve0(struct nouveau_object *obj) static int abi16_engobj(struct nouveau_object *obj) { + struct nouveau_drm *drm = nouveau_drm(obj); struct drm_nouveau_grobj_alloc req = { .channel = obj->parent->handle, .handle = obj->handle, .class = obj->oclass, }; - struct nouveau_device *dev; int ret; - dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS); - ret = drmCommandWrite(dev->fd, DRM_NOUVEAU_GROBJ_ALLOC, + ret = drmCommandWrite(drm->fd, DRM_NOUVEAU_GROBJ_ALLOC, &req, sizeof(req)); if (ret) return ret; @@ -129,17 +128,16 @@ abi16_engobj(struct nouveau_object *obj) static int abi16_ntfy(struct nouveau_object *obj) { + struct nouveau_drm *drm = nouveau_drm(obj); struct nv04_notify *ntfy = obj->data; struct drm_nouveau_notifierobj_alloc req = { .channel = obj->parent->handle, .handle = ntfy->object->handle, .size = ntfy->length, }; - struct nouveau_device *dev; int ret; - dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS); - ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, + ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, &req, sizeof(req)); if (ret) return ret; @@ -179,18 +177,17 @@ abi16_sclass(struct nouveau_object *obj, struct nouveau_sclass **psclass) drm_private void abi16_delete(struct nouveau_object *obj) { - struct nouveau_device *dev - nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS); + struct nouveau_drm *drm = nouveau_drm(obj); if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) { struct drm_nouveau_channel_free req; req.channel = obj->handle; - drmCommandWrite(dev->fd, DRM_NOUVEAU_CHANNEL_FREE, + drmCommandWrite(drm->fd, DRM_NOUVEAU_CHANNEL_FREE, &req, sizeof(req)); } else { struct drm_nouveau_gpuobj_free req; req.channel = obj->parent->handle; req.handle = obj->handle; - drmCommandWrite(dev->fd, DRM_NOUVEAU_GPUOBJ_FREE, + drmCommandWrite(drm->fd, DRM_NOUVEAU_GPUOBJ_FREE, &req, sizeof(req)); } } @@ -267,6 +264,7 @@ abi16_bo_init(struct nouveau_bo *bo, uint32_t alignment, union nouveau_bo_config *config) { struct nouveau_device *dev = bo->device; + struct nouveau_drm *drm = nouveau_drm(&dev->object); struct drm_nouveau_gem_new req = {}; struct drm_nouveau_gem_info *info = &req.info; int ret; @@ -309,7 +307,7 @@ abi16_bo_init(struct nouveau_bo *bo, uint32_t alignment, if (!nouveau_device(dev)->have_bo_usage) info->tile_flags &= 0x0000ff00; - ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_NEW, + ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_GEM_NEW, &req, sizeof(req)); if (ret == 0) abi16_bo_info(bo, &req.info); diff --git a/nouveau/nouveau-symbol-check b/nouveau/nouveau-symbol-check index e360b92..275b6e7 100755 --- a/nouveau/nouveau-symbol-check +++ b/nouveau/nouveau-symbol-check @@ -34,7 +34,6 @@ nouveau_drm_del nouveau_drm_new nouveau_getparam nouveau_object_del -nouveau_object_find nouveau_object_mclass nouveau_object_mthd nouveau_object_new diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c index e304a1b..06fdeed 100644 --- a/nouveau/nouveau.c +++ b/nouveau/nouveau.c @@ -184,17 +184,6 @@ nouveau_object_del(struct nouveau_object **pobj) } } -void * -nouveau_object_find(struct nouveau_object *obj, uint32_t pclass) -{ - while (obj && obj->oclass != pclass) { - obj = obj->parent; - if (pclass == NOUVEAU_PARENT_CLASS) - break; - } - return obj; -} - void nouveau_drm_del(struct nouveau_drm **pdrm) { @@ -345,8 +334,9 @@ nouveau_device_del(struct nouveau_device **pdev) int nouveau_getparam(struct nouveau_device *dev, uint64_t param, uint64_t *value) { + struct nouveau_drm *drm = nouveau_drm(&dev->object); struct drm_nouveau_getparam r = { .param = param }; - int fd = dev->fd, ret + int fd = drm->fd, ret drmCommandWriteRead(fd, DRM_NOUVEAU_GETPARAM, &r, sizeof(r)); *value = r.value; return ret; @@ -355,8 +345,9 @@ nouveau_getparam(struct nouveau_device *dev, uint64_t param, uint64_t *value) int nouveau_setparam(struct nouveau_device *dev, uint64_t param, uint64_t value) { + struct nouveau_drm *drm = nouveau_drm(&dev->object); struct drm_nouveau_setparam r = { .param = param, .value = value }; - return drmCommandWrite(dev->fd, DRM_NOUVEAU_SETPARAM, &r, sizeof(r)); + return drmCommandWrite(drm->fd, DRM_NOUVEAU_SETPARAM, &r, sizeof(r)); } int @@ -417,6 +408,7 @@ nouveau_client_del(struct nouveau_client **pclient) static void nouveau_bo_del(struct nouveau_bo *bo) { + struct nouveau_drm *drm = nouveau_drm(&bo->device->object); struct nouveau_device_priv *nvdev = nouveau_device(bo->device); struct nouveau_bo_priv *nvbo = nouveau_bo(bo); struct drm_gem_close req = { .handle = bo->handle }; @@ -433,11 +425,11 @@ nouveau_bo_del(struct nouveau_bo *bo) * might cause the bo to be closed accidentally while * re-importing. */ - drmIoctl(bo->device->fd, DRM_IOCTL_GEM_CLOSE, &req); + drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &req); } pthread_mutex_unlock(&nvdev->lock); } else { - drmIoctl(bo->device->fd, DRM_IOCTL_GEM_CLOSE, &req); + drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &req); } if (bo->map) drm_munmap(bo->map, bo->size); @@ -474,6 +466,7 @@ static int nouveau_bo_wrap_locked(struct nouveau_device *dev, uint32_t handle, struct nouveau_bo **pbo, int name) { + struct nouveau_drm *drm = nouveau_drm(&dev->object); struct nouveau_device_priv *nvdev = nouveau_device(dev); struct drm_nouveau_gem_info req = { .handle = handle }; struct nouveau_bo_priv *nvbo; @@ -503,7 +496,7 @@ nouveau_bo_wrap_locked(struct nouveau_device *dev, uint32_t handle, } } - ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_INFO, + ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_GEM_INFO, &req, sizeof(req)); if (ret) return ret; @@ -550,6 +543,7 @@ int nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name, struct nouveau_bo **pbo) { + struct nouveau_drm *drm = nouveau_drm(&dev->object); struct nouveau_device_priv *nvdev = nouveau_device(dev); struct nouveau_bo_priv *nvbo; struct drm_gem_open req = { .name = name }; @@ -565,7 +559,7 @@ nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name, } } - ret = drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req); + ret = drmIoctl(drm->fd, DRM_IOCTL_GEM_OPEN, &req); if (ret == 0) { ret = nouveau_bo_wrap_locked(dev, req.handle, pbo, name); } @@ -578,11 +572,12 @@ int nouveau_bo_name_get(struct nouveau_bo *bo, uint32_t *name) { struct drm_gem_flink req = { .handle = bo->handle }; + struct nouveau_drm *drm = nouveau_drm(&bo->device->object); struct nouveau_bo_priv *nvbo = nouveau_bo(bo); *name = nvbo->name; if (!*name) { - int ret = drmIoctl(bo->device->fd, DRM_IOCTL_GEM_FLINK, &req); + int ret = drmIoctl(drm->fd, DRM_IOCTL_GEM_FLINK, &req); if (ret) { *name = 0; @@ -613,6 +608,7 @@ int nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd, struct nouveau_bo **bo) { + struct nouveau_drm *drm = nouveau_drm(&dev->object); struct nouveau_device_priv *nvdev = nouveau_device(dev); int ret; unsigned int handle; @@ -620,7 +616,7 @@ nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd, nouveau_bo_ref(NULL, bo); pthread_mutex_lock(&nvdev->lock); - ret = drmPrimeFDToHandle(dev->fd, prime_fd, &handle); + ret = drmPrimeFDToHandle(drm->fd, prime_fd, &handle); if (ret == 0) { ret = nouveau_bo_wrap_locked(dev, handle, bo, 0); } @@ -631,10 +627,11 @@ nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd, int nouveau_bo_set_prime(struct nouveau_bo *bo, int *prime_fd) { + struct nouveau_drm *drm = nouveau_drm(&bo->device->object); struct nouveau_bo_priv *nvbo = nouveau_bo(bo); int ret; - ret = drmPrimeHandleToFD(bo->device->fd, nvbo->base.handle, DRM_CLOEXEC, prime_fd); + ret = drmPrimeHandleToFD(drm->fd, nvbo->base.handle, DRM_CLOEXEC, prime_fd); if (ret) return ret; @@ -646,6 +643,7 @@ int nouveau_bo_wait(struct nouveau_bo *bo, uint32_t access, struct nouveau_client *client) { + struct nouveau_drm *drm = nouveau_drm(&bo->device->object); struct nouveau_bo_priv *nvbo = nouveau_bo(bo); struct drm_nouveau_gem_cpu_prep req; struct nouveau_pushbuf *push; @@ -669,7 +667,7 @@ nouveau_bo_wait(struct nouveau_bo *bo, uint32_t access, if (access & NOUVEAU_BO_NOBLOCK) req.flags |= NOUVEAU_GEM_CPU_PREP_NOWAIT; - ret = drmCommandWrite(bo->device->fd, DRM_NOUVEAU_GEM_CPU_PREP, + ret = drmCommandWrite(drm->fd, DRM_NOUVEAU_GEM_CPU_PREP, &req, sizeof(req)); if (ret == 0) nvbo->access = 0; @@ -680,10 +678,11 @@ int nouveau_bo_map(struct nouveau_bo *bo, uint32_t access, struct nouveau_client *client) { + struct nouveau_drm *drm = nouveau_drm(&bo->device->object); struct nouveau_bo_priv *nvbo = nouveau_bo(bo); if (bo->map == NULL) { bo->map = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE, - MAP_SHARED, bo->device->fd, nvbo->map_handle); + MAP_SHARED, drm->fd, nvbo->map_handle); if (bo->map == MAP_FAILED) { bo->map = NULL; return -errno; diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h index 58e662f..86d7338 100644 --- a/nouveau/nouveau.h +++ b/nouveau/nouveau.h @@ -105,7 +105,6 @@ int nouveau_object_sclass_get(struct nouveau_object *, void nouveau_object_sclass_put(struct nouveau_sclass **); int nouveau_object_mclass(struct nouveau_object *, const struct nouveau_mclass *); -void *nouveau_object_find(struct nouveau_object *, uint32_t parent_class); struct nouveau_device { struct nouveau_object object; diff --git a/nouveau/pushbuf.c b/nouveau/pushbuf.c index 8e7dcdf..035e301 100644 --- a/nouveau/pushbuf.c +++ b/nouveau/pushbuf.c @@ -312,6 +312,7 @@ pushbuf_submit(struct nouveau_pushbuf *push, struct nouveau_object *chan) struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(push); struct nouveau_pushbuf_krec *krec = nvpb->list; struct nouveau_device *dev = push->client->device; + struct nouveau_drm *drm = nouveau_drm(&dev->object); struct drm_nouveau_gem_pushbuf_bo_presumed *info; struct drm_nouveau_gem_pushbuf_bo *kref; struct drm_nouveau_gem_pushbuf req; @@ -345,7 +346,7 @@ pushbuf_submit(struct nouveau_pushbuf *push, struct nouveau_object *chan) pushbuf_dump(krec, krec_id++, fifo->channel); #ifndef SIMULATE - ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_PUSHBUF, + ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_GEM_PUSHBUF, &req, sizeof(req)); nvpb->suffix0 = req.suffix0; nvpb->suffix1 = req.suffix1; @@ -536,7 +537,7 @@ nouveau_pushbuf_new(struct nouveau_client *client, struct nouveau_object *chan, int nr, uint32_t size, bool immediate, struct nouveau_pushbuf **ppush) { - struct nouveau_device *dev = client->device; + struct nouveau_drm *drm = nouveau_drm(&client->device->object); struct nouveau_fifo *fifo = chan->data; struct nouveau_pushbuf_priv *nvpb; struct nouveau_pushbuf *push; @@ -551,7 +552,7 @@ nouveau_pushbuf_new(struct nouveau_client *client, struct nouveau_object *chan, */ req.channel = fifo->channel; req.nr_push = 0; - ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_PUSHBUF, + ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_GEM_PUSHBUF, &req, sizeof(req)); if (ret) return ret; -- 2.6.3
Ben Skeggs
2015-Nov-26 07:14 UTC
[Nouveau] [libdrm 09/13] nouveau: import and install a selection of nvif headers from the kernel
From: Ben Skeggs <bskeggs at redhat.com> Signed-off-by: Ben Skeggs <bskeggs at redhat.com> --- include/drm/nouveau_drm.h | 1 + nouveau/Makefile.am | 11 +++- nouveau/libdrm_nouveau.pc.in | 2 +- nouveau/nvif/cl0080.h | 45 ++++++++++++++ nouveau/nvif/cl9097.h | 44 ++++++++++++++ nouveau/nvif/class.h | 141 +++++++++++++++++++++++++++++++++++++++++++ nouveau/nvif/if0002.h | 38 ++++++++++++ nouveau/nvif/if0003.h | 33 ++++++++++ nouveau/nvif/ioctl.h | 132 ++++++++++++++++++++++++++++++++++++++++ nouveau/nvif/unpack.h | 28 +++++++++ 10 files changed, 473 insertions(+), 2 deletions(-) create mode 100644 nouveau/nvif/cl0080.h create mode 100644 nouveau/nvif/cl9097.h create mode 100644 nouveau/nvif/class.h create mode 100644 nouveau/nvif/if0002.h create mode 100644 nouveau/nvif/if0003.h create mode 100644 nouveau/nvif/ioctl.h create mode 100644 nouveau/nvif/unpack.h diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h index 87aefc5..e418f9f 100644 --- a/include/drm/nouveau_drm.h +++ b/include/drm/nouveau_drm.h @@ -200,6 +200,7 @@ struct drm_nouveau_sarea { #define DRM_NOUVEAU_GROBJ_ALLOC 0x04 #define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x05 #define DRM_NOUVEAU_GPUOBJ_FREE 0x06 +#define DRM_NOUVEAU_NVIF 0x07 #define DRM_NOUVEAU_GEM_NEW 0x40 #define DRM_NOUVEAU_GEM_PUSHBUF 0x41 #define DRM_NOUVEAU_GEM_CPU_PREP 0x42 diff --git a/nouveau/Makefile.am b/nouveau/Makefile.am index 25ea6dc..76cdeca 100644 --- a/nouveau/Makefile.am +++ b/nouveau/Makefile.am @@ -14,9 +14,18 @@ libdrm_nouveau_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@ libdrm_nouveau_la_SOURCES = $(LIBDRM_NOUVEAU_FILES) -libdrm_nouveauincludedir = ${includedir}/libdrm +libdrm_nouveauincludedir = ${includedir}/libdrm/nouveau libdrm_nouveauinclude_HEADERS = $(LIBDRM_NOUVEAU_H_FILES) +libdrm_nouveaunvifincludedir = ${includedir}/libdrm/nouveau/nvif +libdrm_nouveaunvifinclude_HEADERS = nvif/class.h \ + nvif/cl0080.h \ + nvif/cl9097.h \ + nvif/if0002.h \ + nvif/if0003.h \ + nvif/ioctl.h \ + nvif/unpack.h + pkgconfigdir = @pkgconfigdir@ pkgconfig_DATA = libdrm_nouveau.pc diff --git a/nouveau/libdrm_nouveau.pc.in b/nouveau/libdrm_nouveau.pc.in index 9abfd81..7d0622e 100644 --- a/nouveau/libdrm_nouveau.pc.in +++ b/nouveau/libdrm_nouveau.pc.in @@ -7,5 +7,5 @@ Name: libdrm_nouveau Description: Userspace interface to nouveau kernel DRM services Version: @PACKAGE_VERSION@ Libs: -L${libdir} -ldrm_nouveau -Cflags: -I${includedir} -I${includedir}/libdrm +Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/libdrm/nouveau Requires.private: libdrm diff --git a/nouveau/nvif/cl0080.h b/nouveau/nvif/cl0080.h new file mode 100644 index 0000000..331620a --- /dev/null +++ b/nouveau/nvif/cl0080.h @@ -0,0 +1,45 @@ +#ifndef __NVIF_CL0080_H__ +#define __NVIF_CL0080_H__ + +struct nv_device_v0 { + __u8 version; + __u8 pad01[7]; + __u64 device; /* device identifier, ~0 for client default */ +}; + +#define NV_DEVICE_V0_INFO 0x00 +#define NV_DEVICE_V0_TIME 0x01 + +struct nv_device_info_v0 { + __u8 version; +#define NV_DEVICE_INFO_V0_IGP 0x00 +#define NV_DEVICE_INFO_V0_PCI 0x01 +#define NV_DEVICE_INFO_V0_AGP 0x02 +#define NV_DEVICE_INFO_V0_PCIE 0x03 +#define NV_DEVICE_INFO_V0_SOC 0x04 + __u8 platform; + __u16 chipset; /* from NV_PMC_BOOT_0 */ + __u8 revision; /* from NV_PMC_BOOT_0 */ +#define NV_DEVICE_INFO_V0_TNT 0x01 +#define NV_DEVICE_INFO_V0_CELSIUS 0x02 +#define NV_DEVICE_INFO_V0_KELVIN 0x03 +#define NV_DEVICE_INFO_V0_RANKINE 0x04 +#define NV_DEVICE_INFO_V0_CURIE 0x05 +#define NV_DEVICE_INFO_V0_TESLA 0x06 +#define NV_DEVICE_INFO_V0_FERMI 0x07 +#define NV_DEVICE_INFO_V0_KEPLER 0x08 +#define NV_DEVICE_INFO_V0_MAXWELL 0x09 + __u8 family; + __u8 pad06[2]; + __u64 ram_size; + __u64 ram_user; + char chip[16]; + char name[64]; +}; + +struct nv_device_time_v0 { + __u8 version; + __u8 pad01[7]; + __u64 time; +}; +#endif diff --git a/nouveau/nvif/cl9097.h b/nouveau/nvif/cl9097.h new file mode 100644 index 0000000..4057676 --- /dev/null +++ b/nouveau/nvif/cl9097.h @@ -0,0 +1,44 @@ +#ifndef __NVIF_CL9097_H__ +#define __NVIF_CL9097_H__ + +#define FERMI_A_ZBC_COLOR 0x00 +#define FERMI_A_ZBC_DEPTH 0x01 + +struct fermi_a_zbc_color_v0 { + __u8 version; +#define FERMI_A_ZBC_COLOR_V0_FMT_ZERO 0x01 +#define FERMI_A_ZBC_COLOR_V0_FMT_UNORM_ONE 0x02 +#define FERMI_A_ZBC_COLOR_V0_FMT_RF32_GF32_BF32_AF32 0x04 +#define FERMI_A_ZBC_COLOR_V0_FMT_R16_G16_B16_A16 0x08 +#define FERMI_A_ZBC_COLOR_V0_FMT_RN16_GN16_BN16_AN16 0x0c +#define FERMI_A_ZBC_COLOR_V0_FMT_RS16_GS16_BS16_AS16 0x10 +#define FERMI_A_ZBC_COLOR_V0_FMT_RU16_GU16_BU16_AU16 0x14 +#define FERMI_A_ZBC_COLOR_V0_FMT_RF16_GF16_BF16_AF16 0x16 +#define FERMI_A_ZBC_COLOR_V0_FMT_A8R8G8B8 0x18 +#define FERMI_A_ZBC_COLOR_V0_FMT_A8RL8GL8BL8 0x1c +#define FERMI_A_ZBC_COLOR_V0_FMT_A2B10G10R10 0x20 +#define FERMI_A_ZBC_COLOR_V0_FMT_AU2BU10GU10RU10 0x24 +#define FERMI_A_ZBC_COLOR_V0_FMT_A8B8G8R8 0x28 +#define FERMI_A_ZBC_COLOR_V0_FMT_A8BL8GL8RL8 0x2c +#define FERMI_A_ZBC_COLOR_V0_FMT_AN8BN8GN8RN8 0x30 +#define FERMI_A_ZBC_COLOR_V0_FMT_AS8BS8GS8RS8 0x34 +#define FERMI_A_ZBC_COLOR_V0_FMT_AU8BU8GU8RU8 0x38 +#define FERMI_A_ZBC_COLOR_V0_FMT_A2R10G10B10 0x3c +#define FERMI_A_ZBC_COLOR_V0_FMT_BF10GF11RF11 0x40 + __u8 format; + __u8 index; + __u8 pad03[5]; + __u32 ds[4]; + __u32 l2[4]; +}; + +struct fermi_a_zbc_depth_v0 { + __u8 version; +#define FERMI_A_ZBC_DEPTH_V0_FMT_FP32 0x01 + __u8 format; + __u8 index; + __u8 pad03[5]; + __u32 ds; + __u32 l2; +}; +#endif diff --git a/nouveau/nvif/class.h b/nouveau/nvif/class.h new file mode 100644 index 0000000..4179cd6 --- /dev/null +++ b/nouveau/nvif/class.h @@ -0,0 +1,141 @@ +#ifndef __NVIF_CLASS_H__ +#define __NVIF_CLASS_H__ + +/* these class numbers are made up by us, and not nvidia-assigned */ +#define NVIF_CLASS_CONTROL /* if0001.h */ -1 +#define NVIF_CLASS_PERFMON /* if0002.h */ -2 +#define NVIF_CLASS_PERFDOM /* if0003.h */ -3 +#define NVIF_CLASS_SW_NV04 /* if0004.h */ -4 +#define NVIF_CLASS_SW_NV10 /* if0005.h */ -5 +#define NVIF_CLASS_SW_NV50 /* if0005.h */ -6 +#define NVIF_CLASS_SW_GF100 /* if0005.h */ -7 + +/* the below match nvidia-assigned (either in hw, or sw) class numbers */ +#define NV_DEVICE /* cl0080.h */ 0x00000080 + +#define NV_DMA_FROM_MEMORY /* cl0002.h */ 0x00000002 +#define NV_DMA_TO_MEMORY /* cl0002.h */ 0x00000003 +#define NV_DMA_IN_MEMORY /* cl0002.h */ 0x0000003d + +#define FERMI_TWOD_A 0x0000902d + +#define FERMI_MEMORY_TO_MEMORY_FORMAT_A 0x00009039 + +#define KEPLER_INLINE_TO_MEMORY_A 0x0000a040 +#define KEPLER_INLINE_TO_MEMORY_B 0x0000a140 + +#define NV04_DISP /* cl0046.h */ 0x00000046 + +#define NV03_CHANNEL_DMA /* cl506b.h */ 0x0000006b +#define NV10_CHANNEL_DMA /* cl506b.h */ 0x0000006e +#define NV17_CHANNEL_DMA /* cl506b.h */ 0x0000176e +#define NV40_CHANNEL_DMA /* cl506b.h */ 0x0000406e +#define NV50_CHANNEL_DMA /* cl506e.h */ 0x0000506e +#define G82_CHANNEL_DMA /* cl826e.h */ 0x0000826e + +#define NV50_CHANNEL_GPFIFO /* cl506f.h */ 0x0000506f +#define G82_CHANNEL_GPFIFO /* cl826f.h */ 0x0000826f +#define FERMI_CHANNEL_GPFIFO /* cl906f.h */ 0x0000906f +#define KEPLER_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000a06f +#define MAXWELL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000b06f + +#define NV50_DISP /* cl5070.h */ 0x00005070 +#define G82_DISP /* cl5070.h */ 0x00008270 +#define GT200_DISP /* cl5070.h */ 0x00008370 +#define GT214_DISP /* cl5070.h */ 0x00008570 +#define GT206_DISP /* cl5070.h */ 0x00008870 +#define GF110_DISP /* cl5070.h */ 0x00009070 +#define GK104_DISP /* cl5070.h */ 0x00009170 +#define GK110_DISP /* cl5070.h */ 0x00009270 +#define GM107_DISP /* cl5070.h */ 0x00009470 +#define GM204_DISP /* cl5070.h */ 0x00009570 + +#define NV31_MPEG 0x00003174 +#define G82_MPEG 0x00008274 + +#define NV74_VP2 0x00007476 + +#define NV50_DISP_CURSOR /* cl507a.h */ 0x0000507a +#define G82_DISP_CURSOR /* cl507a.h */ 0x0000827a +#define GT214_DISP_CURSOR /* cl507a.h */ 0x0000857a +#define GF110_DISP_CURSOR /* cl507a.h */ 0x0000907a +#define GK104_DISP_CURSOR /* cl507a.h */ 0x0000917a + +#define NV50_DISP_OVERLAY /* cl507b.h */ 0x0000507b +#define G82_DISP_OVERLAY /* cl507b.h */ 0x0000827b +#define GT214_DISP_OVERLAY /* cl507b.h */ 0x0000857b +#define GF110_DISP_OVERLAY /* cl507b.h */ 0x0000907b +#define GK104_DISP_OVERLAY /* cl507b.h */ 0x0000917b + +#define NV50_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000507c +#define G82_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000827c +#define GT200_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000837c +#define GT214_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000857c +#define GF110_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000907c +#define GK104_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000917c +#define GK110_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000927c + +#define NV50_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000507d +#define G82_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000827d +#define GT200_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000837d +#define GT214_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000857d +#define GT206_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000887d +#define GF110_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000907d +#define GK104_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000917d +#define GK110_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000927d +#define GM107_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000947d +#define GM204_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000957d + +#define NV50_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000507e +#define G82_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000827e +#define GT200_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000837e +#define GT214_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000857e +#define GF110_DISP_OVERLAY_CONTROL_DMA /* cl507e.h */ 0x0000907e +#define GK104_DISP_OVERLAY_CONTROL_DMA /* cl507e.h */ 0x0000917e + +#define FERMI_A /* cl9097.h */ 0x00009097 +#define FERMI_B /* cl9097.h */ 0x00009197 +#define FERMI_C /* cl9097.h */ 0x00009297 + +#define KEPLER_A /* cl9097.h */ 0x0000a097 +#define KEPLER_B /* cl9097.h */ 0x0000a197 +#define KEPLER_C /* cl9097.h */ 0x0000a297 + +#define MAXWELL_A /* cl9097.h */ 0x0000b097 +#define MAXWELL_B /* cl9097.h */ 0x0000b197 + +#define NV74_BSP 0x000074b0 + +#define GT212_MSVLD 0x000085b1 +#define IGT21A_MSVLD 0x000086b1 +#define G98_MSVLD 0x000088b1 +#define GF100_MSVLD 0x000090b1 +#define GK104_MSVLD 0x000095b1 + +#define GT212_MSPDEC 0x000085b2 +#define G98_MSPDEC 0x000088b2 +#define GF100_MSPDEC 0x000090b2 +#define GK104_MSPDEC 0x000095b2 + +#define GT212_MSPPP 0x000085b3 +#define G98_MSPPP 0x000088b3 +#define GF100_MSPPP 0x000090b3 + +#define G98_SEC 0x000088b4 + +#define GT212_DMA 0x000085b5 +#define FERMI_DMA 0x000090b5 +#define KEPLER_DMA_COPY_A 0x0000a0b5 +#define MAXWELL_DMA_COPY_A 0x0000b0b5 + +#define FERMI_DECOMPRESS 0x000090b8 + +#define FERMI_COMPUTE_A 0x000090c0 +#define FERMI_COMPUTE_B 0x000091c0 +#define KEPLER_COMPUTE_A 0x0000a0c0 +#define KEPLER_COMPUTE_B 0x0000a1c0 +#define MAXWELL_COMPUTE_A 0x0000b0c0 +#define MAXWELL_COMPUTE_B 0x0000b1c0 + +#define NV74_CIPHER 0x000074c1 +#endif diff --git a/nouveau/nvif/if0002.h b/nouveau/nvif/if0002.h new file mode 100644 index 0000000..c04c91d --- /dev/null +++ b/nouveau/nvif/if0002.h @@ -0,0 +1,38 @@ +#ifndef __NVIF_IF0002_H__ +#define __NVIF_IF0002_H__ + +#define NVIF_PERFMON_V0_QUERY_DOMAIN 0x00 +#define NVIF_PERFMON_V0_QUERY_SIGNAL 0x01 +#define NVIF_PERFMON_V0_QUERY_SOURCE 0x02 + +struct nvif_perfmon_query_domain_v0 { + __u8 version; + __u8 id; + __u8 counter_nr; + __u8 iter; + __u16 signal_nr; + __u8 pad05[2]; + char name[64]; +}; + +struct nvif_perfmon_query_signal_v0 { + __u8 version; + __u8 domain; + __u16 iter; + __u8 signal; + __u8 source_nr; + __u8 pad05[2]; + char name[64]; +}; + +struct nvif_perfmon_query_source_v0 { + __u8 version; + __u8 domain; + __u8 signal; + __u8 iter; + __u8 pad04[4]; + __u32 source; + __u32 mask; + char name[64]; +}; +#endif diff --git a/nouveau/nvif/if0003.h b/nouveau/nvif/if0003.h new file mode 100644 index 0000000..0cd03ef --- /dev/null +++ b/nouveau/nvif/if0003.h @@ -0,0 +1,33 @@ +#ifndef __NVIF_IF0003_H__ +#define __NVIF_IF0003_H__ + +struct nvif_perfdom_v0 { + __u8 version; + __u8 domain; + __u8 mode; + __u8 pad03[1]; + struct { + __u8 signal[4]; + __u64 source[4][8]; + __u16 logic_op; + } ctr[4]; +}; + +#define NVIF_PERFDOM_V0_INIT 0x00 +#define NVIF_PERFDOM_V0_SAMPLE 0x01 +#define NVIF_PERFDOM_V0_READ 0x02 + +struct nvif_perfdom_init { +}; + +struct nvif_perfdom_sample { +}; + +struct nvif_perfdom_read_v0 { + __u8 version; + __u8 pad01[7]; + __u32 ctr[4]; + __u32 clk; + __u8 pad04[4]; +}; +#endif diff --git a/nouveau/nvif/ioctl.h b/nouveau/nvif/ioctl.h new file mode 100644 index 0000000..c5f5eb8 --- /dev/null +++ b/nouveau/nvif/ioctl.h @@ -0,0 +1,132 @@ +#ifndef __NVIF_IOCTL_H__ +#define __NVIF_IOCTL_H__ + +#define NVIF_VERSION_LATEST 0x0000000000000000ULL + +struct nvif_ioctl_v0 { + __u8 version; +#define NVIF_IOCTL_V0_NOP 0x00 +#define NVIF_IOCTL_V0_SCLASS 0x01 +#define NVIF_IOCTL_V0_NEW 0x02 +#define NVIF_IOCTL_V0_DEL 0x03 +#define NVIF_IOCTL_V0_MTHD 0x04 +#define NVIF_IOCTL_V0_RD 0x05 +#define NVIF_IOCTL_V0_WR 0x06 +#define NVIF_IOCTL_V0_MAP 0x07 +#define NVIF_IOCTL_V0_UNMAP 0x08 +#define NVIF_IOCTL_V0_NTFY_NEW 0x09 +#define NVIF_IOCTL_V0_NTFY_DEL 0x0a +#define NVIF_IOCTL_V0_NTFY_GET 0x0b +#define NVIF_IOCTL_V0_NTFY_PUT 0x0c + __u8 type; + __u8 pad02[4]; +#define NVIF_IOCTL_V0_OWNER_NVIF 0x00 +#define NVIF_IOCTL_V0_OWNER_ANY 0xff + __u8 owner; +#define NVIF_IOCTL_V0_ROUTE_NVIF 0x00 +#define NVIF_IOCTL_V0_ROUTE_HIDDEN 0xff + __u8 route; + __u64 token; + __u64 object; + __u8 data[]; /* ioctl data (below) */ +}; + +struct nvif_ioctl_nop_v0 { + __u64 version; +}; + +struct nvif_ioctl_sclass_v0 { + /* nvif_ioctl ... */ + __u8 version; + __u8 count; + __u8 pad02[6]; + struct nvif_ioctl_sclass_oclass_v0 { + __s32 oclass; + __s16 minver; + __s16 maxver; + } oclass[]; +}; + +struct nvif_ioctl_new_v0 { + /* nvif_ioctl ... */ + __u8 version; + __u8 pad01[6]; + __u8 route; + __u64 token; + __u64 object; + __u32 handle; + __s32 oclass; + __u8 data[]; /* class data (class.h) */ +}; + +struct nvif_ioctl_del { +}; + +struct nvif_ioctl_rd_v0 { + /* nvif_ioctl ... */ + __u8 version; + __u8 size; + __u8 pad02[2]; + __u32 data; + __u64 addr; +}; + +struct nvif_ioctl_wr_v0 { + /* nvif_ioctl ... */ + __u8 version; + __u8 size; + __u8 pad02[2]; + __u32 data; + __u64 addr; +}; + +struct nvif_ioctl_map_v0 { + /* nvif_ioctl ... */ + __u8 version; + __u8 pad01[3]; + __u32 length; + __u64 handle; +}; + +struct nvif_ioctl_unmap { +}; + +struct nvif_ioctl_ntfy_new_v0 { + /* nvif_ioctl ... */ + __u8 version; + __u8 event; + __u8 index; + __u8 pad03[5]; + __u8 data[]; /* event request data (event.h) */ +}; + +struct nvif_ioctl_ntfy_del_v0 { + /* nvif_ioctl ... */ + __u8 version; + __u8 index; + __u8 pad02[6]; +}; + +struct nvif_ioctl_ntfy_get_v0 { + /* nvif_ioctl ... */ + __u8 version; + __u8 index; + __u8 pad02[6]; +}; + +struct nvif_ioctl_ntfy_put_v0 { + /* nvif_ioctl ... */ + __u8 version; + __u8 index; + __u8 pad02[6]; +}; + +struct nvif_ioctl_mthd_v0 { + /* nvif_ioctl ... */ + __u8 version; + __u8 method; + __u8 pad02[6]; + __u8 data[]; /* method data (class.h) */ +}; + +#endif diff --git a/nouveau/nvif/unpack.h b/nouveau/nvif/unpack.h new file mode 100644 index 0000000..751bcf4 --- /dev/null +++ b/nouveau/nvif/unpack.h @@ -0,0 +1,28 @@ +#ifndef __NVIF_UNPACK_H__ +#define __NVIF_UNPACK_H__ + +#define nvif_unvers(r,d,s,m) ({ \ + void **_data = (d); __u32 *_size = (s); int _ret = (r); \ + if (_ret == -ENOSYS && *_size == sizeof(m)) { \ + *_data = NULL; \ + *_size = _ret = 0; \ + } \ + _ret; \ +}) + +#define nvif_unpack(r,d,s,m,vl,vh,x) ({ \ + void **_data = (d); __u32 *_size = (s); \ + int _ret = (r), _vl = (vl), _vh = (vh); \ + if (_ret == -ENOSYS && *_size >= sizeof(m) && \ + (m).version >= _vl && (m).version <= _vh) { \ + *_data = (__u8 *)*_data + sizeof(m); \ + *_size = *_size - sizeof(m); \ + if (_ret = 0, !(x)) { \ + _ret = *_size ? -E2BIG : 0; \ + *_data = NULL; \ + *_size = 0; \ + } \ + } \ + _ret; \ +}) +#endif -- 2.6.3
Ben Skeggs
2015-Nov-26 07:14 UTC
[Nouveau] [libdrm 10/13] nouveau: add new interface to create a nouveau_device
From: Ben Skeggs <bskeggs at redhat.com> Signed-off-by: Ben Skeggs <bskeggs at redhat.com> --- nouveau/nouveau-symbol-check | 1 + nouveau/nouveau.c | 133 ++++++++++++++++++++++++++++--------------- nouveau/nouveau.h | 2 + 3 files changed, 89 insertions(+), 47 deletions(-) diff --git a/nouveau/nouveau-symbol-check b/nouveau/nouveau-symbol-check index 275b6e7..b265cea 100755 --- a/nouveau/nouveau-symbol-check +++ b/nouveau/nouveau-symbol-check @@ -27,6 +27,7 @@ nouveau_bufctx_reset nouveau_client_del nouveau_client_new nouveau_device_del +nouveau_device_new nouveau_device_open nouveau_device_open_existing nouveau_device_wrap diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c index 06fdeed..b54039b 100644 --- a/nouveau/nouveau.c +++ b/nouveau/nouveau.c @@ -45,6 +45,10 @@ #include "nouveau.h" #include "private.h" +#include "nvif/class.h" +#include "nvif/cl0080.h" +#include "nvif/unpack.h" + #ifdef DEBUG drm_private uint32_t nouveau_debug = 0; @@ -231,75 +235,107 @@ nouveau_device_open_existing(struct nouveau_device **pdev, int close, int fd, } int -nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev) +nouveau_device_new(struct nouveau_object *parent, int32_t oclass, + void *data, uint32_t size, struct nouveau_device **pdev) { - struct nouveau_drm *drm; + union { + struct nv_device_v0 v0; + } *args = data; + struct nouveau_drm *drm = nouveau_drm(parent); struct nouveau_device_priv *nvdev; struct nouveau_device *dev; - uint64_t chipset, vram, gart, bousage; - int ret; + uint64_t v; char *tmp; + int ret = -ENOSYS; + + if (oclass != NV_DEVICE || + nvif_unpack(ret, &data, &size, args->v0, 0, 0, false)) + return ret; if (!(nvdev = calloc(1, sizeof(*nvdev)))) return -ENOMEM; - dev = &nvdev->base; + dev = *pdev = &nvdev->base; + dev->fd = -1; - ret = pthread_mutex_init(&nvdev->lock, NULL); - if (ret) { - free(nvdev); - return ret; - } - - ret = nouveau_drm_new(fd, &drm); - if (ret) { - nouveau_device_del(&dev); - return ret; - } - drm->nvif = false; + if (args->v0.device == ~0ULL) { + nvdev->base.object.parent = &drm->client; + nvdev->base.object.handle = ~0ULL; + nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS; + nvdev->base.object.length = ~0; - nvdev->base.object.parent = &drm->client; - nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS; - nvdev->base.object.length = ~0; - nvdev->base.fd = drm->fd; - nvdev->base.drm_version = drm->drm_version; - nvdev->base.lib_version = drm->lib_version; + ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_CHIPSET_ID, &v); + if (ret) + goto done; + nvdev->base.chipset = v; - ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_CHIPSET_ID, &chipset); - if (ret == 0) - ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_FB_SIZE, &vram); - if (ret == 0) - ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_AGP_SIZE, &gart); - if (ret) { - nouveau_device_del(&dev); - return ret; - } + ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_HAS_BO_USAGE, &v); + if (ret == 0) + nvdev->have_bo_usage = (v != 0); + } else + return -ENOSYS; - ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_HAS_BO_USAGE, &bousage); - if (ret == 0) - nvdev->have_bo_usage = (bousage != 0); + ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_FB_SIZE, &v); + if (ret) + goto done; + nvdev->base.vram_size = v; - nvdev->close = close; + ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_AGP_SIZE, &v); + if (ret) + goto done; + nvdev->base.gart_size = v; tmp = getenv("NOUVEAU_LIBDRM_VRAM_LIMIT_PERCENT"); if (tmp) nvdev->vram_limit_percent = atoi(tmp); else nvdev->vram_limit_percent = 80; + + nvdev->base.vram_limit + (nvdev->base.vram_size * nvdev->vram_limit_percent) / 100; + tmp = getenv("NOUVEAU_LIBDRM_GART_LIMIT_PERCENT"); if (tmp) nvdev->gart_limit_percent = atoi(tmp); else nvdev->gart_limit_percent = 80; - DRMINITLISTHEAD(&nvdev->bo_list); - nvdev->base.chipset = chipset; - nvdev->base.vram_size = vram; - nvdev->base.gart_size = gart; - nvdev->base.vram_limit - (nvdev->base.vram_size * nvdev->vram_limit_percent) / 100; + nvdev->base.gart_limit (nvdev->base.gart_size * nvdev->gart_limit_percent) / 100; - *pdev = &nvdev->base; + ret = pthread_mutex_init(&nvdev->lock, NULL); + DRMINITLISTHEAD(&nvdev->bo_list); +done: + if (ret) + nouveau_device_del(pdev); + return ret; +} + +int +nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev) +{ + struct nouveau_drm *drm; + struct nouveau_device_priv *nvdev; + int ret; + + ret = nouveau_drm_new(fd, &drm); + if (ret) + return ret; + drm->nvif = false; + + ret = nouveau_device_new(&drm->client, NV_DEVICE, + &(struct nv_device_v0) { + .device = ~0ULL, + }, sizeof(struct nv_device_v0), pdev); + if (ret) { + nouveau_drm_del(&drm); + return ret; + } + + nvdev = nouveau_device(*pdev); + nvdev->base.fd = drm->fd; + nvdev->base.drm_version = drm->drm_version; + nvdev->base.lib_version = drm->lib_version; + nvdev->close = close; return 0; } @@ -320,12 +356,15 @@ nouveau_device_del(struct nouveau_device **pdev) { struct nouveau_device_priv *nvdev = nouveau_device(*pdev); if (nvdev) { - struct nouveau_drm *drm = nouveau_drm(&nvdev->base.object); free(nvdev->client); - nouveau_drm_del(&drm); pthread_mutex_destroy(&nvdev->lock); - if (nvdev->close) - drmClose(nvdev->base.fd); + if (nvdev->base.fd >= 0) { + struct nouveau_drm *drm + nouveau_drm(&nvdev->base.object); + nouveau_drm_del(&drm); + if (nvdev->close) + drmClose(nvdev->base.fd); + } free(nvdev); *pdev = NULL; } diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h index 86d7338..4658198 100644 --- a/nouveau/nouveau.h +++ b/nouveau/nouveau.h @@ -118,6 +118,8 @@ struct nouveau_device { uint64_t gart_limit; }; +int nouveau_device_new(struct nouveau_object *parent, int32_t oclass, + void *data, uint32_t size, struct nouveau_device **); int nouveau_device_wrap(int fd, int close, struct nouveau_device **); int nouveau_device_open(const char *busid, struct nouveau_device **); void nouveau_device_del(struct nouveau_device **); -- 2.6.3
Ben Skeggs
2015-Nov-26 07:14 UTC
[Nouveau] [libdrm 11/13] nouveau: add support for newer kernel interfaces
From: Ben Skeggs <bskeggs at redhat.com> Signed-off-by: Ben Skeggs <bskeggs at redhat.com> --- nouveau/abi16.c | 5 +- nouveau/nouveau.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 155 insertions(+), 7 deletions(-) diff --git a/nouveau/abi16.c b/nouveau/abi16.c index 5ba2690..328ffb4 100644 --- a/nouveau/abi16.c +++ b/nouveau/abi16.c @@ -32,7 +32,7 @@ #include <errno.h> #include "private.h" - +#include "nvif/class.h" static int abi16_chan_nv04(struct nouveau_object *obj) @@ -197,7 +197,8 @@ abi16_object(struct nouveau_object *obj, int (**func)(struct nouveau_object *)) { struct nouveau_object *parent = obj->parent; - if ((parent->length != 0 && parent->oclass == NOUVEAU_DEVICE_CLASS)) { + if ((parent->length != 0 && parent->oclass == NOUVEAU_DEVICE_CLASS) || + (parent->length == 0 && parent->oclass == NV_DEVICE)) { if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) { struct nouveau_device *dev = (void *)parent; if (dev->chipset < 0xc0) diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c index b54039b..cd8eb5e 100644 --- a/nouveau/nouveau.c +++ b/nouveau/nouveau.c @@ -47,6 +47,7 @@ #include "nvif/class.h" #include "nvif/cl0080.h" +#include "nvif/ioctl.h" #include "nvif/unpack.h" #ifdef DEBUG @@ -63,11 +64,67 @@ debug_init(char *args) } #endif +static int +nouveau_object_ioctl(struct nouveau_object *obj, void *data, uint32_t size) +{ + struct nouveau_drm *drm = nouveau_drm(obj); + union { + struct nvif_ioctl_v0 v0; + } *args = data; + uint32_t argc = size; + int ret = -ENOSYS; + + if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) { + if (!obj->length) { + if (obj != &drm->client) + args->v0.object = (unsigned long)(void *)obj; + else + args->v0.object = 0; + args->v0.owner = NVIF_IOCTL_V0_OWNER_ANY; + args->v0.route = 0x00; + } else { + args->v0.route = 0xff; + args->v0.token = obj->handle; + } + } else + return ret; + + return drmCommandWriteRead(drm->fd, DRM_NOUVEAU_NVIF, args, argc); +} + int nouveau_object_mthd(struct nouveau_object *obj, uint32_t mthd, void *data, uint32_t size) { - return -ENODEV; + struct nouveau_drm *drm = nouveau_drm(obj); + struct { + struct nvif_ioctl_v0 ioctl; + struct nvif_ioctl_mthd_v0 mthd; + } *args; + uint32_t argc = sizeof(*args) + size; + uint8_t stack[128]; + int ret; + + if (!drm->nvif) + return -ENOSYS; + + if (argc > sizeof(stack)) { + if (!(args = malloc(argc))) + return -ENOMEM; + } else { + args = (void *)stack; + } + args->ioctl.version = 0; + args->ioctl.type = NVIF_IOCTL_V0_MTHD; + args->mthd.version = 0; + args->mthd.method = mthd; + + memcpy(args->mthd.data, data, size); + ret = nouveau_object_ioctl(obj, args, argc); + memcpy(data, args->mthd.data, size); + if (args != (void *)stack) + free(args); + return ret; } void @@ -81,7 +138,49 @@ int nouveau_object_sclass_get(struct nouveau_object *obj, struct nouveau_sclass **psclass) { - return abi16_sclass(obj, psclass); + struct nouveau_drm *drm = nouveau_drm(obj); + struct { + struct nvif_ioctl_v0 ioctl; + struct nvif_ioctl_sclass_v0 sclass; + } *args = NULL; + int ret, cnt = 0, i; + uint32_t size; + + if (!drm->nvif) + return abi16_sclass(obj, psclass); + *psclass = NULL; + + while (1) { + size = sizeof(*args) + cnt * sizeof(args->sclass.oclass[0]); + if (!(args = malloc(size))) + return -ENOMEM; + args->ioctl.version = 0; + args->ioctl.type = NVIF_IOCTL_V0_SCLASS; + args->sclass.version = 0; + args->sclass.count = cnt; + + ret = nouveau_object_ioctl(obj, args, size); + if (ret == 0 && args->sclass.count <= cnt) + break; + cnt = args->sclass.count; + free(args); + if (ret != 0) + return ret; + } + + if ((*psclass = calloc(args->sclass.count, sizeof(**psclass)))) { + for (i = 0; i < args->sclass.count; i++) { + (*psclass)[i].oclass = args->sclass.oclass[i].oclass; + (*psclass)[i].minver = args->sclass.oclass[i].minver; + (*psclass)[i].maxver = args->sclass.oclass[i].maxver; + } + ret = args->sclass.count; + } else { + ret = -ENOMEM; + } + + free(args); + return ret; } int @@ -114,12 +213,21 @@ nouveau_object_mclass(struct nouveau_object *obj, static void nouveau_object_fini(struct nouveau_object *obj) { + struct { + struct nvif_ioctl_v0 ioctl; + struct nvif_ioctl_del del; + } args = { + .ioctl.type = NVIF_IOCTL_V0_DEL, + }; + if (obj->data) { abi16_delete(obj); free(obj->data); obj->data = NULL; return; } + + nouveau_object_ioctl(obj, &args, sizeof(args)); } static int @@ -127,6 +235,12 @@ nouveau_object_init(struct nouveau_object *parent, uint32_t handle, int32_t oclass, void *data, uint32_t size, struct nouveau_object *obj) { + struct nouveau_drm *drm = nouveau_drm(parent); + struct { + struct nvif_ioctl_v0 ioctl; + struct nvif_ioctl_new_v0 new; + } *args; + uint32_t argc = sizeof(*args) + size; int (*func)(struct nouveau_object *); int ret = -ENOSYS; @@ -136,7 +250,22 @@ nouveau_object_init(struct nouveau_object *parent, uint32_t handle, obj->length = 0; obj->data = NULL; - abi16_object(obj, &func); + if (!abi16_object(obj, &func) && drm->nvif) { + if (!(args = malloc(argc))) + return -ENOMEM; + args->ioctl.version = 0; + args->ioctl.type = NVIF_IOCTL_V0_NEW; + args->new.version = 0; + args->new.route = NVIF_IOCTL_V0_ROUTE_NVIF; + args->new.token = (unsigned long)(void *)obj; + args->new.object = (unsigned long)(void *)obj; + args->new.handle = handle; + args->new.oclass = oclass; + memcpy(args->new.data, data, size); + ret = nouveau_object_ioctl(parent, args, argc); + memcpy(data, args->new.data, size); + free(args); + } else if (func) { obj->length = size ? size : sizeof(struct nouveau_object *); if (!(obj->data = malloc(obj->length))) @@ -217,8 +346,8 @@ nouveau_drm_new(int fd, struct nouveau_drm **pdrm) drm->drm_version = (ver->version_major << 24) | (ver->version_minor << 8) | ver->version_patchlevel; - drm->lib_version = 0x01000300; - drm->nvif = false; + drm->lib_version = 0x01000301; + drm->nvif = (drm->drm_version >= 0x01000301); drmFreeVersion(ver); return 0; } @@ -238,9 +367,11 @@ int nouveau_device_new(struct nouveau_object *parent, int32_t oclass, void *data, uint32_t size, struct nouveau_device **pdev) { + struct nv_device_info_v0 info = {}; union { struct nv_device_v0 v0; } *args = data; + uint32_t argc = size; struct nouveau_drm *drm = nouveau_drm(parent); struct nouveau_device_priv *nvdev; struct nouveau_device *dev; @@ -257,6 +388,22 @@ nouveau_device_new(struct nouveau_object *parent, int32_t oclass, dev = *pdev = &nvdev->base; dev->fd = -1; + if (drm->nvif) { + ret = nouveau_object_init(parent, 0, oclass, args, argc, + &dev->object); + if (ret) + goto done; + + info.version = 0; + + ret = nouveau_object_mthd(&dev->object, NV_DEVICE_V0_INFO, + &info, sizeof(info)); + if (ret) + goto done; + + nvdev->base.chipset = info.chipset; + nvdev->have_bo_usage = true; + } else if (args->v0.device == ~0ULL) { nvdev->base.object.parent = &drm->client; nvdev->base.object.handle = ~0ULL; -- 2.6.3
Ben Skeggs
2015-Nov-26 07:14 UTC
[Nouveau] [libdrm 12/13] nouveau: clean up nouveau.h, noting deprecated members/functions
From: Ben Skeggs <bskeggs at redhat.com> Signed-off-by: Ben Skeggs <bskeggs at redhat.com> --- nouveau/nouveau.h | 220 +++++++++++++++++++++++++++--------------------------- 1 file changed, 110 insertions(+), 110 deletions(-) diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h index 4658198..b09415e 100644 --- a/nouveau/nouveau.h +++ b/nouveau/nouveau.h @@ -1,27 +1,40 @@ #ifndef __NOUVEAU_H__ #define __NOUVEAU_H__ - -#include <stdint.h> #include <stdbool.h> +#include <xf86drm.h> -#define NOUVEAU_DEVICE_CLASS 0x80000000 -#define NOUVEAU_FIFO_CHANNEL_CLASS 0x80000001 -#define NOUVEAU_NOTIFIER_CLASS 0x80000002 -#define NOUVEAU_PARENT_CLASS 0xffffffff +struct nouveau_sclass { + int32_t oclass; + int minver; + int maxver; +}; -struct nouveau_list { - struct nouveau_list *prev; - struct nouveau_list *next; +struct nouveau_mclass { + int32_t oclass; + int version; + void *data; }; struct nouveau_object { struct nouveau_object *parent; uint64_t handle; uint32_t oclass; - uint32_t length; - void *data; + uint32_t length; /* deprecated */ + void *data; /* deprecated */ }; +int nouveau_object_new(struct nouveau_object *parent, uint64_t handle, + uint32_t oclass, void *data, uint32_t length, + struct nouveau_object **); +void nouveau_object_del(struct nouveau_object **); +int nouveau_object_mthd(struct nouveau_object *, uint32_t mthd, + void *data, uint32_t size); +int nouveau_object_sclass_get(struct nouveau_object *, + struct nouveau_sclass **); +void nouveau_object_sclass_put(struct nouveau_sclass **); +int nouveau_object_mclass(struct nouveau_object *, + const struct nouveau_mclass *); + struct nouveau_drm { struct nouveau_object client; int fd; @@ -41,76 +54,11 @@ nouveau_drm(struct nouveau_object *obj) int nouveau_drm_new(int fd, struct nouveau_drm **); void nouveau_drm_del(struct nouveau_drm **); -struct nouveau_fifo { - struct nouveau_object *object; - uint32_t channel; - uint32_t pushbuf; - uint64_t unused1[3]; -}; - -struct nv04_fifo { - struct nouveau_fifo base; - uint32_t vram; - uint32_t gart; - uint32_t notify; -}; - -struct nvc0_fifo { - struct nouveau_fifo base; - uint32_t notify; -}; - -#define NVE0_FIFO_ENGINE_GR 0x00000001 -#define NVE0_FIFO_ENGINE_VP 0x00000002 -#define NVE0_FIFO_ENGINE_PPP 0x00000004 -#define NVE0_FIFO_ENGINE_BSP 0x00000008 -#define NVE0_FIFO_ENGINE_CE0 0x00000010 -#define NVE0_FIFO_ENGINE_CE1 0x00000020 -#define NVE0_FIFO_ENGINE_ENC 0x00000040 - -struct nve0_fifo { - struct { - struct nouveau_fifo base; - uint32_t notify; - }; - uint32_t engine; -}; - -struct nv04_notify { - struct nouveau_object *object; - uint32_t offset; - uint32_t length; -}; - -struct nouveau_sclass { - int32_t oclass; - int minver; - int maxver; -}; - -struct nouveau_mclass { - int32_t oclass; - int version; - void *data; -}; - -int nouveau_object_new(struct nouveau_object *parent, uint64_t handle, - uint32_t oclass, void *data, uint32_t length, - struct nouveau_object **); -void nouveau_object_del(struct nouveau_object **); -int nouveau_object_mthd(struct nouveau_object *, uint32_t mthd, - void *data, uint32_t size); -int nouveau_object_sclass_get(struct nouveau_object *, - struct nouveau_sclass **); -void nouveau_object_sclass_put(struct nouveau_sclass **); -int nouveau_object_mclass(struct nouveau_object *, - const struct nouveau_mclass *); - struct nouveau_device { struct nouveau_object object; - int fd; - uint32_t lib_version; - uint32_t drm_version; + int fd; /* deprecated */ + uint32_t lib_version; /* deprecated */ + uint32_t drm_version; /* deprecated */ uint32_t chipset; uint64_t vram_size; uint64_t gart_size; @@ -118,20 +66,23 @@ struct nouveau_device { uint64_t gart_limit; }; -int nouveau_device_new(struct nouveau_object *parent, int32_t oclass, - void *data, uint32_t size, struct nouveau_device **); -int nouveau_device_wrap(int fd, int close, struct nouveau_device **); -int nouveau_device_open(const char *busid, struct nouveau_device **); +int nouveau_device_new(struct nouveau_object *parent, int32_t oclass, + void *data, uint32_t size, struct nouveau_device **); void nouveau_device_del(struct nouveau_device **); -int nouveau_getparam(struct nouveau_device *, uint64_t param, uint64_t *value); -int nouveau_setparam(struct nouveau_device *, uint64_t param, uint64_t value); + +int nouveau_getparam(struct nouveau_device *, uint64_t param, uint64_t *value); +int nouveau_setparam(struct nouveau_device *, uint64_t param, uint64_t value); + +/* deprecated */ +int nouveau_device_wrap(int fd, int close, struct nouveau_device **); +int nouveau_device_open(const char *busid, struct nouveau_device **); struct nouveau_client { struct nouveau_device *device; int id; }; -int nouveau_client_new(struct nouveau_device *, struct nouveau_client **); +int nouveau_client_new(struct nouveau_device *, struct nouveau_client **); void nouveau_client_del(struct nouveau_client **); union nouveau_bo_config { @@ -178,22 +129,27 @@ struct nouveau_bo { union nouveau_bo_config config; }; -int nouveau_bo_new(struct nouveau_device *, uint32_t flags, uint32_t align, - uint64_t size, union nouveau_bo_config *, +int nouveau_bo_new(struct nouveau_device *, uint32_t flags, uint32_t align, + uint64_t size, union nouveau_bo_config *, + struct nouveau_bo **); +int nouveau_bo_wrap(struct nouveau_device *, uint32_t handle, struct nouveau_bo **); -int nouveau_bo_wrap(struct nouveau_device *, uint32_t handle, - struct nouveau_bo **); -int nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name, - struct nouveau_bo **); -int nouveau_bo_name_get(struct nouveau_bo *, uint32_t *name); +int nouveau_bo_name_ref(struct nouveau_device *v, uint32_t name, + struct nouveau_bo **); +int nouveau_bo_name_get(struct nouveau_bo *, uint32_t *name); void nouveau_bo_ref(struct nouveau_bo *, struct nouveau_bo **); -int nouveau_bo_map(struct nouveau_bo *, uint32_t access, +int nouveau_bo_map(struct nouveau_bo *, uint32_t access, + struct nouveau_client *); +int nouveau_bo_wait(struct nouveau_bo *, uint32_t access, struct nouveau_client *); -int nouveau_bo_wait(struct nouveau_bo *, uint32_t access, - struct nouveau_client *); -int nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd, - struct nouveau_bo **); -int nouveau_bo_set_prime(struct nouveau_bo *bo, int *prime_fd); +int nouveau_bo_prime_handle_ref(struct nouveau_device *, int prime_fd, + struct nouveau_bo **); +int nouveau_bo_set_prime(struct nouveau_bo *, int *prime_fd); + +struct nouveau_list { + struct nouveau_list *prev; + struct nouveau_list *next; +}; struct nouveau_bufref { struct nouveau_list thead; @@ -215,8 +171,8 @@ struct nouveau_bufctx { int relocs; }; -int nouveau_bufctx_new(struct nouveau_client *, int bins, - struct nouveau_bufctx **); +int nouveau_bufctx_new(struct nouveau_client *, int bins, + struct nouveau_bufctx **); void nouveau_bufctx_del(struct nouveau_bufctx **); struct nouveau_bufref * nouveau_bufctx_refn(struct nouveau_bufctx *, int bin, @@ -245,16 +201,16 @@ struct nouveau_pushbuf_refn { uint32_t flags; }; -int nouveau_pushbuf_new(struct nouveau_client *, struct nouveau_object *channel, - int nr, uint32_t size, bool immediate, - struct nouveau_pushbuf **); +int nouveau_pushbuf_new(struct nouveau_client *, struct nouveau_object *chan, + int nr, uint32_t size, bool immediate, + struct nouveau_pushbuf **); void nouveau_pushbuf_del(struct nouveau_pushbuf **); -int nouveau_pushbuf_space(struct nouveau_pushbuf *, uint32_t dwords, - uint32_t relocs, uint32_t pushes); +int nouveau_pushbuf_space(struct nouveau_pushbuf *, uint32_t dwords, + uint32_t relocs, uint32_t pushes); void nouveau_pushbuf_data(struct nouveau_pushbuf *, struct nouveau_bo *, uint64_t offset, uint64_t length); -int nouveau_pushbuf_refn(struct nouveau_pushbuf *, - struct nouveau_pushbuf_refn *, int nr); +int nouveau_pushbuf_refn(struct nouveau_pushbuf *, + struct nouveau_pushbuf_refn *, int nr); /* Emits a reloc into the push buffer at the current position, you *must* * have previously added the referenced buffer to a buffer context, and * validated it against the current push buffer. @@ -262,10 +218,54 @@ int nouveau_pushbuf_refn(struct nouveau_pushbuf *, void nouveau_pushbuf_reloc(struct nouveau_pushbuf *, struct nouveau_bo *, uint32_t data, uint32_t flags, uint32_t vor, uint32_t tor); -int nouveau_pushbuf_validate(struct nouveau_pushbuf *); +int nouveau_pushbuf_validate(struct nouveau_pushbuf *); uint32_t nouveau_pushbuf_refd(struct nouveau_pushbuf *, struct nouveau_bo *); -int nouveau_pushbuf_kick(struct nouveau_pushbuf *, struct nouveau_object *channel); +int nouveau_pushbuf_kick(struct nouveau_pushbuf *, struct nouveau_object *chan); struct nouveau_bufctx * nouveau_pushbuf_bufctx(struct nouveau_pushbuf *, struct nouveau_bufctx *); +#define NOUVEAU_DEVICE_CLASS 0x80000000 +#define NOUVEAU_FIFO_CHANNEL_CLASS 0x80000001 +#define NOUVEAU_NOTIFIER_CLASS 0x80000002 + +struct nouveau_fifo { + struct nouveau_object *object; + uint32_t channel; + uint32_t pushbuf; + uint64_t unused1[3]; +}; + +struct nv04_fifo { + struct nouveau_fifo base; + uint32_t vram; + uint32_t gart; + uint32_t notify; +}; + +struct nvc0_fifo { + struct nouveau_fifo base; + uint32_t notify; +}; + +#define NVE0_FIFO_ENGINE_GR 0x00000001 +#define NVE0_FIFO_ENGINE_VP 0x00000002 +#define NVE0_FIFO_ENGINE_PPP 0x00000004 +#define NVE0_FIFO_ENGINE_BSP 0x00000008 +#define NVE0_FIFO_ENGINE_CE0 0x00000010 +#define NVE0_FIFO_ENGINE_CE1 0x00000020 +#define NVE0_FIFO_ENGINE_ENC 0x00000040 + +struct nve0_fifo { + struct { + struct nouveau_fifo base; + uint32_t notify; + }; + uint32_t engine; +}; + +struct nv04_notify { + struct nouveau_object *object; + uint32_t offset; + uint32_t length; +}; #endif -- 2.6.3
From: Ben Skeggs <bskeggs at redhat.com> Signed-off-by: Ben Skeggs <bskeggs at redhat.com> --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index b929d36..7678572 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@ AC_PREREQ([2.63]) AC_INIT([libdrm], - [2.4.65], + [2.4.66], [https://bugs.freedesktop.org/enter_bug.cgi?product=DRI], [libdrm]) -- 2.6.3
Emil Velikov
2015-Nov-26 20:21 UTC
[Nouveau] [libdrm 01/13] nouveau: move more abi16-specific logic into abi16.c
Hi Ben, On 26 November 2015 at 07:13, Ben Skeggs <skeggsb at gmail.com> wrote:> From: Ben Skeggs <bskeggs at redhat.com> > > Signed-off-by: Ben Skeggs <bskeggs at redhat.com> > --- > nouveau/abi16.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++----- > nouveau/nouveau.c | 56 +++++++------------------------------------------ > nouveau/private.h | 7 ++----- > 3 files changed, 67 insertions(+), 58 deletions(-) > > diff --git a/nouveau/abi16.c b/nouveau/abi16.c > index 59bc436..8f24ba2 100644 > --- a/nouveau/abi16.c > +++ b/nouveau/abi16.c> +drm_private bool > +abi16_object(struct nouveau_object *obj, int (**func)(struct nouveau_object *)) > +{ > + struct nouveau_object *parent = obj->parent; > + > + if ((parent->length != 0 && parent->oclass == NOUVEAU_DEVICE_CLASS)) { > + if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) { > + struct nouveau_device *dev = (void *)parent; > + if (dev->chipset < 0xc0) > + *func = abi16_chan_nv04; > + else > + if (dev->chipset < 0xe0) > + *func = abi16_chan_nvc0; > + else > + *func = abi16_chan_nve0; > + return true; > + } > + } else > + if ((parent->length != 0 && > + parent->oclass == NOUVEAU_FIFO_CHANNEL_CLASS)) { > + if (obj->oclass == NOUVEAU_NOTIFIER_CLASS) { > + *func = abi16_ntfy; > + return true; > + } > + > + *func = abi16_engobj; > + return false;Surely this is meant to be true, right ?> + } > + > + *func = NULL; > + return false; > +} > + > +drm_private void > abi16_bo_info(struct nouveau_bo *bo, struct drm_nouveau_gem_info *info) > { > struct nouveau_bo_priv *nvbo = nouveau_bo(bo); > diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c > index 97fd77b..8a0be2f 100644 > --- a/nouveau/nouveau.c > +++ b/nouveau/nouveau.c > @@ -135,6 +135,7 @@ nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev) > nvdev->gart_limit_percent = 80; > DRMINITLISTHEAD(&nvdev->bo_list); > nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS; > + nvdev->base.object.length = ~0;There are no hints about this and it's use in abi16_object - worth splitting out or mentioning it in the commit message ? -Emil
Emil Velikov
2015-Nov-26 20:39 UTC
[Nouveau] [libdrm 05/13] nouveau: add interfaces to query information about supported classes
On 26 November 2015 at 07:14, Ben Skeggs <skeggsb at gmail.com> wrote:> From: Ben Skeggs <bskeggs at redhat.com> > > This will expose functionality supported by newer kernel interfaces. > > Current userspace uses the chipset to determine which classes are likely > exposed, which generally works pretty well, but isn't as flexible as it > could be. > > Unfortunately, the G98:GF100 video code in Mesa is still relying on the > kernel exposing incorrect vdec classes on some chipsets. The ABI16 > kernel interfaces have a workaround for this in place, but that will no > longer be available once libdrm supports NVIF. > > To prevent a regression when NVIF support is added, if there's no kernel > support for NVIF, libdrm will magic up a class list containing correct > vdec classes anyway instead of failing with -ENODEV. > > Signed-off-by: Ben Skeggs <bskeggs at redhat.com> > --- > nouveau/abi16.c | 28 ++++++++++++++++++++++++++++ > nouveau/nouveau-symbol-check | 3 +++ > nouveau/nouveau.c | 41 +++++++++++++++++++++++++++++++++++++++++ > nouveau/nouveau.h | 17 +++++++++++++++++ > nouveau/private.h | 1 + > 5 files changed, 90 insertions(+) > > diff --git a/nouveau/abi16.c b/nouveau/abi16.c > index 8f24ba2..34e9fb1 100644 > --- a/nouveau/abi16.c > +++ b/nouveau/abi16.c> +drm_private int > +abi16_sclass(struct nouveau_object *obj, struct nouveau_sclass **psclass) > +{ > + struct nouveau_sclass *sclass; > + struct nouveau_device *dev; > + > + if (!(sclass = *psclass = calloc(8, sizeof(*sclass))))Most places set the user provided pointer if the function succeeds. I.e. move *psclass = sclass; after the error check ?> + return -ENOMEM; > + > + switch (obj->oclass) { > + case NOUVEAU_FIFO_CHANNEL_CLASS: > + dev = (struct nouveau_device *)obj->parent; > + if (dev->chipset >= 0x98 && > + dev->chipset != 0xa0 && > + dev->chipset < 0xc0) { > + *sclass++ = (struct nouveau_sclass){ 0x85b1, -1, -1 }; > + *sclass++ = (struct nouveau_sclass){ 0x85b2, -1, -1 }; > + *sclass++ = (struct nouveau_sclass){ 0x85b3, -1, -1 };Worth adding a comment (just grab the commit message) about this magic ?> --- a/nouveau/nouveau.h > +++ b/nouveau/nouveau.h > @@ -63,12 +63,29 @@ struct nv04_notify { > uint32_t length; > }; > > +struct nouveau_sclass { > + int32_t oclass; > + int minver; > + int maxver; > +}; > + > +struct nouveau_mclass { > + int32_t oclass; > + int version; > + void *data; > +}; > +Can you please add a comment about the meaning of sclass and mclass. Thanks Emil
Emil Velikov
2015-Nov-26 20:46 UTC
[Nouveau] [libdrm 06/13] nouveau: introduce object to represent the kernel client
On 26 November 2015 at 07:14, Ben Skeggs <skeggsb at gmail.com> wrote:> --- a/nouveau/nouveau.c > +++ b/nouveau/nouveau.c> +int > +nouveau_drm_new(int fd, struct nouveau_drm **pdrm) > +{ > + struct nouveau_drm *drm; > + drmVersionPtr ver; > + > +#ifdef DEBUG > + debug_init(getenv("NOUVEAU_LIBDRM_DEBUG")); > +#endif > + > + if (!(drm = *pdrm = calloc(1, sizeof(*drm))))Similar to previous patch - set *pdrm at a later stage.> + return -ENOMEM; > + drm->fd = fd; > + > + if (!(ver = drmGetVersion(fd))) { > + nouveau_drm_del(pdrm); > + return -EINVAL; > + } > + > + drm->drm_version = (ver->version_major << 24) | > + (ver->version_minor << 8) | > + ver->version_patchlevel; > + drm->lib_version = 0x01000300;Do we need this - neither mesa nor xf86-video-nouveau use it. -Emil
Emil Velikov
2015-Nov-26 21:01 UTC
[Nouveau] [libdrm 07/13] nouveau: stack legacy nouveau_device on top of nouveau_drm
On 26 November 2015 at 07:14, Ben Skeggs <skeggsb at gmail.com> wrote:> --- a/nouveau/nouveau.c > +++ b/nouveau/nouveau.c> + nvdev->base.lib_version = drm->lib_version;On top of last patch "do we need lib_version" there has been no ddx and mesa users that I can see. Do we want to carry keep this or we can just drop it ? -Emil
Emil Velikov
2015-Nov-26 21:06 UTC
[Nouveau] [libdrm 08/13] nouveau: make use of nouveau_drm::fd instead of nouveau_device::fd
On 26 November 2015 at 07:14, Ben Skeggs <skeggsb at gmail.com> wrote:> From: Ben Skeggs <bskeggs at redhat.com> > > The latter is deprecated, and will not be valid for newer clients. >Mention (or split) the removal of nouveau_object_find ? Afaics it has never been used in mesa + ddx. -Emil
Emil Velikov
2015-Nov-26 21:14 UTC
[Nouveau] [libdrm 09/13] nouveau: import and install a selection of nvif headers from the kernel
On 26 November 2015 at 07:14, Ben Skeggs <skeggsb at gmail.com> wrote:> From: Ben Skeggs <bskeggs at redhat.com>> --- a/nouveau/Makefile.am > +++ b/nouveau/Makefile.am > @@ -14,9 +14,18 @@ libdrm_nouveau_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@ > > libdrm_nouveau_la_SOURCES = $(LIBDRM_NOUVEAU_FILES) > > -libdrm_nouveauincludedir = ${includedir}/libdrm > +libdrm_nouveauincludedir = ${includedir}/libdrm/nouveauCan we mention the change in the commit message, please ? This will be a nice test for places missing LIBDRM_NOUVEAU_CFLAGS :-) I take it that neither mesa nor ddx explode with this change ? -Emil
Seemingly Similar Threads
- [libdrm v3 01/14] nouveau: import and install a selection of nvif headers from the kernel
- [libdrm v2 01/14] nouveau: import and install a selection of nvif headers from the kernel
- [libdrm 05/13] nouveau: add interfaces to query information about supported classes
- [libdrm 08/13] nouveau: make use of nouveau_drm::fd instead of nouveau_device::fd
- [mesa v2 1/9] nouveau: bump required libdrm version to 2.4.66