Procházet zdrojové kódy

Add support for AMCC PPC440EP/GR eval boards Yosemite and Yellowstone.
Patch by Steven Blakeslee, 27 Jul 2005

Stefan Roese před 19 roky
rodič
revize
c157d8e219

+ 48 - 0
board/amcc/yellowstone/Makefile

@@ -0,0 +1,48 @@
+#
+# (C) Copyright 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# 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., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= lib$(BOARD).a
+
+OBJS	= $(BOARD).o
+OBJS   += flash.o
+SOBJS	= init.o
+
+$(LIB):	$(OBJS) $(SOBJS)
+	$(AR) crv $@ $(OBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+		$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################

+ 44 - 0
board/amcc/yellowstone/config.mk

@@ -0,0 +1,44 @@
+#
+# (C) Copyright 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# 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., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+#
+# esd ADCIOP boards
+#
+
+#TEXT_BASE = 0x00001000
+
+ifeq ($(ramsym),1)
+TEXT_BASE = 0xFBD00000
+else
+TEXT_BASE = 0xFFF80000
+endif
+
+PLATFORM_CPPFLAGS += -DCONFIG_440=1
+
+ifeq ($(debug),1)
+PLATFORM_CPPFLAGS += -DDEBUG
+endif
+
+ifeq ($(dbcr),1)
+PLATFORM_CPPFLAGS += -DCFG_INIT_DBCR=0x8cff0000
+endif

+ 572 - 0
board/amcc/yellowstone/flash.c

@@ -0,0 +1,572 @@
+/*
+ * (C) Copyright 2002-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002 Jun Gu <jung@artesyncp.com>
+ * Add support for Am29F016D and dynamic switch setting.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Modified 4/5/2001
+ * Wait for completion of each sector erase command issued
+ * 4/5/2001
+ * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
+ */
+
+/*
+ * Ported to XPedite1000, 1/2 mb boot flash only
+ * Travis B. Sawyer, <travis.sawyer@sandburst.com>
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+#undef DEBUG
+#ifdef DEBUG
+#define DEBUGF(x...) printf(x)
+#else
+#define DEBUGF(x...)
+#endif				/* DEBUG */
+
+#define BOOT_SMALL_FLASH	32	/* 00100000 */
+#define FLASH_ONBD_N		2	/* 00000010 */
+#define FLASH_SRAM_SEL		1	/* 00000001 */
+
+#define BOOT_SMALL_FLASH_VAL	4
+#define FLASH_ONBD_N_VAL	2
+#define FLASH_SRAM_SEL_VAL	1
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];	/* info for FLASH chips   */
+
+unsigned long flash_addr_table[512][CFG_MAX_FLASH_BANKS] = {
+	{0xfe000000}
+
+};
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size(vu_long * addr, flash_info_t * info);
+static int write_word(flash_info_t * info, ulong dest, ulong data);
+
+#define ADDR0		0xaaaa
+#define ADDR1		0x5554
+#define FLASH_WORD_SIZE unsigned short
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init(void)
+{
+	unsigned long total_b = 0;
+	unsigned long size_b[CFG_MAX_FLASH_BANKS];
+	unsigned short index = 0;
+	int i;
+
+	DEBUGF("\n");
+	DEBUGF("FLASH: Index: %d\n", index);
+
+	/* Init: no FLASHes known */
+	for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
+		flash_info[i].flash_id = FLASH_UNKNOWN;
+		flash_info[i].sector_count = -1;
+		flash_info[i].size = 0;
+
+		/* check whether the address is 0 */
+		if (flash_addr_table[index][i] == 0) {
+			continue;
+		}
+
+		/* call flash_get_size() to initialize sector address */
+		size_b[i] = flash_get_size((vu_long *)
+					   flash_addr_table[index][i],
+					   &flash_info[i]);
+		flash_info[i].size = size_b[i];
+		if (flash_info[i].flash_id == FLASH_UNKNOWN) {
+			printf
+			    ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
+			     i, size_b[i], size_b[i] << 20);
+			flash_info[i].sector_count = -1;
+			flash_info[i].size = 0;
+		}
+
+		total_b += flash_info[i].size;
+	}
+
+	/* FLASH protect Monitor */
+	flash_protect(FLAG_PROTECT_SET,
+		      CFG_MONITOR_BASE, 0xFFFFFFFF, &flash_info[0]);
+
+	return total_b;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info(flash_info_t * info)
+{
+	int i;
+	int k;
+	int size;
+	int erased;
+	volatile unsigned long *flash;
+
+	if (info->flash_id == FLASH_UNKNOWN) {
+		printf("missing or unknown FLASH type\n");
+		return;
+	}
+
+	switch (info->flash_id & FLASH_VENDMASK) {
+	case FLASH_MAN_AMD:
+		printf("AMD ");
+		break;
+	case FLASH_MAN_FUJ:
+		printf("FUJITSU ");
+		break;
+	case FLASH_MAN_SST:
+		printf("SST ");
+		break;
+	default:
+		printf("Unknown Vendor ");
+		break;
+	}
+
+	switch (info->flash_id & FLASH_TYPEMASK) {
+	case FLASH_AMD016:
+		printf("AM29F016D (16 Mbit, uniform sector size)\n");
+		break;
+	case FLASH_AM040:
+		printf("AM29F040 (512 Kbit, uniform sector size)\n");
+		break;
+	case FLASH_AM400B:
+		printf("AM29LV400B (4 Mbit, bottom boot sect)\n");
+		break;
+	case FLASH_AM400T:
+		printf("AM29LV400T (4 Mbit, top boot sector)\n");
+		break;
+	case FLASH_AM800B:
+		printf("AM29LV800B (8 Mbit, bottom boot sect)\n");
+		break;
+	case FLASH_AM800T:
+		printf("AM29LV800T (8 Mbit, top boot sector)\n");
+		break;
+	case FLASH_AM160B:
+		printf("AM29LV160B (16 Mbit, bottom boot sect)\n");
+		break;
+	case FLASH_AM160T:
+		printf("AM29LV160T (16 Mbit, top boot sector)\n");
+		break;
+	case FLASH_AM320B:
+		printf("AM29LV320B (32 Mbit, bottom boot sect)\n");
+		break;
+	case FLASH_AM320T:
+		printf("AM29LV320T (32 Mbit, top boot sector)\n");
+		break;
+	case FLASH_SST800A:
+		printf("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
+		break;
+	case FLASH_SST160A:
+		printf("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
+		break;
+	default:
+		printf("Unknown Chip Type\n");
+		break;
+	}
+
+	printf("  Size: %ld KB in %d Sectors\n",
+	       info->size >> 10, info->sector_count);
+
+	printf("  Sector Start Addresses:");
+	for (i = 0; i < info->sector_count; ++i) {
+		/*
+		 * Check if whole sector is erased
+		 */
+		if (i != (info->sector_count - 1))
+			size = info->start[i + 1] - info->start[i];
+		else
+			size = info->start[0] + info->size - info->start[i];
+		erased = 1;
+		flash = (volatile unsigned long *)info->start[i];
+		size = size >> 2;	/* divide by 4 for longword access */
+		for (k = 0; k < size; k++) {
+			if (*flash++ != 0xffffffff) {
+				erased = 0;
+				break;
+			}
+		}
+
+		if ((i % 5) == 0)
+			printf("\n   ");
+		printf(" %08lX%s%s",
+		       info->start[i],
+		       erased ? " E" : "  ", info->protect[i] ? "RO " : "   ");
+	}
+	printf("\n");
+	return;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+static ulong flash_get_size(vu_long * addr, flash_info_t * info)
+{
+	short i;
+	FLASH_WORD_SIZE value;
+	ulong base = (ulong) addr;
+	volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) addr;
+
+	DEBUGF("FLASH ADDR: %08x\n", (unsigned)addr);
+
+	/* Write auto select command: read Manufacturer ID */
+	udelay(10000);
+	*(FLASH_WORD_SIZE *) ((int)addr + ADDR0) = (FLASH_WORD_SIZE) 0x00AA;
+	udelay(1000);
+	*(FLASH_WORD_SIZE *) ((int)addr + ADDR1) = (FLASH_WORD_SIZE) 0x0055;
+	udelay(1000);
+	*(FLASH_WORD_SIZE *) ((int)addr + ADDR0) = (FLASH_WORD_SIZE) 0x0090;
+	udelay(1000);
+
+	value = addr2[0];
+
+	DEBUGF("FLASH MANUFACT: %x\n", value);
+
+	switch (value) {
+	case (FLASH_WORD_SIZE) AMD_MANUFACT:
+		info->flash_id = FLASH_MAN_AMD;
+		break;
+	case (FLASH_WORD_SIZE) FUJ_MANUFACT:
+		info->flash_id = FLASH_MAN_FUJ;
+		break;
+	case (FLASH_WORD_SIZE) SST_MANUFACT:
+		info->flash_id = FLASH_MAN_SST;
+		break;
+	case (FLASH_WORD_SIZE) STM_MANUFACT:
+		info->flash_id = FLASH_MAN_STM;
+		break;
+	default:
+		info->flash_id = FLASH_UNKNOWN;
+		info->sector_count = 0;
+		info->size = 0;
+		return (0);	/* no or unknown flash  */
+	}
+
+#ifdef CONFIG_ADCIOP
+	value = addr2[0];	/* device ID            */
+	debug("\ndev_code=%x\n", value);
+#else
+	value = addr2[1];	/* device ID            */
+#endif
+
+	DEBUGF("\nFLASH DEVICEID: %x\n", value);
+
+	info->flash_id = 0;
+	info->sector_count = CFG_MAX_FLASH_SECT;
+	info->size = 0x02000000;
+
+	/* set up sector start address table */
+	for (i = 0; i < info->sector_count; i++) {
+		info->start[i] = (int)base + (i * 0x00020000);
+		info->protect[i] = 0;
+	}
+
+	*(FLASH_WORD_SIZE *) ((int)addr) = (FLASH_WORD_SIZE) 0x00F0;	/* reset bank */
+
+	return (info->size);
+}
+
+int wait_for_DQ7(flash_info_t * info, int sect)
+{
+	ulong start, now, last;
+	volatile FLASH_WORD_SIZE *addr =
+	    (FLASH_WORD_SIZE *) (info->start[sect]);
+
+	start = get_timer(0);
+	last = start;
+	while ((addr[0] & (FLASH_WORD_SIZE) 0x00800080) !=
+	       (FLASH_WORD_SIZE) 0x00800080) {
+		if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+			printf("Timeout\n");
+			return -1;
+		}
+		/* show that we're waiting */
+		if ((now - last) > 1000) {	/* every second */
+			putc('.');
+			last = now;
+		}
+	}
+	return 0;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase(flash_info_t * info, int s_first, int s_last)
+{
+	volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *) (info->start[0]);
+	volatile FLASH_WORD_SIZE *addr2;
+	int flag, prot, sect, l_sect;
+	int i;
+
+	if ((s_first < 0) || (s_first > s_last)) {
+		if (info->flash_id == FLASH_UNKNOWN) {
+			printf("- missing\n");
+		} else {
+			printf("- no sectors to erase\n");
+		}
+		return 1;
+	}
+
+	if (info->flash_id == FLASH_UNKNOWN) {
+		printf("Can't erase unknown flash type - aborted\n");
+		return 1;
+	}
+
+	prot = 0;
+	for (sect = s_first; sect <= s_last; ++sect) {
+		if (info->protect[sect]) {
+			prot++;
+		}
+	}
+
+	if (prot) {
+		printf("- Warning: %d protected sectors will not be erased!\n",
+		       prot);
+	} else {
+		printf("\n");
+	}
+
+	l_sect = -1;
+
+	/* Disable interrupts which might cause a timeout here */
+	flag = disable_interrupts();
+
+	/* Start erase on unprotected sectors */
+	for (sect = s_first; sect <= s_last; sect++) {
+		if (info->protect[sect] == 0) {	/* not protected */
+			addr2 = (FLASH_WORD_SIZE *) (info->start[sect]);
+			printf("Erasing sector %p\n", addr2);
+			*(FLASH_WORD_SIZE *) ((int)addr + ADDR0) =
+			    (FLASH_WORD_SIZE) 0x00AA;
+			asm("sync");
+			asm("isync");
+			*(FLASH_WORD_SIZE *) ((int)addr + ADDR1) =
+			    (FLASH_WORD_SIZE) 0x0055;
+			asm("sync");
+			asm("isync");
+			*(FLASH_WORD_SIZE *) ((int)addr + ADDR0) =
+			    (FLASH_WORD_SIZE) 0x0080;
+			asm("sync");
+			asm("isync");
+			*(FLASH_WORD_SIZE *) ((int)addr + ADDR0) =
+			    (FLASH_WORD_SIZE) 0x00AA;
+			asm("sync");
+			asm("isync");
+			*(FLASH_WORD_SIZE *) ((int)addr + ADDR1) =
+			    (FLASH_WORD_SIZE) 0x0055;
+			asm("sync");
+			asm("isync");
+			addr2[0] = (FLASH_WORD_SIZE) 0x00300030;	/* sector erase */
+			asm("sync");
+			asm("isync");
+
+			l_sect = sect;
+			/*
+			 * Wait for each sector to complete, it's more
+			 * reliable.  According to AMD Spec, you must
+			 * issue all erase commands within a specified
+			 * timeout.  This has been seen to fail, especially
+			 * if printf()s are included (for debug)!!
+			 */
+			wait_for_DQ7(info, sect);
+		}
+	}
+
+	/* re-enable interrupts if necessary */
+	if (flag)
+		enable_interrupts();
+
+	/* wait at least 80us - let's wait 1 ms */
+	udelay(1000);
+
+#if 0
+	/*
+	 * We wait for the last triggered sector
+	 */
+	if (l_sect < 0)
+		goto DONE;
+	wait_for_DQ7(info, l_sect);
+
+      DONE:
+#endif
+	/* reset to read mode */
+	addr = (FLASH_WORD_SIZE *) info->start[0];
+	addr[0] = (FLASH_WORD_SIZE) 0x00F000F0;	/* reset bank */
+
+	printf(" done\n");
+	return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+	ulong cp, wp, data;
+	int i, l, rc;
+	ulong status_value = 0;
+
+	wp = (addr & ~3);	/* get lower word aligned address */
+
+	/*
+	 * handle unaligned start bytes
+	 */
+	if ((l = addr - wp) != 0) {
+		data = 0;
+		for (i = 0, cp = wp; i < l; ++i, ++cp) {
+			data = (data << 8) | (*(uchar *) cp);
+		}
+		for (; i < 4 && cnt > 0; ++i) {
+			data = (data << 8) | *src++;
+			--cnt;
+			++cp;
+		}
+		for (; cnt == 0 && i < 4; ++i, ++cp) {
+			data = (data << 8) | (*(uchar *) cp);
+		}
+
+		if ((rc = write_word(info, wp, data)) != 0) {
+			return (rc);
+		}
+		wp += 4;
+	}
+
+	/*
+	 * handle word aligned part
+	 */
+	while (cnt >= 4) {
+
+		/*print status if needed */
+		if ((wp >= (status_value + 0x20000))
+		    && (status_value < 0xFFFE0000)) {
+			status_value = wp;
+			printf("writing to sector 0x%X\n", status_value);
+		}
+
+		data = 0;
+		for (i = 0; i < 4; ++i) {
+			data = (data << 8) | *src++;
+		}
+		if ((rc = write_word(info, wp, data)) != 0) {
+			return (rc);
+		}
+		wp += 4;
+		cnt -= 4;
+	}
+
+	if (cnt == 0) {
+		return (0);
+	}
+
+	/*
+	 * handle unaligned tail bytes
+	 */
+	data = 0;
+	for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
+		data = (data << 8) | *src++;
+		--cnt;
+	}
+	for (; i < 4; ++i, ++cp) {
+		data = (data << 8) | (*(uchar *) cp);
+	}
+
+	return (write_word(info, wp, data));
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word(flash_info_t * info, ulong dest, ulong data)
+{
+	volatile vu_long *addr2 = (vu_long *) (info->start[0]);
+	volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest;
+	volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data;
+	ulong start;
+	int i;
+
+	/* Check if Flash is (sufficiently) erased */
+	if ((*((volatile FLASH_WORD_SIZE *)dest) &
+	     (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) {
+		return (2);
+	}
+
+	for (i = 0; i < 4 / sizeof(FLASH_WORD_SIZE); i++) {
+		int flag;
+
+		/* Disable interrupts which might cause a timeout here */
+		flag = disable_interrupts();
+
+		*(FLASH_WORD_SIZE *) ((int)addr2 + ADDR0) =
+		    (FLASH_WORD_SIZE) 0x00AA;
+		asm("sync");
+		asm("isync");
+		*(FLASH_WORD_SIZE *) ((int)addr2 + ADDR1) =
+		    (FLASH_WORD_SIZE) 0x0055;
+		asm("sync");
+		asm("isync");
+		*(FLASH_WORD_SIZE *) ((int)addr2 + ADDR0) =
+		    (FLASH_WORD_SIZE) 0x00A0;
+		asm("sync");
+		asm("isync");
+
+		dest2[i] = data2[i];
+
+		/* re-enable interrupts if necessary */
+		if (flag)
+			enable_interrupts();
+
+		/* data polling for D7 */
+		start = get_timer(0);
+		while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) !=
+		       (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) {
+
+			if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+				return (1);
+			}
+		}
+	}
+
+	return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */

+ 107 - 0
board/amcc/yellowstone/init.S

@@ -0,0 +1,107 @@
+/*
+*
+* See file CREDITS for list of people who contributed to this
+* project.
+*
+* 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 program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+* GNU General Public License for more details.
+*
+* 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., 59 Temple Place, Suite 330, Boston,
+* MA 02111-1307 USA
+*/
+
+#include <ppc_asm.tmpl>
+#include <config.h>
+
+/* General */
+#define TLB_VALID   0x00000200
+
+/* Supported page sizes */
+
+#define SZ_1K	    0x00000000
+#define SZ_4K	    0x00000010
+#define SZ_16K	    0x00000020
+#define SZ_64K	    0x00000030
+#define SZ_256K	    0x00000040
+#define SZ_1M	    0x00000050
+#define SZ_8M       0x00000060
+#define SZ_16M	    0x00000070
+#define SZ_256M	    0x00000090
+
+/* Storage attributes */
+#define SA_W	    0x00000800	    /* Write-through */
+#define SA_I	    0x00000400	    /* Caching inhibited */
+#define SA_M	    0x00000200	    /* Memory coherence */
+#define SA_G	    0x00000100	    /* Guarded */
+#define SA_E	    0x00000080	    /* Endian */
+
+/* Access control */
+#define AC_X	    0x00000024	    /* Execute */
+#define AC_W	    0x00000012	    /* Write */
+#define AC_R	    0x00000009	    /* Read */
+
+/* Some handy macros */
+
+#define EPN(e)		((e) & 0xfffffc00)
+#define TLB0(epn,sz)	( (EPN((epn)) | (sz) | TLB_VALID ) )
+#define TLB1(rpn,erpn)	( ((rpn)&0xfffffc00) | (erpn) )
+#define TLB2(a)		( (a)&0x00000fbf )
+
+#define tlbtab_start\
+	mflr    r1  ;\
+	bl 0f	    ;
+
+#define tlbtab_end\
+	.long 0, 0, 0	;   \
+0:	mflr    r0	;   \
+	mtlr    r1	;   \
+	blr		;
+
+#define tlbentry(epn,sz,rpn,erpn,attr)\
+	.long TLB0(epn,sz),TLB1(rpn,erpn),TLB2(attr)
+
+
+/**************************************************************************
+ * TLB TABLE
+ *
+ * This table is used by the cpu boot code to setup the initial tlb
+ * entries. Rather than make broad assumptions in the cpu source tree,
+ * this table lets each board set things up however they like.
+ *
+ *  Pointer to the table is returned in r1
+ *
+ *************************************************************************/
+
+    .section .bootpg,"ax"
+    .globl tlbtab
+
+tlbtab:
+    tlbtab_start
+	/*
+		0xf0000000 must be first, before relocation SA_I must be off to use the
+	    dcache as stack. It is patched after relocation to enable SA_I
+	*/
+    tlbentry( 0xf0000000, SZ_256M, 0xf0000000, 0, AC_R|AC_W|AC_X|SA_G/*|SA_I*/)
+    tlbentry( CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
+    tlbentry( CFG_PCI_BASE, SZ_256M, 0xE0000000, 0, AC_R|AC_W|SA_G|SA_I )
+    tlbentry( CFG_NVRAM_BASE_ADDR, SZ_16K, 0x80000000, 0, AC_R|AC_W|AC_X|SA_W|SA_I )
+
+    /* PCI */
+    tlbentry( CFG_PCI_MEMBASE, SZ_256M, CFG_PCI_MEMBASE, 0, AC_R|AC_W|SA_G|SA_I )
+    tlbentry( CFG_PCI_MEMBASE1, SZ_256M, CFG_PCI_MEMBASE1, 0, AC_R|AC_W|SA_G|SA_I )
+    tlbentry( CFG_PCI_MEMBASE2, SZ_256M, CFG_PCI_MEMBASE2, 0, AC_R|AC_W|SA_G|SA_I )
+    tlbentry( CFG_PCI_MEMBASE3, SZ_256M, CFG_PCI_MEMBASE3, 0, AC_R|AC_W|SA_G|SA_I )
+
+    /* USB 2.0 Device */
+    tlbentry( CFG_USB_DEVICE, SZ_1K, 0x50000000, 0, AC_R|AC_W|SA_G|SA_I )
+
+    tlbtab_end

+ 155 - 0
board/amcc/yellowstone/u-boot.lds

@@ -0,0 +1,155 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  .resetvec 0xFFFFFFFC :
+  {
+    *(.resetvec)
+  } = 0xffff
+
+  .bootpg 0xFFFFF000 :
+  {
+    cpu/ppc4xx/start.o	(.bootpg)
+  } = 0xffff
+
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .init          : { *(.init)	}
+  .plt : { *(.plt) }
+  .text      :
+  {
+    /* WARNING - the following is hand-optimized to fit within	*/
+    /* the sector layout of our flash chips!	XXX FIXME XXX	*/
+
+    cpu/ppc4xx/start.o	(.text)
+    board/amcc/yellowstone/init.o	(.text)
+    cpu/ppc4xx/kgdb.o	(.text)
+    cpu/ppc4xx/traps.o	(.text)
+    cpu/ppc4xx/interrupts.o	(.text)
+    cpu/ppc4xx/serial.o	(.text)
+    cpu/ppc4xx/cpu_init.o	(.text)
+    cpu/ppc4xx/speed.o	(.text)
+    cpu/ppc4xx/405gp_enet.o	(.text)
+    common/dlmalloc.o	(.text)
+    lib_generic/crc32.o		(.text)
+    lib_ppc/extable.o	(.text)
+    lib_generic/zlib.o		(.text)
+
+/*    . = env_offset;*/
+/*    common/environment.o(.text)*/
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+    *(.rodata.str1.4)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __u_boot_cmd_start = .;
+  .u_boot_cmd : { *(.u_boot_cmd) }
+  __u_boot_cmd_end = .;
+
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}

+ 426 - 0
board/amcc/yellowstone/yellowstone.c

@@ -0,0 +1,426 @@
+/*
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <spd_sdram.h>
+
+int board_early_init_f(void)
+{
+	register uint reg;
+
+	/*--------------------------------------------------------------------
+	 * Setup the external bus controller/chip selects
+	 *-------------------------------------------------------------------*/
+	mtdcr(ebccfga, xbcfg);
+	reg = mfdcr(ebccfgd);
+	mtdcr(ebccfgd, reg | 0x04000000);	/* Set ATC */
+
+	mtebc(pb0ap, 0x03017300);	/* FLASH/SRAM */
+	mtebc(pb0cr, 0xfe0ba000);	/* BAS=0xfe0 32MB r/w 16-bit */
+
+	mtebc(pb1ap, 0x00000000);
+	mtebc(pb1cr, 0x00000000);
+
+	mtebc(pb2ap, 0x04814500);
+	/*CPLD*/ mtebc(pb2cr, 0x80018000);	/*BAS=0x800 1MB r/w 8-bit */
+
+	mtebc(pb3ap, 0x00000000);
+	mtebc(pb3cr, 0x00000000);
+
+	mtebc(pb4ap, 0x00000000);
+	mtebc(pb4cr, 0x00000000);
+
+	mtebc(pb5ap, 0x00000000);
+	mtebc(pb5cr, 0x00000000);
+
+	/*--------------------------------------------------------------------
+	 * Setup the interrupt controller polarities, triggers, etc.
+	 *-------------------------------------------------------------------*/
+	mtdcr(uic0sr, 0xffffffff);	/* clear all */
+	mtdcr(uic0er, 0x00000000);	/* disable all */
+	mtdcr(uic0cr, 0x00000009);	/* ATI & UIC1 crit are critical */
+	mtdcr(uic0pr, 0xfffffe13);	/* per ref-board manual */
+	mtdcr(uic0tr, 0x01c00008);	/* per ref-board manual */
+	mtdcr(uic0vr, 0x00000001);	/* int31 highest, base=0x000 */
+	mtdcr(uic0sr, 0xffffffff);	/* clear all */
+
+	mtdcr(uic1sr, 0xffffffff);	/* clear all */
+	mtdcr(uic1er, 0x00000000);	/* disable all */
+	mtdcr(uic1cr, 0x00000000);	/* all non-critical */
+	mtdcr(uic1pr, 0xffffe0ff);	/* per ref-board manual */
+	mtdcr(uic1tr, 0x00ffc000);	/* per ref-board manual */
+	mtdcr(uic1vr, 0x00000001);	/* int31 highest, base=0x000 */
+	mtdcr(uic1sr, 0xffffffff);	/* clear all */
+
+	/*--------------------------------------------------------------------
+	 * Setup the GPIO pins
+	 *-------------------------------------------------------------------*/
+	/*CPLD cs */
+	/*setup Address lines for flash sizes larger than 16Meg. */
+	out32(GPIO0_OSRL, in32(GPIO0_OSRL) | 0x40010000);
+	out32(GPIO0_TSRL, in32(GPIO0_TSRL) | 0x40010000);
+	out32(GPIO0_ISR1L, in32(GPIO0_ISR1L) | 0x40000000);
+
+	/*setup emac */
+	out32(GPIO0_TCR, in32(GPIO0_TCR) | 0xC080);
+	out32(GPIO0_TSRL, in32(GPIO0_TSRL) | 0x40);
+	out32(GPIO0_ISR1L, in32(GPIO0_ISR1L) | 0x55);
+	out32(GPIO0_OSRH, in32(GPIO0_OSRH) | 0x50004000);
+	out32(GPIO0_ISR1H, in32(GPIO0_ISR1H) | 0x00440000);
+
+	/*UART1 */
+	out32(GPIO1_TCR, in32(GPIO1_TCR) | 0x02000000);
+	out32(GPIO1_OSRL, in32(GPIO1_OSRL) | 0x00080000);
+	out32(GPIO1_ISR2L, in32(GPIO1_ISR2L) | 0x00010000);
+
+	/*setup USB 2.0 */
+	out32(GPIO1_TCR, in32(GPIO1_TCR) | 0xc0000000);
+	out32(GPIO1_OSRL, in32(GPIO1_OSRL) | 0x50000000);
+	out32(GPIO0_TCR, in32(GPIO0_TCR) | 0xf);
+	out32(GPIO0_OSRH, in32(GPIO0_OSRH) | 0xaa);
+	out32(GPIO0_ISR2H, in32(GPIO0_ISR2H) | 0x00000500);
+
+	/*--------------------------------------------------------------------
+	 * Setup other serial configuration
+	 *-------------------------------------------------------------------*/
+	mfsdr(sdr_pci0, reg);
+	mtsdr(sdr_pci0, 0x80000000 | reg);	/* PCI arbiter enabled */
+	mtsdr(sdr_pfc0, 0x00003e00);	/* Pin function */
+	mtsdr(sdr_pfc1, 0x00048000);	/* Pin function: UART0 has 4 pins */
+
+	/*clear tmrclk divisor */
+	*(unsigned char *)(CFG_BCSR_BASE | 0x04) = 0x00;
+
+	/*enable ethernet */
+	*(unsigned char *)(CFG_BCSR_BASE | 0x08) = 0xf0;
+
+	/*enable usb 1.1 fs device and remove usb 2.0 reset */
+	*(unsigned char *)(CFG_BCSR_BASE | 0x09) = 0x00;
+
+	/*get rid of flash write protect */
+	*(unsigned char *)(CFG_BCSR_BASE | 0x07) = 0x40;
+
+	return 0;
+}
+
+int checkboard(void)
+{
+	sys_info_t sysinfo;
+
+	get_sys_info(&sysinfo);
+
+	printf("Board: AMCC YELLOWSTONE\n");
+	printf("\tVCO: %lu MHz\n", sysinfo.freqVCOMhz / 1000000);
+	printf("\tCPU: %lu MHz\n", sysinfo.freqProcessor / 1000000);
+	printf("\tPLB: %lu MHz\n", sysinfo.freqPLB / 1000000);
+	printf("\tOPB: %lu MHz\n", sysinfo.freqOPB / 1000000);
+	printf("\tPER: %lu MHz\n", sysinfo.freqEPB / 1000000);
+	printf("\tPCI: %lu MHz\n", sysinfo.freqPCI / 1000000);
+	return (0);
+}
+
+/*************************************************************************
+ *  sdram_init -- doesn't use serial presence detect.
+ *
+ *  Assumes:    256 MB, ECC, non-registered
+ *              PLB @ 133 MHz
+ *
+ ************************************************************************/
+void sdram_init(void)
+{
+	register uint reg;
+
+	/*--------------------------------------------------------------------
+	 * Setup some default
+	 *------------------------------------------------------------------*/
+	mtsdram(mem_uabba, 0x00000000);	/* ubba=0 (default)             */
+	mtsdram(mem_slio, 0x00000000);	/* rdre=0 wrre=0 rarw=0         */
+	mtsdram(mem_devopt, 0x00000000);	/* dll=0 ds=0 (normal)          */
+	mtsdram(mem_clktr, 0x40000000);	/* ?? */
+	mtsdram(mem_wddctr, 0x40000000);	/* ?? */
+
+	/*clear this first, if the DDR is enabled by a debugger
+	   then you can not make changes. */
+	mtsdram(mem_cfg0, 0x00000000);	/* Disable EEC */
+
+	/*--------------------------------------------------------------------
+	 * Setup for board-specific specific mem
+	 *------------------------------------------------------------------*/
+	/*
+	 * Following for CAS Latency = 2.5 @ 133 MHz PLB
+	 */
+	mtsdram(mem_b0cr, 0x000a4001);	/* SDBA=0x000 128MB, Mode 3, enabled */
+	mtsdram(mem_b1cr, 0x080a4001);	/* SDBA=0x080 128MB, Mode 3, enabled */
+	mtsdram(mem_tr0, 0x410a4012);	/* ?? */
+	mtsdram(mem_tr1, 0x8080080b);	/* ?? */
+	mtsdram(mem_rtr, 0x04080000);	/* ?? */
+	mtsdram(mem_cfg1, 0x00000000);	/* Self-refresh exit, disable PM    */
+	mtsdram(mem_cfg0, 0x34000000);	/* Disable EEC */
+	udelay(400);		/* Delay 200 usecs (min)            */
+
+	/*--------------------------------------------------------------------
+	 * Enable the controller, then wait for DCEN to complete
+	 *------------------------------------------------------------------*/
+	mtsdram(mem_cfg0, 0x84000000);	/* Enable */
+
+	for (;;) {
+		mfsdram(mem_mcsts, reg);
+		if (reg & 0x80000000)
+			break;
+	}
+}
+
+/*************************************************************************
+ *  long int initdram
+ *
+ ************************************************************************/
+long int initdram(int board)
+{
+	sdram_init();
+	return CFG_SDRAM_BANKS * (CFG_KBYTES_SDRAM * 1024);	/* return bytes */
+}
+
+#if defined(CFG_DRAM_TEST)
+int testdram(void)
+{
+	unsigned long *mem = (unsigned long *)0;
+	const unsigned long kend = (1024 / sizeof(unsigned long));
+	unsigned long k, n;
+
+	mtmsr(0);
+
+	for (k = 0; k < CFG_KBYTES_SDRAM;
+	     ++k, mem += (1024 / sizeof(unsigned long))) {
+		if ((k & 1023) == 0) {
+			printf("%3d MB\r", k / 1024);
+		}
+
+		memset(mem, 0xaaaaaaaa, 1024);
+		for (n = 0; n < kend; ++n) {
+			if (mem[n] != 0xaaaaaaaa) {
+				printf("SDRAM test fails at: %08x\n",
+				       (uint) & mem[n]);
+				return 1;
+			}
+		}
+
+		memset(mem, 0x55555555, 1024);
+		for (n = 0; n < kend; ++n) {
+			if (mem[n] != 0x55555555) {
+				printf("SDRAM test fails at: %08x\n",
+				       (uint) & mem[n]);
+				return 1;
+			}
+		}
+	}
+	printf("SDRAM test passes\n");
+	return 0;
+}
+#endif
+
+/*************************************************************************
+ *  pci_pre_init
+ *
+ *  This routine is called just prior to registering the hose and gives
+ *  the board the opportunity to check things. Returning a value of zero
+ *  indicates that things are bad & PCI initialization should be aborted.
+ *
+ *	Different boards may wish to customize the pci controller structure
+ *	(add regions, override default access routines, etc) or perform
+ *	certain pre-initialization actions.
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT)
+int pci_pre_init(struct pci_controller *hose)
+{
+	unsigned long strap;
+	unsigned long addr;
+
+	/*--------------------------------------------------------------------------+
+     *	Bamboo is always configured as the host & requires the
+     *	PCI arbiter to be enabled.
+	 *--------------------------------------------------------------------------*/
+	mfsdr(sdr_sdstp1, strap);
+	if ((strap & SDR0_SDSTP1_PAE_MASK) == 0) {
+		printf("PCI: SDR0_STRP1[PAE] not set.\n");
+		printf("PCI: Configuration aborted.\n");
+		return 0;
+	}
+
+    /*-------------------------------------------------------------------------+
+    | Set priority for all PLB3 devices to 0.
+    | Set PLB3 arbiter to fair mode.
+    +-------------------------------------------------------------------------*/
+	mfsdr(sdr_amp1, addr);
+	mtsdr(sdr_amp1, (addr & 0x000000FF) | 0x0000FF00);
+	addr = mfdcr(plb3_acr);
+	mtdcr(plb3_acr, addr | 0x80000000);
+
+    /*-------------------------------------------------------------------------+
+    | Set priority for all PLB4 devices to 0.
+    +-------------------------------------------------------------------------*/
+	mfsdr(sdr_amp0, addr);
+	mtsdr(sdr_amp0, (addr & 0x000000FF) | 0x0000FF00);
+	addr = mfdcr(plb4_acr) | 0xa0000000;	/* Was 0x8---- */
+	mtdcr(plb4_acr, addr);
+
+    /*-------------------------------------------------------------------------+
+    | Set Nebula PLB4 arbiter to fair mode.
+    +-------------------------------------------------------------------------*/
+	/*  Segment0 */
+	addr = (mfdcr(plb0_acr) & ~plb0_acr_ppm_mask) | plb0_acr_ppm_fair;
+	addr = (addr & ~plb0_acr_hbu_mask) | plb0_acr_hbu_enabled;
+	addr = (addr & ~plb0_acr_rdp_mask) | plb0_acr_rdp_4deep;
+	addr = (addr & ~plb0_acr_wrp_mask) | plb0_acr_wrp_2deep;
+	mtdcr(plb0_acr, addr);
+
+	/* Segment1 */
+	addr = (mfdcr(plb1_acr) & ~plb1_acr_ppm_mask) | plb1_acr_ppm_fair;
+	addr = (addr & ~plb1_acr_hbu_mask) | plb1_acr_hbu_enabled;
+	addr = (addr & ~plb1_acr_rdp_mask) | plb1_acr_rdp_4deep;
+	addr = (addr & ~plb1_acr_wrp_mask) | plb1_acr_wrp_2deep;
+	mtdcr(plb1_acr, addr);
+
+	return 1;
+}
+#endif				/* defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT) */
+
+/*************************************************************************
+ *  pci_target_init
+ *
+ *	The bootstrap configuration provides default settings for the pci
+ *	inbound map (PIM). But the bootstrap config choices are limited and
+ *	may not be sufficient for a given board.
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT)
+void pci_target_init(struct pci_controller *hose)
+{
+	u16 cmdstat;
+
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/*--------------------------------------------------------------------------+
+	 * Set up Direct MMIO registers
+	 *--------------------------------------------------------------------------*/
+   /*--------------------------------------------------------------------------+
+   | PowerPC440 EP PCI Master configuration.
+   | Map one 1Gig range of PLB/processor addresses to PCI memory space.
+   |   PLB address 0xA0000000-0xDFFFFFFF ==> PCI address 0xA0000000-0xDFFFFFFF
+   |   Use byte reversed out routines to handle endianess.
+   | Make this region non-prefetchable.
+   +--------------------------------------------------------------------------*/
+	out32r(PCIX0_PMM0MA, 0x00000000);	/* PMM0 Mask/Attribute - disabled b4 setting */
+	out32r(PCIX0_PMM0LA, CFG_PCI_MEMBASE);	/* PMM0 Local Address */
+	out32r(PCIX0_PMM0PCILA, CFG_PCI_MEMBASE);	/* PMM0 PCI Low Address */
+	out32r(PCIX0_PMM0PCIHA, 0x00000000);	/* PMM0 PCI High Address */
+	out32r(PCIX0_PMM0MA, 0xE0000001);	/* 512M + No prefetching, and enable region */
+
+	out32r(PCIX0_PMM1MA, 0x00000000);	/* PMM0 Mask/Attribute - disabled b4 setting */
+	out32r(PCIX0_PMM1LA, CFG_PCI_MEMBASE2);	/* PMM0 Local Address */
+	out32r(PCIX0_PMM1PCILA, CFG_PCI_MEMBASE2);	/* PMM0 PCI Low Address */
+	out32r(PCIX0_PMM1PCIHA, 0x00000000);	/* PMM0 PCI High Address */
+	out32r(PCIX0_PMM1MA, 0xE0000001);	/* 512M + No prefetching, and enable region */
+
+	out32r(PCIX0_PTM1MS, 0x00000001);	/* Memory Size/Attribute */
+	out32r(PCIX0_PTM1LA, 0);	/* Local Addr. Reg */
+	out32r(PCIX0_PTM2MS, 0);	/* Memory Size/Attribute */
+	out32r(PCIX0_PTM2LA, 0);	/* Local Addr. Reg */
+
+	/*--------------------------------------------------------------------------+
+	 * Set up Configuration registers
+	 *--------------------------------------------------------------------------*/
+
+	/* Program the board's subsystem id/vendor id */
+	pci_write_config_word(0, PCI_SUBSYSTEM_VENDOR_ID,
+			      CFG_PCI_SUBSYS_VENDORID);
+	pci_write_config_word(0, PCI_SUBSYSTEM_ID, CFG_PCI_SUBSYS_ID);
+
+	/* Configure command register as bus master */
+	pci_write_config_word(0, PCI_COMMAND, PCI_COMMAND_MASTER);
+
+	/* 240nS PCI clock */
+	pci_write_config_word(0, PCI_LATENCY_TIMER, 1);
+
+	/* No error reporting */
+	pci_write_config_word(0, PCI_ERREN, 0);
+
+	pci_write_config_dword(0, PCI_BRDGOPT2, 0x00000101);
+
+}
+#endif				/* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */
+
+/*************************************************************************
+ *  pci_master_init
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_MASTER_INIT)
+void pci_master_init(struct pci_controller *hose)
+{
+	unsigned short temp_short;
+
+   /*--------------------------------------------------------------------------+
+   | Write the PowerPC440 EP PCI Configuration regs.
+   |   Enable PowerPC440 EP to be a master on the PCI bus (PMM).
+   |   Enable PowerPC440 EP to act as a PCI memory target (PTM).
+   +--------------------------------------------------------------------------*/
+	pci_read_config_word(0, PCI_COMMAND, &temp_short);
+	pci_write_config_word(0, PCI_COMMAND,
+			      temp_short | PCI_COMMAND_MASTER |
+			      PCI_COMMAND_MEMORY);
+}
+#endif				/* defined(CONFIG_PCI) && defined(CFG_PCI_MASTER_INIT) */
+
+/*************************************************************************
+ *  is_pci_host
+ *
+ *	This routine is called to determine if a pci scan should be
+ *	performed. With various hardware environments (especially cPCI and
+ *	PPMC) it's insufficient to depend on the state of the arbiter enable
+ *	bit in the strap register, or generic host/adapter assumptions.
+ *
+ *	Rather than hard-code a bad assumption in the general 440 code, the
+ *	440 pci code requires the board to decide at runtime.
+ *
+ *	Return 0 for adapter mode, non-zero for host (monarch) mode.
+ *
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI)
+int is_pci_host(struct pci_controller *hose)
+{
+	/* Bamboo is always configured as host. */
+	return (1);
+}
+#endif				/* defined(CONFIG_PCI) */
+
+/*************************************************************************
+ *  hw_watchdog_reset
+ *
+ *	This routine is called to reset (keep alive) the watchdog timer
+ *
+ ************************************************************************/
+#if defined(CONFIG_HW_WATCHDOG)
+void hw_watchdog_reset(void)
+{
+}
+#endif

