Merge tag 'u-boot-imx-20200115' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx
[platform/kernel/u-boot.git] / drivers / serial / serial_lpuart.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2019 NXP
4  * Copyright 2013 Freescale Semiconductor, Inc.
5  */
6
7 #include <common.h>
8 #include <clk.h>
9 #include <dm.h>
10 #include <fsl_lpuart.h>
11 #include <watchdog.h>
12 #include <asm/io.h>
13 #include <serial.h>
14 #include <linux/compiler.h>
15 #include <asm/arch/imx-regs.h>
16 #include <asm/arch/clock.h>
17
18 #define US1_TDRE        (1 << 7)
19 #define US1_RDRF        (1 << 5)
20 #define US1_OR          (1 << 3)
21 #define UC2_TE          (1 << 3)
22 #define UC2_RE          (1 << 2)
23 #define CFIFO_TXFLUSH   (1 << 7)
24 #define CFIFO_RXFLUSH   (1 << 6)
25 #define SFIFO_RXOF      (1 << 2)
26 #define SFIFO_RXUF      (1 << 0)
27
28 #define STAT_LBKDIF     (1 << 31)
29 #define STAT_RXEDGIF    (1 << 30)
30 #define STAT_TDRE       (1 << 23)
31 #define STAT_RDRF       (1 << 21)
32 #define STAT_IDLE       (1 << 20)
33 #define STAT_OR         (1 << 19)
34 #define STAT_NF         (1 << 18)
35 #define STAT_FE         (1 << 17)
36 #define STAT_PF         (1 << 16)
37 #define STAT_MA1F       (1 << 15)
38 #define STAT_MA2F       (1 << 14)
39 #define STAT_FLAGS      (STAT_LBKDIF | STAT_RXEDGIF | STAT_IDLE | STAT_OR | \
40                          STAT_NF | STAT_FE | STAT_PF | STAT_MA1F | STAT_MA2F)
41
42 #define CTRL_TE         (1 << 19)
43 #define CTRL_RE         (1 << 18)
44
45 #define FIFO_RXFLUSH            BIT(14)
46 #define FIFO_TXFLUSH            BIT(15)
47 #define FIFO_TXSIZE_MASK        0x70
48 #define FIFO_TXSIZE_OFF 4
49 #define FIFO_RXSIZE_MASK        0x7
50 #define FIFO_RXSIZE_OFF 0
51 #define FIFO_TXFE               0x80
52 #if defined(CONFIG_ARCH_IMX8) || defined(CONFIG_ARCH_IMXRT)
53 #define FIFO_RXFE               0x08
54 #else
55 #define FIFO_RXFE               0x40
56 #endif
57
58 #define WATER_TXWATER_OFF       0
59 #define WATER_RXWATER_OFF       16
60
61 DECLARE_GLOBAL_DATA_PTR;
62
63 #define LPUART_FLAG_REGMAP_32BIT_REG    BIT(0)
64 #define LPUART_FLAG_REGMAP_ENDIAN_BIG   BIT(1)
65
66 enum lpuart_devtype {
67         DEV_VF610 = 1,
68         DEV_LS1021A,
69         DEV_MX7ULP,
70         DEV_IMX8,
71         DEV_IMXRT,
72 };
73
74 struct lpuart_serial_platdata {
75         void *reg;
76         enum lpuart_devtype devtype;
77         ulong flags;
78 };
79
80 static void lpuart_read32(u32 flags, u32 *addr, u32 *val)
81 {
82         if (flags & LPUART_FLAG_REGMAP_32BIT_REG) {
83                 if (flags & LPUART_FLAG_REGMAP_ENDIAN_BIG)
84                         *(u32 *)val = in_be32(addr);
85                 else
86                         *(u32 *)val = in_le32(addr);
87         }
88 }
89
90 static void lpuart_write32(u32 flags, u32 *addr, u32 val)
91 {
92         if (flags & LPUART_FLAG_REGMAP_32BIT_REG) {
93                 if (flags & LPUART_FLAG_REGMAP_ENDIAN_BIG)
94                         out_be32(addr, val);
95                 else
96                         out_le32(addr, val);
97         }
98 }
99
100
101 #ifndef CONFIG_SYS_CLK_FREQ
102 #define CONFIG_SYS_CLK_FREQ     0
103 #endif
104
105 u32 __weak get_lpuart_clk(void)
106 {
107         return CONFIG_SYS_CLK_FREQ;
108 }
109
110 #if CONFIG_IS_ENABLED(CLK)
111 static int get_lpuart_clk_rate(struct udevice *dev, u32 *clk)
112 {
113         struct clk per_clk;
114         ulong rate;
115         int ret;
116
117         ret = clk_get_by_name(dev, "per", &per_clk);
118         if (ret) {
119                 dev_err(dev, "Failed to get per clk: %d\n", ret);
120                 return ret;
121         }
122
123         rate = clk_get_rate(&per_clk);
124         if ((long)rate <= 0) {
125                 dev_err(dev, "Failed to get per clk rate: %ld\n", (long)rate);
126                 return ret;
127         }
128         *clk = rate;
129         return 0;
130 }
131 #else
132 static inline int get_lpuart_clk_rate(struct udevice *dev, u32 *clk)
133 { return -ENOSYS; }
134 #endif
135
136 static bool is_lpuart32(struct udevice *dev)
137 {
138         struct lpuart_serial_platdata *plat = dev->platdata;
139
140         return plat->flags & LPUART_FLAG_REGMAP_32BIT_REG;
141 }
142
143 static void _lpuart_serial_setbrg(struct udevice *dev,
144                                   int baudrate)
145 {
146         struct lpuart_serial_platdata *plat = dev_get_platdata(dev);
147         struct lpuart_fsl *base = plat->reg;
148         u32 clk;
149         u16 sbr;
150         int ret;
151
152         if (CONFIG_IS_ENABLED(CLK)) {
153                 ret = get_lpuart_clk_rate(dev, &clk);
154                 if (ret)
155                         return;
156         } else {
157                 clk = get_lpuart_clk();
158         }
159
160         sbr = (u16)(clk / (16 * baudrate));
161
162         /* place adjustment later - n/32 BRFA */
163         __raw_writeb(sbr >> 8, &base->ubdh);
164         __raw_writeb(sbr & 0xff, &base->ubdl);
165 }
166
167 static int _lpuart_serial_getc(struct lpuart_serial_platdata *plat)
168 {
169         struct lpuart_fsl *base = plat->reg;
170         while (!(__raw_readb(&base->us1) & (US1_RDRF | US1_OR)))
171                 WATCHDOG_RESET();
172
173         barrier();
174
175         return __raw_readb(&base->ud);
176 }
177
178 static void _lpuart_serial_putc(struct lpuart_serial_platdata *plat,
179                                 const char c)
180 {
181         struct lpuart_fsl *base = plat->reg;
182
183         while (!(__raw_readb(&base->us1) & US1_TDRE))
184                 WATCHDOG_RESET();
185
186         __raw_writeb(c, &base->ud);
187 }
188
189 /* Test whether a character is in the RX buffer */
190 static int _lpuart_serial_tstc(struct lpuart_serial_platdata *plat)
191 {
192         struct lpuart_fsl *base = plat->reg;
193
194         if (__raw_readb(&base->urcfifo) == 0)
195                 return 0;
196
197         return 1;
198 }
199
200 /*
201  * Initialise the serial port with the given baudrate. The settings
202  * are always 8 data bits, no parity, 1 stop bit, no start bits.
203  */
204 static int _lpuart_serial_init(struct udevice *dev)
205 {
206         struct lpuart_serial_platdata *plat = dev_get_platdata(dev);
207         struct lpuart_fsl *base = (struct lpuart_fsl *)plat->reg;
208         u8 ctrl;
209
210         ctrl = __raw_readb(&base->uc2);
211         ctrl &= ~UC2_RE;
212         ctrl &= ~UC2_TE;
213         __raw_writeb(ctrl, &base->uc2);
214
215         __raw_writeb(0, &base->umodem);
216         __raw_writeb(0, &base->uc1);
217
218         /* Disable FIFO and flush buffer */
219         __raw_writeb(0x0, &base->upfifo);
220         __raw_writeb(0x0, &base->utwfifo);
221         __raw_writeb(0x1, &base->urwfifo);
222         __raw_writeb(CFIFO_TXFLUSH | CFIFO_RXFLUSH, &base->ucfifo);
223
224         /* provide data bits, parity, stop bit, etc */
225         _lpuart_serial_setbrg(dev, gd->baudrate);
226
227         __raw_writeb(UC2_RE | UC2_TE, &base->uc2);
228
229         return 0;
230 }
231
232 static void _lpuart32_serial_setbrg_7ulp(struct udevice *dev,
233                                          int baudrate)
234 {
235         struct lpuart_serial_platdata *plat = dev_get_platdata(dev);
236         struct lpuart_fsl_reg32 *base = plat->reg;
237         u32 sbr, osr, baud_diff, tmp_osr, tmp_sbr, tmp_diff, tmp;
238         u32 clk;
239         int ret;
240
241         if (CONFIG_IS_ENABLED(CLK)) {
242                 ret = get_lpuart_clk_rate(dev, &clk);
243                 if (ret)
244                         return;
245         } else {
246                 clk = get_lpuart_clk();
247         }
248
249         baud_diff = baudrate;
250         osr = 0;
251         sbr = 0;
252
253         for (tmp_osr = 4; tmp_osr <= 32; tmp_osr++) {
254                 tmp_sbr = (clk / (baudrate * tmp_osr));
255
256                 if (tmp_sbr == 0)
257                         tmp_sbr = 1;
258
259                 /*calculate difference in actual buad w/ current values */
260                 tmp_diff = (clk / (tmp_osr * tmp_sbr));
261                 tmp_diff = tmp_diff - baudrate;
262
263                 /* select best values between sbr and sbr+1 */
264                 if (tmp_diff > (baudrate - (clk / (tmp_osr * (tmp_sbr + 1))))) {
265                         tmp_diff = baudrate - (clk / (tmp_osr * (tmp_sbr + 1)));
266                         tmp_sbr++;
267                 }
268
269                 if (tmp_diff <= baud_diff) {
270                         baud_diff = tmp_diff;
271                         osr = tmp_osr;
272                         sbr = tmp_sbr;
273                 }
274         }
275
276         /*
277          * TODO: handle buadrate outside acceptable rate
278          * if (baudDiff > ((config->baudRate_Bps / 100) * 3))
279          * {
280          *   Unacceptable baud rate difference of more than 3%
281          *   return kStatus_LPUART_BaudrateNotSupport;
282          * }
283          */
284         tmp = in_le32(&base->baud);
285
286         if ((osr > 3) && (osr < 8))
287                 tmp |= LPUART_BAUD_BOTHEDGE_MASK;
288
289         tmp &= ~LPUART_BAUD_OSR_MASK;
290         tmp |= LPUART_BAUD_OSR(osr-1);
291
292         tmp &= ~LPUART_BAUD_SBR_MASK;
293         tmp |= LPUART_BAUD_SBR(sbr);
294
295         /* explicitly disable 10 bit mode & set 1 stop bit */
296         tmp &= ~(LPUART_BAUD_M10_MASK | LPUART_BAUD_SBNS_MASK);
297
298         out_le32(&base->baud, tmp);
299 }
300
301 static void _lpuart32_serial_setbrg(struct udevice *dev,
302                                     int baudrate)
303 {
304         struct lpuart_serial_platdata *plat = dev_get_platdata(dev);
305         struct lpuart_fsl_reg32 *base = plat->reg;
306         u32 clk;
307         u32 sbr;
308         int ret;
309
310         if (CONFIG_IS_ENABLED(CLK)) {
311                 ret = get_lpuart_clk_rate(dev, &clk);
312                 if (ret)
313                         return;
314         } else {
315                 clk = get_lpuart_clk();
316         }
317
318         sbr = (clk / (16 * baudrate));
319
320         /* place adjustment later - n/32 BRFA */
321         lpuart_write32(plat->flags, &base->baud, sbr);
322 }
323
324 static int _lpuart32_serial_getc(struct lpuart_serial_platdata *plat)
325 {
326         struct lpuart_fsl_reg32 *base = plat->reg;
327         u32 stat, val;
328
329         lpuart_read32(plat->flags, &base->stat, &stat);
330         while ((stat & STAT_RDRF) == 0) {
331                 lpuart_write32(plat->flags, &base->stat, STAT_FLAGS);
332                 WATCHDOG_RESET();
333                 lpuart_read32(plat->flags, &base->stat, &stat);
334         }
335
336         lpuart_read32(plat->flags, &base->data, &val);
337
338         lpuart_read32(plat->flags, &base->stat, &stat);
339         if (stat & STAT_OR)
340                 lpuart_write32(plat->flags, &base->stat, STAT_OR);
341
342         return val & 0x3ff;
343 }
344
345 static void _lpuart32_serial_putc(struct lpuart_serial_platdata *plat,
346                                   const char c)
347 {
348         struct lpuart_fsl_reg32 *base = plat->reg;
349         u32 stat;
350
351         if (c == '\n')
352                 serial_putc('\r');
353
354         while (true) {
355                 lpuart_read32(plat->flags, &base->stat, &stat);
356
357                 if ((stat & STAT_TDRE))
358                         break;
359
360                 WATCHDOG_RESET();
361         }
362
363         lpuart_write32(plat->flags, &base->data, c);
364 }
365
366 /* Test whether a character is in the RX buffer */
367 static int _lpuart32_serial_tstc(struct lpuart_serial_platdata *plat)
368 {
369         struct lpuart_fsl_reg32 *base = plat->reg;
370         u32 water;
371
372         lpuart_read32(plat->flags, &base->water, &water);
373
374         if ((water >> 24) == 0)
375                 return 0;
376
377         return 1;
378 }
379
380 /*
381  * Initialise the serial port with the given baudrate. The settings
382  * are always 8 data bits, no parity, 1 stop bit, no start bits.
383  */
384 static int _lpuart32_serial_init(struct udevice *dev)
385 {
386         struct lpuart_serial_platdata *plat = dev_get_platdata(dev);
387         struct lpuart_fsl_reg32 *base = (struct lpuart_fsl_reg32 *)plat->reg;
388         u32 val, tx_fifo_size;
389
390         lpuart_read32(plat->flags, &base->ctrl, &val);
391         val &= ~CTRL_RE;
392         val &= ~CTRL_TE;
393         lpuart_write32(plat->flags, &base->ctrl, val);
394
395         lpuart_write32(plat->flags, &base->modir, 0);
396
397         lpuart_read32(plat->flags, &base->fifo, &val);
398         tx_fifo_size = (val & FIFO_TXSIZE_MASK) >> FIFO_TXSIZE_OFF;
399         /* Set the TX water to half of FIFO size */
400         if (tx_fifo_size > 1)
401                 tx_fifo_size = tx_fifo_size >> 1;
402
403         /* Set RX water to 0, to be triggered by any receive data */
404         lpuart_write32(plat->flags, &base->water,
405                        (tx_fifo_size << WATER_TXWATER_OFF));
406
407         /* Enable TX and RX FIFO */
408         val |= (FIFO_TXFE | FIFO_RXFE | FIFO_TXFLUSH | FIFO_RXFLUSH);
409         lpuart_write32(plat->flags, &base->fifo, val);
410
411         lpuart_write32(plat->flags, &base->match, 0);
412
413         if (plat->devtype == DEV_MX7ULP || plat->devtype == DEV_IMX8 ||
414             plat->devtype == DEV_IMXRT) {
415                 _lpuart32_serial_setbrg_7ulp(dev, gd->baudrate);
416         } else {
417                 /* provide data bits, parity, stop bit, etc */
418                 _lpuart32_serial_setbrg(dev, gd->baudrate);
419         }
420
421         lpuart_write32(plat->flags, &base->ctrl, CTRL_RE | CTRL_TE);
422
423         return 0;
424 }
425
426 static int lpuart_serial_setbrg(struct udevice *dev, int baudrate)
427 {
428         struct lpuart_serial_platdata *plat = dev_get_platdata(dev);
429
430         if (is_lpuart32(dev)) {
431                 if (plat->devtype == DEV_MX7ULP || plat->devtype == DEV_IMX8 ||
432                     plat->devtype == DEV_IMXRT)
433                         _lpuart32_serial_setbrg_7ulp(dev, baudrate);
434                 else
435                         _lpuart32_serial_setbrg(dev, baudrate);
436         } else {
437                 _lpuart_serial_setbrg(dev, baudrate);
438         }
439
440         return 0;
441 }
442
443 static int lpuart_serial_getc(struct udevice *dev)
444 {
445         struct lpuart_serial_platdata *plat = dev->platdata;
446
447         if (is_lpuart32(dev))
448                 return _lpuart32_serial_getc(plat);
449
450         return _lpuart_serial_getc(plat);
451 }
452
453 static int lpuart_serial_putc(struct udevice *dev, const char c)
454 {
455         struct lpuart_serial_platdata *plat = dev->platdata;
456
457         if (is_lpuart32(dev))
458                 _lpuart32_serial_putc(plat, c);
459         else
460                 _lpuart_serial_putc(plat, c);
461
462         return 0;
463 }
464
465 static int lpuart_serial_pending(struct udevice *dev, bool input)
466 {
467         struct lpuart_serial_platdata *plat = dev->platdata;
468         struct lpuart_fsl *reg = plat->reg;
469         struct lpuart_fsl_reg32 *reg32 = plat->reg;
470         u32 stat;
471
472         if (is_lpuart32(dev)) {
473                 if (input) {
474                         return _lpuart32_serial_tstc(plat);
475                 } else {
476                         lpuart_read32(plat->flags, &reg32->stat, &stat);
477                         return stat & STAT_TDRE ? 0 : 1;
478                 }
479         }
480
481         if (input)
482                 return _lpuart_serial_tstc(plat);
483         else
484                 return __raw_readb(&reg->us1) & US1_TDRE ? 0 : 1;
485 }
486
487 static int lpuart_serial_probe(struct udevice *dev)
488 {
489 #if CONFIG_IS_ENABLED(CLK)
490         struct clk per_clk;
491         int ret;
492
493         ret = clk_get_by_name(dev, "per", &per_clk);
494         if (!ret) {
495                 ret = clk_enable(&per_clk);
496                 if (ret) {
497                         dev_err(dev, "Failed to get per clk: %d\n", ret);
498                         return ret;
499                 }
500         } else {
501                 dev_warn(dev, "Failed to get per clk: %d\n",  ret);
502         }
503 #endif
504
505         if (is_lpuart32(dev))
506                 return _lpuart32_serial_init(dev);
507         else
508                 return _lpuart_serial_init(dev);
509 }
510
511 static int lpuart_serial_ofdata_to_platdata(struct udevice *dev)
512 {
513         struct lpuart_serial_platdata *plat = dev->platdata;
514         const void *blob = gd->fdt_blob;
515         int node = dev_of_offset(dev);
516         fdt_addr_t addr;
517
518         addr = devfdt_get_addr(dev);
519         if (addr == FDT_ADDR_T_NONE)
520                 return -EINVAL;
521
522         plat->reg = (void *)addr;
523         plat->flags = dev_get_driver_data(dev);
524
525         if (fdtdec_get_bool(blob, node, "little-endian"))
526                 plat->flags &= ~LPUART_FLAG_REGMAP_ENDIAN_BIG;
527
528         if (!fdt_node_check_compatible(blob, node, "fsl,ls1021a-lpuart"))
529                 plat->devtype = DEV_LS1021A;
530         else if (!fdt_node_check_compatible(blob, node, "fsl,imx7ulp-lpuart"))
531                 plat->devtype = DEV_MX7ULP;
532         else if (!fdt_node_check_compatible(blob, node, "fsl,vf610-lpuart"))
533                 plat->devtype = DEV_VF610;
534         else if (!fdt_node_check_compatible(blob, node, "fsl,imx8qm-lpuart"))
535                 plat->devtype = DEV_IMX8;
536         else if (!fdt_node_check_compatible(blob, node, "fsl,imxrt-lpuart"))
537                 plat->devtype = DEV_IMXRT;
538
539         return 0;
540 }
541
542 static const struct dm_serial_ops lpuart_serial_ops = {
543         .putc = lpuart_serial_putc,
544         .pending = lpuart_serial_pending,
545         .getc = lpuart_serial_getc,
546         .setbrg = lpuart_serial_setbrg,
547 };
548
549 static const struct udevice_id lpuart_serial_ids[] = {
550         { .compatible = "fsl,ls1021a-lpuart", .data =
551                 LPUART_FLAG_REGMAP_32BIT_REG | LPUART_FLAG_REGMAP_ENDIAN_BIG },
552         { .compatible = "fsl,imx7ulp-lpuart",
553                 .data = LPUART_FLAG_REGMAP_32BIT_REG },
554         { .compatible = "fsl,vf610-lpuart"},
555         { .compatible = "fsl,imx8qm-lpuart",
556                 .data = LPUART_FLAG_REGMAP_32BIT_REG },
557         { .compatible = "fsl,imxrt-lpuart",
558                 .data = LPUART_FLAG_REGMAP_32BIT_REG },
559         { }
560 };
561
562 U_BOOT_DRIVER(serial_lpuart) = {
563         .name   = "serial_lpuart",
564         .id     = UCLASS_SERIAL,
565         .of_match = lpuart_serial_ids,
566         .ofdata_to_platdata = lpuart_serial_ofdata_to_platdata,
567         .platdata_auto_alloc_size = sizeof(struct lpuart_serial_platdata),
568         .probe = lpuart_serial_probe,
569         .ops    = &lpuart_serial_ops,
570 };