[U-Boot] [PATCH 00/40] Blackfin updates for 2009.03

Nothing terribly interesting here. Normal smatterings of bug fixes and minor updates as we fold the external Blackfin fork back into mainline. Everything can be found in the "next" branch of the Blackfin git tree: git://www.denx.de/git/u-boot-blackfin.git next
Mike Frysinger (40): Blackfin: add defines to describe active bootrom behavior Blackfin: add bit defines for DDR parts Blackfin: convert CMD_LINE_ADDR to CONFIG_LINUX_CMDLINE_{ADDR,SIZE} Blackfin: set more sane default board config values Blackfin: rename bootm.c to boot.c Blackfin: abort dma_memcpy() for L1 scratchpad Blackfin: split cache handling out of dma_memcpy() Blackfin: minimize time cache is turned off when replacing cplb entries Blackfin: pass --bmode/--initcode when creating ldr Blackfin: dont generate ldrs with --force Blackfin: fix dcache handling when doing dma memcpy's Blackfin: bfin_mac: update port muxing Blackfin: do not init i2c in Blackfin board init Blackfin: implement general support for CONFIG_STATUS_LED Blackfin: respect/check CONFIG_SYS_GBL_DATA_SIZE Blackfin: respect CONFIG_SYS_MONITOR_LEN for default flash protection Blackfin: overhaul i2c driver Blackfin: bf533-ezkit: shuffle flash defines a little Blackfin: drop dead/wrong debug code in initdram() Blackfin: bf537-stamp nand: fix more style errors in previous commit Blackfin: tighten up post memory coding style Blackfin: resurrect BF533-STAMP video splash driver Blackfin: punt unused BF533-STAMP definitions Blackfin: set default boot SPI CS for BF538/BF539 Blackfin: use common memcpy routine during init Blackfin: respect CONFIG_CLKIN_HALF Blackfin: add portmuxing for UARTs on the BF51x Blackfin: just set SP register directly during init Blackfin: clarify relocation comment during init Blackfin: pass RETX to Linux Blackfin: handle new anomalies with reset Blackfin: support console-over-JTAG Blackfin: allow serial console to be disabled Blackfin: update on-chip ROM API Blackfin: implement real write support for OTP Blackfin: bootldr: implement BF53x/BF56x LDR loader smc91111_eeprom: move board-specific init into SMC91111_EEPROM_INIT() Blackfin: bf533-stamp: rewrite resource swap logic Blackfin: convert old boards to use COBJS-y Makefile style Blackfin: fixup misc warnings such as printf's and missing casts
Makefile | 2 +- blackfin_config.mk | 4 + board/bf533-ezkit/Makefile | 8 +- board/bf533-ezkit/bf533-ezkit.c | 23 +- board/bf533-ezkit/flash-defines.h | 4 +- board/bf533-ezkit/flash.c | 10 +- board/bf533-stamp/Makefile | 12 +- board/bf533-stamp/bf533-stamp.c | 50 +-- board/bf533-stamp/bf533-stamp.h | 3 - board/bf533-stamp/video.c | 167 +++++++++ board/bf533-stamp/video.h | 25 ++ board/bf537-stamp/Makefile | 10 +- board/bf537-stamp/bf537-stamp.c | 14 +- board/bf537-stamp/nand.c | 9 +- board/bf537-stamp/post-memory.c | 23 +- board/bf537-stamp/spi_flash.c | 8 +- board/bf561-ezkit/Makefile | 8 +- board/bf561-ezkit/bf561-ezkit.c | 14 +- common/cmd_bootldr.c | 135 +++++++- common/cmd_cplbinfo.c | 4 +- common/cmd_otp.c | 163 +++++++--- common/devices.c | 3 + cpu/blackfin/Makefile | 9 +- cpu/blackfin/cache.S | 4 +- cpu/blackfin/cpu.c | 6 + cpu/blackfin/i2c.c | 428 ----------------------- cpu/blackfin/initcode.c | 2 +- cpu/blackfin/jtag-console.c | 125 +++++++ cpu/blackfin/reset.c | 20 +- cpu/blackfin/serial.c | 4 + cpu/blackfin/serial.h | 15 +- cpu/blackfin/start.S | 41 +-- cpu/blackfin/traps.c | 52 +-- drivers/i2c/Makefile | 1 + drivers/i2c/bfin-twi_i2c.c | 285 +++++++++++++++ drivers/net/bfin_mac.c | 47 ++- examples/smc91111_eeprom.c | 15 +- include/asm-blackfin/blackfin-config-post.h | 84 ++++- include/asm-blackfin/blackfin_local.h | 2 +- include/asm-blackfin/mach-common/bits/bootrom.h | 72 +++-- include/asm-blackfin/mach-common/bits/ebiu.h | 21 +- include/asm-blackfin/mach-common/bits/otp.h | 21 +- include/configs/bf533-ezkit.h | 2 +- include/configs/bf533-stamp.h | 2 +- include/configs/bf537-stamp.h | 43 +-- include/devices.h | 3 + include/status_led.h | 3 + lib_blackfin/Makefile | 2 +- lib_blackfin/board.c | 37 +- lib_blackfin/boot.c | 63 ++++ lib_blackfin/bootm.c | 56 --- lib_blackfin/string.c | 45 ++- 52 files changed, 1326 insertions(+), 883 deletions(-) create mode 100644 board/bf533-stamp/video.c create mode 100644 board/bf533-stamp/video.h delete mode 100644 cpu/blackfin/i2c.c create mode 100644 cpu/blackfin/jtag-console.c create mode 100644 drivers/i2c/bfin-twi_i2c.c create mode 100644 lib_blackfin/boot.c delete mode 100644 lib_blackfin/bootm.c

Signed-off-by: Mike Frysinger vapier@gentoo.org --- include/asm-blackfin/mach-common/bits/bootrom.h | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/include/asm-blackfin/mach-common/bits/bootrom.h b/include/asm-blackfin/mach-common/bits/bootrom.h index 6cdaa4f..bf661f0 100644 --- a/include/asm-blackfin/mach-common/bits/bootrom.h +++ b/include/asm-blackfin/mach-common/bits/bootrom.h @@ -88,6 +88,8 @@ #define _BOOTROM_REV 0xEF000040 #define _BOOTROM_SESR 0xEF001000
+#define BOOTROM_FOLLOWS_C_ABI 1 + #define BOOTROM_CAPS_ADI_BOOT_STRUCTS 1
/* Not available on initial BF54x or BF52x */ @@ -100,6 +102,9 @@
#endif
+#ifndef BOOTROM_FOLLOWS_C_ABI +#define BOOTROM_FOLLOWS_C_ABI 0 +#endif #ifndef BOOTROM_CAPS_ADI_BOOT_STRUCTS #define BOOTROM_CAPS_ADI_BOOT_STRUCTS 0 #endif @@ -109,6 +114,12 @@
#ifndef __ASSEMBLY__
+#if BOOTROM_FOLLOWS_C_ABI +# define BOOTROM_CALLED_FUNC_ATTR +#else +# define BOOTROM_CALLED_FUNC_ATTR __attribute__((saveall)) +#endif + /* Structures for the syscontrol() function */ typedef struct ADI_SYSCTRL_VALUES { uint16_t uwVrCtl;

Signed-off-by: Mike Frysinger vapier@gentoo.org --- include/asm-blackfin/mach-common/bits/ebiu.h | 21 ++++++++++++++++++++- 1 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/include/asm-blackfin/mach-common/bits/ebiu.h b/include/asm-blackfin/mach-common/bits/ebiu.h index ab530ad..af456fb 100644 --- a/include/asm-blackfin/mach-common/bits/ebiu.h +++ b/include/asm-blackfin/mach-common/bits/ebiu.h @@ -410,12 +410,31 @@
/* EBIU_SDSTAT Masks */ #define SDCI 0x0001 /* SDRAM controller is idle */ -#define SDSRA 0x0002 /* SDRAM SDRAM self refresh is active */ +#define SDSRA 0x0002 /* SDRAM self refresh is active */ #define SDPUA 0x0004 /* SDRAM power up active */ #define SDRS 0x0008 /* SDRAM is in reset state */ #define SDEASE 0x0010 /* SDRAM EAB sticky error status - W1C */ #define BGSTAT 0x0020 /* Bus granted */
+/* Only available on DDR based-parts */ +#else + +/* EBIU_ERRMST Masks */ +#define DEB0_ERROR 0x0001 /* DEB0 access on reserved memory */ +#define DEB1_ERROR 0x0002 /* DEB1 access on reserved memory */ +#define DEB2_ERROR 0x0004 /* DEB2 (USB) access on reserved memory */ +#define CORE_ERROR 0x0008 /* Core access on reserved memory */ +#define DEB0_MERROR 0x0010 /* DEB0 access on reserved memory and DEB0_ERROR is set */ +#define DEB1_MERROR 0x0020 /* DEB1 access on reserved memory and DEB1_ERROR is set */ +#define DEB2_MERROR 0x0040 /* DEB2 access on reserved memory and DEB2_ERROR is set */ +#define CORE_MERROR 0x0080 /* Core access on reserved memory and CORE_ERROR is set */ + +/* EBIU_RSTCTL Masks */ +#define DDR_SRESET 0x0001 /* Reset Control to DDR Controller */ +#define SRREQ 0x0008 /* Self Refresh Request */ +#define SRACK 0x0010 /* Self Refresh Request Acknowledgement */ +#define MDDRENABLE 0x0020 /* Mobile DDR Enable */ + #endif /* EBIU_SDGCTL */
#endif

Signed-off-by: Mike Frysinger vapier@gentoo.org --- include/asm-blackfin/blackfin-config-post.h | 7 +++++-- lib_blackfin/bootm.c | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/include/asm-blackfin/blackfin-config-post.h b/include/asm-blackfin/blackfin-config-post.h index 0ab68ac..936001a 100644 --- a/include/asm-blackfin/blackfin-config-post.h +++ b/include/asm-blackfin/blackfin-config-post.h @@ -65,8 +65,11 @@ #endif
/* Using L1 scratch pad makes sense for everyone by default. */ -#ifndef CMD_LINE_ADDR -# define CMD_LINE_ADDR L1_SRAM_SCRATCH +#ifndef CONFIG_LINUX_CMDLINE_ADDR +# define CONFIG_LINUX_CMDLINE_ADDR L1_SRAM_SCRATCH +#endif +#ifndef CONFIG_LINUX_CMDLINE_SIZE +# define CONFIG_LINUX_CMDLINE_SIZE L1_SRAM_SCRATCH_SIZE #endif
#endif diff --git a/lib_blackfin/bootm.c b/lib_blackfin/bootm.c index 195eb9c..2954ce6 100644 --- a/lib_blackfin/bootm.c +++ b/lib_blackfin/bootm.c @@ -20,14 +20,14 @@ extern void swap_to(int device_id);
static char *make_command_line(void) { - char *dest = (char *)CMD_LINE_ADDR; + char *dest = (char *)CONFIG_LINUX_CMDLINE_ADDR; char *bootargs = getenv("bootargs");
if (bootargs == NULL) return NULL;
- strncpy(dest, bootargs, 0x1000); - dest[0xfff] = 0; + strncpy(dest, bootargs, CONFIG_LINUX_CMDLINE_SIZE); + dest[CONFIG_LINUX_CMDLINE_SIZE - 1] = 0; return dest; }

Signed-off-by: Mike Frysinger vapier@gentoo.org --- include/asm-blackfin/blackfin-config-post.h | 77 ++++++++++++++++++++++++-- 1 files changed, 71 insertions(+), 6 deletions(-)
diff --git a/include/asm-blackfin/blackfin-config-post.h b/include/asm-blackfin/blackfin-config-post.h index 936001a..21abd72 100644 --- a/include/asm-blackfin/blackfin-config-post.h +++ b/include/asm-blackfin/blackfin-config-post.h @@ -1,7 +1,7 @@ /* * blackfin-config-post.h - setup common defines for Blackfin boards based on config.h * - * Copyright (c) 2007 Analog Devices Inc. + * Copyright (c) 2007-2008 Analog Devices Inc. * * Licensed under the GPL-2 or later. */ @@ -9,11 +9,6 @@ #ifndef __ASM_BLACKFIN_CONFIG_POST_H__ #define __ASM_BLACKFIN_CONFIG_POST_H__
-/* Check to make sure everything fits in external RAM */ -#if ((CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) > CONFIG_SYS_MAX_RAM_SIZE) -# error Memory Map does not fit into configuration -#endif - /* Sanity check CONFIG_BFIN_CPU */ #ifndef CONFIG_BFIN_CPU # error CONFIG_BFIN_CPU: your board config needs to define this @@ -72,4 +67,74 @@ # define CONFIG_LINUX_CMDLINE_SIZE L1_SRAM_SCRATCH_SIZE #endif
+/* Default/common Blackfin memory layout */ +#ifndef CONFIG_SYS_SDRAM_BASE +# define CONFIG_SYS_SDRAM_BASE 0 +#endif +#ifndef CONFIG_SYS_MAX_RAM_SIZE +# define CONFIG_SYS_MAX_RAM_SIZE (CONFIG_MEM_SIZE * 1024 * 1024) +#endif +#ifndef CONFIG_SYS_MONITOR_BASE +# define CONFIG_SYS_MONITOR_BASE (CONFIG_SYS_MAX_RAM_SIZE - CONFIG_SYS_MONITOR_LEN) +#endif +#ifndef CONFIG_SYS_MALLOC_BASE +# define CONFIG_SYS_MALLOC_BASE (CONFIG_SYS_MONITOR_BASE - CONFIG_SYS_MALLOC_LEN) +#endif +#ifndef CONFIG_SYS_GBL_DATA_SIZE +# define CONFIG_SYS_GBL_DATA_SIZE (128) +#endif +#ifndef CONFIG_SYS_GBL_DATA_ADDR +# define CONFIG_SYS_GBL_DATA_ADDR (CONFIG_SYS_MALLOC_BASE - CONFIG_SYS_GBL_DATA_SIZE) +#endif +#ifndef CONFIG_STACKBASE +# define CONFIG_STACKBASE (CONFIG_SYS_GBL_DATA_ADDR - 4) +#endif +#ifndef CONFIG_SYS_MEMTEST_START +# define CONFIG_SYS_MEMTEST_START 0 +#endif +#ifndef CONFIG_SYS_MEMTEST_END +# define CONFIG_SYS_MEMTEST_END (CONFIG_STACKBASE - 8192 + 4) +#endif + +/* Check to make sure everything fits in external RAM */ +#if ((CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) > CONFIG_SYS_MAX_RAM_SIZE) +# error Memory Map does not fit into configuration +#endif + +/* Default/common Blackfin environment settings */ +#ifndef CONFIG_LOADADDR +# define CONFIG_LOADADDR 0x1000000 +#endif +#ifndef CONFIG_SYS_LOAD_ADDR +# define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR +#endif +#ifndef CONFIG_SYS_BOOTM_LEN +# define CONFIG_SYS_BOOTM_LEN 0x4000000 +#endif +#ifndef CONFIG_SYS_PROMPT +# define CONFIG_SYS_PROMPT "bfin> " +#endif +#ifndef CONFIG_SYS_CBSIZE +# ifdef CONFIG_CMD_KGDB +# define CONFIG_SYS_CBSIZE 1024 +# else +# define CONFIG_SYS_CBSIZE 256 +# endif +#endif +#ifndef CONFIG_SYS_BARGSIZE +# define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +#endif +#ifndef CONFIG_SYS_PBSIZE +# define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +#endif +#ifndef CONFIG_SYS_MAXARGS +# define CONFIG_SYS_MAXARGS 16 +#endif +#ifndef CONFIG_SYS_HZ +# define CONFIG_SYS_HZ 1000 +#endif +#ifndef CONFIG_SYS_BAUDRATE_TABLE +# define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } +#endif + #endif

The boot file contains functions for more than just "bootm", so rename it accordingly.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- lib_blackfin/Makefile | 2 +- lib_blackfin/boot.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ lib_blackfin/bootm.c | 56 ------------------------------------------------- 3 files changed, 57 insertions(+), 57 deletions(-) create mode 100644 lib_blackfin/boot.c delete mode 100644 lib_blackfin/bootm.c
diff --git a/lib_blackfin/Makefile b/lib_blackfin/Makefile index 3f69770..fee0fda 100644 --- a/lib_blackfin/Makefile +++ b/lib_blackfin/Makefile @@ -37,7 +37,7 @@ SOBJS-y += memmove.o SOBJS-y += memset.o
COBJS-y += board.o -COBJS-y += bootm.o +COBJS-y += boot.o COBJS-y += cache.o COBJS-y += muldi3.o COBJS-y += post.o diff --git a/lib_blackfin/boot.c b/lib_blackfin/boot.c new file mode 100644 index 0000000..47e27de --- /dev/null +++ b/lib_blackfin/boot.c @@ -0,0 +1,56 @@ +/* + * U-boot - boot.c - misc boot helper 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 <image.h> +#include <asm/blackfin.h> + +#ifdef SHARED_RESOURCES +extern void swap_to(int device_id); +#endif + +static char *make_command_line(void) +{ + char *dest = (char *)CONFIG_LINUX_CMDLINE_ADDR; + char *bootargs = getenv("bootargs"); + + if (bootargs == NULL) + return NULL; + + strncpy(dest, bootargs, CONFIG_LINUX_CMDLINE_SIZE); + dest[CONFIG_LINUX_CMDLINE_SIZE - 1] = 0; + return dest; +} + +int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +{ + int (*appl) (char *cmdline); + char *cmdline; + + if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) + return 1; + +#ifdef SHARED_RESOURCES + swap_to(FLASH); +#endif + + appl = (int (*)(char *))images->ep; + + printf("Starting Kernel at = %x\n", appl); + cmdline = make_command_line(); + icache_disable(); + dcache_disable(); + (*appl) (cmdline); + /* does not return */ + + return 1; +} diff --git a/lib_blackfin/bootm.c b/lib_blackfin/bootm.c deleted file mode 100644 index 2954ce6..0000000 --- a/lib_blackfin/bootm.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * U-boot - bootm.c - misc boot helper 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 <image.h> -#include <asm/blackfin.h> - -#ifdef SHARED_RESOURCES -extern void swap_to(int device_id); -#endif - -static char *make_command_line(void) -{ - char *dest = (char *)CONFIG_LINUX_CMDLINE_ADDR; - char *bootargs = getenv("bootargs"); - - if (bootargs == NULL) - return NULL; - - strncpy(dest, bootargs, CONFIG_LINUX_CMDLINE_SIZE); - dest[CONFIG_LINUX_CMDLINE_SIZE - 1] = 0; - return dest; -} - -int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) -{ - int (*appl) (char *cmdline); - char *cmdline; - - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; - -#ifdef SHARED_RESOURCES - swap_to(FLASH); -#endif - - appl = (int (*)(char *))images->ep; - - printf("Starting Kernel at = %x\n", appl); - cmdline = make_command_line(); - icache_disable(); - dcache_disable(); - (*appl) (cmdline); - /* does not return */ - - return 1; -}

