diff options
39 files changed, 1164 insertions, 479 deletions
@@ -898,6 +898,7 @@ The following options need to be configured: CONFIG_CMD_SF * Read/write/erase SPI NOR flash CONFIG_CMD_SHA1SUM print sha1 memory digest (requires CONFIG_CMD_MEMORY) + CONFIG_CMD_SOFTSWITCH * Soft switch setting command for BF60x CONFIG_CMD_SOURCE "source" command Support CONFIG_CMD_SPI * SPI serial bus support CONFIG_CMD_TFTPSRV * TFTP transfer in server mode diff --git a/arch/blackfin/cpu/Makefile b/arch/blackfin/cpu/Makefile index 0a72ec5df3..1421cb2ca2 100644 --- a/arch/blackfin/cpu/Makefile +++ b/arch/blackfin/cpu/Makefile @@ -18,14 +18,12 @@ CEXTRA := initcode.o SEXTRA := start.o SOBJS := interrupt.o cache.o COBJS-y += cpu.o -COBJS-y += gpio.o +COBJS-$(CONFIG_ADI_GPIO1) += gpio.o COBJS-y += interrupts.o COBJS-$(CONFIG_JTAG_CONSOLE) += jtag-console.o COBJS-y += os_log.o COBJS-y += reset.o -COBJS-y += serial.o COBJS-y += traps.o -COBJS-$(CONFIG_HW_WATCHDOG) += watchdog.o SRCS := $(SEXTRA:.o=.S) $(SOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y) $(SOBJS)) diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c index 0be2e2b835..218f57ed38 100644 --- a/arch/blackfin/cpu/cpu.c +++ b/arch/blackfin/cpu/cpu.c @@ -16,13 +16,39 @@ #include <asm/mach-common/bits/core.h> #include <asm/mach-common/bits/ebiu.h> #include <asm/mach-common/bits/trace.h> +#include <asm/serial.h> #include "cpu.h" -#include "serial.h" #include "initcode.h" ulong bfin_poweron_retx; +#if defined(CONFIG_CORE1_RUN) && defined(COREB_L1_CODE_START) +void bfin_core1_start(void) +{ +#ifdef BF561_FAMILY + /* Enable core 1 */ + bfin_write_SYSCR(bfin_read_SYSCR() & ~0x0020); +#else + /* Enable core 1 */ + bfin_write32(RCU0_SVECT1, COREB_L1_CODE_START); + bfin_write32(RCU0_CRCTL, 0); + + bfin_write32(RCU0_CRCTL, 0x2); + + /* Check if core 1 starts */ + while (!(bfin_read32(RCU0_CRSTAT) & 0x2)) + continue; + + bfin_write32(RCU0_CRCTL, 0); + + /* flag to notify cces core 1 application */ + bfin_write32(SDU0_MSG_SET, (1 << 19)); +#endif +} +#endif + +__attribute__ ((__noreturn__)) void cpu_init_f(ulong bootflag, ulong loaded_from_ldr) { #ifndef CONFIG_BFIN_BOOTROM_USES_EVT1 @@ -72,6 +98,10 @@ void cpu_init_f(ulong bootflag, ulong loaded_from_ldr) # endif #endif +#if defined(CONFIG_CORE1_RUN) && defined(COREB_L1_CODE_START) + bfin_core1_start(); +#endif + serial_early_puts("Board init flash\n"); board_init_f(bootflag); } diff --git a/arch/blackfin/cpu/gpio.c b/arch/blackfin/cpu/gpio.c index f684be531c..f74a0b7c0e 100644 --- a/arch/blackfin/cpu/gpio.c +++ b/arch/blackfin/cpu/gpio.c @@ -1,5 +1,6 @@ /* - * GPIO Abstraction Layer + * ADI GPIO1 Abstraction Layer + * Support BF50x, BF51x, BF52x, BF53x and BF561 only. * * Copyright 2006-2010 Analog Devices Inc. * @@ -55,25 +56,6 @@ static struct gpio_port_t * const gpio_array[] = { (struct gpio_port_t *) FIO0_FLAG_D, (struct gpio_port_t *) FIO1_FLAG_D, (struct gpio_port_t *) FIO2_FLAG_D, -#elif defined(CONFIG_BF54x) - (struct gpio_port_t *)PORTA_FER, - (struct gpio_port_t *)PORTB_FER, - (struct gpio_port_t *)PORTC_FER, - (struct gpio_port_t *)PORTD_FER, - (struct gpio_port_t *)PORTE_FER, - (struct gpio_port_t *)PORTF_FER, - (struct gpio_port_t *)PORTG_FER, - (struct gpio_port_t *)PORTH_FER, - (struct gpio_port_t *)PORTI_FER, - (struct gpio_port_t *)PORTJ_FER, -#elif defined(CONFIG_BF60x) - (struct gpio_port_t *)PORTA_FER, - (struct gpio_port_t *)PORTB_FER, - (struct gpio_port_t *)PORTC_FER, - (struct gpio_port_t *)PORTD_FER, - (struct gpio_port_t *)PORTE_FER, - (struct gpio_port_t *)PORTF_FER, - (struct gpio_port_t *)PORTG_FER, #else # error no gpio arrays defined #endif @@ -174,12 +156,6 @@ DECLARE_RESERVED_MAP(peri, gpio_bank(MAX_RESOURCES)); inline int check_gpio(unsigned gpio) { -#if defined(CONFIG_BF54x) - if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 - || gpio == GPIO_PH14 || gpio == GPIO_PH15 - || gpio == GPIO_PJ14 || gpio == GPIO_PJ15) - return -EINVAL; -#endif if (gpio >= MAX_BLACKFIN_GPIOS) return -EINVAL; return 0; @@ -218,18 +194,6 @@ static void port_setup(unsigned gpio, unsigned short usage) else *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio); SSYNC(); -#elif defined(CONFIG_BF54x) - if (usage == GPIO_USAGE) - gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio); - else - gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio); - SSYNC(); -#elif defined(CONFIG_BF60x) - if (usage == GPIO_USAGE) - gpio_array[gpio_bank(gpio)]->port_fer_clear = gpio_bit(gpio); - else - gpio_array[gpio_bank(gpio)]->port_fer_set = gpio_bit(gpio); - SSYNC(); #endif } @@ -304,30 +268,6 @@ static void portmux_setup(unsigned short per) } } } -#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) -inline void portmux_setup(unsigned short per) -{ - u32 pmux; - u16 ident = P_IDENT(per); - u16 function = P_FUNCT2MUX(per); - - pmux = gpio_array[gpio_bank(ident)]->port_mux; - - pmux &= ~(0x3 << (2 * gpio_sub_n(ident))); - pmux |= (function & 0x3) << (2 * gpio_sub_n(ident)); - - gpio_array[gpio_bank(ident)]->port_mux = pmux; -} - -inline u16 get_portmux(unsigned short per) -{ - u32 pmux; - u16 ident = P_IDENT(per); - - pmux = gpio_array[gpio_bank(ident)]->port_mux; - - return (pmux >> (2 * gpio_sub_n(ident)) & 0x3); -} #elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x) inline void portmux_setup(unsigned short per) { @@ -344,7 +284,6 @@ inline void portmux_setup(unsigned short per) # define portmux_setup(...) do { } while (0) #endif -#if !defined(CONFIG_BF54x) && !defined(CONFIG_BF60x) /*********************************************************** * * FUNCTIONS: Blackfin General Purpose Ports Access Functions @@ -491,15 +430,6 @@ GET_GPIO_P(both) GET_GPIO_P(maska) GET_GPIO_P(maskb) -#else /* CONFIG_BF54x */ - -unsigned short get_gpio_dir(unsigned gpio) -{ - return (0x01 & (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio))); -} - -#endif /* CONFIG_BF54x */ - /*********************************************************** * * FUNCTIONS: Blackfin Peripheral Resource Allocation @@ -548,11 +478,7 @@ int peripheral_request(unsigned short per, const char *label) * be requested and used by several drivers */ -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) - if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) { -#else if (!(per & P_MAYSHARE)) { -#endif /* * Allow that the identical pin function can * be requested from the same driver twice @@ -641,7 +567,7 @@ void peripheral_free_list(const unsigned short per[]) * MODIFICATION HISTORY : **************************************************************/ -int bfin_gpio_request(unsigned gpio, const char *label) +int gpio_request(unsigned gpio, const char *label) { if (check_gpio(gpio) < 0) return -EINVAL; @@ -665,11 +591,9 @@ int bfin_gpio_request(unsigned gpio, const char *label) gpio, get_label(gpio)); return -EBUSY; } -#if !defined(CONFIG_BF54x) && !defined(CONFIG_BF60x) else { /* Reset POLAR setting when acquiring a gpio for the first time */ set_gpio_polar(gpio, 0); } -#endif reserve(gpio, gpio); set_label(gpio, label); @@ -679,27 +603,27 @@ int bfin_gpio_request(unsigned gpio, const char *label) return 0; } -#ifdef CONFIG_BFIN_GPIO_TRACK -void bfin_gpio_free(unsigned gpio) +int gpio_free(unsigned gpio) { if (check_gpio(gpio) < 0) - return; + return -1; if (unlikely(!is_reserved(gpio, gpio, 0))) { gpio_error(gpio); - return; + return -1; } unreserve(gpio, gpio); set_label(gpio, "free"); + + return 0; } -#endif -#ifdef BFIN_SPECIAL_GPIO_BANKS +#ifdef ADI_SPECIAL_GPIO_BANKS DECLARE_RESERVED_MAP(special_gpio, gpio_bank(MAX_RESOURCES)); -int bfin_special_gpio_request(unsigned gpio, const char *label) +int special_gpio_request(unsigned gpio, const char *label) { /* * Allow that the identical GPIO can @@ -731,7 +655,7 @@ int bfin_special_gpio_request(unsigned gpio, const char *label) return 0; } -void bfin_special_gpio_free(unsigned gpio) +void special_gpio_free(unsigned gpio) { if (unlikely(!is_reserved(special_gpio, gpio, 0))) { gpio_error(gpio); @@ -744,21 +668,13 @@ void bfin_special_gpio_free(unsigned gpio) } #endif -static inline void __bfin_gpio_direction_input(unsigned gpio) +static inline void __gpio_direction_input(unsigned gpio) { -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) - gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio); -#else gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); -#endif -#if defined(CONFIG_BF60x) - gpio_array[gpio_bank(gpio)]->inen_set = gpio_bit(gpio); -#else gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio); -#endif } -int bfin_gpio_direction_input(unsigned gpio) +int gpio_direction_input(unsigned gpio) { unsigned long flags; @@ -768,31 +684,24 @@ int bfin_gpio_direction_input(unsigned gpio) } local_irq_save(flags); - __bfin_gpio_direction_input(gpio); + __gpio_direction_input(gpio); AWA_DUMMY_READ(inen); local_irq_restore(flags); return 0; } -void bfin_gpio_toggle_value(unsigned gpio) -{ -#ifdef CONFIG_BF54x - gpio_set_value(gpio, !gpio_get_value(gpio)); -#else - gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio); -#endif -} - -void bfin_gpio_set_value(unsigned gpio, int arg) +int gpio_set_value(unsigned gpio, int arg) { if (arg) gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio); else gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); + + return 0; } -int bfin_gpio_direction_output(unsigned gpio, int value) +int gpio_direction_output(unsigned gpio, int value) { unsigned long flags; @@ -803,17 +712,9 @@ int bfin_gpio_direction_output(unsigned gpio, int value) local_irq_save(flags); -#if defined(CONFIG_BF60x) - gpio_array[gpio_bank(gpio)]->inen_clear = gpio_bit(gpio); -#else gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); -#endif gpio_set_value(gpio, value); -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) - gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio); -#else gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio); -#endif AWA_DUMMY_READ(dir); local_irq_restore(flags); @@ -821,11 +722,8 @@ int bfin_gpio_direction_output(unsigned gpio, int value) return 0; } -int bfin_gpio_get_value(unsigned gpio) +int gpio_get_value(unsigned gpio) { -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) - return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio))); -#else unsigned long flags; if (unlikely(get_gpio_edge(gpio))) { @@ -838,7 +736,6 @@ int bfin_gpio_get_value(unsigned gpio) return ret; } else return get_gpio_data(gpio); -#endif } /* If we are booting from SPI and our board lacks a strong enough pull up, @@ -860,8 +757,7 @@ void bfin_reset_boot_spi_cs(unsigned short pin) udelay(1); } -#ifdef CONFIG_BFIN_GPIO_TRACK -void bfin_gpio_labels(void) +void gpio_labels(void) { int c, gpio; @@ -877,4 +773,3 @@ void bfin_gpio_labels(void) continue; } } -#endif diff --git a/arch/blackfin/cpu/initcode.c b/arch/blackfin/cpu/initcode.c index 1a066806d1..ffaf1017d7 100644 --- a/arch/blackfin/cpu/initcode.c +++ b/arch/blackfin/cpu/initcode.c @@ -13,12 +13,12 @@ #include <config.h> #include <asm/blackfin.h> +#include <asm/mach-common/bits/watchdog.h> #include <asm/mach-common/bits/bootrom.h> #include <asm/mach-common/bits/core.h> +#include <asm/serial.h> -#define BUG() while (1) { asm volatile("emuexcpt;"); } - -#include "serial.h" +#define BUG() while (1) asm volatile("emuexcpt;"); #ifndef __ADSPBF60x__ #include <asm/mach-common/bits/ebiu.h> @@ -193,17 +193,12 @@ static inline void serial_init(void) } #endif +#if CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS if (BFIN_DEBUG_EARLY_SERIAL) { - int enabled = serial_early_enabled(uart_base); - serial_early_init(uart_base); - - /* If the UART is off, that means we need to program - * the baud rate ourselves initially. - */ - if (!enabled) - serial_early_set_baud(uart_base, CONFIG_BAUDRATE); + serial_early_set_baud(uart_base, CONFIG_BAUDRATE); } +#endif } __attribute__((always_inline)) @@ -262,7 +257,8 @@ program_nmi_handler(void) "%1 = RETS;" /* Load addr of NMI handler */ "RETS = %0;" /* Restore RETS */ "[%2] = %1;" /* Write NMI handler */ - : "=r"(tmp1), "=r"(tmp2) : "ab"(EVT2) + : "=d"(tmp1), "=d"(tmp2) + : "ab"(EVT2) ); } @@ -462,19 +458,29 @@ program_early_devices(ADI_BOOT_DATA *bs, uint *sdivB, uint *divB, uint *vcoB) if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS) { serial_putc('e'); #ifdef __ADSPBF60x__ + /* Reset system event controller */ bfin_write_SEC_GCTL(0x2); + bfin_write_SEC_CCTL(0x2); SSYNC(); + + /* Enable fault event input and system reset action in fault + * controller. Route watchdog timeout event to fault interface. + */ bfin_write_SEC_FCTL(0xc1); + /* Enable watchdog interrupt source */ bfin_write_SEC_SCTL(2, bfin_read_SEC_SCTL(2) | 0x6); - - bfin_write_SEC_CCTL(0x2); SSYNC(); + + /* Enable system event controller */ bfin_write_SEC_GCTL(0x1); bfin_write_SEC_CCTL(0x1); + SSYNC(); #endif + bfin_write_WDOG_CTL(WDDIS); + SSYNC(); bfin_write_WDOG_CNT(MSEC_TO_SCLK(CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE)); #if CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_UART - bfin_write_WDOG_CTL(0); + bfin_write_WDOG_CTL(WDEN); #endif serial_putc('f'); } @@ -713,37 +719,32 @@ program_clocks(ADI_BOOT_DATA *bs, bool put_into_srfs) __attribute__((always_inline)) static inline void update_serial_clocks(ADI_BOOT_DATA *bs, uint sdivB, uint divB, uint vcoB) { - serial_putc('a'); - /* Since we've changed the SCLK above, we may need to update * the UART divisors (UART baud rates are based on SCLK). * Do the division by hand as there are no native instructions * for dividing which means we'd generate a libgcc reference. */ - if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) { - unsigned int sdivR, vcoR; - int dividend = sdivB * divB * vcoR; - int divisor = vcoB * sdivR; - unsigned int quotient; + unsigned int sdivR, vcoR; + unsigned int dividend; + unsigned int divisor; + unsigned int quotient; - serial_putc('b'); + serial_putc('a'); #ifdef __ADSPBF60x__ - sdivR = bfin_read_CGU_DIV(); - sdivR = ((sdivR >> 8) & 0x1f) * ((sdivR >> 5) & 0x7); - vcoR = (bfin_read_CGU_CTL() >> 8) & 0x7f; + sdivR = bfin_read_CGU_DIV(); + sdivR = ((sdivR >> 8) & 0x1f) * ((sdivR >> 5) & 0x7); + vcoR = (bfin_read_CGU_CTL() >> 8) & 0x7f; #else - sdivR = bfin_read_PLL_DIV() & 0xf; - vcoR = (bfin_read_PLL_CTL() >> 9) & 0x3f; + sdivR = bfin_read_PLL_DIV() & 0xf; + vcoR = (bfin_read_PLL_CTL() >> 9) & 0x3f; #endif - for (quotient = 0; dividend > 0; ++quotient) - dividend -= divisor; - serial_early_put_div(quotient - ANOMALY_05000230); - serial_putc('c'); - } - - serial_putc('d'); + dividend = sdivB * divB * vcoR; + divisor = vcoB * sdivR; + quotient = early_division(dividend, divisor); + serial_early_put_div(quotient - ANOMALY_05000230); + serial_putc('c'); } __attribute__((always_inline)) static inline void diff --git a/arch/blackfin/cpu/start.S b/arch/blackfin/cpu/start.S index 7155fc858b..da084a87c6 100644 --- a/arch/blackfin/cpu/start.S +++ b/arch/blackfin/cpu/start.S @@ -32,10 +32,10 @@ #include <config.h> #include <asm/blackfin.h> +#include <asm/mach-common/bits/watchdog.h> #include <asm/mach-common/bits/core.h> #include <asm/mach-common/bits/pll.h> - -#include "serial.h" +#include <asm/serial.h> /* It may seem odd that we make calls to functions even though we haven't * relocated ourselves yet out of {flash,ram,wherever}. This is OK because @@ -65,20 +65,29 @@ ENTRY(_start) p5.h = HI(COREMMR_BASE); #ifdef CONFIG_HW_WATCHDOG -#ifndef __ADSPBF60x__ -# ifndef CONFIG_HW_WATCHDOG_TIMEOUT_START -# define CONFIG_HW_WATCHDOG_TIMEOUT_START 5000 -# endif - /* Program the watchdog with an initial timeout of ~5 seconds. + /* Program the watchdog with default timeout of ~5 seconds. * That should be long enough to bootstrap ourselves up and * then the common u-boot code can take over. */ + r1 = WDDIS; +# ifdef __ADSPBF60x__ + [p4 + (WDOG_CTL - SYSMMR_BASE)] = r1; +# else + W[p4 + (WDOG_CTL - SYSMMR_BASE)] = r1; +# endif + SSYNC; r0 = 0; - r0.h = HI(MSEC_TO_SCLK(CONFIG_HW_WATCHDOG_TIMEOUT_START)); + r0.h = HI(MSEC_TO_SCLK(CONFIG_WATCHDOG_TIMEOUT_MSECS)); [p4 + (WDOG_CNT - SYSMMR_BASE)] = r0; + SSYNC; + r1 = WDEN; /* fire up the watchdog - R0.L above needs to be 0x0000 */ - W[p4 + (WDOG_CTL - SYSMMR_BASE)] = r0; -#endif +# ifdef __ADSPBF60x__ + [p4 + (WDOG_CTL - SYSMMR_BASE)] = r1; +# else + W[p4 + (WDOG_CTL - SYSMMR_BASE)] = r1; +# endif + SSYNC; #endif /* Turn on the serial for debugging the init process */ diff --git a/arch/blackfin/include/asm/clock.h b/arch/blackfin/include/asm/clock.h new file mode 100644 index 0000000000..f1fcd40499 --- /dev/null +++ b/arch/blackfin/include/asm/clock.h @@ -0,0 +1,78 @@ + +/* + * Copyright (C) 2012 Analog Devices Inc. + * Licensed under the GPL-2 or later. + */ + +#ifndef __CLOCK_H__ +#define __CLOCK_H__ + +#include <asm/blackfin.h> +#ifdef PLL_CTL +#include <asm/mach-common/bits/pll.h> +# define pll_is_bypassed() (bfin_read_PLL_CTL() & BYPASS) +#else +#include <asm/mach-common/bits/cgu.h> +# define pll_is_bypassed() (bfin_read_CGU_STAT() & PLLBP) +# define bfin_read_PLL_CTL() bfin_read_CGU_CTL() +# define bfin_read_PLL_DIV() bfin_read_CGU_DIV() +# define SSEL SYSSEL +# define SSEL_P SYSSEL_P +#endif + +__attribute__((always_inline)) +static inline uint32_t early_division(uint32_t dividend, uint32_t divisor) +{ + uint32_t quotient; + uint32_t i, j; + + for (quotient = 1, i = 1; dividend > divisor; ++i) { + j = divisor << i; + if (j > dividend || (j & 0x80000000)) { + --i; + quotient += (1 << i); + dividend -= (divisor << i); + i = 0; + } + } + + return quotient; +} + +__attribute__((always_inline)) +static inline uint32_t early_get_uart_clk(void) +{ + uint32_t msel, pll_ctl, vco; + uint32_t div, ssel, sclk, uclk; + + pll_ctl = bfin_read_PLL_CTL(); + msel = (pll_ctl & MSEL) >> MSEL_P; + if (msel == 0) + msel = (MSEL >> MSEL_P) + 1; + + vco = (CONFIG_CLKIN_HZ >> (pll_ctl & DF)) * msel; + sclk = vco; + if (!pll_is_bypassed()) { + div = bfin_read_PLL_DIV(); + ssel = (div & SSEL) >> SSEL_P; +#if CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS + sclk = vco/ssel; +#else + sclk = early_division(vco, ssel); +#endif + } + uclk = sclk; +#ifdef CGU_DIV + ssel = (div & S0SEL) >> S0SEL_P; + uclk = early_division(sclk, ssel); +#endif + return uclk; +} + +#ifdef CGU_DIV +# define get_uart_clk get_sclk0 +#else +# define get_uart_clk get_sclk +#endif + +#endif diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index ef1db6e99c..8a7c07933e 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -17,21 +17,21 @@ struct dmasg_large { void *next_desc_addr; - unsigned long start_addr; - unsigned short cfg; - unsigned short x_count; - short x_modify; - unsigned short y_count; - short y_modify; + u32 start_addr; + u16 cfg; + u16 x_count; + s16 x_modify; + u16 y_count; + s16 y_modify; } __attribute__((packed)); struct dmasg { - unsigned long start_addr; - unsigned short cfg; - unsigned short x_count; - short x_modify; - unsigned short y_count; - short y_modify; + u32 start_addr; + u16 cfg; + u16 x_count; + s16 x_modify; + u16 y_count; + s16 y_modify; } __attribute__((packed)); struct dma_register { diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h index 05131b5e8b..58a6191107 100644 --- a/arch/blackfin/include/asm/gpio.h +++ b/arch/blackfin/include/asm/gpio.h @@ -7,6 +7,8 @@ #ifndef __ARCH_BLACKFIN_GPIO_H__ #define __ARCH_BLACKFIN_GPIO_H__ +#include <asm-generic/gpio.h> + #define gpio_bank(x) ((x) >> 4) #define gpio_bit(x) (1<<((x) & 0xF)) #define gpio_sub_n(x) ((x) & 0xF) @@ -65,10 +67,11 @@ #define PERIPHERAL_USAGE 1 #define GPIO_USAGE 0 +#define MAX_GPIOS MAX_BLACKFIN_GPIOS #ifndef __ASSEMBLY__ -#if !defined(CONFIG_BF54x) && !defined(CONFIG_BF60x) +#ifdef CONFIG_ADI_GPIO1 void set_gpio_dir(unsigned, unsigned short); void set_gpio_inen(unsigned, unsigned short); void set_gpio_polar(unsigned, unsigned short); @@ -140,61 +143,16 @@ struct gpio_port_t { }; #endif -#ifdef CONFIG_BFIN_GPIO_TRACK -void bfin_gpio_labels(void); -void bfin_gpio_free(unsigned gpio); -#else -#define bfin_gpio_labels() -#define bfin_gpio_free(gpio) -#define bfin_gpio_request(gpio, label) bfin_gpio_request(gpio) -#define bfin_special_gpio_request(gpio, label) bfin_special_gpio_request(gpio) -#endif - -#ifdef BFIN_SPECIAL_GPIO_BANKS -void bfin_special_gpio_free(unsigned gpio); -int bfin_special_gpio_request(unsigned gpio, const char *label); +#ifdef ADI_SPECIAL_GPIO_BANKS +void special_gpio_free(unsigned gpio); +int special_gpio_request(unsigned gpio, const char *label); #endif -int bfin_gpio_request(unsigned gpio, const char *label); -int bfin_gpio_direction_input(unsigned gpio); -int bfin_gpio_direction_output(unsigned gpio, int value); -int bfin_gpio_get_value(unsigned gpio); -void bfin_gpio_set_value(unsigned gpio, int value); -void bfin_gpio_toggle_value(unsigned gpio); - -static inline int gpio_request(unsigned gpio, const char *label) -{ - return bfin_gpio_request(gpio, label); -} - -static inline void gpio_free(unsigned gpio) -{ - return bfin_gpio_free(gpio); -} - -static inline int gpio_direction_input(unsigned gpio) -{ - return bfin_gpio_direction_input(gpio); -} - -static inline int gpio_direction_output(unsigned gpio, int value) -{ - return bfin_gpio_direction_output(gpio, value); -} - -static inline int gpio_get_value(unsigned gpio) -{ - return bfin_gpio_get_value(gpio); -} - -static inline void gpio_set_value(unsigned gpio, int value) -{ - return bfin_gpio_set_value(gpio, value); -} +void gpio_labels(void); static inline int gpio_is_valid(int number) { - return number >= 0 && number < MAX_BLACKFIN_GPIOS; + return number >= 0 && number < MAX_GPIOS; } #include <linux/ctype.h> @@ -248,7 +206,7 @@ static inline int name_to_gpio(const char *name) } #define name_to_gpio(n) name_to_gpio(n) -#define gpio_status() bfin_gpio_labels() +#define gpio_status() gpio_labels() #endif /* __ASSEMBLY__ */ diff --git a/arch/blackfin/include/asm/mach-bf561/BF561_def.h b/arch/blackfin/include/asm/mach-bf561/BF561_def.h index a7ff5a3feb..8fd552f2a1 100644 --- a/arch/blackfin/include/asm/mach-bf561/BF561_def.h +++ b/arch/blackfin/include/asm/mach-bf561/BF561_def.h @@ -714,4 +714,6 @@ #define L1_INST_SRAM_SIZE (0xFFA03FFF - 0xFFA00000 + 1) #define L1_INST_SRAM_END (L1_INST_SRAM + L1_INST_SRAM_SIZE) +#define COREB_L1_CODE_START 0xFF600000 + #endif /* __BFIN_DEF_ADSP_BF561_proc__ */ diff --git a/arch/blackfin/include/asm/mach-bf609/BF609_def.h b/arch/blackfin/include/asm/mach-bf609/BF609_def.h index 8c1dcd006e..02b81d3fd1 100644 --- a/arch/blackfin/include/asm/mach-bf609/BF609_def.h +++ b/arch/blackfin/include/asm/mach-bf609/BF609_def.h @@ -128,6 +128,9 @@ #define EMAC0_MACCFG 0xFFC20000 /* EMAC0 MAC Configuration Register */ #define EMAC1_MACCFG 0xFFC22000 /* EMAC1 MAC Configuration Register */ +#define SPI0_REGBASE 0xFFC40400 /* SPI0 Base Address */ +#define SPI1_REGBASE 0xFFC40500 /* SPI1 Base Address */ + #define DMA10_DSCPTR_NXT 0xFFC05000 /* DMA10 Pointer to Next Initial Desc */ #define DMA10_ADDRSTART 0xFFC05004 /* DMA10 Start Address of Current Buf */ #define DMA10_CFG 0xFFC05008 /* DMA10 Configuration Register */ @@ -244,4 +247,6 @@ #define L1_INST_SRAM_SIZE 0x8000 #define L1_INST_SRAM_END (L1_INST_SRAM + L1_INST_SRAM_SIZE) +#define COREB_L1_CODE_START 0xFF600000 + #endif /* __BFIN_DEF_ADSP_BF609_proc__ */ diff --git a/arch/blackfin/include/asm/portmux.h b/arch/blackfin/include/asm/portmux.h index 300ef44fd1..003694b515 100644 --- a/arch/blackfin/include/asm/portmux.h +++ b/arch/blackfin/include/asm/portmux.h @@ -17,11 +17,6 @@ #define P_MAYSHARE 0x2000 #define P_DONTCARE 0x1000 -#ifndef CONFIG_BFIN_GPIO_TRACK -#define peripheral_request(per, label) peripheral_request(per) -#define peripheral_request_list(per, label) peripheral_request_list(per) -#endif - #ifndef __ASSEMBLY__ int peripheral_request(unsigned short per, const char *label); diff --git a/arch/blackfin/cpu/serial.h b/arch/blackfin/include/asm/serial.h index 9200339668..87a337d1b4 100644 --- a/arch/blackfin/cpu/serial.h +++ b/arch/blackfin/include/asm/serial.h @@ -78,19 +78,31 @@ static inline void serial_early_puts(const char *s) #else .macro serial_early_init -#ifdef CONFIG_DEBUG_EARLY_SERIAL - call _serial_initialize; +#if defined(CONFIG_DEBUG_EARLY_SERIAL) && !defined(CONFIG_UART_MEM) + call __serial_early_init; #endif .endm .macro serial_early_set_baud -#ifdef CONFIG_DEBUG_EARLY_SERIAL +#if defined(CONFIG_DEBUG_EARLY_SERIAL) && !defined(CONFIG_UART_MEM) R0.L = LO(CONFIG_BAUDRATE); R0.H = HI(CONFIG_BAUDRATE); - call _serial_set_baud; + call __serial_early_set_baud; #endif .endm +#if CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS +#define update_serial_early_string_addr \ + R1.L = _start; \ + R1.H = _start; \ + R0 = R0 - R1; \ + R1.L = 0; \ + R1.H = 0x2000; \ + R0 = R0 + R1; +#else +#define update_serial_early_string_addr +#endif + /* Since we embed the string right into our .text section, we need * to find its address. We do this by getting our PC and adding 2 * bytes (which is the length of the jump instruction). Then we @@ -108,7 +120,8 @@ static inline void serial_early_puts(const char *s) .previous; \ R0.L = 7b; \ R0.H = 7b; \ - call _serial_puts; + update_serial_early_string_addr \ + call _uart_early_puts; #else # define serial_early_puts(str) #endif diff --git a/arch/blackfin/cpu/serial1.h b/arch/blackfin/include/asm/serial1.h index a20175bc7f..467d3817f1 100644 --- a/arch/blackfin/cpu/serial1.h +++ b/arch/blackfin/include/asm/serial1.h @@ -15,6 +15,8 @@ #ifndef __ASSEMBLY__ +#include <asm/clock.h> + #define MMR_UART(n) _PASTE_UART(n, UART, DLL) #ifdef UART_DLL # define UART0_DLL UART_DLL @@ -230,19 +232,6 @@ static inline void serial_early_do_portmux(void) } __attribute__((always_inline)) -static inline uint32_t uart_sclk(void) -{ -#if defined(BFIN_IN_INITCODE) || defined(CONFIG_DEBUG_EARLY_SERIAL) - /* We cannot use get_sclk() early on as it uses - * caches in external memory - */ - return CONFIG_CLKIN_HZ * CONFIG_VCO_MULT / CONFIG_SCLK_DIV; -#else - return get_sclk(); -#endif -} - -__attribute__((always_inline)) static inline int uart_init(uint32_t uart_base) { /* always enable UART -- avoids anomalies 05000309 and 05000350 */ @@ -275,21 +264,8 @@ static inline int serial_early_uninit(uint32_t uart_base) } __attribute__((always_inline)) -static inline int serial_early_enabled(uint32_t uart_base) +static inline void serial_set_divisor(uint32_t uart_base, uint16_t divisor) { - return bfin_read(&pUART->gctl) & UCEN; -} - -__attribute__((always_inline)) -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. - */ - uint16_t divisor = (uart_sclk() + (baud * 8)) / (baud * 16) - - ANOMALY_05000230; - /* Set DLAB in LCR to Access DLL and DLH */ ACCESS_LATCH(); SSYNC(); @@ -305,6 +281,24 @@ static inline void serial_early_set_baud(uint32_t uart_base, uint32_t baud) } __attribute__((always_inline)) +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. + */ +#if CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS + uint16_t divisor = (early_get_uart_clk() + baud * 8) / (baud * 16) + - ANOMALY_05000230; +#else + uint16_t divisor = early_division(early_get_uart_clk() + (baud * 8), + baud * 16) - ANOMALY_05000230; +#endif + + serial_set_divisor(uart_base, divisor); +} + +__attribute__((always_inline)) static inline void serial_early_put_div(uint16_t divisor) { uint32_t uart_base = UART_BASE; diff --git a/arch/blackfin/cpu/serial4.h b/arch/blackfin/include/asm/serial4.h index 887845c186..65483960b9 100644 --- a/arch/blackfin/cpu/serial4.h +++ b/arch/blackfin/include/asm/serial4.h @@ -15,6 +15,8 @@ #ifndef __ASSEMBLY__ +#include <asm/clock.h> + #define MMR_UART(n) _PASTE_UART(n, UART, REVID) #define UART_BASE MMR_UART(CONFIG_UART_CONSOLE) @@ -84,20 +86,6 @@ static inline void serial_early_do_portmux(void) } __attribute__((always_inline)) -static inline uint32_t uart_sclk(void) -{ -#if defined(BFIN_IN_INITCODE) || defined(CONFIG_DEBUG_EARLY_SERIAL) - /* We cannot use get_sclk() early on as it uses caches in - * external memory - */ - return CONFIG_CLKIN_HZ * CONFIG_VCO_MULT / CONFIG_SCLK_DIV / - CONFIG_SCLK0_DIV; -#else - return get_sclk0(); -#endif -} - -__attribute__((always_inline)) static inline int uart_init(uint32_t uart_base) { /* always enable UART to 8-bit mode */ @@ -127,19 +115,20 @@ static inline int serial_early_uninit(uint32_t uart_base) } __attribute__((always_inline)) -static inline int serial_early_enabled(uint32_t uart_base) +static inline void serial_set_divisor(uint32_t uart_base, uint16_t divisor) { - return bfin_read(&pUART->control) & UEN; + /* Program the divisor to get the baud rate we want */ + bfin_write(&pUART->clock, divisor); + SSYNC(); } __attribute__((always_inline)) static inline void serial_early_set_baud(uint32_t uart_base, uint32_t baud) { - uint32_t divisor = uart_sclk() / (baud * 16); + uint16_t divisor = early_division(early_get_uart_clk(), baud * 16); /* Program the divisor to get the baud rate we want */ - bfin_write(&pUART->clock, divisor); - SSYNC(); + serial_set_divisor(uart_base, divisor); } __attribute__((always_inline)) diff --git a/arch/blackfin/include/asm/soft_switch.h b/arch/blackfin/include/asm/soft_switch.h new file mode 100644 index 0000000000..ff8e44d8be --- /dev/null +++ b/arch/blackfin/include/asm/soft_switch.h @@ -0,0 +1,18 @@ +/* + * U-boot - main board file + * + * Copyright (c) 2008-2012 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __SOFT_SWITCH_H__ +#define __SOFT_SWITCH_H__ + +#define IO_PORT_A 0 +#define IO_PORT_B 1 +#define IO_PORT_INPUT 0 +#define IO_PORT_OUTPUT 1 + +int config_switch_bit(int num, int port, int bit, int dir, uchar value); +#endif diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c index ccea3b9fb1..f1d55470e8 100644 --- a/arch/blackfin/lib/board.c +++ b/arch/blackfin/lib/board.c @@ -231,6 +231,8 @@ static int global_board_data_init(void) bd->bi_sclk = get_sclk(); bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE; + bd->bi_baudrate = (gd->baudrate > 0) + ? simple_strtoul(gd->baudrate, NULL, 10) : CONFIG_BAUDRATE; return 0; } @@ -277,9 +279,9 @@ void board_init_f(ulong bootflag) dcache_enable(); #endif -#ifdef CONFIG_WATCHDOG +#ifdef CONFIG_HW_WATCHDOG serial_early_puts("Setting up external watchdog\n"); - watchdog_init(); + hw_watchdog_init(); #endif #ifdef DEBUG diff --git a/arch/blackfin/lib/clocks.c b/arch/blackfin/lib/clocks.c index d852f5ebed..97795e11ac 100644 --- a/arch/blackfin/lib/clocks.c +++ b/arch/blackfin/lib/clocks.c @@ -7,17 +7,7 @@ */ #include <common.h> -#include <asm/blackfin.h> - -#ifdef PLL_CTL -# include <asm/mach-common/bits/pll.h> -# define pll_is_bypassed() (bfin_read_PLL_STAT() & DF) -#else -# include <asm/mach-common/bits/cgu.h> -# define pll_is_bypassed() (bfin_read_CGU_STAT() & PLLBP) -# define bfin_read_PLL_CTL() bfin_read_CGU_CTL() -# define bfin_read_PLL_DIV() bfin_read_CGU_DIV() -#endif +#include <asm/clock.h> /* Get the voltage input multiplier */ u_long get_vco(void) diff --git a/arch/blackfin/lib/string.c b/arch/blackfin/lib/string.c index 44d8c6d906..5b7ac0b91a 100644 --- a/arch/blackfin/lib/string.c +++ b/arch/blackfin/lib/string.c @@ -128,10 +128,12 @@ static void dma_calc_size(unsigned long ldst, unsigned long lsrc, size_t count, unsigned long limit; #ifdef MSIZE - limit = 6; + /* The max memory DMA memory transfer size is 32 bytes. */ + limit = 5; *dshift = MSIZE_P; #else - limit = 3; + /* The max memory DMA memory transfer size is 4 bytes. */ + limit = 2; *dshift = WDSIZE_P; #endif @@ -170,7 +172,8 @@ void dma_memcpy_nocache(void *dst, const void *src, size_t count) mod = 1 << bpos; #ifdef PSIZE - dsize |= min(3, bpos) << PSIZE_P; + /* The max memory DMA peripheral transfer size is 4 bytes. */ + dsize |= min(2, bpos) << PSIZE_P; #endif /* Copy sram functions from sdram to sram */ diff --git a/board/bf609-ezkit/soft_switch.c b/board/bf609-ezkit/soft_switch.c new file mode 100644 index 0000000000..e0c8d93fe7 --- /dev/null +++ b/board/bf609-ezkit/soft_switch.c @@ -0,0 +1,171 @@ +/* + * U-boot - main board file + * + * Copyright (c) 2008-2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <common.h> +#include <asm/blackfin.h> +#include <asm/io.h> +#include <i2c.h> +#include "soft_switch.h" + +struct switch_config { + uchar dir0; /* IODIRA */ + uchar dir1; /* IODIRB */ + uchar value0; /* OLATA */ + uchar value1; /* OLATB */ +}; + +static struct switch_config switch_config_array[NUM_SWITCH] = { + { +/* + U45 Port A U45 Port B + + 7--------------- RMII_CLK_EN | 7--------------- ~TEMP_THERM_EN + | 6------------- ~CNT0ZM_EN | | 6------------- ~TEMP_IRQ_EN + | | 5----------- ~CNT0DG_EN | | | 5----------- ~UART0CTS_146_EN + | | | 4--------- ~CNT0UD_EN | | | | 4--------- ~UART0CTS_RST_EN + | | | | 3------- ~CAN0RX_EN | | | | | 3------- ~UART0CTS_RTS_LPBK + | | | | | 2----- ~CAN0_ERR_EN | | | | | | 2----- ~UART0CTS_EN + | | | | | | 1--- ~CAN_STB | | | | | | | 1--- ~UART0RX_EN + | | | | | | | 0- CAN_EN | | | | | | | | 0- ~UART0RTS_EN + | | | | | | | | | | | | | | | | | + O O O O O O O O | O O O O O O O O (I/O direction) + 1 0 0 0 0 0 1 1 | 1 1 1 1 1 0 0 0 (value being set) +*/ + .dir0 = 0x0, /* all output */ + .dir1 = 0x0, /* all output */ + .value0 = RMII_CLK_EN | CAN_STB | CAN_EN, + .value1 = TEMP_THERM_EN | TEMP_IRQ_EN | UART0CTS_146_EN + | UART0CTS_RST_EN | UART0CTS_RTS_LPBK, + }, + { +/* + U46 Port A U46 Port B + + 7--------------- ~LED4_GPIO_EN | 7--------------- EMPTY + | 6------------- ~LED3_GPIO_EN | | 6------------- ~SPI0D3_EN + | | 5----------- ~LED2_GPIO_EN | | | 5----------- ~SPI0D2_EN + | | | 4--------- ~LED1_GPIO_EN | | | | 4--------- ~SPIFLASH_CS_EN + | | | | 3------- SMC0_LP0_EN | | | | | 3------- ~SD_WP_EN + | | | | | 2----- EMPTY | | | | | | 2----- ~SD_CD_EN + | | | | | | 1--- SMC0_EPPI2 | | | | | | | 1--- ~PUSHBUTTON2_EN + _LP1_SWITCH + | | | | | | | 0- OVERRIDE_SMC0 | | | | | | | | 0- ~PUSHBUTTON1_EN + _LP0_BOOT + | | | | | | | | | | | | | | | | | + O O O O O O O O | O O O O O O O O (I/O direction) + 0 0 0 0 0 X 0 1 | X 0 0 0 0 0 0 0 (value being set) +*/ + .dir0 = 0x0, /* all output */ + .dir1 = 0x0, /* all output */ +#ifdef CONFIG_BFIN_LINKPORT + .value0 = OVERRIDE_SMC0_LP0_BOOT, +#else + .value0 = SMC0_EPPI2_LP1_SWITCH, +#endif + .value1 = 0x0, + }, + { +/* + U47 Port A U47 Port B + + 7--------------- ~PD2_SPI0MISO | 7--------------- EMPTY + _EI3_EN + | 6------------- ~PD1_SPI0D3 | | 6------------- EMPTY + _EPPI1D17 + _SPI0SEL2 + _EI3_EN + | | 5----------- ~PD0_SPI0D2 | | | 5----------- EMPTY + _EPPI1D16 + _SPI0SEL3 + _EI3_EN + | | | 4--------- ~WAKE_PUSH | | | | 4--------- EMPTY + BUTTON_EN + | | | | 3------- ~ETHERNET_EN | | | | | 3------- EMPTY + | | | | | 2----- PHYAD0 | | | | | | 2----- EMPTY + | | | | | | 1--- PHY_PWR | | | | | | | 1--- ~PD4_SPI0CK_EI3_EN + _DWN_INT + | | | | | | | 0- ~PHYINT_EN | | | | | | | | 0- ~PD3_SPI0MOSI_EI3_EN + | | | | | | | | | | | | | | | | | + O O O O O I I O | O O O O O O O O (I/O direction) + 1 1 1 0 0 0 0 0 | X X X X X X 1 1 (value being set) +*/ + .dir0 = 0x6, /* bits 1 and 2 input, all others output */ + .dir1 = 0x0, /* all output */ + .value0 = PD1_SPI0D3_EN | PD0_SPI0D2_EN, + .value1 = 0, + }, +}; + +static int setup_soft_switch(int addr, struct switch_config *config) +{ + int ret = 0; + + ret = i2c_write(addr, OLATA, 1, &config->value0, 1); + if (ret) + return ret; + ret = i2c_write(addr, OLATB, 1, &config->value1, 1); + if (ret) + return ret; + + ret = i2c_write(addr, IODIRA, 1, &config->dir0, 1); + if (ret) + return ret; + return i2c_write(addr, IODIRB, 1, &config->dir1, 1); +} + +int config_switch_bit(int addr, int port, int bit, int dir, uchar value) +{ + int ret, data_reg, dir_reg; + uchar tmp; + + if (port == IO_PORT_A) { + data_reg = OLATA; + dir_reg = IODIRA; + } else { + data_reg = OLATB; + dir_reg = IODIRB; + } + + if (dir == IO_PORT_INPUT) { + ret = i2c_read(addr, dir_reg, 1, &tmp, 1); + if (ret) + return ret; + tmp |= bit; + return i2c_write(addr, dir_reg, 1, &tmp, 1); + } else { + ret = i2c_read(addr, data_reg, 1, &tmp, 1); + if (ret) + return ret; + if (value) + tmp |= bit; + else + tmp &= ~bit; + ret = i2c_write(addr, data_reg, 1, &tmp, 1); + if (ret) + return ret; + ret = i2c_read(addr, dir_reg, 1, &tmp, 1); + if (ret) + return ret; + tmp &= ~bit; + return i2c_write(addr, dir_reg, 1, &tmp, 1); + } +} + +int setup_board_switches(void) +{ + int ret; + int i; + + for (i = 0; i < NUM_SWITCH; i++) { + ret = setup_soft_switch(SWITCH_ADDR + i, + &switch_config_array[i]); + if (ret) + return ret; + } + return 0; +} diff --git a/board/bf609-ezkit/soft_switch.h b/board/bf609-ezkit/soft_switch.h new file mode 100644 index 0000000000..d147fe1378 --- /dev/null +++ b/board/bf609-ezkit/soft_switch.h @@ -0,0 +1,80 @@ +/* + * U-boot - main board file + * + * Copyright (c) 2008-2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __BOARD_SOFT_SWITCH_H__ +#define __BOARD_SOFT_SWITCH_H__ + +#include <asm/soft_switch.h> + +/* switch 0 port A */ +#define CAN_EN 0x1 +#define CAN_STB 0x2 +#define CAN0_ERR_EN 0x4 +#define CAN0RX_EN 0x8 +#define CNT0UD_EN 0x10 +#define CNT0DG_EN 0x20 +#define CNT0ZM_EN 0x40 +#define RMII_CLK_EN 0x80 + +/* switch 0 port B */ +#define UART0RTS_EN 0x1 +#define UART0RX_EN 0x2 +#define UART0CTS_EN 0x4 +#define UART0CTS_RTS_LPBK 0x8 +#define UART0CTS_RST_EN 0x10 +#define UART0CTS_146_EN 0x20 +#define TEMP_IRQ_EN 0x40 +#define TEMP_THERM_EN 0x80 + +/* switch 1 port A */ +#define OVERRIDE_SMC0_LP0_BOOT 0x1 +#define SMC0_EPPI2_LP1_SWITCH 0x2 +#define SMC0_LP0_EN 0x8 +#define LED1_GPIO_EN 0x10 +#define LED2_GPIO_EN 0x20 +#define LED3_GPIO_EN 0x40 +#define LED4_GPIO_EN 0x80 + +/* switch 1 port B */ +#define PUSHBUTTON1_EN 0x1 +#define PUSHBUTTON2_EN 0x2 +#define SD_CD_EN 0x4 +#define SD_WP_EN 0x8 +#define SPIFLASH_CS_EN 0x10 +#define SPI0D2_EN 0x20 +#define SPI0D3_EN 0x40 + +/* switch 2 port A */ +#define PHYINT_EN 0x1 +#define PHY_PWR_DWN_INT 0x2 +#define PHYAD0 0x4 +#define ETHERNET_EN 0x8 +#define WAKE_PUSHBUTTON_EN 0x10 +#define PD0_SPI0D2_EN 0x20 +#define PD1_SPI0D3_EN 0x40 +#define PD2_SPI0MISO_EN 0x80 + +/* switch 2 port B */ +#define PD3_SPI0MOSI_EN 0x1 +#define PD4_SPI0CK_EN 0x2 + +#ifdef CONFIG_BFIN_BOARD_VERSION_1_0 +#define SWITCH_ADDR 0x21 +#else +#define SWITCH_ADDR 0x20 +#endif + +#define NUM_SWITCH 3 +#define IODIRA 0x0 +#define IODIRB 0x1 +#define OLATA 0x14 +#define OLATB 0x15 + +int setup_board_switches(void); + +#endif /* __BOARD_SOFT_SWITCH_H__ */ diff --git a/common/Makefile b/common/Makefile index 0e0fff1ffa..0429a3c51c 100644 --- a/common/Makefile +++ b/common/Makefile @@ -164,6 +164,7 @@ COBJS-$(CONFIG_CMD_SF) += cmd_sf.o COBJS-$(CONFIG_CMD_SCSI) += cmd_scsi.o COBJS-$(CONFIG_CMD_SHA1SUM) += cmd_sha1sum.o COBJS-$(CONFIG_CMD_SETEXPR) += cmd_setexpr.o +COBJS-$(CONFIG_CMD_SOFTSWITCH) += cmd_softswitch.o COBJS-$(CONFIG_CMD_SPI) += cmd_spi.o COBJS-$(CONFIG_CMD_SPIBOOTLDR) += cmd_spibootldr.o COBJS-$(CONFIG_CMD_STRINGS) += cmd_strings.o diff --git a/common/cmd_softswitch.c b/common/cmd_softswitch.c new file mode 100644 index 0000000000..f75d926770 --- /dev/null +++ b/common/cmd_softswitch.c @@ -0,0 +1,41 @@ +/* + * cmd_softswitch.c - set the softswitch for bf60x + * + * Copyright (c) 2012 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <common.h> +#include <command.h> +#include <asm/blackfin.h> +#include <asm/soft_switch.h> + +int do_softswitch(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int switchaddr, value, pin, port; + + if (argc != 5) + return CMD_RET_USAGE; + + if (strcmp(argv[2], "GPA") == 0) + port = IO_PORT_A; + else if (strcmp(argv[2], "GPB") == 0) + port = IO_PORT_B; + else + return CMD_RET_USAGE; + + switchaddr = simple_strtoul(argv[1], NULL, 16); + pin = simple_strtoul(argv[3], NULL, 16); + value = simple_strtoul(argv[4], NULL, 16); + + config_switch_bit(switchaddr, port, (1 << pin), IO_PORT_OUTPUT, value); + + return 0; +} + +U_BOOT_CMD( + softswitch_output, 5, 1, do_softswitch, + "switchaddr GPA/GPB pin_offset value", + "" +); diff --git a/doc/README.watchdog b/doc/README.watchdog index 33f31c2140..59f306b851 100644 --- a/doc/README.watchdog +++ b/doc/README.watchdog @@ -30,3 +30,6 @@ CONFIG_IMX_WATCHDOG CONFIG_XILINX_TB_WATCHDOG Available for Xilinx Axi platforms to service timebase watchdog timer. + +CONFIG_BFIN_WATCHDOG + Available for bf5xx and bf6xx to service the watchdog. diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 830e8e691a..f77c1ec1ef 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -48,6 +48,7 @@ COBJS-$(CONFIG_DB8500_GPIO) += db8500_gpio.o COBJS-$(CONFIG_BCM2835_GPIO) += bcm2835_gpio.o COBJS-$(CONFIG_S3C2440_GPIO) += s3c2440_gpio.o COBJS-$(CONFIG_XILINX_GPIO) += xilinx_gpio.o +COBJS-$(CONFIG_ADI_GPIO2) += adi_gpio2.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/gpio/adi_gpio2.c b/drivers/gpio/adi_gpio2.c new file mode 100644 index 0000000000..7a034eba12 --- /dev/null +++ b/drivers/gpio/adi_gpio2.c @@ -0,0 +1,440 @@ +/* + * ADI GPIO2 Abstraction Layer + * Support BF54x, BF60x and future processors. + * + * Copyright 2008-2013 Analog Devices Inc. + * + * Licensed under the GPL-2 or later + */ + +#include <common.h> +#include <asm/errno.h> +#include <asm/gpio.h> +#include <asm/portmux.h> + +static struct gpio_port_t * const gpio_array[] = { + (struct gpio_port_t *)PORTA_FER, + (struct gpio_port_t *)PORTB_FER, + (struct gpio_port_t *)PORTC_FER, + (struct gpio_port_t *)PORTD_FER, + (struct gpio_port_t *)PORTE_FER, + (struct gpio_port_t *)PORTF_FER, + (struct gpio_port_t *)PORTG_FER, +#if defined(CONFIG_BF54x) + (struct gpio_port_t *)PORTH_FER, + (struct gpio_port_t *)PORTI_FER, + (struct gpio_port_t *)PORTJ_FER, +#endif +}; + +#define RESOURCE_LABEL_SIZE 16 + +static struct str_ident { + char name[RESOURCE_LABEL_SIZE]; +} str_ident[MAX_RESOURCES]; + +static void gpio_error(unsigned gpio) +{ + printf("adi_gpio2: GPIO %d wasn't requested!\n", gpio); +} + +static void set_label(unsigned short ident, const char *label) +{ + if (label) { + strncpy(str_ident[ident].name, label, + RESOURCE_LABEL_SIZE); + str_ident[ident].name[RESOURCE_LABEL_SIZE - 1] = 0; + } +} + +static char *get_label(unsigned short ident) +{ + return *str_ident[ident].name ? str_ident[ident].name : "UNKNOWN"; +} + +static int cmp_label(unsigned short ident, const char *label) +{ + if (label == NULL) + printf("adi_gpio2: please provide none-null label\n"); + + if (label) + return strcmp(str_ident[ident].name, label); + else + return -EINVAL; +} + +#define map_entry(m, i) reserved_##m##_map[gpio_bank(i)] +#define is_reserved(m, i, e) (map_entry(m, i) & gpio_bit(i)) +#define reserve(m, i) (map_entry(m, i) |= gpio_bit(i)) +#define unreserve(m, i) (map_entry(m, i) &= ~gpio_bit(i)) +#define DECLARE_RESERVED_MAP(m, c) unsigned short reserved_##m##_map[c] + +static DECLARE_RESERVED_MAP(gpio, GPIO_BANK_NUM); +static DECLARE_RESERVED_MAP(peri, gpio_bank(MAX_RESOURCES)); + +inline int check_gpio(unsigned gpio) +{ +#if defined(CONFIG_BF54x) + if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 || + gpio == GPIO_PH14 || gpio == GPIO_PH15 || + gpio == GPIO_PJ14 || gpio == GPIO_PJ15) + return -EINVAL; +#endif + if (gpio >= MAX_GPIOS) + return -EINVAL; + return 0; +} + +static void port_setup(unsigned gpio, unsigned short usage) +{ +#if defined(CONFIG_BF54x) + if (usage == GPIO_USAGE) + gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio); + else + gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio); +#else + if (usage == GPIO_USAGE) + gpio_array[gpio_bank(gpio)]->port_fer_clear = gpio_bit(gpio); + else + gpio_array[gpio_bank(gpio)]->port_fer_set = gpio_bit(gpio); +#endif + SSYNC(); +} + +inline void portmux_setup(unsigned short per) +{ + u32 pmux; + u16 ident = P_IDENT(per); + u16 function = P_FUNCT2MUX(per); + + pmux = gpio_array[gpio_bank(ident)]->port_mux; + + pmux &= ~(0x3 << (2 * gpio_sub_n(ident))); + pmux |= (function & 0x3) << (2 * gpio_sub_n(ident)); + + gpio_array[gpio_bank(ident)]->port_mux = pmux; +} + +inline u16 get_portmux(unsigned short per) +{ + u32 pmux; + u16 ident = P_IDENT(per); + + pmux = gpio_array[gpio_bank(ident)]->port_mux; + + return pmux >> (2 * gpio_sub_n(ident)) & 0x3; +} + +unsigned short get_gpio_dir(unsigned gpio) +{ + return 0x01 & + (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio)); +} + +/*********************************************************** +* +* FUNCTIONS: Peripheral Resource Allocation +* and PortMux Setup +* +* INPUTS/OUTPUTS: +* per Peripheral Identifier +* label String +* +* DESCRIPTION: Peripheral Resource Allocation and Setup API +**************************************************************/ + +int peripheral_request(unsigned short per, const char *label) +{ + unsigned short ident = P_IDENT(per); + + /* + * Don't cares are pins with only one dedicated function + */ + + if (per & P_DONTCARE) + return 0; + + if (!(per & P_DEFINED)) + return -ENODEV; + + BUG_ON(ident >= MAX_RESOURCES); + + /* If a pin can be muxed as either GPIO or peripheral, make + * sure it is not already a GPIO pin when we request it. + */ + if (unlikely(!check_gpio(ident) && is_reserved(gpio, ident, 1))) { + printf("%s: Peripheral %d is already reserved as GPIO by %s!\n", + __func__, ident, get_label(ident)); + return -EBUSY; + } + + if (unlikely(is_reserved(peri, ident, 1))) { + /* + * Pin functions like AMC address strobes my + * be requested and used by several drivers + */ + + if (!((per & P_MAYSHARE) && + get_portmux(per) == P_FUNCT2MUX(per))) { + /* + * Allow that the identical pin function can + * be requested from the same driver twice + */ + + if (cmp_label(ident, label) == 0) + goto anyway; + + printf("%s: Peripheral %d function %d is already " + "reserved by %s!\n", __func__, ident, + P_FUNCT2MUX(per), get_label(ident)); + return -EBUSY; + } + } + + anyway: + reserve(peri, ident); + + portmux_setup(per); + port_setup(ident, PERIPHERAL_USAGE); + + set_label(ident, label); + + return 0; +} + +int peripheral_request_list(const unsigned short per[], const char *label) +{ + u16 cnt; + int ret; + + for (cnt = 0; per[cnt] != 0; cnt++) { + ret = peripheral_request(per[cnt], label); + + if (ret < 0) { + for (; cnt > 0; cnt--) + peripheral_free(per[cnt - 1]); + + return ret; + } + } + + return 0; +} + +void peripheral_free(unsigned short per) +{ + unsigned short ident = P_IDENT(per); + + if (per & P_DONTCARE) + return; + + if (!(per & P_DEFINED)) + return; + + if (unlikely(!is_reserved(peri, ident, 0))) + return; + + if (!(per & P_MAYSHARE)) + port_setup(ident, GPIO_USAGE); + + unreserve(peri, ident); + + set_label(ident, "free"); +} + +void peripheral_free_list(const unsigned short per[]) +{ + u16 cnt; + for (cnt = 0; per[cnt] != 0; cnt++) + peripheral_free(per[cnt]); +} + +/*********************************************************** +* +* FUNCTIONS: GPIO Driver +* +* INPUTS/OUTPUTS: +* gpio PIO Number between 0 and MAX_GPIOS +* label String +* +* DESCRIPTION: GPIO Driver API +**************************************************************/ + +int gpio_request(unsigned gpio, const char *label) +{ + if (check_gpio(gpio) < 0) + return -EINVAL; + + /* + * Allow that the identical GPIO can + * be requested from the same driver twice + * Do nothing and return - + */ + + if (cmp_label(gpio, label) == 0) + return 0; + + if (unlikely(is_reserved(gpio, gpio, 1))) { + printf("adi_gpio2: GPIO %d is already reserved by %s!\n", + gpio, get_label(gpio)); + return -EBUSY; + } + if (unlikely(is_reserved(peri, gpio, 1))) { + printf("adi_gpio2: GPIO %d is already reserved as Peripheral " + "by %s!\n", gpio, get_label(gpio)); + return -EBUSY; + } + + reserve(gpio, gpio); + set_label(gpio, label); + + port_setup(gpio, GPIO_USAGE); + + return 0; +} + +int gpio_free(unsigned gpio) +{ + if (check_gpio(gpio) < 0) + return -1; + + if (unlikely(!is_reserved(gpio, gpio, 0))) { + gpio_error(gpio); + return -1; + } + + unreserve(gpio, gpio); + + set_label(gpio, "free"); + + return 0; +} + +#ifdef ADI_SPECIAL_GPIO_BANKS +static DECLARE_RESERVED_MAP(special_gpio, gpio_bank(MAX_RESOURCES)); + +int special_gpio_request(unsigned gpio, const char *label) +{ + /* + * Allow that the identical GPIO can + * be requested from the same driver twice + * Do nothing and return - + */ + + if (cmp_label(gpio, label) == 0) + return 0; + + if (unlikely(is_reserved(special_gpio, gpio, 1))) { + printf("adi_gpio2: GPIO %d is already reserved by %s!\n", + gpio, get_label(gpio)); + return -EBUSY; + } + if (unlikely(is_reserved(peri, gpio, 1))) { + printf("adi_gpio2: GPIO %d is already reserved as Peripheral " + "by %s!\n", gpio, get_label(gpio)); + + return -EBUSY; + } + + reserve(special_gpio, gpio); + reserve(peri, gpio); + + set_label(gpio, label); + port_setup(gpio, GPIO_USAGE); + + return 0; +} + +void special_gpio_free(unsigned gpio) +{ + if (unlikely(!is_reserved(special_gpio, gpio, 0))) { + gpio_error(gpio); + return; + } + + reserve(special_gpio, gpio); + reserve(peri, gpio); + set_label(gpio, "free"); +} +#endif + +static inline void __gpio_direction_input(unsigned gpio) +{ + gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio); +#if defined(CONFIG_BF54x) + gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio); +#else + gpio_array[gpio_bank(gpio)]->inen_set = gpio_bit(gpio); +#endif +} + +int gpio_direction_input(unsigned gpio) +{ + unsigned long flags; + + if (!is_reserved(gpio, gpio, 0)) { + gpio_error(gpio); + return -EINVAL; + } + + local_irq_save(flags); + __gpio_direction_input(gpio); + local_irq_restore(flags); + + return 0; +} + +int gpio_set_value(unsigned gpio, int arg) +{ + if (arg) + gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio); + else + gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); + + return 0; +} + +int gpio_direction_output(unsigned gpio, int value) +{ + unsigned long flags; + + if (!is_reserved(gpio, gpio, 0)) { + gpio_error(gpio); + return -EINVAL; + } + + local_irq_save(flags); + +#if defined(CONFIG_BF54x) + gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); +#else + gpio_array[gpio_bank(gpio)]->inen_clear = gpio_bit(gpio); +#endif + gpio_set_value(gpio, value); + gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio); + + local_irq_restore(flags); + + return 0; +} + +int gpio_get_value(unsigned gpio) +{ + return 1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio)); +} + +void gpio_labels(void) +{ + int c, gpio; + + for (c = 0; c < MAX_RESOURCES; c++) { + gpio = is_reserved(gpio, c, 1); + if (!check_gpio(c) && gpio) + printf("GPIO_%d:\t%s\tGPIO %s\n", c, get_label(c), + get_gpio_dir(c) ? "OUTPUT" : "INPUT"); + else if (is_reserved(peri, c, 1)) + printf("GPIO_%d:\t%s\tPeripheral\n", c, get_label(c)); + else + continue; + } +} diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index c63398ebf8..0ffd59d497 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c @@ -122,8 +122,6 @@ static int bfin_EMAC_send(struct eth_device *dev, void *packet, int length) { int i; int result = 0; - unsigned int *buf; - buf = (unsigned int *)packet; if (length <= 0) { printf("Ethernet: bad packet size: %d\n", length); diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index fbc4e97e98..442b7ea0df 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -52,6 +52,7 @@ COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o COBJS-$(CONFIG_SANDBOX_SERIAL) += sandbox.o COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o COBJS-$(CONFIG_ZYNQ_SERIAL) += serial_zynq.o +COBJS-$(CONFIG_BFIN_SERIAL) += serial_bfin.o ifndef CONFIG_SPL_BUILD COBJS-$(CONFIG_USB_TTY) += usbtty.o diff --git a/arch/blackfin/cpu/serial.c b/drivers/serial/serial_bfin.c index 9847e9f2c5..0443b8427a 100644 --- a/arch/blackfin/cpu/serial.c +++ b/drivers/serial/serial_bfin.c @@ -43,13 +43,12 @@ #include <serial.h> #include <linux/compiler.h> #include <asm/blackfin.h> +#include <asm/serial.h> DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_UART_CONSOLE -#include "serial.h" - #ifdef CONFIG_DEBUG_SERIAL static uart_lsr_t cached_lsr[256]; static uart_lsr_t cached_rbr[256]; @@ -195,7 +194,18 @@ static void uart_loop(uint32_t uart_base, int state) #endif -#ifdef CONFIG_SYS_BFIN_UART +static inline void __serial_set_baud(uint32_t uart_base, uint32_t baud) +{ +#ifdef CONFIG_DEBUG_EARLY_SERIAL + serial_early_set_baud(uart_base, baud); +#else + uint16_t divisor = (get_uart_clk() + (baud * 8)) / (baud * 16) + - ANOMALY_05000230; + + /* Program the divisor to get the baud rate we want */ + serial_set_divisor(uart_base, divisor); +#endif +} static void uart_puts(uint32_t uart_base, const char *s) { @@ -209,7 +219,7 @@ 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); \ + __serial_set_baud(MMR_UART(n), gd->baudrate); \ uart_lsr_clear(MMR_UART(n)); \ return 0; \ } \ @@ -221,7 +231,7 @@ static int uart##n##_uninit(void) \ \ static void uart##n##_setbrg(void) \ { \ - serial_early_set_baud(MMR_UART(n), gd->baudrate); \ + __serial_set_baud(MMR_UART(n), gd->baudrate); \ } \ \ static int uart##n##_getc(void) \ @@ -305,65 +315,97 @@ void bfin_serial_initialize(void) #endif } -#else +#ifdef CONFIG_DEBUG_EARLY_SERIAL +inline void uart_early_putc(uint32_t uart_base, const char c) +{ + /* send a \r for compatibility */ + if (c == '\n') + uart_early_putc(uart_base, '\r'); -/* Symbol for our assembly to call. */ -void serial_set_baud(uint32_t baud) + /* wait for the hardware fifo to clear up */ + while (!(_lsr_read(pUART) & THRE)) + continue; + + /* queue the character for transmission */ + bfin_write(&pUART->thr, c); + SSYNC(); +} + +void uart_early_puts(const char *s) { - serial_early_set_baud(UART_BASE, baud); + while (*s) + uart_early_putc(UART_BASE, *s++); } -/* Symbol for common u-boot code to call. - * Setup the baudrate (brg: baudrate generator). - */ -void serial_setbrg(void) +/* Symbol for our assembly to call. */ +void _serial_early_set_baud(uint32_t baud) { - serial_set_baud(gd->baudrate); + serial_early_set_baud(UART_BASE, baud); } /* Symbol for our assembly to call. */ -void serial_initialize(void) +void _serial_early_init(void) { serial_early_init(UART_BASE); } +#endif -/* Symbol for common u-boot code to call. */ -int serial_init(void) +#elif defined(CONFIG_UART_MEM) + +char serial_logbuf[CONFIG_UART_MEM]; +char *serial_logbuf_head = serial_logbuf; + +int serial_mem_init(void) { - serial_initialize(); - serial_setbrg(); - uart_lsr_clear(UART_BASE); + serial_logbuf_head = serial_logbuf; return 0; } -int serial_tstc(void) +void serial_mem_setbrg(void) { - return uart_tstc(UART_BASE); } -int serial_getc(void) +int serial_mem_tstc(void) { - return uart_getc(UART_BASE); + return 0; } -void serial_putc(const char c) +int serial_mem_getc(void) { - uart_putc(UART_BASE, c); + return 0; } -void serial_puts(const char *s) +void serial_mem_putc(const char c) +{ + *serial_logbuf_head = c; + if (++serial_logbuf_head == serial_logbuf + CONFIG_UART_MEM) + serial_logbuf_head = serial_logbuf; +} + +void serial_mem_puts(const char *s) { while (*s) serial_putc(*s++); } -LOOP( -void serial_loop(int state) +struct serial_device bfin_serial_mem_device = { + .name = "bfin_uart_mem", + .start = serial_mem_init, + .setbrg = serial_mem_setbrg, + .getc = serial_mem_getc, + .tstc = serial_mem_tstc, + .putc = serial_mem_putc, + .puts = serial_mem_puts, +}; + + +__weak struct serial_device *default_serial_console(void) { - uart_loop(UART_BASE, state); + return &bfin_serial_mem_device; } -) -#endif - -#endif +void bfin_serial_initialize(void) +{ + serial_register(&bfin_serial_mem_device); +} +#endif /* CONFIG_UART_MEM */ diff --git a/drivers/spi/bfin_spi.c b/drivers/spi/bfin_spi.c index ab2e8b998b..a9a4d92c3e 100644 --- a/drivers/spi/bfin_spi.c +++ b/drivers/spi/bfin_spi.c @@ -13,7 +13,6 @@ #include <spi.h> #include <asm/blackfin.h> -#include <asm/dma.h> #include <asm/gpio.h> #include <asm/portmux.h> #include <asm/mach-common/bits/spi.h> @@ -242,109 +241,15 @@ void spi_release_bus(struct spi_slave *slave) SSYNC(); } -#ifdef __ADSPBF54x__ -# define SPI_DMA_BASE DMA4_NEXT_DESC_PTR -#elif defined(__ADSPBF533__) || defined(__ADSPBF532__) || defined(__ADSPBF531__) || \ - defined(__ADSPBF538__) || defined(__ADSPBF539__) -# define SPI_DMA_BASE DMA5_NEXT_DESC_PTR -#elif defined(__ADSPBF561__) -# define SPI_DMA_BASE DMA2_4_NEXT_DESC_PTR -#elif defined(__ADSPBF537__) || defined(__ADSPBF536__) || defined(__ADSPBF534__) || \ - defined(__ADSPBF52x__) || defined(__ADSPBF51x__) -# define SPI_DMA_BASE DMA7_NEXT_DESC_PTR -# elif defined(__ADSPBF50x__) -# define SPI_DMA_BASE DMA6_NEXT_DESC_PTR -#else -# error "Please provide SPI DMA channel defines" -#endif -static volatile struct dma_register *dma = (void *)SPI_DMA_BASE; - #ifndef CONFIG_BFIN_SPI_IDLE_VAL # define CONFIG_BFIN_SPI_IDLE_VAL 0xff #endif -#ifdef CONFIG_BFIN_SPI_NO_DMA -# define SPI_DMA 0 -#else -# define SPI_DMA 1 -#endif - -static int spi_dma_xfer(struct bfin_spi_slave *bss, const u8 *tx, u8 *rx, - uint bytes) -{ - int ret = -1; - u16 ndsize, spi_config, dma_config; - struct dmasg dmasg[2]; - const u8 *buf; - - if (tx) { - debug("%s: doing half duplex TX\n", __func__); - buf = tx; - spi_config = TDBR_DMA; - dma_config = 0; - } else { - debug("%s: doing half duplex RX\n", __func__); - buf = rx; - spi_config = RDBR_DMA; - dma_config = WNR; - } - - dmasg[0].start_addr = (unsigned long)buf; - dmasg[0].x_modify = 1; - dma_config |= WDSIZE_8 | DMAEN; - if (bytes <= 65536) { - blackfin_dcache_flush_invalidate_range(buf, buf + bytes); - ndsize = NDSIZE_5; - dmasg[0].cfg = NDSIZE_0 | dma_config | FLOW_STOP | DI_EN; - dmasg[0].x_count = bytes; - } else { - blackfin_dcache_flush_invalidate_range(buf, buf + 65536 - 1); - ndsize = NDSIZE_7; - dmasg[0].cfg = NDSIZE_5 | dma_config | FLOW_ARRAY | DMA2D; - dmasg[0].x_count = 0; /* 2^16 */ - dmasg[0].y_count = bytes >> 16; /* count / 2^16 */ - dmasg[0].y_modify = 1; - dmasg[1].start_addr = (unsigned long)(buf + (bytes & ~0xFFFF)); - dmasg[1].cfg = NDSIZE_0 | dma_config | FLOW_STOP | DI_EN; - dmasg[1].x_count = bytes & 0xFFFF; /* count % 2^16 */ - dmasg[1].x_modify = 1; - } - - dma->cfg = 0; - dma->irq_status = DMA_DONE | DMA_ERR; - dma->curr_desc_ptr = dmasg; - write_SPI_CTL(bss, (bss->ctl & ~TDBR_CORE)); - write_SPI_STAT(bss, -1); - SSYNC(); - - write_SPI_TDBR(bss, CONFIG_BFIN_SPI_IDLE_VAL); - dma->cfg = ndsize | FLOW_ARRAY | DMAEN; - write_SPI_CTL(bss, (bss->ctl & ~TDBR_CORE) | spi_config); - SSYNC(); - - /* - * We already invalidated the first 64k, - * now while we just wait invalidate the remaining part. - * Its not likely that the DMA is going to overtake - */ - if (bytes > 65536) - blackfin_dcache_flush_invalidate_range(buf + 65536, buf + bytes); - - while (!(dma->irq_status & DMA_DONE)) - if (ctrlc()) - goto done; - - dma->cfg = 0; - - ret = 0; - done: - write_SPI_CTL(bss, bss->ctl); - return ret; -} - static int spi_pio_xfer(struct bfin_spi_slave *bss, const u8 *tx, u8 *rx, uint bytes) { + /* discard invalid data and clear RXS */ + read_SPI_RDBR(bss); /* todo: take advantage of hardware fifos */ while (bytes--) { u8 value = (tx ? *tx++ : CONFIG_BFIN_SPI_IDLE_VAL); @@ -393,11 +298,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, if (flags & SPI_XFER_BEGIN) spi_cs_activate(slave); - /* TX DMA doesn't work quite right */ - if (SPI_DMA && bytes > 6 && (!tx /*|| !rx*/)) - ret = spi_dma_xfer(bss, tx, rx, bytes); - else - ret = spi_pio_xfer(bss, tx, rx, bytes); + ret = spi_pio_xfer(bss, tx, rx, bytes); done: if (flags & SPI_XFER_END) diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 13e7c37686..d57578df6c 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -33,6 +33,7 @@ endif COBJS-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o COBJS-$(CONFIG_S5P) += s5p_wdt.o COBJS-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o +COBJS-$(CONFIG_BFIN_WATCHDOG) += bfin_wdt.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/arch/blackfin/cpu/watchdog.c b/drivers/watchdog/bfin_wdt.c index 1886bda0ae..7a6756b2e5 100644 --- a/arch/blackfin/cpu/watchdog.c +++ b/drivers/watchdog/bfin_wdt.c @@ -9,6 +9,7 @@ #include <common.h> #include <watchdog.h> #include <asm/blackfin.h> +#include <asm/mach-common/bits/watchdog.h> void hw_watchdog_reset(void) { @@ -17,7 +18,9 @@ void hw_watchdog_reset(void) void hw_watchdog_init(void) { - bfin_write_WDOG_CNT(5 * get_sclk()); /* 5 second timeout */ + bfin_write_WDOG_CTL(WDDIS); + SSYNC(); + bfin_write_WDOG_CNT(CONFIG_WATCHDOG_TIMEOUT_MSECS / 1000 * get_sclk()); hw_watchdog_reset(); - bfin_write_WDOG_CTL(0x0); + bfin_write_WDOG_CTL(WDEN); } diff --git a/include/configs/bf527-ezkit.h b/include/configs/bf527-ezkit.h index 7b51b53dc5..db1b6136f3 100644 --- a/include/configs/bf527-ezkit.h +++ b/include/configs/bf527-ezkit.h @@ -149,10 +149,15 @@ #define CONFIG_MUSB_TIMEOUT 100000 #endif +/* Don't waste time transferring a logo over the UART */ +#if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_UART) +/*# define CONFIG_VIDEO*/ +#endif /* * Video Settings */ +#ifdef CONFIG_VIDEO #ifdef CONFIG_BF527_EZKIT_REV_2_1 # define CONFIG_LQ035Q1_SPI_BUS 0 # define CONFIG_LQ035Q1_SPI_CS 7 @@ -166,7 +171,7 @@ #else # define EASYLOGO_HEADER <asm/bfin_logo_230x230_lzma.h> #endif - +#endif /* CONFIG_VIDEO */ /* * Misc Settings @@ -175,11 +180,6 @@ #define CONFIG_RTC_BFIN #define CONFIG_UART_CONSOLE 1 -/* Don't waste time transferring a logo over the UART */ -#if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_UART) -# define CONFIG_VIDEO -#endif - /* * Pull in common ADI header for remaining command/environment setup diff --git a/include/configs/bf537-stamp.h b/include/configs/bf537-stamp.h index 05029d497b..25cebf880f 100644 --- a/include/configs/bf537-stamp.h +++ b/include/configs/bf537-stamp.h @@ -52,7 +52,7 @@ #define CONFIG_EBIU_AMBCTL0_VAL 0x7BB07BB0 #define CONFIG_EBIU_AMBCTL1_VAL 0xFFC27BB0 -#define CONFIG_SYS_MONITOR_LEN (512 * 1024) +#define CONFIG_SYS_MONITOR_LEN (768 * 1024) #define CONFIG_SYS_MALLOC_LEN (384 * 1024) @@ -135,15 +135,17 @@ /* * SPI_MMC Settings */ +#define CONFIG_MMC_SPI +#ifdef CONFIG_MMC_SPI #define CONFIG_MMC #define CONFIG_GENERIC_MMC -#define CONFIG_MMC_SPI - +#endif /* * NAND Settings */ /* #define CONFIG_NAND_PLAT */ +#ifdef CONFIG_NAND_PLAT #define CONFIG_SYS_NAND_BASE 0x20212000 #define CONFIG_SYS_MAX_NAND_DEVICE 1 @@ -158,7 +160,7 @@ #define NAND_PLAT_WRITE_CMD(chip, cmd) BFIN_NAND_WRITE(BFIN_NAND_CLE(chip), cmd) #define NAND_PLAT_WRITE_ADR(chip, cmd) BFIN_NAND_WRITE(BFIN_NAND_ALE(chip), cmd) #define NAND_PLAT_GPIO_DEV_READY GPIO_PF3 - +#endif /* CONFIG_NAND_PLAT */ /* * CF-CARD IDE-HDD Support diff --git a/include/configs/bf548-ezkit.h b/include/configs/bf548-ezkit.h index e6b05db09d..da5f029435 100644 --- a/include/configs/bf548-ezkit.h +++ b/include/configs/bf548-ezkit.h @@ -120,18 +120,16 @@ #define CONFIG_ENV_SECT_SIZE 0x8000 #endif - /* * NAND Settings */ -#define CONFIG_BFIN_NFC_CTL_VAL 0x0033 #if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_NAND) -# define CONFIG_BFIN_NFC_BOOTROM_ECC -#endif +#define CONFIG_BFIN_NFC_CTL_VAL 0x0033 +#define CONFIG_BFIN_NFC_BOOTROM_ECC #define CONFIG_DRIVER_NAND_BFIN -#define CONFIG_SYS_NAND_BASE 0 /* not actually used */ -#define CONFIG_SYS_MAX_NAND_DEVICE 1 - +#define CONFIG_SYS_NAND_BASE 0 /* not actually used */ +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#endif /* * I2C Settings @@ -184,13 +182,12 @@ #define CONFIG_UART_CONSOLE 1 #define CONFIG_BFIN_SPI_IMG_SIZE 0x50000 -#ifndef __ADSPBF542__ -/* Don't waste time transferring a logo over the UART */ -# if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_UART) -# define CONFIG_VIDEO -# define EASYLOGO_HEADER <asm/bfin_logo_230x230_gzip.h> -# endif -# define CONFIG_DEB_DMA_URGENT +#define CONFIG_ADI_GPIO2 + +#undef CONFIG_VIDEO +#ifdef CONFIG_VIDEO +#define EASYLOGO_HEADER < asm/bfin_logo_230x230_gzip.h > +#define CONFIG_DEB_DMA_URGENT #endif /* Define if want to do post memory test */ diff --git a/include/configs/bf561-ezkit.h b/include/configs/bf561-ezkit.h index 1a9d27ea2a..6ee1e4c869 100644 --- a/include/configs/bf561-ezkit.h +++ b/include/configs/bf561-ezkit.h @@ -98,6 +98,11 @@ */ #define CONFIG_UART_CONSOLE 0 +/* + * Run core 1 from L1 SRAM start address when init uboot on core 0 + */ +/* #define CONFIG_CORE1_RUN 1 */ + /* * Pull in common ADI header for remaining command/environment setup diff --git a/include/configs/bf609-ezkit.h b/include/configs/bf609-ezkit.h index 02149fa94d..1a43e1b433 100644 --- a/include/configs/bf609-ezkit.h +++ b/include/configs/bf609-ezkit.h @@ -144,10 +144,13 @@ #define CONFIG_UART_CONSOLE 0 #define CONFIG_CMD_MEMORY +#define CONFIG_CMD_SOFTSWITCH #define CONFIG_SYS_MEMTEST_END (CONFIG_STACKBASE - 20*1024*1024 + 4) #define CONFIG_BFIN_SOFT_SWITCH +#define CONFIG_ADI_GPIO2 + #if 0 #define CONFIG_UART_MEM 1024 #undef CONFIG_UART_CONSOLE @@ -155,6 +158,13 @@ #undef CONFIG_UART_CONSOLE_IS_JTAG #endif +#define CONFIG_BOARD_SIZE_LIMIT $$((512 * 1024)) + +/* + * Run core 1 from L1 SRAM start address when init uboot on core 0 + */ +/* #define CONFIG_CORE1_RUN 1 */ + /* * Pull in common ADI header for remaining command/environment setup */ diff --git a/include/configs/bfin_adi_common.h b/include/configs/bfin_adi_common.h index d3ae3a71cd..e1a6fe3056 100644 --- a/include/configs/bfin_adi_common.h +++ b/include/configs/bfin_adi_common.h @@ -111,8 +111,8 @@ #ifndef CONFIG_BAUDRATE # define CONFIG_BAUDRATE 57600 #endif -#ifndef CONFIG_DEBUG_EARLY_SERIAL -# define CONFIG_SYS_BFIN_UART +#ifdef CONFIG_UART_CONSOLE +# define CONFIG_BFIN_SERIAL #endif /* @@ -317,5 +317,13 @@ #define CONFIG_BFIN_SPI_GPIO_CS /* Only matters if BFIN_SPI is enabled */ #define CONFIG_LZMA #define CONFIG_MONITOR_IS_IN_RAM - +#ifdef CONFIG_HW_WATCHDOG +# define CONFIG_BFIN_WATCHDOG +# ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS +# define CONFIG_WATCHDOG_TIMEOUT_MSECS 5000 +# endif +#endif +#ifndef CONFIG_ADI_GPIO2 +# define CONFIG_ADI_GPIO1 +#endif #endif diff --git a/include/watchdog.h b/include/watchdog.h index 97ec186be3..d95e4b164d 100644 --- a/include/watchdog.h +++ b/include/watchdog.h @@ -108,8 +108,7 @@ int init_func_watchdog_reset(void); void reset_4xx_watchdog(void); #endif -/* Freescale i.MX */ -#if defined(CONFIG_IMX_WATCHDOG) && !defined(__ASSEMBLY__) +#if defined(CONFIG_HW_WATCHDOG) && !defined(__ASSEMBLY__) void hw_watchdog_init(void); #endif #endif /* _WATCHDOG_H_ */ |