dect
/
linux-2.6
Archived
13
0
Fork 0

drm/nv10: Fix up switching of NV10TCL_DMA_VTXBUF.

Not very nice, but I don't think there's a simpler workaround.

Signed-off-by: Francisco Jerez <currojerez@riseup.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Francisco Jerez 2010-08-04 04:54:08 +02:00 committed by Ben Skeggs
parent 308dcebac7
commit d2f4e89254
2 changed files with 132 additions and 61 deletions

View File

@ -220,28 +220,21 @@
# define NV_PGRAPH_INTR_ERROR (1<<20)
#define NV10_PGRAPH_CTX_CONTROL 0x00400144
#define NV10_PGRAPH_CTX_USER 0x00400148
#define NV10_PGRAPH_CTX_SWITCH1 0x0040014C
#define NV10_PGRAPH_CTX_SWITCH2 0x00400150
#define NV10_PGRAPH_CTX_SWITCH3 0x00400154
#define NV10_PGRAPH_CTX_SWITCH4 0x00400158
#define NV10_PGRAPH_CTX_SWITCH5 0x0040015C
#define NV10_PGRAPH_CTX_SWITCH(i) (0x0040014C + 0x4*(i))
#define NV04_PGRAPH_CTX_SWITCH1 0x00400160
#define NV10_PGRAPH_CTX_CACHE1 0x00400160
#define NV10_PGRAPH_CTX_CACHE(i, j) (0x00400160 \
+ 0x4*(i) + 0x20*(j))
#define NV04_PGRAPH_CTX_SWITCH2 0x00400164
#define NV04_PGRAPH_CTX_SWITCH3 0x00400168
#define NV04_PGRAPH_CTX_SWITCH4 0x0040016C
#define NV04_PGRAPH_CTX_CONTROL 0x00400170
#define NV04_PGRAPH_CTX_USER 0x00400174
#define NV04_PGRAPH_CTX_CACHE1 0x00400180
#define NV10_PGRAPH_CTX_CACHE2 0x00400180
#define NV03_PGRAPH_CTX_CONTROL 0x00400190
#define NV03_PGRAPH_CTX_USER 0x00400194
#define NV04_PGRAPH_CTX_CACHE2 0x004001A0
#define NV10_PGRAPH_CTX_CACHE3 0x004001A0
#define NV04_PGRAPH_CTX_CACHE3 0x004001C0
#define NV10_PGRAPH_CTX_CACHE4 0x004001C0
#define NV04_PGRAPH_CTX_CACHE4 0x004001E0
#define NV10_PGRAPH_CTX_CACHE5 0x004001E0
#define NV40_PGRAPH_CTXCTL_0304 0x00400304
#define NV40_PGRAPH_CTXCTL_0304_XFER_CTX 0x00000001
#define NV40_PGRAPH_CTXCTL_UCODE_STAT 0x00400308
@ -356,9 +349,12 @@
#define NV04_PGRAPH_FFINTFC_ST2 0x00400754
#define NV10_PGRAPH_RDI_DATA 0x00400754
#define NV04_PGRAPH_DMA_PITCH 0x00400760
#define NV10_PGRAPH_FFINTFC_ST2 0x00400764
#define NV10_PGRAPH_FFINTFC_FIFO_PTR 0x00400760
#define NV04_PGRAPH_DVD_COLORFMT 0x00400764
#define NV10_PGRAPH_FFINTFC_ST2 0x00400764
#define NV04_PGRAPH_SCALED_FORMAT 0x00400768
#define NV10_PGRAPH_FFINTFC_ST2_DL 0x00400768
#define NV10_PGRAPH_FFINTFC_ST2_DH 0x0040076c
#define NV10_PGRAPH_DMA_PITCH 0x00400770
#define NV10_PGRAPH_DVD_COLORFMT 0x00400774
#define NV10_PGRAPH_SCALED_FORMAT 0x00400778

View File

