1*601976a5SPeng Fan // SPDX-License-Identifier: BSD-2-Clause 2*601976a5SPeng Fan /* 3*601976a5SPeng Fan * Copyright 2017-2019 NXP 4*601976a5SPeng Fan */ 5*601976a5SPeng Fan 6*601976a5SPeng Fan #include <assert.h> 7*601976a5SPeng Fan #include <drivers/imx_uart.h> 8*601976a5SPeng Fan #include <io.h> 9*601976a5SPeng Fan #include <keep.h> 10*601976a5SPeng Fan #include <util.h> 11*601976a5SPeng Fan 12*601976a5SPeng Fan #define STAT 0x14 13*601976a5SPeng Fan #define DATA 0x1C 14*601976a5SPeng Fan #define STAT_TDRE BIT(23) 15*601976a5SPeng Fan #define STAT_RDRF BIT(21) 16*601976a5SPeng Fan #define STAT_OR BIT(19) 17*601976a5SPeng Fan 18*601976a5SPeng Fan static vaddr_t chip_to_base(struct serial_chip *chip) 19*601976a5SPeng Fan { 20*601976a5SPeng Fan struct imx_uart_data *pd = 21*601976a5SPeng Fan container_of(chip, struct imx_uart_data, chip); 22*601976a5SPeng Fan 23*601976a5SPeng Fan return io_pa_or_va(&pd->base); 24*601976a5SPeng Fan } 25*601976a5SPeng Fan 26*601976a5SPeng Fan static void imx_lpuart_flush(struct serial_chip *chip __unused) 27*601976a5SPeng Fan { 28*601976a5SPeng Fan } 29*601976a5SPeng Fan 30*601976a5SPeng Fan static int imx_lpuart_getchar(struct serial_chip *chip) 31*601976a5SPeng Fan { 32*601976a5SPeng Fan int ch = 0; 33*601976a5SPeng Fan vaddr_t base = chip_to_base(chip); 34*601976a5SPeng Fan 35*601976a5SPeng Fan while (io_read32(base + STAT) & STAT_RDRF) 36*601976a5SPeng Fan ; 37*601976a5SPeng Fan 38*601976a5SPeng Fan ch = io_read32(base + DATA) & 0x3ff; 39*601976a5SPeng Fan 40*601976a5SPeng Fan if (io_read32(base + STAT) & STAT_OR) 41*601976a5SPeng Fan io_write32(base + STAT, STAT_OR); 42*601976a5SPeng Fan 43*601976a5SPeng Fan return ch; 44*601976a5SPeng Fan } 45*601976a5SPeng Fan 46*601976a5SPeng Fan static void imx_lpuart_putc(struct serial_chip *chip, int ch) 47*601976a5SPeng Fan { 48*601976a5SPeng Fan vaddr_t base = chip_to_base(chip); 49*601976a5SPeng Fan 50*601976a5SPeng Fan while (!(io_read32(base + STAT) & STAT_TDRE)) 51*601976a5SPeng Fan ; 52*601976a5SPeng Fan 53*601976a5SPeng Fan io_write32(base + DATA, ch); 54*601976a5SPeng Fan } 55*601976a5SPeng Fan 56*601976a5SPeng Fan static const struct serial_ops imx_lpuart_ops = { 57*601976a5SPeng Fan .flush = imx_lpuart_flush, 58*601976a5SPeng Fan .getchar = imx_lpuart_getchar, 59*601976a5SPeng Fan .putc = imx_lpuart_putc, 60*601976a5SPeng Fan }; 61*601976a5SPeng Fan KEEP_PAGER(imx_lpuart_ops); 62*601976a5SPeng Fan 63*601976a5SPeng Fan void imx_uart_init(struct imx_uart_data *pd, paddr_t base) 64*601976a5SPeng Fan { 65*601976a5SPeng Fan pd->base.pa = base; 66*601976a5SPeng Fan pd->chip.ops = &imx_lpuart_ops; 67*601976a5SPeng Fan 68*601976a5SPeng Fan /* 69*601976a5SPeng Fan * Do nothing, debug uart(sc lpuart) shared with normal world, 70*601976a5SPeng Fan * everything for uart initialization is done in bootloader. 71*601976a5SPeng Fan */ 72*601976a5SPeng Fan } 73