+ 48 - 0
board/amcc/yosemite/Makefile

@@ -0,0 +1,48 @@
+#
+# (C) Copyright 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# 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., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= lib$(BOARD).a
+
+OBJS	= $(BOARD).o
+OBJS   += flash.o
+SOBJS	= init.o
+
+$(LIB):	$(OBJS) $(SOBJS)
+	$(AR) crv $@ $(OBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+		$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################

+ 44 - 0
board/amcc/yosemite/config.mk

@@ -0,0 +1,44 @@
+#
+# (C) Copyright 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# 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., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+#
+# esd ADCIOP boards
+#
+
+#TEXT_BASE = 0x00001000
+
+ifeq ($(ramsym),1)
+TEXT_BASE = 0xFBD00000
+else
+TEXT_BASE = 0xFFF80000
+endif
+
+PLATFORM_CPPFLAGS += -DCONFIG_440=1
+
+ifeq ($(debug),1)
+PLATFORM_CPPFLAGS += -DDEBUG
+endif
+
+ifeq ($(dbcr),1)
+PLATFORM_CPPFLAGS += -DCFG_INIT_DBCR=0x8cff0000
+endif

+ 571 - 0
board/amcc/yosemite/flash.c

@@ -0,0 +1,571 @@
+/*
+ * (C) Copyright 2002-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002 Jun Gu <jung@artesyncp.com>
+ * Add support for Am29F016D and dynamic switch setting.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Modified 4/5/2001
+ * Wait for completion of each sector erase command issued
+ * 4/5/2001
+ * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
+ */
+
+/*
+ * Ported to XPedite1000, 1/2 mb boot flash only
+ * Travis B. Sawyer, <travis.sawyer@sandburst.com>
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+#undef DEBUG
+#ifdef DEBUG
+#define DEBUGF(x...) printf(x)
+#else
+#define DEBUGF(x...)
+#endif				/* DEBUG */
+
+#define BOOT_SMALL_FLASH	32	/* 00100000 */
+#define FLASH_ONBD_N		2	/* 00000010 */
+#define FLASH_SRAM_SEL		1	/* 00000001 */
+
+#define BOOT_SMALL_FLASH_VAL	4
+#define FLASH_ONBD_N_VAL	2
+#define FLASH_SRAM_SEL_VAL	1
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];	/* info for FLASH chips   */
+
+unsigned long flash_addr_table[512][CFG_MAX_FLASH_BANKS] = {
+	{0xfe000000}
+
+};
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size(vu_long * addr, flash_info_t * info);
+static int write_word(flash_info_t * info, ulong dest, ulong data);
+
+#define ADDR0		0xaaaa
+#define ADDR1		0x5554
+#define FLASH_WORD_SIZE unsigned short
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init(void)
+{
+	unsigned long total_b = 0;
+	unsigned long size_b[CFG_MAX_FLASH_BANKS];
+	unsigned short index = 0;
+	int i;
+
+	DEBUGF("\n");
+	DEBUGF("FLASH: Index: %d\n", index);
+
+	/* Init: no FLASHes known */
+	for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
+		flash_info[i].flash_id = FLASH_UNKNOWN;
+		flash_info[i].sector_count = -1;
+		flash_info[i].size = 0;
+
+		/* check whether the address is 0 */
+		if (flash_addr_table[index][i] == 0) {
+			continue;
+		}
+
+		/* call flash_get_size() to initialize sector address */
+		size_b[i] = flash_get_size((vu_long *)
+					   flash_addr_table[index][i],
+					   &flash_info[i]);
+		flash_info[i].size = size_b[i];
+		if (flash_info[i].flash_id == FLASH_UNKNOWN) {
+			printf
+			    ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
+			     i, size_b[i], size_b[i] << 20);
+			flash_info[i].sector_count = -1;
+			flash_info[i].size = 0;
+		}
+
+		total_b += flash_info[i].size;
+	}
+
+	/* FLASH protect Monitor */
+	flash_protect(FLAG_PROTECT_SET,
+		      CFG_MONITOR_BASE, 0xFFFFFFFF, &flash_info[0]);
+
+	return total_b;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info(flash_info_t * info)
+{
+	int i;
+	int k;
+	int size;
+	int erased;
+	volatile unsigned long *flash;
+
+	if (info->flash_id == FLASH_UNKNOWN) {
+		printf("missing or unknown FLASH type\n");
+		return;
+	}
+
+	switch (info->flash_id & FLASH_VENDMASK) {
+	case FLASH_MAN_AMD:
+		printf("AMD ");
+		break;
+	case FLASH_MAN_FUJ:
+		printf("FUJITSU ");
+		break;
+	case FLASH_MAN_SST:
+		printf("SST ");
+		break;
+	default:
+		printf("Unknown Vendor ");
+		break;
+	}
+
+	switch (info->flash_id & FLASH_TYPEMASK) {
+	case FLASH_AMD016:
+		printf("AM29F016D (16 Mbit, uniform sector size)\n");
+		break;
+	case FLASH_AM040:
+		printf("AM29F040 (512 Kbit, uniform sector size)\n");
+		break;
+	case FLASH_AM400B:
+		printf("AM29LV400B (4 Mbit, bottom boot sect)\n");
+		break;
+	case FLASH_AM400T:
+		printf("AM29LV400T (4 Mbit, top boot sector)\n");
+		break;
+	case FLASH_AM800B:
+		printf("AM29LV800B (8 Mbit, bottom boot sect)\n");
+		break;
+	case FLASH_AM800T:
+		printf("AM29LV800T (8 Mbit, top boot sector)\n");
+		break;
+	case FLASH_AM160B:
+		printf("AM29LV160B (16 Mbit, bottom boot sect)\n");
+		break;
+	case FLASH_AM160T:
+		printf("AM29LV160T (16 Mbit, top boot sector)\n");
+		break;
+	case FLASH_AM320B:
+		printf("AM29LV320B (32 Mbit, bottom boot sect)\n");
+		break;
+	case FLASH_AM320T:
+		printf("AM29LV320T (32 Mbit, top boot sector)\n");
+		break;
+	case FLASH_SST800A:
+		printf("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
+		break;
+	case FLASH_SST160A:
+		printf("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
+		break;
+	default:
+		printf("Unknown Chip Type\n");
+		break;
+	}
+
+	printf("  Size: %ld KB in %d Sectors\n",
+	       info->size >> 10, info->sector_count);
+
+	printf("  Sector Start Addresses:");
+	for (i = 0; i < info->sector_count; ++i) {
+		/*
+		 * Check if whole sector is erased
+		 */
+		if (i != (info->sector_count - 1))
+			size = info->start[i + 1] - info->start[i];
+		else
+			size = info->start[0] + info->size - info->start[i];
+		erased = 1;
+		flash = (volatile unsigned long *)info->start[i];
+		size = size >> 2;	/* divide by 4 for longword access */
+		for (k = 0; k < size; k++) {
+			if (*flash++ != 0xffffffff) {
+				erased = 0;
+				break;
+			}
+		}
+
+		if ((i % 5) == 0)
+			printf("\n   ");
+		printf(" %08lX%s%s",
+		       info->start[i],
+		       erased ? " E" : "  ", info->protect[i] ? "RO " : "   ");
+	}
+	printf("\n");
+	return;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+static ulong flash_get_size(vu_long * addr, flash_info_t * info)
+{
+	short i;
+	FLASH_WORD_SIZE value;
+	ulong base = (ulong) addr;
+	volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) addr;
+
+	DEBUGF("FLASH ADDR: %08x\n", (unsigned)addr);
+
+	/* Write auto select command: read Manufacturer ID */
+	udelay(10000);
+	*(FLASH_WORD_SIZE *) ((int)addr + ADDR0) = (FLASH_WORD_SIZE) 0x00AA;
+	udelay(1000);
+	*(FLASH_WORD_SIZE *) ((int)addr + ADDR1) = (FLASH_WORD_SIZE) 0x0055;
+	udelay(1000);
+	*(FLASH_WORD_SIZE *) ((int)addr + ADDR0) = (FLASH_WORD_SIZE) 0x0090;
+	udelay(1000);
+
+	value = addr2[0];
+
+	DEBUGF("FLASH MANUFACT: %x\n", value);
+
+	switch (value) {
+	case (FLASH_WORD_SIZE) AMD_MANUFACT:
+		info->flash_id = FLASH_MAN_AMD;
+		break;
+	case (FLASH_WORD_SIZE) FUJ_MANUFACT:
+		info->flash_id = FLASH_MAN_FUJ;
+		break;
+	case (FLASH_WORD_SIZE) SST_MANUFACT:
+		info->flash_id = FLASH_MAN_SST;
+		break;
+	case (FLASH_WORD_SIZE) STM_MANUFACT:
+		info->flash_id = FLASH_MAN_STM;
+		break;
+	default:
+		info->flash_id = FLASH_UNKNOWN;
+		info->sector_count = 0;
+		info->size = 0;
+		return (0);	/* no or unknown flash  */
+	}
+
+#ifdef CONFIG_ADCIOP
+	value = addr2[0];	/* device ID            */
+	debug("\ndev_code=%x\n", value);
+#else
+	value = addr2[1];	/* device ID            */
+#endif
+
+	DEBUGF("\nFLASH DEVICEID: %x\n", value);
+
+	info->flash_id = 0;
+	info->sector_count = CFG_MAX_FLASH_SECT;
+	info->size = 0x02000000;
+
+	/* set up sector start address table */
+	for (i = 0; i < info->sector_count; i++) {
+		info->start[i] = (int)base + (i * 0x00020000);
+		info->protect[i] = 0;
+	}
+
+	*(FLASH_WORD_SIZE *) ((int)addr) = (FLASH_WORD_SIZE) 0x00F0;	/* reset bank */
+
+	return (info->size);
+}
+
+int wait_for_DQ7(flash_info_t * info, int sect)
+{
+	ulong start, now, last;
+	volatile FLASH_WORD_SIZE *addr =
+	    (FLASH_WORD_SIZE *) (info->start[sect]);
+
+	start = get_timer(0);
+	last = start;
+	while ((addr[0] & (FLASH_WORD_SIZE) 0x00800080) !=
+	       (FLASH_WORD_SIZE) 0x00800080) {
+		if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+			printf("Timeout\n");
+			return -1;
+		}
+		/* show that we're waiting */
+		if ((now - last) > 1000) {	/* every second */
+			putc('.');
+			last = now;
+		}
+	}
+	return 0;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase(flash_info_t * info, int s_first, int s_last)
+{
+	volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *) (info->start[0]);
+	volatile FLASH_WORD_SIZE *addr2;
+	int flag, prot, sect, l_sect;
+
+	if ((s_first < 0) || (s_first > s_last)) {
+		if (info->flash_id == FLASH_UNKNOWN) {
+			printf("- missing\n");
+		} else {
+			printf("- no sectors to erase\n");
+		}
+		return 1;
+	}
+
+	if (info->flash_id == FLASH_UNKNOWN) {
+		printf("Can't erase unknown flash type - aborted\n");
+		return 1;
+	}
+
+	prot = 0;
+	for (sect = s_first; sect <= s_last; ++sect) {
+		if (info->protect[sect]) {
+			prot++;
+		}
+	}
+
+	if (prot) {
+		printf("- Warning: %d protected sectors will not be erased!\n",
+		       prot);
+	} else {
+		printf("\n");
+	}
+
+	l_sect = -1;
+
+	/* Disable interrupts which might cause a timeout here */
+	flag = disable_interrupts();
+
+	/* Start erase on unprotected sectors */
+	for (sect = s_first; sect <= s_last; sect++) {
+		if (info->protect[sect] == 0) {	/* not protected */
+			addr2 = (FLASH_WORD_SIZE *) (info->start[sect]);
+			printf("Erasing sector %p\n", addr2);
+			*(FLASH_WORD_SIZE *) ((int)addr + ADDR0) =
+			    (FLASH_WORD_SIZE) 0x00AA;
+			asm("sync");
+			asm("isync");
+			*(FLASH_WORD_SIZE *) ((int)addr + ADDR1) =
+			    (FLASH_WORD_SIZE) 0x0055;
+			asm("sync");
+			asm("isync");
+			*(FLASH_WORD_SIZE *) ((int)addr + ADDR0) =
+			    (FLASH_WORD_SIZE) 0x0080;
+			asm("sync");
+			asm("isync");
+			*(FLASH_WORD_SIZE *) ((int)addr + ADDR0) =
+			    (FLASH_WORD_SIZE) 0x00AA;
+			asm("sync");
+			asm("isync");
+			*(FLASH_WORD_SIZE *) ((int)addr + ADDR1) =
+			    (FLASH_WORD_SIZE) 0x0055;
+			asm("sync");
+			asm("isync");
+			addr2[0] = (FLASH_WORD_SIZE) 0x00300030;	/* sector erase */
+			asm("sync");
+			asm("isync");
+
+			l_sect = sect;
+			/*
+			 * Wait for each sector to complete, it's more
+			 * reliable.  According to AMD Spec, you must
+			 * issue all erase commands within a specified
+			 * timeout.  This has been seen to fail, especially
+			 * if printf()s are included (for debug)!!
+			 */
+			wait_for_DQ7(info, sect);
+		}
+	}
+
+	/* re-enable interrupts if necessary */
+	if (flag)
+		enable_interrupts();
+
+	/* wait at least 80us - let's wait 1 ms */
+	udelay(1000);
+
+#if 0
+	/*
+	 * We wait for the last triggered sector
+	 */
+	if (l_sect < 0)
+		goto DONE;
+	wait_for_DQ7(info, l_sect);
+
+      DONE:
+#endif
+	/* reset to read mode */
+	addr = (FLASH_WORD_SIZE *) info->start[0];
+	addr[0] = (FLASH_WORD_SIZE) 0x00F000F0;	/* reset bank */
+
+	printf(" done\n");
+	return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+	ulong cp, wp, data;
+	int i, l, rc;
+	ulong status_value = 0;
+
+	wp = (addr & ~3);	/* get lower word aligned address */
+
+	/*
+	 * handle unaligned start bytes
+	 */
+	if ((l = addr - wp) != 0) {
+		data = 0;
+		for (i = 0, cp = wp; i < l; ++i, ++cp) {
+			data = (data << 8) | (*(uchar *) cp);
+		}
+		for (; i < 4 && cnt > 0; ++i) {
+			data = (data << 8) | *src++;
+			--cnt;
+			++cp;
+		}
+		for (; cnt == 0 && i < 4; ++i, ++cp) {
+			data = (data << 8) | (*(uchar *) cp);
+		}
+
+		if ((rc = write_word(info, wp, data)) != 0) {
+			return (rc);
+		}
+		wp += 4;
+	}
+
+	/*
+	 * handle word aligned part
+	 */
+	while (cnt >= 4) {
+
+		/*print status if needed */
+		if ((wp >= (status_value + 0x20000))
+		    && (status_value < 0xFFFE0000)) {
+			status_value = wp;
+			printf("writing to sector 0x%X\n", status_value);
+		}
+
+		data = 0;
+		for (i = 0; i < 4; ++i) {
+			data = (data << 8) | *src++;
+		}
+		if ((rc = write_word(info, wp, data)) != 0) {
+			return (rc);
+		}
+		wp += 4;
+		cnt -= 4;
+	}
+
+	if (cnt == 0) {
+		return (0);
+	}
+
+	/*
+	 * handle unaligned tail bytes
+	 */
+	data = 0;
+	for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
+		data = (data << 8) | *src++;
+		--cnt;
+	}
+	for (; i < 4; ++i, ++cp) {
+		data = (data << 8) | (*(uchar *) cp);
+	}
+
+	return (write_word(info, wp, data));
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word(flash_info_t * info, ulong dest, ulong data)
+{
+	vu_long *addr2 = (vu_long *) (info->start[0]);
+	volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest;
+	volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data;
+	ulong start;
+	int i;
+
+	/* Check if Flash is (sufficiently) erased */
+	if ((*((volatile FLASH_WORD_SIZE *)dest) &
+	     (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) {
+		return (2);
+	}
+
+	for (i = 0; i < 4 / sizeof(FLASH_WORD_SIZE); i++) {
+		int flag;
+
+		/* Disable interrupts which might cause a timeout here */
+		flag = disable_interrupts();
+
+		*(FLASH_WORD_SIZE *) ((int)addr2 + ADDR0) =
+		    (FLASH_WORD_SIZE) 0x00AA;
+		asm("sync");
+		asm("isync");
+		*(FLASH_WORD_SIZE *) ((int)addr2 + ADDR1) =
+		    (FLASH_WORD_SIZE) 0x0055;
+		asm("sync");
+		asm("isync");
+		*(FLASH_WORD_SIZE *) ((int)addr2 + ADDR0) =
+		    (FLASH_WORD_SIZE) 0x00A0;
+		asm("sync");
+		asm("isync");
+
+		dest2[i] = data2[i];
+
+		/* re-enable interrupts if necessary */
+		if (flag)
+			enable_interrupts();
+
+		/* data polling for D7 */
+		start = get_timer(0);
+		while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) !=
+		       (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) {
+
+			if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+				return (1);
+			}
+		}
+	}
+
+	return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */

+ 107 - 0
board/amcc/yosemite/init.S

@@ -0,0 +1,107 @@
+/*
+*
+* See file CREDITS for list of people who contributed to this
+* project.
+*
+* 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 program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+* GNU General Public License for more details.
+*
+* 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., 59 Temple Place, Suite 330, Boston,
+* MA 02111-1307 USA
+*/
+
+#include <ppc_asm.tmpl>
+#include <config.h>
+
+/* General */
+#define TLB_VALID   0x00000200
+
+/* Supported page sizes */
+
+#define SZ_1K	    0x00000000
+#define SZ_4K	    0x00000010
+#define SZ_16K	    0x00000020
+#define SZ_64K	    0x00000030
+#define SZ_256K	    0x00000040
+#define SZ_1M	    0x00000050
+#define SZ_8M       0x00000060
+#define SZ_16M	    0x00000070
+#define SZ_256M	    0x00000090
+
+/* Storage attributes */
+#define SA_W	    0x00000800	    /* Write-through */
+#define SA_I	    0x00000400	    /* Caching inhibited */
+#define SA_M	    0x00000200	    /* Memory coherence */
+#define SA_G	    0x00000100	    /* Guarded */
+#define SA_E	    0x00000080	    /* Endian */
+
+/* Access control */
+#define AC_X	    0x00000024	    /* Execute */
+#define AC_W	    0x00000012	    /* Write */
+#define AC_R	    0x00000009	    /* Read */
+
+/* Some handy macros */
+
+#define EPN(e)		((e) & 0xfffffc00)
+#define TLB0(epn,sz)	( (EPN((epn)) | (sz) | TLB_VALID ) )
+#define TLB1(rpn,erpn)	( ((rpn)&0xfffffc00) | (erpn) )
+#define TLB2(a)		( (a)&0x00000fbf )
+
+#define tlbtab_start\
+	mflr    r1  ;\
+	bl 0f	    ;
+
+#define tlbtab_end\
+	.long 0, 0, 0	;   \
+0:	mflr    r0	;   \
+	mtlr    r1	;   \
+	blr		;
+
+#define tlbentry(epn,sz,rpn,erpn,attr)\
+	.long TLB0(epn,sz),TLB1(rpn,erpn),TLB2(attr)
+
+
+/**************************************************************************
+ * TLB TABLE
+ *
+ * This table is used by the cpu boot code to setup the initial tlb
+ * entries. Rather than make broad assumptions in the cpu source tree,
+ * this table lets each board set things up however they like.
+ *
+ *  Pointer to the table is returned in r1
+ *
+ *************************************************************************/
+
+    .section .bootpg,"ax"
+    .globl tlbtab
+
+tlbtab:
+    tlbtab_start
+	/*
+		0xf0000000 must be first, before relocation SA_I must be off to use the
+	    dcache as stack. It is patched after relocation to enable SA_I
+	*/
+    tlbentry( 0xf0000000, SZ_256M, 0xf0000000, 0, AC_R|AC_W|AC_X|SA_G/*|SA_I*/)
+    tlbentry( CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
+    tlbentry( CFG_PCI_BASE, SZ_256M, 0xE0000000, 0, AC_R|AC_W|SA_G|SA_I )
+    tlbentry( CFG_NVRAM_BASE_ADDR, SZ_16K, 0x80000000, 0, AC_R|AC_W|AC_X|SA_W|SA_I )
+
+    /* PCI */
+    tlbentry( CFG_PCI_MEMBASE, SZ_256M, CFG_PCI_MEMBASE, 0, AC_R|AC_W|SA_G|SA_I )
+    tlbentry( CFG_PCI_MEMBASE1, SZ_256M, CFG_PCI_MEMBASE1, 0, AC_R|AC_W|SA_G|SA_I )
+    tlbentry( CFG_PCI_MEMBASE2, SZ_256M, CFG_PCI_MEMBASE2, 0, AC_R|AC_W|SA_G|SA_I )
+    tlbentry( CFG_PCI_MEMBASE3, SZ_256M, CFG_PCI_MEMBASE3, 0, AC_R|AC_W|SA_G|SA_I )
+
+    /* USB 2.0 Device */
+    tlbentry( CFG_USB_DEVICE, SZ_1K, 0x50000000, 0, AC_R|AC_W|SA_G|SA_I )
+
+    tlbtab_end

+ 155 - 0
board/amcc/yosemite/u-boot.lds

@@ -0,0 +1,155 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  .resetvec 0xFFFFFFFC :
+  {
+    *(.resetvec)
+  } = 0xffff
+
+  .bootpg 0xFFFFF000 :
+  {
+    cpu/ppc4xx/start.o	(.bootpg)
+  } = 0xffff
+
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .init          : { *(.init)	}
+  .plt : { *(.plt) }
+  .text      :
+  {
+    /* WARNING - the following is hand-optimized to fit within	*/
+    /* the sector layout of our flash chips!	XXX FIXME XXX	*/
+
+    cpu/ppc4xx/start.o	(.text)
+    board/amcc/yosemite/init.o	(.text)
+    cpu/ppc4xx/kgdb.o	(.text)
+    cpu/ppc4xx/traps.o	(.text)
+    cpu/ppc4xx/interrupts.o	(.text)
+    cpu/ppc4xx/serial.o	(.text)
+    cpu/ppc4xx/cpu_init.o	(.text)
+    cpu/ppc4xx/speed.o	(.text)
+    cpu/ppc4xx/405gp_enet.o	(.text)
+    common/dlmalloc.o	(.text)
+    lib_generic/crc32.o		(.text)
+    lib_ppc/extable.o	(.text)
+    lib_generic/zlib.o		(.text)
+
+/*    . = env_offset;*/
+/*    common/environment.o(.text)*/
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+    *(.rodata.str1.4)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __u_boot_cmd_start = .;
+  .u_boot_cmd : { *(.u_boot_cmd) }
+  __u_boot_cmd_end = .;
+
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}

+ 424 - 0
board/amcc/yosemite/yosemite.c

@@ -0,0 +1,424 @@
+/*
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <spd_sdram.h>
+
+int board_early_init_f(void)
+{
+	register uint reg;
+
+	/*--------------------------------------------------------------------
+	 * Setup the external bus controller/chip selects
+	 *-------------------------------------------------------------------*/
+	mtdcr(ebccfga, xbcfg);
+	reg = mfdcr(ebccfgd);
+	mtdcr(ebccfgd, reg | 0x04000000);	/* Set ATC */
+
+	mtebc(pb0ap, 0x03017300);	/* FLASH/SRAM */
+	mtebc(pb0cr, 0xfe0ba000);	/* BAS=0xfe0 32MB r/w 16-bit */
+
+	mtebc(pb1ap, 0x00000000);
+	mtebc(pb1cr, 0x00000000);
+
+	mtebc(pb2ap, 0x04814500);
+	/*CPLD*/ mtebc(pb2cr, 0x80018000);	/*BAS=0x800 1MB r/w 8-bit */
+
+	mtebc(pb3ap, 0x00000000);
+	mtebc(pb3cr, 0x00000000);
+
+	mtebc(pb4ap, 0x00000000);
+	mtebc(pb4cr, 0x00000000);
+
+	mtebc(pb5ap, 0x00000000);
+	mtebc(pb5cr, 0x00000000);
+
+	/*--------------------------------------------------------------------
+	 * Setup the interrupt controller polarities, triggers, etc.
+	 *-------------------------------------------------------------------*/
+	mtdcr(uic0sr, 0xffffffff);	/* clear all */
+	mtdcr(uic0er, 0x00000000);	/* disable all */
+	mtdcr(uic0cr, 0x00000009);	/* ATI & UIC1 crit are critical */
+	mtdcr(uic0pr, 0xfffffe13);	/* per ref-board manual */
+	mtdcr(uic0tr, 0x01c00008);	/* per ref-board manual */
+	mtdcr(uic0vr, 0x00000001);	/* int31 highest, base=0x000 */
+	mtdcr(uic0sr, 0xffffffff);	/* clear all */
+
+	mtdcr(uic1sr, 0xffffffff);	/* clear all */
+	mtdcr(uic1er, 0x00000000);	/* disable all */
+	mtdcr(uic1cr, 0x00000000);	/* all non-critical */
+	mtdcr(uic1pr, 0xffffe0ff);	/* per ref-board manual */
+	mtdcr(uic1tr, 0x00ffc000);	/* per ref-board manual */
+	mtdcr(uic1vr, 0x00000001);	/* int31 highest, base=0x000 */
+	mtdcr(uic1sr, 0xffffffff);	/* clear all */
+
+	/*--------------------------------------------------------------------
+	 * Setup the GPIO pins
+	 *-------------------------------------------------------------------*/
+	/*CPLD cs */
+	/*setup Address lines for flash sizes larger than 16Meg. */
+	out32(GPIO0_OSRL, in32(GPIO0_OSRL) | 0x40010000);
+	out32(GPIO0_TSRL, in32(GPIO0_TSRL) | 0x40010000);
+	out32(GPIO0_ISR1L, in32(GPIO0_ISR1L) | 0x40000000);
+
+	/*setup emac */
+	out32(GPIO0_TCR, in32(GPIO0_TCR) | 0xC080);
+	out32(GPIO0_TSRL, in32(GPIO0_TSRL) | 0x40);
+	out32(GPIO0_ISR1L, in32(GPIO0_ISR1L) | 0x55);
+	out32(GPIO0_OSRH, in32(GPIO0_OSRH) | 0x50004000);
+	out32(GPIO0_ISR1H, in32(GPIO0_ISR1H) | 0x00440000);
+
+	/*UART1 */
+	out32(GPIO1_TCR, in32(GPIO1_TCR) | 0x02000000);
+	out32(GPIO1_OSRL, in32(GPIO1_OSRL) | 0x00080000);
+	out32(GPIO1_ISR2L, in32(GPIO1_ISR2L) | 0x00010000);
+
+	/*setup USB 2.0 */
+	out32(GPIO1_TCR, in32(GPIO1_TCR) | 0xc0000000);
+	out32(GPIO1_OSRL, in32(GPIO1_OSRL) | 0x50000000);
+	out32(GPIO0_TCR, in32(GPIO0_TCR) | 0xf);
+	out32(GPIO0_OSRH, in32(GPIO0_OSRH) | 0xaa);
+	out32(GPIO0_ISR2H, in32(GPIO0_ISR2H) | 0x00000500);
+
+	/*--------------------------------------------------------------------
+	 * Setup other serial configuration
+	 *-------------------------------------------------------------------*/
+	mfsdr(sdr_pci0, reg);
+	mtsdr(sdr_pci0, 0x80000000 | reg);	/* PCI arbiter enabled */
+	mtsdr(sdr_pfc0, 0x00003e00);	/* Pin function */
+	mtsdr(sdr_pfc1, 0x00048000);	/* Pin function: UART0 has 4 pins */
+
+	/*clear tmrclk divisor */
+	*(unsigned char *)(CFG_BCSR_BASE | 0x04) = 0x00;
+
+	/*enable ethernet */
+	*(unsigned char *)(CFG_BCSR_BASE | 0x08) = 0xf0;
+
+	/*enable usb 1.1 fs device and remove usb 2.0 reset */
+	*(unsigned char *)(CFG_BCSR_BASE | 0x09) = 0x00;
+
+	/*get rid of flash write protect */
+	*(unsigned char *)(CFG_BCSR_BASE | 0x07) = 0x40;
+
+	return 0;
+}
+
+int checkboard(void)
+{
+	sys_info_t sysinfo;
+
+	get_sys_info(&sysinfo);
+
+	printf("Board: AMCC YOSEMITE\n");
+	printf("\tVCO: %lu MHz\n", sysinfo.freqVCOMhz / 1000000);
+	printf("\tCPU: %lu MHz\n", sysinfo.freqProcessor / 1000000);
+	printf("\tPLB: %lu MHz\n", sysinfo.freqPLB / 1000000);
+	printf("\tOPB: %lu MHz\n", sysinfo.freqOPB / 1000000);
+	printf("\tPER: %lu MHz\n", sysinfo.freqEPB / 1000000);
+	printf("\tPCI: %lu MHz\n", sysinfo.freqPCI / 1000000);
+	return (0);
+}
+
+/*************************************************************************
+ *  sdram_init -- doesn't use serial presence detect.
+ *
+ *  Assumes:    256 MB, ECC, non-registered
+ *              PLB @ 133 MHz
+ *
+ ************************************************************************/
+void sdram_init(void)
+{
+	register uint reg;
+
+	/*--------------------------------------------------------------------
+	 * Setup some default
+	 *------------------------------------------------------------------*/
+	mtsdram(mem_uabba, 0x00000000);	/* ubba=0 (default)             */
+	mtsdram(mem_slio, 0x00000000);	/* rdre=0 wrre=0 rarw=0         */
+	mtsdram(mem_devopt, 0x00000000);	/* dll=0 ds=0 (normal)          */
+	mtsdram(mem_clktr, 0x40000000);	/* ?? */
+	mtsdram(mem_wddctr, 0x40000000);	/* ?? */
+
+	/*clear this first, if the DDR is enabled by a debugger
+	   then you can not make changes. */
+	mtsdram(mem_cfg0, 0x00000000);	/* Disable EEC */
+
+	/*--------------------------------------------------------------------
+	 * Setup for board-specific specific mem
+	 *------------------------------------------------------------------*/
+	/*
+	 * Following for CAS Latency = 2.5 @ 133 MHz PLB
+	 */
+	mtsdram(mem_b0cr, 0x000a4001);	/* SDBA=0x000 128MB, Mode 3, enabled */
+	mtsdram(mem_b1cr, 0x080a4001);	/* SDBA=0x080 128MB, Mode 3, enabled */
+
+	mtsdram(mem_tr0, 0x410a4012);	/* ?? */
+	mtsdram(mem_tr1, 0x8080080b);	/* ?? */
+	mtsdram(mem_rtr, 0x04080000);	/* ?? */
+	mtsdram(mem_cfg1, 0x00000000);	/* Self-refresh exit, disable PM    */
+	mtsdram(mem_cfg0, 0x34000000);	/* Disable EEC */
+	udelay(400);		/* Delay 200 usecs (min)            */
+
+	/*--------------------------------------------------------------------
+	 * Enable the controller, then wait for DCEN to complete
+	 *------------------------------------------------------------------*/
+	mtsdram(mem_cfg0, 0x84000000);	/* Enable */
+
+	for (;;) {
+		mfsdram(mem_mcsts, reg);
+		if (reg & 0x80000000)
+			break;
+	}
+}
+
+/*************************************************************************
+ *  long int initdram
+ *
+ ************************************************************************/
+long int initdram(int board)
+{
+	sdram_init();
+	return CFG_SDRAM_BANKS * (CFG_KBYTES_SDRAM * 1024);	/* return bytes */
+}
+
+#if defined(CFG_DRAM_TEST)
+int testdram(void)
+{
+	unsigned long *mem = (unsigned long *)0;
+	const unsigned long kend = (1024 / sizeof(unsigned long));
+	unsigned long k, n;
+
+	mtmsr(0);
+
+	for (k = 0; k < CFG_KBYTES_SDRAM;
+	     ++k, mem += (1024 / sizeof(unsigned long))) {
+		if ((k & 1023) == 0) {
+			printf("%3d MB\r", k / 1024);
+		}
+
+		memset(mem, 0xaaaaaaaa, 1024);
+		for (n = 0; n < kend; ++n) {
+			if (mem[n] != 0xaaaaaaaa) {
+				printf("SDRAM test fails at: %08x\n",
+				       (uint) & mem[n]);
+				return 1;
+			}
+		}
+
+		memset(mem, 0x55555555, 1024);
+		for (n = 0; n < kend; ++n) {
+			if (mem[n] != 0x55555555) {
+				printf("SDRAM test fails at: %08x\n",
+				       (uint) & mem[n]);
+				return 1;
+			}
+		}
+	}
+	printf("SDRAM test passes\n");
+	return 0;
+}
+#endif
+
+/*************************************************************************
+ *  pci_pre_init
+ *
+ *  This routine is called just prior to registering the hose and gives
+ *  the board the opportunity to check things. Returning a value of zero
+ *  indicates that things are bad & PCI initialization should be aborted.
+ *
+ *	Different boards may wish to customize the pci controller structure
+ *	(add regions, override default access routines, etc) or perform
+ *	certain pre-initialization actions.
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT)
+int pci_pre_init(struct pci_controller *hose)
+{
+	unsigned long strap;
+	unsigned long addr;
+
+	/*--------------------------------------------------------------------------+
+	 *	Bamboo is always configured as the host & requires the
+	 *	PCI arbiter to be enabled.
+	 *--------------------------------------------------------------------------*/
+	mfsdr(sdr_sdstp1, strap);
+	if ((strap & SDR0_SDSTP1_PAE_MASK) == 0) {
+		printf("PCI: SDR0_STRP1[PAE] not set.\n");
+		printf("PCI: Configuration aborted.\n");
+		return 0;
+	}
+
+	/*-------------------------------------------------------------------------+
+	  | Set priority for all PLB3 devices to 0.
+	  | Set PLB3 arbiter to fair mode.
+	  +-------------------------------------------------------------------------*/
+	mfsdr(sdr_amp1, addr);
+	mtsdr(sdr_amp1, (addr & 0x000000FF) | 0x0000FF00);
+	addr = mfdcr(plb3_acr);
+	mtdcr(plb3_acr, addr | 0x80000000);
+
+	/*-------------------------------------------------------------------------+
+	  | Set priority for all PLB4 devices to 0.
+	  +-------------------------------------------------------------------------*/
+	mfsdr(sdr_amp0, addr);
+	mtsdr(sdr_amp0, (addr & 0x000000FF) | 0x0000FF00);
+	addr = mfdcr(plb4_acr) | 0xa0000000;	/* Was 0x8---- */
+	mtdcr(plb4_acr, addr);
+
+	/*-------------------------------------------------------------------------+
+	  | Set Nebula PLB4 arbiter to fair mode.
+	  +-------------------------------------------------------------------------*/
+	/* Segment0 */
+	addr = (mfdcr(plb0_acr) & ~plb0_acr_ppm_mask) | plb0_acr_ppm_fair;
+	addr = (addr & ~plb0_acr_hbu_mask) | plb0_acr_hbu_enabled;
+	addr = (addr & ~plb0_acr_rdp_mask) | plb0_acr_rdp_4deep;
+	addr = (addr & ~plb0_acr_wrp_mask) | plb0_acr_wrp_2deep;
+	mtdcr(plb0_acr, addr);
+
+	/* Segment1 */
+	addr = (mfdcr(plb1_acr) & ~plb1_acr_ppm_mask) | plb1_acr_ppm_fair;
+	addr = (addr & ~plb1_acr_hbu_mask) | plb1_acr_hbu_enabled;
+	addr = (addr & ~plb1_acr_rdp_mask) | plb1_acr_rdp_4deep;
+	addr = (addr & ~plb1_acr_wrp_mask) | plb1_acr_wrp_2deep;
+	mtdcr(plb1_acr, addr);
+
+	return 1;
+}
+#endif				/* defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT) */
+
+/*************************************************************************
+ *  pci_target_init
+ *
+ *	The bootstrap configuration provides default settings for the pci
+ *	inbound map (PIM). But the bootstrap config choices are limited and
+ *	may not be sufficient for a given board.
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT)
+void pci_target_init(struct pci_controller *hose)
+{
+	/*--------------------------------------------------------------------------+
+	 * Set up Direct MMIO registers
+	 *--------------------------------------------------------------------------*/
+	/*--------------------------------------------------------------------------+
+	  | PowerPC440 EP PCI Master configuration.
+	  | Map one 1Gig range of PLB/processor addresses to PCI memory space.
+	  |   PLB address 0xA0000000-0xDFFFFFFF ==> PCI address 0xA0000000-0xDFFFFFFF
+	  |   Use byte reversed out routines to handle endianess.
+	  | Make this region non-prefetchable.
+	  +--------------------------------------------------------------------------*/
+	out32r(PCIX0_PMM0MA, 0x00000000);	/* PMM0 Mask/Attribute - disabled b4 setting */
+	out32r(PCIX0_PMM0LA, CFG_PCI_MEMBASE);	/* PMM0 Local Address */
+	out32r(PCIX0_PMM0PCILA, CFG_PCI_MEMBASE);	/* PMM0 PCI Low Address */
+	out32r(PCIX0_PMM0PCIHA, 0x00000000);	/* PMM0 PCI High Address */
+	out32r(PCIX0_PMM0MA, 0xE0000001);	/* 512M + No prefetching, and enable region */
+
+	out32r(PCIX0_PMM1MA, 0x00000000);	/* PMM0 Mask/Attribute - disabled b4 setting */
+	out32r(PCIX0_PMM1LA, CFG_PCI_MEMBASE2);	/* PMM0 Local Address */
+	out32r(PCIX0_PMM1PCILA, CFG_PCI_MEMBASE2);	/* PMM0 PCI Low Address */
+	out32r(PCIX0_PMM1PCIHA, 0x00000000);	/* PMM0 PCI High Address */
+	out32r(PCIX0_PMM1MA, 0xE0000001);	/* 512M + No prefetching, and enable region */
+
+	out32r(PCIX0_PTM1MS, 0x00000001);	/* Memory Size/Attribute */
+	out32r(PCIX0_PTM1LA, 0);	/* Local Addr. Reg */
+	out32r(PCIX0_PTM2MS, 0);	/* Memory Size/Attribute */
+	out32r(PCIX0_PTM2LA, 0);	/* Local Addr. Reg */
+
+	/*--------------------------------------------------------------------------+
+	 * Set up Configuration registers
+	 *--------------------------------------------------------------------------*/
+
+	/* Program the board's subsystem id/vendor id */
+	pci_write_config_word(0, PCI_SUBSYSTEM_VENDOR_ID,
+			      CFG_PCI_SUBSYS_VENDORID);
+	pci_write_config_word(0, PCI_SUBSYSTEM_ID, CFG_PCI_SUBSYS_ID);
+
+	/* Configure command register as bus master */
+	pci_write_config_word(0, PCI_COMMAND, PCI_COMMAND_MASTER);
+
+	/* 240nS PCI clock */
+	pci_write_config_word(0, PCI_LATENCY_TIMER, 1);
+
+	/* No error reporting */
+	pci_write_config_word(0, PCI_ERREN, 0);
+
+	pci_write_config_dword(0, PCI_BRDGOPT2, 0x00000101);
+
+}
+#endif				/* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */
+
+/*************************************************************************
+ *  pci_master_init
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_MASTER_INIT)
+void pci_master_init(struct pci_controller *hose)
+{
+	unsigned short temp_short;
+
+	/*--------------------------------------------------------------------------+
+	  | Write the PowerPC440 EP PCI Configuration regs.
+	  |   Enable PowerPC440 EP to be a master on the PCI bus (PMM).
+	  |   Enable PowerPC440 EP to act as a PCI memory target (PTM).
+	  +--------------------------------------------------------------------------*/
+	pci_read_config_word(0, PCI_COMMAND, &temp_short);
+	pci_write_config_word(0, PCI_COMMAND,
+			      temp_short | PCI_COMMAND_MASTER |
+			      PCI_COMMAND_MEMORY);
+}
+#endif				/* defined(CONFIG_PCI) && defined(CFG_PCI_MASTER_INIT) */
+
+/*************************************************************************
+ *  is_pci_host
+ *
+ *	This routine is called to determine if a pci scan should be
+ *	performed. With various hardware environments (especially cPCI and
+ *	PPMC) it's insufficient to depend on the state of the arbiter enable
+ *	bit in the strap register, or generic host/adapter assumptions.
+ *
+ *	Rather than hard-code a bad assumption in the general 440 code, the
+ *	440 pci code requires the board to decide at runtime.
+ *
+ *	Return 0 for adapter mode, non-zero for host (monarch) mode.
+ *
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI)
+int is_pci_host(struct pci_controller *hose)
+{
+	/* Bamboo is always configured as host. */
+	return (1);
+}
+#endif				/* defined(CONFIG_PCI) */
+
+/*************************************************************************
+ *  hw_watchdog_reset
+ *
+ *	This routine is called to reset (keep alive) the watchdog timer
+ *
+ ************************************************************************/
+#if defined(CONFIG_HW_WATCHDOG)
+void hw_watchdog_reset(void)
+{
+
+}
+#endif

