]>
Commit | Line | Data |
---|---|---|
e3b3d0f5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
b4756f4f MB |
2 | /* |
3 | * Mediatek 8250 driver. | |
4 | * | |
5 | * Copyright (c) 2014 MundoReader S.L. | |
6 | * Author: Matthias Brugger <matthias.bgg@gmail.com> | |
b4756f4f MB |
7 | */ |
8 | #include <linux/clk.h> | |
9 | #include <linux/io.h> | |
88725e91 | 10 | #include <linux/module.h> |
b4756f4f MB |
11 | #include <linux/of_irq.h> |
12 | #include <linux/of_platform.h> | |
13 | #include <linux/platform_device.h> | |
14 | #include <linux/pm_runtime.h> | |
15 | #include <linux/serial_8250.h> | |
16 | #include <linux/serial_reg.h> | |
85b5c1dd LC |
17 | #include <linux/console.h> |
18 | #include <linux/dma-mapping.h> | |
19 | #include <linux/tty.h> | |
20 | #include <linux/tty_flip.h> | |
b4756f4f MB |
21 | |
22 | #include "8250.h" | |
23 | ||
24 | #define UART_MTK_HIGHS 0x09 /* Highspeed register */ | |
25 | #define UART_MTK_SAMPLE_COUNT 0x0a /* Sample count register */ | |
26 | #define UART_MTK_SAMPLE_POINT 0x0b /* Sample point register */ | |
27 | #define MTK_UART_RATE_FIX 0x0d /* UART Rate Fix Register */ | |
28 | ||
85b5c1dd LC |
29 | #define MTK_UART_DMA_EN 0x13 /* DMA Enable register */ |
30 | #define MTK_UART_DMA_EN_TX 0x2 | |
31 | #define MTK_UART_DMA_EN_RX 0x5 | |
32 | ||
33 | #define MTK_UART_TX_SIZE UART_XMIT_SIZE | |
34 | #define MTK_UART_RX_SIZE 0x8000 | |
35 | #define MTK_UART_TX_TRIGGER 1 | |
36 | #define MTK_UART_RX_TRIGGER MTK_UART_RX_SIZE | |
37 | ||
38 | #ifdef CONFIG_SERIAL_8250_DMA | |
39 | enum dma_rx_status { | |
40 | DMA_RX_START = 0, | |
41 | DMA_RX_RUNNING = 1, | |
42 | DMA_RX_SHUTDOWN = 2, | |
43 | }; | |
44 | #endif | |
45 | ||
b4756f4f MB |
46 | struct mtk8250_data { |
47 | int line; | |
85b5c1dd | 48 | unsigned int rx_pos; |
b4756f4f | 49 | struct clk *uart_clk; |
c1c325d7 | 50 | struct clk *bus_clk; |
85b5c1dd LC |
51 | struct uart_8250_dma *dma; |
52 | #ifdef CONFIG_SERIAL_8250_DMA | |
53 | enum dma_rx_status rx_status; | |
54 | #endif | |
b4756f4f MB |
55 | }; |
56 | ||
85b5c1dd LC |
57 | #ifdef CONFIG_SERIAL_8250_DMA |
58 | static void mtk8250_rx_dma(struct uart_8250_port *up); | |
59 | ||
60 | static void mtk8250_dma_rx_complete(void *param) | |
61 | { | |
62 | struct uart_8250_port *up = param; | |
63 | struct uart_8250_dma *dma = up->dma; | |
64 | struct mtk8250_data *data = up->port.private_data; | |
65 | struct tty_port *tty_port = &up->port.state->port; | |
66 | struct dma_tx_state state; | |
67 | unsigned char *ptr; | |
68 | int copied; | |
69 | ||
70 | dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr, | |
71 | dma->rx_size, DMA_FROM_DEVICE); | |
72 | ||
73 | dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); | |
74 | ||
75 | if (data->rx_status == DMA_RX_SHUTDOWN) | |
76 | return; | |
77 | ||
78 | if ((data->rx_pos + state.residue) <= dma->rx_size) { | |
79 | ptr = (unsigned char *)(data->rx_pos + dma->rx_buf); | |
80 | copied = tty_insert_flip_string(tty_port, ptr, state.residue); | |
81 | } else { | |
82 | ptr = (unsigned char *)(data->rx_pos + dma->rx_buf); | |
83 | copied = tty_insert_flip_string(tty_port, ptr, | |
84 | dma->rx_size - data->rx_pos); | |
85 | ptr = (unsigned char *)(dma->rx_buf); | |
86 | copied += tty_insert_flip_string(tty_port, ptr, | |
87 | data->rx_pos + state.residue - dma->rx_size); | |
88 | } | |
89 | up->port.icount.rx += copied; | |
90 | ||
91 | tty_flip_buffer_push(tty_port); | |
92 | ||
93 | mtk8250_rx_dma(up); | |
94 | } | |
95 | ||
96 | static void mtk8250_rx_dma(struct uart_8250_port *up) | |
97 | { | |
98 | struct uart_8250_dma *dma = up->dma; | |
99 | struct mtk8250_data *data = up->port.private_data; | |
100 | struct dma_async_tx_descriptor *desc; | |
101 | struct dma_tx_state state; | |
102 | ||
103 | desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr, | |
104 | dma->rx_size, DMA_DEV_TO_MEM, | |
105 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | |
106 | if (!desc) { | |
107 | pr_err("failed to prepare rx slave single\n"); | |
108 | return; | |
109 | } | |
110 | ||
111 | desc->callback = mtk8250_dma_rx_complete; | |
112 | desc->callback_param = up; | |
113 | ||
114 | dma->rx_cookie = dmaengine_submit(desc); | |
115 | ||
116 | dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); | |
117 | data->rx_pos = state.residue; | |
118 | ||
119 | dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr, | |
120 | dma->rx_size, DMA_FROM_DEVICE); | |
121 | ||
122 | dma_async_issue_pending(dma->rxchan); | |
123 | } | |
124 | ||
125 | static void mtk8250_dma_enable(struct uart_8250_port *up) | |
126 | { | |
127 | struct uart_8250_dma *dma = up->dma; | |
128 | struct mtk8250_data *data = up->port.private_data; | |
129 | int lcr = serial_in(up, UART_LCR); | |
130 | ||
131 | if (data->rx_status != DMA_RX_START) | |
132 | return; | |
133 | ||
134 | dma->rxconf.direction = DMA_DEV_TO_MEM; | |
135 | dma->rxconf.src_addr_width = dma->rx_size / 1024; | |
136 | dma->rxconf.src_addr = dma->rx_addr; | |
137 | ||
138 | dma->txconf.direction = DMA_MEM_TO_DEV; | |
139 | dma->txconf.dst_addr_width = MTK_UART_TX_SIZE / 1024; | |
140 | dma->txconf.dst_addr = dma->tx_addr; | |
141 | ||
142 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | | |
143 | UART_FCR_CLEAR_XMIT); | |
144 | serial_out(up, MTK_UART_DMA_EN, | |
145 | MTK_UART_DMA_EN_RX | MTK_UART_DMA_EN_TX); | |
146 | ||
147 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | |
148 | serial_out(up, UART_EFR, UART_EFR_ECB); | |
149 | serial_out(up, UART_LCR, lcr); | |
150 | ||
151 | if (dmaengine_slave_config(dma->rxchan, &dma->rxconf) != 0) | |
152 | pr_err("failed to configure rx dma channel\n"); | |
153 | if (dmaengine_slave_config(dma->txchan, &dma->txconf) != 0) | |
154 | pr_err("failed to configure tx dma channel\n"); | |
155 | ||
156 | data->rx_status = DMA_RX_RUNNING; | |
157 | data->rx_pos = 0; | |
158 | mtk8250_rx_dma(up); | |
159 | } | |
160 | #endif | |
161 | ||
162 | static int mtk8250_startup(struct uart_port *port) | |
163 | { | |
164 | #ifdef CONFIG_SERIAL_8250_DMA | |
165 | struct uart_8250_port *up = up_to_u8250p(port); | |
166 | struct mtk8250_data *data = port->private_data; | |
167 | ||
168 | /* disable DMA for console */ | |
169 | if (uart_console(port)) | |
170 | up->dma = NULL; | |
171 | ||
172 | if (up->dma) { | |
173 | data->rx_status = DMA_RX_START; | |
174 | uart_circ_clear(&port->state->xmit); | |
175 | } | |
176 | #endif | |
177 | memset(&port->icount, 0, sizeof(port->icount)); | |
178 | ||
179 | return serial8250_do_startup(port); | |
180 | } | |
181 | ||
182 | static void mtk8250_shutdown(struct uart_port *port) | |
183 | { | |
184 | #ifdef CONFIG_SERIAL_8250_DMA | |
185 | struct uart_8250_port *up = up_to_u8250p(port); | |
186 | struct mtk8250_data *data = port->private_data; | |
187 | ||
188 | if (up->dma) | |
189 | data->rx_status = DMA_RX_SHUTDOWN; | |
190 | #endif | |
191 | ||
192 | return serial8250_do_shutdown(port); | |
193 | } | |
194 | ||
b4756f4f MB |
195 | static void |
196 | mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, | |
197 | struct ktermios *old) | |
198 | { | |
013e3586 | 199 | struct uart_8250_port *up = up_to_u8250p(port); |
b4756f4f MB |
200 | unsigned long flags; |
201 | unsigned int baud, quot; | |
202 | ||
85b5c1dd LC |
203 | #ifdef CONFIG_SERIAL_8250_DMA |
204 | if (up->dma) { | |
205 | if (uart_console(port)) { | |
206 | devm_kfree(up->port.dev, up->dma); | |
207 | up->dma = NULL; | |
208 | } else { | |
209 | mtk8250_dma_enable(up); | |
210 | } | |
211 | } | |
212 | #endif | |
213 | ||
b4756f4f MB |
214 | serial8250_do_set_termios(port, termios, old); |
215 | ||
216 | /* | |
217 | * Mediatek UARTs use an extra highspeed register (UART_MTK_HIGHS) | |
218 | * | |
219 | * We need to recalcualte the quot register, as the claculation depends | |
220 | * on the vaule in the highspeed register. | |
221 | * | |
222 | * Some baudrates are not supported by the chip, so we use the next | |
223 | * lower rate supported and update termios c_flag. | |
224 | * | |
225 | * If highspeed register is set to 3, we need to specify sample count | |
226 | * and sample point to increase accuracy. If not, we reset the | |
227 | * registers to their default values. | |
228 | */ | |
229 | baud = uart_get_baud_rate(port, termios, old, | |
6263368c | 230 | port->uartclk / 16 / UART_DIV_MAX, |
81bb549f | 231 | port->uartclk); |
b4756f4f MB |
232 | |
233 | if (baud <= 115200) { | |
234 | serial_port_out(port, UART_MTK_HIGHS, 0x0); | |
235 | quot = uart_get_divisor(port, baud); | |
236 | } else if (baud <= 576000) { | |
237 | serial_port_out(port, UART_MTK_HIGHS, 0x2); | |
238 | ||
239 | /* Set to next lower baudrate supported */ | |
240 | if ((baud == 500000) || (baud == 576000)) | |
241 | baud = 460800; | |
2a768264 | 242 | quot = DIV_ROUND_UP(port->uartclk, 4 * baud); |
b4756f4f MB |
243 | } else { |
244 | serial_port_out(port, UART_MTK_HIGHS, 0x3); | |
2a768264 | 245 | quot = DIV_ROUND_UP(port->uartclk, 256 * baud); |
b4756f4f MB |
246 | } |
247 | ||
248 | /* | |
249 | * Ok, we're now changing the port state. Do it with | |
250 | * interrupts disabled. | |
251 | */ | |
252 | spin_lock_irqsave(&port->lock, flags); | |
253 | ||
254 | /* set DLAB we have cval saved in up->lcr from the call to the core */ | |
255 | serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); | |
256 | serial_dl_write(up, quot); | |
257 | ||
258 | /* reset DLAB */ | |
259 | serial_port_out(port, UART_LCR, up->lcr); | |
260 | ||
261 | if (baud > 460800) { | |
262 | unsigned int tmp; | |
263 | ||
264 | tmp = DIV_ROUND_CLOSEST(port->uartclk, quot * baud); | |
265 | serial_port_out(port, UART_MTK_SAMPLE_COUNT, tmp - 1); | |
266 | serial_port_out(port, UART_MTK_SAMPLE_POINT, | |
267 | (tmp - 2) >> 1); | |
268 | } else { | |
269 | serial_port_out(port, UART_MTK_SAMPLE_COUNT, 0x00); | |
270 | serial_port_out(port, UART_MTK_SAMPLE_POINT, 0xff); | |
271 | } | |
272 | ||
273 | spin_unlock_irqrestore(&port->lock, flags); | |
274 | /* Don't rewrite B0 */ | |
275 | if (tty_termios_baud_rate(termios)) | |
276 | tty_termios_encode_baud_rate(termios, baud, baud); | |
277 | } | |
278 | ||
9db669f1 | 279 | static int __maybe_unused mtk8250_runtime_suspend(struct device *dev) |
68e5fc4a SH |
280 | { |
281 | struct mtk8250_data *data = dev_get_drvdata(dev); | |
282 | ||
283 | clk_disable_unprepare(data->uart_clk); | |
c1c325d7 | 284 | clk_disable_unprepare(data->bus_clk); |
68e5fc4a SH |
285 | |
286 | return 0; | |
287 | } | |
288 | ||
9db669f1 | 289 | static int __maybe_unused mtk8250_runtime_resume(struct device *dev) |
68e5fc4a SH |
290 | { |
291 | struct mtk8250_data *data = dev_get_drvdata(dev); | |
292 | int err; | |
293 | ||
294 | err = clk_prepare_enable(data->uart_clk); | |
295 | if (err) { | |
296 | dev_warn(dev, "Can't enable clock\n"); | |
297 | return err; | |
298 | } | |
299 | ||
c1c325d7 SH |
300 | err = clk_prepare_enable(data->bus_clk); |
301 | if (err) { | |
302 | dev_warn(dev, "Can't enable bus clock\n"); | |
303 | return err; | |
304 | } | |
305 | ||
68e5fc4a SH |
306 | return 0; |
307 | } | |
308 | ||
b4756f4f MB |
309 | static void |
310 | mtk8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old) | |
311 | { | |
312 | if (!state) | |
313 | pm_runtime_get_sync(port->dev); | |
314 | ||
315 | serial8250_do_pm(port, state, old); | |
316 | ||
317 | if (state) | |
318 | pm_runtime_put_sync_suspend(port->dev); | |
319 | } | |
320 | ||
85b5c1dd LC |
321 | #ifdef CONFIG_SERIAL_8250_DMA |
322 | static bool mtk8250_dma_filter(struct dma_chan *chan, void *param) | |
323 | { | |
324 | return false; | |
325 | } | |
326 | #endif | |
327 | ||
b4756f4f MB |
328 | static int mtk8250_probe_of(struct platform_device *pdev, struct uart_port *p, |
329 | struct mtk8250_data *data) | |
330 | { | |
85b5c1dd LC |
331 | #ifdef CONFIG_SERIAL_8250_DMA |
332 | int dmacnt; | |
333 | #endif | |
334 | ||
c1c325d7 | 335 | data->uart_clk = devm_clk_get(&pdev->dev, "baud"); |
b4756f4f | 336 | if (IS_ERR(data->uart_clk)) { |
c1c325d7 SH |
337 | /* |
338 | * For compatibility with older device trees try unnamed | |
339 | * clk when no baud clk can be found. | |
340 | */ | |
341 | data->uart_clk = devm_clk_get(&pdev->dev, NULL); | |
342 | if (IS_ERR(data->uart_clk)) { | |
343 | dev_warn(&pdev->dev, "Can't get uart clock\n"); | |
344 | return PTR_ERR(data->uart_clk); | |
345 | } | |
346 | ||
347 | return 0; | |
b4756f4f MB |
348 | } |
349 | ||
c1c325d7 | 350 | data->bus_clk = devm_clk_get(&pdev->dev, "bus"); |
85b5c1dd LC |
351 | if (IS_ERR(data->bus_clk)) |
352 | return PTR_ERR(data->bus_clk); | |
353 | ||
354 | data->dma = NULL; | |
355 | #ifdef CONFIG_SERIAL_8250_DMA | |
356 | dmacnt = of_property_count_strings(pdev->dev.of_node, "dma-names"); | |
357 | if (dmacnt == 2) { | |
358 | data->dma = devm_kzalloc(&pdev->dev, sizeof(*data->dma), | |
359 | GFP_KERNEL); | |
1575c083 GS |
360 | if (!data->dma) |
361 | return -ENOMEM; | |
362 | ||
85b5c1dd LC |
363 | data->dma->fn = mtk8250_dma_filter; |
364 | data->dma->rx_size = MTK_UART_RX_SIZE; | |
365 | data->dma->rxconf.src_maxburst = MTK_UART_RX_TRIGGER; | |
366 | data->dma->txconf.dst_maxburst = MTK_UART_TX_TRIGGER; | |
367 | } | |
368 | #endif | |
369 | ||
370 | return 0; | |
b4756f4f MB |
371 | } |
372 | ||
373 | static int mtk8250_probe(struct platform_device *pdev) | |
374 | { | |
375 | struct uart_8250_port uart = {}; | |
376 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
377 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | |
378 | struct mtk8250_data *data; | |
379 | int err; | |
380 | ||
381 | if (!regs || !irq) { | |
382 | dev_err(&pdev->dev, "no registers/irq defined\n"); | |
383 | return -EINVAL; | |
384 | } | |
385 | ||
386 | uart.port.membase = devm_ioremap(&pdev->dev, regs->start, | |
387 | resource_size(regs)); | |
388 | if (!uart.port.membase) | |
389 | return -ENOMEM; | |
390 | ||
391 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | |
392 | if (!data) | |
393 | return -ENOMEM; | |
394 | ||
395 | if (pdev->dev.of_node) { | |
396 | err = mtk8250_probe_of(pdev, &uart.port, data); | |
397 | if (err) | |
398 | return err; | |
399 | } else | |
400 | return -ENODEV; | |
401 | ||
402 | spin_lock_init(&uart.port.lock); | |
403 | uart.port.mapbase = regs->start; | |
404 | uart.port.irq = irq->start; | |
405 | uart.port.pm = mtk8250_do_pm; | |
406 | uart.port.type = PORT_16550; | |
407 | uart.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; | |
408 | uart.port.dev = &pdev->dev; | |
409 | uart.port.iotype = UPIO_MEM32; | |
410 | uart.port.regshift = 2; | |
411 | uart.port.private_data = data; | |
85b5c1dd LC |
412 | uart.port.shutdown = mtk8250_shutdown; |
413 | uart.port.startup = mtk8250_startup; | |
b4756f4f | 414 | uart.port.set_termios = mtk8250_set_termios; |
c1c325d7 | 415 | uart.port.uartclk = clk_get_rate(data->uart_clk); |
85b5c1dd LC |
416 | #ifdef CONFIG_SERIAL_8250_DMA |
417 | if (data->dma) | |
418 | uart.dma = data->dma; | |
419 | #endif | |
b4756f4f MB |
420 | |
421 | /* Disable Rate Fix function */ | |
422 | writel(0x0, uart.port.membase + | |
423 | (MTK_UART_RATE_FIX << uart.port.regshift)); | |
424 | ||
b4756f4f MB |
425 | platform_set_drvdata(pdev, data); |
426 | ||
100bc3e2 PS |
427 | err = mtk8250_runtime_resume(&pdev->dev); |
428 | if (err) | |
429 | return err; | |
68e5fc4a SH |
430 | |
431 | data->line = serial8250_register_8250_port(&uart); | |
432 | if (data->line < 0) | |
433 | return data->line; | |
b4756f4f | 434 | |
100bc3e2 PS |
435 | pm_runtime_set_active(&pdev->dev); |
436 | pm_runtime_enable(&pdev->dev); | |
437 | ||
b4756f4f MB |
438 | return 0; |
439 | } | |
440 | ||
88725e91 AB |
441 | static int mtk8250_remove(struct platform_device *pdev) |
442 | { | |
443 | struct mtk8250_data *data = platform_get_drvdata(pdev); | |
444 | ||
445 | pm_runtime_get_sync(&pdev->dev); | |
446 | ||
447 | serial8250_unregister_port(data->line); | |
100bc3e2 | 448 | mtk8250_runtime_suspend(&pdev->dev); |
88725e91 AB |
449 | |
450 | pm_runtime_disable(&pdev->dev); | |
451 | pm_runtime_put_noidle(&pdev->dev); | |
452 | ||
88725e91 AB |
453 | return 0; |
454 | } | |
455 | ||
9db669f1 | 456 | static int __maybe_unused mtk8250_suspend(struct device *dev) |
b4756f4f MB |
457 | { |
458 | struct mtk8250_data *data = dev_get_drvdata(dev); | |
459 | ||
460 | serial8250_suspend_port(data->line); | |
461 | ||
462 | return 0; | |
463 | } | |
464 | ||
9db669f1 | 465 | static int __maybe_unused mtk8250_resume(struct device *dev) |
b4756f4f MB |
466 | { |
467 | struct mtk8250_data *data = dev_get_drvdata(dev); | |
468 | ||
469 | serial8250_resume_port(data->line); | |
470 | ||
471 | return 0; | |
472 | } | |
b4756f4f | 473 | |
b4756f4f MB |
474 | static const struct dev_pm_ops mtk8250_pm_ops = { |
475 | SET_SYSTEM_SLEEP_PM_OPS(mtk8250_suspend, mtk8250_resume) | |
476 | SET_RUNTIME_PM_OPS(mtk8250_runtime_suspend, mtk8250_runtime_resume, | |
477 | NULL) | |
478 | }; | |
479 | ||
480 | static const struct of_device_id mtk8250_of_match[] = { | |
481 | { .compatible = "mediatek,mt6577-uart" }, | |
482 | { /* Sentinel */ } | |
483 | }; | |
88725e91 | 484 | MODULE_DEVICE_TABLE(of, mtk8250_of_match); |
b4756f4f MB |
485 | |
486 | static struct platform_driver mtk8250_platform_driver = { | |
487 | .driver = { | |
88725e91 AB |
488 | .name = "mt6577-uart", |
489 | .pm = &mtk8250_pm_ops, | |
490 | .of_match_table = mtk8250_of_match, | |
b4756f4f MB |
491 | }, |
492 | .probe = mtk8250_probe, | |
88725e91 | 493 | .remove = mtk8250_remove, |
b4756f4f | 494 | }; |
88725e91 | 495 | module_platform_driver(mtk8250_platform_driver); |
b4756f4f | 496 | |
ae73975f | 497 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
2c40b57d EH |
498 | static int __init early_mtk8250_setup(struct earlycon_device *device, |
499 | const char *options) | |
500 | { | |
501 | if (!device->port.membase) | |
502 | return -ENODEV; | |
503 | ||
504 | device->port.iotype = UPIO_MEM32; | |
505 | ||
506 | return early_serial8250_setup(device, NULL); | |
507 | } | |
508 | ||
509 | OF_EARLYCON_DECLARE(mtk8250, "mediatek,mt6577-uart", early_mtk8250_setup); | |
7798edee | 510 | #endif |
88725e91 AB |
511 | |
512 | MODULE_AUTHOR("Matthias Brugger"); | |
513 | MODULE_LICENSE("GPL"); | |
514 | MODULE_DESCRIPTION("Mediatek 8250 serial port driver"); |