示例#1
0
文件: nv20_graph.c 项目: 710leo/LVS
int
nv20_graph_init(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
	uint32_t tmp, vramsz;
	int ret, i;

	switch (dev_priv->chipset) {
	case 0x20:
		pgraph->grctx_size = NV20_GRCTX_SIZE;
		break;
	case 0x25:
	case 0x28:
		pgraph->grctx_size = NV25_GRCTX_SIZE;
		break;
	case 0x2a:
		pgraph->grctx_size = NV2A_GRCTX_SIZE;
		break;
	default:
		NV_ERROR(dev, "unknown chipset, disabling acceleration\n");
		pgraph->accel_blocked = true;
		return 0;
	}

	nv_wr32(dev, NV03_PMC_ENABLE,
		nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH);
	nv_wr32(dev, NV03_PMC_ENABLE,
		nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PGRAPH);

	if (!pgraph->ctx_table) {
		/* Create Context Pointer Table */
		ret = nouveau_gpuobj_new(dev, NULL, 32 * 4, 16,
					 NVOBJ_FLAG_ZERO_ALLOC,
					 &pgraph->ctx_table);
		if (ret)
			return ret;
	}

	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE,
		     pgraph->ctx_table->pinst >> 4);

	nv20_graph_rdi(dev);

	nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);

	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000);
	nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x00118700);
	nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xF3CE0475); /* 0x4 = auto ctx switch */
	nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000);
	nv_wr32(dev, 0x40009C           , 0x00000040);

	if (dev_priv->chipset >= 0x25) {
		nv_wr32(dev, 0x400890, 0x00080000);
		nv_wr32(dev, 0x400610, 0x304B1FB6);
		nv_wr32(dev, 0x400B80, 0x18B82880);
		nv_wr32(dev, 0x400B84, 0x44000000);
		nv_wr32(dev, 0x400098, 0x40000080);
		nv_wr32(dev, 0x400B88, 0x000000ff);
	} else {
		nv_wr32(dev, 0x400880, 0x00080000); /* 0x0008c7df */
		nv_wr32(dev, 0x400094, 0x00000005);
		nv_wr32(dev, 0x400B80, 0x45CAA208); /* 0x45eae20e */
		nv_wr32(dev, 0x400B84, 0x24000000);
		nv_wr32(dev, 0x400098, 0x00000040);
		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E00038);
		nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030);
		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E10038);
		nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030);
	}

	/* Turn all the tiling regions off. */
	for (i = 0; i < NV10_PFB_TILE__SIZE; i++)
		nv20_graph_set_region_tiling(dev, i, 0, 0, 0);

	for (i = 0; i < 8; i++) {
		nv_wr32(dev, 0x400980 + i * 4, nv_rd32(dev, 0x100300 + i * 4));
		nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0090 + i * 4);
		nv_wr32(dev, NV10_PGRAPH_RDI_DATA,
					nv_rd32(dev, 0x100300 + i * 4));
	}
	nv_wr32(dev, 0x4009a0, nv_rd32(dev, 0x100324));
	nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA000C);
	nv_wr32(dev, NV10_PGRAPH_RDI_DATA, nv_rd32(dev, 0x100324));

	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100);
	nv_wr32(dev, NV10_PGRAPH_STATE      , 0xFFFFFFFF);

	tmp = nv_rd32(dev, NV10_PGRAPH_SURFACE) & 0x0007ff00;
	nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp);
	tmp = nv_rd32(dev, NV10_PGRAPH_SURFACE) | 0x00020100;
	nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp);

	/* begin RAM config */
	vramsz = pci_resource_len(dev->pdev, 0) - 1;
	nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0));
	nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1));
	nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0000);
	nv_wr32(dev, NV10_PGRAPH_RDI_DATA , nv_rd32(dev, NV04_PFB_CFG0));
	nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0004);
	nv_wr32(dev, NV10_PGRAPH_RDI_DATA , nv_rd32(dev, NV04_PFB_CFG1));
	nv_wr32(dev, 0x400820, 0);
	nv_wr32(dev, 0x400824, 0);
	nv_wr32(dev, 0x400864, vramsz - 1);
	nv_wr32(dev, 0x400868, vramsz - 1);

	/* interesting.. the below overwrites some of the tile setup above.. */
	nv_wr32(dev, 0x400B20, 0x00000000);
	nv_wr32(dev, 0x400B04, 0xFFFFFFFF);

	nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_XMIN, 0);
	nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_YMIN, 0);
	nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff);
	nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff);

	return 0;
}
示例#2
0
int nv20_graph_init(struct drm_device *dev) {
	struct drm_nouveau_private *dev_priv =
		(struct drm_nouveau_private *)dev->dev_private;
	uint32_t tmp, vramsz;
	int ret, i;

	NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) &
			~NV_PMC_ENABLE_PGRAPH);
	NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) |
			 NV_PMC_ENABLE_PGRAPH);

	/* Create Context Pointer Table */
	dev_priv->ctx_table_size = 32 * 4;
	if ((ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0,
					  dev_priv->ctx_table_size, 16,
					  NVOBJ_FLAG_ZERO_ALLOC,
					  &dev_priv->ctx_table)))
		return ret;

	NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_TABLE,
		 dev_priv->ctx_table->instance >> 4);

	nv20_graph_rdi(dev);

	NV_WRITE(NV03_PGRAPH_INTR   , 0xFFFFFFFF);
	NV_WRITE(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);

	NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
	NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000);
	NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x00118700);
	NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xF3CE0475); /* 0x4 = auto ctx switch */
	NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x00000000);
	NV_WRITE(0x40009C           , 0x00000040);

	if (dev_priv->chipset >= 0x25) {
		NV_WRITE(0x400890, 0x00080000);
		NV_WRITE(0x400610, 0x304B1FB6);
		NV_WRITE(0x400B80, 0x18B82880);
		NV_WRITE(0x400B84, 0x44000000);
		NV_WRITE(0x400098, 0x40000080);
		NV_WRITE(0x400B88, 0x000000ff);
	} else {
		NV_WRITE(0x400880, 0x00080000); /* 0x0008c7df */
		NV_WRITE(0x400094, 0x00000005);
		NV_WRITE(0x400B80, 0x45CAA208); /* 0x45eae20e */
		NV_WRITE(0x400B84, 0x24000000);
		NV_WRITE(0x400098, 0x00000040);
		NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x00E00038);
		NV_WRITE(NV10_PGRAPH_RDI_DATA , 0x00000030);
		NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x00E10038);
		NV_WRITE(NV10_PGRAPH_RDI_DATA , 0x00000030);
	}

	/* copy tile info from PFB */
	for (i = 0; i < NV10_PFB_TILE__SIZE; i++) {
		NV_WRITE(0x00400904 + i*0x10, NV_READ(NV10_PFB_TLIMIT(i)));
			/* which is NV40_PGRAPH_TLIMIT0(i) ?? */
		NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x00EA0030+i*4);
		NV_WRITE(NV10_PGRAPH_RDI_DATA, NV_READ(NV10_PFB_TLIMIT(i)));
		NV_WRITE(0x00400908 + i*0x10, NV_READ(NV10_PFB_TSIZE(i)));
			/* which is NV40_PGRAPH_TSIZE0(i) ?? */
		NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x00EA0050+i*4);
		NV_WRITE(NV10_PGRAPH_RDI_DATA, NV_READ(NV10_PFB_TSIZE(i)));
		NV_WRITE(0x00400900 + i*0x10, NV_READ(NV10_PFB_TILE(i)));
			/* which is NV40_PGRAPH_TILE0(i) ?? */
		NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x00EA0010+i*4);
		NV_WRITE(NV10_PGRAPH_RDI_DATA, NV_READ(NV10_PFB_TILE(i)));
	}
	for (i = 0; i < 8; i++) {
		NV_WRITE(0x400980+i*4, NV_READ(0x100300+i*4));
		NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x00EA0090+i*4);
		NV_WRITE(NV10_PGRAPH_RDI_DATA, NV_READ(0x100300+i*4));
	}
	NV_WRITE(0x4009a0, NV_READ(0x100324));
	NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x00EA000C);
	NV_WRITE(NV10_PGRAPH_RDI_DATA, NV_READ(0x100324));

	NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10000100);
	NV_WRITE(NV10_PGRAPH_STATE      , 0xFFFFFFFF);
	NV_WRITE(NV04_PGRAPH_FIFO       , 0x00000001);

	tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00;
	NV_WRITE(NV10_PGRAPH_SURFACE, tmp);
	tmp = NV_READ(NV10_PGRAPH_SURFACE) | 0x00020100;
	NV_WRITE(NV10_PGRAPH_SURFACE, tmp);

	/* begin RAM config */
	vramsz = drm_get_resource_len(dev, 0) - 1;
	NV_WRITE(0x4009A4, NV_READ(NV04_PFB_CFG0));
	NV_WRITE(0x4009A8, NV_READ(NV04_PFB_CFG1));
	NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x00EA0000);
	NV_WRITE(NV10_PGRAPH_RDI_DATA , NV_READ(NV04_PFB_CFG0));
	NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x00EA0004);
	NV_WRITE(NV10_PGRAPH_RDI_DATA , NV_READ(NV04_PFB_CFG1));
	NV_WRITE(0x400820, 0);
	NV_WRITE(0x400824, 0);
	NV_WRITE(0x400864, vramsz-1);
	NV_WRITE(0x400868, vramsz-1);

	/* interesting.. the below overwrites some of the tile setup above.. */
	NV_WRITE(0x400B20, 0x00000000);
	NV_WRITE(0x400B04, 0xFFFFFFFF);

	NV_WRITE(NV03_PGRAPH_ABS_UCLIP_XMIN, 0);
	NV_WRITE(NV03_PGRAPH_ABS_UCLIP_YMIN, 0);
	NV_WRITE(NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff);
	NV_WRITE(NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff);

	return 0;
}