+ 6 - 4
common/cmd_bdinfo.c

@@ -61,13 +61,15 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 #endif
 	print_num ("bootflags",	    bd->bi_bootflags	);
 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
-    defined(CONFIG_405EP) || defined(CONFIG_XILINX_ML300)
+    defined(CONFIG_405EP) || defined(CONFIG_XILINX_ML300) || \
+    defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
 	print_str ("procfreq",	    strmhz(buf, bd->bi_procfreq));
 	print_str ("plb_busfreq",   strmhz(buf, bd->bi_plb_busfreq));
-#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || defined(CONFIG_XILINX_ML300)
+#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || defined(CONFIG_XILINX_ML300) || \
+    defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
 	print_str ("pci_busfreq",   strmhz(buf, bd->bi_pci_busfreq));
 #endif
-#else	/* ! CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_ML300 */
+#else	/* ! CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_ML300, CONFIG_440_EP CONFIG_440_GR */
 #if defined(CONFIG_8260) || defined(CONFIG_MPC8560)
 	print_str ("vco",	    strmhz(buf, bd->bi_vco));
 	print_str ("sccfreq",	    strmhz(buf, bd->bi_sccfreq));
@@ -78,7 +80,7 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	print_str ("cpmfreq",	    strmhz(buf, bd->bi_cpmfreq));
 #endif
 	print_str ("busfreq",	    strmhz(buf, bd->bi_busfreq));
-#endif /* CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_ML300 */
+#endif /* CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_ML300, CONFIG_440_EP CONFIG_440_GR */
 #if defined(CONFIG_MPC8220)
 	print_str ("inpfreq",	    strmhz(buf, bd->bi_inpfreq));
 	print_str ("flbfreq",	    strmhz(buf, bd->bi_flbfreq));

+ 2 - 2
common/cmd_elf.c

@@ -78,7 +78,7 @@ int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  * ====================================================================== */
 int do_bootvx ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
-#if defined(CONFIG_WALNUT405)	|| \
+#if defined(CONFIG_WALNUT)	|| \
     defined(CFG_VXWORKS_MAC_PTR)
 	DECLARE_GLOBAL_DATA_PTR;
 #endif
@@ -121,7 +121,7 @@ int do_bootvx ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	 * This will vary from board to board
 	 */
 
-#if defined(CONFIG_WALNUT405)
+#if defined(CONFIG_WALNUT)
 	tmp = (char *) CFG_NVRAM_BASE_ADDR + 0x500;
 	memcpy ((char *) tmp, (char *) &gd->bd->bi_enetaddr[3], 3);
 #elif defined(CFG_VXWORKS_MAC_PTR)

+ 1 - 1
common/lynxkdi.c

@@ -20,7 +20,7 @@
 #if defined(CONFIG_LYNXKDI)
 #include <lynxkdi.h>
 
-#if defined(CONFIG_MPC8260)
+#if defined(CONFIG_MPC8260) || defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
 void lynxkdi_boot ( image_header_t *hdr )
 {
 	void (*lynxkdi)(void) = (void(*)(void))hdr->ih_ep;

+ 18 - 12
cpu/ppc4xx/405gp_enet.c

@@ -227,7 +227,12 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
 	 /* wait for reset */
 	 while (mfdcr (malmcr) & MAL_CR_MMSR) {
 	 };
-#if defined(CONFIG_440)
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+	out32 (ZMII_FER, 0);
+	udelay(100);
+	/* set RII mode */
+	out32 (ZMII_FER, ZMII_RMII | ZMII_MDI0);
+#elif defined(CONFIG_440)
 	 /* set RMII mode */
 	 out32 (ZMII_FER, ZMII_RMII | ZMII_MDI0);
 #endif /* CONFIG_440 */
@@ -461,6 +466,18 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
 		out32(ZMII_SSR, in32(ZMII_SSR) | 0x10000000);
 	else
 		out32(ZMII_SSR, in32(ZMII_SSR) & ~0x10000000);
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+	mfsdr(sdr_mfr, reg);
+	/* set speed */
+	if (speed == _100BASET) {
+		out32(ZMII_SSR, in32(ZMII_SSR) | 0x10000000);
+		reg = (reg & ~SDR0_MFR_ZMII_MODE_MASK) | SDR0_MFR_ZMII_MODE_RMII_100M;
+	} else {
+		reg = (reg & ~SDR0_MFR_ZMII_MODE_MASK) | SDR0_MFR_ZMII_MODE_RMII_10M;
+		out32(ZMII_SSR, in32(ZMII_SSR) & ~0x10000000);
+	}
+	mtsdr(sdr_mfr, reg);
+#endif
 #endif
 
 	/* Enable broadcast and indvidual address */
@@ -498,11 +515,6 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
 		/*
 		 * Connect interrupt service routines
 		 */
-#if !defined(CONFIG_405EP)
-		/* 405EP has one EWU interrupt */
-		irq_install_handler (VECNUM_EWU0 + (hw_p->devnum * 2),
-				     (interrupt_handler_t *) enetInt, dev);
-#endif
 		irq_install_handler (VECNUM_ETH0 + (hw_p->devnum * 2),
 				     (interrupt_handler_t *) enetInt, dev);
 	}
@@ -993,12 +1005,6 @@ int ppc_4xx_eth_initialize (bd_t * bis)
 			mtdcr (malrxdeir, 0xffffffff);	/* clear pending interrupts */
 			mtdcr (malier, mal_ier);
 
-#if defined(CONFIG_405EP)
-			/* 405EP has one EWU interrupt */
-			irq_install_handler (VECNUM_EWU0,
-					     (interrupt_handler_t *) enetInt,
-					     dev);
-#endif
 			/* install MAL interrupt handler */
 			irq_install_handler (VECNUM_MS,
 					     (interrupt_handler_t *) enetInt,

+ 4 - 2
cpu/ppc4xx/405gp_pci.c

@@ -437,7 +437,7 @@ void pci_440_init (struct pci_controller *hose)
 	 * The PCI initialization sequence enable bit must be set ... if not abort
 	 * pci setup since updating the bit requires chip reset.
 	 *--------------------------------------------------------------------------*/
-#if defined (CONFIG_440_GX)
+#if defined (CONFIG_440_GX) || defined (CONFIG_440_EP) || defined(CONFIG_440_GR)
 	mfsdr(sdr_sdstp1,strap);
 	if ( (strap & 0x00010000) == 0 ){
 		printf("PCI: SDR0_STRP1[PISE] not set.\n");
@@ -498,7 +498,7 @@ void pci_440_init (struct pci_controller *hose)
 #if defined(CONFIG_440_GX)
 	out32r( PCIX0_BRDGOPT1, 0x04000060 );               /* PLB Rq pri highest   */
 	out32r( PCIX0_BRDGOPT2, in32(PCIX0_BRDGOPT2) | 0x83 ); /* Enable host config, clear Timeout, ensure int src1  */
-#else
+#elif defined(PCIX0_BRDGOPT1)
 	out32r( PCIX0_BRDGOPT1, 0x10000060 );               /* PLB Rq pri highest   */
 	out32r( PCIX0_BRDGOPT2, in32(PCIX0_BRDGOPT2) | 1 ); /* Enable host config   */
 #endif
@@ -531,7 +531,9 @@ void pci_440_init (struct pci_controller *hose)
 #ifdef CONFIG_PCI_SCAN_SHOW
 	printf("PCI:   Bus Dev VenId DevId Class Int\n");
 #endif
+#if !defined(CONFIG_440_EP) && !defined(CONFIG_440_GR)
 	out16r( PCIX0_CMD, in16r( PCIX0_CMD ) | PCI_COMMAND_MASTER);
+#endif
 	hose->last_busno = pci_hose_scan(hose);
     }
 }

+ 39 - 5
cpu/ppc4xx/440gx_enet.c

@@ -167,6 +167,8 @@ static void ppc_440x_eth_halt (struct eth_device *dev)
 	/* EMAC RESET */
 	out32 (EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST);
 
+	hw_p->print_speed = 1;	/* print speed message again next time */
+
 	return;
 }
 
@@ -277,7 +279,9 @@ static int ppc_440x_eth_init (struct eth_device *dev, bd_t * bis)
 	unsigned short devnum;
 	unsigned short reg_short;
 	sys_info_t sysinfo;
+#if defined(CONFIG_440_GX)
 	int ethgroup;
+#endif
 
 	EMAC_440GX_HW_PST hw_p = dev->priv;
 
@@ -289,7 +293,6 @@ static int ppc_440x_eth_init (struct eth_device *dev, bd_t * bis)
 	/* Need to get the OPB frequency so we can access the PHY */
 	get_sys_info (&sysinfo);
 
-
 	msr = mfmsr ();
 	mtmsr (msr & ~(MSR_EE));	/* disable interrupts */
 
@@ -320,7 +323,12 @@ static int ppc_440x_eth_init (struct eth_device *dev, bd_t * bis)
 	/* MAL Channel RESET */
 	/* 1st reset MAL channel */
 	/* Note: writing a 0 to a channel has no effect */
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+	mtdcr (maltxcarr, (MAL_TXRX_CASR >> (hw_p->devnum*2)));
+#else
 	mtdcr (maltxcarr, (MAL_TXRX_CASR >> hw_p->devnum));
+#endif
+
 	mtdcr (malrxcarr, (MAL_TXRX_CASR >> hw_p->devnum));
 
 	/* wait for reset */
@@ -354,7 +362,9 @@ static int ppc_440x_eth_init (struct eth_device *dev, bd_t * bis)
 	out32 (ZMII_FER, 0);
 	udelay (100);
 
-#if defined(CONFIG_440_GX)
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+   	out32 (ZMII_FER, (ZMII_FER_RMII | ZMII_FER_MDI) << ZMII_FER_V (devnum));
+#elif defined(CONFIG_440_GX)
 	ethgroup = ppc_440x_eth_setup_bridge(devnum, bis);
 #else
 	if ((devnum == 0) || (devnum == 1)) {
@@ -499,6 +509,15 @@ static int ppc_440x_eth_init (struct eth_device *dev, bd_t * bis)
 			(int) speed, (duplex == HALF) ? "HALF" : "FULL");
 	}
 
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+	mfsdr(sdr_mfr, reg);
+	if (speed == 100) {
+		reg = (reg & ~SDR0_MFR_ZMII_MODE_MASK) | SDR0_MFR_ZMII_MODE_RMII_100M;
+	} else {
+		reg = (reg & ~SDR0_MFR_ZMII_MODE_MASK) | SDR0_MFR_ZMII_MODE_RMII_10M;
+	}
+	mtsdr(sdr_mfr, reg);
+#endif
 	/* Set ZMII/RGMII speed according to the phy link speed */
 	reg = in32 (ZMII_SSR);
 	if ( (speed == 100) || (speed == 1000) )
