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#include <stdlib.h> 14#include <platsupport/serial.h> 15#include <platsupport/plat/serial.h> 16#include "serial.h" 17#include <string.h> 18 19#define REG_PTR(base, off) ((volatile uint32_t *)((base) + (off))) 20 21/* When DLAB=1, MU_IO is a baud rate register. 22 * Otherwise, write to TX, read to RX */ 23#define MU_IO 0x40 24/* When DLAB=1, MU_IIR is a baud rate register. 25 * Otherwise IRQ enable */ 26#define MU_IIR 0x44 27#define MU_IER 0x48 28#define MU_LCR 0x4C 29#define MU_MCR 0x50 30#define MU_LSR 0x54 31#define MU_MSR 0x58 32#define MU_SCRATCH 0x5C 33#define MU_CNTL 0x60 34 35/* This bit is set if the transmit FIFO can accept at least one byte.*/ 36#define MU_LSR_TXEMPTY BIT(5) 37/* This bit is set if the transmit FIFO is empty and the 38 * transmitter is idle. (Finished shifting out the last bit). */ 39#define MU_LSR_TXIDLE BIT(6) 40#define MU_LSR_RXOVERRUN BIT(1) 41#define MU_LSR_DATAREADY BIT(0) 42 43#define MU_LCR_DLAB BIT(7) 44#define MU_LCR_BREAK BIT(6) 45#define MU_LCR_DATASIZE BIT(0) 46 47static void 48uart_handle_irq(ps_chardevice_t* d UNUSED) 49{ 50} 51 52int uart_putchar(ps_chardevice_t* d, int c) 53{ 54 while ( !(*REG_PTR(d->vaddr, MU_LSR) & MU_LSR_TXIDLE) ); 55 *REG_PTR(d->vaddr, MU_IO) = (c & 0xff); 56 57 return 0; 58} 59 60int uart_getchar(ps_chardevice_t* d UNUSED) 61{ 62 while ( !(*REG_PTR(d->vaddr, MU_LSR) & MU_LSR_DATAREADY) ); 63 return *REG_PTR(d->vaddr, MU_IO); 64} 65 66int uart_init(const struct dev_defn* defn, 67 const ps_io_ops_t* ops, 68 ps_chardevice_t* dev) 69{ 70 /* Attempt to map the virtual address, assure this works */ 71 void* vaddr = chardev_map(defn, ops); 72 memset(dev, 0, sizeof(*dev)); 73 if (vaddr == NULL) { 74 return -1; 75 } 76 77 /* Set up all the device properties. */ 78 dev->id = defn->id; 79 dev->vaddr = (void*)vaddr; 80 dev->read = &uart_read; 81 dev->write = &uart_write; 82 dev->handle_irq = &uart_handle_irq; 83 dev->irqs = defn->irqs; 84 dev->ioops = *ops; 85 dev->flags = SERIAL_AUTO_CR; 86 87 return 0; 88} 89