[U-Boot-Users] [PATCH/review] Blackfin: move bootldr command to common code

This moves the Blackfin-common bootldr command out of the BF537-STAMP specific board directory and into the common directory so that all Blackfin boards may utilize it.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- board/bf537-stamp/bf537-stamp.c | 45 --------------------------- common/Makefile | 1 + common/cmd_bootldr.c | 64 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 45 deletions(-) create mode 100644 common/cmd_bootldr.c
diff --git a/board/bf537-stamp/bf537-stamp.c b/board/bf537-stamp/bf537-stamp.c index d279817..e36a1b6 100644 --- a/board/bf537-stamp/bf537-stamp.c +++ b/board/bf537-stamp/bf537-stamp.c @@ -54,51 +54,6 @@ DECLARE_GLOBAL_DATA_PTR;
#define POST_WORD_ADDR 0xFF903FFC
-/* - * the bootldr command loads an address, checks to see if there - * is a Boot stream that the on-chip BOOTROM can understand, - * and loads it via the BOOTROM Callback. It is possible - * to also add booting from SPI, or TWI, but this function does - * not currently support that. - */ -int do_bootldr(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) -{ - ulong addr, entry; - ulong *data; - - /* Get the address */ - if (argc < 2) { - addr = load_addr; - } else { - addr = simple_strtoul(argv[1], NULL, 16); - } - - /* Check if it is a LDR file */ - data = (ulong *) addr; - if (*data == 0xFF800060 || *data == 0xFF800040 || *data == 0xFF800020) { - /* We want to boot from FLASH or SDRAM */ - entry = _BOOTROM_BOOT_DXE_FLASH; - printf("## Booting ldr image at 0x%08lx ...\n", addr); - if (icache_status()) - icache_disable(); - if (dcache_status()) - dcache_disable(); - - __asm__("R7=%[a];\n" "P0=%[b];\n" "JUMP (P0);\n": - :[a] "d"(addr),[b] "a"(entry) - :"R7", "P0"); - - } else { - printf("## No ldr image at address 0x%08lx\n", addr); - } - - return 0; -} - -U_BOOT_CMD(bootldr, 2, 0, do_bootldr, - "bootldr - boot ldr image from memory\n", - "[addr]\n - boot ldr image stored in memory\n"); - int checkboard(void) { #if (BFIN_CPU == ADSP_BF534) diff --git a/common/Makefile b/common/Makefile index a88d1ef..1244e0b 100644 --- a/common/Makefile +++ b/common/Makefile @@ -37,6 +37,7 @@ COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o COBJS-$(CONFIG_CMD_BEDBUG) += cmd_bedbug.o COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o COBJS-y += cmd_boot.o +COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o COBJS-y += cmd_bootm.o COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o COBJS-$(CONFIG_CMD_CONSOLE) += cmd_console.o diff --git a/common/cmd_bootldr.c b/common/cmd_bootldr.c new file mode 100644 index 0000000..e6474aa --- /dev/null +++ b/common/cmd_bootldr.c @@ -0,0 +1,64 @@ +/* + * U-boot - bootldr.c + * + * Copyright (c) 2005-2008 Analog Devices Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * Licensed under the GPL-2 or later. + */ + +#include <config.h> +#include <common.h> +#include <command.h> + +#include <asm/blackfin.h> +#include <asm/mach-common/bits/bootrom.h> + +/* + * the bootldr command loads an address, checks to see if there + * is a Boot stream that the on-chip BOOTROM can understand, + * and loads it via the BOOTROM Callback. It is possible + * to also add booting from SPI, or TWI, but this function does + * not currently support that. + */ + +int do_bootldr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + void *addr; + uint32_t *data; + + /* Get the address */ + if (argc < 2) + addr = (void *)load_addr; + else + addr = (void *)simple_strtoul(argv[1], NULL, 16); + + /* Check if it is a LDR file */ + data = addr; +#if defined(__ADSPBF54x__) || defined(__ADSPBF52x__) + if ((*data & 0xFF000000) == 0xAD000000 && data[2] == 0x00000000) { +#else + if (*data == 0xFF800060 || *data == 0xFF800040 || *data == 0xFF800020) { +#endif + /* We want to boot from FLASH or SDRAM */ + printf("## Booting ldr image at 0x%p ...\n", addr); + + icache_disable(); + dcache_disable(); + + __asm__( + "jump (%1);" + : + : "q7" (addr), "a" (_BOOTROM_MEMBOOT)); + } else + printf("## No ldr image at address 0x%p\n", addr); + + return 0; +} + +U_BOOT_CMD(bootldr, 2, 0, do_bootldr, + "bootldr - boot ldr image from memory\n", + "[addr]\n" + " - boot ldr image stored in memory\n");

Stop tying things to the processor that should be tied to other defines and change BFIN_CPU to CONFIG_BFIN_CPU so that it can be used in the build system to select the -mcpu option.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- blackfin_config.mk | 6 +++++- board/bf533-ezkit/bf533-ezkit.c | 7 ------- board/bf533-stamp/bf533-stamp.c | 7 ------- board/bf537-stamp/bf537-stamp.c | 11 ----------- include/configs/bf533-ezkit.h | 9 ++++----- include/configs/bf533-stamp.h | 25 ++++--------------------- include/configs/bf537-stamp.h | 34 +++++++++------------------------- include/configs/bf561-ezkit.h | 6 +++++- lib_blackfin/board.c | 3 ++- 9 files changed, 29 insertions(+), 79 deletions(-)
diff --git a/blackfin_config.mk b/blackfin_config.mk index a7513ea..d90eb23 100644 --- a/blackfin_config.mk +++ b/blackfin_config.mk @@ -24,9 +24,13 @@ PLATFORM_RELFLAGS += -ffixed-P5 PLATFORM_CPPFLAGS += -DCONFIG_BLACKFIN
+ifneq (,$(CONFIG_BFIN_CPU)) +PLATFORM_RELFLAGS += -mcpu=$(CONFIG_BFIN_CPU) +endif + SYM_PREFIX = _
LDR_FLAGS += --use-vmas -ifeq (,$(findstring s,$(MAKEFLAGS))) +ifneq (,$(findstring s,$(MAKEFLAGS))) LDR_FLAGS += --quiet endif diff --git a/board/bf533-ezkit/bf533-ezkit.c b/board/bf533-ezkit/bf533-ezkit.c index 98ed6f8..738f69c 100644 --- a/board/bf533-ezkit/bf533-ezkit.c +++ b/board/bf533-ezkit/bf533-ezkit.c @@ -34,13 +34,6 @@ DECLARE_GLOBAL_DATA_PTR;
int checkboard(void) { -#if (BFIN_CPU == ADSP_BF531) - printf("CPU: ADSP BF531 Rev.: 0.%d\n", *pCHIPID >> 28); -#elif (BFIN_CPU == ADSP_BF532) - printf("CPU: ADSP BF532 Rev.: 0.%d\n", *pCHIPID >> 28); -#else - printf("CPU: ADSP BF533 Rev.: 0.%d\n", *pCHIPID >> 28); -#endif printf("Board: ADI BF533 EZ-Kit Lite board\n"); printf(" Support: http://blackfin.uclinux.org/%5Cn"); return 0; diff --git a/board/bf533-stamp/bf533-stamp.c b/board/bf533-stamp/bf533-stamp.c index af03597..c4dde92 100644 --- a/board/bf533-stamp/bf533-stamp.c +++ b/board/bf533-stamp/bf533-stamp.c @@ -43,13 +43,6 @@ DECLARE_GLOBAL_DATA_PTR;
int checkboard(void) { -#if (BFIN_CPU == ADSP_BF531) - printf("CPU: ADSP BF531 Rev.: 0.%d\n", *pCHIPID >> 28); -#elif (BFIN_CPU == ADSP_BF532) - printf("CPU: ADSP BF532 Rev.: 0.%d\n", *pCHIPID >> 28); -#else - printf("CPU: ADSP BF533 Rev.: 0.%d\n", *pCHIPID >> 28); -#endif printf("Board: ADI BF533 Stamp board\n"); printf(" Support: http://blackfin.uclinux.org/%5Cn"); return 0; diff --git a/board/bf537-stamp/bf537-stamp.c b/board/bf537-stamp/bf537-stamp.c index e36a1b6..6ca8e21 100644 --- a/board/bf537-stamp/bf537-stamp.c +++ b/board/bf537-stamp/bf537-stamp.c @@ -31,7 +31,6 @@ #include <asm/blackfin.h> #include <asm/io.h> #include <net.h> -#include "ether_bf537.h" #include <asm/mach-common/bits/bootrom.h>
/** @@ -56,13 +55,6 @@ DECLARE_GLOBAL_DATA_PTR;
int checkboard(void) { -#if (BFIN_CPU == ADSP_BF534) - printf("CPU: ADSP BF534 Rev.: 0.%d\n", *pCHIPID >> 28); -#elif (BFIN_CPU == ADSP_BF536) - printf("CPU: ADSP BF536 Rev.: 0.%d\n", *pCHIPID >> 28); -#else - printf("CPU: ADSP BF537 Rev.: 0.%d\n", *pCHIPID >> 28); -#endif printf("Board: ADI BF537 stamp board\n"); printf(" Support: http://blackfin.uclinux.org/%5Cn"); return 0; @@ -142,9 +134,6 @@ int misc_init_r(void) pMACaddr[2], pMACaddr[3], pMACaddr[4], pMACaddr[5]); setenv("ethaddr", nid); } - if (getenv("ethaddr")) { - SetupMacAddr(SrcAddr); - } #endif #endif /* BFIN_BOOT_MODE == BF537_BYPASS_BOOT */
diff --git a/include/configs/bf533-ezkit.h b/include/configs/bf533-ezkit.h index 6cb6bc4..f2c8703 100644 --- a/include/configs/bf533-ezkit.h +++ b/include/configs/bf533-ezkit.h @@ -5,6 +5,8 @@ #ifndef __CONFIG_EZKIT533_H__ #define __CONFIG_EZKIT533_H__
+#include <asm/blackfin-config-pre.h> + #define CONFIG_BAUDRATE 57600 #define CONFIG_STAMP 1
@@ -41,10 +43,7 @@
#define CONFIG_PANIC_HANG 1
-#define ADSP_BF531 0x31 -#define ADSP_BF532 0x32 -#define ADSP_BF533 0x33 -#define BFIN_CPU ADSP_BF533 +#define CONFIG_BFIN_CPU bf533-0.3
/* This sets the default state of the cache on U-Boot's boot */ #define CONFIG_ICACHE_ON @@ -120,7 +119,7 @@
#define CONFIG_BOOTARGS "root=/dev/mtdblock0 ip=192.168.0.15:192.168.0.2:192.168.0.1:255.255.255.0:ezkit:eth0:off console=ttyBF0,57600"
-#define CFG_PROMPT "ezkit> " /* Monitor Command Prompt */ +#define CFG_PROMPT "bfin> " /* Monitor Command Prompt */ #if defined(CONFIG_CMD_KGDB) #define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ #else diff --git a/include/configs/bf533-stamp.h b/include/configs/bf533-stamp.h index cce6ef7..76dd2fa 100644 --- a/include/configs/bf533-stamp.h +++ b/include/configs/bf533-stamp.h @@ -5,6 +5,8 @@ #ifndef __CONFIG_STAMP_H__ #define __CONFIG_STAMP_H__
+#include <asm/blackfin-config-pre.h> + #define CONFIG_STAMP 1 #define CONFIG_RTC_BFIN 1 #define CONFIG_BF533 1 @@ -21,10 +23,7 @@
#define CONFIG_PANIC_HANG 1
-#define ADSP_BF531 0x31 -#define ADSP_BF532 0x32 -#define ADSP_BF533 0x33 -#define BFIN_CPU ADSP_BF533 +#define CONFIG_BFIN_CPU bf533-0.3
/* This sets the default state of the cache on U-Boot's boot */ #define CONFIG_ICACHE_ON @@ -329,23 +328,7 @@ #define CONFIG_BAUDRATE 57600 #define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
-#if (BFIN_BOOT_MODE == BF533_SPI_BOOT) -#if (BFIN_CPU == ADSP_BF531) -#define CFG_PROMPT "serial_bf531> " /* Monitor Command Prompt */ -#elif (BFIN_CPU == ADSP_BF532) -#define CFG_PROMPT "serial_bf532> " /* Monitor Command Prompt */ -#else -#define CFG_PROMPT "serial_bf533> " /* Monitor Command Prompt */ -#endif -#else -#if (BFIN_CPU == ADSP_BF531) -#define CFG_PROMPT "bf531> " /* Monitor Command Prompt */ -#elif (BFIN_CPU == ADSP_BF532) -#define CFG_PROMPT "bf532> " /* Monitor Command Prompt */ -#else -#define CFG_PROMPT "bf533> " /* Monitor Command Prompt */ -#endif -#endif +#define CFG_PROMPT "bfin> " /* Monitor Command Prompt */
#if defined(CONFIG_CMD_KGDB) #define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ diff --git a/include/configs/bf537-stamp.h b/include/configs/bf537-stamp.h index b9a9e3c..0679f43 100644 --- a/include/configs/bf537-stamp.h +++ b/include/configs/bf537-stamp.h @@ -5,6 +5,8 @@ #ifndef __CONFIG_BF537_H__ #define __CONFIG_BF537_H__
+#include <asm/blackfin-config-pre.h> + #define CFG_LONGHELP 1 #define CONFIG_CMDLINE_EDITING 1 #define CONFIG_BAUDRATE 57600 @@ -31,10 +33,8 @@
#define CONFIG_PANIC_HANG 1
-#define ADSP_BF534 0x34 -#define ADSP_BF536 0x36 -#define ADSP_BF537 0x37 -#define BFIN_CPU ADSP_BF537 +#define CONFIG_BFIN_CPU bf537-0.2 +#define CONFIG_BFIN_MAC
/* This sets the default state of the cache on U-Boot's boot */ #define CONFIG_ICACHE_ON @@ -113,7 +113,7 @@ * Network Settings */ /* network support */ -#if (BFIN_CPU != ADSP_BF534) +#ifdef CONFIG_BFIN_MAC #define CONFIG_IPADDR 192.168.0.15 #define CONFIG_NETMASK 255.255.255.0 #define CONFIG_GATEWAYIP 192.168.0.1 @@ -186,7 +186,7 @@ #define CONFIG_CMD_EEPROM #define CONFIG_CMD_DATE
-#if (BFIN_CPU == ADSP_BF534) +#ifndef CONFIG_BFIN_MAC #undef CONFIG_CMD_NET #else #define CONFIG_CMD_PING @@ -219,7 +219,7 @@ #define CONFIG_LOADADDR 0x1000000
#if (BFIN_BOOT_MODE == BF537_BYPASS_BOOT) -#if (BFIN_CPU != ADSP_BF534) +#ifdef CONFIG_BFIN_MAC #define CONFIG_EXTRA_ENV_SETTINGS \ "ramargs=setenv bootargs root=/dev/mtdblock0 rw console=ttyBF0,57600\0" \ "nfsargs=setenv bootargs root=/dev/nfs rw " \ @@ -243,7 +243,7 @@ "" #endif #elif (BFIN_BOOT_MODE == BF537_SPI_MASTER_BOOT) -#if (BFIN_CPU != ADSP_BF534) +#ifdef CONFIG_BFIN_MAC #define CONFIG_EXTRA_ENV_SETTINGS \ "ramargs=setenv bootargs root=/dev/mtdblock0 rw console=ttyBF0,57600\0" \ "nfsargs=setenv bootargs root=/dev/nfs rw " \ @@ -267,23 +267,7 @@ #endif #endif
-#if (BFIN_BOOT_MODE == BF537_SPI_MASTER_BOOT) -#if (BFIN_CPU == ADSP_BF534) -#define CFG_PROMPT "serial_bf534> " /* Monitor Command Prompt */ -#elif (BFIN_CPU == ADSP_BF536) -#define CFG_PROMPT "serial_bf536> " /* Monitor Command Prompt */ -#else -#define CFG_PROMPT "serial_bf537> " /* Monitor Command Prompt */ -#endif -#else -#if (BFIN_CPU == ADSP_BF534) -#define CFG_PROMPT "bf534> " /* Monitor Command Prompt */ -#elif (BFIN_CPU == ADSP_BF536) -#define CFG_PROMPT "bf536> " /* Monitor Command Prompt */ -#else -#define CFG_PROMPT "bf537> " /* Monitor Command Prompt */ -#endif -#endif +#define CFG_PROMPT "bfin> " /* Monitor Command Prompt */
#if defined(CONFIG_CMD_KGDB) #define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ diff --git a/include/configs/bf561-ezkit.h b/include/configs/bf561-ezkit.h index 2966260..c29555a 100644 --- a/include/configs/bf561-ezkit.h +++ b/include/configs/bf561-ezkit.h @@ -5,6 +5,8 @@ #ifndef __CONFIG_EZKIT561_H__ #define __CONFIG_EZKIT561_H__
+#include <asm/blackfin-config-pre.h> + #define CONFIG_VDSP 1 #define CONFIG_BF561 1
@@ -18,6 +20,8 @@
#define CONFIG_PANIC_HANG 1
+#define CONFIG_BFIN_CPU bf561-0.3 + /* * Boot Mode Set * Blackfin can support several boot modes @@ -216,7 +220,7 @@ */ #define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
-#define CFG_PROMPT "ezkit> " /* Monitor Command Prompt */ +#define CFG_PROMPT "bfin> " /* Monitor Command Prompt */
#if defined(CONFIG_CMD_KGDB) #define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ diff --git a/lib_blackfin/board.c b/lib_blackfin/board.c index 86a3b67..2a5a2fc 100644 --- a/lib_blackfin/board.c +++ b/lib_blackfin/board.c @@ -116,6 +116,7 @@ static int display_banner(void) { sprintf(version_string, VERSION_STRING_FORMAT, VERSION_STRING); printf("%s\n", version_string); + printf("CPU: ADSP " MK_STR(CONFIG_BFIN_CPU) " (Detected Rev: 0.%d)\n", bfin_revid()); return (0); }
@@ -404,7 +405,7 @@ void board_init_r(gd_t * id, ulong dest_addr) misc_init_r(); #endif
-#if ((BFIN_CPU == ADSP_BF537) || (BFIN_CPU == ADSP_BF536)) +#ifdef CONFIG_CMD_NET printf("Net: "); eth_initialize(bd); #endif

The parallel flash on the BF537-STAMP is CFI compliant, so there is no need for the board specific driver at all. Just use the common CFI driver.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- board/bf537-stamp/Makefile | 2 +- board/bf537-stamp/flash-defines.h | 123 ----------- board/bf537-stamp/flash.c | 403 ------------------------------------- include/configs/bf537-stamp.h | 9 +- 4 files changed, 6 insertions(+), 531 deletions(-) delete mode 100644 board/bf537-stamp/flash-defines.h delete mode 100644 board/bf537-stamp/flash.c
diff --git a/board/bf537-stamp/Makefile b/board/bf537-stamp/Makefile index fcdfd24..5d22393 100644 --- a/board/bf537-stamp/Makefile +++ b/board/bf537-stamp/Makefile @@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS := $(BOARD).o flash.o post-memory.o stm_m25p64.o cmd_bf537led.o nand.o +COBJS := $(BOARD).o post-memory.o stm_m25p64.o cmd_bf537led.o nand.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/include/configs/bf537-stamp.h b/include/configs/bf537-stamp.h index 0679f43..0e189d4 100644 --- a/include/configs/bf537-stamp.h +++ b/include/configs/bf537-stamp.h @@ -286,6 +286,11 @@ #define CFG_SDRAM_BASE 0x00000000
#define CFG_FLASH_BASE 0x20000000 +#define CFG_FLASH_CFI /* The flash is CFI compatible */ +#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CFG_FLASH_PROTECTION +#define CFG_MAX_FLASH_BANKS 1 +#define CFG_MAX_FLASH_SECT 71 /* some have 67 sectors (M29W320DB), but newer have 71 (M29W320EB) */
#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ #define CFG_MONITOR_BASE (CFG_MAX_RAM_SIZE - CFG_MONITOR_LEN) @@ -295,10 +300,6 @@ #define CFG_GBL_DATA_ADDR (CFG_MALLOC_BASE - CFG_GBL_DATA_SIZE) #define CONFIG_STACKBASE (CFG_GBL_DATA_ADDR - 4)
-#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ -#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ -#define CFG_MAX_FLASH_SECT 71 /* max number of sectors on one chip */ - #if (BFIN_BOOT_MODE == BF537_BYPASS_BOOT) || (BFIN_BOOT_MODE == BF537_UART_BOOT) /* for bf537-stamp, usrt boot mode still store env in flash */ #define CFG_ENV_IS_IN_FLASH 1

This punts the old spi flash driver for a new/generalized one.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- board/bf533-stamp/Makefile | 2 +- board/bf533-stamp/spi.c | 474 ----------------------- board/bf533-stamp/spi_flash.c | 2 + board/bf537-stamp/Makefile | 2 +- board/bf537-stamp/spi_flash.c | 815 ++++++++++++++++++++++++++++++++++++++++ board/bf537-stamp/stm_m25p64.c | 516 ------------------------- 6 files changed, 819 insertions(+), 992 deletions(-) delete mode 100644 board/bf533-stamp/spi.c create mode 100644 board/bf533-stamp/spi_flash.c create mode 100644 board/bf537-stamp/spi_flash.c delete mode 100644 board/bf537-stamp/stm_m25p64.c
diff --git a/board/bf533-stamp/Makefile b/board/bf533-stamp/Makefile index 02c941b..14bb7a2 100644 --- a/board/bf533-stamp/Makefile +++ b/board/bf533-stamp/Makefile @@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS := $(BOARD).o spi.o +COBJS := $(BOARD).o spi_flash.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/bf533-stamp/spi_flash.c b/board/bf533-stamp/spi_flash.c new file mode 100644 index 0000000..8784741 --- /dev/null +++ b/board/bf533-stamp/spi_flash.c @@ -0,0 +1,2 @@ +/* Share the spi flash code */ +#include "../bf537-stamp/spi_flash.c" diff --git a/board/bf537-stamp/Makefile b/board/bf537-stamp/Makefile index 5d22393..5326154 100644 --- a/board/bf537-stamp/Makefile +++ b/board/bf537-stamp/Makefile @@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS := $(BOARD).o post-memory.o stm_m25p64.o cmd_bf537led.o nand.o +COBJS := $(BOARD).o post-memory.o spi_flash.o cmd_bf537led.o nand.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/bf537-stamp/spi_flash.c b/board/bf537-stamp/spi_flash.c new file mode 100644 index 0000000..7c73ddd --- /dev/null +++ b/board/bf537-stamp/spi_flash.c @@ -0,0 +1,815 @@ +/* + * SPI flash driver + * + * Enter bugs at http://blackfin.uclinux.org/ + * + * Copyright (c) 2005-2007 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +/* Configuration options: + * CONFIG_SPI_BAUD - value to load into SPI_BAUD (divisor of SCLK to get SPI CLK) + * CONFIG_SPI_FLASH_SLOW_READ - force usage of the slower read + * WARNING: make sure your SCLK + SPI_BAUD is slow enough + */ + +#include <common.h> +#include <malloc.h> +#include <asm/io.h> +#include <asm/mach-common/bits/spi.h> + +/* Forcibly phase out these */ +#ifdef CONFIG_SPI_FLASH_NUM_SECTORS +# error do not set CONFIG_SPI_FLASH_NUM_SECTORS +#endif +#ifdef CONFIG_SPI_FLASH_SECTOR_SIZE +# error do not set CONFIG_SPI_FLASH_SECTOR_SIZE +#endif + +#if defined(CONFIG_SPI) + +struct flash_info { + char *name; + uint16_t id; + unsigned sector_size; + unsigned num_sectors; +}; + +/* SPI Speeds: 50 MHz / 33 MHz */ +static struct flash_info flash_spansion_serial_flash[] = { + { "S25FL016", 0x0215, 64 * 1024, 32 }, + { "S25FL032", 0x0216, 64 * 1024, 64 }, + { "S25FL064", 0x0217, 64 * 1024, 128 }, + { "S25FL0128", 0x0218, 256 * 1024, 64 }, + { NULL, 0, 0, 0 } +}; + +/* SPI Speeds: 50 MHz / 20 MHz */ +static struct flash_info flash_st_serial_flash[] = { + { "m25p05", 0x2010, 32 * 1024, 2 }, + { "m25p10", 0x2011, 32 * 1024, 4 }, + { "m25p20", 0x2012, 64 * 1024, 4 }, + { "m25p40", 0x2013, 64 * 1024, 8 }, + { "m25p16", 0x2015, 64 * 1024, 32 }, + { "m25p32", 0x2016, 64 * 1024, 64 }, + { "m25p64", 0x2017, 64 * 1024, 128 }, + { "m25p128", 0x2018, 256 * 1024, 64 }, + { NULL, 0, 0, 0 } +}; + +/* SPI Speeds: 66 MHz / 33 MHz */ +static struct flash_info flash_atmel_dataflash[] = { + { "AT45DB011x", 0x0c, 264, 512 }, + { "AT45DB021x", 0x14, 264, 1025 }, + { "AT45DB041x", 0x1c, 264, 2048 }, + { "AT45DB081x", 0x24, 264, 4096 }, + { "AT45DB161x", 0x2c, 528, 4096 }, + { "AT45DB321x", 0x34, 528, 8192 }, + { "AT45DB642x", 0x3c, 1056, 8192 }, + { NULL, 0, 0, 0 } +}; + +/* SPI Speed: 50 MHz / 25 MHz or 40 MHz / 20 MHz */ +static struct flash_info flash_winbond_serial_flash[] = { + { "W25X10", 0x3011, 16 * 256, 32 }, + { "W25X20", 0x3012, 16 * 256, 64 }, + { "W25X40", 0x3013, 16 * 256, 128 }, + { "W25X80", 0x3014, 16 * 256, 256 }, + { "W25P80", 0x2014, 256 * 256, 16 }, + { "W25P16", 0x2015, 256 * 256, 32 }, + { NULL, 0, 0, 0 } +}; + +struct flash_ops { + uint8_t read, write, erase, status; +}; + +#ifdef CONFIG_SPI_FLASH_SLOW_READ +# define OP_READ 0x03 +#else +# define OP_READ 0x0B +#endif +static struct flash_ops flash_st_ops = { + .read = OP_READ, + .write = 0x02, + .erase = 0xD8, + .status = 0x05, +}; + +static struct flash_ops flash_atmel_ops = { + .read = OP_READ, + .write = 0x82, + .erase = 0x81, + .status = 0xD7, +}; + +static struct flash_ops flash_winbond_ops = { + .read = OP_READ, + .write = 0x02, + .erase = 0x20, + .status = 0x05, +}; + +struct manufacturer_info { + const char *name; + uint8_t id; + struct flash_info *flashes; + struct flash_ops *ops; +}; + +static struct { + struct manufacturer_info *manufacturer; + struct flash_info *flash; + struct flash_ops *ops; + uint8_t manufacturer_id, device_id1, device_id2; + unsigned int write_length; + unsigned long sector_size, num_sectors; +} flash; + +enum { + JED_MANU_SPANSION = 0x01, + JED_MANU_ST = 0x20, + JED_MANU_ATMEL = 0x1F, + JED_MANU_WINBOND = 0xEF, +}; + +static struct manufacturer_info flash_manufacturers[] = { + { + .name = "Spansion", + .id = JED_MANU_SPANSION, + .flashes = flash_spansion_serial_flash, + .ops = &flash_st_ops, + }, + { + .name = "ST", + .id = JED_MANU_ST, + .flashes = flash_st_serial_flash, + .ops = &flash_st_ops, + }, + { + .name = "Atmel", + .id = JED_MANU_ATMEL, + .flashes = flash_atmel_dataflash, + .ops = &flash_atmel_ops, + }, + { + .name = "Winbond", + .id = JED_MANU_WINBOND, + .flashes = flash_winbond_serial_flash, + .ops = &flash_winbond_ops, + }, +}; + +#define TIMEOUT 5000 /* timeout of 5 seconds */ + +/* BF54x support */ +#ifndef pSPI_CTL +# define pSPI_CTL pSPI0_CTL +# define pSPI_BAUD pSPI0_BAUD +# define pSPI_FLG pSPI0_FLG +# define pSPI_RDBR pSPI0_RDBR +# define pSPI_STAT pSPI0_STAT +# define pSPI_TDBR pSPI0_TDBR +# define SPI0_SCK 0x0001 +# define SPI0_MOSI 0x0004 +# define SPI0_MISO 0x0002 +# define SPI0_SEL1 0x0010 +#endif + +/* Default to the SPI SSEL that we boot off of: + * BF54x, BF537, (everything new?): SSEL1 + * BF533, BF561: SSEL2 + */ +#ifndef CONFIG_SPI_FLASH_SSEL +# if defined(__ADSPBF531__) || defined(__ADSPBF532__) || \ + defined(__ADSPBF533__) || defined(__ADSPBF561__) +# define CONFIG_SPI_FLASH_SSEL 2 +# else +# define CONFIG_SPI_FLASH_SSEL 1 +# endif +#endif +#define SSEL_MASK (1 << CONFIG_SPI_FLASH_SSEL) + +static void SPI_INIT(void) +{ + /* [#3541] This delay appears to be necessary, but not sure + * exactly why as the history behind it is non-existant. + */ + udelay(CONFIG_CCLK_HZ / 25000000); + + /* enable SPI pins: SSEL, MOSI, MISO, SCK */ +#ifdef __ADSPBF54x__ + *pPORTE_FER |= (SPI0_SCK | SPI0_MOSI | SPI0_MISO | SPI0_SEL1); +#elif defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) + *pPORTF_FER |= (PF10 | PF11 | PF12 | PF13); +#elif defined(__ADSPBF52x__) + bfin_write_PORTG_MUX((bfin_read_PORTG_MUX() & ~PORT_x_MUX_0_MASK) | PORT_x_MUX_0_FUNC_3); + bfin_write_PORTG_FER(bfin_read_PORTG_FER() | PG1 | PG2 | PG3 | PG4); +#endif + + /* initate communication upon write of TDBR */ + *pSPI_CTL = (SPE|MSTR|CPHA|CPOL|0x01); + *pSPI_BAUD = CONFIG_SPI_BAUD; +} + +static void SPI_DEINIT(void) +{ + /* put SPI settings back to reset state */ + *pSPI_CTL = 0x0400; + *pSPI_BAUD = 0; + SSYNC(); +} + +static void SPI_ON(void) +{ + /* toggle SSEL to reset the device so it'll take a new command */ + *pSPI_FLG = 0xFF00 | SSEL_MASK; + SSYNC(); + + *pSPI_FLG = ((0xFF & ~SSEL_MASK) << 8) | SSEL_MASK; + SSYNC(); +} + +static void SPI_OFF(void) +{ + /* put SPI settings back to reset state */ + *pSPI_FLG = 0xFF00; + SSYNC(); +} + +static uint8_t spi_write_read_byte(uint8_t transmit) +{ + *pSPI_TDBR = transmit; + SSYNC(); + + while ((*pSPI_STAT & TXS)) + if (ctrlc()) + break; + while (!(*pSPI_STAT & SPIF)) + if (ctrlc()) + break; + while (!(*pSPI_STAT & RXS)) + if (ctrlc()) + break; + + /* Read dummy to empty the receive register */ + return *pSPI_RDBR; +} + +static uint8_t read_status_register(void) +{ + uint8_t status_register; + + /* send instruction to read status register */ + SPI_ON(); + spi_write_read_byte(flash.ops->status); + /* send dummy to receive the status register */ + status_register = spi_write_read_byte(0); + SPI_OFF(); + + return status_register; +} + +static int wait_for_ready_status(void) +{ + ulong start = get_timer(0); + + while (get_timer(0) - start < TIMEOUT) { + switch (flash.manufacturer_id) { + case JED_MANU_SPANSION: + case JED_MANU_ST: + case JED_MANU_WINBOND: + if (!(read_status_register() & 0x01)) + return 0; + break; + + case JED_MANU_ATMEL: + if (read_status_register() & 0x80) + return 0; + break; + } + + if (ctrlc()) { + puts("\nAbort\n"); + return -1; + } + } + + puts("Timeout\n"); + return -1; +} + +/* Request and read the manufacturer and device id of parts which + * are compatible with the JEDEC standard (JEP106) and use that to + * setup other operating conditions. + */ +static int spi_detect_part(void) +{ + uint16_t dev_id; + size_t i; + + static char called_init; + if (called_init) + return 0; + + SPI_ON(); + + /* Send the request for the part identification */ + spi_write_read_byte(0x9F); + + /* Now read in the manufacturer id bytes */ + do { + flash.manufacturer_id = spi_write_read_byte(0); + if (flash.manufacturer_id == 0x7F) + puts("Warning: unhandled manufacturer continuation byte!\n"); + } while (flash.manufacturer_id == 0x7F); + + /* Now read in the first device id byte */ + flash.device_id1 = spi_write_read_byte(0); + + /* Now read in the second device id byte */ + flash.device_id2 = spi_write_read_byte(0); + + SPI_OFF(); + + dev_id = (flash.device_id1 << 8) | flash.device_id2; + + for (i = 0; i < ARRAY_SIZE(flash_manufacturers); ++i) { + if (flash.manufacturer_id == flash_manufacturers[i].id) + break; + } + if (i == ARRAY_SIZE(flash_manufacturers)) + goto unknown; + + flash.manufacturer = &flash_manufacturers[i]; + flash.ops = flash_manufacturers[i].ops; + + switch (flash.manufacturer_id) { + case JED_MANU_SPANSION: + case JED_MANU_ST: + case JED_MANU_WINBOND: + for (i = 0; flash.manufacturer->flashes[i].name; ++i) { + if (dev_id == flash.manufacturer->flashes[i].id) + break; + } + if (!flash.manufacturer->flashes[i].name) + goto unknown; + + flash.flash = &flash.manufacturer->flashes[i]; + flash.sector_size = flash.flash->sector_size; + flash.num_sectors = flash.flash->num_sectors; + flash.write_length = 256; + break; + + case JED_MANU_ATMEL: { + uint8_t status = read_status_register(); + + for (i = 0; flash.manufacturer->flashes[i].name; ++i) { + if ((status & 0x3c) == flash.manufacturer->flashes[i].id) + break; + } + if (!flash.manufacturer->flashes[i].name) + goto unknown; + + flash.flash = &flash.manufacturer->flashes[i]; + flash.sector_size = flash.flash->sector_size; + flash.num_sectors = flash.flash->num_sectors; + + /* see if flash is in "power of 2" mode */ + if (status & 0x1) + flash.sector_size &= ~(1 << (ffs(flash.sector_size) - 1)); + + flash.write_length = flash.sector_size; + break; + } + } + + called_init = 1; + return 0; + + unknown: + printf("Unknown SPI device: 0x%02X 0x%02X 0x%02X\n", + flash.manufacturer_id, flash.device_id1, flash.device_id2); + return 1; +} + +/* + * Function: spi_init_f + * Description: Init SPI-Controller (ROM part) + * return: --- + */ +void spi_init_f(void) +{ +} + +/* + * Function: spi_init_r + * Description: Init SPI-Controller (RAM part) - + * The malloc engine is ready and we can move our buffers to + * normal RAM + * return: --- + */ +void spi_init_r(void) +{ +#if defined(CONFIG_POST) && (CONFIG_POST & CFG_POST_SPI) + /* Our testing strategy here is pretty basic: + * - fill src memory with an 8-bit pattern + * - write the src memory to the SPI flash + * - read the SPI flash into the dst memory + * - compare src and dst memory regions + * - repeat a few times + * The variations we test for: + * - change the 8-bit pattern a bit + * - change the read/write block size so we know: + * - writes smaller/equal/larger than the buffer work + * - writes smaller/equal/larger than the sector work + * - change the SPI offsets so we know: + * - writing partial sectors works + */ + uint8_t *mem_src, *mem_dst; + size_t i, c, l, o; + size_t test_count, errors; + uint8_t pattern; + + SPI_INIT(); + + if (spi_detect_part()) + goto out; + eeprom_info(); + + ulong lengths[] = { + flash.write_length, + flash.write_length * 2, + flash.write_length / 2, + flash.sector_size, + flash.sector_size * 2, + flash.sector_size / 2 + }; + ulong offsets[] = { + 0, + flash.write_length, + flash.write_length * 2, + flash.write_length / 2, + flash.write_length / 4, + flash.sector_size, + flash.sector_size * 2, + flash.sector_size / 2, + flash.sector_size / 4, + }; + + /* the exact addresses are arbitrary ... they just need to not overlap */ + mem_src = (void *)(0); + mem_dst = (void *)(max(flash.write_length, flash.sector_size) * 2); + + test_count = 0; + errors = 0; + pattern = 0x00; + + for (i = 0; i < 16; ++i) { /* 16 = 8 bits * 2 iterations */ + for (l = 0; l < ARRAY_SIZE(lengths); ++l) { + for (o = 0; o < ARRAY_SIZE(offsets); ++o) { + ulong len = lengths[l]; + ulong off = offsets[o]; + + printf("Testing pattern 0x%02X of length %5lu and offset %5lu: ", pattern, len, off); + + /* setup the source memory region */ + memset(mem_src, pattern, len); + + test_count += 4; + for (c = 0; c < 4; ++c) { /* 4 is just a random repeat count */ + if (ctrlc()) { + puts("\nAbort\n"); + goto out; + } + + /* make sure background fill pattern != pattern */ + memset(mem_dst, pattern ^ 0xFF, len); + + /* write out the source memory and then read it back and compare */ + eeprom_write(0, off, mem_src, len); + eeprom_read(0, off, mem_dst, len); + + if (memcmp(mem_src, mem_dst, len)) { + for (c = 0; c < len; ++c) + if (mem_src[c] != mem_dst[c]) + break; + printf(" FAIL @ offset %u, skipping repeats ", c); + ++errors; + break; + } + + /* XXX: should shrink write region here to test with + * leading/trailing canaries so we know surrounding + * bytes don't get screwed. + */ + } + puts("\n"); + } + } + + /* invert the pattern every other run and shift out bits slowly */ + pattern ^= 0xFF; + if (i % 2) + pattern = (pattern | 0x01) << 1; + } + + if (errors) + printf("SPI FAIL: Out of %i tests, there were %i errors ;(\n", test_count, errors); + else + printf("SPI PASS: %i tests worked!\n", test_count); + + out: + SPI_DEINIT(); + +#endif +} + +static void transmit_address(uint32_t addr) +{ + /* Send the highest byte of the 24 bit address at first */ + spi_write_read_byte(addr >> 16); + /* Send the middle byte of the 24 bit address at second */ + spi_write_read_byte(addr >> 8); + /* Send the lowest byte of the 24 bit address finally */ + spi_write_read_byte(addr); +} + +/* + * Read a value from flash for verify purpose + * Inputs: unsigned long ulStart - holds the SPI start address + * int pnData - pointer to store value read from flash + * long lCount - number of elements to read + */ +static int read_flash(unsigned long address, long count, uchar *buffer) +{ + size_t i; + + /* Send the read command to SPI device */ + SPI_ON(); + spi_write_read_byte(flash.ops->read); + transmit_address(address); + +#ifndef CONFIG_SPI_FLASH_SLOW_READ + /* Send dummy byte when doing SPI fast reads */ + spi_write_read_byte(0); +#endif + + /* After the SPI device address has been placed on the MOSI pin the data can be */ + /* received on the MISO pin. */ + for (i = 1; i <= count; ++i) { + *buffer++ = spi_write_read_byte(0); + if (i % flash.sector_size == 0) + puts("."); + } + + SPI_OFF(); + + return 0; +} + +static int enable_writing(void) +{ + ulong start; + + if (flash.manufacturer_id == JED_MANU_ATMEL) + return 0; + + /* A write enable instruction must previously have been executed */ + SPI_ON(); + spi_write_read_byte(0x06); + SPI_OFF(); + + /* The status register will be polled to check the write enable latch "WREN" */ + start = get_timer(0); + while (get_timer(0) - start < TIMEOUT) { + if (read_status_register() & 0x02) + return 0; + + if (ctrlc()) { + puts("\nAbort\n"); + return -1; + } + } + + puts("Timeout\n"); + return -1; +} + +static long address_to_sector(unsigned long address) +{ + if (address > (flash.num_sectors * flash.sector_size) - 1) + return -1; + return address / flash.sector_size; +} + +static int erase_sector(int address) +{ + /* sector gets checked in higher function, so assume it's valid + * here and figure out the offset of the sector in flash + */ + if (enable_writing()) + return -1; + + /* + * Send the erase block command to the flash followed by the 24 address + * to point to the start of a sector + */ + SPI_ON(); + spi_write_read_byte(flash.ops->erase); + transmit_address(address); + SPI_OFF(); + + return wait_for_ready_status(); +} + +/* Write [count] bytes out of [buffer] into the given SPI [address] */ +static long write_flash(unsigned long address, long count, uchar *buffer) +{ + long i, write_buffer_size; + + if (enable_writing()) + return -1; + + /* Send write command followed by the 24 bit address */ + SPI_ON(); + spi_write_read_byte(flash.ops->write); + transmit_address(address); + + /* Shoot out a single write buffer */ + write_buffer_size = min(count, flash.write_length); + for (i = 0; i < write_buffer_size; ++i) + spi_write_read_byte(buffer[i]); + + SPI_OFF(); + + /* Wait for the flash to do its thing */ + if (wait_for_ready_status()) { + puts("SPI Program Time out! "); + return -1; + } + + return i; +} + +/* Write [count] bytes out of [buffer] into the given SPI [address] */ +static int write_sector(unsigned long address, long count, uchar *buffer) +{ + long write_cnt; + + while (count != 0) { + write_cnt = write_flash(address, count, buffer); + if (write_cnt == -1) + return -1; + + /* Now that we've sent some bytes out to the flash, update + * our counters a bit + */ + count -= write_cnt; + address += write_cnt; + buffer += write_cnt; + } + + /* return the appropriate error code */ + return 0; +} + +/* + * Function: spi_write + */ +ssize_t spi_write(uchar *addr, int alen, uchar *buffer, int len) +{ + unsigned long offset; + int start_sector, end_sector; + int start_byte, end_byte; + uchar *temp = NULL; + int num, ret = 0; + + SPI_INIT(); + + if (spi_detect_part()) + goto out; + + offset = addr[0] << 16 | addr[1] << 8 | addr[2]; + + /* Get the start block number */ + start_sector = address_to_sector(offset); + if (start_sector == -1) { + puts("Invalid sector! "); + goto out; + } + end_sector = address_to_sector(offset + len - 1); + if (end_sector == -1) { + puts("Invalid sector! "); + goto out; + } + + /* Since flashes operate in sector units but the eeprom command + * operates as a continuous stream of bytes, we need to emulate + * the eeprom behavior. So here we read in the sector, overlay + * any bytes we're actually modifying, erase the sector, and + * then write back out the new sector. + */ + temp = malloc(flash.sector_size); + if (!temp) { + puts("Malloc for sector failed! "); + goto out; + } + + for (num = start_sector; num <= end_sector; num++) { + unsigned long address = num * flash.sector_size; + + /* XXX: should add an optimization when spanning sectors: + * No point in reading in a sector if we're going to be + * clobbering the whole thing. Need to also add a test + * case to make sure the optimization is correct. + */ + if (read_flash(address, flash.sector_size, temp)) { + puts("Read sector failed! "); + len = 0; + break; + } + + start_byte = max(address, offset); + end_byte = address + flash.sector_size - 1; + if (end_byte > (offset + len)) + end_byte = (offset + len - 1); + + memcpy(temp + start_byte - address, + buffer + start_byte - offset, + end_byte - start_byte + 1); + + if (erase_sector(address)) { + puts("Erase sector failed! "); + goto out; + } + + if (write_sector(address, flash.sector_size, temp)) { + puts("Write sector failed! "); + goto out; + } + + puts("."); + } + + ret = len; + + out: + free(temp); + + SPI_DEINIT(); + + return ret; +} + +/* + * Function: spi_read + */ +ssize_t spi_read(uchar *addr, int alen, uchar *buffer, int len) +{ + unsigned long offset; + + SPI_INIT(); + + if (spi_detect_part()) + len = 0; + else { + offset = addr[0] << 16 | addr[1] << 8 | addr[2]; + read_flash(offset, len, buffer); + } + + SPI_DEINIT(); + + return len; +} + +/* + * Spit out some useful information about the SPI eeprom + */ +int eeprom_info(void) +{ + int ret = 0; + + SPI_INIT(); + + if (spi_detect_part()) + ret = 1; + else + printf("SPI Device: %s 0x%02X (%s) 0x%02X 0x%02X\n" + "Parameters: num sectors = %i, sector size = %i, write size = %i\n" + "Flash Size: %i mbit (%i mbyte)\n" + "Status: 0x%02X\n", + flash.flash->name, flash.manufacturer_id, flash.manufacturer->name, + flash.device_id1, flash.device_id2, flash.num_sectors, + flash.sector_size, flash.write_length, + (flash.num_sectors * flash.sector_size) >> 17, + (flash.num_sectors * flash.sector_size) >> 20, + read_status_register()); + + SPI_DEINIT(); + + return ret; +} + +#endif

All of the duplicated code for Blackfin processors and boot modes have been unified. After all, the core is the same for all processors, just the peripheral set differs (which gets handled in the drivers).
Signed-off-by: Mike Frysinger vapier@gentoo.org --- Makefile | 4 +- blackfin_config.mk | 3 + cpu/bf533/Makefile | 52 --- cpu/bf533/bf533_serial.h | 77 ---- cpu/bf533/cache.S | 129 ------ cpu/bf533/config.mk | 27 -- cpu/bf533/cpu.c | 213 ---------- cpu/bf533/cpu.h | 66 --- cpu/bf533/flush.S | 405 ------------------- cpu/bf533/init_sdram.S | 183 --------- cpu/bf533/init_sdram_bootrom_initblock.S | 183 --------- cpu/bf533/interrupt.S | 244 ----------- cpu/bf533/interrupts.c | 165 -------- cpu/bf533/ints.c | 112 ------ cpu/bf533/serial.c | 186 --------- cpu/bf533/start.S | 313 --------------- cpu/bf533/start1.S | 38 -- cpu/bf533/traps.c | 238 ----------- cpu/bf533/video.c | 194 --------- cpu/bf533/video.h | 25 -- cpu/bf537/Makefile | 52 --- cpu/bf537/cache.S | 129 ------ cpu/bf537/config.mk | 27 -- cpu/bf537/cpu.c | 219 ---------- cpu/bf537/cpu.h | 66 --- cpu/bf537/flush.S | 403 ------------------- cpu/bf537/i2c.c | 418 ------------------- cpu/bf537/init_sdram.S | 178 --------- cpu/bf537/init_sdram_bootrom_initblock.S | 203 ---------- cpu/bf537/interrupt.S | 244 ----------- cpu/bf537/interrupts.c | 170 -------- cpu/bf537/ints.c | 112 ------ cpu/bf537/serial.c | 186 --------- cpu/bf537/serial.h | 77 ---- cpu/bf537/start.S | 576 --------------------------- cpu/bf537/start1.S | 38 -- cpu/bf537/traps.c | 239 ----------- cpu/bf537/video.c | 194 --------- cpu/bf537/video.h | 25 -- cpu/bf561/Makefile | 52 --- cpu/bf561/cache.S | 129 ------ cpu/bf561/config.mk | 27 -- cpu/bf561/cpu.c | 212 ---------- cpu/bf561/cpu.h | 66 --- cpu/bf561/flush.S | 402 ------------------- cpu/bf561/init_sdram.S | 175 -------- cpu/bf561/init_sdram_bootrom_initblock.S | 189 --------- cpu/bf561/interrupt.S | 244 ----------- cpu/bf561/interrupts.c | 167 -------- cpu/bf561/ints.c | 112 ------ cpu/bf561/serial.c | 188 --------- cpu/bf561/serial.h | 77 ---- cpu/bf561/start.S | 303 -------------- cpu/bf561/start1.S | 38 -- cpu/bf561/traps.c | 238 ----------- cpu/bf561/video.c | 194 --------- cpu/bf561/video.h | 25 -- cpu/blackfin/.gitignore | 1 + cpu/blackfin/Makefile | 65 +++ cpu/blackfin/bootrom-asm-offsets.awk | 41 ++ cpu/blackfin/bootrom-asm-offsets.c.in | 12 + cpu/blackfin/cache.S | 61 +++ cpu/blackfin/cpu.c | 141 +++++++ cpu/blackfin/cpu.h | 38 ++ cpu/blackfin/flush.S | 230 +++++++++++ cpu/blackfin/initcode.c | 353 ++++++++++++++++ cpu/blackfin/interrupt.S | 33 ++ cpu/blackfin/interrupts.c | 155 +++++++ cpu/blackfin/reset.c | 96 +++++ cpu/blackfin/serial.c | 124 ++++++ cpu/blackfin/serial.h | 275 +++++++++++++ cpu/blackfin/start.S | 219 ++++++++++ cpu/blackfin/system_map.S | 18 + cpu/blackfin/traps.c | 353 ++++++++++++++++ cpu/blackfin/watchdog.c | 25 ++ include/asm-blackfin/blackfin-config-post.h | 6 +- include/configs/bf533-ezkit.h | 44 +-- include/configs/bf533-stamp.h | 113 +----- include/configs/bf537-stamp.h | 104 +---- include/configs/bf561-ezkit.h | 40 +-- lib_blackfin/board.c | 39 +-- 100 files changed, 3422 insertions(+), 10330 deletions(-) delete mode 100644 cpu/bf533/Makefile delete mode 100644 cpu/bf533/bf533_serial.h delete mode 100644 cpu/bf533/cache.S delete mode 100644 cpu/bf533/config.mk delete mode 100644 cpu/bf533/cpu.c delete mode 100644 cpu/bf533/cpu.h delete mode 100644 cpu/bf533/flush.S delete mode 100644 cpu/bf533/init_sdram.S delete mode 100644 cpu/bf533/init_sdram_bootrom_initblock.S delete mode 100644 cpu/bf533/interrupt.S delete mode 100644 cpu/bf533/interrupts.c delete mode 100644 cpu/bf533/ints.c delete mode 100644 cpu/bf533/serial.c delete mode 100644 cpu/bf533/start.S delete mode 100644 cpu/bf533/start1.S delete mode 100644 cpu/bf533/traps.c delete mode 100644 cpu/bf533/video.c delete mode 100644 cpu/bf533/video.h delete mode 100644 cpu/bf537/Makefile delete mode 100644 cpu/bf537/cache.S delete mode 100644 cpu/bf537/config.mk delete mode 100644 cpu/bf537/cpu.c delete mode 100644 cpu/bf537/cpu.h delete mode 100644 cpu/bf537/flush.S delete mode 100644 cpu/bf537/i2c.c delete mode 100644 cpu/bf537/init_sdram.S delete mode 100644 cpu/bf537/init_sdram_bootrom_initblock.S delete mode 100644 cpu/bf537/interrupt.S delete mode 100644 cpu/bf537/interrupts.c delete mode 100644 cpu/bf537/ints.c delete mode 100644 cpu/bf537/serial.c delete mode 100644 cpu/bf537/serial.h delete mode 100644 cpu/bf537/start.S delete mode 100644 cpu/bf537/start1.S delete mode 100644 cpu/bf537/traps.c delete mode 100644 cpu/bf537/video.c delete mode 100644 cpu/bf537/video.h delete mode 100644 cpu/bf561/Makefile delete mode 100644 cpu/bf561/cache.S delete mode 100644 cpu/bf561/config.mk delete mode 100644 cpu/bf561/cpu.c delete mode 100644 cpu/bf561/cpu.h delete mode 100644 cpu/bf561/flush.S delete mode 100644 cpu/bf561/init_sdram.S delete mode 100644 cpu/bf561/init_sdram_bootrom_initblock.S delete mode 100644 cpu/bf561/interrupt.S delete mode 100644 cpu/bf561/interrupts.c delete mode 100644 cpu/bf561/ints.c delete mode 100644 cpu/bf561/serial.c delete mode 100644 cpu/bf561/serial.h delete mode 100644 cpu/bf561/start.S delete mode 100644 cpu/bf561/start1.S delete mode 100644 cpu/bf561/traps.c delete mode 100644 cpu/bf561/video.c delete mode 100644 cpu/bf561/video.h create mode 100644 cpu/blackfin/.gitignore create mode 100644 cpu/blackfin/Makefile create mode 100755 cpu/blackfin/bootrom-asm-offsets.awk create mode 100644 cpu/blackfin/bootrom-asm-offsets.c.in create mode 100644 cpu/blackfin/cache.S create mode 100644 cpu/blackfin/cpu.c create mode 100644 cpu/blackfin/cpu.h create mode 100644 cpu/blackfin/flush.S create mode 100644 cpu/blackfin/i2c.c create mode 100644 cpu/blackfin/initcode.c create mode 100644 cpu/blackfin/interrupt.S create mode 100644 cpu/blackfin/interrupts.c create mode 100644 cpu/blackfin/reset.c create mode 100644 cpu/blackfin/serial.c create mode 100644 cpu/blackfin/serial.h create mode 100644 cpu/blackfin/start.S create mode 100644 cpu/blackfin/system_map.S create mode 100644 cpu/blackfin/traps.c create mode 100644 cpu/blackfin/watchdog.c
diff --git a/Makefile b/Makefile index 2790865..abbd193 100644 --- a/Makefile +++ b/Makefile @@ -2834,7 +2834,8 @@ xupv2p_config: unconfig BFIN_BOARDS = bf533-ezkit bf533-stamp bf537-stamp bf561-ezkit
$(BFIN_BOARDS:%=%_config) : unconfig - @$(MKCONFIG) $(@:_config=) blackfin $(firstword $(subst -, ,$@)) $(@:_config=) + @$(MKCONFIG) $(@:_config=) blackfin blackfin $(@:_config=) +# @$(MKCONFIG) $(@:_config=) blackfin $(firstword $(subst -, ,$@)) $(@:_config=)
$(BFIN_BOARDS): $(MAKE) $@_config @@ -2911,6 +2912,7 @@ clean: @rm -f $(obj)board/integratorap/u-boot.lds $(obj)board/integratorcp/u-boot.lds @rm -f $(obj)board/bf533-ezkit/u-boot.lds $(obj)board/bf533-stamp/u-boot.lds @rm -f $(obj)board/bf537-stamp/u-boot.lds $(obj)board/bf561-ezkit/u-boot.lds + @rm -f $(obj)cpu/blackfin/bootrom-asm-offsets.[chs] @rm -f $(obj)include/bmp_logo.h @rm -f $(obj)nand_spl/u-boot-spl $(obj)nand_spl/u-boot-spl.map @rm -f $(obj)onenand_ipl/onenand-ipl $(obj)onenand_ipl/onenand-ipl.bin \ diff --git a/blackfin_config.mk b/blackfin_config.mk index d90eb23..a9a3d1a 100644 --- a/blackfin_config.mk +++ b/blackfin_config.mk @@ -21,6 +21,9 @@ # MA 02111-1307 USA #
+CONFIG_BFIN_CPU := $(strip $(subst ",,$(CONFIG_BFIN_CPU))) +CONFIG_BFIN_BOOT_MODE := $(strip $(subst ",,$(CONFIG_BFIN_BOOT_MODE))) + PLATFORM_RELFLAGS += -ffixed-P5 PLATFORM_CPPFLAGS += -DCONFIG_BLACKFIN
diff --git a/board/bf537-stamp/bf537-stamp.c b/board/bf537-stamp/bf537-stamp.c index 6ca8e21..533da03 100644 --- a/board/bf537-stamp/bf537-stamp.c +++ b/board/bf537-stamp/bf537-stamp.c @@ -120,12 +120,11 @@ long int initdram(int board_type) /* miscellaneous platform dependent initialisations */ int misc_init_r(void) { -#if (BFIN_BOOT_MODE == BF537_BYPASS_BOOT) +#if defined(CONFIG_CMD_NET) char nid[32]; unsigned char *pMACaddr = (unsigned char *)0x203F0000; u8 SrcAddr[6] = { 0x02, 0x80, 0xAD, 0x20, 0x31, 0xB8 };
-#if defined(CONFIG_CMD_NET) /* The 0xFF check here is to make sure we don't use the address * in flash if it's simply been erased (aka all 0xFF values) */ if (getenv("ethaddr") == NULL && is_valid_ether_addr(pMACaddr)) { @@ -135,7 +134,6 @@ int misc_init_r(void) setenv("ethaddr", nid); } #endif -#endif /* BFIN_BOOT_MODE == BF537_BYPASS_BOOT */
#if defined(CONFIG_BFIN_IDE) #if defined(CONFIG_BFIN_TRUE_IDE) @@ -158,13 +156,6 @@ int misc_init_r(void) #endif /* CONFIG_MISC_INIT_R */
#ifdef CONFIG_POST -#if (BFIN_BOOT_MODE != BF537_BYPASS_BOOT) -/* Using sw10-PF5 as the hotkey */ -int post_hotkeys_pressed(void) -{ - return 0; -} -#else /* Using sw10-PF5 as the hotkey */ int post_hotkeys_pressed(void) { @@ -197,7 +188,6 @@ int post_hotkeys_pressed(void) } } #endif -#endif
#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER) void post_word_store(ulong a) diff --git a/cpu/blackfin/.gitignore b/cpu/blackfin/.gitignore new file mode 100644 index 0000000..0ec9d56 --- /dev/null +++ b/cpu/blackfin/.gitignore @@ -0,0 +1 @@ +bootrom-asm-offsets.[chs] diff --git a/cpu/blackfin/Makefile b/cpu/blackfin/Makefile new file mode 100644 index 0000000..f484e8f --- /dev/null +++ b/cpu/blackfin/Makefile @@ -0,0 +1,65 @@ +# +# U-boot - Makefile +# +# Copyright (c) 2005-2008 Analog Device Inc. +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# Licensed under the GPL-2 or later. +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +EXTRA := +CEXTRA := initcode.o +SEXTRA := start.o +SOBJS := interrupt.o cache.o flush.o +COBJS := cpu.o traps.o interrupts.o reset.o serial.o i2c.o watchdog.o + +ifeq ($(CONFIG_BFIN_BOOT_MODE),BFIN_BOOT_BYPASS) +COBJS += initcode.o +endif + +SRCS := $(SEXTRA:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +EXTRA := $(addprefix $(obj),$(EXTRA)) +CEXTRA := $(addprefix $(obj),$(CEXTRA)) +SEXTRA := $(addprefix $(obj),$(SEXTRA)) + +all: $(obj).depend $(LIB) $(obj).depend $(EXTRA) $(CEXTRA) $(SEXTRA) check_initcode + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +$(OBJS): $(obj)bootrom-asm-offsets.h +$(obj)bootrom-asm-offsets.c: bootrom-asm-offsets.c.in bootrom-asm-offsets.awk + echo '#include <asm/mach-common/bits/bootrom.h>' | $(CPP) $(CPPFLAGS) - | ./bootrom-asm-offsets.awk > $@.tmp + mv $@.tmp $@ +$(obj)bootrom-asm-offsets.s: $(obj)bootrom-asm-offsets.c + $(CC) $(CFLAGS) -S $^ -o $@.tmp + mv $@.tmp $@ +$(obj)bootrom-asm-offsets.h: $(obj)bootrom-asm-offsets.s + sed -ne "/^->/{s:^->([^ ]*) [$$#]*([^ ]*) (.*):#define \1 \2 /* \3 */:; s:->::; p;}" $^ > $@ + +# make sure our initcode (which goes into LDR) does not +# have relocs or external references +READINIT = env LC_ALL=C $(CROSS_COMPILE)readelf -s $< +check_initcode: $(obj)initcode.o +ifneq ($(CONFIG_BFIN_BOOT_MODE),BFIN_BOOT_BYPASS) + @if $(READINIT) | grep '<GLOBAL>.*<UND>' ; then \ + echo "$< contains external references!" 1>&2 ; \ + exit 1 ; \ + fi +endif + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/cpu/blackfin/bootrom-asm-offsets.awk b/cpu/blackfin/bootrom-asm-offsets.awk new file mode 100755 index 0000000..1d61824 --- /dev/null +++ b/cpu/blackfin/bootrom-asm-offsets.awk @@ -0,0 +1,41 @@ +#!/usr/bin/gawk -f +BEGIN { + print "/* DO NOT EDIT: AUTOMATICALLY GENERATED" + print " * Input files: bootrom-asm-offsets.awk bootrom-asm-offsets.c.in" + print " * DO NOT EDIT: AUTOMATICALLY GENERATED" + print " */" + print "" + system("cat bootrom-asm-offsets.c.in") + print "{" +} + +{ + /* find a structure definition */ + if ($0 ~ /typedef struct .* {/) { + delete members; + i = 0; + + /* extract each member of the structure */ + while (1) { + getline + if ($1 == "}") + break; + gsub(/[*;]/, ""); + members[i++] = $NF; + } + + /* grab the structure's name */ + struct = $NF; + sub(/;$/, "", struct); + + /* output the DEFINE() macros */ + while (i-- > 0) + print "\tDEFINE(" struct ", " members[i] ");" + print "" + } +} + +END { + print "\treturn 0;" + print "}" +} diff --git a/cpu/blackfin/bootrom-asm-offsets.c.in b/cpu/blackfin/bootrom-asm-offsets.c.in new file mode 100644 index 0000000..3146e46 --- /dev/null +++ b/cpu/blackfin/bootrom-asm-offsets.c.in @@ -0,0 +1,12 @@ +/* A little trick taken from the kernel asm-offsets.h where we convert + * the C structures automatically into a bunch of defines for use in + * the assembly files. + */ + +#include <linux/stddef.h> +#include <asm/mach-common/bits/bootrom.h> + +#define _DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val)) +#define DEFINE(s, m) _DEFINE(offset_##s##_##m, offsetof(s, m)) + +int main(int argc, char *argv[]) diff --git a/cpu/blackfin/cache.S b/cpu/blackfin/cache.S new file mode 100644 index 0000000..51bdb30 --- /dev/null +++ b/cpu/blackfin/cache.S @@ -0,0 +1,61 @@ +/* cache.S - low level cache handling routines + * Copyright (C) 2003-2007 Analog Devices Inc. + * Licensed under the GPL-2 or later. + */ + +#include <asm/linkage.h> +#include <config.h> +#include <asm/blackfin.h> + +.text +.align 2 +ENTRY(_blackfin_icache_flush_range) + R2 = -32; + R2 = R0 & R2; + P0 = R2; + P1 = R1; + CSYNC; +1: + IFLUSH[P0++]; + CC = P0 < P1(iu); + IF CC JUMP 1b(bp); + IFLUSH[P0]; + SSYNC; + RTS; +ENDPROC(_blackfin_icache_flush_range) + +ENTRY(_blackfin_dcache_flush_range) + R2 = -32; + R2 = R0 & R2; + P0 = R2; + P1 = R1; + CSYNC; +1: + FLUSH[P0++]; + CC = P0 < P1(iu); + IF CC JUMP 1b(bp); + FLUSH[P0]; + SSYNC; + RTS; +ENDPROC(_blackfin_dcache_flush_range) + +ENTRY(_blackfin_dcache_invalidate_range) + R2 = -32; + R2 = R0 & R2; + P0 = R2; + P1 = R1; + CSYNC; +1: + FLUSHINV[P0++]; + CC = P0 < P1(iu); + IF CC JUMP 1b(bp); + + /* + * If the data crosses a cache line, then we'll be pointing to + * the last cache line, but won't have flushed/invalidated it yet, so do + * one more. + */ + FLUSHINV[P0]; + SSYNC; + RTS; +ENDPROC(_blackfin_dcache_invalidate_range) diff --git a/cpu/blackfin/cpu.c b/cpu/blackfin/cpu.c new file mode 100644 index 0000000..53de5ab --- /dev/null +++ b/cpu/blackfin/cpu.c @@ -0,0 +1,141 @@ +/* + * U-boot - cpu.c CPU specific functions + * + * Copyright (c) 2005-2008 Analog Devices Inc. + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Licensed under the GPL-2 or later. + */ + +#include <common.h> +#include <command.h> +#include <asm/blackfin.h> +#include <asm/cplb.h> +#include <asm/mach-common/bits/core.h> +#include <asm/mach-common/bits/mpu.h> +#include <asm/mach-common/bits/trace.h> + +#include "cpu.h" +#include "serial.h" + +void icache_enable(void) +{ + bfin_write_IMEM_CONTROL(bfin_read_IMEM_CONTROL() | (IMC | ENICPLB)); + SSYNC(); +} + +void icache_disable(void) +{ + bfin_write_IMEM_CONTROL(bfin_read_IMEM_CONTROL() & ~(IMC | ENICPLB)); + SSYNC(); +} + +int icache_status(void) +{ + return bfin_read_IMEM_CONTROL() & ENICPLB; +} + +void dcache_enable(void) +{ + bfin_write_DMEM_CONTROL(bfin_read_DMEM_CONTROL() | (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)); + SSYNC(); +} + +void dcache_disable(void) +{ + bfin_write_DMEM_CONTROL(bfin_read_DMEM_CONTROL() & ~(ACACHE_BCACHE | ENDCPLB | PORT_PREF0)); + SSYNC(); +} + +int dcache_status(void) +{ + return bfin_read_DMEM_CONTROL() & ENDCPLB; +} + +__attribute__ ((__noreturn__)) +void cpu_init_f(ulong bootflag, ulong loaded_from_ldr) +{ + /* Build a NOP slide over the LDR jump block. Whee! */ + serial_early_puts("NOP Slide\n"); + char nops[0xC]; + memset(nops, 0x00, sizeof(nops)); + extern char _stext_l1; + memcpy(&_stext_l1 - sizeof(nops), nops, sizeof(nops)); + + if (!loaded_from_ldr) { + /* Relocate sections into L1 if the LDR didn't do it -- don't + * check length because the linker script does the size + * checking at build time. + */ + serial_early_puts("L1 Relocate\n"); + extern char _stext_l1, _etext_l1, _stext_l1_lma; + memcpy(&_stext_l1, &_stext_l1_lma, (&_etext_l1 - &_stext_l1)); + extern char _sdata_l1, _edata_l1, _sdata_l1_lma; + memcpy(&_sdata_l1, &_sdata_l1_lma, (&_edata_l1 - &_sdata_l1)); + } +#if defined(__ADSPBF537__) || defined(__ADSPBF536__) || defined(__ADSPBF534__) + /* The BF537 bootrom will reset the EBIU_AMGCTL register on us + * after it has finished loading the LDR. So configure it again. + */ + else + bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL); +#endif + +#ifdef CONFIG_DEBUG_DUMP + /* Turn on hardware trace buffer */ + bfin_write_TBUFCTL(TBUFPWR | TBUFEN); +#endif + +#ifndef CONFIG_PANIC_HANG + /* Reset upon a double exception rather than just hanging. + * Do not do bfin_read on SWRST as that will reset status bits. + */ + bfin_write_SWRST(DOUBLE_FAULT); +#endif + + serial_early_puts("Board init flash\n"); + board_init_f(bootflag); +} + +int exception_init(void) +{ + bfin_write_EVT3(trap); + return 0; +} + +int irq_init(void) +{ +#ifdef SIC_IMASK0 + bfin_write_SIC_IMASK0(0); + bfin_write_SIC_IMASK1(0); +# ifdef SIC_IMASK2 + bfin_write_SIC_IMASK2(0); +# endif +#elif defined(SICA_IMASK0) + bfin_write_SICA_IMASK0(0); + bfin_write_SICA_IMASK1(0); +#else + bfin_write_SIC_IMASK(0); +#endif + bfin_write_EVT2(evt_default); /* NMI */ + bfin_write_EVT5(evt_default); /* hardware error */ + bfin_write_EVT6(evt_default); /* core timer */ + bfin_write_EVT7(evt_default); + bfin_write_EVT8(evt_default); + bfin_write_EVT9(evt_default); + bfin_write_EVT10(evt_default); + bfin_write_EVT11(evt_default); + bfin_write_EVT12(evt_default); + bfin_write_EVT13(evt_default); + bfin_write_EVT14(evt_default); + bfin_write_EVT15(evt_default); + bfin_write_ILAT(0); + CSYNC(); + /* enable all interrupts except for core timer */ + irq_flags = 0xffffffbf; + local_irq_enable(); + CSYNC(); + return 0; +} diff --git a/cpu/blackfin/cpu.h b/cpu/blackfin/cpu.h new file mode 100644 index 0000000..0a13c28 --- /dev/null +++ b/cpu/blackfin/cpu.h @@ -0,0 +1,38 @@ +/* + * U-boot - cpu.h + * + * Copyright (c) 2005-2007 Analog Devices Inc. + * + * 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., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _CPU_H_ +#define _CPU_H_ + +#include <command.h> + +void board_reset(void) __attribute__((__weak__)); +void bfin_reset_or_hang(void) __attribute__((__noreturn__)); +void bfin_panic(struct pt_regs *reg); +void dump(struct pt_regs *regs); + +asmlinkage void trap(void); +asmlinkage void evt_default(void); + +#endif diff --git a/cpu/blackfin/flush.S b/cpu/blackfin/flush.S new file mode 100644 index 0000000..8072b86 --- /dev/null +++ b/cpu/blackfin/flush.S @@ -0,0 +1,230 @@ +/* flush.S - low level cache flushing routines + * Copyright (C) 2003-2007 Analog Devices Inc. + * Licensed under the GPL-2 or later. + */ + +#include <config.h> +#include <asm/blackfin.h> +#include <asm/cplb.h> +#include <asm/mach-common/bits/mpu.h> + +.text + +/* This is an external function being called by the user + * application through __flush_cache_all. Currently this function + * serves the purpose of flushing all the pending writes in + * in the data cache. + */ + +ENTRY(_flush_data_cache) + [--SP] = ( R7:6, P5:4 ); + LINK 12; + SP += -12; + P5.H = HI(DCPLB_ADDR0); + P5.L = LO(DCPLB_ADDR0); + P4.H = HI(DCPLB_DATA0); + P4.L = LO(DCPLB_DATA0); + R7 = CPLB_VALID | CPLB_L1_CHBL | CPLB_DIRTY (Z); + R6 = 16; +.Lnext: R0 = [P5++]; + R1 = [P4++]; + CC = BITTST(R1, 14); /* Is it write-through?*/ + IF CC JUMP .Lskip; /* If so, ignore it.*/ + R2 = R1 & R7; /* Is it a dirty, cached page?*/ + CC = R2; + IF !CC JUMP .Lskip; /* If not, ignore it.*/ + [--SP] = RETS; + CALL _dcplb_flush; /* R0 = page, R1 = data*/ + RETS = [SP++]; +.Lskip: R6 += -1; + CC = R6; + IF CC JUMP .Lnext; + SSYNC; + SP += 12; + UNLINK; + ( R7:6, P5:4 ) = [SP++]; + RTS; +ENDPROC(_flush_data_cache) + +/* This is an internal function to flush all pending + * writes in the cache associated with a particular DCPLB. + * + * R0 - page's start address + * R1 - CPLB's data field. + */ + +.align 2 +ENTRY(_dcplb_flush) + [--SP] = ( R7:0, P5:0 ); + [--SP] = LC0; + [--SP] = LT0; + [--SP] = LB0; + [--SP] = LC1; + [--SP] = LT1; + [--SP] = LB1; + + /* If it's a 1K or 4K page, then it's quickest to + * just systematically flush all the addresses in + * the page, regardless of whether they're in the + * cache, or dirty. If it's a 1M or 4M page, there + * are too many addresses, and we have to search the + * cache for lines corresponding to the page. + */ + + CC = BITTST(R1, 17); /* 1MB or 4MB */ + IF !CC JUMP .Ldflush_whole_page; + + /* We're only interested in the page's size, so extract + * this from the CPLB (bits 17:16), and scale to give an + * offset into the page_size and page_prefix tables. + */ + + R1 <<= 14; + R1 >>= 30; + R1 <<= 2; + + /* The page could be mapped into Bank A or Bank B, depending + * on (a) whether both banks are configured as cache, and + * (b) on whether address bit A[x] is set. x is determined + * by DCBS in DMEM_CONTROL + */ + + R2 = 0; /* Default to Bank A (Bank B would be 1)*/ + + P0.L = LO(DMEM_CONTROL); + P0.H = HI(DMEM_CONTROL); + + R3 = [P0]; /* If Bank B is not enabled as cache*/ + CC = BITTST(R3, 2); /* then Bank A is our only option.*/ + IF CC JUMP .Lbank_chosen; + + R4 = 1<<14; /* If DCBS==0, use A[14].*/ + R5 = R4 << 7; /* If DCBS==1, use A[23];*/ + CC = BITTST(R3, 4); + IF CC R4 = R5; /* R4 now has either bit 14 or bit 23 set.*/ + R5 = R0 & R4; /* Use it to test the Page address*/ + CC = R5; /* and if that bit is set, we use Bank B,*/ + R2 = CC; /* else we use Bank A.*/ + R2 <<= 23; /* The Bank selection's at posn 23.*/ + +.Lbank_chosen: + + /* We can also determine the sub-bank used, because this is + * taken from bits 13:12 of the address. + */ + + R3 = ((12<<8)|2); /* Extraction pattern */ + nop; /*Anamoly 05000209*/ + R4 = EXTRACT(R0, R3.L) (Z); /* Extract bits*/ + /* Save in extraction pattern for later deposit.*/ + R3.H = R4.L << 0; + + /* So: + * R0 = Page start + * R1 = Page length (actually, offset into size/prefix tables) + * R2 = Bank select mask + * R3 = sub-bank deposit values + * + * The cache has 2 Ways, and 64 sets, so we iterate through + * the sets, accessing the tag for each Way, for our Bank and + * sub-bank, looking for dirty, valid tags that match our + * address prefix. + */ + + P5.L = LO(DTEST_COMMAND); + P5.H = HI(DTEST_COMMAND); + P4.L = LO(DTEST_DATA0); + P4.H = HI(DTEST_DATA0); + + P0.L = page_prefix_table; + P0.H = page_prefix_table; + P1 = R1; + R5 = 0; /* Set counter*/ + P0 = P1 + P0; + R4 = [P0]; /* This is the address prefix*/ + + + /* We're reading (bit 1==0) the tag (bit 2==0), and we + * don't care about which double-word, since we're only + * fetching tags, so we only have to set Set, Bank, + * Sub-bank and Way. + */ + + P2 = 2; + LSETUP (.Lfs1, .Lfe1) LC1 = P2; +.Lfs1: P0 = 64; /* iterate over all sets*/ + LSETUP (.Lfs0, .Lfe0) LC0 = P0; +.Lfs0: R6 = R5 << 5; /* Combine set*/ + R6.H = R3.H << 0 ; /* and sub-bank*/ + R6 = R6 | R2; /* and Bank. Leave Way==0 at first.*/ + BITSET(R6,14); + [P5] = R6; /* Issue Command*/ + SSYNC; + R7 = [P4]; /* and read Tag.*/ + CC = BITTST(R7, 0); /* Check if valid*/ + IF !CC JUMP .Lfskip; /* and skip if not.*/ + CC = BITTST(R7, 1); /* Check if dirty*/ + IF !CC JUMP .Lfskip; /* and skip if not.*/ + + /* Compare against the page address. First, plant bits 13:12 + * into the tag, since those aren't part of the returned data. + */ + + R7 = DEPOSIT(R7, R3); /* set 13:12*/ + R1 = R7 & R4; /* Mask off lower bits*/ + CC = R1 == R0; /* Compare against page start.*/ + IF !CC JUMP .Lfskip; /* Skip it if it doesn't match.*/ + + /* Tag address matches against page, so this is an entry + * we must flush. + */ + + R7 >>= 10; /* Mask off the non-address bits*/ + R7 <<= 10; + P3 = R7; + SSYNC; + FLUSHINV [P3]; /* And flush the entry*/ +.Lfskip: +.Lfe0: R5 += 1; /* Advance to next Set*/ +.Lfe1: BITSET(R2, 26); /* Go to next Way.*/ + +.Ldfinished: + SSYNC; /* Ensure the data gets out to mem.*/ + + /*Finished. Restore context.*/ + LB1 = [SP++]; + LT1 = [SP++]; + LC1 = [SP++]; + LB0 = [SP++]; + LT0 = [SP++]; + LC0 = [SP++]; + ( R7:0, P5:0 ) = [SP++]; + RTS; + +.Ldflush_whole_page: + + /* It's a 1K or 4K page, so quicker to just flush the + * entire page. + */ + + P1 = 32; /* For 1K pages*/ + P2 = P1 << 2; /* For 4K pages*/ + P0 = R0; /* Start of page*/ + CC = BITTST(R1, 16); /* Whether 1K or 4K*/ + IF CC P1 = P2; + P1 += -1; /* Unroll one iteration*/ + SSYNC; + FLUSHINV [P0++]; /* because CSYNC can't end loops.*/ + LSETUP (.Leall, .Leall) LC0 = P1; +.Leall: FLUSHINV [P0++]; + SSYNC; + JUMP .Ldfinished; +ENDPROC(_dcplb_flush) + +.align 4; +page_prefix_table: +.byte4 0xFFFFFC00; /* 1K */ +.byte4 0xFFFFF000; /* 4K */ +.byte4 0xFFF00000; /* 1M */ +.byte4 0xFFC00000; /* 4M */ +.page_prefix_table.end: diff --git a/cpu/blackfin/initcode.c b/cpu/blackfin/initcode.c new file mode 100644 index 0000000..ffc8420 --- /dev/null +++ b/cpu/blackfin/initcode.c @@ -0,0 +1,353 @@ +/* + * initcode.c - Initialize the processor. This is usually entails things + * like external memory, voltage regulators, etc... Note that this file + * cannot make any function calls as it may be executed all by itself by + * the Blackfin's bootrom in LDR format. + * + * Copyright (c) 2004-2008 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <config.h> +#include <asm/blackfin.h> +#include <asm/mach-common/bits/bootrom.h> +#include <asm/mach-common/bits/ebiu.h> +#include <asm/mach-common/bits/pll.h> +#include <asm/mach-common/bits/uart.h> + +#define BFIN_IN_INITCODE +#include "serial.h" + +__attribute__((always_inline)) +static inline uint32_t serial_init(void) +{ +#ifdef __ADSPBF54x__ +# ifdef BFIN_BOOT_UART_USE_RTS +# define BFIN_UART_USE_RTS 1 +# else +# define BFIN_UART_USE_RTS 0 +# endif + if (BFIN_UART_USE_RTS && CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) { + size_t i; + + /* force RTS rather than relying on auto RTS */ + bfin_write_UART1_MCR(bfin_read_UART1_MCR() | FCPOL); + + /* Wait for the line to clear up. We cannot rely on UART + * registers as none of them reflect the status of the RSR. + * Instead, we'll sleep for ~10 bit times at 9600 baud. + * We can precalc things here by assuming boot values for + * PLL rather than loading registers and calculating. + * baud = SCLK / (16 ^ (1 - EDBO) * Divisor) + * EDB0 = 0 + * Divisor = (SCLK / baud) / 16 + * SCLK = baud * 16 * Divisor + * SCLK = (0x14 * CONFIG_CLKIN_HZ) / 5 + * CCLK = (16 * Divisor * 5) * (9600 / 10) + * In reality, this will probably be just about 1 second delay, + * so assuming 9600 baud is OK (both as a very low and too high + * speed as this will buffer things enough). + */ +#define _NUMBITS (10) /* how many bits to delay */ +#define _LOWBAUD (9600) /* low baud rate */ +#define _SCLK ((0x14 * CONFIG_CLKIN_HZ) / 5) /* SCLK based on PLL */ +#define _DIVISOR ((_SCLK / _LOWBAUD) / 16) /* UART DLL/DLH */ +#define _NUMINS (3) /* how many instructions in loop */ +#define _CCLK (((16 * _DIVISOR * 5) * (_LOWBAUD / _NUMBITS)) / _NUMINS) + i = _CCLK; + while (i--) + asm volatile("" : : : "memory"); + } +#endif + + uint32_t old_baud = serial_early_get_baud(); + + if (BFIN_DEBUG_EARLY_SERIAL) { + serial_early_init(); + + /* If the UART is off, that means we need to program + * the baud rate ourselves initially. + */ + if (!old_baud) { + old_baud = CONFIG_BAUDRATE; + serial_early_set_baud(CONFIG_BAUDRATE); + } + } + + return old_baud; +} + +__attribute__((always_inline)) +static inline void serial_deinit(void) +{ +#ifdef __ADSPBF54x__ + if (BFIN_UART_USE_RTS && CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) { + /* clear forced RTS rather than relying on auto RTS */ + bfin_write_UART1_MCR(bfin_read_UART1_MCR() & ~FCPOL); + } +#endif +} + +/* We need to reset the baud rate when we have early debug turned on + * or when we are booting over the UART. + * XXX: we should fix this to calc the old baud and restore it rather + * than hardcoding it via CONFIG_LDR_LOAD_BAUD ... but we have + * to figure out how to avoid the division in the baud calc ... + */ +__attribute__((always_inline)) +static inline void serial_reset_baud(uint32_t baud) +{ + if (!BFIN_DEBUG_EARLY_SERIAL && CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_UART) + return; + +#ifndef CONFIG_LDR_LOAD_BAUD +# define CONFIG_LDR_LOAD_BAUD 115200 +#endif + + if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS) + serial_early_set_baud(baud); + else if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) + serial_early_set_baud(CONFIG_LDR_LOAD_BAUD); + else + serial_early_set_baud(CONFIG_BAUDRATE); +} + +__attribute__((always_inline)) +static inline void serial_putc(char c) +{ + if (!BFIN_DEBUG_EARLY_SERIAL) + return; + + if (c == '\n') + *pUART_THR = '\r'; + + *pUART_THR = c; + + while (!(*pUART_LSR & TEMT)) + continue; +} + + +/* Max SCLK can be 133MHz ... dividing that by 4 gives + * us a freq of 33MHz for SPI which should generally be + * slow enough for the slow reads the bootrom uses. + */ +#ifndef CONFIG_SPI_BAUD_INITBLOCK +# define CONFIG_SPI_BAUD_INITBLOCK 4 +#endif + +/* PLL_DIV defines */ +#ifndef CONFIG_PLL_DIV_VAL +# if (CONFIG_CCLK_DIV == 1) +# define CONFIG_CCLK_ACT_DIV CCLK_DIV1 +# elif (CONFIG_CCLK_DIV == 2) +# define CONFIG_CCLK_ACT_DIV CCLK_DIV2 +# elif (CONFIG_CCLK_DIV == 4) +# define CONFIG_CCLK_ACT_DIV CCLK_DIV4 +# elif (CONFIG_CCLK_DIV == 8) +# define CONFIG_CCLK_ACT_DIV CCLK_DIV8 +# else +# define CONFIG_CCLK_ACT_DIV CONFIG_CCLK_DIV_not_defined_properly +# endif +# define CONFIG_PLL_DIV_VAL (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV) +#endif + +#ifndef CONFIG_PLL_LOCKCNT_VAL +# define CONFIG_PLL_LOCKCNT_VAL 0x0300 +#endif + +#ifndef CONFIG_PLL_CTL_VAL +# define CONFIG_PLL_CTL_VAL (SPORT_HYST | (CONFIG_VCO_MULT << 9)) +#endif + +#ifndef CONFIG_EBIU_RSTCTL_VAL +# define CONFIG_EBIU_RSTCTL_VAL 0 /* only MDDRENABLE is useful */ +#endif + +#ifndef CONFIG_EBIU_MBSCTL_VAL +# define CONFIG_EBIU_MBSCTL_VAL 0 +#endif + +/* Make sure our voltage value is sane so we don't blow up! */ +#ifndef CONFIG_VR_CTL_VAL +# define BFIN_CCLK ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_CCLK_DIV) +# if defined(__ADSPBF533__) || defined(__ADSPBF532__) || defined(__ADSPBF531__) +# define CCLK_VLEV_120 400000000 +# define CCLK_VLEV_125 533000000 +# elif defined(__ADSPBF537__) || defined(__ADSPBF536__) || defined(__ADSPBF534__) +# define CCLK_VLEV_120 401000000 +# define CCLK_VLEV_125 401000000 +# elif defined(__ADSPBF561__) +# define CCLK_VLEV_120 300000000 +# define CCLK_VLEV_125 501000000 +# endif +# if BFIN_CCLK < CCLK_VLEV_120 +# define CONFIG_VR_CTL_VLEV VLEV_120 +# elif BFIN_CCLK < CCLK_VLEV_125 +# define CONFIG_VR_CTL_VLEV VLEV_125 +# else +# define CONFIG_VR_CTL_VLEV VLEV_130 +# endif +# if defined(__ADSPBF52x__) /* TBD; use default */ +# undef CONFIG_VR_CTL_VLEV +# define CONFIG_VR_CTL_VLEV VLEV_110 +# elif defined(__ADSPBF54x__) /* TBD; use default */ +# undef CONFIG_VR_CTL_VLEV +# define CONFIG_VR_CTL_VLEV VLEV_120 +# endif + +# ifdef CONFIG_BFIN_MAC +# define CONFIG_VR_CTL_CLKBUF CLKBUFOE +# else +# define CONFIG_VR_CTL_CLKBUF 0 +# endif + +# if defined(__ADSPBF52x__) +# define CONFIG_VR_CTL_FREQ FREQ_1000 +# else +# define CONFIG_VR_CTL_FREQ (GAIN_20 | FREQ_1000) +# endif + +# define CONFIG_VR_CTL_VAL (CONFIG_VR_CTL_CLKBUF | CONFIG_VR_CTL_VLEV | CONFIG_VR_CTL_FREQ) +#endif + +__attribute__((saveall)) +void initcode(ADI_BOOT_DATA *bootstruct) +{ + uint32_t old_baud = serial_init(); + +#ifdef CONFIG_HW_WATCHDOG +# ifndef CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE +# define CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE 20000 +# endif + /* Program the watchdog with an initial timeout of ~20 seconds. + * Hopefully that should be long enough to load the u-boot LDR + * (from wherever) and then the common u-boot code can take over. + * In bypass mode, the start.S would have already set a much lower + * timeout, so don't clobber that. + */ + if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS) { + bfin_write_WDOG_CNT(MSEC_TO_SCLK(CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE)); + bfin_write_WDOG_CTL(0); + } +#endif + + serial_putc('S'); + + /* Blackfin bootroms use the SPI slow read opcode instead of the SPI + * fast read, so we need to slow down the SPI clock a lot more during + * boot. Once we switch over to u-boot's SPI flash driver, we'll + * increase the speed appropriately. + */ + if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_SPI_MASTER) +#ifdef SPI0_BAUD + bfin_write_SPI0_BAUD(CONFIG_SPI_BAUD_INITBLOCK); +#else + bfin_write_SPI_BAUD(CONFIG_SPI_BAUD_INITBLOCK); +#endif + + serial_putc('B'); + + /* Disable all peripheral wakeups except for the PLL event. */ +#ifdef SIC_IWR0 + bfin_write_SIC_IWR0(1); + bfin_write_SIC_IWR1(0); +# ifdef SIC_IWR2 + bfin_write_SIC_IWR2(0); +# endif +#elif defined(SICA_IWR0) + bfin_write_SICA_IWR0(1); + bfin_write_SICA_IWR1(0); +#else + bfin_write_SIC_IWR(1); +#endif + + serial_putc('L'); + + bfin_write_PLL_LOCKCNT(CONFIG_PLL_LOCKCNT_VAL); + + serial_putc('A'); + + /* Only reprogram when needed to avoid triggering unnecessary + * PLL relock sequences. + */ + if (bfin_read_VR_CTL() != CONFIG_VR_CTL_VAL) { + serial_putc('!'); + bfin_write_VR_CTL(CONFIG_VR_CTL_VAL); + asm("idle;"); + } + + serial_putc('C'); + + bfin_write_PLL_DIV(CONFIG_PLL_DIV_VAL); + + serial_putc('K'); + + /* Only reprogram when needed to avoid triggering unnecessary + * PLL relock sequences. + */ + if (bfin_read_PLL_CTL() != CONFIG_PLL_CTL_VAL) { + serial_putc('!'); + bfin_write_PLL_CTL(CONFIG_PLL_CTL_VAL); + asm("idle;"); + } + + /* Since we've changed the SCLK above, we may need to update + * the UART divisors (UART baud rates are based on SCLK). + */ + serial_reset_baud(old_baud); + + serial_putc('F'); + + /* Program the async banks controller. */ + bfin_write_EBIU_AMBCTL0(CONFIG_EBIU_AMBCTL0_VAL); + bfin_write_EBIU_AMBCTL1(CONFIG_EBIU_AMBCTL1_VAL); + bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL); + +#ifdef EBIU_MODE + /* Not all parts have these additional MMRs. */ + bfin_write_EBIU_MBSCTL(CONFIG_EBIU_MBSCTL_VAL); + bfin_write_EBIU_MODE(CONFIG_EBIU_MODE_VAL); + bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTL_VAL); +#endif + + serial_putc('I'); + + /* Program the external memory controller. */ +#ifdef EBIU_RSTCTL + bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() | 0x1 /*DDRSRESET*/ | CONFIG_EBIU_RSTCTL_VAL); + bfin_write_EBIU_DDRCTL0(CONFIG_EBIU_DDRCTL0_VAL); + bfin_write_EBIU_DDRCTL1(CONFIG_EBIU_DDRCTL1_VAL); + bfin_write_EBIU_DDRCTL2(CONFIG_EBIU_DDRCTL2_VAL); +# ifdef CONFIG_EBIU_DDRCTL3_VAL + /* default is disable, so don't need to force this */ + bfin_write_EBIU_DDRCTL3(CONFIG_EBIU_DDRCTL3_VAL); +# endif +#else + bfin_write_EBIU_SDRRC(CONFIG_EBIU_SDRRC_VAL); + bfin_write_EBIU_SDBCTL(CONFIG_EBIU_SDBCTL_VAL); + bfin_write_EBIU_SDGCTL(CONFIG_EBIU_SDGCTL_VAL); +#endif + + serial_putc('N'); + + /* Restore all peripheral wakeups. */ +#ifdef SIC_IWR0 + bfin_write_SIC_IWR0(-1); + bfin_write_SIC_IWR1(-1); +# ifdef SIC_IWR2 + bfin_write_SIC_IWR2(-1); +# endif +#elif defined(SICA_IWR0) + bfin_write_SICA_IWR0(-1); + bfin_write_SICA_IWR1(-1); +#else + bfin_write_SIC_IWR(-1); +#endif + + serial_putc('>'); + serial_putc('\n'); + + serial_deinit(); +} diff --git a/cpu/blackfin/interrupt.S b/cpu/blackfin/interrupt.S new file mode 100644 index 0000000..dd2cc53 --- /dev/null +++ b/cpu/blackfin/interrupt.S @@ -0,0 +1,33 @@ +/* + * interrupt.S - trampoline default exceptions/interrupts to C handlers + * + * Copyright (c) 2005-2007 Analog Devices Inc. + * Licensed under the GPL-2 or later. + */ + +#include <asm/blackfin.h> +#include <asm/entry.h> + +.text + +/* default entry point for exceptions */ +ENTRY(_trap) + SAVE_ALL_SYS + r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ + sp += -12; + call _trap_c; + sp += 12; + RESTORE_ALL_SYS + rtx; +ENDPROC(_trap) + +/* default entry point for interrupts */ +ENTRY(_evt_default) + SAVE_ALL_SYS + r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ + sp += -12; + call _bfin_panic; + sp += 12; + RESTORE_ALL_SYS + rti; +ENDPROC(_evt_default) diff --git a/cpu/blackfin/interrupts.c b/cpu/blackfin/interrupts.c new file mode 100644 index 0000000..80c5505 --- /dev/null +++ b/cpu/blackfin/interrupts.c @@ -0,0 +1,155 @@ +/* + * U-boot - interrupts.c Interrupt related routines + * + * Copyright (c) 2005-2008 Analog Devices Inc. + * + * This file is based on interrupts.c + * Copyright 1996 Roman Zippel + * Copyright 1999 D. Jeff Dionne jeff@uclinux.org + * Copyright 2000-2001 Lineo, Inc. D. Jefff Dionne jeff@lineo.ca + * Copyright 2002 Arcturus Networks Inc. MaTed mated@sympatico.ca + * Copyright 2003 Metrowerks/Motorola + * Copyright 2003 Bas Vermeulen bas@buyways.nl, + * BuyWays B.V. (www.buyways.nl) + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Licensed under the GPL-2 or later. + */ + +#include <common.h> +#include <config.h> +#include <asm/blackfin.h> +#include "cpu.h" + +static ulong timestamp; +static ulong last_time; +static int int_flag; + +int irq_flags; /* needed by asm-blackfin/system.h */ + +/* Functions just to satisfy the linker */ + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On Blackfin it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On Blackfin it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + ulong tbclk; + + tbclk = CFG_HZ; + return tbclk; +} + +void enable_interrupts(void) +{ + local_irq_restore(int_flag); +} + +int disable_interrupts(void) +{ + local_irq_save(int_flag); + return 1; +} + +void udelay(unsigned long usec) +{ + unsigned long delay, start, stop; + unsigned long cclk; + cclk = (CONFIG_CCLK_HZ); + + while (usec > 1) { + /* + * how many clock ticks to delay? + * - request(in useconds) * clock_ticks(Hz) / useconds/second + */ + if (usec < 1000) { + delay = (usec * (cclk / 244)) >> 12; + usec = 0; + } else { + delay = (1000 * (cclk / 244)) >> 12; + usec -= 1000; + } + + asm volatile (" %0 = CYCLES;" : "=r" (start)); + do { + asm volatile (" %0 = CYCLES; " : "=r" (stop)); + } while (stop - start < delay); + } + + return; +} + +#define MAX_TIM_LOAD 0xFFFFFFFF +int timer_init(void) +{ + *pTCNTL = 0x1; + *pTSCALE = 0x0; + *pTCOUNT = MAX_TIM_LOAD; + *pTPERIOD = MAX_TIM_LOAD; + *pTCNTL = 0x7; + asm("CSYNC;"); + + timestamp = 0; + last_time = 0; + + return 0; +} + +/* + * Any network command or flash + * command is started get_timer shall + * be called before TCOUNT gets reset, + * to implement the accurate timeouts. + * + * How ever milliconds doesn't return + * the number that has been elapsed from + * the last reset. + * + * As get_timer is used in the u-boot + * only for timeouts this should be + * sufficient + */ +ulong get_timer(ulong base) +{ + ulong milisec; + + /* Number of clocks elapsed */ + ulong clocks = (MAX_TIM_LOAD - (*pTCOUNT)); + + /* + * Find if the TCOUNT is reset + * timestamp gives the number of times + * TCOUNT got reset + */ + if (clocks < last_time) + timestamp++; + last_time = clocks; + + /* Get the number of milliseconds */ + milisec = clocks / (CONFIG_CCLK_HZ / 1000); + + /* + * Find the number of millisonds that + * got elapsed before this TCOUNT cycle + */ + milisec += timestamp * (MAX_TIM_LOAD / (CONFIG_CCLK_HZ / 1000)); + + return (milisec - base); +} + +void reset_timer(void) +{ + timestamp = 0; +} diff --git a/cpu/blackfin/reset.c b/cpu/blackfin/reset.c new file mode 100644 index 0000000..d1e34b3 --- /dev/null +++ b/cpu/blackfin/reset.c @@ -0,0 +1,96 @@ +/* + * reset.c - logic for resetting the cpu + * + * Copyright (c) 2005-2008 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <common.h> +#include <command.h> +#include <asm/blackfin.h> +#include "cpu.h" + +/* A system soft reset makes external memory unusable so force + * this function into L1. We use the compiler ssync here rather + * than SSYNC() because it's safe (no interrupts and such) and + * we save some L1. We do not need to force sanity in the SYSCR + * register as the BMODE selection bit is cleared by the soft + * reset while the Core B bit (on dual core parts) is cleared by + * the core reset. + */ +__attribute__ ((__l1_text__, __noreturn__)) +void bfin_reset(void) +{ + /* Wait for completion of "system" events such as cache line + * line fills so that we avoid infinite stalls later on as + * much as possible. This code is in L1, so it won't trigger + * any such event after this point in time. + */ + __builtin_bfin_ssync(); + + while (1) { + /* Initiate System software reset. */ + bfin_write_SWRST(0x7); + + /* Due to the way reset is handled in the hardware, we need + * to delay for 7 SCLKS. The only reliable way to do this is + * to calculate the CCLK/SCLK ratio and multiply 7. For now, + * we'll assume worse case which is a 1:15 ratio. + */ + asm( + "LSETUP (1f, 1f) LC0 = %0\n" + "1: nop;" + : + : "a" (15 * 7) + : "LC0", "LB0", "LT0" + ); + + /* Clear System software reset */ + bfin_write_SWRST(0); + + /* Wait for the SWRST write to complete. Cannot rely on SSYNC + * though as the System state is all reset now. + */ + asm( + "LSETUP (1f, 1f) LC1 = %0\n" + "1: nop;" + : + : "a" (15 * 1) + : "LC1", "LB1", "LT1" + ); + + /* Issue core reset */ + asm("raise 1"); + } +} + +/* We need to trampoline ourselves up into L1 since our linker + * does not have relaxtion support and will only generate a + * PC relative call with a 25 bit immediate. This is not enough + * to get us from the top of SDRAM into L1. + */ +__attribute__ ((__noreturn__)) +static inline void bfin_reset_trampoline(void) +{ + if (board_reset) + board_reset(); + while (1) + asm("jump (%0);" : : "a" (bfin_reset)); +} + +__attribute__ ((__noreturn__)) +void bfin_reset_or_hang(void) +{ +#ifdef CONFIG_PANIC_HANG + hang(); +#else + bfin_reset_trampoline(); +#endif +} + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + bfin_reset_trampoline(); + return 0; +} diff --git a/cpu/blackfin/serial.c b/cpu/blackfin/serial.c new file mode 100644 index 0000000..0dfee51 --- /dev/null +++ b/cpu/blackfin/serial.c @@ -0,0 +1,124 @@ +/* + * U-boot - serial.c Blackfin Serial Driver + * + * Copyright (c) 2005-2008 Analog Devices Inc. + * + * Copyright (c) 2003 Bas Vermeulen bas@buyways.nl, + * BuyWays B.V. (www.buyways.nl) + * + * Based heavily on: + * blkfinserial.c: Serial driver for BlackFin DSP internal USRTs. + * Copyright(c) 2003 Metrowerks mwaddel@metrowerks.com + * Copyright(c) 2001 Tony Z. Kou tonyko@arcturusnetworks.com + * Copyright(c) 2001-2002 Arcturus Networks Inc. <www.arcturusnetworks.com> + * + * Based on code from 68328 version serial driver imlpementation which was: + * Copyright (C) 1995 David S. Miller davem@caip.rutgers.edu + * Copyright (C) 1998 Kenneth Albanowski kjahds@kjahds.com + * Copyright (C) 1998, 1999 D. Jeff Dionne jeff@uclinux.org + * Copyright (C) 1999 Vladimir Gurevich vgurevic@cisco.com + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Licensed under the GPL-2 or later. + */ + +#include <common.h> +#include <watchdog.h> +#include <asm/blackfin.h> +#include <asm/mach-common/bits/uart.h> + +#if defined(UART_LSR) && (CONFIG_UART_CONSOLE != 0) +# error CONFIG_UART_CONSOLE must be 0 on parts with only one UART +#endif + +#include "serial.h" + +/* Symbol for our assembly to call. */ +void serial_set_baud(uint32_t baud) +{ + serial_early_set_baud(baud); +} + +/* Symbol for common u-boot code to call. + * Setup the baudrate (brg: baudrate generator). + */ +void serial_setbrg(void) +{ + DECLARE_GLOBAL_DATA_PTR; + serial_set_baud(gd->baudrate); +} + +/* Symbol for our assembly to call. */ +void serial_initialize(void) +{ + serial_early_init(); +} + +/* Symbol for common u-boot code to call. */ +int serial_init(void) +{ + serial_initialize(); + serial_setbrg(); + return 0; +} + +void serial_putc(const char c) +{ + /* send a \r for compatibility */ + if (c == '\n') + serial_putc('\r'); + + WATCHDOG_RESET(); + + /* wait for the hardware fifo to clear up */ + while (!(*pUART_LSR & THRE)) + continue; + + /* queue the character for transmission */ + *pUART_THR = c; + SSYNC(); + + WATCHDOG_RESET(); + + /* wait for the byte to be shifted over the line */ + while (!(*pUART_LSR & TEMT)) + continue; +} + +int serial_tstc(void) +{ + WATCHDOG_RESET(); + return (*pUART_LSR & DR) ? 1 : 0; +} + +int serial_getc(void) +{ + uint16_t uart_lsr_val, uart_rbr_val; + + /* wait for data ! */ + while (!serial_tstc()) + continue; + + /* clear the status and grab the new byte */ + uart_lsr_val = *pUART_LSR; + uart_rbr_val = *pUART_RBR; + + if (uart_lsr_val & (OE|PE|FE|BI)) { + /* Some parts are read-to-clear while others are + * write-to-clear. Just do the write for everyone + * since it cant hurt (other than code size). + */ + *pUART_LSR = (OE|PE|FE|BI); + return -1; + } + + return uart_rbr_val & 0xFF; +} + +void serial_puts(const char *s) +{ + while (*s) + serial_putc(*s++); +} diff --git a/cpu/blackfin/serial.h b/cpu/blackfin/serial.h new file mode 100644 index 0000000..1f0f4b4 --- /dev/null +++ b/cpu/blackfin/serial.h @@ -0,0 +1,275 @@ +/* + * serial.h - common serial defines for early debug and serial driver. + * any functions defined here must be always_inline since + * initcode cannot have function calls. + * + * Copyright (c) 2004-2007 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __BFIN_CPU_SERIAL_H__ +#define __BFIN_CPU_SERIAL_H__ + +#include <asm/blackfin.h> +#include <asm/mach-common/bits/uart.h> + +#ifdef CONFIG_DEBUG_EARLY_SERIAL +# define BFIN_DEBUG_EARLY_SERIAL 1 +#else +# define BFIN_DEBUG_EARLY_SERIAL 0 +#endif + +#define LOB(x) ((x) & 0xFF) +#define HIB(x) (((x) >> 8) & 0xFF) + +#ifndef UART_LSR +# if (CONFIG_UART_CONSOLE == 3) +# define pUART_DLH pUART3_DLH +# define pUART_DLL pUART3_DLL +# define pUART_GCTL pUART3_GCTL +# define pUART_IER pUART3_IER +# define pUART_IERC pUART3_IER_CLEAR +# define pUART_LCR pUART3_LCR +# define pUART_LSR pUART3_LSR +# define pUART_RBR pUART3_RBR +# define pUART_THR pUART3_THR +# define UART_THR UART3_THR +# define UART_LSR UART3_LSR +# elif (CONFIG_UART_CONSOLE == 2) +# define pUART_DLH pUART2_DLH +# define pUART_DLL pUART2_DLL +# define pUART_GCTL pUART2_GCTL +# define pUART_IER pUART2_IER +# define pUART_IERC pUART2_IER_CLEAR +# define pUART_LCR pUART2_LCR +# define pUART_LSR pUART2_LSR +# define pUART_RBR pUART2_RBR +# define pUART_THR pUART2_THR +# define UART_THR UART2_THR +# define UART_LSR UART2_LSR +# elif (CONFIG_UART_CONSOLE == 1) +# define pUART_DLH pUART1_DLH +# define pUART_DLL pUART1_DLL +# define pUART_GCTL pUART1_GCTL +# define pUART_IER pUART1_IER +# define pUART_IERC pUART1_IER_CLEAR +# define pUART_LCR pUART1_LCR +# define pUART_LSR pUART1_LSR +# define pUART_RBR pUART1_RBR +# define pUART_THR pUART1_THR +# define UART_THR UART1_THR +# define UART_LSR UART1_LSR +# elif (CONFIG_UART_CONSOLE == 0) +# define pUART_DLH pUART0_DLH +# define pUART_DLL pUART0_DLL +# define pUART_GCTL pUART0_GCTL +# define pUART_IER pUART0_IER +# define pUART_IERC pUART0_IER_CLEAR +# define pUART_LCR pUART0_LCR +# define pUART_LSR pUART0_LSR +# define pUART_RBR pUART0_RBR +# define pUART_THR pUART0_THR +# define UART_THR UART0_THR +# define UART_LSR UART0_LSR +# endif +#endif + +#ifndef __ASSEMBLY__ + +/* We cannot use get_sclk() in initcode as it is defined elsewhere. */ +#ifdef BFIN_IN_INITCODE +# define get_sclk() (CONFIG_CLKIN_HZ * CONFIG_VCO_MULT / CONFIG_SCLK_DIV) +#endif + +#ifdef __ADSPBF54x__ +# define ACCESS_LATCH() +# define ACCESS_PORT_IER() +# define CLEAR_IER() (*pUART_IERC = 0) +#else +# define ACCESS_LATCH() (*pUART_LCR |= DLAB) +# define ACCESS_PORT_IER() (*pUART_LCR &= ~DLAB) +# define CLEAR_IER() (*pUART_IER = 0) +#endif + +__attribute__((always_inline)) +static inline void serial_do_portmux(void) +{ +#ifdef __ADSPBF52x__ +# define DO_MUX(port, mux, tx, rx) \ + bfin_write_PORT##port##_MUX((bfin_read_PORT##port##_MUX() & ~PORT_x_MUX_##mux##_MASK) | PORT_x_MUX_##mux##_FUNC_3); \ + bfin_write_PORT##port##_FER(bfin_read_PORT##port##_FER() | P##port##tx | P##port##rx); + switch (CONFIG_UART_CONSOLE) { + case 0: DO_MUX(G, 2, 7, 8); break; /* Port G; mux 2; PG2 and PG8 */ + case 1: DO_MUX(F, 5, 14, 15); break; /* Port F; mux 5; PF14 and PF15 */ + } + SSYNC(); +#elif defined(__ADSPBF537__) || defined(__ADSPBF536__) || defined(__ADSPBF534__) +# define DO_MUX(func, tx, rx) \ + bfin_write_PORT_MUX(bfin_read_PORT_MUX() & ~(func)); \ + bfin_write_PORTF_FER(bfin_read_PORTF_FER() | PF##tx | PF##rx); + switch (CONFIG_UART_CONSOLE) { + case 0: DO_MUX(PFDE, 0, 1); break; + case 1: DO_MUX(PFTE, 2, 3); break; + } + SSYNC(); +#elif defined(__ADSPBF54x__) +# define DO_MUX(port, tx, rx) \ + bfin_write_PORT##port##_MUX((bfin_read_PORT##port##_MUX() & ~(PORT_x_MUX_##tx##_MASK | PORT_x_MUX_##rx##_MASK)) | PORT_x_MUX_##tx##_FUNC_1 | PORT_x_MUX_##rx##_FUNC_1); \ + bfin_write_PORT##port##_FER(bfin_read_PORT##port##_FER() | P##port##tx | P##port##rx); + switch (CONFIG_UART_CONSOLE) { + case 0: DO_MUX(E, 7, 8); break; /* Port E; PE7 and PE8 */ + case 1: DO_MUX(H, 0, 1); break; /* Port H; PH0 and PH1 */ + case 2: DO_MUX(B, 4, 5); break; /* Port B; PB4 and PB5 */ + case 3: DO_MUX(B, 6, 7); break; /* Port B; PB6 and PB7 */ + } + SSYNC(); +#endif +} + +__attribute__((always_inline)) +static inline void serial_early_init(void) +{ + /* handle portmux crap on different Blackfins */ + serial_do_portmux(); + + /* Enable UART */ + *pUART_GCTL = UCEN; + + /* Set LCR to Word Lengh 8-bit word select */ + *pUART_LCR = WLS_8; + + SSYNC(); +} + +__attribute__((always_inline)) +static inline uint32_t serial_early_get_baud(void) +{ + /* If the UART isnt enabled, then we are booting an LDR + * from a non-UART source (so like flash) which means + * the baud rate here is meaningless. + */ + if ((*pUART_GCTL & UCEN) != UCEN) + return 0; + +#if (0) /* See comment for serial_reset_baud() in initcode.c */ + /* Set DLAB in LCR to Access DLL and DLH */ + ACCESS_LATCH(); + SSYNC(); + + uint8_t dll = *pUART_DLL; + uint8_t dlh = *pUART_DLH; + uint16_t divisor = (dlh << 8) | dll; + uint32_t baud = get_sclk() / (divisor * 16); + + /* Clear DLAB in LCR to Access THR RBR IER */ + ACCESS_PORT_IER(); + SSYNC(); + + return baud; +#else + return CONFIG_BAUDRATE; +#endif +} + +__attribute__((always_inline)) +static inline void serial_early_set_baud(uint32_t baud) +{ + /* Translate from baud into divisor in terms of SCLK. + * The +1 is to make sure we over sample just a little + * rather than under sample the incoming signals. + */ + uint16_t divisor = (get_sclk() / (baud * 16)) + 1; + + /* Set DLAB in LCR to Access DLL and DLH */ + ACCESS_LATCH(); + SSYNC(); + + /* Program the divisor to get the baud rate we want */ + *pUART_DLL = LOB(divisor); + *pUART_DLH = HIB(divisor); + SSYNC(); + + /* Clear DLAB in LCR to Access THR RBR IER */ + ACCESS_PORT_IER(); + SSYNC(); +} + +#ifndef BFIN_IN_INITCODE +__attribute__((always_inline)) +static inline void serial_early_puts(const char *s) +{ + if (BFIN_DEBUG_EARLY_SERIAL) { + serial_puts("Early: "); + serial_puts(s); + } +} +#endif + +#else + +.macro serial_early_init +#ifdef CONFIG_DEBUG_EARLY_SERIAL + call _serial_initialize; +#endif +.endm + +.macro serial_early_set_baud +#ifdef CONFIG_DEBUG_EARLY_SERIAL + R0.L = LO(CONFIG_BAUDRATE); + R0.H = HI(CONFIG_BAUDRATE); + call _serial_set_baud; +#endif +.endm + +/* Recursively expand calls to _serial_putc for every byte + * passed to us. Append a newline when we're all done. + */ +.macro _serial_early_putc byte:req morebytes:vararg +#ifdef CONFIG_DEBUG_EARLY_SERIAL + R0 = \byte; + call _serial_putc; +.ifnb \morebytes + _serial_early_putc \morebytes +.else +.if (\byte != '\n') + _serial_early_putc '\n' +.endif +.endif +#endif +.endm + +/* Wrapper around recurisve _serial_early_putc macro which + * simply prepends the string "Early: " + */ +.macro serial_early_putc byte:req morebytes:vararg +#ifdef CONFIG_DEBUG_EARLY_SERIAL + _serial_early_putc 'E', 'a', 'r', 'l', 'y', ':', ' ', \byte, \morebytes +#endif +.endm + +/* Since we embed the string right into our .text section, we need + * to find its address. We do this by getting our PC and adding 2 + * bytes (which is the length of the jump instruction). Then we + * pass this address to serial_puts(). + */ +#ifdef CONFIG_DEBUG_EARLY_SERIAL +# define serial_early_puts(str) \ + call _get_pc; \ + jump 1f; \ + .ascii "Early:"; \ + .ascii __FILE__; \ + .ascii ": "; \ + .ascii str; \ + .asciz "\n"; \ + .align 4; \ +1: \ + R0 += 2; \ + call _serial_puts; +#else +# define serial_early_puts(str) +#endif + +#endif + +#endif diff --git a/cpu/blackfin/start.S b/cpu/blackfin/start.S new file mode 100644 index 0000000..30212e9 --- /dev/null +++ b/cpu/blackfin/start.S @@ -0,0 +1,219 @@ +/* + * U-boot - start.S Startup file for Blackfin u-boot + * + * Copyright (c) 2005-2007 Analog Devices Inc. + * + * This file is based on head.S + * Copyright (c) 2003 Metrowerks/Motorola + * Copyright (C) 1998 D. Jeff Dionne jeff@ryeham.ee.ryerson.ca, + * Kenneth Albanowski kjahds@kjahds.com, + * The Silver Hammer Group, Ltd. + * (c) 1995, Dionne & Associates + * (c) 1995, DKG Display Tech. + * + * 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., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <config.h> +#include <asm/blackfin.h> +#include <asm/mach-common/bits/core.h> +#include <asm/mach-common/bits/dma.h> +#include <asm/mach-common/bits/pll.h> + +#include "serial.h" + +/* It may seem odd that we make calls to functions even though we haven't + * relocated ourselves yet out of {flash,ram,wherever}. This is OK because + * the "call" instruction in the Blackfin architecture is actually PC + * relative. So we can call functions all we want and not worry about them + * not being relocated yet. + */ + +.text +ENTRY(_start) + + /* Set our initial stack to L1 scratch space */ + sp.l = LO(L1_SRAM_SCRATCH + L1_SRAM_SCRATCH_SIZE); + sp.h = HI(L1_SRAM_SCRATCH + L1_SRAM_SCRATCH_SIZE); + +#ifdef CONFIG_HW_WATCHDOG +# ifndef CONFIG_HW_WATCHDOG_TIMEOUT_START +# define CONFIG_HW_WATCHDOG_TIMEOUT_START 5000 +# endif + /* Program the watchdog with an initial timeout of ~5 seconds. + * That should be long enough to bootstrap ourselves up and + * then the common u-boot code can take over. + */ + P0.L = LO(WDOG_CNT); + P0.H = HI(WDOG_CNT); + R0.L = 0; + R0.H = HI(MSEC_TO_SCLK(CONFIG_HW_WATCHDOG_TIMEOUT_START)); + [P0] = R0; + /* fire up the watchdog - R0.L above needs to be 0x0000 */ + W[P0 + (WDOG_CTL - WDOG_CNT)] = R0; +#endif + + /* Turn on the serial for debugging the init process */ + serial_early_init + serial_early_set_baud + + serial_early_puts("Init Registers"); + + /* Disable nested interrupts and enable CYCLES for udelay() */ + R0 = CCEN | 0x30; + SYSCFG = R0; + + /* Zero out registers required by Blackfin ABI. + * http://docs.blackfin.uclinux.org/doku.php?id=application_binary_interface + */ + r1 = 0 (x); + /* Disable circular buffers */ + l0 = r1; + l1 = r1; + l2 = r1; + l3 = r1; + /* Disable hardware loops in case we were started by 'go' */ + lc0 = r1; + lc1 = r1; + + /* Save RETX so we can pass it while booting Linux */ + r7 = RETX; + +#if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS) + /* In bypass mode, we don't have an LDR with an init block + * so we need to explicitly call it ourselves. This will + * reprogram our clocks and setup our async banks. + */ + /* XXX: we should DMA this into L1, put external memory into + * self refresh, and then jump there ... + */ + call _get_pc; + r3 = 0x0; + r3.h = 0x2000; + cc = r0 < r3 (iu); + if cc jump .Lproc_initialized; + + serial_early_puts("Program Clocks"); + + call _initcode; + + /* Since we reprogrammed SCLK, we need to update the serial divisor */ + serial_early_set_baud + +.Lproc_initialized: +#endif + + /* Inform upper layers if we had to do the relocation ourselves. + * This allows us to detect whether we were loaded by 'go 0x1000' + * or by the bootrom from an LDR. "r6" is "loaded_from_ldr". + */ + r6 = 1 (x); + + /* Relocate from wherever are (FLASH/RAM/etc...) to the + * hardcoded monitor location in the end of RAM. + */ + serial_early_puts("Relocate"); + call _get_pc; +.Loffset: + r2.l = .Loffset; + r2.h = .Loffset; + r3.l = _start; + r3.h = _start; + r1 = r2 - r3; + + r0 = r0 - r1; + + cc = r0 == r3; + if cc jump .Lnorelocate; + + r6 = 0 (x); + p1 = r0; + + p2.l = LO(CFG_MONITOR_BASE); + p2.h = HI(CFG_MONITOR_BASE); + + p3 = 0x04; + p4.l = LO(CFG_MONITOR_BASE + CFG_MONITOR_LEN); + p4.h = HI(CFG_MONITOR_BASE + CFG_MONITOR_LEN); +.Lloop1: + r1 = [p1 ++ p3]; + [p2 ++ p3] = r1; + cc=p2==p4; + if !cc jump .Lloop1; + + /* Initialize BSS section ... we know that memset() does not + * use the BSS, so it is safe to call here. The bootrom LDR + * takes care of clearing things for us. + */ + serial_early_puts("Zero BSS"); + r0.l = __bss_start; + r0.h = __bss_start; + r1 = 0 (x); + r2.l = __bss_end; + r2.h = __bss_end; + r2 = r2 - r0; + call _memset; + +.Lnorelocate: + + /* Setup the actual stack in external memory */ + r0.h = HI(CONFIG_STACKBASE); + r0.l = LO(CONFIG_STACKBASE); + sp = r0; + fp = sp; + + /* Now lower ourselves from the highest interrupt level to + * the lowest. We do this by masking all interrupts but 15, + * setting the 15 handler to "board_init_f", raising the 15 + * interrupt, and then returning from the highest interrupt + * level to the dummy "jump" until the interrupt controller + * services the pending 15 interrupt. + */ + serial_early_puts("Lower to 15"); + r0 = r7; + r1 = r6; + p0.l = LO(EVT15); + p0.h = HI(EVT15); + p1.l = _cpu_init_f; + p1.h = _cpu_init_f; + [p0] = p1; + p2.l = LO(IMASK); + p2.h = HI(IMASK); + p3.l = LO(EVT_IVG15); + p3.h = HI(EVT_IVG15); + [p2] = p3; + raise 15; + p4.l = .LWAIT_HERE; + p4.h = .LWAIT_HERE; + reti = p4; + rti; + +.LWAIT_HERE: + jump .LWAIT_HERE; +ENDPROC(_start) + +LENTRY(_get_pc) + r0 = rets; +#if ANOMALY_05000371 + NOP; + NOP; + NOP; +#endif + rts; +ENDPROC(_get_pc) diff --git a/cpu/blackfin/system_map.S b/cpu/blackfin/system_map.S new file mode 100644 index 0000000..286d7f3 --- /dev/null +++ b/cpu/blackfin/system_map.S @@ -0,0 +1,18 @@ +/* + * system_map.S - optional symbol lookup for debugging + * + * Copyright (c) 2007 Analog Devices Inc. + * Licensed under the GPL-2 or later. + */ + +#include <config.h> + +#ifdef CONFIG_DEBUG_DUMP_SYMS +.data +.global _system_map +.type _system_map,@object +_system_map: +#include SYM_FILE +.asciz "" +.size _system_map,.-_system_map +#endif diff --git a/cpu/blackfin/traps.c b/cpu/blackfin/traps.c new file mode 100644 index 0000000..4474fe5 --- /dev/null +++ b/cpu/blackfin/traps.c @@ -0,0 +1,353 @@ +/* + * U-boot - traps.c Routines related to interrupts and exceptions + * + * Copyright (c) 2005-2008 Analog Devices Inc. + * + * This file is based on + * No original Copyright holder listed, + * Probabily original (C) Roman Zippel (assigned DJD, 1999) + * + * Copyright 2003 Metrowerks - for Blackfin + * Copyright 2000-2001 Lineo, Inc. D. Jeff Dionne jeff@lineo.ca + * Copyright 1999-2000 D. Jeff Dionne, jeff@uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Licensed under the GPL-2 or later. + */ + +#include <common.h> +#include <linux/types.h> +#include <asm/traps.h> +#include <asm/cplb.h> +#include <asm/io.h> +#include <asm/mach-common/bits/core.h> +#include <asm/mach-common/bits/mpu.h> +#include <asm/mach-common/bits/trace.h> +#include "cpu.h" + +#define trace_buffer_save(x) \ + do { \ + (x) = bfin_read_TBUFCTL(); \ + bfin_write_TBUFCTL((x) & ~TBUFEN); \ + } while (0) + +#define trace_buffer_restore(x) \ + bfin_write_TBUFCTL((x)) + +/* The purpose of this map is to provide a mapping of address<->cplb settings + * rather than an exact map of what is actually addressable on the part. This + * map covers all current Blackfin parts. If you try to access an address that + * is in this map but not actually on the part, you won't get an exception and + * reboot, you'll get an external hardware addressing error and reboot. Since + * only the ends matter (you did something wrong and the board reset), the means + * are largely irrelevant. + */ +struct memory_map { + uint32_t start, end; + uint32_t data_flags, inst_flags; +}; +const struct memory_map const bfin_memory_map[] = { + { /* external memory */ + .start = 0x00000000, + .end = 0x20000000, + .data_flags = SDRAM_DGENERIC, + .inst_flags = SDRAM_IGENERIC, + }, + { /* async banks */ + .start = 0x20000000, + .end = 0x30000000, + .data_flags = SDRAM_EBIU, + .inst_flags = SDRAM_INON_CHBL, + }, + { /* everything on chip */ + .start = 0xE0000000, + .end = 0xFFFFFFFF, + .data_flags = L1_DMEMORY, + .inst_flags = L1_IMEMORY, + } +}; + +void trap_c(struct pt_regs *regs) +{ + uint32_t trapnr = (regs->seqstat & EXCAUSE); + bool data = false; + + switch (trapnr) { + /* 0x26 - Data CPLB Miss */ + case VEC_CPLB_M: + + if (ANOMALY_05000261) { + static uint32_t last_cplb_fault_retx; + /* + * Work around an anomaly: if we see a new DCPLB fault, + * return without doing anything. Then, + * if we get the same fault again, handle it. + */ + if (last_cplb_fault_retx != regs->retx) { + last_cplb_fault_retx = regs->retx; + return; + } + } + + data = true; + /* fall through */ + + /* 0x27 - Instruction CPLB Miss */ + case VEC_CPLB_I_M: { + volatile uint32_t *CPLB_ADDR_BASE, *CPLB_DATA_BASE, *CPLB_ADDR, *CPLB_DATA; + uint32_t new_cplb_addr = 0, new_cplb_data = 0; + static size_t last_evicted; + size_t i; + + new_cplb_addr = (data ? bfin_read_DCPLB_FAULT_ADDR() : bfin_read_ICPLB_FAULT_ADDR()) & ~(4 * 1024 * 1024 - 1); + + for (i = 0; i < ARRAY_SIZE(bfin_memory_map); ++i) { + /* if the exception is inside this range, lets use it */ + if (new_cplb_addr >= bfin_memory_map[i].start && + new_cplb_addr < bfin_memory_map[i].end) + break; + } + if (i == ARRAY_SIZE(bfin_memory_map)) { + printf("%cCPLB exception outside of memory map at 0x%p\n", + (data ? 'D' : 'I'), new_cplb_addr); + bfin_panic(regs); + } else + debug("CPLB addr %p matches map 0x%p - 0x%p\n", new_cplb_addr, bfin_memory_map[i].start, bfin_memory_map[i].end); + new_cplb_data = (data ? bfin_memory_map[i].data_flags : bfin_memory_map[i].inst_flags); + + /* Turn the cache off */ + SSYNC(); + if (data) { + asm(" .align 8; "); + *pDMEM_CONTROL &= ~ENDCPLB; + } else { + asm(" .align 8; "); + *pIMEM_CONTROL &= ~ENICPLB; + } + SSYNC(); + + if (data) { + CPLB_ADDR_BASE = (uint32_t *)DCPLB_ADDR0; + CPLB_DATA_BASE = (uint32_t *)DCPLB_DATA0; + } else { + CPLB_ADDR_BASE = (uint32_t *)ICPLB_ADDR0; + CPLB_DATA_BASE = (uint32_t *)ICPLB_DATA0; + } + + /* find the next unlocked entry and evict it */ + i = last_evicted & 0xF; + debug("last evicted = %i\n", i); + CPLB_DATA = CPLB_DATA_BASE + i; + while (*CPLB_DATA & CPLB_LOCK) { + debug("skipping %i %p - %08X\n", i, CPLB_DATA, *CPLB_DATA); + i = (i + 1) & 0xF; /* wrap around */ + CPLB_DATA = CPLB_DATA_BASE + i; + } + CPLB_ADDR = CPLB_ADDR_BASE + i; + + debug("evicting entry %i: 0x%p 0x%08X\n", i, *CPLB_ADDR, *CPLB_DATA); + last_evicted = i + 1; + *CPLB_ADDR = new_cplb_addr; + *CPLB_DATA = new_cplb_data; + + /* dump current table for debugging purposes */ + CPLB_ADDR = CPLB_ADDR_BASE; + CPLB_DATA = CPLB_DATA_BASE; + for (i = 0; i < 16; ++i) + debug("%2i 0x%p 0x%08X\n", i, *CPLB_ADDR++, *CPLB_DATA++); + + /* Turn the cache back on */ + SSYNC(); + if (data) { + asm(" .align 8; "); + *pDMEM_CONTROL |= ENDCPLB; + } else { + asm(" .align 8; "); + *pIMEM_CONTROL |= ENICPLB; + } + SSYNC(); + + break; + } + + default: + /* All traps come here */ + bfin_panic(regs); + } +} + +#ifdef CONFIG_DEBUG_DUMP +# define ENABLE_DUMP 1 +#else +# define ENABLE_DUMP 0 +#endif + +#ifdef CONFIG_DEBUG_DUMP_SYMS +# define ENABLE_DUMP_SYMS 1 +#else +# define ENABLE_DUMP_SYMS 0 +#endif + +static const char *symbol_lookup(unsigned long addr, unsigned long *caddr) +{ + if (!ENABLE_DUMP_SYMS) + return NULL; + + extern const char system_map[] __attribute__((__weak__)); + const char *sym, *csym; + char *esym; + unsigned long sym_addr; + + sym = system_map; + csym = NULL; + *caddr = 0; + + while (*sym) { + sym_addr = simple_strtoul(sym, &esym, 16); + sym = esym + 1; + if (sym_addr > addr) + break; + *caddr = sym_addr; + csym = sym; + sym += strlen(sym) + 1; + } + + return csym; +} + +static void decode_address(char *buf, unsigned long address) +{ + unsigned long sym_addr; + const char *sym = symbol_lookup(address, &sym_addr); + + if (sym) { + sprintf(buf, "<0x%p> { %s + 0x%x }", address, sym, address - sym_addr); + return; + } + + if (!address) + sprintf(buf, "<0x%p> /* Maybe null pointer? */", address); + else if (address >= CFG_MONITOR_BASE && + address < CFG_MONITOR_BASE + CFG_MONITOR_LEN) + sprintf(buf, "<0x%p> /* somewhere in u-boot */", address); + else + sprintf(buf, "<0x%p> /* unknown address */", address); +} + +void dump(struct pt_regs *fp) +{ + char buf[150]; + size_t i; + + if (!ENABLE_DUMP) + return; + + printf("SEQUENCER STATUS:\n"); + printf(" SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", + fp->seqstat, fp->ipend, fp->syscfg); + printf(" HWERRCAUSE: 0x%lx\n", (fp->seqstat & HWERRCAUSE) >> HWERRCAUSE_P); + printf(" EXCAUSE : 0x%lx\n", (fp->seqstat & EXCAUSE) >> EXCAUSE_P); + for (i = 6; i <= 15; ++i) { + if (fp->ipend & (1 << i)) { + decode_address(buf, bfin_read32(EVT0 + 4*i)); + printf(" physical IVG%i asserted : %s\n", i, buf); + } + } + decode_address(buf, fp->rete); + printf(" RETE: %s\n", buf); + decode_address(buf, fp->retn); + printf(" RETN: %s\n", buf); + decode_address(buf, fp->retx); + printf(" RETX: %s\n", buf); + decode_address(buf, fp->rets); + printf(" RETS: %s\n", buf); + decode_address(buf, fp->pc); + printf(" PC : %s\n", buf); + + if (fp->seqstat & EXCAUSE) { + decode_address(buf, bfin_read_DCPLB_FAULT_ADDR()); + printf("DCPLB_FAULT_ADDR: %s\n", buf); + decode_address(buf, bfin_read_ICPLB_FAULT_ADDR()); + printf("ICPLB_FAULT_ADDR: %s\n", buf); + } + + printf("\nPROCESSOR STATE:\n"); + printf(" R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", + fp->r0, fp->r1, fp->r2, fp->r3); + printf(" R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n", + fp->r4, fp->r5, fp->r6, fp->r7); + printf(" P0 : %08lx P1 : %08lx P2 : %08lx P3 : %08lx\n", + fp->p0, fp->p1, fp->p2, fp->p3); + printf(" P4 : %08lx P5 : %08lx FP : %08lx SP : %08lx\n", + fp->p4, fp->p5, fp->fp, fp); + printf(" LB0: %08lx LT0: %08lx LC0: %08lx\n", + fp->lb0, fp->lt0, fp->lc0); + printf(" LB1: %08lx LT1: %08lx LC1: %08lx\n", + fp->lb1, fp->lt1, fp->lc1); + printf(" B0 : %08lx L0 : %08lx M0 : %08lx I0 : %08lx\n", + fp->b0, fp->l0, fp->m0, fp->i0); + printf(" B1 : %08lx L1 : %08lx M1 : %08lx I1 : %08lx\n", + fp->b1, fp->l1, fp->m1, fp->i1); + printf(" B2 : %08lx L2 : %08lx M2 : %08lx I2 : %08lx\n", + fp->b2, fp->l2, fp->m2, fp->i2); + printf(" B3 : %08lx L3 : %08lx M3 : %08lx I3 : %08lx\n", + fp->b3, fp->l3, fp->m3, fp->i3); + printf("A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", + fp->a0w, fp->a0x, fp->a1w, fp->a1x); + + printf("USP : %08lx ASTAT: %08lx\n", + fp->usp, fp->astat); + + printf("\n"); +} + +void dump_bfin_trace_buffer(void) +{ + char buf[150]; + unsigned long tflags; + size_t i = 0; + + if (!ENABLE_DUMP) + return; + + trace_buffer_save(tflags); + + printf("Hardware Trace:\n"); + + if (bfin_read_TBUFSTAT() & TBUFCNT) { + for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { + decode_address(buf, bfin_read_TBUF()); + printf("%4i Target : %s\n", i, buf); + decode_address(buf, bfin_read_TBUF()); + printf(" Source : %s\n", buf); + } + } + + trace_buffer_restore(tflags); +} + +void bfin_panic(struct pt_regs *regs) +{ + if (ENABLE_DUMP) { + unsigned long tflags; + trace_buffer_save(tflags); + } + + puts( + "\n" + "\n" + "\n" + "Ack! Something bad happened to the Blackfin!\n" + "\n" + ); + dump(regs); + dump_bfin_trace_buffer(); + printf( + "\n" + "Please reset the board\n" + "\n" + ); + bfin_reset_or_hang(); +} diff --git a/cpu/blackfin/watchdog.c b/cpu/blackfin/watchdog.c new file mode 100644 index 0000000..b47c6b6 --- /dev/null +++ b/cpu/blackfin/watchdog.c @@ -0,0 +1,25 @@ +/* + * watchdog.c - driver for Blackfin on-chip watchdog + * + * Copyright (c) 2007-2008 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <common.h> +#include <watchdog.h> +#include <asm/blackfin.h> + +#ifdef CONFIG_HW_WATCHDOG +void hw_watchdog_reset(void) +{ + bfin_write_WDOG_STAT(0); +} + +void hw_watchdog_init(void) +{ + bfin_write_WDOG_CNT(5 * get_sclk()); /* 5 second timeout */ + hw_watchdog_reset(); + bfin_write_WDOG_CTL(0x0); +} +#endif diff --git a/include/asm-blackfin/blackfin-config-post.h b/include/asm-blackfin/blackfin-config-post.h index 4422225..6a1ffa1 100644 --- a/include/asm-blackfin/blackfin-config-post.h +++ b/include/asm-blackfin/blackfin-config-post.h @@ -14,9 +14,9 @@ # error Memory Map does not fit into configuration #endif
-/* Sanity check BFIN_CPU */ -#ifndef BFIN_CPU -# error BFIN_CPU: your board config needs to define this +/* Sanity check CONFIG_BFIN_CPU */ +#ifndef CONFIG_BFIN_CPU +# error CONFIG_BFIN_CPU: your board config needs to define this #endif
/* Make sure the structure is properly aligned */ diff --git a/include/configs/bf533-ezkit.h b/include/configs/bf533-ezkit.h index f2c8703..2f551ad 100644 --- a/include/configs/bf533-ezkit.h +++ b/include/configs/bf533-ezkit.h @@ -8,7 +8,6 @@ #include <asm/blackfin-config-pre.h>
#define CONFIG_BAUDRATE 57600 -#define CONFIG_STAMP 1
#define CONFIG_BOOTDELAY 5 #define CFG_AUTOLOAD "no" /*rarpb, bootp or dhcp commands will perform only a */ @@ -30,28 +29,15 @@ #define CONFIG_RTC_BFIN 1 #define CONFIG_BOOT_RETRY_TIME -1 /* Enable this if bootretry required, currently its disabled */
-/* - * Boot Mode Set - * Blackfin can support several boot modes - */ -#define BF533_BYPASS_BOOT 0x0001 /* Bootmode 0: Execute from 16-bit externeal memory ( bypass BOOT ROM) */ -#define BF533_PARA_BOOT 0x0002 /* Bootmode 1: Boot from 8-bit or 16-bit flash */ -#define BF533_SPI_BOOT 0x0004 /* Bootmode 3: Boot from SPI flash */ -/* Define the boot mode */ -#define BFIN_BOOT_MODE BF533_BYPASS_BOOT -/* #define BFIN_BOOT_MODE BF533_SPI_BOOT */ - #define CONFIG_PANIC_HANG 1
#define CONFIG_BFIN_CPU bf533-0.3 +#define CONFIG_BFIN_BOOT_MODE BFIN_BOOT_BYPASS
/* This sets the default state of the cache on U-Boot's boot */ #define CONFIG_ICACHE_ON #define CONFIG_DCACHE_ON
-/* Define where the uboot will be loaded by on-chip boot rom */ -#define APP_ENTRY 0x00001000 - /* CONFIG_CLKIN_HZ is any value in Hz */ #define CONFIG_CLKIN_HZ 27000000 /* CONFIG_CLKIN_HALF controls what is passed to PLL 0=CLKIN */ @@ -216,24 +202,14 @@
#define CFG_BOOTM_LEN 0x4000000 /* Large Image Length, set to 64 Meg */
-/* 0xFF, 0x7BB07BB0, 0x22547BB0 */ -/* #define AMGCTLVAL (AMBEN_P0 | AMBEN_P1 | AMBEN_P2 | AMCKEN) -#define AMBCTL0VAL (B1WAT_7 | B1RAT_11 | B1HT_2 | B1ST_3 | B1TT_4 | ~B1RDYPOL | \ - ~B1RDYEN | B0WAT_7 | B0RAT_11 | B0HT_2 | B0ST_3 | B0TT_4 | ~B0RDYPOL | ~B0RDYEN) -#define AMBCTL1VAL (B3WAT_2 | B3RAT_2 | B3HT_1 | B3ST_1 | B3TT_4 | B3RDYPOL | ~B3RDYEN | \ - B2WAT_7 | B2RAT_11 | B2HT_2 | B2ST_3 | B2TT_4 | ~B2RDYPOL | ~B2RDYEN) -*/ -#define AMGCTLVAL 0xFF -#define AMBCTL0VAL 0x7BB07BB0 -#define AMBCTL1VAL 0xFFC27BB0 - -#define CONFIG_VDSP 1 - -#ifdef CONFIG_VDSP -#define ET_EXEC_VDSP 0x8 -#define SHT_STRTAB_VDSP 0x1 -#define ELFSHDRSIZE_VDSP 0x2C -#define VDSP_ENTRY_ADDR 0xFFA00000 -#endif +#define CONFIG_EBIU_SDRRC_VAL 0x398 +#define CONFIG_EBIU_SDGCTL_VAL 0x91118d +#define CONFIG_EBIU_SDBCTL_VAL 0x13 + +#define CONFIG_EBIU_AMGCTL_VAL 0xFF +#define CONFIG_EBIU_AMBCTL0_VAL 0x7BB07BB0 +#define CONFIG_EBIU_AMBCTL1_VAL 0xFFC27BB0 + +#include <asm/blackfin-config-post.h>
#endif diff --git a/include/configs/bf533-stamp.h b/include/configs/bf533-stamp.h index 76dd2fa..66a0af6 100644 --- a/include/configs/bf533-stamp.h +++ b/include/configs/bf533-stamp.h @@ -7,37 +7,17 @@
#include <asm/blackfin-config-pre.h>
-#define CONFIG_STAMP 1 #define CONFIG_RTC_BFIN 1 -#define CONFIG_BF533 1 -/* - * Boot Mode Set - * Blackfin can support several boot modes - */ -#define BF533_BYPASS_BOOT 0x0001 /* Bootmode 0: Execute from 16-bit externeal memory ( bypass BOOT ROM) */ -#define BF533_PARA_BOOT 0x0002 /* Bootmode 1: Boot from 8-bit or 16-bit flash */ -#define BF533_SPI_BOOT 0x0004 /* Bootmode 3: Boot from SPI flash */ -/* Define the boot mode */ -#define BFIN_BOOT_MODE BF533_BYPASS_BOOT -/* #define BFIN_BOOT_MODE BF533_SPI_BOOT */
#define CONFIG_PANIC_HANG 1
#define CONFIG_BFIN_CPU bf533-0.3 +#define CONFIG_BFIN_BOOT_MODE BFIN_BOOT_BYPASS
/* This sets the default state of the cache on U-Boot's boot */ #define CONFIG_ICACHE_ON #define CONFIG_DCACHE_ON
-/* Define where the uboot will be loaded by on-chip boot rom */ -#define APP_ENTRY 0x00001000 - -/* - * Stringize definitions - needed for environmental settings - */ -#define STRINGIZE2(x) #x -#define STRINGIZE(x) STRINGIZE2(x) - /* * Board settings */ @@ -61,8 +41,6 @@ */ #define CONFIG_VIDEO 0
-#define CONFIG_VDSP 1 - /* * Clock settings */ @@ -88,10 +66,7 @@ /* Values can range from 2-65535 */ /* SCK Frequency = SCLK / (2 * CONFIG_SPI_BAUD) */ #define CONFIG_SPI_BAUD 2 - -#if (BFIN_BOOT_MODE == BF533_SPI_BOOT) #define CONFIG_SPI_BAUD_INITBLOCK 4 -#endif
/* * Network settings @@ -126,14 +101,14 @@ #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ #define CFG_MAX_FLASH_SECT 67 /* max number of sectors on one chip */
-#if (BFIN_BOOT_MODE == BF533_BYPASS_BOOT) -#define CFG_ENV_IS_IN_FLASH 1 -#define CFG_ENV_ADDR 0x20004000 -#define CFG_ENV_OFFSET (CFG_ENV_ADDR - CFG_FLASH_BASE) -#elif (BFIN_BOOT_MODE == BF533_SPI_BOOT) +#if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_SPI_MASTER) #define CFG_ENV_IS_IN_EEPROM 1 #define CFG_ENV_OFFSET 0x4000 #define CFG_ENV_HEADER (CFG_ENV_OFFSET + 0x12A) /* 0x12A is the length of LDR file header */ +#else +#define CFG_ENV_IS_IN_FLASH 1 +#define CFG_ENV_ADDR 0x20004000 +#define CFG_ENV_OFFSET (CFG_ENV_ADDR - CFG_FLASH_BASE) #endif
#define CFG_ENV_SIZE 0x2000 @@ -165,11 +140,7 @@ #define CONFIG_MEM_ADD_WDTH 11 /* 8, 9, 10, 11 */ #define CONFIG_MEM_MT48LC64M4A2FB_7E 1
-#if (BFIN_BOOT_MODE == BF533_BYPASS_BOOT) #define CFG_MEMTEST_START 0x00000000 /* memtest works on */ -#elif (BFIN_BOOT_MODE == BF533_SPI_BOOT) -#define CFG_MEMTEST_START 0x00100000 /* memtest works on */ -#endif
#define CFG_SDRAM_BASE 0x00000000
@@ -207,14 +178,6 @@ #define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ #endif
-#if (BFIN_BOOT_MODE == BF533_SPI_BOOT) -#if (CONFIG_SCLK_HZ / (2*CONFIG_SPI_BAUD) > 20000000) -#define CONFIG_SPI_FLASH_FAST_READ 1 /* Needed if SPI_CLK > 20 MHz */ -#else -#undef CONFIG_SPI_FLASH_FAST_READ -#endif -#endif - /* * Command settings */ @@ -222,26 +185,18 @@ #define CFG_LONGHELP 1 #define CONFIG_CMDLINE_EDITING 1
-#if (BFIN_BOOT_MODE == BF533_BYPASS_BOOT) #define CFG_AUTOLOAD "no" /*rarpb, bootp or dhcp commands will perform only a */ -#endif
/* configuration lookup from the BOOTP/DHCP server, */ /* but not try to load any image using TFTP */
#define CONFIG_BOOTDELAY 5 #define CONFIG_BOOT_RETRY_TIME -1 /* Enable this if bootretry required, currently its disabled */ -#if (BFIN_BOOT_MODE == BF533_BYPASS_BOOT) #define CONFIG_BOOTCOMMAND "run ramboot" -#elif (BFIN_BOOT_MODE == BF533_SPI_BOOT) -#define CONFIG_BOOTCOMMAND "eeprom read 0x1000000 0x100000 0x180000;icache on;dcache on;bootm 0x1000000" -#endif
#define CONFIG_BOOTARGS "root=/dev/mtdblock0 rw console=ttyBF0,57600"
-#if (BFIN_BOOT_MODE == BF533_BYPASS_BOOT) -#if (CONFIG_DRIVER_SMC91111) #define CONFIG_EXTRA_ENV_SETTINGS \ "ramargs=setenv bootargs root=/dev/mtdblock0 rw console=ttyBF0,57600\0" \ "nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):" \ @@ -257,29 +212,6 @@ "protect off 0x20000000 0x2003FFFF; erase 0x20000000 0x2003FFFF;" \ "cp.b $(loadaddr) 0x20000000 $(filesize)\0" \ "" -#else -#define CONFIG_EXTRA_ENV_SETTINGS \ - "ramargs=setenv bootargs root=/dev/mtdblock0 rw console=ttyBF0,57600\0" \ - "flashboot=bootm 0x20100000\0" \ - " -#endif - -#elif (BFIN_BOOT_MODE == BF533_SPI_BOOT) -#define CONFIG_EXTRA_ENV_SETTINGS \ - "ramargs=setenv bootargs root=/dev/mtdblock0 rw console=ttyBF0,57600\0" \ - "nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):" \ - "$(rootpath) console=ttyBF0,57600\0" \ - "addip=setenv bootargs $(bootargs) ip=$(ipaddr):$(serverip):" \ - "$(gatewayip):$(netmask):$(hostname):eth0:off\0" \ - "ramboot=tftpboot $(loadaddr) linux; " \ - "run ramargs;run addip;bootelf\0" \ - "nfsboot=tftpboot $(loadaddr) linux; " \ - "run nfsargs;run addip;bootelf\0" \ - "flashboot=bootm 0x20100000\0" \ - "update=tftpboot $(loadaddr) u-boot.ldr;" \ - "eeprom write $(loadaddr) 0x0 $(filesize);\0"\ - "" -#endif
#ifdef CONFIG_SOFT_I2C #if (!CONFIG_SOFT_I2C) @@ -316,9 +248,7 @@ #define CONFIG_CMD_I2C #endif
-#if (BFIN_BOOT_MODE == BF533_BYPASS_BOOT) #define CONFIG_CMD_DHCP -#endif
/* @@ -428,25 +358,16 @@ /* * FLASH organization and environment definitions */ -#define CFG_BOOTMAPSZ (8 << 20)/* Initial Memory map for Linux */ - -/* 0xFF, 0xBBC3BBc3, 0x99B39983 */ -/*#define AMGCTLVAL (AMBEN_P0 | AMBEN_P1 | AMBEN_P2 | AMCKEN) -#define AMBCTL0VAL (B1WAT_11 | B1RAT_11 | B1HT_3 | B1ST_4 | B1TT_4 | B1RDYPOL | \ - B1RDYEN | B0WAT_11 | B0RAT_11 | B0HT_3 | B0ST_4 | B0TT_4 | B0RDYPOL | B0RDYEN) -#define AMBCTL1VAL (B3WAT_9 | B3RAT_9 | B3HT_2 | B3ST_3 | B3TT_4 | B3RDYPOL | \ - B3RDYEN | B2WAT_9 | B2RAT_9 | B2HT_2 | B2ST_4 | B2TT_4 | B2RDYPOL | B2RDYEN) -*/ -#define AMGCTLVAL 0xFF -#define AMBCTL0VAL 0xBBC3BBC3 -#define AMBCTL1VAL 0x99B39983 -#define CF_AMBCTL1VAL 0x99B3ffc2 - -#ifdef CONFIG_VDSP -#define ET_EXEC_VDSP 0x8 -#define SHT_STRTAB_VDSP 0x1 -#define ELFSHDRSIZE_VDSP 0x2C -#define VDSP_ENTRY_ADDR 0xFFA00000 -#endif + +#define CONFIG_EBIU_SDRRC_VAL 0x268 +#define CONFIG_EBIU_SDGCTL_VAL 0x911109 +#define CONFIG_EBIU_SDBCTL_VAL 0x37 + +#define CONFIG_EBIU_AMGCTL_VAL 0xFF +#define CONFIG_EBIU_AMBCTL0_VAL 0xBBC3BBC3 +#define CONFIG_EBIU_AMBCTL1_VAL 0x99B39983 +#define CF_CONFIG_EBIU_AMBCTL1_VAL 0x99B3ffc2 + +#include <asm/blackfin-config-post.h>
#endif diff --git a/include/configs/bf537-stamp.h b/include/configs/bf537-stamp.h index 0e189d4..39c7359 100644 --- a/include/configs/bf537-stamp.h +++ b/include/configs/bf537-stamp.h @@ -12,28 +12,15 @@ #define CONFIG_BAUDRATE 57600 /* Set default serial console for bf537 */ #define CONFIG_UART_CONSOLE 0 -#define CONFIG_BF537 1 #define CONFIG_BOOTDELAY 5 /* define CONFIG_BF537_STAMP_LEDCMD to enable LED command*/ /*#define CONFIG_BF537_STAMP_LEDCMD 1*/
-/* - * Boot Mode Set - * Blackfin can support several boot modes - */ -#define BF537_BYPASS_BOOT 0x0011 /* Bootmode 0: Execute from 16-bit externeal memory ( bypass BOOT ROM) */ -#define BF537_PARA_BOOT 0x0012 /* Bootmode 1: Boot from 8-bit or 16-bit flash */ -#define BF537_SPI_MASTER_BOOT 0x0014 /* Bootmode 3: SPI master mode boot from SPI flash */ -#define BF537_SPI_SLAVE_BOOT 0x0015 /* Bootmode 4: SPI slave mode boot from SPI flash */ -#define BF537_TWI_MASTER_BOOT 0x0016 /* Bootmode 5: TWI master mode boot from EEPROM */ -#define BF537_TWI_SLAVE_BOOT 0x0017 /* Bootmode 6: TWI slave mode boot from EEPROM */ -#define BF537_UART_BOOT 0x0018 /* Bootmode 7: UART slave mdoe boot via UART host */ -/* Define the boot mode */ -#define BFIN_BOOT_MODE BF537_BYPASS_BOOT - #define CONFIG_PANIC_HANG 1
#define CONFIG_BFIN_CPU bf537-0.2 +#define CONFIG_BFIN_BOOT_MODE BFIN_BOOT_BYPASS + #define CONFIG_BFIN_MAC
/* This sets the default state of the cache on U-Boot's boot */ @@ -43,9 +30,6 @@ /* Define if want to do post memory test */ #undef CONFIG_POST_TEST
-/* Define where the uboot will be loaded by on-chip boot rom */ -#define APP_ENTRY 0x00001000 - #define CONFIG_RTC_BFIN 1 #define CONFIG_BOOT_RETRY_TIME -1 /* Enable this if bootretry required, currently its disabled */
@@ -70,9 +54,7 @@ /* Values can range from 2-65535 */ /* SCK Frequency = SCLK / (2 * CONFIG_SPI_BAUD) */ #define CONFIG_SPI_BAUD 2 -#if (BFIN_BOOT_MODE == BF537_SPI_MASTER_BOOT) #define CONFIG_SPI_BAUD_INITBLOCK 4 -#endif
#if ( CONFIG_CLKIN_HALF == 0 ) #define CONFIG_VCO_HZ ( CONFIG_CLKIN_HZ * CONFIG_VCO_MULT ) @@ -88,14 +70,6 @@ #define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ #endif
-#if (BFIN_BOOT_MODE == BF537_SPI_MASTER_BOOT) -#if (CONFIG_SCLK_HZ / (2*CONFIG_SPI_BAUD) > 20000000) -#define CONFIG_SPI_FLASH_FAST_READ 1 /* Needed if SPI_CLK > 20 MHz */ -#else -#undef CONFIG_SPI_FLASH_FAST_READ -#endif -#endif - #define CONFIG_MEM_SIZE 64 /* 128, 64, 32, 16 */ #define CONFIG_MEM_ADD_WDTH 10 /* 8, 9, 10, 11 */ #define CONFIG_MEM_MT48LC32M8A2_75 1 @@ -131,7 +105,7 @@ #define CONFIG_BOOT_RETRY_TIME -1 /* Enable this if bootretry required, currently its disabled */ #define CONFIG_BOOTCOMMAND "run ramboot"
-#if (BFIN_BOOT_MODE == BF537_BYPASS_BOOT) && defined(CONFIG_POST_TEST) +#if defined(CONFIG_POST_TEST) /* POST support */ #define CONFIG_POST ( CFG_POST_MEMORY | \ CFG_POST_UART | \ @@ -177,8 +151,6 @@ */ #include <config_cmd_default.h>
-#if (BFIN_BOOT_MODE == BF537_BYPASS_BOOT) || (BFIN_BOOT_MODE == BF537_SPI_MASTER_BOOT) - #define CONFIG_CMD_ELF #define CONFIG_CMD_I2C #define CONFIG_CMD_CACHE @@ -198,10 +170,6 @@ #define CONFIG_CMD_IDE #endif
-#endif - -#if (BFIN_BOOT_MODE == BF537_BYPASS_BOOT) - #define CONFIG_CMD_DHCP
#if defined(CONFIG_POST) @@ -212,14 +180,10 @@ #define CONFIG_CMD_NAND #endif
-#endif -
#define CONFIG_BOOTARGS "root=/dev/mtdblock0 rw console=ttyBF0,57600" #define CONFIG_LOADADDR 0x1000000
-#if (BFIN_BOOT_MODE == BF537_BYPASS_BOOT) -#ifdef CONFIG_BFIN_MAC #define CONFIG_EXTRA_ENV_SETTINGS \ "ramargs=setenv bootargs root=/dev/mtdblock0 rw console=ttyBF0,57600\0" \ "nfsargs=setenv bootargs root=/dev/nfs rw " \ @@ -236,36 +200,6 @@ "protect off 0x20000000 0x2007FFFF;" \ "erase 0x20000000 0x2007FFFF;cp.b 0x1000000 0x20000000 $(filesize)\0" \ "" -#else -#define CONFIG_EXTRA_ENV_SETTINGS \ - "ramargs=setenv bootargs root=/dev/mtdblock0 rw console=ttyBF0,57600\0" \ - "flashboot=bootm 0x20100000\0" \ - "" -#endif -#elif (BFIN_BOOT_MODE == BF537_SPI_MASTER_BOOT) -#ifdef CONFIG_BFIN_MAC -#define CONFIG_EXTRA_ENV_SETTINGS \ - "ramargs=setenv bootargs root=/dev/mtdblock0 rw console=ttyBF0,57600\0" \ - "nfsargs=setenv bootargs root=/dev/nfs rw " \ - "nfsroot=$(serverip):$(rootpath) console=ttyBF0,57600\0"\ - "addip=setenv bootargs $(bootargs) " \ - "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask)" \ - ":$(hostname):eth0:off\0" \ - "ramboot=tftpboot $(loadaddr) linux;" \ - "run ramargs;run addip;bootelf\0" \ - "nfsboot=tftpboot $(loadaddr) linux;" \ - "run nfsargs;run addip;bootelf\0" \ - "flashboot=bootm 0x20100000\0" \ - "update=tftpboot $(loadaddr) u-boot.ldr;" \ - "eeprom write $(loadaddr) 0x0 $(filesize);\0" \ - "" -#else -#define CONFIG_EXTRA_ENV_SETTINGS \ - "ramargs=setenv bootargs root=/dev/mtdblock0 rw console=ttyBF0,57600\0" \ - "flashboot=bootm 0x20100000\0" \ - "" -#endif -#endif
#define CFG_PROMPT "bfin> " /* Monitor Command Prompt */
@@ -300,21 +234,18 @@ #define CFG_GBL_DATA_ADDR (CFG_MALLOC_BASE - CFG_GBL_DATA_SIZE) #define CONFIG_STACKBASE (CFG_GBL_DATA_ADDR - 4)
-#if (BFIN_BOOT_MODE == BF537_BYPASS_BOOT) || (BFIN_BOOT_MODE == BF537_UART_BOOT) -/* for bf537-stamp, usrt boot mode still store env in flash */ -#define CFG_ENV_IS_IN_FLASH 1 -#define CFG_ENV_ADDR 0x20004000 -#define CFG_ENV_OFFSET (CFG_ENV_ADDR - CFG_FLASH_BASE) -#elif (BFIN_BOOT_MODE == BF537_SPI_MASTER_BOOT) +#if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_SPI_MASTER) #define CFG_ENV_IS_IN_EEPROM 1 #define CFG_ENV_OFFSET 0x4000 #define CFG_ENV_HEADER (CFG_ENV_OFFSET + 0x16e) /* 0x12A is the length of LDR file header */ +#else +#define CFG_ENV_IS_IN_FLASH 1 +#define CFG_ENV_ADDR 0x20004000 +#define CFG_ENV_OFFSET (CFG_ENV_ADDR - CFG_FLASH_BASE) #endif #define CFG_ENV_SIZE 0x2000 #define CFG_ENV_SECT_SIZE 0x2000 /* Total Size of Environment Sector */ -/* #if (BFIN_BOOT_MODE == BF537_BYPASS_BOOT) */ #define ENV_IS_EMBEDDED -/* #endif */
/* JFFS Partition offset set */ #define CFG_JFFS2_FIRST_BANK 0 @@ -383,6 +314,14 @@ #define CONFIG_TWICLK_KHZ 50 #endif
+#define CONFIG_EBIU_SDRRC_VAL 0x306 +#define CONFIG_EBIU_SDGCTL_VAL 0x91114d +#define CONFIG_EBIU_SDBCTL_VAL 0x25 + +#define CONFIG_EBIU_AMGCTL_VAL 0xFF +#define CONFIG_EBIU_AMBCTL0_VAL 0x7BB07BB0 +#define CONFIG_EBIU_AMBCTL1_VAL 0xFFC27BB0 + #if defined CONFIG_SOFT_I2C /* * Software (bit-bang) I2C driver configuration @@ -428,15 +367,6 @@ #define AMBCTL0VAL 0x7BB07BB0 #define AMBCTL1VAL 0xFFC27BB0
-#define CONFIG_VDSP 1 - -#ifdef CONFIG_VDSP -#define ET_EXEC_VDSP 0x8 -#define SHT_STRTAB_VDSP 0x1 -#define ELFSHDRSIZE_VDSP 0x2C -#define VDSP_ENTRY_ADDR 0xFFA00000 -#endif - #if defined(CONFIG_BFIN_IDE)
#define CONFIG_DOS_PARTITION 1 @@ -492,4 +422,6 @@
#endif /*CONFIG_BFIN_IDE */
+#include <asm/blackfin-config-post.h> + #endif diff --git a/include/configs/bf561-ezkit.h b/include/configs/bf561-ezkit.h index c29555a..641548d 100644 --- a/include/configs/bf561-ezkit.h +++ b/include/configs/bf561-ezkit.h @@ -7,9 +7,6 @@
#include <asm/blackfin-config-pre.h>
-#define CONFIG_VDSP 1 -#define CONFIG_BF561 1 - #define CFG_LONGHELP 1 #define CONFIG_CMDLINE_EDITING 1 #define CONFIG_BAUDRATE 57600 @@ -21,30 +18,12 @@ #define CONFIG_PANIC_HANG 1
#define CONFIG_BFIN_CPU bf561-0.3 - -/* -* Boot Mode Set -* Blackfin can support several boot modes -*/ -#define BF561_BYPASS_BOOT 0x21 -#define BF561_PARA_BOOT 0x22 -#define BF561_SPI_BOOT 0x24 -/* Define the boot mode */ -#define BFIN_BOOT_MODE BF561_BYPASS_BOOT +#define CONFIG_BFIN_BOOT_MODE BFIN_BOOT_BYPASS
/* This sets the default state of the cache on U-Boot's boot */ #define CONFIG_ICACHE_ON #define CONFIG_DCACHE_ON
-/* Define where the uboot will be loaded by on-chip boot rom */ -#define APP_ENTRY 0x00001000 - -/* - * Stringize definitions - needed for environmental settings - */ -#define STRINGIZE2(x) #x -#define STRINGIZE(x) STRINGIZE2(x) - /* * Board settings */ @@ -242,17 +221,14 @@ /* * FLASH organization and environment definitions */ -#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ +#define CONFIG_EBIU_SDRRC_VAL 0x306 +#define CONFIG_EBIU_SDGCTL_VAL 0x91114d +#define CONFIG_EBIU_SDBCTL_VAL 0x15
-#define AMGCTLVAL 0x3F -#define AMBCTL0VAL 0x7BB07BB0 -#define AMBCTL1VAL 0xFFC27BB0 +#define CONFIG_EBIU_AMGCTL_VAL 0x3F +#define CONFIG_EBIU_AMBCTL0_VAL 0x7BB07BB0 +#define CONFIG_EBIU_AMBCTL1_VAL 0xFFC27BB0
-#ifdef CONFIG_VDSP -#define ET_EXEC_VDSP 0x8 -#define SHT_STRTAB_VDSP 0x1 -#define ELFSHDRSIZE_VDSP 0x2C -#define VDSP_ENTRY_ADDR 0xFFA00000 -#endif +#include <asm/blackfin-config-post.h>
#endif /* __CONFIG_EZKIT561_H__ */ diff --git a/lib_blackfin/board.c b/lib_blackfin/board.c index 2a5a2fc..140ec07 100644 --- a/lib_blackfin/board.c +++ b/lib_blackfin/board.c @@ -37,7 +37,7 @@ #include <asm/cplb.h> #include "../drivers/net/smc91111.h"
-#if defined(CONFIG_BF537)&&defined(CONFIG_POST) +#if defined(CONFIG_POST) #include <post.h> int post_flag; #endif @@ -192,21 +192,8 @@ void init_cplbtables(void) } j++; } -#if defined(CONFIG_BF561) - /* MAC space */ - icplb_table[j][0] = 0x2C000000; - icplb_table[j][1] = SDRAM_INON_CHBL; - j++; - /* Async Memory space */ - for (i = 0; i < 3; i++) { - icplb_table[j][0] = 0x20000000 + i * 4 * 1024 * 1024; - icplb_table[j][1] = SDRAM_INON_CHBL; - j++; - } -#else icplb_table[j][0] = 0x20000000; icplb_table[j][1] = SDRAM_INON_CHBL; -#endif j = 0; dcplb_table[j][0] = 0xFF800000; dcplb_table[j][1] = L1_DMEMORY; @@ -223,22 +210,8 @@ void init_cplbtables(void) j++; }
-#if defined(CONFIG_BF561) - /* MAC space */ - dcplb_table[j][0] = 0x2C000000; - dcplb_table[j][1] = SDRAM_EBIU; - j++; - - /* Flash space */ - for (i = 0; i < 3; i++) { - dcplb_table[j][0] = 0x20000000 + i * 4 * 1024 * 1024; - dcplb_table[j][1] = SDRAM_EBIU; - j++; - } -#else dcplb_table[j][0] = 0x20000000; dcplb_table[j][1] = SDRAM_EBIU; -#endif }
/* @@ -275,7 +248,7 @@ void board_init_f(ulong bootflag) memset((void *)bd, 0, sizeof(bd_t));
/* Initialize */ - init_IRQ(); + irq_init(); env_init(); /* initialize environment */ init_baudrate(); /* initialze baudrate settings */ serial_init(); /* serial communications setup */ @@ -304,7 +277,7 @@ void board_init_f(ulong bootflag) get_vco() / 1000000, get_cclk() / 1000000, get_sclk() / 1000000); printf("SDRAM: "); print_size(initdram(0), "\n"); -#if defined(CONFIG_BF537)&&defined(CONFIG_POST) +#if defined(CONFIG_POST) post_init_f(); post_bootmode_init(); post_run(NULL, POST_ROM | post_bootmode_get(0)); @@ -333,12 +306,12 @@ void board_init_r(gd_t * id, ulong dest_addr) gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ bd = gd->bd;
-#if defined(CONFIG_BF537) && defined(CONFIG_POST) +#if defined(CONFIG_POST) post_output_backlog(); post_reloc(); #endif
-#if (CONFIG_STAMP || CONFIG_BF537 || CONFIG_EZKIT561) && !defined(CFG_NO_FLASH) +#if !defined(CFG_NO_FLASH) /* There are some other pointer constants we must deal with */ /* configure available FLASH banks */ size = flash_init(); @@ -434,7 +407,7 @@ void board_init_r(gd_t * id, ulong dest_addr) display_global_data(); #endif
-#if defined(CONFIG_BF537) && defined(CONFIG_POST) +#if defined(CONFIG_POST) if (post_flag) post_run(NULL, POST_RAM | post_bootmode_get(0)); #endif

Signed-off-by: Mike Frysinger vapier@gentoo.org --- common/Makefile | 1 + common/cmd_cplbinfo.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 0 deletions(-) create mode 100644 common/cmd_cplbinfo.c
diff --git a/common/Makefile b/common/Makefile index 1244e0b..56d0581 100644 --- a/common/Makefile +++ b/common/Makefile @@ -41,6 +41,7 @@ COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o COBJS-y += cmd_bootm.o COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o COBJS-$(CONFIG_CMD_CONSOLE) += cmd_console.o +COBJS-$(CONFIG_CMD_CPLBINFO) += cmd_cplbinfo.o COBJS-$(CONFIG_CMD_DATE) += cmd_date.o ifdef CONFIG_4xx COBJS-$(CONFIG_CMD_SETGETDCR) += cmd_dcr.o diff --git a/common/cmd_cplbinfo.c b/common/cmd_cplbinfo.c new file mode 100644 index 0000000..b2bbec1 --- /dev/null +++ b/common/cmd_cplbinfo.c @@ -0,0 +1,59 @@ +/* + * cmd_cplbinfo.c - dump the instruction/data cplb tables + * + * Copyright (c) 2007-2008 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <common.h> +#include <command.h> +#include <asm/blackfin.h> +#include <asm/cplb.h> +#include <asm/mach-common/bits/mpu.h> + +/* + * Translate the PAGE_SIZE bits into a human string + */ +static const char *cplb_page_size(uint32_t data) +{ + static const char page_size_string_table[][4] = { "1K", "4K", "1M", "4M" }; + return page_size_string_table[(data & PAGE_SIZE_MASK) >> PAGE_SIZE_SHIFT]; +} + +/* + * show a hardware cplb table + */ +static void show_cplb_table(uint32_t *addr, uint32_t *data) +{ + size_t i; + printf(" Address Data Size Valid Locked\n"); + for (i = 1; i <= 16; ++i) { + printf(" %2i 0x%p 0x%05X %s %c %c\n", + i, *addr, *data, + cplb_page_size(*data), + (*data & CPLB_VALID ? 'Y' : 'N'), + (*data & CPLB_LOCK ? 'Y' : 'N')); + ++addr; + ++data; + } +} + +/* + * display current instruction and data cplb tables + */ +int do_cplbinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + printf("%s CPLB table [%08x]:\n", "Instruction", *(uint32_t *)DMEM_CONTROL); + show_cplb_table((uint32_t *)ICPLB_ADDR0, (uint32_t *)ICPLB_DATA0); + + printf("%s CPLB table [%08x]:\n", "Data", *(uint32_t *)IMEM_CONTROL); + show_cplb_table((uint32_t *)DCPLB_ADDR0, (uint32_t *)DCPLB_DATA0); + + return 0; +} + +U_BOOT_CMD(cplbinfo, 1, 0, do_cplbinfo, + "cplbinfo- display current CPLB tables\n", + "\n" + " - display current CPLB tables\n");

Signed-off-by: Mike Frysinger vapier@gentoo.org --- lib_blackfin/memcmp.S | 3 +++ lib_blackfin/memcpy.S | 3 +++ lib_blackfin/memmove.S | 3 +++ lib_blackfin/memset.S | 3 +++ 4 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/lib_blackfin/memcmp.S b/lib_blackfin/memcmp.S index 9b58832..6c834a7 100644 --- a/lib_blackfin/memcmp.S +++ b/lib_blackfin/memcmp.S @@ -31,6 +31,7 @@ */
.globl _memcmp; +.type _memcmp, STT_FUNC; _memcmp: I1 = P3; P0 = R0; /* P0 = s1 address */ @@ -98,3 +99,5 @@ _memcmp: R0 = 0; P3 = I1; RTS; + +.size _memcmp, .-_memcmp diff --git a/lib_blackfin/memcpy.S b/lib_blackfin/memcpy.S index 24577be..e6b359a 100644 --- a/lib_blackfin/memcpy.S +++ b/lib_blackfin/memcpy.S @@ -23,6 +23,7 @@ .align 2
.globl _memcpy_ASM; +.type _memcpy_ASM, STT_FUNC; _memcpy_ASM: CC = R2 <= 0; /* length not positive?*/ IF CC JUMP .L_P1L2147483647; /* Nothing to do */ @@ -112,3 +113,5 @@ _memcpy_ASM: B[P0--] = R1;
RTS; + +.size _memcpy_ASM, .-_memcpy_ASM diff --git a/lib_blackfin/memmove.S b/lib_blackfin/memmove.S index 46f79ed..e385c4f 100644 --- a/lib_blackfin/memmove.S +++ b/lib_blackfin/memmove.S @@ -31,6 +31,7 @@ */
.globl _memmove; +.type _memmove, STT_FUNC; _memmove: I1 = P3; P0 = R0; /* P0 = To address */ @@ -91,3 +92,5 @@ _memmove: .Lno_loop: B[P0] = R1; P3 = I1; RTS; + +.size _memmove, .-_memmove diff --git a/lib_blackfin/memset.S b/lib_blackfin/memset.S index c33c551..26f63cd 100644 --- a/lib_blackfin/memset.S +++ b/lib_blackfin/memset.S @@ -31,6 +31,7 @@ */
.globl _memset; +.type _memset, STT_FUNC; _memset: P0 = R0 ; /* P0 = address */ P2 = R2 ; /* P2 = count */ @@ -91,3 +92,5 @@ _memset: B[P0++] = R1; B[P0++] = R1; JUMP .Laligned; + +.size _memset, .-_memset

Signed-off-by: Mike Frysinger vapier@gentoo.org --- lib_blackfin/cache.c | 35 ++++++++--------------------------- lib_blackfin/cache.h | 35 ----------------------------------- 2 files changed, 8 insertions(+), 62 deletions(-) delete mode 100644 lib_blackfin/cache.h
diff --git a/lib_blackfin/cache.c b/lib_blackfin/cache.c index 6fc4983..c2f6e28 100644 --- a/lib_blackfin/cache.c +++ b/lib_blackfin/cache.c @@ -1,45 +1,26 @@ /* * U-boot - cache.c * - * Copyright (c) 2005-2007 Analog Devices Inc. + * Copyright (c) 2005-2008 Analog Devices Inc. * * (C) Copyright 2000-2004 * 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., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA + * Licensed under the GPL-2 or later. */
-/* for now: just dummy functions to satisfy the linker */ -#include <config.h> #include <common.h> #include <asm/blackfin.h> -#include "cache.h"
-void flush_cache(unsigned long dummy1, unsigned long dummy2) +void flush_cache(unsigned long addr, unsigned long size) { - if (dummy1 >= 0xE0000000) + /* no need to flush stuff in on chip memory (L1/L2/etc...) */ + if (addr >= 0xE0000000) return;
if (icache_status()) - blackfin_icache_flush_range((void*)dummy1, (void*)(dummy1 + dummy2)); - if (dcache_status()) - blackfin_dcache_flush_range((void*)dummy1, (void*)(dummy1 + dummy2)); + blackfin_icache_flush_range((void *)addr, (void *)(addr + size));
- return; + if (dcache_status()) + blackfin_dcache_flush_range((void *)addr, (void *)(addr + size)); } diff --git a/lib_blackfin/cache.h b/lib_blackfin/cache.h deleted file mode 100644 index 3ea6809..0000000 --- a/lib_blackfin/cache.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * U-boot - prototypes for cache handling functions. - * - * Copyright (c) 2005-2007 Analog Devices Inc. - * - * (C) Copyright 2000-2004 - * 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, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _LIB_BLACKFIN_CACHE_H_ -#define _LIB_BLACKFIN_CACHE_H_ - -extern void blackfin_icache_flush_range(const void *, const void *); -extern void blackfin_dcache_flush_range(const void *, const void *); -extern void blackfin_dcache_invalidate_range(const void *, const void *); - -#endif

Signed-off-by: Mike Frysinger vapier@gentoo.org --- lib_blackfin/Makefile | 4 +- lib_blackfin/blackfin_board.h | 64 ------- lib_blackfin/board.c | 394 +++++++++++++++++++++++------------------ 3 files changed, 226 insertions(+), 236 deletions(-) delete mode 100644 lib_blackfin/blackfin_board.h
diff --git a/lib_blackfin/Makefile b/lib_blackfin/Makefile index 527fe1b..a5ab3f7 100644 --- a/lib_blackfin/Makefile +++ b/lib_blackfin/Makefile @@ -1,7 +1,7 @@ # # U-boot Makefile # -# Copyright (c) 2005-2007 Analog Devices Inc. +# Copyright (c) 2005-2008 Analog Devices Inc. # # (C) Copyright 2000-2006 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -27,6 +27,8 @@
include $(TOPDIR)/config.mk
+CFLAGS += -DBFIN_BOARD_NAME='"$(BOARD)"' + LIB = $(obj)lib$(ARCH).a
SOBJS = memcpy.o memcmp.o memset.o memmove.o diff --git a/lib_blackfin/blackfin_board.h b/lib_blackfin/blackfin_board.h deleted file mode 100644 index 1353421..0000000 --- a/lib_blackfin/blackfin_board.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * U-boot - blackfin_board.h - * - * Copyright (c) 2005-2007 Analog Devices Inc. - * - * (C) Copyright 2000-2004 - * 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., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#ifndef __BLACKFIN_BOARD_H__ -#define __BLACKFIN_BOARD_H__ - -#include <version.h> - -extern void timer_init(void); -extern void init_IRQ(void); -extern void rtc_init(void); - -extern ulong uboot_end_data; -extern ulong uboot_end; - -ulong monitor_flash_len; - - -#define VERSION_STRING_SIZE 150 /* including 40 bytes buffer to change any string */ -#define VERSION_STRING_FORMAT "%s (%s - %s)\n" -#define VERSION_STRING U_BOOT_VERSION, __DATE__, __TIME__ - -char version_string[VERSION_STRING_SIZE]; - -int *g_addr; -static ulong mem_malloc_start; -static ulong mem_malloc_end; -static ulong mem_malloc_brk; -extern char _sram_in_sdram_start[]; -extern char _sram_inst_size[]; -#ifdef DEBUG -static void display_global_data(void); -#endif - -/* definitions used to check the SMC card availability */ -#define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE -#define UPPER_BYTE_MASK 0xFF00 -#define SMC_IDENT 0x3300 - -#endif diff --git a/lib_blackfin/board.c b/lib_blackfin/board.c index 140ec07..43d8be8 100644 --- a/lib_blackfin/board.c +++ b/lib_blackfin/board.c @@ -1,41 +1,29 @@ /* * U-boot - board.c First C file to be called contains init routines * - * Copyright (c) 2005-2007 Analog Devices Inc. + * Copyright (c) 2005-2008 Analog Devices Inc. * * (C) Copyright 2000-2004 * 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., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA + * Licensed under the GPL-2 or later. */
#include <common.h> #include <command.h> -#include <malloc.h> #include <devices.h> -#include <version.h> -#include <net.h> #include <environment.h> #include <i2c.h> -#include "blackfin_board.h" +#include <malloc.h> +#include <net.h> +#include <version.h> + #include <asm/cplb.h> -#include "../drivers/net/smc91111.h" +#include <asm/mach-common/bits/mpu.h> + +#ifdef CONFIG_CMD_NAND +#include <nand.h> /* cannot even include nand.h if it isnt configured */ +#endif
#if defined(CONFIG_POST) #include <post.h> @@ -44,11 +32,19 @@ int post_flag;
DECLARE_GLOBAL_DATA_PTR;
-#ifndef CFG_NO_FLASH -extern flash_info_t flash_info[]; +const char version_string[] = U_BOOT_VERSION " (" __DATE__ " - " __TIME__ ")"; + +__attribute__((always_inline)) +static inline void serial_early_puts(const char *s) +{ +#ifdef CONFIG_DEBUG_EARLY_SERIAL + serial_puts("Early: "); + serial_puts(s); #endif +}
-static inline u_long get_vco(void) +/* Get the input voltage */ +static u_long get_vco(void) { u_long msel; u_long vco; @@ -63,7 +59,7 @@ static inline u_long get_vco(void) return vco; }
-/*Get the Core clock*/ +/* Get the Core clock */ u_long get_cclk(void) { u_long csel, ssel; @@ -91,127 +87,152 @@ u_long get_sclk(void) return get_vco() / ssel; }
+static void *mem_malloc_start, *mem_malloc_end, *mem_malloc_brk; + static void mem_malloc_init(void) { - mem_malloc_start = CFG_MALLOC_BASE; - mem_malloc_end = (CFG_MALLOC_BASE + CFG_MALLOC_LEN); + mem_malloc_start = (void *)CFG_MALLOC_BASE; + mem_malloc_end = (void *)(CFG_MALLOC_BASE + CFG_MALLOC_LEN); mem_malloc_brk = mem_malloc_start; - memset((void *)mem_malloc_start, 0, mem_malloc_end - mem_malloc_start); + memset(mem_malloc_start, 0, mem_malloc_end - mem_malloc_start); }
void *sbrk(ptrdiff_t increment) { - ulong old = mem_malloc_brk; - ulong new = old + increment; + void *old = mem_malloc_brk; + void *new = old + increment; + + if (new < mem_malloc_start || new > mem_malloc_end) + return NULL;
- if ((new < mem_malloc_start) || (new > mem_malloc_end)) { - return (NULL); - } mem_malloc_brk = new;
- return ((void *)old); + return old; }
static int display_banner(void) { - sprintf(version_string, VERSION_STRING_FORMAT, VERSION_STRING); - printf("%s\n", version_string); + printf("\n\n%s\n\n", version_string); printf("CPU: ADSP " MK_STR(CONFIG_BFIN_CPU) " (Detected Rev: 0.%d)\n", bfin_revid()); - return (0); -} - -static void display_flash_config(ulong size) -{ - puts("FLASH: "); - print_size(size, "\n"); - return; + return 0; }
static int init_baudrate(void) { - char tmp[64]; - int i = getenv_r("baudrate", tmp, sizeof(tmp)); + char baudrate[15]; + int i = getenv_r("baudrate", baudrate, sizeof(baudrate)); gd->bd->bi_baudrate = gd->baudrate = (i > 0) - ? (int)simple_strtoul(tmp, NULL, 10) + ? simple_strtoul(baudrate, NULL, 10) : CONFIG_BAUDRATE; - return (0); + return 0; }
-#ifdef DEBUG static void display_global_data(void) { +#ifdef CONFIG_DEBUG_EARLY_SERIAL bd_t *bd; bd = gd->bd; - printf("--flags:%x\n", gd->flags); - printf("--board_type:%x\n", gd->board_type); - printf("--baudrate:%x\n", gd->baudrate); - printf("--have_console:%x\n", gd->have_console); - printf("--ram_size:%x\n", gd->ram_size); - printf("--reloc_off:%x\n", gd->reloc_off); - printf("--env_addr:%x\n", gd->env_addr); - printf("--env_valid:%x\n", gd->env_valid); - printf("--bd:%x %x\n", gd->bd, bd); - printf("---bi_baudrate:%x\n", bd->bi_baudrate); - printf("---bi_ip_addr:%x\n", bd->bi_ip_addr); - printf("---bi_enetaddr:%x %x %x %x %x %x\n", - bd->bi_enetaddr[0], - bd->bi_enetaddr[1], - bd->bi_enetaddr[2], - bd->bi_enetaddr[3], bd->bi_enetaddr[4], bd->bi_enetaddr[5]); - printf("---bi_arch_number:%x\n", bd->bi_arch_number); - printf("---bi_boot_params:%x\n", bd->bi_boot_params); - printf("---bi_memstart:%x\n", bd->bi_memstart); - printf("---bi_memsize:%x\n", bd->bi_memsize); - printf("---bi_flashstart:%x\n", bd->bi_flashstart); - printf("---bi_flashsize:%x\n", bd->bi_flashsize); - printf("---bi_flashoffset:%x\n", bd->bi_flashoffset); - printf("--jt:%x *:%x\n", gd->jt, *(gd->jt)); -} + printf(" gd: %x\n", gd); + printf(" |-flags: %x\n", gd->flags); + printf(" |-board_type: %x\n", gd->board_type); + printf(" |-baudrate: %i\n", gd->baudrate); + printf(" |-have_console: %x\n", gd->have_console); + printf(" |-ram_size: %x\n", gd->ram_size); + printf(" |-reloc_off: %x\n", gd->reloc_off); + printf(" |-env_addr: %x\n", gd->env_addr); + printf(" |-env_valid: %x\n", gd->env_valid); + printf(" |-jt(%x): %x\n", gd->jt, *(gd->jt)); + printf(" \-bd: %x\n", gd->bd); + printf(" |-bi_baudrate: %x\n", bd->bi_baudrate); + printf(" |-bi_ip_addr: %x\n", bd->bi_ip_addr); + printf(" |-bi_enetaddr: %x %x %x %x %x %x\n", + bd->bi_enetaddr[0], bd->bi_enetaddr[1], + bd->bi_enetaddr[2], bd->bi_enetaddr[3], + bd->bi_enetaddr[4], bd->bi_enetaddr[5]); + printf(" |-bi_boot_params: %x\n", bd->bi_boot_params); + printf(" |-bi_memstart: %x\n", bd->bi_memstart); + printf(" |-bi_memsize: %x\n", bd->bi_memsize); + printf(" |-bi_flashstart: %x\n", bd->bi_flashstart); + printf(" |-bi_flashsize: %x\n", bd->bi_flashsize); + printf(" \-bi_flashoffset: %x\n", bd->bi_flashoffset); #endif +}
-/* we cover everything with 4 meg pages, and need an extra for L1 */ -unsigned int icplb_table[page_descriptor_table_size][2]; -unsigned int dcplb_table[page_descriptor_table_size][2]; - +#define CPLB_PAGE_SIZE (4 * 1024 * 1024) +#define CPLB_PAGE_MASK (~(CPLB_PAGE_SIZE - 1)) void init_cplbtables(void) { - int i, j; - - j = 0; - icplb_table[j][0] = 0xFFA00000; - icplb_table[j][1] = L1_IMEMORY; - j++; - - for (i = 0; i < CONFIG_MEM_SIZE / 4; i++) { - icplb_table[j][0] = (i * 4 * 1024 * 1024); - if (i * 4 * 1024 * 1024 <= CFG_MONITOR_BASE - && (i + 1) * 4 * 1024 * 1024 >= CFG_MONITOR_BASE) { - icplb_table[j][1] = SDRAM_IKERNEL; - } else { - icplb_table[j][1] = SDRAM_IGENERIC; - } - j++; + volatile uint32_t *ICPLB_ADDR, *ICPLB_DATA; + volatile uint32_t *DCPLB_ADDR, *DCPLB_DATA; + uint32_t extern_memory; + size_t i; + + void icplb_add(uint32_t addr, uint32_t data) + { + *(ICPLB_ADDR + i) = addr; + *(ICPLB_DATA + i) = data; } - icplb_table[j][0] = 0x20000000; - icplb_table[j][1] = SDRAM_INON_CHBL; - j = 0; - dcplb_table[j][0] = 0xFF800000; - dcplb_table[j][1] = L1_DMEMORY; - j++; - - for (i = 0; i < CONFIG_MEM_SIZE / 4; i++) { - dcplb_table[j][0] = (i * 4 * 1024 * 1024); - if (i * 4 * 1024 * 1024 <= CFG_MONITOR_BASE - && (i + 1) * 4 * 1024 * 1024 >= CFG_MONITOR_BASE) { - dcplb_table[j][1] = SDRAM_DKERNEL; - } else { - dcplb_table[j][1] = SDRAM_DGENERIC; - } - j++; + void dcplb_add(uint32_t addr, uint32_t data) + { + *(DCPLB_ADDR + i) = addr; + *(DCPLB_DATA + i) = data; }
- dcplb_table[j][0] = 0x20000000; - dcplb_table[j][1] = SDRAM_EBIU; + /* populate a few common entries ... we'll let + * the memory map and cplb exception handler do + * the rest of the work. + */ + i = 0; + ICPLB_ADDR = (uint32_t *)ICPLB_ADDR0; + ICPLB_DATA = (uint32_t *)ICPLB_DATA0; + DCPLB_ADDR = (uint32_t *)DCPLB_ADDR0; + DCPLB_DATA = (uint32_t *)DCPLB_DATA0; + + icplb_add(0xFFA00000, L1_IMEMORY); + dcplb_add(0xFF800000, L1_DMEMORY); + ++i; + + icplb_add(CFG_MONITOR_BASE & CPLB_PAGE_MASK, SDRAM_IKERNEL); + dcplb_add(CFG_MONITOR_BASE & CPLB_PAGE_MASK, SDRAM_DKERNEL); + ++i; + + /* If the monitor crosses a 4 meg boundary, we'll need + * to lock two entries for it. + */ + if ((CFG_MONITOR_BASE & CPLB_PAGE_MASK) != ((CFG_MONITOR_BASE + CFG_MONITOR_LEN) & CPLB_PAGE_MASK)) { + icplb_add((CFG_MONITOR_BASE + CFG_MONITOR_LEN) & CPLB_PAGE_MASK, SDRAM_IKERNEL); + dcplb_add((CFG_MONITOR_BASE + CFG_MONITOR_LEN) & CPLB_PAGE_MASK, SDRAM_DKERNEL); + ++i; + } + + icplb_add(0x20000000, SDRAM_INON_CHBL); + dcplb_add(0x20000000, SDRAM_EBIU); + ++i; + + /* Add entries for the rest of external RAM up to the bootrom */ + extern_memory = 0; + +#ifdef CONFIG_DEBUG_NULL_PTR + icplb_add(extern_memory, (SDRAM_IKERNEL & ~PAGE_SIZE_MASK) | PAGE_SIZE_1KB); + dcplb_add(extern_memory, (SDRAM_DKERNEL & ~PAGE_SIZE_MASK) | PAGE_SIZE_1KB); + ++i; + icplb_add(extern_memory, SDRAM_IKERNEL); + dcplb_add(extern_memory, SDRAM_DKERNEL); + extern_memory += CPLB_PAGE_SIZE; + ++i; +#endif + + while (i < 16 && extern_memory < (CFG_MONITOR_BASE & CPLB_PAGE_MASK)) { + icplb_add(extern_memory, SDRAM_IGENERIC); + dcplb_add(extern_memory, SDRAM_DGENERIC); + extern_memory += CPLB_PAGE_SIZE; + ++i; + } + while (i < 16) { + icplb_add(0, 0); + dcplb_add(0, 0); + ++i; + } }
/* @@ -227,14 +248,37 @@ void init_cplbtables(void) * "continue" and != 0 means "fatal error, hang the system". */
+extern int exception_init(void); +extern int irq_init(void); +extern int rtc_init(void); +extern int timer_init(void); + void board_init_f(ulong bootflag) { ulong addr; bd_t *bd; - int i;
+#ifdef CONFIG_BOARD_EARLY_INIT_F + serial_early_puts("Board early init flash\n"); + board_early_init_f(); +#endif + + serial_early_puts("Init CPLB tables\n"); init_cplbtables();
+ serial_early_puts("Exceptions setup\n"); + exception_init(); + +#ifndef CONFIG_ICACHE_OFF + serial_early_puts("Turn on ICACHE\n"); + icache_enable(); +#endif +#ifndef CONFIG_DCACHE_OFF + serial_early_puts("Turn on DCACHE\n"); + dcache_enable(); +#endif + + serial_early_puts("Init global data\n"); gd = (gd_t *) (CFG_GBL_DATA_ADDR); memset((void *)gd, 0, sizeof(gd_t));
@@ -247,41 +291,44 @@ void board_init_f(ulong bootflag) gd->bd = bd; memset((void *)bd, 0, sizeof(bd_t));
+ bd->bi_r_version = version_string; + bd->bi_cpu = MK_STR(CONFIG_BFIN_CPU); + bd->bi_board_name = BFIN_BOARD_NAME; + bd->bi_vco = get_vco(); + bd->bi_cclk = get_cclk(); + bd->bi_sclk = get_sclk(); + /* Initialize */ + serial_early_puts("IRQ init\n"); irq_init(); - env_init(); /* initialize environment */ - init_baudrate(); /* initialze baudrate settings */ - serial_init(); /* serial communications setup */ + serial_early_puts("Environment init\n"); + env_init(); + serial_early_puts("Baudrate init\n"); + init_baudrate(); + serial_early_puts("Serial init\n"); + serial_init(); + serial_early_puts("Console init flash\n"); console_init_f(); -#ifdef CONFIG_ICACHE_ON - icache_enable(); -#endif -#ifdef CONFIG_DCACHE_ON - dcache_enable(); -#endif - display_banner(); /* say that we are here */ - - for (i = 0; i < page_descriptor_table_size; i++) { - debug - ("data (%02i)= 0x%08x : 0x%08x intr = 0x%08x : 0x%08x\n", - i, dcplb_table[i][0], dcplb_table[i][1], icplb_table[i][0], - icplb_table[i][1]); - } + serial_early_puts("End of early debugging\n"); + display_banner();
checkboard(); -#if defined(CONFIG_RTC_BF533) && defined(CONFIG_CMD_DATE) +#if defined(CONFIG_RTC_BFIN) && defined(CONFIG_CMD_DATE) rtc_init(); #endif timer_init(); + printf("Clock: VCO: %lu MHz, Core: %lu MHz, System: %lu MHz\n", get_vco() / 1000000, get_cclk() / 1000000, get_sclk() / 1000000); - printf("SDRAM: "); + + printf("RAM: "); print_size(initdram(0), "\n"); #if defined(CONFIG_POST) post_init_f(); post_bootmode_init(); post_run(NULL, POST_ROM | post_bootmode_get(0)); #endif + board_init_r((gd_t *) gd, 0x20000010); }
@@ -297,11 +344,9 @@ static int init_func_i2c(void)
void board_init_r(gd_t * id, ulong dest_addr) { - ulong size; extern void malloc_bin_reloc(void); - char *s, *e; + char *s; bd_t *bd; - int i; gd = id; gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ bd = gd->bd; @@ -314,8 +359,10 @@ void board_init_r(gd_t * id, ulong dest_addr) #if !defined(CFG_NO_FLASH) /* There are some other pointer constants we must deal with */ /* configure available FLASH banks */ - size = flash_init(); - display_flash_config(size); + extern flash_info_t flash_info[]; + ulong size = flash_init(); + puts("Flash: "); + print_size(size, "\n"); flash_protect(FLAG_PROTECT_SET, CFG_FLASH_BASE, CFG_FLASH_BASE + 0x1ffff, &flash_info[0]); bd->bi_flashstart = CFG_FLASH_BASE; @@ -340,16 +387,34 @@ void board_init_r(gd_t * id, ulong dest_addr) /* relocate environment function pointers etc. */ env_relocate();
+#ifdef CONFIG_CMD_NET /* board MAC address */ s = getenv("ethaddr"); - for (i = 0; i < 6; ++i) { - bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0; - if (s) + if (s == NULL) { +# ifndef CONFIG_ETHADDR +# if 0 + if (!board_get_enetaddr(bd->bi_enetaddr)) { + char nid[20]; + sprintf(nid, "%02X:%02X:%02X:%02X:%02X:%02X", + bd->bi_enetaddr[0], bd->bi_enetaddr[1], + bd->bi_enetaddr[2], bd->bi_enetaddr[3], + bd->bi_enetaddr[4], bd->bi_enetaddr[5]); + setenv("ethaddr", nid); + } +# endif +# endif + } else { + int i; + char *e; + for (i = 0; i < 6; ++i) { + bd->bi_enetaddr[i] = simple_strtoul(s, &e, 16); s = (*e) ? e + 1 : e; + } }
/* IP Address */ bd->bi_ip_addr = getenv_IPaddr("ipaddr"); +#endif
/* Initialize devices */ devices_init(); @@ -359,16 +424,14 @@ void board_init_r(gd_t * id, ulong dest_addr) console_init_r();
/* Initialize from environment */ - if ((s = getenv("loadaddr")) != NULL) { + if ((s = getenv("loadaddr")) != NULL) load_addr = simple_strtoul(s, NULL, 16); - } -#if defined(CONFIG_CMD_NET) - if ((s = getenv("bootfile")) != NULL) { +#ifdef CONFIG_CMD_NET + if ((s = getenv("bootfile")) != NULL) copy_filename(BootFile, s, sizeof(BootFile)); - } #endif
-#if defined(CONFIG_CMD_NAND) +#ifdef CONFIG_CMD_NAND puts("NAND: "); nand_init(); /* go init the NAND */ #endif @@ -379,33 +442,19 @@ void board_init_r(gd_t * id, ulong dest_addr) #endif
#ifdef CONFIG_CMD_NET - printf("Net: "); - eth_initialize(bd); -#endif - -#ifdef CONFIG_DRIVER_SMC91111 -#ifdef SHARED_RESOURCES - /* Switch to Ethernet */ - swap_to(ETHERNET); + printf("Net: "); + eth_initialize(gd->bd); + if (getenv("ethaddr")) + printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", + bd->bi_enetaddr[0], bd->bi_enetaddr[1], bd->bi_enetaddr[2], + bd->bi_enetaddr[3], bd->bi_enetaddr[4], bd->bi_enetaddr[5]); #endif - if ((SMC_inw(BANK_SELECT) & UPPER_BYTE_MASK) != SMC_IDENT) { - printf("ERROR: Can't find SMC91111 at address %x\n", - SMC_BASE_ADDRESS); - } else { - printf("Net: SMC91111 at 0x%08X\n", SMC_BASE_ADDRESS); - }
-#ifdef SHARED_RESOURCES - swap_to(FLASH); -#endif -#endif #if defined(CONFIG_SOFT_I2C) || defined(CONFIG_HARD_I2C) init_func_i2c(); #endif
-#ifdef DEBUG display_global_data(); -#endif
#if defined(CONFIG_POST) if (post_flag) @@ -413,13 +462,16 @@ void board_init_r(gd_t * id, ulong dest_addr) #endif
/* main_loop() can return to retry autoboot, if so just run it again. */ - for (;;) { + for (;;) main_loop(); - } }
void hang(void) { puts("### ERROR ### Please RESET the board ###\n"); - for (;;) ; + while (1) + /* If a JTAG emulator is hooked up, we'll automatically trigger + * a breakpoint in it. If one isn't, this is just a NOP. + */ + asm("emuexcpt;"); }

This adds a new CONFIG_DEBUG_SERIAL define so that people can figure out if/when their serial port is hitting errors.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- cpu/blackfin/serial.c | 57 +++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 48 insertions(+), 9 deletions(-)
diff --git a/cpu/blackfin/serial.c b/cpu/blackfin/serial.c index 0dfee51..f538bba 100644 --- a/cpu/blackfin/serial.c +++ b/cpu/blackfin/serial.c @@ -35,6 +35,29 @@
#include "serial.h"
+#ifdef CONFIG_DEBUG_SERIAL +uint16_t cached_lsr[256]; +uint16_t cached_rbr[256]; +size_t cache_count; +#endif + +/* The LSR is read-to-clear on some parts, so we have to make sure status + * bits aren't inadvertently lost when doing various tests. + */ +static uint16_t uart_lsr_save; +static uint16_t uart_lsr_read(void) +{ + uint16_t lsr = *pUART_LSR; + uart_lsr_save |= (lsr & (OE|PE|FE|BI)); + return lsr | uart_lsr_save; +} +/* Just do the clear for everyone since it can't hurt. */ +static void uart_lsr_clear(void) +{ + uart_lsr_save = 0; + *pUART_LSR |= -1; +} + /* Symbol for our assembly to call. */ void serial_set_baud(uint32_t baud) { @@ -61,6 +84,12 @@ int serial_init(void) { serial_initialize(); serial_setbrg(); + uart_lsr_clear(); +#ifdef CONFIG_DEBUG_SERIAL + cache_count = 0; + memset(cached_lsr, 0x00, sizeof(cached_lsr)); + memset(cached_rbr, 0x00, sizeof(cached_rbr)); +#endif return 0; }
@@ -73,7 +102,7 @@ void serial_putc(const char c) WATCHDOG_RESET();
/* wait for the hardware fifo to clear up */ - while (!(*pUART_LSR & THRE)) + while (!(uart_lsr_read() & THRE)) continue;
/* queue the character for transmission */ @@ -83,14 +112,14 @@ void serial_putc(const char c) WATCHDOG_RESET();
/* wait for the byte to be shifted over the line */ - while (!(*pUART_LSR & TEMT)) + while (!(uart_lsr_read() & TEMT)) continue; }
int serial_tstc(void) { WATCHDOG_RESET(); - return (*pUART_LSR & DR) ? 1 : 0; + return (uart_lsr_read() & DR) ? 1 : 0; }
int serial_getc(void) @@ -102,15 +131,25 @@ int serial_getc(void) continue;
/* clear the status and grab the new byte */ - uart_lsr_val = *pUART_LSR; + uart_lsr_val = uart_lsr_read(); uart_rbr_val = *pUART_RBR;
+#ifdef CONFIG_DEBUG_SERIAL + cached_lsr[cache_count] = uart_lsr_val; + cached_rbr[cache_count] = uart_rbr_val; + cache_count = (cache_count + 1) % ARRAY_SIZE(cached_lsr); +#endif + if (uart_lsr_val & (OE|PE|FE|BI)) { - /* Some parts are read-to-clear while others are - * write-to-clear. Just do the write for everyone - * since it cant hurt (other than code size). - */ - *pUART_LSR = (OE|PE|FE|BI); +#ifdef CONFIG_DEBUG_SERIAL + printf("\n[SERIAL ERROR]\n"); + do { + --cache_count; + printf("\t%3i: RBR=0x%02x LSR=0x%02x\n", cache_count, + cached_rbr[cache_count], cached_lsr[cache_count]); + } while (cache_count > 0); +#endif + uart_lsr_clear(); return -1; }

On 03:09 Mon 25 Feb , Mike Frysinger wrote:
This punts the old spi flash driver for a new/generalized one.
Signed-off-by: Mike Frysinger vapier@gentoo.org
As I said before, it will be good to merge the SPI flash to the common drivers/mtd and allow it to be usable on other architectures.
Best Regards, J.

On Tuesday 26 February 2008, Jean-Christophe PLAGNIOL-VILLARD wrote:
On 03:09 Mon 25 Feb , Mike Frysinger wrote:
This punts the old spi flash driver for a new/generalized one.
Signed-off-by: Mike Frysinger vapier@gentoo.org
As I said before, it will be good to merge the SPI flash to the common drivers/mtd and allow it to be usable on other architectures.
and as i said before, that's already being done and is not a reason to hold up working code. -mike

In message 200802261609.13208.vapier@gentoo.org you wrote:
and as i said before, that's already being done and is not a reason to hold up working code.
Well, you gotta wait for the next merge window anyway, so maybe we could skip this temporay version and use the new one right from the beginning?
Best regards,
Wolfgang Denk

On Thursday 28 February 2008, Wolfgang Denk wrote:
In message 200802261609.13208.vapier@gentoo.org you wrote:
and as i said before, that's already being done and is not a reason to hold up working code.
Well, you gotta wait for the next merge window anyway, so maybe we could skip this temporay version and use the new one right from the beginning?
no, because it isnt done, and it's going to be a while in the making. it relies on the SPI pieces that arent in and it needs sector protection added. -mike
participants (3)
-
Jean-Christophe PLAGNIOL-VILLARD
-
Mike Frysinger
-
Wolfgang Denk