drm/nouveau/fifo: move PBDMA intr to runq
- merges gf100/gk104- NV_PFIFO_INTR_0_PBDMA and NV_PPBDMA_INTR_0 code Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Reviewed-by: Lyude Paul <lyude@redhat.com>
This commit is contained in:
parent
87c8602431
commit
923f1ff527
@ -30,7 +30,6 @@
|
||||
#include "changf100.h"
|
||||
|
||||
#include <core/client.h>
|
||||
#include <core/enum.h>
|
||||
#include <core/gpuobj.h>
|
||||
#include <subdev/bar.h>
|
||||
#include <subdev/fault.h>
|
||||
@ -52,27 +51,28 @@ gf100_engn_sw = {
|
||||
};
|
||||
|
||||
static const struct nvkm_bitfield
|
||||
gf100_fifo_pbdma_intr[] = {
|
||||
gf100_runq_intr_0_names[] = {
|
||||
/* { 0x00008000, "" } seen with null ib push */
|
||||
{ 0x00200000, "ILLEGAL_MTHD" },
|
||||
{ 0x00800000, "EMPTY_SUBC" },
|
||||
{}
|
||||
};
|
||||
|
||||
static void
|
||||
gf100_fifo_intr_pbdma(struct gf100_fifo *fifo, int unit)
|
||||
bool
|
||||
gf100_runq_intr(struct nvkm_runq *runq, struct nvkm_runl *null)
|
||||
{
|
||||
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
|
||||
struct nvkm_subdev *subdev = &runq->fifo->engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
u32 stat = nvkm_rd32(device, 0x040108 + (unit * 0x2000));
|
||||
u32 addr = nvkm_rd32(device, 0x0400c0 + (unit * 0x2000));
|
||||
u32 data = nvkm_rd32(device, 0x0400c4 + (unit * 0x2000));
|
||||
u32 chid = nvkm_rd32(device, 0x040120 + (unit * 0x2000)) & 0x7f;
|
||||
u32 mask = nvkm_rd32(device, 0x04010c + (runq->id * 0x2000));
|
||||
u32 stat = nvkm_rd32(device, 0x040108 + (runq->id * 0x2000)) & mask;
|
||||
u32 addr = nvkm_rd32(device, 0x0400c0 + (runq->id * 0x2000));
|
||||
u32 data = nvkm_rd32(device, 0x0400c4 + (runq->id * 0x2000));
|
||||
u32 chid = nvkm_rd32(device, 0x040120 + (runq->id * 0x2000)) & runq->fifo->chid->mask;
|
||||
u32 subc = (addr & 0x00070000) >> 16;
|
||||
u32 mthd = (addr & 0x00003ffc);
|
||||
struct nvkm_fifo_chan *chan;
|
||||
unsigned long flags;
|
||||
u32 show = stat;
|
||||
struct nvkm_chan *chan;
|
||||
unsigned long flags;
|
||||
char msg[128];
|
||||
|
||||
if (stat & 0x00800000) {
|
||||
@ -83,18 +83,19 @@ gf100_fifo_intr_pbdma(struct gf100_fifo *fifo, int unit)
|
||||
}
|
||||
|
||||
if (show) {
|
||||
nvkm_snprintbf(msg, sizeof(msg), gf100_fifo_pbdma_intr, show);
|
||||
chan = nvkm_fifo_chan_chid(&fifo->base, chid, &flags);
|
||||
nvkm_snprintbf(msg, sizeof(msg), runq->func->intr_0_names, show);
|
||||
chan = nvkm_fifo_chan_chid(runq->fifo, chid, &flags);
|
||||
nvkm_error(subdev, "PBDMA%d: %08x [%s] ch %d [%010llx %s] "
|
||||
"subc %d mthd %04x data %08x\n",
|
||||
unit, show, msg, chid, chan ? chan->inst->addr : 0,
|
||||
runq->id, show, msg, chid, chan ? chan->inst->addr : 0,
|
||||
chan ? chan->object.client->name : "unknown",
|
||||
subc, mthd, data);
|
||||
nvkm_fifo_chan_put(&fifo->base, flags, &chan);
|
||||
nvkm_fifo_chan_put(runq->fifo, flags, &chan);
|
||||
}
|
||||
|
||||
nvkm_wr32(device, 0x0400c0 + (unit * 0x2000), 0x80600008);
|
||||
nvkm_wr32(device, 0x040108 + (unit * 0x2000), stat);
|
||||
nvkm_wr32(device, 0x0400c0 + (runq->id * 0x2000), 0x80600008);
|
||||
nvkm_wr32(device, 0x040108 + (runq->id * 0x2000), stat);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
@ -110,6 +111,8 @@ gf100_runq_init(struct nvkm_runq *runq)
|
||||
static const struct nvkm_runq_func
|
||||
gf100_runq = {
|
||||
.init = gf100_runq_init,
|
||||
.intr = gf100_runq_intr,
|
||||
.intr_0_names = gf100_runq_intr_0_names,
|
||||
};
|
||||
|
||||
void
|
||||
@ -495,6 +498,24 @@ gf100_fifo_intr_mmu_fault_unit(struct nvkm_fifo *fifo, int unit)
|
||||
nvkm_fifo_fault(fifo, &info);
|
||||
}
|
||||
|
||||
bool
|
||||
gf100_fifo_intr_pbdma(struct nvkm_fifo *fifo)
|
||||
{
|
||||
struct nvkm_device *device = fifo->engine.subdev.device;
|
||||
struct nvkm_runq *runq;
|
||||
u32 mask = nvkm_rd32(device, 0x0025a0);
|
||||
bool handled = false;
|
||||
|
||||
nvkm_runq_foreach_cond(runq, fifo, mask & BIT(runq->id)) {
|
||||
if (runq->func->intr(runq, NULL))
|
||||
handled = true;
|
||||
|
||||
nvkm_wr32(device, 0x0025a0, BIT(runq->id));
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
static void
|
||||
gf100_fifo_intr_runlist(struct gf100_fifo *fifo)
|
||||
{
|
||||
@ -599,14 +620,8 @@ gf100_fifo_intr(struct nvkm_inth *inth)
|
||||
}
|
||||
|
||||
if (stat & 0x20000000) {
|
||||
u32 mask = nvkm_rd32(device, 0x0025a0);
|
||||
while (mask) {
|
||||
u32 unit = __ffs(mask);
|
||||
gf100_fifo_intr_pbdma(gf100_fifo(fifo), unit);
|
||||
nvkm_wr32(device, 0x0025a0, (1 << unit));
|
||||
mask &= ~(1 << unit);
|
||||
}
|
||||
stat &= ~0x20000000;
|
||||
if (gf100_fifo_intr_pbdma(fifo))
|
||||
stat &= ~0x20000000;
|
||||
}
|
||||
|
||||
if (stat & 0x40000000) {
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include <subdev/mc.h>
|
||||
#include <subdev/timer.h>
|
||||
#include <subdev/top.h>
|
||||
#include <engine/sw.h>
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
@ -100,7 +99,8 @@ const struct nvkm_engn_func
|
||||
gk104_engn_ce = {
|
||||
};
|
||||
|
||||
static const struct nvkm_bitfield gk104_fifo_pbdma_intr_1[] = {
|
||||
static const struct nvkm_bitfield
|
||||
gk104_runq_intr_1_names[] = {
|
||||
{ 0x00000001, "HCE_RE_ILLEGAL_OP" },
|
||||
{ 0x00000002, "HCE_RE_ALIGNB" },
|
||||
{ 0x00000004, "HCE_PRIV" },
|
||||
@ -109,28 +109,30 @@ static const struct nvkm_bitfield gk104_fifo_pbdma_intr_1[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
void
|
||||
gk104_fifo_intr_pbdma_1(struct gk104_fifo *fifo, int unit)
|
||||
static bool
|
||||
gk104_runq_intr_1(struct nvkm_runq *runq)
|
||||
{
|
||||
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
|
||||
struct nvkm_subdev *subdev = &runq->fifo->engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
u32 mask = nvkm_rd32(device, 0x04014c + (unit * 0x2000));
|
||||
u32 stat = nvkm_rd32(device, 0x040148 + (unit * 0x2000)) & mask;
|
||||
u32 chid = nvkm_rd32(device, 0x040120 + (unit * 0x2000)) & 0xfff;
|
||||
u32 mask = nvkm_rd32(device, 0x04014c + (runq->id * 0x2000));
|
||||
u32 stat = nvkm_rd32(device, 0x040148 + (runq->id * 0x2000)) & mask;
|
||||
u32 chid = nvkm_rd32(device, 0x040120 + (runq->id * 0x2000)) & 0xfff;
|
||||
char msg[128];
|
||||
|
||||
if (stat) {
|
||||
nvkm_snprintbf(msg, sizeof(msg), gk104_fifo_pbdma_intr_1, stat);
|
||||
nvkm_snprintbf(msg, sizeof(msg), gk104_runq_intr_1_names, stat);
|
||||
nvkm_error(subdev, "PBDMA%d: %08x [%s] ch %d %08x %08x\n",
|
||||
unit, stat, msg, chid,
|
||||
nvkm_rd32(device, 0x040150 + (unit * 0x2000)),
|
||||
nvkm_rd32(device, 0x040154 + (unit * 0x2000)));
|
||||
runq->id, stat, msg, chid,
|
||||
nvkm_rd32(device, 0x040150 + (runq->id * 0x2000)),
|
||||
nvkm_rd32(device, 0x040154 + (runq->id * 0x2000)));
|
||||
}
|
||||
|
||||
nvkm_wr32(device, 0x040148 + (unit * 0x2000), stat);
|
||||
nvkm_wr32(device, 0x040148 + (runq->id * 0x2000), stat);
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct nvkm_bitfield gk104_fifo_pbdma_intr_0[] = {
|
||||
const struct nvkm_bitfield
|
||||
gk104_runq_intr_0_names[] = {
|
||||
{ 0x00000001, "MEMREQ" },
|
||||
{ 0x00000002, "MEMACK_TIMEOUT" },
|
||||
{ 0x00000004, "MEMACK_EXTRA" },
|
||||
@ -164,6 +166,15 @@ static const struct nvkm_bitfield gk104_fifo_pbdma_intr_0[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
bool
|
||||
gk104_runq_intr(struct nvkm_runq *runq, struct nvkm_runl *null)
|
||||
{
|
||||
bool intr0 = gf100_runq_intr(runq, NULL);
|
||||
bool intr1 = gk104_runq_intr_1(runq);
|
||||
|
||||
return intr0 || intr1;
|
||||
}
|
||||
|
||||
void
|
||||
gk104_runq_init(struct nvkm_runq *runq)
|
||||
{
|
||||
@ -184,6 +195,8 @@ gk104_runq_runm(struct nvkm_runq *runq)
|
||||
const struct nvkm_runq_func
|
||||
gk104_runq = {
|
||||
.init = gk104_runq_init,
|
||||
.intr = gk104_runq_intr,
|
||||
.intr_0_names = gk104_runq_intr_0_names,
|
||||
};
|
||||
|
||||
void
|
||||
@ -806,46 +819,6 @@ gk104_fifo_intr_dropped_fault(struct nvkm_fifo *fifo)
|
||||
nvkm_error(subdev, "DROPPED_MMU_FAULT %08x\n", stat);
|
||||
}
|
||||
|
||||
void
|
||||
gk104_fifo_intr_pbdma_0(struct gk104_fifo *fifo, int unit)
|
||||
{
|
||||
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
u32 mask = nvkm_rd32(device, 0x04010c + (unit * 0x2000));
|
||||
u32 stat = nvkm_rd32(device, 0x040108 + (unit * 0x2000)) & mask;
|
||||
u32 addr = nvkm_rd32(device, 0x0400c0 + (unit * 0x2000));
|
||||
u32 data = nvkm_rd32(device, 0x0400c4 + (unit * 0x2000));
|
||||
u32 chid = nvkm_rd32(device, 0x040120 + (unit * 0x2000)) & 0xfff;
|
||||
u32 subc = (addr & 0x00070000) >> 16;
|
||||
u32 mthd = (addr & 0x00003ffc);
|
||||
u32 show = stat;
|
||||
struct nvkm_fifo_chan *chan;
|
||||
unsigned long flags;
|
||||
char msg[128];
|
||||
|
||||
if (stat & 0x00800000) {
|
||||
if (device->sw) {
|
||||
if (nvkm_sw_mthd(device->sw, chid, subc, mthd, data))
|
||||
show &= ~0x00800000;
|
||||
}
|
||||
}
|
||||
|
||||
nvkm_wr32(device, 0x0400c0 + (unit * 0x2000), 0x80600008);
|
||||
|
||||
if (show) {
|
||||
nvkm_snprintbf(msg, sizeof(msg), gk104_fifo_pbdma_intr_0, show);
|
||||
chan = nvkm_fifo_chan_chid(&fifo->base, chid, &flags);
|
||||
nvkm_error(subdev, "PBDMA%d: %08x [%s] ch %d [%010llx %s] "
|
||||
"subc %d mthd %04x data %08x\n",
|
||||
unit, show, msg, chid, chan ? chan->inst->addr : 0,
|
||||
chan ? chan->object.client->name : "unknown",
|
||||
subc, mthd, data);
|
||||
nvkm_fifo_chan_put(&fifo->base, flags, &chan);
|
||||
}
|
||||
|
||||
nvkm_wr32(device, 0x040108 + (unit * 0x2000), stat);
|
||||
}
|
||||
|
||||
void
|
||||
gk104_fifo_intr_runlist(struct gk104_fifo *fifo)
|
||||
{
|
||||
@ -922,15 +895,8 @@ gk104_fifo_intr(struct nvkm_inth *inth)
|
||||
}
|
||||
|
||||
if (stat & 0x20000000) {
|
||||
u32 mask = nvkm_rd32(device, 0x0025a0);
|
||||
while (mask) {
|
||||
u32 unit = __ffs(mask);
|
||||
gk104_fifo_intr_pbdma_0(gk104_fifo(fifo), unit);
|
||||
gk104_fifo_intr_pbdma_1(gk104_fifo(fifo), unit);
|
||||
nvkm_wr32(device, 0x0025a0, (1 << unit));
|
||||
mask &= ~(1 << unit);
|
||||
}
|
||||
stat &= ~0x20000000;
|
||||
if (gf100_fifo_intr_pbdma(fifo))
|
||||
stat &= ~0x20000000;
|
||||
}
|
||||
|
||||
if (stat & 0x40000000) {
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include "priv.h"
|
||||
struct nvkm_fifo_cgrp;
|
||||
|
||||
#include <core/enum.h>
|
||||
#include <subdev/mmu.h>
|
||||
|
||||
#define gk104_fifo_func nvkm_fifo_func
|
||||
@ -64,8 +63,6 @@ void gk104_fifo_runlist_remove(struct gk104_fifo *, struct gk104_fifo_chan *);
|
||||
void gk104_fifo_runlist_update(struct gk104_fifo *, int runl);
|
||||
void gk104_fifo_engine_status(struct gk104_fifo *fifo, int engn,
|
||||
struct gk104_fifo_engine_status *status);
|
||||
void gk104_fifo_intr_pbdma_0(struct gk104_fifo *fifo, int unit);
|
||||
void gk104_fifo_intr_pbdma_1(struct gk104_fifo *fifo, int unit);
|
||||
void gk104_fifo_intr_runlist(struct gk104_fifo *fifo);
|
||||
void *gk104_fifo_dtor(struct nvkm_fifo *base);
|
||||
int gk104_fifo_oneinit(struct nvkm_fifo *);
|
||||
|
@ -38,6 +38,8 @@ gk208_runq_init(struct nvkm_runq *runq)
|
||||
const struct nvkm_runq_func
|
||||
gk208_runq = {
|
||||
.init = gk208_runq_init,
|
||||
.intr = gk104_runq_intr,
|
||||
.intr_0_names = gk104_runq_intr_0_names,
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -46,6 +46,8 @@ gv100_engn_ce = {
|
||||
const struct nvkm_runq_func
|
||||
gv100_runq = {
|
||||
.init = gk208_runq_init,
|
||||
.intr = gk104_runq_intr,
|
||||
.intr_0_names = gk104_runq_intr_0_names,
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -3,8 +3,10 @@
|
||||
#define __NVKM_FIFO_PRIV_H__
|
||||
#define nvkm_fifo(p) container_of((p), struct nvkm_fifo, engine)
|
||||
#include <engine/fifo.h>
|
||||
#include <core/enum.h>
|
||||
struct nvkm_cgrp;
|
||||
struct nvkm_memory;
|
||||
struct nvkm_runl;
|
||||
struct nvkm_runq;
|
||||
struct gk104_fifo;
|
||||
struct gk104_fifo_chan;
|
||||
@ -113,9 +115,11 @@ extern const struct nvkm_chan_func g84_chan;
|
||||
|
||||
int gf100_fifo_chid_ctor(struct nvkm_fifo *, int);
|
||||
int gf100_fifo_runq_nr(struct nvkm_fifo *);
|
||||
bool gf100_fifo_intr_pbdma(struct nvkm_fifo *);
|
||||
void gf100_fifo_intr_mmu_fault_unit(struct nvkm_fifo *, int);
|
||||
extern const struct nvkm_event_func gf100_fifo_nonstall;
|
||||
void gf100_runq_init(struct nvkm_runq *);
|
||||
bool gf100_runq_intr(struct nvkm_runq *, struct nvkm_runl *);
|
||||
extern const struct nvkm_engn_func gf100_engn_sw;
|
||||
|
||||
int gk104_fifo_chid_nr(struct nvkm_fifo *);
|
||||
@ -130,6 +134,8 @@ void gk104_fifo_recover_chan(struct nvkm_fifo *, int);
|
||||
int gk104_fifo_engine_id(struct nvkm_fifo *, struct nvkm_engine *);
|
||||
extern const struct nvkm_runq_func gk104_runq;
|
||||
void gk104_runq_init(struct nvkm_runq *);
|
||||
bool gk104_runq_intr(struct nvkm_runq *, struct nvkm_runl *);
|
||||
extern const struct nvkm_bitfield gk104_runq_intr_0_names[];
|
||||
extern const struct nvkm_engn_func gk104_engn;
|
||||
extern const struct nvkm_engn_func gk104_engn_ce;
|
||||
|
||||
|
@ -2,10 +2,13 @@
|
||||
#ifndef __NVKM_RUNQ_H__
|
||||
#define __NVKM_RUNQ_H__
|
||||
#include <core/os.h>
|
||||
struct nvkm_runl;
|
||||
|
||||
struct nvkm_runq {
|
||||
const struct nvkm_runq_func {
|
||||
void (*init)(struct nvkm_runq *);
|
||||
bool (*intr)(struct nvkm_runq *, struct nvkm_runl *);
|
||||
const struct nvkm_bitfield *intr_0_names;
|
||||
} *func;
|
||||
struct nvkm_fifo *fifo;
|
||||
int id;
|
||||
|
@ -395,17 +395,8 @@ tu102_fifo_intr(struct nvkm_inth *inth)
|
||||
}
|
||||
|
||||
if (stat & 0x20000000) {
|
||||
u32 mask = nvkm_rd32(device, 0x0025a0);
|
||||
|
||||
while (mask) {
|
||||
u32 unit = __ffs(mask);
|
||||
|
||||
gk104_fifo_intr_pbdma_0(gk104_fifo(fifo), unit);
|
||||
gk104_fifo_intr_pbdma_1(gk104_fifo(fifo), unit);
|
||||
nvkm_wr32(device, 0x0025a0, (1 << unit));
|
||||
mask &= ~(1 << unit);
|
||||
}
|
||||
stat &= ~0x20000000;
|
||||
if (gf100_fifo_intr_pbdma(fifo))
|
||||
stat &= ~0x20000000;
|
||||
}
|
||||
|
||||
if (stat & 0x40000000) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user