mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 09:31:50 +00:00
drm/nouveau: use ioctl interface for abi16 grobj alloc
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
fdb751ef2b
commit
a4e610b5e6
@ -21,7 +21,9 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nvif/os.h>
|
#include <nvif/client.h>
|
||||||
|
#include <nvif/driver.h>
|
||||||
|
#include <nvif/ioctl.h>
|
||||||
#include <nvif/class.h>
|
#include <nvif/class.h>
|
||||||
|
|
||||||
#include "nouveau_drm.h"
|
#include "nouveau_drm.h"
|
||||||
@ -46,7 +48,7 @@ nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev)
|
|||||||
* opened)
|
* opened)
|
||||||
*/
|
*/
|
||||||
if (nvif_device_init(&cli->base.base, NULL,
|
if (nvif_device_init(&cli->base.base, NULL,
|
||||||
NVDRM_DEVICE, NV_DEVICE_CLASS,
|
NOUVEAU_ABI16_DEVICE, NV_DEVICE,
|
||||||
&(struct nv_device_class) {
|
&(struct nv_device_class) {
|
||||||
.device = ~0ULL,
|
.device = ~0ULL,
|
||||||
}, sizeof(struct nv_device_class),
|
}, sizeof(struct nv_device_class),
|
||||||
@ -280,7 +282,8 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
|
|||||||
abi16->handles |= (1ULL << init->channel);
|
abi16->handles |= (1ULL << init->channel);
|
||||||
|
|
||||||
/* create channel object and initialise dma and fence management */
|
/* create channel object and initialise dma and fence management */
|
||||||
ret = nouveau_channel_new(drm, device, NVDRM_CHAN | init->channel,
|
ret = nouveau_channel_new(drm, device,
|
||||||
|
NOUVEAU_ABI16_CHAN(init->channel),
|
||||||
init->fb_ctxdma_handle,
|
init->fb_ctxdma_handle,
|
||||||
init->tt_ctxdma_handle, &chan->chan);
|
init->tt_ctxdma_handle, &chan->chan);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -330,6 +333,18 @@ done:
|
|||||||
return nouveau_abi16_put(abi16, ret);
|
return nouveau_abi16_put(abi16, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct nouveau_abi16_chan *
|
||||||
|
nouveau_abi16_chan(struct nouveau_abi16 *abi16, int channel)
|
||||||
|
{
|
||||||
|
struct nouveau_abi16_chan *chan;
|
||||||
|
|
||||||
|
list_for_each_entry(chan, &abi16->channels, head) {
|
||||||
|
if (chan->chan->object->handle == NOUVEAU_ABI16_CHAN(channel))
|
||||||
|
return chan;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS)
|
nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS)
|
||||||
@ -337,28 +352,38 @@ nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS)
|
|||||||
struct drm_nouveau_channel_free *req = data;
|
struct drm_nouveau_channel_free *req = data;
|
||||||
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
|
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
|
||||||
struct nouveau_abi16_chan *chan;
|
struct nouveau_abi16_chan *chan;
|
||||||
int ret = -ENOENT;
|
|
||||||
|
|
||||||
if (unlikely(!abi16))
|
if (unlikely(!abi16))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
list_for_each_entry(chan, &abi16->channels, head) {
|
chan = nouveau_abi16_chan(abi16, req->channel);
|
||||||
if (chan->chan->object->handle == (NVDRM_CHAN | req->channel)) {
|
if (!chan)
|
||||||
|
return nouveau_abi16_put(abi16, -ENOENT);
|
||||||
nouveau_abi16_chan_fini(abi16, chan);
|
nouveau_abi16_chan_fini(abi16, chan);
|
||||||
return nouveau_abi16_put(abi16, 0);
|
return nouveau_abi16_put(abi16, 0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return nouveau_abi16_put(abi16, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
|
nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
|
||||||
{
|
{
|
||||||
struct drm_nouveau_grobj_alloc *init = data;
|
struct drm_nouveau_grobj_alloc *init = data;
|
||||||
|
struct {
|
||||||
|
struct nvif_ioctl_v0 ioctl;
|
||||||
|
struct nvif_ioctl_new_v0 new;
|
||||||
|
} args = {
|
||||||
|
.ioctl.owner = NVIF_IOCTL_V0_OWNER_ANY,
|
||||||
|
.ioctl.type = NVIF_IOCTL_V0_NEW,
|
||||||
|
.ioctl.path_nr = 3,
|
||||||
|
.ioctl.path[2] = NOUVEAU_ABI16_CLIENT,
|
||||||
|
.ioctl.path[1] = NOUVEAU_ABI16_DEVICE,
|
||||||
|
.ioctl.path[0] = NOUVEAU_ABI16_CHAN(init->channel),
|
||||||
|
.new.route = NVDRM_OBJECT_ABI16,
|
||||||
|
.new.handle = init->handle,
|
||||||
|
.new.oclass = init->class,
|
||||||
|
};
|
||||||
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
|
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
|
||||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||||
struct nouveau_object *object;
|
struct nvif_client *client;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (unlikely(!abi16))
|
if (unlikely(!abi16))
|
||||||
@ -366,6 +391,7 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
|
|||||||
|
|
||||||
if (init->handle == ~0)
|
if (init->handle == ~0)
|
||||||
return nouveau_abi16_put(abi16, -EINVAL);
|
return nouveau_abi16_put(abi16, -EINVAL);
|
||||||
|
client = nvif_client(nvif_object(&abi16->device));
|
||||||
|
|
||||||
/* compatibility with userspace that assumes 506e for all chipsets */
|
/* compatibility with userspace that assumes 506e for all chipsets */
|
||||||
if (init->class == 0x506e) {
|
if (init->class == 0x506e) {
|
||||||
@ -374,10 +400,7 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
|
|||||||
return nouveau_abi16_put(abi16, 0);
|
return nouveau_abi16_put(abi16, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*XXX*/
|
ret = nvif_client_ioctl(client, &args, sizeof(args));
|
||||||
ret = nouveau_object_new(nv_object(nvkm_client(&abi16->device.base)),
|
|
||||||
NVDRM_CHAN | init->channel, init->handle,
|
|
||||||
init->class, NULL, 0, &object);
|
|
||||||
return nouveau_abi16_put(abi16, ret);
|
return nouveau_abi16_put(abi16, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,7 +410,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
|
|||||||
struct drm_nouveau_notifierobj_alloc *info = data;
|
struct drm_nouveau_notifierobj_alloc *info = data;
|
||||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||||
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
|
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
|
||||||
struct nouveau_abi16_chan *chan = NULL, *temp;
|
struct nouveau_abi16_chan *chan;
|
||||||
struct nouveau_abi16_ntfy *ntfy;
|
struct nouveau_abi16_ntfy *ntfy;
|
||||||
struct nvif_device *device = &abi16->device;
|
struct nvif_device *device = &abi16->device;
|
||||||
struct nouveau_object *object;
|
struct nouveau_object *object;
|
||||||
@ -401,13 +424,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
|
|||||||
if (unlikely(device->info.family >= NV_DEVICE_INFO_V0_FERMI))
|
if (unlikely(device->info.family >= NV_DEVICE_INFO_V0_FERMI))
|
||||||
return nouveau_abi16_put(abi16, -EINVAL);
|
return nouveau_abi16_put(abi16, -EINVAL);
|
||||||
|
|
||||||
list_for_each_entry(temp, &abi16->channels, head) {
|
chan = nouveau_abi16_chan(abi16, info->channel);
|
||||||
if (temp->chan->object->handle == (NVDRM_CHAN | info->channel)) {
|
|
||||||
chan = temp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!chan)
|
if (!chan)
|
||||||
return nouveau_abi16_put(abi16, -ENOENT);
|
return nouveau_abi16_put(abi16, -ENOENT);
|
||||||
|
|
||||||
@ -461,20 +478,14 @@ nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS)
|
|||||||
{
|
{
|
||||||
struct drm_nouveau_gpuobj_free *fini = data;
|
struct drm_nouveau_gpuobj_free *fini = data;
|
||||||
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
|
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
|
||||||
struct nouveau_abi16_chan *chan = NULL, *temp;
|
struct nouveau_abi16_chan *chan;
|
||||||
struct nouveau_abi16_ntfy *ntfy;
|
struct nouveau_abi16_ntfy *ntfy;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (unlikely(!abi16))
|
if (unlikely(!abi16))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
list_for_each_entry(temp, &abi16->channels, head) {
|
chan = nouveau_abi16_chan(abi16, fini->channel);
|
||||||
if (temp->chan->object->handle == (NVDRM_CHAN | fini->channel)) {
|
|
||||||
chan = temp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!chan)
|
if (!chan)
|
||||||
return nouveau_abi16_put(abi16, -ENOENT);
|
return nouveau_abi16_put(abi16, -ENOENT);
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#include <core/class.h>
|
#include <core/class.h>
|
||||||
|
|
||||||
#include <drmP.h>
|
#include <drmP.h>
|
||||||
#include <drm/nouveau_drm.h>
|
|
||||||
|
|
||||||
#include <drm/ttm/ttm_bo_api.h>
|
#include <drm/ttm/ttm_bo_api.h>
|
||||||
#include <drm/ttm/ttm_bo_driver.h>
|
#include <drm/ttm/ttm_bo_driver.h>
|
||||||
@ -40,6 +39,8 @@
|
|||||||
#include <drm/ttm/ttm_module.h>
|
#include <drm/ttm/ttm_module.h>
|
||||||
#include <drm/ttm/ttm_page_alloc.h>
|
#include <drm/ttm/ttm_page_alloc.h>
|
||||||
|
|
||||||
|
#include "uapi/drm/nouveau_drm.h"
|
||||||
|
|
||||||
struct nouveau_channel;
|
struct nouveau_channel;
|
||||||
struct platform_device;
|
struct platform_device;
|
||||||
|
|
||||||
|
@ -25,6 +25,14 @@
|
|||||||
#ifndef __NOUVEAU_DRM_H__
|
#ifndef __NOUVEAU_DRM_H__
|
||||||
#define __NOUVEAU_DRM_H__
|
#define __NOUVEAU_DRM_H__
|
||||||
|
|
||||||
|
/* reserved object handles when using deprecated object APIs - these
|
||||||
|
* are here so that libdrm can allow interoperability with the new
|
||||||
|
* object APIs
|
||||||
|
*/
|
||||||
|
#define NOUVEAU_ABI16_CLIENT 0xffffffff
|
||||||
|
#define NOUVEAU_ABI16_DEVICE 0xdddddddd
|
||||||
|
#define NOUVEAU_ABI16_CHAN(n) (0xcccc0000 | (n))
|
||||||
|
|
||||||
#define NOUVEAU_GEM_DOMAIN_CPU (1 << 0)
|
#define NOUVEAU_GEM_DOMAIN_CPU (1 << 0)
|
||||||
#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1)
|
#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1)
|
||||||
#define NOUVEAU_GEM_DOMAIN_GART (1 << 2)
|
#define NOUVEAU_GEM_DOMAIN_GART (1 << 2)
|
||||||
|
Loading…
Reference in New Issue
Block a user