1/* 2 * Copyright 2019, 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/* Mostly copy/paste from the HiKey plat. 14 * Should be moved to a common driver file for PL011 */ 15 16#include <string.h> 17#include <stdlib.h> 18#include <platsupport/serial.h> 19#include "../../chardev.h" 20 21#define RHR_MASK MASK(8) 22#define UARTDR 0x000 23#define UARTFR 0x018 24#define UARTIMSC 0x038 25#define UARTICR 0x044 26#define PL011_UARTFR_TXFF BIT(5) 27#define PL011_UARTFR_RXFE BIT(4) 28 29#define REG_PTR(base, off) ((volatile uint32_t *)((base) + (off))) 30 31int uart_getchar(ps_chardevice_t *d) 32{ 33 int ch = EOF; 34 35 if ((*REG_PTR(d->vaddr, UARTFR) & PL011_UARTFR_RXFE) == 0) { 36 ch = *REG_PTR(d->vaddr, UARTDR) & RHR_MASK; 37 } 38 return ch; 39} 40 41int uart_putchar(ps_chardevice_t* d, int c) 42{ 43 while ((*REG_PTR(d->vaddr, UARTFR) & PL011_UARTFR_TXFF) != 0); 44 45 *REG_PTR(d->vaddr, UARTDR) = c; 46 if (c == '\n' && (d->flags & SERIAL_AUTO_CR)) { 47 uart_putchar(d, '\r'); 48 } 49 50 return c; 51} 52 53static void 54uart_handle_irq(ps_chardevice_t* dev) 55{ 56 *REG_PTR(dev->vaddr, UARTICR) = 0x7f0; 57} 58 59int uart_init(const struct dev_defn* defn, 60 const ps_io_ops_t* ops, 61 ps_chardevice_t* dev) 62{ 63 memset(dev, 0, sizeof(*dev)); 64 void* vaddr = chardev_map(defn, ops); 65 if (vaddr == NULL) { 66 return -1; 67 } 68 69 /* Set up all the device properties. */ 70 dev->id = defn->id; 71 dev->vaddr = (void*)vaddr; 72 dev->read = &uart_read; 73 dev->write = &uart_write; 74 dev->handle_irq = &uart_handle_irq; 75 dev->irqs = defn->irqs; 76 dev->ioops = *ops; 77 dev->flags = SERIAL_AUTO_CR; 78 79 *REG_PTR(dev->vaddr, UARTIMSC) = 0x50; 80 return 0; 81} 82