## Automatically generated incremental diff
## From:   linux-2.4.21-bk7
## To:     linux-2.4.21-bk8
## Robot:  $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $

diff -urN linux-2.4.21-bk7/Documentation/cciss.txt linux-2.4.21-bk8/Documentation/cciss.txt
--- linux-2.4.21-bk7/Documentation/cciss.txt	2003-07-12 02:52:18.000000000 -0700
+++ linux-2.4.21-bk8/Documentation/cciss.txt	2003-07-12 02:52:23.000000000 -0700
@@ -11,8 +11,8 @@
 	* SA 5312
 	* SA 641
 	* SA 642
-	* SA 6402
-	* SA 6404/256
+	* SA 6400
+	* SA 6400 U320 Expansion Module
 
 If nodes are not already created in the /dev/cciss directory
 
diff -urN linux-2.4.21-bk7/MAINTAINERS linux-2.4.21-bk8/MAINTAINERS
--- linux-2.4.21-bk7/MAINTAINERS	2003-07-12 02:52:18.000000000 -0700
+++ linux-2.4.21-bk8/MAINTAINERS	2003-07-12 02:52:23.000000000 -0700
@@ -1426,13 +1426,13 @@
 
 RADEON FRAMEBUFFER DISPLAY DRIVER
 P:	Ani Joshi
-M:	ajoshi@shell.unixbox.com
+M:	ajoshi@kernel.crashing.org
 L:      linux-fbdev-devel@lists.sourceforge.net
 S:      Maintained
 
 RAGE128 FRAMEBUFFER DISPLAY DRIVER
 P:	Ani Joshi
-M:	ajoshi@shell.unixbox.com
+M:	ajoshi@kernel.crashing.org
 L:	linux-fbdev-devel@lists.sourceforge.net
 S:	Maintained
 
diff -urN linux-2.4.21-bk7/Makefile linux-2.4.21-bk8/Makefile
--- linux-2.4.21-bk7/Makefile	2003-07-12 02:52:18.000000000 -0700
+++ linux-2.4.21-bk8/Makefile	2003-07-12 02:52:23.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 21
-EXTRAVERSION = -bk7
+EXTRAVERSION = -bk8
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.21-bk7/arch/i386/kernel/acpi.c linux-2.4.21-bk8/arch/i386/kernel/acpi.c
--- linux-2.4.21-bk7/arch/i386/kernel/acpi.c	2003-07-12 02:52:18.000000000 -0700
+++ linux-2.4.21-bk8/arch/i386/kernel/acpi.c	2003-07-12 02:52:24.000000000 -0700
@@ -44,6 +44,7 @@
 #include <asm/io_apic.h>
 #include <asm/acpi.h>
 #include <asm/save_state.h>
+#include <asm/smpboot.h>
 
 
 #define PREFIX			"ACPI: "
@@ -129,7 +130,7 @@
 	printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n",
 		madt->lapic_address);
 
-	acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id);
+	detect_clustered_apic(madt->header.oem_id, madt->header.oem_table_id);
 
 	return 0;
 }
diff -urN linux-2.4.21-bk7/arch/i386/kernel/mpparse.c linux-2.4.21-bk8/arch/i386/kernel/mpparse.c
--- linux-2.4.21-bk7/arch/i386/kernel/mpparse.c	2003-07-12 02:52:18.000000000 -0700
+++ linux-2.4.21-bk8/arch/i386/kernel/mpparse.c	2003-07-12 02:52:24.000000000 -0700
@@ -1252,22 +1252,6 @@
 	io_apic_set_pci_routing(ioapic, ioapic_pin, irq);
 }
 
-/* Hook from generic ACPI tables.c */
-void __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-	if (!strncmp(oem_id, "IBM", 3) &&
-	    (!strncmp(oem_table_id, "SERVIGIL", 8) ||
-	     !strncmp(oem_table_id, "EXA", 3) ||
-	     !strncmp(oem_table_id, "RUTHLESS", 8))){
-		clustered_apic_mode = CLUSTERED_APIC_XAPIC;
-		apic_broadcast_id = APIC_BROADCAST_ID_XAPIC;
-		int_dest_addr_mode = APIC_DEST_PHYSICAL;
-		int_delivery_mode = dest_Fixed;
-		esr_disable = 1;
-		/*Start cyclone clock*/
-		cyclone_setup(0);
-	}
-}
 
 #ifdef CONFIG_ACPI_PCI
 
diff -urN linux-2.4.21-bk7/drivers/block/cciss.c linux-2.4.21-bk8/drivers/block/cciss.c
--- linux-2.4.21-bk7/drivers/block/cciss.c	2003-07-12 02:52:20.000000000 -0700
+++ linux-2.4.21-bk8/drivers/block/cciss.c	2003-07-12 02:52:25.000000000 -0700
@@ -44,12 +44,12 @@
 #include <linux/genhd.h>
 
 #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
-#define DRIVER_NAME "HP CISS Driver (v 2.4.44)"
-#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,4,44)
+#define DRIVER_NAME "HP CISS Driver (v 2.4.47)"
+#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,4,47)
 
 /* Embedded module documentation macros - see modules.h */
 MODULE_AUTHOR("Charles M. White III - Hewlett-Packard Company");
-MODULE_DESCRIPTION("Driver for HP SA5xxx SA6xxx Controllers version 2.4.44");
+MODULE_DESCRIPTION("Driver for HP SA5xxx SA6xxx Controllers version 2.4.47");
 MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"); 
 MODULE_LICENSE("GPL");
 
@@ -92,8 +92,8 @@
 	{ 0x40830E11, "Smart Array 5312", &SA5B_access},
 	{ 0x409A0E11, "Smart Array 641", &SA5_access},
 	{ 0x409B0E11, "Smart Array 642", &SA5_access},
-	{ 0x409C0E11, "Smart Array 6402", &SA5_access},
-	{ 0x409C0E11, "Smart Array 6404/256", &SA5_access},
+	{ 0x409C0E11, "Smart Array 6400", &SA5_access},
+	{ 0x409D0E11, "Smart Array 6400 EM", &SA5_access},
 };
 
 /* How long to wait (in millesconds) for board to go into simple mode */
@@ -2460,7 +2460,9 @@
 				case PCI_BASE_ADDRESS_MEM_TYPE_64:
 					offset += 8;
 					break;
-				case PCI_BASE_ADDRESS_MEM_PREFETCH:
+				default: /* reserved in PCI 2.2 */
+					printk(KERN_WARNING "Base address is invalid\n");
+					return -1;	
 				break;
 			}
 		}
@@ -2472,19 +2474,21 @@
 			
 static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
 {
-	ushort vendor_id, device_id, command;
-	unchar cache_line_size, latency_timer;
-	unchar irq, revision;
+	ushort subsystem_vendor_id, subsystem_device_id, command;
+	unchar irq = pdev->irq;
 	__u32 board_id;
 	__u64 cfg_offset;
 	__u32 cfg_base_addr;
 	__u64 cfg_base_addr_index;
 	int i;
 
-	vendor_id = pdev->vendor;
-	device_id = pdev->device;
-	irq = pdev->irq;
-
+	/* check to see if controller has been disabled */
+	/* BEFORE we try to enable it */
+	(void) pci_read_config_word(pdev, PCI_COMMAND,&command);
+	if (!(command & 0x02)) {
+		printk(KERN_WARNING "cciss: controller appears to be disabled\n");
+		return -1;
+	}
 	if (pci_enable_device(pdev)) {
 		printk(KERN_ERR "cciss: Unable to Enable PCI device\n");
 		return -1;
@@ -2494,21 +2498,12 @@
 		return -1;
 	}
 	
-	(void) pci_read_config_word(pdev, PCI_COMMAND,&command);
-	(void) pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
-	(void) pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE,
-						&cache_line_size);
-	(void) pci_read_config_byte(pdev, PCI_LATENCY_TIMER,
-						&latency_timer);
+	subsystem_vendor_id = pdev->subsystem_vendor;
+	subsystem_device_id = pdev->subsystem_device;
+	board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) |
+					subsystem_vendor_id );
 
-	(void) pci_read_config_dword(pdev, PCI_SUBSYSTEM_VENDOR_ID, 
-						&board_id);
 
-	/* check to see if controller has been disabled */
-	if (!(command & 0x02)) {
-		printk(KERN_WARNING "cciss: controller appears to be disabled\n");
-		return -1;
-	}
 	/* search for our IO range so we can protect it */
 	for (i=0; i<DEVICE_COUNT_RESOURCE; i++) {
 		/* is this an IO range */
@@ -2535,15 +2530,8 @@
 	}
 
 #ifdef CCISS_DEBUG
-	printk("vendor_id = %x\n", vendor_id);
-	printk("device_id = %x\n", device_id);
 	printk("command = %x\n", command);
-	for(i=0; i<6; i++)
-		printk("addr[%d] = %x\n", i, pci_resource_start(pdev, i);
-	printk("revision = %x\n", revision);
 	printk("irq = %x\n", irq);
-	printk("cache_line_size = %x\n", cache_line_size);
-	printk("latency_timer = %x\n", latency_timer);
 	printk("board_id = %x\n", board_id);
 #endif /* CCISS_DEBUG */ 
 
diff -urN linux-2.4.21-bk7/drivers/block/cciss_scsi.c linux-2.4.21-bk8/drivers/block/cciss_scsi.c
--- linux-2.4.21-bk7/drivers/block/cciss_scsi.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.21-bk8/drivers/block/cciss_scsi.c	2003-07-12 02:52:25.000000000 -0700
@@ -1182,6 +1182,12 @@
 		{
 		  case 0x01: /* sequential access, (tape) */
 		  case 0x08: /* medium changer */
+			if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
+				printk(KERN_INFO "cciss%d: %s ignored, "
+					"too many devices.\n", cntl_num,
+					DEVICETYPE(devtype));
+				break;
+			}
 			memcpy(&currentsd[ncurrent].scsi3addr[0],
 				&scsi3addr[0], 8);
 			currentsd[ncurrent].devtype = devtype;
diff -urN linux-2.4.21-bk7/drivers/block/ll_rw_blk.c linux-2.4.21-bk8/drivers/block/ll_rw_blk.c
--- linux-2.4.21-bk7/drivers/block/ll_rw_blk.c	2003-07-12 02:52:20.000000000 -0700
+++ linux-2.4.21-bk8/drivers/block/ll_rw_blk.c	2003-07-12 02:52:25.000000000 -0700
@@ -618,7 +618,7 @@
 	do {
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		spin_lock_irq(&io_request_lock);
-		if (blk_oversized_queue(q)) {
+		if (blk_oversized_queue(q) || q->rq.count == 0) {
 			__generic_unplug_device(q);
 			spin_unlock_irq(&io_request_lock);
 			schedule();
diff -urN linux-2.4.21-bk7/drivers/macintosh/adbhid.c linux-2.4.21-bk8/drivers/macintosh/adbhid.c
--- linux-2.4.21-bk7/drivers/macintosh/adbhid.c	2003-07-12 02:52:20.000000000 -0700
+++ linux-2.4.21-bk8/drivers/macintosh/adbhid.c	2003-07-12 02:52:25.000000000 -0700
@@ -44,7 +44,9 @@
 #include <linux/pmu.h>
 
 #include <asm/machdep.h>
+#ifdef CONFIG_ALL_PPC
 #include <asm/pmac_feature.h>
+#endif
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 #include <asm/backlight.h>
@@ -158,6 +160,7 @@
 		return;
 	case 0x3f: /* ignore Powerbook Fn key */
 		return;
+#ifdef CONFIG_ALL_PPC
 	case 0x7e: /* Power key on PBook 3400 needs remapping */
 		switch(pmac_call_feature(PMAC_FTR_GET_MB_INFO,
 			NULL, PMAC_MB_INFO_MODEL, 0)) {
@@ -167,6 +170,7 @@
 			keycode = 0x7f;
 		}
 		break;
+#endif /* CONFIG_ALL_PPC */
 	}
 
 	if (adbhid[id]->keycode[keycode])
diff -urN linux-2.4.21-bk7/drivers/net/Config.in linux-2.4.21-bk8/drivers/net/Config.in
--- linux-2.4.21-bk7/drivers/net/Config.in	2003-07-12 02:52:20.000000000 -0700
+++ linux-2.4.21-bk8/drivers/net/Config.in	2003-07-12 02:52:25.000000000 -0700
@@ -274,6 +274,10 @@
    dep_tristate 'iSeries Virtual Ethernet driver support' CONFIG_VETH $CONFIG_PPC_ISERIES
 fi
 
+if [ "$CONFIG_4xx" = "y" ]; then
+   source drivers/net/ibm_emac/Config.in
+fi
+
 bool 'FDDI driver support' CONFIG_FDDI
 if [ "$CONFIG_FDDI" = "y" ]; then
    if [ "$CONFIG_PCI" = "y" -o "$CONFIG_EISA" = "y" ]; then
diff -urN linux-2.4.21-bk7/drivers/net/Makefile linux-2.4.21-bk8/drivers/net/Makefile
--- linux-2.4.21-bk7/drivers/net/Makefile	2003-07-12 02:52:20.000000000 -0700
+++ linux-2.4.21-bk8/drivers/net/Makefile	2003-07-12 02:52:25.000000000 -0700
@@ -25,6 +25,8 @@
   obj-y += tulip/tulip.o
 endif
 
+obj-$(CONFIG_OCP_NET) += ibm_emac/ocp.o
+
 ifeq ($(CONFIG_E1000),y)
   obj-y += e1000/e1000.o
 endif
@@ -40,6 +42,7 @@
 subdir-$(CONFIG_NET_PCMCIA) += pcmcia
 subdir-$(CONFIG_NET_WIRELESS) += wireless
 subdir-$(CONFIG_TULIP) += tulip
+subdir-$(CONFIG_OCP_NET) += ibm_emac
 subdir-$(CONFIG_IRDA) += irda
 subdir-$(CONFIG_TR) += tokenring
 subdir-$(CONFIG_WAN) += wan
diff -urN linux-2.4.21-bk7/drivers/net/Makefile.lib linux-2.4.21-bk8/drivers/net/Makefile.lib
--- linux-2.4.21-bk7/drivers/net/Makefile.lib	2003-07-12 02:52:20.000000000 -0700
+++ linux-2.4.21-bk8/drivers/net/Makefile.lib	2003-07-12 02:52:25.000000000 -0700
@@ -72,3 +72,5 @@
 # drivers/net/tulip
 obj-$(CONFIG_TULIP)		+= crc32.o
 
+# drivers/net/ibm_emac
+obj-$(CONFIG_OCP_NET)		+= crc32.o
diff -urN linux-2.4.21-bk7/drivers/net/ibm_emac/Config.in linux-2.4.21-bk8/drivers/net/ibm_emac/Config.in
--- linux-2.4.21-bk7/drivers/net/ibm_emac/Config.in	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.21-bk8/drivers/net/ibm_emac/Config.in	2003-07-12 02:52:25.000000000 -0700
@@ -0,0 +1,24 @@
+#
+#	On-chip network configuration
+#
+mainmenu_option next_comment
+comment 'On-chip net devices'
+if [ "$CONFIG_IBM_OCP" = "y" ]; then
+   bool '  IBM on-chip ethernet' CONFIG_IBM_OCP_ENET
+   if [ "$CONFIG_IBM_OCP_ENET" = "y" ]; then
+      bool '    Verbose error messages' CONFIG_IBM_OCP_ENET_ERROR_MSG
+      int '    Number of receive buffers' CONFIG_IBM_OCP_ENET_RX_BUFF 64
+      int '    Number of transmit buffers' CONFIG_IBM_OCP_ENET_TX_BUFF 8
+      int '    Frame gap' CONFIG_IBM_OCP_ENET_GAP 8
+      int '    Skb reserve amount' CONFIG_IBM_OCP_ENET_SKB_RES 0
+   fi
+   if [ "$CONFIG_IBM_OCP_ENET" = "y" ]; then
+      define_bool CONFIG_OCP_NET y
+      if [ "$CONFIG_NP405H" = "y" -o  "$CONFIG_NP405L" = "y"	\
+	   -o "$CONFIG_440" = "y" ]; then
+	 define_int CONFIG_IBM_OCP_MAL_CNT 1
+	 define_bool CONFIG_IBM_OCP_ZMII  y
+      fi
+   fi
+fi
+endmenu
diff -urN linux-2.4.21-bk7/drivers/net/ibm_emac/Makefile linux-2.4.21-bk8/drivers/net/ibm_emac/Makefile
--- linux-2.4.21-bk7/drivers/net/ibm_emac/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.21-bk8/drivers/net/ibm_emac/Makefile	2003-07-12 02:52:25.000000000 -0700
@@ -0,0 +1,26 @@
+#
+# Makefile for the On-chip  ethernet drivers
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+
+obj-y   := 
+obj-m   := 
+
+O_TARGET := ocp.o
+
+# Module support doesn't work yet.
+export-objs     := 
+
+obj-$(CONFIG_IBM_OCP_ENET) += ibm_ocp_enet.o ibm_ocp_phy.o ibm_ocp_mal.o
+
+# Only need this if you want to see additional debug messages
+ifeq ($(CONFIG_IBM_OCP_ENET_ERROR_MSG), y)
+obj-$(CONFIG_IBM_OCP_ENET) += ibm_ocp_debug.o
+endif
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_emac.h linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_emac.h
--- linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_emac.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_emac.h	2003-07-12 02:52:25.000000000 -0700
@@ -0,0 +1,195 @@
+/*
+ * ibm_emac.h
+ *
+ *
+ *      Armin Kuster akuster@mvista.com
+ *      June, 2002
+ *
+ * Copyright 2002 MontaVista Softare Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Version: 1.0: 06/02/02 - armin
+ *  	pulled all emac defined out od enet.h
+ *
+ */
+
+#ifndef _IBM_OCP_EMAC_H_
+#define _IBM_OCP_EMAC_H_
+/* General defines needed for the driver */
+
+/* Emac */
+typedef struct emac_regs {
+	u32 em0mr0;
+	u32 em0mr1;
+	u32 em0tmr0;
+	u32 em0tmr1;
+	u32 em0rmr;
+	u32 em0isr;
+	u32 em0iser;
+	u32 em0iahr;
+	u32 em0ialr;
+	u32 em0vtpid;
+	u32 em0vtci;
+	u32 em0ptr;
+	u32 em0iaht1;
+	u32 em0iaht2;
+	u32 em0iaht3;
+	u32 em0iaht4;
+	u32 em0gaht1;
+	u32 em0gaht2;
+	u32 em0gaht3;
+	u32 em0gaht4;
+	u32 em0lsal;
+	u32 em0lsah;
+	u32 em0ipgvr;
+	u32 em0stacr;
+	u32 em0trtr;
+	u32 em0rwmr;
+} emac_t;
+
+
+/* MODE REG 0 */
+#define EMAC_M0_RXI			0x80000000
+#define EMAC_M0_TXI			0x40000000
+#define EMAC_M0_SRST			0x20000000
+#define EMAC_M0_TXE			0x10000000
+#define EMAC_M0_RXE			0x08000000
+#define EMAC_M0_WKE			0x04000000
+
+/* MODE Reg 1 */
+#define EMAC_M1_FDE			0x80000000
+#define EMAC_M1_ILE			0x40000000
+#define EMAC_M1_VLE			0x20000000
+#define EMAC_M1_EIFC			0x10000000
+#define EMAC_M1_APP			0x08000000
+#define EMAC_M1_AEMI			0x02000000
+#define EMAC_M1_IST			0x01000000
+#define EMAC_M1_MF_1000MBPS		0x00800000	/* 0's for 10MBPS */
+#define EMAC_M1_MF_100MBPS		0x00400000
+#define EMAC_M1_RFS_4K			0x00300000	/* ~4k for 512 byte */
+#define EMAC_M1_RFS_2K			0x00200000
+#define EMAC_M1_RFS_1K			0x00100000
+#define EMAC_M1_TX_FIFO_2K		0x00080000	/* 0's for 512 byte */
+#define EMAC_M1_TX_FIFO_1K		0x00040000
+#define EMAC_M1_TR0_DEPEND		0x00010000	/* 0'x for single packet */
+#define EMAC_M1_TR0_MULTI		0x00008000
+#define EMAC_M1_TR1_DEPEND		0x00004000
+#define EMAC_M1_TR1_MULTI		0x00002000
+#define EMAC_M1_JUMBO_ENABLE		0x00001000
+
+/* Transmit Mode Register 0 */
+#define EMAC_TXM0_GNP0			0x80000000
+#define EMAC_TXM0_GNP1			0x40000000
+#define EMAC_TXM0_GNPD			0x20000000
+#define EMAC_TXM0_FC			0x10000000
+
+/* Receive Mode Register */
+#define EMAC_RMR_SP			0x80000000
+#define EMAC_RMR_SFCS			0x40000000
+#define EMAC_RMR_ARRP			0x20000000
+#define EMAC_RMR_ARP			0x10000000
+#define EMAC_RMR_AROP			0x08000000
+#define EMAC_RMR_ARPI			0x04000000
+#define EMAC_RMR_PPP			0x02000000
+#define EMAC_RMR_PME			0x01000000
+#define EMAC_RMR_PMME			0x00800000
+#define EMAC_RMR_IAE			0x00400000
+#define EMAC_RMR_MIAE			0x00200000
+#define EMAC_RMR_BAE			0x00100000
+#define EMAC_RMR_MAE			0x00080000
+
+/* Interrupt Status & enable Regs */
+#define EMAC_ISR_OVR			0x02000000
+#define EMAC_ISR_PP			0x01000000
+#define EMAC_ISR_BP			0x00800000
+#define EMAC_ISR_RP			0x00400000
+#define EMAC_ISR_SE			0x00200000
+#define EMAC_ISR_ALE			0x00100000
+#define EMAC_ISR_BFCS			0x00080000
+#define EMAC_ISR_PTLE			0x00040000
+#define EMAC_ISR_ORE			0x00020000
+#define EMAC_ISR_IRE			0x00010000
+#define EMAC_ISR_DBDM			0x00000200
+#define EMAC_ISR_DB0			0x00000100
+#define EMAC_ISR_SE0			0x00000080
+#define EMAC_ISR_TE0			0x00000040
+#define EMAC_ISR_DB1			0x00000020
+#define EMAC_ISR_SE1			0x00000010
+#define EMAC_ISR_TE1			0x00000008
+#define EMAC_ISR_MOS			0x00000002
+#define EMAC_ISR_MOF			0x00000001
+
+/* STA CONTROL REG */
+#define EMAC_STACR_OC			0x00008000
+#define EMAC_STACR_PHYE			0x00004000
+#define EMAC_STACR_WRITE		0x00002000
+#define EMAC_STACR_READ			0x00001000
+#define EMAC_STACR_CLK_83MHZ		0x00000800	/* 0's for 50Mhz */
+#define EMAC_STACR_CLK_66MHZ		0x00000400
+#define EMAC_STACR_CLK_100MHZ		0x00000C00
+
+/* Transmit Request Threshold Register */
+#define EMAC_TRTR_256			0x18000000	/* 0's for 64 Bytes */
+#define EMAC_TRTR_192			0x10000000
+#define EMAC_TRTR_128			0x01000000
+
+
+#define EMAC_TX_CTRL_GFCS		0x0200
+#define EMAC_TX_CTRL_GP			0x0100
+#define EMAC_TX_CTRL_ISA		0x0080
+#define EMAC_TX_CTRL_RSA		0x0040
+#define EMAC_TX_CTRL_IVT		0x0020
+#define EMAC_TX_CTRL_RVT		0x0010
+
+#define EMAC_TX_CTRL_DFLT ( \
+	MAL_TX_CTRL_LAST | MAL_TX_CTRL_READY | MAL_TX_CTRL_INTR | \
+	EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP )
+
+/* madmal transmit status / Control bits */
+#define EMAC_TX_ST_BFCS			0x0200
+#define EMAC_TX_ST_BPP			0x0100
+#define EMAC_TX_ST_LCS			0x0080
+#define EMAC_TX_ST_ED			0x0040
+#define EMAC_TX_ST_EC			0x0020
+#define EMAC_TX_ST_LC			0x0010
+#define EMAC_TX_ST_MC			0x0008
+#define EMAC_TX_ST_SC			0x0004
+#define EMAC_TX_ST_UR			0x0002
+#define EMAC_TX_ST_SQE			0x0001
+
+#define EMAC_TX_ST_DEFAULT		0x03F3
+
+/* madmal receive status / Control bits */
+#define EMAC_RX_ST_OE			0x0200
+#define EMAC_RX_ST_PP			0x0100
+#define EMAC_RX_ST_BP			0x0080
+#define EMAC_RX_ST_RP			0x0040
+#define EMAC_RX_ST_SE			0x0020
+#define EMAC_RX_ST_AE			0x0010
+#define EMAC_RX_ST_BFCS			0x0008
+#define EMAC_RX_ST_PTL			0x0004
+#define EMAC_RX_ST_ORE			0x0002
+#define EMAC_RX_ST_IRE			0x0001
+#define EMAC_BAD_RX_PACKET		0x02ff
+
+
+#endif
diff -urN linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_ocp_debug.c linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_ocp_debug.c
--- linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_ocp_debug.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_ocp_debug.c	2003-07-12 02:52:25.000000000 -0700
@@ -0,0 +1,264 @@
+/*
+ * ibm_ocp_debug.c
+ *
+ * This has all the debug routines that where in *_enet.c
+ *
+ *      Armin Kuster akuster@mvista.com
+ *      April , 2002
+ *
+ * Copyright 2002 MontaVista Softare Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * TODO: 
+ *
+ * Version 1.0: (04/15/02)
+ * 	initial release 
+ * 	These are all the debug routines from *_enet.c and a few new ones. 
+ * 	this was done to reduce the *_enet.c code.
+ *
+ * Version 1.1: 04/24/02
+ * 	fixed missind EMAC_DEV macros - Todd
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <asm/io.h>
+#include "ibm_ocp_mal.h"
+#include "ibm_ocp_zmii.h"
+#include "ibm_ocp_enet.h"
+
+extern int
+emac_phy_read(struct net_device *dev, int mii_id, int reg);
+
+void emac_phy_dump(struct net_device *dev)
+{
+	struct ocp_enet_private *fep = dev->priv;
+	unsigned long i;
+	uint data;
+
+	printk(KERN_DEBUG " Prepare for Phy dump....\n");
+	for (i = 0; i < 0x1A; i++) {
+	        data = emac_phy_read(dev, fep->mii_phy_addr, i);
+		printk(KERN_DEBUG "Phy reg 0x%lx ==> %4x\n", i, data);
+		if (i == 0x07)
+			i = 0x0f;
+	}
+}
+
+void
+emac_desc_dump(struct net_device *dev)
+{
+	struct ocp_enet_private *fep = dev->priv;
+	int curr_slot;
+
+	printk(KERN_DEBUG "dumping the receive descriptors:  current slot is %d\n",
+	       fep->rx_slot);
+	for (curr_slot = 0; curr_slot < NUM_RX_BUFF; curr_slot++) {
+		printk(KERN_DEBUG "Desc %02d: status 0x%04x, length %3d, addr 0x%x\n",
+		       curr_slot,
+		       fep->rx_desc[curr_slot].ctrl,
+		       fep->rx_desc[curr_slot].data_len,
+		       (unsigned int) fep->rx_desc[curr_slot].data_ptr);
+	}
+}
+
+void
+emac_mac_dump(struct net_device *dev)
+{
+	struct ocp_enet_private *fep = dev->priv;
+	volatile emac_t *emacp = fep->emacp;
+
+	printk(KERN_DEBUG "EMAC DEBUG ********** \n");
+	printk(KERN_DEBUG "EMAC_M0  ==> 0x%x\n", in_be32(&emacp->em0mr0));
+	printk(KERN_DEBUG "EMAC_M1  ==> 0x%x\n", in_be32(&emacp->em0mr1));
+	printk(KERN_DEBUG "EMAC_TXM0==> 0x%x\n", in_be32(&emacp->em0tmr0));
+	printk(KERN_DEBUG "EMAC_TXM1==> 0x%x\n", in_be32(&emacp->em0tmr1));
+	printk(KERN_DEBUG "EMAC_RXM ==> 0x%x\n", in_be32(&emacp->em0rmr));
+	printk(KERN_DEBUG "EMAC_ISR ==> 0x%x\n", in_be32(&emacp->em0isr));
+	printk(KERN_DEBUG "EMAC_IER ==> 0x%x\n", in_be32(&emacp->em0iser));
+	printk(KERN_DEBUG "EMAC_IAH ==> 0x%x\n", in_be32(&emacp->em0iahr));
+	printk(KERN_DEBUG "EMAC_IAL ==> 0x%x\n", in_be32(&emacp->em0ialr));
+	printk(KERN_DEBUG "EMAC_VLAN_TPID_REG ==> 0x%x\n", in_be32(&emacp->em0vtpid));
+}
+
+void
+emac_mal_dump(struct net_device *dev)
+{
+	struct ibm_ocp_mal* mal = ((struct ocp_enet_private*)dev->priv)->mal;
+
+	printk(KERN_DEBUG " MAL DEBUG ********** \n");
+	printk(KERN_DEBUG " MCR      ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALCR));
+	printk(KERN_DEBUG " ESR      ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALESR));
+	printk(KERN_DEBUG " IER      ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALIER));
+#ifdef CONFIG_40x
+	printk(KERN_DEBUG " DBR      ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALDBR));
+#endif				/* CONFIG_40x */
+	printk(KERN_DEBUG " TXCASR   ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALTXCASR));
+	printk(KERN_DEBUG " TXCARR   ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALTXCARR));
+	printk(KERN_DEBUG " TXEOBISR ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALTXEOBISR));
+	printk(KERN_DEBUG " TXDEIR   ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALTXDEIR));
+	printk(KERN_DEBUG " RXCASR   ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALRXCASR));
+	printk(KERN_DEBUG " RXCARR   ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALRXCARR));
+	printk(KERN_DEBUG " RXEOBISR ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALRXEOBISR));
+	printk(KERN_DEBUG " RXDEIR   ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALRXDEIR));
+	printk(KERN_DEBUG " TXCTP0R  ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALTXCTP0R));
+	printk(KERN_DEBUG " TXCTP1R  ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALTXCTP1R));
+	printk(KERN_DEBUG " TXCTP2R  ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALTXCTP2R));
+	printk(KERN_DEBUG " TXCTP3R  ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALTXCTP3R));
+	printk(KERN_DEBUG " RXCTP0R  ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALRXCTP0R));
+	printk(KERN_DEBUG " RXCTP1R  ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALRXCTP1R));
+	printk(KERN_DEBUG " RCBS0    ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALRCBS0));
+	printk(KERN_DEBUG " RCBS1    ==> 0x%x\n", 
+	       (unsigned int) get_mal_dcrn(mal, DCRN_MALRCBS1));
+}
+
+void
+emac_serr_dump_0(struct net_device *dev)
+{
+	struct ibm_ocp_mal* mal = ((struct ocp_enet_private*)dev->priv)->mal;
+	unsigned long int mal_error, plb_error, plb_addr;
+
+	mal_error = get_mal_dcrn(mal, DCRN_MALESR);
+	printk(KERN_DEBUG "ppc405_eth_serr: %s channel %ld \n",
+	       (mal_error & 0x40000000) ? "Receive" :
+	       "Transmit", (mal_error & 0x3e000000) >> 25);
+	printk(KERN_DEBUG "  -----  latched error  -----\n");
+	if (mal_error & MALESR_DE)
+		printk(KERN_DEBUG "  DE: descriptor error\n");
+	if (mal_error & MALESR_OEN)
+		printk(KERN_DEBUG
+		       "  ONE: OPB non-fullword error\n");
+	if (mal_error & MALESR_OTE)
+		printk(KERN_DEBUG "  OTE: OPB timeout error\n");
+	if (mal_error & MALESR_OSE)
+		printk(KERN_DEBUG "  OSE: OPB slave error\n");
+	
+	if (mal_error & MALESR_PEIN) {
+		plb_error = mfdcr(DCRN_PLB0_BESR);
+		printk(KERN_DEBUG
+		       "  PEIN: PLB error, PLB0_BESR is 0x%x\n",
+		       (unsigned int) plb_error);
+		plb_addr = mfdcr(DCRN_PLB0_BEAR);
+		printk(KERN_DEBUG
+		       "  PEIN: PLB error, PLB0_BEAR is 0x%x\n",
+		       (unsigned int) plb_addr);
+	}
+}
+
+void
+emac_serr_dump_1(struct net_device *dev)
+{
+	struct ibm_ocp_mal* mal = ((struct ocp_enet_private*)dev->priv)->mal;
+	int mal_error = get_mal_dcrn(mal, DCRN_MALESR);
+
+	printk(KERN_DEBUG "  -----  cumulative errors  -----\n");
+	if (mal_error & MALESR_DEI)
+		printk(KERN_DEBUG
+		       "  DEI: descriptor error interrupt\n");
+	if (mal_error & MALESR_ONEI)
+		printk(KERN_DEBUG
+		       "  OPB non-fullword error interrupt\n");
+	if (mal_error & MALESR_OTEI)
+		printk(KERN_DEBUG
+		       "  OTEI: timeout error interrupt\n");
+	if (mal_error & MALESR_OSEI)
+		printk(KERN_DEBUG
+		       "  OSEI: slave error interrupt\n");
+	if (mal_error & MALESR_PBEI)
+		printk(KERN_DEBUG
+		       "  PBEI: PLB bus error interrupt\n");
+}
+
+void
+emac_err_dump(struct net_device *dev, int em0isr)
+{
+	printk(KERN_DEBUG "%s: on-chip ethernet error:\n", dev->name);
+	
+	if (em0isr & EMAC_ISR_OVR)
+		printk(KERN_DEBUG "  OVR: overrun\n");
+	if (em0isr & EMAC_ISR_PP)
+		printk(KERN_DEBUG "  PP: control pause packet\n");
+	if (em0isr & EMAC_ISR_BP)
+		printk(KERN_DEBUG "  BP: packet error\n");
+	if (em0isr & EMAC_ISR_RP)
+		printk(KERN_DEBUG "  RP: runt packet\n");
+	if (em0isr & EMAC_ISR_SE)
+		printk(KERN_DEBUG "  SE: short event\n");
+	if (em0isr & EMAC_ISR_ALE)
+		printk(KERN_DEBUG
+		       "  ALE: odd number of nibbles in packet\n");
+	if (em0isr & EMAC_ISR_BFCS)
+		printk(KERN_DEBUG "  BFCS: bad FCS\n");
+	if (em0isr & EMAC_ISR_PTLE)
+		printk(KERN_DEBUG "  PTLE: oversized packet\n");
+	if (em0isr & EMAC_ISR_ORE)
+		printk(KERN_DEBUG
+		       "  ORE: packet length field > max allowed LLC\n");
+	if (em0isr & EMAC_ISR_IRE)
+		printk(KERN_DEBUG "  IRE: In Range error\n");
+	if (em0isr & EMAC_ISR_DBDM)
+		printk(KERN_DEBUG "  DBDM: xmit error or SQE\n");
+	if (em0isr & EMAC_ISR_DB0)
+		printk(KERN_DEBUG
+		       "  DB0: xmit error or SQE on TX channel 0\n");
+	if (em0isr & EMAC_ISR_SE0)
+		printk(KERN_DEBUG
+		       "  SE0: Signal Quality Error test failure from TX channel 0\n");
+	if (em0isr & EMAC_ISR_TE0)
+		printk(KERN_DEBUG "  TE0: xmit channel 0 aborted\n");
+	if (em0isr & EMAC_ISR_DB1)
+		printk(KERN_DEBUG
+		       "  DB1: xmit error or SQE on TX channel \n");
+	if (em0isr & EMAC_ISR_SE1)
+		printk(KERN_DEBUG
+		       "  SE1: Signal Quality Error test failure from TX channel 1\n");
+	if (em0isr & EMAC_ISR_TE1)
+		printk(KERN_DEBUG "  TE1: xmit channel 1 aborted\n");
+	if (em0isr & EMAC_ISR_MOS)
+		printk(KERN_DEBUG "  MOS\n");
+	if (em0isr & EMAC_ISR_MOF)
+		printk(KERN_DEBUG "  MOF\n");
+	
+	emac_mac_dump(dev);
+	emac_mal_dump(dev);
+}
diff -urN linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_ocp_enet.c linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_ocp_enet.c
--- linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_ocp_enet.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_ocp_enet.c	2003-07-12 02:52:25.000000000 -0700
@@ -0,0 +1,1458 @@
+/*
+ * ibm_ocp_enet.c
+ *
+ * Ethernet driver for the built in ethernet on the IBM 4xx PowerPC
+ * processors.
+ * 
+ * (c) 2003 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ *
+ * Based on original work by
+ *
+ *      Armin Kuster <akuster@mvista.com>
+ * 	Johnnie Peters <jpeters@mvista.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * TODO
+ *       - Check for races in the "remove" code path
+ *       - Add some Power Management to the MAC and the PHY
+ *       - Audit remaining of non-rewritten code (--BenH)
+ *       - Cleanup message display using msglevel mecanism
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+
+#include <asm/processor.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/ocp.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/crc32.h>
+
+#include "ibm_ocp_enet.h"
+
+//#define MDIO_DEBUG(fmt) printk fmt
+#define MDIO_DEBUG(fmt)
+
+//#define LINK_DEBUG(fmt) printk fmt
+#define LINK_DEBUG(fmt)
+
+//#define PKT_DEBUG(fmt) printk fmt
+#define PKT_DEBUG(fmt)
+
+#define DRV_NAME        "emac"
+#define DRV_VERSION     "2.0"
+#define DRV_AUTHOR      "Benjamin Herrenschmidt <benh@kernel.crashing.org>"
+#define DRV_DESC        "IBM OCP EMAC Ethernet driver"
+
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_LICENSE("GPL");
+
+static int skb_res = SKB_RES;
+MODULE_PARM(skb_res, "i");
+MODULE_PARM_DESC(skb_res, "Amount of data to reserve on skb buffs\n"
+		 "The 405 handles a misaligned IP header fine but\n"
+		 "this can help if you are routing to a tunnel or a\n"
+		 "device that needs aligned data. 0..2");
+
+#define ZMII_PRIV(ocpdev) ((struct ibm_ocp_zmii*)ocp_get_drvdata(ocpdev))
+
+static unsigned int zmii_enable[][4] = {
+	{ZMII_SMII0, ZMII_RMII0, ZMII_MII0,
+	 ~(ZMII_MDI1 | ZMII_MDI2 | ZMII_MDI3)},
+	{ZMII_SMII1, ZMII_RMII1, ZMII_MII1,
+	 ~(ZMII_MDI0 | ZMII_MDI2 | ZMII_MDI3)},
+	{ZMII_SMII2, ZMII_RMII2, ZMII_MII2,
+	 ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI3)},
+	{ZMII_SMII3, ZMII_RMII3, ZMII_MII3, ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI2)}
+};
+static unsigned int mdi_enable[] =
+    { ZMII_MDI0, ZMII_MDI1, ZMII_MDI2, ZMII_MDI3 };
+
+static unsigned int zmii_speed = 0x0;
+static unsigned int zmii_speed100[] = { ZMII_MII0_100MB, ZMII_MII1_100MB };
+
+/* Since multiple EMACs share MDIO lines in various ways, we need
+ * to avoid re-using the same PHY ID in cases where the arch didn't
+ * setup precise emac_phy_map entries
+ */
+static u32 busy_phy_map = 0;
+
+static struct net_device_stats *
+emac_stats(struct net_device *dev)
+{
+	struct ocp_enet_private *fep = dev->priv;
+	return &fep->stats;
+}
+
+static int
+emac_init_zmii(struct ocp_device *ocpdev, int mode)
+{
+	struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev);
+	struct zmii_regs *zmiip;
+	const char *mode_name[] = { "SMII", "RMII", "MII" };
+	
+	if (zmii){
+		/* We have already initialized ZMII device,
+		   so just increment refcount and return */	
+		zmii->users++;
+		return 0;		   
+	}
+	
+	zmii = kmalloc(sizeof(struct ibm_ocp_zmii), GFP_KERNEL);
+	if (zmii == NULL) {
+		printk(KERN_ERR "zmii%d: Out of memory allocating ZMII structure!\n",
+			ocpdev->def->index);
+		return -ENOMEM;
+	}
+	memset(zmii, 0, sizeof(*zmii));
+		
+	zmiip = (struct zmii_regs *)ioremap(ocpdev->def->paddr, sizeof(*zmiip));
+	if (zmiip == NULL){
+		printk(KERN_ERR "zmii%d: Cannot ioremap bridge registers!\n",
+			ocpdev->def->index);
+		
+		kfree(zmii);
+		return -ENOMEM;	
+	}	
+	
+	if (mode == ZMII_AUTO) {
+		if (zmiip->fer & (ZMII_MII0 | ZMII_MII1 | 
+				  ZMII_MII2 | ZMII_MII3))
+			mode = MII;
+		if (zmiip->fer & (ZMII_RMII0 | ZMII_RMII1 |
+				  ZMII_RMII2 | ZMII_RMII3))
+			mode = RMII;
+		if (zmiip->fer & (ZMII_SMII0 | ZMII_SMII1 |
+				  ZMII_SMII2 | ZMII_SMII3))
+			mode = SMII;
+
+		/* Failsafe: ZMII_AUTO is invalid index into the arrays,
+		   so force SMII if all else fails. */
+
+		if (mode == ZMII_AUTO)
+			mode = SMII;
+	}
+	
+	zmii->base = zmiip;
+	zmii->mode = mode;
+	zmii->users++;
+	ocp_set_drvdata(ocpdev, zmii);
+
+	printk(KERN_NOTICE "zmii%d: bridge in %s mode\n", ocpdev->def->index,
+		mode_name[mode]);
+	return 0;
+}
+
+static void
+emac_enable_zmii_port(struct ocp_device *ocpdev, int input)
+{
+	u32 mask;
+	struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev);
+
+	mask  = in_be32(&zmii->base->fer);
+	mask &= zmii_enable[input][MDI];	/* turn all non enabled MDI's off */
+	mask |= zmii_enable[input][zmii->mode] | mdi_enable[input];
+	out_be32(&zmii->base->fer, mask);
+}
+
+static void
+emac_zmii_port_speed(struct ocp_device *ocpdev, int input, int speed)
+{
+	struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev);
+
+	if (speed == 100)
+		zmii_speed |= zmii_speed100[input];
+	else
+		zmii_speed &= ~zmii_speed100[input];
+
+	out_be32(&zmii->base->ssr, zmii_speed);
+}
+
+static void
+emac_fini_zmii(struct ocp_device *ocpdev)
+{
+	struct ibm_ocp_zmii *zmii = ZMII_PRIV(ocpdev);
+	BUG_ON(!zmii || zmii->users == 0);
+
+	if (!--zmii->users){
+		ocp_set_drvdata(ocpdev, NULL);
+		iounmap((void*)zmii->base);
+		kfree(zmii);
+	}
+}
+
+int
+emac_phy_read(struct net_device *dev, int mii_id, int reg)
+{
+	register int i;
+	uint32_t stacr;
+	struct ocp_enet_private *fep = dev->priv;
+	volatile emac_t *emacp = fep->emacp;
+
+	MDIO_DEBUG(("%s: phy_read, id: 0x%x, reg: 0x%x\n", dev->name, mii_id, reg));
+
+	/* Enable proper ZMII port */
+	if (fep->zmii_dev)
+		emac_enable_zmii_port(fep->zmii_dev, fep->zmii_input);
+	/* Use the EMAC that has the MDIO port */
+	if (fep->mdio_dev) {
+		dev = fep->mdio_dev;
+		fep = dev->priv;
+	}
+	
+	/* Wait for data transfer complete bit */
+	for (i = 0; i < OCP_RESET_DELAY; ++i) {
+		if (emacp->em0stacr & EMAC_STACR_OC)
+			break;
+		udelay(MDIO_DELAY);	/* changed to 2 with new scheme -armin */
+	}
+	if ((emacp->em0stacr & EMAC_STACR_OC) == 0) {
+		printk(KERN_WARNING "%s: PHY read timeout #1!\n", dev->name);
+		return -1;
+	}
+
+	/* Clear the speed bits and make a read request to the PHY */
+	stacr = ((EMAC_STACR_READ | (reg & 0x1f)) & ~EMAC_STACR_CLK_100MHZ);
+	stacr |= ((mii_id & 0x1F) << 5);
+
+	out_be32(&emacp->em0stacr, stacr);
+	stacr = in_be32(&emacp->em0stacr);
+	/* Wait for data transfer complete bit */
+	for (i = 0; i < OCP_RESET_DELAY; ++i) {
+		if ((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC)
+			break;
+		udelay(MDIO_DELAY);
+	}
+	if ((stacr & EMAC_STACR_OC) == 0) {
+		printk(KERN_WARNING "%s: PHY read timeout #2!\n", dev->name);
+		return -1;
+	}
+
+	/* Check for a read error */
+	if (stacr & EMAC_STACR_PHYE) {
+	        MDIO_DEBUG(("OCP MDIO PHY error !\n"));
+		return -1;
+	}
+   
+	MDIO_DEBUG((" -> 0x%x\n", stacr >> 16));
+
+	return (stacr >> 16);
+}
+
+
+void
+emac_phy_write(struct net_device *dev, int mii_id, int reg, int data)
+{
+	register int i = 0;
+	uint32_t stacr;
+	struct ocp_enet_private *fep = dev->priv;
+	volatile emac_t *emacp = fep->emacp;
+
+	MDIO_DEBUG(("%s phy_write, id: 0x%x, reg: 0x%x, data: 0x%x\n",
+            dev->name, mii_id, reg, data));
+
+	/* Enable proper ZMII port */
+	if (fep->zmii_dev)
+		emac_enable_zmii_port(fep->zmii_dev, fep->zmii_input);
+	/* Use the EMAC that has the MDIO port */
+	if (fep->mdio_dev) {
+		dev = fep->mdio_dev;
+		fep = dev->priv;
+	}
+
+	/* Wait for data transfer complete bit */
+	for (i = 0; i < OCP_RESET_DELAY; ++i) {
+		if (emacp->em0stacr & EMAC_STACR_OC)
+			break;
+		udelay(MDIO_DELAY);	/* changed to 2 with new scheme -armin */
+	}
+	if ((emacp->em0stacr & EMAC_STACR_OC) == 0) {
+		printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name);
+		return;
+	}
+
+	/* Clear the speed bits and make a read request to the PHY */
+
+	stacr = ((EMAC_STACR_WRITE | (reg & 0x1f)) & ~EMAC_STACR_CLK_100MHZ);
+	stacr |= ((mii_id & 0x1f) << 5) | ((data & 0xffff) << 16);
+
+	out_be32(&emacp->em0stacr, stacr);
+
+	/* Wait for data transfer complete bit */
+	for (i = 0; i < OCP_RESET_DELAY; ++i) {
+		if ((stacr = emacp->em0stacr) & EMAC_STACR_OC)
+			break;
+		udelay(MDIO_DELAY);
+	}
+	if ((emacp->em0stacr & EMAC_STACR_OC) == 0)
+		printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name);
+
+	/* Check for a write error */
+	if ((stacr & EMAC_STACR_PHYE) != 0) {
+		MDIO_DEBUG(("OCP MDIO PHY error !\n"));
+        }
+}
+
+static void
+emac_wakeup_irq(int irq, void *param, struct pt_regs *regs)
+{
+	struct net_device *dev = param;
+
+	/* On Linux the 405 ethernet will always be active if configured
+	 * in.  This interrupt should never occur.
+	 */
+	printk(KERN_INFO "%s: WakeUp interrupt !\n", dev->name);
+}
+
+static void
+emac_txeob_dev(void *param, u32 chanmask)
+{
+	struct net_device *dev = param;
+	struct ocp_enet_private *fep = dev->priv;
+        unsigned long flags;
+
+        spin_lock_irqsave(&fep->lock, flags);
+
+	PKT_DEBUG(("emac_txeob_dev() entry, tx_cnt: %d\n", fep->tx_cnt));
+
+	while (fep->tx_cnt &&
+	       !(fep->tx_desc[fep->ack_slot].ctrl & MAL_TX_CTRL_READY)) {
+
+		/* Tell the system the transmit completed. */
+		dev_kfree_skb_irq(fep->tx_skb[fep->ack_slot]);
+
+		if (fep->tx_desc[fep->ack_slot].ctrl &
+		    (EMAC_TX_ST_EC | EMAC_TX_ST_MC | EMAC_TX_ST_SC))
+			fep->stats.collisions++;
+
+		fep->tx_skb[fep->ack_slot] = (struct sk_buff *) NULL;
+		if (++fep->ack_slot == NUM_TX_BUFF)
+			fep->ack_slot = 0;
+
+		fep->tx_cnt--;
+	}
+	if (fep->tx_cnt < NUM_TX_BUFF)
+       		netif_wake_queue(dev);
+
+	PKT_DEBUG(("emac_txeob_dev() exit, tx_cnt: %d\n", fep->tx_cnt));
+	
+        spin_unlock_irqrestore(&fep->lock, flags);
+}
+
+/*
+  Fill/Re-fill the rx chain with valid ctrl/ptrs.
+  This function will fill from rx_slot up to the parm end.
+  So to completely fill the chain pre-set rx_slot to 0 and
+  pass in an end of 0.
+ */
+static void
+emac_rx_fill(struct net_device *dev, int end)
+{
+	int i;
+	struct ocp_enet_private *fep = dev->priv;
+	unsigned char *ptr;
+
+	i = fep->rx_slot;
+	do {
+		if (fep->rx_skb[i] != NULL) {
+			/*We will trust the skb is still in a good state */
+			ptr = (char *) virt_to_phys(fep->rx_skb[i]->data);
+		} else {
+
+			/* We don't want the 16 bytes skb_reserve done by dev_alloc_skb,
+			 * it breaks our cache line alignement. However, we still allocate
+			 * +16 so that we end up allocating the exact same size as
+			 * dev_alloc_skb() would do.
+			 * Also, because of the skb_res, the max DMA size we give to EMAC
+			 * is slighly wrong, causing it to potentially DMA 2 more bytes
+                         * from a broken/oversized packet. These 16 bytes will take care
+                         * that we don't walk on somebody else toes with that.
+			 */
+			fep->rx_skb[i] =
+			    alloc_skb(DESC_RX_BUF_SIZE + 16, GFP_ATOMIC);
+
+			if (fep->rx_skb[i] == NULL) {
+				/* Keep rx_slot here, the next time clean/fill is called
+				 * we will try again before the MAL wraps back here
+				 * If the MAL tries to use this descriptor with
+				 * the EMPTY bit off it will cause the
+				 * rxde interrupt.  That is where we will
+				 * try again to allocate an sk_buff.
+				 */
+				break;
+
+			}
+
+			if (skb_res)
+				skb_reserve(fep->rx_skb[i], skb_res);
+
+			/* We must NOT consistent_sync the cache line right after the
+			 * buffer, so we must crop our sync size to account for the
+			 * reserved space
+			 */
+			consistent_sync((void *) fep->rx_skb[i]->
+					data, (DESC_RX_BUF_SIZE-skb_res),
+					PCI_DMA_FROMDEVICE);
+			ptr = (char *) virt_to_phys(fep->rx_skb[i]->data);
+		}
+		fep->rx_desc[i].ctrl = MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR |	/*could be smarter about this to avoid ints at high loads */
+		    (i == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
+
+		fep->rx_desc[i].data_ptr = ptr;
+		/*
+		   * 440GP uses the previously reserved bits in the
+		   * data_len to encode the upper 4-bits of the buffer
+		   * physical address (ERPN). Initialize these.
+		 */
+		fep->rx_desc[i].data_len = 0;
+	} while ((i = (i + 1) % NUM_RX_BUFF) != end);
+
+	fep->rx_slot = i;
+}
+
+static void 
+emac_rx_clean(struct net_device *dev, int call_rx_fill)
+{
+	int i;
+	int error, frame_length;
+	struct ocp_enet_private *fep = dev->priv;
+	unsigned short ctrl;
+	int slots_walked = 0;
+
+	i = fep->rx_slot;
+
+	PKT_DEBUG(("emac_rx_clean() entry, call_rx_fill: %d, rx_slot: %d\n", call_rx_fill, fep->rx_slot));
+
+	do {
+		if (fep->rx_skb[i] == NULL)
+			goto skip;	/*we have already handled the packet but haved failed to alloc */
+		/* 
+		   since rx_desc is in uncached mem we don't keep reading it directly 
+		   we pull out a local copy of ctrl and do the checks on the copy.
+		 */
+		ctrl = fep->rx_desc[i].ctrl;
+		if (ctrl & MAL_RX_CTRL_EMPTY)
+			break;	/*we don't have any more ready packets */
+
+		if (ctrl & EMAC_BAD_RX_PACKET) {
+
+			fep->stats.rx_errors++;
+			fep->stats.rx_dropped++;
+
+			if (ctrl & EMAC_RX_ST_OE)
+				fep->stats.rx_fifo_errors++;
+			if (ctrl & EMAC_RX_ST_AE)
+				fep->stats.rx_frame_errors++;
+			if (ctrl & EMAC_RX_ST_BFCS)
+				fep->stats.rx_crc_errors++;
+			if (ctrl & (EMAC_RX_ST_RP | EMAC_RX_ST_PTL |
+				    EMAC_RX_ST_ORE | EMAC_RX_ST_IRE))
+				fep->stats.rx_length_errors++;
+		} else {
+
+			/* Send the skb up the chain. */
+		frame_length = fep->rx_desc[i].data_len - 4;
+
+			skb_put(fep->rx_skb[i], frame_length);
+			fep->rx_skb[i]->dev = dev;
+			fep->rx_skb[i]->protocol =
+			    eth_type_trans(fep->rx_skb[i], dev);
+
+			error = netif_rx(fep->rx_skb[i]);
+			if ((error == NET_RX_DROP) || (error == NET_RX_BAD)) {
+				fep->stats.rx_dropped++;
+			} else {
+				fep->stats.rx_packets++;
+				fep->stats.rx_bytes += frame_length;
+			}
+			fep->rx_skb[i] = NULL;
+		}
+	      skip:
+		slots_walked = 1;
+
+	} while ((i = (i + 1) % NUM_RX_BUFF) != fep->rx_slot);
+
+	PKT_DEBUG(("emac_rx_clean() exit, rx_slot: %d\n", fep->rx_slot));
+
+	if (slots_walked && call_rx_fill)
+           emac_rx_fill(dev, i);
+}
+
+static void
+emac_rxeob_dev(void *param, u32 chanmask)
+{
+	struct net_device *dev = param;
+	struct ocp_enet_private *fep = dev->priv;
+        unsigned long flags;
+
+	spin_lock_irqsave(&fep->lock, flags);
+	emac_rx_clean(dev, 1);
+	spin_unlock_irqrestore(&fep->lock, flags);
+}
+
+/*
+ * This interrupt should never occurr, we don't program
+ * the MAL for contiunous mode.
+ */
+static void
+emac_txde_dev(void *param, u32 chanmask)
+{
+	struct net_device *dev = param;
+	struct ocp_enet_private *fep = dev->priv;
+
+	printk(KERN_WARNING "%s: transmit descriptor error\n", dev->name);
+
+	emac_mac_dump(dev);
+	emac_mal_dump(dev);
+
+	/* Reenable the transmit channel */
+	mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
+}
+
+/*
+ * This interrupt should be very rare at best.  This occurs when
+ * the hardware has a problem with the receive descriptors.  The manual
+ * states that it occurs when the hardware cannot the receive descriptor
+ * empty bit is not set.  The recovery mechanism will be to
+ * traverse through the descriptors, handle any that are marked to be
+ * handled and reinitialize each along the way.  At that point the driver
+ * will be restarted.
+ */
+static void
+emac_rxde_dev(void *param, u32 chanmask)
+{
+ 	struct net_device *dev = param;
+     	struct ocp_enet_private *fep = dev->priv;
+        unsigned long flags;
+
+	printk(KERN_WARNING "%s: receive descriptor error\n", fep->ndev->name);
+
+	emac_mac_dump(dev);
+	emac_mal_dump(dev);
+	emac_desc_dump(dev);
+
+	/* Disable RX channel */
+	spin_lock_irqsave(&fep->lock, flags);
+       	mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
+       	
+	/* For now, charge the error against all emacs */
+	fep->stats.rx_errors++;
+
+	/* so do we have any good packets still? */
+	emac_rx_clean(dev,0);
+
+	/* When the interface is restarted it resets processing to the
+	 *  first descriptor in the table.
+	 */
+
+	fep->rx_slot = 0;
+	emac_rx_fill(dev, 0);
+
+	set_mal_dcrn(fep->mal, DCRN_MALRXEOBISR, fep->commac.rx_chan_mask);
+	set_mal_dcrn(fep->mal, DCRN_MALRXDEIR, fep->commac.rx_chan_mask);
+
+	/* Reenable the receive channels */
+       	mal_enable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
+	spin_unlock_irqrestore(&fep->lock, flags);
+}
+
+static void
+emac_mac_irq(int irq, void *dev_instance, struct pt_regs *regs)
+{
+	struct net_device *dev = dev_instance;
+	struct ocp_enet_private *fep = dev->priv;
+	volatile emac_t *emacp = fep->emacp;
+	unsigned long tmp_em0isr;
+
+	/* EMAC interrupt */
+	tmp_em0isr = in_be32(&emacp->em0isr);
+	if (tmp_em0isr & (EMAC_ISR_TE0 | EMAC_ISR_TE1)) {
+		/* This error is a hard transmit error - could retransmit */
+		fep->stats.tx_errors++;
+
+		/* Reenable the transmit channel */
+		mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
+
+	} else {
+		fep->stats.rx_errors++;
+	}
+
+	if (tmp_em0isr & EMAC_ISR_RP)
+		fep->stats.rx_length_errors++;
+	if (tmp_em0isr & EMAC_ISR_ALE)
+		fep->stats.rx_frame_errors++;
+	if (tmp_em0isr & EMAC_ISR_BFCS)
+		fep->stats.rx_crc_errors++;
+	if (tmp_em0isr & EMAC_ISR_PTLE)
+		fep->stats.rx_length_errors++;
+	if (tmp_em0isr & EMAC_ISR_ORE)
+		fep->stats.rx_length_errors++;
+	if (tmp_em0isr & EMAC_ISR_TE0)
+		fep->stats.tx_aborted_errors++;
+
+	emac_err_dump(dev, tmp_em0isr);
+
+	out_be32(&emacp->em0isr, tmp_em0isr);
+}
+
+static int
+emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	unsigned short ctrl;
+	unsigned long flags;
+	struct ocp_enet_private *fep = dev->priv;
+	volatile emac_t *emacp = fep->emacp;
+
+        spin_lock_irqsave(&fep->lock, flags);
+
+	PKT_DEBUG(("emac_start_xmit() entry, queue stopped: %d, fep->tx_cnt: %d\n",
+		netif_queue_stopped(dev), fep->tx_cnt));
+
+	/* That shouldn't happen... */
+	if (netif_queue_stopped(dev) || (fep->tx_cnt == NUM_TX_BUFF)) {
+		printk("%s: start_xmit called on full queue !\n", dev->name);
+		BUG();
+	}
+
+	if (++fep->tx_cnt == NUM_TX_BUFF) {
+		PKT_DEBUG(("emac_start_xmit() stopping queue\n"));
+		netif_stop_queue(dev);
+	}
+	
+	/* Store the skb buffer for later ack by the transmit end of buffer
+	 * interrupt.
+	 */
+	fep->tx_skb[fep->tx_slot] = skb;
+	consistent_sync((void *) skb->data, skb->len, PCI_DMA_TODEVICE);
+
+	ctrl = EMAC_TX_CTRL_DFLT;
+	if ((NUM_TX_BUFF - 1) == fep->tx_slot)
+		ctrl |= MAL_TX_CTRL_WRAP;
+	fep->tx_desc[fep->tx_slot].data_ptr = (char *) virt_to_phys(skb->data);
+	fep->tx_desc[fep->tx_slot].data_len = (short) skb->len;
+	fep->tx_desc[fep->tx_slot].ctrl = ctrl;
+
+	/* Send the packet out. */
+	out_be32(&emacp->em0tmr0, EMAC_TXM0_GNP0);
+
+	if (++fep->tx_slot == NUM_TX_BUFF)
+		fep->tx_slot = 0;
+
+	fep->stats.tx_packets++;
+	fep->stats.tx_bytes += skb->len;
+
+	PKT_DEBUG(("emac_start_xmit() exitn"));
+
+        spin_unlock_irqrestore(&fep->lock, flags);
+
+	return 0;
+}
+
+static int
+emac_adjust_to_link(struct ocp_enet_private *fep)
+{
+	volatile emac_t *emacp = fep->emacp;
+	unsigned long mode_reg;
+	int full_duplex, speed;
+
+	full_duplex = 0;
+	speed = SPEED_10;
+
+	/* set receive fifo to 4k and tx fifo to 2k */
+	mode_reg = EMAC_M1_RFS_4K | EMAC_M1_TX_FIFO_2K | EMAC_M1_APP |
+	    EMAC_M1_TR0_MULTI;
+       
+	/* Read link mode on PHY */
+    	if (fep->phy_mii.def->ops->read_link(&fep->phy_mii) == 0) {
+	        /* If an error occurred, we don't deal with it yet */
+		full_duplex = (fep->phy_mii.duplex == DUPLEX_FULL);
+		speed = fep->phy_mii.speed;	        
+	}
+
+	/* set speed (default is 10Mb) */
+	if (speed == SPEED_100) {
+		mode_reg |= EMAC_M1_MF_100MBPS;
+		if (fep->zmii_dev)
+			emac_zmii_port_speed(fep->zmii_dev, fep->zmii_input, 100);
+	} else {
+		mode_reg &= ~EMAC_M1_MF_100MBPS;
+		if (fep->zmii_dev)
+			emac_zmii_port_speed(fep->zmii_dev, fep->zmii_input, 10);
+	}
+
+	if (full_duplex)
+		mode_reg |= EMAC_M1_FDE | EMAC_M1_EIFC | EMAC_M1_IST;
+	else
+		mode_reg &= ~(EMAC_M1_FDE | EMAC_M1_EIFC | EMAC_M1_ILE);
+
+        LINK_DEBUG(("%s: adjust to link, speed: %d, duplex: %d, opened: %d\n",
+            fep->ndev->name, speed, full_duplex, fep->opened));
+
+        printk(KERN_INFO "%s: Speed: %s, %s duplex.\n",
+	       fep->ndev->name,
+	       speed == SPEED_100 ? "100" : "10",
+	       full_duplex ? "Full" : "Half");
+	if (fep->opened)
+	        out_be32(&emacp->em0mr1, mode_reg);
+
+	return 0;
+}
+
+static void
+__emac_set_multicast_list(struct net_device *dev)
+{
+	struct ocp_enet_private *fep = dev->priv;
+	volatile emac_t *emacp = fep->emacp;
+
+	if (dev->flags & IFF_PROMISC) {
+
+		/* If promiscuous mode is set then we do not need anything else */
+		out_be32(&emacp->em0rmr, EMAC_RMR_PME);
+
+	} else if (dev->flags & IFF_ALLMULTI || 32 < dev->mc_count) {
+
+		/* Must be setting up to use multicast.  Now check for promiscuous
+		 * multicast
+		 */
+		out_be32(&emacp->em0rmr,
+			 EMAC_RMR_IAE | EMAC_RMR_BAE | EMAC_RMR_PMME);
+	} else if (dev->flags & IFF_MULTICAST && 0 < dev->mc_count) {
+
+		unsigned short em0gaht[4] = { 0, 0, 0, 0 };
+		struct dev_mc_list *dmi;
+
+		/* Need to hash on the multicast address. */
+		for (dmi = dev->mc_list; dmi; dmi = dmi->next) {
+			unsigned long mc_crc;
+			unsigned int bit_number;
+
+			mc_crc = ether_crc(6, (char *) dmi->dmi_addr);
+			bit_number = 63 - (mc_crc >> 26);	/* MSB: 0 LSB: 63 */
+			em0gaht[bit_number >> 4] |=
+			    0x8000 >> (bit_number & 0x0f);
+		}
+		emacp->em0gaht1 = em0gaht[0];
+		emacp->em0gaht2 = em0gaht[1];
+		emacp->em0gaht3 = em0gaht[2];
+		emacp->em0gaht4 = em0gaht[3];
+
+		/* Turn on multicast addressing */
+		out_be32(&emacp->em0rmr,
+			 EMAC_RMR_IAE | EMAC_RMR_BAE | EMAC_RMR_MAE);
+
+	} else {
+		/* If multicast mode is not set then we are 
+		 * turning it off at this point 
+		 */
+		out_be32(&emacp->em0rmr, EMAC_RMR_IAE | EMAC_RMR_BAE);
+
+	}
+}
+
+static void
+emac_init_rings(struct net_device *dev)
+{
+	struct ocp_enet_private *ep = dev->priv;
+	int loop;
+
+	ep->tx_desc = (struct mal_descriptor *) ((char *) ep->mal->tx_virt_addr +
+				      (ep->mal_tx_chan * MAL_DT_ALIGN));
+	ep->rx_desc = (struct mal_descriptor *) ((char *) ep->mal->rx_virt_addr +
+				      (ep->mal_rx_chan * MAL_DT_ALIGN));
+
+	/* Fill in the transmit descriptor ring. */
+	for (loop = 0; loop < NUM_TX_BUFF; loop++) {
+                if (ep->tx_skb[loop])
+                        dev_kfree_skb_irq(ep->tx_skb[loop]);
+		ep->tx_skb[loop] = NULL;
+		ep->tx_desc[loop].ctrl = 0;
+		ep->tx_desc[loop].data_len = 0;
+		ep->tx_desc[loop].data_ptr = NULL;
+	}
+	ep->tx_desc[loop - 1].ctrl |= MAL_TX_CTRL_WRAP;
+
+	/* Format the receive descriptor ring. */
+	ep->rx_slot = 0;
+	emac_rx_fill(dev, 0);
+	if (ep->rx_slot != 0) {
+		printk(KERN_ERR
+		       "%s: Not enough mem for RxChain durning Open?\n",
+		       dev->name);
+		/*We couldn't fill the ring at startup?
+		 *We could clean up and fail to open but right now we will try to
+		 *carry on. It may be a sign of a bad NUM_RX_BUFF value
+		 */
+	}
+
+	ep->tx_cnt = 0;
+	ep->tx_slot = 0;
+	ep->ack_slot = 0;
+}
+
+static void
+emac_reset_configure(struct ocp_enet_private *fep)
+{
+	volatile emac_t *emacp = fep->emacp;
+        int i;
+
+	mal_disable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
+	mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
+
+	/* Reset the EMAC */
+	out_be32(&emacp->em0mr0, EMAC_M0_SRST);
+	udelay(20);
+        for (i=0; i<100; i++) {
+                if ((in_be32(&emacp->em0mr0) & EMAC_M0_SRST) == 0)
+                        break;
+                udelay(10);
+        }
+	
+        if (i >= 100) {
+                printk(KERN_ERR "%s: Cannot reset EMAC\n", fep->ndev->name);
+		return;
+        }
+
+	/* Switch IRQs off for now */
+	out_be32(&emacp->em0iser, 0);
+
+	/* Configure MAL rx channel */
+	mal_set_rcbs(fep->mal, fep->mal_rx_chan, DESC_BUF_SIZE_REG);
+
+	/* set the high address */
+	out_be32(&emacp->em0iahr, (fep->ndev->dev_addr[0] << 8) | fep->ndev->dev_addr[1]);
+
+	/* set the low address */
+	out_be32(&emacp->em0ialr,
+		 (fep->ndev->dev_addr[2] << 24) | (fep->ndev->dev_addr[3] << 16)
+		 | (fep->ndev->dev_addr[4] << 8) | fep->ndev->dev_addr[5]);
+
+        /* Adjust to link */
+	if (netif_carrier_ok(fep->ndev))
+	    emac_adjust_to_link(fep);
+
+	/* enable broadcast and individual address */
+	out_be32(&emacp->em0rmr, EMAC_RMR_IAE | EMAC_RMR_BAE);
+
+
+        /* Reconfigure multicast */
+        __emac_set_multicast_list(fep->ndev);
+
+	/* set transmit request threshold register */
+	out_be32(&emacp->em0trtr, EMAC_TRTR_256);
+
+
+	/* set receive low/high water mark register */
+#ifdef CONFIG_440
+	/* 440GP has a 64 byte burst length */
+	out_be32(&emacp->em0rwmr, 0x80009000);
+	out_be32(&emacp->em0tmr1, 0xf8640000);
+#else
+	/* 405s have a 16 byte burst length */
+	out_be32(&emacp->em0rwmr, 0x0f002000);
+#endif				/* CONFIG_440 */
+
+	/* set frame gap */
+	out_be32(&emacp->em0ipgvr, CONFIG_IBM_OCP_ENET_GAP);
+
+        /* Init ring buffers */
+        emac_init_rings(fep->ndev);
+}
+
+static void
+emac_kick(struct ocp_enet_private *fep)
+{
+	volatile emac_t *emacp = fep->emacp;
+	unsigned long emac_ier;
+
+	emac_ier = EMAC_ISR_PP | EMAC_ISR_BP | EMAC_ISR_RP |
+	    EMAC_ISR_SE | EMAC_ISR_PTLE | EMAC_ISR_ALE |
+	    EMAC_ISR_BFCS | EMAC_ISR_ORE | EMAC_ISR_IRE;
+
+	out_be32(&emacp->em0iser, emac_ier);
+
+	/* enable all MAL transmit and receive channels */
+	mal_enable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
+	mal_enable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
+
+	/* set transmit and receive enable */
+	out_be32(&emacp->em0mr0, EMAC_M0_TXE | EMAC_M0_RXE);
+}
+
+static void
+emac_start_link(struct ocp_enet_private *fep, struct ethtool_cmd *ep)
+{
+	u32 advertise;
+	int autoneg;
+	int forced_speed;
+	int forced_duplex;
+
+	/* Default advertise */
+	advertise = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+		    ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
+	autoneg = fep->want_autoneg;
+	forced_speed = fep->phy_mii.speed;
+	forced_duplex = fep->phy_mii.duplex;
+
+	/* Setup link parameters */
+	if (ep) {
+	    if (ep->autoneg == AUTONEG_ENABLE) {
+		advertise = ep->advertising;
+		autoneg = 1;
+	    } else {
+		autoneg = 0;
+		forced_speed = ep->speed;
+		forced_duplex = ep->duplex;
+	    }
+	}
+
+	/* Configure PHY & start aneg */
+	fep->want_autoneg = autoneg;
+	if (autoneg) {
+                LINK_DEBUG(("%s: start link aneg, advertise: 0x%x\n",
+                        fep->ndev->name, advertise));
+		fep->phy_mii.def->ops->setup_aneg(&fep->phy_mii, advertise);
+        } else {
+                LINK_DEBUG(("%s: start link forced, speed: %d, duplex: %d\n",
+                        fep->ndev->name, forced_speed, forced_duplex));
+		fep->phy_mii.def->ops->setup_forced(&fep->phy_mii, forced_speed,
+				forced_duplex);
+        }
+	fep->timer_ticks = 0;
+	mod_timer(&fep->link_timer, jiffies + HZ);
+}
+
+static void
+emac_link_timer(unsigned long data)
+{
+        struct ocp_enet_private *fep = (struct ocp_enet_private *)data;
+	int link;
+
+	if (fep->going_away)
+		return;
+
+	spin_lock_irq(&fep->lock);
+	
+	link = fep->phy_mii.def->ops->poll_link(&fep->phy_mii);
+        LINK_DEBUG(("%s: poll_link: %d\n", fep->ndev->name, link));
+
+	if (link == netif_carrier_ok(fep->ndev)) {
+	        if (!link && fep->want_autoneg && (++fep->timer_ticks) > 10)
+		        emac_start_link(fep, NULL);
+	        goto out;
+        }
+	printk(KERN_INFO "%s: Link is %s\n", fep->ndev->name, link ? "Up" : "Down");
+	if (link) {
+	        netif_carrier_on(fep->ndev);
+                /* Chip needs a full reset on config change. That sucks, so I
+                 * should ultimately move that to some tasklet to limit
+                 * latency peaks caused by this code
+                 */
+                emac_reset_configure(fep);
+                emac_kick(fep);
+	} else {
+	        fep->timer_ticks = 0;
+	        netif_carrier_off(fep->ndev);
+	}
+out:
+	mod_timer(&fep->link_timer, jiffies + HZ);
+	spin_unlock_irq(&fep->lock);
+}
+
+static void
+emac_set_multicast_list(struct net_device *dev)
+{
+	struct ocp_enet_private *fep = dev->priv;
+
+	spin_lock_irq(&fep->lock);
+        __emac_set_multicast_list(dev);
+	spin_unlock_irq(&fep->lock);
+}
+
+static int
+emac_ethtool(struct net_device *dev, void* ep_user)
+{
+        struct ocp_enet_private *fep = dev->priv;
+        struct ethtool_cmd ecmd;
+        unsigned long features = fep->phy_mii.def->features;
+
+        if (copy_from_user(&ecmd, ep_user, sizeof(ecmd)))
+                return -EFAULT;
+
+        switch(ecmd.cmd) {
+        case ETHTOOL_GDRVINFO: {
+                struct ethtool_drvinfo info;
+                memset(&info, 0, sizeof(info));
+                info.cmd = ETHTOOL_GDRVINFO;
+                strncpy(info.driver, DRV_NAME, ETHTOOL_BUSINFO_LEN);
+                strncpy(info.version, DRV_VERSION, ETHTOOL_BUSINFO_LEN);
+                info.fw_version[0] = '\0';
+                sprintf(info.bus_info, "OCP EMAC %d", fep->ocpdev->def->index);
+                info.regdump_len = 0;
+                if (copy_to_user(ep_user, &info, sizeof(info)))
+                        return -EFAULT;
+                return 0;
+                }
+
+        case ETHTOOL_GSET:
+                ecmd.supported = features;
+                ecmd.port = PORT_MII;
+                ecmd.transceiver = XCVR_EXTERNAL;
+                ecmd.phy_address = fep->mii_phy_addr;
+                spin_lock_irq(&fep->lock);
+                ecmd.autoneg = fep->want_autoneg;
+                ecmd.speed = fep->phy_mii.speed;
+                ecmd.duplex = fep->phy_mii.duplex;
+                spin_unlock_irq(&fep->lock);
+                if (copy_to_user(ep_user, &ecmd, sizeof(ecmd)))
+                        return -EFAULT;
+                return 0;
+
+        case ETHTOOL_SSET:
+                if (!capable(CAP_NET_ADMIN))
+                        return -EPERM;
+                
+                if (ecmd.autoneg != AUTONEG_ENABLE &&
+                    ecmd.autoneg != AUTONEG_DISABLE)
+                        return -EINVAL;
+                if (ecmd.autoneg == AUTONEG_ENABLE &&
+                    ecmd.advertising == 0)
+                        return -EINVAL;
+                if (ecmd.duplex != DUPLEX_HALF && ecmd.duplex != DUPLEX_FULL)
+                        return -EINVAL;
+                if (ecmd.autoneg == AUTONEG_DISABLE)
+                        switch(ecmd.speed) {
+                        case SPEED_10:
+                                if (ecmd.duplex == DUPLEX_HALF &&
+                                    (features & SUPPORTED_10baseT_Half) == 0)
+                                        return -EINVAL;
+                                if (ecmd.duplex == DUPLEX_FULL &&
+                                    (features & SUPPORTED_10baseT_Full) == 0)
+                                        return -EINVAL;
+                                break;
+                        case SPEED_100:
+                                if (ecmd.duplex == DUPLEX_HALF &&
+                                    (features & SUPPORTED_100baseT_Half) == 0)
+                                        return -EINVAL;
+                                if (ecmd.duplex == DUPLEX_FULL &&
+                                    (features & SUPPORTED_100baseT_Full) == 0)
+                                        return -EINVAL;
+                                break;
+                        default:
+                                return -EINVAL;
+                        }
+                else if ((features & SUPPORTED_Autoneg) == 0)
+                        return -EINVAL;
+                spin_lock_irq(&fep->lock);
+                emac_start_link(fep, &ecmd);
+                spin_unlock_irq(&fep->lock);                
+                return 0;
+
+        case ETHTOOL_NWAY_RST:
+                if (!fep->want_autoneg)
+                        return -EINVAL;
+                spin_lock_irq(&fep->lock);
+                emac_start_link(fep, NULL);
+                spin_unlock_irq(&fep->lock);
+                return 0;
+
+        case ETHTOOL_GLINK: {
+                struct ethtool_value edata;
+                memset(&edata, 0, sizeof(edata));
+                edata.cmd = ETHTOOL_GLINK;
+                edata.data = netif_carrier_ok(dev);
+                if (copy_to_user(ep_user, &edata, sizeof(edata)))
+                        return -EFAULT;
+                return 0;
+                }
+        }
+
+        return -EOPNOTSUPP;
+}
+
+static int
+emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct ocp_enet_private *fep = dev->priv;
+	uint *data = (uint *) & rq->ifr_data;
+
+	switch (cmd) {
+        case SIOCETHTOOL:
+                return emac_ethtool(dev, rq->ifr_data);
+	case SIOCDEVPRIVATE:
+	case SIOCGMIIPHY:
+		data[0] = fep->mii_phy_addr;
+		/*FALLTHRU*/
+	case SIOCDEVPRIVATE + 1:
+	case SIOCGMIIREG:
+		data[3] = emac_phy_read(dev, fep->mii_phy_addr, data[1]);
+		return 0;
+	case SIOCDEVPRIVATE + 2:
+	case SIOCSMIIREG:
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+
+		emac_phy_write(dev, fep->mii_phy_addr, data[1], data[2]);
+		return 0;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+ 
+static int
+emac_open(struct net_device *dev)
+{
+	struct ocp_enet_private *fep = dev->priv;
+	int rc;
+
+	spin_lock_irq(&fep->lock);
+
+	fep->opened = 1;
+        
+        /* Reset & configure the chip */
+        emac_reset_configure(fep);
+
+	spin_unlock_irq(&fep->lock);
+
+        /* Request our interrupt lines */
+	rc = request_irq(dev->irq, emac_mac_irq, 0, "OCP EMAC MAC", dev);
+	if (rc != 0)
+		goto bail;
+	rc = request_irq(fep->wol_irq, emac_wakeup_irq, 0, "OCP EMAC Wakeup", dev);
+	if (rc != 0) {
+		free_irq(dev->irq, dev);
+		goto bail;
+	}
+        /* Kick the chip rx & tx channels into life */ 
+	spin_lock_irq(&fep->lock);
+        emac_kick(fep);
+        spin_unlock_irq(&fep->lock);
+
+	netif_start_queue(dev);
+bail:
+	return rc;
+}
+
+static int
+emac_close(struct net_device *dev)
+{
+	struct ocp_enet_private *fep = dev->priv;
+	volatile emac_t *emacp = fep->emacp;
+
+	/* XXX Stop IRQ emitting here */
+	spin_lock_irq(&fep->lock);
+	fep->opened = 0;
+	mal_disable_tx_channels(fep->mal, fep->commac.tx_chan_mask);
+	mal_disable_rx_channels(fep->mal, fep->commac.rx_chan_mask);
+	netif_stop_queue(dev);
+
+	out_be32(&emacp->em0mr0, EMAC_M0_SRST);
+	udelay(10);
+
+	if (emacp->em0mr0 & EMAC_M0_SRST) {
+		/*not sure what to do here hopefully it clears before another open */
+		printk(KERN_ERR "%s: Phy SoftReset didn't clear, no link?\n",
+		       dev->name);
+	}
+
+	/* Free the irq's */
+	free_irq(dev->irq, dev);
+	free_irq(fep->wol_irq, dev);
+
+	spin_unlock_irq(&fep->lock);
+
+	return 0;
+}
+
+static void
+emac_remove(struct ocp_device *ocpdev)
+{
+	struct net_device *dev = ocp_get_drvdata(ocpdev);
+	struct ocp_enet_private *ep = dev->priv;
+
+	/* FIXME: locking, races, ... */
+	ep->going_away = 1;
+	ocp_set_drvdata(ocpdev, NULL);
+	if (ep->zmii_dev)
+		emac_fini_zmii(ep->zmii_dev);
+
+	unregister_netdev(dev);
+	del_timer_sync(&ep->link_timer);
+	mal_unregister_commac(ep->mal, &ep->commac);
+	iounmap((void *)ep->emacp);
+	kfree(dev);
+}
+
+struct mal_commac_ops emac_commac_ops = {
+	.txeob = &emac_txeob_dev,
+	.txde = &emac_txde_dev,
+	.rxeob = &emac_rxeob_dev,
+	.rxde = &emac_rxde_dev,
+};
+
+static int
+emac_probe(struct ocp_device *ocpdev)
+{
+	int rc = 0, i;
+	bd_t *bd;
+	struct net_device *ndev;
+	struct ocp_enet_private *ep;
+	struct ocp_device *maldev;
+	struct ibm_ocp_mal *mal;
+	struct ocp_func_emac_data *emacdata;
+	struct ocp_device *mdiodev;
+	struct net_device *mdio_ndev = NULL;
+	int commac_reg = 0;
+	u32 phy_map;
+	
+	emacdata = (struct ocp_func_emac_data *)ocpdev->def->additions;
+	if (emacdata == NULL) {
+		printk(KERN_ERR "emac%d: Missing additional datas !\n", ocpdev->def->index);
+		return -ENODEV;
+	}
+
+	/* Wait for MAL to show up */
+	maldev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_MAL, emacdata->mal_idx);
+	if (maldev == NULL)
+		return -EAGAIN;
+	/* Check if MAL driver attached yet */
+	mal = (struct ibm_ocp_mal *)ocp_get_drvdata(maldev);
+	if (mal == NULL)
+		return -EAGAIN;
+
+	/* If we depend on another EMAC for MDIO, wait for it to show up */
+	if (emacdata->mdio_idx >= 0 && emacdata->mdio_idx != ocpdev->def->index) {
+		mdiodev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_EMAC, emacdata->mdio_idx);
+		if (mdiodev == NULL)
+			return -EAGAIN;
+		mdio_ndev = (struct net_device *)ocp_get_drvdata(mdiodev);
+		if (mdio_ndev == NULL)
+			return -EAGAIN;
+	}
+
+	/* Allocate our net_device structure */
+	ndev = alloc_etherdev(sizeof (struct ocp_enet_private));
+	if (ndev == NULL) {
+		printk(KERN_ERR
+		       "emac%d: Could not allocate ethernet device.\n", ocpdev->def->index);
+		return -ENOMEM;
+	}
+	ep = ndev->priv;
+	memset(ep, 0, sizeof(*ep));
+	ep->ndev = ndev;
+	ep->ocpdev = ocpdev;
+	ndev->irq = ocpdev->def->irq;
+	ep->wol_irq = emacdata->wol_irq;
+	ep->mdio_dev = mdio_ndev;
+	ocp_set_drvdata(ocpdev, ndev);
+	spin_lock_init(&ep->lock);
+
+	/* Fill out MAL informations and register commac */
+	ep->mal = mal;
+	ep->mal_tx_chan = emacdata->mal_tx1_chan;
+	ep->mal_rx_chan = emacdata->mal_rx_chan;
+	ep->commac.ops = &emac_commac_ops;
+	ep->commac.dev = ndev;
+	ep->commac.tx_chan_mask = MAL_CHAN_MASK(ep->mal_tx_chan);
+	ep->commac.rx_chan_mask = MAL_CHAN_MASK(ep->mal_rx_chan);
+	rc = mal_register_commac(ep->mal, &ep->commac);
+	if (rc != 0)
+		goto bail;
+	commac_reg = 1;
+
+	/* Map our MMIOs */
+	ep->emacp = (volatile emac_t *)ioremap(ocpdev->def->paddr, sizeof (emac_t));
+
+	/* Check if we need to attach to a ZMII */
+	if (emacdata->zmii_idx >= 0) {
+		ep->zmii_input = emacdata->zmii_mux;
+		ep->zmii_dev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_ZMII, emacdata->zmii_idx);
+		if (ep->zmii_dev == NULL)
+	                printk(KERN_WARNING "emac%d: ZMII %d requested but not found !\n",
+	                	ocpdev->def->index, emacdata->zmii_idx);
+		else if ((rc = emac_init_zmii(ep->zmii_dev, ZMII_AUTO)) != 0)
+			goto bail;
+	}
+
+	/* Reset the EMAC */
+	out_be32(&ep->emacp->em0mr0, EMAC_M0_SRST);
+	udelay(20);
+        for (i=0; i<100; i++) {
+                if ((in_be32(&ep->emacp->em0mr0) & EMAC_M0_SRST) == 0)
+                        break;
+                udelay(10);
+        }
+	
+        if (i >= 100) {
+                printk(KERN_ERR "emac%d: Cannot reset EMAC\n", ocpdev->def->index);
+		rc = -ENXIO;
+		goto bail;
+        }
+
+	/* Init link monitoring timer */
+	init_timer(&ep->link_timer);
+	ep->link_timer.function = emac_link_timer;
+	ep->link_timer.data = (unsigned long) ep;
+	ep->timer_ticks = 0;
+
+	/* Fill up the mii_phy structure */
+	ep->phy_mii.dev = ndev;
+	ep->phy_mii.mdio_read = emac_phy_read;
+	ep->phy_mii.mdio_write = emac_phy_write;
+
+	/* Find PHY */
+	phy_map = emac_phy_map[ocpdev->def->index] | busy_phy_map;
+	for (i = 0; i <= 0x1f; i++, phy_map >>= 1) {
+		if ((phy_map & 0x1) == 0) {
+			int  val = emac_phy_read(ndev, i, MII_BMCR);
+			if (val != 0xffff && val != -1)
+			        break;
+		}
+	}
+	if (i == 0x20) {
+	        printk(KERN_WARNING "emac%d: Can't find PHY.\n", ocpdev->def->index);
+		rc = -ENODEV;
+		goto bail;
+	}
+	busy_phy_map |= 1 << i;
+	ep->mii_phy_addr = i;
+	rc = mii_phy_probe(&ep->phy_mii, i);
+	if (rc) {
+	        printk(KERN_WARNING "emac%d: Failed to probe PHY type.\n", ocpdev->def->index);
+		rc = -ENODEV;
+		goto bail;
+	}
+
+	/* Setup initial PHY config & startup aneg */
+	if (ep->phy_mii.def->ops->init)
+	        ep->phy_mii.def->ops->init(&ep->phy_mii);
+	netif_carrier_off(ndev);
+        if (ep->phy_mii.def->features & SUPPORTED_Autoneg)
+                ep->want_autoneg = 1;
+	emac_start_link(ep, NULL);
+
+
+	/* read the MAC Address */
+	bd = (bd_t *) __res;
+	for (i = 0; i < 6; i++)
+		ndev->dev_addr[i] = bd->BD_EMAC_ADDR(ocpdev->def->index, i);	/* Marco to disques array */
+
+	/* Fill in the driver function table */
+	ndev->open = &emac_open;
+	ndev->hard_start_xmit = &emac_start_xmit;
+	ndev->stop = &emac_close;
+	ndev->get_stats = &emac_stats;
+	ndev->set_multicast_list = &emac_set_multicast_list;
+	ndev->do_ioctl = &emac_ioctl;
+
+	SET_MODULE_OWNER(ndev);
+	
+	rc = register_netdev(ndev);
+	if (rc != 0)
+		goto bail;
+
+	printk("%s: IBM emac, MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+		ndev->name,
+		ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
+		ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
+	printk(KERN_INFO "%s: Found %s PHY (0x%02x)\n",
+		ndev->name, ep->phy_mii.def->name, ep->mii_phy_addr);
+
+
+bail:
+	if (rc && commac_reg)
+		mal_unregister_commac(ep->mal, &ep->commac);
+	if (rc && ndev)
+		kfree(ndev);
+
+	return rc;
+
+}
+
+/* Structure for a device driver */
+static struct ocp_device_id emac_ids[] =
+{
+	{ .vendor = OCP_ANY_ID, .function = OCP_FUNC_EMAC },
+	{ .vendor = OCP_VENDOR_INVALID }
+};
+
+static struct ocp_driver emac_driver =
+{
+	.name 		= "emac",
+	.id_table	= emac_ids,
+	
+	.probe		= emac_probe,
+	.remove		= emac_remove,
+};
+
+static int __init
+emac_init(void)
+{
+	int rc;
+	
+        printk(KERN_INFO DRV_NAME ": " DRV_DESC ", version " DRV_VERSION "\n");
+        printk(KERN_INFO "Maintained by " DRV_AUTHOR "\n");
+
+	if (skb_res > 2) {
+	    printk(KERN_WARNING "Invalid skb_res: %d, cropping to 2\n", skb_res);
+	    skb_res = 2;
+	}
+	rc = ocp_register_driver(&emac_driver);
+	if (rc == 0) {
+		ocp_unregister_driver(&emac_driver);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+
+
+static void __exit
+emac_exit(void)
+{
+	ocp_unregister_driver(&emac_driver);
+}
+
+module_init(emac_init);
+module_exit(emac_exit);
diff -urN linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_ocp_enet.h linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_ocp_enet.h
--- linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_ocp_enet.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_ocp_enet.h	2003-07-12 02:52:25.000000000 -0700
@@ -0,0 +1,160 @@
+/*
+ * ibm_ocp_enet.h
+ *
+ * Ethernet driver for the built in ethernet on the IBM 405 PowerPC
+ * processor.
+ *
+ *      Armin Kuster akuster@mvista.com
+ *      Sept, 2001
+ *
+ *      Orignial driver
+ *         Johnnie Peters
+ *         jpeters@mvista.com
+ *
+ * Copyright 2000 MontaVista Softare Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Version: 1.0: Name change - armin
+ *  Version: 1.0: Added extern prototypes for new mal func. - David M.
+ *  		: removed #ifdef for irqs.i - Armin
+ *  		: added irq_resourse to private data struct. 
+ *
+ *  Version: 1.1: Added new min/max value for phy & removed unused phy_id_done - *			- andrew May
+ *  Version: 1.2: added all emac extern protos here - Armin
+ *
+ *  Version: 1.3: Using CONFIG_IBM_OCP_ZMII instead of ZMII_NUMS > 0
+ *
+ *  Version: 1.3: Name change *_driver to *_dev
+ *  Version: 1.4: removed irq_resource & BL_* defines
+ *
+ */
+
+#ifndef _IBM_OCP_ENET_H_
+#define _IBM_OCP_ENET_H_
+
+#include <linux/netdevice.h>
+#include <asm/ocp.h>
+#include <asm/mmu.h>		/* For phys_addr_t */
+
+#include "ibm_emac.h"
+#include "ibm_ocp_phy.h"
+#include "ibm_ocp_zmii.h"
+#include "ibm_ocp_mal.h"
+
+#ifndef CONFIG_IBM_OCP_ENET_TX_BUFF
+#define NUM_TX_BUFF		64
+#define NUM_RX_BUFF		64
+#else
+#define NUM_TX_BUFF		CONFIG_IBM_OCP_ENET_TX_BUFF
+#define NUM_RX_BUFF		CONFIG_IBM_OCP_ENET_RX_BUFF
+#endif
+
+/* This does 16 byte alignment, exactly what we need.
+ * The packet length includes FCS, but we don't want to
+ * include that when passing upstream as it messes up
+ * bridging applications.
+ */
+#ifndef CONFIG_IBM_OCP_ENET_SKB_RES
+#define SKB_RES 2
+#else
+#define SKB_RES CONFIG_IBM_OCP_ENET_SKB_RES
+#endif
+
+/* Note about alignement. alloc_skb() returns a cache line
+ * aligned buffer. However, dev_alloc_skb() will add 16 more
+ * bytes and "reserve" them, so our buffer will actually end
+ * on a half cache line. What we do is to use directly
+ * alloc_skb, allocate 16 more bytes to match the total amount
+ * allocated by dev_alloc_skb(), but we don't reserve.
+ */
+#define MAX_NUM_BUF_DESC	255
+#define DESC_RX_BUF_SIZE	1536
+#define DESC_BUF_SIZE_REG	(DESC_RX_BUF_SIZE / 16)
+
+/* Transmitter timeout. */
+#define TX_TIMEOUT		(2*HZ)
+#define OCP_RESET_DELAY		50
+#define MDIO_DELAY		2
+
+/* Power managment shift registers */
+#define IBM_CPM_EMMII	0	/* Shift value for MII */
+#define IBM_CPM_EMRX	1	/* Shift value for recv */
+#define IBM_CPM_EMTX	2	/* Shift value for MAC */
+#define IBM_CPM_EMAC(x)	(((x)>>IBM_CPM_EMMII) | ((x)>>IBM_CPM_EMRX) | ((x)>>IBM_CPM_EMTX))
+
+#ifdef CONFIG_IBM_OCP_ENET_ERROR_MSG
+void emac_serr_dump_0(struct net_device *dev);
+void emac_serr_dump_1(struct net_device *dev);
+void emac_err_dump(struct net_device *dev, int em0isr);
+void emac_phy_dump(struct net_device *);
+void emac_desc_dump(struct net_device *);
+void emac_mac_dump(struct net_device *);
+void emac_mal_dump(struct net_device *);
+#else
+#define emac_serr_dump_0(dev) do { } while (0)
+#define emac_serr_dump_1(dev) do { } while (0)
+#define emac_err_dump(dev,x) do { } while (0)
+#define emac_phy_dump(dev) do { } while (0)
+#define emac_desc_dump(dev) do { } while (0)
+#define emac_mac_dump(dev) do { } while (0)
+#define emac_mal_dump(dev) do { } while (0)
+#endif
+
+
+struct ocp_enet_private {
+	struct sk_buff *tx_skb[NUM_TX_BUFF];
+	struct sk_buff *rx_skb[NUM_RX_BUFF];
+	struct mal_descriptor *tx_desc;
+	struct mal_descriptor *rx_desc;
+	struct mal_descriptor *rx_dirty;
+	struct net_device_stats stats;
+	int tx_cnt;
+	int rx_slot;
+	int dirty_rx;
+	int tx_slot;
+	int ack_slot;
+
+	struct mii_phy phy_mii;
+        int mii_phy_addr;
+        int want_autoneg;
+        int timer_ticks;
+	struct timer_list link_timer;
+	struct net_device *mdio_dev;
+
+	struct ocp_device *zmii_dev;
+	int zmii_input;
+
+	struct ibm_ocp_mal *mal;
+	int mal_tx_chan, mal_rx_chan;
+	struct mal_commac commac;
+
+        int opened;
+        int going_away;
+        int wol_irq;
+	volatile emac_t *emacp;
+	struct ocp_device *ocpdev;
+        struct net_device *ndev;
+        spinlock_t lock;
+};
+
+
+#endif				/* _IBM_OCP_ENET_H_ */
diff -urN linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_ocp_mal.c linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_ocp_mal.c
--- linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_ocp_mal.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_ocp_mal.c	2003-07-12 02:52:25.000000000 -0700
@@ -0,0 +1,484 @@
+/*
+ * ibm_ocp_mal.c
+ *
+ *      Armin Kuster akuster@mvista.com
+ *      Juen, 2002
+ *
+ * Copyright 2002 MontaVista Softare Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *  
+ *  TODO: Move to a separate module
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/ocp.h>
+
+#include "ibm_ocp_mal.h"
+
+// Locking: Should we share a lock with the client ? The client could provide
+// a lock pointer (optionally) in the commac structure... I don't think this is
+// really necessary though
+
+
+/* This lock protects the commac list. On today UP implementations, it's
+ * really only used as IRQ protection in mal_{register,unregister}_commac()
+ */
+static rwlock_t	mal_list_lock = RW_LOCK_UNLOCKED;
+
+int
+mal_register_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac)
+{
+	unsigned long flags;
+
+	write_lock_irqsave(&mal_list_lock, flags);
+	
+	/* Don't let multiple commacs claim the same channel */
+	if ( (mal->tx_chan_mask & commac->tx_chan_mask) ||
+	     (mal->rx_chan_mask & commac->rx_chan_mask) ) {
+	     	write_unlock(&mal_list_lock);
+		return -EBUSY;
+	}
+
+	mal->tx_chan_mask |= commac->tx_chan_mask;
+	mal->rx_chan_mask |= commac->rx_chan_mask;
+
+	list_add(&commac->list, &mal->commac);
+
+     	write_unlock_irqrestore(&mal_list_lock, flags);
+
+	MOD_INC_USE_COUNT;
+
+	return 0;
+}
+
+int
+mal_unregister_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac)
+{
+	unsigned long flags;
+
+	write_lock_irqsave(&mal_list_lock, flags);
+
+	mal->tx_chan_mask &= ~commac->tx_chan_mask;
+	mal->rx_chan_mask &= ~commac->rx_chan_mask;
+
+	list_del_init(&commac->list);
+
+     	write_unlock_irqrestore(&mal_list_lock, flags);
+
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel, unsigned long size)
+{
+	switch (channel) {
+	case 0:
+		set_mal_dcrn(mal, DCRN_MALRCBS0, size);
+		break;
+#ifdef DCRN_RCBS1
+	case 1:
+		set_mal_dcrn(mal, DCRN_MALRCBS1, size);
+		break;
+#endif
+#ifdef DCRN_RCBS2
+	case 2:
+		set_mal_dcrn(mal, DCRN_MALRCBS2, size);
+		break;
+#endif
+#ifdef DCRN_RCBS3
+	case 3:
+		set_mal_dcrn(mal, DCRN_MALRCBS3, size);
+		break;
+#endif
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void
+mal_serr(int irq, void *dev_instance, struct pt_regs *regs)
+{
+	struct ibm_ocp_mal *mal = dev_instance;
+	unsigned long mal_error;
+
+	/*
+	 * This SERR applies to one of the devices on the MAL, here we charge
+	 * it against the first EMAC registered for the MAL.
+	 */
+
+	mal_error = get_mal_dcrn(mal, DCRN_MALESR);
+
+	printk(KERN_ERR "%s: System Error (MALESR=%lx)\n", 
+	       "MAL" /* FIXME: get the name right */, mal_error);
+
+	/* FIXME: decipher error */
+	/* DIXME: distribute to commacs, if possible */
+
+	/* Clear the error status register */
+	set_mal_dcrn(mal, DCRN_MALESR, mal_error);
+}
+
+static void
+mal_txeob(int irq, void *dev_instance, struct pt_regs *regs)
+{
+	struct ibm_ocp_mal *mal = dev_instance;
+	struct list_head *l;
+	unsigned long isr;
+
+	isr = get_mal_dcrn(mal, DCRN_MALTXEOBISR);
+	set_mal_dcrn(mal, DCRN_MALTXEOBISR, isr);
+
+	read_lock(&mal_list_lock);
+	list_for_each(l, &mal->commac) {
+		struct mal_commac *mc = list_entry(l, struct mal_commac, list);
+
+		if (isr & mc->tx_chan_mask) {
+			mc->ops->txeob(mc->dev, isr & mc->tx_chan_mask);
+		}
+	}
+	read_unlock(&mal_list_lock);
+}
+
+static void
+mal_rxeob(int irq, void *dev_instance, struct pt_regs *regs)
+{
+	struct ibm_ocp_mal *mal = dev_instance;
+	struct list_head *l;
+	unsigned long isr;
+
+
+	isr = get_mal_dcrn(mal, DCRN_MALRXEOBISR);
+	set_mal_dcrn(mal, DCRN_MALRXEOBISR, isr);
+
+	read_lock(&mal_list_lock);
+	list_for_each(l, &mal->commac) {
+		struct mal_commac *mc = list_entry(l, struct mal_commac, list);
+
+		if (isr & mc->rx_chan_mask) {
+			mc->ops->rxeob(mc->dev, isr & mc->rx_chan_mask);
+		}
+	}
+	read_unlock(&mal_list_lock);
+}
+
+static void
+mal_txde(int irq, void *dev_instance, struct pt_regs *regs)
+{
+	struct ibm_ocp_mal *mal = dev_instance;
+	struct list_head *l;
+	unsigned long deir;
+
+	deir = get_mal_dcrn(mal, DCRN_MALTXDEIR);
+
+	/* FIXME: print which MAL correctly */
+	printk(KERN_WARNING "%s: Tx descriptor error (MALTXDEIR=%lx)\n",
+	       "MAL", deir);
+
+	read_lock(&mal_list_lock);
+	list_for_each(l, &mal->commac) {
+		struct mal_commac *mc = list_entry(l, struct mal_commac, list);
+
+		if (deir & mc->tx_chan_mask) {
+			mc->ops->txde(mc->dev, deir & mc->tx_chan_mask);
+		}
+	}
+	read_unlock(&mal_list_lock);
+}
+
+/*
+ * This interrupt should be very rare at best.  This occurs when
+ * the hardware has a problem with the receive descriptors.  The manual
+ * states that it occurs when the hardware cannot the receive descriptor
+ * empty bit is not set.  The recovery mechanism will be to
+ * traverse through the descriptors, handle any that are marked to be
+ * handled and reinitialize each along the way.  At that point the driver
+ * will be restarted.
+ */
+static void
+mal_rxde(int irq, void *dev_instance, struct pt_regs *regs)
+{
+	struct ibm_ocp_mal *mal = dev_instance;
+	struct list_head *l;
+	unsigned long deir;
+
+	deir = get_mal_dcrn(mal, DCRN_MALRXDEIR);
+
+	/*
+	 * This really is needed.  This case encountered in stress testing.
+	 */
+	if (deir == 0)
+		return;
+
+	/* FIXME: print which MAL correctly */
+	printk(KERN_WARNING "%s: Rx descriptor error (MALRXDEIR=%lx)\n",
+	       "MAL", deir);
+
+	read_lock(&mal_list_lock);
+	list_for_each(l, &mal->commac) {
+		struct mal_commac *mc = list_entry(l, struct mal_commac, list);
+
+		if (deir & mc->rx_chan_mask) {
+			mc->ops->rxde(mc->dev, deir & mc->rx_chan_mask);
+		}
+	}
+	read_unlock(&mal_list_lock);
+}
+
+static int __init
+mal_probe(struct ocp_device *ocpdev)
+{
+	struct ibm_ocp_mal *mal = NULL;
+	struct ocp_func_mal_data *maldata;
+	int err = 0;
+
+	maldata = (struct ocp_func_mal_data *)ocpdev->def->additions;
+	if (maldata == NULL) {
+		printk(KERN_ERR "mal%d: Missing additional datas !\n", ocpdev->def->index);
+		return -ENODEV;
+	}
+
+	mal = kmalloc(sizeof(struct ibm_ocp_mal), GFP_KERNEL);
+	if (mal == NULL) {
+		printk(KERN_ERR "mal%d: Out of memory allocating MAL structure !\n",
+			ocpdev->def->index);
+		return -ENOMEM;
+	}
+	memset(mal, 0, sizeof(*mal));
+	
+	switch (ocpdev->def->index) {
+	case 0:
+		mal->dcrbase = DCRN_MAL_BASE;
+		break;
+#ifdef DCRN_MAL1_BASE
+	case 1:
+		mal->dcrbase = DCRN_MAL1_BASE;
+		break;
+#endif
+	default:
+		BUG();
+	}
+	mal->serr_irq = BL_MAL_SERR;
+	mal->txde_irq = BL_MAL_TXDE;
+	mal->txeob_irq = BL_MAL_TXEOB;
+	mal->rxde_irq = BL_MAL_RXDE;
+	mal->rxeob_irq = BL_MAL_RXEOB;
+	
+	mal->num_tx_channels = maldata->num_tx_chans;
+	mal->num_rx_channels = maldata->num_rx_chans;
+
+	/**************************/
+
+	INIT_LIST_HEAD(&mal->commac);
+
+
+	set_mal_dcrn(mal, DCRN_MALRXCARR, 0xFFFFFFFF);
+	set_mal_dcrn(mal, DCRN_MALTXCARR, 0xFFFFFFFF);
+
+	set_mal_dcrn(mal, DCRN_MALCR, MALCR_MMSR);	/* 384 */
+	/* FIXME: Add delay */
+
+	/* Set the MAL configuration register */
+	set_mal_dcrn(mal, DCRN_MALCR,
+		     MALCR_PLBB | MALCR_OPBBL | MALCR_LEA |
+		     MALCR_PLBLT_DEFAULT);
+
+	/* It would be nice to allocate buffers separately for each
+	 * channel, but we can't because the channels share the upper
+	 * 13 bits of address lines.  Each channels buffer must also
+	 * be 4k aligned, so we allocate 4k for each channel.  This is
+	 * inefficient FIXME: do better, if possible */
+
+	mal->tx_virt_addr = consistent_alloc(GFP_KERNEL,
+					     MAL_DT_ALIGN * mal->num_tx_channels,
+					     &mal->tx_phys_addr);
+	if (mal->tx_virt_addr == NULL) {
+		printk(KERN_ERR "mal%d: Out of memory allocating MAL descriptors !\n",
+			ocpdev->def->index);
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	/* God, oh, god, I hate DCRs */
+	set_mal_dcrn(mal, DCRN_MALTXCTP0R, mal->tx_phys_addr);
+#ifdef DCRN_MALTXCTP1R
+	if (mal->num_tx_channels > 1)
+		set_mal_dcrn(mal, DCRN_MALTXCTP1R,
+			     mal->tx_phys_addr + MAL_DT_ALIGN);
+#endif /* DCRN_MALTXCTP1R */
+#ifdef DCRN_MALTXCTP2R
+	if (mal->num_tx_channels > 2)
+		set_mal_dcrn(mal, DCRN_MALTXCTP2R,
+			     mal->tx_phys_addr + 2*MAL_DT_ALIGN);
+#endif /* DCRN_MALTXCTP2R */
+#ifdef DCRN_MALTXCTP3R
+	if (mal->num_tx_channels > 3)
+		set_mal_dcrn(mal, DCRN_MALTXCTP3R,
+			     mal->tx_phys_addr + 3*MAL_DT_ALIGN);
+#endif /* DCRN_MALTXCTP3R */
+#ifdef DCRN_MALTXCTP4R
+	if (mal->num_tx_channels > 4)
+		set_mal_dcrn(mal, DCRN_MALTXCTP4R,
+			     mal->tx_phys_addr + 4*MAL_DT_ALIGN);
+#endif /* DCRN_MALTXCTP4R */
+#ifdef DCRN_MALTXCTP5R
+	if (mal->num_tx_channels > 5)
+		set_mal_dcrn(mal, DCRN_MALTXCTP5R,
+			     mal->tx_phys_addr + 5*MAL_DT_ALIGN);
+#endif /* DCRN_MALTXCTP5R */
+#ifdef DCRN_MALTXCTP6R
+	if (mal->num_tx_channels > 6)
+		set_mal_dcrn(mal, DCRN_MALTXCTP6R,
+			     mal->tx_phys_addr + 6*MAL_DT_ALIGN);
+#endif /* DCRN_MALTXCTP6R */
+#ifdef DCRN_MALTXCTP7R
+	if (mal->num_tx_channels > 7)
+		set_mal_dcrn(mal, DCRN_MALTXCTP7R,
+			     mal->tx_phys_addr + 7*MAL_DT_ALIGN);
+#endif /* DCRN_MALTXCTP7R */
+
+	mal->rx_virt_addr = consistent_alloc(GFP_KERNEL,
+					     MAL_DT_ALIGN * mal->num_rx_channels,
+					     &mal->rx_phys_addr);
+
+	set_mal_dcrn(mal, DCRN_MALRXCTP0R, mal->rx_phys_addr);
+#ifdef DCRN_MALRXCTP1R
+	if (mal->num_rx_channels > 1)
+		set_mal_dcrn(mal, DCRN_MALRXCTP1R,
+			     mal->rx_phys_addr + MAL_DT_ALIGN);
+#endif /* DCRN_MALRXCTP1R */
+#ifdef DCRN_MALRXCTP2R
+	if (mal->num_rx_channels > 2)
+		set_mal_dcrn(mal, DCRN_MALRXCTP2R,
+			     mal->rx_phys_addr + 2*MAL_DT_ALIGN);
+#endif /* DCRN_MALRXCTP2R */
+#ifdef DCRN_MALRXCTP3R
+	if (mal->num_rx_channels > 3)
+		set_mal_dcrn(mal, DCRN_MALRXCTP3R,
+			     mal->rx_phys_addr + 3*MAL_DT_ALIGN);
+#endif /* DCRN_MALRXCTP3R */
+	
+	err = request_irq(mal->serr_irq, mal_serr, 0 ,"MAL SERR", mal);
+	if (err)
+		goto fail;
+	err = request_irq(mal->txde_irq, mal_txde,0, "MAL TX DE ", mal);
+	if (err)
+		goto fail;
+	err = request_irq(mal->txeob_irq, mal_txeob, 0, "MAL TX EOB", mal);
+	if (err)
+		goto fail;
+	err = request_irq(mal->rxde_irq, mal_rxde, 0, "MAL RX DE", mal);
+	if (err)
+		goto fail;
+	err = request_irq(mal->rxeob_irq, mal_rxeob, 0, "MAL RX EOB", mal);
+	if (err)
+		goto fail;
+
+	set_mal_dcrn(mal, DCRN_MALIER,
+		     MALIER_DE | MALIER_NE | MALIER_TE |
+		     MALIER_OPBE | MALIER_PLBE);
+
+	/* Advertise me to the rest of the world */
+	ocp_set_drvdata(ocpdev, mal);
+
+	printk(KERN_INFO "mal%d: Initialized, %d tx channels, %d rx channels\n",
+			ocpdev->def->index, mal->num_tx_channels, mal->num_rx_channels);
+
+	return 0;
+
+ fail:
+ 	/* FIXME: dispose requested IRQs ! */
+	if (err && mal)
+		kfree(mal);
+	return err;
+}
+
+static void __exit
+mal_remove(struct ocp_device *ocpdev)
+{
+	struct ibm_ocp_mal *mal = ocp_get_drvdata(ocpdev);
+
+	ocp_set_drvdata(ocpdev, NULL);
+
+	/* FIXME: shut down the MAL, deal with dependency with emac */
+	free_irq(mal->serr_irq, mal);
+	free_irq(mal->txde_irq, mal);
+	free_irq(mal->txeob_irq, mal);
+	free_irq(mal->rxde_irq, mal);
+	free_irq(mal->rxeob_irq, mal);
+	
+	if (mal->tx_virt_addr)
+		consistent_free(mal->tx_virt_addr);
+	if (mal->rx_virt_addr)
+		consistent_free(mal->rx_virt_addr);
+
+	kfree(mal);
+}
+
+/* Structure for a device driver */
+static struct ocp_device_id mal_ids[] =
+{
+	{ .vendor = OCP_ANY_ID, .function = OCP_FUNC_MAL },
+	{ .vendor = OCP_VENDOR_INVALID }
+};
+
+static struct ocp_driver mal_driver =
+{
+	.name 		= "mal",
+	.id_table	= mal_ids,
+	
+	.probe		= mal_probe,
+	.remove		= mal_remove,
+};
+
+static int __init
+init_mals(void)
+{
+	int rc;
+	
+	rc = ocp_register_driver(&mal_driver);
+	if (rc == 0) {
+		ocp_unregister_driver(&mal_driver);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static void __exit
+exit_mals(void)
+{
+	ocp_unregister_driver(&mal_driver);
+}
+
+module_init(init_mals);
+module_exit(exit_mals);
diff -urN linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_ocp_mal.h linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_ocp_mal.h
--- linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_ocp_mal.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_ocp_mal.h	2003-07-12 02:52:25.000000000 -0700
@@ -0,0 +1,147 @@
+/*
+ * 06/02/02 -Armin
+ *    added new mal functions and defines from ibm_ocp_enet.h
+ */
+
+#ifndef _IBM_OCP_MAL_H
+#define _IBM_OCP_MAL_H
+
+#include <linux/list.h>
+
+#define MAL_DT_ALIGN	(4096)	/* Alignment for each channel's descriptor table */
+
+#define MAL_CHAN_MASK(chan)	(0x80000000 >> (chan))
+
+/* MAL Buffer Descriptor structure */
+struct mal_descriptor {
+	volatile unsigned short ctrl;	/* MAL / Commac status control bits */
+	volatile short data_len;	/* Max length is 4K-1 (12 bits)     */
+	unsigned char *data_ptr;	/* pointer to actual data buffer    */
+} __attribute__((packed));
+
+/* the following defines are for the MadMAL status and control registers. */
+/* MADMAL transmit and receive status/control bits  */
+#define MAL_RX_CTRL_EMPTY		0x8000
+#define MAL_RX_CTRL_WRAP		0x4000
+#define MAL_RX_CTRL_CM			0x2000
+#define MAL_RX_CTRL_LAST		0x1000
+#define MAL_RX_CTRL_FIRST		0x0800
+#define MAL_RX_CTRL_INTR		0x0400
+
+#define MAL_TX_CTRL_READY		0x8000
+#define MAL_TX_CTRL_WRAP		0x4000
+#define MAL_TX_CTRL_CM			0x2000
+#define MAL_TX_CTRL_LAST		0x1000
+#define MAL_TX_CTRL_INTR		0x0400
+
+struct mal_commac_ops {
+	void (*txeob)(void *dev, u32 chanmask);
+	void (*txde)(void *dev, u32 chanmask);
+	void (*rxeob)(void *dev, u32 chanmask);
+	void (*rxde)(void *dev, u32 chanmask);
+};
+
+struct mal_commac {
+	struct mal_commac_ops *ops;
+	void *dev;
+	u32 tx_chan_mask, rx_chan_mask;
+	struct list_head list;
+};
+
+/* FIXME: Work this out better */
+#define MAL_MAX_TX_CHANNELS	(EMAC_NUMS*2)
+#define MAL_MAX_RX_CHANNELS	(EMAC_NUMS)
+
+struct ibm_ocp_mal {
+	int dcrbase;
+	int serr_irq, txeob_irq, txde_irq, rxeob_irq, rxde_irq;
+
+	struct list_head commac;
+	u32 tx_chan_mask, rx_chan_mask;
+
+	int num_tx_channels;
+	dma_addr_t tx_phys_addr;
+	struct mal_descriptor *tx_virt_addr;
+
+	int num_rx_channels;
+	dma_addr_t rx_phys_addr;
+	struct mal_descriptor *rx_virt_addr;
+};
+
+#ifdef DCRN_MAL1_BASE
+#define NUM_MALS	2
+#else
+#define	NUM_MALS	1
+#endif
+
+extern struct ibm_ocp_mal mal_table[NUM_MALS];
+
+#define GET_MAL_STANZA(base,dcrn) \
+	case base: \
+		x = mfdcr(dcrn(base)); \
+		break;
+
+#define SET_MAL_STANZA(base,dcrn, val) \
+	case base: \
+		mtdcr(dcrn(base), (val)); \
+		break;
+
+#define GET_MAL0_STANZA(dcrn) GET_MAL_STANZA(DCRN_MAL_BASE,dcrn)
+#define SET_MAL0_STANZA(dcrn,val) SET_MAL_STANZA(DCRN_MAL_BASE,dcrn,val)
+
+#ifdef DCRN_MAL1_BASE
+#define GET_MAL1_STANZA(dcrn) GET_MAL_STANZA(DCRN_MAL1_BASE,dcrn)
+#define SET_MAL1_STANZA(dcrn,val) SET_MAL_STANZA(DCRN_MAL1_BASE,dcrn,val)
+#else /* ! DCRN_MAL1_BASE */
+#define GET_MAL1_STANZA(dcrn) 
+#define SET_MAL1_STANZA(dcrn,val)
+#endif
+
+
+#define get_mal_dcrn(mal, dcrn) ({ \
+	u32 x; \
+	switch ((mal)->dcrbase) { \
+		GET_MAL0_STANZA(dcrn) \
+		GET_MAL1_STANZA(dcrn) \
+	default: \
+		BUG(); \
+	} \
+x; })
+
+#define set_mal_dcrn(mal, dcrn, val) do { \
+	switch ((mal)->dcrbase) { \
+		SET_MAL0_STANZA(dcrn,val) \
+		SET_MAL1_STANZA(dcrn,val) \
+	default: \
+		BUG(); \
+	} } while (0)
+
+
+static inline void mal_enable_tx_channels(struct ibm_ocp_mal *mal, u32 chanmask)
+{
+	set_mal_dcrn(mal, DCRN_MALTXCASR,
+		     get_mal_dcrn(mal, DCRN_MALTXCASR) | chanmask);
+}
+
+static inline void mal_disable_tx_channels(struct ibm_ocp_mal *mal, u32 chanmask)
+{
+	set_mal_dcrn(mal, DCRN_MALTXCARR, chanmask);
+}
+
+static inline void mal_enable_rx_channels(struct ibm_ocp_mal *mal, u32 chanmask)
+{
+	set_mal_dcrn(mal, DCRN_MALRXCASR,
+		     get_mal_dcrn(mal, DCRN_MALRXCASR) | chanmask);
+}
+
+static inline void mal_disable_rx_channels(struct ibm_ocp_mal *mal, u32 chanmask)
+{
+	set_mal_dcrn(mal, DCRN_MALRXCARR, chanmask);
+}
+
+extern int mal_register_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac);
+extern int mal_unregister_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac);
+
+extern int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel, unsigned long size);
+
+#endif /* _IBM_OCP_MAL_H */
diff -urN linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_ocp_phy.c linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_ocp_phy.c
--- linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_ocp_phy.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_ocp_phy.c	2003-07-12 02:52:25.000000000 -0700
@@ -0,0 +1,243 @@
+/*
+ * ibm_ocp_phy.c
+ *
+ * PHY drivers for the ibm ocp ethernet driver. Borrowed
+ * from sungem_phy.c, though I only kept the generic MII
+ * driver for now.
+ * 
+ * This file should be shared with other drivers or eventually
+ * merged as the "low level" part of miilib
+ * 
+ * (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org)
+ *
+ */
+
+#include <linux/config.h>
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/delay.h>
+
+#include "ibm_ocp_phy.h"
+
+
+static inline int __phy_read(struct mii_phy* phy, int id, int reg)
+{
+	return phy->mdio_read(phy->dev, id, reg);
+}
+
+static inline void __phy_write(struct mii_phy* phy, int id, int reg, int val)
+{
+	phy->mdio_write(phy->dev, id, reg, val);
+}
+
+static inline int phy_read(struct mii_phy* phy, int reg)
+{
+	return phy->mdio_read(phy->dev, phy->mii_id, reg);
+}
+
+static inline void phy_write(struct mii_phy* phy, int reg, int val)
+{
+	phy->mdio_write(phy->dev, phy->mii_id, reg, val);
+}
+
+static int reset_one_mii_phy(struct mii_phy* phy, int phy_id)
+{
+	u16 val;
+	int limit = 10000;
+	
+	val = __phy_read(phy, phy_id, MII_BMCR);
+	val &= ~BMCR_ISOLATE;
+	val |= BMCR_RESET;
+	__phy_write(phy, phy_id, MII_BMCR, val);
+
+	udelay(100);
+
+	while (limit--) {
+		val = __phy_read(phy, phy_id, MII_BMCR);
+		if ((val & BMCR_RESET) == 0)
+			break;
+		udelay(10);
+	}
+	if ((val & BMCR_ISOLATE) && limit > 0)
+		__phy_write(phy, phy_id, MII_BMCR, val & ~BMCR_ISOLATE);
+	
+	return (limit <= 0);
+}
+
+static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
+{
+	u16 ctl, adv;
+	
+	phy->autoneg = 1;
+	phy->speed = SPEED_10;
+	phy->duplex = DUPLEX_HALF;
+	phy->pause = 0;
+	phy->advertising = advertise;
+
+	/* Setup standard advertise */
+	adv = phy_read(phy, MII_ADVERTISE);
+	adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
+	if (advertise & ADVERTISED_10baseT_Half)
+		adv |= ADVERTISE_10HALF;
+	if (advertise & ADVERTISED_10baseT_Full)
+		adv |= ADVERTISE_10FULL;
+	if (advertise & ADVERTISED_100baseT_Half)
+		adv |= ADVERTISE_100HALF;
+	if (advertise & ADVERTISED_100baseT_Full)
+		adv |= ADVERTISE_100FULL;
+	phy_write(phy, MII_ADVERTISE, adv);
+
+	/* Start/Restart aneg */
+	ctl = phy_read(phy, MII_BMCR);
+	ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
+	phy_write(phy, MII_BMCR, ctl);
+
+	return 0;
+}
+
+static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
+{
+	u16 ctl;
+	
+	phy->autoneg = 0;
+	phy->speed = speed;
+	phy->duplex = fd;
+	phy->pause = 0;
+
+	ctl = phy_read(phy, MII_BMCR);
+	ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_ANENABLE);
+
+	/* First reset the PHY */
+	phy_write(phy, MII_BMCR, ctl | BMCR_RESET);
+
+	/* Select speed & duplex */
+	switch(speed) {
+	case SPEED_10:
+		break;
+	case SPEED_100:
+		ctl |= BMCR_SPEED100;
+		break;
+	case SPEED_1000:
+	default:
+		return -EINVAL;
+	}
+	if (fd == DUPLEX_FULL)
+		ctl |= BMCR_FULLDPLX;
+	phy_write(phy, MII_BMCR, ctl);
+
+	return 0;
+}
+
+static int genmii_poll_link(struct mii_phy *phy)
+{
+	u16 status;
+	
+	(void)phy_read(phy, MII_BMSR);
+	status = phy_read(phy, MII_BMSR);
+	if ((status & BMSR_LSTATUS) == 0)
+		return 0;
+	if (phy->autoneg && !(status & BMSR_ANEGCOMPLETE))
+		return 0;
+	return 1;
+}
+
+static int genmii_read_link(struct mii_phy *phy)
+{
+	u16 lpa;
+
+	if (phy->autoneg) {
+		lpa = phy_read(phy, MII_LPA);
+
+		if (lpa & (LPA_10FULL | LPA_100FULL))
+			phy->duplex = DUPLEX_FULL;
+		else
+			phy->duplex = DUPLEX_HALF;
+		if (lpa & (LPA_100FULL | LPA_100HALF))
+			phy->speed = SPEED_100;
+		else
+			phy->speed = SPEED_10;
+		phy->pause = 0;
+	}
+	/* On non-aneg, we assume what we put in BMCR is the speed,
+	 * though magic-aneg shouldn't prevent this case from occurring
+	 */
+
+	 return 0;
+}
+
+
+#define MII_BASIC_FEATURES	(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
+				 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
+				 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII)
+#define MII_GBIT_FEATURES	(MII_BASIC_FEATURES | \
+				 SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)
+
+
+/* Generic implementation for most 10/100 PHYs */
+static struct mii_phy_ops generic_phy_ops = {
+	setup_aneg:	genmii_setup_aneg,
+	setup_forced:	genmii_setup_forced,
+	poll_link:	genmii_poll_link,
+	read_link:	genmii_read_link
+};
+
+static struct mii_phy_def genmii_phy_def = {
+	phy_id:		0x00000000,
+	phy_id_mask:	0x00000000,
+	name:		"Generic MII",
+	features:	MII_BASIC_FEATURES,
+	magic_aneg:	0,
+	ops:		&generic_phy_ops
+};
+
+static struct mii_phy_def* mii_phy_table[] = {
+	&genmii_phy_def,
+	NULL
+};
+
+int mii_phy_probe(struct mii_phy *phy, int mii_id)
+{
+	int rc;
+	u32 id;
+	struct mii_phy_def* def;
+	int i;
+	
+	phy->autoneg = 0;
+	phy->advertising = 0;
+	phy->mii_id = mii_id;
+	phy->speed = 0;
+	phy->duplex = 0;
+	phy->pause = 0;
+	
+	/* Take PHY out of isloate mode and reset it. */
+	rc = reset_one_mii_phy(phy, mii_id);
+	if (rc)
+		return -ENODEV;
+
+	/* Read ID and find matching entry */	
+	id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2))
+			 	& 0xfffffff0;
+	for (i=0; (def = mii_phy_table[i]) != NULL; i++)
+		if ((id & def->phy_id_mask) == def->phy_id)
+			break;
+	/* Should never be NULL (we have a generic entry), but... */
+	if (def == NULL)
+		return -ENODEV;
+
+	phy->def = def;
+
+	/* Setup default advertising */
+	phy->advertising = def->features;
+
+	return 0;
+}
+
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_ocp_phy.h linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_ocp_phy.h
--- linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_ocp_phy.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_ocp_phy.h	2003-07-12 02:52:25.000000000 -0700
@@ -0,0 +1,90 @@
+
+/*
+ * ibm_ocp_phy.h
+ *
+ *
+ *      Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ *      February 2003
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This file basically duplicates sungem_phy.{c,h} with different PHYs
+ * supported. I'm looking into merging that in a single mii layer more
+ * flexible than mii.c 
+ */
+
+#ifndef _IBM_OCP_PHY_H_
+#define _IBM_OCP_PHY_H_
+
+struct mii_phy;
+
+/* Operations supported by any kind of PHY */
+struct mii_phy_ops
+{
+	int		(*init)(struct mii_phy *phy);
+	int		(*suspend)(struct mii_phy *phy, int wol_options);
+	int		(*setup_aneg)(struct mii_phy *phy, u32 advertise);
+	int		(*setup_forced)(struct mii_phy *phy, int speed, int fd);
+	int		(*poll_link)(struct mii_phy *phy);
+	int		(*read_link)(struct mii_phy *phy);
+};
+
+/* Structure used to statically define an mii/gii based PHY */
+struct mii_phy_def
+{
+	u32				phy_id;		/* Concatenated ID1 << 16 | ID2 */
+	u32				phy_id_mask;	/* Significant bits */
+	u32				features;	/* Ethtool SUPPORTED_* defines */
+	int				magic_aneg;	/* Autoneg does all speed test for us */
+	const char*			name;
+	const struct mii_phy_ops*	ops;
+};
+
+/* An instance of a PHY, partially borrowed from mii_if_info */
+struct mii_phy
+{
+	struct mii_phy_def*	def;
+	int			advertising;
+	int			mii_id;
+
+	/* 1: autoneg enabled, 0: disabled */
+	int			autoneg;
+
+	/* forced speed & duplex (no autoneg)
+	 * partner speed & duplex & pause (autoneg)
+	 */
+	int			speed;
+	int			duplex;
+	int			pause;
+
+	/* Provided by host chip */
+	struct net_device*	dev;
+	int (*mdio_read) (struct net_device *dev, int mii_id, int reg);
+	void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val);
+};
+
+/* Pass in a struct mii_phy with dev, mdio_read and mdio_write
+ * filled, the remaining fields will be filled on return
+ */
+extern int mii_phy_probe(struct mii_phy *phy, int mii_id);
+
+#endif				/* _IBM_OCP_PHY_H_ */
diff -urN linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_ocp_zmii.h linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_ocp_zmii.h
--- linux-2.4.21-bk7/drivers/net/ibm_emac/ibm_ocp_zmii.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.21-bk8/drivers/net/ibm_emac/ibm_ocp_zmii.h	2003-07-12 02:52:25.000000000 -0700
@@ -0,0 +1,109 @@
+/*
+ * ocp_zmii.h
+ *
+ * Defines for the IBM ZMII bridge
+ *
+ *      Armin Kuster akuster@mvista.com
+ *      Dec, 2001
+ *
+ * Copyright 2001 MontaVista Softare Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  V 1.2 (04/19/02 ) - Armin
+ *    added support for emac 2 & 3
+ */
+
+#ifndef _OCP_ZMII_H_
+#define _OCP_ZMII_H_
+
+#include <linux/config.h>
+
+/* ZMII bridge registers */
+struct zmii_regs {
+	u32 fer;		/* Function enable reg */
+	u32 ssr;		/* Spedd select reg */
+	u32 smiirs;		/* SMII status reg */
+};
+
+/* ZMII device */
+struct ibm_ocp_zmii {
+	struct zmii_regs *base;
+	int		  mode;  
+	int 		  users;/* number of EMACs using this ZMII bridge */
+};
+
+/* Fuctional Enable Reg */
+
+#define ZMII_MDI0	0x80000000
+#define ZMII_SMII0	0x40000000
+#define ZMII_RMII0	0x20000000
+#define ZMII_MII0	0x10000000
+#define ZMII_MDI1	0x08000000
+#define ZMII_SMII1	0x04000000
+#define ZMII_RMII1	0x02000000
+#define ZMII_MII1	0x01000000
+#define ZMII_MDI2	0x00800000
+#define ZMII_SMII2	0x00400000
+#define ZMII_RMII2	0x00200000
+#define ZMII_MII2	0x00100000
+#define ZMII_MDI3	0x00080000
+#define ZMII_SMII3	0x00040000
+#define ZMII_RMII3	0x00020000
+#define ZMII_MII3	0x00010000
+
+/* Speed Selection reg */
+
+#define ZMII_SCI0	0x40000000
+#define ZMII_FSS0	0x20000000
+#define ZMII_SP0	0x10000000
+#define ZMII_SCI1	0x04000000
+#define ZMII_FSS1	0x02000000
+#define ZMII_SP1	0x01000000
+#define ZMII_SCI2	0x00400000
+#define ZMII_FSS2	0x00200000
+#define ZMII_SP2	0x00100000
+#define ZMII_SCI3	0x00040000
+#define ZMII_FSS3	0x00020000
+#define ZMII_SP3	0x00010000
+
+#define ZMII_MII0_100MB	ZMII_SP0
+#define ZMII_MII0_10MB	~ZMII_SP0
+#define ZMII_MII1_100MB	ZMII_SP1
+#define ZMII_MII1_10MB	~ZMII_SP1
+#define ZMII_MII2_100MB	ZMII_SP2
+#define ZMII_MII2_10MB	~ZMII_SP2
+#define ZMII_MII3_100MB	ZMII_SP3
+#define ZMII_MII3_10MB	~ZMII_SP3
+
+/* SMII Status reg */
+
+#define ZMII_STS0 0xFF000000	/* EMAC0 smii status mask */
+#define ZMII_STS1 0x00FF0000	/* EMAC1 smii status mask */
+
+
+#define SMII	0
+#define RMII	1
+#define MII	2
+#define MDI	3
+#define ZMII_AUTO 4
+
+#endif				/* _OCP_ZMII_H_ */
diff -urN linux-2.4.21-bk7/drivers/net/sundance.c linux-2.4.21-bk8/drivers/net/sundance.c
--- linux-2.4.21-bk7/drivers/net/sundance.c	2003-07-12 02:52:20.000000000 -0700
+++ linux-2.4.21-bk8/drivers/net/sundance.c	2003-07-12 02:52:25.000000000 -0700
@@ -87,11 +87,15 @@
 	Version LK1.09 (D-Link):
 	- Fix the flowctrl bug.	
 	- Set Pause bit in MII ANAR if flow control enabled.	
+
+	Version LK1.09a (ICPlus):
+	- Add the delay time in reading the contents of EEPROM
+
 */
 
 #define DRV_NAME	"sundance"
 #define DRV_VERSION	"1.01+LK1.09a"
-#define DRV_RELDATE	"16-May-2003"
+#define DRV_RELDATE	"10-Jul-2003"
 
 
 /* The user-configurable values.
@@ -743,12 +747,14 @@
 	return 0;
 }
 
+#define eeprom_delay(ee_addr)	readl(ee_addr)
 /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. */
 static int __devinit eeprom_read(long ioaddr, int location)
 {
-	int boguscnt = 1000;		/* Typical 190 ticks. */
+	int boguscnt = 10000;		/* Typical 1900 ticks. */
 	writew(0x0200 | (location & 0xff), ioaddr + EECtrl);
 	do {
+		eeprom_delay(ioaddr + EECtrl);
 		if (! (readw(ioaddr + EECtrl) & 0x8000)) {
 			return readw(ioaddr + EEData);
 		}
diff -urN linux-2.4.21-bk7/drivers/video/radeon.h linux-2.4.21-bk8/drivers/video/radeon.h
--- linux-2.4.21-bk7/drivers/video/radeon.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.21-bk8/drivers/video/radeon.h	2003-07-12 02:52:26.000000000 -0700
@@ -2,20 +2,6 @@
 #define _RADEON_H
 
 
-/* radeon PCI ids */
-#define PCI_DEVICE_ID_RADEON_QD		0x5144
-#define PCI_DEVICE_ID_RADEON_QE		0x5145
-#define PCI_DEVICE_ID_RADEON_QF		0x5146
-#define PCI_DEVICE_ID_RADEON_QG		0x5147
-#define PCI_DEVICE_ID_RADEON_QY		0x5159
-#define PCI_DEVICE_ID_RADEON_QZ		0x515a
-#define PCI_DEVICE_ID_RADEON_LW		0x4c57
-#define PCI_DEVICE_ID_RADEON_LY		0x4c59
-#define PCI_DEVICE_ID_RADEON_LZ		0x4c5a
-#define PCI_DEVICE_ID_RADEON_PM		0x4c52
-#define PCI_DEVICE_ID_RADEON_QL		0x514c
-#define PCI_DEVICE_ID_RADEON_QW		0x5157
-
 #define RADEON_REGSIZE			0x4000
 
 
@@ -78,6 +64,7 @@
 #define AIC_TLB_ADDR                           0x01E4  
 #define AIC_TLB_DATA                           0x01E8  
 #define DAC_CNTL                               0x0058  
+#define DAC_CNTL2                              0x007c
 #define CRTC_GEN_CNTL                          0x0050  
 #define MEM_CNTL                               0x0140  
 #define EXT_MEM_CNTL                           0x0144  
@@ -150,6 +137,7 @@
 #define GPIO_VGA_DDC                           0x0060  
 #define GPIO_DVI_DDC                           0x0064  
 #define GPIO_MONID                             0x0068  
+#define GPIO_CRT2_DDC                          0x006c
 #define PALETTE_INDEX                          0x00B0  
 #define PALETTE_DATA                           0x00B4  
 #define PALETTE_30_DATA                        0x00B8  
@@ -186,14 +174,16 @@
 #define CRTC_MORE_CNTL                         0x027C  
 #define DAC_EXT_CNTL                           0x0280  
 #define FP_GEN_CNTL                            0x0284  
+#define FP2_GEN_CNTL                           0x0288
 #define FP_HORZ_STRETCH                        0x028C  
 #define FP_VERT_STRETCH                        0x0290  
 #define FP_H_SYNC_STRT_WID                     0x02C4  
 #define FP_V_SYNC_STRT_WID                     0x02C8  
 #define AUX_WINDOW_HORZ_CNTL                   0x02D8  
 #define AUX_WINDOW_VERT_CNTL                   0x02DC  
-#define DDA_CONFIG			       0x02e0
-#define DDA_ON_OFF			       0x02e4
+//#define DDA_CONFIG			       0x02e0
+//#define DDA_ON_OFF			       0x02e4
+#define DVI_I2C_CNTL_1			       0x02e4
 #define GRPH_BUFFER_CNTL                       0x02F0
 #define VGA_BUFFER_CNTL                        0x02F4
 #define OV0_Y_X_START                          0x0400
@@ -374,15 +364,19 @@
 #define CLR_CMP_MSK                            0x15CC  
 #define DSTCACHE_MODE                          0x1710  
 #define DSTCACHE_CTLSTAT                       0x1714  
+#define SRC_PITCH_OFFSET                       0x1428
+#define DST_PITCH_OFFSET                       0x142C
 #define DEFAULT_PITCH_OFFSET                   0x16E0  
 #define DEFAULT_SC_BOTTOM_RIGHT                0x16E8  
 #define DP_GUI_MASTER_CNTL                     0x146C  
 #define SC_TOP_LEFT                            0x16EC  
 #define SC_BOTTOM_RIGHT                        0x16F0  
 #define SRC_SC_BOTTOM_RIGHT                    0x16F4  
+#define RB2D_DSTCACHE_MODE		       0x3428
 #define RB2D_DSTCACHE_CTLSTAT		       0x342C
 #define LVDS_GEN_CNTL			       0x02d0
 #define LVDS_PLL_CNTL			       0x02d4
+#define TMDS_CNTL                              0x0294
 #define TMDS_CRC			       0x02a0
 #define TMDS_TRANSMITTER_CNTL		       0x02a4
 
@@ -396,7 +390,17 @@
 #define RADEON_BIOS_6_SCRATCH		       0x0028
 #define RADEON_BIOS_7_SCRATCH		       0x002c
 
+#define TV_DAC_CNTL                            0x088c
+#define GPIOPAD_MASK                           0x0198
+#define GPIOPAD_A                              0x019c
+#define GPIOPAD_EN                             0x01a0
+#define GPIOPAD_Y                              0x01a4
+#define ZV_LCDPAD_MASK                         0x01a8
+#define ZV_LCDPAD_A                            0x01ac
+#define ZV_LCDPAD_EN                           0x01b0
+#define ZV_LCDPAD_Y                            0x01b4
 
+/* PLL Registers */
 #define CLK_PIN_CNTL                               0x0001
 #define PPLL_CNTL                                  0x0002
 #define PPLL_REF_DIV                               0x0003
@@ -412,9 +416,17 @@
 #define SCLK_CNTL                                  0x000d
 #define MPLL_CNTL                                  0x000e
 #define MDLL_CKO                                   0x000f
+#define MDLL_RDCKA                                 0x0010
 #define MCLK_CNTL                                  0x0012
 #define AGP_PLL_CNTL                               0x000b
 #define PLL_TEST_CNTL                              0x0013
+#define SCLK_MORE_CNTL				   0x0035
+#define CLK_PWRMGT_CNTL                            0x0014
+#define PLL_PWRMGT_CNTL                            0x0015
+#define MCLK_MISC                                  0x001f
+#define P2PLL_CNTL                                 0x002a
+#define P2PLL_REF_DIV                              0x002b
+#define PIXCLKS_CNTL                               0x002d
 
 /* MCLK_CNTL bit constants */
 #define FORCEON_MCLKA				   (1 << 16)
@@ -424,6 +436,13 @@
 #define FORCEON_MC            		   	   (1 << 20)
 #define FORCEON_AIC           		   	   (1 << 21)
 
+/* SCLK_CNTL bit constants */
+#define DYN_STOP_LAT_MASK			   0x00007ff8
+#define CP_MAX_DYN_STOP_LAT			   0x0008
+#define SCLK_FORCEON_MASK			   0xffff8000
+
+/* SCLK_MORE_CNTL bit constants */
+#define SCLK_MORE_FORCEON			   0x0700
 
 /* BUS_CNTL bit constants */
 #define BUS_DBL_RESYNC                             0x00000001
@@ -477,6 +496,7 @@
 #define CRTC_DBL_SCAN_EN                           0x00000001
 #define CRTC_CUR_EN                                0x00010000
 #define CRTC_INTERLACE_EN			   (1 << 1)
+#define CRTC_BYPASS_LUT_EN     			   (1 << 14)
 #define CRTC_EXT_DISP_EN      			   (1 << 24)
 #define CRTC_EN					   (1 << 25)
 #define CRTC_DISP_REQ_EN_B                         (1 << 26)
@@ -550,10 +570,10 @@
 #define HSYNC_DELAY_MASK			   (0xf << 0x1c)
 
 /* TMDS_TRANSMITTER_CNTL bit constants */
-#define TMDS_PLL_EN				   (1 << 0)
-#define TMDS_PLLRST				   (1 << 1)
-#define TMDS_RAN_PAT_RST			   (1 << 7)
-#define ICHCSEL					   (1 << 28)
+#define TMDS_PLL_EN                                (1 << 0)
+#define TMDS_PLLRST                                (1 << 1)
+#define TMDS_RAN_PAT_RST                           (1 << 7)
+#define TMDS_ICHCSEL                               (1 << 28)
 
 /* FP_HORZ_STRETCH bit constants */
 #define HORZ_STRETCH_RATIO_MASK			   0xffff
@@ -589,6 +609,12 @@
 #define DAC_VGA_ADR_EN				   (1 << 13)
 #define DAC_RANGE_CNTL				   (3 << 0)
 #define DAC_BLANKING				   (1 << 2)
+#define DAC_CMP_EN                                 (1 << 3)
+
+/* DAC_CNTL2 bit constants */   
+#define DAC2_CMP_EN                                (1 << 7)
+#define DAC2_PALETTE_ACCESS_CNTL                   (1 << 5)
+
 
 /* GEN_RESET_CNTL bit constants */
 #define SOFT_RESET_GUI                             0x00000001
@@ -618,10 +644,15 @@
 #define SOFT_RESET_RB           		   (1 <<  6)
 #define SOFT_RESET_HDP          		   (1 <<  7)
 
+/* HOST_PATH_CNTL bit constants */
+#define HDP_SOFT_RESET				   (1 << 26)
+
 /* SURFACE_CNTL bit consants */
 #define SURF_TRANSLATION_DIS			   (1 << 8)
 #define NONSURF_AP0_SWP_16BPP			   (1 << 20)
 #define NONSURF_AP0_SWP_32BPP			   (1 << 21)
+#define NONSURF_AP1_SWP_16BPP			   (1 << 22)
+#define NONSURF_AP1_SWP_32BPP			   (1 << 23)
 
 /* DEFAULT_SC_BOTTOM_RIGHT bit constants */
 #define DEFAULT_SC_RIGHT_MAX			   (0x1fff << 0)
@@ -770,13 +801,70 @@
 /* MPLL_CNTL bit constants */
 #define MPLL_RESET                                 0x00000001
 
-/* MDLL_CKO bit constants */
-#define MDLL_CKO__MCKOA_RESET                      0x00000002
+/* MDLL_RDCKA bit constants */
+#define MRDCKA0_SLEEP                              0x00000001
+#define MRDCKA0_RESET                              0x00000002
+#define MRDCKA1_SLEEP                              0x00010000
+#define MRDCKA1_RESET                              0x00020000
 
 /* VCLK_ECP_CNTL constants */
 #define PIXCLK_ALWAYS_ONb                          0x00000040
 #define PIXCLK_DAC_ALWAYS_ONb                      0x00000080
 
+/* BUS_CNTL1 constants */
+#define BUS_CNTL1_MOBILE_PLATFORM_SEL_MASK         0x0c000000
+#define BUS_CNTL1_MOBILE_PLATFORM_SEL_SHIFT        26
+#define BUS_CNTL1_AGPCLK_VALID                     0x80000000
+
+/* PLL_PWRMGT_CNTL constants */
+#define PLL_PWRMGT_CNTL_SPLL_TURNOFF               0x00000002
+#define PLL_PWRMGT_CNTL_PPLL_TURNOFF               0x00000004
+#define PLL_PWRMGT_CNTL_P2PLL_TURNOFF              0x00000008
+#define PLL_PWRMGT_CNTL_TVPLL_TURNOFF              0x00000010
+#define PLL_PWRMGT_CNTL_MOBILE_SU                  0x00010000
+#define PLL_PWRMGT_CNTL_SU_SCLK_USE_BCLK           0x00020000
+#define PLL_PWRMGT_CNTL_SU_MCLK_USE_BCLK           0x00040000
+
+/* TV_DAC_CNTL constants */
+#define TV_DAC_CNTL_BGSLEEP                        0x00000040
+#define TV_DAC_CNTL_DETECT                         0x00000010
+#define TV_DAC_CNTL_BGADJ_MASK                     0x000f0000
+#define TV_DAC_CNTL_DACADJ_MASK                    0x00f00000
+#define TV_DAC_CNTL_BGADJ__SHIFT                   16
+#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
+
+/* DISP_MISC_CNTL constants */
+#define DISP_MISC_CNTL_SOFT_RESET_GRPH_PP          (1 << 0)
+#define DISP_MISC_CNTL_SOFT_RESET_SUBPIC_PP        (1 << 1)
+#define DISP_MISC_CNTL_SOFT_RESET_OV0_PP           (1 << 2)
+#define DISP_MISC_CNTL_SOFT_RESET_GRPH_SCLK        (1 << 4)
+#define DISP_MISC_CNTL_SOFT_RESET_SUBPIC_SCLK      (1 << 5)
+#define DISP_MISC_CNTL_SOFT_RESET_OV0_SCLK         (1 << 6)
+#define DISP_MISC_CNTL_SOFT_RESET_GRPH2_PP         (1 << 12)
+#define DISP_MISC_CNTL_SOFT_RESET_GRPH2_SCLK       (1 << 15)
+#define DISP_MISC_CNTL_SOFT_RESET_LVDS             (1 << 16)
+#define DISP_MISC_CNTL_SOFT_RESET_TMDS             (1 << 17)
+#define DISP_MISC_CNTL_SOFT_RESET_DIG_TMDS         (1 << 18)
+#define DISP_MISC_CNTL_SOFT_RESET_TV               (1 << 19)
+
+/* DISP_PWR_MAN constants */
+#define DISP_PWR_MAN_DISP_PWR_MAN_D3_CRTC_EN       (1 << 0)
+#define DISP_PWR_MAN_DISP2_PWR_MAN_D3_CRTC2_EN     (1 << 4)
+#define DISP_PWR_MAN_DISP_D3_RST                   (1 << 16)
+#define DISP_PWR_MAN_DISP_D3_REG_RST               (1 << 17)
+#define DISP_PWR_MAN_DISP_D3_GRPH_RST              (1 << 18)
+#define DISP_PWR_MAN_DISP_D3_SUBPIC_RST            (1 << 19)
+#define DISP_PWR_MAN_DISP_D3_OV0_RST               (1 << 20)
+#define DISP_PWR_MAN_DISP_D1D2_GRPH_RST            (1 << 21)
+#define DISP_PWR_MAN_DISP_D1D2_SUBPIC_RST          (1 << 22)
+#define DISP_PWR_MAN_DISP_D1D2_OV0_RST             (1 << 23)
+#define DISP_PWR_MAN_DIG_TMDS_ENABLE_RST           (1 << 24)
+#define DISP_PWR_MAN_TV_ENABLE_RST                 (1 << 25)
+#define DISP_PWR_MAN_AUTO_PWRUP_EN                 (1 << 26)
+
 /* masks */
 
 #define CONFIG_MEMSIZE_MASK		0x1f000000
@@ -796,5 +884,994 @@
 
 #define GUI_ACTIVE			0x80000000
 
+
+#define MC_IND_INDEX                           0x01F8
+#define MC_IND_DATA                            0x01FC
+#define MEM_REFRESH_CNTL                       0x0178
+
+// CLK_PIN_CNTL
+#define CLK_PIN_CNTL__OSC_EN_MASK                          0x00000001L
+#define CLK_PIN_CNTL__OSC_EN                               0x00000001L
+#define CLK_PIN_CNTL__XTL_LOW_GAIN_MASK                    0x00000004L
+#define CLK_PIN_CNTL__XTL_LOW_GAIN                         0x00000004L
+#define CLK_PIN_CNTL__DONT_USE_XTALIN_MASK                 0x00000010L
+#define CLK_PIN_CNTL__DONT_USE_XTALIN                      0x00000010L
+#define CLK_PIN_CNTL__SLOW_CLOCK_SOURCE_MASK               0x00000020L
+#define CLK_PIN_CNTL__SLOW_CLOCK_SOURCE                    0x00000020L
+#define CLK_PIN_CNTL__CG_CLK_TO_OUTPIN_MASK                0x00000800L
+#define CLK_PIN_CNTL__CG_CLK_TO_OUTPIN                     0x00000800L
+#define CLK_PIN_CNTL__CG_COUNT_UP_TO_OUTPIN_MASK           0x00001000L
+#define CLK_PIN_CNTL__CG_COUNT_UP_TO_OUTPIN                0x00001000L
+#define CLK_PIN_CNTL__ACCESS_REGS_IN_SUSPEND_MASK          0x00002000L
+#define CLK_PIN_CNTL__ACCESS_REGS_IN_SUSPEND               0x00002000L
+#define CLK_PIN_CNTL__CG_SPARE_MASK                        0x00004000L
+#define CLK_PIN_CNTL__CG_SPARE                             0x00004000L
+#define CLK_PIN_CNTL__SCLK_DYN_START_CNTL_MASK             0x00008000L
+#define CLK_PIN_CNTL__SCLK_DYN_START_CNTL                  0x00008000L
+#define CLK_PIN_CNTL__CP_CLK_RUNNING_MASK                  0x00010000L
+#define CLK_PIN_CNTL__CP_CLK_RUNNING                       0x00010000L
+#define CLK_PIN_CNTL__CG_SPARE_RD_MASK                     0x00060000L
+#define CLK_PIN_CNTL__XTALIN_ALWAYS_ONb_MASK               0x00080000L
+#define CLK_PIN_CNTL__XTALIN_ALWAYS_ONb                    0x00080000L
+#define CLK_PIN_CNTL__PWRSEQ_DELAY_MASK                    0xff000000L
+
+// CLK_PWRMGT_CNTL_M6
+#define	CLK_PWRMGT_CNTL_M6__MPLL_PWRMGT_OFF__SHIFT         0x00000000
+#define	CLK_PWRMGT_CNTL_M6__SPLL_PWRMGT_OFF__SHIFT         0x00000001
+#define	CLK_PWRMGT_CNTL_M6__PPLL_PWRMGT_OFF__SHIFT         0x00000002
+#define	CLK_PWRMGT_CNTL_M6__P2PLL_PWRMGT_OFF__SHIFT        0x00000003
+#define	CLK_PWRMGT_CNTL_M6__MCLK_TURNOFF__SHIFT            0x00000004
+#define	CLK_PWRMGT_CNTL_M6__SCLK_TURNOFF__SHIFT            0x00000005
+#define	CLK_PWRMGT_CNTL_M6__PCLK_TURNOFF__SHIFT            0x00000006
+#define	CLK_PWRMGT_CNTL_M6__P2CLK_TURNOFF__SHIFT           0x00000007
+#define	CLK_PWRMGT_CNTL_M6__MC_CH_MODE__SHIFT              0x00000008
+#define	CLK_PWRMGT_CNTL_M6__TEST_MODE__SHIFT               0x00000009
+#define	CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN__SHIFT          0x0000000a
+#define	CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE__SHIFT      0x0000000c
+#define	CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT__SHIFT         0x0000000d
+#define	CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT__SHIFT       0x0000000f
+#define	CLK_PWRMGT_CNTL_M6__MC_BUSY__SHIFT                 0x00000010
+#define	CLK_PWRMGT_CNTL_M6__MC_INT_CNTL__SHIFT             0x00000011
+#define	CLK_PWRMGT_CNTL_M6__MC_SWITCH__SHIFT               0x00000012
+#define	CLK_PWRMGT_CNTL_M6__DLL_READY__SHIFT               0x00000013
+#define	CLK_PWRMGT_CNTL_M6__DISP_PM__SHIFT                 0x00000014
+#define	CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE__SHIFT           0x00000015
+#define	CLK_PWRMGT_CNTL_M6__CG_NO1_DEBUG__SHIFT            0x00000018
+#define	CLK_PWRMGT_CNTL_M6__TVPLL_PWRMGT_OFF__SHIFT        0x0000001e
+#define	CLK_PWRMGT_CNTL_M6__TVCLK_TURNOFF__SHIFT           0x0000001f
+
+// P2PLL_CNTL
+#define P2PLL_CNTL__P2PLL_RESET_MASK                       0x00000001L
+#define P2PLL_CNTL__P2PLL_RESET                            0x00000001L
+#define P2PLL_CNTL__P2PLL_SLEEP_MASK                       0x00000002L
+#define P2PLL_CNTL__P2PLL_SLEEP                            0x00000002L
+#define P2PLL_CNTL__P2PLL_TST_EN_MASK                      0x00000004L
+#define P2PLL_CNTL__P2PLL_TST_EN                           0x00000004L
+#define P2PLL_CNTL__P2PLL_REFCLK_SEL_MASK                  0x00000010L
+#define P2PLL_CNTL__P2PLL_REFCLK_SEL                       0x00000010L
+#define P2PLL_CNTL__P2PLL_FBCLK_SEL_MASK                   0x00000020L
+#define P2PLL_CNTL__P2PLL_FBCLK_SEL                        0x00000020L
+#define P2PLL_CNTL__P2PLL_TCPOFF_MASK                      0x00000040L
+#define P2PLL_CNTL__P2PLL_TCPOFF                           0x00000040L
+#define P2PLL_CNTL__P2PLL_TVCOMAX_MASK                     0x00000080L
+#define P2PLL_CNTL__P2PLL_TVCOMAX                          0x00000080L
+#define P2PLL_CNTL__P2PLL_PCP_MASK                         0x00000700L
+#define P2PLL_CNTL__P2PLL_PVG_MASK                         0x00003800L
+#define P2PLL_CNTL__P2PLL_PDC_MASK                         0x0000c000L
+#define P2PLL_CNTL__P2PLL_ATOMIC_UPDATE_EN_MASK            0x00010000L
+#define P2PLL_CNTL__P2PLL_ATOMIC_UPDATE_EN                 0x00010000L
+#define P2PLL_CNTL__P2PLL_ATOMIC_UPDATE_SYNC_MASK          0x00040000L
+#define P2PLL_CNTL__P2PLL_ATOMIC_UPDATE_SYNC               0x00040000L
+#define P2PLL_CNTL__P2PLL_DISABLE_AUTO_RESET_MASK          0x00080000L
+#define P2PLL_CNTL__P2PLL_DISABLE_AUTO_RESET               0x00080000L
+
+// PIXCLKS_CNTL
+#define	PIXCLKS_CNTL__PIX2CLK_SRC_SEL__SHIFT               0x00000000
+#define	PIXCLKS_CNTL__PIX2CLK_INVERT__SHIFT                0x00000004
+#define	PIXCLKS_CNTL__PIX2CLK_SRC_INVERT__SHIFT            0x00000005
+#define	PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb__SHIFT            0x00000006
+#define	PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb__SHIFT        0x00000007
+#define	PIXCLKS_CNTL__PIXCLK_TV_SRC_SEL__SHIFT             0x00000008
+#define	PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb__SHIFT       0x0000000b
+#define	PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb__SHIFT          0x0000000c
+#define	PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb__SHIFT    0x0000000d
+#define	PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb__SHIFT        0x0000000e
+#define	PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb__SHIFT        0x0000000f
+
+
+// PIXCLKS_CNTL
+#define PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK                 0x00000003L
+#define PIXCLKS_CNTL__PIX2CLK_INVERT_MASK                  0x00000010L
+#define PIXCLKS_CNTL__PIX2CLK_INVERT                       0x00000010L
+#define PIXCLKS_CNTL__PIX2CLK_SRC_INVERT_MASK              0x00000020L
+#define PIXCLKS_CNTL__PIX2CLK_SRC_INVERT                   0x00000020L
+#define PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb_MASK              0x00000040L
+#define PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb                   0x00000040L
+#define PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb_MASK          0x00000080L
+#define PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb               0x00000080L
+#define PIXCLKS_CNTL__PIXCLK_TV_SRC_SEL_MASK               0x00000100L
+#define PIXCLKS_CNTL__PIXCLK_TV_SRC_SEL                    0x00000100L
+#define PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb_MASK         0x00000800L
+#define PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb              0x00000800L
+#define PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb_MASK            0x00001000L
+#define PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb                 0x00001000L
+#define PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb_MASK      0x00002000L
+#define PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb           0x00002000L
+#define PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb_MASK          0x00004000L
+#define PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb               0x00004000L
+#define PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb_MASK          0x00008000L
+#define PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb               0x00008000L
+
+
+// P2PLL_DIV_0
+#define P2PLL_DIV_0__P2PLL_FB_DIV_MASK                     0x000007ffL
+#define P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_W_MASK            0x00008000L
+#define P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_W                 0x00008000L
+#define P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_R_MASK            0x00008000L
+#define P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_R                 0x00008000L
+#define P2PLL_DIV_0__P2PLL_POST_DIV_MASK                   0x00070000L
+
+// SCLK_CNTL_M6
+#define SCLK_CNTL_M6__SCLK_SRC_SEL_MASK                    0x00000007L
+#define SCLK_CNTL_M6__CP_MAX_DYN_STOP_LAT_MASK             0x00000008L
+#define SCLK_CNTL_M6__CP_MAX_DYN_STOP_LAT                  0x00000008L
+#define SCLK_CNTL_M6__HDP_MAX_DYN_STOP_LAT_MASK            0x00000010L
+#define SCLK_CNTL_M6__HDP_MAX_DYN_STOP_LAT                 0x00000010L
+#define SCLK_CNTL_M6__TV_MAX_DYN_STOP_LAT_MASK             0x00000020L
+#define SCLK_CNTL_M6__TV_MAX_DYN_STOP_LAT                  0x00000020L
+#define SCLK_CNTL_M6__E2_MAX_DYN_STOP_LAT_MASK             0x00000040L
+#define SCLK_CNTL_M6__E2_MAX_DYN_STOP_LAT                  0x00000040L
+#define SCLK_CNTL_M6__SE_MAX_DYN_STOP_LAT_MASK             0x00000080L
+#define SCLK_CNTL_M6__SE_MAX_DYN_STOP_LAT                  0x00000080L
+#define SCLK_CNTL_M6__IDCT_MAX_DYN_STOP_LAT_MASK           0x00000100L
+#define SCLK_CNTL_M6__IDCT_MAX_DYN_STOP_LAT                0x00000100L
+#define SCLK_CNTL_M6__VIP_MAX_DYN_STOP_LAT_MASK            0x00000200L
+#define SCLK_CNTL_M6__VIP_MAX_DYN_STOP_LAT                 0x00000200L
+#define SCLK_CNTL_M6__RE_MAX_DYN_STOP_LAT_MASK             0x00000400L
+#define SCLK_CNTL_M6__RE_MAX_DYN_STOP_LAT                  0x00000400L
+#define SCLK_CNTL_M6__PB_MAX_DYN_STOP_LAT_MASK             0x00000800L
+#define SCLK_CNTL_M6__PB_MAX_DYN_STOP_LAT                  0x00000800L
+#define SCLK_CNTL_M6__TAM_MAX_DYN_STOP_LAT_MASK            0x00001000L
+#define SCLK_CNTL_M6__TAM_MAX_DYN_STOP_LAT                 0x00001000L
+#define SCLK_CNTL_M6__TDM_MAX_DYN_STOP_LAT_MASK            0x00002000L
+#define SCLK_CNTL_M6__TDM_MAX_DYN_STOP_LAT                 0x00002000L
+#define SCLK_CNTL_M6__RB_MAX_DYN_STOP_LAT_MASK             0x00004000L
+#define SCLK_CNTL_M6__RB_MAX_DYN_STOP_LAT                  0x00004000L
+#define SCLK_CNTL_M6__FORCE_DISP2_MASK                     0x00008000L
+#define SCLK_CNTL_M6__FORCE_DISP2                          0x00008000L
+#define SCLK_CNTL_M6__FORCE_CP_MASK                        0x00010000L
+#define SCLK_CNTL_M6__FORCE_CP                             0x00010000L
+#define SCLK_CNTL_M6__FORCE_HDP_MASK                       0x00020000L
+#define SCLK_CNTL_M6__FORCE_HDP                            0x00020000L
+#define SCLK_CNTL_M6__FORCE_DISP1_MASK                     0x00040000L
+#define SCLK_CNTL_M6__FORCE_DISP1                          0x00040000L
+#define SCLK_CNTL_M6__FORCE_TOP_MASK                       0x00080000L
+#define SCLK_CNTL_M6__FORCE_TOP                            0x00080000L
+#define SCLK_CNTL_M6__FORCE_E2_MASK                        0x00100000L
+#define SCLK_CNTL_M6__FORCE_E2                             0x00100000L
+#define SCLK_CNTL_M6__FORCE_SE_MASK                        0x00200000L
+#define SCLK_CNTL_M6__FORCE_SE                             0x00200000L
+#define SCLK_CNTL_M6__FORCE_IDCT_MASK                      0x00400000L
+#define SCLK_CNTL_M6__FORCE_IDCT                           0x00400000L
+#define SCLK_CNTL_M6__FORCE_VIP_MASK                       0x00800000L
+#define SCLK_CNTL_M6__FORCE_VIP                            0x00800000L
+#define SCLK_CNTL_M6__FORCE_RE_MASK                        0x01000000L
+#define SCLK_CNTL_M6__FORCE_RE                             0x01000000L
+#define SCLK_CNTL_M6__FORCE_PB_MASK                        0x02000000L
+#define SCLK_CNTL_M6__FORCE_PB                             0x02000000L
+#define SCLK_CNTL_M6__FORCE_TAM_MASK                       0x04000000L
+#define SCLK_CNTL_M6__FORCE_TAM                            0x04000000L
+#define SCLK_CNTL_M6__FORCE_TDM_MASK                       0x08000000L
+#define SCLK_CNTL_M6__FORCE_TDM                            0x08000000L
+#define SCLK_CNTL_M6__FORCE_RB_MASK                        0x10000000L
+#define SCLK_CNTL_M6__FORCE_RB                             0x10000000L
+#define SCLK_CNTL_M6__FORCE_TV_SCLK_MASK                   0x20000000L
+#define SCLK_CNTL_M6__FORCE_TV_SCLK                        0x20000000L
+#define SCLK_CNTL_M6__FORCE_SUBPIC_MASK                    0x40000000L
+#define SCLK_CNTL_M6__FORCE_SUBPIC                         0x40000000L
+#define SCLK_CNTL_M6__FORCE_OV0_MASK                       0x80000000L
+#define SCLK_CNTL_M6__FORCE_OV0                            0x80000000L
+
+// SCLK_MORE_CNTL
+#define SCLK_MORE_CNTL__DISPREGS_MAX_DYN_STOP_LAT_MASK     0x00000001L
+#define SCLK_MORE_CNTL__DISPREGS_MAX_DYN_STOP_LAT          0x00000001L
+#define SCLK_MORE_CNTL__MC_GUI_MAX_DYN_STOP_LAT_MASK       0x00000002L
+#define SCLK_MORE_CNTL__MC_GUI_MAX_DYN_STOP_LAT            0x00000002L
+#define SCLK_MORE_CNTL__MC_HOST_MAX_DYN_STOP_LAT_MASK      0x00000004L
+#define SCLK_MORE_CNTL__MC_HOST_MAX_DYN_STOP_LAT           0x00000004L
+#define SCLK_MORE_CNTL__FORCE_DISPREGS_MASK                0x00000100L
+#define SCLK_MORE_CNTL__FORCE_DISPREGS                     0x00000100L
+#define SCLK_MORE_CNTL__FORCE_MC_GUI_MASK                  0x00000200L
+#define SCLK_MORE_CNTL__FORCE_MC_GUI                       0x00000200L
+#define SCLK_MORE_CNTL__FORCE_MC_HOST_MASK                 0x00000400L
+#define SCLK_MORE_CNTL__FORCE_MC_HOST                      0x00000400L
+#define SCLK_MORE_CNTL__STOP_SCLK_EN_MASK                  0x00001000L
+#define SCLK_MORE_CNTL__STOP_SCLK_EN                       0x00001000L
+#define SCLK_MORE_CNTL__STOP_SCLK_A_MASK                   0x00002000L
+#define SCLK_MORE_CNTL__STOP_SCLK_A                        0x00002000L
+#define SCLK_MORE_CNTL__STOP_SCLK_B_MASK                   0x00004000L
+#define SCLK_MORE_CNTL__STOP_SCLK_B                        0x00004000L
+#define SCLK_MORE_CNTL__STOP_SCLK_C_MASK                   0x00008000L
+#define SCLK_MORE_CNTL__STOP_SCLK_C                        0x00008000L
+#define SCLK_MORE_CNTL__HALF_SPEED_SCLK_MASK               0x00010000L
+#define SCLK_MORE_CNTL__HALF_SPEED_SCLK                    0x00010000L
+#define SCLK_MORE_CNTL__IO_CG_VOLTAGE_DROP_MASK            0x00020000L
+#define SCLK_MORE_CNTL__IO_CG_VOLTAGE_DROP                 0x00020000L
+#define SCLK_MORE_CNTL__TVFB_SOFT_RESET_MASK               0x00040000L
+#define SCLK_MORE_CNTL__TVFB_SOFT_RESET                    0x00040000L
+#define SCLK_MORE_CNTL__VOLTAGE_DROP_SYNC_MASK             0x00080000L
+#define SCLK_MORE_CNTL__VOLTAGE_DROP_SYNC                  0x00080000L
+#define SCLK_MORE_CNTL__VOLTAGE_DELAY_SEL_MASK             0x00300000L
+#define SCLK_MORE_CNTL__IDLE_DELAY_HALF_SCLK_MASK          0x00400000L
+#define SCLK_MORE_CNTL__IDLE_DELAY_HALF_SCLK               0x00400000L
+#define SCLK_MORE_CNTL__AGP_BUSY_HALF_SCLK_MASK            0x00800000L
+#define SCLK_MORE_CNTL__AGP_BUSY_HALF_SCLK                 0x00800000L
+#define SCLK_MORE_CNTL__CG_SPARE_RD_C_MASK                 0xff000000L
+
+// MCLK_CNTL_M6
+#define MCLK_CNTL_M6__MCLKA_SRC_SEL_MASK                   0x00000007L
+#define MCLK_CNTL_M6__YCLKA_SRC_SEL_MASK                   0x00000070L
+#define MCLK_CNTL_M6__MCLKB_SRC_SEL_MASK                   0x00000700L
+#define MCLK_CNTL_M6__YCLKB_SRC_SEL_MASK                   0x00007000L
+#define MCLK_CNTL_M6__FORCE_MCLKA_MASK                     0x00010000L
+#define MCLK_CNTL_M6__FORCE_MCLKA                          0x00010000L
+#define MCLK_CNTL_M6__FORCE_MCLKB_MASK                     0x00020000L
+#define MCLK_CNTL_M6__FORCE_MCLKB                          0x00020000L
+#define MCLK_CNTL_M6__FORCE_YCLKA_MASK                     0x00040000L
+#define MCLK_CNTL_M6__FORCE_YCLKA                          0x00040000L
+#define MCLK_CNTL_M6__FORCE_YCLKB_MASK                     0x00080000L
+#define MCLK_CNTL_M6__FORCE_YCLKB                          0x00080000L
+#define MCLK_CNTL_M6__FORCE_MC_MASK                        0x00100000L
+#define MCLK_CNTL_M6__FORCE_MC                             0x00100000L
+#define MCLK_CNTL_M6__FORCE_AIC_MASK                       0x00200000L
+#define MCLK_CNTL_M6__FORCE_AIC                            0x00200000L
+#define MCLK_CNTL_M6__MRDCKA0_SOUTSEL_MASK                 0x03000000L
+#define MCLK_CNTL_M6__MRDCKA1_SOUTSEL_MASK                 0x0c000000L
+#define MCLK_CNTL_M6__MRDCKB0_SOUTSEL_MASK                 0x30000000L
+#define MCLK_CNTL_M6__MRDCKB1_SOUTSEL_MASK                 0xc0000000L
+
+// MCLK_MISC
+#define MCLK_MISC__SCLK_SOURCED_FROM_MPLL_SEL_MASK         0x00000003L
+#define MCLK_MISC__MCLK_FROM_SPLL_DIV_SEL_MASK             0x00000004L
+#define MCLK_MISC__MCLK_FROM_SPLL_DIV_SEL                  0x00000004L
+#define MCLK_MISC__ENABLE_SCLK_FROM_MPLL_MASK              0x00000008L
+#define MCLK_MISC__ENABLE_SCLK_FROM_MPLL                   0x00000008L
+#define MCLK_MISC__MPLL_MODEA_MODEC_HW_SEL_EN_MASK         0x00000010L
+#define MCLK_MISC__MPLL_MODEA_MODEC_HW_SEL_EN              0x00000010L
+#define MCLK_MISC__DLL_READY_LAT_MASK                      0x00000100L
+#define MCLK_MISC__DLL_READY_LAT                           0x00000100L
+#define MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT_MASK           0x00001000L
+#define MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT                0x00001000L
+#define MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT_MASK           0x00002000L
+#define MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT                0x00002000L
+#define MCLK_MISC__MC_MCLK_DYN_ENABLE_MASK                 0x00004000L
+#define MCLK_MISC__MC_MCLK_DYN_ENABLE                      0x00004000L
+#define MCLK_MISC__IO_MCLK_DYN_ENABLE_MASK                 0x00008000L
+#define MCLK_MISC__IO_MCLK_DYN_ENABLE                      0x00008000L
+#define MCLK_MISC__CGM_CLK_TO_OUTPIN_MASK                  0x00010000L
+#define MCLK_MISC__CGM_CLK_TO_OUTPIN                       0x00010000L
+#define MCLK_MISC__CLK_OR_COUNT_SEL_MASK                   0x00020000L
+#define MCLK_MISC__CLK_OR_COUNT_SEL                        0x00020000L
+#define MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND_MASK        0x00040000L
+#define MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND             0x00040000L
+#define MCLK_MISC__CGM_SPARE_RD_MASK                       0x00300000L
+#define MCLK_MISC__CGM_SPARE_A_RD_MASK                     0x00c00000L
+#define MCLK_MISC__TCLK_TO_YCLKB_EN_MASK                   0x01000000L
+#define MCLK_MISC__TCLK_TO_YCLKB_EN                        0x01000000L
+#define MCLK_MISC__CGM_SPARE_A_MASK                        0x0e000000L
+
+// VCLK_ECP_CNTL
+#define VCLK_ECP_CNTL__VCLK_SRC_SEL_MASK                   0x00000003L
+#define VCLK_ECP_CNTL__VCLK_INVERT_MASK                    0x00000010L
+#define VCLK_ECP_CNTL__VCLK_INVERT                         0x00000010L
+#define VCLK_ECP_CNTL__PIXCLK_SRC_INVERT_MASK              0x00000020L
+#define VCLK_ECP_CNTL__PIXCLK_SRC_INVERT                   0x00000020L
+#define VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb_MASK              0x00000040L
+#define VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb                   0x00000040L
+#define VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb_MASK          0x00000080L
+#define VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb               0x00000080L
+#define VCLK_ECP_CNTL__ECP_DIV_MASK                        0x00000300L
+#define VCLK_ECP_CNTL__ECP_FORCE_ON_MASK                   0x00040000L
+#define VCLK_ECP_CNTL__ECP_FORCE_ON                        0x00040000L
+#define VCLK_ECP_CNTL__SUBCLK_FORCE_ON_MASK                0x00080000L
+#define VCLK_ECP_CNTL__SUBCLK_FORCE_ON                     0x00080000L
+
+// PLL_PWRMGT_CNTL
+#define PLL_PWRMGT_CNTL__MPLL_TURNOFF_MASK                 0x00000001L
+#define PLL_PWRMGT_CNTL__MPLL_TURNOFF                      0x00000001L
+#define PLL_PWRMGT_CNTL__SPLL_TURNOFF_MASK                 0x00000002L
+#define PLL_PWRMGT_CNTL__SPLL_TURNOFF                      0x00000002L
+#define PLL_PWRMGT_CNTL__PPLL_TURNOFF_MASK                 0x00000004L
+#define PLL_PWRMGT_CNTL__PPLL_TURNOFF                      0x00000004L
+#define PLL_PWRMGT_CNTL__P2PLL_TURNOFF_MASK                0x00000008L
+#define PLL_PWRMGT_CNTL__P2PLL_TURNOFF                     0x00000008L
+#define PLL_PWRMGT_CNTL__TVPLL_TURNOFF_MASK                0x00000010L
+#define PLL_PWRMGT_CNTL__TVPLL_TURNOFF                     0x00000010L
+#define PLL_PWRMGT_CNTL__AGPCLK_DYN_STOP_LAT_MASK          0x000001e0L
+#define PLL_PWRMGT_CNTL__APM_POWER_STATE_MASK              0x00000600L
+#define PLL_PWRMGT_CNTL__APM_PWRSTATE_RD_MASK              0x00001800L
+#define PLL_PWRMGT_CNTL__PM_MODE_SEL_MASK                  0x00002000L
+#define PLL_PWRMGT_CNTL__PM_MODE_SEL                       0x00002000L
+#define PLL_PWRMGT_CNTL__EN_PWRSEQ_DONE_COND_MASK          0x00004000L
+#define PLL_PWRMGT_CNTL__EN_PWRSEQ_DONE_COND               0x00004000L
+#define PLL_PWRMGT_CNTL__EN_DISP_PARKED_COND_MASK          0x00008000L
+#define PLL_PWRMGT_CNTL__EN_DISP_PARKED_COND               0x00008000L
+#define PLL_PWRMGT_CNTL__MOBILE_SU_MASK                    0x00010000L
+#define PLL_PWRMGT_CNTL__MOBILE_SU                         0x00010000L
+#define PLL_PWRMGT_CNTL__SU_SCLK_USE_BCLK_MASK             0x00020000L
+#define PLL_PWRMGT_CNTL__SU_SCLK_USE_BCLK                  0x00020000L
+#define PLL_PWRMGT_CNTL__SU_MCLK_USE_BCLK_MASK             0x00040000L
+#define PLL_PWRMGT_CNTL__SU_MCLK_USE_BCLK                  0x00040000L
+#define PLL_PWRMGT_CNTL__SU_SUSTAIN_DISABLE_MASK           0x00080000L
+#define PLL_PWRMGT_CNTL__SU_SUSTAIN_DISABLE                0x00080000L
+#define PLL_PWRMGT_CNTL__TCL_BYPASS_DISABLE_MASK           0x00100000L
+#define PLL_PWRMGT_CNTL__TCL_BYPASS_DISABLE                0x00100000L
+#define PLL_PWRMGT_CNTL__TCL_CLOCK_ACTIVE_RD_MASK          0x00200000L
+#define PLL_PWRMGT_CNTL__TCL_CLOCK_ACTIVE_RD               0x00200000L
+#define PLL_PWRMGT_CNTL__CG_NO2_DEBUG_MASK                 0xff000000L
+
+// CLK_PWRMGT_CNTL_M6
+#define CLK_PWRMGT_CNTL_M6__MPLL_PWRMGT_OFF_MASK           0x00000001L
+#define CLK_PWRMGT_CNTL_M6__MPLL_PWRMGT_OFF                0x00000001L
+#define CLK_PWRMGT_CNTL_M6__SPLL_PWRMGT_OFF_MASK           0x00000002L
+#define CLK_PWRMGT_CNTL_M6__SPLL_PWRMGT_OFF                0x00000002L
+#define CLK_PWRMGT_CNTL_M6__PPLL_PWRMGT_OFF_MASK           0x00000004L
+#define CLK_PWRMGT_CNTL_M6__PPLL_PWRMGT_OFF                0x00000004L
+#define CLK_PWRMGT_CNTL_M6__P2PLL_PWRMGT_OFF_MASK          0x00000008L
+#define CLK_PWRMGT_CNTL_M6__P2PLL_PWRMGT_OFF               0x00000008L
+#define CLK_PWRMGT_CNTL_M6__MCLK_TURNOFF_MASK              0x00000010L
+#define CLK_PWRMGT_CNTL_M6__MCLK_TURNOFF                   0x00000010L
+#define CLK_PWRMGT_CNTL_M6__SCLK_TURNOFF_MASK              0x00000020L
+#define CLK_PWRMGT_CNTL_M6__SCLK_TURNOFF                   0x00000020L
+#define CLK_PWRMGT_CNTL_M6__PCLK_TURNOFF_MASK              0x00000040L
+#define CLK_PWRMGT_CNTL_M6__PCLK_TURNOFF                   0x00000040L
+#define CLK_PWRMGT_CNTL_M6__P2CLK_TURNOFF_MASK             0x00000080L
+#define CLK_PWRMGT_CNTL_M6__P2CLK_TURNOFF                  0x00000080L
+#define CLK_PWRMGT_CNTL_M6__MC_CH_MODE_MASK                0x00000100L
+#define CLK_PWRMGT_CNTL_M6__MC_CH_MODE                     0x00000100L
+#define CLK_PWRMGT_CNTL_M6__TEST_MODE_MASK                 0x00000200L
+#define CLK_PWRMGT_CNTL_M6__TEST_MODE                      0x00000200L
+#define CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN_MASK            0x00000400L
+#define CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN                 0x00000400L
+#define CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE_MASK        0x00001000L
+#define CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE             0x00001000L
+#define CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK           0x00006000L
+#define CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT_MASK         0x00008000L
+#define CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT              0x00008000L
+#define CLK_PWRMGT_CNTL_M6__MC_BUSY_MASK                   0x00010000L
+#define CLK_PWRMGT_CNTL_M6__MC_BUSY                        0x00010000L
+#define CLK_PWRMGT_CNTL_M6__MC_INT_CNTL_MASK               0x00020000L
+#define CLK_PWRMGT_CNTL_M6__MC_INT_CNTL                    0x00020000L
+#define CLK_PWRMGT_CNTL_M6__MC_SWITCH_MASK                 0x00040000L
+#define CLK_PWRMGT_CNTL_M6__MC_SWITCH                      0x00040000L
+#define CLK_PWRMGT_CNTL_M6__DLL_READY_MASK                 0x00080000L
+#define CLK_PWRMGT_CNTL_M6__DLL_READY                      0x00080000L
+#define CLK_PWRMGT_CNTL_M6__DISP_PM_MASK                   0x00100000L
+#define CLK_PWRMGT_CNTL_M6__DISP_PM                        0x00100000L
+#define CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE_MASK             0x00e00000L
+#define CLK_PWRMGT_CNTL_M6__CG_NO1_DEBUG_MASK              0x3f000000L
+#define CLK_PWRMGT_CNTL_M6__TVPLL_PWRMGT_OFF_MASK          0x40000000L
+#define CLK_PWRMGT_CNTL_M6__TVPLL_PWRMGT_OFF               0x40000000L
+#define CLK_PWRMGT_CNTL_M6__TVCLK_TURNOFF_MASK             0x80000000L
+#define CLK_PWRMGT_CNTL_M6__TVCLK_TURNOFF                  0x80000000L
+
+// BUS_CNTL1
+#define BUS_CNTL1__PMI_IO_DISABLE_MASK                     0x00000001L
+#define BUS_CNTL1__PMI_IO_DISABLE                          0x00000001L
+#define BUS_CNTL1__PMI_MEM_DISABLE_MASK                    0x00000002L
+#define BUS_CNTL1__PMI_MEM_DISABLE                         0x00000002L
+#define BUS_CNTL1__PMI_BM_DISABLE_MASK                     0x00000004L
+#define BUS_CNTL1__PMI_BM_DISABLE                          0x00000004L
+#define BUS_CNTL1__PMI_INT_DISABLE_MASK                    0x00000008L
+#define BUS_CNTL1__PMI_INT_DISABLE                         0x00000008L
+#define BUS_CNTL1__BUS2_IMMEDIATE_PMI_DISABLE_MASK         0x00000020L
+#define BUS_CNTL1__BUS2_IMMEDIATE_PMI_DISABLE              0x00000020L
+#define BUS_CNTL1__BUS2_VGA_REG_COHERENCY_DIS_MASK         0x00000100L
+#define BUS_CNTL1__BUS2_VGA_REG_COHERENCY_DIS              0x00000100L
+#define BUS_CNTL1__BUS2_VGA_MEM_COHERENCY_DIS_MASK         0x00000200L
+#define BUS_CNTL1__BUS2_VGA_MEM_COHERENCY_DIS              0x00000200L
+#define BUS_CNTL1__BUS2_HDP_REG_COHERENCY_DIS_MASK         0x00000400L
+#define BUS_CNTL1__BUS2_HDP_REG_COHERENCY_DIS              0x00000400L
+#define BUS_CNTL1__BUS2_GUI_INITIATOR_COHERENCY_DIS_MASK   0x00000800L
+#define BUS_CNTL1__BUS2_GUI_INITIATOR_COHERENCY_DIS        0x00000800L
+#define BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK                0x0c000000L
+#define BUS_CNTL1__SEND_SBA_LATENCY_MASK                   0x70000000L
+#define BUS_CNTL1__AGPCLK_VALID_MASK                       0x80000000L
+#define BUS_CNTL1__AGPCLK_VALID                            0x80000000L
+
+// BUS_CNTL1
+#define	BUS_CNTL1__PMI_IO_DISABLE__SHIFT                   0x00000000
+#define	BUS_CNTL1__PMI_MEM_DISABLE__SHIFT                  0x00000001
+#define	BUS_CNTL1__PMI_BM_DISABLE__SHIFT                   0x00000002
+#define	BUS_CNTL1__PMI_INT_DISABLE__SHIFT                  0x00000003
+#define	BUS_CNTL1__BUS2_IMMEDIATE_PMI_DISABLE__SHIFT       0x00000005
+#define	BUS_CNTL1__BUS2_VGA_REG_COHERENCY_DIS__SHIFT       0x00000008
+#define	BUS_CNTL1__BUS2_VGA_MEM_COHERENCY_DIS__SHIFT       0x00000009
+#define	BUS_CNTL1__BUS2_HDP_REG_COHERENCY_DIS__SHIFT       0x0000000a
+#define	BUS_CNTL1__BUS2_GUI_INITIATOR_COHERENCY_DIS__SHIFT 0x0000000b
+#define	BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT              0x0000001a
+#define	BUS_CNTL1__SEND_SBA_LATENCY__SHIFT                 0x0000001c
+#define	BUS_CNTL1__AGPCLK_VALID__SHIFT                     0x0000001f
+
+// CRTC_OFFSET_CNTL
+#define CRTC_OFFSET_CNTL__CRTC_TILE_LINE_MASK              0x0000000fL
+#define CRTC_OFFSET_CNTL__CRTC_TILE_LINE_RIGHT_MASK        0x000000f0L
+#define CRTC_OFFSET_CNTL__CRTC_TILE_EN_RIGHT_MASK          0x00004000L
+#define CRTC_OFFSET_CNTL__CRTC_TILE_EN_RIGHT               0x00004000L
+#define CRTC_OFFSET_CNTL__CRTC_TILE_EN_MASK                0x00008000L
+#define CRTC_OFFSET_CNTL__CRTC_TILE_EN                     0x00008000L
+#define CRTC_OFFSET_CNTL__CRTC_OFFSET_FLIP_CNTL_MASK       0x00010000L
+#define CRTC_OFFSET_CNTL__CRTC_OFFSET_FLIP_CNTL            0x00010000L
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_OFFSET_EN_MASK       0x00020000L
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_OFFSET_EN            0x00020000L
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_EN_MASK         0x000c0000L
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN_MASK     0x00100000L
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN          0x00100000L
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_MASK            0x00200000L
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC                 0x00200000L
+#define CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET_LEFT_EN_MASK 0x10000000L
+#define CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET_LEFT_EN     0x10000000L
+#define CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET_RIGHT_EN_MASK 0x20000000L
+#define CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET_RIGHT_EN    0x20000000L
+#define CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET_MASK        0x40000000L
+#define CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET             0x40000000L
+#define CRTC_OFFSET_CNTL__CRTC_OFFSET_LOCK_MASK            0x80000000L
+#define CRTC_OFFSET_CNTL__CRTC_OFFSET_LOCK                 0x80000000L
+
+// CRTC_GEN_CNTL
+#define CRTC_GEN_CNTL__CRTC_DBL_SCAN_EN_MASK               0x00000001L
+#define CRTC_GEN_CNTL__CRTC_DBL_SCAN_EN                    0x00000001L
+#define CRTC_GEN_CNTL__CRTC_INTERLACE_EN_MASK              0x00000002L
+#define CRTC_GEN_CNTL__CRTC_INTERLACE_EN                   0x00000002L
+#define CRTC_GEN_CNTL__CRTC_C_SYNC_EN_MASK                 0x00000010L
+#define CRTC_GEN_CNTL__CRTC_C_SYNC_EN                      0x00000010L
+#define CRTC_GEN_CNTL__CRTC_PIX_WIDTH_MASK                 0x00000f00L
+#define CRTC_GEN_CNTL__CRTC_ICON_EN_MASK                   0x00008000L
+#define CRTC_GEN_CNTL__CRTC_ICON_EN                        0x00008000L
+#define CRTC_GEN_CNTL__CRTC_CUR_EN_MASK                    0x00010000L
+#define CRTC_GEN_CNTL__CRTC_CUR_EN                         0x00010000L
+#define CRTC_GEN_CNTL__CRTC_VSTAT_MODE_MASK                0x00060000L
+#define CRTC_GEN_CNTL__CRTC_CUR_MODE_MASK                  0x00700000L
+#define CRTC_GEN_CNTL__CRTC_EXT_DISP_EN_MASK               0x01000000L
+#define CRTC_GEN_CNTL__CRTC_EXT_DISP_EN                    0x01000000L
+#define CRTC_GEN_CNTL__CRTC_EN_MASK                        0x02000000L
+#define CRTC_GEN_CNTL__CRTC_EN                             0x02000000L
+#define CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B_MASK             0x04000000L
+#define CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B                  0x04000000L
+
+// CRTC2_GEN_CNTL
+#define CRTC2_GEN_CNTL__CRTC2_DBL_SCAN_EN_MASK             0x00000001L
+#define CRTC2_GEN_CNTL__CRTC2_DBL_SCAN_EN                  0x00000001L
+#define CRTC2_GEN_CNTL__CRTC2_INTERLACE_EN_MASK            0x00000002L
+#define CRTC2_GEN_CNTL__CRTC2_INTERLACE_EN                 0x00000002L
+#define CRTC2_GEN_CNTL__CRTC2_SYNC_TRISTATE_MASK           0x00000010L
+#define CRTC2_GEN_CNTL__CRTC2_SYNC_TRISTATE                0x00000010L
+#define CRTC2_GEN_CNTL__CRTC2_HSYNC_TRISTATE_MASK          0x00000020L
+#define CRTC2_GEN_CNTL__CRTC2_HSYNC_TRISTATE               0x00000020L
+#define CRTC2_GEN_CNTL__CRTC2_VSYNC_TRISTATE_MASK          0x00000040L
+#define CRTC2_GEN_CNTL__CRTC2_VSYNC_TRISTATE               0x00000040L
+#define CRTC2_GEN_CNTL__CRT2_ON_MASK                       0x00000080L
+#define CRTC2_GEN_CNTL__CRT2_ON                            0x00000080L
+#define CRTC2_GEN_CNTL__CRTC2_PIX_WIDTH_MASK               0x00000f00L
+#define CRTC2_GEN_CNTL__CRTC2_ICON_EN_MASK                 0x00008000L
+#define CRTC2_GEN_CNTL__CRTC2_ICON_EN                      0x00008000L
+#define CRTC2_GEN_CNTL__CRTC2_CUR_EN_MASK                  0x00010000L
+#define CRTC2_GEN_CNTL__CRTC2_CUR_EN                       0x00010000L
+#define CRTC2_GEN_CNTL__CRTC2_CUR_MODE_MASK                0x00700000L
+#define CRTC2_GEN_CNTL__CRTC2_DISPLAY_DIS_MASK             0x00800000L
+#define CRTC2_GEN_CNTL__CRTC2_DISPLAY_DIS                  0x00800000L
+#define CRTC2_GEN_CNTL__CRTC2_EN_MASK                      0x02000000L
+#define CRTC2_GEN_CNTL__CRTC2_EN                           0x02000000L
+#define CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B_MASK           0x04000000L
+#define CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B                0x04000000L
+#define CRTC2_GEN_CNTL__CRTC2_C_SYNC_EN_MASK               0x08000000L
+#define CRTC2_GEN_CNTL__CRTC2_C_SYNC_EN                    0x08000000L
+#define CRTC2_GEN_CNTL__CRTC2_HSYNC_DIS_MASK               0x10000000L
+#define CRTC2_GEN_CNTL__CRTC2_HSYNC_DIS                    0x10000000L
+#define CRTC2_GEN_CNTL__CRTC2_VSYNC_DIS_MASK               0x20000000L
+#define CRTC2_GEN_CNTL__CRTC2_VSYNC_DIS                    0x20000000L
+
+// AGP_CNTL
+#define AGP_CNTL__MAX_IDLE_CLK_MASK                        0x000000ffL
+#define AGP_CNTL__HOLD_RD_FIFO_MASK                        0x00000100L
+#define AGP_CNTL__HOLD_RD_FIFO                             0x00000100L
+#define AGP_CNTL__HOLD_RQ_FIFO_MASK                        0x00000200L
+#define AGP_CNTL__HOLD_RQ_FIFO                             0x00000200L
+#define AGP_CNTL__EN_2X_STBB_MASK                          0x00000400L
+#define AGP_CNTL__EN_2X_STBB                               0x00000400L
+#define AGP_CNTL__FORCE_FULL_SBA_MASK                      0x00000800L
+#define AGP_CNTL__FORCE_FULL_SBA                           0x00000800L
+#define AGP_CNTL__SBA_DIS_MASK                             0x00001000L
+#define AGP_CNTL__SBA_DIS                                  0x00001000L
+#define AGP_CNTL__AGP_REV_ID_MASK                          0x00002000L
+#define AGP_CNTL__AGP_REV_ID                               0x00002000L
+#define AGP_CNTL__REG_CRIPPLE_AGP4X_MASK                   0x00004000L
+#define AGP_CNTL__REG_CRIPPLE_AGP4X                        0x00004000L
+#define AGP_CNTL__REG_CRIPPLE_AGP2X4X_MASK                 0x00008000L
+#define AGP_CNTL__REG_CRIPPLE_AGP2X4X                      0x00008000L
+#define AGP_CNTL__FORCE_INT_VREF_MASK                      0x00010000L
+#define AGP_CNTL__FORCE_INT_VREF                           0x00010000L
+#define AGP_CNTL__PENDING_SLOTS_VAL_MASK                   0x00060000L
+#define AGP_CNTL__PENDING_SLOTS_SEL_MASK                   0x00080000L
+#define AGP_CNTL__PENDING_SLOTS_SEL                        0x00080000L
+#define AGP_CNTL__EN_EXTENDED_AD_STB_2X_MASK               0x00100000L
+#define AGP_CNTL__EN_EXTENDED_AD_STB_2X                    0x00100000L
+#define AGP_CNTL__DIS_QUEUED_GNT_FIX_MASK                  0x00200000L
+#define AGP_CNTL__DIS_QUEUED_GNT_FIX                       0x00200000L
+#define AGP_CNTL__EN_RDATA2X4X_MULTIRESET_MASK             0x00400000L
+#define AGP_CNTL__EN_RDATA2X4X_MULTIRESET                  0x00400000L
+#define AGP_CNTL__EN_RBFCALM_MASK                          0x00800000L
+#define AGP_CNTL__EN_RBFCALM                               0x00800000L
+#define AGP_CNTL__FORCE_EXT_VREF_MASK                      0x01000000L
+#define AGP_CNTL__FORCE_EXT_VREF                           0x01000000L
+#define AGP_CNTL__DIS_RBF_MASK                             0x02000000L
+#define AGP_CNTL__DIS_RBF                                  0x02000000L
+#define AGP_CNTL__DELAY_FIRST_SBA_EN_MASK                  0x04000000L
+#define AGP_CNTL__DELAY_FIRST_SBA_EN                       0x04000000L
+#define AGP_CNTL__DELAY_FIRST_SBA_VAL_MASK                 0x38000000L
+#define AGP_CNTL__AGP_MISC_MASK                            0xc0000000L
+
+// AGP_CNTL
+#define	AGP_CNTL__MAX_IDLE_CLK__SHIFT                      0x00000000
+#define	AGP_CNTL__HOLD_RD_FIFO__SHIFT                      0x00000008
+#define	AGP_CNTL__HOLD_RQ_FIFO__SHIFT                      0x00000009
+#define	AGP_CNTL__EN_2X_STBB__SHIFT                        0x0000000a
+#define	AGP_CNTL__FORCE_FULL_SBA__SHIFT                    0x0000000b
+#define	AGP_CNTL__SBA_DIS__SHIFT                           0x0000000c
+#define	AGP_CNTL__AGP_REV_ID__SHIFT                        0x0000000d
+#define	AGP_CNTL__REG_CRIPPLE_AGP4X__SHIFT                 0x0000000e
+#define	AGP_CNTL__REG_CRIPPLE_AGP2X4X__SHIFT               0x0000000f
+#define	AGP_CNTL__FORCE_INT_VREF__SHIFT                    0x00000010
+#define	AGP_CNTL__PENDING_SLOTS_VAL__SHIFT                 0x00000011
+#define	AGP_CNTL__PENDING_SLOTS_SEL__SHIFT                 0x00000013
+#define	AGP_CNTL__EN_EXTENDED_AD_STB_2X__SHIFT             0x00000014
+#define	AGP_CNTL__DIS_QUEUED_GNT_FIX__SHIFT                0x00000015
+#define	AGP_CNTL__EN_RDATA2X4X_MULTIRESET__SHIFT           0x00000016
+#define	AGP_CNTL__EN_RBFCALM__SHIFT                        0x00000017
+#define	AGP_CNTL__FORCE_EXT_VREF__SHIFT                    0x00000018
+#define	AGP_CNTL__DIS_RBF__SHIFT                           0x00000019
+#define	AGP_CNTL__DELAY_FIRST_SBA_EN__SHIFT                0x0000001a
+#define	AGP_CNTL__DELAY_FIRST_SBA_VAL__SHIFT               0x0000001b
+#define	AGP_CNTL__AGP_MISC__SHIFT                          0x0000001e
+
+// DISP_MISC_CNTL
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH_PP_MASK            0x00000001L
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH_PP                 0x00000001L
+#define DISP_MISC_CNTL__SOFT_RESET_SUBPIC_PP_MASK          0x00000002L
+#define DISP_MISC_CNTL__SOFT_RESET_SUBPIC_PP               0x00000002L
+#define DISP_MISC_CNTL__SOFT_RESET_OV0_PP_MASK             0x00000004L
+#define DISP_MISC_CNTL__SOFT_RESET_OV0_PP                  0x00000004L
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH_SCLK_MASK          0x00000010L
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH_SCLK               0x00000010L
+#define DISP_MISC_CNTL__SOFT_RESET_SUBPIC_SCLK_MASK        0x00000020L
+#define DISP_MISC_CNTL__SOFT_RESET_SUBPIC_SCLK             0x00000020L
+#define DISP_MISC_CNTL__SOFT_RESET_OV0_SCLK_MASK           0x00000040L
+#define DISP_MISC_CNTL__SOFT_RESET_OV0_SCLK                0x00000040L
+#define DISP_MISC_CNTL__SYNC_STRENGTH_MASK                 0x00000300L
+#define DISP_MISC_CNTL__SYNC_PAD_FLOP_EN_MASK              0x00000400L
+#define DISP_MISC_CNTL__SYNC_PAD_FLOP_EN                   0x00000400L
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH2_PP_MASK           0x00001000L
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH2_PP                0x00001000L
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH2_SCLK_MASK         0x00008000L
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH2_SCLK              0x00008000L
+#define DISP_MISC_CNTL__SOFT_RESET_LVDS_MASK               0x00010000L
+#define DISP_MISC_CNTL__SOFT_RESET_LVDS                    0x00010000L
+#define DISP_MISC_CNTL__SOFT_RESET_TMDS_MASK               0x00020000L
+#define DISP_MISC_CNTL__SOFT_RESET_TMDS                    0x00020000L
+#define DISP_MISC_CNTL__SOFT_RESET_DIG_TMDS_MASK           0x00040000L
+#define DISP_MISC_CNTL__SOFT_RESET_DIG_TMDS                0x00040000L
+#define DISP_MISC_CNTL__SOFT_RESET_TV_MASK                 0x00080000L
+#define DISP_MISC_CNTL__SOFT_RESET_TV                      0x00080000L
+#define DISP_MISC_CNTL__PALETTE2_MEM_RD_MARGIN_MASK        0x00f00000L
+#define DISP_MISC_CNTL__PALETTE_MEM_RD_MARGIN_MASK         0x0f000000L
+#define DISP_MISC_CNTL__RMX_BUF_MEM_RD_MARGIN_MASK         0xf0000000L
+
+// DISP_PWR_MAN
+#define DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN_MASK         0x00000001L
+#define DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN              0x00000001L
+#define DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN_MASK       0x00000010L
+#define DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN            0x00000010L
+#define DISP_PWR_MAN__DISP_PWR_MAN_DPMS_MASK               0x00000300L
+#define DISP_PWR_MAN__DISP_D3_RST_MASK                     0x00010000L
+#define DISP_PWR_MAN__DISP_D3_RST                          0x00010000L
+#define DISP_PWR_MAN__DISP_D3_REG_RST_MASK                 0x00020000L
+#define DISP_PWR_MAN__DISP_D3_REG_RST                      0x00020000L
+#define DISP_PWR_MAN__DISP_D3_GRPH_RST_MASK                0x00040000L
+#define DISP_PWR_MAN__DISP_D3_GRPH_RST                     0x00040000L
+#define DISP_PWR_MAN__DISP_D3_SUBPIC_RST_MASK              0x00080000L
+#define DISP_PWR_MAN__DISP_D3_SUBPIC_RST                   0x00080000L
+#define DISP_PWR_MAN__DISP_D3_OV0_RST_MASK                 0x00100000L
+#define DISP_PWR_MAN__DISP_D3_OV0_RST                      0x00100000L
+#define DISP_PWR_MAN__DISP_D1D2_GRPH_RST_MASK              0x00200000L
+#define DISP_PWR_MAN__DISP_D1D2_GRPH_RST                   0x00200000L
+#define DISP_PWR_MAN__DISP_D1D2_SUBPIC_RST_MASK            0x00400000L
+#define DISP_PWR_MAN__DISP_D1D2_SUBPIC_RST                 0x00400000L
+#define DISP_PWR_MAN__DISP_D1D2_OV0_RST_MASK               0x00800000L
+#define DISP_PWR_MAN__DISP_D1D2_OV0_RST                    0x00800000L
+#define DISP_PWR_MAN__DIG_TMDS_ENABLE_RST_MASK             0x01000000L
+#define DISP_PWR_MAN__DIG_TMDS_ENABLE_RST                  0x01000000L
+#define DISP_PWR_MAN__TV_ENABLE_RST_MASK                   0x02000000L
+#define DISP_PWR_MAN__TV_ENABLE_RST                        0x02000000L
+#define DISP_PWR_MAN__AUTO_PWRUP_EN_MASK                   0x04000000L
+#define DISP_PWR_MAN__AUTO_PWRUP_EN                        0x04000000L
+
+// MC_IND_INDEX
+#define MC_IND_INDEX__MC_IND_ADDR_MASK                     0x0000001fL
+#define MC_IND_INDEX__MC_IND_WR_EN_MASK                    0x00000100L
+#define MC_IND_INDEX__MC_IND_WR_EN                         0x00000100L
+
+// MC_IND_DATA
+#define MC_IND_DATA__MC_IND_DATA_MASK                      0xffffffffL
+
+// MC_CHP_IO_CNTL_A1
+#define	MC_CHP_IO_CNTL_A1__MEM_SLEWN_CKA__SHIFT            0x00000000
+#define	MC_CHP_IO_CNTL_A1__MEM_SLEWN_AA__SHIFT             0x00000001
+#define	MC_CHP_IO_CNTL_A1__MEM_SLEWN_DQMA__SHIFT           0x00000002
+#define	MC_CHP_IO_CNTL_A1__MEM_SLEWN_DQSA__SHIFT           0x00000003
+#define	MC_CHP_IO_CNTL_A1__MEM_SLEWP_CKA__SHIFT            0x00000004
+#define	MC_CHP_IO_CNTL_A1__MEM_SLEWP_AA__SHIFT             0x00000005
+#define	MC_CHP_IO_CNTL_A1__MEM_SLEWP_DQMA__SHIFT           0x00000006
+#define	MC_CHP_IO_CNTL_A1__MEM_SLEWP_DQSA__SHIFT           0x00000007
+#define	MC_CHP_IO_CNTL_A1__MEM_PREAMP_AA__SHIFT            0x00000008
+#define	MC_CHP_IO_CNTL_A1__MEM_PREAMP_DQMA__SHIFT          0x00000009
+#define	MC_CHP_IO_CNTL_A1__MEM_PREAMP_DQSA__SHIFT          0x0000000a
+#define	MC_CHP_IO_CNTL_A1__MEM_IO_MODEA__SHIFT             0x0000000c
+#define	MC_CHP_IO_CNTL_A1__MEM_REC_CKA__SHIFT              0x0000000e
+#define	MC_CHP_IO_CNTL_A1__MEM_REC_AA__SHIFT               0x00000010
+#define	MC_CHP_IO_CNTL_A1__MEM_REC_DQMA__SHIFT             0x00000012
+#define	MC_CHP_IO_CNTL_A1__MEM_REC_DQSA__SHIFT             0x00000014
+#define	MC_CHP_IO_CNTL_A1__MEM_SYNC_PHASEA__SHIFT          0x00000016
+#define	MC_CHP_IO_CNTL_A1__MEM_SYNC_CENTERA__SHIFT         0x00000017
+#define	MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT             0x00000018
+#define	MC_CHP_IO_CNTL_A1__MEM_CLK_SELA__SHIFT             0x0000001a
+#define	MC_CHP_IO_CNTL_A1__MEM_CLK_INVA__SHIFT             0x0000001c
+#define	MC_CHP_IO_CNTL_A1__MEM_DATA_ENIMP_A__SHIFT         0x0000001e
+#define	MC_CHP_IO_CNTL_A1__MEM_CNTL_ENIMP_A__SHIFT         0x0000001f
+
+// MC_CHP_IO_CNTL_B1
+#define	MC_CHP_IO_CNTL_B1__MEM_SLEWN_CKB__SHIFT            0x00000000
+#define	MC_CHP_IO_CNTL_B1__MEM_SLEWN_AB__SHIFT             0x00000001
+#define	MC_CHP_IO_CNTL_B1__MEM_SLEWN_DQMB__SHIFT           0x00000002
+#define	MC_CHP_IO_CNTL_B1__MEM_SLEWN_DQSB__SHIFT           0x00000003
+#define	MC_CHP_IO_CNTL_B1__MEM_SLEWP_CKB__SHIFT            0x00000004
+#define	MC_CHP_IO_CNTL_B1__MEM_SLEWP_AB__SHIFT             0x00000005
+#define	MC_CHP_IO_CNTL_B1__MEM_SLEWP_DQMB__SHIFT           0x00000006
+#define	MC_CHP_IO_CNTL_B1__MEM_SLEWP_DQSB__SHIFT           0x00000007
+#define	MC_CHP_IO_CNTL_B1__MEM_PREAMP_AB__SHIFT            0x00000008
+#define	MC_CHP_IO_CNTL_B1__MEM_PREAMP_DQMB__SHIFT          0x00000009
+#define	MC_CHP_IO_CNTL_B1__MEM_PREAMP_DQSB__SHIFT          0x0000000a
+#define	MC_CHP_IO_CNTL_B1__MEM_IO_MODEB__SHIFT             0x0000000c
+#define	MC_CHP_IO_CNTL_B1__MEM_REC_CKB__SHIFT              0x0000000e
+#define	MC_CHP_IO_CNTL_B1__MEM_REC_AB__SHIFT               0x00000010
+#define	MC_CHP_IO_CNTL_B1__MEM_REC_DQMB__SHIFT             0x00000012
+#define	MC_CHP_IO_CNTL_B1__MEM_REC_DQSB__SHIFT             0x00000014
+#define	MC_CHP_IO_CNTL_B1__MEM_SYNC_PHASEB__SHIFT          0x00000016
+#define	MC_CHP_IO_CNTL_B1__MEM_SYNC_CENTERB__SHIFT         0x00000017
+#define	MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT             0x00000018
+#define	MC_CHP_IO_CNTL_B1__MEM_CLK_SELB__SHIFT             0x0000001a
+#define	MC_CHP_IO_CNTL_B1__MEM_CLK_INVB__SHIFT             0x0000001c
+#define	MC_CHP_IO_CNTL_B1__MEM_DATA_ENIMP_B__SHIFT         0x0000001e
+#define	MC_CHP_IO_CNTL_B1__MEM_CNTL_ENIMP_B__SHIFT         0x0000001f
+
+// MC_CHP_IO_CNTL_A1
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWN_CKA_MASK              0x00000001L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWN_CKA                   0x00000001L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWN_AA_MASK               0x00000002L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWN_AA                    0x00000002L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWN_DQMA_MASK             0x00000004L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWN_DQMA                  0x00000004L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWN_DQSA_MASK             0x00000008L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWN_DQSA                  0x00000008L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWP_CKA_MASK              0x00000010L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWP_CKA                   0x00000010L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWP_AA_MASK               0x00000020L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWP_AA                    0x00000020L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWP_DQMA_MASK             0x00000040L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWP_DQMA                  0x00000040L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWP_DQSA_MASK             0x00000080L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWP_DQSA                  0x00000080L
+#define MC_CHP_IO_CNTL_A1__MEM_PREAMP_AA_MASK              0x00000100L
+#define MC_CHP_IO_CNTL_A1__MEM_PREAMP_AA                   0x00000100L
+#define MC_CHP_IO_CNTL_A1__MEM_PREAMP_DQMA_MASK            0x00000200L
+#define MC_CHP_IO_CNTL_A1__MEM_PREAMP_DQMA                 0x00000200L
+#define MC_CHP_IO_CNTL_A1__MEM_PREAMP_DQSA_MASK            0x00000400L
+#define MC_CHP_IO_CNTL_A1__MEM_PREAMP_DQSA                 0x00000400L
+#define MC_CHP_IO_CNTL_A1__MEM_IO_MODEA_MASK               0x00003000L
+#define MC_CHP_IO_CNTL_A1__MEM_REC_CKA_MASK                0x0000c000L
+#define MC_CHP_IO_CNTL_A1__MEM_REC_AA_MASK                 0x00030000L
+#define MC_CHP_IO_CNTL_A1__MEM_REC_DQMA_MASK               0x000c0000L
+#define MC_CHP_IO_CNTL_A1__MEM_REC_DQSA_MASK               0x00300000L
+#define MC_CHP_IO_CNTL_A1__MEM_SYNC_PHASEA_MASK            0x00400000L
+#define MC_CHP_IO_CNTL_A1__MEM_SYNC_PHASEA                 0x00400000L
+#define MC_CHP_IO_CNTL_A1__MEM_SYNC_CENTERA_MASK           0x00800000L
+#define MC_CHP_IO_CNTL_A1__MEM_SYNC_CENTERA                0x00800000L
+#define MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA_MASK               0x03000000L
+#define MC_CHP_IO_CNTL_A1__MEM_CLK_SELA_MASK               0x0c000000L
+#define MC_CHP_IO_CNTL_A1__MEM_CLK_INVA_MASK               0x10000000L
+#define MC_CHP_IO_CNTL_A1__MEM_CLK_INVA                    0x10000000L
+#define MC_CHP_IO_CNTL_A1__MEM_DATA_ENIMP_A_MASK           0x40000000L
+#define MC_CHP_IO_CNTL_A1__MEM_DATA_ENIMP_A                0x40000000L
+#define MC_CHP_IO_CNTL_A1__MEM_CNTL_ENIMP_A_MASK           0x80000000L
+#define MC_CHP_IO_CNTL_A1__MEM_CNTL_ENIMP_A                0x80000000L
+
+// MC_CHP_IO_CNTL_B1
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWN_CKB_MASK              0x00000001L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWN_CKB                   0x00000001L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWN_AB_MASK               0x00000002L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWN_AB                    0x00000002L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWN_DQMB_MASK             0x00000004L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWN_DQMB                  0x00000004L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWN_DQSB_MASK             0x00000008L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWN_DQSB                  0x00000008L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWP_CKB_MASK              0x00000010L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWP_CKB                   0x00000010L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWP_AB_MASK               0x00000020L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWP_AB                    0x00000020L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWP_DQMB_MASK             0x00000040L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWP_DQMB                  0x00000040L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWP_DQSB_MASK             0x00000080L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWP_DQSB                  0x00000080L
+#define MC_CHP_IO_CNTL_B1__MEM_PREAMP_AB_MASK              0x00000100L
+#define MC_CHP_IO_CNTL_B1__MEM_PREAMP_AB                   0x00000100L
+#define MC_CHP_IO_CNTL_B1__MEM_PREAMP_DQMB_MASK            0x00000200L
+#define MC_CHP_IO_CNTL_B1__MEM_PREAMP_DQMB                 0x00000200L
+#define MC_CHP_IO_CNTL_B1__MEM_PREAMP_DQSB_MASK            0x00000400L
+#define MC_CHP_IO_CNTL_B1__MEM_PREAMP_DQSB                 0x00000400L
+#define MC_CHP_IO_CNTL_B1__MEM_IO_MODEB_MASK               0x00003000L
+#define MC_CHP_IO_CNTL_B1__MEM_REC_CKB_MASK                0x0000c000L
+#define MC_CHP_IO_CNTL_B1__MEM_REC_AB_MASK                 0x00030000L
+#define MC_CHP_IO_CNTL_B1__MEM_REC_DQMB_MASK               0x000c0000L
+#define MC_CHP_IO_CNTL_B1__MEM_REC_DQSB_MASK               0x00300000L
+#define MC_CHP_IO_CNTL_B1__MEM_SYNC_PHASEB_MASK            0x00400000L
+#define MC_CHP_IO_CNTL_B1__MEM_SYNC_PHASEB                 0x00400000L
+#define MC_CHP_IO_CNTL_B1__MEM_SYNC_CENTERB_MASK           0x00800000L
+#define MC_CHP_IO_CNTL_B1__MEM_SYNC_CENTERB                0x00800000L
+#define MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB_MASK               0x03000000L
+#define MC_CHP_IO_CNTL_B1__MEM_CLK_SELB_MASK               0x0c000000L
+#define MC_CHP_IO_CNTL_B1__MEM_CLK_INVB_MASK               0x10000000L
+#define MC_CHP_IO_CNTL_B1__MEM_CLK_INVB                    0x10000000L
+#define MC_CHP_IO_CNTL_B1__MEM_DATA_ENIMP_B_MASK           0x40000000L
+#define MC_CHP_IO_CNTL_B1__MEM_DATA_ENIMP_B                0x40000000L
+#define MC_CHP_IO_CNTL_B1__MEM_CNTL_ENIMP_B_MASK           0x80000000L
+#define MC_CHP_IO_CNTL_B1__MEM_CNTL_ENIMP_B                0x80000000L
+
+// MEM_SDRAM_MODE_REG
+#define MEM_SDRAM_MODE_REG__MEM_MODE_REG_MASK              0x00007fffL
+#define MEM_SDRAM_MODE_REG__MEM_WR_LATENCY_MASK            0x000f0000L
+#define MEM_SDRAM_MODE_REG__MEM_CAS_LATENCY_MASK           0x00700000L
+#define MEM_SDRAM_MODE_REG__MEM_CMD_LATENCY_MASK           0x00800000L
+#define MEM_SDRAM_MODE_REG__MEM_CMD_LATENCY                0x00800000L
+#define MEM_SDRAM_MODE_REG__MEM_STR_LATENCY_MASK           0x01000000L
+#define MEM_SDRAM_MODE_REG__MEM_STR_LATENCY                0x01000000L
+#define MEM_SDRAM_MODE_REG__MEM_FALL_OUT_CMD_MASK          0x02000000L
+#define MEM_SDRAM_MODE_REG__MEM_FALL_OUT_CMD               0x02000000L
+#define MEM_SDRAM_MODE_REG__MEM_FALL_OUT_DATA_MASK         0x04000000L
+#define MEM_SDRAM_MODE_REG__MEM_FALL_OUT_DATA              0x04000000L
+#define MEM_SDRAM_MODE_REG__MEM_FALL_OUT_STR_MASK          0x08000000L
+#define MEM_SDRAM_MODE_REG__MEM_FALL_OUT_STR               0x08000000L
+#define MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE_MASK          0x10000000L
+#define MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE               0x10000000L
+#define MEM_SDRAM_MODE_REG__MEM_DDR_DLL_MASK               0x20000000L
+#define MEM_SDRAM_MODE_REG__MEM_DDR_DLL                    0x20000000L
+#define MEM_SDRAM_MODE_REG__MEM_CFG_TYPE_MASK              0x40000000L
+#define MEM_SDRAM_MODE_REG__MEM_CFG_TYPE                   0x40000000L
+#define MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET_MASK           0x80000000L
+#define MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET                0x80000000L
+
+// MEM_SDRAM_MODE_REG
+#define	MEM_SDRAM_MODE_REG__MEM_MODE_REG__SHIFT            0x00000000
+#define	MEM_SDRAM_MODE_REG__MEM_WR_LATENCY__SHIFT          0x00000010
+#define	MEM_SDRAM_MODE_REG__MEM_CAS_LATENCY__SHIFT         0x00000014
+#define	MEM_SDRAM_MODE_REG__MEM_CMD_LATENCY__SHIFT         0x00000017
+#define	MEM_SDRAM_MODE_REG__MEM_STR_LATENCY__SHIFT         0x00000018
+#define	MEM_SDRAM_MODE_REG__MEM_FALL_OUT_CMD__SHIFT        0x00000019
+#define	MEM_SDRAM_MODE_REG__MEM_FALL_OUT_DATA__SHIFT       0x0000001a
+#define	MEM_SDRAM_MODE_REG__MEM_FALL_OUT_STR__SHIFT        0x0000001b
+#define	MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE__SHIFT        0x0000001c
+#define	MEM_SDRAM_MODE_REG__MEM_DDR_DLL__SHIFT             0x0000001d
+#define	MEM_SDRAM_MODE_REG__MEM_CFG_TYPE__SHIFT            0x0000001e
+#define	MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET__SHIFT         0x0000001f
+
+// MEM_REFRESH_CNTL
+#define MEM_REFRESH_CNTL__MEM_REFRESH_RATE_MASK            0x000000ffL
+#define MEM_REFRESH_CNTL__MEM_REFRESH_DIS_MASK             0x00000100L
+#define MEM_REFRESH_CNTL__MEM_REFRESH_DIS                  0x00000100L
+#define MEM_REFRESH_CNTL__MEM_DYNAMIC_CKE_MASK             0x00000200L
+#define MEM_REFRESH_CNTL__MEM_DYNAMIC_CKE                  0x00000200L
+#define MEM_REFRESH_CNTL__MEM_TRFC_MASK                    0x0000f000L
+#define MEM_REFRESH_CNTL__MEM_CLKA0_ENABLE_MASK            0x00010000L
+#define MEM_REFRESH_CNTL__MEM_CLKA0_ENABLE                 0x00010000L
+#define MEM_REFRESH_CNTL__MEM_CLKA0b_ENABLE_MASK           0x00020000L
+#define MEM_REFRESH_CNTL__MEM_CLKA0b_ENABLE                0x00020000L
+#define MEM_REFRESH_CNTL__MEM_CLKA1_ENABLE_MASK            0x00040000L
+#define MEM_REFRESH_CNTL__MEM_CLKA1_ENABLE                 0x00040000L
+#define MEM_REFRESH_CNTL__MEM_CLKA1b_ENABLE_MASK           0x00080000L
+#define MEM_REFRESH_CNTL__MEM_CLKA1b_ENABLE                0x00080000L
+#define MEM_REFRESH_CNTL__MEM_CLKAFB_ENABLE_MASK           0x00100000L
+#define MEM_REFRESH_CNTL__MEM_CLKAFB_ENABLE                0x00100000L
+#define MEM_REFRESH_CNTL__DLL_FB_SLCT_CKA_MASK             0x00c00000L
+#define MEM_REFRESH_CNTL__MEM_CLKB0_ENABLE_MASK            0x01000000L
+#define MEM_REFRESH_CNTL__MEM_CLKB0_ENABLE                 0x01000000L
+#define MEM_REFRESH_CNTL__MEM_CLKB0b_ENABLE_MASK           0x02000000L
+#define MEM_REFRESH_CNTL__MEM_CLKB0b_ENABLE                0x02000000L
+#define MEM_REFRESH_CNTL__MEM_CLKB1_ENABLE_MASK            0x04000000L
+#define MEM_REFRESH_CNTL__MEM_CLKB1_ENABLE                 0x04000000L
+#define MEM_REFRESH_CNTL__MEM_CLKB1b_ENABLE_MASK           0x08000000L
+#define MEM_REFRESH_CNTL__MEM_CLKB1b_ENABLE                0x08000000L
+#define MEM_REFRESH_CNTL__MEM_CLKBFB_ENABLE_MASK           0x10000000L
+#define MEM_REFRESH_CNTL__MEM_CLKBFB_ENABLE                0x10000000L
+#define MEM_REFRESH_CNTL__DLL_FB_SLCT_CKB_MASK             0xc0000000L
+
+// MC_STATUS
+#define MC_STATUS__MEM_PWRUP_COMPL_A_MASK                  0x00000001L
+#define MC_STATUS__MEM_PWRUP_COMPL_A                       0x00000001L
+#define MC_STATUS__MEM_PWRUP_COMPL_B_MASK                  0x00000002L
+#define MC_STATUS__MEM_PWRUP_COMPL_B                       0x00000002L
+#define MC_STATUS__MC_IDLE_MASK                            0x00000004L
+#define MC_STATUS__MC_IDLE                                 0x00000004L
+#define MC_STATUS__IMP_N_VALUE_R_BACK_MASK                 0x00000078L
+#define MC_STATUS__IMP_P_VALUE_R_BACK_MASK                 0x00000780L
+#define MC_STATUS__TEST_OUT_R_BACK_MASK                    0x00000800L
+#define MC_STATUS__TEST_OUT_R_BACK                         0x00000800L
+#define MC_STATUS__DUMMY_OUT_R_BACK_MASK                   0x00001000L
+#define MC_STATUS__DUMMY_OUT_R_BACK                        0x00001000L
+#define MC_STATUS__IMP_N_VALUE_A_R_BACK_MASK               0x0001e000L
+#define MC_STATUS__IMP_P_VALUE_A_R_BACK_MASK               0x001e0000L
+#define MC_STATUS__IMP_N_VALUE_CK_R_BACK_MASK              0x01e00000L
+#define MC_STATUS__IMP_P_VALUE_CK_R_BACK_MASK              0x1e000000L
+
+// MDLL_CKO
+#define MDLL_CKO__MCKOA_SLEEP_MASK                         0x00000001L
+#define MDLL_CKO__MCKOA_SLEEP                              0x00000001L
+#define MDLL_CKO__MCKOA_RESET_MASK                         0x00000002L
+#define MDLL_CKO__MCKOA_RESET                              0x00000002L
+#define MDLL_CKO__MCKOA_RANGE_MASK                         0x0000000cL
+#define MDLL_CKO__ERSTA_SOUTSEL_MASK                       0x00000030L
+#define MDLL_CKO__MCKOA_FB_SEL_MASK                        0x000000c0L
+#define MDLL_CKO__MCKOA_REF_SKEW_MASK                      0x00000700L
+#define MDLL_CKO__MCKOA_FB_SKEW_MASK                       0x00007000L
+#define MDLL_CKO__MCKOA_BP_SEL_MASK                        0x00008000L
+#define MDLL_CKO__MCKOA_BP_SEL                             0x00008000L
+#define MDLL_CKO__MCKOB_SLEEP_MASK                         0x00010000L
+#define MDLL_CKO__MCKOB_SLEEP                              0x00010000L
+#define MDLL_CKO__MCKOB_RESET_MASK                         0x00020000L
+#define MDLL_CKO__MCKOB_RESET                              0x00020000L
+#define MDLL_CKO__MCKOB_RANGE_MASK                         0x000c0000L
+#define MDLL_CKO__ERSTB_SOUTSEL_MASK                       0x00300000L
+#define MDLL_CKO__MCKOB_FB_SEL_MASK                        0x00c00000L
+#define MDLL_CKO__MCKOB_REF_SKEW_MASK                      0x07000000L
+#define MDLL_CKO__MCKOB_FB_SKEW_MASK                       0x70000000L
+#define MDLL_CKO__MCKOB_BP_SEL_MASK                        0x80000000L
+#define MDLL_CKO__MCKOB_BP_SEL                             0x80000000L
+
+// MDLL_RDCKA
+#define MDLL_RDCKA__MRDCKA0_SLEEP_MASK                     0x00000001L
+#define MDLL_RDCKA__MRDCKA0_SLEEP                          0x00000001L
+#define MDLL_RDCKA__MRDCKA0_RESET_MASK                     0x00000002L
+#define MDLL_RDCKA__MRDCKA0_RESET                          0x00000002L
+#define MDLL_RDCKA__MRDCKA0_RANGE_MASK                     0x0000000cL
+#define MDLL_RDCKA__MRDCKA0_REF_SEL_MASK                   0x00000030L
+#define MDLL_RDCKA__MRDCKA0_FB_SEL_MASK                    0x000000c0L
+#define MDLL_RDCKA__MRDCKA0_REF_SKEW_MASK                  0x00000700L
+#define MDLL_RDCKA__MRDCKA0_SINSEL_MASK                    0x00000800L
+#define MDLL_RDCKA__MRDCKA0_SINSEL                         0x00000800L
+#define MDLL_RDCKA__MRDCKA0_FB_SKEW_MASK                   0x00007000L
+#define MDLL_RDCKA__MRDCKA0_BP_SEL_MASK                    0x00008000L
+#define MDLL_RDCKA__MRDCKA0_BP_SEL                         0x00008000L
+#define MDLL_RDCKA__MRDCKA1_SLEEP_MASK                     0x00010000L
+#define MDLL_RDCKA__MRDCKA1_SLEEP                          0x00010000L
+#define MDLL_RDCKA__MRDCKA1_RESET_MASK                     0x00020000L
+#define MDLL_RDCKA__MRDCKA1_RESET                          0x00020000L
+#define MDLL_RDCKA__MRDCKA1_RANGE_MASK                     0x000c0000L
+#define MDLL_RDCKA__MRDCKA1_REF_SEL_MASK                   0x00300000L
+#define MDLL_RDCKA__MRDCKA1_FB_SEL_MASK                    0x00c00000L
+#define MDLL_RDCKA__MRDCKA1_REF_SKEW_MASK                  0x07000000L
+#define MDLL_RDCKA__MRDCKA1_SINSEL_MASK                    0x08000000L
+#define MDLL_RDCKA__MRDCKA1_SINSEL                         0x08000000L
+#define MDLL_RDCKA__MRDCKA1_FB_SKEW_MASK                   0x70000000L
+#define MDLL_RDCKA__MRDCKA1_BP_SEL_MASK                    0x80000000L
+#define MDLL_RDCKA__MRDCKA1_BP_SEL                         0x80000000L
+
+// MDLL_RDCKB
+#define MDLL_RDCKB__MRDCKB0_SLEEP_MASK                     0x00000001L
+#define MDLL_RDCKB__MRDCKB0_SLEEP                          0x00000001L
+#define MDLL_RDCKB__MRDCKB0_RESET_MASK                     0x00000002L
+#define MDLL_RDCKB__MRDCKB0_RESET                          0x00000002L
+#define MDLL_RDCKB__MRDCKB0_RANGE_MASK                     0x0000000cL
+#define MDLL_RDCKB__MRDCKB0_REF_SEL_MASK                   0x00000030L
+#define MDLL_RDCKB__MRDCKB0_FB_SEL_MASK                    0x000000c0L
+#define MDLL_RDCKB__MRDCKB0_REF_SKEW_MASK                  0x00000700L
+#define MDLL_RDCKB__MRDCKB0_SINSEL_MASK                    0x00000800L
+#define MDLL_RDCKB__MRDCKB0_SINSEL                         0x00000800L
+#define MDLL_RDCKB__MRDCKB0_FB_SKEW_MASK                   0x00007000L
+#define MDLL_RDCKB__MRDCKB0_BP_SEL_MASK                    0x00008000L
+#define MDLL_RDCKB__MRDCKB0_BP_SEL                         0x00008000L
+#define MDLL_RDCKB__MRDCKB1_SLEEP_MASK                     0x00010000L
+#define MDLL_RDCKB__MRDCKB1_SLEEP                          0x00010000L
+#define MDLL_RDCKB__MRDCKB1_RESET_MASK                     0x00020000L
+#define MDLL_RDCKB__MRDCKB1_RESET                          0x00020000L
+#define MDLL_RDCKB__MRDCKB1_RANGE_MASK                     0x000c0000L
+#define MDLL_RDCKB__MRDCKB1_REF_SEL_MASK                   0x00300000L
+#define MDLL_RDCKB__MRDCKB1_FB_SEL_MASK                    0x00c00000L
+#define MDLL_RDCKB__MRDCKB1_REF_SKEW_MASK                  0x07000000L
+#define MDLL_RDCKB__MRDCKB1_SINSEL_MASK                    0x08000000L
+#define MDLL_RDCKB__MRDCKB1_SINSEL                         0x08000000L
+#define MDLL_RDCKB__MRDCKB1_FB_SKEW_MASK                   0x70000000L
+#define MDLL_RDCKB__MRDCKB1_BP_SEL_MASK                    0x80000000L
+#define MDLL_RDCKB__MRDCKB1_BP_SEL                         0x80000000L
+
+#define pllVCLK_ECP_CNTL                            0x0008
+#define pllDISP_TEST_MACRO_RW_WRITE                 0x001A
+#define pllDISP_TEST_MACRO_RW_READ                  0x001B
+#define pllDISP_TEST_MACRO_RW_DATA                  0x001C
+#define pllDISP_TEST_MACRO_RW_CNTL                  0x001D
+#define pllPIXCLKS_CNTL                             0x002D
+#define pllPPLL_DIV_0                               0x0004
+#define pllPPLL_DIV_1                               0x0005
+#define pllPPLL_DIV_2                               0x0006
+#define pllPPLL_DIV_3                               0x0007
+#define pllHTOTAL_CNTL                              0x0009
+#define pllPLL_TEST_CNTL_M6                         0x0013
+#define pllP2PLL_DIV_0                              0x002C
+#define pllHTOTAL2_CNTL                             0x002E
+#define pllCLK_PIN_CNTL                             0x0001
+#define pllPPLL_CNTL                                0x0002
+#define pllPPLL_REF_DIV                             0x0003
+#define pllSPLL_CNTL                                0x000C
+#define pllSPLL_AUX_CNTL                            0x0024
+#define pllSCLK_CNTL_M6                             0x000D
+#define pllAGP_PLL_CNTL                             0x000B
+#define pllTV_PLL_FINE_CNTL                         0x0020
+#define pllTV_PLL_CNTL                              0x0021
+#define pllTV_PLL_CNTL1                             0x0022
+#define pllTV_DTO_INCREMENTS                        0x0023
+#define pllP2PLL_CNTL                               0x002A
+#define pllP2PLL_REF_DIV                            0x002B
+#define pllSSPLL_CNTL                               0x0030
+#define pllSSPLL_REF_DIV                            0x0031
+#define pllSSPLL_DIV_0                              0x0032
+#define pllSS_INT_CNTL                              0x0033
+#define pllSS_TST_CNTL                              0x0034
+#define pllSCLK_MORE_CNTL                           0x0035
+#define pllCLK_PWRMGT_CNTL_M6                       0x0014
+#define pllPLL_PWRMGT_CNTL                          0x0015
+#define pllM_SPLL_REF_FB_DIV                        0x000A
+#define pllMPLL_CNTL                                0x000E
+#define pllMPLL_AUX_CNTL                            0x0025
+#define pllMDLL_CKO                                 0x000F
+#define pllMDLL_RDCKA                               0x0010
+#define pllMDLL_RDCKB                               0x0011
+#define pllMCLK_CNTL_M6                             0x0012
+#define pllMCLK_MISC                                0x001F
+#define pllCG_TEST_MACRO_RW_WRITE                   0x0016
+#define pllCG_TEST_MACRO_RW_READ                    0x0017
+#define pllCG_TEST_MACRO_RW_DATA                    0x0018
+#define pllCG_TEST_MACRO_RW_CNTL                    0x0019
+
+#define ixMC_PERF_CNTL                             0x0000
+#define ixMC_PERF_SEL                              0x0001
+#define ixMC_PERF_REGION_0                         0x0002
+#define ixMC_PERF_REGION_1                         0x0003
+#define ixMC_PERF_COUNT_0                          0x0004
+#define ixMC_PERF_COUNT_1                          0x0005
+#define ixMC_PERF_COUNT_2                          0x0006
+#define ixMC_PERF_COUNT_3                          0x0007
+#define ixMC_PERF_COUNT_MEMCH_A                    0x0008
+#define ixMC_PERF_COUNT_MEMCH_B                    0x0009
+#define ixMC_IMP_CNTL                              0x000A
+#define ixMC_CHP_IO_CNTL_A0                        0x000B
+#define ixMC_CHP_IO_CNTL_A1                        0x000C
+#define ixMC_CHP_IO_CNTL_B0                        0x000D
+#define ixMC_CHP_IO_CNTL_B1                        0x000E
+#define ixMC_IMP_CNTL_0                            0x000F
+#define ixTC_MISMATCH_1                            0x0010
+#define ixTC_MISMATCH_2                            0x0011
+#define ixMC_BIST_CTRL                             0x0012
+#define ixREG_COLLAR_WRITE                         0x0013
+#define ixREG_COLLAR_READ                          0x0014
+
+
+
+
 #endif	/* _RADEON_H */
 
diff -urN linux-2.4.21-bk7/drivers/video/radeonfb.c linux-2.4.21-bk8/drivers/video/radeonfb.c
--- linux-2.4.21-bk7/drivers/video/radeonfb.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.21-bk8/drivers/video/radeonfb.c	2003-07-12 02:52:26.000000000 -0700
@@ -2,7 +2,7 @@
  *	drivers/video/radeonfb.c
  *	framebuffer driver for ATI Radeon chipset video boards
  *
- *	Copyright 2000	Ani Joshi <ajoshi@unixbox.com>
+ *	Copyright 2000	Ani Joshi <ajoshi@kernel.crashing.org>
  *
  *
  *	ChangeLog:
@@ -19,13 +19,94 @@
  *	2001-11-18	DFP fixes, Kevin Hendricks, 0.1.3
  *	2001-11-29	more cmap, backlight fixes, Benjamin Herrenschmidt
  *	2002-01-18	DFP panel detection via BIOS, Michael Clark, 0.1.4
+ *	2002-06-02	console switching, mode set fixes, accel fixes
+ *	2002-06-03	MTRR support, Peter Horton, 0.1.5
+ *	2002-09-21	rv250, r300, m9 initial support,
+ *			added mirror option, 0.1.6
+ *	2003-04-10	accel engine fixes, 0.1.7
+ *	2003-04-12	Mac PowerBook sleep fixes, Benjamin Herrenschmidt,
+ *			0.1.8
  *
- *	Special thanks to ATI DevRel team for their hardware donations.
+ * Other change (--BenH)
+ * 
+ * 	2003-01-01	- Tweaks for PLL on some iBooks
+ * 			- Fix SURFACE_CNTL usage on r9000	
+ *      2003-03-23	- Added new Power Management code from ATI
+ *      		- Added default PLL values for r300 from lkml
+ *      		- Fix mirror ioctl result code (that ioctl still need some
+ *      		  rework to actually use the second head)
+ *      2003-03-26	- Never set TMDS_PLL_EN, it seem to break more than
+ *                        just old r300's
+ *      2003-04-02	- Got final word from ATI, TMDS_PLL_EN has to be flipped
+ *      		  depending if we are dealing with an "RV" card or not
+ *      		- Comsetic changes to sleep code, make it a bit more robust
+ *      		  hopefully
+ *      		- Fix 800x600-8 mode accel (Daniel Mantione)
+ *      		- Fix scaling on LCDs (not yet preserving aspect ratio though)
+ *      		- Properly set scroll mode to SCROLL_YREDRAW when accel
+ *      		  is disabled from fbset
+ *      		- Add some more radeon PCI IDs & default PLL values
+ *      2003-04-05	- Update the code that retreive the panel infos from the
+ *                        BIOS to match what XFree is doing
+ *                      - Avoid a divide by 0 when failing to retreive those infos
+ *      2003-04-07	- Fix the M6 video RAM workaround
+ *      		- Some bits in the PM code were flipped, fix that.
+ *      		- RB2D_DSTCACHE_MODE shouldn't be cleared on r300 (and
+ *      		  maybe not on others according to a comment in XFree, but
+ *      		  we keep working code for now).
+ *      		- Use ROP3_S for rectangle fill
+ *      2003-04-10      - Re-change the pitch workaround. We now align the pitch
+ *      		  when accel is enabled for a given mode, and we don't when
+ *      		  accel is disabled. That should properly deal with all cases
+ *      		  and allows us to remove the "special case" accel code
+ *      		- Bring in XFree workaround to not write the same value to
+ *      		  the PLL (can cause blanking of some panels)
+ *      		- Bring in some of Peter Horton fixes (accel reset, cleanups)
+ *      		  still some more to get in though...
+ *      		- Back to use of ROP3_P for rectangle fill (hrm...)
+ *      2003-04-11	- Properly reset accel engine on each console switch so
+ *      		  we work around switching from XFree leaving it in a weird
+ *      		  state. Also extend the comparison of values causing us to
+ *      		  reload the mode on console switch.
+ *      2003-04-30	- For BIOS returned LCD infos, assume high sync polarity
+ *      2003-07-08	- Fix an oops during boot related to disp not beeing initialized
+ *      		  when modedb called us back for set_var. Remove bogus refs to
+ *      		  RADEON_PM chip, this is really a mach64 chip, not a Radeon.
+ *      		  Add some DFP blanking support
+ *      2003-07-11	- Merged with Ani's 0.1.8 version
+ *      
+ *	Special thanks to ATI DevRel team for their hardware donations,
+ *	and for spending the time to fix the power management code !
+ *	
+ *	Note: This driver in in bad need of beeing completely re-organized.
+ *	      My long term plans, if I ever get enough time for that, is
+ *	      to split the actual mode setting code so it can properly 
+ *	      work on any head, the probe code, which will be stuffed with
+ *	      OF parsing on PPC and i2c fallback (look at what XFree does)
+ *	      and the PM code ought to be in a separate file. --BenH.
  *
+ *
+ *      Known Bugs:
+ *      
+ *       - Incompatible with ATI FireGL drivers. They are playing with things
+ *         like MC_FB_LOCATION behind our back. Not much we can do. This is
+ *         becoming a real problem as DRI is also playing with those and the
+ *         GATOS CVS as well in a different way.
+ *         We should really define _once for all_ the way we want those setup
+ *         and do it the same way everywhere or we won't be able to keep
+ *         compatibility with radeonfb.
+ *         IMHO, the proper setup is what radeon_fixup_apertures() does on
+ *         PPC when SET_MC_FB_FROM_APERTURE is defined (not the case currently
+ *         because of compatiblity problems with DRI). This is, I think, also
+ *         what GATOS does. We shall ask ATI what they do in the FireGL drivers
+ *       - We don't preserve aspect ratio on scaled modes on LCDs yet
+ *       - The way we retreive the BIOS informations probably doesn't work with
+ *         anything but the primary card since we need a "live" BIOS image in
+ *         memory to find the tables configured by the BIOS during POST stage.
  */
 
 
-#define RADEON_VERSION	"0.1.4"
+#define RADEON_VERSION	"0.1.8-ben"
 
 
 #include <linux/config.h>
@@ -39,6 +120,7 @@
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/console.h>
+#include <linux/vt_kern.h>
 #include <linux/selection.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
@@ -46,7 +128,8 @@
 #include <linux/vmalloc.h>
 
 #include <asm/io.h>
-#if defined(__powerpc__)
+#include <asm/uaccess.h>
+#ifdef CONFIG_ALL_PPC
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <video/macmodes.h>
@@ -68,7 +151,11 @@
 #include <linux/pmu.h>
 #endif
 
-#endif /* __powerpc__ */
+#endif /* CONFIG_ALL_PPC */
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
 
 #include <video/fbcon.h> 
 #include <video/fbcon-cfb8.h>
@@ -78,6 +165,8 @@
 
 #include "radeon.h"
 
+#include <linux/radeonfb.h>
+
 
 #define DEBUG	0
 
@@ -90,18 +179,103 @@
 
 
 enum radeon_chips {
-	RADEON_QD,	/* Radeon R100 */
-	RADEON_QE,	/* Radeon R100 */
-	RADEON_QF,	/* Radeon R100 */
-	RADEON_QG,	/* Radeon R100 */
-	RADEON_QY,	/* Radeon RV100 (VE) */
-	RADEON_QZ,	/* Radeon RV100 (VE) */
-	RADEON_QL,	/* Radeon R200 (8500) */
-	RADEON_QW,	/* Radeon RV200 (7500) */
-	RADEON_LW,	/* Radeon Mobility M7 */
-	RADEON_LY,	/* Radeon Mobility M6 */
-	RADEON_LZ,	/* Radeon Mobility M6 */
-	RADEON_PM	/* Radeon Mobility P/M */
+	RADEON_QD,
+	RADEON_QE,
+	RADEON_QF,
+	RADEON_QG,
+	RADEON_QY,
+	RADEON_QZ,
+	RADEON_LW,
+	RADEON_LX,
+	RADEON_LY,
+	RADEON_LZ,
+	RADEON_QL,
+	RADEON_QN,
+	RADEON_QO,
+	RADEON_Ql,
+	RADEON_BB,
+	RADEON_QM,
+	RADEON_QW,
+	RADEON_QX,
+	RADEON_Id,
+	RADEON_Ie,
+	RADEON_If,
+	RADEON_Ig,
+	RADEON_Y_,
+	RADEON_Ld,
+	RADEON_Le,
+	RADEON_Lf,
+	RADEON_Lg,
+	RADEON_ND,
+	RADEON_NE,
+	RADEON_NF,
+	RADEON_NG,
+	RADEON_AE,
+	RADEON_AF,
+	RADEON_AD,
+	RADEON_NH,
+	RADEON_NI,
+	RADEON_AP,
+	RADEON_AR,
+};
+
+enum radeon_arch {
+	RADEON_R100,
+	RADEON_M6,
+	RADEON_RV100,
+	RADEON_R200,
+	RADEON_M7,
+	RADEON_RV200,
+	RADEON_M9,
+	RADEON_RV250,
+	RADEON_RV280,
+	RADEON_R300,
+	RADEON_R350,
+	RADEON_RV350,
+};
+
+static struct radeon_chip_info {
+	const char *name;
+	unsigned char arch;
+} radeon_chip_info[] __devinitdata = {
+	{ "QD", RADEON_R100 },
+	{ "QE", RADEON_R100 },
+	{ "QF", RADEON_R100 },
+	{ "QG", RADEON_R100 },
+	{ "VE QY", RADEON_RV100 },
+	{ "VE QZ", RADEON_RV100 },
+	{ "M7 LW", RADEON_M7 },
+	{ "M7 LX", RADEON_M7 },
+	{ "M6 LY", RADEON_M6 },
+	{ "M6 LZ", RADEON_M6 },
+	{ "8500 QL", RADEON_R200 },
+	{ "8500 QN", RADEON_R200 },
+	{ "8500 QO", RADEON_R200 },
+	{ "8500 Ql", RADEON_R200 },
+	{ "8500 BB", RADEON_R200 },
+	{ "9100 QM", RADEON_R200 },
+	{ "7500 QW", RADEON_RV200 },
+	{ "7500 QX", RADEON_RV200 },
+	{ "9000 Id", RADEON_RV250 },
+	{ "9000 Ie", RADEON_RV250 },
+	{ "9000 If", RADEON_RV250 },
+	{ "9000 Ig", RADEON_RV250 },
+	{ "9200 Y", RADEON_RV280 },
+	{ "M9 Ld", RADEON_M9 },
+	{ "M9 Le", RADEON_M9 },
+	{ "M9 Lf", RADEON_M9 },
+	{ "M9 Lg", RADEON_M9 },
+	{ "9700 ND", RADEON_R300 },
+	{ "9700 NE", RADEON_R300 },
+	{ "9700 NF", RADEON_R350 },
+	{ "9700 NG", RADEON_R350 },
+	{ "9700 AE", RADEON_R300 },
+	{ "9700 AF", RADEON_R300 },
+	{ "9500 AD", RADEON_R300 },
+	{ "9800 NH", RADEON_R350 },
+	{ "9800 NI", RADEON_R350 },
+	{ "9600 AP", RADEON_RV350 },
+	{ "9600 AR", RADEON_RV350 },
 };
 
 
@@ -117,18 +291,44 @@
 
 
 static struct pci_device_id radeonfb_pci_table[] __devinitdata = {
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QY},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QZ},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QL},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QW},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LW},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LY},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LZ},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_PM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_PM},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QY},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QZ},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LW},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LX},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LY},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LZ},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QL},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QN, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QN},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QO},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ql, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ql},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_BB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_BB},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QM},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QW},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QX},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Id},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ie, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ie},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_If, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_If},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ig, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ig},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ld, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ld},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Le, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Le},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lf},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lg, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lg},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_ND, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_ND},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NE},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NF},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NG},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AE},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AF},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NH, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NH},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NI, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NI},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Y_, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Y_},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AD},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AP},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AR},
 	{ 0, }
 };
 MODULE_DEVICE_TABLE(pci, radeonfb_pci_table);
@@ -155,7 +355,19 @@
 	{ CAP0_TRIG_CNTL, 0 },
 };
 
+reg_val common_regs_m6[] = {
+	{ OVR_CLR, 0 },
+	{ OVR_WID_LEFT_RIGHT, 0 },
+	{ OVR_WID_TOP_BOTTOM, 0 },
+	{ OV0_SCALE_CNTL, 0 },
+	{ SUBPIC_CNTL, 0 },
+	{ GEN_INT_CNTL, 0 },
+	{ CAP0_TRIG_CNTL, 0 }
+};
+
+
 #define COMMON_REGS_SIZE = (sizeof(common_regs)/sizeof(common_regs[0]))
+#define COMMON_REGS_M6_SIZE = (sizeof(common_regs)/sizeof(common_regs_m6[0]))
 
 typedef struct {
         u8 clock_chip_type;
@@ -214,6 +426,7 @@
 	u32 crtc_pitch;
 	u32 crtc_gen_cntl;
 	u32 crtc_ext_cntl;
+	u32 crtc_more_cntl;
 	u32 dac_cntl;
 
 	u32 flags;
@@ -242,9 +455,11 @@
 	u32 tmds_crc;
 	u32 tmds_transmitter_cntl;
 
-#if defined(__BIG_ENDIAN)
+	/* Dynamic clock control */
+	u32 vclk_ecp_cntl;
+
+	/* Endian control */
 	u32 surface_cntl;
-#endif
 };
 
 
@@ -254,15 +469,17 @@
 	struct radeon_regs state;
 	struct radeon_regs init_state;
 
-	char name[17];
+	char name[16];
 	char ram_type[12];
 
-	u32 mmio_base_phys;
-	u32 fb_base_phys;
+	unsigned long mmio_base_phys;
+	unsigned long fb_base_phys;
 
 	unsigned long mmio_base;
 	unsigned long fb_base;
 
+	unsigned long fb_local_base;
+
 	struct pci_dev *pdev;
 
 	unsigned char *EDID;
@@ -274,11 +491,13 @@
 
 	struct { u8 red, green, blue, pad; } palette[256];
 
-	int chipset;
+	short chipset;
+	unsigned char arch;
 	int video_ram;
 	u8 rev;
 	int pitch, bpp, depth;
 	int xres, yres, pixclock;
+	int xres_virtual, yres_virtual;
 
 	int use_default_var;
 	int got_dfpinfo;
@@ -301,8 +520,7 @@
 
 	struct ram_info ram;
 
-        u32 hack_crtc_ext_cntl;
-        u32 hack_crtc_v_sync_strt_wid;
+	int mtrr_hdl;
 
 #if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
         union {
@@ -319,10 +537,13 @@
 #endif  
 
 #ifdef CONFIG_PMAC_PBOOK
-	unsigned char *save_framebuffer;
 	int pm_reg;
+	u32 save_regs[64];
+	u32 mdll, mdll2;
 #endif
 
+	int asleep;
+
 	struct radeonfb_info *next;
 };
 
@@ -344,8 +565,12 @@
 #define INREG(addr)		readl((rinfo->mmio_base)+addr)
 #define OUTREG(addr,val)	writel(val, (rinfo->mmio_base)+addr)
 
-#define OUTPLL(addr,val)	OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000001f) | 0x00000080); \
-				OUTREG(CLOCK_CNTL_DATA, val)
+#define OUTPLL(addr,val)						\
+	do {								\
+		OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000003f) | 0x00000080); \
+		OUTREG(CLOCK_CNTL_DATA, val);				\
+	} while (0)							\
+
 #define OUTPLLP(addr,val,mask)  					\
 	do {								\
 		unsigned int _tmp = INPLL(addr);			\
@@ -363,9 +588,9 @@
 	} while (0)
 
 
-static __inline__ u32 _INPLL(struct radeonfb_info *rinfo, unsigned long addr)
+static __inline__ u32 _INPLL(struct radeonfb_info *rinfo, u32 addr)
 {
-	OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000001f);
+	OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f);
 	return (INREG(CLOCK_CNTL_DATA));
 }
 
@@ -487,9 +712,36 @@
 static void _radeon_engine_reset(struct radeonfb_info *rinfo)
 {
 	u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
+	u32 host_path_cntl;
 
 	radeon_engine_flush (rinfo);
 
+    	/* Some ASICs have bugs with dynamic-on feature, which are  
+     	 * ASIC-version dependent, so we force all blocks on for now
+     	 * -- from XFree86
+     	 * We don't do that on macs, things just work here with dynamic
+     	 * clocking... --BenH
+	 */
+#ifdef CONFIG_ALL_PPC
+	if (_machine != _MACH_Pmac && rinfo->hasCRTC2)
+#else
+	if (rinfo->hasCRTC2)
+#endif	
+	{
+		u32 tmp;
+
+		tmp = INPLL(SCLK_CNTL);
+		OUTPLL(SCLK_CNTL, ((tmp & ~DYN_STOP_LAT_MASK) |
+				   CP_MAX_DYN_STOP_LAT |
+				   SCLK_FORCEON_MASK));
+
+		if (rinfo->arch == RADEON_RV200)
+		{
+			tmp = INPLL(SCLK_MORE_CNTL);
+			OUTPLL(SCLK_MORE_CNTL, tmp | SCLK_MORE_FORCEON);
+		}
+	}
+
 	clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
 	mclk_cntl = INPLL(MCLK_CNTL);
 
@@ -500,32 +752,51 @@
 			   FORCEON_YCLKB |
 			   FORCEON_MC |
 			   FORCEON_AIC));
+
+	host_path_cntl = INREG(HOST_PATH_CNTL);
 	rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
 
-	OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset |
-				SOFT_RESET_CP |
-				SOFT_RESET_HI |
-				SOFT_RESET_SE |
-				SOFT_RESET_RE |
-				SOFT_RESET_PP |
-				SOFT_RESET_E2 |
-				SOFT_RESET_RB |
-				SOFT_RESET_HDP);
-	INREG(RBBM_SOFT_RESET);
-	OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32)
-				~(SOFT_RESET_CP |
-				  SOFT_RESET_HI |
-				  SOFT_RESET_SE |
-				  SOFT_RESET_RE |
-				  SOFT_RESET_PP |
-				  SOFT_RESET_E2 |
-				  SOFT_RESET_RB |
-				  SOFT_RESET_HDP));
-	INREG(RBBM_SOFT_RESET);
+	if (rinfo->arch == RADEON_R300) {
+		u32 tmp;
+
+		OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset |
+					 SOFT_RESET_CP |
+					 SOFT_RESET_HI |
+					 SOFT_RESET_E2));
+		INREG(RBBM_SOFT_RESET);
+		OUTREG(RBBM_SOFT_RESET, 0);
+		tmp = INREG(RB2D_DSTCACHE_MODE);
+		OUTREG(RB2D_DSTCACHE_MODE, tmp | (1 << 17)); /* FIXME */
+	} else {
+		OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset |
+					SOFT_RESET_CP |
+					SOFT_RESET_HI |
+					SOFT_RESET_SE |
+					SOFT_RESET_RE |
+					SOFT_RESET_PP |
+					SOFT_RESET_E2 |
+					SOFT_RESET_RB);
+		INREG(RBBM_SOFT_RESET);
+		OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32)
+					~(SOFT_RESET_CP |
+					  SOFT_RESET_HI |
+					  SOFT_RESET_SE |
+					  SOFT_RESET_RE |
+					  SOFT_RESET_PP |
+					  SOFT_RESET_E2 |
+					  SOFT_RESET_RB));
+		INREG(RBBM_SOFT_RESET);
+	}
+
+	OUTREG(HOST_PATH_CNTL, host_path_cntl | HDP_SOFT_RESET);
+	INREG(HOST_PATH_CNTL);
+	OUTREG(HOST_PATH_CNTL, host_path_cntl);
+
+	if (rinfo->arch != RADEON_R300)
+		OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
 
-	OUTPLL(MCLK_CNTL, mclk_cntl);
 	OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
-	OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
+	OUTPLL(MCLK_CNTL, mclk_cntl);
 
 	return;
 }
@@ -533,37 +804,11 @@
 #define radeon_engine_reset()		_radeon_engine_reset(rinfo)
 
 
-static __inline__ u8 radeon_get_post_div_bitval(int post_div)
-{
-        switch (post_div) {
-                case 1:
-                        return 0x00;
-                case 2: 
-                        return 0x01;
-                case 3: 
-                        return 0x04;
-                case 4:
-                        return 0x02;
-                case 6:
-                        return 0x06;
-                case 8:
-                        return 0x03;
-                case 12:
-                        return 0x07;
-                default:
-                        return 0x02;
-        }
-}
-
-
-
 static __inline__ int round_div(int num, int den)
 {
         return (num + (den / 2)) / den;
 }
 
-
-
 static __inline__ int min_bits_req(int val)
 {
         int bits_req = 0;
@@ -579,7 +824,6 @@
         return (bits_req);
 }
 
-
 static __inline__ int _max(int val1, int val2)
 {
         if (val1 >= val2)
@@ -596,15 +840,27 @@
         
 static char fontname[40] __initdata;
 static char *mode_option __initdata;
-static char noaccel __initdata = 0;
+static char noaccel = 0;
+static char mirror = 0;
 static int panel_yres __initdata = 0;
 static char force_dfp __initdata = 0;
+static char force_crt __initdata = 0;
+static char force_nolcd __initdata = 0;
 static struct radeonfb_info *board_list = NULL;
+static char nomtrr __initdata = 0;
 
 #ifdef FBCON_HAS_CFB8
 static struct display_switch fbcon_radeon8;
 #endif
 
+#ifdef FBCON_HAS_CFB16
+static struct display_switch fbcon_radeon16;
+#endif
+
+#ifdef FBCON_HAS_CFB32
+static struct display_switch fbcon_radeon32;
+#endif
+
 
 /*
  * prototypes
@@ -636,46 +892,39 @@
 static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp);
 static void radeon_save_state (struct radeonfb_info *rinfo,
                                struct radeon_regs *save);
-static void radeon_engine_init (struct radeonfb_info *rinfo);
+static int radeon_engine_init (struct radeonfb_info *rinfo);
 static void radeon_load_video_mode (struct radeonfb_info *rinfo,
                                     struct fb_var_screeninfo *mode);
 static void radeon_write_mode (struct radeonfb_info *rinfo,
                                struct radeon_regs *mode);
 static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo);
 static int __devinit radeon_init_disp (struct radeonfb_info *rinfo);
-static int radeon_init_disp_var (struct radeonfb_info *rinfo);
 static int radeonfb_pci_register (struct pci_dev *pdev,
                                  const struct pci_device_id *ent);
 static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev);
-static char *radeon_find_rom(struct radeonfb_info *rinfo);
-static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg);
-static void radeon_get_moninfo (struct radeonfb_info *rinfo);
-static int radeon_get_dfpinfo (struct radeonfb_info *rinfo);
-static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo);
-static void radeon_get_EDID(struct radeonfb_info *rinfo);
-static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo);
-static void radeon_update_default_var(struct radeonfb_info *rinfo);
-
-
-#ifdef CONFIG_ALL_PPC
-static int radeon_read_OF (struct radeonfb_info *rinfo);
-static int radeon_get_EDID_OF(struct radeonfb_info *rinfo);
-extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev);
 
 #ifdef CONFIG_PMAC_PBOOK
-int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when);
+static int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when);
 static struct pmu_sleep_notifier radeon_sleep_notifier = {
 	radeon_sleep_notify, SLEEP_LEVEL_VIDEO,
 };
+#endif /* CONFIG_PMAC_PBOOK */
+#ifdef CONFIG_PMAC_BACKLIGHT
 static int radeon_set_backlight_enable(int on, int level, void *data);
 static int radeon_set_backlight_level(int level, void *data);
 static struct backlight_controller radeon_backlight_controller = {
 	radeon_set_backlight_enable,
 	radeon_set_backlight_level
 };
-#endif /* CONFIG_PMAC_PBOOK */
-
-#endif /* CONFIG_ALL_PPC */
+static void OUTMC( struct radeonfb_info *rinfo, u8 indx, u32 value);
+static u32 INMC(struct radeonfb_info *rinfo, u8 indx);
+static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo);
+static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo);
+static void radeon_pm_yclk_mclk_sync(struct radeonfb_info *rinfo);
+static void radeon_pm_program_mode_reg(struct radeonfb_info *rinfo, u16 value, u8 delay_required);
+static void radeon_pm_enable_dll(struct radeonfb_info *rinfo);
+static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo);
+#endif /* CONFIG_PMAC_BACKLIGHT */
 
 static struct fb_ops radeon_fb_ops = {
 	fb_get_fix:		radeonfb_get_fix,
@@ -729,10 +978,20 @@
                         memcpy(fontname, this_opt + 5, i);
                 } else if (!strncmp(this_opt, "noaccel", 7)) {
 			noaccel = 1;
+                } else if (!strncmp(this_opt, "mirror", 6)) {
+			mirror = 1;
 		} else if (!strncmp(this_opt, "dfp", 3)) {
 			force_dfp = 1;
+			force_nolcd = 1;
+		} else if (!strncmp(this_opt, "crt", 3)) {
+			force_crt = 1;
+			force_nolcd = 1;
+		} else if (!strncmp(this_opt, "nolcd", 5)) {
+			force_nolcd = 1;
 		} else if (!strncmp(this_opt, "panel_yres:", 11)) {
 			panel_yres = simple_strtoul((this_opt+11), NULL, 0);
+		} else if (!strncmp(this_opt, "nomtrr", 6)) {
+			nomtrr = 1;
                 } else
 			mode_option = this_opt;
         }
@@ -750,500 +1009,185 @@
 MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");
 MODULE_LICENSE("GPL");
 
-static int radeonfb_pci_register (struct pci_dev *pdev,
-				  const struct pci_device_id *ent)
+MODULE_PARM(noaccel, "i");
+MODULE_PARM_DESC(noaccel, "Disable (1) or enable (0) the usage of the 2d accel engine");
+MODULE_PARM(force_dfp, "i");
+MODULE_PARM_DESC(force_dfp,"Force (1) the usage of a digital flat panel");
+MODULE_PARM(force_crt, "i");
+MODULE_PARM_DESC(force_crt,"Force (1) the usage of a CRT monitor");
+MODULE_PARM(force_nolcd, "i");
+MODULE_PARM_DESC(force_nolcd,"Avoid (1) the usage of a digital flat panel");
+
+static unsigned char *radeon_find_rom(struct radeonfb_info *rinfo)
+{       
+#if defined(__i386__)
+	/* I simplified this code as we used to miss the signatures in
+	 * a lot of case. It's now closer to XFree, we just don't check
+	 * for signatures at all... Something better will have to be done
+	 * later obviously
+	 */
+        u32  segstart;
+        unsigned char *rom_base;
+                                                
+        for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
+                rom_base = (char *)ioremap(segstart, 0x1000);
+                if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa))
+	                return rom_base;
+                iounmap(rom_base);
+        }
+#endif          
+        return NULL;
+}
+
+#ifdef CONFIG_ALL_PPC
+static int radeon_read_OF (struct radeonfb_info *rinfo)
 {
-	struct radeonfb_info *rinfo;
-	u32 tmp;
-	int i, j;
+	struct device_node *dp;
+	unsigned int *xtal;
 
-	RTRACE("radeonfb_pci_register BEGIN\n");
+	dp = pci_device_to_OF_node(rinfo->pdev);
+	if (dp == NULL)
+		return 0;
 
-	rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL);
-	if (!rinfo) {
-		printk ("radeonfb: could not allocate memory\n");
-		return -ENODEV;
-	}
+	xtal = (unsigned int *) get_property(dp, "ATY,RefCLK", 0);
+	if ((xtal == NULL) || (*xtal == 0))
+		return 0;
 
-	memset (rinfo, 0, sizeof (struct radeonfb_info));
+	rinfo->pll.ref_clk = *xtal / 10;
 
-	rinfo->pdev = pdev;
+	return 1;
+}
+#endif	
 
-	/* enable device */
-	{
-		int err;
+static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg)
+{
+        void *bios_header;
+        void *header_ptr;
+        u16 bios_header_offset, pll_info_offset;
+        PLL_BLOCK pll;
 
-		if ((err = pci_enable_device(pdev))) {
-			printk("radeonfb: cannot enable device\n");
-			kfree (rinfo);
-			return -ENODEV;
-		}
-	}
+	if (bios_seg) {
+	        bios_header = bios_seg + 0x48L;
+       		header_ptr  = bios_header;
+        
+        	bios_header_offset = readw(header_ptr);
+	        bios_header = bios_seg + bios_header_offset;
+        	bios_header += 0x30;
+        
+        	header_ptr = bios_header;
+        	pll_info_offset = readw(header_ptr);
+        	header_ptr = bios_seg + pll_info_offset;
+        
+        	memcpy_fromio(&pll, header_ptr, 50);
+        
+        	/* Consider ref clock to be sane between 1000 and 5000,
+        	 * just in case we tapped the wrong BIOS...
+        	 */
+		if (pll.PCLK_ref_freq < 1000 || pll.PCLK_ref_freq > 5000)
+			goto use_defaults;
 
-	/* set base addrs */
-	rinfo->fb_base_phys = pci_resource_start (pdev, 0);
-	rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
+        	rinfo->pll.xclk = (u32)pll.XCLK;
+        	rinfo->pll.ref_clk = (u32)pll.PCLK_ref_freq;
+        	rinfo->pll.ref_div = (u32)pll.PCLK_ref_divider;
+        	rinfo->pll.ppll_min = pll.PCLK_min_freq;
+        	rinfo->pll.ppll_max = pll.PCLK_max_freq;
 
-	/* request the mem regions */
-	if (!request_mem_region (rinfo->fb_base_phys,
-				 pci_resource_len(pdev, 0), "radeonfb")) {
-		printk ("radeonfb: cannot reserve FB region\n");
-		kfree (rinfo);
-		return -ENODEV;
-	}
+		printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from BIOS\n",
+			rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
+	} else {
+#ifdef CONFIG_ALL_PPC
+		if (radeon_read_OF(rinfo)) {
+			unsigned int tmp, Nx, M, ref_div, xclk;
 
-	if (!request_mem_region (rinfo->mmio_base_phys,
-				 pci_resource_len(pdev, 2), "radeonfb")) {
-		printk ("radeonfb: cannot reserve MMIO region\n");
-		release_mem_region (rinfo->fb_base_phys,
-				    pci_resource_len(pdev, 0));
-		kfree (rinfo);
-		return -ENODEV;
-	}
+			tmp = INPLL(M_SPLL_REF_FB_DIV);
+			ref_div = INPLL(PPLL_REF_DIV) & 0x3ff;
 
-	/* map the regions */
-	rinfo->mmio_base = (unsigned long)ioremap (rinfo->mmio_base_phys,
-				    		    RADEON_REGSIZE);
-	if (!rinfo->mmio_base) {
-		printk ("radeonfb: cannot map MMIO\n");
-		release_mem_region (rinfo->mmio_base_phys,
-				    pci_resource_len(pdev, 2));
-		release_mem_region (rinfo->fb_base_phys,
-				    pci_resource_len(pdev, 0));
-		kfree (rinfo);
-		return -ENODEV;
-	}
+			Nx = (tmp & 0xff00) >> 8;
+			M = (tmp & 0xff);
+			xclk = ((((2 * Nx * rinfo->pll.ref_clk) + (M)) /
+				(2 * M)));
 
-	rinfo->chipset = pdev->device;
+			rinfo->pll.xclk = xclk;
+			rinfo->pll.ref_div = ref_div;
+			rinfo->pll.ppll_min = 12000;
+			rinfo->pll.ppll_max = 35000;
 
-	/* chipset */
-	switch (pdev->device) {
-		case PCI_DEVICE_ID_RADEON_QD:
-			strcpy(rinfo->name, "Radeon QD ");
-			break;
-		case PCI_DEVICE_ID_RADEON_QE:
-			strcpy(rinfo->name, "Radeon QE ");
-			break;
-		case PCI_DEVICE_ID_RADEON_QF:
-			strcpy(rinfo->name, "Radeon QF ");
-			break;
-		case PCI_DEVICE_ID_RADEON_QG:
-			strcpy(rinfo->name, "Radeon QG ");
-			break;
-		case PCI_DEVICE_ID_RADEON_QY:
-			strcpy(rinfo->name, "Radeon QY VE ");
-			rinfo->hasCRTC2 = 1;
-			break;
-		case PCI_DEVICE_ID_RADEON_QZ:
-			strcpy(rinfo->name, "Radeon QZ VE ");
-			rinfo->hasCRTC2 = 1;
-			break;
-		case PCI_DEVICE_ID_RADEON_QW:
-			strcpy(rinfo->name, "Radeon 7500 QW ");
-			rinfo->hasCRTC2 = 1;
-			break;
-		case PCI_DEVICE_ID_RADEON_QL:
-			strcpy(rinfo->name, "Radeon 8500 QL ");
-			rinfo->hasCRTC2 = 1;
-			break;
-		case PCI_DEVICE_ID_RADEON_LW:
-			strcpy(rinfo->name, "Radeon M7 LW ");
-			rinfo->hasCRTC2 = 1;
-			break;
-		case PCI_DEVICE_ID_RADEON_LY:
-			strcpy(rinfo->name, "Radeon M6 LY ");
-			rinfo->hasCRTC2 = 1;
-			break;
-		case PCI_DEVICE_ID_RADEON_LZ:
-			strcpy(rinfo->name, "Radeon M6 LZ ");
-			rinfo->hasCRTC2 = 1;
-			break;
-	        case PCI_DEVICE_ID_RADEON_PM:
-			strcpy(rinfo->name, "Radeon P/M ");
-			rinfo->hasCRTC2 = 1;
-		default:
-			return -ENODEV;
+			printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from OF\n",
+				rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
+
+			return;
+		}
+#endif
+use_defaults:
+		/* No BIOS or BIOS not found, use defaults
+		 * 
+		 * NOTE: Those defaults settings are rather "randomly" picked from
+		 * informations we found so far, but we would really need some
+		 * better mecanism to get them. Recent XFree can +/- probe for
+		 * the proper clocks.
+		 */
+		switch (rinfo->arch) {
+			case RADEON_RV200:
+				rinfo->pll.ppll_max = 35000;
+				rinfo->pll.ppll_min = 12000;
+				rinfo->pll.xclk = 23000;
+				rinfo->pll.ref_div = 12;
+				rinfo->pll.ref_clk = 2700;
+				break;
+			case RADEON_R200:
+				rinfo->pll.ppll_max = 35000;
+				rinfo->pll.ppll_min = 12000;
+				rinfo->pll.xclk = 27500;
+				rinfo->pll.ref_div = 12;
+				rinfo->pll.ref_clk = 2700;
+				break;
+			case RADEON_RV250:
+				rinfo->pll.ppll_max = 35000;
+				rinfo->pll.ppll_min = 12000;
+				rinfo->pll.xclk = 25000;
+				rinfo->pll.ref_div = 12;
+				rinfo->pll.ref_clk = 2700;
+				break;
+			case RADEON_R300:
+				rinfo->pll.ppll_max = 40000;
+				rinfo->pll.ppll_min = 20000;
+				rinfo->pll.xclk = 27000;
+				rinfo->pll.ref_div = 12;
+				rinfo->pll.ref_clk = 2700;
+				break;
+			case RADEON_R100:
+			default:
+				rinfo->pll.ppll_max = 35000;
+				rinfo->pll.ppll_min = 12000;
+				rinfo->pll.xclk = 16600;
+				rinfo->pll.ref_div = 67;
+				rinfo->pll.ref_clk = 2700;
+				break;
+		}
+
+		printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d defaults\n",
+			rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
 	}
+}
 
-	/* framebuffer size */
-	tmp = INREG(CONFIG_MEMSIZE);
 
-	/* mem size is bits [28:0], mask off the rest */
-	rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
+static void radeon_get_moninfo (struct radeonfb_info *rinfo)
+{
+	u32 tmp = INREG(RADEON_BIOS_4_SCRATCH);
 
-	/* According to XFree86 4.2.0, some production M6's return 0
-	   for 8MB. */
-	if (rinfo->video_ram == 0 &&
-	    (pdev->device == PCI_DEVICE_ID_RADEON_LY ||
-	     pdev->device == PCI_DEVICE_ID_RADEON_LZ)) {
-	    rinfo->video_ram = 8192 * 1024;
-	  }
+	if (force_dfp) {
+		printk("radeonfb: forcing DFP\n");
+		rinfo->dviDisp_type = MT_DFP;
+		return;
+	} else if (force_crt) {
+		printk("radeonfb: forcing CRT\n");
+		rinfo->dviDisp_type = MT_NONE;
+		rinfo->crtDisp_type = MT_CRT;
+		return;
+	}
 
-	/* ram type */
-	tmp = INREG(MEM_SDRAM_MODE_REG);
-	switch ((MEM_CFG_TYPE & tmp) >> 30) {
-		case 0:
-			/* SDR SGRAM (2:1) */
-			strcpy(rinfo->ram_type, "SDR SGRAM");
-			rinfo->ram.ml = 4;
-			rinfo->ram.mb = 4;
-			rinfo->ram.trcd = 1;
-			rinfo->ram.trp = 2;
-			rinfo->ram.twr = 1;
-			rinfo->ram.cl = 2;
-			rinfo->ram.loop_latency = 16;
-			rinfo->ram.rloop = 16;
-	
-			break;
-		case 1:
-			/* DDR SGRAM */
-			strcpy(rinfo->ram_type, "DDR SGRAM");
-			rinfo->ram.ml = 4;
-			rinfo->ram.mb = 4;
-			rinfo->ram.trcd = 3;
-			rinfo->ram.trp = 3;
-			rinfo->ram.twr = 2;
-			rinfo->ram.cl = 3;
-			rinfo->ram.tr2w = 1;
-			rinfo->ram.loop_latency = 16;
-			rinfo->ram.rloop = 16;
-
-			break;
-		default:
-			/* 64-bit SDR SGRAM */
-			strcpy(rinfo->ram_type, "SDR SGRAM 64");
-			rinfo->ram.ml = 4;
-			rinfo->ram.mb = 8;
-			rinfo->ram.trcd = 3;
-			rinfo->ram.trp = 3;
-			rinfo->ram.twr = 1;
-			rinfo->ram.cl = 3;
-			rinfo->ram.tr2w = 1;
-			rinfo->ram.loop_latency = 17;
-			rinfo->ram.rloop = 17;
-
-			break;
-	}
-
-	rinfo->bios_seg = radeon_find_rom(rinfo);
-	radeon_get_pllinfo(rinfo, rinfo->bios_seg);
-
-	RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
-
-#if !defined(__powerpc__)
-	radeon_get_moninfo(rinfo);
-#else
-	switch (pdev->device) {
-		case PCI_DEVICE_ID_RADEON_LW:
-		case PCI_DEVICE_ID_RADEON_LY:
-		case PCI_DEVICE_ID_RADEON_LZ:
-		case PCI_DEVICE_ID_RADEON_PM:
-			rinfo->dviDisp_type = MT_LCD;
-			break;
-		default:
-			radeon_get_moninfo(rinfo);
-			break;
-	}
-#endif
-
-	radeon_get_EDID(rinfo);
 
-	if ((rinfo->dviDisp_type == MT_DFP) || (rinfo->dviDisp_type == MT_LCD) ||
-	    (rinfo->crtDisp_type == MT_DFP)) {
-		if (!radeon_get_dfpinfo(rinfo)) {
-			iounmap ((void*)rinfo->mmio_base);
-			release_mem_region (rinfo->mmio_base_phys,
-					    pci_resource_len(pdev, 2));
-			release_mem_region (rinfo->fb_base_phys,
-					    pci_resource_len(pdev, 0));
-			kfree (rinfo);
-			return -ENODEV;
-		}
-	}
-
-	rinfo->fb_base = (unsigned long) ioremap (rinfo->fb_base_phys,
-				  		  rinfo->video_ram);
-	if (!rinfo->fb_base) {
-		printk ("radeonfb: cannot map FB\n");
-		iounmap ((void*)rinfo->mmio_base);
-		release_mem_region (rinfo->mmio_base_phys,
-				    pci_resource_len(pdev, 2));
-		release_mem_region (rinfo->fb_base_phys,
-				    pci_resource_len(pdev, 0));
-		kfree (rinfo);
-		return -ENODEV;
-	}
-
-	/* XXX turn off accel for now, blts aren't working right */
-	noaccel = 1;
-
-	/* currcon not yet configured, will be set by first switch */
-	rinfo->currcon = -1;
-
-	/* set all the vital stuff */
-	radeon_set_fbinfo (rinfo);
-
-	/* save current mode regs before we switch into the new one
-	 * so we can restore this upon __exit
-	 */
-	radeon_save_state (rinfo, &rinfo->init_state);
-
-	/* init palette */
-	for (i=0; i<16; i++) {
-		j = color_table[i];
-		rinfo->palette[i].red = default_red[j];
-		rinfo->palette[i].green = default_grn[j];
-		rinfo->palette[i].blue = default_blu[j];
-	}
-
-	pci_set_drvdata(pdev, rinfo);
-	rinfo->next = board_list;
-	board_list = rinfo;
-
-	if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
-		printk ("radeonfb: could not register framebuffer\n");
-		iounmap ((void*)rinfo->fb_base);
-		iounmap ((void*)rinfo->mmio_base);
-		release_mem_region (rinfo->mmio_base_phys,
-				    pci_resource_len(pdev, 2));
-		release_mem_region (rinfo->fb_base_phys,
-				    pci_resource_len(pdev, 0));
-		kfree (rinfo);
-		return -ENODEV;
-	}
-
-	if (!noaccel) {
-		/* initialize the engine */
-		radeon_engine_init (rinfo);
-	}
-
-#ifdef CONFIG_PMAC_BACKLIGHT
-	if (rinfo->dviDisp_type == MT_LCD)
-		register_backlight_controller(&radeon_backlight_controller,
-					      rinfo, "ati");
-#endif
-
-#ifdef CONFIG_PMAC_PBOOK
-	if (rinfo->dviDisp_type == MT_LCD) {
-		rinfo->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
-		pmu_register_sleep_notifier(&radeon_sleep_notifier);
-	}
-#endif
-
-	printk ("radeonfb: ATI %s %s %d MB\n", rinfo->name, rinfo->ram_type,
-		(rinfo->video_ram/(1024*1024)));
-
-	if (rinfo->hasCRTC2) {
-		printk("radeonfb: DVI port %s monitor connected\n",
-			GET_MON_NAME(rinfo->dviDisp_type));
-		printk("radeonfb: CRT port %s monitor connected\n",
-			GET_MON_NAME(rinfo->crtDisp_type));
-	} else {
-		printk("radeonfb: CRT port %s monitor connected\n",
-			GET_MON_NAME(rinfo->crtDisp_type));
-	}
-
-	RTRACE("radeonfb_pci_register END\n");
-
-	return 0;
-}
-
-
-
-static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
-{
-        struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
- 
-        if (!rinfo)
-                return;
- 
-	/* restore original state */
-        radeon_write_mode (rinfo, &rinfo->init_state);
- 
-        unregister_framebuffer ((struct fb_info *) rinfo);
-                
-        iounmap ((void*)rinfo->mmio_base);
-        iounmap ((void*)rinfo->fb_base);
- 
-	release_mem_region (rinfo->mmio_base_phys,
-			    pci_resource_len(pdev, 2));
-	release_mem_region (rinfo->fb_base_phys,
-			    pci_resource_len(pdev, 0));
-        
-        kfree (rinfo);
-}
-
-
-
-static char *radeon_find_rom(struct radeonfb_info *rinfo)
-{       
-#if defined(__i386__)
-        u32  segstart;
-        char *rom_base;
-        char *rom;
-        int  stage;
-        int  i,j;       
-        char aty_rom_sig[] = "761295520";
-        char *radeon_sig[] = {
-          "RG6",
-          "RADEON"
-        };
-                                                
-        for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
-                        
-                stage = 1;
-                
-                rom_base = (char *)ioremap(segstart, 0x1000);
-
-                if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa))
-                        stage = 2;
-                
-                    
-                if (stage != 2) {
-                        iounmap(rom_base);
-                        continue;
-                }
-                                              
-                rom = rom_base;
-                     
-                for (i = 0; (i < 128 - strlen(aty_rom_sig)) && (stage != 3); i++) {
-                        if (aty_rom_sig[0] == *rom)
-                                if (strncmp(aty_rom_sig, rom,
-                                                strlen(aty_rom_sig)) == 0)
-                                        stage = 3;
-                        rom++;
-                }
-                if (stage != 3) {
-                        iounmap(rom_base);
-                        continue;
-                }
-                rom = rom_base;
-        
-                for (i = 0; (i < 512) && (stage != 4); i++) {
-                    for(j = 0;j < sizeof(radeon_sig)/sizeof(char *);j++) {
-                        if (radeon_sig[j][0] == *rom)
-                                if (strncmp(radeon_sig[j], rom,
-                                            strlen(radeon_sig[j])) == 0) {
-                                              stage = 4;
-                                              break;
-                                            }
-                    }                           
-                        rom++;
-                }       
-                if (stage != 4) {
-                        iounmap(rom_base);
-                        continue;
-                }       
-                
-                return rom_base;
-        }
-#endif          
-        return NULL;
-}
-
-
-
-
-static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg)
-{
-        void *bios_header;
-        void *header_ptr;
-        u16 bios_header_offset, pll_info_offset;
-        PLL_BLOCK pll;
-
-	if (bios_seg) {
-	        bios_header = bios_seg + 0x48L;
-       		header_ptr  = bios_header;
-        
-        	bios_header_offset = readw(header_ptr);
-	        bios_header = bios_seg + bios_header_offset;
-        	bios_header += 0x30;
-        
-        	header_ptr = bios_header;
-        	pll_info_offset = readw(header_ptr);
-        	header_ptr = bios_seg + pll_info_offset;
-        
-        	memcpy_fromio(&pll, header_ptr, 50);
-        
-        	rinfo->pll.xclk = (u32)pll.XCLK;
-        	rinfo->pll.ref_clk = (u32)pll.PCLK_ref_freq;
-        	rinfo->pll.ref_div = (u32)pll.PCLK_ref_divider;
-        	rinfo->pll.ppll_min = pll.PCLK_min_freq;
-        	rinfo->pll.ppll_max = pll.PCLK_max_freq;
-
-		printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from BIOS\n",
-			rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
-	} else {
-#ifdef CONFIG_ALL_PPC
-		if (radeon_read_OF(rinfo)) {
-			unsigned int tmp, Nx, M, ref_div, xclk;
-
-			tmp = INPLL(M_SPLL_REF_FB_DIV);
-			ref_div = INPLL(PPLL_REF_DIV) & 0x3ff;
-
-			Nx = (tmp & 0xff00) >> 8;
-			M = (tmp & 0xff);
-			xclk = ((((2 * Nx * rinfo->pll.ref_clk) + (M)) /
-				(2 * M)));
-
-			rinfo->pll.xclk = xclk;
-			rinfo->pll.ref_div = ref_div;
-			rinfo->pll.ppll_min = 12000;
-			rinfo->pll.ppll_max = 35000;
-
-			printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from OF\n",
-				rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
-
-			return;
-		}
-#endif
-		/* no BIOS or BIOS not found, use defaults */
-		switch (rinfo->chipset) {
-			case PCI_DEVICE_ID_RADEON_QW:
-				rinfo->pll.ppll_max = 35000;
-				rinfo->pll.ppll_min = 12000;
-				rinfo->pll.xclk = 23000;
-				rinfo->pll.ref_div = 12;
-				rinfo->pll.ref_clk = 2700;
-				break;
-			case PCI_DEVICE_ID_RADEON_QL:
-				rinfo->pll.ppll_max = 35000;
-				rinfo->pll.ppll_min = 12000;
-				rinfo->pll.xclk = 27500;
-				rinfo->pll.ref_div = 12;
-				rinfo->pll.ref_clk = 2700;
-				break;
-			case PCI_DEVICE_ID_RADEON_QD:
-			case PCI_DEVICE_ID_RADEON_QE:
-			case PCI_DEVICE_ID_RADEON_QF:
-			case PCI_DEVICE_ID_RADEON_QG:
-			default:
-				rinfo->pll.ppll_max = 35000;
-				rinfo->pll.ppll_min = 12000;
-				rinfo->pll.xclk = 16600;
-				rinfo->pll.ref_div = 67;
-				rinfo->pll.ref_clk = 2700;
-				break;
-		}
-
-		printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d defaults\n",
-			rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
-	}
-}
-
-
-static void radeon_get_moninfo (struct radeonfb_info *rinfo)
-{
-	unsigned int tmp;
-
-	if (force_dfp) {
-		rinfo->dviDisp_type = MT_DFP;
-		return;
-	}
-
-	tmp = INREG(RADEON_BIOS_4_SCRATCH);
-
-	if (rinfo->hasCRTC2) {
+	if (rinfo->hasCRTC2 && tmp) {
 		/* primary DVI port */
 		if (tmp & 0x08)
 			rinfo->dviDisp_type = MT_DFP;
@@ -1279,7 +1223,29 @@
 	}
 }
 
-
+#ifdef CONFIG_ALL_PPC
+static int radeon_get_EDID_OF(struct radeonfb_info *rinfo)
+{
+        struct device_node *dp;
+        unsigned char *pedid = NULL;
+        static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", "EDID1", NULL };
+        int i;  
+
+        dp = pci_device_to_OF_node(rinfo->pdev);
+        while (dp != NULL) {
+                for (i = 0; propnames[i] != NULL; ++i) {
+                        pedid = (unsigned char *)
+                                get_property(dp, propnames[i], NULL);
+                        if (pedid != NULL) {
+                                rinfo->EDID = pedid;
+                                return 1;
+                        }
+                }
+                dp = dp->child;
+        }
+        return 0;
+}
+#endif /* CONFIG_ALL_PPC */
 
 static void radeon_get_EDID(struct radeonfb_info *rinfo)
 {
@@ -1291,29 +1257,83 @@
 #endif
 }
 
-
 #ifdef CONFIG_ALL_PPC
-static int radeon_get_EDID_OF(struct radeonfb_info *rinfo)
-{
-	struct device_node *dp;
-	unsigned char *pedid = NULL;
+#undef SET_MC_FB_FROM_APERTURE
+static void
+radeon_fixup_apertures(struct radeonfb_info *rinfo)
+{
+	u32 save_crtc_gen_cntl, save_crtc2_gen_cntl;
+	u32 save_crtc_ext_cntl;
+	u32 aper_base, aper_size;
+	u32 agp_base;
 
-	dp = pci_device_to_OF_node(rinfo->pdev);
-	pedid = (unsigned char *) get_property(dp, "DFP,EDID", 0);
-	if (!pedid)
-		pedid = (unsigned char *) get_property(dp, "LCD,EDID", 0);
-	if (!pedid)
-		pedid = (unsigned char *) get_property(dp, "EDID", 0);
+	/* First, we disable display to avoid interfering */
+	if (rinfo->hasCRTC2) {
+		save_crtc2_gen_cntl = INREG(CRTC2_GEN_CNTL);
+		OUTREG(CRTC2_GEN_CNTL, save_crtc2_gen_cntl | CRTC2_DISP_REQ_EN_B);
+	}
+	save_crtc_gen_cntl = INREG(CRTC_GEN_CNTL);
+	save_crtc_ext_cntl = INREG(CRTC_EXT_CNTL);
+	
+	OUTREG(CRTC_EXT_CNTL, save_crtc_ext_cntl | CRTC_DISPLAY_DIS);
+	OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl | CRTC_DISP_REQ_EN_B);
+	mdelay(100);
+
+	aper_base = INREG(CONFIG_APER_0_BASE);
+	aper_size = INREG(CONFIG_APER_SIZE);
+
+#ifdef SET_MC_FB_FROM_APERTURE
+	/* Set framebuffer to be at the same address as set in PCI BAR */
+	OUTREG(MC_FB_LOCATION, 
+		((aper_base + aper_size - 1) & 0xffff0000) | (aper_base >> 16));
+	rinfo->fb_local_base = aper_base;
+#else
+	OUTREG(MC_FB_LOCATION, 0x7fff0000);
+	rinfo->fb_local_base = 0;
+#endif
+	agp_base = aper_base + aper_size;
+	if (agp_base & 0xf0000000)
+		agp_base = (aper_base | 0x0fffffff) + 1;
+
+	/* Set AGP to be just after the framebuffer on a 256Mb boundary. This
+	 * assumes the FB isn't mapped to 0xf0000000 or above, but this is
+	 * always the case on PPCs afaik.
+	 */
+#ifdef SET_MC_FB_FROM_APERTURE
+	OUTREG(MC_AGP_LOCATION, 0xffff0000 | (agp_base >> 16));
+#else
+	OUTREG(MC_AGP_LOCATION, 0xffffe000);
+#endif
 
-	if (pedid) {
-		rinfo->EDID = pedid;
-		return 1;
-	} else
-		return 0;
+	/* Fixup the display base addresses & engine offsets while we
+	 * are at it as well
+	 */
+#ifdef SET_MC_FB_FROM_APERTURE
+	OUTREG(DISPLAY_BASE_ADDR, aper_base);
+	if (rinfo->hasCRTC2)
+		OUTREG(CRTC2_DISPLAY_BASE_ADDR, aper_base);
+#else
+	OUTREG(DISPLAY_BASE_ADDR, 0);
+	if (rinfo->hasCRTC2)
+		OUTREG(CRTC2_DISPLAY_BASE_ADDR, 0);
+#endif
+	mdelay(100);
+
+	/* Restore display settings */
+	OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl);
+	OUTREG(CRTC_EXT_CNTL, save_crtc_ext_cntl);
+	if (rinfo->hasCRTC2)
+		OUTREG(CRTC2_GEN_CNTL, save_crtc2_gen_cntl);	
+
+#if 0
+	printk("aper_base: %08x MC_FB_LOC to: %08x, MC_AGP_LOC to: %08x\n",
+		aper_base,
+		((aper_base + aper_size - 1) & 0xffff0000) | (aper_base >> 16),
+		0xffff0000 | (agp_base >> 16));
+#endif
 }
 #endif /* CONFIG_ALL_PPC */
 
-
 static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo)
 {
 	unsigned char *block = rinfo->EDID;
@@ -1344,6 +1364,15 @@
 			rinfo->vAct_high = 1;
 	}
 
+	RTRACE("hOver_plus = %d\t hSync_width = %d\n", rinfo->hOver_plus,
+		rinfo->hSync_width);
+	RTRACE("vOver_plus = %d\t vSync_width = %d\n", rinfo->vOver_plus,
+		rinfo->vSync_width);
+	RTRACE("hblank = %d\t vblank = %d\n", rinfo->hblank,
+		rinfo->vblank);
+	RTRACE("sync = %d\n", rinfo->synct);
+	RTRACE("misc = %d\n", rinfo->misc);
+	RTRACE("clock = %d\n", rinfo->clock);
 	printk("radeonfb: detected DFP panel size from EDID: %dx%d\n",
 		rinfo->panel_xres, rinfo->panel_yres);
 
@@ -1352,11 +1381,13 @@
 	return 1;
 }
 
-
 static void radeon_update_default_var(struct radeonfb_info *rinfo)
 {
 	struct fb_var_screeninfo *var = &radeonfb_default_var;
 
+        /*
+         * Update default var to match the lcd monitor's native resolution
+         */
 	var->xres = rinfo->panel_xres;
 	var->yres = rinfo->panel_yres;
 	var->xres_virtual = rinfo->panel_xres;
@@ -1371,12 +1402,10 @@
 	var->hsync_len = rinfo->hSync_width;
 	var->vsync_len = rinfo->vSync_width;
 	var->sync = 0;
-	if (rinfo->synct == 3) {
-		if (rinfo->hAct_high)
-			var->sync |= FB_SYNC_HOR_HIGH_ACT;
-		if (rinfo->vAct_high)
-			var->sync |= FB_SYNC_VERT_HIGH_ACT;
-	}
+	if (rinfo->hAct_high)
+		var->sync |= FB_SYNC_HOR_HIGH_ACT;
+	if (rinfo->vAct_high)
+		var->sync |= FB_SYNC_VERT_HIGH_ACT;
 
 	var->vmode = 0;
 	if (rinfo->interlaced)
@@ -1385,25 +1414,65 @@
 	rinfo->use_default_var = 1;
 }
 
-
-static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo)
-{
-	char *fpbiosstart, *tmp, *tmp0;
-	char stmp[30];
-	int i;
-
-	if (!rinfo->bios_seg)
-		return 0;
-
-	if (!(fpbiosstart = rinfo->bios_seg + readw(rinfo->bios_seg + 0x48))) {
+/* Copied from XFree86 4.3 --BenH */
+static int
+radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo, unsigned char *fpbiosstart)
+{
+	unsigned char *tmp;
+	unsigned short offset;
+
+	offset = readw(fpbiosstart + 0x34);
+	if (offset != 0)
+		offset = readw(rinfo->bios_seg + offset + 2);
+	if (offset == 0) {
 		printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
 		return 0;
 	}
+	tmp = rinfo->bios_seg + offset;
 
-	if (!(tmp = rinfo->bios_seg + readw(fpbiosstart + 0x40))) {
-		printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
+	/* This is an EDID block */
+	rinfo->clock = readw(tmp);
+	rinfo->panel_xres = (readb(tmp + 2) + ((readb(tmp + 4) & 0xf0) << 4));
+	rinfo->hblank = (readb(tmp + 3) + ((readb(tmp + 4) & 0x0f) << 8));
+	rinfo->panel_yres = (readb(tmp + 5) + ((readb(tmp + 7) & 0xf0) << 4));
+	rinfo->vblank = (readb(tmp + 6) + ((readb(tmp + 7) & 0x0f) << 8));
+	rinfo->hOver_plus = (readb(tmp + 8) + ((readb(tmp + 11) & 0xc0) << 2));
+	rinfo->hSync_width = (readb(tmp + 9) + ((readb(tmp + 11) & 0x30) << 4));
+	rinfo->vOver_plus = ((readb(tmp + 10) >> 4) + ((readb(tmp + 11) & 0x0c) << 2));
+	rinfo->vSync_width = ((readb(tmp + 10) & 0x0f) + ((readb(tmp + 11) & 0x03) << 4));
+	rinfo->interlaced = ((readb(tmp + 17) & 0x80) >> 7);
+	rinfo->synct = ((readb(tmp + 17) & 0x18) >> 3);
+	rinfo->misc = ((readb(tmp + 17) & 0x06) >> 1);
+	rinfo->hAct_high = rinfo->vAct_high = 0;
+	if (rinfo->synct == 3) {
+		if (rinfo->misc & 2)
+			rinfo->hAct_high = 1;
+		if (rinfo->misc & 1)
+			rinfo->vAct_high = 1;
+	}
+
+	printk("radeonfb: detected DFP panel size from BIOS: %dx%d\n",
+		rinfo->panel_xres, rinfo->panel_yres);
+
+	rinfo->got_dfpinfo = 1;
+	return 1;
+}
+
+
+static int
+radeon_get_lcdinfo_BIOS(struct radeonfb_info *rinfo, unsigned char *fpbiosstart)
+{
+	unsigned char *tmp, *tmp0;
+	unsigned char stmp[30];
+	unsigned short offset;
+	int i;
+
+	offset = readw(fpbiosstart + 0x40);
+	if (offset == 0) {
+		printk("radeonfb: Failed to detect LCD panel info using BIOS\n");
 		return 0;
 	}
+	tmp = rinfo->bios_seg + offset;
 
 	for(i=0; i<24; i++)
 		stmp[i] = readb(tmp+i+1);
@@ -1411,7 +1480,7 @@
 	printk("radeonfb: panel ID string: %s\n", stmp);
 	rinfo->panel_xres = readw(tmp + 25);
 	rinfo->panel_yres = readw(tmp + 27);
-	printk("radeonfb: detected DFP panel size from BIOS: %dx%d\n",
+	printk("radeonfb: detected LCD panel size from BIOS: %dx%d\n",
 		rinfo->panel_xres, rinfo->panel_yres);
 
 	for(i=0; i<20; i++) {
@@ -1427,12 +1496,34 @@
 			rinfo->vOver_plus = (readw(tmp0+28) & 0x7ff) - readw(tmp0+26);
 			rinfo->vSync_width = (readw(tmp0+28) & 0xf800) >> 11;
 			rinfo->clock = readw(tmp0+9);
+                        /* We don't know that the H/V sync active level should be
+                           make the same assumptions as XFree does - High Active */
+                        rinfo->vAct_high=1;
+                        rinfo->hAct_high=1;
+			rinfo->got_dfpinfo = 1;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static int radeon_get_panelinfo_BIOS(struct radeonfb_info *rinfo)
+{
+	unsigned char *fpbiosstart;
+
+	if (!rinfo->bios_seg)
+		return 0;
 
-			rinfo->got_dfpinfo = 1;
-			return 1;
-		}
+	if (!(fpbiosstart = rinfo->bios_seg + readw(rinfo->bios_seg + 0x48))) {
+		printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
+		return 0;
 	}
 
+	if (rinfo->dviDisp_type == MT_LCD)
+		return radeon_get_lcdinfo_BIOS(rinfo, fpbiosstart);
+	else if (rinfo->dviDisp_type == MT_DFP)
+		return radeon_get_dfpinfo_BIOS(rinfo, fpbiosstart);
+
 	return 0;
 }
 
@@ -1443,7 +1534,7 @@
 	unsigned int tmp;
 	unsigned short a, b;
 
-	if (radeon_get_dfpinfo_BIOS(rinfo))
+	if (radeon_get_panelinfo_BIOS(rinfo))
 		radeon_update_default_var(rinfo);
 
 	if (radeon_dfp_parse_EDID(rinfo))
@@ -1470,11 +1561,6 @@
 				rinfo->panel_xres = 800;
 				break;
 			case 768:
-#if defined(__powerpc__)
-				if (rinfo->dviDisp_type == MT_LCD)
-					rinfo->panel_xres = 1152;
-				else
-#endif
 				rinfo->panel_xres = 1024;
 				break;
 			case 1024:
@@ -1499,54 +1585,375 @@
 		b = (tmp & 0x01ff0000) >> FP_CRTC_H_DISP_SHIFT;
 		rinfo->hblank = (a - b + 1) * 8;
 
-		tmp = INREG(FP_H_SYNC_STRT_WID);
-		rinfo->hOver_plus = (unsigned short) ((tmp & FP_H_SYNC_STRT_CHAR_MASK) >>
-					FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1;
-		rinfo->hOver_plus *= 8;
-		rinfo->hSync_width = (unsigned short) ((tmp & FP_H_SYNC_WID_MASK) >>
-					FP_H_SYNC_WID_SHIFT);
-		rinfo->hSync_width *= 8;
-		tmp = INREG(FP_CRTC_V_TOTAL_DISP);
-		a = (tmp & FP_CRTC_V_TOTAL_MASK) + 1;
-		b = (tmp & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT;
-		rinfo->vblank = a - b /* + 24 */ ;
+		tmp = INREG(FP_H_SYNC_STRT_WID);
+		rinfo->hOver_plus = (unsigned short) ((tmp & FP_H_SYNC_STRT_CHAR_MASK) >>
+					FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1;
+		rinfo->hOver_plus *= 8;
+		rinfo->hSync_width = (unsigned short) ((tmp & FP_H_SYNC_WID_MASK) >>
+					FP_H_SYNC_WID_SHIFT);
+		rinfo->hSync_width *= 8;
+		tmp = INREG(FP_CRTC_V_TOTAL_DISP);
+		a = (tmp & FP_CRTC_V_TOTAL_MASK) + 1;
+		b = (tmp & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT;
+		rinfo->vblank = a - b /* + 24 */ ;
+
+		tmp = INREG(FP_V_SYNC_STRT_WID);
+		rinfo->vOver_plus = (unsigned short) (tmp & FP_V_SYNC_STRT_MASK)
+					- b + 1;
+		rinfo->vSync_width = (unsigned short) ((tmp & FP_V_SYNC_WID_MASK) >>
+					FP_V_SYNC_WID_SHIFT);
+
+		/* XXX */
+		/* We should calculate the pixclock as well here... --BenH.
+		 */
+
+		return 1;
+	}
+
+	return 1;
+}
+
+static int radeonfb_pci_register (struct pci_dev *pdev,
+				  const struct pci_device_id *ent)
+{
+	struct radeonfb_info *rinfo;
+	struct radeon_chip_info *rci = &radeon_chip_info[ent->driver_data];
+	u32 tmp;
+	int i, j;
+
+	RTRACE("radeonfb_pci_register BEGIN\n");
+
+	rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL);
+	if (!rinfo) {
+		printk ("radeonfb: could not allocate memory\n");
+		return -ENODEV;
+	}
+
+	memset (rinfo, 0, sizeof (struct radeonfb_info));
+
+	rinfo->pdev = pdev;
+	strncpy(rinfo->name, rci->name, 16);
+	rinfo->arch = rci->arch;
+
+	/* enable device */
+	{
+		int err;
+
+		if ((err = pci_enable_device(pdev))) {
+			printk("radeonfb: cannot enable device\n");
+			kfree (rinfo);
+			return -ENODEV;
+		}
+	}
+
+	/* set base addrs */
+	rinfo->fb_base_phys = pci_resource_start (pdev, 0);
+	rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
+
+	/* request the mem regions */
+	if (!request_mem_region (rinfo->fb_base_phys,
+				 pci_resource_len(pdev, 0), "radeonfb")) {
+		printk ("radeonfb: cannot reserve FB region\n");
+		kfree (rinfo);
+		return -ENODEV;
+	}
+
+	if (!request_mem_region (rinfo->mmio_base_phys,
+				 pci_resource_len(pdev, 2), "radeonfb")) {
+		printk ("radeonfb: cannot reserve MMIO region\n");
+		release_mem_region (rinfo->fb_base_phys,
+				    pci_resource_len(pdev, 0));
+		kfree (rinfo);
+		return -ENODEV;
+	}
+
+	/* map the regions */
+	rinfo->mmio_base = (unsigned long) ioremap (rinfo->mmio_base_phys,
+				    		    RADEON_REGSIZE);
+	if (!rinfo->mmio_base) {
+		printk ("radeonfb: cannot map MMIO\n");
+		release_mem_region (rinfo->mmio_base_phys,
+				    pci_resource_len(pdev, 2));
+		release_mem_region (rinfo->fb_base_phys,
+				    pci_resource_len(pdev, 0));
+		kfree (rinfo);
+		return -ENODEV;
+	}
+
+	rinfo->chipset = pdev->device;
+
+	switch (rinfo->arch) {
+		case RADEON_R100:
+			rinfo->hasCRTC2 = 0;
+			break;
+		default:
+			/* all the rest have it */
+			rinfo->hasCRTC2 = 1;
+			break;
+	}
+
+	if (mirror)
+		printk("radeonfb: mirroring display to CRT\n");
+
+	/* framebuffer size */
+	tmp = INREG(CONFIG_MEMSIZE);
+
+	/* mem size is bits [28:0], mask off the rest */
+	rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
+
+	/* ram type */
+	tmp = INREG(MEM_SDRAM_MODE_REG);
+	switch ((MEM_CFG_TYPE & tmp) >> 30) {
+		case 0:
+			/* SDR SGRAM (2:1) */
+			strcpy(rinfo->ram_type, "SDR SGRAM");
+			rinfo->ram.ml = 4;
+			rinfo->ram.mb = 4;
+			rinfo->ram.trcd = 1;
+			rinfo->ram.trp = 2;
+			rinfo->ram.twr = 1;
+			rinfo->ram.cl = 2;
+			rinfo->ram.loop_latency = 16;
+			rinfo->ram.rloop = 16;
+	
+			break;
+		case 1:
+			/* DDR SGRAM */
+			strcpy(rinfo->ram_type, "DDR SGRAM");
+			rinfo->ram.ml = 4;
+			rinfo->ram.mb = 4;
+			rinfo->ram.trcd = 3;
+			rinfo->ram.trp = 3;
+			rinfo->ram.twr = 2;
+			rinfo->ram.cl = 3;
+			rinfo->ram.tr2w = 1;
+			rinfo->ram.loop_latency = 16;
+			rinfo->ram.rloop = 16;
+
+			break;
+		default:
+			/* 64-bit SDR SGRAM */
+			strcpy(rinfo->ram_type, "SDR SGRAM 64");
+			rinfo->ram.ml = 4;
+			rinfo->ram.mb = 8;
+			rinfo->ram.trcd = 3;
+			rinfo->ram.trp = 3;
+			rinfo->ram.twr = 1;
+			rinfo->ram.cl = 3;
+			rinfo->ram.tr2w = 1;
+			rinfo->ram.loop_latency = 17;
+			rinfo->ram.rloop = 17;
+
+			break;
+	}
+
+	rinfo->bios_seg = radeon_find_rom(rinfo);
+	radeon_get_pllinfo(rinfo, rinfo->bios_seg);
+
+	/*
+	 * Hack to get around some busted production M6's
+	 * reporting no ram
+	 */
+	if (rinfo->video_ram == 0) {
+		switch (pdev->device) {
+			case PCI_DEVICE_ID_ATI_RADEON_LY:
+			case PCI_DEVICE_ID_ATI_RADEON_LZ:
+				rinfo->video_ram = 8192 * 1024;
+				break;
+			default:
+				break;
+		}
+	}
+
+
+	RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
+
+	RTRACE("BIOS 4 scratch = %x\n", INREG(RADEON_BIOS_4_SCRATCH));
+	RTRACE("FP_GEN_CNTL: %x, FP2_GEN_CNTL: %x\n",
+		INREG(FP_GEN_CNTL), INREG(FP2_GEN_CNTL));
+	RTRACE("TMDS_TRANSMITTER_CNTL: %x, TMDS_CNTL: %x, LVDS_GEN_CNTL: %x\n",
+		INREG(TMDS_TRANSMITTER_CNTL), INREG(TMDS_CNTL), INREG(LVDS_GEN_CNTL));
+	RTRACE("DAC_CNTL: %x, DAC_CNTL2: %x, CRTC_GEN_CNTL: %x\n",
+		INREG(DAC_CNTL), INREG(DAC_CNTL2), INREG(CRTC_GEN_CNTL));
+
+
+#if !defined(__powerpc__)
+	radeon_get_moninfo(rinfo);
+#else
+	switch (rinfo->arch) {
+		case RADEON_M6:
+		case RADEON_M7:
+		case RADEON_M9:
+			/* If forced to no-LCD, we shut down the backlight */
+			if (force_nolcd) {
+#ifdef CONFIG_PMAC_BACKLIGHT
+				radeon_set_backlight_enable(0, BACKLIGHT_OFF, rinfo);
+#endif
+			} else {
+				rinfo->dviDisp_type = MT_LCD;
+				break;
+			}
+			/* Fall through */
+		default:
+			radeon_get_moninfo(rinfo);
+			break;
+	}
+#endif
+
+	radeon_get_EDID(rinfo);
+
+	if ((rinfo->dviDisp_type == MT_DFP) || (rinfo->dviDisp_type == MT_LCD) ||
+	    (rinfo->crtDisp_type == MT_DFP)) {
+		if (!radeon_get_dfpinfo(rinfo)) {
+			iounmap ((void*)rinfo->mmio_base);
+			release_mem_region (rinfo->mmio_base_phys,
+					    pci_resource_len(pdev, 2));
+			release_mem_region (rinfo->fb_base_phys,
+					    pci_resource_len(pdev, 0));
+			kfree (rinfo);
+			return -ENODEV;
+		}
+	}
+
+	rinfo->fb_base = (unsigned long) ioremap (rinfo->fb_base_phys,
+				  		  rinfo->video_ram);
+	if (!rinfo->fb_base) {
+		printk ("radeonfb: cannot map FB\n");
+		iounmap ((void*)rinfo->mmio_base);
+		release_mem_region (rinfo->mmio_base_phys,
+				    pci_resource_len(pdev, 2));
+		release_mem_region (rinfo->fb_base_phys,
+				    pci_resource_len(pdev, 0));
+		kfree (rinfo);
+		return -ENODEV;
+	}
+
+	/* currcon not yet configured, will be set by first switch */
+	rinfo->currcon = -1;
+
+	/* On PPC, the firmware sets up a memory mapping that tends
+	 * to cause lockups when enabling the engine. We reconfigure
+	 * the card internal memory mappings properly
+	 */
+#ifdef CONFIG_ALL_PPC
+	radeon_fixup_apertures(rinfo);
+#else	
+	rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
+#endif /* CONFIG_ALL_PPC */
+
+	/* save current mode regs before we switch into the new one
+	 * so we can restore this upon __exit
+	 */
+	radeon_save_state (rinfo, &rinfo->init_state);
+
+	/* init palette */
+	for (i=0; i<16; i++) {
+		j = color_table[i];
+		rinfo->palette[i].red = default_red[j];
+		rinfo->palette[i].green = default_grn[j];
+		rinfo->palette[i].blue = default_blu[j];
+	}
+
+	pci_set_drvdata(pdev, rinfo);
+	rinfo->next = board_list;
+	board_list = rinfo;
+
+	/* set all the vital stuff */
+	radeon_set_fbinfo (rinfo);
+
+	if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
+		printk ("radeonfb: could not register framebuffer\n");
+		iounmap ((void*)rinfo->fb_base);
+		iounmap ((void*)rinfo->mmio_base);
+		release_mem_region (rinfo->mmio_base_phys,
+				    pci_resource_len(pdev, 2));
+		release_mem_region (rinfo->fb_base_phys,
+				    pci_resource_len(pdev, 0));
+		kfree (rinfo);
+		return -ENODEV;
+	}
+
+#ifdef CONFIG_MTRR
+	rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->fb_base_phys,
+						 rinfo->video_ram,
+						 MTRR_TYPE_WRCOMB, 1);
+#endif
+
 
-		tmp = INREG(FP_V_SYNC_STRT_WID);
-		rinfo->vOver_plus = (unsigned short) (tmp & FP_V_SYNC_STRT_MASK)
-					- b + 1;
-		rinfo->vSync_width = (unsigned short) ((tmp & FP_V_SYNC_WID_MASK) >>
-					FP_V_SYNC_WID_SHIFT);
+#ifdef CONFIG_PMAC_BACKLIGHT
+	if (rinfo->dviDisp_type == MT_LCD)
+		register_backlight_controller(&radeon_backlight_controller,
+					      rinfo, "ati");
+#endif
 
-		return 1;
+	printk ("radeonfb: ATI Radeon %s %s %d MB\n", rinfo->name, rinfo->ram_type,
+		(rinfo->video_ram/(1024*1024)));
+
+	if (rinfo->hasCRTC2) {
+		printk("radeonfb: DVI port %s monitor connected\n",
+			GET_MON_NAME(rinfo->dviDisp_type));
+		printk("radeonfb: CRT port %s monitor connected\n",
+			GET_MON_NAME(rinfo->crtDisp_type));
+	} else {
+		printk("radeonfb: CRT port %s monitor connected\n",
+			GET_MON_NAME(rinfo->crtDisp_type));
 	}
 
-	return 1;
-}
+#ifdef CONFIG_PMAC_PBOOK
+	if (rinfo->arch == RADEON_M6 || 
+	    rinfo->arch == RADEON_M7 || 
+	    rinfo->arch == RADEON_M9) {
+               /* Find PM registers in config space */
+               rinfo->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
+
+               /* Enable dynamic PM of chip clocks */
+               radeon_pm_enable_dynamic_mode(rinfo);
+
+               /* Register sleep callbacks */
+               pmu_register_sleep_notifier(&radeon_sleep_notifier);
+               printk("radeonfb: Power Management enabled for Mobility chipsets\n");
+       }
+#endif
 
+	RTRACE("radeonfb_pci_register END\n");
 
-#ifdef CONFIG_ALL_PPC
-static int radeon_read_OF (struct radeonfb_info *rinfo)
-{
-	struct device_node *dp;
-	unsigned int *xtal;
+	return 0;
+}
 
-	dp = pci_device_to_OF_node(rinfo->pdev);
 
-	xtal = (unsigned int *) get_property(dp, "ATY,RefCLK", 0);
 
-	rinfo->pll.ref_clk = *xtal / 10;
+static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
+{
+        struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
+ 
+        if (!rinfo)
+                return;
+ 
+	/* restore original state */
+        radeon_write_mode (rinfo, &rinfo->init_state);
+ 
+#ifdef CONFIG_MTRR
+	if (rinfo->mtrr_hdl >= 0)
+		mtrr_del(rinfo->mtrr_hdl, 0, 0);
+#endif
 
-	if (*xtal)
-		return 1;
-	else
-		return 0;
+        unregister_framebuffer ((struct fb_info *) rinfo);
+                
+        iounmap ((void*)rinfo->mmio_base);
+        iounmap ((void*)rinfo->fb_base);
+ 
+	release_mem_region (rinfo->mmio_base_phys,
+			    pci_resource_len(pdev, 2));
+	release_mem_region (rinfo->fb_base_phys,
+			    pci_resource_len(pdev, 0));
+        
+        kfree (rinfo);
 }
-#endif	
 
 
-static void radeon_engine_init (struct radeonfb_info *rinfo)
+static int radeon_engine_init (struct radeonfb_info *rinfo)
 {
-	u32 temp;
+	unsigned long temp;
 
 	/* disable 3D engine */
 	OUTREG(RB3D_CNTL, 0);
@@ -1554,25 +1961,33 @@
 	radeon_engine_reset ();
 
 	radeon_fifo_wait (1);
-	OUTREG(DSTCACHE_MODE, 0);
+	if (rinfo->arch != RADEON_R300)
+		OUTREG(RB2D_DSTCACHE_MODE, 0);
 
-	/* XXX */
-	rinfo->pitch = ((rinfo->xres * (rinfo->bpp / 8) + 0x3f)) >> 6;
+	radeon_fifo_wait (3);
+	/* We re-read MC_FB_LOCATION from card as it can have been
+	 * modified by XFree drivers (ouch !)
+	 */
+	rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
 
-	radeon_fifo_wait (1);
-	temp = INREG(DEFAULT_PITCH_OFFSET);
-	OUTREG(DEFAULT_PITCH_OFFSET, ((temp & 0xc0000000) | 
-				      (rinfo->pitch << 0x16)));
+	OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) |
+				     (rinfo->fb_local_base >> 10));
+	OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
+	OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
 
 	radeon_fifo_wait (1);
+#if defined(__BIG_ENDIAN)
+	OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN);
+#else
 	OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
-
+#endif
 	radeon_fifo_wait (1);
 	OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
 					 DEFAULT_SC_BOTTOM_MAX));
 
 	temp = radeon_get_dstbpp(rinfo->depth);
 	rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
+
 	radeon_fifo_wait (1);
 	OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
 				    GMC_BRUSH_SOLID_COLOR |
@@ -1596,6 +2011,8 @@
 	OUTREG(DP_WRITE_MSK, 0xffffffff);
 
 	radeon_engine_idle ();
+
+	return 0;
 }
 
 
@@ -1635,66 +2052,35 @@
         disp = &rinfo->disp;
         
         disp->var = radeonfb_default_var;
-#if defined(__powerpc__)
-	if (rinfo->dviDisp_type == MT_LCD) {
-		if (mac_vmode_to_var(VMODE_1152_768_60, CMODE_8, &disp->var))
-			disp->var = radeonfb_default_var;
-	}
-#endif
-
-	rinfo->depth = var_to_depth(&disp->var);
-	rinfo->bpp = disp->var.bits_per_pixel;
 
+	/* We must initialize disp before calling fb_find_mode, as the later
+	 * will cause an implicit call to radeonfb_set_var that could crash
+	 * if disp is NULL
+	 */
         info->disp = disp;
-
-        radeon_set_dispsw (rinfo, disp);
-
-	if (noaccel)
-	        disp->scrollmode = SCROLL_YREDRAW;
-	else
-		disp->scrollmode = 0;
-        
         rinfo->currcon_display = disp;
 
-        if ((radeon_init_disp_var (rinfo)) < 0)
-                return -1;
-        
-        return 0;
-}
-
-
-
-static int radeon_init_disp_var (struct radeonfb_info *rinfo)
-{
 #ifndef MODULE
         if (mode_option)
-                fb_find_mode (&rinfo->disp.var, &rinfo->info, mode_option,
+                fb_find_mode (&disp->var, &rinfo->info, mode_option,
                               NULL, 0, NULL, 8);
         else
 #endif
-#if defined(__powerpc__)
-	if (rinfo->dviDisp_type == MT_LCD) {
-		if (mac_vmode_to_var(VMODE_1152_768_60, CMODE_8, &rinfo->disp.var))
-			rinfo->disp.var = radeonfb_default_var;
-	}
-	else
-#endif
-	if (rinfo->use_default_var)
-		/* We will use the modified default far */
-		rinfo->disp.var = radeonfb_default_var;
-	else
-
-                fb_find_mode (&rinfo->disp.var, &rinfo->info, "640x480-8@60",
+	if (!rinfo->use_default_var)
+                fb_find_mode (&disp->var, &rinfo->info, "640x480-8@60",
                               NULL, 0, NULL, 0);
 
-	if (noaccel)
-		rinfo->disp.var.accel_flags &= ~FB_ACCELF_TEXT;
-	else
-		rinfo->disp.var.accel_flags |= FB_ACCELF_TEXT;
- 
-        return 0;
-}
+	disp->var.accel_flags |= FB_ACCELF_TEXT;
 
+	/* Do we need that below ? ... */
+	rinfo->depth = var_to_depth(&disp->var);
+	rinfo->bpp = disp->var.bits_per_pixel;
+
+	/* Apply that dawn mode ! */
+	radeonfb_set_var(&disp->var, -1, info);
+
+	return 0;
+}
 
 
 static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp)
@@ -1717,43 +2103,58 @@
         switch (disp->var.bits_per_pixel) {
 #ifdef FBCON_HAS_CFB8
                 case 8:
-                        disp->dispsw = &fbcon_cfb8;
                         disp->visual = FB_VISUAL_PSEUDOCOLOR;
-                        disp->line_length = disp->var.xres_virtual;
+                        disp->dispsw = accel ? &fbcon_radeon8 : &fbcon_cfb8;
+                        if (accel)
+                        	disp->line_length = (disp->var.xres_virtual + 0x3f) & ~0x3f;
+                        else
+                        	disp->line_length = disp->var.xres_virtual;
                         break;
-#endif
+#endif /* FBCON_HAS_CFB8 */
+
 #ifdef FBCON_HAS_CFB16
                 case 16:
-                        disp->dispsw = &fbcon_cfb16;
+                        disp->dispsw = accel ? &fbcon_radeon16 : &fbcon_cfb16;
                         disp->dispsw_data = &rinfo->con_cmap.cfb16;
                         disp->visual = FB_VISUAL_DIRECTCOLOR;
-                        disp->line_length = disp->var.xres_virtual * 2;
+                        if (accel)
+				disp->line_length = (disp->var.xres_virtual * 2 + 0x3f) & ~0x3f;
+			else
+				disp->line_length = disp->var.xres_virtual * 2;
                         break;
-#endif  
-#ifdef FBCON_HAS_CFB32       
+#endif  /* FBCON_HAS_CFB16 */
+
+#ifdef FBCON_HAS_CFB24       
                 case 24:
                         disp->dispsw = &fbcon_cfb24;
                         disp->dispsw_data = &rinfo->con_cmap.cfb24;
                         disp->visual = FB_VISUAL_DIRECTCOLOR;
-                        disp->line_length = disp->var.xres_virtual * 4;
+                        if (accel)
+				disp->line_length = (disp->var.xres_virtual * 3 + 0x3f) & ~0x3f;
+			else
+				disp->line_length = disp->var.xres_virtual * 3;
                         break;
-#endif
+#endif /* FBCON_HAS_CFB24 */
+
 #ifdef FBCON_HAS_CFB32
                 case 32:
-                        disp->dispsw = &fbcon_cfb32;
+                        disp->dispsw = accel ? &fbcon_radeon32 : &fbcon_cfb32;
                         disp->dispsw_data = &rinfo->con_cmap.cfb32;
                         disp->visual = FB_VISUAL_DIRECTCOLOR;
-                        disp->line_length = disp->var.xres_virtual * 4;
+                        if (accel)
+				disp->line_length = (disp->var.xres_virtual * 4 + 0x3f) & ~0x3f;
+			else
+				disp->line_length = disp->var.xres_virtual * 4;
                         break;   
-#endif
+#endif /* FBCON_HAS_CFB32 */
+
                 default:
                         printk ("radeonfb: setting fbcon_dummy renderer\n");
                         disp->dispsw = &fbcon_dummy;
         }
                 
         return;
-}
-                        
+}                        
 
 
 static void do_install_cmap(int con, struct fb_info *info)
@@ -1849,7 +2250,7 @@
         disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
 
         memset (fix, 0, sizeof (struct fb_fix_screeninfo));
-	strcpy (fix->id, rinfo->name);
+	sprintf (fix->id, "ATI Radeon %s", rinfo->name);
         
         fix->smem_start = rinfo->fb_base_phys;
         fix->smem_len = rinfo->video_ram;
@@ -1895,11 +2296,11 @@
         struct display *disp;
         struct fb_var_screeninfo v;
         int nom, den, accel;
-        unsigned chgvar = 0;
+        unsigned chgvar = 1;
 
         disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
 
-        accel = var->accel_flags & FB_ACCELF_TEXT;
+        accel = (noaccel == 0) && ((var->accel_flags & FB_ACCELF_TEXT) != 0);
 
         if (con >= 0) {
                 chgvar = ((disp->var.xres != var->xres) ||
@@ -1909,9 +2310,12 @@
                           (disp->var.bits_per_pixel != var->bits_per_pixel) ||
                           memcmp (&disp->var.red, &var->red, sizeof (var->red)) ||
                           memcmp (&disp->var.green, &var->green, sizeof (var->green)) ||
-                          memcmp (&disp->var.blue, &var->blue, sizeof (var->blue)));
+                          memcmp (&disp->var.blue, &var->blue, sizeof (var->blue)) ||
+                          var->accel_flags != disp->var.accel_flags);
         }
 
+try_again:
+
         memcpy (&v, var, sizeof (v));
 
         switch (v.bits_per_pixel) {
@@ -1935,7 +2339,10 @@
 #ifdef FBCON_HAS_CFB8
                 case 8:
                         nom = den = 1;
-                        disp->line_length = v.xres_virtual;
+                        if (accel)
+                        	disp->line_length = (v.xres_virtual + 0x3f) & ~0x3f;
+                        else
+                        	disp->line_length = v.xres_virtual;
                         disp->visual = FB_VISUAL_PSEUDOCOLOR; 
                         v.red.offset = v.green.offset = v.blue.offset = 0;
                         v.red.length = v.green.length = v.blue.length = 8;
@@ -1947,7 +2354,10 @@
 		case 15:
 			nom = 2;
 			den = 1;
-			disp->line_length = v.xres_virtual * 2;
+			if (accel)
+                        	disp->line_length = (v.xres_virtual * 2 + 0x3f) & ~0x3f;
+			else
+                        	disp->line_length = v.xres_virtual * 2;
 			disp->visual = FB_VISUAL_DIRECTCOLOR;
 			v.red.offset = 10;
 			v.green.offset = 5;
@@ -1958,7 +2368,10 @@
                 case 16:
                         nom = 2;
                         den = 1;
-                        disp->line_length = v.xres_virtual * 2;
+			if (accel)
+                        	disp->line_length = (v.xres_virtual * 2 + 0x3f) & ~0x3f;
+			else
+                        	disp->line_length = v.xres_virtual * 2;
                         disp->visual = FB_VISUAL_DIRECTCOLOR;
                         v.red.offset = 11;
                         v.green.offset = 5;
@@ -1974,7 +2387,10 @@
                 case 24:
                         nom = 4;
                         den = 1;
-                        disp->line_length = v.xres_virtual * 3;
+			if (accel)
+                        	disp->line_length = (v.xres_virtual * 3 + 0x3f) & ~0x3f;
+			else
+                        	disp->line_length = v.xres_virtual * 3;
                         disp->visual = FB_VISUAL_DIRECTCOLOR;
                         v.red.offset = 16;
                         v.green.offset = 8;
@@ -1987,7 +2403,10 @@
                 case 32:
                         nom = 4;
                         den = 1;
-                        disp->line_length = v.xres_virtual * 4;
+			if (accel)
+                        	disp->line_length = (v.xres_virtual * 4 + 0x3f) & ~0x3f;
+			else
+                        	disp->line_length = v.xres_virtual * 4;
                         disp->visual = FB_VISUAL_DIRECTCOLOR;
                         v.red.offset = 16;
                         v.green.offset = 8;
@@ -2030,22 +2449,34 @@
                 default:
                         return -EINVAL;
         }
+
+        /* Set real accel */
+        if (accel)
+	        v.accel_flags |= FB_ACCELF_TEXT;
+        else
+	        v.accel_flags &= ~FB_ACCELF_TEXT;
         
         memcpy (&disp->var, &v, sizeof (v));
         
+        radeon_load_video_mode (rinfo, &v);
+	if (accel) {
+		if (radeon_engine_init(rinfo) < 0) {
+                        var->accel_flags &= ~FB_ACCELF_TEXT;
+			goto try_again;
+		}
+	}
+
         if (chgvar) {     
-                radeon_set_dispsw(rinfo, disp);
+	        radeon_set_dispsw(rinfo, disp);
 
-                if (noaccel)
+                if (!accel)
                         disp->scrollmode = SCROLL_YREDRAW;
                 else
                         disp->scrollmode = 0;
                 
-                if (info && info->changevar)
+                if (info && info->changevar && con >= 0)
                         info->changevar(con);
         }
-         
-        radeon_load_video_mode (rinfo, &v);
                 
         do_install_cmap(con, info);
   
@@ -2107,19 +2538,17 @@
                                  struct fb_info *info)
 {
         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
-        u32 offset, xoffset, yoffset;
-                
-        xoffset = (var->xoffset + 7) & ~7;
-        yoffset = var->yoffset;
-                
-        if ((xoffset + var->xres > var->xres_virtual) || (yoffset+var->yres >
-                var->yres_virtual))
-                return -EINVAL;
+                        
+        if (((var->xoffset + var->xres) > var->xres_virtual)
+            || ((var->yoffset + var->yres) > var->yres_virtual))
+               return -EINVAL;
+                        
+        if (rinfo->asleep)
+                return 0;
+
+        OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
+                             * var->bits_per_pixel / 8) & ~7);
                 
-        offset = ((yoffset * var->xres + xoffset) * var->bits_per_pixel) >> 6;
-         
-        OUTREG(CRTC_OFFSET, offset);
-        
         return 0;
 }
 
@@ -2127,6 +2556,79 @@
 static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
                            unsigned long arg, int con, struct fb_info *info)
 {
+        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+	unsigned int tmp;
+	u32 value = 0;
+	int rc;
+
+	switch (cmd) {
+		/*
+		 * TODO:  set mirror accordingly for non-Mobility chipsets with 2 CRTC's
+		 */
+		case FBIO_RADEON_SET_MIRROR:
+			switch (rinfo->arch) {
+				case RADEON_M6:
+				case RADEON_M7:
+				case RADEON_M9:
+					break;
+				default:
+					return -EINVAL;
+			}
+
+			rc = get_user(value, (__u32*)arg);
+
+			if (rc)
+				return rc;
+
+			if (value & 0x01) {
+				tmp = INREG(LVDS_GEN_CNTL);
+
+				tmp |= (LVDS_ON | LVDS_BLON);
+			} else {
+				tmp = INREG(LVDS_GEN_CNTL);
+
+				tmp &= ~(LVDS_ON | LVDS_BLON);
+			}
+
+			OUTREG(LVDS_GEN_CNTL, tmp);
+
+			if (value & 0x02) {
+				tmp = INREG(CRTC_EXT_CNTL);
+				tmp |= CRTC_CRT_ON;
+
+				mirror = 1;
+			} else {
+				tmp = INREG(CRTC_EXT_CNTL);
+				tmp &= ~CRTC_CRT_ON;
+
+				mirror = 0;
+			}
+
+			OUTREG(CRTC_EXT_CNTL, tmp);
+
+			return 0;
+
+		case FBIO_RADEON_GET_MIRROR:
+			switch (rinfo->arch) {
+				case RADEON_M6:
+				case RADEON_M7:
+				case RADEON_M9:
+					break;
+				default:
+					return -EINVAL;
+			}
+
+			tmp = INREG(LVDS_GEN_CNTL);
+			if ((LVDS_ON | LVDS_BLON) & tmp)
+				value |= 0x01;
+
+			tmp = INREG(CRTC_EXT_CNTL);
+			if (CRTC_CRT_ON & tmp)
+				value |= 0x02;
+
+			return put_user(value, (__u32*)arg);
+	}
+
 	return -EINVAL;
 }
 
@@ -2134,42 +2636,55 @@
 static int radeonfb_switch (int con, struct fb_info *info)
 {
         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
-        struct display *disp;
+        struct display *disp, *old_disp;
         struct fb_cmap *cmap;
         int switchmode = 0;
         
         disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
+        old_disp = rinfo->currcon_display;
                 
         if (rinfo->currcon >= 0) {
                 cmap = &(rinfo->currcon_display->cmap);
                 if (cmap->len)
                         fb_get_cmap (cmap, 1, radeon_getcolreg, info);
         }   
-                
-	switchmode = (con != rinfo->currcon);
 
+        if ((old_disp == NULL) || ((disp->var.xres != old_disp->var.xres) ||
+            (disp->var.yres != old_disp->var.yres) ||
+            (disp->var.xres_virtual != old_disp->var.xres_virtual) ||
+            (disp->var.yres_virtual != old_disp->var.yres_virtual) ||
+            (disp->var.bits_per_pixel != old_disp->var.bits_per_pixel) ||
+            memcmp (&disp->var.red, &old_disp->var.red, sizeof (old_disp->var.red)) ||
+            memcmp (&disp->var.green, &old_disp->var.green, sizeof (old_disp->var.green)) ||
+            memcmp (&disp->var.blue, &old_disp->var.blue, sizeof (old_disp->var.blue)) ||
+            old_disp->var.accel_flags != disp->var.accel_flags))
+        	switchmode = 1;                  
+
+	if (rinfo->currcon == -1)
+		switchmode = 1;
+
+try_again:
 	rinfo->currcon = con;
 	rinfo->currcon_display = disp;
 	disp->var.activate = FB_ACTIVATE_NOW;
         
         if (switchmode) {
                 radeonfb_set_var (&disp->var, con, info);
-                radeon_set_dispsw (rinfo, disp);
                 do_install_cmap(con, info);
-        }       
-
-        /* XXX absurd hack for X to restore console */
-        {   
-		OUTREGP(CRTC_EXT_CNTL, rinfo->hack_crtc_ext_cntl,
-			CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
-                OUTREG(CRTC_V_SYNC_STRT_WID, rinfo->hack_crtc_v_sync_strt_wid);
+        } else {
+		if (radeon_engine_init(rinfo) < 0) {
+                        disp->var.accel_flags &= ~FB_ACCELF_TEXT;
+                        switchmode = 1;
+			goto try_again;
+		}
         }
 
+        radeon_set_dispsw (rinfo, disp);
+
         return 0;
 }
 
 
-
 static int radeonfb_updatevar (int con, struct fb_info *info)
 {
         int rc;
@@ -2184,8 +2699,12 @@
 {
         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
         u32 val = INREG(CRTC_EXT_CNTL);
-	u32 val2 = INREG(LVDS_GEN_CNTL);
+	u32 val_lvds = INREG(LVDS_GEN_CNTL);
+	u32 val_dfp = INREG(FP_GEN_CNTL);
 
+	if (rinfo->asleep)
+		return;
+		
 #ifdef CONFIG_PMAC_BACKLIGHT
 	if (rinfo->dviDisp_type == MT_LCD && _machine == _MACH_Pmac) {
 		set_backlight_enable(!blank);
@@ -2196,7 +2715,8 @@
         /* reset it */
         val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
                  CRTC_VSYNC_DIS);
-	val2 &= ~(LVDS_DISPLAY_DIS);
+	val_lvds &= ~(LVDS_DISPLAY_DIS);
+	val_dfp |= FP_FPON | FP_TMDS_EN;
 
         switch (blank) {
                 case VESA_NO_BLANKING:
@@ -2210,13 +2730,17 @@
                 case VESA_POWERDOWN:
                         val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | 
                                 CRTC_HSYNC_DIS);
-			val2 |= (LVDS_DISPLAY_DIS);
+			val_lvds |= (LVDS_DISPLAY_DIS);
+			val_dfp &= ~(FP_FPON | FP_TMDS_EN);
                         break;
         }
 
 	switch (rinfo->dviDisp_type) {
 		case MT_LCD:
-			OUTREG(LVDS_GEN_CNTL, val2);
+			OUTREG(LVDS_GEN_CNTL, val_lvds);
+			break;
+		case MT_DFP:
+			OUTREG(FP_GEN_CNTL, val_dfp);
 			break;
 		case MT_CRT:
 		default:
@@ -2243,7 +2767,6 @@
 }
 
 
-
 static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
                              unsigned *blue, unsigned *transp,
                              struct fb_info *info)
@@ -2281,29 +2804,44 @@
 
         /* default */
         pindex = regno;
-        
-	if (rinfo->bpp == 16) {
-		pindex = regno * 8;
 
-		if (rinfo->depth == 16 && regno > 63)
-			return 1;
-		if (rinfo->depth == 15 && regno > 31)
-			return 1;
+        if (!rinfo->asleep) {
+        	u32 dac_cntl2, vclk_cntl;
+        	
+		vclk_cntl = INPLL(VCLK_ECP_CNTL);
+		OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
+
+		/* Make sure we are on first palette */
+		if (rinfo->hasCRTC2) {
+			dac_cntl2 = INREG(DAC_CNTL2);
+			dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL;
+			OUTREG(DAC_CNTL2, dac_cntl2);
+		}
 
-		/* For 565, the green component is mixed one order below */
-		if (rinfo->depth == 16) {
-	                OUTREG(PALETTE_INDEX, pindex>>1);
-       	         	OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) |
-                        	(green << 8) | (rinfo->palette[regno>>1].blue));
-                	green = rinfo->palette[regno<<1].green;
-        	}
-	}
+		if (rinfo->bpp == 16) {
+			pindex = regno * 8;
 
-	if (rinfo->depth != 16 || regno < 32) {
-		OUTREG(PALETTE_INDEX, pindex);
-		OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue);
-	}
+			if (rinfo->depth == 16 && regno > 63)
+				return 1;
+			if (rinfo->depth == 15 && regno > 31)
+				return 1;
+
+			/* For 565, the green component is mixed one order below */
+			if (rinfo->depth == 16) {
+		                OUTREG8(PALETTE_INDEX, pindex>>1);
+	       	         	OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) |
+	                        	(green << 8) | (rinfo->palette[regno>>1].blue));
+	                	green = rinfo->palette[regno<<1].green;
+	        	}
+		}
 
+		if (rinfo->depth != 16 || regno < 32) {
+			OUTREG8(PALETTE_INDEX, pindex);
+			OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue);
+		}
+
+		OUTPLL(VCLK_ECP_CNTL, vclk_cntl);
+	}
  	if (regno < 16) {
         	switch (rinfo->depth) {
 #ifdef FBCON_HAS_CFB16
@@ -2316,7 +2854,7 @@
 				                       	 	  regno;   
 			        break;
 #endif
-#ifdef FBCON_HAS_CFB24
+#ifdef FBCON_HAS_CFB24   
                         case 24:
                                 rinfo->con_cmap.cfb24[regno] = (regno << 16) | (regno << 8) | regno;
                                 break;
@@ -2330,11 +2868,11 @@
 		        	break;
         		}
 #endif
-		}
+                }
         }
-	return 0;
-}
+        return 0;
 
+}
 
 
 static void radeon_save_state (struct radeonfb_info *rinfo,
@@ -2343,6 +2881,7 @@
 	/* CRTC regs */
 	save->crtc_gen_cntl = INREG(CRTC_GEN_CNTL);
 	save->crtc_ext_cntl = INREG(CRTC_EXT_CNTL);
+	save->crtc_more_cntl = INREG(CRTC_MORE_CNTL);
 	save->dac_cntl = INREG(DAC_CNTL);
         save->crtc_h_total_disp = INREG(CRTC_H_TOTAL_DISP);
         save->crtc_h_sync_strt_wid = INREG(CRTC_H_SYNC_STRT_WID);
@@ -2365,9 +2904,58 @@
 	save->lvds_pll_cntl = INREG(LVDS_PLL_CNTL);
 	save->tmds_crc = INREG(TMDS_CRC);
 	save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL);
+	save->vclk_ecp_cntl = INPLL(VCLK_ECP_CNTL);
 }
 
 
+static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *regs, unsigned long freq)
+{
+	const struct {
+		int divider;
+		int bitvalue;
+	} *post_div,
+	  post_divs[] = {
+		{ 1,  0 },
+		{ 2,  1 },
+		{ 4,  2 },
+		{ 8,  3 },
+		{ 3,  4 },
+		{ 16, 5 },
+		{ 6,  6 },
+		{ 12, 7 },
+		{ 0,  0 },
+	};
+
+	if (freq > rinfo->pll.ppll_max)
+		freq = rinfo->pll.ppll_max;
+	if (freq*12 < rinfo->pll.ppll_min)
+		freq = rinfo->pll.ppll_min / 12;
+
+
+	for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
+		rinfo->pll_output_freq = post_div->divider * freq;
+		if (rinfo->pll_output_freq >= rinfo->pll.ppll_min  &&
+		    rinfo->pll_output_freq <= rinfo->pll.ppll_max)
+			break;
+	}
+
+	/* Why do we have those in rinfo at this point ? --BenH */
+	rinfo->post_div = post_div->divider;
+	rinfo->fb_div = round_div(rinfo->pll.ref_div*rinfo->pll_output_freq,
+				  rinfo->pll.ref_clk);
+	regs->ppll_ref_div = rinfo->pll.ref_div;
+	regs->ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16);
+
+#ifdef CONFIG_ALL_PPC
+	/* Gross hack for iBook with M7 until I find out a proper fix */
+	if (machine_is_compatible("PowerBook4,3") && rinfo->arch == RADEON_M7)
+		regs->ppll_div_3 = 0x000600ad;
+#endif /* CONFIG_ALL_PPC */
+
+	RTRACE("post div = 0x%x\n", rinfo->post_div);
+	RTRACE("fb_div = 0x%x\n", rinfo->fb_div);
+	RTRACE("ppll_div_3 = 0x%x\n", regs->ppll_div_3);
+}
 
 static void radeon_load_video_mode (struct radeonfb_info *rinfo,
                                     struct fb_var_screeninfo *mode)
@@ -2377,18 +2965,24 @@
 	    hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync;
 	u8 hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5};
 	u8 hsync_fudge_fp[] = {2, 2, 0, 0, 5, 5};
-	u32 dotClock = 1000000000 / mode->pixclock,
-	    sync, h_sync_pol, v_sync_pol;
-	int freq = dotClock / 10;  /* x 100 */
-        int xclk_freq, vclk_freq, xclk_per_trans, xclk_per_trans_precise;
+	u32 sync, h_sync_pol, v_sync_pol, dotClock, pixClock;
+	unsigned int freq;
+#if 0
+        unsigned int xclk_freq, vclk_freq;
+        int xclk_per_trans, xclk_per_trans_precise;
         int useable_precision, roff, ron;
-        int min_bits, format = 0;
+        int min_bits;
+#endif
+	int format = 0;
 	int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid;
 	int primary_mon = PRIMARY_MONITOR(rinfo);
 	int depth = var_to_depth(mode);
+        int accel = mode->accel_flags & FB_ACCELF_TEXT;
 
 	rinfo->xres = mode->xres;
 	rinfo->yres = mode->yres;
+	rinfo->xres_virtual = mode->xres_virtual;
+	rinfo->yres_virtual = mode->yres_virtual;
 	rinfo->pixclock = mode->pixclock;
 
 	hSyncStart = mode->xres + mode->right_margin;
@@ -2398,8 +2992,18 @@
 	vSyncStart = mode->yres + mode->lower_margin;
 	vSyncEnd = vSyncStart + mode->vsync_len;
 	vTotal = vSyncEnd + mode->upper_margin;
-
+	pixClock = mode->pixclock;
+	
 	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
+                /* Force the native video mode of the LCD monitor.
+                 * This is complicated, because when the hardware
+                 * stretcher is used, the extra pixels are not counted
+                 * in the horizontal timing parameters. So:
+                 *   - For the visible part of the display, we use the
+                 *     requested paramters.
+                 *   - For the invisible part of the display, we use the
+                 *     parameters of the native video mode.
+                 */
 		if (rinfo->panel_xres < mode->xres)
 			rinfo->xres = mode->xres = rinfo->panel_xres;
 		if (rinfo->panel_yres < mode->yres)
@@ -2412,7 +3016,15 @@
 		vTotal = mode->yres + rinfo->vblank;
 		vSyncStart = mode->yres + rinfo->vOver_plus;
 		vSyncEnd = vSyncStart + rinfo->vSync_width;
+
+		/* If we know the LCD clock, we shall use it, unfortunately,
+		 * we may not know it until we have proper EDID probing
+		 */
+		if (rinfo->clock)
+			pixClock = 100000000 / rinfo->clock;
 	}
+	dotClock = 1000000000 / pixClock;
+	freq = dotClock / 10; /* x100 */
 
 	sync = mode->sync;
 	h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
@@ -2453,8 +3065,18 @@
 	newmode.crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN |
 				(format << 8);
 
+	/* Clear auto-center etc... Maybe we can actually use these
+	 * later, when I implement a scaling mode that keep
+	 * aspect ratio
+	 */
+	newmode.crtc_more_cntl = rinfo->init_state.crtc_more_cntl;
+	newmode.crtc_more_cntl &= 0xfffffff0;
+	
 	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
 		newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
+		if (mirror)
+			newmode.crtc_ext_cntl |= CRTC_CRT_ON;
+
 		newmode.crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN |
 					   CRTC_INTERLACE_EN);
 	} else {
@@ -2477,25 +3099,44 @@
 	newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
 					 (vsync_wid << 16) | (v_sync_pol  << 23));
 
-	newmode.crtc_pitch = (mode->xres >> 3);
+	/* We first calculate the engine pitch (we always calculate it as this value may
+	 * be used elsewhere, like when setting us the btext engine
+	 */
+	rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
+ 				& ~(0x3f)) >> 6;
+	if (accel)
+		/* Then, re-multiply it to get the CRTC pitch */
+		newmode.crtc_pitch = (rinfo->pitch << 3) / ((mode->bits_per_pixel + 1) / 8);
+	else
+		newmode.crtc_pitch = (mode->xres_virtual >> 3);
+
 	newmode.crtc_pitch |= (newmode.crtc_pitch << 16);
 
+	/*
+	 * It looks like recent chips have a problem with SURFACE_CNTL,
+	 * setting SURF_TRANSLATION_DIS completely disables the
+	 * swapper as well, so we leave it unset now.
+	 */
+	newmode.surface_cntl = 0;
+
 #if defined(__BIG_ENDIAN)
-	newmode.surface_cntl = SURF_TRANSLATION_DIS;
+	/* Setup swapping on both apertures, though we currently
+	 * only use aperture 0, enabling swapper on aperture 1
+	 * won't harm
+	 */
 	switch (mode->bits_per_pixel) {
 		case 16:
 			newmode.surface_cntl |= NONSURF_AP0_SWP_16BPP;
+			newmode.surface_cntl |= NONSURF_AP1_SWP_16BPP;
 			break;
 		case 24:	
 		case 32:
 			newmode.surface_cntl |= NONSURF_AP0_SWP_32BPP;
+			newmode.surface_cntl |= NONSURF_AP1_SWP_32BPP;
 			break;
 	}
 #endif
 
-	rinfo->pitch = ((mode->xres * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
-			& ~(0x3f)) / 64;
-
 	RTRACE("h_total_disp = 0x%x\t   hsync_strt_wid = 0x%x\n",
 		newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid);
 	RTRACE("v_total_disp = 0x%x\t   vsync_strt_wid = 0x%x\n",
@@ -2507,50 +3148,17 @@
 	rinfo->bpp = mode->bits_per_pixel;
 	rinfo->depth = depth;
 
-	rinfo->hack_crtc_ext_cntl = newmode.crtc_ext_cntl;
-	rinfo->hack_crtc_v_sync_strt_wid = newmode.crtc_v_sync_strt_wid;
+	RTRACE("pixclock = %lu\n", (unsigned long)pixClock);
+	RTRACE("freq = %lu\n", (unsigned long)freq);
+	radeon_calc_pll_regs(rinfo, &newmode, freq);
 
-	if (freq > rinfo->pll.ppll_max)
-		freq = rinfo->pll.ppll_max;
-	if (freq*12 < rinfo->pll.ppll_min)
-		freq = rinfo->pll.ppll_min / 12;
-
-	{
-		struct {
-			int divider;
-			int bitvalue;
-		} *post_div,
-		  post_divs[] = {
-			{ 1,  0 },
-			{ 2,  1 },
-			{ 4,  2 },
-			{ 8,  3 },
-			{ 3,  4 },
-			{ 16, 5 },
-			{ 6,  6 },
-			{ 12, 7 },
-			{ 0,  0 },
-		};
-
-		for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
-			rinfo->pll_output_freq = post_div->divider * freq;
-			if (rinfo->pll_output_freq >= rinfo->pll.ppll_min  &&
-			    rinfo->pll_output_freq <= rinfo->pll.ppll_max)
-				break;
-		}
-
-		rinfo->post_div = post_div->divider;
-		rinfo->fb_div = round_div(rinfo->pll.ref_div*rinfo->pll_output_freq,
-					  rinfo->pll.ref_clk);
-		newmode.ppll_ref_div = rinfo->pll.ref_div;
-		newmode.ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16);
-	}
-
-	RTRACE("post div = 0x%x\n", rinfo->post_div);
-	RTRACE("fb_div = 0x%x\n", rinfo->fb_div);
-	RTRACE("ppll_div_3 = 0x%x\n", newmode.ppll_div_3);
+	newmode.vclk_ecp_cntl = rinfo->init_state.vclk_ecp_cntl;
 
+#if 0
 	/* DDA */
+	/* XXX: Figure out if there is really a DDA on radeons ! I think there
+	 * isn't actually...
+	 */
 	vclk_freq = round_div(rinfo->pll.ref_clk * rinfo->fb_div,
 			      rinfo->pll.ref_div * rinfo->post_div);
 	xclk_freq = rinfo->pll.xclk;
@@ -2580,6 +3188,7 @@
 			      (useable_precision << 16) |
 			      (rinfo->ram.rloop << 20));
 	newmode.dda_on_off = (ron << 16) | roff;
+#endif
 
 	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
 		unsigned int hRatio, vRatio;
@@ -2607,13 +3216,13 @@
 		newmode.fp_horz_stretch &= ~HORZ_AUTO_RATIO;
 
 		if (mode->yres != rinfo->panel_yres) {
-				vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX,
-						   rinfo->panel_yres);
-				newmode.fp_vert_stretch = (((((unsigned long)vRatio) & VERT_STRETCH_RATIO_MASK)) |
-							   (newmode.fp_vert_stretch &
-							   (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED)));
-				newmode.fp_vert_stretch |= (VERT_STRETCH_BLEND |
-							    VERT_STRETCH_ENABLE);
+			vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX,
+					   rinfo->panel_yres);
+			newmode.fp_vert_stretch = (((((unsigned long)vRatio) & VERT_STRETCH_RATIO_MASK)) |
+						   (newmode.fp_vert_stretch &
+						   (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED)));
+			newmode.fp_vert_stretch |= (VERT_STRETCH_BLEND |
+						    VERT_STRETCH_ENABLE);
 		}
 		newmode.fp_vert_stretch &= ~VERT_AUTO_RATIO_EN;
 
@@ -2641,189 +3250,980 @@
 		} else {
 			/* DFP */
 			newmode.fp_gen_cntl |= (FP_FPON | FP_TMDS_EN);
-			newmode.tmds_transmitter_cntl = (TMDS_RAN_PAT_RST |
-							 ICHCSEL) & ~(TMDS_PLLRST);
+			newmode.tmds_transmitter_cntl = (TMDS_RAN_PAT_RST | TMDS_ICHCSEL) &
+							 ~(TMDS_PLLRST);
+			/* TMDS_PLL_EN bit is reversed on RV (and mobility) chips */
+			if (rinfo->arch == RADEON_R100 ||
+			    rinfo->arch == RADEON_R200 ||
+			    rinfo->arch == RADEON_R300 ||
+			    rinfo->arch == RADEON_R350)
+				newmode.tmds_transmitter_cntl &= ~TMDS_PLL_EN;
+			else
+				newmode.tmds_transmitter_cntl |= TMDS_PLL_EN;
+
 			newmode.crtc_ext_cntl &= ~CRTC_CRT_ON;
 		}
 
-		newmode.fp_crtc_h_total_disp = newmode.crtc_h_total_disp;
-		newmode.fp_crtc_v_total_disp = newmode.crtc_v_total_disp;
-		newmode.fp_h_sync_strt_wid = newmode.crtc_h_sync_strt_wid;
-		newmode.fp_v_sync_strt_wid = newmode.crtc_v_sync_strt_wid;
-	}
+		newmode.fp_crtc_h_total_disp = (((rinfo->hblank / 8) & 0x3ff) |
+				(((mode->xres / 8) - 1) << 16));
+		newmode.fp_crtc_v_total_disp = (rinfo->vblank & 0xffff) |
+				((mode->yres - 1) << 16);
+		newmode.fp_h_sync_strt_wid = ((rinfo->hOver_plus & 0x1fff) |
+				(hsync_wid << 16) | (h_sync_pol << 23));
+		newmode.fp_v_sync_strt_wid = ((rinfo->vOver_plus & 0xfff) |
+				(vsync_wid << 16) | (v_sync_pol  << 23));
+	}
+
+	/* do it! */
+	if (!rinfo->asleep)
+		radeon_write_mode (rinfo, &newmode);
+
+#if defined(CONFIG_BOOTX_TEXT)
+	btext_update_display(rinfo->fb_base_phys, mode->xres, mode->yres,
+			     rinfo->depth, rinfo->pitch*64);
+#endif
+
+	return;
+}
+
+
+static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode)
+{
+	/* Workaround from XFree */
+	if (rinfo->arch < RADEON_R300) {
+	        /* A temporal workaround for the occational blanking on certain laptop panels. 
+	           This appears to related to the PLL divider registers (fail to lock?).  
+		   It occurs even when all dividers are the same with their old settings.  
+	           In this case we really don't need to fiddle with PLL registers. 
+	           By doing this we can avoid the blanking problem with some panels.
+	        */
+		if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) &&
+		    (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) &
+		    		(PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK))))
+            		return;
+	}
+
+	while ((INREG(CLOCK_CNTL_INDEX) & PPLL_DIV_SEL_MASK) !=
+	       PPLL_DIV_SEL_MASK) {
+		OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, 0xffff);
+	}
+
+	OUTPLLP(PPLL_CNTL, PPLL_RESET, 0xffff);
+
+	while ((INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK) !=
+	       (mode->ppll_ref_div & PPLL_REF_DIV_MASK)) {
+		OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
+	}
+
+	while ((INPLL(PPLL_DIV_3) & PPLL_FB3_DIV_MASK) !=
+	       (mode->ppll_div_3 & PPLL_FB3_DIV_MASK)) {
+		OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
+	}
+
+	while ((INPLL(PPLL_DIV_3) & PPLL_POST3_DIV_MASK) !=
+	       (mode->ppll_div_3 & PPLL_POST3_DIV_MASK)) {
+		OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
+	}
+
+	OUTPLL(HTOTAL_CNTL, 0);
+
+	OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET);
+}
+
+static void radeon_write_mode (struct radeonfb_info *rinfo,
+                               struct radeon_regs *mode)
+{
+	int i;
+	int primary_mon = PRIMARY_MONITOR(rinfo);
+
+	radeonfb_blank(VESA_POWERDOWN, (struct fb_info *)rinfo);
+
+        if (rinfo->arch == RADEON_M6) {
+		for (i=0; i<8; i++)
+			OUTREG(common_regs_m6[i].reg, common_regs_m6[i].val);
+	} else {
+		for (i=0; i<9; i++)
+			OUTREG(common_regs[i].reg, common_regs[i].val);
+	}
+
+	OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
+	OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
+		CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
+	OUTREG(CRTC_MORE_CNTL, mode->crtc_more_cntl);
+	OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
+	OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
+	OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
+	OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
+	OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
+	OUTREG(CRTC_OFFSET, 0);
+	OUTREG(CRTC_OFFSET_CNTL, 0);
+	OUTREG(CRTC_PITCH, mode->crtc_pitch);
+	OUTREG(SURFACE_CNTL, mode->surface_cntl);
+
+	radeon_write_pll_regs(rinfo, mode);
+
+#if 0
+	/* Those don't seem to actually exist in radeon's, despite some drivers still
+	 * apparently trying to fill them, including some ATI sample codes ...
+	 * Can someone confirm what's up ? --BenH.
+	 */
+	OUTREG(DDA_CONFIG, mode->dda_config);
+	OUTREG(DDA_ON_OFF, mode->dda_on_off);
+#endif
+
+	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
+		OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
+		OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
+		OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
+		OUTREG(FP_V_SYNC_STRT_WID, mode->fp_v_sync_strt_wid);
+		OUTREG(FP_HORZ_STRETCH, mode->fp_horz_stretch);
+		OUTREG(FP_VERT_STRETCH, mode->fp_vert_stretch);
+		OUTREG(FP_GEN_CNTL, mode->fp_gen_cntl);
+		OUTREG(TMDS_CRC, mode->tmds_crc);
+		OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl);
+
+		if (primary_mon == MT_LCD) {
+			unsigned int tmp = INREG(LVDS_GEN_CNTL);
+
+			mode->lvds_gen_cntl &= ~LVDS_STATE_MASK;
+			mode->lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_STATE_MASK);
+
+			if ((tmp & (LVDS_ON | LVDS_BLON)) ==
+			    (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON))) {
+				OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
+			} else {
+				if (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) {
+					udelay(1000);
+					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
+				} else {
+					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl |
+					       LVDS_BLON);
+					udelay(1000);
+					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
+				}
+			}
+		}
+	}
+
+	radeonfb_blank(VESA_NO_BLANKING, (struct fb_info *)rinfo);
+
+	OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
+
+	return;
+}
+
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+
+/* TODO: Dbl check these tables, we don't go up to full ON backlight
+ * in these, possibly because we noticed MacOS doesn't, but I'd prefer
+ * having some more official numbers from ATI
+ */
+static int backlight_conv_m6[] = {
+        0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
+        0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
+};
+static int backlight_conv_m7[] = {
+        0x00, 0x3f, 0x4a, 0x55, 0x60, 0x6b, 0x76, 0x81,
+        0x8c, 0x97, 0xa2, 0xad, 0xb8, 0xc3, 0xce, 0xd9
+};
+                
+/* We turn off the LCD completely instead of just dimming the backlight.
+ * This provides some greater power saving and the display is useless
+ * without backlight anyway.
+ */
+
+
+static int radeon_set_backlight_enable(int on, int level, void *data)
+{
+	struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
+	unsigned int lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
+	int* conv_table;
+
+	/* Pardon me for that hack... maybe some day we can figure
+	 * out in what direction backlight should work on a given
+	 * panel ?
+	 */
+	if ((rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9)
+		&& !machine_is_compatible("PowerBook4,3"))
+		conv_table = backlight_conv_m7;
+	else
+		conv_table = backlight_conv_m6;
+
+	lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON);
+	if (on && (level > BACKLIGHT_OFF)) {
+		lvds_gen_cntl |= LVDS_DIGON;
+		if ((lvds_gen_cntl & LVDS_ON) == 0) {
+			lvds_gen_cntl &= ~LVDS_BLON;
+			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+			(void)INREG(LVDS_GEN_CNTL);
+			mdelay(10);
+			lvds_gen_cntl |= LVDS_BLON;
+			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+		}
+		lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
+		lvds_gen_cntl |= (conv_table[level] <<
+				  LVDS_BL_MOD_LEVEL_SHIFT);
+		lvds_gen_cntl |= (LVDS_ON | LVDS_EN);
+		lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;
+	} else {
+		lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
+		lvds_gen_cntl |= (conv_table[0] <<
+				  LVDS_BL_MOD_LEVEL_SHIFT);
+		lvds_gen_cntl |= LVDS_DISPLAY_DIS;
+		OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+		udelay(10);
+		lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGON);
+	}
+
+	OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+	rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
+	rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK);
+
+	return 0;
+}
+
+static int radeon_set_backlight_level(int level, void *data)
+{
+	return radeon_set_backlight_enable(1, level, data);
+}
+#endif /* CONFIG_PMAC_BACKLIGHT */
+
+
+#ifdef CONFIG_PMAC_PBOOK
+
+/*
+ * Radeon M6, M7 and M9 Power Management code. This code currently
+ * only supports the mobile chips in D2 mode, that is typically what
+ * is used on Apple laptops, it's based from some informations provided by ATI
+ * along with hours of tracing of MacOS drivers.
+ * 
+ * New version of this code almost totally rewritten by ATI, many thanks
+ * for their support.
+ */
+
+static void OUTMC( struct radeonfb_info *rinfo, u8 indx, u32 value)
+{
+	OUTREG( MC_IND_INDEX, indx | MC_IND_INDEX__MC_IND_WR_EN);	
+	OUTREG( MC_IND_DATA, value);		
+}
+
+static u32 INMC(struct radeonfb_info *rinfo, u8 indx)
+{
+	OUTREG( MC_IND_INDEX, indx);					
+	return INREG( MC_IND_DATA);
+}
+
+static void radeon_pm_save_regs(struct radeonfb_info *rinfo)
+{
+	rinfo->save_regs[0] = INPLL(PLL_PWRMGT_CNTL);
+	rinfo->save_regs[1] = INPLL(CLK_PWRMGT_CNTL);
+	rinfo->save_regs[2] = INPLL(MCLK_CNTL);
+	rinfo->save_regs[3] = INPLL(SCLK_CNTL);
+	rinfo->save_regs[4] = INPLL(CLK_PIN_CNTL);
+	rinfo->save_regs[5] = INPLL(VCLK_ECP_CNTL);
+	rinfo->save_regs[6] = INPLL(PIXCLKS_CNTL);
+	rinfo->save_regs[7] = INPLL(MCLK_MISC);
+	rinfo->save_regs[8] = INPLL(P2PLL_CNTL);
+	
+	rinfo->save_regs[9] = INREG(DISP_MISC_CNTL);
+	rinfo->save_regs[10] = INREG(DISP_PWR_MAN);
+	rinfo->save_regs[11] = INREG(LVDS_GEN_CNTL);
+	rinfo->save_regs[12] = INREG(LVDS_PLL_CNTL);
+	rinfo->save_regs[13] = INREG(TV_DAC_CNTL);
+	rinfo->save_regs[14] = INREG(BUS_CNTL1);
+	rinfo->save_regs[15] = INREG(CRTC_OFFSET_CNTL);
+	rinfo->save_regs[16] = INREG(AGP_CNTL);
+	rinfo->save_regs[17] = (INREG(CRTC_GEN_CNTL) & 0xfdffffff) | 0x04000000;
+	rinfo->save_regs[18] = (INREG(CRTC2_GEN_CNTL) & 0xfdffffff) | 0x04000000;
+	rinfo->save_regs[19] = INREG(GPIOPAD_A);
+	rinfo->save_regs[20] = INREG(GPIOPAD_EN);
+	rinfo->save_regs[21] = INREG(GPIOPAD_MASK);
+	rinfo->save_regs[22] = INREG(ZV_LCDPAD_A);
+	rinfo->save_regs[23] = INREG(ZV_LCDPAD_EN);
+	rinfo->save_regs[24] = INREG(ZV_LCDPAD_MASK);
+	rinfo->save_regs[25] = INREG(GPIO_VGA_DDC);
+	rinfo->save_regs[26] = INREG(GPIO_DVI_DDC);
+	rinfo->save_regs[27] = INREG(GPIO_MONID);
+	rinfo->save_regs[28] = INREG(GPIO_CRT2_DDC);
+
+	rinfo->save_regs[29] = INREG(SURFACE_CNTL);
+	rinfo->save_regs[30] = INREG(MC_FB_LOCATION);
+	rinfo->save_regs[31] = INREG(DISPLAY_BASE_ADDR);
+	rinfo->save_regs[32] = INREG(MC_AGP_LOCATION);
+	rinfo->save_regs[33] = INREG(CRTC2_DISPLAY_BASE_ADDR);
+}
+
+static void radeon_pm_restore_regs(struct radeonfb_info *rinfo)
+{
+	OUTPLL(P2PLL_CNTL, rinfo->save_regs[8] & 0xFFFFFFFE); /* First */
+	
+	OUTPLL(PLL_PWRMGT_CNTL, rinfo->save_regs[0]);
+	OUTPLL(CLK_PWRMGT_CNTL, rinfo->save_regs[1]);
+	OUTPLL(MCLK_CNTL, rinfo->save_regs[2]);
+	OUTPLL(SCLK_CNTL, rinfo->save_regs[3]);
+	OUTPLL(CLK_PIN_CNTL, rinfo->save_regs[4]);
+	OUTPLL(VCLK_ECP_CNTL, rinfo->save_regs[5]);
+	OUTPLL(PIXCLKS_CNTL, rinfo->save_regs[6]);
+	OUTPLL(MCLK_MISC, rinfo->save_regs[7]);
+	
+	OUTREG(SURFACE_CNTL, rinfo->save_regs[29]);
+	OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]);
+	OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]);
+	OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]);
+	OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
+
+	OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
+	OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]);
+	OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11]);
+	OUTREG(LVDS_PLL_CNTL,rinfo->save_regs[12]);
+	OUTREG(TV_DAC_CNTL, rinfo->save_regs[13]);
+	OUTREG(BUS_CNTL1, rinfo->save_regs[14]);
+	OUTREG(CRTC_OFFSET_CNTL, rinfo->save_regs[15]);
+	OUTREG(AGP_CNTL, rinfo->save_regs[16]);
+	OUTREG(CRTC_GEN_CNTL, rinfo->save_regs[17]);
+	OUTREG(CRTC2_GEN_CNTL, rinfo->save_regs[18]);
+
+	// wait VBL before that one  ?
+	OUTPLL(P2PLL_CNTL, rinfo->save_regs[8]);
+	
+	OUTREG(GPIOPAD_A, rinfo->save_regs[19]);
+	OUTREG(GPIOPAD_EN, rinfo->save_regs[20]);
+	OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]);
+	OUTREG(ZV_LCDPAD_A, rinfo->save_regs[22]);
+	OUTREG(ZV_LCDPAD_EN, rinfo->save_regs[23]);
+	OUTREG(ZV_LCDPAD_MASK, rinfo->save_regs[24]);
+	OUTREG(GPIO_VGA_DDC, rinfo->save_regs[25]);
+	OUTREG(GPIO_DVI_DDC, rinfo->save_regs[26]);
+	OUTREG(GPIO_MONID, rinfo->save_regs[27]);
+	OUTREG(GPIO_CRT2_DDC, rinfo->save_regs[28]);
+}
+
+static void radeon_pm_disable_iopad(struct radeonfb_info *rinfo)
+{		
+	OUTREG(GPIOPAD_MASK, 0x0001ffff);
+	OUTREG(GPIOPAD_EN, 0x00000400);
+	OUTREG(GPIOPAD_A, 0x00000000);		
+        OUTREG(ZV_LCDPAD_MASK, 0x00000000);
+        OUTREG(ZV_LCDPAD_EN, 0x00000000);
+      	OUTREG(ZV_LCDPAD_A, 0x00000000); 	
+	OUTREG(GPIO_VGA_DDC, 0x00030000);
+	OUTREG(GPIO_DVI_DDC, 0x00000000);
+	OUTREG(GPIO_MONID, 0x00030000);
+	OUTREG(GPIO_CRT2_DDC, 0x00000000);
+}
+
+static void radeon_pm_program_v2clk(struct radeonfb_info *rinfo)
+{
+	/* Set v2clk to 65MHz */
+  	OUTPLL(pllPIXCLKS_CNTL,
+  		INPLL(pllPIXCLKS_CNTL) & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK);
+	 
+  	OUTPLL(pllP2PLL_REF_DIV, 0x0000000c);
+	OUTPLL(pllP2PLL_CNTL, 0x0000bf00);
+	OUTPLL(pllP2PLL_DIV_0, 0x00020074 | P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_W);
+	
+	OUTPLL(pllP2PLL_CNTL, INPLL(pllP2PLL_CNTL) & ~P2PLL_CNTL__P2PLL_SLEEP);
+	mdelay(1);
+
+	OUTPLL(pllP2PLL_CNTL, INPLL(pllP2PLL_CNTL) & ~P2PLL_CNTL__P2PLL_RESET); 	
+	mdelay( 1);
+
+  	OUTPLL(pllPIXCLKS_CNTL,
+  		(INPLL(pllPIXCLKS_CNTL) & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK)
+  		| (0x03 << PIXCLKS_CNTL__PIX2CLK_SRC_SEL__SHIFT));
+	mdelay( 1);	
+}
+
+static void radeon_pm_low_current(struct radeonfb_info *rinfo)
+{
+	u32 reg;
+
+	reg  = INREG(BUS_CNTL1);
+	reg &= ~BUS_CNTL1_MOBILE_PLATFORM_SEL_MASK;
+	reg |= BUS_CNTL1_AGPCLK_VALID | (1<<BUS_CNTL1_MOBILE_PLATFORM_SEL_SHIFT);
+	OUTREG(BUS_CNTL1, reg);
+	
+	reg  = INPLL(PLL_PWRMGT_CNTL);
+	reg |= PLL_PWRMGT_CNTL_SPLL_TURNOFF | PLL_PWRMGT_CNTL_PPLL_TURNOFF |
+		PLL_PWRMGT_CNTL_P2PLL_TURNOFF | PLL_PWRMGT_CNTL_TVPLL_TURNOFF;
+	reg &= ~PLL_PWRMGT_CNTL_SU_MCLK_USE_BCLK;
+	reg &= ~PLL_PWRMGT_CNTL_MOBILE_SU;
+	OUTPLL(PLL_PWRMGT_CNTL, reg);
+	
+	reg  = INREG(TV_DAC_CNTL);
+	reg &= ~(TV_DAC_CNTL_BGADJ_MASK |TV_DAC_CNTL_DACADJ_MASK);
+	reg |=TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD |
+		TV_DAC_CNTL_BDACPD |
+		(8<<TV_DAC_CNTL_BGADJ__SHIFT) | (8<<TV_DAC_CNTL_DACADJ__SHIFT);
+	OUTREG(TV_DAC_CNTL, reg);
+	
+	reg  = INREG(TMDS_TRANSMITTER_CNTL);
+	reg &= ~(TMDS_PLL_EN | TMDS_PLLRST);
+	OUTREG(TMDS_TRANSMITTER_CNTL, reg);
+
+	reg = INREG(DAC_CNTL);
+	reg &= ~DAC_CMP_EN;
+	OUTREG(DAC_CNTL, reg);
+
+	reg = INREG(DAC_CNTL2);
+	reg &= ~DAC2_CMP_EN;
+	OUTREG(DAC_CNTL2, reg);
+	
+	reg  = INREG(TV_DAC_CNTL);
+	reg &= ~TV_DAC_CNTL_DETECT;
+	OUTREG(TV_DAC_CNTL, reg);
+}
+
+static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo)
+{
+
+	u32 sclk_cntl, mclk_cntl, sclk_more_cntl;
+
+	u32 pll_pwrmgt_cntl;
+	u32 clk_pwrmgt_cntl;
+	u32 clk_pin_cntl;
+	u32 vclk_ecp_cntl; 
+	u32 pixclks_cntl;
+	u32 disp_mis_cntl;
+	u32 disp_pwr_man;
+
+	
+	/* Force Core Clocks */
+	sclk_cntl = INPLL( pllSCLK_CNTL_M6);
+	sclk_cntl |= 	SCLK_CNTL_M6__IDCT_MAX_DYN_STOP_LAT|
+			SCLK_CNTL_M6__VIP_MAX_DYN_STOP_LAT|
+			SCLK_CNTL_M6__RE_MAX_DYN_STOP_LAT|
+			SCLK_CNTL_M6__PB_MAX_DYN_STOP_LAT|
+			SCLK_CNTL_M6__TAM_MAX_DYN_STOP_LAT|
+			SCLK_CNTL_M6__TDM_MAX_DYN_STOP_LAT|
+			SCLK_CNTL_M6__RB_MAX_DYN_STOP_LAT|
+			
+			SCLK_CNTL_M6__FORCE_DISP2|
+			SCLK_CNTL_M6__FORCE_CP|
+			SCLK_CNTL_M6__FORCE_HDP|
+			SCLK_CNTL_M6__FORCE_DISP1|
+			SCLK_CNTL_M6__FORCE_TOP|
+			SCLK_CNTL_M6__FORCE_E2|
+			SCLK_CNTL_M6__FORCE_SE|
+			SCLK_CNTL_M6__FORCE_IDCT|
+			SCLK_CNTL_M6__FORCE_VIP|
+			
+			SCLK_CNTL_M6__FORCE_RE|
+			SCLK_CNTL_M6__FORCE_PB|
+			SCLK_CNTL_M6__FORCE_TAM|
+			SCLK_CNTL_M6__FORCE_TDM|
+			SCLK_CNTL_M6__FORCE_RB|
+			SCLK_CNTL_M6__FORCE_TV_SCLK|
+			SCLK_CNTL_M6__FORCE_SUBPIC|
+			SCLK_CNTL_M6__FORCE_OV0;
+
+	OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
+
+	sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
+	sclk_more_cntl |= 	SCLK_MORE_CNTL__FORCE_DISPREGS |
+				SCLK_MORE_CNTL__FORCE_MC_GUI |
+				SCLK_MORE_CNTL__FORCE_MC_HOST;
+
+	OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);		
+
+	
+	mclk_cntl = INPLL( pllMCLK_CNTL_M6);
+	mclk_cntl &= ~(	MCLK_CNTL_M6__FORCE_MCLKA |  
+			MCLK_CNTL_M6__FORCE_MCLKB |
+			MCLK_CNTL_M6__FORCE_YCLKA | 
+			MCLK_CNTL_M6__FORCE_YCLKB | 
+			MCLK_CNTL_M6__FORCE_MC
+		      );	
+    	OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
+	
+	/* Force Display clocks	*/
+	vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
+	vclk_ecp_cntl &= ~(VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);
+	vclk_ecp_cntl |= VCLK_ECP_CNTL__ECP_FORCE_ON;
+	OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
+	
+	
+	pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
+	pixclks_cntl &= ~(	PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb | 
+				PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
+				PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb |
+				PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
+				PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb|
+				PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb|
+				PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb);
+						
+ 	OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
+
+
+
+	/* Enable System power management */
+	pll_pwrmgt_cntl = INPLL( pllPLL_PWRMGT_CNTL);
+	
+	pll_pwrmgt_cntl |= 	PLL_PWRMGT_CNTL__SPLL_TURNOFF |
+				PLL_PWRMGT_CNTL__MPLL_TURNOFF|
+				PLL_PWRMGT_CNTL__PPLL_TURNOFF|
+				PLL_PWRMGT_CNTL__P2PLL_TURNOFF|
+				PLL_PWRMGT_CNTL__TVPLL_TURNOFF;
+						
+	OUTPLL( pllPLL_PWRMGT_CNTL, pll_pwrmgt_cntl);
+	
+	clk_pwrmgt_cntl	 = INPLL( pllCLK_PWRMGT_CNTL_M6);
+	
+	clk_pwrmgt_cntl &= ~(	CLK_PWRMGT_CNTL_M6__MPLL_PWRMGT_OFF|
+				CLK_PWRMGT_CNTL_M6__SPLL_PWRMGT_OFF|
+				CLK_PWRMGT_CNTL_M6__PPLL_PWRMGT_OFF|
+				CLK_PWRMGT_CNTL_M6__P2PLL_PWRMGT_OFF|
+				CLK_PWRMGT_CNTL_M6__MCLK_TURNOFF|
+				CLK_PWRMGT_CNTL_M6__SCLK_TURNOFF|
+				CLK_PWRMGT_CNTL_M6__PCLK_TURNOFF|
+				CLK_PWRMGT_CNTL_M6__P2CLK_TURNOFF|
+				CLK_PWRMGT_CNTL_M6__TVPLL_PWRMGT_OFF|
+				CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN|
+				CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE|
+				CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK|
+				CLK_PWRMGT_CNTL_M6__CG_NO1_DEBUG_MASK			
+			);
+						
+	clk_pwrmgt_cntl |= CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN | CLK_PWRMGT_CNTL_M6__DISP_PM;
+	
+	OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);	
+	
+	clk_pin_cntl = INPLL( pllCLK_PIN_CNTL);
+	
+	clk_pin_cntl &= ~CLK_PIN_CNTL__ACCESS_REGS_IN_SUSPEND;
+	OUTPLL( pllMCLK_MISC, INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND);	
+	
+	/* AGP PLL control */
+	OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) |  BUS_CNTL1__AGPCLK_VALID);
+
+	OUTREG(BUS_CNTL1,
+		(INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK)
+		| (2<<BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT));	// 440BX
+	OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL) & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN));
+	
+	clk_pin_cntl &= ~CLK_PIN_CNTL__CG_CLK_TO_OUTPIN;
+	clk_pin_cntl |= CLK_PIN_CNTL__XTALIN_ALWAYS_ONb;	
+	OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
+
+	/* Solano2M */
+	OUTREG(AGP_CNTL,
+		(INREG(AGP_CNTL) & ~(AGP_CNTL__MAX_IDLE_CLK_MASK))
+		| (0x20<<AGP_CNTL__MAX_IDLE_CLK__SHIFT));
+
+	/* ACPI mode */
+	OUTPLL( pllPLL_PWRMGT_CNTL, INPLL( pllPLL_PWRMGT_CNTL) & ~PLL_PWRMGT_CNTL__PM_MODE_SEL);					
+
+
+	disp_mis_cntl = INREG(DISP_MISC_CNTL);
+	
+	disp_mis_cntl &= ~(	DISP_MISC_CNTL__SOFT_RESET_GRPH_PP | 
+				DISP_MISC_CNTL__SOFT_RESET_SUBPIC_PP | 
+				DISP_MISC_CNTL__SOFT_RESET_OV0_PP |
+				DISP_MISC_CNTL__SOFT_RESET_GRPH_SCLK|
+				DISP_MISC_CNTL__SOFT_RESET_SUBPIC_SCLK|
+				DISP_MISC_CNTL__SOFT_RESET_OV0_SCLK|
+				DISP_MISC_CNTL__SOFT_RESET_GRPH2_PP|
+				DISP_MISC_CNTL__SOFT_RESET_GRPH2_SCLK|
+				DISP_MISC_CNTL__SOFT_RESET_LVDS|
+				DISP_MISC_CNTL__SOFT_RESET_TMDS|
+				DISP_MISC_CNTL__SOFT_RESET_DIG_TMDS|
+				DISP_MISC_CNTL__SOFT_RESET_TV);
+	
+	OUTREG(DISP_MISC_CNTL, disp_mis_cntl);					
+						
+	disp_pwr_man = INREG(DISP_PWR_MAN);
+	
+	disp_pwr_man &= ~(	DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN	| 
+						DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN |
+						DISP_PWR_MAN__DISP_PWR_MAN_DPMS_MASK|		
+						DISP_PWR_MAN__DISP_D3_RST|
+						DISP_PWR_MAN__DISP_D3_REG_RST
+					);
+	
+	disp_pwr_man |= 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__DIG_TMDS_ENABLE_RST|
+					DISP_PWR_MAN__TV_ENABLE_RST| 
+//					DISP_PWR_MAN__AUTO_PWRUP_EN|
+					0;
+	
+	OUTREG(DISP_PWR_MAN, disp_pwr_man);					
+							
+	clk_pwrmgt_cntl = INPLL( pllCLK_PWRMGT_CNTL_M6);
+	pll_pwrmgt_cntl = INPLL( pllPLL_PWRMGT_CNTL) ;
+	clk_pin_cntl 	= INPLL( pllCLK_PIN_CNTL);
+	disp_pwr_man	= INREG(DISP_PWR_MAN);
+		
+	
+	/* D2 */
+	clk_pwrmgt_cntl |= CLK_PWRMGT_CNTL_M6__DISP_PM;
+	pll_pwrmgt_cntl |= PLL_PWRMGT_CNTL__MOBILE_SU | PLL_PWRMGT_CNTL__SU_SCLK_USE_BCLK;
+	clk_pin_cntl	|= CLK_PIN_CNTL__XTALIN_ALWAYS_ONb;
+	disp_pwr_man 	&= ~(DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN_MASK | DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN_MASK);							
+						
+
+	OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
+	OUTPLL( pllPLL_PWRMGT_CNTL, pll_pwrmgt_cntl);
+	OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
+	OUTREG(DISP_PWR_MAN, disp_pwr_man);
+
+	/* disable display request & disable display */
+	OUTREG( CRTC_GEN_CNTL, (INREG( CRTC_GEN_CNTL) & ~CRTC_GEN_CNTL__CRTC_EN) | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B);
+	OUTREG( CRTC2_GEN_CNTL, (INREG( CRTC2_GEN_CNTL) & ~CRTC2_GEN_CNTL__CRTC2_EN) | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B);
+
+	mdelay(17);				   
+
+}
+
+static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo)
+{
+
+	u32 sclk_cntl;
+	u32 mclk_cntl;
+	u32 sclk_more_cntl;
+	
+	u32 vclk_ecp_cntl;
+	u32 pixclks_cntl;
+
+	/* Mobility chips only */
+	if ((rinfo->arch != RADEON_M6) && (rinfo->arch != RADEON_M7) && (rinfo->arch != RADEON_M9))
+		return;
+	
+	/* Force Core Clocks */
+	sclk_cntl = INPLL( pllSCLK_CNTL_M6);
+	sclk_cntl |= 	SCLK_CNTL_M6__FORCE_CP|
+			SCLK_CNTL_M6__FORCE_HDP|
+			SCLK_CNTL_M6__FORCE_DISP1|
+			SCLK_CNTL_M6__FORCE_DISP2|
+			SCLK_CNTL_M6__FORCE_TOP|
+			SCLK_CNTL_M6__FORCE_E2|
+			SCLK_CNTL_M6__FORCE_SE|
+			SCLK_CNTL_M6__FORCE_IDCT|
+			SCLK_CNTL_M6__FORCE_VIP|
+			SCLK_CNTL_M6__FORCE_RE|
+			SCLK_CNTL_M6__FORCE_PB|
+			SCLK_CNTL_M6__FORCE_TAM|
+			SCLK_CNTL_M6__FORCE_TDM|
+			SCLK_CNTL_M6__FORCE_RB|
+			SCLK_CNTL_M6__FORCE_TV_SCLK|
+			SCLK_CNTL_M6__FORCE_SUBPIC|
+			SCLK_CNTL_M6__FORCE_OV0;
+    	OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
+	
+	
+	
+	sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
+	sclk_more_cntl |= 	SCLK_MORE_CNTL__FORCE_DISPREGS|
+				SCLK_MORE_CNTL__FORCE_MC_GUI|
+				SCLK_MORE_CNTL__FORCE_MC_HOST;	
+	OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);
+	
+	/* Force Display clocks	*/
+	vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
+	vclk_ecp_cntl &= ~(	VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |
+			 	VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);
+
+	OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
+	
+	pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
+	pixclks_cntl &= ~(	PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb |
+			 	PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
+				PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb |
+				PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
+				PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb|
+				PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb|
+				PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb);
+						
+ 	OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
+
+	/* Force Memory Clocks */
+	mclk_cntl  = INPLL( pllMCLK_CNTL_M6);
+	mclk_cntl |= 	MCLK_CNTL_M6__FORCE_MCLKA|  
+			MCLK_CNTL_M6__FORCE_MCLKB|	
+			MCLK_CNTL_M6__FORCE_YCLKA|
+			MCLK_CNTL_M6__FORCE_YCLKB;
+			
+    	OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
+}
+
+static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
+{
+	u32 clk_pwrmgt_cntl;
+	u32 sclk_cntl;
+	u32 sclk_more_cntl;
+	u32 clk_pin_cntl;
+	u32 pixclks_cntl;
+	u32 vclk_ecp_cntl;
+	u32 mclk_cntl;
+	u32 mclk_misc;
+
+	/* Mobility chips only */
+	if ((rinfo->arch != RADEON_M6) && (rinfo->arch != RADEON_M7) && (rinfo->arch != RADEON_M9))
+		return;
+	
+	/* Set Latencies */
+	clk_pwrmgt_cntl = INPLL( pllCLK_PWRMGT_CNTL_M6);
+	
+	clk_pwrmgt_cntl &= ~(	 CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE_MASK|
+				 CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK|
+				 CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT_MASK|
+				 CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE_MASK);
+	/* Mode 1 */
+	clk_pwrmgt_cntl = 	CLK_PWRMGT_CNTL_M6__MC_CH_MODE|
+				CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE | 
+				(1<<CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT__SHIFT) |
+				(0<<CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT__SHIFT)|
+				(0<<CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE__SHIFT);
+
+	OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
+						
+
+	clk_pin_cntl = INPLL( pllCLK_PIN_CNTL);
+	clk_pin_cntl |= CLK_PIN_CNTL__SCLK_DYN_START_CNTL;
+	 
+	OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
+
+	/* Enable Dyanmic mode for SCLK */
+
+	sclk_cntl = INPLL( pllSCLK_CNTL_M6);	
+	sclk_cntl &= SCLK_CNTL_M6__SCLK_SRC_SEL_MASK;
+	sclk_cntl |= SCLK_CNTL_M6__FORCE_VIP;		
+
+	OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
+
+
+	sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
+	sclk_more_cntl &= ~(SCLK_MORE_CNTL__FORCE_DISPREGS);
+				                    
+	OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);
 
-	/* do it! */
-	radeon_write_mode (rinfo, &newmode);
+	
+	/* Enable Dynamic mode for PIXCLK & PIX2CLK */
 
-#if defined(CONFIG_BOOTX_TEXT)
-	btext_update_display(rinfo->fb_base_phys, mode->xres, mode->yres,
-			     rinfo->depth, rinfo->pitch*64);
-#endif
+	pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
+	
+	pixclks_cntl|=  PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb | 
+			PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb|
+			PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
+			PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb|
+			PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb|
+			PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
+			PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb;
+
+	OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
+		
+		
+	vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
+	
+	vclk_ecp_cntl|=  VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb | 
+			 VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb;
 
-	return;
+	OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
+
+
+	/* Enable Dynamic mode for MCLK	*/
+	mclk_cntl = INPLL( pllMCLK_CNTL_M6);
+	mclk_cntl &= ~(	MCLK_CNTL_M6__FORCE_MCLKA |  
+			MCLK_CNTL_M6__FORCE_MCLKB |
+			MCLK_CNTL_M6__FORCE_YCLKA |
+			MCLK_CNTL_M6__FORCE_YCLKB );
+    	OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
+
+	mclk_misc = INPLL(pllMCLK_MISC);
+	mclk_misc |= 	MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT|
+			MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT|
+			MCLK_MISC__MC_MCLK_DYN_ENABLE|
+			MCLK_MISC__IO_MCLK_DYN_ENABLE;	
+	
+	OUTPLL(pllMCLK_MISC, mclk_misc);
 }
 
 
-static void radeon_write_mode (struct radeonfb_info *rinfo,
-                               struct radeon_regs *mode)
+static void radeon_pm_yclk_mclk_sync(struct radeonfb_info *rinfo)
 {
-	int i;
-	int primary_mon = PRIMARY_MONITOR(rinfo);
-
-	/* blank screen */
-	OUTREGP(CRTC_EXT_CNTL, CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | CRTC_HSYNC_DIS,
-		~(CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | CRTC_HSYNC_DIS));
+	u32 mc_chp_io_cntl_a1, mc_chp_io_cntl_b1;
 
-	for (i=0; i<9; i++)
-		OUTREG(common_regs[i].reg, common_regs[i].val);
+	mc_chp_io_cntl_a1 = INMC( rinfo, ixMC_CHP_IO_CNTL_A1) & ~MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA_MASK;
+	mc_chp_io_cntl_b1 = INMC( rinfo, ixMC_CHP_IO_CNTL_B1) & ~MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB_MASK;
 
-	OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
-	OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
-		CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
-	OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
-	OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
-	OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
-	OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
-	OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
-	OUTREG(CRTC_OFFSET, 0);
-	OUTREG(CRTC_OFFSET_CNTL, 0);
-	OUTREG(CRTC_PITCH, mode->crtc_pitch);
+	OUTMC( rinfo, ixMC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1 | (1<<MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT));
+	OUTMC( rinfo, ixMC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1 | (1<<MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT));
 
-#if defined(__BIG_ENDIAN)
-	OUTREG(SURFACE_CNTL, mode->surface_cntl);
+	/* Wassup ? This doesn't seem to be defined, let's hope we are ok this way --BenH */
+#ifdef MCLK_YCLK_SYNC_ENABLE
+	mc_chp_io_cntl_a1 |= (2<<MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT);
+	mc_chp_io_cntl_b1 |= (2<<MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT);
 #endif
 
-	while ((INREG(CLOCK_CNTL_INDEX) & PPLL_DIV_SEL_MASK) !=
-	       PPLL_DIV_SEL_MASK) {
-		OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, 0xffff);
-	}
+	OUTMC( rinfo, ixMC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1);
+	OUTMC( rinfo, ixMC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1);
 
-	OUTPLLP(PPLL_CNTL, PPLL_RESET, 0xffff);
+	mdelay( 1);
+}
 
-	while ((INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK) !=
-	       (mode->ppll_ref_div & PPLL_REF_DIV_MASK)) {
-		OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
-	}
+static void radeon_pm_program_mode_reg(struct radeonfb_info *rinfo, u16 value, u8 delay_required)
+{  
+	u32 mem_sdram_mode;
 
-	while ((INPLL(PPLL_DIV_3) & PPLL_FB3_DIV_MASK) !=
-	       (mode->ppll_div_3 & PPLL_FB3_DIV_MASK)) {
-		OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
-	}
+	mem_sdram_mode  = INREG( MEM_SDRAM_MODE_REG);
 
-	while ((INPLL(PPLL_DIV_3) & PPLL_POST3_DIV_MASK) !=
-	       (mode->ppll_div_3 & PPLL_POST3_DIV_MASK)) {
-		OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
-	}
+	mem_sdram_mode &= ~MEM_SDRAM_MODE_REG__MEM_MODE_REG_MASK;
+	mem_sdram_mode |= (value<<MEM_SDRAM_MODE_REG__MEM_MODE_REG__SHIFT) | MEM_SDRAM_MODE_REG__MEM_CFG_TYPE;
+	OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
 
-	OUTPLL(HTOTAL_CNTL, 0);
+	mem_sdram_mode |=  MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET;
+	OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
 
-	OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET);
+	mem_sdram_mode &= ~MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET;
+	OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
 
-	OUTREG(DDA_CONFIG, mode->dda_config);
-	OUTREG(DDA_ON_OFF, mode->dda_on_off);
+	if (delay_required == 1)
+		while( (INREG( MC_STATUS) & (MC_STATUS__MEM_PWRUP_COMPL_A | MC_STATUS__MEM_PWRUP_COMPL_B) ) == 0 )
+			{ }; 	
+}
 
-	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
-		OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
-		OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
-		OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
-		OUTREG(FP_V_SYNC_STRT_WID, mode->fp_v_sync_strt_wid);
-		OUTREG(FP_HORZ_STRETCH, mode->fp_horz_stretch);
-		OUTREG(FP_VERT_STRETCH, mode->fp_vert_stretch);
-		OUTREG(FP_GEN_CNTL, mode->fp_gen_cntl);
-		OUTREG(TMDS_CRC, mode->tmds_crc);
-		OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl);
 
-		if (primary_mon == MT_LCD) {
-			unsigned int tmp = INREG(LVDS_GEN_CNTL);
+static void radeon_pm_enable_dll(struct radeonfb_info *rinfo)
+{  
+#define DLL_RESET_DELAY 	5
+#define DLL_SLEEP_DELAY		1
 
-			mode->lvds_gen_cntl &= ~LVDS_STATE_MASK;
-			mode->lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_STATE_MASK);
+	u32 DLL_CKO_Value = INPLL(pllMDLL_CKO)   | MDLL_CKO__MCKOA_SLEEP |  MDLL_CKO__MCKOA_RESET;
+	u32 DLL_CKA_Value = INPLL(pllMDLL_RDCKA) | MDLL_RDCKA__MRDCKA0_SLEEP | MDLL_RDCKA__MRDCKA1_SLEEP | MDLL_RDCKA__MRDCKA0_RESET | MDLL_RDCKA__MRDCKA1_RESET;
+	u32 DLL_CKB_Value = INPLL(pllMDLL_RDCKB) | MDLL_RDCKB__MRDCKB0_SLEEP | MDLL_RDCKB__MRDCKB1_SLEEP | MDLL_RDCKB__MRDCKB0_RESET | MDLL_RDCKB__MRDCKB1_RESET;
 
-			if ((tmp & (LVDS_ON | LVDS_BLON)) ==
-			    (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON))) {
-				OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
-			} else {
-				if (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) {
-					udelay(1000);
-					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
-				} else {
-					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl |
-					       LVDS_BLON);
-					udelay(1000);
-					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
-				}
-			}
-		}
-	}
+	/* Setting up the DLL range for write */
+	OUTPLL(pllMDLL_CKO,   	DLL_CKO_Value);
+	OUTPLL(pllMDLL_RDCKA,  	DLL_CKA_Value);
+	OUTPLL(pllMDLL_RDCKB,	DLL_CKB_Value);
 
-	/* unblank screen */
-	OUTREG8(CRTC_EXT_CNTL + 1, 0);
+	mdelay( DLL_RESET_DELAY);
 
-	return;
-}
+	/* Channel A */
 
+	/* Power Up */
+	DLL_CKO_Value &= ~(MDLL_CKO__MCKOA_SLEEP );
+	OUTPLL(pllMDLL_CKO,   	DLL_CKO_Value);
+	mdelay( DLL_SLEEP_DELAY);  		
+   
+	DLL_CKO_Value &= ~(MDLL_CKO__MCKOA_RESET );
+	OUTPLL(pllMDLL_CKO,	DLL_CKO_Value);
+	mdelay( DLL_RESET_DELAY);  		
+
+	/* Power Up */
+	DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA0_SLEEP );
+	OUTPLL(pllMDLL_RDCKA,  	DLL_CKA_Value);
+	mdelay( DLL_SLEEP_DELAY);  		
+
+	DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA0_RESET );
+	OUTPLL(pllMDLL_RDCKA,	DLL_CKA_Value);
+	mdelay( DLL_RESET_DELAY);  		
+
+	/* Power Up */
+	DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA1_SLEEP);
+	OUTPLL(pllMDLL_RDCKA,	DLL_CKA_Value);
+	mdelay( DLL_SLEEP_DELAY);  		
+
+	DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA1_RESET);
+	OUTPLL(pllMDLL_RDCKA,	DLL_CKA_Value);
+	mdelay( DLL_RESET_DELAY);  		
+
+
+	/* Channel B */
+
+	/* Power Up */
+	DLL_CKO_Value &= ~(MDLL_CKO__MCKOB_SLEEP );
+	OUTPLL(pllMDLL_CKO,   	DLL_CKO_Value);
+	mdelay( DLL_SLEEP_DELAY);  		
+   
+	DLL_CKO_Value &= ~(MDLL_CKO__MCKOB_RESET );
+	OUTPLL(pllMDLL_CKO,   	DLL_CKO_Value);
+	mdelay( DLL_RESET_DELAY);  		
 
-#ifdef CONFIG_PMAC_BACKLIGHT
+	/* Power Up */
+	DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB0_SLEEP);
+	OUTPLL(pllMDLL_RDCKB,   DLL_CKB_Value);
+	mdelay( DLL_SLEEP_DELAY);  		
 
-static int backlight_conv[] = {
-	0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
-	0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
-};
+	DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB0_RESET);
+	OUTPLL(pllMDLL_RDCKB,   DLL_CKB_Value);
+	mdelay( DLL_RESET_DELAY);  		
 
-#define BACKLIGHT_LVDS_OFF
-#undef BACKLIGHT_DAC_OFF
+	/* Power Up */
+	DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB1_SLEEP);
+	OUTPLL(pllMDLL_RDCKB,   DLL_CKB_Value);
+	mdelay( DLL_SLEEP_DELAY);  		
 
-/* We turn off the LCD completely instead of just dimming the backlight.
- * This provides some greater power saving and the display is useless
- * without backlight anyway.
- */
+	DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB1_RESET);
+	OUTPLL(pllMDLL_RDCKB,   DLL_CKB_Value);
+	mdelay( DLL_RESET_DELAY);  		
 
-static int radeon_set_backlight_enable(int on, int level, void *data)
+#undef DLL_RESET_DELAY 
+#undef DLL_SLEEP_DELAY
+}
+
+static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo)
 {
-	struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
-	unsigned int lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
+	u32 crtcGenCntl, crtcGenCntl2, memRefreshCntl, crtc_more_cntl, fp_gen_cntl, fp2_gen_cntl;
+ 
+	crtcGenCntl  = INREG( CRTC_GEN_CNTL);
+	crtcGenCntl2 = INREG( CRTC2_GEN_CNTL);
 
-	lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON);
-	if (on && (level > BACKLIGHT_OFF)) {
-		lvds_gen_cntl |= LVDS_DIGON;
-		if ((lvds_gen_cntl & LVDS_ON) == 0) {
-			lvds_gen_cntl &= ~LVDS_BLON;
-			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
-			(void)INREG(LVDS_GEN_CNTL);
-			mdelay(10);
-			lvds_gen_cntl |= LVDS_BLON;
-			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
-		}
-		lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
-		lvds_gen_cntl |= (backlight_conv[level] <<
-				  LVDS_BL_MOD_LEVEL_SHIFT);
-		lvds_gen_cntl |= (LVDS_ON | LVDS_EN);
-		lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;
-	} else {
-		lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
-		lvds_gen_cntl |= (backlight_conv[0] <<
-				  LVDS_BL_MOD_LEVEL_SHIFT);
-		lvds_gen_cntl |= LVDS_DISPLAY_DIS;
-		OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
-		udelay(10);
-		lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGON);
-	}
+	memRefreshCntl 	= INREG( MEM_REFRESH_CNTL);
+	crtc_more_cntl 	= INREG( CRTC_MORE_CNTL);
+	fp_gen_cntl 	= INREG( FP_GEN_CNTL);
+	fp2_gen_cntl 	= INREG( FP2_GEN_CNTL);
+ 
 
-	OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
-	rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
-	rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK);
+	OUTREG( CRTC_MORE_CNTL, 	0);
+	OUTREG( FP_GEN_CNTL, 	0);
+	OUTREG( FP2_GEN_CNTL, 	0);
+ 
+	OUTREG( CRTC_GEN_CNTL,  (crtcGenCntl | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B) );
+	OUTREG( CRTC2_GEN_CNTL, (crtcGenCntl2 | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B) );
+  
+	/* Disable refresh */
+	OUTREG( MEM_REFRESH_CNTL, memRefreshCntl | MEM_REFRESH_CNTL__MEM_REFRESH_DIS);
+ 
+	/* Reset memory */
+	OUTREG( MEM_SDRAM_MODE_REG,
+		INREG( MEM_SDRAM_MODE_REG) & ~MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE); // Init  Not Complete
 
-	return 0;
-}
+	/* DLL */
+	radeon_pm_enable_dll(rinfo);
 
-static int radeon_set_backlight_level(int level, void *data)
-{
-	return radeon_set_backlight_enable(1, level, data);
+	// MLCK /YCLK sync 
+	radeon_pm_yclk_mclk_sync(rinfo);
+
+	if ((rinfo->arch == RADEON_M6) || (rinfo->arch == RADEON_M7) || (rinfo->arch == RADEON_M9)) {
+		radeon_pm_program_mode_reg(rinfo, 0x2000, 1);   
+		radeon_pm_program_mode_reg(rinfo, 0x2001, 1);   
+		radeon_pm_program_mode_reg(rinfo, 0x2002, 1);   
+		radeon_pm_program_mode_reg(rinfo, 0x0132, 1);   
+		radeon_pm_program_mode_reg(rinfo, 0x0032, 1); 
+	}	
+
+	OUTREG( MEM_SDRAM_MODE_REG,
+		INREG( MEM_SDRAM_MODE_REG) |  MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE); // Init Complete
+
+	OUTREG( MEM_REFRESH_CNTL, 	memRefreshCntl);
+
+	OUTREG( CRTC_GEN_CNTL, 		crtcGenCntl);
+	OUTREG( CRTC2_GEN_CNTL, 	crtcGenCntl2);
+	OUTREG( FP_GEN_CNTL, 		fp_gen_cntl);
+	OUTREG( FP2_GEN_CNTL, 		fp2_gen_cntl);
+
+	OUTREG( CRTC_MORE_CNTL, 	crtc_more_cntl);
+
+	mdelay( 15);
 }
-#endif /* CONFIG_PMAC_BACKLIGHT */
 
 
-#ifdef CONFIG_PMAC_PBOOK
 static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
 {
 	u16 pwr_cmd;
@@ -2836,28 +4236,58 @@
 	 * including PCI config registers, clocks, AGP conf, ...)
 	 */
 	if (suspend) {
-		/* Make sure CRTC2 is reset.  Remove that the day
-		 * we decide to actually use CRTC2 and replace it with
-		 * real code for disabling the CRTC2 output during sleep.
+		/* Disable dynamic power management of clocks for the
+		 * duration of the suspend/resume process
+		 */
+		radeon_pm_disable_dynamic_mode(rinfo);
+		/* Save some registers */
+		radeon_pm_save_regs(rinfo);
+
+		/* Prepare mobility chips for suspend
 		 */
+		if (rinfo->arch == RADEON_M6 || rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9) {
+			/* Program V2CLK */
+			radeon_pm_program_v2clk(rinfo);
+		
+			/* Disable IO PADs */
+			radeon_pm_disable_iopad(rinfo);
+
+			/* Set low current */
+			radeon_pm_low_current(rinfo);
 
-		pci_read_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
-				     &pwr_cmd);
+			/* Prepare chip for power management */
+			radeon_pm_setup_for_suspend(rinfo);
+
+			/* Reset the MDLL */
+			OUTPLL( pllMDLL_CKO, INPLL( pllMDLL_CKO) | MDLL_CKO__MCKOA_RESET | MDLL_CKO__MCKOB_RESET);
+		}
 
-		/* Switch PCI power managment to D2 */
-		pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
-				      (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK)
-				      | 2);
-		pci_read_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
-				     &pwr_cmd);
+		/* Switch PCI power managment to D2. */
+		for (;;) {
+			pci_read_config_word(
+				rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
+				&pwr_cmd);
+			if (pwr_cmd & 2)
+				break;			
+			pci_write_config_word(
+				rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
+				(pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2);
+			mdelay(500);
+		}
 	} else {
 		/* Switch back PCI powermanagment to D0 */
-		mdelay(100);
+		mdelay(200);
 		pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
-		mdelay(100);
-		pci_read_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
-				     &pwr_cmd);
-		mdelay(100);
+		mdelay(500);
+
+		/* Reset the SDRAM controller */
+		if (rinfo->arch == RADEON_M6 || rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9)
+			radeon_pm_full_reset_sdram(rinfo);
+		
+		/* Restore some registers */
+		radeon_pm_restore_regs(rinfo);
+		radeon_pm_enable_dynamic_mode(rinfo);
+		mdelay(10);
 	}
 }
 
@@ -2866,19 +4296,21 @@
  * and restore it when we wake up again.
  */
 
-int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when)
+static int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when)
 {
 	struct radeonfb_info *rinfo;
 
 	for (rinfo = board_list; rinfo != NULL; rinfo = rinfo->next) {
 		struct fb_fix_screeninfo fix;
 		int nb;
+	        struct display *disp;  
 
-		switch (rinfo->chipset) {
-			case PCI_DEVICE_ID_RADEON_LW:
-			case PCI_DEVICE_ID_RADEON_LY:
-			case PCI_DEVICE_ID_RADEON_LZ:
-			case PCI_DEVICE_ID_RADEON_PM:
+        	disp = (rinfo->currcon < 0) ? rinfo->info.disp : &fb_display[rinfo->currcon];
+
+		switch (rinfo->arch) {
+			case RADEON_M6:
+			case RADEON_M7:
+			case RADEON_M9:
 				break;
 			default:
 				return PBOOK_SLEEP_REFUSE;
@@ -2888,72 +4320,45 @@
 		nb = fb_display[fg_console].var.yres * fix.line_length;
 
 		switch (when) {
-			case PBOOK_SLEEP_REQUEST:
-#if 0
-				rinfo->save_framebuffer = vmalloc(nb);
-				if (rinfo->save_framebuffer == NULL)
-					return PBOOK_SLEEP_REFUSE;
-#endif
-				break;
-			case PBOOK_SLEEP_REJECT:
-#if 0
-				if (rinfo->save_framebuffer) {
-					vfree(rinfo->save_framebuffer);
-					rinfo->save_framebuffer = 0;
-				}
-#endif
-				break;
 			case PBOOK_SLEEP_NOW:
-				radeon_engine_idle();
-				radeon_engine_reset();
-				radeon_engine_idle();
+				acquire_console_sem();
+				disp->dispsw = &fbcon_dummy;
 
-#if 0
-				/* Backup framebuffer content */
-				if (rinfo->save_framebuffer)
-					memcpy_fromio(rinfo->save_framebuffer,
-						      (void *)rinfo->fb_base,
-						      nb);
-#endif
+				if (!noaccel) {
+					/* Make sure engine is idle and reset */
+					radeon_engine_idle();
+					radeon_engine_reset();
+					radeon_engine_idle();
+				}
 
 				/* Blank display and LCD */
 				radeonfb_blank(VESA_POWERDOWN+1,
 					       (struct fb_info *)rinfo);
 
 				/* Sleep */
+				rinfo->asleep = 1;
 				radeon_set_suspend(rinfo, 1);
-
+				release_console_sem();
+				
 				break;
 			case PBOOK_WAKE:
-				/* Wakeup */
+				acquire_console_sem();
+				/* Wakeup chip*/
 				radeon_set_suspend(rinfo, 0);
 
-				radeon_engine_reset();
-				if (!noaccel) {
+				/* Re-set mode */
+				rinfo->asleep = 0;
+				radeon_load_video_mode(rinfo, &disp->var);
+				if ((disp->var.accel_flags & FB_ACCELF_TEXT) && !noaccel)
 					radeon_engine_init(rinfo);
-					radeon_engine_reset();
-				}
-
-#if 0
-				/* Restore framebuffer content */
-				if (rinfo->save_framebuffer) {
-					memcpy_toio((void *)rinfo->fb_base,
-						    rinfo->save_framebuffer,
-						    nb);
-					vfree(rinfo->save_framebuffer);
-					rinfo->save_framebuffer = 0;
-				}
-#endif
-
-				if (rinfo->currcon_display) {
-					radeonfb_set_var(&rinfo->currcon_display->var, rinfo->currcon,
-							 (struct fb_info *) rinfo);
-					radeon_set_dispsw(rinfo, rinfo->currcon_display);
-					do_install_cmap(rinfo->currcon,
-							(struct fb_info *)rinfo);
-				}
+				do_install_cmap(rinfo->currcon < 0 ? 0 : rinfo->currcon,
+						(struct fb_info *)rinfo);
+				/* Allow fbdev to tap us again */
+				radeon_set_dispsw(rinfo, disp);
 
+				/* Unblank screen */
 				radeonfb_blank(0, (struct fb_info *)rinfo);
+				release_console_sem();
 				break;
 		}
 	}
@@ -2973,6 +4378,7 @@
 {
 	struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
 	u32 dp_cntl = DST_LAST_PEL;
+	u32 dp_cntl_save = 0;
 
 	srcx *= fontwidth(p);
 	srcy *= fontheight(p);
@@ -2982,17 +4388,19 @@
 	height *= fontheight(p);
 
 	if (srcy < dsty) {
-		srcy += height - 1;
-		dsty += height - 1;
+		srcy += height;
+		dsty += height;
 	} else
 		dp_cntl |= DST_Y_TOP_TO_BOTTOM;
 
 	if (srcx < dstx) {
-		srcx += width - 1;
-		dstx += width - 1;
+		srcx += width;
+		dstx += width;
 	} else
 		dp_cntl |= DST_X_LEFT_TO_RIGHT;
 
+	dp_cntl_save = INREG(DP_CNTL);
+
 	radeon_fifo_wait(6);
 	OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
 				    GMC_BRUSH_NONE |
@@ -3004,11 +4412,39 @@
 	OUTREG(SRC_Y_X, (srcy << 16) | srcx);
 	OUTREG(DST_Y_X, (dsty << 16) | dstx);
 	OUTREG(DST_HEIGHT_WIDTH, (height << 16) | width);
+
+	radeon_fifo_wait(1);
+	OUTREG(DP_CNTL, dp_cntl_save);
+
+	radeon_engine_idle();
+}
+
+
+
+static void radeon_rectfill(struct radeonfb_info *rinfo,
+			    int dsty, int dstx,
+			    int height, int width,
+			    u32 clr)
+{
+	radeon_fifo_wait(6);
+	OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
+				    GMC_BRUSH_SOLID_COLOR |
+				    GMC_SRC_DATATYPE_COLOR |
+				    ROP3_P));
+	OUTREG(DP_BRUSH_FRGD_CLR, clr);
+	OUTREG(DP_WRITE_MSK, 0xffffffff);
+	OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
+	OUTREG(DST_Y_X, (dsty << 16) | dstx);
+	OUTREG(DST_WIDTH_HEIGHT, (width << 16) | height);
+
+	radeon_engine_idle();
 }
 
 
 
-static void fbcon_radeon_clear(struct vc_data *conp, struct display *p,
+#ifdef FBCON_HAS_CFB8
+
+static void fbcon_radeon8_clear(struct vc_data *conp, struct display *p,
 			       int srcy, int srcx, int height, int width)
 {
 	struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
@@ -3023,25 +4459,15 @@
 	width *= fontwidth(p);
 	height *= fontheight(p);
 
-	radeon_fifo_wait(6);
-	OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
-				    GMC_BRUSH_SOLID_COLOR |
-				    GMC_SRC_DATATYPE_COLOR |
-				    ROP3_P));
-	OUTREG(DP_BRUSH_FRGD_CLR, clr);
-	OUTREG(DP_WRITE_MSK, 0xffffffff);
-	OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
-	OUTREG(DST_Y_X, (srcy << 16) | srcx);
-	OUTREG(DST_WIDTH_HEIGHT, (width << 16) | height);
+	radeon_rectfill(rinfo, srcy, srcx, height, width, clr);
 }
 
 
 
-#ifdef FBCON_HAS_CFB8
 static struct display_switch fbcon_radeon8 = {
 	setup:			fbcon_cfb8_setup,
 	bmove:			fbcon_radeon_bmove,
-	clear:			fbcon_radeon_clear,
+	clear:			fbcon_radeon8_clear,
 	putc:			fbcon_cfb8_putc,
 	putcs:			fbcon_cfb8_putcs,
 	revc:			fbcon_cfb8_revc,
@@ -3049,3 +4475,71 @@
 	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
+
+#ifdef FBCON_HAS_CFB16
+
+
+static void fbcon_radeon16_clear(struct vc_data *conp, struct display *p,
+			       int srcy, int srcx, int height, int width)
+{
+	struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
+	u32 clr;
+
+	clr = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
+	clr |= (clr << 16);
+
+	srcx *= fontwidth(p);
+	srcy *= fontheight(p);
+	width *= fontwidth(p);
+	height *= fontheight(p);
+
+	radeon_rectfill(rinfo, srcy, srcx, height, width, clr);
+}
+
+
+
+static struct display_switch fbcon_radeon16 = {
+	setup:			fbcon_cfb16_setup,
+	bmove:			fbcon_radeon_bmove,
+	clear:			fbcon_radeon16_clear,
+	putc:			fbcon_cfb16_putc,
+	putcs:			fbcon_cfb16_putcs,
+	revc:			fbcon_cfb16_revc,
+	clear_margins:		fbcon_cfb16_clear_margins,
+	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+
+#ifdef FBCON_HAS_CFB32
+
+
+static void fbcon_radeon32_clear(struct vc_data *conp, struct display *p,
+			       int srcy, int srcx, int height, int width)
+{
+	struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
+	u32 clr;
+
+	clr = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
+
+	srcx *= fontwidth(p);
+	srcy *= fontheight(p);
+	width *= fontwidth(p);
+	height *= fontheight(p);
+
+	radeon_rectfill(rinfo, srcy, srcx, height, width, clr);
+}
+
+
+
+static struct display_switch fbcon_radeon32 = {
+	setup:			fbcon_cfb32_setup,
+	bmove:			fbcon_radeon_bmove,
+	clear:			fbcon_radeon32_clear,
+	putc:			fbcon_cfb32_putc,
+	putcs:			fbcon_cfb32_putcs,
+	revc:			fbcon_cfb32_revc,
+	clear_margins:		fbcon_cfb32_clear_margins,
+	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+
diff -urN linux-2.4.21-bk7/include/asm-i386/acpi.h linux-2.4.21-bk8/include/asm-i386/acpi.h
--- linux-2.4.21-bk7/include/asm-i386/acpi.h	2003-07-12 02:52:21.000000000 -0700
+++ linux-2.4.21-bk8/include/asm-i386/acpi.h	2003-07-12 02:52:26.000000000 -0700
@@ -165,9 +165,6 @@
 /* early initialization routine */
 extern void acpi_reserve_bootmem(void);
 
-/* Check for special HW using OEM name lists */
-extern void acpi_madt_oem_check(char *oem_id, char *oem_table_id);
-
 #endif /*CONFIG_ACPI_SLEEP*/
 
 
diff -urN linux-2.4.21-bk7/include/asm-i386/smpboot.h linux-2.4.21-bk8/include/asm-i386/smpboot.h
--- linux-2.4.21-bk7/include/asm-i386/smpboot.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.21-bk8/include/asm-i386/smpboot.h	2003-07-12 02:52:26.000000000 -0700
@@ -29,8 +29,19 @@
 		esr_disable = 1;
 		/*Start cyclone clock*/
 		cyclone_setup(0);
-	}
-	else if (!strncmp(oem, "IBM NUMA", 8)){
+	/* check for ACPI tables */
+	} else if (!strncmp(oem, "IBM", 3) &&
+	    (!strncmp(prod, "SERVIGIL", 8) ||
+	     !strncmp(prod, "EXA", 3) ||
+	     !strncmp(prod, "RUTHLESS", 8))){
+		clustered_apic_mode = CLUSTERED_APIC_XAPIC;
+		apic_broadcast_id = APIC_BROADCAST_ID_XAPIC;
+		int_dest_addr_mode = APIC_DEST_PHYSICAL;
+		int_delivery_mode = dest_Fixed;
+		esr_disable = 1;
+		/*Start cyclone clock*/
+		cyclone_setup(0);
+	} else if (!strncmp(oem, "IBM NUMA", 8)){
 		clustered_apic_mode = CLUSTERED_APIC_NUMAQ;
 		apic_broadcast_id = APIC_BROADCAST_ID_APIC;
 		int_dest_addr_mode = APIC_DEST_LOGICAL;
diff -urN linux-2.4.21-bk7/include/asm-x86_64/ioctls.h linux-2.4.21-bk8/include/asm-x86_64/ioctls.h
--- linux-2.4.21-bk7/include/asm-x86_64/ioctls.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.21-bk8/include/asm-x86_64/ioctls.h	2003-07-12 02:52:26.000000000 -0700
@@ -67,6 +67,7 @@
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 #define TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
 #define TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
+#define FIOQSIZE       0x5460
 
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
diff -urN linux-2.4.21-bk7/include/linux/pci_ids.h linux-2.4.21-bk8/include/linux/pci_ids.h
--- linux-2.4.21-bk7/include/linux/pci_ids.h	2003-07-12 02:52:22.000000000 -0700
+++ linux-2.4.21-bk8/include/linux/pci_ids.h	2003-07-12 02:52:26.000000000 -0700
@@ -258,17 +258,61 @@
 #define PCI_DEVICE_ID_ATI_RAGE128_U1	0x5446
 #define PCI_DEVICE_ID_ATI_RAGE128_U2	0x544C
 #define PCI_DEVICE_ID_ATI_RAGE128_U3	0x5452
-/* Radeon M4 */
+/* Rage M4 */
 #define PCI_DEVICE_ID_ATI_RADEON_LE	0x4d45
 #define PCI_DEVICE_ID_ATI_RADEON_LF	0x4d46
-/* Radeon NV-100 */
-#define PCI_DEVICE_ID_ATI_RADEON_N1	0x5159
-#define PCI_DEVICE_ID_ATI_RADEON_N2	0x515a
-/* Radeon */
-#define PCI_DEVICE_ID_ATI_RADEON_RA	0x5144
-#define PCI_DEVICE_ID_ATI_RADEON_RB	0x5145
-#define PCI_DEVICE_ID_ATI_RADEON_RC	0x5146
-#define PCI_DEVICE_ID_ATI_RADEON_RD	0x5147
+/* Radeon R100 */
+#define PCI_DEVICE_ID_ATI_RADEON_QD	0x5144
+#define PCI_DEVICE_ID_ATI_RADEON_QE	0x5145
+#define PCI_DEVICE_ID_ATI_RADEON_QF	0x5146
+#define PCI_DEVICE_ID_ATI_RADEON_QG	0x5147
+/* Radeon RV100 (VE) */
+#define PCI_DEVICE_ID_ATI_RADEON_QY	0x5159
+#define PCI_DEVICE_ID_ATI_RADEON_QZ	0x515a
+/* Radeon R200 (8500) */
+#define PCI_DEVICE_ID_ATI_RADEON_QL	0x514c
+#define PCI_DEVICE_ID_ATI_RADEON_QN	0x514e
+#define PCI_DEVICE_ID_ATI_RADEON_QO	0x514f
+#define PCI_DEVICE_ID_ATI_RADEON_Ql	0x516c
+#define PCI_DEVICE_ID_ATI_RADEON_BB	0x4242
+/* Radeon R200 (9100) */
+#define PCI_DEVICE_ID_ATI_RADEON_QM	0x514d
+/* Radeon RV200 (7500) */
+#define PCI_DEVICE_ID_ATI_RADEON_QW	0x5157
+#define PCI_DEVICE_ID_ATI_RADEON_QX	0x5158
+/* Radeon RV250 (9000) */
+#define PCI_DEVICE_ID_ATI_RADEON_Id	0x4964
+#define PCI_DEVICE_ID_ATI_RADEON_Ie	0x4965
+#define PCI_DEVICE_ID_ATI_RADEON_If	0x4966
+#define PCI_DEVICE_ID_ATI_RADEON_Ig	0x4967
+/* Radeon RV280 (9200) */
+#define PCI_DEVICE_ID_ATI_RADEON_Y_	0x5960
+/* Radeon R300 (9700) */
+#define PCI_DEVICE_ID_ATI_RADEON_ND	0x4e44
+#define PCI_DEVICE_ID_ATI_RADEON_NE	0x4e45
+#define PCI_DEVICE_ID_ATI_RADEON_NF	0x4e46
+#define PCI_DEVICE_ID_ATI_RADEON_NG	0x4e47
+#define PCI_DEVICE_ID_ATI_RADEON_AE	0x4145
+#define PCI_DEVICE_ID_ATI_RADEON_AF	0x4146
+/* Radeon R300 (9500) */
+#define PCI_DEVICE_ID_ATI_RADEON_AD	0x4144
+/* Radeon R350 (9800) */
+#define PCI_DEVICE_ID_ATI_RADEON_NH	0x4e48
+#define PCI_DEVICE_ID_ATI_RADEON_NI	0x4e49
+/* Radeon RV350 (9600) */
+#define PCI_DEVICE_ID_ATI_RADEON_AP	0x4150
+#define PCI_DEVICE_ID_ATI_RADEON_AR	0x4152
+/* Radeon M6 */
+#define PCI_DEVICE_ID_ATI_RADEON_LY	0x4c59
+#define PCI_DEVICE_ID_ATI_RADEON_LZ	0x4c5a
+/* Radeon M7 */
+#define PCI_DEVICE_ID_ATI_RADEON_LW	0x4c57
+#define PCI_DEVICE_ID_ATI_RADEON_LX	0x4c58
+/* Radeon M9 */
+#define PCI_DEVICE_ID_ATI_RADEON_Ld	0x4c64
+#define PCI_DEVICE_ID_ATI_RADEON_Le	0x4c65
+#define PCI_DEVICE_ID_ATI_RADEON_Lf	0x4c66
+#define PCI_DEVICE_ID_ATI_RADEON_Lg	0x4c67
 /* RadeonIGP */
 #define PCI_DEVICE_ID_ATI_RADEON_IGP	0xCAB0
 