Signed-off-by: Mike Frysinger vapier@gentoo.org --- lib_blackfin/string.c | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/lib_blackfin/string.c b/lib_blackfin/string.c index 6887c93..ab71285 100644 --- a/lib_blackfin/string.c +++ b/lib_blackfin/string.c @@ -1,7 +1,7 @@ /* * U-boot - string.c Contains library 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. @@ -130,8 +130,19 @@ int strncmp(const char *cs, const char *ct, size_t count) # define bfin_write_MDMA_D0_IRQ_STATUS bfin_write_MDMA1_D0_IRQ_STATUS # define bfin_read_MDMA_D0_IRQ_STATUS bfin_read_MDMA1_D0_IRQ_STATUS #endif +/* This version misbehaves for count values of 0 and 2^16+. + * Perhaps we should detect that ? Nowhere do we actually + * use dma memcpy for those types of lengths though ... + */ static void *dma_memcpy(void *dst, const void *src, size_t count) { + /* Scratchpad cannot be a DMA source or destination */ + if (((unsigned long)src >= L1_SRAM_SCRATCH && + (unsigned long)src < L1_SRAM_SCRATCH_END) || + ((unsigned long)dst >= L1_SRAM_SCRATCH && + (unsigned long)dst < L1_SRAM_SCRATCH_END)) + hang(); + if (dcache_status()) blackfin_dcache_flush_range(src, src + count);

Creating a new dma_memcpy() function that skips all cache checks allows us to use the function in very early init where the cache is not yet setup.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- lib_blackfin/string.c | 25 +++++++++++++++++-------- 1 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/lib_blackfin/string.c b/lib_blackfin/string.c index ab71285..2a56910 100644 --- a/lib_blackfin/string.c +++ b/lib_blackfin/string.c @@ -134,7 +134,7 @@ int strncmp(const char *cs, const char *ct, size_t count) * Perhaps we should detect that ? Nowhere do we actually * use dma memcpy for those types of lengths though ... */ -static void *dma_memcpy(void *dst, const void *src, size_t count) +void dma_memcpy_nocache(void *dst, const void *src, size_t count) { /* Scratchpad cannot be a DMA source or destination */ if (((unsigned long)src >= L1_SRAM_SCRATCH && @@ -143,10 +143,9 @@ static void *dma_memcpy(void *dst, const void *src, size_t count) (unsigned long)dst < L1_SRAM_SCRATCH_END)) hang();
- if (dcache_status()) - blackfin_dcache_flush_range(src, src + count); - - bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); + bfin_write_MDMA_S0_CONFIG(0); + bfin_write_MDMA_D0_CONFIG(0); + bfin_write_MDMA_D0_IRQ_STATUS(DMA_RUN | DMA_DONE | DMA_ERR);
/* Copy sram functions from sdram to sram */ /* Setup destination start address */ @@ -165,13 +164,23 @@ static void *dma_memcpy(void *dst, const void *src, size_t count)
/* Enable source DMA */ bfin_write_MDMA_S0_CONFIG(DMAEN); - SSYNC();
bfin_write_MDMA_D0_CONFIG(WNR | DMAEN); + SSYNC();
while (bfin_read_MDMA_D0_IRQ_STATUS() & DMA_RUN) - bfin_write_MDMA_D0_IRQ_STATUS(bfin_read_MDMA_D0_IRQ_STATUS() | DMA_DONE | DMA_ERR); - bfin_write_MDMA_D0_IRQ_STATUS(bfin_read_MDMA_D0_IRQ_STATUS() | DMA_DONE | DMA_ERR); + continue; + + bfin_write_MDMA_D0_IRQ_STATUS(bfin_read_MDMA_D0_IRQ_STATUS() | DMA_RUN | DMA_DONE | DMA_ERR); + bfin_write_MDMA_D0_CONFIG(0); + bfin_write_MDMA_S0_CONFIG(0); +} +void *dma_memcpy(void *dst, const void *src, size_t count) +{ + if (dcache_status()) + blackfin_dcache_flush_range(src, src + count); + + dma_memcpy_nocache(dst, src, count);
if (icache_status()) blackfin_icache_flush_range(dst, dst + count);

Signed-off-by: Mike Frysinger vapier@gentoo.org --- cpu/blackfin/traps.c | 31 +++++++++---------------------- 1 files changed, 9 insertions(+), 22 deletions(-)
diff --git a/cpu/blackfin/traps.c b/cpu/blackfin/traps.c index d17c0a1..e72b347 100644 --- a/cpu/blackfin/traps.c +++ b/cpu/blackfin/traps.c @@ -117,17 +117,6 @@ void trap_c(struct pt_regs *regs) 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; @@ -149,8 +138,17 @@ void trap_c(struct pt_regs *regs)
debug("evicting entry %i: 0x%p 0x%08X\n", i, *CPLB_ADDR, *CPLB_DATA); last_evicted = i + 1; + + /* need to turn off cplbs whenever we muck with the cplb table */ +#if ENDCPLB != ENICPLB +# error cplb enable bit violates my sanity +#endif + uint32_t mem_control = (data ? DMEM_CONTROL : IMEM_CONTROL); + bfin_write32(mem_control, bfin_read32(mem_control) & ~ENDCPLB); *CPLB_ADDR = new_cplb_addr; *CPLB_DATA = new_cplb_data; + bfin_write32(mem_control, bfin_read32(mem_control) | ENDCPLB); + SSYNC();
/* dump current table for debugging purposes */ CPLB_ADDR = CPLB_ADDR_BASE; @@ -158,17 +156,6 @@ void trap_c(struct pt_regs *regs) 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; }

Signed-off-by: Mike Frysinger vapier@gentoo.org --- blackfin_config.mk | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/blackfin_config.mk b/blackfin_config.mk index c8be75e..7bde449 100644 --- a/blackfin_config.mk +++ b/blackfin_config.mk @@ -33,7 +33,11 @@ endif
SYM_PREFIX = _
+LDR_FLAGS += --bmode $(subst BFIN_BOOT_,,$(CONFIG_BFIN_BOOT_MODE)) LDR_FLAGS += --use-vmas +ifneq ($(CONFIG_BFIN_BOOT_MODE),BFIN_BOOT_BYPASS) +LDR_FLAGS += --initcode $(obj)cpu/$(CPU)/initcode.o +endif ifneq (,$(findstring s,$(MAKEFLAGS))) LDR_FLAGS += --quiet endif

Signed-off-by: Mike Frysinger vapier@gentoo.org --- Makefile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/Makefile b/Makefile index d533564..50e51a5 100644 --- a/Makefile +++ b/Makefile @@ -317,7 +317,7 @@ $(obj)u-boot.bin: $(obj)u-boot $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
$(obj)u-boot.ldr: $(obj)u-boot - $(LDR) -T $(CONFIG_BFIN_CPU) -f -c $@ $< $(LDR_FLAGS) + $(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS)
$(obj)u-boot.ldr.hex: $(obj)u-boot.ldr $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ -I binary

Our dcache invalidate function doesn't just invalidate, it also flushes. So rename the function accordingly and fix the dma_memcpy() function so it doesn't inadvertently corrupt the data destination.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- cpu/blackfin/cache.S | 4 ++-- include/asm-blackfin/blackfin_local.h | 2 +- lib_blackfin/string.c | 11 +++++++---- 3 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/cpu/blackfin/cache.S b/cpu/blackfin/cache.S index 51bdb30..9facadf 100644 --- a/cpu/blackfin/cache.S +++ b/cpu/blackfin/cache.S @@ -39,7 +39,7 @@ ENTRY(_blackfin_dcache_flush_range) RTS; ENDPROC(_blackfin_dcache_flush_range)
-ENTRY(_blackfin_dcache_invalidate_range) +ENTRY(_blackfin_dcache_flush_invalidate_range) R2 = -32; R2 = R0 & R2; P0 = R2; @@ -58,4 +58,4 @@ ENTRY(_blackfin_dcache_invalidate_range) FLUSHINV[P0]; SSYNC; RTS; -ENDPROC(_blackfin_dcache_invalidate_range) +ENDPROC(_blackfin_dcache_flush_invalidate_range) diff --git a/include/asm-blackfin/blackfin_local.h b/include/asm-blackfin/blackfin_local.h index 6f0e662..c9ee91a 100644 --- a/include/asm-blackfin/blackfin_local.h +++ b/include/asm-blackfin/blackfin_local.h @@ -58,7 +58,7 @@ extern u_long get_sclk(void);
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 *); +extern void blackfin_dcache_flush_invalidate_range(const void *, const void *);
/* Use DMA to move data from on chip to external memory. While this is * required for only L1 instruction (it is not directly readable by the diff --git a/lib_blackfin/string.c b/lib_blackfin/string.c index 2a56910..36eecdf 100644 --- a/lib_blackfin/string.c +++ b/lib_blackfin/string.c @@ -175,19 +175,22 @@ void dma_memcpy_nocache(void *dst, const void *src, size_t count) bfin_write_MDMA_D0_CONFIG(0); bfin_write_MDMA_S0_CONFIG(0); } +/* We should do a dcache invalidate on the destination after the dma, but since + * we lack such hardware capability, we'll flush/invalidate the destination + * before the dma and bank on the idea that u-boot is single threaded. + */ void *dma_memcpy(void *dst, const void *src, size_t count) { - if (dcache_status()) + if (dcache_status()) { blackfin_dcache_flush_range(src, src + count); + blackfin_dcache_flush_invalidate_range(dst, dst + count); + }
dma_memcpy_nocache(dst, src, count);
if (icache_status()) blackfin_icache_flush_range(dst, dst + count);
- if (dcache_status()) - blackfin_dcache_invalidate_range(dst, dst + count); - return dst; }

Adds support more Blackfin parts and fixes broken muxing for older ones.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- drivers/net/bfin_mac.c | 47 +++++++++++++++++++++++++++++++++++------------ 1 files changed, 35 insertions(+), 12 deletions(-)
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 504fd10..dddbb78 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c @@ -331,20 +331,43 @@ static int SetupSystemRegs(int *opmode) *pVR_CTL |= CLKBUFOE; /* Set all the pins to peripheral mode */
-#ifndef CONFIG_BFIN_MAC_RMII - *pPORTH_FER = 0xFFFF; -#ifdef __ADSPBF52x__ - *pPORTH_MUX = PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2 | PORT_x_MUX_2_FUNC_2; -#endif +#ifdef CONFIG_BFIN_MAC_RMII + /* grab RMII pins */ +# if defined(__ADSPBF51x__) + *pPORTF_MUX = (*pPORTF_MUX & \ + ~(PORT_x_MUX_3_MASK | PORT_x_MUX_4_MASK | PORT_x_MUX_5_MASK)) | \ + PORT_x_MUX_3_FUNC_1 | PORT_x_MUX_4_FUNC_1 | PORT_x_MUX_5_FUNC_1; + *pPORTF_FER |= PF8 | PF9 | PF10 | PF11 | PF12 | PF13 | PF14 | PF15; + *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_0_MASK) | PORT_x_MUX_0_FUNC_1; + *pPORTG_FER |= PG0 | PG1 | PG2; +# elif defined(__ADSPBF52x__) + *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_6_MASK) | PORT_x_MUX_6_FUNC_2; + *pPORTG_FER |= PG14 | PG15; + *pPORTH_MUX = (*pPORTH_MUX & ~(PORT_x_MUX_0_MASK | PORT_x_MUX_1_MASK)) | \ + PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2; + *pPORTH_FER |= PH0 | PH1 | PH2 | PH3 | PH4 | PH5 | PH6 | PH7 | PH8; +# else + *pPORTH_FER |= PH0 | PH1 | PH4 | PH5 | PH6 | PH8 | PH9 | PH14 | PH15; +# endif #else -#if defined(__ADSPBF536__) || defined(__ADSPBF537__) - *pPORTH_FER = 0xC373; -#endif -#ifdef __ADSPBF52x__ - *pPORTH_FER = 0x01FF; - *pPORTH_MUX = PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2; -#endif + /* grab MII & RMII pins */ +# if defined(__ADSPBF51x__) + *pPORTF_MUX = (*pPORTF_MUX & \ + ~(PORT_x_MUX_0_MASK | PORT_x_MUX_1_MASK | PORT_x_MUX_3_MASK | PORT_x_MUX_4_MASK | PORT_x_MUX_5_MASK)) | \ + PORT_x_MUX_0_FUNC_1 | PORT_x_MUX_1_FUNC_1 | PORT_x_MUX_3_FUNC_1 | PORT_x_MUX_4_FUNC_1 | PORT_x_MUX_5_FUNC_1; + *pPORTF_FER |= PF0 | PF1 | PF2 | PF3 | PF4 | PF5 | PF6 | PF8 | PF9 | PF10 | PF11 | PF12 | PF13 | PF14 | PF15; + *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_0_MASK) | PORT_x_MUX_0_FUNC_1; + *pPORTG_FER |= PG0 | PG1 | PG2; +# elif defined(__ADSPBF52x__) + *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_6_MASK) | PORT_x_MUX_6_FUNC_2; + *pPORTG_FER |= PG14 | PG15; + *pPORTH_MUX = PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2 | PORT_x_MUX_2_FUNC_2; + *pPORTH_FER = -1; /* all pins */ +# else + *pPORTH_FER = -1; /* all pins */ +# endif #endif + /* MDC = 2.5 MHz */ sysctl = SET_MDCDIV(24); /* Odd word alignment for Receive Frame DMA word */

The common code takes care of calling i2c_init() when needed, so no point in us doing it as well.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- lib_blackfin/board.c | 15 --------------- 1 files changed, 0 insertions(+), 15 deletions(-)
diff --git a/lib_blackfin/board.c b/lib_blackfin/board.c index 05e66e3..d16c819 100644 --- a/lib_blackfin/board.c +++ b/lib_blackfin/board.c @@ -13,7 +13,6 @@ #include <command.h> #include <devices.h> #include <environment.h> -#include <i2c.h> #include <malloc.h> #include <net.h> #include <timestamp.h> @@ -329,16 +328,6 @@ void board_init_f(ulong bootflag) board_init_r((gd_t *) gd, 0x20000010); }
-#if defined(CONFIG_SOFT_I2C) || defined(CONFIG_HARD_I2C) -static int init_func_i2c(void) -{ - puts("I2C: "); - i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); - puts("ready\n"); - return (0); -} -#endif - void board_init_r(gd_t * id, ulong dest_addr) { extern void malloc_bin_reloc(void); @@ -440,10 +429,6 @@ void board_init_r(gd_t * id, ulong dest_addr) bd->bi_enetaddr[3], bd->bi_enetaddr[4], bd->bi_enetaddr[5]); #endif
-#if defined(CONFIG_SOFT_I2C) || defined(CONFIG_HARD_I2C) - init_func_i2c(); -#endif - display_global_data();
#if defined(CONFIG_POST)

