Commit fc10199e authored by Marcin Slusarz's avatar Marcin Slusarz Committed by Ben Skeggs

drm/nouveau: split fifo interrupt handler

Signed-off-by: default avatarMarcin Slusarz <marcin.slusarz@gmail.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 3600ad5e
...@@ -398,57 +398,36 @@ nv04_fifo_swmthd(struct nv04_fifo_priv *priv, u32 chid, u32 addr, u32 data) ...@@ -398,57 +398,36 @@ nv04_fifo_swmthd(struct nv04_fifo_priv *priv, u32 chid, u32 addr, u32 data)
return handled; return handled;
} }
void static void
nv04_fifo_intr(struct nouveau_subdev *subdev) nv04_fifo_cache_error(struct nouveau_device *device,
struct nv04_fifo_priv *priv, u32 chid, u32 get)
{ {
struct nouveau_device *device = nv_device(subdev); u32 mthd, data;
struct nv04_fifo_priv *priv = (void *)subdev;
uint32_t status, reassign;
int cnt = 0;
reassign = nv_rd32(priv, NV03_PFIFO_CACHES) & 1;
while ((status = nv_rd32(priv, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) {
uint32_t chid, get;
nv_wr32(priv, NV03_PFIFO_CACHES, 0);
chid = nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH1) & priv->base.max;
get = nv_rd32(priv, NV03_PFIFO_CACHE1_GET);
if (status & NV_PFIFO_INTR_CACHE_ERROR) {
uint32_t mthd, data;
int ptr; int ptr;
/* NV_PFIFO_CACHE1_GET actually goes to 0xffc before /* NV_PFIFO_CACHE1_GET actually goes to 0xffc before wrapping on my
* wrapping on my G80 chips, but CACHE1 isn't big * G80 chips, but CACHE1 isn't big enough for this much data.. Tests
* enough for this much data.. Tests show that it * show that it wraps around to the start at GET=0x800.. No clue as to
* wraps around to the start at GET=0x800.. No clue * why..
* as to why..
*/ */
ptr = (get & 0x7ff) >> 2; ptr = (get & 0x7ff) >> 2;
if (device->card_type < NV_40) { if (device->card_type < NV_40) {
mthd = nv_rd32(priv, mthd = nv_rd32(priv, NV04_PFIFO_CACHE1_METHOD(ptr));
NV04_PFIFO_CACHE1_METHOD(ptr)); data = nv_rd32(priv, NV04_PFIFO_CACHE1_DATA(ptr));
data = nv_rd32(priv,
NV04_PFIFO_CACHE1_DATA(ptr));
} else { } else {
mthd = nv_rd32(priv, mthd = nv_rd32(priv, NV40_PFIFO_CACHE1_METHOD(ptr));
NV40_PFIFO_CACHE1_METHOD(ptr)); data = nv_rd32(priv, NV40_PFIFO_CACHE1_DATA(ptr));
data = nv_rd32(priv,
NV40_PFIFO_CACHE1_DATA(ptr));
} }
if (!nv04_fifo_swmthd(priv, chid, mthd, data)) { if (!nv04_fifo_swmthd(priv, chid, mthd, data)) {
nv_error(priv, "CACHE_ERROR - Ch %d/%d " nv_error(priv,
"Mthd 0x%04x Data 0x%08x\n", "CACHE_ERROR - Ch %d/%d Mthd 0x%04x Data 0x%08x\n",
chid, (mthd >> 13) & 7, mthd & 0x1ffc, chid, (mthd >> 13) & 7, mthd & 0x1ffc, data);
data);
} }
nv_wr32(priv, NV04_PFIFO_CACHE1_DMA_PUSH, 0); nv_wr32(priv, NV04_PFIFO_CACHE1_DMA_PUSH, 0);
nv_wr32(priv, NV03_PFIFO_INTR_0, nv_wr32(priv, NV03_PFIFO_INTR_0, NV_PFIFO_INTR_CACHE_ERROR);
NV_PFIFO_INTR_CACHE_ERROR);
nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0, nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0,
nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH0) & ~1); nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH0) & ~1);
...@@ -460,11 +439,12 @@ nv04_fifo_intr(struct nouveau_subdev *subdev) ...@@ -460,11 +439,12 @@ nv04_fifo_intr(struct nouveau_subdev *subdev)
nv_wr32(priv, NV04_PFIFO_CACHE1_DMA_PUSH, nv_wr32(priv, NV04_PFIFO_CACHE1_DMA_PUSH,
nv_rd32(priv, NV04_PFIFO_CACHE1_DMA_PUSH) | 1); nv_rd32(priv, NV04_PFIFO_CACHE1_DMA_PUSH) | 1);
nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1); nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
}
status &= ~NV_PFIFO_INTR_CACHE_ERROR; static void
} nv04_fifo_dma_pusher(struct nouveau_device *device, struct nv04_fifo_priv *priv,
u32 chid)
if (status & NV_PFIFO_INTR_DMA_PUSHER) { {
u32 dma_get = nv_rd32(priv, 0x003244); u32 dma_get = nv_rd32(priv, 0x003244);
u32 dma_put = nv_rd32(priv, 0x003240); u32 dma_put = nv_rd32(priv, 0x003240);
u32 push = nv_rd32(priv, 0x003220); u32 push = nv_rd32(priv, 0x003220);
...@@ -476,13 +456,10 @@ nv04_fifo_intr(struct nouveau_subdev *subdev) ...@@ -476,13 +456,10 @@ nv04_fifo_intr(struct nouveau_subdev *subdev)
u32 ib_get = nv_rd32(priv, 0x003334); u32 ib_get = nv_rd32(priv, 0x003334);
u32 ib_put = nv_rd32(priv, 0x003330); u32 ib_put = nv_rd32(priv, 0x003330);
nv_error(priv, "DMA_PUSHER - Ch %d Get 0x%02x%08x " nv_error(priv,
"Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x " "DMA_PUSHER - Ch %d Get 0x%02x%08x Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x State 0x%08x (err: %s) Push 0x%08x\n",
"State 0x%08x (err: %s) Push 0x%08x\n", chid, ho_get, dma_get, ho_put, dma_put, ib_get, ib_put,
chid, ho_get, dma_get, ho_put, state, nv_dma_state_err(state), push);
dma_put, ib_get, ib_put, state,
nv_dma_state_err(state),
push);
/* METHOD_COUNT, in DMA_STATE on earlier chipsets */ /* METHOD_COUNT, in DMA_STATE on earlier chipsets */
nv_wr32(priv, 0x003364, 0x00000000); nv_wr32(priv, 0x003364, 0x00000000);
...@@ -490,14 +467,13 @@ nv04_fifo_intr(struct nouveau_subdev *subdev) ...@@ -490,14 +467,13 @@ nv04_fifo_intr(struct nouveau_subdev *subdev)
nv_wr32(priv, 0x003244, dma_put); nv_wr32(priv, 0x003244, dma_put);
nv_wr32(priv, 0x003328, ho_put); nv_wr32(priv, 0x003328, ho_put);
} else } else
if (ib_get != ib_put) { if (ib_get != ib_put)
nv_wr32(priv, 0x003334, ib_put); nv_wr32(priv, 0x003334, ib_put);
}
} else { } else {
nv_error(priv, "DMA_PUSHER - Ch %d Get 0x%08x " nv_error(priv,
"Put 0x%08x State 0x%08x (err: %s) Push 0x%08x\n", "DMA_PUSHER - Ch %d Get 0x%08x Put 0x%08x State 0x%08x (err: %s) Push 0x%08x\n",
chid, dma_get, dma_put, state, chid, dma_get, dma_put, state, nv_dma_state_err(state),
nv_dma_state_err(state), push); push);
if (dma_get != dma_put) if (dma_get != dma_put)
nv_wr32(priv, 0x003244, dma_put); nv_wr32(priv, 0x003244, dma_put);
...@@ -506,6 +482,32 @@ nv04_fifo_intr(struct nouveau_subdev *subdev) ...@@ -506,6 +482,32 @@ nv04_fifo_intr(struct nouveau_subdev *subdev)
nv_wr32(priv, 0x003228, 0x00000000); nv_wr32(priv, 0x003228, 0x00000000);
nv_wr32(priv, 0x003220, 0x00000001); nv_wr32(priv, 0x003220, 0x00000001);
nv_wr32(priv, 0x002100, NV_PFIFO_INTR_DMA_PUSHER); nv_wr32(priv, 0x002100, NV_PFIFO_INTR_DMA_PUSHER);
}
void
nv04_fifo_intr(struct nouveau_subdev *subdev)
{
struct nouveau_device *device = nv_device(subdev);
struct nv04_fifo_priv *priv = (void *)subdev;
uint32_t status, reassign;
int cnt = 0;
reassign = nv_rd32(priv, NV03_PFIFO_CACHES) & 1;
while ((status = nv_rd32(priv, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) {
uint32_t chid, get;
nv_wr32(priv, NV03_PFIFO_CACHES, 0);
chid = nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH1) & priv->base.max;
get = nv_rd32(priv, NV03_PFIFO_CACHE1_GET);
if (status & NV_PFIFO_INTR_CACHE_ERROR) {
nv04_fifo_cache_error(device, priv, chid, get);
status &= ~NV_PFIFO_INTR_CACHE_ERROR;
}
if (status & NV_PFIFO_INTR_DMA_PUSHER) {
nv04_fifo_dma_pusher(device, priv, chid);
status &= ~NV_PFIFO_INTR_DMA_PUSHER; status &= ~NV_PFIFO_INTR_DMA_PUSHER;
} }
......
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