24a07a1241
The ADSP-BF54x was specifically designed to meet the needs of convergent multimedia applications where system performance and cost are essential ingredients. The integration of multimedia, human interface, and connectivity peripherals combined with increased system bandwidth and on-chip memory provides customers a platform to design the most demanding applications. Since now, ADSP-BF54x will be supported in the Linux kernel and bunch of related drivers such as USB OTG, ATAPI, NAND flash controller, LCD framebuffer, sound, touch screen will be submitted later. Please enjoy the show. Signed-off-by: Roy Huang <roy.huang@analog.com> Signed-off-by: Bryan Wu <bryan.wu@analog.com>
194 lines
5.8 KiB
C
194 lines
5.8 KiB
C
#include <linux/serial.h>
|
|
#include <asm/dma.h>
|
|
|
|
#define NR_PORTS 4
|
|
|
|
#define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */
|
|
#define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */
|
|
#define OFFSET_GCTL 0x08 /* Global Control Register */
|
|
#define OFFSET_LCR 0x0C /* Line Control Register */
|
|
#define OFFSET_MCR 0x10 /* Modem Control Register */
|
|
#define OFFSET_LSR 0x14 /* Line Status Register */
|
|
#define OFFSET_MSR 0x18 /* Modem Status Register */
|
|
#define OFFSET_SCR 0x1C /* SCR Scratch Register */
|
|
#define OFFSET_IER_SET 0x20 /* Set Interrupt Enable Register */
|
|
#define OFFSET_IER_CLEAR 0x24 /* Clear Interrupt Enable Register */
|
|
#define OFFSET_THR 0x28 /* Transmit Holding register */
|
|
#define OFFSET_RBR 0x2C /* Receive Buffer register */
|
|
|
|
#define UART_GET_CHAR(uart) bfin_read16(((uart)->port.membase + OFFSET_RBR))
|
|
#define UART_GET_DLL(uart) bfin_read16(((uart)->port.membase + OFFSET_DLL))
|
|
#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH))
|
|
#define UART_GET_IER(uart) bfin_read16(((uart)->port.membase + OFFSET_IER_SET))
|
|
#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
|
|
#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR))
|
|
#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
|
|
|
|
#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v)
|
|
#define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
|
|
#define UART_SET_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER_SET),v)
|
|
#define UART_CLEAR_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER_CLEAR),v)
|
|
#define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
|
|
#define UART_PUT_LSR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LSR),v)
|
|
#define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
|
|
#define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
|
|
|
|
#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
|
|
# define CONFIG_SERIAL_BFIN_CTSRTS
|
|
|
|
# ifndef CONFIG_UART0_CTS_PIN
|
|
# define CONFIG_UART0_CTS_PIN -1
|
|
# endif
|
|
|
|
# ifndef CONFIG_UART0_RTS_PIN
|
|
# define CONFIG_UART0_RTS_PIN -1
|
|
# endif
|
|
|
|
# ifndef CONFIG_UART1_CTS_PIN
|
|
# define CONFIG_UART1_CTS_PIN -1
|
|
# endif
|
|
|
|
# ifndef CONFIG_UART1_RTS_PIN
|
|
# define CONFIG_UART1_RTS_PIN -1
|
|
# endif
|
|
#endif
|
|
/*
|
|
* The pin configuration is different from schematic
|
|
*/
|
|
struct bfin_serial_port {
|
|
struct uart_port port;
|
|
unsigned int old_status;
|
|
#ifdef CONFIG_SERIAL_BFIN_DMA
|
|
int tx_done;
|
|
int tx_count;
|
|
struct circ_buf rx_dma_buf;
|
|
struct timer_list rx_dma_timer;
|
|
int rx_dma_nrows;
|
|
unsigned int tx_dma_channel;
|
|
unsigned int rx_dma_channel;
|
|
struct work_struct tx_dma_workqueue;
|
|
#else
|
|
struct work_struct cts_workqueue;
|
|
#endif
|
|
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
|
|
int cts_pin;
|
|
int rts_pin;
|
|
#endif
|
|
};
|
|
|
|
struct bfin_serial_port bfin_serial_ports[NR_PORTS];
|
|
struct bfin_serial_res {
|
|
unsigned long uart_base_addr;
|
|
int uart_irq;
|
|
#ifdef CONFIG_SERIAL_BFIN_DMA
|
|
unsigned int uart_tx_dma_channel;
|
|
unsigned int uart_rx_dma_channel;
|
|
#endif
|
|
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
|
|
int uart_cts_pin;
|
|
int uart_rts_pin;
|
|
#endif
|
|
};
|
|
|
|
struct bfin_serial_res bfin_serial_resource[] = {
|
|
#ifdef CONFIG_SERIAL_BFIN_UART0
|
|
{
|
|
0xFFC00400,
|
|
IRQ_UART0_RX,
|
|
#ifdef CONFIG_SERIAL_BFIN_DMA
|
|
CH_UART0_TX,
|
|
CH_UART0_RX,
|
|
#endif
|
|
#ifdef CONFIG_BFIN_UART0_CTSRTS
|
|
CONFIG_UART0_CTS_PIN,
|
|
CONFIG_UART0_RTS_PIN,
|
|
#endif
|
|
},
|
|
#endif
|
|
#ifdef CONFIG_SERIAL_BFIN_UART1
|
|
{
|
|
0xFFC02000,
|
|
IRQ_UART1_RX,
|
|
#ifdef CONFIG_SERIAL_BFIN_DMA
|
|
CH_UART1_TX,
|
|
CH_UART1_RX,
|
|
#endif
|
|
},
|
|
#endif
|
|
#ifdef CONFIG_SERIAL_BFIN_UART2
|
|
{
|
|
0xFFC02100,
|
|
IRQ_UART2_RX,
|
|
#ifdef CONFIG_SERIAL_BFIN_DMA
|
|
CH_UART2_TX,
|
|
CH_UART2_RX,
|
|
#endif
|
|
#ifdef CONFIG_BFIN_UART2_CTSRTS
|
|
CONFIG_UART2_CTS_PIN,
|
|
CONFIG_UART2_RTS_PIN,
|
|
#endif
|
|
},
|
|
#endif
|
|
#ifdef CONFIG_SERIAL_BFIN_UART3
|
|
{
|
|
0xFFC03100,
|
|
IRQ_UART3_RX,
|
|
#ifdef CONFIG_SERIAL_BFIN_DMA
|
|
CH_UART3_TX,
|
|
CH_UART3_RX,
|
|
#endif
|
|
},
|
|
#endif
|
|
};
|
|
|
|
int nr_ports = ARRAY_SIZE(bfin_serial_resource);
|
|
|
|
static void bfin_serial_hw_init(struct bfin_serial_port *uart)
|
|
{
|
|
#ifdef CONFIG_SERIAL_BFIN_UART0
|
|
/* Enable UART0 RX and TX on pin 7 & 8 of PORT E */
|
|
bfin_write_PORTE_FER(0x180 | bfin_read_PORTE_FER());
|
|
bfin_write_PORTE_MUX(0x3C000 | bfin_read_PORTE_MUX());
|
|
#endif
|
|
|
|
#ifdef CONFIG_SERIAL_BFIN_UART1
|
|
/* Enable UART1 RX and TX on pin 0 & 1 of PORT H */
|
|
bfin_write_PORTH_FER(0x3 | bfin_read_PORTH_FER());
|
|
bfin_write_PORTH_MUX(~0xF & bfin_read_PORTH_MUX());
|
|
#ifdef CONFIG_BFIN_UART1_CTSRTS
|
|
/* Enable UART1 RTS and CTS on pin 9 & 10 of PORT E */
|
|
bfin_write_PORTE_FER(0x600 | bfin_read_PORTE_FER());
|
|
bfin_write_PORTE_MUX(~0x3C0000 & bfin_read_PORTE_MUX());
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef CONFIG_SERIAL_BFIN_UART2
|
|
/* Enable UART2 RX and TX on pin 4 & 5 of PORT B */
|
|
bfin_write_PORTB_FER(0x30 | bfin_read_PORTB_FER());
|
|
bfin_write_PORTB_MUX(~0xF00 & bfin_read_PORTB_MUX());
|
|
#endif
|
|
|
|
#ifdef CONFIG_SERIAL_BFIN_UART3
|
|
/* Enable UART3 RX and TX on pin 6 & 7 of PORT B */
|
|
bfin_write_PORTB_FER(0xC0 | bfin_read_PORTB_FER());
|
|
bfin_write_PORTB_MUX(~0xF000 | bfin_read_PORTB_MUX());
|
|
#ifdef CONFIG_BFIN_UART3_CTSRTS
|
|
/* Enable UART3 RTS and CTS on pin 2 & 3 of PORT B */
|
|
bfin_write_PORTB_FER(0xC | bfin_read_PORTB_FER());
|
|
bfin_write_PORTB_MUX(~0xF0 | bfin_read_PORTB_MUX());
|
|
#endif
|
|
#endif
|
|
SSYNC();
|
|
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
|
|
if (uart->cts_pin >= 0) {
|
|
gpio_request(uart->cts_pin, NULL);
|
|
gpio_direction_input(uart->cts_pin);
|
|
}
|
|
|
|
if (uart->rts_pin >= 0) {
|
|
gpio_request(uart->rts_pin, NULL);
|
|
gpio_direction_output(uart->rts_pin);
|
|
}
|
|
#endif
|
|
}
|