drm/nouveau/fifo: allow direct access to channel control registers where possible
The indirect method has been left in-place here as a fallback path, as it may not be possible to map the non-PAGE_SIZE aligned control areas across some chipset+interface combinations. This isn't a problem for the primary use-case where the core and drm are linked together in kernel-land, but across a VM or (in the case where it applies now) between the core in the kernel and a userspace test tool. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Родитель
bbf8906b2c
Коммит
6c6ae061b6
|
@ -103,15 +103,10 @@ nouveau_fifo_channel_create_(struct nouveau_object *parent,
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* map fifo control registers */
|
chan->addr = nv_device_resource_start(device, bar) +
|
||||||
chan->user = ioremap(nv_device_resource_start(device, bar) + addr +
|
addr + size * chan->chid;
|
||||||
(chan->chid * size), size);
|
|
||||||
if (!chan->user)
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
nvkm_event_send(&priv->cevent, 1, 0, NULL, 0);
|
|
||||||
|
|
||||||
chan->size = size;
|
chan->size = size;
|
||||||
|
nvkm_event_send(&priv->cevent, 1, 0, NULL, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +116,8 @@ nouveau_fifo_channel_destroy(struct nouveau_fifo_chan *chan)
|
||||||
struct nouveau_fifo *priv = (void *)nv_object(chan)->engine;
|
struct nouveau_fifo *priv = (void *)nv_object(chan)->engine;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
iounmap(chan->user);
|
if (chan->user)
|
||||||
|
iounmap(chan->user);
|
||||||
|
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
priv->channel[chan->chid] = NULL;
|
priv->channel[chan->chid] = NULL;
|
||||||
|
@ -139,10 +135,24 @@ _nouveau_fifo_channel_dtor(struct nouveau_object *object)
|
||||||
nouveau_fifo_channel_destroy(chan);
|
nouveau_fifo_channel_destroy(chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_nouveau_fifo_channel_map(struct nouveau_object *object, u64 *addr, u32 *size)
|
||||||
|
{
|
||||||
|
struct nouveau_fifo_chan *chan = (void *)object;
|
||||||
|
*addr = chan->addr;
|
||||||
|
*size = chan->size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
u32
|
u32
|
||||||
_nouveau_fifo_channel_rd32(struct nouveau_object *object, u64 addr)
|
_nouveau_fifo_channel_rd32(struct nouveau_object *object, u64 addr)
|
||||||
{
|
{
|
||||||
struct nouveau_fifo_chan *chan = (void *)object;
|
struct nouveau_fifo_chan *chan = (void *)object;
|
||||||
|
if (unlikely(!chan->user)) {
|
||||||
|
chan->user = ioremap(chan->addr, chan->size);
|
||||||
|
if (WARN_ON_ONCE(chan->user == NULL))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return ioread32_native(chan->user + addr);
|
return ioread32_native(chan->user + addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,6 +160,11 @@ void
|
||||||
_nouveau_fifo_channel_wr32(struct nouveau_object *object, u64 addr, u32 data)
|
_nouveau_fifo_channel_wr32(struct nouveau_object *object, u64 addr, u32 data)
|
||||||
{
|
{
|
||||||
struct nouveau_fifo_chan *chan = (void *)object;
|
struct nouveau_fifo_chan *chan = (void *)object;
|
||||||
|
if (unlikely(!chan->user)) {
|
||||||
|
chan->user = ioremap(chan->addr, chan->size);
|
||||||
|
if (WARN_ON_ONCE(chan->user == NULL))
|
||||||
|
return;
|
||||||
|
}
|
||||||
iowrite32_native(data, chan->user + addr);
|
iowrite32_native(data, chan->user + addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -252,6 +252,7 @@ nv04_fifo_ofuncs = {
|
||||||
.dtor = nv04_fifo_chan_dtor,
|
.dtor = nv04_fifo_chan_dtor,
|
||||||
.init = nv04_fifo_chan_init,
|
.init = nv04_fifo_chan_init,
|
||||||
.fini = nv04_fifo_chan_fini,
|
.fini = nv04_fifo_chan_fini,
|
||||||
|
.map = _nouveau_fifo_channel_map,
|
||||||
.rd32 = _nouveau_fifo_channel_rd32,
|
.rd32 = _nouveau_fifo_channel_rd32,
|
||||||
.wr32 = _nouveau_fifo_channel_wr32,
|
.wr32 = _nouveau_fifo_channel_wr32,
|
||||||
};
|
};
|
||||||
|
|
|
@ -110,6 +110,7 @@ nv10_fifo_ofuncs = {
|
||||||
.dtor = nv04_fifo_chan_dtor,
|
.dtor = nv04_fifo_chan_dtor,
|
||||||
.init = nv04_fifo_chan_init,
|
.init = nv04_fifo_chan_init,
|
||||||
.fini = nv04_fifo_chan_fini,
|
.fini = nv04_fifo_chan_fini,
|
||||||
|
.map = _nouveau_fifo_channel_map,
|
||||||
.rd32 = _nouveau_fifo_channel_rd32,
|
.rd32 = _nouveau_fifo_channel_rd32,
|
||||||
.wr32 = _nouveau_fifo_channel_wr32,
|
.wr32 = _nouveau_fifo_channel_wr32,
|
||||||
};
|
};
|
||||||
|
|
|
@ -117,6 +117,7 @@ nv17_fifo_ofuncs = {
|
||||||
.dtor = nv04_fifo_chan_dtor,
|
.dtor = nv04_fifo_chan_dtor,
|
||||||
.init = nv04_fifo_chan_init,
|
.init = nv04_fifo_chan_init,
|
||||||
.fini = nv04_fifo_chan_fini,
|
.fini = nv04_fifo_chan_fini,
|
||||||
|
.map = _nouveau_fifo_channel_map,
|
||||||
.rd32 = _nouveau_fifo_channel_rd32,
|
.rd32 = _nouveau_fifo_channel_rd32,
|
||||||
.wr32 = _nouveau_fifo_channel_wr32,
|
.wr32 = _nouveau_fifo_channel_wr32,
|
||||||
};
|
};
|
||||||
|
|
|
@ -236,6 +236,7 @@ nv40_fifo_ofuncs = {
|
||||||
.dtor = nv04_fifo_chan_dtor,
|
.dtor = nv04_fifo_chan_dtor,
|
||||||
.init = nv04_fifo_chan_init,
|
.init = nv04_fifo_chan_init,
|
||||||
.fini = nv04_fifo_chan_fini,
|
.fini = nv04_fifo_chan_fini,
|
||||||
|
.map = _nouveau_fifo_channel_map,
|
||||||
.rd32 = _nouveau_fifo_channel_rd32,
|
.rd32 = _nouveau_fifo_channel_rd32,
|
||||||
.wr32 = _nouveau_fifo_channel_wr32,
|
.wr32 = _nouveau_fifo_channel_wr32,
|
||||||
};
|
};
|
||||||
|
|
|
@ -363,6 +363,7 @@ nv50_fifo_ofuncs_dma = {
|
||||||
.dtor = nv50_fifo_chan_dtor,
|
.dtor = nv50_fifo_chan_dtor,
|
||||||
.init = nv50_fifo_chan_init,
|
.init = nv50_fifo_chan_init,
|
||||||
.fini = nv50_fifo_chan_fini,
|
.fini = nv50_fifo_chan_fini,
|
||||||
|
.map = _nouveau_fifo_channel_map,
|
||||||
.rd32 = _nouveau_fifo_channel_rd32,
|
.rd32 = _nouveau_fifo_channel_rd32,
|
||||||
.wr32 = _nouveau_fifo_channel_wr32,
|
.wr32 = _nouveau_fifo_channel_wr32,
|
||||||
};
|
};
|
||||||
|
@ -373,6 +374,7 @@ nv50_fifo_ofuncs_ind = {
|
||||||
.dtor = nv50_fifo_chan_dtor,
|
.dtor = nv50_fifo_chan_dtor,
|
||||||
.init = nv50_fifo_chan_init,
|
.init = nv50_fifo_chan_init,
|
||||||
.fini = nv50_fifo_chan_fini,
|
.fini = nv50_fifo_chan_fini,
|
||||||
|
.map = _nouveau_fifo_channel_map,
|
||||||
.rd32 = _nouveau_fifo_channel_rd32,
|
.rd32 = _nouveau_fifo_channel_rd32,
|
||||||
.wr32 = _nouveau_fifo_channel_wr32,
|
.wr32 = _nouveau_fifo_channel_wr32,
|
||||||
};
|
};
|
||||||
|
|
|
@ -324,6 +324,7 @@ nv84_fifo_ofuncs_dma = {
|
||||||
.dtor = nv50_fifo_chan_dtor,
|
.dtor = nv50_fifo_chan_dtor,
|
||||||
.init = nv84_fifo_chan_init,
|
.init = nv84_fifo_chan_init,
|
||||||
.fini = nv50_fifo_chan_fini,
|
.fini = nv50_fifo_chan_fini,
|
||||||
|
.map = _nouveau_fifo_channel_map,
|
||||||
.rd32 = _nouveau_fifo_channel_rd32,
|
.rd32 = _nouveau_fifo_channel_rd32,
|
||||||
.wr32 = _nouveau_fifo_channel_wr32,
|
.wr32 = _nouveau_fifo_channel_wr32,
|
||||||
};
|
};
|
||||||
|
@ -334,6 +335,7 @@ nv84_fifo_ofuncs_ind = {
|
||||||
.dtor = nv50_fifo_chan_dtor,
|
.dtor = nv50_fifo_chan_dtor,
|
||||||
.init = nv84_fifo_chan_init,
|
.init = nv84_fifo_chan_init,
|
||||||
.fini = nv50_fifo_chan_fini,
|
.fini = nv50_fifo_chan_fini,
|
||||||
|
.map = _nouveau_fifo_channel_map,
|
||||||
.rd32 = _nouveau_fifo_channel_rd32,
|
.rd32 = _nouveau_fifo_channel_rd32,
|
||||||
.wr32 = _nouveau_fifo_channel_wr32,
|
.wr32 = _nouveau_fifo_channel_wr32,
|
||||||
};
|
};
|
||||||
|
|
|
@ -302,6 +302,7 @@ nvc0_fifo_ofuncs = {
|
||||||
.dtor = _nouveau_fifo_channel_dtor,
|
.dtor = _nouveau_fifo_channel_dtor,
|
||||||
.init = nvc0_fifo_chan_init,
|
.init = nvc0_fifo_chan_init,
|
||||||
.fini = nvc0_fifo_chan_fini,
|
.fini = nvc0_fifo_chan_fini,
|
||||||
|
.map = _nouveau_fifo_channel_map,
|
||||||
.rd32 = _nouveau_fifo_channel_rd32,
|
.rd32 = _nouveau_fifo_channel_rd32,
|
||||||
.wr32 = _nouveau_fifo_channel_wr32,
|
.wr32 = _nouveau_fifo_channel_wr32,
|
||||||
};
|
};
|
||||||
|
|
|
@ -336,6 +336,7 @@ nve0_fifo_ofuncs = {
|
||||||
.dtor = _nouveau_fifo_channel_dtor,
|
.dtor = _nouveau_fifo_channel_dtor,
|
||||||
.init = nve0_fifo_chan_init,
|
.init = nve0_fifo_chan_init,
|
||||||
.fini = nve0_fifo_chan_fini,
|
.fini = nve0_fifo_chan_fini,
|
||||||
|
.map = _nouveau_fifo_channel_map,
|
||||||
.rd32 = _nouveau_fifo_channel_rd32,
|
.rd32 = _nouveau_fifo_channel_rd32,
|
||||||
.wr32 = _nouveau_fifo_channel_wr32,
|
.wr32 = _nouveau_fifo_channel_wr32,
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,7 @@ struct nouveau_fifo_chan {
|
||||||
struct nouveau_dmaobj *pushdma;
|
struct nouveau_dmaobj *pushdma;
|
||||||
struct nouveau_gpuobj *pushgpu;
|
struct nouveau_gpuobj *pushgpu;
|
||||||
void __iomem *user;
|
void __iomem *user;
|
||||||
|
u64 addr;
|
||||||
u32 size;
|
u32 size;
|
||||||
u16 chid;
|
u16 chid;
|
||||||
atomic_t refcnt; /* NV04_NVSW_SET_REF */
|
atomic_t refcnt; /* NV04_NVSW_SET_REF */
|
||||||
|
@ -40,6 +41,7 @@ void nouveau_fifo_channel_destroy(struct nouveau_fifo_chan *);
|
||||||
#define _nouveau_fifo_channel_fini _nouveau_namedb_fini
|
#define _nouveau_fifo_channel_fini _nouveau_namedb_fini
|
||||||
|
|
||||||
void _nouveau_fifo_channel_dtor(struct nouveau_object *);
|
void _nouveau_fifo_channel_dtor(struct nouveau_object *);
|
||||||
|
int _nouveau_fifo_channel_map(struct nouveau_object *, u64 *, u32 *);
|
||||||
u32 _nouveau_fifo_channel_rd32(struct nouveau_object *, u64);
|
u32 _nouveau_fifo_channel_rd32(struct nouveau_object *, u64);
|
||||||
void _nouveau_fifo_channel_wr32(struct nouveau_object *, u64, u32);
|
void _nouveau_fifo_channel_wr32(struct nouveau_object *, u64, u32);
|
||||||
|
|
||||||
|
|
|
@ -291,6 +291,8 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
|
||||||
struct nv_dma_v0 args = {};
|
struct nv_dma_v0 args = {};
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
|
nvif_object_map(chan->object);
|
||||||
|
|
||||||
/* allocate dma objects to cover all allowed vram, and gart */
|
/* allocate dma objects to cover all allowed vram, and gart */
|
||||||
if (device->info.family < NV_DEVICE_INFO_V0_FERMI) {
|
if (device->info.family < NV_DEVICE_INFO_V0_FERMI) {
|
||||||
if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) {
|
if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче