diff options
| author | Stefan Roese <sr@denx.de> | 2005-08-01 16:41:48 +0200 | 
|---|---|---|
| committer | Stefan Roese <stefan@debian.(none)> | 2005-08-01 16:41:48 +0200 | 
| commit | c157d8e219694f5c3dea1ed3826668bdc67ca093 (patch) | |
| tree | 0db7954a0b50e4b5f2a5da2e007ea82a965c6663 | |
| parent | 15f36a5efd31fe608b43dc197ebbd80d3cecbe44 (diff) | |
| download | olio-uboot-2014.01-c157d8e219694f5c3dea1ed3826668bdc67ca093.tar.xz olio-uboot-2014.01-c157d8e219694f5c3dea1ed3826668bdc67ca093.zip | |
Add support for AMCC PPC440EP/GR eval boards Yosemite and Yellowstone.
Patch by Steven Blakeslee, 27 Jul 2005
43 files changed, 7208 insertions, 1189 deletions
| diff --git a/board/amcc/yellowstone/Makefile b/board/amcc/yellowstone/Makefile new file mode 100644 index 000000000..5654f91a8 --- /dev/null +++ b/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 + +######################################################################### diff --git a/board/amcc/yellowstone/config.mk b/board/amcc/yellowstone/config.mk new file mode 100644 index 000000000..4ab0ea008 --- /dev/null +++ b/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 diff --git a/board/amcc/yellowstone/flash.c b/board/amcc/yellowstone/flash.c new file mode 100644 index 000000000..99fcfb5c7 --- /dev/null +++ b/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); +} + +/*----------------------------------------------------------------------- + */ diff --git a/board/amcc/yellowstone/init.S b/board/amcc/yellowstone/init.S new file mode 100644 index 000000000..7ba43c7b0 --- /dev/null +++ b/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 diff --git a/board/amcc/yellowstone/u-boot.lds b/board/amcc/yellowstone/u-boot.lds new file mode 100644 index 000000000..769eed3ef --- /dev/null +++ b/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 = .); +} diff --git a/board/amcc/yellowstone/yellowstone.c b/board/amcc/yellowstone/yellowstone.c new file mode 100644 index 000000000..840a46c86 --- /dev/null +++ b/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 diff --git a/board/amcc/yosemite/Makefile b/board/amcc/yosemite/Makefile new file mode 100644 index 000000000..5654f91a8 --- /dev/null +++ b/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 + +######################################################################### diff --git a/board/amcc/yosemite/config.mk b/board/amcc/yosemite/config.mk new file mode 100644 index 000000000..4ab0ea008 --- /dev/null +++ b/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 diff --git a/board/amcc/yosemite/flash.c b/board/amcc/yosemite/flash.c new file mode 100644 index 000000000..cd6a2e61e --- /dev/null +++ b/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); +} + +/*----------------------------------------------------------------------- + */ diff --git a/board/amcc/yosemite/init.S b/board/amcc/yosemite/init.S new file mode 100644 index 000000000..7ba43c7b0 --- /dev/null +++ b/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 diff --git a/board/amcc/yosemite/u-boot.lds b/board/amcc/yosemite/u-boot.lds new file mode 100644 index 000000000..62dc988d9 --- /dev/null +++ b/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 = .); +} diff --git a/board/amcc/yosemite/yosemite.c b/board/amcc/yosemite/yosemite.c new file mode 100644 index 000000000..6c8a883e1 --- /dev/null +++ b/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 diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index ca834732b..6f29e2f58 100644 --- a/common/cmd_bdinfo.c +++ b/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)); diff --git a/common/cmd_elf.c b/common/cmd_elf.c index 37286e86a..eccf2e9e7 100644 --- a/common/cmd_elf.c +++ b/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) diff --git a/common/lynxkdi.c b/common/lynxkdi.c index 14aa175b1..19f0620c9 100644 --- a/common/lynxkdi.c +++ b/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; diff --git a/cpu/ppc4xx/405gp_enet.c b/cpu/ppc4xx/405gp_enet.c index 9d8e2b6de..9c17e31bd 100644 --- a/cpu/ppc4xx/405gp_enet.c +++ b/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, diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c index 4f1754ade..ebbcfd573 100644 --- a/cpu/ppc4xx/405gp_pci.c +++ b/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);      }  } diff --git a/cpu/ppc4xx/440gx_enet.c b/cpu/ppc4xx/440gx_enet.c index 871f83b96..24e6ef357 100644 --- a/cpu/ppc4xx/440gx_enet.c +++ b/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; @@ -1171,6 +1203,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; diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile index a841109e8..5b16754c5 100644 --- a/cpu/ppc4xx/Makefile +++ b/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) diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c index 06acb8162..ae45a23d0 100644 --- a/cpu/ppc4xx/cpu.c +++ b/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;  } diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c index 25508e750..74f013520 100644 --- a/cpu/ppc4xx/cpu_init.c +++ b/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); diff --git a/cpu/ppc4xx/interrupts.c b/cpu/ppc4xx/interrupts.c index 90899dd1e..c0e51f929 100644 --- a/cpu/ppc4xx/interrupts.c +++ b/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);  	} diff --git a/cpu/ppc4xx/serial.c b/cpu/ppc4xx/serial.c index 4abd3fc49..92f8ddb2e 100644 --- a/cpu/ppc4xx/serial.c +++ b/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) { diff --git a/cpu/ppc4xx/spd_sdram.c b/cpu/ppc4xx/spd_sdram.c index 794a72c8b..520107a8f 100644 --- a/cpu/ppc4xx/spd_sdram.c +++ b/cpu/ppc4xx/spd_sdram.c @@ -16,6 +16,9 @@   * Jun Gu, Artesyn Technology, jung@artesyncp.com   * Support for IBM 440 based on OpenBIOS draminit.c from IBM.   * + * (C) Copyright 2005 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + *   * See file CREDITS for list of people who contributed to this   * project.   * @@ -53,7 +56,9 @@  #define	CFG_I2C_SLAVE	0xFE  #endif -#ifndef  CONFIG_440              /* for 405 WALNUT board */ +#define ONE_BILLION         1000000000 + +#ifndef  CONFIG_440              /* for 405 WALNUT/SYCAMORE/BUBINGA boards */  #define  SDRAM0_CFG_DCE          0x80000000  #define  SDRAM0_CFG_SRE          0x40000000 @@ -111,7 +116,7 @@ int spd_read(uint addr);  long int spd_sdram(int(read_spd)(uint addr))  { -	int bus_period,tmp,row,col; +	int tmp,row,col;  	int total_size,bank_size,bank_code;  	int ecc_on;  	int mode; @@ -141,226 +146,189 @@ long int spd_sdram(int(read_spd)(uint addr))  	int t_rc;  	int min_cas; -	if(read_spd == 0){ -		read_spd=spd_read; -	/* -	 * Make sure I2C controller is initialized -	 * before continuing. -	 */ -		i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); -	} - +	PPC405_SYS_INFO sys_info; +	unsigned long bus_period_x_10;  	/* -	 * Calculate the bus period, we do it this -	 * way to minimize stack utilization. +	 * get the board info  	 */ -#ifndef CONFIG_405EP -	tmp = (mfdcr(pllmd) >> (31-6)) & 0xf;	/* get FBDV bits */ -	tmp = CONFIG_SYS_CLK_FREQ * tmp;	/* get plb freq */ -#else -	{ -		unsigned long freqCPU; -		unsigned long pllmr0; -		unsigned long pllmr1; -		unsigned long pllFbkDiv; -		unsigned long pllPlbDiv; -		unsigned long pllmr0_ccdv; - -		/* -		 * Read PLL Mode registers -		 */ -		pllmr0 = mfdcr (cpc0_pllmr0); -		pllmr1 = mfdcr (cpc0_pllmr1); - -		pllFbkDiv = ((pllmr1 & PLLMR1_FBMUL_MASK) >> 20); -		if (pllFbkDiv == 0) { -			pllFbkDiv = 16; -		} -		pllPlbDiv = ((pllmr0 & PLLMR0_CPU_TO_PLB_MASK) >> 16) + 1; - -		/* -		 * Determine CPU clock frequency -		 */ -		pllmr0_ccdv = ((pllmr0 & PLLMR0_CPU_DIV_MASK) >> 20) + 1; -		if (pllmr1 & PLLMR1_SSCS_MASK) { -			freqCPU = (CONFIG_SYS_CLK_FREQ * pllFbkDiv) / pllmr0_ccdv; -		} else { -			freqCPU = CONFIG_SYS_CLK_FREQ / pllmr0_ccdv; -		} +	get_sys_info(&sys_info); +	bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10); +	if (read_spd == 0){ +		read_spd=spd_read;  		/* -		 * Determine PLB clock frequency +		 * Make sure I2C controller is initialized +		 * before continuing.  		 */ -		tmp = freqCPU / pllPlbDiv; +		i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);  	} -#endif -	bus_period = sdram_HZ_to_ns(tmp);	/* get sdram speed */  	/* Make shure we are using SDRAM */ -	if (read_spd(2) != 0x04){ -	  SPD_ERR("SDRAM - non SDRAM memory module found\n"); -	  } - -/*------------------------------------------------------------------ -  configure memory timing register +	if (read_spd(2) != 0x04) { +		SPD_ERR("SDRAM - non SDRAM memory module found\n"); +	} -  data from DIMM: -  27	IN Row Precharge Time ( t RP) -  29	MIN RAS to CAS Delay ( t RCD) -  127   Component and Clock Detail ,clk0-clk3, junction temp, CAS -  -------------------------------------------------------------------*/ +	/* ------------------------------------------------------------------ +	 * configure memory timing register +	 * +	 * data from DIMM: +	 * 27	IN Row Precharge Time ( t RP) +	 * 29	MIN RAS to CAS Delay ( t RCD) +	 * 127   Component and Clock Detail ,clk0-clk3, junction temp, CAS +	 * -------------------------------------------------------------------*/ -     /* -      * first figure out which cas latency mode to use -      * use the min supported mode -      */ +	/* +	 * first figure out which cas latency mode to use +	 * use the min supported mode +	 */  	tmp = read_spd(127) & 0x6; -     if(tmp == 0x02){      	   /* only cas = 2 supported */ -	  min_cas = 2; +	if (tmp == 0x02){      	   /* only cas = 2 supported */ +		min_cas = 2;  /*     	  t_ck = read_spd(9); */  /*     	  t_ac = read_spd(10); */ -	  } -     else if (tmp == 0x04){         /* only cas = 3 supported */ -	  min_cas = 3; +	} else if (tmp == 0x04) {         /* only cas = 3 supported */ +		min_cas = 3;  /*     	  t_ck = read_spd(9); */  /*     	  t_ac = read_spd(10); */ -	  } -     else if (tmp == 0x06){         /* 2,3 supported, so use 2 */ -	  min_cas = 2; +	} else if (tmp == 0x06) {         /* 2,3 supported, so use 2 */ +		min_cas = 2;  /*     	  t_ck = read_spd(23); */  /*     	  t_ac = read_spd(24); */ -	  } -     else { -	     SPD_ERR("SDRAM - unsupported CAS latency \n"); +	} else { +		SPD_ERR("SDRAM - unsupported CAS latency \n");  	} -     /* get some timing values, t_rp,t_rcd,t_ras,t_rc -     */ -     t_rp = read_spd(27); -     t_rcd = read_spd(29); -     t_ras = read_spd(30); -     t_rc = t_ras + t_rp; +	/* get some timing values, t_rp,t_rcd,t_ras,t_rc +	 */ +	t_rp = read_spd(27); +	t_rcd = read_spd(29); +	t_ras = read_spd(30); +	t_rc = t_ras + t_rp; -     /* The following timing calcs subtract 1 before deviding. -      * this has effect of using ceiling instead of floor rounding, -      * and also subtracting 1 to convert number to reg value -      */ -     /* set up CASL */ -     sdram0_tr = (min_cas - 1) << SDRAM0_TR_CASL_SHIFT; -     /* set up PTA */ -     sdram0_tr |= (((t_rp - 1)/bus_period) & 0x3) << SDRAM0_TR_PTA_SHIFT; -     /* set up CTP */ -     tmp = ((t_rc - t_rcd - t_rp -1) / bus_period) & 0x3; -     if(tmp<1) tmp=1; -     sdram0_tr |= tmp << SDRAM0_TR_CTP_SHIFT; -     /* set LDF	= 2 cycles, reg value = 1 */ -     sdram0_tr |= 1 << SDRAM0_TR_LDF_SHIFT; -     /* set RFTA = t_rfc/bus_period, use t_rfc = t_rc */ -	tmp = ( (t_rc - 1) / bus_period)-3; -	if(tmp<0)tmp=0; -	if(tmp>6)tmp=6; +	/* The following timing calcs subtract 1 before deviding. +	 * this has effect of using ceiling instead of floor rounding, +	 * and also subtracting 1 to convert number to reg value +	 */ +	/* set up CASL */ +	sdram0_tr = (min_cas - 1) << SDRAM0_TR_CASL_SHIFT; +	/* set up PTA */ +	sdram0_tr |= ((((t_rp - 1) * 10)/bus_period_x_10) & 0x3) << SDRAM0_TR_PTA_SHIFT; +	/* set up CTP */ +	tmp = (((t_rc - t_rcd - t_rp -1) * 10) / bus_period_x_10) & 0x3; +	if (tmp < 1) +		tmp = 1; +	sdram0_tr |= tmp << SDRAM0_TR_CTP_SHIFT; +	/* set LDF	= 2 cycles, reg value = 1 */ +	sdram0_tr |= 1 << SDRAM0_TR_LDF_SHIFT; +	/* set RFTA = t_rfc/bus_period, use t_rfc = t_rc */ +	tmp = (((t_rc - 1) * 10) / bus_period_x_10) - 3; +	if (tmp < 0) +		tmp = 0; +	if (tmp > 6) +		tmp = 6;  	sdram0_tr |= tmp << SDRAM0_TR_RFTA_SHIFT; -     /* set RCD = t_rcd/bus_period*/ -     sdram0_tr |= (((t_rcd - 1) / bus_period) &0x3) << SDRAM0_TR_RCD_SHIFT ; +	/* set RCD = t_rcd/bus_period*/ +	sdram0_tr |= ((((t_rcd - 1) * 10) / bus_period_x_10) &0x3) << SDRAM0_TR_RCD_SHIFT ; -/*------------------------------------------------------------------ -  configure RTR register -  -------------------------------------------------------------------*/ -     row = read_spd(3); -     col = read_spd(4); -     tmp = read_spd(12) & 0x7f ; /* refresh type less self refresh bit */ -     switch(tmp){ +	/*------------------------------------------------------------------ +	 * configure RTR register +	 * -------------------------------------------------------------------*/ +	row = read_spd(3); +	col = read_spd(4); +	tmp = read_spd(12) & 0x7f ; /* refresh type less self refresh bit */ +	switch (tmp) {  	case 0x00: -	  tmp=15625; -	  break; +		tmp = 15625; +		break;  	case 0x01: -	  tmp=15625/4; -	  break; +		tmp = 15625 / 4; +		break;  	case 0x02: -	  tmp=15625/2; -	  break; +		tmp = 15625 / 2; +		break;  	case 0x03: -	  tmp=15625*2; -	  break; +		tmp = 15625 * 2; +		break;  	case 0x04: -	  tmp=15625*4; -	  break; +		tmp = 15625 * 4; +		break;  	case 0x05: -	  tmp=15625*8; -	  break; +		tmp = 15625 * 8; +		break;  	default: -	  SPD_ERR("SDRAM - Bad refresh period \n"); +		SPD_ERR("SDRAM - Bad refresh period \n");  	}  	/* convert from nsec to bus cycles */ -	tmp = tmp/bus_period; -	sdram0_rtr = (tmp & 0x3ff8)<<  SDRAM0_RTR_SHIFT; +	tmp = (tmp * 10) / bus_period_x_10; +	sdram0_rtr = (tmp & 0x3ff8) <<  SDRAM0_RTR_SHIFT; -/*------------------------------------------------------------------ -  determine the number of banks used -  -------------------------------------------------------------------*/ +	/*------------------------------------------------------------------ +	 * determine the number of banks used +	 * -------------------------------------------------------------------*/  	/* byte 7:6 is module data width */ -	if(read_spd(7) != 0) -	    SPD_ERR("SDRAM - unsupported module width\n"); +	if (read_spd(7) != 0) +		SPD_ERR("SDRAM - unsupported module width\n");  	tmp = read_spd(6);  	if (tmp < 32) -	    SPD_ERR("SDRAM - unsupported module width\n"); +		SPD_ERR("SDRAM - unsupported module width\n");  	else if (tmp < 64) -	    bank_cnt=1;		/* one bank per sdram side */ +		bank_cnt = 1;		/* one bank per sdram side */  	else if (tmp < 73) -	    bank_cnt=2;	/* need two banks per side */ +		bank_cnt = 2;	/* need two banks per side */  	else if (tmp < 161) -	    bank_cnt=4;	/* need four banks per side */ +		bank_cnt = 4;	/* need four banks per side */  	else -	    SPD_ERR("SDRAM - unsupported module width\n"); +		SPD_ERR("SDRAM - unsupported module width\n");  	/* byte 5 is the module row count (refered to as dimm "sides") */  	tmp = read_spd(5); -	if(tmp==1); -	else if(tmp==2) bank_cnt *=2; -	else if(tmp==4) bank_cnt *=4; -	else bank_cnt = 8; 		/* 8 is an error code */ +	if (tmp == 1) +		; +	else if (tmp==2) +		bank_cnt *= 2; +	else if (tmp==4) +		bank_cnt *= 4; +	else +		bank_cnt = 8; 		/* 8 is an error code */ -	if(bank_cnt > 4)	/* we only have 4 banks to work with */ -	    SPD_ERR("SDRAM - unsupported module rows for this width\n"); +	if (bank_cnt > 4)	/* we only have 4 banks to work with */ +		SPD_ERR("SDRAM - unsupported module rows for this width\n");  	/* now check for ECC ability of module. We only support ECC  	 *   on 32 bit wide devices with 8 bit ECC.  	 */ -	if ( (read_spd(11)==2) && (read_spd(6)==40) && (read_spd(14)==8) ){ -	   sdram0_ecccfg=0xf<<SDRAM0_ECCCFG_SHIFT; -	   ecc_on = 1; -	} -	else{ -	   sdram0_ecccfg=0; -	   ecc_on = 0; +	if ((read_spd(11)==2) && (read_spd(6)==40) && (read_spd(14)==8)) { +		sdram0_ecccfg = 0xf << SDRAM0_ECCCFG_SHIFT; +		ecc_on = 1; +	} else { +		sdram0_ecccfg = 0; +		ecc_on = 0;  	} -/*------------------------------------------------------------------ -	calculate total size -  -------------------------------------------------------------------*/ +	/*------------------------------------------------------------------ +	 * calculate total size +	 * -------------------------------------------------------------------*/  	/* calculate total size and do sanity check */  	tmp = read_spd(31); -	total_size=1<<22;	/* total_size = 4MB */ +	total_size = 1 << 22;	/* total_size = 4MB */  	/* now multiply 4M by the smallest device row density */  	/* note that we don't support asymetric rows */ -	while (((tmp & 0x0001) == 0) && (tmp != 0)){ -	    total_size= total_size<<1; -	    tmp = tmp>>1; -	    } +	while (((tmp & 0x0001) == 0) && (tmp != 0)) { +		total_size = total_size << 1; +		tmp = tmp >> 1; +	}  	total_size *= read_spd(5);	/* mult by module rows (dimm sides) */ -/*------------------------------------------------------------------ -	map  rows * cols * banks to a mode - -------------------------------------------------------------------*/ +	/*------------------------------------------------------------------ +	 * map  rows * cols * banks to a mode +	 * -------------------------------------------------------------------*/ -	switch( row ) -	{ +	switch (row) {  	case 11: -		switch ( col ) -		{ +		switch (col) {  		case 8:  			mode=4; /* mode 5 */  			break; @@ -369,12 +337,11 @@ long int spd_sdram(int(read_spd)(uint addr))  			mode=0; /* mode 1 */  			break;  		default: -		SPD_ERR("SDRAM - unsupported mode\n"); +			SPD_ERR("SDRAM - unsupported mode\n");  		}  		break;  	case 12: -		switch ( col ) -		{ +		switch (col) {  		case 8:  			mode=3; /* mode 4 */  			break; @@ -383,37 +350,36 @@ long int spd_sdram(int(read_spd)(uint addr))  			mode=1; /* mode 2 */  			break;  		default: -		SPD_ERR("SDRAM - unsupported mode\n"); +			SPD_ERR("SDRAM - unsupported mode\n");  		}  		break;  	case 13: -		switch ( col ) -		{ +		switch (col) {  		case 8:  			mode=5; /* mode 6 */  			break;  		case 9:  		case 10: -			if (read_spd(17) ==2 ) -				mode=6; /* mode 7 */ +			if (read_spd(17) == 2) +				mode = 6; /* mode 7 */  			else -				mode=2; /* mode 3 */ +				mode = 2; /* mode 3 */  			break;  		case 11: -			mode=2; /* mode 3 */ +			mode = 2; /* mode 3 */  			break;  		default: -		SPD_ERR("SDRAM - unsupported mode\n"); +			SPD_ERR("SDRAM - unsupported mode\n");  		}  		break;  	default: -	     SPD_ERR("SDRAM - unsupported mode\n"); +		SPD_ERR("SDRAM - unsupported mode\n");  	} -/*------------------------------------------------------------------ -	using the calculated values, compute the bank -	config register values. - -------------------------------------------------------------------*/ +	/*------------------------------------------------------------------ +	 * using the calculated values, compute the bank +	 * config register values. +	 * -------------------------------------------------------------------*/  	sdram0_b1cr = 0;  	sdram0_b2cr = 0;  	sdram0_b3cr = 0; @@ -421,44 +387,46 @@ long int spd_sdram(int(read_spd)(uint addr))  	/* compute the size of each bank */  	bank_size = total_size / bank_cnt;  	/* convert bank size to bank size code for ppc4xx -		by takeing log2(bank_size) - 22 */ -	tmp=bank_size; 		/* start with tmp = bank_size */ -	bank_code=0;			/* and bank_code = 0 */ -	while (tmp>1){ 		/* this takes log2 of tmp */ +	   by takeing log2(bank_size) - 22 */ +	tmp = bank_size; 		/* start with tmp = bank_size */ +	bank_code = 0;			/* and bank_code = 0 */ +	while (tmp > 1) { 		/* this takes log2 of tmp */  		bank_code++;		/* and stores result in bank_code */ -		tmp=tmp>>1; -		}				/* bank_code is now log2(bank_size) */ -	bank_code-=22;				/* subtract 22 to get the code */ +		tmp = tmp >> 1; +	}				/* bank_code is now log2(bank_size) */ +	bank_code -= 22;		/* subtract 22 to get the code */  	tmp = SDRAM0_BXCR_SZ(bank_code) | SDRAM0_BXCR_AM(mode) | 1; -	sdram0_b0cr = (bank_size) * 0 | tmp; +	sdram0_b0cr = (bank_size * 0) | tmp;  #ifndef CONFIG_405EP /* not on PPC405EP */ -	if(bank_cnt>1) sdram0_b2cr = (bank_size) * 1 | tmp; -	if(bank_cnt>2) sdram0_b1cr = (bank_size) * 2 | tmp; -	if(bank_cnt>3) sdram0_b3cr = (bank_size) * 3 | tmp; +	if (bank_cnt > 1) +		sdram0_b2cr = (bank_size * 1) | tmp; +	if (bank_cnt > 2) +		sdram0_b1cr = (bank_size * 2) | tmp; +	if (bank_cnt > 3) +		sdram0_b3cr = (bank_size * 3) | tmp;  #else  	/* PPC405EP chip only supports two SDRAM banks */ -	if(bank_cnt>1) sdram0_b1cr = (bank_size) * 1 | tmp; -	if(bank_cnt>2) total_size -= (bank_size) * (bank_cnt - 2); +	if (bank_cnt > 1) +		sdram0_b1cr = (bank_size * 1) | tmp; +	if (bank_cnt > 2) +		total_size = 2 * bank_size;  #endif -  	/*  	 *   enable sdram controller DCE=1  	 *  enable burst read prefetch to 32 bytes BRPF=2  	 *  leave other functions off  	 */ -/*------------------------------------------------------------------ -	now that we've done our calculations, we are ready to -	program all the registers. - -------------------------------------------------------------------*/ - +	/*------------------------------------------------------------------ +	 * now that we've done our calculations, we are ready to +	 * program all the registers. +	 * -------------------------------------------------------------------*/  #define mtsdram0(reg, data)  mtdcr(memcfga,reg);mtdcr(memcfgd,data)  	/* disable memcontroller so updates work */ -	sdram0_cfg = 0; -	mtsdram0( mem_mcopt1, sdram0_cfg ); +	mtsdram0( mem_mcopt1, 0 );  #ifndef CONFIG_405EP /* not on PPC405EP */  	mtsdram0( mem_besra , sdram0_besr0 ); @@ -479,15 +447,10 @@ long int spd_sdram(int(read_spd)(uint addr))  	/* SDRAM have a power on delay,  500 micro should do */  	udelay(500);  	sdram0_cfg = SDRAM0_CFG_DCE | SDRAM0_CFG_BRPF(1) | SDRAM0_CFG_ECCDD | SDRAM0_CFG_EMDULR; -	if(ecc_on) sdram0_cfg |= SDRAM0_CFG_MEMCHK; -	mtsdram0( mem_mcopt1, sdram0_cfg ); - +	if (ecc_on) +		sdram0_cfg |= SDRAM0_CFG_MEMCHK; +	mtsdram0(mem_mcopt1, sdram0_cfg); -	/* kernel 2.4.2 from mvista has a bug with memory over 128MB */ -#ifdef MVISTA_MEM_BUG -	if (total_size > 128*1024*1024 ) -		total_size=128*1024*1024; -#endif  	return (total_size);  } @@ -504,8 +467,8 @@ int spd_read(uint addr)  #else                             /* CONFIG_440 */  /*----------------------------------------------------------------------------- -|  Memory Controller Options 0 -+-----------------------------------------------------------------------------*/ +  |  Memory Controller Options 0 +  +-----------------------------------------------------------------------------*/  #define SDRAM_CFG0_DCEN           0x80000000  /* SDRAM Controller Enable      */  #define SDRAM_CFG0_MCHK_MASK      0x30000000  /* Memory data errchecking mask */  #define SDRAM_CFG0_MCHK_NON       0x00000000  /* No ECC generation            */ @@ -520,39 +483,39 @@ int spd_read(uint addr)  #define SDRAM_CFG0_PDP            0x00200000  /* Page deallocation policy     */  /*----------------------------------------------------------------------------- -|  Memory Controller Options 1 -+-----------------------------------------------------------------------------*/ +  |  Memory Controller Options 1 +  +-----------------------------------------------------------------------------*/  #define SDRAM_CFG1_SRE            0x80000000  /* Self-Refresh Entry           */  #define SDRAM_CFG1_PMEN           0x40000000  /* Power Management Enable      */  /*-----------------------------------------------------------------------------+ -|  SDRAM DEVPOT Options -+-----------------------------------------------------------------------------*/ +  |  SDRAM DEVPOT Options +  +-----------------------------------------------------------------------------*/  #define SDRAM_DEVOPT_DLL          0x80000000  #define SDRAM_DEVOPT_DS           0x40000000  /*-----------------------------------------------------------------------------+ -|  SDRAM MCSTS Options -+-----------------------------------------------------------------------------*/ +  |  SDRAM MCSTS Options +  +-----------------------------------------------------------------------------*/  #define SDRAM_MCSTS_MRSC          0x80000000  #define SDRAM_MCSTS_SRMS          0x40000000  #define SDRAM_MCSTS_CIS           0x20000000  /*----------------------------------------------------------------------------- -|  SDRAM Refresh Timer Register -+-----------------------------------------------------------------------------*/ +  |  SDRAM Refresh Timer Register +  +-----------------------------------------------------------------------------*/  #define SDRAM_RTR_RINT_MASK       0xFFFF0000  #define SDRAM_RTR_RINT_ENCODE(n)  (((n) << 16) & SDRAM_RTR_RINT_MASK)  #define sdram_HZ_to_ns(hertz)     (1000000000/(hertz))  /*-----------------------------------------------------------------------------+ -|  SDRAM UABus Base Address Reg -+-----------------------------------------------------------------------------*/ +  |  SDRAM UABus Base Address Reg +  +-----------------------------------------------------------------------------*/  #define SDRAM_UABBA_UBBA_MASK     0x0000000F  /*-----------------------------------------------------------------------------+ -|  Memory Bank 0-7 configuration -+-----------------------------------------------------------------------------*/ +  |  Memory Bank 0-7 configuration +  +-----------------------------------------------------------------------------*/  #define SDRAM_BXCR_SDBA_MASK      0xff800000      /* Base address             */  #define SDRAM_BXCR_SDSZ_MASK      0x000e0000      /* Size                     */  #define SDRAM_BXCR_SDSZ_8         0x00020000      /*   8M                     */ @@ -570,8 +533,8 @@ int spd_read(uint addr)  #define SDRAM_BXCR_SDBE           0x00000001      /* Memory Bank Enable       */  /*-----------------------------------------------------------------------------+ -|  SDRAM TR0 Options -+-----------------------------------------------------------------------------*/ +  |  SDRAM TR0 Options +  +-----------------------------------------------------------------------------*/  #define SDRAM_TR0_SDWR_MASK       0x80000000  #define   SDRAM_TR0_SDWR_2_CLK    0x00000000  #define   SDRAM_TR0_SDWR_3_CLK    0x80000000 @@ -609,8 +572,8 @@ int spd_read(uint addr)  #define   SDRAM_TR0_SDRD_4_CLK    0x00000003  /*-----------------------------------------------------------------------------+ -|  SDRAM TR1 Options -+-----------------------------------------------------------------------------*/ +  |  SDRAM TR1 Options +  +-----------------------------------------------------------------------------*/  #define SDRAM_TR1_RDSS_MASK         0xC0000000  #define   SDRAM_TR1_RDSS_TR0        0x00000000  #define   SDRAM_TR1_RDSS_TR1        0x40000000 @@ -630,8 +593,8 @@ int spd_read(uint addr)  #define   SDRAM_TR1_RDCT_MAX        0x000001FF  /*-----------------------------------------------------------------------------+ -|  SDRAM WDDCTR Options -+-----------------------------------------------------------------------------*/ +  |  SDRAM WDDCTR Options +  +-----------------------------------------------------------------------------*/  #define SDRAM_WDDCTR_WRCP_MASK       0xC0000000  #define   SDRAM_WDDCTR_WRCP_0DEG     0x00000000  #define   SDRAM_WDDCTR_WRCP_90DEG    0x40000000 @@ -639,8 +602,8 @@ int spd_read(uint addr)  #define SDRAM_WDDCTR_DCD_MASK        0x000001FF  /*-----------------------------------------------------------------------------+ -|  SDRAM CLKTR Options -+-----------------------------------------------------------------------------*/ +  |  SDRAM CLKTR Options +  +-----------------------------------------------------------------------------*/  #define SDRAM_CLKTR_CLKP_MASK       0xC0000000  #define   SDRAM_CLKTR_CLKP_0DEG     0x00000000  #define   SDRAM_CLKTR_CLKP_90DEG    0x40000000 @@ -648,18 +611,17 @@ int spd_read(uint addr)  #define SDRAM_CLKTR_DCDT_MASK       0x000001FF  /*-----------------------------------------------------------------------------+ -|  SDRAM DLYCAL Options -+-----------------------------------------------------------------------------*/ +  |  SDRAM DLYCAL Options +  +-----------------------------------------------------------------------------*/  #define SDRAM_DLYCAL_DLCV_MASK      0x000003FC  #define   SDRAM_DLYCAL_DLCV_ENCODE(x) (((x)<<2) & SDRAM_DLYCAL_DLCV_MASK)  #define   SDRAM_DLYCAL_DLCV_DECODE(x) (((x) & SDRAM_DLYCAL_DLCV_MASK)>>2)  /*-----------------------------------------------------------------------------+ -|  General Definition -+-----------------------------------------------------------------------------*/ +  |  General Definition +  +-----------------------------------------------------------------------------*/  #define DEFAULT_SPD_ADDR1   0x53  #define DEFAULT_SPD_ADDR2   0x52 -#define ONE_BILLION         1000000000  #define MAXBANKS            4               /* at most 4 dimm banks */  #define MAX_SPD_BYTES       256  #define NUMHALFCYCLES       4 @@ -670,22 +632,22 @@ int spd_read(uint addr)  #define FALSE               0  const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = { -    {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, -     0xFFFFFFFF, 0xFFFFFFFF}, -    {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, -     0x00000000, 0x00000000}, -    {0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, -     0x55555555, 0x55555555}, -    {0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, -     0xAAAAAAAA, 0xAAAAAAAA}, -    {0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, -     0x5A5A5A5A, 0x5A5A5A5A}, -    {0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, -     0xA5A5A5A5, 0xA5A5A5A5}, -    {0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, -     0x55AA55AA, 0x55AA55AA}, -    {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, -     0xAA55AA55, 0xAA55AA55} +	{0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, +	 0xFFFFFFFF, 0xFFFFFFFF}, +	{0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, +	 0x00000000, 0x00000000}, +	{0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, +	 0x55555555, 0x55555555}, +	{0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, +	 0xAAAAAAAA, 0xAAAAAAAA}, +	{0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, +	 0x5A5A5A5A, 0x5A5A5A5A}, +	{0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, +	 0xA5A5A5A5, 0xA5A5A5A5}, +	{0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, +	 0x55AA55AA, 0x55AA55AA}, +	{0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, +	 0xAA55AA55, 0xAA55AA55}  }; @@ -696,14 +658,14 @@ void get_spd_info(unsigned long* dimm_populated,  		  unsigned long  num_dimm_banks);  void check_mem_type -		 (unsigned long* dimm_populated, -		  unsigned char* iic0_dimm_addr, -		  unsigned long  num_dimm_banks); +(unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long  num_dimm_banks);  void check_volt_type -		 (unsigned long* dimm_populated, -		  unsigned char* iic0_dimm_addr, -		  unsigned long  num_dimm_banks); +(unsigned long* dimm_populated, + unsigned char* iic0_dimm_addr, + unsigned long  num_dimm_banks);  void program_cfg0(unsigned long* dimm_populated,  		  unsigned char* iic0_dimm_addr, @@ -741,14 +703,14 @@ long  program_bxcr(unsigned long* dimm_populated,   */  long int spd_sdram(void) { -    unsigned char iic0_dimm_addr[] = SPD_EEPROM_ADDRESS; -    unsigned long dimm_populated[sizeof(iic0_dimm_addr)]; -    unsigned long total_size; -    unsigned long cfg0; -    unsigned long mcsts; -    unsigned long num_dimm_banks;               /* on board dimm banks */ +	unsigned char iic0_dimm_addr[] = SPD_EEPROM_ADDRESS; +	unsigned long dimm_populated[sizeof(iic0_dimm_addr)]; +	unsigned long total_size; +	unsigned long cfg0; +	unsigned long mcsts; +	unsigned long num_dimm_banks;               /* on board dimm banks */ -    num_dimm_banks = sizeof(iic0_dimm_addr); +	num_dimm_banks = sizeof(iic0_dimm_addr);  	/*  	 * Make sure I2C controller is initialized @@ -756,90 +718,90 @@ long int spd_sdram(void) {  	 */  	i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); -    /* -     * Read the SPD information using I2C interface. Check to see if the -     * DIMM slots are populated. -     */ -    get_spd_info(dimm_populated, iic0_dimm_addr, num_dimm_banks); +	/* +	 * Read the SPD information using I2C interface. Check to see if the +	 * DIMM slots are populated. +	 */ +	get_spd_info(dimm_populated, iic0_dimm_addr, num_dimm_banks); -    /* -     * Check the memory type for the dimms plugged. -     */ -    check_mem_type(dimm_populated, iic0_dimm_addr, num_dimm_banks); +	/* +	 * Check the memory type for the dimms plugged. +	 */ +	check_mem_type(dimm_populated, iic0_dimm_addr, num_dimm_banks); -    /* -     * Check the voltage type for the dimms plugged. -     */ -    check_volt_type(dimm_populated, iic0_dimm_addr, num_dimm_banks); +	/* +	 * Check the voltage type for the dimms plugged. +	 */ +	check_volt_type(dimm_populated, iic0_dimm_addr, num_dimm_banks);  #if defined(CONFIG_440_GX) -    /* -     * Soft-reset SDRAM controller. -     */ -    mtsdr(sdr_srst, SDR0_SRST_DMC); -    mtsdr(sdr_srst, 0x00000000); +	/* +	 * Soft-reset SDRAM controller. +	 */ +	mtsdr(sdr_srst, SDR0_SRST_DMC); +	mtsdr(sdr_srst, 0x00000000);  #endif -    /* -     * program 440GP SDRAM controller options (SDRAM0_CFG0) -     */ -    program_cfg0(dimm_populated, iic0_dimm_addr, num_dimm_banks); +	/* +	 * program 440GP SDRAM controller options (SDRAM0_CFG0) +	 */ +	program_cfg0(dimm_populated, iic0_dimm_addr, num_dimm_banks); -    /* -     * program 440GP SDRAM controller options (SDRAM0_CFG1) -     */ -    program_cfg1(dimm_populated, iic0_dimm_addr, num_dimm_banks); +	/* +	 * program 440GP SDRAM controller options (SDRAM0_CFG1) +	 */ +	program_cfg1(dimm_populated, iic0_dimm_addr, num_dimm_banks); -    /* -     * program SDRAM refresh register (SDRAM0_RTR) -     */ -    program_rtr(dimm_populated, iic0_dimm_addr, num_dimm_banks); +	/* +	 * program SDRAM refresh register (SDRAM0_RTR) +	 */ +	program_rtr(dimm_populated, iic0_dimm_addr, num_dimm_banks); -    /* -     * program SDRAM Timing Register 0 (SDRAM0_TR0) -     */ -    program_tr0(dimm_populated, iic0_dimm_addr, num_dimm_banks); +	/* +	 * program SDRAM Timing Register 0 (SDRAM0_TR0) +	 */ +	program_tr0(dimm_populated, iic0_dimm_addr, num_dimm_banks); -    /* -     * program the BxCR registers to find out total sdram installed -     */ -    total_size = program_bxcr(dimm_populated, iic0_dimm_addr, -	num_dimm_banks); +	/* +	 * program the BxCR registers to find out total sdram installed +	 */ +	total_size = program_bxcr(dimm_populated, iic0_dimm_addr, +				  num_dimm_banks); -    /* -     * program SDRAM Clock Timing Register (SDRAM0_CLKTR) -     */ -    mtsdram(mem_clktr, 0x40000000); +	/* +	 * program SDRAM Clock Timing Register (SDRAM0_CLKTR) +	 */ +	mtsdram(mem_clktr, 0x40000000); -    /* -     * delay to ensure 200 usec has elapsed -     */ -    udelay(400); +	/* +	 * delay to ensure 200 usec has elapsed +	 */ +	udelay(400); -    /* -     * enable the memory controller -     */ -    mfsdram(mem_cfg0, cfg0); -    mtsdram(mem_cfg0, cfg0 | SDRAM_CFG0_DCEN); +	/* +	 * enable the memory controller +	 */ +	mfsdram(mem_cfg0, cfg0); +	mtsdram(mem_cfg0, cfg0 | SDRAM_CFG0_DCEN); -    /* -     * wait for SDRAM_CFG0_DC_EN to complete -     */ -    while(1) { -	mfsdram(mem_mcsts, mcsts); -	if ((mcsts & SDRAM_MCSTS_MRSC) != 0) { -	    break; +	/* +	 * wait for SDRAM_CFG0_DC_EN to complete +	 */ +	while (1) { +		mfsdram(mem_mcsts, mcsts); +		if ((mcsts & SDRAM_MCSTS_MRSC) != 0) { +			break; +		}  	} -    } -    /* -     * program SDRAM Timing Register 1, adding some delays -     */ -    program_tr1(); +	/* +	 * program SDRAM Timing Register 1, adding some delays +	 */ +	program_tr1(); -    /* -     * if ECC is enabled, initialize parity bits -     */ +	/* +	 * if ECC is enabled, initialize parity bits +	 */  	return total_size;  } @@ -847,76 +809,78 @@ long int spd_sdram(void) {  unsigned char spd_read(uchar chip, uint addr) {  	unsigned char data[2]; -	if (i2c_read(chip, addr, 1, data, 1) == 0) -		return data[0]; -	else -		return 0; +	if (i2c_probe(chip) == 0) { +		if (i2c_read(chip, addr, 1, data, 1) == 0) { +			return data[0]; +		} +	} + +	return 0;  }  void get_spd_info(unsigned long*   dimm_populated,  		  unsigned char*   iic0_dimm_addr,  		  unsigned long    num_dimm_banks)  { -    unsigned long dimm_num; -    unsigned long dimm_found; -    unsigned char num_of_bytes; -    unsigned char total_size; +	unsigned long dimm_num; +	unsigned long dimm_found; +	unsigned char num_of_bytes; +	unsigned char total_size; -    dimm_found = FALSE; -    for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { -	num_of_bytes = 0; -	total_size = 0; +	dimm_found = FALSE; +	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { +		num_of_bytes = 0; +		total_size = 0; -	num_of_bytes = spd_read(iic0_dimm_addr[dimm_num], 0); -	total_size = spd_read(iic0_dimm_addr[dimm_num], 1); +		num_of_bytes = spd_read(iic0_dimm_addr[dimm_num], 0); +		total_size = spd_read(iic0_dimm_addr[dimm_num], 1); -	if ((num_of_bytes != 0) && (total_size != 0)) { -	    dimm_populated[dimm_num] = TRUE; -	    dimm_found = TRUE; +		if ((num_of_bytes != 0) && (total_size != 0)) { +			dimm_populated[dimm_num] = TRUE; +			dimm_found = TRUE;  #if 0 -	    printf("DIMM slot %lu: populated\n", dimm_num); +			printf("DIMM slot %lu: populated\n", dimm_num);  #endif -	} -	else { -	    dimm_populated[dimm_num] = FALSE; +		} else { +			dimm_populated[dimm_num] = FALSE;  #if 0 -	    printf("DIMM slot %lu: Not populated\n", dimm_num); +			printf("DIMM slot %lu: Not populated\n", dimm_num);  #endif +		}  	} -    } -    if (dimm_found == FALSE) { -	printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n"); -	hang(); -    } +	if (dimm_found == FALSE) { +		printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n"); +		hang(); +	}  }  void check_mem_type(unsigned long*   dimm_populated,  		    unsigned char*   iic0_dimm_addr,  		    unsigned long    num_dimm_banks)  { -    unsigned long dimm_num; -    unsigned char dimm_type; +	unsigned long dimm_num; +	unsigned char dimm_type; -    for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { -	if (dimm_populated[dimm_num] == TRUE) { -	    dimm_type = spd_read(iic0_dimm_addr[dimm_num], 2); -	    switch (dimm_type) { -	    case 7: +	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { +		if (dimm_populated[dimm_num] == TRUE) { +			dimm_type = spd_read(iic0_dimm_addr[dimm_num], 2); +			switch (dimm_type) { +			case 7:  #if 0 -		printf("DIMM slot %lu: DDR SDRAM detected\n", dimm_num); +				printf("DIMM slot %lu: DDR SDRAM detected\n", dimm_num);  #endif -		break; -	    default: -		printf("ERROR: Unsupported DIMM detected in slot %lu.\n", -		    dimm_num); -		printf("Only DDR SDRAM DIMMs are supported.\n"); -		printf("Replace the DIMM module with a supported DIMM.\n\n"); -		hang(); -		break; -	    } +				break; +			default: +				printf("ERROR: Unsupported DIMM detected in slot %lu.\n", +				       dimm_num); +				printf("Only DDR SDRAM DIMMs are supported.\n"); +				printf("Replace the DIMM module with a supported DIMM.\n\n"); +				hang(); +				break; +			} +		}  	} -    }  } @@ -924,894 +888,877 @@ void check_volt_type(unsigned long*   dimm_populated,  		     unsigned char*   iic0_dimm_addr,  		     unsigned long    num_dimm_banks)  { -    unsigned long dimm_num; -    unsigned long voltage_type; +	unsigned long dimm_num; +	unsigned long voltage_type; -    for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { -	if (dimm_populated[dimm_num] == TRUE) { -	    voltage_type = spd_read(iic0_dimm_addr[dimm_num], 8); -	    if (voltage_type != 0x04) { -		printf("ERROR: DIMM %lu with unsupported voltage level.\n", -		    dimm_num); -		hang(); -	    } -	    else { +	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { +		if (dimm_populated[dimm_num] == TRUE) { +			voltage_type = spd_read(iic0_dimm_addr[dimm_num], 8); +			if (voltage_type != 0x04) { +				printf("ERROR: DIMM %lu with unsupported voltage level.\n", +				       dimm_num); +				hang(); +			} else {  #if 0 -		printf("DIMM %lu voltage level supported.\n", dimm_num); +				printf("DIMM %lu voltage level supported.\n", dimm_num);  #endif -	    } -	    break; +			} +			break; +		}  	} -    }  }  void program_cfg0(unsigned long* dimm_populated,  		  unsigned char* iic0_dimm_addr,  		  unsigned long  num_dimm_banks)  { -    unsigned long dimm_num; -    unsigned long cfg0; -    unsigned long ecc_enabled; -    unsigned char ecc; -    unsigned char attributes; -    unsigned long data_width; -    unsigned long dimm_32bit; -    unsigned long dimm_64bit; +	unsigned long dimm_num; +	unsigned long cfg0; +	unsigned long ecc_enabled; +	unsigned char ecc; +	unsigned char attributes; +	unsigned long data_width; +	unsigned long dimm_32bit; +	unsigned long dimm_64bit; -    /* -     * get Memory Controller Options 0 data -     */ -    mfsdram(mem_cfg0, cfg0); +	/* +	 * get Memory Controller Options 0 data +	 */ +	mfsdram(mem_cfg0, cfg0); -    /* -     * clear bits -     */ -    cfg0 &= ~(SDRAM_CFG0_DCEN | SDRAM_CFG0_MCHK_MASK | -	      SDRAM_CFG0_RDEN | SDRAM_CFG0_PMUD | -	      SDRAM_CFG0_DMWD_MASK | -	      SDRAM_CFG0_UIOS_MASK | SDRAM_CFG0_PDP); +	/* +	 * clear bits +	 */ +	cfg0 &= ~(SDRAM_CFG0_DCEN | SDRAM_CFG0_MCHK_MASK | +		  SDRAM_CFG0_RDEN | SDRAM_CFG0_PMUD | +		  SDRAM_CFG0_DMWD_MASK | +		  SDRAM_CFG0_UIOS_MASK | SDRAM_CFG0_PDP); -    /* -     * FIXME: assume the DDR SDRAMs in both banks are the same -     */ -    ecc_enabled = TRUE; -    for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { -	if (dimm_populated[dimm_num] == TRUE) { -	    ecc = spd_read(iic0_dimm_addr[dimm_num], 11); -	    if (ecc != 0x02) { -		ecc_enabled = FALSE; -	    } +	/* +	 * FIXME: assume the DDR SDRAMs in both banks are the same +	 */ +	ecc_enabled = TRUE; +	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { +		if (dimm_populated[dimm_num] == TRUE) { +			ecc = spd_read(iic0_dimm_addr[dimm_num], 11); +			if (ecc != 0x02) { +				ecc_enabled = FALSE; +			} -	    /* -	     * program Registered DIMM Enable -	     */ -	    attributes = spd_read(iic0_dimm_addr[dimm_num], 21); -	    if ((attributes & 0x02) != 0x00) { -		cfg0 |= SDRAM_CFG0_RDEN; -	    } +			/* +			 * program Registered DIMM Enable +			 */ +			attributes = spd_read(iic0_dimm_addr[dimm_num], 21); +			if ((attributes & 0x02) != 0x00) { +				cfg0 |= SDRAM_CFG0_RDEN; +			} -	    /* -	     * program DDR SDRAM Data Width -	     */ -	    data_width = -		(unsigned long)spd_read(iic0_dimm_addr[dimm_num],6) + -		(((unsigned long)spd_read(iic0_dimm_addr[dimm_num],7)) << 8); -	    if (data_width == 64 || data_width == 72) { -		dimm_64bit = TRUE; -		cfg0 |= SDRAM_CFG0_DMWD_64; -	    } -	    else if (data_width == 32 || data_width == 40) { -		dimm_32bit = TRUE; -		cfg0 |= SDRAM_CFG0_DMWD_32; -	    } -	    else { -		printf("WARNING: DIMM with datawidth of %lu bits.\n", -		    data_width); -		printf("Only DIMMs with 32 or 64 bit datawidths supported.\n"); -		hang(); -	    } -	    break; +			/* +			 * program DDR SDRAM Data Width +			 */ +			data_width = +				(unsigned long)spd_read(iic0_dimm_addr[dimm_num],6) + +				(((unsigned long)spd_read(iic0_dimm_addr[dimm_num],7)) << 8); +			if (data_width == 64 || data_width == 72) { +				dimm_64bit = TRUE; +				cfg0 |= SDRAM_CFG0_DMWD_64; +			} else if (data_width == 32 || data_width == 40) { +				dimm_32bit = TRUE; +				cfg0 |= SDRAM_CFG0_DMWD_32; +			} else { +				printf("WARNING: DIMM with datawidth of %lu bits.\n", +				       data_width); +				printf("Only DIMMs with 32 or 64 bit datawidths supported.\n"); +				hang(); +			} +			break; +		}  	} -    } -    /* -     * program Memory Data Error Checking -     */ -    if (ecc_enabled == TRUE) { -	cfg0 |= SDRAM_CFG0_MCHK_GEN; -    } -    else { -	cfg0 |= SDRAM_CFG0_MCHK_NON; -    } +	/* +	 * program Memory Data Error Checking +	 */ +	if (ecc_enabled == TRUE) { +		cfg0 |= SDRAM_CFG0_MCHK_GEN; +	} else { +		cfg0 |= SDRAM_CFG0_MCHK_NON; +	} -    /* -     * program Page Management Unit -     */ -    cfg0 |= SDRAM_CFG0_PMUD; +	/* +	 * program Page Management Unit +	 */ +	cfg0 |= SDRAM_CFG0_PMUD; -    /* -     * program Memory Controller Options 0 -     * Note: DCEN must be enabled after all DDR SDRAM controller -     * configuration registers get initialized. -     */ -    mtsdram(mem_cfg0, cfg0); +	/* +	 * program Memory Controller Options 0 +	 * Note: DCEN must be enabled after all DDR SDRAM controller +	 * configuration registers get initialized. +	 */ +	mtsdram(mem_cfg0, cfg0);  }  void program_cfg1(unsigned long* dimm_populated,  		  unsigned char* iic0_dimm_addr,  		  unsigned long  num_dimm_banks)  { -    unsigned long cfg1; -    mfsdram(mem_cfg1, cfg1); +	unsigned long cfg1; +	mfsdram(mem_cfg1, cfg1); -    /* -     * Self-refresh exit, disable PM -     */ -    cfg1 &= ~(SDRAM_CFG1_SRE | SDRAM_CFG1_PMEN); +	/* +	 * Self-refresh exit, disable PM +	 */ +	cfg1 &= ~(SDRAM_CFG1_SRE | SDRAM_CFG1_PMEN); -    /* -     * program Memory Controller Options 1 -     */ -    mtsdram(mem_cfg1, cfg1); +	/* +	 * program Memory Controller Options 1 +	 */ +	mtsdram(mem_cfg1, cfg1);  }  void program_rtr (unsigned long* dimm_populated,  		  unsigned char* iic0_dimm_addr,  		  unsigned long  num_dimm_banks)  { -    unsigned long dimm_num; -    unsigned long bus_period_x_10; -    unsigned long refresh_rate = 0; -    unsigned char refresh_rate_type; -    unsigned long refresh_interval; -    unsigned long sdram_rtr; -    PPC440_SYS_INFO sys_info; +	unsigned long dimm_num; +	unsigned long bus_period_x_10; +	unsigned long refresh_rate = 0; +	unsigned char refresh_rate_type; +	unsigned long refresh_interval; +	unsigned long sdram_rtr; +	PPC440_SYS_INFO sys_info; -    /* -     * get the board info -     */ -    get_sys_info(&sys_info); -    bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10); +	/* +	 * get the board info +	 */ +	get_sys_info(&sys_info); +	bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10); -    for (dimm_num = 0;  dimm_num < num_dimm_banks; dimm_num++) { -	if (dimm_populated[dimm_num] == TRUE) { -	    refresh_rate_type = 0x7F & spd_read(iic0_dimm_addr[dimm_num], 12); -	    switch (refresh_rate_type) { -	    case 0x00: -		refresh_rate = 15625; -		break; -	    case 0x01: -		refresh_rate = 15625/4; -		break; -	    case 0x02: -		refresh_rate = 15625/2; -		break; -	    case 0x03: -		refresh_rate = 15626*2; -		break; -	    case 0x04: -		refresh_rate = 15625*4; -		break; -	    case 0x05: -		refresh_rate = 15625*8; -		break; -	    default: -		printf("ERROR: DIMM %lu, unsupported refresh rate/type.\n", -		    dimm_num); -		printf("Replace the DIMM module with a supported DIMM.\n"); -		break; -	    } +	for (dimm_num = 0;  dimm_num < num_dimm_banks; dimm_num++) { +		if (dimm_populated[dimm_num] == TRUE) { +			refresh_rate_type = 0x7F & spd_read(iic0_dimm_addr[dimm_num], 12); +			switch (refresh_rate_type) { +			case 0x00: +				refresh_rate = 15625; +				break; +			case 0x01: +				refresh_rate = 15625/4; +				break; +			case 0x02: +				refresh_rate = 15625/2; +				break; +			case 0x03: +				refresh_rate = 15626*2; +				break; +			case 0x04: +				refresh_rate = 15625*4; +				break; +			case 0x05: +				refresh_rate = 15625*8; +				break; +			default: +				printf("ERROR: DIMM %lu, unsupported refresh rate/type.\n", +				       dimm_num); +				printf("Replace the DIMM module with a supported DIMM.\n"); +				break; +			} -	    break; +			break; +		}  	} -    } -    refresh_interval = refresh_rate * 10 / bus_period_x_10; -    sdram_rtr = (refresh_interval & 0x3ff8) <<  16; +	refresh_interval = refresh_rate * 10 / bus_period_x_10; +	sdram_rtr = (refresh_interval & 0x3ff8) <<  16; -    /* -     * program Refresh Timer Register (SDRAM0_RTR) -     */ -    mtsdram(mem_rtr, sdram_rtr); +	/* +	 * program Refresh Timer Register (SDRAM0_RTR) +	 */ +	mtsdram(mem_rtr, sdram_rtr);  }  void program_tr0 (unsigned long* dimm_populated,  		  unsigned char* iic0_dimm_addr,  		  unsigned long  num_dimm_banks)  { -    unsigned long dimm_num; -    unsigned long tr0; -    unsigned char wcsbc; -    unsigned char t_rp_ns; -    unsigned char t_rcd_ns; -    unsigned char t_ras_ns; -    unsigned long t_rp_clk; -    unsigned long t_ras_rcd_clk; -    unsigned long t_rcd_clk; -    unsigned long t_rfc_clk; -    unsigned long plb_check; -    unsigned char cas_bit; -    unsigned long cas_index; -    unsigned char cas_2_0_available; -    unsigned char cas_2_5_available; -    unsigned char cas_3_0_available; -    unsigned long cycle_time_ns_x_10[3]; -    unsigned long tcyc_3_0_ns_x_10; -    unsigned long tcyc_2_5_ns_x_10; -    unsigned long tcyc_2_0_ns_x_10; -    unsigned long tcyc_reg; -    unsigned long bus_period_x_10; -    PPC440_SYS_INFO sys_info; -    unsigned long residue; +	unsigned long dimm_num; +	unsigned long tr0; +	unsigned char wcsbc; +	unsigned char t_rp_ns; +	unsigned char t_rcd_ns; +	unsigned char t_ras_ns; +	unsigned long t_rp_clk; +	unsigned long t_ras_rcd_clk; +	unsigned long t_rcd_clk; +	unsigned long t_rfc_clk; +	unsigned long plb_check; +	unsigned char cas_bit; +	unsigned long cas_index; +	unsigned char cas_2_0_available; +	unsigned char cas_2_5_available; +	unsigned char cas_3_0_available; +	unsigned long cycle_time_ns_x_10[3]; +	unsigned long tcyc_3_0_ns_x_10; +	unsigned long tcyc_2_5_ns_x_10; +	unsigned long tcyc_2_0_ns_x_10; +	unsigned long tcyc_reg; +	unsigned long bus_period_x_10; +	PPC440_SYS_INFO sys_info; +	unsigned long residue; -    /* -     * get the board info -     */ -    get_sys_info(&sys_info); -    bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10); +	/* +	 * get the board info +	 */ +	get_sys_info(&sys_info); +	bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10); -    /* -     * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits -     */ -    mfsdram(mem_tr0, tr0); -    tr0 &= ~(SDRAM_TR0_SDWR_MASK | SDRAM_TR0_SDWD_MASK | -	     SDRAM_TR0_SDCL_MASK | SDRAM_TR0_SDPA_MASK | -	     SDRAM_TR0_SDCP_MASK | SDRAM_TR0_SDLD_MASK | -	     SDRAM_TR0_SDRA_MASK | SDRAM_TR0_SDRD_MASK); +	/* +	 * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits +	 */ +	mfsdram(mem_tr0, tr0); +	tr0 &= ~(SDRAM_TR0_SDWR_MASK | SDRAM_TR0_SDWD_MASK | +		 SDRAM_TR0_SDCL_MASK | SDRAM_TR0_SDPA_MASK | +		 SDRAM_TR0_SDCP_MASK | SDRAM_TR0_SDLD_MASK | +		 SDRAM_TR0_SDRA_MASK | SDRAM_TR0_SDRD_MASK); -    /* -     * initialization -     */ -    wcsbc = 0; -    t_rp_ns = 0; -    t_rcd_ns = 0; -    t_ras_ns = 0; -    cas_2_0_available = TRUE; -    cas_2_5_available = TRUE; -    cas_3_0_available = TRUE; -    tcyc_2_0_ns_x_10 = 0; -    tcyc_2_5_ns_x_10 = 0; -    tcyc_3_0_ns_x_10 = 0; +	/* +	 * initialization +	 */ +	wcsbc = 0; +	t_rp_ns = 0; +	t_rcd_ns = 0; +	t_ras_ns = 0; +	cas_2_0_available = TRUE; +	cas_2_5_available = TRUE; +	cas_3_0_available = TRUE; +	tcyc_2_0_ns_x_10 = 0; +	tcyc_2_5_ns_x_10 = 0; +	tcyc_3_0_ns_x_10 = 0; -    for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { -	if (dimm_populated[dimm_num] == TRUE) { -	    wcsbc = spd_read(iic0_dimm_addr[dimm_num], 15); -	    t_rp_ns  = spd_read(iic0_dimm_addr[dimm_num], 27) >> 2; -	    t_rcd_ns = spd_read(iic0_dimm_addr[dimm_num], 29) >> 2; -	    t_ras_ns = spd_read(iic0_dimm_addr[dimm_num], 30); -	    cas_bit = spd_read(iic0_dimm_addr[dimm_num], 18); +	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { +		if (dimm_populated[dimm_num] == TRUE) { +			wcsbc = spd_read(iic0_dimm_addr[dimm_num], 15); +			t_rp_ns  = spd_read(iic0_dimm_addr[dimm_num], 27) >> 2; +			t_rcd_ns = spd_read(iic0_dimm_addr[dimm_num], 29) >> 2; +			t_ras_ns = spd_read(iic0_dimm_addr[dimm_num], 30); +			cas_bit = spd_read(iic0_dimm_addr[dimm_num], 18); -	    for (cas_index = 0; cas_index < 3; cas_index++) { -		switch (cas_index) { -		case 0: -		    tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 9); -		    break; -		case 1: -		    tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 23); -		    break; -		default: -		    tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 25); -		    break; -		} +			for (cas_index = 0; cas_index < 3; cas_index++) { +				switch (cas_index) { +				case 0: +					tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 9); +					break; +				case 1: +					tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 23); +					break; +				default: +					tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 25); +					break; +				} -		if ((tcyc_reg & 0x0F) >= 10) { -		    printf("ERROR: Tcyc incorrect for DIMM in slot %lu\n", -			dimm_num); -		    hang(); -		} +				if ((tcyc_reg & 0x0F) >= 10) { +					printf("ERROR: Tcyc incorrect for DIMM in slot %lu\n", +					       dimm_num); +					hang(); +				} -		cycle_time_ns_x_10[cas_index] = -		    (((tcyc_reg & 0xF0) >> 4) * 10) + (tcyc_reg & 0x0F); -	    } +				cycle_time_ns_x_10[cas_index] = +					(((tcyc_reg & 0xF0) >> 4) * 10) + (tcyc_reg & 0x0F); +			} -	    cas_index = 0; +			cas_index = 0; -	    if ((cas_bit & 0x80) != 0) { -		cas_index += 3; -	    } -	    else if ((cas_bit & 0x40) != 0) { -		cas_index += 2; -	    } -	    else if ((cas_bit & 0x20) != 0) { -		cas_index += 1; -	    } +			if ((cas_bit & 0x80) != 0) { +				cas_index += 3; +			} else if ((cas_bit & 0x40) != 0) { +				cas_index += 2; +			} else if ((cas_bit & 0x20) != 0) { +				cas_index += 1; +			} -	    if (((cas_bit & 0x10) != 0) && (cas_index < 3)) { -		tcyc_3_0_ns_x_10 = cycle_time_ns_x_10[cas_index]; -		cas_index++; -	    } -	    else { -		if (cas_index != 0) { -		    cas_index++; -		} -		cas_3_0_available = FALSE; -	    } +			if (((cas_bit & 0x10) != 0) && (cas_index < 3)) { +				tcyc_3_0_ns_x_10 = cycle_time_ns_x_10[cas_index]; +				cas_index++; +			} else { +				if (cas_index != 0) { +					cas_index++; +				} +				cas_3_0_available = FALSE; +			} -	    if (((cas_bit & 0x08) != 0) || (cas_index < 3)) { -		tcyc_2_5_ns_x_10 = cycle_time_ns_x_10[cas_index]; -		cas_index++; -	    } -	    else { -		if (cas_index != 0) { -		    cas_index++; -		} -		cas_2_5_available = FALSE; -	    } +			if (((cas_bit & 0x08) != 0) || (cas_index < 3)) { +				tcyc_2_5_ns_x_10 = cycle_time_ns_x_10[cas_index]; +				cas_index++; +			} else { +				if (cas_index != 0) { +					cas_index++; +				} +				cas_2_5_available = FALSE; +			} -	    if (((cas_bit & 0x04) != 0) || (cas_index < 3)) { -		tcyc_2_0_ns_x_10 = cycle_time_ns_x_10[cas_index]; -		cas_index++; -	    } -	    else { -		if (cas_index != 0) { -		    cas_index++; -		} -		cas_2_0_available = FALSE; -	    } +			if (((cas_bit & 0x04) != 0) || (cas_index < 3)) { +				tcyc_2_0_ns_x_10 = cycle_time_ns_x_10[cas_index]; +				cas_index++; +			} else { +				if (cas_index != 0) { +					cas_index++; +				} +				cas_2_0_available = FALSE; +			} -	    break; +			break; +		}  	} -    } -    /* -     * Program SD_WR and SD_WCSBC fields -     */ -    tr0 |= SDRAM_TR0_SDWR_2_CLK;                /* Write Recovery: 2 CLK */ -    switch (wcsbc) { -    case 0: -	tr0 |= SDRAM_TR0_SDWD_0_CLK; -	break; -    default: -	tr0 |= SDRAM_TR0_SDWD_1_CLK; -	break; -    } +	/* +	 * Program SD_WR and SD_WCSBC fields +	 */ +	tr0 |= SDRAM_TR0_SDWR_2_CLK;                /* Write Recovery: 2 CLK */ +	switch (wcsbc) { +	case 0: +		tr0 |= SDRAM_TR0_SDWD_0_CLK; +		break; +	default: +		tr0 |= SDRAM_TR0_SDWD_1_CLK; +		break; +	} -    /* -     * Program SD_CASL field -     */ -    if ((cas_2_0_available == TRUE) && -	(bus_period_x_10 >= tcyc_2_0_ns_x_10)) { -	tr0 |= SDRAM_TR0_SDCL_2_0_CLK; -    } -    else if((cas_2_5_available == TRUE) && -	(bus_period_x_10 >= tcyc_2_5_ns_x_10)) { -	tr0 |= SDRAM_TR0_SDCL_2_5_CLK; -    } -    else if((cas_3_0_available == TRUE) && -	(bus_period_x_10 >= tcyc_3_0_ns_x_10)) { -	tr0 |= SDRAM_TR0_SDCL_3_0_CLK; -    } -    else { -	printf("ERROR: No supported CAS latency with the installed DIMMs.\n"); -	printf("Only CAS latencies of 2.0, 2.5, and 3.0 are supported.\n"); -	printf("Make sure the PLB speed is within the supported range.\n"); -	hang(); -    } +	/* +	 * Program SD_CASL field +	 */ +	if ((cas_2_0_available == TRUE) && +	    (bus_period_x_10 >= tcyc_2_0_ns_x_10)) { +		tr0 |= SDRAM_TR0_SDCL_2_0_CLK; +	} else if ((cas_2_5_available == TRUE) && +		 (bus_period_x_10 >= tcyc_2_5_ns_x_10)) { +		tr0 |= SDRAM_TR0_SDCL_2_5_CLK; +	} else if ((cas_3_0_available == TRUE) && +		 (bus_period_x_10 >= tcyc_3_0_ns_x_10)) { +		tr0 |= SDRAM_TR0_SDCL_3_0_CLK; +	} else { +		printf("ERROR: No supported CAS latency with the installed DIMMs.\n"); +		printf("Only CAS latencies of 2.0, 2.5, and 3.0 are supported.\n"); +		printf("Make sure the PLB speed is within the supported range.\n"); +		hang(); +	} -    /* -     * Calculate Trp in clock cycles and round up if necessary -     * Program SD_PTA field -     */ -    t_rp_clk = sys_info.freqPLB * t_rp_ns / ONE_BILLION; -    plb_check = ONE_BILLION * t_rp_clk / t_rp_ns; -    if (sys_info.freqPLB != plb_check) { -	t_rp_clk++; -    } -    switch ((unsigned long)t_rp_clk) { -    case 0: -    case 1: -    case 2: -	tr0 |= SDRAM_TR0_SDPA_2_CLK; -	break; -    case 3: -	tr0 |= SDRAM_TR0_SDPA_3_CLK; -	break; -    default: -	tr0 |= SDRAM_TR0_SDPA_4_CLK; -	break; -    } +	/* +	 * Calculate Trp in clock cycles and round up if necessary +	 * Program SD_PTA field +	 */ +	t_rp_clk = sys_info.freqPLB * t_rp_ns / ONE_BILLION; +	plb_check = ONE_BILLION * t_rp_clk / t_rp_ns; +	if (sys_info.freqPLB != plb_check) { +		t_rp_clk++; +	} +	switch ((unsigned long)t_rp_clk) { +	case 0: +	case 1: +	case 2: +		tr0 |= SDRAM_TR0_SDPA_2_CLK; +		break; +	case 3: +		tr0 |= SDRAM_TR0_SDPA_3_CLK; +		break; +	default: +		tr0 |= SDRAM_TR0_SDPA_4_CLK; +		break; +	} -    /* -     * Program SD_CTP field -     */ -    t_ras_rcd_clk = sys_info.freqPLB * (t_ras_ns - t_rcd_ns) / ONE_BILLION; -    plb_check = ONE_BILLION * t_ras_rcd_clk / (t_ras_ns - t_rcd_ns); -    if (sys_info.freqPLB != plb_check) { -	t_ras_rcd_clk++; -    } -    switch (t_ras_rcd_clk) { -    case 0: -    case 1: -    case 2: -      tr0 |= SDRAM_TR0_SDCP_2_CLK; -      break; -    case 3: -      tr0 |= SDRAM_TR0_SDCP_3_CLK; -      break; -    case 4: -      tr0 |= SDRAM_TR0_SDCP_4_CLK; -      break; -    default: -      tr0 |= SDRAM_TR0_SDCP_5_CLK; -      break; -    } +	/* +	 * Program SD_CTP field +	 */ +	t_ras_rcd_clk = sys_info.freqPLB * (t_ras_ns - t_rcd_ns) / ONE_BILLION; +	plb_check = ONE_BILLION * t_ras_rcd_clk / (t_ras_ns - t_rcd_ns); +	if (sys_info.freqPLB != plb_check) { +		t_ras_rcd_clk++; +	} +	switch (t_ras_rcd_clk) { +	case 0: +	case 1: +	case 2: +		tr0 |= SDRAM_TR0_SDCP_2_CLK; +		break; +	case 3: +		tr0 |= SDRAM_TR0_SDCP_3_CLK; +		break; +	case 4: +		tr0 |= SDRAM_TR0_SDCP_4_CLK; +		break; +	default: +		tr0 |= SDRAM_TR0_SDCP_5_CLK; +		break; +	} -    /* -     * Program SD_LDF field -     */ -    tr0 |= SDRAM_TR0_SDLD_2_CLK; +	/* +	 * Program SD_LDF field +	 */ +	tr0 |= SDRAM_TR0_SDLD_2_CLK; -    /* -     * Program SD_RFTA field -     * FIXME tRFC hardcoded as 75 nanoseconds -     */ -    t_rfc_clk = sys_info.freqPLB / (ONE_BILLION / 75); -    residue = sys_info.freqPLB % (ONE_BILLION / 75); -    if (residue >= (ONE_BILLION / 150)) { -	t_rfc_clk++; -    } -    switch (t_rfc_clk) { -    case 0: -    case 1: -    case 2: -    case 3: -    case 4: -    case 5: -    case 6: -	tr0 |= SDRAM_TR0_SDRA_6_CLK; -	break; -    case 7: -	tr0 |= SDRAM_TR0_SDRA_7_CLK; -	break; -    case 8: -	tr0 |= SDRAM_TR0_SDRA_8_CLK; -	break; -    case 9: -	tr0 |= SDRAM_TR0_SDRA_9_CLK; -	break; -    case 10: -	tr0 |= SDRAM_TR0_SDRA_10_CLK; -	break; -    case 11: -	tr0 |= SDRAM_TR0_SDRA_11_CLK; -	break; -    case 12: -	tr0 |= SDRAM_TR0_SDRA_12_CLK; -	break; -    default: -	tr0 |= SDRAM_TR0_SDRA_13_CLK; -	break; -    } +	/* +	 * Program SD_RFTA field +	 * FIXME tRFC hardcoded as 75 nanoseconds +	 */ +	t_rfc_clk = sys_info.freqPLB / (ONE_BILLION / 75); +	residue = sys_info.freqPLB % (ONE_BILLION / 75); +	if (residue >= (ONE_BILLION / 150)) { +		t_rfc_clk++; +	} +	switch (t_rfc_clk) { +	case 0: +	case 1: +	case 2: +	case 3: +	case 4: +	case 5: +	case 6: +		tr0 |= SDRAM_TR0_SDRA_6_CLK; +		break; +	case 7: +		tr0 |= SDRAM_TR0_SDRA_7_CLK; +		break; +	case 8: +		tr0 |= SDRAM_TR0_SDRA_8_CLK; +		break; +	case 9: +		tr0 |= SDRAM_TR0_SDRA_9_CLK; +		break; +	case 10: +		tr0 |= SDRAM_TR0_SDRA_10_CLK; +		break; +	case 11: +		tr0 |= SDRAM_TR0_SDRA_11_CLK; +		break; +	case 12: +		tr0 |= SDRAM_TR0_SDRA_12_CLK; +		break; +	default: +		tr0 |= SDRAM_TR0_SDRA_13_CLK; +		break; +	} -    /* -     * Program SD_RCD field -     */ -    t_rcd_clk = sys_info.freqPLB * t_rcd_ns / ONE_BILLION; -    plb_check = ONE_BILLION * t_rcd_clk / t_rcd_ns; -    if (sys_info.freqPLB != plb_check) { -	t_rcd_clk++; -    } -    switch (t_rcd_clk) { -    case 0: -    case 1: -    case 2: -	tr0 |= SDRAM_TR0_SDRD_2_CLK; -	break; -    case 3: -	tr0 |= SDRAM_TR0_SDRD_3_CLK; -	break; -    default: -	tr0 |= SDRAM_TR0_SDRD_4_CLK; -	break; -    } +	/* +	 * Program SD_RCD field +	 */ +	t_rcd_clk = sys_info.freqPLB * t_rcd_ns / ONE_BILLION; +	plb_check = ONE_BILLION * t_rcd_clk / t_rcd_ns; +	if (sys_info.freqPLB != plb_check) { +		t_rcd_clk++; +	} +	switch (t_rcd_clk) { +	case 0: +	case 1: +	case 2: +		tr0 |= SDRAM_TR0_SDRD_2_CLK; +		break; +	case 3: +		tr0 |= SDRAM_TR0_SDRD_3_CLK; +		break; +	default: +		tr0 |= SDRAM_TR0_SDRD_4_CLK; +		break; +	}  #if 0 -    printf("tr0: %x\n", tr0); +	printf("tr0: %x\n", tr0);  #endif -    mtsdram(mem_tr0, tr0); +	mtsdram(mem_tr0, tr0);  }  void program_tr1 (void)  { -    unsigned long tr0; -    unsigned long tr1; -    unsigned long cfg0; -    unsigned long ecc_temp; -    unsigned long dlycal; -    unsigned long dly_val; -    unsigned long i, j, k; -    unsigned long bxcr_num; -    unsigned long max_pass_length; -    unsigned long current_pass_length; -    unsigned long current_fail_length; -    unsigned long current_start; -    unsigned long rdclt; -    unsigned long rdclt_offset; -    long max_start; -    long max_end; -    long rdclt_average; -    unsigned char window_found; -    unsigned char fail_found; -    unsigned char pass_found; -    unsigned long * membase; -    PPC440_SYS_INFO sys_info; +	unsigned long tr0; +	unsigned long tr1; +	unsigned long cfg0; +	unsigned long ecc_temp; +	unsigned long dlycal; +	unsigned long dly_val; +	unsigned long i, j, k; +	unsigned long bxcr_num; +	unsigned long max_pass_length; +	unsigned long current_pass_length; +	unsigned long current_fail_length; +	unsigned long current_start; +	unsigned long rdclt; +	unsigned long rdclt_offset; +	long max_start; +	long max_end; +	long rdclt_average; +	unsigned char window_found; +	unsigned char fail_found; +	unsigned char pass_found; +	unsigned long * membase; +	PPC440_SYS_INFO sys_info; -    /* -     * get the board info -     */ -    get_sys_info(&sys_info); +	/* +	 * get the board info +	 */ +	get_sys_info(&sys_info); -    /* -     * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits -     */ -    mfsdram(mem_tr1, tr1); -    tr1 &= ~(SDRAM_TR1_RDSS_MASK | SDRAM_TR1_RDSL_MASK | -	     SDRAM_TR1_RDCD_MASK | SDRAM_TR1_RDCT_MASK); +	/* +	 * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits +	 */ +	mfsdram(mem_tr1, tr1); +	tr1 &= ~(SDRAM_TR1_RDSS_MASK | SDRAM_TR1_RDSL_MASK | +		 SDRAM_TR1_RDCD_MASK | SDRAM_TR1_RDCT_MASK); -    mfsdram(mem_tr0, tr0); -    if (((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) && -       (sys_info.freqPLB > 100000000)) { -	tr1 |= SDRAM_TR1_RDSS_TR2; -	tr1 |= SDRAM_TR1_RDSL_STAGE3; -	tr1 |= SDRAM_TR1_RDCD_RCD_1_2; -    } -    else { -	tr1 |= SDRAM_TR1_RDSS_TR1; -	tr1 |= SDRAM_TR1_RDSL_STAGE2; -	tr1 |= SDRAM_TR1_RDCD_RCD_0_0; -    } +	mfsdram(mem_tr0, tr0); +	if (((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) && +	    (sys_info.freqPLB > 100000000)) { +		tr1 |= SDRAM_TR1_RDSS_TR2; +		tr1 |= SDRAM_TR1_RDSL_STAGE3; +		tr1 |= SDRAM_TR1_RDCD_RCD_1_2; +	} else { +		tr1 |= SDRAM_TR1_RDSS_TR1; +		tr1 |= SDRAM_TR1_RDSL_STAGE2; +		tr1 |= SDRAM_TR1_RDCD_RCD_0_0; +	} -    /* -     * save CFG0 ECC setting to a temporary variable and turn ECC off -     */ -    mfsdram(mem_cfg0, cfg0); -    ecc_temp = cfg0 & SDRAM_CFG0_MCHK_MASK; -    mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_NON); +	/* +	 * save CFG0 ECC setting to a temporary variable and turn ECC off +	 */ +	mfsdram(mem_cfg0, cfg0); +	ecc_temp = cfg0 & SDRAM_CFG0_MCHK_MASK; +	mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_NON); -    /* -     * get the delay line calibration register value -     */ -    mfsdram(mem_dlycal, dlycal); -    dly_val = SDRAM_DLYCAL_DLCV_DECODE(dlycal) << 2; +	/* +	 * get the delay line calibration register value +	 */ +	mfsdram(mem_dlycal, dlycal); +	dly_val = SDRAM_DLYCAL_DLCV_DECODE(dlycal) << 2; -    max_pass_length = 0; -    max_start = 0; -    max_end = 0; -    current_pass_length = 0; -    current_fail_length = 0; -    current_start = 0; -    rdclt_offset = 0; -    window_found = FALSE; -    fail_found = FALSE; -    pass_found = FALSE; +	max_pass_length = 0; +	max_start = 0; +	max_end = 0; +	current_pass_length = 0; +	current_fail_length = 0; +	current_start = 0; +	rdclt_offset = 0; +	window_found = FALSE; +	fail_found = FALSE; +	pass_found = FALSE;  #ifdef DEBUG -    printf("Starting memory test "); +	printf("Starting memory test ");  #endif -    for (k = 0; k < NUMHALFCYCLES; k++) { -	for (rdclt = 0; rdclt < dly_val; rdclt++)  { -	    /* -	     * Set the timing reg for the test. -	     */ -	    mtsdram(mem_tr1, (tr1 | SDRAM_TR1_RDCT_ENCODE(rdclt))); +	for (k = 0; k < NUMHALFCYCLES; k++) { +		for (rdclt = 0; rdclt < dly_val; rdclt++)  { +			/* +			 * Set the timing reg for the test. +			 */ +			mtsdram(mem_tr1, (tr1 | SDRAM_TR1_RDCT_ENCODE(rdclt))); -	    for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) { -		mtdcr(memcfga, mem_b0cr + (bxcr_num<<2)); -		if ((mfdcr(memcfgd) & SDRAM_BXCR_SDBE) == SDRAM_BXCR_SDBE) { -		    /* Bank is enabled */ -		    membase = (unsigned long*) -			(mfdcr(memcfgd) & SDRAM_BXCR_SDBA_MASK); +			for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) { +				mtdcr(memcfga, mem_b0cr + (bxcr_num<<2)); +				if ((mfdcr(memcfgd) & SDRAM_BXCR_SDBE) == SDRAM_BXCR_SDBE) { +					/* Bank is enabled */ +					membase = (unsigned long*) +						(mfdcr(memcfgd) & SDRAM_BXCR_SDBA_MASK); -		    /* -		     * Run the short memory test -		     */ -		    for (i = 0; i < NUMMEMTESTS; i++) { -			for (j = 0; j < NUMMEMWORDS; j++) { -			    membase[j] = test[i][j]; -			    ppcDcbf((unsigned long)&(membase[j])); -			} +					/* +					 * Run the short memory test +					 */ +					for (i = 0; i < NUMMEMTESTS; i++) { +						for (j = 0; j < NUMMEMWORDS; j++) { +							membase[j] = test[i][j]; +							ppcDcbf((unsigned long)&(membase[j])); +						} -			for (j = 0; j < NUMMEMWORDS; j++) { -			    if (membase[j] != test[i][j]) { -				ppcDcbf((unsigned long)&(membase[j])); -				break; -			    } -			    ppcDcbf((unsigned long)&(membase[j])); -			} +						for (j = 0; j < NUMMEMWORDS; j++) { +							if (membase[j] != test[i][j]) { +								ppcDcbf((unsigned long)&(membase[j])); +								break; +							} +							ppcDcbf((unsigned long)&(membase[j])); +						} -			if (j < NUMMEMWORDS) { -			    break; -			} -		    } +						if (j < NUMMEMWORDS) { +							break; +						} +					} -		    /* -		     * see if the rdclt value passed -		     */ -		    if (i < NUMMEMTESTS) { -			break; -		    } -		} -	    } +					/* +					 * see if the rdclt value passed +					 */ +					if (i < NUMMEMTESTS) { +						break; +					} +				} +			} -	    if (bxcr_num == MAXBXCR) { -		if (fail_found == TRUE) { -		    pass_found = TRUE; -		    if (current_pass_length == 0) { -			current_start = rdclt_offset + rdclt; -		    } +			if (bxcr_num == MAXBXCR) { +				if (fail_found == TRUE) { +					pass_found = TRUE; +					if (current_pass_length == 0) { +						current_start = rdclt_offset + rdclt; +					} -		    current_fail_length = 0; -		    current_pass_length++; +					current_fail_length = 0; +					current_pass_length++; -		    if (current_pass_length > max_pass_length) { -			max_pass_length = current_pass_length; -			max_start = current_start; -			max_end = rdclt_offset + rdclt; -		    } -		} -	    } -	    else { -		current_pass_length = 0; -		current_fail_length++; +					if (current_pass_length > max_pass_length) { +						max_pass_length = current_pass_length; +						max_start = current_start; +						max_end = rdclt_offset + rdclt; +					} +				} +			} else { +				current_pass_length = 0; +				current_fail_length++; -		if (current_fail_length >= (dly_val>>2)) { -		    if (fail_found == FALSE) { -			fail_found = TRUE; -		    } -		    else if (pass_found == TRUE) { -			window_found = TRUE; -			break; -		    } +				if (current_fail_length >= (dly_val>>2)) { +					if (fail_found == FALSE) { +						fail_found = TRUE; +					} else if (pass_found == TRUE) { +						window_found = TRUE; +						break; +					} +				} +			}  		} -	    } -	}  #ifdef DEBUG -	printf("."); +		printf(".");  #endif -	if (window_found == TRUE) { -	    break; -	} +		if (window_found == TRUE) { +			break; +		} -	tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK; -	rdclt_offset += dly_val; -    } +		tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK; +		rdclt_offset += dly_val; +	}  #ifdef DEBUG -    printf("\n"); +	printf("\n");  #endif -    /* -     * make sure we find the window -     */ -    if (window_found == FALSE) { -       printf("ERROR: Cannot determine a common read delay.\n"); -       hang(); -    } +	/* +	 * make sure we find the window +	 */ +	if (window_found == FALSE) { +		printf("ERROR: Cannot determine a common read delay.\n"); +		hang(); +	} -    /* -     * restore the orignal ECC setting -     */ -    mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | ecc_temp); +	/* +	 * restore the orignal ECC setting +	 */ +	mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | ecc_temp); -    /* -     * set the SDRAM TR1 RDCD value -     */ -    tr1 &= ~SDRAM_TR1_RDCD_MASK; -    if ((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) { -	tr1 |= SDRAM_TR1_RDCD_RCD_1_2; -    } -    else { -	tr1 |= SDRAM_TR1_RDCD_RCD_0_0; -    } +	/* +	 * set the SDRAM TR1 RDCD value +	 */ +	tr1 &= ~SDRAM_TR1_RDCD_MASK; +	if ((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) { +		tr1 |= SDRAM_TR1_RDCD_RCD_1_2; +	} else { +		tr1 |= SDRAM_TR1_RDCD_RCD_0_0; +	} -    /* -     * set the SDRAM TR1 RDCLT value -     */ -    tr1 &= ~SDRAM_TR1_RDCT_MASK; -    while (max_end >= (dly_val<<1)) { -	max_end -= (dly_val<<1); -	max_start -= (dly_val<<1); -    } +	/* +	 * set the SDRAM TR1 RDCLT value +	 */ +	tr1 &= ~SDRAM_TR1_RDCT_MASK; +	while (max_end >= (dly_val << 1)) { +		max_end -= (dly_val << 1); +		max_start -= (dly_val << 1); +	} -    rdclt_average = ((max_start + max_end) >> 1); -    if (rdclt_average >= 0x60) -	while(1); +	rdclt_average = ((max_start + max_end) >> 1); +	if (rdclt_average >= 0x60) +		while (1) +			; -    if (rdclt_average < 0) { -	rdclt_average = 0; -    } +	if (rdclt_average < 0) { +		rdclt_average = 0; +	} -    if (rdclt_average >= dly_val) { -	rdclt_average -= dly_val; -	tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK; -    } -    tr1 |= SDRAM_TR1_RDCT_ENCODE(rdclt_average); +	if (rdclt_average >= dly_val) { +		rdclt_average -= dly_val; +		tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK; +	} +	tr1 |= SDRAM_TR1_RDCT_ENCODE(rdclt_average);  #if 0 -    printf("tr1: %x\n", tr1); +	printf("tr1: %x\n", tr1);  #endif -    /* -     * program SDRAM Timing Register 1 TR1 -     */ -    mtsdram(mem_tr1, tr1); +	/* +	 * program SDRAM Timing Register 1 TR1 +	 */ +	mtsdram(mem_tr1, tr1);  }  unsigned long program_bxcr(unsigned long* dimm_populated,  			   unsigned char* iic0_dimm_addr,  			   unsigned long  num_dimm_banks)  { -    unsigned long dimm_num; -    unsigned long bxcr_num; -    unsigned long bank_base_addr; -    unsigned long bank_size_bytes; -    unsigned long cr; -    unsigned long i; -    unsigned long temp; -    unsigned char num_row_addr; -    unsigned char num_col_addr; -    unsigned char num_banks; -    unsigned char bank_size_id; +	unsigned long dimm_num; +	unsigned long bxcr_num; +	unsigned long bank_base_addr; +	unsigned long bank_size_bytes; +	unsigned long cr; +	unsigned long i; +	unsigned long temp; +	unsigned char num_row_addr; +	unsigned char num_col_addr; +	unsigned char num_banks; +	unsigned char bank_size_id; -    /* -     * Set the BxCR regs.  First, wipe out the bank config registers. -     */ -    for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) { -	mtdcr(memcfga, mem_b0cr + (bxcr_num << 2)); -	mtdcr(memcfgd, 0x00000000); -    } +	/* +	 * Set the BxCR regs.  First, wipe out the bank config registers. +	 */ +	for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) { +		mtdcr(memcfga, mem_b0cr + (bxcr_num << 2)); +		mtdcr(memcfgd, 0x00000000); +	} -    /* -     * reset the bank_base address -     */ -    bank_base_addr = CFG_SDRAM_BASE; +	/* +	 * reset the bank_base address +	 */ +	bank_base_addr = CFG_SDRAM_BASE; -    for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { -	if (dimm_populated[dimm_num] == TRUE) { -	    num_row_addr = spd_read(iic0_dimm_addr[dimm_num], 3); -	    num_col_addr = spd_read(iic0_dimm_addr[dimm_num], 4); -	    num_banks    = spd_read(iic0_dimm_addr[dimm_num], 5); -	    bank_size_id = spd_read(iic0_dimm_addr[dimm_num], 31); +	for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { +		if (dimm_populated[dimm_num] == TRUE) { +			num_row_addr = spd_read(iic0_dimm_addr[dimm_num], 3); +			num_col_addr = spd_read(iic0_dimm_addr[dimm_num], 4); +			num_banks    = spd_read(iic0_dimm_addr[dimm_num], 5); +			bank_size_id = spd_read(iic0_dimm_addr[dimm_num], 31); -	    /* -	     * Set the SDRAM0_BxCR regs -	     */ -	    cr = 0; -	    bank_size_bytes = 4 * 1024 * 1024 * bank_size_id; -	    switch (bank_size_id) { -	    case 0x02: -		cr |= SDRAM_BXCR_SDSZ_8; -		break; -	    case 0x04: -		cr |= SDRAM_BXCR_SDSZ_16; -		break; -	    case 0x08: -		cr |= SDRAM_BXCR_SDSZ_32; -		break; -	    case 0x10: -		cr |= SDRAM_BXCR_SDSZ_64; -		break; -	    case 0x20: -		cr |= SDRAM_BXCR_SDSZ_128; -		break; -	    case 0x40: -		cr |= SDRAM_BXCR_SDSZ_256; -		break; -	    case 0x80: -		cr |= SDRAM_BXCR_SDSZ_512; -		break; -	    default: -		printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n", -		    dimm_num); -		printf("ERROR: Unsupported value for the banksize: %d.\n", -		   bank_size_id); -		printf("Replace the DIMM module with a supported DIMM.\n\n"); -		hang(); -	    } +			/* +			 * Set the SDRAM0_BxCR regs +			 */ +			cr = 0; +			bank_size_bytes = 4 * 1024 * 1024 * bank_size_id; +			switch (bank_size_id) { +			case 0x02: +				cr |= SDRAM_BXCR_SDSZ_8; +				break; +			case 0x04: +				cr |= SDRAM_BXCR_SDSZ_16; +				break; +			case 0x08: +				cr |= SDRAM_BXCR_SDSZ_32; +				break; +			case 0x10: +				cr |= SDRAM_BXCR_SDSZ_64; +				break; +			case 0x20: +				cr |= SDRAM_BXCR_SDSZ_128; +				break; +			case 0x40: +				cr |= SDRAM_BXCR_SDSZ_256; +				break; +			case 0x80: +				cr |= SDRAM_BXCR_SDSZ_512; +				break; +			default: +				printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n", +				       dimm_num); +				printf("ERROR: Unsupported value for the banksize: %d.\n", +				       bank_size_id); +				printf("Replace the DIMM module with a supported DIMM.\n\n"); +				hang(); +			} -	    switch (num_col_addr) { -	    case 0x08: -		cr |= SDRAM_BXCR_SDAM_1; -		break; -	    case 0x09: -		cr |= SDRAM_BXCR_SDAM_2; -		break; -	    case 0x0A: -		cr |= SDRAM_BXCR_SDAM_3; -		break; -	    case 0x0B: -		cr |= SDRAM_BXCR_SDAM_4; -		break; -	    default: -		printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n", -		   dimm_num); -		printf("ERROR: Unsupported value for number of " -		   "column addresses: %d.\n", num_col_addr); -		printf("Replace the DIMM module with a supported DIMM.\n\n"); -		hang(); -	    } +			switch (num_col_addr) { +			case 0x08: +				cr |= SDRAM_BXCR_SDAM_1; +				break; +			case 0x09: +				cr |= SDRAM_BXCR_SDAM_2; +				break; +			case 0x0A: +				cr |= SDRAM_BXCR_SDAM_3; +				break; +			case 0x0B: +				cr |= SDRAM_BXCR_SDAM_4; +				break; +			default: +				printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n", +				       dimm_num); +				printf("ERROR: Unsupported value for number of " +				       "column addresses: %d.\n", num_col_addr); +				printf("Replace the DIMM module with a supported DIMM.\n\n"); +				hang(); +			} -	    /* -	     * enable the bank -	     */ -	    cr |= SDRAM_BXCR_SDBE; +			/* +			 * enable the bank +			 */ +			cr |= SDRAM_BXCR_SDBE; -	    /*------------------------------------------------------------------ -	    | This next section is hardware dependent and must be programmed -	    | to match the hardware. -	    +-----------------------------------------------------------------*/ -	    if (dimm_num == 0) { -		for (i = 0; i < num_banks; i++) { -		    mtdcr(memcfga, mem_b0cr + (i << 2)); -		    temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK | -					      SDRAM_BXCR_SDSZ_MASK | -					      SDRAM_BXCR_SDAM_MASK | -					      SDRAM_BXCR_SDBE); -		    cr |= temp; -		    cr |= bank_base_addr & SDRAM_BXCR_SDBA_MASK; -		    mtdcr(memcfgd, cr); -		    bank_base_addr += bank_size_bytes; -		} -	    } -	    else { -		for (i = 0; i < num_banks; i++) { -		    mtdcr(memcfga, mem_b2cr + (i << 2)); -		    temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK | -					      SDRAM_BXCR_SDSZ_MASK | -					      SDRAM_BXCR_SDAM_MASK | -					      SDRAM_BXCR_SDBE); -		    cr |= temp; -		    cr |= bank_base_addr & SDRAM_BXCR_SDBA_MASK; -		    mtdcr(memcfgd, cr); -		    bank_base_addr += bank_size_bytes; +			/*------------------------------------------------------------------ +			  | This next section is hardware dependent and must be programmed +			  | to match the hardware. +			  +-----------------------------------------------------------------*/ +			if (dimm_num == 0) { +				for (i = 0; i < num_banks; i++) { +					mtdcr(memcfga, mem_b0cr + (i << 2)); +					temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK | +								  SDRAM_BXCR_SDSZ_MASK | +								  SDRAM_BXCR_SDAM_MASK | +								  SDRAM_BXCR_SDBE); +					cr |= temp; +					cr |= bank_base_addr & SDRAM_BXCR_SDBA_MASK; +					mtdcr(memcfgd, cr); +					bank_base_addr += bank_size_bytes; +				} +			} else { +				for (i = 0; i < num_banks; i++) { +					mtdcr(memcfga, mem_b2cr + (i << 2)); +					temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK | +								  SDRAM_BXCR_SDSZ_MASK | +								  SDRAM_BXCR_SDAM_MASK | +								  SDRAM_BXCR_SDBE); +					cr |= temp; +					cr |= bank_base_addr & SDRAM_BXCR_SDBA_MASK; +					mtdcr(memcfgd, cr); +					bank_base_addr += bank_size_bytes; +				} +			}  		} -	    }  	} -    } -    return(bank_base_addr); +	return(bank_base_addr);  }  void program_ecc (unsigned long  num_bytes)  { -    unsigned long bank_base_addr; -    unsigned long current_address; -    unsigned long end_address; -    unsigned long address_increment; -    unsigned long cfg0; +	unsigned long bank_base_addr; +	unsigned long current_address; +	unsigned long end_address; +	unsigned long address_increment; +	unsigned long cfg0; -    /* -     * get Memory Controller Options 0 data -     */ -    mfsdram(mem_cfg0, cfg0); +	/* +	 * get Memory Controller Options 0 data +	 */ +	mfsdram(mem_cfg0, cfg0); -    /* -     * reset the bank_base address -     */ -    bank_base_addr = CFG_SDRAM_BASE; +	/* +	 * reset the bank_base address +	 */ +	bank_base_addr = CFG_SDRAM_BASE; -    if ((cfg0 & SDRAM_CFG0_MCHK_MASK) != SDRAM_CFG0_MCHK_NON) { -	mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | -	    SDRAM_CFG0_MCHK_GEN); +	if ((cfg0 & SDRAM_CFG0_MCHK_MASK) != SDRAM_CFG0_MCHK_NON) { +		mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | +			SDRAM_CFG0_MCHK_GEN); -	if ((cfg0 & SDRAM_CFG0_DMWD_MASK) == SDRAM_CFG0_DMWD_32) { -	    address_increment = 4; -	} -	else { -	    address_increment = 8; -	} +		if ((cfg0 & SDRAM_CFG0_DMWD_MASK) == SDRAM_CFG0_DMWD_32) { +			address_increment = 4; +		} else { +			address_increment = 8; +		} -	current_address = (unsigned long)(bank_base_addr); -	end_address = (unsigned long)(bank_base_addr) + num_bytes; +		current_address = (unsigned long)(bank_base_addr); +		end_address = (unsigned long)(bank_base_addr) + num_bytes; -	while (current_address < end_address) { -	    *((unsigned long*)current_address) = 0x00000000; -	    current_address += address_increment; -	} +		while (current_address < end_address) { +			*((unsigned long*)current_address) = 0x00000000; +			current_address += address_increment; +		} -	mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | -	    SDRAM_CFG0_MCHK_CHK); -    } +		mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | +			SDRAM_CFG0_MCHK_CHK); +	}  }  #endif /* CONFIG_440 */ diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c index 0d6d88a2a..7a4af75ef 100644 --- a/cpu/ppc4xx/speed.c +++ b/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; diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index 3473baafc..3a8ff2b02 100644 --- a/cpu/ppc4xx/start.S +++ b/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 @@ -408,6 +423,7 @@ __440gx_msr_continue:  	ori	r1,r1,0x0380		/* 8k rw */  	mtdcr	isram0_sb0cr,r1  #endif +#endif  	/*----------------------------------------------------------------*/  	/* Setup the stack in internal SRAM */ @@ -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     /* */ diff --git a/cpu/ppc4xx/usb_ohci.c b/cpu/ppc4xx/usb_ohci.c new file mode 100644 index 000000000..6176709f2 --- /dev/null +++ b/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(®s->revision) & 0xff; +	if (temp != 0x10) +		dbg("spec %d.%d", (temp >> 4), (temp & 0x0f)); + +	temp = readl(®s->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(®s->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(®s->intrstatus)); +	ohci_dump_intr_mask("intrenable", readl(®s->intrenable)); + +	maybe_print_eds("ed_periodcurrent", readl(®s->ed_periodcurrent)); + +	maybe_print_eds("ed_controlhead", readl(®s->ed_controlhead)); +	maybe_print_eds("ed_controlcurrent", readl(®s->ed_controlcurrent)); + +	maybe_print_eds("ed_bulkhead", readl(®s->ed_bulkhead)); +	maybe_print_eds("ed_bulkcurrent", readl(®s->ed_bulkcurrent)); + +	maybe_print_eds("donehead", readl(®s->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(®s->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, ®s->intrdisable); +		stat = dl_done_list(&gohci, dl_reverse_done_list(&gohci)); +		writel(OHCI_INTR_WDH, ®s->intrenable); +	} + +	if (ints & OHCI_INTR_SO) { +		dbg("USB Schedule overrun\n"); +		writel(OHCI_INTR_SO, ®s->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, ®s->intrdisable); +		if (ohci->ed_rm_list[frame] != NULL) +			writel(OHCI_INTR_SF, ®s->intrenable); +		stat = 0xff; +	} + +	writel(ints, ®s->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 */ diff --git a/cpu/ppc4xx/usb_ohci.h b/cpu/ppc4xx/usb_ohci.h new file mode 100644 index 000000000..706e05ea2 --- /dev/null +++ b/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; +} diff --git a/cpu/ppc4xx/usbdev.c b/cpu/ppc4xx/usbdev.c new file mode 100644 index 000000000..f0901ac51 --- /dev/null +++ b/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 */ diff --git a/cpu/ppc4xx/usbdev.h b/cpu/ppc4xx/usbdev.h new file mode 100644 index 000000000..3446d9893 --- /dev/null +++ b/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); diff --git a/cpu/ppc4xx/vecnum.h b/cpu/ppc4xx/vecnum.h index d493a5dd8..1038975a2 100644 --- a/cpu/ppc4xx/vecnum.h +++ b/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            */ diff --git a/drivers/pci_indirect.c b/drivers/pci_indirect.c index 584a4fc84..4923209d6 100644 --- a/drivers/pci_indirect.c +++ b/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, 		 \ diff --git a/include/405gp_enet.h b/include/405gp_enet.h index 88ac4add9..233ea1113 100644 --- a/include/405gp_enet.h +++ b/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 diff --git a/include/440_i2c.h b/include/440_i2c.h index b0ac592fa..01a5bacaa 100644 --- a/include/440_i2c.h +++ b/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) diff --git a/include/440gx_enet.h b/include/440gx_enet.h index 8caf9691e..022c5d871 100644 --- a/include/440gx_enet.h +++ b/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) diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index 71fadbc91..806085ed6 100644 --- a/include/asm-ppc/processor.h +++ b/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 diff --git a/include/asm-ppc/u-boot.h b/include/asm-ppc/u-boot.h index f8282d40c..a7593156b 100644 --- a/include/asm-ppc/u-boot.h +++ b/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 */ diff --git a/include/configs/yellowstone.h b/include/configs/yellowstone.h new file mode 100644 index 000000000..90418e0b7 --- /dev/null +++ b/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 */ diff --git a/include/configs/yosemite.h b/include/configs/yosemite.h new file mode 100644 index 000000000..5f8830641 --- /dev/null +++ b/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 */ diff --git a/include/pci.h b/include/pci.h index 458be233e..8f1999755 100644 --- a/include/pci.h +++ b/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 */ diff --git a/include/ppc440.h b/include/ppc440.h index acd4572a8..3e9034f35 100644 --- a/include/ppc440.h +++ b/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 */ diff --git a/include/usb_defs.h b/include/usb_defs.h index 353019fc1..33d1e46f2 100644 --- a/include/usb_defs.h +++ b/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 */ diff --git a/lib_ppc/board.c b/lib_ppc/board.c index e46b8a9e6..5951d560d 100644 --- a/lib_ppc/board.c +++ b/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) |