1 /*
2 * Copyright (c) 2019-2020
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 */
7
8 #include <rthw.h>
9 #include <rtdevice.h>
10 #include <lwp_user_mm.h>
11 #include <ioremap.h>
12
13 #include "board.h"
14 #include "drv_uart.h"
15 #include "riscv_io.h"
16
17 #define UART_DEFAULT_BAUDRATE 115200
18 #define UART_CLK 50000000
19 #define UART_ADDR UART0_BASE_ADDR
20 #define UART_IRQ K230_IRQ_UART0
21
22
23 #define UART_RBR (0x00) /* receive buffer register */
24 #define UART_THR (0x00) /* transmit holding register */
25 #define UART_DLL (0x00) /* divisor latch low register */
26 #define UART_DLH (0x04) /* diviso latch high register */
27 #define UART_IER (0x04) /* interrupt enable register */
28 #define UART_IIR (0x08) /* interrupt identity register */
29 #define UART_FCR (0x08) /* FIFO control register */
30 #define UART_LCR (0x0c) /* line control register */
31 #define UART_MCR (0x10) /* modem control register */
32 #define UART_LSR (0x14) /* line status register */
33 #define UART_MSR (0x18) /* modem status register */
34 #define UART_SCH (0x1c) /* scratch register */
35 #define UART_USR (0x7c) /* status register */
36 #define UART_TFL (0x80) /* transmit FIFO level */
37 #define UART_RFL (0x84) /* RFL */
38 #define UART_HALT (0xa4) /* halt tx register */
39 #define UART_DLF (0xc0) /* Divisor Latch Fraction Register */
40
41 #define BIT(x) (1 << x)
42
43 /* Line Status Rigster */
44 #define UART_LSR_RXFIFOE (BIT(7))
45 #define UART_LSR_TEMT (BIT(6))
46 #define UART_LSR_THRE (BIT(5))
47 #define UART_LSR_BI (BIT(4))
48 #define UART_LSR_FE (BIT(3))
49 #define UART_LSR_PE (BIT(2))
50 #define UART_LSR_OE (BIT(1))
51 #define UART_LSR_DR (BIT(0))
52 #define UART_LSR_BRK_ERROR_BITS 0x1E /* BI, FE, PE, OE bits */
53
54 /* Line Control Register */
55 #define UART_LCR_DLAB (BIT(7))
56 #define UART_LCR_SBC (BIT(6))
57 #define UART_LCR_PARITY_MASK (BIT(5)|BIT(4))
58 #define UART_LCR_EPAR (1 << 4)
59 #define UART_LCR_OPAR (0 << 4)
60 #define UART_LCR_PARITY (BIT(3))
61 #define UART_LCR_STOP (BIT(2))
62 #define UART_LCR_DLEN_MASK (BIT(1)|BIT(0))
63 #define UART_LCR_WLEN5 (0)
64 #define UART_LCR_WLEN6 (1)
65 #define UART_LCR_WLEN7 (2)
66 #define UART_LCR_WLEN8 (3)
67
68 /* Halt Register */
69 #define UART_HALT_LCRUP (BIT(2))
70 #define UART_HALT_FORCECFG (BIT(1))
71 #define UART_HALT_HTX (BIT(0))
72
73 /* Interrupt Enable Register */
74 #define UART_IER_MASK (0xff)
75 #define UART_IER_PTIME (BIT(7))
76 #define UART_IER_RS485 (BIT(4))
77 #define UART_IER_MSI (BIT(3))
78 #define UART_IER_RLSI (BIT(2))
79 #define UART_IER_THRI (BIT(1))
80 #define UART_IER_RDI (BIT(0))
81
82 /* Interrupt ID Register */
83 #define UART_IIR_FEFLAG_MASK (BIT(6)|BIT(7))
84 #define UART_IIR_IID_MASK (BIT(0)|BIT(1)|BIT(2)|BIT(3))
85 #define UART_IIR_IID_MSTA (0)
86 #define UART_IIR_IID_NOIRQ (1)
87 #define UART_IIR_IID_THREMP (2)
88 #define UART_IIR_IID_RXDVAL (4)
89 #define UART_IIR_IID_LINESTA (6)
90 #define UART_IIR_IID_BUSBSY (7)
91 #define UART_IIR_IID_CHARTO (12)
92
93 struct device_uart
94 {
95 rt_ubase_t hw_base;
96 void* pa_base;
97 rt_uint32_t irqno;
98 };
99
100 static rt_err_t rt_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg);
101 static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg);
102 static int drv_uart_putc(struct rt_serial_device *serial, char c);
103 static int drv_uart_getc(struct rt_serial_device *serial);
104
105 const struct rt_uart_ops _uart_ops =
106 {
107 rt_uart_configure,
108 uart_control,
109 drv_uart_putc,
110 drv_uart_getc,
111 //TODO: add DMA support
112 RT_NULL
113 };
114
115 struct rt_serial_device serial1;
116 struct device_uart uart1;
117
118 #define write32(addr, val) writel(val, (void*)(addr))
119 #define read32(addr) readl((void*)(addr))
120
_uart_init(void * uart_base)121 static void _uart_init(void *uart_base)
122 {
123 uint32_t bdiv;
124 uint32_t dlf;
125 uint32_t dlh;
126 uint32_t dll;
127
128 bdiv = UART_CLK / UART_DEFAULT_BAUDRATE;
129 dlh = bdiv >> 12;
130 dll = (bdiv - (dlh << 12)) / 16;
131 dlf = bdiv - (dlh << 12) - dll * 16;
132 // dlh can be 0 only if bdiv < 4096 (since we're shifting right by 12 bits)
133 // bdiv = UART_CLK / UART_DEFAULT_BAUDRATE
134 // = 50000000 / 115200
135 // = 434.027
136 // so when dlh is 0,
137 // dll = (bdiv - (dlh << 12)) / 16
138 // = (434.027 - 0) / 16
139 // = 27.626
140 // which means dll can not reach 0,
141 // so we use 1 as the minimum value for dll
142 if((dlh == 0) && (dll < 1))
143 {
144 dll = 1;
145 dlf = 0;
146 }
147
148 write32(uart_base + UART_LCR, 0x00);
149 /* Disable all interrupts */
150 write32(uart_base + UART_IER, 0x00);
151 /* Enable DLAB */
152 write32(uart_base + UART_LCR, 0x80);
153 if (bdiv) {
154 /* Set divisor low byte */
155 write32(uart_base + UART_DLL, dll);
156 /* Set divisor high byte */
157 write32(uart_base + UART_DLH, dlh);
158 /* Set divisor fraction byte*/
159 write32(uart_base + UART_DLF, dlf);
160 }
161 /* 8 bits, no parity, one stop bit */
162 write32(uart_base + UART_LCR, 0x03);
163 /* Enable FIFO */
164 write32(uart_base + UART_FCR, 0x01);
165 /* No modem control DTR RTS */
166 write32(uart_base + UART_MCR, 0x00);
167 /* Clear line status */
168 read32(uart_base + UART_LSR);
169 /* Read receive buffer */
170 read32(uart_base + UART_RBR);
171 read32(uart_base + UART_USR);
172 read32(uart_base + UART_FCR);
173 /* Set scratchpad */
174 write32(uart_base + UART_SCH, 0x00);
175 //enable uart rx irq
176 // write32(uart_base + UART_IER, 0x01);
177 }
178
uart_set_isr(void * uart_base,uint8_t enable,uint32_t irq_type)179 static void uart_set_isr(void *uart_base, uint8_t enable, uint32_t irq_type)
180 {
181 uint32_t value;
182
183 value = read32(uart_base + UART_IER);
184
185 if (enable)
186 {
187 value |= irq_type;
188 }
189 else
190 {
191 value &= ~irq_type;
192 }
193 write32(uart_base + UART_IER, value);
194 }
195
196 /*
197 * UART interface
198 */
rt_uart_configure(struct rt_serial_device * serial,struct serial_configure * cfg)199 static rt_err_t rt_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
200 {
201 return (RT_EOK);
202 }
203
uart_control(struct rt_serial_device * serial,int cmd,void * arg)204 static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
205 {
206 struct device_uart *uart = (struct device_uart*)serial->parent.user_data;
207
208 #ifdef RT_USING_SERIAL_V2
209 rt_ubase_t ctrl_flag = 0;
210 rt_ubase_t ctrl_arg;
211 #endif
212
213 #ifdef RT_USING_SERIAL_V2
214 ctrl_arg = (rt_ubase_t)arg;
215
216 if (ctrl_arg & (RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_RX_NON_BLOCKING))
217 {
218 ctrl_flag |= RT_DEVICE_FLAG_INT_RX;
219 }
220 #endif
221
222 switch (cmd)
223 {
224 case RT_DEVICE_CTRL_CLR_INT:
225 #ifdef RT_USING_SERIAL_V2
226 if (ctrl_flag & RT_DEVICE_FLAG_INT_RX)
227 #else
228 if ((size_t)arg == RT_DEVICE_FLAG_INT_RX)
229 #endif
230 {
231 uart_set_isr((void*)(uart->hw_base), 0, UART_IER_RDI);
232 }
233 break;
234
235 case RT_DEVICE_CTRL_SET_INT:
236 #ifdef RT_USING_SERIAL_V2
237 if (ctrl_flag & RT_DEVICE_FLAG_INT_RX)
238 #else
239 if ((size_t)arg == RT_DEVICE_FLAG_INT_RX)
240 #endif
241 {
242 uart_set_isr((void*)(uart->hw_base), 1, UART_IER_RDI);
243 }
244 break;
245 #ifdef RT_USING_SERIAL_V2
246 case RT_DEVICE_CTRL_CONFIG:
247 if (ctrl_flag & RT_DEVICE_FLAG_INT_RX)
248 {
249 uart_set_isr((void*)(uart->hw_base), 1, UART_IER_RDI);
250 }
251 break;
252 #endif
253
254 case RT_FIOMMAP2:
255 {
256 struct dfs_mmap2_args *mmap2 = (struct dfs_mmap2_args *)arg;
257 if (mmap2)
258 {
259 if (mmap2->length > 0x400)
260 {
261 return -RT_ENOMEM;
262 }
263
264 mmap2->ret = lwp_map_user_phy(lwp_self(), RT_NULL, uart->pa_base, mmap2->length, 0);
265 }
266 break;
267 }
268 }
269
270 return (RT_EOK);
271 }
272
drv_uart_putc(struct rt_serial_device * serial,char c)273 static int drv_uart_putc(struct rt_serial_device *serial, char c)
274 {
275 volatile uint32_t *sed_buf;
276 volatile uint32_t *sta;
277 struct device_uart *uart = (struct device_uart*)serial->parent.user_data;
278
279 sed_buf = (uint32_t *)(uart->hw_base + UART_THR);
280 sta = (uint32_t *)(uart->hw_base + UART_USR);
281
282 /* FIFO status, contain valid data */
283 // while (!(*sta & 0x02));
284 while (!(read32(uart->hw_base + UART_LSR) & 0x20));
285
286 *sed_buf = c;
287
288 return (1);
289 }
290
drv_uart_getc(struct rt_serial_device * serial)291 static int drv_uart_getc(struct rt_serial_device *serial)
292 {
293 struct device_uart *uart = (struct device_uart*)serial->parent.user_data;
294 volatile uint32_t *lsr = (uint32_t *)(uart->hw_base + UART_LSR);
295 volatile uint32_t *rbr = (uint32_t *)(uart->hw_base + UART_RBR);
296
297 if (!(*lsr & UART_LSR_DR))
298 {
299 return -1;
300 }
301 return (int)*rbr;
302 }
303
rt_hw_uart_isr(int irq,void * param)304 static void rt_hw_uart_isr(int irq, void *param)
305 {
306 struct rt_serial_device *serial = (struct rt_serial_device*)param;
307 struct device_uart *uart;
308 size_t uart_base;
309 uint32_t iir, lsr;
310
311 uart = (struct device_uart*)serial->parent.user_data;
312 uart_base = uart->hw_base;
313
314 iir = readb((void*)(uart_base + UART_IIR)) & UART_IIR_IID_MASK;
315 lsr = readb((void*)(uart_base + UART_LSR));
316 // rt_kprintf("uart isr iir:%x lsr:%x\r\n", iir, lsr);
317
318 if (iir == UART_IIR_IID_BUSBSY)
319 {
320 (void)readb((void*)(uart_base + UART_USR));
321 }
322 else if (lsr & (UART_LSR_DR | UART_LSR_BI))
323 {
324 struct rt_serial_rx_fifo *rx_fifo;
325 rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
326
327 if (rx_fifo == NULL)
328 {
329 readb((void*)(uart_base + UART_RBR));
330 return;
331 }
332 #ifdef RT_USING_SERIAL_V2
333 uint8_t data;
334
335 do {
336 data = readb((void*)(uart_base + UART_RBR));
337 rt_ringbuffer_putchar(&(rx_fifo->rb), data);
338 lsr = readb((void*)(uart_base + UART_LSR));
339 } while(lsr & UART_LSR_DR);
340
341 #endif
342
343 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
344 }
345 else if (iir & UART_IIR_IID_CHARTO)
346 /* has charto irq but no dr lsr? just read and ignore */
347 {
348 readb((void*)(uart_base + UART_RBR));
349 }
350 }
351
352 /*
353 * UART Initiation
354 */
rt_hw_uart_init(void)355 int rt_hw_uart_init(void)
356 {
357 struct rt_serial_device *serial;
358 struct device_uart *uart;
359 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
360
361 {
362 serial = &serial1;
363 uart = &uart1;
364
365 serial->ops = &_uart_ops;
366 serial->config = config;
367 serial->config.baud_rate = UART_DEFAULT_BAUDRATE;
368
369 uart->pa_base = (void *)UART_ADDR;
370 uart->hw_base = (rt_base_t)rt_ioremap(uart->pa_base, 0x1000);
371 uart->irqno = UART_IRQ;
372
373 _uart_init((void*)(uart->hw_base));
374
375 rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, serial, "uart1");
376 rt_hw_interrupt_umask(uart->irqno);
377
378 rt_hw_serial_register(serial,
379 RT_CONSOLE_DEVICE_NAME,
380 RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
381 uart);
382 }
383
384 return 0;
385 }
386