Deblobbed. Adjusted for replacement of voodoo blobs with /*(DEBLOBBED)*/. commit 2ab03489c6a63b4861736f1904566c95098119bf Author: Dave Airlie Date: Mon Apr 14 13:38:40 2008 +1000 nouveau: update to latest drm diff --git a/drivers/char/drm/drm_mm.c b/drivers/char/drm/drm_mm.c index 369a052..7d8b670 100644 --- a/drivers/char/drm/drm_mm.c +++ b/drivers/char/drm/drm_mm.c @@ -217,6 +217,7 @@ void drm_mm_put_block(struct drm_mm_node * cur) drm_ctl_free(cur, sizeof(*cur), DRM_MEM_MM); } } +EXPORT_SYMBOL(drm_mm_put_block); struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm, unsigned long size, diff --git a/drivers/char/drm/nouveau_bo.c b/drivers/char/drm/nouveau_bo.c index 9407bd3..ab3b23a 100644 --- a/drivers/char/drm/nouveau_bo.c +++ b/drivers/char/drm/nouveau_bo.c @@ -198,8 +198,8 @@ nouveau_bo_move_m2mf(struct drm_buffer_object *bo, int evict, int no_wait, /* Flip pages into the GART and move if we can. */ static int -nouveau_bo_move_gart(struct drm_buffer_object *bo, int evict, int no_wait, - struct drm_bo_mem_reg *new_mem) +nouveau_bo_move_flipd(struct drm_buffer_object *bo, int evict, int no_wait, + struct drm_bo_mem_reg *new_mem) { struct drm_device *dev = bo->dev; struct drm_bo_mem_reg tmp_mem; @@ -212,11 +212,10 @@ nouveau_bo_move_gart(struct drm_buffer_object *bo, int evict, int no_wait, DRM_BO_FLAG_FORCE_CACHING); ret = drm_bo_mem_space(bo, &tmp_mem, no_wait); - if (ret) return ret; - ret = drm_ttm_bind (bo->ttm, &tmp_mem); + ret = drm_ttm_bind(bo->ttm, &tmp_mem); if (ret) goto out_cleanup; @@ -234,6 +233,7 @@ out_cleanup: tmp_mem.mm_node = NULL; mutex_unlock(&dev->struct_mutex); } + return ret; } @@ -246,16 +246,19 @@ nouveau_bo_move(struct drm_buffer_object *bo, int evict, int no_wait, if (new_mem->mem_type == DRM_BO_MEM_LOCAL) { if (old_mem->mem_type == DRM_BO_MEM_LOCAL) return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); + if (nouveau_bo_move_flipd(bo, evict, no_wait, new_mem)) return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); } else if (old_mem->mem_type == DRM_BO_MEM_LOCAL) { + if (1 /*nouveau_bo_move_flips(bo, evict, no_wait, new_mem)*/) return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); } else { -// if (nouveau_bo_move_m2mf(bo, evict, no_wait, new_mem)) + if (nouveau_bo_move_m2mf(bo, evict, no_wait, new_mem)) return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); } + return 0; } diff --git a/drivers/char/drm/nouveau_drm.h b/drivers/char/drm/nouveau_drm.h index 5f07fcb..cf76205 100644 --- a/drivers/char/drm/nouveau_drm.h +++ b/drivers/char/drm/nouveau_drm.h @@ -87,6 +87,10 @@ struct drm_nouveau_gpuobj_free { #define NOUVEAU_MEM_MAPPED 0x00000100 #define NOUVEAU_MEM_INSTANCE 0x00000200 /* internal */ #define NOUVEAU_MEM_NOTIFIER 0x00000400 /* internal */ +#define NOUVEAU_MEM_NOVM 0x00000800 /* internal */ +#define NOUVEAU_MEM_INTERNAL (NOUVEAU_MEM_INSTANCE | \ + NOUVEAU_MEM_NOTIFIER | \ + NOUVEAU_MEM_NOVM) struct drm_nouveau_mem_alloc { int flags; diff --git a/drivers/char/drm/nouveau_drv.h b/drivers/char/drm/nouveau_drv.h index c338964..a51e552 100644 --- a/drivers/char/drm/nouveau_drv.h +++ b/drivers/char/drm/nouveau_drv.h @@ -136,6 +136,7 @@ struct nouveau_channel /* NV50 VM */ struct nouveau_gpuobj *vm_pd; struct nouveau_gpuobj_ref *vm_gart_pt; + struct nouveau_gpuobj_ref *vm_vram_pt; /* Objects */ struct nouveau_gpuobj_ref *ramin; /* Private instmem */ @@ -290,6 +291,9 @@ struct drm_nouveau_private { unsigned long sg_handle; } gart_info; + /* G8x global VRAM page table */ + struct nouveau_gpuobj *vm_vram_pt; + /* the mtrr covering the FB */ int fb_mtrr; @@ -432,7 +436,7 @@ extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, /* nouveau_irq.c */ extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS); extern void nouveau_irq_preinstall(struct drm_device *); -extern void nouveau_irq_postinstall(struct drm_device *); +extern int nouveau_irq_postinstall(struct drm_device *); extern void nouveau_irq_uninstall(struct drm_device *); /* nouveau_sgdma.c */ diff --git a/drivers/char/drm/nouveau_fence.c b/drivers/char/drm/nouveau_fence.c index 59dcf7d..4ad51ae 100644 --- a/drivers/char/drm/nouveau_fence.c +++ b/drivers/char/drm/nouveau_fence.c @@ -80,12 +80,11 @@ nouveau_fence_poll(struct drm_device *dev, uint32_t class, uint32_t waiting_type struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_fence_class_manager *fc = &dev->fm.fence_class[class]; struct nouveau_channel *chan = dev_priv->fifos[class]; - uint32_t pending_types = 0; DRM_DEBUG("class=%d\n", class); DRM_DEBUG("pending: 0x%08x 0x%08x\n", waiting_types, fc->waiting_types); - if (pending_types) { + if (waiting_types & DRM_FENCE_TYPE_EXE) { uint32_t sequence = NV_READ(chan->ref_cnt); DRM_DEBUG("got 0x%08x\n", sequence); diff --git a/drivers/char/drm/nouveau_fifo.c b/drivers/char/drm/nouveau_fifo.c index 056cb6d..d8fda27 100644 --- a/drivers/char/drm/nouveau_fifo.c +++ b/drivers/char/drm/nouveau_fifo.c @@ -390,6 +390,34 @@ nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, return 0; } +static int +nouveau_channel_idle(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; + uint32_t caches; + int idle; + + caches = NV_READ(NV03_PFIFO_CACHES); + NV_WRITE(NV03_PFIFO_CACHES, caches & ~1); + + if (engine->fifo.channel_id(dev) != chan->id) { + struct nouveau_gpuobj *ramfc = chan->ramfc->gpuobj; + + if (INSTANCE_RD(ramfc, 0) != INSTANCE_RD(ramfc, 1)) + idle = 0; + else + idle = 1; + } else { + idle = (NV_READ(NV04_PFIFO_CACHE1_DMA_GET) == + NV_READ(NV04_PFIFO_CACHE1_DMA_PUT)); + } + + NV_WRITE(NV03_PFIFO_CACHES, caches); + return idle; +} + /* stops a fifo */ void nouveau_fifo_free(struct nouveau_channel *chan) { @@ -400,22 +428,9 @@ void nouveau_fifo_free(struct nouveau_channel *chan) DRM_INFO("%s: freeing fifo %d\n", __func__, chan->id); - /* Disable channel switching, if this channel isn't currenly - * active re-enable it if there's still pending commands. - * We really should do a manual context switch here, but I'm - * not sure I trust our ability to do this reliably yet.. - */ - NV_WRITE(NV03_PFIFO_CACHES, 0); - if (engine->fifo.channel_id(dev) != chan->id && - NV_READ(chan->get) != NV_READ(chan->put)) { - NV_WRITE(NV03_PFIFO_CACHES, 1); - } - /* Give the channel a chance to idle, wait 2s (hopefully) */ t_start = engine->timer.read(dev); - while (NV_READ(chan->get) != NV_READ(chan->put) || - NV_READ(NV03_PFIFO_CACHE1_GET) != - NV_READ(NV03_PFIFO_CACHE1_PUT)) { + while (!nouveau_channel_idle(chan)) { if (engine->timer.read(dev) - t_start > 2000000000ULL) { DRM_ERROR("Failed to idle channel %d before destroy." "Prepare for strangeness..\n", chan->id); @@ -433,13 +448,6 @@ void nouveau_fifo_free(struct nouveau_channel *chan) NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000000); NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000); - /* stop the fifo, otherwise it could be running and - * it will crash when removing gpu objects - *XXX: from real-world evidence, absolutely useless.. - */ - NV_WRITE(chan->get, chan->pushbuf_base); - NV_WRITE(chan->put, chan->pushbuf_base); - // FIXME XXX needs more code engine->fifo.destroy_context(chan); diff --git a/drivers/char/drm/nouveau_ioc32.c b/drivers/char/drm/nouveau_ioc32.c index f55ae7a..4f53a50 100644 --- a/drivers/char/drm/nouveau_ioc32.c +++ b/drivers/char/drm/nouveau_ioc32.c @@ -57,10 +57,6 @@ long nouveau_compat_ioctl(struct file *filp, unsigned int cmd, if (nr < DRM_COMMAND_BASE) return drm_compat_ioctl(filp, cmd, arg); -#if 0 - if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) - fn = nouveau_compat_ioctls[nr - DRM_COMMAND_BASE]; -#endif lock_kernel(); /* XXX for now */ if (fn != NULL) ret = (*fn)(filp, cmd, arg); diff --git a/drivers/char/drm/nouveau_irq.c b/drivers/char/drm/nouveau_irq.c index cae83ae..ec158d8 100644 --- a/drivers/char/drm/nouveau_irq.c +++ b/drivers/char/drm/nouveau_irq.c @@ -37,7 +37,8 @@ #include "nouveau_reg.h" #include "nouveau_swmthd.h" -void nouveau_irq_preinstall(struct drm_device *dev) +void +nouveau_irq_preinstall(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -45,14 +46,15 @@ void nouveau_irq_preinstall(struct drm_device *dev) NV_WRITE(NV03_PMC_INTR_EN_0, 0); } -void nouveau_irq_postinstall(struct drm_device *dev) +int +nouveau_irq_postinstall(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; /* Master enable */ NV_WRITE(NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE); - return; + return 0; } void @@ -444,6 +446,28 @@ nouveau_crtc_irq_handler(struct drm_device *dev, int crtc) } } +static void +nouveau_nv50_display_irq_handler(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t val = NV_READ(NV50_DISPLAY_SUPERVISOR); + + DRM_INFO("NV50_DISPLAY_INTR - 0x%08X\n", val); + + NV_WRITE(NV50_DISPLAY_SUPERVISOR, val); +} + +static void +nouveau_nv50_i2c_irq_handler(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + DRM_INFO("NV50_I2C_INTR - 0x%08X\n", NV_READ(NV50_I2C_CONTROLLER)); + + /* This seems to be the way to acknowledge an interrupt. */ + NV_WRITE(NV50_I2C_CONTROLLER, 0x7FFF7FFF); +} + irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS) { @@ -470,6 +494,16 @@ nouveau_irq_handler(DRM_IRQ_ARGS) status &= ~NV_PMC_INTR_0_CRTCn_PENDING; } + if (status & NV_PMC_INTR_0_NV50_DISPLAY_PENDING) { + nouveau_nv50_display_irq_handler(dev); + status &= ~NV_PMC_INTR_0_NV50_DISPLAY_PENDING; + } + + if (status & NV_PMC_INTR_0_NV50_I2C_PENDING) { + nouveau_nv50_i2c_irq_handler(dev); + status &= ~NV_PMC_INTR_0_NV50_I2C_PENDING; + } + if (status) DRM_ERROR("Unhandled PMC INTR status bits 0x%08x\n", status); diff --git a/drivers/char/drm/nouveau_mem.c b/drivers/char/drm/nouveau_mem.c index 622fe99..c861267 100644 --- a/drivers/char/drm/nouveau_mem.c +++ b/drivers/char/drm/nouveau_mem.c @@ -296,6 +296,32 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) return 0; } +static void nouveau_mem_reset_agp(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t saved_pci_nv_1, saved_pci_nv_19, pmc_enable; + + saved_pci_nv_1 = NV_READ(NV04_PBUS_PCI_NV_1); + saved_pci_nv_19 = NV_READ(NV04_PBUS_PCI_NV_19); + + /* clear busmaster bit */ + NV_WRITE(NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~0x4); + /* clear SBA and AGP bits */ + NV_WRITE(NV04_PBUS_PCI_NV_19, saved_pci_nv_19 & 0xfffff0ff); + + /* power cycle pgraph, if enabled */ + pmc_enable = NV_READ(NV03_PMC_ENABLE); + if (pmc_enable & NV_PMC_ENABLE_PGRAPH) { + NV_WRITE(NV03_PMC_ENABLE, pmc_enable & ~NV_PMC_ENABLE_PGRAPH); + NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) | + NV_PMC_ENABLE_PGRAPH); + } + + /* and restore (gives effect of resetting AGP) */ + NV_WRITE(NV04_PBUS_PCI_NV_19, saved_pci_nv_19); + NV_WRITE(NV04_PBUS_PCI_NV_1, saved_pci_nv_1); +} + static int nouveau_mem_init_agp(struct drm_device *dev, int ttm) { @@ -304,6 +330,8 @@ nouveau_mem_init_agp(struct drm_device *dev, int ttm) struct drm_agp_mode mode; int ret; + nouveau_mem_reset_agp(dev); + ret = drm_agp_acquire(dev); if (ret) { DRM_ERROR("Unable to acquire AGP: %d\n", ret); @@ -436,6 +464,11 @@ int nouveau_mem_init(struct drm_device *dev) /* Init FB */ dev_priv->fb_phys=drm_get_resource_start(dev,1); fb_size = nouveau_mem_fb_amount(dev); + /* On G80, limit VRAM to 512MiB temporarily due to limits in how + * we handle VRAM page tables. + */ + if (dev_priv->card_type >= NV_50 && fb_size > (512 * 1024 * 1024)) + fb_size = (512 * 1024 * 1024); /* On at least NV40, RAMIN is actually at the end of vram. * We don't want to allocate this... */ if (dev_priv->card_type >= NV_40) @@ -508,6 +541,21 @@ int nouveau_mem_init(struct drm_device *dev) } } + /* G8x: Allocate shared page table to map real VRAM pages into */ + if (dev_priv->card_type >= NV_50) { + unsigned size = ((512 * 1024 * 1024) / 65536) * 8; + + ret = nouveau_gpuobj_new(dev, NULL, size, 0, + NVOBJ_FLAG_ZERO_ALLOC | + NVOBJ_FLAG_ALLOW_NO_REFS, + &dev_priv->vm_vram_pt); + if (ret) { + DRM_ERROR("Error creating VRAM page table: %d\n", ret); + return ret; + } + } + + return 0; } @@ -526,6 +574,12 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, if (alignment < PAGE_SHIFT) alignment = PAGE_SHIFT; + /* Align allocation sizes to 64KiB blocks on G8x. We use a 64KiB + * page size in the GPU VM. + */ + if (flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50) + size = (size + (64 * 1024)) & ~((64 * 1024) - 1); + /* * Warn about 0 sized allocations, but let it go through. It'll return 1 page */ @@ -580,6 +634,30 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, alloc_ok: block->flags=type; + /* On G8x, map memory into VM */ + if (block->flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50 && + !(flags & NOUVEAU_MEM_NOVM)) { + struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt; + unsigned offset = block->start; + unsigned count = block->size / 65536; + + if (!pt) { + DRM_ERROR("vm alloc without vm pt\n"); + nouveau_mem_free_block(block); + return NULL; + } + + while (count--) { + unsigned pte = offset / 65536; + + INSTANCE_WR(pt, (pte * 2) + 0, offset | 1); + INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000); + offset += 65536; + } + } else { + block->flags |= NOUVEAU_MEM_NOVM; + } + if (flags&NOUVEAU_MEM_MAPPED) { struct drm_map_list *entry; @@ -621,9 +699,34 @@ alloc_ok: void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + DRM_DEBUG("freeing 0x%llx type=0x%08x\n", block->start, block->flags); + if (block->flags&NOUVEAU_MEM_MAPPED) drm_rmmap(dev, block->map); + + /* G8x: Remove pages from vm */ + if (block->flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50 && + !(block->flags & NOUVEAU_MEM_NOVM)) { + struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt; + unsigned offset = block->start; + unsigned count = block->size / 65536; + + if (!pt) { + DRM_ERROR("vm free without vm pt\n"); + goto out_free; + } + + while (count--) { + unsigned pte = offset / 65536; + INSTANCE_WR(pt, (pte * 2) + 0, 0); + INSTANCE_WR(pt, (pte * 2) + 1, 0); + offset += 65536; + } + } + +out_free: nouveau_mem_free_block(block); } @@ -638,6 +741,9 @@ int nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, struct drm_file NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + if (alloc->flags & NOUVEAU_MEM_INTERNAL) + return -EINVAL; + block=nouveau_mem_alloc(dev, alloc->alignment, alloc->size, alloc->flags, file_priv); if (!block) diff --git a/drivers/char/drm/nouveau_object.c b/drivers/char/drm/nouveau_object.c index fbce770..df534bd 100644 --- a/drivers/char/drm/nouveau_object.c +++ b/drivers/char/drm/nouveau_object.c @@ -983,10 +983,14 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, return ret; } - /* NV50 VM, point offset 0-512MiB at shared PCIEGART table */ + /* NV50 VM + * - Allocate per-channel page-directory + * - Point offset 0-512MiB at shared PCIEGART table + * - Point offset 512-1024MiB at shared VRAM table + */ if (dev_priv->card_type >= NV_50) { uint32_t vm_offset; - + vm_offset = (dev_priv->chipset & 0xf0) == 0x50 ? 0x1400 : 0x200; vm_offset += chan->ramin->gpuobj->im_pramin->start; if ((ret = nouveau_gpuobj_new_fake(dev, vm_offset, ~0, 0x4000, @@ -1004,6 +1008,14 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, INSTANCE_WR(chan->vm_pd, (0+0)/4, chan->vm_gart_pt->instance | 0x03); INSTANCE_WR(chan->vm_pd, (0+4)/4, 0x00000000); + + if ((ret = nouveau_gpuobj_ref_add(dev, NULL, 0, + dev_priv->vm_vram_pt, + &chan->vm_vram_pt))) + return ret; + INSTANCE_WR(chan->vm_pd, (8+0)/4, + chan->vm_vram_pt->instance | 0x61); + INSTANCE_WR(chan->vm_pd, (8+4)/4, 0x00000000); } /* RAMHT */ @@ -1022,6 +1034,17 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, } /* VRAM ctxdma */ + if (dev_priv->card_type >= NV_50) { + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, + 512*1024*1024, + dev_priv->fb_available_size, + NV_DMA_ACCESS_RW, + NV_DMA_TARGET_AGP, &vram); + if (ret) { + DRM_ERROR("Error creating VRAM ctxdma: %d\n", ret); + return ret; + } + } else if ((ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, dev_priv->fb_available_size, NV_DMA_ACCESS_RW, @@ -1084,6 +1107,7 @@ nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan) nouveau_gpuobj_del(dev, &chan->vm_pd); nouveau_gpuobj_ref_del(dev, &chan->vm_gart_pt); + nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt); if (chan->ramin_heap) nouveau_mem_takedown(&chan->ramin_heap); diff --git a/drivers/char/drm/nouveau_reg.h b/drivers/char/drm/nouveau_reg.h index 2f7d77c..1ae0177 100644 --- a/drivers/char/drm/nouveau_reg.h +++ b/drivers/char/drm/nouveau_reg.h @@ -85,8 +85,10 @@ #define NV03_PMC_INTR_0 0x00000100 # define NV_PMC_INTR_0_PFIFO_PENDING (1<< 8) # define NV_PMC_INTR_0_PGRAPH_PENDING (1<<12) +# define NV_PMC_INTR_0_NV50_I2C_PENDING (1<<21) # define NV_PMC_INTR_0_CRTC0_PENDING (1<<24) # define NV_PMC_INTR_0_CRTC1_PENDING (1<<25) +# define NV_PMC_INTR_0_NV50_DISPLAY_PENDING (1<<26) # 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) @@ -123,6 +125,8 @@ #define NV04_PTIMER_TIME_1 0x00009410 #define NV04_PTIMER_ALARM_0 0x00009420 +#define NV50_I2C_CONTROLLER 0x0000E054 + #define NV04_PFB_CFG0 0x00100200 #define NV04_PFB_CFG1 0x00100204 #define NV40_PFB_020C 0x0010020C @@ -535,6 +539,9 @@ #define NV_CRTC1_INTEN 0x00602140 # define NV_CRTC_INTR_VBLANK (1<<0) +/* This name is a partial guess. */ +#define NV50_DISPLAY_SUPERVISOR 0x00610024 + /* Fifo commands. These are not regs, neither masks */ #define NV03_FIFO_CMD_JUMP 0x20000000 #define NV03_FIFO_CMD_JUMP_OFFSET_MASK 0x1ffffffc diff --git a/drivers/char/drm/nouveau_state.c b/drivers/char/drm/nouveau_state.c index 39524ae..90d5748 100644 --- a/drivers/char/drm/nouveau_state.c +++ b/drivers/char/drm/nouveau_state.c @@ -41,7 +41,7 @@ static int nouveau_init_card_mappings(struct drm_device *dev) /* 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); + _DRM_REGISTERS, _DRM_READ_ONLY|_DRM_DRIVER, &dev_priv->mmio); if (ret) { DRM_ERROR("Unable to initialize the mmio mapping (%d). " "Please report your setup to " DRIVER_EMAIL "\n", @@ -60,7 +60,7 @@ static int nouveau_init_card_mappings(struct drm_device *dev) ret = drm_addmap(dev, drm_get_resource_start(dev, ramin_resource), drm_get_resource_len(dev, ramin_resource), - _DRM_REGISTERS, _DRM_READ_ONLY, + _DRM_REGISTERS, _DRM_READ_ONLY|_DRM_DRIVER, &dev_priv->ramin); if (ret) { DRM_ERROR("Failed to init RAMIN mapping, " @@ -75,7 +75,7 @@ static int nouveau_init_card_mappings(struct drm_device *dev) ret = drm_addmap(dev, drm_get_resource_start(dev, 0) + NV_RAMIN, (1*1024*1024), - _DRM_REGISTERS, _DRM_READ_ONLY, + _DRM_REGISTERS, _DRM_READ_ONLY|_DRM_DRIVER, &dev_priv->ramin); if (ret) { DRM_ERROR("Failed to map BAR0 PRAMIN: %d\n", ret); @@ -384,6 +384,7 @@ static void nouveau_card_takedown(struct drm_device *dev) nouveau_sgdma_takedown(dev); nouveau_gpuobj_takedown(dev); + nouveau_gpuobj_del(dev, &dev_priv->vm_vram_pt); nouveau_mem_close(dev); engine->instmem.takedown(dev); @@ -416,6 +417,7 @@ int nouveau_firstopen(struct drm_device *dev) struct device_node *dn; #endif int ret; + /* Map any PCI resources we need on the card */ ret = nouveau_init_card_mappings(dev); if (ret) return ret; @@ -559,6 +561,15 @@ void nouveau_lastclose(struct drm_device *dev) drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1),nouveau_mem_fb_amount(dev), DRM_MTRR_WC); dev_priv->fb_mtrr=0; } + + if (dev_priv->ramin) { + drm_rmmap(dev, dev_priv->ramin); + dev_priv->ramin = NULL; + } + if (dev_priv->mmio) { + drm_rmmap(dev, dev_priv->mmio); + dev_priv->mmio = NULL; + } } } diff --git a/drivers/char/drm/nv04_mc.c b/drivers/char/drm/nv04_mc.c index 766f3a3..24c1f7b 100644 --- a/drivers/char/drm/nv04_mc.c +++ b/drivers/char/drm/nv04_mc.c @@ -7,25 +7,12 @@ int nv04_mc_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t saved_pci_nv_1, saved_pci_nv_19; - - saved_pci_nv_1 = NV_READ(NV04_PBUS_PCI_NV_1); - saved_pci_nv_19 = NV_READ(NV04_PBUS_PCI_NV_19); - - /* clear busmaster bit */ - NV_WRITE(NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~(0x00000001 << 2)); - /* clear SBA and AGP bits */ - NV_WRITE(NV04_PBUS_PCI_NV_19, saved_pci_nv_19 & 0xfffff0ff); /* Power up everything, resetting each individual unit will * be done later if needed. */ NV_WRITE(NV03_PMC_ENABLE, 0xFFFFFFFF); - /* and restore (gives effect of resetting AGP) */ - NV_WRITE(NV04_PBUS_PCI_NV_19, saved_pci_nv_19); - NV_WRITE(NV04_PBUS_PCI_NV_1, saved_pci_nv_1); - return 0; } diff --git a/drivers/char/drm/nv04_timer.c b/drivers/char/drm/nv04_timer.c index 88dff36..616f197 100644 --- a/drivers/char/drm/nv04_timer.c +++ b/drivers/char/drm/nv04_timer.c @@ -11,8 +11,17 @@ nv04_timer_init(struct drm_device *dev) 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); + /* Just use the pre-existing values when possible for now; these regs + * are not written in nv (driver writer missed a /4 on the address), and + * writing 8 and 3 to the correct regs breaks the timings on the LVDS + * hardware sequencing microcode. + * A correct solution (involving calculations with the GPU PLL) can + * be done when kernel modesetting lands + */ + if (!NV_READ(NV04_PTIMER_NUMERATOR) || !NV_READ(NV04_PTIMER_DENOMINATOR)) { + NV_WRITE(NV04_PTIMER_NUMERATOR, 0x00000008); + NV_WRITE(NV04_PTIMER_DENOMINATOR, 0x00000003); + } return 0; } diff --git a/drivers/char/drm/nv40_graph.c b/drivers/char/drm/nv40_graph.c index 6ef02bf..2540fc5 100644 --- a/drivers/char/drm/nv40_graph.c +++ b/drivers/char/drm/nv40_graph.c @@ -28,22 +28,6 @@ #include "drm.h" #include "nouveau_drv.h" -/* The sizes are taken from the difference between the start of two - * grctx addresses while running the nvidia driver. Probably slightly - * larger than they actually are, because of other objects being created - * between the contexts - */ -#define NV40_GRCTX_SIZE (175*1024) -#define NV41_GRCTX_SIZE (92*1024) -#define NV43_GRCTX_SIZE (70*1024) -#define NV46_GRCTX_SIZE (70*1024) /* probably ~64KiB */ -#define NV47_GRCTX_SIZE (125*1024) -#define NV49_GRCTX_SIZE (164640) -#define NV4A_GRCTX_SIZE (64*1024) -#define NV4B_GRCTX_SIZE (164640) -#define NV4C_GRCTX_SIZE (25*1024) -#define NV4E_GRCTX_SIZE (25*1024) - /*TODO: deciper what each offset in the context represents. The below * contexts are taken from dumps just after the 3D object is * created. @@ -1471,61 +1455,60 @@ nv40_graph_create_context(struct nouveau_channel *chan) struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *); - unsigned int ctx_size; int ret; + /* These functions populate the graphics context with a whole heap + * of default state. All these functions are very similar, with + * a minimal amount of chipset-specific changes. However, as we're + * currently dependant on the context programs used by the NVIDIA + * binary driver these functions must match the layout expected by + * them. Hopefully at some point this will all change. + */ switch (dev_priv->chipset) { case 0x40: - ctx_size = NV40_GRCTX_SIZE; ctx_init = nv40_graph_context_init; break; case 0x41: case 0x42: - ctx_size = NV41_GRCTX_SIZE; ctx_init = nv41_graph_context_init; break; case 0x43: - ctx_size = NV43_GRCTX_SIZE; ctx_init = nv43_graph_context_init; break; case 0x46: - ctx_size = NV46_GRCTX_SIZE; ctx_init = nv46_graph_context_init; break; case 0x47: - DRM_INFO("NV47 warning: If your card behaves strangely, please come to the irc channel\n"); - ctx_size = NV47_GRCTX_SIZE; ctx_init = nv47_graph_context_init; break; case 0x49: - ctx_size = NV49_GRCTX_SIZE; ctx_init = nv49_graph_context_init; break; case 0x44: case 0x4a: - ctx_size = NV4A_GRCTX_SIZE; ctx_init = nv4a_graph_context_init; break; case 0x4b: - ctx_size = NV4B_GRCTX_SIZE; ctx_init = nv4b_graph_context_init; break; case 0x4c: case 0x67: - ctx_size = NV4C_GRCTX_SIZE; ctx_init = nv4c_graph_context_init; break; case 0x4e: - ctx_size = NV4E_GRCTX_SIZE; ctx_init = nv4e_graph_context_init; break; default: - ctx_size = NV40_GRCTX_SIZE; ctx_init = nv40_graph_context_init; break; } - if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ctx_size, 16, + /* Allocate a 175KiB block of PRAMIN to store the context. This + * is massive overkill for a lot of chipsets, but it should be safe + * until we're able to implement this properly (will happen at more + * or less the same time we're able to write our own context programs. + */ + if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 175*1024, 16, NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin_grctx))) return ret; @@ -1634,65 +1617,52 @@ nv40_graph_load_context(struct nouveau_channel *chan) return 0; } -/* Some voodoo that makes context switching work without the binary driver - * initialising the card first. - * - * It is possible to effect how the context is saved from PGRAPH into a block - * of instance memory by altering the values in these tables. This may mean - * that the context layout of each chipset is slightly different (at least - * NV40 and C51 are different). It would also be possible for chipsets to - * have an identical context layout, but pull the data from different PGRAPH - * registers. - * - * TODO: decode the meaning of the magic values, may provide clues about the - * differences between the various NV40 chipsets. - * TODO: one we have a better idea of how each chipset differs, perhaps think - * about unifying these instead of providing a separate table for each - * chip. - * - * mmio-trace dumps from other nv4x/g7x/c5x cards very welcome :) +/* These blocks of "magic numbers" are actually a microcode that the GPU uses + * to control how graphics contexts get saved and restored between PRAMIN + * and PGRAPH during a context switch. We're currently using values seen + * in mmio-traces of the binary driver. */ -static uint32_t nv40_ctx_voodoo[] = { +static uint32_t nv40_ctx_prog[] = { /*(DEBLOBBED)*/ ~0 }; -static uint32_t nv41_ctx_voodoo[] = { +static uint32_t nv41_ctx_prog[] = { /*(DEBLOBBED)*/~0 }; -static uint32_t nv43_ctx_voodoo[] = { +static uint32_t nv43_ctx_prog[] = { /*(DEBLOBBED)*/ ~0 }; -static uint32_t nv44_ctx_voodoo[] = { +static uint32_t nv44_ctx_prog[] = { /*(DEBLOBBED)*/~0 }; -static uint32_t nv46_ctx_voodoo[] = { +static uint32_t nv46_ctx_prog[] = { /*(DEBLOBBED)*/~0 }; -static uint32_t nv47_ctx_voodoo[] = { +static uint32_t nv47_ctx_prog[] = { /*(DEBLOBBED)*/~0 }; //this is used for nv49 and nv4b -static uint32_t nv49_4b_ctx_voodoo[] ={ +static uint32_t nv49_4b_ctx_prog[] ={ /*(DEBLOBBED)*/~0 }; -static uint32_t nv4a_ctx_voodoo[] = { +static uint32_t nv4a_ctx_prog[] = { /*(DEBLOBBED)*/~0 }; -static uint32_t nv4c_ctx_voodoo[] = { +static uint32_t nv4c_ctx_prog[] = { /*(DEBLOBBED)*/~0 }; -static uint32_t nv4e_ctx_voodoo[] = { +static uint32_t nv4e_ctx_prog[] = { /*(DEBLOBBED)*/~0 }; @@ -1988,7 +1958,7 @@ nv40_graph_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = (struct drm_nouveau_private *)dev->dev_private; - uint32_t *ctx_voodoo; + uint32_t *ctx_prog; uint32_t vramsz, tmp; int i, j; @@ -1998,34 +1968,34 @@ nv40_graph_init(struct drm_device *dev) NV_PMC_ENABLE_PGRAPH); switch (dev_priv->chipset) { - case 0x40: ctx_voodoo = nv40_ctx_voodoo; break; + case 0x40: ctx_prog = nv40_ctx_prog; break; case 0x41: - case 0x42: ctx_voodoo = nv41_ctx_voodoo; break; - case 0x43: ctx_voodoo = nv43_ctx_voodoo; break; - case 0x44: ctx_voodoo = nv44_ctx_voodoo; break; - case 0x46: ctx_voodoo = nv46_ctx_voodoo; break; - case 0x47: ctx_voodoo = nv47_ctx_voodoo; break; - case 0x49: ctx_voodoo = nv49_4b_ctx_voodoo; break; - case 0x4a: ctx_voodoo = nv4a_ctx_voodoo; break; - case 0x4b: ctx_voodoo = nv49_4b_ctx_voodoo; break; + case 0x42: ctx_prog = nv41_ctx_prog; break; + case 0x43: ctx_prog = nv43_ctx_prog; break; + case 0x44: ctx_prog = nv44_ctx_prog; break; + case 0x46: ctx_prog = nv46_ctx_prog; break; + case 0x47: ctx_prog = nv47_ctx_prog; break; + case 0x49: ctx_prog = nv49_4b_ctx_prog; break; + case 0x4a: ctx_prog = nv4a_ctx_prog; break; + case 0x4b: ctx_prog = nv49_4b_ctx_prog; break; case 0x4c: - case 0x67: ctx_voodoo = nv4c_ctx_voodoo; break; - case 0x4e: ctx_voodoo = nv4e_ctx_voodoo; break; + case 0x67: ctx_prog = nv4c_ctx_prog; break; + case 0x4e: ctx_prog = nv4e_ctx_prog; break; default: - DRM_ERROR("Unknown ctx_voodoo for chipset 0x%02x\n", - dev_priv->chipset); - ctx_voodoo = NULL; + DRM_ERROR("Context program for 0x%02x unavailable\n", + dev_priv->chipset); + ctx_prog = NULL; break; } - /* Load the context voodoo onto the card */ - if (ctx_voodoo) { - DRM_DEBUG("Loading context-switch voodoo\n"); + /* Load the context program onto the card */ + if (ctx_prog) { + DRM_DEBUG("Loading context program\n"); i = 0; NV_WRITE(NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); - while (ctx_voodoo[i] != ~0) { - NV_WRITE(NV40_PGRAPH_CTXCTL_UCODE_DATA, ctx_voodoo[i]); + while (ctx_prog[i] != ~0) { + NV_WRITE(NV40_PGRAPH_CTXCTL_UCODE_DATA, ctx_prog[i]); i++; } } diff --git a/drivers/char/drm/nv50_graph.c b/drivers/char/drm/nv50_graph.c index b95afeb..55df5fc 100644 --- a/drivers/char/drm/nv50_graph.c +++ b/drivers/char/drm/nv50_graph.c @@ -245,6 +245,692 @@ nv50_graph_takedown(struct drm_device *dev) DRM_DEBUG("\n"); } +static void +nv86_graph_init_ctxvals(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *ctx = ref->gpuobj; + + INSTANCE_WR(ctx, 0x0/4, 0x1); + INSTANCE_WR(ctx, 0x10C/4, 0x30); + INSTANCE_WR(ctx, 0x1D4/4, 0x3); + INSTANCE_WR(ctx, 0x1D8/4, 0x1000); + INSTANCE_WR(ctx, 0x218/4, 0xFE0C); + INSTANCE_WR(ctx, 0x22C/4, 0x1000); + INSTANCE_WR(ctx, 0x258/4, 0x187); + INSTANCE_WR(ctx, 0x26C/4, 0x1018); + INSTANCE_WR(ctx, 0x270/4, 0xFF); + INSTANCE_WR(ctx, 0x2AC/4, 0x4); + INSTANCE_WR(ctx, 0x2B0/4, 0x44D00DF); + INSTANCE_WR(ctx, 0x2B8/4, 0x600); + INSTANCE_WR(ctx, 0x2D0/4, 0x1000000); + INSTANCE_WR(ctx, 0x2D4/4, 0xFF); + INSTANCE_WR(ctx, 0x2DC/4, 0x400); + INSTANCE_WR(ctx, 0x2F4/4, 0x1); + INSTANCE_WR(ctx, 0x2F8/4, 0x80); + INSTANCE_WR(ctx, 0x2FC/4, 0x4); + INSTANCE_WR(ctx, 0x318/4, 0x2); + INSTANCE_WR(ctx, 0x31C/4, 0x1); + INSTANCE_WR(ctx, 0x328/4, 0x1); + INSTANCE_WR(ctx, 0x32C/4, 0x100); + INSTANCE_WR(ctx, 0x344/4, 0x2); + INSTANCE_WR(ctx, 0x348/4, 0x1); + INSTANCE_WR(ctx, 0x34C/4, 0x1); + INSTANCE_WR(ctx, 0x35C/4, 0x1); + INSTANCE_WR(ctx, 0x360/4, 0x3FFFFF); + INSTANCE_WR(ctx, 0x364/4, 0x1FFF); + INSTANCE_WR(ctx, 0x36C/4, 0x1); + INSTANCE_WR(ctx, 0x370/4, 0x1); + INSTANCE_WR(ctx, 0x378/4, 0x1); + INSTANCE_WR(ctx, 0x37C/4, 0x1); + INSTANCE_WR(ctx, 0x380/4, 0x1); + INSTANCE_WR(ctx, 0x384/4, 0x4); + INSTANCE_WR(ctx, 0x388/4, 0x1); + INSTANCE_WR(ctx, 0x38C/4, 0x1); + INSTANCE_WR(ctx, 0x390/4, 0x1); + INSTANCE_WR(ctx, 0x394/4, 0x7); + INSTANCE_WR(ctx, 0x398/4, 0x1); + INSTANCE_WR(ctx, 0x39C/4, 0x7); + INSTANCE_WR(ctx, 0x3A0/4, 0x1); + INSTANCE_WR(ctx, 0x3A4/4, 0x1); + INSTANCE_WR(ctx, 0x3A8/4, 0x1); + INSTANCE_WR(ctx, 0x3BC/4, 0x1); + INSTANCE_WR(ctx, 0x3C0/4, 0x100); + INSTANCE_WR(ctx, 0x3C8/4, 0x1); + INSTANCE_WR(ctx, 0x3D4/4, 0x100); + INSTANCE_WR(ctx, 0x3D8/4, 0x1); + INSTANCE_WR(ctx, 0x3DC/4, 0x100); + INSTANCE_WR(ctx, 0x3E4/4, 0x1); + INSTANCE_WR(ctx, 0x3F0/4, 0x100); + INSTANCE_WR(ctx, 0x404/4, 0x4); + INSTANCE_WR(ctx, 0x408/4, 0x70); + INSTANCE_WR(ctx, 0x40C/4, 0x80); + INSTANCE_WR(ctx, 0x420/4, 0xC); + INSTANCE_WR(ctx, 0x428/4, 0x8); + INSTANCE_WR(ctx, 0x42C/4, 0x14); + INSTANCE_WR(ctx, 0x434/4, 0x29); + INSTANCE_WR(ctx, 0x438/4, 0x27); + INSTANCE_WR(ctx, 0x43C/4, 0x26); + INSTANCE_WR(ctx, 0x440/4, 0x8); + INSTANCE_WR(ctx, 0x444/4, 0x4); + INSTANCE_WR(ctx, 0x448/4, 0x27); + INSTANCE_WR(ctx, 0x454/4, 0x1); + INSTANCE_WR(ctx, 0x458/4, 0x2); + INSTANCE_WR(ctx, 0x45C/4, 0x3); + INSTANCE_WR(ctx, 0x460/4, 0x4); + INSTANCE_WR(ctx, 0x464/4, 0x5); + INSTANCE_WR(ctx, 0x468/4, 0x6); + INSTANCE_WR(ctx, 0x46C/4, 0x7); + INSTANCE_WR(ctx, 0x470/4, 0x1); + INSTANCE_WR(ctx, 0x4B4/4, 0xCF); + INSTANCE_WR(ctx, 0x4E4/4, 0x80); + INSTANCE_WR(ctx, 0x4E8/4, 0x4); + INSTANCE_WR(ctx, 0x4EC/4, 0x4); + INSTANCE_WR(ctx, 0x4F0/4, 0x3); + INSTANCE_WR(ctx, 0x4F4/4, 0x1); + INSTANCE_WR(ctx, 0x500/4, 0x12); + INSTANCE_WR(ctx, 0x504/4, 0x10); + INSTANCE_WR(ctx, 0x508/4, 0xC); + INSTANCE_WR(ctx, 0x50C/4, 0x1); + INSTANCE_WR(ctx, 0x51C/4, 0x4); + INSTANCE_WR(ctx, 0x520/4, 0x2); + INSTANCE_WR(ctx, 0x524/4, 0x4); + INSTANCE_WR(ctx, 0x530/4, 0x3FFFFF); + INSTANCE_WR(ctx, 0x534/4, 0x1FFF); + INSTANCE_WR(ctx, 0x55C/4, 0x4); + INSTANCE_WR(ctx, 0x560/4, 0x14); + INSTANCE_WR(ctx, 0x564/4, 0x1); + INSTANCE_WR(ctx, 0x570/4, 0x2); + INSTANCE_WR(ctx, 0x57C/4, 0x1); + INSTANCE_WR(ctx, 0x584/4, 0x2); + INSTANCE_WR(ctx, 0x588/4, 0x1000); + INSTANCE_WR(ctx, 0x58C/4, 0xE00); + INSTANCE_WR(ctx, 0x590/4, 0x1000); + INSTANCE_WR(ctx, 0x594/4, 0x1E00); + INSTANCE_WR(ctx, 0x59C/4, 0x1); + INSTANCE_WR(ctx, 0x5A0/4, 0x1); + INSTANCE_WR(ctx, 0x5A4/4, 0x1); + INSTANCE_WR(ctx, 0x5A8/4, 0x1); + INSTANCE_WR(ctx, 0x5AC/4, 0x1); + INSTANCE_WR(ctx, 0x5BC/4, 0x200); + INSTANCE_WR(ctx, 0x5C4/4, 0x1); + INSTANCE_WR(ctx, 0x5C8/4, 0x70); + INSTANCE_WR(ctx, 0x5CC/4, 0x80); + INSTANCE_WR(ctx, 0x5D8/4, 0x1); + INSTANCE_WR(ctx, 0x5DC/4, 0x70); + INSTANCE_WR(ctx, 0x5E0/4, 0x80); + INSTANCE_WR(ctx, 0x5F0/4, 0x1); + INSTANCE_WR(ctx, 0x5F4/4, 0xCF); + INSTANCE_WR(ctx, 0x5FC/4, 0x1); + INSTANCE_WR(ctx, 0x60C/4, 0xCF); + INSTANCE_WR(ctx, 0x614/4, 0x2); + INSTANCE_WR(ctx, 0x61C/4, 0x1); + INSTANCE_WR(ctx, 0x624/4, 0x1); + INSTANCE_WR(ctx, 0x62C/4, 0xCF); + INSTANCE_WR(ctx, 0x630/4, 0xCF); + INSTANCE_WR(ctx, 0x634/4, 0x1); + INSTANCE_WR(ctx, 0x63C/4, 0xF80); + INSTANCE_WR(ctx, 0x684/4, 0x7F0080); + INSTANCE_WR(ctx, 0x6C0/4, 0x7F0080); + INSTANCE_WR(ctx, 0x6E4/4, 0x3B74F821); + INSTANCE_WR(ctx, 0x6E8/4, 0x89058001); + INSTANCE_WR(ctx, 0x6F0/4, 0x1000); + INSTANCE_WR(ctx, 0x6F4/4, 0x1F); + INSTANCE_WR(ctx, 0x6F8/4, 0x27C10FA); + INSTANCE_WR(ctx, 0x6FC/4, 0x400000C0); + INSTANCE_WR(ctx, 0x700/4, 0xB7892080); + INSTANCE_WR(ctx, 0x70C/4, 0x3B74F821); + INSTANCE_WR(ctx, 0x710/4, 0x89058001); + INSTANCE_WR(ctx, 0x718/4, 0x1000); + INSTANCE_WR(ctx, 0x71C/4, 0x1F); + INSTANCE_WR(ctx, 0x720/4, 0x27C10FA); + INSTANCE_WR(ctx, 0x724/4, 0x400000C0); + INSTANCE_WR(ctx, 0x728/4, 0xB7892080); + INSTANCE_WR(ctx, 0x734/4, 0x10040); + INSTANCE_WR(ctx, 0x73C/4, 0x22); + INSTANCE_WR(ctx, 0x748/4, 0x10040); + INSTANCE_WR(ctx, 0x74C/4, 0x22); + INSTANCE_WR(ctx, 0x764/4, 0x1800000); + INSTANCE_WR(ctx, 0x768/4, 0x160000); + INSTANCE_WR(ctx, 0x76C/4, 0x1800000); + INSTANCE_WR(ctx, 0x77C/4, 0x3FFFF); + INSTANCE_WR(ctx, 0x780/4, 0x8C0000); + INSTANCE_WR(ctx, 0x7A4/4, 0x10401); + INSTANCE_WR(ctx, 0x7AC/4, 0x78); + INSTANCE_WR(ctx, 0x7B4/4, 0xBF); + INSTANCE_WR(ctx, 0x7BC/4, 0x1210); + INSTANCE_WR(ctx, 0x7C0/4, 0x8000080); + INSTANCE_WR(ctx, 0x7E4/4, 0x1800000); + INSTANCE_WR(ctx, 0x7E8/4, 0x160000); + INSTANCE_WR(ctx, 0x7EC/4, 0x1800000); + INSTANCE_WR(ctx, 0x7FC/4, 0x3FFFF); + INSTANCE_WR(ctx, 0x800/4, 0x8C0000); + INSTANCE_WR(ctx, 0x824/4, 0x10401); + INSTANCE_WR(ctx, 0x82C/4, 0x78); + INSTANCE_WR(ctx, 0x834/4, 0xBF); + INSTANCE_WR(ctx, 0x83C/4, 0x1210); + INSTANCE_WR(ctx, 0x840/4, 0x8000080); + INSTANCE_WR(ctx, 0x868/4, 0x27070); + INSTANCE_WR(ctx, 0x874/4, 0x3FFFFFF); + INSTANCE_WR(ctx, 0x88C/4, 0x120407); + INSTANCE_WR(ctx, 0x890/4, 0x5091507); + INSTANCE_WR(ctx, 0x894/4, 0x5010202); + INSTANCE_WR(ctx, 0x898/4, 0x30201); + INSTANCE_WR(ctx, 0x8B4/4, 0x40); + INSTANCE_WR(ctx, 0x8B8/4, 0xD0C0B0A); + INSTANCE_WR(ctx, 0x8BC/4, 0x141210); + INSTANCE_WR(ctx, 0x8C0/4, 0x1F0); + INSTANCE_WR(ctx, 0x8C4/4, 0x1); + INSTANCE_WR(ctx, 0x8C8/4, 0x3); + INSTANCE_WR(ctx, 0x8D4/4, 0x39E00); + INSTANCE_WR(ctx, 0x8D8/4, 0x100); + INSTANCE_WR(ctx, 0x8DC/4, 0x3800); + INSTANCE_WR(ctx, 0x8E0/4, 0x404040); + INSTANCE_WR(ctx, 0x8E4/4, 0xFF0A); + INSTANCE_WR(ctx, 0x8EC/4, 0x77F005); + INSTANCE_WR(ctx, 0x8F0/4, 0x3F7FFF); + INSTANCE_WR(ctx, 0x7BA0/4, 0x21); + INSTANCE_WR(ctx, 0x7BC0/4, 0x1); + INSTANCE_WR(ctx, 0x7BE0/4, 0x2); + INSTANCE_WR(ctx, 0x7C00/4, 0x100); + INSTANCE_WR(ctx, 0x7C20/4, 0x100); + INSTANCE_WR(ctx, 0x7C40/4, 0x1); + INSTANCE_WR(ctx, 0x7CA0/4, 0x1); + INSTANCE_WR(ctx, 0x7CC0/4, 0x2); + INSTANCE_WR(ctx, 0x7CE0/4, 0x100); + INSTANCE_WR(ctx, 0x7D00/4, 0x100); + INSTANCE_WR(ctx, 0x7D20/4, 0x1); + INSTANCE_WR(ctx, 0x11640/4, 0x4); + INSTANCE_WR(ctx, 0x11660/4, 0x4); + INSTANCE_WR(ctx, 0x49FE0/4, 0x4); + INSTANCE_WR(ctx, 0x4A000/4, 0x4); + INSTANCE_WR(ctx, 0x4A020/4, 0x8100C12); + INSTANCE_WR(ctx, 0x4A040/4, 0x3); + INSTANCE_WR(ctx, 0x4A080/4, 0x8100C12); + INSTANCE_WR(ctx, 0x4A0C0/4, 0x80C14); + INSTANCE_WR(ctx, 0x4A0E0/4, 0x1); + INSTANCE_WR(ctx, 0x4A100/4, 0x80C14); + INSTANCE_WR(ctx, 0x4A160/4, 0x8100C12); + INSTANCE_WR(ctx, 0x4A180/4, 0x27); + INSTANCE_WR(ctx, 0x4A1E0/4, 0x1); + INSTANCE_WR(ctx, 0x51A20/4, 0x1); + INSTANCE_WR(ctx, 0x51D00/4, 0x8100C12); + INSTANCE_WR(ctx, 0x51EA0/4, 0x4000000); + INSTANCE_WR(ctx, 0x51EC0/4, 0x4000000); + INSTANCE_WR(ctx, 0x51F00/4, 0x80); + INSTANCE_WR(ctx, 0x51F80/4, 0x80); + INSTANCE_WR(ctx, 0x51FC0/4, 0x3F); + INSTANCE_WR(ctx, 0x52120/4, 0x2); + INSTANCE_WR(ctx, 0x52140/4, 0x4000000); + INSTANCE_WR(ctx, 0x52160/4, 0x4000000); + INSTANCE_WR(ctx, 0x52280/4, 0x4); + INSTANCE_WR(ctx, 0x52300/4, 0x4); + INSTANCE_WR(ctx, 0x52540/4, 0x1); + INSTANCE_WR(ctx, 0x52560/4, 0x1001); + INSTANCE_WR(ctx, 0x52580/4, 0xFFFF); + INSTANCE_WR(ctx, 0x525A0/4, 0xFFFF); + INSTANCE_WR(ctx, 0x525C0/4, 0xFFFF); + INSTANCE_WR(ctx, 0x525E0/4, 0xFFFF); + INSTANCE_WR(ctx, 0x52A00/4, 0x3F800000); + INSTANCE_WR(ctx, 0x52A20/4, 0x3F800000); + INSTANCE_WR(ctx, 0x52A40/4, 0x3F800000); + INSTANCE_WR(ctx, 0x52A60/4, 0x3F800000); + INSTANCE_WR(ctx, 0x52A80/4, 0x3F800000); + INSTANCE_WR(ctx, 0x52AA0/4, 0x3F800000); + INSTANCE_WR(ctx, 0x52AC0/4, 0x3F800000); + INSTANCE_WR(ctx, 0x52AE0/4, 0x3F800000); + INSTANCE_WR(ctx, 0x52B00/4, 0x3F800000); + INSTANCE_WR(ctx, 0x52B20/4, 0x3F800000); + INSTANCE_WR(ctx, 0x52B40/4, 0x3F800000); + INSTANCE_WR(ctx, 0x52B60/4, 0x3F800000); + INSTANCE_WR(ctx, 0x52B80/4, 0x3F800000); + INSTANCE_WR(ctx, 0x52BA0/4, 0x3F800000); + INSTANCE_WR(ctx, 0x52BC0/4, 0x3F800000); + INSTANCE_WR(ctx, 0x52BE0/4, 0x3F800000); + INSTANCE_WR(ctx, 0x52C00/4, 0x10); + INSTANCE_WR(ctx, 0x52C60/4, 0x3); + INSTANCE_WR(ctx, 0xA84/4, 0xF); + INSTANCE_WR(ctx, 0xB24/4, 0x20); + INSTANCE_WR(ctx, 0xD04/4, 0x1A); + INSTANCE_WR(ctx, 0xEC4/4, 0x4); + INSTANCE_WR(ctx, 0xEE4/4, 0x4); + INSTANCE_WR(ctx, 0xF24/4, 0x4); + INSTANCE_WR(ctx, 0xF44/4, 0x8); + INSTANCE_WR(ctx, 0xF84/4, 0x7FF); + INSTANCE_WR(ctx, 0x1124/4, 0xF); + INSTANCE_WR(ctx, 0x3604/4, 0xF); + INSTANCE_WR(ctx, 0x3644/4, 0x1); + INSTANCE_WR(ctx, 0x41A4/4, 0xF); + INSTANCE_WR(ctx, 0x14844/4, 0xF); + INSTANCE_WR(ctx, 0x14AE4/4, 0x1); + INSTANCE_WR(ctx, 0x14B04/4, 0x100); + INSTANCE_WR(ctx, 0x14B24/4, 0x100); + INSTANCE_WR(ctx, 0x14B44/4, 0x11); + INSTANCE_WR(ctx, 0x14B84/4, 0x8); + INSTANCE_WR(ctx, 0x14C44/4, 0x1); + INSTANCE_WR(ctx, 0x14C84/4, 0x1); + INSTANCE_WR(ctx, 0x14CA4/4, 0x1); + INSTANCE_WR(ctx, 0x14CC4/4, 0x1); + INSTANCE_WR(ctx, 0x14CE4/4, 0xCF); + INSTANCE_WR(ctx, 0x14D04/4, 0x2); + INSTANCE_WR(ctx, 0x14DE4/4, 0x1); + INSTANCE_WR(ctx, 0x14E24/4, 0x1); + INSTANCE_WR(ctx, 0x14E44/4, 0x1); + INSTANCE_WR(ctx, 0x14E64/4, 0x1); + INSTANCE_WR(ctx, 0x14F04/4, 0x4); + INSTANCE_WR(ctx, 0x14F44/4, 0x1); + INSTANCE_WR(ctx, 0x14F64/4, 0x15); + INSTANCE_WR(ctx, 0x14FE4/4, 0x4444480); + INSTANCE_WR(ctx, 0x15764/4, 0x8100C12); + INSTANCE_WR(ctx, 0x15804/4, 0x100); + INSTANCE_WR(ctx, 0x15864/4, 0x10001); + INSTANCE_WR(ctx, 0x158A4/4, 0x10001); + INSTANCE_WR(ctx, 0x158C4/4, 0x1); + INSTANCE_WR(ctx, 0x158E4/4, 0x10001); + INSTANCE_WR(ctx, 0x15904/4, 0x1); + INSTANCE_WR(ctx, 0x15924/4, 0x4); + INSTANCE_WR(ctx, 0x15944/4, 0x2); + INSTANCE_WR(ctx, 0x166C4/4, 0x4E3BFDF); + INSTANCE_WR(ctx, 0x166E4/4, 0x4E3BFDF); + INSTANCE_WR(ctx, 0x16784/4, 0xFAC6881); + INSTANCE_WR(ctx, 0x16904/4, 0x4E3BFDF); + INSTANCE_WR(ctx, 0x16924/4, 0x4E3BFDF); + INSTANCE_WR(ctx, 0x15948/4, 0x3FFFFF); + INSTANCE_WR(ctx, 0x159A8/4, 0x1FFF); + INSTANCE_WR(ctx, 0x15B88/4, 0x3F800000); + INSTANCE_WR(ctx, 0x15C68/4, 0x4); + INSTANCE_WR(ctx, 0x15C88/4, 0x1A); + INSTANCE_WR(ctx, 0x15CE8/4, 0x1); + INSTANCE_WR(ctx, 0x15F48/4, 0xFFFF00); + INSTANCE_WR(ctx, 0x16028/4, 0xF); + INSTANCE_WR(ctx, 0x16128/4, 0xFAC6881); + INSTANCE_WR(ctx, 0x16148/4, 0x11); + INSTANCE_WR(ctx, 0x16348/4, 0x4); + INSTANCE_WR(ctx, 0x163E8/4, 0x2); + INSTANCE_WR(ctx, 0x16408/4, 0x4000000); + INSTANCE_WR(ctx, 0x16428/4, 0x4000000); + INSTANCE_WR(ctx, 0x164A8/4, 0x5); + INSTANCE_WR(ctx, 0x164C8/4, 0x52); + INSTANCE_WR(ctx, 0x16568/4, 0x1); + INSTANCE_WR(ctx, 0x16788/4, 0x3F800000); + INSTANCE_WR(ctx, 0x167A8/4, 0x3F800000); + INSTANCE_WR(ctx, 0x167C8/4, 0x3F800000); + INSTANCE_WR(ctx, 0x167E8/4, 0x3F800000); + INSTANCE_WR(ctx, 0x16808/4, 0x3F800000); + INSTANCE_WR(ctx, 0x16828/4, 0x3F800000); + INSTANCE_WR(ctx, 0x16848/4, 0x3F800000); + INSTANCE_WR(ctx, 0x16868/4, 0x3F800000); + INSTANCE_WR(ctx, 0x16888/4, 0x3F800000); + INSTANCE_WR(ctx, 0x168A8/4, 0x3F800000); + INSTANCE_WR(ctx, 0x168C8/4, 0x3F800000); + INSTANCE_WR(ctx, 0x168E8/4, 0x3F800000); + INSTANCE_WR(ctx, 0x16908/4, 0x3F800000); + INSTANCE_WR(ctx, 0x16928/4, 0x3F800000); + INSTANCE_WR(ctx, 0x16948/4, 0x3F800000); + INSTANCE_WR(ctx, 0x16968/4, 0x3F800000); + INSTANCE_WR(ctx, 0x16988/4, 0x10); + INSTANCE_WR(ctx, 0x16E68/4, 0x8100C12); + INSTANCE_WR(ctx, 0x16E88/4, 0x5); + INSTANCE_WR(ctx, 0x16EE8/4, 0x1); + INSTANCE_WR(ctx, 0x16F28/4, 0xFFFF); + INSTANCE_WR(ctx, 0x16F48/4, 0xFFFF); + INSTANCE_WR(ctx, 0x16F68/4, 0xFFFF); + INSTANCE_WR(ctx, 0x16F88/4, 0xFFFF); + INSTANCE_WR(ctx, 0x16FA8/4, 0x3); + INSTANCE_WR(ctx, 0x173A8/4, 0xFFFF00); + INSTANCE_WR(ctx, 0x173C8/4, 0x1A); + INSTANCE_WR(ctx, 0x17408/4, 0x3); + INSTANCE_WR(ctx, 0x178E8/4, 0x102); + INSTANCE_WR(ctx, 0x17928/4, 0x4); + INSTANCE_WR(ctx, 0x17948/4, 0x4); + INSTANCE_WR(ctx, 0x17968/4, 0x4); + INSTANCE_WR(ctx, 0x17988/4, 0x4); + INSTANCE_WR(ctx, 0x179A8/4, 0x4); + INSTANCE_WR(ctx, 0x179C8/4, 0x4); + INSTANCE_WR(ctx, 0x17A08/4, 0x7FF); + INSTANCE_WR(ctx, 0x17A48/4, 0x102); + INSTANCE_WR(ctx, 0x17B88/4, 0x4); + INSTANCE_WR(ctx, 0x17BA8/4, 0x4); + INSTANCE_WR(ctx, 0x17BC8/4, 0x4); + INSTANCE_WR(ctx, 0x17BE8/4, 0x4); + INSTANCE_WR(ctx, 0x18228/4, 0x80C14); + INSTANCE_WR(ctx, 0x18288/4, 0x804); + INSTANCE_WR(ctx, 0x182C8/4, 0x4); + INSTANCE_WR(ctx, 0x182E8/4, 0x4); + INSTANCE_WR(ctx, 0x18308/4, 0x8100C12); + INSTANCE_WR(ctx, 0x18348/4, 0x4); + INSTANCE_WR(ctx, 0x18368/4, 0x4); + INSTANCE_WR(ctx, 0x183A8/4, 0x10); + INSTANCE_WR(ctx, 0x18448/4, 0x804); + INSTANCE_WR(ctx, 0x18468/4, 0x1); + INSTANCE_WR(ctx, 0x18488/4, 0x1A); + INSTANCE_WR(ctx, 0x184A8/4, 0x7F); + INSTANCE_WR(ctx, 0x184E8/4, 0x1); + INSTANCE_WR(ctx, 0x18508/4, 0x80C14); + INSTANCE_WR(ctx, 0x18548/4, 0x8100C12); + INSTANCE_WR(ctx, 0x18568/4, 0x4); + INSTANCE_WR(ctx, 0x18588/4, 0x4); + INSTANCE_WR(ctx, 0x185C8/4, 0x10); + INSTANCE_WR(ctx, 0x18648/4, 0x1); + INSTANCE_WR(ctx, 0x18668/4, 0x8100C12); + INSTANCE_WR(ctx, 0x18748/4, 0x7FF); + INSTANCE_WR(ctx, 0x18768/4, 0x80C14); + INSTANCE_WR(ctx, 0x18E88/4, 0x1); + INSTANCE_WR(ctx, 0x18EE8/4, 0x10); + INSTANCE_WR(ctx, 0x19608/4, 0x88); + INSTANCE_WR(ctx, 0x19628/4, 0x88); + INSTANCE_WR(ctx, 0x19688/4, 0x4); + INSTANCE_WR(ctx, 0x19968/4, 0x26); + INSTANCE_WR(ctx, 0x199C8/4, 0x3F800000); + INSTANCE_WR(ctx, 0x19A48/4, 0x1A); + INSTANCE_WR(ctx, 0x19A68/4, 0x10); + INSTANCE_WR(ctx, 0x19F88/4, 0x52); + INSTANCE_WR(ctx, 0x19FC8/4, 0x26); + INSTANCE_WR(ctx, 0x1A008/4, 0x4); + INSTANCE_WR(ctx, 0x1A028/4, 0x4); + INSTANCE_WR(ctx, 0x1A068/4, 0x1A); + INSTANCE_WR(ctx, 0x1A0C8/4, 0xFFFF00); + INSTANCE_WR(ctx, 0x1A108/4, 0x4); + INSTANCE_WR(ctx, 0x1A128/4, 0x4); + INSTANCE_WR(ctx, 0x1A168/4, 0x80); + INSTANCE_WR(ctx, 0x1A188/4, 0x4); + INSTANCE_WR(ctx, 0x1A1A8/4, 0x80C14); + INSTANCE_WR(ctx, 0x1A1E8/4, 0x7FF); + INSTANCE_WR(ctx, 0x24A48/4, 0x4); + INSTANCE_WR(ctx, 0x24A68/4, 0x4); + INSTANCE_WR(ctx, 0x24AA8/4, 0x80); + INSTANCE_WR(ctx, 0x24AC8/4, 0x4); + INSTANCE_WR(ctx, 0x24AE8/4, 0x1); + INSTANCE_WR(ctx, 0x24B28/4, 0x27); + INSTANCE_WR(ctx, 0x24B68/4, 0x26); + INSTANCE_WR(ctx, 0x24BE8/4, 0x4000000); + INSTANCE_WR(ctx, 0x24C08/4, 0x4000000); + INSTANCE_WR(ctx, 0x24C28/4, 0x4000000); + INSTANCE_WR(ctx, 0x24C48/4, 0x4000000); + INSTANCE_WR(ctx, 0x24C68/4, 0x4000000); + INSTANCE_WR(ctx, 0x24C88/4, 0x4000000); + INSTANCE_WR(ctx, 0x24CA8/4, 0x4000000); + INSTANCE_WR(ctx, 0x24CC8/4, 0x4000000); + INSTANCE_WR(ctx, 0x24CE8/4, 0x4000000); + INSTANCE_WR(ctx, 0x24D08/4, 0x4000000); + INSTANCE_WR(ctx, 0x24D28/4, 0x4000000); + INSTANCE_WR(ctx, 0x24D48/4, 0x4000000); + INSTANCE_WR(ctx, 0x24D68/4, 0x4000000); + INSTANCE_WR(ctx, 0x24D88/4, 0x4000000); + INSTANCE_WR(ctx, 0x24DA8/4, 0x4000000); + INSTANCE_WR(ctx, 0x24DC8/4, 0x4000000); + INSTANCE_WR(ctx, 0x25268/4, 0x4E3BFDF); + INSTANCE_WR(ctx, 0x25288/4, 0x4E3BFDF); + INSTANCE_WR(ctx, 0x252E8/4, 0x1FE21); + INSTANCE_WR(ctx, 0xB0C/4, 0x2); + INSTANCE_WR(ctx, 0xB4C/4, 0x1FFE67); + INSTANCE_WR(ctx, 0xCEC/4, 0x1); + INSTANCE_WR(ctx, 0xD0C/4, 0x10); + INSTANCE_WR(ctx, 0xD6C/4, 0x1); + INSTANCE_WR(ctx, 0xE0C/4, 0x4); + INSTANCE_WR(ctx, 0xE2C/4, 0x400); + INSTANCE_WR(ctx, 0xE4C/4, 0x300); + INSTANCE_WR(ctx, 0xE6C/4, 0x1001); + INSTANCE_WR(ctx, 0xE8C/4, 0x15); + INSTANCE_WR(ctx, 0xF4C/4, 0x2); + INSTANCE_WR(ctx, 0x106C/4, 0x1); + INSTANCE_WR(ctx, 0x108C/4, 0x10); + INSTANCE_WR(ctx, 0x10CC/4, 0x1); + INSTANCE_WR(ctx, 0x134C/4, 0x10); + INSTANCE_WR(ctx, 0x156C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x158C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x15AC/4, 0x3F800000); + INSTANCE_WR(ctx, 0x15CC/4, 0x3F800000); + INSTANCE_WR(ctx, 0x15EC/4, 0x3F800000); + INSTANCE_WR(ctx, 0x160C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x162C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x164C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x166C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x168C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x16AC/4, 0x3F800000); + INSTANCE_WR(ctx, 0x16CC/4, 0x3F800000); + INSTANCE_WR(ctx, 0x16EC/4, 0x3F800000); + INSTANCE_WR(ctx, 0x170C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x172C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x174C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x1A8C/4, 0x10); + INSTANCE_WR(ctx, 0x1ACC/4, 0x3F); + INSTANCE_WR(ctx, 0x1BAC/4, 0x1); + INSTANCE_WR(ctx, 0x1BEC/4, 0x1); + INSTANCE_WR(ctx, 0x1C2C/4, 0x1); + INSTANCE_WR(ctx, 0x1DCC/4, 0x11); + INSTANCE_WR(ctx, 0x1ECC/4, 0xF); + INSTANCE_WR(ctx, 0x1FCC/4, 0x11); + INSTANCE_WR(ctx, 0x20AC/4, 0x1); + INSTANCE_WR(ctx, 0x20CC/4, 0x1); + INSTANCE_WR(ctx, 0x20EC/4, 0x1); + INSTANCE_WR(ctx, 0x210C/4, 0x2); + INSTANCE_WR(ctx, 0x212C/4, 0x1); + INSTANCE_WR(ctx, 0x214C/4, 0x2); + INSTANCE_WR(ctx, 0x216C/4, 0x1); + INSTANCE_WR(ctx, 0x21AC/4, 0x1FFE67); + INSTANCE_WR(ctx, 0x21EC/4, 0xFAC6881); + INSTANCE_WR(ctx, 0x24AC/4, 0x1); + INSTANCE_WR(ctx, 0x24CC/4, 0x2); + INSTANCE_WR(ctx, 0x24EC/4, 0x1); + INSTANCE_WR(ctx, 0x250C/4, 0x1); + INSTANCE_WR(ctx, 0x252C/4, 0x2); + INSTANCE_WR(ctx, 0x254C/4, 0x1); + INSTANCE_WR(ctx, 0x256C/4, 0x1); + INSTANCE_WR(ctx, 0x25EC/4, 0x11); + INSTANCE_WR(ctx, 0x260C/4, 0x1); + INSTANCE_WR(ctx, 0x328C/4, 0x2); + INSTANCE_WR(ctx, 0x32CC/4, 0x1FFE67); + INSTANCE_WR(ctx, 0x346C/4, 0x1); + INSTANCE_WR(ctx, 0x348C/4, 0x10); + INSTANCE_WR(ctx, 0x34EC/4, 0x1); + INSTANCE_WR(ctx, 0x358C/4, 0x4); + INSTANCE_WR(ctx, 0x35AC/4, 0x400); + INSTANCE_WR(ctx, 0x35CC/4, 0x300); + INSTANCE_WR(ctx, 0x35EC/4, 0x1001); + INSTANCE_WR(ctx, 0x360C/4, 0x15); + INSTANCE_WR(ctx, 0x36CC/4, 0x2); + INSTANCE_WR(ctx, 0x37EC/4, 0x1); + INSTANCE_WR(ctx, 0x380C/4, 0x10); + INSTANCE_WR(ctx, 0x384C/4, 0x1); + INSTANCE_WR(ctx, 0x3ACC/4, 0x10); + INSTANCE_WR(ctx, 0x3CEC/4, 0x3F800000); + INSTANCE_WR(ctx, 0x3D0C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x3D2C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x3D4C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x3D6C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x3D8C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x3DAC/4, 0x3F800000); + INSTANCE_WR(ctx, 0x3DCC/4, 0x3F800000); + INSTANCE_WR(ctx, 0x3DEC/4, 0x3F800000); + INSTANCE_WR(ctx, 0x3E0C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x3E2C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x3E4C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x3E6C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x3E8C/4, 0x3F800000); + INSTANCE_WR(ctx, 0x3EAC/4, 0x3F800000); + INSTANCE_WR(ctx, 0x3ECC/4, 0x3F800000); + INSTANCE_WR(ctx, 0x420C/4, 0x10); + INSTANCE_WR(ctx, 0x424C/4, 0x3F); + INSTANCE_WR(ctx, 0x432C/4, 0x1); + INSTANCE_WR(ctx, 0x436C/4, 0x1); + INSTANCE_WR(ctx, 0x43AC/4, 0x1); + INSTANCE_WR(ctx, 0x454C/4, 0x11); + INSTANCE_WR(ctx, 0x464C/4, 0xF); + INSTANCE_WR(ctx, 0x474C/4, 0x11); + INSTANCE_WR(ctx, 0x482C/4, 0x1); + INSTANCE_WR(ctx, 0x484C/4, 0x1); + INSTANCE_WR(ctx, 0x486C/4, 0x1); + INSTANCE_WR(ctx, 0x488C/4, 0x2); + INSTANCE_WR(ctx, 0x48AC/4, 0x1); + INSTANCE_WR(ctx, 0x48CC/4, 0x2); + INSTANCE_WR(ctx, 0x48EC/4, 0x1); + INSTANCE_WR(ctx, 0x492C/4, 0x1FFE67); + INSTANCE_WR(ctx, 0x496C/4, 0xFAC6881); + INSTANCE_WR(ctx, 0x4C2C/4, 0x1); + INSTANCE_WR(ctx, 0x4C4C/4, 0x2); + INSTANCE_WR(ctx, 0x4C6C/4, 0x1); + INSTANCE_WR(ctx, 0x4C8C/4, 0x1); + INSTANCE_WR(ctx, 0x4CAC/4, 0x2); + INSTANCE_WR(ctx, 0x4CCC/4, 0x1); + INSTANCE_WR(ctx, 0x4CEC/4, 0x1); + INSTANCE_WR(ctx, 0x4D6C/4, 0x11); + INSTANCE_WR(ctx, 0x4D8C/4, 0x1); + INSTANCE_WR(ctx, 0xA30/4, 0x4); + INSTANCE_WR(ctx, 0xCF0/4, 0x4); + INSTANCE_WR(ctx, 0xD10/4, 0x4); + INSTANCE_WR(ctx, 0xD30/4, 0x608080); + INSTANCE_WR(ctx, 0xDD0/4, 0x4); + INSTANCE_WR(ctx, 0xE30/4, 0x4); + INSTANCE_WR(ctx, 0xE50/4, 0x4); + INSTANCE_WR(ctx, 0xE70/4, 0x80); + INSTANCE_WR(ctx, 0xE90/4, 0x1E00); + INSTANCE_WR(ctx, 0xEB0/4, 0x4); + INSTANCE_WR(ctx, 0x1350/4, 0x4); + INSTANCE_WR(ctx, 0x1370/4, 0x80); + INSTANCE_WR(ctx, 0x1390/4, 0x4); + INSTANCE_WR(ctx, 0x13B0/4, 0x3020100); + INSTANCE_WR(ctx, 0x13D0/4, 0x3); + INSTANCE_WR(ctx, 0x13F0/4, 0x1E00); + INSTANCE_WR(ctx, 0x1410/4, 0x4); + INSTANCE_WR(ctx, 0x14B0/4, 0x4); + INSTANCE_WR(ctx, 0x14D0/4, 0x3); + INSTANCE_WR(ctx, 0x1550/4, 0x4); + INSTANCE_WR(ctx, 0x159F0/4, 0x4); + INSTANCE_WR(ctx, 0x15A10/4, 0x3); + INSTANCE_WR(ctx, 0x15C50/4, 0xF); + INSTANCE_WR(ctx, 0x15DD0/4, 0x4); + INSTANCE_WR(ctx, 0x15DF0/4, 0xFFFF); + INSTANCE_WR(ctx, 0x15E10/4, 0xFFFF); + INSTANCE_WR(ctx, 0x15E30/4, 0xFFFF); + INSTANCE_WR(ctx, 0x15E50/4, 0xFFFF); + INSTANCE_WR(ctx, 0x15F70/4, 0x1); + INSTANCE_WR(ctx, 0x15FF0/4, 0x1); + INSTANCE_WR(ctx, 0x160B0/4, 0x1); + INSTANCE_WR(ctx, 0x16250/4, 0x1); + INSTANCE_WR(ctx, 0x16270/4, 0x1); + INSTANCE_WR(ctx, 0x16290/4, 0x2); + INSTANCE_WR(ctx, 0x162B0/4, 0x1); + INSTANCE_WR(ctx, 0x162D0/4, 0x1); + INSTANCE_WR(ctx, 0x162F0/4, 0x2); + INSTANCE_WR(ctx, 0x16310/4, 0x1); + INSTANCE_WR(ctx, 0x16350/4, 0x11); + INSTANCE_WR(ctx, 0x16450/4, 0xFAC6881); + INSTANCE_WR(ctx, 0x164B0/4, 0x4); + INSTANCE_WR(ctx, 0x16530/4, 0x11); + INSTANCE_WR(ctx, 0x16550/4, 0x1); + INSTANCE_WR(ctx, 0x16590/4, 0xCF); + INSTANCE_WR(ctx, 0x165B0/4, 0xCF); + INSTANCE_WR(ctx, 0x165D0/4, 0xCF); + INSTANCE_WR(ctx, 0x16730/4, 0x1); + INSTANCE_WR(ctx, 0x16750/4, 0x1); + INSTANCE_WR(ctx, 0x16770/4, 0x2); + INSTANCE_WR(ctx, 0x16790/4, 0x1); + INSTANCE_WR(ctx, 0x167B0/4, 0x1); + INSTANCE_WR(ctx, 0x167D0/4, 0x2); + INSTANCE_WR(ctx, 0x167F0/4, 0x1); + INSTANCE_WR(ctx, 0x16830/4, 0x1); + INSTANCE_WR(ctx, 0x16850/4, 0x1); + INSTANCE_WR(ctx, 0x16870/4, 0x1); + INSTANCE_WR(ctx, 0x16890/4, 0x1); + INSTANCE_WR(ctx, 0x168B0/4, 0x1); + INSTANCE_WR(ctx, 0x168D0/4, 0x1); + INSTANCE_WR(ctx, 0x168F0/4, 0x1); + INSTANCE_WR(ctx, 0x16910/4, 0x1); + INSTANCE_WR(ctx, 0x16930/4, 0x11); + INSTANCE_WR(ctx, 0x16A30/4, 0xFAC6881); + INSTANCE_WR(ctx, 0x16A50/4, 0xF); + INSTANCE_WR(ctx, 0x16B50/4, 0x1FFE67); + INSTANCE_WR(ctx, 0x16BB0/4, 0x11); + INSTANCE_WR(ctx, 0x16BD0/4, 0x1); + INSTANCE_WR(ctx, 0x16C50/4, 0x4); + INSTANCE_WR(ctx, 0x16D10/4, 0x1); + INSTANCE_WR(ctx, 0x16DB0/4, 0x11); + INSTANCE_WR(ctx, 0x16EB0/4, 0xFAC6881); + INSTANCE_WR(ctx, 0x16F30/4, 0x11); + INSTANCE_WR(ctx, 0x16F50/4, 0x1); + INSTANCE_WR(ctx, 0x16F90/4, 0x1); + INSTANCE_WR(ctx, 0x16FD0/4, 0x1); + INSTANCE_WR(ctx, 0x17010/4, 0x7FF); + INSTANCE_WR(ctx, 0x17050/4, 0x1); + INSTANCE_WR(ctx, 0x17090/4, 0x1); + INSTANCE_WR(ctx, 0x175F0/4, 0x8); + INSTANCE_WR(ctx, 0x17610/4, 0x8); + INSTANCE_WR(ctx, 0x17630/4, 0x8); + INSTANCE_WR(ctx, 0x17650/4, 0x8); + INSTANCE_WR(ctx, 0x17670/4, 0x8); + INSTANCE_WR(ctx, 0x17690/4, 0x8); + INSTANCE_WR(ctx, 0x176B0/4, 0x8); + INSTANCE_WR(ctx, 0x176D0/4, 0x8); + INSTANCE_WR(ctx, 0x176F0/4, 0x11); + INSTANCE_WR(ctx, 0x177F0/4, 0xFAC6881); + INSTANCE_WR(ctx, 0x17810/4, 0x400); + INSTANCE_WR(ctx, 0x17830/4, 0x400); + INSTANCE_WR(ctx, 0x17850/4, 0x400); + INSTANCE_WR(ctx, 0x17870/4, 0x400); + INSTANCE_WR(ctx, 0x17890/4, 0x400); + INSTANCE_WR(ctx, 0x178B0/4, 0x400); + INSTANCE_WR(ctx, 0x178D0/4, 0x400); + INSTANCE_WR(ctx, 0x178F0/4, 0x400); + INSTANCE_WR(ctx, 0x17910/4, 0x300); + INSTANCE_WR(ctx, 0x17930/4, 0x300); + INSTANCE_WR(ctx, 0x17950/4, 0x300); + INSTANCE_WR(ctx, 0x17970/4, 0x300); + INSTANCE_WR(ctx, 0x17990/4, 0x300); + INSTANCE_WR(ctx, 0x179B0/4, 0x300); + INSTANCE_WR(ctx, 0x179D0/4, 0x300); + INSTANCE_WR(ctx, 0x179F0/4, 0x300); + INSTANCE_WR(ctx, 0x17A10/4, 0x1); + INSTANCE_WR(ctx, 0x17A30/4, 0xF); + INSTANCE_WR(ctx, 0x17B30/4, 0x20); + INSTANCE_WR(ctx, 0x17B50/4, 0x11); + INSTANCE_WR(ctx, 0x17B70/4, 0x100); + INSTANCE_WR(ctx, 0x17BB0/4, 0x1); + INSTANCE_WR(ctx, 0x17C10/4, 0x40); + INSTANCE_WR(ctx, 0x17C30/4, 0x100); + INSTANCE_WR(ctx, 0x17C70/4, 0x3); + INSTANCE_WR(ctx, 0x17D10/4, 0x1FFE67); + INSTANCE_WR(ctx, 0x17D90/4, 0x2); + INSTANCE_WR(ctx, 0x17DB0/4, 0xFAC6881); + INSTANCE_WR(ctx, 0x17EF0/4, 0x1); + INSTANCE_WR(ctx, 0x17F90/4, 0x4); + INSTANCE_WR(ctx, 0x17FD0/4, 0x1); + INSTANCE_WR(ctx, 0x17FF0/4, 0x400); + INSTANCE_WR(ctx, 0x18010/4, 0x300); + INSTANCE_WR(ctx, 0x18030/4, 0x1001); + INSTANCE_WR(ctx, 0x180B0/4, 0x11); + INSTANCE_WR(ctx, 0x181B0/4, 0xFAC6881); + INSTANCE_WR(ctx, 0x181D0/4, 0xF); + INSTANCE_WR(ctx, 0x184D0/4, 0x1FFE67); + INSTANCE_WR(ctx, 0x18550/4, 0x11); + INSTANCE_WR(ctx, 0x185B0/4, 0x4); + INSTANCE_WR(ctx, 0x185F0/4, 0x1); + INSTANCE_WR(ctx, 0x18610/4, 0x1); + INSTANCE_WR(ctx, 0x18690/4, 0x1); + INSTANCE_WR(ctx, 0x18730/4, 0x1); + INSTANCE_WR(ctx, 0x18770/4, 0x1); + INSTANCE_WR(ctx, 0x187F0/4, 0x2A712488); + INSTANCE_WR(ctx, 0x18830/4, 0x4085C000); + INSTANCE_WR(ctx, 0x18850/4, 0x40); + INSTANCE_WR(ctx, 0x18870/4, 0x100); + INSTANCE_WR(ctx, 0x18890/4, 0x10100); + INSTANCE_WR(ctx, 0x188B0/4, 0x2800000); + INSTANCE_WR(ctx, 0x18B10/4, 0x4E3BFDF); + INSTANCE_WR(ctx, 0x18B30/4, 0x4E3BFDF); + INSTANCE_WR(ctx, 0x18B50/4, 0x1); + INSTANCE_WR(ctx, 0x18B90/4, 0xFFFF00); + INSTANCE_WR(ctx, 0x18BB0/4, 0x1); + INSTANCE_WR(ctx, 0x18C10/4, 0xFFFF00); + INSTANCE_WR(ctx, 0x18D30/4, 0x1); + INSTANCE_WR(ctx, 0x18D70/4, 0x1); + INSTANCE_WR(ctx, 0x18D90/4, 0x30201000); + INSTANCE_WR(ctx, 0x18DB0/4, 0x70605040); + INSTANCE_WR(ctx, 0x18DD0/4, 0xB8A89888); + INSTANCE_WR(ctx, 0x18DF0/4, 0xF8E8D8C8); + INSTANCE_WR(ctx, 0x18E30/4, 0x1A); +} + + int nv50_graph_create_context(struct nouveau_channel *chan) { @@ -272,10 +958,17 @@ nv50_graph_create_context(struct nouveau_channel *chan) INSTANCE_WR(ramin, (hdr + 0x10)/4, 0); INSTANCE_WR(ramin, (hdr + 0x14)/4, 0x00010000); - ret = engine->graph.load_context(chan); - if (ret) { - DRM_ERROR("Error hacking up initial context: %d\n", ret); - return ret; + switch (dev_priv->chipset) { + case 0x86: + nv86_graph_init_ctxvals(dev, chan->ramin_grctx); + break; + default: + ret = engine->graph.load_context(chan); + if (ret) { + DRM_ERROR("Error hacking up initial context: %d\n", ret); + return ret; + } + break; } INSTANCE_WR(chan->ramin_grctx->gpuobj, 0x00000/4, diff --git a/drivers/char/drm/nv50_instmem.c b/drivers/char/drm/nv50_instmem.c index 9687ecb..b7a51f0 100644 --- a/drivers/char/drm/nv50_instmem.c +++ b/drivers/char/drm/nv50_instmem.c @@ -243,7 +243,8 @@ nv50_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, uin return -EINVAL; gpuobj->im_backing = nouveau_mem_alloc(dev, NV50_INSTMEM_PAGE_SIZE, - *sz, NOUVEAU_MEM_FB, + *sz, NOUVEAU_MEM_FB | + NOUVEAU_MEM_NOVM, (struct drm_file *)-2); if (!gpuobj->im_backing) { DRM_ERROR("Couldn't allocate vram to back PRAMIN pages\n");