diff options
| author | wdenk <wdenk> | 2003-03-31 17:27:09 +0000 | 
|---|---|---|
| committer | wdenk <wdenk> | 2003-03-31 17:27:09 +0000 | 
| commit | 0db5bca8076998a7516102988ac976a2da28d531 (patch) | |
| tree | a722fe95ad378dea8b2ec9777744dc0a4a8d72a3 | |
| parent | 85ec0bcc1bc40a67368461fee0435d79305168b1 (diff) | |
| download | olio-uboot-2014.01-0db5bca8076998a7516102988ac976a2da28d531.tar.xz olio-uboot-2014.01-0db5bca8076998a7516102988ac976a2da28d531.zip | |
* Patch by Martin Winistoerfer, 23 Mar 2003
  - Add port to MPC555/556 microcontrollers
  - Add support for cmi customer board with
    Intel 28F128J3A, 28F320J3A or 28F640J3A flash.
* Patch by Rick Bronson, 28 Mar 2003:
  - fix common/cmd_nand.c
38 files changed, 3971 insertions, 146 deletions
| @@ -2,6 +2,14 @@  Changes since U-Boot 0.2.2:  ====================================================================== +* Patch by Martin Winistoerfer, 23 Mar 2003 +  - Add port to MPC555/556 microcontrollers +  - Add support for cmi customer board with +    Intel 28F128J3A, 28F320J3A or 28F640J3A flash. + +* Patch by Rick Bronson, 28 Mar 2003: +  - fix common/cmd_nand.c +  * Patch by Arun Dharankar, 24 Mar 2003:    - add threads / scheduler example code @@ -266,6 +266,10 @@ N: David Updegraff  E: dave@cray.com  D: Port to Cray L1 board; DHCP vendor extensions +N: Martin Winistoerfer +E: martinwinistoerfer@gmx.ch +D: Port to MPC555/556 microcontrollers and support for cmi board +  N: Christian Vejlbo  E: christian.vejlbo@tellabs.com  D: FADS860T ethernet support @@ -11,6 +11,14 @@ fi  LIST=""  ######################################################################### +## MPC5xx Systems +######################################################################### + +LIST_5xx="	\ +	cmi_mpc5xx							\ +" + +#########################################################################  ## MPC8xx Systems  ######################################################################### @@ -77,8 +85,10 @@ LIST_7xx="	\  	BAB7xx		ELPPC						\  " -LIST_ppc="${LIST_8xx} ${LIST_824x} ${LIST_8260} \ -	  ${LIST_4xx} ${LIST_74xx} ${LIST_7xx}" +LIST_ppc="${LIST_5xx}  ${LIST_8xx}  \ +	  ${LIST_824x} ${LIST_8260} \ +	  ${LIST_4xx}		    \ +	  ${LIST_74xx} ${LIST_7xx}"  #########################################################################  ## StrongARM Systems @@ -136,7 +146,7 @@ build_target() {  for arg in $@  do  	case "$arg" in -	8xx|824x|8260|4xx|7xx|74xx|SA|ARM7|ARM9|ppc|arm|xscale|mips) +	5xx|8xx|824x|8260|4xx|7xx|74xx|SA|ARM7|ARM9|ppc|arm|xscale|mips)  			for target in `eval echo '$LIST_'${arg}`  			do  				build_target ${target} @@ -168,6 +168,14 @@ unconfig:  #========================================================================  # PowerPC  #======================================================================== + +######################################################################### +## MPC5xx Systems +######################################################################### + +cmi_mpc5xx_config:	unconfig +	@./mkconfig $(@:_config=) ppc mpc5xx cmi +  #########################################################################  ## MPC8xx Systems  ######################################################################### @@ -621,6 +629,7 @@ BAB7xx_config: unconfig  ELPPC_config: unconfig  	@./mkconfig $(@:_config=) ppc 74xx_7xx elppc eltec +  #========================================================================  # ARM  #======================================================================== @@ -140,6 +140,7 @@ Directory Hierarchy:  - tools		Tools to build S-Record or U-Boot images, etc.  - cpu/74xx_7xx	Files specific to Motorola MPC74xx and 7xx CPUs +- cpu/mpc5xx	Files specific to Motorola MPC5xx  CPUs  - cpu/mpc8xx	Files specific to Motorola MPC8xx  CPUs  - cpu/mpc824x	Files specific to Motorola MPC824x CPUs  - cpu/mpc8260	Files specific to Motorola MPC8260 CPU @@ -151,6 +152,7 @@ Directory Hierarchy:  		Files specific to RPXClassic boards  - board/RPXlite	Files specific to RPXlite    boards  - board/c2mon	Files specific to c2mon	     boards +- board/cmi	Files specific to cmi        boards  - board/cogent	Files specific to Cogent     boards  		(need further configuration)  		Files specific to CPCIISER4  boards @@ -292,6 +294,7 @@ The following options need to be configured:  		PowerPC based CPUs:  		-------------------  		CONFIG_MPC823,	CONFIG_MPC850,	CONFIG_MPC855,	CONFIG_MPC860 +	or	CONFIG_MPC5xx  	or	CONFIG_MPC824X, CONFIG_MPC8260  	or	CONFIG_IOP480  	or	CONFIG_405GP @@ -340,7 +343,7 @@ The following options need to be configured:  		CONFIG_GTH,        CONFIG_RPXClassic, CONFIG_rsdproto,  		CONFIG_IAD210,     CONFIG_RPXlite,    CONFIG_sbc8260,  		CONFIG_EBONY,      CONFIG_sacsng,     CONFIG_FPS860L, -		CONFIG_V37,        CONFIG_ELPT860 +		CONFIG_V37,        CONFIG_ELPT860,    CONFIG_CMI  		ARM based boards:  		----------------- @@ -1716,7 +1719,7 @@ configurations; the following names are supported:      FPS850L_config	  Sandpoint8240_config	sbc8260_config      GENIETV_config	  TQM823L_config	PIP405_config      GEN860T_config	  EBONY_config		FPS860L_config -    ELPT860_config +    ELPT860_config	  cmi_mpc5xx_config  Note: for some board special configuration names may exist; check  if        additional  information is available from the board vendor; for diff --git a/board/cmi/Makefile b/board/cmi/Makefile new file mode 100644 index 000000000..0a92da874 --- /dev/null +++ b/board/cmi/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2001	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	:= flash.o cmi.o +SOBJS	:= + +$(LIB):	$(OBJS) +	$(AR) crv $@ $^ + +clean: +	rm -f $(SOBJS) $(OBJS) + +distclean:	clean +	rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) +		$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff --git a/board/cmi/cmi.c b/board/cmi/cmi.c new file mode 100644 index 000000000..cbf34f785 --- /dev/null +++ b/board/cmi/cmi.c @@ -0,0 +1,73 @@ +/* + * (C) Copyright 2003 + * Martin Winistoerfer, martinwinistoerfer@gmx.ch. + * + * 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 + */ + +/* + * File:		cmi.c + * + * Discription:		For generic board specific functions + * + */ + + +#include <common.h> +#include <mpc5xx.h> + +#define SRAM_SIZE	1024000L	/* 1M RAM available*/ + +#if defined(__APPLE__) +/* Leading underscore on symbols */ +#  define SYM_CHAR "_" +#else /* No leading character on symbols */ +#  define SYM_CHAR +#endif + +/* + * Macros to generate global absolutes. + */ +#define GEN_SYMNAME(str) SYM_CHAR #str +#define GEN_VALUE(str) #str +#define GEN_ABS(name, value) \ +		asm (".globl " GEN_SYMNAME(name)); \ +		asm (GEN_SYMNAME(name) " = " GEN_VALUE(value)) + +/* + * Check the board + */ +int checkboard(void) +{ +    puts ("Board: ### No HW ID - assuming CMI board\n"); +    return (0); +} + +/* + * Get RAM size. + */ +long int initdram(int board_type) +{ +	return (SRAM_SIZE);		/* We currently have a static size adapted for cmi board. */ +} + +/* + * Absolute environment address for linker file. + */ +GEN_ABS(env_start, CFG_ENV_OFFSET + CFG_FLASH_BASE); diff --git a/board/cmi/config.mk b/board/cmi/config.mk new file mode 100644 index 000000000..564f638a3 --- /dev/null +++ b/board/cmi/config.mk @@ -0,0 +1,31 @@ +# +# (C) Copyright 2003 +# Martin Winistoerfer, martinwinistoerfer@gmx.ch. +# +# 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 +# + +# +# EPQ Board Configuration +# + +# Boot from flash at location 0x00000000 +TEXT_BASE = 0x02000000 + +PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR) diff --git a/board/cmi/flash.c b/board/cmi/flash.c new file mode 100644 index 000000000..b41ff1252 --- /dev/null +++ b/board/cmi/flash.c @@ -0,0 +1,517 @@ +/* + * (C) Copyright 2003 + * Martin Winistoerfer, martinwinistoerfer@gmx.ch. + * + * 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 + */ + +/* + * File:		flash.c + * + * Discription:		This Driver is for 28F320J3A, 28F640J3A and + * 			28F128J3A Intel flashs working in 16 Bit mode. + *			They are single bank flashs. + * + *			Most of this code is taken from existing u-boot + *			source code. + */ + + +#include <common.h> +#include <mpc5xx.h> + +#if defined(CFG_ENV_IS_IN_FLASH) +# ifndef  CFG_ENV_ADDR +#  define CFG_ENV_ADDR	(CFG_FLASH_BASE + CFG_ENV_OFFSET) +# endif +# ifndef  CFG_ENV_SIZE +#  define CFG_ENV_SIZE	CFG_ENV_SECT_SIZE +# endif +# ifndef  CFG_ENV_SECT_SIZE +#  define CFG_ENV_SECT_SIZE  CFG_ENV_SIZE +# endif +#endif + +#define	FLASH_ID_MASK			0xFFFF +#define FLASH_BLOCK_SIZE		0x00010000 +#define FLASH_CMD_READ_ID		0x0090 +#define FLASH_CMD_RESET			0x00ff +#define FLASH_CMD_BLOCK_ERASE		0x0020 +#define FLASH_CMD_ERASE_CONFIRM		0x00D0 +#define FLASH_CMD_CLEAR_STATUS		0x0050 +#define FLASH_CMD_SUSPEND_ERASE		0x00B0 +#define FLASH_CMD_WRITE			0x0040 +#define FLASH_CMD_PROTECT		0x0060 +#define FLASH_CMD_PROTECT_SET		0x0001 +#define FLASH_CMD_PROTECT_CLEAR		0x00D0 +#define FLASH_STATUS_DONE		0x0080 + +flash_info_t	flash_info[CFG_MAX_FLASH_BANKS]; + +/* + * Local function prototypes + */ +static ulong 	flash_get_size 		(vu_short *addr, flash_info_t *info); +static int 	write_short 		(flash_info_t *info, ulong dest, ushort data); +static void 	flash_get_offsets 	(ulong base, flash_info_t *info); + +/* + * Initialize flash + */ + +unsigned long flash_init (void) +{ +	unsigned long size_b0; +	int i; + +	/* Init: no FLASHes known */ +	for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { +		flash_info[i].flash_id = FLASH_UNKNOWN; +	} + +	/* Static FLASH Bank configuration here - FIXME XXX */ +#if 1 +	debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_PRELIM); +#endif +	size_b0 = flash_get_size((vu_short *)FLASH_BASE0_PRELIM, &flash_info[0]); + +	if (flash_info[0].flash_id == FLASH_UNKNOWN) { +		printf ("## Unknown FLASH on Bank 0: " +			"ID 0x%lx, Size = 0x%08lx = %ld MB\n", +			flash_info[0].flash_id, +			size_b0, size_b0<<20); +	} + +	flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]); + +	flash_info[0].size = size_b0; + +#if CFG_MONITOR_BASE >= CFG_FLASH_BASE +	/* monitor protection ON by default */ +	flash_protect(FLAG_PROTECT_SET, +		      CFG_MONITOR_BASE, +		      CFG_MONITOR_BASE+CFG_MONITOR_LEN-1, +		      &flash_info[0]); +#endif + +#ifdef	CFG_ENV_IS_IN_FLASH +	/* ENV protection ON by default */ +	flash_protect(FLAG_PROTECT_SET, +		      CFG_ENV_ADDR, +		      CFG_ENV_ADDR+CFG_ENV_SECT_SIZE-1, +		      &flash_info[0]); +#endif + +	return size_b0; +} + +/* + * Compute start adress of each sector (block) + */ + +static void flash_get_offsets (ulong base, flash_info_t *info) +{ +	int i; + +	if (info->flash_id == FLASH_UNKNOWN) { +		return; +	} + +	switch (info->flash_id & FLASH_VENDMASK) { +	case FLASH_MAN_INTEL: +	    for (i = 0; i < info->sector_count; i++) { +		info->start[i] = base + i * FLASH_BLOCK_SIZE; +	    } +	    return; + +	default: +	    printf ("Don't know sector offsets for flash type 0x%lx\n", +		info->flash_id); +	    return; +	} +} + +/* + * Print flash information + */ +void flash_print_info  (flash_info_t *info) +{ +	int i; + +	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; +	case FLASH_MAN_STM:	printf ("STM ");		break; +	case FLASH_MAN_INTEL:	printf ("Intel ");		break; +	case FLASH_MAN_MT:	printf ("MT ");			break; +	default:		printf ("Unknown Vendor ");	break; +	} + +	switch (info->flash_id & FLASH_TYPEMASK) { +	case FLASH_28F320J3A:	printf ("28F320J3A (32Mbit) 16-Bit\n"); +				break; +	case FLASH_28F640J3A:	printf ("28F640J3A (64Mbit) 16-Bit\n"); +				break; +	case FLASH_28F128J3A:	printf ("28F128J3A (128Mbit) 16-Bit\n"); +				break; +	default:		printf ("Unknown Chip Type\n"); +				break; +	} + +	if (info->size >= (1 << 20)) { +		i = 20; +	} else { +		i = 10; +	} +	printf ("  Size: %ld %cB in %d Sectors\n", +		info->size >> i, +		(i == 20) ? 'M' : 'k', +		info->sector_count); + +	printf ("  Sector Start Addresses:"); +	for (i=0; i<info->sector_count; ++i) { +		if ((i % 5) == 0) +			printf ("\n   "); +		printf (" %08lX%s", +			info->start[i], +			info->protect[i] ? " (RO)" : "     " +		); +	} +	printf ("\n"); +	return; +} + +/* + * Get size of flash in bytes. + * The following code cannot be run from FLASH! + */ + +static ulong flash_get_size (vu_short *addr, flash_info_t *info) +{ +	vu_short value; + +	/* Read Manufacturer ID */ +	addr[0] = FLASH_CMD_READ_ID; +	value = addr[0]; + +	switch (value) { +	case (AMD_MANUFACT & FLASH_ID_MASK): +		info->flash_id = FLASH_MAN_AMD; +		break; +	case (FUJ_MANUFACT & FLASH_ID_MASK): +		info->flash_id = FLASH_MAN_FUJ; +		break; +	case (SST_MANUFACT & FLASH_ID_MASK): +		info->flash_id = FLASH_MAN_SST; +		break; +	case (STM_MANUFACT & FLASH_ID_MASK): +		info->flash_id = FLASH_MAN_STM; +		break; +	case (INTEL_MANUFACT & FLASH_ID_MASK): +		info->flash_id = FLASH_MAN_INTEL; +		break; +	default: +		info->flash_id = FLASH_UNKNOWN; +		info->sector_count = 0; +		info->size = 0; +		addr[0] = FLASH_CMD_RESET;	/* restore read mode */ +		return (0);			/* no or unknown flash	*/ +	} + +	value = addr[1];			/* device ID		*/ + +	switch (value) { +	case (INTEL_ID_28F320J3A  & FLASH_ID_MASK): +		info->flash_id += FLASH_28F320J3A; +		info->sector_count = 32; +		info->size = 0x00400000; +		break;				/* =>  32 MBit		*/ + +	case (INTEL_ID_28F640J3A & FLASH_ID_MASK): +		info->flash_id += FLASH_28F640J3A; +		info->sector_count = 64; +		info->size = 0x00800000; +		break;				/* => 64 MBit		*/ + +	case (INTEL_ID_28F128J3A & FLASH_ID_MASK): +		info->flash_id += FLASH_28F128J3A; +		info->sector_count = 128; +		info->size = 0x01000000; +		break;				/* => 128 MBit		*/ + +	default: +		info->flash_id = FLASH_UNKNOWN; +		addr[0] = FLASH_CMD_RESET;	/* restore read mode */ +		return (0);			/* => no or unknown flash */ + +	} + +	if (info->sector_count > CFG_MAX_FLASH_SECT) { +		printf ("** ERROR: sector count %d > max (%d) **\n", +			info->sector_count, CFG_MAX_FLASH_SECT); +		info->sector_count = CFG_MAX_FLASH_SECT; +	} + +	addr[0] = FLASH_CMD_RESET;		/* restore read mode */ + +	return (info->size); +} + + +/* + * Erase unprotected sectors + */ + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ +	int flag, prot, sect; +	ulong start, now, last; + +	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_VENDMASK) != FLASH_MAN_INTEL) { +		printf ("Can erase only Intel flash types - 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"); +	} + +	start = get_timer (0); +	last  = start; + +	/* Start erase on unprotected sectors */ +	for (sect = s_first; sect<=s_last; sect++) { +		if (info->protect[sect] == 0) {	/* not protected */ +			vu_short *addr = (vu_short *)(info->start[sect]); +			unsigned long status; + +			/* Disable interrupts which might cause a timeout here */ +			flag = disable_interrupts(); + +#ifdef DEBUG +			printf("Erase sector %d at start addr 0x%08X", sect, (unsigned int)info->start[sect]); +#endif + +			*addr = FLASH_CMD_CLEAR_STATUS; +			*addr = FLASH_CMD_BLOCK_ERASE; +			*addr = FLASH_CMD_ERASE_CONFIRM; + +			/* re-enable interrupts if necessary */ +			if (flag) +				enable_interrupts(); + +			/* wait at least 80us - let's wait 1 ms */ +			udelay (1000); + +			while (((status = *addr) & FLASH_STATUS_DONE) != FLASH_STATUS_DONE) { +				if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) { +					printf("Flash erase timeout at address %lx\n", info->start[sect]); +					*addr = FLASH_CMD_SUSPEND_ERASE; +					*addr = FLASH_CMD_RESET; +					return 1; +				} + +				/* show that we're waiting */ +				if ((now - last) > 1000) {	/* every second */ +					putc ('.'); +					last = now; +				} +			} +			*addr = FLASH_CMD_RESET; +		} +	} +	printf (" done\n"); +	return 0; +} + +/* + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 4 - Flash not identified + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ +	ulong cp, wp; +	ushort data; +	int i, rc; + +	if (info->flash_id == FLASH_UNKNOWN) { +		return 4; +	} + +	wp = (addr & ~1);	/* get lower word aligned address */ + +	/* +	 * handle unaligned start byte +	 */ + +	if (addr - wp) { +		data = 0; +		data = (data << 8) | *src++; +		--cnt; +		if ((rc = write_short(info, wp, data)) != 0) { +			return (rc); +		} +		wp += 2; +	} + +	/* +	 * handle word aligned part +	 */ + +	while (cnt >= 2) { +		data = 0; +		for (i=0; i<2; ++i) { +			data = (data << 8) | *src++; +		} + +		if ((rc = write_short(info, wp, data)) != 0) { +			return (rc); +		} +		wp  += 2; +		cnt -= 2; +	} + +	if (cnt == 0) { +		return (0); +	} + +	/* +	 * handle unaligned tail bytes +	 */ + +	data = 0; +	for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) { +		data = (data << 8) | *src++; +		--cnt; +	} +	for (; i<2; ++i, ++cp) { +		data = (data << 8) | (*(uchar *)cp); +	} + +	return (write_short(info, wp, data)); + +} + +/* + * Write 16 bit (short) to flash + */ + +static int write_short (flash_info_t *info, ulong dest, ushort data) +{ +	vu_short *addr = (vu_short*)(info->start[0]); +	ulong start; +	int flag; + +	/* Check if Flash is (sufficiently) erased */ +	if ((*((vu_short *)dest) & data) != data) { +		return (2); +	} + +	/* Disable interrupts which might cause a timeout here */ +	flag = disable_interrupts(); + +	if (!(info->flash_id & FLASH_VENDMASK)) { +		return 4; +	} +        *addr = FLASH_CMD_ERASE_CONFIRM; +	*addr = FLASH_CMD_WRITE; + +	*((vu_short *)dest) = data; + +	/* re-enable interrupts if necessary */ +	if (flag) { +		enable_interrupts(); +	} + +	/* data polling for D7 */ +	start = get_timer (0); + +	/* wait for error or finish */ +	while(!(addr[0] & FLASH_STATUS_DONE)){ +		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { +		  	addr[0] = FLASH_CMD_RESET; +			return (1); +		} +	} + +	*addr = FLASH_CMD_RESET; +	return (0); +} + +/* + * Protects a flash sector + */ + +int flash_real_protect(flash_info_t *info, long sector, int prot) +{ +	vu_short *addr = (vu_short*)(info->start[sector]); +	ulong start; + +	*addr = FLASH_CMD_CLEAR_STATUS; +	*addr = FLASH_CMD_PROTECT; + +	if(prot) { +		*addr = FLASH_CMD_PROTECT_SET; +	} else { +		*addr = FLASH_CMD_PROTECT_CLEAR; +	} + +	/* wait for error or finish */ +	start = get_timer (0); +	while(!(addr[0] & FLASH_STATUS_DONE)){ +		if (get_timer(start) > CFG_FLASH_ERASE_TOUT) { +		  	printf("Flash protect timeout at address %lx\n",  info->start[sector]); +			addr[0] = FLASH_CMD_RESET; +			return (1); +		} +	} +	/* Set software protect flag */ +	info->protect[sector] = prot; +	*addr = FLASH_CMD_RESET; +	return (0); +} diff --git a/board/cmi/u-boot.lds b/board/cmi/u-boot.lds new file mode 100644 index 000000000..986517131 --- /dev/null +++ b/board/cmi/u-boot.lds @@ -0,0 +1,131 @@ +/* + * (C) Copyright 2001	Wolfgang Denk, DENX Software Engineering, wd@denx.de + * (C) Copyright 2003	Martin Winistoerfer, martinwinistoerfer@gmx.ch + * + * 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 +{ +  /* 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/mpc5xx/start.o	(.text) + +    *(.text) +    *(.fixup) +    *(.got1) +  } +  _etext = .; +  PROVIDE (etext = .); +  .rodata    : +  { +    *(.rodata) +    *(.rodata1) +  } +  .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 = .); + +  __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 = .); +    . = env_start; +	.ppcenv	: +	{ +		common/environment.o (.ppcenv) +	} + +} diff --git a/common/cmd_boot.c b/common/cmd_boot.c index 59bab35df..09f3f78f4 100644 --- a/common/cmd_boot.c +++ b/common/cmd_boot.c @@ -71,7 +71,7 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  	print_num ("flashoffset",   bd->bi_flashoffset	);  	print_num ("sramstart",	    bd->bi_sramstart	);  	print_num ("sramsize",	    bd->bi_sramsize	); -#if defined(CONFIG_8xx) || defined(CONFIG_8260) +#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260)  	print_num ("immr_base",	    bd->bi_immr_base	);  #endif  	print_num ("bootflags",	    bd->bi_bootflags	); diff --git a/common/cmd_nand.c b/common/cmd_nand.c index a041b29c2..edb717d8a 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -302,7 +302,7 @@ static int nand_rw (struct nand_chip* nand, int cmd,  }  static void nand_print(struct nand_chip *nand) - { +{  	printf("%s at 0x%lX,\n"  	       "\t  %d chip%s %s, size %d MB, \n"  	       "\t  total size %ld MB, sector size %ld kB\n", @@ -333,16 +333,17 @@ static void nand_print(struct nand_chip *nand)  /* ------------------------------------------------------------------------- */  /* This function is needed to avoid calls of the __ashrdi3 function. */ +#if 0  static int shr(int val, int shift) - { +{  	return val >> shift;  } - +#endif  static int NanD_WaitReady(struct nand_chip *nand)  {  	/* This is inline, to optimise the common case, where it's ready instantly */  	int ret = 0; -        NAND_WAIT_READY(nand); +	NAND_WAIT_READY(nand);  	return ret;  } @@ -368,42 +369,42 @@ static inline int NanD_Command(struct nand_chip *nand, unsigned char command)  /* NanD_Address: Set the current address for the flash chip */  static int NanD_Address(struct nand_chip *nand, int numbytes, unsigned long ofs) -  { -  unsigned long nandptr; -  int i; +{ +	unsigned long nandptr; +	int i; -  nandptr = nand->IO_ADDR; +	nandptr = nand->IO_ADDR;  	/* Assert the ALE (Address Latch Enable) line to the flash chip */ -  NAND_CTL_SETALE(nandptr); +	NAND_CTL_SETALE(nandptr); -  /* Send the address */ -  /* Devices with 256-byte page are addressed as: -     Column (bits 0-7), Page (bits 8-15, 16-23, 24-31) -     * there is no device on the market with page256 -     and more than 24 bits. -     Devices with 512-byte page are addressed as: -     Column (bits 0-7), Page (bits 9-16, 17-24, 25-31) -     * 25-31 is sent only if the chip support it. -     * bit 8 changes the read command to be sent -     (NAND_CMD_READ0 or NAND_CMD_READ1). +	/* Send the address */ +	/* Devices with 256-byte page are addressed as: +	 * Column (bits 0-7), Page (bits 8-15, 16-23, 24-31) +	 * there is no device on the market with page256 +	 * and more than 24 bits. +	 * Devices with 512-byte page are addressed as: +	 * Column (bits 0-7), Page (bits 9-16, 17-24, 25-31) +	 * 25-31 is sent only if the chip support it. +	 * bit 8 changes the read command to be sent +	 * (NAND_CMD_READ0 or NAND_CMD_READ1).  	 */ -  if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) -    WRITE_NAND_ADDRESS(ofs, nandptr); +	if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) +		WRITE_NAND_ADDRESS(ofs, nandptr); -  ofs = ofs >> nand->page_shift; +	ofs = ofs >> nand->page_shift; -  if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) -    for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8) -      WRITE_NAND_ADDRESS(ofs, nandptr); +	if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) +		for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8) +			WRITE_NAND_ADDRESS(ofs, nandptr); -  /* Lower the ALE line */ -  NAND_CTL_CLRALE(nandptr); +	/* Lower the ALE line */ +	NAND_CTL_CLRALE(nandptr); -  /* Wait for the chip to respond */ -  return NanD_WaitReady(nand); -  } +	/* Wait for the chip to respond */ +	return NanD_WaitReady(nand); +}  /* NanD_SelectChip: Select a given flash chip within the current floor */ @@ -419,14 +420,14 @@ static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)  {  	int mfr, id, i; -      NAND_ENABLE_CE(nand);  /* set pin low */ +	NAND_ENABLE_CE(nand);  /* set pin low */  	/* Reset the chip */  	if (NanD_Command(nand, NAND_CMD_RESET)) {  #ifdef NAND_DEBUG  		printf("NanD_Command (reset) for %d,%d returned true\n",  		       floor, chip);  #endif -      NAND_DISABLE_CE(nand);  /* set pin high */ +		NAND_DISABLE_CE(nand);  /* set pin high */  		return 0;  	} @@ -436,7 +437,7 @@ static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)  		printf("NanD_Command (ReadID) for %d,%d returned true\n",  		       floor, chip);  #endif -      NAND_DISABLE_CE(nand);  /* set pin high */ +		NAND_DISABLE_CE(nand);  /* set pin high */  		return 0;  	} @@ -451,11 +452,10 @@ static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)          NAND_DISABLE_CE(nand);  /* set pin high */  	/* No response - return failure */ -	if (mfr == 0xff || mfr == 0) -          { -          printf("NanD_Command (ReadID) got %d %d\n", mfr, id); -          return 0; -          } +	if (mfr == 0xff || mfr == 0) { +		printf("NanD_Command (ReadID) got %d %d\n", mfr, id); +		return 0; +	}  	/* Check it's the same as the first chip we identified.  	 * M-Systems say that any given nand_chip device should only @@ -578,66 +578,66 @@ static void NanD_ScanChips(struct nand_chip *nand)  	       nand->numchips, nand->totlen >> 20);  #endif  } +  #ifdef CONFIG_MTD_NAND_ECC  /* we need to be fast here, 1 us per read translates to 1 second per meg */  static void nand_fast_copy (unsigned char *source, unsigned char *dest, long cntr) -  { -  while (cntr > 16) -    { -    *dest++ = *source++; -    *dest++ = *source++; -    *dest++ = *source++; -    *dest++ = *source++; -    *dest++ = *source++; -    *dest++ = *source++; -    *dest++ = *source++; -    *dest++ = *source++; -    *dest++ = *source++; -    *dest++ = *source++; -    *dest++ = *source++; -    *dest++ = *source++; -    *dest++ = *source++; -    *dest++ = *source++; -    *dest++ = *source++; -    *dest++ = *source++; -    cntr -= 16; -    } -  while (cntr > 0) -    { -    *dest++ = *source++; -    cntr--; -    } -  } +{ +	while (cntr > 16) { +		*dest++ = *source++; +		*dest++ = *source++; +		*dest++ = *source++; +		*dest++ = *source++; +		*dest++ = *source++; +		*dest++ = *source++; +		*dest++ = *source++; +		*dest++ = *source++; +		*dest++ = *source++; +		*dest++ = *source++; +		*dest++ = *source++; +		*dest++ = *source++; +		*dest++ = *source++; +		*dest++ = *source++; +		*dest++ = *source++; +		*dest++ = *source++; +		cntr -= 16; +	} + +	while (cntr > 0) { +		*dest++ = *source++; +		cntr--; +	} +}  #endif +  /* we need to be fast here, 1 us per read translates to 1 second per meg */  static void nand_fast_read(unsigned char *data_buf, int cntr, unsigned long nandptr) -  { -  while (cntr > 16) -    { -    *data_buf++ = READ_NAND(nandptr); -    *data_buf++ = READ_NAND(nandptr); -    *data_buf++ = READ_NAND(nandptr); -    *data_buf++ = READ_NAND(nandptr); -    *data_buf++ = READ_NAND(nandptr); -    *data_buf++ = READ_NAND(nandptr); -    *data_buf++ = READ_NAND(nandptr); -    *data_buf++ = READ_NAND(nandptr); -    *data_buf++ = READ_NAND(nandptr); -    *data_buf++ = READ_NAND(nandptr); -    *data_buf++ = READ_NAND(nandptr); -    *data_buf++ = READ_NAND(nandptr); -    *data_buf++ = READ_NAND(nandptr); -    *data_buf++ = READ_NAND(nandptr); -    *data_buf++ = READ_NAND(nandptr); -    *data_buf++ = READ_NAND(nandptr); -    cntr -= 16; -    } -  while (cntr > 0) -    { -    *data_buf++ = READ_NAND(nandptr); -    cntr--; -    } -  } +{ +	while (cntr > 16) { +		*data_buf++ = READ_NAND(nandptr); +		*data_buf++ = READ_NAND(nandptr); +		*data_buf++ = READ_NAND(nandptr); +		*data_buf++ = READ_NAND(nandptr); +		*data_buf++ = READ_NAND(nandptr); +		*data_buf++ = READ_NAND(nandptr); +		*data_buf++ = READ_NAND(nandptr); +		*data_buf++ = READ_NAND(nandptr); +		*data_buf++ = READ_NAND(nandptr); +		*data_buf++ = READ_NAND(nandptr); +		*data_buf++ = READ_NAND(nandptr); +		*data_buf++ = READ_NAND(nandptr); +		*data_buf++ = READ_NAND(nandptr); +		*data_buf++ = READ_NAND(nandptr); +		*data_buf++ = READ_NAND(nandptr); +		*data_buf++ = READ_NAND(nandptr); +		cntr -= 16; +	} + +	while (cntr > 0) { +		*data_buf++ = READ_NAND(nandptr); +		cntr--; +	} +}  /* This routine is made available to other mtd code via   * inter_module_register.  It must only be accessed through @@ -665,13 +665,14 @@ static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,  	/* Do not allow reads past end of device */  	if ((start + len) > nand->totlen) { -		printf ("nand_read_ecc: Attempt read beyond end of device %x %x %x\n", (uint) start, (uint) len, (uint) nand->totlen); +		printf ("%s: Attempt read beyond end of device %x %x %x\n", __FUNCTION__, (uint) start, (uint) len, (uint) nand->totlen);  		*retlen = 0;  		return -1;  	}  	/* First we calculate the starting page */ -	page = shr(start, nand->page_shift); +	/*page = shr(start, nand->page_shift);*/ +	page = start >> nand->page_shift;  	/* Get raw starting column */  	col = start & (nand->oobblock - 1); @@ -713,7 +714,7 @@ static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,  			nand_calculate_ecc (&nand->data_buf[0], &ecc_calc[0]);  			switch (nand_correct_data (&nand->data_buf[0], &ecc_code[0], &ecc_calc[0])) {  			case -1: -				printf ("nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page); +				printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);  				ecc_failed++;  				break;  			case 1: @@ -729,7 +730,7 @@ static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,  			nand_calculate_ecc (&nand->data_buf[256], &ecc_calc[3]);  			switch (nand_correct_data (&nand->data_buf[256], &ecc_code[3], &ecc_calc[3])) {  			case -1: -				printf ("nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page); +				printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);  				ecc_failed++;  				break;  			case 1: @@ -778,7 +779,7 @@ readdata:  	}  	/* De-select the NAND device */ -      NAND_DISABLE_CE(nand);  /* set pin high */ +	NAND_DISABLE_CE(nand);  /* set pin high */  	/*  	 * Return success, if no ECC failures, else -EIO @@ -788,7 +789,6 @@ readdata:  	return ecc_status ? -1 : 0;  } -  /*   *	Nand_page_program function is used for write and writev !   */ @@ -815,7 +815,7 @@ static int nand_write_page (struct nand_chip *nand,  	/* Read back previous written data, if col > 0 */  	if (col) {  		NanD_Command(nand, NAND_CMD_READ0); -                NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col); +		NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);  		for (i = 0; i < col; i++)  			nand->data_buf[i] = READ_NAND (nandptr);  	} @@ -852,15 +852,15 @@ static int nand_write_page (struct nand_chip *nand,  	/* Write out complete page of data */  	for (i = 0; i < (nand->oobblock + nand->oobsize); i++) -          WRITE_NAND(nand->data_buf[i], nand->IO_ADDR); +		WRITE_NAND(nand->data_buf[i], nand->IO_ADDR);  	/* Send command to actually program the data */ -        NanD_Command(nand, NAND_CMD_PAGEPROG); -        NanD_Command(nand, NAND_CMD_STATUS); +	NanD_Command(nand, NAND_CMD_PAGEPROG); +	NanD_Command(nand, NAND_CMD_STATUS);  	/* See if device thinks it succeeded */  	if (READ_NAND(nand->IO_ADDR) & 0x01) { -		printf ("nand_write_ecc: " "Failed write, page 0x%08x, ", page); +		printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__, page);  		return -1;  	}  #ifdef CONFIG_MTD_NAND_VERIFY_WRITE @@ -879,15 +879,15 @@ static int nand_write_page (struct nand_chip *nand,  	/* Send command to read back the page */  	if (col < nand->eccsize) -          NanD_Command(nand, NAND_CMD_READ0); +		NanD_Command(nand, NAND_CMD_READ0);  	else -          NanD_Command(nand, NAND_CMD_READ1); -        NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col); +		NanD_Command(nand, NAND_CMD_READ1); +	NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);  	/* Loop through and verify the data */  	for (i = col; i < last; i++) {  		if (nand->data_buf[i] != readb (nand->IO_ADDR)) { -			printf ("nand_write_ecc: " "Failed write verify, page 0x%08x ", page); +			printf ("%s: Failed write verify, page 0x%08x ", __FUNCTION__, page);  			return -1;  		}  	} @@ -903,8 +903,8 @@ static int nand_write_page (struct nand_chip *nand,  		nand->data_buf[i] = readb (nand->IO_ADDR);  	for (i = 0; i < ecc_bytes; i++) {  		if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) { -			printf ("nand_write_ecc: Failed ECC write " -			       "verify, page 0x%08x, " "%6i bytes were succesful\n", page, i); +			printf ("%s: Failed ECC write " +			       "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);  			return -1;  		}  	} @@ -912,6 +912,7 @@ static int nand_write_page (struct nand_chip *nand,  #endif  	return 0;  } +  static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,  			   size_t * retlen, const u_char * buf, u_char * ecc_code)  { @@ -919,7 +920,7 @@ static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,  	/* Do not allow write past end of device */  	if ((to + len) > nand->totlen) { -		printf ("nand_write_oob: Attempt to write past end of page\n"); +		printf ("%s: Attempt to write past end of page\n", __FUNCTION__);  		return -1;  	} @@ -933,12 +934,12 @@ static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,  	*retlen = 0;  	/* Select the NAND device */ -      NAND_ENABLE_CE(nand);  /* set pin low */ +	NAND_ENABLE_CE(nand);  /* set pin low */  	/* Check the WP bit */ -      NanD_Command(nand, NAND_CMD_STATUS); +	NanD_Command(nand, NAND_CMD_STATUS);  	if (!(READ_NAND(nand->IO_ADDR) & 0x80)) { -		printf ("nand_write_ecc: Device is write protected!!!\n"); +		printf ("%s: Device is write protected!!!\n", __FUNCTION__);  		ret = -1;  		goto out;  	} @@ -976,7 +977,7 @@ static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,  out:  	/* De-select the NAND device */ -      NAND_DISABLE_CE(nand);  /* set pin high */ +	NAND_DISABLE_CE(nand);  /* set pin high */  	return ret;  } @@ -1150,6 +1151,7 @@ static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,  	int len256 = 0, ret;  	unsigned long nandptr;  	struct Nand *mychip; +	int ret = 0;  	nandptr = nand->IO_ADDR; @@ -1287,9 +1289,21 @@ static int nand_erase(struct nand_chip* nand, size_t ofs, size_t len)  		goto out;  	} +	/* Select the NAND device */ +	NAND_ENABLE_CE(nand);  /* set pin low */ + +	/* Check the WP bit */ +	NanD_Command(nand, NAND_CMD_STATUS); +	if (!(READ_NAND(nand->IO_ADDR) & 0x80)) { +		printf ("%s: Device is write protected!!!\n", __FUNCTION__); +		ret = -1; +		goto out; +	} +  	/* FIXME: Do nand in the background. Use timers or schedule_task() */  	while(len) { -		mychip = &nand->chips[shr(ofs, nand->chipshift)]; +		/*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/ +		mychip = &nand->chips[ofs >> nand->chipshift];  		NanD_Command(nand, NAND_CMD_ERASE1);  		NanD_Address(nand, ADDR_PAGE, ofs); @@ -1298,7 +1312,8 @@ static int nand_erase(struct nand_chip* nand, size_t ofs, size_t len)  		NanD_Command(nand, NAND_CMD_STATUS);  		if (READ_NAND(nandptr) & 1) { -			printf("Error erasing at 0x%lx\n", (long)ofs); +			printf ("%s: Error erasing at 0x%lx\n", +				__FUNCTION__, (long)ofs);  			/* There was an error */  			ret = -1;  			goto out; @@ -1351,20 +1366,20 @@ void nand_probe(unsigned long physadr)  		}  	} -		if (curr_device == -1) -			curr_device = i; +	if (curr_device == -1) +		curr_device = i; -		memset((char *)nand, 0, sizeof(struct nand_chip)); +	memset((char *)nand, 0, sizeof(struct nand_chip)); -		nand->cache_page = -1;  /* init the cache page */ -		nand->IO_ADDR = physadr; -		nand->ChipID = ChipID; -                NanD_ScanChips(nand); -                nand->data_buf = malloc (nand->oobblock + nand->oobsize); -		if (!nand->data_buf) { -			puts ("Cannot allocate memory for data structures.\n"); -			return; -		} +	nand->cache_page = -1;  /* init the cache page */ +	nand->IO_ADDR = physadr; +	nand->ChipID = ChipID; +	NanD_ScanChips(nand); +	nand->data_buf = malloc (nand->oobblock + nand->oobsize); +	if (!nand->data_buf) { +		puts ("Cannot allocate memory for data structures.\n"); +		return; +	}  }  #ifdef CONFIG_MTD_NAND_ECC diff --git a/common/cmd_reginfo.c b/common/cmd_reginfo.c index 1986c2257..954e93737 100644 --- a/common/cmd_reginfo.c +++ b/common/cmd_reginfo.c @@ -28,6 +28,8 @@  #include <mpc8xx.h>  #elif defined (CONFIG_405GP)  #include <asm/processor.h> +#elif defined (CONFIG_5xx) +#include <mpc5xx.h>  #endif  #if (CONFIG_COMMANDS & CFG_CMD_REGINFO) @@ -172,9 +174,42 @@ mfdcr(dmacr3), mfdcr(dmact3),mfdcr(dmada3), mfdcr(dmasa3), mfdcr(dmasb3) );  	mtdcr(ebccfga,pb7ap); 	printf ("%08x ", mfdcr(ebccfgd));  	printf ("\n\n"); -#endif /*(CONFIG_405GP)*/ +#elif defined(CONFIG_5xx) +	volatile immap_t     	*immap  = (immap_t *)CFG_IMMR; +	volatile memctl5xx_t	*memctl = &immap->im_memctl; +	volatile sysconf5xx_t	*sysconf = &immap->im_siu_conf; +	volatile sit5xx_t	*timers = &immap->im_sit; +	volatile car5xx_t	*car = &immap->im_clkrst; +	volatile uimb5xx_t	*uimb = &immap->im_uimb; + +	printf("\nSystem Configuration registers\n"); +	printf("\tIMMR\t0x%08X\tSIUMCR\t0x%08X \n", get_immr(0), sysconf->sc_siumcr); +	printf("\tSYPCR\t0x%08X\tSWSR\t0x%04X \n" ,sysconf->sc_sypcr, sysconf->sc_swsr); +	printf("\tSIPEND\t0x%08X\tSIMASK\t0x%08X \n", sysconf->sc_sipend, sysconf->sc_simask); +	printf("\tSIEL\t0x%08X\tSIVEC\t0x%08X \n", sysconf->sc_siel, sysconf->sc_sivec); +	printf("\tTESR\t0x%08X\n", sysconf->sc_tesr); + +	printf("\nMemory Controller Registers\n"); +	printf("\tBR0\t0x%08X\tOR0\t0x%08X \n", memctl->memc_br0, memctl->memc_or0); +	printf("\tBR1\t0x%08X\tOR1\t0x%08X \n", memctl->memc_br1, memctl->memc_or1); +	printf("\tBR2\t0x%08X\tOR2\t0x%08X \n", memctl->memc_br2, memctl->memc_or2); +	printf("\tBR3\t0x%08X\tOR3\t0x%08X \n", memctl->memc_br3, memctl->memc_or3); +	printf("\tDMBR\t0x%08X\tDMOR\t0x%08X \n", memctl->memc_dmbr, memctl->memc_dmor ); +	printf("\tMSTAT\t0x%08X\n", memctl->memc_mstat); + +	printf("\nSystem Integration Timers\n"); +	printf("\tTBSCR\t0x%08X\tRTCSC\t0x%08X \n", timers->sit_tbscr, timers->sit_rtcsc); +	printf("\tPISCR\t0x%08X \n", timers->sit_piscr); + +	printf("\nClocks and Reset\n"); +	printf("\tSCCR\t0x%08X\tPLPRCR\t0x%08X \n", car->car_sccr, car->car_plprcr); + +	printf("\nU-Bus to IMB3 Bus Interface\n"); +	printf("\tUMCR\t0x%08X\tUIPEND\t0x%08X \n", uimb->uimb_umcr, uimb->uimb_uipend); +	printf ("\n\n"); +#endif /* CONFIG_5xx */  	return 0;  } -#endif	/* CONFIG_8xx && CFG_CMD_REGINFO */ +#endif	/* CONFIG_COMMANDS & CFG_CMD_REGINFO */ diff --git a/common/environment.c b/common/environment.c index 244c2a26b..a868dccbd 100644 --- a/common/environment.c +++ b/common/environment.c @@ -46,7 +46,8 @@   * a seperate section.  Note that ENV_CRC is only defined when building   * U-Boot itself.   */ -#if (defined(CONFIG_FADS)	|| \ +#if (defined(CONFIG_CMI)	|| \ +     defined(CONFIG_FADS)	|| \       defined(CONFIG_HYMOD)	|| \       defined(CONFIG_ICU862)	|| \       defined(CONFIG_R360MPI)	|| \ diff --git a/cpu/mpc5xx/Makefile b/cpu/mpc5xx/Makefile new file mode 100644 index 000000000..a1e0421ae --- /dev/null +++ b/cpu/mpc5xx/Makefile @@ -0,0 +1,52 @@ +# +# (C) Copyright 2003 +# Martin Winistoerfer, martinwinistoerfer@gmx.ch. +# +# 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 +# + +# +# File:			cpu/mpc5xx/Makefile +#  +# Discription:		Makefile to build mpc5xx cpu configuration. +#			Will include top config.mk which itselfs +#			uses the definitions made in cpu/mpc5xx/config.mk  +# + + +include $(TOPDIR)/config.mk + +LIB	= lib$(CPU).a + +START	= start.S  +OBJS	= serial.o cpu.o cpu_init.o interrupts.o traps.o speed.o status_led.o + +all:	.depend $(START) $(LIB) + +$(LIB):	$(OBJS) +	$(AR) crv $@ $(OBJS) + +######################################################################### + +.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c) +		$(CC) -M $(CFLAGS) $(START:.o=.S)  $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/cpu/mpc5xx/config.mk b/cpu/mpc5xx/config.mk new file mode 100644 index 000000000..d302d4835 --- /dev/null +++ b/cpu/mpc5xx/config.mk @@ -0,0 +1,34 @@ +# +# (C) Copyright 2003 +# Martin Winistoerfer, martinwinistoerfer@gmx.ch. +# +# 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 +# + +# +# File:			config.mk +#  +# Discription:		compiler flags and make definitions +# +  + +PLATFORM_RELFLAGS += 	-mrelocatable -ffixed-r14 -meabi + +PLATFORM_CPPFLAGS +=	-DCONFIG_5xx -ffixed-r2 -ffixed-r29  -mpowerpc -msoft-float + diff --git a/cpu/mpc5xx/cpu.c b/cpu/mpc5xx/cpu.c new file mode 100644 index 000000000..6018436a2 --- /dev/null +++ b/cpu/mpc5xx/cpu.c @@ -0,0 +1,155 @@ +/* + * (C) Copyright 2003 + * Martin Winistoerfer, martinwinistoerfer@gmx.ch. + * + * 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,  + */ + +/* + * File:		cpu.c + *  + * Discription:		Some cpu specific function for watchdog,  + *                      cpu version test, clock setting ... + *  + */ + + +#include <common.h> +#include <watchdog.h> +#include <command.h> +#include <mpc5xx.h> + + +#if (defined(CONFIG_MPC555)) +#  define	ID_STR	"MPC555/556" + +/* + * Check version of cpu with Processor Version Register (PVR) + */ +static int check_cpu_version (long clock, uint pvr, uint immr) +{ +    char buf[32]; +	/* The highest 16 bits should be 0x0002 for a MPC555/556 */ +	if ((pvr >> 16) == 0x0002) { +		printf (" " ID_STR " Version %x", (pvr >> 16)); +		printf (" at %s MHz:", strmhz (buf, clock)); +	} else { +		printf ("Not supported cpu version"); +		return -1; +	} +	return 0; +} +#endif /* CONFIG_MPC555 */ + + +/* + * Check version of mpc5xx + */ +int checkcpu (void) +{ +	DECLARE_GLOBAL_DATA_PTR; + +	ulong clock = gd->cpu_clk; +	uint immr = get_immr (0);	/* Return full IMMR contents */ +	uint pvr = get_pvr ();		/* Retrieve PVR register */ + +	puts ("CPU:   "); + +	return check_cpu_version (clock, pvr, immr); +} + +/* + * Called by macro WATCHDOG_RESET  + */ +#if defined(CONFIG_WATCHDOG) +void watchdog_reset (void) +{ +	int re_enable = disable_interrupts (); + +	reset_5xx_watchdog ((immap_t *) CFG_IMMR); +	if (re_enable) +		enable_interrupts (); +} + +/* + * Will clear software reset + */ +void reset_5xx_watchdog (volatile immap_t * immr) +{ +	/* Use the MPC5xx Internal Watchdog */ +	immr->im_siu_conf.sc_swsr = 0x556c;	/* Prevent SW time-out */ +	immr->im_siu_conf.sc_swsr = 0xaa39;     +} + +#endif /* CONFIG_WATCHDOG */ + + +/* + * Get timebase clock frequency + */ +unsigned long get_tbclk (void) +{ +	DECLARE_GLOBAL_DATA_PTR; +	volatile immap_t *immr = (volatile immap_t *) CFG_IMMR; +	ulong oscclk, factor; + +	if (immr->im_clkrst.car_sccr & SCCR_TBS) { +		return (gd->cpu_clk / 16); +	} + +	factor = (((CFG_PLPRCR) & PLPRCR_MF_MSK) >> PLPRCR_MF_SHIFT) + 1; + +	oscclk = gd->cpu_clk / factor; + +	if ((immr->im_clkrst.car_sccr & SCCR_RTSEL) == 0 || factor > 2) { +		return (oscclk / 4); +	} +	return (oscclk / 16); +} + + +/* + * Reset board  + */ +int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	ulong addr; +	 +	/* Interrupts off, enable reset */ +        __asm__ volatile	("  mtspr	81, %r0		\n\t +				    mfmsr	%r3		\n\t +				    rlwinm	%r31,%r3,0,25,23\n\t +				    mtmsr	%r31		\n\t"); +        /* +         * Trying to execute the next instruction at a non-existing address +         * should cause a machine check, resulting in reset +         */ +#ifdef CFG_RESET_ADDRESS +        addr = CFG_RESET_ADDRESS; +#else +        /* +         * note: when CFG_MONITOR_BASE points to a RAM address, CFG_MONITOR_BASE         * - sizeof (ulong) is usually a valid address. Better pick an address +         * known to be invalid on your system and assign it to CFG_RESET_ADDRESS. +         * "(ulong)-1" used to be a good choice for many systems... +         */ +        addr = CFG_MONITOR_BASE - sizeof (ulong); +#endif +	((void (*) (void)) addr) (); +	return 1; +} + diff --git a/cpu/mpc5xx/cpu_init.c b/cpu/mpc5xx/cpu_init.c new file mode 100644 index 000000000..27cf3d6b1 --- /dev/null +++ b/cpu/mpc5xx/cpu_init.c @@ -0,0 +1,119 @@ +/* + * (C) Copyright 2003  Martin Winistoerfer, martinwinistoerfer@gmx.ch. + * + * 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,  + */ + +/* + * File:		cpu_init.c + *  + * Discription:		Contains initialisation functions to setup + *    			the cpu properly + * + */ + +#include <common.h> +#include <mpc5xx.h> +#include <watchdog.h> + +/* + * Setup essential cpu registers to run  + */ +void cpu_init_f (volatile immap_t * immr) +{ +	volatile memctl5xx_t *memctl = &immr->im_memctl; +	ulong reg; + +	/* SYPCR - contains watchdog control. This will enable watchdog */ +	/* if CONFIG_WATCHDOG is set */ +	immr->im_siu_conf.sc_sypcr = CFG_SYPCR; + +#if defined(CONFIG_WATCHDOG) +	reset_5xx_watchdog (immr); +#endif  + +	/* SIUMCR - contains debug pin configuration */ +	immr->im_siu_conf.sc_siumcr |= CFG_SIUMCR; + +	/* Initialize timebase. Unlock TBSCRK */ +	immr->im_sitk.sitk_tbscrk = KAPWR_KEY; +	immr->im_sit.sit_tbscr = CFG_TBSCR; + +	/* Full IMB bus speed */ +	immr->im_uimb.uimb_umcr = CFG_UMCR; +	 +	/* Time base and decrementer will be enables (TBE) */ +	/* in init_timebase() in time.c called from board_init_f(). */ +  +	/* Initialize the PIT. Unlock PISCRK */ +	immr->im_sitk.sitk_piscrk = KAPWR_KEY; +	immr->im_sit.sit_piscr = CFG_PISCR; + +	/* PLL (CPU clock) settings */ +	immr->im_clkrstk.cark_plprcrk = KAPWR_KEY; + +	/* If CFG_PLPRCR (set in the various *_config.h files) tries to +	 * set the MF field, then just copy CFG_PLPRCR over car_plprcr, +	 * otherwise OR in CFG_PLPRCR so we do not change the currentMF +	 * field value. +	 */ +#if ((CFG_PLPRCR & PLPRCR_MF_MSK) != 0) +	reg = CFG_PLPRCR;			/* reset control bits   */ +#else +	reg = immr->im_clkrst.car_plprcr; +	reg &= PLPRCR_MF_MSK;			/* isolate MF field */ +	reg |= CFG_PLPRCR;			/* reset control bits   */ +#endif +	immr->im_clkrst.car_plprcr = reg; + +	/* System integration timers. CFG_MASK has EBDF configuration */ +	immr->im_clkrstk.cark_sccrk = KAPWR_KEY; +	reg = immr->im_clkrst.car_sccr; +	reg &= SCCR_MASK; +	reg |= CFG_SCCR; +	immr->im_clkrst.car_sccr = reg; + +	/* Memory Controller */ +	memctl->memc_br0 = CFG_BR0_PRELIM; +	memctl->memc_or0 = CFG_OR0_PRELIM; + +#if (defined(CFG_OR1_PRELIM) && defined(CFG_BR1_PRELIM)) +	memctl->memc_or1 = CFG_OR1_PRELIM; +	memctl->memc_br1 = CFG_BR1_PRELIM; +#endif + +#if defined(CFG_OR2_PRELIM) && defined(CFG_BR2_PRELIM) +	memctl->memc_or2 = CFG_OR2_PRELIM; +	memctl->memc_br2 = CFG_BR2_PRELIM; +#endif + +#if defined(CFG_OR3_PRELIM) && defined(CFG_BR3_PRELIM) +	memctl->memc_or3 = CFG_OR3_PRELIM; +	memctl->memc_br3 = CFG_BR3_PRELIM; +#endif + +} + +/* + * Initialize higher level parts of cpu + */ +int cpu_init_r (void) +{ +  	/* Nothing to do at the moment */ +	return (0); +} diff --git a/cpu/mpc5xx/interrupts.c b/cpu/mpc5xx/interrupts.c new file mode 100644 index 000000000..282c3165d --- /dev/null +++ b/cpu/mpc5xx/interrupts.c @@ -0,0 +1,273 @@ +/* + * (C) Copyright 2000-2002	Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * (C) Copyright 2003		Martin Winistoerfer, martinwinistoerfer@gmx.ch. + * + * 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,  + */ + +/* + * File:		interrupt.c + *  + * Discription:		Contains interrupt routines needed by U-Boot + * + */ + +#include <common.h> +#include <watchdog.h> +#include <mpc5xx.h> +#include <asm/processor.h> + +/************************************************************************/ + +unsigned decrementer_count;	/* count value for 1e6/HZ microseconds	*/ + +/************************************************************************/ + +struct interrupt_action { +	interrupt_handler_t *handler; +	void *arg; +}; + +static struct interrupt_action irq_vecs[NR_IRQS]; + +/* + * Local function prototypes  + */ +static __inline__ unsigned long get_msr (void) +{ +	unsigned long msr; + +	asm volatile ("mfmsr %0":"=r" (msr):); + +	return msr; +} + +static __inline__ void set_msr (unsigned long msr) +{ +	asm volatile ("mtmsr %0"::"r" (msr)); +} + +static __inline__ unsigned long get_dec (void) +{ +	unsigned long val; + +	asm volatile ("mfdec %0":"=r" (val):); + +	return val; +} + + +static __inline__ void set_dec (unsigned long val) +{ +	asm volatile ("mtdec %0"::"r" (val)); +} + +/* + * Enable interrupts  + */  +void enable_interrupts (void) +{ +	set_msr (get_msr () | MSR_EE); +} + +/*  + * Returns flag if MSR_EE was set before  + */ +int disable_interrupts (void) +{ +	ulong msr = get_msr (); + +	set_msr (msr & ~MSR_EE); +	return ((msr & MSR_EE) != 0); +} + +/* + * Initialise interrupts  + */ + +int interrupt_init (void) +{ +	volatile immap_t *immr = (immap_t *) CFG_IMMR; + +	/* Decrementer used here for status led */ +	decrementer_count = get_tbclk () / CFG_HZ; + +	/* Disable all interrupts */ +	immr->im_siu_conf.sc_simask = 0; + +	set_dec (decrementer_count); + +	set_msr (get_msr () | MSR_EE); +	return (0); +} + +/* + * Handle external interrupts + */ +void external_interrupt (struct pt_regs *regs) +{ +	volatile immap_t *immr = (immap_t *) CFG_IMMR; +	int irq; +	ulong simask, newmask; +	ulong vec, v_bit; + +	/* +	 * read the SIVEC register and shift the bits down +	 * to get the irq number +	 */ +	vec = immr->im_siu_conf.sc_sivec; +	irq = vec >> 26; +	v_bit = 0x80000000UL >> irq; + +	/* +	 * Read Interrupt Mask Register and Mask Interrupts +	 */ +	simask = immr->im_siu_conf.sc_simask; +	newmask = simask & (~(0xFFFF0000 >> irq)); +	immr->im_siu_conf.sc_simask = newmask; + +	if (!(irq & 0x1)) {		/* External Interrupt ?     */ +		ulong siel; + +		/* +		 * Read Interrupt Edge/Level Register +		 */ +		siel = immr->im_siu_conf.sc_siel; + +		if (siel & v_bit) {	/* edge triggered interrupt ?   */ +			/* +			 * Rewrite SIPEND Register to clear interrupt +			 */ +			immr->im_siu_conf.sc_sipend = v_bit; +		} +	} + +	if (irq_vecs[irq].handler != NULL) { +		irq_vecs[irq].handler (irq_vecs[irq].arg); +	} else { +		printf ("\nBogus External Interrupt IRQ %d Vector %ld\n", +				irq, vec); +		/* turn off the bogus interrupt to avoid it from now */ +		simask &= ~v_bit; +	} +	/* +	 * Re-Enable old Interrupt Mask +	 */ +	immr->im_siu_conf.sc_simask = simask; +} + +/* + * Install and free an interrupt handler + */ +void irq_install_handler (int vec, interrupt_handler_t * handler, +						  void *arg) +{ +	volatile immap_t *immr = (immap_t *) CFG_IMMR; +	/* SIU interrupt */ +	if (irq_vecs[vec].handler != NULL) { +		printf ("SIU interrupt %d 0x%x\n", +			vec, +			(uint) handler); +	} +	irq_vecs[vec].handler = handler; +	irq_vecs[vec].arg = arg; +	immr->im_siu_conf.sc_simask |= 1 << (31 - vec); +#if 0 +	printf ("Install SIU interrupt for vector %d ==> %p\n", +		vec, handler); +#endif +} + +void irq_free_handler (int vec) +{ +	volatile immap_t *immr = (immap_t *) CFG_IMMR; +	/* SIU interrupt */ +#if 0 +	printf ("Free CPM interrupt for vector %d\n", +		vec); +#endif +	immr->im_siu_conf.sc_simask &= ~(1 << (31 - vec)); +	irq_vecs[vec].handler = NULL; +	irq_vecs[vec].arg = NULL; +} + +volatile ulong timestamp = 0; + +/* + *  Timer interrupt - gets called when  bit 0 of DEC changes from  + *  0. Decrementer is enabled with bit TBE in TBSCR. + */ +void timer_interrupt (struct pt_regs *regs) +{ +	volatile immap_t *immr = (immap_t *) CFG_IMMR; + +#ifdef CONFIG_STATUS_LED +	extern void status_led_tick (ulong); +#endif +#if 0 +	printf ("*** Timer Interrupt *** "); +#endif +	/* Reset Timer Status Bit and Timers Interrupt Status */ +	immr->im_clkrstk.cark_plprcrk = KAPWR_KEY; +	__asm__ ("nop"); +	immr->im_clkrst.car_plprcr |= PLPRCR_TEXPS | PLPRCR_TMIST; +	 +	/* Restore Decrementer Count */ +	set_dec (decrementer_count); + +	timestamp++; + +#ifdef CONFIG_STATUS_LED +	status_led_tick (timestamp); +#endif /* CONFIG_STATUS_LED */ + +#if defined(CONFIG_WATCHDOG) +	/* +	 * The shortest watchdog period of all boards +	 * is approx. 1 sec, thus re-trigger watchdog at least +	 * every 500 ms = CFG_HZ / 2 +	 */ +	if ((timestamp % (CFG_HZ / 2)) == 0) { +		reset_5xx_watchdog (immr); +	} +#endif /* CONFIG_WATCHDOG */ +} + +/* + * Reset timer  + */ +void reset_timer (void) +{ +	timestamp = 0; +} + +/* + * Get Timer + */ +ulong get_timer (ulong base) +{ +	return (timestamp - base); +} + +/* + * Set timer + */ +void set_timer (ulong t) +{ +	timestamp = t; +} diff --git a/cpu/mpc5xx/serial.c b/cpu/mpc5xx/serial.c new file mode 100644 index 000000000..738c275f8 --- /dev/null +++ b/cpu/mpc5xx/serial.c @@ -0,0 +1,171 @@ +/* + * (C) Copyright 2003 + * Martin Winistoerfer, martinwinistoerfer@gmx.ch. + * + * 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,  + */ + +/* + * File:		serial.c + *  + * Discription:		Serial interface driver for SCI1 and SCI2.  + *     			Since this code will be called from ROM use + * 			only non-static local variables. + * + */ + +#include <common.h> +#include <watchdog.h> +#include <command.h> +#include <mpc5xx.h> + + +/* + * Local function prototypes  + */ + +static int ready_to_send(void); + +/* + * Minimal global serial functions needed to use one of the SCI modules. + */ + +int serial_init (void) +{ +	volatile immap_t *immr = (immap_t *)CFG_IMMR; + +	serial_setbrg(); + +#if defined(CONFIG_5xx_CONS_SCI1) +	/* 10-Bit, 1 start bit, 8 data bit, no parity, 1 stop bit */ +	immr->im_qsmcm.qsmcm_scc1r1 = SCI_M_10; +	immr->im_qsmcm.qsmcm_scc1r1 = SCI_TE | SCI_RE;  +#else +	immr->im_qsmcm.qsmcm_scc2r1 = SCI_M_10;  +	immr->im_qsmcm.qsmcm_scc2r1 = SCI_TE | SCI_RE; +#endif +	return 0; +} + +void serial_putc(const char c) +{         +	volatile immap_t *immr = (immap_t *)CFG_IMMR; +	 +	/* Test for completition */ +	if(ready_to_send()) { +#if defined(CONFIG_5xx_CONS_SCI1) +		immr->im_qsmcm.qsmcm_sc1dr = (short)c;  +#else +		immr->im_qsmcm.qsmcm_sc2dr = (short)c; +#endif		 +		if(c == '\n') { +			if(ready_to_send()); +#if defined(CONFIG_5xx_CONS_SCI1) +			immr->im_qsmcm.qsmcm_sc1dr = (short)'\r'; +#else +			immr->im_qsmcm.qsmcm_sc2dr = (short)'\r'; +#endif +		} +	} +} + +int serial_getc(void) +{	 +	volatile immap_t *immr = (immap_t *)CFG_IMMR; +	volatile short status; +	unsigned char tmp; +     +	/* New data ? */ +	do { +#if defined(CONFIG_5xx_CONS_SCI1) +      		status = immr->im_qsmcm.qsmcm_sc1sr;  +#else +		status = immr->im_qsmcm.qsmcm_sc2sr; +#endif + +#if defined(CONFIG_WATCHDOG) +		reset_5xx_watchdog (immr);	 +#endif +  	} while ((status & SCI_RDRF) == 0); +    		 +	/* Read data */ +#if defined(CONFIG_5xx_CONS_SCI1) +	tmp = (unsigned char)(immr->im_qsmcm.qsmcm_sc1dr & SCI_SCXDR_MK);  +#else +	tmp = (unsigned char)( immr->im_qsmcm.qsmcm_sc2dr & SCI_SCXDR_MK); +#endif +	return	tmp; +} + +int serial_tstc() +{ +	volatile immap_t *immr = (immap_t *)CFG_IMMR; +  	short status; + +	/* New data character ? */ +#if defined(CONFIG_5xx_CONS_SCI1) +	status = immr->im_qsmcm.qsmcm_sc1sr;  +#else +	status = immr->im_qsmcm.qsmcm_sc2sr; +#endif +	return (status & SCI_RDRF);  +} + +void serial_setbrg (void) +{ +	DECLARE_GLOBAL_DATA_PTR; +        volatile immap_t *immr = (immap_t *)CFG_IMMR; +	short scxbr; + +	/* Set baudrate */ +	scxbr = (gd->cpu_clk / (32 * gd->baudrate)); +#if defined(CONFIG_5xx_CONS_SCI1) +	immr->im_qsmcm.qsmcm_scc1r0 = (scxbr & SCI_SCXBR_MK);  +#else +	immr->im_qsmcm.qsmcm_scc2r0 = (scxbr & SCI_SCXBR_MK); +#endif +} + +void serial_puts (const char *s) +{ +	while (*s) { +		serial_putc(*s); +		++s; +	} +} + +int ready_to_send(void) +{ +	volatile immap_t *immr = (immap_t *)CFG_IMMR; +	volatile short status; + +  	do { +#if defined(CONFIG_5xx_CONS_SCI1) +    		status = immr->im_qsmcm.qsmcm_sc1sr;  +#else +		status = immr->im_qsmcm.qsmcm_sc2sr; +#endif + +#if defined(CONFIG_WATCHDOG) +		reset_5xx_watchdog (immr);	 +#endif +  	} while ((status & SCI_TDRE) == 0); +	return 1;  + +} + diff --git a/cpu/mpc5xx/speed.c b/cpu/mpc5xx/speed.c new file mode 100644 index 000000000..8098c9982 --- /dev/null +++ b/cpu/mpc5xx/speed.c @@ -0,0 +1,66 @@ +/* + * (C) Copyright 2003 + * Martin Winistoerfer, martinwinistoerfer@gmx.ch. + * + * 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,  + */ + +/* + * File:		speed.c + *  + * Discription:		Provides cpu speed calculation + *  + */ + +#include <common.h> +#include <mpc5xx.h> +#include <asm/processor.h> + +/* + * Get cpu and bus clock + */ +int get_clocks (void) +{ +	DECLARE_GLOBAL_DATA_PTR; +	volatile immap_t *immr = (immap_t *) CFG_IMMR; + +#ifndef	CONFIG_5xx_GCLK_FREQ +	uint divf = (immr->im_clkrst.car_plprcr & PLPRCR_DIVF_MSK); +	uint mf = ((immr->im_clkrst.car_plprcr & PLPRCR_MF_MSK) >> PLPRCR_MF_SHIFT); +	ulong vcoout; + +	vcoout = (CFG_OSC_CLK / (divf + 1)) * (mf + 1) * 2; +	if(immr->im_clkrst.car_plprcr & PLPRCR_CSRC_MSK) { +		gd->cpu_clk = vcoout / (2^(((immr->im_clkrst.car_sccr & SCCR_DFNL_MSK) >> SCCR_DFNL_SHIFT) + 1)); +	} else { +    		gd->cpu_clk = vcoout / (2^(immr->im_clkrst.car_sccr & SCCR_DFNH_MSK)); +    	}	 +	 +#else /* CONFIG_5xx_GCLK_FREQ */ +	gd->bus_clk = CONFIG_5xx_GCLK_FREQ; +#endif /* CONFIG_5xx_GCLK_FREQ */ + +	if ((immr->im_clkrst.car_sccr & SCCR_EBDF11) == 0) { +		/* No Bus Divider active */ +		gd->bus_clk = gd->cpu_clk; +	} else { +		/* CLKOUT is GCLK / 2 */ +		gd->bus_clk = gd->cpu_clk / 2; +	} +	return (0); +} diff --git a/cpu/mpc5xx/start.S b/cpu/mpc5xx/start.S new file mode 100644 index 000000000..d17fe9272 --- /dev/null +++ b/cpu/mpc5xx/start.S @@ -0,0 +1,629 @@ +/* + *  Copyright (C) 1998	Dan Malek <dmalek@jlc.net> + *  Copyright (C) 1999	Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> + *  Copyright (C) 2000, 2001, 2002 Wolfgang Denk <wd@denx.de> + *  Copyright (C) 2003  Martin Winistoerfer, martinwinistoerfer@gmx.ch. + *  + * 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 + */ + +/* + * File:		start.S + *  + * Discription:		startup code + * + */ + +#include <config.h> +#include <mpc5xx.h> +#include <version.h> + +#define CONFIG_5xx 1		/* needed for Linux kernel header files */ +#define _LINUX_CONFIG_H 1	/* avoid reading Linux autoconf.h file	*/ + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> +	 +#include <linux/config.h> +#include <asm/processor.h>	 + +#ifndef  CONFIG_IDENT_STRING +#define  CONFIG_IDENT_STRING "" +#endif + +/* We don't have a MMU. +*/ +#undef	MSR_KERNEL +#define MSR_KERNEL ( MSR_ME | MSR_RI )		/* Machine Check and Recoverable Interr. */ + +/* + * Set up GOT: Global Offset Table + * + * Use r14 to access the GOT + */ +	START_GOT +	GOT_ENTRY(_GOT2_TABLE_) +	GOT_ENTRY(_FIXUP_TABLE_) + +	GOT_ENTRY(_start) +	GOT_ENTRY(_start_of_vectors) +	GOT_ENTRY(_end_of_vectors) +	GOT_ENTRY(transfer_to_handler) + +	GOT_ENTRY(_end) +	GOT_ENTRY(.bss) +	END_GOT + +/* + * r3 - 1st arg to board_init(): IMMP pointer + * r4 - 2nd arg to board_init(): boot flag + */ +	.text +	.long	0x27051956			/* U-Boot Magic Number */ +	.globl	version_string +version_string: +	.ascii U_BOOT_VERSION +	.ascii " (", __DATE__, " - ", __TIME__, ")" +	.ascii CONFIG_IDENT_STRING, "\0" + +	. = EXC_OFF_SYS_RESET +	.globl	_start +_start: +	mfspr	r3, 638 +	li	r4, CFG_ISB			/* Set ISB bit */ +	or	r3, r3, r4  +	mtspr	638, r3 +	li	r21, BOOTFLAG_COLD		/* Normal Power-On: Boot from FLASH	*/ +	b	boot_cold + +	. = EXC_OFF_SYS_RESET + 0x20 + +	.globl	_start_warm +_start_warm: +	li	r21, BOOTFLAG_WARM		/* Software reboot */ +	b	boot_warm + +boot_cold: +boot_warm: + +	/* Initialize machine status; enable machine check interrupt		*/ +	/*----------------------------------------------------------------------*/ +	li	r3, MSR_KERNEL			/* Set ME, RI flags */ +	mtmsr	r3 +	mtspr	SRR1, r3			/* Make SRR1 match MSR */ + +	/* Initialize debug port registers					*/ +	/*----------------------------------------------------------------------*/ +	xor	r0, r0, r0			/* Clear R0 */ +	mtspr	LCTRL1, r0			/* Initialize debug port regs */ +	mtspr	LCTRL2, r0 +	mtspr	COUNTA, r0 +	mtspr	COUNTB, r0 + +	/* +	 * Calculate absolute address in FLASH and jump there +	 *----------------------------------------------------------------------*/ + +	lis	r3, CFG_MONITOR_BASE@h +	ori	r3, r3, CFG_MONITOR_BASE@l +	addi	r3, r3, in_flash - _start + EXC_OFF_SYS_RESET +	mtlr	r3 +	blr + +in_flash: + +	/* Initialize some SPRs that are hard to access from C			*/ +	/*----------------------------------------------------------------------*/ +	 +	lis     r3, CFG_IMMR@h          	/* Pass IMMR as arg1 to C routine */ +	lis	r2, CFG_INIT_SP_ADDR@h +	ori	r1, r2, CFG_INIT_SP_ADDR@l	/* Set up the stack in internal SRAM */ +	/* Note: R0 is still 0 here */ +	stwu	r0, -4(r1)			/* Clear final stack frame so that	*/ +	stwu	r0, -4(r1)			/* stack backtraces terminate cleanly	*/ + +	/* +	 * Disable serialized ifetch and show cycles +	 * (i.e. set processor to normal mode) for maximum +	 * performance. +	 */ + +	li	r2, 0x0007 +	mtspr	ICTRL, r2 + +	/* Set up debug mode entry */ + +	lis	r2, CFG_DER@h +	ori	r2, r2, CFG_DER@l +	mtspr	DER, r2 + +	/* Let the C-code set up the rest					*/ +	/*									*/ +	/* Be careful to keep code relocatable !				*/ +	/*----------------------------------------------------------------------*/ + +	GET_GOT			/* initialize GOT access			*/ + +	/* r3: IMMR */ +	bl	cpu_init_f	/* run low-level CPU init code     (from Flash)	*/ + +	mr	r3, r21 +	/* r3: BOOTFLAG */ +	bl	board_init_f	/* run 1st part of board init code (from Flash) */ + + + +	.globl	_start_of_vectors +_start_of_vectors: + +/* Machine check */ +	STD_EXCEPTION(0x200, MachineCheck, MachineCheckException) + +/* Data Storage exception.  "Never" generated on the 860. */ +	STD_EXCEPTION(0x300, DataStorage, UnknownException) + +/* Instruction Storage exception.  "Never" generated on the 860. */ +	STD_EXCEPTION(0x400, InstStorage, UnknownException) + +/* External Interrupt exception. */ +	STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt) + +/* Alignment exception. */ +	. = 0x600 +Alignment: +	EXCEPTION_PROLOG +	mfspr	r4,DAR +	stw	r4,_DAR(r21) +	mfspr	r5,DSISR +	stw	r5,_DSISR(r21) +	addi	r3,r1,STACK_FRAME_OVERHEAD +	li	r20,MSR_KERNEL +	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */ +	lwz	r6,GOT(transfer_to_handler) +	mtlr	r6 +	blrl +.L_Alignment: +	.long	AlignmentException - _start + EXC_OFF_SYS_RESET +	.long	int_return - _start + EXC_OFF_SYS_RESET + +/* Program check exception */ +	. = 0x700 +ProgramCheck: +	EXCEPTION_PROLOG +	addi	r3,r1,STACK_FRAME_OVERHEAD +	li	r20,MSR_KERNEL +	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */ +	lwz	r6,GOT(transfer_to_handler) +	mtlr	r6 +	blrl +.L_ProgramCheck: +	.long	ProgramCheckException - _start + EXC_OFF_SYS_RESET +	.long	int_return - _start + EXC_OFF_SYS_RESET + +	/* FPU on MPC5xx available. We will use it later. +	*/ +	STD_EXCEPTION(0x800, FPUnavailable, UnknownException) + +	/* I guess we could implement decrementer, and may have +	 * to someday for timekeeping. +	 */ +	STD_EXCEPTION(0x900, Decrementer, timer_interrupt) +	STD_EXCEPTION(0xa00, Trap_0a, UnknownException) +	STD_EXCEPTION(0xb00, Trap_0b, UnknownException) + +	. = 0xc00 +/* + * r0 - SYSCALL number + * r3-... arguments + */ +SystemCall: +	addis	r11,r0,0		/* get functions table addr */ +	ori	r11,r11,0		/* Note: this code is patched in trap_init */ +	addis	r12,r0,0		/* get number of functions */ +	ori	r12,r12,0 + +	cmplw	0, r0, r12 +	bge	1f + +	rlwinm	r0,r0,2,0,31		/* fn_addr = fn_tbl[r0] */ +	add	r11,r11,r0 +	lwz	r11,0(r11) + +	li	r20,0xd00-4		/* Get stack pointer */ +	lwz	r12,0(r20) +	subi	r12,r12,12		/* Adjust stack pointer */ +	li	r0,0xc00+_end_back-SystemCall +	cmplw	0, r0, r12		/* Check stack overflow */ +	bgt	1f +	stw	r12,0(r20) + +	mflr	r0 +	stw	r0,0(r12) +	mfspr	r0,SRR0 +	stw	r0,4(r12) +	mfspr	r0,SRR1 +	stw	r0,8(r12) + +	li	r12,0xc00+_back-SystemCall +	mtlr	r12 +	mtspr	SRR0,r11 + +1:	SYNC +	rfi + +_back: + +	mfmsr	r11			/* Disable interrupts */ +	li	r12,0 +	ori	r12,r12,MSR_EE +	andc	r11,r11,r12 +	SYNC				/* Some chip revs need this... */ +	mtmsr	r11 +	SYNC + +	li	r12,0xd00-4		/* restore regs */ +	lwz	r12,0(r12) + +	lwz	r11,0(r12) +	mtlr	r11 +	lwz	r11,4(r12) +	mtspr	SRR0,r11 +	lwz	r11,8(r12) +	mtspr	SRR1,r11 + +	addi	r12,r12,12		/* Adjust stack pointer */ +	li	r20,0xd00-4 +	stw	r12,0(r20) + +	SYNC +	rfi +_end_back: + +	STD_EXCEPTION(0xd00, SingleStep, UnknownException) + +	STD_EXCEPTION(0xe00, Trap_0e, UnknownException) +	STD_EXCEPTION(0xf00, Trap_0f, UnknownException) + +	/* On the MPC8xx, this is a software emulation interrupt.  It occurs +	 * for all unimplemented and illegal instructions. +	 */ +	STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException) +	STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException) +	STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException) +	STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException) +	STD_EXCEPTION(0x1400, DataTLBError, UnknownException) + +	STD_EXCEPTION(0x1500, Reserved5, UnknownException) +	STD_EXCEPTION(0x1600, Reserved6, UnknownException) +	STD_EXCEPTION(0x1700, Reserved7, UnknownException) +	STD_EXCEPTION(0x1800, Reserved8, UnknownException) +	STD_EXCEPTION(0x1900, Reserved9, UnknownException) +	STD_EXCEPTION(0x1a00, ReservedA, UnknownException) +	STD_EXCEPTION(0x1b00, ReservedB, UnknownException) + +	STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException) +	STD_EXCEPTION(0x1d00, InstructionBreakpoint, DebugException) +	STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException) +	STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException) + + +	.globl	_end_of_vectors +_end_of_vectors: + + +	. = 0x2000 + +/* + * This code finishes saving the registers to the exception frame + * and jumps to the appropriate handler for the exception. + * Register r21 is pointer into trap frame, r1 has new stack pointer. + */ +	.globl	transfer_to_handler +transfer_to_handler: +	stw	r22,_NIP(r21) +	lis	r22,MSR_POW@h +	andc	r23,r23,r22 +	stw	r23,_MSR(r21) +	SAVE_GPR(7, r21) +	SAVE_4GPRS(8, r21) +	SAVE_8GPRS(12, r21) +	SAVE_8GPRS(24, r21) +	mflr	r23 +	andi.	r24,r23,0x3f00		/* get vector offset */ +	stw	r24,TRAP(r21) +	li	r22,0 +	stw	r22,RESULT(r21) +	mtspr	SPRG2,r22		/* r1 is now kernel sp */ +	lwz	r24,0(r23)		/* virtual address of handler */ +	lwz	r23,4(r23)		/* where to go when done */ +	mtspr	SRR0,r24 +	mtspr	SRR1,r20 +	mtlr	r23 +	SYNC +	rfi				/* jump to handler, enable MMU */ + +int_return: +	mfmsr	r28			/* Disable interrupts */ +	li	r4,0 +	ori	r4,r4,MSR_EE +	andc	r28,r28,r4 +	SYNC				/* Some chip revs need this... */ +	mtmsr	r28 +	SYNC +	lwz	r2,_CTR(r1) +	lwz	r0,_LINK(r1) +	mtctr	r2 +	mtlr	r0 +	lwz	r2,_XER(r1) +	lwz	r0,_CCR(r1) +	mtspr	XER,r2 +	mtcrf	0xFF,r0 +	REST_10GPRS(3, r1) +	REST_10GPRS(13, r1) +	REST_8GPRS(23, r1) +	REST_GPR(31, r1) +	lwz	r2,_NIP(r1)		/* Restore environment */ +	lwz	r0,_MSR(r1) +	mtspr	SRR0,r2 +	mtspr	SRR1,r0 +	lwz	r0,GPR0(r1) +	lwz	r2,GPR2(r1) +	lwz	r1,GPR1(r1) +	SYNC +	rfi + +		 +/* + * unsigned int get_immr (unsigned int mask) + * + * return (mask ? (IMMR & mask) : IMMR); + */ +	.globl	get_immr +get_immr: +	mr	r4,r3		/* save mask */ +	mfspr	r3, IMMR	/* IMMR */ +	cmpwi	0,r4,0		/* mask != 0 ? */ +	beq	4f +	and	r3,r3,r4	/* IMMR & mask */ +4: +	blr + +	.globl get_pvr +get_pvr: +	mfspr	r3, PVR +	blr + + +/*------------------------------------------------------------------------------*/ + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * r3 = dest + * r4 = src + * r5 = length in bytes + * r6 = cachelinesize + */ +	.globl	relocate_code +relocate_code: +	mr	r1,  r3		/* Set new stack pointer in SRAM	*/ +	mr	r9,  r4		/* Save copy of global data pointer in SRAM */ +	mr	r10, r5		/* Save copy of monitor destination Address in SRAM */ + +	mr	r3,  r5				/* Destination Address	*/ +	lis	r4, CFG_MONITOR_BASE@h		/* Source      Address	*/ +	ori	r4, r4, CFG_MONITOR_BASE@l +	lis	r5, CFG_MONITOR_LEN@h		/* Length in Bytes	*/ +	ori	r5, r5, CFG_MONITOR_LEN@l + +	/* +	 * Fix GOT pointer: +	 * +	 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address +	 * +	 * Offset: +	 */ +	sub	r15, r10, r4 + +	/* First our own GOT */ +	add	r14, r14, r15 +	/* the the one used by the C code */ +	add	r30, r30, r15 + +	/* +	 * Now relocate code +	 */ + +	cmplw	cr1,r3,r4 +	addi	r0,r5,3 +	srwi.	r0,r0,2 +	beq	cr1,4f		/* In place copy is not necessary	*/ +	beq	4f		/* Protect against 0 count		*/ +	mtctr	r0 +	bge	cr1,2f + +	la	r8,-4(r4) +	la	r7,-4(r3) +1:	lwzu	r0,4(r8) +	stwu	r0,4(r7) +	bdnz	1b +	b	4f + +2:	slwi	r0,r0,2 +	add	r8,r4,r0 +	add	r7,r3,r0 +3:	lwzu	r0,-4(r8) +	stwu	r0,-4(r7) +	bdnz	3b + +4:	sync			 +	isync + +/* + * We are done. Do not return, instead branch to second part of board + * initialization, now running from RAM. + */ + +	addi	r0, r10, in_ram - _start + EXC_OFF_SYS_RESET +	mtlr	r0 +	blr + +in_ram: + +	/* +	 * Relocation Function, r14 point to got2+0x8000 +	 * +         * Adjust got2 pointers, no need to check for 0, this code +         * already puts a few entries in the table. +	 */ +	li	r0,__got2_entries@sectoff@l +	la	r3,GOT(_GOT2_TABLE_) +	lwz	r11,GOT(_GOT2_TABLE_) +	mtctr	r0 +	sub	r11,r3,r11 +	addi	r3,r3,-4 +1:	lwzu	r0,4(r3) +	add	r0,r0,r11 +	stw	r0,0(r3) +	bdnz	1b + +	/* +         * Now adjust the fixups and the pointers to the fixups +	 * in case we need to move ourselves again. +	 */ +2:	li	r0,__fixup_entries@sectoff@l +	lwz	r3,GOT(_FIXUP_TABLE_) +	cmpwi	r0,0 +	mtctr	r0 +	addi	r3,r3,-4 +	beq	4f +3:	lwzu	r4,4(r3) +	lwzux	r0,r4,r11 +	add	r0,r0,r11 +	stw	r10,0(r3) +	stw	r0,0(r4) +	bdnz	3b +4: +clear_bss: +	/* +	 * Now clear BSS segment +	 */ +	lwz	r3,GOT(.bss) +	lwz	r4,GOT(_end) +	cmplw	0, r3, r4 +	beq	6f + +	li	r0, 0 +5: +	stw	r0, 0(r3) +	addi	r3, r3, 4 +	cmplw	0, r3, r4 +	bne	5b +6: + +	mr	r3, r9		/* Global Data pointer		*/ +	mr	r4, r10		/* Destination Address		*/ +	bl	board_init_r + +	/* Problems accessing "end" in C, so do it here */ +	.globl	get_endaddr +get_endaddr: +	lwz	r3,GOT(_end) +	blr + +	/* +	 * Copy exception vector code to low memory +	 * +	 * r3: dest_addr +	 * r7: source address, r8: end address, r9: target address +	 */ +	.globl	trap_init +trap_init: +	lwz	r7, GOT(_start) +	lwz	r8, GOT(_end_of_vectors) + +	rlwinm	r9, r7, 0, 22, 31	/* _start & 0x3FF	*/ + +	cmplw	0, r7, r8 +	bgelr				/* return if r7>=r8 - just in case */ + +	mflr	r4			/* save link register		*/ +1: +	lwz	r0, 0(r7) +	stw	r0, 0(r9) +	addi	r7, r7, 4 +	addi	r9, r9, 4 +	cmplw	0, r7, r8 +	bne	1b + +	/* +	 * relocate `hdlr' and `int_return' entries +	 */ +	li	r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET +	li	r8, Alignment - _start + EXC_OFF_SYS_RESET +2: +	bl	trap_reloc +	addi	r7, r7, 0x100		/* next exception vector	*/ +	cmplw	0, r7, r8 +	blt	2b + +	li	r7, .L_Alignment - _start + EXC_OFF_SYS_RESET +	bl	trap_reloc + +	li	r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET +	bl	trap_reloc + +	li	r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET +	li	r8, SystemCall - _start + EXC_OFF_SYS_RESET +3: +	bl	trap_reloc +	addi	r7, r7, 0x100		/* next exception vector	*/ +	cmplw	0, r7, r8 +	blt	3b + +	li	r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET +	li	r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET +4: +	bl	trap_reloc +	addi	r7, r7, 0x100		/* next exception vector	*/ +	cmplw	0, r7, r8 +	blt	4b + +	mtlr	r4			/* restore link register	*/ +	blr + +	/* +	 * Function: relocate entries for one exception vector +	 */ +trap_reloc: +	lwz	r0, 0(r7)		/* hdlr ...			*/ +	add	r0, r0, r3		/*  ... += dest_addr		*/ +	stw	r0, 0(r7) + +	lwz	r0, 4(r7)		/* int_return ...		*/ +	add	r0, r0, r3		/*  ... += dest_addr		*/ +	stw	r0, 4(r7) + +	sync +	isync + +	blr diff --git a/cpu/mpc5xx/status_led.c b/cpu/mpc5xx/status_led.c new file mode 100644 index 000000000..f15bbe821 --- /dev/null +++ b/cpu/mpc5xx/status_led.c @@ -0,0 +1,161 @@ +/* + * (C) Copyright 2000-2002	Wolfgang Denk, DENX Software Engineering, wd@denx.de + * (C) Copyright 2003		Martin Winistoerfer, martinwinistoerfer@gmx.ch. + * + * 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 + */ + +/* + * File:		status_led.c + *  + * Discription:		Blink a board led to show boot progress. Led's + *			are connected via the MIOS module. + */ + +#include <common.h> +#include <mpc5xx.h> +#include <status_led.h> + +#ifdef CONFIG_STATUS_LED + +typedef struct { +	ulong	mask; +	int	state; +	int	period; +	int	cnt; +} led_dev_t; + +led_dev_t led_dev[] = { +    {	STATUS_LED_BIT, +	STATUS_LED_STATE, +	STATUS_LED_PERIOD, +	0, +    }, +#if defined(STATUS_LED_BIT1) +    {	STATUS_LED_BIT1, +	STATUS_LED_STATE1, +	STATUS_LED_PERIOD1, +	0, +    }, +#endif +#if defined(STATUS_LED_BIT2) +    {	STATUS_LED_BIT2, +	STATUS_LED_STATE2, +	STATUS_LED_PERIOD2, +	0, +    }, +#endif +#if defined(STATUS_LED_BIT3) +    {	STATUS_LED_BIT3, +	STATUS_LED_STATE3, +	STATUS_LED_PERIOD3, +	0, +    }, +#endif +}; + +#define MAX_LED_DEV	(sizeof(led_dev)/sizeof(led_dev_t)) + +static int status_led_init_done = 0; + +static void status_led_init (void) +{ +    volatile immap_t *immr = (immap_t *)CFG_IMMR; +    int i; + +    for (i=0; i<MAX_LED_DEV; ++i) { +	led_dev_t *ld = &led_dev[i]; +	 +	immr->STATUS_LED_DIR = STATUS_LED_BIT; + +#if (STATUS_LED_ACTIVE == 0) +	if (ld->state == STATUS_LED_ON) +		immr->STATUS_LED_DAT &= ~(ld->mask); +	else +		immr->STATUS_LED_DAT |=   ld->mask ; +#else +	if (ld->state == STATUS_LED_ON) +		immr->STATUS_LED_DAT |=   ld->mask ; +	else +		immr->STATUS_LED_DAT &= ~(ld->mask); +#endif +    } + +    status_led_init_done  = 1; +} + +void status_led_tick (ulong timestamp) +{ +    volatile immap_t *immr = (immap_t *)CFG_IMMR; +    int i; + +    if (!status_led_init_done) +	status_led_init(); + +    for (i=0; i<MAX_LED_DEV; ++i) { +	led_dev_t *ld = &led_dev[i]; + +	if (ld->state != STATUS_LED_BLINKING) +		continue; + +	if (++(ld->cnt) >= ld->period) { +		immr->STATUS_LED_DAT ^= ld->mask; +		ld->cnt -= ld->period; +	} +    } +} + +void status_led_set (int led, int state) +{ +    volatile immap_t *immr = (immap_t *)CFG_IMMR; +    led_dev_t *ld; + +    if (led < 0 || led >= MAX_LED_DEV) +	return; + +    if (!status_led_init_done) +	status_led_init(); + +    ld = &led_dev[led]; + +    switch (state) { +    default: +	return; +    case STATUS_LED_BLINKING: +	ld->cnt = 0;		/* always start with full period	*/ +	/* fall through */	/* always start with LED _ON_		*/ +    case STATUS_LED_ON: +#if (STATUS_LED_ACTIVE == 0) +	immr->STATUS_LED_DAT &= ~(ld->mask); +#else +	immr->STATUS_LED_DAT |=   ld->mask ; +#endif +	break; +    case STATUS_LED_OFF: +#if (STATUS_LED_ACTIVE == 0) +	immr->STATUS_LED_DAT |=   ld->mask ; +#else +	immr->STATUS_LED_DAT &= ~(ld->mask); +#endif +	break; +    } +    ld->state = state; +} + +#endif	/* CONFIG_STATUS_LED */ diff --git a/cpu/mpc5xx/traps.c b/cpu/mpc5xx/traps.c new file mode 100644 index 000000000..41939c15d --- /dev/null +++ b/cpu/mpc5xx/traps.c @@ -0,0 +1,231 @@ +/* + * linux/arch/ppc/kernel/traps.c + * + * Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org) + * + * Modified by Cort Dougan (cort@cs.nmt.edu) + * and Paul Mackerras (paulus@cs.anu.edu.au) + * + * (C) Copyright 2000 + * 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 + */ + +/* + * This file handles the architecture-dependent parts of hardware exceptions + */ + +#include <common.h> +#include <command.h> +#include <asm/processor.h> + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +int (*debugger_exception_handler)(struct pt_regs *) = 0; +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) +extern void do_bedbug_breakpoint(struct pt_regs *); +#endif + +/* Returns 0 if exception not found and fixup otherwise.  */ +extern unsigned long search_exception_table(unsigned long); + +/* THIS NEEDS CHANGING to use the board info structure. +*/ +#define END_OF_MEM	0x0001000 + + +/* + * Print stack backtrace + */ +void print_backtrace(unsigned long *sp) +{ +	int cnt = 0; +	unsigned long i; + +	printf("Call backtrace: "); +	while (sp) { +		if ((uint)sp > END_OF_MEM) +			break; + +		i = sp[1]; +		if (cnt++ % 7 == 0) +			printf("\n"); +		printf("%08lX ", i); +		if (cnt > 32) break; +		sp = (unsigned long *)*sp; +	} +	printf("\n"); +} + +/* + * Print current registers + */ +void show_regs(struct pt_regs * regs) +{ +	int i; +	printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n", +	       regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar); +	printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n", +	       regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0, +	       regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0, +	       regs->msr&MSR_IR ? 1 : 0, +	       regs->msr&MSR_DR ? 1 : 0); + +	printf("\n"); +	for (i = 0;  i < 32;  i++) { +		if ((i % 8) == 0) +		{ +			printf("GPR%02d: ", i); +		} + +		printf("%08lX ", regs->gpr[i]); +		if ((i % 8) == 7) +		{ +			printf("\n"); +		} +	} +} + + +/* + * General exception handler routine + */ +void _exception(int signr, struct pt_regs *regs) +{ +	show_regs(regs); +	print_backtrace((unsigned long *)regs->gpr[1]); +	panic("Exception in kernel pc %lx signal %d",regs->nip,signr); +} + +/* + * Machine check exception handler routine + */ +void MachineCheckException(struct pt_regs *regs) +{ +	unsigned long fixup; + +	/* Probing PCI using config cycles cause this exception +	 * when a device is not present.  Catch it and return to +	 * the PCI exception handler. +	 */ +	if ((fixup = search_exception_table(regs->nip)) != 0) { +		regs->nip = fixup; +		return; +	} + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +	if (debugger_exception_handler && (*debugger_exception_handler)(regs)) +		return; +#endif + +	printf("Machine check in kernel mode.\n"); +	printf("Caused by (from msr): "); +	printf("regs %p ",regs); +	switch( regs->msr & 0x0000F000) +	{ +	case (1<<12) : +		printf("Machine check signal\n"); +		break; +	case (1<<13) : +		printf("Transfer error ack signal\n"); +		break; +	case (1<<14) : +		printf("Data parity signal\n"); +		break; +	case (1<<15) : +		printf("Address parity signal\n"); +		break; +	default: +		printf("Unknown values in msr\n"); +	} +	show_regs(regs); +	print_backtrace((unsigned long *)regs->gpr[1]); +	panic("machine check"); +} + +/* + * Alignment exception handler routine + */ +void AlignmentException(struct pt_regs *regs) +{ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +	if (debugger_exception_handler && (*debugger_exception_handler)(regs)) +		return; +#endif +	show_regs(regs); +	print_backtrace((unsigned long *)regs->gpr[1]); +	panic("Alignment Exception"); +} + +/* + * Program check exception handler routine + */ +void ProgramCheckException(struct pt_regs *regs) +{ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +	if (debugger_exception_handler && (*debugger_exception_handler)(regs)) +		return; +#endif +	show_regs(regs); +	print_backtrace((unsigned long *)regs->gpr[1]); +	panic("Program Check Exception"); +} + +/* + * Software emulation exception handler routine + */ +void SoftEmuException(struct pt_regs *regs) +{ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +	if (debugger_exception_handler && (*debugger_exception_handler)(regs)) +		return; +#endif +	show_regs(regs); +	print_backtrace((unsigned long *)regs->gpr[1]); +	panic("Software Emulation Exception"); +} + + +/* + * Unknown exception handler routine + */ +void UnknownException(struct pt_regs *regs) +{ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +	if (debugger_exception_handler && (*debugger_exception_handler)(regs)) +		return; +#endif +	printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", +	       regs->nip, regs->msr, regs->trap); +	_exception(0, regs); +} + +/* + * Debug exception handler routine + */ +void DebugException(struct pt_regs *regs) +{ +	printf("Debugger trap at @ %lx\n", regs->nip ); +  	show_regs(regs); +#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) +  	do_bedbug_breakpoint( regs ); +#endif +} diff --git a/doc/README.cmi b/doc/README.cmi new file mode 100644 index 000000000..48052b867 --- /dev/null +++ b/doc/README.cmi @@ -0,0 +1,84 @@ + +Summary: +======== + +This file contains information about the cmi board configuration. +Please see cmi_mpc5xx_config for further details. The cmi board is  +a customer specific board but should work with small modifications  +on every board which has a MPC5xx and either a 28F128J3A,  +28F320J3A or 28F640J3A Intel flash mounted. + +Board Discription: +================== + +* Motorola MPC555 +* RS232 connection +* Intel flash 28F640J3A +* Micron SRAM 1M +* Altera PLD +      +Bootstrap: +========== + +In contrast to the usual boot sequence used in U-Boot, on the +cmi board we don't boot from the external flash directly. +Because of we use a 16-bit flash and don't sample a RCW +from the data bus to set the startup buswidth to 16-bit.  +Unfortunatly the default width, sampled from the default RCW +is 32-bit. For this reason we burn the proper RCW into the +internal flash shadow location and boot after power-on or +reset from the internal flash and then branch to 0x02000100 +where the U-Boot reset vector handler is located. + +Memory Map: +=========== + +Memory Map after relocation: + +    0x0000 0000		CFG_SDRAM_BASE  +	  : +    0x000F 9FFF +	  : +          : +    0x0100 0000		CFG_IMMR (Internal memory map base adress)	     +	  : +    0x0130 7FFF +	  : +    	  : +    0x0200 0000		CFG_FLASH_BASE +	  : +    0x027C FFFF +	  : +	  : +    0x0300 0000		PLD_BASE + +Flash Partition: +     +    0x0200 0000		Block 0 and 1 contain U-Boot except  +	  :		environment +	  : +    0x0201 FFFF +    0x0202 0000		Block 2 contains environment (.ppcenv) +	  : +    0x0202 FFFF  +  +See README file for futher information about U-Boot relocation +and partitioning. + +Tested Features: +================ + +* U-Boot commands: go, loads, loadb, all memory features, printenv, +  setenv, saveenv, protect, erase, fli, bdi, mtest, reset, version, +  coninfo, help (see configuration file for available commands) +   +* Blinking led to indicate boot process + +Added or Changed Files: +======================= + +u-boot-0.2.0/board/cmi/* +u-boot-0.2.0/include/configs/cmi_mpc5xx.h + +Regards, +Martin diff --git a/doc/README.mpc5xx b/doc/README.mpc5xx new file mode 100644 index 000000000..2c1a29321 --- /dev/null +++ b/doc/README.mpc5xx @@ -0,0 +1,48 @@ + +Summary: +======== + +This file contains information about the port of U-Boot to the +Motorola mpc5xx series of CPUs. Most of this code is taken from +existing code mainly from the mpc8xx port. In contrast to mpc8xx, +the mpc5xx has no CPM, MMU and cache facilities.  + +The implemented features have been tested on the cmi board, a  +customer specific board (see README.cmi).  + +Hence this port is only tested on the cmi board further possible  +tests on other boards will be very valuable. +   +Not Tested Features: +==================== + +* System calls +* Interrupts + +Added or Changed Files: +======================= + +u-boot-0.2.0/common/cmd_boot.c +u-boot-0.2.0/common/cmd_reginfo.c +u-boot-0.2.0/common/environment.c +u-boot-0.2.0/cpu/mpc5xx/* +u-boot-0.2.0/include/cmd_reginfo.h +u-boot-0.2.0/include/common.h +u-boot-0.2.0/include/ppc_asm.tmpl +u-boot-0.2.0/include/watchdog.h +u-boot-0.2.0/include/mpc5xx.h +u-boot-0.2.0/include/status_led.h +u-boot-0.2.0/include/asm-ppc/u-boot.h +u-boot-0.2.0/include/asm-ppc/5xx_immap.h +u-boot-0.2.0/lib_ppc/board.c +u-boot-0.2.0/lib_ppc/cache.c +u-boot-0.2.0/lib_ppc/time.c +u-boot-0.2.0/Makefile +u-boot-0.2.0/CREDITS +u-boot-0.2.0/doc/README.mpc5xx +u-boot-0.2.0/doc/README.cmi +u-boot-0.2.0/README +u-boot-0.2.0/MAKEALL + +Regards, +Martin diff --git a/include/asm-ppc/5xx_immap.h b/include/asm-ppc/5xx_immap.h new file mode 100644 index 000000000..ffff975c9 --- /dev/null +++ b/include/asm-ppc/5xx_immap.h @@ -0,0 +1,440 @@ +/* + * (C) Copyright 2003 + * Martin Winistoerfer, martinwinistoerfer@gmx.ch. + * + * 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,  + */ + +/* + * File:		5xx_immap.h + *  + * Discription:		MPC555 Internal Memory Map + *  + */ +  +#ifndef __IMMAP_5XX__ +#define __IMMAP_5XX__ + +/* System Configuration Registers. +*/ +typedef	struct sys_conf { +        uint sc_siumcr; +        uint sc_sypcr; +        char res1[6]; +        ushort sc_swsr; +        uint sc_sipend; +        uint sc_simask; +        uint sc_siel; +        uint sc_sivec; +        uint sc_tesr; +        uint sc_sgpiodt1; +        uint sc_sgpiodt2; +        uint sc_sgpiocr; +        uint sc_emcr; +        uint sc_res1aa; +        uint sc_res1ab; +        uint sc_pdmcr; +        char res3[192]; +} sysconf5xx_t; + + +/* Memory Controller Registers. +*/ +typedef struct	mem_ctlr { +        uint memc_br0; +        uint memc_or0; +        uint memc_br1; +        uint memc_or1; +        uint memc_br2; +        uint memc_or2; +        uint memc_br3; +        uint memc_or3; +        char res1[32]; +        uint memc_dmbr; +        uint memc_dmor;  +        char res2[48];         +        ushort memc_mstat; +        ushort memc_res4a; +        char res3[132]; +} memctl5xx_t; + +/* System Integration Timers. +*/ +typedef struct	sys_int_timers { +        ushort sit_tbscr; +        char res1[2]; +        uint sit_tbref0; +        uint sit_tbref1; +        char res2[20]; +        ushort sit_rtcsc; +        char res3[2]; +        uint sit_rtc; +        uint sit_rtsec; +        uint sit_rtcal; +        char res4[16]; +        ushort sit_piscr; +        char res5[2]; +        uint sit_pitc; +        uint sit_pitr; +        char res6[52]; +} sit5xx_t; + +/* Clocks and Reset +*/ +typedef struct clk_and_reset { +        uint car_sccr; +        uint car_plprcr; +        ushort car_rsr; +        ushort car_res7a; +        ushort car_colir; +        ushort car_res7b; +        ushort car_vsrmcr; +        ushort car_res7c; +        char res1[108]; + +} car5xx_t; + +#define TBSCR_TBE		((ushort)0x0001) + +/* System Integration Timer Keys +*/ +typedef struct sitk { +        uint sitk_tbscrk; +        uint sitk_tbref0k; +        uint sitk_tbref1k; +        uint sitk_tbk; +        char res1[16]; +        uint sitk_rtcsck; +        uint sitk_rtck; +        uint sitk_rtseck; +        uint sitk_rtcalk; +        char res2[16]; +        uint sitk_piscrk; +        uint sitk_pitck; +        char res3[56]; +} sitk5xx_t; + +/* Clocks and Reset Keys. +*/ +typedef struct cark { +	uint	cark_sccrk; +	uint	cark_plprcrk; +	uint	cark_rsrk; +	char	res1[1140]; +} cark8xx_t; + +/* The key to unlock registers maintained by keep-alive power. +*/ +#define KAPWR_KEY	((unsigned int)0x55ccaa33) + +/* Flash Configuration +*/ +typedef struct fl { +        uint fl_cmfmcr; +        uint fl_cmftst; +        uint fl_cmfctl; +        char res1[52]; +} fl5xx_t; + +/* Dpram Control +*/ +typedef struct dprc {		 +        ushort dprc_dptmcr; +        ushort dprc_ramtst; +        ushort dprc_rambar; +        ushort dprc_misrh; +        ushort dprc_misrl; +        ushort dprc_miscnt; +} dprc5xx_t; + +/* Time Processor Unit +*/ +typedef struct tpu { +        ushort tpu_tpumcr; +        ushort tpu_tcr; +        ushort tpu_dscr; +        ushort tpu_dssr; +        ushort tpu_ticr; +        ushort tpu_cier; +        ushort tpu_cfsr0; +        ushort tpu_cfsr1; +        ushort tpu_cfsr2; +        ushort tpu_cfsr3; +        ushort tpu_hsqr0; +        ushort tpu_hsqr1; +        ushort tpu_hsrr0; +        ushort tpu_hsrr1; +        ushort tpu_cpr0; +        ushort tpu_cpr1; +        ushort tpu_cisr; +        ushort tpu_lr; +        ushort tpu_sglr; +        ushort tpu_dcnr; +        ushort tpu_tpumcr2; +        ushort tpu_tpumcr3; +        ushort tpu_isdr; +        ushort tpu_iscr; +        char   res1[208]; +        char   tpu[16][16]; +        char   res2[512]; +} tpu5xx_t; + +/* QADC +*/ +typedef struct qadc { +        ushort qadc_64mcr; +        ushort qadc_64test; +        ushort qadc_64int; +        u_char  qadc_portqa; +        u_char  qadc_portqb; +        ushort qadc_ddrqa; +        ushort qadc_qacr0; +        ushort qadc_qacr1; +        ushort qadc_qacr2; +        ushort qadc_qasr0; +        ushort qadc_qasr1; +        char   res1[492]; +       /* command convertion word table */ +        ushort qadc_ccw[64]; +       /* result word table, unsigned right justified */ +        ushort qadc_rjurr[64]; +       /* result word table, signed left justified */ +        ushort qadc_ljsrr[64]; +       /* result word table, unsigned left justified */ +        ushort qadc_ljurr[64]; +} qadc5xx_t; + +/* QSMCM +*/ +typedef struct qsmcm { +        ushort qsmcm_qsmcr; +        ushort qsmcm_qtest; +        ushort qsmcm_qdsci_il; +        ushort qsmcm_qspi_il; +        ushort qsmcm_scc1r0; +        ushort qsmcm_scc1r1; +        ushort qsmcm_sc1sr; +        ushort qsmcm_sc1dr; +        char   res1[2]; +        char   res2[2]; +        ushort qsmcm_portqs; +        u_char qsmcm_pqspar; +        u_char qsmcm_ddrqs; +        ushort qsmcm_spcr0; +        ushort qsmcm_spcr1; +        ushort qsmcm_spcr2; +        u_char qsmcm_spcr3; +        u_char qsmcm_spsr; +        ushort qsmcm_scc2r0; +        ushort qsmcm_scc2r1; +        ushort qsmcm_sc2sr; +        ushort qsmcm_sc2dr; +        ushort qsmcm_qsci1cr; +        ushort qsmcm_qsci1sr; +        ushort qsmcm_sctq[16]; +        ushort qsmcm_scrq[16]; +        char   res3[212]; +        ushort qsmcm_recram[32]; +        ushort qsmcm_tranram[32]; +        u_char qsmcm_comdram[32]; +        char   res[3616]; +} qsmcm5xx_t; + + +/* MIOS +*/ + +typedef struct mios { +        ushort mios_mpwmsm0perr;                 /* mpwmsm0 */ +        ushort mios_mpwmsm0pulr; +        ushort mios_mpwmsm0cntr; +        ushort mios_mpwmsm0scr; +        ushort mios_mpwmsm1perr;                 /* mpwmsm1 */ +        ushort mios_mpwmsm1pulr; +        ushort mios_mpwmsm1cntr; +        ushort mios_mpwmsm1scr; +        ushort mios_mpwmsm2perr;                 /* mpwmsm2 */ +        ushort mios_mpwmsm2pulr; +        ushort mios_mpwmsm2cntr; +        ushort mios_mpwmsm2scr; +        ushort mios_mpwmsm3perr;                 /* mpwmsm3 */ +        ushort mios_mpwmsm3pulr; +        ushort mios_mpwmsm3cntr; +        ushort mios_mpwmsm3scr; +        char res1[16]; +        ushort mios_mmcsm6cnt;                   /* mmcsm6 */ +        ushort mios_mmcsm6mlr; +        ushort mios_mmcsm6scrd, mmcsm6scr; +        char res2[32]; +        ushort mios_mdasm11ar;                   /* mdasm11 */ +        ushort mios_mdasm11br; +        ushort mios_mdasm11scrd, mdasm11scr; +        ushort mios_mdasm12ar;                   /* mdasm12 */ +        ushort mios_mdasm12br; +        ushort mios_mdasm12scrd, mdasm12scr; +        ushort mios_mdasm13ar;                   /* mdasm13 */ +        ushort mios_mdasm13br; +        ushort mios_mdasm13scrd, mdasm13scr; +        ushort mios_mdasm14ar;                   /* mdasm14 */ +        ushort mios_mdasm14br; +        ushort mios_mdasm14scrd, mdasm14scr; +        ushort mios_mdasm15ar;                   /* mdasm15 */ +        ushort mios_mdasm15br; +        ushort mios_mdasm15scrd, mdasm15scr; +        ushort mios_mpwmsm16perr;                /* mpwmsm16 */ +        ushort mios_mpwmsm16pulr; +        ushort mios_mpwmsm16cntr; +        ushort mios_mpwmsm16scr; +        ushort mios_mpwmsm17perr;                /* mpwmsm17 */ +        ushort mios_mpwmsm17pulr; +        ushort mios_mpwmsm17cntr; +        ushort mios_mpwmsm17scr; +        ushort mios_mpwmsm18perr;                /* mpwmsm18 */ +        ushort mios_mpwmsm18pulr; +        ushort mios_mpwmsm18cntr; +        ushort mios_mpwmsm18scr; +        ushort mios_mpwmsm19perr;                /* mpwmsm19 */ +        ushort mios_mpwmsm19pulr; +        ushort mios_mpwmsm19cntr; +        ushort mios_mpwmsm19scr; +        char res3[16]; +        ushort mios_mmcsm22cnt;                  /* mmcsm22 */ +        ushort mios_mmcsm22mlr; +        ushort mios_mmcsm22scrd, mmcsm22scr; +        char res4[32]; +        ushort mios_mdasm27ar;                   /* mdasm27 */ +        ushort mios_mdasm27br; +        ushort mios_mdasm27scrd, mdasm27scr; +        ushort mios_mdasm28ar;                   /*mdasm28 */ +        ushort mios_mdasm28br; +        ushort mios_mdasm28scrd, mdasm28scr; +        ushort mios_mdasm29ar;                   /* mdasm29 */ +        ushort mios_mdasm29br; +        ushort mios_mdasm29scrd, mdasm29scr; +        ushort mios_mdasm30ar;                   /* mdasm30 */ +        ushort mios_mdasm30br; +        ushort mios_mdasm30scrd, mdasm30scr; +        ushort mios_mdasm31ar;                   /* mdasm31 */ +        ushort mios_mdasm31br; +        ushort mios_mdasm31scrd, mdasm31scr; +        ushort mios_mpiosm32dr; +        ushort mios_mpiosm32ddr; +        char res5[1788]; +        ushort mios_mios1tpcr; +        char mios_res13[2]; +        ushort mios_mios1vnr; +        ushort mios_mios1mcr; +        char res6[12]; +        ushort mios_res42z; +        ushort mios_mcpsmscr; +        char res7[1000]; +        ushort mios_mios1sr0; +        char res12[2]; +        ushort mios_mios1er0; +        ushort mios_mios1rpr0; +        char res8[40]; +        ushort mios_mios1lvl0; +        char res9[14]; +        ushort mios_mios1sr1; +        char res10[2]; +        ushort mios_mios1er1; +        ushort mios_mios1rpr1; +        char res11[40]; +        ushort mios_mios1lvl1; +        char res13[1038]; +} mios5xx_t; + +/* Toucan Module +*/ +typedef struct tcan { +        ushort tcan_tcnmcr; +        ushort tcan_cantcr; +        ushort tcan_canicr; +        u_char tcan_canctrl0; +        u_char tcan_canctrl1; +        u_char tcan_presdiv; +        u_char tcan_canctrl2; +        ushort tcan_timer; +        char res1[4]; +        ushort tcan_rxgmskhi; +        ushort tcan_rxgmsklo; +        ushort tcan_rx14mskhi; +        ushort tcan_rx14msklo; +        ushort tcan_rx15mskhi; +        ushort tcan_rx15msklo; +        char res2[4]; +        ushort tcan_estat; +        ushort tcan_imask; +        ushort tcan_iflag; +        u_char tcan_rxectr; +        u_char tcan_txectr; +        char res3[88]; +        struct { +               ushort scr; +               ushort id_high; +               ushort id_low; +               u_char data[8]; +	           char res4[2]; +	    } tcan_mbuff[16]; +	    char res5[640]; +} tcan5xx_t; + +/* UIMB +*/ +typedef struct uimb { +        uint uimb_umcr; +        char res1[12]; +        uint uimb_utstcreg; +        char res2[12]; +        uint uimb_uipend; +} uimb5xx_t; + + + +/* Internal Memory Map MPC555 +*/ +typedef struct immap { +        char               res1[262144];       	/* CMF Flash A 256 Kbytes */ +        char               res2[196608];       	/* CMF Flash B 192 Kbytes */ +        char               res3[2670592];      	/* Reserved for Flash */ +        sysconf5xx_t       im_siu_conf;        	/* SIU Configuration */ +        memctl5xx_t	   im_memctl;		/* Memory Controller */ +        sit5xx_t           im_sit;		/* System Integration Timers */ +        car5xx_t	   im_clkrst;		/* Clocks and Reset */ +        sitk5xx_t          im_sitk;            	/* System Integration Timer Keys*/ +        cark8xx_t          im_clkrstk;         	/* Clocks and Resert Keys */ +        fl5xx_t	           im_fla;	        /* Flash Module A */ +        fl5xx_t	           im_flb;	        /* Flash Module B */ +        char               res4[14208];        	/* Reserved for SIU */ +        dprc5xx_t	   im_dprc;            	/* Dpram Control Register */ +        char               res5[8180];         	/* Reserved */ +        char               dptram[6144];       	/* Dptram */ +        char               res6[2048];         	/* Reserved */ +        tpu5xx_t	   im_tpua;		/* Time Proessing Unit A */ +        tpu5xx_t	   im_tpub;  	      	/* Time Processing Unit B */ +        qadc5xx_t	   im_qadca;           	/* QADC A */ +        qadc5xx_t	   im_qadcb;           	/* QADC B */ +        qsmcm5xx_t	   im_qsmcm;		/* SCI and SPI */ +        mios5xx_t      	   im_mios;		/* MIOS */ +        tcan5xx_t          im_tcana;           	/* Toucan A */ +        tcan5xx_t          im_tcanb;	       	/* Toucan B */ +        char               res7[1792];         	/* Reserved */ +        uimb5xx_t          im_uimb;	        /* UIMB */ +} immap_t; + +#endif /* __IMMAP_5XX__ */ diff --git a/include/asm-ppc/u-boot.h b/include/asm-ppc/u-boot.h index 78744e28f..5e8f4b577 100644 --- a/include/asm-ppc/u-boot.h +++ b/include/asm-ppc/u-boot.h @@ -38,7 +38,7 @@ typedef struct bd_info {  	unsigned long	bi_flashoffset; /* reserved area for startup monitor */  	unsigned long	bi_sramstart;	/* start of SRAM memory */  	unsigned long	bi_sramsize;	/* size	 of SRAM memory */ -#if defined(CONFIG_8xx) || defined(CONFIG_8260) +#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260)  	unsigned long	bi_immr_base;	/* base of IMMR register */  #endif  	unsigned long	bi_bootflags;	/* boot / reboot flag (for LynxOS) */ diff --git a/include/cmd_reginfo.h b/include/cmd_reginfo.h index d4e995d1a..6a67b36e2 100644 --- a/include/cmd_reginfo.h +++ b/include/cmd_reginfo.h @@ -24,7 +24,7 @@  #ifndef	_CMD_REGINFO_H_  #define	_CMD_REGINFO_H_ -#if (defined(CONFIG_8xx) || defined(CONFIG_405GP)) && \ +#if (defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_405GP)) && \      (CONFIG_COMMANDS & CFG_CMD_REGINFO)  #define	CMD_TBL_REGINFO	MK_CMD_TBL_ENTRY(					\  	"reginfo",	3,	2,	1,	do_reginfo,			\ @@ -35,6 +35,6 @@ int do_reginfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);  #else  #define CMD_TBL_REGINFO -#endif	/* CONFIG_8xx && CFG_CMD_REGINFO */ +#endif	/* CONFIG_COMMANDS && CFG_CMD_REGINFO */  #endif	/* _CMD_REGINFO_H_ */ diff --git a/include/common.h b/include/common.h index ac2a57d9a..0d7f79a44 100644 --- a/include/common.h +++ b/include/common.h @@ -43,6 +43,8 @@ typedef volatile unsigned char	vu_char;  #endif  #ifdef	CONFIG_8xx  #include <asm/8xx_immap.h> +#elif defined(CONFIG_5xx) +#include <asm/5xx_immap.h>  #elif defined(CONFIG_8260)  #include <asm/immap_8260.h>  #endif @@ -241,7 +243,8 @@ int testdram(void);  #endif /* CFG_DRAM_TEST */  /* $(CPU)/start.S */ -#ifdef	CONFIG_8xx +#if defined(CONFIG_5xx)	|| \ +    defined(CONFIG_8xx)  uint	get_immr      (uint);  #endif  uint	get_pvr	      (void); @@ -370,6 +373,7 @@ ulong	video_setmem (ulong);  /* ppc/cache.c */  void	flush_cache   (unsigned long, unsigned long); +  /* ppc/ticks.S */  unsigned long long get_ticks(void);  void	wait_ticks    (unsigned long); diff --git a/include/configs/cmi_mpc5xx.h b/include/configs/cmi_mpc5xx.h new file mode 100644 index 000000000..e8b3eb5d8 --- /dev/null +++ b/include/configs/cmi_mpc5xx.h @@ -0,0 +1,256 @@ +/* + * (C) Copyright 2003 + * Martin Winistoerfer, martinwinistoerfer@gmx.ch. + * + * 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,  + */ + +/* + * File:		cmi_mpc5xx.h + *  + * Discription:		Config header file for cmi  + * 			board  using an MPC5xx CPU + * + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + */ + +#define CONFIG_MPC555		1		/* This is an MPC555 CPU		*/ +#define CONFIG_CMI		1		/* Using the customized cmi board 	*/ + +/* Serial Console Configuration */ +#define	CONFIG_5xx_CONS_SCI1 +#undef	CONFIG_5xx_CONS_SCI2 + +#define CONFIG_BAUDRATE		57600 + +#define CONFIG_COMMANDS		(CFG_CMD_MEMORY | CFG_CMD_LOADB | CFG_CMD_REGINFO | 		\ +				 CFG_CMD_FLASH | CFG_CMD_LOADS | CFG_CMD_ASKENV |   		\ +				 CFG_CMD_BDI | CFG_CMD_CONSOLE | CFG_CMD_ENV | CFG_CMD_RUN |	\ +				 CFG_CMD_IMI) + +/* This must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include <cmd_confdefs.h> + +#if 0 +#define CONFIG_BOOTDELAY	-1		/* autoboot disabled			*/ +#else +#define CONFIG_BOOTDELAY	5		/* autoboot after 5 seconds		*/ +#endif +#define CONFIG_BOOTCOMMAND	"go 02034004" 	/* autoboot command			*/ + +#define CONFIG_BOOTARGS		""		/* Assuming OS Image in 4 flash sector at offset 4004 */ + +#define CONFIG_WATCHDOG				/* turn on platform specific watchdog 	*/ + +#define CONFIG_STATUS_LED	1		/* Enable status led */  + +#define CONFIG_LOADS_ECHO	1		/* Echo on for serial download */ + +/* + * 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	0x00000000	/* memtest works on		*/ +#define CFG_MEMTEST_END		0x000fa000	/* 1 MB in SRAM			*/ + +#define	CFG_LOAD_ADDR		0x100000	/* default load address		*/ + +#define	CFG_HZ			1000		/* Decrementer freq: 1 ms ticks	*/ + +#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200, 1250000 } + + +/* + * Low Level Configuration Settings + */ + +/* + * Internal Memory Mapped (This is not the IMMR content) + */ +#define CFG_IMMR		0x01000000				/* Physical start adress of internal memory map */ + +/* + * Definitions for initial stack pointer and data area + */ +#define CFG_INIT_RAM_ADDR	(CFG_IMMR + 0x003f9800)      		/* Physical start adress of internal MPC555 writable RAM */        +#define	CFG_INIT_RAM_END	(CFG_IMMR + 0x003fffff)       		/* Physical end adress of internal MPC555 used RAM area	*/ +#define	CFG_GBL_DATA_SIZE	64					/* Size in bytes reserved for initial global data */ +#define CFG_GBL_DATA_OFFSET	((CFG_INIT_RAM_END - CFG_INIT_RAM_ADDR) - CFG_GBL_DATA_SIZE) /* Offset from the beginning of ram */ +#define	CFG_INIT_SP_ADDR	0x013fa000				/* Physical start adress of inital stack */ + +/* + * Start addresses for the final memory configuration + * Please note that CFG_SDRAM_BASE _must_ start at 0 + */ +#define	CFG_SDRAM_BASE		0x00000000	/* Monitor won't change memory map 			*/ +#define CFG_FLASH_BASE		0x02000000	/* External flash */ +#define PLD_BASE		0x03000000	/* PLD  */ +#define ANYBUS_BASE		0x03010000	/* Anybus Module */ + +#define CFG_RESET_ADRESS	0x01000000	/* Adress which causes reset */ +#define	CFG_MONITOR_BASE	CFG_FLASH_BASE	/* TEXT_BASE is defined in the board config.mk file. 	*/ +						/* This adress is given to the linker with -Ttext to 	*/ +						/* locate the text section at this adress. 		*/ +#define	CFG_MONITOR_LEN		(192 << 10)	/* Reserve 192 kB for Monitor				*/ +#define	CFG_MALLOC_LEN		(64 << 10)	/* Reserve 128 kB for malloc()				*/ + +/* + * 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		*/ + + +/*----------------------------------------------------------------------- + * FLASH organization  + *----------------------------------------------------------------------- + *  + */ + +#define CFG_MAX_FLASH_BANKS	1		/* Max number of memory banks		*/ +#define CFG_MAX_FLASH_SECT	64		/* Max number of sectors on one chip 	*/ +#define CFG_FLASH_ERASE_TOUT	180000		/* Timeout for Flash Erase (in ms) 	*/ +#define CFG_FLASH_WRITE_TOUT	600		/* Timeout for Flash Write (in ms) 	*/ +#define CFG_FLASH_PROTECTION    1		/* Physically section protection on	*/ + +#define	CFG_ENV_IS_IN_FLASH	1 + +#ifdef	CFG_ENV_IS_IN_FLASH +#define CFG_ENV_OFFSET		0x00020000		/* Environment starts at this adress 	*/ +#define	CFG_ENV_SIZE		0x00010000		/* Set whole sector as env 		*/ +#endif + +/*----------------------------------------------------------------------- + * SYPCR - System Protection Control			 + * SYPCR can only be written once after reset! + *----------------------------------------------------------------------- + * SW Watchdog freeze + */ +#if defined(CONFIG_WATCHDOG) +#define CFG_SYPCR	(SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | \ +			 SYPCR_SWE | SYPCR_SWRI| SYPCR_SWP) +#else +#define CFG_SYPCR	(SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | \ +			 SYPCR_SWP)		 +#endif	/* CONFIG_WATCHDOG */ + +/*----------------------------------------------------------------------- + * TBSCR - Time Base Status and Control + *----------------------------------------------------------------------- + * Clear Reference Interrupt Status, Timebase freezing enabled + */ +#define CFG_TBSCR	(TBSCR_REFA | TBSCR_REFB | TBSCR_TBF) + +/*----------------------------------------------------------------------- + * PISCR - Periodic Interrupt Status and Control + *----------------------------------------------------------------------- + * Clear Periodic Interrupt Status, Interrupt Timer freezing enabled + */ +#define CFG_PISCR	(PISCR_PITF) + +/*----------------------------------------------------------------------- + * SCCR - System Clock and reset Control Register + *----------------------------------------------------------------------- + * Set clock output, timebase and RTC source and divider, + * power management and some other internal clocks + */ +#define SCCR_MASK	SCCR_EBDF00 +#define CFG_SCCR	(SCCR_TBS     | SCCR_RTDIV    | SCCR_RTSEL    | \ +			 SCCR_COM00   | SCCR_DFNL000 | SCCR_DFNH000) + +/*----------------------------------------------------------------------- + * SIUMCR - SIU Module Configuration + *----------------------------------------------------------------------- + * Data show cycle + */ +#define CFG_SIUMCR	(SIUMCR_DBGC00)		/* Disable data show cycle 	*/ + +/*----------------------------------------------------------------------- + * PLPRCR - PLL, Low-Power, and Reset Control Register + *----------------------------------------------------------------------- + * Set all bits to 40 Mhz + *  + */ +#define CFG_OSC_CLK   	((uint)4000000) 	/* Oscillator clock is 4MHz 	*/ +#define CFG_PLPRCR	(PLPRCR_MF_9 | PLPRCR_DIVF_0) +	 + +/*----------------------------------------------------------------------- + * UMCR - UIMB Module Configuration Register + *----------------------------------------------------------------------- + *  + */ +#define CFG_UMCR	(UMCR_FSPEED) 		/* IMB clock same as U-bus 	*/ + +/*----------------------------------------------------------------------- + * ICTRL - I-Bus Support Control Register + */ +#define CFG_ICTRL	(ICTRL_ISCT_SER_7) 	/* Take out of serialized mode 	*/  + +/*----------------------------------------------------------------------- + * USIU - Memory Controller Register + *-----------------------------------------------------------------------  + */ + +#define CFG_BR0_PRELIM		(CFG_FLASH_BASE | BR_V | BR_BI | BR_PS_16)		 +#define CFG_OR0_PRELIM		(OR_ADDR_MK_FF | OR_SCY_3) +#define CFG_BR1_PRELIM		(ANYBUS_BASE) +#define CFG_OR1_PRELIM		(OR_ADDR_MK_FFFF | OR_SCY_1 | OR_ETHR) +#define CFG_BR2_PRELIM		(CFG_SDRAM_BASE | BR_V | BR_PS_32) +#define CFG_OR2_PRELIM		(OR_ADDR_MK_FF) +#define CFG_BR3_PRELIM		(PLD_BASE | BR_V | BR_BI | BR_LBDIR | BR_PS_8) +#define CFG_OR3_PRELIM		(OR_ADDR_MK_FF | OR_TRLX | OR_BSCY | OR_SCY_8 | \ +			 	 OR_ACS_10 | OR_ETHR | OR_CSNT) + +#define FLASH_BASE0_PRELIM	CFG_FLASH_BASE	/* We don't realign the flash	*/ + +/*----------------------------------------------------------------------- + * DER - Timer Decrementer  + *----------------------------------------------------------------------- + * Initialise to zero + */ +#define CFG_DER			0x00000000 + + +/* + * Internal Definitions + * + * Boot Flags + */ +#define	BOOTFLAG_COLD	0x01			/* Normal Power-On: Boot from FLASH	*/ +#define BOOTFLAG_WARM	0x02			/* Software reboot			*/ + +#endif	/* __CONFIG_H */ diff --git a/include/mpc5xx.h b/include/mpc5xx.h new file mode 100644 index 000000000..8541ef6f7 --- /dev/null +++ b/include/mpc5xx.h @@ -0,0 +1,180 @@ +/* + * (C) Copyright 2003 + * Martin Winistoerfer, martinwinistoerfer@gmx.ch. + * + * 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 + */ + +/* + * File:		mpc5xx.h + *  + * Discription:		mpc5xx specific definitions + * + */ + +#ifndef __MPC5XX_H__ +#define __MPC5XX_H__ + + +/*----------------------------------------------------------------------- + * Exception offsets (PowerPC standard) + */ +#define EXC_OFF_SYS_RESET	0x0100	/* System reset				*/ + +/*----------------------------------------------------------------------- + * ISB bit in IMMR to set internal memory map + */ + +#define CFG_ISB			((CFG_IMMR / 0x00400000) << 1) + +/*----------------------------------------------------------------------- + * SYPCR - System Protection Control Register + */ +#define SYPCR_SWTC	0xffff0000	/* Software Watchdog Timer Count	*/ +#define SYPCR_BMT	0x0000ff00	/* Bus Monitor Timing			*/ +#define SYPCR_BME	0x00000080	/* Bus Monitor Enable			*/ +#define SYPCR_SWF	0x00000008	/* Software Watchdog Freeze		*/ +#define SYPCR_SWE	0x00000004	/* Software Watchdog Enable		*/ +#define SYPCR_SWRI	0x00000002	/* Software Watchdog Reset/Int Select	*/ +#define SYPCR_SWP	0x00000001	/* Software Watchdog Prescale		*/ + +/*----------------------------------------------------------------------- + * SIUMCR - SIU Module Configuration Register + */ +#define SIUMCR_EARB	0x80000000	/* External Arbitration			*/ +#define SIUMCR_EARP0	0x00000000	/* External Arbi. Request priority 0	*/ +#define SIUMCR_EARP1	0x10000000	/* External Arbi. Request priority 1	*/ +#define SIUMCR_EARP2	0x20000000	/* External Arbi. Request priority 2	*/ +#define SIUMCR_EARP3	0x30000000	/* External Arbi. Request priority 3	*/ +#define SIUMCR_EARP4	0x40000000	/* External Arbi. Request priority 4	*/ +#define SIUMCR_EARP5	0x50000000	/* External Arbi. Request priority 5	*/ +#define SIUMCR_EARP6	0x60000000	/* External Arbi. Request priority 6	*/ +#define SIUMCR_EARP7	0x70000000	/* External Arbi. Request priority 7	*/ +#define SIUMCR_DSHW	0x00800000	/* Data Showcycles			*/ +#define SIUMCR_DBGC00	0x00000000	/* Debug pins configuration		*/ +#define SIUMCR_DBGC01	0x00200000	/* - " -				*/ +#define SIUMCR_DBGC10	0x00400000	/* - " -				*/ +#define SIUMCR_DBGC11	0x00600000	/* - " -				*/ +#define SIUMCR_DBPC00	0x00000000	/* Debug Port pins Config.		*/ +#define SIUMCR_DBPC01	0x00080000	/* - " -				*/ +#define SIUMCR_DBPC10	0x00100000	/* - " -				*/ +#define SIUMCR_DBPC11	0x00180000	/* - " -				*/ +#define SIUMCR_DLK	0x00010000	/* Debug Register Lock			*/ +#define SIUMCR_SC00	0x00000000	/* Multi Chip 32 bit			*/ +#define SIUMCR_SC01	0x00004000	/* Muilt Chip 16 bit			*/ +#define SIUMCR_SC10	0x00004000	/* Single adress show			*/ +#define SIUMCR_SC11	0x00006000	/* Single adress			*/ +#define SIUMCR_RCTX	0x00001000	/* Data Parity pins Config.		*/ +#define SIUMCR_MLRC00	0x00000000	/* Multi Level Reserva. Ctrl		*/ +#define SIUMCR_MLRC01	0x00000400	/* - " -				*/ +#define SIUMCR_MLRC10	0x00000800	/* - " -				*/ +#define SIUMCR_MLRC11	0x00000c00	/* - " -				*/ +#define SIUMCR_MTSC	0x00000100	/* Memory transfer      		*/ + +/*----------------------------------------------------------------------- + * TBSCR - Time Base Status and Control Register		 + */ +#define TBSCR_REFA	((ushort)0x0080)	/* Reference Interrupt Status A	*/ +#define TBSCR_REFB	((ushort)0x0040)	/* Reference Interrupt Status B */ +#define TBSCR_TBF	((ushort)0x0002)	/* Time Base stops while FREEZE */ + +/*----------------------------------------------------------------------- + * PISCR - Periodic Interrupt Status and Control Register + */ +#define PISCR_PITF	((ushort)0x0002)	/* PIT stops when FREEZE	*/ + +/*----------------------------------------------------------------------- + * PLPRCR - PLL, Low-Power, and Reset Control Register + */ +#define PLPRCR_MF_MSK	0xfff00000	/* MF mask				*/ +#define PLPRCR_DIVF_MSK	0x0000001f	/* DIVF mask				*/ +#define PLPRCR_CSRC_MSK 0x00000400	/* CSRC mask				*/ +#define PLPRCR_MF_SHIFT 0x00000014	/* Multiplication factor shift value	*/ +#define PLPRCR_DIVF_0   0x00900000	/* Division factor 0			*/ +#define PLPRCR_MF_9     0x00000000	/* Mulitipliaction factor 9		*/ +#define PLPRCR_TEXPS	0x00004000	/* TEXP Status				*/ +#define PLPRCR_TMIST	0x00001000	/* Timers Interrupt Status		*/ +#define PLPRCR_CSR	0x00000080	/* CheskStop Reset value		*/ + +/*----------------------------------------------------------------------- + * SCCR - System Clock and reset Control Register	 + */ +#define SCCR_DFNL_MSK	0x00000070	/* DFNL mask				*/ +#define SCCR_DFNH_MSK	0x00000007  	/* DFNH mask				*/ +#define SCCR_DFNL_SHIFT 0x0000004	/* DFNL shift value			*/ +#define SCCR_RTSEL	0x00100000	/* RTC circuit input source select	*/ +#define SCCR_EBDF00	0x00000000	/* Division factor 1. CLKOUT is GCLK2   */		 +#define SCCR_EBDF11	0x00060000	/* reserved				*/ +#define SCCR_TBS	0x02000000	/* Time Base Source			*/ +#define SCCR_RTDIV	0x01000000	/* RTC Clock Divide 			*/ +#define SCCR_COM00	0x00000000	/* full strength CLKOUT output buffer	*/ +#define SCCR_DFNL000	0x00000000	/* Division by 2 (default = minimum)	*/ +#define SCCR_DFNH000	0x00000000	/* Division by 1 (default = minimum)	*/ + +/*----------------------------------------------------------------------- + * MC - Memory Controller + */ +#define BR_V		0x00000001	/* Bank valid 				*/ +#define BR_BI		0x00000002	/* Burst inhibit 			*/ +#define BR_PS_8		0x00000400	/* 8 bit port size 			*/ +#define BR_PS_16	0x00000800	/* 16 bit port size 			*/ +#define BR_PS_32	0x00000000	/* 32 bit port size 			*/ +#define BR_LBDIR	0x00000008	/* Late burst data in progess		*/ +#define OR_SCY_3	0x00000030	/* 3 clock cycles wait states		*/ +#define OR_SCY_1	0x00000000	/* 1 clock cycle wait state		*/ +#define OR_SCY_8	0x00000080	/* 8 clock cycles wait states		*/ +#define OR_TRLX		0x00000001	/* Timing relaxed			*/ +#define OR_BSCY		0x00000060	/* Burst beats length in clocks		*/ +#define OR_ACS_10	0x00000600	/* Adress to chip-select setup		*/ +#define OR_CSNT		0x00000800	/* Chip-select negotation time		*/ +#define OR_ETHR		0x00000000	/* Extended hold time on read		*/ +#define OR_ADDR_MK_FF	0xFF000000 +#define OR_ADDR_MK_FFFF	0xFFFF0000 + +/*----------------------------------------------------------------------- + * UMCR - UIMB Module Configuration Register + */ +#define UMCR_FSPEED 	0x00000000	/* Full speed. Opposit of UMCR_HSPEED	*/ +#define UMCR_HSPEED 	0x10000000	/* Half speed				*/ + +/*----------------------------------------------------------------------- + * ICTRL - I-Bus Support Control Register + */ +#define ICTRL_ISCT_SER_7 0x00000007	/* All indirect change of flow		*/ + + +#define NR_IRQS		0		/* Place this later in a separate file */ + +/*----------------------------------------------------------------------- + * SCI - Serial communication interface + */ + +#define SCI_TDRE	0x0100		/* Transmit data register empty 	*/ +#define SCI_TE		0x0008		/* Transmitter enabled 			*/ +#define SCI_RE		0x0004		/* Receiver enabled			*/ +#define SCI_RDRF	0x0040		/* Receive data register full 		*/ +#define SCI_PE		0x0400		/* Parity enable 			*/ +#define SCI_SCXBR_MK	0x1fff		/* Baudrate mask 			*/ +#define SCI_SCXDR_MK	0x00ff		/* Data register mask 			*/ +#define SCI_M_11	0x0200		/* Frame size is 11 bit			*/ +#define SCI_M_10	0x0000		/* Frame size is 10 bit			*/ +#define SCI_PORT_1	((int)1)	/* Place this later somewhere better 	*/ +#define SCI_PORT_2	((int)2) + +#endif	/* __MPC5XX_H__ */ diff --git a/include/ppc_asm.tmpl b/include/ppc_asm.tmpl index 931950967..f99d7b2fb 100644 --- a/include/ppc_asm.tmpl +++ b/include/ppc_asm.tmpl @@ -110,6 +110,18 @@  #endif	/* CONFIG_8xx, CONFIG_MPC824X */ + +#if  defined(CONFIG_5xx) +/* Some special purpose registers */ +#define DER	149		/* Debug Enable Register	    	*/ +#define COUNTA	150		/* Breakpoint Counter	    	 	*/ +#define COUNTB	151		/* Breakpoint Counter	    	 	*/ +#define LCTRL1	156		/* Load/Store Support	    	 	*/ +#define LCTRL2	157		/* Load/Store Support	    	 	*/ +#define ICTRL	158		/* I-Bus Support Control Register	*/ +#define EID	81 +#endif	/* CONFIG_5xx */ +  #if defined(CONFIG_8xx)  /* Registers in the processor's internal memory map that we use. diff --git a/include/status_led.h b/include/status_led.h index 79d9fb475..773573d47 100644 --- a/include/status_led.h +++ b/include/status_led.h @@ -253,6 +253,19 @@ void status_led_set  (int led, int state);  # define STATUS_LED_BOOT	0		/* LED 0 used for boot status */ +/*****  CMI   ********************************************************/ +#elif defined(CONFIG_CMI) +# define STATUS_LED_DIR		im_mios.mios_mpiosm32ddr  +# define STATUS_LED_DAT		im_mios.mios_mpiosm32dr  + +# define STATUS_LED_BIT		0x2000		/* Select one of the 16 possible*/ +						/* MIOS outputs */ +# define STATUS_LED_PERIOD	(CFG_HZ / 2)	/* Blinking periode is 500 ms */ +# define STATUS_LED_STATE	STATUS_LED_BLINKING + +# define STATUS_LED_ACTIVE	1		/* LED on for bit == 0	*/ +# define STATUS_LED_BOOT	0		/* LED 0 used for boot status */ +  /*****  KUP4K  ********************************************************/  #elif defined(CONFIG_KUP4K) diff --git a/include/watchdog.h b/include/watchdog.h index 6a64409e5..dc26e6ad0 100644 --- a/include/watchdog.h +++ b/include/watchdog.h @@ -75,6 +75,11 @@  	void reset_8xx_watchdog(volatile immap_t *immr);  #endif +/* MPC 5xx */ +#if defined(CONFIG_5xx) && !defined(__ASSEMBLY__) +	void reset_5xx_watchdog(volatile immap_t *immr); +#endif +  /* IBM 4xx */  #if defined(CONFIG_4xx) && !defined(__ASSEMBLY__)  	void reset_4xx_watchdog(void); diff --git a/lib_ppc/board.c b/lib_ppc/board.c index c617049f5..eb67942d7 100644 --- a/lib_ppc/board.c +++ b/lib_ppc/board.c @@ -30,6 +30,9 @@  #ifdef CONFIG_8xx  #include <mpc8xx.h>  #endif +#ifdef CONFIG_5xx +#include <mpc5xx.h> +#endif  #if (CONFIG_COMMANDS & CFG_CMD_IDE)  #include <ide.h>  #endif @@ -160,12 +163,15 @@ static void syscalls_init (void)  	*addr++ |= NR_SYSCALLS >> 16;  	*addr++ |= NR_SYSCALLS & 0xFFFF; +#ifndef CONFIG_5XX  	flush_cache (0x0C00, 0x10); - +#endif  	/* Initialize syscalls stack pointer                                 */  	addr = (ulong *) 0xCFC;  	*addr = (ulong)addr; +#ifndef CONFIG_5xx	  	flush_cache ((ulong)addr, 0x10); +#endif  }  /* @@ -199,7 +205,6 @@ static int init_baudrate (void)  	gd->baudrate = (i > 0)  			? (int) simple_strtoul (tmp, NULL, 10)  			: CONFIG_BAUDRATE; -  	return (0);  } @@ -496,7 +501,7 @@ void board_init_f (ulong bootflag)  	bd->bi_sramsize  = 0;		/* FIXME */ /* size  of  SRAM memory      */  #endif -#if defined(CONFIG_8xx) || defined(CONFIG_8260) +#if defined(CONFIG_8xx) || defined(CONFIG_8260) || defined(CONFIG_5xx)  	bd->bi_immr_base = CFG_IMMR;	/* base  of IMMR register     */  #endif diff --git a/lib_ppc/cache.c b/lib_ppc/cache.c index bec092e4c..a81ab5e36 100644 --- a/lib_ppc/cache.c +++ b/lib_ppc/cache.c @@ -23,8 +23,10 @@  #include <common.h> +  void flush_cache (ulong start_addr, ulong size)  { +#ifndef CONFIG_5xx  	ulong addr, end_addr = start_addr + size;  	if (CFG_CACHELINE_SIZE) { @@ -44,4 +46,5 @@ void flush_cache (ulong start_addr, ulong size)  	}  	asm ("sync");		/* Always flush prefetch queue in any case */  	asm ("isync"); +#endif  } diff --git a/lib_ppc/time.c b/lib_ppc/time.c index 5165abbe3..3b3c50e45 100644 --- a/lib_ppc/time.c +++ b/lib_ppc/time.c @@ -80,7 +80,7 @@ unsigned long ticks2usec(unsigned long ticks)  int init_timebase (void)  { -#ifdef	CONFIG_8xx +#if defined(CONFIG_5xx) || defined(CONFIG_8xx)  	volatile immap_t *immap = (immap_t *) CFG_IMMR;  	/* unlock */ @@ -90,7 +90,7 @@ int init_timebase (void)  	/* reset */  	asm ("li 3,0 ; mttbu 3 ; mttbl 3 ;"); -#ifdef	CONFIG_8xx +#if defined(CONFIG_5xx) || defined(CONFIG_8xx)  	/* enable */  	immap->im_sit.sit_tbscr |= TBSCR_TBE;  #endif |