diff options
31 files changed, 1327 insertions, 270 deletions
diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index 81a94331..6f5b021b 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -21,7 +21,11 @@ i810-objs := i810_drv.o i810_dma.o i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_fence.o \ i915_buffer.o nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \ - nouveau_object.o nouveau_irq.o nv04_graph.o nv10_graph.o nv20_graph.o nv30_graph.o \ + nouveau_object.o nouveau_irq.o \ + nv04_timer.o \ + nv04_mc.o nv40_mc.o \ + nv04_fb.o nv10_fb.o nv40_fb.o \ + nv04_graph.o nv10_graph.o nv20_graph.o nv30_graph.o \ nv40_graph.o radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o sis-objs := sis_drv.o sis_mm.o diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index d3e89af6..1bdc6fef 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -832,6 +832,9 @@ int drm_bo_mem_space(drm_buffer_object_t * bo, mem_type = prios[i]; man = &bm->man[mem_type]; + if (!man->has_type) + continue; + if (!drm_bo_mt_compatible(man, mem_type, mem->mask, &cur_flags)) continue; diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c index 3521c092..d400a4d5 100644 --- a/linux-core/drm_fops.c +++ b/linux-core/drm_fops.c @@ -154,10 +154,13 @@ int drm_open(struct inode *inode, struct file *filp) spin_lock(&dev->count_lock); if (!dev->open_count++) { spin_unlock(&dev->count_lock); - return drm_setup(dev); + retcode = drm_setup(dev); + goto out; } spin_unlock(&dev->count_lock); } + + out: mutex_lock(&dev->struct_mutex); BUG_ON((dev->dev_mapping != NULL) && (dev->dev_mapping != inode->i_mapping)); diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index 775ca878..54a0849f 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -596,13 +596,12 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) ) return drm_mmap_dma(filp, vma); - if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff , &hash)) { + if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash)) { DRM_ERROR("Could not find map\n"); return -EINVAL; } - map = drm_hash_entry(hash,drm_map_list_t, hash)->map; - + map = drm_hash_entry(hash, drm_map_list_t, hash)->map; if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) return -EPERM; @@ -647,16 +646,11 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) vma->vm_page_prot = drm_io_prot(map->type, vma); #ifdef __sparc__ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); +#endif if (io_remap_pfn_range(vma, vma->vm_start, - (map->offset + offset) >>PAGE_SHIFT, + (map->offset + offset) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) -#else - if (remap_pfn_range(vma, vma->vm_start, - (map->offset + offset) >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) -#endif return -EAGAIN; DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," " offset = 0x%lx\n", diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c index 56e5998f..7fdb0839 100644 --- a/linux-core/i915_drv.c +++ b/linux-core/i915_drv.c @@ -79,6 +79,7 @@ static struct drm_driver driver = { DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2, .load = i915_driver_load, + .firstopen = i915_driver_firstopen, .lastclose = i915_driver_lastclose, .preclose = i915_driver_preclose, .device_is_agp = i915_driver_device_is_agp, diff --git a/linux-core/nv04_fb.c b/linux-core/nv04_fb.c new file mode 120000 index 00000000..867e2007 --- /dev/null +++ b/linux-core/nv04_fb.c @@ -0,0 +1 @@ +../shared-core/nv04_fb.c
\ No newline at end of file diff --git a/linux-core/nv04_mc.c b/linux-core/nv04_mc.c new file mode 120000 index 00000000..32e91825 --- /dev/null +++ b/linux-core/nv04_mc.c @@ -0,0 +1 @@ +../shared-core/nv04_mc.c
\ No newline at end of file diff --git a/linux-core/nv04_timer.c b/linux-core/nv04_timer.c new file mode 120000 index 00000000..11108b2b --- /dev/null +++ b/linux-core/nv04_timer.c @@ -0,0 +1 @@ +../shared-core/nv04_timer.c
\ No newline at end of file diff --git a/linux-core/nv10_fb.c b/linux-core/nv10_fb.c new file mode 120000 index 00000000..f858c7c6 --- /dev/null +++ b/linux-core/nv10_fb.c @@ -0,0 +1 @@ +../shared-core/nv10_fb.c
\ No newline at end of file diff --git a/linux-core/nv40_fb.c b/linux-core/nv40_fb.c new file mode 120000 index 00000000..4a816b13 --- /dev/null +++ b/linux-core/nv40_fb.c @@ -0,0 +1 @@ +../shared-core/nv40_fb.c
\ No newline at end of file diff --git a/linux-core/nv40_mc.c b/linux-core/nv40_mc.c new file mode 120000 index 00000000..fff26494 --- /dev/null +++ b/linux-core/nv40_mc.c @@ -0,0 +1 @@ +../shared-core/nv40_mc.c
\ No newline at end of file diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index c8b7e588..9053f544 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -195,9 +195,6 @@ static int i915_initialize(drm_device_t * dev, I915_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); dev->dev_private = (void *)dev_priv; -#ifdef I915_HAVE_BUFFER - drm_bo_driver_init(dev); -#endif return 0; } @@ -949,3 +946,11 @@ int i915_driver_device_is_agp(drm_device_t * dev) { return 1; } + +int i915_driver_firstopen(struct drm_device *dev) +{ +#ifdef I915_HAVE_BUFFER + drm_bo_driver_init(dev); +#endif + return 0; +} diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 662ffad6..e8a7be29 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -153,7 +153,7 @@ extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, extern void i915_emit_breadcrumb(drm_device_t *dev); extern void i915_dispatch_flip(drm_device_t * dev, int pipes, int sync); extern int i915_emit_mi_flush(drm_device_t *dev, uint32_t flush); - +extern int i915_driver_firstopen(struct drm_device *dev); /* i915_irq.c */ extern int i915_irq_emit(DRM_IOCTL_ARGS); 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 <NV40 cards?, and does RAMIN * exist in vram on those cards as well? */ dev_priv->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); i<dev_priv->ramin_size; i+=4) + DRM_WRITE32(dev_priv->ramin, i, 0x00000000); + } else { + for (i=(64*1024); i<dev_priv->ramin_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..0cd4d3b8 100644 --- a/shared-core/nv04_graph.c +++ b/shared-core/nv04_graph.c @@ -32,122 +32,259 @@ struct reg_interval uint32_t reg; int number; } nv04_graph_ctx_regs [] = { - {NV04_PGRAPH_CTX_SWITCH1, 1}, - {NV04_PGRAPH_CTX_SWITCH2, 1}, - {NV04_PGRAPH_CTX_SWITCH3, 1}, - {NV04_PGRAPH_CTX_SWITCH4, 1}, - {NV04_PGRAPH_CTX_USER, 1}, - {NV04_PGRAPH_CTX_CACHE1, 8}, - {NV04_PGRAPH_CTX_CACHE2, 8}, - {NV04_PGRAPH_CTX_CACHE3, 8}, - {NV04_PGRAPH_CTX_CACHE4, 8}, - {NV03_PGRAPH_ABS_X_RAM, 32}, - {NV03_PGRAPH_ABS_Y_RAM, 32}, - {NV03_PGRAPH_X_MISC, 1}, - {NV03_PGRAPH_Y_MISC, 1}, - {NV04_PGRAPH_VALID1, 1}, - {NV04_PGRAPH_SOURCE_COLOR, 1}, - {NV04_PGRAPH_MISC24_0, 1}, - {NV03_PGRAPH_XY_LOGIC_MISC0, 1}, - {NV03_PGRAPH_XY_LOGIC_MISC1, 1}, - {NV03_PGRAPH_XY_LOGIC_MISC2, 1}, - {NV03_PGRAPH_XY_LOGIC_MISC3, 1}, - {NV03_PGRAPH_CLIPX_0, 1}, - {NV03_PGRAPH_CLIPX_1, 1}, - {NV03_PGRAPH_CLIPY_0, 1}, - {NV03_PGRAPH_CLIPY_1, 1}, - {NV03_PGRAPH_ABS_ICLIP_XMAX, 1}, - {NV03_PGRAPH_ABS_ICLIP_YMAX, 1}, - {NV03_PGRAPH_ABS_UCLIP_XMIN, 1}, - {NV03_PGRAPH_ABS_UCLIP_YMIN, 1}, - {NV03_PGRAPH_ABS_UCLIP_XMAX, 1}, - {NV03_PGRAPH_ABS_UCLIP_YMAX, 1}, - {NV03_PGRAPH_ABS_UCLIPA_XMIN, 1}, - {NV03_PGRAPH_ABS_UCLIPA_YMIN, 1}, - {NV03_PGRAPH_ABS_UCLIPA_XMAX, 1}, - {NV03_PGRAPH_ABS_UCLIPA_YMAX, 1}, - {NV04_PGRAPH_MISC24_1, 1}, - {NV04_PGRAPH_MISC24_2, 1}, - {NV04_PGRAPH_VALID2, 1}, - {NV04_PGRAPH_PASSTHRU_0, 1}, - {NV04_PGRAPH_PASSTHRU_1, 1}, - {NV04_PGRAPH_PASSTHRU_2, 1}, - {NV04_PGRAPH_COMBINE_0_ALPHA, 1}, - {NV04_PGRAPH_COMBINE_0_COLOR, 1}, - {NV04_PGRAPH_COMBINE_1_ALPHA, 1}, - {NV04_PGRAPH_COMBINE_1_COLOR, 1}, - // texture state - {NV04_PGRAPH_FORMAT_0, 1}, - {NV04_PGRAPH_FORMAT_1, 1}, - {NV04_PGRAPH_FILTER_0, 1}, - {NV04_PGRAPH_FILTER_1, 1}, - // vertex state - {0x004005c0, 1}, - {0x004005c4, 1}, - {0x004005c8, 1}, - {0x004005cc, 1}, - {0x004005d0, 1}, - {0x004005d4, 1}, - {0x004005d8, 1}, - {0x004005dc, 1}, - {0x004005e0, 1}, - {NV03_PGRAPH_MONO_COLOR0, 1}, - {NV04_PGRAPH_ROP3, 1}, - {NV04_PGRAPH_BETA_AND, 1}, - {NV04_PGRAPH_BETA_PREMULT, 1}, - {NV04_PGRAPH_FORMATS, 1}, - {NV04_PGRAPH_BOFFSET0, 6}, - {NV04_PGRAPH_BBASE0, 6}, - {NV04_PGRAPH_BPITCH0, 5}, - {NV04_PGRAPH_BLIMIT0, 6}, - {NV04_PGRAPH_BSWIZZLE2, 1}, - {NV04_PGRAPH_BSWIZZLE5, 1}, - {NV04_PGRAPH_SURFACE, 1}, - {NV04_PGRAPH_STATE, 1}, - {NV04_PGRAPH_NOTIFY, 1}, - {NV04_PGRAPH_BPIXEL, 1}, - {NV04_PGRAPH_DMA_PITCH, 1}, - {NV04_PGRAPH_DVD_COLORFMT, 1}, - {NV04_PGRAPH_SCALED_FORMAT, 1}, - {NV04_PGRAPH_PATT_COLOR0, 1}, - {NV04_PGRAPH_PATT_COLOR1, 1}, - {NV04_PGRAPH_PATTERN, 2}, - {NV04_PGRAPH_PATTERN_SHAPE, 1}, - {NV04_PGRAPH_CHROMA, 1}, - {NV04_PGRAPH_CONTROL0, 1}, - {NV04_PGRAPH_CONTROL1, 1}, - {NV04_PGRAPH_CONTROL2, 1}, - {NV04_PGRAPH_BLEND, 1}, - {NV04_PGRAPH_STORED_FMT, 1}, - {NV04_PGRAPH_PATT_COLORRAM, 64}, - {NV04_PGRAPH_U_RAM, 16}, - {NV04_PGRAPH_V_RAM, 16}, - {NV04_PGRAPH_W_RAM, 16}, - {NV04_PGRAPH_DMA_START_0, 1}, - {NV04_PGRAPH_DMA_START_1, 1}, - {NV04_PGRAPH_DMA_LENGTH, 1}, - {NV04_PGRAPH_DMA_MISC, 1}, - {NV04_PGRAPH_DMA_DATA_0, 1}, - {NV04_PGRAPH_DMA_DATA_1, 1}, - {NV04_PGRAPH_DMA_RM, 1}, - {NV04_PGRAPH_DMA_A_XLATE_INST, 1}, - {NV04_PGRAPH_DMA_A_CONTROL, 1}, - {NV04_PGRAPH_DMA_A_LIMIT, 1}, - {NV04_PGRAPH_DMA_A_TLB_PTE, 1}, - {NV04_PGRAPH_DMA_A_TLB_TAG, 1}, - {NV04_PGRAPH_DMA_A_ADJ_OFFSET, 1}, - {NV04_PGRAPH_DMA_A_OFFSET, 1}, - {NV04_PGRAPH_DMA_A_SIZE, 1}, - {NV04_PGRAPH_DMA_A_Y_SIZE, 1}, - {NV04_PGRAPH_DMA_B_XLATE_INST, 1}, - {NV04_PGRAPH_DMA_B_CONTROL, 1}, - {NV04_PGRAPH_DMA_B_LIMIT, 1}, - {NV04_PGRAPH_DMA_B_TLB_PTE, 1}, - {NV04_PGRAPH_DMA_B_TLB_TAG, 1}, - {NV04_PGRAPH_DMA_B_ADJ_OFFSET, 1}, - {NV04_PGRAPH_DMA_B_OFFSET, 1}, - {NV04_PGRAPH_DMA_B_SIZE, 1}, - {NV04_PGRAPH_DMA_B_Y_SIZE, 1}, + {NV04_PGRAPH_CTX_SWITCH1,1}, + {NV04_PGRAPH_CTX_SWITCH2,1}, + {NV04_PGRAPH_CTX_SWITCH3,1}, + {NV04_PGRAPH_CTX_SWITCH4,1}, + {NV04_PGRAPH_CTX_CACHE1,1}, + {NV04_PGRAPH_CTX_CACHE2,1}, + {NV04_PGRAPH_CTX_CACHE3,1}, + {NV04_PGRAPH_CTX_CACHE4,1}, + {0x00400184,1}, + {0x004001a4,1}, + {0x004001c4,1}, + {0x004001e4,1}, + {0x00400188,1}, + {0x004001a8,1}, + {0x004001c8,1}, + {0x004001e8,1}, + {0x0040018c,1}, + {0x004001ac,1}, + {0x004001cc,1}, + {0x004001ec,1}, + {0x00400190,1}, + {0x004001b0,1}, + {0x004001d0,1}, + {0x004001f0,1}, + {0x00400194,1}, + {0x004001b4,1}, + {0x004001d4,1}, + {0x004001f4,1}, + {0x00400198,1}, + {0x004001b8,1}, + {0x004001d8,1}, + {0x004001f8,1}, + {0x0040019c,1}, + {0x004001bc,1}, + {0x004001dc,1}, + {0x004001fc,1}, + {0x00400174,1}, + {NV04_PGRAPH_DMA_START_0,1}, + {NV04_PGRAPH_DMA_START_1,1}, + {NV04_PGRAPH_DMA_LENGTH,1}, + {NV04_PGRAPH_DMA_MISC,1}, + {NV04_PGRAPH_DMA_PITCH,1}, + {NV04_PGRAPH_BOFFSET0,1}, + {NV04_PGRAPH_BBASE0,1}, + {NV04_PGRAPH_BLIMIT0,1}, + {NV04_PGRAPH_BOFFSET1,1}, + {NV04_PGRAPH_BBASE1,1}, + {NV04_PGRAPH_BLIMIT1,1}, + {NV04_PGRAPH_BOFFSET2,1}, + {NV04_PGRAPH_BBASE2,1}, + {NV04_PGRAPH_BLIMIT2,1}, + {NV04_PGRAPH_BOFFSET3,1}, + {NV04_PGRAPH_BBASE3,1}, + {NV04_PGRAPH_BLIMIT3,1}, + {NV04_PGRAPH_BOFFSET4,1}, + {NV04_PGRAPH_BBASE4,1}, + {NV04_PGRAPH_BLIMIT4,1}, + {NV04_PGRAPH_BOFFSET5,1}, + {NV04_PGRAPH_BBASE5,1}, + {NV04_PGRAPH_BLIMIT5,1}, + {NV04_PGRAPH_BPITCH0,1}, + {NV04_PGRAPH_BPITCH1,1}, + {NV04_PGRAPH_BPITCH2,1}, + {NV04_PGRAPH_BPITCH3,1}, + {NV04_PGRAPH_BPITCH4,1}, + {NV04_PGRAPH_SURFACE,1}, + {NV04_PGRAPH_STATE,1}, + {NV04_PGRAPH_BSWIZZLE2,1}, + {NV04_PGRAPH_BSWIZZLE5,1}, + {NV04_PGRAPH_BPIXEL,1}, + {NV04_PGRAPH_NOTIFY,1}, + {NV04_PGRAPH_PATT_COLOR0,1}, + {NV04_PGRAPH_PATT_COLOR1,1}, + {NV04_PGRAPH_PATT_COLORRAM,64}, + {NV04_PGRAPH_PATTERN,1}, + {0x0040080c,1}, + {NV04_PGRAPH_PATTERN_SHAPE,1}, + {0x00400600,1}, + {NV04_PGRAPH_ROP3,1}, + {NV04_PGRAPH_CHROMA,1}, + {NV04_PGRAPH_BETA_AND,1}, + {NV04_PGRAPH_BETA_PREMULT,1}, + {NV04_PGRAPH_CONTROL0,1}, + {NV04_PGRAPH_CONTROL1,1}, + {NV04_PGRAPH_CONTROL2,1}, + {NV04_PGRAPH_BLEND,1}, + {NV04_PGRAPH_STORED_FMT,1}, + {NV04_PGRAPH_SOURCE_COLOR,1}, + {0x00400560,1}, + {0x00400568,1}, + {0x00400564,1}, + {0x0040056c,1}, + {0x00400400,1}, + {0x00400480,1}, + {0x00400404,1}, + {0x00400484,1}, + {0x00400408,1}, + {0x00400488,1}, + {0x0040040c,1}, + {0x0040048c,1}, + {0x00400410,1}, + {0x00400490,1}, + {0x00400414,1}, + {0x00400494,1}, + {0x00400418,1}, + {0x00400498,1}, + {0x0040041c,1}, + {0x0040049c,1}, + {0x00400420,1}, + {0x004004a0,1}, + {0x00400424,1}, + {0x004004a4,1}, + {0x00400428,1}, + {0x004004a8,1}, + {0x0040042c,1}, + {0x004004ac,1}, + {0x00400430,1}, + {0x004004b0,1}, + {0x00400434,1}, + {0x004004b4,1}, + {0x00400438,1}, + {0x004004b8,1}, + {0x0040043c,1}, + {0x004004bc,1}, + {0x00400440,1}, + {0x004004c0,1}, + {0x00400444,1}, + {0x004004c4,1}, + {0x00400448,1}, + {0x004004c8,1}, + {0x0040044c,1}, + {0x004004cc,1}, + {0x00400450,1}, + {0x004004d0,1}, + {0x00400454,1}, + {0x004004d4,1}, + {0x00400458,1}, + {0x004004d8,1}, + {0x0040045c,1}, + {0x004004dc,1}, + {0x00400460,1}, + {0x004004e0,1}, + {0x00400464,1}, + {0x004004e4,1}, + {0x00400468,1}, + {0x004004e8,1}, + {0x0040046c,1}, + {0x004004ec,1}, + {0x00400470,1}, + {0x004004f0,1}, + {0x00400474,1}, + {0x004004f4,1}, + {0x00400478,1}, + {0x004004f8,1}, + {0x0040047c,1}, + {0x004004fc,1}, + {0x0040053c,1}, + {0x00400544,1}, + {0x00400540,1}, + {0x00400548,1}, + {0x00400560,1}, + {0x00400568,1}, + {0x00400564,1}, + {0x0040056c,1}, + {0x00400534,1}, + {0x00400538,1}, + {0x00400514,1}, + {0x00400518,1}, + {0x0040051c,1}, + {0x00400520,1}, + {0x00400524,1}, + {0x00400528,1}, + {0x0040052c,1}, + {0x00400530,1}, + {0x00400d00,1}, + {0x00400d40,1}, + {0x00400d80,1}, + {0x00400d04,1}, + {0x00400d44,1}, + {0x00400d84,1}, + {0x00400d08,1}, + {0x00400d48,1}, + {0x00400d88,1}, + {0x00400d0c,1}, + {0x00400d4c,1}, + {0x00400d8c,1}, + {0x00400d10,1}, + {0x00400d50,1}, + {0x00400d90,1}, + {0x00400d14,1}, + {0x00400d54,1}, + {0x00400d94,1}, + {0x00400d18,1}, + {0x00400d58,1}, + {0x00400d98,1}, + {0x00400d1c,1}, + {0x00400d5c,1}, + {0x00400d9c,1}, + {0x00400d20,1}, + {0x00400d60,1}, + {0x00400da0,1}, + {0x00400d24,1}, + {0x00400d64,1}, + {0x00400da4,1}, + {0x00400d28,1}, + {0x00400d68,1}, + {0x00400da8,1}, + {0x00400d2c,1}, + {0x00400d6c,1}, + {0x00400dac,1}, + {0x00400d30,1}, + {0x00400d70,1}, + {0x00400db0,1}, + {0x00400d34,1}, + {0x00400d74,1}, + {0x00400db4,1}, + {0x00400d38,1}, + {0x00400d78,1}, + {0x00400db8,1}, + {0x00400d3c,1}, + {0x00400d7c,1}, + {0x00400dbc,1}, + {0x00400590,1}, + {0x00400594,1}, + {0x00400598,1}, + {0x0040059c,1}, + {0x004005a8,1}, + {0x004005ac,1}, + {0x004005b0,1}, + {0x004005b4,1}, + {0x004005c0,1}, + {0x004005c4,1}, + {0x004005c8,1}, + {0x004005cc,1}, + {0x004005d0,1}, + {0x004005d4,1}, + {0x004005d8,1}, + {0x004005dc,1}, + {0x004005e0,1}, + {NV04_PGRAPH_PASSTHRU_0,1}, + {NV04_PGRAPH_PASSTHRU_1,1}, + {NV04_PGRAPH_PASSTHRU_2,1}, + {NV04_PGRAPH_DVD_COLORFMT,1}, + {NV04_PGRAPH_SCALED_FORMAT,1}, + {NV04_PGRAPH_MISC24_0,1}, + {NV04_PGRAPH_MISC24_1,1}, + {NV04_PGRAPH_MISC24_2,1}, + {0x00400500,1}, + {0x00400504,1}, + {NV04_PGRAPH_VALID1,1}, + {NV04_PGRAPH_VALID2,1} + + }; void nouveau_nv04_context_switch(drm_device_t *dev) @@ -158,13 +295,15 @@ void nouveau_nv04_context_switch(drm_device_t *dev) channel=NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1); channel_old = (NV_READ(NV04_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1); - DRM_INFO("NV: PGRAPH context switch interrupt channel %x -> %x\n",channel_old, channel); + DRM_DEBUG("NV: PGRAPH context switch interrupt channel %x -> %x\n",channel_old, channel); NV_WRITE(NV03_PFIFO_CACHES, 0x0); NV_WRITE(NV04_PFIFO_CACHE0_PULL0, 0x0); NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x0); NV_WRITE(NV04_PGRAPH_FIFO,0x0); + nouveau_wait_for_idle(dev); + // save PGRAPH context index=0; for (i = 0; i<sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0]); i++) @@ -174,15 +313,10 @@ void nouveau_nv04_context_switch(drm_device_t *dev) index++; } - nouveau_wait_for_idle(dev); - NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10000000); NV_WRITE(NV04_PGRAPH_CTX_USER, (NV_READ(NV04_PGRAPH_CTX_USER) & 0xffffff) | (0x0f << 24)); - nouveau_wait_for_idle(dev); // restore PGRAPH context - //XXX not working yet -#if 1 index=0; for (i = 0; i<sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0]); i++) for (j = 0; j<nv04_graph_ctx_regs[i].number; j++) @@ -190,12 +324,10 @@ void nouveau_nv04_context_switch(drm_device_t *dev) NV_WRITE(nv04_graph_ctx_regs[i].reg+j*4, dev_priv->fifos[channel].pgraph_ctx[index]); index++; } - nouveau_wait_for_idle(dev); -#endif NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10010100); NV_WRITE(NV04_PGRAPH_CTX_USER, channel << 24); - NV_WRITE(NV04_PGRAPH_FFINTFC_ST2, NV_READ(NV04_PGRAPH_FFINTFC_ST2)&0xCFFFFFFF); + NV_WRITE(NV04_PGRAPH_FFINTFC_ST2, NV_READ(NV04_PGRAPH_FFINTFC_ST2)&0x000FFFFF); NV_WRITE(NV04_PGRAPH_FIFO,0x0); NV_WRITE(NV04_PFIFO_CACHE0_PULL0, 0x0); @@ -222,13 +354,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 ; i<sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0]); i++) sum+=nv04_graph_ctx_regs[i].number; if ( sum*4>sizeof(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; i<NV10_PFB_TILE__SIZE; i++) { + NV_WRITE(NV10_PFB_TILE(i), 0); + NV_WRITE(NV10_PFB_TLIMIT(i), fb_bar_size); + } + + return 0; +} + +void +nv10_fb_takedown(drm_device_t *dev) +{ +} + diff --git a/shared-core/nv10_graph.c b/shared-core/nv10_graph.c index ad74b840..3ca843d4 100644 --- a/shared-core/nv10_graph.c +++ b/shared-core/nv10_graph.c @@ -605,5 +605,58 @@ int nv10_graph_context_create(drm_device_t *dev, int channel) { int nv10_graph_init(drm_device_t *dev) { + drm_nouveau_private_t *dev_priv = dev->dev_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; i<NV10_PFB_TILE__SIZE; i++) { + NV_WRITE(NV10_PGRAPH_TILE(i), NV_READ(NV10_PFB_TILE(i))); + NV_WRITE(NV10_PGRAPH_TLIMIT(i), NV_READ(NV10_PFB_TLIMIT(i))); + NV_WRITE(NV10_PGRAPH_TSIZE(i), NV_READ(NV10_PFB_TSIZE(i))); + NV_WRITE(NV10_PGRAPH_TSTATUS(i), NV_READ(NV10_PFB_TSTATUS(i))); + } + + NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10010100); + NV_WRITE(NV10_PGRAPH_STATE , 0xFFFFFFFF); + NV_WRITE(NV04_PGRAPH_FIFO , 0x00000001); + + /* the below don't belong here, per-channel context state */ + 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); + + vramsz = drm_get_resource_len(dev, 0) - 1; + NV_WRITE(NV04_PGRAPH_BOFFSET0, 0); + NV_WRITE(NV04_PGRAPH_BOFFSET1, 0); + NV_WRITE(NV04_PGRAPH_BLIMIT0 , vramsz); + NV_WRITE(NV04_PGRAPH_BLIMIT1 , vramsz); + + NV_WRITE(NV04_PGRAPH_PATTERN_SHAPE, 0x00000000); + NV_WRITE(NV04_PGRAPH_BETA_AND , 0xFFFFFFFF); + return 0; + } + +void nv10_graph_takedown(drm_device_t *dev) +{ +} + diff --git a/shared-core/nv20_graph.c b/shared-core/nv20_graph.c index 9ba6a873..45d88d6b 100644 --- a/shared-core/nv20_graph.c +++ b/shared-core/nv20_graph.c @@ -136,6 +136,12 @@ int nv20_graph_init(drm_device_t *dev) { drm_nouveau_private_t *dev_priv = (drm_nouveau_private_t *)dev->dev_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; i<NV10_PFB_TILE__SIZE; i++) { + NV_WRITE(NV10_PGRAPH_TILE(i), NV_READ(NV10_PFB_TILE(i))); + NV_WRITE(NV10_PGRAPH_TLIMIT(i), NV_READ(NV10_PFB_TLIMIT(i))); + NV_WRITE(NV10_PGRAPH_TSIZE(i), NV_READ(NV10_PFB_TSIZE(i))); + NV_WRITE(NV10_PGRAPH_TSTATUS(i), NV_READ(NV10_PFB_TSTATUS(i))); + } + + NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10010100); + 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; } + +void nv20_graph_takedown(drm_device_t *dev) +{ +} + diff --git a/shared-core/nv30_graph.c b/shared-core/nv30_graph.c index cb183bea..391a1063 100644 --- a/shared-core/nv30_graph.c +++ b/shared-core/nv30_graph.c @@ -136,8 +136,14 @@ int nv30_graph_init(drm_device_t *dev) { drm_nouveau_private_t *dev_priv = (drm_nouveau_private_t *)dev->dev_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; i<NV10_PFB_TILE__SIZE; i++) { + NV_WRITE(NV10_PGRAPH_TILE(i), NV_READ(NV10_PFB_TILE(i))); + NV_WRITE(NV10_PGRAPH_TLIMIT(i), NV_READ(NV10_PFB_TLIMIT(i))); + NV_WRITE(NV10_PGRAPH_TSIZE(i), NV_READ(NV10_PFB_TSIZE(i))); + NV_WRITE(NV10_PGRAPH_TSTATUS(i), NV_READ(NV10_PFB_TSTATUS(i))); + } + + NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10010100); + NV_WRITE(NV10_PGRAPH_STATE , 0xFFFFFFFF); + NV_WRITE(NV04_PGRAPH_FIFO , 0x00000001); + + /* 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(0x400750, 0x00EA0000); + NV_WRITE(0x400754, NV_READ(NV04_PFB_CFG0)); + NV_WRITE(0x400750, 0x00EA0004); + NV_WRITE(0x400754, NV_READ(NV04_PFB_CFG1)); + NV_WRITE(0x400820, 0); + NV_WRITE(0x400824, 0); + NV_WRITE(0x400864, vramsz-1); + NV_WRITE(0x400868, vramsz-1); + + NV_WRITE(0x400B20, 0x00000000); + NV_WRITE(0x400B04, 0xFFFFFFFF); + + /* per-context state, doesn't belong here */ + 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 nv30_graph_takedown(drm_device_t *dev) +{ +} + diff --git a/shared-core/nv40_fb.c b/shared-core/nv40_fb.c new file mode 100644 index 00000000..83a7580e --- /dev/null +++ b/shared-core/nv40_fb.c @@ -0,0 +1,56 @@ +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" +#include "nouveau_drm.h" + +int +nv40_fb_init(drm_device_t *dev) +{ + drm_nouveau_private_t *dev_priv = dev->dev_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; i<num_tiles; i++) { + NV_WRITE(NV10_PFB_TILE(i), 0); + NV_WRITE(NV10_PFB_TLIMIT(i), fb_bar_size); + } + break; + default: + for (i=0; i<num_tiles; i++) { + NV_WRITE(NV40_PFB_TILE(i), 0); + NV_WRITE(NV40_PFB_TLIMIT(i), fb_bar_size); + } + break; + } + + return 0; +} + +void +nv40_fb_takedown(drm_device_t *dev) +{ +} + diff --git a/shared-core/nv40_graph.c b/shared-core/nv40_graph.c index f2650ca1..510ffa76 100644 --- a/shared-core/nv40_graph.c +++ b/shared-core/nv40_graph.c @@ -887,14 +887,28 @@ static uint32_t nv4e_ctx_voodoo[] = { ~0 }; - +/* + * G70 0x47 + * G71 0x49 + * NV45 0x48 + * G72 0x46 + * G73 0x4b + * C51_G7X 0x4c + * C51 0x4e + */ int nv40_graph_init(drm_device_t *dev) { drm_nouveau_private_t *dev_priv = (drm_nouveau_private_t *)dev->dev_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; i<NV10_PFB_TILE__SIZE; i++) { + tmp = NV_READ(NV10_PFB_TILE(i)); + NV_WRITE(NV40_PGRAPH_TILE0(i), tmp); + NV_WRITE(NV40_PGRAPH_TILE1(i), tmp); + tmp = NV_READ(NV10_PFB_TLIMIT(i)); + NV_WRITE(NV40_PGRAPH_TLIMIT0(i), tmp); + NV_WRITE(NV40_PGRAPH_TLIMIT1(i), tmp); + tmp = NV_READ(NV10_PFB_TSIZE(i)); + NV_WRITE(NV40_PGRAPH_TSIZE0(i), tmp); + NV_WRITE(NV40_PGRAPH_TSIZE1(i), tmp); + tmp = NV_READ(NV10_PFB_TSTATUS(i)); + NV_WRITE(NV40_PGRAPH_TSTATUS0(i), tmp); + NV_WRITE(NV40_PGRAPH_TSTATUS1(i), tmp); + } + break; + case 0x44: + case 0x4a: + case 0x4e: /* NV44-based cores don't have 0x406900? */ + for (i=0; i<NV40_PFB_TILE__SIZE_0; i++) { + tmp = NV_READ(NV40_PFB_TILE(i)); + NV_WRITE(NV40_PGRAPH_TILE0(i), tmp); + tmp = NV_READ(NV40_PFB_TLIMIT(i)); + NV_WRITE(NV40_PGRAPH_TLIMIT0(i), tmp); + tmp = NV_READ(NV40_PFB_TSIZE(i)); + NV_WRITE(NV40_PGRAPH_TSIZE0(i), tmp); + tmp = NV_READ(NV40_PFB_TSTATUS(i)); + NV_WRITE(NV40_PGRAPH_TSTATUS0(i), tmp); + } + break; + case 0x46: + case 0x47: + case 0x49: + case 0x4b: /* G7X-based cores */ + for (i=0; i<NV40_PFB_TILE__SIZE_1; i++) { + tmp = NV_READ(NV40_PFB_TILE(i)); + NV_WRITE(NV47_PGRAPH_TILE0(i), tmp); + NV_WRITE(NV40_PGRAPH_TILE1(i), tmp); + tmp = NV_READ(NV40_PFB_TLIMIT(i)); + NV_WRITE(NV47_PGRAPH_TLIMIT0(i), tmp); + NV_WRITE(NV40_PGRAPH_TLIMIT1(i), tmp); + tmp = NV_READ(NV40_PFB_TSIZE(i)); + NV_WRITE(NV47_PGRAPH_TSIZE0(i), tmp); + NV_WRITE(NV40_PGRAPH_TSIZE1(i), tmp); + tmp = NV_READ(NV40_PFB_TSTATUS(i)); + NV_WRITE(NV47_PGRAPH_TSTATUS0(i), tmp); + NV_WRITE(NV40_PGRAPH_TSTATUS1(i), tmp); + } + break; + default: /* everything else */ + for (i=0; i<NV40_PFB_TILE__SIZE_0; i++) { + tmp = NV_READ(NV40_PFB_TILE(i)); + NV_WRITE(NV40_PGRAPH_TILE0(i), tmp); + NV_WRITE(NV40_PGRAPH_TILE1(i), tmp); + tmp = NV_READ(NV40_PFB_TLIMIT(i)); + NV_WRITE(NV40_PGRAPH_TLIMIT0(i), tmp); + NV_WRITE(NV40_PGRAPH_TLIMIT1(i), tmp); + tmp = NV_READ(NV40_PFB_TSIZE(i)); + NV_WRITE(NV40_PGRAPH_TSIZE0(i), tmp); + NV_WRITE(NV40_PGRAPH_TSIZE1(i), tmp); + tmp = NV_READ(NV40_PFB_TSTATUS(i)); + NV_WRITE(NV40_PGRAPH_TSTATUS0(i), tmp); + NV_WRITE(NV40_PGRAPH_TSTATUS1(i), tmp); + } + break; + } + + /* begin RAM config */ + vramsz = drm_get_resource_len(dev, 0) - 1; + switch (dev_priv->chipset) { + 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) +{ +} + |