xref: /optee_os/core/drivers/amlogic_uart.c (revision 5b25c76ac40f830867e3d60800120ffd7874e8dc)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2020 Carlo Caione <ccaione@baylibre.com>
4  */
5 
6 #include <assert.h>
7 #include <drivers/amlogic_uart.h>
8 #include <io.h>
9 #include <keep.h>
10 #include <util.h>
11 
12 /* Registers */
13 #define AML_UART_WFIFO		0x0000
14 #define AML_UART_RFIFO		0x0004
15 #define AML_UART_CONTROL	0x0008
16 #define AML_UART_STATUS		0x000C
17 #define AML_UART_MISC		0x0010
18 
19 /* AML_UART_STATUS bits */
20 #define AML_UART_RX_EMPTY	BIT(20)
21 #define AML_UART_TX_FULL	BIT(21)
22 #define AML_UART_TX_EMPTY	BIT(22)
23 
24 static vaddr_t chip_to_base(struct serial_chip *chip)
25 {
26 	struct amlogic_uart_data *pd =
27 		container_of(chip, struct amlogic_uart_data, chip);
28 
29 	return io_pa_or_va(&pd->base);
30 }
31 
32 static void amlogic_uart_flush(struct serial_chip *chip)
33 {
34 	vaddr_t base = chip_to_base(chip);
35 
36 	while (!(io_read32(base + AML_UART_STATUS) & AML_UART_TX_EMPTY))
37 		;
38 }
39 
40 static int amlogic_uart_getchar(struct serial_chip *chip)
41 {
42 	vaddr_t base = chip_to_base(chip);
43 
44 	if (io_read32(base + AML_UART_STATUS) & AML_UART_RX_EMPTY)
45 		return -1;
46 
47 	return io_read32(base + AML_UART_RFIFO) & 0xff;
48 }
49 
50 static void amlogic_uart_putc(struct serial_chip *chip, int ch)
51 {
52 	vaddr_t base = chip_to_base(chip);
53 
54 	while (io_read32(base + AML_UART_STATUS) & AML_UART_TX_FULL)
55 		;
56 
57 	io_write32(base + AML_UART_WFIFO, ch);
58 }
59 
60 static const struct serial_ops amlogic_uart_ops = {
61 	.flush = amlogic_uart_flush,
62 	.getchar = amlogic_uart_getchar,
63 	.putc = amlogic_uart_putc,
64 };
65 
66 void amlogic_uart_init(struct amlogic_uart_data *pd, paddr_t base)
67 {
68 	pd->base.pa = base;
69 	pd->chip.ops = &amlogic_uart_ops;
70 
71 	/*
72 	 * Do nothing, debug uart (AO) shared with normal world, everything for
73 	 * uart initialization is done in bootloader.
74 	 */
75 }
76