Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2f4e892 authored by Francisco Jerez's avatar Francisco Jerez Committed by Ben Skeggs
Browse files

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: default avatarFrancisco Jerez <currojerez@riseup.net>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 308dceba
Loading
Loading
Loading
Loading
+7 −11
Original line number Diff line number Diff line
@@ -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
+125 −50
Original line number Diff line number Diff line
@@ -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,10 +930,11 @@ 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_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;