summaryrefslogtreecommitdiff
path: root/arch/blackfin/cpu/serial.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/cpu/serial.h')
-rw-r--r--arch/blackfin/cpu/serial.h70
1 files changed, 46 insertions, 24 deletions
diff --git a/arch/blackfin/cpu/serial.h b/arch/blackfin/cpu/serial.h
index 7999a19..8a076dd 100644
--- a/arch/blackfin/cpu/serial.h
+++ b/arch/blackfin/cpu/serial.h
@@ -82,26 +82,28 @@ 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()
# 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))
@@ -168,30 +170,47 @@ 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);
+ 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();
+
+ 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_write(&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();
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 */
@@ -202,12 +221,14 @@ 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();
- 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 */
@@ -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
@@ -266,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)