@@ -618,8 +637,12 @@ static int ppc_440x_eth_init (struct eth_device *dev, bd_t * bis)
 	switch (devnum) {
 	case 1:
 		/* setup MAL tx & rx channel pointers */
-		mtdcr (maltxbattr, 0x0);
+#if defined (CONFIG_440_EP) || defined (CONFIG_440_GR)
+		mtdcr (maltxctp2r, hw_p->tx);
+#else
 		mtdcr (maltxctp1r, hw_p->tx);
+#endif
+		mtdcr (maltxbattr, 0x0);
 		mtdcr (malrxbattr, 0x0);
 		mtdcr (malrxctp1r, hw_p->rx);
 		/* set RX buffer size */
@@ -658,7 +681,11 @@ static int ppc_440x_eth_init (struct eth_device *dev, bd_t * bis)
 	}
 
 	/* Enable MAL transmit and receive channels */
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+	mtdcr (maltxcasr, (MAL_TXRX_CASR >> (hw_p->devnum*2)));
+#else
 	mtdcr (maltxcasr, (MAL_TXRX_CASR >> hw_p->devnum));
+#endif
 	mtdcr (malrxcasr, (MAL_TXRX_CASR >> hw_p->devnum));
 
 	/* set transmit enable & receive enable */
@@ -1148,19 +1175,24 @@ static int ppc_440x_eth_rx (struct eth_device *dev)
 int ppc_440x_eth_initialize (bd_t * bis)
 {
 	static int virgin = 0;
-	unsigned long pfc1;
 	struct eth_device *dev;
 	int eth_num = 0;
-
 	EMAC_440GX_HW_PST hw = NULL;
 
+#if defined(CONFIG_440_GX)
+	unsigned long pfc1;
+
 	mfsdr (sdr_pfc1, pfc1);
 	pfc1 &= ~(0x01e00000);
 	pfc1 |= 0x01200000;
 	mtsdr (sdr_pfc1, pfc1);
+#endif
 	/* set phy num and mode */
 	bis->bi_phynum[0] = CONFIG_PHY_ADDR;
+#if defined(CONFIG_PHY1_ADDR)
 	bis->bi_phynum[1] = CONFIG_PHY1_ADDR;
+#endif
+#if defined(CONFIG_440_GX)
 	bis->bi_phynum[2] = CONFIG_PHY2_ADDR;
 	bis->bi_phynum[3] = CONFIG_PHY3_ADDR;
 	bis->bi_phymode[0] = 0;
@@ -1170,6 +1202,7 @@ int ppc_440x_eth_initialize (bd_t * bis)
 
 #if defined (CONFIG_440_GX)
 	ppc_440x_eth_setup_bridge(0, bis);
+#endif
 #endif
 
 	for (eth_num = 0; eth_num < EMAC_NUM_DEV; eth_num++) {
@@ -1256,6 +1289,7 @@ int ppc_440x_eth_initialize (bd_t * bis)
 		}
 
 		hw->devnum = eth_num;
+		hw->print_speed = 1;
 
 		sprintf (dev->name, "ppc_440x_eth%d", eth_num);
 		dev->priv = (void *) hw;

+ 1 - 1
cpu/ppc4xx/Makefile

@@ -31,7 +31,7 @@ COBJS	= 405gp_enet.o 405gp_pci.o 440gx_enet.o \
 	  bedbug_405.o commproc.o \
 	  cpu.o cpu_init.o i2c.o interrupts.o \
 	  miiphy.o miiphy_440.o sdram.o serial.o \
-	  spd_sdram.o speed.o traps.o
+	  spd_sdram.o speed.o traps.o usb_ohci.o usbdev.o
 
 OBJS	= $(AOBJS) $(COBJS)
 

+ 34 - 10
cpu/ppc4xx/cpu.c

@@ -71,17 +71,17 @@ int checkcpu (void)
 	get_sys_info(&sys_info);
 
 #ifdef CONFIG_405GP
-	puts ("IBM PowerPC 405GP");
+	puts ("AMCC PowerPC 405GP");
 	if (pvr == PVR_405GPR_RB) {
 		putc('r');
 	}
 	puts (" Rev. ");
 #endif
 #ifdef CONFIG_405CR
-	puts ("IBM PowerPC 405CR Rev. ");
+	puts ("AMCC PowerPC 405CR Rev. ");
 #endif
 #ifdef CONFIG_405EP
-	puts ("IBM PowerPC 405EP Rev. ");
+	puts ("AMCC PowerPC 405EP Rev. ");
 #endif
 	switch (pvr) {
 	case PVR_405GP_RB:
@@ -152,10 +152,10 @@ int checkcpu (void)
 #endif
 
 #if defined(CONFIG_440)
-	puts ("IBM PowerPC 440 G");
+	puts ("AMCC PowerPC 440 ");
 	switch(pvr) {
 	case PVR_440GP_RB:
-		puts("P Rev. B");
+		puts("GP Rev. B");
 		/* See errata 1.12: CHIP_4 */
 		if ((mfdcr(cpc0_sys0) != mfdcr(cpc0_strp0)) ||
 		    (mfdcr(cpc0_sys1) != mfdcr(cpc0_strp1)) ){
@@ -167,19 +167,35 @@ int checkcpu (void)
 		}
 		break;
 	case PVR_440GP_RC:
-		puts("P Rev. C");
+		puts("GP Rev. C");
 		break;
 	case PVR_440GX_RA:
-		puts("X Rev. A");
+		puts("GX Rev. A");
 		break;
 	case PVR_440GX_RB:
-		puts("X Rev. B");
+		puts("GX Rev. B");
 		break;
 	case PVR_440GX_RC:
-		puts("X Rev. C");
+		puts("GX Rev. C");
 		break;
+#if defined(CONFIG_440_GR)
+	case PVR_440EP_RA:
+		puts("GR Rev. A");
+		break;
+	case PVR_440EP_RB:
+		puts("GR Rev. B");
+		break;
+#else
+	case PVR_440EP_RA:
+		puts("EP Rev. A");
+		break;
+	case PVR_440EP_RB:
+		puts("EP Rev. B");
+		break;
+#endif
+
 	default:
-		printf (" UNKNOWN (PVR=%08x)", pvr);
+		printf ("UNKNOWN (PVR=%08x)", pvr);
 		break;
 	}
 #endif
@@ -193,6 +209,12 @@ int checkcpu (void)
 
 int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
+#if defined(CONFIG_YOSEMITE) || defined(CONFIG_YELLOWSTONE)
+	/*give reset to BCSR*/
+	*(unsigned char*)(CFG_BCSR_BASE | 0x06) = 0x09;
+
+#else
+
 	/*
 	 * Initiate system reset in debug control register DBCR
 	 */
@@ -202,6 +224,8 @@ int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 #else
 	__asm__ __volatile__("mtspr 0x3f2, 3");
 #endif
+
+#endif/* defined(CONFIG_YOSEMITE) || defined(CONFIG_YELLOWSTONE)*/
 	return 1;
 }
 

+ 4 - 0
cpu/ppc4xx/cpu_init.c

@@ -188,7 +188,11 @@ cpu_init_f (void)
 	unsigned long val;
 
 	val = mfspr(tcr);
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+	val |= 0xb8000000;      /* generate system reset after 1.34 seconds */
+#else
 	val |= 0xf0000000;      /* generate system reset after 2.684 seconds */
+#endif
 	mtspr(tcr, val);
 
 	val = mfspr(tsr);

+ 4 - 1
cpu/ppc4xx/interrupts.c

@@ -430,7 +430,10 @@ void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg)
 #endif /* CONFIG_440_GX */
 #endif /* CONFIG_440 */
 
-	if (irqa[i].handler != NULL) {
+	/*
+	 * print warning when replacing with a different irq vector
+	 */
+	if ((irqa[i].handler != NULL) && (irqa[i].handler != handler)) {
 		printf ("Interrupt vector %d: handler 0x%x replacing 0x%x\n",
 			vec, (uint) handler, (uint) irqa[i].handler);
 	}

+ 9 - 4
cpu/ppc4xx/serial.c

@@ -269,9 +269,14 @@ int serial_tstc ()
 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) || defined(CONFIG_405EP)
 
 #if defined(CONFIG_440)
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+#define UART0_BASE  CFG_PERIPHERAL_BASE + 0x00000300
+#define UART1_BASE  CFG_PERIPHERAL_BASE + 0x00000400
+#else
 #define UART0_BASE  CFG_PERIPHERAL_BASE + 0x00000200
 #define UART1_BASE  CFG_PERIPHERAL_BASE + 0x00000300
-#if defined(CONFIG_440_GX)
+#endif
+#if defined(CONFIG_440_GX) || defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
 #define CR0_MASK        0xdfffffff
 #define CR0_EXTCLK_ENA  0x00800000
 #define CR0_UDIV_POS    0
@@ -301,14 +306,14 @@ int serial_tstc ()
 #if defined(CONFIG_UART1_CONSOLE)
 #define ACTING_UART0_BASE	UART1_BASE
 #define ACTING_UART1_BASE	UART0_BASE
-#if defined(CONFIG_440_GX)
+#if defined(CONFIG_440_GX) || defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
 #define UART0_SDR           sdr_uart1
 #define UART1_SDR           sdr_uart0
 #endif /* CONFIG_440_GX */
 #else
 #define ACTING_UART0_BASE	UART0_BASE
 #define ACTING_UART1_BASE	UART1_BASE
-#if defined(CONFIG_440_GX)
+#if defined(CONFIG_440_GX) || defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
 #define UART0_SDR           sdr_uart0
 #define UART1_SDR           sdr_uart1
 #endif /* CONFIG_440_GX */
@@ -460,7 +465,7 @@ int serial_init(void)
 	serial_divs (gd->baudrate, &udiv, &bdiv);
 #endif
 
-#if defined(CONFIG_440_GX)
+#if defined(CONFIG_440_GX) || defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
 	reg |= udiv << CR0_UDIV_POS;	/* set the UART divisor */
 #if defined(CONFIG_SERIAL_MULTI)
 	if (UART0_BASE == dev_base) {

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 352 - 388
cpu/ppc4xx/spd_sdram.c


+ 92 - 3
cpu/ppc4xx/speed.c

@@ -194,7 +194,96 @@ ulong get_PCI_freq (void)
 
 
 #elif defined(CONFIG_440)
-#if !defined(CONFIG_440_GX)
+
+#if  defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+void get_sys_info (sys_info_t *sysInfo)
+{
+	unsigned long temp;
+	unsigned long reg;
+	unsigned long lfdiv;
+	unsigned long m;
+	unsigned long prbdv0;
+	/*
+	  WARNING: ASSUMES the following:
+	  ENG=1
+	  PRADV0=1
+	  PRBDV0=1
+	*/
+
+	/* Decode CPR0_PLLD0 for divisors */
+	mfclk(clk_plld, reg);
+	temp = (reg & PLLD_FWDVA_MASK) >> 16;
+	sysInfo->pllFwdDivA = temp ? temp : 16;
+	temp = (reg & PLLD_FWDVB_MASK) >> 8;
+	sysInfo->pllFwdDivB = temp ? temp: 8 ;
+	temp = (reg & PLLD_FBDV_MASK) >> 24;
+	sysInfo->pllFbkDiv = temp ? temp : 32;
+	lfdiv = reg & PLLD_LFBDV_MASK;
+
+	mfclk(clk_opbd, reg);
+	temp = (reg & OPBDDV_MASK) >> 24;
+	sysInfo->pllOpbDiv = temp ? temp : 4;
+
+	mfclk(clk_perd, reg);
+	temp = (reg & PERDV_MASK) >> 24;
+	sysInfo->pllExtBusDiv = temp ? temp : 8;
+
+	mfclk(clk_primbd, reg);
+	temp = (reg & PRBDV_MASK) >> 24;
+	prbdv0 = temp ? temp : 8;
+
+	mfclk(clk_spcid, reg);
+	temp = (reg & SPCID_MASK) >> 24;
+	sysInfo->pllPciDiv = temp ? temp : 4;
+
+	/* Calculate 'M' based on feedback source */
+	mfsdr(sdr_sdstp0, reg);
+	temp = (reg & PLLSYS0_SEL_MASK) >> 27;
+	if (temp == 0) { /* PLL output */
+		/* Figure which pll to use */
+		mfclk(clk_pllc, reg);
+		temp = (reg & PLLC_SRC_MASK) >> 29;
+		if (!temp) /* PLLOUTA */
+			m = sysInfo->pllFbkDiv * lfdiv * sysInfo->pllFwdDivA;
+		else       /* PLLOUTB */
+			m = sysInfo->pllFbkDiv * lfdiv * sysInfo->pllFwdDivB;
+	}
+	else if (temp == 1) /* CPU output */
+		m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivA;
+	else /* PerClk */
+		m = sysInfo->pllExtBusDiv * sysInfo->pllOpbDiv * sysInfo->pllFwdDivB;
+
+	/* Now calculate the individual clocks */
+	sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m>>1);
+	sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
+	sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB/prbdv0;
+	sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
+	sysInfo->freqEPB = sysInfo->freqPLB/sysInfo->pllExtBusDiv;
+	sysInfo->freqPCI = sysInfo->freqPLB/sysInfo->pllPciDiv;
+
+	/* Figure which timer source to use */
+	if (mfspr(ccr1) & 0x0080) { /* External Clock, assume same as SYS_CLK */
+		temp = sysInfo->freqProcessor / 2;  /* Max extern clock speed */
+		if (CONFIG_SYS_CLK_FREQ > temp)
+			sysInfo->freqTmrClk = temp;
+		else
+			sysInfo->freqTmrClk = CONFIG_SYS_CLK_FREQ;
+	}
+	else  /* Internal clock */
+		sysInfo->freqTmrClk = sysInfo->freqProcessor;
+}
+/********************************************
+ * get_PCI_freq
+ * return PCI bus freq in Hz
+ *********************************************/
+ulong get_PCI_freq (void)
+{
+	sys_info_t sys_info;
+	get_sys_info (&sys_info);
+	return sys_info.freqPCI;
+}
+
+#elif !defined(CONFIG_440_GX)
 void get_sys_info (sys_info_t * sysInfo)
 {
 	unsigned long strp0;
@@ -220,8 +309,8 @@ void get_sys_info (sys_info_t * sysInfo)
 	sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m>>1);
 	sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA;
 	sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB;
-    if( get_pvr() == PVR_440GP_RB ) /* Rev B divs an extra 2 -- geez! */
-	sysInfo->freqPLB >>= 1;
+	if( get_pvr() == PVR_440GP_RB ) /* Rev B divs an extra 2 -- geez! */
+		sysInfo->freqPLB >>= 1;
 	sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv;
 	sysInfo->freqEPB = sysInfo->freqOPB/sysInfo->pllExtBusDiv;
 

+ 32 - 7
cpu/ppc4xx/start.S

@@ -344,7 +344,7 @@ _start:
 	lis	r1,0x0002		/* set CE bit (Critical Exceptions) */
 	ori	r1,r1,0x1000		/* set ME bit (Machine Exceptions) */
 	mtmsr	r1			/* change MSR */
-#else
+#elif !defined(CONFIG_440_EP) && !defined(CONFIG_440_GR)
 	bl	__440gx_msr_set
 	b	__440gx_msr_continue
 
@@ -377,6 +377,21 @@ __440gx_msr_continue:
 	/* Setup the internal SRAM */
 	/*----------------------------------------------------------------*/
 	li	r0,0
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+	/* Clear Dcache to use as RAM */
+	lis     r3,CFG_INIT_RAM_ADDR@h
+	li      r4,CFG_INIT_RAM_END@l
+	rlwinm. r5,r4,0,27,31
+	rlwinm  r5,r4,27,5,31
+	beq	..d_ran
+	addi    r5,r5,0x0001
+..d_ran:
+	mtctr   r5
+..d_ag:
+	dcbz    r0,r3
+	addi    r3,r3,32
+	bdnz    ..d_ag
+#else
 #if defined (CONFIG_440_GX)
 	mtdcr   l2_cache_cfg,r0		/* Ensure L2 Cache is off */
 #endif
@@ -407,6 +422,7 @@ __440gx_msr_continue:
 #else
 	ori	r1,r1,0x0380		/* 8k rw */
 	mtdcr	isram0_sb0cr,r1
+#endif
 #endif
 
 	/*----------------------------------------------------------------*/
@@ -957,7 +973,7 @@ invalidate_icache:
 invalidate_dcache:
 	addi	r6,0,0x0000		/* clear GPR 6 */
 	/* Do loop for # of dcache congruence classes. */
-#if defined(CONFIG_440_GX)
+#if defined(CONFIG_440_GX) || defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
 	lis     r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha	/* TBS for large sized cache */
 	ori     r7, r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
 #else
@@ -983,7 +999,7 @@ flush_dcache:
 	mtdccr	r10
 
 	/* do loop for # of congruence classes. */
-#if defined(CONFIG_440_GX)
+#if defined(CONFIG_440_GX) || defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
 	lis     r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha	/* TBS: for large cache sizes */
 	ori     r10,r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
 	lis     r11,(CFG_DCACHE_SIZE / 2)@ha /* D cache set size - 2 way sets */
@@ -1210,6 +1226,15 @@ ppcSync:
  */
 	.globl	relocate_code
 relocate_code:
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+	dccci	0,0		            /* Invalidate data cache, now no longer our stack */
+	sync
+	addi    r1,r0,0x0000        /* Tlb entry #0 */
+	tlbre	r0,r1,0x0002		/* Read contents */
+	ori     r0,r0,0x0c00        /* Or in the inhibit, write through bit */
+	tlbwe   r0,r1,0x0002		/* Save it out */
+	isync
+#endif
 	mr	r1,  r3		/* Set new stack pointer		*/
 	mr	r9,  r4		/* Save copy of Init Data pointer	*/
 	mr	r10, r5		/* Save copy of Destination Address	*/
@@ -1433,7 +1458,7 @@ trap_reloc:
 #ifdef CONFIG_405EP
 ppc405ep_init:
 
-#ifdef CONFIG_BUBINGA405EP
+#ifdef CONFIG_BUBINGA
 	/*
 	 * Initialize EBC chip selects 1 & 4 and GPIO pins (for alternate
 	 * function) to support FPGA and NVRAM accesses below.
@@ -1513,7 +1538,7 @@ ppc405ep_init:
 #endif
 
 	addi    r3,0,CPC0_PCI_HOST_CFG_EN
-#ifdef CONFIG_BUBINGA405EP
+#ifdef CONFIG_BUBINGA
 	/*
 	!-----------------------------------------------------------------------
 	! Check FPGA for PCI internal/external arbitration
@@ -1548,7 +1573,7 @@ ppc405ep_init:
 					  /* and CPU has been reset */
 					  /* so skip to next section */
 
-#ifdef CONFIG_BUBINGA405EP
+#ifdef CONFIG_BUBINGA
 	/*
 	!-----------------------------------------------------------------------
 	! Read NVRAM to get value to write in PLLMR.
@@ -1583,7 +1608,7 @@ ppc405ep_init:
 	cmpi     cr0,0,r5,1             /* See if PLL is locked */
 	beq     pll_write
 ..no_pllset:
-#endif /* CONFIG_BUBINGA405EP */
+#endif /* CONFIG_BUBINGA */
 
 	addis   r3,0,PLLMR0_DEFAULT@h       /* PLLMR0 default value */
 	ori     r3,r3,PLLMR0_DEFAULT@l     /* */

+ 1648 - 0
cpu/ppc4xx/usb_ohci.c

