radeon_ms: radeon modesetting first commit.
authorJerome Glisse <glisse@freedesktop.org>
Sun, 2 Dec 2007 22:48:45 +0000 (23:48 +0100)
committerJerome Glisse <glisse@freedesktop.org>
Tue, 4 Dec 2007 22:03:12 +0000 (23:03 +0100)
This should work on all radeon but there is still many things todo:
    - add crtc2
    - tmds
    - lvds
    - add bios data table so we don't need to hardcode dac/crtc infos
    - separate clock control to make power saving easier & cleaner
    - tiling (warning tiling shouldn't be enable in double scan or interlace)
    - surface reg manager (this goes along with tiling)
    - suspend/resume hook
    - avivo & r500 family support
    - atom bios support (for posting card mostly)
    - finish superioctl skeleton
    - what else ? :)

43 files changed:
linux-core/Makefile
linux-core/Makefile.kernel
linux-core/radeon_ms.h [new symlink]
linux-core/radeon_ms_bo.c [new symlink]
linux-core/radeon_ms_bus.c [new symlink]
linux-core/radeon_ms_compat.c [new file with mode: 0644]
linux-core/radeon_ms_cp.c [new symlink]
linux-core/radeon_ms_cp_mc.c [new symlink]
linux-core/radeon_ms_crtc.c [new symlink]
linux-core/radeon_ms_dac.c [new symlink]
linux-core/radeon_ms_drm.c [new symlink]
linux-core/radeon_ms_drm.h [new symlink]
linux-core/radeon_ms_drv.c [new file with mode: 0644]
linux-core/radeon_ms_drv.h [new file with mode: 0644]
linux-core/radeon_ms_exec.c [new symlink]
linux-core/radeon_ms_family.c [new symlink]
linux-core/radeon_ms_fb.c [new file with mode: 0644]
linux-core/radeon_ms_fence.c [new symlink]
linux-core/radeon_ms_gpu.c [new symlink]
linux-core/radeon_ms_i2c.c [new symlink]
linux-core/radeon_ms_irq.c [new symlink]
linux-core/radeon_ms_output.c [new symlink]
linux-core/radeon_ms_reg.h [new symlink]
linux-core/radeon_ms_state.c [new symlink]
shared-core/drm_pciids.txt
shared-core/radeon_ms.h [new file with mode: 0644]
shared-core/radeon_ms_bo.c [new file with mode: 0644]
shared-core/radeon_ms_bus.c [new file with mode: 0644]
shared-core/radeon_ms_cp.c [new file with mode: 0644]
shared-core/radeon_ms_cp_mc.c [new file with mode: 0644]
shared-core/radeon_ms_crtc.c [new file with mode: 0644]
shared-core/radeon_ms_dac.c [new file with mode: 0644]
shared-core/radeon_ms_drm.c [new file with mode: 0644]
shared-core/radeon_ms_drm.h [new file with mode: 0644]
shared-core/radeon_ms_exec.c [new file with mode: 0644]
shared-core/radeon_ms_family.c [new file with mode: 0644]
shared-core/radeon_ms_fence.c [new file with mode: 0644]
shared-core/radeon_ms_gpu.c [new file with mode: 0644]
shared-core/radeon_ms_i2c.c [new file with mode: 0644]
shared-core/radeon_ms_irq.c [new file with mode: 0644]
shared-core/radeon_ms_output.c [new file with mode: 0644]
shared-core/radeon_ms_reg.h [new file with mode: 0644]
shared-core/radeon_ms_state.c [new file with mode: 0644]

index 7f6b123..76ed3e3 100644 (file)
@@ -58,7 +58,7 @@ endif
 
 # Modules for all architectures
 MODULE_LIST := drm.o tdfx.o r128.o radeon.o mga.o sis.o savage.o via.o \
-               mach64.o nv.o nouveau.o xgi.o
+               mach64.o nv.o nouveau.o xgi.o radeon_ms.o
 
 # Modules only for ix86 architectures
 ifneq (,$(findstring 86,$(MACHINE)))
@@ -92,6 +92,7 @@ NVHEADERS =     nv_drv.h $(DRMHEADERS)
 FFBHEADERS =   ffb_drv.h $(DRMHEADERS)
 NOUVEAUHEADERS = nouveau_drv.h nouveau_drm.h nouveau_reg.h $(DRMHEADERS)
 XGIHEADERS = xgi_cmdlist.h xgi_drv.h xgi_misc.h xgi_regs.h $(DRMHEADERS)
+RADEONMSHEADERS = radeon_ms_driver.h $(DRMHEADERS) 
 
 PROGS = dristat drmstat
 
@@ -286,6 +287,7 @@ CONFIG_DRM_MACH64 := n
 CONFIG_DRM_NV := n
 CONFIG_DRM_NOUVEAU := n
 CONFIG_DRM_XGI := n
+CONFIG_DRM_RADEON_MS := m
 
 # Enable module builds for the modules requested/supported.
 
index 63c93f0..7ef504a 100644 (file)
@@ -34,6 +34,12 @@ nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \
                nv40_graph.o nv50_graph.o \
                nv04_instmem.o nv50_instmem.o
 radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o radeon_fence.o radeon_buffer.o
+radeon_ms-objs := radeon_ms_drv.o radeon_ms_drm.o radeon_ms_family.o \
+               radeon_ms_state.o radeon_ms_bo.o radeon_ms_irq.o \
+               radeon_ms_bus.o radeon_ms_fence.o \
+               radeon_ms_cp.o radeon_ms_cp_mc.o radeon_ms_i2c.o \
+               radeon_ms_output.o radeon_ms_crtc.o radeon_ms_fb.o \
+               radeon_ms_exec.o radeon_ms_gpu.o radeon_ms_dac.o
 sis-objs    := sis_drv.o sis_mm.o
 ffb-objs    := ffb_drv.o ffb_context.o
 savage-objs := savage_drv.o savage_bci.o savage_state.o
@@ -47,6 +53,7 @@ xgi-objs    := xgi_cmdlist.o xgi_drv.o xgi_fb.o xgi_misc.o xgi_pcie.o \
 ifeq ($(CONFIG_COMPAT),y)
 drm-objs    += drm_ioc32.o
 radeon-objs += radeon_ioc32.o
+radeon_ms-objs += radeon_ms_compat.o
 mga-objs    += mga_ioc32.o
 r128-objs   += r128_ioc32.o
 i915-objs   += i915_ioc32.o
@@ -69,3 +76,4 @@ obj-$(CONFIG_DRM_MACH64)+= mach64.o
 obj-$(CONFIG_DRM_NV)    += nv.o
 obj-$(CONFIG_DRM_NOUVEAU) += nouveau.o
 obj-$(CONFIG_DRM_XGI)   += xgi.o
+obj-$(CONFIG_DRM_RADEON_MS) += radeon_ms.o
diff --git a/linux-core/radeon_ms.h b/linux-core/radeon_ms.h
new file mode 120000 (symlink)
index 0000000..da340c5
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms.h
\ No newline at end of file
diff --git a/linux-core/radeon_ms_bo.c b/linux-core/radeon_ms_bo.c
new file mode 120000 (symlink)
index 0000000..d05df59
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_bo.c
\ No newline at end of file
diff --git a/linux-core/radeon_ms_bus.c b/linux-core/radeon_ms_bus.c
new file mode 120000 (symlink)
index 0000000..50f649d
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_bus.c
\ No newline at end of file
diff --git a/linux-core/radeon_ms_compat.c b/linux-core/radeon_ms_compat.c
new file mode 100644 (file)
index 0000000..6efdc78
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2007 Dave Airlie
+ * Copyright 2007 Alex Deucher
+ * Copyright 2007 Michel Dänzer
+ * Copyright 2007 Roland Scheidegger
+ * Copyright 2007 Vladimir Dergachev
+ * Copyright 2007 Nicolai Haehnle
+ * Copyright 2007 Aapo Tahkola
+ * Copyright 2007 Ben Skeggs
+ * Copyright 2007 Jérôme Glisse
+ * 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
+ * PRECISION INSIGHT 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.
+ */
+/*
+ * Authors:
+ *    Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_ms.h"
+
+/**
+ * Called whenever a 32-bit process running under a 64-bit kernel
+ * performs an ioctl on /dev/dri/card<n>.
+
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ */
+long radeon_ms_compat_ioctl(struct file *filp, unsigned int cmd,
+                           unsigned long arg)
+{
+       unsigned int nr = DRM_IOCTL_NR(cmd);
+       drm_ioctl_compat_t *fn = NULL;
+       int ret;
+
+       if (nr < DRM_COMMAND_BASE)
+               return drm_compat_ioctl(filp, cmd, arg);
+
+       lock_kernel();
+       if (fn != NULL)
+               ret = (*fn)(filp, cmd, arg);
+       else
+               ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+       unlock_kernel();
+
+       return ret;
+}
diff --git a/linux-core/radeon_ms_cp.c b/linux-core/radeon_ms_cp.c
new file mode 120000 (symlink)
index 0000000..6aee3e6
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_cp.c
\ No newline at end of file
diff --git a/linux-core/radeon_ms_cp_mc.c b/linux-core/radeon_ms_cp_mc.c
new file mode 120000 (symlink)
index 0000000..0ae1a64
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_cp_mc.c
\ No newline at end of file
diff --git a/linux-core/radeon_ms_crtc.c b/linux-core/radeon_ms_crtc.c
new file mode 120000 (symlink)
index 0000000..31f1144
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_crtc.c
\ No newline at end of file
diff --git a/linux-core/radeon_ms_dac.c b/linux-core/radeon_ms_dac.c
new file mode 120000 (symlink)
index 0000000..cb523cf
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_dac.c
\ No newline at end of file
diff --git a/linux-core/radeon_ms_drm.c b/linux-core/radeon_ms_drm.c
new file mode 120000 (symlink)
index 0000000..8bbf19a
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_drm.c
\ No newline at end of file
diff --git a/linux-core/radeon_ms_drm.h b/linux-core/radeon_ms_drm.h
new file mode 120000 (symlink)
index 0000000..5d9d731
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_drm.h
\ No newline at end of file
diff --git a/linux-core/radeon_ms_drv.c b/linux-core/radeon_ms_drv.c
new file mode 100644 (file)
index 0000000..4b52a7d
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2007 Jerome Glisse.
+ * 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
+ * PRECISION INSIGHT 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.
+ */
+/*
+ * Authors:
+ *    Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "drm_pciids.h"
+#include "radeon_ms.h"
+
+extern struct drm_fence_driver radeon_ms_fence_driver;
+extern struct drm_bo_driver radeon_ms_bo_driver;
+extern struct drm_ioctl_desc radeon_ms_ioctls[];
+extern int radeon_ms_num_ioctls;
+
+static int radeon_ms_driver_dri_library_name(struct drm_device * dev,
+                                            char * buf);
+static int radeon_ms_driver_probe(struct pci_dev *pdev,
+                                 const struct pci_device_id *ent);
+
+static struct pci_device_id pciidlist[] = {
+       radeon_ms_PCI_IDS
+};
+
+static struct drm_driver driver = {
+       .load = radeon_ms_driver_load,
+       .firstopen = NULL,
+       .open = radeon_ms_driver_open,
+       .preclose = NULL,
+       .postclose = NULL,
+       .lastclose = radeon_ms_driver_lastclose,
+       .unload = radeon_ms_driver_unload,
+       .dma_ioctl = radeon_ms_driver_dma_ioctl,
+       .dma_ready = NULL,
+       .dma_quiescent = NULL,
+       .context_ctor = NULL,
+       .context_dtor = NULL,
+       .kernel_context_switch = NULL,
+       .kernel_context_switch_unlock = NULL,
+       .vblank_wait = NULL,
+       .vblank_wait2 = NULL,
+       .dri_library_name = radeon_ms_driver_dri_library_name,
+       .device_is_agp = NULL,
+       .irq_handler = radeon_ms_irq_handler,
+       .irq_preinstall = radeon_ms_irq_preinstall,
+       .irq_postinstall = radeon_ms_irq_postinstall,
+       .irq_uninstall = radeon_ms_irq_uninstall,
+       .reclaim_buffers = drm_core_reclaim_buffers,
+       .reclaim_buffers_locked = NULL,
+       .reclaim_buffers_idlelocked = NULL,
+       .get_map_ofs = drm_core_get_map_ofs,
+       .get_reg_ofs = drm_core_get_reg_ofs,
+       .set_version = NULL,
+       .fb_probe = radeonfb_probe,
+       .fb_remove = radeonfb_remove,
+       .fence_driver = &radeon_ms_fence_driver,
+       .bo_driver = &radeon_ms_bo_driver,
+       .major = DRIVER_MAJOR,
+       .minor = DRIVER_MINOR,
+       .patchlevel = DRIVER_PATCHLEVEL,
+       .name = DRIVER_NAME,
+       .desc = DRIVER_DESC,
+       .date = DRIVER_DATE,
+       .driver_features =
+           DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
+           DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED |
+           DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2,
+       .dev_priv_size = 0, 
+       .ioctls = radeon_ms_ioctls,
+       .num_ioctls = 0,
+       .fops = {
+               .owner = THIS_MODULE,
+               .open = drm_open,
+               .release = drm_release,
+               .ioctl = drm_ioctl,
+               .mmap = drm_mmap,
+               .poll = drm_poll,
+               .fasync = drm_fasync,
+#if defined(CONFIG_COMPAT) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
+               .compat_ioctl = radeon_ms_compat_ioctl,
+#endif
+               },
+       .pci_driver = {
+               .name = DRIVER_NAME,
+               .id_table = pciidlist,
+               .probe = radeon_ms_driver_probe,
+               .remove = __devexit_p(drm_cleanup_pci),
+       },
+};
+
+static int radeon_ms_driver_probe(struct pci_dev *pdev,
+                                 const struct pci_device_id *ent)
+{
+       return drm_get_dev(pdev, ent, &driver);
+}
+
+static int radeon_ms_driver_dri_library_name(struct drm_device * dev,
+                                            char * buf)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       int ret;
+
+       switch (dev_priv->family) {
+       default:
+               ret = snprintf(buf, PAGE_SIZE, "\n");
+       }
+       return ret;
+}
+
+static void __exit radeon_ms_driver_exit(void)
+{
+       drm_exit(&driver);
+}
+
+static int __init radeon_ms_driver_init(void)
+{
+       driver.num_ioctls = radeon_ms_num_ioctls;
+       return drm_init(&driver, pciidlist);
+}
+
+module_init(radeon_ms_driver_init);
+module_exit(radeon_ms_driver_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL and additional rights");
diff --git a/linux-core/radeon_ms_drv.h b/linux-core/radeon_ms_drv.h
new file mode 100644 (file)
index 0000000..529f9c4
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Dave Airlie
+ * Copyright 2007 Alex Deucher
+ * Copyright 2007 Michel Dänzer
+ * Copyright 2007 Roland Scheidegger
+ * Copyright 2007 Vladimir Dergachev
+ * Copyright 2007 Nicolai Haehnle
+ * Copyright 2007 Aapo Tahkola
+ * Copyright 2007 Ben Skeggs
+ * Copyright 2007 Jérôme Glisse
+ * 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
+ * PRECISION INSIGHT 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.
+ */
+/*
+ * Authors:
+ *    Jérôme Glisse <glisse@freedesktop.org>
+ */
+#ifndef __RADEON_MS_DRV_H__
+#define __RADEON_MS_DRV_H__
+
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/i2c-algo-bit.h>
+#include "drm.h"
+#include "drmP.h"
+
+#endif
diff --git a/linux-core/radeon_ms_exec.c b/linux-core/radeon_ms_exec.c
new file mode 120000 (symlink)
index 0000000..cb397fb
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_exec.c
\ No newline at end of file
diff --git a/linux-core/radeon_ms_family.c b/linux-core/radeon_ms_family.c
new file mode 120000 (symlink)
index 0000000..1f12e09
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_family.c
\ No newline at end of file
diff --git a/linux-core/radeon_ms_fb.c b/linux-core/radeon_ms_fb.c
new file mode 100644 (file)
index 0000000..ef7c5cf
--- /dev/null
@@ -0,0 +1,384 @@
+/*
+ * Copyright © 2007 David Airlie
+ * Copyright © 2007 Jerome Glisse
+ *
+ * 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 on 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
+ * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR 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 <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "drm_crtc.h"
+#include "radeon_ms.h"
+
+struct radeonfb_par {
+       struct drm_device       *dev;
+       struct drm_crtc         *crtc;
+};
+
+static int radeonfb_setcolreg(unsigned regno, unsigned red,
+                              unsigned green, unsigned blue,
+                              unsigned transp, struct fb_info *info)
+{
+       struct radeonfb_par *par = info->par;
+       struct drm_crtc *crtc = par->crtc;
+
+       if (regno > 255)
+               return 1;
+       if (crtc->funcs->gamma_set)
+               crtc->funcs->gamma_set(crtc, red, green, blue, regno);
+       return 0;
+}
+
+static int radeonfb_check_var(struct fb_var_screeninfo *var,
+                              struct fb_info *info)
+{
+        struct radeonfb_par *par = info->par;
+       struct drm_framebuffer *fb = par->crtc->fb;
+
+        if (!var->pixclock)
+                return -EINVAL;
+
+        /* Need to resize the fb object !!! */
+        if (var->xres > fb->width || var->yres > fb->height) {
+                DRM_ERROR("Requested width/height is greater than "
+                         "current fb object %dx%d > %dx%d\n",
+                         var->xres, var->yres, fb->width, fb->height);
+                DRM_ERROR("Need resizing code.\n");
+                return -EINVAL;
+        }
+
+        switch (var->bits_per_pixel) {
+        case 16:
+               if (var->green.length == 5) {
+                       var->red.offset = 10;
+                       var->green.offset = 5;
+                       var->blue.offset = 0;
+                       var->red.length = 5;
+                       var->green.length = 5;
+                       var->blue.length = 5;
+                       var->transp.length = 0;
+                       var->transp.offset = 0;
+               } else {
+                       var->red.offset = 11;
+                       var->green.offset = 6;
+                       var->blue.offset = 0;
+                       var->red.length = 5;
+                       var->green.length = 6;
+                       var->blue.length = 5;
+                       var->transp.length = 0;
+                       var->transp.offset = 0;
+               }
+                break;
+       case 32:
+                if (var->transp.length) {
+                       var->red.offset = 16;
+                       var->green.offset = 8;
+                       var->blue.offset = 0;
+                       var->red.length = 8;
+                       var->green.length = 8;
+                       var->blue.length = 8;
+                       var->transp.length = 8;
+                       var->transp.offset = 24;
+               } else {
+                       var->red.offset = 16;
+                       var->green.offset = 8;
+                       var->blue.offset = 0;
+                       var->red.length = 8;
+                       var->green.length = 8;
+                       var->blue.length = 8;
+                       var->transp.length = 0;
+                       var->transp.offset = 0;
+               }
+               break;
+        default:
+               return -EINVAL; 
+        }
+       return 0;
+}
+
+static int radeonfb_set_par(struct fb_info *info)
+{
+       struct radeonfb_par *par = info->par;
+       struct drm_framebuffer *fb = par->crtc->fb;
+       struct drm_device *dev = par->dev;
+        struct drm_display_mode *drm_mode;
+        struct fb_var_screeninfo *var = &info->var;
+
+        switch (var->bits_per_pixel) {
+        case 16:
+               fb->depth = (var->green.length == 6) ? 16 : 15;
+               break;
+        case 32:
+               fb->depth = (var->transp.length > 0) ? 32 : 24;
+               break;
+       default:
+               return -EINVAL; 
+       }
+       fb->bits_per_pixel = var->bits_per_pixel;
+
+       info->fix.line_length = fb->pitch;
+       info->fix.smem_len = info->fix.line_length * fb->height;
+       info->fix.visual = FB_VISUAL_TRUECOLOR;
+       info->screen_size = info->fix.smem_len; /* ??? */
+
+        /* Should we walk the output's modelist or just create our own ???
+         * For now, we create and destroy a mode based on the incoming 
+         * parameters. But there's commented out code below which scans 
+         * the output list too.
+         */
+       drm_mode = drm_mode_create(dev);
+       drm_mode->hdisplay = var->xres;
+       drm_mode->hsync_start = drm_mode->hdisplay + var->right_margin;
+       drm_mode->hsync_end = drm_mode->hsync_start + var->hsync_len;
+       drm_mode->htotal = drm_mode->hsync_end + var->left_margin;
+       drm_mode->vdisplay = var->yres;
+       drm_mode->vsync_start = drm_mode->vdisplay + var->lower_margin;
+       drm_mode->vsync_end = drm_mode->vsync_start + var->vsync_len;
+       drm_mode->vtotal = drm_mode->vsync_end + var->upper_margin;
+       drm_mode->clock = PICOS2KHZ(var->pixclock);
+       drm_mode->vrefresh = drm_mode_vrefresh(drm_mode);
+       drm_mode_set_name(drm_mode);
+       drm_mode_set_crtcinfo(drm_mode, CRTC_INTERLACE_HALVE_V);
+
+       drm_mode_debug_printmodeline(dev, drm_mode);
+
+       if (!drm_crtc_set_mode(par->crtc, drm_mode, 0, 0))
+               return -EINVAL;
+
+        /* Have to destroy our created mode if we're not searching the mode
+         * list for it.
+         */
+       drm_mode_destroy(dev, drm_mode);
+
+       return 0;
+}
+
+static struct fb_ops radeonfb_ops = {
+       .owner = THIS_MODULE,
+       //      .fb_open = radeonfb_open,
+       //      .fb_read = radeonfb_read,
+       //      .fb_write = radeonfb_write,
+       //      .fb_release = radeonfb_release,
+       //      .fb_ioctl = radeonfb_ioctl,
+       .fb_check_var = radeonfb_check_var,
+       .fb_set_par = radeonfb_set_par,
+       .fb_setcolreg = radeonfb_setcolreg,
+       .fb_fillrect = cfb_fillrect,
+       .fb_copyarea = cfb_copyarea,
+       .fb_imageblit = cfb_imageblit,
+};
+
+int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc)
+{
+       struct fb_info *info;
+       struct radeonfb_par *par;
+       struct device *device = &dev->pdev->dev; 
+       struct drm_framebuffer *fb;
+       struct drm_display_mode *mode = crtc->desired_mode;
+       int ret;
+
+       info = framebuffer_alloc(sizeof(struct radeonfb_par), device);
+       if (!info){
+               DRM_INFO("[radeon_ms] framebuffer_alloc failed\n");
+               return -EINVAL;
+       }
+
+       fb = drm_framebuffer_create(dev);
+       if (!fb) {
+               framebuffer_release(info);
+               DRM_ERROR("[radeon_ms] failed to allocate fb.\n");
+               return -EINVAL;
+       }
+       crtc->fb = fb;
+
+       fb->width = crtc->desired_mode->hdisplay;
+       fb->height = crtc->desired_mode->vdisplay;
+       fb->bits_per_pixel = 32;
+       fb->pitch = fb->width * ((fb->bits_per_pixel + 1) / 8);
+       fb->depth = 24;
+       /* one page alignment should be fine for constraint (micro|macro tiling,
+        * bit depth, color buffer offset, ...) */
+       ret = drm_buffer_object_create(dev, fb->width * fb->height * 4, 
+                                      drm_bo_type_kernel,
+                                      DRM_BO_FLAG_READ |
+                                      DRM_BO_FLAG_WRITE |
+                                      DRM_BO_FLAG_NO_EVICT |
+                                      DRM_BO_FLAG_MEM_VRAM,
+                                      DRM_BO_HINT_DONT_FENCE,
+                                      1,
+                                      0,
+                                      &fb->bo);
+       if (ret || fb->bo == NULL) {
+               DRM_ERROR("[radeon_ms] failed to allocate framebuffer\n");
+               drm_framebuffer_destroy(fb);
+               framebuffer_release(info);
+               return -EINVAL;
+       }
+
+       fb->offset = fb->bo->offset;
+       DRM_INFO("[radeon_ms] framebuffer %dx%d at 0x%08lX\n",
+                fb->width, fb->height, fb->bo->offset);
+
+       fb->fbdev = info;
+       par = info->par;
+       par->dev = dev;
+       par->crtc = crtc;
+       info->fbops = &radeonfb_ops;
+       strcpy(info->fix.id, "radeonfb");
+       info->fix.type = FB_TYPE_PACKED_PIXELS;
+       info->fix.visual = FB_VISUAL_TRUECOLOR;
+       info->fix.type_aux = 0;
+       info->fix.xpanstep = 8;
+       info->fix.ypanstep = 1;
+       info->fix.ywrapstep = 0;
+       info->fix.accel = FB_ACCEL_ATI_RADEON;
+       info->fix.type_aux = 0;
+       info->fix.mmio_start = 0;
+       info->fix.mmio_len = 0;
+       info->fix.line_length = fb->pitch;
+       info->fix.smem_start = fb->offset + dev->mode_config.fb_base;
+       info->fix.smem_len = info->fix.line_length * fb->height;
+       info->flags = FBINFO_DEFAULT;
+       DRM_INFO("[radeon_ms] fb physical start : 0x%lX\n", info->fix.smem_start);
+       DRM_INFO("[radeon_ms] fb physical size  : %d\n", info->fix.smem_len);
+
+       ret = drm_mem_reg_ioremap(dev, &fb->bo->mem, &fb->virtual_base);
+       if (ret) {
+               DRM_ERROR("error mapping fb: %d\n", ret);
+       }
+
+       info->screen_base = fb->virtual_base;
+       info->screen_size = info->fix.smem_len; /* FIXME */
+       info->pseudo_palette = fb->pseudo_palette;
+       info->var.xres_virtual = fb->width;
+       info->var.yres_virtual = fb->height;
+       info->var.bits_per_pixel = fb->bits_per_pixel;
+       info->var.xoffset = 0;
+       info->var.yoffset = 0;
+       info->var.activate = FB_ACTIVATE_NOW;
+       info->var.height = -1;
+       info->var.width = -1;
+       info->var.vmode = FB_VMODE_NONINTERLACED;
+
+       info->var.xres = mode->hdisplay;
+       info->var.right_margin = mode->hsync_start - mode->hdisplay;
+       info->var.hsync_len = mode->hsync_end - mode->hsync_start;
+       info->var.left_margin = mode->htotal - mode->hsync_end;
+       info->var.yres = mode->vdisplay;
+       info->var.lower_margin = mode->vsync_start - mode->vdisplay;
+       info->var.vsync_len = mode->vsync_end - mode->vsync_start;
+       info->var.upper_margin = mode->vtotal - mode->vsync_end;
+       info->var.pixclock = 10000000 / mode->htotal * 1000 /
+               mode->vtotal * 100;
+       /* avoid overflow */
+       info->var.pixclock = info->var.pixclock * 1000 / mode->vrefresh;
+
+       info->pixmap.size = 64*1024;
+       info->pixmap.buf_align = 8;
+       info->pixmap.access_align = 32;
+       info->pixmap.flags = FB_PIXMAP_SYSTEM;
+       info->pixmap.scan_align = 1;
+
+       DRM_DEBUG("fb depth is %d\n", fb->depth);
+       DRM_DEBUG("   pitch is %d\n", fb->pitch);
+       switch(fb->depth) {
+       case 15:
+                info->var.red.offset = 10;
+               info->var.green.offset = 5;
+               info->var.blue.offset = 0;
+               info->var.red.length = info->var.green.length =
+                       info->var.blue.length = 5;
+               info->var.transp.offset = 15;
+                info->var.transp.length = 1;
+                break;
+       case 16:
+                info->var.red.offset = 11;
+                info->var.green.offset = 5;
+                info->var.blue.offset = 0;
+                info->var.red.length = 5;
+                info->var.green.length = 6;
+                info->var.blue.length = 5;
+                info->var.transp.offset = 0;
+               break;
+       case 24:
+                info->var.red.offset = 16;
+                info->var.green.offset = 8;
+                info->var.blue.offset = 0;
+                info->var.red.length = info->var.green.length =
+                        info->var.blue.length = 8;
+                info->var.transp.offset = 0;
+                info->var.transp.length = 0;
+                break;
+       case 32:
+               info->var.red.offset = 16;
+               info->var.green.offset = 8;
+               info->var.blue.offset = 0;
+               info->var.red.length = info->var.green.length =
+                       info->var.blue.length = 8;
+               info->var.transp.offset = 24;
+               info->var.transp.length = 8;
+               break;
+       default:
+               DRM_ERROR("only support 15, 16, 24 or 32bits per pixel "
+                         "got %d\n", fb->depth);
+               return -EINVAL;
+               break;
+       }
+
+       if (register_framebuffer(info) < 0) {
+               return -EINVAL;
+       }
+
+       DRM_INFO("[radeon_ms] fb%d: %s frame buffer device\n", info->node,
+                info->fix.id);
+       return 0;
+}
+EXPORT_SYMBOL(radeonfb_probe);
+
+int radeonfb_remove(struct drm_device *dev, struct drm_crtc *crtc)
+{
+       struct drm_framebuffer *fb = crtc->fb;
+       struct fb_info *info = fb->fbdev;
+       
+       if (info) {
+               unregister_framebuffer(info);
+               framebuffer_release(info);
+               drm_mem_reg_iounmap(dev, &fb->bo->mem, fb->virtual_base);
+               drm_bo_usage_deref_unlocked(&fb->bo);
+               drm_framebuffer_destroy(fb);
+       }
+       return 0;
+}
+EXPORT_SYMBOL(radeonfb_remove);
+MODULE_LICENSE("GPL");
diff --git a/linux-core/radeon_ms_fence.c b/linux-core/radeon_ms_fence.c
new file mode 120000 (symlink)
index 0000000..383cc07
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_fence.c
\ No newline at end of file
diff --git a/linux-core/radeon_ms_gpu.c b/linux-core/radeon_ms_gpu.c
new file mode 120000 (symlink)
index 0000000..fa5e05b
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_gpu.c
\ No newline at end of file
diff --git a/linux-core/radeon_ms_i2c.c b/linux-core/radeon_ms_i2c.c
new file mode 120000 (symlink)
index 0000000..1863e6d
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_i2c.c
\ No newline at end of file
diff --git a/linux-core/radeon_ms_irq.c b/linux-core/radeon_ms_irq.c
new file mode 120000 (symlink)
index 0000000..c4e60ba
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_irq.c
\ No newline at end of file
diff --git a/linux-core/radeon_ms_output.c b/linux-core/radeon_ms_output.c
new file mode 120000 (symlink)
index 0000000..6a38b67
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_output.c
\ No newline at end of file
diff --git a/linux-core/radeon_ms_reg.h b/linux-core/radeon_ms_reg.h
new file mode 120000 (symlink)
index 0000000..24b01b4
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_reg.h
\ No newline at end of file
diff --git a/linux-core/radeon_ms_state.c b/linux-core/radeon_ms_state.c
new file mode 120000 (symlink)
index 0000000..2d2e2ef
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/radeon_ms_state.c
\ No newline at end of file
index 05d32f2..a76413d 100644 (file)
@@ -1,3 +1,7 @@
+[radeon_ms]
+0x1002 0x4150 CHIP_RV350|RADEON_AGP "ATI Radeon RV350 9600"
+0x1002 0x5b63 CHIP_RV370|RADEON_PCIE "ATI Radeon RV370 X550"
+
 [radeon]
 0x1002 0x3150 CHIP_RV380|RADEON_IS_MOBILITY "ATI Radeon Mobility X600 M24"
 0x1002 0x3152 CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Radeon Mobility X300 M24"
diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h
new file mode 100644 (file)
index 0000000..ee795f3
--- /dev/null
@@ -0,0 +1,607 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Dave Airlie
+ * Copyright 2007 Alex Deucher
+ * 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
+ * PRECISION INSIGHT 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.
+ */
+/*
+ * Authors:
+ *    Jérôme Glisse <glisse@freedesktop.org>
+ */
+#ifndef __RADEON_MS_H__
+#define __RADEON_MS_H__
+
+#include "radeon_ms_drv.h"
+#include "radeon_ms_reg.h"
+#include "radeon_ms_drm.h"
+
+#define DRIVER_AUTHOR      "Jerome Glisse, Dave Airlie,  Gareth Hughes, "\
+                          "Keith Whitwell, others."
+#define DRIVER_NAME        "radeon_ms"
+#define DRIVER_DESC        "radeon kernel modesetting"
+#define DRIVER_DATE        "20071108"
+#define DRIVER_MAJOR        1
+#define DRIVER_MINOR        0
+#define DRIVER_PATCHLEVEL   0
+
+#define RADEON_PAGE_SIZE        4096
+#define RADEON_MAX_CONNECTORS   8
+#define RADEON_MAX_OUTPUTS      8
+
+enum radeon_bus_type {
+       RADEON_PCI = 0x10000,
+       RADEON_AGP = 0x20000,
+       RADEON_PCIE = 0x30000,
+};
+
+enum radeon_family {
+       CHIP_R100,
+       CHIP_RV100,
+       CHIP_RS100,
+       CHIP_RV200,
+       CHIP_RS200,
+       CHIP_R200,
+       CHIP_RV250,
+       CHIP_RS300,
+       CHIP_RV280,
+       CHIP_R300,
+       CHIP_R350,
+       CHIP_R360,
+       CHIP_RV350,
+       CHIP_RV370,
+       CHIP_RV380,
+       CHIP_RS400,
+       CHIP_RV410,
+       CHIP_R420,
+       CHIP_R430,
+       CHIP_R480,
+       CHIP_LAST,
+};
+
+enum radeon_monitor_type {
+       MT_UNKNOWN = -1,
+       MT_NONE    = 0,
+       MT_CRT     = 1,
+       MT_LCD     = 2,
+       MT_DFP     = 3,
+       MT_CTV     = 4,
+       MT_STV     = 5
+};
+
+enum radeon_connector_type {
+       CONNECTOR_NONE,
+       CONNECTOR_PROPRIETARY,
+       CONNECTOR_VGA,
+       CONNECTOR_DVI_I,
+       CONNECTOR_DVI_D,
+       CONNECTOR_CTV,
+       CONNECTOR_STV,
+       CONNECTOR_UNSUPPORTED
+};
+
+enum radeon_output_type {
+       OUTPUT_NONE,
+       OUTPUT_DAC1,
+       OUTPUT_DAC2,
+       OUTPUT_TMDS,
+       OUTPUT_LVDS
+};
+
+struct radeon_state;
+
+struct radeon_ms_crtc {
+       int             crtc;
+       uint16_t        lut_r[256];
+       uint16_t        lut_g[256];
+       uint16_t        lut_b[256];
+};
+
+struct radeon_ms_i2c {
+       struct drm_device           *drm_dev;
+       uint32_t                    reg;
+       struct i2c_adapter          adapter;
+       struct i2c_algo_bit_data    algo;
+};
+
+struct radeon_ms_connector {
+       struct radeon_ms_i2c    *i2c;
+       struct edid             *edid;
+       struct drm_output       *output;
+       int                     type;
+       int                     monitor_type;
+       int                     crtc;
+       uint32_t                i2c_reg;
+       char                    outputs[RADEON_MAX_OUTPUTS];
+       char                    name[32];
+};
+
+struct radeon_ms_output {
+       int                         type;
+       struct drm_device           *dev;
+       struct radeon_ms_connector  *connector;
+       int (*initialize)(struct radeon_ms_output *output);
+       enum drm_output_status (*detect)(struct radeon_ms_output *output);
+       void (*dpms)(struct radeon_ms_output *output, int mode);
+       int (*get_modes)(struct radeon_ms_output *output);
+       bool (*mode_fixup)(struct radeon_ms_output *output,
+                       struct drm_display_mode *mode,
+                       struct drm_display_mode *adjusted_mode);
+       int (*mode_set)(struct radeon_ms_output *output,
+                       struct drm_display_mode *mode,
+                       struct drm_display_mode *adjusted_mode);
+       void (*restore)(struct radeon_ms_output *output,
+                       struct radeon_state *state);
+       void (*save)(struct radeon_ms_output *output,
+                       struct radeon_state *state);
+};
+
+struct radeon_ms_properties {
+       uint16_t                    subvendor;
+       uint16_t                    subdevice;
+       int16_t                     pll_reference_freq;
+       int32_t                     pll_min_pll_freq;
+       int32_t                     pll_max_pll_freq;
+       char                        pll_use_bios;
+       char                        pll_dummy_reads;
+       char                        pll_delay;
+       char                        pll_r300_errata;
+       struct radeon_ms_output     *outputs[RADEON_MAX_OUTPUTS];
+       struct radeon_ms_connector  *connectors[RADEON_MAX_CONNECTORS];
+};
+
+struct radeon_state {
+       /* memory */
+       uint32_t        config_aper_0_base;
+       uint32_t        config_aper_1_base;
+       uint32_t        config_aper_size;
+       uint32_t        mc_fb_location;
+       uint32_t        display_base_addr;
+       /* irq */
+       uint32_t        gen_int_cntl;
+       /* pci */
+       uint32_t        aic_ctrl;
+       uint32_t        aic_pt_base;
+       uint32_t        aic_pt_base_lo;
+       uint32_t        aic_pt_base_hi;
+       uint32_t        aic_lo_addr;
+       uint32_t        aic_hi_addr;
+       /* agp */
+       uint32_t        agp_cntl;
+       uint32_t        agp_command;
+       uint32_t        agp_base;
+       uint32_t        agp_base_2;
+       uint32_t        bus_cntl;
+       uint32_t        mc_agp_location;
+       /* cp */
+       uint32_t        cp_rb_cntl;
+       uint32_t        cp_rb_base;
+       uint32_t        cp_rb_rptr_addr;
+       uint32_t        cp_rb_wptr;
+       uint32_t        cp_rb_wptr_delay;
+       uint32_t        scratch_umsk;
+       uint32_t        scratch_addr;
+       /* pcie */
+       uint32_t        pcie_tx_gart_cntl;
+       uint32_t        pcie_tx_gart_discard_rd_addr_lo;
+       uint32_t        pcie_tx_gart_discard_rd_addr_hi;
+       uint32_t        pcie_tx_gart_base;
+       uint32_t        pcie_tx_gart_start_lo;
+       uint32_t        pcie_tx_gart_start_hi;
+       uint32_t        pcie_tx_gart_end_lo;
+       uint32_t        pcie_tx_gart_end_hi;
+       /* surface */
+       uint32_t        surface_cntl;
+       uint32_t        surface0_info;
+       uint32_t        surface0_lower_bound;
+       uint32_t        surface0_upper_bound;
+       uint32_t        surface1_info;
+       uint32_t        surface1_lower_bound;
+       uint32_t        surface1_upper_bound;
+       uint32_t        surface2_info;
+       uint32_t        surface2_lower_bound;
+       uint32_t        surface2_upper_bound;
+       uint32_t        surface3_info;
+       uint32_t        surface3_lower_bound;
+       uint32_t        surface3_upper_bound;
+       uint32_t        surface4_info;
+       uint32_t        surface4_lower_bound;
+       uint32_t        surface4_upper_bound;
+       uint32_t        surface5_info;
+       uint32_t        surface5_lower_bound;
+       uint32_t        surface5_upper_bound;
+       uint32_t        surface6_info;
+       uint32_t        surface6_lower_bound;
+       uint32_t        surface6_upper_bound;
+       uint32_t        surface7_info;
+       uint32_t        surface7_lower_bound;
+       uint32_t        surface7_upper_bound;
+       /* crtc */
+       uint32_t        crtc_gen_cntl;
+       uint32_t        crtc_ext_cntl;
+       uint32_t        crtc_h_total_disp;
+       uint32_t        crtc_h_sync_strt_wid;
+       uint32_t        crtc_v_total_disp;
+       uint32_t        crtc_v_sync_strt_wid;
+       uint32_t        crtc_offset;
+       uint32_t        crtc_offset_cntl;
+       uint32_t        crtc_pitch;
+       uint32_t        crtc_more_cntl;
+       uint32_t        crtc_tile_x0_y0;
+       uint32_t        fp_h_sync_strt_wid;
+       uint32_t        fp_v_sync_strt_wid;
+       uint32_t        fp_crtc_h_total_disp;
+       uint32_t        fp_crtc_v_total_disp;
+       /* pll */
+       uint32_t        clock_cntl_index;
+       uint32_t        ppll_cntl;
+       uint32_t        ppll_ref_div;
+       uint32_t        ppll_div_0;
+       uint32_t        ppll_div_1;
+       uint32_t        ppll_div_2;
+       uint32_t        ppll_div_3;
+       uint32_t        vclk_ecp_cntl;
+       uint32_t        htotal_cntl;
+       /* dac */
+       uint32_t        dac_cntl;
+       uint32_t        dac_cntl2;
+       uint32_t        dac_ext_cntl;
+       uint32_t        disp_misc_cntl;
+       uint32_t        dac_macro_cntl;
+       uint32_t        disp_pwr_man;
+       uint32_t        disp_merge_cntl;
+       uint32_t        disp_output_cntl;
+       uint32_t        disp2_merge_cntl;
+       uint32_t        dac_embedded_sync_cntl;
+       uint32_t        dac_broad_pulse;
+       uint32_t        dac_skew_clks;
+       uint32_t        dac_incr;
+       uint32_t        dac_neg_sync_level;
+       uint32_t        dac_pos_sync_level;
+       uint32_t        dac_blank_level;
+       uint32_t        dac_sync_equalization;
+       uint32_t        tv_dac_cntl;
+       uint32_t        tv_master_cntl;
+};
+
+struct drm_radeon_private {
+       /* driver family specific functions */
+       int (*bus_finish)(struct drm_device *dev);
+       int (*bus_init)(struct drm_device *dev);
+       void (*bus_restore)(struct drm_device *dev, struct radeon_state *state);
+       void (*bus_save)(struct drm_device *dev, struct radeon_state *state);
+       struct drm_ttm_backend *(*create_ttm)(struct drm_device *dev);
+       void (*irq_emit)(struct drm_device *dev);
+       void (*flush_cache)(struct drm_device *dev);
+       /* bus informations */
+       void                        *bus;
+       uint32_t                    bus_type;
+       /* cp */
+       uint32_t                    ring_buffer_size;
+       uint32_t                    ring_rptr;
+       uint32_t                    ring_wptr;
+       uint32_t                    ring_mask;
+       int                         ring_free;
+       uint32_t                    ring_tail_mask;
+       uint32_t                    write_back_area_size;
+       struct drm_buffer_object    *ring_buffer_object;
+       struct drm_bo_kmap_obj      ring_buffer_map;
+       uint32_t                    *ring_buffer;
+       uint32_t                    *write_back_area;
+       const uint32_t              *microcode;
+       /* card family */
+       uint32_t                    usec_timeout;
+       uint32_t                    family;
+       struct radeon_ms_properties *properties;
+       struct radeon_ms_output     *outputs[RADEON_MAX_OUTPUTS];
+       struct radeon_ms_connector  *connectors[RADEON_MAX_CONNECTORS];
+       /* drm map (MMIO, FB) */
+       struct drm_map              mmio;
+       struct drm_map              vram;
+       /* gpu address space */
+       uint32_t                    gpu_vram_size;
+       uint32_t                    gpu_vram_start;
+       uint32_t                    gpu_vram_end;
+       uint32_t                    gpu_gart_size;
+       uint32_t                    gpu_gart_start;
+       uint32_t                    gpu_gart_end;
+       /* state of the card when module was loaded */
+       struct radeon_state         load_state;
+       /* state the driver wants */
+       struct radeon_state         driver_state;
+       /* last emitted fence */
+       uint32_t                    fence_id_last;
+       uint32_t                    fence_reg;
+       /* when doing gpu stop we save here current state */
+       uint32_t                    crtc_ext_cntl;
+       uint32_t                    crtc_gen_cntl;
+       uint32_t                    crtc2_gen_cntl;
+       uint32_t                    ov0_scale_cntl;
+       /* bool & type on the hw */
+       uint8_t                     crtc1_dpms;
+       uint8_t                     crtc2_dpms;
+       uint8_t                     restore_state;
+       uint8_t                     cp_ready;
+       uint8_t                     bus_ready;
+       uint8_t                     write_back;
+};
+
+
+/* radeon_ms_bo.c */
+int radeon_ms_bo_get_gpu_addr(struct drm_device *dev,
+                             struct drm_bo_mem_reg *mem,
+                             uint32_t *gpu_addr);
+int radeon_ms_bo_move(struct drm_buffer_object * bo, int evict,
+                     int no_wait, struct drm_bo_mem_reg * new_mem);
+struct drm_ttm_backend *radeon_ms_create_ttm_backend(struct drm_device * dev);
+uint32_t radeon_ms_evict_mask(struct drm_buffer_object *bo);
+int radeon_ms_init_mem_type(struct drm_device * dev, uint32_t type,
+                           struct drm_mem_type_manager * man);
+int radeon_ms_invalidate_caches(struct drm_device * dev, uint64_t flags);
+void radeon_ms_ttm_flush(struct drm_ttm *ttm);
+
+/* radeon_ms_bus.c */
+int radeon_ms_agp_finish(struct drm_device *dev);
+int radeon_ms_agp_init(struct drm_device *dev);
+void radeon_ms_agp_restore(struct drm_device *dev, struct radeon_state *state);
+void radeon_ms_agp_save(struct drm_device *dev, struct radeon_state *state);
+struct drm_ttm_backend *radeon_ms_pcie_create_ttm(struct drm_device *dev);
+int radeon_ms_pcie_finish(struct drm_device *dev);
+int radeon_ms_pcie_init(struct drm_device *dev);
+void radeon_ms_pcie_restore(struct drm_device *dev, struct radeon_state *state);
+void radeon_ms_pcie_save(struct drm_device *dev, struct radeon_state *state);
+
+/* radeon_ms_compat.c */
+long radeon_ms_compat_ioctl(struct file *filp, unsigned int cmd,
+                           unsigned long arg);
+
+/* radeon_ms_cp.c */
+int radeon_ms_cp_finish(struct drm_device *dev);
+int radeon_ms_cp_init(struct drm_device *dev);
+void radeon_ms_cp_restore(struct drm_device *dev, struct radeon_state *state);
+void radeon_ms_cp_save(struct drm_device *dev, struct radeon_state *state);
+void radeon_ms_cp_stop(struct drm_device *dev);
+int radeon_ms_cp_wait(struct drm_device *dev, int n);
+int radeon_ms_ring_emit(struct drm_device *dev, uint32_t *cmd, uint32_t count);
+
+/* radeon_ms_crtc.c */
+int radeon_ms_crtc_create(struct drm_device *dev, int crtc);
+void radeon_ms_crtc1_restore(struct drm_device *dev,
+                            struct radeon_state *state);
+void radeon_ms_crtc1_save(struct drm_device *dev, struct radeon_state *state);
+
+/* radeon_ms_dac.c */
+int radeon_ms_dac1_initialize(struct radeon_ms_output *output);
+enum drm_output_status radeon_ms_dac1_detect(struct radeon_ms_output *output);
+void radeon_ms_dac1_dpms(struct radeon_ms_output *output, int mode);
+int radeon_ms_dac1_get_modes(struct radeon_ms_output *output);
+bool radeon_ms_dac1_mode_fixup(struct radeon_ms_output *output,
+               struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode);
+int radeon_ms_dac1_mode_set(struct radeon_ms_output *output,
+               struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode);
+void radeon_ms_dac1_restore(struct radeon_ms_output *output,
+               struct radeon_state *state);
+void radeon_ms_dac1_save(struct radeon_ms_output *output,
+               struct radeon_state *state);
+int radeon_ms_dac2_initialize(struct radeon_ms_output *output);
+enum drm_output_status radeon_ms_dac2_detect(struct radeon_ms_output *output);
+void radeon_ms_dac2_dpms(struct radeon_ms_output *output, int mode);
+int radeon_ms_dac2_get_modes(struct radeon_ms_output *output);
+bool radeon_ms_dac2_mode_fixup(struct radeon_ms_output *output,
+               struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode);
+int radeon_ms_dac2_mode_set(struct radeon_ms_output *output,
+               struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode);
+void radeon_ms_dac2_restore(struct radeon_ms_output *output,
+               struct radeon_state *state);
+void radeon_ms_dac2_save(struct radeon_ms_output *output,
+               struct radeon_state *state);
+
+/* radeon_ms_drm.c */
+int radeon_ms_driver_dma_ioctl(struct drm_device *dev, void *data,
+                              struct drm_file *file_priv);
+void radeon_ms_driver_lastclose(struct drm_device * dev);
+int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags);
+int radeon_ms_driver_open(struct drm_device * dev, struct drm_file *file_priv);
+int radeon_ms_driver_unload(struct drm_device *dev);
+
+/* radeon_ms_exec.c */
+int radeon_ms_execbuffer(struct drm_device *dev, void *data,
+                        struct drm_file *file_priv);
+
+/* radeon_ms_family.c */
+int radeon_ms_family_init(struct drm_device *dev);
+
+/* radeon_ms_fence.c */
+int radeon_ms_fence_emit_sequence(struct drm_device *dev, uint32_t class,
+                                 uint32_t flags, uint32_t *sequence,
+                                 uint32_t *native_type);
+void radeon_ms_fence_handler(struct drm_device * dev);
+int radeon_ms_fence_has_irq(struct drm_device *dev, uint32_t class,
+                           uint32_t flags);
+int radeon_ms_fence_types(struct drm_buffer_object *bo,
+                         uint32_t * class, uint32_t * type);
+void radeon_ms_poke_flush(struct drm_device * dev, uint32_t class);
+
+/* radeon_ms_fb.c */
+int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc);
+int radeonfb_remove(struct drm_device *dev, struct drm_crtc *crtc);
+
+/* radeon_ms_gpu.c */
+int radeon_ms_gpu_initialize(struct drm_device *dev);
+void radeon_ms_gpu_dpms(struct drm_device *dev);
+void radeon_ms_gpu_flush(struct drm_device *dev);
+void radeon_ms_gpu_restore(struct drm_device *dev, struct radeon_state *state);
+void radeon_ms_gpu_save(struct drm_device *dev, struct radeon_state *state);
+int radeon_ms_wait_for_idle(struct drm_device *dev);
+
+/* radeon_ms_i2c.c */
+void radeon_ms_i2c_destroy(struct radeon_ms_i2c *i2c);
+struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev,
+                                          const uint32_t reg,
+                                          const char *name);
+
+/* radeon_ms_irq.c */
+void radeon_ms_irq_emit(struct drm_device *dev);
+irqreturn_t radeon_ms_irq_handler(DRM_IRQ_ARGS);
+void radeon_ms_irq_preinstall(struct drm_device * dev);
+void radeon_ms_irq_postinstall(struct drm_device * dev);
+int radeon_ms_irq_init(struct drm_device *dev);
+void radeon_ms_irq_restore(struct drm_device *dev, struct radeon_state *state);
+void radeon_ms_irq_save(struct drm_device *dev, struct radeon_state *state);
+void radeon_ms_irq_uninstall(struct drm_device * dev);
+
+/* radeon_ms_output.c */
+void radeon_ms_connectors_destroy(struct drm_device *dev);
+int radeon_ms_connectors_from_properties(struct drm_device *dev);
+void radeon_ms_outputs_destroy(struct drm_device *dev);
+int radeon_ms_outputs_from_properties(struct drm_device *dev);
+void radeon_ms_outputs_restore(struct drm_device *dev,
+               struct radeon_state *state);
+void radeon_ms_outputs_save(struct drm_device *dev, struct radeon_state *state);
+
+/* radeon_ms_state.c */
+void radeon_ms_state_save(struct drm_device *dev, struct radeon_state *state);
+void radeon_ms_state_restore(struct drm_device *dev,
+                            struct radeon_state *state);
+
+
+/* packect stuff **************************************************************/
+#define RADEON_CP_PACKET0                               0x00000000
+#define CP_PACKET0(reg, n)                                             \
+       (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
+#define CP_PACKET3_CNTL_BITBLT_MULTI                    0xC0009B00
+#    define GMC_SRC_PITCH_OFFSET_CNTL                       (1    <<  0)
+#    define GMC_DST_PITCH_OFFSET_CNTL                       (1    <<  1)
+#    define GMC_BRUSH_NONE                                  (15   <<  4)
+#    define GMC_SRC_DATATYPE_COLOR                          (3    << 12)
+#    define ROP3_S                                          0x00cc0000
+#    define DP_SRC_SOURCE_MEMORY                            (2    << 24)
+#    define GMC_CLR_CMP_CNTL_DIS                            (1    << 28)
+#    define GMC_WR_MSK_DIS                                  (1    << 30)
+
+/* helper macro & functions ***************************************************/
+#define REG_S(rn, bn, v)    (((v) << rn##__##bn##__SHIFT) & rn##__##bn##__MASK)
+#define REG_G(rn, bn, v)    (((v) & rn##__##bn##__MASK) >> rn##__##bn##__SHIFT)
+#define MMIO_R(rid)         mmio_read(dev_priv, rid)
+#define MMIO_W(rid, v)      mmio_write(dev_priv, rid, v)
+#define PCIE_R(rid)         pcie_read(dev_priv, rid)
+#define PCIE_W(rid, v)      pcie_write(dev_priv, rid, v)
+#define PPLL_R(rid)         pll_read(dev_priv, rid)
+#define PPLL_W(rid, v)      pll_write(dev_priv, rid, v)
+
+static __inline__ uint32_t mmio_read(struct drm_radeon_private *dev_priv,
+                                    uint32_t offset)
+{
+       return DRM_READ32(&dev_priv->mmio, offset);
+}
+
+
+static __inline__ void mmio_write(struct drm_radeon_private *dev_priv,
+                                 uint32_t offset, uint32_t v)
+{
+       DRM_WRITE32(&dev_priv->mmio, offset, v);
+}
+
+static __inline__ uint32_t pcie_read(struct drm_radeon_private *dev_priv,
+                                    uint32_t offset)
+{
+       MMIO_W(PCIE_INDEX, REG_S(PCIE_INDEX, PCIE_INDEX, offset));
+       return MMIO_R(PCIE_DATA);
+}
+
+static __inline__ void pcie_write(struct drm_radeon_private *dev_priv,
+                                 uint32_t offset, uint32_t v)
+{
+       MMIO_W(PCIE_INDEX, REG_S(PCIE_INDEX, PCIE_INDEX, offset));
+       MMIO_W(PCIE_DATA, v);
+}
+
+static __inline__ void pll_index_errata(struct drm_radeon_private *dev_priv)
+{
+       uint32_t tmp, save;
+
+       /* This workaround is necessary on rv200 and RS200 or PLL
+        * reads may return garbage (among others...)
+        */
+       if (dev_priv->properties->pll_dummy_reads) {
+               tmp = MMIO_R(CLOCK_CNTL_DATA);
+               tmp = MMIO_R(CRTC_GEN_CNTL);
+       }
+       /* This function is required to workaround a hardware bug in some (all?)
+        * revisions of the R300.  This workaround should be called after every
+        * CLOCK_CNTL_INDEX register access.  If not, register reads afterward
+        * may not be correct.
+        */
+       if (dev_priv->properties->pll_r300_errata) {
+               tmp = save = MMIO_R(CLOCK_CNTL_INDEX);
+               tmp = tmp & ~CLOCK_CNTL_INDEX__PLL_ADDR__MASK;
+               tmp = tmp & ~CLOCK_CNTL_INDEX__PLL_WR_EN;
+               MMIO_W(CLOCK_CNTL_INDEX, tmp);
+               tmp = MMIO_R(CLOCK_CNTL_DATA);
+               MMIO_W(CLOCK_CNTL_INDEX, save);
+       }
+}
+
+static __inline__ void pll_data_errata(struct drm_radeon_private *dev_priv)
+{
+       /* This workarounds is necessary on RV100, RS100 and RS200 chips
+        * or the chip could hang on a subsequent access
+        */
+       if (dev_priv->properties->pll_delay) {
+               /* we can't deal with posted writes here ... */
+               udelay(5000);
+       }
+}
+
+static __inline__ uint32_t pll_read(struct drm_radeon_private *dev_priv,
+                                   uint32_t offset)
+{
+       uint32_t clock_cntl_index = dev_priv->driver_state.clock_cntl_index;
+       uint32_t data;
+
+       clock_cntl_index &= ~CLOCK_CNTL_INDEX__PLL_ADDR__MASK;
+       clock_cntl_index |= REG_S(CLOCK_CNTL_INDEX, PLL_ADDR, offset);
+       MMIO_W(CLOCK_CNTL_INDEX, clock_cntl_index);
+       pll_index_errata(dev_priv);
+       data = MMIO_R(CLOCK_CNTL_DATA);
+       pll_data_errata(dev_priv);
+       return data;
+}
+
+static __inline__ void pll_write(struct drm_radeon_private *dev_priv,
+                                uint32_t offset, uint32_t value)
+{
+       uint32_t clock_cntl_index = dev_priv->driver_state.clock_cntl_index;
+
+       clock_cntl_index &= ~CLOCK_CNTL_INDEX__PLL_ADDR__MASK;
+       clock_cntl_index |= REG_S(CLOCK_CNTL_INDEX, PLL_ADDR, offset);
+       clock_cntl_index |= CLOCK_CNTL_INDEX__PLL_WR_EN;
+       MMIO_W(CLOCK_CNTL_INDEX, clock_cntl_index);
+       pll_index_errata(dev_priv);
+       MMIO_W(CLOCK_CNTL_DATA, value);
+       pll_data_errata(dev_priv);
+}
+
+#endif
diff --git a/shared-core/radeon_ms_bo.c b/shared-core/radeon_ms_bo.c
new file mode 100644 (file)
index 0000000..cedad68
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2007 Dave Airlie
+ * Copyright 2007 Jérôme Glisse
+ * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ *    Dave Airlie <airlied@linux.ie>
+ *    Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "drmP.h"
+#include "drm.h"
+
+#include "radeon_ms.h"
+
+void radeon_ms_bo_copy_blit(struct drm_device *dev,
+                           uint32_t src_offset,
+                           uint32_t dst_offset,
+                           uint32_t pages)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       uint32_t num_pages, stride, c;
+       uint32_t offset_inc = 0;
+       uint32_t cmd[7];
+
+       if (!dev_priv) {
+               return;
+       }
+
+       /* radeon limited to 16320=255*64 bytes per row so copy at
+        * most 2 pages */
+       num_pages = 2;
+       stride = ((num_pages * PAGE_SIZE) / 64) & 0xff;
+       while(pages > 0) {
+               if (num_pages > pages) {
+                       num_pages = pages;
+                       stride = ((num_pages * PAGE_SIZE) / 64) & 0xff;
+               }
+               c = pages / num_pages;
+               if (c >= 8192) {
+                       c = 8191;
+               }
+               cmd[0] = CP_PACKET3_CNTL_BITBLT_MULTI | (5 << 16);
+               cmd[1] = GMC_SRC_PITCH_OFFSET_CNTL |
+                        GMC_DST_PITCH_OFFSET_CNTL |
+                        GMC_BRUSH_NONE |
+                        (0x6 << 8) |
+                        GMC_SRC_DATATYPE_COLOR |
+                        ROP3_S |
+                        DP_SRC_SOURCE_MEMORY |
+                        GMC_CLR_CMP_CNTL_DIS |
+                        GMC_WR_MSK_DIS;
+               cmd[2] = (stride << 22) | (src_offset >> 10);
+               cmd[3] = (stride << 22) | (dst_offset >> 10);
+               cmd[4] = (0 << 16) | 0;
+               cmd[5] = (0 << 16) | 0;
+               cmd[6] = ((stride * 16) << 16) | c;
+               radeon_ms_ring_emit(dev, cmd, 7);
+               offset_inc = num_pages * c * PAGE_SIZE;
+               src_offset += offset_inc;
+               dst_offset += offset_inc;
+               pages -= num_pages * c;
+       }
+       /* wait for 2d engine to go busy so wait_until stall */
+       for (c = 0; c < dev_priv->usec_timeout; c++) {
+               uint32_t status = MMIO_R(RBBM_STATUS);
+               if ((RBBM_STATUS__E2_BUSY & status) ||
+                   (RBBM_STATUS__CBA2D_BUSY & status)) {
+                       DRM_INFO("[radeon_ms] RBBM_STATUS 0x%08X\n", status);
+                       break;
+               }
+               DRM_UDELAY(1);
+       }
+       /* Sync everything up */
+       cmd[0] = CP_PACKET0(WAIT_UNTIL, 0);
+       cmd[1] = WAIT_UNTIL__WAIT_2D_IDLECLEAN |
+                WAIT_UNTIL__WAIT_HOST_IDLECLEAN;
+       radeon_ms_ring_emit(dev, cmd, 2);
+       return;
+}
+
+static int radeon_ms_bo_move_blit(struct drm_buffer_object *bo,
+                                 int evict, int no_wait,
+                                 struct drm_bo_mem_reg *new_mem)
+{
+       struct drm_device *dev = bo->dev;
+       struct drm_bo_mem_reg *old_mem = &bo->mem;
+       uint32_t gpu_src_addr;
+       uint32_t gpu_dst_addr;
+       int ret;
+
+       ret = radeon_ms_bo_get_gpu_addr(dev, old_mem, &gpu_src_addr);
+       if (ret) {
+               return ret;
+       }
+       ret = radeon_ms_bo_get_gpu_addr(dev, new_mem, &gpu_dst_addr);
+       if (ret) {
+               return ret;
+       }
+
+       radeon_ms_bo_copy_blit(bo->dev,
+                              gpu_src_addr,
+                              gpu_dst_addr,
+                              new_mem->num_pages);
+       
+       ret = drm_bo_move_accel_cleanup(bo, evict, no_wait, 0,
+                                        DRM_FENCE_TYPE_EXE |
+                                        DRM_RADEON_FENCE_TYPE_RW,
+                                        DRM_RADEON_FENCE_FLAG_FLUSHED,
+                                        new_mem);
+       return ret;
+}
+
+static int radeon_ms_bo_move_flip(struct drm_buffer_object *bo,
+                                 int evict, int no_wait,
+                                 struct drm_bo_mem_reg *new_mem)
+{
+       struct drm_device *dev = bo->dev;
+       struct drm_bo_mem_reg tmp_mem;
+       int ret;
+
+       tmp_mem = *new_mem;
+       tmp_mem.mm_node = NULL;
+       tmp_mem.mask = DRM_BO_FLAG_MEM_TT |
+                      DRM_BO_FLAG_CACHED |
+                      DRM_BO_FLAG_FORCE_CACHING;
+       ret = drm_bo_mem_space(bo, &tmp_mem, no_wait);
+       if (ret) {
+               return ret;
+       }
+
+       ret = drm_bind_ttm(bo->ttm, &tmp_mem);
+       if (ret) {
+               goto out_cleanup;
+       }
+       ret = radeon_ms_bo_move_blit(bo, 1, no_wait, &tmp_mem);
+       if (ret) {
+               goto out_cleanup;
+       }
+       ret = drm_bo_move_ttm(bo, evict, no_wait, new_mem);
+out_cleanup:
+       if (tmp_mem.mm_node) {
+               mutex_lock(&dev->struct_mutex);
+               if (tmp_mem.mm_node != bo->pinned_node)
+                       drm_mm_put_block(tmp_mem.mm_node);
+               tmp_mem.mm_node = NULL;
+               mutex_unlock(&dev->struct_mutex);
+       }
+       return ret;
+}
+
+int radeon_ms_bo_get_gpu_addr(struct drm_device *dev,
+                             struct drm_bo_mem_reg *mem,
+                             uint32_t *gpu_addr)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       *gpu_addr = mem->mm_node->start << PAGE_SHIFT;
+       switch (mem->flags & DRM_BO_MASK_MEM) {
+       case DRM_BO_FLAG_MEM_TT:
+               *gpu_addr +=  dev_priv->gpu_gart_start;
+               DRM_INFO("[radeon_ms] GPU TT: 0x%08X\n", *gpu_addr);
+               break;
+       case DRM_BO_FLAG_MEM_VRAM:
+               *gpu_addr +=  dev_priv->gpu_vram_start;
+               DRM_INFO("[radeon_ms] GPU VRAM: 0x%08X\n", *gpu_addr);
+               break;
+       default:
+               DRM_ERROR("[radeon_ms] memory not accessible by GPU\n");
+               return -EINVAL;
+       }
+       return 0;
+}
+
+int radeon_ms_bo_move(struct drm_buffer_object *bo, int evict,
+                  int no_wait, struct drm_bo_mem_reg *new_mem)
+{
+       struct drm_bo_mem_reg *old_mem = &bo->mem;
+       if (old_mem->mem_type == DRM_BO_MEM_LOCAL) {
+               return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
+       } else if (new_mem->mem_type == DRM_BO_MEM_LOCAL) {
+               if (radeon_ms_bo_move_flip(bo, evict, no_wait, new_mem))
+                       return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
+       } else {
+               if (radeon_ms_bo_move_blit(bo, evict, no_wait, new_mem))
+                       return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
+       }
+       return 0;
+}
+
+struct drm_ttm_backend *radeon_ms_create_ttm_backend(struct drm_device * dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       if (dev_priv && dev_priv->create_ttm)
+               return dev_priv->create_ttm(dev);
+       return NULL;
+}
+
+uint32_t radeon_ms_evict_mask(struct drm_buffer_object *bo)
+{
+       switch (bo->mem.mem_type) {
+       case DRM_BO_MEM_LOCAL:
+       case DRM_BO_MEM_TT:
+               return DRM_BO_FLAG_MEM_LOCAL;
+       case DRM_BO_MEM_VRAM:
+               if (bo->mem.num_pages > 128)
+                       return DRM_BO_MEM_TT;
+               else
+                       return DRM_BO_MEM_LOCAL;
+       default:
+               return DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_CACHED;
+       }
+}
+
+int radeon_ms_init_mem_type(struct drm_device * dev, uint32_t type,
+                           struct drm_mem_type_manager * man)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       switch (type) {
+       case DRM_BO_MEM_LOCAL:
+               man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
+                   _DRM_FLAG_MEMTYPE_CACHED;
+               man->drm_bus_maptype = 0;
+               break;
+       case DRM_BO_MEM_VRAM:
+               man->flags =  _DRM_FLAG_MEMTYPE_FIXED |
+                             _DRM_FLAG_MEMTYPE_MAPPABLE |
+                             _DRM_FLAG_NEEDS_IOREMAP;
+               man->io_addr = NULL;
+               man->drm_bus_maptype = _DRM_FRAME_BUFFER;
+               man->io_offset = dev_priv->vram.offset;
+               man->io_size = dev_priv->vram.size;
+               break;
+       case DRM_BO_MEM_TT:
+               if (!dev_priv->bus_ready) {
+                       DRM_ERROR("Bus isn't initialized while "
+                                 "intializing TT memory type\n");
+                       return -EINVAL;
+               }
+               switch(dev_priv->bus_type) {
+               case RADEON_AGP:
+                       if (!(drm_core_has_AGP(dev) && dev->agp)) {
+                               DRM_ERROR("AGP is not enabled for memory "
+                                         "type %u\n", (unsigned)type);
+                               return -EINVAL;
+                       }
+                       man->io_offset = dev->agp->agp_info.aper_base;
+                       man->io_size = dev->agp->agp_info.aper_size *
+                                      1024 * 1024;
+                       man->io_addr = NULL;
+                       man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
+                                    _DRM_FLAG_MEMTYPE_CSELECT |
+                                    _DRM_FLAG_NEEDS_IOREMAP;
+                       man->drm_bus_maptype = _DRM_AGP;
+                       man->gpu_offset = 0;
+                       break;
+               default:
+                       man->io_offset = dev_priv->gpu_gart_start;
+                       man->io_size = dev_priv->gpu_gart_size;
+                       man->io_addr = NULL;
+                       man->flags = _DRM_FLAG_MEMTYPE_CSELECT |
+                                    _DRM_FLAG_MEMTYPE_MAPPABLE |
+                                    _DRM_FLAG_MEMTYPE_CMA;
+                       man->drm_bus_maptype = _DRM_SCATTER_GATHER;
+                       break;
+               }
+               break;
+       default:
+               DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+int radeon_ms_invalidate_caches(struct drm_device * dev, uint64_t flags)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       dev_priv->flush_cache(dev);
+       return 0;
+}
+
+void radeon_ms_ttm_flush(struct drm_ttm *ttm)
+{
+       if (!ttm)
+               return;
+
+       DRM_MEMORYBARRIER();
+}
diff --git a/shared-core/radeon_ms_bus.c b/shared-core/radeon_ms_bus.c
new file mode 100644 (file)
index 0000000..6a782b1
--- /dev/null
@@ -0,0 +1,443 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Alex Deucher
+ * Copyright 2007 Dave Airlie
+ * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ *    Dave Airlie <airlied@linux.ie>
+ *    Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_ms.h"
+
+struct radeon_pcie {
+       uint32_t                    gart_table_size;
+       struct drm_buffer_object    *gart_table_object;
+       volatile uint32_t           *gart_table;
+       struct drm_device           *dev;
+       unsigned long               page_last;
+};
+
+struct radeon_pcie_gart {
+       struct drm_ttm_backend  backend;
+       struct radeon_pcie      *pcie;
+       unsigned long           page_first;
+       struct page             **pages;
+       unsigned long           num_pages;
+       int                     populated;
+       int                     bound;
+};
+
+static int pcie_ttm_bind(struct drm_ttm_backend *backend,
+                        struct drm_bo_mem_reg *bo_mem);
+static void pcie_ttm_clear(struct drm_ttm_backend *backend);
+static void pcie_ttm_destroy(struct drm_ttm_backend *backend);
+static int pcie_ttm_needs_ub_cache_adjust(struct drm_ttm_backend *backend);
+static int pcie_ttm_populate(struct drm_ttm_backend *backend,
+                            unsigned long num_pages, struct page **pages);
+static int pcie_ttm_unbind(struct drm_ttm_backend *backend);
+
+static struct drm_ttm_backend_func radeon_pcie_gart_ttm_backend = 
+{
+       .needs_ub_cache_adjust = pcie_ttm_needs_ub_cache_adjust,
+       .populate = pcie_ttm_populate,
+       .clear = pcie_ttm_clear,
+       .bind = pcie_ttm_bind,
+       .unbind = pcie_ttm_unbind,
+       .destroy =  pcie_ttm_destroy,
+};
+
+static void pcie_gart_flush(struct radeon_pcie *pcie)
+{
+       struct drm_device *dev;
+       struct drm_radeon_private *dev_priv;
+       uint32_t flush;
+
+       if (pcie == NULL) {
+               return;
+       }
+       dev = pcie->dev;
+       dev_priv = dev->dev_private;
+       flush = dev_priv->driver_state.pcie_tx_gart_cntl;
+       flush |= PCIE_TX_GART_CNTL__GART_INVALIDATE_TLB;
+       PCIE_W(PCIE_TX_GART_CNTL, flush);
+       PCIE_W(PCIE_TX_GART_CNTL, dev_priv->driver_state.pcie_tx_gart_cntl);
+}
+
+static __inline__ uint32_t pcie_gart_get_page_base(struct radeon_pcie *pcie,
+                                                  unsigned long page)
+{
+       if (pcie == NULL || pcie->gart_table == NULL) {
+               return 0;
+       }
+       return ((pcie->gart_table[page] & (~0xC)) << 8);
+}
+
+static __inline__ void pcie_gart_set_page_base(struct radeon_pcie *pcie,
+                                              unsigned long page,
+                                              uint32_t page_base)
+{
+       if (pcie == NULL || pcie->gart_table == NULL) {
+               return;
+       }
+       pcie->gart_table[page] = cpu_to_le32((page_base >> 8) | 0xC);
+}
+
+static int pcie_ttm_bind(struct drm_ttm_backend *backend,
+                        struct drm_bo_mem_reg *bo_mem)
+{
+       struct radeon_pcie_gart *pcie_gart;
+       unsigned long page_first;
+       unsigned long page_last;
+       unsigned long page, i;
+       uint32_t page_base;
+
+       pcie_gart = container_of(backend, struct radeon_pcie_gart, backend);
+       page = page_first = bo_mem->mm_node->start;
+       page_last = page_first + pcie_gart->num_pages;
+       if (page_first >= pcie_gart->pcie->page_last ||
+           page_last >= pcie_gart->pcie->page_last)
+           return -EINVAL;
+        while (page < page_last) {
+               if (pcie_gart_get_page_base(pcie_gart->pcie, page)) {
+                       return -EBUSY;
+               }
+                page++;
+        }
+
+        for (i = 0, page = page_first; i < pcie_gart->num_pages; i++, page++) {
+               struct page *cur_page = pcie_gart->pages[i];
+                /* write value */
+               page_base = page_to_phys(cur_page);
+               pcie_gart_set_page_base(pcie_gart->pcie, page, page_base);
+        }
+       DRM_MEMORYBARRIER();
+       pcie_gart_flush(pcie_gart->pcie);
+       pcie_gart->bound = 1;
+       pcie_gart->page_first = page_first;
+       return 0;
+}
+
+static void pcie_ttm_clear(struct drm_ttm_backend *backend)
+{
+       struct radeon_pcie_gart *pcie_gart;
+
+       pcie_gart = container_of(backend, struct radeon_pcie_gart, backend);
+       if (pcie_gart->pages) {
+               backend->func->unbind(backend);
+               pcie_gart->pages = NULL;
+       }
+       pcie_gart->num_pages = 0;
+}
+
+static void pcie_ttm_destroy(struct drm_ttm_backend *backend)
+{
+       struct radeon_pcie_gart *pcie_gart;
+
+       if (backend == NULL) {
+               return;
+       }
+       pcie_gart = container_of(backend, struct radeon_pcie_gart, backend);
+       if (pcie_gart->pages) {
+               backend->func->clear(backend);
+       }
+       drm_ctl_free(pcie_gart, sizeof(*pcie_gart), DRM_MEM_TTM);
+}
+
+static int pcie_ttm_needs_ub_cache_adjust(struct drm_ttm_backend *backend)
+{
+       return ((backend->flags & DRM_BE_FLAG_BOUND_CACHED) ? 0 : 1);
+}
+
+static int pcie_ttm_populate(struct drm_ttm_backend *backend,
+                            unsigned long num_pages, struct page **pages)
+{
+       struct radeon_pcie_gart *pcie_gart;
+
+       pcie_gart = container_of(backend, struct radeon_pcie_gart, backend);
+       pcie_gart->pages = pages;
+       pcie_gart->num_pages = num_pages;
+       pcie_gart->populated = 1;
+       return 0;
+}
+
+static int pcie_ttm_unbind(struct drm_ttm_backend *backend)
+{
+       struct radeon_pcie_gart *pcie_gart;
+       unsigned long page, i;
+
+       pcie_gart = container_of(backend, struct radeon_pcie_gart, backend);
+       if (pcie_gart->bound != 1 || pcie_gart->pcie->gart_table == NULL) {
+               return -EINVAL;
+       }
+       for (i = 0, page = pcie_gart->page_first; i < pcie_gart->num_pages;
+            i++, page++) {
+               pcie_gart->pcie->gart_table[page] = 0;
+       }
+       pcie_gart_flush(pcie_gart->pcie);
+       pcie_gart->bound = 0;
+       pcie_gart->page_first = 0;
+       return 0;
+}
+
+int radeon_ms_agp_finish(struct drm_device *dev)
+{
+       drm_agp_release(dev);
+       return 0;
+}
+
+int radeon_ms_agp_init(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+       struct drm_agp_mode mode;
+       uint32_t agp_status;
+       int ret;
+
+       if (dev->agp == NULL) {
+               DRM_ERROR("[radeon_ms] can't initialize AGP\n");
+               return -EINVAL;
+       }
+       ret = drm_agp_acquire(dev);
+       if (ret) {
+               DRM_ERROR("[radeon_ms] error failed to acquire agp\n");
+               return ret;
+       }
+       agp_status = MMIO_R(AGP_STATUS);
+       if ((AGP_STATUS__MODE_AGP30 & agp_status)) {
+               mode.mode = AGP_STATUS__RATE4X;
+       } else {
+               mode.mode = AGP_STATUS__RATE2X_8X;
+       }
+       ret = drm_agp_enable(dev, mode);
+       if (ret) {
+               DRM_ERROR("[radeon_ms] error failed to enable agp\n");
+               return ret;
+       }
+       state->agp_command = MMIO_R(AGP_COMMAND) | AGP_COMMAND__AGP_EN;
+       state->agp_command &= ~AGP_COMMAND__FW_EN;
+       state->agp_command &= ~AGP_COMMAND__MODE_4G_EN;
+       state->aic_ctrl = 0;
+       state->agp_base = REG_S(AGP_BASE, AGP_BASE_ADDR, dev->agp->base);
+       state->agp_base_2 = 0;
+       state->bus_cntl = MMIO_R(BUS_CNTL);
+       state->bus_cntl &= ~BUS_CNTL__BUS_MASTER_DIS;
+       state->mc_agp_location =
+               REG_S(MC_AGP_LOCATION, MC_AGP_START,
+                               dev_priv->gpu_gart_start >> 16) |
+               REG_S(MC_AGP_LOCATION, MC_AGP_TOP,
+                               dev_priv->gpu_gart_end >> 16);
+       DRM_INFO("[radeon_ms] gpu agp base 0x%08X\n", MMIO_R(AGP_BASE));
+       DRM_INFO("[radeon_ms] gpu agp location 0x%08X\n",
+                MMIO_R(MC_AGP_LOCATION));
+       DRM_INFO("[radeon_ms] gpu agp location 0x%08X\n",
+                state->mc_agp_location);
+       DRM_INFO("[radeon_ms] bus ready\n");
+       return 0;
+}
+
+void radeon_ms_agp_restore(struct drm_device *dev, struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       MMIO_W(MC_AGP_LOCATION, state->mc_agp_location);
+       MMIO_W(AGP_BASE, state->agp_base);
+       MMIO_W(AGP_BASE_2, state->agp_base_2);
+       MMIO_W(AGP_COMMAND, state->agp_command);
+}
+
+void radeon_ms_agp_save(struct drm_device *dev, struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       state->agp_command = MMIO_R(AGP_COMMAND);
+       state->agp_base = MMIO_R(AGP_BASE);
+       state->agp_base_2 = MMIO_R(AGP_BASE_2);
+       state->mc_agp_location = MMIO_R(MC_AGP_LOCATION);
+}
+
+struct drm_ttm_backend *radeon_ms_pcie_create_ttm(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct radeon_pcie_gart *pcie_gart;
+
+       pcie_gart = drm_ctl_calloc(1, sizeof (*pcie_gart), DRM_MEM_TTM);
+       if (pcie_gart == NULL) {
+               return NULL;
+       }
+       memset(pcie_gart, 0, sizeof(struct radeon_pcie_gart));
+       pcie_gart->populated = 0;
+       pcie_gart->pcie = dev_priv->bus;
+       pcie_gart->backend.func = &radeon_pcie_gart_ttm_backend;
+
+       return &pcie_gart->backend;
+}
+
+int radeon_ms_pcie_finish(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct radeon_pcie *pcie = dev_priv->bus;
+
+       if (!dev_priv->bus_ready || pcie == NULL) {
+               dev_priv->bus_ready = 0;
+               return 0;
+       }
+       dev_priv->bus_ready = 0;
+       if (pcie->gart_table) {
+               drm_mem_reg_iounmap(dev, &pcie->gart_table_object->mem,
+                                   (void *)pcie->gart_table);
+       }
+       pcie->gart_table = NULL;
+       if (pcie->gart_table_object) {
+               mutex_lock(&dev->struct_mutex);
+               drm_bo_usage_deref_locked(&pcie->gart_table_object);
+               mutex_unlock(&dev->struct_mutex);
+       }
+       dev_priv->bus = NULL;
+       drm_free(pcie, sizeof(*pcie), DRM_MEM_DRIVER);
+       return 0;
+}
+
+int radeon_ms_pcie_init(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+       struct radeon_pcie *pcie;
+       int ret = 0;
+
+       /* allocate and clear device private structure */
+       pcie = drm_alloc(sizeof(struct radeon_pcie), DRM_MEM_DRIVER);
+       if (pcie == NULL) {
+               return -ENOMEM;
+       }
+       memset(pcie, 0, sizeof(struct radeon_pcie));
+       pcie->dev = dev;
+       dev_priv->bus = (void *)pcie;
+       pcie->gart_table_size = (dev_priv->gpu_gart_size / RADEON_PAGE_SIZE) *
+                               4;
+       /* gart table start must be aligned on 16bytes, align it on one page */
+       ret = drm_buffer_object_create(dev,
+                                      pcie->gart_table_size,
+                                      drm_bo_type_kernel,
+                                      DRM_BO_FLAG_READ |
+                                      DRM_BO_FLAG_WRITE |
+                                      DRM_BO_FLAG_MEM_VRAM |
+                                      DRM_BO_FLAG_NO_EVICT,
+                                      DRM_BO_HINT_DONT_FENCE,
+                                      1,
+                                      0,
+                                      &pcie->gart_table_object);
+       if (ret) {
+               return ret;
+       }
+       ret = drm_mem_reg_ioremap(dev, &pcie->gart_table_object->mem,
+                                 (void **) &pcie->gart_table);
+       if (ret) {
+               DRM_ERROR("[radeon_ms] error mapping gart table: %d\n", ret);
+               return ret;
+       }
+       DRM_INFO("[radeon_ms] gart table in vram at 0x%08lX\n",
+                pcie->gart_table_object->offset);
+       memset((void *)pcie->gart_table, 0, pcie->gart_table_size);
+       pcie->page_last = pcie->gart_table_size >> 2;
+       state->pcie_tx_gart_discard_rd_addr_lo =
+               REG_S(PCIE_TX_GART_DISCARD_RD_ADDR_LO,
+                               GART_DISCARD_RD_ADDR_LO,
+                               dev_priv->gpu_gart_start);
+       state->pcie_tx_gart_discard_rd_addr_hi =
+               REG_S(PCIE_TX_GART_DISCARD_RD_ADDR_HI,
+                               GART_DISCARD_RD_ADDR_HI, 0);
+       state->pcie_tx_gart_base =
+               REG_S(PCIE_TX_GART_BASE, GART_BASE,
+                               pcie->gart_table_object->offset);
+       state->pcie_tx_gart_start_lo =
+               REG_S(PCIE_TX_GART_START_LO, GART_START_LO,
+                               dev_priv->gpu_gart_start);
+       state->pcie_tx_gart_start_hi =
+               REG_S(PCIE_TX_GART_START_HI, GART_START_HI, 0);
+       state->pcie_tx_gart_end_lo =
+               REG_S(PCIE_TX_GART_END_LO, GART_END_LO, dev_priv->gpu_gart_end);
+       state->pcie_tx_gart_end_hi =
+               REG_S(PCIE_TX_GART_END_HI, GART_END_HI, 0);
+       /* FIXME: why this ? */
+       state->aic_ctrl = 0;
+       state->agp_base = 0; 
+       state->agp_base_2 = 0; 
+       state->bus_cntl = MMIO_R(BUS_CNTL);
+       state->mc_agp_location = REG_S(MC_AGP_LOCATION, MC_AGP_START, 0xffc0) |
+                                REG_S(MC_AGP_LOCATION, MC_AGP_TOP, 0xffff);
+       state->pcie_tx_gart_cntl =
+               PCIE_TX_GART_CNTL__GART_EN |
+               REG_S(PCIE_TX_GART_CNTL, GART_UNMAPPED_ACCESS,
+                               GART_UNMAPPED_ACCESS__DISCARD) |
+               REG_S(PCIE_TX_GART_CNTL, GART_MODE, GART_MODE__CACHE_32x128) |
+               REG_S(PCIE_TX_GART_CNTL, GART_RDREQPATH_SEL,
+                               GART_RDREQPATH_SEL__HDP);
+       DRM_INFO("[radeon_ms] gpu gart start 0x%08X\n",
+                PCIE_R(PCIE_TX_GART_START_LO));
+       DRM_INFO("[radeon_ms] gpu gart end   0x%08X\n",
+                PCIE_R(PCIE_TX_GART_END_LO));
+       DRM_INFO("[radeon_ms] bus ready\n");
+       return 0;
+}
+
+void radeon_ms_pcie_restore(struct drm_device *dev, struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       /* disable gart before programing other registers */
+       radeon_ms_agp_restore(dev, state);
+       PCIE_W(PCIE_TX_GART_CNTL, 0);
+       PCIE_W(PCIE_TX_GART_BASE, state->pcie_tx_gart_base);
+       PCIE_W(PCIE_TX_GART_BASE, state->pcie_tx_gart_base);
+       PCIE_W(PCIE_TX_GART_DISCARD_RD_ADDR_HI,
+              state->pcie_tx_gart_discard_rd_addr_hi);
+       PCIE_W(PCIE_TX_GART_DISCARD_RD_ADDR_LO,
+              state->pcie_tx_gart_discard_rd_addr_lo);
+       PCIE_W(PCIE_TX_GART_START_HI, state->pcie_tx_gart_start_hi);
+       PCIE_W(PCIE_TX_GART_START_LO, state->pcie_tx_gart_start_lo);
+       PCIE_W(PCIE_TX_GART_END_HI, state->pcie_tx_gart_end_hi);
+       PCIE_W(PCIE_TX_GART_END_LO, state->pcie_tx_gart_end_lo);
+       PCIE_W(PCIE_TX_GART_CNTL, state->pcie_tx_gart_cntl);
+}
+
+void radeon_ms_pcie_save(struct drm_device *dev, struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       radeon_ms_agp_save(dev, state);
+       state->pcie_tx_gart_base = PCIE_R(PCIE_TX_GART_BASE);
+       state->pcie_tx_gart_base = PCIE_R(PCIE_TX_GART_BASE);
+       state->pcie_tx_gart_discard_rd_addr_hi =
+               PCIE_R(PCIE_TX_GART_DISCARD_RD_ADDR_HI);
+       state->pcie_tx_gart_discard_rd_addr_lo =
+               PCIE_R(PCIE_TX_GART_DISCARD_RD_ADDR_LO);
+       state->pcie_tx_gart_start_hi = PCIE_R(PCIE_TX_GART_START_HI);
+       state->pcie_tx_gart_start_lo = PCIE_R(PCIE_TX_GART_START_LO);
+       state->pcie_tx_gart_end_hi = PCIE_R(PCIE_TX_GART_END_HI);
+       state->pcie_tx_gart_end_lo = PCIE_R(PCIE_TX_GART_END_LO);
+       state->pcie_tx_gart_cntl = PCIE_R(PCIE_TX_GART_CNTL);
+}
diff --git a/shared-core/radeon_ms_cp.c b/shared-core/radeon_ms_cp.c
new file mode 100644 (file)
index 0000000..7426fac
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Dave Airlie
+ * Copyright 2007 Alex Deucher
+ * 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
+ * PRECISION INSIGHT 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.
+ */
+/*
+ * Authors:
+ *    Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "radeon_ms.h"
+
+static int radeon_ms_test_ring_buffer(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       int i, ret;
+       uint32_t cmd[4];
+
+       MMIO_W(SCRATCH_REG4, 0);
+       cmd[0] = CP_PACKET0(SCRATCH_REG4, 0);
+       cmd[1] = 0xdeadbeef;
+       cmd[2] = CP_PACKET0(WAIT_UNTIL, 0);
+       cmd[3] = WAIT_UNTIL__WAIT_2D_IDLECLEAN |
+               WAIT_UNTIL__WAIT_HOST_IDLECLEAN;
+       DRM_MEMORYBARRIER();
+       ret = radeon_ms_ring_emit(dev, cmd, 4);
+       if (ret) {
+               return 0;
+       }
+       DRM_UDELAY(100);
+
+       for (i = 0; i < dev_priv->usec_timeout; i++) {
+               if (MMIO_R(SCRATCH_REG4) == 0xdeadbeef) {
+                       DRM_INFO("[radeon_ms] cp test succeeded in %d usecs\n",
+                                i);
+                       return 1;
+               }
+               DRM_UDELAY(1);
+       }
+       DRM_INFO("[radeon_ms] cp test failed\n");
+       return 0;
+}
+
+static int radeon_ms_test_write_back(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       uint32_t tmp;
+
+       if (dev_priv->ring_buffer_object == NULL ||
+           dev_priv->ring_buffer == NULL)
+           return 0;
+       dev_priv->write_back_area[0] = 0x0;
+       MMIO_W(SCRATCH_REG0, 0xdeadbeef);
+       for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
+               if (dev_priv->write_back_area[0] == 0xdeadbeef)
+                       break;
+               DRM_UDELAY(1);
+       }
+       if (tmp < dev_priv->usec_timeout) {
+               DRM_INFO("[radeon_ms] writeback test succeeded in %d usecs\n",
+                        tmp);
+               return 1;
+       }
+       MMIO_W(SCRATCH_UMSK, 0x0);
+       DRM_INFO("[radeon_ms] writeback test failed\n");
+       return 0;
+}
+
+static __inline__ void radeon_ms_load_mc(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       int i;
+
+       MMIO_W(CP_ME_RAM_ADDR, 0);
+       for (i = 0; i < 256; i++) {
+               MMIO_W(CP_ME_RAM_DATAH, dev_priv->microcode[(i * 2) + 1]);
+               MMIO_W(CP_ME_RAM_DATAL, dev_priv->microcode[(i * 2) + 0]);
+       }
+}
+
+int radeon_ms_cp_finish(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       dev_priv->cp_ready = 0;
+       radeon_ms_wait_for_idle(dev);
+       DRM_INFO("[radeon_ms] cp idle\n");
+       radeon_ms_cp_stop(dev);
+
+       DRM_INFO("[radeon_ms] ring buffer %p\n", dev_priv->ring_buffer);
+       if (dev_priv->ring_buffer) {
+               drm_bo_kunmap(&dev_priv->ring_buffer_map);
+       }
+       dev_priv->ring_buffer = NULL;
+       DRM_INFO("[radeon_ms] ring buffer object %p\n", dev_priv->ring_buffer_object);
+       if (dev_priv->ring_buffer_object) {
+               mutex_lock(&dev->struct_mutex);
+               drm_bo_usage_deref_locked(&dev_priv->ring_buffer_object);
+               mutex_unlock(&dev->struct_mutex);
+       }
+       return 0;
+}
+
+int radeon_ms_cp_init(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+       int ret = 0;
+
+       if (dev_priv->microcode == NULL) {
+               DRM_INFO("[radeon_ms] no microcode not starting cp");
+               return 0;
+       }
+       /* we allocate an extra page for all write back stuff */
+       ret = drm_buffer_object_create(dev,
+                       dev_priv->ring_buffer_size +
+                       dev_priv->write_back_area_size,
+                       drm_bo_type_kernel,
+                       DRM_BO_FLAG_READ |
+                       DRM_BO_FLAG_WRITE |
+                       DRM_BO_FLAG_MEM_TT |
+                       DRM_BO_FLAG_NO_EVICT,
+                       DRM_BO_HINT_DONT_FENCE,
+                       1,
+                       0,
+                       &dev_priv->ring_buffer_object);
+       if (ret) {
+               return ret;
+       }
+       memset(&dev_priv->ring_buffer_map, 0, sizeof(struct drm_bo_kmap_obj));
+       ret = drm_bo_kmap(dev_priv->ring_buffer_object,
+                       dev_priv->ring_buffer_object->mem.mm_node->start,
+                       dev_priv->ring_buffer_object->mem.num_pages,
+                       &dev_priv->ring_buffer_map);
+       if (ret) {
+               DRM_ERROR("[radeon_ms] error mapping ring buffer: %d\n", ret);
+               return ret;
+       }
+       dev_priv->ring_buffer = dev_priv->ring_buffer_map.virtual; 
+       dev_priv->write_back_area =
+               &dev_priv->ring_buffer[dev_priv->ring_buffer_size >> 2];
+       /* setup write back offset */
+       state->scratch_umsk = 0x7; 
+       state->scratch_addr = 
+               REG_S(SCRATCH_ADDR, SCRATCH_ADDR,
+                               (dev_priv->ring_buffer_object->offset +
+                                dev_priv->ring_buffer_size +
+                                dev_priv->gpu_gart_start) >> 5);
+       MMIO_W(SCRATCH_ADDR, state->scratch_addr);
+       MMIO_W(SCRATCH_UMSK, REG_S(SCRATCH_UMSK, SCRATCH_UMSK, 0x7));
+       DRM_INFO("[radeon_ms] write back at 0x%08X in gpu space\n",
+                MMIO_R(SCRATCH_ADDR));
+       dev_priv->write_back = radeon_ms_test_write_back(dev);
+
+       /* stop cp so it's in know state */
+       radeon_ms_cp_stop(dev);
+       if (dev_priv->ring_rptr) {
+               DRM_INFO("[radeon_ms] failed to set cp read ptr to 0\n");
+       } else {
+               DRM_INFO("[radeon_ms] set cp read ptr to 0\n");
+       }
+       dev_priv->ring_mask = (dev_priv->ring_buffer_size / 4) - 1;
+
+       /* load microcode */
+       DRM_INFO("[radeon_ms] load microcode\n");
+       radeon_ms_load_mc(dev);
+       /* initialize CP registers */
+       state->cp_rb_cntl =
+               REG_S(CP_RB_CNTL, RB_BUFSZ,
+                               drm_order(dev_priv->ring_buffer_size / 8)) |
+               REG_S(CP_RB_CNTL, RB_BLKSZ, drm_order(4096 / 8)) |
+               REG_S(CP_RB_CNTL, MAX_FETCH, 2);
+       if (!dev_priv->write_back) {
+               state->cp_rb_cntl |= CP_RB_CNTL__RB_NO_UPDATE;
+       }
+       state->cp_rb_base =
+               REG_S(CP_RB_BASE, RB_BASE,
+                               (dev_priv->ring_buffer_object->offset +
+                                dev_priv->gpu_gart_start) >> 2);
+       /* read ptr writeback just after the
+        * 8 scratch registers 32 = 8*4 */
+       state->cp_rb_rptr_addr =
+               REG_S(CP_RB_RPTR_ADDR, RB_RPTR_ADDR,
+                               (dev_priv->ring_buffer_object->offset +
+                                dev_priv->ring_buffer_size + 32 +
+                                dev_priv->gpu_gart_start) >> 2);
+       state->cp_rb_wptr = dev_priv->ring_wptr;
+       state->cp_rb_wptr_delay =
+               REG_S(CP_RB_WPTR_DELAY, PRE_WRITE_TIMER, 64) |
+               REG_S(CP_RB_WPTR_DELAY, PRE_WRITE_LIMIT, 8);
+       state->cp_rb_wptr_delay = 0; 
+
+       radeon_ms_cp_restore(dev, state);
+       DRM_INFO("[radeon_ms] ring buffer at 0x%08X in gpu space\n",
+                MMIO_R(CP_RB_BASE));
+
+       /* compute free space */
+       dev_priv->ring_free = 0;
+       ret = radeon_ms_cp_wait(dev, 64);
+       if (ret) {
+               /* we shouldn't fail here */
+               DRM_INFO("[radeon_ms] failed to get ring free space\n");
+               return ret;
+       }
+       DRM_INFO("[radeon_ms] free ring size: %d\n", dev_priv->ring_free * 4);
+
+       MMIO_W(CP_CSQ_CNTL, REG_S(CP_CSQ_CNTL, CSQ_MODE,
+                               CSQ_MODE__CSQ_PRIBM_INDBM));
+       if (!radeon_ms_test_ring_buffer(dev)) {
+               DRM_INFO("[radeon_ms] cp doesn't work\n");
+               /* disable ring should wait idle before */
+               radeon_ms_cp_stop(dev);
+               return -EBUSY;
+       }
+       /* waaooo the cp is ready & working */
+       DRM_INFO("[radeon_ms] cp ready, enjoy\n");
+       dev_priv->cp_ready = 1;
+       return 0;
+}
+
+void radeon_ms_cp_restore(struct drm_device *dev, struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       radeon_ms_wait_for_idle(dev);
+       MMIO_W(SCRATCH_ADDR, state->scratch_addr);
+       MMIO_W(SCRATCH_UMSK, state->scratch_umsk);
+       MMIO_W(CP_RB_BASE, state->cp_rb_base);
+       MMIO_W(CP_RB_RPTR_ADDR, state->cp_rb_rptr_addr);
+       MMIO_W(CP_RB_WPTR_DELAY, state->cp_rb_wptr_delay);
+       MMIO_W(CP_RB_CNTL, state->cp_rb_cntl);
+       /* Sync everything up */
+       MMIO_W(ISYNC_CNTL, ISYNC_CNTL__ISYNC_ANY2D_IDLE3D |
+                          ISYNC_CNTL__ISYNC_ANY3D_IDLE2D |
+                          ISYNC_CNTL__ISYNC_WAIT_IDLEGUI |
+                          ISYNC_CNTL__ISYNC_CPSCRATCH_IDLEGUI);
+}
+
+void radeon_ms_cp_save(struct drm_device *dev, struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       state->scratch_addr = MMIO_R(SCRATCH_ADDR);
+       state->scratch_umsk = MMIO_R(SCRATCH_UMSK);
+       state->cp_rb_base = MMIO_R(CP_RB_BASE);
+       state->cp_rb_rptr_addr = MMIO_R(CP_RB_RPTR_ADDR);
+       state->cp_rb_wptr_delay = MMIO_R(CP_RB_WPTR_DELAY);
+       state->cp_rb_wptr = MMIO_R(CP_RB_WPTR);
+       state->cp_rb_cntl = MMIO_R(CP_RB_CNTL);
+}
+
+void radeon_ms_cp_stop(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       MMIO_W(CP_CSQ_CNTL, REG_S(CP_CSQ_CNTL, CSQ_MODE,
+                               CSQ_MODE__CSQ_PRIDIS_INDDIS));
+       MMIO_W(CP_RB_CNTL, CP_RB_CNTL__RB_RPTR_WR_ENA);
+       MMIO_W(CP_RB_RPTR_WR, 0);
+       MMIO_W(CP_RB_WPTR, 0);
+       DRM_UDELAY(5);
+       dev_priv->ring_wptr = dev_priv->ring_rptr = MMIO_R(CP_RB_RPTR);
+       MMIO_W(CP_RB_WPTR, dev_priv->ring_wptr);
+}
+
+int radeon_ms_cp_wait(struct drm_device *dev, int n)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       uint32_t i, last_rptr, p = 0;
+
+       last_rptr = MMIO_R(CP_RB_RPTR);
+       for (i = 0; i < dev_priv->usec_timeout; i++) {
+               dev_priv->ring_rptr = MMIO_R(CP_RB_RPTR);
+               if (last_rptr != dev_priv->ring_rptr) {
+                       /* the ring is progressing no lockup */
+                       p = 1;
+               }
+               dev_priv->ring_free = (((int)dev_priv->ring_rptr) -
+                                      ((int)dev_priv->ring_wptr));
+               if (dev_priv->ring_free <= 0)
+                       dev_priv->ring_free += (dev_priv->ring_buffer_size / 4);
+               if (dev_priv->ring_free > n)
+                       return 0;
+               last_rptr = dev_priv->ring_rptr;
+               DRM_UDELAY(1);
+       }
+       if (p) {
+               DRM_INFO("[radeon_ms] timed out waiting free slot\n");
+       } else {
+               DRM_INFO("[radeon_ms] cp have lickely locked up\n");
+       }
+       return -EBUSY;
+}
+
+int radeon_ms_ring_emit(struct drm_device *dev, uint32_t *cmd, uint32_t count)
+{
+       static spinlock_t ring_lock = SPIN_LOCK_UNLOCKED;
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       uint32_t i = 0;
+
+       if (!count)
+               return -EINVAL;
+
+       spin_lock(&ring_lock);
+       if (dev_priv->ring_free <= (count)) {
+               spin_unlock(&ring_lock);
+               return -EBUSY;
+       }
+       dev_priv->ring_free -= count;
+       for (i = 0; i < count; i++) {
+               dev_priv->ring_buffer[dev_priv->ring_wptr] = cmd[i];
+               dev_priv->ring_wptr++;
+               dev_priv->ring_wptr &= dev_priv->ring_mask;
+       }
+       /* commit ring */
+       DRM_MEMORYBARRIER();
+       MMIO_W(CP_RB_WPTR, REG_S(CP_RB_WPTR, RB_WPTR, dev_priv->ring_wptr));
+       /* read from PCI bus to ensure correct posting */
+       MMIO_R(CP_RB_WPTR);
+       spin_unlock(&ring_lock);
+       return 0;
+}
diff --git a/shared-core/radeon_ms_cp_mc.c b/shared-core/radeon_ms_cp_mc.c
new file mode 100644 (file)
index 0000000..f0397d8
--- /dev/null
@@ -0,0 +1,801 @@
+/*
+ * Copyright 2007  Advanced Micro Devices, Inc.
+ *
+ * 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 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 HOLDER(S) OR AUTHOR(S) 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 "radeon_ms.h"
+
+/* CP microcode (from ATI) */
+
+const uint32_t radeon_cp_microcode[] = {
+       0x21007000, 0000000000,
+       0x20007000, 0000000000,
+       0x000000b4, 0x00000004,
+       0x000000b8, 0x00000004,
+       0x6f5b4d4c, 0000000000,
+       0x4c4c427f, 0000000000,
+       0x5b568a92, 0000000000,
+       0x4ca09c6d, 0000000000,
+       0xad4c4c4c, 0000000000,
+       0x4ce1af3d, 0000000000,
+       0xd8afafaf, 0000000000,
+       0xd64c4cdc, 0000000000,
+       0x4cd10d10, 0000000000,
+       0x000f0000, 0x00000016,
+       0x362f242d, 0000000000,
+       0x00000012, 0x00000004,
+       0x000f0000, 0x00000016,
+       0x362f282d, 0000000000,
+       0x000380e7, 0x00000002,
+       0x04002c97, 0x00000002,
+       0x000f0001, 0x00000016,
+       0x333a3730, 0000000000,
+       0x000077ef, 0x00000002,
+       0x00061000, 0x00000002,
+       0x00000021, 0x0000001a,
+       0x00004000, 0x0000001e,
+       0x00061000, 0x00000002,
+       0x00000021, 0x0000001a,
+       0x00004000, 0x0000001e,
+       0x00061000, 0x00000002,
+       0x00000021, 0x0000001a,
+       0x00004000, 0x0000001e,
+       0x00000017, 0x00000004,
+       0x0003802b, 0x00000002,
+       0x040067e0, 0x00000002,
+       0x00000017, 0x00000004,
+       0x000077e0, 0x00000002,
+       0x00065000, 0x00000002,
+       0x000037e1, 0x00000002,
+       0x040067e1, 0x00000006,
+       0x000077e0, 0x00000002,
+       0x000077e1, 0x00000002,
+       0x000077e1, 0x00000006,
+       0xffffffff, 0000000000,
+       0x10000000, 0000000000,
+       0x0003802b, 0x00000002,
+       0x040067e0, 0x00000006,
+       0x00007675, 0x00000002,
+       0x00007676, 0x00000002,
+       0x00007677, 0x00000002,
+       0x00007678, 0x00000006,
+       0x0003802c, 0x00000002,
+       0x04002676, 0x00000002,
+       0x00007677, 0x00000002,
+       0x00007678, 0x00000006,
+       0x0000002f, 0x00000018,
+       0x0000002f, 0x00000018,
+       0000000000, 0x00000006,
+       0x00000030, 0x00000018,
+       0x00000030, 0x00000018,
+       0000000000, 0x00000006,
+       0x01605000, 0x00000002,
+       0x00065000, 0x00000002,
+       0x00098000, 0x00000002,
+       0x00061000, 0x00000002,
+       0x64c0603e, 0x00000004,
+       0x000380e6, 0x00000002,
+       0x040025c5, 0x00000002,
+       0x00080000, 0x00000016,
+       0000000000, 0000000000,
+       0x0400251d, 0x00000002,
+       0x00007580, 0x00000002,
+       0x00067581, 0x00000002,
+       0x04002580, 0x00000002,
+       0x00067581, 0x00000002,
+       0x00000049, 0x00000004,
+       0x00005000, 0000000000,
+       0x000380e6, 0x00000002,
+       0x040025c5, 0x00000002,
+       0x00061000, 0x00000002,
+       0x0000750e, 0x00000002,
+       0x00019000, 0x00000002,
+       0x00011055, 0x00000014,
+       0x00000055, 0x00000012,
+       0x0400250f, 0x00000002,
+       0x0000504f, 0x00000004,
+       0x000380e6, 0x00000002,
+       0x040025c5, 0x00000002,
+       0x00007565, 0x00000002,
+       0x00007566, 0x00000002,
+       0x00000058, 0x00000004,
+       0x000380e6, 0x00000002,
+       0x040025c5, 0x00000002,
+       0x01e655b4, 0x00000002,
+       0x4401b0e4, 0x00000002,
+       0x01c110e4, 0x00000002,
+       0x26667066, 0x00000018,
+       0x040c2565, 0x00000002,
+       0x00000066, 0x00000018,
+       0x04002564, 0x00000002,
+       0x00007566, 0x00000002,
+       0x0000005d, 0x00000004,
+       0x00401069, 0x00000008,
+       0x00101000, 0x00000002,
+       0x000d80ff, 0x00000002,
+       0x0080006c, 0x00000008,
+       0x000f9000, 0x00000002,
+       0x000e00ff, 0x00000002,
+       0000000000, 0x00000006,
+       0x0000008f, 0x00000018,
+       0x0000005b, 0x00000004,
+       0x000380e6, 0x00000002,
+       0x040025c5, 0x00000002,
+       0x00007576, 0x00000002,
+       0x00065000, 0x00000002,
+       0x00009000, 0x00000002,
+       0x00041000, 0x00000002,
+       0x0c00350e, 0x00000002,
+       0x00049000, 0x00000002,
+       0x00051000, 0x00000002,
+       0x01e785f8, 0x00000002,
+       0x00200000, 0x00000002,
+       0x0060007e, 0x0000000c,
+       0x00007563, 0x00000002,
+       0x006075f0, 0x00000021,
+       0x20007073, 0x00000004,
+       0x00005073, 0x00000004,
+       0x000380e6, 0x00000002,
+       0x040025c5, 0x00000002,
+       0x00007576, 0x00000002,
+       0x00007577, 0x00000002,
+       0x0000750e, 0x00000002,
+       0x0000750f, 0x00000002,
+       0x00a05000, 0x00000002,
+       0x00600083, 0x0000000c,
+       0x006075f0, 0x00000021,
+       0x000075f8, 0x00000002,
+       0x00000083, 0x00000004,
+       0x000a750e, 0x00000002,
+       0x000380e6, 0x00000002,
+       0x040025c5, 0x00000002,
+       0x0020750f, 0x00000002,
+       0x00600086, 0x00000004,
+       0x00007570, 0x00000002,
+       0x00007571, 0x00000002,
+       0x00007572, 0x00000006,
+       0x000380e6, 0x00000002,
+       0x040025c5, 0x00000002,
+       0x00005000, 0x00000002,
+       0x00a05000, 0x00000002,
+       0x00007568, 0x00000002,
+       0x00061000, 0x00000002,
+       0x00000095, 0x0000000c,
+       0x00058000, 0x00000002,
+       0x0c607562, 0x00000002,
+       0x00000097, 0x00000004,
+       0x000380e6, 0x00000002,
+       0x040025c5, 0x00000002,
+       0x00600096, 0x00000004,
+       0x400070e5, 0000000000,
+       0x000380e6, 0x00000002,
+       0x040025c5, 0x00000002,
+       0x000380e5, 0x00000002,
+       0x000000a8, 0x0000001c,
+       0x000650aa, 0x00000018,
+       0x040025bb, 0x00000002,
+       0x000610ab, 0x00000018,
+       0x040075bc, 0000000000,
+       0x000075bb, 0x00000002,
+       0x000075bc, 0000000000,
+       0x00090000, 0x00000006,
+       0x00090000, 0x00000002,
+       0x000d8002, 0x00000006,
+       0x00007832, 0x00000002,
+       0x00005000, 0x00000002,
+       0x000380e7, 0x00000002,
+       0x04002c97, 0x00000002,
+       0x00007820, 0x00000002,
+       0x00007821, 0x00000002,
+       0x00007800, 0000000000,
+       0x01200000, 0x00000002,
+       0x20077000, 0x00000002,
+       0x01200000, 0x00000002,
+       0x20007000, 0x00000002,
+       0x00061000, 0x00000002,
+       0x0120751b, 0x00000002,
+       0x8040750a, 0x00000002,
+       0x8040750b, 0x00000002,
+       0x00110000, 0x00000002,
+       0x000380e5, 0x00000002,
+       0x000000c6, 0x0000001c,
+       0x000610ab, 0x00000018,
+       0x844075bd, 0x00000002,
+       0x000610aa, 0x00000018,
+       0x840075bb, 0x00000002,
+       0x000610ab, 0x00000018,
+       0x844075bc, 0x00000002,
+       0x000000c9, 0x00000004,
+       0x804075bd, 0x00000002,
+       0x800075bb, 0x00000002,
+       0x804075bc, 0x00000002,
+       0x00108000, 0x00000002,
+       0x01400000, 0x00000002,
+       0x006000cd, 0x0000000c,
+       0x20c07000, 0x00000020,
+       0x000000cf, 0x00000012,
+       0x00800000, 0x00000006,
+       0x0080751d, 0x00000006,
+       0000000000, 0000000000,
+       0x0000775c, 0x00000002,
+       0x00a05000, 0x00000002,
+       0x00661000, 0x00000002,
+       0x0460275d, 0x00000020,
+       0x00004000, 0000000000,
+       0x01e00830, 0x00000002,
+       0x21007000, 0000000000,
+       0x6464614d, 0000000000,
+       0x69687420, 0000000000,
+       0x00000073, 0000000000,
+       0000000000, 0000000000,
+       0x00005000, 0x00000002,
+       0x000380d0, 0x00000002,
+       0x040025e0, 0x00000002,
+       0x000075e1, 0000000000,
+       0x00000001, 0000000000,
+       0x000380e0, 0x00000002,
+       0x04002394, 0x00000002,
+       0x00005000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0x00000008, 0000000000,
+       0x00000004, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+};
+
+const uint32_t r200_cp_microcode[] = {
+       0x21007000, 0000000000,
+       0x20007000, 0000000000,
+       0x000000ab, 0x00000004,
+       0x000000af, 0x00000004,
+       0x66544a49, 0000000000,
+       0x49494174, 0000000000,
+       0x54517d83, 0000000000,
+       0x498d8b64, 0000000000,
+       0x49494949, 0000000000,
+       0x49da493c, 0000000000,
+       0x49989898, 0000000000,
+       0xd34949d5, 0000000000,
+       0x9dc90e11, 0000000000,
+       0xce9b9b9b, 0000000000,
+       0x000f0000, 0x00000016,
+       0x352e232c, 0000000000,
+       0x00000013, 0x00000004,
+       0x000f0000, 0x00000016,
+       0x352e272c, 0000000000,
+       0x000f0001, 0x00000016,
+       0x3239362f, 0000000000,
+       0x000077ef, 0x00000002,
+       0x00061000, 0x00000002,
+       0x00000020, 0x0000001a,
+       0x00004000, 0x0000001e,
+       0x00061000, 0x00000002,
+       0x00000020, 0x0000001a,
+       0x00004000, 0x0000001e,
+       0x00061000, 0x00000002,
+       0x00000020, 0x0000001a,
+       0x00004000, 0x0000001e,
+       0x00000016, 0x00000004,
+       0x0003802a, 0x00000002,
+       0x040067e0, 0x00000002,
+       0x00000016, 0x00000004,
+       0x000077e0, 0x00000002,
+       0x00065000, 0x00000002,
+       0x000037e1, 0x00000002,
+       0x040067e1, 0x00000006,
+       0x000077e0, 0x00000002,
+       0x000077e1, 0x00000002,
+       0x000077e1, 0x00000006,
+       0xffffffff, 0000000000,
+       0x10000000, 0000000000,
+       0x0003802a, 0x00000002,
+       0x040067e0, 0x00000006,
+       0x00007675, 0x00000002,
+       0x00007676, 0x00000002,
+       0x00007677, 0x00000002,
+       0x00007678, 0x00000006,
+       0x0003802b, 0x00000002,
+       0x04002676, 0x00000002,
+       0x00007677, 0x00000002,
+       0x00007678, 0x00000006,
+       0x0000002e, 0x00000018,
+       0x0000002e, 0x00000018,
+       0000000000, 0x00000006,
+       0x0000002f, 0x00000018,
+       0x0000002f, 0x00000018,
+       0000000000, 0x00000006,
+       0x01605000, 0x00000002,
+       0x00065000, 0x00000002,
+       0x00098000, 0x00000002,
+       0x00061000, 0x00000002,
+       0x64c0603d, 0x00000004,
+       0x00080000, 0x00000016,
+       0000000000, 0000000000,
+       0x0400251d, 0x00000002,
+       0x00007580, 0x00000002,
+       0x00067581, 0x00000002,
+       0x04002580, 0x00000002,
+       0x00067581, 0x00000002,
+       0x00000046, 0x00000004,
+       0x00005000, 0000000000,
+       0x00061000, 0x00000002,
+       0x0000750e, 0x00000002,
+       0x00019000, 0x00000002,
+       0x00011055, 0x00000014,
+       0x00000055, 0x00000012,
+       0x0400250f, 0x00000002,
+       0x0000504a, 0x00000004,
+       0x00007565, 0x00000002,
+       0x00007566, 0x00000002,
+       0x00000051, 0x00000004,
+       0x01e655b4, 0x00000002,
+       0x4401b0dc, 0x00000002,
+       0x01c110dc, 0x00000002,
+       0x2666705d, 0x00000018,
+       0x040c2565, 0x00000002,
+       0x0000005d, 0x00000018,
+       0x04002564, 0x00000002,
+       0x00007566, 0x00000002,
+       0x00000054, 0x00000004,
+       0x00401060, 0x00000008,
+       0x00101000, 0x00000002,
+       0x000d80ff, 0x00000002,
+       0x00800063, 0x00000008,
+       0x000f9000, 0x00000002,
+       0x000e00ff, 0x00000002,
+       0000000000, 0x00000006,
+       0x00000080, 0x00000018,
+       0x00000054, 0x00000004,
+       0x00007576, 0x00000002,
+       0x00065000, 0x00000002,
+       0x00009000, 0x00000002,
+       0x00041000, 0x00000002,
+       0x0c00350e, 0x00000002,
+       0x00049000, 0x00000002,
+       0x00051000, 0x00000002,
+       0x01e785f8, 0x00000002,
+       0x00200000, 0x00000002,
+       0x00600073, 0x0000000c,
+       0x00007563, 0x00000002,
+       0x006075f0, 0x00000021,
+       0x20007068, 0x00000004,
+       0x00005068, 0x00000004,
+       0x00007576, 0x00000002,
+       0x00007577, 0x00000002,
+       0x0000750e, 0x00000002,
+       0x0000750f, 0x00000002,
+       0x00a05000, 0x00000002,
+       0x00600076, 0x0000000c,
+       0x006075f0, 0x00000021,
+       0x000075f8, 0x00000002,
+       0x00000076, 0x00000004,
+       0x000a750e, 0x00000002,
+       0x0020750f, 0x00000002,
+       0x00600079, 0x00000004,
+       0x00007570, 0x00000002,
+       0x00007571, 0x00000002,
+       0x00007572, 0x00000006,
+       0x00005000, 0x00000002,
+       0x00a05000, 0x00000002,
+       0x00007568, 0x00000002,
+       0x00061000, 0x00000002,
+       0x00000084, 0x0000000c,
+       0x00058000, 0x00000002,
+       0x0c607562, 0x00000002,
+       0x00000086, 0x00000004,
+       0x00600085, 0x00000004,
+       0x400070dd, 0000000000,
+       0x000380dd, 0x00000002,
+       0x00000093, 0x0000001c,
+       0x00065095, 0x00000018,
+       0x040025bb, 0x00000002,
+       0x00061096, 0x00000018,
+       0x040075bc, 0000000000,
+       0x000075bb, 0x00000002,
+       0x000075bc, 0000000000,
+       0x00090000, 0x00000006,
+       0x00090000, 0x00000002,
+       0x000d8002, 0x00000006,
+       0x00005000, 0x00000002,
+       0x00007821, 0x00000002,
+       0x00007800, 0000000000,
+       0x00007821, 0x00000002,
+       0x00007800, 0000000000,
+       0x01665000, 0x00000002,
+       0x000a0000, 0x00000002,
+       0x000671cc, 0x00000002,
+       0x0286f1cd, 0x00000002,
+       0x000000a3, 0x00000010,
+       0x21007000, 0000000000,
+       0x000000aa, 0x0000001c,
+       0x00065000, 0x00000002,
+       0x000a0000, 0x00000002,
+       0x00061000, 0x00000002,
+       0x000b0000, 0x00000002,
+       0x38067000, 0x00000002,
+       0x000a00a6, 0x00000004,
+       0x20007000, 0000000000,
+       0x01200000, 0x00000002,
+       0x20077000, 0x00000002,
+       0x01200000, 0x00000002,
+       0x20007000, 0000000000,
+       0x00061000, 0x00000002,
+       0x0120751b, 0x00000002,
+       0x8040750a, 0x00000002,
+       0x8040750b, 0x00000002,
+       0x00110000, 0x00000002,
+       0x000380dd, 0x00000002,
+       0x000000bd, 0x0000001c,
+       0x00061096, 0x00000018,
+       0x844075bd, 0x00000002,
+       0x00061095, 0x00000018,
+       0x840075bb, 0x00000002,
+       0x00061096, 0x00000018,
+       0x844075bc, 0x00000002,
+       0x000000c0, 0x00000004,
+       0x804075bd, 0x00000002,
+       0x800075bb, 0x00000002,
+       0x804075bc, 0x00000002,
+       0x00108000, 0x00000002,
+       0x01400000, 0x00000002,
+       0x006000c4, 0x0000000c,
+       0x20c07000, 0x00000020,
+       0x000000c6, 0x00000012,
+       0x00800000, 0x00000006,
+       0x0080751d, 0x00000006,
+       0x000025bb, 0x00000002,
+       0x000040c0, 0x00000004,
+       0x0000775c, 0x00000002,
+       0x00a05000, 0x00000002,
+       0x00661000, 0x00000002,
+       0x0460275d, 0x00000020,
+       0x00004000, 0000000000,
+       0x00007999, 0x00000002,
+       0x00a05000, 0x00000002,
+       0x00661000, 0x00000002,
+       0x0460299b, 0x00000020,
+       0x00004000, 0000000000,
+       0x01e00830, 0x00000002,
+       0x21007000, 0000000000,
+       0x00005000, 0x00000002,
+       0x00038042, 0x00000002,
+       0x040025e0, 0x00000002,
+       0x000075e1, 0000000000,
+       0x00000001, 0000000000,
+       0x000380d9, 0x00000002,
+       0x04007394, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+       0000000000, 0000000000,
+};
+
+const uint32_t r300_cp_microcode[] = {
+        0x4200e000, 0000000000,
+        0x4000e000, 0000000000,
+        0x000000af, 0x00000008,
+        0x000000b3, 0x00000008,
+        0x6c5a504f, 0000000000,
+        0x4f4f497a, 0000000000,
+        0x5a578288, 0000000000,
+        0x4f91906a, 0000000000,
+        0x4f4f4f4f, 0000000000,
+        0x4fe24f44, 0000000000,
+        0x4f9c9c9c, 0000000000,
+        0xdc4f4fde, 0000000000,
+        0xa1cd4f4f, 0000000000,
+        0xd29d9d9d, 0000000000,
+        0x4f0f9fd7, 0000000000,
+        0x000ca000, 0x00000004,
+        0x000d0012, 0x00000038,
+        0x0000e8b4, 0x00000004,
+        0x000d0014, 0x00000038,
+        0x0000e8b6, 0x00000004,
+        0x000d0016, 0x00000038,
+        0x0000e854, 0x00000004,
+        0x000d0018, 0x00000038,
+        0x0000e855, 0x00000004,
+        0x000d001a, 0x00000038,
+        0x0000e856, 0x00000004,
+        0x000d001c, 0x00000038,
+        0x0000e857, 0x00000004,
+        0x000d001e, 0x00000038,
+        0x0000e824, 0x00000004,
+        0x000d0020, 0x00000038,
+        0x0000e825, 0x00000004,
+        0x000d0022, 0x00000038,
+        0x0000e830, 0x00000004,
+        0x000d0024, 0x00000038,
+        0x0000f0c0, 0x00000004,
+        0x000d0026, 0x00000038,
+        0x0000f0c1, 0x00000004,
+        0x000d0028, 0x00000038,
+        0x0000f041, 0x00000004,
+        0x000d002a, 0x00000038,
+        0x0000f184, 0x00000004,
+        0x000d002c, 0x00000038,
+        0x0000f185, 0x00000004,
+        0x000d002e, 0x00000038,
+        0x0000f186, 0x00000004,
+        0x000d0030, 0x00000038,
+        0x0000f187, 0x00000004,
+        0x000d0032, 0x00000038,
+        0x0000f180, 0x00000004,
+        0x000d0034, 0x00000038,
+        0x0000f393, 0x00000004,
+        0x000d0036, 0x00000038,
+        0x0000f38a, 0x00000004,
+        0x000d0038, 0x00000038,
+        0x0000f38e, 0x00000004,
+        0x0000e821, 0x00000004,
+        0x0140a000, 0x00000004,
+        0x00000043, 0x00000018,
+        0x00cce800, 0x00000004,
+        0x001b0001, 0x00000004,
+        0x08004800, 0x00000004,
+        0x001b0001, 0x00000004,
+        0x08004800, 0x00000004,
+        0x001b0001, 0x00000004,
+        0x08004800, 0x00000004,
+        0x0000003a, 0x00000008,
+        0x0000a000, 0000000000,
+        0x02c0a000, 0x00000004,
+        0x000ca000, 0x00000004,
+        0x00130000, 0x00000004,
+        0x000c2000, 0x00000004,
+        0xc980c045, 0x00000008,
+        0x2000451d, 0x00000004,
+        0x0000e580, 0x00000004,
+        0x000ce581, 0x00000004,
+        0x08004580, 0x00000004,
+        0x000ce581, 0x00000004,
+        0x0000004c, 0x00000008,
+        0x0000a000, 0000000000,
+        0x000c2000, 0x00000004,
+        0x0000e50e, 0x00000004,
+        0x00032000, 0x00000004,
+        0x00022056, 0x00000028,
+        0x00000056, 0x00000024,
+        0x0800450f, 0x00000004,
+        0x0000a050, 0x00000008,
+        0x0000e565, 0x00000004,
+        0x0000e566, 0x00000004,
+        0x00000057, 0x00000008,
+        0x03cca5b4, 0x00000004,
+        0x05432000, 0x00000004,
+        0x00022000, 0x00000004,
+        0x4ccce063, 0x00000030,
+        0x08274565, 0x00000004,
+        0x00000063, 0x00000030,
+        0x08004564, 0x00000004,
+        0x0000e566, 0x00000004,
+        0x0000005a, 0x00000008,
+        0x00802066, 0x00000010,
+        0x00202000, 0x00000004,
+        0x001b00ff, 0x00000004,
+        0x01000069, 0x00000010,
+        0x001f2000, 0x00000004,
+        0x001c00ff, 0x00000004,
+        0000000000, 0x0000000c,
+        0x00000085, 0x00000030,
+        0x0000005a, 0x00000008,
+        0x0000e576, 0x00000004,
+        0x000ca000, 0x00000004,
+        0x00012000, 0x00000004,
+        0x00082000, 0x00000004,
+        0x1800650e, 0x00000004,
+        0x00092000, 0x00000004,
+        0x000a2000, 0x00000004,
+        0x000f0000, 0x00000004,
+        0x00400000, 0x00000004,
+        0x00000079, 0x00000018,
+        0x0000e563, 0x00000004,
+        0x00c0e5f9, 0x000000c2,
+        0x0000006e, 0x00000008,
+        0x0000a06e, 0x00000008,
+        0x0000e576, 0x00000004,
+        0x0000e577, 0x00000004,
+        0x0000e50e, 0x00000004,
+        0x0000e50f, 0x00000004,
+        0x0140a000, 0x00000004,
+        0x0000007c, 0x00000018,
+        0x00c0e5f9, 0x000000c2,
+        0x0000007c, 0x00000008,
+        0x0014e50e, 0x00000004,
+        0x0040e50f, 0x00000004,
+        0x00c0007f, 0x00000008,
+        0x0000e570, 0x00000004,
+        0x0000e571, 0x00000004,
+        0x0000e572, 0x0000000c,
+        0x0000a000, 0x00000004,
+        0x0140a000, 0x00000004,
+        0x0000e568, 0x00000004,
+        0x000c2000, 0x00000004,
+        0x00000089, 0x00000018,
+        0x000b0000, 0x00000004,
+        0x18c0e562, 0x00000004,
+        0x0000008b, 0x00000008,
+        0x00c0008a, 0x00000008,
+        0x000700e4, 0x00000004,
+        0x00000097, 0x00000038,
+        0x000ca099, 0x00000030,
+        0x080045bb, 0x00000004,
+        0x000c209a, 0x00000030,
+        0x0800e5bc, 0000000000,
+        0x0000e5bb, 0x00000004,
+        0x0000e5bc, 0000000000,
+        0x00120000, 0x0000000c,
+        0x00120000, 0x00000004,
+        0x001b0002, 0x0000000c,
+        0x0000a000, 0x00000004,
+        0x0000e821, 0x00000004,
+        0x0000e800, 0000000000,
+        0x0000e821, 0x00000004,
+        0x0000e82e, 0000000000,
+        0x02cca000, 0x00000004,
+        0x00140000, 0x00000004,
+        0x000ce1cc, 0x00000004,
+        0x050de1cd, 0x00000004,
+        0x000000a7, 0x00000020,
+        0x4200e000, 0000000000,
+        0x000000ae, 0x00000038,
+        0x000ca000, 0x00000004,
+        0x00140000, 0x00000004,
+        0x000c2000, 0x00000004,
+        0x00160000, 0x00000004,
+        0x700ce000, 0x00000004,
+        0x001400aa, 0x00000008,
+        0x4000e000, 0000000000,
+        0x02400000, 0x00000004,
+        0x400ee000, 0x00000004,
+        0x02400000, 0x00000004,
+        0x4000e000, 0000000000,
+        0x000c2000, 0x00000004,
+        0x0240e51b, 0x00000004,
+        0x0080e50a, 0x00000005,
+        0x0080e50b, 0x00000005,
+        0x00220000, 0x00000004,
+        0x000700e4, 0x00000004,
+        0x000000c1, 0x00000038,
+        0x000c209a, 0x00000030,
+        0x0880e5bd, 0x00000005,
+        0x000c2099, 0x00000030,
+        0x0800e5bb, 0x00000005,
+        0x000c209a, 0x00000030,
+        0x0880e5bc, 0x00000005,
+        0x000000c4, 0x00000008,
+        0x0080e5bd, 0x00000005,
+        0x0000e5bb, 0x00000005,
+        0x0080e5bc, 0x00000005,
+        0x00210000, 0x00000004,
+        0x02800000, 0x00000004,
+        0x00c000c8, 0x00000018,
+        0x4180e000, 0x00000040,
+        0x000000ca, 0x00000024,
+        0x01000000, 0x0000000c,
+        0x0100e51d, 0x0000000c,
+        0x000045bb, 0x00000004,
+        0x000080c4, 0x00000008,
+        0x0000f3ce, 0x00000004,
+        0x0140a000, 0x00000004,
+        0x00cc2000, 0x00000004,
+        0x08c053cf, 0x00000040,
+        0x00008000, 0000000000,
+        0x0000f3d2, 0x00000004,
+        0x0140a000, 0x00000004,
+        0x00cc2000, 0x00000004,
+        0x08c053d3, 0x00000040,
+        0x00008000, 0000000000,
+        0x0000f39d, 0x00000004,
+        0x0140a000, 0x00000004,
+        0x00cc2000, 0x00000004,
+        0x08c0539e, 0x00000040,
+        0x00008000, 0000000000,
+        0x03c00830, 0x00000004,
+        0x4200e000, 0000000000,
+        0x0000a000, 0x00000004,
+        0x200045e0, 0x00000004,
+        0x0000e5e1, 0000000000,
+        0x00000001, 0000000000,
+        0x000700e1, 0x00000004,
+        0x0800e394, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+        0000000000, 0000000000,
+};
diff --git a/shared-core/radeon_ms_crtc.c b/shared-core/radeon_ms_crtc.c
new file mode 100644 (file)
index 0000000..a9387f9
--- /dev/null
@@ -0,0 +1,769 @@
+/*
+ * Copyright © 2007 Alex Deucher
+ * Copyright © 2007 Dave Airlie
+ * Copyright © 2007 Michel Dänzer
+ * Copyright © 2007 Jerome Glisse
+ *
+ * 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 on 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
+ * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR 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 "drm_crtc.h"
+#include "radeon_ms.h"
+
+static void radeon_pll1_init(struct drm_radeon_private *dev_priv,
+                            struct radeon_state *state);
+static void radeon_pll1_restore(struct drm_radeon_private *dev_priv,
+                               struct radeon_state *state);
+static void radeon_pll1_save(struct drm_radeon_private *dev_priv,
+                            struct radeon_state *state);
+static void radeon_ms_crtc_load_lut(struct drm_crtc *crtc);
+
+/**
+ * radeon_ms_crtc1_init - initialize CRTC state
+ * @dev_priv: radeon private structure
+ * @state: state structure to initialize to default value
+ *
+ * Initialize CRTC state to default values
+ */
+static void radeon_ms_crtc1_init(struct drm_radeon_private *dev_priv,
+                                struct radeon_state *state)
+{
+       state->surface_cntl = SURFACE_CNTL__SURF_TRANSLATION_DIS;
+       state->surface0_info = 0;
+       state->surface0_lower_bound = 0;
+       state->surface0_upper_bound = 0;
+       state->surface1_info = 0;
+       state->surface1_lower_bound = 0;
+       state->surface1_upper_bound = 0;
+       state->surface2_info = 0;
+       state->surface2_lower_bound = 0;
+       state->surface2_upper_bound = 0;
+       state->surface3_info = 0;
+       state->surface3_lower_bound = 0;
+       state->surface3_upper_bound = 0;
+       state->surface4_info = 0;
+       state->surface4_lower_bound = 0;
+       state->surface4_upper_bound = 0;
+       state->surface5_info = 0;
+       state->surface5_lower_bound = 0;
+       state->surface5_upper_bound = 0;
+       state->surface6_info = 0;
+       state->surface6_lower_bound = 0;
+       state->surface6_upper_bound = 0;
+       state->surface7_info = 0;
+       state->surface7_lower_bound = 0;
+       state->surface7_upper_bound = 0;
+       state->crtc_gen_cntl = CRTC_GEN_CNTL__CRTC_EXT_DISP_EN |
+                              CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B;
+       state->crtc_ext_cntl = CRTC_EXT_CNTL__VGA_ATI_LINEAR |
+                              CRTC_EXT_CNTL__VGA_XCRT_CNT_EN |
+                              CRTC_EXT_CNTL__CRT_ON;
+       state->crtc_h_total_disp = 0;
+       state->crtc_h_sync_strt_wid = 0;
+       state->crtc_v_total_disp = 0;
+       state->crtc_v_sync_strt_wid = 0;
+       state->crtc_offset = 0;
+       state->crtc_pitch = 0;
+       state->crtc_more_cntl = 0;
+       state->crtc_tile_x0_y0 = 0;
+       state->crtc_offset_cntl = 0;
+       switch (dev_priv->family) {
+       case CHIP_R100:
+       case CHIP_R200:
+       case CHIP_RV200:
+       case CHIP_RV250:
+       case CHIP_RV280:
+       case CHIP_RS300:
+               break;
+       case CHIP_R300:
+       case CHIP_R350:
+       case CHIP_R360:
+       case CHIP_RV350:
+       case CHIP_RV370:
+       case CHIP_RV380:
+       case CHIP_RS400:
+       case CHIP_RV410:
+       case CHIP_R420:
+       case CHIP_R430:
+       case CHIP_R480:
+               state->crtc_offset_cntl |= REG_S(CRTC_OFFSET_CNTL,
+                               CRTC_MICRO_TILE_BUFFER_MODE,
+                               CRTC_MICRO_TILE_BUFFER_MODE__DIS);
+               break;
+       default:
+               DRM_ERROR("Unknown radeon family, aborting\n");
+               return;
+       }
+       radeon_pll1_init(dev_priv, state);
+}
+
+/**
+ * radeon_pll1_init - initialize PLL1 state
+ * @dev_priv: radeon private structure
+ * @state: state structure to initialize to default value
+ *
+ * Initialize PLL1 state to default values
+ */
+static void radeon_pll1_init(struct drm_radeon_private *dev_priv,
+                            struct radeon_state *state)
+{
+       state->clock_cntl_index = 0;
+       state->ppll_cntl = PPLL_R(PPLL_CNTL);
+       state->ppll_cntl |= PPLL_CNTL__PPLL_ATOMIC_UPDATE_EN |
+               PPLL_CNTL__PPLL_ATOMIC_UPDATE_SYNC |
+               PPLL_CNTL__PPLL_VGA_ATOMIC_UPDATE_EN;
+       state->ppll_cntl &= ~PPLL_CNTL__PPLL_TST_EN;
+       state->ppll_cntl &= ~PPLL_CNTL__PPLL_TCPOFF;
+       state->ppll_cntl &= ~PPLL_CNTL__PPLL_TVCOMAX;
+       state->ppll_cntl &= ~PPLL_CNTL__PPLL_DISABLE_AUTO_RESET;
+       state->ppll_ref_div = 0;
+       state->ppll_ref_div = REG_S(PPLL_REF_DIV, PPLL_REF_DIV, 12) |
+               REG_S(PPLL_REF_DIV, PPLL_REF_DIV_SRC, PPLL_REF_DIV_SRC__XTALIN);
+       state->ppll_div_0 = 0;
+       state->ppll_div_1 = 0;
+       state->ppll_div_2 = 0;
+       state->ppll_div_3 = 0;
+       state->vclk_ecp_cntl = 0;
+       state->htotal_cntl = 0;
+}
+
+/**
+ * radeon_ms_crtc1_restore - restore CRTC state
+ * @dev_priv: radeon private structure
+ * @state: CRTC state to restore
+ */
+void radeon_ms_crtc1_restore(struct drm_device *dev, struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       /* We prevent the CRTC from hitting the memory controller until
+        * fully programmed
+        */
+       MMIO_W(CRTC_GEN_CNTL, ~CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B &
+                       state->crtc_gen_cntl);
+       MMIO_W(CRTC_EXT_CNTL, CRTC_EXT_CNTL__CRTC_VSYNC_DIS |
+                       CRTC_EXT_CNTL__CRTC_HSYNC_DIS |
+                       CRTC_EXT_CNTL__CRTC_DISPLAY_DIS |
+                       state->crtc_ext_cntl);
+       MMIO_W(SURFACE_CNTL, state->surface_cntl);
+       MMIO_W(SURFACE0_INFO, state->surface0_info);
+       MMIO_W(SURFACE0_LOWER_BOUND, state->surface0_lower_bound);
+       MMIO_W(SURFACE0_UPPER_BOUND, state->surface0_upper_bound);
+       MMIO_W(SURFACE1_INFO, state->surface1_info);
+       MMIO_W(SURFACE1_LOWER_BOUND, state->surface1_lower_bound);
+       MMIO_W(SURFACE1_UPPER_BOUND, state->surface1_upper_bound);
+       MMIO_W(SURFACE2_INFO, state->surface2_info);
+       MMIO_W(SURFACE2_LOWER_BOUND, state->surface2_lower_bound);
+       MMIO_W(SURFACE2_UPPER_BOUND, state->surface2_upper_bound);
+       MMIO_W(SURFACE3_INFO, state->surface3_info);
+       MMIO_W(SURFACE3_LOWER_BOUND, state->surface3_lower_bound);
+       MMIO_W(SURFACE3_UPPER_BOUND, state->surface3_upper_bound);
+       MMIO_W(SURFACE4_INFO, state->surface4_info);
+       MMIO_W(SURFACE4_LOWER_BOUND, state->surface4_lower_bound);
+       MMIO_W(SURFACE4_UPPER_BOUND, state->surface4_upper_bound);
+       MMIO_W(SURFACE5_INFO, state->surface5_info);
+       MMIO_W(SURFACE5_LOWER_BOUND, state->surface5_lower_bound);
+       MMIO_W(SURFACE5_UPPER_BOUND, state->surface5_upper_bound);
+       MMIO_W(SURFACE6_INFO, state->surface6_info);
+       MMIO_W(SURFACE6_LOWER_BOUND, state->surface6_lower_bound);
+       MMIO_W(SURFACE6_UPPER_BOUND, state->surface6_upper_bound);
+       MMIO_W(SURFACE7_INFO, state->surface7_info);
+       MMIO_W(SURFACE7_LOWER_BOUND, state->surface7_lower_bound);
+       MMIO_W(SURFACE7_UPPER_BOUND, state->surface7_upper_bound);
+       MMIO_W(CRTC_H_TOTAL_DISP, state->crtc_h_total_disp);
+       MMIO_W(CRTC_H_SYNC_STRT_WID, state->crtc_h_sync_strt_wid);
+       MMIO_W(CRTC_V_TOTAL_DISP, state->crtc_v_total_disp);
+       MMIO_W(CRTC_V_SYNC_STRT_WID, state->crtc_v_sync_strt_wid);
+       MMIO_W(FP_H_SYNC_STRT_WID, state->fp_h_sync_strt_wid);
+       MMIO_W(FP_V_SYNC_STRT_WID, state->fp_v_sync_strt_wid);
+       MMIO_W(FP_CRTC_H_TOTAL_DISP, state->fp_crtc_h_total_disp);
+       MMIO_W(FP_CRTC_V_TOTAL_DISP, state->fp_crtc_v_total_disp);
+       MMIO_W(CRTC_TILE_X0_Y0, state->crtc_tile_x0_y0);
+       MMIO_W(CRTC_OFFSET_CNTL, state->crtc_offset_cntl);
+       MMIO_W(CRTC_OFFSET, state->crtc_offset);
+       MMIO_W(CRTC_PITCH, state->crtc_pitch);
+       radeon_pll1_restore(dev_priv, state);
+       MMIO_W(CRTC_MORE_CNTL, state->crtc_more_cntl);
+       MMIO_W(CRTC_GEN_CNTL, state->crtc_gen_cntl);
+       MMIO_W(CRTC_EXT_CNTL, state->crtc_ext_cntl);
+}
+
+/**
+ * radeon_pll1_restore - restore PLL1 state
+ * @dev_priv: radeon private structure
+ * @state: PLL1 state to restore
+ */
+static void radeon_pll1_restore(struct drm_radeon_private *dev_priv,
+                               struct radeon_state *state)
+{
+       uint32_t tmp;
+
+       /* switch to gpu clock while programing new clock */
+       MMIO_W(CLOCK_CNTL_INDEX, state->clock_cntl_index);
+       tmp = state->vclk_ecp_cntl;
+       tmp = REG_S(VCLK_ECP_CNTL, VCLK_SRC_SEL, VCLK_SRC_SEL__CPUCLK);
+       PPLL_W(VCLK_ECP_CNTL, tmp);
+       /* reset PLL and update atomicly */
+       state->ppll_cntl |= PPLL_CNTL__PPLL_ATOMIC_UPDATE_EN |
+               PPLL_CNTL__PPLL_ATOMIC_UPDATE_SYNC; 
+
+       PPLL_W(PPLL_CNTL, state->ppll_cntl | PPLL_CNTL__PPLL_RESET);
+       PPLL_W(PPLL_REF_DIV, state->ppll_ref_div);
+       PPLL_W(PPLL_DIV_0, state->ppll_div_0);
+       PPLL_W(PPLL_DIV_1, state->ppll_div_1);
+       PPLL_W(PPLL_DIV_2, state->ppll_div_2);
+       PPLL_W(PPLL_DIV_3, state->ppll_div_3);
+       PPLL_W(HTOTAL_CNTL, state->htotal_cntl);
+
+       /* update */
+       PPLL_W(PPLL_REF_DIV, state->ppll_ref_div |
+                       PPLL_REF_DIV__PPLL_ATOMIC_UPDATE_W);
+       for (tmp = 0; tmp < 100; tmp++) {
+               if (!(PPLL_REF_DIV__PPLL_ATOMIC_UPDATE_R &
+                                       PPLL_R(PPLL_REF_DIV))) {
+                     break;
+               }
+               DRM_UDELAY(10);
+       }
+       state->ppll_cntl &= ~PPLL_CNTL__PPLL_RESET;
+       PPLL_W(PPLL_CNTL, state->ppll_cntl);
+       PPLL_W(VCLK_ECP_CNTL, state->vclk_ecp_cntl);
+}
+
+/**
+ * radeon_ms_crtc1_save - save CRTC state
+ * @dev_priv: radeon private structure
+ * @state: state where saving current CRTC state
+ */
+void radeon_ms_crtc1_save(struct drm_device *dev, struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       state->surface_cntl = MMIO_R(SURFACE_CNTL);
+       state->surface0_info = MMIO_R(SURFACE0_INFO);
+       state->surface0_lower_bound = MMIO_R(SURFACE0_LOWER_BOUND);
+       state->surface0_upper_bound = MMIO_R(SURFACE0_UPPER_BOUND);
+       state->surface1_info = MMIO_R(SURFACE1_INFO);
+       state->surface1_lower_bound = MMIO_R(SURFACE1_LOWER_BOUND);
+       state->surface1_upper_bound = MMIO_R(SURFACE1_UPPER_BOUND);
+       state->surface2_info = MMIO_R(SURFACE2_INFO);
+       state->surface2_lower_bound = MMIO_R(SURFACE2_LOWER_BOUND);
+       state->surface2_upper_bound = MMIO_R(SURFACE2_UPPER_BOUND);
+       state->surface3_info = MMIO_R(SURFACE3_INFO);
+       state->surface3_lower_bound = MMIO_R(SURFACE3_LOWER_BOUND);
+       state->surface3_upper_bound = MMIO_R(SURFACE3_UPPER_BOUND);
+       state->surface4_info = MMIO_R(SURFACE4_INFO);
+       state->surface4_lower_bound = MMIO_R(SURFACE4_LOWER_BOUND);
+       state->surface4_upper_bound = MMIO_R(SURFACE4_UPPER_BOUND);
+       state->surface5_info = MMIO_R(SURFACE5_INFO);
+       state->surface5_lower_bound = MMIO_R(SURFACE5_LOWER_BOUND);
+       state->surface5_upper_bound = MMIO_R(SURFACE5_UPPER_BOUND);
+       state->surface6_info = MMIO_R(SURFACE6_INFO);
+       state->surface6_lower_bound = MMIO_R(SURFACE6_LOWER_BOUND);
+       state->surface6_upper_bound = MMIO_R(SURFACE6_UPPER_BOUND);
+       state->surface7_info = MMIO_R(SURFACE7_INFO);
+       state->surface7_lower_bound = MMIO_R(SURFACE7_LOWER_BOUND);
+       state->surface7_upper_bound = MMIO_R(SURFACE7_UPPER_BOUND);
+       state->crtc_gen_cntl = MMIO_R(CRTC_GEN_CNTL);
+       state->crtc_ext_cntl = MMIO_R(CRTC_EXT_CNTL);
+       state->crtc_h_total_disp = MMIO_R(CRTC_H_TOTAL_DISP);
+       state->crtc_h_sync_strt_wid = MMIO_R(CRTC_H_SYNC_STRT_WID);
+       state->crtc_v_total_disp = MMIO_R(CRTC_V_TOTAL_DISP);
+       state->crtc_v_sync_strt_wid = MMIO_R(CRTC_V_SYNC_STRT_WID);
+       state->fp_h_sync_strt_wid = MMIO_R(FP_H_SYNC_STRT_WID);
+       state->fp_v_sync_strt_wid = MMIO_R(FP_V_SYNC_STRT_WID);
+       state->fp_crtc_h_total_disp = MMIO_R(FP_CRTC_H_TOTAL_DISP);
+       state->fp_crtc_v_total_disp = MMIO_R(FP_CRTC_V_TOTAL_DISP);
+       state->crtc_offset = MMIO_R(CRTC_OFFSET);
+       state->crtc_offset_cntl = MMIO_R(CRTC_OFFSET_CNTL);
+       state->crtc_pitch = MMIO_R(CRTC_PITCH);
+       state->crtc_more_cntl = MMIO_R(CRTC_MORE_CNTL);
+       state->crtc_tile_x0_y0 =  MMIO_R(CRTC_TILE_X0_Y0);
+       radeon_pll1_save(dev_priv,state);
+}
+
+/**
+ * radeon_pll1_save - save PLL1 state
+ * @dev_priv: radeon private structure
+ * @state: state where saving current PLL1 state
+ */
+static void radeon_pll1_save(struct drm_radeon_private *dev_priv,
+                            struct radeon_state *state)
+{
+       state->clock_cntl_index = MMIO_R(CLOCK_CNTL_INDEX);
+       state->ppll_cntl = PPLL_R(PPLL_CNTL);
+       state->ppll_ref_div = PPLL_R(PPLL_REF_DIV);
+       state->ppll_div_0 = PPLL_R(PPLL_DIV_0);
+       state->ppll_div_1 = PPLL_R(PPLL_DIV_1);
+       state->ppll_div_2 = PPLL_R(PPLL_DIV_2);
+       state->ppll_div_3 = PPLL_R(PPLL_DIV_3);
+       state->vclk_ecp_cntl = PPLL_R(VCLK_ECP_CNTL);
+       state->htotal_cntl = PPLL_R(HTOTAL_CNTL);
+}
+
+static void radeon_ms_crtc1_dpms(struct drm_crtc *crtc, int mode)
+{
+       struct drm_radeon_private *dev_priv = crtc->dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+
+       state->crtc_gen_cntl &= ~CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B;
+       state->crtc_ext_cntl &= ~CRTC_EXT_CNTL__CRTC_DISPLAY_DIS;
+       state->crtc_ext_cntl &= ~CRTC_EXT_CNTL__CRTC_HSYNC_DIS;
+       state->crtc_ext_cntl &= ~CRTC_EXT_CNTL__CRTC_VSYNC_DIS;
+       switch(mode) {
+       case DPMSModeOn:
+               break;
+       case DPMSModeStandby:
+               state->crtc_ext_cntl |=
+                       CRTC_EXT_CNTL__CRTC_DISPLAY_DIS |
+                       CRTC_EXT_CNTL__CRTC_HSYNC_DIS;
+               break;
+       case DPMSModeSuspend:
+               state->crtc_ext_cntl |=
+                       CRTC_EXT_CNTL__CRTC_DISPLAY_DIS |
+                       CRTC_EXT_CNTL__CRTC_VSYNC_DIS;
+               break;
+       case DPMSModeOff:
+               state->crtc_ext_cntl |=
+                       CRTC_EXT_CNTL__CRTC_DISPLAY_DIS |
+                       CRTC_EXT_CNTL__CRTC_HSYNC_DIS |
+                       CRTC_EXT_CNTL__CRTC_VSYNC_DIS;
+               state->crtc_gen_cntl |=
+                       CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B;
+               break;
+       }
+       MMIO_W(CRTC_GEN_CNTL, state->crtc_gen_cntl);
+       MMIO_W(CRTC_EXT_CNTL, state->crtc_ext_cntl);
+
+       dev_priv->crtc1_dpms = mode;
+       /* FIXME: once adding crtc2 remove this */
+       dev_priv->crtc2_dpms = mode;
+       radeon_ms_gpu_dpms(crtc->dev);
+
+       if (mode != DPMSModeOff) {
+               radeon_ms_crtc_load_lut(crtc);
+       }
+}
+
+static bool radeon_ms_crtc_mode_fixup(struct drm_crtc *crtc,
+                                     struct drm_display_mode *mode,
+                                     struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+static void radeon_ms_crtc_mode_prepare(struct drm_crtc *crtc)
+{
+       crtc->funcs->dpms(crtc, DPMSModeOff);
+}
+
+/* Compute n/d with rounding */
+static int radeon_div(int n, int d)
+{
+       return (n + (d / 2)) / d;
+}
+
+/* compute PLL registers values for requested video mode */
+static void radeon_pll1_compute(struct drm_crtc *crtc,
+                               struct drm_display_mode *mode)
+{
+       struct {
+               int divider;
+               int divider_id;
+       } *post_div, post_divs[] = {
+               /* From RAGE 128 VR/RAGE 128 GL Register
+                * Reference Manual (Technical Reference
+                * Manual P/N RRG-G04100-C Rev. 0.04), page
+                * 3-17 (PLL_DIV_[3:0]).
+                */
+               {  1, 0 },              /* VCLK_SRC                 */
+               {  2, 1 },              /* VCLK_SRC/2               */
+               {  4, 2 },              /* VCLK_SRC/4               */
+               {  8, 3 },              /* VCLK_SRC/8               */
+               {  3, 4 },              /* VCLK_SRC/3               */
+               { 16, 5 },              /* VCLK_SRC/16              */
+               {  6, 6 },              /* VCLK_SRC/6               */
+               { 12, 7 },              /* VCLK_SRC/12              */
+               {  0, 0 }
+       };
+       struct drm_radeon_private *dev_priv = crtc->dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+       unsigned long freq = mode->clock / 10;
+       int pll_output_freq;
+       int min_rcenter_dist;
+       int rcenter_dist;
+       int post_divider;
+       int post_divider_id;
+       int ref_div;
+       int fb_div;
+       int vco_freq;
+       int vco_gain;
+
+       /* clamp frequency into pll [min; max] frequency range */
+       if (freq > dev_priv->properties->pll_max_pll_freq) {
+               freq = dev_priv->properties->pll_max_pll_freq;
+       }
+       if (freq < dev_priv->properties->pll_min_pll_freq) {
+               freq = dev_priv->properties->pll_min_pll_freq;
+       }
+       /* select divider so that pll output frequency is the nearest to
+        * the center of [350; 125]Mhz range */
+       min_rcenter_dist = 350 * 100;
+       post_divider = post_divs[0].divider;
+       post_divider_id = post_divs[0].divider_id;
+       for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
+               if (post_div->divider == 0)
+                       break;
+               /* pll output frequency (before post divider) */
+               pll_output_freq = post_div->divider * freq;
+               /* compute distance to [350; 125] range center*/
+               rcenter_dist = abs(pll_output_freq - 11250);
+               if (rcenter_dist < min_rcenter_dist) {
+                       min_rcenter_dist = rcenter_dist;
+                       post_divider = post_div->divider;
+                       post_divider_id = post_div->divider_id;
+               }
+       }
+       pll_output_freq = post_divider * freq;
+       /* select first feedback */
+       state->clock_cntl_index = REG_S(CLOCK_CNTL_INDEX, PPLL_DIV_SEL, 0);
+       /* set ref div so that ref_freq/ref_div is in middle of [2; 3.3]Mhz */
+       ref_div = dev_priv->properties->pll_reference_freq / 265;
+       state->ppll_ref_div = REG_S(PPLL_REF_DIV, PPLL_REF_DIV, ref_div) |
+               REG_S(PPLL_REF_DIV, PPLL_REF_DIV_ACC, ref_div);
+       fb_div = radeon_div(pll_output_freq * ref_div,
+                       dev_priv->properties->pll_reference_freq);
+       state->ppll_div_0 = REG_S(PPLL_DIV_0, PPLL_FB0_DIV, fb_div) |
+               REG_S(PPLL_DIV_0, PPLL_POST0_DIV, post_divider_id);
+       /* configure vco gain */
+       state->ppll_cntl = PPLL_R(PPLL_CNTL);
+       vco_gain = REG_G(PPLL_CNTL, PPLL_PVG, state->ppll_cntl); 
+       vco_freq = (fb_div * dev_priv->properties->pll_reference_freq) /
+               ref_div;
+       /* This is horribly crude: the VCO frequency range is divided into
+        * 3 parts, each part having a fixed PLL gain value.
+        */
+        if (vco_freq >= 30000) {
+               /* [300..max] MHz : 7 */
+               vco_gain = 7;
+       } else if (vco_freq >= 18000) {
+               /* [180..300) MHz : 4 */
+               vco_gain = 4;
+       } else {
+               /* [0..180) MHz : 1 */
+               vco_gain = 1;
+       }
+       state->ppll_cntl |= REG_S(PPLL_CNTL, PPLL_PVG, vco_gain);
+       state->vclk_ecp_cntl |= REG_S(VCLK_ECP_CNTL, VCLK_SRC_SEL,
+                       VCLK_SRC_SEL__PPLLCLK);
+       state->htotal_cntl = 0;
+}
+
+static void radeon_ms_crtc1_mode_set(struct drm_crtc *crtc,
+                                    struct drm_display_mode *mode,
+                                    struct drm_display_mode *adjusted_mode,
+                                    int x, int y)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+       int format, hsync_wid, vsync_wid, pitch;
+
+       DRM_INFO("[radeon_ms] set modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x\n",
+                 mode->mode_id, mode->name, mode->vrefresh, mode->clock,
+                 mode->hdisplay, mode->hsync_start,
+                 mode->hsync_end, mode->htotal,
+                 mode->vdisplay, mode->vsync_start,
+                 mode->vsync_end, mode->vtotal, mode->type);
+       DRM_INFO("[radeon_ms] set modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x (adjusted)\n",
+                 adjusted_mode->mode_id, adjusted_mode->name, adjusted_mode->vrefresh, adjusted_mode->clock,
+                 adjusted_mode->hdisplay, adjusted_mode->hsync_start,
+                 adjusted_mode->hsync_end, adjusted_mode->htotal,
+                 adjusted_mode->vdisplay, adjusted_mode->vsync_start,
+                 adjusted_mode->vsync_end, adjusted_mode->vtotal, adjusted_mode->type);
+
+       /* only support RGB555,RGB565,ARGB8888 should satisfy all users */
+       switch (crtc->fb->bits_per_pixel) {
+       case 16:
+               if (crtc->fb->depth == 15) {
+                       format = 3;
+               } else {
+                       format = 4;
+               }
+               break;
+       case 32:
+               format = 6;
+               break;
+       default:
+               DRM_ERROR("Unknown color depth\n");
+               return;
+       }
+       radeon_pll1_compute(crtc, adjusted_mode);
+
+       state->crtc_offset = REG_S(CRTC_OFFSET, CRTC_OFFSET, crtc->fb->offset);
+       state->crtc_gen_cntl = CRTC_GEN_CNTL__CRTC_EXT_DISP_EN |
+               CRTC_GEN_CNTL__CRTC_EN |
+               REG_S(CRTC_GEN_CNTL, CRTC_PIX_WIDTH, format);
+       if (adjusted_mode->flags & V_DBLSCAN) {
+               state->crtc_gen_cntl |= CRTC_GEN_CNTL__CRTC_DBL_SCAN_EN;
+       }
+       if (adjusted_mode->flags & V_CSYNC) {
+               state->crtc_gen_cntl |= CRTC_GEN_CNTL__CRTC_C_SYNC_EN;
+       }
+       if (adjusted_mode->flags & V_INTERLACE) {
+               state->crtc_gen_cntl |= CRTC_GEN_CNTL__CRTC_INTERLACE_EN;
+       }
+       state->crtc_more_cntl = 0;
+       state->crtc_h_total_disp =
+               REG_S(CRTC_H_TOTAL_DISP,
+                               CRTC_H_TOTAL,
+                               (adjusted_mode->crtc_htotal/8) - 1) |
+               REG_S(CRTC_H_TOTAL_DISP,
+                               CRTC_H_DISP,
+                               (adjusted_mode->crtc_hdisplay/8) - 1);
+       hsync_wid = (adjusted_mode->crtc_hsync_end -
+                    adjusted_mode->crtc_hsync_start) / 8;
+       if (!hsync_wid) {
+               hsync_wid = 1;
+       }
+       if (hsync_wid > 0x3f) {
+               hsync_wid = 0x3f;
+       }
+       state->crtc_h_sync_strt_wid =
+               REG_S(CRTC_H_SYNC_STRT_WID,
+                               CRTC_H_SYNC_WID, hsync_wid) |
+               REG_S(CRTC_H_SYNC_STRT_WID,
+                               CRTC_H_SYNC_STRT_PIX,
+                               adjusted_mode->crtc_hsync_start) |
+               REG_S(CRTC_H_SYNC_STRT_WID,
+                               CRTC_H_SYNC_STRT_CHAR,
+                               adjusted_mode->crtc_hsync_start/8);
+       if (adjusted_mode->flags & V_NHSYNC) {
+               state->crtc_h_sync_strt_wid |=
+                       CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_POL;
+       }
+
+       state->crtc_v_total_disp =
+               REG_S(CRTC_V_TOTAL_DISP, CRTC_V_TOTAL,
+                               adjusted_mode->crtc_vtotal - 1) |
+               REG_S(CRTC_V_TOTAL_DISP, CRTC_V_DISP,
+                               adjusted_mode->crtc_vdisplay - 1);
+       vsync_wid = adjusted_mode->crtc_vsync_end -
+                   adjusted_mode->crtc_vsync_start;
+       if (!vsync_wid) {
+               vsync_wid = 1;
+       }
+       if (vsync_wid > 0x1f) {
+               vsync_wid = 0x1f;
+       }
+       state->crtc_v_sync_strt_wid =
+               REG_S(CRTC_V_SYNC_STRT_WID,
+                               CRTC_V_SYNC_WID,
+                               vsync_wid) |
+               REG_S(CRTC_V_SYNC_STRT_WID,
+                               CRTC_V_SYNC_STRT,
+                               adjusted_mode->crtc_vsync_start);
+       if (adjusted_mode->flags & V_NVSYNC) {
+               state->crtc_v_sync_strt_wid |=
+                       CRTC_V_SYNC_STRT_WID__CRTC_V_SYNC_POL;
+       }
+
+       pitch = (crtc->fb->width * crtc->fb->bits_per_pixel +
+                ((crtc->fb->bits_per_pixel * 8)- 1)) /
+               (crtc->fb->bits_per_pixel * 8);
+       state->crtc_pitch = REG_S(CRTC_PITCH, CRTC_PITCH, pitch) |
+               REG_S(CRTC_PITCH, CRTC_PITCH_RIGHT, pitch);
+
+       state->fp_h_sync_strt_wid = state->crtc_h_sync_strt_wid;
+       state->fp_v_sync_strt_wid = state->crtc_v_sync_strt_wid;
+       state->fp_crtc_h_total_disp = state->crtc_h_total_disp;
+       state->fp_crtc_v_total_disp = state->crtc_v_total_disp;
+
+       radeon_ms_crtc1_restore(dev, state);
+}
+
+static void radeon_ms_crtc_mode_commit(struct drm_crtc *crtc)
+{
+       crtc->funcs->dpms(crtc, DPMSModeOn);
+}
+
+static void radeon_ms_crtc_gamma_set(struct drm_crtc *crtc, u16 r,
+                                    u16 g, u16 b, int regno)
+{
+       struct drm_radeon_private *dev_priv = crtc->dev->dev_private;
+       struct radeon_ms_crtc *radeon_ms_crtc = crtc->driver_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+       uint32_t color;
+
+       switch(radeon_ms_crtc->crtc) {
+       case 1:
+               state->dac_cntl2 &= ~DAC_CNTL2__PALETTE_ACCESS_CNTL;
+               break;
+       case 2:
+               state->dac_cntl2 |= DAC_CNTL2__PALETTE_ACCESS_CNTL;
+               break;
+       }
+       MMIO_W(DAC_CNTL2, state->dac_cntl2);
+       if (crtc->fb->bits_per_pixel == 16 && crtc->fb->depth == 16) {
+               if (regno >= 64) {
+                       return;
+               }
+               MMIO_W(PALETTE_INDEX,
+                               REG_S(PALETTE_INDEX, PALETTE_W_INDEX,
+                                       regno * 4));
+               color = 0;
+               color = REG_S(PALETTE_DATA, PALETTE_DATA_R, r >> 8) |
+                       REG_S(PALETTE_DATA, PALETTE_DATA_G, g >> 8) |
+                       REG_S(PALETTE_DATA, PALETTE_DATA_B, b >> 8);
+               MMIO_W(PALETTE_DATA, color);
+               MMIO_W(PALETTE_INDEX,
+                      REG_S(PALETTE_INDEX, PALETTE_W_INDEX, regno * 4));
+               color = 0;
+               color = REG_S(PALETTE_30_DATA, PALETTE_DATA_R, r >> 6) |
+                       REG_S(PALETTE_30_DATA, PALETTE_DATA_G, g >> 6) |
+                       REG_S(PALETTE_30_DATA, PALETTE_DATA_B, b >> 6);
+               MMIO_W(PALETTE_30_DATA, color);
+               radeon_ms_crtc->lut_r[regno * 4] = r;
+               radeon_ms_crtc->lut_g[regno * 4] = g;
+               radeon_ms_crtc->lut_b[regno * 4] = b;
+               if (regno < 32) {
+                       MMIO_W(PALETTE_INDEX,
+                              REG_S(PALETTE_INDEX, PALETTE_W_INDEX,
+                                      regno * 8));
+                       color = 0;
+                       color = REG_S(PALETTE_DATA, PALETTE_DATA_R, r >> 8) |
+                               REG_S(PALETTE_DATA, PALETTE_DATA_G, g >> 8) |
+                               REG_S(PALETTE_DATA, PALETTE_DATA_B, b >> 8);
+                       MMIO_W(PALETTE_DATA, color);
+                       MMIO_W(PALETTE_INDEX,
+                              REG_S(PALETTE_INDEX, PALETTE_W_INDEX,
+                                     regno * 8));
+                       color = 0;
+                       color = REG_S(PALETTE_30_DATA, PALETTE_DATA_R,r >> 6) |
+                               REG_S(PALETTE_30_DATA, PALETTE_DATA_G,g >> 6) |
+                               REG_S(PALETTE_30_DATA, PALETTE_DATA_B,b >> 6);
+                       MMIO_W(PALETTE_30_DATA, color);
+                       radeon_ms_crtc->lut_r[regno * 8] = r;
+                       radeon_ms_crtc->lut_g[regno * 8] = g;
+                       radeon_ms_crtc->lut_b[regno * 8] = b;
+               }
+       } else {
+               if (regno >= 256) {
+                       return;
+               }
+               radeon_ms_crtc->lut_r[regno] = r;
+               radeon_ms_crtc->lut_g[regno] = g;
+               radeon_ms_crtc->lut_b[regno] = b;
+               MMIO_W(PALETTE_INDEX,
+                      REG_S(PALETTE_INDEX, PALETTE_W_INDEX, regno));
+               color = 0;
+               color = REG_S(PALETTE_DATA, PALETTE_DATA_R, r >> 8) |
+                       REG_S(PALETTE_DATA, PALETTE_DATA_G, g >> 8) |
+                       REG_S(PALETTE_DATA, PALETTE_DATA_B, b >> 8);
+               MMIO_W(PALETTE_DATA, color);
+               MMIO_W(PALETTE_INDEX,
+                               REG_S(PALETTE_INDEX, PALETTE_W_INDEX, regno));
+               color = 0;
+               color = REG_S(PALETTE_30_DATA, PALETTE_DATA_R, r >> 6) |
+                       REG_S(PALETTE_30_DATA, PALETTE_DATA_G, g >> 6) |
+                       REG_S(PALETTE_30_DATA, PALETTE_DATA_B, b >> 6);
+       }
+}
+
+static void radeon_ms_crtc_load_lut(struct drm_crtc *crtc)
+{
+       struct radeon_ms_crtc *radeon_ms_crtc = crtc->driver_private;
+       int i;
+
+       if (!crtc->enabled)
+               return;
+
+       for (i = 0; i < 256; i++) {
+               radeon_ms_crtc_gamma_set(crtc,
+                               radeon_ms_crtc->lut_r[i],
+                               radeon_ms_crtc->lut_g[i],
+                               radeon_ms_crtc->lut_b[i],
+                               i);
+       }
+}
+
+static bool radeon_ms_crtc_lock(struct drm_crtc *crtc)
+{
+    return true;
+}
+
+static void radeon_ms_crtc_unlock(struct drm_crtc *crtc)
+{
+}
+
+static const struct drm_crtc_funcs radeon_ms_crtc1_funcs= {
+       .dpms = radeon_ms_crtc1_dpms,
+       .save = NULL, /* XXX */
+       .restore = NULL, /* XXX */
+       .lock = radeon_ms_crtc_lock,
+       .unlock = radeon_ms_crtc_unlock,
+       .prepare = radeon_ms_crtc_mode_prepare,
+       .commit = radeon_ms_crtc_mode_commit,
+       .mode_fixup = radeon_ms_crtc_mode_fixup,
+       .mode_set = radeon_ms_crtc1_mode_set,
+       .gamma_set = radeon_ms_crtc_gamma_set,
+       .cleanup = NULL, /* XXX */
+};
+
+int radeon_ms_crtc_create(struct drm_device *dev, int crtc)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct drm_crtc *drm_crtc;
+       struct radeon_ms_crtc *radeon_ms_crtc;
+       int i;
+
+       switch (crtc) {
+       case 1:
+               radeon_ms_crtc1_init(dev_priv, &dev_priv->driver_state);
+               drm_crtc = drm_crtc_create(dev, &radeon_ms_crtc1_funcs);
+               break;
+       case 2:
+       default:
+               return -EINVAL;
+       }
+       if (drm_crtc == NULL) {
+               return -ENOMEM;
+       }
+
+       radeon_ms_crtc = drm_alloc(sizeof(struct radeon_ms_crtc), DRM_MEM_DRIVER);
+       if (radeon_ms_crtc == NULL) {
+               kfree(drm_crtc);
+               return -ENOMEM;
+       }
+
+       radeon_ms_crtc->crtc = crtc;
+       for (i = 0; i < 256; i++) {
+               radeon_ms_crtc->lut_r[i] = i << 8;
+               radeon_ms_crtc->lut_g[i] = i << 8;
+               radeon_ms_crtc->lut_b[i] = i << 8;
+       }
+       drm_crtc->driver_private = radeon_ms_crtc;
+       return 0;
+}
diff --git a/shared-core/radeon_ms_dac.c b/shared-core/radeon_ms_dac.c
new file mode 100644 (file)
index 0000000..297623a
--- /dev/null
@@ -0,0 +1,400 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Alex Deucher
+ * Copyright 2007 Dave Airlie
+ * 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 on 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
+ * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR 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 "radeon_ms.h"
+
+int radeon_ms_dac1_initialize(struct radeon_ms_output *output)
+{
+       struct drm_radeon_private *dev_priv = output->dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+
+       state->dac_cntl =
+               REG_S(DAC_CNTL, DAC_RANGE_CNTL, DAC_RANGE_CNTL__PS2) |
+               DAC_CNTL__DAC_8BIT_EN |
+               DAC_CNTL__DAC_VGA_ADR_EN |
+               DAC_CNTL__DAC_PDWN |
+               REG_S(DAC_CNTL, DAC, 0xff);
+       state->dac_ext_cntl = 0;
+       state->dac_macro_cntl =
+               DAC_MACRO_CNTL__DAC_PDWN_R |
+               DAC_MACRO_CNTL__DAC_PDWN_G |
+               DAC_MACRO_CNTL__DAC_PDWN_B |
+               REG_S(DAC_MACRO_CNTL, DAC_WHITE_CNTL, 7) |
+               REG_S(DAC_MACRO_CNTL, DAC_BG_ADJ, 7);
+       state->dac_embedded_sync_cntl =
+               DAC_EMBEDDED_SYNC_CNTL__DAC_EMBED_VSYNC_EN_Y_G;
+       state->dac_broad_pulse = 0;
+       state->dac_skew_clks = 0;
+       state->dac_incr = 0;
+       state->dac_neg_sync_level = 0;
+       state->dac_pos_sync_level = 0;
+       state->dac_blank_level = 0;
+       state->dac_sync_equalization = 0;
+       state->disp_output_cntl = 0;
+       radeon_ms_dac1_restore(output, state);
+       return 0;
+}
+
+enum drm_output_status radeon_ms_dac1_detect(struct radeon_ms_output *output)
+{
+       return output_status_unknown;
+}
+
+void radeon_ms_dac1_dpms(struct radeon_ms_output *output, int mode)
+{
+       struct drm_radeon_private *dev_priv = output->dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+       uint32_t dac_cntl;
+       uint32_t dac_macro_cntl;
+
+       dac_cntl = DAC_CNTL__DAC_PDWN;
+       dac_macro_cntl = DAC_MACRO_CNTL__DAC_PDWN_R |
+               DAC_MACRO_CNTL__DAC_PDWN_G |
+               DAC_MACRO_CNTL__DAC_PDWN_B;
+       switch(mode) {
+       case DPMSModeOn:
+               state->dac_cntl &= ~dac_cntl;
+               state->dac_macro_cntl &= ~dac_macro_cntl;
+               break;
+       case DPMSModeStandby:
+       case DPMSModeSuspend:
+       case DPMSModeOff:
+               state->dac_cntl |= dac_cntl;
+               state->dac_macro_cntl |= dac_macro_cntl;
+               break;
+       default:
+               /* error */
+               break;
+       }
+       MMIO_W(DAC_CNTL, state->dac_cntl);
+       MMIO_W(DAC_MACRO_CNTL, state->dac_macro_cntl);
+}
+
+int radeon_ms_dac1_get_modes(struct radeon_ms_output *output)
+{
+       return 0;
+}
+
+bool radeon_ms_dac1_mode_fixup(struct radeon_ms_output *output,
+               struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+int radeon_ms_dac1_mode_set(struct radeon_ms_output *output,
+               struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode)
+{
+       struct drm_radeon_private *dev_priv = output->dev->dev_private;
+       struct radeon_ms_connector *connector = output->connector;
+       struct radeon_state *state = &dev_priv->driver_state;
+       uint32_t v = 0;
+
+       if (connector == NULL) {
+               /* output not associated with a connector */
+               return -EINVAL;
+       }
+       state->disp_output_cntl &= ~DISP_OUTPUT_CNTL__DISP_DAC_SOURCE__MASK;
+       state->dac_cntl2 &= ~DAC_CNTL2__DAC_CLK_SEL;
+       switch (connector->crtc) {
+       case 1:
+               v =  DISP_DAC_SOURCE__PRIMARYCRTC;
+               break;
+       case 2:
+               v =  DISP_DAC_SOURCE__SECONDARYCRTC;
+               state->dac_cntl2 |= DAC_CNTL2__DAC_CLK_SEL;
+               break;
+       }
+       state->disp_output_cntl |= REG_S(DISP_OUTPUT_CNTL, DISP_DAC_SOURCE, v);
+       MMIO_W(DISP_OUTPUT_CNTL, state->disp_output_cntl);
+       MMIO_W(DAC_CNTL2, state->dac_cntl2);
+       return 0;
+}
+
+void radeon_ms_dac1_restore(struct radeon_ms_output *output,
+               struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = output->dev->dev_private;
+
+       MMIO_W(DAC_CNTL, state->dac_cntl);
+       MMIO_W(DAC_EXT_CNTL, state->dac_ext_cntl);
+       MMIO_W(DAC_MACRO_CNTL, state->dac_macro_cntl);
+       MMIO_W(DAC_EMBEDDED_SYNC_CNTL, state->dac_embedded_sync_cntl);
+       MMIO_W(DAC_BROAD_PULSE, state->dac_broad_pulse);
+       MMIO_W(DAC_SKEW_CLKS, state->dac_skew_clks);
+       MMIO_W(DAC_INCR, state->dac_incr);
+       MMIO_W(DAC_NEG_SYNC_LEVEL, state->dac_neg_sync_level);
+       MMIO_W(DAC_POS_SYNC_LEVEL, state->dac_pos_sync_level);
+       MMIO_W(DAC_BLANK_LEVEL, state->dac_blank_level);
+       MMIO_W(DAC_SYNC_EQUALIZATION, state->dac_sync_equalization);
+}
+
+void radeon_ms_dac1_save(struct radeon_ms_output *output,
+               struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = output->dev->dev_private;
+
+       state->dac_cntl = MMIO_R(DAC_CNTL);
+       state->dac_ext_cntl = MMIO_R(DAC_EXT_CNTL);
+       state->dac_macro_cntl = MMIO_R(DAC_MACRO_CNTL);
+       state->dac_embedded_sync_cntl = MMIO_R(DAC_EMBEDDED_SYNC_CNTL);
+       state->dac_broad_pulse = MMIO_R(DAC_BROAD_PULSE);
+       state->dac_skew_clks = MMIO_R(DAC_SKEW_CLKS);
+       state->dac_incr = MMIO_R(DAC_INCR);
+       state->dac_neg_sync_level = MMIO_R(DAC_NEG_SYNC_LEVEL);
+       state->dac_pos_sync_level = MMIO_R(DAC_POS_SYNC_LEVEL);
+       state->dac_blank_level = MMIO_R(DAC_BLANK_LEVEL);
+       state->dac_sync_equalization = MMIO_R(DAC_SYNC_EQUALIZATION);
+}
+
+int radeon_ms_dac2_initialize(struct radeon_ms_output *output)
+{
+       struct drm_radeon_private *dev_priv = output->dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+
+       state->tv_dac_cntl = TV_DAC_CNTL__BGSLEEP |
+               REG_S(TV_DAC_CNTL, STD, STD__PS2) |
+               REG_S(TV_DAC_CNTL, BGADJ, 0);
+       switch (dev_priv->family) {
+       case CHIP_R100:
+       case CHIP_R200:
+       case CHIP_RV200:
+       case CHIP_RV250:
+       case CHIP_RV280:
+       case CHIP_RS300:
+       case CHIP_R300:
+       case CHIP_R350:
+       case CHIP_R360:
+       case CHIP_RV350:
+       case CHIP_RV370:
+       case CHIP_RV380:
+       case CHIP_RS400:
+               state->tv_dac_cntl |= TV_DAC_CNTL__RDACPD |
+                       TV_DAC_CNTL__GDACPD |
+                       TV_DAC_CNTL__BDACPD |
+                       REG_S(TV_DAC_CNTL, DACADJ, 0);
+               break;
+       case CHIP_RV410:
+       case CHIP_R420:
+       case CHIP_R430:
+       case CHIP_R480:
+               state->tv_dac_cntl |= TV_DAC_CNTL__RDACPD_R4 |
+                       TV_DAC_CNTL__GDACPD_R4 |
+                       TV_DAC_CNTL__BDACPD_R4 |
+                       REG_S(TV_DAC_CNTL, DACADJ_R4, 0);
+               break;
+       }
+       state->tv_master_cntl = TV_MASTER_CNTL__TV_ASYNC_RST |
+               TV_MASTER_CNTL__CRT_ASYNC_RST |
+               TV_MASTER_CNTL__RESTART_PHASE_FIX |
+               TV_MASTER_CNTL__CRT_FIFO_CE_EN |
+               TV_MASTER_CNTL__TV_FIFO_CE_EN;
+       state->dac_cntl2 = 0;
+       state->disp_output_cntl = 0;
+       radeon_ms_dac2_restore(output, state);
+       return 0;
+}
+
+enum drm_output_status radeon_ms_dac2_detect(struct radeon_ms_output *output)
+{
+       return output_status_unknown;
+}
+
+void radeon_ms_dac2_dpms(struct radeon_ms_output *output, int mode)
+{
+       struct drm_radeon_private *dev_priv = output->dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+       uint32_t tv_dac_cntl_on, tv_dac_cntl_off;
+
+       tv_dac_cntl_off = TV_DAC_CNTL__BGSLEEP;
+       tv_dac_cntl_on = TV_DAC_CNTL__NBLANK |
+                        TV_DAC_CNTL__NHOLD;
+       switch (dev_priv->family) {
+       case CHIP_R100:
+       case CHIP_R200:
+       case CHIP_RV200:
+       case CHIP_RV250:
+       case CHIP_RV280:
+       case CHIP_RS300:
+       case CHIP_R300:
+       case CHIP_R350:
+       case CHIP_R360:
+       case CHIP_RV350:
+       case CHIP_RV370:
+       case CHIP_RV380:
+       case CHIP_RS400:
+               tv_dac_cntl_off |= TV_DAC_CNTL__RDACPD |
+                       TV_DAC_CNTL__GDACPD |
+                       TV_DAC_CNTL__BDACPD;
+               break;
+       case CHIP_RV410:
+       case CHIP_R420:
+       case CHIP_R430:
+       case CHIP_R480:
+               tv_dac_cntl_off |= TV_DAC_CNTL__RDACPD_R4 |
+                       TV_DAC_CNTL__GDACPD_R4 |
+                       TV_DAC_CNTL__BDACPD_R4;
+               break;
+       }
+       switch(mode) {
+       case DPMSModeOn:
+               state->tv_dac_cntl &= ~tv_dac_cntl_off;
+               state->tv_dac_cntl |= tv_dac_cntl_on;
+               break;
+       case DPMSModeStandby:
+       case DPMSModeSuspend:
+       case DPMSModeOff:
+               state->tv_dac_cntl &= ~tv_dac_cntl_on;
+               state->tv_dac_cntl |= tv_dac_cntl_off;
+               break;
+       default:
+               /* error */
+               break;
+       }
+       MMIO_W(TV_DAC_CNTL, state->tv_dac_cntl);
+}
+
+int radeon_ms_dac2_get_modes(struct radeon_ms_output *output)
+{
+       return 0;
+}
+
+bool radeon_ms_dac2_mode_fixup(struct radeon_ms_output *output,
+               struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+int radeon_ms_dac2_mode_set(struct radeon_ms_output *output,
+               struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode)
+{
+       struct drm_radeon_private *dev_priv = output->dev->dev_private;
+       struct radeon_ms_connector *connector = output->connector;
+       struct radeon_state *state = &dev_priv->driver_state;
+
+       if (connector == NULL) {
+               /* output not associated with a connector */
+               return -EINVAL;
+       }
+       switch (dev_priv->family) {
+       case CHIP_R100:
+       case CHIP_R200:
+               state->disp_output_cntl &= ~DISP_OUTPUT_CNTL__DISP_TV_SOURCE;
+               switch (connector->crtc) {
+               case 1:
+                       break;
+               case 2:
+                       state->disp_output_cntl |=
+                               DISP_OUTPUT_CNTL__DISP_TV_SOURCE;
+                       break;
+               }
+               break;
+       case CHIP_RV200:
+       case CHIP_RV250:
+       case CHIP_RV280:
+       case CHIP_RS300:
+               break;
+       case CHIP_R300:
+       case CHIP_R350:
+       case CHIP_R360:
+       case CHIP_RV350:
+       case CHIP_RV370:
+       case CHIP_RV380:
+       case CHIP_RS400:
+       case CHIP_RV410:
+       case CHIP_R420:
+       case CHIP_R430:
+       case CHIP_R480:
+               state->disp_output_cntl &=
+                       ~DISP_OUTPUT_CNTL__DISP_TVDAC_SOURCE__MASK;
+               switch (connector->crtc) {
+               case 1:
+                       state->disp_output_cntl |=
+                               REG_S(DISP_OUTPUT_CNTL,
+                                               DISP_TVDAC_SOURCE,
+                                               DISP_TVDAC_SOURCE__PRIMARYCRTC);
+                               break;
+               case 2:
+                               state->disp_output_cntl |=
+                                       REG_S(DISP_OUTPUT_CNTL,
+                                                       DISP_TVDAC_SOURCE,
+                                                       DISP_TVDAC_SOURCE__SECONDARYCRTC);
+                               break;
+               }
+               break;
+       }
+       switch (dev_priv->family) {
+       case CHIP_R200:
+               break;
+       case CHIP_R100:
+       case CHIP_RV200:
+       case CHIP_RV250:
+       case CHIP_RV280:
+       case CHIP_RS300:
+       case CHIP_R300:
+       case CHIP_R350:
+       case CHIP_R360:
+       case CHIP_RV350:
+       case CHIP_RV370:
+       case CHIP_RV380:
+       case CHIP_RS400:
+       case CHIP_RV410:
+       case CHIP_R420:
+       case CHIP_R430:
+       case CHIP_R480:
+               if (connector->type != CONNECTOR_CTV &&
+                               connector->type != CONNECTOR_STV) {
+                       state->dac_cntl2 |= DAC_CNTL2__DAC2_CLK_SEL;
+               }
+       }
+       MMIO_W(DAC_CNTL2, state->dac_cntl2);
+       MMIO_W(DISP_OUTPUT_CNTL, state->disp_output_cntl);
+       return 0;
+}
+
+void radeon_ms_dac2_restore(struct radeon_ms_output *output,
+               struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = output->dev->dev_private;
+
+       MMIO_W(DAC_CNTL2, state->dac_cntl2);
+       MMIO_W(TV_DAC_CNTL, state->tv_dac_cntl);
+       MMIO_W(TV_MASTER_CNTL, state->tv_master_cntl);
+}
+
+void radeon_ms_dac2_save(struct radeon_ms_output *output,
+               struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = output->dev->dev_private;
+
+       state->dac_cntl2 = MMIO_R(DAC_CNTL2);
+       state->tv_dac_cntl = MMIO_R(TV_DAC_CNTL);
+       state->tv_master_cntl = MMIO_R(TV_MASTER_CNTL);
+}
diff --git a/shared-core/radeon_ms_drm.c b/shared-core/radeon_ms_drm.c
new file mode 100644 (file)
index 0000000..b22c83a
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Alex Deucher
+ * Copyright 2007 Dave Airlie
+ * 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
+ * PRECISION INSIGHT 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.
+ */
+/*
+ * Authors:
+ *    Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "drm_pciids.h"
+#include "radeon_ms.h"
+
+
+static uint32_t radeon_ms_mem_prios[] = {
+       DRM_BO_MEM_VRAM,
+       DRM_BO_MEM_TT,
+       DRM_BO_MEM_LOCAL,
+};
+
+static uint32_t radeon_ms_busy_prios[] = {
+       DRM_BO_MEM_TT,
+       DRM_BO_MEM_VRAM,
+       DRM_BO_MEM_LOCAL,
+};
+
+struct drm_fence_driver radeon_ms_fence_driver = {
+       .num_classes = 1,
+       .wrap_diff = (1 << 30),
+       .flush_diff = (1 << 29),
+       .sequence_mask = 0xffffffffU,
+       .lazy_capable = 1,
+       .emit = radeon_ms_fence_emit_sequence,
+       .poke_flush = radeon_ms_poke_flush,
+       .has_irq = radeon_ms_fence_has_irq,
+};
+
+struct drm_bo_driver radeon_ms_bo_driver = {
+       .mem_type_prio = radeon_ms_mem_prios,
+       .mem_busy_prio = radeon_ms_busy_prios,
+       .num_mem_type_prio = sizeof(radeon_ms_mem_prios)/sizeof(uint32_t),
+       .num_mem_busy_prio = sizeof(radeon_ms_busy_prios)/sizeof(uint32_t),
+       .create_ttm_backend_entry = radeon_ms_create_ttm_backend,
+       .fence_type = radeon_ms_fence_types,
+       .invalidate_caches = radeon_ms_invalidate_caches,
+       .init_mem_type = radeon_ms_init_mem_type,
+       .evict_mask = radeon_ms_evict_mask,
+       .move = radeon_ms_bo_move,
+       .ttm_cache_flush = radeon_ms_ttm_flush,
+};
+
+struct drm_ioctl_desc radeon_ms_ioctls[] = {
+       DRM_IOCTL_DEF(DRM_RADEON_EXECBUFFER, radeon_ms_execbuffer, DRM_AUTH),
+};
+int radeon_ms_num_ioctls = DRM_ARRAY_SIZE(radeon_ms_ioctls);
+
+int radeon_ms_driver_dma_ioctl(struct drm_device *dev, void *data,
+                              struct drm_file *file_priv)
+{
+       struct drm_device_dma *dma = dev->dma;
+       struct drm_dma *d = data;
+
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
+
+       /* Please don't send us buffers.
+        */
+       if (d->send_count != 0) {
+               DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
+                         DRM_CURRENTPID, d->send_count);
+               return -EINVAL;
+       }
+
+       /* Don't ask us buffer neither :)
+        */
+       DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
+                 DRM_CURRENTPID, d->request_count, dma->buf_count);
+       return -EINVAL;
+}
+
+void radeon_ms_driver_lastclose(struct drm_device * dev)
+{
+}
+
+int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags)
+{
+       struct drm_radeon_private *dev_priv;
+       int ret = 0;
+
+       DRM_INFO("[radeon_ms] loading\n");
+       /* allocate and clear device private structure */
+       dev_priv = drm_alloc(sizeof(struct drm_radeon_private), DRM_MEM_DRIVER);
+       if (dev_priv == NULL)
+               return -ENOMEM;
+       memset(dev_priv, 0, sizeof(struct drm_radeon_private));
+       dev->dev_private = (void *)dev_priv;
+
+       /* initialize modesetting structure (must be done here) */
+       drm_mode_config_init(dev);
+
+       /* flags correspond to chipset family */
+       dev_priv->usec_timeout = 100;
+       dev_priv->family = flags & 0xffffU;
+       dev_priv->bus_type = flags & 0xff0000U;
+       /* initialize family functions */
+       ret = radeon_ms_family_init(dev);
+       if (ret != 0) {
+               radeon_ms_driver_unload(dev);
+               return ret;
+       }
+
+       /* we don't want userspace to be able to map this so don't use
+        * drm_addmap */
+       dev_priv->mmio.offset = drm_get_resource_start(dev, 2);
+       dev_priv->mmio.size = drm_get_resource_len(dev, 2);
+       dev_priv->mmio.type = _DRM_REGISTERS;
+       dev_priv->mmio.flags = _DRM_RESTRICTED;
+       drm_core_ioremap(&dev_priv->mmio, dev); 
+       /* map vram FIXME: IGP likely don't have any of this */
+       dev_priv->vram.offset = drm_get_resource_start(dev, 0);
+       dev_priv->vram.size = drm_get_resource_len(dev, 0);
+       dev_priv->vram.type = _DRM_FRAME_BUFFER;
+       dev_priv->vram.flags = _DRM_RESTRICTED;
+       drm_core_ioremap(&dev_priv->vram, dev);
+
+       /* save radeon initial state which will be restored upon module
+        * exit */
+       radeon_ms_state_save(dev, &dev_priv->load_state);
+       dev_priv->restore_state = 1;
+       memcpy(&dev_priv->driver_state, &dev_priv->load_state,
+              sizeof(struct radeon_state));
+
+       /* initialize irq */
+       ret = radeon_ms_irq_init(dev);
+       if (ret != 0) {
+               radeon_ms_driver_unload(dev);
+               return ret;
+       }
+
+       /* init bo driver */
+       dev_priv->fence_id_last = 1;
+       dev_priv->fence_reg = SCRATCH_REG2;
+       drm_bo_driver_init(dev);
+       /* initialize vram */
+       ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, dev_priv->vram.size);
+       if (ret != 0) {
+               radeon_ms_driver_unload(dev);
+               return ret;
+       }
+
+       /* initialize gpu address space (only after) VRAM initialization */
+       ret = radeon_ms_gpu_initialize(dev);
+       if (ret != 0) {
+               radeon_ms_driver_unload(dev);
+               return ret;
+       }
+       radeon_ms_gpu_restore(dev, &dev_priv->driver_state);
+       dev_priv->bus_ready = 1;
+
+       /* initialize ttm */
+       ret = drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0,
+                            dev_priv->gpu_gart_size / RADEON_PAGE_SIZE);
+       if (ret != 0) {
+               radeon_ms_driver_unload(dev);
+               return ret;
+       }
+
+       /* initialize ring buffer */
+       /* set ring size to 4Mo FIXME: should make a parameter for this */
+       dev_priv->write_back_area_size = 4 * 1024;
+       dev_priv->ring_buffer_size = 4 * 1024 * 1024;
+       ret = radeon_ms_cp_init(dev);
+       if (ret != 0) {
+               radeon_ms_driver_unload(dev);
+               return ret;
+       }
+
+       /* initialize modesetting */
+       dev->mode_config.min_width = 0;
+       dev->mode_config.min_height = 0;
+       dev->mode_config.max_width = 4096;
+       dev->mode_config.max_height = 4096;
+       dev->mode_config.fb_base = dev_priv->vram.offset;
+       ret = radeon_ms_crtc_create(dev, 1);
+       if (ret != 0) {
+               radeon_ms_driver_unload(dev);
+               return ret;
+       }
+       ret = radeon_ms_outputs_from_properties(dev);
+       if (ret != 0) {
+               radeon_ms_driver_unload(dev);
+               return ret;
+       }
+       ret = radeon_ms_connectors_from_properties(dev);
+       if (ret != 0) {
+               radeon_ms_driver_unload(dev);
+               return ret;
+       }
+       radeon_ms_outputs_save(dev, &dev_priv->load_state);
+       drm_initial_config(dev, false);
+
+       ret = drm_irq_install(dev);
+       if (ret != 0) {
+               radeon_ms_driver_unload(dev);
+               return ret;
+       }
+
+       DRM_INFO("[radeon_ms] successfull initialization\n");
+       return 0;
+}
+
+int radeon_ms_driver_open(struct drm_device * dev, struct drm_file *file_priv)
+{
+       return 0;
+}
+
+
+int radeon_ms_driver_unload(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       if (dev_priv == NULL) {
+               return 0;
+       }
+
+       /* cleanup modesetting */
+       drm_mode_config_cleanup(dev);
+       DRM_INFO("[radeon_ms] modesetting clean\n");
+       radeon_ms_outputs_restore(dev, &dev_priv->load_state);
+       radeon_ms_connectors_destroy(dev);
+       radeon_ms_outputs_destroy(dev);
+       
+       /* shutdown cp engine */
+       radeon_ms_cp_finish(dev);
+       DRM_INFO("[radeon_ms] cp clean\n");
+
+       drm_irq_uninstall(dev);
+       DRM_INFO("[radeon_ms] irq uninstalled\n");
+
+       DRM_INFO("[radeon_ms] unloading\n");
+       /* clean ttm memory manager */
+       mutex_lock(&dev->struct_mutex);
+       if (drm_bo_clean_mm(dev, DRM_BO_MEM_TT)) {
+               DRM_ERROR("TT memory manager not clean. Delaying takedown\n");
+       }
+       mutex_unlock(&dev->struct_mutex);
+       DRM_INFO("[radeon_ms] TT memory clean\n");
+       /* finish */
+       if (dev_priv->bus_finish) {
+               dev_priv->bus_finish(dev);
+       }
+       DRM_INFO("[radeon_ms] bus down\n");
+       /* clean vram memory manager */
+       mutex_lock(&dev->struct_mutex);
+       if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM)) {
+               DRM_ERROR("VRAM memory manager not clean. Delaying takedown\n");
+       }
+       mutex_unlock(&dev->struct_mutex);
+       DRM_INFO("[radeon_ms] VRAM memory clean\n");
+       /* clean memory manager */
+       drm_bo_driver_finish(dev);
+       DRM_INFO("[radeon_ms] memory manager clean\n");
+       /* restore card state */
+       if (dev_priv->restore_state) {
+               radeon_ms_state_restore(dev, &dev_priv->load_state);
+       }
+       DRM_INFO("[radeon_ms] state restored\n");
+       if (dev_priv->mmio.handle) {
+               drm_core_ioremapfree(&dev_priv->mmio, dev);
+       }
+       if (dev_priv->vram.handle) {
+               drm_core_ioremapfree(&dev_priv->vram, dev);
+       }
+       DRM_INFO("[radeon_ms] map released\n");
+       drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
+       dev->dev_private = NULL;
+
+       DRM_INFO("[radeon_ms] that's all the folks\n");
+       return 0;
+}
+
diff --git a/shared-core/radeon_ms_drm.h b/shared-core/radeon_ms_drm.h
new file mode 100644 (file)
index 0000000..842d533
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Dave Airlie
+ * Copyright 2007 Alex Deucher
+ * 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
+ * PRECISION INSIGHT 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.
+ */
+/*
+ * Authors:
+ *    Jérôme Glisse <glisse@freedesktop.org>
+ */
+#ifndef __RADEON_MS_DRM_H__
+#define __RADEON_MS_DRM_H__
+
+/* fence definitions */
+/* The only fence class we support */
+#define DRM_RADEON_FENCE_CLASS_ACCEL 0
+/* Fence type that guarantees read-write flush */
+#define DRM_RADEON_FENCE_TYPE_RW 2
+/* cache flushes programmed just before the fence */
+#define DRM_RADEON_FENCE_FLAG_FLUSHED 0x01000000
+
+/* radeon ms ioctl */
+#define DRM_RADEON_EXECBUFFER  0x00
+
+struct drm_radeon_execbuffer_arg {
+       uint64_t    next;
+       uint32_t    reloc_offset;
+       union {
+               struct drm_bo_op_req    req;
+               struct drm_bo_arg_rep   rep;
+       } d;
+};
+
+struct drm_radeon_execbuffer {
+       uint32_t args_count;
+       uint64_t args;
+       uint32_t cmd_size;
+       struct drm_fence_arg fence_arg;
+};
+
+#endif
diff --git a/shared-core/radeon_ms_exec.c b/shared-core/radeon_ms_exec.c
new file mode 100644 (file)
index 0000000..b2ce3cb
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * 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
+ * PRECISION INSIGHT 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.
+ *
+ * Authors:
+ *    Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "radeon_ms.h"
+
+static void radeon_ms_execbuffer_args_clean(struct drm_device *dev,
+                                           struct drm_buffer_object **buffers,
+                                           uint32_t args_count)
+{
+       mutex_lock(&dev->struct_mutex);
+       while (args_count--) {
+               drm_bo_usage_deref_locked(&buffers[args_count]);
+       }
+       mutex_unlock(&dev->struct_mutex);
+}
+
+static int radeon_ms_execbuffer_args(struct drm_device *dev,
+                                    struct drm_file *file_priv,
+                                    struct drm_radeon_execbuffer *execbuffer,
+                                    struct drm_buffer_object **buffers,
+                                    uint32_t *relocs)
+{
+       struct drm_radeon_execbuffer_arg arg;
+       struct drm_bo_arg_rep rep;
+       uint32_t args_count = 0;
+       uint64_t next = 0;
+       uint64_t data = execbuffer->args;
+       int ret = 0;
+
+       do {
+               if (args_count >= execbuffer->args_count) {
+                       DRM_ERROR("[radeon_ms] buffer count exceeded %d\n.",
+                                 execbuffer->args_count);
+                       ret = -EINVAL;
+                       goto out_err;
+               }
+               buffers[args_count] = NULL;
+               if (copy_from_user(&arg, (void __user *)((unsigned)data),
+                   sizeof(struct drm_radeon_execbuffer_arg))) {
+                       ret = -EFAULT;
+                       goto out_err;
+               }
+               mutex_lock(&dev->struct_mutex);
+               buffers[args_count] =
+                       drm_lookup_buffer_object(file_priv,
+                                                arg.d.req.arg_handle, 1);
+               relocs[args_count] = arg.reloc_offset;
+               mutex_unlock(&dev->struct_mutex);
+               if (arg.d.req.op != drm_bo_validate) {
+                       DRM_ERROR("[radeon_ms] buffer object operation wasn't "
+                                 "validate.\n");
+                       ret = -EINVAL;
+                       goto out_err;
+               }
+               memset(&rep, 0, sizeof(struct drm_bo_arg_rep));
+               if (args_count >= 1) {
+                       ret = drm_bo_handle_validate(file_priv,
+                                                    arg.d.req.bo_req.handle,
+                                                    arg.d.req.bo_req.fence_class,
+                                                    arg.d.req.bo_req.flags,
+                                                    arg.d.req.bo_req.mask,
+                                                    arg.d.req.bo_req.hint,
+                                                    0,
+                                                    &rep.bo_info,
+                                                    &buffers[args_count]);
+               }
+               if (ret) {
+                       DRM_ERROR("[radeon_ms] error on handle validate %d\n",
+                                 ret);
+                       rep.ret = ret;
+                       goto out_err;
+               }
+               next = arg.next;
+               arg.d.rep = rep;
+               if (copy_to_user((void __user *)((unsigned)data), &arg,
+                   sizeof(struct drm_radeon_execbuffer_arg))) {
+                       ret = -EFAULT;
+                       goto out_err;
+               }
+               data = next;
+               args_count++;
+       } while (next != 0);
+       if (args_count != execbuffer->args_count) {
+               DRM_ERROR("[radeon_ms] not enought buffer got %d waited %d\n.",
+                         args_count, execbuffer->args_count);
+               ret = -EINVAL;
+               goto out_err;
+       }
+       return 0;
+out_err:
+       radeon_ms_execbuffer_args_clean(dev, buffers, args_count);
+       return ret;
+}
+
+static int radeon_ms_execbuffer_check(struct drm_device *dev,
+                                     struct drm_file *file_priv,
+                                     struct drm_radeon_execbuffer *execbuffer,
+                                     struct drm_buffer_object **buffers,
+                                     uint32_t *relocs,
+                                     uint32_t *cmd)
+{
+       uint32_t i, gpu_addr;
+       int ret;
+
+       for (i = 0; i < execbuffer->args_count; i++) {
+               if (relocs[i]) {
+                       ret = radeon_ms_bo_get_gpu_addr(dev, &buffers[i]->mem,
+                                                       &gpu_addr);
+                       if (ret) {
+                               return ret;
+                       }
+                       cmd[relocs[i]] |= (gpu_addr) >> 10;
+               }
+       }
+       for (i = 0; i < execbuffer->cmd_size; i++) {
+#if 0
+               DRM_INFO("cmd[%d]=0x%08X\n", i, cmd[i]);
+#endif
+       }
+       return 0;
+}
+
+int radeon_ms_execbuffer(struct drm_device *dev, void *data,
+                        struct drm_file *file_priv)
+{
+       struct drm_radeon_execbuffer *execbuffer = data;
+       struct drm_fence_arg *fence_arg = &execbuffer->fence_arg;
+       struct drm_buffer_object **buffers;
+       struct drm_bo_kmap_obj cmd_kmap;
+       struct drm_fence_object *fence;
+       uint32_t *relocs;
+       uint32_t *cmd;
+       int cmd_is_iomem;
+       int ret = 0;
+
+
+       ret = drm_bo_read_lock(&dev->bm.bm_lock);
+       if (ret) {
+               return ret;
+       }
+
+       relocs = drm_calloc(execbuffer->args_count, sizeof(uint32_t),
+                           DRM_MEM_DRIVER);
+       if (relocs == NULL) {
+               drm_bo_read_unlock(&dev->bm.bm_lock);
+               return -ENOMEM;
+        }
+       buffers = drm_calloc(execbuffer->args_count,
+                            sizeof(struct drm_buffer_object *),
+                            DRM_MEM_DRIVER);
+       if (buffers == NULL) {
+               drm_free(relocs, (execbuffer->args_count * sizeof(uint32_t)),
+                        DRM_MEM_DRIVER);
+               drm_bo_read_unlock(&dev->bm.bm_lock);
+               return -ENOMEM;
+        }
+       /* process arguments */
+       ret = radeon_ms_execbuffer_args(dev, file_priv, execbuffer,
+                                       buffers, relocs);
+       if (ret) {
+               DRM_ERROR("[radeon_ms] execbuffer wrong arguments\n");
+               goto out_free;
+       }
+       /* map command buffer */
+       memset(&cmd_kmap, 0, sizeof(struct drm_bo_kmap_obj));
+       ret = drm_bo_kmap(buffers[0],
+                         0,
+                         buffers[0]->mem.num_pages,
+                         &cmd_kmap);
+       if (ret) {
+               DRM_ERROR("[radeon_ms] error mapping ring buffer: %d\n", ret);
+               goto out_free_release;
+       }
+       cmd = drm_bmo_virtual(&cmd_kmap, &cmd_is_iomem);
+       /* do cmd checking & relocations */
+       ret = radeon_ms_execbuffer_check(dev, file_priv, execbuffer,
+                                        buffers, relocs, cmd);
+       if (ret) {
+               drm_putback_buffer_objects(dev);
+               goto out_free_release;
+       }
+
+       ret = radeon_ms_ring_emit(dev, cmd, execbuffer->cmd_size);
+       if (ret) {
+               drm_putback_buffer_objects(dev);
+               goto out_free_release;
+       }
+
+       /* fence */
+       ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence);
+       if (ret) {
+               drm_putback_buffer_objects(dev);
+               DRM_ERROR("[radeon_ms] fence buffer objects failed\n");
+               goto out_free_release;
+       }
+       if (!(fence_arg->flags & DRM_FENCE_FLAG_NO_USER)) {
+               ret = drm_fence_add_user_object(file_priv, fence,
+                                               fence_arg->flags & DRM_FENCE_FLAG_SHAREABLE);
+               if (!ret) {
+                       fence_arg->handle = fence->base.hash.key;
+                       fence_arg->fence_class = fence->fence_class;
+                       fence_arg->type = fence->type;
+                       fence_arg->signaled = fence->signaled;
+                       fence_arg->sequence = fence->sequence;
+               }
+       }
+       drm_fence_usage_deref_unlocked(&fence);
+out_free_release:
+       drm_bo_kunmap(&cmd_kmap);
+       radeon_ms_execbuffer_args_clean(dev, buffers, execbuffer->args_count);
+out_free:
+       drm_free(relocs, (execbuffer->args_count * sizeof(uint32_t)),
+                DRM_MEM_DRIVER);
+       drm_free(buffers,
+                (execbuffer->args_count * sizeof(struct drm_buffer_object *)),
+                DRM_MEM_DRIVER);
+       drm_bo_read_unlock(&dev->bm.bm_lock);
+       return ret;
+}
diff --git a/shared-core/radeon_ms_family.c b/shared-core/radeon_ms_family.c
new file mode 100644 (file)
index 0000000..ea5f6ca
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * 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
+ * PRECISION INSIGHT 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.
+ */
+/*
+ * Authors:
+ *    Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_ms.h"
+
+static struct radeon_ms_output radeon_ms_dac1 = {
+       OUTPUT_DAC1,
+       NULL,
+       NULL,
+       radeon_ms_dac1_initialize,
+       radeon_ms_dac1_detect,
+       radeon_ms_dac1_dpms,
+       radeon_ms_dac1_get_modes,
+       radeon_ms_dac1_mode_fixup,
+       radeon_ms_dac1_mode_set,
+       radeon_ms_dac1_restore,
+       radeon_ms_dac1_save
+};
+
+static struct radeon_ms_output radeon_ms_dac2 = {
+       OUTPUT_DAC2,
+       NULL,
+       NULL,
+       radeon_ms_dac2_initialize,
+       radeon_ms_dac2_detect,
+       radeon_ms_dac2_dpms,
+       radeon_ms_dac2_get_modes,
+       radeon_ms_dac2_mode_fixup,
+       radeon_ms_dac2_mode_set,
+       radeon_ms_dac2_restore,
+       radeon_ms_dac2_save
+};
+
+static struct radeon_ms_connector radeon_ms_vga = {
+       NULL, NULL, NULL, CONNECTOR_VGA, MT_NONE, 0, GPIO_DDC1,
+       {
+               0, -1, -1, -1, -1, -1, -1, -1
+       },
+       "VGA"
+};
+
+static struct radeon_ms_connector radeon_ms_dvi_i_2 = {
+       NULL, NULL, NULL, CONNECTOR_DVI_I, MT_NONE, 0, GPIO_DDC2,
+       {
+               1, -1, -1, -1, -1, -1, -1, -1
+       },
+       "DVI-I"
+};
+
+static struct radeon_ms_properties properties[] = {
+       /* default only one VGA connector */
+       {
+               0, 0, 2700, 2500, 20000, 1, 1, 1, 1,
+               {
+                       &radeon_ms_dac1, NULL, NULL, NULL, NULL, NULL, NULL,
+                       NULL
+               },
+               {
+                       &radeon_ms_vga, NULL, NULL, NULL, NULL, NULL, NULL,
+                       NULL
+               }
+       },
+       {
+               0x1043, 0x176, 2700, 2500, 20000, 1, 1, 1, 1,
+               {
+                       &radeon_ms_dac1, &radeon_ms_dac2, NULL, NULL, NULL,
+                       NULL, NULL, NULL
+               },
+               {
+                       &radeon_ms_vga, &radeon_ms_dvi_i_2, NULL, NULL, NULL,
+                       NULL, NULL, NULL
+               }
+       },
+       {
+               0x1002, 0x4150, 2700, 2500, 20000, 1, 1, 1, 1,
+               {
+                       &radeon_ms_dac1, &radeon_ms_dac2, NULL, NULL, NULL,
+                       NULL, NULL, NULL
+               },
+               {
+                       &radeon_ms_vga, &radeon_ms_dvi_i_2, NULL, NULL, NULL,
+                       NULL, NULL, NULL
+               }
+       },
+};
+
+extern const uint32_t radeon_cp_microcode[];
+extern const uint32_t r200_cp_microcode[];
+extern const uint32_t r300_cp_microcode[];
+
+static void radeon_flush_cache(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       uint32_t cmd[6];
+       int i, ret;
+
+       cmd[0] = CP_PACKET0(RB2D_DSTCACHE_CTLSTAT, 0);
+       cmd[1] = REG_S(RB2D_DSTCACHE_CTLSTAT, DC_FLUSH, 3);
+       cmd[2] = CP_PACKET0(RB3D_DSTCACHE_CTLSTAT, 0);
+       cmd[3] = REG_S(RB3D_DSTCACHE_CTLSTAT, DC_FLUSH, 3);
+       cmd[4] = CP_PACKET0(RB3D_ZCACHE_CTLSTAT, 0);
+       cmd[5] = RB3D_ZCACHE_CTLSTAT__ZC_FLUSH;
+       /* try to wait but if we timeout we likely are in bad situation */
+       for (i = 0; i < dev_priv->usec_timeout; i++) {
+               ret = radeon_ms_ring_emit(dev, cmd, 6);
+               if (!ret) {
+                       break;
+               }
+       }
+}
+
+static void r300_flush_cache(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       uint32_t cmd[6];
+       int i, ret;
+
+       cmd[0] = CP_PACKET0(RB2D_DSTCACHE_CTLSTAT, 0);
+       cmd[1] = REG_S(RB2D_DSTCACHE_CTLSTAT, DC_FLUSH, 3);
+       cmd[2] = CP_PACKET0(RB3D_DSTCACHE_CTLSTAT_R3, 0);
+       cmd[3] = REG_S(RB3D_DSTCACHE_CTLSTAT_R3, DC_FLUSH, 3);
+       cmd[4] = CP_PACKET0(RB3D_ZCACHE_CTLSTAT_R3, 0);
+       cmd[5] = RB3D_ZCACHE_CTLSTAT_R3__ZC_FLUSH;
+       /* try to wait but if we timeout we likely are in bad situation */
+       for (i = 0; i < dev_priv->usec_timeout; i++) {
+               ret = radeon_ms_ring_emit(dev, cmd, 6);
+               if (!ret) {
+                       break;
+               }
+       }
+}
+
+int radeon_ms_family_init(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       int i;
+
+       dev_priv->microcode = radeon_cp_microcode;
+       dev_priv->irq_emit = radeon_ms_irq_emit;
+
+       switch (dev_priv->family) {
+       case CHIP_R100:
+       case CHIP_R200:
+               dev_priv->microcode = radeon_cp_microcode;
+               dev_priv->flush_cache = radeon_flush_cache;
+               break;
+       case CHIP_RV200:
+       case CHIP_RV250:
+       case CHIP_RV280:
+       case CHIP_RS300:
+               dev_priv->microcode = r200_cp_microcode;
+               dev_priv->flush_cache = radeon_flush_cache;
+               break;
+       case CHIP_R300:
+       case CHIP_R350:
+       case CHIP_R360:
+       case CHIP_RV350:
+       case CHIP_RV370:
+       case CHIP_RV380:
+       case CHIP_RS400:
+       case CHIP_RV410:
+       case CHIP_R420:
+       case CHIP_R430:
+       case CHIP_R480:
+               dev_priv->microcode = r300_cp_microcode;
+               dev_priv->flush_cache = r300_flush_cache;
+               break;
+       default:
+               DRM_ERROR("Unknown radeon family, aborting\n");
+               return -EINVAL;
+       }
+       switch (dev_priv->bus_type) {
+       case RADEON_AGP:
+               dev_priv->create_ttm = drm_agp_init_ttm;
+               dev_priv->bus_init = radeon_ms_agp_init;
+               dev_priv->bus_restore = radeon_ms_agp_restore;
+               dev_priv->bus_save = radeon_ms_agp_save;
+               break;
+       case RADEON_PCIE:
+               dev_priv->create_ttm = radeon_ms_pcie_create_ttm;
+               dev_priv->bus_finish = radeon_ms_pcie_finish;
+               dev_priv->bus_init = radeon_ms_pcie_init;
+               dev_priv->bus_restore = radeon_ms_pcie_restore;
+               dev_priv->bus_save = radeon_ms_pcie_save;
+               break;
+       default:
+               DRM_ERROR("Unknown radeon bus type, aborting\n");
+               return -EINVAL;
+       }
+       dev_priv->properties = NULL;
+       for (i = 1; i < sizeof(properties)/sizeof(properties[0]); i++) {
+               if (dev->pdev->subsystem_vendor == properties[i].subvendor &&
+                   dev->pdev->subsystem_device == properties[i].subdevice) {
+                   DRM_INFO("[radeon_ms] found properties for 0x%04X:0x%04X\n",
+                            properties[i].subvendor, properties[i].subdevice);
+                   dev_priv->properties = &properties[i];
+               }
+       }
+       if (dev_priv->properties == NULL) {
+               dev_priv->properties = &properties[0];
+       }
+       return 0;
+}
diff --git a/shared-core/radeon_ms_fence.c b/shared-core/radeon_ms_fence.c
new file mode 100644 (file)
index 0000000..96bb085
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2007 Dave Airlie.
+ * Copyright 2007 Jérôme Glisse
+ * 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
+ * PRECISION INSIGHT 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.
+ *
+ * Authors:
+ *    Dave Airlie
+ *    Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "radeon_ms.h"
+
+static void radeon_ms_fence_flush(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct drm_fence_class_manager *fc = &dev->fm.fence_class[0];
+       uint32_t pending_flush_types = 0;
+       uint32_t sequence;
+
+       if (dev_priv == NULL) {
+               return;
+       }
+       pending_flush_types = fc->pending_flush |
+                             ((fc->pending_exe_flush) ?
+                               DRM_FENCE_TYPE_EXE : 0);
+       if (pending_flush_types) {
+               sequence = mmio_read(dev_priv, dev_priv->fence_reg);
+               drm_fence_handler(dev, 0, sequence, pending_flush_types, 0);
+       }
+}
+
+int radeon_ms_fence_emit_sequence(struct drm_device *dev, uint32_t class,
+                                 uint32_t flags, uint32_t *sequence,
+                                 uint32_t *native_type)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       uint32_t fence_id, cmd[2], i, ret;
+
+       if (!dev_priv || !dev_priv->cp_ready) {
+               return -EINVAL;
+       }
+       fence_id = (++dev_priv->fence_id_last);
+       if (dev_priv->fence_id_last > 0x7FFFFFFF) {
+               fence_id = dev_priv->fence_id_last = 1;
+       }
+       *sequence = fence_id;
+       *native_type = DRM_FENCE_TYPE_EXE;
+       if (flags & DRM_RADEON_FENCE_FLAG_FLUSHED) {
+               *native_type |= DRM_RADEON_FENCE_TYPE_RW;
+               dev_priv->flush_cache(dev);
+       }
+       cmd[0] = CP_PACKET0(dev_priv->fence_reg, 0);
+       cmd[1] = fence_id;
+       for (i = 0; i < dev_priv->usec_timeout; i++) {
+               ret = radeon_ms_ring_emit(dev, cmd, 2);
+               if (!ret) {
+                       dev_priv->irq_emit(dev);
+                       return 0;
+               }
+       }
+       return -EBUSY;
+}
+
+void radeon_ms_fence_handler(struct drm_device * dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct drm_fence_manager *fm = &dev->fm;
+
+       if (dev_priv == NULL) {
+               return;
+       }
+
+       write_lock(&fm->lock);
+       radeon_ms_fence_flush(dev);
+       write_unlock(&fm->lock);
+}
+
+int radeon_ms_fence_has_irq(struct drm_device *dev, uint32_t class,
+                           uint32_t flags)
+{
+       /*
+        * We have an irq that tells us when we have a new breadcrumb.
+        */
+       if (class == 0 && flags == DRM_FENCE_TYPE_EXE)
+               return 1;
+
+       return 0;
+}
+
+int radeon_ms_fence_types(struct drm_buffer_object *bo,
+                         uint32_t *class, uint32_t *type)
+{
+       *class = 0;
+       if (bo->mem.flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE))
+               *type = 3;
+       else
+               *type = 1;
+       return 0;
+}
+
+void radeon_ms_poke_flush(struct drm_device *dev, uint32_t class)
+{
+       struct drm_fence_manager *fm = &dev->fm;
+       unsigned long flags;
+
+       if (class != 0)
+               return;
+       write_lock_irqsave(&fm->lock, flags);
+       radeon_ms_fence_flush(dev);
+       write_unlock_irqrestore(&fm->lock, flags);
+}
diff --git a/shared-core/radeon_ms_gpu.c b/shared-core/radeon_ms_gpu.c
new file mode 100644 (file)
index 0000000..2868378
--- /dev/null
@@ -0,0 +1,589 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Alex Deucher
+ * Copyright 2007 Dave Airlie
+ * 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 on 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
+ * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR 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 "radeon_ms.h"
+
+static int radeon_ms_gpu_address_space_init(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+
+       /* initialize gpu mapping */
+       dev_priv->gpu_vram_start = dev_priv->vram.offset;
+       dev_priv->gpu_vram_end = dev_priv->gpu_vram_start + dev_priv->vram.size;
+       /* align it on 16Mo boundary (clamp memory which is then
+        * unreachable but not manufacturer should use strange
+        * memory size */
+       dev_priv->gpu_vram_end = dev_priv->gpu_vram_end & (~0xFFFFFF);
+       dev_priv->gpu_vram_end -= 1;
+       dev_priv->gpu_vram_size = dev_priv->gpu_vram_end -
+                                 dev_priv->gpu_vram_start + 1;
+       /* set gart size to 32Mo FIXME: should make a parameter for this */
+       dev_priv->gpu_gart_size = 1024 * 1024 * 32;
+       if (dev_priv->gpu_gart_size > (0xffffffffU - dev_priv->gpu_vram_end)) {
+               /* align gart start to next 4Ko in gpu address space */
+               dev_priv->gpu_gart_start = (dev_priv->gpu_vram_end + 1) + 0xfff;
+               dev_priv->gpu_gart_start = dev_priv->gpu_gart_start & (~0xfff);
+               dev_priv->gpu_gart_end = dev_priv->gpu_gart_start +
+                                        dev_priv->gpu_gart_size;
+               dev_priv->gpu_gart_end = (dev_priv->gpu_gart_end & (~0xfff)) -
+                                        0x1000;
+       } else {
+               /* align gart start to next 4Ko in gpu address space */
+               dev_priv->gpu_gart_start = (dev_priv->gpu_vram_start & ~0xfff) -
+                                          dev_priv->gpu_gart_size;
+               dev_priv->gpu_gart_start = dev_priv->gpu_gart_start & (~0xfff);
+               dev_priv->gpu_gart_end = dev_priv->gpu_gart_start +
+                                        dev_priv->gpu_gart_size;
+               dev_priv->gpu_gart_end = (dev_priv->gpu_gart_end & (~0xfff)) -
+                                        0x1000;
+       }
+       state->mc_fb_location =
+               REG_S(MC_FB_LOCATION, MC_FB_START,
+                               dev_priv->gpu_vram_start >> 16) |
+               REG_S(MC_FB_LOCATION, MC_FB_TOP, dev_priv->gpu_vram_end >> 16);
+       state->display_base_addr =
+               REG_S(DISPLAY_BASE_ADDR, DISPLAY_BASE_ADDR,
+                               dev_priv->gpu_vram_start);
+       state->config_aper_0_base = dev_priv->gpu_vram_start;
+       state->config_aper_1_base = dev_priv->gpu_vram_start;
+       state->config_aper_size = dev_priv->gpu_vram_size;
+       DRM_INFO("[radeon_ms] gpu vram start 0x%08X\n",
+                dev_priv->gpu_vram_start);
+       DRM_INFO("[radeon_ms] gpu vram end   0x%08X\n",
+                dev_priv->gpu_vram_end);
+       DRM_INFO("[radeon_ms] gpu gart start 0x%08X\n",
+                dev_priv->gpu_gart_start);
+       DRM_INFO("[radeon_ms] gpu gart end   0x%08X\n",
+                dev_priv->gpu_gart_end);
+       return 0;
+}
+
+static void radeon_ms_gpu_reset(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       uint32_t clock_cntl_index, mclk_cntl, rbbm_soft_reset;
+       uint32_t reset_mask, host_path_cntl, cache_mode;
+
+       radeon_ms_cp_stop(dev);
+       radeon_ms_gpu_flush(dev);
+
+       /* reset clock */
+       clock_cntl_index = MMIO_R(CLOCK_CNTL_INDEX);
+       pll_index_errata(dev_priv);
+       mclk_cntl = PPLL_R(MCLK_CNTL);
+       PPLL_W(MCLK_CNTL,
+                       mclk_cntl |
+                       MCLK_CNTL__FORCE_MCLKA |
+                       MCLK_CNTL__FORCE_MCLKB |
+                       MCLK_CNTL__FORCE_YCLKA |
+                       MCLK_CNTL__FORCE_YCLKB |
+                       MCLK_CNTL__FORCE_MC |
+                       MCLK_CNTL__FORCE_AIC);
+       PPLL_W(SCLK_CNTL,
+                       PPLL_R(SCLK_CNTL) |
+                       SCLK_CNTL__FORCE_CP |
+                       SCLK_CNTL__FORCE_VIP);
+
+       /* Soft resetting HDP thru RBBM_SOFT_RESET register can cause some
+        * unexpected behaviour on some machines.  Here we use
+        * RADEON_HOST_PATH_CNTL to reset it.
+        */
+       host_path_cntl = MMIO_R(HOST_PATH_CNTL);
+       rbbm_soft_reset = MMIO_R(RBBM_SOFT_RESET);
+       reset_mask = RBBM_SOFT_RESET__SOFT_RESET_CP |
+               RBBM_SOFT_RESET__SOFT_RESET_HI |
+               RBBM_SOFT_RESET__SOFT_RESET_VAP |
+               RBBM_SOFT_RESET__SOFT_RESET_SE |
+               RBBM_SOFT_RESET__SOFT_RESET_RE |
+               RBBM_SOFT_RESET__SOFT_RESET_PP |
+               RBBM_SOFT_RESET__SOFT_RESET_E2 |
+               RBBM_SOFT_RESET__SOFT_RESET_RB;
+       MMIO_W(RBBM_SOFT_RESET, rbbm_soft_reset | reset_mask);
+       MMIO_R(RBBM_SOFT_RESET);
+       MMIO_W(RBBM_SOFT_RESET, 0);
+       MMIO_R(RBBM_SOFT_RESET);
+
+       cache_mode = MMIO_R(RB2D_DSTCACHE_MODE);
+       MMIO_W(RB2D_DSTCACHE_MODE,
+                       cache_mode | RB2D_DSTCACHE_MODE__DC_DISABLE_IGNORE_PE);
+
+       MMIO_W(HOST_PATH_CNTL, host_path_cntl | HOST_PATH_CNTL__HDP_SOFT_RESET);
+       MMIO_R(HOST_PATH_CNTL);
+       MMIO_W(HOST_PATH_CNTL, host_path_cntl);
+       MMIO_R(HOST_PATH_CNTL);
+
+       MMIO_W(CLOCK_CNTL_INDEX, clock_cntl_index);
+       pll_index_errata(dev_priv);
+       PPLL_W(MCLK_CNTL, mclk_cntl);
+}
+
+static void radeon_ms_gpu_resume(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       uint32_t a;
+       uint32_t i;
+
+       /* make sure we have sane offset before restoring crtc */
+       a = (MMIO_R(MC_FB_LOCATION) & MC_FB_LOCATION__MC_FB_START__MASK) << 16;
+       MMIO_W(DISPLAY_BASE_ADDR, a);
+       MMIO_W(CRTC2_DISPLAY_BASE_ADDR, a);
+       MMIO_W(CRTC_OFFSET, 0);
+       MMIO_W(CUR_OFFSET, 0);
+       MMIO_W(CRTC_OFFSET_CNTL, CRTC_OFFSET_CNTL__CRTC_OFFSET_FLIP_CNTL);
+       MMIO_W(CRTC2_OFFSET, 0);
+       MMIO_W(CUR2_OFFSET, 0);
+       MMIO_W(CRTC2_OFFSET_CNTL, CRTC2_OFFSET_CNTL__CRTC2_OFFSET_FLIP_CNTL);
+       for (i = 0; i < dev_priv->usec_timeout; i++) {
+               if (!(CRTC_OFFSET__CRTC_GUI_TRIG_OFFSET &
+                     MMIO_R(CRTC_OFFSET))) {
+                       break;
+               }
+               DRM_UDELAY(1);
+       }
+       if (i >= dev_priv->usec_timeout) {
+               DRM_ERROR("[radeon_ms] timeout waiting for crtc...\n");
+       }
+       for (i = 0; i < dev_priv->usec_timeout; i++) {
+               if (!(CRTC2_OFFSET__CRTC2_GUI_TRIG_OFFSET &
+                     MMIO_R(CRTC2_OFFSET))) {
+                       break;
+               }
+               DRM_UDELAY(1);
+       }
+       if (i >= dev_priv->usec_timeout) {
+               DRM_ERROR("[radeon_ms] timeout waiting for crtc...\n");
+       }
+       DRM_UDELAY(10000);
+}
+
+static void radeon_ms_gpu_stop(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       uint32_t ov0_scale_cntl, crtc_ext_cntl, crtc_gen_cntl;
+       uint32_t crtc2_gen_cntl, i;
+
+       radeon_ms_wait_for_idle(dev);
+       /* Capture MC_STATUS in case things go wrong ... */
+       ov0_scale_cntl = dev_priv->ov0_scale_cntl = MMIO_R(OV0_SCALE_CNTL);
+       crtc_ext_cntl = dev_priv->crtc_ext_cntl = MMIO_R(CRTC_EXT_CNTL);
+       crtc_gen_cntl = dev_priv->crtc_gen_cntl = MMIO_R(CRTC_GEN_CNTL);
+       crtc2_gen_cntl = dev_priv->crtc2_gen_cntl = MMIO_R(CRTC2_GEN_CNTL);
+       ov0_scale_cntl &= ~OV0_SCALE_CNTL__OV0_OVERLAY_EN__MASK;
+       crtc_ext_cntl |= CRTC_EXT_CNTL__CRTC_DISPLAY_DIS;
+       crtc_gen_cntl &= ~CRTC_GEN_CNTL__CRTC_CUR_EN;
+       crtc_gen_cntl &= ~CRTC_GEN_CNTL__CRTC_ICON_EN;
+       crtc_gen_cntl |= CRTC_GEN_CNTL__CRTC_EXT_DISP_EN;
+       crtc_gen_cntl |= CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B;
+       crtc2_gen_cntl &= ~CRTC2_GEN_CNTL__CRTC2_CUR_EN;
+       crtc2_gen_cntl &= ~CRTC2_GEN_CNTL__CRTC2_ICON_EN;
+       crtc2_gen_cntl |= CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B;
+       MMIO_W(OV0_SCALE_CNTL, ov0_scale_cntl);
+       MMIO_W(CRTC_EXT_CNTL, crtc_ext_cntl);
+       MMIO_W(CRTC_GEN_CNTL, crtc_gen_cntl);
+       MMIO_W(CRTC2_GEN_CNTL, crtc2_gen_cntl);
+       DRM_UDELAY(10000);
+       switch (dev_priv->family) {
+       case CHIP_R100:
+       case CHIP_R200:
+       case CHIP_RV200:
+       case CHIP_RV250:
+       case CHIP_RV280:
+       case CHIP_RS300:
+               for (i = 0; i < dev_priv->usec_timeout; i++) {
+                       if ((MC_STATUS__MC_IDLE & MMIO_R(MC_STATUS))) {
+                               DRM_INFO("[radeon_ms] gpu stoped in %d usecs\n",
+                                        i);
+                               return;
+                       }
+                       DRM_UDELAY(1);
+               }
+               break;
+       case CHIP_R300:
+       case CHIP_R350:
+       case CHIP_R360:
+       case CHIP_RV350:
+       case CHIP_RV370:
+       case CHIP_RV380:
+       case CHIP_RS400:
+       case CHIP_RV410:
+       case CHIP_R420:
+       case CHIP_R430:
+       case CHIP_R480:
+               for (i = 0; i < dev_priv->usec_timeout; i++) {
+                       if ((MC_STATUS__MC_IDLE_R3 & MMIO_R(MC_STATUS))) {
+                               DRM_INFO("[radeon_ms] gpu stoped in %d usecs\n",
+                                        i);
+                               return;
+                       }
+                       DRM_UDELAY(1);
+               }
+               break;
+       default:
+               DRM_ERROR("Unknown radeon family, aborting\n");
+               return;
+       }
+       DRM_ERROR("[radeon_ms] failed to stop gpu...will proceed anyway\n");
+       DRM_UDELAY(20000);
+}
+
+static int radeon_ms_wait_for_fifo(struct drm_device *dev, int num_fifo)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       int i;
+
+       for (i = 0; i < dev_priv->usec_timeout; i++) {
+               int t;
+               t = RBBM_STATUS__CMDFIFO_AVAIL__MASK & MMIO_R(RBBM_STATUS);
+               t = t >> RBBM_STATUS__CMDFIFO_AVAIL__SHIFT;
+               if (t >= num_fifo)
+                       return 0;
+               DRM_UDELAY(1);
+       }
+       DRM_ERROR("[radeon_ms] failed to wait for fifo\n");
+       return -EBUSY;
+}
+
+int radeon_ms_gpu_initialize(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+       int ret;
+
+       state->disp_misc_cntl = DISP_MISC_CNTL__SYNC_PAD_FLOP_EN |
+               REG_S(DISP_MISC_CNTL, SYNC_STRENGTH, 2) |
+               REG_S(DISP_MISC_CNTL, PALETTE_MEM_RD_MARGIN, 0xb) |
+               REG_S(DISP_MISC_CNTL, PALETTE2_MEM_RD_MARGIN, 0xb) |
+               REG_S(DISP_MISC_CNTL, RMX_BUF_MEM_RD_MARGIN, 0x5);
+       state->disp_merge_cntl = REG_S(DISP_MERGE_CNTL, DISP_GRPH_ALPHA, 0xff) |
+               REG_S(DISP_MERGE_CNTL, DISP_OV0_ALPHA, 0xff);
+       state->disp_pwr_man = DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN |
+               DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN |
+               REG_S(DISP_PWR_MAN, DISP_PWR_MAN_DPMS, DISP_PWR_MAN_DPMS__OFF) |
+               DISP_PWR_MAN__DISP_D3_RST |
+               DISP_PWR_MAN__DISP_D3_REG_RST |
+               DISP_PWR_MAN__DISP_D3_GRPH_RST |
+               DISP_PWR_MAN__DISP_D3_SUBPIC_RST |
+               DISP_PWR_MAN__DISP_D3_OV0_RST |
+               DISP_PWR_MAN__DISP_D1D2_GRPH_RST |
+               DISP_PWR_MAN__DISP_D1D2_SUBPIC_RST |
+               DISP_PWR_MAN__DISP_D1D2_OV0_RST |
+               DISP_PWR_MAN__DISP_DVO_ENABLE_RST |
+               DISP_PWR_MAN__TV_ENABLE_RST;
+       state->disp2_merge_cntl = 0;
+       ret = radeon_ms_gpu_address_space_init(dev);
+       if (ret) {
+               return ret;
+       }
+
+       /* initialize bus */
+       ret = dev_priv->bus_init(dev);
+       if (ret != 0) {
+               return ret;
+       }
+       return 0;
+}
+
+void radeon_ms_gpu_dpms(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+
+       if (dev_priv->crtc1_dpms == dev_priv->crtc2_dpms) {
+               /* both crtc are in same state so use global display pwr */
+               state->disp_pwr_man &= ~DISP_PWR_MAN__DISP_PWR_MAN_DPMS__MASK;
+               switch(dev_priv->crtc1_dpms) {
+               case DPMSModeOn:
+                       state->disp_pwr_man |= REG_S(DISP_PWR_MAN,
+                                       DISP_PWR_MAN_DPMS,
+                                       DISP_PWR_MAN_DPMS__ON);
+                       break;
+               case DPMSModeStandby:
+                       state->disp_pwr_man |= REG_S(DISP_PWR_MAN,
+                                       DISP_PWR_MAN_DPMS,
+                                       DISP_PWR_MAN_DPMS__STANDBY);
+                       break;
+               case DPMSModeSuspend:
+                       state->disp_pwr_man |= REG_S(DISP_PWR_MAN,
+                                       DISP_PWR_MAN_DPMS,
+                                       DISP_PWR_MAN_DPMS__SUSPEND);
+                       break;
+               case DPMSModeOff:
+                       state->disp_pwr_man |= REG_S(DISP_PWR_MAN,
+                                       DISP_PWR_MAN_DPMS,
+                                       DISP_PWR_MAN_DPMS__OFF);
+                       break;
+               default:
+                       /* error */
+                       break;
+               }
+               MMIO_W(DISP_PWR_MAN, state->disp_pwr_man);
+       } else {
+               state->disp_pwr_man &= ~DISP_PWR_MAN__DISP_PWR_MAN_DPMS__MASK;
+               state->disp_pwr_man |= REG_S(DISP_PWR_MAN,
+                               DISP_PWR_MAN_DPMS,
+                               DISP_PWR_MAN_DPMS__ON);
+               MMIO_W(DISP_PWR_MAN, state->disp_pwr_man);
+       }
+}
+
+void radeon_ms_gpu_flush(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       uint32_t i;
+       uint32_t purge2d;
+       uint32_t purge3d;
+
+       switch (dev_priv->family) {
+       case CHIP_R100:
+       case CHIP_R200:
+       case CHIP_RV200:
+       case CHIP_RV250:
+       case CHIP_RV280:
+       case CHIP_RS300:
+               purge2d = REG_S(RB2D_DSTCACHE_CTLSTAT, DC_FLUSH, 3) |
+                       REG_S(RB2D_DSTCACHE_CTLSTAT, DC_FREE, 3);
+               purge3d = REG_S(RB3D_DSTCACHE_CTLSTAT, DC_FLUSH, 3) |
+                       REG_S(RB3D_DSTCACHE_CTLSTAT, DC_FREE, 3);
+               MMIO_W(RB2D_DSTCACHE_CTLSTAT, purge2d);
+               MMIO_W(RB3D_DSTCACHE_CTLSTAT, purge3d);
+               break;
+       case CHIP_R300:
+       case CHIP_R350:
+       case CHIP_R360:
+       case CHIP_RV350:
+       case CHIP_RV370:
+       case CHIP_RV380:
+       case CHIP_RS400:
+       case CHIP_RV410:
+       case CHIP_R420:
+       case CHIP_R430:
+       case CHIP_R480:
+               purge2d = REG_S(RB2D_DSTCACHE_CTLSTAT, DC_FLUSH, 3) |
+                       REG_S(RB2D_DSTCACHE_CTLSTAT, DC_FREE, 3);
+               purge3d = REG_S(RB3D_DSTCACHE_CTLSTAT_R3, DC_FLUSH, 3) |
+                       REG_S(RB3D_DSTCACHE_CTLSTAT_R3, DC_FREE, 3);
+               MMIO_W(RB2D_DSTCACHE_CTLSTAT, purge2d);
+               MMIO_W(RB3D_DSTCACHE_CTLSTAT_R3, purge3d);
+               break;
+       default:
+               DRM_ERROR("Unknown radeon family, aborting\n");
+               return;
+       }
+       for (i = 0; i < dev_priv->usec_timeout; i++) {
+               if (!(RB2D_DSTCACHE_CTLSTAT__DC_BUSY &
+                                       MMIO_R(RB2D_DSTCACHE_CTLSTAT))) {
+                       return;
+               }
+               DRM_UDELAY(1);
+       }
+       DRM_ERROR("[radeon_ms] gpu flush timeout\n");
+}
+
+void radeon_ms_gpu_restore(struct drm_device *dev, struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       uint32_t wait_until;
+       uint32_t fbstart;
+       int ret, ok = 1;
+
+       radeon_ms_gpu_reset(dev);
+       radeon_ms_wait_for_idle(dev);
+       radeon_ms_gpu_stop(dev);
+
+       MMIO_W(AIC_CTRL, state->aic_ctrl);
+       MMIO_W(MC_FB_LOCATION, state->mc_fb_location);
+       MMIO_R(MC_FB_LOCATION);
+       MMIO_W(CONFIG_APER_0_BASE, state->config_aper_0_base);
+       MMIO_W(CONFIG_APER_1_BASE, state->config_aper_1_base);
+       MMIO_W(CONFIG_APER_SIZE, state->config_aper_size);
+       MMIO_W(DISPLAY_BASE_ADDR, state->display_base_addr);
+       if (dev_priv->bus_restore) {
+               dev_priv->bus_restore(dev, state);
+       }
+
+       radeon_ms_gpu_reset(dev);
+       radeon_ms_gpu_resume(dev);
+
+       MMIO_W(BUS_CNTL, state->bus_cntl);
+       wait_until = WAIT_UNTIL__WAIT_DMA_VIPH0_IDLE |
+               WAIT_UNTIL__WAIT_DMA_VIPH1_IDLE |
+               WAIT_UNTIL__WAIT_DMA_VIPH2_IDLE |
+               WAIT_UNTIL__WAIT_DMA_VIPH3_IDLE |
+               WAIT_UNTIL__WAIT_DMA_VID_IDLE |
+               WAIT_UNTIL__WAIT_DMA_GUI_IDLE |
+               WAIT_UNTIL__WAIT_2D_IDLE |
+               WAIT_UNTIL__WAIT_3D_IDLE |
+               WAIT_UNTIL__WAIT_2D_IDLECLEAN |
+               WAIT_UNTIL__WAIT_3D_IDLECLEAN |
+               WAIT_UNTIL__WAIT_HOST_IDLECLEAN;
+       switch (dev_priv->family) {
+       case CHIP_R100:
+       case CHIP_R200:
+       case CHIP_RV200:
+       case CHIP_RV250:
+       case CHIP_RV280:
+       case CHIP_RS300:
+               break;
+       case CHIP_R300:
+       case CHIP_R350:
+       case CHIP_R360:
+       case CHIP_RV350:
+       case CHIP_RV370:
+       case CHIP_RV380:
+       case CHIP_RS400:
+       case CHIP_RV410:
+       case CHIP_R420:
+       case CHIP_R430:
+       case CHIP_R480:
+               wait_until |= WAIT_UNTIL__WAIT_VAP_IDLE;
+               break;
+       }
+       MMIO_W(WAIT_UNTIL, wait_until); 
+       MMIO_W(DISP_MISC_CNTL, state->disp_misc_cntl);
+       MMIO_W(DISP_PWR_MAN, state->disp_pwr_man);
+       MMIO_W(DISP_MERGE_CNTL, state->disp_merge_cntl);
+       MMIO_W(DISP_OUTPUT_CNTL, state->disp_output_cntl);
+       MMIO_W(DISP2_MERGE_CNTL, state->disp2_merge_cntl);
+
+       /* Setup engine location. This shouldn't be necessary since we
+        * set them appropriately before any accel ops, but let's avoid
+        * random bogus DMA in case we inadvertently trigger the engine
+        * in the wrong place (happened).
+        */
+       ret = radeon_ms_wait_for_fifo(dev, 2);
+       if (ret) {
+               ok = 0;
+               DRM_ERROR("[radeon_ms] no fifo for setting up dst & src gui\n");
+               DRM_ERROR("[radeon_ms] proceed anyway\n");
+       }
+       fbstart = (MC_FB_LOCATION__MC_FB_START__MASK &
+                       MMIO_R(MC_FB_LOCATION)) << 16;
+       MMIO_W(DST_PITCH_OFFSET,
+               REG_S(DST_PITCH_OFFSET, DST_OFFSET, fbstart >> 10));
+       MMIO_W(SRC_PITCH_OFFSET,
+               REG_S(SRC_PITCH_OFFSET, SRC_OFFSET, fbstart >> 10));
+
+       ret = radeon_ms_wait_for_fifo(dev, 1);
+       if (ret) {
+               ok = 0;
+               DRM_ERROR("[radeon_ms] no fifo for setting up dp data type\n");
+               DRM_ERROR("[radeon_ms] proceed anyway\n");
+       }
+#ifdef __BIG_ENDIAN
+       MMIO_W(DP_DATATYPE, DP_DATATYPE__DP_BYTE_PIX_ORDER);
+#else
+       MMIO_W(DP_DATATYPE, 0);
+#endif
+
+       ret = radeon_ms_wait_for_fifo(dev, 1);
+       if (ret) {
+               ok = 0;
+               DRM_ERROR("[radeon_ms] no fifo for setting up surface cntl\n");
+               DRM_ERROR("[radeon_ms] proceed anyway\n");
+       }
+       MMIO_W(SURFACE_CNTL, SURFACE_CNTL__SURF_TRANSLATION_DIS);
+
+       ret = radeon_ms_wait_for_fifo(dev, 2);
+       if (ret) {
+               ok = 0;
+               DRM_ERROR("[radeon_ms] no fifo for setting scissor\n");
+               DRM_ERROR("[radeon_ms] proceed anyway\n");
+       }
+       MMIO_W(DEFAULT_SC_BOTTOM_RIGHT, 0x1fff1fff);
+       MMIO_W(DEFAULT2_SC_BOTTOM_RIGHT, 0x1fff1fff);
+
+       ret = radeon_ms_wait_for_fifo(dev, 1);
+       if (ret) {
+               ok = 0;
+               DRM_ERROR("[radeon_ms] no fifo for setting up gui cntl\n");
+               DRM_ERROR("[radeon_ms] proceed anyway\n");
+       }
+       MMIO_W(DP_GUI_MASTER_CNTL, 0);
+
+       ret = radeon_ms_wait_for_fifo(dev, 5);
+       if (ret) {
+               ok = 0;
+               DRM_ERROR("[radeon_ms] no fifo for setting up clear color\n");
+               DRM_ERROR("[radeon_ms] proceed anyway\n");
+       }
+       MMIO_W(DP_BRUSH_BKGD_CLR, 0x00000000);
+       MMIO_W(DP_BRUSH_FRGD_CLR, 0xffffffff);
+       MMIO_W(DP_SRC_BKGD_CLR, 0x00000000);
+       MMIO_W(DP_SRC_FRGD_CLR, 0xffffffff);
+       MMIO_W(DP_WRITE_MSK, 0xffffffff);
+
+       if (!ok) {
+               DRM_ERROR("[radeon_ms] engine restore not enough fifo\n");
+       }
+}
+
+void radeon_ms_gpu_save(struct drm_device *dev, struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       state->aic_ctrl = MMIO_R(AIC_CTRL);
+       state->bus_cntl = MMIO_R(BUS_CNTL);
+       state->mc_fb_location = MMIO_R(MC_FB_LOCATION);
+       state->display_base_addr = MMIO_R(DISPLAY_BASE_ADDR);
+       state->config_aper_0_base = MMIO_R(CONFIG_APER_0_BASE);
+       state->config_aper_1_base = MMIO_R(CONFIG_APER_1_BASE);
+       state->config_aper_size = MMIO_R(CONFIG_APER_SIZE);
+       state->disp_misc_cntl = MMIO_R(DISP_MISC_CNTL);
+       state->disp_pwr_man = MMIO_R(DISP_PWR_MAN);
+       state->disp_merge_cntl = MMIO_R(DISP_MERGE_CNTL);
+       state->disp_output_cntl = MMIO_R(DISP_OUTPUT_CNTL);
+       state->disp2_merge_cntl = MMIO_R(DISP2_MERGE_CNTL);
+       if (dev_priv->bus_save) {
+               dev_priv->bus_save(dev, state);
+       }
+}
+
+int radeon_ms_wait_for_idle(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       int i, j, ret;
+
+       for (i = 0; i < 2; i++) {
+               ret = radeon_ms_wait_for_fifo(dev, 64);
+               if (ret) {
+                       DRM_ERROR("[radeon_ms] fifo not empty\n");
+               }
+               for (j = 0; j < dev_priv->usec_timeout; j++) {
+                       if (!(RBBM_STATUS__GUI_ACTIVE & MMIO_R(RBBM_STATUS))) {
+                               radeon_ms_gpu_flush(dev);
+                               return 0;
+                       }
+                       DRM_UDELAY(1);
+               }
+               DRM_ERROR("[radeon_ms] idle timed out:  status=0x%08x\n",
+                               MMIO_R(RBBM_STATUS));
+               radeon_ms_gpu_stop(dev);
+               radeon_ms_gpu_reset(dev);
+       }
+       return -EBUSY;
+}
diff --git a/shared-core/radeon_ms_i2c.c b/shared-core/radeon_ms_i2c.c
new file mode 100644 (file)
index 0000000..1801c49
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Alex Deucher
+ * Copyright 2007 Dave Airlie
+ * 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 on 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
+ * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR 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 "radeon_ms.h"
+
+static int get_clock(void *data)
+{
+       struct radeon_ms_i2c *i2c = data;
+       struct drm_radeon_private *dev_priv = i2c->drm_dev->dev_private;
+       int v;
+
+       switch (i2c->reg) {
+       case VIPPAD_EN:
+               v = MMIO_R(VIPPAD_Y);
+               if ((REG_G(VIPPAD_Y, VIPPAD_Y_VHAD, v) & 2)) {
+                       v = 1;
+               } else {
+                       v = 0;
+               }
+               break;
+       case VIPPAD1_EN:
+               v = MMIO_R(VIPPAD1_Y);
+               if ((REG_G(VIPPAD1_Y, VIPPAD_Y_DVODATA, v) & 8)) {
+                       v = 1;
+               } else {
+                       v = 0;
+               }
+               break;
+       case GPIO_DDC1:
+               v = MMIO_R(GPIO_DDC1);
+               if ((GPIO_DDC1__DDC1_CLK_INPUT & v)) {
+                       v = 1;
+               } else {
+                       v = 0;
+               }
+               break;
+       case GPIO_DDC2:
+               v = MMIO_R(GPIO_DDC2);
+               if ((GPIO_DDC2__DDC2_CLK_INPUT & v)) {
+                       v = 1;
+               } else {
+                       v = 0;
+               }
+               break;
+       default:
+               v = 0;
+               break;
+       }
+       return v;
+}
+
+static int get_data(void *data)
+{
+       struct radeon_ms_i2c *i2c = data;
+       struct drm_radeon_private *dev_priv = i2c->drm_dev->dev_private;
+       int v;
+
+       switch (i2c->reg) {
+       case VIPPAD_EN:
+               v = MMIO_R(VIPPAD_Y);
+               if ((REG_G(VIPPAD_Y, VIPPAD_Y_VHAD, v) & 1)) {
+                       v = 1;
+               } else {
+                       v = 0;
+               }
+               break;
+       case VIPPAD1_EN:
+               v = MMIO_R(VIPPAD1_Y);
+               if ((REG_G(VIPPAD1_Y, VIPPAD_Y_DVODATA, v) & 4)) {
+                       v = 1;
+               } else {
+                       v = 0;
+               }
+               break;
+       case GPIO_DDC1:
+               v = MMIO_R(GPIO_DDC1);
+               if ((GPIO_DDC1__DDC1_DATA_INPUT & v)) {
+                       v = 1;
+               } else {
+                       v = 0;
+               }
+               break;
+       case GPIO_DDC2:
+               v = MMIO_R(GPIO_DDC2);
+               if ((GPIO_DDC2__DDC2_DATA_INPUT & v)) {
+                       v = 1;
+               } else {
+                       v = 0;
+               }
+               break;
+       default:
+               v = 0;
+               break;
+       }
+       return v;
+}
+
+static void set_clock(void *i2c_priv, int clock)
+{
+       struct radeon_ms_i2c *i2c = i2c_priv;
+       struct drm_radeon_private *dev_priv = i2c->drm_dev->dev_private;
+       int v, line;
+
+       v = MMIO_R(i2c->reg);
+       switch (i2c->reg) {
+       case VIPPAD_EN:
+               line = REG_G(VIPPAD_EN, VIPPAD_EN_VHAD, v) & ~2;
+               v &= ~VIPPAD_EN__VIPPAD_EN_VHAD__MASK;
+               if (!clock) {
+                       v |= REG_S(VIPPAD_EN, VIPPAD_EN_VHAD, line | 2);
+               } else {
+                       v |= REG_S(VIPPAD_EN, VIPPAD_EN_VHAD, line);
+               }
+               break;
+       case VIPPAD1_EN:
+               line = REG_G(VIPPAD1_EN, VIPPAD_EN_DVODATA, v) & ~8;
+               v &= ~VIPPAD1_EN__VIPPAD_EN_DVODATA__MASK;
+               if (!clock) {
+                       v |= REG_S(VIPPAD1_EN, VIPPAD_EN_DVODATA, line | 8);
+               } else {
+                       v |= REG_S(VIPPAD1_EN, VIPPAD_EN_DVODATA, line);
+               }
+               break;
+       case GPIO_DDC1:
+               v &= ~GPIO_DDC1__DDC1_CLK_OUT_EN;
+               if (!clock) {
+                       v |= GPIO_DDC1__DDC1_CLK_OUT_EN;
+               }
+               break;
+       case GPIO_DDC2:
+               v &= ~GPIO_DDC2__DDC2_CLK_OUT_EN;
+               if (!clock) {
+                       v |= GPIO_DDC2__DDC2_CLK_OUT_EN;
+               }
+               break;
+       default:
+               return;
+       }
+       MMIO_W(i2c->reg, v);
+}
+
+static void set_data(void *i2c_priv, int data)
+{
+       struct radeon_ms_i2c *i2c = i2c_priv;
+       struct drm_radeon_private *dev_priv = i2c->drm_dev->dev_private;
+       int v, line;
+
+       v = MMIO_R(i2c->reg);
+       switch (i2c->reg) {
+       case VIPPAD_EN:
+               line = REG_G(VIPPAD_EN, VIPPAD_EN_VHAD, v) & ~1;
+               v &= ~VIPPAD_EN__VIPPAD_EN_VHAD__MASK;
+               if (!data) {
+                       v |= REG_S(VIPPAD_EN, VIPPAD_EN_VHAD, line | 1);
+               } else {
+                       v |= REG_S(VIPPAD_EN, VIPPAD_EN_VHAD, line);
+               }
+               break;
+       case VIPPAD1_EN:
+               line = REG_G(VIPPAD1_EN, VIPPAD_EN_DVODATA, v) & ~4;
+               v &= ~VIPPAD1_EN__VIPPAD_EN_DVODATA__MASK;
+               if (!data) {
+                       v |= REG_S(VIPPAD1_EN, VIPPAD_EN_DVODATA, line | 4);
+               } else {
+                       v |= REG_S(VIPPAD1_EN, VIPPAD_EN_DVODATA, line);
+               }
+               break;
+       case GPIO_DDC1:
+               v &= ~GPIO_DDC1__DDC1_DATA_OUT_EN;
+               if (!data) {
+                       v |= GPIO_DDC1__DDC1_DATA_OUT_EN;
+               }
+               break;
+       case GPIO_DDC2:
+               v &= ~GPIO_DDC2__DDC2_DATA_OUT_EN;
+               if (!data) {
+                       v |= GPIO_DDC2__DDC2_DATA_OUT_EN;
+               }
+               break;
+       default:
+               return;
+       }
+       MMIO_W(i2c->reg, v);
+}
+
+/**
+ * radeon_ms_i2c_create - instantiate an radeon i2c bus on specified GPIO reg
+ * @dev: DRM device
+ * @output: driver specific output device
+ * @reg: GPIO reg to use
+ * @name: name for this bus
+ *
+ * Creates and registers a new i2c bus with the Linux i2c layer, for use
+ * in output probing and control (e.g. DDC or SDVO control functions).
+ *
+ */
+struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev,
+                                          const uint32_t reg,
+                                          const char *name)
+{
+       struct radeon_ms_i2c *i2c;
+       int ret;
+
+       i2c = drm_alloc(sizeof(struct radeon_ms_i2c), DRM_MEM_DRIVER);
+       if (i2c == NULL) {
+               return NULL;
+       }
+       memset(i2c, 0, sizeof(struct radeon_ms_i2c));
+
+       i2c->drm_dev = dev;
+       i2c->reg = reg;
+       snprintf(i2c->adapter.name, I2C_NAME_SIZE, "radeon-%s", name);
+       i2c->adapter.owner = THIS_MODULE;
+       /* fixme need to take a look at what its needed for */
+       i2c->adapter.id = I2C_HW_B_RADEON;
+       i2c->adapter.algo_data = &i2c->algo;
+       i2c->adapter.dev.parent = &dev->pdev->dev;
+       i2c->algo.setsda = set_data;
+       i2c->algo.setscl = set_clock;
+       i2c->algo.getsda = get_data;
+       i2c->algo.getscl = get_clock;
+       i2c->algo.udelay = 20;
+       i2c->algo.timeout = usecs_to_jiffies(2200);
+       i2c->algo.data = i2c;
+
+       i2c_set_adapdata(&i2c->adapter, i2c);
+
+       ret = i2c_bit_add_bus(&i2c->adapter);
+       if(ret) {
+               DRM_INFO("[radeon_ms] failed to register I2C '%s' bus\n",
+                        i2c->adapter.name);
+               goto out_free;
+       }
+       DRM_INFO("[radeon_ms] registered I2C '%s' bus\n", i2c->adapter.name);
+       return i2c;
+
+out_free:
+       drm_free(i2c, sizeof(struct radeon_ms_i2c), DRM_MEM_DRIVER);
+       return NULL;
+}
+
+/**
+ * radeon_ms_i2c_destroy - unregister and free i2c bus resources
+ * @output: channel to free
+ *
+ * Unregister the adapter from the i2c layer, then free the structure.
+ */
+void radeon_ms_i2c_destroy(struct radeon_ms_i2c *i2c)
+{
+       if (i2c == NULL) {
+               return;
+       }
+       i2c_del_adapter(&i2c->adapter);
+       drm_free(i2c, sizeof(struct radeon_ms_i2c), DRM_MEM_DRIVER);
+}
diff --git a/shared-core/radeon_ms_irq.c b/shared-core/radeon_ms_irq.c
new file mode 100644 (file)
index 0000000..24182c7
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Alex Deucher
+ * Copyright 2007 Dave Airlie
+ * 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
+ * PRECISION INSIGHT 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.
+ *
+ * Authors:
+ *    Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_ms.h"
+
+static uint32_t radeon_ack_irqs(struct drm_radeon_private *dev_priv,
+                               uint32_t mask)
+{
+       uint32_t irqs;
+
+       irqs = MMIO_R(GEN_INT_STATUS);
+       if (irqs) {
+               MMIO_W(GEN_INT_STATUS, irqs);
+       }
+       if (irqs & (~mask)) {
+               /* reprogram irq */
+               MMIO_W(GEN_INT_CNTL, dev_priv->driver_state.gen_int_cntl);
+       }
+       return irqs;
+}
+
+void radeon_ms_irq_emit(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       uint32_t cmd[4];
+       int i, ret;
+
+       cmd[0] = CP_PACKET0(GEN_INT_CNTL, 1);
+       cmd[1] = dev_priv->driver_state.gen_int_cntl | GEN_INT_CNTL__SW_INT_EN;
+       cmd[2] = GEN_INT_STATUS__SW_INT_SET;
+       /* try to wait but if we timeout we likely are in bad situation */
+       for (i = 0; i < dev_priv->usec_timeout; i++) {
+               ret = radeon_ms_ring_emit(dev, cmd, 3);
+               if (!ret) {
+                       break;
+               }
+       }
+}
+
+static void radeon_ms_irq_enable(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+
+       state->gen_int_cntl = GEN_INT_CNTL__SW_INT_EN;
+       radeon_ms_irq_restore(dev, state);
+}
+
+irqreturn_t radeon_ms_irq_handler(DRM_IRQ_ARGS)
+{
+       struct drm_device *dev = (struct drm_device *)arg;
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       uint32_t status, mask;
+
+       /* Only consider the bits we're interested in - others could be used
+        * outside the DRM
+        */
+       mask = GEN_INT_STATUS__SW_INT |
+              GEN_INT_STATUS__CRTC_VBLANK_STAT |
+              GEN_INT_STATUS__CRTC2_VBLANK_STAT;
+       status = radeon_ack_irqs(dev_priv, mask);
+       if (!status) {
+               return IRQ_NONE;
+       }
+
+       /* SW interrupt */
+       if (GEN_INT_STATUS__SW_INT & status) {
+               radeon_ms_fence_handler(dev);
+       }
+       radeon_ms_fence_handler(dev);
+       return IRQ_HANDLED;
+}
+
+void radeon_ms_irq_preinstall(struct drm_device * dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+       uint32_t mask;
+
+       /* Disable *all* interrupts */
+       state->gen_int_cntl = 0;
+       radeon_ms_irq_restore(dev, state);
+
+       /* Clear bits if they're already high */
+       mask = GEN_INT_STATUS__SW_INT |
+              GEN_INT_STATUS__CRTC_VBLANK_STAT |
+              GEN_INT_STATUS__CRTC2_VBLANK_STAT;
+       radeon_ack_irqs(dev_priv, mask);
+}
+
+void radeon_ms_irq_postinstall(struct drm_device * dev)
+{
+       radeon_ms_irq_enable(dev);
+}
+
+int radeon_ms_irq_init(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+
+       /* Disable *all* interrupts */
+       state->gen_int_cntl = 0;
+       radeon_ms_irq_restore(dev, state);
+       return 0;
+}
+
+void radeon_ms_irq_restore(struct drm_device *dev, struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       MMIO_W(GEN_INT_CNTL, state->gen_int_cntl);
+}
+
+void radeon_ms_irq_save(struct drm_device *dev, struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+
+       state->gen_int_cntl = MMIO_R(GEN_INT_CNTL);
+}
+
+void radeon_ms_irq_uninstall(struct drm_device * dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct radeon_state *state = &dev_priv->driver_state;
+
+       if (dev_priv == NULL) {
+               return;
+       }
+
+       /* Disable *all* interrupts */
+       state->gen_int_cntl = 0;
+       radeon_ms_irq_restore(dev, state);
+}
diff --git a/shared-core/radeon_ms_output.c b/shared-core/radeon_ms_output.c
new file mode 100644 (file)
index 0000000..4d6cb01
--- /dev/null
@@ -0,0 +1,333 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * Copyright 2007 Alex Deucher
+ * Copyright 2007 Dave Airlie
+ * 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 on 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
+ * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR 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 "radeon_ms.h"
+
+static struct radeon_ms_output *radeon_ms_connector_get_output(
+               struct drm_radeon_private *dev_priv,
+               struct radeon_ms_connector *connector, int i)
+{
+       if (connector->outputs[i] < 0) {
+               return NULL;
+       }
+       if (connector->outputs[i] >= RADEON_MAX_OUTPUTS) {
+               return NULL;
+       }
+       i = connector->outputs[i];
+       if (dev_priv->outputs[i] == NULL) {
+               return NULL;
+       }
+       if (dev_priv->outputs[i]->connector == NULL) {
+               return dev_priv->outputs[i];
+       }
+       if (dev_priv->outputs[i]->connector == connector) {
+               return dev_priv->outputs[i];
+       }
+       return NULL;
+}
+
+static void radeon_ms_output_dpms(struct drm_output *output, int mode)
+{
+       struct drm_radeon_private *dev_priv = output->dev->dev_private;
+       struct radeon_ms_connector *connector = output->driver_private;
+       struct radeon_ms_output *routput = NULL;
+       int i;
+
+       if (connector == NULL) {
+               return;
+       }
+       for (i = 0; i < RADEON_MAX_OUTPUTS; i++) {
+               routput = radeon_ms_connector_get_output(dev_priv,
+                               connector, i);
+
+               if (routput) {
+                       routput->connector = connector;
+                       routput->dpms(routput, mode);
+               }
+       }
+       radeon_ms_gpu_dpms(output->dev);
+}
+
+static int radeon_ms_output_mode_valid(struct drm_output *output,
+               struct drm_display_mode *mode)
+{
+       struct radeon_ms_connector *connector = output->driver_private;
+
+       if (connector == NULL) {
+               return MODE_ERROR;
+       }
+       return MODE_OK;
+}
+
+static bool radeon_ms_output_mode_fixup(struct drm_output *output,
+               struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+static void radeon_ms_output_prepare(struct drm_output *output)
+{
+       if (output->funcs->dpms) {
+               output->funcs->dpms(output, DPMSModeOff);
+       }
+}
+
+static void radeon_ms_output_commit(struct drm_output *output)
+{
+       if (output->funcs->dpms) {
+               output->funcs->dpms(output, DPMSModeOn);
+       }
+}
+
+static void radeon_ms_output_mode_set(struct drm_output *output,
+               struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode)
+{
+       struct drm_radeon_private *dev_priv = output->dev->dev_private;
+       struct radeon_ms_connector *connector = output->driver_private;
+       struct radeon_ms_crtc *crtc;
+       struct radeon_ms_output *routput = NULL;
+       int i;
+
+       if (connector == NULL) {
+               return;
+       }
+       if (output->crtc == NULL) {
+               return;
+       }
+       crtc = output->crtc->driver_private;
+       connector->crtc = crtc->crtc;
+       /* catch unknown crtc */
+       switch (connector->crtc) {
+               case 1:
+               case 2:
+                       break;
+               default:
+                       /* error */
+                       return;
+       }
+       for (i = 0; i < RADEON_MAX_OUTPUTS; i++) {
+               routput = radeon_ms_connector_get_output(dev_priv,
+                               connector, i);
+               if (routput) {
+                       routput->connector = connector;
+                       routput->mode_set(routput, mode, adjusted_mode);
+               }
+       }
+}
+
+static enum drm_output_status radeon_ms_output_detect(struct drm_output *output)
+{
+       struct radeon_ms_connector *connector = output->driver_private;
+
+       if (connector == NULL || connector->i2c == NULL) {
+               return output_status_unknown;
+       }
+       kfree(connector->edid);
+       connector->edid = drm_get_edid(output, &connector->i2c->adapter);
+       if (connector->edid == NULL) {
+               return output_status_unknown;
+       }
+       return output_status_connected;
+}
+
+static int radeon_ms_output_get_modes(struct drm_output *output)
+{
+       struct radeon_ms_connector *connector = output->driver_private;
+       int ret = 0;
+
+       if (connector == NULL || connector->i2c == NULL) {
+               return 0;
+       }
+       ret = drm_add_edid_modes(output, connector->edid);
+       kfree(connector->edid);
+       connector->edid = NULL;
+       return ret;
+}
+
+static void radeon_ms_output_cleanup(struct drm_output *output)
+{
+       struct radeon_ms_connector *connector = output->driver_private;
+
+       if (connector == NULL) {
+               return;
+       }
+       if (connector->edid) {
+               kfree(connector->edid);
+       }
+       connector->edid = NULL;
+       connector->output = NULL;
+       output->driver_private = NULL;
+}
+
+static const struct drm_output_funcs radeon_ms_output_funcs = {
+       .dpms = radeon_ms_output_dpms,
+       .save = NULL,
+       .restore = NULL,
+       .mode_valid = radeon_ms_output_mode_valid,
+       .mode_fixup = radeon_ms_output_mode_fixup,
+       .prepare = radeon_ms_output_prepare,
+       .mode_set = radeon_ms_output_mode_set,
+       .commit = radeon_ms_output_commit,
+       .detect = radeon_ms_output_detect,
+       .get_modes = radeon_ms_output_get_modes,
+       .cleanup = radeon_ms_output_cleanup,
+};
+
+void radeon_ms_connectors_destroy(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct radeon_ms_connector *connector = NULL;
+       int i = 0;
+
+       for (i = 0; i < RADEON_MAX_CONNECTORS; i++) {
+               if (dev_priv->connectors[i]) {
+                       connector = dev_priv->connectors[i];
+                       dev_priv->connectors[i] = NULL;
+                       if (connector->output) {
+                               drm_output_destroy(connector->output);
+                               connector->output = NULL;
+                       }
+                       if (connector->i2c) {
+                               radeon_ms_i2c_destroy(connector->i2c);
+                               connector->i2c = NULL;
+                       }
+                       drm_free(connector,
+                                       sizeof(struct radeon_ms_connector),
+                                       DRM_MEM_DRIVER);
+               }
+       }
+}
+
+int radeon_ms_connectors_from_properties(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct radeon_ms_connector *connector = NULL;
+       struct drm_output *output = NULL;
+       int i = 0;
+
+       radeon_ms_connectors_destroy(dev);
+       for (i = 0; i < RADEON_MAX_CONNECTORS; i++) {
+               if (dev_priv->properties->connectors[i]) {
+                       connector =
+                               drm_alloc(sizeof(struct radeon_ms_connector),
+                                               DRM_MEM_DRIVER);
+                       if (connector == NULL) {
+                               radeon_ms_connectors_destroy(dev);
+                               return -ENOMEM;
+                       }
+                       memcpy(connector,
+                                       dev_priv->properties->connectors[i],
+                                       sizeof(struct radeon_ms_connector));
+                       connector->i2c = radeon_ms_i2c_create(dev,
+                                       connector->i2c_reg, connector->name);
+                       if (connector->i2c == NULL) {
+                               radeon_ms_connectors_destroy(dev);
+                               return -ENOMEM;
+                       }
+                       output = drm_output_create(dev,
+                                       &radeon_ms_output_funcs,
+                                       connector->name);
+                       if (output == NULL) {
+                               radeon_ms_connectors_destroy(dev);
+                               return -EINVAL;
+                       }
+                       connector->output = output;
+                       output->driver_private = connector;
+                       output->possible_crtcs = 0x3;
+                       dev_priv->connectors[i] = connector;
+               }
+       }
+       return 0;
+}
+
+void radeon_ms_outputs_destroy(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       int i = 0;
+
+       for (i = 0; i < RADEON_MAX_OUTPUTS; i++) {
+               if (dev_priv->outputs[i]) {
+                       drm_free(dev_priv->outputs[i],
+                                       sizeof(struct radeon_ms_output),
+                                       DRM_MEM_DRIVER);
+                       dev_priv->outputs[i] = NULL;
+               }
+       }
+}
+
+int radeon_ms_outputs_from_properties(struct drm_device *dev)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       int i = 0;
+
+       radeon_ms_outputs_destroy(dev);
+       for (i = 0; i < RADEON_MAX_OUTPUTS; i++) {
+               if (dev_priv->properties->outputs[i]) {
+                       dev_priv->outputs[i] =
+                               drm_alloc(sizeof(struct radeon_ms_output),
+                                               DRM_MEM_DRIVER);
+                       if (dev_priv->outputs[i] == NULL) {
+                               radeon_ms_outputs_destroy(dev);
+                               return -ENOMEM;
+                       }
+                       memcpy(dev_priv->outputs[i],
+                                       dev_priv->properties->outputs[i],
+                                       sizeof(struct radeon_ms_output));
+                       dev_priv->outputs[i]->dev = dev;
+                       dev_priv->outputs[i]->initialize(dev_priv->outputs[i]);
+               }
+       }
+       return 0;
+}
+
+void radeon_ms_outputs_restore(struct drm_device *dev,
+               struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       int i;
+
+       for (i = 0; i < RADEON_MAX_OUTPUTS; i++) {
+               if (dev_priv->outputs[i]) {
+                       dev_priv->outputs[i]->restore(dev_priv->outputs[i],
+                                       state);
+               }
+       }
+}
+
+void radeon_ms_outputs_save(struct drm_device *dev, struct radeon_state *state)
+{
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       int i;
+
+       for (i = 0; i < RADEON_MAX_OUTPUTS; i++) {
+               if (dev_priv->outputs[i]) {
+                       dev_priv->outputs[i]->save(dev_priv->outputs[i], state);
+               }
+       }
+}
diff --git a/shared-core/radeon_ms_reg.h b/shared-core/radeon_ms_reg.h
new file mode 100644 (file)
index 0000000..d450280
--- /dev/null
@@ -0,0 +1,1655 @@
+/*
+ * Copyright 2007  Advanced Micro Devices, Inc.
+ *
+ * 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 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 HOLDER(S) OR AUTHOR(S) 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 __RADEON_REG_H__
+#define __RADEON_REG_H__
+
+#define MC_FB_LOCATION                                      0x00000148
+#define    MC_FB_LOCATION__MC_FB_START__MASK                    0x0000FFFF
+#define    MC_FB_LOCATION__MC_FB_START__SHIFT                   0
+#define    MC_FB_LOCATION__MC_FB_TOP__MASK                      0xFFFF0000
+#define    MC_FB_LOCATION__MC_FB_TOP__SHIFT                     16
+#define MC_AGP_LOCATION                                     0x0000014C
+#define    MC_AGP_LOCATION__MC_AGP_START__MASK                  0x0000FFFF
+#define    MC_AGP_LOCATION__MC_AGP_START__SHIFT                 0
+#define    MC_AGP_LOCATION__MC_AGP_TOP__MASK                    0xFFFF0000
+#define    MC_AGP_LOCATION__MC_AGP_TOP__SHIFT                   16
+#define AGP_COMMAND                                         0x00000F60
+#define    AGP_COMMAND__DATA_RATE__MASK                         0x00000007
+#define    AGP_COMMAND__DATA_RATE__SHIFT                        0
+#define    DATA_RATE__v2_1X                                         0x1
+#define    DATA_RATE__v2_2X                                         0x2
+#define    DATA_RATE__v2_4X                                         0x4
+#define    DATA_RATE__v3_4X                                         0x1
+#define    DATA_RATE__v3_8X                                         0x2
+#define    AGP_COMMAND__AGP_EN                                  0x00000100
+#define    AGP_COMMAND__SBA_EN                                  0x00000200
+#define    AGP_COMMAND__RQ_DEPTH__MASK                          0xFF000000
+#define    AGP_COMMAND__RQ_DEPTH__SHIFT                         24
+#define    AGP_COMMAND__FW_EN                                   0x00000010
+#define    AGP_COMMAND__MODE_4G_EN                              0x00000020
+#define    AGP_COMMAND__PARQSZ__MASK                            0x0000E000
+#define    AGP_COMMAND__PARQSZ__SHIFT                           13
+#define AGP_STATUS                                          0x00000F5C
+#define    AGP_STATUS__RATE1X                                   0x00000001
+#define    AGP_STATUS__RATE2X                                   0x00000002
+#define    AGP_STATUS__RATE4X                                   0x00000004
+#define    AGP_STATUS__SBA                                      0x00000200
+#define    AGP_STATUS__RQ__MASK                                 0xFF000000
+#define    AGP_STATUS__RQ__SHIFT                                24
+#define    AGP_STATUS__FW                                       0x00000010
+#define    AGP_STATUS__MODE_4G                                  0x00000020
+#define    AGP_STATUS__RATE1X_4X                                0x00000001
+#define    AGP_STATUS__RATE2X_8X                                0x00000002
+#define    AGP_STATUS__MODE_AGP30                               0x00000008
+#define    AGP_STATUS__CAL_CYCLE__MASK                          0x00001C00
+#define    AGP_STATUS__CAL_CYCLE__SHIFT                         10
+#define    AGP_STATUS__ISOCH_SUPPORT                            0x00020000
+#define AGP_BASE                                            0x00000170
+#define    AGP_BASE__AGP_BASE_ADDR__MASK                        0xFFFFFFFF
+#define    AGP_BASE__AGP_BASE_ADDR__SHIFT                       0
+#define AGP_BASE_2                                          0x0000015C
+#define    AGP_BASE_2__AGP_BASE_ADDR_2__MASK                    0x0000000F
+#define    AGP_BASE_2__AGP_BASE_ADDR_2__SHIFT                   0
+#define CONFIG_MEMSIZE                                      0x000000F8
+#define    CONFIG_MEMSIZE__CONFIG_MEMSIZE__MASK                 0x1F000000
+#define    CONFIG_MEMSIZE__CONFIG_MEMSIZE__SHIFT                24
+#define    CONFIG_MEMSIZE__CONFIG_MEMSIZE_R2__MASK              0x1FF00000
+#define    CONFIG_MEMSIZE__CONFIG_MEMSIZE_R2__SHIFT             20
+#define CONFIG_APER_0_BASE                                  0x00000100
+#define    CONFIG_APER_0_BASE__APER_0_BASE__MASK                0xFE000000
+#define    CONFIG_APER_0_BASE__APER_0_BASE__SHIFT               25
+#define CONFIG_APER_1_BASE                                  0x00000104
+#define    CONFIG_APER_1_BASE__APER_1_BASE__MASK                0xFF000000
+#define    CONFIG_APER_1_BASE__APER_1_BASE__SHIFT               24
+#define CONFIG_APER_SIZE                                    0x00000108
+#define    CONFIG_APER_SIZE__APER_SIZE__MASK                    0x0F000000
+#define    CONFIG_APER_SIZE__APER_SIZE__SHIFT                   24
+#define GEN_INT_CNTL                                        0x00000040
+#define    GEN_INT_CNTL__CRTC_VBLANK                            0x00000001
+#define    GEN_INT_CNTL__CRTC_VLINE                             0x00000002
+#define    GEN_INT_CNTL__CRTC_VSYNC                             0x00000004
+#define    GEN_INT_CNTL__SNAPSHOT                               0x00000008
+#define    GEN_INT_CNTL__FP_DETECT                              0x00000010
+#define    GEN_INT_CNTL__CRTC2_VLINE                            0x00000020
+#define    GEN_INT_CNTL__DMA_VIPH0_INT_EN                       0x00001000
+#define    GEN_INT_CNTL__CRTC2_VSYNC                            0x00000040
+#define    GEN_INT_CNTL__SNAPSHOT2                              0x00000080
+#define    GEN_INT_CNTL__CRTC2_VBLANK                           0x00000200
+#define    GEN_INT_CNTL__FP2_DETECT                             0x00000400
+#define    GEN_INT_CNTL__VSYNC_DIFF_OVER_LIMIT                  0x00000800
+#define    GEN_INT_CNTL__DMA_VIPH1_INT_EN                       0x00002000
+#define    GEN_INT_CNTL__DMA_VIPH2_INT_EN                       0x00004000
+#define    GEN_INT_CNTL__DMA_VIPH3_INT_EN                       0x00008000
+#define    GEN_INT_CNTL__I2C_INT_EN                             0x00020000
+#define    GEN_INT_CNTL__GUI_IDLE                               0x00080000
+#define    GEN_INT_CNTL__VIPH_INT_EN                            0x01000000
+#define    GEN_INT_CNTL__SW_INT_EN                              0x02000000
+#define    GEN_INT_CNTL__GEYSERVILLE                            0x08000000
+#define    GEN_INT_CNTL__DVI_I2C_INT                            0x20000000
+#define    GEN_INT_CNTL__GUIDMA                                 0x40000000
+#define    GEN_INT_CNTL__VIDDMA                                 0x80000000
+#define    GEN_INT_CNTL__TIMER_INT                              0x00010000
+#define    GEN_INT_CNTL__IDCT_INT_EN                            0x08000000
+#define GEN_INT_STATUS                                      0x00000044
+#define    GEN_INT_STATUS__CRTC_VBLANK_STAT                     0x00000001
+#define    GEN_INT_STATUS__CRTC_VBLANK_STAT_AK                  0x00000001
+#define    GEN_INT_STATUS__CRTC_VLINE_STAT                      0x00000002
+#define    GEN_INT_STATUS__CRTC_VLINE_STAT_AK                   0x00000002
+#define    GEN_INT_STATUS__CRTC_VSYNC_STAT                      0x00000004
+#define    GEN_INT_STATUS__CRTC_VSYNC_STAT_AK                   0x00000004
+#define    GEN_INT_STATUS__SNAPSHOT_STAT                        0x00000008
+#define    GEN_INT_STATUS__SNAPSHOT_STAT_AK                     0x00000008
+#define    GEN_INT_STATUS__FP_DETECT_STAT                       0x00000010
+#define    GEN_INT_STATUS__FP_DETECT_STAT_AK                    0x00000010
+#define    GEN_INT_STATUS__CRTC2_VLINE_STAT                     0x00000020
+#define    GEN_INT_STATUS__CRTC2_VLINE_STAT_AK                  0x00000020
+#define    GEN_INT_STATUS__CRTC2_VSYNC_STAT                     0x00000040
+#define    GEN_INT_STATUS__CRTC2_VSYNC_STAT_AK                  0x00000040
+#define    GEN_INT_STATUS__SNAPSHOT2_STAT                       0x00000080
+#define    GEN_INT_STATUS__SNAPSHOT2_STAT_AK                    0x00000080
+#define    GEN_INT_STATUS__CAP0_INT_ACTIVE                      0x00000100
+#define    GEN_INT_STATUS__CRTC2_VBLANK_STAT                    0x00000200
+#define    GEN_INT_STATUS__CRTC2_VBLANK_STAT_AK                 0x00000200
+#define    GEN_INT_STATUS__FP2_DETECT_STAT                      0x00000400
+#define    GEN_INT_STATUS__FP2_DETECT_STAT_AK                   0x00000400
+#define    GEN_INT_STATUS__VSYNC_DIFF_OVER_LIMIT_STAT           0x00000800
+#define    GEN_INT_STATUS__VSYNC_DIFF_OVER_LIMIT_STAT_AK        0x00000800
+#define    GEN_INT_STATUS__DMA_VIPH0_INT                        0x00001000
+#define    GEN_INT_STATUS__DMA_VIPH0_INT_AK                     0x00001000
+#define    GEN_INT_STATUS__DMA_VIPH1_INT                        0x00002000
+#define    GEN_INT_STATUS__DMA_VIPH1_INT_AK                     0x00002000
+#define    GEN_INT_STATUS__DMA_VIPH2_INT                        0x00004000
+#define    GEN_INT_STATUS__DMA_VIPH2_INT_AK                     0x00004000
+#define    GEN_INT_STATUS__DMA_VIPH3_INT                        0x00008000
+#define    GEN_INT_STATUS__DMA_VIPH3_INT_AK                     0x00008000
+#define    GEN_INT_STATUS__I2C_INT                              0x00020000
+#define    GEN_INT_STATUS__I2C_INT_AK                           0x00020000
+#define    GEN_INT_STATUS__GUI_IDLE_STAT                        0x00080000
+#define    GEN_INT_STATUS__GUI_IDLE_STAT_AK                     0x00080000
+#define    GEN_INT_STATUS__VIPH_INT                             0x01000000
+#define    GEN_INT_STATUS__SW_INT                               0x02000000
+#define    GEN_INT_STATUS__SW_INT_AK                            0x02000000
+#define    GEN_INT_STATUS__SW_INT_SET                           0x04000000
+#define    GEN_INT_STATUS__GEYSERVILLE_STAT                     0x08000000
+#define    GEN_INT_STATUS__GEYSERVILLE_STAT_AK                  0x08000000
+#define    GEN_INT_STATUS__DVI_I2C_INT_STAT                     0x20000000
+#define    GEN_INT_STATUS__DVI_I2C_INT_AK                       0x20000000
+#define    GEN_INT_STATUS__GUIDMA_STAT                          0x40000000
+#define    GEN_INT_STATUS__GUIDMA_AK                            0x40000000
+#define    GEN_INT_STATUS__VIDDMA_STAT                          0x80000000
+#define    GEN_INT_STATUS__VIDDMA_AK                            0x80000000
+#define    GEN_INT_STATUS__TIMER_INT_STAT                       0x00010000
+#define    GEN_INT_STATUS__TIMER_INT_STAT_AK                    0x00010000
+#define    GEN_INT_STATUS__IDCT_INT_STAT                        0x08000000
+#define    GEN_INT_STATUS__IDCT_INT_STAT_AK                     0x08000000
+#define RB2D_DSTCACHE_MODE                                  0x00003428
+#define    RB2D_DSTCACHE_MODE__DC_BYPASS__MASK                  0x00000003
+#define    RB2D_DSTCACHE_MODE__DC_BYPASS__SHIFT                 0
+#define    RB2D_DSTCACHE_MODE__DC_LINE_SIZE__MASK               0x0000000C
+#define    RB2D_DSTCACHE_MODE__DC_LINE_SIZE__SHIFT              2
+#define    RB2D_DSTCACHE_MODE__DC_AUTOFLUSH_ENABLE__MASK        0x00000300
+#define    RB2D_DSTCACHE_MODE__DC_AUTOFLUSH_ENABLE__SHIFT       8
+#define    RB2D_DSTCACHE_MODE__DC_FORCE_RMW                     0x00010000
+#define    RB2D_DSTCACHE_MODE__DC_DISABLE_RI_FILL               0x01000000
+#define    RB2D_DSTCACHE_MODE__DC_DISABLE_RI_READ               0x02000000
+#define    RB2D_DSTCACHE_MODE__DC_AUTOFREE_ENABLE__MASK         0x00000C00
+#define    RB2D_DSTCACHE_MODE__DC_AUTOFREE_ENABLE__SHIFT        10
+#define    RB2D_DSTCACHE_MODE__DC_DISABLE                       0x04000000
+#define    RB2D_DSTCACHE_MODE__DC_DISABLE_IGNORE_PE             0x00020000
+#define RB2D_DSTCACHE_CTLSTAT                               0x0000342C
+#define    RB2D_DSTCACHE_CTLSTAT__DC_FLUSH__MASK                0x00000003
+#define    RB2D_DSTCACHE_CTLSTAT__DC_FLUSH__SHIFT               0
+#define    RB2D_DSTCACHE_CTLSTAT__DC_FREE__MASK                 0x0000000C
+#define    RB2D_DSTCACHE_CTLSTAT__DC_FREE__SHIFT                2
+#define    RB2D_DSTCACHE_CTLSTAT__DC_BUSY                       0x80000000
+#define RB3D_DSTCACHE_CTLSTAT                               0x0000325C
+#define    RB3D_DSTCACHE_CTLSTAT__DC_FLUSH__MASK                0x00000003
+#define    RB3D_DSTCACHE_CTLSTAT__DC_FLUSH__SHIFT               0
+#define    RB3D_DSTCACHE_CTLSTAT__DC_FREE__MASK                 0x0000000C
+#define    RB3D_DSTCACHE_CTLSTAT__DC_FREE__SHIFT                2
+#define    RB3D_DSTCACHE_CTLSTAT__DC_BUSY                       0x80000000
+#define RB3D_DSTCACHE_CTLSTAT_R3                            0x00004E4C
+#define    RB3D_DSTCACHE_CTLSTAT_R3__DC_FLUSH__MASK             0x00000003
+#define    RB3D_DSTCACHE_CTLSTAT_R3__DC_FLUSH__SHIFT            0
+#define    RB3D_DSTCACHE_CTLSTAT_R3__DC_FREE__MASK              0x0000000C
+#define    RB3D_DSTCACHE_CTLSTAT_R3__DC_FREE__SHIFT             2
+#define    RB3D_DSTCACHE_CTLSTAT_R3__DC_FINISH                  0x00000010
+#define RB3D_ZCACHE_CTLSTAT                                 0x00003254
+#define    RB3D_ZCACHE_CTLSTAT__ZC_FLUSH                        0x00000001
+#define    RB3D_ZCACHE_CTLSTAT__ZC_FREE                         0x00000004
+#define    RB3D_ZCACHE_CTLSTAT__ZC_DIRTY                        0x40000000
+#define    RB3D_ZCACHE_CTLSTAT__ZC_BUSY                         0x80000000
+#define RB3D_ZCACHE_CTLSTAT_R3                              0x00004F18
+#define    RB3D_ZCACHE_CTLSTAT_R3__ZC_FLUSH                     0x00000001
+#define    RB3D_ZCACHE_CTLSTAT_R3__ZC_FREE                      0x00000002
+#define    RB3D_ZCACHE_CTLSTAT_R3__ZC_BUSY                      0x80000000
+#define SCRATCH_REG0                                        0x000015E0
+#define    SCRATCH_REG0__SCRATCH_REG0__MASK                     0xFFFFFFFF
+#define    SCRATCH_REG0__SCRATCH_REG0__SHIFT                    0
+#define SCRATCH_REG1                                        0x000015E4
+#define    SCRATCH_REG1__SCRATCH_REG1__MASK                     0xFFFFFFFF
+#define    SCRATCH_REG1__SCRATCH_REG1__SHIFT                    0
+#define SCRATCH_REG2                                        0x000015E8
+#define    SCRATCH_REG2__SCRATCH_REG2__MASK                     0xFFFFFFFF
+#define    SCRATCH_REG2__SCRATCH_REG2__SHIFT                    0
+#define SCRATCH_REG3                                        0x000015EC
+#define    SCRATCH_REG3__SCRATCH_REG3__MASK                     0xFFFFFFFF
+#define    SCRATCH_REG3__SCRATCH_REG3__SHIFT                    0
+#define SCRATCH_REG4                                        0x000015F0
+#define    SCRATCH_REG4__SCRATCH_REG4__MASK                     0xFFFFFFFF
+#define    SCRATCH_REG4__SCRATCH_REG4__SHIFT                    0
+#define SCRATCH_REG5                                        0x000015F4
+#define    SCRATCH_REG5__SCRATCH_REG5__MASK                     0xFFFFFFFF
+#define    SCRATCH_REG5__SCRATCH_REG5__SHIFT                    0
+#define SCRATCH_REG6                                        0x000015F8
+#define    SCRATCH_REG6__SCRATCH_REG6__MASK                     0xFFFFFFFF
+#define    SCRATCH_REG6__SCRATCH_REG6__SHIFT                    0
+#define SCRATCH_REG7                                        0x000015FC
+#define    SCRATCH_REG7__SCRATCH_REG7__MASK                     0xFFFFFFFF
+#define    SCRATCH_REG7__SCRATCH_REG7__SHIFT                    0
+#define PCIE_INDEX                                          0x00000030
+#define    PCIE_INDEX__PCIE_INDEX__MASK                         0x000007FF
+#define    PCIE_INDEX__PCIE_INDEX__SHIFT                        0
+#define PCIE_DATA                                           0x00000034
+#define    PCIE_DATA__PCIE_DATA__MASK                           0xFFFFFFFF
+#define    PCIE_DATA__PCIE_DATA__SHIFT                          0
+#define PCIE_TX_GART_CNTL                                   0x00000010
+#define    PCIE_TX_GART_CNTL__GART_EN                           0x00000001
+#define    PCIE_TX_GART_CNTL__GART_UNMAPPED_ACCESS__MASK        0x00000006
+#define    PCIE_TX_GART_CNTL__GART_UNMAPPED_ACCESS__SHIFT       1
+#define    GART_UNMAPPED_ACCESS__PTHRU                              0x0
+#define    GART_UNMAPPED_ACCESS__CLAMP                              0x1
+#define    GART_UNMAPPED_ACCESS__DISCARD                            0x3
+#define    PCIE_TX_GART_CNTL__GART_MODE__MASK                   0x00000018
+#define    PCIE_TX_GART_CNTL__GART_MODE__SHIFT                  3
+#define    GART_MODE__CACHE_32x128                                  0x0
+#define    GART_MODE__CACHE_8x4x128                                 0x1
+#define    PCIE_TX_GART_CNTL__GART_CHK_RW_VALID_EN              0x00000020
+#define    PCIE_TX_GART_CNTL__GART_RDREQPATH_SEL__MASK          0x00000040
+#define    PCIE_TX_GART_CNTL__GART_RDREQPATH_SEL__SHIFT         6
+#define    GART_RDREQPATH_SEL__HDP                                  0x0
+#define    GART_RDREQPATH_SEL__DRQMC                                0x1
+#define    PCIE_TX_GART_CNTL__GART_INVALIDATE_TLB               0x00000100
+#define PCIE_TX_GART_DISCARD_RD_ADDR_LO                     0x00000011
+#define    PCIE_TX_GART_DISCARD_RD_ADDR_LO__GART_DISCARD_RD_ADDR_LO__MASK 0xFFFFFFFF
+#define    PCIE_TX_GART_DISCARD_RD_ADDR_LO__GART_DISCARD_RD_ADDR_LO__SHIFT 0
+#define PCIE_TX_GART_DISCARD_RD_ADDR_HI                     0x00000012
+#define    PCIE_TX_GART_DISCARD_RD_ADDR_HI__GART_DISCARD_RD_ADDR_HI__MASK 0x000000FF
+#define    PCIE_TX_GART_DISCARD_RD_ADDR_HI__GART_DISCARD_RD_ADDR_HI__SHIFT 0
+#define PCIE_TX_GART_BASE                                   0x00000013
+#define    PCIE_TX_GART_BASE__GART_BASE__MASK                   0xFFFFFFFF
+#define    PCIE_TX_GART_BASE__GART_BASE__SHIFT                  0
+#define PCIE_TX_GART_START_LO                               0x00000014
+#define    PCIE_TX_GART_START_LO__GART_START_LO__MASK           0xFFFFFFFF
+#define    PCIE_TX_GART_START_LO__GART_START_LO__SHIFT          0
+#define PCIE_TX_GART_START_HI                               0x00000015
+#define    PCIE_TX_GART_START_HI__GART_START_HI__MASK           0x000000FF
+#define    PCIE_TX_GART_START_HI__GART_START_HI__SHIFT          0
+#define PCIE_TX_GART_END_LO                                 0x00000016
+#define    PCIE_TX_GART_END_LO__GART_END_LO__MASK               0xFFFFFFFF
+#define    PCIE_TX_GART_END_LO__GART_END_LO__SHIFT              0
+#define PCIE_TX_GART_END_HI                                 0x00000017
+#define    PCIE_TX_GART_END_HI__GART_END_HI__MASK               0x000000FF
+#define    PCIE_TX_GART_END_HI__GART_END_HI__SHIFT              0
+#define PCIE_TX_GART_ERROR                                  0x00000018
+#define    PCIE_TX_GART_ERROR__GART_UNMAPPED                    0x00000002
+#define    PCIE_TX_GART_ERROR__GART_INVALID_READ                0x00000004
+#define    PCIE_TX_GART_ERROR__GART_INVALID_WRITE               0x00000008
+#define    PCIE_TX_GART_ERROR__GART_INVALID_ADDR__MASK          0xFFFFFFF0
+#define    PCIE_TX_GART_ERROR__GART_INVALID_ADDR__SHIFT         4
+#define CP_RB_CNTL                                          0x00000704
+#define    CP_RB_CNTL__RB_BUFSZ__MASK                           0x0000003F
+#define    CP_RB_CNTL__RB_BUFSZ__SHIFT                          0
+#define    CP_RB_CNTL__RB_BLKSZ__MASK                           0x00003F00
+#define    CP_RB_CNTL__RB_BLKSZ__SHIFT                          8
+#define    CP_RB_CNTL__BUF_SWAP__MASK                           0x00030000
+#define    CP_RB_CNTL__BUF_SWAP__SHIFT                          16
+#define    CP_RB_CNTL__MAX_FETCH__MASK                          0x000C0000
+#define    CP_RB_CNTL__MAX_FETCH__SHIFT                         18
+#define    CP_RB_CNTL__RB_NO_UPDATE                             0x08000000
+#define    CP_RB_CNTL__RB_RPTR_WR_ENA                           0x80000000
+#define CP_RB_BASE                                          0x00000700
+#define    CP_RB_BASE__RB_BASE__MASK                            0xFFFFFFFC
+#define    CP_RB_BASE__RB_BASE__SHIFT                           2
+#define CP_RB_RPTR_ADDR                                     0x0000070C
+#define    CP_RB_RPTR_ADDR__RB_RPTR_SWAP__MASK                  0x00000003
+#define    CP_RB_RPTR_ADDR__RB_RPTR_SWAP__SHIFT                 0
+#define    CP_RB_RPTR_ADDR__RB_RPTR_ADDR__MASK                  0xFFFFFFFC
+#define    CP_RB_RPTR_ADDR__RB_RPTR_ADDR__SHIFT                 2
+#define CP_RB_RPTR                                          0x00000710
+#define    CP_RB_RPTR__RB_RPTR__MASK                            0x007FFFFF
+#define    CP_RB_RPTR__RB_RPTR__SHIFT                           0
+#define CP_RB_RPTR_WR                                       0x0000071C
+#define    CP_RB_RPTR_WR__RB_RPTR_WR__MASK                      0x007FFFFF
+#define    CP_RB_RPTR_WR__RB_RPTR_WR__SHIFT                     0
+#define CP_RB_WPTR                                          0x00000714
+#define    CP_RB_WPTR__RB_WPTR__MASK                            0x007FFFFF
+#define    CP_RB_WPTR__RB_WPTR__SHIFT                           0
+#define CP_RB_WPTR_DELAY                                    0x00000718
+#define    CP_RB_WPTR_DELAY__PRE_WRITE_TIMER__MASK              0x0FFFFFFF
+#define    CP_RB_WPTR_DELAY__PRE_WRITE_TIMER__SHIFT             0
+#define    CP_RB_WPTR_DELAY__PRE_WRITE_LIMIT__MASK              0xF0000000
+#define    CP_RB_WPTR_DELAY__PRE_WRITE_LIMIT__SHIFT             28
+#define SCRATCH_UMSK                                        0x00000770
+#define    SCRATCH_UMSK__SCRATCH_UMSK__MASK                     0x0000003F
+#define    SCRATCH_UMSK__SCRATCH_UMSK__SHIFT                    0
+#define    SCRATCH_UMSK__SCRATCH_SWAP__MASK                     0x00030000
+#define    SCRATCH_UMSK__SCRATCH_SWAP__SHIFT                    16
+#define    SCRATCH_UMSK__SCRATCH_UMSK_R2__MASK                  0x000000FF
+#define    SCRATCH_UMSK__SCRATCH_UMSK_R2__SHIFT                 0
+#define SCRATCH_ADDR                                        0x00000774
+#define    SCRATCH_ADDR__SCRATCH_ADDR__MASK                     0xFFFFFFE0
+#define    SCRATCH_ADDR__SCRATCH_ADDR__SHIFT                    5
+#define CP_ME_RAM_ADDR                                      0x000007D4
+#define    CP_ME_RAM_ADDR__ME_RAM_ADDR__MASK                    0x000000FF
+#define    CP_ME_RAM_ADDR__ME_RAM_ADDR__SHIFT                   0
+#define CP_ME_RAM_DATAH                                     0x000007DC
+#define    CP_ME_RAM_DATAH__ME_RAM_DATAH__MASK                  0x0000003F
+#define    CP_ME_RAM_DATAH__ME_RAM_DATAH__SHIFT                 0
+#define    CP_ME_RAM_DATAH__ME_RAM_DATAH_R3__MASK               0x000000FF
+#define    CP_ME_RAM_DATAH__ME_RAM_DATAH_R3__SHIFT              0
+#define CP_ME_RAM_DATAL                                     0x000007E0
+#define    CP_ME_RAM_DATAL__ME_RAM_DATAL__MASK                  0xFFFFFFFF
+#define    CP_ME_RAM_DATAL__ME_RAM_DATAL__SHIFT                 0
+#define CP_CSQ_CNTL                                         0x00000740
+#define    CP_CSQ_CNTL__CSQ_CNT_PRIMARY__MASK                   0x000000FF
+#define    CP_CSQ_CNTL__CSQ_CNT_PRIMARY__SHIFT                  0
+#define    CP_CSQ_CNTL__CSQ_CNT_INDIRECT__MASK                  0x0000FF00
+#define    CP_CSQ_CNTL__CSQ_CNT_INDIRECT__SHIFT                 8
+#define    CP_CSQ_CNTL__CSQ_MODE__MASK                          0xF0000000
+#define    CP_CSQ_CNTL__CSQ_MODE__SHIFT                         28
+#define    CSQ_MODE__CSQ_PRIDIS_INDDIS                              0x0
+#define    CSQ_MODE__CSQ_PRIPIO_INDDIS                              0x1
+#define    CSQ_MODE__CSQ_PRIBM_INDDIS                               0x2
+#define    CSQ_MODE__CSQ_PRIPIO_INDBM                               0x3
+#define    CSQ_MODE__CSQ_PRIBM_INDBM                                0x4
+#define    CSQ_MODE__CSQ_PRIPIO_INDPIO                              0xF
+#define    CP_CSQ_CNTL__CSQ_CNT_PRIMARY_R2__MASK                0x000001FF
+#define    CP_CSQ_CNTL__CSQ_CNT_PRIMARY_R2__SHIFT               0
+#define    CP_CSQ_CNTL__CSQ_CNT_INDIRECT_R2__MASK               0x0003FE00
+#define    CP_CSQ_CNTL__CSQ_CNT_INDIRECT_R2__SHIFT              9
+#define    CP_CSQ_CNTL__CSQ_CNT_INDIRECT2__MASK                 0x07FC0000
+#define    CP_CSQ_CNTL__CSQ_CNT_INDIRECT2__SHIFT                18
+#define CRTC_GEN_CNTL                                       0x00000050
+#define    CRTC_GEN_CNTL__CRTC_DBL_SCAN_EN                      0x00000001
+#define    CRTC_GEN_CNTL__CRTC_INTERLACE_EN                     0x00000002
+#define    CRTC_GEN_CNTL__CRTC_C_SYNC_EN                        0x00000010
+#define    CRTC_GEN_CNTL__CRTC_PIX_WIDTH__MASK                  0x00000F00
+#define    CRTC_GEN_CNTL__CRTC_PIX_WIDTH__SHIFT                 8
+#define    CRTC_PIX_WIDTH__4BPP                                     0x100
+#define    CRTC_PIX_WIDTH__8BPP                                     0x200
+#define    CRTC_PIX_WIDTH__15BPP                                    0x300
+#define    CRTC_PIX_WIDTH__16BPP                                    0x400
+#define    CRTC_PIX_WIDTH__24BPP                                    0x500
+#define    CRTC_PIX_WIDTH__34BPP                                    0x600
+#define    CRTC_PIX_WIDTH__16BPP_4444                               0x700
+#define    CRTC_PIX_WIDTH__16BPP_88                                 0x800
+#define    CRTC_GEN_CNTL__CRTC_ICON_EN                          0x00008000
+#define    CRTC_GEN_CNTL__CRTC_CUR_EN                           0x00010000
+#define    CRTC_GEN_CNTL__CRTC_VSTAT_MODE__MASK                 0x00060000
+#define    CRTC_GEN_CNTL__CRTC_VSTAT_MODE__SHIFT                17
+#define    CRTC_GEN_CNTL__CRTC_CUR_MODE__MASK                   0x00700000
+#define    CRTC_GEN_CNTL__CRTC_CUR_MODE__SHIFT                  20
+#define    CRTC_CUR_MODE__PREMULTI_ALPHA                            0x2
+#define    CRTC_CUR_MODE__COLOR24BPP                                0x1
+#define    CRTC_GEN_CNTL__CRTC_EXT_DISP_EN                      0x01000000
+#define    CRTC_GEN_CNTL__CRTC_EN                               0x02000000
+#define    CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B                    0x04000000
+#define    CRTC_GEN_CNTL__CRTC_MODE9_COLOR_ORDER                0x00001000
+#define CRTC_EXT_CNTL                                       0x00000054
+#define    CRTC_EXT_CNTL__CRTC_VGA_XOVERSCAN                    0x00000001
+#define    CRTC_EXT_CNTL__VGA_BLINK_RATE__MASK                  0x00000006
+#define    CRTC_EXT_CNTL__VGA_BLINK_RATE__SHIFT                 1
+#define    CRTC_EXT_CNTL__VGA_ATI_LINEAR                        0x00000008
+#define    CRTC_EXT_CNTL__VGA_128KAP_PAGING                     0x00000010
+#define    CRTC_EXT_CNTL__VGA_TEXT_132                          0x00000020
+#define    CRTC_EXT_CNTL__VGA_XCRT_CNT_EN                       0x00000040
+#define    CRTC_EXT_CNTL__CRTC_HSYNC_DIS                        0x00000100
+#define    CRTC_EXT_CNTL__CRTC_VSYNC_DIS                        0x00000200
+#define    CRTC_EXT_CNTL__CRTC_DISPLAY_DIS                      0x00000400
+#define    CRTC_EXT_CNTL__CRTC_SYNC_TRISTATE                    0x00000800
+#define    CRTC_EXT_CNTL__CRTC_HSYNC_TRISTATE                   0x00001000
+#define    CRTC_EXT_CNTL__CRTC_VSYNC_TRISTATE                   0x00002000
+#define    CRTC_EXT_CNTL__CRT_ON                                0x00008000
+#define    CRTC_EXT_CNTL__VGA_CUR_B_TEST                        0x00020000
+#define    CRTC_EXT_CNTL__VGA_PACK_DIS                          0x00040000
+#define    CRTC_EXT_CNTL__VGA_MEM_PS_EN                         0x00080000
+#define    CRTC_EXT_CNTL__VCRTC_IDX_MASTER__MASK                0x7F000000
+#define    CRTC_EXT_CNTL__VCRTC_IDX_MASTER__SHIFT               24
+#define CRTC_H_TOTAL_DISP                                   0x00000200
+#define    CRTC_H_TOTAL_DISP__CRTC_H_TOTAL__MASK                0x000003FF
+#define    CRTC_H_TOTAL_DISP__CRTC_H_TOTAL__SHIFT               0
+#define    CRTC_H_TOTAL_DISP__CRTC_H_DISP__MASK                 0x01FF0000
+#define    CRTC_H_TOTAL_DISP__CRTC_H_DISP__SHIFT                16
+#define CRTC_H_SYNC_STRT_WID                                0x00000204
+#define    CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_STRT_PIX__MASK     0x00000007
+#define    CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_STRT_PIX__SHIFT    0
+#define    CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_STRT_CHAR__MASK    0x00001FF8
+#define    CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_STRT_CHAR__SHIFT   3
+#define    CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_WID__MASK          0x003F0000
+#define    CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_WID__SHIFT         16
+#define    CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_POL                0x00800000
+#define    CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_SKEW_TUNE__MASK    0x07000000
+#define    CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_SKEW_TUNE__SHIFT   24
+#define    CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_SKEW_TUNE_MODE     0x10000000
+#define CRTC_V_TOTAL_DISP                                   0x00000208
+#define    CRTC_V_TOTAL_DISP__CRTC_V_TOTAL__MASK                0x00000FFF
+#define    CRTC_V_TOTAL_DISP__CRTC_V_TOTAL__SHIFT               0
+#define    CRTC_V_TOTAL_DISP__CRTC_V_DISP__MASK                 0x0FFF0000
+#define    CRTC_V_TOTAL_DISP__CRTC_V_DISP__SHIFT                16
+#define CRTC_V_SYNC_STRT_WID                                0x0000020C
+#define    CRTC_V_SYNC_STRT_WID__CRTC_V_SYNC_STRT__MASK         0x00000FFF
+#define    CRTC_V_SYNC_STRT_WID__CRTC_V_SYNC_STRT__SHIFT        0
+#define    CRTC_V_SYNC_STRT_WID__CRTC_V_SYNC_WID__MASK          0x001F0000
+#define    CRTC_V_SYNC_STRT_WID__CRTC_V_SYNC_WID__SHIFT         16
+#define    CRTC_V_SYNC_STRT_WID__CRTC_V_SYNC_POL                0x00800000
+#define CRTC_OFFSET                                         0x00000224
+#define    CRTC_OFFSET__CRTC_OFFSET__MASK                       0x07FFFFFF
+#define    CRTC_OFFSET__CRTC_OFFSET__SHIFT                      0
+#define    CRTC_OFFSET__CRTC_GUI_TRIG_OFFSET                    0x40000000
+#define    CRTC_OFFSET__CRTC_OFFSET_LOCK                        0x80000000
+#define    CRTC_OFFSET__CRTC_OFFSET_R3__MASK                    0x0FFFFFFF
+#define    CRTC_OFFSET__CRTC_OFFSET_R3__SHIFT                   0
+#define CRTC_OFFSET_CNTL                                    0x00000228
+#define    CRTC_OFFSET_CNTL__CRTC_TILE_LINE__MASK               0x0000000F
+#define    CRTC_OFFSET_CNTL__CRTC_TILE_LINE__SHIFT              0
+#define    CRTC_OFFSET_CNTL__CRTC_TILE_LINE_RIGHT__MASK         0x000000F0
+#define    CRTC_OFFSET_CNTL__CRTC_TILE_LINE_RIGHT__SHIFT        4
+#define    CRTC_OFFSET_CNTL__CRTC_TILE_EN_RIGHT                 0x00004000
+#define    CRTC_OFFSET_CNTL__CRTC_TILE_EN                       0x00008000
+#define    CRTC_OFFSET_CNTL__CRTC_OFFSET_FLIP_CNTL              0x00010000
+#define    CRTC_OFFSET_CNTL__CRTC_STEREO_OFFSET_EN              0x00020000
+#define    CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_EN__MASK          0x000C0000
+#define    CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_EN__SHIFT         18
+#define    CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN            0x00100000
+#define    CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC                   0x00200000
+#define    CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET_LEFT_EN       0x10000000
+#define    CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET_RIGHT_EN      0x20000000
+#define    CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET               0x40000000
+#define    CRTC_OFFSET_CNTL__CRTC_OFFSET_LOCK                   0x80000000
+#define    CRTC_OFFSET_CNTL__CRTC_X_Y_MODE_EN_RIGHT             0x00000040
+#define    CRTC_OFFSET_CNTL__CRTC_MICRO_TILE_BUFFER_MODE_RIGHT__MASK 0x00000180
+#define    CRTC_OFFSET_CNTL__CRTC_MICRO_TILE_BUFFER_MODE_RIGHT__SHIFT 7
+#define    CRTC_OFFSET_CNTL__CRTC_X_Y_MODE_EN                   0x00000200
+#define    CRTC_OFFSET_CNTL__CRTC_MICRO_TILE_BUFFER_MODE__MASK  0x00000C00
+#define    CRTC_OFFSET_CNTL__CRTC_MICRO_TILE_BUFFER_MODE__SHIFT 10
+#define    CRTC_MICRO_TILE_BUFFER_MODE__AUTO                        0x0
+#define    CRTC_MICRO_TILE_BUFFER_MODE__SLINE                       0x1
+#define    CRTC_MICRO_TILE_BUFFER_MODE__DLINE                       0x2
+#define    CRTC_MICRO_TILE_BUFFER_MODE__DIS                         0x3
+#define    CRTC_OFFSET_CNTL__CRTC_MICRO_TILE_EN_RIGHT           0x00001000
+#define    CRTC_OFFSET_CNTL__CRTC_MICRO_TILE_EN                 0x00002000
+#define    CRTC_OFFSET_CNTL__CRTC_MACRO_TILE_EN_RIGHT           0x00004000
+#define    CRTC_OFFSET_CNTL__CRTC_MACRO_TILE_EN                 0x00008000
+#define CRTC_PITCH                                          0x0000022C
+#define    CRTC_PITCH__CRTC_PITCH__MASK                         0x000007FF
+#define    CRTC_PITCH__CRTC_PITCH__SHIFT                        0
+#define    CRTC_PITCH__CRTC_PITCH_RIGHT__MASK                   0x07FF0000
+#define    CRTC_PITCH__CRTC_PITCH_RIGHT__SHIFT                  16
+#define CRTC_MORE_CNTL                                      0x0000027C
+#define    CRTC_MORE_CNTL__CRTC_HORZ_BLANK_MODE_SEL             0x00000001
+#define    CRTC_MORE_CNTL__CRTC_VERT_BLANK_MODE_SEL             0x00000002
+#define    CRTC_MORE_CNTL__CRTC_AUTO_HORZ_CENTER_EN             0x00000004
+#define    CRTC_MORE_CNTL__CRTC_AUTO_VERT_CENTER_EN             0x00000008
+#define    CRTC_MORE_CNTL__CRTC_H_CUTOFF_ACTIVE_EN              0x00000010
+#define    CRTC_MORE_CNTL__CRTC_V_CUTOFF_ACTIVE_EN              0x00000020
+#define    CRTC_MORE_CNTL__FORCE_H_EVEN_PIXEL_COUNT             0x00000040
+#define    CRTC_MORE_CNTL__RMX_H_FILT_COEFFICIENT__MASK         0x07000000
+#define    CRTC_MORE_CNTL__RMX_H_FILT_COEFFICIENT__SHIFT        24
+#define    CRTC_MORE_CNTL__RMX_H_FILTER_EN                      0x08000000
+#define    CRTC_MORE_CNTL__RMX_V_FILT_COEFFICIENT__MASK         0x70000000
+#define    CRTC_MORE_CNTL__RMX_V_FILT_COEFFICIENT__SHIFT        28
+#define    CRTC_MORE_CNTL__RMX_V_FILTER_EN                      0x80000000
+#define    CRTC_MORE_CNTL__DSP_RST_HCOUNT                       0x00000100
+#define    CRTC_MORE_CNTL__DSP_RST_VCOUNT                       0x00000200
+#define    CRTC_MORE_CNTL__HCOUNT_RST_POS                       0x00000400
+#define    CRTC_MORE_CNTL__VCOUNT_RST_POS                       0x00000800
+#define    CRTC_MORE_CNTL__CRTC_FIX_VSYNC_EDGE_POSITION_EN      0x00001000
+#define CRTC_TILE_X0_Y0                                     0x00000350
+#define    CRTC_TILE_X0_Y0__CRTC_TILE_X0__MASK                  0x00000FFF
+#define    CRTC_TILE_X0_Y0__CRTC_TILE_X0__SHIFT                 0
+#define    CRTC_TILE_X0_Y0__CRTC_TILE_Y0__MASK                  0x0FFF0000
+#define    CRTC_TILE_X0_Y0__CRTC_TILE_Y0__SHIFT                 16
+#define    CRTC_TILE_X0_Y0__CRTC_GUI_TRIG_OFFSET                0x40000000
+#define    CRTC_TILE_X0_Y0__CRTC_OFFSET_LOCK                    0x80000000
+#define DAC_CNTL                                            0x00000058
+#define    DAC_CNTL__DAC_RANGE_CNTL__MASK                       0x00000003
+#define    DAC_CNTL__DAC_RANGE_CNTL__SHIFT                      0
+#define    DAC_RANGE_CNTL__PS2                                      0x2
+#define    DAC_RANGE_CNTL__YPbPr                                    0x3
+#define    DAC_CNTL__DAC_BLANKING                               0x00000004
+#define    DAC_CNTL__DAC_CMP_EN                                 0x00000008
+#define    DAC_CNTL__DAC_CMP_OUT_R                              0x00000010
+#define    DAC_CNTL__DAC_CMP_OUT_G                              0x00000020
+#define    DAC_CNTL__DAC_CMP_OUT_B                              0x00000040
+#define    DAC_CNTL__DAC_CMP_OUTPUT                             0x00000080
+#define    DAC_CNTL__DAC_8BIT_EN                                0x00000100
+#define    DAC_CNTL__DAC_4BPP_PIX_ORDER                         0x00000200
+#define    DAC_CNTL__DAC_TVO_EN                                 0x00000400
+#define    DAC_CNTL__DAC_VGA_ADR_EN                             0x00002000
+#define    DAC_CNTL__DAC_EXPAND_MODE                            0x00004000
+#define    DAC_CNTL__DAC_PDWN                                   0x00008000
+#define    DAC_CNTL__CRT_SENSE                                  0x00010000
+#define    DAC_CNTL__CRT_DETECTION_ON                           0x00020000
+#define    DAC_CNTL__DAC_CRC_CONT_EN                            0x00040000
+#define    DAC_CNTL__DAC_CRC_EN                                 0x00080000
+#define    DAC_CNTL__DAC_CRC_FIELD                              0x00100000
+#define    DAC_CNTL__DAC_LUT_COUNTER_LIMIT__MASK                0x00600000
+#define    DAC_CNTL__DAC_LUT_COUNTER_LIMIT__SHIFT               21
+#define    DAC_CNTL__DAC_LUT_READ_SEL                           0x00800000
+#define    DAC_CNTL__DAC__MASK                                  0xFF000000
+#define    DAC_CNTL__DAC__SHIFT                                 24
+#define    DAC_CNTL__DAC_CRC_BLANKb_ONLY                        0x00000800
+#define DAC_CNTL2                                           0x0000007C
+#define    DAC_CNTL2__DAC_CLK_SEL                               0x00000001
+#define    DAC_CNTL2__DAC2_CLK_SEL                              0x00000002
+#define    DAC_CNTL2__PALETTE_ACCESS_CNTL                       0x00000020
+#define    DAC_CNTL2__DAC2_CMP_EN                               0x00000080
+#define    DAC_CNTL2__DAC2_CMP_OUT_R                            0x00000100
+#define    DAC_CNTL2__DAC2_CMP_OUT_G                            0x00000200
+#define    DAC_CNTL2__DAC2_CMP_OUT_B                            0x00000400
+#define    DAC_CNTL2__DAC2_CMP_OUTPUT                           0x00000800
+#define    DAC_CNTL2__DAC2_EXPAND_MODE                          0x00004000
+#define    DAC_CNTL2__CRT2_SENSE                                0x00010000
+#define    DAC_CNTL2__CRT2_DETECTION_ON                         0x00020000
+#define    DAC_CNTL2__DAC_CRC2_CONT_EN                          0x00040000
+#define    DAC_CNTL2__DAC_CRC2_EN                               0x00080000
+#define    DAC_CNTL2__DAC_CRC2_FIELD                            0x00100000
+#define    DAC_CNTL2__DAC2_LUT_COUNTER_LIMIT__MASK              0x00600000
+#define    DAC_CNTL2__DAC2_LUT_COUNTER_LIMIT__SHIFT             21
+#define    DAC_CNTL2__PALETTE_AUTOFILL_PRIMARY_W                0x00000800
+#define    DAC_CNTL2__PALETTE_AUTOFILL_PRIMARY_R                0x00000800
+#define    DAC_CNTL2__PALETTE_AUTOFILL_SECONDARY_W              0x00001000
+#define    DAC_CNTL2__PALETTE_AUTOFILL_SECONDARY_R              0x00001000
+#define    DAC_CNTL2__DAC2_CMP_EN_R3                            0x00000040
+#define    DAC_CNTL2__DAC2_CMP_OUT_R_R3                         0x00000080
+#define    DAC_CNTL2__DAC2_CMP_OUT_G_R3                         0x00000100
+#define    DAC_CNTL2__DAC2_CMP_OUT_B_R3                         0x00000200
+#define    DAC_CNTL2__DAC2_CMP_OUTPUT_R3                        0x00000400
+#define    DAC_CNTL2__DAC_CRC2_BLANKb_ONLY                      0x00020000
+#define DAC_EXT_CNTL                                        0x00000280
+#define    DAC_EXT_CNTL__DAC2_FORCE_BLANK_OFF_EN                0x00000001
+#define    DAC_EXT_CNTL__DAC2_FORCE_DATA_EN                     0x00000002
+#define    DAC_EXT_CNTL__DAC_FORCE_BLANK_OFF_EN                 0x00000010
+#define    DAC_EXT_CNTL__DAC_FORCE_DATA_EN                      0x00000020
+#define    DAC_EXT_CNTL__DAC_FORCE_DATA_SEL__MASK               0x000000C0
+#define    DAC_EXT_CNTL__DAC_FORCE_DATA_SEL__SHIFT              6
+#define    DAC_EXT_CNTL__DAC_FORCE_DATA__MASK                   0x0003FF00
+#define    DAC_EXT_CNTL__DAC_FORCE_DATA__SHIFT                  8
+#define DISP_MISC_CNTL                                      0x00000D00
+#define    DISP_MISC_CNTL__SOFT_RESET_GRPH_PP                   0x00000001
+#define    DISP_MISC_CNTL__SOFT_RESET_SUBPIC_PP                 0x00000002
+#define    DISP_MISC_CNTL__SOFT_RESET_OV0_PP                    0x00000004
+#define    DISP_MISC_CNTL__SOFT_RESET_GRPH_SCLK                 0x00000010
+#define    DISP_MISC_CNTL__SOFT_RESET_SUBPIC_SCLK               0x00000020
+#define    DISP_MISC_CNTL__SOFT_RESET_OV0_SCLK                  0x00000040
+#define    DISP_MISC_CNTL__SYNC_STRENGTH__MASK                  0x00000300
+#define    DISP_MISC_CNTL__SYNC_STRENGTH__SHIFT                 8
+#define    DISP_MISC_CNTL__SYNC_PAD_FLOP_EN                     0x00000400
+#define    DISP_MISC_CNTL__SOFT_RESET_GRPH2_PP                  0x00001000
+#define    DISP_MISC_CNTL__SOFT_RESET_GRPH2_SCLK                0x00008000
+#define    DISP_MISC_CNTL__SOFT_RESET_LVDS                      0x00010000
+#define    DISP_MISC_CNTL__SOFT_RESET_TMDS                      0x00020000
+#define    DISP_MISC_CNTL__SOFT_RESET_DIG_TMDS                  0x00040000
+#define    DISP_MISC_CNTL__SOFT_RESET_TV                        0x00080000
+#define    DISP_MISC_CNTL__PALETTE2_MEM_RD_MARGIN__MASK         0x00F00000
+#define    DISP_MISC_CNTL__PALETTE2_MEM_RD_MARGIN__SHIFT        20
+#define    DISP_MISC_CNTL__PALETTE_MEM_RD_MARGIN__MASK          0x0F000000
+#define    DISP_MISC_CNTL__PALETTE_MEM_RD_MARGIN__SHIFT         24
+#define    DISP_MISC_CNTL__RMX_BUF_MEM_RD_MARGIN__MASK          0xF0000000
+#define    DISP_MISC_CNTL__RMX_BUF_MEM_RD_MARGIN__SHIFT         28
+#define    DISP_MISC_CNTL__SOFT_RESET_DVO                       0x00040000
+#define    DISP_MISC_CNTL__SOFT_RESET_TV_R2                     0x00000800
+#define DAC_MACRO_CNTL                                      0x00000D04
+#define    DAC_MACRO_CNTL__DAC_WHITE_CNTL__MASK                 0x0000000F
+#define    DAC_MACRO_CNTL__DAC_WHITE_CNTL__SHIFT                0
+#define    DAC_MACRO_CNTL__DAC_BG_ADJ__MASK                     0x00000F00
+#define    DAC_MACRO_CNTL__DAC_BG_ADJ__SHIFT                    8
+#define    DAC_MACRO_CNTL__DAC_PDWN_R                           0x00010000
+#define    DAC_MACRO_CNTL__DAC_PDWN_G                           0x00020000
+#define    DAC_MACRO_CNTL__DAC_PDWN_B                           0x00040000
+#define DISP_PWR_MAN                                        0x00000D08
+#define    DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN                0x00000001
+#define    DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN              0x00000010
+#define    DISP_PWR_MAN__DISP_PWR_MAN_DPMS__MASK                0x00000300
+#define    DISP_PWR_MAN__DISP_PWR_MAN_DPMS__SHIFT               8
+#define    DISP_PWR_MAN_DPMS__ON                                    0x0
+#define    DISP_PWR_MAN_DPMS__STANDBY                               0x1
+#define    DISP_PWR_MAN_DPMS__SUSPEND                               0x2
+#define    DISP_PWR_MAN_DPMS__OFF                                   0x3
+#define    DISP_PWR_MAN__DISP_D3_RST                            0x00010000
+#define    DISP_PWR_MAN__DISP_D3_REG_RST                        0x00020000
+#define    DISP_PWR_MAN__DISP_D3_GRPH_RST                       0x00040000
+#define    DISP_PWR_MAN__DISP_D3_SUBPIC_RST                     0x00080000
+#define    DISP_PWR_MAN__DISP_D3_OV0_RST                        0x00100000
+#define    DISP_PWR_MAN__DISP_D1D2_GRPH_RST                     0x00200000
+#define    DISP_PWR_MAN__DISP_D1D2_SUBPIC_RST                   0x00400000
+#define    DISP_PWR_MAN__DISP_D1D2_OV0_RST                      0x00800000
+#define    DISP_PWR_MAN__DIG_TMDS_ENABLE_RST                    0x01000000
+#define    DISP_PWR_MAN__TV_ENABLE_RST                          0x02000000
+#define    DISP_PWR_MAN__AUTO_PWRUP_EN                          0x04000000
+#define    DISP_PWR_MAN__DISP_DVO_ENABLE_RST                    0x01000000
+#define DISP_MERGE_CNTL                                     0x00000D60
+#define    DISP_MERGE_CNTL__DISP_ALPHA_MODE__MASK               0x00000003
+#define    DISP_MERGE_CNTL__DISP_ALPHA_MODE__SHIFT              0
+#define    DISP_MERGE_CNTL__DISP_ALPHA_INV                      0x00000004
+#define    DISP_MERGE_CNTL__DISP_ALPHA_PREMULT                  0x00000008
+#define    DISP_MERGE_CNTL__DISP_RGB_OFFSET_EN                  0x00000100
+#define    DISP_MERGE_CNTL__DISP_LIN_TRANS_BYPASS               0x00000200
+#define    DISP_MERGE_CNTL__DISP_GRPH_ALPHA__MASK               0x00FF0000
+#define    DISP_MERGE_CNTL__DISP_GRPH_ALPHA__SHIFT              16
+#define    DISP_MERGE_CNTL__DISP_OV0_ALPHA__MASK                0xFF000000
+#define    DISP_MERGE_CNTL__DISP_OV0_ALPHA__SHIFT               24
+#define DISP_OUTPUT_CNTL                                    0x00000D64
+#define    DISP_OUTPUT_CNTL__DISP_DAC_SOURCE__MASK              0x00000003
+#define    DISP_OUTPUT_CNTL__DISP_DAC_SOURCE__SHIFT             0
+#define    DISP_DAC_SOURCE__YPbPr                                   0x3
+#define    DISP_DAC_SOURCE__PRIMARYCRTC                             0x0
+#define    DISP_DAC_SOURCE__SECONDARYCRTC                           0x1
+#define    DISP_DAC_SOURCE__RMX                                     0x2
+#define    DISP_OUTPUT_CNTL__DISP_TRANS_MATRIX_SEL__MASK        0x00000030
+#define    DISP_OUTPUT_CNTL__DISP_TRANS_MATRIX_SEL__SHIFT       4
+#define    DISP_OUTPUT_CNTL__DISP_RMX_SOURCE                    0x00000100
+#define    DISP_OUTPUT_CNTL__DISP_RMX_HTAP_SEL                  0x00000200
+#define    DISP_OUTPUT_CNTL__DISP_RMX_DITH_EN                   0x00000400
+#define    DISP_OUTPUT_CNTL__DISP_TV_SOURCE                     0x00010000
+#define    DISP_OUTPUT_CNTL__DISP_TV_MODE__MASK                 0x00060000
+#define    DISP_OUTPUT_CNTL__DISP_TV_MODE__SHIFT                17
+#define    DISP_OUTPUT_CNTL__DISP_TV_YG_DITH_EN                 0x00080000
+#define    DISP_OUTPUT_CNTL__DISP_TV_CbB_CrR_DITH_EN            0x00100000
+#define    DISP_OUTPUT_CNTL__DISP_TV_BIT_WIDTH                  0x00200000
+#define    DISP_OUTPUT_CNTL__DISP_TV_SYNC_MODE__MASK            0x00C00000
+#define    DISP_OUTPUT_CNTL__DISP_TV_SYNC_MODE__SHIFT           22
+#define    DISP_OUTPUT_CNTL__DISP_TV_SYNC_FORCE                 0x01000000
+#define    DISP_OUTPUT_CNTL__DISP_TV_SYNC_COLOR__MASK           0x06000000
+#define    DISP_OUTPUT_CNTL__DISP_TV_SYNC_COLOR__SHIFT          25
+#define    DISP_OUTPUT_CNTL__DISP_TV_EVEN_FLAG_CNTL__MASK       0x18000000
+#define    DISP_OUTPUT_CNTL__DISP_TV_EVEN_FLAG_CNTL__SHIFT      27
+#define    DISP_OUTPUT_CNTL__DISP_TV_SYNC_STATUS                0x20000000
+#define    DISP_OUTPUT_CNTL__DISP_TV_H_DOWNSCALE                0x40000000
+#define    DISP_OUTPUT_CNTL__DISP_TRANS_SOURCE__MASK            0x00003000
+#define    DISP_OUTPUT_CNTL__DISP_TRANS_SOURCE__SHIFT           12
+#define    DISP_TRANS_SOURCE__PRIMARYCRTC                           0x0
+#define    DISP_TRANS_SOURCE__SECONDARYCRTC                         0x1
+#define    DISP_TRANS_SOURCE__RMX                                   0x2
+#define    DISP_OUTPUT_CNTL__DISP_TVDAC_SOURCE__MASK            0x0000000C
+#define    DISP_OUTPUT_CNTL__DISP_TVDAC_SOURCE__SHIFT           2
+#define    DISP_TVDAC_SOURCE__PRIMARYCRTC                           0x0
+#define    DISP_TVDAC_SOURCE__SECONDARYCRTC                         0x1
+#define    DISP_TVDAC_SOURCE__RMX                                   0x2
+#define    DISP_TVDAC_SOURCE__YPbPr                                 0x3
+#define DISP2_MERGE_CNTL                                    0x00000D68
+#define    DISP2_MERGE_CNTL__DISP2_RGB_OFFSET_EN                0x00000100
+#define DAC_EMBEDDED_SYNC_CNTL                              0x00000DC0
+#define    DAC_EMBEDDED_SYNC_CNTL__DAC_EMBED_SYNC_EN_Y_G        0x00000001
+#define    DAC_EMBEDDED_SYNC_CNTL__DAC_EMBED_SYNC_EN_Cb_B       0x00000002
+#define    DAC_EMBEDDED_SYNC_CNTL__DAC_EMBED_SYNC_EN_Cr_R       0x00000004
+#define    DAC_EMBEDDED_SYNC_CNTL__DAC_TRILEVEL_SYNC_EN         0x00000008
+#define    DAC_EMBEDDED_SYNC_CNTL__DAC_EMBED_VSYNC_EN_Y_G       0x00000010
+#define    DAC_EMBEDDED_SYNC_CNTL__DAC_EMBED_VSYNC_EN_CbCr_BR   0x00000020
+#define    DAC_EMBEDDED_SYNC_CNTL__DAC_HSYNC_WID_LSB__MASK      0x00070000
+#define    DAC_EMBEDDED_SYNC_CNTL__DAC_HSYNC_WID_LSB__SHIFT     16
+#define DAC_BROAD_PULSE                                     0x00000DC4
+#define    DAC_BROAD_PULSE__DAC_BROAD_PULSE_START__MASK         0x00001FFF
+#define    DAC_BROAD_PULSE__DAC_BROAD_PULSE_START__SHIFT        0
+#define    DAC_BROAD_PULSE__DAC_BROAD_PULSE_END__MASK           0x1FFF0000
+#define    DAC_BROAD_PULSE__DAC_BROAD_PULSE_END__SHIFT          16
+#define    DAC_BROAD_PULSE__DAC_BROAD_PULSE_START_R2__MASK      0x00000FFF
+#define    DAC_BROAD_PULSE__DAC_BROAD_PULSE_START_R2__SHIFT     0
+#define    DAC_BROAD_PULSE__DAC_BROAD_PULSE_END_R2__MASK        0x0FFF0000
+#define    DAC_BROAD_PULSE__DAC_BROAD_PULSE_END_R2__SHIFT       16
+#define DAC_SKEW_CLKS                                       0x00000DC8
+#define    DAC_SKEW_CLKS__DAC_SKEW_CLKS__MASK                   0x000000FF
+#define    DAC_SKEW_CLKS__DAC_SKEW_CLKS__SHIFT                  0
+#define DAC_INCR                                            0x00000DCC
+#define    DAC_INCR__DAC_INCR_Y_G__MASK                         0x000003FF
+#define    DAC_INCR__DAC_INCR_Y_G__SHIFT                        0
+#define    DAC_INCR__DAC_INCR_CrCb_RB__MASK                     0x03FF0000
+#define    DAC_INCR__DAC_INCR_CrCb_RB__SHIFT                    16
+#define DAC_NEG_SYNC_LEVEL                                  0x00000DD0
+#define    DAC_NEG_SYNC_LEVEL__DAC_NEG_SYNC_LEVEL_Y_G__MASK     0x000003FF
+#define    DAC_NEG_SYNC_LEVEL__DAC_NEG_SYNC_LEVEL_Y_G__SHIFT    0
+#define    DAC_NEG_SYNC_LEVEL__DAC_NEG_SYNC_LEVEL_CrCb_RB__MASK 0x03FF0000
+#define    DAC_NEG_SYNC_LEVEL__DAC_NEG_SYNC_LEVEL_CrCb_RB__SHIFT 16
+#define DAC_POS_SYNC_LEVEL                                  0x00000DD4
+#define    DAC_POS_SYNC_LEVEL__DAC_POS_SYNC_LEVEL_Y_G__MASK     0x000003FF
+#define    DAC_POS_SYNC_LEVEL__DAC_POS_SYNC_LEVEL_Y_G__SHIFT    0
+#define    DAC_POS_SYNC_LEVEL__DAC_POS_SYNC_LEVEL_CrCb_RB__MASK 0x03FF0000
+#define    DAC_POS_SYNC_LEVEL__DAC_POS_SYNC_LEVEL_CrCb_RB__SHIFT 16
+#define DAC_BLANK_LEVEL                                     0x00000DD8
+#define    DAC_BLANK_LEVEL__DAC_BLANK_LEVEL_Y_G__MASK           0x000003FF
+#define    DAC_BLANK_LEVEL__DAC_BLANK_LEVEL_Y_G__SHIFT          0
+#define    DAC_BLANK_LEVEL__DAC_BLANK_LEVEL_CrCb_RB__MASK       0x03FF0000
+#define    DAC_BLANK_LEVEL__DAC_BLANK_LEVEL_CrCb_RB__SHIFT      16
+#define DAC_SYNC_EQUALIZATION                               0x00000DDC
+#define    DAC_SYNC_EQUALIZATION__DAC_SYNC_EQ_START__MASK       0x000007FF
+#define    DAC_SYNC_EQUALIZATION__DAC_SYNC_EQ_START__SHIFT      0
+#define    DAC_SYNC_EQUALIZATION__DAC_SYNC_EQ_END__MASK         0x07FF0000
+#define    DAC_SYNC_EQUALIZATION__DAC_SYNC_EQ_END__SHIFT        16
+#define TV_MASTER_CNTL                                      0x00000800
+#define    TV_MASTER_CNTL__TV_ASYNC_RST                         0x00000001
+#define    TV_MASTER_CNTL__CRT_ASYNC_RST                        0x00000002
+#define    TV_MASTER_CNTL__RESTART_PHASE_FIX                    0x00000008
+#define    TV_MASTER_CNTL__TV_FIFO_ASYNC_RST                    0x00000010
+#define    TV_MASTER_CNTL__MV_BP_LEVEL_FIX_EN                   0x00000020
+#define    TV_MASTER_CNTL__EXTRA_BIT_ONE_0                      0x00000040
+#define    TV_MASTER_CNTL__CRT_FIFO_CE_EN                       0x00000200
+#define    TV_MASTER_CNTL__TV_FIFO_CE_EN                        0x00000400
+#define    TV_MASTER_CNTL__RE_SYNC_NOW_SEL__MASK                0x0000C000
+#define    TV_MASTER_CNTL__RE_SYNC_NOW_SEL__SHIFT               14
+#define    TV_MASTER_CNTL__EXTRA_BIT_ZERO_1                     0x00010000
+#define    TV_MASTER_CNTL__EXTRA_BIT_ONE_1                      0x00020000
+#define    TV_MASTER_CNTL__EXTRA_BIT_ZERO_2                     0x00040000
+#define    TV_MASTER_CNTL__EXTRA_BIT_ONE_2                      0x00080000
+#define    TV_MASTER_CNTL__TVCLK_ALWAYS_ONb                     0x40000000
+#define    TV_MASTER_CNTL__TV_ON                                0x80000000
+#define TV_DAC_CNTL                                         0x0000088C
+#define    TV_DAC_CNTL__NBLANK                                  0x00000001
+#define    TV_DAC_CNTL__NHOLD                                   0x00000002
+#define    TV_DAC_CNTL__PEDESTAL                                0x00000004
+#define    TV_DAC_CNTL__DETECT                                  0x00000010
+#define    TV_DAC_CNTL__CMPOUT                                  0x00000020
+#define    TV_DAC_CNTL__BGSLEEP                                 0x00000040
+#define    TV_DAC_CNTL__STD__MASK                               0x00000300
+#define    TV_DAC_CNTL__STD__SHIFT                              8
+#define    STD__PAL                                                 0x0
+#define    STD__NTSC                                                0x1
+#define    STD__PS2                                                 0x2
+#define    STD__RS343                                               0x3
+#define    TV_DAC_CNTL__MON__MASK                               0x0000F000
+#define    TV_DAC_CNTL__MON__SHIFT                              12
+#define    TV_DAC_CNTL__BGADJ__MASK                             0x000F0000
+#define    TV_DAC_CNTL__BGADJ__SHIFT                            16
+#define    TV_DAC_CNTL__DACADJ__MASK                            0x00F00000
+#define    TV_DAC_CNTL__DACADJ__SHIFT                           20
+#define    TV_DAC_CNTL__RDACPD                                  0x01000000
+#define    TV_DAC_CNTL__GDACPD                                  0x02000000
+#define    TV_DAC_CNTL__BDACPD                                  0x04000000
+#define    TV_DAC_CNTL__RDACDET                                 0x20000000
+#define    TV_DAC_CNTL__GDACDET                                 0x40000000
+#define    TV_DAC_CNTL__BDACDET                                 0x80000000
+#define    TV_DAC_CNTL__DACADJ_R4__MASK                         0x01F00000
+#define    TV_DAC_CNTL__DACADJ_R4__SHIFT                        20
+#define    TV_DAC_CNTL__RDACPD_R4                               0x02000000
+#define    TV_DAC_CNTL__GDACPD_R4                               0x04000000
+#define    TV_DAC_CNTL__BDACPD_R4                               0x08000000
+#define    TV_DAC_CNTL__TVENABLE_R4                             0x10000000
+#define VIPPAD_EN                                           0x000001A0
+#define    VIPPAD_EN__VIPPAD_EN__MASK                           0x0007FFFF
+#define    VIPPAD_EN__VIPPAD_EN__SHIFT                          0
+#define    VIPPAD_EN__VIPPAD_EN_TVODATA__MASK                   0x000003FF
+#define    VIPPAD_EN__VIPPAD_EN_TVODATA__SHIFT                  0
+#define    VIPPAD_EN__VIPPAD_EN_TVOCLKO                         0x00000400
+#define    VIPPAD_EN__VIPPAD_EN_ROMCSb                          0x00000800
+#define    VIPPAD_EN__VIPPAD_EN_VHAD__MASK                      0x00003000
+#define    VIPPAD_EN__VIPPAD_EN_VHAD__SHIFT                     12
+#define    VIPPAD_EN__VIPPAD_EN_VPHCTL                          0x00010000
+#define    VIPPAD_EN__VIPPAD_EN_VIPCLK                          0x00020000
+#define    VIPPAD_EN__VIPPAD_EN_SI                              0x00080000
+#define    VIPPAD_EN__VIPPAD_EN_SO                              0x00100000
+#define    VIPPAD_EN__VIPPAD_EN_SCK                             0x00200000
+#define VIPPAD_Y                                            0x000001A4
+#define    VIPPAD_Y__VIPPAD_Y__MASK                             0x0007FFFF
+#define    VIPPAD_Y__VIPPAD_Y__SHIFT                            0
+#define    VIPPAD_Y__VIPPAD_Y_TVODATA__MASK                     0x000003FF
+#define    VIPPAD_Y__VIPPAD_Y_TVODATA__SHIFT                    0
+#define    VIPPAD_Y__VIPPAD_Y_TVOCLKO                           0x00000400
+#define    VIPPAD_Y__VIPPAD_Y_ROMCSb                            0x00000800
+#define    VIPPAD_Y__VIPPAD_Y_VHAD__MASK                        0x00003000
+#define    VIPPAD_Y__VIPPAD_Y_VHAD__SHIFT                       12
+#define    VIPPAD_Y__VIPPAD_Y_VPHCTL                            0x00010000
+#define    VIPPAD_Y__VIPPAD_Y_VIPCLK                            0x00020000
+#define    VIPPAD_Y__VIPPAD_Y_SI                                0x00080000
+#define    VIPPAD_Y__VIPPAD_Y_SO                                0x00100000
+#define    VIPPAD_Y__VIPPAD_Y_SCK                               0x00200000
+#define VIPPAD1_EN                                          0x000001B0
+#define    VIPPAD1_EN__VIPPAD1_EN__MASK                         0x0003FFFF
+#define    VIPPAD1_EN__VIPPAD1_EN__SHIFT                        0
+#define    VIPPAD1_EN__VIPPAD_EN_VID__MASK                      0x000000FF
+#define    VIPPAD1_EN__VIPPAD_EN_VID__SHIFT                     0
+#define    VIPPAD1_EN__VIPPAD_EN_VPCLK0                         0x00000100
+#define    VIPPAD1_EN__VIPPAD_EN_DVALID                         0x00000200
+#define    VIPPAD1_EN__VIPPAD_EN_PSYNC                          0x00000400
+#define    VIPPAD1_EN__VIPPAD_EN_DVODATA__MASK                  0x0FFF0000
+#define    VIPPAD1_EN__VIPPAD_EN_DVODATA__SHIFT                 16
+#define    VIPPAD1_EN__VIPPAD_EN_DVOCNTL__MASK                  0x70000000
+#define    VIPPAD1_EN__VIPPAD_EN_DVOCNTL__SHIFT                 28
+#define VIPPAD1_Y                                           0x000001B4
+#define    VIPPAD1_Y__VIPPAD1_Y__MASK                           0x0003FFFF
+#define    VIPPAD1_Y__VIPPAD1_Y__SHIFT                          0
+#define    VIPPAD1_Y__VIPPAD_Y_VID__MASK                        0x000000FF
+#define    VIPPAD1_Y__VIPPAD_Y_VID__SHIFT                       0
+#define    VIPPAD1_Y__VIPPAD_Y_VPCLK0                           0x00000100
+#define    VIPPAD1_Y__VIPPAD_Y_DVALID                           0x00000200
+#define    VIPPAD1_Y__VIPPAD_Y_PSYNC                            0x00000400
+#define    VIPPAD1_Y__VIPPAD_Y_DVODATA__MASK                    0x0FFF0000
+#define    VIPPAD1_Y__VIPPAD_Y_DVODATA__SHIFT                   16
+#define    VIPPAD1_Y__VIPPAD_Y_DVOCNTL__MASK                    0x70000000
+#define    VIPPAD1_Y__VIPPAD_Y_DVOCNTL__SHIFT                   28
+#define GPIO_DDC1                                           0x00000060
+#define    GPIO_DDC1__DDC1_DATA_OUTPUT                          0x00000001
+#define    GPIO_DDC1__DDC1_CLK_OUTPUT                           0x00000002
+#define    GPIO_DDC1__DDC1_DATA_INPUT                           0x00000100
+#define    GPIO_DDC1__DDC1_CLK_INPUT                            0x00000200
+#define    GPIO_DDC1__DDC1_DATA_OUT_EN                          0x00010000
+#define    GPIO_DDC1__DDC1_CLK_OUT_EN                           0x00020000
+#define    GPIO_DDC1__SW_WANTS_TO_USE_DVI_I2C                   0x00100000
+#define    GPIO_DDC1__SW_CAN_USE_DVI_I2C                        0x00100000
+#define    GPIO_DDC1__SW_DONE_USING_DVI_I2C                     0x00200000
+#define    GPIO_DDC1__HW_USING_DVI_I2C                          0x00400000
+#define GPIO_DDC2                                           0x00000064
+#define    GPIO_DDC2__DDC2_DATA_OUTPUT                          0x00000001
+#define    GPIO_DDC2__DDC2_CLK_OUTPUT                           0x00000002
+#define    GPIO_DDC2__DDC2_DATA_INPUT                           0x00000100
+#define    GPIO_DDC2__DDC2_CLK_INPUT                            0x00000200
+#define    GPIO_DDC2__DDC2_DATA_OUT_EN                          0x00010000
+#define    GPIO_DDC2__DDC2_CLK_OUT_EN                           0x00020000
+#define    GPIO_DDC2__SW_WANTS_TO_USE_DVI_I2C                   0x00100000
+#define    GPIO_DDC2__SW_CAN_USE_DVI_I2C                        0x00100000
+#define    GPIO_DDC2__SW_DONE_USING_DVI_I2C                     0x00200000
+#define    GPIO_DDC2__HW_USING_DVI_I2C                          0x00400000
+#define CLOCK_CNTL_INDEX                                    0x00000008
+#define    CLOCK_CNTL_INDEX__PLL_ADDR__MASK                     0x0000001F
+#define    CLOCK_CNTL_INDEX__PLL_ADDR__SHIFT                    0
+#define    CLOCK_CNTL_INDEX__PLL_WR_EN                          0x00000080
+#define    CLOCK_CNTL_INDEX__PPLL_DIV_SEL__MASK                 0x00000300
+#define    CLOCK_CNTL_INDEX__PPLL_DIV_SEL__SHIFT                8
+#define    CLOCK_CNTL_INDEX__PLL_ADDR_R2__MASK                  0x0000003F
+#define    CLOCK_CNTL_INDEX__PLL_ADDR_R2__SHIFT                 0
+#define CLOCK_CNTL_DATA                                     0x0000000C
+#define    CLOCK_CNTL_DATA__PLL_DATA__MASK                      0xFFFFFFFF
+#define    CLOCK_CNTL_DATA__PLL_DATA__SHIFT                     0
+#define MCLK_CNTL                                           0x00000012
+#define    MCLK_CNTL__MCLKA_SRC_SEL__MASK                       0x00000007
+#define    MCLK_CNTL__MCLKA_SRC_SEL__SHIFT                      0
+#define    MCLK_CNTL__YCLKA_SRC_SEL__MASK                       0x00000070
+#define    MCLK_CNTL__YCLKA_SRC_SEL__SHIFT                      4
+#define    MCLK_CNTL__MCLKB_SRC_SEL__MASK                       0x00000700
+#define    MCLK_CNTL__MCLKB_SRC_SEL__SHIFT                      8
+#define    MCLK_CNTL__YCLKB_SRC_SEL__MASK                       0x00007000
+#define    MCLK_CNTL__YCLKB_SRC_SEL__SHIFT                      12
+#define    MCLK_CNTL__FORCE_MCLKA                               0x00010000
+#define    MCLK_CNTL__FORCE_MCLKB                               0x00020000
+#define    MCLK_CNTL__FORCE_YCLKA                               0x00040000
+#define    MCLK_CNTL__FORCE_YCLKB                               0x00080000
+#define    MCLK_CNTL__FORCE_MC                                  0x00100000
+#define    MCLK_CNTL__FORCE_AIC                                 0x00200000
+#define    MCLK_CNTL__MRDCKA0_SOUTSEL__MASK                     0x03000000
+#define    MCLK_CNTL__MRDCKA0_SOUTSEL__SHIFT                    24
+#define    MCLK_CNTL__MRDCKA1_SOUTSEL__MASK                     0x0C000000
+#define    MCLK_CNTL__MRDCKA1_SOUTSEL__SHIFT                    26
+#define    MCLK_CNTL__MRDCKB0_SOUTSEL__MASK                     0x30000000
+#define    MCLK_CNTL__MRDCKB0_SOUTSEL__SHIFT                    28
+#define    MCLK_CNTL__MRDCKB1_SOUTSEL__MASK                     0xC0000000
+#define    MCLK_CNTL__MRDCKB1_SOUTSEL__SHIFT                    30
+#define    MCLK_CNTL__FORCE_MC_MCLKA                            0x00010000
+#define    MCLK_CNTL__FORCE_MC_MCLKB                            0x00020000
+#define    MCLK_CNTL__FORCE_MC_MCLK                             0x00100000
+#define    MCLK_CNTL__DISABLE_MC_MCLKA                          0x00200000
+#define    MCLK_CNTL__DISABLE_MC_MCLKB                          0x00400000
+#define SCLK_CNTL                                           0x0000000D
+#define    SCLK_CNTL__SCLK_SRC_SEL__MASK                        0x00000007
+#define    SCLK_CNTL__SCLK_SRC_SEL__SHIFT                       0
+#define    SCLK_CNTL__TCLK_SRC_SEL__MASK                        0x00000700
+#define    SCLK_CNTL__TCLK_SRC_SEL__SHIFT                       8
+#define    SCLK_CNTL__FORCE_CP                                  0x00010000
+#define    SCLK_CNTL__FORCE_HDP                                 0x00020000
+#define    SCLK_CNTL__FORCE_DISP                                0x00040000
+#define    SCLK_CNTL__FORCE_TOP                                 0x00080000
+#define    SCLK_CNTL__FORCE_E2                                  0x00100000
+#define    SCLK_CNTL__FORCE_SE                                  0x00200000
+#define    SCLK_CNTL__FORCE_IDCT                                0x00400000
+#define    SCLK_CNTL__FORCE_VIP                                 0x00800000
+#define    SCLK_CNTL__FORCE_RE                                  0x01000000
+#define    SCLK_CNTL__FORCE_PB                                  0x02000000
+#define    SCLK_CNTL__FORCE_TAM                                 0x04000000
+#define    SCLK_CNTL__FORCE_TDM                                 0x08000000
+#define    SCLK_CNTL__FORCE_RB                                  0x10000000
+#define    SCLK_CNTL__CP_MAX_DYN_STOP_LAT                       0x00000008
+#define    SCLK_CNTL__HDP_MAX_DYN_STOP_LAT                      0x00000010
+#define    SCLK_CNTL__E2_MAX_DYN_STOP_LAT                       0x00000040
+#define    SCLK_CNTL__SE_MAX_DYN_STOP_LAT                       0x00000080
+#define    SCLK_CNTL__IDCT_MAX_DYN_STOP_LAT                     0x00000100
+#define    SCLK_CNTL__VIP_MAX_DYN_STOP_LAT                      0x00000200
+#define    SCLK_CNTL__RE_MAX_DYN_STOP_LAT                       0x00000400
+#define    SCLK_CNTL__PB_MAX_DYN_STOP_LAT                       0x00000800
+#define    SCLK_CNTL__TAM_MAX_DYN_STOP_LAT                      0x00001000
+#define    SCLK_CNTL__TDM_MAX_DYN_STOP_LAT                      0x00002000
+#define    SCLK_CNTL__RB_MAX_DYN_STOP_LAT                       0x00004000
+#define    SCLK_CNTL__FORCE_DISP2                               0x00008000
+#define    SCLK_CNTL__FORCE_DISP1                               0x00040000
+#define    SCLK_CNTL__FORCE_SUBPIC                              0x40000000
+#define    SCLK_CNTL__FORCE_OV0                                 0x80000000
+#define    SCLK_CNTL__TV_MAX_DYN_STOP_LAT                       0x00000020
+#define    SCLK_CNTL__FORCE_TV_SCLK                             0x20000000
+#define    SCLK_CNTL__VAP_MAX_DYN_STOP_LAT                      0x00000080
+#define    SCLK_CNTL__SR_MAX_DYN_STOP_LAT                       0x00000400
+#define    SCLK_CNTL__PX_MAX_DYN_STOP_LAT                       0x00000800
+#define    SCLK_CNTL__TX_MAX_DYN_STOP_LAT                       0x00001000
+#define    SCLK_CNTL__US_MAX_DYN_STOP_LAT                       0x00002000
+#define    SCLK_CNTL__SU_MAX_DYN_STOP_LAT                       0x00004000
+#define    SCLK_CNTL__FORCE_VAP                                 0x00200000
+#define    SCLK_CNTL__FORCE_SR                                  0x02000000
+#define    SCLK_CNTL__FORCE_PX                                  0x04000000
+#define    SCLK_CNTL__FORCE_TX                                  0x08000000
+#define    SCLK_CNTL__FORCE_US                                  0x10000000
+#define    SCLK_CNTL__FORCE_SU                                  0x40000000
+#define PPLL_CNTL                                           0x00000002
+#define    PPLL_CNTL__PPLL_RESET                                0x00000001
+#define    PPLL_CNTL__PPLL_SLEEP                                0x00000002
+#define    PPLL_CNTL__PPLL_TST_EN                               0x00000004
+#define    PPLL_CNTL__PPLL_REFCLK_SEL                           0x00000010
+#define    PPLL_CNTL__PPLL_FBCLK_SEL                            0x00000020
+#define    PPLL_CNTL__PPLL_TCPOFF                               0x00000040
+#define    PPLL_CNTL__PPLL_TVCOMAX                              0x00000080
+#define    PPLL_CNTL__PPLL_PCP__MASK                            0x00000700
+#define    PPLL_CNTL__PPLL_PCP__SHIFT                           8
+#define    PPLL_CNTL__PPLL_PVG__MASK                            0x00003800
+#define    PPLL_CNTL__PPLL_PVG__SHIFT                           11
+#define    PPLL_CNTL__PPLL_PDC__MASK                            0x0000C000
+#define    PPLL_CNTL__PPLL_PDC__SHIFT                           14
+#define    PPLL_CNTL__PPLL_ATOMIC_UPDATE_EN                     0x00010000
+#define    PPLL_CNTL__PPLL_VGA_ATOMIC_UPDATE_EN                 0x00020000
+#define    PPLL_CNTL__PPLL_ATOMIC_UPDATE_SYNC                   0x00040000
+#define    PPLL_CNTL__PPLL_DISABLE_AUTO_RESET                   0x00080000
+#define    PPLL_CNTL__PPLL_DIV_RESET                            0x00000008
+#define PPLL_REF_DIV                                        0x00000003
+#define    PPLL_REF_DIV__PPLL_REF_DIV__MASK                     0x000003FF
+#define    PPLL_REF_DIV__PPLL_REF_DIV__SHIFT                    0
+#define    PPLL_REF_DIV__PPLL_ATOMIC_UPDATE_W                   0x00008000
+#define    PPLL_REF_DIV__PPLL_ATOMIC_UPDATE_R                   0x00008000
+#define    PPLL_REF_DIV__PPLL_REF_DIV_SRC__MASK                 0x00030000
+#define    PPLL_REF_DIV__PPLL_REF_DIV_SRC__SHIFT                16
+#define    PPLL_REF_DIV_SRC__XTALIN                                 0x0
+#define    PPLL_REF_DIV_SRC__PLLSCLK_2                              0x1
+#define    PPLL_REF_DIV_SRC__PLLSCLK_4                              0x2
+#define    PPLL_REF_DIV_SRC__SREFCLK                                0x3
+#define    PPLL_REF_DIV__PPLL_REF_DIV_ACC__MASK                 0x0FFC0000
+#define    PPLL_REF_DIV__PPLL_REF_DIV_ACC__SHIFT                18
+#define PPLL_DIV_0                                          0x00000004
+#define    PPLL_DIV_0__PPLL_FB0_DIV__MASK                       0x000007FF
+#define    PPLL_DIV_0__PPLL_FB0_DIV__SHIFT                      0
+#define    PPLL_DIV_0__PPLL_ATOMIC_UPDATE_W                     0x00008000
+#define    PPLL_DIV_0__PPLL_ATOMIC_UPDATE_R                     0x00008000
+#define    PPLL_DIV_0__PPLL_POST0_DIV__MASK                     0x00070000
+#define    PPLL_DIV_0__PPLL_POST0_DIV__SHIFT                    16
+#define    PPLL_DIV_0__PPLL_FB_DIV_FRACTION__MASK               0x00380000
+#define    PPLL_DIV_0__PPLL_FB_DIV_FRACTION__SHIFT              19
+#define    PPLL_DIV_0__PPLL_FB_DIV_FRACTION_UPDATE              0x00400000
+#define    PPLL_DIV_0__PPLL_FB_DIV_FRACTION_EN                  0x00800000
+#define PPLL_DIV_1                                          0x00000005
+#define    PPLL_DIV_1__PPLL_FB1_DIV__MASK                       0x000007FF
+#define    PPLL_DIV_1__PPLL_FB1_DIV__SHIFT                      0
+#define    PPLL_DIV_1__PPLL_ATOMIC_UPDATE_W                     0x00008000
+#define    PPLL_DIV_1__PPLL_ATOMIC_UPDATE_R                     0x00008000
+#define    PPLL_DIV_1__PPLL_POST1_DIV__MASK                     0x00070000
+#define    PPLL_DIV_1__PPLL_POST1_DIV__SHIFT                    16
+#define PPLL_DIV_2                                          0x00000006
+#define    PPLL_DIV_2__PPLL_FB2_DIV__MASK                       0x000007FF
+#define    PPLL_DIV_2__PPLL_FB2_DIV__SHIFT                      0
+#define    PPLL_DIV_2__PPLL_ATOMIC_UPDATE_W                     0x00008000
+#define    PPLL_DIV_2__PPLL_ATOMIC_UPDATE_R                     0x00008000
+#define    PPLL_DIV_2__PPLL_POST2_DIV__MASK                     0x00070000
+#define    PPLL_DIV_2__PPLL_POST2_DIV__SHIFT                    16
+#define PPLL_DIV_3                                          0x00000007
+#define    PPLL_DIV_3__PPLL_FB3_DIV__MASK                       0x000007FF
+#define    PPLL_DIV_3__PPLL_FB3_DIV__SHIFT                      0
+#define    PPLL_DIV_3__PPLL_ATOMIC_UPDATE_W                     0x00008000
+#define    PPLL_DIV_3__PPLL_ATOMIC_UPDATE_R                     0x00008000
+#define    PPLL_DIV_3__PPLL_POST3_DIV__MASK                     0x00070000
+#define    PPLL_DIV_3__PPLL_POST3_DIV__SHIFT                    16
+#define VCLK_ECP_CNTL                                       0x00000008
+#define    VCLK_ECP_CNTL__VCLK_SRC_SEL__MASK                    0x00000003
+#define    VCLK_ECP_CNTL__VCLK_SRC_SEL__SHIFT                   0
+#define    VCLK_SRC_SEL__CPUCLK                                     0x0
+#define    VCLK_SRC_SEL__PSCANCLK                                   0x1
+#define    VCLK_SRC_SEL__BYTE_CLK                                   0x2
+#define    VCLK_SRC_SEL__PPLLCLK                                    0x3
+#define    VCLK_ECP_CNTL__VCLK_INVERT                           0x00000010
+#define    VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb                     0x00000040
+#define    VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb                 0x00000080
+#define    VCLK_ECP_CNTL__ECP_DIV__MASK                         0x00000300
+#define    VCLK_ECP_CNTL__ECP_DIV__SHIFT                        8
+#define    VCLK_ECP_CNTL__ECP_FORCE_ON                          0x00040000
+#define    VCLK_ECP_CNTL__SUBCLK_FORCE_ON                       0x00080000
+#define    VCLK_ECP_CNTL__BYTE_CLK_POST_DIV__MASK               0x00030000
+#define    VCLK_ECP_CNTL__BYTE_CLK_POST_DIV__SHIFT              16
+#define    VCLK_ECP_CNTL__BYTE_CLK_OUT_EN                       0x00100000
+#define    VCLK_ECP_CNTL__BYTE_CLK_SKEW__MASK                   0x07000000
+#define    VCLK_ECP_CNTL__BYTE_CLK_SKEW__SHIFT                  24
+#define    VCLK_ECP_CNTL__PCICLK_INVERT                         0x00000020
+#define    VCLK_ECP_CNTL__PIXCLK_SRC_INVERT                     0x00000020
+#define    VCLK_ECP_CNTL__PIXCLK_SRC_INVERT_R3                  0x08000000
+#define    VCLK_ECP_CNTL__DISP_DAC_PIXCLK_DAC_BLANK_OFF         0x00800000
+#define HTOTAL_CNTL                                         0x00000009
+#define    HTOTAL_CNTL__HTOT_PIX_SLIP__MASK                     0x0000000F
+#define    HTOTAL_CNTL__HTOT_PIX_SLIP__SHIFT                    0
+#define    HTOTAL_CNTL__HTOT_VCLK_SLIP__MASK                    0x00000F00
+#define    HTOTAL_CNTL__HTOT_VCLK_SLIP__SHIFT                   8
+#define    HTOTAL_CNTL__HTOT_PPLL_SLIP__MASK                    0x00070000
+#define    HTOTAL_CNTL__HTOT_PPLL_SLIP__SHIFT                   16
+#define    HTOTAL_CNTL__HTOT_CNTL_EDGE                          0x01000000
+#define    HTOTAL_CNTL__HTOT_CNTL_VGA_EN                        0x10000000
+#define FP_H_SYNC_STRT_WID                                  0x000002C4
+#define    FP_H_SYNC_STRT_WID__FP_H_SYNC_STRT_PIX__MASK         0x00000007
+#define    FP_H_SYNC_STRT_WID__FP_H_SYNC_STRT_PIX__SHIFT        0
+#define    FP_H_SYNC_STRT_WID__FP_H_SYNC_STRT_CHAR__MASK        0x00001FF8
+#define    FP_H_SYNC_STRT_WID__FP_H_SYNC_STRT_CHAR__SHIFT       3
+#define    FP_H_SYNC_STRT_WID__FP_H_SYNC_WID__MASK              0x003F0000
+#define    FP_H_SYNC_STRT_WID__FP_H_SYNC_WID__SHIFT             16
+#define    FP_H_SYNC_STRT_WID__FP_H_SYNC_POL                    0x00800000
+#define FP_V_SYNC_STRT_WID                                  0x000002C8
+#define    FP_V_SYNC_STRT_WID__FP_V_SYNC_STRT__MASK             0x00000FFF
+#define    FP_V_SYNC_STRT_WID__FP_V_SYNC_STRT__SHIFT            0
+#define    FP_V_SYNC_STRT_WID__FP_V_SYNC_WID__MASK              0x001F0000
+#define    FP_V_SYNC_STRT_WID__FP_V_SYNC_WID__SHIFT             16
+#define    FP_V_SYNC_STRT_WID__FP_V_SYNC_POL                    0x00800000
+#define FP_CRTC_H_TOTAL_DISP                                0x00000250
+#define    FP_CRTC_H_TOTAL_DISP__FP_CRTC_H_TOTAL__MASK          0x000003FF
+#define    FP_CRTC_H_TOTAL_DISP__FP_CRTC_H_TOTAL__SHIFT         0
+#define    FP_CRTC_H_TOTAL_DISP__FP_CRTC_H_DISP__MASK           0x01FF0000
+#define    FP_CRTC_H_TOTAL_DISP__FP_CRTC_H_DISP__SHIFT          16
+#define FP_CRTC_V_TOTAL_DISP                                0x00000254
+#define    FP_CRTC_V_TOTAL_DISP__FP_CRTC_V_TOTAL__MASK          0x00000FFF
+#define    FP_CRTC_V_TOTAL_DISP__FP_CRTC_V_TOTAL__SHIFT         0
+#define    FP_CRTC_V_TOTAL_DISP__FP_CRTC_V_DISP__MASK           0x0FFF0000
+#define    FP_CRTC_V_TOTAL_DISP__FP_CRTC_V_DISP__SHIFT          16
+#define PALETTE_INDEX                                       0x000000B0
+#define    PALETTE_INDEX__PALETTE_W_INDEX__MASK                 0x000000FF
+#define    PALETTE_INDEX__PALETTE_W_INDEX__SHIFT                0
+#define    PALETTE_INDEX__PALETTE_R_INDEX__MASK                 0x00FF0000
+#define    PALETTE_INDEX__PALETTE_R_INDEX__SHIFT                16
+#define PALETTE_DATA                                        0x000000B4
+#define    PALETTE_DATA__PALETTE_DATA_B__MASK                   0x000000FF
+#define    PALETTE_DATA__PALETTE_DATA_B__SHIFT                  0
+#define    PALETTE_DATA__PALETTE_DATA_G__MASK                   0x0000FF00
+#define    PALETTE_DATA__PALETTE_DATA_G__SHIFT                  8
+#define    PALETTE_DATA__PALETTE_DATA_R__MASK                   0x00FF0000
+#define    PALETTE_DATA__PALETTE_DATA_R__SHIFT                  16
+#define PALETTE_30_DATA                                     0x000000B8
+#define    PALETTE_30_DATA__PALETTE_DATA_B__MASK                0x000003FF
+#define    PALETTE_30_DATA__PALETTE_DATA_B__SHIFT               0
+#define    PALETTE_30_DATA__PALETTE_DATA_G__MASK                0x000FFC00
+#define    PALETTE_30_DATA__PALETTE_DATA_G__SHIFT               10
+#define    PALETTE_30_DATA__PALETTE_DATA_R__MASK                0x3FF00000
+#define    PALETTE_30_DATA__PALETTE_DATA_R__SHIFT               20
+#define SURFACE_CNTL                                        0x00000B00
+#define    SURFACE_CNTL__SURF_TRANSLATION_DIS                   0x00000100
+#define    SURFACE_CNTL__NONSURF_AP0_SWP__MASK                  0x00300000
+#define    SURFACE_CNTL__NONSURF_AP0_SWP__SHIFT                 20
+#define    SURFACE_CNTL__NONSURF_AP1_SWP__MASK                  0x00C00000
+#define    SURFACE_CNTL__NONSURF_AP1_SWP__SHIFT                 22
+#define SURFACE0_INFO                                       0x00000B0C
+#define    SURFACE0_INFO__SURF0_PITCHSEL__MASK                  0x000003FF
+#define    SURFACE0_INFO__SURF0_PITCHSEL__SHIFT                 0
+#define    SURFACE0_INFO__SURF0_TILE_MODE__MASK                 0x00030000
+#define    SURFACE0_INFO__SURF0_TILE_MODE__SHIFT                16
+#define    SURF0_TILE_MODE__NO_TILING(p)                            0x0
+#define    SURF0_TILE_MODE__MACRO_TILING(p)                         0x0
+#define    SURF0_TILE_MODE__MICRO_TILING(p)                         0x0
+#define    SURF0_TILE_MODE__MACRO_MICRO_TILING(p)                   0x0
+#define    SURF0_TILE_MODE__32_BIT_Z_TILING(p)                      0x0
+#define    SURF0_TILE_MODE__16_BIT_Z_TILING(p)                      0x0
+#define    SURFACE0_INFO__SURF0_AP0_SWP__MASK                   0x00300000
+#define    SURFACE0_INFO__SURF0_AP0_SWP__SHIFT                  20
+#define    SURFACE0_INFO__SURF0_AP1_SWP__MASK                   0x00C00000
+#define    SURFACE0_INFO__SURF0_AP1_SWP__SHIFT                  22
+#define    SURFACE0_INFO__SURF0_WRITE_FLAG                      0x01000000
+#define    SURFACE0_INFO__SURF0_READ_FLAG                       0x02000000
+#define    SURFACE0_INFO__SURF0_TILE_MODE_R2__MASK              0x00070000
+#define    SURFACE0_INFO__SURF0_TILE_MODE_R2__SHIFT             16
+#define    SURFACE0_INFO__SURF0_PITCHSEL_R3__MASK               0x00001FFF
+#define    SURFACE0_INFO__SURF0_PITCHSEL_R3__SHIFT              0
+#define SURFACE0_LOWER_BOUND                                0x00000B04
+#define    SURFACE0_LOWER_BOUND__SURF_LOWER__MASK               0x0FFFFFFF
+#define    SURFACE0_LOWER_BOUND__SURF_LOWER__SHIFT              0
+#define SURFACE0_UPPER_BOUND                                0x00000B08
+#define    SURFACE0_UPPER_BOUND__SURF_UPPER__MASK               0x0FFFFFFF
+#define    SURFACE0_UPPER_BOUND__SURF_UPPER__SHIFT              0
+#define SURFACE1_INFO                                       0x00000B1C
+#define    SURFACE1_INFO__SURF1_PITCHSEL__MASK                  0x000003FF
+#define    SURFACE1_INFO__SURF1_PITCHSEL__SHIFT                 0
+#define    SURFACE1_INFO__SURF1_TILE_MODE__MASK                 0x00030000
+#define    SURFACE1_INFO__SURF1_TILE_MODE__SHIFT                16
+#define    SURFACE1_INFO__SURF1_AP0_SWP__MASK                   0x00300000
+#define    SURFACE1_INFO__SURF1_AP0_SWP__SHIFT                  20
+#define    SURFACE1_INFO__SURF1_AP1_SWP__MASK                   0x00C00000
+#define    SURFACE1_INFO__SURF1_AP1_SWP__SHIFT                  22
+#define    SURFACE1_INFO__SURF1_WRITE_FLAG                      0x01000000
+#define    SURFACE1_INFO__SURF1_READ_FLAG                       0x02000000
+#define    SURFACE1_INFO__SURF1_TILE_MODE_R2__MASK              0x00070000
+#define    SURFACE1_INFO__SURF1_TILE_MODE_R2__SHIFT             16
+#define    SURFACE1_INFO__SURF1_PITCHSEL_R3__MASK               0x00001FFF
+#define    SURFACE1_INFO__SURF1_PITCHSEL_R3__SHIFT              0
+#define SURFACE1_LOWER_BOUND                                0x00000B14
+#define    SURFACE1_LOWER_BOUND__SURF_LOWER__MASK               0x0FFFFFFF
+#define    SURFACE1_LOWER_BOUND__SURF_LOWER__SHIFT              0
+#define SURFACE1_UPPER_BOUND                                0x00000B18
+#define    SURFACE1_UPPER_BOUND__SURF_UPPER__MASK               0x0FFFFFFF
+#define    SURFACE1_UPPER_BOUND__SURF_UPPER__SHIFT              0
+#define SURFACE2_INFO                                       0x00000B2C
+#define    SURFACE2_INFO__SURF2_PITCHSEL__MASK                  0x000003FF
+#define    SURFACE2_INFO__SURF2_PITCHSEL__SHIFT                 0
+#define    SURFACE2_INFO__SURF2_TILE_MODE__MASK                 0x00030000
+#define    SURFACE2_INFO__SURF2_TILE_MODE__SHIFT                16
+#define    SURFACE2_INFO__SURF2_AP0_SWP__MASK                   0x00300000
+#define    SURFACE2_INFO__SURF2_AP0_SWP__SHIFT                  20
+#define    SURFACE2_INFO__SURF2_AP1_SWP__MASK                   0x00C00000
+#define    SURFACE2_INFO__SURF2_AP1_SWP__SHIFT                  22
+#define    SURFACE2_INFO__SURF2_WRITE_FLAG                      0x01000000
+#define    SURFACE2_INFO__SURF2_READ_FLAG                       0x02000000
+#define    SURFACE2_INFO__SURF2_TILE_MODE_R2__MASK              0x00070000
+#define    SURFACE2_INFO__SURF2_TILE_MODE_R2__SHIFT             16
+#define    SURFACE2_INFO__SURF2_PITCHSEL_R3__MASK               0x00001FFF
+#define    SURFACE2_INFO__SURF2_PITCHSEL_R3__SHIFT              0
+#define SURFACE2_LOWER_BOUND                                0x00000B24
+#define    SURFACE2_LOWER_BOUND__SURF_LOWER__MASK               0x0FFFFFFF
+#define    SURFACE2_LOWER_BOUND__SURF_LOWER__SHIFT              0
+#define SURFACE2_UPPER_BOUND                                0x00000B28
+#define    SURFACE2_UPPER_BOUND__SURF_UPPER__MASK               0x0FFFFFFF
+#define    SURFACE2_UPPER_BOUND__SURF_UPPER__SHIFT              0
+#define SURFACE3_INFO                                       0x00000B3C
+#define    SURFACE3_INFO__SURF3_PITCHSEL__MASK                  0x000003FF
+#define    SURFACE3_INFO__SURF3_PITCHSEL__SHIFT                 0
+#define    SURFACE3_INFO__SURF3_TILE_MODE__MASK                 0x00030000
+#define    SURFACE3_INFO__SURF3_TILE_MODE__SHIFT                16
+#define    SURFACE3_INFO__SURF3_AP0_SWP__MASK                   0x00300000
+#define    SURFACE3_INFO__SURF3_AP0_SWP__SHIFT                  20
+#define    SURFACE3_INFO__SURF3_AP1_SWP__MASK                   0x00C00000
+#define    SURFACE3_INFO__SURF3_AP1_SWP__SHIFT                  22
+#define    SURFACE3_INFO__SURF3_WRITE_FLAG                      0x01000000
+#define    SURFACE3_INFO__SURF3_READ_FLAG                       0x02000000
+#define    SURFACE3_INFO__SURF3_TILE_MODE_R2__MASK              0x00070000
+#define    SURFACE3_INFO__SURF3_TILE_MODE_R2__SHIFT             16
+#define    SURFACE3_INFO__SURF3_PITCHSEL_R3__MASK               0x00001FFF
+#define    SURFACE3_INFO__SURF3_PITCHSEL_R3__SHIFT              0
+#define SURFACE3_LOWER_BOUND                                0x00000B34
+#define    SURFACE3_LOWER_BOUND__SURF_LOWER__MASK               0x0FFFFFFF
+#define    SURFACE3_LOWER_BOUND__SURF_LOWER__SHIFT              0
+#define SURFACE3_UPPER_BOUND                                0x00000B38
+#define    SURFACE3_UPPER_BOUND__SURF_UPPER__MASK               0x0FFFFFFF
+#define    SURFACE3_UPPER_BOUND__SURF_UPPER__SHIFT              0
+#define SURFACE4_INFO                                       0x00000B4C
+#define    SURFACE4_INFO__SURF4_PITCHSEL__MASK                  0x000003FF
+#define    SURFACE4_INFO__SURF4_PITCHSEL__SHIFT                 0
+#define    SURFACE4_INFO__SURF4_TILE_MODE__MASK                 0x00030000
+#define    SURFACE4_INFO__SURF4_TILE_MODE__SHIFT                16
+#define    SURFACE4_INFO__SURF4_AP0_SWP__MASK                   0x00300000
+#define    SURFACE4_INFO__SURF4_AP0_SWP__SHIFT                  20
+#define    SURFACE4_INFO__SURF4_AP1_SWP__MASK                   0x00C00000
+#define    SURFACE4_INFO__SURF4_AP1_SWP__SHIFT                  22
+#define    SURFACE4_INFO__SURF4_WRITE_FLAG                      0x01000000
+#define    SURFACE4_INFO__SURF4_READ_FLAG                       0x02000000
+#define    SURFACE4_INFO__SURF4_TILE_MODE_R2__MASK              0x00070000
+#define    SURFACE4_INFO__SURF4_TILE_MODE_R2__SHIFT             16
+#define    SURFACE4_INFO__SURF4_PITCHSEL_R3__MASK               0x00001FFF
+#define    SURFACE4_INFO__SURF4_PITCHSEL_R3__SHIFT              0
+#define SURFACE4_LOWER_BOUND                                0x00000B44
+#define    SURFACE4_LOWER_BOUND__SURF_LOWER__MASK               0x0FFFFFFF
+#define    SURFACE4_LOWER_BOUND__SURF_LOWER__SHIFT              0
+#define SURFACE4_UPPER_BOUND                                0x00000B48
+#define    SURFACE4_UPPER_BOUND__SURF_UPPER__MASK               0x0FFFFFFF
+#define    SURFACE4_UPPER_BOUND__SURF_UPPER__SHIFT              0
+#define SURFACE5_INFO                                       0x00000B5C
+#define    SURFACE5_INFO__SURF5_PITCHSEL__MASK                  0x000003FF
+#define    SURFACE5_INFO__SURF5_PITCHSEL__SHIFT                 0
+#define    SURFACE5_INFO__SURF5_TILE_MODE__MASK                 0x00030000
+#define    SURFACE5_INFO__SURF5_TILE_MODE__SHIFT                16
+#define    SURFACE5_INFO__SURF5_AP0_SWP__MASK                   0x00300000
+#define    SURFACE5_INFO__SURF5_AP0_SWP__SHIFT                  20
+#define    SURFACE5_INFO__SURF5_AP1_SWP__MASK                   0x00C00000
+#define    SURFACE5_INFO__SURF5_AP1_SWP__SHIFT                  22
+#define    SURFACE5_INFO__SURF5_WRITE_FLAG                      0x01000000
+#define    SURFACE5_INFO__SURF5_READ_FLAG                       0x02000000
+#define    SURFACE5_INFO__SURF5_TILE_MODE_R2__MASK              0x00070000
+#define    SURFACE5_INFO__SURF5_TILE_MODE_R2__SHIFT             16
+#define    SURFACE5_INFO__SURF5_PITCHSEL_R3__MASK               0x00001FFF
+#define    SURFACE5_INFO__SURF5_PITCHSEL_R3__SHIFT              0
+#define SURFACE5_LOWER_BOUND                                0x00000B54
+#define    SURFACE5_LOWER_BOUND__SURF_LOWER__MASK               0x0FFFFFFF
+#define    SURFACE5_LOWER_BOUND__SURF_LOWER__SHIFT              0
+#define SURFACE5_UPPER_BOUND                                0x00000B58
+#define    SURFACE5_UPPER_BOUND__SURF_UPPER__MASK               0x0FFFFFFF
+#define    SURFACE5_UPPER_BOUND__SURF_UPPER__SHIFT              0
+#define SURFACE6_INFO                                       0x00000B6C
+#define    SURFACE6_INFO__SURF6_PITCHSEL__MASK                  0x000003FF
+#define    SURFACE6_INFO__SURF6_PITCHSEL__SHIFT                 0
+#define    SURFACE6_INFO__SURF6_TILE_MODE__MASK                 0x00030000
+#define    SURFACE6_INFO__SURF6_TILE_MODE__SHIFT                16
+#define    SURFACE6_INFO__SURF6_AP0_SWP__MASK                   0x00300000
+#define    SURFACE6_INFO__SURF6_AP0_SWP__SHIFT                  20
+#define    SURFACE6_INFO__SURF6_AP1_SWP__MASK                   0x00C00000
+#define    SURFACE6_INFO__SURF6_AP1_SWP__SHIFT                  22
+#define    SURFACE6_INFO__SURF6_WRITE_FLAG                      0x01000000
+#define    SURFACE6_INFO__SURF6_READ_FLAG                       0x02000000
+#define    SURFACE6_INFO__SURF6_TILE_MODE_R2__MASK              0x00070000
+#define    SURFACE6_INFO__SURF6_TILE_MODE_R2__SHIFT             16
+#define    SURFACE6_INFO__SURF6_PITCHSEL_R3__MASK               0x00001FFF
+#define    SURFACE6_INFO__SURF6_PITCHSEL_R3__SHIFT              0
+#define SURFACE6_LOWER_BOUND                                0x00000B64
+#define    SURFACE6_LOWER_BOUND__SURF_LOWER__MASK               0x0FFFFFFF
+#define    SURFACE6_LOWER_BOUND__SURF_LOWER__SHIFT              0
+#define SURFACE6_UPPER_BOUND                                0x00000B68
+#define    SURFACE6_UPPER_BOUND__SURF_UPPER__MASK               0x0FFFFFFF
+#define    SURFACE6_UPPER_BOUND__SURF_UPPER__SHIFT              0
+#define SURFACE7_INFO                                       0x00000B7C
+#define    SURFACE7_INFO__SURF7_PITCHSEL__MASK                  0x000003FF
+#define    SURFACE7_INFO__SURF7_PITCHSEL__SHIFT                 0
+#define    SURFACE7_INFO__SURF7_TILE_MODE__MASK                 0x00030000
+#define    SURFACE7_INFO__SURF7_TILE_MODE__SHIFT                16
+#define    SURFACE7_INFO__SURF7_AP0_SWP__MASK                   0x00300000
+#define    SURFACE7_INFO__SURF7_AP0_SWP__SHIFT                  20
+#define    SURFACE7_INFO__SURF7_AP1_SWP__MASK                   0x00C00000
+#define    SURFACE7_INFO__SURF7_AP1_SWP__SHIFT                  22
+#define    SURFACE7_INFO__SURF7_WRITE_FLAG                      0x01000000
+#define    SURFACE7_INFO__SURF7_READ_FLAG                       0x02000000
+#define    SURFACE7_INFO__SURF7_TILE_MODE_R2__MASK              0x00070000
+#define    SURFACE7_INFO__SURF7_TILE_MODE_R2__SHIFT             16
+#define    SURFACE7_INFO__SURF7_PITCHSEL_R3__MASK               0x00001FFF
+#define    SURFACE7_INFO__SURF7_PITCHSEL_R3__SHIFT              0
+#define SURFACE7_LOWER_BOUND                                0x00000B74
+#define    SURFACE7_LOWER_BOUND__SURF_LOWER__MASK               0x0FFFFFFF
+#define    SURFACE7_LOWER_BOUND__SURF_LOWER__SHIFT              0
+#define SURFACE7_UPPER_BOUND                                0x00000B78
+#define    SURFACE7_UPPER_BOUND__SURF_UPPER__MASK               0x0FFFFFFF
+#define    SURFACE7_UPPER_BOUND__SURF_UPPER__SHIFT              0
+#define ISYNC_CNTL                                          0x00001724
+#define    ISYNC_CNTL__ISYNC_ANY2D_IDLE3D                       0x00000001
+#define    ISYNC_CNTL__ISYNC_ANY3D_IDLE2D                       0x00000002
+#define    ISYNC_CNTL__ISYNC_TRIG2D_IDLE3D                      0x00000004
+#define    ISYNC_CNTL__ISYNC_TRIG3D_IDLE2D                      0x00000008
+#define    ISYNC_CNTL__ISYNC_WAIT_IDLEGUI                       0x00000010
+#define    ISYNC_CNTL__ISYNC_CPSCRATCH_IDLEGUI                  0x00000020
+#define RBBM_STATUS                                         0x00000E40
+#define    RBBM_STATUS__CMDFIFO_AVAIL__MASK                     0x0000007F
+#define    RBBM_STATUS__CMDFIFO_AVAIL__SHIFT                    0
+#define    RBBM_STATUS__HIRQ_ON_RBB                             0x00000100
+#define    RBBM_STATUS__CPRQ_ON_RBB                             0x00000200
+#define    RBBM_STATUS__CFRQ_ON_RBB                             0x00000400
+#define    RBBM_STATUS__HIRQ_IN_RTBUF                           0x00000800
+#define    RBBM_STATUS__CPRQ_IN_RTBUF                           0x00001000
+#define    RBBM_STATUS__CFRQ_IN_RTBUF                           0x00002000
+#define    RBBM_STATUS__CF_PIPE_BUSY                            0x00004000
+#define    RBBM_STATUS__ENG_EV_BUSY                             0x00008000
+#define    RBBM_STATUS__CP_CMDSTRM_BUSY                         0x00010000
+#define    RBBM_STATUS__E2_BUSY                                 0x00020000
+#define    RBBM_STATUS__RB2D_BUSY                               0x00040000
+#define    RBBM_STATUS__RB3D_BUSY                               0x00080000
+#define    RBBM_STATUS__SE_BUSY                                 0x00100000
+#define    RBBM_STATUS__RE_BUSY                                 0x00200000
+#define    RBBM_STATUS__TAM_BUSY                                0x00400000
+#define    RBBM_STATUS__TDM_BUSY                                0x00800000
+#define    RBBM_STATUS__PB_BUSY                                 0x01000000
+#define    RBBM_STATUS__GUI_ACTIVE                              0x80000000
+#define    RBBM_STATUS__VAP_BUSY                                0x00100000
+#define    RBBM_STATUS__TIM_BUSY                                0x02000000
+#define    RBBM_STATUS__GA_BUSY                                 0x04000000
+#define    RBBM_STATUS__CBA2D_BUSY                              0x08000000
+#define RBBM_SOFT_RESET                                     0x000000F0
+#define    RBBM_SOFT_RESET__SOFT_RESET_CP                       0x00000001
+#define    RBBM_SOFT_RESET__SOFT_RESET_HI                       0x00000002
+#define    RBBM_SOFT_RESET__SOFT_RESET_SE                       0x00000004
+#define    RBBM_SOFT_RESET__SOFT_RESET_RE                       0x00000008
+#define    RBBM_SOFT_RESET__SOFT_RESET_PP                       0x00000010
+#define    RBBM_SOFT_RESET__SOFT_RESET_E2                       0x00000020
+#define    RBBM_SOFT_RESET__SOFT_RESET_RB                       0x00000040
+#define    RBBM_SOFT_RESET__SOFT_RESET_HDP                      0x00000080
+#define    RBBM_SOFT_RESET__SOFT_RESET_MC                       0x00000100
+#define    RBBM_SOFT_RESET__SOFT_RESET_AIC                      0x00000200
+#define    RBBM_SOFT_RESET__SOFT_RESET_VIP                      0x00000400
+#define    RBBM_SOFT_RESET__SOFT_RESET_DISP                     0x00000800
+#define    RBBM_SOFT_RESET__SOFT_RESET_CG                       0x00001000
+#define    RBBM_SOFT_RESET__SOFT_RESET_VAP                      0x00000004
+#define    RBBM_SOFT_RESET__SOFT_RESET_GA                       0x00002000
+#define    RBBM_SOFT_RESET__SOFT_RESET_IDCT                     0x00004000
+#define WAIT_UNTIL                                          0x00001720
+#define    WAIT_UNTIL__WAIT_CRTC_PFLIP                          0x00000001
+#define    WAIT_UNTIL__WAIT_RE_CRTC_VLINE                       0x00000002
+#define    WAIT_UNTIL__WAIT_FE_CRTC_VLINE                       0x00000004
+#define    WAIT_UNTIL__WAIT_CRTC_VLINE                          0x00000008
+#define    WAIT_UNTIL__WAIT_DMA_VIPH0_IDLE                      0x00000010
+#define    WAIT_UNTIL__WAIT_DMA_VIPH1_IDLE                      0x00000020
+#define    WAIT_UNTIL__WAIT_DMA_VIPH2_IDLE                      0x00000040
+#define    WAIT_UNTIL__WAIT_DMA_VIPH3_IDLE                      0x00000080
+#define    WAIT_UNTIL__WAIT_DMA_VID_IDLE                        0x00000100
+#define    WAIT_UNTIL__WAIT_DMA_GUI_IDLE                        0x00000200
+#define    WAIT_UNTIL__WAIT_CMDFIFO                             0x00000400
+#define    WAIT_UNTIL__WAIT_OV0_FLIP                            0x00000800
+#define    WAIT_UNTIL__WAIT_OV0_SLICEDONE                       0x00001000
+#define    WAIT_UNTIL__WAIT_2D_IDLE                             0x00004000
+#define    WAIT_UNTIL__WAIT_3D_IDLE                             0x00008000
+#define    WAIT_UNTIL__WAIT_2D_IDLECLEAN                        0x00010000
+#define    WAIT_UNTIL__WAIT_3D_IDLECLEAN                        0x00020000
+#define    WAIT_UNTIL__WAIT_HOST_IDLECLEAN                      0x00040000
+#define    WAIT_UNTIL__WAIT_EXTERN_SIG                          0x00080000
+#define    WAIT_UNTIL__CMDFIFO_ENTRIES__MASK                    0x07F00000
+#define    WAIT_UNTIL__CMDFIFO_ENTRIES__SHIFT                   20
+#define    WAIT_UNTIL__WAIT_BOTH_CRTC_PFLIP                     0x40000000
+#define    WAIT_UNTIL__ENG_DISPLAY_SELECT                       0x80000000
+#define    WAIT_UNTIL__WAIT_AGP_FLUSH                           0x00002000
+#define    WAIT_UNTIL__WAIT_IDCT_SEMAPHORE                      0x08000000
+#define    WAIT_UNTIL__WAIT_VAP_IDLE                            0x10000000
+#define DISPLAY_BASE_ADDR                                   0x0000023C
+#define    DISPLAY_BASE_ADDR__DISPLAY_BASE_ADDR__MASK           0xFFFFFFFF
+#define    DISPLAY_BASE_ADDR__DISPLAY_BASE_ADDR__SHIFT          0
+#define CRTC2_DISPLAY_BASE_ADDR                             0x0000033C
+#define    CRTC2_DISPLAY_BASE_ADDR__CRTC2_DISPLAY_BASE_ADDR__MASK 0xFFFFFFFF
+#define    CRTC2_DISPLAY_BASE_ADDR__CRTC2_DISPLAY_BASE_ADDR__SHIFT 0
+#define AIC_CTRL                                            0x000001D0
+#define    AIC_CTRL__TRANSLATE_EN                               0x00000001
+#define    AIC_CTRL__HW_0_DEBUG                                 0x00000002
+#define    AIC_CTRL__HW_1_DEBUG                                 0x00000004
+#define    AIC_CTRL__HW_2_DEBUG                                 0x00000008
+#define    AIC_CTRL__HW_3_DEBUG                                 0x00000010
+#define    AIC_CTRL__HW_4_DEBUG                                 0x00000020
+#define    AIC_CTRL__HW_5_DEBUG                                 0x00000040
+#define    AIC_CTRL__HW_6_DEBUG                                 0x00000080
+#define    AIC_CTRL__HW_7_DEBUG                                 0x00000100
+#define    AIC_CTRL__HW_8_DEBUG                                 0x00000200
+#define    AIC_CTRL__HW_9_DEBUG                                 0x00000400
+#define    AIC_CTRL__HW_A_DEBUG                                 0x00000800
+#define    AIC_CTRL__HW_B_DEBUG                                 0x00001000
+#define    AIC_CTRL__HW_C_DEBUG                                 0x00002000
+#define    AIC_CTRL__HW_D_DEBUG                                 0x00004000
+#define    AIC_CTRL__HW_E_DEBUG                                 0x00008000
+#define    AIC_CTRL__HW_F_DEBUG                                 0x00010000
+#define    AIC_CTRL__HW_10_DEBUG                                0x00020000
+#define    AIC_CTRL__HW_11_DEBUG                                0x00040000
+#define    AIC_CTRL__HW_12_DEBUG                                0x00080000
+#define    AIC_CTRL__HW_13_DEBUG                                0x00100000
+#define    AIC_CTRL__HW_14_DEBUG                                0x00200000
+#define    AIC_CTRL__HW_15_DEBUG                                0x00400000
+#define    AIC_CTRL__HW_16_DEBUG                                0x00800000
+#define    AIC_CTRL__HW_17_DEBUG                                0x01000000
+#define    AIC_CTRL__HW_18_DEBUG                                0x02000000
+#define    AIC_CTRL__HW_19_DEBUG                                0x04000000
+#define    AIC_CTRL__HW_1A_DEBUG                                0x08000000
+#define    AIC_CTRL__HW_1B_DEBUG                                0x10000000
+#define    AIC_CTRL__HW_1C_DEBUG                                0x20000000
+#define    AIC_CTRL__HW_1D_DEBUG                                0x40000000
+#define    AIC_CTRL__HW_1E_DEBUG                                0x80000000
+#define    AIC_CTRL__DIS_OUT_OF_PCI_GART_ACCESS                 0x00000002
+#define    AIC_CTRL__HW_02_DEBUG                                0x00000004
+#define    AIC_CTRL__HW_03_DEBUG                                0x00000008
+#define    AIC_CTRL__TEST_RBF_DIV_VAL__MASK                     0x00000070
+#define    AIC_CTRL__TEST_RBF_DIV_VAL__SHIFT                    4
+#define    AIC_CTRL__TEST_RBF_EN                                0x00000080
+#define    AIC_CTRL__HW_08_DEBUG                                0x00000100
+#define    AIC_CTRL__HW_09_DEBUG                                0x00000200
+#define    AIC_CTRL__HW_10_DEBUG_R3                             0x00000400
+#define    AIC_CTRL__HW_11_DEBUG_R3                             0x00000800
+#define    AIC_CTRL__HW_12_DEBUG_R3                             0x00001000
+#define    AIC_CTRL__HW_13_DEBUG_R3                             0x00002000
+#define    AIC_CTRL__HW_14_DEBUG_R3                             0x00004000
+#define    AIC_CTRL__HW_15_DEBUG_R3                             0x00008000
+#define    AIC_CTRL__HW_16_DEBUG_R3                             0x00010000
+#define    AIC_CTRL__HW_17_DEBUG_R3                             0x00020000
+#define    AIC_CTRL__HW_18_DEBUG_R3                             0x00040000
+#define    AIC_CTRL__HW_19_DEBUG_R3                             0x00080000
+#define    AIC_CTRL__HW_20_DEBUG                                0x00100000
+#define    AIC_CTRL__HW_21_DEBUG                                0x00200000
+#define    AIC_CTRL__HW_22_DEBUG                                0x00400000
+#define    AIC_CTRL__HW_23_DEBUG                                0x00800000
+#define    AIC_CTRL__HW_24_DEBUG                                0x01000000
+#define    AIC_CTRL__HW_25_DEBUG                                0x02000000
+#define    AIC_CTRL__HW_26_DEBUG                                0x04000000
+#define    AIC_CTRL__HW_27_DEBUG                                0x08000000
+#define    AIC_CTRL__HW_28_DEBUG                                0x10000000
+#define    AIC_CTRL__HW_29_DEBUG                                0x20000000
+#define    AIC_CTRL__HW_30_DEBUG                                0x40000000
+#define    AIC_CTRL__HW_31_DEBUG                                0x80000000
+#define BUS_CNTL                                            0x00000030
+#define    BUS_CNTL__BUS_DBL_RESYNC                             0x00000001
+#define    BUS_CNTL__BUS_MSTR_RESET                             0x00000002
+#define    BUS_CNTL__BUS_FLUSH_BUF                              0x00000004
+#define    BUS_CNTL__BUS_STOP_REQ_DIS                           0x00000008
+#define    BUS_CNTL__BUS_READ_COMBINE_EN                        0x00000010
+#define    BUS_CNTL__BUS_WRT_COMBINE_EN                         0x00000020
+#define    BUS_CNTL__BUS_MASTER_DIS                             0x00000040
+#define    BUS_CNTL__BIOS_ROM_WRT_EN                            0x00000080
+#define    BUS_CNTL__BUS_PREFETCH_MODE__MASK                    0x00000300
+#define    BUS_CNTL__BUS_PREFETCH_MODE__SHIFT                   8
+#define    BUS_CNTL__BUS_VGA_PREFETCH_EN                        0x00000400
+#define    BUS_CNTL__BUS_SGL_READ_DISABLE                       0x00000800
+#define    BUS_CNTL__BIOS_DIS_ROM                               0x00001000
+#define    BUS_CNTL__BUS_PCI_READ_RETRY_EN                      0x00002000
+#define    BUS_CNTL__BUS_AGP_AD_STEPPING_EN                     0x00004000
+#define    BUS_CNTL__BUS_PCI_WRT_RETRY_EN                       0x00008000
+#define    BUS_CNTL__BUS_RETRY_WS__MASK                         0x000F0000
+#define    BUS_CNTL__BUS_RETRY_WS__SHIFT                        16
+#define    BUS_CNTL__BUS_MSTR_RD_MULT                           0x00100000
+#define    BUS_CNTL__BUS_MSTR_RD_LINE                           0x00200000
+#define    BUS_CNTL__BUS_SUSPEND                                0x00400000
+#define    BUS_CNTL__LAT_16X                                    0x00800000
+#define    BUS_CNTL__BUS_RD_DISCARD_EN                          0x01000000
+#define    BUS_CNTL__ENFRCWRDY                                  0x02000000
+#define    BUS_CNTL__BUS_MSTR_WS                                0x04000000
+#define    BUS_CNTL__BUS_PARKING_DIS                            0x08000000
+#define    BUS_CNTL__BUS_MSTR_DISCONNECT_EN                     0x10000000
+#define    BUS_CNTL__SERR_EN                                    0x20000000
+#define    BUS_CNTL__BUS_READ_BURST                             0x40000000
+#define    BUS_CNTL__BUS_RDY_READ_DLY                           0x80000000
+#define    BUS_CNTL__BUS_PM4_READ_COMBINE_EN                    0x00000010
+#define    BUS_CNTL__BM_DAC_CRIPPLE                             0x00000100
+#define    BUS_CNTL__BUS_NON_PM4_READ_COMBINE_EN                0x00000200
+#define    BUS_CNTL__BUS_XFERD_DISCARD_EN                       0x00000400
+#define MC_STATUS                                           0x00000150
+#define    MC_STATUS__MEM_PWRUP_COMPL_A                         0x00000001
+#define    MC_STATUS__MEM_PWRUP_COMPL_B                         0x00000002
+#define    MC_STATUS__MC_IDLE                                   0x00000004
+#define    MC_STATUS__SPARE__MASK                               0x0000FFF8
+#define    MC_STATUS__SPARE__SHIFT                              3
+#define    MC_STATUS__IMP_N_VALUE_R_BACK__MASK                  0x00000078
+#define    MC_STATUS__IMP_N_VALUE_R_BACK__SHIFT                 3
+#define    MC_STATUS__IMP_P_VALUE_R_BACK__MASK                  0x00000780
+#define    MC_STATUS__IMP_P_VALUE_R_BACK__SHIFT                 7
+#define    MC_STATUS__TEST_OUT_R_BACK                           0x00000800
+#define    MC_STATUS__DUMMY_OUT_R_BACK                          0x00001000
+#define    MC_STATUS__IMP_N_VALUE_A_R_BACK__MASK                0x0001E000
+#define    MC_STATUS__IMP_N_VALUE_A_R_BACK__SHIFT               13
+#define    MC_STATUS__IMP_P_VALUE_A_R_BACK__MASK                0x001E0000
+#define    MC_STATUS__IMP_P_VALUE_A_R_BACK__SHIFT               17
+#define    MC_STATUS__IMP_N_VALUE_CK_R_BACK__MASK               0x01E00000
+#define    MC_STATUS__IMP_N_VALUE_CK_R_BACK__SHIFT              21
+#define    MC_STATUS__IMP_P_VALUE_CK_R_BACK__MASK               0x1E000000
+#define    MC_STATUS__IMP_P_VALUE_CK_R_BACK__SHIFT              25
+#define    MC_STATUS__MEM_PWRUP_COMPL_C                         0x00000004
+#define    MC_STATUS__MEM_PWRUP_COMPL_D                         0x00000008
+#define    MC_STATUS__MC_IDLE_R3                                0x00000010
+#define    MC_STATUS__IMP_CAL_COUNT__MASK                       0x0000F000
+#define    MC_STATUS__IMP_CAL_COUNT__SHIFT                      12
+#define OV0_SCALE_CNTL                                      0x00000420
+#define    OV0_SCALE_CNTL__OV0_NO_READ_BEHIND_SCAN              0x00000002
+#define    OV0_SCALE_CNTL__OV0_HORZ_PICK_NEAREST                0x00000004
+#define    OV0_SCALE_CNTL__OV0_VERT_PICK_NEAREST                0x00000008
+#define    OV0_SCALE_CNTL__OV0_SIGNED_UV                        0x00000010
+#define    OV0_SCALE_CNTL__OV0_GAMMA_SEL__MASK                  0x000000E0
+#define    OV0_SCALE_CNTL__OV0_GAMMA_SEL__SHIFT                 5
+#define    OV0_SCALE_CNTL__OV0_SURFACE_FORMAT__MASK             0x00000F00
+#define    OV0_SCALE_CNTL__OV0_SURFACE_FORMAT__SHIFT            8
+#define    OV0_SURFACE_FORMAT__RESERVED0                            0x0
+#define    OV0_SURFACE_FORMAT__RESERVED1                            0x100
+#define    OV0_SURFACE_FORMAT__RESERVED2                            0x200
+#define    OV0_SURFACE_FORMAT__16BPP_ARGB                           0x300
+#define    OV0_SURFACE_FORMAT__16BPP_RGB                            0x400
+#define    OV0_SURFACE_FORMAT__RESERVED5                            0x500
+#define    OV0_SURFACE_FORMAT__32BPP_ARGB                           0x600
+#define    OV0_SURFACE_FORMAT__RESERVED7                            0x700
+#define    OV0_SURFACE_FORMAT__RESERVED8                            0x800
+#define    OV0_SURFACE_FORMAT__IF09_PLANAR                          0x900
+#define    OV0_SURFACE_FORMAT__YV12_PLANAR                          0xA00
+#define    OV0_SURFACE_FORMAT__YUY2_PACKED                          0xB00
+#define    OV0_SURFACE_FORMAT__UYVY_PACKED                          0xC00
+#define    OV0_SURFACE_FORMAT__YYUV9_PLANAR                         0xD00
+#define    OV0_SURFACE_FORMAT__YYUV12_PLANAR                        0xE00
+#define    OV0_SURFACE_FORMAT__RESERVED15                           0xF00
+#define    OV0_SCALE_CNTL__OV0_ADAPTIVE_DEINT                   0x00001000
+#define    OV0_SCALE_CNTL__OV0_CRTC_SEL                         0x00004000
+#define    OV0_SCALE_CNTL__OV0_BURST_PER_PLANE__MASK            0x007F0000
+#define    OV0_SCALE_CNTL__OV0_BURST_PER_PLANE__SHIFT           16
+#define    OV0_SCALE_CNTL__OV0_DOUBLE_BUFFER_REGS               0x01000000
+#define    OV0_SCALE_CNTL__OV0_BANDWIDTH                        0x04000000
+#define    OV0_SCALE_CNTL__OV0_LIN_TRANS_BYPASS                 0x10000000
+#define    OV0_SCALE_CNTL__OV0_INT_EMU                          0x20000000
+#define    OV0_SCALE_CNTL__OV0_OVERLAY_EN__MASK                 0x40000000
+#define    OV0_SCALE_CNTL__OV0_OVERLAY_EN__SHIFT                30
+#define    OV0_OVERLAY_EN__ENABLE                                   0x40000000
+#define    OV0_SCALE_CNTL__OV0_SOFT_RESET__MASK                 0x80000000
+#define    OV0_SCALE_CNTL__OV0_SOFT_RESET__SHIFT                31
+#define    OV0_SOFT_RESET__RESET                                    0x80000000
+#define    OV0_SCALE_CNTL__OV0_TEMPORAL_DEINT                   0x00002000
+#define    OV0_SCALE_CNTL__OV0_PULLDOWN_ON_P1_ONLY              0x00008000
+#define    OV0_SCALE_CNTL__OV0_FULL_BYPASS                      0x00000020
+#define    OV0_SCALE_CNTL__OV0_DYNAMIC_EXT                      0x00000040
+#define    OV0_SCALE_CNTL__OV0_RGB30_ON                         0x00000080
+#define CRTC2_GEN_CNTL                                      0x000003F8
+#define    CRTC2_GEN_CNTL__CRTC2_DBL_SCAN_EN                    0x00000001
+#define    CRTC2_GEN_CNTL__CRTC2_INTERLACE_EN                   0x00000002
+#define    CRTC2_GEN_CNTL__CRTC2_SYNC_TRISTATE                  0x00000010
+#define    CRTC2_GEN_CNTL__CRTC2_HSYNC_TRISTATE                 0x00000020
+#define    CRTC2_GEN_CNTL__CRTC2_VSYNC_TRISTATE                 0x00000040
+#define    CRTC2_GEN_CNTL__CRT2_ON                              0x00000080
+#define    CRTC2_GEN_CNTL__CRTC2_PIX_WIDTH__MASK                0x00000F00
+#define    CRTC2_GEN_CNTL__CRTC2_PIX_WIDTH__SHIFT               8
+#define    CRTC2_GEN_CNTL__CRTC2_ICON_EN                        0x00008000
+#define    CRTC2_GEN_CNTL__CRTC2_CUR_EN                         0x00010000
+#define    CRTC2_GEN_CNTL__CRTC2_CUR_MODE__MASK                 0x00700000
+#define    CRTC2_GEN_CNTL__CRTC2_CUR_MODE__SHIFT                20
+#define    CRTC2_GEN_CNTL__CRTC2_DISPLAY_DIS                    0x00800000
+#define    CRTC2_GEN_CNTL__CRTC2_EN                             0x02000000
+#define    CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B                  0x04000000
+#define    CRTC2_GEN_CNTL__CRTC2_C_SYNC_EN                      0x08000000
+#define    CRTC2_GEN_CNTL__CRTC2_HSYNC_DIS                      0x10000000
+#define    CRTC2_GEN_CNTL__CRTC2_VSYNC_DIS                      0x20000000
+#define    CRTC2_GEN_CNTL__CRTC2_MODE9_COLOR_ORDER              0x00001000
+#define    CRTC2_GEN_CNTL__CRTC2_FIX_VSYNC_EDGE_POSITION_EN     0x40000000
+#define CRTC2_OFFSET                                        0x00000324
+#define    CRTC2_OFFSET__CRTC2_OFFSET__MASK                     0x07FFFFFF
+#define    CRTC2_OFFSET__CRTC2_OFFSET__SHIFT                    0
+#define    CRTC2_OFFSET__CRTC2_GUI_TRIG_OFFSET                  0x40000000
+#define    CRTC2_OFFSET__CRTC2_OFFSET_LOCK                      0x80000000
+#define    CRTC2_OFFSET__CRTC2_OFFSET_R3__MASK                  0x0FFFFFFF
+#define    CRTC2_OFFSET__CRTC2_OFFSET_R3__SHIFT                 0
+#define CRTC2_OFFSET_CNTL                                   0x00000328
+#define    CRTC2_OFFSET_CNTL__CRTC2_TILE_LINE__MASK             0x0000000F
+#define    CRTC2_OFFSET_CNTL__CRTC2_TILE_LINE__SHIFT            0
+#define    CRTC2_OFFSET_CNTL__CRTC2_TILE_EN                     0x00008000
+#define    CRTC2_OFFSET_CNTL__CRTC2_OFFSET_FLIP_CNTL            0x00010000
+#define    CRTC2_OFFSET_CNTL__CRTC2_GUI_TRIG_OFFSET_LEFT_EN     0x10000000
+#define    CRTC2_OFFSET_CNTL__CRTC2_GUI_TRIG_OFFSET             0x40000000
+#define    CRTC2_OFFSET_CNTL__CRTC2_OFFSET_LOCK                 0x80000000
+#define    CRTC2_OFFSET_CNTL__CRTC2_TILE_LINE_RIGHT__MASK       0x000000F0
+#define    CRTC2_OFFSET_CNTL__CRTC2_TILE_LINE_RIGHT__SHIFT      4
+#define    CRTC2_OFFSET_CNTL__CRTC2_TILE_EN_RIGHT               0x00004000
+#define    CRTC2_OFFSET_CNTL__CRTC2_STEREO_OFFSET_EN            0x00020000
+#define    CRTC2_OFFSET_CNTL__CRTC2_STEREO_SYNC_EN__MASK        0x000C0000
+#define    CRTC2_OFFSET_CNTL__CRTC2_STEREO_SYNC_EN__SHIFT       18
+#define    CRTC2_OFFSET_CNTL__CRTC2_STEREO_SYNC                 0x00200000
+#define    CRTC2_OFFSET_CNTL__CRTC2_GUI_TRIG_OFFSET_RIGHT_EN    0x20000000
+#define    CRTC2_OFFSET_CNTL__CRTC2_X_Y_MODE_EN_RIGHT           0x00000100
+#define    CRTC2_OFFSET_CNTL__CRTC2_X_Y_MODE_EN                 0x00000200
+#define    CRTC2_OFFSET_CNTL__CRTC2_MICRO_TILE_EN_RIGHT         0x00001000
+#define    CRTC2_OFFSET_CNTL__CRTC2_MICRO_TILE_EN               0x00002000
+#define    CRTC2_OFFSET_CNTL__CRTC2_MACRO_TILE_EN_RIGHT         0x00004000
+#define    CRTC2_OFFSET_CNTL__CRTC2_MACRO_TILE_EN               0x00008000
+#define CUR_OFFSET                                          0x00000260
+#define    CUR_OFFSET__CUR_OFFSET__MASK                         0x07FFFFFF
+#define    CUR_OFFSET__CUR_OFFSET__SHIFT                        0
+#define    CUR_OFFSET__CUR_LOCK                                 0x80000000
+#define CUR2_OFFSET                                         0x00000360
+#define    CUR2_OFFSET__CUR2_OFFSET__MASK                       0x07FFFFFF
+#define    CUR2_OFFSET__CUR2_OFFSET__SHIFT                      0
+#define    CUR2_OFFSET__CUR2_LOCK                               0x80000000
+#define HOST_PATH_CNTL                                      0x00000130
+#define    HOST_PATH_CNTL__HDP_APER_CNTL                        0x00800000
+#define    HOST_PATH_CNTL__HP_LIN_RD_CACHE_DIS                  0x01000000
+#define    HOST_PATH_CNTL__HP_RBBM_LOCK_DIS                     0x02000000
+#define    HOST_PATH_CNTL__HDP_SOFT_RESET                       0x04000000
+#define    HOST_PATH_CNTL__HDP_WRITE_COMBINER_TIMEOUT__MASK     0x70000000
+#define    HOST_PATH_CNTL__HDP_WRITE_COMBINER_TIMEOUT__SHIFT    28
+#define    HOST_PATH_CNTL__HP_TEST_RST_CNTL                     0x80000000
+#define    HOST_PATH_CNTL__HDP_WRITE_THROUGH_CACHE_DIS          0x00400000
+#define    HOST_PATH_CNTL__HDP_READ_BUFFER_INVALIDATE           0x08000000
+#define DST_PITCH_OFFSET                                    0x0000142C
+#define    DST_PITCH_OFFSET__DST_OFFSET__MASK                   0x003FFFFF
+#define    DST_PITCH_OFFSET__DST_OFFSET__SHIFT                  0
+#define    DST_PITCH_OFFSET__DST_PITCH__MASK                    0x3FC00000
+#define    DST_PITCH_OFFSET__DST_PITCH__SHIFT                   22
+#define    DST_PITCH_OFFSET__DST_TILE__MASK                     0xC0000000
+#define    DST_PITCH_OFFSET__DST_TILE__SHIFT                    30
+#define    DST_TILE__MACRO                                          0x1
+#define    DST_TILE__MICRO                                          0x2
+#define SRC_PITCH_OFFSET                                    0x00001428
+#define    SRC_PITCH_OFFSET__SRC_OFFSET__MASK                   0x003FFFFF
+#define    SRC_PITCH_OFFSET__SRC_OFFSET__SHIFT                  0
+#define    SRC_PITCH_OFFSET__SRC_PITCH__MASK                    0x3FC00000
+#define    SRC_PITCH_OFFSET__SRC_PITCH__SHIFT                   22
+#define    SRC_PITCH_OFFSET__SRC_TILE                           0x40000000
+#define DEFAULT_SC_BOTTOM_RIGHT                             0x000016E8
+#define    DEFAULT_SC_BOTTOM_RIGHT__DEFAULT_SC_RIGHT__MASK      0x00003FFF
+#define    DEFAULT_SC_BOTTOM_RIGHT__DEFAULT_SC_RIGHT__SHIFT     0
+#define    DEFAULT_SC_BOTTOM_RIGHT__DEFAULT_SC_BOTTOM__MASK     0x3FFF0000
+#define    DEFAULT_SC_BOTTOM_RIGHT__DEFAULT_SC_BOTTOM__SHIFT    16
+#define DEFAULT2_SC_BOTTOM_RIGHT                            0x000016DC
+#define    DEFAULT2_SC_BOTTOM_RIGHT__DEFAULT_SC_RIGHT__MASK     0x00003FFF
+#define    DEFAULT2_SC_BOTTOM_RIGHT__DEFAULT_SC_RIGHT__SHIFT    0
+#define    DEFAULT2_SC_BOTTOM_RIGHT__DEFAULT_SC_BOTTOM__MASK    0x3FFF0000
+#define    DEFAULT2_SC_BOTTOM_RIGHT__DEFAULT_SC_BOTTOM__SHIFT   16
+#define DP_DATATYPE                                         0x000016C4
+#define    DP_DATATYPE__DP_DST_DATATYPE__MASK                   0x0000000F
+#define    DP_DATATYPE__DP_DST_DATATYPE__SHIFT                  0
+#define    DP_DATATYPE__DP_BRUSH_DATATYPE__MASK                 0x00000F00
+#define    DP_DATATYPE__DP_BRUSH_DATATYPE__SHIFT                8
+#define    DP_DATATYPE__DP_SRC_DATATYPE__MASK                   0x00070000
+#define    DP_DATATYPE__DP_SRC_DATATYPE__SHIFT                  16
+#define    DP_DATATYPE__DP_BYTE_PIX_ORDER                       0x40000000
+#define DP_GUI_MASTER_CNTL                                  0x0000146C
+#define    DP_GUI_MASTER_CNTL__GMC_SRC_PITCH_OFFSET_CNTL        0x00000001
+#define    DP_GUI_MASTER_CNTL__GMC_DST_PITCH_OFFSET_CNTL        0x00000002
+#define    DP_GUI_MASTER_CNTL__GMC_SRC_CLIPPING                 0x00000004
+#define    DP_GUI_MASTER_CNTL__GMC_DST_CLIPPING                 0x00000008
+#define    DP_GUI_MASTER_CNTL__GMC_BRUSH_DATATYPE__MASK         0x000000F0
+#define    DP_GUI_MASTER_CNTL__GMC_BRUSH_DATATYPE__SHIFT        4
+#define    GMC_BRUSH_DATATYPE__8X8_MONO_FG_BG                       0x0
+#define    GMC_BRUSH_DATATYPE__8X8_MONO_FG                          0x1
+#define    GMC_BRUSH_DATATYPE__32X1_MONO_LINE_FG_BG                 0x6
+#define    GMC_BRUSH_DATATYPE__32X1_MONO_LINE_FG                    0x7
+#define    GMC_BRUSH_DATATYPE__8X8_COLOR                            0xA
+#define    GMC_BRUSH_DATATYPE__SOLID_COLOR_FG                       0xD
+#define    GMC_BRUSH_DATATYPE__SOLID_COLOR_RESERVED                 0xF
+#define    GMC_BRUSH_DATATYPE__SOLID                                0xD0
+#define    GMC_BRUSH_DATATYPE__MONO8x8                              0x0
+#define    GMC_BRUSH_DATATYPE__COLOR8x8                             0xA0
+#define    DP_GUI_MASTER_CNTL__GMC_DST_DATATYPE__MASK           0x00000F00
+#define    DP_GUI_MASTER_CNTL__GMC_DST_DATATYPE__SHIFT          8
+#define    GMC_DST_DATATYPE__8BPP_CLUT                              0x2
+#define    GMC_DST_DATATYPE__16BPP_1555                             0x3
+#define    GMC_DST_DATATYPE__16BPP_565                              0x4
+#define    GMC_DST_DATATYPE__32BPP_8888                             0x6
+#define    GMC_DST_DATATYPE__CI8                                    0x200
+#define    GMC_DST_DATATYPE__RGB16_1555                             0x300
+#define    GMC_DST_DATATYPE__RGB16_565                              0x400
+#define    GMC_DST_DATATYPE__RGB32                                  0x600
+#define    DP_GUI_MASTER_CNTL__GMC_SRC_DATATYPE__MASK           0x00003000
+#define    DP_GUI_MASTER_CNTL__GMC_SRC_DATATYPE__SHIFT          12
+#define    GMC_SRC_DATATYPE__BUILD(x)                               0x0
+#define    GMC_SRC_DATATYPE__MONO_OPAQUE                            0x0
+#define    GMC_SRC_DATATYPE__MONO_TRANSPARENT                       0x0
+#define    GMC_SRC_DATATYPE__SAME_AS_DST                            0x0
+#define    GMC_SRC_DATATYPE__8BPP_CLUT_XLAT                         0x0
+#define    GMC_SRC_DATATYPE__32BPP_CLUT_XLAT                        0x0
+#define    GMC_SRC_DATATYPE__MONO_FG_BG                             0x0
+#define    GMC_SRC_DATATYPE__MONO_FG                                0x1000
+#define    GMC_SRC_DATATYPE__COLOR                                  0x3000
+#define    GMC_SRC_DATATYPE__DST                                    0x3000
+#define    DP_GUI_MASTER_CNTL__GMC_BYTE_PIX_ORDER               0x00004000
+#define    DP_GUI_MASTER_CNTL__GMC_DEFAULT_SEL                  0x00008000
+#define    DP_GUI_MASTER_CNTL__GMC_ROP3__MASK                   0x00FF0000
+#define    DP_GUI_MASTER_CNTL__GMC_ROP3__SHIFT                  16
+#define    GMC_ROP3__SRCCPY                                         0xCC
+#define    GMC_ROP3__WHITENESS                                      0xFF
+#define    GMC_ROP3__BLACKNESS                                      0x0
+#define    DP_GUI_MASTER_CNTL__GMC_DP_SRC_SOURCE__MASK          0x07000000
+#define    DP_GUI_MASTER_CNTL__GMC_DP_SRC_SOURCE__SHIFT         24
+#define    GMC_DP_SRC_SOURCE__VIDEO_MEM                             0x2
+#define    GMC_DP_SRC_SOURCE__HOSTDATA                              0x3
+#define    GMC_DP_SRC_SOURCE__HOSTDATA_BYTE                         0x4
+#define    DP_GUI_MASTER_CNTL__GMC_SRC_DATATYPE2                0x08000000
+#define    DP_GUI_MASTER_CNTL__GMC_CLR_CMP_FCN_DIS              0x10000000
+#define    DP_GUI_MASTER_CNTL__GMC_WR_MSK_DIS                   0x40000000
+#define DP_BRUSH_FRGD_CLR                                   0x0000147C
+#define    DP_BRUSH_FRGD_CLR__DP_BRUSH_FRGD_CLR__MASK           0xFFFFFFFF
+#define    DP_BRUSH_FRGD_CLR__DP_BRUSH_FRGD_CLR__SHIFT          0
+#define DP_BRUSH_BKGD_CLR                                   0x00001478
+#define    DP_BRUSH_BKGD_CLR__DP_BRUSH_BKGD_CLR__MASK           0xFFFFFFFF
+#define    DP_BRUSH_BKGD_CLR__DP_BRUSH_BKGD_CLR__SHIFT          0
+#define DP_SRC_FRGD_CLR                                     0x000015D8
+#define    DP_SRC_FRGD_CLR__DP_SRC_FRGD_CLR__MASK               0xFFFFFFFF
+#define    DP_SRC_FRGD_CLR__DP_SRC_FRGD_CLR__SHIFT              0
+#define DP_SRC_BKGD_CLR                                     0x000015DC
+#define    DP_SRC_BKGD_CLR__DP_SRC_BKGD_CLR__MASK               0xFFFFFFFF
+#define    DP_SRC_BKGD_CLR__DP_SRC_BKGD_CLR__SHIFT              0
+#define DP_WRITE_MSK                                        0x000016CC
+#define    DP_WRITE_MSK__DP_WRITE_MSK__MASK                     0xFFFFFFFF
+#define    DP_WRITE_MSK__DP_WRITE_MSK__SHIFT                    0
+
+#endif
diff --git a/shared-core/radeon_ms_state.c b/shared-core/radeon_ms_state.c
new file mode 100644 (file)
index 0000000..17f8b76
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 Jérôme Glisse
+ * 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
+ * PRECISION INSIGHT 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.
+ *
+ * Authors:
+ *    Jerome Glisse <glisse@freedesktop.org>
+ */
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_ms.h"
+
+void radeon_ms_state_restore(struct drm_device *dev, struct radeon_state *state)
+{
+       radeon_ms_irq_restore(dev, state);
+       radeon_ms_gpu_restore(dev, state);
+       radeon_ms_cp_restore(dev, state);
+       radeon_ms_crtc1_restore(dev, state);
+}
+
+void radeon_ms_state_save(struct drm_device *dev, struct radeon_state *state)
+{
+       radeon_ms_crtc1_save(dev, state);
+       radeon_ms_cp_save(dev, state);
+       radeon_ms_gpu_save(dev, state);
+       radeon_ms_irq_save(dev, state);
+}