svn commit: r189499 - in head/sys: conf dev/drm modules/drm/radeon

Robert Noland rnoland at FreeBSD.org
Sat Mar 7 13:36:58 PST 2009


Author: rnoland
Date: Sat Mar  7 21:36:57 2009
New Revision: 189499
URL: http://svn.freebsd.org/changeset/base/189499

Log:
  Import support for ATI Radeon R600 and R700 series chips.
  
  Tested on an HD3850 (RV670) on loan from Warren Block.
  
  Currently, you need one of the following for this to be useful:
  
  	x11-drivers/xf86-video-radeonhd-devel (not tested)
  	xf86-video-ati from git (EXA works, xv is too fast)
  	xf86-video-radeonhd from git (EXA works, xv works)
  
  There is no 3d support available from dri just yet.
  
  MFC after:	2 weeks

Added:
  head/sys/dev/drm/r600_cp.c   (contents, props changed)
  head/sys/dev/drm/r600_microcode.h   (contents, props changed)
Modified:
  head/sys/conf/files
  head/sys/dev/drm/drm_pciids.h
  head/sys/dev/drm/radeon_cp.c
  head/sys/dev/drm/radeon_drm.h
  head/sys/dev/drm/radeon_drv.h
  head/sys/dev/drm/radeon_irq.c
  head/sys/dev/drm/radeon_state.c
  head/sys/modules/drm/radeon/Makefile

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Sat Mar  7 20:39:42 2009	(r189498)
+++ head/sys/conf/files	Sat Mar  7 21:36:57 2009	(r189499)
@@ -801,6 +801,7 @@ dev/drm/r128_irq.c		optional r128drm
 dev/drm/r128_state.c		optional r128drm \
 	compile-with "${NORMAL_C} -finline-limit=13500"
 dev/drm/r300_cmdbuf.c		optional radeondrm
+dev/drm/r600_cp.c		optional radeondrm
 dev/drm/radeon_cp.c		optional radeondrm
 dev/drm/radeon_drv.c		optional radeondrm
 dev/drm/radeon_irq.c		optional radeondrm

