meson_uart.c 15 KB

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