Here are the Blackfin-specific and board-independent pieces for status leds.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- include/status_led.h | 3 +++ lib_blackfin/board.c | 10 ++++++++++ 2 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/include/status_led.h b/include/status_led.h index 79be698..175972a 100644 --- a/include/status_led.h +++ b/include/status_led.h @@ -346,6 +346,9 @@ void status_led_set (int led, int state); #elif defined(CONFIG_NIOS2) /* XXX empty just to avoid the error */ /************************************************************************/ +#elif defined(CONFIG_BLACKFIN) +/* XXX empty just to avoid the error */ +/************************************************************************/ #elif defined(CONFIG_V38B)
# define STATUS_LED_BIT 0x0010 /* Timer7 GPIO */ diff --git a/lib_blackfin/board.c b/lib_blackfin/board.c index d16c819..9d7a0f6 100644 --- a/lib_blackfin/board.c +++ b/lib_blackfin/board.c @@ -16,6 +16,7 @@ #include <malloc.h> #include <net.h> #include <timestamp.h> +#include <status_led.h> #include <version.h>
#include <asm/cplb.h> @@ -407,6 +408,11 @@ void board_init_r(gd_t * id, ulong dest_addr) /* Initialize the console (after the relocation and devices init) */ console_init_r();
+#ifdef CONFIG_STATUS_LED + status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING); + status_led_set(STATUS_LED_CRASH, STATUS_LED_OFF); +#endif + /* Initialize from environment */ if ((s = getenv("loadaddr")) != NULL) load_addr = simple_strtoul(s, NULL, 16); @@ -443,6 +449,10 @@ void board_init_r(gd_t * id, ulong dest_addr)
void hang(void) { +#ifdef CONFIG_STATUS_LED + status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF); + status_led_set(STATUS_LED_CRASH, STATUS_LED_BLINKING); +#endif puts("### ERROR ### Please RESET the board ###\n"); while (1) /* If a JTAG emulator is hooked up, we'll automatically trigger

When setting up the global data, rather than relying on sizeof(), use the common CONFIG_SYS_GBL_DATA_SIZE define.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- lib_blackfin/board.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/lib_blackfin/board.c b/lib_blackfin/board.c index 9d7a0f6..2feb64b 100644 --- a/lib_blackfin/board.c +++ b/lib_blackfin/board.c @@ -278,9 +278,13 @@ void board_init_f(ulong bootflag) dcache_enable(); #endif
+#ifdef DEBUG + if (CONFIG_SYS_GBL_DATA_SIZE < sizeof(*gd)) + hang(); +#endif serial_early_puts("Init global data\n"); gd = (gd_t *) (CONFIG_SYS_GBL_DATA_ADDR); - memset((void *)gd, 0, sizeof(gd_t)); + memset((void *)gd, 0, CONFIG_SYS_GBL_DATA_SIZE);
/* Board data initialization */ addr = (CONFIG_SYS_GBL_DATA_ADDR + sizeof(gd_t));

Respect the CONFIG_SYS_MONITOR_LEN define rather than assuming a size of 128kB when setting up the default flash protection region for U-Boot itself.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- lib_blackfin/board.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib_blackfin/board.c b/lib_blackfin/board.c index 2feb64b..809c68c 100644 --- a/lib_blackfin/board.c +++ b/lib_blackfin/board.c @@ -348,14 +348,14 @@ void board_init_r(gd_t * id, ulong dest_addr) #endif
#if !defined(CONFIG_SYS_NO_FLASH) - /* There are some other pointer constants we must deal with */ - /* configure available FLASH banks */ + /* Initialize the flash and protect u-boot by default */ extern flash_info_t flash_info[]; ulong size = flash_init(); puts("Flash: "); print_size(size, "\n"); flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_FLASH_BASE, - CONFIG_SYS_FLASH_BASE + 0x1ffff, &flash_info[0]); + CONFIG_SYS_FLASH_BASE + CONFIG_SYS_MONITOR_LEN - 1, + &flash_info[0]); bd->bi_flashstart = CONFIG_SYS_FLASH_BASE; bd->bi_flashsize = size; bd->bi_flashoffset = 0;

The current Blackfin i2c driver does not work properly with certain devices due to it breaking up transfers incorrectly. This is a rewrite of the driver and relocates it to the newer place in the source tree.
Also remove duplicated I2C speed defines in Blackfin board configs and disable I2C slave address usage since it isn't implemented.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- cpu/blackfin/Makefile | 2 +- cpu/blackfin/i2c.c | 428 ----------------------------------------- drivers/i2c/Makefile | 1 + drivers/i2c/bfin-twi_i2c.c | 285 +++++++++++++++++++++++++++ include/configs/bf533-ezkit.h | 2 +- include/configs/bf533-stamp.h | 2 +- include/configs/bf537-stamp.h | 43 +---- 7 files changed, 293 insertions(+), 470 deletions(-) delete mode 100644 cpu/blackfin/i2c.c create mode 100644 drivers/i2c/bfin-twi_i2c.c
diff --git a/cpu/blackfin/Makefile b/cpu/blackfin/Makefile index 8fed4b4..b90fb48 100644 --- a/cpu/blackfin/Makefile +++ b/cpu/blackfin/Makefile @@ -17,7 +17,7 @@ EXTRA := CEXTRA := initcode.o SEXTRA := start.o SOBJS := interrupt.o cache.o -COBJS := cpu.o traps.o interrupts.o reset.o serial.o i2c.o watchdog.o +COBJS := cpu.o traps.o interrupts.o reset.o serial.o watchdog.o
ifeq ($(CONFIG_BFIN_BOOT_MODE),BFIN_BOOT_BYPASS) COBJS += initcode.o diff --git a/cpu/blackfin/i2c.c b/cpu/blackfin/i2c.c deleted file mode 100644 index 2a3e223..0000000 --- a/cpu/blackfin/i2c.c +++ /dev/null @@ -1,428 +0,0 @@ -/* - * i2c.c - driver for Blackfin on-chip TWI/I2C - * - * Copyright (c) 2006-2008 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include <common.h> - -#ifdef CONFIG_HARD_I2C - -#include <asm/blackfin.h> -#include <i2c.h> -#include <asm/io.h> -#include <asm/mach-common/bits/twi.h> - -/* Two-Wire Interface (0xFFC01400 - 0xFFC014FF) */ -#ifdef TWI0_CLKDIV -#define bfin_read_TWI_CLKDIV() bfin_read_TWI0_CLKDIV() -#define bfin_write_TWI_CLKDIV(val) bfin_write_TWI0_CLKDIV(val) -#define bfin_read_TWI_CONTROL() bfin_read_TWI0_CONTROL() -#define bfin_write_TWI_CONTROL(val) bfin_write_TWI0_CONTROL(val) -#define bfin_read_TWI_SLAVE_CTL() bfin_read_TWI0_SLAVE_CTL() -#define bfin_write_TWI_SLAVE_CTL(val) bfin_write_TWI0_SLAVE_CTL(val) -#define bfin_read_TWI_SLAVE_STAT() bfin_read_TWI0_SLAVE_STAT() -#define bfin_write_TWI_SLAVE_STAT(val) bfin_write_TWI0_SLAVE_STAT(val) -#define bfin_read_TWI_SLAVE_ADDR() bfin_read_TWI0_SLAVE_ADDR() -#define bfin_write_TWI_SLAVE_ADDR(val) bfin_write_TWI0_SLAVE_ADDR(val) -#define bfin_read_TWI_MASTER_CTL() bfin_read_TWI0_MASTER_CTL() -#define bfin_write_TWI_MASTER_CTL(val) bfin_write_TWI0_MASTER_CTL(val) -#define bfin_read_TWI_MASTER_STAT() bfin_read_TWI0_MASTER_STAT() -#define bfin_write_TWI_MASTER_STAT(val) bfin_write_TWI0_MASTER_STAT(val) -#define bfin_read_TWI_MASTER_ADDR() bfin_read_TWI0_MASTER_ADDR() -#define bfin_write_TWI_MASTER_ADDR(val) bfin_write_TWI0_MASTER_ADDR(val) -#define bfin_read_TWI_INT_STAT() bfin_read_TWI0_INT_STAT() -#define bfin_write_TWI_INT_STAT(val) bfin_write_TWI0_INT_STAT(val) -#define bfin_read_TWI_INT_MASK() bfin_read_TWI0_INT_MASK() -#define bfin_write_TWI_INT_MASK(val) bfin_write_TWI0_INT_MASK(val) -#define bfin_read_TWI_FIFO_CTL() bfin_read_TWI0_FIFO_CTL() -#define bfin_write_TWI_FIFO_CTL(val) bfin_write_TWI0_FIFO_CTL(val) -#define bfin_read_TWI_FIFO_STAT() bfin_read_TWI0_FIFO_STAT() -#define bfin_write_TWI_FIFO_STAT(val) bfin_write_TWI0_FIFO_STAT(val) -#define bfin_read_TWI_XMT_DATA8() bfin_read_TWI0_XMT_DATA8() -#define bfin_write_TWI_XMT_DATA8(val) bfin_write_TWI0_XMT_DATA8(val) -#define bfin_read_TWI_XMT_DATA_16() bfin_read_TWI0_XMT_DATA16() -#define bfin_write_TWI_XMT_DATA16(val) bfin_write_TWI0_XMT_DATA16(val) -#define bfin_read_TWI_RCV_DATA8() bfin_read_TWI0_RCV_DATA8() -#define bfin_write_TWI_RCV_DATA8(val) bfin_write_TWI0_RCV_DATA8(val) -#define bfin_read_TWI_RCV_DATA16() bfin_read_TWI0_RCV_DATA16() -#define bfin_write_TWI_RCV_DATA16(val) bfin_write_TWI0_RCV_DATA16(val) -#endif - -#ifdef DEBUG_I2C -#define PRINTD(fmt,args...) do { \ - DECLARE_GLOBAL_DATA_PTR; \ - if (gd->have_console) \ - printf(fmt ,##args); \ - } while (0) -#else -#define PRINTD(fmt,args...) -#endif - -#ifndef CONFIG_TWICLK_KHZ -#define CONFIG_TWICLK_KHZ 50 -#endif - -/* All transfers are described by this data structure */ -struct i2c_msg { - u16 addr; /* slave address */ - u16 flags; -#define I2C_M_STOP 0x2 -#define I2C_M_RD 0x1 - u16 len; /* msg length */ - u8 *buf; /* pointer to msg data */ -}; - -/** - * i2c_reset: - reset the host controller - */ -static void i2c_reset(void) -{ - /* Disable TWI */ - bfin_write_TWI_CONTROL(0); - SSYNC(); - - /* Set TWI internal clock as 10MHz */ - bfin_write_TWI_CONTROL(((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F); - - /* Set Twi interface clock as specified */ - if (CONFIG_TWICLK_KHZ > 400) - bfin_write_TWI_CLKDIV(((5 * 1024 / 400) << 8) | ((5 * 1024 / - 400) & 0xFF)); - else - bfin_write_TWI_CLKDIV(((5 * 1024 / - CONFIG_TWICLK_KHZ) << 8) | ((5 * 1024 / - CONFIG_TWICLK_KHZ) - & 0xFF)); - - /* Enable TWI */ - bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA); - SSYNC(); -} - -int wait_for_completion(struct i2c_msg *msg, int timeout_count) -{ - unsigned short twi_int_stat; - unsigned short mast_stat; - int i; - - for (i = 0; i < timeout_count; i++) { - twi_int_stat = bfin_read_TWI_INT_STAT(); - mast_stat = bfin_read_TWI_MASTER_STAT(); - - if (XMTSERV & twi_int_stat) { - /* Transmit next data */ - if (msg->len > 0) { - bfin_write_TWI_XMT_DATA8(*(msg->buf++)); - msg->len--; - } else if (msg->flags & I2C_M_STOP) - bfin_write_TWI_MASTER_CTL - (bfin_read_TWI_MASTER_CTL() | STOP); - SSYNC(); - /* Clear status */ - bfin_write_TWI_INT_STAT(XMTSERV); - SSYNC(); - i = 0; - } - if (RCVSERV & twi_int_stat) { - if (msg->len > 0) { - /* Receive next data */ - *(msg->buf++) = bfin_read_TWI_RCV_DATA8(); - msg->len--; - } else if (msg->flags & I2C_M_STOP) { - bfin_write_TWI_MASTER_CTL - (bfin_read_TWI_MASTER_CTL() | STOP); - SSYNC(); - } - /* Clear interrupt source */ - bfin_write_TWI_INT_STAT(RCVSERV); - SSYNC(); - i = 0; - } - if (MERR & twi_int_stat) { - bfin_write_TWI_INT_STAT(MERR); - bfin_write_TWI_INT_MASK(0); - bfin_write_TWI_MASTER_STAT(0x3e); - bfin_write_TWI_MASTER_CTL(0); - SSYNC(); - /* - * if both err and complete int stats are set, - * return proper results. - */ - if (MCOMP & twi_int_stat) { - bfin_write_TWI_INT_STAT(MCOMP); - bfin_write_TWI_INT_MASK(0); - bfin_write_TWI_MASTER_CTL(0); - SSYNC(); - /* - * If it is a quick transfer, - * only address bug no data, not an err. - */ - if (msg->len == 0 && mast_stat & BUFRDERR) - return 0; - /* - * If address not acknowledged return -3, - * else return 0. - */ - else if (!(mast_stat & ANAK)) - return 0; - else - return -3; - } - return -1; - } - if (MCOMP & twi_int_stat) { - bfin_write_TWI_INT_STAT(MCOMP); - SSYNC(); - bfin_write_TWI_INT_MASK(0); - bfin_write_TWI_MASTER_CTL(0); - SSYNC(); - return 0; - } - } - if (msg->flags & I2C_M_RD) - return -4; - else - return -2; -} - -/** - * i2c_transfer: - Transfer one byte over the i2c bus - * - * This function can tranfer a byte over the i2c bus in both directions. - * It is used by the public API functions. - * - * @return: 0: transfer successful - * -1: transfer fail - * -2: transmit timeout - * -3: ACK missing - * -4: receive timeout - * -5: controller not ready - */ -int i2c_transfer(struct i2c_msg *msg) -{ - int ret = 0; - int timeout_count = 10000; - int len = msg->len; - - if (!(bfin_read_TWI_CONTROL() & TWI_ENA)) { - ret = -5; - goto transfer_error; - } - - while (bfin_read_TWI_MASTER_STAT() & BUSBUSY) - continue; - - /* Set Transmit device address */ - bfin_write_TWI_MASTER_ADDR(msg->addr); - - /* - * FIFO Initiation. - * Data in FIFO should be discarded before start a new operation. - */ - bfin_write_TWI_FIFO_CTL(0x3); - SSYNC(); - bfin_write_TWI_FIFO_CTL(0); - SSYNC(); - - if (!(msg->flags & I2C_M_RD)) { - /* Transmit first data */ - if (msg->len > 0) { - PRINTD("1 in i2c_transfer: buf=%d, len=%d\n", *msg->buf, - len); - bfin_write_TWI_XMT_DATA8(*(msg->buf++)); - msg->len--; - SSYNC(); - } - } - - /* clear int stat */ - bfin_write_TWI_INT_STAT(MERR | MCOMP | XMTSERV | RCVSERV); - - /* Interrupt mask . Enable XMT, RCV interrupt */ - bfin_write_TWI_INT_MASK(MCOMP | MERR | - ((msg->flags & I2C_M_RD) ? RCVSERV : XMTSERV)); - SSYNC(); - - if (len > 0 && len <= 255) - bfin_write_TWI_MASTER_CTL((len << 6)); - else if (msg->len > 255) { - bfin_write_TWI_MASTER_CTL((0xff << 6)); - msg->flags &= I2C_M_STOP; - } else - bfin_write_TWI_MASTER_CTL(0); - - /* Master enable */ - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | - ((msg->flags & I2C_M_RD) - ? MDIR : 0) | ((CONFIG_TWICLK_KHZ > - 100) ? FAST : 0)); - SSYNC(); - - ret = wait_for_completion(msg, timeout_count); - PRINTD("3 in i2c_transfer: ret=%d\n", ret); - - transfer_error: - switch (ret) { - case 1: - PRINTD(("i2c_transfer: error: transfer fail\n")); - break; - case 2: - PRINTD(("i2c_transfer: error: transmit timeout\n")); - break; - case 3: - PRINTD(("i2c_transfer: error: ACK missing\n")); - break; - case 4: - PRINTD(("i2c_transfer: error: receive timeout\n")); - break; - case 5: - PRINTD(("i2c_transfer: error: controller not ready\n")); - i2c_reset(); - break; - default: - break; - } - return ret; - -} - -/* ---------------------------------------------------------------------*/ -/* API Functions */ -/* ---------------------------------------------------------------------*/ - -void i2c_init(int speed, int slaveaddr) -{ - i2c_reset(); -} - -/** - * i2c_probe: - Test if a chip answers for a given i2c address - * - * @chip: address of the chip which is searched for - * @return: 0 if a chip was found, -1 otherwhise - */ - -int i2c_probe(uchar chip) -{ - struct i2c_msg msg; - u8 probebuf; - - i2c_reset(); - - probebuf = 0; - msg.addr = chip; - msg.flags = 0; - msg.len = 1; - msg.buf = &probebuf; - if (i2c_transfer(&msg)) - return -1; - - msg.addr = chip; - msg.flags = I2C_M_RD; - msg.len = 1; - msg.buf = &probebuf; - if (i2c_transfer(&msg)) - return -1; - - return 0; -} - -/** - * i2c_read: - Read multiple bytes from an i2c device - * - * chip: I2C chip address, range 0..127 - * addr: Memory (register) address within the chip - * alen: Number of bytes to use for addr (typically 1, 2 for larger - * memories, 0 for register type devices with only one - * register) - * buffer: Where to read/write the data - * len: How many bytes to read/write - * - * Returns: 0 on success, not 0 on failure - */ - -int i2c_read(uchar chip, uint addr, int alen, uchar * buffer, int len) -{ - struct i2c_msg msg; - u8 addr_bytes[3]; /* lowest...highest byte of data address */ - - PRINTD("i2c_read: chip=0x%x, addr=0x%x, alen=0x%x, len=0x%x\n", chip, - addr, alen, len); - - if (alen > 0) { - addr_bytes[0] = (u8) ((addr >> 0) & 0x000000FF); - addr_bytes[1] = (u8) ((addr >> 8) & 0x000000FF); - addr_bytes[2] = (u8) ((addr >> 16) & 0x000000FF); - msg.addr = chip; - msg.flags = 0; - msg.len = alen; - msg.buf = addr_bytes; - if (i2c_transfer(&msg)) - return -1; - } - - /* start read sequence */ - PRINTD(("i2c_read: start read sequence\n")); - msg.addr = chip; - msg.flags = I2C_M_RD; - msg.len = len; - msg.buf = buffer; - if (i2c_transfer(&msg)) - return -1; - - return 0; -} - -/** - * i2c_write: - Write multiple bytes to an i2c device - * - * chip: I2C chip address, range 0..127 - * addr: Memory (register) address within the chip - * alen: Number of bytes to use for addr (typically 1, 2 for larger - * memories, 0 for register type devices with only one - * register) - * buffer: Where to read/write the data - * len: How many bytes to read/write - * - * Returns: 0 on success, not 0 on failure - */ - -int i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len) -{ - struct i2c_msg msg; - u8 addr_bytes[3]; /* lowest...highest byte of data address */ - - PRINTD - ("i2c_write: chip=0x%x, addr=0x%x, alen=0x%x, len=0x%x, buf0=0x%x\n", - chip, addr, alen, len, buffer[0]); - - /* chip address write */ - if (alen > 0) { - addr_bytes[0] = (u8) ((addr >> 0) & 0x000000FF); - addr_bytes[1] = (u8) ((addr >> 8) & 0x000000FF); - addr_bytes[2] = (u8) ((addr >> 16) & 0x000000FF); - msg.addr = chip; - msg.flags = 0; - msg.len = alen; - msg.buf = addr_bytes; - if (i2c_transfer(&msg)) - return -1; - } - - /* start read sequence */ - PRINTD(("i2c_write: start write sequence\n")); - msg.addr = chip; - msg.flags = 0; - msg.len = len; - msg.buf = buffer; - if (i2c_transfer(&msg)) - return -1; - - return 0; - -} - -#endif /* CONFIG_HARD_I2C */ diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 6079c05..08cb91d 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libi2c.a
+COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o diff --git a/drivers/i2c/bfin-twi_i2c.c b/drivers/i2c/bfin-twi_i2c.c new file mode 100644 index 0000000..cfe55cd --- /dev/null +++ b/drivers/i2c/bfin-twi_i2c.c @@ -0,0 +1,285 @@ +/* + * i2c.c - driver for Blackfin on-chip TWI/I2C + * + * Copyright (c) 2006-2008 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <common.h> +#include <i2c.h> + +#include <asm/blackfin.h> +#include <asm/mach-common/bits/twi.h> + +#ifdef DEBUG +# define dmemset(s, c, n) memset(s, c, n) +#else +# define dmemset(s, c, n) +#endif +#define debugi(fmt, args...) \ + debug( \ + "MSTAT:0x%03x FSTAT:0x%x ISTAT:0x%02x\t" \ + "%-20s:%-3i: " fmt "\n", \ + bfin_read_TWI_MASTER_STAT(), bfin_read_TWI_FIFO_STAT(), bfin_read_TWI_INT_STAT(), \ + __func__, __LINE__, ## args) + +#ifdef TWI0_CLKDIV +#define bfin_write_TWI_CLKDIV(val) bfin_write_TWI0_CLKDIV(val) +#define bfin_write_TWI_CONTROL(val) bfin_write_TWI0_CONTROL(val) +#define bfin_read_TWI_CONTROL(val) bfin_read_TWI0_CONTROL(val) +#define bfin_write_TWI_MASTER_ADDR(val) bfin_write_TWI0_MASTER_ADDR(val) +#define bfin_write_TWI_XMT_DATA8(val) bfin_write_TWI0_XMT_DATA8(val) +#define bfin_read_TWI_RCV_DATA8() bfin_read_TWI0_RCV_DATA8() +#define bfin_read_TWI_INT_STAT() bfin_read_TWI0_INT_STAT() +#define bfin_write_TWI_INT_STAT(val) bfin_write_TWI0_INT_STAT(val) +#define bfin_read_TWI_MASTER_STAT() bfin_read_TWI0_MASTER_STAT() +#define bfin_write_TWI_MASTER_STAT(val) bfin_write_TWI0_MASTER_STAT(val) +#define bfin_read_TWI_MASTER_CTL() bfin_read_TWI0_MASTER_CTL() +#define bfin_write_TWI_MASTER_CTL(val) bfin_write_TWI0_MASTER_CTL(val) +#define bfin_write_TWI_INT_MASK(val) bfin_write_TWI0_INT_MASK(val) +#define bfin_write_TWI_FIFO_CTL(val) bfin_write_TWI0_FIFO_CTL(val) +#endif + +#ifdef CONFIG_TWICLK_KHZ +# error do not define CONFIG_TWICLK_KHZ ... use CONFIG_SYS_I2C_SPEED +#endif +#if CONFIG_SYS_I2C_SPEED > 400000 +# error The Blackfin I2C hardware can only operate at 400KHz max +#endif + +/* All transfers are described by this data structure */ +struct i2c_msg { + u8 flags; +#define I2C_M_COMBO 0x4 +#define I2C_M_STOP 0x2 +#define I2C_M_READ 0x1 + int len; /* msg length */ + u8 *buf; /* pointer to msg data */ + int alen; /* addr length */ + u8 *abuf; /* addr buffer */ +}; + +/** + * wait_for_completion - manage the actual i2c transfer + * @msg: the i2c msg + */ +static int wait_for_completion(struct i2c_msg *msg) +{ + uint16_t int_stat; + + while (!ctrlc()) { + int_stat = bfin_read_TWI_INT_STAT(); + + if (int_stat & XMTSERV) { + debugi("processing XMTSERV"); + bfin_write_TWI_INT_STAT(XMTSERV); + SSYNC(); + if (msg->alen) { + bfin_write_TWI_XMT_DATA8(*(msg->abuf++)); + --msg->alen; + } else if (!(msg->flags & I2C_M_COMBO) && msg->len) { + bfin_write_TWI_XMT_DATA8(*(msg->buf++)); + --msg->len; + } else { + bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | + (msg->flags & I2C_M_COMBO ? RSTART | MDIR : STOP)); + SSYNC(); + } + } + if (int_stat & RCVSERV) { + debugi("processing RCVSERV"); + bfin_write_TWI_INT_STAT(RCVSERV); + SSYNC(); + if (msg->len) { + *(msg->buf++) = bfin_read_TWI_RCV_DATA8(); + --msg->len; + } else if (msg->flags & I2C_M_STOP) { + bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | STOP); + SSYNC(); + } + } + if (int_stat & MERR) { + debugi("processing MERR"); + bfin_write_TWI_INT_STAT(MERR); + SSYNC(); + break; + } + if (int_stat & MCOMP) { + debugi("processing MCOMP"); + bfin_write_TWI_INT_STAT(MCOMP); + SSYNC(); + if (msg->flags & I2C_M_COMBO && msg->len) { + bfin_write_TWI_MASTER_CTL((bfin_read_TWI_MASTER_CTL() & ~RSTART) | + (min(msg->len, 0xff) << 6) | MEN | MDIR); + SSYNC(); + } else + break; + } + } + + return msg->len; +} + +/** + * i2c_transfer - setup an i2c transfer + * @return: 0 if things worked, non-0 if things failed + * + * Here we just get the i2c stuff all prepped and ready, and then tail off + * into wait_for_completion() for all the bits to go. + */ +static int i2c_transfer(uchar chip, uint addr, int alen, uchar *buffer, int len, u8 flags) +{ + uchar addr_buffer[] = { + (addr >> 0), + (addr >> 8), + (addr >> 16), + }; + struct i2c_msg msg = { + .flags = flags | (len >= 0xff ? I2C_M_STOP : 0), + .buf = buffer, + .len = len, + .abuf = addr_buffer, + .alen = alen, + }; + int ret; + + dmemset(buffer, 0xff, len); + debugi("chip=0x%x addr=0x%02x alen=%i buf[0]=0x%02x len=%i flags=0x%02x[%s] ", + chip, addr, alen, buffer[0], len, flags, (flags & I2C_M_READ ? "rd" : "wr")); + + /* wait for things to settle */ + while (bfin_read_TWI_MASTER_STAT() & BUSBUSY) + if (ctrlc()) + return 1; + + /* Set Transmit device address */ + bfin_write_TWI_MASTER_ADDR(chip); + + /* Clear the FIFO before starting things */ + bfin_write_TWI_FIFO_CTL(XMTFLUSH | RCVFLUSH); + SSYNC(); + bfin_write_TWI_FIFO_CTL(0); + SSYNC(); + + /* prime the pump */ + if (msg.alen) { + len = msg.alen; + debugi("first byte=0x%02x", *msg.abuf); + bfin_write_TWI_XMT_DATA8(*(msg.abuf++)); + --msg.alen; + } else if (!(msg.flags & I2C_M_READ) && msg.len) { + debugi("first byte=0x%02x", *msg.buf); + bfin_write_TWI_XMT_DATA8(*(msg.buf++)); + --msg.len; + } + + /* clear int stat */ + bfin_write_TWI_MASTER_STAT(-1); + bfin_write_TWI_INT_STAT(-1); + bfin_write_TWI_INT_MASK(0); + SSYNC(); + + /* Master enable */ + bfin_write_TWI_MASTER_CTL( + (bfin_read_TWI_MASTER_CTL() & FAST) | + (min(len, 0xff) << 6) | MEN | + ((msg.flags & I2C_M_READ) ? MDIR : 0) + ); + SSYNC(); + debugi("CTL=0x%04x", bfin_read_TWI_MASTER_CTL()); + + /* process the rest */ + ret = wait_for_completion(&msg); + debugi("ret=%d", ret); + + if (ret) { + bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() & ~MEN); + bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() & ~TWI_ENA); + SSYNC(); + bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA); + SSYNC(); + } + + return ret; +} + +/* + * i2c_init - initialize the i2c bus + * @speed: bus speed (in HZ) + * @slaveaddr: address of device in slave mode (0 - not slave) + * + * Slave mode isn't actually implemented. It'll stay that way until + * we get a real request for it. + */ +void i2c_init(int speed, int slaveaddr) +{ + uint8_t prescale = ((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F; + + /* Set TWI internal clock as 10MHz */ + bfin_write_TWI_CONTROL(prescale); + + /* Set TWI interface clock as specified */ + bfin_write_TWI_CLKDIV( + ((5 * 1024 / (speed / 1000)) << 8) | + ((5 * 1024 / (speed / 1000)) & 0xFF) + ); + + /* Don't turn it on */ + bfin_write_TWI_MASTER_CTL(speed > 100000 ? FAST : 0); + + /* But enable it */ + bfin_write_TWI_CONTROL(TWI_ENA | prescale); + SSYNC(); + + debugi("CONTROL:0x%04x CLKDIV:0x%04x", + bfin_read_TWI_CONTROL(), bfin_read_TWI_CLKDIV()); + +#if CONFIG_SYS_I2C_SLAVE +# error I2C slave support not tested/supported + /* If they want us as a slave, do it */ + if (slaveaddr) { + bfin_write_TWI_SLAVE_ADDR(slaveaddr); + bfin_write_TWI_SLAVE_CTL(SEN); + } +#endif +} + +/** + * i2c_probe - test if a chip exists at a given i2c address + * @chip: i2c chip addr to search for + * @return: 0 if found, non-0 if not found + */ +int i2c_probe(uchar chip) +{ + u8 byte; + return i2c_read(chip, 0, 0, &byte, 1); +} + +/** + * i2c_read - read data from an i2c device + * @chip: i2c chip addr + * @addr: memory (register) address in the chip + * @alen: byte size of address + * @buffer: buffer to store data read from chip + * @len: how many bytes to read + * @return: 0 on success, non-0 on failure + */ +int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) +{ + return i2c_transfer(chip, addr, alen, buffer, len, (alen ? I2C_M_COMBO : I2C_M_READ)); +} + +/** + * i2c_write - write data to an i2c device + * @chip: i2c chip addr + * @addr: memory (register) address in the chip + * @alen: byte size of address + * @buffer: buffer to store data read from chip + * @len: how many bytes to write + * @return: 0 on success, non-0 on failure + */ +int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) +{ + return i2c_transfer(chip, addr, alen, buffer, len, 0); +} diff --git a/include/configs/bf533-ezkit.h b/include/configs/bf533-ezkit.h index e871737..48c0252 100644 --- a/include/configs/bf533-ezkit.h +++ b/include/configs/bf533-ezkit.h @@ -198,7 +198,7 @@ #define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */
#define CONFIG_SYS_I2C_SPEED 50000 -#define CONFIG_SYS_I2C_SLAVE 0xFE +#define CONFIG_SYS_I2C_SLAVE 0
#define CONFIG_SYS_BOOTM_LEN 0x4000000 /* Large Image Length, set to 64 Meg */
diff --git a/include/configs/bf533-stamp.h b/include/configs/bf533-stamp.h index 5ad99a2..ee41c7e 100644 --- a/include/configs/bf533-stamp.h +++ b/include/configs/bf533-stamp.h @@ -300,7 +300,7 @@ #define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */
#define CONFIG_SYS_I2C_SPEED 50000 -#define CONFIG_SYS_I2C_SLAVE 0xFE +#define CONFIG_SYS_I2C_SLAVE 0 #endif /* CONFIG_SOFT_I2C */
/* diff --git a/include/configs/bf537-stamp.h b/include/configs/bf537-stamp.h index 1b54d3b..c504666 100644 --- a/include/configs/bf537-stamp.h +++ b/include/configs/bf537-stamp.h @@ -306,13 +306,11 @@
/* * I2C settings - * By default PF1 is used as SDA and PF0 as SCL on the Stamp board */ -/* #define CONFIG_SOFT_I2C 1*/ /* I2C bit-banged */ -#define CONFIG_HARD_I2C 1 /* I2C TWI */ -#if defined CONFIG_HARD_I2C -#define CONFIG_TWICLK_KHZ 50 -#endif +#define CONFIG_HARD_I2C 1 +#define CONFIG_BFIN_TWI_I2C 1 +#define CFG_I2C_SPEED 50000 +#define CFG_I2C_SLAVE 0
#define CONFIG_EBIU_SDRRC_VAL 0x306 #define CONFIG_EBIU_SDGCTL_VAL 0x91114d @@ -322,39 +320,6 @@ #define CONFIG_EBIU_AMBCTL0_VAL 0x7BB07BB0 #define CONFIG_EBIU_AMBCTL1_VAL 0xFFC27BB0
-#if defined CONFIG_SOFT_I2C -/* - * Software (bit-bang) I2C driver configuration - */ -#define PF_SCL PF0 -#define PF_SDA PF1 - -#define I2C_INIT (*pFIO_DIR |= PF_SCL); asm("ssync;") -#define I2C_ACTIVE (*pFIO_DIR |= PF_SDA); *pFIO_INEN &= ~PF_SDA; asm("ssync;") -#define I2C_TRISTATE (*pFIO_DIR &= ~PF_SDA); *pFIO_INEN |= PF_SDA; asm("ssync;") -#define I2C_READ ((volatile)(*pFIO_FLAG_D & PF_SDA) != 0); asm("ssync;") -#define I2C_SDA(bit) if(bit) { \ - *pFIO_FLAG_S = PF_SDA; \ - asm("ssync;"); \ - } \ - else { \ - *pFIO_FLAG_C = PF_SDA; \ - asm("ssync;"); \ - } -#define I2C_SCL(bit) if(bit) { \ - *pFIO_FLAG_S = PF_SCL; \ - asm("ssync;"); \ - } \ - else { \ - *pFIO_FLAG_C = PF_SCL; \ - asm("ssync;"); \ - } -#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ -#endif - -#define CONFIG_SYS_I2C_SPEED 50000 -#define CONFIG_SYS_I2C_SLAVE 0xFE - /* 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 | \

On Fri, Jan 23, 2009 at 12:00 PM, Mike Frysinger vapier@gentoo.org wrote:
The current Blackfin i2c driver does not work properly with certain devices due to it breaking up transfers incorrectly. This is a rewrite of the driver and relocates it to the newer place in the source tree.
Also remove duplicated I2C speed defines in Blackfin board configs and disable I2C slave address usage since it isn't implemented.
Signed-off-by: Mike Frysinger vapier@gentoo.org
include/i2c.h still has this:
static inline void i2c_reg_write(u8 addr, u8 reg, u8 val) { ... #ifdef CONFIG_BLACKFIN /* This ifdef will become unneccessary in a future version of the * blackfin I2C driver. */ i2c_write(addr, reg, 0, &val, 1); #else i2c_write(addr, reg, 1, &val, 1); #endif }
There's a similar #ifdef in i2c_reg_read(). Are these #ifdefs still necessary? If so, could you modify your I2C driver so that they aren't? And then fix i2c.h as well?

On Wednesday 11 February 2009 18:19:36 Timur Tabi wrote:
On Fri, Jan 23, 2009 at 12:00 PM, Mike Frysinger vapier@gentoo.org wrote:
The current Blackfin i2c driver does not work properly with certain devices due to it breaking up transfers incorrectly. This is a rewrite of the driver and relocates it to the newer place in the source tree.
Also remove duplicated I2C speed defines in Blackfin board configs and disable I2C slave address usage since it isn't implemented.
Signed-off-by: Mike Frysinger vapier@gentoo.org
include/i2c.h still has this:
static inline void i2c_reg_write(u8 addr, u8 reg, u8 val) { ... #ifdef CONFIG_BLACKFIN /* This ifdef will become unneccessary in a future version of the * blackfin I2C driver. */ i2c_write(addr, reg, 0, &val, 1); #else i2c_write(addr, reg, 1, &val, 1); #endif }
There's a similar #ifdef in i2c_reg_read(). Are these #ifdefs still necessary? If so, could you modify your I2C driver so that they aren't? And then fix i2c.h as well?
ugh, i told the guy submitting those changes to ignore the Blackfin i2c driver. the ifdef's in the common code should be dropped, thanks for pointing this out. -mike

Mike Frysinger wrote:
ugh, i told the guy submitting those changes to ignore the Blackfin i2c driver. the ifdef's in the common code should be dropped, thanks for pointing this out.
I know - I'm the guy who made those changes, but I didn't want to ignore blackfin because I wasn't sure when you were going to write your driver, and I didn't want to introduce code that altered the behavior of blackfin.

On Wednesday 11 February 2009 18:44:00 Timur Tabi wrote:
Mike Frysinger wrote:
ugh, i told the guy submitting those changes to ignore the Blackfin i2c driver. the ifdef's in the common code should be dropped, thanks for pointing this out.
I know - I'm the guy who made those changes, but I didn't want to ignore blackfin because I wasn't sure when you were going to write your driver, and I didn't want to introduce code that altered the behavior of blackfin.
i told you at the time that the Blackfin i2c driver in the tree was broken. no matter what your changes did, it wouldnt make the existing situation worse. instead, we'd end up with bit rot like we now have.
will you post a patch to fix the issue or shall i ? -mike

On Wed, Feb 11, 2009 at 5:58 PM, Mike Frysinger vapier@gentoo.org wrote:
will you post a patch to fix the issue or shall i ?
I'd rather you do it, because then you can test the code to make sure it really works.

Some of the flash defines weren't in the correct location and caused build problems in some configurations, so let's move types and defines to better local locations.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- board/bf533-ezkit/bf533-ezkit.c | 9 +++------ board/bf533-ezkit/flash-defines.h | 4 +--- board/bf533-ezkit/flash.c | 4 ++++ 3 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/board/bf533-ezkit/bf533-ezkit.c b/board/bf533-ezkit/bf533-ezkit.c index 42c4b50..6973082 100644 --- a/board/bf533-ezkit/bf533-ezkit.c +++ b/board/bf533-ezkit/bf533-ezkit.c @@ -1,7 +1,7 @@ /* - * U-boot - ezkit533.c + * U-boot - main board file * - * 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. @@ -26,9 +26,8 @@ */
#include <common.h> -#if defined(CONFIG_MISC_INIT_R) #include "psd4256.h" -#endif +#include "flash-defines.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -58,7 +57,6 @@ phys_size_t initdram(int board_type) return CONFIG_SYS_MAX_RAM_SIZE; }
-#if defined(CONFIG_MISC_INIT_R) /* miscellaneous platform dependent initialisations */ int misc_init_r(void) { @@ -71,4 +69,3 @@ int misc_init_r(void)
return 0; } -#endif diff --git a/board/bf533-ezkit/flash-defines.h b/board/bf533-ezkit/flash-defines.h index 1a4aa5f..eb0af94 100644 --- a/board/bf533-ezkit/flash-defines.h +++ b/board/bf533-ezkit/flash-defines.h @@ -50,6 +50,7 @@ #define FLASH_SIZE 0x220000 #define FLASH_MAN_ST 2 #define CONFIG_SYS_FLASH0_BASE 0x20000000 +#define CONFIG_SYS_FLASH1_BASE 0x20200000 #define RESET_VAL 0xF0
flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; @@ -68,9 +69,6 @@ int write_flash(long nOffset, int nValue); void get_sector_number(long lOffset, int *pnSector); int GetSectorProtectionStatus(flash_info_t * info, int nSector); int GetOffset(int nBlock); -int AFP_NumSectors = 40; -long AFP_SectorSize1 = 0x10000; -int AFP_SectorSize2 = 0x4000;
#define WRITESEQ1 0x0AAA #define WRITESEQ2 0x0554 diff --git a/board/bf533-ezkit/flash.c b/board/bf533-ezkit/flash.c index a861e16..539c00d 100644 --- a/board/bf533-ezkit/flash.c +++ b/board/bf533-ezkit/flash.c @@ -29,6 +29,10 @@ #include <asm/io.h> #include "flash-defines.h"
+int AFP_NumSectors = 40; +long AFP_SectorSize1 = 0x10000; +int AFP_SectorSize2 = 0x4000; + void flash_reset(void) { reset_flash();

The DEBUG code in initdram() is quite old and was never really useful, so just drop it altogether. Common Blackfin debug code does a better job.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- board/bf533-ezkit/bf533-ezkit.c | 14 +------------- board/bf533-stamp/bf533-stamp.c | 11 +---------- board/bf537-stamp/bf537-stamp.c | 14 +------------- board/bf561-ezkit/bf561-ezkit.c | 14 +------------- 4 files changed, 4 insertions(+), 49 deletions(-)
diff --git a/board/bf533-ezkit/bf533-ezkit.c b/board/bf533-ezkit/bf533-ezkit.c index 6973082..d5f0b7c 100644 --- a/board/bf533-ezkit/bf533-ezkit.c +++ b/board/bf533-ezkit/bf533-ezkit.c @@ -40,21 +40,9 @@ int checkboard(void)
phys_size_t initdram(int board_type) { -#ifdef DEBUG - int brate; - char *tmp = getenv("baudrate"); - brate = simple_strtoul(tmp, NULL, 16); - printf("Serial Port initialized with Baud rate = %x\n", brate); - printf("SDRAM attributes:\n"); - printf("tRCD %d SCLK Cycles,tRP %d SCLK Cycles,tRAS %d SCLK Cycles" - "tWR %d SCLK Cycles,CAS Latency %d SCLK cycles \n", - 3, 3, 6, 2, 3); - printf("SDRAM Begin: 0x%x\n", CONFIG_SYS_SDRAM_BASE); - printf("Bank size = %d MB\n", CONFIG_SYS_MAX_RAM_SIZE >> 20); -#endif gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; gd->bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE; - return CONFIG_SYS_MAX_RAM_SIZE; + return gd->bd->bi_memsize; }
/* miscellaneous platform dependent initialisations */ diff --git a/board/bf533-stamp/bf533-stamp.c b/board/bf533-stamp/bf533-stamp.c index 0c6324b..1a073a6 100644 --- a/board/bf533-stamp/bf533-stamp.c +++ b/board/bf533-stamp/bf533-stamp.c @@ -49,18 +49,9 @@ int checkboard(void)
phys_size_t initdram(int board_type) { -#ifdef DEBUG - printf("SDRAM attributes:\n"); - printf - (" tRCD:%d Cycles; tRP:%d Cycles; tRAS:%d Cycles; tWR:%d Cycles; " - "CAS Latency:%d cycles\n", (SDRAM_tRCD >> 15), (SDRAM_tRP >> 11), - (SDRAM_tRAS >> 6), (SDRAM_tWR >> 19), (SDRAM_CL >> 2)); - printf("SDRAM Begin: 0x%x\n", CONFIG_SYS_SDRAM_BASE); - printf("Bank size = %d MB\n", 128); -#endif gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; gd->bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE; - return (gd->bd->bi_memsize); + return gd->bd->bi_memsize; }
void swap_to(int device_id) diff --git a/board/bf537-stamp/bf537-stamp.c b/board/bf537-stamp/bf537-stamp.c index 7303f1b..63992f6 100644 --- a/board/bf537-stamp/bf537-stamp.c +++ b/board/bf537-stamp/bf537-stamp.c @@ -100,21 +100,9 @@ void cf_outsw(unsigned short *addr, unsigned short *sect_buf, int words)
phys_size_t initdram(int board_type) { -#ifdef DEBUG - int brate; - char *tmp = getenv("baudrate"); - brate = simple_strtoul(tmp, NULL, 16); - printf("Serial Port initialized with Baud rate = %x\n", brate); - printf("SDRAM attributes:\n"); - printf("tRCD %d SCLK Cycles,tRP %d SCLK Cycles,tRAS %d SCLK Cycles" - "tWR %d SCLK Cycles,CAS Latency %d SCLK cycles \n", - 3, 3, 6, 2, 3); - printf("SDRAM Begin: 0x%x\n", CONFIG_SYS_SDRAM_BASE); - printf("Bank size = %d MB\n", CONFIG_SYS_MAX_RAM_SIZE >> 20); -#endif gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; gd->bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE; - return CONFIG_SYS_MAX_RAM_SIZE; + return gd->bd->bi_memsize; }
#if defined(CONFIG_MISC_INIT_R) diff --git a/board/bf561-ezkit/bf561-ezkit.c b/board/bf561-ezkit/bf561-ezkit.c index 7f8598c..5aede17 100644 --- a/board/bf561-ezkit/bf561-ezkit.c +++ b/board/bf561-ezkit/bf561-ezkit.c @@ -39,19 +39,7 @@ int checkboard(void)
phys_size_t initdram(int board_type) { -#ifdef DEBUG - int brate; - char *tmp = getenv("baudrate"); - brate = simple_strtoul(tmp, NULL, 16); - printf("Serial Port initialized with Baud rate = %x\n", brate); - printf("SDRAM attributes:\n"); - printf("tRCD %d SCLK Cycles,tRP %d SCLK Cycles,tRAS %d SCLK Cycles" - "tWR %d SCLK Cycles,CAS Latency %d SCLK cycles \n", - 3, 3, 6, 2, 3); - printf("SDRAM Begin: 0x%x\n", CONFIG_SYS_SDRAM_BASE); - printf("Bank size = %d MB\n", CONFIG_SYS_MAX_RAM_SIZE >> 20); -#endif gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; gd->bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE; - return CONFIG_SYS_MAX_RAM_SIZE; + return gd->bd->bi_memsize; }

Signed-off-by: Mike Frysinger vapier@gentoo.org --- board/bf537-stamp/nand.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/board/bf537-stamp/nand.c b/board/bf537-stamp/nand.c index 20a7d0e..2866834 100644 --- a/board/bf537-stamp/nand.c +++ b/board/bf537-stamp/nand.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2006 Aubrey.Li, aubrey.li@analog.com + * Copyright (c) 2006-2007 Analog Devices Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -43,11 +43,11 @@ static void bfin_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) u32 IO_ADDR_W = (u32) this->IO_ADDR_W;
if (ctrl & NAND_CTRL_CHANGE) { - if( ctrl & NAND_CLE ) + if (ctrl & NAND_CLE) IO_ADDR_W = CONFIG_SYS_NAND_BASE + BFIN_NAND_CLE; else IO_ADDR_W = CONFIG_SYS_NAND_BASE; - if( ctrl & NAND_ALE ) + if (ctrl & NAND_ALE) IO_ADDR_W = CONFIG_SYS_NAND_BASE + BFIN_NAND_ALE; else IO_ADDR_W = CONFIG_SYS_NAND_BASE;

No functional changes here; just cleanup code style a bit.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- board/bf537-stamp/post-memory.c | 23 +++++++++++------------ 1 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/board/bf537-stamp/post-memory.c b/board/bf537-stamp/post-memory.c index 889aa5c..9626f4c 100644 --- a/board/bf537-stamp/post-memory.c +++ b/board/bf537-stamp/post-memory.c @@ -21,10 +21,10 @@ int post_init_sdram(int sclk); void post_init_uart(int sclk);
const int pll[CCLK_NUM][SCLK_NUM][2] = { - {{20, 4}, {20, 5}, {20, 10}}, /* CCLK = 500M */ - {{16, 4}, {16, 5}, {16, 8}}, /* CCLK = 400M */ - {{8, 2}, {8, 4}, {8, 5}}, /* CCLK = 200M */ - {{4, 1}, {4, 2}, {4, 4}} /* CCLK = 100M */ + { {20, 4}, {20, 5}, {20, 10} }, /* CCLK = 500M */ + { {16, 4}, {16, 5}, {16, 8} }, /* CCLK = 400M */ + { {8, 2}, {8, 4}, {8, 5} }, /* CCLK = 200M */ + { {4, 1}, {4, 2}, {4, 4} } /* CCLK = 100M */ }; const char *const log[CCLK_NUM][SCLK_NUM] = { {"CCLK-500MHz SCLK-125MHz: Writing...\0", @@ -119,7 +119,8 @@ void post_out_buff(char *buff) {
int i = 0; - for (i = 0; i < 0x80000; i++) ; + for (i = 0; i < 0x80000; i++) + ; i = 0; while ((buff[i] != '\0') && (i != 100)) { while (!(*pUART_LSR & 0x20)) ; @@ -127,7 +128,8 @@ void post_out_buff(char *buff) SSYNC(); i++; } - for (i = 0; i < 0x80000; i++) ; + for (i = 0; i < 0x80000; i++) + ; }
/* Using sw10-PF5 as the hotkey */ @@ -150,9 +152,8 @@ int post_key_pressed(void) value = 0; goto key_pressed; } - if (value != 0) { + if (value != 0) goto key_pressed; - } for (n = 0; n < KEY_DELAY; n++) asm("nop"); } @@ -164,9 +165,8 @@ int post_key_pressed(void) value = 0; goto key_pressed; } - if (value != 0) { + if (value != 0) goto key_pressed; - } for (n = 0; n < KEY_DELAY; n++) asm("nop"); } @@ -178,9 +178,8 @@ int post_key_pressed(void) value = 0; goto key_pressed; } - if (value != 0) { + if (value != 0) goto key_pressed; - } for (n = 0; n < KEY_DELAY; n++) asm("nop"); }

This video driver used to live in the Blackfin cpu directory, but it was lost during the unification process. This brings it back.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- board/bf533-stamp/Makefile | 9 ++- board/bf533-stamp/video.c | 167 ++++++++++++++++++++++++++++++++++++++++++++ board/bf533-stamp/video.h | 25 +++++++ 3 files changed, 197 insertions(+), 4 deletions(-) create mode 100644 board/bf533-stamp/video.c create mode 100644 board/bf533-stamp/video.h
diff --git a/board/bf533-stamp/Makefile b/board/bf533-stamp/Makefile index 5ae0228..5b5e199 100644 --- a/board/bf533-stamp/Makefile +++ b/board/bf533-stamp/Makefile @@ -1,7 +1,7 @@ # # U-boot - Makefile # -# Copyright (c) 2005-2007 Analog Device Inc. +# Copyright (c) 2005-2008 Analog Device Inc. # # (C) Copyright 2000-2006 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -29,10 +29,11 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS := $(BOARD).o spi_flash.o +COBJS-y := $(BOARD).o spi_flash.o +COBJS-$(CONFIG_VIDEO) += video.o
-SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) SOBJS := $(addprefix $(obj),$(SOBJS))
$(LIB): $(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds diff --git a/board/bf533-stamp/video.c b/board/bf533-stamp/video.c new file mode 100644 index 0000000..3c15eaa --- /dev/null +++ b/board/bf533-stamp/video.c @@ -0,0 +1,167 @@ +/* + * BF533-STAMP splash driver + * + * Copyright (c) 2006-2008 Analog Devices Inc. + * (C) Copyright 2000 + * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it + * (C) Copyright 2002 + * Wolfgang Denk, wd@denx.de + * + * Licensed under the GPL-2 or later. + */ + +#include <stdarg.h> +#include <common.h> +#include <config.h> +#include <malloc.h> +#include <asm/blackfin.h> +#include <asm/mach-common/bits/dma.h> +#include <i2c.h> +#include <linux/types.h> +#include <devices.h> + +int gunzip(void *, int, unsigned char *, unsigned long *); + +#define DMA_SIZE16 2 + +#include <asm/mach-common/bits/ppi.h> + +#define NTSC_FRAME_ADDR 0x06000000 +#include "video.h" + +/* NTSC OUTPUT SIZE 720 * 240 */ +#define VERTICAL 2 +#define HORIZONTAL 4 + +int is_vblank_line(const int line) +{ + /* + * This array contains a single bit for each line in + * an NTSC frame. + */ + if ((line <= 18) || (line >= 264 && line <= 281) || (line == 528)) + return true; + + return false; +} + +int NTSC_framebuffer_init(char *base_address) +{ + const int NTSC_frames = 1; + const int NTSC_lines = 525; + char *dest = base_address; + int frame_num, line_num; + + for (frame_num = 0; frame_num < NTSC_frames; ++frame_num) { + for (line_num = 1; line_num <= NTSC_lines; ++line_num) { + unsigned int code; + int offset = 0; + int i; + + if (is_vblank_line(line_num)) + offset++; + + if (line_num > 266 || line_num < 3) + offset += 2; + + /* Output EAV code */ + code = system_code_map[offset].eav; + write_dest_byte((char)(code >> 24) & 0xff); + write_dest_byte((char)(code >> 16) & 0xff); + write_dest_byte((char)(code >> 8) & 0xff); + write_dest_byte((char)(code) & 0xff); + + /* Output horizontal blanking */ + for (i = 0; i < 67 * 2; ++i) { + write_dest_byte(0x80); + write_dest_byte(0x10); + } + + /* Output SAV */ + code = system_code_map[offset].sav; + write_dest_byte((char)(code >> 24) & 0xff); + write_dest_byte((char)(code >> 16) & 0xff); + write_dest_byte((char)(code >> 8) & 0xff); + write_dest_byte((char)(code) & 0xff); + + /* Output empty horizontal data */ + for (i = 0; i < 360 * 2; ++i) { + write_dest_byte(0x80); + write_dest_byte(0x10); + } + } + } + + return dest - base_address; +} + +void fill_frame(char *Frame, int Value) +{ + int *OddPtr32; + int OddLine; + int *EvenPtr32; + int EvenLine; + int i; + int *data; + int m, n; + + /* fill odd and even frames */ + for (OddLine = 22, EvenLine = 285; OddLine < 263; OddLine++, EvenLine++) { + OddPtr32 = (int *)((Frame + (OddLine * 1716)) + 276); + EvenPtr32 = (int *)((Frame + (EvenLine * 1716)) + 276); + for (i = 0; i < 360; i++, OddPtr32++, EvenPtr32++) { + *OddPtr32 = Value; + *EvenPtr32 = Value; + } + } + + for (m = 0; m < VERTICAL; m++) { + data = (int *)u_boot_logo.data; + for (OddLine = (22 + m), EvenLine = (285 + m); + OddLine < (u_boot_logo.height * VERTICAL) + (22 + m); + OddLine += VERTICAL, EvenLine += VERTICAL) { + OddPtr32 = (int *)((Frame + ((OddLine) * 1716)) + 276); + EvenPtr32 = + (int *)((Frame + ((EvenLine) * 1716)) + 276); + for (i = 0; i < u_boot_logo.width / 2; i++) { + /* enlarge one pixel to m x n */ + for (n = 0; n < HORIZONTAL; n++) { + *OddPtr32++ = *data; + *EvenPtr32++ = *data; + } + data++; + } + } + } +} + +static void video_init(char *NTSCFrame) +{ + NTSC_framebuffer_init(NTSCFrame); + fill_frame(NTSCFrame, BLUE); + + bfin_write_PPI_CONTROL(0x0082); + bfin_write_PPI_FRAME(0x020D); + + bfin_write_DMA0_START_ADDR(NTSCFrame); + bfin_write_DMA0_X_COUNT(0x035A); + bfin_write_DMA0_X_MODIFY(0x0002); + bfin_write_DMA0_Y_COUNT(0x020D); + bfin_write_DMA0_Y_MODIFY(0x0002); + bfin_write_DMA0_CONFIG(0x1015); + bfin_write_PPI_CONTROL(0x0083); +} + +int drv_video_init(void) +{ + device_t videodev; + + video_init((void *)NTSC_FRAME_ADDR); + + memset(&videodev, 0, sizeof(videodev)); + strcpy(videodev.name, "video"); + videodev.ext = DEV_EXT_VIDEO; + videodev.flags = DEV_FLAGS_SYSTEM; + + return device_register(&videodev); +} diff --git a/board/bf533-stamp/video.h b/board/bf533-stamp/video.h new file mode 100644 index 0000000..80837e2 --- /dev/null +++ b/board/bf533-stamp/video.h @@ -0,0 +1,25 @@ +#include <video_logo.h> +#define write_dest_byte(val) {*dest++=val;} +#define BLACK (0x01800180) /* black pixel pattern */ +#define BLUE (0x296E29F0) /* blue pixel pattern */ +#define RED (0x51F0515A) /* red pixel pattern */ +#define MAGENTA (0x6ADE6ACA) /* magenta pixel pattern */ +#define GREEN (0x91229136) /* green pixel pattern */ +#define CYAN (0xAA10AAA6) /* cyan pixel pattern */ +#define YELLOW (0xD292D210) /* yellow pixel pattern */ +#define WHITE (0xFE80FE80) /* white pixel pattern */ + +#define true 1 +#define false 0 + +typedef struct { + unsigned int sav; + unsigned int eav; +} system_code_type; + +const system_code_type system_code_map[] = { + { 0xFF000080, 0xFF00009D }, + { 0xFF0000AB, 0xFF0000B6 }, + { 0xFF0000C7, 0xFF0000DA }, + { 0xFF0000EC, 0xFF0000F1 }, +};

Signed-off-by: Mike Frysinger vapier@gentoo.org --- board/bf533-stamp/bf533-stamp.h | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/board/bf533-stamp/bf533-stamp.h b/board/bf533-stamp/bf533-stamp.h index 3b0d620..ebd39c7 100644 --- a/board/bf533-stamp/bf533-stamp.h +++ b/board/bf533-stamp/bf533-stamp.h @@ -34,9 +34,6 @@ extern volatile unsigned long *ambctl0; extern volatile unsigned long *ambctl1; extern volatile unsigned long *amgctl;
-extern unsigned long pll_div_fact; -extern void serial_setbrg(void); - /* Definitions used in Compact Flash Boot support */ #define FIO_EDGE_CF_BITS 0x0000 #define FIO_POLAR_CF_BITS 0x0000

The BF538/BF539 use CS2 for booting off of rather than CS1 like newer Blackfin parts.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- board/bf537-stamp/spi_flash.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/board/bf537-stamp/spi_flash.c b/board/bf537-stamp/spi_flash.c index 11a2803..a99c3fa 100644 --- a/board/bf537-stamp/spi_flash.c +++ b/board/bf537-stamp/spi_flash.c @@ -182,8 +182,8 @@ static struct manufacturer_info flash_manufacturers[] = { * BF533, BF561: SSEL2 */ #ifndef CONFIG_SPI_FLASH_SSEL -# if defined(__ADSPBF531__) || defined(__ADSPBF532__) || \ - defined(__ADSPBF533__) || defined(__ADSPBF561__) +# if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \ + defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__) # define CONFIG_SPI_FLASH_SSEL 2 # else # define CONFIG_SPI_FLASH_SSEL 1

Rather than using a local custom memcpy function, just call the existing optimized Blackfin version.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- cpu/blackfin/start.S | 32 +++++++++++--------------------- 1 files changed, 11 insertions(+), 21 deletions(-)
diff --git a/cpu/blackfin/start.S b/cpu/blackfin/start.S index 9975a0c..6c5fef7 100644 --- a/cpu/blackfin/start.S +++ b/cpu/blackfin/start.S @@ -125,8 +125,9 @@ ENTRY(_start) */ r6 = 1 (x);
- /* Relocate from wherever are (FLASH/RAM/etc...) to the - * hardcoded monitor location in the end of RAM. + /* Relocate from wherever are (FLASH/RAM/etc...) to the hardcoded + * monitor location in the end of RAM. We know that memcpy() only + * uses registers, so it is safe to call here. */ serial_early_puts("Relocate"); call _get_pc; @@ -135,27 +136,16 @@ ENTRY(_start) r2.h = .Loffset; r3.l = _start; r3.h = _start; - r1 = r2 - r3; - - r0 = r0 - r1; - - cc = r0 == r3; + r2 = r2 - r3; + r1 = r0 - r2; + cc = r1 == r3; if cc jump .Lnorelocate; - r6 = 0 (x); - p1 = r0; - - p2.l = LO(CONFIG_SYS_MONITOR_BASE); - p2.h = HI(CONFIG_SYS_MONITOR_BASE); - - p3 = 0x04; - p4.l = LO(CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN); - p4.h = HI(CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN); -.Lloop1: - r1 = [p1 ++ p3]; - [p2 ++ p3] = r1; - cc=p2==p4; - if !cc jump .Lloop1; + + r0 = r3; + r2.l = LO(CONFIG_SYS_MONITOR_LEN); + r2.h = HI(CONFIG_SYS_MONITOR_LEN); + call _memcpy_ASM;
/* Initialize BSS section ... we know that memset() does not * use the BSS, so it is safe to call here. The bootrom LDR

As pointed out by Ivan Koryakovskiy, the initialization code was not actually respecting the CONFIG_CLKIN_HALF option when configuring the PLL_CTL register.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- cpu/blackfin/initcode.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/cpu/blackfin/initcode.c b/cpu/blackfin/initcode.c index ffc8420..e733dd2 100644 --- a/cpu/blackfin/initcode.c +++ b/cpu/blackfin/initcode.c @@ -158,7 +158,7 @@ static inline void serial_putc(char c) #endif
#ifndef CONFIG_PLL_CTL_VAL -# define CONFIG_PLL_CTL_VAL (SPORT_HYST | (CONFIG_VCO_MULT << 9)) +# define CONFIG_PLL_CTL_VAL (SPORT_HYST | (CONFIG_VCO_MULT << 9) | CONFIG_CLKIN_HALF) #endif
#ifndef CONFIG_EBIU_RSTCTL_VAL

Signed-off-by: Mike Frysinger vapier@gentoo.org --- cpu/blackfin/serial.h | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/cpu/blackfin/serial.h b/cpu/blackfin/serial.h index ec40c26..90fceec 100644 --- a/cpu/blackfin/serial.h +++ b/cpu/blackfin/serial.h @@ -95,7 +95,16 @@ __attribute__((always_inline)) static inline void serial_do_portmux(void) { -#ifdef __ADSPBF52x__ +#if defined(__ADSPBF51x__) +# define DO_MUX(port, mux_tx, mux_rx, tx, rx) \ + bfin_write_PORT##port##_MUX((bfin_read_PORT##port##_MUX() & ~(PORT_x_MUX_##mux_tx##_MASK | PORT_x_MUX_##mux_rx##_MASK)) | PORT_x_MUX_##mux_tx##_FUNC_2 | PORT_x_MUX_##mux_rx##_FUNC_2); \ + 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, 5, 5, 9, 10); break; /* Port G; mux 5; PG9 and PG10 */ + case 1: DO_MUX(F, 2, 3, 14, 15); break; /* Port H; mux 2/3; PH14 and PH15 */ + } + SSYNC(); +#elif defined(__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);

No need to set the SP register indirectly to the configured value when it can be set directly.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- cpu/blackfin/start.S | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/cpu/blackfin/start.S b/cpu/blackfin/start.S index 6c5fef7..8617c98 100644 --- a/cpu/blackfin/start.S +++ b/cpu/blackfin/start.S @@ -163,9 +163,8 @@ ENTRY(_start) .Lnorelocate:
/* Setup the actual stack in external memory */ - r0.h = HI(CONFIG_STACKBASE); - r0.l = LO(CONFIG_STACKBASE); - sp = r0; + sp.h = HI(CONFIG_STACKBASE); + sp.l = LO(CONFIG_STACKBASE); fp = sp;
/* Now lower ourselves from the highest interrupt level to

People often ask questions about the init process and when things go from flash to relocated base, so clarify the comments a bit.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- cpu/blackfin/start.S | 10 +++++++--- 1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/cpu/blackfin/start.S b/cpu/blackfin/start.S index 8617c98..6c8def4 100644 --- a/cpu/blackfin/start.S +++ b/cpu/blackfin/start.S @@ -125,9 +125,11 @@ ENTRY(_start) */ r6 = 1 (x);
- /* Relocate from wherever are (FLASH/RAM/etc...) to the hardcoded + /* Relocate from wherever we are (FLASH/RAM/etc...) to the hardcoded * monitor location in the end of RAM. We know that memcpy() only - * uses registers, so it is safe to call here. + * uses registers, so it is safe to call here. Note that this only + * copies to external memory ... we do not start executing out of + * it yet (see "lower to 15" below). */ serial_early_puts("Relocate"); call _get_pc; @@ -172,7 +174,9 @@ ENTRY(_start) * setting the 15 handler to ".Lenable_nested", 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. + * services the pending 15 interrupt. If executing out of + * flash, these steps also changes the code flow from flash + * to external memory. */ serial_early_puts("Lower to 15"); r0 = r7;

Make sure we save the value of RETX at power on and then pass it on to the kernel so that it can nicely debug a "double-fault-caused-a-reset" crash.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- cpu/blackfin/cpu.c | 6 ++++++ lib_blackfin/boot.c | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletions(-)
diff --git a/cpu/blackfin/cpu.c b/cpu/blackfin/cpu.c index 9efd88e..30c214b 100644 --- a/cpu/blackfin/cpu.c +++ b/cpu/blackfin/cpu.c @@ -14,11 +14,14 @@ #include <asm/blackfin.h> #include <asm/cplb.h> #include <asm/mach-common/bits/core.h> +#include <asm/mach-common/bits/ebiu.h> #include <asm/mach-common/bits/trace.h>
#include "cpu.h" #include "serial.h"
+ulong bfin_poweron_retx; + __attribute__ ((__noreturn__)) void cpu_init_f(ulong bootflag, ulong loaded_from_ldr) { @@ -48,6 +51,9 @@ void cpu_init_f(ulong bootflag, ulong loaded_from_ldr) bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL); #endif
+ /* Save RETX so we can pass it while booting Linux */ + bfin_poweron_retx = bootflag; + #ifdef CONFIG_DEBUG_DUMP /* Turn on hardware trace buffer */ bfin_write_TBUFCTL(TBUFPWR | TBUFEN); diff --git a/lib_blackfin/boot.c b/lib_blackfin/boot.c index 47e27de..537be2b 100644 --- a/lib_blackfin/boot.c +++ b/lib_blackfin/boot.c @@ -31,6 +31,8 @@ static char *make_command_line(void) return dest; }
+extern ulong bfin_poweron_retx; + int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) { int (*appl) (char *cmdline); @@ -49,7 +51,12 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) cmdline = make_command_line(); icache_disable(); dcache_disable(); - (*appl) (cmdline); + asm __volatile__( + "RETX = %[retx];" + "CALL (%0);" + : + : "p"(appl), "q0"(cmdline), [retx] "d"(bfin_poweron_retx) + ); /* does not return */
return 1;

Workaround fun new anomalies related to software reset of the processor.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- cpu/blackfin/reset.c | 20 +++++++++++++++----- 1 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/cpu/blackfin/reset.c b/cpu/blackfin/reset.c index d1e34b3..284cea5 100644 --- a/cpu/blackfin/reset.c +++ b/cpu/blackfin/reset.c @@ -29,26 +29,35 @@ void bfin_reset(void) */ __builtin_bfin_ssync();
- while (1) { + /* The bootrom checks to see how it was reset and will + * automatically perform a software reset for us when + * it starts executing after the core reset. + */ + if (ANOMALY_05000353 || ANOMALY_05000386) { /* 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, + * to delay for 10 SCLKS. The only reliable way to do this is + * to calculate the CCLK/SCLK ratio and multiply 10. 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) + : "a" (15 * 10) : "LC0", "LB0", "LT0" );
/* Clear System software reset */ bfin_write_SWRST(0);
+ /* The BF526 ROM will crash during reset */ +#if defined(__ADSPBF522__) || defined(__ADSPBF524__) || defined(__ADSPBF526__) + bfin_read_SWRST(); +#endif + /* Wait for the SWRST write to complete. Cannot rely on SSYNC * though as the System state is all reset now. */ @@ -59,10 +68,11 @@ void bfin_reset(void) : "a" (15 * 1) : "LC1", "LB1", "LT1" ); + }
+ while (1) /* Issue core reset */ asm("raise 1"); - } }
/* We need to trampoline ourselves up into L1 since our linker

The Blackfin JTAG has the ability to pass data via a back-channel without halting the processor. Utilize that channel to emulate a console.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- common/devices.c | 3 + cpu/blackfin/Makefile | 9 ++-- cpu/blackfin/jtag-console.c | 125 +++++++++++++++++++++++++++++++++++++++++++ include/devices.h | 3 + 4 files changed, 136 insertions(+), 4 deletions(-) create mode 100644 cpu/blackfin/jtag-console.c
diff --git a/common/devices.c b/common/devices.c index ce3b7a0..38f1bbc 100644 --- a/common/devices.c +++ b/common/devices.c @@ -240,6 +240,9 @@ int devices_init (void) #ifdef CONFIG_NETCONSOLE drv_nc_init (); #endif +#ifdef CONFIG_JTAG_CONSOLE + drv_jtag_console_init (); +#endif
return (0); } diff --git a/cpu/blackfin/Makefile b/cpu/blackfin/Makefile index b90fb48..b4049ff 100644 --- a/cpu/blackfin/Makefile +++ b/cpu/blackfin/Makefile @@ -17,14 +17,15 @@ EXTRA := CEXTRA := initcode.o SEXTRA := start.o SOBJS := interrupt.o cache.o -COBJS := cpu.o traps.o interrupts.o reset.o serial.o watchdog.o +COBJS-y := cpu.o traps.o interrupts.o reset.o serial.o watchdog.o +COBJS-$(CONFIG_JTAG_CONSOLE) += jtag-console.o
ifeq ($(CONFIG_BFIN_BOOT_MODE),BFIN_BOOT_BYPASS) -COBJS += initcode.o +COBJS-y += initcode.o endif
-SRCS := $(SEXTRA:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +SRCS := $(SEXTRA:.o=.S) $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y) $(SOBJS)) EXTRA := $(addprefix $(obj),$(EXTRA)) CEXTRA := $(addprefix $(obj),$(CEXTRA)) SEXTRA := $(addprefix $(obj),$(SEXTRA)) diff --git a/cpu/blackfin/jtag-console.c b/cpu/blackfin/jtag-console.c new file mode 100644 index 0000000..44c0a83 --- /dev/null +++ b/cpu/blackfin/jtag-console.c @@ -0,0 +1,125 @@ +/* + * jtag-console.c - console driver over Blackfin JTAG + * + * Copyright (c) 2008 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <common.h> +#include <devices.h> +#include <asm/blackfin.h> + +#ifndef CONFIG_JTAG_CONSOLE_TIMEOUT +# define CONFIG_JTAG_CONSOLE_TIMEOUT 100 +#endif + +/* The Blackfin tends to be much much faster than the JTAG hardware. */ +static void jtag_write_emudat(uint32_t emudat) +{ + static bool overflowed = false; + ulong timeout = get_timer(0) + CONFIG_JTAG_CONSOLE_TIMEOUT; + while (bfin_read_DBGSTAT() & 0x1) { + if (overflowed) + return; + if (timeout < get_timer(0)) + overflowed = true; + } + overflowed = false; + __asm__ __volatile__("emudat = %0;" : : "d"(emudat)); +} +/* Transmit a buffer. The format is: + * [32bit length][actual data] + */ +static void jtag_send(const char *c, uint32_t len) +{ + uint32_t i; + + if (len == 0) + return; + + /* First send the length */ + jtag_write_emudat(len); + + /* Then send the data */ + for (i = 0; i < len; i += 4) + jtag_write_emudat((c[i] << 0) | (c[i+1] << 8) | (c[i+2] << 16) | (c[i+3] << 24)); +} +static void jtag_putc(const char c) +{ + jtag_send(&c, 1); +} +static void jtag_puts(const char *s) +{ + jtag_send(s, strlen(s)); +} + +static int jtag_tstc(void) +{ + return (bfin_read_DBGSTAT() & 0x2); +} + +/* Receive a buffer. The format is: + * [32bit length][actual data] + */ +static size_t inbound_len; +static int leftovers_len; +static uint32_t leftovers; +static int jtag_getc(void) +{ + int ret; + uint32_t emudat; + + /* see if any data is left over */ + if (leftovers_len) { + --leftovers_len; + ret = leftovers & 0xff; + leftovers >>= 8; + return ret; + } + + /* wait for new data ! */ + while (!jtag_tstc()) + continue; + __asm__("%0 = emudat;" : "=d"(emudat)); + + if (inbound_len == 0) { + /* grab the length */ + inbound_len = emudat; + } else { + /* store the bytes */ + leftovers_len = min(4, inbound_len); + inbound_len -= leftovers_len; + leftovers = emudat; + } + + return jtag_getc(); +} + +int drv_jtag_console_init(void) +{ + device_t dev; + int ret; + + memset(&dev, 0x00, sizeof(dev)); + strcpy(dev.name, "jtag"); + dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; + dev.putc = jtag_putc; + dev.puts = jtag_puts; + dev.tstc = jtag_tstc; + dev.getc = jtag_getc; + + ret = device_register(&dev); + return (ret == 0 ? 1 : ret); +} + +#ifdef CONFIG_UART_CONSOLE_IS_JTAG +/* Since the JTAG is always available (at power on), allow it to fake a UART */ +void serial_set_baud(uint32_t baud) {} +void serial_setbrg(void) {} +int serial_init(void) { return 0; } +void serial_putc(const char c) __attribute__((alias("jtag_putc"))); +void serial_puts(const char *s) __attribute__((alias("jtag_puts"))); +int serial_tstc(void) __attribute__((alias("jtag_tstc"))); +int serial_getc(void) __attribute__((alias("jtag_getc"))); +#endif diff --git a/include/devices.h b/include/devices.h index 20ddfc4..84c4514 100644 --- a/include/devices.h +++ b/include/devices.h @@ -116,5 +116,8 @@ int drv_usbtty_init (void); #ifdef CONFIG_NETCONSOLE int drv_nc_init (void); #endif +#ifdef CONFIG_JTAG_CONSOLE +int drv_jtag_console_init (void); +#endif
#endif /* _DEVICES_H_ */

Some devices have no UART device pulled out, so allow people to disable the driver completely in favor of other methods (like JTAG-console).
Signed-off-by: Mike Frysinger vapier@gentoo.org --- cpu/blackfin/serial.c | 4 ++++ cpu/blackfin/serial.h | 4 ++++ 2 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/cpu/blackfin/serial.c b/cpu/blackfin/serial.c index 0d6f377..42534bd 100644 --- a/cpu/blackfin/serial.c +++ b/cpu/blackfin/serial.c @@ -29,6 +29,8 @@ #include <asm/blackfin.h> #include <asm/mach-common/bits/uart.h>
+#ifdef CONFIG_UART_CONSOLE + #if defined(UART_LSR) && (CONFIG_UART_CONSOLE != 0) # error CONFIG_UART_CONSOLE must be 0 on parts with only one UART #endif @@ -170,3 +172,5 @@ void serial_puts(const char *s) while (*s) serial_putc(*s++); } + +#endif diff --git a/cpu/blackfin/serial.h b/cpu/blackfin/serial.h index 90fceec..f671096 100644 --- a/cpu/blackfin/serial.h +++ b/cpu/blackfin/serial.h @@ -14,6 +14,10 @@ #include <asm/blackfin.h> #include <asm/mach-common/bits/uart.h>
+#ifndef CONFIG_UART_CONSOLE +# define CONFIG_UART_CONSOLE 0 +#endif + #ifdef CONFIG_DEBUG_EARLY_SERIAL # define BFIN_DEBUG_EARLY_SERIAL 1 #else

This brings the API for the on-chip ROM in line with the toolchain and hardware documentation.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- include/asm-blackfin/mach-common/bits/bootrom.h | 63 ++++++++++++---------- include/asm-blackfin/mach-common/bits/otp.h | 21 ++++---- 2 files changed, 44 insertions(+), 40 deletions(-)
diff --git a/include/asm-blackfin/mach-common/bits/bootrom.h b/include/asm-blackfin/mach-common/bits/bootrom.h index bf661f0..fb97ff8 100644 --- a/include/asm-blackfin/mach-common/bits/bootrom.h +++ b/include/asm-blackfin/mach-common/bits/bootrom.h @@ -92,14 +92,6 @@
#define BOOTROM_CAPS_ADI_BOOT_STRUCTS 1
-/* Not available on initial BF54x or BF52x */ -#if (defined(__ADSPBF54x__) && __SILICON_REVISION__ < 1) || \ - (defined(__ADSPBF52x__) && __SILICON_REVISION__ < 2) -#define BOOTROM_CAPS_SYSCONTROL 0 -#else -#define BOOTROM_CAPS_SYSCONTROL 1 -#endif - #endif
#ifndef BOOTROM_FOLLOWS_C_ABI @@ -108,9 +100,21 @@ #ifndef BOOTROM_CAPS_ADI_BOOT_STRUCTS #define BOOTROM_CAPS_ADI_BOOT_STRUCTS 0 #endif -#ifndef BOOTROM_CAPS_SYSCONTROL -#define BOOTROM_CAPS_SYSCONTROL 0 -#endif + +/* Possible syscontrol action flags */ +#define SYSCTRL_READ 0x00000000 /* read registers */ +#define SYSCTRL_WRITE 0x00000001 /* write registers */ +#define SYSCTRL_SYSRESET 0x00000002 /* perform system reset */ +#define SYSCTRL_CORERESET 0x00000004 /* perform core reset */ +#define SYSCTRL_SOFTRESET 0x00000006 /* perform core and system reset */ +#define SYSCTRL_VRCTL 0x00000010 /* read/write VR_CTL register */ +#define SYSCTRL_EXTVOLTAGE 0x00000020 /* VDDINT supplied externally */ +#define SYSCTRL_INTVOLTAGE 0x00000000 /* VDDINT generated by on-chip regulator */ +#define SYSCTRL_OTPVOLTAGE 0x00000040 /* For Factory Purposes Only */ +#define SYSCTRL_PLLCTL 0x00000100 /* read/write PLL_CTL register */ +#define SYSCTRL_PLLDIV 0x00000200 /* read/write PLL_DIV register */ +#define SYSCTRL_LOCKCNT 0x00000400 /* read/write PLL_LOCKCNT register */ +#define SYSCTRL_PLLSTAT 0x00000800 /* read/write PLL_STAT register */
#ifndef __ASSEMBLY__
@@ -132,25 +136,26 @@ typedef struct ADI_SYSCTRL_VALUES { #ifndef _BOOTROM_SYSCONTROL #define _BOOTROM_SYSCONTROL 0 #endif -static uint32_t (* const syscontrol)(uint32_t action_flags, ADI_SYSCTRL_VALUES *power_settings, void *reserved) = (void *)_BOOTROM_SYSCONTROL; +static uint32_t (* const bfrom_SysControl)(uint32_t action_flags, ADI_SYSCTRL_VALUES *power_settings, void *reserved) = (void *)_BOOTROM_SYSCONTROL;
-#endif /* __ASSEMBLY__ */ - -/* Possible syscontrol action flags */ -#define SYSCTRL_READ 0x00000000 /* read registers */ -#define SYSCTRL_WRITE 0x00000001 /* write registers */ -#define SYSCTRL_SYSRESET 0x00000002 /* perform system reset */ -#define SYSCTRL_SOFTRESET 0x00000004 /* perform core and system reset */ -#define SYSCTRL_VRCTL 0x00000010 /* read/write VR_CTL register */ -#define SYSCTRL_EXTVOLTAGE 0x00000020 /* VDDINT supplied externally */ -#define SYSCTRL_INTVOLTAGE 0x00000000 /* VDDINT generated by on-chip regulator */ -#define SYSCTRL_OTPVOLTAGE 0x00000040 /* For Factory Purposes Only */ -#define SYSCTRL_PLLCTL 0x00000100 /* read/write PLL_CTL register */ -#define SYSCTRL_PLLDIV 0x00000200 /* read/write PLL_DIV register */ -#define SYSCTRL_LOCKCNT 0x00000400 /* read/write PLL_LOCKCNT register */ -#define SYSCTRL_PLLSTAT 0x00000800 /* read/write PLL_STAT register */ - -#ifndef __ASSEMBLY__ +/* We need a dedicated function since we need to screw with the stack pointer + * when resetting. The on-chip ROM will save/restore registers on the stack + * when doing a system reset, so the stack cannot be outside of the chip. + */ +__attribute__((__noreturn__)) +static inline void bfrom_SoftReset(void *new_stack) +{ + while (1) + __asm__ __volatile__( + "sp = %[stack];" + "jump (%[bfrom_syscontrol]);" + : : [bfrom_syscontrol] "p"(bfrom_SysControl), + "q0"(SYSCTRL_SOFTRESET), + "q1"(0), + "q2"(NULL), + [stack] "p"(new_stack) + ); +}
/* Structures for working with LDRs and boot rom callbacks */ typedef struct ADI_BOOT_HEADER { diff --git a/include/asm-blackfin/mach-common/bits/otp.h b/include/asm-blackfin/mach-common/bits/otp.h index d529a0a..4e3f1af 100644 --- a/include/asm-blackfin/mach-common/bits/otp.h +++ b/include/asm-blackfin/mach-common/bits/otp.h @@ -9,23 +9,22 @@
#include "bootrom.h"
-static uint32_t (* const otp_command)(uint32_t command, uint32_t value) = (void *)_BOOTROM_OTP_COMMAND; -static uint32_t (* const otp_read)(uint32_t page, uint32_t flags, uint64_t *page_content) = (void *)_BOOTROM_OTP_READ; -static uint32_t (* const otp_write)(uint32_t page, uint32_t flags, uint64_t *page_content) = (void *)_BOOTROM_OTP_WRITE; +static uint32_t (* const bfrom_OtpCommand)(uint32_t command, uint32_t value) = (void *)_BOOTROM_OTP_COMMAND; +static uint32_t (* const bfrom_OtpRead)(uint32_t page, uint32_t flags, uint64_t *page_content) = (void *)_BOOTROM_OTP_READ; +static uint32_t (* const bfrom_OtpWrite)(uint32_t page, uint32_t flags, uint64_t *page_content) = (void *)_BOOTROM_OTP_WRITE;
#endif
/* otp_command(): defines for "command" */ -#define OTP_INIT 0x00000001 -#define OTP_CLOSE 0x00000002 +#define OTP_INIT 0x00000001 +#define OTP_CLOSE 0x00000002
/* otp_{read,write}(): defines for "flags" */ -#define OTP_LOWER_HALF 0x00000000 /* select upper/lower 64-bit half (bit 0) */ -#define OTP_UPPER_HALF 0x00000001 -#define OTP_NO_ECC 0x00000010 /* do not use ECC */ -#define OTP_LOCK 0x00000020 /* sets page protection bit for page */ -#define OTP_ACCESS_READ 0x00001000 -#define OTP_ACCESS_READWRITE 0x00002000 +#define OTP_LOWER_HALF 0x00000000 /* select upper/lower 64-bit half (bit 0) */ +#define OTP_UPPER_HALF 0x00000001 +#define OTP_NO_ECC 0x00000010 /* do not use ECC */ +#define OTP_LOCK 0x00000020 /* sets page protection bit for page */ +#define OTP_CHECK_FOR_PREV_WRITE 0x00000080
/* Return values for all functions */ #define OTP_SUCCESS 0x00000000

Now that real documentation has been released for the OTP interface and the on-chip ROM wrt writing/timings, implement support for reading/writing as well as dumping/locking.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- common/cmd_otp.c | 157 +++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 115 insertions(+), 42 deletions(-)
diff --git a/common/cmd_otp.c b/common/cmd_otp.c index 825fa34..ce8c63b 100644 --- a/common/cmd_otp.c +++ b/common/cmd_otp.c @@ -6,7 +6,7 @@ * Licensed under the GPL-2 or later. */
-/* There are 512 128-bit "pages" (0x000 to 0x1FF). +/* There are 512 128-bit "pages" (0x000 through 0x1FF). * The pages are accessable as 64-bit "halfpages" (an upper and lower half). * The pages are not part of the memory map. There is an OTP controller which * handles scanning in/out of bits. While access is done through OTP MMRs, @@ -17,8 +17,6 @@ #include <common.h> #include <command.h>
-#ifdef CONFIG_CMD_OTP - #include <asm/blackfin.h> #include <asm/mach-common/bits/otp.h>
@@ -40,30 +38,87 @@ static const char *otp_strerror(uint32_t err)
#define lowup(x) ((x) % 2 ? "upper" : "lower")
-int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +static int check_voltage(void) +{ + /* Make sure voltage limits are within datasheet spec */ + uint16_t vr_ctl = bfin_read_VR_CTL(); + +#ifdef __ADSPBF54x__ + /* 0.9V <= VDDINT <= 1.1V */ + if ((vr_ctl & 0xc) && (vr_ctl & 0xc0) == 0xc0) + return 1; +#else + /* for the parts w/out qualification yet */ + (void)vr_ctl; +#endif + + return 0; +} + +static void set_otp_timing(bool write) { - bool force = false; - if (!strcmp(argv[1], "--force")) { - force = true; - argv[1] = argv[0]; - argv++; - --argc; + static uint32_t timing; + if (!timing) { + uint32_t tp1, tp2, tp3; + /* OTP_TP1 = 1000 / sclk_period (in nanoseconds) + * OTP_TP1 = 1000 / (1 / get_sclk() * 10^9) + * OTP_TP1 = (1000 * get_sclk()) / 10^9 + * OTP_TP1 = get_sclk() / 10^6 + */ + tp1 = get_sclk() / 1000000; + /* OTP_TP2 = 400 / (2 * sclk_period) + * OTP_TP2 = 400 / (2 * 1 / get_sclk() * 10^9) + * OTP_TP2 = (400 * get_sclk()) / (2 * 10^9) + * OTP_TP2 = (2 * get_sclk()) / 10^7 + */ + tp2 = (2 * get_sclk() / 10000000) << 8; + /* OTP_TP3 = magic constant */ + tp3 = (0x1401) << 15; + timing = tp1 | tp2 | tp3; }
+ bfrom_OtpCommand(OTP_INIT, write ? timing : timing & ~(-1 << 15)); +} + +int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + uint32_t ret, base_flags; + bool prompt_user, force_read; uint32_t (*otp_func)(uint32_t page, uint32_t flags, uint64_t *page_content); - if (!strcmp(argv[1], "read")) - otp_func = otp_read; - else if (!strcmp(argv[1], "write")) - otp_func = otp_write; - else { + + if (argc < 4) { usage: printf("Usage:\n%s\n", cmdtp->usage); return 1; }
+ prompt_user = false; + base_flags = 0; + if (!strcmp(argv[1], "read")) + otp_func = bfrom_OtpRead; + else if (!strcmp(argv[1], "dump")) { + otp_func = bfrom_OtpRead; + force_read = true; + } else if (!strcmp(argv[1], "write")) { + otp_func = bfrom_OtpWrite; + base_flags = OTP_CHECK_FOR_PREV_WRITE; + if (!strcmp(argv[2], "--force")) { + argv[2] = argv[1]; + argv++; + --argc; + } else + prompt_user = false; + } else if (!strcmp(argv[1], "lock")) { + if (argc != 4) + goto usage; + otp_func = bfrom_OtpWrite; + base_flags = OTP_LOCK; + } else + goto usage; + uint64_t *addr = (uint64_t *)simple_strtoul(argv[2], NULL, 16); uint32_t page = simple_strtoul(argv[3], NULL, 16); - uint32_t flags, ret; + uint32_t flags; size_t i, count; ulong half;
@@ -81,8 +136,15 @@ int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } else half = 0;
+ /* "otp lock" has slightly different semantics */ + if (base_flags & OTP_LOCK) { + count = page; + page = (uint32_t)addr; + addr = NULL; + } + /* do to the nature of OTP, make sure users are sure */ - if (!force && otp_func == otp_write) { + if (prompt_user) { printf( "Writing one time programmable memory\n" "Make sure your operating voltages and temperature are within spec\n" @@ -111,30 +173,42 @@ int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } } } - - /* Only supported in newer silicon ... enable writing */ -#if (0) - otp_command(OTP_INIT, ...); -#else - *pOTP_TIMING = 0x32149485; -#endif }
printf("OTP memory %s: addr 0x%08lx page 0x%03X count %ld ... ", argv[1], addr, page, count);
+ set_otp_timing(otp_func == bfrom_OtpWrite); + if (otp_func == bfrom_OtpWrite && check_voltage()) { + puts("ERROR: VDDINT voltage is out of spec for writing\n"); + return -1; + } + + /* Do the actual reading/writing stuff */ ret = 0; for (i = half; i < count + half; ++i) { - flags = (i % 2) ? OTP_UPPER_HALF : OTP_LOWER_HALF; + flags = base_flags | (i % 2 ? OTP_UPPER_HALF : OTP_LOWER_HALF); + try_again: ret = otp_func(page, flags, addr); - if (ret & 0x1) - break; - else if (ret) + if (ret & OTP_MASTER_ERROR) { + if (force_read) { + if (flags & OTP_NO_ECC) + break; + else + flags |= OTP_NO_ECC; + puts("E"); + goto try_again; + } else + break; + } else if (ret) puts("W"); else puts("."); - ++addr; - if (i % 2) + if (!(base_flags & OTP_LOCK)) { + ++addr; + if (i % 2) + ++page; + } else ++page; } if (ret & 0x1) @@ -143,21 +217,20 @@ int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) else puts(" done\n");
- if (otp_func == otp_write) - /* Only supported in newer silicon ... disable writing */ -#if (0) - otp_command(OTP_INIT, ...); -#else - *pOTP_TIMING = 0x1485; -#endif + /* Make sure we disable writing */ + set_otp_timing(false); + bfrom_OtpCommand(OTP_CLOSE, 0);
return ret; }
-U_BOOT_CMD(otp, 6, 0, do_otp, - "otp - One-Time-Programmable sub-system\n", +U_BOOT_CMD(otp, 7, 0, do_otp, + "otp - One-Time-Programmable sub-system\n", "read <addr> <page> [count] [half]\n" + " - read 'count' half-pages starting at 'page' (offset 'half') to 'addr'\n" + "otp dump <addr> <page> [count] [half]\n" + " - like 'otp read', but skip read errors\n" "otp write [--force] <addr> <page> [count] [half]\n" - " - read/write 'count' half-pages starting at page 'page' (offset 'half')\n"); - -#endif + " - write 'count' half-pages starting at 'page' (offset 'half') from 'addr'\n" + "otp lock <page> <count>\n" + " - lock 'count' pages starting at 'page'\n");

The BF53x/BF56x parts do not have an on-chip ROM to boot LDRs out of arbitrary memory locations, so implement a basic one in software.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- common/cmd_bootldr.c | 137 +++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 124 insertions(+), 13 deletions(-)
diff --git a/common/cmd_bootldr.c b/common/cmd_bootldr.c index e6474aa..a969242 100644 --- a/common/cmd_bootldr.c +++ b/common/cmd_bootldr.c @@ -16,6 +16,127 @@ #include <asm/blackfin.h> #include <asm/mach-common/bits/bootrom.h>
+/* Simple sanity check on the specified address to make sure it contains + * an LDR image of some sort. + */ +static bool ldr_valid_signature(uint8_t *data) +{ +#if defined(__ADSPBF561__) + + /* BF56x has a 4 byte global header */ + if (data[3] == 0xA0) + return true; + +#elif defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \ + defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) || \ + defined(__ADSPBF538__) || defined(__ADSPBF539__) + + /* all the BF53x should start at this address mask */ + uint32_t addr; + memmove(&addr, data, sizeof(addr)); + if ((addr & 0xFF0FFF0F) == 0xFF000000) + return true; +#else + + /* everything newer has a magic byte */ + uint32_t count; + memmove(&count, data + 8, sizeof(count)); + if (data[3] == 0xAD && count == 0) + return true; + +#endif + + return false; +} + +/* If the Blackfin is new enough, the Blackfin on-chip ROM supports loading + * LDRs from random memory addresses. So whenever possible, use that. In + * the older cases (BF53x/BF561), parse the LDR format ourselves. + */ +#define ZEROFILL 0x0001 +#define RESVECT 0x0002 +#define INIT 0x0008 +#define IGNORE 0x0010 +#define FINAL 0x8000 +static void ldr_load(uint8_t *base_addr) +{ +#if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \ + /*defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) ||*/\ + defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__) + + void *ret; + + uint32_t addr; + uint32_t count; + uint16_t flags; + + /* the bf56x has a 4 byte global header ... but it is useless to + * us when booting an LDR from a memory address, so skip it + */ +# ifdef __ADSPBF561__ + base_addr += 4; +# endif + + memmove(&flags, base_addr + 8, sizeof(flags)); + bfin_write_EVT1(flags & RESVECT ? 0xFFA00000 : 0xFFA08000); + + do { + /* block header may not be aligned */ + memmove(&addr, base_addr, sizeof(addr)); + memmove(&count, base_addr+4, sizeof(count)); + memmove(&flags, base_addr+8, sizeof(flags)); + base_addr += sizeof(addr) + sizeof(count) + sizeof(flags); + + printf("loading to 0x%08x (0x%x bytes) flags: 0x%04x\n", + addr, count, flags); + + if (!(flags & IGNORE)) { + if (flags & ZEROFILL) + memset((void *)addr, 0x00, count); + else + memcpy((void *)addr, base_addr, count); + + if (flags & INIT) { + void (*init)(void) = (void *)addr; + init(); + } + } + + if (!(flags & ZEROFILL)) + base_addr += count; + } while (!(flags & FINAL)); + +#endif +} + +/* For BF537, we use the _BOOTROM_BOOT_DXE_FLASH funky ROM function. + * For all other BF53x/BF56x, we just call the entry point. + * For everything else (newer), we use _BOOTROM_MEMBOOT ROM function. + */ +static void ldr_exec(void *addr) +{ +#if defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) + + /* restore EVT1 to reset value as this is what the bootrom uses as + * the default entry point when booting the final block of LDRs + */ + bfin_write_EVT1(L1_INST_SRAM); + __asm__("call (%0);" : : "a"(_BOOTROM_MEMBOOT), "q7"(addr) : "RETS", "memory"); + +#elif defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \ + defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__) + + void (*ldr_entry)(void) = bfin_read_EVT1(); + ldr_entry(); + +#else + + int32_t (*BOOTROM_MEM)(void *, int32_t, int32_t, void *) = (void *)_BOOTROM_MEMBOOT; + BOOTROM_MEM(addr, 0, 0, NULL); + +#endif +} + /* * the bootldr command loads an address, checks to see if there * is a Boot stream that the on-chip BOOTROM can understand, @@ -23,11 +144,9 @@ * 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) @@ -36,22 +155,14 @@ int do_bootldr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) 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 */ + if (ldr_valid_signature(addr)) { printf("## Booting ldr image at 0x%p ...\n", addr); + ldr_load(addr);
icache_disable(); dcache_disable();
- __asm__( - "jump (%1);" - : - : "q7" (addr), "a" (_BOOTROM_MEMBOOT)); + ldr_exec(addr); } else printf("## No ldr image at address 0x%p\n", addr);

Rather than sticking Blackfin-specific stuff into the eeprom example, use an indirect macro so that any board can override it with their own magic sauce in their board config file.
Also fix some spurious semi-colons in defines while I'm at it ...
Signed-off-by: Mike Frysinger vapier@gentoo.org --- examples/smc91111_eeprom.c | 15 ++++++--------- 1 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/examples/smc91111_eeprom.c b/examples/smc91111_eeprom.c index 62347c7..39e5306 100644 --- a/examples/smc91111_eeprom.c +++ b/examples/smc91111_eeprom.c @@ -33,15 +33,14 @@
#ifdef CONFIG_DRIVER_SMC91111
-#ifdef pFIO0_DIR -# define pFIO_DIR pFIO0_DIR -# define pFIO_FLAG_S pFIO0_FLAG_S +#ifndef SMC91111_EEPROM_INIT +# define SMC91111_EEPROM_INIT() #endif
#define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE -#define EEPROM 0x1; -#define MAC 0x2; -#define UNKNOWN 0x4; +#define EEPROM 0x1 +#define MAC 0x2 +#define UNKNOWN 0x4
void dump_reg (void); void dump_eeprom (void); @@ -66,9 +65,7 @@ int smc91111_eeprom (int argc, char *argv[]) return (0); }
- *pFIO_DIR = 0x01; - *pFIO_FLAG_S = 0x01; - SSYNC(); + SMC91111_EEPROM_INIT();
if ((SMC_inw (BANK_SELECT) & 0xFF00) != 0x3300) { printf ("Can't find SMSC91111\n");

On Friday 23 January 2009 13:00:38 Mike Frysinger wrote:
Rather than sticking Blackfin-specific stuff into the eeprom example, use an indirect macro so that any board can override it with their own magic sauce in their board config file.
Also fix some spurious semi-colons in defines while I'm at it ...
Ben: this changes Blackfin-specific code in the smc91111_eeprom.c example ... -mike

The old swap function tended to clobber unrelated pins and screw up masks. Rewrite the thing from scratch so it only uses the resources it needs.
Signed-off-by: Mike Frysinger vapier@gentoo.org --- board/bf533-stamp/bf533-stamp.c | 39 +++++++++++++++------------------------ 1 files changed, 15 insertions(+), 24 deletions(-)
diff --git a/board/bf533-stamp/bf533-stamp.c b/board/bf533-stamp/bf533-stamp.c index 1a073a6..44ebc93 100644 --- a/board/bf533-stamp/bf533-stamp.c +++ b/board/bf533-stamp/bf533-stamp.c @@ -54,29 +54,23 @@ phys_size_t initdram(int board_type) return gd->bd->bi_memsize; }
+/* PF0 and PF1 are used to switch between the ethernet and flash: + * PF0 PF1 + * flash: 0 0 + * ether: 1 0 + */ void swap_to(int device_id) { - - if (device_id == ETHERNET) { - *pFIO_DIR = PF0; - SSYNC(); - *pFIO_FLAG_S = PF0; - SSYNC(); - } else if (device_id == FLASH) { - *pFIO_DIR = (PF4 | PF3 | PF2 | PF1 | PF0); - *pFIO_FLAG_S = (PF4 | PF3 | PF2); - *pFIO_MASKA_D = (PF8 | PF6 | PF5); - *pFIO_MASKB_D = (PF7); - *pFIO_POLAR = (PF8 | PF6 | PF5); - *pFIO_EDGE = (PF8 | PF7 | PF6 | PF5); - *pFIO_INEN = (PF8 | PF7 | PF6 | PF5); - *pFIO_FLAG_D = (PF4 | PF3 | PF2); - SSYNC(); - } else { - printf("Unknown bank to switch\n"); - } - - return; + bfin_write_FIO_DIR(bfin_read_FIO_DIR() | PF1 | PF0); + SSYNC(); + bfin_write_FIO_FLAG_C(PF1); + if (device_id == ETHERNET) + bfin_write_FIO_FLAG_S(PF0); + else if (device_id == FLASH) + bfin_write_FIO_FLAG_C(PF0); + else + printf("Unknown device to switch\n"); + SSYNC(); }
#if defined(CONFIG_MISC_INIT_R) @@ -104,9 +98,6 @@ int misc_init_r(void) if (cf_stat) { printf("Booting from COMPACT flash\n");
- /* Set cycle time for CF */ - *(volatile unsigned long *)ambctl1 = CF_AMBCTL1VAL; - for (i = 0; i < 0x1000; i++) asm("nop;"); for (i = 0; i < 0x1000; i++)

Signed-off-by: Mike Frysinger vapier@gentoo.org --- board/bf533-ezkit/Makefile | 8 ++++---- board/bf533-stamp/Makefile | 7 ++++--- board/bf537-stamp/Makefile | 10 ++++++---- board/bf537-stamp/nand.c | 3 --- board/bf561-ezkit/Makefile | 8 ++++---- 5 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/board/bf533-ezkit/Makefile b/board/bf533-ezkit/Makefile index 6a45b7c..1260277 100644 --- a/board/bf533-ezkit/Makefile +++ b/board/bf533-ezkit/Makefile @@ -29,11 +29,11 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS := $(BOARD).o flash.o +COBJS-y := $(BOARD).o flash.o
-SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) -SOBJS := $(addprefix $(obj),$(SOBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS-y))
$(LIB): $(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) diff --git a/board/bf533-stamp/Makefile b/board/bf533-stamp/Makefile index 5b5e199..a03fe89 100644 --- a/board/bf533-stamp/Makefile +++ b/board/bf533-stamp/Makefile @@ -29,12 +29,13 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS-y := $(BOARD).o spi_flash.o +COBJS-y := $(BOARD).o +COBJS-$(CONFIG_CMD_EEPROM) += spi_flash.o COBJS-$(CONFIG_VIDEO) += video.o
-SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y)) -SOBJS := $(addprefix $(obj),$(SOBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS-y))
$(LIB): $(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) diff --git a/board/bf537-stamp/Makefile b/board/bf537-stamp/Makefile index e5ef9af..cb38b96 100644 --- a/board/bf537-stamp/Makefile +++ b/board/bf537-stamp/Makefile @@ -29,11 +29,13 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS := $(BOARD).o post-memory.o spi_flash.o cmd_bf537led.o nand.o +COBJS-y := $(BOARD).o post-memory.o cmd_bf537led.o +COBJS-$(CONFIG_CMD_EEPROM) += spi_flash.o +COBJS-$(CONFIG_CMD_NAND) += nand.o
-SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) -SOBJS := $(addprefix $(obj),$(SOBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS-y))
$(LIB): $(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) diff --git a/board/bf537-stamp/nand.c b/board/bf537-stamp/nand.c index 2866834..181e83d 100644 --- a/board/bf537-stamp/nand.c +++ b/board/bf537-stamp/nand.c @@ -23,8 +23,6 @@ #include <common.h> #include <asm/io.h>
-#if defined(CONFIG_CMD_NAND) - #include <nand.h>
#define CONCAT(a,b,c,d) a ## b ## c ## d @@ -100,4 +98,3 @@ int board_nand_init(struct nand_chip *nand)
return 0; } -#endif diff --git a/board/bf561-ezkit/Makefile b/board/bf561-ezkit/Makefile index e7ee243..daebb74 100644 --- a/board/bf561-ezkit/Makefile +++ b/board/bf561-ezkit/Makefile @@ -29,11 +29,11 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS := $(BOARD).o +COBJS-y := $(BOARD).o
-SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) -SOBJS := $(addprefix $(obj),$(SOBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS-y))
$(LIB): $(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)

