drm/nouveau/vfn/tu102-: support new-style interrupt tree
- switches ampere over now, and removes its hack mc implementation Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Reviewed-by: Lyude Paul <lyude@redhat.com>
This commit is contained in:
parent
58c3d3c837
commit
e650738055
@ -12,6 +12,8 @@ struct nvkm_vfn {
|
||||
u32 user;
|
||||
} addr;
|
||||
|
||||
struct nvkm_intr intr;
|
||||
|
||||
struct nvkm_device_oclass user;
|
||||
};
|
||||
|
||||
|
@ -24,36 +24,23 @@
|
||||
static void
|
||||
ga100_mc_intr_unarm(struct nvkm_mc *mc)
|
||||
{
|
||||
nvkm_wr32(mc->subdev.device, 0xb81610, 0x00000004);
|
||||
}
|
||||
|
||||
static void
|
||||
ga100_mc_intr_rearm(struct nvkm_mc *mc)
|
||||
{
|
||||
nvkm_wr32(mc->subdev.device, 0xb81608, 0x00000004);
|
||||
}
|
||||
|
||||
static void
|
||||
ga100_mc_intr_mask(struct nvkm_mc *mc, u32 mask, u32 intr)
|
||||
{
|
||||
nvkm_wr32(mc->subdev.device, 0xb81210, mask & intr );
|
||||
nvkm_wr32(mc->subdev.device, 0xb81410, mask & ~(mask & intr));
|
||||
}
|
||||
|
||||
static u32
|
||||
ga100_mc_intr_stat(struct nvkm_mc *mc)
|
||||
{
|
||||
u32 intr_top = nvkm_rd32(mc->subdev.device, 0xb81600), intr = 0x00000000;
|
||||
if (intr_top & 0x00000004)
|
||||
intr = nvkm_mask(mc->subdev.device, 0xb81010, 0x00000000, 0x00000000);
|
||||
return intr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ga100_mc_init(struct nvkm_mc *mc)
|
||||
{
|
||||
nv50_mc_init(mc);
|
||||
nvkm_wr32(mc->subdev.device, 0xb81210, 0xffffffff);
|
||||
}
|
||||
|
||||
static const struct nvkm_mc_func
|
||||
@ -62,7 +49,6 @@ ga100_mc = {
|
||||
.intr = gp100_mc_intr,
|
||||
.intr_unarm = ga100_mc_intr_unarm,
|
||||
.intr_rearm = ga100_mc_intr_rearm,
|
||||
.intr_mask = ga100_mc_intr_mask,
|
||||
.intr_stat = ga100_mc_intr_stat,
|
||||
.reset = gk104_mc_reset,
|
||||
};
|
||||
|
@ -37,6 +37,7 @@ nvkm_vfn_new_(const struct nvkm_vfn_func *func, struct nvkm_device *device,
|
||||
enum nvkm_subdev_type type, int inst, u32 addr, struct nvkm_vfn **pvfn)
|
||||
{
|
||||
struct nvkm_vfn *vfn;
|
||||
int ret;
|
||||
|
||||
if (!(vfn = *pvfn = kzalloc(sizeof(*vfn), GFP_KERNEL)))
|
||||
return -ENOMEM;
|
||||
@ -46,6 +47,13 @@ nvkm_vfn_new_(const struct nvkm_vfn_func *func, struct nvkm_device *device,
|
||||
vfn->addr.priv = addr;
|
||||
vfn->addr.user = vfn->addr.priv + func->user.addr;
|
||||
|
||||
if (vfn->func->intr) {
|
||||
ret = nvkm_intr_add(vfn->func->intr, vfn->func->intrs,
|
||||
&vfn->subdev, 8, &vfn->intr);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
vfn->user.ctor = nvkm_uvfn_new;
|
||||
vfn->user.base = func->user.base;
|
||||
return 0;
|
||||
|
@ -23,8 +23,19 @@
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
static const struct nvkm_intr_data
|
||||
ga100_vfn_intrs[] = {
|
||||
{ NVKM_ENGINE_DISP , 0, 4, 0x04000000, true },
|
||||
{ NVKM_SUBDEV_GPIO , 0, 4, 0x00200000, true },
|
||||
{ NVKM_SUBDEV_I2C , 0, 4, 0x00200000, true },
|
||||
{ NVKM_SUBDEV_PRIVRING, 0, 4, 0x40000000, true },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_vfn_func
|
||||
ga100_vfn = {
|
||||
.intr = &tu102_vfn_intr,
|
||||
.intrs = ga100_vfn_intrs,
|
||||
.user = { 0x030000, 0x010000, { -1, -1, AMPERE_USERMODE_A } },
|
||||
};
|
||||
|
||||
|
@ -5,6 +5,9 @@
|
||||
#include <subdev/vfn.h>
|
||||
|
||||
struct nvkm_vfn_func {
|
||||
const struct nvkm_intr_func *intr;
|
||||
const struct nvkm_intr_data *intrs;
|
||||
|
||||
struct {
|
||||
u32 addr;
|
||||
u32 size;
|
||||
@ -15,6 +18,8 @@ struct nvkm_vfn_func {
|
||||
int nvkm_vfn_new_(const struct nvkm_vfn_func *, struct nvkm_device *, enum nvkm_subdev_type, int,
|
||||
u32 addr, struct nvkm_vfn **);
|
||||
|
||||
extern const struct nvkm_intr_func tu102_vfn_intr;
|
||||
|
||||
int nvkm_uvfn_new(struct nvkm_device *, const struct nvkm_oclass *, void *, u32,
|
||||
struct nvkm_object **);
|
||||
#endif
|
||||
|
@ -23,8 +23,80 @@
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
static void
|
||||
tu102_vfn_intr_reset(struct nvkm_intr *intr, int leaf, u32 mask)
|
||||
{
|
||||
struct nvkm_vfn *vfn = container_of(intr, typeof(*vfn), intr);
|
||||
|
||||
nvkm_wr32(vfn->subdev.device, vfn->addr.priv + 0x1000 + (leaf * 4), mask);
|
||||
}
|
||||
|
||||
static void
|
||||
tu102_vfn_intr_allow(struct nvkm_intr *intr, int leaf, u32 mask)
|
||||
{
|
||||
struct nvkm_vfn *vfn = container_of(intr, typeof(*vfn), intr);
|
||||
|
||||
nvkm_wr32(vfn->subdev.device, vfn->addr.priv + 0x1200 + (leaf * 4), mask);
|
||||
}
|
||||
|
||||
static void
|
||||
tu102_vfn_intr_block(struct nvkm_intr *intr, int leaf, u32 mask)
|
||||
{
|
||||
struct nvkm_vfn *vfn = container_of(intr, typeof(*vfn), intr);
|
||||
|
||||
nvkm_wr32(vfn->subdev.device, vfn->addr.priv + 0x1400 + (leaf * 4), mask);
|
||||
}
|
||||
|
||||
static void
|
||||
tu102_vfn_intr_rearm(struct nvkm_intr *intr)
|
||||
{
|
||||
struct nvkm_vfn *vfn = container_of(intr, typeof(*vfn), intr);
|
||||
|
||||
nvkm_wr32(vfn->subdev.device, vfn->addr.priv + 0x1608, 0x0000000f);
|
||||
}
|
||||
|
||||
static void
|
||||
tu102_vfn_intr_unarm(struct nvkm_intr *intr)
|
||||
{
|
||||
struct nvkm_vfn *vfn = container_of(intr, typeof(*vfn), intr);
|
||||
|
||||
nvkm_wr32(vfn->subdev.device, vfn->addr.priv + 0x1610, 0x0000000f);
|
||||
}
|
||||
|
||||
static bool
|
||||
tu102_vfn_intr_pending(struct nvkm_intr *intr)
|
||||
{
|
||||
struct nvkm_vfn *vfn = container_of(intr, typeof(*vfn), intr);
|
||||
struct nvkm_device *device = vfn->subdev.device;
|
||||
u32 intr_top = nvkm_rd32(device, vfn->addr.priv + 0x1600);
|
||||
int pending = 0, leaf;
|
||||
|
||||
for (leaf = 0; leaf < 8; leaf++) {
|
||||
if (intr_top & BIT(leaf / 2)) {
|
||||
intr->stat[leaf] = nvkm_rd32(device, vfn->addr.priv + 0x1000 + (leaf * 4));
|
||||
if (intr->stat[leaf])
|
||||
pending++;
|
||||
} else {
|
||||
intr->stat[leaf] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return pending != 0;
|
||||
}
|
||||
|
||||
const struct nvkm_intr_func
|
||||
tu102_vfn_intr = {
|
||||
.pending = tu102_vfn_intr_pending,
|
||||
.unarm = tu102_vfn_intr_unarm,
|
||||
.rearm = tu102_vfn_intr_rearm,
|
||||
.block = tu102_vfn_intr_block,
|
||||
.allow = tu102_vfn_intr_allow,
|
||||
.reset = tu102_vfn_intr_reset,
|
||||
};
|
||||
|
||||
static const struct nvkm_vfn_func
|
||||
tu102_vfn = {
|
||||
.intr = &tu102_vfn_intr,
|
||||
.user = { 0x030000, 0x010000, { -1, -1, TURING_USERMODE_A } },
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user