提交 d2f4e892 编写于 作者: F Francisco Jerez 提交者: Ben Skeggs

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: NFrancisco Jerez <currojerez@riseup.net>
Signed-off-by: NBen Skeggs <bskeggs@redhat.com>
上级 308dceba
...@@ -220,28 +220,21 @@ ...@@ -220,28 +220,21 @@
# define NV_PGRAPH_INTR_ERROR (1<<20) # define NV_PGRAPH_INTR_ERROR (1<<20)
#define NV10_PGRAPH_CTX_CONTROL 0x00400144 #define NV10_PGRAPH_CTX_CONTROL 0x00400144
#define NV10_PGRAPH_CTX_USER 0x00400148 #define NV10_PGRAPH_CTX_USER 0x00400148
#define NV10_PGRAPH_CTX_SWITCH1 0x0040014C #define NV10_PGRAPH_CTX_SWITCH(i) (0x0040014C + 0x4*(i))
#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 NV04_PGRAPH_CTX_SWITCH1 0x00400160 #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_SWITCH2 0x00400164
#define NV04_PGRAPH_CTX_SWITCH3 0x00400168 #define NV04_PGRAPH_CTX_SWITCH3 0x00400168
#define NV04_PGRAPH_CTX_SWITCH4 0x0040016C #define NV04_PGRAPH_CTX_SWITCH4 0x0040016C
#define NV04_PGRAPH_CTX_CONTROL 0x00400170 #define NV04_PGRAPH_CTX_CONTROL 0x00400170
#define NV04_PGRAPH_CTX_USER 0x00400174 #define NV04_PGRAPH_CTX_USER 0x00400174
#define NV04_PGRAPH_CTX_CACHE1 0x00400180 #define NV04_PGRAPH_CTX_CACHE1 0x00400180
#define NV10_PGRAPH_CTX_CACHE2 0x00400180
#define NV03_PGRAPH_CTX_CONTROL 0x00400190 #define NV03_PGRAPH_CTX_CONTROL 0x00400190
#define NV03_PGRAPH_CTX_USER 0x00400194 #define NV03_PGRAPH_CTX_USER 0x00400194
#define NV04_PGRAPH_CTX_CACHE2 0x004001A0 #define NV04_PGRAPH_CTX_CACHE2 0x004001A0
#define NV10_PGRAPH_CTX_CACHE3 0x004001A0
#define NV04_PGRAPH_CTX_CACHE3 0x004001C0 #define NV04_PGRAPH_CTX_CACHE3 0x004001C0
#define NV10_PGRAPH_CTX_CACHE4 0x004001C0
#define NV04_PGRAPH_CTX_CACHE4 0x004001E0 #define NV04_PGRAPH_CTX_CACHE4 0x004001E0
#define NV10_PGRAPH_CTX_CACHE5 0x004001E0
#define NV40_PGRAPH_CTXCTL_0304 0x00400304 #define NV40_PGRAPH_CTXCTL_0304 0x00400304
#define NV40_PGRAPH_CTXCTL_0304_XFER_CTX 0x00000001 #define NV40_PGRAPH_CTXCTL_0304_XFER_CTX 0x00000001
#define NV40_PGRAPH_CTXCTL_UCODE_STAT 0x00400308 #define NV40_PGRAPH_CTXCTL_UCODE_STAT 0x00400308
...@@ -356,9 +349,12 @@ ...@@ -356,9 +349,12 @@
#define NV04_PGRAPH_FFINTFC_ST2 0x00400754 #define NV04_PGRAPH_FFINTFC_ST2 0x00400754
#define NV10_PGRAPH_RDI_DATA 0x00400754 #define NV10_PGRAPH_RDI_DATA 0x00400754
#define NV04_PGRAPH_DMA_PITCH 0x00400760 #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 NV04_PGRAPH_DVD_COLORFMT 0x00400764
#define NV10_PGRAPH_FFINTFC_ST2 0x00400764
#define NV04_PGRAPH_SCALED_FORMAT 0x00400768 #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_DMA_PITCH 0x00400770
#define NV10_PGRAPH_DVD_COLORFMT 0x00400774 #define NV10_PGRAPH_DVD_COLORFMT 0x00400774
#define NV10_PGRAPH_SCALED_FORMAT 0x00400778 #define NV10_PGRAPH_SCALED_FORMAT 0x00400778
......
...@@ -43,51 +43,51 @@ struct pipe_state { ...@@ -43,51 +43,51 @@ struct pipe_state {
}; };
static int nv10_graph_ctx_regs[] = { static int nv10_graph_ctx_regs[] = {
NV10_PGRAPH_CTX_SWITCH1, NV10_PGRAPH_CTX_SWITCH(0),
NV10_PGRAPH_CTX_SWITCH2, NV10_PGRAPH_CTX_SWITCH(1),
NV10_PGRAPH_CTX_SWITCH3, NV10_PGRAPH_CTX_SWITCH(2),
NV10_PGRAPH_CTX_SWITCH4, NV10_PGRAPH_CTX_SWITCH(3),
NV10_PGRAPH_CTX_SWITCH5, NV10_PGRAPH_CTX_SWITCH(4),
NV10_PGRAPH_CTX_CACHE1, /* 8 values from 0x400160 to 0x40017c */ NV10_PGRAPH_CTX_CACHE(0, 0),
NV10_PGRAPH_CTX_CACHE2, /* 8 values from 0x400180 to 0x40019c */ NV10_PGRAPH_CTX_CACHE(0, 1),
NV10_PGRAPH_CTX_CACHE3, /* 8 values from 0x4001a0 to 0x4001bc */ NV10_PGRAPH_CTX_CACHE(0, 2),
NV10_PGRAPH_CTX_CACHE4, /* 8 values from 0x4001c0 to 0x4001dc */ NV10_PGRAPH_CTX_CACHE(0, 3),
NV10_PGRAPH_CTX_CACHE5, /* 8 values from 0x4001e0 to 0x4001fc */ NV10_PGRAPH_CTX_CACHE(0, 4),
0x00400164, NV10_PGRAPH_CTX_CACHE(1, 0),
0x00400184, NV10_PGRAPH_CTX_CACHE(1, 1),
0x004001a4, NV10_PGRAPH_CTX_CACHE(1, 2),
0x004001c4, NV10_PGRAPH_CTX_CACHE(1, 3),
0x004001e4, NV10_PGRAPH_CTX_CACHE(1, 4),
0x00400168, NV10_PGRAPH_CTX_CACHE(2, 0),
0x00400188, NV10_PGRAPH_CTX_CACHE(2, 1),
0x004001a8, NV10_PGRAPH_CTX_CACHE(2, 2),
0x004001c8, NV10_PGRAPH_CTX_CACHE(2, 3),
0x004001e8, NV10_PGRAPH_CTX_CACHE(2, 4),
0x0040016c, NV10_PGRAPH_CTX_CACHE(3, 0),
0x0040018c, NV10_PGRAPH_CTX_CACHE(3, 1),
0x004001ac, NV10_PGRAPH_CTX_CACHE(3, 2),
0x004001cc, NV10_PGRAPH_CTX_CACHE(3, 3),
0x004001ec, NV10_PGRAPH_CTX_CACHE(3, 4),
0x00400170, NV10_PGRAPH_CTX_CACHE(4, 0),
0x00400190, NV10_PGRAPH_CTX_CACHE(4, 1),
0x004001b0, NV10_PGRAPH_CTX_CACHE(4, 2),
0x004001d0, NV10_PGRAPH_CTX_CACHE(4, 3),
0x004001f0, NV10_PGRAPH_CTX_CACHE(4, 4),
0x00400174, NV10_PGRAPH_CTX_CACHE(5, 0),
0x00400194, NV10_PGRAPH_CTX_CACHE(5, 1),
0x004001b4, NV10_PGRAPH_CTX_CACHE(5, 2),
0x004001d4, NV10_PGRAPH_CTX_CACHE(5, 3),
0x004001f4, NV10_PGRAPH_CTX_CACHE(5, 4),
0x00400178, NV10_PGRAPH_CTX_CACHE(6, 0),
0x00400198, NV10_PGRAPH_CTX_CACHE(6, 1),
0x004001b8, NV10_PGRAPH_CTX_CACHE(6, 2),
0x004001d8, NV10_PGRAPH_CTX_CACHE(6, 3),
0x004001f8, NV10_PGRAPH_CTX_CACHE(6, 4),
0x0040017c, NV10_PGRAPH_CTX_CACHE(7, 0),
0x0040019c, NV10_PGRAPH_CTX_CACHE(7, 1),
0x004001bc, NV10_PGRAPH_CTX_CACHE(7, 2),
0x004001dc, NV10_PGRAPH_CTX_CACHE(7, 3),
0x004001fc, NV10_PGRAPH_CTX_CACHE(7, 4),
NV10_PGRAPH_CTX_USER, NV10_PGRAPH_CTX_USER,
NV04_PGRAPH_DMA_START_0, NV04_PGRAPH_DMA_START_0,
NV04_PGRAPH_DMA_START_1, NV04_PGRAPH_DMA_START_1,
...@@ -653,6 +653,78 @@ static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg) ...@@ -653,6 +653,78 @@ static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
return -1; 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) int nv10_graph_load_context(struct nouveau_channel *chan)
{ {
struct drm_device *dev = chan->dev; struct drm_device *dev = chan->dev;
...@@ -670,6 +742,8 @@ int nv10_graph_load_context(struct nouveau_channel *chan) ...@@ -670,6 +742,8 @@ int nv10_graph_load_context(struct nouveau_channel *chan)
} }
nv10_graph_load_pipe(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); nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER); tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER);
...@@ -856,11 +930,12 @@ int nv10_graph_init(struct drm_device *dev) ...@@ -856,11 +930,12 @@ int nv10_graph_init(struct drm_device *dev)
for (i = 0; i < NV10_PFB_TILE__SIZE; i++) for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
nv10_graph_set_region_tiling(dev, i, 0, 0, 0); nv10_graph_set_region_tiling(dev, i, 0, 0, 0);
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH1, 0x00000000); nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(0), 0x00000000);
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH2, 0x00000000); nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000);
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH3, 0x00000000); nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(2), 0x00000000);
nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH4, 0x00000000); nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(3), 0x00000000);
nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF); 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 = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
tmp |= (dev_priv->engine.fifo.channels - 1) << 24; tmp |= (dev_priv->engine.fifo.channels - 1) << 24;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册