2 * uart-8250.c -- polling driver for 32-bit 8250 UART.
3 * Provides _uart_8250_setup(), _read() and _write(). Please note that
4 * _read() and _write() from this file can only be used for console access.
6 * Copyright (c) 2024 Synopsys Inc.
8 * The authors hereby grant permission to use, copy, modify, distribute,
9 * and license this software and its documentation for any purpose, provided
10 * that existing copyright notices are retained in all copies and that this
11 * notice is included verbatim in any distributions. No written agreement,
12 * license, or royalty fee is required for any of the authorized uses.
13 * Modifications to this software may be copyrighted by their authors
14 * and need not follow the licensing terms described here, provided that
15 * the new terms are clearly indicated on the first page of each file where
23 #include "arc-specific.h"
26 * List of UART 8250 registers with offsets:
28 * 0x00 - Transmit Holding Register, WO, LCR_DLAB == 0
29 * 0x00 - Receive Buffer Register, RO, LCR_DLAB == 0
30 * 0x00 - Divisor Latch Low, RW, LCR_DLAB == 1
31 * 0x04 - Divisor Latch High, RW, LCR_DLAB == 1
32 * 0x04 - Interrupt Enable Register, RW, LCR_DLAB == 0
33 * 0x08 - FIFO Control Register, WO
34 * 0x08 - Interrupt Identification Register, RO
35 * 0x0C - Line Control Register, RW
36 * 0x10 - Modem Control Register, RW
37 * 0x14 - Line Status Register, RO
38 * 0x18 - Modem Status Register, RO
41 #define THR_OFFSET 0x00
42 #define RBR_OFFSET 0x00
43 #define DLL_OFFSET 0x00
44 #define DLH_OFFSET 0x04
45 #define IER_OFFSET 0x04
46 #define FCR_OFFSET 0x08
47 #define IIR_OFFSET 0x08
48 #define LCR_OFFSET 0x0C
49 #define MCR_OFFSET 0x10
50 #define LSR_OFFSET 0x14
51 #define MSR_OFFSET 0x18
54 * LCR (Line Control Register) fields:
56 * [7] - Divisor Latch Access Bit
59 * [4] - Even Parity Select
61 * [2] - Number of Stop Bits
62 * [1:0] - Data Length Select. Values:
63 * 0b11 - 8 data bits per character (default)
64 * 0b10 - 7 data bits per character
65 * 0b01 - 6 data bits per character
66 * 0b00 - 5 data bits per character
69 #define LCR_DLAB_SHIFT 7
70 #define LCR_SB_SHIFT 6
71 #define LCR_SP_SHIFT 5
72 #define LCR_EPS_SHIFT 4
73 #define LCR_PEN_SHIFT 3
74 #define LCR_STB_SHIFT 2
75 #define LCR_DLS_SHIFT 0
77 * MCR (Modem Control Register) fields:
80 * [3] - Auxiliary Output 2
81 * [2] - Auxiliary Output 1
82 * [1] - Request To Send (ON by default)
83 * [0] - Data Terminal Ready (ON by default)
86 #define MCR_LB_SHIFT 4
87 #define MCR_OUT2_SHIFT 3
88 #define MCR_OUT1_SHIFT 2
89 #define MCR_RTS_SHIFT 1
90 #define MCR_DTR_SHIFT 0
93 * LSR (Line Status Register) fields:
95 * [7] - Receiver FIFO Error
96 * [6] - Transmitter Empty
97 * [5] - Transmit Holding Register Empty
98 * [4] - Break Interrupt
101 * [1] - Overrun Error
105 #define LSR_RFE_SHIFT 7
106 #define LSR_TEMT_SHIFT 6
107 #define LSR_THRE_SHIFT 5
108 #define LSR_BI_SHIFT 4
109 #define LSR_FE_SHIFT 3
110 #define LSR_PE_SHIFT 2
111 #define LSR_OE_SHIFT 1
112 #define LSR_DR_SHIFT 0
115 * Default initial values for configuration registers.
118 #define FCR_DEFAULT 0x0
119 #define IER_DEFAULT 0x0
120 #define LCR_DLS_DEFAULT 0x3
121 #define LCR_DEFAULT (LCR_DLS_DEFAULT << LCR_DLS_SHIFT)
122 #define MCR_RTS_DEFAULT 0x1
123 #define MCR_DTR_DEFAULT 0x1
124 #define MCR_DEFAULT ((MCR_RTS_DEFAULT << MCR_RTS_SHIFT) | \
125 (MCR_DTR_DEFAULT << MCR_DTR_SHIFT))
127 #define LCR_MODE_SETUP (0x1 << LCR_DLAB_SHIFT)
128 #define LSR_MODE_GETC (0x1 << LSR_DR_SHIFT)
129 #define LSR_MODE_PUTC ((0x1 << LSR_TEMT_SHIFT) | (0x1 << LSR_THRE_SHIFT))
131 /* Main UART control structure. */
133 volatile char *base
; /* Start of UART registers. */
134 uint32_t clk
; /* UART clock. */
135 uint32_t baud
; /* Baud rate. */
136 int aux_mapped
; /* If UART registers are mapped to AUX or memory. */
137 int ready
; /* If UART is ready to use or not. */
140 static struct _uart_8250 _uart_8250
;
142 /* Write 32-bit value to the UART register. */
144 _uart_8250_write_reg (const struct _uart_8250
*uart
, uint32_t reg
,
147 if (uart
->aux_mapped
)
148 write_aux_reg (value
, (uint32_t) uart
->base
+ reg
);
150 *(volatile uint32_t *)(uart
->base
+ reg
) = value
;
153 /* Read 32-bit value from the UART register. */
154 static inline uint32_t
155 _uart_8250_read_reg (const struct _uart_8250
*uart
, uint32_t reg
)
157 if (uart
->aux_mapped
)
158 return read_aux_reg ((uint32_t) uart
->base
+ reg
);
160 return *(volatile uint32_t *)(uart
->base
+ reg
);
163 /* Wait until all flags are set. */
165 _uart_8250_wait (const struct _uart_8250
*uart
, uint32_t reg
, uint32_t flags
)
169 if ((_uart_8250_read_reg (uart
, reg
) & flags
) == flags
)
174 /* Get one character from UART. CR is converted to NL. */
176 _uart_8250_getc (const struct _uart_8250
*uart
)
180 _uart_8250_wait (uart
, LSR_OFFSET
, LSR_MODE_GETC
);
182 c
= _uart_8250_read_reg (uart
, RBR_OFFSET
);
190 /* Put one character to UART. CR is placed before NL. */
192 _uart_8250_putc (const struct _uart_8250
*uart
, char c
)
195 _uart_8250_putc (uart
, '\r');
197 _uart_8250_wait (uart
, LSR_OFFSET
, LSR_MODE_PUTC
);
199 _uart_8250_write_reg (uart
, THR_OFFSET
, c
);
203 * Setup UART control structure and following parameters:
205 * - baudrate if clock and baudrate are passed to function
206 * - 8n1 (8 data bits, no parity bit, one stop bit)
207 * - disable interrupts
209 * - set Request To Send and Data Terminal Ready
213 * - base - start address of UART registers
214 * - aux_mapped - set if UART registers are mapped to ARC AUX
215 * - clk - UART clock frequency
216 * - baud - UART baudrate to setup
218 * The function returns 0 on success.
221 _uart_8250_setup (void *base
, int aux_mapped
, uint32_t clk
, uint32_t baud
)
223 struct _uart_8250
*uart
= &_uart_8250
;
226 uart
->aux_mapped
= aux_mapped
;
234 div
= ((clk
+ 8 * baud
) / baud
) / 16;
235 _uart_8250_write_reg (uart
, LCR_OFFSET
, LCR_MODE_SETUP
);
236 _uart_8250_write_reg (uart
, DLL_OFFSET
, div
& 0xFF);
237 _uart_8250_write_reg (uart
, DLH_OFFSET
, div
>> 8);
240 _uart_8250_write_reg (uart
, FCR_OFFSET
, FCR_DEFAULT
);
241 _uart_8250_write_reg (uart
, IER_OFFSET
, IER_DEFAULT
);
242 _uart_8250_write_reg (uart
, LCR_OFFSET
, LCR_DEFAULT
);
243 _uart_8250_write_reg (uart
, MCR_OFFSET
, MCR_DEFAULT
);
250 /* _read() is implemented only for stdin. Each read character is echoed. */
252 _read (int fd
, void *buf
, size_t count
)
254 struct _uart_8250
*uart
= &_uart_8250
;
256 char *buf_char
= buf
;
259 if (fd
!= STDIN_FILENO
)
273 /* Break on '\n' to simulate readline behavior. */
274 while (bytes_read
!= count
&& c
!= '\n')
276 c
= _uart_8250_getc (uart
);
280 /* Echo character to the console. */
281 _uart_8250_putc (uart
, c
);
283 buf_char
[bytes_read
] = c
;
290 /* _write() is implemented only for stdout and stderr. */
292 _write (int fd
, const char *buf
, size_t nbyte
)
294 struct _uart_8250
*uart
= &_uart_8250
;
295 uint32_t bytes_written
;
297 if (fd
!= STDOUT_FILENO
&& fd
!= STDERR_FILENO
)
310 while (bytes_written
!= nbyte
)
312 _uart_8250_putc (uart
, buf
[bytes_written
]);
316 return bytes_written
;