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 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 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 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 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 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