X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=cpu%2Fblackfin%2Fserial.h;h=6cbc564b532b974ebbf5ecd1a2fb8893545b3959;hb=7527feef06b13e9fd5b6d10a4bfc81b59ee56f27;hp=1f0f4b46c7df1793ff07671f90b0a308e2877d3d;hpb=34e6cb8d1d9dc8194b2d8cad1cc39273ac58f8d8;p=u-boot diff --git a/cpu/blackfin/serial.h b/cpu/blackfin/serial.h index 1f0f4b46c7..6cbc564b53 100644 --- a/cpu/blackfin/serial.h +++ b/cpu/blackfin/serial.h @@ -14,6 +14,10 @@ #include #include +#ifndef CONFIG_UART_CONSOLE +# define CONFIG_UART_CONSOLE 0 +#endif + #ifdef CONFIG_DEBUG_EARLY_SERIAL # define BFIN_DEBUG_EARLY_SERIAL 1 #else @@ -77,11 +81,6 @@ #ifndef __ASSEMBLY__ -/* We cannot use get_sclk() in initcode as it is defined elsewhere. */ -#ifdef BFIN_IN_INITCODE -# define get_sclk() (CONFIG_CLKIN_HZ * CONFIG_VCO_MULT / CONFIG_SCLK_DIV) -#endif - #ifdef __ADSPBF54x__ # define ACCESS_LATCH() # define ACCESS_PORT_IER() @@ -95,7 +94,16 @@ __attribute__((always_inline)) static inline void serial_do_portmux(void) { -#ifdef __ADSPBF52x__ +#if defined(__ADSPBF51x__) +# define DO_MUX(port, mux_tx, mux_rx, tx, rx) \ + bfin_write_PORT##port##_MUX((bfin_read_PORT##port##_MUX() & ~(PORT_x_MUX_##mux_tx##_MASK | PORT_x_MUX_##mux_rx##_MASK)) | PORT_x_MUX_##mux_tx##_FUNC_2 | PORT_x_MUX_##mux_rx##_FUNC_2); \ + bfin_write_PORT##port##_FER(bfin_read_PORT##port##_FER() | P##port##tx | P##port##rx); + switch (CONFIG_UART_CONSOLE) { + case 0: DO_MUX(G, 5, 5, 9, 10); break; /* Port G; mux 5; PG9 and PG10 */ + case 1: DO_MUX(F, 2, 3, 14, 15); break; /* Port H; mux 2/3; PH14 and PH15 */ + } + SSYNC(); +#elif defined(__ADSPBF52x__) # define DO_MUX(port, mux, tx, rx) \ bfin_write_PORT##port##_MUX((bfin_read_PORT##port##_MUX() & ~PORT_x_MUX_##mux##_MASK) | PORT_x_MUX_##mux##_FUNC_3); \ bfin_write_PORT##port##_FER(bfin_read_PORT##port##_FER() | P##port##tx | P##port##rx); @@ -133,7 +141,7 @@ static inline void serial_early_init(void) /* handle portmux crap on different Blackfins */ serial_do_portmux(); - /* Enable UART */ + /* always enable UART -- avoids anomalies 05000309 and 05000350 */ *pUART_GCTL = UCEN; /* Set LCR to Word Lengh 8-bit word select */ @@ -143,56 +151,53 @@ static inline void serial_early_init(void) } __attribute__((always_inline)) -static inline uint32_t serial_early_get_baud(void) +static inline void serial_early_put_div(uint16_t divisor) { - /* If the UART isnt enabled, then we are booting an LDR - * from a non-UART source (so like flash) which means - * the baud rate here is meaningless. - */ - if ((*pUART_GCTL & UCEN) != UCEN) - return 0; - -#if (0) /* See comment for serial_reset_baud() in initcode.c */ /* Set DLAB in LCR to Access DLL and DLH */ ACCESS_LATCH(); SSYNC(); - uint8_t dll = *pUART_DLL; - uint8_t dlh = *pUART_DLH; - uint16_t divisor = (dlh << 8) | dll; - uint32_t baud = get_sclk() / (divisor * 16); + /* Program the divisor to get the baud rate we want */ + *pUART_DLL = LOB(divisor); + *pUART_DLH = HIB(divisor); + SSYNC(); /* Clear DLAB in LCR to Access THR RBR IER */ ACCESS_PORT_IER(); SSYNC(); - - return baud; -#else - return CONFIG_BAUDRATE; -#endif } __attribute__((always_inline)) -static inline void serial_early_set_baud(uint32_t baud) +static inline uint16_t serial_early_get_div(void) { - /* Translate from baud into divisor in terms of SCLK. - * The +1 is to make sure we over sample just a little - * rather than under sample the incoming signals. - */ - uint16_t divisor = (get_sclk() / (baud * 16)) + 1; - /* Set DLAB in LCR to Access DLL and DLH */ ACCESS_LATCH(); SSYNC(); - /* Program the divisor to get the baud rate we want */ - *pUART_DLL = LOB(divisor); - *pUART_DLH = HIB(divisor); - SSYNC(); + uint8_t dll = *pUART_DLL; + uint8_t dlh = *pUART_DLH; + uint16_t divisor = (dlh << 8) | dll; /* Clear DLAB in LCR to Access THR RBR IER */ ACCESS_PORT_IER(); SSYNC(); + + return divisor; +} + +/* We cannot use get_sclk() early on as it uses caches in external memory */ +#if defined(BFIN_IN_INITCODE) || defined(CONFIG_DEBUG_EARLY_SERIAL) +# define get_sclk() (CONFIG_CLKIN_HZ * CONFIG_VCO_MULT / CONFIG_SCLK_DIV) +#endif + +__attribute__((always_inline)) +static inline void serial_early_set_baud(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); } #ifndef BFIN_IN_INITCODE @@ -222,32 +227,6 @@ static inline void serial_early_puts(const char *s) #endif .endm -/* Recursively expand calls to _serial_putc for every byte - * passed to us. Append a newline when we're all done. - */ -.macro _serial_early_putc byte:req morebytes:vararg -#ifdef CONFIG_DEBUG_EARLY_SERIAL - R0 = \byte; - call _serial_putc; -.ifnb \morebytes - _serial_early_putc \morebytes -.else -.if (\byte != '\n') - _serial_early_putc '\n' -.endif -.endif -#endif -.endm - -/* Wrapper around recurisve _serial_early_putc macro which - * simply prepends the string "Early: " - */ -.macro serial_early_putc byte:req morebytes:vararg -#ifdef CONFIG_DEBUG_EARLY_SERIAL - _serial_early_putc 'E', 'a', 'r', 'l', 'y', ':', ' ', \byte, \morebytes -#endif -.endm - /* Since we embed the string right into our .text section, we need * to find its address. We do this by getting our PC and adding 2 * bytes (which is the length of the jump instruction). Then we