From 674cefd4fe4b537a20a10edcb4ec5df55facca8e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 26 Mar 2007 19:43:48 +1000 Subject: nouveau: move card initialisation into the drm The PGRAPH init for the various cards will need cleaning up at some point, a lot of the values written there are per-context state left over from the all the hardcoding done in the ddx. It's possible some cards get broken by this commit, let me know. Tested on: NV5, NV18, NV28, NV35, NV40, NV4E --- shared-core/nouveau_drm.h | 4 +- shared-core/nouveau_drv.h | 65 ++++++++++++- shared-core/nouveau_fifo.c | 53 ++--------- shared-core/nouveau_irq.c | 27 ++++++ shared-core/nouveau_mem.c | 115 ++++++++++++++++------ shared-core/nouveau_reg.h | 53 +++++++++++ shared-core/nouveau_state.c | 225 ++++++++++++++++++++++++++++++++++---------- shared-core/nv04_fb.c | 24 +++++ shared-core/nv04_graph.c | 33 ++++++- shared-core/nv04_mc.c | 20 ++++ shared-core/nv04_timer.c | 24 +++++ shared-core/nv10_fb.c | 26 +++++ shared-core/nv10_graph.c | 53 +++++++++++ shared-core/nv20_graph.c | 79 ++++++++++++++++ shared-core/nv30_graph.c | 68 +++++++++++++ shared-core/nv40_fb.c | 56 +++++++++++ shared-core/nv40_graph.c | 206 +++++++++++++++++++++++++++++++++++++++- shared-core/nv40_mc.c | 36 +++++++ 18 files changed, 1038 insertions(+), 129 deletions(-) create mode 100644 shared-core/nv04_fb.c create mode 100644 shared-core/nv04_mc.c create mode 100644 shared-core/nv04_timer.c create mode 100644 shared-core/nv10_fb.c create mode 100644 shared-core/nv40_fb.c create mode 100644 shared-core/nv40_mc.c (limited to 'shared-core') diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h index c3a69a8f..3ba7e961 100644 --- a/shared-core/nouveau_drm.h +++ b/shared-core/nouveau_drm.h @@ -25,7 +25,7 @@ #ifndef __NOUVEAU_DRM_H__ #define __NOUVEAU_DRM_H__ -#define NOUVEAU_DRM_HEADER_PATCHLEVEL 5 +#define NOUVEAU_DRM_HEADER_PATCHLEVEL 6 typedef struct drm_nouveau_fifo_alloc { int channel; @@ -142,7 +142,7 @@ drm_nouveau_sarea_t; #define DRM_NOUVEAU_FIFO_ALLOC 0x00 #define DRM_NOUVEAU_OBJECT_INIT 0x01 -#define DRM_NOUVEAU_DMA_OBJECT_INIT 0x02 // We don't want this eventually.. +#define DRM_NOUVEAU_DMA_OBJECT_INIT 0x02 #define DRM_NOUVEAU_MEM_ALLOC 0x03 #define DRM_NOUVEAU_MEM_FREE 0x04 #define DRM_NOUVEAU_GETPARAM 0x05 diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 265479f8..debee8e4 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -34,7 +34,7 @@ #define DRIVER_MAJOR 0 #define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 5 +#define DRIVER_PATCHLEVEL 6 #define NOUVEAU_FAMILY 0x0000FFFF #define NOUVEAU_FLAGS 0xFFFF0000 @@ -99,6 +99,33 @@ struct nouveau_config { } cmdbuf; }; +struct nouveau_engine_func { + struct { + int (*Init)(drm_device_t *dev); + void (*Takedown)(drm_device_t *dev); + } Mc; + + struct { + int (*Init)(drm_device_t *dev); + void (*Takedown)(drm_device_t *dev); + } Timer; + + struct { + int (*Init)(drm_device_t *dev); + void (*Takedown)(drm_device_t *dev); + } Fb; + + struct { + int (*Init)(drm_device_t *dev); + void (*Takedown)(drm_device_t *dev); + } Graph; + + struct { + int (*Init)(drm_device_t *dev); + void (*Takedown)(drm_device_t *dev); + } Fifo; +}; + typedef struct drm_nouveau_private { /* the card type, takes NV_* as values */ int card_type; @@ -113,6 +140,8 @@ typedef struct drm_nouveau_private { int fifo_alloc_count; struct nouveau_fifo fifos[NV_MAX_FIFO_NUMBER]; + struct nouveau_engine_func Engine; + /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ uint32_t ramin_size; uint32_t ramht_offset; @@ -154,6 +183,7 @@ extern int nouveau_unload(struct drm_device *dev); extern int nouveau_ioctl_getparam(DRM_IOCTL_ARGS); extern int nouveau_ioctl_setparam(DRM_IOCTL_ARGS); extern void nouveau_wait_for_idle(struct drm_device *dev); +extern int nouveau_ioctl_card_init(DRM_IOCTL_ARGS); /* nouveau_mem.c */ extern uint64_t nouveau_mem_fb_amount(struct drm_device *dev); @@ -164,8 +194,7 @@ extern struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment extern void nouveau_mem_free(struct drm_device* dev, struct mem_block*); extern int nouveau_mem_init(struct drm_device *dev); extern void nouveau_mem_close(struct drm_device *dev); -extern int nouveau_instmem_init(struct drm_device *dev, - uint32_t offset); +extern int nouveau_instmem_init(struct drm_device *dev); extern struct mem_block* nouveau_instmem_alloc(struct drm_device *dev, uint32_t size, uint32_t align); extern void nouveau_instmem_free(struct drm_device *dev, @@ -179,6 +208,7 @@ extern void nouveau_instmem_w32(drm_nouveau_private_t *dev_priv, /* nouveau_fifo.c */ extern int nouveau_fifo_init(drm_device_t *dev); extern int nouveau_fifo_number(drm_device_t *dev); +extern int nouveau_fifo_ctx_size(drm_device_t *dev); extern void nouveau_fifo_cleanup(drm_device_t *dev, DRMFILE filp); extern int nouveau_fifo_owner(drm_device_t *dev, DRMFILE filp, int channel); extern void nouveau_fifo_free(drm_device_t *dev, int channel); @@ -202,31 +232,60 @@ extern void nouveau_irq_preinstall(drm_device_t*); extern void nouveau_irq_postinstall(drm_device_t*); extern void nouveau_irq_uninstall(drm_device_t*); +/* nv04_fb.c */ +extern int nv04_fb_init(drm_device_t *dev); +extern void nv04_fb_takedown(drm_device_t *dev); + +/* nv10_fb.c */ +extern int nv10_fb_init(drm_device_t *dev); +extern void nv10_fb_takedown(drm_device_t *dev); + +/* nv40_fb.c */ +extern int nv40_fb_init(drm_device_t *dev); +extern void nv40_fb_takedown(drm_device_t *dev); + /* nv04_graph.c */ extern void nouveau_nv04_context_switch(drm_device_t *dev); extern int nv04_graph_init(drm_device_t *dev); +extern void nv04_graph_takedown(drm_device_t *dev); extern int nv04_graph_context_create(drm_device_t *dev, int channel); /* nv10_graph.c */ extern void nouveau_nv10_context_switch(drm_device_t *dev); extern int nv10_graph_init(drm_device_t *dev); +extern void nv10_graph_takedown(drm_device_t *dev); extern int nv10_graph_context_create(drm_device_t *dev, int channel); /* nv20_graph.c */ extern void nouveau_nv20_context_switch(drm_device_t *dev); extern int nv20_graph_init(drm_device_t *dev); +extern void nv20_graph_takedown(drm_device_t *dev); extern int nv20_graph_context_create(drm_device_t *dev, int channel); /* nv30_graph.c */ extern int nv30_graph_init(drm_device_t *dev); +extern void nv30_graph_takedown(drm_device_t *dev); extern int nv30_graph_context_create(drm_device_t *dev, int channel); /* nv40_graph.c */ extern int nv40_graph_init(drm_device_t *dev); +extern void nv40_graph_takedown(drm_device_t *dev); extern int nv40_graph_context_create(drm_device_t *dev, int channel); extern void nv40_graph_context_save_current(drm_device_t *dev); extern void nv40_graph_context_restore(drm_device_t *dev, int channel); +/* nv04_mc.c */ +extern int nv04_mc_init(drm_device_t *dev); +extern void nv04_mc_takedown(drm_device_t *dev); + +/* nv40_mc.c */ +extern int nv40_mc_init(drm_device_t *dev); +extern void nv40_mc_takedown(drm_device_t *dev); + +/* nv04_timer.c */ +extern int nv04_timer_init(drm_device_t *dev); +extern void nv04_timer_takedown(drm_device_t *dev); + extern long nouveau_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 2733c1b0..92166eeb 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -45,7 +45,7 @@ int nouveau_fifo_number(drm_device_t* dev) } /* returns the size of fifo context */ -static int nouveau_fifo_ctx_size(drm_device_t* dev) +int nouveau_fifo_ctx_size(drm_device_t* dev) { drm_nouveau_private_t *dev_priv=dev->dev_private; @@ -69,78 +69,36 @@ static int nouveau_fifo_ctx_size(drm_device_t* dev) static int nouveau_fifo_instmem_configure(drm_device_t *dev) { drm_nouveau_private_t *dev_priv = dev->dev_private; - int i; - - /* Clear start of RAMIN, enough to cover RAMFC/HT/RO basically */ - for (i=0x00710000; i<0x00730000; i++) - NV_WRITE(i, 0x00000000); - /* FIFO hash table (RAMHT) - * use 4k hash table at RAMIN+0x10000 - * TODO: extend the hash table - */ - dev_priv->ramht_offset = 0x10000; - dev_priv->ramht_bits = 9; - dev_priv->ramht_size = (1 << dev_priv->ramht_bits); NV_WRITE(NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | ((dev_priv->ramht_bits - 9) << 16) | (dev_priv->ramht_offset >> 8) ); - DRM_DEBUG("RAMHT offset=0x%x, size=%d\n", - dev_priv->ramht_offset, - dev_priv->ramht_size); - /* FIFO runout table (RAMRO) - 512k at 0x11200 */ - dev_priv->ramro_offset = 0x11200; - dev_priv->ramro_size = 512; NV_WRITE(NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8); - DRM_DEBUG("RAMRO offset=0x%x, size=%d\n", - dev_priv->ramro_offset, - dev_priv->ramro_size); - - /* FIFO context table (RAMFC) - * NV40 : Not sure exactly how to position RAMFC on some cards, - * 0x30002 seems to position it at RAMIN+0x20000 on these - * cards. RAMFC is 4kb (32 fifos, 128byte entries). - * Others: Position RAMFC at RAMIN+0x11400 - */ + switch(dev_priv->card_type) { case NV_50: case NV_40: - dev_priv->ramfc_offset = 0x20000; - dev_priv->ramfc_size = nouveau_fifo_number(dev) * nouveau_fifo_ctx_size(dev); NV_WRITE(NV40_PFIFO_RAMFC, 0x30002); break; case NV_44: - dev_priv->ramfc_offset = 0x20000; - dev_priv->ramfc_size = nouveau_fifo_number(dev) * nouveau_fifo_ctx_size(dev); NV_WRITE(NV40_PFIFO_RAMFC, ((nouveau_mem_fb_amount(dev)-512*1024+dev_priv->ramfc_offset)>>16) | (2 << 16)); break; case NV_30: case NV_20: case NV_10: - dev_priv->ramfc_offset = 0x11400; - dev_priv->ramfc_size = nouveau_fifo_number(dev) * nouveau_fifo_ctx_size(dev); NV_WRITE(NV03_PFIFO_RAMFC, (dev_priv->ramfc_offset>>8) | (1 << 16) /* 64 Bytes entry*/); break; case NV_04: case NV_03: - dev_priv->ramfc_offset = 0x11400; - dev_priv->ramfc_size = nouveau_fifo_number(dev) * nouveau_fifo_ctx_size(dev); NV_WRITE(NV03_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); break; } - DRM_DEBUG("RAMFC offset=0x%x, size=%d\n", - dev_priv->ramfc_offset, - dev_priv->ramfc_size); - - if (nouveau_instmem_init(dev, dev_priv->ramfc_offset + - dev_priv->ramfc_size)) - return 1; return 0; } @@ -150,6 +108,11 @@ int nouveau_fifo_init(drm_device_t *dev) drm_nouveau_private_t *dev_priv = dev->dev_private; int ret; + NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) & + ~NV_PMC_ENABLE_PFIFO); + NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) | + NV_PMC_ENABLE_PFIFO); + NV_WRITE(NV03_PFIFO_CACHES, 0x00000000); ret = nouveau_fifo_instmem_configure(dev); @@ -736,7 +699,7 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) ***********************************/ drm_ioctl_desc_t nouveau_ioctls[] = { - [DRM_IOCTL_NR(DRM_NOUVEAU_FIFO_ALLOC)] = {nouveau_ioctl_fifo_alloc, DRM_AUTH}, + [DRM_IOCTL_NR(DRM_NOUVEAU_FIFO_ALLOC)] = {nouveau_ioctl_fifo_alloc, DRM_AUTH}, [DRM_IOCTL_NR(DRM_NOUVEAU_OBJECT_INIT)] = {nouveau_ioctl_object_init, DRM_AUTH}, [DRM_IOCTL_NR(DRM_NOUVEAU_DMA_OBJECT_INIT)] = {nouveau_ioctl_dma_object_init, DRM_AUTH}, [DRM_IOCTL_NR(DRM_NOUVEAU_MEM_ALLOC)] = {nouveau_ioctl_mem_alloc, DRM_AUTH}, diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 32b33070..b7c1d532 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -42,6 +42,15 @@ void nouveau_irq_preinstall(drm_device_t *dev) DRM_DEBUG("IRQ: preinst\n"); + if (!dev_priv) { + DRM_ERROR("AIII, no dev_priv\n"); + return; + } + if (!dev_priv->mmio) { + DRM_ERROR("AIII, no dev_priv->mmio\n"); + return; + } + /* Disable/Clear PFIFO interrupts */ NV_WRITE(NV03_PFIFO_INTR_EN_0, 0); NV_WRITE(NV03_PFIFO_INTR_0, 0xFFFFFFFF); @@ -66,6 +75,15 @@ void nouveau_irq_postinstall(drm_device_t *dev) { drm_nouveau_private_t *dev_priv = dev->dev_private; + if (!dev_priv) { + DRM_ERROR("AIII, no dev_priv\n"); + return; + } + if (!dev_priv->mmio) { + DRM_ERROR("AIII, no dev_priv->mmio\n"); + return; + } + DRM_DEBUG("IRQ: postinst\n"); /* Enable PFIFO error reporting */ @@ -113,6 +131,15 @@ void nouveau_irq_uninstall(drm_device_t *dev) { drm_nouveau_private_t *dev_priv = dev->dev_private; + if (!dev_priv) { + DRM_ERROR("AIII, no dev_priv\n"); + return; + } + if (!dev_priv->mmio) { + DRM_ERROR("AIII, no dev_priv->mmio\n"); + return; + } + DRM_DEBUG("IRQ: uninst\n"); /* Disable PFIFO interrupts */ diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index f62d8615..541f1545 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -35,8 +35,6 @@ #include "drm_sarea.h" #include "nouveau_drv.h" -//static int meminit_ok=0; - static struct mem_block *split_block(struct mem_block *p, uint64_t start, uint64_t size, DRMFILE filp) { @@ -340,6 +338,11 @@ int nouveau_mem_init(struct drm_device *dev) } no_agp: + /* setup a mtrr over the FB */ + dev_priv->fb_mtrr = drm_mtrr_add(drm_get_resource_start(dev, 1), + nouveau_mem_fb_amount(dev), + DRM_MTRR_WC); + /* Init FB */ dev_priv->fb_phys=drm_get_resource_start(dev,1); fb_size = nouveau_mem_fb_amount(dev); @@ -372,14 +375,6 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, uint6 int type; drm_nouveau_private_t *dev_priv = dev->dev_private; - /* - * Init memory if needed - */ - if (dev_priv->fb_phys == 0) - { - nouveau_mem_init(dev); - } - /* * Make things easier on ourselves: all allocations are page-aligned. * We need that to map allocated regions into the user space @@ -447,44 +442,113 @@ alloc_ok: void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - DRM_INFO("freeing 0x%llx\n", block->start); - if (dev_priv->fb_phys == 0) - { - DRM_ERROR("%s called without init\n", __FUNCTION__); - return; - } if (block->flags&NOUVEAU_MEM_MAPPED) drm_rmmap(dev, block->map); free_block(block); } -int nouveau_instmem_init(struct drm_device *dev, uint32_t offset) +static void +nouveau_instmem_determine_amount(struct drm_device *dev) { drm_nouveau_private_t *dev_priv = dev->dev_private; - int ret; + int i; - if (dev_priv->card_type >= NV_40) + /* Figure out how much instance memory we need */ + switch (dev_priv->card_type) { + case NV_40: /* We'll want more instance memory than this on some NV4x cards. * There's a 16MB aperture to play with that maps onto the end * of vram. For now, only reserve a small piece until we know * more about what each chipset requires. */ dev_priv->ramin_size = (1*1024* 1024); - else { + break; + default: /*XXX: what *are* the limits on ramin_size = (512*1024); + break; } DRM_DEBUG("RAMIN size: %dKiB\n", dev_priv->ramin_size>>10); + /* Clear all of it, except the BIOS image that's in the first 64KiB */ + if (dev_priv->ramin) { + for (i=(64*1024); iramin_size; i+=4) + DRM_WRITE32(dev_priv->ramin, i, 0x00000000); + } else { + for (i=(64*1024); iramin_size; i+=4) + DRM_WRITE32(dev_priv->mmio, NV_RAMIN + i, 0x00000000); + } +} + +static void +nouveau_instmem_configure_fixed_tables(struct drm_device *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + + /* FIFO hash table (RAMHT) + * use 4k hash table at RAMIN+0x10000 + * TODO: extend the hash table + */ + dev_priv->ramht_offset = 0x10000; + dev_priv->ramht_bits = 9; + dev_priv->ramht_size = (1 << dev_priv->ramht_bits); + DRM_DEBUG("RAMHT offset=0x%x, size=%d\n", dev_priv->ramht_offset, + dev_priv->ramht_size); + + /* FIFO runout table (RAMRO) - 512k at 0x11200 */ + dev_priv->ramro_offset = 0x11200; + dev_priv->ramro_size = 512; + DRM_DEBUG("RAMRO offset=0x%x, size=%d\n", dev_priv->ramro_offset, + dev_priv->ramro_size); + + /* FIFO context table (RAMFC) + * NV40 : Not sure exactly how to position RAMFC on some cards, + * 0x30002 seems to position it at RAMIN+0x20000 on these + * cards. RAMFC is 4kb (32 fifos, 128byte entries). + * Others: Position RAMFC at RAMIN+0x11400 + */ + switch(dev_priv->card_type) + { + case NV_50: + case NV_40: + case NV_44: + dev_priv->ramfc_offset = 0x20000; + dev_priv->ramfc_size = nouveau_fifo_number(dev) * + nouveau_fifo_ctx_size(dev); + break; + case NV_30: + case NV_20: + case NV_10: + case NV_04: + case NV_03: + default: + dev_priv->ramfc_offset = 0x11400; + dev_priv->ramfc_size = nouveau_fifo_number(dev) * + nouveau_fifo_ctx_size(dev); + break; + } + DRM_DEBUG("RAMFC offset=0x%x, size=%d\n", dev_priv->ramfc_offset, + dev_priv->ramfc_size); +} + +int nouveau_instmem_init(struct drm_device *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + uint32_t offset; + int ret = 0; + + nouveau_instmem_determine_amount(dev); + nouveau_instmem_configure_fixed_tables(dev); + /* Create a heap to manage RAMIN allocations, we don't allocate * the space that was reserved for RAMHT/FC/RO. */ - ret = init_heap(&dev_priv->ramin_heap, offset, - dev_priv->ramin_size - offset); + offset = dev_priv->ramfc_offset + dev_priv->ramfc_size; + ret = init_heap(&dev_priv->ramin_heap, + offset, dev_priv->ramin_size - offset); if (ret) { dev_priv->ramin_heap = NULL; DRM_ERROR("Failed to init RAMIN heap\n"); @@ -590,11 +654,6 @@ int nouveau_ioctl_mem_free(DRM_IOCTL_ARGS) drm_nouveau_mem_free_t memfree; struct mem_block *block; - if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); - } - DRM_COPY_FROM_USER_IOCTL(memfree, (drm_nouveau_mem_free_t __user *) data, sizeof(memfree)); diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index e7ab3804..3360fec2 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -62,7 +62,42 @@ # define NV_PMC_INTR_0_CRTCn_PENDING (3<<24) #define NV03_PMC_INTR_EN_0 0x00000140 # define NV_PMC_INTR_EN_0_MASTER_ENABLE (1<< 0) +#define NV03_PMC_ENABLE 0x00000200 +# define NV_PMC_ENABLE_PFIFO (1<< 8) +# define NV_PMC_ENABLE_PGRAPH (1<<12) +#define NV40_PMC_1700 0x00001700 +#define NV40_PMC_1704 0x00001704 +#define NV40_PMC_1708 0x00001708 +#define NV40_PMC_170C 0x0000170C +#define NV04_PTIMER_INTR_0 0x00009100 +#define NV04_PTIMER_INTR_EN_0 0x00009140 +#define NV04_PTIMER_NUMERATOR 0x00009200 +#define NV04_PTIMER_DENOMINATOR 0x00009210 +#define NV04_PTIMER_TIME_0 0x00009400 +#define NV04_PTIMER_TIME_1 0x00009410 +#define NV04_PTIMER_ALARM_0 0x00009420 + +#define NV04_PFB_CFG0 0x00100200 +#define NV04_PFB_CFG1 0x00100204 +#define NV40_PFB_020C 0x0010020C +#define NV10_PFB_TILE(i) (0x00100240 + (i*16)) +#define NV10_PFB_TILE__SIZE 8 +#define NV10_PFB_TLIMIT(i) (0x00100244 + (i*16)) +#define NV10_PFB_TSIZE(i) (0x00100248 + (i*16)) +#define NV10_PFB_TSTATUS(i) (0x0010024C + (i*16)) +#define NV10_PFB_CLOSE_PAGE2 0x0010033C +#define NV40_PFB_TILE(i) (0x00100600 + (i*16)) +#define NV40_PFB_TILE__SIZE_0 12 +#define NV40_PFB_TILE__SIZE_1 15 +#define NV40_PFB_TLIMIT(i) (0x00100604 + (i*16)) +#define NV40_PFB_TSIZE(i) (0x00100608 + (i*16)) +#define NV40_PFB_TSTATUS(i) (0x0010060C + (i*16)) + +#define NV04_PGRAPH_DEBUG_0 0x00400080 +#define NV04_PGRAPH_DEBUG_1 0x00400084 +#define NV04_PGRAPH_DEBUG_2 0x00400088 +#define NV04_PGRAPH_DEBUG_3 0x0040008c #define NV10_PGRAPH_DEBUG_4 0x00400090 #define NV03_PGRAPH_INTR 0x00400100 #define NV03_PGRAPH_INTR_EN 0x00400140 @@ -141,7 +176,9 @@ #define NV04_PGRAPH_ROP3 0x00400604 #define NV04_PGRAPH_BETA_AND 0x00400608 #define NV04_PGRAPH_BETA_PREMULT 0x0040060C +#define NV04_PGRAPH_LIMIT_VIOL_PIX 0x00400610 #define NV04_PGRAPH_FORMATS 0x00400618 +#define NV10_PGRAPH_DEBUG_2 0x00400620 #define NV04_PGRAPH_BOFFSET0 0x00400640 #define NV04_PGRAPH_BOFFSET1 0x00400644 #define NV04_PGRAPH_BOFFSET2 0x00400648 @@ -201,7 +238,19 @@ #define NV04_PGRAPH_BLEND 0x00400824 #define NV04_PGRAPH_STORED_FMT 0x00400830 #define NV04_PGRAPH_PATT_COLORRAM 0x00400900 +#define NV40_PGRAPH_TILE0(i) 0x00400900 +#define NV40_PGRAPH_TLIMIT0(i) 0x00400904 +#define NV40_PGRAPH_TSIZE0(i) 0x00400908 +#define NV40_PGRAPH_TSTATUS0(i) 0x0040090C +#define NV10_PGRAPH_TILE(i) (0x00400B00 + (i*16)) +#define NV10_PGRAPH_TLIMIT(i) (0x00400B04 + (i*16)) +#define NV10_PGRAPH_TSIZE(i) (0x00400B08 + (i*16)) +#define NV10_PGRAPH_TSTATUS(i) (0x00400B0C + (i*16)) #define NV04_PGRAPH_U_RAM 0x00400D00 +#define NV47_PGRAPH_TILE0(i) 0x00400D00 +#define NV47_PGRAPH_TLIMIT0(i) 0x00400D04 +#define NV47_PGRAPH_TSIZE0(i) 0x00400D08 +#define NV47_PGRAPH_TSTATUS0(i) 0x00400D0C #define NV04_PGRAPH_V_RAM 0x00400D40 #define NV04_PGRAPH_W_RAM 0x00400D80 #define NV10_PGRAPH_WINDOWCLIP_HORIZONTAL 0x00400F00 @@ -237,6 +286,10 @@ #define NV04_PGRAPH_DMA_B_OFFSET 0x00401098 #define NV04_PGRAPH_DMA_B_SIZE 0x0040109C #define NV04_PGRAPH_DMA_B_Y_SIZE 0x004010A0 +#define NV40_PGRAPH_TILE1(i) 0x00406900 +#define NV40_PGRAPH_TLIMIT1(i) 0x00406904 +#define NV40_PGRAPH_TSIZE1(i) 0x00406908 +#define NV40_PGRAPH_TSTATUS1(i) 0x0040690C /* It's a guess that this works on NV03. Confirmed on NV04, though */ diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index ed45c166..e7930b9e 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -26,22 +26,12 @@ #include "drm.h" #include "drm_sarea.h" #include "nouveau_drv.h" +#include "nouveau_drm.h" -/* here a client dies, release the stuff that was allocated for its filp */ -void nouveau_preclose(drm_device_t * dev, DRMFILE filp) +static int nouveau_init_card_mappings(drm_device_t *dev) { drm_nouveau_private_t *dev_priv = dev->dev_private; - - nouveau_mem_release(filp,dev_priv->fb_heap); - nouveau_mem_release(filp,dev_priv->agp_heap); - nouveau_fifo_cleanup(dev, filp); -} - -/* first module load, setup the mmio/fb mapping */ -int nouveau_firstopen(struct drm_device *dev) -{ int ret; - drm_nouveau_private_t *dev_priv = dev->dev_private; /* resource 0 is mmio regs */ /* resource 1 is linear FB */ @@ -49,19 +39,16 @@ int nouveau_firstopen(struct drm_device *dev) /* resource 6 is bios */ /* map the mmio regs */ - ret = drm_addmap(dev, drm_get_resource_start(dev, 0), drm_get_resource_len(dev, 0), - _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio); - if (dev_priv->mmio) - { - DRM_INFO("regs mapped ok at 0x%lx\n",dev_priv->mmio->offset); - } - else - { - DRM_ERROR("Unable to initialize the mmio mapping. Please report your setup to " DRIVER_EMAIL "\n"); - return 1; + ret = drm_addmap(dev, drm_get_resource_start(dev, 0), + drm_get_resource_len(dev, 0), + _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio); + if (ret) { + DRM_ERROR("Unable to initialize the mmio mapping (%d). " + "Please report your setup to " DRIVER_EMAIL "\n", + ret); + return 1; } - - DRM_INFO("%lld MB of video ram detected\n",nouveau_mem_fb_amount(dev)>>20); + DRM_DEBUG("regs mapped ok at 0x%lx\n", dev_priv->mmio->offset); /* map larger RAMIN aperture on NV40 cards */ if (dev_priv->card_type >= NV_40) { @@ -69,11 +56,11 @@ int nouveau_firstopen(struct drm_device *dev) if (drm_get_resource_len(dev, ramin_resource) == 0) ramin_resource = 3; - ret = drm_addmap(dev, drm_get_resource_start(dev, ramin_resource), - drm_get_resource_len(dev, ramin_resource), - _DRM_REGISTERS, - _DRM_READ_ONLY, - &dev_priv->ramin); + ret = drm_addmap(dev, + drm_get_resource_start(dev, ramin_resource), + drm_get_resource_len(dev, ramin_resource), + _DRM_REGISTERS, _DRM_READ_ONLY, + &dev_priv->ramin); if (ret) { DRM_ERROR("Failed to init RAMIN mapping, " "limited instance memory available\n"); @@ -82,33 +69,165 @@ int nouveau_firstopen(struct drm_device *dev) } else dev_priv->ramin = NULL; + return 0; +} + +static void nouveau_stub_takedown(drm_device_t *dev) {} +static int nouveau_init_engine_ptrs(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + struct nouveau_engine_func *engine = &dev_priv->Engine; + + switch (dev_priv->chipset & 0xf0) { + case 0x00: + engine->Mc.Init = nv04_mc_init; + engine->Mc.Takedown = nv04_mc_takedown; + engine->Timer.Init = nv04_timer_init; + engine->Timer.Takedown = nv04_timer_takedown; + engine->Fb.Init = nv04_fb_init; + engine->Fb.Takedown = nv04_fb_takedown; + engine->Graph.Init = nv04_graph_init; + engine->Graph.Takedown = nv04_graph_takedown; + engine->Fifo.Init = nouveau_fifo_init; + engine->Fifo.Takedown = nouveau_stub_takedown; + break; + case 0x10: + engine->Mc.Init = nv04_mc_init; + engine->Mc.Takedown = nv04_mc_takedown; + engine->Timer.Init = nv04_timer_init; + engine->Timer.Takedown = nv04_timer_takedown; + engine->Fb.Init = nv10_fb_init; + engine->Fb.Takedown = nv10_fb_takedown; + engine->Graph.Init = nv10_graph_init; + engine->Graph.Takedown = nv10_graph_takedown; + engine->Fifo.Init = nouveau_fifo_init; + engine->Fifo.Takedown = nouveau_stub_takedown; + break; + case 0x20: + engine->Mc.Init = nv04_mc_init; + engine->Mc.Takedown = nv04_mc_takedown; + engine->Timer.Init = nv04_timer_init; + engine->Timer.Takedown = nv04_timer_takedown; + engine->Fb.Init = nv10_fb_init; + engine->Fb.Takedown = nv10_fb_takedown; + engine->Graph.Init = nv20_graph_init; + engine->Graph.Takedown = nv20_graph_takedown; + engine->Fifo.Init = nouveau_fifo_init; + engine->Fifo.Takedown = nouveau_stub_takedown; + break; + case 0x30: + engine->Mc.Init = nv04_mc_init; + engine->Mc.Takedown = nv04_mc_takedown; + engine->Timer.Init = nv04_timer_init; + engine->Timer.Takedown = nv04_timer_takedown; + engine->Fb.Init = nv10_fb_init; + engine->Fb.Takedown = nv10_fb_takedown; + engine->Graph.Init = nv30_graph_init; + engine->Graph.Takedown = nv30_graph_takedown; + engine->Fifo.Init = nouveau_fifo_init; + engine->Fifo.Takedown = nouveau_stub_takedown; + break; + case 0x40: + engine->Mc.Init = nv40_mc_init; + engine->Mc.Takedown = nv40_mc_takedown; + engine->Timer.Init = nv04_timer_init; + engine->Timer.Takedown = nv04_timer_takedown; + engine->Fb.Init = nv40_fb_init; + engine->Fb.Takedown = nv40_fb_takedown; + engine->Graph.Init = nv40_graph_init; + engine->Graph.Takedown = nv40_graph_takedown; + engine->Fifo.Init = nouveau_fifo_init; + engine->Fifo.Takedown = nouveau_stub_takedown; + break; + case 0x50: + default: + DRM_ERROR("NV%02x unsupported\n", dev_priv->chipset); + return 1; + } + + return 0; +} + +static int nouveau_card_init(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + struct nouveau_engine_func *engine; + int ret; + + /* Map any PCI resources we need on the card */ + ret = nouveau_init_card_mappings(dev); + if (ret) return ret; + /* Determine exact chipset we're running on */ if (dev_priv->card_type < NV_10) dev_priv->chipset = dev_priv->card_type; else - dev_priv->chipset =(NV_READ(NV03_PMC_BOOT_0) & 0x0ff00000) >> 20; + dev_priv->chipset = + (NV_READ(NV03_PMC_BOOT_0) & 0x0ff00000) >> 20; - /* Clear RAMIN - * Determine locations for RAMHT/FC/RO - * Initialise PFIFO + /* Initialise internal driver API hooks */ + ret = nouveau_init_engine_ptrs(dev); + if (ret) return ret; + engine = &dev_priv->Engine; + + /* Initialise instance memory, must happen before mem_init so we + * know exactly how much VRAM we're able to use for "normal" + * purposes. */ - ret = nouveau_fifo_init(dev); + ret = nouveau_instmem_init(dev); + if (ret) return ret; + + /* Setup the memory manager */ + ret = nouveau_mem_init(dev); + if (ret) return ret; + + /* Parse BIOS tables / Run init tables? */ + + /* PMC */ + ret = engine->Mc.Init(dev); + if (ret) return ret; + + /* PTIMER */ + ret = engine->Timer.Init(dev); + if (ret) return ret; + + /* PFB */ + ret = engine->Fb.Init(dev); + if (ret) return ret; + + /* PGRAPH */ + ret = engine->Graph.Init(dev); + if (ret) return ret; + + /* PFIFO */ + ret = engine->Fifo.Init(dev); if (ret) return ret; - /* setup a mtrr over the FB */ - dev_priv->fb_mtrr=drm_mtrr_add(drm_get_resource_start(dev, 1),nouveau_mem_fb_amount(dev), DRM_MTRR_WC); - - /* FIXME: doesn't belong here, and have no idea what it's for.. */ - if (dev_priv->card_type >= NV_40) - nv40_graph_init(dev); - else if (dev_priv->card_type >= NV_30) - nv30_graph_init(dev); - else if (dev_priv->card_type >= NV_20) - nv20_graph_init(dev); - else if (dev_priv->card_type >= NV_10) - nv10_graph_init(dev); - else if (dev_priv->card_type >= NV_04) - nv04_graph_init(dev); + /* what about PVIDEO/PCRTC/PRAMDAC etc? */ + + return 0; +} + +/* here a client dies, release the stuff that was allocated for its filp */ +void nouveau_preclose(drm_device_t * dev, DRMFILE filp) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + + nouveau_mem_release(filp,dev_priv->fb_heap); + nouveau_mem_release(filp,dev_priv->agp_heap); + nouveau_fifo_cleanup(dev, filp); +} + +/* first module load, setup the mmio/fb mapping */ +int nouveau_firstopen(struct drm_device *dev) +{ + int ret; + + ret = nouveau_card_init(dev); + if (ret) { + DRM_ERROR("nouveau_card_init() failed! (%d)\n", ret); + return ret; + } return 0; } @@ -116,6 +235,7 @@ int nouveau_firstopen(struct drm_device *dev) int nouveau_load(struct drm_device *dev, unsigned long flags) { drm_nouveau_private_t *dev_priv; + int ret; if (flags==NV_UNKNOWN) return DRM_ERR(EINVAL); @@ -130,6 +250,14 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) dev->dev_private = (void *)dev_priv; +#if 0 + ret = nouveau_card_init(dev); + if (ret) { + DRM_ERROR("nouveau_card_init() failed! (%d)\n", ret); + return ret; + } +#endif + return 0; } @@ -244,3 +372,4 @@ void nouveau_wait_for_idle(struct drm_device *dev) } } + diff --git a/shared-core/nv04_fb.c b/shared-core/nv04_fb.c new file mode 100644 index 00000000..06b1c994 --- /dev/null +++ b/shared-core/nv04_fb.c @@ -0,0 +1,24 @@ +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" +#include "nouveau_drm.h" + +int +nv04_fb_init(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + + /* This is what the DDX did for NV_ARCH_04, but a mmio-trace shows + * nvidia reading PFB_CFG_0, then writing back its original value. + * (which was 0x701114 in this case) + */ + NV_WRITE(NV04_PFB_CFG0, 0x1114); + + return 0; +} + +void +nv04_fb_takedown(drm_device_t *dev) +{ +} + diff --git a/shared-core/nv04_graph.c b/shared-core/nv04_graph.c index 830d673e..cf4e58f6 100644 --- a/shared-core/nv04_graph.c +++ b/shared-core/nv04_graph.c @@ -222,13 +222,44 @@ int nv04_graph_context_create(drm_device_t *dev, int channel) { int nv04_graph_init(drm_device_t *dev) { drm_nouveau_private_t *dev_priv = dev->dev_private; + int i,sum=0; + + 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); // check the context is big enough - int i,sum=0; for ( i = 0 ; isizeof(dev_priv->fifos[0].pgraph_ctx) ) DRM_ERROR("pgraph_ctx too small\n"); + + NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000); + NV_WRITE(NV03_PGRAPH_INTR , 0xFFFFFFFF); + + NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x000001FF); + NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x1230C000); + NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x72111101); + NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x11D5F071); + NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x0004FF31); + NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x4004FF31 | + (0x00D00000) | + (1<<29) | + (1<<31)); + + NV_WRITE(NV04_PGRAPH_STATE , 0xFFFFFFFF); + NV_WRITE(NV04_PGRAPH_CTX_CONTROL , 0x10010100); + NV_WRITE(NV04_PGRAPH_FIFO , 0x00000001); + + /* These don't belong here, they're part of a per-channel context */ + NV_WRITE(NV04_PGRAPH_PATTERN_SHAPE, 0x00000000); + NV_WRITE(NV04_PGRAPH_BETA_AND , 0xFFFFFFFF); + return 0; } +void nv04_graph_takedown(drm_device_t *dev) +{ +} + diff --git a/shared-core/nv04_mc.c b/shared-core/nv04_mc.c new file mode 100644 index 00000000..2619eb71 --- /dev/null +++ b/shared-core/nv04_mc.c @@ -0,0 +1,20 @@ +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" +#include "nouveau_drm.h" + +int +nv04_mc_init(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + + NV_WRITE(NV03_PMC_INTR_EN_0, 0); + + return 0; +} + +void +nv04_mc_takedown(drm_device_t *dev) +{ +} + diff --git a/shared-core/nv04_timer.c b/shared-core/nv04_timer.c new file mode 100644 index 00000000..a4b4e826 --- /dev/null +++ b/shared-core/nv04_timer.c @@ -0,0 +1,24 @@ +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" +#include "nouveau_drm.h" + +int +nv04_timer_init(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + + NV_WRITE(NV04_PTIMER_INTR_EN_0, 0x00000000); + NV_WRITE(NV04_PTIMER_INTR_0, 0xFFFFFFFF); + + NV_WRITE(NV04_PTIMER_NUMERATOR, 0x00000008); + NV_WRITE(NV04_PTIMER_DENOMINATOR, 0x00000003); + + return 0; +} + +void +nv04_timer_takedown(drm_device_t *dev) +{ +} + diff --git a/shared-core/nv10_fb.c b/shared-core/nv10_fb.c new file mode 100644 index 00000000..e8336a2d --- /dev/null +++ b/shared-core/nv10_fb.c @@ -0,0 +1,26 @@ +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" +#include "nouveau_drm.h" + +int +nv10_fb_init(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + uint32_t fb_bar_size; + int i; + + fb_bar_size = drm_get_resource_len(dev, 0) - 1; + for (i=0; idev_private; + uint32_t tmp, vramsz; + int 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); + + NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000); + NV_WRITE(NV03_PGRAPH_INTR , 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_2, 0x24E00810); + NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x55DE0030 | + (1<<29) | + (1<<31)); + + /* copy tile info from PFB */ + for (i=0; idev_private; int i; + uint32_t tmp, vramsz; + + 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; @@ -151,5 +157,78 @@ int nv20_graph_init(drm_device_t *dev) { //XXX need to be done and save/restore for each fifo ??? nv20_graph_rdi(dev); + NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000); + NV_WRITE(NV03_PGRAPH_INTR , 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, 0xF20E0431); + 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); + NV_WRITE(0x400094, 0x00000005); + NV_WRITE(0x400B80, 0x45CAA208); + 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; idev_private; + uint32_t vramsz, tmp; int 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; dev_priv->ctx_table = nouveau_instmem_alloc(dev, dev_priv->ctx_table_size, 4); @@ -149,6 +155,68 @@ int nv30_graph_init(drm_device_t *dev) NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_TABLE, nouveau_chip_instance_get(dev, dev_priv->ctx_table)); + NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000); + NV_WRITE(NV03_PGRAPH_INTR , 0xFFFFFFFF); + + NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); + NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000); + NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x401287c0); + NV_WRITE(0x400890, 0x00140000); + NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xf0de0475); + NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x10008000); + NV_WRITE(NV04_PGRAPH_LIMIT_VIOL_PIX, 0xf04b1f36); + NV_WRITE(0x400B80, 0x1003d888); + NV_WRITE(0x400B84, 0x0c000000); + NV_WRITE(0x400B88, 0x62ff0f7f); + NV_WRITE(0x400098, 0x000000c0); + NV_WRITE(0x40009C, 0x0005dc00); + NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x62ff0f7f); + NV_WRITE(0x4000a0, 0x00000000); + NV_WRITE(0x4000a4, 0x00000008); + + /* copy tile info from PFB */ + for (i=0; idev_private; + uint32_t fb_bar_size, tmp; + int num_tiles; + int i; + + switch (dev_priv->chipset) { + case 0x40: + case 0x45: + tmp = NV_READ(NV10_PFB_CLOSE_PAGE2); + NV_WRITE(NV10_PFB_CLOSE_PAGE2, tmp & ~(1<<15)); + num_tiles = NV10_PFB_TILE__SIZE; + break; + case 0x46: /* G72 */ + case 0x47: /* G70 */ + case 0x49: /* G71 */ + case 0x4b: /* G73 */ + case 0x4c: /* C51 (G7X version) */ + num_tiles = NV40_PFB_TILE__SIZE_1; + break; + default: + num_tiles = NV40_PFB_TILE__SIZE_0; + break; + } + + fb_bar_size = drm_get_resource_len(dev, 0) - 1; + switch (dev_priv->chipset) { + case 0x40: + for (i=0; idev_private; uint32_t *ctx_voodoo; - int i; + uint32_t vramsz, tmp; + int i, j; + + 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); switch (dev_priv->chipset) { case 0x40: ctx_voodoo = nv40_ctx_voodoo; break; @@ -923,6 +937,194 @@ nv40_graph_init(drm_device_t *dev) /* No context present currently */ NV_WRITE(0x40032C, 0x00000000); + NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000); + NV_WRITE(NV03_PGRAPH_INTR , 0xFFFFFFFF); + + NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); + NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000); + NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x401287c0); + NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xe0de8055); + NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x00008000); + NV_WRITE(NV04_PGRAPH_LIMIT_VIOL_PIX, 0x00be3c5f); + + NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10010100); + NV_WRITE(NV10_PGRAPH_STATE , 0xFFFFFFFF); + NV_WRITE(NV04_PGRAPH_FIFO , 0x00000001); + + j = NV_READ(0x1540) & 0xff; + if (j) { + for (i=0; !(j&1); j>>=1, i++); + NV_WRITE(0x405000, i); + } + + if (dev_priv->chipset == 0x40) { + NV_WRITE(0x4009b0, 0x83280fff); + NV_WRITE(0x4009b4, 0x000000a0); + } else { + NV_WRITE(0x400820, 0x83280eff); + NV_WRITE(0x400824, 0x000000a0); + } + + switch (dev_priv->chipset) { + case 0x40: + case 0x45: + NV_WRITE(0x4009b8, 0x0078e366); + NV_WRITE(0x4009bc, 0x0000014c); + break; + case 0x41: + case 0x42: /* pciid also 0x00Cx */ +// case 0x0120: //XXX (pciid) + NV_WRITE(0x400828, 0x007596ff); + NV_WRITE(0x40082c, 0x00000108); + break; + case 0x43: + NV_WRITE(0x400828, 0x0072cb77); + NV_WRITE(0x40082c, 0x00000108); + break; + case 0x44: + case 0x46: /* G72 */ + case 0x4a: + case 0x4c: /* G7x-based C51 */ + case 0x4e: + NV_WRITE(0x400860, 0); + NV_WRITE(0x400864, 0); + break; + case 0x47: /* G70 */ + case 0x49: /* G71 */ + case 0x4b: /* G73 */ + NV_WRITE(0x400828, 0x07830610); + NV_WRITE(0x40082c, 0x0000016A); + break; + default: + break; + } + + NV_WRITE(0x400b38, 0x2ffff800); + NV_WRITE(0x400b3c, 0x00006000); + + /* copy tile info from PFB */ + switch (dev_priv->chipset) { + case 0x40: /* vanilla NV40 */ + for (i=0; ichipset) { + case 0x40: + NV_WRITE(0x4009A4, NV_READ(NV04_PFB_CFG0)); + NV_WRITE(0x4009A8, NV_READ(NV04_PFB_CFG1)); + NV_WRITE(0x4069A4, NV_READ(NV04_PFB_CFG0)); + NV_WRITE(0x4069A8, NV_READ(NV04_PFB_CFG1)); + NV_WRITE(0x400820, 0); + NV_WRITE(0x400824, 0); + NV_WRITE(0x400864, vramsz); + NV_WRITE(0x400868, vramsz); + break; + default: + switch (dev_priv->chipset) { + case 0x46: + case 0x47: + case 0x49: + case 0x4b: + NV_WRITE(0x400DF0, NV_READ(NV04_PFB_CFG0)); + NV_WRITE(0x400DF4, NV_READ(NV04_PFB_CFG1)); + break; + default: + NV_WRITE(0x4009F0, NV_READ(NV04_PFB_CFG0)); + NV_WRITE(0x4009F4, NV_READ(NV04_PFB_CFG1)); + break; + } + NV_WRITE(0x4069F0, NV_READ(NV04_PFB_CFG0)); + NV_WRITE(0x4069F4, NV_READ(NV04_PFB_CFG1)); + NV_WRITE(0x400840, 0); + NV_WRITE(0x400844, 0); + NV_WRITE(0x4008A0, vramsz); + NV_WRITE(0x4008A4, vramsz); + break; + } + + /* per-context state, doesn't belong here */ + NV_WRITE(0x400B20, 0x00000000); + NV_WRITE(0x400B04, 0xFFFFFFFF); + + 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); + + 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; } +void nv40_graph_takedown(drm_device_t *dev) +{ +} + diff --git a/shared-core/nv40_mc.c b/shared-core/nv40_mc.c new file mode 100644 index 00000000..554a2241 --- /dev/null +++ b/shared-core/nv40_mc.c @@ -0,0 +1,36 @@ +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" +#include "nouveau_drm.h" + +int +nv40_mc_init(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + uint32_t tmp; + + NV_WRITE(NV03_PMC_INTR_EN_0, 0); + + switch (dev_priv->chipset) { + case 0x44: + case 0x46: /* G72 */ + case 0x4e: + case 0x4c: /* C51_G7X */ + tmp = NV_READ(NV40_PFB_020C); + NV_WRITE(NV40_PMC_1700, tmp); + NV_WRITE(NV40_PMC_1704, 0); + NV_WRITE(NV40_PMC_1708, 0); + NV_WRITE(NV40_PMC_170C, tmp); + break; + default: + break; + } + + return 0; +} + +void +nv40_mc_takedown(drm_device_t *dev) +{ +} + -- cgit v1.2.3