Modified: head/sys/dev/drm/drm_pciids.h
==============================================================================
--- head/sys/dev/drm/drm_pciids.h	Sat Mar  7 20:39:42 2009	(r189498)
+++ head/sys/dev/drm/drm_pciids.h	Sat Mar  7 21:36:57 2009	(r189499)
@@ -240,12 +240,123 @@
 	{0x1002, 0x7297, CHIP_RV560|RADEON_NEW_MEMMAP, "ATI RV560"}, \
 	{0x1002, 0x7834, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP, "ATI Radeon RS350 9000/9100 IGP"}, \
 	{0x1002, 0x7835, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Radeon RS350 Mobility IGP"}, \
+	{0x1002, 0x793f, CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP, "ATI Radeon X1200"}, \
+	{0x1002, 0x7941, CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP, "ATI Radeon X1200"}, \
+	{0x1002, 0x7942, CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP, "ATI Radeon X1200"}, \
 	{0x1002, 0x791e, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS690 X1250 IGP"}, \
 	{0x1002, 0x791f, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS690 X1270 IGP"}, \
 	{0x1002, 0x796c, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS740 HD2100 IGP"}, \
 	{0x1002, 0x796d, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS740 HD2100 IGP"}, \
 	{0x1002, 0x796e, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS740 HD2100 IGP"}, \
 	{0x1002, 0x796f, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS740 HD2100 IGP"}, \
+	{0x1002, 0x9400, CHIP_R600|RADEON_NEW_MEMMAP, "ATI Radeon HD 2900 XT"}, \
+	{0x1002, 0x9401, CHIP_R600|RADEON_NEW_MEMMAP, "ATI Radeon HD 2900 XT"}, \
+	{0x1002, 0x9402, CHIP_R600|RADEON_NEW_MEMMAP, "ATI Radeon HD 2900 XT"}, \
+	{0x1002, 0x9403, CHIP_R600|RADEON_NEW_MEMMAP, "ATI Radeon HD 2900 Pro"}, \
+	{0x1002, 0x9405, CHIP_R600|RADEON_NEW_MEMMAP, "ATI Radeon HD 2900 GT"}, \
+	{0x1002, 0x940A, CHIP_R600|RADEON_NEW_MEMMAP, "ATI FireGL V8650"}, \
+	{0x1002, 0x940B, CHIP_R600|RADEON_NEW_MEMMAP, "ATI FireGL V8600"}, \
+	{0x1002, 0x940F, CHIP_R600|RADEON_NEW_MEMMAP, "ATI FireGL V7600"}, \
+	{0x1002, 0x94C0, CHIP_RV610|RADEON_NEW_MEMMAP, "RV610"}, \
+	{0x1002, 0x94C1, CHIP_RV610|RADEON_NEW_MEMMAP, "Radeon HD 2400 XT"}, \
+	{0x1002, 0x94C3, CHIP_RV610|RADEON_NEW_MEMMAP, "Radeon HD 2400 Pro"}, \
+	{0x1002, 0x94C4, CHIP_RV610|RADEON_NEW_MEMMAP, "Radeon HD 2400 PRO AGP"}, \
+	{0x1002, 0x94C5, CHIP_RV610|RADEON_NEW_MEMMAP, "FireGL V4000"}, \
+	{0x1002, 0x94C6, CHIP_RV610|RADEON_NEW_MEMMAP, "RV610"}, \
+	{0x1002, 0x94C7, CHIP_RV610|RADEON_NEW_MEMMAP, "ATI Radeon HD 2350"}, \
+	{0x1002, 0x94C8, CHIP_RV610|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 2400 XT"}, \
+	{0x1002, 0x94C9, CHIP_RV610|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 2400"}, \
+	{0x1002, 0x94CB, CHIP_RV610|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI RADEON E2400"}, \
+	{0x1002, 0x94CC, CHIP_RV610|RADEON_NEW_MEMMAP, "ATI RV610"}, \
+	{0x1002, 0x94CD, CHIP_RV610|RADEON_NEW_MEMMAP, "ATI FireMV 2260"}, \
+	{0x1002, 0x9500, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI RV670"}, \
+	{0x1002, 0x9501, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI Radeon HD3870"}, \
+	{0x1002, 0x9504, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3850"}, \
+	{0x1002, 0x9505, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI Radeon HD3850"}, \
+	{0x1002, 0x9506, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3850 X2"}, \
+	{0x1002, 0x9507, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI RV670"}, \
+	{0x1002, 0x9508, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3870"}, \
+	{0x1002, 0x9509, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3870 X2"}, \
+	{0x1002, 0x950F, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI Radeon HD3870 X2"}, \
+	{0x1002, 0x9511, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI FireGL V7700"}, \
+	{0x1002, 0x9515, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI Radeon HD3850"}, \
+	{0x1002, 0x9517, CHIP_RV670|RADEON_NEW_MEMMAP, "ATI Radeon HD3690"}, \
+	{0x1002, 0x9519, CHIP_RV670|RADEON_NEW_MEMMAP, "AMD Firestream 9170"}, \
+	{0x1002, 0x9580, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI RV630"}, \
+	{0x1002, 0x9581, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 2600"}, \
+	{0x1002, 0x9583, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 2600 XT"}, \
+	{0x1002, 0x9586, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Radeon HD 2600 XT AGP"}, \
+	{0x1002, 0x9587, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Radeon HD 2600 Pro AGP"}, \
+	{0x1002, 0x9588, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Radeon HD 2600 XT"}, \
+	{0x1002, 0x9589, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Radeon HD 2600 Pro"}, \
+	{0x1002, 0x958A, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Gemini RV630"}, \
+	{0x1002, 0x958B, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Gemini Mobility Radeon HD 2600 XT"}, \
+	{0x1002, 0x958C, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI FireGL V5600"}, \
+	{0x1002, 0x958D, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI FireGL V3600"}, \
+	{0x1002, 0x958E, CHIP_RV630|RADEON_NEW_MEMMAP, "ATI Radeon HD 2600 LE"}, \
+	{0x1002, 0x958F, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL Graphics Processor"}, \
+	{0x1002, 0x95C0, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI Radeon HD 3470"}, \
+	{0x1002, 0x95C5, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI Radeon HD 3450"}, \
+	{0x1002, 0x95C6, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI Radeon HD 3450"}, \
+	{0x1002, 0x95C7, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI Radeon HD 3430"}, \
+	{0x1002, 0x95C9, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI Radeon HD 3450"}, \
+	{0x1002, 0x95C2, CHIP_RV620|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3430"}, \
+	{0x1002, 0x95C4, CHIP_RV620|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3400 Series"}, \
+	{0x1002, 0x95CC, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI FirePro V3700"}, \
+	{0x1002, 0x95CD, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI FireMV 2450"}, \
+	{0x1002, 0x95CE, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI FireMV 2260"}, \
+	{0x1002, 0x95CF, CHIP_RV620|RADEON_NEW_MEMMAP, "ATI FireMV 2260"}, \
+	{0x1002, 0x9590, CHIP_RV635|RADEON_NEW_MEMMAP, "ATI ATI Radeon HD 3600 Series"}, \
+	{0x1002, 0x9596, CHIP_RV635|RADEON_NEW_MEMMAP, "ATI ATI Radeon HD 3650 AGP"}, \
+	{0x1002, 0x9597, CHIP_RV635|RADEON_NEW_MEMMAP, "ATI ATI Radeon HD 3600 PRO"}, \
+	{0x1002, 0x9598, CHIP_RV635|RADEON_NEW_MEMMAP, "ATI ATI Radeon HD 3600 XT"}, \
+	{0x1002, 0x9599, CHIP_RV635|RADEON_NEW_MEMMAP, "ATI ATI Radeon HD 3600 PRO"}, \
+	{0x1002, 0x9591, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3650"}, \
+	{0x1002, 0x9593, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 3670"}, \
+	{0x1002, 0x9595, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V5700"}, \
+	{0x1002, 0x959B, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V5725"}, \
+	{0x1002, 0x9610, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon HD 3200 Graphics"}, \
+	{0x1002, 0x9611, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon 3100 Graphics"}, \
+	{0x1002, 0x9612, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon HD 3200 Graphics"}, \
+	{0x1002, 0x9613, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon 3100 Graphics"}, \
+	{0x1002, 0x9614, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP, "ATI Radeon 3300 Graphics"}, \
+	{0x1002, 0x9440, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \
+	{0x1002, 0x9441, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4870 X2"}, \
+	{0x1002, 0x9442, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \
+	{0x1002, 0x944C, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI Radeon 4800 Series"}, \
+	{0x1002, 0x9450, CHIP_RV770|RADEON_NEW_MEMMAP, "AMD FireStream 9270"}, \
+	{0x1002, 0x9452, CHIP_RV770|RADEON_NEW_MEMMAP, "AMD FireStream 9250"}, \
+	{0x1002, 0x9444, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI FirePro V8750 (FireGL)"}, \
+	{0x1002, 0x9446, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI FirePro V7760 (FireGL)"}, \
+	{0x1002, 0x9456, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI FirePro V8700 (FireGL)"}, \
+	{0x1002, 0x944E, CHIP_RV770|RADEON_NEW_MEMMAP, "ATI FirePro RV770"}, \
+	{0x1002, 0x944A, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4850"}, \
+	{0x1002, 0x944B, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4850 X2"}, \
+	{0x1002, 0x945A, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4870"}, \
+	{0x1002, 0x945B, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon M98"}, \
+	{0x1002, 0x946A, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI FirePro M7750"}, \
+	{0x1002, 0x946B, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI M98"}, \
+	{0x1002, 0x947A, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI M98"}, \
+	{0x1002, 0x947B, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI M98"}, \
+	{0x1002, 0x9487, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon RV730 (AGP)"}, \
+	{0x1002, 0x948F, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon RV730 (AGP)"}, \
+	{0x1002, 0x9490, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon HD 4670"}, \
+	{0x1002, 0x9498, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI Radeon HD 4650"}, \
+	{0x1002, 0x9480, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4650"}, \
+	{0x1002, 0x9488, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 4670"}, \
+	{0x1002, 0x9489, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI FirePro M5750"}, \
+	{0x1002, 0x9491, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI RADEON E4600"}, \
+	{0x1002, 0x949C, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI FirePro V7750 (FireGL)"}, \
+	{0x1002, 0x949E, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI FirePro V5700 (FireGL)"}, \
+	{0x1002, 0x949F, CHIP_RV730|RADEON_NEW_MEMMAP, "ATI FirePro V3750 (FireGL)"}, \
+	{0x1002, 0x9540, CHIP_RV710|RADEON_NEW_MEMMAP, "ATI Radeon HD 4550"}, \
+	{0x1002, 0x9541, CHIP_RV710|RADEON_NEW_MEMMAP, "ATI Radeon RV710"}, \
+	{0x1002, 0x9542, CHIP_RV710|RADEON_NEW_MEMMAP, "ATI Radeon RV710"}, \
+	{0x1002, 0x954E, CHIP_RV710|RADEON_NEW_MEMMAP, "ATI Radeon RV710"}, \
+	{0x1002, 0x954F, CHIP_RV710|RADEON_NEW_MEMMAP, "ATI Radeon HD 4350"}, \
+	{0x1002, 0x9552, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon 4300 Series"}, \
+	{0x1002, 0x9553, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon 4500 Series"}, \
+	{0x1002, 0x9555, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon 4500 Series"}, \
 	{0, 0, 0, NULL}
 
 #define r128_PCI_IDS \

Added: head/sys/dev/drm/r600_cp.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/drm/r600_cp.c	Sat Mar  7 21:36:57 2009	(r189499)
@@ -0,0 +1,2258 @@
+/*-
+ * Copyright 2008-2009 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *     Dave Airlie <airlied at redhat.com>
+ *     Alex Deucher <alexander.deucher at amd.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "dev/drm/drmP.h"
+#include "dev/drm/drm.h"
+#include "dev/drm/radeon_drm.h"
+#include "dev/drm/radeon_drv.h"
+
+#include "dev/drm/r600_microcode.h"
+
+# define ATI_PCIGART_PAGE_SIZE		4096	/**< PCI GART page size */
+# define ATI_PCIGART_PAGE_MASK		(~(ATI_PCIGART_PAGE_SIZE-1))
+
+#define R600_PTE_VALID     (1 << 0)
+#define R600_PTE_SYSTEM    (1 << 1)
+#define R600_PTE_SNOOPED   (1 << 2)
+#define R600_PTE_READABLE  (1 << 5)
+#define R600_PTE_WRITEABLE (1 << 6)
+
+/* MAX values used for gfx init */
+#define R6XX_MAX_SH_GPRS           256
+#define R6XX_MAX_TEMP_GPRS         16
+#define R6XX_MAX_SH_THREADS        256
+#define R6XX_MAX_SH_STACK_ENTRIES  4096
+#define R6XX_MAX_BACKENDS          8
+#define R6XX_MAX_BACKENDS_MASK     0xff
+#define R6XX_MAX_SIMDS             8
+#define R6XX_MAX_SIMDS_MASK        0xff
+#define R6XX_MAX_PIPES             8
+#define R6XX_MAX_PIPES_MASK        0xff
+
+#define R7XX_MAX_SH_GPRS           256
+#define R7XX_MAX_TEMP_GPRS         16
+#define R7XX_MAX_SH_THREADS        256
+#define R7XX_MAX_SH_STACK_ENTRIES  4096
+#define R7XX_MAX_BACKENDS          8
+#define R7XX_MAX_BACKENDS_MASK     0xff
+#define R7XX_MAX_SIMDS             16
+#define R7XX_MAX_SIMDS_MASK        0xffff
+#define R7XX_MAX_PIPES             8
+#define R7XX_MAX_PIPES_MASK        0xff
+
+static int r600_do_wait_for_fifo(drm_radeon_private_t *dev_priv, int entries)
+{
+	int i;
+
+	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+
+	for (i = 0; i < dev_priv->usec_timeout; i++) {
+		int slots;
+		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+			slots = (RADEON_READ(R600_GRBM_STATUS)
+				 & R700_CMDFIFO_AVAIL_MASK);
+		else
+			slots = (RADEON_READ(R600_GRBM_STATUS)
+				 & R600_CMDFIFO_AVAIL_MASK);
+		if (slots >= entries)
+			return 0;
+		DRM_UDELAY(1);
+	}
+	DRM_INFO("wait for fifo failed status : 0x%08X 0x%08X\n",
+		 RADEON_READ(R600_GRBM_STATUS),
+		 RADEON_READ(R600_GRBM_STATUS2));
+
+	return -EBUSY;
+}
+
+static int r600_do_wait_for_idle(drm_radeon_private_t *dev_priv)
+{
+	int i, ret;
+
+	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+		ret = r600_do_wait_for_fifo(dev_priv, 8);
+	else
+		ret = r600_do_wait_for_fifo(dev_priv, 16);
+	if (ret)
+		return ret;
+	for (i = 0; i < dev_priv->usec_timeout; i++) {
+		if (!(RADEON_READ(R600_GRBM_STATUS) & R600_GUI_ACTIVE))
+			return 0;
+		DRM_UDELAY(1);
+	}
+	DRM_INFO("wait idle failed status : 0x%08X 0x%08X\n",
+		 RADEON_READ(R600_GRBM_STATUS),
+		 RADEON_READ(R600_GRBM_STATUS2));
+
+	return -EBUSY;
+}
+
+void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info)
+{
+#ifdef __linux__
+	struct drm_sg_mem *entry = dev->sg;
+	int max_pages;
+	int pages;
+	int i;
+#endif
+	if (gart_info->bus_addr) {
+#ifdef __linux__
+		max_pages = (gart_info->table_size / sizeof(u32));
+		pages = (entry->pages <= max_pages)
+		  ? entry->pages : max_pages;
+
+		for (i = 0; i < pages; i++) {
+			if (!entry->busaddr[i])
+				break;
+			pci_unmap_single(dev->pdev, entry->busaddr[i],
+					 PAGE_SIZE, PCI_DMA_TODEVICE);
+		}
+#endif
+		if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
+			gart_info->bus_addr = 0;
+	}
+}
+
+/* R600 has page table setup */
+int r600_page_table_init(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info;
+	struct drm_sg_mem *entry = dev->sg;
+	int ret = 0;
+	int i, j;
+	int max_pages, pages;
+	u64 *pci_gart, page_base;
+	dma_addr_t entry_addr;
+
+	/* okay page table is available - lets rock */
+
+	/* PTEs are 64-bits */
+	pci_gart = (u64 *)gart_info->addr;
+
+	max_pages = (gart_info->table_size / sizeof(u64));
+	pages = (entry->pages <= max_pages) ? entry->pages : max_pages;
+
+	memset(pci_gart, 0, max_pages * sizeof(u64));
+
+	for (i = 0; i < pages; i++) {
+#ifdef __linux__
+		entry->busaddr[i] = pci_map_single(dev->pdev,
+						   page_address(entry->
+								pagelist[i]),
+						   PAGE_SIZE, PCI_DMA_TODEVICE);
+		if (entry->busaddr[i] == 0) {
+			DRM_ERROR("unable to map PCIGART pages!\n");
+			r600_page_table_cleanup(dev, gart_info);
+			ret = -EINVAL;
+			goto done;
+		}
+#endif
+		entry_addr = entry->busaddr[i];
+		for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
+			page_base = (u64) entry_addr & ATI_PCIGART_PAGE_MASK;
+			page_base |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED;
+			page_base |= R600_PTE_READABLE | R600_PTE_WRITEABLE;
+
+			*pci_gart = page_base;
+
+			if ((i % 128) == 0)
+				DRM_DEBUG("page entry %d: 0x%016llx\n",
+				    i, (unsigned long long)page_base);
+			pci_gart++;
+			entry_addr += ATI_PCIGART_PAGE_SIZE;
+		}
+	}
+#ifdef __linux__
+done:
+#endif
+	return ret;
+}
+
+static void r600_vm_flush_gart_range(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	u32 resp, countdown = 1000;
+	RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR, dev_priv->gart_vm_start >> 12);
+	RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+	RADEON_WRITE(R600_VM_CONTEXT0_REQUEST_RESPONSE, 2);
+
+	do {
+		resp = RADEON_READ(R600_VM_CONTEXT0_REQUEST_RESPONSE);
+		countdown--;
+		DRM_UDELAY(1);
+	} while (((resp & 0xf0) == 0) && countdown);
+}
+
+static void r600_vm_init(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	/* initialise the VM to use the page table we constructed up there */
+	u32 vm_c0, i;
+	u32 mc_rd_a;
+	u32 vm_l2_cntl, vm_l2_cntl3;
+	/* okay set up the PCIE aperture type thingo */
+	RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12);
+	RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+	RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
+
+	/* setup MC RD a */
+	mc_rd_a = R600_MCD_L1_TLB | R600_MCD_L1_FRAG_PROC | R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS |
+		R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | R600_MCD_EFFECTIVE_L1_TLB_SIZE(5) |
+		R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(5) | R600_MCD_WAIT_L2_QUERY;
+
+	RADEON_WRITE(R600_MCD_RD_A_CNTL, mc_rd_a);
+	RADEON_WRITE(R600_MCD_RD_B_CNTL, mc_rd_a);
+
+	RADEON_WRITE(R600_MCD_WR_A_CNTL, mc_rd_a);
+	RADEON_WRITE(R600_MCD_WR_B_CNTL, mc_rd_a);
+
+	RADEON_WRITE(R600_MCD_RD_GFX_CNTL, mc_rd_a);
+	RADEON_WRITE(R600_MCD_WR_GFX_CNTL, mc_rd_a);
+
+	RADEON_WRITE(R600_MCD_RD_SYS_CNTL, mc_rd_a);
+	RADEON_WRITE(R600_MCD_WR_SYS_CNTL, mc_rd_a);
+
+	RADEON_WRITE(R600_MCD_RD_HDP_CNTL, mc_rd_a | R600_MCD_L1_STRICT_ORDERING);
+	RADEON_WRITE(R600_MCD_WR_HDP_CNTL, mc_rd_a /*| R600_MCD_L1_STRICT_ORDERING*/);
+
+	RADEON_WRITE(R600_MCD_RD_PDMA_CNTL, mc_rd_a);
+	RADEON_WRITE(R600_MCD_WR_PDMA_CNTL, mc_rd_a);
+
+	RADEON_WRITE(R600_MCD_RD_SEM_CNTL, mc_rd_a | R600_MCD_SEMAPHORE_MODE);
+	RADEON_WRITE(R600_MCD_WR_SEM_CNTL, mc_rd_a);
+
+	vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W;
+	vm_l2_cntl |= R600_VM_L2_CNTL_QUEUE_SIZE(7);
+	RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl);
+
+	RADEON_WRITE(R600_VM_L2_CNTL2, 0);
+	vm_l2_cntl3 = (R600_VM_L2_CNTL3_BANK_SELECT_0(0) |
+		       R600_VM_L2_CNTL3_BANK_SELECT_1(1) |
+		       R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(2));
+	RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3);
+
+	vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT;
+
+	RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0);
+
+	vm_c0 &= ~R600_VM_ENABLE_CONTEXT;
+
+	/* disable all other contexts */
+	for (i = 1; i < 8; i++)
+		RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0);
+
+	RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12);
+	RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12);
+	RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+
+	r600_vm_flush_gart_range(dev);
+}
+
+/* load r600 microcode */
+static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv)
+{
+	int i;
+
+	r600_do_cp_stop(dev_priv);
+
+	RADEON_WRITE(R600_CP_RB_CNTL,
+		     R600_RB_NO_UPDATE |
+		     R600_RB_BLKSZ(15) |
+		     R600_RB_BUFSZ(3));
+
+	RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
+	RADEON_READ(R600_GRBM_SOFT_RESET);
+	DRM_UDELAY(15000);
+	RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
+
+	RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+
+	if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600)) {
+		DRM_INFO("Loading R600 CP Microcode\n");
+		for (i = 0; i < PM4_UCODE_SIZE; i++) {
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     R600_cp_microcode[i][0]);
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     R600_cp_microcode[i][1]);
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     R600_cp_microcode[i][2]);
+		}
+
+		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+		DRM_INFO("Loading R600 PFP Microcode\n");
+		for (i = 0; i < PFP_UCODE_SIZE; i++)
+			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, R600_pfp_microcode[i]);
+	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610)) {
+		DRM_INFO("Loading RV610 CP Microcode\n");
+		for (i = 0; i < PM4_UCODE_SIZE; i++) {
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV610_cp_microcode[i][0]);
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV610_cp_microcode[i][1]);
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV610_cp_microcode[i][2]);
+		}
+
+		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+		DRM_INFO("Loading RV610 PFP Microcode\n");
+		for (i = 0; i < PFP_UCODE_SIZE; i++)
+			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV610_pfp_microcode[i]);
+	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) {
+		DRM_INFO("Loading RV630 CP Microcode\n");
+		for (i = 0; i < PM4_UCODE_SIZE; i++) {
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV630_cp_microcode[i][0]);
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV630_cp_microcode[i][1]);
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV630_cp_microcode[i][2]);
+		}
+
+		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+		DRM_INFO("Loading RV630 PFP Microcode\n");
+		for (i = 0; i < PFP_UCODE_SIZE; i++)
+			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV630_pfp_microcode[i]);
+	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620)) {
+		DRM_INFO("Loading RV620 CP Microcode\n");
+		for (i = 0; i < PM4_UCODE_SIZE; i++) {
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV620_cp_microcode[i][0]);
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV620_cp_microcode[i][1]);
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV620_cp_microcode[i][2]);
+		}
+
+		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+		DRM_INFO("Loading RV620 PFP Microcode\n");
+		for (i = 0; i < PFP_UCODE_SIZE; i++)
+			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV620_pfp_microcode[i]);
+	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) {
+		DRM_INFO("Loading RV635 CP Microcode\n");
+		for (i = 0; i < PM4_UCODE_SIZE; i++) {
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV635_cp_microcode[i][0]);
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV635_cp_microcode[i][1]);
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV635_cp_microcode[i][2]);
+		}
+
+		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+		DRM_INFO("Loading RV635 PFP Microcode\n");
+		for (i = 0; i < PFP_UCODE_SIZE; i++)
+			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV635_pfp_microcode[i]);
+	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670)) {
+		DRM_INFO("Loading RV670 CP Microcode\n");
+		for (i = 0; i < PM4_UCODE_SIZE; i++) {
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV670_cp_microcode[i][0]);
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV670_cp_microcode[i][1]);
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV670_cp_microcode[i][2]);
+		}
+
+		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+		DRM_INFO("Loading RV670 PFP Microcode\n");
+		for (i = 0; i < PFP_UCODE_SIZE; i++)
+			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]);
+	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) {
+		DRM_INFO("Loading RS780 CP Microcode\n");
+		for (i = 0; i < PM4_UCODE_SIZE; i++) {
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV670_cp_microcode[i][0]);
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV670_cp_microcode[i][1]);
+			RADEON_WRITE(R600_CP_ME_RAM_DATA,
+				     RV670_cp_microcode[i][2]);
+		}
+
+		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+		DRM_INFO("Loading RS780 PFP Microcode\n");
+		for (i = 0; i < PFP_UCODE_SIZE; i++)
+			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]);
+	}
+	RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+	RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+	RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0);
+
+}
+
+static void r700_vm_init(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	/* initialise the VM to use the page table we constructed up there */
+	u32 vm_c0, i;
+	u32 mc_vm_md_l1;
+	u32 vm_l2_cntl, vm_l2_cntl3;
+	/* okay set up the PCIE aperture type thingo */
+	RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12);
+	RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+	RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
+
+	mc_vm_md_l1 = R700_ENABLE_L1_TLB |
+	    R700_ENABLE_L1_FRAGMENT_PROCESSING |
+	    R700_SYSTEM_ACCESS_MODE_IN_SYS |
+	    R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
+	    R700_EFFECTIVE_L1_TLB_SIZE(5) |
+	    R700_EFFECTIVE_L1_QUEUE_SIZE(5);
+
+	RADEON_WRITE(R700_MC_VM_MD_L1_TLB0_CNTL, mc_vm_md_l1);
+	RADEON_WRITE(R700_MC_VM_MD_L1_TLB1_CNTL, mc_vm_md_l1);
+	RADEON_WRITE(R700_MC_VM_MD_L1_TLB2_CNTL, mc_vm_md_l1);
+	RADEON_WRITE(R700_MC_VM_MB_L1_TLB0_CNTL, mc_vm_md_l1);
+	RADEON_WRITE(R700_MC_VM_MB_L1_TLB1_CNTL, mc_vm_md_l1);
+	RADEON_WRITE(R700_MC_VM_MB_L1_TLB2_CNTL, mc_vm_md_l1);
+	RADEON_WRITE(R700_MC_VM_MB_L1_TLB3_CNTL, mc_vm_md_l1);
+
+	vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W;
+	vm_l2_cntl |= R700_VM_L2_CNTL_QUEUE_SIZE(7);
+	RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl);
+
+	RADEON_WRITE(R600_VM_L2_CNTL2, 0);
+	vm_l2_cntl3 = R700_VM_L2_CNTL3_BANK_SELECT(0) | R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(2);
+	RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3);
+
+	vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT;
+
+	RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0);
+
+	vm_c0 &= ~R600_VM_ENABLE_CONTEXT;
+
+	/* disable all other contexts */
+	for (i = 1; i < 8; i++)
+		RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0);
+
+	RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12);
+	RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12);
+	RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+
+	r600_vm_flush_gart_range(dev);
+}
+
+/* load r600 microcode */
+static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv)
+{
+	int i;
+
+	r600_do_cp_stop(dev_priv);
+
+	RADEON_WRITE(R600_CP_RB_CNTL,
+		     R600_RB_NO_UPDATE |
+		     (15 << 8) |
+		     (3 << 0));
+
+	RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
+	RADEON_READ(R600_GRBM_SOFT_RESET);
+	DRM_UDELAY(15000);
+	RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
+
+
+	if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770)) {
+		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+		DRM_INFO("Loading RV770 PFP Microcode\n");
+		for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
+			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV770_pfp_microcode[i]);
+		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+
+		RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+		DRM_INFO("Loading RV770 CP Microcode\n");
+		for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
+			RADEON_WRITE(R600_CP_ME_RAM_DATA, RV770_cp_microcode[i]);
+		RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+
+	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV730)) {
+		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+		DRM_INFO("Loading RV730 PFP Microcode\n");
+		for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
+			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV730_pfp_microcode[i]);
+		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+
+		RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+		DRM_INFO("Loading RV730 CP Microcode\n");
+		for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
+			RADEON_WRITE(R600_CP_ME_RAM_DATA, RV730_cp_microcode[i]);
+		RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+
+	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) {
+		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+		DRM_INFO("Loading RV710 PFP Microcode\n");
+		for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
+			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV710_pfp_microcode[i]);
+		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+
+		RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+		DRM_INFO("Loading RV710 CP Microcode\n");
+		for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
+			RADEON_WRITE(R600_CP_ME_RAM_DATA, RV710_cp_microcode[i]);
+		RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+
+	}
+	RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+	RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+	RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0);
+
+}
+
+static void r600_test_writeback(drm_radeon_private_t *dev_priv)
+{
+	u32 tmp;
+
+	/* Start with assuming that writeback doesn't work */
+	dev_priv->writeback_works = 0;
+
+	/* Writeback doesn't seem to work everywhere, test it here and possibly
+	 * enable it if it appears to work
+	 */
+	radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0);
+
+	RADEON_WRITE(R600_SCRATCH_REG1, 0xdeadbeef);
+
+	for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
+		u32 val;
+
+		val = radeon_read_ring_rptr(dev_priv, R600_SCRATCHOFF(1));
+		if (val == 0xdeadbeef)
+			break;
+		DRM_UDELAY(1);
+	}
+
+	if (tmp < dev_priv->usec_timeout) {
+		dev_priv->writeback_works = 1;
+		DRM_INFO("writeback test succeeded in %d usecs\n", tmp);
+	} else {
+		dev_priv->writeback_works = 0;
+		DRM_INFO("writeback test failed\n");
+	}
+	if (radeon_no_wb == 1) {
+		dev_priv->writeback_works = 0;
+		DRM_INFO("writeback forced off\n");
+	}
+
+	if (!dev_priv->writeback_works) {
+		/* Disable writeback to avoid unnecessary bus master transfer */
+		RADEON_WRITE(R600_CP_RB_CNTL, RADEON_READ(R600_CP_RB_CNTL) |
+			     RADEON_RB_NO_UPDATE);
+		RADEON_WRITE(R600_SCRATCH_UMSK, 0);
+	}
+}
+
+int r600_do_engine_reset(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	u32 cp_ptr, cp_me_cntl, cp_rb_cntl;
+
+	DRM_INFO("Resetting GPU\n");
+
+	cp_ptr = RADEON_READ(R600_CP_RB_WPTR);
+	cp_me_cntl = RADEON_READ(R600_CP_ME_CNTL);
+	RADEON_WRITE(R600_CP_ME_CNTL, R600_CP_ME_HALT);
+
+	RADEON_WRITE(R600_GRBM_SOFT_RESET, 0x7fff);
+	RADEON_READ(R600_GRBM_SOFT_RESET);
+	DRM_UDELAY(50);
+	RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
+	RADEON_READ(R600_GRBM_SOFT_RESET);
+
+	RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0);
+	cp_rb_cntl = RADEON_READ(R600_CP_RB_CNTL);
+	RADEON_WRITE(R600_CP_RB_CNTL, R600_RB_RPTR_WR_ENA);
+
+	RADEON_WRITE(R600_CP_RB_RPTR_WR, cp_ptr);
+	RADEON_WRITE(R600_CP_RB_WPTR, cp_ptr);
+	RADEON_WRITE(R600_CP_RB_CNTL, cp_rb_cntl);
+	RADEON_WRITE(R600_CP_ME_CNTL, cp_me_cntl);
+
+	/* Reset the CP ring */
+	r600_do_cp_reset(dev_priv);
+
+	/* The CP is no longer running after an engine reset */
+	dev_priv->cp_running = 0;
+
+	/* Reset any pending vertex, indirect buffers */
+	radeon_freelist_reset(dev);
+
+	return 0;
+
+}
+
+static u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
+					     u32 num_backends,
+					     u32 backend_disable_mask)
+{
+	u32 backend_map = 0;
+	u32 enabled_backends_mask;
+	u32 enabled_backends_count;
+	u32 cur_pipe;
+	u32 swizzle_pipe[R6XX_MAX_PIPES];
+	u32 cur_backend;
+	u32 i;
+
+	if (num_tile_pipes > R6XX_MAX_PIPES)
+		num_tile_pipes = R6XX_MAX_PIPES;
+	if (num_tile_pipes < 1)
+		num_tile_pipes = 1;
+	if (num_backends > R6XX_MAX_BACKENDS)
+		num_backends = R6XX_MAX_BACKENDS;
+	if (num_backends < 1)
+		num_backends = 1;
+
+	enabled_backends_mask = 0;
+	enabled_backends_count = 0;
+	for (i = 0; i < R6XX_MAX_BACKENDS; ++i) {
+		if (((backend_disable_mask >> i) & 1) == 0) {
+			enabled_backends_mask |= (1 << i);
+			++enabled_backends_count;
+		}
+		if (enabled_backends_count == num_backends)
+			break;
+	}
+
+	if (enabled_backends_count == 0) {
+		enabled_backends_mask = 1;
+		enabled_backends_count = 1;
+	}
+
+	if (enabled_backends_count != num_backends)
+		num_backends = enabled_backends_count;
+
+	memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES);
+	switch (num_tile_pipes) {
+	case 1:
+		swizzle_pipe[0] = 0;
+		break;
+	case 2:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 1;
+		break;
+	case 3:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 1;
+		swizzle_pipe[2] = 2;
+		break;
+	case 4:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 1;
+		swizzle_pipe[2] = 2;
+		swizzle_pipe[3] = 3;
+		break;
+	case 5:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 1;
+		swizzle_pipe[2] = 2;
+		swizzle_pipe[3] = 3;
+		swizzle_pipe[4] = 4;
+		break;
+	case 6:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 5;
+		swizzle_pipe[4] = 1;
+		swizzle_pipe[5] = 3;
+		break;
+	case 7:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 6;
+		swizzle_pipe[4] = 1;
+		swizzle_pipe[5] = 3;
+		swizzle_pipe[6] = 5;
+		break;
+	case 8:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 6;
+		swizzle_pipe[4] = 1;
+		swizzle_pipe[5] = 3;
+		swizzle_pipe[6] = 5;
+		swizzle_pipe[7] = 7;
+		break;
+	}
+
+	cur_backend = 0;
+	for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) {
+		while (((1 << cur_backend) & enabled_backends_mask) == 0)
+			cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS;
+
+		backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2)));
+
+		cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS;
+	}
+
+	return backend_map;
+}
+
+static int r600_count_pipe_bits(uint32_t val)
+{
+	int i, ret = 0;
+	for (i = 0; i < 32; i++) {
+		ret += val & 1;
+		val >>= 1;
+	}
+	return ret;
+}
+
+static void r600_gfx_init(struct drm_device *dev,
+			  drm_radeon_private_t *dev_priv)
+{
+	int i, j, num_qd_pipes;
+	u32 sx_debug_1;
+	u32 tc_cntl;
+	u32 arb_pop;
+	u32 num_gs_verts_per_thread;
+	u32 vgt_gs_per_es;
+	u32 gs_prim_buffer_depth = 0;
+	u32 sq_ms_fifo_sizes;
+	u32 sq_config;
+	u32 sq_gpr_resource_mgmt_1 = 0;
+	u32 sq_gpr_resource_mgmt_2 = 0;
+	u32 sq_thread_resource_mgmt = 0;
+	u32 sq_stack_resource_mgmt_1 = 0;
+	u32 sq_stack_resource_mgmt_2 = 0;
+	u32 hdp_host_path_cntl;
+	u32 backend_map;
+	u32 gb_tiling_config = 0;
+	u32 cc_rb_backend_disable = 0;
+	u32 cc_gc_shader_pipe_config = 0;
+	u32 ramcfg;
+
+	/* setup chip specs */
+	switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+	case CHIP_R600:
+		dev_priv->r600_max_pipes = 4;
+		dev_priv->r600_max_tile_pipes = 8;
+		dev_priv->r600_max_simds = 4;
+		dev_priv->r600_max_backends = 4;
+		dev_priv->r600_max_gprs = 256;
+		dev_priv->r600_max_threads = 192;
+		dev_priv->r600_max_stack_entries = 256;
+		dev_priv->r600_max_hw_contexts = 8;
+		dev_priv->r600_max_gs_threads = 16;
+		dev_priv->r600_sx_max_export_size = 128;
+		dev_priv->r600_sx_max_export_pos_size = 16;
+		dev_priv->r600_sx_max_export_smx_size = 128;
+		dev_priv->r600_sq_num_cf_insts = 2;
+		break;
+	case CHIP_RV630:
+	case CHIP_RV635:
+		dev_priv->r600_max_pipes = 2;
+		dev_priv->r600_max_tile_pipes = 2;
+		dev_priv->r600_max_simds = 3;
+		dev_priv->r600_max_backends = 1;
+		dev_priv->r600_max_gprs = 128;
+		dev_priv->r600_max_threads = 192;
+		dev_priv->r600_max_stack_entries = 128;
+		dev_priv->r600_max_hw_contexts = 8;
+		dev_priv->r600_max_gs_threads = 4;
+		dev_priv->r600_sx_max_export_size = 128;
+		dev_priv->r600_sx_max_export_pos_size = 16;
+		dev_priv->r600_sx_max_export_smx_size = 128;
+		dev_priv->r600_sq_num_cf_insts = 2;
+		break;
+	case CHIP_RV610:
+	case CHIP_RS780:
+	case CHIP_RV620:
+		dev_priv->r600_max_pipes = 1;
+		dev_priv->r600_max_tile_pipes = 1;
+		dev_priv->r600_max_simds = 2;
+		dev_priv->r600_max_backends = 1;
+		dev_priv->r600_max_gprs = 128;
+		dev_priv->r600_max_threads = 192;
+		dev_priv->r600_max_stack_entries = 128;
+		dev_priv->r600_max_hw_contexts = 4;
+		dev_priv->r600_max_gs_threads = 4;
+		dev_priv->r600_sx_max_export_size = 128;
+		dev_priv->r600_sx_max_export_pos_size = 16;
+		dev_priv->r600_sx_max_export_smx_size = 128;
+		dev_priv->r600_sq_num_cf_insts = 1;
+		break;
+	case CHIP_RV670:
+		dev_priv->r600_max_pipes = 4;
+		dev_priv->r600_max_tile_pipes = 4;
+		dev_priv->r600_max_simds = 4;
+		dev_priv->r600_max_backends = 4;
+		dev_priv->r600_max_gprs = 192;
+		dev_priv->r600_max_threads = 192;
+		dev_priv->r600_max_stack_entries = 256;
+		dev_priv->r600_max_hw_contexts = 8;
+		dev_priv->r600_max_gs_threads = 16;
+		dev_priv->r600_sx_max_export_size = 128;
+		dev_priv->r600_sx_max_export_pos_size = 16;
+		dev_priv->r600_sx_max_export_smx_size = 128;
+		dev_priv->r600_sq_num_cf_insts = 2;
+		break;
+	default:
+		break;
+	}
+
+	/* Initialize HDP */
+	j = 0;
+	for (i = 0; i < 32; i++) {
+		RADEON_WRITE((0x2c14 + j), 0x00000000);
+		RADEON_WRITE((0x2c18 + j), 0x00000000);
+		RADEON_WRITE((0x2c1c + j), 0x00000000);
+		RADEON_WRITE((0x2c20 + j), 0x00000000);
+		RADEON_WRITE((0x2c24 + j), 0x00000000);
+		j += 0x18;
+	}
+
+	RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff));
+
+	/* setup tiling, simd, pipe config */
+	ramcfg = RADEON_READ(R600_RAMCFG);
+
+	switch (dev_priv->r600_max_tile_pipes) {
+	case 1:
+		gb_tiling_config |= R600_PIPE_TILING(0);
+		break;
+	case 2:
+		gb_tiling_config |= R600_PIPE_TILING(1);
+		break;
+	case 4:
+		gb_tiling_config |= R600_PIPE_TILING(2);
+		break;
+	case 8:
+		gb_tiling_config |= R600_PIPE_TILING(3);
+		break;
+	default:
+		break;
+	}
+
+	gb_tiling_config |= R600_BANK_TILING((ramcfg >> R600_NOOFBANK_SHIFT) & R600_NOOFBANK_MASK);
+
+	gb_tiling_config |= R600_GROUP_SIZE(0);
+
+	if (((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK) > 3) {
+		gb_tiling_config |= R600_ROW_TILING(3);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list