blob: 15c74975331752ca2e17ca47aab0e623858b90a8 [file] [log] [blame]
Carlo Caioneff7693d2014-08-17 12:49:49 +02001/*
2 * Based on meson_uart.c, by AMLOGIC, INC.
3 *
4 * Copyright (C) 2014 Carlo Caione <carlo@caione.org>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/clk.h>
18#include <linux/console.h>
19#include <linux/delay.h>
20#include <linux/init.h>
21#include <linux/io.h>
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/of.h>
25#include <linux/platform_device.h>
26#include <linux/serial.h>
27#include <linux/serial_core.h>
28#include <linux/tty.h>
29#include <linux/tty_flip.h>
30
31/* Register offsets */
32#define AML_UART_WFIFO 0x00
33#define AML_UART_RFIFO 0x04
34#define AML_UART_CONTROL 0x08
35#define AML_UART_STATUS 0x0c
36#define AML_UART_MISC 0x10
37#define AML_UART_REG5 0x14
38
39/* AML_UART_CONTROL bits */
40#define AML_UART_TX_EN BIT(12)
41#define AML_UART_RX_EN BIT(13)
42#define AML_UART_TX_RST BIT(22)
43#define AML_UART_RX_RST BIT(23)
44#define AML_UART_CLR_ERR BIT(24)
45#define AML_UART_RX_INT_EN BIT(27)
46#define AML_UART_TX_INT_EN BIT(28)
47#define AML_UART_DATA_LEN_MASK (0x03 << 20)
48#define AML_UART_DATA_LEN_8BIT (0x00 << 20)
49#define AML_UART_DATA_LEN_7BIT (0x01 << 20)
50#define AML_UART_DATA_LEN_6BIT (0x02 << 20)
51#define AML_UART_DATA_LEN_5BIT (0x03 << 20)
52
53/* AML_UART_STATUS bits */
54#define AML_UART_PARITY_ERR BIT(16)
55#define AML_UART_FRAME_ERR BIT(17)
56#define AML_UART_TX_FIFO_WERR BIT(18)
57#define AML_UART_RX_EMPTY BIT(20)
58#define AML_UART_TX_FULL BIT(21)
59#define AML_UART_TX_EMPTY BIT(22)
60#define AML_UART_ERR (AML_UART_PARITY_ERR | \
61 AML_UART_FRAME_ERR | \
62 AML_UART_TX_FIFO_WERR)
63
64/* AML_UART_CONTROL bits */
65#define AML_UART_TWO_WIRE_EN BIT(15)
66#define AML_UART_PARITY_TYPE BIT(18)
67#define AML_UART_PARITY_EN BIT(19)
68#define AML_UART_CLEAR_ERR BIT(24)
69#define AML_UART_STOP_BIN_LEN_MASK (0x03 << 16)
70#define AML_UART_STOP_BIN_1SB (0x00 << 16)
71#define AML_UART_STOP_BIN_2SB (0x01 << 16)
72
73/* AML_UART_MISC bits */
74#define AML_UART_XMIT_IRQ(c) (((c) & 0xff) << 8)
75#define AML_UART_RECV_IRQ(c) ((c) & 0xff)
76
77/* AML_UART_REG5 bits */
78#define AML_UART_BAUD_MASK 0x7fffff
79#define AML_UART_BAUD_USE BIT(23)
80
81#define AML_UART_PORT_NUM 6
82#define AML_UART_DEV_NAME "ttyAML"
83
84
85static struct uart_driver meson_uart_driver;
86
87static struct uart_port *meson_ports[AML_UART_PORT_NUM];
88
89static void meson_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
90{
91}
92
93static unsigned int meson_uart_get_mctrl(struct uart_port *port)
94{
95 return TIOCM_CTS;
96}
97
98static unsigned int meson_uart_tx_empty(struct uart_port *port)
99{
100 u32 val;
101
102 val = readl(port->membase + AML_UART_STATUS);
103 return (val & AML_UART_TX_EMPTY) ? TIOCSER_TEMT : 0;
104}
105
106static void meson_uart_stop_tx(struct uart_port *port)
107{
108 u32 val;
109
110 val = readl(port->membase + AML_UART_CONTROL);
111 val &= ~AML_UART_TX_EN;
112 writel(val, port->membase + AML_UART_CONTROL);
113}
114
115static void meson_uart_stop_rx(struct uart_port *port)
116{
117 u32 val;
118
119 val = readl(port->membase + AML_UART_CONTROL);
120 val &= ~AML_UART_RX_EN;
121 writel(val, port->membase + AML_UART_CONTROL);
122}
123
124static void meson_uart_shutdown(struct uart_port *port)
125{
126 unsigned long flags;
127 u32 val;
128
129 free_irq(port->irq, port);
130
131 spin_lock_irqsave(&port->lock, flags);
132
133 val = readl(port->membase + AML_UART_CONTROL);
134 val &= ~(AML_UART_RX_EN | AML_UART_TX_EN);
135 val &= ~(AML_UART_RX_INT_EN | AML_UART_TX_INT_EN);
136 writel(val, port->membase + AML_UART_CONTROL);
137
138 spin_unlock_irqrestore(&port->lock, flags);
139}
140
141static void meson_uart_start_tx(struct uart_port *port)
142{
143 struct circ_buf *xmit = &port->state->xmit;
144 unsigned int ch;
145
146 if (uart_tx_stopped(port)) {
147 meson_uart_stop_tx(port);
148 return;
149 }
150
151 while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)) {
152 if (port->x_char) {
153 writel(port->x_char, port->membase + AML_UART_WFIFO);
154 port->icount.tx++;
155 port->x_char = 0;
156 continue;
157 }
158
159 if (uart_circ_empty(xmit))
160 break;
161
162 ch = xmit->buf[xmit->tail];
163 writel(ch, port->membase + AML_UART_WFIFO);
164 xmit->tail = (xmit->tail+1) & (SERIAL_XMIT_SIZE - 1);
165 port->icount.tx++;
166 }
167
168 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
169 uart_write_wakeup(port);
170}
171
172static void meson_receive_chars(struct uart_port *port)
173{
174 struct tty_port *tport = &port->state->port;
175 char flag;
176 u32 status, ch, mode;
177
178 do {
179 flag = TTY_NORMAL;
180 port->icount.rx++;
181 status = readl(port->membase + AML_UART_STATUS);
182
183 if (status & AML_UART_ERR) {
184 if (status & AML_UART_TX_FIFO_WERR)
185 port->icount.overrun++;
186 else if (status & AML_UART_FRAME_ERR)
187 port->icount.frame++;
188 else if (status & AML_UART_PARITY_ERR)
189 port->icount.frame++;
190
191 mode = readl(port->membase + AML_UART_CONTROL);
192 mode |= AML_UART_CLEAR_ERR;
193 writel(mode, port->membase + AML_UART_CONTROL);
194
195 /* It doesn't clear to 0 automatically */
196 mode &= ~AML_UART_CLEAR_ERR;
197 writel(mode, port->membase + AML_UART_CONTROL);
198
199 status &= port->read_status_mask;
200 if (status & AML_UART_FRAME_ERR)
201 flag = TTY_FRAME;
202 else if (status & AML_UART_PARITY_ERR)
203 flag = TTY_PARITY;
204 }
205
206 ch = readl(port->membase + AML_UART_RFIFO);
207 ch &= 0xff;
208
209 if ((status & port->ignore_status_mask) == 0)
210 tty_insert_flip_char(tport, ch, flag);
211
212 if (status & AML_UART_TX_FIFO_WERR)
213 tty_insert_flip_char(tport, 0, TTY_OVERRUN);
214
215 } while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY));
216
217 spin_unlock(&port->lock);
218 tty_flip_buffer_push(tport);
219 spin_lock(&port->lock);
220}
221
222static irqreturn_t meson_uart_interrupt(int irq, void *dev_id)
223{
224 struct uart_port *port = (struct uart_port *)dev_id;
225
226 spin_lock(&port->lock);
227
228 if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY))
229 meson_receive_chars(port);
230
231 if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL))
232 meson_uart_start_tx(port);
233
234 spin_unlock(&port->lock);
235
236 return IRQ_HANDLED;
237}
238
239static const char *meson_uart_type(struct uart_port *port)
240{
241 return (port->type == PORT_MESON) ? "meson_uart" : NULL;
242}
243
244static int meson_uart_startup(struct uart_port *port)
245{
246 u32 val;
247 int ret = 0;
248
249 val = readl(port->membase + AML_UART_CONTROL);
250 val |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR);
251 writel(val, port->membase + AML_UART_CONTROL);
252
253 val &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR);
254 writel(val, port->membase + AML_UART_CONTROL);
255
256 val |= (AML_UART_RX_EN | AML_UART_TX_EN);
257 writel(val, port->membase + AML_UART_CONTROL);
258
259 val |= (AML_UART_RX_INT_EN | AML_UART_TX_INT_EN);
260 writel(val, port->membase + AML_UART_CONTROL);
261
262 val = (AML_UART_RECV_IRQ(1) | AML_UART_XMIT_IRQ(port->fifosize / 2));
263 writel(val, port->membase + AML_UART_MISC);
264
265 ret = request_irq(port->irq, meson_uart_interrupt, 0,
266 meson_uart_type(port), port);
267
268 return ret;
269}
270
271static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
272{
273 u32 val;
274
275 while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_EMPTY))
276 cpu_relax();
277
278 val = readl(port->membase + AML_UART_REG5);
279 val &= ~AML_UART_BAUD_MASK;
280 val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
281 val |= AML_UART_BAUD_USE;
282 writel(val, port->membase + AML_UART_REG5);
283}
284
285static void meson_uart_set_termios(struct uart_port *port,
286 struct ktermios *termios,
287 struct ktermios *old)
288{
289 unsigned int cflags, iflags, baud;
290 unsigned long flags;
291 u32 val;
292
293 spin_lock_irqsave(&port->lock, flags);
294
295 cflags = termios->c_cflag;
296 iflags = termios->c_iflag;
297
298 val = readl(port->membase + AML_UART_CONTROL);
299
300 val &= ~AML_UART_DATA_LEN_MASK;
301 switch (cflags & CSIZE) {
302 case CS8:
303 val |= AML_UART_DATA_LEN_8BIT;
304 break;
305 case CS7:
306 val |= AML_UART_DATA_LEN_7BIT;
307 break;
308 case CS6:
309 val |= AML_UART_DATA_LEN_6BIT;
310 break;
311 case CS5:
312 val |= AML_UART_DATA_LEN_5BIT;
313 break;
314 }
315
316 if (cflags & PARENB)
317 val |= AML_UART_PARITY_EN;
318 else
319 val &= ~AML_UART_PARITY_EN;
320
321 if (cflags & PARODD)
322 val |= AML_UART_PARITY_TYPE;
323 else
324 val &= ~AML_UART_PARITY_TYPE;
325
326 val &= ~AML_UART_STOP_BIN_LEN_MASK;
327 if (cflags & CSTOPB)
328 val |= AML_UART_STOP_BIN_2SB;
329 else
330 val &= ~AML_UART_STOP_BIN_1SB;
331
332 if (cflags & CRTSCTS)
333 val &= ~AML_UART_TWO_WIRE_EN;
334 else
335 val |= AML_UART_TWO_WIRE_EN;
336
337 writel(val, port->membase + AML_UART_CONTROL);
338
339 baud = uart_get_baud_rate(port, termios, old, 9600, 115200);
340 meson_uart_change_speed(port, baud);
341
342 port->read_status_mask = AML_UART_TX_FIFO_WERR;
343 if (iflags & INPCK)
344 port->read_status_mask |= AML_UART_PARITY_ERR |
345 AML_UART_FRAME_ERR;
346
347 port->ignore_status_mask = 0;
348 if (iflags & IGNPAR)
349 port->ignore_status_mask |= AML_UART_PARITY_ERR |
350 AML_UART_FRAME_ERR;
351
352 uart_update_timeout(port, termios->c_cflag, baud);
353 spin_unlock_irqrestore(&port->lock, flags);
354}
355
356static int meson_uart_verify_port(struct uart_port *port,
357 struct serial_struct *ser)
358{
359 int ret = 0;
360
361 if (port->type != PORT_MESON)
362 ret = -EINVAL;
363 if (port->irq != ser->irq)
364 ret = -EINVAL;
365 if (ser->baud_base < 9600)
366 ret = -EINVAL;
367 return ret;
368}
369
370static void meson_uart_release_port(struct uart_port *port)
371{
372 if (port->flags & UPF_IOREMAP) {
373 iounmap(port->membase);
374 port->membase = NULL;
375 }
376}
377
378static int meson_uart_request_port(struct uart_port *port)
379{
380 struct platform_device *pdev = to_platform_device(port->dev);
381 struct resource *res;
382 int size;
383
384 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
385 if (!res) {
386 dev_err(&pdev->dev, "cannot obtain I/O memory region");
387 return -ENODEV;
388 }
389 size = resource_size(res);
390
391 if (!devm_request_mem_region(port->dev, port->mapbase, size,
392 dev_name(port->dev))) {
393 dev_err(port->dev, "Memory region busy\n");
394 return -EBUSY;
395 }
396
397 if (port->flags & UPF_IOREMAP) {
398 port->membase = devm_ioremap_nocache(port->dev,
399 port->mapbase,
400 size);
401 if (port->membase == NULL)
402 return -ENOMEM;
403 }
404
405 return 0;
406}
407
408static void meson_uart_config_port(struct uart_port *port, int flags)
409{
410 if (flags & UART_CONFIG_TYPE) {
411 port->type = PORT_MESON;
412 meson_uart_request_port(port);
413 }
414}
415
416static struct uart_ops meson_uart_ops = {
417 .set_mctrl = meson_uart_set_mctrl,
418 .get_mctrl = meson_uart_get_mctrl,
419 .tx_empty = meson_uart_tx_empty,
420 .start_tx = meson_uart_start_tx,
421 .stop_tx = meson_uart_stop_tx,
422 .stop_rx = meson_uart_stop_rx,
423 .startup = meson_uart_startup,
424 .shutdown = meson_uart_shutdown,
425 .set_termios = meson_uart_set_termios,
426 .type = meson_uart_type,
427 .config_port = meson_uart_config_port,
428 .request_port = meson_uart_request_port,
429 .release_port = meson_uart_release_port,
430 .verify_port = meson_uart_verify_port,
431};
432
433#ifdef CONFIG_SERIAL_MESON_CONSOLE
434
435static void meson_console_putchar(struct uart_port *port, int ch)
436{
437 if (!port->membase)
438 return;
439
440 while (readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)
441 cpu_relax();
442 writel(ch, port->membase + AML_UART_WFIFO);
443}
444
445static void meson_serial_console_write(struct console *co, const char *s,
446 u_int count)
447{
448 struct uart_port *port;
449 unsigned long flags;
450 int locked;
451
452 port = meson_ports[co->index];
453 if (!port)
454 return;
455
456 local_irq_save(flags);
457 if (port->sysrq) {
458 locked = 0;
459 } else if (oops_in_progress) {
460 locked = spin_trylock(&port->lock);
461 } else {
462 spin_lock(&port->lock);
463 locked = 1;
464 }
465
466 uart_console_write(port, s, count, meson_console_putchar);
467
468 if (locked)
469 spin_unlock(&port->lock);
470 local_irq_restore(flags);
471}
472
473static int meson_serial_console_setup(struct console *co, char *options)
474{
475 struct uart_port *port;
476 int baud = 115200;
477 int bits = 8;
478 int parity = 'n';
479 int flow = 'n';
480
481 if (co->index < 0 || co->index >= AML_UART_PORT_NUM)
482 return -EINVAL;
483
484 port = meson_ports[co->index];
485 if (!port || !port->membase)
486 return -ENODEV;
487
488 if (options)
489 uart_parse_options(options, &baud, &parity, &bits, &flow);
490
491 return uart_set_options(port, co, baud, parity, bits, flow);
492}
493
494static struct console meson_serial_console = {
495 .name = AML_UART_DEV_NAME,
496 .write = meson_serial_console_write,
497 .device = uart_console_device,
498 .setup = meson_serial_console_setup,
499 .flags = CON_PRINTBUFFER,
500 .index = -1,
501 .data = &meson_uart_driver,
502};
503
504static int __init meson_serial_console_init(void)
505{
506 register_console(&meson_serial_console);
507 return 0;
508}
509console_initcall(meson_serial_console_init);
510
511#define MESON_SERIAL_CONSOLE (&meson_serial_console)
512#else
513#define MESON_SERIAL_CONSOLE NULL
514#endif
515
516static struct uart_driver meson_uart_driver = {
517 .owner = THIS_MODULE,
518 .driver_name = "meson_uart",
519 .dev_name = AML_UART_DEV_NAME,
520 .nr = AML_UART_PORT_NUM,
521 .cons = MESON_SERIAL_CONSOLE,
522};
523
524static int meson_uart_probe(struct platform_device *pdev)
525{
526 struct resource *res_mem, *res_irq;
527 struct uart_port *port;
528 struct clk *clk;
529 int ret = 0;
530
531 if (pdev->dev.of_node)
532 pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
533
534 if (pdev->id < 0 || pdev->id >= AML_UART_PORT_NUM)
535 return -EINVAL;
536
537 res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
538 if (!res_mem)
539 return -ENODEV;
540
541 res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
542 if (!res_irq)
543 return -ENODEV;
544
545 if (meson_ports[pdev->id]) {
546 dev_err(&pdev->dev, "port %d already allocated\n", pdev->id);
547 return -EBUSY;
548 }
549
550 port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
551 if (!port)
552 return -ENOMEM;
553
554 clk = clk_get(&pdev->dev, NULL);
555 if (IS_ERR(clk))
556 return PTR_ERR(clk);
557
558 port->uartclk = clk_get_rate(clk);
559 port->iotype = UPIO_MEM;
560 port->mapbase = res_mem->start;
561 port->irq = res_irq->start;
562 port->flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_LOW_LATENCY;
563 port->dev = &pdev->dev;
564 port->line = pdev->id;
565 port->type = PORT_MESON;
566 port->x_char = 0;
567 port->ops = &meson_uart_ops;
568 port->fifosize = 64;
569
570 meson_ports[pdev->id] = port;
571 platform_set_drvdata(pdev, port);
572
573 ret = uart_add_one_port(&meson_uart_driver, port);
574 if (ret)
575 meson_ports[pdev->id] = NULL;
576
577 return ret;
578}
579
580static int meson_uart_remove(struct platform_device *pdev)
581{
582 struct uart_port *port;
583
584 port = platform_get_drvdata(pdev);
585 uart_remove_one_port(&meson_uart_driver, port);
586 meson_ports[pdev->id] = NULL;
587
588 return 0;
589}
590
591
592static const struct of_device_id meson_uart_dt_match[] = {
593 { .compatible = "amlogic,meson-uart" },
594 { /* sentinel */ },
595};
596MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
597
598static struct platform_driver meson_uart_platform_driver = {
599 .probe = meson_uart_probe,
600 .remove = meson_uart_remove,
601 .driver = {
602 .owner = THIS_MODULE,
603 .name = "meson_uart",
604 .of_match_table = meson_uart_dt_match,
605 },
606};
607
608static int __init meson_uart_init(void)
609{
610 int ret;
611
612 ret = uart_register_driver(&meson_uart_driver);
613 if (ret)
614 return ret;
615
616 ret = platform_driver_register(&meson_uart_platform_driver);
617 if (ret)
618 uart_unregister_driver(&meson_uart_driver);
619
620 return ret;
621}
622
623static void __exit meson_uart_exit(void)
624{
625 platform_driver_unregister(&meson_uart_platform_driver);
626 uart_unregister_driver(&meson_uart_driver);
627}
628
629module_init(meson_uart_init);
630module_exit(meson_uart_exit);
631
632MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
633MODULE_DESCRIPTION("Amlogic Meson serial port driver");
634MODULE_LICENSE("GPL v2");