@@ -0,0 +1,1648 @@
+/*
+ * URB OHCI HCD (Host Controller Driver) for USB on the PPC 440.
+ *
+ * (C) Copyright 2003-2004
+ * Gary Jennejohn, DENX Software Engineering <gj@denx.de>
+ *
+ * (C) Copyright 2004
+ * Pierre Aubert, Staubli Faverges <p.aubert@staubli.com>
+ *
+ * Note: Much of this code has been derived from Linux 2.4
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2002 David Brownell
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+/*
+ * IMPORTANT NOTES
+ * 1 - this driver is intended for use with USB Mass Storage Devices
+ *     (BBB) ONLY. There is NO support for Interrupt or Isochronous pipes!
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_USB_OHCI
+
+#include <malloc.h>
+#include <usb.h>
+#include "usb_ohci.h"
+#include "usbdev.h"
+
+#define OHCI_USE_NPS		/* force NoPowerSwitching mode */
+#undef OHCI_VERBOSE_DEBUG	/* not always helpful */
+#undef DEBUG
+#undef SHOW_INFO
+#undef OHCI_FILL_TRACE
+
+/* For initializing controller (mask in an HCFS mode too) */
+#define OHCI_CONTROL_INIT \
+	(OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
+
+#define readl(a) (*((vu_long *)(a)))
+#define writel(a, b) (*((vu_long *)(b)) = ((vu_long)a))
+
+#define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
+
+#ifdef DEBUG
+#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg)
+#else
+#define dbg(format, arg...) do {} while(0)
+#endif				/* DEBUG */
+#define err(format, arg...) printf("ERROR: " format "\n", ## arg)
+#ifdef SHOW_INFO
+#define info(format, arg...) printf("INFO: " format "\n", ## arg)
+#else
+#define info(format, arg...) do {} while(0)
+#endif
+
+#define m16_swap(x) swap_16(x)
+#define m32_swap(x) swap_32(x)
+
+#if 1
+#define ohci_cpu_to_le16(x) (x)
+#define ohci_cpu_to_le32(x) (x)
+#else
+#define ohci_cpu_to_le16(x) swap_16(x)
+#define ohci_cpu_to_le32(x) swap_32(x)
+#endif
+
+/* global ohci_t */
+static ohci_t gohci;
+/* this must be aligned to a 256 byte boundary */
+struct ohci_hcca ghcca[1];
+/* a pointer to the aligned storage */
+struct ohci_hcca *phcca;
+/* this allocates EDs for all possible endpoints */
+struct ohci_device ohci_dev;
+/* urb_priv */
+urb_priv_t urb_priv;
+/* RHSC flag */
+int got_rhsc;
+/* device which was disconnected */
+struct usb_device *devgone;
+
+/*-------------------------------------------------------------------------*/
+
+/* AMD-756 (D2 rev) reports corrupt register contents in some cases.
+ * The erratum (#4) description is incorrect.  AMD's workaround waits
+ * till some bits (mostly reserved) are clear; ok for all revs.
+ */
+#define OHCI_QUIRK_AMD756 0xabcd
+#define read_roothub(hc, register, mask) ({ \
+	u32 temp = readl (&hc->regs->roothub.register); \
+	if (hc->flags & OHCI_QUIRK_AMD756) \
+		while (temp & mask) \
+			temp = readl (&hc->regs->roothub.register); \
+	temp; })
+
+static u32 roothub_a(struct ohci *hc)
+{
+	return read_roothub(hc, a, 0xfc0fe000);
+}
+static inline u32 roothub_b(struct ohci *hc)
+{
+	return readl(&hc->regs->roothub.b);
+}
+static inline u32 roothub_status(struct ohci *hc)
+{
+	return readl(&hc->regs->roothub.status);
+}
+static u32 roothub_portstatus(struct ohci *hc, int i)
+{
+	return read_roothub(hc, portstatus[i], 0xffe0fce0);
+}
+
+/* forward declaration */
+static int hc_interrupt(void);
+static void
+td_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer,
+	      int transfer_len, struct devrequest *setup, urb_priv_t * urb,
+	      int interval);
+
+/*-------------------------------------------------------------------------*
+ * URB support functions
+ *-------------------------------------------------------------------------*/
+
+/* free HCD-private data associated with this URB */
+
+static void urb_free_priv(urb_priv_t * urb)
+{
+	int i;
+	int last;
+	struct td *td;
+
+	last = urb->length - 1;
+	if (last >= 0) {
+		for (i = 0; i <= last; i++) {
+			td = urb->td[i];
+			if (td) {
+				td->usb_dev = NULL;
+				urb->td[i] = NULL;
+			}
+		}
+	}
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef DEBUG
+static int sohci_get_current_frame_number(struct usb_device *dev);
+
+/* debug| print the main components of an URB
+ * small: 0) header + data packets 1) just header */
+
+static void pkt_print(struct usb_device *dev, unsigned long pipe, void *buffer,
+		      int transfer_len, struct devrequest *setup, char *str,
+		      int small)
+{
+	urb_priv_t *purb = &urb_priv;
+
+	dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx",
+	    str,
+	    sohci_get_current_frame_number(dev),
+	    usb_pipedevice(pipe),
+	    usb_pipeendpoint(pipe),
+	    usb_pipeout(pipe) ? 'O' : 'I',
+	    usb_pipetype(pipe) < 2 ? (usb_pipeint(pipe) ? "INTR" : "ISOC") :
+	    (usb_pipecontrol(pipe) ? "CTRL" : "BULK"),
+	    purb->actual_length, transfer_len, dev->status);
+#ifdef	OHCI_VERBOSE_DEBUG
+	if (!small) {
+		int i, len;
+
+		if (usb_pipecontrol(pipe)) {
+			printf(__FILE__ ": cmd(8):");
+			for (i = 0; i < 8; i++)
+				printf(" %02x", ((__u8 *) setup)[i]);
+			printf("\n");
+		}
+		if (transfer_len > 0 && buffer) {
+			printf(__FILE__ ": data(%d/%d):",
+			       purb->actual_length, transfer_len);
+			len = usb_pipeout(pipe) ?
+			    transfer_len : purb->actual_length;
+			for (i = 0; i < 16 && i < len; i++)
+				printf(" %02x", ((__u8 *) buffer)[i]);
+			printf("%s\n", i < len ? "..." : "");
+		}
+	}
+#endif
+}
+
+/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/
+void ep_print_int_eds(ohci_t * ohci, char *str)
+{
+	int i, j;
+	__u32 *ed_p;
+	for (i = 0; i < 32; i++) {
+		j = 5;
+		ed_p = &(ohci->hcca->int_table[i]);
+		if (*ed_p == 0)
+			continue;
+		printf(__FILE__ ": %s branch int %2d(%2x):", str, i, i);
+		while (*ed_p != 0 && j--) {
+			ed_t *ed = (ed_t *) ohci_cpu_to_le32(ed_p);
+			printf(" ed: %4x;", ed->hwINFO);
+			ed_p = &ed->hwNextED;
+		}
+		printf("\n");
+	}
+}
+
+static void ohci_dump_intr_mask(char *label, __u32 mask)
+{
+	dbg("%s: 0x%08x%s%s%s%s%s%s%s%s%s",
+	    label,
+	    mask,
+	    (mask & OHCI_INTR_MIE) ? " MIE" : "",
+	    (mask & OHCI_INTR_OC) ? " OC" : "",
+	    (mask & OHCI_INTR_RHSC) ? " RHSC" : "",
+	    (mask & OHCI_INTR_FNO) ? " FNO" : "",
+	    (mask & OHCI_INTR_UE) ? " UE" : "",
+	    (mask & OHCI_INTR_RD) ? " RD" : "",
+	    (mask & OHCI_INTR_SF) ? " SF" : "",
+	    (mask & OHCI_INTR_WDH) ? " WDH" : "",
+	    (mask & OHCI_INTR_SO) ? " SO" : "");
+}
+
+static void maybe_print_eds(char *label, __u32 value)
+{
+	ed_t *edp = (ed_t *) value;
+
+	if (value) {
+		dbg("%s %08x", label, value);
+		dbg("%08x", edp->hwINFO);
+		dbg("%08x", edp->hwTailP);
+		dbg("%08x", edp->hwHeadP);
+		dbg("%08x", edp->hwNextED);
+	}
+}
+
+static char *hcfs2string(int state)
+{
+	switch (state) {
+	case OHCI_USB_RESET:
+		return "reset";
+	case OHCI_USB_RESUME:
+		return "resume";
+	case OHCI_USB_OPER:
+		return "operational";
+	case OHCI_USB_SUSPEND:
+		return "suspend";
+	}
+	return "?";
+}
+
+/* dump control and status registers */
+static void ohci_dump_status(ohci_t * controller)
+{
+	struct ohci_regs *regs = controller->regs;
+	__u32 temp;
+
+	temp = readl(&regs->revision) & 0xff;
+	if (temp != 0x10)
+		dbg("spec %d.%d", (temp >> 4), (temp & 0x0f));
+
+	temp = readl(&regs->control);
+	dbg("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp,
+	    (temp & OHCI_CTRL_RWE) ? " RWE" : "",
+	    (temp & OHCI_CTRL_RWC) ? " RWC" : "",
+	    (temp & OHCI_CTRL_IR) ? " IR" : "",
+	    hcfs2string(temp & OHCI_CTRL_HCFS),
+	    (temp & OHCI_CTRL_BLE) ? " BLE" : "",
+	    (temp & OHCI_CTRL_CLE) ? " CLE" : "",
+	    (temp & OHCI_CTRL_IE) ? " IE" : "",
+	    (temp & OHCI_CTRL_PLE) ? " PLE" : "", temp & OHCI_CTRL_CBSR);
+
+	temp = readl(&regs->cmdstatus);
+	dbg("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp,
+	    (temp & OHCI_SOC) >> 16,
+	    (temp & OHCI_OCR) ? " OCR" : "",
+	    (temp & OHCI_BLF) ? " BLF" : "",
+	    (temp & OHCI_CLF) ? " CLF" : "", (temp & OHCI_HCR) ? " HCR" : "");
+
+	ohci_dump_intr_mask("intrstatus", readl(&regs->intrstatus));
+	ohci_dump_intr_mask("intrenable", readl(&regs->intrenable));
+
+	maybe_print_eds("ed_periodcurrent", readl(&regs->ed_periodcurrent));
+
+	maybe_print_eds("ed_controlhead", readl(&regs->ed_controlhead));
+	maybe_print_eds("ed_controlcurrent", readl(&regs->ed_controlcurrent));
+
+	maybe_print_eds("ed_bulkhead", readl(&regs->ed_bulkhead));
+	maybe_print_eds("ed_bulkcurrent", readl(&regs->ed_bulkcurrent));
+
+	maybe_print_eds("donehead", readl(&regs->donehead));
+}
+
+static void ohci_dump_roothub(ohci_t * controller, int verbose)
+{
+	__u32 temp, ndp, i;
+
+	temp = roothub_a(controller);
+	ndp = (temp & RH_A_NDP);
+
+	if (verbose) {
+		dbg("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp,
+		    ((temp & RH_A_POTPGT) >> 24) & 0xff,
+		    (temp & RH_A_NOCP) ? " NOCP" : "",
+		    (temp & RH_A_OCPM) ? " OCPM" : "",
+		    (temp & RH_A_DT) ? " DT" : "",
+		    (temp & RH_A_NPS) ? " NPS" : "",
+		    (temp & RH_A_PSM) ? " PSM" : "", ndp);
+		temp = roothub_b(controller);
+		dbg("roothub.b: %08x PPCM=%04x DR=%04x",
+		    temp, (temp & RH_B_PPCM) >> 16, (temp & RH_B_DR)
+		    );
+		temp = roothub_status(controller);
+		dbg("roothub.status: %08x%s%s%s%s%s%s",
+		    temp,
+		    (temp & RH_HS_CRWE) ? " CRWE" : "",
+		    (temp & RH_HS_OCIC) ? " OCIC" : "",
+		    (temp & RH_HS_LPSC) ? " LPSC" : "",
+		    (temp & RH_HS_DRWE) ? " DRWE" : "",
+		    (temp & RH_HS_OCI) ? " OCI" : "",
+		    (temp & RH_HS_LPS) ? " LPS" : "");
+	}
+
+	for (i = 0; i < ndp; i++) {
+		temp = roothub_portstatus(controller, i);
+		dbg("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s",
+		    i,
+		    temp,
+		    (temp & RH_PS_PRSC) ? " PRSC" : "",
+		    (temp & RH_PS_OCIC) ? " OCIC" : "",
+		    (temp & RH_PS_PSSC) ? " PSSC" : "",
+		    (temp & RH_PS_PESC) ? " PESC" : "",
+		    (temp & RH_PS_CSC) ? " CSC" : "",
+		    (temp & RH_PS_LSDA) ? " LSDA" : "",
+		    (temp & RH_PS_PPS) ? " PPS" : "",
+		    (temp & RH_PS_PRS) ? " PRS" : "",
+		    (temp & RH_PS_POCI) ? " POCI" : "",
+		    (temp & RH_PS_PSS) ? " PSS" : "",
+		    (temp & RH_PS_PES) ? " PES" : "",
+		    (temp & RH_PS_CCS) ? " CCS" : "");
+	}
+}
+
+static void ohci_dump(ohci_t * controller, int verbose)
+{
+	dbg("OHCI controller usb-%s state", controller->slot_name);
+
+	/* dumps some of the state we know about */
+	ohci_dump_status(controller);
+	if (verbose)
+		ep_print_int_eds(controller, "hcca");
+	dbg("hcca frame #%04x", controller->hcca->frame_no);
+	ohci_dump_roothub(controller, 1);
+}
+
+#endif				/* DEBUG */
+
+/*-------------------------------------------------------------------------*
+ * Interface functions (URB)
+ *-------------------------------------------------------------------------*/
+
+/* get a transfer request */
+
+int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer,
+		     int transfer_len, struct devrequest *setup, int interval)
+{
+	ohci_t *ohci;
+	ed_t *ed;
+	urb_priv_t *purb_priv;
+	int i, size = 0;
+
+	ohci = &gohci;
+
+	/* when controller's hung, permit only roothub cleanup attempts
+	 * such as powering down ports */
+	if (ohci->disabled) {
+		err("sohci_submit_job: EPIPE");
+		return -1;
+	}
+
+	/* every endpoint has a ed, locate and fill it */
+	if (!(ed = ep_add_ed(dev, pipe))) {
+		err("sohci_submit_job: ENOMEM");
+		return -1;
+	}
+
+	/* for the private part of the URB we need the number of TDs (size) */
+	switch (usb_pipetype(pipe)) {
+	case PIPE_BULK:	/* one TD for every 4096 Byte */
+		size = (transfer_len - 1) / 4096 + 1;
+		break;
+	case PIPE_CONTROL:	/* 1 TD for setup, 1 for ACK and 1 for every 4096 B */
+		size = (transfer_len == 0) ? 2 : (transfer_len - 1) / 4096 + 3;
+		break;
+	}
+
+	if (size >= (N_URB_TD - 1)) {
+		err("need %d TDs, only have %d", size, N_URB_TD);
+		return -1;
+	}
+	purb_priv = &urb_priv;
+	purb_priv->pipe = pipe;
+
+	/* fill the private part of the URB */
+	purb_priv->length = size;
+	purb_priv->ed = ed;
+	purb_priv->actual_length = 0;
+
+	/* allocate the TDs */
+	/* note that td[0] was allocated in ep_add_ed */
+	for (i = 0; i < size; i++) {
+		purb_priv->td[i] = td_alloc(dev);
+		if (!purb_priv->td[i]) {
+			purb_priv->length = i;
+			urb_free_priv(purb_priv);
+			err("sohci_submit_job: ENOMEM");
+			return -1;
+		}
+	}
+
+	if (ed->state == ED_NEW || (ed->state & ED_DEL)) {
+		urb_free_priv(purb_priv);
+		err("sohci_submit_job: EINVAL");
+		return -1;
+	}
+
+	/* link the ed into a chain if is not already */
+	if (ed->state != ED_OPER)
+		ep_link(ohci, ed);
+
+	/* fill the TDs and link it to the ed */
+	td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv,
+		      interval);
+
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef DEBUG
+/* tell us the current USB frame number */
+
+static int sohci_get_current_frame_number(struct usb_device *usb_dev)
+{
+	ohci_t *ohci = &gohci;
+
+	return ohci_cpu_to_le16(ohci->hcca->frame_no);
+}
+#endif
+
+/*-------------------------------------------------------------------------*
+ * ED handling functions
+ *-------------------------------------------------------------------------*/
+
+/* link an ed into one of the HC chains */
+
+static int ep_link(ohci_t * ohci, ed_t * edi)
+{
+	volatile ed_t *ed = edi;
+
+	ed->state = ED_OPER;
+
+	switch (ed->type) {
+	case PIPE_CONTROL:
+		ed->hwNextED = 0;
+		if (ohci->ed_controltail == NULL) {
+			writel(ed, &ohci->regs->ed_controlhead);
+		} else {
+			ohci->ed_controltail->hwNextED =
+			    ohci_cpu_to_le32((unsigned long)ed);
+		}
+		ed->ed_prev = ohci->ed_controltail;
+		if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
+		    !ohci->ed_rm_list[1] && !ohci->sleeping) {
+			ohci->hc_control |= OHCI_CTRL_CLE;
+			writel(ohci->hc_control, &ohci->regs->control);
+		}
+		ohci->ed_controltail = edi;
+		break;
+
+	case PIPE_BULK:
+		ed->hwNextED = 0;
+		if (ohci->ed_bulktail == NULL) {
+			writel(ed, &ohci->regs->ed_bulkhead);
+		} else {
+			ohci->ed_bulktail->hwNextED =
+			    ohci_cpu_to_le32((unsigned long)ed);
+		}
+		ed->ed_prev = ohci->ed_bulktail;
+		if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
+		    !ohci->ed_rm_list[1] && !ohci->sleeping) {
+			ohci->hc_control |= OHCI_CTRL_BLE;
+			writel(ohci->hc_control, &ohci->regs->control);
+		}
+		ohci->ed_bulktail = edi;
+		break;
+	}
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* unlink an ed from one of the HC chains.
+ * just the link to the ed is unlinked.
+ * the link from the ed still points to another operational ed or 0
+ * so the HC can eventually finish the processing of the unlinked ed */
+
+static int ep_unlink(ohci_t * ohci, ed_t * edi)
+{
+	volatile ed_t *ed = edi;
+
+	ed->hwINFO |= ohci_cpu_to_le32(OHCI_ED_SKIP);
+
+	switch (ed->type) {
+	case PIPE_CONTROL:
+		if (ed->ed_prev == NULL) {
+			if (!ed->hwNextED) {
+				ohci->hc_control &= ~OHCI_CTRL_CLE;
+				writel(ohci->hc_control, &ohci->regs->control);
+			}
+			writel(ohci_cpu_to_le32(*((__u32 *) & ed->hwNextED)),
+			       &ohci->regs->ed_controlhead);
+		} else {
+			ed->ed_prev->hwNextED = ed->hwNextED;
+		}
+		if (ohci->ed_controltail == ed) {
+			ohci->ed_controltail = ed->ed_prev;
+		} else {
+			((ed_t *)
+			 ohci_cpu_to_le32(*((__u32 *) & ed->hwNextED)))->
+		   ed_prev = ed->ed_prev;
+		}
+		break;
+
+	case PIPE_BULK:
+		if (ed->ed_prev == NULL) {
+			if (!ed->hwNextED) {
+				ohci->hc_control &= ~OHCI_CTRL_BLE;
+				writel(ohci->hc_control, &ohci->regs->control);
+			}
+			writel(ohci_cpu_to_le32(*((__u32 *) & ed->hwNextED)),
+			       &ohci->regs->ed_bulkhead);
+		} else {
+			ed->ed_prev->hwNextED = ed->hwNextED;
+		}
+		if (ohci->ed_bulktail == ed) {
+			ohci->ed_bulktail = ed->ed_prev;
+		} else {
+			((ed_t *)
+			 ohci_cpu_to_le32(*((__u32 *) & ed->hwNextED)))->
+		   ed_prev = ed->ed_prev;
+		}
+		break;
+	}
+	ed->state = ED_UNLINK;
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* add/reinit an endpoint; this should be done once at the usb_set_configuration command,
+ * but the USB stack is a little bit stateless	so we do it at every transaction
+ * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK
+ * in all other cases the state is left unchanged
+ * the ed info fields are setted anyway even though most of them should not change */
+
+static ed_t *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe)
+{
+	td_t *td;
+	ed_t *ed_ret;
+	volatile ed_t *ed;
+
+	ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint(pipe) << 1) |
+				   (usb_pipecontrol(pipe) ? 0 :
+				    usb_pipeout(pipe))];
+
+	if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) {
+		err("ep_add_ed: pending delete");
+		/* pending delete request */
+		return NULL;
+	}
+
+	if (ed->state == ED_NEW) {
+		ed->hwINFO = ohci_cpu_to_le32(OHCI_ED_SKIP);	/* skip ed */
+		/* dummy td; end of td list for ed */
+		td = td_alloc(usb_dev);
+		ed->hwTailP = ohci_cpu_to_le32((unsigned long)td);
+		ed->hwHeadP = ed->hwTailP;
+		ed->state = ED_UNLINK;
+		ed->type = usb_pipetype(pipe);
+		ohci_dev.ed_cnt++;
+	}
+
+	ed->hwINFO = ohci_cpu_to_le32(usb_pipedevice(pipe)
+				      | usb_pipeendpoint(pipe) << 7
+				      | (usb_pipeisoc(pipe) ? 0x8000 : 0)
+				      | (usb_pipecontrol(pipe) ? 0
+					 : (usb_pipeout(pipe) ? 0x800 : 0x1000))
+				      | usb_pipeslow(pipe) << 13 |
+				      usb_maxpacket(usb_dev, pipe) << 16);
+
+	return ed_ret;
+}
+
+/*-------------------------------------------------------------------------*
+ * TD handling functions
+ *-------------------------------------------------------------------------*/
+
+/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */
+
+static void td_fill(ohci_t * ohci, unsigned int info,
+		    void *data, int len,
+		    struct usb_device *dev, int index, urb_priv_t * urb_priv)
+{
+	volatile td_t *td, *td_pt;
+#ifdef OHCI_FILL_TRACE
+	int i;
+#endif
+
+	if (index > urb_priv->length) {
+		err("index > length");
+		return;
+	}
+	/* use this td as the next dummy */
+	td_pt = urb_priv->td[index];
+	td_pt->hwNextTD = 0;
+
+	/* fill the old dummy TD */
+	td = urb_priv->td[index] =
+	    (td_t *) (ohci_cpu_to_le32(urb_priv->ed->hwTailP) & ~0xf);
+
+	td->ed = urb_priv->ed;
+	td->next_dl_td = NULL;
+	td->index = index;
+	td->data = (__u32) data;
+#ifdef OHCI_FILL_TRACE
+	if ((usb_pipetype(urb_priv->pipe) == PIPE_BULK)
+	    && usb_pipeout(urb_priv->pipe)) {
+		for (i = 0; i < len; i++)
+			printf("td->data[%d] %#2x ", i,
+			       ((unsigned char *)td->data)[i]);
+		printf("\n");
+	}
+#endif
+	if (!len)
+		data = 0;
+
+	td->hwINFO = ohci_cpu_to_le32(info);
+	td->hwCBP = ohci_cpu_to_le32((unsigned long)data);
+	if (data)
+		td->hwBE = ohci_cpu_to_le32((unsigned long)(data + len - 1));
+	else
+		td->hwBE = 0;
+	td->hwNextTD = ohci_cpu_to_le32((unsigned long)td_pt);
+	td->hwPSW[0] = ohci_cpu_to_le16(((__u32) data & 0x0FFF) | 0xE000);
+
+	/* append to queue */
+	td->ed->hwTailP = td->hwNextTD;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* prepare all TDs of a transfer */
+
+static void td_submit_job(struct usb_device *dev, unsigned long pipe,
+			  void *buffer, int transfer_len,
+			  struct devrequest *setup, urb_priv_t * urb,
+			  int interval)
+{
+	ohci_t *ohci = &gohci;
+	int data_len = transfer_len;
+	void *data;
+	int cnt = 0;
+	__u32 info = 0;
+	unsigned int toggle = 0;
+
+	/* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */
+	if (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {
+		toggle = TD_T_TOGGLE;
+	} else {
+		toggle = TD_T_DATA0;
+		usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe),
+			      1);
+	}
+	urb->td_cnt = 0;
+	if (data_len)
+		data = buffer;
+	else
+		data = 0;
+
+	switch (usb_pipetype(pipe)) {
+	case PIPE_BULK:
+		info = usb_pipeout(pipe) ? TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN;
+		while (data_len > 4096) {
+			td_fill(ohci, info | (cnt ? TD_T_TOGGLE : toggle), data,
+				4096, dev, cnt, urb);
+			data += 4096;
+			data_len -= 4096;
+			cnt++;
+		}
+		info = usb_pipeout(pipe) ?
+		    TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN;
+		td_fill(ohci, info | (cnt ? TD_T_TOGGLE : toggle), data,
+			data_len, dev, cnt, urb);
+		cnt++;
+
+		if (!ohci->sleeping)
+			writel(OHCI_BLF, &ohci->regs->cmdstatus);	/* start bulk list */
+		break;
+
+	case PIPE_CONTROL:
+		info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
+		td_fill(ohci, info, setup, 8, dev, cnt++, urb);
+		if (data_len > 0) {
+			info = usb_pipeout(pipe) ?
+			    TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R
+			    | TD_DP_IN | TD_T_DATA1;
+			/* NOTE:  mishandles transfers >8K, some >4K */
+			td_fill(ohci, info, data, data_len, dev, cnt++, urb);
+		}
+		info = usb_pipeout(pipe) ?
+		    TD_CC | TD_DP_IN | TD_T_DATA1 : TD_CC | TD_DP_OUT |
+		    TD_T_DATA1;
+		td_fill(ohci, info, data, 0, dev, cnt++, urb);
+		if (!ohci->sleeping)
+			writel(OHCI_CLF, &ohci->regs->cmdstatus);	/* start Control list */
+		break;
+	}
+	if (urb->length != cnt)
+		dbg("TD LENGTH %d != CNT %d", urb->length, cnt);
+}
+
+/*-------------------------------------------------------------------------*
+ * Done List handling functions
+ *-------------------------------------------------------------------------*/
+
+/* calculate the transfer length and update the urb */
+
+static void dl_transfer_length(td_t * td)
+{
+	__u32 tdINFO, tdBE, tdCBP;
+	urb_priv_t *lurb_priv = &urb_priv;
+
+	tdINFO = ohci_cpu_to_le32(td->hwINFO);
+	tdBE = ohci_cpu_to_le32(td->hwBE);
+	tdCBP = ohci_cpu_to_le32(td->hwCBP);
+
+	if (!(usb_pipetype(lurb_priv->pipe) == PIPE_CONTROL &&
+	      ((td->index == 0) || (td->index == lurb_priv->length - 1)))) {
+		if (tdBE != 0) {
+			if (td->hwCBP == 0)
+				lurb_priv->actual_length += tdBE - td->data + 1;
+			else
+				lurb_priv->actual_length += tdCBP - td->data;
+		}
+	}
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* replies to the request have to be on a FIFO basis so
+ * we reverse the reversed done-list */
+
+static td_t *dl_reverse_done_list(ohci_t * ohci)
+{
+	__u32 td_list_hc;
+	td_t *td_rev = NULL;
+	td_t *td_list = NULL;
+	urb_priv_t *lurb_priv = NULL;
+
+	td_list_hc = ohci_cpu_to_le32(ohci->hcca->done_head) & 0xfffffff0;
+	ohci->hcca->done_head = 0;
+
+	while (td_list_hc) {
+		td_list = (td_t *) td_list_hc;
+
+		if (TD_CC_GET(ohci_cpu_to_le32(td_list->hwINFO))) {
+			lurb_priv = &urb_priv;
+			dbg(" USB-error/status: %x : %p",
+			    TD_CC_GET(ohci_cpu_to_le32(td_list->hwINFO)),
+			    td_list);
+			if (td_list->ed->hwHeadP & ohci_cpu_to_le32(0x1)) {
+				if (lurb_priv
+				    && ((td_list->index + 1) <
+					lurb_priv->length)) {
+					td_list->ed->hwHeadP =
+					    (lurb_priv->
+					     td[lurb_priv->length -
+						1]->
+					     hwNextTD &
+					     ohci_cpu_to_le32(0xfffffff0)) |
+					    (td_list->ed->
+					     hwHeadP & ohci_cpu_to_le32(0x2));
+					lurb_priv->td_cnt +=
+					    lurb_priv->length - td_list->index -
+					    1;
+				} else
+					td_list->ed->hwHeadP &=
+					    ohci_cpu_to_le32(0xfffffff2);
+			}
+#ifdef CONFIG_MPC5200
+			td_list->hwNextTD = 0;
+#endif
+		}
+
+		td_list->next_dl_td = td_rev;
+		td_rev = td_list;
+		td_list_hc = ohci_cpu_to_le32(td_list->hwNextTD) & 0xfffffff0;
+	}
+	return td_list;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* td done list */
+static int dl_done_list(ohci_t * ohci, td_t * td_list)
+{
+	td_t *td_list_next = NULL;
+	ed_t *ed;
+	int cc = 0;
+	int stat = 0xff;
+	/* urb_t *urb; */
+	urb_priv_t *lurb_priv;
+	__u32 tdINFO, edHeadP, edTailP;
+
+	while (td_list) {
+		td_list_next = td_list->next_dl_td;
+
+		lurb_priv = &urb_priv;
+		tdINFO = ohci_cpu_to_le32(td_list->hwINFO);
+
+		ed = td_list->ed;
+
+		dl_transfer_length(td_list);
+
+		/* error code of transfer */
+		cc = TD_CC_GET(tdINFO);
+		if (++(lurb_priv->td_cnt) == lurb_priv->length) {
+			if ((ed->state & (ED_OPER | ED_UNLINK))
+			    && (lurb_priv->state != URB_DEL)) {
+				dbg("ConditionCode %#x", cc);
+				stat = cc_to_error[cc];
+			}
+		}
+
+		if (ed->state != ED_NEW) {
+			edHeadP = ohci_cpu_to_le32(ed->hwHeadP) & 0xfffffff0;
+			edTailP = ohci_cpu_to_le32(ed->hwTailP);
+
+			/* unlink eds if they are not busy */
+			if ((edHeadP == edTailP) && (ed->state == ED_OPER))
+				ep_unlink(ohci, ed);
+		}
+
+		td_list = td_list_next;
+	}
+	return stat;
+}
+
+/*-------------------------------------------------------------------------*
+ * Virtual Root Hub
+ *-------------------------------------------------------------------------*/
+
+/* Device descriptor */
+static __u8 root_hub_dev_des[] = {
+	0x12,			/*  __u8  bLength; */
+	0x01,			/*  __u8  bDescriptorType; Device */
+	0x10,			/*  __u16 bcdUSB; v1.1 */
+	0x01,
+	0x09,			/*  __u8  bDeviceClass; HUB_CLASSCODE */
+	0x00,			/*  __u8  bDeviceSubClass; */
+	0x00,			/*  __u8  bDeviceProtocol; */
+	0x08,			/*  __u8  bMaxPacketSize0; 8 Bytes */
+	0x00,			/*  __u16 idVendor; */
+	0x00,
+	0x00,			/*  __u16 idProduct; */
+	0x00,
+	0x00,			/*  __u16 bcdDevice; */
+	0x00,
+	0x00,			/*  __u8  iManufacturer; */
+	0x01,			/*  __u8  iProduct; */
+	0x00,			/*  __u8  iSerialNumber; */
+	0x01			/*  __u8  bNumConfigurations; */
+};
+
+/* Configuration descriptor */
+static __u8 root_hub_config_des[] = {
+	0x09,			/*  __u8  bLength; */
+	0x02,			/*  __u8  bDescriptorType; Configuration */
+	0x19,			/*  __u16 wTotalLength; */
+	0x00,
+	0x01,			/*  __u8  bNumInterfaces; */
+	0x01,			/*  __u8  bConfigurationValue; */
+	0x00,			/*  __u8  iConfiguration; */
+	0x40,			/*  __u8  bmAttributes;
+				   Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
+	0x00,			/*  __u8  MaxPower; */
+
+	/* interface */
+	0x09,			/*  __u8  if_bLength; */
+	0x04,			/*  __u8  if_bDescriptorType; Interface */
+	0x00,			/*  __u8  if_bInterfaceNumber; */
+	0x00,			/*  __u8  if_bAlternateSetting; */
+	0x01,			/*  __u8  if_bNumEndpoints; */
+	0x09,			/*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
+	0x00,			/*  __u8  if_bInterfaceSubClass; */
+	0x00,			/*  __u8  if_bInterfaceProtocol; */
+	0x00,			/*  __u8  if_iInterface; */
+
+	/* endpoint */
+	0x07,			/*  __u8  ep_bLength; */
+	0x05,			/*  __u8  ep_bDescriptorType; Endpoint */
+	0x81,			/*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
+	0x03,			/*  __u8  ep_bmAttributes; Interrupt */
+	0x02,			/*  __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
+	0x00,
+	0xff			/*  __u8  ep_bInterval; 255 ms */
+};
+
+static unsigned char root_hub_str_index0[] = {
+	0x04,			/*  __u8  bLength; */
+	0x03,			/*  __u8  bDescriptorType; String-descriptor */
+	0x09,			/*  __u8  lang ID */
+	0x04,			/*  __u8  lang ID */
+};
+
+static unsigned char root_hub_str_index1[] = {
+	28,			/*  __u8  bLength; */
+	0x03,			/*  __u8  bDescriptorType; String-descriptor */
+	'O',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'H',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'C',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'I',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	' ',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'R',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'o',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'o',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	't',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	' ',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'H',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'u',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'b',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+};
+
+/* Hub class-specific descriptor is constructed dynamically */
+
+/*-------------------------------------------------------------------------*/
+
+#define OK(x)			len = (x); break
+#ifdef DEBUG
+#define WR_RH_STAT(x)		{info("WR:status %#8x", (x));writel((x), &gohci.regs->roothub.status);}
+#define WR_RH_PORTSTAT(x)	{info("WR:portstatus[%d] %#8x", wIndex-1, (x));writel((x), &gohci.regs->roothub.portstatus[wIndex-1]);}
+#else
+#define WR_RH_STAT(x)		writel((x), &gohci.regs->roothub.status)
+#define WR_RH_PORTSTAT(x)	writel((x), &gohci.regs->roothub.portstatus[wIndex-1])
+#endif
+#define RD_RH_STAT		roothub_status(&gohci)
+#define RD_RH_PORTSTAT		roothub_portstatus(&gohci,wIndex-1)
+
+/* request to virtual root hub */
+
+int rh_check_port_status(ohci_t * controller)
+{
+	__u32 temp, ndp, i;
+	int res;
+
+	res = -1;
+	temp = roothub_a(controller);
+	ndp = (temp & RH_A_NDP);
+	for (i = 0; i < ndp; i++) {
+		temp = roothub_portstatus(controller, i);
+		/* check for a device disconnect */
+		if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
+		     (RH_PS_PESC | RH_PS_CSC)) && ((temp & RH_PS_CCS) == 0)) {
+			res = i;
+			break;
+		}
+	}
+	return res;
+}
+
+static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+			      void *buffer, int transfer_len,
+			      struct devrequest *cmd)
+{
+	void *data = buffer;
+	int leni = transfer_len;
+	int len = 0;
+	int stat = 0;
+	__u32 datab[4];
+	__u8 *data_buf = (__u8 *) datab;
+	__u16 bmRType_bReq;
+	__u16 wValue;
+	__u16 wIndex;
+	__u16 wLength;
+
+#ifdef DEBUG
+	urb_priv.actual_length = 0;
+	pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)",
+		  usb_pipein(pipe));
+#endif
+	if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
+		info("Root-Hub submit IRQ: NOT implemented");
+		return 0;
+	}
+
+	bmRType_bReq = cmd->requesttype | (cmd->request << 8);
+	wValue = m16_swap(cmd->value);
+	wIndex = m16_swap(cmd->index);
+	wLength = m16_swap(cmd->length);
+
+	info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x",
+	     dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength);
+
+	switch (bmRType_bReq) {
+		/* Request Destination:
+		   without flags: Device,
+		   RH_INTERFACE: interface,
+		   RH_ENDPOINT: endpoint,
+		   RH_CLASS means HUB here,
+		   RH_OTHER | RH_CLASS  almost ever means HUB_PORT here
+		 */
+
+	case RH_GET_STATUS:
+		*(__u16 *) data_buf = m16_swap(1);
+		OK(2);
+	case RH_GET_STATUS | RH_INTERFACE:
+		*(__u16 *) data_buf = m16_swap(0);
+		OK(2);
+	case RH_GET_STATUS | RH_ENDPOINT:
+		*(__u16 *) data_buf = m16_swap(0);
+		OK(2);
+	case RH_GET_STATUS | RH_CLASS:
+		*(__u32 *) data_buf =
+		    m32_swap(RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
+		OK(4);
+	case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+		*(__u32 *) data_buf = m32_swap(RD_RH_PORTSTAT);
+		OK(4);
+
+	case RH_CLEAR_FEATURE | RH_ENDPOINT:
+		switch (wValue) {
+		case (RH_ENDPOINT_STALL):
+			OK(0);
+		}
+		break;
+
+	case RH_CLEAR_FEATURE | RH_CLASS:
+		switch (wValue) {
+		case RH_C_HUB_LOCAL_POWER:
+			OK(0);
+		case (RH_C_HUB_OVER_CURRENT):
+			WR_RH_STAT(RH_HS_OCIC);
+			OK(0);
+		}
+		break;
+
+	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+		switch (wValue) {
+		case (RH_PORT_ENABLE):
+			WR_RH_PORTSTAT(RH_PS_CCS);
+			OK(0);
+		case (RH_PORT_SUSPEND):
+			WR_RH_PORTSTAT(RH_PS_POCI);
+			OK(0);
+		case (RH_PORT_POWER):
+			WR_RH_PORTSTAT(RH_PS_LSDA);
+			OK(0);
+		case (RH_C_PORT_CONNECTION):
+			WR_RH_PORTSTAT(RH_PS_CSC);
+			OK(0);
+		case (RH_C_PORT_ENABLE):
+			WR_RH_PORTSTAT(RH_PS_PESC);
+			OK(0);
+		case (RH_C_PORT_SUSPEND):
+			WR_RH_PORTSTAT(RH_PS_PSSC);
+			OK(0);
+		case (RH_C_PORT_OVER_CURRENT):
+			WR_RH_PORTSTAT(RH_PS_OCIC);
+			OK(0);
+		case (RH_C_PORT_RESET):
+			WR_RH_PORTSTAT(RH_PS_PRSC);
+			OK(0);
+		}
+		break;
+
+	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+		switch (wValue) {
+		case (RH_PORT_SUSPEND):
+			WR_RH_PORTSTAT(RH_PS_PSS);
+			OK(0);
+		case (RH_PORT_RESET):	/* BUG IN HUP CODE ******** */
+			if (RD_RH_PORTSTAT & RH_PS_CCS)
+				WR_RH_PORTSTAT(RH_PS_PRS);
+			OK(0);
+		case (RH_PORT_POWER):
+			WR_RH_PORTSTAT(RH_PS_PPS);
+			OK(0);
+		case (RH_PORT_ENABLE):	/* BUG IN HUP CODE ******** */
+			if (RD_RH_PORTSTAT & RH_PS_CCS)
+				WR_RH_PORTSTAT(RH_PS_PES);
+			OK(0);
+		}
+		break;
+
+	case RH_SET_ADDRESS:
+		gohci.rh.devnum = wValue;
+		OK(0);
+
+	case RH_GET_DESCRIPTOR:
+		switch ((wValue & 0xff00) >> 8) {
+		case (0x01):	/* device descriptor */
+			len = min_t(unsigned int,
+				    leni,
+				    min_t(unsigned int,
+					  sizeof(root_hub_dev_des), wLength));
+			data_buf = root_hub_dev_des;
+			OK(len);
+		case (0x02):	/* configuration descriptor */
+			len = min_t(unsigned int,
+				    leni,
+				    min_t(unsigned int,
+					  sizeof(root_hub_config_des),
+					  wLength));
+			data_buf = root_hub_config_des;
+			OK(len);
+		case (0x03):	/* string descriptors */
+			if (wValue == 0x0300) {
+				len = min_t(unsigned int,
+					    leni,
+					    min_t(unsigned int,
+						  sizeof(root_hub_str_index0),
+						  wLength));
+				data_buf = root_hub_str_index0;
+				OK(len);
+			}
+			if (wValue == 0x0301) {
+				len = min_t(unsigned int,
+					    leni,
+					    min_t(unsigned int,
+						  sizeof(root_hub_str_index1),
+						  wLength));
+				data_buf = root_hub_str_index1;
+				OK(len);
+			}
+		default:
+			stat = USB_ST_STALLED;
+		}
+		break;
+
+	case RH_GET_DESCRIPTOR | RH_CLASS:
+		{
+			__u32 temp = roothub_a(&gohci);
+
+			data_buf[0] = 9;	/* min length; */
+			data_buf[1] = 0x29;
+			data_buf[2] = temp & RH_A_NDP;
+			data_buf[3] = 0;
+			if (temp & RH_A_PSM)	/* per-port power switching? */
+				data_buf[3] |= 0x1;
+			if (temp & RH_A_NOCP)	/* no overcurrent reporting? */
+				data_buf[3] |= 0x10;
+			else if (temp & RH_A_OCPM)	/* per-port overcurrent reporting? */
+				data_buf[3] |= 0x8;
+
+			/* corresponds to data_buf[4-7] */
+			datab[1] = 0;
+			data_buf[5] = (temp & RH_A_POTPGT) >> 24;
+			temp = roothub_b(&gohci);
+			data_buf[7] = temp & RH_B_DR;
+			if (data_buf[2] < 7) {
+				data_buf[8] = 0xff;
+			} else {
+				data_buf[0] += 2;
+				data_buf[8] = (temp & RH_B_DR) >> 8;
+				data_buf[10] = data_buf[9] = 0xff;
+			}
+
+			len = min_t(unsigned int, leni,
+				    min_t(unsigned int, data_buf[0], wLength));
+			OK(len);
+		}
+
+	case RH_GET_CONFIGURATION:
+		*(__u8 *) data_buf = 0x01;
+		OK(1);
+
+	case RH_SET_CONFIGURATION:
+		WR_RH_STAT(0x10000);
+		OK(0);
+
+	default:
+		dbg("unsupported root hub command");
+		stat = USB_ST_STALLED;
+	}
+
+#ifdef	DEBUG
+	ohci_dump_roothub(&gohci, 1);
+#endif
+
+	len = min_t(int, len, leni);
+	if (data != data_buf)
+		memcpy(data, data_buf, len);
+	dev->act_len = len;
+	dev->status = stat;
+
+#ifdef DEBUG
+	if (transfer_len)
+		urb_priv.actual_length = transfer_len;
+	pkt_print(dev, pipe, buffer, transfer_len, cmd, "RET(rh)",
+		  0 /*usb_pipein(pipe) */ );
+#endif
+
+	return stat;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* common code for handling submit messages - used for all but root hub */
+/* accesses. */
+int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+		      int transfer_len, struct devrequest *setup, int interval)
+{
+	int stat = 0;
+	int maxsize = usb_maxpacket(dev, pipe);
+	int timeout;
+
+	/* device pulled? Shortcut the action. */
+	if (devgone == dev) {
+		dev->status = USB_ST_CRC_ERR;
+		return 0;
+	}
+#ifdef DEBUG
+	urb_priv.actual_length = 0;
+	pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB",
+		  usb_pipein(pipe));
+#endif
+	if (!maxsize) {
+		err("submit_common_message: pipesize for pipe %lx is zero",
+		    pipe);
+		return -1;
+	}
+
+	if (sohci_submit_job(dev, pipe, buffer, transfer_len, setup, interval) <
+	    0) {
+		err("sohci_submit_job failed");
+		return -1;
+	}
+
+	/* allow more time for a BULK device to react - some are slow */
+#define BULK_TO	 5000		/* timeout in milliseconds */
+	if (usb_pipetype(pipe) == PIPE_BULK)
+		timeout = BULK_TO;
+	else
+		timeout = 100;
+
+	/* wait for it to complete */
+	for (;;) {
+		/* check whether the controller is done */
+		stat = hc_interrupt();
+		if (stat < 0) {
+			stat = USB_ST_CRC_ERR;
+			break;
+		}
+		if (stat >= 0 && stat < 0xff) {
+			/* 0xff is returned for an SF-interrupt */
+			break;
+		}
+		if (--timeout) {
+			wait_ms(1);
+		} else {
+			err("CTL:TIMEOUT ");
+			stat = USB_ST_CRC_ERR;
+			break;
+		}
+	}
+	/* we got an Root Hub Status Change interrupt */
+	if (got_rhsc) {
+#ifdef DEBUG
+		ohci_dump_roothub(&gohci, 1);
+#endif
+		got_rhsc = 0;
+		/* abuse timeout */
+		timeout = rh_check_port_status(&gohci);
+		if (timeout >= 0) {
+#if 0				/* this does nothing useful, but leave it here in case that changes */
+			/* the called routine adds 1 to the passed value */
+			usb_hub_port_connect_change(gohci.rh.dev, timeout - 1);
+#endif
+			/*
+			 * XXX
+			 * This is potentially dangerous because it assumes
+			 * that only one device is ever plugged in!
+			 */
+			devgone = dev;
+		}
+	}
+
+	dev->status = stat;
+	dev->act_len = transfer_len;
+
+#ifdef DEBUG
+	pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)",
+		  usb_pipein(pipe));
+#endif
+
+	/* free TDs in urb_priv */
+	urb_free_priv(&urb_priv);
+	return 0;
+}
+
+/* submit routines called from usb.c */
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+		    int transfer_len)
+{
+	info("submit_bulk_msg");
+	return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0);
+}
+
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+		       int transfer_len, struct devrequest *setup)
+{
+	int maxsize = usb_maxpacket(dev, pipe);
+
+	info("submit_control_msg");
+#ifdef DEBUG
+	urb_priv.actual_length = 0;
+	pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB",
+		  usb_pipein(pipe));
+#endif
+	if (!maxsize) {
+		err("submit_control_message: pipesize for pipe %lx is zero",
+		    pipe);
+		return -1;
+	}
+	if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) {
+		gohci.rh.dev = dev;
+		/* root hub - redirect */
+		return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len,
+					  setup);
+	}
+
+	return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0);
+}
+
+int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+		   int transfer_len, int interval)
+{
+	info("submit_int_msg");
+	return -1;
+}
+
+/*-------------------------------------------------------------------------*
+ * HC functions
+ *-------------------------------------------------------------------------*/
+
+/* reset the HC and BUS */
+
+static int hc_reset(ohci_t * ohci)
+{
+	int timeout = 30;
+	int smm_timeout = 50;	/* 0,5 sec */
+
+	if (readl(&ohci->regs->control) & OHCI_CTRL_IR) {	/* SMM owns the HC */
+		writel(OHCI_OCR, &ohci->regs->cmdstatus);	/* request ownership */
+		info("USB HC TakeOver from SMM");
+		while (readl(&ohci->regs->control) & OHCI_CTRL_IR) {
+			wait_ms(10);
+			if (--smm_timeout == 0) {
+				err("USB HC TakeOver failed!");
+				return -1;
+			}
+		}
+	}
+
+	/* Disable HC interrupts */
+	writel(OHCI_INTR_MIE, &ohci->regs->intrdisable);
+
+	dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;",
+	    ohci->slot_name, readl(&ohci->regs->control));
+
+	/* Reset USB (needed by some controllers) */
+	ohci->hc_control = 0;
+	writel(ohci->hc_control, &ohci->regs->control);
+
+	/* HC Reset requires max 10 us delay */
+	writel(OHCI_HCR, &ohci->regs->cmdstatus);
+	while ((readl(&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
+		if (--timeout == 0) {
+			err("USB HC reset timed out!");
+			return -1;
+		}
+		udelay(1);
+	}
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* Start an OHCI controller, set the BUS operational
+ * enable interrupts
+ * connect the virtual root hub */
+
+static int hc_start(ohci_t * ohci)
+{
+	__u32 mask;
+	unsigned int fminterval;
+
+	ohci->disabled = 1;
+
+	/* Tell the controller where the control and bulk lists are
+	 * The lists are empty now. */
+
+	writel(0, &ohci->regs->ed_controlhead);
+	writel(0, &ohci->regs->ed_bulkhead);
+
+	writel((__u32) ohci->hcca, &ohci->regs->hcca);	/* a reset clears this */
+
+	fminterval = 0x2edf;
+	writel((fminterval * 9) / 10, &ohci->regs->periodicstart);
+	fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
+	writel(fminterval, &ohci->regs->fminterval);
+	writel(0x628, &ohci->regs->lsthresh);
+
+	/* start controller operations */
+	ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
+	ohci->disabled = 0;
+	writel(ohci->hc_control, &ohci->regs->control);
+
+	/* disable all interrupts */
+	mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD |
+		OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC |
+		OHCI_INTR_OC | OHCI_INTR_MIE);
+	writel(mask, &ohci->regs->intrdisable);
+	/* clear all interrupts */
+	mask &= ~OHCI_INTR_MIE;
+	writel(mask, &ohci->regs->intrstatus);
+	/* Choose the interrupts we care about now  - but w/o MIE */
+	mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;
+	writel(mask, &ohci->regs->intrenable);
+
+#ifdef	OHCI_USE_NPS
+	/* required for AMD-756 and some Mac platforms */
+	writel((roothub_a(ohci) | RH_A_NPS) & ~RH_A_PSM,
+	       &ohci->regs->roothub.a);
+	writel(RH_HS_LPSC, &ohci->regs->roothub.status);
+#endif				/* OHCI_USE_NPS */
+
+#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})
+	/* POTPGT delay is bits 24-31, in 2 ms units. */
+	mdelay((roothub_a(ohci) >> 23) & 0x1fe);
+
+	/* connect the virtual root hub */
+	ohci->rh.devnum = 0;
+
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* an interrupt happens */
+
+static int hc_interrupt(void)
+{
+	ohci_t *ohci = &gohci;
+	struct ohci_regs *regs = ohci->regs;
+	int ints;
+	int stat = -1;
+
+	if ((ohci->hcca->done_head != 0)
+	    && !(ohci_cpu_to_le32(ohci->hcca->done_head) & 0x01)) {
+		ints = OHCI_INTR_WDH;
+	} else {
+		ints = readl(&regs->intrstatus);
+	}
+
+	/* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */
+
+	if (ints & OHCI_INTR_RHSC) {
+		got_rhsc = 1;
+	}
+
+	if (ints & OHCI_INTR_UE) {
+		ohci->disabled++;
+		err("OHCI Unrecoverable Error, controller usb-%s disabled",
+		    ohci->slot_name);
+		/* e.g. due to PCI Master/Target Abort */
+
+#ifdef	DEBUG
+		ohci_dump(ohci, 1);
+#endif
+		/* FIXME: be optimistic, hope that bug won't repeat often. */
+		/* Make some non-interrupt context restart the controller. */
+		/* Count and limit the retries though; either hardware or */
+		/* software errors can go forever... */
+		hc_reset(ohci);
+		return -1;
+	}
+
+	if (ints & OHCI_INTR_WDH) {
+		writel(OHCI_INTR_WDH, &regs->intrdisable);
+		stat = dl_done_list(&gohci, dl_reverse_done_list(&gohci));
+		writel(OHCI_INTR_WDH, &regs->intrenable);
+	}
+
+	if (ints & OHCI_INTR_SO) {
+		dbg("USB Schedule overrun\n");
+		writel(OHCI_INTR_SO, &regs->intrenable);
+		stat = -1;
+	}
+
+	/* FIXME:  this assumes SOF (1/ms) interrupts don't get lost... */
+	if (ints & OHCI_INTR_SF) {
+		unsigned int frame = ohci_cpu_to_le16(ohci->hcca->frame_no) & 1;
+		writel(OHCI_INTR_SF, &regs->intrdisable);
+		if (ohci->ed_rm_list[frame] != NULL)
+			writel(OHCI_INTR_SF, &regs->intrenable);
+		stat = 0xff;
+	}
+
+	writel(ints, &regs->intrstatus);
+	return stat;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------*/
+
+/* De-allocate all resources.. */
+
+static void hc_release_ohci(ohci_t * ohci)
+{
+	dbg("USB HC release ohci usb-%s", ohci->slot_name);
+
+	if (!ohci->disabled)
+		hc_reset(ohci);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * low level initalisation routine, called from usb.c
+ */
+static char ohci_inited = 0;
+
+int usb_lowlevel_init(void)
+{
+
+	memset(&gohci, 0, sizeof(ohci_t));
+	memset(&urb_priv, 0, sizeof(urb_priv_t));
+
+	/* align the storage */
+	if ((__u32) & ghcca[0] & 0xff) {
+		err("HCCA not aligned!!");
+		return -1;
+	}
+	phcca = &ghcca[0];
+	info("aligned ghcca %p", phcca);
+	memset(&ohci_dev, 0, sizeof(struct ohci_device));
+	if ((__u32) & ohci_dev.ed[0] & 0x7) {
+		err("EDs not aligned!!");
+		return -1;
+	}
+	memset(gtd, 0, sizeof(td_t) * (NUM_TD + 1));
+	if ((__u32) gtd & 0x7) {
+		err("TDs not aligned!!");
+		return -1;
+	}
+	ptd = gtd;
+	gohci.hcca = phcca;
+	memset(phcca, 0, sizeof(struct ohci_hcca));
+
+	gohci.disabled = 1;
+	gohci.sleeping = 0;
+	gohci.irq = -1;
+	gohci.regs = (struct ohci_regs *)(CFG_PERIPHERAL_BASE | 0x1000);
+
+	gohci.flags = 0;
+	gohci.slot_name = "ppc440";
+
+	if (hc_reset(&gohci) < 0) {
+		hc_release_ohci(&gohci);
+		return -1;
+	}
+
+	if (hc_start(&gohci) < 0) {
+		err("can't start usb-%s", gohci.slot_name);
+		hc_release_ohci(&gohci);
+		return -1;
+	}
+#ifdef	DEBUG
+	ohci_dump(&gohci, 1);
+#endif
+	ohci_inited = 1;
+
+	/* init the device driver */
+	usb_dev_init();
+
+	return 0;
+}
+
+int usb_lowlevel_stop(void)
+{
+	/* this gets called really early - before the controller has */
+	/* even been initialized! */
+	if (!ohci_inited)
+		return 0;
+	/* TODO release any interrupts, etc. */
+	/* call hc_release_ohci() here ? */
+	hc_reset(&gohci);
+	return 0;
+}
+
+#endif				/* CONFIG_USB_OHCI */

+ 410 - 0
cpu/ppc4xx/usb_ohci.h

@@ -0,0 +1,410 @@
+/*
+ * URB OHCI HCD (Host Controller Driver) for USB.
+ *
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net>
+ *
+ * usb-ohci.h
+ */
+
+static int cc_to_error[16] = {
+
+/* mapping of the OHCI CC status to error codes */
+	/* No  Error  */ 0,
+	/* CRC Error  */ USB_ST_CRC_ERR,
+	/* Bit Stuff  */ USB_ST_BIT_ERR,
+	/* Data Togg  */ USB_ST_CRC_ERR,
+	/* Stall      */ USB_ST_STALLED,
+	/* DevNotResp */ -1,
+	/* PIDCheck   */ USB_ST_BIT_ERR,
+	/* UnExpPID   */ USB_ST_BIT_ERR,
+	/* DataOver   */ USB_ST_BUF_ERR,
+	/* DataUnder  */ USB_ST_BUF_ERR,
+	/* reservd    */ -1,
+	/* reservd    */ -1,
+	/* BufferOver */ USB_ST_BUF_ERR,
+	/* BuffUnder  */ USB_ST_BUF_ERR,
+	/* Not Access */ -1,
+	/* Not Access */ -1
+};
+
+/* ED States */
+
+#define ED_NEW		0x00
+#define ED_UNLINK	0x01
+#define ED_OPER		0x02
+#define ED_DEL		0x04
+#define ED_URB_DEL	0x08
+
+/* usb_ohci_ed */
+struct ed {
+	__u32 hwINFO;
+	__u32 hwTailP;
+	__u32 hwHeadP;
+	__u32 hwNextED;
+
+	struct ed *ed_prev;
+	__u8 int_period;
+	__u8 int_branch;
+	__u8 int_load;
+	__u8 int_interval;
+	__u8 state;
+	__u8 type;
+	__u16 last_iso;
+	struct ed *ed_rm_list;
+
+	struct usb_device *usb_dev;
+	__u32 unused[3];
+} __attribute((aligned(16)));
+typedef struct ed ed_t;
+
+/* TD info field */
+#define TD_CC	    0xf0000000
+#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f)
+#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)
+#define TD_EC	    0x0C000000
+#define TD_T	    0x03000000
+#define TD_T_DATA0  0x02000000
+#define TD_T_DATA1  0x03000000
+#define TD_T_TOGGLE 0x00000000
+#define TD_R	    0x00040000
+#define TD_DI	    0x00E00000
+#define TD_DI_SET(X) (((X) & 0x07)<< 21)
+#define TD_DP	    0x00180000
+#define TD_DP_SETUP 0x00000000
+#define TD_DP_IN    0x00100000
+#define TD_DP_OUT   0x00080000
+
+#define TD_ISO	    0x00010000
+#define TD_DEL	    0x00020000
+
+/* CC Codes */
+#define TD_CC_NOERROR	   0x00
+#define TD_CC_CRC	   0x01
+#define TD_CC_BITSTUFFING  0x02
+#define TD_CC_DATATOGGLEM  0x03
+#define TD_CC_STALL	   0x04
+#define TD_DEVNOTRESP	   0x05
+#define TD_PIDCHECKFAIL	   0x06
+#define TD_UNEXPECTEDPID   0x07
+#define TD_DATAOVERRUN	   0x08
+#define TD_DATAUNDERRUN	   0x09
+#define TD_BUFFEROVERRUN   0x0C
+#define TD_BUFFERUNDERRUN  0x0D
+#define TD_NOTACCESSED	   0x0F
+
+#define MAXPSW 1
+
+struct td {
+	__u32 hwINFO;
+	__u32 hwCBP;		/* Current Buffer Pointer */
+	__u32 hwNextTD;		/* Next TD Pointer */
+	__u32 hwBE;		/* Memory Buffer End Pointer */
+
+	__u16 hwPSW[MAXPSW];
+	__u8 unused;
+	__u8 index;
+	struct ed *ed;
+	struct td *next_dl_td;
+	struct usb_device *usb_dev;
+	int transfer_len;
+	__u32 data;
+
+	__u32 unused2[2];
+} __attribute((aligned(32)));
+typedef struct td td_t;
+
+#define OHCI_ED_SKIP	(1 << 14)
+
+/*
+ * The HCCA (Host Controller Communications Area) is a 256 byte
+ * structure defined in the OHCI spec. that the host controller is
+ * told the base address of.  It must be 256-byte aligned.
+ */
+
+#define NUM_INTS 32		/* part of the OHCI standard */
+struct ohci_hcca {
+	__u32 int_table[NUM_INTS];	/* Interrupt ED table */
+#if defined(CONFIG_MPC5200)
+	__u16 pad1;		/* set to 0 on each frame_no change */
+	__u16 frame_no;		/* current frame number */
+#else
+	__u16 frame_no;		/* current frame number */
+	__u16 pad1;		/* set to 0 on each frame_no change */
+#endif
+	__u32 done_head;	/* info returned for an interrupt */
+	u8 reserved_for_hc[116];
+} __attribute((aligned(256)));
+
+/*
+ * Maximum number of root hub ports.
+ */
+#define MAX_ROOT_PORTS	15	/* maximum OHCI root hub ports */
+
+/*
+ * This is the structure of the OHCI controller's memory mapped I/O
+ * region.  This is Memory Mapped I/O.	You must use the readl() and
+ * writel() macros defined in asm/io.h to access these!!
+ */
+struct ohci_regs {
+	/* control and status registers */
+	__u32 revision;
+	__u32 control;
+	__u32 cmdstatus;
+	__u32 intrstatus;
+	__u32 intrenable;
+	__u32 intrdisable;
+	/* memory pointers */
+	__u32 hcca;
+	__u32 ed_periodcurrent;
+	__u32 ed_controlhead;
+	__u32 ed_controlcurrent;
+	__u32 ed_bulkhead;
+	__u32 ed_bulkcurrent;
+	__u32 donehead;
+	/* frame counters */
+	__u32 fminterval;
+	__u32 fmremaining;
+	__u32 fmnumber;
+	__u32 periodicstart;
+	__u32 lsthresh;
+	/* Root hub ports */
+	struct ohci_roothub_regs {
+		__u32 a;
+		__u32 b;
+		__u32 status;
+		__u32 portstatus[MAX_ROOT_PORTS];
+	} roothub;
+} __attribute((aligned(32)));
+
+/* OHCI CONTROL AND STATUS REGISTER MASKS */
+
+/*
+ * HcControl (control) register masks
+ */
+#define OHCI_CTRL_CBSR	(3 << 0)	/* control/bulk service ratio */
+#define OHCI_CTRL_PLE	(1 << 2)	/* periodic list enable */
+#define OHCI_CTRL_IE	(1 << 3)	/* isochronous enable */
+#define OHCI_CTRL_CLE	(1 << 4)	/* control list enable */
+#define OHCI_CTRL_BLE	(1 << 5)	/* bulk list enable */
+#define OHCI_CTRL_HCFS	(3 << 6)	/* host controller functional state */
+#define OHCI_CTRL_IR	(1 << 8)	/* interrupt routing */
+#define OHCI_CTRL_RWC	(1 << 9)	/* remote wakeup connected */
+#define OHCI_CTRL_RWE	(1 << 10)	/* remote wakeup enable */
+
+/* pre-shifted values for HCFS */
+#	define OHCI_USB_RESET	(0 << 6)
+#	define OHCI_USB_RESUME	(1 << 6)
+#	define OHCI_USB_OPER	(2 << 6)
+#	define OHCI_USB_SUSPEND (3 << 6)
+
+/*
+ * HcCommandStatus (cmdstatus) register masks
+ */
+#define OHCI_HCR	(1 << 0)	/* host controller reset */
+#define OHCI_CLF	(1 << 1)	/* control list filled */
+#define OHCI_BLF	(1 << 2)	/* bulk list filled */
+#define OHCI_OCR	(1 << 3)	/* ownership change request */
+#define OHCI_SOC	(3 << 16)	/* scheduling overrun count */
+
+/*
+ * masks used with interrupt registers:
+ * HcInterruptStatus (intrstatus)
+ * HcInterruptEnable (intrenable)
+ * HcInterruptDisable (intrdisable)
+ */
+#define OHCI_INTR_SO	(1 << 0)	/* scheduling overrun */
+#define OHCI_INTR_WDH	(1 << 1)	/* writeback of done_head */
+#define OHCI_INTR_SF	(1 << 2)	/* start frame */
+#define OHCI_INTR_RD	(1 << 3)	/* resume detect */
+#define OHCI_INTR_UE	(1 << 4)	/* unrecoverable error */
+#define OHCI_INTR_FNO	(1 << 5)	/* frame number overflow */
+#define OHCI_INTR_RHSC	(1 << 6)	/* root hub status change */
+#define OHCI_INTR_OC	(1 << 30)	/* ownership change */
+#define OHCI_INTR_MIE	(1 << 31)	/* master interrupt enable */
+
+/* Virtual Root HUB */
+struct virt_root_hub {
+	int devnum;		/* Address of Root Hub endpoint */
+	void *dev;		/* was urb */
+	void *int_addr;
+	int send;
+	int interval;
+};
+
+/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */
+
+/* destination of request */
+#define RH_INTERFACE		   0x01
+#define RH_ENDPOINT		   0x02
+#define RH_OTHER		   0x03
+
+#define RH_CLASS		   0x20
+#define RH_VENDOR		   0x40
+
+/* Requests: bRequest << 8 | bmRequestType */
+#define RH_GET_STATUS		0x0080
+#define RH_CLEAR_FEATURE	0x0100
+#define RH_SET_FEATURE		0x0300
+#define RH_SET_ADDRESS		0x0500
+#define RH_GET_DESCRIPTOR	0x0680
+#define RH_SET_DESCRIPTOR	0x0700
+#define RH_GET_CONFIGURATION	0x0880
+#define RH_SET_CONFIGURATION	0x0900
+#define RH_GET_STATE		0x0280
+#define RH_GET_INTERFACE	0x0A80
+#define RH_SET_INTERFACE	0x0B00
+#define RH_SYNC_FRAME		0x0C80
+/* Our Vendor Specific Request */
+#define RH_SET_EP		0x2000
+
+/* Hub port features */
+#define RH_PORT_CONNECTION	   0x00
+#define RH_PORT_ENABLE		   0x01
+#define RH_PORT_SUSPEND		   0x02
+#define RH_PORT_OVER_CURRENT	   0x03
+#define RH_PORT_RESET		   0x04
+#define RH_PORT_POWER		   0x08
+#define RH_PORT_LOW_SPEED	   0x09
+
+#define RH_C_PORT_CONNECTION	   0x10
+#define RH_C_PORT_ENABLE	   0x11
+#define RH_C_PORT_SUSPEND	   0x12
+#define RH_C_PORT_OVER_CURRENT	   0x13
+#define RH_C_PORT_RESET		   0x14
+
+/* Hub features */
+#define RH_C_HUB_LOCAL_POWER	   0x00
+#define RH_C_HUB_OVER_CURRENT	   0x01
+
+#define RH_DEVICE_REMOTE_WAKEUP	   0x00
+#define RH_ENDPOINT_STALL	   0x01
+
+#define RH_ACK			   0x01
+#define RH_REQ_ERR		   -1
+#define RH_NACK			   0x00
+
+/* OHCI ROOT HUB REGISTER MASKS */
+
+/* roothub.portstatus [i] bits */
+#define RH_PS_CCS	     0x00000001	/* current connect status */
+#define RH_PS_PES	     0x00000002	/* port enable status */
+#define RH_PS_PSS	     0x00000004	/* port suspend status */
+#define RH_PS_POCI	     0x00000008	/* port over current indicator */
+#define RH_PS_PRS	     0x00000010	/* port reset status */
+#define RH_PS_PPS	     0x00000100	/* port power status */
+#define RH_PS_LSDA	     0x00000200	/* low speed device attached */
+#define RH_PS_CSC	     0x00010000	/* connect status change */
+#define RH_PS_PESC	     0x00020000	/* port enable status change */
+#define RH_PS_PSSC	     0x00040000	/* port suspend status change */
+#define RH_PS_OCIC	     0x00080000	/* over current indicator change */
+#define RH_PS_PRSC	     0x00100000	/* port reset status change */
+
+/* roothub.status bits */
+#define RH_HS_LPS	     0x00000001	/* local power status */
+#define RH_HS_OCI	     0x00000002	/* over current indicator */
+#define RH_HS_DRWE	     0x00008000	/* device remote wakeup enable */
+#define RH_HS_LPSC	     0x00010000	/* local power status change */
+#define RH_HS_OCIC	     0x00020000	/* over current indicator change */
+#define RH_HS_CRWE	     0x80000000	/* clear remote wakeup enable */
+
+/* roothub.b masks */
+#define RH_B_DR		0x0000ffff	/* device removable flags */
+#define RH_B_PPCM	0xffff0000	/* port power control mask */
+
+/* roothub.a masks */
+#define RH_A_NDP	(0xff << 0)	/* number of downstream ports */
+#define RH_A_PSM	(1 << 8)	/* power switching mode */
+#define RH_A_NPS	(1 << 9)	/* no power switching */
+#define RH_A_DT		(1 << 10)	/* device type (mbz) */
+#define RH_A_OCPM	(1 << 11)	/* over current protection mode */
+#define RH_A_NOCP	(1 << 12)	/* no over current protection */
+#define RH_A_POTPGT	(0xff << 24)	/* power on to power good time */
+
+/* urb */
+#define N_URB_TD 48
+typedef struct {
+	ed_t *ed;
+	__u16 length;		/* number of tds associated with this request */
+	__u16 td_cnt;		/* number of tds already serviced */
+	int state;
+	unsigned long pipe;
+	int actual_length;
+	td_t *td[N_URB_TD];	/* list pointer to all corresponding TDs associated with this request */
+} urb_priv_t;
+#define URB_DEL 1
+
+/*
+ * This is the full ohci controller description
+ *
+ * Note how the "proper" USB information is just
+ * a subset of what the full implementation needs. (Linus)
+ */
+
+typedef struct ohci {
+	struct ohci_hcca *hcca;	/* hcca */
+	/*dma_addr_t hcca_dma; */
+
+	int irq;
+	int disabled;		/* e.g. got a UE, we're hung */
+	int sleeping;
+	unsigned long flags;	/* for HC bugs */
+
+	struct ohci_regs *regs;	/* OHCI controller's memory */
+
+	ed_t *ed_rm_list[2];	/* lists of all endpoints to be removed */
+	ed_t *ed_bulktail;	/* last endpoint of bulk list */
+	ed_t *ed_controltail;	/* last endpoint of control list */
+	int intrstatus;
+	__u32 hc_control;	/* copy of the hc control reg */
+	struct usb_device *dev[32];
+	struct virt_root_hub rh;
+
+	const char *slot_name;
+} ohci_t;
+
+#define NUM_EDS 8		/* num of preallocated endpoint descriptors */
+
+struct ohci_device {
+	ed_t ed[NUM_EDS];
+	int ed_cnt;
+};
+
+/* hcd */
+/* endpoint */
+static int ep_link(ohci_t * ohci, ed_t * ed);
+static int ep_unlink(ohci_t * ohci, ed_t * ed);
+static ed_t *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe);
+
+/*-------------------------------------------------------------------------*/
+
+/* we need more TDs than EDs */
+#define NUM_TD 64
+
+/* +1 so we can align the storage */
+td_t gtd[NUM_TD + 1];
+/* pointers to aligned storage */
+td_t *ptd;
+
+/* TDs ... */
+static inline struct td *td_alloc(struct usb_device *usb_dev)
+{
+	int i;
+	struct td *td;
+
+	td = NULL;
+	for (i = 0; i < NUM_TD; i++) {
+		if (ptd[i].usb_dev == NULL) {
+			td = &ptd[i];
+			td->usb_dev = usb_dev;
+			break;
+		}
+	}
+
+	return td;
+}
+
+static inline void ed_free(struct ed *ed)
+{
+	ed->usb_dev = NULL;
+}

+ 214 - 0
cpu/ppc4xx/usbdev.c

@@ -0,0 +1,214 @@
+/*USB 1.1,2.0 device*/
+
+#include <common.h>
+#include <asm/processor.h>
+
+#ifdef CONFIG_440_EP
+
+#include <usb.h>
+#include "usbdev.h"
+#include "vecnum.h"
+
+#define USB_DT_DEVICE        0x01
+#define USB_DT_CONFIG        0x02
+#define USB_DT_STRING        0x03
+#define USB_DT_INTERFACE     0x04
+#define USB_DT_ENDPOINT      0x05
+
+unsigned char set_value = -1;
+
+void process_endpoints(unsigned short usb2d0_intrin)
+{
+	/*will hold the packet received */
+	struct usb_device_descriptor usb_device_packet;
+	struct usb_config_descriptor usb_config_packet;
+	struct usb_string_descriptor usb_string_packet;
+	struct devrequest setup_packet;
+	unsigned int *setup_packet_pt;
+	unsigned char *packet_pt;
+	int temp, temp1;
+
+	int i;
+
+	/*printf("{USB device} - endpoint 0x%X \n", usb2d0_intrin); */
+
+	/*set usb address, seems to not work unless it is done in the next
+	   interrupt, so that is why it is done this way */
+	if (set_value != -1)
+		*(unsigned char *)USB2D0_FADDR_8 = set_value;
+
+	/*endpoint 1 */
+	if (usb2d0_intrin & 0x01) {
+		setup_packet_pt = (unsigned int *)&setup_packet;
+
+		/*copy packet */
+		setup_packet_pt[0] = *(unsigned int *)USB2D0_FIFO_0;
+		setup_packet_pt[1] = *(unsigned int *)USB2D0_FIFO_0;
+		temp = *(unsigned int *)USB2D0_FIFO_0;
+		temp1 = *(unsigned int *)USB2D0_FIFO_0;
+
+		/*do some swapping */
+		setup_packet.value = swap_16(setup_packet.value);
+		setup_packet.index = swap_16(setup_packet.index);
+		setup_packet.length = swap_16(setup_packet.length);
+
+		/*clear rx packet */
+		*(unsigned short *)USB2D0_INCSR0_8 = 0x48;
+
+		/*printf("0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n", setup_packet.requesttype,
+		   setup_packet.request, setup_packet.value,
+		   setup_packet.index, setup_packet.length, temp, temp1 ); */
+
+		switch (setup_packet.request) {
+		case USB_REQ_GET_DESCRIPTOR:
+
+			switch (setup_packet.value >> 8) {
+			case USB_DT_DEVICE:
+				/*create packet */
+				usb_device_packet.bLength = 18;
+				usb_device_packet.bDescriptorType =
+				    USB_DT_DEVICE;
+#ifdef USB_2_0_DEVICE
+				usb_device_packet.bcdUSB = swap_16(0x200);
+#else
+				usb_device_packet.bcdUSB = swap_16(0x110);
+#endif
+				usb_device_packet.bDeviceClass = 0xff;
+				usb_device_packet.bDeviceSubClass = 0;
+				usb_device_packet.bDeviceProtocol = 0;
+				usb_device_packet.bMaxPacketSize0 = 32;
+				usb_device_packet.idVendor = swap_16(1);
+				usb_device_packet.idProduct = swap_16(2);
+				usb_device_packet.bcdDevice = swap_16(0x300);
+				usb_device_packet.iManufacturer = 1;
+				usb_device_packet.iProduct = 1;
+				usb_device_packet.iSerialNumber = 1;
+				usb_device_packet.bNumConfigurations = 1;
+
+				/*put packet in fifo */
+				packet_pt = (unsigned char *)&usb_device_packet;
+				break;
+
+			case USB_DT_CONFIG:
+				/*create packet */
+				usb_config_packet.bLength = 9;
+				usb_config_packet.bDescriptorType =
+				    USB_DT_CONFIG;
+				usb_config_packet.wTotalLength = swap_16(25);
+				usb_config_packet.bNumInterfaces = 1;
+				usb_config_packet.bConfigurationValue = 1;
+				usb_config_packet.iConfiguration = 0;
+				usb_config_packet.bmAttributes = 0x40;
+				usb_config_packet.MaxPower = 0;
+
+				/*put packet in fifo */
+				packet_pt = (unsigned char *)&usb_config_packet;
+				break;
+
+			case USB_DT_STRING:
+				/*create packet */
+				usb_string_packet.bLength = 2;
+				usb_string_packet.bDescriptorType =
+				    USB_DT_STRING;
+				usb_string_packet.wData[0] = 0x0094;
+
+				/*put packet in fifo */
+				packet_pt = (unsigned char *)&usb_string_packet;
+				break;
+			}
+
+			/*put packet in fifo */
+			for (i = 0; i < (setup_packet.length); i++) {
+				*(unsigned char *)USB2D0_FIFO_0 = packet_pt[i];
+			}
+
+			/*give tx command */
+			*(unsigned short *)USB2D0_INCSR0_8 = 0x0a;
+
+			break;
+
+		case USB_REQ_SET_ADDRESS:
+
+			/*copy usb address */
+			set_value = setup_packet.value;
+
+			break;
+		}
+
+	}
+}
+
+void process_other(unsigned char usb2d0_intrusb)
+{
+
+	/*check for sof */
+	if (usb2d0_intrusb & 0x08) {
+		/*printf("{USB device} - sof detected\n"); */
+	}
+
+	/*check for reset */
+	if (usb2d0_intrusb & 0x04) {
+		/*printf("{USB device} - reset detected\n"); */
+
+		/*copy usb address of zero, need to do this when usb reset */
+		set_value = 0;
+	}
+
+	if (usb2d0_intrusb & 0x02) {
+		/*printf("{USB device} - resume detected\n"); */
+	}
+
+	if (usb2d0_intrusb & 0x01) {
+		/*printf("{USB device} - suspend detected\n"); */
+	}
+}
+
+int usbInt(void)
+{
+	/*Must read these 2 registers and use values to clear interrupts.  If you
+	   do not read them then the interrupt will not be cleared.  If you do not
+	   use the variable the optimizer will not do a read. */
+	volatile unsigned short usb2d0_intrin =
+	    *(unsigned short *)USB2D0_INTRIN_16;
+	volatile unsigned char usb2d0_intrusb =
+	    *(unsigned char *)USB2D0_INTRUSB_8;
+
+	/*check if there was an endpoint interrupt */
+	if (usb2d0_intrin != 0) {
+		process_endpoints(usb2d0_intrin);
+	}
+
+	/*check for other interrupts */
+	if (usb2d0_intrusb != 0) {
+		process_other(usb2d0_intrusb);
+	}
+
+	return 0;
+}
+
+void usb_dev_init()
+{
+#ifdef USB_2_0_DEVICE
+	printf("USB 2.0 Device init\n");
+	/*select 2.0 device */
+	mtsdr(sdr_usb0, 0x0);	/* 2.0 */
+
+	/*usb dev init */
+	*(unsigned char *)USB2D0_POWER_8 = 0xa1;	/* 2.0 */
+#else
+	printf("USB 1.1 Device init\n");
+	/*select 1.1 device */
+	mtsdr(sdr_usb0, 0x2);	/* 1.1 */
+
+	/*usb dev init */
+	*(unsigned char *)USB2D0_POWER_8 = 0xc0;	/* 1.1 */
+#endif
+
+	/*enable interrupts */
+	*(unsigned char *)USB2D0_INTRUSBE_8 = 0x0f;
+
+	irq_install_handler(VECNUM_USBDEV, (interrupt_handler_t *) usbInt,
+			    NULL);
+}
+
+#endif				/*CONFIG_440_EP */

+ 31 - 0
cpu/ppc4xx/usbdev.h

@@ -0,0 +1,31 @@
+#include <config.h>
+
+/*Common Registers*/
+#define USB2D0_INTRIN_16   (CFG_USB_DEVICE | 0x100)
+#define USB2D0_POWER_8     (CFG_USB_DEVICE | 0x102)
+#define USB2D0_FADDR_8     (CFG_USB_DEVICE | 0x103)
+#define USB2D0_INTRINE_16  (CFG_USB_DEVICE | 0x104)
+#define USB2D0_INTROUT_16  (CFG_USB_DEVICE | 0x106)
+#define USB2D0_INTRUSBE_8  (CFG_USB_DEVICE | 0x108)
+#define USB2D0_INTRUSB_8   (CFG_USB_DEVICE | 0x109)
+#define USB2D0_INTROUTE_16 (CFG_USB_DEVICE | 0x10a)
+#define USB2D0_TSTMODE_8   (CFG_USB_DEVICE | 0x10c)
+#define USB2D0_INDEX_8     (CFG_USB_DEVICE | 0x10d)
+#define USB2D0_FRAME_16    (CFG_USB_DEVICE | 0x10e)
+
+/*Indexed Registers*/
+#define USB2D0_INCSR0_8    (CFG_USB_DEVICE | 0x110)
+#define USB2D0_INCSR_16    (CFG_USB_DEVICE | 0x110)
+#define USB2D0_INMAXP_16   (CFG_USB_DEVICE | 0x112)
+#define USB2D0_OUTCSR_16   (CFG_USB_DEVICE | 0x114)
+#define USB2D0_OUTMAXP_16  (CFG_USB_DEVICE | 0x116)
+#define USB2D0_OUTCOUNT0_8 (CFG_USB_DEVICE | 0x11a)
+#define USB2D0_OUTCOUNT_16 (CFG_USB_DEVICE | 0x11a)
+
+/*FIFOs*/
+#define USB2D0_FIFO_0 (CFG_USB_DEVICE | 0x120)
+#define USB2D0_FIFO_1 (CFG_USB_DEVICE | 0x124)
+#define USB2D0_FIFO_2 (CFG_USB_DEVICE | 0x128)
+#define USB2D0_FIFO_3 (CFG_USB_DEVICE | 0x12c)
+
+void usb_dev_init(void);

+ 1 - 0
cpu/ppc4xx/vecnum.h

@@ -69,6 +69,7 @@
 #define VECNUM_MS           (32 + 0 )   /* MAL SERR                     */
 #define VECNUM_TXDE         (32 + 1 )   /* MAL TXDE                     */
 #define VECNUM_RXDE         (32 + 2 )   /* MAL RXDE                     */
+#define VECNUM_USBDEV	    (32 + 23)   /* USB 1.1/USB 2.0 Device       */
 #define VECNUM_ETH0         (32 + 28)   /* Ethernet 0 interrupt status  */
 #define VECNUM_EWU0         (32 + 29)   /* Ethernet 0 wakeup            */
 

+ 1 - 1
drivers/pci_indirect.c

@@ -52,7 +52,7 @@ indirect_##rw##_config_##size(struct pci_controller *hose,               \
 	cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);       \
 	return 0;                                                        \
 }
-#elif defined(CONFIG_440_GX)
+#elif defined(CONFIG_440_GX) || defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
 #define INDIRECT_PCI_OP(rw, size, type, op, mask)			 \
 static int								 \
 indirect_##rw##_config_##size(struct pci_controller *hose, 		 \

+ 9 - 1
include/405gp_enet.h

@@ -67,7 +67,11 @@ struct arp_entry {
 
 			/*Register addresses */
 #if defined(CONFIG_440)
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+#define ZMII_BASE			(CFG_PERIPHERAL_BASE + 0x0D00)
+#else
 #define ZMII_BASE			(CFG_PERIPHERAL_BASE + 0x0780)
+#endif
 #define ZMII_FER			(ZMII_BASE)
 #define ZMII_SSR			(ZMII_BASE + 4)
 #define ZMII_SMIISR			(ZMII_BASE + 8)
@@ -77,7 +81,11 @@ struct arp_entry {
 #endif /* CONFIG_440 */
 
 #if defined(CONFIG_440)
-#define EMAC_BASE 			(CFG_PERIPHERAL_BASE + 0x0800)
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+#define EMAC_BASE			    (CFG_PERIPHERAL_BASE + 0x0E00)
+#else
+#define EMAC_BASE			    (CFG_PERIPHERAL_BASE + 0x0800)
+#endif
 #else
 #define EMAC_BASE 			0xEF600800
 #endif

+ 4 - 0
include/440_i2c.h

@@ -1,7 +1,11 @@
 #ifndef _440_i2c_h_
 #define _440_i2c_h_
 
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR) 
+#define    I2C_BASE_ADDR (CFG_PERIPHERAL_BASE + 0x00000700)
+#else
 #define    I2C_BASE_ADDR (CFG_PERIPHERAL_BASE + 0x00000400)
+#endif /*CONFIG_440_EP CONFIG_440_GR*/
 
 #define	   I2C_REGISTERS_BASE_ADDRESS I2C_BASE_ADDR
 #define    IIC_MDBUF	(I2C_REGISTERS_BASE_ADDRESS+IICMDBUF)

+ 8 - 0
include/440gx_enet.h

@@ -140,7 +140,11 @@ typedef struct emac_440gx_hw_st {
 
 
 /*ZMII Bridge Register addresses */
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+#define ZMII_BASE			(CFG_PERIPHERAL_BASE + 0x0D00)
+#else
 #define ZMII_BASE			(CFG_PERIPHERAL_BASE + 0x0780)
+#endif
 #define ZMII_FER			(ZMII_BASE)
 #define ZMII_SSR			(ZMII_BASE + 4)
 #define ZMII_SMIISR			(ZMII_BASE + 8)
@@ -272,7 +276,11 @@ typedef struct emac_440gx_hw_st {
 
 
 /* Ethernet MAC Regsiter Addresses */
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+#define EMAC_BASE			    (CFG_PERIPHERAL_BASE + 0x0E00)
+#else
 #define EMAC_BASE			    (CFG_PERIPHERAL_BASE + 0x0800)
+#endif
 
 #define EMAC_M0				    (EMAC_BASE)
 #define EMAC_M1				    (EMAC_BASE + 4)

+ 2 - 0
include/asm-ppc/processor.h

@@ -716,6 +716,8 @@
 #define PVR_405GPR_RB	0x50910951
 #define PVR_440GP_RB	0x40120440
 #define PVR_440GP_RC	0x40120481
+#define PVR_440EP_RA	0x42221850
+#define PVR_440EP_RB	0x422218D3
 #define PVR_440GX_RA	0x51B21850
 #define PVR_440GX_RB	0x51B21851
 #define PVR_440GX_RC	0x51B21892

+ 6 - 1
include/asm-ppc/u-boot.h

@@ -98,13 +98,18 @@ typedef struct bd_info {
 	unsigned char   bi_enet3addr[6];
 #endif
 
-#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || defined (CONFIG_440_GX)
+#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || defined (CONFIG_440_GX) || \
+    defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
 	unsigned int	bi_opbfreq;		/* OPB clock in Hz */
 	int		bi_iic_fast[2];		/* Use fast i2c mode */
 #endif
 #if defined(CONFIG_NX823)
 	unsigned char	bi_sernum[8];
 #endif
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+	int 		bi_phynum[2];           /* Determines phy mapping */
+	int 		bi_phymode[2];          /* Determines phy mode */
+#endif
 #if defined(CONFIG_440_GX)
 	int 		bi_phynum[4];           /* Determines phy mapping */
 	int 		bi_phymode[4];          /* Determines phy mode */

+ 298 - 0
include/configs/yellowstone.h

@@ -0,0 +1,298 @@
+/*
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/************************************************************************
+ * yellowstone.h - configuration for YELLOWSTONE board
+ ***********************************************************************/
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*-----------------------------------------------------------------------
+ * High Level Configuration Options
+ *----------------------------------------------------------------------*/
+#define CONFIG_YELLOWSTONE			1	/* Board is BAMBOO           */
+#define CONFIG_440_GR				1	/* Specific PPC440GR support */
+
+#define CONFIG_4xx					1	/* ... PPC4xx family	*/
+#define CONFIG_BOARD_EARLY_INIT_F 	1   /* Call board_early_init_f	*/
+#undef	CFG_DRAM_TEST					/* disable - takes long time! */
+#define CONFIG_SYS_CLK_FREQ	66666666    /* external freq to pll	*/
+
+/*-----------------------------------------------------------------------
+ * Base addresses -- Note these are effective addresses where the
+ * actual resources get mapped (not physical addresses)
+ *----------------------------------------------------------------------*/
+#define CFG_SDRAM_BASE	    0x00000000	    /* _must_ be 0		    */
+#define CFG_FLASH_BASE	    0xf0000000	    /* start of FLASH		*/
+#define CFG_MONITOR_BASE    TEXT_BASE	    /* start of monitor		*/
+#define CFG_PCI_MEMBASE	    0xa0000000	    /* mapped pci memory	*/
+#define CFG_PCI_MEMBASE1    CFG_PCI_MEMBASE  + 0x10000000
+#define CFG_PCI_MEMBASE2    CFG_PCI_MEMBASE1 + 0x10000000
+#define CFG_PCI_MEMBASE3    CFG_PCI_MEMBASE2 + 0x10000000
+
+
+/*Don't change either of these*/
+#define CFG_PERIPHERAL_BASE 0xef600000	    /* internal peripherals	*/
+#define CFG_PCI_BASE	    0xe0000000	    /* internal PCI regs	*/
+/*Don't change either of these*/
+
+#define CFG_USB_DEVICE 0x50000000
+#define CFG_NVRAM_BASE_ADDR 0x80000000
+#define CFG_BCSR_BASE	    (CFG_NVRAM_BASE_ADDR | 0x2000)
+
+/*-----------------------------------------------------------------------
+ * Initial RAM & stack pointer (placed in SDRAM)
+ *----------------------------------------------------------------------*/
+#define CFG_INIT_RAM_ADDR	  0xf0000000		/* DCache */
+#define CFG_INIT_RAM_END	0x2000
+#define CFG_GBL_DATA_SIZE	256		    	/* num bytes initial data	*/
+#define CFG_GBL_DATA_OFFSET	(CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET	CFG_GBL_DATA_OFFSET
+
+#define CFG_MONITOR_LEN	    (256 * 1024)    /* Reserve 256 kB for Mon	*/
+#define CFG_MALLOC_LEN	    (128 * 1024)    /* Reserve 128 kB for malloc*/
+#define CFG_KBYTES_SDRAM	( 128 * 1024)	/* 128MB                     */
+#define CFG_SDRAM_BANKS     (2)
+/*-----------------------------------------------------------------------
+ * Serial Port
+ *----------------------------------------------------------------------*/
+#undef	CONFIG_SERIAL_SOFTWARE_FIFO
+#define CFG_EXT_SERIAL_CLOCK	11059200 /* use external 11.059MHz clk	*/
+#define CONFIG_BAUDRATE			9600
+#define CONFIG_SERIAL_MULTI   1
+/*define this if you want console on UART1*/
+#undef CONFIG_UART1_CONSOLE
+
+#define CFG_BAUDRATE_TABLE  \
+    {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200}
+
+/*-----------------------------------------------------------------------
+ * NVRAM/RTC
+ *
+ * NOTE: The RTC registers are located at 0x7FFF0 - 0x7FFFF
+ * The DS1558 code assumes this condition
+ *
+ *----------------------------------------------------------------------*/
+#define CFG_NVRAM_SIZE	    (0x2000 - 0x10) /* NVRAM size(8k)- RTC regs */
+#define CONFIG_RTC_DS1556	1		         /* DS1556 RTC		*/
+
+/*-----------------------------------------------------------------------
+ * FLASH related
+ *----------------------------------------------------------------------*/
+#define CFG_MAX_FLASH_BANKS	1		    /* number of banks	    */
+#define CFG_MAX_FLASH_SECT	256		    /* sectors per device   */
+
+#undef	CFG_FLASH_CHECKSUM
+#define CFG_FLASH_ERASE_TOUT	120000	/* Timeout for Flash Erase (in ms)	*/
+#define CFG_FLASH_WRITE_TOUT	120000	    /* Timeout for Flash Write (in ms)	*/
+
+/*-----------------------------------------------------------------------
+ * DDR SDRAM
+ *----------------------------------------------------------------------*/
+#undef CONFIG_SPD_EEPROM               /* Don't use SPD EEPROM for setup    */
+
+/*-----------------------------------------------------------------------
+ * I2C
+ *----------------------------------------------------------------------*/
+#define CONFIG_HARD_I2C		1	    /* I2C with hardware support	*/
+#undef	CONFIG_SOFT_I2C			    /* I2C bit-banged		*/
+#define CFG_I2C_SPEED		400000	/* I2C speed and slave address	*/
+#define CFG_I2C_SLAVE		0x7F
+
+
+/*-----------------------------------------------------------------------
+ * Environment
+ *----------------------------------------------------------------------*/
+#undef  CFG_ENV_IS_IN_NVRAM		    /*No NVRAM on board*/
+#undef	CFG_ENV_IS_IN_FLASH		    /* ... not in flash		*/
+#define CFG_ENV_IS_IN_EEPROM 1
+
+/* Define to allow the user to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+#define CFG_I2C_MULTI_EEPROMS
+#define CFG_ENV_SIZE		0x200	    /* Size of Environment vars */
+#define CFG_ENV_OFFSET		0x0
+#define CFG_I2C_EEPROM_ADDR	(0xa8>>1)
+#define CFG_I2C_EEPROM_ADDR_LEN 1
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+#define CFG_EEPROM_PAGE_WRITE_BITS 3
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10
+
+#define CONFIG_BOOTCOMMAND	"bootm 0xfe000000"    /* autoboot command */
+#define CONFIG_BOOTDELAY	3		    /* disable autoboot */
+
+#define CONFIG_LOADS_ECHO		1	/* echo on for serial download	*/
+#define CFG_LOADS_BAUD_CHANGE	1	/* allow baudrate change	*/
+
+#define CONFIG_MII			1	/* MII PHY management		*/
+#define CONFIG_NET_MULTI    1   /* required for netconsole  */
+#define CONFIG_PHY1_ADDR    3
+#define CONFIG_HAS_ETH1		1	/* add support for "eth1addr"	*/
+#define CONFIG_PHY_ADDR		1	/* PHY address, See schematics	*/
+#define CONFIG_NETMASK		255.255.255.0
+#define CONFIG_IPADDR		10.0.4.251
+#define CONFIG_ETHADDR		00:10:EC:00:12:34
+#define CONFIG_ETH1ADDR		00:10:EC:00:12:35
+
+#define CFG_RX_ETH_BUFFER	32	  /* Number of ethernet rx buffers & descriptors */
+#define CONFIG_SERVERIP		10.0.4.115
+
+/* Partitions */
+#define CONFIG_MAC_PARTITION
+#define CONFIG_DOS_PARTITION
+#define CONFIG_ISO_PARTITION
+
+#ifdef CONFIG_440_EP
+/* USB */
+#define CONFIG_USB_OHCI
+#define CONFIG_USB_STORAGE
+
+/*Comment this out to enable USB 1.1 device*/
+#define USB_2_0_DEVICE
+#endif /*CONFIG_440_EP*/
+
+#ifdef DEBUG
+#define CONFIG_PANIC_HANG
+#else
+#define CONFIG_HW_WATCHDOG			/* watchdog */
+#endif
+
+#ifdef CONFIG_440_EP
+	/* Need to define POST */
+#define CONFIG_COMMANDS	       ((CONFIG_CMD_DFL	| \
+			CFG_CMD_DATE	|   \
+			CFG_CMD_DHCP	|   \
+			CFG_CMD_DIAG	|   \
+			CFG_CMD_ECHO	|   \
+			CFG_CMD_EEPROM	|   \
+			CFG_CMD_ELF	|   \
+    /*      CFG_CMD_EXT2    |*/ \
+	/*		CFG_CMD_FAT		|*/	\
+			CFG_CMD_I2C	|	\
+	/*		CFG_CMD_IDE		|*/	\
+			CFG_CMD_IRQ	|	\
+    /*     	CFG_CMD_KGDB	|*/	\
+            		CFG_CMD_MII     |   \
+			CFG_CMD_PCI		|	\
+			CFG_CMD_PING	| 	\
+			CFG_CMD_REGINFO | 	\
+			CFG_CMD_SDRAM	|   \
+			CFG_CMD_FLASH   |   \
+	/*		CFG_CMD_SPI		|*/	\
+			CFG_CMD_USB	|	\
+			0 ) & ~CFG_CMD_IMLS)
+#else
+#define CONFIG_COMMANDS	       ((CONFIG_CMD_DFL	| \
+			CFG_CMD_DATE	|   \
+			CFG_CMD_DHCP	|   \
+			CFG_CMD_DIAG	|   \
+			CFG_CMD_ECHO	|   \
+			CFG_CMD_EEPROM	|   \
+			CFG_CMD_ELF	|   \
+    /*      CFG_CMD_EXT2    |*/ \
+	/*		CFG_CMD_FAT		|*/	\
+			CFG_CMD_I2C	|	\
+	/*		CFG_CMD_IDE		|*/	\
+			CFG_CMD_IRQ	|	\
+    /*     	CFG_CMD_KGDB	|*/	\
+            		CFG_CMD_MII     |   \
+			CFG_CMD_PCI		|	\
+			CFG_CMD_PING	| 	\
+			CFG_CMD_REGINFO | 	\
+			CFG_CMD_SDRAM	|   \
+			CFG_CMD_FLASH   |   \
+	/*		CFG_CMD_SPI		|*/	\
+			0 ) & ~CFG_CMD_IMLS)
+#endif
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP			/* undef to save memory		*/
+#define CFG_PROMPT	"=> "		/* Monitor Command Prompt	*/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE	1024		/* Console I/O Buffer Size	*/
+#else
+#define CFG_CBSIZE	256		/* Console I/O Buffer Size	*/
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS	16		/* max number of command args	*/
+#define CFG_BARGSIZE	CFG_CBSIZE	/* Boot Argument Buffer Size	*/
+
+#define CFG_MEMTEST_START	0x0400000	/* memtest works on	*/
+#define CFG_MEMTEST_END		0x0C00000	/* 4 ... 12 MB in DRAM	*/
+
+#define CFG_LOAD_ADDR		0x100000	/* default load address */
+#define CFG_EXTBDINFO		    1	/* To use extended board_into (bd_t) */
+#define CONFIG_LYNXKDI          1   /* support kdi files */
+
+#define CFG_HZ		1000		/* decrementer freq: 1 ms ticks */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+/* General PCI */
+#define CONFIG_PCI			            /* include pci support	        */
+#undef  CONFIG_PCI_PNP			        /* do (not) pci plug-and-play         */
+#define CONFIG_PCI_SCAN_SHOW            /* show pci devices on startup  */
+#define CFG_PCI_TARGBASE    0x80000000  /* PCIaddr mapped to CFG_PCI_MEMBASE */
+
+/* Board-specific PCI */
+#define CFG_PCI_PRE_INIT                /* enable board pci_pre_init()  */
+#define CFG_PCI_TARGET_INIT
+#define CFG_PCI_MASTER_INIT
+
+#define CFG_PCI_SUBSYS_VENDORID 0x1014  /* IBM */
+#define CFG_PCI_SUBSYS_ID 0xcafe        /* Whatever */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ		(8 << 20)	/* Initial Memory map for Linux */
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE		8192	/* For IBM 405 CPUs			*/
+#define CFG_CACHELINE_SIZE	32	/* ...			*/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value	*/
+#endif
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD	0x01		/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM	0x02		/* Software reboot			*/
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE	230400	/* speed to run kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX	2	/* which serial port to use */
+#endif
+#endif	/* __CONFIG_H */

+ 312 - 0
include/configs/yosemite.h

@@ -0,0 +1,312 @@
+/*
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/************************************************************************
+ * yosemite.h - configuration for YOSEMITE board
+ ***********************************************************************/
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*-----------------------------------------------------------------------
+ * High Level Configuration Options
+ *----------------------------------------------------------------------*/
+#define CONFIG_YOSEMITE				1	/* Board is BAMBOO           */
+#define CONFIG_440_EP				1	/* Specific PPC440EP support */
+
+#define CONFIG_4xx					1	/* ... PPC4xx family	*/
+#define CONFIG_BOARD_EARLY_INIT_F 	1   /* Call board_early_init_f	*/
+#undef	CFG_DRAM_TEST					/* disable - takes long time! */
+#define CONFIG_SYS_CLK_FREQ	66666666    /* external freq to pll	*/
+
+/*-----------------------------------------------------------------------
+ * Base addresses -- Note these are effective addresses where the
+ * actual resources get mapped (not physical addresses)
+ *----------------------------------------------------------------------*/
+#define CFG_SDRAM_BASE	    0x00000000	    /* _must_ be 0		    */
+#define CFG_FLASH_BASE	    0xfe000000	    /* start of FLASH		*/
+#define CFG_MONITOR_BASE    TEXT_BASE	    /* start of monitor		*/
+#define CFG_PCI_MEMBASE	    0xa0000000	    /* mapped pci memory	*/
+#define CFG_PCI_MEMBASE1    CFG_PCI_MEMBASE  + 0x10000000
+#define CFG_PCI_MEMBASE2    CFG_PCI_MEMBASE1 + 0x10000000
+#define CFG_PCI_MEMBASE3    CFG_PCI_MEMBASE2 + 0x10000000
+
+
+/*Don't change either of these*/
+#define CFG_PERIPHERAL_BASE 0xef600000	    /* internal peripherals	*/
+#define CFG_PCI_BASE	    0xe0000000	    /* internal PCI regs	*/
+/*Don't change either of these*/
+
+#define CFG_USB_DEVICE 0x50000000
+#define CFG_NVRAM_BASE_ADDR 0x80000000
+#define CFG_BCSR_BASE	    (CFG_NVRAM_BASE_ADDR | 0x2000)
+
+/*-----------------------------------------------------------------------
+ * Initial RAM & stack pointer (placed in SDRAM)
+ *----------------------------------------------------------------------*/
+#define CFG_INIT_RAM_ADDR	  0xf0000000		/* DCache */
+#define CFG_INIT_RAM_END	0x2000
+#define CFG_GBL_DATA_SIZE	256		    	/* num bytes initial data	*/
+#define CFG_GBL_DATA_OFFSET	(CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET	CFG_GBL_DATA_OFFSET
+
+#define CFG_MONITOR_LEN	    (256 * 1024)    /* Reserve 256 kB for Mon	*/
+#define CFG_MALLOC_LEN	    (128 * 1024)    /* Reserve 128 kB for malloc*/
+#define CFG_KBYTES_SDRAM	( 128 * 1024)	/* 128MB                     */
+#define CFG_SDRAM_BANKS     (2)
+/*-----------------------------------------------------------------------
+ * Serial Port
+ *----------------------------------------------------------------------*/
+#undef	CONFIG_SERIAL_SOFTWARE_FIFO
+#define CFG_EXT_SERIAL_CLOCK	11059200 /* use external 11.059MHz clk	*/
+#define CONFIG_BAUDRATE			9600
+#define CONFIG_SERIAL_MULTI   1
+/*define this if you want console on UART1*/
+#undef CONFIG_UART1_CONSOLE
+
+#define CFG_BAUDRATE_TABLE  \
+    {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200}
+
+/*-----------------------------------------------------------------------
+ * NVRAM/RTC
+ *
+ * NOTE: The RTC registers are located at 0x7FFF0 - 0x7FFFF
+ * The DS1558 code assumes this condition
+ *
+ *----------------------------------------------------------------------*/
+#define CFG_NVRAM_SIZE	    (0x2000 - 0x10) /* NVRAM size(8k)- RTC regs */
+#define CONFIG_RTC_DS1556	1		         /* DS1556 RTC		*/
+
+/*-----------------------------------------------------------------------
+ * FLASH related
+ *----------------------------------------------------------------------*/
+#if 1 /* test-only */
+#define CFG_MAX_FLASH_BANKS	1		    /* number of banks	    */
+#define CFG_MAX_FLASH_SECT	256		    /* sectors per device   */
+
+#undef	CFG_FLASH_CHECKSUM
+#define CFG_FLASH_ERASE_TOUT	120000	/* Timeout for Flash Erase (in ms)	*/
+#define CFG_FLASH_WRITE_TOUT	120000	    /* Timeout for Flash Write (in ms)	*/
+#else
+#define CFG_FLASH_CFI				/* The flash is CFI compatible  */
+#define CFG_FLASH_CFI_DRIVER			/* Use common CFI driver        */
+#define CFG_FLASH_CFI_AMD_RESET	1		/* AMD RESET for STM 29W320DB!  */
+
+#define CFG_MAX_FLASH_BANKS	1	/* max number of memory banks		*/
+#define CFG_MAX_FLASH_SECT	512	/* max number of sectors on one chip	*/
+
+#define CFG_FLASH_ERASE_TOUT	120000	/* Timeout for Flash Erase (in ms)	*/
+#define CFG_FLASH_WRITE_TOUT	500	/* Timeout for Flash Write (in ms)	*/
+
+#define CFG_FLASH_EMPTY_INFO		/* print 'E' for empty sector on flinfo */
+#endif
+
+/*-----------------------------------------------------------------------
+ * DDR SDRAM
+ *----------------------------------------------------------------------*/
+#undef CONFIG_SPD_EEPROM               /* Don't use SPD EEPROM for setup    */
+
+/*-----------------------------------------------------------------------
+ * I2C
+ *----------------------------------------------------------------------*/
+#define CONFIG_HARD_I2C		1	    /* I2C with hardware support	*/
+#undef	CONFIG_SOFT_I2C			    /* I2C bit-banged		*/
+#define CFG_I2C_SPEED		400000	/* I2C speed and slave address	*/
+#define CFG_I2C_SLAVE		0x7F
+
+
+/*-----------------------------------------------------------------------
+ * Environment
+ *----------------------------------------------------------------------*/
+#undef  CFG_ENV_IS_IN_NVRAM		    /*No NVRAM on board*/
+#undef	CFG_ENV_IS_IN_FLASH		    /* ... not in flash		*/
+#define CFG_ENV_IS_IN_EEPROM 1
+
+/* Define to allow the user to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+#define CFG_I2C_MULTI_EEPROMS
+#define CFG_ENV_SIZE		0x200	    /* Size of Environment vars */
+#define CFG_ENV_OFFSET		0x0
+#define CFG_I2C_EEPROM_ADDR	(0xa8>>1)
+#define CFG_I2C_EEPROM_ADDR_LEN 1
+#define CFG_EEPROM_PAGE_WRITE_ENABLE
+#define CFG_EEPROM_PAGE_WRITE_BITS 3
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10
+
+#define CONFIG_BOOTCOMMAND	"bootm 0xfe000000"    /* autoboot command */
+#define CONFIG_BOOTDELAY	3		    /* disable autoboot */
+
+#define CONFIG_LOADS_ECHO		1	/* echo on for serial download	*/
+#define CFG_LOADS_BAUD_CHANGE	1	/* allow baudrate change	*/
+
+#define CONFIG_MII			1	/* MII PHY management		*/
+#define CONFIG_NET_MULTI    1   /* required for netconsole  */
+#define CONFIG_PHY1_ADDR    3
+#define CONFIG_HAS_ETH1		1	/* add support for "eth1addr"	*/
+#define CONFIG_PHY_ADDR		1	/* PHY address, See schematics	*/
+#define CONFIG_NETMASK		255.255.255.0
+#define CONFIG_IPADDR		10.0.4.251
+#define CONFIG_ETHADDR		00:10:EC:00:12:34
+#define CONFIG_ETH1ADDR		00:10:EC:00:12:35
+
+#define CFG_RX_ETH_BUFFER	32	  /* Number of ethernet rx buffers & descriptors */
+#define CONFIG_SERVERIP		10.0.4.115
+
+/* Partitions */
+#define CONFIG_MAC_PARTITION
+#define CONFIG_DOS_PARTITION
+#define CONFIG_ISO_PARTITION
+
+#ifdef CONFIG_440_EP
+/* USB */
+#define CONFIG_USB_OHCI
+#define CONFIG_USB_STORAGE
+
+/*Comment this out to enable USB 1.1 device*/
+#define USB_2_0_DEVICE
+#endif /*CONFIG_440_EP*/
+
+#ifdef DEBUG
+#define CONFIG_PANIC_HANG
+#else
+#define CONFIG_HW_WATCHDOG			/* watchdog */
+#endif
+
+#ifdef CONFIG_440_EP
+	/* Need to define POST */
+#define CONFIG_COMMANDS	       ((CONFIG_CMD_DFL	| \
+			CFG_CMD_DATE	|   \
+			CFG_CMD_DHCP	|   \
+			CFG_CMD_DIAG	|   \
+			CFG_CMD_ECHO	|   \
+			CFG_CMD_EEPROM	|   \
+			CFG_CMD_ELF	|   \
+    /*      CFG_CMD_EXT2    |*/ \
+	/*		CFG_CMD_FAT		|*/	\
+			CFG_CMD_I2C	|	\
+	/*		CFG_CMD_IDE		|*/	\
+			CFG_CMD_IRQ	|	\
+    /*     	CFG_CMD_KGDB	|*/	\
+            		CFG_CMD_MII     |   \
+			CFG_CMD_PCI		|	\
+			CFG_CMD_PING	| 	\
+			CFG_CMD_REGINFO | 	\
+			CFG_CMD_SDRAM	|   \
+			CFG_CMD_FLASH   |   \
+	/*		CFG_CMD_SPI		|*/	\
+			CFG_CMD_USB	|	\
+			0 ) & ~CFG_CMD_IMLS)
+#else
+#define CONFIG_COMMANDS	       ((CONFIG_CMD_DFL	| \
+			CFG_CMD_DATE	|   \
+			CFG_CMD_DHCP	|   \
+			CFG_CMD_DIAG	|   \
+			CFG_CMD_ECHO	|   \
+			CFG_CMD_EEPROM	|   \
+			CFG_CMD_ELF	|   \
+    /*      CFG_CMD_EXT2    |*/ \
+	/*		CFG_CMD_FAT		|*/	\
+			CFG_CMD_I2C	|	\
+	/*		CFG_CMD_IDE		|*/	\
+			CFG_CMD_IRQ	|	\
+    /*     	CFG_CMD_KGDB	|*/	\
+            		CFG_CMD_MII     |   \
+			CFG_CMD_PCI		|	\
+			CFG_CMD_PING	| 	\
+			CFG_CMD_REGINFO | 	\
+			CFG_CMD_SDRAM	|   \
+			CFG_CMD_FLASH   |   \
+	/*		CFG_CMD_SPI		|*/	\
+			0 ) & ~CFG_CMD_IMLS)
+#endif
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP			/* undef to save memory		*/
+#define CFG_PROMPT	"=> "		/* Monitor Command Prompt	*/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE	1024		/* Console I/O Buffer Size	*/
+#else
+#define CFG_CBSIZE	256		/* Console I/O Buffer Size	*/
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS	16		/* max number of command args	*/
+#define CFG_BARGSIZE	CFG_CBSIZE	/* Boot Argument Buffer Size	*/
+
+#define CFG_MEMTEST_START	0x0400000	/* memtest works on	*/
+#define CFG_MEMTEST_END		0x0C00000	/* 4 ... 12 MB in DRAM	*/
+
+#define CFG_LOAD_ADDR		0x100000	/* default load address */
+#define CFG_EXTBDINFO		    1	/* To use extended board_into (bd_t) */
+#define CONFIG_LYNXKDI          1   /* support kdi files */
+
+#define CFG_HZ		1000		/* decrementer freq: 1 ms ticks */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+/* General PCI */
+#define CONFIG_PCI			            /* include pci support	        */
+#undef  CONFIG_PCI_PNP			        /* do (not) pci plug-and-play         */
+#define CONFIG_PCI_SCAN_SHOW            /* show pci devices on startup  */
+#define CFG_PCI_TARGBASE    0x80000000  /* PCIaddr mapped to CFG_PCI_MEMBASE */
+
+/* Board-specific PCI */
+#define CFG_PCI_PRE_INIT                /* enable board pci_pre_init()  */
+#define CFG_PCI_TARGET_INIT
+#define CFG_PCI_MASTER_INIT
+
+#define CFG_PCI_SUBSYS_VENDORID 0x1014  /* IBM */
+#define CFG_PCI_SUBSYS_ID 0xcafe        /* Whatever */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ		(8 << 20)	/* Initial Memory map for Linux */
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE		8192	/* For IBM 405 CPUs			*/
+#define CFG_CACHELINE_SIZE	32	/* ...			*/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value	*/
+#endif
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD	0x01		/* Normal Power-On: Boot from FLASH	*/
+#define BOOTFLAG_WARM	0x02		/* Software reboot			*/
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE	230400	/* speed to run kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX	2	/* which serial port to use */
+#endif
+#endif	/* __CONFIG_H */

+ 15 - 0
include/pci.h

@@ -160,6 +160,21 @@
 #define  PCI_BRIDGE_CTL_BUS_RESET 0x40	/* Secondary bus reset */
 #define  PCI_BRIDGE_CTL_FAST_BACK 0x80	/* Fast Back2Back enabled on secondary interface */
 
+/* From 440ep */
+#define PCI_ERREN       0x48     /* Error Enable */
+#define PCI_ERRSTS      0x49     /* Error Status */
+#define PCI_BRDGOPT1    0x4A     /* PCI Bridge Options 1 */
+#define PCI_PLBSESR0    0x4C     /* PCI PLB Slave Error Syndrome 0 */
+#define PCI_PLBSESR1    0x50     /* PCI PLB Slave Error Syndrome 1 */
+#define PCI_PLBSEAR     0x54     /* PCI PLB Slave Error Address */
+#define PCI_CAPID       0x58     /* Capability Identifier */
+#define PCI_NEXTITEMPTR 0x59     /* Next Item Pointer */
+#define PCI_PMC         0x5A     /* Power Management Capabilities */
+#define PCI_PMCSR       0x5C     /* Power Management Control Status */
+#define PCI_PMCSRBSE    0x5E     /* PMCSR PCI to PCI Bridge Support Extensions */
+#define PCI_BRDGOPT2    0x60     /* PCI Bridge Options 2 */
+#define PCI_PMSCRR      0x64     /* Power Management State Change Request Re. */
+
 /* Header type 2 (CardBus bridges) */
 #define PCI_CB_CAPABILITY_LIST	0x14
 /* 0x15 reserved */

