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