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; }
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; }