+ 213 - 6
include/ppc440.h

@@ -78,7 +78,7 @@
 #define	 ivor13 0x19d	/* interrupt vector offset register 13 */
 #define	 ivor14 0x19e	/* interrupt vector offset register 14 */
 #define	 ivor15 0x19f	/* interrupt vector offset register 15 */
-#if defined(CONFIG_440_GX)
+#if defined(CONFIG_440_GX) || defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
 #define	 mcsrr0 0x23a	/* machine check save/restore register 0 */
 #define	 mcsrr1 0x23b	/* mahcine check save/restore register 1 */
 #define	 mcsr	0x23c	/* machine check status register */
@@ -108,6 +108,7 @@
 #define	 icdbtrh 0x39f	/* instruction cache debug tag register high */
 #define	 mmucr	0x3b2	/* mmu control register */
 #define	 ccr0	0x3b3	/* core configuration register 0 */
+#define  ccr1  	0x378	/* core configuration for 440x5 only */
 #define	 icdbdr 0x3d3	/* instruction cache debug data register */
 #define	 dbdr	0x3f3	/* debug data register */
 
@@ -131,6 +132,7 @@
 #define clk_opbd	0x00c0
 #define clk_perd	0x00e0
 #define clk_mald	0x0100
+#define clk_spcid   	0x0120
 #define clk_icfg	0x0140
 
 /* 440gx sdr register definations */
