Commit 923f1ff5 authored by Ben Skeggs's avatar Ben Skeggs

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