1 /*
2 * omap-uart.c
3 * Based on drivers/char/ns16550.c
4 *
5 * Driver for OMAP-UART controller
6 *
7 * Copyright (C) 2013, Chen Baozi <baozich@gmail.com>
8 *
9 * Note: This driver is made separate from 16550-series UART driver as
10 * omap platform has some specific configurations
11 */
12
13 #include <xen/console.h>
14 #include <xen/serial.h>
15 #include <xen/init.h>
16 #include <xen/irq.h>
17 #include <xen/device_tree.h>
18 #include <asm/device.h>
19 #include <xen/errno.h>
20 #include <xen/mm.h>
21 #include <xen/vmap.h>
22 #include <xen/8250-uart.h>
23 #include <asm/io.h>
24
25 #define REG_SHIFT 2
26
27 /* Register offsets */
28 #define UART_OMAP_EFR 0x02 /* Enhanced feature register */
29 #define UART_OMAP_MDR1 0x08 /* Mode definition register 1 */
30 #define UART_OMAP_SCR 0x10 /* Supplementary control register */
31 #define UART_OMAP_SSR 0x11 /* Supplementary status register */
32 #define UART_OMAP_SYSC 0x15 /* System configuration register */
33 #define UART_OMAP_TXFIFO_LVL 0x1A /* TX FIFO level register */
34
35 /* Enhanced feature register */
36 #define UART_OMAP_EFR_ECB 0x10 /* Enhanced control bit */
37
38 /* Mode definition register 1 */
39 #define UART_OMAP_MDR1_16X_MODE 0x00 /* UART 16x mode */
40 #define UART_OMAP_MDR1_DISABLE 0x07 /* Disable (default state) */
41
42 /* Supplementary control register bitmasks */
43 #define UART_OMAP_SCR_RX_TRIG_GRANU1_MASK (1 << 7)
44
45 /* Supplementary status register bitmasks */
46 #define UART_OMAP_SSR_TX_FIFO_FULL_MASK (1 << 0)
47
48 /* System configuration register */
49 #define UART_OMAP_SYSC_DEF_CONF 0x0d /* autoidle mode, wakeup is enabled */
50
51 #define omap_read(uart, off) readl((uart)->regs + (off<<REG_SHIFT))
52 #define omap_write(uart, off, val) writel((val), (uart)->regs + (off<<REG_SHIFT))
53
54 static struct omap_uart {
55 u32 baud, clock_hz, data_bits, parity, stop_bits, fifo_size;
56 unsigned int irq;
57 char __iomem *regs;
58 struct irqaction irqaction;
59 struct vuart_info vuart;
60 } omap_com = {0};
61
omap_uart_interrupt(int irq,void * data,struct cpu_user_regs * regs)62 static void omap_uart_interrupt(int irq, void *data, struct cpu_user_regs *regs)
63 {
64 struct serial_port *port = data;
65 struct omap_uart *uart = port->uart;
66 u32 lsr;
67 uint32_t reg;
68
69 while ( !(omap_read(uart, UART_IIR) & UART_IIR_NOINT) )
70 {
71 lsr = omap_read(uart, UART_LSR) & 0xff;
72 if ( lsr & UART_LSR_THRE )
73 serial_tx_interrupt(port, regs);
74 if ( lsr & UART_LSR_DR )
75 serial_rx_interrupt(port, regs);
76
77 if ( port->txbufc == port->txbufp ) {
78 reg = omap_read(uart, UART_IER);
79 omap_write(uart, UART_IER, reg & (~UART_IER_ETHREI));
80 }
81 };
82 }
83
baud_protocol_setup(struct omap_uart * uart)84 static void baud_protocol_setup(struct omap_uart *uart)
85 {
86 u32 dll, dlh, efr;
87 unsigned int divisor;
88
89 divisor = uart->clock_hz / (uart->baud << 4);
90 dll = divisor & 0xff;
91 dlh = divisor >> 8;
92
93 /*
94 * Switch to register configuration mode B to access the UART_OMAP_EFR
95 * register.
96 */
97 omap_write(uart, UART_LCR, UART_LCR_CONF_MODE_B);
98 /*
99 * Enable access to the UART_IER[7:4] bit field.
100 */
101 efr = omap_read(uart, UART_OMAP_EFR);
102 omap_write(uart, UART_OMAP_EFR, efr|UART_OMAP_EFR_ECB);
103 /*
104 * Switch to register operation mode to access the UART_IER register.
105 */
106 omap_write(uart, UART_LCR, 0);
107 /*
108 * Clear the UART_IER register (set the UART_IER[4] SLEEP_MODE bit
109 * to 0 to change the UART_DLL and UART_DLM register). Set the
110 * UART_IER register value to 0x0000.
111 */
112 omap_write(uart, UART_IER, 0);
113 /*
114 * Switch to register configuartion mode B to access the UART_DLL and
115 * UART_DLM registers.
116 */
117 omap_write(uart, UART_LCR, UART_LCR_CONF_MODE_B);
118 /*
119 * Load divisor value.
120 */
121 omap_write(uart, UART_DLL, dll);
122 omap_write(uart, UART_DLM, dlh);
123 /*
124 * Restore the UART_OMAP_EFR
125 */
126 omap_write(uart, UART_OMAP_EFR, efr);
127 /*
128 * Load the new protocol formatting (parity, stop-bit, character length)
129 * and switch to register operational mode.
130 */
131 omap_write(uart, UART_LCR, (uart->data_bits - 5) |
132 ((uart->stop_bits - 1) << 2) | uart->parity);
133 }
134
fifo_setup(struct omap_uart * uart)135 static void fifo_setup(struct omap_uart *uart)
136 {
137 u32 lcr, efr, mcr;
138 /*
139 * Switch to register configuration mode B to access the UART_OMAP_EFR
140 * register.
141 */
142 lcr = omap_read(uart, UART_LCR);
143 omap_write(uart, UART_LCR, UART_LCR_CONF_MODE_B);
144 /*
145 * Enable register submode TCR_TLR to access the UART_OMAP_TLR register.
146 */
147 efr = omap_read(uart, UART_OMAP_EFR);
148 omap_write(uart, UART_OMAP_EFR, efr|UART_OMAP_EFR_ECB);
149 /*
150 * Switch to register configuration mode A to access the UART_MCR
151 * register.
152 */
153 omap_write(uart, UART_LCR, UART_LCR_CONF_MODE_A);
154 /*
155 * Enable register submode TCR_TLR to access the UART_OMAP_TLR register
156 */
157 mcr = omap_read(uart, UART_MCR);
158 omap_write(uart, UART_MCR, mcr|UART_MCR_TCRTLR);
159 /*
160 * Enable the FIFO; load the new FIFO trigger and the new DMA mode.
161 */
162 omap_write(uart, UART_FCR, UART_FCR_R_TRIG_01|
163 UART_FCR_T_TRIG_10|UART_FCR_ENABLE);
164 /*
165 * Switch to register configuration mode B to access the UART_EFR
166 * register.
167 */
168 omap_write(uart, UART_LCR, UART_LCR_CONF_MODE_B);
169 /*
170 * Load the new FIFO triggers and the new DMA mode bit.
171 */
172 omap_write(uart, UART_OMAP_SCR, UART_OMAP_SCR_RX_TRIG_GRANU1_MASK);
173 /*
174 * Restore the UART_OMAP_EFR[4] value.
175 */
176 omap_write(uart, UART_OMAP_EFR, efr);
177 /*
178 * Switch to register configuration mode A to access the UART_MCR
179 * register.
180 */
181 omap_write(uart, UART_LCR, UART_LCR_CONF_MODE_A);
182 /*
183 * Restore UART_MCR[6] value.
184 */
185 omap_write(uart, UART_MCR, mcr);
186 /*
187 * Restore UART_LCR value.
188 */
189 omap_write(uart, UART_LCR, lcr);
190
191 uart->fifo_size = 64;
192 }
193
omap_uart_init_preirq(struct serial_port * port)194 static void __init omap_uart_init_preirq(struct serial_port *port)
195 {
196 struct omap_uart *uart = port->uart;
197
198 /*
199 * Clear the FIFO buffers.
200 */
201 omap_write(uart, UART_FCR, UART_FCR_ENABLE);
202 omap_write(uart, UART_FCR, UART_FCR_ENABLE|UART_FCR_CLRX|UART_FCR_CLTX);
203 omap_write(uart, UART_FCR, 0);
204
205 /*
206 * The TRM says the mode should be disabled while UART_DLL and UART_DHL
207 * are being changed so we disable before setup, then enable.
208 */
209 omap_write(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
210
211 /* Baud rate & protocol format setup */
212 baud_protocol_setup(uart);
213
214 /* FIFO setup */
215 fifo_setup(uart);
216
217 /* No flow control */
218 omap_write(uart, UART_MCR, UART_MCR_DTR|UART_MCR_RTS);
219
220 omap_write(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE);
221
222 /* setup idle mode */
223 omap_write(uart, UART_OMAP_SYSC, UART_OMAP_SYSC_DEF_CONF);
224 }
225
omap_uart_init_postirq(struct serial_port * port)226 static void __init omap_uart_init_postirq(struct serial_port *port)
227 {
228 struct omap_uart *uart = port->uart;
229
230 uart->irqaction.handler = omap_uart_interrupt;
231 uart->irqaction.name = "omap_uart";
232 uart->irqaction.dev_id = port;
233
234 if ( setup_irq(uart->irq, 0, &uart->irqaction) != 0 )
235 {
236 dprintk(XENLOG_ERR, "Failed to allocated omap_uart IRQ %d\n",
237 uart->irq);
238 return;
239 }
240
241 /* Enable interrupts */
242 omap_write(uart, UART_IER, UART_IER_ERDAI|UART_IER_ETHREI|UART_IER_ELSI);
243 }
244
omap_uart_suspend(struct serial_port * port)245 static void omap_uart_suspend(struct serial_port *port)
246 {
247 BUG();
248 }
249
omap_uart_resume(struct serial_port * port)250 static void omap_uart_resume(struct serial_port *port)
251 {
252 BUG();
253 }
254
omap_uart_tx_ready(struct serial_port * port)255 static int omap_uart_tx_ready(struct serial_port *port)
256 {
257 struct omap_uart *uart = port->uart;
258 uint32_t reg;
259 uint8_t cnt;
260
261 reg = omap_read(uart, UART_IER);
262 omap_write(uart, UART_IER, reg | UART_IER_ETHREI);
263
264 /* Check for empty space in TX FIFO */
265 if ( omap_read(uart, UART_OMAP_SSR) & UART_OMAP_SSR_TX_FIFO_FULL_MASK )
266 return 0;
267
268 /* Check number of data bytes stored in TX FIFO */
269 cnt = omap_read(uart, UART_OMAP_TXFIFO_LVL);
270 ASSERT( cnt >= 0 && cnt <= uart->fifo_size );
271
272 return (uart->fifo_size - cnt);
273 }
274
omap_uart_putc(struct serial_port * port,char c)275 static void omap_uart_putc(struct serial_port *port, char c)
276 {
277 struct omap_uart *uart = port->uart;
278
279 omap_write(uart, UART_THR, (uint32_t)(unsigned char)c);
280 }
281
omap_uart_getc(struct serial_port * port,char * pc)282 static int omap_uart_getc(struct serial_port *port, char *pc)
283 {
284 struct omap_uart *uart = port->uart;
285
286 if ( !(omap_read(uart, UART_LSR) & UART_LSR_DR) )
287 return 0;
288
289 *pc = omap_read(uart, UART_RBR) & 0xff;
290 return 1;
291 }
292
omap_uart_irq(struct serial_port * port)293 static int __init omap_uart_irq(struct serial_port *port)
294 {
295 struct omap_uart *uart = port->uart;
296
297 return ((uart->irq > 0) ? uart->irq : -1);
298 }
299
omap_vuart_info(struct serial_port * port)300 static const struct vuart_info *omap_vuart_info(struct serial_port *port)
301 {
302 struct omap_uart *uart = port->uart;
303
304 return &uart->vuart;
305 }
306
307 static struct uart_driver __read_mostly omap_uart_driver = {
308 .init_preirq = omap_uart_init_preirq,
309 .init_postirq = omap_uart_init_postirq,
310 .endboot = NULL,
311 .suspend = omap_uart_suspend,
312 .resume = omap_uart_resume,
313 .tx_ready = omap_uart_tx_ready,
314 .putc = omap_uart_putc,
315 .getc = omap_uart_getc,
316 .irq = omap_uart_irq,
317 .vuart_info = omap_vuart_info,
318 };
319
omap_uart_init(struct dt_device_node * dev,const void * data)320 static int __init omap_uart_init(struct dt_device_node *dev,
321 const void *data)
322 {
323 const char *config = data;
324 struct omap_uart *uart;
325 u32 clkspec;
326 int res;
327 u64 addr, size;
328
329 if ( strcmp(config, "") )
330 printk("WARNING: UART configuration is not supported\n");
331
332 uart = &omap_com;
333
334 res = dt_property_read_u32(dev, "clock-frequency", &clkspec);
335 if ( !res )
336 {
337 printk("omap-uart: Unable to retrieve the clock frequency\n");
338 return -EINVAL;
339 }
340
341 uart->clock_hz = clkspec;
342 uart->baud = 115200;
343 uart->data_bits = 8;
344 uart->parity = UART_PARITY_NONE;
345 uart->stop_bits = 1;
346
347 res = dt_device_get_address(dev, 0, &addr, &size);
348 if ( res )
349 {
350 printk("omap-uart: Unable to retrieve the base"
351 " address of the UART\n");
352 return res;
353 }
354
355 res = platform_get_irq(dev, 0);
356 if ( res < 0 )
357 {
358 printk("omap-uart: Unable to retrieve the IRQ\n");
359 return -EINVAL;
360 }
361 uart->irq = res;
362
363 uart->regs = ioremap_nocache(addr, size);
364 if ( !uart->regs )
365 {
366 printk("omap-uart: Unable to map the UART memory\n");
367 return -ENOMEM;
368 }
369
370
371 uart->vuart.base_addr = addr;
372 uart->vuart.size = size;
373 uart->vuart.data_off = UART_THR;
374 uart->vuart.status_off = UART_LSR << REG_SHIFT;
375 uart->vuart.status = UART_LSR_THRE;
376
377 /* Register with generic serial driver */
378 serial_register_uart(SERHND_DTUART, &omap_uart_driver, uart);
379
380 dt_device_set_used_by(dev, DOMID_XEN);
381
382 return 0;
383 }
384
385 static const struct dt_device_match omap_uart_dt_match[] __initconst =
386 {
387 DT_MATCH_COMPATIBLE("ti,omap4-uart"),
388 { /* sentinel */ },
389 };
390
391 DT_DEVICE_START(omap_uart, "OMAP UART", DEVICE_SERIAL)
392 .dt_match = omap_uart_dt_match,
393 .init = omap_uart_init,
394 DT_DEVICE_END
395
396 /*
397 * Local variables:
398 * mode: C
399 * c-file-style: "BSD"
400 * c-basic-offset: 4
401 * indent-tabs-mode: nil
402 * End:
403 */
404