1 /**
2   * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
3   *
4   * SPDX-License-Identifier: Apache-2.0
5   ******************************************************************************
6   * @file    drv_uart.c
7   * @author  Huibin Hong
8   * @version V0.5
9   * @date    10-Dec-2018
10   * @brief   serial driver
11   *
12   ******************************************************************************
13   */
14 
15 #include <rthw.h>
16 #include <rtdevice.h>
17 #include <rtthread.h>
18 
19 #ifdef RT_USING_UART
20 
21 #include "hal_base.h"
22 #include "hal_bsp.h"
23 #include "drv_uart.h"
24 #include "drv_clock.h"
25 #ifdef RK_BSP_TEMP
26 #include "drv_pm.h"
27 #endif
28 #include "board.h"
29 
30 /****************************************************************************
31  * Private Types
32  ****************************************************************************/
33 struct rockchip_uart
34 {
35     const struct uart_board *uart_board;
36     /* HAL */
37     const struct HAL_UART_DEV *dev;
38 
39     /* irq handler */
40     rt_isr_handler_t irq_handler;
41 };
42 
43 static int rockchip_uart_irq(rt_serial_t *serial);
44 
45 #define DEFINE_ROCKCHIP_UART(ID)                            \
46 static void rockchip_uart##ID##_irq(int irq, void *param);  \
47 static struct rt_serial_device serial##ID;                  \
48 static struct rockchip_uart rk_uart##ID =                   \
49 {                                                           \
50     .uart_board = &g_uart##ID##_board,                      \
51     .dev = &g_uart##ID##Dev,                               \
52     .irq_handler = rockchip_uart##ID##_irq,                 \
53 };                                                          \
54 static void rockchip_uart##ID##_irq(int irq, void *param)   \
55 {                                                           \
56     rockchip_uart_irq(&serial##ID);                         \
57 }                                                           \
58 
59 #if defined(RT_USING_UART0)
60 DEFINE_ROCKCHIP_UART(0);
61 #endif /* RT_USING_UART0 */
62 
63 #if defined(RT_USING_UART1)
64 DEFINE_ROCKCHIP_UART(1);
65 #endif /* RT_USING_UART1 */
66 
67 #if defined(RT_USING_UART2)
68 DEFINE_ROCKCHIP_UART(2);
69 #endif /* RT_USING_UART2 */
70 
71 #if defined(RT_USING_UART3)
72 DEFINE_ROCKCHIP_UART(3);
73 #endif /* RT_USING_UART3 */
74 
75 #if defined(RT_USING_UART4)
76 DEFINE_ROCKCHIP_UART(4);
77 #endif /* RT_USING_UART4 */
78 
79 #if defined(RT_USING_UART5)
80 DEFINE_ROCKCHIP_UART(5);
81 #endif /* RT_USING_UART5 */
82 
83 #if defined(RT_USING_UART6)
84 DEFINE_ROCKCHIP_UART(6);
85 #endif /* RT_USING_UART6 */
86 
87 #if defined(RT_USING_UART7)
88 DEFINE_ROCKCHIP_UART(7);
89 #endif /* RT_USING_UART7 */
90 
91 #if defined(RT_USING_UART8)
92 DEFINE_ROCKCHIP_UART(8);
93 #endif /* RT_USING_UART8 */
94 
95 #if defined(RT_USING_UART9)
96 DEFINE_ROCKCHIP_UART(9);
97 #endif /* RT_USING_UART9 */
98 
99 static struct rockchip_uart *rk_uart_table[] =
100 {
101 #if defined(RT_USING_UART0)
102     &rk_uart0,
103 #endif
104 #if defined(RT_USING_UART1)
105     &rk_uart1,
106 #endif
107 #if defined(RT_USING_UART2)
108     &rk_uart2,
109 #endif
110 #if defined(RT_USING_UART3)
111     &rk_uart3,
112 #endif
113 #if defined(RT_USING_UART4)
114     &rk_uart4,
115 #endif
116 #if defined(RT_USING_UART5)
117     &rk_uart5,
118 #endif
119 #if defined(RT_USING_UART6)
120     &rk_uart6,
121 #endif
122 #if defined(RT_USING_UART7)
123     &rk_uart7,
124 #endif
125 #if defined(RT_USING_UART8)
126     &rk_uart8,
127 #endif
128 #if defined(RT_USING_UART9)
129     &rk_uart9,
130 #endif
131 };
132 
133 static struct rt_serial_device *rt_serial_table[] =
134 {
135 #if defined(RT_USING_UART0)
136     &serial0,
137 #endif
138 #if defined(RT_USING_UART1)
139     &serial1,
140 #endif
141 #if defined(RT_USING_UART2)
142     &serial2,
143 #endif
144 #if defined(RT_USING_UART3)
145     &serial3,
146 #endif
147 #if defined(RT_USING_UART4)
148     &serial4,
149 #endif
150 #if defined(RT_USING_UART5)
151     &serial5,
152 #endif
153 #if defined(RT_USING_UART6)
154     &serial6,
155 #endif
156 #if defined(RT_USING_UART7)
157     &serial7,
158 #endif
159 #if defined(RT_USING_UART8)
160     &serial8,
161 #endif
162 #if defined(RT_USING_UART9)
163     &serial9,
164 #endif
165 };
166 
rockchip_uart_putc(rt_serial_t * serial,char c)167 static int rockchip_uart_putc(rt_serial_t *serial, char c)
168 {
169     struct rockchip_uart *uart = RT_NULL;
170 
171     RT_ASSERT(serial != RT_NULL);
172     uart = (struct rockchip_uart *)serial->parent.user_data;
173 
174     HAL_UART_SerialOutChar(uart->dev->pReg, c);
175     return 1;
176 }
177 
rockchip_uart_getc(rt_serial_t * serial)178 static int rockchip_uart_getc(rt_serial_t *serial)
179 {
180     rt_uint8_t c = 0;
181     int ret = -1;
182 
183     struct rockchip_uart *uart = RT_NULL;
184 
185     RT_ASSERT(serial != RT_NULL);
186     uart = (struct rockchip_uart *)serial->parent.user_data;
187 
188     ret = HAL_UART_SerialIn(uart->dev->pReg, &c, 1);
189 
190     if (ret <= 0)
191     {
192         return -1;
193     }
194     else
195     {
196         ret = c;
197         return ret;
198     }
199 }
200 
rt_hw_console_channel(void)201 int rt_hw_console_channel(void)
202 {
203 #if defined(RT_CONSOLE_DEVICE_NAME)
204 #if defined(RT_USING_UART0)
205     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart0"))
206         return 0;
207 #endif
208 #if defined(RT_USING_UART1)
209     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart1"))
210         return 1;
211 #endif
212 #if defined(RT_USING_UART2)
213     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart2"))
214         return 2;
215 #endif
216 #if defined(RT_USING_UART3)
217     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart3"))
218         return 3;
219 #endif
220 #if defined(RT_USING_UART4)
221     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart4"))
222         return 4;
223 #endif
224 #if defined(RT_USING_UART5)
225     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart5"))
226         return 5;
227 #endif
228 #if defined(RT_USING_UART6)
229     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart6"))
230         return 6;
231 #endif
232 #if defined(RT_USING_UART7)
233     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart7"))
234         return 7;
235 #endif
236 #if defined(RT_USING_UART8)
237     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart8"))
238         return 8;
239 #endif
240 #if defined(RT_USING_UART9)
241     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart9"))
242         return 9;
243 #endif
244 #endif
245 
246     return -RT_EINVAL;
247 }
248 
rt_hw_console_output(const char * str)249 void rt_hw_console_output(const char *str)
250 {
251     struct rockchip_uart *uart = RT_NULL;
252 
253 #if defined(RT_CONSOLE_DEVICE_NAME)
254 #if defined(RT_USING_UART0)
255     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart0"))
256         uart = &rk_uart0;
257 #endif
258 #if defined(RT_USING_UART1)
259     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart1"))
260         uart = &rk_uart1;
261 #endif
262 #if defined(RT_USING_UART2)
263     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart2"))
264         uart = &rk_uart2;
265 #endif
266 #if defined(RT_USING_UART3)
267     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart3"))
268         uart = &rk_uart3;
269 #endif
270 #if defined(RT_USING_UART4)
271     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart4"))
272         uart = &rk_uart4;
273 #endif
274 #if defined(RT_USING_UART5)
275     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart5"))
276         uart = &rk_uart5;
277 #endif
278 #if defined(RT_USING_UART6)
279     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart6"))
280         uart = &rk_uart6;
281 #endif
282 #if defined(RT_USING_UART7)
283     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart7"))
284         uart = &rk_uart7;
285 #endif
286 #if defined(RT_USING_UART8)
287     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart8"))
288         uart = &rk_uart8;
289 #endif
290 #if defined(RT_USING_UART9)
291     if (!strcmp(RT_CONSOLE_DEVICE_NAME, "uart9"))
292         uart = &rk_uart9;
293 #endif
294 #endif
295 
296     if (!uart)
297         return;
298 
299     while (*str)
300     {
301         if (*str == '\n')
302             HAL_UART_SerialOutChar(uart->dev->pReg, '\r');
303 
304         HAL_UART_SerialOutChar(uart->dev->pReg, *str);
305         str++;
306     }
307 }
308 
rockchip_uart_configure(rt_serial_t * serial,struct serial_configure * cfg)309 static rt_err_t rockchip_uart_configure(rt_serial_t *serial, struct serial_configure *cfg)
310 {
311     struct rockchip_uart *uart = RT_NULL;
312     struct HAL_UART_CONFIG hal_uart_config;
313     const struct HAL_UART_DEV *dev;
314 
315     RT_ASSERT(serial != RT_NULL);
316     uart = (struct rockchip_uart *)serial->parent.user_data;
317     dev = uart->dev;
318 
319     if (cfg->stop_bits == STOP_BITS_1)
320         hal_uart_config.stopBit = UART_ONE_STOPBIT;
321     else if (cfg->stop_bits == STOP_BITS_2)
322         hal_uart_config.stopBit = UART_ONE_AND_HALF_OR_TWO_STOPBIT;
323     else
324         rt_kprintf("STOP_BITS_3 and STOP_BITS_4 are not supported\n");
325 
326     if (cfg->parity == PARITY_ODD)
327         hal_uart_config.parity = UART_ODD_PARITY;
328     else if (cfg->parity == PARITY_EVEN)
329         hal_uart_config.parity = UART_EVEN_PARITY;
330     else
331         hal_uart_config.parity = UART_PARITY_DISABLE;
332 
333     hal_uart_config.baudRate = cfg->baud_rate;
334     hal_uart_config.dataBit = cfg->data_bits;
335 
336     HAL_UART_Init(dev, &hal_uart_config);
337 #ifdef RK_BSP_TEMP
338     if (dev->isAutoFlow && (cfg->flow_ctrl == RT_SERIAL_AUTO_FLOW_ENABLE))
339         HAL_UART_EnableAutoFlowControl(dev->pReg);
340     else
341         HAL_UART_DisableAutoFlowControl(dev->pReg);
342 #endif
343     rt_hw_interrupt_umask(dev->irqNum);
344 
345     return RT_EOK;
346 }
347 
rockchip_uart_control(rt_serial_t * serial,int cmd,void * arg)348 static rt_err_t rockchip_uart_control(rt_serial_t *serial, int cmd, void *arg)
349 {
350     struct rockchip_uart *uart = RT_NULL;
351     struct UART_REG *hw_base = RT_NULL;
352     const struct HAL_UART_DEV *dev;
353     rt_uint32_t flag = (rt_uint32_t)arg;
354 
355     RT_ASSERT(serial != RT_NULL);
356     uart = (struct rockchip_uart *)serial->parent.user_data;
357     hw_base = uart->dev->pReg;
358     dev = uart->dev;
359 
360     switch (cmd)
361     {
362     case RT_DEVICE_CTRL_CLR_INT:
363         if (flag == RT_DEVICE_FLAG_INT_RX)
364             HAL_UART_DisableIrq(hw_base, UART_IER_RDI);
365         else if (flag == RT_DEVICE_FLAG_INT_TX)
366             HAL_UART_DisableIrq(hw_base, UART_IER_THRI);
367         break;
368 
369     case RT_DEVICE_CTRL_SET_INT:
370         if (flag == RT_DEVICE_FLAG_INT_RX)
371             HAL_UART_EnableIrq(hw_base, UART_IER_RDI);
372         else if (flag == RT_DEVICE_FLAG_INT_TX)
373             HAL_UART_EnableIrq(hw_base, UART_IER_THRI);
374         break;
375     case RT_DEVICE_CTRL_CONFIG:
376         if (flag == RT_DEVICE_FLAG_DMA_RX)
377             HAL_UART_EnableIrq(hw_base, UART_IER_RDI);
378         break;
379 #ifdef RK_BSP_TEMP
380     case RT_DEVICE_CTRL_HW_OPEN:
381         clk_enable_by_id(dev->sclkGateID);
382         break;
383     case RT_DEVICE_CTRL_HW_CLOSE:
384         clk_disable_by_id(dev->sclkGateID);
385         break;
386 #endif
387     }
388 
389     return RT_EOK;
390 }
391 
rockchip_uart_irq(rt_serial_t * serial)392 static int rockchip_uart_irq(rt_serial_t *serial)
393 {
394     rt_uint32_t iir = 0;
395     struct rockchip_uart *uart = RT_NULL;
396     struct UART_REG *hw_base = RT_NULL;
397 
398     RT_ASSERT(serial != RT_NULL);
399     uart = (struct rockchip_uart *)serial->parent.user_data;
400     hw_base = uart->dev->pReg;
401 
402     rt_interrupt_enter();
403 
404     iir = HAL_UART_GetIrqID(hw_base);
405 
406     switch (iir)
407     {
408     case UART_IIR_RDI:
409     case UART_IIR_RX_TIMEOUT:
410         rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
411         break;
412 
413     case UART_IIR_THRI:
414         rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE);
415         break;
416 
417     default:
418         HAL_UART_HandleIrq(hw_base);
419         break;
420     }
421 
422     rt_interrupt_leave();
423     return 0;
424 }
425 
426 static const struct rt_uart_ops rockchip_uart_ops =
427 {
428     rockchip_uart_configure,
429     rockchip_uart_control,
430     rockchip_uart_putc,
431     rockchip_uart_getc,
432 };
433 
434 #ifdef RT_USING_PM
435 
436 static struct UART_SAVE_CONFIG pUartSave;
437 
rockchip_uart_suspend(const struct rt_device * device)438 static int rockchip_uart_suspend(const struct rt_device *device)
439 {
440     struct rockchip_uart *uart = RT_NULL;
441     const struct HAL_UART_DEV *dev;
442 
443     RT_ASSERT(device != RT_NULL);
444     uart = (struct rockchip_uart *)device->user_data;
445     dev = uart->dev;
446 
447     rt_hw_interrupt_mask(dev->irqNum);
448     HAL_UART_Suspend(dev->pReg, &pUartSave);
449     clk_disable_by_id(dev->pclkGateID);
450     clk_disable_by_id(dev->sclkGateID);
451     return RT_EOK;
452 }
453 
rockchip_uart_resume(const struct rt_device * device)454 static void rockchip_uart_resume(const struct rt_device *device)
455 {
456     struct rockchip_uart *uart = RT_NULL;
457     const struct HAL_UART_DEV *dev;
458 
459     RT_ASSERT(device != RT_NULL);
460     uart = (struct rockchip_uart *)device->user_data;
461     dev = uart->dev;
462 
463     clk_enable_by_id(dev->pclkGateID);
464     clk_enable_by_id(dev->sclkGateID);
465     HAL_UART_Reset(dev->pReg);
466     HAL_UART_Resume(dev->pReg, &pUartSave);
467     rt_hw_interrupt_umask(dev->irqNum);
468 }
469 
470 static const struct rt_device_pm_ops rockchip_uart_pm_ops =
471 {
472     .suspend = rockchip_uart_suspend,
473     .resume = rockchip_uart_resume,
474 };
475 
rockchip_rt_hw_uart_pm_register(void)476 int rockchip_rt_hw_uart_pm_register(void)
477 {
478     int i = 0;
479     struct rockchip_uart *uart;
480     struct rt_serial_device *serial;
481     const struct uart_board *uart_board;
482 
483     for (i = 0; i < HAL_ARRAY_SIZE(rk_uart_table); i++)
484     {
485         uart = rk_uart_table[i];
486         if (uart)
487         {
488             rt_bool_t is_console;
489             uart_board = uart->uart_board;
490 
491 #ifdef RT_CONSOLE_DEVICE_NAME
492             if (!strcmp(RT_CONSOLE_DEVICE_NAME, uart_board->name))
493                 is_console = true;
494             else
495                 is_console = false;
496 #else
497             is_console = false;
498 #endif
499 
500             serial = rt_serial_table[i];
501             serial->ops = &rockchip_uart_ops;
502 #ifdef RK_BSP_TEMP
503             if (!is_console && !uart_board->en_irq_wake)
504                 rt_pm_register_device(&serial->parent, &rockchip_uart_pm_ops);
505 #endif
506         }
507     }
508 
509     return 0;
510 }
511 INIT_PREV_EXPORT(rockchip_rt_hw_uart_pm_register);
512 
513 #endif
514 
rt_hw_usart_init(void)515 void rt_hw_usart_init(void)
516 {
517     int i = 0;
518     struct rockchip_uart *uart;
519     struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
520     struct rt_serial_device *serial;
521     const struct HAL_UART_DEV *dev;
522     const struct uart_board *uart_board;
523 
524     for (i = 0; i < HAL_ARRAY_SIZE(rk_uart_table); i++)
525     {
526         uart = rk_uart_table[i];
527         if (uart)
528         {
529             rt_bool_t is_console;     /* uart is used for console */
530 
531             dev = uart->dev;
532             uart_board = uart->uart_board;
533 
534             if (uart_board->baud_rate)
535             {
536                 config.baud_rate = uart_board->baud_rate;
537             }
538 
539 #ifdef RT_CONSOLE_DEVICE_NAME
540             if (!strcmp(RT_CONSOLE_DEVICE_NAME, uart_board->name))
541             {
542                 is_console = true;
543             }
544             else
545             {
546                 is_console = false;
547             }
548 #else
549             is_console = false;
550 #endif
551 
552             config.bufsz = uart_board->bufer_size;
553             serial = rt_serial_table[i];
554             serial->ops = &rockchip_uart_ops;
555             serial->config = config;
556 
557             /* enable uart clk here */
558             clk_enable_by_id(dev->pclkGateID);
559             clk_enable_by_id(dev->sclkGateID);
560 
561             if (!is_console)
562                 HAL_UART_Reset(dev->pReg);
563 
564             /* register UARTx device */
565             rt_hw_serial_register(serial, uart_board->name,
566                                   uart_board->dev_flag, (void *)uart);
567 
568             /* enable interrupt */
569             rt_hw_interrupt_install(dev->irqNum, uart->irq_handler,
570                                     RT_NULL, uart_board->name);
571             rt_hw_interrupt_mask(dev->irqNum);
572         }
573     }
574 }
575 #endif
576