xref: /optee_os/core/drivers/imx_lpuart.c (revision dc57b1101a33ec9bf18ee3d2b88a0d8ff12d2ede)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2017-2019 NXP
4  */
5 
6 #include <assert.h>
7 #include <drivers/imx_uart.h>
8 #include <io.h>
9 #include <keep.h>
10 #include <util.h>
11 
12 #define STAT		0x14
13 #define DATA		0x1C
14 #define STAT_TDRE	BIT(23)
15 #define STAT_RDRF	BIT(21)
16 #define STAT_OR		BIT(19)
17 
18 static vaddr_t chip_to_base(struct serial_chip *chip)
19 {
20 	struct imx_uart_data *pd =
21 		container_of(chip, struct imx_uart_data, chip);
22 
23 	return io_pa_or_va(&pd->base);
24 }
25 
26 static void imx_lpuart_flush(struct serial_chip *chip __unused)
27 {
28 }
29 
30 static int imx_lpuart_getchar(struct serial_chip *chip)
31 {
32 	int ch = 0;
33 	vaddr_t base = chip_to_base(chip);
34 
35 	while (io_read32(base + STAT) & STAT_RDRF)
36 		;
37 
38 	ch = io_read32(base + DATA) & 0x3ff;
39 
40 	if (io_read32(base + STAT) & STAT_OR)
41 		io_write32(base + STAT, STAT_OR);
42 
43 	return ch;
44 }
45 
46 static void imx_lpuart_putc(struct serial_chip *chip, int ch)
47 {
48 	vaddr_t base = chip_to_base(chip);
49 
50 	while (!(io_read32(base + STAT) & STAT_TDRE))
51 		;
52 
53 	io_write32(base + DATA, ch);
54 }
55 
56 static const struct serial_ops imx_lpuart_ops = {
57 	.flush = imx_lpuart_flush,
58 	.getchar = imx_lpuart_getchar,
59 	.putc = imx_lpuart_putc,
60 };
61 KEEP_PAGER(imx_lpuart_ops);
62 
63 void imx_uart_init(struct imx_uart_data *pd, paddr_t base)
64 {
65 	pd->base.pa = base;
66 	pd->chip.ops = &imx_lpuart_ops;
67 
68 	/*
69 	 * Do nothing, debug uart(sc lpuart) shared with normal world,
70 	 * everything for uart initialization is done in bootloader.
71 	 */
72 }
73