From 0db5bca8076998a7516102988ac976a2da28d531 Mon Sep 17 00:00:00 2001 From: wdenk Date: Mon, 31 Mar 2003 17:27:09 +0000 Subject: [PATCH] * 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 --- CHANGELOG | 8 + CREDITS | 4 + MAKEALL | 16 +- Makefile | 9 + README | 7 +- board/cmi/Makefile | 47 +++ board/cmi/cmi.c | 73 ++++ board/cmi/config.mk | 31 ++ board/cmi/flash.c | 517 ++++++++++++++++++++++++++++ board/cmi/u-boot.lds | 131 ++++++++ common/cmd_boot.c | 2 +- common/cmd_nand.c | 273 ++++++++------- common/cmd_reginfo.c | 39 ++- common/environment.c | 3 +- cpu/mpc5xx/Makefile | 52 +++ cpu/mpc5xx/config.mk | 34 ++ cpu/mpc5xx/cpu.c | 155 +++++++++ cpu/mpc5xx/cpu_init.c | 119 +++++++ cpu/mpc5xx/interrupts.c | 273 +++++++++++++++ cpu/mpc5xx/serial.c | 171 ++++++++++ cpu/mpc5xx/speed.c | 66 ++++ cpu/mpc5xx/start.S | 629 +++++++++++++++++++++++++++++++++++ cpu/mpc5xx/status_led.c | 161 +++++++++ cpu/mpc5xx/traps.c | 231 +++++++++++++ doc/README.cmi | 84 +++++ doc/README.mpc5xx | 48 +++ include/asm-ppc/5xx_immap.h | 440 ++++++++++++++++++++++++ include/asm-ppc/u-boot.h | 2 +- include/cmd_reginfo.h | 4 +- include/common.h | 6 +- include/configs/cmi_mpc5xx.h | 256 ++++++++++++++ include/mpc5xx.h | 180 ++++++++++ include/ppc_asm.tmpl | 12 + include/status_led.h | 13 + include/watchdog.h | 5 + lib_ppc/board.c | 11 +- lib_ppc/cache.c | 3 + lib_ppc/time.c | 4 +- 38 files changed, 3972 insertions(+), 147 deletions(-) create mode 100644 board/cmi/Makefile create mode 100644 board/cmi/cmi.c create mode 100644 board/cmi/config.mk create mode 100644 board/cmi/flash.c create mode 100644 board/cmi/u-boot.lds create mode 100644 cpu/mpc5xx/Makefile create mode 100644 cpu/mpc5xx/config.mk create mode 100644 cpu/mpc5xx/cpu.c create mode 100644 cpu/mpc5xx/cpu_init.c create mode 100644 cpu/mpc5xx/interrupts.c create mode 100644 cpu/mpc5xx/serial.c create mode 100644 cpu/mpc5xx/speed.c create mode 100644 cpu/mpc5xx/start.S create mode 100644 cpu/mpc5xx/status_led.c create mode 100644 cpu/mpc5xx/traps.c create mode 100644 doc/README.cmi create mode 100644 doc/README.mpc5xx create mode 100644 include/asm-ppc/5xx_immap.h create mode 100644 include/configs/cmi_mpc5xx.h create mode 100644 include/mpc5xx.h diff --git a/CHANGELOG b/CHANGELOG index 00f1935ebb..f5f26527dd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -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 diff --git a/CREDITS b/CREDITS index 54eb5b6eb4..e7ae377ef9 100644 --- a/CREDITS +++ b/CREDITS @@ -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 diff --git a/MAKEALL b/MAKEALL index fd459b73ad..830f9aca18 100644 --- a/MAKEALL +++ b/MAKEALL @@ -10,6 +10,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} diff --git a/Makefile b/Makefile index 5b9e3c8858..1fae64520f 100644 --- a/Makefile +++ b/Makefile @@ -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 #======================================================================== diff --git a/README b/README index 46ca7e9404..40dec968bf 100644 --- a/README +++ b/README @@ -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 0000000000..0a92da874b --- /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 0000000000..cbf34f7854 --- /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 +#include + +#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 0000000000..564f638a39 --- /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 0000000000..b41ff12520 --- /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 +#include + +#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_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; isector_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 0000000000..9865171317 --- /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 59bab35dfb..09f3f78f49 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 a041b29c20..edb717d8af 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); - - /* 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). + 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). */ - 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 1986c22579..954e937375 100644 --- a/common/cmd_reginfo.c +++ b/common/cmd_reginfo.c @@ -28,6 +28,8 @@ #include #elif defined (CONFIG_405GP) #include +#elif defined (CONFIG_5xx) +#include #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 244c2a26ba..a868dccbdc 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 0000000000..a1e0421aea --- /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 0000000000..d302d4835c --- /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 0000000000..6018436a27 --- /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 +#include +#include +#include + + +#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 0000000000..27cf3d6b17 --- /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 +#include +#include + +/* + * 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 0000000000..282c3165d5 --- /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 +#include +#include +#include + +/************************************************************************/ + +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 0000000000..738c275f81 --- /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 +#include +#include +#include + + +/* + * 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 0000000000..8098c9982a --- /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 +#include +#include + +/* + * 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 0000000000..d17fe92720 --- /dev/null +++ b/cpu/mpc5xx/start.S @@ -0,0 +1,629 @@ +/* + * Copyright (C) 1998 Dan Malek + * Copyright (C) 1999 Magnus Damm + * Copyright (C) 2000, 2001, 2002 Wolfgang Denk + * 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 +#include +#include + +#define CONFIG_5xx 1 /* needed for Linux kernel header files */ +#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ + +#include +#include + +#include +#include + +#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 0000000000..f15bbe8215 --- /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 +#include +#include + +#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; iSTATUS_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; istate != 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 0000000000..41939c15d8 --- /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 +#include +#include + +#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 0000000000..48052b867b --- /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 0000000000..2c1a29321b --- /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 0000000000..ffff975c97 --- /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 78744e28fd..5e8f4b5771 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 d4e995d1a7..6a67b36e29 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 ac2a57d9a3..0d7f79a448 100644 --- a/include/common.h +++ b/include/common.h @@ -43,6 +43,8 @@ typedef volatile unsigned char vu_char; #endif #ifdef CONFIG_8xx #include +#elif defined(CONFIG_5xx) +#include #elif defined(CONFIG_8260) #include #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 0000000000..e8b3eb5d82 --- /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 + +#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 0000000000..8541ef6f72 --- /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 9319509671..f99d7b2fb9 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 79d9fb475a..773573d479 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 6a64409e5e..dc26e6ad06 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 c617049f58..eb67942d77 100644 --- a/lib_ppc/board.c +++ b/lib_ppc/board.c @@ -30,6 +30,9 @@ #ifdef CONFIG_8xx #include #endif +#ifdef CONFIG_5xx +#include +#endif #if (CONFIG_COMMANDS & CFG_CMD_IDE) #include #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 bec092e4ce..a81ab5e363 100644 --- a/lib_ppc/cache.c +++ b/lib_ppc/cache.c @@ -23,8 +23,10 @@ #include + 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 5165abbe35..3b3c50e452 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 -- 2.25.1