Signed-off-by: Mike Frysinger vapier@gentoo.org --- board/bf533-ezkit/flash.c | 6 +++--- board/bf537-stamp/spi_flash.c | 4 ++-- common/cmd_bootldr.c | 4 +--- common/cmd_cplbinfo.c | 4 ++-- common/cmd_otp.c | 6 +++--- cpu/blackfin/traps.c | 21 +++++++++++---------- lib_blackfin/boot.c | 2 +- 7 files changed, 23 insertions(+), 24 deletions(-)
diff --git a/board/bf533-ezkit/flash.c b/board/bf533-ezkit/flash.c index 539c00d..ab808d8 100644 --- a/board/bf533-ezkit/flash.c +++ b/board/bf533-ezkit/flash.c @@ -127,7 +127,7 @@ void flash_print_info(flash_info_t * info) printf("ST Microelectronics "); break; default: - printf("Unknown Vendor: (0x%08X) ", info->flash_id); + printf("Unknown Vendor: (0x%08lX) ", info->flash_id); break; } for (i = 0; i < info->sector_count; ++i) { @@ -215,7 +215,7 @@ int write_data(long lStart, long lCount, uchar * pnData) read_flash(ulOffset, &d); if (d != 0xffff) { printf - ("Flash not erased at offset 0x%x Please erase to reprogram \n", + ("Flash not erased at offset 0x%lx Please erase to reprogram\n", ulOffset); return FLASH_FAIL; } @@ -234,7 +234,7 @@ int write_data(long lStart, long lCount, uchar * pnData) read_flash(ulOffset, &d); if (d != 0xffff) { printf - ("Flash not erased at offset 0x%x Please erase to reprogram \n", + ("Flash not erased at offset 0x%lx Please erase to reprogram\n", ulOffset); return FLASH_FAIL; } diff --git a/board/bf537-stamp/spi_flash.c b/board/bf537-stamp/spi_flash.c index a99c3fa..99caa96 100644 --- a/board/bf537-stamp/spi_flash.c +++ b/board/bf537-stamp/spi_flash.c @@ -797,8 +797,8 @@ int eeprom_info(void) 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" + "Parameters: num sectors = %lu, sector size = %lu, write size = %i\n" + "Flash Size: %lu mbit (%lu mbyte)\n" "Status: 0x%02X\n", flash.flash->name, flash.manufacturer_id, flash.manufacturer->name, flash.device_id1, flash.device_id2, flash.num_sectors, diff --git a/common/cmd_bootldr.c b/common/cmd_bootldr.c index a969242..f8db0bc 100644 --- a/common/cmd_bootldr.c +++ b/common/cmd_bootldr.c @@ -64,8 +64,6 @@ static void ldr_load(uint8_t *base_addr) /*defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) ||*/\ defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__)
- void *ret; - uint32_t addr; uint32_t count; uint16_t flags; @@ -126,7 +124,7 @@ static void ldr_exec(void *addr) #elif defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \ defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__)
- void (*ldr_entry)(void) = bfin_read_EVT1(); + void (*ldr_entry)(void) = (void *)bfin_read_EVT1(); ldr_entry();
#else diff --git a/common/cmd_cplbinfo.c b/common/cmd_cplbinfo.c index b2bbec1..eae1f53 100644 --- a/common/cmd_cplbinfo.c +++ b/common/cmd_cplbinfo.c @@ -26,11 +26,11 @@ static const char *cplb_page_size(uint32_t data) */ static void show_cplb_table(uint32_t *addr, uint32_t *data) { - size_t i; + int 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, + i, (void *)*addr, *data, cplb_page_size(*data), (*data & CPLB_VALID ? 'Y' : 'N'), (*data & CPLB_LOCK ? 'Y' : 'N')); diff --git a/common/cmd_otp.c b/common/cmd_otp.c index ce8c63b..08d7b7e 100644 --- a/common/cmd_otp.c +++ b/common/cmd_otp.c @@ -149,8 +149,8 @@ int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) "Writing one time programmable memory\n" "Make sure your operating voltages and temperature are within spec\n" " source address: 0x%p\n" - " OTP destination: %s page 0x%03X - %s page 0x%03X\n" - " number to write: %ld halfpages\n" + " OTP destination: %s page 0x%03X - %s page 0x%03lX\n" + " number to write: %lu halfpages\n" " type "YES" (no quotes) to confirm: ", addr, lowup(half), page, @@ -175,7 +175,7 @@ int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } }
- printf("OTP memory %s: addr 0x%08lx page 0x%03X count %ld ... ", + printf("OTP memory %s: addr 0x%p page 0x%03X count %zu ... ", argv[1], addr, page, count);
set_otp_timing(otp_func == bfrom_OtpWrite); diff --git a/cpu/blackfin/traps.c b/cpu/blackfin/traps.c index e72b347..a2c6f1e 100644 --- a/cpu/blackfin/traps.c +++ b/cpu/blackfin/traps.c @@ -111,7 +111,7 @@ void trap_c(struct pt_regs *regs) } if (i == ARRAY_SIZE(bfin_memory_map)) { printf("%cCPLB exception outside of memory map at 0x%p\n", - (data ? 'D' : 'I'), new_cplb_addr); + (data ? 'D' : 'I'), (void *)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); @@ -207,20 +207,21 @@ static const char *symbol_lookup(unsigned long addr, unsigned long *caddr) static void decode_address(char *buf, unsigned long address) { unsigned long sym_addr; + void *paddr = (void *)address; const char *sym = symbol_lookup(address, &sym_addr);
if (sym) { - sprintf(buf, "<0x%p> { %s + 0x%x }", address, sym, address - sym_addr); + sprintf(buf, "<0x%p> { %s + 0x%lx }", paddr, sym, address - sym_addr); return; }
if (!address) - sprintf(buf, "<0x%p> /* Maybe null pointer? */", address); + sprintf(buf, "<0x%p> /* Maybe null pointer? */", paddr); else if (address >= CONFIG_SYS_MONITOR_BASE && address < CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) - sprintf(buf, "<0x%p> /* somewhere in u-boot */", address); + sprintf(buf, "<0x%p> /* somewhere in u-boot */", paddr); else - sprintf(buf, "<0x%p> /* unknown address */", address); + sprintf(buf, "<0x%p> /* unknown address */", paddr); }
static char *strhwerrcause(uint16_t hwerrcause) @@ -260,7 +261,7 @@ static char *strexcause(uint16_t excause) void dump(struct pt_regs *fp) { char buf[150]; - size_t i; + int i; uint16_t hwerrcause, excause;
if (!ENABLE_DUMP) @@ -275,8 +276,8 @@ void dump(struct pt_regs *fp) printf("SEQUENCER STATUS:\n"); printf(" SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", fp->seqstat, fp->ipend, fp->syscfg); - printf(" HWERRCAUSE: 0x%lx: %s\n", hwerrcause, strhwerrcause(hwerrcause)); - printf(" EXCAUSE : 0x%lx: %s\n", excause, strexcause(excause)); + printf(" HWERRCAUSE: 0x%x: %s\n", hwerrcause, strhwerrcause(hwerrcause)); + printf(" EXCAUSE : 0x%x: %s\n", excause, strexcause(excause)); for (i = 6; i <= 15; ++i) { if (fp->ipend & (1 << i)) { decode_address(buf, bfin_read32(EVT0 + 4*i)); @@ -310,7 +311,7 @@ void dump(struct pt_regs *fp) 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); + fp->p4, fp->p5, fp->fp, (unsigned long)fp); printf(" LB0: %08lx LT0: %08lx LC0: %08lx\n", fp->lb0, fp->lt0, fp->lc0); printf(" LB1: %08lx LT1: %08lx LC1: %08lx\n", @@ -336,7 +337,7 @@ void dump_bfin_trace_buffer(void) { char buf[150]; unsigned long tflags; - size_t i = 0; + int i = 0;
if (!ENABLE_DUMP) return; diff --git a/lib_blackfin/boot.c b/lib_blackfin/boot.c index 537be2b..951d5b0 100644 --- a/lib_blackfin/boot.c +++ b/lib_blackfin/boot.c @@ -47,7 +47,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
appl = (int (*)(char *))images->ep;
- printf("Starting Kernel at = %x\n", appl); + printf("Starting Kernel at = %p\n", appl); cmdline = make_command_line(); icache_disable(); dcache_disable();
participants (2)
-
Mike Frysinger
-
Timur Tabi