From dca067ee938b3f1c1fda30e56095e0dc62a3a723 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 1 Mar 2016 22:19:39 +0000 Subject: sun50i: clean up serial (debug) driver The serial debug driver is hard to read. Also it uses a C struct to describe a fixed hardware device' register layout. Clean up the code to be more readable and switch to the usual (BASE_ADDR + REG_OFFSET) scheme for accessing registers. Signed-off-by: Andre Przywara --- plat/sun50iw1p1/drivers/uart/uart.c | 105 ++++++++++++++++-------------------- plat/sun50iw1p1/include/uart.h | 28 +++++----- 2 files changed, 60 insertions(+), 73 deletions(-) (limited to 'plat') diff --git a/plat/sun50iw1p1/drivers/uart/uart.c b/plat/sun50iw1p1/drivers/uart/uart.c index 710957c..bd1e7ff 100644 --- a/plat/sun50iw1p1/drivers/uart/uart.c +++ b/plat/sun50iw1p1/drivers/uart/uart.c @@ -33,100 +33,90 @@ #include #include #include + #if DEBUG -#define thr rbr -#define dll rbr -#define dlh ier -#define iir fcr - -static serial_hw_t *serial_ctrl_base = NULL; -static uint32_t uart_lock = 1; -#if 0 -normal_gpio_set_t uart_ctrl[2] = -{ - { 2, 8, 4, 1, 1, 0, {0}},//PB8: 4--RX - { 2, 9, 4, 1, 1, 0, {0}},//PB9: 4--TX -}; -#endif -void sunxi_serial_init(int uart_port, void *gpio_cfg, int gpio_max) +uintptr_t serial_ctrl_base; +int uart_locked = 1; + +void sunxi_serial_init(int uart_port) { - uint32_t reg, i; + uint32_t reg; uint32_t uart_clk; - if( (uart_port < 0) ||(uart_port > 0) ) - { - return ; - } - //reset + /* assert the UART port's reset line */ reg = mmio_read_32(CCMU_BUS_SOFT_RST_REG4); - reg &= ~(1<<(CCM_UART_PORT_OFFSET + uart_port)); - mmio_write_32(CCMU_BUS_SOFT_RST_REG4,reg); - for( i = 0; i < 100; i++ ); - reg |= (1<<(CCM_UART_PORT_OFFSET + uart_port)); - mmio_write_32(CCMU_BUS_SOFT_RST_REG4,reg); - //gate + reg &= ~(1 << (CCM_UART_PORT_OFFSET + uart_port)); + mmio_write_32(CCMU_BUS_SOFT_RST_REG4, reg); + + /* release the clock gate */ reg = mmio_read_32(CCMU_BUS_CLK_GATING_REG3); - reg &= ~(1<<(CCM_UART_PORT_OFFSET + uart_port)); - mmio_write_32(CCMU_BUS_CLK_GATING_REG3,reg); - for( i = 0; i < 100; i++ ); - reg |= (1<<(CCM_UART_PORT_OFFSET + uart_port)); - mmio_write_32(CCMU_BUS_CLK_GATING_REG3,reg); - - //gpio - //boot_set_gpio(gpio_cfg, gpio_max, 1); //boot set,so not need to set again - //uart init - serial_ctrl_base = (serial_hw_t *)(SUNXI_UART0_BASE + uart_port * CCM_UART_ADDR_OFFSET); - serial_ctrl_base->mcr = 0x3; - uart_clk = (24000000 + 8 * UART_BAUD)/(16 * UART_BAUD); - serial_ctrl_base->lcr |= 0x80; - serial_ctrl_base->dlh = uart_clk>>8; - serial_ctrl_base->dll = uart_clk&0xff; - serial_ctrl_base->lcr &= ~0x80; - serial_ctrl_base->lcr = ((PARITY&0x03)<<3) | ((STOP&0x01)<<2) | (DLEN&0x03); - serial_ctrl_base->fcr = 0x7; + reg |= (1 << (CCM_UART_PORT_OFFSET + uart_port)); + mmio_write_32(CCMU_BUS_CLK_GATING_REG3, reg); + + /* de-assert the UART port's reset line */ + reg = mmio_read_32(CCMU_BUS_SOFT_RST_REG4); + reg |= (1 << (CCM_UART_PORT_OFFSET + uart_port)); + mmio_write_32(CCMU_BUS_SOFT_RST_REG4, reg); + + + /* The GPIO pins are already configured */ + serial_ctrl_base = SUNXI_UART0_BASE + uart_port * CCM_UART_ADDR_OFFSET; + + mmio_write_32(serial_ctrl_base + DW_UART_MCR, 0x3); + uart_clk = (24000000 + 8 * UART_BAUD) / (16 * UART_BAUD); + mmio_write_32(serial_ctrl_base + DW_UART_LCR, + mmio_read_32(serial_ctrl_base + DW_UART_LCR) | 0x80); + + mmio_write_32(serial_ctrl_base + DW_UART_DLH, uart_clk >> 8); + mmio_write_32(serial_ctrl_base + DW_UART_DLL, uart_clk & 0xff); + mmio_write_32(serial_ctrl_base + DW_UART_LCR, + mmio_read_32(serial_ctrl_base + DW_UART_LCR) & ~0x80); + mmio_write_32(serial_ctrl_base + DW_UART_LCR, + (PARITY << 3) | (STOP << 2) | DLEN); + mmio_write_32(serial_ctrl_base + DW_UART_FCR, 0x7); - uart_lock = 0; + uart_locked = 0; return; } - void sunxi_serial_exit(void) { - uart_lock = 1; + uart_locked = 1; } void sunxi_serial_putc (char c) { - if (uart_lock) + if (uart_locked) return; - while((serial_ctrl_base->lsr & ( 1 << 6 )) == 0); - serial_ctrl_base->thr = c; + while (!(mmio_read_32(serial_ctrl_base + DW_UART_LSR) & 0x40)) + ; + mmio_write_32(serial_ctrl_base + DW_UART_THR, c); } char sunxi_serial_getc (void) { - if (uart_lock) + if (uart_locked) return 0; - while((serial_ctrl_base->lsr & 1) == 0); - return serial_ctrl_base->rbr; - + while (!(mmio_read_32(serial_ctrl_base + DW_UART_LSR) & 0x01)) + ; + return mmio_read_32(serial_ctrl_base + DW_UART_RBR); } int sunxi_serial_tstc (void) { - return serial_ctrl_base->lsr & 1; + return mmio_read_32(serial_ctrl_base + DW_UART_LSR) & 0x01; } #endif /* DEBUG */ int console_init(unsigned long base_addr, unsigned int uart_clk, unsigned int baud_rate) { - sunxi_serial_init(0,NULL,0); + sunxi_serial_init(0); return 0; } @@ -146,4 +136,3 @@ int console_getc(void) { return sunxi_serial_getc(); } - diff --git a/plat/sun50iw1p1/include/uart.h b/plat/sun50iw1p1/include/uart.h index af26c0b..e057bab 100644 --- a/plat/sun50iw1p1/include/uart.h +++ b/plat/sun50iw1p1/include/uart.h @@ -1,22 +1,20 @@ #ifndef _UART_H_ #define _UART_H_ -#define NULL ((void*)0) #define CCM_UART_PORT_OFFSET 16 #define CCM_UART_ADDR_OFFSET 0x400 -typedef struct serial_hw -{ - volatile unsigned int rbr; /* 0 */ - volatile unsigned int ier; /* 1 */ - volatile unsigned int fcr; /* 2 */ - volatile unsigned int lcr; /* 3 */ - volatile unsigned int mcr; /* 4 */ - volatile unsigned int lsr; /* 5 */ - volatile unsigned int msr; /* 6 */ - volatile unsigned int sch; /* 7 */ -}serial_hw_t; - +#define DW_UART_RBR 0x00 +#define DW_UART_THR 0x00 +#define DW_UART_DLL 0x00 +#define DW_UART_IER 0x04 +#define DW_UART_DLH 0x04 +#define DW_UART_FCR 0x08 +#define DW_UART_LCR 0x0c +#define DW_UART_MCR 0x10 +#define DW_UART_LSR 0x14 +#define DW_UART_MSR 0x18 +#define DW_UART_SCH 0x1c #define UART_BAUD 115200 // Baud rate for UART // Compute the divisor factor @@ -26,13 +24,13 @@ typedef struct serial_hw #define DLEN 3 // Data Length: 0 - 5bits; 1 - 6bits; 2 - 7bits; 3 - 8bits #if DEBUG -void sunxi_serial_init(int uart_port, void *gpio_cfg, int gpio_max); +void sunxi_serial_init(int uart_port); void sunxi_serial_exit(void); void sunxi_serial_putc (char c); char sunxi_serial_getc (void); int sunxi_serial_tstc (void); #else -static inline void sunxi_serial_init(int uart_port, void *gpio_cfg, int gpio_max) {} +static inline void sunxi_serial_init(int uart_port) {} static inline void sunxi_serial_exit(void) {} static inline void sunxi_serial_putc(char c) {} static inline char sunxi_serial_getc(void) { return 0;} -- cgit v1.2.3