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