1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13/* disabled until someone makes it compile */ 14 15#include <platsupport/clock.h> 16#include <platsupport/serial.h> 17#include <utils/util.h> 18#include <string.h> 19 20#include "serial.h" 21#include "mux.h" 22 23#include "../../common.h" 24 25/* TX FIFO IRQ threshold ratio {0..7}. 26 * The absolute value depends on the FIFO size of the individual UART 27 * A high value avoids underruns, but increases IRQ overhead */ 28#define FIFO_TXLVL_VAL 2 29 30/* RX FIFO IRQ threshold ratio {0..7}. 31 * The absolute value depends on the FIFO size of the individual UART 32 * A low value avoids overruns, but increases IRQ overhead */ 33#define FIFO_RXLVL_VAL 2 34 35/* Timeout on RX {0..15} */ 36#define RX_TIMEOUT_VAL 15 /* 8*(N + 1) frames */ 37 38#define ULCON 0x0000 /* line control */ 39#define UCON 0x0004 /* control */ 40#define UFCON 0x0008 /* fifo control */ 41#define UMCON 0x000C /* modem control */ 42#define UTRSTAT 0x0010 /* TX/RX status */ 43#define UERSTAT 0x0014 /* RX error status */ 44#define UFRSTAT 0x0018 /* FIFO status */ 45#define UMSTAT 0x001C /* modem status */ 46#define UTXH 0x0020 /* TX buffer */ 47#define URXH 0x0024 /* RX buffer */ 48#define UBRDIV 0x0028 /* baud rate divisor */ 49#define UFRACVAL 0x002C /* divisor fractional value */ 50#define UINTP 0x0030 /* interrupt pending */ 51#define UINTSP 0x0034 /* interrupt source pending */ 52#define UINTM 0x0038 /* interrupt mask */ 53 54/* UTRSTAT */ 55#define TRSTAT_RXTIMEOUT BIT(3) 56#define TRSTAT_TX_EMPTY BIT(2) 57#define TRSTAT_TXBUF_EMPTY BIT(1) 58#define TRSTAT_RXBUF_READY BIT(0) 59 60/* FRSTAT */ 61#define FRSTAT_TX_FULL BIT(24) 62#define FRSTAT_GET_TXFIFO(x) (((x) >> 16) & 0xff) 63#define FRSTAT_RXFIFO_ERR BIT(9) 64#define FRSTAT_RXFIFO_FULL BIT(8) 65#define FRSTAT_GET_RXFIFO(x) (((x) >> 0) & 0xff) 66 67/* UCON */ 68#define CON_MODE_DISABLE 0x0 69#define CON_MODE_POLL 0x1 70#define CON_MODE_DMA 0x2 71#define CON_MODE_MASK 0x3 72#define CON_TXMODE(x) (CON_MODE_##x << 2) 73#define CON_RXMODE(x) (CON_MODE_##x << 0) 74#define CON_RX_TIMEOUT(x) (((x) & 0xf) << 12) 75#define CON_RX_TIMEOUT_MASK CON_RX_TIMEOUT(0xf) 76#define CON_RX_TIMEOUT_EMPTY BIT(11) 77#define CON_TXIRQTYPE_LEVEL BIT(9) 78#define CON_RXIRQTYPE_LEVEL BIT(8) 79#define CON_RXTIMEOUT_ENABLE BIT(7) 80#define CON_RXERR_IRQ_EN BIT(6) 81/* FIFO control */ 82#define FIFO_EN BIT(0) 83#define FIFO_RX_RESET BIT(1) 84#define FIFO_TX_RESET BIT(2) 85#define FIFO_TXLVL(x) ((x) << 8) 86#define FIFO_TXLVL_MASK FIFO_TXLVL(0x7) 87#define FIFO_RXLVL(x) ((x) << 4) 88#define FIFO_RXLVL_MASK FIFO_RXLVL(0x7) 89 90/* INTP, INTSP, INTM */ 91#define INT_MODEM BIT(3) 92#define INT_TX BIT(2) 93#define INT_ERR BIT(1) 94#define INT_RX BIT(0) 95 96#define REG_PTR(base, offset) ((volatile uint32_t *)((char*)(base) + (offset))) 97 98static clk_t *clk; 99 100enum mux_feature uart_mux[] = { 101 [PS_SERIAL0] = MUX_UART0, 102 [PS_SERIAL1] = MUX_UART1, 103 [PS_SERIAL2] = MUX_UART2, 104 [PS_SERIAL3] = MUX_UART3 105}; 106 107static const int uart_irqs[][2] = { 108 [PS_SERIAL0] = {EXYNOS_UART0_IRQ, -1}, 109 [PS_SERIAL1] = {EXYNOS_UART1_IRQ, -1}, 110 [PS_SERIAL2] = {EXYNOS_UART2_IRQ, -1}, 111 [PS_SERIAL3] = {EXYNOS_UART3_IRQ, -1} 112}; 113 114static const uint32_t uart_paddr[] = { 115 [PS_SERIAL0] = EXYNOS_UART0_PADDR, 116 [PS_SERIAL1] = EXYNOS_UART1_PADDR, 117 [PS_SERIAL2] = EXYNOS_UART2_PADDR, 118 [PS_SERIAL3] = EXYNOS_UART3_PADDR 119}; 120 121static const enum clk_id uart_clk[] = { 122 [PS_SERIAL0] = CLK_UART0, 123 [PS_SERIAL1] = CLK_UART1, 124 [PS_SERIAL2] = CLK_UART2, 125 [PS_SERIAL3] = CLK_UART3 126}; 127 128#define UART_DEFN(devid) { \ 129 .id = PS_SERIAL##devid, \ 130 .paddr = EXYNOS_UART##devid##_PADDR, \ 131 .size = BIT(12), \ 132 .irqs = uart_irqs[devid], \ 133 .init_fn = &uart_init \ 134 } 135 136static const struct dev_defn dev_defn[] = { 137 UART_DEFN(0), 138 UART_DEFN(1), 139 UART_DEFN(2), 140 UART_DEFN(3), 141}; 142 143static int exynos_uart_putchar(ps_chardevice_t *d, int c) 144{ 145 if (*REG_PTR(d->vaddr, UFRSTAT) & FRSTAT_TX_FULL) { 146 /* abort: no room in FIFO */ 147 return -1; 148 } else { 149 /* Write out the next character. */ 150 *REG_PTR(d->vaddr, UTXH) = c; 151 if (c == '\n' && (d->flags & SERIAL_AUTO_CR)) { 152 /* In this case, We should have checked that we had two free bytes in 153 * the FIFO before we submitted the first char, however, the fifo size 154 * would need to be considered and this differs between UARTs. 155 * To keep things simple, we recognise that it is rare for a '\n' to 156 * be sent when there is insufficient FIFO space and accept the 157 * inefficiencies of spinning, waiting for space. 158 */ 159 while (exynos_uart_putchar(d, '\r') < 0); 160 } 161 return c; 162 } 163} 164 165static int uart_fill_fifo(ps_chardevice_t *d, const char *data, size_t len) 166{ 167 int i; 168 for (i = 0; i < len; i++) { 169 if (exynos_uart_putchar(d, *data++) < 0) { 170 return i; 171 } 172 } 173 return len; 174} 175 176static void uart_drain_tx_fifo(ps_chardevice_t *d) 177{ 178 if (d->write_descriptor.data) { 179 exynos_handle_tx_irq(d); 180 } 181} 182 183static ssize_t exynos_uart_write(ps_chardevice_t *d, const void *vdata, size_t count, chardev_callback_t wcb, 184 void *token) 185{ 186 const char *data = (const char *)vdata; 187 int sent; 188 189 /* 190 * Try to further drain the TX FIFO before writing. 191 * This is a slight optimisation to maximize the amount of 192 * data we can write and possibly free up the write 193 * descriptor (instead of returning failure). 194 */ 195 uart_drain_tx_fifo(d); 196 197 if (d->write_descriptor.data) { 198 /* Transaction is already in progress */ 199 return -1; 200 } 201 /* Fill the FIFO */ 202 sent = uart_fill_fifo(d, data, count); 203 if (wcb) { 204 /* Register the callback */ 205 d->write_descriptor.callback = wcb; 206 d->write_descriptor.token = token; 207 d->write_descriptor.bytes_transfered = sent; 208 d->write_descriptor.bytes_requested = count; 209 d->write_descriptor.data = (void *)data + sent; 210 /* Enable TX IRQ */ 211 *REG_PTR(d->vaddr, UINTP) = INT_TX; 212 *REG_PTR(d->vaddr, UINTM) &= ~INT_TX; 213 } 214 return sent; 215} 216 217static void uart_handle_tx_irq(ps_chardevice_t *d) 218{ 219 int sent; 220 int to_send; 221 /* pipe more data onto the fifo */ 222 to_send = d->write_descriptor.bytes_requested - d->write_descriptor.bytes_transfered; 223 sent = uart_fill_fifo(d, d->write_descriptor.data, to_send); 224 d->write_descriptor.bytes_transfered += sent; 225 d->write_descriptor.data += sent; 226 227 /* Check if this transaction is complete */ 228 if (d->write_descriptor.bytes_transfered == d->write_descriptor.bytes_requested) { 229 /* Shutdown IRQs */ 230 *REG_PTR(d->vaddr, UINTM) |= INT_TX; 231 d->write_descriptor.data = NULL; 232 /* Signal completion */ 233 d->write_descriptor.callback(d, CHARDEV_STAT_COMPLETE, 234 d->write_descriptor.bytes_transfered, 235 d->write_descriptor.token); 236 } 237 238 /* Clear the pending flag, ready for the next IRQ */ 239 *REG_PTR(d->vaddr, UINTP) = INT_TX; 240} 241 242static int exynos_uart_getchar(ps_chardevice_t *d) 243{ 244 if (*REG_PTR(d->vaddr, UTRSTAT) & TRSTAT_RXBUF_READY) { 245 return *REG_PTR(d->vaddr, URXH); 246 } else { 247 return -1; 248 } 249} 250 251static int uart_read_fifo(ps_chardevice_t *d, char *data, size_t len) 252{ 253 int i; 254 for (i = 0; i < len; i++) { 255 int c; 256 c = exynos_uart_getchar(d); 257 if (c < 0) { 258 break; 259 } 260 *data++ = c; 261 } 262 /* Clear the pending flag */ 263 *REG_PTR(d->vaddr, UINTP) = INT_RX; 264 return i; 265} 266 267static ssize_t exynos_uart_read(ps_chardevice_t *d, void *vdata, size_t count, chardev_callback_t rcb, void *token) 268{ 269 if (d->read_descriptor.data) { 270 /* Transaction is already in progress */ 271 return -1; 272 } else if (rcb) { 273 /* We don't want to perform an actual read here as we want the ISR to catch 274 * timeouts appropriately. Just register the callback and wait for the IRQ */ 275 d->read_descriptor.callback = rcb; 276 d->read_descriptor.token = token; 277 d->read_descriptor.bytes_transfered = 0; 278 d->read_descriptor.bytes_requested = count; 279 d->read_descriptor.data = (void *)vdata; 280 /* Dont need to enable the RX IRQ because it is always enabled */ 281 return 0; 282 } else { 283 /* Read what we can into the buffer and return */ 284 return uart_read_fifo(d, (char *)vdata, count); 285 } 286} 287 288static void uart_handle_rx_irq(ps_chardevice_t *d) 289{ 290 int timeout; 291 uint32_t v; 292 int read; 293 int to_read; 294 /* If a callback was not registered, simply return. User is expected 295 * to read FIFO data with a call to 'read' */ 296 if (d->read_descriptor.data == NULL) { 297 return; 298 } 299 /* Check for timeout */ 300 v = *REG_PTR(d->vaddr, UTRSTAT); 301 timeout = v & TRSTAT_RXTIMEOUT; 302 /* Clear timeout condition */ 303 *REG_PTR(d->vaddr, UTRSTAT) = v; 304 /* Drain the RX FIFO */ 305 to_read = d->read_descriptor.bytes_requested - d->read_descriptor.bytes_transfered; 306 read = uart_read_fifo(d, d->read_descriptor.data, to_read); 307 if (read >= 0) { 308 d->read_descriptor.bytes_transfered += read; 309 d->read_descriptor.data += read; 310 } 311 312 /* Check if this transaction is complete */ 313 if (timeout || d->read_descriptor.bytes_transfered == d->read_descriptor.bytes_requested) { 314 d->read_descriptor.data = NULL; 315 /* Signal completion */ 316 d->read_descriptor.callback(d, CHARDEV_STAT_COMPLETE, 317 d->read_descriptor.bytes_transfered, 318 d->read_descriptor.token); 319 } 320 /* Clear the pending flag */ 321 *REG_PTR(d->vaddr, UINTP) = INT_RX; 322} 323 324static void uart_flush(ps_chardevice_t *d) 325{ 326 while (!(*REG_PTR(d->vaddr, UTRSTAT) & TRSTAT_TX_EMPTY)); 327} 328 329int exynos_check_irq(ps_chardevice_t *d) 330{ 331 return *REG_PTR(d->vaddr, UINTP); 332} 333 334void exynos_handle_rx_irq(ps_chardevice_t *d) 335{ 336 uint32_t sts; 337 sts = *REG_PTR(d->vaddr, UINTP); 338 if (sts & INT_RX) { 339 sts &= ~INT_RX; 340 uart_handle_rx_irq(d); 341 } 342} 343 344void exynos_handle_tx_irq(ps_chardevice_t *d) 345{ 346 uint32_t sts; 347 sts = *REG_PTR(d->vaddr, UINTP); 348 if (sts & INT_TX) { 349 sts &= ~INT_TX; 350 uart_handle_tx_irq(d); 351 } 352} 353 354static void uart_handle_irq(ps_chardevice_t *d) 355{ 356 uint32_t sts; 357 sts = *REG_PTR(d->vaddr, UINTP); 358 if (sts & INT_TX) { 359 sts &= ~INT_TX; 360 uart_handle_tx_irq(d); 361 } 362 if (sts & INT_RX) { 363 sts &= ~INT_RX; 364 uart_handle_rx_irq(d); 365 } 366 if (sts) { 367 ZF_LOGE("Unhandled IRQ (status 0x%x)\n", sts); 368 } 369} 370 371#define BRDIV_BITS 16 372static int uart_set_baud(const ps_chardevice_t *d, long bps) 373{ 374 long div_val, sclk_uart; 375 uint32_t brdiv, brfrac; 376 377 sclk_uart = (clk == NULL) ? UART_DEFAULT_FIN : clk_get_freq(clk); 378 div_val = sclk_uart / bps - 16; 379 /* Check if we need to scale down the clock */ 380 if (div_val / 16 >> BRDIV_BITS > 0) { 381 assert(!"Not implemented"); 382 sclk_uart = 0;//clk_set_div(device_data_clk(d), div_val >> BRDIV_BITS); 383 div_val = sclk_uart / bps; 384 /* Make sure that we have fixed the problem */ 385 if (div_val / 16 >> BRDIV_BITS > 0) { 386 return -1; 387 } 388 } 389 brfrac = div_val % 16; 390 brdiv = (div_val / 16) & 0xffff; 391 392 *REG_PTR(d->vaddr, UBRDIV) = brdiv; 393 *REG_PTR(d->vaddr, UFRACVAL) = brfrac; 394 return 0; 395} 396 397static int uart_set_charsize(ps_chardevice_t *d, int char_size) 398{ 399 uint32_t v; 400 v = *REG_PTR(d->vaddr, ULCON); 401 v &= ~(0x3 << 0); 402 switch (char_size) { 403 case 5: 404 v |= (0x0 << 0); 405 break; 406 case 6: 407 v |= (BIT(0)); 408 break; 409 case 7: 410 v |= (0x2 << 0); 411 break; 412 case 8: 413 v |= (0x3 << 0); 414 break; 415 default : 416 return -1; 417 } 418 *REG_PTR(d->vaddr, ULCON) = v; 419 return 0; 420} 421 422static int uart_set_stop(ps_chardevice_t *d, int stop_bits) 423{ 424 uint32_t v; 425 v = *REG_PTR(d->vaddr, ULCON); 426 v &= ~(BIT(2)); 427 switch (stop_bits) { 428 case 1: 429 v |= (0x0 << 2); 430 break; 431 case 2: 432 v |= (BIT(2)); 433 break; 434 default : 435 return -1; 436 } 437 *REG_PTR(d->vaddr, ULCON) = v; 438 return 0; 439} 440 441static int uart_set_parity(ps_chardevice_t *d, enum serial_parity parity) 442{ 443 uint32_t v; 444 v = *REG_PTR(d->vaddr, ULCON); 445 v &= ~(0x7 << 3); 446 switch (parity) { 447 case PARITY_EVEN: 448 v |= (0x5 << 3); 449 break; 450 case PARITY_ODD: 451 v |= (0x4 << 3); 452 break; 453 case PARITY_NONE: 454 v |= (0x0 << 3); 455 break; 456 default : 457 return -1; 458 } 459 *REG_PTR(d->vaddr, ULCON) = v; 460 return 0; 461} 462 463int serial_configure(ps_chardevice_t *d, long bps, int char_size, 464 enum serial_parity parity, int stop_bits) 465{ 466 return uart_set_baud(d, bps) 467 || uart_set_parity(d, parity) 468 || uart_set_charsize(d, char_size) 469 || uart_set_stop(d, stop_bits); 470} 471 472static void mux_uart_init(enum mux_feature feature, mux_sys_t *mux_sys) 473{ 474 if (mux_sys_valid(mux_sys)) { 475 if (mux_feature_enable(mux_sys, feature, MUX_DIR_NOT_A_GPIO)) { 476 ZF_LOGE("Failed to initialise MUX for UART\n"); 477 } 478 } 479} 480 481static void chardevice_init(ps_chardevice_t *dev, void *vaddr, const int *irqs) 482{ 483 assert(dev != NULL); 484 memset(dev, 0, sizeof(*dev)); 485 dev->vaddr = vaddr; 486 dev->read = &exynos_uart_read; 487 dev->write = &exynos_uart_write; 488 dev->handle_irq = &uart_handle_irq; 489 dev->irqs = irqs; 490 dev->flags = SERIAL_AUTO_CR; 491 /* TODO */ 492 dev->clk = NULL; 493} 494 495int exynos_serial_init(enum chardev_id id, void *vaddr, mux_sys_t *mux_sys, 496 clk_t *clk_src, ps_chardevice_t *dev) 497{ 498 int v; 499 uart_flush(dev); 500 501 if (clk_src != NULL) { 502 clk = clk_src; 503 } 504 505 /* Set character encoding */ 506 serial_configure(dev, 115200UL, 8, PARITY_NONE, 1); 507 /* Set FIFO trigger levels */ 508 v = FIFO_EN; 509 v |= FIFO_RXLVL(FIFO_RXLVL_VAL); 510 v |= FIFO_TXLVL(FIFO_TXLVL_VAL); 511 *REG_PTR(dev->vaddr, UFCON) = v; 512 /* Configure TX/RX modes and enable TX/RX */ 513 v = CON_RX_TIMEOUT(RX_TIMEOUT_VAL) | CON_RXTIMEOUT_ENABLE; 514 v |= (CON_TXMODE(POLL) | CON_RXMODE(POLL)); 515 v |= CON_TXIRQTYPE_LEVEL | CON_RXIRQTYPE_LEVEL; 516 *REG_PTR(dev->vaddr, UCON) = v; 517 /* Enable RX IRQ */ 518 *REG_PTR(dev->vaddr, UINTM) = ~INT_RX; 519 *REG_PTR(dev->vaddr, UINTP) = INT_RX | INT_TX | INT_ERR | INT_MODEM; 520 521 return 0; 522} 523 524static clk_t *clk_init(enum clk_id clock_id, ps_io_ops_t *ops) 525{ 526 assert(ops != NULL); 527 if (clock_sys_valid(&ops->clock_sys)) { 528 return clk_get_clock(&ops->clock_sys, clock_id); 529 } 530 return NULL; 531} 532 533int serial_init(enum chardev_id id, ps_io_ops_t *ops, 534 ps_chardevice_t *dev) 535{ 536 void *vaddr; 537 clk_t *clk; 538 vaddr = ps_io_map(&ops->io_mapper, uart_paddr[id], BIT(12), 0, PS_MEM_NORMAL); 539 if (vaddr == NULL) { 540 return -1; 541 } 542 clk = clk_init(uart_clk[id], ops); 543 mux_uart_init(uart_mux[id], (mux_sys_t *)&ops->mux_sys); 544 chardevice_init(dev, vaddr, &uart_irqs[id][0]); 545 dev->id = id; 546 return exynos_serial_init(id, vaddr, &ops->mux_sys, clk, dev); 547} 548 549int uart_init(const struct dev_defn *defn, const ps_io_ops_t *ops, ps_chardevice_t *dev) 550{ 551 return serial_init(defn->id, (ps_io_ops_t *)ops, dev); 552} 553 554ps_chardevice_t *ps_cdev_init(enum chardev_id id, const ps_io_ops_t *o, ps_chardevice_t *d) 555{ 556 unsigned int i; 557 for (i = 0; i < ARRAY_SIZE(dev_defn); i++) { 558 if (dev_defn[i].id == id) { 559 return (dev_defn[i].init_fn(dev_defn + i, o, d)) ? NULL : d; 560 } 561 } 562 return NULL; 563} 564 565ps_chardevice_t *ps_cdev_static_init(const ps_io_ops_t *o, ps_chardevice_t *d, void *params) 566{ 567 568 if (params == NULL) { 569 return NULL; 570 } 571 572 static_serial_params_t *serial_params = (static_serial_params_t *) params; 573 clk_t *clk; 574 575 enum clk_id clock_id = serial_params->clock_id; 576 enum mux_feature uart_mux_feature = serial_params->uart_mux_feature; 577 void *vaddr = serial_params->vaddr; 578 if (vaddr == NULL) { 579 return NULL; 580 } 581 clk = clk_init(clock_id, (ps_io_ops_t *)o); 582 mux_uart_init(uart_mux_feature, (mux_sys_t *) &o->mux_sys); 583 chardevice_init(d, vaddr, NULL); 584 return exynos_serial_init(0, vaddr, (mux_sys_t *) &o->mux_sys, clk, d) ? NULL : d; 585} 586