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 #define AML_UART_SIZE		0x0014
19 
20 /* AML_UART_STATUS bits */
21 #define AML_UART_RX_EMPTY	BIT(20)
22 #define AML_UART_TX_FULL	BIT(21)
23 #define AML_UART_TX_EMPTY	BIT(22)
24 
chip_to_base(struct serial_chip * chip)25 static vaddr_t chip_to_base(struct serial_chip *chip)
26 {
27 	struct amlogic_uart_data *pd =
28 		container_of(chip, struct amlogic_uart_data, chip);
29 
30 	return io_pa_or_va(&pd->base, AML_UART_SIZE);
31 }
32 
amlogic_uart_flush(struct serial_chip * chip)33 static void amlogic_uart_flush(struct serial_chip *chip)
34 {
35 	vaddr_t base = chip_to_base(chip);
36 
37 	while (!(io_read32(base + AML_UART_STATUS) & AML_UART_TX_EMPTY))
38 		;
39 }
40 
amlogic_uart_getchar(struct serial_chip * chip)41 static int amlogic_uart_getchar(struct serial_chip *chip)
42 {
43 	vaddr_t base = chip_to_base(chip);
44 
45 	if (io_read32(base + AML_UART_STATUS) & AML_UART_RX_EMPTY)
46 		return -1;
47 
48 	return io_read32(base + AML_UART_RFIFO) & 0xff;
49 }
50 
amlogic_uart_putc(struct serial_chip * chip,int ch)51 static void amlogic_uart_putc(struct serial_chip *chip, int ch)
52 {
53 	vaddr_t base = chip_to_base(chip);
54 
55 	while (io_read32(base + AML_UART_STATUS) & AML_UART_TX_FULL)
56 		;
57 
58 	io_write32(base + AML_UART_WFIFO, ch);
59 }
60 
61 static const struct serial_ops amlogic_uart_ops = {
62 	.flush = amlogic_uart_flush,
63 	.getchar = amlogic_uart_getchar,
64 	.putc = amlogic_uart_putc,
65 };
66 
amlogic_uart_init(struct amlogic_uart_data * pd,paddr_t base)67 void amlogic_uart_init(struct amlogic_uart_data *pd, paddr_t base)
68 {
69 	pd->base.pa = base;
70 	pd->chip.ops = &amlogic_uart_ops;
71 
72 	/*
73 	 * Do nothing, debug uart (AO) shared with normal world, everything for
74 	 * uart initialization is done in bootloader.
75 	 */
76 }
77