@ -43,51 +43,51 @@ struct pipe_state {
};
static int nv10_graph_ctx_regs[] = {
NV10_PGRAPH_CTX_SWITCH1,
NV10_PGRAPH_CTX_SWITCH2,
NV10_PGRAPH_CTX_SWITCH3,
NV10_PGRAPH_CTX_SWITCH4,
NV10_PGRAPH_CTX_SWITCH5,
NV10_PGRAPH_CTX_CACHE1, /* 8 values from 0x400160 to 0x40017c */
NV10_PGRAPH_CTX_CACHE2, /* 8 values from 0x400180 to 0x40019c */
NV10_PGRAPH_CTX_CACHE3, /* 8 values from 0x4001a0 to 0x4001bc */
NV10_PGRAPH_CTX_CACHE4, /* 8 values from 0x4001c0 to 0x4001dc */
NV10_PGRAPH_CTX_CACHE5, /* 8 values from 0x4001e0 to 0x4001fc */
0x00400164,
0x00400184,
0x004001a4,
0x004001c4,
0x004001e4,
0x00400168,
0x00400188,
0x004001a8,
0x004001c8,
0x004001e8,
0x0040016c,
0x0040018c,
0x004001ac,
0x004001cc,
0x004001ec,
0x00400170,
0x00400190,
0x004001b0,
0x004001d0,
0x004001f0,
0x00400174,
0x00400194,
0x004001b4,
0x004001d4,
0x004001f4,
0x00400178,
0x00400198,
0x004001b8,
0x004001d8,
0x004001f8,
0x0040017c,
0x0040019c,
0x004001bc,
0x004001dc,
0x004001fc,
NV10_PGRAPH_CTX_SWITCH(0),
NV10_PGRAPH_CTX_SWITCH(1),
NV10_PGRAPH_CTX_SWITCH(2),
NV10_PGRAPH_CTX_SWITCH(3),
NV10_PGRAPH_CTX_SWITCH(4),
NV10_PGRAPH_CTX_CACHE(0, 0),
NV10_PGRAPH_CTX_CACHE(0, 1),
NV10_PGRAPH_CTX_CACHE(0, 2),
NV10_PGRAPH_CTX_CACHE(0, 3),
NV10_PGRAPH_CTX_CACHE(0, 4),
NV10_PGRAPH_CTX_CACHE(1, 0),
NV10_PGRAPH_CTX_CACHE(1, 1),
NV10_PGRAPH_CTX_CACHE(1, 2),
NV10_PGRAPH_CTX_CACHE(1, 3),
NV10_PGRAPH_CTX_CACHE(1, 4),
NV10_PGRAPH_CTX_CACHE(2, 0),
NV10_PGRAPH_CTX_CACHE(2, 1),
NV10_PGRAPH_CTX_CACHE(2, 2),
NV10_PGRAPH_CTX_CACHE(2, 3),
NV10_PGRAPH_CTX_CACHE(2, 4),
NV10_PGRAPH_CTX_CACHE(3, 0),
NV10_PGRAPH_CTX_CACHE(3, 1),
NV10_PGRAPH_CTX_CACHE(3, 2),
NV10_PGRAPH_CTX_CACHE(3, 3),
NV10_PGRAPH_CTX_CACHE(3, 4),
NV10_PGRAPH_CTX_CACHE(4, 0),
NV10_PGRAPH_CTX_CACHE(4, 1),
NV10_PGRAPH_CTX_CACHE(4, 2),
NV10_PGRAPH_CTX_CACHE(4, 3),
NV10_PGRAPH_CTX_CACHE(4, 4),
NV10_PGRAPH_CTX_CACHE(5, 0),
NV10_PGRAPH_CTX_CACHE(5, 1),
NV10_PGRAPH_CTX_CACHE(5, 2),
NV10_PGRAPH_CTX_CACHE(5, 3),
NV10_PGRAPH_CTX_CACHE(5, 4),
NV10_PGRAPH_CTX_CACHE(6, 0),
NV10_PGRAPH_CTX_CACHE(6, 1),
NV10_PGRAPH_CTX_CACHE(6, 2),
NV10_PGRAPH_CTX_CACHE(6, 3),
NV10_PGRAPH_CTX_CACHE(6, 4),
NV10_PGRAPH_CTX_CACHE(7, 0),
NV10_PGRAPH_CTX_CACHE(7, 1),
NV10_PGRAPH_CTX_CACHE(7, 2),
NV10_PGRAPH_CTX_CACHE(7, 3),
NV10_PGRAPH_CTX_CACHE(7, 4),
NV10_PGRAPH_CTX_USER,
NV04_PGRAPH_DMA_START_0,
NV04_PGRAPH_DMA_START_1,
@ -653,6 +653,78 @@ static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
return -1;
}
static void nv10_graph_load_dma_vtxbuf(struct nouveau_channel *chan,
uint32_t inst)
{
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
uint32_t st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4];
uint32_t ctx_user, ctx_switch[5];
int i, subchan = -1;
/* NV10TCL_DMA_VTXBUF (method 0x18c) modifies hidden state
* that cannot be restored via MMIO. Do it through the FIFO
* instead.
*/
/* Look for a celsius object */
for (i = 0; i < 8; i++) {
int class = nv_rd32(dev, NV10_PGRAPH_CTX_CACHE(i, 0)) & 0xfff;
if (class == 0x56 || class == 0x96 || class == 0x99) {
subchan = i;
break;
}
}
if (subchan < 0 || !inst)
return;
/* Save the current ctx object */
ctx_user = nv_rd32(dev, NV10_PGRAPH_CTX_USER);
for (i = 0; i < 5; i++)
ctx_switch[i] = nv_rd32(dev, NV10_PGRAPH_CTX_SWITCH(i));
/* Save the FIFO state */
st2 = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2);
st2_dl = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2_DL);
st2_dh = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2_DH);
fifo_ptr = nv_rd32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR);
for (i = 0; i < ARRAY_SIZE(fifo); i++)
fifo[i] = nv_rd32(dev, 0x4007a0 + 4 * i);
/* Switch to the celsius subchannel */
for (i = 0; i < 5; i++)
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(i),
nv_rd32(dev, NV10_PGRAPH_CTX_CACHE(subchan, i)));
nv_mask(dev, NV10_PGRAPH_CTX_USER, 0xe000, subchan << 13);
/* Inject NV10TCL_DMA_VTXBUF */
nv_wr32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR, 0);
nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2,
0x2c000000 | chan->id << 20 | subchan << 16 | 0x18c);
nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, inst);
nv_mask(dev, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000);
pgraph->fifo_access(dev, true);
pgraph->fifo_access(dev, false);
/* Restore the FIFO state */
for (i = 0; i < ARRAY_SIZE(fifo); i++)
nv_wr32(dev, 0x4007a0 + 4 * i, fifo[i]);
nv_wr32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR, fifo_ptr);
nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, st2);
nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, st2_dl);
nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DH, st2_dh);
/* Restore the current ctx object */
for (i = 0; i < 5; i++)
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(i), ctx_switch[i]);
nv_wr32(dev, NV10_PGRAPH_CTX_USER, ctx_user);
}
int nv10_graph_load_context(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->dev;
@ -670,6 +742,8 @@ int nv10_graph_load_context(struct nouveau_channel *chan)
}
nv10_graph_load_pipe(chan);
nv10_graph_load_dma_vtxbuf(chan, (nv_rd32(dev, NV10_PGRAPH_GLOBALSTATE1)
& 0xffff));
nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER);
@ -856,11 +930,12 @@ int nv10_graph_init(struct drm_device *dev)
for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
nv10_graph_set_region_tiling(dev, i, 0, 0, 0);
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH1, 0x00000000);
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH2, 0x00000000);
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH3, 0x00000000);
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH4, 0x00000000);
nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF);
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(0), 0x00000000);
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000);
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(2), 0x00000000);
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(3), 0x00000000);
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(4), 0x00000000);
nv_wr32(dev, NV10_PGRAPH_STATE, 0xFFFFFFFF);
tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
tmp |= (dev_priv->engine.fifo.channels - 1) << 24;