@@ -149,19 +151,24 @@
 #define sdr_ebc		0x0100
 #define sdr_uart0	0x0120	/* UART0 Config */
 #define sdr_uart1	0x0121	/* UART1 Config */
+#define sdr_uart2	0x0122	/* UART2 Config */
+#define sdr_uart3	0x0123	/* UART3 Config */
 #define sdr_cp440	0x0180
 #define sdr_xcr		0x01c0
 #define sdr_xpllc	0x01c1
 #define sdr_xplld	0x01c2
 #define sdr_srst	0x0200
 #define sdr_slpipe	0x0220
-#define sdr_amp		0x0240
+#define sdr_amp0        0x0240  /* Override PLB4 prioritiy for up to 8 masters */
+#define sdr_amp1        0x0241  /* Override PLB3 prioritiy for up to 8 masters */
 #define sdr_mirq0	0x0260
 #define sdr_mirq1	0x0261
 #define sdr_maltbl	0x0280
 #define sdr_malrbl	0x02a0
 #define sdr_maltbs	0x02c0
 #define sdr_malrbs	0x02e0
+#define sdr_pci0        0x0300
+#define sdr_usb0        0x0320
 #define sdr_cust0	0x4000
 #define sdr_sdstp2	0x4001
 #define sdr_cust1	0x4002
@@ -234,6 +241,98 @@
 #define xbcfg		0x23	/* external bus configuration reg	*/
 #define xbcid		0x23	/* external bus core id reg		*/
 
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+
+/* PLB4 to PLB3 Bridge OUT */
+#define P4P3_DCR_BASE           0x020
+#define p4p3_esr0_read          (P4P3_DCR_BASE+0x0)
+#define p4p3_esr0_write         (P4P3_DCR_BASE+0x1)
+#define p4p3_eadr               (P4P3_DCR_BASE+0x2)
+#define p4p3_euadr              (P4P3_DCR_BASE+0x3)
+#define p4p3_esr1_read          (P4P3_DCR_BASE+0x4)
+#define p4p3_esr1_write         (P4P3_DCR_BASE+0x5)
+#define p4p3_confg              (P4P3_DCR_BASE+0x6)
+#define p4p3_pic                (P4P3_DCR_BASE+0x7)
+#define p4p3_peir               (P4P3_DCR_BASE+0x8)
+#define p4p3_rev                (P4P3_DCR_BASE+0xA)
+
+/* PLB3 to PLB4 Bridge IN */
+#define P3P4_DCR_BASE           0x030
+#define p3p4_esr0_read          (P3P4_DCR_BASE+0x0)
+#define p3p4_esr0_write         (P3P4_DCR_BASE+0x1)
+#define p3p4_eadr               (P3P4_DCR_BASE+0x2)
+#define p3p4_euadr              (P3P4_DCR_BASE+0x3)
+#define p3p4_esr1_read          (P3P4_DCR_BASE+0x4)
+#define p3p4_esr1_write         (P3P4_DCR_BASE+0x5)
+#define p3p4_confg              (P3P4_DCR_BASE+0x6)
+#define p3p4_pic                (P3P4_DCR_BASE+0x7)
+#define p3p4_peir               (P3P4_DCR_BASE+0x8)
+#define p3p4_rev                (P3P4_DCR_BASE+0xA)
+
+/* PLB3 Arbiter */
+#define PLB3_DCR_BASE           0x070
+#define plb3_revid              (PLB3_DCR_BASE+0x2)
+#define plb3_besr               (PLB3_DCR_BASE+0x3)
+#define plb3_bear               (PLB3_DCR_BASE+0x6)
+#define plb3_acr                (PLB3_DCR_BASE+0x7)
+
+/* PLB4 Arbiter - PowerPC440EP Pass1 */
+#define PLB4_DCR_BASE           0x080
+#define plb4_revid              (PLB4_DCR_BASE+0x2)
+#define plb4_acr                (PLB4_DCR_BASE+0x3)
+#define plb4_besr               (PLB4_DCR_BASE+0x4)
+#define plb4_bearl              (PLB4_DCR_BASE+0x6)
+#define plb4_bearh              (PLB4_DCR_BASE+0x7)
+
+/* Nebula PLB4 Arbiter - PowerPC440EP */
+#define PLB_ARBITER_BASE   0x80
+
+#define plb0_revid                (PLB_ARBITER_BASE+ 0x00)
+#define plb0_acr                  (PLB_ARBITER_BASE+ 0x01)
+#define   plb0_acr_ppm_mask             0xF0000000
+#define   plb0_acr_ppm_fixed            0x00000000
+#define   plb0_acr_ppm_fair             0xD0000000
+#define   plb0_acr_hbu_mask             0x08000000
+#define   plb0_acr_hbu_disabled         0x00000000
+#define   plb0_acr_hbu_enabled          0x08000000
+#define   plb0_acr_rdp_mask             0x06000000
+#define   plb0_acr_rdp_disabled         0x00000000
+#define   plb0_acr_rdp_2deep            0x02000000
+#define   plb0_acr_rdp_3deep            0x04000000
+#define   plb0_acr_rdp_4deep            0x06000000
+#define   plb0_acr_wrp_mask             0x01000000
+#define   plb0_acr_wrp_disabled         0x00000000
+#define   plb0_acr_wrp_2deep            0x01000000
+
+#define plb0_besrl                (PLB_ARBITER_BASE+ 0x02)
+#define plb0_besrh                (PLB_ARBITER_BASE+ 0x03)
+#define plb0_bearl                (PLB_ARBITER_BASE+ 0x04)
+#define plb0_bearh                (PLB_ARBITER_BASE+ 0x05)
+#define plb0_ccr                  (PLB_ARBITER_BASE+ 0x08)
+
+#define plb1_acr                  (PLB_ARBITER_BASE+ 0x09)
+#define   plb1_acr_ppm_mask             0xF0000000
+#define   plb1_acr_ppm_fixed            0x00000000
+#define   plb1_acr_ppm_fair             0xD0000000
+#define   plb1_acr_hbu_mask             0x08000000
+#define   plb1_acr_hbu_disabled         0x00000000
+#define   plb1_acr_hbu_enabled          0x08000000
+#define   plb1_acr_rdp_mask             0x06000000
+#define   plb1_acr_rdp_disabled         0x00000000
+#define   plb1_acr_rdp_2deep            0x02000000
+#define   plb1_acr_rdp_3deep            0x04000000
+#define   plb1_acr_rdp_4deep            0x06000000
+#define   plb1_acr_wrp_mask             0x01000000
+#define   plb1_acr_wrp_disabled         0x00000000
+#define   plb1_acr_wrp_2deep            0x01000000
+
+#define plb1_besrl                (PLB_ARBITER_BASE+ 0x0A)
+#define plb1_besrh                (PLB_ARBITER_BASE+ 0x0B)
+#define plb1_bearl                (PLB_ARBITER_BASE+ 0x0C)
+#define plb1_bearh                (PLB_ARBITER_BASE+ 0x0D)
+
+#else
+
 /*-----------------------------------------------------------------------------
  | Internal SRAM
  +----------------------------------------------------------------------------*/
@@ -265,6 +364,7 @@
 #define l2_cache_snp1	(L2_CACHE_BASE+0x07)	/* L2 Cache Snoop reg 1 */
 
 #endif /* CONFIG_440_GX */
+#endif /* !CONFIG_440_EP !CONFIG_440_GR*/
 
 /*-----------------------------------------------------------------------------
  | On-Chip Buses
@@ -417,10 +517,8 @@
 #define malrxbattr  (MAL_DCR_BASE+0x15) /* RX descriptor base addr reg	    */
 #define maltxctp0r  (MAL_DCR_BASE+0x20) /* TX 0 Channel table pointer reg   */
 #define maltxctp1r  (MAL_DCR_BASE+0x21) /* TX 1 Channel table pointer reg   */
-#if defined(CONFIG_440_GX)
 #define maltxctp2r  (MAL_DCR_BASE+0x22) /* TX 2 Channel table pointer reg   */
 #define maltxctp3r  (MAL_DCR_BASE+0x23) /* TX 3 Channel table pointer reg   */
-#endif /* CONFIG_440_GX */
 #define malrxctp0r  (MAL_DCR_BASE+0x40) /* RX 0 Channel table pointer reg   */
 #define malrxctp1r  (MAL_DCR_BASE+0x41) /* RX 1 Channel table pointer reg   */
 #if defined(CONFIG_440_GX)
@@ -893,6 +991,23 @@
 #define SDR0_MFR_ECS_MASK		0x10000000
 #define SDR0_MFR_ECS_INTERNAL		0x10000000
 
+#define SDR0_MFR_ETH0_CLK_SEL        0x08000000   /* Ethernet0 Clock Select */
+#define SDR0_MFR_ETH1_CLK_SEL        0x04000000   /* Ethernet1 Clock Select */
+#define SDR0_MFR_ZMII_MODE_MASK      0x03000000   /* ZMII Mode Mask   */
+#define SDR0_MFR_ZMII_MODE_MII       0x00000000     /* ZMII Mode MII  */
+#define SDR0_MFR_ZMII_MODE_SMII      0x01000000     /* ZMII Mode SMII */
+#define SDR0_MFR_ZMII_MODE_RMII_10M  0x02000000     /* ZMII Mode RMII - 10 Mbs   */
+#define SDR0_MFR_ZMII_MODE_RMII_100M 0x03000000     /* ZMII Mode RMII - 100 Mbs  */
+#define SDR0_MFR_ZMII_MODE_BIT0      0x02000000     /* ZMII Mode Bit0 */
+#define SDR0_MFR_ZMII_MODE_BIT1      0x01000000     /* ZMII Mode Bit1 */
+#define SDR0_MFR_ERRATA3_EN0         0x00800000
+#define SDR0_MFR_ERRATA3_EN1         0x00400000
+#define SDR0_MFR_PKT_REJ_MASK        0x00300000   /* Pkt Rej. Enable Mask */
+#define SDR0_MFR_PKT_REJ_EN          0x00300000   /* Pkt Rej. Enable on both EMAC3 0-1 */
+#define SDR0_MFR_PKT_REJ_EN0         0x00200000   /* Pkt Rej. Enable on EMAC3(0) */
+#define SDR0_MFR_PKT_REJ_EN1         0x00100000   /* Pkt Rej. Enable on EMAC3(1) */
+#define SDR0_MFR_PKT_REJ_POL         0x00080000   /* Packet Reject Polarity      */
+
 #define SDR0_SRST_BGO			0x80000000
 #define SDR0_SRST_PLB			0x40000000
 #define SDR0_SRST_EBC			0x20000000
@@ -927,7 +1042,7 @@
 /*-----------------------------------------------------------------------------+
 |  Clocking
 +-----------------------------------------------------------------------------*/
-#if !defined (CONFIG_440_GX)
+#if !defined (CONFIG_440_GX) && !defined(CONFIG_440_EP) && !defined(CONFIG_440_GR)
 #define PLLSYS0_TUNE_MASK	0xffc00000	/* PLL TUNE bits	    */
 #define PLLSYS0_FB_DIV_MASK	0x003c0000	/* Feedback divisor	    */
 #define PLLSYS0_FWD_DIV_A_MASK	0x00038000	/* Forward divisor A	    */
@@ -945,7 +1060,7 @@
 #define PLL_VCO_FREQ_MAX	1000		/* Max VCO freq (MHz)	    */
 #define PLL_CPU_FREQ_MAX	400		/* Max CPU freq (MHz)	    */
 #define PLL_PLB_FREQ_MAX	133		/* Max PLB freq (MHz)	    */
-#else /* !CONFIG_440_GX */
+#else /* !CONFIG_440_GX or CONFIG_440_EP or CONFIG_440_GR */
 #define PLLSYS0_ENG_MASK	0x80000000	/* 0 = SysClk, 1 = PLL VCO */
 #define PLLSYS0_SRC_MASK	0x40000000	/* 0 = PLL A, 1 = PLL B */
 #define PLLSYS0_SEL_MASK	0x38000000	/* 0 = PLL, 1 = CPU, 5 = PerClk */
@@ -956,6 +1071,19 @@
 #define PLLSYS0_PRI_DIV_B_MASK	0x0000001c	/* PLL Primary Divisor B */
 #define PLLSYS0_OPB_DIV_MASK	0x00000003	/* OPB Divisor */
 
+#define PLLC_ENG_MASK       0x20000000  /* PLL primary forward divisor source   */
+#define PLLC_SRC_MASK       0x20000000  /* PLL feedback source   */
+#define PLLD_FBDV_MASK      0x1f000000  /* PLL Feedback Divisor  */
+#define PLLD_FWDVA_MASK     0x000f0000  /* PLL Forward Divisor A */
+#define PLLD_FWDVB_MASK     0x00000700  /* PLL Forward Divisor B */
+#define PLLD_LFBDV_MASK     0x0000003f  /* PLL Local Feedback Divisor */
+
+#define OPBDDV_MASK         0x03000000  /* OPB Clock Divisor Register */
+#define PERDV_MASK          0x07000000  /* Periferal Clock Divisor */
+#define PRADV_MASK          0x07000000  /* Primary Divisor A */
+#define PRBDV_MASK          0x07000000  /* Primary Divisor B */
+#define SPCID_MASK          0x03000000  /* Sync PCI Divisor  */
+
 #define PLL_VCO_FREQ_MIN	500		/* Min VCO freq (MHz)	    */
 #define PLL_VCO_FREQ_MAX	1000		/* Max VCO freq (MHz)	    */
 #define PLL_CPU_FREQ_MAX	400		/* Max CPU freq (MHz)	    */
@@ -1023,6 +1151,34 @@
 #define PCIX0_CFGBASE		(CFG_PCI_BASE + 0x0ec80000)
 #define PCIX0_IOBASE		(CFG_PCI_BASE + 0x08000000)
 
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+
+/* PCI Local Configuration Registers
+   --------------------------------- */
+#define PCI_MMIO_LCR_BASE (CFG_PCI_BASE + 0x0f400000)    /* Real => 0x0EF400000 */
+
+/* PCI Master Local Configuration Registers */
+#define PCIX0_PMM0LA         (PCI_MMIO_LCR_BASE + 0x00) /* PMM0 Local Address */
+#define PCIX0_PMM0MA         (PCI_MMIO_LCR_BASE + 0x04) /* PMM0 Mask/Attribute */
+#define PCIX0_PMM0PCILA      (PCI_MMIO_LCR_BASE + 0x08) /* PMM0 PCI Low Address */
+#define PCIX0_PMM0PCIHA      (PCI_MMIO_LCR_BASE + 0x0C) /* PMM0 PCI High Address */
+#define PCIX0_PMM1LA         (PCI_MMIO_LCR_BASE + 0x10) /* PMM1 Local Address */
+#define PCIX0_PMM1MA         (PCI_MMIO_LCR_BASE + 0x14) /* PMM1 Mask/Attribute */
+#define PCIX0_PMM1PCILA      (PCI_MMIO_LCR_BASE + 0x18) /* PMM1 PCI Low Address */
+#define PCIX0_PMM1PCIHA      (PCI_MMIO_LCR_BASE + 0x1C) /* PMM1 PCI High Address */
+#define PCIX0_PMM2LA         (PCI_MMIO_LCR_BASE + 0x20) /* PMM2 Local Address */
+#define PCIX0_PMM2MA         (PCI_MMIO_LCR_BASE + 0x24) /* PMM2 Mask/Attribute */
+#define PCIX0_PMM2PCILA      (PCI_MMIO_LCR_BASE + 0x28) /* PMM2 PCI Low Address */
+#define PCIX0_PMM2PCIHA      (PCI_MMIO_LCR_BASE + 0x2C) /* PMM2 PCI High Address */
+
+/* PCI Target Local Configuration Registers */
+#define PCIX0_PTM1MS         (PCI_MMIO_LCR_BASE + 0x30) /* PTM1 Memory Size/Attribute */
+#define PCIX0_PTM1LA         (PCI_MMIO_LCR_BASE + 0x34) /* PTM1 Local Addr. Reg */
+#define PCIX0_PTM2MS         (PCI_MMIO_LCR_BASE + 0x38) /* PTM2 Memory Size/Attribute */
+#define PCIX0_PTM2LA         (PCI_MMIO_LCR_BASE + 0x3C) /* PTM2 Local Addr. Reg */
+
+#else
+
 #define PCIX0_VENDID		(PCIX0_CFGBASE + PCI_VENDOR_ID )
 #define PCIX0_DEVID		(PCIX0_CFGBASE + PCI_DEVICE_ID )
 #define PCIX0_CMD		(PCIX0_CFGBASE + PCI_COMMAND )
@@ -1079,6 +1235,52 @@
 
 #define PCIX0_STS		(PCIX0_CFGBASE + 0x00e0)
 
+#endif /* !defined(CONFIG_440_EP) !defined(CONFIG_440_GR) */
+
+/******************************************************************************
+ * GPIO macro register defines
+ ******************************************************************************/
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+#define GPIO_BASE0             (CFG_PERIPHERAL_BASE+0x00000B00)
+#define GPIO_BASE1             (CFG_PERIPHERAL_BASE+0x00000C00)
+
+#define GPIO0_OR               (GPIO_BASE0+0x0)
+#define GPIO0_TCR              (GPIO_BASE0+0x4)
+#define GPIO0_OSRL             (GPIO_BASE0+0x8)
+#define GPIO0_OSRH             (GPIO_BASE0+0xC)
+#define GPIO0_TSRL             (GPIO_BASE0+0x10)
+#define GPIO0_TSRH             (GPIO_BASE0+0x14)
+#define GPIO0_ODR              (GPIO_BASE0+0x18)
+#define GPIO0_IR               (GPIO_BASE0+0x1C)
+#define GPIO0_RR1              (GPIO_BASE0+0x20)
+#define GPIO0_RR2              (GPIO_BASE0+0x24)
+#define GPIO0_RR3	       (GPIO_BASE0+0x28)
+#define GPIO0_ISR1L            (GPIO_BASE0+0x30)
+#define GPIO0_ISR1H            (GPIO_BASE0+0x34)
+#define GPIO0_ISR2L            (GPIO_BASE0+0x38)
+#define GPIO0_ISR2H            (GPIO_BASE0+0x3C)
+#define GPIO0_ISR3L            (GPIO_BASE0+0x40)
+#define GPIO0_ISR3H            (GPIO_BASE0+0x44)
+
+#define GPIO1_OR               (GPIO_BASE1+0x0)
+#define GPIO1_TCR              (GPIO_BASE1+0x4)
+#define GPIO1_OSRL             (GPIO_BASE1+0x8)
+#define GPIO1_OSRH             (GPIO_BASE1+0xC)
+#define GPIO1_TSRL             (GPIO_BASE1+0x10)
+#define GPIO1_TSRH             (GPIO_BASE1+0x14)
+#define GPIO1_ODR              (GPIO_BASE1+0x18)
+#define GPIO1_IR               (GPIO_BASE1+0x1C)
+#define GPIO1_RR1              (GPIO_BASE1+0x20)
+#define GPIO1_RR2              (GPIO_BASE1+0x24)
+#define GPIO1_RR3              (GPIO_BASE1+0x28)
+#define GPIO1_ISR1L            (GPIO_BASE1+0x30)
+#define GPIO1_ISR1H            (GPIO_BASE1+0x34)
+#define GPIO1_ISR2L            (GPIO_BASE1+0x38)
+#define GPIO1_ISR2H            (GPIO_BASE1+0x3C)
+#define GPIO1_ISR3L            (GPIO_BASE1+0x40)
+#define GPIO1_ISR3H            (GPIO_BASE1+0x44)
+#endif
+
 /*
  * Macros for accessing the indirect EBC registers
  */
@@ -1111,12 +1313,17 @@ typedef struct {
 	unsigned long pllFwdDivB;
 	unsigned long pllFbkDiv;
 	unsigned long pllOpbDiv;
+	unsigned long pllPciDiv;
 	unsigned long pllExtBusDiv;
 	unsigned long freqVCOMhz;	/* in MHz			   */
 	unsigned long freqProcessor;
+	unsigned long freqTmrClk;
 	unsigned long freqPLB;
 	unsigned long freqOPB;
 	unsigned long freqEPB;
+	unsigned long freqPCI;
+	unsigned long pciIntArbEn;            /* Internal PCI arbiter is enabled */
+	unsigned long pciClkSync;             /* PCI clock is synchronous        */
 } PPC440_SYS_INFO;
 
 #endif	/* _ASMLANGUAGE */

+ 14 - 0
include/usb_defs.h

@@ -26,6 +26,20 @@
 #ifndef _USB_DEFS_H_
 #define _USB_DEFS_H_
 
+
+/* Everything is aribtrary */
+#define USB_ALTSETTINGALLOC          4
+#define USB_MAXALTSETTING	           128  /* Hard limit */
+
+#define USB_MAX_DEVICE              32
+#define USB_MAXCONFIG		            8
+#define USB_MAXINTERFACES	          8
+#define USB_MAXENDPOINTS	          16
+#define USB_MAXCHILDREN  						8 	/* This is arbitrary */
+#define USB_MAX_HUB									16
+
+#define USB_CNTL_TIMEOUT 100 /* 100ms timeout */
+
 /* USB constants */
 
 /* Device and/or Interface Class codes */

+ 1 - 1
lib_ppc/board.c

@@ -539,7 +539,7 @@ void board_init_f (ulong bootflag)
 
 	bd->bi_procfreq = gd->cpu_clk;	/* Processor Speed, In Hz */
 	bd->bi_plb_busfreq = gd->bus_clk;
-#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
+#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
 	bd->bi_pci_busfreq = get_PCI_freq ();
 	bd->bi_opbfreq = get_OPB_freq ();
 #elif defined(CONFIG_XILINX_ML300)

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů