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 <autoconf.h> 14#include <platsupport/gen_config.h> 15 16#include <stdlib.h> 17#include <platsupport/serial.h> 18#include <platsupport/plat/serial.h> 19#include <string.h> 20 21#include "../../../chardev.h" 22 23#ifndef UART_REF_CLK 24#error "UART_REF_CLK undefined" 25#endif 26 27#define UART_SR1_RRDY BIT( 9) 28#define UART_SR1_TRDY BIT(13) 29/* CR1 */ 30#define UART_CR1_UARTEN BIT( 0) 31#define UART_CR1_RRDYEN BIT( 9) 32/* CR2 */ 33#define UART_CR2_SRST BIT( 0) 34#define UART_CR2_RXEN BIT( 1) 35#define UART_CR2_TXEN BIT( 2) 36#define UART_CR2_ATEN BIT( 3) 37#define UART_CR2_RTSEN BIT( 4) 38#define UART_CR2_WS BIT( 5) 39#define UART_CR2_STPB BIT( 6) 40#define UART_CR2_PROE BIT( 7) 41#define UART_CR2_PREN BIT( 8) 42#define UART_CR2_RTEC BIT( 9) 43#define UART_CR2_ESCEN BIT(11) 44#define UART_CR2_CTS BIT(12) 45#define UART_CR2_CTSC BIT(13) 46#define UART_CR2_IRTS BIT(14) 47#define UART_CR2_ESCI BIT(15) 48/* CR3 */ 49#define UART_CR3_RXDMUXDEL BIT( 2) 50/* FCR */ 51#define UART_FCR_RFDIV(x) ((x) * BIT(7)) 52#define UART_FCR_RFDIV_MASK UART_FCR_RFDIV(0x7) 53#define UART_FCR_RXTL(x) ((x) * BIT(0)) 54#define UART_FCR_RXTL_MASK UART_FCR_RXTL(0x1F) 55/* SR2 */ 56#define UART_SR2_RXFIFO_RDR BIT(0) 57#define UART_SR2_TXFIFO_EMPTY BIT(14) 58/* RXD */ 59#define UART_URXD_READY_MASK BIT(15) 60#define UART_BYTE_MASK 0xFF 61 62struct imx_uart_regs { 63 uint32_t rxd; /* 0x000 Receiver Register */ 64 uint32_t res0[15]; 65 uint32_t txd; /* 0x040 Transmitter Register */ 66 uint32_t res1[15]; 67 uint32_t cr1; /* 0x080 Control Register 1 */ 68 uint32_t cr2; /* 0x084 Control Register 2 */ 69 uint32_t cr3; /* 0x088 Control Register 3 */ 70 uint32_t cr4; /* 0x08C Control Register 4 */ 71 uint32_t fcr; /* 0x090 FIFO Control Register */ 72 uint32_t sr1; /* 0x094 Status Register 1 */ 73 uint32_t sr2; /* 0x098 Status Register 2 */ 74 uint32_t esc; /* 0x09c Escape Character Register */ 75 uint32_t tim; /* 0x0a0 Escape Timer Register */ 76 uint32_t bir; /* 0x0a4 BRM Incremental Register */ 77 uint32_t bmr; /* 0x0a8 BRM Modulator Register */ 78 uint32_t brc; /* 0x0ac Baud Rate Counter Register */ 79 uint32_t onems; /* 0x0b0 One Millisecond Register */ 80 uint32_t ts; /* 0x0b4 Test Register */ 81}; 82typedef volatile struct imx_uart_regs imx_uart_regs_t; 83 84static inline imx_uart_regs_t *imx_uart_get_priv( 85 ps_chardevice_t *d) 86{ 87 return (imx_uart_regs_t *)d->vaddr; 88} 89 90int uart_getchar( 91 ps_chardevice_t *d) 92{ 93 imx_uart_regs_t *regs = imx_uart_get_priv(d); 94 uint32_t reg = 0; 95 int c = -1; 96 97 if (regs->sr2 & UART_SR2_RXFIFO_RDR) { 98 reg = regs->rxd; 99 if (reg & UART_URXD_READY_MASK) { 100 c = reg & UART_BYTE_MASK; 101 } 102 } 103 return c; 104} 105 106static int internal_is_tx_fifo_busy( 107 imx_uart_regs_t *regs) 108{ 109 /* check the TXFE (transmit buffer FIFO empty) flag, which is cleared 110 * automatically when data is written to the TxFIFO. Even though the flag 111 * is set, the actual data transmission via the UART's 32 byte FIFO buffer 112 * might still be in progress. 113 */ 114 return (0 == (regs->sr2 & UART_SR2_TXFIFO_EMPTY)); 115} 116 117int uart_putchar( 118 ps_chardevice_t *d, 119 int c) 120{ 121 imx_uart_regs_t *regs = imx_uart_get_priv(d); 122 123 if (internal_is_tx_fifo_busy(regs)) { 124 return -1; 125 } 126 127 if (c == '\n' && (d->flags & SERIAL_AUTO_CR)) { 128 /* write CR first */ 129 regs->txd = '\r'; 130 /* if we transform a '\n' (LF) into '\r\n' (CR+LF) this shall become an 131 * atom, ie we don't want CR to be sent and then fail at sending LF 132 * because the TX FIFO is full. Basically there are two options: 133 * - check if the FIFO can hold CR+LF and either send both or none 134 * - send CR, then block until the FIFO has space and send LF. 135 * Assuming that if SERIAL_AUTO_CR is set, it's likely this is a serial 136 * console for logging, so blocking seems acceptable in this special 137 * case. The IMX6's TX FIFO size is 32 byte and TXFIFO_EMPTY is cleared 138 * automatically as soon as data is written from regs->txd into the 139 * FIFO. Thus the worst case blocking is roughly the time it takes to 140 * send 1 byte to have room in the FIFO again. At 115200 baud with 8N1 141 * this takes 10 bit-times, which is 10/115200 = 86,8 usec. 142 */ 143 while (internal_is_tx_fifo_busy(regs)) { 144 /* busy loop */ 145 } 146 } 147 148 regs->txd = c; 149 return c; 150} 151 152static void uart_handle_irq(ps_chardevice_t *d UNUSED) 153{ 154 /* TODO */ 155} 156 157/* 158 * BaudRate = RefFreq / (16 * (BMR + 1)/(BIR + 1) ) 159 * BMR and BIR are 16 bit 160 */ 161static void imx_uart_set_baud( 162 ps_chardevice_t *d, 163 long bps) 164{ 165 imx_uart_regs_t *regs = imx_uart_get_priv(d); 166 uint32_t bmr, bir, fcr; 167 fcr = regs->fcr; 168 fcr &= ~UART_FCR_RFDIV_MASK; 169 fcr |= UART_FCR_RFDIV(4); 170 bir = 0xf; 171 bmr = UART_REF_CLK / bps - 1; 172 regs->bir = bir; 173 regs->bmr = bmr; 174 regs->fcr = fcr; 175} 176 177int serial_configure( 178 ps_chardevice_t *d, 179 long bps, 180 int char_size, 181 enum serial_parity parity, 182 int stop_bits) 183{ 184 imx_uart_regs_t *regs = imx_uart_get_priv(d); 185 uint32_t cr2; 186 /* Character size */ 187 cr2 = regs->cr2; 188 if (char_size == 8) { 189 cr2 |= UART_CR2_WS; 190 } else if (char_size == 7) { 191 cr2 &= ~UART_CR2_WS; 192 } else { 193 return -1; 194 } 195 /* Stop bits */ 196 if (stop_bits == 2) { 197 cr2 |= UART_CR2_STPB; 198 } else if (stop_bits == 1) { 199 cr2 &= ~UART_CR2_STPB; 200 } else { 201 return -1; 202 } 203 /* Parity */ 204 if (parity == PARITY_NONE) { 205 cr2 &= ~UART_CR2_PREN; 206 } else if (parity == PARITY_ODD) { 207 /* ODD */ 208 cr2 |= UART_CR2_PREN; 209 cr2 |= UART_CR2_PROE; 210 } else if (parity == PARITY_EVEN) { 211 /* Even */ 212 cr2 |= UART_CR2_PREN; 213 cr2 &= ~UART_CR2_PROE; 214 } else { 215 return -1; 216 } 217 /* Apply the changes */ 218 regs->cr2 = cr2; 219 /* Now set the board rate */ 220 imx_uart_set_baud(d, bps); 221 return 0; 222} 223 224int uart_init( 225 const struct dev_defn *defn, 226 const ps_io_ops_t *ops, 227 ps_chardevice_t *dev) 228{ 229 /* Attempt to map the virtual address, assure this works */ 230 void *vaddr = chardev_map(defn, ops); 231 if (vaddr == NULL) { 232 return -1; 233 } 234 235 memset(dev, 0, sizeof(*dev)); 236 237 /* Set up all the device properties. */ 238 dev->id = defn->id; 239 dev->vaddr = (void *)vaddr; 240 dev->read = &uart_read; 241 dev->write = &uart_write; 242 dev->handle_irq = &uart_handle_irq; 243 dev->irqs = defn->irqs; 244 dev->ioops = *ops; 245 dev->flags = SERIAL_AUTO_CR; 246 247 imx_uart_regs_t *regs = imx_uart_get_priv(dev); 248 249 /* Software reset */ 250 regs->cr2 &= ~UART_CR2_SRST; 251 while (!(regs->cr2 & UART_CR2_SRST)); 252 253 /* Line configuration */ 254 serial_configure(dev, 115200, 8, PARITY_NONE, 1); 255 256 /* Enable the UART */ 257 regs->cr1 |= UART_CR1_UARTEN; /* Enable The uart. */ 258 regs->cr2 |= UART_CR2_RXEN | UART_CR2_TXEN; /* RX/TX enable */ 259 regs->cr2 |= UART_CR2_IRTS; /* Ignore RTS */ 260 regs->cr3 |= UART_CR3_RXDMUXDEL; /* Configure the RX MUX */ 261 /* Initialise the receiver interrupt. */ 262 regs->cr1 &= ~UART_CR1_RRDYEN; /* Disable recv interrupt. */ 263 regs->fcr &= ~UART_FCR_RXTL_MASK; /* Clear the rx trigger level value. */ 264 regs->fcr |= UART_FCR_RXTL(1); /* Set the rx tigger level to 1. */ 265 regs->cr1 |= UART_CR1_RRDYEN; /* Enable recv interrupt. */ 266 267 268#ifdef CONFIG_PLAT_IMX6 269#include <platsupport/plat/mux.h> 270 /* The UART1 on the IMX6 has the problem that the MUX is not correctly set, 271 * and the RX PIN is not routed correctly. 272 */ 273 if ((defn->id == IMX_UART1) && mux_sys_valid(&ops->mux_sys)) { 274 if (mux_feature_enable(&ops->mux_sys, MUX_UART1, 0)) { 275 /* Failed to configure the mux */ 276 return -1; 277 } 278 } 279#endif 280 281 return 0; 282} 283