From 34a6d0b84a25a141123f589b0cfef2bf88afe220 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 29 Apr 2011 23:10:54 -0400 Subject: Blackfin: uart: move debug buffers into local bss There's no need for these saved buffers to be global symbols, or in the data section. So mark them static to move them into the bss. Signed-off-by: Mike Frysinger --- arch/blackfin/cpu/serial.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'arch/blackfin/cpu') diff --git a/arch/blackfin/cpu/serial.c b/arch/blackfin/cpu/serial.c index 650202e..b15c945 100644 --- a/arch/blackfin/cpu/serial.c +++ b/arch/blackfin/cpu/serial.c @@ -49,9 +49,9 @@ DECLARE_GLOBAL_DATA_PTR; #include "serial.h" #ifdef CONFIG_DEBUG_SERIAL -uint16_t cached_lsr[256]; -uint16_t cached_rbr[256]; -size_t cache_count; +static uint16_t cached_lsr[256]; +static uint16_t cached_rbr[256]; +static size_t cache_count; /* The LSR is read-to-clear on some parts, so we have to make sure status * bits aren't inadvertently lost when doing various tests. This also @@ -112,11 +112,6 @@ int serial_init(void) serial_initialize(); serial_setbrg(); uart_lsr_clear(); -#ifdef CONFIG_DEBUG_SERIAL - cache_count = 0; - memset(cached_lsr, 0x00, sizeof(cached_lsr)); - memset(cached_rbr, 0x00, sizeof(cached_rbr)); -#endif return 0; } -- cgit v1.1 From 635f330fc7883a4cc703bc5ea2b90fc7d7f69e10 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 29 Apr 2011 23:23:28 -0400 Subject: Blackfin: uart: add multiple serial support This brings CONFIG_SERIAL_MULTI support to the Blackfin on-chip UARTs. Ends up adding only ~512bytes per additional UART. Signed-off-by: Mike Frysinger --- arch/blackfin/cpu/initcode.c | 12 ++- arch/blackfin/cpu/serial.c | 205 ++++++++++++++++++++++++++++++++++--------- arch/blackfin/cpu/serial.h | 44 +++++++--- 3 files changed, 206 insertions(+), 55 deletions(-) (limited to 'arch/blackfin/cpu') diff --git a/arch/blackfin/cpu/initcode.c b/arch/blackfin/cpu/initcode.c index 750add0..61dc5ab 100644 --- a/arch/blackfin/cpu/initcode.c +++ b/arch/blackfin/cpu/initcode.c @@ -24,6 +24,8 @@ __attribute__((always_inline)) static inline void serial_init(void) { + uint32_t uart_base = UART_DLL; + #ifdef __ADSPBF54x__ # ifdef BFIN_BOOT_UART_USE_RTS # define BFIN_UART_USE_RTS 1 @@ -65,13 +67,13 @@ static inline void serial_init(void) if (BFIN_DEBUG_EARLY_SERIAL) { int ucen = bfin_read16(&pUART->gctl) & UCEN; - serial_early_init(); + serial_early_init(uart_base); /* If the UART is off, that means we need to program * the baud rate ourselves initially. */ if (ucen != UCEN) - serial_early_set_baud(CONFIG_BAUDRATE); + serial_early_set_baud(uart_base, CONFIG_BAUDRATE); } } @@ -79,6 +81,8 @@ __attribute__((always_inline)) static inline void serial_deinit(void) { #ifdef __ADSPBF54x__ + uint32_t uart_base = UART_DLL; + if (BFIN_UART_USE_RTS && CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) { /* clear forced RTS rather than relying on auto RTS */ bfin_write16(&pUART->mcr, bfin_read16(&pUART->mcr) & ~FCPOL); @@ -89,6 +93,8 @@ static inline void serial_deinit(void) __attribute__((always_inline)) static inline void serial_putc(char c) { + uint32_t uart_base = UART_DLL; + if (!BFIN_DEBUG_EARLY_SERIAL) return; @@ -519,7 +525,7 @@ update_serial_clocks(ADI_BOOT_DATA *bs, uint sdivB, uint divB, uint vcoB) unsigned int quotient; for (quotient = 0; dividend > 0; ++quotient) dividend -= divisor; - serial_early_put_div(quotient - ANOMALY_05000230); + serial_early_put_div(UART_DLL, quotient - ANOMALY_05000230); serial_putc('c'); } diff --git a/arch/blackfin/cpu/serial.c b/arch/blackfin/cpu/serial.c index b15c945..0252220 100644 --- a/arch/blackfin/cpu/serial.c +++ b/arch/blackfin/cpu/serial.c @@ -39,6 +39,8 @@ #include #include +#include +#include #include #include @@ -59,14 +61,14 @@ static size_t cache_count; * tally of all the status bits. */ static uint16_t uart_lsr_save; -static uint16_t uart_lsr_read(void) +static uint16_t uart_lsr_read(uint32_t uart_base) { uint16_t lsr = bfin_read16(&pUART->lsr); uart_lsr_save |= (lsr & (OE|PE|FE|BI)); return lsr | uart_lsr_save; } /* Just do the clear for everyone since it can't hurt. */ -static void uart_lsr_clear(void) +static void uart_lsr_clear(uint32_t uart_base) { uart_lsr_save = 0; bfin_write16(&pUART->lsr, bfin_read16(&pUART->lsr) | -1); @@ -76,46 +78,17 @@ static void uart_lsr_clear(void) * bits get set/cleared, we don't really care since we don't read them * anyways (and thus anomaly 05000099 is irrelevant). */ -static uint16_t uart_lsr_read(void) +static inline uint16_t uart_lsr_read(uint32_t uart_base) { return bfin_read16(&pUART->lsr); } -static void uart_lsr_clear(void) +static void uart_lsr_clear(uint32_t uart_base) { bfin_write16(&pUART->lsr, bfin_read16(&pUART->lsr) | -1); } #endif -/* Symbol for our assembly to call. */ -void serial_set_baud(uint32_t baud) -{ - serial_early_set_baud(baud); -} - -/* Symbol for common u-boot code to call. - * Setup the baudrate (brg: baudrate generator). - */ -void serial_setbrg(void) -{ - serial_set_baud(gd->baudrate); -} - -/* Symbol for our assembly to call. */ -void serial_initialize(void) -{ - serial_early_init(); -} - -/* Symbol for common u-boot code to call. */ -int serial_init(void) -{ - serial_initialize(); - serial_setbrg(); - uart_lsr_clear(); - return 0; -} - -void serial_putc(const char c) +static void uart_putc(uint32_t uart_base, const char c) { /* send a \r for compatibility */ if (c == '\n') @@ -124,7 +97,7 @@ void serial_putc(const char c) WATCHDOG_RESET(); /* wait for the hardware fifo to clear up */ - while (!(uart_lsr_read() & THRE)) + while (!(uart_lsr_read(uart_base) & THRE)) continue; /* queue the character for transmission */ @@ -134,18 +107,18 @@ void serial_putc(const char c) WATCHDOG_RESET(); } -int serial_tstc(void) +static int uart_tstc(uint32_t uart_base) { WATCHDOG_RESET(); - return (uart_lsr_read() & DR) ? 1 : 0; + return (uart_lsr_read(uart_base) & DR) ? 1 : 0; } -int serial_getc(void) +static int uart_getc(uint32_t uart_base) { uint16_t uart_rbr_val; /* wait for data ! */ - while (!serial_tstc()) + while (!uart_tstc(uart_base)) continue; /* grab the new byte */ @@ -153,7 +126,7 @@ int serial_getc(void) #ifdef CONFIG_DEBUG_SERIAL /* grab & clear the LSR */ - uint16_t uart_lsr_val = uart_lsr_read(); + uint16_t uart_lsr_val = uart_lsr_read(uart_base); cached_lsr[cache_count] = uart_lsr_val; cached_rbr[cache_count] = uart_rbr_val; @@ -175,11 +148,159 @@ int serial_getc(void) return -1; } #endif - uart_lsr_clear(); + uart_lsr_clear(uart_base); return uart_rbr_val; } +#ifdef CONFIG_SYS_BFIN_UART + +static void uart_puts(uint32_t uart_base, const char *s) +{ + while (*s) + uart_putc(uart_base, *s++); +} + +#define DECL_BFIN_UART(n) \ +static int uart##n##_init(void) \ +{ \ + const unsigned short pins[] = { _P_UART(n, RX), _P_UART(n, TX), 0, }; \ + peripheral_request_list(pins, "bfin-uart"); \ + uart_init(MMR_UART(n)); \ + serial_early_set_baud(MMR_UART(n), gd->baudrate); \ + uart_lsr_clear(MMR_UART(n)); \ + return 0; \ +} \ +\ +static int uart##n##_uninit(void) \ +{ \ + return serial_early_uninit(MMR_UART(n)); \ +} \ +\ +static void uart##n##_setbrg(void) \ +{ \ + serial_early_set_baud(MMR_UART(n), gd->baudrate); \ +} \ +\ +static int uart##n##_getc(void) \ +{ \ + return uart_getc(MMR_UART(n)); \ +} \ +\ +static int uart##n##_tstc(void) \ +{ \ + return uart_tstc(MMR_UART(n)); \ +} \ +\ +static void uart##n##_putc(const char c) \ +{ \ + uart_putc(MMR_UART(n), c); \ +} \ +\ +static void uart##n##_puts(const char *s) \ +{ \ + uart_puts(MMR_UART(n), s); \ +} \ +\ +struct serial_device bfin_serial##n##_device = { \ + .name = "bfin_uart"#n, \ + .init = uart##n##_init, \ + .uninit = uart##n##_uninit, \ + .setbrg = uart##n##_setbrg, \ + .getc = uart##n##_getc, \ + .tstc = uart##n##_tstc, \ + .putc = uart##n##_putc, \ + .puts = uart##n##_puts, \ +}; + +#ifdef UART0_DLL +DECL_BFIN_UART(0) +#endif +#ifdef UART1_DLL +DECL_BFIN_UART(1) +#endif +#ifdef UART2_DLL +DECL_BFIN_UART(2) +#endif +#ifdef UART3_DLL +DECL_BFIN_UART(3) +#endif + +__weak struct serial_device *default_serial_console(void) +{ +#if CONFIG_UART_CONSOLE == 0 + return &bfin_serial0_device; +#elif CONFIG_UART_CONSOLE == 1 + return &bfin_serial1_device; +#elif CONFIG_UART_CONSOLE == 2 + return &bfin_serial2_device; +#elif CONFIG_UART_CONSOLE == 3 + return &bfin_serial3_device; +#endif +} + +void serial_register_bfin_uart(void) +{ +#ifdef UART0_DLL + serial_register(&bfin_serial0_device); +#endif +#ifdef UART1_DLL + serial_register(&bfin_serial1_device); +#endif +#ifdef UART2_DLL + serial_register(&bfin_serial2_device); +#endif +#ifdef UART3_DLL + serial_register(&bfin_serial3_device); +#endif +} + +#else + +/* Symbol for our assembly to call. */ +void serial_set_baud(uint32_t baud) +{ + serial_early_set_baud(UART_DLL, baud); +} + +/* Symbol for common u-boot code to call. + * Setup the baudrate (brg: baudrate generator). + */ +void serial_setbrg(void) +{ + serial_set_baud(gd->baudrate); +} + +/* Symbol for our assembly to call. */ +void serial_initialize(void) +{ + serial_early_init(UART_DLL); +} + +/* Symbol for common u-boot code to call. */ +int serial_init(void) +{ + serial_initialize(); + serial_setbrg(); + uart_lsr_clear(UART_DLL); + return 0; +} + +int serial_tstc(void) +{ + return uart_tstc(UART_DLL); +} + +int serial_getc(void) +{ + return uart_getc(UART_DLL); +} + +void serial_putc(const char c) +{ + uart_putc(UART_DLL, c); +} + void serial_puts(const char *s) { while (*s) @@ -187,3 +308,5 @@ void serial_puts(const char *s) } #endif + +#endif diff --git a/arch/blackfin/cpu/serial.h b/arch/blackfin/cpu/serial.h index 7999a19..aa5c217 100644 --- a/arch/blackfin/cpu/serial.h +++ b/arch/blackfin/cpu/serial.h @@ -82,17 +82,19 @@ struct bfin_mmr_serial { #define __PASTE_UART(num, pfx, sfx) pfx##num##_##sfx #define _PASTE_UART(num, pfx, sfx) __PASTE_UART(num, pfx, sfx) -#define MMR_UART(mmr) _PASTE_UART(CONFIG_UART_CONSOLE, UART, DLL) -#define P_UART(pin) _PASTE_UART(CONFIG_UART_CONSOLE, P_UART, pin) +#define MMR_UART(n) _PASTE_UART(n, UART, DLL) +#define _P_UART(n, pin) _PASTE_UART(n, P_UART, pin) +#define P_UART(pin) _P_UART(CONFIG_UART_CONSOLE, pin) #ifndef UART_DLL -# define UART_DLL MMR_UART(DLL) +# define UART_DLL MMR_UART(CONFIG_UART_CONSOLE) #else +# define UART0_DLL UART_DLL # if CONFIG_UART_CONSOLE != 0 # error CONFIG_UART_CONSOLE must be 0 on parts with only one UART # endif #endif -#define pUART ((volatile struct bfin_mmr_serial *)UART_DLL) +#define pUART ((volatile struct bfin_mmr_serial *)uart_base) #if BFIN_UART_HW_VER == 2 # define ACCESS_LATCH() @@ -168,11 +170,8 @@ static inline void serial_do_portmux(void) } __attribute__((always_inline)) -static inline void serial_early_init(void) +static inline int uart_init(uint32_t uart_base) { - /* handle portmux crap on different Blackfins */ - serial_do_portmux(); - /* always enable UART -- avoids anomalies 05000309 and 05000350 */ bfin_write16(&pUART->gctl, UCEN); @@ -180,10 +179,30 @@ static inline void serial_early_init(void) bfin_write16(&pUART->lcr, WLS_8); SSYNC(); + + return 0; } __attribute__((always_inline)) -static inline void serial_early_put_div(uint16_t divisor) +static inline int serial_early_init(uint32_t uart_base) +{ + /* handle portmux crap on different Blackfins */ + serial_do_portmux(); + + return uart_init(uart_base); +} + +__attribute__((always_inline)) +static inline int serial_early_uninit(uint32_t uart_base) +{ + /* disable the UART by clearing UCEN */ + bfin_write16(&pUART->gctl, 0); + + return 0; +} + +__attribute__((always_inline)) +static inline void serial_early_put_div(uint32_t uart_base, uint16_t divisor) { /* Set DLAB in LCR to Access DLL and DLH */ ACCESS_LATCH(); @@ -202,6 +221,8 @@ static inline void serial_early_put_div(uint16_t divisor) __attribute__((always_inline)) static inline uint16_t serial_early_get_div(void) { + uint32_t uart_base = UART_DLL; + /* Set DLAB in LCR to Access DLL and DLH */ ACCESS_LATCH(); SSYNC(); @@ -223,13 +244,14 @@ static inline uint16_t serial_early_get_div(void) #endif __attribute__((always_inline)) -static inline void serial_early_set_baud(uint32_t baud) +static inline void serial_early_set_baud(uint32_t uart_base, uint32_t baud) { /* Translate from baud into divisor in terms of SCLK. The * weird multiplication is to make sure we over sample just * a little rather than under sample the incoming signals. */ - serial_early_put_div((get_sclk() + (baud * 8)) / (baud * 16) - ANOMALY_05000230); + serial_early_put_div(uart_base, + (get_sclk() + (baud * 8)) / (baud * 16) - ANOMALY_05000230); } #ifndef BFIN_IN_INITCODE -- cgit v1.1 From 08a82a447b2a89d705edba952612d00c84129cb8 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 30 Apr 2011 04:38:22 -0400 Subject: Blackfin: dont reset SWRST on newer bf526 parts The bug in the BF526 rom when doing a software reset exists only in older silicon versions, so don't clear SWRST on newer parts. Signed-off-by: Mike Frysinger --- arch/blackfin/cpu/reset.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/blackfin/cpu') diff --git a/arch/blackfin/cpu/reset.c b/arch/blackfin/cpu/reset.c index e23dcc7..ff39035 100644 --- a/arch/blackfin/cpu/reset.c +++ b/arch/blackfin/cpu/reset.c @@ -51,7 +51,9 @@ static void bfin_reset(void) /* The BF526 ROM will crash during reset */ #if defined(__ADSPBF522__) || defined(__ADSPBF524__) || defined(__ADSPBF526__) - bfin_read_SWRST(); + /* Seems to be fixed with newer parts though ... */ + if (__SILICON_REVISION__ < 1 && bfin_revid() < 1) + bfin_read_SWRST(); #endif /* Wait for the SWRST write to complete. Cannot rely on SSYNC -- cgit v1.1 From fb5166ce35de489c8a96f3696e208eaae6a5a8d8 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 7 May 2011 17:55:04 -0400 Subject: Blackfin: add init.elf helper code This creates a standalone ELF that executes just the Blackfin initcode. This is useful for people who want to program the low level aspects of the CPU (memory/clocks/etc...) and can easily be used with JTAG for quick booting while developing. Signed-off-by: Mike Frysinger --- arch/blackfin/cpu/.gitignore | 3 +++ arch/blackfin/cpu/Makefile | 7 ++++++- arch/blackfin/cpu/init.S | 9 +++++++++ arch/blackfin/cpu/init.lds.S | 25 +++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 arch/blackfin/cpu/init.S create mode 100644 arch/blackfin/cpu/init.lds.S (limited to 'arch/blackfin/cpu') diff --git a/arch/blackfin/cpu/.gitignore b/arch/blackfin/cpu/.gitignore index 0ec9d56..ba986d8 100644 --- a/arch/blackfin/cpu/.gitignore +++ b/arch/blackfin/cpu/.gitignore @@ -1 +1,4 @@ bootrom-asm-offsets.[chs] + +init.lds +init.elf diff --git a/arch/blackfin/cpu/Makefile b/arch/blackfin/cpu/Makefile index df10f1b..5deaa9e 100644 --- a/arch/blackfin/cpu/Makefile +++ b/arch/blackfin/cpu/Makefile @@ -13,7 +13,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).o -EXTRA := +EXTRA := init.elf CEXTRA := initcode.o SEXTRA := start.o SOBJS := interrupt.o cache.o @@ -61,6 +61,11 @@ ifneq ($(CONFIG_BFIN_BOOT_MODE),BFIN_BOOT_BYPASS) fi endif +$(obj)init.lds: init.lds.S + $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P $^ -o $@ +$(obj)init.elf: $(obj)init.lds $(obj)init.o $(obj)initcode.o + $(LD) $(LDFLAGS) -T $^ -o $@ + ######################################################################### # defines $(obj).depend target diff --git a/arch/blackfin/cpu/init.S b/arch/blackfin/cpu/init.S new file mode 100644 index 0000000..f48c113 --- /dev/null +++ b/arch/blackfin/cpu/init.S @@ -0,0 +1,9 @@ +#include +ENTRY(_start) + sp.l = LO(L1_SRAM_SCRATCH_END - 20); + sp.h = HI(L1_SRAM_SCRATCH_END - 20); + call _initcode; +1: + emuexcpt; + jump 1b; +END(_start) diff --git a/arch/blackfin/cpu/init.lds.S b/arch/blackfin/cpu/init.lds.S new file mode 100644 index 0000000..602e7c8 --- /dev/null +++ b/arch/blackfin/cpu/init.lds.S @@ -0,0 +1,25 @@ +/* + * linker script for simple init.elf + * + * Copyright (c) 2005-2011 Analog Device Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#undef ALIGN +#undef ENTRY + +OUTPUT_ARCH(bfin) + +MEMORY +{ + l1_code : ORIGIN = L1_INST_SRAM, LENGTH = L1_INST_SRAM_SIZE +} + +ENTRY(_start) +SECTIONS +{ + .text.l1 : { *(.text .text.*) } >l1_code +} -- cgit v1.1 From f9aee4b4b65583149ed098c6908942d264db521b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 9 May 2011 14:56:38 -0400 Subject: Blackfin: uart: fix printf warning The code uses %i to printf a size_t when it should use %zu, otherwise we get a warning from gcc about it. Signed-off-by: Mike Frysinger --- arch/blackfin/cpu/serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/blackfin/cpu') diff --git a/arch/blackfin/cpu/serial.c b/arch/blackfin/cpu/serial.c index 0252220..1124ffd 100644 --- a/arch/blackfin/cpu/serial.c +++ b/arch/blackfin/cpu/serial.c @@ -142,7 +142,7 @@ static int uart_getc(uint32_t uart_base) printf("\tDLL=0x%x DLH=0x%x\n", dll, dlh); do { --cache_count; - printf("\t%3i: RBR=0x%02x LSR=0x%02x\n", cache_count, + printf("\t%3zu: RBR=0x%02x LSR=0x%02x\n", cache_count, cached_rbr[cache_count], cached_lsr[cache_count]); } while (cache_count > 0); return -1; -- cgit v1.1 From 95b4b9d97a5bb6a93ec269cb9cf85e95a8f8295d Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 10 May 2011 12:56:58 -0400 Subject: Blackfin: gpio: optimize free path a little When we aren't doing resource tracking, the gpio_free() function is a stub that simply returns, so pull this logic up a level and make it an inline stub in the header. Now we don't have to waste time at any of the call sites. Signed-off-by: Mike Frysinger --- arch/blackfin/cpu/gpio.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/blackfin/cpu') diff --git a/arch/blackfin/cpu/gpio.c b/arch/blackfin/cpu/gpio.c index cb96721..5674d42 100644 --- a/arch/blackfin/cpu/gpio.c +++ b/arch/blackfin/cpu/gpio.c @@ -665,6 +665,7 @@ int bfin_gpio_request(unsigned gpio, const char *label) return 0; } +#ifdef CONFIG_BFIN_GPIO_TRACK void bfin_gpio_free(unsigned gpio) { if (check_gpio(gpio) < 0) @@ -679,6 +680,7 @@ void bfin_gpio_free(unsigned gpio) set_label(gpio, "free"); } +#endif #ifdef BFIN_SPECIAL_GPIO_BANKS DECLARE_RESERVED_MAP(special_gpio, gpio_bank(MAX_RESOURCES)); -- cgit v1.1 From ed7496349d7b0556af497d1f6d59c2b055f7ad02 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 1 Jun 2011 13:30:25 -0400 Subject: Blackfin: drop unused dma.h header from start code Signed-off-by: Mike Frysinger --- arch/blackfin/cpu/start.S | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/blackfin/cpu') diff --git a/arch/blackfin/cpu/start.S b/arch/blackfin/cpu/start.S index 15ecb1e..90b4d1a 100644 --- a/arch/blackfin/cpu/start.S +++ b/arch/blackfin/cpu/start.S @@ -33,7 +33,6 @@ #include #include #include -#include #include #include "serial.h" -- cgit v1.1 From 4150cec3353b7a6d7a3ea71b2d3c62deafff353d Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 30 May 2011 13:47:38 -0400 Subject: Blackfin: split out async setup We really only need to tweak the async banks in the initcode if the processor is booting out of it, otherwise we can wait until later on in the CPU booting setup. This also makes testing in the sim and early bring up over JTAG work much smoother when the initcode gets bypassed. Signed-off-by: Mike Frysinger --- arch/blackfin/cpu/cpu.c | 16 ++++++---- arch/blackfin/cpu/initcode.c | 47 ++--------------------------- arch/blackfin/cpu/initcode.h | 71 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 50 deletions(-) create mode 100644 arch/blackfin/cpu/initcode.h (limited to 'arch/blackfin/cpu') diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c index 18dbdf7..6a0bcca 100644 --- a/arch/blackfin/cpu/cpu.c +++ b/arch/blackfin/cpu/cpu.c @@ -19,6 +19,7 @@ #include "cpu.h" #include "serial.h" +#include "initcode.h" ulong bfin_poweron_retx; @@ -44,13 +45,16 @@ void cpu_init_f(ulong bootflag, ulong loaded_from_ldr) extern char _sdata_l1[], _data_l1_lma[], _data_l1_len[]; memcpy(&_sdata_l1, &_data_l1_lma, (unsigned long)_data_l1_len); } -#if defined(__ADSPBF537__) || defined(__ADSPBF536__) || defined(__ADSPBF534__) - /* The BF537 bootrom will reset the EBIU_AMGCTL register on us - * after it has finished loading the LDR. So configure it again. + + /* + * Make sure our async settings are committed. Some bootroms + * (like the BF537) will reset some registers on us after it + * has finished loading the LDR. Or if we're booting over + * JTAG, the initcode never got a chance to run. Or if we + * aren't booting from parallel flash, the initcode skipped + * this step completely. */ - else - bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL); -#endif + program_async_controller(NULL); /* Save RETX so we can pass it while booting Linux */ bfin_poweron_retx = bootflag; diff --git a/arch/blackfin/cpu/initcode.c b/arch/blackfin/cpu/initcode.c index 61dc5ab..917b7f9 100644 --- a/arch/blackfin/cpu/initcode.c +++ b/arch/blackfin/cpu/initcode.c @@ -4,7 +4,7 @@ * cannot make any function calls as it may be executed all by itself by * the Blackfin's bootrom in LDR format. * - * Copyright (c) 2004-2008 Analog Devices Inc. + * Copyright (c) 2004-2011 Analog Devices Inc. * * Licensed under the GPL-2 or later. */ @@ -107,6 +107,8 @@ static inline void serial_putc(char c) continue; } +#include "initcode.h" + __attribute__((always_inline)) static inline void program_nmi_handler(void) { @@ -172,21 +174,6 @@ program_nmi_handler(void) # define CONFIG_PLL_CTL_VAL (SPORT_HYST | (CONFIG_VCO_MULT << 9) | CONFIG_CLKIN_HALF) #endif -#ifndef CONFIG_EBIU_RSTCTL_VAL -# define CONFIG_EBIU_RSTCTL_VAL 0 /* only MDDRENABLE is useful */ -#endif -#if ((CONFIG_EBIU_RSTCTL_VAL & 0xFFFFFFC4) != 0) -# error invalid EBIU_RSTCTL value: must not set reserved bits -#endif - -#ifndef CONFIG_EBIU_MBSCTL_VAL -# define CONFIG_EBIU_MBSCTL_VAL 0 -#endif - -#if defined(CONFIG_EBIU_DDRQUE_VAL) && ((CONFIG_EBIU_DDRQUE_VAL & 0xFFFF8000) != 0) -# error invalid EBIU_DDRQUE value: must not set reserved bits -#endif - /* Make sure our voltage value is sane so we don't blow up! */ #ifndef CONFIG_VR_CTL_VAL # define BFIN_CCLK ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_CCLK_DIV) @@ -642,34 +629,6 @@ check_hibernation(ADI_BOOT_DATA *bs, u16 vr_ctl, bool put_into_srfs) serial_putc('e'); } -__attribute__((always_inline)) static inline void -program_async_controller(ADI_BOOT_DATA *bs) -{ - serial_putc('a'); - - /* Program the async banks controller. */ - bfin_write_EBIU_AMBCTL0(CONFIG_EBIU_AMBCTL0_VAL); - bfin_write_EBIU_AMBCTL1(CONFIG_EBIU_AMBCTL1_VAL); - bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL); - - serial_putc('b'); - - /* Not all parts have these additional MMRs. */ -#ifdef EBIU_MBSCTL - bfin_write_EBIU_MBSCTL(CONFIG_EBIU_MBSCTL_VAL); -#endif -#ifdef EBIU_MODE -# ifdef CONFIG_EBIU_MODE_VAL - bfin_write_EBIU_MODE(CONFIG_EBIU_MODE_VAL); -# endif -# ifdef CONFIG_EBIU_FCTL_VAL - bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTL_VAL); -# endif -#endif - - serial_putc('c'); -} - BOOTROM_CALLED_FUNC_ATTR void initcode(ADI_BOOT_DATA *bs) { diff --git a/arch/blackfin/cpu/initcode.h b/arch/blackfin/cpu/initcode.h new file mode 100644 index 0000000..e0aad6d --- /dev/null +++ b/arch/blackfin/cpu/initcode.h @@ -0,0 +1,71 @@ +/* + * Code for early processor initialization + * + * Copyright (c) 2004-2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __BFIN_INITCODE_H__ +#define __BFIN_INITCODE_H__ + +#include + +#ifndef BFIN_IN_INITCODE +# define serial_putc(c) +#endif + +#ifndef CONFIG_EBIU_RSTCTL_VAL +# define CONFIG_EBIU_RSTCTL_VAL 0 /* only MDDRENABLE is useful */ +#endif +#if ((CONFIG_EBIU_RSTCTL_VAL & 0xFFFFFFC4) != 0) +# error invalid EBIU_RSTCTL value: must not set reserved bits +#endif + +#ifndef CONFIG_EBIU_MBSCTL_VAL +# define CONFIG_EBIU_MBSCTL_VAL 0 +#endif + +#if defined(CONFIG_EBIU_DDRQUE_VAL) && ((CONFIG_EBIU_DDRQUE_VAL & 0xFFFF8000) != 0) +# error invalid EBIU_DDRQUE value: must not set reserved bits +#endif + +__attribute__((always_inline)) static inline void +program_async_controller(ADI_BOOT_DATA *bs) +{ +#ifdef BFIN_IN_INITCODE + /* + * We really only need to setup the async banks early if we're + * booting out of it. Otherwise, do it later on in cpu_init. + */ + if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS && + CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_PARA) + return; +#endif + + serial_putc('a'); + + /* Program the async banks controller. */ + bfin_write_EBIU_AMBCTL0(CONFIG_EBIU_AMBCTL0_VAL); + bfin_write_EBIU_AMBCTL1(CONFIG_EBIU_AMBCTL1_VAL); + bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL); + + serial_putc('b'); + + /* Not all parts have these additional MMRs. */ +#ifdef EBIU_MBSCTL + bfin_write_EBIU_MBSCTL(CONFIG_EBIU_MBSCTL_VAL); +#endif +#ifdef EBIU_MODE +# ifdef CONFIG_EBIU_MODE_VAL + bfin_write_EBIU_MODE(CONFIG_EBIU_MODE_VAL); +# endif +# ifdef CONFIG_EBIU_FCTL_VAL + bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTL_VAL); +# endif +#endif + + serial_putc('c'); +} + +#endif -- cgit v1.1 From b1e574d95b6a2d8674dc45b6ff3425cffc115c14 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 6 Jun 2011 16:47:31 -0400 Subject: Blackfin: serial: convert to bfin_{read,write} helpers Since the serial struct declares the sizes for us, no need to hardcode them in the accessor functions. Let the bfin_{read,write} helpers do it for us. Signed-off-by: Mike Frysinger --- arch/blackfin/cpu/initcode.c | 2 ++ arch/blackfin/cpu/serial.c | 16 ++++++++-------- arch/blackfin/cpu/serial.h | 18 +++++++++--------- 3 files changed, 19 insertions(+), 17 deletions(-) (limited to 'arch/blackfin/cpu') diff --git a/arch/blackfin/cpu/initcode.c b/arch/blackfin/cpu/initcode.c index 917b7f9..fb3a101 100644 --- a/arch/blackfin/cpu/initcode.c +++ b/arch/blackfin/cpu/initcode.c @@ -19,6 +19,8 @@ #include #include +#define BUG() while (1) { asm volatile("emuexcpt;"); } + #include "serial.h" __attribute__((always_inline)) diff --git a/arch/blackfin/cpu/serial.c b/arch/blackfin/cpu/serial.c index 1124ffd..030160f 100644 --- a/arch/blackfin/cpu/serial.c +++ b/arch/blackfin/cpu/serial.c @@ -63,7 +63,7 @@ static size_t cache_count; static uint16_t uart_lsr_save; static uint16_t uart_lsr_read(uint32_t uart_base) { - uint16_t lsr = bfin_read16(&pUART->lsr); + uint16_t lsr = bfin_read(&pUART->lsr); uart_lsr_save |= (lsr & (OE|PE|FE|BI)); return lsr | uart_lsr_save; } @@ -71,7 +71,7 @@ static uint16_t uart_lsr_read(uint32_t uart_base) static void uart_lsr_clear(uint32_t uart_base) { uart_lsr_save = 0; - bfin_write16(&pUART->lsr, bfin_read16(&pUART->lsr) | -1); + bfin_write(&pUART->lsr, bfin_read(&pUART->lsr) | -1); } #else /* When debugging is disabled, we only care about the DR bit, so if other @@ -80,11 +80,11 @@ static void uart_lsr_clear(uint32_t uart_base) */ static inline uint16_t uart_lsr_read(uint32_t uart_base) { - return bfin_read16(&pUART->lsr); + return bfin_read(&pUART->lsr); } static void uart_lsr_clear(uint32_t uart_base) { - bfin_write16(&pUART->lsr, bfin_read16(&pUART->lsr) | -1); + bfin_write(&pUART->lsr, bfin_read(&pUART->lsr) | -1); } #endif @@ -101,7 +101,7 @@ static void uart_putc(uint32_t uart_base, const char c) continue; /* queue the character for transmission */ - bfin_write16(&pUART->thr, c); + bfin_write(&pUART->thr, c); SSYNC(); WATCHDOG_RESET(); @@ -122,7 +122,7 @@ static int uart_getc(uint32_t uart_base) continue; /* grab the new byte */ - uart_rbr_val = bfin_read16(&pUART->rbr); + uart_rbr_val = bfin_read(&pUART->rbr); #ifdef CONFIG_DEBUG_SERIAL /* grab & clear the LSR */ @@ -136,8 +136,8 @@ static int uart_getc(uint32_t uart_base) uint16_t dll, dlh; printf("\n[SERIAL ERROR]\n"); ACCESS_LATCH(); - dll = bfin_read16(&pUART->dll); - dlh = bfin_read16(&pUART->dlh); + dll = bfin_read(&pUART->dll); + dlh = bfin_read(&pUART->dlh); ACCESS_PORT_IER(); printf("\tDLL=0x%x DLH=0x%x\n", dll, dlh); do { diff --git a/arch/blackfin/cpu/serial.h b/arch/blackfin/cpu/serial.h index aa5c217..f649e40 100644 --- a/arch/blackfin/cpu/serial.h +++ b/arch/blackfin/cpu/serial.h @@ -101,9 +101,9 @@ struct bfin_mmr_serial { # define ACCESS_PORT_IER() #else # define ACCESS_LATCH() \ - bfin_write16(&pUART->lcr, bfin_read16(&pUART->lcr) | DLAB) + bfin_write(&pUART->lcr, bfin_read(&pUART->lcr) | DLAB) # define ACCESS_PORT_IER() \ - bfin_write16(&pUART->lcr, bfin_read16(&pUART->lcr) & ~DLAB) + bfin_write(&pUART->lcr, bfin_read(&pUART->lcr) & ~DLAB) #endif __attribute__((always_inline)) @@ -173,10 +173,10 @@ __attribute__((always_inline)) static inline int uart_init(uint32_t uart_base) { /* always enable UART -- avoids anomalies 05000309 and 05000350 */ - bfin_write16(&pUART->gctl, UCEN); + bfin_write(&pUART->gctl, UCEN); /* Set LCR to Word Lengh 8-bit word select */ - bfin_write16(&pUART->lcr, WLS_8); + bfin_write(&pUART->lcr, WLS_8); SSYNC(); @@ -196,7 +196,7 @@ __attribute__((always_inline)) static inline int serial_early_uninit(uint32_t uart_base) { /* disable the UART by clearing UCEN */ - bfin_write16(&pUART->gctl, 0); + bfin_write(&pUART->gctl, 0); return 0; } @@ -209,8 +209,8 @@ static inline void serial_early_put_div(uint32_t uart_base, uint16_t divisor) SSYNC(); /* Program the divisor to get the baud rate we want */ - bfin_write16(&pUART->dll, LOB(divisor)); - bfin_write16(&pUART->dlh, HIB(divisor)); + bfin_write(&pUART->dll, LOB(divisor)); + bfin_write(&pUART->dlh, HIB(divisor)); SSYNC(); /* Clear DLAB in LCR to Access THR RBR IER */ @@ -227,8 +227,8 @@ static inline uint16_t serial_early_get_div(void) ACCESS_LATCH(); SSYNC(); - uint8_t dll = bfin_read16(&pUART->dll); - uint8_t dlh = bfin_read16(&pUART->dlh); + uint8_t dll = bfin_read(&pUART->dll); + uint8_t dlh = bfin_read(&pUART->dlh); uint16_t divisor = (dlh << 8) | dll; /* Clear DLAB in LCR to Access THR RBR IER */ -- cgit v1.1 From e8e35efc8f2a16cf72ddc475df4ff26d76f03d1e Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 29 Jun 2011 16:21:28 -0400 Subject: Blackfin: serial: move early debug strings into .rodata section Rewrite the assembly serial_early_puts() helper to place the strings in the .rodata section rather than embedding them directly in the .text section. Using .text is a little simpler, but it doesn't let people execute out of internal L1 sram (since core reads don't work on those regions). Signed-off-by: Mike Frysinger --- arch/blackfin/cpu/serial.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/blackfin/cpu') diff --git a/arch/blackfin/cpu/serial.h b/arch/blackfin/cpu/serial.h index f649e40..8a076dd 100644 --- a/arch/blackfin/cpu/serial.h +++ b/arch/blackfin/cpu/serial.h @@ -288,16 +288,16 @@ static inline void serial_early_puts(const char *s) */ #ifdef CONFIG_DEBUG_EARLY_SERIAL # define serial_early_puts(str) \ - call _get_pc; \ - jump 1f; \ + .section .rodata; \ + 7: \ .ascii "Early:"; \ .ascii __FILE__; \ .ascii ": "; \ .ascii str; \ .asciz "\n"; \ - .align 4; \ -1: \ - R0 += 2; \ + .previous; \ + R0.L = 7b; \ + R0.H = 7b; \ call _serial_puts; #else # define serial_early_puts(str) -- cgit v1.1 From d8940a654435dfa48013229edf53bd3e353e97c1 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 4 Jul 2011 19:25:07 -0400 Subject: Blackfin: jtag-console: fix timer usage Reported-by: Graeme Russ Signed-off-by: Mike Frysinger --- arch/blackfin/cpu/jtag-console.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/blackfin/cpu') diff --git a/arch/blackfin/cpu/jtag-console.c b/arch/blackfin/cpu/jtag-console.c index e0f2975..a77358a 100644 --- a/arch/blackfin/cpu/jtag-console.c +++ b/arch/blackfin/cpu/jtag-console.c @@ -48,11 +48,11 @@ static inline uint32_t bfin_read_emudat(void) static bool jtag_write_emudat(uint32_t emudat) { static bool overflowed = false; - ulong timeout = get_timer(0) + CONFIG_JTAG_CONSOLE_TIMEOUT; + ulong timeout = get_timer(0); while (bfin_read_DBGSTAT() & 0x1) { if (overflowed) return overflowed; - if (timeout < get_timer(0)) + if (get_timer(timeout) > CONFIG_JTAG_CONSOLE_TIMEOUT) overflowed = true; } overflowed = false; -- cgit v1.1