1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2015, Linaro Limited 4 * All rights reserved. 5 */ 6 7 #include <compiler.h> 8 #include <console.h> 9 #include <drivers/serial8250_uart.h> 10 #include <io.h> 11 #include <keep.h> 12 #include <util.h> 13 14 /* uart register defines */ 15 #define UART_RHR 0x0 16 #define UART_THR 0x0 17 #define UART_IER 0x4 18 #define UART_ISR 0x8 19 #define UART_FCR 0x8 20 #define UART_LCR 0xc 21 #define UART_MCR 0x10 22 #define UART_LSR 0x14 23 #define UART_MSR 0x18 24 #define UART_SPR 0x1c 25 26 /* uart status register bits */ 27 #define LSR_TEMT 0x40 /* Transmitter empty */ 28 #define LSR_THRE 0x20 /* Transmit-hold-register empty */ 29 #define LSR_EMPTY (LSR_TEMT | LSR_THRE) 30 #define LSR_DR 0x01 /* DATA Ready */ 31 32 static vaddr_t chip_to_base(struct serial_chip *chip) 33 { 34 struct serial8250_uart_data *pd = 35 container_of(chip, struct serial8250_uart_data, chip); 36 37 return io_pa_or_va(&pd->base); 38 } 39 40 static void serial8250_uart_flush(struct serial_chip *chip) 41 { 42 vaddr_t base = chip_to_base(chip); 43 44 while (1) { 45 uint32_t state = read32(base + UART_LSR); 46 47 /* Wait until transmit FIFO is empty */ 48 if ((state & LSR_EMPTY) == LSR_EMPTY) 49 break; 50 } 51 } 52 53 static bool serial8250_uart_have_rx_data(struct serial_chip *chip) 54 { 55 vaddr_t base = chip_to_base(chip); 56 57 return (read32(base + UART_LSR) & LSR_DR); 58 } 59 60 static int serial8250_uart_getchar(struct serial_chip *chip) 61 { 62 vaddr_t base = chip_to_base(chip); 63 64 while (!serial8250_uart_have_rx_data(chip)) { 65 /* Transmit FIFO is empty, waiting again */ 66 ; 67 } 68 return read32(base + UART_RHR) & 0xff; 69 } 70 71 static void serial8250_uart_putc(struct serial_chip *chip, int ch) 72 { 73 vaddr_t base = chip_to_base(chip); 74 75 serial8250_uart_flush(chip); 76 77 /* Write out character to transmit FIFO */ 78 write32(ch, base + UART_THR); 79 } 80 81 static const struct serial_ops serial8250_uart_ops = { 82 .flush = serial8250_uart_flush, 83 .getchar = serial8250_uart_getchar, 84 .have_rx_data = serial8250_uart_have_rx_data, 85 .putc = serial8250_uart_putc, 86 }; 87 KEEP_PAGER(serial8250_uart_ops); 88 89 void serial8250_uart_init(struct serial8250_uart_data *pd, paddr_t base, 90 uint32_t __unused uart_clk, 91 uint32_t __unused baud_rate) 92 93 { 94 pd->base.pa = base; 95 pd->chip.ops = &serial8250_uart_ops; 96 97 /* 98 * do nothing, debug uart(uart0) share with normal world, 99 * everything for uart0 is ready now. 100 */ 101 } 102