Commit d4c4cc83 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/mc: abstract interface to master intr registers

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 0a34fb31
...@@ -10,6 +10,9 @@ struct nvkm_mc { ...@@ -10,6 +10,9 @@ struct nvkm_mc {
bool use_msi; bool use_msi;
}; };
void nvkm_mc_intr_unarm(struct nvkm_mc *);
void nvkm_mc_intr_rearm(struct nvkm_mc *);
u32 nvkm_mc_intr_mask(struct nvkm_mc *);
void nvkm_mc_unk260(struct nvkm_mc *, u32 data); void nvkm_mc_unk260(struct nvkm_mc *, u32 data);
int nv04_mc_new(struct nvkm_device *, int, struct nvkm_mc **); int nv04_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
......
...@@ -32,13 +32,24 @@ nvkm_mc_unk260(struct nvkm_mc *mc, u32 data) ...@@ -32,13 +32,24 @@ nvkm_mc_unk260(struct nvkm_mc *mc, u32 data)
mc->func->unk260(mc, data); mc->func->unk260(mc, data);
} }
static inline u32 void
nvkm_mc_intr_unarm(struct nvkm_mc *mc)
{
return mc->func->intr_unarm(mc);
}
void
nvkm_mc_intr_rearm(struct nvkm_mc *mc)
{
return mc->func->intr_rearm(mc);
}
u32
nvkm_mc_intr_mask(struct nvkm_mc *mc) nvkm_mc_intr_mask(struct nvkm_mc *mc)
{ {
struct nvkm_device *device = mc->subdev.device; u32 intr = mc->func->intr_mask(mc);
u32 intr = nvkm_rd32(device, 0x000100); if (WARN_ON_ONCE(intr == 0xffffffff))
if (intr == 0xffffffff) /* likely fallen off the bus */ intr = 0; /* likely fallen off the bus */
intr = 0x00000000;
return intr; return intr;
} }
...@@ -52,8 +63,7 @@ nvkm_mc_intr(int irq, void *arg) ...@@ -52,8 +63,7 @@ nvkm_mc_intr(int irq, void *arg)
struct nvkm_subdev *unit; struct nvkm_subdev *unit;
u32 intr; u32 intr;
nvkm_wr32(device, 0x000140, 0x00000000); nvkm_mc_intr_unarm(mc);
nvkm_rd32(device, 0x000140);
intr = nvkm_mc_intr_mask(mc); intr = nvkm_mc_intr_mask(mc);
if (mc->use_msi) if (mc->use_msi)
mc->func->msi_rearm(mc); mc->func->msi_rearm(mc);
...@@ -74,14 +84,15 @@ nvkm_mc_intr(int irq, void *arg) ...@@ -74,14 +84,15 @@ nvkm_mc_intr(int irq, void *arg)
nvkm_error(subdev, "unknown intr %08x\n", stat); nvkm_error(subdev, "unknown intr %08x\n", stat);
} }
nvkm_wr32(device, 0x000140, 0x00000001); nvkm_mc_intr_rearm(mc);
return intr ? IRQ_HANDLED : IRQ_NONE; return intr ? IRQ_HANDLED : IRQ_NONE;
} }
static int static int
nvkm_mc_fini(struct nvkm_subdev *subdev, bool suspend) nvkm_mc_fini(struct nvkm_subdev *subdev, bool suspend)
{ {
nvkm_wr32(subdev->device, 0x000140, 0x00000000); struct nvkm_mc *mc = nvkm_mc(subdev);
nvkm_mc_intr_unarm(mc);
return 0; return 0;
} }
...@@ -96,10 +107,9 @@ static int ...@@ -96,10 +107,9 @@ static int
nvkm_mc_init(struct nvkm_subdev *subdev) nvkm_mc_init(struct nvkm_subdev *subdev)
{ {
struct nvkm_mc *mc = nvkm_mc(subdev); struct nvkm_mc *mc = nvkm_mc(subdev);
struct nvkm_device *device = mc->subdev.device;
if (mc->func->init) if (mc->func->init)
mc->func->init(mc); mc->func->init(mc);
nvkm_wr32(device, 0x000140, 0x00000001); nvkm_mc_intr_rearm(mc);
return 0; return 0;
} }
......
...@@ -27,6 +27,9 @@ static const struct nvkm_mc_func ...@@ -27,6 +27,9 @@ static const struct nvkm_mc_func
g94_mc = { g94_mc = {
.init = nv50_mc_init, .init = nv50_mc_init,
.intr = nv50_mc_intr, .intr = nv50_mc_intr,
.intr_unarm = nv04_mc_intr_unarm,
.intr_rearm = nv04_mc_intr_rearm,
.intr_mask = nv04_mc_intr_mask,
.msi_rearm = nv40_mc_msi_rearm, .msi_rearm = nv40_mc_msi_rearm,
}; };
......
...@@ -48,6 +48,9 @@ static const struct nvkm_mc_func ...@@ -48,6 +48,9 @@ static const struct nvkm_mc_func
g98_mc = { g98_mc = {
.init = nv50_mc_init, .init = nv50_mc_init,
.intr = g98_mc_intr, .intr = g98_mc_intr,
.intr_unarm = nv04_mc_intr_unarm,
.intr_rearm = nv04_mc_intr_rearm,
.intr_mask = nv04_mc_intr_mask,
.msi_rearm = nv40_mc_msi_rearm, .msi_rearm = nv40_mc_msi_rearm,
}; };
......
...@@ -64,6 +64,9 @@ static const struct nvkm_mc_func ...@@ -64,6 +64,9 @@ static const struct nvkm_mc_func
gf100_mc = { gf100_mc = {
.init = nv50_mc_init, .init = nv50_mc_init,
.intr = gf100_mc_intr, .intr = gf100_mc_intr,
.intr_unarm = nv04_mc_intr_unarm,
.intr_rearm = nv04_mc_intr_rearm,
.intr_mask = nv04_mc_intr_mask,
.msi_rearm = gf100_mc_msi_rearm, .msi_rearm = gf100_mc_msi_rearm,
.unk260 = gf100_mc_unk260, .unk260 = gf100_mc_unk260,
}; };
......
...@@ -27,6 +27,9 @@ static const struct nvkm_mc_func ...@@ -27,6 +27,9 @@ static const struct nvkm_mc_func
gf106_mc = { gf106_mc = {
.init = nv50_mc_init, .init = nv50_mc_init,
.intr = gf100_mc_intr, .intr = gf100_mc_intr,
.intr_unarm = nv04_mc_intr_unarm,
.intr_rearm = nv04_mc_intr_rearm,
.intr_mask = nv04_mc_intr_mask,
.msi_rearm = nv40_mc_msi_rearm, .msi_rearm = nv40_mc_msi_rearm,
.unk260 = gf100_mc_unk260, .unk260 = gf100_mc_unk260,
}; };
......
...@@ -27,6 +27,9 @@ static const struct nvkm_mc_func ...@@ -27,6 +27,9 @@ static const struct nvkm_mc_func
gk20a_mc = { gk20a_mc = {
.init = nv50_mc_init, .init = nv50_mc_init,
.intr = gf100_mc_intr, .intr = gf100_mc_intr,
.intr_unarm = nv04_mc_intr_unarm,
.intr_rearm = nv04_mc_intr_rearm,
.intr_mask = nv04_mc_intr_mask,
.msi_rearm = nv40_mc_msi_rearm, .msi_rearm = nv40_mc_msi_rearm,
}; };
......
...@@ -38,6 +38,27 @@ nv04_mc_intr[] = { ...@@ -38,6 +38,27 @@ nv04_mc_intr[] = {
{} {}
}; };
void
nv04_mc_intr_unarm(struct nvkm_mc *mc)
{
struct nvkm_device *device = mc->subdev.device;
nvkm_wr32(device, 0x000140, 0x00000000);
nvkm_rd32(device, 0x000140);
}
void
nv04_mc_intr_rearm(struct nvkm_mc *mc)
{
struct nvkm_device *device = mc->subdev.device;
nvkm_wr32(device, 0x000140, 0x00000001);
}
u32
nv04_mc_intr_mask(struct nvkm_mc *mc)
{
return nvkm_rd32(mc->subdev.device, 0x000100);
}
void void
nv04_mc_init(struct nvkm_mc *mc) nv04_mc_init(struct nvkm_mc *mc)
{ {
...@@ -50,6 +71,9 @@ static const struct nvkm_mc_func ...@@ -50,6 +71,9 @@ static const struct nvkm_mc_func
nv04_mc = { nv04_mc = {
.init = nv04_mc_init, .init = nv04_mc_init,
.intr = nv04_mc_intr, .intr = nv04_mc_intr,
.intr_unarm = nv04_mc_intr_unarm,
.intr_rearm = nv04_mc_intr_rearm,
.intr_mask = nv04_mc_intr_mask,
}; };
int int
......
...@@ -33,6 +33,9 @@ static const struct nvkm_mc_func ...@@ -33,6 +33,9 @@ static const struct nvkm_mc_func
nv40_mc = { nv40_mc = {
.init = nv04_mc_init, .init = nv04_mc_init,
.intr = nv04_mc_intr, .intr = nv04_mc_intr,
.intr_unarm = nv04_mc_intr_unarm,
.intr_rearm = nv04_mc_intr_rearm,
.intr_mask = nv04_mc_intr_mask,
.msi_rearm = nv40_mc_msi_rearm, .msi_rearm = nv40_mc_msi_rearm,
}; };
......
...@@ -41,6 +41,9 @@ static const struct nvkm_mc_func ...@@ -41,6 +41,9 @@ static const struct nvkm_mc_func
nv44_mc = { nv44_mc = {
.init = nv44_mc_init, .init = nv44_mc_init,
.intr = nv04_mc_intr, .intr = nv04_mc_intr,
.intr_unarm = nv04_mc_intr_unarm,
.intr_rearm = nv04_mc_intr_rearm,
.intr_mask = nv04_mc_intr_mask,
.msi_rearm = nv40_mc_msi_rearm, .msi_rearm = nv40_mc_msi_rearm,
}; };
......
...@@ -27,6 +27,9 @@ static const struct nvkm_mc_func ...@@ -27,6 +27,9 @@ static const struct nvkm_mc_func
nv4c_mc = { nv4c_mc = {
.init = nv44_mc_init, .init = nv44_mc_init,
.intr = nv04_mc_intr, .intr = nv04_mc_intr,
.intr_unarm = nv04_mc_intr_unarm,
.intr_rearm = nv04_mc_intr_rearm,
.intr_mask = nv04_mc_intr_mask,
}; };
int int
......
...@@ -59,6 +59,9 @@ static const struct nvkm_mc_func ...@@ -59,6 +59,9 @@ static const struct nvkm_mc_func
nv50_mc = { nv50_mc = {
.init = nv50_mc_init, .init = nv50_mc_init,
.intr = nv50_mc_intr, .intr = nv50_mc_intr,
.intr_unarm = nv04_mc_intr_unarm,
.intr_rearm = nv04_mc_intr_rearm,
.intr_mask = nv04_mc_intr_mask,
.msi_rearm = nv50_mc_msi_rearm, .msi_rearm = nv50_mc_msi_rearm,
}; };
......
...@@ -14,12 +14,21 @@ struct nvkm_mc_intr { ...@@ -14,12 +14,21 @@ struct nvkm_mc_intr {
struct nvkm_mc_func { struct nvkm_mc_func {
void (*init)(struct nvkm_mc *); void (*init)(struct nvkm_mc *);
const struct nvkm_mc_intr *intr; const struct nvkm_mc_intr *intr;
/* disable reporting of interrupts to host */
void (*intr_unarm)(struct nvkm_mc *);
/* enable reporting of interrupts to host */
void (*intr_rearm)(struct nvkm_mc *);
/* retrieve pending interrupt mask (NV_PMC_INTR) */
u32 (*intr_mask)(struct nvkm_mc *);
void (*msi_rearm)(struct nvkm_mc *); void (*msi_rearm)(struct nvkm_mc *);
void (*unk260)(struct nvkm_mc *, u32); void (*unk260)(struct nvkm_mc *, u32);
}; };
void nv04_mc_init(struct nvkm_mc *); void nv04_mc_init(struct nvkm_mc *);
extern const struct nvkm_mc_intr nv04_mc_intr[]; extern const struct nvkm_mc_intr nv04_mc_intr[];
void nv04_mc_intr_unarm(struct nvkm_mc *);
void nv04_mc_intr_rearm(struct nvkm_mc *);
u32 nv04_mc_intr_mask(struct nvkm_mc *);
void nv40_mc_msi_rearm(struct nvkm_mc *); void nv40_mc_msi_rearm(struct nvkm_mc *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment