drm/nouveau/fifo/gv100: initial support
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Родитель
facaed62b4
Коммит
37e1c45a58
|
@ -52,6 +52,8 @@
|
||||||
|
|
||||||
#define NV04_DISP /* cl0046.h */ 0x00000046
|
#define NV04_DISP /* cl0046.h */ 0x00000046
|
||||||
|
|
||||||
|
#define VOLTA_USERMODE_A 0x0000c361
|
||||||
|
|
||||||
#define NV03_CHANNEL_DMA /* cl506b.h */ 0x0000006b
|
#define NV03_CHANNEL_DMA /* cl506b.h */ 0x0000006b
|
||||||
#define NV10_CHANNEL_DMA /* cl506b.h */ 0x0000006e
|
#define NV10_CHANNEL_DMA /* cl506b.h */ 0x0000006e
|
||||||
#define NV17_CHANNEL_DMA /* cl506b.h */ 0x0000176e
|
#define NV17_CHANNEL_DMA /* cl506b.h */ 0x0000176e
|
||||||
|
@ -66,6 +68,7 @@
|
||||||
#define KEPLER_CHANNEL_GPFIFO_B /* cla06f.h */ 0x0000a16f
|
#define KEPLER_CHANNEL_GPFIFO_B /* cla06f.h */ 0x0000a16f
|
||||||
#define MAXWELL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000b06f
|
#define MAXWELL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000b06f
|
||||||
#define PASCAL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000c06f
|
#define PASCAL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000c06f
|
||||||
|
#define VOLTA_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000c36f
|
||||||
|
|
||||||
#define NV50_DISP /* cl5070.h */ 0x00005070
|
#define NV50_DISP /* cl5070.h */ 0x00005070
|
||||||
#define G82_DISP /* cl5070.h */ 0x00008270
|
#define G82_DISP /* cl5070.h */ 0x00008270
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <nvif/object.h>
|
#include <nvif/object.h>
|
||||||
#include <nvif/cl0080.h>
|
#include <nvif/cl0080.h>
|
||||||
|
#include <nvif/user.h>
|
||||||
|
|
||||||
struct nvif_device {
|
struct nvif_device {
|
||||||
struct nvif_object object;
|
struct nvif_object object;
|
||||||
|
@ -13,6 +14,8 @@ struct nvif_device {
|
||||||
u64 engines;
|
u64 engines;
|
||||||
} *runlist;
|
} *runlist;
|
||||||
int runlists;
|
int runlists;
|
||||||
|
|
||||||
|
struct nvif_user user;
|
||||||
};
|
};
|
||||||
|
|
||||||
int nvif_device_init(struct nvif_object *, u32 handle, s32 oclass, void *, u32,
|
int nvif_device_init(struct nvif_object *, u32 handle, s32 oclass, void *, u32,
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef __NVIF_USER_H__
|
||||||
|
#define __NVIF_USER_H__
|
||||||
|
#include <nvif/object.h>
|
||||||
|
struct nvif_device;
|
||||||
|
|
||||||
|
struct nvif_user {
|
||||||
|
const struct nvif_user_func *func;
|
||||||
|
struct nvif_object object;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nvif_user_func {
|
||||||
|
void (*doorbell)(struct nvif_user *, u32 token);
|
||||||
|
};
|
||||||
|
|
||||||
|
int nvif_user_init(struct nvif_device *);
|
||||||
|
void nvif_user_fini(struct nvif_device *);
|
||||||
|
|
||||||
|
extern const struct nvif_user_func nvif_userc361;
|
||||||
|
#endif
|
|
@ -73,4 +73,5 @@ int gm200_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
|
||||||
int gm20b_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
|
int gm20b_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
|
||||||
int gp100_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
|
int gp100_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
|
||||||
int gp10b_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
|
int gp10b_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
|
||||||
|
int gv100_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -220,7 +220,8 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
|
||||||
u64 runlist, struct nouveau_channel **pchan)
|
u64 runlist, struct nouveau_channel **pchan)
|
||||||
{
|
{
|
||||||
struct nouveau_cli *cli = (void *)device->object.client;
|
struct nouveau_cli *cli = (void *)device->object.client;
|
||||||
static const u16 oclasses[] = { PASCAL_CHANNEL_GPFIFO_A,
|
static const u16 oclasses[] = { VOLTA_CHANNEL_GPFIFO_A,
|
||||||
|
PASCAL_CHANNEL_GPFIFO_A,
|
||||||
MAXWELL_CHANNEL_GPFIFO_A,
|
MAXWELL_CHANNEL_GPFIFO_A,
|
||||||
KEPLER_CHANNEL_GPFIFO_B,
|
KEPLER_CHANNEL_GPFIFO_B,
|
||||||
KEPLER_CHANNEL_GPFIFO_A,
|
KEPLER_CHANNEL_GPFIFO_A,
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include "nouveau_dma.h"
|
#include "nouveau_dma.h"
|
||||||
#include "nouveau_vmm.h"
|
#include "nouveau_vmm.h"
|
||||||
|
|
||||||
|
#include <nvif/user.h>
|
||||||
|
|
||||||
void
|
void
|
||||||
OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords)
|
OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords)
|
||||||
{
|
{
|
||||||
|
@ -82,6 +84,7 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout)
|
||||||
void
|
void
|
||||||
nv50_dma_push(struct nouveau_channel *chan, u64 offset, int length)
|
nv50_dma_push(struct nouveau_channel *chan, u64 offset, int length)
|
||||||
{
|
{
|
||||||
|
struct nvif_user *user = &chan->drm->client.device.user;
|
||||||
struct nouveau_bo *pb = chan->push.buffer;
|
struct nouveau_bo *pb = chan->push.buffer;
|
||||||
int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;
|
int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;
|
||||||
|
|
||||||
|
@ -97,6 +100,8 @@ nv50_dma_push(struct nouveau_channel *chan, u64 offset, int length)
|
||||||
nouveau_bo_rd32(pb, 0);
|
nouveau_bo_rd32(pb, 0);
|
||||||
|
|
||||||
nvif_wr32(&chan->user, 0x8c, chan->dma.ib_put);
|
nvif_wr32(&chan->user, 0x8c, chan->dma.ib_put);
|
||||||
|
if (user->func && user->func->doorbell)
|
||||||
|
user->func->doorbell(user, chan->chid);
|
||||||
chan->dma.ib_free--;
|
chan->dma.ib_free--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
#include <nvif/driver.h>
|
#include <nvif/driver.h>
|
||||||
#include <nvif/fifo.h>
|
#include <nvif/fifo.h>
|
||||||
|
#include <nvif/user.h>
|
||||||
|
|
||||||
#include <nvif/class.h>
|
#include <nvif/class.h>
|
||||||
#include <nvif/cl0002.h>
|
#include <nvif/cl0002.h>
|
||||||
|
@ -310,6 +311,12 @@ nouveau_accel_init(struct nouveau_drm *drm)
|
||||||
if (ret)
|
if (ret)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_VOLTA) {
|
||||||
|
ret = nvif_user_init(device);
|
||||||
|
if (ret)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* initialise synchronisation routines */
|
/* initialise synchronisation routines */
|
||||||
/*XXX: this is crap, but the fence/channel stuff is a little
|
/*XXX: this is crap, but the fence/channel stuff is a little
|
||||||
* backwards in some places. this will be fixed.
|
* backwards in some places. this will be fixed.
|
||||||
|
@ -341,6 +348,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
|
||||||
case KEPLER_CHANNEL_GPFIFO_B:
|
case KEPLER_CHANNEL_GPFIFO_B:
|
||||||
case MAXWELL_CHANNEL_GPFIFO_A:
|
case MAXWELL_CHANNEL_GPFIFO_A:
|
||||||
case PASCAL_CHANNEL_GPFIFO_A:
|
case PASCAL_CHANNEL_GPFIFO_A:
|
||||||
|
case VOLTA_CHANNEL_GPFIFO_A:
|
||||||
ret = nvc0_fence_create(drm);
|
ret = nvc0_fence_create(drm);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -8,3 +8,7 @@ nvif-y += nvif/mem.o
|
||||||
nvif-y += nvif/mmu.o
|
nvif-y += nvif/mmu.o
|
||||||
nvif-y += nvif/notify.o
|
nvif-y += nvif/notify.o
|
||||||
nvif-y += nvif/vmm.o
|
nvif-y += nvif/vmm.o
|
||||||
|
|
||||||
|
# Usermode classes
|
||||||
|
nvif-y += nvif/user.o
|
||||||
|
nvif-y += nvif/userc361.o
|
||||||
|
|
|
@ -37,6 +37,7 @@ nvif_device_time(struct nvif_device *device)
|
||||||
void
|
void
|
||||||
nvif_device_fini(struct nvif_device *device)
|
nvif_device_fini(struct nvif_device *device)
|
||||||
{
|
{
|
||||||
|
nvif_user_fini(device);
|
||||||
kfree(device->runlist);
|
kfree(device->runlist);
|
||||||
device->runlist = NULL;
|
device->runlist = NULL;
|
||||||
nvif_object_fini(&device->object);
|
nvif_object_fini(&device->object);
|
||||||
|
@ -49,6 +50,7 @@ nvif_device_init(struct nvif_object *parent, u32 handle, s32 oclass,
|
||||||
int ret = nvif_object_init(parent, handle, oclass, data, size,
|
int ret = nvif_object_init(parent, handle, oclass, data, size,
|
||||||
&device->object);
|
&device->object);
|
||||||
device->runlist = NULL;
|
device->runlist = NULL;
|
||||||
|
device->user.func = NULL;
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
device->info.version = 0;
|
device->info.version = 0;
|
||||||
ret = nvif_object_mthd(&device->object, NV_DEVICE_V0_INFO,
|
ret = nvif_object_mthd(&device->object, NV_DEVICE_V0_INFO,
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#include <nvif/user.h>
|
||||||
|
#include <nvif/device.h>
|
||||||
|
|
||||||
|
#include <nvif/class.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
nvif_user_fini(struct nvif_device *device)
|
||||||
|
{
|
||||||
|
if (device->user.func) {
|
||||||
|
nvif_object_fini(&device->user.object);
|
||||||
|
device->user.func = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
nvif_user_init(struct nvif_device *device)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
s32 oclass;
|
||||||
|
int version;
|
||||||
|
const struct nvif_user_func *func;
|
||||||
|
} users[] = {
|
||||||
|
{ VOLTA_USERMODE_A, -1, &nvif_userc361 },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
int cid, ret;
|
||||||
|
|
||||||
|
if (device->user.func)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cid = nvif_mclass(&device->object, users);
|
||||||
|
if (cid < 0)
|
||||||
|
return cid;
|
||||||
|
|
||||||
|
ret = nvif_object_init(&device->object, 0, users[cid].oclass, NULL, 0,
|
||||||
|
&device->user.object);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
nvif_object_map(&device->user.object, NULL, 0);
|
||||||
|
device->user.func = users[cid].func;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#include <nvif/user.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
nvif_userc361_doorbell(struct nvif_user *user, u32 token)
|
||||||
|
{
|
||||||
|
nvif_wr32(&user->object, 0x90, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct nvif_user_func
|
||||||
|
nvif_userc361 = {
|
||||||
|
.doorbell = nvif_userc361_doorbell,
|
||||||
|
};
|
|
@ -2418,6 +2418,7 @@ nv140_chipset = {
|
||||||
.top = gk104_top_new,
|
.top = gk104_top_new,
|
||||||
.disp = gv100_disp_new,
|
.disp = gv100_disp_new,
|
||||||
.dma = gv100_dma_new,
|
.dma = gv100_dma_new,
|
||||||
|
.fifo = gv100_fifo_new,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -15,6 +15,7 @@ nvkm-y += nvkm/engine/fifo/gm200.o
|
||||||
nvkm-y += nvkm/engine/fifo/gm20b.o
|
nvkm-y += nvkm/engine/fifo/gm20b.o
|
||||||
nvkm-y += nvkm/engine/fifo/gp100.o
|
nvkm-y += nvkm/engine/fifo/gp100.o
|
||||||
nvkm-y += nvkm/engine/fifo/gp10b.o
|
nvkm-y += nvkm/engine/fifo/gp10b.o
|
||||||
|
nvkm-y += nvkm/engine/fifo/gv100.o
|
||||||
|
|
||||||
nvkm-y += nvkm/engine/fifo/chan.o
|
nvkm-y += nvkm/engine/fifo/chan.o
|
||||||
nvkm-y += nvkm/engine/fifo/channv50.o
|
nvkm-y += nvkm/engine/fifo/channv50.o
|
||||||
|
@ -31,3 +32,6 @@ nvkm-y += nvkm/engine/fifo/gpfifonv50.o
|
||||||
nvkm-y += nvkm/engine/fifo/gpfifog84.o
|
nvkm-y += nvkm/engine/fifo/gpfifog84.o
|
||||||
nvkm-y += nvkm/engine/fifo/gpfifogf100.o
|
nvkm-y += nvkm/engine/fifo/gpfifogf100.o
|
||||||
nvkm-y += nvkm/engine/fifo/gpfifogk104.o
|
nvkm-y += nvkm/engine/fifo/gpfifogk104.o
|
||||||
|
nvkm-y += nvkm/engine/fifo/gpfifogv100.o
|
||||||
|
|
||||||
|
nvkm-y += nvkm/engine/fifo/usergv100.o
|
||||||
|
|
|
@ -20,6 +20,20 @@ struct gk104_fifo_chan {
|
||||||
} engn[NVKM_SUBDEV_NR];
|
} engn[NVKM_SUBDEV_NR];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern const struct nvkm_fifo_chan_func gk104_fifo_gpfifo_func;
|
||||||
|
|
||||||
int gk104_fifo_gpfifo_new(struct gk104_fifo *, const struct nvkm_oclass *,
|
int gk104_fifo_gpfifo_new(struct gk104_fifo *, const struct nvkm_oclass *,
|
||||||
void *data, u32 size, struct nvkm_object **);
|
void *data, u32 size, struct nvkm_object **);
|
||||||
|
void *gk104_fifo_gpfifo_dtor(struct nvkm_fifo_chan *);
|
||||||
|
void gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *);
|
||||||
|
void gk104_fifo_gpfifo_fini(struct nvkm_fifo_chan *);
|
||||||
|
int gk104_fifo_gpfifo_engine_ctor(struct nvkm_fifo_chan *, struct nvkm_engine *,
|
||||||
|
struct nvkm_object *);
|
||||||
|
void gk104_fifo_gpfifo_engine_dtor(struct nvkm_fifo_chan *,
|
||||||
|
struct nvkm_engine *);
|
||||||
|
int gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *);
|
||||||
|
int gk104_fifo_gpfifo_kick_locked(struct gk104_fifo_chan *);
|
||||||
|
|
||||||
|
int gv100_fifo_gpfifo_new(struct gk104_fifo *, const struct nvkm_oclass *,
|
||||||
|
void *data, u32 size, struct nvkm_object **);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -103,6 +103,10 @@ gk104_fifo_class_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
|
||||||
if (oclass->engn == &fifo->func->chan) {
|
if (oclass->engn == &fifo->func->chan) {
|
||||||
const struct gk104_fifo_chan_user *user = oclass->engn;
|
const struct gk104_fifo_chan_user *user = oclass->engn;
|
||||||
return user->ctor(fifo, oclass, argv, argc, pobject);
|
return user->ctor(fifo, oclass, argv, argc, pobject);
|
||||||
|
} else
|
||||||
|
if (oclass->engn == &fifo->func->user) {
|
||||||
|
const struct gk104_fifo_user_user *user = oclass->engn;
|
||||||
|
return user->ctor(oclass, argv, argc, pobject);
|
||||||
}
|
}
|
||||||
WARN_ON(1);
|
WARN_ON(1);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -115,6 +119,12 @@ gk104_fifo_class_get(struct nvkm_fifo *base, int index,
|
||||||
struct gk104_fifo *fifo = gk104_fifo(base);
|
struct gk104_fifo *fifo = gk104_fifo(base);
|
||||||
int c = 0;
|
int c = 0;
|
||||||
|
|
||||||
|
if (fifo->func->user.ctor && c++ == index) {
|
||||||
|
oclass->base = fifo->func->user.user;
|
||||||
|
oclass->engn = &fifo->func->user;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (fifo->func->chan.ctor && c++ == index) {
|
if (fifo->func->chan.ctor && c++ == index) {
|
||||||
oclass->base = fifo->func->chan.user;
|
oclass->base = fifo->func->chan.user;
|
||||||
oclass->engn = &fifo->func->chan;
|
oclass->engn = &fifo->func->chan;
|
||||||
|
|
|
@ -63,6 +63,12 @@ struct gk104_fifo_func {
|
||||||
struct nvkm_memory *, u32 offset);
|
struct nvkm_memory *, u32 offset);
|
||||||
} *runlist;
|
} *runlist;
|
||||||
|
|
||||||
|
struct gk104_fifo_user_user {
|
||||||
|
struct nvkm_sclass user;
|
||||||
|
int (*ctor)(const struct nvkm_oclass *, void *, u32,
|
||||||
|
struct nvkm_object **);
|
||||||
|
} user;
|
||||||
|
|
||||||
struct gk104_fifo_chan_user {
|
struct gk104_fifo_chan_user {
|
||||||
struct nvkm_sclass user;
|
struct nvkm_sclass user;
|
||||||
int (*ctor)(struct gk104_fifo *, const struct nvkm_oclass *,
|
int (*ctor)(struct gk104_fifo *, const struct nvkm_oclass *,
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
#include <nvif/cla06f.h>
|
#include <nvif/cla06f.h>
|
||||||
#include <nvif/unpack.h>
|
#include <nvif/unpack.h>
|
||||||
|
|
||||||
static int
|
int
|
||||||
gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan)
|
gk104_fifo_gpfifo_kick_locked(struct gk104_fifo_chan *chan)
|
||||||
{
|
{
|
||||||
struct gk104_fifo *fifo = chan->fifo;
|
struct gk104_fifo *fifo = chan->fifo;
|
||||||
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
|
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
|
||||||
|
@ -44,7 +44,6 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan)
|
||||||
struct nvkm_fifo_cgrp *cgrp = chan->cgrp;
|
struct nvkm_fifo_cgrp *cgrp = chan->cgrp;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
mutex_lock(&subdev->mutex);
|
|
||||||
if (cgrp)
|
if (cgrp)
|
||||||
nvkm_wr32(device, 0x002634, cgrp->id | 0x01000000);
|
nvkm_wr32(device, 0x002634, cgrp->id | 0x01000000);
|
||||||
else
|
else
|
||||||
|
@ -59,7 +58,16 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan)
|
||||||
nvkm_fifo_recover_chan(&fifo->base, chan->base.chid);
|
nvkm_fifo_recover_chan(&fifo->base, chan->base.chid);
|
||||||
ret = -ETIMEDOUT;
|
ret = -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
mutex_unlock(&subdev->mutex);
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
mutex_lock(&chan->base.fifo->engine.subdev.mutex);
|
||||||
|
ret = gk104_fifo_gpfifo_kick_locked(chan);
|
||||||
|
mutex_unlock(&chan->base.fifo->engine.subdev.mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +146,7 @@ gk104_fifo_gpfifo_engine_init(struct nvkm_fifo_chan *base,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
gk104_fifo_gpfifo_engine_dtor(struct nvkm_fifo_chan *base,
|
gk104_fifo_gpfifo_engine_dtor(struct nvkm_fifo_chan *base,
|
||||||
struct nvkm_engine *engine)
|
struct nvkm_engine *engine)
|
||||||
{
|
{
|
||||||
|
@ -147,7 +155,7 @@ gk104_fifo_gpfifo_engine_dtor(struct nvkm_fifo_chan *base,
|
||||||
nvkm_gpuobj_del(&chan->engn[engine->subdev.index].inst);
|
nvkm_gpuobj_del(&chan->engn[engine->subdev.index].inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
gk104_fifo_gpfifo_engine_ctor(struct nvkm_fifo_chan *base,
|
gk104_fifo_gpfifo_engine_ctor(struct nvkm_fifo_chan *base,
|
||||||
struct nvkm_engine *engine,
|
struct nvkm_engine *engine,
|
||||||
struct nvkm_object *object)
|
struct nvkm_object *object)
|
||||||
|
@ -172,7 +180,7 @@ gk104_fifo_gpfifo_engine_ctor(struct nvkm_fifo_chan *base,
|
||||||
chan->engn[engn].vma, NULL, 0);
|
chan->engn[engn].vma, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
gk104_fifo_gpfifo_fini(struct nvkm_fifo_chan *base)
|
gk104_fifo_gpfifo_fini(struct nvkm_fifo_chan *base)
|
||||||
{
|
{
|
||||||
struct gk104_fifo_chan *chan = gk104_fifo_chan(base);
|
struct gk104_fifo_chan *chan = gk104_fifo_chan(base);
|
||||||
|
@ -190,7 +198,7 @@ gk104_fifo_gpfifo_fini(struct nvkm_fifo_chan *base)
|
||||||
nvkm_wr32(device, 0x800000 + coff, 0x00000000);
|
nvkm_wr32(device, 0x800000 + coff, 0x00000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *base)
|
gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *base)
|
||||||
{
|
{
|
||||||
struct gk104_fifo_chan *chan = gk104_fifo_chan(base);
|
struct gk104_fifo_chan *chan = gk104_fifo_chan(base);
|
||||||
|
@ -210,7 +218,7 @@ gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *base)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
void *
|
||||||
gk104_fifo_gpfifo_dtor(struct nvkm_fifo_chan *base)
|
gk104_fifo_gpfifo_dtor(struct nvkm_fifo_chan *base)
|
||||||
{
|
{
|
||||||
struct gk104_fifo_chan *chan = gk104_fifo_chan(base);
|
struct gk104_fifo_chan *chan = gk104_fifo_chan(base);
|
||||||
|
@ -218,7 +226,7 @@ gk104_fifo_gpfifo_dtor(struct nvkm_fifo_chan *base)
|
||||||
return chan;
|
return chan;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct nvkm_fifo_chan_func
|
const struct nvkm_fifo_chan_func
|
||||||
gk104_fifo_gpfifo_func = {
|
gk104_fifo_gpfifo_func = {
|
||||||
.dtor = gk104_fifo_gpfifo_dtor,
|
.dtor = gk104_fifo_gpfifo_dtor,
|
||||||
.init = gk104_fifo_gpfifo_init,
|
.init = gk104_fifo_gpfifo_init,
|
||||||
|
|
|
@ -0,0 +1,225 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#include "changk104.h"
|
||||||
|
#include "cgrp.h"
|
||||||
|
|
||||||
|
#include <core/client.h>
|
||||||
|
#include <core/gpuobj.h>
|
||||||
|
|
||||||
|
#include <nvif/cla06f.h>
|
||||||
|
#include <nvif/unpack.h>
|
||||||
|
|
||||||
|
static int
|
||||||
|
gv100_fifo_gpfifo_engine_valid(struct gk104_fifo_chan *chan, bool ce, bool valid)
|
||||||
|
{
|
||||||
|
struct nvkm_subdev *subdev = &chan->base.fifo->engine.subdev;
|
||||||
|
struct nvkm_device *device = subdev->device;
|
||||||
|
const u32 mask = ce ? 0x00020000 : 0x00010000;
|
||||||
|
const u32 data = valid ? mask : 0x00000000;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Block runlist to prevent the channel from being rescheduled. */
|
||||||
|
mutex_lock(&subdev->mutex);
|
||||||
|
nvkm_mask(device, 0x002630, BIT(chan->runl), BIT(chan->runl));
|
||||||
|
|
||||||
|
/* Preempt the channel. */
|
||||||
|
ret = gk104_fifo_gpfifo_kick_locked(chan);
|
||||||
|
if (ret == 0) {
|
||||||
|
/* Update engine context validity. */
|
||||||
|
nvkm_kmap(chan->base.inst);
|
||||||
|
nvkm_mo32(chan->base.inst, 0x0ac, mask, data);
|
||||||
|
nvkm_done(chan->base.inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resume runlist. */
|
||||||
|
nvkm_mask(device, 0x002630, BIT(chan->runl), 0);
|
||||||
|
mutex_unlock(&subdev->mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gv100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base,
|
||||||
|
struct nvkm_engine *engine, bool suspend)
|
||||||
|
{
|
||||||
|
struct gk104_fifo_chan *chan = gk104_fifo_chan(base);
|
||||||
|
struct nvkm_gpuobj *inst = chan->base.inst;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (engine->subdev.index >= NVKM_ENGINE_CE0 &&
|
||||||
|
engine->subdev.index <= NVKM_ENGINE_CE_LAST)
|
||||||
|
return gk104_fifo_gpfifo_kick(chan);
|
||||||
|
|
||||||
|
ret = gv100_fifo_gpfifo_engine_valid(chan, false, false);
|
||||||
|
if (ret && suspend)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
nvkm_kmap(inst);
|
||||||
|
nvkm_wo32(inst, 0x0210, 0x00000000);
|
||||||
|
nvkm_wo32(inst, 0x0214, 0x00000000);
|
||||||
|
nvkm_done(inst);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gv100_fifo_gpfifo_engine_init(struct nvkm_fifo_chan *base,
|
||||||
|
struct nvkm_engine *engine)
|
||||||
|
{
|
||||||
|
struct gk104_fifo_chan *chan = gk104_fifo_chan(base);
|
||||||
|
struct nvkm_gpuobj *inst = chan->base.inst;
|
||||||
|
u64 addr;
|
||||||
|
|
||||||
|
if (engine->subdev.index >= NVKM_ENGINE_CE0 &&
|
||||||
|
engine->subdev.index <= NVKM_ENGINE_CE_LAST)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
addr = chan->engn[engine->subdev.index].vma->addr;
|
||||||
|
nvkm_kmap(inst);
|
||||||
|
nvkm_wo32(inst, 0x210, lower_32_bits(addr) | 0x00000004);
|
||||||
|
nvkm_wo32(inst, 0x214, upper_32_bits(addr));
|
||||||
|
nvkm_done(inst);
|
||||||
|
|
||||||
|
return gv100_fifo_gpfifo_engine_valid(chan, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct nvkm_fifo_chan_func
|
||||||
|
gv100_fifo_gpfifo_func = {
|
||||||
|
.dtor = gk104_fifo_gpfifo_dtor,
|
||||||
|
.init = gk104_fifo_gpfifo_init,
|
||||||
|
.fini = gk104_fifo_gpfifo_fini,
|
||||||
|
.ntfy = gf100_fifo_chan_ntfy,
|
||||||
|
.engine_ctor = gk104_fifo_gpfifo_engine_ctor,
|
||||||
|
.engine_dtor = gk104_fifo_gpfifo_engine_dtor,
|
||||||
|
.engine_init = gv100_fifo_gpfifo_engine_init,
|
||||||
|
.engine_fini = gv100_fifo_gpfifo_engine_fini,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
gv100_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
|
||||||
|
u64 vmm, u64 ioffset, u64 ilength,
|
||||||
|
const struct nvkm_oclass *oclass,
|
||||||
|
struct nvkm_object **pobject)
|
||||||
|
{
|
||||||
|
struct gk104_fifo_chan *chan;
|
||||||
|
int runlist = ffs(*runlists) -1, ret, i;
|
||||||
|
unsigned long engm;
|
||||||
|
u64 subdevs = 0;
|
||||||
|
u64 usermem;
|
||||||
|
|
||||||
|
if (!vmm || runlist < 0 || runlist >= fifo->runlist_nr)
|
||||||
|
return -EINVAL;
|
||||||
|
*runlists = BIT_ULL(runlist);
|
||||||
|
|
||||||
|
engm = fifo->runlist[runlist].engm;
|
||||||
|
for_each_set_bit(i, &engm, fifo->engine_nr) {
|
||||||
|
if (fifo->engine[i].engine)
|
||||||
|
subdevs |= BIT_ULL(fifo->engine[i].engine->subdev.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate the channel. */
|
||||||
|
if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL)))
|
||||||
|
return -ENOMEM;
|
||||||
|
*pobject = &chan->base.object;
|
||||||
|
chan->fifo = fifo;
|
||||||
|
chan->runl = runlist;
|
||||||
|
INIT_LIST_HEAD(&chan->head);
|
||||||
|
|
||||||
|
ret = nvkm_fifo_chan_ctor(&gv100_fifo_gpfifo_func, &fifo->base,
|
||||||
|
0x1000, 0x1000, true, vmm, 0, subdevs,
|
||||||
|
1, fifo->user.bar->addr, 0x200,
|
||||||
|
oclass, &chan->base);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
*chid = chan->base.chid;
|
||||||
|
|
||||||
|
/* Hack to support GPUs where even individual channels should be
|
||||||
|
* part of a channel group.
|
||||||
|
*/
|
||||||
|
if (fifo->func->cgrp_force) {
|
||||||
|
if (!(chan->cgrp = kmalloc(sizeof(*chan->cgrp), GFP_KERNEL)))
|
||||||
|
return -ENOMEM;
|
||||||
|
chan->cgrp->id = chan->base.chid;
|
||||||
|
INIT_LIST_HEAD(&chan->cgrp->head);
|
||||||
|
INIT_LIST_HEAD(&chan->cgrp->chan);
|
||||||
|
chan->cgrp->chan_nr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear channel control registers. */
|
||||||
|
usermem = chan->base.chid * 0x200;
|
||||||
|
ilength = order_base_2(ilength / 8);
|
||||||
|
|
||||||
|
nvkm_kmap(fifo->user.mem);
|
||||||
|
for (i = 0; i < 0x200; i += 4)
|
||||||
|
nvkm_wo32(fifo->user.mem, usermem + i, 0x00000000);
|
||||||
|
nvkm_done(fifo->user.mem);
|
||||||
|
usermem = nvkm_memory_addr(fifo->user.mem) + usermem;
|
||||||
|
|
||||||
|
/* RAMFC */
|
||||||
|
nvkm_kmap(chan->base.inst);
|
||||||
|
nvkm_wo32(chan->base.inst, 0x008, lower_32_bits(usermem));
|
||||||
|
nvkm_wo32(chan->base.inst, 0x00c, upper_32_bits(usermem));
|
||||||
|
nvkm_wo32(chan->base.inst, 0x010, 0x0000face);
|
||||||
|
nvkm_wo32(chan->base.inst, 0x030, 0x7ffff902);
|
||||||
|
nvkm_wo32(chan->base.inst, 0x048, lower_32_bits(ioffset));
|
||||||
|
nvkm_wo32(chan->base.inst, 0x04c, upper_32_bits(ioffset) |
|
||||||
|
(ilength << 16));
|
||||||
|
nvkm_wo32(chan->base.inst, 0x084, 0x20400000);
|
||||||
|
nvkm_wo32(chan->base.inst, 0x094, 0x30000001);
|
||||||
|
nvkm_wo32(chan->base.inst, 0x0e4, 0x00000020);
|
||||||
|
nvkm_wo32(chan->base.inst, 0x0e8, chan->base.chid);
|
||||||
|
nvkm_wo32(chan->base.inst, 0x0f4, 0x00001100);
|
||||||
|
nvkm_wo32(chan->base.inst, 0x0f8, 0x10003080);
|
||||||
|
nvkm_mo32(chan->base.inst, 0x218, 0x00000000, 0x00000000);
|
||||||
|
nvkm_wo32(chan->base.inst, 0x220, 0x020a1000);
|
||||||
|
nvkm_wo32(chan->base.inst, 0x224, 0x00000000);
|
||||||
|
nvkm_done(chan->base.inst);
|
||||||
|
return gv100_fifo_gpfifo_engine_valid(chan, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gv100_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
|
||||||
|
void *data, u32 size, struct nvkm_object **pobject)
|
||||||
|
{
|
||||||
|
struct nvkm_object *parent = oclass->parent;
|
||||||
|
union {
|
||||||
|
struct kepler_channel_gpfifo_a_v0 v0;
|
||||||
|
} *args = data;
|
||||||
|
int ret = -ENOSYS;
|
||||||
|
|
||||||
|
nvif_ioctl(parent, "create channel gpfifo size %d\n", size);
|
||||||
|
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
|
||||||
|
nvif_ioctl(parent, "create channel gpfifo vers %d vmm %llx "
|
||||||
|
"ioffset %016llx ilength %08x "
|
||||||
|
"runlist %016llx\n",
|
||||||
|
args->v0.version, args->v0.vmm, args->v0.ioffset,
|
||||||
|
args->v0.ilength, args->v0.runlist);
|
||||||
|
return gv100_fifo_gpfifo_new_(fifo,
|
||||||
|
&args->v0.runlist,
|
||||||
|
&args->v0.chid,
|
||||||
|
args->v0.vmm,
|
||||||
|
args->v0.ioffset,
|
||||||
|
args->v0.ilength,
|
||||||
|
oclass, pobject);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -0,0 +1,306 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#include "gk104.h"
|
||||||
|
#include "cgrp.h"
|
||||||
|
#include "changk104.h"
|
||||||
|
#include "user.h"
|
||||||
|
|
||||||
|
#include <core/gpuobj.h>
|
||||||
|
|
||||||
|
#include <nvif/class.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
gv100_fifo_runlist_chan(struct gk104_fifo_chan *chan,
|
||||||
|
struct nvkm_memory *memory, u32 offset)
|
||||||
|
{
|
||||||
|
struct nvkm_memory *usermem = chan->fifo->user.mem;
|
||||||
|
const u64 user = nvkm_memory_addr(usermem) + (chan->base.chid * 0x200);
|
||||||
|
const u64 inst = chan->base.inst->addr;
|
||||||
|
|
||||||
|
nvkm_wo32(memory, offset + 0x0, lower_32_bits(user));
|
||||||
|
nvkm_wo32(memory, offset + 0x4, upper_32_bits(user));
|
||||||
|
nvkm_wo32(memory, offset + 0x8, lower_32_bits(inst) | chan->base.chid);
|
||||||
|
nvkm_wo32(memory, offset + 0xc, upper_32_bits(inst));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gv100_fifo_runlist_cgrp(struct nvkm_fifo_cgrp *cgrp,
|
||||||
|
struct nvkm_memory *memory, u32 offset)
|
||||||
|
{
|
||||||
|
nvkm_wo32(memory, offset + 0x0, (128 << 24) | (3 << 16) | 0x00000001);
|
||||||
|
nvkm_wo32(memory, offset + 0x4, cgrp->chan_nr);
|
||||||
|
nvkm_wo32(memory, offset + 0x8, cgrp->id);
|
||||||
|
nvkm_wo32(memory, offset + 0xc, 0x00000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct gk104_fifo_runlist_func
|
||||||
|
gv100_fifo_runlist = {
|
||||||
|
.size = 16,
|
||||||
|
.cgrp = gv100_fifo_runlist_cgrp,
|
||||||
|
.chan = gv100_fifo_runlist_chan,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct nvkm_enum
|
||||||
|
gv100_fifo_fault_gpcclient[] = {
|
||||||
|
{ 0x00, "T1_0" },
|
||||||
|
{ 0x01, "T1_1" },
|
||||||
|
{ 0x02, "T1_2" },
|
||||||
|
{ 0x03, "T1_3" },
|
||||||
|
{ 0x04, "T1_4" },
|
||||||
|
{ 0x05, "T1_5" },
|
||||||
|
{ 0x06, "T1_6" },
|
||||||
|
{ 0x07, "T1_7" },
|
||||||
|
{ 0x08, "PE_0" },
|
||||||
|
{ 0x09, "PE_1" },
|
||||||
|
{ 0x0a, "PE_2" },
|
||||||
|
{ 0x0b, "PE_3" },
|
||||||
|
{ 0x0c, "PE_4" },
|
||||||
|
{ 0x0d, "PE_5" },
|
||||||
|
{ 0x0e, "PE_6" },
|
||||||
|
{ 0x0f, "PE_7" },
|
||||||
|
{ 0x10, "RAST" },
|
||||||
|
{ 0x11, "GCC" },
|
||||||
|
{ 0x12, "GPCCS" },
|
||||||
|
{ 0x13, "PROP_0" },
|
||||||
|
{ 0x14, "PROP_1" },
|
||||||
|
{ 0x15, "PROP_2" },
|
||||||
|
{ 0x16, "PROP_3" },
|
||||||
|
{ 0x17, "GPM" },
|
||||||
|
{ 0x18, "LTP_UTLB_0" },
|
||||||
|
{ 0x19, "LTP_UTLB_1" },
|
||||||
|
{ 0x1a, "LTP_UTLB_2" },
|
||||||
|
{ 0x1b, "LTP_UTLB_3" },
|
||||||
|
{ 0x1c, "LTP_UTLB_4" },
|
||||||
|
{ 0x1d, "LTP_UTLB_5" },
|
||||||
|
{ 0x1e, "LTP_UTLB_6" },
|
||||||
|
{ 0x1f, "LTP_UTLB_7" },
|
||||||
|
{ 0x20, "RGG_UTLB" },
|
||||||
|
{ 0x21, "T1_8" },
|
||||||
|
{ 0x22, "T1_9" },
|
||||||
|
{ 0x23, "T1_10" },
|
||||||
|
{ 0x24, "T1_11" },
|
||||||
|
{ 0x25, "T1_12" },
|
||||||
|
{ 0x26, "T1_13" },
|
||||||
|
{ 0x27, "T1_14" },
|
||||||
|
{ 0x28, "T1_15" },
|
||||||
|
{ 0x29, "TPCCS_0" },
|
||||||
|
{ 0x2a, "TPCCS_1" },
|
||||||
|
{ 0x2b, "TPCCS_2" },
|
||||||
|
{ 0x2c, "TPCCS_3" },
|
||||||
|
{ 0x2d, "TPCCS_4" },
|
||||||
|
{ 0x2e, "TPCCS_5" },
|
||||||
|
{ 0x2f, "TPCCS_6" },
|
||||||
|
{ 0x30, "TPCCS_7" },
|
||||||
|
{ 0x31, "PE_8" },
|
||||||
|
{ 0x32, "PE_9" },
|
||||||
|
{ 0x33, "TPCCS_8" },
|
||||||
|
{ 0x34, "TPCCS_9" },
|
||||||
|
{ 0x35, "T1_16" },
|
||||||
|
{ 0x36, "T1_17" },
|
||||||
|
{ 0x37, "T1_18" },
|
||||||
|
{ 0x38, "T1_19" },
|
||||||
|
{ 0x39, "PE_10" },
|
||||||
|
{ 0x3a, "PE_11" },
|
||||||
|
{ 0x3b, "TPCCS_10" },
|
||||||
|
{ 0x3c, "TPCCS_11" },
|
||||||
|
{ 0x3d, "T1_20" },
|
||||||
|
{ 0x3e, "T1_21" },
|
||||||
|
{ 0x3f, "T1_22" },
|
||||||
|
{ 0x40, "T1_23" },
|
||||||
|
{ 0x41, "PE_12" },
|
||||||
|
{ 0x42, "PE_13" },
|
||||||
|
{ 0x43, "TPCCS_12" },
|
||||||
|
{ 0x44, "TPCCS_13" },
|
||||||
|
{ 0x45, "T1_24" },
|
||||||
|
{ 0x46, "T1_25" },
|
||||||
|
{ 0x47, "T1_26" },
|
||||||
|
{ 0x48, "T1_27" },
|
||||||
|
{ 0x49, "PE_14" },
|
||||||
|
{ 0x4a, "PE_15" },
|
||||||
|
{ 0x4b, "TPCCS_14" },
|
||||||
|
{ 0x4c, "TPCCS_15" },
|
||||||
|
{ 0x4d, "T1_28" },
|
||||||
|
{ 0x4e, "T1_29" },
|
||||||
|
{ 0x4f, "T1_30" },
|
||||||
|
{ 0x50, "T1_31" },
|
||||||
|
{ 0x51, "PE_16" },
|
||||||
|
{ 0x52, "PE_17" },
|
||||||
|
{ 0x53, "TPCCS_16" },
|
||||||
|
{ 0x54, "TPCCS_17" },
|
||||||
|
{ 0x55, "T1_32" },
|
||||||
|
{ 0x56, "T1_33" },
|
||||||
|
{ 0x57, "T1_34" },
|
||||||
|
{ 0x58, "T1_35" },
|
||||||
|
{ 0x59, "PE_18" },
|
||||||
|
{ 0x5a, "PE_19" },
|
||||||
|
{ 0x5b, "TPCCS_18" },
|
||||||
|
{ 0x5c, "TPCCS_19" },
|
||||||
|
{ 0x5d, "T1_36" },
|
||||||
|
{ 0x5e, "T1_37" },
|
||||||
|
{ 0x5f, "T1_38" },
|
||||||
|
{ 0x60, "T1_39" },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct nvkm_enum
|
||||||
|
gv100_fifo_fault_hubclient[] = {
|
||||||
|
{ 0x00, "VIP" },
|
||||||
|
{ 0x01, "CE0" },
|
||||||
|
{ 0x02, "CE1" },
|
||||||
|
{ 0x03, "DNISO" },
|
||||||
|
{ 0x04, "FE" },
|
||||||
|
{ 0x05, "FECS" },
|
||||||
|
{ 0x06, "HOST" },
|
||||||
|
{ 0x07, "HOST_CPU" },
|
||||||
|
{ 0x08, "HOST_CPU_NB" },
|
||||||
|
{ 0x09, "ISO" },
|
||||||
|
{ 0x0a, "MMU" },
|
||||||
|
{ 0x0b, "NVDEC" },
|
||||||
|
{ 0x0d, "NVENC1" },
|
||||||
|
{ 0x0e, "NISO" },
|
||||||
|
{ 0x0f, "P2P" },
|
||||||
|
{ 0x10, "PD" },
|
||||||
|
{ 0x11, "PERF" },
|
||||||
|
{ 0x12, "PMU" },
|
||||||
|
{ 0x13, "RASTERTWOD" },
|
||||||
|
{ 0x14, "SCC" },
|
||||||
|
{ 0x15, "SCC_NB" },
|
||||||
|
{ 0x16, "SEC" },
|
||||||
|
{ 0x17, "SSYNC" },
|
||||||
|
{ 0x18, "CE2" },
|
||||||
|
{ 0x19, "XV" },
|
||||||
|
{ 0x1a, "MMU_NB" },
|
||||||
|
{ 0x1b, "NVENC0" },
|
||||||
|
{ 0x1c, "DFALCON" },
|
||||||
|
{ 0x1d, "SKED" },
|
||||||
|
{ 0x1e, "AFALCON" },
|
||||||
|
{ 0x1f, "DONT_CARE" },
|
||||||
|
{ 0x20, "HSCE0" },
|
||||||
|
{ 0x21, "HSCE1" },
|
||||||
|
{ 0x22, "HSCE2" },
|
||||||
|
{ 0x23, "HSCE3" },
|
||||||
|
{ 0x24, "HSCE4" },
|
||||||
|
{ 0x25, "HSCE5" },
|
||||||
|
{ 0x26, "HSCE6" },
|
||||||
|
{ 0x27, "HSCE7" },
|
||||||
|
{ 0x28, "HSCE8" },
|
||||||
|
{ 0x29, "HSCE9" },
|
||||||
|
{ 0x2a, "HSHUB" },
|
||||||
|
{ 0x2b, "PTP_X0" },
|
||||||
|
{ 0x2c, "PTP_X1" },
|
||||||
|
{ 0x2d, "PTP_X2" },
|
||||||
|
{ 0x2e, "PTP_X3" },
|
||||||
|
{ 0x2f, "PTP_X4" },
|
||||||
|
{ 0x30, "PTP_X5" },
|
||||||
|
{ 0x31, "PTP_X6" },
|
||||||
|
{ 0x32, "PTP_X7" },
|
||||||
|
{ 0x33, "NVENC2" },
|
||||||
|
{ 0x34, "VPR_SCRUBBER0" },
|
||||||
|
{ 0x35, "VPR_SCRUBBER1" },
|
||||||
|
{ 0x36, "DWBIF" },
|
||||||
|
{ 0x37, "FBFALCON" },
|
||||||
|
{ 0x38, "CE_SHIM" },
|
||||||
|
{ 0x39, "GSP" },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct nvkm_enum
|
||||||
|
gv100_fifo_fault_reason[] = {
|
||||||
|
{ 0x00, "PDE" },
|
||||||
|
{ 0x01, "PDE_SIZE" },
|
||||||
|
{ 0x02, "PTE" },
|
||||||
|
{ 0x03, "VA_LIMIT_VIOLATION" },
|
||||||
|
{ 0x04, "UNBOUND_INST_BLOCK" },
|
||||||
|
{ 0x05, "PRIV_VIOLATION" },
|
||||||
|
{ 0x06, "RO_VIOLATION" },
|
||||||
|
{ 0x07, "WO_VIOLATION" },
|
||||||
|
{ 0x08, "PITCH_MASK_VIOLATION" },
|
||||||
|
{ 0x09, "WORK_CREATION" },
|
||||||
|
{ 0x0a, "UNSUPPORTED_APERTURE" },
|
||||||
|
{ 0x0b, "COMPRESSION_FAILURE" },
|
||||||
|
{ 0x0c, "UNSUPPORTED_KIND" },
|
||||||
|
{ 0x0d, "REGION_VIOLATION" },
|
||||||
|
{ 0x0e, "POISONED" },
|
||||||
|
{ 0x0f, "ATOMIC_VIOLATION" },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct nvkm_enum
|
||||||
|
gv100_fifo_fault_engine[] = {
|
||||||
|
{ 0x01, "DISPLAY" },
|
||||||
|
{ 0x03, "PTP" },
|
||||||
|
{ 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR },
|
||||||
|
{ 0x05, "BAR2", NULL, NVKM_SUBDEV_INSTMEM },
|
||||||
|
{ 0x06, "PWR_PMU" },
|
||||||
|
{ 0x08, "IFB", NULL, NVKM_ENGINE_IFB },
|
||||||
|
{ 0x09, "PERF" },
|
||||||
|
{ 0x1f, "PHYSICAL" },
|
||||||
|
{ 0x20, "HOST0" },
|
||||||
|
{ 0x21, "HOST1" },
|
||||||
|
{ 0x22, "HOST2" },
|
||||||
|
{ 0x23, "HOST3" },
|
||||||
|
{ 0x24, "HOST4" },
|
||||||
|
{ 0x25, "HOST5" },
|
||||||
|
{ 0x26, "HOST6" },
|
||||||
|
{ 0x27, "HOST7" },
|
||||||
|
{ 0x28, "HOST8" },
|
||||||
|
{ 0x29, "HOST9" },
|
||||||
|
{ 0x2a, "HOST10" },
|
||||||
|
{ 0x2b, "HOST11" },
|
||||||
|
{ 0x2c, "HOST12" },
|
||||||
|
{ 0x2d, "HOST13" },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct nvkm_enum
|
||||||
|
gv100_fifo_fault_access[] = {
|
||||||
|
{ 0x0, "VIRT_READ" },
|
||||||
|
{ 0x1, "VIRT_WRITE" },
|
||||||
|
{ 0x2, "VIRT_ATOMIC" },
|
||||||
|
{ 0x3, "VIRT_PREFETCH" },
|
||||||
|
{ 0x4, "VIRT_ATOMIC_WEAK" },
|
||||||
|
{ 0x8, "PHYS_READ" },
|
||||||
|
{ 0x9, "PHYS_WRITE" },
|
||||||
|
{ 0xa, "PHYS_ATOMIC" },
|
||||||
|
{ 0xb, "PHYS_PREFETCH" },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct gk104_fifo_func
|
||||||
|
gv100_fifo = {
|
||||||
|
.init_pbdma_timeout = gk208_fifo_init_pbdma_timeout,
|
||||||
|
.fault.access = gv100_fifo_fault_access,
|
||||||
|
.fault.engine = gv100_fifo_fault_engine,
|
||||||
|
.fault.reason = gv100_fifo_fault_reason,
|
||||||
|
.fault.hubclient = gv100_fifo_fault_hubclient,
|
||||||
|
.fault.gpcclient = gv100_fifo_fault_gpcclient,
|
||||||
|
.runlist = &gv100_fifo_runlist,
|
||||||
|
.user = {{-1,-1,VOLTA_USERMODE_A }, gv100_fifo_user_new },
|
||||||
|
.chan = {{ 0, 0,VOLTA_CHANNEL_GPFIFO_A}, gv100_fifo_gpfifo_new },
|
||||||
|
.cgrp_force = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
gv100_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
|
||||||
|
{
|
||||||
|
return gk104_fifo_new_(&gv100_fifo, device, index, 4096, pfifo);
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef __NVKM_FIFO_USER_H__
|
||||||
|
#define __NVKM_FIFO_USER_H__
|
||||||
|
#include "priv.h"
|
||||||
|
int gv100_fifo_user_new(const struct nvkm_oclass *, void *, u32,
|
||||||
|
struct nvkm_object **);
|
||||||
|
#endif
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#include "user.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
gv100_fifo_user_map(struct nvkm_object *object, void *argv, u32 argc,
|
||||||
|
enum nvkm_object_map *type, u64 *addr, u64 *size)
|
||||||
|
{
|
||||||
|
struct nvkm_device *device = object->engine->subdev.device;
|
||||||
|
*addr = 0x810000 + device->func->resource_addr(device, 0);
|
||||||
|
*size = 0x010000;
|
||||||
|
*type = NVKM_OBJECT_MAP_IO;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct nvkm_object_func
|
||||||
|
gv100_fifo_user = {
|
||||||
|
.map = gv100_fifo_user_map,
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
gv100_fifo_user_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
|
||||||
|
struct nvkm_object **pobject)
|
||||||
|
{
|
||||||
|
return nvkm_object_new_(&gv100_fifo_user, oclass, argv, argc, pobject);
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче