1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014, Linaro Limited 4 */ 5 #include <assert.h> 6 #include <drivers/pl011.h> 7 #include <io.h> 8 #include <util.h> 9 #include <keep.h> 10 #include <kernel/dt.h> 11 #include <kernel/dt_driver.h> 12 #include <kernel/spinlock.h> 13 #include <stdlib.h> 14 #include <trace.h> 15 #include <types_ext.h> 16 #include <util.h> 17 18 #define UART_DR 0x00 /* data register */ 19 #define UART_RSR_ECR 0x04 /* receive status or error clear */ 20 #define UART_DMAWM 0x08 /* DMA watermark configure */ 21 #define UART_TIMEOUT 0x0C /* Timeout period */ 22 /* reserved space */ 23 #define UART_FR 0x18 /* flag register */ 24 #define UART_ILPR 0x20 /* IrDA low-poer */ 25 #define UART_IBRD 0x24 /* integer baud register */ 26 #define UART_FBRD 0x28 /* fractional baud register */ 27 #define UART_LCR_H 0x2C /* line control register */ 28 #define UART_CR 0x30 /* control register */ 29 #define UART_IFLS 0x34 /* interrupt FIFO level select */ 30 #define UART_IMSC 0x38 /* interrupt mask set/clear */ 31 #define UART_RIS 0x3C /* raw interrupt register */ 32 #define UART_MIS 0x40 /* masked interrupt register */ 33 #define UART_ICR 0x44 /* interrupt clear register */ 34 #define UART_DMACR 0x48 /* DMA control register */ 35 36 /* flag register bits */ 37 #define UART_FR_RTXDIS (1 << 13) 38 #define UART_FR_TERI (1 << 12) 39 #define UART_FR_DDCD (1 << 11) 40 #define UART_FR_DDSR (1 << 10) 41 #define UART_FR_DCTS (1 << 9) 42 #define UART_FR_RI (1 << 8) 43 #define UART_FR_TXFE (1 << 7) 44 #define UART_FR_RXFF (1 << 6) 45 #define UART_FR_TXFF (1 << 5) 46 #define UART_FR_RXFE (1 << 4) 47 #define UART_FR_BUSY (1 << 3) 48 #define UART_FR_DCD (1 << 2) 49 #define UART_FR_DSR (1 << 1) 50 #define UART_FR_CTS (1 << 0) 51 52 /* transmit/receive line register bits */ 53 #define UART_LCRH_SPS (1 << 7) 54 #define UART_LCRH_WLEN_8 (3 << 5) 55 #define UART_LCRH_WLEN_7 (2 << 5) 56 #define UART_LCRH_WLEN_6 (1 << 5) 57 #define UART_LCRH_WLEN_5 (0 << 5) 58 #define UART_LCRH_FEN (1 << 4) 59 #define UART_LCRH_STP2 (1 << 3) 60 #define UART_LCRH_EPS (1 << 2) 61 #define UART_LCRH_PEN (1 << 1) 62 #define UART_LCRH_BRK (1 << 0) 63 64 /* control register bits */ 65 #define UART_CR_CTSEN (1 << 15) 66 #define UART_CR_RTSEN (1 << 14) 67 #define UART_CR_OUT2 (1 << 13) 68 #define UART_CR_OUT1 (1 << 12) 69 #define UART_CR_RTS (1 << 11) 70 #define UART_CR_DTR (1 << 10) 71 #define UART_CR_RXE (1 << 9) 72 #define UART_CR_TXE (1 << 8) 73 #define UART_CR_LPE (1 << 7) 74 #define UART_CR_OVSFACT (1 << 3) 75 #define UART_CR_UARTEN (1 << 0) 76 77 #define UART_IMSC_RTIM (1 << 6) 78 #define UART_IMSC_RXIM (1 << 4) 79 80 static vaddr_t chip_to_base(struct serial_chip *chip) 81 { 82 struct pl011_data *pd = 83 container_of(chip, struct pl011_data, chip); 84 85 return io_pa_or_va(&pd->base, PL011_REG_SIZE); 86 } 87 88 static void pl011_flush(struct serial_chip *chip) 89 { 90 vaddr_t base = chip_to_base(chip); 91 92 /* 93 * Wait for the transmit FIFO to be empty. 94 * It can happen that Linux initializes the OP-TEE driver with the 95 * console UART disabled; avoid an infinite loop by checking the UART 96 * enabled flag. Checking it in the loop makes the code safe against 97 * asynchronous disable. 98 */ 99 while ((io_read32(base + UART_CR) & UART_CR_UARTEN) && 100 !(io_read32(base + UART_FR) & UART_FR_TXFE)) 101 ; 102 } 103 104 static bool pl011_have_rx_data(struct serial_chip *chip) 105 { 106 vaddr_t base = chip_to_base(chip); 107 108 return !(io_read32(base + UART_FR) & UART_FR_RXFE); 109 } 110 111 static int pl011_getchar(struct serial_chip *chip) 112 { 113 vaddr_t base = chip_to_base(chip); 114 115 while (!pl011_have_rx_data(chip)) 116 ; 117 return io_read32(base + UART_DR) & 0xff; 118 } 119 120 static void pl011_putc(struct serial_chip *chip, int ch) 121 { 122 vaddr_t base = chip_to_base(chip); 123 124 /* Wait until there is space in the FIFO or device is disabled */ 125 while (io_read32(base + UART_FR) & UART_FR_TXFF) 126 ; 127 128 /* Send the character */ 129 io_write32(base + UART_DR, ch); 130 } 131 132 static void pl011_rx_intr_enable(struct serial_chip *chip) 133 { 134 vaddr_t base = chip_to_base(chip); 135 136 io_write32(base + UART_IMSC, UART_IMSC_RXIM); 137 } 138 139 static void pl011_rx_intr_disable(struct serial_chip *chip) 140 { 141 vaddr_t base = chip_to_base(chip); 142 143 io_write32(base + UART_IMSC, 0); 144 } 145 146 static const struct serial_ops pl011_ops = { 147 .flush = pl011_flush, 148 .getchar = pl011_getchar, 149 .have_rx_data = pl011_have_rx_data, 150 .putc = pl011_putc, 151 .rx_intr_enable = pl011_rx_intr_enable, 152 .rx_intr_disable = pl011_rx_intr_disable, 153 }; 154 DECLARE_KEEP_PAGER(pl011_ops); 155 156 void pl011_init(struct pl011_data *pd, paddr_t pbase, uint32_t uart_clk, 157 uint32_t baud_rate) 158 { 159 vaddr_t base; 160 161 pd->base.pa = pbase; 162 pd->chip.ops = &pl011_ops; 163 164 base = io_pa_or_va(&pd->base, PL011_REG_SIZE); 165 166 /* Clear all errors */ 167 io_write32(base + UART_RSR_ECR, 0); 168 /* Disable everything */ 169 io_write32(base + UART_CR, 0); 170 171 if (baud_rate) { 172 uint32_t divisor = (uart_clk * 4) / baud_rate; 173 174 io_write32(base + UART_IBRD, divisor >> 6); 175 io_write32(base + UART_FBRD, divisor & 0x3f); 176 } 177 178 /* Configure TX to 8 bits, 1 stop bit, no parity, fifo disabled. */ 179 io_write32(base + UART_LCR_H, UART_LCRH_WLEN_8); 180 181 /* Enable receive interrupt */ 182 io_write32(base + UART_IMSC, UART_IMSC_RXIM); 183 184 /* Enable UART and RX/TX */ 185 io_write32(base + UART_CR, UART_CR_UARTEN | UART_CR_TXE | UART_CR_RXE); 186 187 pl011_flush(&pd->chip); 188 } 189 190 #ifdef CFG_DT 191 192 static struct serial_chip *pl011_dev_alloc(void) 193 { 194 struct pl011_data *pd = nex_calloc(1, sizeof(*pd)); 195 196 if (!pd) 197 return NULL; 198 return &pd->chip; 199 } 200 201 static int pl011_dev_init(struct serial_chip *chip, const void *fdt, int offs, 202 const char *parms) 203 { 204 struct pl011_data *pd = container_of(chip, struct pl011_data, chip); 205 vaddr_t vbase; 206 paddr_t pbase; 207 size_t size; 208 209 if (parms && parms[0]) 210 IMSG("pl011: device parameters ignored (%s)", parms); 211 212 if (dt_map_dev(fdt, offs, &vbase, &size, DT_MAP_AUTO) < 0) 213 return -1; 214 215 if (size != 0x1000) { 216 EMSG("pl011: unexpected register size: %zx", size); 217 return -1; 218 } 219 220 pbase = virt_to_phys((void *)vbase); 221 pl011_init(pd, pbase, 0, 0); 222 223 return 0; 224 } 225 226 static void pl011_dev_free(struct serial_chip *chip) 227 { 228 struct pl011_data *pd = container_of(chip, struct pl011_data, chip); 229 230 nex_free(pd); 231 } 232 233 static const struct serial_driver pl011_driver = { 234 .dev_alloc = pl011_dev_alloc, 235 .dev_init = pl011_dev_init, 236 .dev_free = pl011_dev_free, 237 }; 238 239 static const struct dt_device_match pl011_match_table[] = { 240 { .compatible = "arm,pl011" }, 241 { 0 } 242 }; 243 244 DEFINE_DT_DRIVER(pl011_dt_driver) = { 245 .name = "pl011", 246 .type = DT_DRIVER_UART, 247 .match_table = pl011_match_table, 248 .driver = &pl011_driver, 249 }; 250 251 #endif /* CFG_DT */ 252