summaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
Diffstat (limited to 'shared-core')
-rw-r--r--shared-core/drm.h20
-rw-r--r--shared-core/drm_pciids.txt35
-rw-r--r--shared-core/i915_dma.c10
-rw-r--r--shared-core/i915_drv.h117
-rw-r--r--shared-core/nouveau_dma.c177
-rw-r--r--shared-core/nouveau_dma.h98
-rw-r--r--shared-core/nouveau_drm.h35
-rw-r--r--shared-core/nouveau_drv.h456
-rw-r--r--shared-core/nouveau_fifo.c250
-rw-r--r--shared-core/nouveau_irq.c241
-rw-r--r--shared-core/nouveau_mem.c78
-rw-r--r--shared-core/nouveau_notifier.c88
-rw-r--r--shared-core/nouveau_object.c322
-rw-r--r--shared-core/nouveau_reg.h22
-rw-r--r--shared-core/nouveau_state.c74
-rw-r--r--shared-core/nv04_fifo.c29
-rw-r--r--shared-core/nv04_graph.c657
-rw-r--r--shared-core/nv04_instmem.c27
-rw-r--r--shared-core/nv04_mc.c2
-rw-r--r--shared-core/nv10_fifo.c29
-rw-r--r--shared-core/nv10_graph.c181
-rw-r--r--shared-core/nv20_graph.c70
-rw-r--r--shared-core/nv30_graph.c2857
-rw-r--r--shared-core/nv40_fifo.c37
-rw-r--r--shared-core/nv40_graph.c117
-rw-r--r--shared-core/nv40_mc.c2
-rw-r--r--shared-core/nv50_fifo.c120
-rw-r--r--shared-core/nv50_graph.c45
-rw-r--r--shared-core/nv50_instmem.c246
-rw-r--r--shared-core/nv50_mc.c1
-rw-r--r--shared-core/r128_drm.h18
31 files changed, 4961 insertions, 1500 deletions
diff --git a/shared-core/drm.h b/shared-core/drm.h
index db913b1f..a9882d49 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -89,24 +89,6 @@
#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
#endif
-#define XFREE86_VERSION(major,minor,patch,snap) \
- ((major << 16) | (minor << 8) | patch)
-
-#ifndef CONFIG_XFREE86_VERSION
-#define CONFIG_XFREE86_VERSION XFREE86_VERSION(4,1,0,0)
-#endif
-
-#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
-#define DRM_PROC_DEVICES "/proc/devices"
-#define DRM_PROC_MISC "/proc/misc"
-#define DRM_PROC_DRM "/proc/drm"
-#define DRM_DEV_DRM "/dev/drm"
-#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
-#define DRM_DEV_UID 0
-#define DRM_DEV_GID 0
-#endif
-
-#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0)
#ifdef __OpenBSD__
#define DRM_MAJOR 81
#endif
@@ -114,7 +96,7 @@
#define DRM_MAJOR 226
#endif
#define DRM_MAX_MINOR 15
-#endif
+
#define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */
#define DRM_MIN_ORDER 5 /**< At least 2^5 bytes = 32 bytes */
#define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */
diff --git a/shared-core/drm_pciids.txt b/shared-core/drm_pciids.txt
index 4504cf77..39ddc1c5 100644
--- a/shared-core/drm_pciids.txt
+++ b/shared-core/drm_pciids.txt
@@ -482,9 +482,6 @@
0x10DE 0x009E NV40 "NVidia 0x009E"
[nouveau]
-0x10de 0x0008 NV_03 "EDGE 3D"
-0x10de 0x0009 NV_03 "EDGE 3D"
-0x10de 0x0010 NV_03 "Mutara V08"
0x10de 0x0020 NV_04 "RIVA TNT"
0x10de 0x0028 NV_04 "RIVA TNT2/TNT2 Pro"
0x10de 0x0029 NV_04 "RIVA TNT2 Ultra"
@@ -510,8 +507,9 @@
0x10de 0x0091 NV_40 "GeForce 7800 GTX"
0x10de 0x0092 NV_40 "GeForce 7800 GT"
0x10de 0x0093 NV_40 "GeForce 7800 GS"
+0x10de 0x0095 NV_40 "GeForce 7800 SLI"
0x10de 0x0098 NV_40 "GeForce Go 7800"
-0x10de 0x0099 NV_40 "GE Force Go 7800 GTX"
+0x10de 0x0099 NV_40 "GeForce Go 7800 GTX"
0x10de 0x009d NV_40 "Quadro FX4500"
0x10de 0x00a0 NV_04 "Aladdin TNT2"
0x10de 0x00c0 NV_40 "GeForce 6800 GS"
@@ -547,13 +545,16 @@
0x10de 0x0113 NV_11 "Quadro2 MXR/EX/Go"
0x10de 0x0140 NV_40 "GeForce 6600 GT"
0x10de 0x0141 NV_40 "GeForce 6600"
-0x10de 0x0142 NV_40 "GeForce 6600 PCIe"
+0x10de 0x0142 NV_40 "GeForce 6600 LE"
+0x10de 0x0143 NV_40 "GeForce 6600 VE"
0x10de 0x0144 NV_40 "GeForce Go 6600"
0x10de 0x0145 NV_40 "GeForce 6610 XL"
0x10de 0x0146 NV_40 "Geforce Go 6600TE/6200TE"
+0x10de 0x0147 NV_40 "GeForce 6700 XL"
0x10de 0x0148 NV_40 "GeForce Go 6600"
0x10de 0x0149 NV_40 "GeForce Go 6600 GT"
0x10de 0x014a NV_40 "Quadro NVS 440"
+0x10de 0x014c NV_40 "Quadro FX 550"
0x10de 0x014d NV_17 "Quadro FX 550"
0x10de 0x014e NV_40 "Quadro FX 540"
0x10de 0x014f NV_40 "GeForce 6200"
@@ -561,6 +562,7 @@
0x10de 0x0151 NV_15 "GeForce2 Ti"
0x10de 0x0152 NV_15 "GeForce2 Ultra, Bladerunner"
0x10de 0x0153 NV_15 "Quadro2 Pro"
+0x10de 0x0160 NV_44 "GeForce 6500"
0x10de 0x0161 NV_44 "GeForce 6200 TurboCache(TM)"
0x10de 0x0162 NV_44 "GeForce 6200 SE TurboCache (TM)"
0x10de 0x0163 NV_44 "GeForce 6200 LE"
@@ -569,6 +571,7 @@
0x10de 0x0166 NV_44 "GeForce Go 6400"
0x10de 0x0167 NV_44 "GeForce Go 6200 TurboCache"
0x10de 0x0168 NV_44 "GeForce Go 6200 TurboCache"
+0x10de 0x0169 NV_44 "GeForce 6250"
0x10de 0x0170 NV_17 "GeForce4 MX 460"
0x10de 0x0171 NV_17 "GeForce4 MX 440"
0x10de 0x0172 NV_17 "GeForce4 MX 420"
@@ -601,11 +604,16 @@
0x10de 0x019e NV_50 "Quadro FX 4600"
0x10de 0x01a0 NV_11|NV_NFORCE "GeForce2 MX Integrated Graphics"
0x10de 0x01d1 NV_44 "GeForce 7300 LE"
+0x10de 0x01d3 NV_44 "Geforce 7300 SE"
0x10de 0x01d6 NV_44 "GeForce Go 7200"
0x10de 0x01d7 NV_44 "Quadro NVS 110M / GeForce Go 7300"
0x10de 0x01d8 NV_44 "GeForce Go 7400"
+0x10de 0x01d9 NV_44 "GeForce Go 7400 GS"
0x10de 0x01da NV_44 "Quadro NVS 110M"
+0x10de 0x01db NV_44 "Quadro NVS 120M"
0x10de 0x01dc NV_44 "Quadro FX 350M"
+0x10de 0x01dd NV_44 "GeForce 7500 LE"
+0x10de 0x01de NV_44 "Quadro FX 350"
0x10de 0x01df NV_44 "GeForce 7300 GS"
0x10de 0x01f0 NV_17|NV_NFORCE2 "GeForce4 MX - nForce GPU"
0x10de 0x0200 NV_20 "GeForce3"
@@ -617,9 +625,12 @@
0x10de 0x0215 NV_40 "GeForce 6800 GT"
0x10de 0x0218 NV_40 "GeForce 6800 XT"
0x10de 0x0221 NV_44 "GeForce 6200"
+0x10de 0x0222 NV_44 "GeForce 6200 A-LE"
0x10de 0x0240 NV_44 "GeForce 6150"
+0x10de 0x0241 NV_44 "GeForce 6150 LE"
0x10de 0x0242 NV_44 "GeForce 6100"
-0x10de 0x0244 NV_44 "GeForce 6150 Go"
+0x10de 0x0244 NV_44 "GeForce Go 6150"
+0x10de 0x0247 NV_44 "GeForce Go 6100"
0x10de 0x0250 NV_25 "GeForce4 Ti 4600"
0x10de 0x0251 NV_25 "GeForce4 Ti 4400"
0x10de 0x0252 NV_25 "GeForce4 Ti"
@@ -700,7 +711,15 @@
0x10de 0x0391 NV_40 "GeForce 7600 GT"
0x10de 0x0392 NV_40 "GeForce 7600 GS"
0x10de 0x0393 NV_40 "GeForce 7300 GT"
+0x10de 0x0394 NV_40 "GeForce 7600 LE"
+0x10de 0x0395 NV_40 "GeForce 7300 GT"
+0x10de 0x0397 NV_40 "GeForce Go 7700"
0x10de 0x0398 NV_40 "GeForce Go 7600"
+0x10de 0x0399 NV_40 "GeForce Go 7600 GT"
+0x10de 0x039a NV_40 "Quadro NVS 300M"
+0x10de 0x039b NV_40 "GeForce Go 7900 SE"
+0x10de 0x039c NV_40 "Quadro FX 550M"
+0x10de 0x039e NV_40 "Quadro FX 560"
0x10de 0x03d0 NV_44 "GeForce 6100 nForce 430"
0x10de 0x03d1 NV_44 "GeForce 6100 nForce 405"
0x10de 0x03d2 NV_44 "GeForce 6100 nForce 400"
@@ -710,10 +729,6 @@
0x10de 0x0421 NV_50 "GeForce 8500 GT"
0x10de 0x0422 NV_50 "GeForce 8400 GS"
0x10de 0x0423 NV_50 "GeForce 8300 GS"
-0x12d2 0x0008 NV_03 "NV1"
-0x12d2 0x0009 NV_03 "DAC64"
-0x12d2 0x0018 NV_03 "Riva128"
-0x12d2 0x0019 NV_03 "Riva128ZX"
0x12d2 0x0020 NV_04 "TNT"
0x12d2 0x0028 NV_04 "TNT2"
0x12d2 0x0029 NV_04 "UTNT2"
diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c
index 5d227d8b..9f18feee 100644
--- a/shared-core/i915_dma.c
+++ b/shared-core/i915_dma.c
@@ -546,9 +546,15 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
if (dev_priv->use_mi_batchbuffer_start) {
BEGIN_LP_RING(2);
- OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
- OUT_RING(batch->start | MI_BATCH_NON_SECURE);
+ if (IS_I965G(dev)) {
+ OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
+ OUT_RING(batch->start);
+ } else {
+ OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
+ OUT_RING(batch->start | MI_BATCH_NON_SECURE);
+ }
ADVANCE_LP_RING();
+
} else {
BEGIN_LP_RING(4);
OUT_RING(MI_BATCH_BUFFER);
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h
index e641fdc6..aff03bee 100644
--- a/shared-core/i915_drv.h
+++ b/shared-core/i915_drv.h
@@ -272,12 +272,25 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define MI_NO_WRITE_FLUSH (1 << 2)
#define MI_READ_FLUSH (1 << 0)
#define MI_EXE_FLUSH (1 << 1)
+#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
+#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
+
+/* Packet to load a register value from the ring/batch command stream:
+ */
+#define CMD_MI_LOAD_REGISTER_IMM ((0x22 << 23)|0x1)
#define BB1_START_ADDR_MASK (~0x7)
#define BB1_PROTECTED (1<<0)
#define BB1_UNPROTECTED (0<<0)
#define BB2_END_ADDR_MASK (~0x7)
+/* Interrupt bits:
+ */
+#define USER_INT_FLAG (1<<1)
+#define VSYNC_PIPEB_FLAG (1<<5)
+#define VSYNC_PIPEA_FLAG (1<<7)
+#define HWB_OOM_FLAG (1<<13) /* binner out of memory */
+
#define I915REG_HWSTAM 0x02098
#define I915REG_INT_IDENTITY_R 0x020a4
#define I915REG_INT_MASK_R 0x020a8
@@ -315,6 +328,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define NOPID 0x2094
#define LP_RING 0x2030
#define HP_RING 0x2040
+/* The binner has its own ring buffer:
+ */
+#define HWB_RING 0x2400
+
#define RING_TAIL 0x00
#define TAIL_ADDR 0x001FFFF8
#define RING_HEAD 0x04
@@ -333,11 +350,105 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define RING_VALID 0x00000001
#define RING_INVALID 0x00000000
+/* Instruction parser error reg:
+ */
+#define IPEIR 0x2088
+
+/* Scratch pad debug 0 reg:
+ */
+#define SCPD0 0x209c
+
+/* Error status reg:
+ */
+#define ESR 0x20b8
+
+/* Secondary DMA fetch address debug reg:
+ */
+#define DMA_FADD_S 0x20d4
+
+/* Cache mode 0 reg.
+ * - Manipulating render cache behaviour is central
+ * to the concept of zone rendering, tuning this reg can help avoid
+ * unnecessary render cache reads and even writes (for z/stencil)
+ * at beginning and end of scene.
+ *
+ * - To change a bit, write to this reg with a mask bit set and the
+ * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set.
+ */
+#define Cache_Mode_0 0x2120
+#define CM0_MASK_SHIFT 16
+#define CM0_IZ_OPT_DISABLE (1<<6)
+#define CM0_ZR_OPT_DISABLE (1<<5)
+#define CM0_DEPTH_EVICT_DISABLE (1<<4)
+#define CM0_COLOR_EVICT_DISABLE (1<<3)
+#define CM0_DEPTH_WRITE_DISABLE (1<<1)
+#define CM0_RC_OP_FLUSH_DISABLE (1<<0)
+
+
+/* Graphics flush control. A CPU write flushes the GWB of all writes.
+ * The data is discarded.
+ */
+#define GFX_FLSH_CNTL 0x2170
+
+/* Binner control. Defines the location of the bin pointer list:
+ */
+#define BINCTL 0x2420
+#define BC_MASK (1 << 9)
+
+/* Binned scene info.
+ */
+#define BINSCENE 0x2428
+#define BS_OP_LOAD (1 << 8)
+#define BS_MASK (1 << 22)
+
+/* Bin command parser debug reg:
+ */
+#define BCPD 0x2480
+
+/* Bin memory control debug reg:
+ */
+#define BMCD 0x2484
+
+/* Bin data cache debug reg:
+ */
+#define BDCD 0x2488
+
+/* Binner pointer cache debug reg:
+ */
+#define BPCD 0x248c
+
+/* Binner scratch pad debug reg:
+ */
+#define BINSKPD 0x24f0
+
+/* HWB scratch pad debug reg:
+ */
+#define HWBSKPD 0x24f4
+
+/* Binner memory pool reg:
+ */
+#define BMP_BUFFER 0x2430
+#define BMP_PAGE_SIZE_4K (0 << 10)
+#define BMP_BUFFER_SIZE_SHIFT 1
+#define BMP_ENABLE (1 << 0)
+
+/* Get/put memory from the binner memory pool:
+ */
+#define BMP_GET 0x2438
+#define BMP_PUT 0x2440
+#define BMP_OFFSET_SHIFT 5
+
+/* 3D state packets:
+ */
+#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24))
+
#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
#define SC_UPDATE_SCISSOR (0x1<<1)
#define SC_ENABLE_MASK (0x1<<0)
#define SC_ENABLE (0x1<<0)
+#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16))
+
#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
#define SCI_YMIN_MASK (0xffff<<16)
#define SCI_XMIN_MASK (0xffff<<0)
@@ -364,6 +475,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define MI_BATCH_BUFFER_END (0xA<<23)
#define MI_BATCH_NON_SECURE (1)
+#define MI_BATCH_NON_SECURE_I965 (1<<8)
+
#define MI_WAIT_FOR_EVENT ((0x3<<23))
#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
@@ -376,6 +489,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define DISPLAY_PLANE_A (0<<20)
#define DISPLAY_PLANE_B (1<<20)
+/* Define the region of interest for the binner:
+ */
+#define CMD_OP_BIN_CONTROL ((0x3<<29)|(0x1d<<24)|(0x84<<16)|4)
+
#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
#define BREADCRUMB_BITS 31
diff --git a/shared-core/nouveau_dma.c b/shared-core/nouveau_dma.c
new file mode 100644
index 00000000..ab502e6a
--- /dev/null
+++ b/shared-core/nouveau_dma.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_dma.h"
+
+#define SKIPS 8
+
+int
+nouveau_dma_channel_init(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm_channel *dchan = &dev_priv->channel;
+ struct nouveau_gpuobj *gpuobj = NULL;
+ struct mem_block *pushbuf;
+ int grclass, ret, i;
+
+ DRM_DEBUG("\n");
+
+ pushbuf = nouveau_mem_alloc(dev, 0, 0x8000,
+ NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED,
+ (struct drm_file *)-2);
+ if (!pushbuf) {
+ DRM_ERROR("Failed to allocate DMA push buffer\n");
+ return -ENOMEM;
+ }
+
+ /* Allocate channel */
+ ret = nouveau_fifo_alloc(dev, &dchan->chan, (struct drm_file *)-2,
+ pushbuf, NvDmaFB, NvDmaTT);
+ if (ret) {
+ DRM_ERROR("Error allocating GPU channel: %d\n", ret);
+ return ret;
+ }
+ DRM_DEBUG("Using FIFO channel %d\n", dchan->chan->id);
+
+ /* Map push buffer */
+ drm_core_ioremap(dchan->chan->pushbuf_mem->map, dev);
+ if (!dchan->chan->pushbuf_mem->map->handle) {
+ DRM_ERROR("Failed to ioremap push buffer\n");
+ return -EINVAL;
+ }
+ dchan->pushbuf = (void*)dchan->chan->pushbuf_mem->map->handle;
+
+ /* Initialise DMA vars */
+ dchan->max = (dchan->chan->pushbuf_mem->size >> 2) - 2;
+ dchan->put = dchan->chan->pushbuf_base >> 2;
+ dchan->cur = dchan->put;
+ dchan->free = dchan->max - dchan->cur;
+
+ /* Insert NOPS for SKIPS */
+ dchan->free -= SKIPS;
+ dchan->push_free = SKIPS;
+ for (i=0; i<SKIPS; i++)
+ OUT_RING(0);
+
+ /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier */
+ if ((ret = nouveau_notifier_alloc(dchan->chan, NvNotify0, 1,
+ &dchan->notify0_offset))) {
+ DRM_ERROR("Error allocating NvNotify0: %d\n", ret);
+ return ret;
+ }
+
+ /* We use NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */
+ if (dev_priv->card_type < NV_50) grclass = NV_MEMORY_TO_MEMORY_FORMAT;
+ else grclass = NV50_MEMORY_TO_MEMORY_FORMAT;
+ if ((ret = nouveau_gpuobj_gr_new(dchan->chan, grclass, &gpuobj))) {
+ DRM_ERROR("Error creating NvM2MF: %d\n", ret);
+ return ret;
+ }
+
+ if ((ret = nouveau_gpuobj_ref_add(dev, dchan->chan, NvM2MF,
+ gpuobj, NULL))) {
+ DRM_ERROR("Error referencing NvM2MF: %d\n", ret);
+ return ret;
+ }
+ dchan->m2mf_dma_source = NvDmaFB;
+ dchan->m2mf_dma_destin = NvDmaFB;
+
+ BEGIN_RING(NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NAME, 1);
+ OUT_RING (NvM2MF);
+ BEGIN_RING(NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_SET_DMA_NOTIFY, 1);
+ OUT_RING (NvNotify0);
+ BEGIN_RING(NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_SET_DMA_SOURCE, 2);
+ OUT_RING (dchan->m2mf_dma_source);
+ OUT_RING (dchan->m2mf_dma_destin);
+ FIRE_RING();
+
+ return 0;
+}
+
+void
+nouveau_dma_channel_takedown(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm_channel *dchan = &dev_priv->channel;
+
+ DRM_DEBUG("\n");
+
+ if (dchan->chan) {
+ nouveau_fifo_free(dchan->chan);
+ dchan->chan = NULL;
+ }
+}
+
+#define RING_SKIPS 8
+
+#define READ_GET() ((NV_READ(NV03_FIFO_REGS_DMAGET(dchan->chan->id)) - \
+ dchan->chan->pushbuf_base) >> 2)
+#define WRITE_PUT(val) do { \
+ NV_WRITE(NV03_FIFO_REGS_DMAPUT(dchan->chan->id), \
+ ((val) << 2) + dchan->chan->pushbuf_base); \
+} while(0)
+
+int
+nouveau_dma_wait(struct drm_device *dev, int size)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_drm_channel *dchan = &dev_priv->channel;
+ uint32_t get;
+
+ while (dchan->free < size) {
+ get = READ_GET();
+
+ if (dchan->put >= get) {
+ dchan->free = dchan->max - dchan->cur;
+
+ if (dchan->free < size) {
+ dchan->push_free = 1;
+ OUT_RING(0x20000000|dchan->chan->pushbuf_base);
+ if (get <= RING_SKIPS) {
+ /*corner case - will be idle*/
+ if (dchan->put <= RING_SKIPS)
+ WRITE_PUT(RING_SKIPS + 1);
+
+ do {
+ get = READ_GET();
+ } while (get <= RING_SKIPS);
+ }
+
+ WRITE_PUT(RING_SKIPS);
+ dchan->cur = dchan->put = RING_SKIPS;
+ dchan->free = get - (RING_SKIPS + 1);
+ }
+ } else {
+ dchan->free = get - dchan->cur - 1;
+ }
+ }
+
+ return 0;
+}
+
diff --git a/shared-core/nouveau_dma.h b/shared-core/nouveau_dma.h
new file mode 100644
index 00000000..5e51c1c4
--- /dev/null
+++ b/shared-core/nouveau_dma.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __NOUVEAU_DMA_H__
+#define __NOUVEAU_DMA_H__
+
+typedef enum {
+ NvSubM2MF = 0,
+} nouveau_subchannel_id_t;
+
+typedef enum {
+ NvM2MF = 0x80039001,
+ NvDmaFB = 0x8003d001,
+ NvDmaTT = 0x8003d002,
+ NvNotify0 = 0x8003d003
+} nouveau_object_handle_t;
+
+#define NV_MEMORY_TO_MEMORY_FORMAT 0x00000039
+#define NV_MEMORY_TO_MEMORY_FORMAT_NAME 0x00000000
+#define NV_MEMORY_TO_MEMORY_FORMAT_SET_REF 0x00000050
+#define NV_MEMORY_TO_MEMORY_FORMAT_NOP 0x00000100
+#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104
+#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE 0x00000000
+#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE_LE_AWAKEN 0x00000001
+#define NV_MEMORY_TO_MEMORY_FORMAT_SET_DMA_NOTIFY 0x00000180
+#define NV_MEMORY_TO_MEMORY_FORMAT_SET_DMA_SOURCE 0x00000184
+#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c
+
+#define NV50_MEMORY_TO_MEMORY_FORMAT 0x00005039
+#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK200 0x00000200
+#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK21C 0x0000021c
+#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH 0x00000238
+#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT_HIGH 0x0000023c
+
+#define BEGIN_RING(subc, mthd, cnt) do { \
+ int push_size = (cnt) + 1; \
+ if (dchan->push_free) { \
+ DRM_ERROR("prior packet incomplete: %d\n", dchan->push_free); \
+ break; \
+ } \
+ if (dchan->free < push_size) { \
+ if (nouveau_dma_wait(dev, push_size)) { \
+ DRM_ERROR("FIFO timeout\n"); \
+ break; \
+ } \
+ } \
+ dchan->free -= push_size; \
+ dchan->push_free = push_size; \
+ OUT_RING(((cnt)<<18) | ((subc)<<15) | mthd); \
+} while(0)
+
+#define OUT_RING(data) do { \
+ if (dchan->push_free == 0) { \
+ DRM_ERROR("no space left in packet\n"); \
+ break; \
+ } \
+ dchan->pushbuf[dchan->cur++] = (data); \
+ dchan->push_free--; \
+} while(0)
+
+#define FIRE_RING() do { \
+ if (dchan->push_free) { \
+ DRM_ERROR("packet incomplete: %d\n", dchan->push_free); \
+ break; \
+ } \
+ if (dchan->cur != dchan->put) { \
+ DRM_MEMORYBARRIER(); \
+ dchan->put = dchan->cur; \
+ NV_WRITE(NV03_FIFO_REGS_DMAPUT(dchan->chan->id), \
+ (dchan->put<<2)); \
+ } \
+} while(0)
+
+#endif
+
diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h
index 4016f004..c4f1e9a4 100644
--- a/shared-core/nouveau_drm.h
+++ b/shared-core/nouveau_drm.h
@@ -25,9 +25,9 @@
#ifndef __NOUVEAU_DRM_H__
#define __NOUVEAU_DRM_H__
-#define NOUVEAU_DRM_HEADER_PATCHLEVEL 9
+#define NOUVEAU_DRM_HEADER_PATCHLEVEL 10
-struct drm_nouveau_fifo_alloc {
+struct drm_nouveau_channel_alloc {
uint32_t fb_ctxdma_handle;
uint32_t tt_ctxdma_handle;
@@ -44,6 +44,10 @@ struct drm_nouveau_fifo_alloc {
int notifier_size;
};
+struct drm_nouveau_channel_free {
+ int channel;
+};
+
struct drm_nouveau_grobj_alloc {
int channel;
uint32_t handle;
@@ -53,7 +57,7 @@ struct drm_nouveau_grobj_alloc {
#define NOUVEAU_MEM_ACCESS_RO 1
#define NOUVEAU_MEM_ACCESS_WO 2
#define NOUVEAU_MEM_ACCESS_RW 3
-struct drm_nouveau_notifier_alloc {
+struct drm_nouveau_notifierobj_alloc {
int channel;
uint32_t handle;
int count;
@@ -61,6 +65,11 @@ struct drm_nouveau_notifier_alloc {
uint32_t offset;
};
+struct drm_nouveau_gpuobj_free {
+ int channel;
+ uint32_t handle;
+};
+
#define NOUVEAU_MEM_FB 0x00000001
#define NOUVEAU_MEM_AGP 0x00000002
#define NOUVEAU_MEM_FB_ACCEPTABLE 0x00000004
@@ -95,6 +104,7 @@ struct drm_nouveau_mem_free {
#define NOUVEAU_GETPARAM_FB_SIZE 8
#define NOUVEAU_GETPARAM_AGP_SIZE 9
#define NOUVEAU_GETPARAM_PCI_PHYSICAL 10
+#define NOUVEAU_GETPARAM_CHIPSET_ID 11
struct drm_nouveau_getparam {
uint64_t param;
uint64_t value;
@@ -109,8 +119,6 @@ struct drm_nouveau_setparam {
enum nouveau_card_type {
NV_UNKNOWN =0,
- NV_01 =1,
- NV_03 =3,
NV_04 =4,
NV_05 =5,
NV_10 =10,
@@ -141,13 +149,16 @@ struct drm_nouveau_sarea {
unsigned int nbox;
};
-#define DRM_NOUVEAU_FIFO_ALLOC 0x00
-#define DRM_NOUVEAU_GROBJ_ALLOC 0x01
-#define DRM_NOUVEAU_NOTIFIER_ALLOC 0x02
-#define DRM_NOUVEAU_MEM_ALLOC 0x03
-#define DRM_NOUVEAU_MEM_FREE 0x04
-#define DRM_NOUVEAU_GETPARAM 0x05
-#define DRM_NOUVEAU_SETPARAM 0x06
+#define DRM_NOUVEAU_CARD_INIT 0x00
+#define DRM_NOUVEAU_GETPARAM 0x01
+#define DRM_NOUVEAU_SETPARAM 0x02
+#define DRM_NOUVEAU_CHANNEL_ALLOC 0x03
+#define DRM_NOUVEAU_CHANNEL_FREE 0x04
+#define DRM_NOUVEAU_GROBJ_ALLOC 0x05
+#define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x06
+#define DRM_NOUVEAU_GPUOBJ_FREE 0x07
+#define DRM_NOUVEAU_MEM_ALLOC 0x08
+#define DRM_NOUVEAU_MEM_FREE 0x09
#endif /* __NOUVEAU_DRM_H__ */
diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h
index dd323a0b..e96c8fad 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 9
+#define DRIVER_PATCHLEVEL 10
#define NOUVEAU_FAMILY 0x0000FFFF
#define NOUVEAU_FLAGS 0xFFFF0000
@@ -67,8 +67,7 @@ enum nouveau_flags {
#define NVOBJ_FLAG_ZERO_FREE (1 << 2)
#define NVOBJ_FLAG_FAKE (1 << 3)
struct nouveau_gpuobj {
- struct nouveau_gpuobj *next;
- struct nouveau_gpuobj *prev;
+ struct list_head list;
int im_channel;
struct mem_block *im_pramin;
@@ -80,10 +79,13 @@ struct nouveau_gpuobj {
uint32_t engine;
uint32_t class;
+
+ void (*dtor)(struct drm_device *, struct nouveau_gpuobj *);
+ void *priv;
};
struct nouveau_gpuobj_ref {
- struct nouveau_gpuobj_ref *next;
+ struct list_head list;
struct nouveau_gpuobj *gpuobj;
uint32_t instance;
@@ -92,8 +94,11 @@ struct nouveau_gpuobj_ref {
int handle;
};
-struct nouveau_fifo
+struct nouveau_channel
{
+ struct drm_device *dev;
+ int id;
+
/* owner of this fifo */
struct drm_file *file_priv;
/* mapping of the fifo itself */
@@ -126,7 +131,23 @@ struct nouveau_fifo
struct nouveau_gpuobj_ref *ramin; /* Private instmem */
struct mem_block *ramin_heap; /* Private PRAMIN heap */
struct nouveau_gpuobj_ref *ramht; /* Hash table */
- struct nouveau_gpuobj_ref *ramht_refs; /* Objects referenced by RAMHT */
+ struct list_head ramht_refs; /* Objects referenced by RAMHT */
+};
+
+struct nouveau_drm_channel {
+ struct nouveau_channel *chan;
+
+ /* DMA state */
+ int max, put, cur, free;
+ int push_free;
+ volatile uint32_t *pushbuf;
+
+ /* Notifiers */
+ uint32_t notify0_offset;
+
+ /* Buffer moves */
+ uint32_t m2mf_dma_source;
+ uint32_t m2mf_dma_destin;
};
struct nouveau_config {
@@ -136,57 +157,64 @@ struct nouveau_config {
} cmdbuf;
};
-struct nouveau_engine_func {
- struct {
- void *priv;
+struct nouveau_instmem_engine {
+ void *priv;
- int (*init)(struct drm_device *dev);
- void (*takedown)(struct drm_device *dev);
+ int (*init)(struct drm_device *dev);
+ void (*takedown)(struct drm_device *dev);
- int (*populate)(struct drm_device *, struct nouveau_gpuobj *,
- uint32_t *size);
- void (*clear)(struct drm_device *, struct nouveau_gpuobj *);
- int (*bind)(struct drm_device *, struct nouveau_gpuobj *);
- int (*unbind)(struct drm_device *, struct nouveau_gpuobj *);
- } instmem;
+ int (*populate)(struct drm_device *, struct nouveau_gpuobj *,
+ uint32_t *size);
+ void (*clear)(struct drm_device *, struct nouveau_gpuobj *);
+ int (*bind)(struct drm_device *, struct nouveau_gpuobj *);
+ int (*unbind)(struct drm_device *, struct nouveau_gpuobj *);
+};
- struct {
- int (*init)(struct drm_device *dev);
- void (*takedown)(struct drm_device *dev);
- } mc;
+struct nouveau_mc_engine {
+ int (*init)(struct drm_device *dev);
+ void (*takedown)(struct drm_device *dev);
+};
- struct {
- int (*init)(struct drm_device *dev);
- uint64_t (*read)(struct drm_device *dev);
- void (*takedown)(struct drm_device *dev);
- } timer;
+struct nouveau_timer_engine {
+ int (*init)(struct drm_device *dev);
+ void (*takedown)(struct drm_device *dev);
+ uint64_t (*read)(struct drm_device *dev);
+};
- struct {
- int (*init)(struct drm_device *dev);
- void (*takedown)(struct drm_device *dev);
- } fb;
+struct nouveau_fb_engine {
+ int (*init)(struct drm_device *dev);
+ void (*takedown)(struct drm_device *dev);
+};
- struct {
- int (*init)(struct drm_device *);
- void (*takedown)(struct drm_device *);
+struct nouveau_fifo_engine {
+ void *priv;
- int (*create_context)(struct drm_device *, int channel);
- void (*destroy_context)(struct drm_device *, int channel);
- int (*load_context)(struct drm_device *, int channel);
- int (*save_context)(struct drm_device *, int channel);
- } graph;
+ int (*init)(struct drm_device *);
+ void (*takedown)(struct drm_device *);
- struct {
- void *priv;
+ int (*create_context)(struct nouveau_channel *);
+ void (*destroy_context)(struct nouveau_channel *);
+ int (*load_context)(struct nouveau_channel *);
+ int (*save_context)(struct nouveau_channel *);
+};
- int (*init)(struct drm_device *);
- void (*takedown)(struct drm_device *);
+struct nouveau_pgraph_engine {
+ int (*init)(struct drm_device *);
+ void (*takedown)(struct drm_device *);
- int (*create_context)(struct drm_device *, int channel);
- void (*destroy_context)(struct drm_device *, int channel);
- int (*load_context)(struct drm_device *, int channel);
- int (*save_context)(struct drm_device *, int channel);
- } fifo;
+ int (*create_context)(struct nouveau_channel *);
+ void (*destroy_context)(struct nouveau_channel *);
+ int (*load_context)(struct nouveau_channel *);
+ int (*save_context)(struct nouveau_channel *);
+};
+
+struct nouveau_engine {
+ struct nouveau_instmem_engine instmem;
+ struct nouveau_mc_engine mc;
+ struct nouveau_timer_engine timer;
+ struct nouveau_fb_engine fb;
+ struct nouveau_pgraph_engine graph;
+ struct nouveau_fifo_engine fifo;
};
struct drm_nouveau_private {
@@ -207,9 +235,10 @@ struct drm_nouveau_private {
drm_local_map_t *ramin; /* NV40 onwards */
int fifo_alloc_count;
- struct nouveau_fifo *fifos[NV_MAX_FIFO_NUMBER];
+ struct nouveau_channel *fifos[NV_MAX_FIFO_NUMBER];
- struct nouveau_engine_func Engine;
+ struct nouveau_engine Engine;
+ struct nouveau_drm_channel channel;
/* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */
struct nouveau_gpuobj *ramht;
@@ -259,230 +288,277 @@ struct drm_nouveau_private {
struct nouveau_config config;
- struct nouveau_gpuobj *gpuobj_all;
+ struct list_head gpuobj_list;
};
+#define NOUVEAU_CHECK_INITIALISED_WITH_RETURN do { \
+ struct drm_nouveau_private *nv = dev->dev_private; \
+ if (nv->init_state != NOUVEAU_CARD_INIT_DONE) { \
+ DRM_ERROR("called without init\n"); \
+ return -EINVAL; \
+ } \
+} while(0)
+
+#define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id,cl,ch) do { \
+ struct drm_nouveau_private *nv = dev->dev_private; \
+ if (!nouveau_fifo_owner(dev, (cl), (id))) { \
+ DRM_ERROR("pid %d doesn't own channel %d\n", \
+ DRM_CURRENTPID, (id)); \
+ return -EPERM; \
+ } \
+ (ch) = nv->fifos[(id)]; \
+} while(0)
+
/* nouveau_state.c */
-extern void nouveau_preclose(struct drm_device * dev,
- struct drm_file *file_priv);
-extern int nouveau_load(struct drm_device *dev, unsigned long flags);
-extern int nouveau_firstopen(struct drm_device *dev);
-extern void nouveau_lastclose(struct drm_device *dev);
-extern int nouveau_unload(struct drm_device *dev);
-extern int nouveau_ioctl_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int nouveau_ioctl_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern void nouveau_wait_for_idle(struct drm_device *dev);
-extern int nouveau_ioctl_card_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern void nouveau_preclose(struct drm_device *dev, struct drm_file *);
+extern int nouveau_load(struct drm_device *, unsigned long flags);
+extern int nouveau_firstopen(struct drm_device *);
+extern void nouveau_lastclose(struct drm_device *);
+extern int nouveau_unload(struct drm_device *);
+extern int nouveau_ioctl_getparam(struct drm_device *, void *data,
+ struct drm_file *);
+extern int nouveau_ioctl_setparam(struct drm_device *, void *data,
+ struct drm_file *);
+extern void nouveau_wait_for_idle(struct drm_device *);
+extern int nouveau_card_init(struct drm_device *);
+extern int nouveau_ioctl_card_init(struct drm_device *, void *data,
+ struct drm_file *);
/* nouveau_mem.c */
-extern int nouveau_mem_init_heap(struct mem_block **,
- uint64_t start, uint64_t size);
+extern int nouveau_mem_init_heap(struct mem_block **, uint64_t start,
+ uint64_t size);
extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *,
uint64_t size, int align2,
- struct drm_file *file_priv);
-extern void nouveau_mem_takedown(struct mem_block **heap);
-extern void nouveau_mem_free_block(struct mem_block *);
-extern uint64_t nouveau_mem_fb_amount(struct drm_device *dev);
-extern void nouveau_mem_release(struct drm_file *file_priv,
- struct mem_block *heap);
-extern int nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int nouveau_ioctl_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern struct mem_block* nouveau_mem_alloc(struct drm_device *dev,
+ struct drm_file *);
+extern void nouveau_mem_takedown(struct mem_block **heap);
+extern void nouveau_mem_free_block(struct mem_block *);
+extern uint64_t nouveau_mem_fb_amount(struct drm_device *);
+extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap);
+extern int nouveau_ioctl_mem_alloc(struct drm_device *, void *data,
+ struct drm_file *);
+extern int nouveau_ioctl_mem_free(struct drm_device *, void *data,
+ struct drm_file *);
+extern struct mem_block* nouveau_mem_alloc(struct drm_device *,
int alignment, uint64_t size,
- int flags,
- struct drm_file *file_priv);
-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);
+ int flags, struct drm_file *);
+extern void nouveau_mem_free(struct drm_device *dev, struct mem_block*);
+extern int nouveau_mem_init(struct drm_device *);
+extern void nouveau_mem_close(struct drm_device *);
/* nouveau_notifier.c */
-extern int nouveau_notifier_init_channel(struct drm_device *, int channel,
- struct drm_file *file_priv);
-extern void nouveau_notifier_takedown_channel(struct drm_device *, int channel);
-extern int nouveau_notifier_alloc(struct drm_device *, int channel,
- uint32_t handle, int cout, uint32_t *offset);
-extern int nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int nouveau_notifier_init_channel(struct nouveau_channel *);
+extern void nouveau_notifier_takedown_channel(struct nouveau_channel *);
+extern int nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle,
+ int cout, uint32_t *offset);
+extern int nouveau_ioctl_notifier_alloc(struct drm_device *, void *data,
+ struct drm_file *);
+extern int nouveau_ioctl_notifier_free(struct drm_device *, void *data,
+ struct drm_file *);
/* nouveau_fifo.c */
-extern int nouveau_fifo_init(struct drm_device *dev);
-extern int nouveau_fifo_number(struct drm_device *dev);
-extern int nouveau_fifo_ctx_size(struct drm_device *dev);
-extern void nouveau_fifo_cleanup(struct drm_device *dev,
- struct drm_file *file_priv);
-extern int nouveau_fifo_owner(struct drm_device *dev,
- struct drm_file *file_priv, int channel);
-extern void nouveau_fifo_free(struct drm_device *dev, int channel);
+extern int nouveau_fifo_init(struct drm_device *);
+extern int nouveau_fifo_number(struct drm_device *);
+extern int nouveau_fifo_ctx_size(struct drm_device *);
+extern void nouveau_fifo_cleanup(struct drm_device *, struct drm_file *);
+extern int nouveau_fifo_owner(struct drm_device *, struct drm_file *,
+ int channel);
+extern int nouveau_fifo_alloc(struct drm_device *dev,
+ struct nouveau_channel **chan,
+ struct drm_file *file_priv,
+ struct mem_block *pushbuf,
+ uint32_t fb_ctxdma, uint32_t tt_ctxdma);
+extern void nouveau_fifo_free(struct nouveau_channel *);
/* nouveau_object.c */
-extern void nouveau_gpuobj_takedown(struct drm_device *dev);
-extern int nouveau_gpuobj_channel_init(struct drm_device *, int channel,
+extern int nouveau_gpuobj_early_init(struct drm_device *);
+extern int nouveau_gpuobj_init(struct drm_device *);
+extern void nouveau_gpuobj_takedown(struct drm_device *);
+extern void nouveau_gpuobj_late_takedown(struct drm_device *);
+extern int nouveau_gpuobj_channel_init(struct nouveau_channel *,
uint32_t vram_h, uint32_t tt_h);
-extern void nouveau_gpuobj_channel_takedown(struct drm_device *, int channel);
-extern int nouveau_gpuobj_new(struct drm_device *, int channel, int size, int align,
- uint32_t flags, struct nouveau_gpuobj **);
+extern void nouveau_gpuobj_channel_takedown(struct nouveau_channel *);
+extern int nouveau_gpuobj_new(struct drm_device *, struct nouveau_channel *,
+ int size, int align, uint32_t flags,
+ struct nouveau_gpuobj **);
extern int nouveau_gpuobj_del(struct drm_device *, struct nouveau_gpuobj **);
-extern int nouveau_gpuobj_ref_add(struct drm_device *, int channel, uint32_t handle,
- struct nouveau_gpuobj *,
+extern int nouveau_gpuobj_ref_add(struct drm_device *, struct nouveau_channel *,
+ uint32_t handle, struct nouveau_gpuobj *,
struct nouveau_gpuobj_ref **);
-extern int nouveau_gpuobj_ref_del(struct drm_device *, struct nouveau_gpuobj_ref **);
-extern int nouveau_gpuobj_new_ref(struct drm_device *, int chan_obj, int chan_ref,
+extern int nouveau_gpuobj_ref_del(struct drm_device *,
+ struct nouveau_gpuobj_ref **);
+extern int nouveau_gpuobj_ref_find(struct nouveau_channel *, uint32_t handle,
+ struct nouveau_gpuobj_ref **ref_ret);
+extern int nouveau_gpuobj_new_ref(struct drm_device *,
+ struct nouveau_channel *alloc_chan,
+ struct nouveau_channel *ref_chan,
uint32_t handle, int size, int align,
uint32_t flags, struct nouveau_gpuobj_ref **);
-extern int nouveau_gpuobj_new_fake(struct drm_device *, uint32_t offset,
+extern int nouveau_gpuobj_new_fake(struct drm_device *,
+ uint32_t p_offset, uint32_t b_offset,
uint32_t size, uint32_t flags,
- struct nouveau_gpuobj**,
+ struct nouveau_gpuobj **,
struct nouveau_gpuobj_ref**);
-extern int nouveau_gpuobj_dma_new(struct drm_device *, int channel, int class,
- uint64_t offset, uint64_t size,
- int access, int target,
- struct nouveau_gpuobj **);
-extern int nouveau_gpuobj_gart_dma_new(struct drm_device *, int channel,
+extern int nouveau_gpuobj_dma_new(struct nouveau_channel *, int class,
+ uint64_t offset, uint64_t size, int access,
+ int target, struct nouveau_gpuobj **);
+extern int nouveau_gpuobj_gart_dma_new(struct nouveau_channel *,
uint64_t offset, uint64_t size,
int access, struct nouveau_gpuobj **,
uint32_t *o_ret);
-extern int nouveau_gpuobj_gr_new(struct drm_device *, int channel, int class,
+extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class,
struct nouveau_gpuobj **);
-extern int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data,
+ struct drm_file *);
+extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data,
+ struct drm_file *);
/* 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 void nouveau_irq_uninstall(struct drm_device*);
+extern void nouveau_irq_preinstall(struct drm_device *);
+extern void nouveau_irq_postinstall(struct drm_device *);
+extern void nouveau_irq_uninstall(struct drm_device *);
/* nouveau_sgdma.c */
extern int nouveau_sgdma_init(struct drm_device *);
extern void nouveau_sgdma_takedown(struct drm_device *);
+extern int nouveau_sgdma_get_page(struct drm_device *, uint32_t offset,
+ uint32_t *page);
extern struct drm_ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *);
extern int nouveau_sgdma_nottm_hack_init(struct drm_device *);
extern void nouveau_sgdma_nottm_hack_takedown(struct drm_device *);
+/* nouveau_dma.c */
+extern int nouveau_dma_channel_init(struct drm_device *);
+extern void nouveau_dma_channel_takedown(struct drm_device *);
+extern int nouveau_dma_wait(struct drm_device *, int size);
+
/* nv04_fb.c */
-extern int nv04_fb_init(struct drm_device *dev);
-extern void nv04_fb_takedown(struct drm_device *dev);
+extern int nv04_fb_init(struct drm_device *);
+extern void nv04_fb_takedown(struct drm_device *);
/* nv10_fb.c */
-extern int nv10_fb_init(struct drm_device *dev);
-extern void nv10_fb_takedown(struct drm_device *dev);
+extern int nv10_fb_init(struct drm_device *);
+extern void nv10_fb_takedown(struct drm_device *);
/* nv40_fb.c */
-extern int nv40_fb_init(struct drm_device *dev);
-extern void nv40_fb_takedown(struct drm_device *dev);
+extern int nv40_fb_init(struct drm_device *);
+extern void nv40_fb_takedown(struct drm_device *);
/* nv04_fifo.c */
-extern int nv04_fifo_create_context(struct drm_device *dev, int channel);
-extern void nv04_fifo_destroy_context(struct drm_device *dev, int channel);
-extern int nv04_fifo_load_context(struct drm_device *dev, int channel);
-extern int nv04_fifo_save_context(struct drm_device *dev, int channel);
+extern int nv04_fifo_create_context(struct nouveau_channel *);
+extern void nv04_fifo_destroy_context(struct nouveau_channel *);
+extern int nv04_fifo_load_context(struct nouveau_channel *);
+extern int nv04_fifo_save_context(struct nouveau_channel *);
/* nv10_fifo.c */
-extern int nv10_fifo_create_context(struct drm_device *dev, int channel);
-extern void nv10_fifo_destroy_context(struct drm_device *dev, int channel);
-extern int nv10_fifo_load_context(struct drm_device *dev, int channel);
-extern int nv10_fifo_save_context(struct drm_device *dev, int channel);
+extern int nv10_fifo_create_context(struct nouveau_channel *);
+extern void nv10_fifo_destroy_context(struct nouveau_channel *);
+extern int nv10_fifo_load_context(struct nouveau_channel *);
+extern int nv10_fifo_save_context(struct nouveau_channel *);
/* nv40_fifo.c */
-extern int nv40_fifo_create_context(struct drm_device *, int channel);
-extern void nv40_fifo_destroy_context(struct drm_device *, int channel);
-extern int nv40_fifo_load_context(struct drm_device *, int channel);
-extern int nv40_fifo_save_context(struct drm_device *, int channel);
+extern int nv40_fifo_init(struct drm_device *);
+extern int nv40_fifo_create_context(struct nouveau_channel *);
+extern void nv40_fifo_destroy_context(struct nouveau_channel *);
+extern int nv40_fifo_load_context(struct nouveau_channel *);
+extern int nv40_fifo_save_context(struct nouveau_channel *);
/* nv50_fifo.c */
extern int nv50_fifo_init(struct drm_device *);
extern void nv50_fifo_takedown(struct drm_device *);
-extern int nv50_fifo_create_context(struct drm_device *, int channel);
-extern void nv50_fifo_destroy_context(struct drm_device *, int channel);
-extern int nv50_fifo_load_context(struct drm_device *, int channel);
-extern int nv50_fifo_save_context(struct drm_device *, int channel);
+extern int nv50_fifo_create_context(struct nouveau_channel *);
+extern void nv50_fifo_destroy_context(struct nouveau_channel *);
+extern int nv50_fifo_load_context(struct nouveau_channel *);
+extern int nv50_fifo_save_context(struct nouveau_channel *);
/* nv04_graph.c */
-extern void nouveau_nv04_context_switch(struct drm_device *dev);
-extern int nv04_graph_init(struct drm_device *dev);
-extern void nv04_graph_takedown(struct drm_device *dev);
-extern int nv04_graph_create_context(struct drm_device *dev, int channel);
-extern void nv04_graph_destroy_context(struct drm_device *dev, int channel);
-extern int nv04_graph_load_context(struct drm_device *dev, int channel);
-extern int nv04_graph_save_context(struct drm_device *dev, int channel);
+extern void nouveau_nv04_context_switch(struct drm_device *);
+extern int nv04_graph_init(struct drm_device *);
+extern void nv04_graph_takedown(struct drm_device *);
+extern int nv04_graph_create_context(struct nouveau_channel *);
+extern void nv04_graph_destroy_context(struct nouveau_channel *);
+extern int nv04_graph_load_context(struct nouveau_channel *);
+extern int nv04_graph_save_context(struct nouveau_channel *);
/* nv10_graph.c */
-extern void nouveau_nv10_context_switch(struct drm_device *dev);
-extern int nv10_graph_init(struct drm_device *dev);
-extern void nv10_graph_takedown(struct drm_device *dev);
-extern int nv10_graph_create_context(struct drm_device *dev, int channel);
-extern void nv10_graph_destroy_context(struct drm_device *dev, int channel);
-extern int nv10_graph_load_context(struct drm_device *dev, int channel);
-extern int nv10_graph_save_context(struct drm_device *dev, int channel);
+extern void nouveau_nv10_context_switch(struct drm_device *);
+extern int nv10_graph_init(struct drm_device *);
+extern void nv10_graph_takedown(struct drm_device *);
+extern int nv10_graph_create_context(struct nouveau_channel *);
+extern void nv10_graph_destroy_context(struct nouveau_channel *);
+extern int nv10_graph_load_context(struct nouveau_channel *);
+extern int nv10_graph_save_context(struct nouveau_channel *);
/* nv20_graph.c */
-extern void nouveau_nv20_context_switch(struct drm_device *dev);
-extern int nv20_graph_init(struct drm_device *dev);
-extern void nv20_graph_takedown(struct drm_device *dev);
-extern int nv20_graph_create_context(struct drm_device *dev, int channel);
-extern void nv20_graph_destroy_context(struct drm_device *dev, int channel);
-extern int nv20_graph_load_context(struct drm_device *dev, int channel);
-extern int nv20_graph_save_context(struct drm_device *dev, int channel);
+extern void nouveau_nv20_context_switch(struct drm_device *);
+extern int nv20_graph_init(struct drm_device *);
+extern void nv20_graph_takedown(struct drm_device *);
+extern int nv20_graph_create_context(struct nouveau_channel *);
+extern void nv20_graph_destroy_context(struct nouveau_channel *);
+extern int nv20_graph_load_context(struct nouveau_channel *);
+extern int nv20_graph_save_context(struct nouveau_channel *);
/* nv30_graph.c */
-extern int nv30_graph_init(struct drm_device *dev);
-extern void nv30_graph_takedown(struct drm_device *dev);
-extern int nv30_graph_create_context(struct drm_device *, int channel);
-extern void nv30_graph_destroy_context(struct drm_device *, int channel);
-extern int nv30_graph_load_context(struct drm_device *, int channel);
-extern int nv30_graph_save_context(struct drm_device *, int channel);
+extern int nv30_graph_init(struct drm_device *);
+extern void nv30_graph_takedown(struct drm_device *);
+extern int nv30_graph_create_context(struct nouveau_channel *);
+extern void nv30_graph_destroy_context(struct nouveau_channel *);
+extern int nv30_graph_load_context(struct nouveau_channel *);
+extern int nv30_graph_save_context(struct nouveau_channel *);
/* nv40_graph.c */
extern int nv40_graph_init(struct drm_device *);
extern void nv40_graph_takedown(struct drm_device *);
-extern int nv40_graph_create_context(struct drm_device *, int channel);
-extern void nv40_graph_destroy_context(struct drm_device *, int channel);
-extern int nv40_graph_load_context(struct drm_device *, int channel);
-extern int nv40_graph_save_context(struct drm_device *, int channel);
+extern int nv40_graph_create_context(struct nouveau_channel *);
+extern void nv40_graph_destroy_context(struct nouveau_channel *);
+extern int nv40_graph_load_context(struct nouveau_channel *);
+extern int nv40_graph_save_context(struct nouveau_channel *);
/* nv50_graph.c */
extern int nv50_graph_init(struct drm_device *);
extern void nv50_graph_takedown(struct drm_device *);
-extern int nv50_graph_create_context(struct drm_device *, int channel);
-extern void nv50_graph_destroy_context(struct drm_device *, int channel);
-extern int nv50_graph_load_context(struct drm_device *, int channel);
-extern int nv50_graph_save_context(struct drm_device *, int channel);
+extern int nv50_graph_create_context(struct nouveau_channel *);
+extern void nv50_graph_destroy_context(struct nouveau_channel *);
+extern int nv50_graph_load_context(struct nouveau_channel *);
+extern int nv50_graph_save_context(struct nouveau_channel *);
/* nv04_instmem.c */
-extern int nv04_instmem_init(struct drm_device *dev);
-extern void nv04_instmem_takedown(struct drm_device *dev);
-extern int nv04_instmem_populate(struct drm_device*, struct nouveau_gpuobj*,
+extern int nv04_instmem_init(struct drm_device *);
+extern void nv04_instmem_takedown(struct drm_device *);
+extern int nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
uint32_t *size);
-extern void nv04_instmem_clear(struct drm_device*, struct nouveau_gpuobj*);
-extern int nv04_instmem_bind(struct drm_device*, struct nouveau_gpuobj*);
-extern int nv04_instmem_unbind(struct drm_device*, struct nouveau_gpuobj*);
+extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
+extern int nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
+extern int nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
/* nv50_instmem.c */
-extern int nv50_instmem_init(struct drm_device *dev);
-extern void nv50_instmem_takedown(struct drm_device *dev);
-extern int nv50_instmem_populate(struct drm_device*, struct nouveau_gpuobj*,
+extern int nv50_instmem_init(struct drm_device *);
+extern void nv50_instmem_takedown(struct drm_device *);
+extern int nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
uint32_t *size);
-extern void nv50_instmem_clear(struct drm_device*, struct nouveau_gpuobj*);
-extern int nv50_instmem_bind(struct drm_device*, struct nouveau_gpuobj*);
-extern int nv50_instmem_unbind(struct drm_device*, struct nouveau_gpuobj*);
+extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
+extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
+extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
/* nv04_mc.c */
-extern int nv04_mc_init(struct drm_device *dev);
-extern void nv04_mc_takedown(struct drm_device *dev);
+extern int nv04_mc_init(struct drm_device *);
+extern void nv04_mc_takedown(struct drm_device *);
/* nv40_mc.c */
-extern int nv40_mc_init(struct drm_device *dev);
-extern void nv40_mc_takedown(struct drm_device *dev);
+extern int nv40_mc_init(struct drm_device *);
+extern void nv40_mc_takedown(struct drm_device *);
/* nv50_mc.c */
-extern int nv50_mc_init(struct drm_device *dev);
-extern void nv50_mc_takedown(struct drm_device *dev);
+extern int nv50_mc_init(struct drm_device *);
+extern void nv50_mc_takedown(struct drm_device *);
/* nv04_timer.c */
-extern int nv04_timer_init(struct drm_device *dev);
-extern uint64_t nv04_timer_read(struct drm_device *dev);
-extern void nv04_timer_takedown(struct drm_device *dev);
+extern int nv04_timer_init(struct drm_device *);
+extern uint64_t nv04_timer_read(struct drm_device *);
+extern void nv04_timer_takedown(struct drm_device *);
extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg);
+ unsigned long arg);
#if defined(__powerpc__)
#define NV_READ(reg) in_be32((void __iomem *)(dev_priv->mmio)->handle + (reg) )
diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c
index e5d3ab3c..437c84f2 100644
--- a/shared-core/nouveau_fifo.c
+++ b/shared-core/nouveau_fifo.c
@@ -34,8 +34,6 @@ int nouveau_fifo_number(struct drm_device *dev)
struct drm_nouveau_private *dev_priv=dev->dev_private;
switch(dev_priv->card_type)
{
- case NV_03:
- return 8;
case NV_04:
case NV_05:
return 16;
@@ -84,9 +82,16 @@ static int nouveau_fifo_instmem_configure(struct drm_device *dev)
{
case NV_50:
case NV_40:
+ switch (dev_priv->chipset) {
+ case 0x47:
+ case 0x49:
+ case 0x4b:
+ NV_WRITE(0x2230, 1);
+ break;
+ default:
+ break;
+ }
NV_WRITE(NV40_PFIFO_RAMFC, 0x30002);
- if((dev_priv->chipset == 0x49) || (dev_priv->chipset == 0x4b))
- NV_WRITE(0x2230,0x00000001);
break;
case NV_44:
NV_WRITE(NV40_PFIFO_RAMFC, ((nouveau_mem_fb_amount(dev)-512*1024+dev_priv->ramfc_offset)>>16) |
@@ -102,7 +107,6 @@ static int nouveau_fifo_instmem_configure(struct drm_device *dev)
case NV_11:
case NV_10:
case NV_04:
- case NV_03:
NV_WRITE(NV03_PFIFO_RAMFC, dev_priv->ramfc_offset>>8);
break;
}
@@ -120,6 +124,10 @@ int nouveau_fifo_init(struct drm_device *dev)
NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) |
NV_PMC_ENABLE_PFIFO);
+ /* Enable PFIFO error reporting */
+ NV_WRITE(NV03_PFIFO_INTR_0, 0xFFFFFFFF);
+ NV_WRITE(NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF);
+
NV_WRITE(NV03_PFIFO_CACHES, 0x00000000);
ret = nouveau_fifo_instmem_configure(dev);
@@ -186,72 +194,47 @@ int nouveau_fifo_init(struct drm_device *dev)
}
static int
-nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel)
+nouveau_fifo_pushbuf_ctxdma_init(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
- struct nouveau_config *config = &dev_priv->config;
- struct mem_block *cb;
- int cb_min_size = max(NV03_FIFO_SIZE,PAGE_SIZE);
+ struct mem_block *pb = chan->pushbuf_mem;
struct nouveau_gpuobj *pushbuf = NULL;
int ret;
- /* Defaults for unconfigured values */
- if (!config->cmdbuf.location)
- config->cmdbuf.location = NOUVEAU_MEM_FB;
- if (!config->cmdbuf.size || config->cmdbuf.size < cb_min_size)
- config->cmdbuf.size = cb_min_size;
-
- cb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size,
- config->cmdbuf.location | NOUVEAU_MEM_MAPPED,
- (struct drm_file *)-2);
- if (!cb) {
- DRM_ERROR("Couldn't allocate DMA command buffer.\n");
- return -ENOMEM;
- }
-
- if (cb->flags & NOUVEAU_MEM_AGP) {
- ret = nouveau_gpuobj_gart_dma_new(dev, channel,
- cb->start, cb->size,
+ if (pb->flags & NOUVEAU_MEM_AGP) {
+ ret = nouveau_gpuobj_gart_dma_new(chan, pb->start, pb->size,
NV_DMA_ACCESS_RO,
&pushbuf,
&chan->pushbuf_base);
} else
- if (cb->flags & NOUVEAU_MEM_PCI) {
- ret = nouveau_gpuobj_dma_new(dev, channel,
- NV_CLASS_DMA_IN_MEMORY,
- cb->start, cb->size,
+ if (pb->flags & NOUVEAU_MEM_PCI) {
+ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
+ pb->start, pb->size,
NV_DMA_ACCESS_RO,
NV_DMA_TARGET_PCI_NONLINEAR,
&pushbuf);
chan->pushbuf_base = 0;
} else if (dev_priv->card_type != NV_04) {
- ret = nouveau_gpuobj_dma_new
- (dev, channel, NV_CLASS_DMA_IN_MEMORY,
- cb->start,
- cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM,
- &pushbuf);
+ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
+ pb->start, pb->size,
+ NV_DMA_ACCESS_RO,
+ NV_DMA_TARGET_VIDMEM, &pushbuf);
chan->pushbuf_base = 0;
} else {
/* NV04 cmdbuf hack, from original ddx.. not sure of it's
* exact reason for existing :) PCI access to cmdbuf in
* VRAM.
*/
- ret = nouveau_gpuobj_dma_new
- (dev, channel, NV_CLASS_DMA_IN_MEMORY,
- cb->start + drm_get_resource_start(dev, 1),
- cb->size, NV_DMA_ACCESS_RO,
- NV_DMA_TARGET_PCI, &pushbuf);
+ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
+ pb->start +
+ drm_get_resource_start(dev, 1),
+ pb->size, NV_DMA_ACCESS_RO,
+ NV_DMA_TARGET_PCI, &pushbuf);
chan->pushbuf_base = 0;
}
- if (ret) {
- nouveau_mem_free(dev, cb);
- DRM_ERROR("Error creating push buffer ctxdma: %d\n", ret);
- return ret;
- }
-
- if ((ret = nouveau_gpuobj_ref_add(dev, channel, 0, pushbuf,
+ if ((ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf,
&chan->pushbuf))) {
DRM_ERROR("Error referencing push buffer ctxdma: %d\n", ret);
if (pushbuf != dev_priv->gart_info.sg_ctxdma)
@@ -259,19 +242,42 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel)
return ret;
}
- chan->pushbuf_mem = cb;
return 0;
}
+static struct mem_block *
+nouveau_fifo_user_pushbuf_alloc(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_config *config = &dev_priv->config;
+ struct mem_block *pb;
+ int pb_min_size = max(NV03_FIFO_SIZE,PAGE_SIZE);
+
+ /* Defaults for unconfigured values */
+ if (!config->cmdbuf.location)
+ config->cmdbuf.location = NOUVEAU_MEM_FB;
+ if (!config->cmdbuf.size || config->cmdbuf.size < pb_min_size)
+ config->cmdbuf.size = pb_min_size;
+
+ pb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size,
+ config->cmdbuf.location | NOUVEAU_MEM_MAPPED,
+ (struct drm_file *)-2);
+ if (!pb)
+ DRM_ERROR("Couldn't allocate DMA push buffer.\n");
+
+ return pb;
+}
+
/* allocates and initializes a fifo for user space consumption */
-int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret,
- struct drm_file *file_priv,
- uint32_t vram_handle, uint32_t tt_handle)
+int
+nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
+ struct drm_file *file_priv, struct mem_block *pushbuf,
+ uint32_t vram_handle, uint32_t tt_handle)
{
int ret;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_engine_func *engine = &dev_priv->Engine;
- struct nouveau_fifo *chan;
+ struct nouveau_engine *engine = &dev_priv->Engine;
+ struct nouveau_channel *chan;
int channel;
/*
@@ -283,44 +289,44 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret,
* When there are no more contexts, you lost
*/
for(channel=0; channel<nouveau_fifo_number(dev); channel++) {
- if ((dev_priv->card_type == NV_50) && (channel == 0))
- continue;
if (dev_priv->fifos[channel] == NULL)
break;
}
/* no more fifos. you lost. */
if (channel==nouveau_fifo_number(dev))
return -EINVAL;
- (*chan_ret) = channel;
- dev_priv->fifos[channel] = drm_calloc(1, sizeof(struct nouveau_fifo),
+ dev_priv->fifos[channel] = drm_calloc(1, sizeof(struct nouveau_channel),
DRM_MEM_DRIVER);
if (!dev_priv->fifos[channel])
return -ENOMEM;
dev_priv->fifo_alloc_count++;
chan = dev_priv->fifos[channel];
+ chan->dev = dev;
+ chan->id = channel;
chan->file_priv = file_priv;
+ chan->pushbuf_mem = pushbuf;
DRM_INFO("Allocating FIFO number %d\n", channel);
- /* Setup channel's default objects */
- ret = nouveau_gpuobj_channel_init(dev, channel, vram_handle, tt_handle);
+ /* Allocate space for per-channel fixed notifier memory */
+ ret = nouveau_notifier_init_channel(chan);
if (ret) {
- nouveau_fifo_free(dev, channel);
+ nouveau_fifo_free(chan);
return ret;
}
- /* allocate a command buffer, and create a dma object for the gpu */
- ret = nouveau_fifo_cmdbuf_alloc(dev, channel);
+ /* Setup channel's default objects */
+ ret = nouveau_gpuobj_channel_init(chan, vram_handle, tt_handle);
if (ret) {
- nouveau_fifo_free(dev, channel);
+ nouveau_fifo_free(chan);
return ret;
}
- /* Allocate space for per-channel fixed notifier memory */
- ret = nouveau_notifier_init_channel(dev, channel, file_priv);
+ /* Create a dma object for the push buffer */
+ ret = nouveau_fifo_pushbuf_ctxdma_init(chan);
if (ret) {
- nouveau_fifo_free(dev, channel);
+ nouveau_fifo_free(chan);
return ret;
}
@@ -333,16 +339,16 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret,
NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000);
/* Create a graphics context for new channel */
- ret = engine->graph.create_context(dev, channel);
+ ret = engine->graph.create_context(chan);
if (ret) {
- nouveau_fifo_free(dev, channel);
+ nouveau_fifo_free(chan);
return ret;
}
/* Construct inital RAMFC for new channel */
- ret = engine->fifo.create_context(dev, channel);
+ ret = engine->fifo.create_context(chan);
if (ret) {
- nouveau_fifo_free(dev, channel);
+ nouveau_fifo_free(chan);
return ret;
}
@@ -359,30 +365,17 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret,
* other case, the GPU will handle this when it switches contexts.
*/
if (dev_priv->fifo_alloc_count == 1) {
- ret = engine->fifo.load_context(dev, channel);
+ ret = engine->fifo.load_context(chan);
if (ret) {
- nouveau_fifo_free(dev, channel);
+ nouveau_fifo_free(chan);
return ret;
}
- ret = engine->graph.load_context(dev, channel);
+ ret = engine->graph.load_context(chan);
if (ret) {
- nouveau_fifo_free(dev, channel);
+ nouveau_fifo_free(chan);
return ret;
}
-
- /* Temporary hack, to avoid breaking Xv on cards where the
- * initial context value for 0x400710 doesn't have these bits
- * set. Proper fix would be to find which object+method is
- * responsible for modifying this state.
- */
- if (dev_priv->chipset >= 0x10 && dev_priv->chipset < 0x50) {
- uint32_t tmp;
- 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(NV04_PFIFO_CACHE1_DMA_PUSH,
@@ -395,32 +388,28 @@ int nouveau_fifo_alloc(struct drm_device *dev, int *chan_ret,
NV_WRITE(NV03_PFIFO_CACHES, 1);
DRM_INFO("%s: initialised FIFO %d\n", __func__, channel);
+ *chan_ret = chan;
return 0;
}
/* stops a fifo */
-void nouveau_fifo_free(struct drm_device *dev, int channel)
+void nouveau_fifo_free(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_engine_func *engine = &dev_priv->Engine;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
-
- if (!chan) {
- DRM_ERROR("Freeing non-existant channel %d\n", channel);
- return;
- }
+ struct nouveau_engine *engine = &dev_priv->Engine;
- DRM_INFO("%s: freeing fifo %d\n", __func__, channel);
+ DRM_INFO("%s: freeing fifo %d\n", __func__, chan->id);
/* disable the fifo caches */
NV_WRITE(NV03_PFIFO_CACHES, 0x00000000);
// FIXME XXX needs more code
- engine->fifo.destroy_context(dev, channel);
+ engine->fifo.destroy_context(chan);
/* Cleanup PGRAPH state */
- engine->graph.destroy_context(dev, channel);
+ engine->graph.destroy_context(chan);
/* reenable the fifo caches */
NV_WRITE(NV03_PFIFO_CACHES, 0x00000001);
@@ -432,12 +421,12 @@ void nouveau_fifo_free(struct drm_device *dev, int channel)
chan->pushbuf_mem = NULL;
}
- nouveau_notifier_takedown_channel(dev, channel);
-
/* Destroy objects belonging to the channel */
- nouveau_gpuobj_channel_takedown(dev, channel);
+ nouveau_gpuobj_channel_takedown(chan);
+
+ nouveau_notifier_takedown_channel(chan);
- dev_priv->fifos[channel] = NULL;
+ dev_priv->fifos[chan->id] = NULL;
dev_priv->fifo_alloc_count--;
drm_free(chan, sizeof(*chan), DRM_MEM_DRIVER);
}
@@ -445,14 +434,16 @@ void nouveau_fifo_free(struct drm_device *dev, int channel)
/* cleanups all the fifos from file_priv */
void nouveau_fifo_cleanup(struct drm_device *dev, struct drm_file *file_priv)
{
- int i;
struct drm_nouveau_private *dev_priv = dev->dev_private;
+ int i;
DRM_DEBUG("clearing FIFO enables from file_priv\n");
- for(i=0;i<nouveau_fifo_number(dev);i++)
- if (dev_priv->fifos[i] &&
- dev_priv->fifos[i]->file_priv==file_priv)
- nouveau_fifo_free(dev,i);
+ for(i = 0; i < nouveau_fifo_number(dev); i++) {
+ struct nouveau_channel *chan = dev_priv->fifos[i];
+
+ if (chan && chan->file_priv == file_priv)
+ nouveau_fifo_free(chan);
+ }
}
int
@@ -472,24 +463,31 @@ nouveau_fifo_owner(struct drm_device *dev, struct drm_file *file_priv,
* ioctls wrapping the functions
***********************************/
-static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
+static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct drm_nouveau_fifo_alloc *init = data;
+ struct drm_nouveau_channel_alloc *init = data;
struct drm_map_list *entry;
- struct nouveau_fifo *chan;
+ struct nouveau_channel *chan;
+ struct mem_block *pushbuf;
int res;
+ NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
return -EINVAL;
- res = nouveau_fifo_alloc(dev, &init->channel, file_priv,
+ pushbuf = nouveau_fifo_user_pushbuf_alloc(dev);
+ if (!pushbuf)
+ return -ENOMEM;
+
+ res = nouveau_fifo_alloc(dev, &chan, file_priv, pushbuf,
init->fb_ctxdma_handle,
init->tt_ctxdma_handle);
if (res)
return res;
- chan = dev_priv->fifos[init->channel];
-
+ init->channel = chan->id;
init->put_base = chan->pushbuf_base;
/* make the fifo available to user space */
@@ -523,18 +521,34 @@ static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, struct d
return 0;
}
+static int nouveau_ioctl_fifo_free(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_nouveau_channel_free *cfree = data;
+ struct nouveau_channel *chan;
+
+ NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan);
+
+ nouveau_fifo_free(chan);
+ return 0;
+}
+
/***********************************
* finally, the ioctl table
***********************************/
struct drm_ioctl_desc nouveau_ioctls[] = {
- DRM_IOCTL_DEF(DRM_NOUVEAU_FIFO_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_CARD_INIT, nouveau_ioctl_card_init, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIER_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_ALLOC, nouveau_ioctl_mem_alloc, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_FREE, nouveau_ioctl_mem_free, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
};
int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls);
diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c
index f7baf89e..e64677ed 100644
--- a/shared-core/nouveau_irq.c
+++ b/shared-core/nouveau_irq.c
@@ -40,33 +40,6 @@ void nouveau_irq_preinstall(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- 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);
- /* Disable/Clear PGRAPH interrupts */
- if (dev_priv->card_type<NV_40)
- NV_WRITE(NV03_PGRAPH_INTR_EN, 0);
- else
- NV_WRITE(NV40_PGRAPH_INTR_EN, 0);
- NV_WRITE(NV03_PGRAPH_INTR, 0xFFFFFFFF);
-#if 0
- /* Disable/Clear CRTC0/1 interrupts */
- NV_WRITE(NV_CRTC0_INTEN, 0);
- NV_WRITE(NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK);
- NV_WRITE(NV_CRTC1_INTEN, 0);
- NV_WRITE(NV_CRTC1_INTSTAT, NV_CRTC_INTR_VBLANK);
-#endif
/* Master disable */
NV_WRITE(NV03_PMC_INTR_EN_0, 0);
}
@@ -75,34 +48,6 @@ void nouveau_irq_postinstall(struct drm_device *dev)
{
struct drm_nouveau_private *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 */
- NV_WRITE(NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF);
- NV_WRITE(NV03_PFIFO_INTR_0, 0xFFFFFFFF);
-
- /* Enable PGRAPH interrupts */
- if (dev_priv->card_type<NV_40)
- NV_WRITE(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
- else
- NV_WRITE(NV40_PGRAPH_INTR_EN, 0xFFFFFFFF);
- NV_WRITE(NV03_PGRAPH_INTR, 0xFFFFFFFF);
-
-#if 0
- /* Enable CRTC0/1 interrupts */
- NV_WRITE(NV_CRTC0_INTEN, NV_CRTC_INTR_VBLANK);
- NV_WRITE(NV_CRTC1_INTEN, NV_CRTC_INTR_VBLANK);
-#endif
-
/* Master enable */
NV_WRITE(NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE);
}
@@ -111,29 +56,6 @@ void nouveau_irq_uninstall(struct drm_device *dev)
{
struct drm_nouveau_private *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 */
- NV_WRITE(NV03_PFIFO_INTR_EN_0, 0);
- /* Disable PGRAPH interrupts */
- if (dev_priv->card_type<NV_40)
- NV_WRITE(NV03_PGRAPH_INTR_EN, 0);
- else
- NV_WRITE(NV40_PGRAPH_INTR_EN, 0);
-#if 0
- /* Disable CRTC0/1 interrupts */
- NV_WRITE(NV_CRTC0_INTEN, 0);
- NV_WRITE(NV_CRTC1_INTEN, 0);
-#endif
/* Master disable */
NV_WRITE(NV03_PMC_INTR_EN_0, 0);
}
@@ -150,12 +72,10 @@ static void nouveau_fifo_irq_handler(struct drm_device *dev)
chstat = NV_READ(NV04_PFIFO_DMA);
channel=NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1);
- DRM_DEBUG("NV: PFIFO interrupt! Channel=%d, INTSTAT=0x%08x/MODE=0x%08x/PEND=0x%08x\n", channel, status, chmode, chstat);
-
if (status & NV_PFIFO_INTR_CACHE_ERROR) {
uint32_t c1get, c1method, c1data;
- DRM_ERROR("NV: PFIFO error interrupt\n");
+ DRM_ERROR("PFIFO error interrupt\n");
c1get = NV_READ(NV03_PFIFO_CACHE1_GET) >> 2;
if (dev_priv->card_type < NV_40) {
@@ -167,17 +87,17 @@ static void nouveau_fifo_irq_handler(struct drm_device *dev)
c1data = NV_READ(NV40_PFIFO_CACHE1_DATA(c1get));
}
- DRM_ERROR("NV: Channel %d/%d - Method 0x%04x, Data 0x%08x\n",
- channel, (c1method >> 13) & 7,
- c1method & 0x1ffc, c1data
- );
+ DRM_ERROR("Channel %d/%d - Method 0x%04x, Data 0x%08x\n",
+ channel, (c1method >> 13) & 7, c1method & 0x1ffc,
+ c1data);
status &= ~NV_PFIFO_INTR_CACHE_ERROR;
NV_WRITE(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_CACHE_ERROR);
}
if (status & NV_PFIFO_INTR_DMA_PUSHER) {
- DRM_INFO("NV: PFIFO DMA pusher interrupt\n");
+ DRM_ERROR("PFIFO DMA pusher interrupt: ch%d, 0x%08x\n",
+ channel, NV_READ(NV04_PFIFO_CACHE1_DMA_GET));
status &= ~NV_PFIFO_INTR_DMA_PUSHER;
NV_WRITE(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_DMA_PUSHER);
@@ -191,7 +111,7 @@ static void nouveau_fifo_irq_handler(struct drm_device *dev)
}
if (status) {
- DRM_INFO("NV: unknown PFIFO interrupt. status=0x%08x\n", status);
+ DRM_ERROR("Unhandled PFIFO interrupt: status=0x%08x\n", status);
NV_WRITE(NV03_PFIFO_INTR_0, status);
}
@@ -301,20 +221,86 @@ nouveau_print_bitfield_names(uint32_t value,
printk(" (unknown bits 0x%08x)", value);
}
+static int
+nouveau_graph_trapped_channel(struct drm_device *dev, int *channel_ret)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ int channel;
+
+ if (dev_priv->card_type < NV_10) {
+ channel = (NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 24) & 0xf;
+ } else if (dev_priv->card_type < NV_40) {
+ channel = (NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f;
+ } else
+ if (dev_priv->card_type < NV_50) {
+ uint32_t cur_grctx = (NV_READ(0x40032C) & 0xfffff) << 4;
+
+ /* 0x400704 *sometimes* contains a sensible channel ID, but
+ * mostly not.. for now lookup which channel owns the active
+ * PGRAPH context. Probably a better way, but this'll do
+ * for now.
+ */
+ for (channel = 0; channel < 32; channel++) {
+ if (dev_priv->fifos[channel] == NULL)
+ continue;
+ if (cur_grctx ==
+ dev_priv->fifos[channel]->ramin_grctx->instance)
+ break;
+ }
+ if (channel == 32) {
+ DRM_ERROR("AIII, unable to determine active channel "
+ "from PGRAPH context 0x%08x\n", cur_grctx);
+ return -EINVAL;
+ }
+ } else {
+ uint32_t cur_grctx = (NV_READ(0x40032C) & 0xfffff) << 12;
+
+ for (channel = 0; channel < 128; channel++) {
+ if (dev_priv->fifos[channel] == NULL)
+ continue;
+ if (cur_grctx ==
+ dev_priv->fifos[channel]->ramin_grctx->instance)
+ break;
+ }
+ if (channel == 128) {
+ DRM_ERROR("AIII, unable to determine active channel "
+ "from PGRAPH context 0x%08x\n", cur_grctx);
+ return -EINVAL;
+ }
+ }
+
+ if (channel > nouveau_fifo_number(dev) ||
+ dev_priv->fifos[channel] == NULL) {
+ DRM_ERROR("AIII, invalid/inactive channel id %d\n", channel);
+ return -EINVAL;
+ }
+
+ *channel_ret = channel;
+ return 0;
+}
+
static void
nouveau_graph_dump_trap_info(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
uint32_t address;
uint32_t channel, class;
- uint32_t method, subc, data;
+ uint32_t method, subc, data, data2;
uint32_t nsource, nstatus;
- address = NV_READ(0x400704);
- channel = (address >> 20) & 0x1F;
- subc = (address >> 16) & 0x7;
+ if (nouveau_graph_trapped_channel(dev, &channel))
+ channel = -1;
+
+ data = NV_READ(NV04_PGRAPH_TRAPPED_DATA);
+ address = NV_READ(NV04_PGRAPH_TRAPPED_ADDR);
method = address & 0x1FFC;
- data = NV_READ(0x400708);
+ if (dev_priv->card_type < NV_10) {
+ subc = (address >> 13) & 0x7;
+ data2= 0;
+ } else {
+ subc = (address >> 16) & 0x7;
+ data2= NV_READ(NV10_PGRAPH_TRAPPED_DATA_HIGH);
+ }
nsource = NV_READ(NV03_PGRAPH_NSOURCE);
nstatus = NV_READ(NV03_PGRAPH_NSTATUS);
if (dev_priv->card_type < NV_50) {
@@ -331,77 +317,31 @@ nouveau_graph_dump_trap_info(struct drm_device *dev)
ARRAY_SIZE(nouveau_nstatus_names));
printk("\n");
- DRM_ERROR("NV: Channel %d/%d (class 0x%04x) - "
- "Method 0x%04x, Data 0x%08x\n",
- channel, subc, class, method, data
- );
+ DRM_ERROR("Channel %d/%d (class 0x%04x) - Method 0x%04x, Data 0x%08x:0x%08x\n",
+ channel, subc, class, method, data2, data);
}
static void nouveau_pgraph_irq_handler(struct drm_device *dev)
{
- uint32_t status;
struct drm_nouveau_private *dev_priv = dev->dev_private;
+ uint32_t status, nsource;
status = NV_READ(NV03_PGRAPH_INTR);
if (!status)
return;
+ nsource = NV_READ(NV03_PGRAPH_NSOURCE);
if (status & NV_PGRAPH_INTR_NOTIFY) {
- uint32_t nsource, nstatus, instance, notify;
- DRM_DEBUG("NV: PGRAPH notify interrupt\n");
-
- nstatus = NV_READ(NV03_PGRAPH_NSTATUS);
- nsource = NV_READ(NV03_PGRAPH_NSOURCE);
- DRM_DEBUG("nsource:0x%08x\tnstatus:0x%08x\n", nsource, nstatus);
+ DRM_DEBUG("PGRAPH notify interrupt\n");
- /* if this wasn't NOTIFICATION_PENDING, dump extra trap info */
- if (nsource & ~(1<<0)) {
- nouveau_graph_dump_trap_info(dev);
- } else {
- instance = NV_READ(0x00400158);
- notify = NV_READ(0x00400150) >> 16;
- DRM_DEBUG("instance:0x%08x\tnotify:0x%08x\n",
- instance, notify);
- }
+ nouveau_graph_dump_trap_info(dev);
status &= ~NV_PGRAPH_INTR_NOTIFY;
NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_NOTIFY);
}
- if (status & NV_PGRAPH_INTR_BUFFER_NOTIFY) {
- uint32_t nsource, nstatus, instance, notify;
- DRM_DEBUG("NV: PGRAPH buffer notify interrupt\n");
-
- nstatus = NV_READ(NV03_PGRAPH_NSTATUS);
- nsource = NV_READ(NV03_PGRAPH_NSOURCE);
- DRM_DEBUG("nsource:0x%08x\tnstatus:0x%08x\n", nsource, nstatus);
-
- instance = NV_READ(0x00400158);
- notify = NV_READ(0x00400150) >> 16;
- DRM_DEBUG("instance:0x%08x\tnotify:0x%08x\n", instance, notify);
-
- status &= ~NV_PGRAPH_INTR_BUFFER_NOTIFY;
- NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_BUFFER_NOTIFY);
- }
-
- if (status & NV_PGRAPH_INTR_MISSING_HW) {
- DRM_ERROR("NV: PGRAPH missing hw interrupt\n");
-
- status &= ~NV_PGRAPH_INTR_MISSING_HW;
- NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_MISSING_HW);
- }
-
if (status & NV_PGRAPH_INTR_ERROR) {
- uint32_t nsource, nstatus, instance;
-
- DRM_ERROR("NV: PGRAPH error interrupt\n");
-
- nstatus = NV_READ(NV03_PGRAPH_NSTATUS);
- nsource = NV_READ(NV03_PGRAPH_NSOURCE);
- DRM_ERROR("nsource:0x%08x\tnstatus:0x%08x\n", nsource, nstatus);
-
- instance = NV_READ(0x00400158);
- DRM_ERROR("instance:0x%08x\n", instance);
+ DRM_ERROR("PGRAPH error interrupt\n");
nouveau_graph_dump_trap_info(dev);
@@ -411,7 +351,7 @@ static void nouveau_pgraph_irq_handler(struct drm_device *dev)
if (status & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
uint32_t channel=NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1);
- DRM_INFO("NV: PGRAPH context switch interrupt channel %x\n",channel);
+ DRM_DEBUG("PGRAPH context switch interrupt channel %x\n",channel);
switch(dev_priv->card_type)
{
case NV_04:
@@ -428,7 +368,7 @@ static void nouveau_pgraph_irq_handler(struct drm_device *dev)
nouveau_nv20_context_switch(dev);
break;
default:
- DRM_INFO("NV: Context switch not implemented\n");
+ DRM_ERROR("Context switch not implemented\n");
break;
}
@@ -437,7 +377,7 @@ static void nouveau_pgraph_irq_handler(struct drm_device *dev)
}
if (status) {
- DRM_INFO("NV: Unknown PGRAPH interrupt! STAT=0x%08x\n", status);
+ DRM_ERROR("Unhandled PGRAPH interrupt: STAT=0x%08x\n", status);
NV_WRITE(NV03_PGRAPH_INTR, status);
}
@@ -447,6 +387,7 @@ static void nouveau_pgraph_irq_handler(struct drm_device *dev)
static void nouveau_crtc_irq_handler(struct drm_device *dev, int crtc)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
+
if (crtc&1) {
NV_WRITE(NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK);
}
@@ -466,16 +407,16 @@ irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS)
if (!status)
return IRQ_NONE;
- DRM_DEBUG("PMC INTSTAT: 0x%08x\n", status);
-
if (status & NV_PMC_INTR_0_PFIFO_PENDING) {
nouveau_fifo_irq_handler(dev);
status &= ~NV_PMC_INTR_0_PFIFO_PENDING;
}
+
if (status & NV_PMC_INTR_0_PGRAPH_PENDING) {
nouveau_pgraph_irq_handler(dev);
status &= ~NV_PMC_INTR_0_PGRAPH_PENDING;
}
+
if (status & NV_PMC_INTR_0_CRTCn_PENDING) {
nouveau_crtc_irq_handler(dev, (status>>24)&3);
status &= ~NV_PMC_INTR_0_CRTCn_PENDING;
diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c
index a7044c94..dbfba351 100644
--- a/shared-core/nouveau_mem.c
+++ b/shared-core/nouveau_mem.c
@@ -219,24 +219,44 @@ void nouveau_mem_close(struct drm_device *dev)
nouveau_mem_takedown(&dev_priv->pci_heap);
}
+/*XXX won't work on BSD because of pci_read_config_dword */
+static uint32_t
+nouveau_mem_fb_amount_igp(struct drm_device *dev)
+{
+#if defined(LINUX) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct pci_dev *bridge;
+ uint32_t mem;
+
+ bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0,1));
+ if (!bridge) {
+ DRM_ERROR("no bridge device\n");
+ return 0;
+ }
+
+ if (dev_priv->flags&NV_NFORCE) {
+ pci_read_config_dword(bridge, 0x7C, &mem);
+ return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024;
+ } else
+ if(dev_priv->flags&NV_NFORCE2) {
+ pci_read_config_dword(bridge, 0x84, &mem);
+ return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024;
+ }
+
+ DRM_ERROR("impossible!\n");
+#else
+ DRM_ERROR("Linux kernel >= 2.6.19 required to check for igp memory amount\n");
+#endif
+
+ return 0;
+}
+
/* returns the amount of FB ram in bytes */
uint64_t nouveau_mem_fb_amount(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv=dev->dev_private;
switch(dev_priv->card_type)
{
- case NV_03:
- switch(NV_READ(NV03_BOOT_0)&NV03_BOOT_0_RAM_AMOUNT)
- {
- case NV03_BOOT_0_RAM_AMOUNT_8MB:
- case NV03_BOOT_0_RAM_AMOUNT_8MB_SDRAM:
- return 8*1024*1024;
- case NV03_BOOT_0_RAM_AMOUNT_4MB:
- return 4*1024*1024;
- case NV03_BOOT_0_RAM_AMOUNT_2MB:
- return 2*1024*1024;
- }
- break;
case NV_04:
case NV_05:
if (NV_READ(NV03_BOOT_0) & 0x00000100) {
@@ -263,18 +283,14 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev)
case NV_44:
case NV_50:
default:
- // XXX won't work on BSD because of pci_read_config_dword
- if (dev_priv->flags&NV_NFORCE) {
- uint32_t mem;
- pci_read_config_dword(dev->pdev, 0x7C, &mem);
- return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024;
- } else if(dev_priv->flags&NV_NFORCE2) {
- uint32_t mem;
- pci_read_config_dword(dev->pdev, 0x84, &mem);
- return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024;
+ if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
+ return nouveau_mem_fb_amount_igp(dev);
} else {
uint64_t mem;
- mem=(NV_READ(NV04_FIFO_DATA)&NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >> NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT;
+
+ mem = (NV_READ(NV04_FIFO_DATA) &
+ NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >>
+ NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT;
return mem*1024*1024;
}
break;
@@ -411,11 +427,11 @@ int nouveau_mem_init(struct drm_device *dev)
struct drm_scatter_gather sgreq;
DRM_DEBUG("Allocating sg memory for PCI DMA\n");
- sgreq.size = 4 << 20; //4MB of PCI scatter-gather zone
+ sgreq.size = 16 << 20; //16MB of PCI scatter-gather zone
if (drm_sg_alloc(dev, &sgreq)) {
- DRM_ERROR("Unable to allocate 4MB of scatter-gather"
- " pages for PCI DMA!");
+ DRM_ERROR("Unable to allocate %dMB of scatter-gather"
+ " pages for PCI DMA!",sgreq.size>>20);
} else {
if (nouveau_mem_init_heap(&dev_priv->pci_heap, 0,
dev->sg->pages * PAGE_SIZE)) {
@@ -531,13 +547,13 @@ alloc_ok:
block->map_handle = entry->user_token;
}
- DRM_INFO("allocated 0x%llx\n", block->start);
+ DRM_DEBUG("allocated 0x%llx type=0x%08x\n", block->start, block->flags);
return block;
}
void nouveau_mem_free(struct drm_device* dev, struct mem_block* block)
{
- DRM_INFO("freeing 0x%llx\n", block->start);
+ DRM_DEBUG("freeing 0x%llx type=0x%08x\n", block->start, block->flags);
if (block->flags&NOUVEAU_MEM_MAPPED)
drm_rmmap(dev, block->map);
nouveau_mem_free_block(block);
@@ -549,14 +565,10 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block)
int nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_nouveau_mem_alloc *alloc = data;
struct mem_block *block;
- if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
- return -EINVAL;
- }
+ NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
block=nouveau_mem_alloc(dev, alloc->alignment, alloc->size,
alloc->flags, file_priv);
@@ -575,6 +587,8 @@ int nouveau_ioctl_mem_free(struct drm_device *dev, void *data, struct drm_file *
struct drm_nouveau_mem_free *memfree = data;
struct mem_block *block;
+ NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
block=NULL;
if (memfree->flags & NOUVEAU_MEM_FB)
block = find_block(dev_priv->fb_heap, memfree->offset);
diff --git a/shared-core/nouveau_notifier.c b/shared-core/nouveau_notifier.c
index 24a306e8..71b8cbe1 100644
--- a/shared-core/nouveau_notifier.c
+++ b/shared-core/nouveau_notifier.c
@@ -30,25 +30,27 @@
#include "nouveau_drv.h"
int
-nouveau_notifier_init_channel(struct drm_device *dev, int channel,
- struct drm_file *file_priv)
+nouveau_notifier_init_channel(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
int flags, ret;
/*TODO: PCI notifier blocks */
- if (dev_priv->agp_heap &&
- dev_priv->gart_info.type != NOUVEAU_GART_SGDMA)
- flags = NOUVEAU_MEM_AGP | NOUVEAU_MEM_FB_ACCEPTABLE;
+ if (dev_priv->agp_heap)
+ flags = NOUVEAU_MEM_AGP;
+ else if (dev_priv->pci_heap)
+ flags = NOUVEAU_MEM_PCI;
else
flags = NOUVEAU_MEM_FB;
- flags |= NOUVEAU_MEM_MAPPED;
+ flags |= (NOUVEAU_MEM_MAPPED | NOUVEAU_MEM_FB_ACCEPTABLE);
chan->notifier_block = nouveau_mem_alloc(dev, 0, PAGE_SIZE, flags,
- file_priv);
+ (struct drm_file *)-2);
if (!chan->notifier_block)
return -ENOMEM;
+ DRM_DEBUG("Allocated notifier block in 0x%08x\n",
+ chan->notifier_block->flags);
ret = nouveau_mem_init_heap(&chan->notifier_heap,
0, chan->notifier_block->size);
@@ -59,25 +61,34 @@ nouveau_notifier_init_channel(struct drm_device *dev, int channel,
}
void
-nouveau_notifier_takedown_channel(struct drm_device *dev, int channel)
+nouveau_notifier_takedown_channel(struct nouveau_channel *chan)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
+ struct drm_device *dev = chan->dev;
if (chan->notifier_block) {
nouveau_mem_free(dev, chan->notifier_block);
chan->notifier_block = NULL;
}
- /*XXX: heap destroy */
+ nouveau_mem_takedown(&chan->notifier_heap);
+}
+
+static void
+nouveau_notifier_gpuobj_dtor(struct drm_device *dev,
+ struct nouveau_gpuobj *gpuobj)
+{
+ DRM_DEBUG("\n");
+
+ if (gpuobj->priv)
+ nouveau_mem_free_block(gpuobj->priv);
}
int
-nouveau_notifier_alloc(struct drm_device *dev, int channel, uint32_t handle,
+nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
int count, uint32_t *b_offset)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
struct nouveau_gpuobj *nobj = NULL;
struct mem_block *mem;
uint32_t offset;
@@ -85,38 +96,53 @@ nouveau_notifier_alloc(struct drm_device *dev, int channel, uint32_t handle,
if (!chan->notifier_heap) {
DRM_ERROR("Channel %d doesn't have a notifier heap!\n",
- channel);
+ chan->id);
return -EINVAL;
}
- mem = nouveau_mem_alloc_block(chan->notifier_heap, 32, 0,
- chan->file_priv);
+ mem = nouveau_mem_alloc_block(chan->notifier_heap, count*32, 0,
+ (struct drm_file *)-2);
if (!mem) {
- DRM_ERROR("Channel %d notifier block full\n", channel);
+ DRM_ERROR("Channel %d notifier block full\n", chan->id);
return -ENOMEM;
}
mem->flags = NOUVEAU_MEM_NOTIFIER;
- offset = chan->notifier_block->start + mem->start;
+ offset = chan->notifier_block->start;
if (chan->notifier_block->flags & NOUVEAU_MEM_FB) {
target = NV_DMA_TARGET_VIDMEM;
- } else if (chan->notifier_block->flags & NOUVEAU_MEM_AGP) {
- target = NV_DMA_TARGET_AGP;
+ } else
+ if (chan->notifier_block->flags & NOUVEAU_MEM_AGP) {
+ if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA &&
+ dev_priv->card_type < NV_50) {
+ ret = nouveau_sgdma_get_page(dev, offset, &offset);
+ if (ret)
+ return ret;
+ target = NV_DMA_TARGET_PCI;
+ } else {
+ target = NV_DMA_TARGET_AGP;
+ }
+ } else
+ if (chan->notifier_block->flags & NOUVEAU_MEM_PCI) {
+ target = NV_DMA_TARGET_PCI_NONLINEAR;
} else {
DRM_ERROR("Bad DMA target, flags 0x%08x!\n",
chan->notifier_block->flags);
return -EINVAL;
}
+ offset += mem->start;
- if ((ret = nouveau_gpuobj_dma_new(dev, channel, NV_CLASS_DMA_IN_MEMORY,
+ if ((ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
offset, mem->size,
NV_DMA_ACCESS_RW, target, &nobj))) {
nouveau_mem_free_block(mem);
DRM_ERROR("Error creating notifier ctxdma: %d\n", ret);
return ret;
}
+ nobj->dtor = nouveau_notifier_gpuobj_dtor;
+ nobj->priv = mem;
- if ((ret = nouveau_gpuobj_ref_add(dev, channel, handle, nobj, NULL))) {
+ if ((ret = nouveau_gpuobj_ref_add(dev, chan, handle, nobj, NULL))) {
nouveau_gpuobj_del(dev, &nobj);
nouveau_mem_free_block(mem);
DRM_ERROR("Error referencing notifier ctxdma: %d\n", ret);
@@ -128,19 +154,17 @@ nouveau_notifier_alloc(struct drm_device *dev, int channel, uint32_t handle,
}
int
-nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
+nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
- struct drm_nouveau_notifier_alloc *na = data;
+ struct drm_nouveau_notifierobj_alloc *na = data;
+ struct nouveau_channel *chan;
int ret;
- if (!nouveau_fifo_owner(dev, file_priv, na->channel)) {
- DRM_ERROR("pid %d doesn't own channel %d\n",
- DRM_CURRENTPID, na->channel);
- return -EPERM;
- }
+ NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan);
- ret = nouveau_notifier_alloc(dev, na->channel, na->handle,
- na->count, &na->offset);
+ ret = nouveau_notifier_alloc(chan, na->handle, na->count, &na->offset);
if (ret)
return ret;
diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c
index e8b12bb7..fbce7702 100644
--- a/shared-core/nouveau_object.c
+++ b/shared-core/nouveau_object.c
@@ -72,6 +72,8 @@ nouveau_ramht_hash_handle(struct drm_device *dev, int channel, uint32_t handle)
uint32_t hash = 0;
int i;
+ DRM_DEBUG("ch%d handle=0x%08x\n", channel, handle);
+
for (i=32;i>0;i-=dev_priv->ramht_bits) {
hash ^= (handle & ((1 << dev_priv->ramht_bits) - 1));
handle >>= dev_priv->ramht_bits;
@@ -80,7 +82,7 @@ nouveau_ramht_hash_handle(struct drm_device *dev, int channel, uint32_t handle)
hash ^= channel << (dev_priv->ramht_bits - 4);
hash <<= 3;
- DRM_DEBUG("ch%d handle=0x%08x hash=0x%08x\n", channel, handle, hash);
+ DRM_DEBUG("hash=0x%08x\n", hash);
return hash;
}
@@ -100,7 +102,7 @@ static int
nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
{
struct drm_nouveau_private *dev_priv=dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[ref->channel];
+ struct nouveau_channel *chan = dev_priv->fifos[ref->channel];
struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL;
struct nouveau_gpuobj *gpuobj = ref->gpuobj;
uint32_t ctx, co, ho;
@@ -131,14 +133,21 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
ref->channel, co, ref->handle, ctx);
INSTANCE_WR(ramht, (co + 0)/4, ref->handle);
INSTANCE_WR(ramht, (co + 4)/4, ctx);
+
+ list_add_tail(&ref->list, &chan->ramht_refs);
return 0;
}
DRM_DEBUG("collision ch%d 0x%08x: h=0x%08x\n",
ref->channel, co, INSTANCE_RD(ramht, co/4));
co += 8;
- if (co >= dev_priv->ramht_size)
+ if (co >= dev_priv->ramht_size) {
+ DRM_INFO("no space left after collision\n");
co = 0;
+ /* exit as it seems to cause crash with nouveau_demo and
+ * 0xdead0001 object */
+ break;
+ }
} while (co != ho);
DRM_ERROR("RAMHT space exhausted. ch=%d\n", ref->channel);
@@ -149,7 +158,7 @@ static void
nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[ref->channel];
+ struct nouveau_channel *chan = dev_priv->fifos[ref->channel];
struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL;
uint32_t co, ho;
@@ -167,6 +176,8 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
INSTANCE_RD(ramht, (co + 4)));
INSTANCE_WR(ramht, (co + 0)/4, 0x00000000);
INSTANCE_WR(ramht, (co + 4)/4, 0x00000000);
+
+ list_del(&ref->list);
return;
}
@@ -180,34 +191,30 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
}
int
-nouveau_gpuobj_new(struct drm_device *dev, int channel, int size, int align,
- uint32_t flags, struct nouveau_gpuobj **gpuobj_ret)
+nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
+ int size, int align, uint32_t flags,
+ struct nouveau_gpuobj **gpuobj_ret)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_engine_func *engine = &dev_priv->Engine;
- struct nouveau_fifo *chan = NULL;
+ struct nouveau_engine *engine = &dev_priv->Engine;
struct nouveau_gpuobj *gpuobj;
struct mem_block *pramin = NULL;
int ret;
DRM_DEBUG("ch%d size=%d align=%d flags=0x%08x\n",
- channel, size, align, flags);
+ chan ? chan->id : -1, size, align, flags);
if (!dev_priv || !gpuobj_ret || *gpuobj_ret != NULL)
return -EINVAL;
- if (channel >= 0) {
- if (channel > nouveau_fifo_number(dev))
- return -EINVAL;
- chan = dev_priv->fifos[channel];
- }
-
gpuobj = drm_calloc(1, sizeof(*gpuobj), DRM_MEM_DRIVER);
if (!gpuobj)
return -ENOMEM;
DRM_DEBUG("gpuobj %p\n", gpuobj);
gpuobj->flags = flags;
- gpuobj->im_channel = channel;
+ gpuobj->im_channel = chan ? chan->id : -1;
+
+ list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
/* Choose between global instmem heap, and per-channel private
* instmem heap. On <NV50 allow requests for private instmem
@@ -260,24 +267,64 @@ nouveau_gpuobj_new(struct drm_device *dev, int channel, int size, int align,
INSTANCE_WR(gpuobj, i/4, 0);
}
- if (dev_priv->gpuobj_all) {
- gpuobj->next = dev_priv->gpuobj_all;
- gpuobj->next->prev = gpuobj;
+ *gpuobj_ret = gpuobj;
+ return 0;
+}
+
+int
+nouveau_gpuobj_early_init(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+ DRM_DEBUG("\n");
+
+ INIT_LIST_HEAD(&dev_priv->gpuobj_list);
+
+ return 0;
+}
+
+int
+nouveau_gpuobj_init(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ int ret;
+
+ DRM_DEBUG("\n");
+
+ if (dev_priv->card_type < NV_50) {
+ if ((ret = nouveau_gpuobj_new_fake(dev, dev_priv->ramht_offset,
+ ~0, dev_priv->ramht_size,
+ NVOBJ_FLAG_ZERO_ALLOC |
+ NVOBJ_FLAG_ALLOW_NO_REFS,
+ &dev_priv->ramht, NULL)))
+ return ret;
}
- dev_priv->gpuobj_all = gpuobj;
- *gpuobj_ret = gpuobj;
return 0;
}
-void nouveau_gpuobj_takedown(struct drm_device *dev)
+void
+nouveau_gpuobj_takedown(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+ DRM_DEBUG("\n");
+
+ nouveau_gpuobj_del(dev, &dev_priv->ramht);
+}
+
+void
+nouveau_gpuobj_late_takedown(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_gpuobj *gpuobj = NULL;
+ struct list_head *entry, *tmp;
DRM_DEBUG("\n");
- while ((gpuobj = dev_priv->gpuobj_all)) {
+ list_for_each_safe(entry, tmp, &dev_priv->gpuobj_list) {
+ gpuobj = list_entry(entry, struct nouveau_gpuobj, list);
+
DRM_ERROR("gpuobj %p still exists at takedown, refs=%d\n",
gpuobj, gpuobj->refcount);
gpuobj->refcount = 0;
@@ -285,10 +332,11 @@ void nouveau_gpuobj_takedown(struct drm_device *dev)
}
}
-int nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj)
+int
+nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_engine_func *engine = &dev_priv->Engine;
+ struct nouveau_engine *engine = &dev_priv->Engine;
struct nouveau_gpuobj *gpuobj;
DRM_DEBUG("gpuobj %p\n", pgpuobj ? *pgpuobj : NULL);
@@ -302,7 +350,16 @@ int nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj)
return -EINVAL;
}
- engine->instmem.clear(dev, gpuobj);
+ if (gpuobj->dtor)
+ gpuobj->dtor(dev, gpuobj);
+
+ if (gpuobj->im_backing) {
+ if (gpuobj->flags & NVOBJ_FLAG_FAKE)
+ drm_free(gpuobj->im_backing,
+ sizeof(*gpuobj->im_backing), DRM_MEM_DRIVER);
+ else
+ engine->instmem.clear(dev, gpuobj);
+ }
if (gpuobj->im_pramin) {
if (gpuobj->flags & NVOBJ_FLAG_FAKE)
@@ -312,12 +369,7 @@ int nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj)
nouveau_mem_free_block(gpuobj->im_pramin);
}
- if (gpuobj->next)
- gpuobj->next->prev = gpuobj->prev;
- if (gpuobj->prev)
- gpuobj->prev->next = gpuobj->next;
- else
- dev_priv->gpuobj_all = gpuobj->next;
+ list_del(&gpuobj->list);
*pgpuobj = NULL;
drm_free(gpuobj, sizeof(*gpuobj), DRM_MEM_DRIVER);
@@ -325,7 +377,8 @@ int nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj)
}
static int
-nouveau_gpuobj_instance_get(struct drm_device *dev, int channel,
+nouveau_gpuobj_instance_get(struct drm_device *dev,
+ struct nouveau_channel *chan,
struct nouveau_gpuobj *gpuobj, uint32_t *inst)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -337,15 +390,15 @@ nouveau_gpuobj_instance_get(struct drm_device *dev, int channel,
return 0;
}
- if ((channel > 0) && gpuobj->im_channel != channel) {
+ if (chan && gpuobj->im_channel != chan->id) {
DRM_ERROR("Channel mismatch: obj %d, ref %d\n",
- gpuobj->im_channel, channel);
+ gpuobj->im_channel, chan->id);
return -EINVAL;
}
/* NV50 channel-local instance */
- if (channel > 0) {
- cpramin = dev_priv->fifos[channel]->ramin->gpuobj;
+ if (chan > 0) {
+ cpramin = chan->ramin->gpuobj;
*inst = gpuobj->im_pramin->start - cpramin->im_pramin->start;
return 0;
}
@@ -371,29 +424,25 @@ nouveau_gpuobj_instance_get(struct drm_device *dev, int channel,
}
int
-nouveau_gpuobj_ref_add(struct drm_device *dev, int channel, uint32_t handle,
- struct nouveau_gpuobj *gpuobj, struct nouveau_gpuobj_ref **ref_ret)
+nouveau_gpuobj_ref_add(struct drm_device *dev, struct nouveau_channel *chan,
+ uint32_t handle, struct nouveau_gpuobj *gpuobj,
+ struct nouveau_gpuobj_ref **ref_ret)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = NULL;
struct nouveau_gpuobj_ref *ref;
uint32_t instance;
int ret;
- DRM_DEBUG("ch%d h=0x%08x gpuobj=%p\n", channel, handle, gpuobj);
+ DRM_DEBUG("ch%d h=0x%08x gpuobj=%p\n",
+ chan ? chan->id : -1, handle, gpuobj);
if (!dev_priv || !gpuobj || (ref_ret && *ref_ret != NULL))
return -EINVAL;
- if (channel >= 0) {
- if (channel > nouveau_fifo_number(dev))
- return -EINVAL;
- chan = dev_priv->fifos[channel];
- } else
- if (!ref_ret)
+ if (!chan && !ref_ret)
return -EINVAL;
- ret = nouveau_gpuobj_instance_get(dev, channel, gpuobj, &instance);
+ ret = nouveau_gpuobj_instance_get(dev, chan, gpuobj, &instance);
if (ret)
return ret;
@@ -401,7 +450,7 @@ nouveau_gpuobj_ref_add(struct drm_device *dev, int channel, uint32_t handle,
if (!ref)
return -ENOMEM;
ref->gpuobj = gpuobj;
- ref->channel = channel;
+ ref->channel = chan ? chan->id : -1;
ref->instance = instance;
if (!ref_ret) {
@@ -412,9 +461,6 @@ nouveau_gpuobj_ref_add(struct drm_device *dev, int channel, uint32_t handle,
drm_free(ref, sizeof(*ref), DRM_MEM_DRIVER);
return ret;
}
-
- ref->next = chan->ramht_refs;
- chan->ramht_refs = ref;
} else {
ref->handle = ~0;
*ref_ret = ref;
@@ -452,8 +498,9 @@ int nouveau_gpuobj_ref_del(struct drm_device *dev, struct nouveau_gpuobj_ref **p
}
int
-nouveau_gpuobj_new_ref(struct drm_device *dev, int oc, int rc, uint32_t handle,
- int size, int align, uint32_t flags,
+nouveau_gpuobj_new_ref(struct drm_device *dev,
+ struct nouveau_channel *oc, struct nouveau_channel *rc,
+ uint32_t handle, int size, int align, uint32_t flags,
struct nouveau_gpuobj_ref **ref)
{
struct nouveau_gpuobj *gpuobj = NULL;
@@ -470,28 +517,29 @@ nouveau_gpuobj_new_ref(struct drm_device *dev, int oc, int rc, uint32_t handle,
return 0;
}
-static int
-nouveau_gpuobj_ref_find(struct drm_device *dev, int channel, uint32_t handle,
+int
+nouveau_gpuobj_ref_find(struct nouveau_channel *chan, uint32_t handle,
struct nouveau_gpuobj_ref **ref_ret)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
- struct nouveau_gpuobj_ref *ref = chan->ramht_refs;
+ struct nouveau_gpuobj_ref *ref;
+ struct list_head *entry, *tmp;
+
+ list_for_each_safe(entry, tmp, &chan->ramht_refs) {
+ ref = list_entry(entry, struct nouveau_gpuobj_ref, list);
- while (ref) {
if (ref->handle == handle) {
if (ref_ret)
*ref_ret = ref;
return 0;
}
- ref = ref->next;
}
return -EINVAL;
}
int
-nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t offset, uint32_t size,
+nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset,
+ uint32_t b_offset, uint32_t size,
uint32_t flags, struct nouveau_gpuobj **pgpuobj,
struct nouveau_gpuobj_ref **pref)
{
@@ -499,8 +547,8 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t offset, uint32_t size,
struct nouveau_gpuobj *gpuobj = NULL;
int i;
- DRM_DEBUG("offset=0x%08x size=0x%08x flags=0x%08x\n",
- offset, size, flags);
+ DRM_DEBUG("p_offset=0x%08x b_offset=0x%08x size=0x%08x flags=0x%08x\n",
+ p_offset, b_offset, size, flags);
gpuobj = drm_calloc(1, sizeof(*gpuobj), DRM_MEM_DRIVER);
if (!gpuobj)
@@ -509,14 +557,29 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t offset, uint32_t size,
gpuobj->im_channel = -1;
gpuobj->flags = flags | NVOBJ_FLAG_FAKE;
- gpuobj->im_pramin = drm_calloc(1, sizeof(struct mem_block),
- DRM_MEM_DRIVER);
- if (!gpuobj->im_pramin) {
- nouveau_gpuobj_del(dev, &gpuobj);
- return -ENOMEM;
+ list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
+
+ if (p_offset != ~0) {
+ gpuobj->im_pramin = drm_calloc(1, sizeof(struct mem_block),
+ DRM_MEM_DRIVER);
+ if (!gpuobj->im_pramin) {
+ nouveau_gpuobj_del(dev, &gpuobj);
+ return -ENOMEM;
+ }
+ gpuobj->im_pramin->start = p_offset;
+ gpuobj->im_pramin->size = size;
+ }
+
+ if (b_offset != ~0) {
+ gpuobj->im_backing = drm_calloc(1, sizeof(struct mem_block),
+ DRM_MEM_DRIVER);
+ if (!gpuobj->im_backing) {
+ nouveau_gpuobj_del(dev, &gpuobj);
+ return -ENOMEM;
+ }
+ gpuobj->im_backing->start = b_offset;
+ gpuobj->im_backing->size = size;
}
- gpuobj->im_pramin->start = offset;
- gpuobj->im_pramin->size = size;
if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
for (i = 0; i < gpuobj->im_pramin->size; i += 4)
@@ -524,7 +587,7 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t offset, uint32_t size,
}
if (pref) {
- if ((i = nouveau_gpuobj_ref_add(dev, -1, 0, gpuobj, pref))) {
+ if ((i = nouveau_gpuobj_ref_add(dev, NULL, 0, gpuobj, pref))) {
nouveau_gpuobj_del(dev, &gpuobj);
return i;
}
@@ -577,10 +640,11 @@ nouveau_gpuobj_class_instmem_size(struct drm_device *dev, int class)
to it that can be used to set up context objects.
*/
int
-nouveau_gpuobj_dma_new(struct drm_device *dev, int channel, int class,
- uint64_t offset, uint64_t size, int access, int target,
- struct nouveau_gpuobj **gpuobj)
+nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class,
+ uint64_t offset, uint64_t size, int access,
+ int target, struct nouveau_gpuobj **gpuobj)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
int ret;
uint32_t is_scatter_gather = 0;
@@ -591,7 +655,7 @@ nouveau_gpuobj_dma_new(struct drm_device *dev, int channel, int class,
DRM_DEBUG("ch%d class=0x%04x offset=0x%llx size=0x%llx\n",
- channel, class, offset, size);
+ chan->id, class, offset, size);
DRM_DEBUG("access=%d target=%d\n", access, target);
switch (target) {
@@ -608,7 +672,7 @@ nouveau_gpuobj_dma_new(struct drm_device *dev, int channel, int class,
break;
}
- ret = nouveau_gpuobj_new(dev, channel,
+ ret = nouveau_gpuobj_new(dev, chan,
is_scatter_gather ? ((page_count << 2) + 12) : nouveau_gpuobj_class_instmem_size(dev, class),
16,
NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE,
@@ -711,19 +775,19 @@ nouveau_gpuobj_dma_new(struct drm_device *dev, int channel, int class,
}
int
-nouveau_gpuobj_gart_dma_new(struct drm_device *dev, int channel,
+nouveau_gpuobj_gart_dma_new(struct nouveau_channel *chan,
uint64_t offset, uint64_t size, int access,
struct nouveau_gpuobj **gpuobj,
uint32_t *o_ret)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
int ret;
if (dev_priv->gart_info.type == NOUVEAU_GART_AGP ||
(dev_priv->card_type >= NV_50 &&
dev_priv->gart_info.type == NOUVEAU_GART_SGDMA)) {
- ret = nouveau_gpuobj_dma_new(dev, channel,
- NV_CLASS_DMA_IN_MEMORY,
+ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
offset, size, access,
NV_DMA_TARGET_AGP, gpuobj);
if (o_ret)
@@ -798,15 +862,16 @@ nouveau_gpuobj_gart_dma_new(struct drm_device *dev, int channel,
set to 0?
*/
int
-nouveau_gpuobj_gr_new(struct drm_device *dev, int channel, int class,
+nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class,
struct nouveau_gpuobj **gpuobj)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
int ret;
- DRM_DEBUG("ch%d class=0x%04x\n", channel, class);
+ DRM_DEBUG("ch%d class=0x%04x\n", chan->id, class);
- ret = nouveau_gpuobj_new(dev, channel,
+ ret = nouveau_gpuobj_new(dev, chan,
nouveau_gpuobj_class_instmem_size(dev, class),
16,
NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE,
@@ -847,14 +912,14 @@ nouveau_gpuobj_gr_new(struct drm_device *dev, int channel, int class,
}
static int
-nouveau_gpuobj_channel_init_pramin(struct drm_device *dev, int channel)
+nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
struct nouveau_gpuobj *pramin = NULL;
int size, base, ret;
- DRM_DEBUG("ch%d\n", channel);
+ DRM_DEBUG("ch%d\n", chan->id);
/* Base amount for object storage (4KiB enough?) */
size = 0x1000;
@@ -876,8 +941,8 @@ nouveau_gpuobj_channel_init_pramin(struct drm_device *dev, int channel)
}
DRM_DEBUG("ch%d PRAMIN size: 0x%08x bytes, base alloc=0x%08x\n",
- channel, size, base);
- ret = nouveau_gpuobj_new_ref(dev, -1, -1, 0, size, 0x1000, 0,
+ chan->id, size, base);
+ ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, size, 0x1000, 0,
&chan->ramin);
if (ret) {
DRM_ERROR("Error allocating channel PRAMIN: %d\n", ret);
@@ -897,21 +962,23 @@ nouveau_gpuobj_channel_init_pramin(struct drm_device *dev, int channel)
}
int
-nouveau_gpuobj_channel_init(struct drm_device *dev, int channel,
+nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
uint32_t vram_h, uint32_t tt_h)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
struct nouveau_gpuobj *vram = NULL, *tt = NULL;
int ret, i;
- DRM_DEBUG("ch%d vram=0x%08x tt=0x%08x\n", channel, vram_h, tt_h);
+ INIT_LIST_HEAD(&chan->ramht_refs);
+
+ DRM_DEBUG("ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h);
/* Reserve a block of PRAMIN for the channel
*XXX: maybe on <NV50 too at some point
*/
if (0 || dev_priv->card_type == NV_50) {
- ret = nouveau_gpuobj_channel_init_pramin(dev, channel);
+ ret = nouveau_gpuobj_channel_init_pramin(chan);
if (ret)
return ret;
}
@@ -922,7 +989,7 @@ nouveau_gpuobj_channel_init(struct drm_device *dev, int channel,
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, 0x4000,
+ if ((ret = nouveau_gpuobj_new_fake(dev, vm_offset, ~0, 0x4000,
0, &chan->vm_pd, NULL)))
return ret;
for (i=0; i<0x4000; i+=8) {
@@ -930,7 +997,7 @@ nouveau_gpuobj_channel_init(struct drm_device *dev, int channel,
INSTANCE_WR(chan->vm_pd, (i+4)/4, 0xdeadcafe);
}
- if ((ret = nouveau_gpuobj_ref_add(dev, -1, 0,
+ if ((ret = nouveau_gpuobj_ref_add(dev, NULL, 0,
dev_priv->gart_info.sg_ctxdma,
&chan->vm_gart_pt)))
return ret;
@@ -941,12 +1008,12 @@ nouveau_gpuobj_channel_init(struct drm_device *dev, int channel,
/* RAMHT */
if (dev_priv->card_type < NV_50) {
- ret = nouveau_gpuobj_ref_add(dev, -1, 0, dev_priv->ramht,
+ ret = nouveau_gpuobj_ref_add(dev, NULL, 0, dev_priv->ramht,
&chan->ramht);
if (ret)
return ret;
} else {
- ret = nouveau_gpuobj_new_ref(dev, channel, channel, 0,
+ ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0,
0x8000, 16,
NVOBJ_FLAG_ZERO_ALLOC,
&chan->ramht);
@@ -955,7 +1022,7 @@ nouveau_gpuobj_channel_init(struct drm_device *dev, int channel,
}
/* VRAM ctxdma */
- if ((ret = nouveau_gpuobj_dma_new(dev, channel, NV_CLASS_DMA_IN_MEMORY,
+ if ((ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
0, dev_priv->fb_available_size,
NV_DMA_ACCESS_RW,
NV_DMA_TARGET_VIDMEM, &vram))) {
@@ -963,20 +1030,19 @@ nouveau_gpuobj_channel_init(struct drm_device *dev, int channel,
return ret;
}
- if ((ret = nouveau_gpuobj_ref_add(dev, channel, vram_h, vram, NULL))) {
+ if ((ret = nouveau_gpuobj_ref_add(dev, chan, vram_h, vram, NULL))) {
DRM_ERROR("Error referencing VRAM ctxdma: %d\n", ret);
return ret;
}
/* TT memory ctxdma */
if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) {
- ret = nouveau_gpuobj_gart_dma_new(dev, channel, 0,
+ ret = nouveau_gpuobj_gart_dma_new(chan, 0,
dev_priv->gart_info.aper_size,
NV_DMA_ACCESS_RW, &tt, NULL);
} else
if (dev_priv->pci_heap) {
- ret = nouveau_gpuobj_dma_new(dev, channel,
- NV_CLASS_DMA_IN_MEMORY,
+ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
0, dev->sg->pages * PAGE_SIZE,
NV_DMA_ACCESS_RW,
NV_DMA_TARGET_PCI_NONLINEAR, &tt);
@@ -990,7 +1056,7 @@ nouveau_gpuobj_channel_init(struct drm_device *dev, int channel,
return ret;
}
- ret = nouveau_gpuobj_ref_add(dev, channel, tt_h, tt, NULL);
+ ret = nouveau_gpuobj_ref_add(dev, chan, tt_h, tt, NULL);
if (ret) {
DRM_ERROR("Error referencing TT ctxdma: %d\n", ret);
return ret;
@@ -1000,18 +1066,20 @@ nouveau_gpuobj_channel_init(struct drm_device *dev, int channel,
}
void
-nouveau_gpuobj_channel_takedown(struct drm_device *dev, int channel)
+nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
+ struct drm_device *dev = chan->dev;
+ struct list_head *entry, *tmp;
struct nouveau_gpuobj_ref *ref;
- DRM_DEBUG("ch%d\n", channel);
+ DRM_DEBUG("ch%d\n", chan->id);
+
+ list_for_each_safe(entry, tmp, &chan->ramht_refs) {
+ ref = list_entry(entry, struct nouveau_gpuobj_ref, list);
- while ((ref = chan->ramht_refs)) {
- chan->ramht_refs = ref->next;
nouveau_gpuobj_ref_del(dev, &ref);
}
+
nouveau_gpuobj_ref_del(dev, &chan->ramht);
nouveau_gpuobj_del(dev, &chan->vm_pd);
@@ -1024,35 +1092,33 @@ nouveau_gpuobj_channel_takedown(struct drm_device *dev, int channel)
}
-int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
+int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
+ struct nouveau_channel *chan;
struct drm_nouveau_grobj_alloc *init = data;
struct nouveau_gpuobj *gr = NULL;
int ret;
- if (!nouveau_fifo_owner(dev, file_priv, init->channel)) {
- DRM_ERROR("pid %d doesn't own channel %d\n",
- DRM_CURRENTPID, init->channel);
- return -EINVAL;
- }
+ NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init->channel, file_priv, chan);
//FIXME: check args, only allow trusted objects to be created
if (init->handle == ~0)
return -EINVAL;
- if (nouveau_gpuobj_ref_find(dev, init->channel, init->handle, NULL) ==
- 0)
+
+ if (nouveau_gpuobj_ref_find(chan, init->handle, NULL) == 0)
return -EEXIST;
- ret = nouveau_gpuobj_gr_new(dev, init->channel, init->class, &gr);
+ ret = nouveau_gpuobj_gr_new(chan, init->class, &gr);
if (ret) {
DRM_ERROR("Error creating gr object: %d (%d/0x%08x)\n",
ret, init->channel, init->handle);
return ret;
}
- if ((ret = nouveau_gpuobj_ref_add(dev, init->channel, init->handle,
- gr, NULL))) {
+ if ((ret = nouveau_gpuobj_ref_add(dev, chan, init->handle, gr, NULL))) {
DRM_ERROR("Error referencing gr object: %d (%d/0x%08x\n)",
ret, init->channel, init->handle);
nouveau_gpuobj_del(dev, &gr);
@@ -1062,3 +1128,21 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, struct drm_fil
return 0;
}
+int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_nouveau_gpuobj_free *objfree = data;
+ struct nouveau_gpuobj_ref *ref;
+ struct nouveau_channel *chan;
+ int ret;
+
+ NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree->channel, file_priv, chan);
+
+ if ((ret = nouveau_gpuobj_ref_find(chan, objfree->handle, &ref)))
+ return ret;
+ nouveau_gpuobj_ref_del(dev, &ref);
+
+ return 0;
+}
+
diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h
index 47d54b2a..a1895c34 100644
--- a/shared-core/nouveau_reg.h
+++ b/shared-core/nouveau_reg.h
@@ -15,9 +15,6 @@
# define NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000
# define NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20
-#define NV03_PGRAPH_STATUS 0x004006b0
-#define NV04_PGRAPH_STATUS 0x00400700
-
#define NV_RAMIN 0x00700000
#define NV_RAMHT_HANDLE_OFFSET 0
@@ -80,6 +77,16 @@
#define NV40_PMC_1708 0x00001708
#define NV40_PMC_170C 0x0000170C
+/* probably PMC ? */
+#define NV50_PUNK_BAR0_PRAMIN 0x00001700
+#define NV50_PUNK_BAR_CFG_BASE 0x00001704
+#define NV50_PUNK_BAR_CFG_BASE_VALID (1<<30)
+#define NV50_PUNK_BAR1_CTXDMA 0x00001708
+#define NV50_PUNK_BAR1_CTXDMA_VALID (1<<31)
+#define NV50_PUNK_BAR3_CTXDMA 0x0000170C
+#define NV50_PUNK_BAR3_CTXDMA_VALID (1<<31)
+#define NV50_PUNK_UNK1710 0x00001710
+
#define NV04_PTIMER_INTR_0 0x00009100
#define NV04_PTIMER_INTR_EN_0 0x00009140
#define NV04_PTIMER_NUMERATOR 0x00009200
@@ -168,6 +175,10 @@
#define NV10_PGRAPH_CTX_CACHE5 0x004001E0
#define NV40_PGRAPH_CTXCTL_0304 0x00400304
#define NV40_PGRAPH_CTXCTL_0304_XFER_CTX 0x00000001
+#define NV40_PGRAPH_CTXCTL_UCODE_STAT 0x00400308
+#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_MASK 0xff000000
+#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT 24
+#define NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK 0x00ffffff
#define NV40_PGRAPH_CTXCTL_0310 0x00400310
#define NV40_PGRAPH_CTXCTL_0310_XFER_SAVE 0x00000020
#define NV40_PGRAPH_CTXCTL_0310_XFER_LOAD 0x00000040
@@ -250,7 +261,12 @@
#define NV04_PGRAPH_BLIMIT5 0x00400698
#define NV04_PGRAPH_BSWIZZLE2 0x0040069C
#define NV04_PGRAPH_BSWIZZLE5 0x004006A0
+#define NV03_PGRAPH_STATUS 0x004006B0
+#define NV04_PGRAPH_STATUS 0x00400700
+#define NV04_PGRAPH_TRAPPED_ADDR 0x00400704
+#define NV04_PGRAPH_TRAPPED_DATA 0x00400708
#define NV04_PGRAPH_SURFACE 0x0040070C
+#define NV10_PGRAPH_TRAPPED_DATA_HIGH 0x0040070C
#define NV04_PGRAPH_STATE 0x00400710
#define NV10_PGRAPH_SURFACE 0x00400710
#define NV04_PGRAPH_NOTIFY 0x00400714
diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c
index f45f2783..e73b4878 100644
--- a/shared-core/nouveau_state.c
+++ b/shared-core/nouveau_state.c
@@ -93,7 +93,7 @@ static uint64_t nouveau_stub_timer_read(struct drm_device *dev) { return 0; }
static int nouveau_init_engine_ptrs(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_engine_func *engine = &dev_priv->Engine;
+ struct nouveau_engine *engine = &dev_priv->Engine;
switch (dev_priv->chipset & 0xf0) {
case 0x00:
@@ -224,7 +224,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->graph.destroy_context = nv40_graph_destroy_context;
engine->graph.load_context = nv40_graph_load_context;
engine->graph.save_context = nv40_graph_save_context;
- engine->fifo.init = nouveau_fifo_init;
+ engine->fifo.init = nv40_fifo_init;
engine->fifo.takedown = nouveau_stub_takedown;
engine->fifo.create_context = nv40_fifo_create_context;
engine->fifo.destroy_context = nv40_fifo_destroy_context;
@@ -267,12 +267,18 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
return 0;
}
-static int nouveau_card_init(struct drm_device *dev)
+int
+nouveau_card_init(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_engine_func *engine;
+ struct nouveau_engine *engine;
int ret;
+ DRM_DEBUG("prev state = %d\n", dev_priv->init_state);
+
+ if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE)
+ return 0;
+
/* Map any PCI resources we need on the card */
ret = nouveau_init_card_mappings(dev);
if (ret) return ret;
@@ -290,6 +296,9 @@ static int nouveau_card_init(struct drm_device *dev)
engine = &dev_priv->Engine;
dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED;
+ ret = nouveau_gpuobj_early_init(dev);
+ if (ret) return ret;
+
/* Initialise instance memory, must happen before mem_init so we
* know exactly how much VRAM we're able to use for "normal"
* purposes.
@@ -301,6 +310,9 @@ static int nouveau_card_init(struct drm_device *dev)
ret = nouveau_mem_init(dev);
if (ret) return ret;
+ ret = nouveau_gpuobj_init(dev);
+ if (ret) return ret;
+
/* Parse BIOS tables / Run init tables? */
/* PMC */
@@ -323,8 +335,17 @@ static int nouveau_card_init(struct drm_device *dev)
ret = engine->fifo.init(dev);
if (ret) return ret;
+ /* this call irq_preinstall, register irq handler and
+ * call irq_postinstall
+ */
+ ret = drm_irq_install(dev);
+ if (ret) return ret;
+
/* what about PVIDEO/PCRTC/PRAMDAC etc? */
+ ret = nouveau_dma_channel_init(dev);
+ if (ret) return ret;
+
dev_priv->init_state = NOUVEAU_CARD_INIT_DONE;
return 0;
}
@@ -332,9 +353,13 @@ static int nouveau_card_init(struct drm_device *dev)
static void nouveau_card_takedown(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_engine_func *engine = &dev_priv->Engine;
+ struct nouveau_engine *engine = &dev_priv->Engine;
+
+ DRM_DEBUG("prev state = %d\n", dev_priv->init_state);
if (dev_priv->init_state != NOUVEAU_CARD_INIT_DOWN) {
+ nouveau_dma_channel_takedown(dev);
+
engine->fifo.takedown(dev);
engine->graph.takedown(dev);
engine->fb.takedown(dev);
@@ -349,6 +374,10 @@ static void nouveau_card_takedown(struct drm_device *dev)
nouveau_mem_close(dev);
engine->instmem.takedown(dev);
+ drm_irq_uninstall(dev);
+
+ nouveau_gpuobj_late_takedown(dev);
+
dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;
}
}
@@ -368,14 +397,6 @@ void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv)
/* 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;
}
@@ -395,15 +416,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;
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;
}
@@ -427,12 +439,24 @@ int nouveau_unload(struct drm_device *dev)
return 0;
}
+int
+nouveau_ioctl_card_init(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ return nouveau_card_init(dev);
+}
+
int nouveau_ioctl_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_nouveau_getparam *getparam = data;
+ NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
switch (getparam->param) {
+ case NOUVEAU_GETPARAM_CHIPSET_ID:
+ getparam->value = dev_priv->chipset;
+ break;
case NOUVEAU_GETPARAM_PCI_VENDOR:
getparam->value=dev->pci_vendor;
break;
@@ -481,6 +505,8 @@ int nouveau_ioctl_setparam(struct drm_device *dev, void *data, struct drm_file *
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_nouveau_setparam *setparam = data;
+ NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
switch (setparam->param) {
case NOUVEAU_SETPARAM_CMDBUF_LOCATION:
switch (setparam->value) {
@@ -512,9 +538,6 @@ void nouveau_wait_for_idle(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv=dev->dev_private;
switch(dev_priv->card_type) {
- case NV_03:
- while (NV_READ(NV03_PGRAPH_STATUS));
- break;
case NV_50:
break;
default: {
@@ -526,6 +549,7 @@ void nouveau_wait_for_idle(struct drm_device *dev)
uint32_t status;
do {
uint32_t pmc_e = NV_READ(NV03_PMC_ENABLE);
+ (void)pmc_e;
status = NV_READ(NV04_PGRAPH_STATUS);
if (!status)
break;
diff --git a/shared-core/nv04_fifo.c b/shared-core/nv04_fifo.c
index 564efd0b..d750ced8 100644
--- a/shared-core/nv04_fifo.c
+++ b/shared-core/nv04_fifo.c
@@ -36,13 +36,13 @@
#define NV04_RAMFC__SIZE 32
int
-nv04_fifo_create_context(struct drm_device *dev, int channel)
+nv04_fifo_create_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
int ret;
- if ((ret = nouveau_gpuobj_new_fake(dev, NV04_RAMFC(channel),
+ if ((ret = nouveau_gpuobj_new_fake(dev, NV04_RAMFC(chan->id), ~0,
NV04_RAMFC__SIZE,
NVOBJ_FLAG_ZERO_ALLOC |
NVOBJ_FLAG_ZERO_FREE,
@@ -62,30 +62,29 @@ nv04_fifo_create_context(struct drm_device *dev, int channel)
0));
/* enable the fifo dma operation */
- NV_WRITE(NV04_PFIFO_MODE,NV_READ(NV04_PFIFO_MODE)|(1<<channel));
+ NV_WRITE(NV04_PFIFO_MODE,NV_READ(NV04_PFIFO_MODE) | (1<<chan->id));
return 0;
}
void
-nv04_fifo_destroy_context(struct drm_device *dev, int channel)
+nv04_fifo_destroy_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
-
- NV_WRITE(NV04_PFIFO_MODE, NV_READ(NV04_PFIFO_MODE)&~(1<<channel));
+
+ NV_WRITE(NV04_PFIFO_MODE, NV_READ(NV04_PFIFO_MODE)&~(1<<chan->id));
- if (chan->ramfc)
- nouveau_gpuobj_ref_del(dev, &chan->ramfc);
+ nouveau_gpuobj_ref_del(dev, &chan->ramfc);
}
int
-nv04_fifo_load_context(struct drm_device *dev, int channel)
+nv04_fifo_load_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
uint32_t tmp;
- NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, (1<<8) | channel);
+ NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, (1<<8) | chan->id);
NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET, RAMFC_RD(DMA_GET));
NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUT, RAMFC_RD(DMA_PUT));
@@ -107,10 +106,10 @@ nv04_fifo_load_context(struct drm_device *dev, int channel)
}
int
-nv04_fifo_save_context(struct drm_device *dev, int channel)
+nv04_fifo_save_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
uint32_t tmp;
RAMFC_WR(DMA_PUT, NV04_PFIFO_CACHE1_DMA_PUT);
diff --git a/shared-core/nv04_graph.c b/shared-core/nv04_graph.c
index e35e3071..213696ca 100644
--- a/shared-core/nv04_graph.c
+++ b/shared-core/nv04_graph.c
@@ -27,262 +27,321 @@
#include "nouveau_drm.h"
#include "nouveau_drv.h"
-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_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}
+static uint32_t nv04_graph_ctx_regs [] = {
+ NV04_PGRAPH_CTX_SWITCH1,
+ NV04_PGRAPH_CTX_SWITCH2,
+ NV04_PGRAPH_CTX_SWITCH3,
+ NV04_PGRAPH_CTX_SWITCH4,
+ NV04_PGRAPH_CTX_CACHE1,
+ NV04_PGRAPH_CTX_CACHE2,
+ NV04_PGRAPH_CTX_CACHE3,
+ NV04_PGRAPH_CTX_CACHE4,
+ 0x00400184,
+ 0x004001a4,
+ 0x004001c4,
+ 0x004001e4,
+ 0x00400188,
+ 0x004001a8,
+ 0x004001c8,
+ 0x004001e8,
+ 0x0040018c,
+ 0x004001ac,
+ 0x004001cc,
+ 0x004001ec,
+ 0x00400190,
+ 0x004001b0,
+ 0x004001d0,
+ 0x004001f0,
+ 0x00400194,
+ 0x004001b4,
+ 0x004001d4,
+ 0x004001f4,
+ 0x00400198,
+ 0x004001b8,
+ 0x004001d8,
+ 0x004001f8,
+ 0x0040019c,
+ 0x004001bc,
+ 0x004001dc,
+ 0x004001fc,
+ 0x00400174,
+ NV04_PGRAPH_DMA_START_0,
+ NV04_PGRAPH_DMA_START_1,
+ NV04_PGRAPH_DMA_LENGTH,
+ NV04_PGRAPH_DMA_MISC,
+ NV04_PGRAPH_DMA_PITCH,
+ NV04_PGRAPH_BOFFSET0,
+ NV04_PGRAPH_BBASE0,
+ NV04_PGRAPH_BLIMIT0,
+ NV04_PGRAPH_BOFFSET1,
+ NV04_PGRAPH_BBASE1,
+ NV04_PGRAPH_BLIMIT1,
+ NV04_PGRAPH_BOFFSET2,
+ NV04_PGRAPH_BBASE2,
+ NV04_PGRAPH_BLIMIT2,
+ NV04_PGRAPH_BOFFSET3,
+ NV04_PGRAPH_BBASE3,
+ NV04_PGRAPH_BLIMIT3,
+ NV04_PGRAPH_BOFFSET4,
+ NV04_PGRAPH_BBASE4,
+ NV04_PGRAPH_BLIMIT4,
+ NV04_PGRAPH_BOFFSET5,
+ NV04_PGRAPH_BBASE5,
+ NV04_PGRAPH_BLIMIT5,
+ NV04_PGRAPH_BPITCH0,
+ NV04_PGRAPH_BPITCH1,
+ NV04_PGRAPH_BPITCH2,
+ NV04_PGRAPH_BPITCH3,
+ NV04_PGRAPH_BPITCH4,
+ NV04_PGRAPH_SURFACE,
+ NV04_PGRAPH_STATE,
+ NV04_PGRAPH_BSWIZZLE2,
+ NV04_PGRAPH_BSWIZZLE5,
+ NV04_PGRAPH_BPIXEL,
+ NV04_PGRAPH_NOTIFY,
+ NV04_PGRAPH_PATT_COLOR0,
+ NV04_PGRAPH_PATT_COLOR1,
+ NV04_PGRAPH_PATT_COLORRAM+0x00,
+ NV04_PGRAPH_PATT_COLORRAM+0x01,
+ NV04_PGRAPH_PATT_COLORRAM+0x02,
+ NV04_PGRAPH_PATT_COLORRAM+0x03,
+ NV04_PGRAPH_PATT_COLORRAM+0x04,
+ NV04_PGRAPH_PATT_COLORRAM+0x05,
+ NV04_PGRAPH_PATT_COLORRAM+0x06,
+ NV04_PGRAPH_PATT_COLORRAM+0x07,
+ NV04_PGRAPH_PATT_COLORRAM+0x08,
+ NV04_PGRAPH_PATT_COLORRAM+0x09,
+ NV04_PGRAPH_PATT_COLORRAM+0x0A,
+ NV04_PGRAPH_PATT_COLORRAM+0x0B,
+ NV04_PGRAPH_PATT_COLORRAM+0x0C,
+ NV04_PGRAPH_PATT_COLORRAM+0x0D,
+ NV04_PGRAPH_PATT_COLORRAM+0x0E,
+ NV04_PGRAPH_PATT_COLORRAM+0x0F,
+ NV04_PGRAPH_PATT_COLORRAM+0x10,
+ NV04_PGRAPH_PATT_COLORRAM+0x11,
+ NV04_PGRAPH_PATT_COLORRAM+0x12,
+ NV04_PGRAPH_PATT_COLORRAM+0x13,
+ NV04_PGRAPH_PATT_COLORRAM+0x14,
+ NV04_PGRAPH_PATT_COLORRAM+0x15,
+ NV04_PGRAPH_PATT_COLORRAM+0x16,
+ NV04_PGRAPH_PATT_COLORRAM+0x17,
+ NV04_PGRAPH_PATT_COLORRAM+0x18,
+ NV04_PGRAPH_PATT_COLORRAM+0x19,
+ NV04_PGRAPH_PATT_COLORRAM+0x1A,
+ NV04_PGRAPH_PATT_COLORRAM+0x1B,
+ NV04_PGRAPH_PATT_COLORRAM+0x1C,
+ NV04_PGRAPH_PATT_COLORRAM+0x1D,
+ NV04_PGRAPH_PATT_COLORRAM+0x1E,
+ NV04_PGRAPH_PATT_COLORRAM+0x1F,
+ NV04_PGRAPH_PATT_COLORRAM+0x20,
+ NV04_PGRAPH_PATT_COLORRAM+0x21,
+ NV04_PGRAPH_PATT_COLORRAM+0x22,
+ NV04_PGRAPH_PATT_COLORRAM+0x23,
+ NV04_PGRAPH_PATT_COLORRAM+0x24,
+ NV04_PGRAPH_PATT_COLORRAM+0x25,
+ NV04_PGRAPH_PATT_COLORRAM+0x26,
+ NV04_PGRAPH_PATT_COLORRAM+0x27,
+ NV04_PGRAPH_PATT_COLORRAM+0x28,
+ NV04_PGRAPH_PATT_COLORRAM+0x29,
+ NV04_PGRAPH_PATT_COLORRAM+0x2A,
+ NV04_PGRAPH_PATT_COLORRAM+0x2B,
+ NV04_PGRAPH_PATT_COLORRAM+0x2C,
+ NV04_PGRAPH_PATT_COLORRAM+0x2D,
+ NV04_PGRAPH_PATT_COLORRAM+0x2E,
+ NV04_PGRAPH_PATT_COLORRAM+0x2F,
+ NV04_PGRAPH_PATT_COLORRAM+0x30,
+ NV04_PGRAPH_PATT_COLORRAM+0x31,
+ NV04_PGRAPH_PATT_COLORRAM+0x32,
+ NV04_PGRAPH_PATT_COLORRAM+0x33,
+ NV04_PGRAPH_PATT_COLORRAM+0x34,
+ NV04_PGRAPH_PATT_COLORRAM+0x35,
+ NV04_PGRAPH_PATT_COLORRAM+0x36,
+ NV04_PGRAPH_PATT_COLORRAM+0x37,
+ NV04_PGRAPH_PATT_COLORRAM+0x38,
+ NV04_PGRAPH_PATT_COLORRAM+0x39,
+ NV04_PGRAPH_PATT_COLORRAM+0x3A,
+ NV04_PGRAPH_PATT_COLORRAM+0x3B,
+ NV04_PGRAPH_PATT_COLORRAM+0x3C,
+ NV04_PGRAPH_PATT_COLORRAM+0x3D,
+ NV04_PGRAPH_PATT_COLORRAM+0x3E,
+ NV04_PGRAPH_PATT_COLORRAM+0x3F,
+ NV04_PGRAPH_PATTERN,
+ 0x0040080c,
+ NV04_PGRAPH_PATTERN_SHAPE,
+ 0x00400600,
+ NV04_PGRAPH_ROP3,
+ NV04_PGRAPH_CHROMA,
+ NV04_PGRAPH_BETA_AND,
+ NV04_PGRAPH_BETA_PREMULT,
+ NV04_PGRAPH_CONTROL0,
+ NV04_PGRAPH_CONTROL1,
+ NV04_PGRAPH_CONTROL2,
+ NV04_PGRAPH_BLEND,
+ NV04_PGRAPH_STORED_FMT,
+ NV04_PGRAPH_SOURCE_COLOR,
+ 0x00400560,
+ 0x00400568,
+ 0x00400564,
+ 0x0040056c,
+ 0x00400400,
+ 0x00400480,
+ 0x00400404,
+ 0x00400484,
+ 0x00400408,
+ 0x00400488,
+ 0x0040040c,
+ 0x0040048c,
+ 0x00400410,
+ 0x00400490,
+ 0x00400414,
+ 0x00400494,
+ 0x00400418,
+ 0x00400498,
+ 0x0040041c,
+ 0x0040049c,
+ 0x00400420,
+ 0x004004a0,
+ 0x00400424,
+ 0x004004a4,
+ 0x00400428,
+ 0x004004a8,
+ 0x0040042c,
+ 0x004004ac,
+ 0x00400430,
+ 0x004004b0,
+ 0x00400434,
+ 0x004004b4,
+ 0x00400438,
+ 0x004004b8,
+ 0x0040043c,
+ 0x004004bc,
+ 0x00400440,
+ 0x004004c0,
+ 0x00400444,
+ 0x004004c4,
+ 0x00400448,
+ 0x004004c8,
+ 0x0040044c,
+ 0x004004cc,
+ 0x00400450,
+ 0x004004d0,
+ 0x00400454,
+ 0x004004d4,
+ 0x00400458,
+ 0x004004d8,
+ 0x0040045c,
+ 0x004004dc,
+ 0x00400460,
+ 0x004004e0,
+ 0x00400464,
+ 0x004004e4,
+ 0x00400468,
+ 0x004004e8,
+ 0x0040046c,
+ 0x004004ec,
+ 0x00400470,
+ 0x004004f0,
+ 0x00400474,
+ 0x004004f4,
+ 0x00400478,
+ 0x004004f8,
+ 0x0040047c,
+ 0x004004fc,
+ 0x0040053c,
+ 0x00400544,
+ 0x00400540,
+ 0x00400548,
+ 0x00400560,
+ 0x00400568,
+ 0x00400564,
+ 0x0040056c,
+ 0x00400534,
+ 0x00400538,
+ 0x00400514,
+ 0x00400518,
+ 0x0040051c,
+ 0x00400520,
+ 0x00400524,
+ 0x00400528,
+ 0x0040052c,
+ 0x00400530,
+ 0x00400d00,
+ 0x00400d40,
+ 0x00400d80,
+ 0x00400d04,
+ 0x00400d44,
+ 0x00400d84,
+ 0x00400d08,
+ 0x00400d48,
+ 0x00400d88,
+ 0x00400d0c,
+ 0x00400d4c,
+ 0x00400d8c,
+ 0x00400d10,
+ 0x00400d50,
+ 0x00400d90,
+ 0x00400d14,
+ 0x00400d54,
+ 0x00400d94,
+ 0x00400d18,
+ 0x00400d58,
+ 0x00400d98,
+ 0x00400d1c,
+ 0x00400d5c,
+ 0x00400d9c,
+ 0x00400d20,
+ 0x00400d60,
+ 0x00400da0,
+ 0x00400d24,
+ 0x00400d64,
+ 0x00400da4,
+ 0x00400d28,
+ 0x00400d68,
+ 0x00400da8,
+ 0x00400d2c,
+ 0x00400d6c,
+ 0x00400dac,
+ 0x00400d30,
+ 0x00400d70,
+ 0x00400db0,
+ 0x00400d34,
+ 0x00400d74,
+ 0x00400db4,
+ 0x00400d38,
+ 0x00400d78,
+ 0x00400db8,
+ 0x00400d3c,
+ 0x00400d7c,
+ 0x00400dbc,
+ 0x00400590,
+ 0x00400594,
+ 0x00400598,
+ 0x0040059c,
+ 0x004005a8,
+ 0x004005ac,
+ 0x004005b0,
+ 0x004005b4,
+ 0x004005c0,
+ 0x004005c4,
+ 0x004005c8,
+ 0x004005cc,
+ 0x004005d0,
+ 0x004005d4,
+ 0x004005d8,
+ 0x004005dc,
+ 0x004005e0,
+ NV04_PGRAPH_PASSTHRU_0,
+ NV04_PGRAPH_PASSTHRU_1,
+ NV04_PGRAPH_PASSTHRU_2,
+ NV04_PGRAPH_DVD_COLORFMT,
+ NV04_PGRAPH_SCALED_FORMAT,
+ NV04_PGRAPH_MISC24_0,
+ NV04_PGRAPH_MISC24_1,
+ NV04_PGRAPH_MISC24_2,
+ 0x00400500,
+ 0x00400504,
+ NV04_PGRAPH_VALID1,
+ NV04_PGRAPH_VALID2
};
@@ -290,43 +349,35 @@ struct reg_interval
void nouveau_nv04_context_switch(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- int channel, channel_old, i, j, index;
+ struct nouveau_channel *next, *last;
+ int chid;
+
+ chid = NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1);
+ next = dev_priv->fifos[chid];
- 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);
+ chid = (NV_READ(NV04_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1);
+ last = dev_priv->fifos[chid];
- DRM_DEBUG("NV: PGRAPH context switch interrupt channel %x -> %x\n",channel_old, channel);
+ DRM_DEBUG("NV: PGRAPH context switch interrupt channel %x -> %x\n",last->id, next->id);
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);
+ nv04_graph_save_context(last);
- // save PGRAPH context
- 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++)
- {
- dev_priv->fifos[channel_old]->pgraph_ctx[index] = NV_READ(nv04_graph_ctx_regs[i].reg+j*4);
- 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));
- // restore PGRAPH context
- 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++)
- {
- NV_WRITE(nv04_graph_ctx_regs[i].reg+j*4, dev_priv->fifos[channel]->pgraph_ctx[index]);
- index++;
- }
+ nouveau_wait_for_idle(dev);
+
+ nv04_graph_load_context(last);
NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10010100);
- NV_WRITE(NV04_PGRAPH_CTX_USER, channel << 24);
+ NV_WRITE(NV04_PGRAPH_CTX_USER, next->id << 24);
NV_WRITE(NV04_PGRAPH_FFINTFC_ST2, NV_READ(NV04_PGRAPH_FFINTFC_ST2)&0x000FFFFF);
NV_WRITE(NV04_PGRAPH_FIFO,0x0);
@@ -336,14 +387,13 @@ void nouveau_nv04_context_switch(struct drm_device *dev)
NV_WRITE(NV04_PGRAPH_FIFO,0x1);
}
-int nv04_graph_create_context(struct drm_device *dev, int channel) {
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- DRM_DEBUG("nv04_graph_context_create %d\n", channel);
+int nv04_graph_create_context(struct nouveau_channel *chan) {
+ DRM_DEBUG("nv04_graph_context_create %d\n", chan->id);
- memset(dev_priv->fifos[channel]->pgraph_ctx, 0, sizeof(dev_priv->fifos[channel]->pgraph_ctx));
+ memset(chan->pgraph_ctx, 0, sizeof(chan->pgraph_ctx));
//dev_priv->fifos[channel].pgraph_ctx_user = channel << 24;
- dev_priv->fifos[channel]->pgraph_ctx[0] = 0x0001ffff;
+ chan->pgraph_ctx[0] = 0x0001ffff;
/* is it really needed ??? */
//dev_priv->fifos[channel].pgraph_ctx[1] = NV_READ(NV_PGRAPH_DEBUG_4);
//dev_priv->fifos[channel].pgraph_ctx[2] = NV_READ(0x004006b0);
@@ -351,49 +401,60 @@ int nv04_graph_create_context(struct drm_device *dev, int channel) {
return 0;
}
-void nv04_graph_destroy_context(struct drm_device *dev, int channel)
+void nv04_graph_destroy_context(struct nouveau_channel *chan)
{
}
-int nv04_graph_load_context(struct drm_device *dev, int channel)
+int nv04_graph_load_context(struct nouveau_channel *chan)
{
- DRM_ERROR("stub!\n");
+ struct drm_device *dev = chan->dev;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ int i;
+
+ for (i = 0; i < sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0]); i++)
+ NV_WRITE(nv04_graph_ctx_regs[i], chan->pgraph_ctx[i]);
+
return 0;
}
-int nv04_graph_save_context(struct drm_device *dev, int channel)
+int nv04_graph_save_context(struct nouveau_channel *chan)
{
- DRM_ERROR("stub!\n");
+ struct drm_device *dev = chan->dev;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ int i;
+
+ for (i = 0; i < sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0]); i++)
+ chan->pgraph_ctx[i] = NV_READ(nv04_graph_ctx_regs[i]);
+
return 0;
}
int nv04_graph_init(struct drm_device *dev) {
struct drm_nouveau_private *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);
+ /* Enable PGRAPH interrupts */
+ NV_WRITE(NV03_PGRAPH_INTR, 0xFFFFFFFF);
+ NV_WRITE(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
+
// check the context is big enough
- 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) )
+ if ( sizeof(nv04_graph_ctx_regs)>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_0, 0x1231c000);
+ NV_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);
+ NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x11d5f870);
NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x0004FF31);
NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x4004FF31 |
(0x00D00000) |
(1<<29) |
(1<<31));
+ NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xfad4ff31);
NV_WRITE(NV04_PGRAPH_STATE , 0xFFFFFFFF);
NV_WRITE(NV04_PGRAPH_CTX_CONTROL , 0x10010100);
diff --git a/shared-core/nv04_instmem.c b/shared-core/nv04_instmem.c
index 35b20abd..5a446450 100644
--- a/shared-core/nv04_instmem.c
+++ b/shared-core/nv04_instmem.c
@@ -9,21 +9,18 @@ nv04_instmem_determine_amount(struct drm_device *dev)
int i;
/* Figure out how much instance memory we need */
- switch (dev_priv->card_type) {
- case NV_40:
+ if (dev_priv->card_type >= 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_rsvd_vram = (1*1024* 1024);
- break;
- default:
+ } else {
/*XXX: what *are* the limits on <NV40 cards?, and does RAMIN
* exist in vram on those cards as well?
*/
dev_priv->ramin_rsvd_vram = (512*1024);
- break;
}
DRM_DEBUG("RAMIN size: %dKiB\n", dev_priv->ramin_rsvd_vram>>10);
@@ -73,7 +70,6 @@ nv04_instmem_configure_fixed_tables(struct drm_device *dev)
case NV_11:
case NV_10:
case NV_04:
- case NV_03:
default:
dev_priv->ramfc_offset = 0x11400;
dev_priv->ramfc_size = nouveau_fifo_number(dev) *
@@ -93,17 +89,18 @@ int nv04_instmem_init(struct drm_device *dev)
nv04_instmem_determine_amount(dev);
nv04_instmem_configure_fixed_tables(dev);
- if ((ret = nouveau_gpuobj_new_fake(dev, dev_priv->ramht_offset,
- dev_priv->ramht_size,
- NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ALLOW_NO_REFS,
- &dev_priv->ramht, NULL)))
- return ret;
-
/* Create a heap to manage RAMIN allocations, we don't allocate
* the space that was reserved for RAMHT/FC/RO.
*/
offset = dev_priv->ramfc_offset + dev_priv->ramfc_size;
+
+ /* On my NV4E, there's *something* clobbering the 16KiB just after
+ * where we setup these fixed tables. No idea what it is just yet,
+ * so reserve this space on all NV4X cards for now.
+ */
+ if (dev_priv->card_type >= NV_40)
+ offset += 16*1024;
+
ret = nouveau_mem_init_heap(&dev_priv->ramin_heap,
offset, dev_priv->ramin_rsvd_vram - offset);
if (ret) {
@@ -117,9 +114,6 @@ int nv04_instmem_init(struct drm_device *dev)
void
nv04_instmem_takedown(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- nouveau_gpuobj_del(dev, &dev_priv->ramht);
}
int
@@ -139,7 +133,6 @@ nv04_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
if (gpuobj && gpuobj->im_backing) {
if (gpuobj->im_bound)
dev_priv->Engine.instmem.unbind(dev, gpuobj);
- nouveau_mem_free(dev, gpuobj->im_backing);
gpuobj->im_backing = NULL;
}
}
diff --git a/shared-core/nv04_mc.c b/shared-core/nv04_mc.c
index 1d998851..eee0c50c 100644
--- a/shared-core/nv04_mc.c
+++ b/shared-core/nv04_mc.c
@@ -13,8 +13,6 @@ nv04_mc_init(struct drm_device *dev)
*/
NV_WRITE(NV03_PMC_ENABLE, 0xFFFFFFFF);
- NV_WRITE(NV03_PMC_INTR_EN_0, 0);
-
return 0;
}
diff --git a/shared-core/nv10_fifo.c b/shared-core/nv10_fifo.c
index 7b9c665b..c86725d2 100644
--- a/shared-core/nv10_fifo.c
+++ b/shared-core/nv10_fifo.c
@@ -33,17 +33,17 @@
NV10_RAMFC_##offset/4, (val))
#define RAMFC_RD(offset) INSTANCE_RD(chan->ramfc->gpuobj, \
NV10_RAMFC_##offset/4)
-#define NV10_RAMFC(c) (dev_priv->ramfc_offset + NV10_RAMFC__SIZE)
+#define NV10_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV10_RAMFC__SIZE))
#define NV10_RAMFC__SIZE ((dev_priv->chipset) >= 0x17 ? 64 : 32)
int
-nv10_fifo_create_context(struct drm_device *dev, int channel)
+nv10_fifo_create_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
int ret;
- if ((ret = nouveau_gpuobj_new_fake(dev, NV10_RAMFC(channel),
+ if ((ret = nouveau_gpuobj_new_fake(dev, NV10_RAMFC(chan->id), ~0,
NV10_RAMFC__SIZE,
NVOBJ_FLAG_ZERO_ALLOC |
NVOBJ_FLAG_ZERO_FREE,
@@ -65,30 +65,29 @@ nv10_fifo_create_context(struct drm_device *dev, int channel)
0);
/* enable the fifo dma operation */
- NV_WRITE(NV04_PFIFO_MODE,NV_READ(NV04_PFIFO_MODE)|(1<<channel));
+ NV_WRITE(NV04_PFIFO_MODE,NV_READ(NV04_PFIFO_MODE)|(1<<chan->id));
return 0;
}
void
-nv10_fifo_destroy_context(struct drm_device *dev, int channel)
+nv10_fifo_destroy_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
- NV_WRITE(NV04_PFIFO_MODE, NV_READ(NV04_PFIFO_MODE)&~(1<<channel));
+ NV_WRITE(NV04_PFIFO_MODE, NV_READ(NV04_PFIFO_MODE)&~(1<<chan->id));
- if (chan->ramfc)
- nouveau_gpuobj_ref_del(dev, &chan->ramfc);
+ nouveau_gpuobj_ref_del(dev, &chan->ramfc);
}
int
-nv10_fifo_load_context(struct drm_device *dev, int channel)
+nv10_fifo_load_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
uint32_t tmp;
- NV_WRITE(NV03_PFIFO_CACHE1_PUSH1 , 0x00000100 | channel);
+ NV_WRITE(NV03_PFIFO_CACHE1_PUSH1 , 0x00000100 | chan->id);
NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET , RAMFC_RD(DMA_GET));
NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUT , RAMFC_RD(DMA_PUT));
@@ -124,10 +123,10 @@ nv10_fifo_load_context(struct drm_device *dev, int channel)
}
int
-nv10_fifo_save_context(struct drm_device *dev, int channel)
+nv10_fifo_save_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
uint32_t tmp;
RAMFC_WR(DMA_PUT , NV_READ(NV04_PFIFO_CACHE1_DMA_PUT));
diff --git a/shared-core/nv10_graph.c b/shared-core/nv10_graph.c
index 930fcbdf..e470ff06 100644
--- a/shared-core/nv10_graph.c
+++ b/shared-core/nv10_graph.c
@@ -181,11 +181,7 @@ static void nv10_praph_pipe(struct drm_device *dev) {
nouveau_wait_for_idle(dev);
}
-/* TODO replace address with name
- use loops */
static int nv10_graph_ctx_regs [] = {
-NV03_PGRAPH_XY_LOGIC_MISC0,
-
NV10_PGRAPH_CTX_SWITCH1,
NV10_PGRAPH_CTX_SWITCH2,
NV10_PGRAPH_CTX_SWITCH3,
@@ -455,6 +451,7 @@ NV03_PGRAPH_ABS_UCLIPA_YMIN,
NV03_PGRAPH_ABS_UCLIPA_YMAX,
NV03_PGRAPH_ABS_ICLIP_XMAX,
NV03_PGRAPH_ABS_ICLIP_YMAX,
+NV03_PGRAPH_XY_LOGIC_MISC0,
NV03_PGRAPH_XY_LOGIC_MISC1,
NV03_PGRAPH_XY_LOGIC_MISC2,
NV03_PGRAPH_XY_LOGIC_MISC3,
@@ -544,82 +541,115 @@ static int nv10_graph_ctx_regs_find_offset(struct drm_device *dev, int reg)
return -1;
}
-static void restore_ctx_regs(struct drm_device *dev, int channel)
+int nv10_graph_load_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *fifo = dev_priv->fifos[channel];
int i, j;
+
for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++)
- NV_WRITE(nv10_graph_ctx_regs[i], fifo->pgraph_ctx[i]);
+ NV_WRITE(nv10_graph_ctx_regs[i], chan->pgraph_ctx[i]);
if (dev_priv->chipset>=0x17) {
for (j = 0; j < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++,j++)
- NV_WRITE(nv17_graph_ctx_regs[j], fifo->pgraph_ctx[i]);
+ NV_WRITE(nv17_graph_ctx_regs[j], chan->pgraph_ctx[i]);
}
- nouveau_wait_for_idle(dev);
+ NV_WRITE(NV10_PGRAPH_CTX_USER, chan->id << 24);
+
+ return 0;
}
-void nouveau_nv10_context_switch(struct drm_device *dev)
+int nv10_graph_save_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- int channel, channel_old, i, j;
-
- channel=NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1);
- channel_old = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1);
-
- DRM_INFO("NV: PGRAPH context switch interrupt channel %x -> %x\n",channel_old, channel);
-
- NV_WRITE(NV04_PGRAPH_FIFO,0x0);
-#if 0
- NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000000);
- NV_WRITE(NV_PFIFO_CACH1_PUL1, 0x00000000);
- NV_WRITE(NV_PFIFO_CACHES, 0x00000000);
-#endif
+ int i, j;
- // save PGRAPH context
for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++)
- dev_priv->fifos[channel_old]->pgraph_ctx[i] = NV_READ(nv10_graph_ctx_regs[i]);
+ chan->pgraph_ctx[i] = NV_READ(nv10_graph_ctx_regs[i]);
if (dev_priv->chipset>=0x17) {
for (j = 0; j < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++,j++)
- dev_priv->fifos[channel_old]->pgraph_ctx[i] = NV_READ(nv17_graph_ctx_regs[j]);
+ chan->pgraph_ctx[i] = NV_READ(nv17_graph_ctx_regs[j]);
}
-
+
+ return 0;
+}
+
+void nouveau_nv10_context_switch(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv;
+ struct nouveau_channel *next, *last;
+ int chid;
+
+ if (!dev) {
+ DRM_DEBUG("Invalid drm_device\n");
+ return;
+ }
+ dev_priv = dev->dev_private;
+ if (!dev_priv) {
+ DRM_DEBUG("Invalid drm_nouveau_private\n");
+ return;
+ }
+ if (!dev_priv->fifos) {
+ DRM_DEBUG("Invalid drm_nouveau_private->fifos\n");
+ return;
+ }
+
+ chid = (NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 20)&(nouveau_fifo_number(dev)-1);
+ next = dev_priv->fifos[chid];
+
+ if (!next) {
+ DRM_DEBUG("Invalid next channel\n");
+ return;
+ }
+
+ chid = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1);
+ last = dev_priv->fifos[chid];
+
+ if (!last) {
+ DRM_DEBUG("WARNING: Invalid last channel, switch to %x\n",
+ next->id);
+ } else {
+ DRM_INFO("NV: PGRAPH context switch interrupt channel %x -> %x\n",
+ last->id, next->id);
+ }
+
+ NV_WRITE(NV04_PGRAPH_FIFO,0x0);
+ if (last) {
+ nv10_graph_save_context(last);
+ }
+
nouveau_wait_for_idle(dev);
NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10000000);
NV_WRITE(NV10_PGRAPH_CTX_USER, (NV_READ(NV10_PGRAPH_CTX_USER) & 0xffffff) | (0x1f << 24));
nouveau_wait_for_idle(dev);
- // restore PGRAPH context
-#if 1
- restore_ctx_regs(dev, channel);
-#endif
-
+
+ nv10_graph_load_context(next);
+
NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10010100);
- NV_WRITE(NV10_PGRAPH_CTX_USER, channel << 24);
+ //NV_WRITE(NV10_PGRAPH_CTX_USER, next->id << 24);
NV_WRITE(NV10_PGRAPH_FFINTFC_ST2, NV_READ(NV10_PGRAPH_FFINTFC_ST2)&0xCFFFFFFF);
-
-#if 0
- NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000001);
- NV_WRITE(NV_PFIFO_CACH1_PUL1, 0x00000001);
- NV_WRITE(NV_PFIFO_CACHES, 0x00000001);
-#endif
NV_WRITE(NV04_PGRAPH_FIFO,0x1);
}
#define NV_WRITE_CTX(reg, val) do { \
int offset = nv10_graph_ctx_regs_find_offset(dev, reg); \
if (offset > 0) \
- fifo->pgraph_ctx[offset] = val; \
+ chan->pgraph_ctx[offset] = val; \
} while (0)
-int nv10_graph_create_context(struct drm_device *dev, int channel) {
+
+int nv10_graph_create_context(struct nouveau_channel *chan) {
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *fifo = dev_priv->fifos[channel];
- uint32_t tmp, vramsz;
- DRM_DEBUG("nv10_graph_context_create %d\n", channel);
+ DRM_DEBUG("nv10_graph_context_create %d\n", chan->id);
- memset(fifo->pgraph_ctx, 0, sizeof(fifo->pgraph_ctx));
+ memset(chan->pgraph_ctx, 0, sizeof(chan->pgraph_ctx));
+ /* mmio trace suggest that should be done in ddx with methods/objects */
+#if 0
+ uint32_t tmp, vramsz;
/* per channel init from ddx */
tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00;
/*XXX the original ddx code, does this in 2 steps :
@@ -644,17 +674,28 @@ int nv10_graph_create_context(struct drm_device *dev, int channel) {
NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_YMIN, 0);
NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff);
NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff);
+#endif
+ NV_WRITE_CTX(0x00400e88, 0x08000000);
+ NV_WRITE_CTX(0x00400e9c, 0x4b7fffff);
NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff);
- /* is it really needed ??? */
+ NV_WRITE_CTX(0x00400e10, 0x00001000);
+ NV_WRITE_CTX(0x00400e14, 0x00001000);
+ NV_WRITE_CTX(0x00400e30, 0x00080008);
+ NV_WRITE_CTX(0x00400e34, 0x00080008);
if (dev_priv->chipset>=0x17) {
+ /* is it really needed ??? */
NV_WRITE_CTX(NV10_PGRAPH_DEBUG_4, NV_READ(NV10_PGRAPH_DEBUG_4));
NV_WRITE_CTX(0x004006b0, NV_READ(0x004006b0));
+ NV_WRITE_CTX(0x00400eac, 0x0fff0000);
+ NV_WRITE_CTX(0x00400eb0, 0x0fff0000);
+ NV_WRITE_CTX(0x00400ec0, 0x00000080);
+ NV_WRITE_CTX(0x00400ed0, 0x00000080);
}
/* for the first channel init the regs */
if (dev_priv->fifo_alloc_count == 0)
- restore_ctx_regs(dev, channel);
+ nv10_graph_load_context(chan);
//XXX should be saved/restored for each fifo
@@ -663,20 +704,25 @@ int nv10_graph_create_context(struct drm_device *dev, int channel) {
return 0;
}
-void nv10_graph_destroy_context(struct drm_device *dev, int channel)
-{
-}
-
-int nv10_graph_load_context(struct drm_device *dev, int channel)
+void nv10_graph_destroy_context(struct nouveau_channel *chan)
{
- DRM_ERROR("stub!\n");
- return 0;
-}
+ struct drm_device *dev = chan->dev;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ int chid;
+ chid = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1);
-int nv10_graph_save_context(struct drm_device *dev, int channel)
-{
- DRM_ERROR("stub!\n");
- return 0;
+ /* does this avoid a potential context switch while we are written graph
+ * reg, or we should mask graph interrupt ???
+ */
+ NV_WRITE(NV04_PGRAPH_FIFO,0x0);
+ if (chid == chan->id) {
+ DRM_INFO("cleanning a channel with graph in current context\n");
+ nouveau_wait_for_idle(dev);
+ DRM_INFO("reseting current graph context\n");
+ nv10_graph_create_context(chan);
+ nv10_graph_load_context(chan);
+ }
+ NV_WRITE(NV04_PGRAPH_FIFO,0x1);
}
int nv10_graph_init(struct drm_device *dev) {
@@ -688,16 +734,23 @@ int nv10_graph_init(struct drm_device *dev) {
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(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000);
NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x00118700);
- NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x24E00810);
- NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x55DE0030 |
+ //NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x24E00810); /* 0x25f92ad9 */
+ NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x25f92ad9);
+ NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x55DE0830 |
(1<<29) |
(1<<31));
+ if (dev_priv->chipset>=0x17) {
+ NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x1f000000);
+ NV_WRITE(0x004006b0, 0x40000020);
+ }
+ else
+ NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x00000000);
/* copy tile info from PFB */
for (i=0; i<NV10_PFB_TILE__SIZE; i++) {
@@ -707,6 +760,10 @@ int nv10_graph_init(struct drm_device *dev) {
NV_WRITE(NV10_PGRAPH_TSTATUS(i), NV_READ(NV10_PFB_TSTATUS(i)));
}
+ NV_WRITE(NV10_PGRAPH_CTX_SWITCH1, 0x00000000);
+ NV_WRITE(NV10_PGRAPH_CTX_SWITCH2, 0x00000000);
+ NV_WRITE(NV10_PGRAPH_CTX_SWITCH3, 0x00000000);
+ NV_WRITE(NV10_PGRAPH_CTX_SWITCH4, 0x00000000);
NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10010100);
NV_WRITE(NV10_PGRAPH_STATE , 0xFFFFFFFF);
NV_WRITE(NV04_PGRAPH_FIFO , 0x00000001);
diff --git a/shared-core/nv20_graph.c b/shared-core/nv20_graph.c
index 1670c527..c163daf9 100644
--- a/shared-core/nv20_graph.c
+++ b/shared-core/nv20_graph.c
@@ -29,39 +29,36 @@
#define NV20_GRCTX_SIZE (3529*4)
-int nv20_graph_create_context(struct drm_device *dev, int channel) {
- struct drm_nouveau_private *dev_priv =
- (struct drm_nouveau_private *)dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
+int nv20_graph_create_context(struct nouveau_channel *chan) {
+ struct drm_device *dev = chan->dev;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
unsigned int ctx_size = NV20_GRCTX_SIZE;
int ret;
- if ((ret = nouveau_gpuobj_new_ref(dev, channel, -1, 0, ctx_size, 16,
+ if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ctx_size, 16,
NVOBJ_FLAG_ZERO_ALLOC,
&chan->ramin_grctx)))
return ret;
/* Initialise default context values */
- INSTANCE_WR(chan->ramin_grctx->gpuobj, 10, channel<<24); /* CTX_USER */
+ INSTANCE_WR(chan->ramin_grctx->gpuobj, 10, chan->id<<24); /* CTX_USER */
- INSTANCE_WR(dev_priv->ctx_table->gpuobj, channel,
+ INSTANCE_WR(dev_priv->ctx_table->gpuobj, chan->id,
chan->ramin_grctx->instance >> 4);
return 0;
}
-void nv20_graph_destroy_context(struct drm_device *dev, int channel) {
+void nv20_graph_destroy_context(struct nouveau_channel *chan) {
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
- if (chan->ramin_grctx)
- nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
+ nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
- INSTANCE_WR(dev_priv->ctx_table->gpuobj, channel, 0);
+ INSTANCE_WR(dev_priv->ctx_table->gpuobj, chan->id, 0);
}
static void nv20_graph_rdi(struct drm_device *dev) {
- struct drm_nouveau_private *dev_priv =
- (struct drm_nouveau_private *)dev->dev_private;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
int i;
NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x2c80000);
@@ -73,13 +70,12 @@ static void nv20_graph_rdi(struct drm_device *dev) {
/* Save current context (from PGRAPH) into the channel's context
*/
-int nv20_graph_save_context(struct drm_device *dev, int channel) {
- struct drm_nouveau_private *dev_priv =
- (struct drm_nouveau_private *)dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
+int nv20_graph_save_context(struct nouveau_channel *chan) {
+ struct drm_device *dev = chan->dev;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
uint32_t instance;
- instance = INSTANCE_RD(dev_priv->ctx_table->gpuobj, channel);
+ instance = INSTANCE_RD(dev_priv->ctx_table->gpuobj, chan->id);
if (!instance) {
return -EINVAL;
}
@@ -94,20 +90,19 @@ int nv20_graph_save_context(struct drm_device *dev, int channel) {
/* Restore the context for a specific channel into PGRAPH
*/
-int nv20_graph_load_context(struct drm_device *dev, int channel) {
- struct drm_nouveau_private *dev_priv =
- (struct drm_nouveau_private *)dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
+int nv20_graph_load_context(struct nouveau_channel *chan) {
+ struct drm_device *dev = chan->dev;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
uint32_t instance;
- instance = INSTANCE_RD(dev_priv->ctx_table->gpuobj, channel);
+ instance = INSTANCE_RD(dev_priv->ctx_table->gpuobj, chan->id);
if (!instance) {
return -EINVAL;
}
if (instance != (chan->ramin_grctx->instance >> 4))
DRM_ERROR("nv20_graph_load_context_current : bad instance\n");
- NV_WRITE(NV10_PGRAPH_CTX_USER, channel << 24);
+ NV_WRITE(NV10_PGRAPH_CTX_USER, chan->id << 24);
NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_SIZE, instance);
NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_POINTER, 1 /* restore ctx */);
return 0;
@@ -116,27 +111,32 @@ int nv20_graph_load_context(struct drm_device *dev, int channel) {
void nouveau_nv20_context_switch(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- int channel, channel_old;
+ struct nouveau_channel *next, *last;
+ int chid;
+
+ chid = NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1);
+ next = dev_priv->fifos[chid];
- channel=NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1);
- channel_old = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1);
+ chid = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1);
+ last = dev_priv->fifos[chid];
- DRM_DEBUG("NV: PGRAPH context switch interrupt channel %x -> %x\n",channel_old, channel);
+ DRM_DEBUG("NV: PGRAPH context switch interrupt channel %x -> %x\n",
+ last->id, next->id);
NV_WRITE(NV04_PGRAPH_FIFO,0x0);
- nv20_graph_save_context(dev, channel_old);
+ nv20_graph_save_context(last);
nouveau_wait_for_idle(dev);
NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10000000);
- nv20_graph_load_context(dev, channel);
+ nv20_graph_load_context(next);
nouveau_wait_for_idle(dev);
- if ((NV_READ(NV10_PGRAPH_CTX_USER) >> 24) != channel)
- DRM_ERROR("nouveau_nv20_context_switch : wrong channel restored %x %x!!!\n", channel, NV_READ(NV10_PGRAPH_CTX_USER) >> 24);
+ if ((NV_READ(NV10_PGRAPH_CTX_USER) >> 24) != next->id)
+ DRM_ERROR("nouveau_nv20_context_switch : wrong channel restored %x %x!!!\n", next->id, NV_READ(NV10_PGRAPH_CTX_USER) >> 24);
NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10010100);
NV_WRITE(NV10_PGRAPH_FFINTFC_ST2, NV_READ(NV10_PGRAPH_FFINTFC_ST2)&0xCFFFFFFF);
@@ -157,7 +157,7 @@ int nv20_graph_init(struct drm_device *dev) {
/* Create Context Pointer Table */
dev_priv->ctx_table_size = 32 * 4;
- if ((ret = nouveau_gpuobj_new_ref(dev, -1, -1, 0,
+ if ((ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0,
dev_priv->ctx_table_size, 16,
NVOBJ_FLAG_ZERO_ALLOC,
&dev_priv->ctx_table)))
@@ -169,8 +169,8 @@ int nv20_graph_init(struct drm_device *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(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000);
diff --git a/shared-core/nv30_graph.c b/shared-core/nv30_graph.c
index 4ed2e2ba..ca43bb95 100644
--- a/shared-core/nv30_graph.c
+++ b/shared-core/nv30_graph.c
@@ -8,139 +8,2757 @@
#include "nouveau_drm.h"
/*
- * This is obviously not the correct size.
+ * There are 4 families :
+ * NV30 is 0x10de:0x030* (not working, no dump for that one)
+ *
+ * NV31 is 0x10de:0x031*
+ *
+ * NV34 is 0x10de:0x032*
+ *
+ * NV35 is 0x10de:0x033* (NV35 and NV36 are the same)
+ * NV36 is 0x10de:0x034*
+ *
+ * Not seen in the wild, no dumps (probably NV35) :
+ * NV37 is 0x10de:0x00fc, 0x10de:0x00fd
+ * NV38 is 0x10de:0x0333, 0x10de:0x00fe
+ *
*/
-#define NV30_GRCTX_SIZE (23840)
-/*TODO: deciper what each offset in the context represents. The below
- * contexts are taken from dumps just after the 3D object is
- * created.
- */
-static void nv30_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+
+#define NV31_GRCTX_SIZE (22392)
+#define NV34_GRCTX_SIZE (18140)
+#define NV35_GRCTX_SIZE (22396)
+
+static void nv31_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ int i;
+
+ INSTANCE_WR(ctx, 0x410/4, 0x00000101);
+ INSTANCE_WR(ctx, 0x424/4, 0x00000111);
+ INSTANCE_WR(ctx, 0x428/4, 0x00000060);
+ INSTANCE_WR(ctx, 0x444/4, 0x00000080);
+ INSTANCE_WR(ctx, 0x448/4, 0xffff0000);
+ INSTANCE_WR(ctx, 0x44c/4, 0x00000001);
+ INSTANCE_WR(ctx, 0x460/4, 0x44400000);
+ INSTANCE_WR(ctx, 0x48c/4, 0xffff0000);
+ for(i = 0x4e0; i< 0x4e8; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x0fff0000);
+ INSTANCE_WR(ctx, 0x4ec/4, 0x00011100);
+ for(i = 0x508; i< 0x548; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x07ff0000);
+ INSTANCE_WR(ctx, 0x550/4, 0x4b7fffff);
+ INSTANCE_WR(ctx, 0x58c/4, 0x00000080);
+ INSTANCE_WR(ctx, 0x590/4, 0x30201000);
+ INSTANCE_WR(ctx, 0x594/4, 0x70605040);
+ INSTANCE_WR(ctx, 0x598/4, 0xb8a89888);
+ INSTANCE_WR(ctx, 0x59c/4, 0xf8e8d8c8);
+ INSTANCE_WR(ctx, 0x5b0/4, 0xb0000000);
+ for(i = 0x600; i< 0x640; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x00010588);
+ for(i = 0x640; i< 0x680; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x00030303);
+ for(i = 0x6c0; i< 0x700; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x0008aae4);
+ for(i = 0x700; i< 0x740; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x01012000);
+ for(i = 0x740; i< 0x780; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x00080008);
+ INSTANCE_WR(ctx, 0x85c/4, 0x00040000);
+ INSTANCE_WR(ctx, 0x860/4, 0x00010000);
+ for(i = 0x864; i< 0x874; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x00040004);
+ INSTANCE_WR(ctx, 0x1f18/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f1c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f20/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f28/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f2c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f30/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f38/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f3c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f40/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f48/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f4c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f50/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f58/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f5c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f60/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f68/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f6c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f70/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f78/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f7c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f80/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f88/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f8c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f90/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f98/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f9c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1fa0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1fa8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1fac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1fb0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1fb8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1fbc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1fc0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1fc8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1fcc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1fd0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1fd8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1fdc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1fe0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1fe8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1fec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1ff0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1ff8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1ffc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2000/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2008/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x200c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2010/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2018/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x201c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2020/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2028/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x202c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2030/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2038/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x203c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2040/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2048/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x204c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2050/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2058/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x205c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2060/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2068/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x206c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2070/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2078/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x207c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2080/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2088/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x208c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2090/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2098/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x209c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20a0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20a8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20ac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20b0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20b8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20bc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20c0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20c8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20cc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20d0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20d8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20dc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20e0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20e8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20ec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20f0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20f8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20fc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2100/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2108/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x210c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2110/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2118/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x211c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2120/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2128/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x212c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2130/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2138/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x213c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2140/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2148/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x214c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2150/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2158/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x215c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2160/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2168/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x216c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2170/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2178/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x217c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2180/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2188/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x218c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2190/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2198/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x219c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21a0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21a8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21ac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21b0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21b8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21bc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21c0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21c8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21cc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21d0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21d8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21dc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21e0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21e8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21ec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21f0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21f8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21fc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2200/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2208/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x220c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2210/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2218/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x221c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2220/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2228/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x222c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2230/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2238/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x223c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2240/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2248/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x224c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2250/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2258/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x225c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2260/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2268/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x226c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2270/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2278/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x227c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2280/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2288/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x228c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2290/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2298/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x229c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22a0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22a8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22ac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22b0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22b8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22bc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22c0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22c8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22cc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22d0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22d8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22dc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22e0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22e8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22ec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22f0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22f8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22fc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2300/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2308/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x230c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2310/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2318/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x231c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2320/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2328/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x232c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2330/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2338/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x233c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2340/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2348/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x234c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2350/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2358/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x235c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2360/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2368/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x236c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2370/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2378/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x237c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2380/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2388/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x238c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2390/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2398/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x239c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23a0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23a8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23ac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23b0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23b8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23bc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23c0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23c8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23cc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23d0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23d8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23dc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23e0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23e8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23ec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23f0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23f8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23fc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2400/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2408/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x240c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2410/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2418/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x241c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2420/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2428/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x242c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2430/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2438/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x243c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2440/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2448/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x244c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2450/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2458/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x245c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2460/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2468/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x246c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2470/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2478/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x247c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2480/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2488/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x248c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2490/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2498/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x249c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24a0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24a8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24ac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24b0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24b8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24bc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24c0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24c8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24cc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24d0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24d8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24dc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24e0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24e8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24ec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24f0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24f8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24fc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2500/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2508/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x250c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2510/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2518/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x251c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2520/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2528/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x252c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2530/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2538/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x253c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2540/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2548/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x254c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2550/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2558/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x255c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2560/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2568/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x256c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2570/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2578/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x257c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2580/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2588/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x258c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2590/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2598/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x259c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25a0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25a8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25ac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25b0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25b8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25bc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25c0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25c8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25cc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25d0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25d8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25dc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25e0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25e8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25ec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25f0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25f8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25fc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2600/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2608/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x260c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2610/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2618/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x261c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2620/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2628/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x262c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2630/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2638/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x263c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2640/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2648/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x264c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2650/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2658/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x265c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2660/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2668/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x266c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2670/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2678/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x267c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2680/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2688/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x268c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2690/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2698/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x269c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26a0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26a8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26ac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26b0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26b8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26bc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26c0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26c8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26cc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26d0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26d8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26dc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26e0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26e8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26ec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26f0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26f8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26fc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2700/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2708/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x270c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2710/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2718/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x271c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2720/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2728/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x272c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2730/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2738/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x273c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2740/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2748/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x274c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2750/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2758/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x275c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2760/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2768/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x276c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2770/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2778/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x277c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2780/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2788/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x278c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2790/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2798/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x279c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x27a0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x27a8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x27ac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x27b0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x27b8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x27bc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x27c0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x27c8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x27cc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x27d0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x27d8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x27dc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x27e0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x27e8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x27ec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x27f0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x27f8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x27fc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2800/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2808/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x280c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2810/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2818/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x281c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2820/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2828/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x282c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2830/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2838/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x283c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2840/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2848/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x284c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2850/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2858/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x285c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2860/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2868/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x286c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2870/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2878/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x287c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2880/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2888/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x288c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2890/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2898/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x289c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x28a0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x28a8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x28ac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x28b0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x28b8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x28bc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x28c0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x28c8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x28cc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x28d0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x28d8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x28dc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x28e0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x28e8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x28ec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x28f0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x28f8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x28fc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2900/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2908/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x290c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2910/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2918/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x291c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2920/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2928/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x292c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2930/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2938/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x293c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2940/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2948/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x294c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2950/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2958/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x295c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2960/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2968/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x296c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2970/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2978/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x297c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2980/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2988/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x298c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2990/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2998/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x299c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x29a0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x29a8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x29ac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x29b0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x29b8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x29bc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x29c0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x29c8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x29cc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x29d0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x29d8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x29dc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x29e0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x29e8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x29ec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x29f0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x29f8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x29fc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a00/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a08/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a0c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a10/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a18/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a1c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a20/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a28/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a2c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a30/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a38/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a3c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a40/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a48/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a4c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a50/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a58/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a5c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a60/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a68/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a6c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a70/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a78/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a7c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a80/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a88/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a8c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a90/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a98/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a9c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2aa0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2aa8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2aac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ab0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ab8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2abc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ac0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ac8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2acc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ad0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ad8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2adc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ae0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ae8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2aec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2af0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2af8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2afc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b00/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b08/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b0c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b10/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b18/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b1c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b20/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b28/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b2c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b30/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b38/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b3c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b40/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b48/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b4c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b50/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b58/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b5c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b60/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b68/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b6c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b70/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b78/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b7c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b80/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b88/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b8c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b90/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b98/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b9c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ba0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ba8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2bac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2bb0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2bb8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2bbc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2bc0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2bc8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2bcc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2bd0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2bd8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2bdc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2be0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2be8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2bec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2bf0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2bf8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2bfc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c00/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c08/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c0c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c10/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c18/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c1c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c20/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c28/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c2c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c30/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c38/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c3c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c40/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c48/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c4c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c50/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c58/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c5c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c60/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c68/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c6c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c70/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c78/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c7c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c80/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c88/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c8c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c90/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c98/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c9c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ca0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ca8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2cac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2cb0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2cb8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2cbc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2cc0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2cc8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ccc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2cd0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2cd8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2cdc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ce0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ce8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2cec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2cf0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2cf8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2cfc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d00/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d08/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d0c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d10/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d18/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d1c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d20/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d28/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d2c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d30/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d38/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d3c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d40/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d48/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d4c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d50/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d58/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d5c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d60/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d68/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d6c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d70/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d78/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d7c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d80/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d88/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d8c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d90/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d98/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d9c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2da0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2da8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2dac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2db0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2db8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2dbc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2dc0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2dc8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2dcc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2dd0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2dd8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ddc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2de0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2de8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2dec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2df0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2df8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2dfc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e00/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e08/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e0c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e10/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e18/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e1c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e20/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e28/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e2c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e30/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e38/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e3c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e40/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e48/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e4c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e50/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e58/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e5c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e60/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e68/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e6c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e70/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e78/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e7c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e80/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e88/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e8c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e90/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e98/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e9c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ea0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ea8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2eac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2eb0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2eb8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ebc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ec0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ec8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ecc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ed0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ed8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2edc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ee0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ee8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2eec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ef0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ef8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2efc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f00/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f08/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f0c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f10/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f18/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f1c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f20/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f28/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f2c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f30/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f38/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f3c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f40/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f48/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f4c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f50/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f58/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f5c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f60/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f68/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f6c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f70/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f78/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f7c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f80/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f88/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f8c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f90/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f98/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f9c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2fa0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2fa8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2fac/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2fb0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2fb8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2fbc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2fc0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2fc8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2fcc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2fd0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2fd8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2fdc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2fe0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2fe8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2fec/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ff0/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ff8/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ffc/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3000/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x3008/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x300c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3010/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x3018/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x301c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3020/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x3028/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x302c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3030/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x3038/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x303c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3040/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x3048/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x304c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3050/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x3058/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x305c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3060/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x3068/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x306c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3070/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x3078/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x307c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3080/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x3088/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x308c/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3090/4, 0x000c001b);
+ for(i = 0x30b8; i< 0x30c8; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x0000ffff);
+ INSTANCE_WR(ctx, 0x344c/4, 0x3f800000);
+ INSTANCE_WR(ctx, 0x3808/4, 0x3f800000);
+ INSTANCE_WR(ctx, 0x381c/4, 0x3f800000);
+ INSTANCE_WR(ctx, 0x3848/4, 0x40000000);
+ INSTANCE_WR(ctx, 0x384c/4, 0x3f800000);
+ INSTANCE_WR(ctx, 0x3850/4, 0x3f000000);
+ INSTANCE_WR(ctx, 0x3858/4, 0x40000000);
+ INSTANCE_WR(ctx, 0x385c/4, 0x3f800000);
+ INSTANCE_WR(ctx, 0x3864/4, 0xbf800000);
+ INSTANCE_WR(ctx, 0x386c/4, 0xbf800000);}
+
+static void nv34_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
int i;
-
- INSTANCE_WR(ctx, 0x28/4, 0x10000000);
- INSTANCE_WR(ctx, 0x40c/4, 0x00000101);
- INSTANCE_WR(ctx, 0x420/4, 0x00000111);
- INSTANCE_WR(ctx, 0x424/4, 0x00000060);
- INSTANCE_WR(ctx, 0x440/4, 0x00000080);
- INSTANCE_WR(ctx, 0x444/4, 0xffff0000);
- INSTANCE_WR(ctx, 0x448/4, 0x00000001);
- INSTANCE_WR(ctx, 0x45c/4, 0x44400000);
- INSTANCE_WR(ctx, 0x448/4, 0xffff0000);
- INSTANCE_WR(ctx, 0x4dc/4, 0xfff00000);
- INSTANCE_WR(ctx, 0x4e0/4, 0xfff00000);
- INSTANCE_WR(ctx, 0x4e8/4, 0x00011100);
-
- for (i = 0x504; i <= 0x540; i += 4)
- INSTANCE_WR(ctx, i/4, 0x7ff00000);
-
- INSTANCE_WR(ctx, 0x54c/4, 0x4b7fffff);
- INSTANCE_WR(ctx, 0x588/4, 0x00000080);
- INSTANCE_WR(ctx, 0x58c/4, 0x30201000);
- INSTANCE_WR(ctx, 0x590/4, 0x70605040);
- INSTANCE_WR(ctx, 0x594/4, 0xb8a89888);
- INSTANCE_WR(ctx, 0x598/4, 0xf8e8d8c8);
- INSTANCE_WR(ctx, 0x5ac/4, 0xb0000000);
-
- for (i = 0x604; i <= 0x640; i += 4)
- INSTANCE_WR(ctx, i/4, 0x00010588);
-
- for (i = 0x644; i <= 0x680; i += 4)
- INSTANCE_WR(ctx, i/4, 0x00030303);
-
- for (i = 0x6c4; i <= 0x700; i += 4)
- INSTANCE_WR(ctx, i/4, 0x0008aae4);
-
- for (i = 0x704; i <= 0x740; i += 4)
- INSTANCE_WR(ctx, i/4, 0x1012000);
-
- for (i = 0x744; i <= 0x780; i += 4)
- INSTANCE_WR(ctx, i/4, 0x0080008);
-
- INSTANCE_WR(ctx, 0x860/4, 0x00040000);
- INSTANCE_WR(ctx, 0x864/4, 0x00010000);
- INSTANCE_WR(ctx, 0x868/4, 0x00040000);
- INSTANCE_WR(ctx, 0x86c/4, 0x00040000);
- INSTANCE_WR(ctx, 0x870/4, 0x00040000);
- INSTANCE_WR(ctx, 0x874/4, 0x00040000);
-
- for (i = 0x00; i <= 0x1170; i += 0x10)
- {
- INSTANCE_WR(ctx, (0x1f24 + i)/4, 0x000c001b);
- INSTANCE_WR(ctx, (0x1f20 + i)/4, 0x0436086c);
- INSTANCE_WR(ctx, (0x1f1c + i)/4, 0x10700ff9);
- }
-
- INSTANCE_WR(ctx, 0x30bc/4, 0x0000ffff);
- INSTANCE_WR(ctx, 0x30c0/4, 0x0000ffff);
- INSTANCE_WR(ctx, 0x30c4/4, 0x0000ffff);
- INSTANCE_WR(ctx, 0x30c8/4, 0x0000ffff);
-
- INSTANCE_WR(ctx, 0x380c/4, 0x3f800000);
- INSTANCE_WR(ctx, 0x3450/4, 0x3f800000);
- INSTANCE_WR(ctx, 0x3820/4, 0x3f800000);
- INSTANCE_WR(ctx, 0x3854/4, 0x3f800000);
- INSTANCE_WR(ctx, 0x3850/4, 0x3f000000);
- INSTANCE_WR(ctx, 0x384c/4, 0x40000000);
- INSTANCE_WR(ctx, 0x3868/4, 0xbf800000);
- INSTANCE_WR(ctx, 0x3860/4, 0x3f800000);
- INSTANCE_WR(ctx, 0x386c/4, 0x40000000);
- INSTANCE_WR(ctx, 0x3870/4, 0xbf800000);
-
- for (i = 0x4e0; i <= 0x4e1c; i += 4)
- INSTANCE_WR(ctx, i/4, 0x001c527d);
- INSTANCE_WR(ctx, 0x4e40, 0x001c527c);
-
- INSTANCE_WR(ctx, 0x5680/4, 0x000a0000);
- INSTANCE_WR(ctx, 0x87c/4, 0x10000000);
- INSTANCE_WR(ctx, 0x28/4, 0x10000011);
+
+ INSTANCE_WR(ctx, 0x40c/4, 0x01000101);
+ INSTANCE_WR(ctx, 0x420/4, 0x00000111);
+ INSTANCE_WR(ctx, 0x424/4, 0x00000060);
+ INSTANCE_WR(ctx, 0x440/4, 0x00000080);
+ INSTANCE_WR(ctx, 0x444/4, 0xffff0000);
+ INSTANCE_WR(ctx, 0x448/4, 0x00000001);
+ INSTANCE_WR(ctx, 0x45c/4, 0x44400000);
+ INSTANCE_WR(ctx, 0x480/4, 0xffff0000);
+ for(i = 0x4d4; i< 0x4dc; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x0fff0000);
+ INSTANCE_WR(ctx, 0x4e0/4, 0x00011100);
+ for(i = 0x4fc; i< 0x53c; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x07ff0000);
+ INSTANCE_WR(ctx, 0x544/4, 0x4b7fffff);
+ INSTANCE_WR(ctx, 0x57c/4, 0x00000080);
+ INSTANCE_WR(ctx, 0x580/4, 0x30201000);
+ INSTANCE_WR(ctx, 0x584/4, 0x70605040);
+ INSTANCE_WR(ctx, 0x588/4, 0xb8a89888);
+ INSTANCE_WR(ctx, 0x58c/4, 0xf8e8d8c8);
+ INSTANCE_WR(ctx, 0x5a0/4, 0xb0000000);
+ for(i = 0x5f0; i< 0x630; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x00010588);
+ for(i = 0x630; i< 0x670; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x00030303);
+ for(i = 0x6b0; i< 0x6f0; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x0008aae4);
+ for(i = 0x6f0; i< 0x730; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x01012000);
+ for(i = 0x730; i< 0x770; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x00080008);
+ INSTANCE_WR(ctx, 0x850/4, 0x00040000);
+ INSTANCE_WR(ctx, 0x854/4, 0x00010000);
+ for(i = 0x858; i< 0x868; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x00040004);
+ INSTANCE_WR(ctx, 0x15ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x15b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x15b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x15bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x15c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x15c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x15cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x15d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x15d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x15dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x15e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x15e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x15ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x15f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x15f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x15fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1600/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1604/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x160c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1610/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1614/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x161c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1620/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1624/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x162c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1630/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1634/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x163c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1640/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1644/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x164c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1650/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1654/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x165c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1660/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1664/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x166c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1670/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1674/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x167c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1680/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1684/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x168c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1690/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1694/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x169c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x16a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x16a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x16ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x16b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x16b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x16bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x16c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x16c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x16cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x16d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x16d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x16dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x16e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x16e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x16ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x16f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x16f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x16fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1700/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1704/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x170c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1710/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1714/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x171c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1720/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1724/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x172c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1730/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1734/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x173c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1740/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1744/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x174c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1750/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1754/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x175c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1760/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1764/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x176c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1770/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1774/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x177c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1780/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1784/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x178c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1790/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1794/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x179c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x17a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x17a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x17ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x17b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x17b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x17bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x17c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x17c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x17cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x17d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x17d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x17dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x17e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x17e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x17ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x17f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x17f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x17fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1800/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1804/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x180c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1810/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1814/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x181c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1820/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1824/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x182c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1830/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1834/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x183c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1840/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1844/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x184c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1850/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1854/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x185c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1860/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1864/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x186c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1870/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1874/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x187c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1880/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1884/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x188c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1890/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1894/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x189c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x18a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x18a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x18ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x18b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x18b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x18bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x18c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x18c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x18cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x18d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x18d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x18dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x18e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x18e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x18ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x18f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x18f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x18fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1900/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1904/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x190c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1910/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1914/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x191c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1920/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1924/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x192c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1930/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1934/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x193c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1940/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1944/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x194c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1950/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1954/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x195c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1960/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1964/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x196c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1970/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1974/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x197c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1980/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1984/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x198c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1990/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1994/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x199c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x19a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x19a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x19ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x19b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x19b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x19bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x19c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x19c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x19cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x19d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x19d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x19dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x19e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x19e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x19ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x19f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x19f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x19fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1a00/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1a04/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1a0c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1a10/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1a14/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1a1c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1a20/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1a24/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1a2c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1a30/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1a34/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1a3c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1a40/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1a44/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1a4c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1a50/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1a54/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1a5c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1a60/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1a64/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1a6c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1a70/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1a74/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1a7c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1a80/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1a84/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1a8c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1a90/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1a94/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1a9c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1aa0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1aa4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1aac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1ab0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1ab4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1abc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1ac0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1ac4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1acc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1ad0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1ad4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1adc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1ae0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1ae4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1aec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1af0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1af4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1afc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1b00/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1b04/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1b0c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1b10/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1b14/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1b1c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1b20/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1b24/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1b2c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1b30/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1b34/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1b3c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1b40/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1b44/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1b4c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1b50/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1b54/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1b5c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1b60/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1b64/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1b6c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1b70/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1b74/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1b7c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1b80/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1b84/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1b8c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1b90/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1b94/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1b9c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1ba0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1ba4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1bac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1bb0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1bb4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1bbc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1bc0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1bc4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1bcc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1bd0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1bd4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1bdc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1be0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1be4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1bec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1bf0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1bf4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1bfc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1c00/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1c04/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1c0c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1c10/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1c14/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1c1c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1c20/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1c24/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1c2c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1c30/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1c34/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1c3c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1c40/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1c44/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1c4c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1c50/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1c54/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1c5c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1c60/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1c64/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1c6c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1c70/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1c74/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1c7c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1c80/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1c84/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1c8c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1c90/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1c94/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1c9c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1ca0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1ca4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1cac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1cb0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1cb4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1cbc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1cc0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1cc4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1ccc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1cd0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1cd4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1cdc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1ce0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1ce4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1cec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1cf0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1cf4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1cfc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1d00/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1d04/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1d0c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1d10/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1d14/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1d1c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1d20/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1d24/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1d2c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1d30/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1d34/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1d3c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1d40/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1d44/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1d4c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1d50/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1d54/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1d5c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1d60/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1d64/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1d6c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1d70/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1d74/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1d7c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1d80/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1d84/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1d8c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1d90/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1d94/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1d9c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1da0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1da4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1dac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1db0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1db4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1dbc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1dc0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1dc4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1dcc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1dd0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1dd4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1ddc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1de0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1de4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1dec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1df0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1df4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1dfc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1e00/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1e04/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1e0c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1e10/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1e14/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1e1c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1e20/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1e24/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1e2c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1e30/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1e34/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1e3c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1e40/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1e44/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1e4c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1e50/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1e54/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1e5c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1e60/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1e64/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1e6c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1e70/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1e74/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1e7c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1e80/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1e84/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1e8c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1e90/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1e94/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1e9c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1ea0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1ea4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1eac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1eb0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1eb4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1ebc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1ec0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1ec4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1ecc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1ed0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1ed4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1edc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1ee0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1ee4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1eec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1ef0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1ef4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1efc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f00/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f04/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f0c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f10/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f14/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f1c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f20/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f24/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f2c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f30/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f34/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f3c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f40/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f44/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f4c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f50/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f54/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f5c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f60/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f64/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f6c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f70/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f74/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f7c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f80/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f84/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f8c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f90/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f94/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f9c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1fa0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1fa4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1fac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1fb0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1fb4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1fbc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1fc0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1fc4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1fcc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1fd0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1fd4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1fdc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1fe0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1fe4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1fec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1ff0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1ff4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1ffc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2000/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2004/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x200c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2010/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2014/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x201c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2020/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2024/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x202c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2030/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2034/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x203c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2040/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2044/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x204c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2050/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2054/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x205c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2060/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2064/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x206c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2070/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2074/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x207c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2080/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2084/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x208c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2090/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2094/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x209c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2100/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2104/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x210c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2110/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2114/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x211c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2120/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2124/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x212c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2130/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2134/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x213c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2140/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2144/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x214c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2150/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2154/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x215c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2160/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2164/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x216c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2170/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2174/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x217c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2180/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2184/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x218c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2190/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2194/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x219c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2200/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2204/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x220c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2210/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2214/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x221c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2220/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2224/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x222c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2230/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2234/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x223c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2240/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2244/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x224c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2250/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2254/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x225c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2260/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2264/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x226c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2270/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2274/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x227c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2280/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2284/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x228c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2290/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2294/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x229c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2300/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2304/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x230c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2310/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2314/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x231c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2320/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2324/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x232c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2330/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2334/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x233c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2340/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2344/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x234c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2350/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2354/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x235c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2360/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2364/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x236c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2370/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2374/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x237c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2380/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2384/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x238c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2390/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2394/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x239c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2400/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2404/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x240c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2410/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2414/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x241c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2420/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2424/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x242c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2430/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2434/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x243c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2440/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2444/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x244c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2450/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2454/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x245c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2460/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2464/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x246c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2470/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2474/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x247c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2480/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2484/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x248c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2490/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2494/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x249c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2500/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2504/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x250c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2510/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2514/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x251c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2520/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2524/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x252c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2530/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2534/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x253c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2540/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2544/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x254c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2550/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2554/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x255c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2560/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2564/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x256c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2570/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2574/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x257c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2580/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2584/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x258c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2590/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2594/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x259c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2600/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2604/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x260c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2610/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2614/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x261c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2620/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2624/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x262c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2630/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2634/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x263c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2640/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2644/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x264c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2650/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2654/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x265c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2660/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2664/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x266c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2670/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2674/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x267c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2680/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2684/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x268c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2690/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2694/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x269c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2700/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2704/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x270c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2710/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2714/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x271c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2720/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2724/4, 0x000c001b);
+ for(i = 0x274c; i< 0x275c; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x0000ffff);
+ INSTANCE_WR(ctx, 0x2ae0/4, 0x3f800000);
+ INSTANCE_WR(ctx, 0x2e9c/4, 0x3f800000);
+ INSTANCE_WR(ctx, 0x2eb0/4, 0x3f800000);
+ INSTANCE_WR(ctx, 0x2edc/4, 0x40000000);
+ INSTANCE_WR(ctx, 0x2ee0/4, 0x3f800000);
+ INSTANCE_WR(ctx, 0x2ee4/4, 0x3f000000);
+ INSTANCE_WR(ctx, 0x2eec/4, 0x40000000);
+ INSTANCE_WR(ctx, 0x2ef0/4, 0x3f800000);
+ INSTANCE_WR(ctx, 0x2ef8/4, 0xbf800000);
+ INSTANCE_WR(ctx, 0x2f00/4, 0xbf800000);
}
+static void nv35_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ int i;
+
+ INSTANCE_WR(ctx, 0x40c/4, 0x00000101);
+ INSTANCE_WR(ctx, 0x420/4, 0x00000111);
+ INSTANCE_WR(ctx, 0x424/4, 0x00000060);
+ INSTANCE_WR(ctx, 0x440/4, 0x00000080);
+ INSTANCE_WR(ctx, 0x444/4, 0xffff0000);
+ INSTANCE_WR(ctx, 0x448/4, 0x00000001);
+ INSTANCE_WR(ctx, 0x45c/4, 0x44400000);
+ INSTANCE_WR(ctx, 0x488/4, 0xffff0000);
+ for(i = 0x4dc; i< 0x4e4; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x0fff0000);
+ INSTANCE_WR(ctx, 0x4e8/4, 0x00011100);
+ for(i = 0x504; i< 0x544; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x07ff0000);
+ INSTANCE_WR(ctx, 0x54c/4, 0x4b7fffff);
+ INSTANCE_WR(ctx, 0x588/4, 0x00000080);
+ INSTANCE_WR(ctx, 0x58c/4, 0x30201000);
+ INSTANCE_WR(ctx, 0x590/4, 0x70605040);
+ INSTANCE_WR(ctx, 0x594/4, 0xb8a89888);
+ INSTANCE_WR(ctx, 0x598/4, 0xf8e8d8c8);
+ INSTANCE_WR(ctx, 0x5ac/4, 0xb0000000);
+ for(i = 0x604; i< 0x644; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x00010588);
+ for(i = 0x644; i< 0x684; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x00030303);
+ for(i = 0x6c4; i< 0x704; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x0008aae4);
+ for(i = 0x704; i< 0x744; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x01012000);
+ for(i = 0x744; i< 0x784; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x00080008);
+ INSTANCE_WR(ctx, 0x860/4, 0x00040000);
+ INSTANCE_WR(ctx, 0x864/4, 0x00010000);
+ for(i = 0x868; i< 0x878; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x00040004);
+ INSTANCE_WR(ctx, 0x1f1c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f20/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f24/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f2c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f30/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f34/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f3c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f40/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f44/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f4c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f50/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f54/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f5c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f60/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f64/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f6c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f70/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f74/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f7c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f80/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f84/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f8c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1f90/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1f94/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1f9c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1fa0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1fa4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1fac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1fb0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1fb4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1fbc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1fc0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1fc4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1fcc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1fd0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1fd4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1fdc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1fe0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1fe4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1fec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x1ff0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x1ff4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x1ffc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2000/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2004/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x200c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2010/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2014/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x201c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2020/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2024/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x202c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2030/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2034/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x203c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2040/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2044/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x204c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2050/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2054/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x205c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2060/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2064/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x206c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2070/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2074/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x207c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2080/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2084/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x208c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2090/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2094/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x209c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x20f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x20f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x20fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2100/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2104/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x210c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2110/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2114/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x211c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2120/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2124/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x212c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2130/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2134/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x213c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2140/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2144/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x214c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2150/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2154/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x215c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2160/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2164/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x216c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2170/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2174/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x217c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2180/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2184/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x218c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2190/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2194/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x219c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x21f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x21f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x21fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2200/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2204/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x220c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2210/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2214/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x221c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2220/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2224/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x222c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2230/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2234/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x223c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2240/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2244/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x224c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2250/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2254/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x225c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2260/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2264/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x226c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2270/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2274/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x227c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2280/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2284/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x228c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2290/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2294/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x229c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x22f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x22f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x22fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2300/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2304/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x230c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2310/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2314/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x231c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2320/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2324/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x232c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2330/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2334/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x233c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2340/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2344/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x234c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2350/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2354/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x235c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2360/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2364/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x236c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2370/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2374/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x237c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2380/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2384/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x238c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2390/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2394/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x239c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x23f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x23f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x23fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2400/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2404/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x240c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2410/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2414/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x241c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2420/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2424/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x242c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2430/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2434/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x243c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2440/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2444/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x244c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2450/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2454/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x245c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2460/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2464/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x246c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2470/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2474/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x247c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2480/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2484/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x248c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2490/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2494/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x249c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x24f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x24f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x24fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2500/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2504/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x250c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2510/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2514/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x251c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2520/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2524/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x252c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2530/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2534/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x253c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2540/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2544/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x254c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2550/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2554/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x255c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2560/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2564/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x256c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2570/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2574/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x257c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2580/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2584/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x258c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2590/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2594/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x259c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x25f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x25f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x25fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2600/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2604/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x260c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2610/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2614/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x261c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2620/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2624/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x262c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2630/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2634/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x263c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2640/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2644/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x264c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2650/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2654/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x265c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2660/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2664/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x266c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2670/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2674/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x267c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2680/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2684/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x268c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2690/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2694/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x269c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x26f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x26f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x26fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2700/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2704/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x270c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2710/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2714/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x271c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2720/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2724/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x272c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2730/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2734/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x273c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2740/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2744/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x274c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2750/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2754/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x275c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2760/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2764/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x276c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2770/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2774/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x277c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2780/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2784/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x278c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2790/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2794/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x279c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x27a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x27a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x27ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x27b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x27b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x27bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x27c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x27c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x27cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x27d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x27d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x27dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x27e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x27e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x27ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x27f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x27f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x27fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2800/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2804/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x280c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2810/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2814/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x281c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2820/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2824/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x282c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2830/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2834/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x283c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2840/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2844/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x284c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2850/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2854/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x285c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2860/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2864/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x286c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2870/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2874/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x287c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2880/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2884/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x288c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2890/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2894/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x289c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x28a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x28a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x28ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x28b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x28b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x28bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x28c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x28c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x28cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x28d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x28d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x28dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x28e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x28e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x28ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x28f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x28f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x28fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2900/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2904/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x290c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2910/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2914/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x291c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2920/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2924/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x292c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2930/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2934/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x293c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2940/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2944/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x294c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2950/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2954/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x295c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2960/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2964/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x296c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2970/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2974/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x297c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2980/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2984/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x298c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2990/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2994/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x299c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x29a0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x29a4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x29ac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x29b0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x29b4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x29bc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x29c0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x29c4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x29cc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x29d0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x29d4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x29dc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x29e0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x29e4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x29ec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x29f0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x29f4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x29fc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a00/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a04/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a0c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a10/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a14/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a1c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a20/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a24/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a2c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a30/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a34/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a3c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a40/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a44/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a4c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a50/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a54/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a5c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a60/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a64/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a6c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a70/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a74/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a7c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a80/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a84/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a8c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2a90/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2a94/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2a9c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2aa0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2aa4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2aac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ab0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ab4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2abc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ac0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ac4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2acc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ad0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ad4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2adc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ae0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ae4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2aec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2af0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2af4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2afc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b00/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b04/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b0c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b10/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b14/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b1c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b20/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b24/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b2c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b30/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b34/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b3c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b40/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b44/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b4c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b50/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b54/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b5c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b60/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b64/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b6c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b70/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b74/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b7c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b80/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b84/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b8c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2b90/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2b94/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2b9c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ba0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ba4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2bac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2bb0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2bb4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2bbc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2bc0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2bc4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2bcc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2bd0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2bd4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2bdc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2be0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2be4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2bec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2bf0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2bf4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2bfc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c00/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c04/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c0c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c10/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c14/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c1c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c20/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c24/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c2c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c30/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c34/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c3c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c40/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c44/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c4c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c50/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c54/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c5c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c60/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c64/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c6c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c70/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c74/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c7c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c80/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c84/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c8c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2c90/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2c94/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2c9c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ca0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ca4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2cac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2cb0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2cb4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2cbc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2cc0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2cc4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ccc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2cd0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2cd4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2cdc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ce0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ce4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2cec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2cf0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2cf4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2cfc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d00/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d04/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d0c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d10/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d14/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d1c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d20/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d24/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d2c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d30/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d34/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d3c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d40/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d44/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d4c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d50/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d54/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d5c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d60/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d64/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d6c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d70/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d74/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d7c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d80/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d84/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d8c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2d90/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2d94/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2d9c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2da0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2da4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2dac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2db0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2db4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2dbc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2dc0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2dc4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2dcc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2dd0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2dd4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ddc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2de0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2de4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2dec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2df0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2df4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2dfc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e00/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e04/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e0c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e10/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e14/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e1c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e20/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e24/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e2c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e30/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e34/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e3c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e40/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e44/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e4c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e50/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e54/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e5c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e60/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e64/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e6c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e70/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e74/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e7c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e80/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e84/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e8c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2e90/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2e94/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2e9c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ea0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ea4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2eac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2eb0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2eb4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ebc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ec0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ec4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ecc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ed0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ed4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2edc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ee0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ee4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2eec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ef0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ef4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2efc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f00/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f04/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f0c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f10/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f14/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f1c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f20/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f24/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f2c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f30/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f34/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f3c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f40/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f44/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f4c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f50/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f54/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f5c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f60/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f64/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f6c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f70/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f74/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f7c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f80/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f84/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f8c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2f90/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2f94/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2f9c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2fa0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2fa4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2fac/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2fb0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2fb4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2fbc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2fc0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2fc4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2fcc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2fd0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2fd4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2fdc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2fe0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2fe4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2fec/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x2ff0/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x2ff4/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x2ffc/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x3000/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3004/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x300c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x3010/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3014/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x301c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x3020/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3024/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x302c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x3030/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3034/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x303c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x3040/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3044/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x304c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x3050/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3054/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x305c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x3060/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3064/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x306c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x3070/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3074/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x307c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x3080/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3084/4, 0x000c001b);
+ INSTANCE_WR(ctx, 0x308c/4, 0x10700ff9);
+ INSTANCE_WR(ctx, 0x3090/4, 0x0436086c);
+ INSTANCE_WR(ctx, 0x3094/4, 0x000c001b);
+ for(i = 0x30bc; i< 0x30cc; i += 4)
+ INSTANCE_WR(ctx, i/4, 0x0000ffff);
+ INSTANCE_WR(ctx, 0x3450/4, 0x3f800000);
+ INSTANCE_WR(ctx, 0x380c/4, 0x3f800000);
+ INSTANCE_WR(ctx, 0x3820/4, 0x3f800000);
+ INSTANCE_WR(ctx, 0x384c/4, 0x40000000);
+ INSTANCE_WR(ctx, 0x3850/4, 0x3f800000);
+ INSTANCE_WR(ctx, 0x3854/4, 0x3f000000);
+ INSTANCE_WR(ctx, 0x385c/4, 0x40000000);
+ INSTANCE_WR(ctx, 0x3860/4, 0x3f800000);
+ INSTANCE_WR(ctx, 0x3868/4, 0xbf800000);
+ INSTANCE_WR(ctx, 0x3870/4, 0xbf800000);}
-int nv30_graph_create_context(struct drm_device *dev, int channel)
+int nv30_graph_create_context(struct nouveau_channel *chan)
{
- struct drm_nouveau_private *dev_priv =
- (struct drm_nouveau_private *)dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
+ 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;
switch (dev_priv->chipset) {
+ case 0x31:
+ ctx_size = NV31_GRCTX_SIZE;
+ ctx_init = nv31_graph_context_init;
+ break;
+ case 0x34:
+ ctx_size = NV34_GRCTX_SIZE;
+ ctx_init = nv34_graph_context_init;
+ break;
+ case 0x35:
+ case 0x36:
+ ctx_size = NV35_GRCTX_SIZE;
+ ctx_init = nv35_graph_context_init;
+ break;
default:
- ctx_size = NV30_GRCTX_SIZE;
- ctx_init = nv30_graph_context_init;
+ ctx_size = 0;
+ ctx_init = nv35_graph_context_init;
+ DRM_ERROR("Please contact the devs if you want your NV%x card to work\n",dev_priv->chipset);
break;
}
- if ((ret = nouveau_gpuobj_new_ref(dev, channel, -1, 0, ctx_size, 16,
+ if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ctx_size, 16,
NVOBJ_FLAG_ZERO_ALLOC,
&chan->ramin_grctx)))
return ret;
/* Initialise default context values */
ctx_init(dev, chan->ramin_grctx->gpuobj);
-
- INSTANCE_WR(chan->ramin_grctx->gpuobj, 10, channel<<24); /* CTX_USER */
- INSTANCE_WR(dev_priv->ctx_table->gpuobj, channel,
- chan->ramin_grctx->instance >> 4);
+
+ INSTANCE_WR(chan->ramin_grctx->gpuobj, 0x28/4, (chan->id<<24)|0x1); /* CTX_USER */
+ INSTANCE_WR(dev_priv->ctx_table->gpuobj, chan->id,
+ chan->ramin_grctx->instance >> 4);
return 0;
}
-void nv30_graph_destroy_context(struct drm_device *dev, int channel)
+void nv30_graph_destroy_context(struct nouveau_channel *chan)
{
- struct drm_nouveau_private *dev_priv =
- (struct drm_nouveau_private *)dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
+ struct drm_device *dev = chan->dev;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
if (chan->ramin_grctx)
nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
- INSTANCE_WR(dev_priv->ctx_table->gpuobj, channel, 0);
+ INSTANCE_WR(dev_priv->ctx_table->gpuobj, chan->id, 0);
}
static int
@@ -161,10 +2779,10 @@ nouveau_graph_wait_idle(struct drm_device *dev)
return 0;
}
-int nv30_graph_load_context(struct drm_device *dev, int channel)
+int nv30_graph_load_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
uint32_t inst;
if (!chan->ramin_grctx)
@@ -178,10 +2796,10 @@ int nv30_graph_load_context(struct drm_device *dev, int channel)
return nouveau_graph_wait_idle(dev);
}
-int nv30_graph_save_context(struct drm_device *dev, int channel)
+int nv30_graph_save_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
uint32_t inst;
if (!chan->ramin_grctx)
@@ -197,8 +2815,7 @@ int nv30_graph_save_context(struct drm_device *dev, int channel)
int nv30_graph_init(struct drm_device *dev)
{
- struct drm_nouveau_private *dev_priv =
- (struct drm_nouveau_private *)dev->dev_private;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
uint32_t vramsz, tmp;
int ret, i;
@@ -209,7 +2826,7 @@ int nv30_graph_init(struct drm_device *dev)
/* Create Context Pointer Table */
dev_priv->ctx_table_size = 32 * 4;
- if ((ret = nouveau_gpuobj_new_ref(dev, -1, -1, 0,
+ if ((ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0,
dev_priv->ctx_table_size, 16,
NVOBJ_FLAG_ZERO_ALLOC,
&dev_priv->ctx_table)))
@@ -218,24 +2835,30 @@ int nv30_graph_init(struct drm_device *dev)
NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_TABLE,
dev_priv->ctx_table->instance >> 4);
- NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000);
NV_WRITE(NV03_PGRAPH_INTR , 0xFFFFFFFF);
+ NV_WRITE(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000);
NV_WRITE(NV04_PGRAPH_DEBUG_1, 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(0x400890, 0x01b463ff);
+ NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xf3de0471);
+ NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x00008000);
+ NV_WRITE(NV04_PGRAPH_LIMIT_VIOL_PIX, 0xf04bdff6);
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(0x400098, 0x00000000);
+ NV_WRITE(0x40009C, 0x0005ad00);
+ NV_WRITE(0x400B88, 0x62ff00ff); // suspiciously like PGRAPH_DEBUG_2
NV_WRITE(0x4000a0, 0x00000000);
NV_WRITE(0x4000a4, 0x00000008);
+ NV_WRITE(0x4008a8, 0xb784a400);
+ NV_WRITE(0x400ba0, 0x002f8685);
+ NV_WRITE(0x400ba4, 0x00231f3f);
+ NV_WRITE(0x4008a4, 0x40000020);
+ NV_WRITE(0x400B84, 0x0c000000);
+ NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x62ff0f7f);
+ NV_WRITE(0x4000c0, 0x00000016);
+ NV_WRITE(0x400780, 0x000014e4);
/* copy tile info from PFB */
for (i=0; i<NV10_PFB_TILE__SIZE; i++) {
diff --git a/shared-core/nv40_fifo.c b/shared-core/nv40_fifo.c
index ecb1d21e..ce3f8fdd 100644
--- a/shared-core/nv40_fifo.c
+++ b/shared-core/nv40_fifo.c
@@ -37,13 +37,13 @@
#define NV40_RAMFC__SIZE 128
int
-nv40_fifo_create_context(struct drm_device *dev, int channel)
+nv40_fifo_create_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
int ret;
- if ((ret = nouveau_gpuobj_new_fake(dev, NV40_RAMFC(channel),
+ if ((ret = nouveau_gpuobj_new_fake(dev, NV40_RAMFC(chan->id), ~0,
NV40_RAMFC__SIZE,
NVOBJ_FLAG_ZERO_ALLOC |
NVOBJ_FLAG_ZERO_FREE,
@@ -68,27 +68,27 @@ nv40_fifo_create_context(struct drm_device *dev, int channel)
RAMFC_WR(DMA_TIMESLICE , 0x0001FFFF);
/* enable the fifo dma operation */
- NV_WRITE(NV04_PFIFO_MODE,NV_READ(NV04_PFIFO_MODE)|(1<<channel));
+ NV_WRITE(NV04_PFIFO_MODE,NV_READ(NV04_PFIFO_MODE)|(1<<chan->id));
return 0;
}
void
-nv40_fifo_destroy_context(struct drm_device *dev, int channel)
+nv40_fifo_destroy_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
- NV_WRITE(NV04_PFIFO_MODE, NV_READ(NV04_PFIFO_MODE)&~(1<<channel));
+ NV_WRITE(NV04_PFIFO_MODE, NV_READ(NV04_PFIFO_MODE)&~(1<<chan->id));
if (chan->ramfc)
nouveau_gpuobj_ref_del(dev, &chan->ramfc);
}
int
-nv40_fifo_load_context(struct drm_device *dev, int channel)
+nv40_fifo_load_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
uint32_t tmp, tmp2;
NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET , RAMFC_RD(DMA_GET));
@@ -135,7 +135,7 @@ nv40_fifo_load_context(struct drm_device *dev, int channel)
NV_WRITE(NV04_PFIFO_DMA_TIMESLICE, tmp);
/* Set channel active, and in DMA mode */
- NV_WRITE(NV03_PFIFO_CACHE1_PUSH1 , 0x00010000 | channel);
+ NV_WRITE(NV03_PFIFO_CACHE1_PUSH1 , 0x00010000 | chan->id);
/* Reset DMA_CTL_AT_INFO to INVALID */
tmp = NV_READ(NV04_PFIFO_CACHE1_DMA_CTL) & ~(1<<31);
NV_WRITE(NV04_PFIFO_CACHE1_DMA_CTL, tmp);
@@ -144,10 +144,10 @@ nv40_fifo_load_context(struct drm_device *dev, int channel)
}
int
-nv40_fifo_save_context(struct drm_device *dev, int channel)
+nv40_fifo_save_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
uint32_t tmp;
RAMFC_WR(DMA_PUT , NV_READ(NV04_PFIFO_CACHE1_DMA_PUT));
@@ -193,3 +193,16 @@ nv40_fifo_save_context(struct drm_device *dev, int channel)
return 0;
}
+int
+nv40_fifo_init(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ int ret;
+
+ if ((ret = nouveau_fifo_init(dev)))
+ return ret;
+
+ NV_WRITE(NV04_PFIFO_DMA_TIMESLICE, 0x2101ffff);
+ return 0;
+}
+
diff --git a/shared-core/nv40_graph.c b/shared-core/nv40_graph.c
index 441dbae7..26237c7d 100644
--- a/shared-core/nv40_graph.c
+++ b/shared-core/nv40_graph.c
@@ -1224,11 +1224,10 @@ nv4e_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
}
int
-nv40_graph_create_context(struct drm_device *dev, int channel)
+nv40_graph_create_context(struct nouveau_channel *chan)
{
- struct drm_nouveau_private *dev_priv =
- (struct drm_nouveau_private *)dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
+ 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;
@@ -1250,6 +1249,7 @@ nv40_graph_create_context(struct drm_device *dev, int channel)
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;
@@ -1272,7 +1272,7 @@ nv40_graph_create_context(struct drm_device *dev, int channel)
break;
}
- if ((ret = nouveau_gpuobj_new_ref(dev, channel, -1, 0, ctx_size, 16,
+ if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ctx_size, 16,
NVOBJ_FLAG_ZERO_ALLOC,
&chan->ramin_grctx)))
return ret;
@@ -1284,37 +1284,43 @@ nv40_graph_create_context(struct drm_device *dev, int channel)
}
void
-nv40_graph_destroy_context(struct drm_device *dev, int channel)
+nv40_graph_destroy_context(struct nouveau_channel *chan)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
-
- if (chan->ramin_grctx)
- nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
+ nouveau_gpuobj_ref_del(chan->dev, &chan->ramin_grctx);
}
static int
nv40_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- uint32_t old_cp, tv = 1000;
+ uint32_t old_cp, tv = 1000, tmp;
int i;
old_cp = NV_READ(NV20_PGRAPH_CHANNEL_CTX_POINTER);
NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
- NV_WRITE(NV40_PGRAPH_CTXCTL_0310,
- save ? NV40_PGRAPH_CTXCTL_0310_XFER_SAVE :
- NV40_PGRAPH_CTXCTL_0310_XFER_LOAD);
- NV_WRITE(NV40_PGRAPH_CTXCTL_0304, NV40_PGRAPH_CTXCTL_0304_XFER_CTX);
+
+ tmp = NV_READ(NV40_PGRAPH_CTXCTL_0310);
+ tmp |= save ? NV40_PGRAPH_CTXCTL_0310_XFER_SAVE :
+ NV40_PGRAPH_CTXCTL_0310_XFER_LOAD;
+ NV_WRITE(NV40_PGRAPH_CTXCTL_0310, tmp);
+
+ tmp = NV_READ(NV40_PGRAPH_CTXCTL_0304);
+ tmp |= NV40_PGRAPH_CTXCTL_0304_XFER_CTX;
+ NV_WRITE(NV40_PGRAPH_CTXCTL_0304, tmp);
for (i = 0; i < tv; i++) {
if (NV_READ(NV40_PGRAPH_CTXCTL_030C) == 0)
break;
}
+
NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, old_cp);
if (i == tv) {
- DRM_ERROR("failed: inst=0x%08x save=%d\n", inst, save);
+ uint32_t ucstat = NV_READ(NV40_PGRAPH_CTXCTL_UCODE_STAT);
+ DRM_ERROR("Failed: Instance=0x%08x Save=%d\n", inst, save);
+ DRM_ERROR("IP: 0x%02x, Opcode: 0x%08x\n",
+ ucstat >> NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT,
+ ucstat & NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK);
DRM_ERROR("0x40030C = 0x%08x\n",
NV_READ(NV40_PGRAPH_CTXCTL_030C));
return -EBUSY;
@@ -1327,10 +1333,9 @@ nv40_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save)
*XXX: fails sometimes, not sure why..
*/
int
-nv40_graph_save_context(struct drm_device *dev, int channel)
+nv40_graph_save_context(struct nouveau_channel *chan)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
+ struct drm_device *dev = chan->dev;
uint32_t inst;
if (!chan->ramin_grctx)
@@ -1344,10 +1349,10 @@ nv40_graph_save_context(struct drm_device *dev, int channel)
* XXX: fails sometimes.. not sure why
*/
int
-nv40_graph_load_context(struct drm_device *dev, int channel)
+nv40_graph_load_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
uint32_t inst;
int ret;
@@ -1459,6 +1464,39 @@ static uint32_t nv43_ctx_voodoo[] = {
~0
};
+static uint32_t nv44_ctx_voodoo[] = {
+ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001,
+ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409a65, 0x00409f06,
+ 0x0040ac68, 0x0040248f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042,
+ 0x001041c6, 0x00104040, 0x00200001, 0x0060000a, 0x00700000, 0x001040c5,
+ 0x00402320, 0x00402321, 0x00402322, 0x00402324, 0x00402326, 0x0040232b,
+ 0x001040c5, 0x00402328, 0x001040c5, 0x00402320, 0x00402468, 0x0060000d,
+ 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, 0x00402be6,
+ 0x007000a0, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, 0x00110158,
+ 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, 0x001041c9,
+ 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, 0x001242c0,
+ 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, 0x0011415f,
+ 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, 0x001046ec,
+ 0x00500060, 0x00404b87, 0x0060000d, 0x004084e6, 0x002000f1, 0x0060000a,
+ 0x00148653, 0x00104668, 0x0010c66d, 0x00120682, 0x0011068b, 0x00168691,
+ 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, 0x001646cc,
+ 0x001186e6, 0x001046ed, 0x001246f0, 0x002000c0, 0x00100700, 0x0010c3d7,
+ 0x001043e1, 0x00500060, 0x00200232, 0x0060000a, 0x00104800, 0x00108901,
+ 0x00104910, 0x00124920, 0x0020001f, 0x00100940, 0x00140965, 0x00148a00,
+ 0x00108a14, 0x00160b00, 0x00134b2c, 0x0010cd00, 0x0010cd04, 0x0010cd08,
+ 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, 0x00104f06, 0x002002c8,
+ 0x0060000a, 0x00300000, 0x00200080, 0x00407d00, 0x00200084, 0x00800001,
+ 0x00200510, 0x0060000a, 0x002037e0, 0x0040838a, 0x00201320, 0x00800029,
+ 0x00409400, 0x00600006, 0x004090e6, 0x00700080, 0x0020007a, 0x0060000a,
+ 0x00104280, 0x002002c8, 0x0060000a, 0x00200004, 0x00800001, 0x00700000,
+ 0x00200000, 0x0060000a, 0x00106002, 0x0040ac68, 0x00700000, 0x00200000,
+ 0x0060000a, 0x00106002, 0x00700080, 0x00400a68, 0x00500060, 0x00600007,
+ 0x00409e88, 0x0060000f, 0x00000000, 0x00500060, 0x00200000, 0x0060000a,
+ 0x00700000, 0x00106001, 0x00910880, 0x00901ffe, 0x01940000, 0x00200020,
+ 0x0060000b, 0x00500069, 0x0060000c, 0x00402c68, 0x0040ae06, 0x0040af05,
+ 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0
+};
+
static uint32_t nv46_ctx_voodoo[] = {
0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001,
0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00408f65, 0x00409306,
@@ -1556,6 +1594,37 @@ static uint32_t nv4a_ctx_voodoo[] = {
0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0
};
+static uint32_t nv4c_ctx_voodoo[] = {
+ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001,
+ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409065, 0x00409406,
+ 0x0040a168, 0x0040198f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042,
+ 0x00200001, 0x0060000a, 0x00700000, 0x001040c5, 0x00401826, 0x00401968,
+ 0x0060000d, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080,
+ 0x004020e6, 0x007000a0, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d,
+ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4,
+ 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e,
+ 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143,
+ 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10,
+ 0x0010427e, 0x001046ec, 0x00500060, 0x00404187, 0x0060000d, 0x00407ae6,
+ 0x002000f2, 0x0060000a, 0x00148653, 0x00104668, 0x0010c66d, 0x00120682,
+ 0x0011068b, 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4,
+ 0x001146c6, 0x00200020, 0x001006cc, 0x001046ed, 0x001246f0, 0x002000c0,
+ 0x00100700, 0x0010c3d7, 0x001043e1, 0x00500060, 0x00200234, 0x0060000a,
+ 0x00104800, 0x00108901, 0x00104910, 0x00124920, 0x0020001f, 0x00100940,
+ 0x00140965, 0x00148a00, 0x00108a14, 0x00140b00, 0x00134b2c, 0x0010cd00,
+ 0x0010cd04, 0x00104d08, 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00,
+ 0x00104f06, 0x002002c0, 0x0060000a, 0x00300000, 0x00200080, 0x00407300,
+ 0x00200084, 0x00800001, 0x00200508, 0x0060000a, 0x00201320, 0x0040798a,
+ 0xfffffaf8, 0x00800029, 0x00408a00, 0x00600006, 0x004086e6, 0x00700080,
+ 0x0020007a, 0x0060000a, 0x00104280, 0x002002c0, 0x0060000a, 0x00200004,
+ 0x00800001, 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x0040a168,
+ 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x00700080, 0x00400a68,
+ 0x00500060, 0x00600007, 0x00409488, 0x0060000f, 0x00500060, 0x00200000,
+ 0x0060000a, 0x00700000, 0x00106001, 0x00910880, 0x00901ffe, 0x01940000,
+ 0x00200020, 0x0060000b, 0x00500069, 0x0060000c, 0x00402168, 0x0040a306,
+ 0x0040a405, 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0
+};
+
static uint32_t nv4e_ctx_voodoo[] = {
0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001,
0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409565, 0x00409a06,
@@ -1615,10 +1684,12 @@ nv40_graph_init(struct drm_device *dev)
switch (dev_priv->chipset) {
case 0x40: ctx_voodoo = nv40_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 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 0x4c: ctx_voodoo = nv4c_ctx_voodoo; break;
case 0x4e: ctx_voodoo = nv4e_ctx_voodoo; break;
default:
DRM_ERROR("Unknown ctx_voodoo for chipset 0x%02x\n",
@@ -1642,8 +1713,8 @@ nv40_graph_init(struct drm_device *dev)
/* No context present currently */
NV_WRITE(NV40_PGRAPH_CTXCTL_CUR, 0x00000000);
- NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000);
NV_WRITE(NV03_PGRAPH_INTR , 0xFFFFFFFF);
+ NV_WRITE(NV40_PGRAPH_INTR_EN, 0xFFFFFFFF);
NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000);
diff --git a/shared-core/nv40_mc.c b/shared-core/nv40_mc.c
index 8bb6b083..c7db9023 100644
--- a/shared-core/nv40_mc.c
+++ b/shared-core/nv40_mc.c
@@ -14,8 +14,6 @@ nv40_mc_init(struct drm_device *dev)
*/
NV_WRITE(NV03_PMC_ENABLE, 0xFFFFFFFF);
- NV_WRITE(NV03_PMC_INTR_EN_0, 0);
-
switch (dev_priv->chipset) {
case 0x44:
case 0x46: /* G72 */
diff --git a/shared-core/nv50_fifo.c b/shared-core/nv50_fifo.c
index f7b98220..7859544a 100644
--- a/shared-core/nv50_fifo.c
+++ b/shared-core/nv50_fifo.c
@@ -30,7 +30,6 @@
typedef struct {
struct nouveau_gpuobj_ref *thingo;
- struct nouveau_gpuobj_ref *dummyctx;
} nv50_fifo_priv;
#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50)
@@ -47,7 +46,7 @@ nv50_fifo_init_thingo(struct drm_device *dev)
INSTANCE_WR(thingo->gpuobj, 0, 0x7e);
INSTANCE_WR(thingo->gpuobj, 1, 0x7e);
- for (i = 0; i <NV_MAX_FIFO_NUMBER; i++, fi) {
+ for (i = 1; i < 127; i++, fi) {
if (dev_priv->fifos[i]) {
INSTANCE_WR(thingo->gpuobj, fi, i);
fi++;
@@ -60,30 +59,23 @@ nv50_fifo_init_thingo(struct drm_device *dev)
}
static int
-nv50_fifo_channel_enable(struct drm_device *dev, int channel)
+nv50_fifo_channel_enable(struct drm_device *dev, int channel, int nt)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
+ struct nouveau_channel *chan = dev_priv->fifos[channel];
+ uint32_t inst;
DRM_DEBUG("ch%d\n", channel);
- if (IS_G80) {
- if (!chan->ramin)
- return -EINVAL;
-
- NV_WRITE(NV50_PFIFO_CTX_TABLE(channel),
- (chan->ramin->instance >> 12) |
- NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED);
- } else {
- if (!chan->ramfc)
- return -EINVAL;
+ if (!chan->ramfc)
+ return -EINVAL;
- NV_WRITE(NV50_PFIFO_CTX_TABLE(channel),
- (chan->ramfc->instance >> 8) |
- NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED);
- }
+ if (IS_G80) inst = chan->ramfc->instance >> 12;
+ else inst = chan->ramfc->instance >> 8;
+ NV_WRITE(NV50_PFIFO_CTX_TABLE(channel),
+ inst | NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED);
- nv50_fifo_init_thingo(dev);
+ if (!nt) nv50_fifo_init_thingo(dev);
return 0;
}
@@ -91,16 +83,13 @@ static void
nv50_fifo_channel_disable(struct drm_device *dev, int channel, int nt)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
+ uint32_t inst;
DRM_DEBUG("ch%d, nt=%d\n", channel, nt);
- if (IS_G80) {
- NV_WRITE(NV50_PFIFO_CTX_TABLE(channel),
- NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80);
- } else {
- NV_WRITE(NV50_PFIFO_CTX_TABLE(channel),
- NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84);
- }
+ if (IS_G80) inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80;
+ else inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84;
+ NV_WRITE(NV50_PFIFO_CTX_TABLE(channel), inst);
if (!nt) nv50_fifo_init_thingo(dev);
}
@@ -120,6 +109,17 @@ nv50_fifo_init_reset(struct drm_device *dev)
}
static void
+nv50_fifo_init_intr(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+ DRM_DEBUG("\n");
+
+ NV_WRITE(NV03_PFIFO_INTR_0, 0xFFFFFFFF);
+ NV_WRITE(NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF);
+}
+
+static void
nv50_fifo_init_context_table(struct drm_device *dev)
{
int i;
@@ -145,18 +145,9 @@ static int
nv50_fifo_init_regs(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- nv50_fifo_priv *priv = dev_priv->Engine.fifo.priv;
- int ret;
DRM_DEBUG("\n");
- if ((ret = nouveau_gpuobj_new_ref(dev, -1, -1, 0, 0x1000,
- 0x1000,
- NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ZERO_FREE,
- &priv->dummyctx)))
- return ret;
-
NV_WRITE(0x2500, 0);
NV_WRITE(0x3250, 0);
NV_WRITE(0x3220, 0);
@@ -164,13 +155,9 @@ nv50_fifo_init_regs(struct drm_device *dev)
NV_WRITE(0x3210, 0);
NV_WRITE(0x3270, 0);
- if (IS_G80) {
- NV_WRITE(0x2600, (priv->dummyctx->instance>>8) | (1<<31));
- NV_WRITE(0x27fc, (priv->dummyctx->instance>>8) | (1<<31));
- } else {
- NV_WRITE(0x2600, (priv->dummyctx->instance>>12) | (1<<31));
- NV_WRITE(0x27fc, (priv->dummyctx->instance>>12) | (1<<31));
- }
+ /* Enable dummy channels setup by nv50_instmem.c */
+ nv50_fifo_channel_enable(dev, 0, 1);
+ nv50_fifo_channel_enable(dev, 127, 1);
return 0;
}
@@ -190,13 +177,15 @@ nv50_fifo_init(struct drm_device *dev)
dev_priv->Engine.fifo.priv = priv;
nv50_fifo_init_reset(dev);
+ nv50_fifo_init_intr(dev);
- if ((ret = nouveau_gpuobj_new_ref(dev, -1, -1, 0, (128+2)*4, 0x1000,
+ if ((ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, (128+2)*4, 0x1000,
NVOBJ_FLAG_ZERO_ALLOC,
&priv->thingo))) {
DRM_ERROR("error creating thingo: %d\n", ret);
return ret;
}
+
nv50_fifo_init_context_table(dev);
nv50_fifo_init_regs__nv(dev);
@@ -218,31 +207,32 @@ nv50_fifo_takedown(struct drm_device *dev)
return;
nouveau_gpuobj_ref_del(dev, &priv->thingo);
- nouveau_gpuobj_ref_del(dev, &priv->dummyctx);
dev_priv->Engine.fifo.priv = NULL;
drm_free(priv, sizeof(*priv), DRM_MEM_DRIVER);
}
int
-nv50_fifo_create_context(struct drm_device *dev, int channel)
+nv50_fifo_create_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
struct nouveau_gpuobj *ramfc = NULL;
int ret;
- DRM_DEBUG("ch%d\n", channel);
+ DRM_DEBUG("ch%d\n", chan->id);
if (IS_G80) {
uint32_t ramfc_offset = chan->ramin->gpuobj->im_pramin->start;
- if ((ret = nouveau_gpuobj_new_fake(dev, ramfc_offset, 0x100,
+ uint32_t vram_offset = chan->ramin->gpuobj->im_backing->start;
+ if ((ret = nouveau_gpuobj_new_fake(dev, ramfc_offset,
+ vram_offset, 0x100,
NVOBJ_FLAG_ZERO_ALLOC |
NVOBJ_FLAG_ZERO_FREE,
&ramfc, &chan->ramfc)))
return ret;
} else {
- if ((ret = nouveau_gpuobj_new_ref(dev, channel, -1, 0, 0x100,
+ if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 0x100,
256,
NVOBJ_FLAG_ZERO_ALLOC |
NVOBJ_FLAG_ZERO_FREE,
@@ -266,15 +256,15 @@ nv50_fifo_create_context(struct drm_device *dev, int channel)
INSTANCE_WR(ramfc, 0x4c/4, chan->pushbuf_mem->size - 1);
if (!IS_G80) {
- INSTANCE_WR(chan->ramin->gpuobj, 0, channel);
+ INSTANCE_WR(chan->ramin->gpuobj, 0, chan->id);
INSTANCE_WR(chan->ramin->gpuobj, 1, chan->ramfc->instance);
INSTANCE_WR(ramfc, 0x88/4, 0x3d520); /* some vram addy >> 10 */
INSTANCE_WR(ramfc, 0x98/4, chan->ramin->instance >> 12);
}
- if ((ret = nv50_fifo_channel_enable(dev, channel))) {
- DRM_ERROR("error enabling ch%d: %d\n", channel, ret);
+ if ((ret = nv50_fifo_channel_enable(dev, chan->id, 0))) {
+ DRM_ERROR("error enabling ch%d: %d\n", chan->id, ret);
nouveau_gpuobj_ref_del(dev, &chan->ramfc);
return ret;
}
@@ -283,25 +273,29 @@ nv50_fifo_create_context(struct drm_device *dev, int channel)
}
void
-nv50_fifo_destroy_context(struct drm_device *dev, int channel)
+nv50_fifo_destroy_context(struct nouveau_channel *chan)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
+ struct drm_device *dev = chan->dev;
- DRM_DEBUG("ch%d\n", channel);
+ DRM_DEBUG("ch%d\n", chan->id);
+
+ nv50_fifo_channel_disable(dev, chan->id, 0);
+
+ /* Dummy channel, also used on ch 127 */
+ if (chan->id == 0)
+ nv50_fifo_channel_disable(dev, 127, 0);
- nv50_fifo_channel_disable(dev, channel, 0);
nouveau_gpuobj_ref_del(dev, &chan->ramfc);
}
int
-nv50_fifo_load_context(struct drm_device *dev, int channel)
+nv50_fifo_load_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
struct nouveau_gpuobj *ramfc = chan->ramfc->gpuobj;
- DRM_DEBUG("ch%d\n", channel);
+ DRM_DEBUG("ch%d\n", chan->id);
/*XXX: incomplete, only touches the regs that NV does */
@@ -319,14 +313,14 @@ nv50_fifo_load_context(struct drm_device *dev, int channel)
NV_WRITE(0x3410, INSTANCE_RD(ramfc, 0x98/4));
}
- NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, channel | (1<<16));
+ NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16));
return 0;
}
int
-nv50_fifo_save_context(struct drm_device *dev, int channel)
+nv50_fifo_save_context(struct nouveau_channel *chan)
{
- DRM_DEBUG("ch%d\n", channel);
+ DRM_DEBUG("ch%d\n", chan->id);
DRM_ERROR("stub!\n");
return 0;
}
diff --git a/shared-core/nv50_graph.c b/shared-core/nv50_graph.c
index 8df5df25..e5bbf65e 100644
--- a/shared-core/nv50_graph.c
+++ b/shared-core/nv50_graph.c
@@ -45,6 +45,16 @@ nv50_graph_init_reset(struct drm_device *dev)
}
static void
+nv50_graph_init_intr(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+ DRM_DEBUG("\n");
+ NV_WRITE(NV03_PGRAPH_INTR, 0xffffffff);
+ NV_WRITE(NV40_PGRAPH_INTR_EN, 0xffffffff);
+}
+
+static void
nv50_graph_init_regs__nv(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -59,7 +69,6 @@ nv50_graph_init_regs__nv(struct drm_device *dev)
NV_WRITE(0x402000, 0xc0000000);
NV_WRITE(0x400108, 0xffffffff);
- NV_WRITE(0x400100, 0xffffffff);
NV_WRITE(0x400824, 0x00004000);
NV_WRITE(0x400500, 0x00010001);
@@ -174,6 +183,7 @@ nv50_graph_init(struct drm_device *dev)
DRM_DEBUG("\n");
nv50_graph_init_reset(dev);
+ nv50_graph_init_intr(dev);
nv50_graph_init_regs__nv(dev);
nv50_graph_init_regs(dev);
nv50_graph_init_ctxctl(dev);
@@ -188,17 +198,18 @@ nv50_graph_takedown(struct drm_device *dev)
}
int
-nv50_graph_create_context(struct drm_device *dev, int channel)
+nv50_graph_create_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
+ struct nouveau_engine *engine = &dev_priv->Engine;
struct nouveau_gpuobj *ramin = chan->ramin->gpuobj;
int grctx_size = 0x60000, hdr;
int ret;
- DRM_DEBUG("ch%d\n", channel);
+ DRM_DEBUG("ch%d\n", chan->id);
- if ((ret = nouveau_gpuobj_new_ref(dev, channel, -1, 0,
+ if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0,
grctx_size, 0x1000,
NVOBJ_FLAG_ZERO_ALLOC |
NVOBJ_FLAG_ZERO_FREE,
@@ -214,17 +225,22 @@ nv50_graph_create_context(struct drm_device *dev, int channel)
INSTANCE_WR(ramin, (hdr + 0x10)/4, 0);
INSTANCE_WR(ramin, (hdr + 0x14)/4, 0x00010000);
+ if ((ret = engine->graph.load_context(chan))) {
+ DRM_ERROR("Error hacking up initial context: %d\n", ret);
+ return ret;
+ }
+
return 0;
}
void
-nv50_graph_destroy_context(struct drm_device *dev, int channel)
+nv50_graph_destroy_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
int i, hdr;
- DRM_DEBUG("ch%d\n", channel);
+ DRM_DEBUG("ch%d\n", chan->id);
hdr = IS_G80 ? 0x200 : 0x20;
for (i=hdr; i<hdr+24; i+=4)
@@ -266,14 +282,14 @@ nv50_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save)
}
int
-nv50_graph_load_context(struct drm_device *dev, int channel)
+nv50_graph_load_context(struct nouveau_channel *chan)
{
+ struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
uint32_t inst = ((chan->ramin->instance >> 12) | (1<<31));
int ret; (void)ret;
- DRM_DEBUG("ch%d\n", channel);
+ DRM_DEBUG("ch%d\n", chan->id);
#if 0
if ((ret = nv50_graph_transfer_context(dev, inst, 0)))
@@ -288,13 +304,12 @@ nv50_graph_load_context(struct drm_device *dev, int channel)
}
int
-nv50_graph_save_context(struct drm_device *dev, int channel)
+nv50_graph_save_context(struct nouveau_channel *chan)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_fifo *chan = dev_priv->fifos[channel];
+ struct drm_device *dev = chan->dev;
uint32_t inst = ((chan->ramin->instance >> 12) | (1<<31));
- DRM_DEBUG("ch%d\n", channel);
+ DRM_DEBUG("ch%d\n", chan->id);
return nv50_graph_transfer_context(dev, inst, 1);
}
diff --git a/shared-core/nv50_instmem.c b/shared-core/nv50_instmem.c
index c26b1db5..1eeb54df 100644
--- a/shared-core/nv50_instmem.c
+++ b/shared-core/nv50_instmem.c
@@ -31,118 +31,162 @@
typedef struct {
uint32_t save1700[5]; /* 0x1700->0x1710 */
+
+ struct nouveau_gpuobj_ref *pramin_pt;
+ struct nouveau_gpuobj_ref *pramin_bar;
} nv50_instmem_priv;
#define NV50_INSTMEM_PAGE_SHIFT 12
#define NV50_INSTMEM_PAGE_SIZE (1 << NV50_INSTMEM_PAGE_SHIFT)
-#define NV50_INSTMEM_RSVD_SIZE (64 * 1024)
#define NV50_INSTMEM_PT_SIZE(a) (((a) >> 12) << 3)
+/*NOTE: - Assumes 0x1700 already covers the correct MiB of PRAMIN
+ */
+#define BAR0_WI32(g,o,v) do { \
+ uint32_t offset; \
+ if ((g)->im_backing) { \
+ offset = (g)->im_backing->start; \
+ } else { \
+ offset = chan->ramin->gpuobj->im_backing->start; \
+ offset += (g)->im_pramin->start; \
+ } \
+ offset += (o); \
+ NV_WRITE(NV_RAMIN + (offset & 0xfffff), (v)); \
+} while(0)
+
int
nv50_instmem_init(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_channel *chan;
+ uint32_t c_offset, c_size, c_ramfc, c_vmpd, c_base, pt_size;
nv50_instmem_priv *priv;
- uint32_t rv, pt, pts, cb, cb0, cb1, unk, as;
- uint32_t i, v;
- int ret;
+ int ret, i;
+ uint32_t v;
priv = drm_calloc(1, sizeof(*priv), DRM_MEM_DRIVER);
if (!priv)
return -ENOMEM;
dev_priv->Engine.instmem.priv = priv;
- /* Save current state */
- for (i = 0x1700; i <= 0x1710; i+=4)
- priv->save1700[(i-0x1700)/4] = NV_READ(i);
-
- as = dev_priv->ramin->size;
- rv = nouveau_mem_fb_amount(dev) - (1*1024*1024);
- pt = rv + 0xd0000;
- pts = NV50_INSTMEM_PT_SIZE(as);
- cb = rv + 0xc8000;
- if ((dev_priv->chipset & 0xf0) != 0x50) {
- unk = cb + 0x4200;
- cb0 = cb + 0x4240;
- cb1 = cb + 0x278;
- } else {
- unk = cb + 0x5400;
- cb0 = cb + 0x5440;
- cb1 = cb + 0x1478;
- }
-
- DRM_DEBUG("PRAMIN config:\n");
- DRM_DEBUG(" Rsvd VRAM base: 0x%08x\n", rv);
- DRM_DEBUG(" Aperture size: %i MiB\n", as >> 20);
- DRM_DEBUG(" PT base: 0x%08x\n", pt);
- DRM_DEBUG(" PT size: %d KiB\n", pts >> 10);
- DRM_DEBUG(" BIOS image: 0x%08x\n", (NV_READ(0x619f04)&~0xff)<<8);
- DRM_DEBUG(" Config base: 0x%08x\n", cb);
- DRM_DEBUG(" ctxdma Config0: 0x%08x\n", cb0);
- DRM_DEBUG(" Config1: 0x%08x\n", cb1);
-
- /* Map first MiB of reserved vram into BAR0 PRAMIN aperture */
- NV_WRITE(0x1700, (rv>>16));
- /* Poke some regs.. */
- NV_WRITE(0x1704, (cb>>12));
- NV_WRITE(0x1710, (((unk-cb)>>4))|(1<<31));
- NV_WRITE(0x1704, (cb>>12)|(1<<30));
-
- /* CB0, some DMA object, NFI what it points at... Needed however,
- * or the PRAMIN aperture doesn't operate as expected.
+ /* Reserve the last MiB of VRAM, we should probably try to avoid
+ * setting up the below tables over the top of the VBIOS image at
+ * some point.
*/
- NV_WRITE(NV_RAMIN + (cb0 - rv) + 0x00, 0x7fc00000);
- NV_WRITE(NV_RAMIN + (cb0 - rv) + 0x04, 0xe1ffffff);
- NV_WRITE(NV_RAMIN + (cb0 - rv) + 0x08, 0xe0000000);
- NV_WRITE(NV_RAMIN + (cb0 - rv) + 0x0c, 0x01000001);
- NV_WRITE(NV_RAMIN + (cb0 - rv) + 0x10, 0x00000000);
- NV_WRITE(NV_RAMIN + (cb0 - rv) + 0x14, 0x00000000);
-
- /* CB1, points at PRAMIN PT */
- NV_WRITE(NV_RAMIN + (cb1 - rv) + 0, pt | 0x63);
- NV_WRITE(NV_RAMIN + (cb1 - rv) + 4, 0x00000000);
-
- /* Zero PRAMIN page table */
- v = NV_RAMIN + (pt - rv);
- for (i = v; i < v + pts; i += 8) {
- NV_WRITE(i + 0x00, 0x00000009);
- NV_WRITE(i + 0x04, 0x00000000);
- }
+ dev_priv->ramin_rsvd_vram = 1 << 20;
+ c_offset = nouveau_mem_fb_amount(dev) - dev_priv->ramin_rsvd_vram;
+ c_size = 128 << 10;
+ c_vmpd = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x1400 : 0x200;
+ c_ramfc = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x0 : 0x20;
+ c_base = c_vmpd + 0x4000;
+ pt_size = NV50_INSTMEM_PT_SIZE(dev_priv->ramin->size);
+
+ DRM_DEBUG(" Rsvd VRAM base: 0x%08x\n", c_offset);
+ DRM_DEBUG(" VBIOS image: 0x%08x\n", (NV_READ(0x619f04)&~0xff)<<8);
+ DRM_DEBUG(" Aperture size: %d MiB\n",
+ (uint32_t)dev_priv->ramin->size >> 20);
+ DRM_DEBUG(" PT size: %d KiB\n", pt_size >> 10);
+
+ NV_WRITE(NV50_PUNK_BAR0_PRAMIN, (c_offset >> 16));
+
+ /* Create a fake channel, and use it as our "dummy" channels 0/127.
+ * The main reason for creating a channel is so we can use the gpuobj
+ * code. However, it's probably worth noting that NVIDIA also setup
+ * their channels 0/127 with the same values they configure here.
+ * So, there may be some other reason for doing this.
+ *
+ * Have to create the entire channel manually, as the real channel
+ * creation code assumes we have PRAMIN access, and we don't until
+ * we're done here.
+ */
+ chan = drm_calloc(1, sizeof(*chan), DRM_MEM_DRIVER);
+ if (!chan)
+ return -ENOMEM;
+ chan->id = 0;
+ chan->dev = dev;
+ chan->file_priv = (struct drm_file *)-2;
+ dev_priv->fifos[0] = dev_priv->fifos[127] = chan;
- /* Map page table into PRAMIN aperture */
- for (i = pt; i < pt + pts; i += 0x1000) {
- uint32_t pte = NV_RAMIN + (pt-rv) + (((i-pt) >> 12) << 3);
- DRM_DEBUG("PRAMIN PTE = 0x%08x @ 0x%08x\n", i, pte);
- NV_WRITE(pte + 0x00, i | 1);
- NV_WRITE(pte + 0x04, 0x00000000);
- }
+ /* Channel's PRAMIN object + heap */
+ if ((ret = nouveau_gpuobj_new_fake(dev, 0, c_offset, 128<<10, 0,
+ NULL, &chan->ramin)))
+ return ret;
- /* Points at CB0 */
- NV_WRITE(0x170c, (((cb0 - cb)>>4)|(1<<31)));
+ if (nouveau_mem_init_heap(&chan->ramin_heap, c_base, c_size - c_base))
+ return -ENOMEM;
+
+ /* RAMFC + zero channel's PRAMIN up to start of VM pagedir */
+ if ((ret = nouveau_gpuobj_new_fake(dev, c_ramfc, c_offset + c_ramfc,
+ 0x4000, 0, NULL, &chan->ramfc)))
+ return ret;
+
+ for (i = 0; i < c_vmpd; i += 4)
+ BAR0_WI32(chan->ramin->gpuobj, i, 0);
+
+ /* VM page directory */
+ if ((ret = nouveau_gpuobj_new_fake(dev, c_vmpd, c_offset + c_vmpd,
+ 0x4000, 0, &chan->vm_pd, NULL)))
+ return ret;
+ for (i = 0; i < 0x4000; i += 8) {
+ BAR0_WI32(chan->vm_pd, i + 0x00, 0x00000000);
+ BAR0_WI32(chan->vm_pd, i + 0x04, 0x00000000);
+ }
- /* Confirm it all worked, should be able to read back the page table's
- * PTEs from the PRAMIN BAR
+ /* PRAMIN page table, cheat and map into VM at 0x0000000000.
+ * We map the entire fake channel into the start of the PRAMIN BAR
*/
- NV_WRITE(0x1700, pt >> 16);
- if (NV_READ(0x700000) != NV_RI32(0)) {
- DRM_ERROR("Failed to init PRAMIN page table\n");
- return -EINVAL;
+ if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pt_size, 0x1000,
+ 0, &priv->pramin_pt)))
+ return ret;
+
+ for (i = 0, v = c_offset; i < pt_size; i+=8, v+=0x1000) {
+ if (v < (c_offset + c_size))
+ BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v | 1);
+ else
+ BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, 0x00000009);
+ BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000);
}
- /* Create a heap to manage PRAMIN aperture allocations */
- ret = nouveau_mem_init_heap(&dev_priv->ramin_heap, pts, as-pts);
- if (ret) {
- DRM_ERROR("Failed to init PRAMIN heap\n");
- return -ENOMEM;
+ BAR0_WI32(chan->vm_pd, 0x00, priv->pramin_pt->instance | 0x63);
+ BAR0_WI32(chan->vm_pd, 0x04, 0x00000000);
+
+ /* DMA object for PRAMIN BAR */
+ if ((ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, 6*4, 16, 0,
+ &priv->pramin_bar)))
+ return ret;
+ BAR0_WI32(priv->pramin_bar->gpuobj, 0x00, 0x7fc00000);
+ BAR0_WI32(priv->pramin_bar->gpuobj, 0x04, dev_priv->ramin->size - 1);
+ BAR0_WI32(priv->pramin_bar->gpuobj, 0x08, 0x00000000);
+ BAR0_WI32(priv->pramin_bar->gpuobj, 0x0c, 0x00000000);
+ BAR0_WI32(priv->pramin_bar->gpuobj, 0x10, 0x00000000);
+ BAR0_WI32(priv->pramin_bar->gpuobj, 0x14, 0x00000000);
+
+ /* Poke the relevant regs, and pray it works :) */
+ NV_WRITE(NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12));
+ NV_WRITE(NV50_PUNK_UNK1710, 0);
+ NV_WRITE(NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12) |
+ NV50_PUNK_BAR_CFG_BASE_VALID);
+ NV_WRITE(NV50_PUNK_BAR1_CTXDMA, 0);
+ NV_WRITE(NV50_PUNK_BAR3_CTXDMA, (priv->pramin_bar->instance >> 4) |
+ NV50_PUNK_BAR3_CTXDMA_VALID);
+
+ /* Assume that praying isn't enough, check that we can re-read the
+ * entire fake channel back from the PRAMIN BAR */
+ for (i = 0; i < c_size; i+=4) {
+ if (NV_READ(NV_RAMIN + i) != NV_RI32(i)) {
+ DRM_ERROR("Error reading back PRAMIN at 0x%08x\n", i);
+ return -EINVAL;
+ }
}
- DRM_DEBUG("NV50: PRAMIN setup ok\n");
- /* Don't alloc the last MiB of VRAM, probably too much, but be safe
- * at least for now.
- */
- dev_priv->ramin_rsvd_vram = 1*1024*1024;
+ /* Global PRAMIN heap */
+ if (nouveau_mem_init_heap(&dev_priv->ramin_heap,
+ c_size, dev_priv->ramin->size - c_size)) {
+ dev_priv->ramin_heap = NULL;
+ DRM_ERROR("Failed to init RAMIN heap\n");
+ }
- /*XXX: probably incorrect, but needed to make hash func "work" */
+ /*XXX: incorrect, but needed to make hash func "work" */
dev_priv->ramht_offset = 0x10000;
dev_priv->ramht_bits = 9;
dev_priv->ramht_size = (1 << dev_priv->ramht_bits);
@@ -154,8 +198,11 @@ nv50_instmem_takedown(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
nv50_instmem_priv *priv = dev_priv->Engine.instmem.priv;
+ struct nouveau_channel *chan = dev_priv->fifos[0];
int i;
+ DRM_DEBUG("\n");
+
if (!priv)
return;
@@ -163,6 +210,20 @@ nv50_instmem_takedown(struct drm_device *dev)
for (i = 0x1700; i <= 0x1710; i+=4)
NV_WRITE(i, priv->save1700[(i-0x1700)/4]);
+ nouveau_gpuobj_ref_del(dev, &priv->pramin_bar);
+ nouveau_gpuobj_ref_del(dev, &priv->pramin_pt);
+
+ /* Destroy dummy channel */
+ if (chan) {
+ nouveau_gpuobj_del(dev, &chan->vm_pd);
+ nouveau_gpuobj_ref_del(dev, &chan->ramfc);
+ nouveau_gpuobj_ref_del(dev, &chan->ramin);
+ nouveau_mem_takedown(&chan->ramin_heap);
+
+ dev_priv->fifos[0] = dev_priv->fifos[127] = NULL;
+ drm_free(chan, sizeof(*chan), DRM_MEM_DRIVER);
+ }
+
dev_priv->Engine.instmem.priv = NULL;
drm_free(priv, sizeof(*priv), DRM_MEM_DRIVER);
}
@@ -205,6 +266,7 @@ int
nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
+ nv50_instmem_priv *priv = dev_priv->Engine.instmem.priv;
uint32_t pte, pte_end, vram;
if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound)
@@ -217,19 +279,14 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte;
vram = gpuobj->im_backing->start;
- if (pte == pte_end) {
- DRM_ERROR("WARNING: badness in bind() pte calc\n");
- pte_end++;
- }
-
DRM_DEBUG("pramin=0x%llx, pte=%d, pte_end=%d\n",
gpuobj->im_pramin->start, pte, pte_end);
DRM_DEBUG("first vram page: 0x%llx\n",
gpuobj->im_backing->start);
while (pte < pte_end) {
- NV_WI32(pte + 0, vram | 1);
- NV_WI32(pte + 4, 0x00000000);
+ INSTANCE_WR(priv->pramin_pt->gpuobj, (pte + 0)/4, vram | 1);
+ INSTANCE_WR(priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000);
pte += 8;
vram += NV50_INSTMEM_PAGE_SIZE;
@@ -243,6 +300,7 @@ int
nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
+ nv50_instmem_priv *priv = dev_priv->Engine.instmem.priv;
uint32_t pte, pte_end;
if (gpuobj->im_bound == 0)
@@ -251,8 +309,8 @@ nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
pte = (gpuobj->im_pramin->start >> 12) << 3;
pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte;
while (pte < pte_end) {
- NV_WI32(pte + 0, 0x00000000);
- NV_WI32(pte + 4, 0x00000000);
+ INSTANCE_WR(priv->pramin_pt->gpuobj, (pte + 0)/4, 0x00000009);
+ INSTANCE_WR(priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000);
pte += 8;
}
diff --git a/shared-core/nv50_mc.c b/shared-core/nv50_mc.c
index 952dea9f..b111826b 100644
--- a/shared-core/nv50_mc.c
+++ b/shared-core/nv50_mc.c
@@ -34,6 +34,7 @@ nv50_mc_init(struct drm_device *dev)
struct drm_nouveau_private *dev_priv = dev->dev_private;
NV_WRITE(NV03_PMC_ENABLE, 0xFFFFFFFF);
+
return 0;
}
diff --git a/shared-core/r128_drm.h b/shared-core/r128_drm.h
index e94a39c6..8d8878b5 100644
--- a/shared-core/r128_drm.h
+++ b/shared-core/r128_drm.h
@@ -222,11 +222,7 @@ typedef struct drm_r128_init {
R128_INIT_CCE = 0x01,
R128_CLEANUP_CCE = 0x02
} func;
-#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
- int sarea_priv_offset;
-#else
unsigned long sarea_priv_offset;
-#endif
int is_pci;
int cce_mode;
int cce_secure;
@@ -240,21 +236,12 @@ typedef struct drm_r128_init {
unsigned int depth_offset, depth_pitch;
unsigned int span_offset;
-#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
- unsigned int fb_offset;
- unsigned int mmio_offset;
- unsigned int ring_offset;
- unsigned int ring_rptr_offset;
- unsigned int buffers_offset;
- unsigned int agp_textures_offset;
-#else
unsigned long fb_offset;
unsigned long mmio_offset;
unsigned long ring_offset;
unsigned long ring_rptr_offset;
unsigned long buffers_offset;
unsigned long agp_textures_offset;
-#endif
} drm_r128_init_t;
typedef struct drm_r128_cce_stop {
@@ -264,15 +251,10 @@ typedef struct drm_r128_cce_stop {
typedef struct drm_r128_clear {
unsigned int flags;
-#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
- int x, y, w, h;
-#endif
unsigned int clear_color;
unsigned int clear_depth;
-#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0)
unsigned int color_mask;
unsigned int depth_mask;
-#endif
} drm_r128_clear_t;
typedef struct drm_r128_vertex {