1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // Copyright (c) 2017-2018, The Linux foundation. All rights reserved. |
3 | |
4 | /* Disable MMIO tracing to prevent excessive logging of unwanted MMIO traces */ |
5 | #define __DISABLE_TRACE_MMIO__ |
6 | |
7 | #include <linux/clk.h> |
8 | #include <linux/console.h> |
9 | #include <linux/io.h> |
10 | #include <linux/iopoll.h> |
11 | #include <linux/irq.h> |
12 | #include <linux/module.h> |
13 | #include <linux/of.h> |
14 | #include <linux/pm_opp.h> |
15 | #include <linux/platform_device.h> |
16 | #include <linux/pm_runtime.h> |
17 | #include <linux/pm_wakeirq.h> |
18 | #include <linux/soc/qcom/geni-se.h> |
19 | #include <linux/serial.h> |
20 | #include <linux/serial_core.h> |
21 | #include <linux/slab.h> |
22 | #include <linux/tty.h> |
23 | #include <linux/tty_flip.h> |
24 | #include <dt-bindings/interconnect/qcom,icc.h> |
25 | |
26 | /* UART specific GENI registers */ |
27 | #define SE_UART_LOOPBACK_CFG 0x22c |
28 | #define SE_UART_IO_MACRO_CTRL 0x240 |
29 | #define SE_UART_TX_TRANS_CFG 0x25c |
30 | #define SE_UART_TX_WORD_LEN 0x268 |
31 | #define SE_UART_TX_STOP_BIT_LEN 0x26c |
32 | #define SE_UART_TX_TRANS_LEN 0x270 |
33 | #define SE_UART_RX_TRANS_CFG 0x280 |
34 | #define SE_UART_RX_WORD_LEN 0x28c |
35 | #define SE_UART_RX_STALE_CNT 0x294 |
36 | #define SE_UART_TX_PARITY_CFG 0x2a4 |
37 | #define SE_UART_RX_PARITY_CFG 0x2a8 |
38 | #define SE_UART_MANUAL_RFR 0x2ac |
39 | |
40 | /* SE_UART_TRANS_CFG */ |
41 | #define UART_TX_PAR_EN BIT(0) |
42 | #define UART_CTS_MASK BIT(1) |
43 | |
44 | /* SE_UART_TX_STOP_BIT_LEN */ |
45 | #define TX_STOP_BIT_LEN_1 0 |
46 | #define TX_STOP_BIT_LEN_2 2 |
47 | |
48 | /* SE_UART_RX_TRANS_CFG */ |
49 | #define UART_RX_PAR_EN BIT(3) |
50 | |
51 | /* SE_UART_RX_WORD_LEN */ |
52 | #define RX_WORD_LEN_MASK GENMASK(9, 0) |
53 | |
54 | /* SE_UART_RX_STALE_CNT */ |
55 | #define RX_STALE_CNT GENMASK(23, 0) |
56 | |
57 | /* SE_UART_TX_PARITY_CFG/RX_PARITY_CFG */ |
58 | #define PAR_CALC_EN BIT(0) |
59 | #define PAR_EVEN 0x00 |
60 | #define PAR_ODD 0x01 |
61 | #define PAR_SPACE 0x10 |
62 | |
63 | /* SE_UART_MANUAL_RFR register fields */ |
64 | #define UART_MANUAL_RFR_EN BIT(31) |
65 | #define UART_RFR_NOT_READY BIT(1) |
66 | #define UART_RFR_READY BIT(0) |
67 | |
68 | /* UART M_CMD OP codes */ |
69 | #define UART_START_TX 0x1 |
70 | /* UART S_CMD OP codes */ |
71 | #define UART_START_READ 0x1 |
72 | #define UART_PARAM 0x1 |
73 | #define UART_PARAM_RFR_OPEN BIT(7) |
74 | |
75 | #define UART_OVERSAMPLING 32 |
76 | #define STALE_TIMEOUT 16 |
77 | #define DEFAULT_BITS_PER_CHAR 10 |
78 | #define GENI_UART_CONS_PORTS 1 |
79 | #define GENI_UART_PORTS 3 |
80 | #define DEF_FIFO_DEPTH_WORDS 16 |
81 | #define DEF_TX_WM 2 |
82 | #define DEF_FIFO_WIDTH_BITS 32 |
83 | #define UART_RX_WM 2 |
84 | |
85 | /* SE_UART_LOOPBACK_CFG */ |
86 | #define RX_TX_SORTED BIT(0) |
87 | #define CTS_RTS_SORTED BIT(1) |
88 | #define RX_TX_CTS_RTS_SORTED (RX_TX_SORTED | CTS_RTS_SORTED) |
89 | |
90 | /* UART pin swap value */ |
91 | #define DEFAULT_IO_MACRO_IO0_IO1_MASK GENMASK(3, 0) |
92 | #define IO_MACRO_IO0_SEL 0x3 |
93 | #define DEFAULT_IO_MACRO_IO2_IO3_MASK GENMASK(15, 4) |
94 | #define IO_MACRO_IO2_IO3_SWAP 0x4640 |
95 | |
96 | /* We always configure 4 bytes per FIFO word */ |
97 | #define BYTES_PER_FIFO_WORD 4U |
98 | |
99 | #define DMA_RX_BUF_SIZE 2048 |
100 | |
101 | struct qcom_geni_device_data { |
102 | bool console; |
103 | enum geni_se_xfer_mode mode; |
104 | }; |
105 | |
106 | struct qcom_geni_private_data { |
107 | /* NOTE: earlycon port will have NULL here */ |
108 | struct uart_driver *drv; |
109 | |
110 | u32 poll_cached_bytes; |
111 | unsigned int poll_cached_bytes_cnt; |
112 | |
113 | u32 write_cached_bytes; |
114 | unsigned int write_cached_bytes_cnt; |
115 | }; |
116 | |
117 | struct qcom_geni_serial_port { |
118 | struct uart_port uport; |
119 | struct geni_se se; |
120 | const char *name; |
121 | u32 tx_fifo_depth; |
122 | u32 tx_fifo_width; |
123 | u32 rx_fifo_depth; |
124 | dma_addr_t tx_dma_addr; |
125 | dma_addr_t rx_dma_addr; |
126 | bool setup; |
127 | unsigned int baud; |
128 | unsigned long clk_rate; |
129 | void *rx_buf; |
130 | u32 loopback; |
131 | bool brk; |
132 | |
133 | unsigned int tx_remaining; |
134 | int wakeup_irq; |
135 | bool rx_tx_swap; |
136 | bool cts_rts_swap; |
137 | |
138 | struct qcom_geni_private_data private_data; |
139 | const struct qcom_geni_device_data *dev_data; |
140 | }; |
141 | |
142 | static const struct uart_ops qcom_geni_console_pops; |
143 | static const struct uart_ops qcom_geni_uart_pops; |
144 | static struct uart_driver qcom_geni_console_driver; |
145 | static struct uart_driver qcom_geni_uart_driver; |
146 | |
147 | static inline struct qcom_geni_serial_port *to_dev_port(struct uart_port *uport) |
148 | { |
149 | return container_of(uport, struct qcom_geni_serial_port, uport); |
150 | } |
151 | |
152 | static struct qcom_geni_serial_port qcom_geni_uart_ports[GENI_UART_PORTS] = { |
153 | [0] = { |
154 | .uport = { |
155 | .iotype = UPIO_MEM, |
156 | .ops = &qcom_geni_uart_pops, |
157 | .flags = UPF_BOOT_AUTOCONF, |
158 | .line = 0, |
159 | }, |
160 | }, |
161 | [1] = { |
162 | .uport = { |
163 | .iotype = UPIO_MEM, |
164 | .ops = &qcom_geni_uart_pops, |
165 | .flags = UPF_BOOT_AUTOCONF, |
166 | .line = 1, |
167 | }, |
168 | }, |
169 | [2] = { |
170 | .uport = { |
171 | .iotype = UPIO_MEM, |
172 | .ops = &qcom_geni_uart_pops, |
173 | .flags = UPF_BOOT_AUTOCONF, |
174 | .line = 2, |
175 | }, |
176 | }, |
177 | }; |
178 | |
179 | static struct qcom_geni_serial_port qcom_geni_console_port = { |
180 | .uport = { |
181 | .iotype = UPIO_MEM, |
182 | .ops = &qcom_geni_console_pops, |
183 | .flags = UPF_BOOT_AUTOCONF, |
184 | .line = 0, |
185 | }, |
186 | }; |
187 | |
188 | static int qcom_geni_serial_request_port(struct uart_port *uport) |
189 | { |
190 | struct platform_device *pdev = to_platform_device(uport->dev); |
191 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
192 | |
193 | uport->membase = devm_platform_ioremap_resource(pdev, index: 0); |
194 | if (IS_ERR(ptr: uport->membase)) |
195 | return PTR_ERR(ptr: uport->membase); |
196 | port->se.base = uport->membase; |
197 | return 0; |
198 | } |
199 | |
200 | static void qcom_geni_serial_config_port(struct uart_port *uport, int cfg_flags) |
201 | { |
202 | if (cfg_flags & UART_CONFIG_TYPE) { |
203 | uport->type = PORT_MSM; |
204 | qcom_geni_serial_request_port(uport); |
205 | } |
206 | } |
207 | |
208 | static unsigned int qcom_geni_serial_get_mctrl(struct uart_port *uport) |
209 | { |
210 | unsigned int mctrl = TIOCM_DSR | TIOCM_CAR; |
211 | u32 geni_ios; |
212 | |
213 | if (uart_console(uport)) { |
214 | mctrl |= TIOCM_CTS; |
215 | } else { |
216 | geni_ios = readl(addr: uport->membase + SE_GENI_IOS); |
217 | if (!(geni_ios & IO2_DATA_IN)) |
218 | mctrl |= TIOCM_CTS; |
219 | } |
220 | |
221 | return mctrl; |
222 | } |
223 | |
224 | static void qcom_geni_serial_set_mctrl(struct uart_port *uport, |
225 | unsigned int mctrl) |
226 | { |
227 | u32 uart_manual_rfr = 0; |
228 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
229 | |
230 | if (uart_console(uport)) |
231 | return; |
232 | |
233 | if (mctrl & TIOCM_LOOP) |
234 | port->loopback = RX_TX_CTS_RTS_SORTED; |
235 | |
236 | if (!(mctrl & TIOCM_RTS) && !uport->suspended) |
237 | uart_manual_rfr = UART_MANUAL_RFR_EN | UART_RFR_NOT_READY; |
238 | writel(val: uart_manual_rfr, addr: uport->membase + SE_UART_MANUAL_RFR); |
239 | } |
240 | |
241 | static const char *qcom_geni_serial_get_type(struct uart_port *uport) |
242 | { |
243 | return "MSM" ; |
244 | } |
245 | |
246 | static struct qcom_geni_serial_port *get_port_from_line(int line, bool console) |
247 | { |
248 | struct qcom_geni_serial_port *port; |
249 | int nr_ports = console ? GENI_UART_CONS_PORTS : GENI_UART_PORTS; |
250 | |
251 | if (line < 0 || line >= nr_ports) |
252 | return ERR_PTR(error: -ENXIO); |
253 | |
254 | port = console ? &qcom_geni_console_port : &qcom_geni_uart_ports[line]; |
255 | return port; |
256 | } |
257 | |
258 | static bool qcom_geni_serial_main_active(struct uart_port *uport) |
259 | { |
260 | return readl(addr: uport->membase + SE_GENI_STATUS) & M_GENI_CMD_ACTIVE; |
261 | } |
262 | |
263 | static bool qcom_geni_serial_secondary_active(struct uart_port *uport) |
264 | { |
265 | return readl(addr: uport->membase + SE_GENI_STATUS) & S_GENI_CMD_ACTIVE; |
266 | } |
267 | |
268 | static bool qcom_geni_serial_poll_bit(struct uart_port *uport, |
269 | int offset, int field, bool set) |
270 | { |
271 | u32 reg; |
272 | struct qcom_geni_serial_port *port; |
273 | unsigned int baud; |
274 | unsigned int fifo_bits; |
275 | unsigned long timeout_us = 20000; |
276 | struct qcom_geni_private_data *private_data = uport->private_data; |
277 | |
278 | if (private_data->drv) { |
279 | port = to_dev_port(uport); |
280 | baud = port->baud; |
281 | if (!baud) |
282 | baud = 115200; |
283 | fifo_bits = port->tx_fifo_depth * port->tx_fifo_width; |
284 | /* |
285 | * Total polling iterations based on FIFO worth of bytes to be |
286 | * sent at current baud. Add a little fluff to the wait. |
287 | */ |
288 | timeout_us = ((fifo_bits * USEC_PER_SEC) / baud) + 500; |
289 | } |
290 | |
291 | /* |
292 | * Use custom implementation instead of readl_poll_atomic since ktimer |
293 | * is not ready at the time of early console. |
294 | */ |
295 | timeout_us = DIV_ROUND_UP(timeout_us, 10) * 10; |
296 | while (timeout_us) { |
297 | reg = readl(addr: uport->membase + offset); |
298 | if ((bool)(reg & field) == set) |
299 | return true; |
300 | udelay(10); |
301 | timeout_us -= 10; |
302 | } |
303 | return false; |
304 | } |
305 | |
306 | static void qcom_geni_serial_setup_tx(struct uart_port *uport, u32 xmit_size) |
307 | { |
308 | u32 m_cmd; |
309 | |
310 | writel(val: xmit_size, addr: uport->membase + SE_UART_TX_TRANS_LEN); |
311 | m_cmd = UART_START_TX << M_OPCODE_SHFT; |
312 | writel(val: m_cmd, addr: uport->membase + SE_GENI_M_CMD0); |
313 | } |
314 | |
315 | static void qcom_geni_serial_poll_tx_done(struct uart_port *uport) |
316 | { |
317 | int done; |
318 | u32 irq_clear = M_CMD_DONE_EN; |
319 | |
320 | done = qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, |
321 | M_CMD_DONE_EN, set: true); |
322 | if (!done) { |
323 | writel(M_GENI_CMD_ABORT, addr: uport->membase + |
324 | SE_GENI_M_CMD_CTRL_REG); |
325 | irq_clear |= M_CMD_ABORT_EN; |
326 | qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, |
327 | M_CMD_ABORT_EN, set: true); |
328 | } |
329 | writel(val: irq_clear, addr: uport->membase + SE_GENI_M_IRQ_CLEAR); |
330 | } |
331 | |
332 | static void qcom_geni_serial_abort_rx(struct uart_port *uport) |
333 | { |
334 | u32 irq_clear = S_CMD_DONE_EN | S_CMD_ABORT_EN; |
335 | |
336 | writel(S_GENI_CMD_ABORT, addr: uport->membase + SE_GENI_S_CMD_CTRL_REG); |
337 | qcom_geni_serial_poll_bit(uport, SE_GENI_S_CMD_CTRL_REG, |
338 | S_GENI_CMD_ABORT, set: false); |
339 | writel(val: irq_clear, addr: uport->membase + SE_GENI_S_IRQ_CLEAR); |
340 | writel(FORCE_DEFAULT, addr: uport->membase + GENI_FORCE_DEFAULT_REG); |
341 | } |
342 | |
343 | #ifdef CONFIG_CONSOLE_POLL |
344 | static int qcom_geni_serial_get_char(struct uart_port *uport) |
345 | { |
346 | struct qcom_geni_private_data *private_data = uport->private_data; |
347 | u32 status; |
348 | u32 word_cnt; |
349 | int ret; |
350 | |
351 | if (!private_data->poll_cached_bytes_cnt) { |
352 | status = readl(addr: uport->membase + SE_GENI_M_IRQ_STATUS); |
353 | writel(val: status, addr: uport->membase + SE_GENI_M_IRQ_CLEAR); |
354 | |
355 | status = readl(addr: uport->membase + SE_GENI_S_IRQ_STATUS); |
356 | writel(val: status, addr: uport->membase + SE_GENI_S_IRQ_CLEAR); |
357 | |
358 | status = readl(addr: uport->membase + SE_GENI_RX_FIFO_STATUS); |
359 | word_cnt = status & RX_FIFO_WC_MSK; |
360 | if (!word_cnt) |
361 | return NO_POLL_CHAR; |
362 | |
363 | if (word_cnt == 1 && (status & RX_LAST)) |
364 | /* |
365 | * NOTE: If RX_LAST_BYTE_VALID is 0 it needs to be |
366 | * treated as if it was BYTES_PER_FIFO_WORD. |
367 | */ |
368 | private_data->poll_cached_bytes_cnt = |
369 | (status & RX_LAST_BYTE_VALID_MSK) >> |
370 | RX_LAST_BYTE_VALID_SHFT; |
371 | |
372 | if (private_data->poll_cached_bytes_cnt == 0) |
373 | private_data->poll_cached_bytes_cnt = BYTES_PER_FIFO_WORD; |
374 | |
375 | private_data->poll_cached_bytes = |
376 | readl(addr: uport->membase + SE_GENI_RX_FIFOn); |
377 | } |
378 | |
379 | private_data->poll_cached_bytes_cnt--; |
380 | ret = private_data->poll_cached_bytes & 0xff; |
381 | private_data->poll_cached_bytes >>= 8; |
382 | |
383 | return ret; |
384 | } |
385 | |
386 | static void qcom_geni_serial_poll_put_char(struct uart_port *uport, |
387 | unsigned char c) |
388 | { |
389 | writel(DEF_TX_WM, addr: uport->membase + SE_GENI_TX_WATERMARK_REG); |
390 | qcom_geni_serial_setup_tx(uport, xmit_size: 1); |
391 | WARN_ON(!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, |
392 | M_TX_FIFO_WATERMARK_EN, true)); |
393 | writel(val: c, addr: uport->membase + SE_GENI_TX_FIFOn); |
394 | writel(M_TX_FIFO_WATERMARK_EN, addr: uport->membase + SE_GENI_M_IRQ_CLEAR); |
395 | qcom_geni_serial_poll_tx_done(uport); |
396 | } |
397 | #endif |
398 | |
399 | #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE |
400 | static void qcom_geni_serial_wr_char(struct uart_port *uport, unsigned char ch) |
401 | { |
402 | struct qcom_geni_private_data *private_data = uport->private_data; |
403 | |
404 | private_data->write_cached_bytes = |
405 | (private_data->write_cached_bytes >> 8) | (ch << 24); |
406 | private_data->write_cached_bytes_cnt++; |
407 | |
408 | if (private_data->write_cached_bytes_cnt == BYTES_PER_FIFO_WORD) { |
409 | writel(val: private_data->write_cached_bytes, |
410 | addr: uport->membase + SE_GENI_TX_FIFOn); |
411 | private_data->write_cached_bytes_cnt = 0; |
412 | } |
413 | } |
414 | |
415 | static void |
416 | __qcom_geni_serial_console_write(struct uart_port *uport, const char *s, |
417 | unsigned int count) |
418 | { |
419 | struct qcom_geni_private_data *private_data = uport->private_data; |
420 | |
421 | int i; |
422 | u32 bytes_to_send = count; |
423 | |
424 | for (i = 0; i < count; i++) { |
425 | /* |
426 | * uart_console_write() adds a carriage return for each newline. |
427 | * Account for additional bytes to be written. |
428 | */ |
429 | if (s[i] == '\n') |
430 | bytes_to_send++; |
431 | } |
432 | |
433 | writel(DEF_TX_WM, addr: uport->membase + SE_GENI_TX_WATERMARK_REG); |
434 | qcom_geni_serial_setup_tx(uport, xmit_size: bytes_to_send); |
435 | for (i = 0; i < count; ) { |
436 | size_t chars_to_write = 0; |
437 | size_t avail = DEF_FIFO_DEPTH_WORDS - DEF_TX_WM; |
438 | |
439 | /* |
440 | * If the WM bit never set, then the Tx state machine is not |
441 | * in a valid state, so break, cancel/abort any existing |
442 | * command. Unfortunately the current data being written is |
443 | * lost. |
444 | */ |
445 | if (!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, |
446 | M_TX_FIFO_WATERMARK_EN, set: true)) |
447 | break; |
448 | chars_to_write = min_t(size_t, count - i, avail / 2); |
449 | uart_console_write(port: uport, s: s + i, count: chars_to_write, |
450 | putchar: qcom_geni_serial_wr_char); |
451 | writel(M_TX_FIFO_WATERMARK_EN, addr: uport->membase + |
452 | SE_GENI_M_IRQ_CLEAR); |
453 | i += chars_to_write; |
454 | } |
455 | |
456 | if (private_data->write_cached_bytes_cnt) { |
457 | private_data->write_cached_bytes >>= BITS_PER_BYTE * |
458 | (BYTES_PER_FIFO_WORD - private_data->write_cached_bytes_cnt); |
459 | writel(val: private_data->write_cached_bytes, |
460 | addr: uport->membase + SE_GENI_TX_FIFOn); |
461 | private_data->write_cached_bytes_cnt = 0; |
462 | } |
463 | |
464 | qcom_geni_serial_poll_tx_done(uport); |
465 | } |
466 | |
467 | static void qcom_geni_serial_console_write(struct console *co, const char *s, |
468 | unsigned int count) |
469 | { |
470 | struct uart_port *uport; |
471 | struct qcom_geni_serial_port *port; |
472 | bool locked = true; |
473 | unsigned long flags; |
474 | u32 geni_status; |
475 | u32 irq_en; |
476 | |
477 | WARN_ON(co->index < 0 || co->index >= GENI_UART_CONS_PORTS); |
478 | |
479 | port = get_port_from_line(line: co->index, console: true); |
480 | if (IS_ERR(ptr: port)) |
481 | return; |
482 | |
483 | uport = &port->uport; |
484 | if (oops_in_progress) |
485 | locked = uart_port_trylock_irqsave(up: uport, flags: &flags); |
486 | else |
487 | uart_port_lock_irqsave(up: uport, flags: &flags); |
488 | |
489 | geni_status = readl(addr: uport->membase + SE_GENI_STATUS); |
490 | |
491 | /* Cancel the current write to log the fault */ |
492 | if (!locked) { |
493 | geni_se_cancel_m_cmd(se: &port->se); |
494 | if (!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, |
495 | M_CMD_CANCEL_EN, set: true)) { |
496 | geni_se_abort_m_cmd(se: &port->se); |
497 | qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, |
498 | M_CMD_ABORT_EN, set: true); |
499 | writel(M_CMD_ABORT_EN, addr: uport->membase + |
500 | SE_GENI_M_IRQ_CLEAR); |
501 | } |
502 | writel(M_CMD_CANCEL_EN, addr: uport->membase + SE_GENI_M_IRQ_CLEAR); |
503 | } else if ((geni_status & M_GENI_CMD_ACTIVE) && !port->tx_remaining) { |
504 | /* |
505 | * It seems we can't interrupt existing transfers if all data |
506 | * has been sent, in which case we need to look for done first. |
507 | */ |
508 | qcom_geni_serial_poll_tx_done(uport); |
509 | |
510 | if (!uart_circ_empty(&uport->state->xmit)) { |
511 | irq_en = readl(addr: uport->membase + SE_GENI_M_IRQ_EN); |
512 | writel(val: irq_en | M_TX_FIFO_WATERMARK_EN, |
513 | addr: uport->membase + SE_GENI_M_IRQ_EN); |
514 | } |
515 | } |
516 | |
517 | __qcom_geni_serial_console_write(uport, s, count); |
518 | |
519 | if (port->tx_remaining) |
520 | qcom_geni_serial_setup_tx(uport, xmit_size: port->tx_remaining); |
521 | |
522 | if (locked) |
523 | uart_port_unlock_irqrestore(up: uport, flags); |
524 | } |
525 | |
526 | static void handle_rx_console(struct uart_port *uport, u32 bytes, bool drop) |
527 | { |
528 | u32 i; |
529 | unsigned char buf[sizeof(u32)]; |
530 | struct tty_port *tport; |
531 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
532 | |
533 | tport = &uport->state->port; |
534 | for (i = 0; i < bytes; ) { |
535 | int c; |
536 | int chunk = min_t(int, bytes - i, BYTES_PER_FIFO_WORD); |
537 | |
538 | ioread32_rep(port: uport->membase + SE_GENI_RX_FIFOn, buf, count: 1); |
539 | i += chunk; |
540 | if (drop) |
541 | continue; |
542 | |
543 | for (c = 0; c < chunk; c++) { |
544 | int sysrq; |
545 | |
546 | uport->icount.rx++; |
547 | if (port->brk && buf[c] == 0) { |
548 | port->brk = false; |
549 | if (uart_handle_break(port: uport)) |
550 | continue; |
551 | } |
552 | |
553 | sysrq = uart_prepare_sysrq_char(port: uport, ch: buf[c]); |
554 | |
555 | if (!sysrq) |
556 | tty_insert_flip_char(port: tport, ch: buf[c], TTY_NORMAL); |
557 | } |
558 | } |
559 | if (!drop) |
560 | tty_flip_buffer_push(port: tport); |
561 | } |
562 | #else |
563 | static void handle_rx_console(struct uart_port *uport, u32 bytes, bool drop) |
564 | { |
565 | |
566 | } |
567 | #endif /* CONFIG_SERIAL_QCOM_GENI_CONSOLE */ |
568 | |
569 | static void handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop) |
570 | { |
571 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
572 | struct tty_port *tport = &uport->state->port; |
573 | int ret; |
574 | |
575 | ret = tty_insert_flip_string(port: tport, chars: port->rx_buf, size: bytes); |
576 | if (ret != bytes) { |
577 | dev_err(uport->dev, "%s:Unable to push data ret %d_bytes %d\n" , |
578 | __func__, ret, bytes); |
579 | WARN_ON_ONCE(1); |
580 | } |
581 | uport->icount.rx += ret; |
582 | tty_flip_buffer_push(port: tport); |
583 | } |
584 | |
585 | static unsigned int qcom_geni_serial_tx_empty(struct uart_port *uport) |
586 | { |
587 | return !readl(addr: uport->membase + SE_GENI_TX_FIFO_STATUS); |
588 | } |
589 | |
590 | static void qcom_geni_serial_stop_tx_dma(struct uart_port *uport) |
591 | { |
592 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
593 | bool done; |
594 | |
595 | if (!qcom_geni_serial_main_active(uport)) |
596 | return; |
597 | |
598 | if (port->tx_dma_addr) { |
599 | geni_se_tx_dma_unprep(se: &port->se, iova: port->tx_dma_addr, |
600 | len: port->tx_remaining); |
601 | port->tx_dma_addr = 0; |
602 | port->tx_remaining = 0; |
603 | } |
604 | |
605 | geni_se_cancel_m_cmd(se: &port->se); |
606 | |
607 | done = qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, |
608 | M_CMD_CANCEL_EN, set: true); |
609 | if (!done) { |
610 | geni_se_abort_m_cmd(se: &port->se); |
611 | done = qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, |
612 | M_CMD_ABORT_EN, set: true); |
613 | if (!done) |
614 | dev_err_ratelimited(uport->dev, "M_CMD_ABORT_EN not set" ); |
615 | writel(M_CMD_ABORT_EN, addr: uport->membase + SE_GENI_M_IRQ_CLEAR); |
616 | } |
617 | |
618 | writel(M_CMD_CANCEL_EN, addr: uport->membase + SE_GENI_M_IRQ_CLEAR); |
619 | } |
620 | |
621 | static void qcom_geni_serial_start_tx_dma(struct uart_port *uport) |
622 | { |
623 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
624 | struct circ_buf *xmit = &uport->state->xmit; |
625 | unsigned int xmit_size; |
626 | int ret; |
627 | |
628 | if (port->tx_dma_addr) |
629 | return; |
630 | |
631 | if (uart_circ_empty(xmit)) |
632 | return; |
633 | |
634 | xmit_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); |
635 | |
636 | qcom_geni_serial_setup_tx(uport, xmit_size); |
637 | |
638 | ret = geni_se_tx_dma_prep(se: &port->se, buf: &xmit->buf[xmit->tail], |
639 | len: xmit_size, iova: &port->tx_dma_addr); |
640 | if (ret) { |
641 | dev_err(uport->dev, "unable to start TX SE DMA: %d\n" , ret); |
642 | qcom_geni_serial_stop_tx_dma(uport); |
643 | return; |
644 | } |
645 | |
646 | port->tx_remaining = xmit_size; |
647 | } |
648 | |
649 | static void qcom_geni_serial_start_tx_fifo(struct uart_port *uport) |
650 | { |
651 | u32 irq_en; |
652 | |
653 | if (qcom_geni_serial_main_active(uport) || |
654 | !qcom_geni_serial_tx_empty(uport)) |
655 | return; |
656 | |
657 | irq_en = readl(addr: uport->membase + SE_GENI_M_IRQ_EN); |
658 | irq_en |= M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN; |
659 | |
660 | writel(DEF_TX_WM, addr: uport->membase + SE_GENI_TX_WATERMARK_REG); |
661 | writel(val: irq_en, addr: uport->membase + SE_GENI_M_IRQ_EN); |
662 | } |
663 | |
664 | static void qcom_geni_serial_stop_tx_fifo(struct uart_port *uport) |
665 | { |
666 | u32 irq_en; |
667 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
668 | |
669 | irq_en = readl(addr: uport->membase + SE_GENI_M_IRQ_EN); |
670 | irq_en &= ~(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN); |
671 | writel(val: 0, addr: uport->membase + SE_GENI_TX_WATERMARK_REG); |
672 | writel(val: irq_en, addr: uport->membase + SE_GENI_M_IRQ_EN); |
673 | /* Possible stop tx is called multiple times. */ |
674 | if (!qcom_geni_serial_main_active(uport)) |
675 | return; |
676 | |
677 | geni_se_cancel_m_cmd(se: &port->se); |
678 | if (!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, |
679 | M_CMD_CANCEL_EN, set: true)) { |
680 | geni_se_abort_m_cmd(se: &port->se); |
681 | qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, |
682 | M_CMD_ABORT_EN, set: true); |
683 | writel(M_CMD_ABORT_EN, addr: uport->membase + SE_GENI_M_IRQ_CLEAR); |
684 | } |
685 | writel(M_CMD_CANCEL_EN, addr: uport->membase + SE_GENI_M_IRQ_CLEAR); |
686 | } |
687 | |
688 | static void qcom_geni_serial_handle_rx_fifo(struct uart_port *uport, bool drop) |
689 | { |
690 | u32 status; |
691 | u32 word_cnt; |
692 | u32 last_word_byte_cnt; |
693 | u32 last_word_partial; |
694 | u32 total_bytes; |
695 | |
696 | status = readl(addr: uport->membase + SE_GENI_RX_FIFO_STATUS); |
697 | word_cnt = status & RX_FIFO_WC_MSK; |
698 | last_word_partial = status & RX_LAST; |
699 | last_word_byte_cnt = (status & RX_LAST_BYTE_VALID_MSK) >> |
700 | RX_LAST_BYTE_VALID_SHFT; |
701 | |
702 | if (!word_cnt) |
703 | return; |
704 | total_bytes = BYTES_PER_FIFO_WORD * (word_cnt - 1); |
705 | if (last_word_partial && last_word_byte_cnt) |
706 | total_bytes += last_word_byte_cnt; |
707 | else |
708 | total_bytes += BYTES_PER_FIFO_WORD; |
709 | handle_rx_console(uport, bytes: total_bytes, drop); |
710 | } |
711 | |
712 | static void qcom_geni_serial_stop_rx_fifo(struct uart_port *uport) |
713 | { |
714 | u32 irq_en; |
715 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
716 | u32 s_irq_status; |
717 | |
718 | irq_en = readl(addr: uport->membase + SE_GENI_S_IRQ_EN); |
719 | irq_en &= ~(S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN); |
720 | writel(val: irq_en, addr: uport->membase + SE_GENI_S_IRQ_EN); |
721 | |
722 | irq_en = readl(addr: uport->membase + SE_GENI_M_IRQ_EN); |
723 | irq_en &= ~(M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN); |
724 | writel(val: irq_en, addr: uport->membase + SE_GENI_M_IRQ_EN); |
725 | |
726 | if (!qcom_geni_serial_secondary_active(uport)) |
727 | return; |
728 | |
729 | geni_se_cancel_s_cmd(se: &port->se); |
730 | qcom_geni_serial_poll_bit(uport, SE_GENI_S_IRQ_STATUS, |
731 | S_CMD_CANCEL_EN, set: true); |
732 | /* |
733 | * If timeout occurs secondary engine remains active |
734 | * and Abort sequence is executed. |
735 | */ |
736 | s_irq_status = readl(addr: uport->membase + SE_GENI_S_IRQ_STATUS); |
737 | /* Flush the Rx buffer */ |
738 | if (s_irq_status & S_RX_FIFO_LAST_EN) |
739 | qcom_geni_serial_handle_rx_fifo(uport, drop: true); |
740 | writel(val: s_irq_status, addr: uport->membase + SE_GENI_S_IRQ_CLEAR); |
741 | |
742 | if (qcom_geni_serial_secondary_active(uport)) |
743 | qcom_geni_serial_abort_rx(uport); |
744 | } |
745 | |
746 | static void qcom_geni_serial_start_rx_fifo(struct uart_port *uport) |
747 | { |
748 | u32 irq_en; |
749 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
750 | |
751 | if (qcom_geni_serial_secondary_active(uport)) |
752 | qcom_geni_serial_stop_rx_fifo(uport); |
753 | |
754 | geni_se_setup_s_cmd(se: &port->se, UART_START_READ, params: 0); |
755 | |
756 | irq_en = readl(addr: uport->membase + SE_GENI_S_IRQ_EN); |
757 | irq_en |= S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN; |
758 | writel(val: irq_en, addr: uport->membase + SE_GENI_S_IRQ_EN); |
759 | |
760 | irq_en = readl(addr: uport->membase + SE_GENI_M_IRQ_EN); |
761 | irq_en |= M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN; |
762 | writel(val: irq_en, addr: uport->membase + SE_GENI_M_IRQ_EN); |
763 | } |
764 | |
765 | static void qcom_geni_serial_stop_rx_dma(struct uart_port *uport) |
766 | { |
767 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
768 | |
769 | if (!qcom_geni_serial_secondary_active(uport)) |
770 | return; |
771 | |
772 | geni_se_cancel_s_cmd(se: &port->se); |
773 | qcom_geni_serial_poll_bit(uport, SE_GENI_S_IRQ_STATUS, |
774 | S_CMD_CANCEL_EN, set: true); |
775 | |
776 | if (qcom_geni_serial_secondary_active(uport)) |
777 | qcom_geni_serial_abort_rx(uport); |
778 | |
779 | if (port->rx_dma_addr) { |
780 | geni_se_rx_dma_unprep(se: &port->se, iova: port->rx_dma_addr, |
781 | DMA_RX_BUF_SIZE); |
782 | port->rx_dma_addr = 0; |
783 | } |
784 | } |
785 | |
786 | static void qcom_geni_serial_start_rx_dma(struct uart_port *uport) |
787 | { |
788 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
789 | int ret; |
790 | |
791 | if (qcom_geni_serial_secondary_active(uport)) |
792 | qcom_geni_serial_stop_rx_dma(uport); |
793 | |
794 | geni_se_setup_s_cmd(se: &port->se, UART_START_READ, UART_PARAM_RFR_OPEN); |
795 | |
796 | ret = geni_se_rx_dma_prep(se: &port->se, buf: port->rx_buf, |
797 | DMA_RX_BUF_SIZE, |
798 | iova: &port->rx_dma_addr); |
799 | if (ret) { |
800 | dev_err(uport->dev, "unable to start RX SE DMA: %d\n" , ret); |
801 | qcom_geni_serial_stop_rx_dma(uport); |
802 | } |
803 | } |
804 | |
805 | static void qcom_geni_serial_handle_rx_dma(struct uart_port *uport, bool drop) |
806 | { |
807 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
808 | u32 rx_in; |
809 | int ret; |
810 | |
811 | if (!qcom_geni_serial_secondary_active(uport)) |
812 | return; |
813 | |
814 | if (!port->rx_dma_addr) |
815 | return; |
816 | |
817 | geni_se_rx_dma_unprep(se: &port->se, iova: port->rx_dma_addr, DMA_RX_BUF_SIZE); |
818 | port->rx_dma_addr = 0; |
819 | |
820 | rx_in = readl(addr: uport->membase + SE_DMA_RX_LEN_IN); |
821 | if (!rx_in) { |
822 | dev_warn(uport->dev, "serial engine reports 0 RX bytes in!\n" ); |
823 | return; |
824 | } |
825 | |
826 | if (!drop) |
827 | handle_rx_uart(uport, bytes: rx_in, drop); |
828 | |
829 | ret = geni_se_rx_dma_prep(se: &port->se, buf: port->rx_buf, |
830 | DMA_RX_BUF_SIZE, |
831 | iova: &port->rx_dma_addr); |
832 | if (ret) { |
833 | dev_err(uport->dev, "unable to start RX SE DMA: %d\n" , ret); |
834 | qcom_geni_serial_stop_rx_dma(uport); |
835 | } |
836 | } |
837 | |
838 | static void qcom_geni_serial_start_rx(struct uart_port *uport) |
839 | { |
840 | uport->ops->start_rx(uport); |
841 | } |
842 | |
843 | static void qcom_geni_serial_stop_rx(struct uart_port *uport) |
844 | { |
845 | uport->ops->stop_rx(uport); |
846 | } |
847 | |
848 | static void qcom_geni_serial_stop_tx(struct uart_port *uport) |
849 | { |
850 | uport->ops->stop_tx(uport); |
851 | } |
852 | |
853 | static void qcom_geni_serial_send_chunk_fifo(struct uart_port *uport, |
854 | unsigned int remaining) |
855 | { |
856 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
857 | struct circ_buf *xmit = &uport->state->xmit; |
858 | unsigned int tx_bytes; |
859 | u8 buf[BYTES_PER_FIFO_WORD]; |
860 | |
861 | while (remaining) { |
862 | memset(buf, 0, sizeof(buf)); |
863 | tx_bytes = min(remaining, BYTES_PER_FIFO_WORD); |
864 | |
865 | memcpy(buf, &xmit->buf[xmit->tail], tx_bytes); |
866 | uart_xmit_advance(up: uport, chars: tx_bytes); |
867 | |
868 | iowrite32_rep(port: uport->membase + SE_GENI_TX_FIFOn, buf, count: 1); |
869 | |
870 | remaining -= tx_bytes; |
871 | port->tx_remaining -= tx_bytes; |
872 | } |
873 | } |
874 | |
875 | static void qcom_geni_serial_handle_tx_fifo(struct uart_port *uport, |
876 | bool done, bool active) |
877 | { |
878 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
879 | struct circ_buf *xmit = &uport->state->xmit; |
880 | size_t avail; |
881 | size_t pending; |
882 | u32 status; |
883 | u32 irq_en; |
884 | unsigned int chunk; |
885 | |
886 | status = readl(addr: uport->membase + SE_GENI_TX_FIFO_STATUS); |
887 | |
888 | /* Complete the current tx command before taking newly added data */ |
889 | if (active) |
890 | pending = port->tx_remaining; |
891 | else |
892 | pending = uart_circ_chars_pending(xmit); |
893 | |
894 | /* All data has been transmitted and acknowledged as received */ |
895 | if (!pending && !status && done) { |
896 | qcom_geni_serial_stop_tx_fifo(uport); |
897 | goto out_write_wakeup; |
898 | } |
899 | |
900 | avail = port->tx_fifo_depth - (status & TX_FIFO_WC); |
901 | avail *= BYTES_PER_FIFO_WORD; |
902 | |
903 | chunk = min(avail, pending); |
904 | if (!chunk) |
905 | goto out_write_wakeup; |
906 | |
907 | if (!port->tx_remaining) { |
908 | qcom_geni_serial_setup_tx(uport, xmit_size: pending); |
909 | port->tx_remaining = pending; |
910 | |
911 | irq_en = readl(addr: uport->membase + SE_GENI_M_IRQ_EN); |
912 | if (!(irq_en & M_TX_FIFO_WATERMARK_EN)) |
913 | writel(val: irq_en | M_TX_FIFO_WATERMARK_EN, |
914 | addr: uport->membase + SE_GENI_M_IRQ_EN); |
915 | } |
916 | |
917 | qcom_geni_serial_send_chunk_fifo(uport, remaining: chunk); |
918 | |
919 | /* |
920 | * The tx fifo watermark is level triggered and latched. Though we had |
921 | * cleared it in qcom_geni_serial_isr it will have already reasserted |
922 | * so we must clear it again here after our writes. |
923 | */ |
924 | writel(M_TX_FIFO_WATERMARK_EN, |
925 | addr: uport->membase + SE_GENI_M_IRQ_CLEAR); |
926 | |
927 | out_write_wakeup: |
928 | if (!port->tx_remaining) { |
929 | irq_en = readl(addr: uport->membase + SE_GENI_M_IRQ_EN); |
930 | if (irq_en & M_TX_FIFO_WATERMARK_EN) |
931 | writel(val: irq_en & ~M_TX_FIFO_WATERMARK_EN, |
932 | addr: uport->membase + SE_GENI_M_IRQ_EN); |
933 | } |
934 | |
935 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
936 | uart_write_wakeup(port: uport); |
937 | } |
938 | |
939 | static void qcom_geni_serial_handle_tx_dma(struct uart_port *uport) |
940 | { |
941 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
942 | struct circ_buf *xmit = &uport->state->xmit; |
943 | |
944 | uart_xmit_advance(up: uport, chars: port->tx_remaining); |
945 | geni_se_tx_dma_unprep(se: &port->se, iova: port->tx_dma_addr, len: port->tx_remaining); |
946 | port->tx_dma_addr = 0; |
947 | port->tx_remaining = 0; |
948 | |
949 | if (!uart_circ_empty(xmit)) |
950 | qcom_geni_serial_start_tx_dma(uport); |
951 | |
952 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
953 | uart_write_wakeup(port: uport); |
954 | } |
955 | |
956 | static irqreturn_t qcom_geni_serial_isr(int isr, void *dev) |
957 | { |
958 | u32 m_irq_en; |
959 | u32 m_irq_status; |
960 | u32 s_irq_status; |
961 | u32 geni_status; |
962 | u32 dma; |
963 | u32 dma_tx_status; |
964 | u32 dma_rx_status; |
965 | struct uart_port *uport = dev; |
966 | bool drop_rx = false; |
967 | struct tty_port *tport = &uport->state->port; |
968 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
969 | |
970 | if (uport->suspended) |
971 | return IRQ_NONE; |
972 | |
973 | uart_port_lock(up: uport); |
974 | |
975 | m_irq_status = readl(addr: uport->membase + SE_GENI_M_IRQ_STATUS); |
976 | s_irq_status = readl(addr: uport->membase + SE_GENI_S_IRQ_STATUS); |
977 | dma_tx_status = readl(addr: uport->membase + SE_DMA_TX_IRQ_STAT); |
978 | dma_rx_status = readl(addr: uport->membase + SE_DMA_RX_IRQ_STAT); |
979 | geni_status = readl(addr: uport->membase + SE_GENI_STATUS); |
980 | dma = readl(addr: uport->membase + SE_GENI_DMA_MODE_EN); |
981 | m_irq_en = readl(addr: uport->membase + SE_GENI_M_IRQ_EN); |
982 | writel(val: m_irq_status, addr: uport->membase + SE_GENI_M_IRQ_CLEAR); |
983 | writel(val: s_irq_status, addr: uport->membase + SE_GENI_S_IRQ_CLEAR); |
984 | writel(val: dma_tx_status, addr: uport->membase + SE_DMA_TX_IRQ_CLR); |
985 | writel(val: dma_rx_status, addr: uport->membase + SE_DMA_RX_IRQ_CLR); |
986 | |
987 | if (WARN_ON(m_irq_status & M_ILLEGAL_CMD_EN)) |
988 | goto out_unlock; |
989 | |
990 | if (s_irq_status & S_RX_FIFO_WR_ERR_EN) { |
991 | uport->icount.overrun++; |
992 | tty_insert_flip_char(port: tport, ch: 0, TTY_OVERRUN); |
993 | } |
994 | |
995 | if (s_irq_status & (S_GP_IRQ_0_EN | S_GP_IRQ_1_EN)) { |
996 | if (s_irq_status & S_GP_IRQ_0_EN) |
997 | uport->icount.parity++; |
998 | drop_rx = true; |
999 | } else if (s_irq_status & (S_GP_IRQ_2_EN | S_GP_IRQ_3_EN)) { |
1000 | uport->icount.brk++; |
1001 | port->brk = true; |
1002 | } |
1003 | |
1004 | if (dma) { |
1005 | if (dma_tx_status & TX_DMA_DONE) |
1006 | qcom_geni_serial_handle_tx_dma(uport); |
1007 | |
1008 | if (dma_rx_status) { |
1009 | if (dma_rx_status & RX_RESET_DONE) |
1010 | goto out_unlock; |
1011 | |
1012 | if (dma_rx_status & RX_DMA_PARITY_ERR) { |
1013 | uport->icount.parity++; |
1014 | drop_rx = true; |
1015 | } |
1016 | |
1017 | if (dma_rx_status & RX_DMA_BREAK) |
1018 | uport->icount.brk++; |
1019 | |
1020 | if (dma_rx_status & (RX_DMA_DONE | RX_EOT)) |
1021 | qcom_geni_serial_handle_rx_dma(uport, drop: drop_rx); |
1022 | } |
1023 | } else { |
1024 | if (m_irq_status & m_irq_en & |
1025 | (M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN)) |
1026 | qcom_geni_serial_handle_tx_fifo(uport, |
1027 | done: m_irq_status & M_CMD_DONE_EN, |
1028 | active: geni_status & M_GENI_CMD_ACTIVE); |
1029 | |
1030 | if (s_irq_status & (S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN)) |
1031 | qcom_geni_serial_handle_rx_fifo(uport, drop: drop_rx); |
1032 | } |
1033 | |
1034 | out_unlock: |
1035 | uart_unlock_and_check_sysrq(port: uport); |
1036 | |
1037 | return IRQ_HANDLED; |
1038 | } |
1039 | |
1040 | static int setup_fifos(struct qcom_geni_serial_port *port) |
1041 | { |
1042 | struct uart_port *uport; |
1043 | u32 old_rx_fifo_depth = port->rx_fifo_depth; |
1044 | |
1045 | uport = &port->uport; |
1046 | port->tx_fifo_depth = geni_se_get_tx_fifo_depth(se: &port->se); |
1047 | port->tx_fifo_width = geni_se_get_tx_fifo_width(se: &port->se); |
1048 | port->rx_fifo_depth = geni_se_get_rx_fifo_depth(se: &port->se); |
1049 | uport->fifosize = |
1050 | (port->tx_fifo_depth * port->tx_fifo_width) / BITS_PER_BYTE; |
1051 | |
1052 | if (port->rx_buf && (old_rx_fifo_depth != port->rx_fifo_depth) && port->rx_fifo_depth) { |
1053 | /* |
1054 | * Use krealloc rather than krealloc_array because rx_buf is |
1055 | * accessed as 1 byte entries as well as 4 byte entries so it's |
1056 | * not necessarily an array. |
1057 | */ |
1058 | port->rx_buf = devm_krealloc(dev: uport->dev, ptr: port->rx_buf, |
1059 | size: port->rx_fifo_depth * sizeof(u32), |
1060 | GFP_KERNEL); |
1061 | if (!port->rx_buf) |
1062 | return -ENOMEM; |
1063 | } |
1064 | |
1065 | return 0; |
1066 | } |
1067 | |
1068 | |
1069 | static void qcom_geni_serial_shutdown(struct uart_port *uport) |
1070 | { |
1071 | disable_irq(irq: uport->irq); |
1072 | |
1073 | if (uart_console(uport)) |
1074 | return; |
1075 | |
1076 | qcom_geni_serial_stop_tx(uport); |
1077 | qcom_geni_serial_stop_rx(uport); |
1078 | } |
1079 | |
1080 | static int qcom_geni_serial_port_setup(struct uart_port *uport) |
1081 | { |
1082 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
1083 | u32 rxstale = DEFAULT_BITS_PER_CHAR * STALE_TIMEOUT; |
1084 | u32 proto; |
1085 | u32 pin_swap; |
1086 | int ret; |
1087 | |
1088 | proto = geni_se_read_proto(se: &port->se); |
1089 | if (proto != GENI_SE_UART) { |
1090 | dev_err(uport->dev, "Invalid FW loaded, proto: %d\n" , proto); |
1091 | return -ENXIO; |
1092 | } |
1093 | |
1094 | qcom_geni_serial_stop_rx(uport); |
1095 | |
1096 | ret = setup_fifos(port); |
1097 | if (ret) |
1098 | return ret; |
1099 | |
1100 | writel(val: rxstale, addr: uport->membase + SE_UART_RX_STALE_CNT); |
1101 | |
1102 | pin_swap = readl(addr: uport->membase + SE_UART_IO_MACRO_CTRL); |
1103 | if (port->rx_tx_swap) { |
1104 | pin_swap &= ~DEFAULT_IO_MACRO_IO2_IO3_MASK; |
1105 | pin_swap |= IO_MACRO_IO2_IO3_SWAP; |
1106 | } |
1107 | if (port->cts_rts_swap) { |
1108 | pin_swap &= ~DEFAULT_IO_MACRO_IO0_IO1_MASK; |
1109 | pin_swap |= IO_MACRO_IO0_SEL; |
1110 | } |
1111 | /* Configure this register if RX-TX, CTS-RTS pins are swapped */ |
1112 | if (port->rx_tx_swap || port->cts_rts_swap) |
1113 | writel(val: pin_swap, addr: uport->membase + SE_UART_IO_MACRO_CTRL); |
1114 | |
1115 | /* |
1116 | * Make an unconditional cancel on the main sequencer to reset |
1117 | * it else we could end up in data loss scenarios. |
1118 | */ |
1119 | if (uart_console(uport)) |
1120 | qcom_geni_serial_poll_tx_done(uport); |
1121 | geni_se_config_packing(se: &port->se, BITS_PER_BYTE, BYTES_PER_FIFO_WORD, |
1122 | msb_to_lsb: false, tx_cfg: true, rx_cfg: true); |
1123 | geni_se_init(se: &port->se, UART_RX_WM, rx_rfr: port->rx_fifo_depth - 2); |
1124 | geni_se_select_mode(se: &port->se, mode: port->dev_data->mode); |
1125 | qcom_geni_serial_start_rx(uport); |
1126 | port->setup = true; |
1127 | |
1128 | return 0; |
1129 | } |
1130 | |
1131 | static int qcom_geni_serial_startup(struct uart_port *uport) |
1132 | { |
1133 | int ret; |
1134 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
1135 | |
1136 | if (!port->setup) { |
1137 | ret = qcom_geni_serial_port_setup(uport); |
1138 | if (ret) |
1139 | return ret; |
1140 | } |
1141 | enable_irq(irq: uport->irq); |
1142 | |
1143 | return 0; |
1144 | } |
1145 | |
1146 | static unsigned long find_clk_rate_in_tol(struct clk *clk, unsigned int desired_clk, |
1147 | unsigned int *clk_div, unsigned int percent_tol) |
1148 | { |
1149 | unsigned long freq; |
1150 | unsigned long div, maxdiv; |
1151 | u64 mult; |
1152 | unsigned long offset, abs_tol, achieved; |
1153 | |
1154 | abs_tol = div_u64(dividend: (u64)desired_clk * percent_tol, divisor: 100); |
1155 | maxdiv = CLK_DIV_MSK >> CLK_DIV_SHFT; |
1156 | div = 1; |
1157 | while (div <= maxdiv) { |
1158 | mult = (u64)div * desired_clk; |
1159 | if (mult != (unsigned long)mult) |
1160 | break; |
1161 | |
1162 | offset = div * abs_tol; |
1163 | freq = clk_round_rate(clk, rate: mult - offset); |
1164 | |
1165 | /* Can only get lower if we're done */ |
1166 | if (freq < mult - offset) |
1167 | break; |
1168 | |
1169 | /* |
1170 | * Re-calculate div in case rounding skipped rates but we |
1171 | * ended up at a good one, then check for a match. |
1172 | */ |
1173 | div = DIV_ROUND_CLOSEST(freq, desired_clk); |
1174 | achieved = DIV_ROUND_CLOSEST(freq, div); |
1175 | if (achieved <= desired_clk + abs_tol && |
1176 | achieved >= desired_clk - abs_tol) { |
1177 | *clk_div = div; |
1178 | return freq; |
1179 | } |
1180 | |
1181 | div = DIV_ROUND_UP(freq, desired_clk); |
1182 | } |
1183 | |
1184 | return 0; |
1185 | } |
1186 | |
1187 | static unsigned long get_clk_div_rate(struct clk *clk, unsigned int baud, |
1188 | unsigned int sampling_rate, unsigned int *clk_div) |
1189 | { |
1190 | unsigned long ser_clk; |
1191 | unsigned long desired_clk; |
1192 | |
1193 | desired_clk = baud * sampling_rate; |
1194 | if (!desired_clk) |
1195 | return 0; |
1196 | |
1197 | /* |
1198 | * try to find a clock rate within 2% tolerance, then within 5% |
1199 | */ |
1200 | ser_clk = find_clk_rate_in_tol(clk, desired_clk, clk_div, percent_tol: 2); |
1201 | if (!ser_clk) |
1202 | ser_clk = find_clk_rate_in_tol(clk, desired_clk, clk_div, percent_tol: 5); |
1203 | |
1204 | return ser_clk; |
1205 | } |
1206 | |
1207 | static void qcom_geni_serial_set_termios(struct uart_port *uport, |
1208 | struct ktermios *termios, |
1209 | const struct ktermios *old) |
1210 | { |
1211 | unsigned int baud; |
1212 | u32 bits_per_char; |
1213 | u32 tx_trans_cfg; |
1214 | u32 tx_parity_cfg; |
1215 | u32 rx_trans_cfg; |
1216 | u32 rx_parity_cfg; |
1217 | u32 stop_bit_len; |
1218 | unsigned int clk_div; |
1219 | u32 ser_clk_cfg; |
1220 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
1221 | unsigned long clk_rate; |
1222 | u32 ver, sampling_rate; |
1223 | unsigned int avg_bw_core; |
1224 | |
1225 | qcom_geni_serial_stop_rx(uport); |
1226 | /* baud rate */ |
1227 | baud = uart_get_baud_rate(port: uport, termios, old, min: 300, max: 4000000); |
1228 | port->baud = baud; |
1229 | |
1230 | sampling_rate = UART_OVERSAMPLING; |
1231 | /* Sampling rate is halved for IP versions >= 2.5 */ |
1232 | ver = geni_se_get_qup_hw_version(se: &port->se); |
1233 | if (ver >= QUP_SE_VERSION_2_5) |
1234 | sampling_rate /= 2; |
1235 | |
1236 | clk_rate = get_clk_div_rate(clk: port->se.clk, baud, |
1237 | sampling_rate, clk_div: &clk_div); |
1238 | if (!clk_rate) { |
1239 | dev_err(port->se.dev, |
1240 | "Couldn't find suitable clock rate for %u\n" , |
1241 | baud * sampling_rate); |
1242 | goto out_restart_rx; |
1243 | } |
1244 | |
1245 | dev_dbg(port->se.dev, "desired_rate = %u, clk_rate = %lu, clk_div = %u\n" , |
1246 | baud * sampling_rate, clk_rate, clk_div); |
1247 | |
1248 | uport->uartclk = clk_rate; |
1249 | port->clk_rate = clk_rate; |
1250 | dev_pm_opp_set_rate(dev: uport->dev, target_freq: clk_rate); |
1251 | ser_clk_cfg = SER_CLK_EN; |
1252 | ser_clk_cfg |= clk_div << CLK_DIV_SHFT; |
1253 | |
1254 | /* |
1255 | * Bump up BW vote on CPU and CORE path as driver supports FIFO mode |
1256 | * only. |
1257 | */ |
1258 | avg_bw_core = (baud > 115200) ? Bps_to_icc(CORE_2X_50_MHZ) |
1259 | : GENI_DEFAULT_BW; |
1260 | port->se.icc_paths[GENI_TO_CORE].avg_bw = avg_bw_core; |
1261 | port->se.icc_paths[CPU_TO_GENI].avg_bw = Bps_to_icc(baud); |
1262 | geni_icc_set_bw(se: &port->se); |
1263 | |
1264 | /* parity */ |
1265 | tx_trans_cfg = readl(addr: uport->membase + SE_UART_TX_TRANS_CFG); |
1266 | tx_parity_cfg = readl(addr: uport->membase + SE_UART_TX_PARITY_CFG); |
1267 | rx_trans_cfg = readl(addr: uport->membase + SE_UART_RX_TRANS_CFG); |
1268 | rx_parity_cfg = readl(addr: uport->membase + SE_UART_RX_PARITY_CFG); |
1269 | if (termios->c_cflag & PARENB) { |
1270 | tx_trans_cfg |= UART_TX_PAR_EN; |
1271 | rx_trans_cfg |= UART_RX_PAR_EN; |
1272 | tx_parity_cfg |= PAR_CALC_EN; |
1273 | rx_parity_cfg |= PAR_CALC_EN; |
1274 | if (termios->c_cflag & PARODD) { |
1275 | tx_parity_cfg |= PAR_ODD; |
1276 | rx_parity_cfg |= PAR_ODD; |
1277 | } else if (termios->c_cflag & CMSPAR) { |
1278 | tx_parity_cfg |= PAR_SPACE; |
1279 | rx_parity_cfg |= PAR_SPACE; |
1280 | } else { |
1281 | tx_parity_cfg |= PAR_EVEN; |
1282 | rx_parity_cfg |= PAR_EVEN; |
1283 | } |
1284 | } else { |
1285 | tx_trans_cfg &= ~UART_TX_PAR_EN; |
1286 | rx_trans_cfg &= ~UART_RX_PAR_EN; |
1287 | tx_parity_cfg &= ~PAR_CALC_EN; |
1288 | rx_parity_cfg &= ~PAR_CALC_EN; |
1289 | } |
1290 | |
1291 | /* bits per char */ |
1292 | bits_per_char = tty_get_char_size(cflag: termios->c_cflag); |
1293 | |
1294 | /* stop bits */ |
1295 | if (termios->c_cflag & CSTOPB) |
1296 | stop_bit_len = TX_STOP_BIT_LEN_2; |
1297 | else |
1298 | stop_bit_len = TX_STOP_BIT_LEN_1; |
1299 | |
1300 | /* flow control, clear the CTS_MASK bit if using flow control. */ |
1301 | if (termios->c_cflag & CRTSCTS) |
1302 | tx_trans_cfg &= ~UART_CTS_MASK; |
1303 | else |
1304 | tx_trans_cfg |= UART_CTS_MASK; |
1305 | |
1306 | if (baud) |
1307 | uart_update_timeout(port: uport, cflag: termios->c_cflag, baud); |
1308 | |
1309 | if (!uart_console(uport)) |
1310 | writel(val: port->loopback, |
1311 | addr: uport->membase + SE_UART_LOOPBACK_CFG); |
1312 | writel(val: tx_trans_cfg, addr: uport->membase + SE_UART_TX_TRANS_CFG); |
1313 | writel(val: tx_parity_cfg, addr: uport->membase + SE_UART_TX_PARITY_CFG); |
1314 | writel(val: rx_trans_cfg, addr: uport->membase + SE_UART_RX_TRANS_CFG); |
1315 | writel(val: rx_parity_cfg, addr: uport->membase + SE_UART_RX_PARITY_CFG); |
1316 | writel(val: bits_per_char, addr: uport->membase + SE_UART_TX_WORD_LEN); |
1317 | writel(val: bits_per_char, addr: uport->membase + SE_UART_RX_WORD_LEN); |
1318 | writel(val: stop_bit_len, addr: uport->membase + SE_UART_TX_STOP_BIT_LEN); |
1319 | writel(val: ser_clk_cfg, addr: uport->membase + GENI_SER_M_CLK_CFG); |
1320 | writel(val: ser_clk_cfg, addr: uport->membase + GENI_SER_S_CLK_CFG); |
1321 | out_restart_rx: |
1322 | qcom_geni_serial_start_rx(uport); |
1323 | } |
1324 | |
1325 | #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE |
1326 | static int qcom_geni_console_setup(struct console *co, char *options) |
1327 | { |
1328 | struct uart_port *uport; |
1329 | struct qcom_geni_serial_port *port; |
1330 | int baud = 115200; |
1331 | int bits = 8; |
1332 | int parity = 'n'; |
1333 | int flow = 'n'; |
1334 | int ret; |
1335 | |
1336 | if (co->index >= GENI_UART_CONS_PORTS || co->index < 0) |
1337 | return -ENXIO; |
1338 | |
1339 | port = get_port_from_line(line: co->index, console: true); |
1340 | if (IS_ERR(ptr: port)) { |
1341 | pr_err("Invalid line %d\n" , co->index); |
1342 | return PTR_ERR(ptr: port); |
1343 | } |
1344 | |
1345 | uport = &port->uport; |
1346 | |
1347 | if (unlikely(!uport->membase)) |
1348 | return -ENXIO; |
1349 | |
1350 | if (!port->setup) { |
1351 | ret = qcom_geni_serial_port_setup(uport); |
1352 | if (ret) |
1353 | return ret; |
1354 | } |
1355 | |
1356 | if (options) |
1357 | uart_parse_options(options, baud: &baud, parity: &parity, bits: &bits, flow: &flow); |
1358 | |
1359 | return uart_set_options(port: uport, co, baud, parity, bits, flow); |
1360 | } |
1361 | |
1362 | static void qcom_geni_serial_earlycon_write(struct console *con, |
1363 | const char *s, unsigned int n) |
1364 | { |
1365 | struct earlycon_device *dev = con->data; |
1366 | |
1367 | __qcom_geni_serial_console_write(uport: &dev->port, s, count: n); |
1368 | } |
1369 | |
1370 | #ifdef CONFIG_CONSOLE_POLL |
1371 | static int qcom_geni_serial_earlycon_read(struct console *con, |
1372 | char *s, unsigned int n) |
1373 | { |
1374 | struct earlycon_device *dev = con->data; |
1375 | struct uart_port *uport = &dev->port; |
1376 | int num_read = 0; |
1377 | int ch; |
1378 | |
1379 | while (num_read < n) { |
1380 | ch = qcom_geni_serial_get_char(uport); |
1381 | if (ch == NO_POLL_CHAR) |
1382 | break; |
1383 | s[num_read++] = ch; |
1384 | } |
1385 | |
1386 | return num_read; |
1387 | } |
1388 | |
1389 | static void __init qcom_geni_serial_enable_early_read(struct geni_se *se, |
1390 | struct console *con) |
1391 | { |
1392 | geni_se_setup_s_cmd(se, UART_START_READ, params: 0); |
1393 | con->read = qcom_geni_serial_earlycon_read; |
1394 | } |
1395 | #else |
1396 | static inline void qcom_geni_serial_enable_early_read(struct geni_se *se, |
1397 | struct console *con) { } |
1398 | #endif |
1399 | |
1400 | static struct qcom_geni_private_data earlycon_private_data; |
1401 | |
1402 | static int __init qcom_geni_serial_earlycon_setup(struct earlycon_device *dev, |
1403 | const char *opt) |
1404 | { |
1405 | struct uart_port *uport = &dev->port; |
1406 | u32 tx_trans_cfg; |
1407 | u32 tx_parity_cfg = 0; /* Disable Tx Parity */ |
1408 | u32 rx_trans_cfg = 0; |
1409 | u32 rx_parity_cfg = 0; /* Disable Rx Parity */ |
1410 | u32 stop_bit_len = 0; /* Default stop bit length - 1 bit */ |
1411 | u32 bits_per_char; |
1412 | struct geni_se se; |
1413 | |
1414 | if (!uport->membase) |
1415 | return -EINVAL; |
1416 | |
1417 | uport->private_data = &earlycon_private_data; |
1418 | |
1419 | memset(&se, 0, sizeof(se)); |
1420 | se.base = uport->membase; |
1421 | if (geni_se_read_proto(se: &se) != GENI_SE_UART) |
1422 | return -ENXIO; |
1423 | /* |
1424 | * Ignore Flow control. |
1425 | * n = 8. |
1426 | */ |
1427 | tx_trans_cfg = UART_CTS_MASK; |
1428 | bits_per_char = BITS_PER_BYTE; |
1429 | |
1430 | /* |
1431 | * Make an unconditional cancel on the main sequencer to reset |
1432 | * it else we could end up in data loss scenarios. |
1433 | */ |
1434 | qcom_geni_serial_poll_tx_done(uport); |
1435 | qcom_geni_serial_abort_rx(uport); |
1436 | geni_se_config_packing(se: &se, BITS_PER_BYTE, BYTES_PER_FIFO_WORD, |
1437 | msb_to_lsb: false, tx_cfg: true, rx_cfg: true); |
1438 | geni_se_init(se: &se, DEF_FIFO_DEPTH_WORDS / 2, DEF_FIFO_DEPTH_WORDS - 2); |
1439 | geni_se_select_mode(se: &se, mode: GENI_SE_FIFO); |
1440 | |
1441 | writel(val: tx_trans_cfg, addr: uport->membase + SE_UART_TX_TRANS_CFG); |
1442 | writel(val: tx_parity_cfg, addr: uport->membase + SE_UART_TX_PARITY_CFG); |
1443 | writel(val: rx_trans_cfg, addr: uport->membase + SE_UART_RX_TRANS_CFG); |
1444 | writel(val: rx_parity_cfg, addr: uport->membase + SE_UART_RX_PARITY_CFG); |
1445 | writel(val: bits_per_char, addr: uport->membase + SE_UART_TX_WORD_LEN); |
1446 | writel(val: bits_per_char, addr: uport->membase + SE_UART_RX_WORD_LEN); |
1447 | writel(val: stop_bit_len, addr: uport->membase + SE_UART_TX_STOP_BIT_LEN); |
1448 | |
1449 | dev->con->write = qcom_geni_serial_earlycon_write; |
1450 | dev->con->setup = NULL; |
1451 | qcom_geni_serial_enable_early_read(se: &se, con: dev->con); |
1452 | |
1453 | return 0; |
1454 | } |
1455 | OF_EARLYCON_DECLARE(qcom_geni, "qcom,geni-debug-uart" , |
1456 | qcom_geni_serial_earlycon_setup); |
1457 | |
1458 | static int __init console_register(struct uart_driver *drv) |
1459 | { |
1460 | return uart_register_driver(uart: drv); |
1461 | } |
1462 | |
1463 | static void console_unregister(struct uart_driver *drv) |
1464 | { |
1465 | uart_unregister_driver(uart: drv); |
1466 | } |
1467 | |
1468 | static struct console cons_ops = { |
1469 | .name = "ttyMSM" , |
1470 | .write = qcom_geni_serial_console_write, |
1471 | .device = uart_console_device, |
1472 | .setup = qcom_geni_console_setup, |
1473 | .flags = CON_PRINTBUFFER, |
1474 | .index = -1, |
1475 | .data = &qcom_geni_console_driver, |
1476 | }; |
1477 | |
1478 | static struct uart_driver qcom_geni_console_driver = { |
1479 | .owner = THIS_MODULE, |
1480 | .driver_name = "qcom_geni_console" , |
1481 | .dev_name = "ttyMSM" , |
1482 | .nr = GENI_UART_CONS_PORTS, |
1483 | .cons = &cons_ops, |
1484 | }; |
1485 | #else |
1486 | static int console_register(struct uart_driver *drv) |
1487 | { |
1488 | return 0; |
1489 | } |
1490 | |
1491 | static void console_unregister(struct uart_driver *drv) |
1492 | { |
1493 | } |
1494 | #endif /* CONFIG_SERIAL_QCOM_GENI_CONSOLE */ |
1495 | |
1496 | static struct uart_driver qcom_geni_uart_driver = { |
1497 | .owner = THIS_MODULE, |
1498 | .driver_name = "qcom_geni_uart" , |
1499 | .dev_name = "ttyHS" , |
1500 | .nr = GENI_UART_PORTS, |
1501 | }; |
1502 | |
1503 | static void qcom_geni_serial_pm(struct uart_port *uport, |
1504 | unsigned int new_state, unsigned int old_state) |
1505 | { |
1506 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
1507 | |
1508 | /* If we've never been called, treat it as off */ |
1509 | if (old_state == UART_PM_STATE_UNDEFINED) |
1510 | old_state = UART_PM_STATE_OFF; |
1511 | |
1512 | if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF) { |
1513 | geni_icc_enable(se: &port->se); |
1514 | if (port->clk_rate) |
1515 | dev_pm_opp_set_rate(dev: uport->dev, target_freq: port->clk_rate); |
1516 | geni_se_resources_on(se: &port->se); |
1517 | } else if (new_state == UART_PM_STATE_OFF && |
1518 | old_state == UART_PM_STATE_ON) { |
1519 | geni_se_resources_off(se: &port->se); |
1520 | dev_pm_opp_set_rate(dev: uport->dev, target_freq: 0); |
1521 | geni_icc_disable(se: &port->se); |
1522 | } |
1523 | } |
1524 | |
1525 | static const struct uart_ops qcom_geni_console_pops = { |
1526 | .tx_empty = qcom_geni_serial_tx_empty, |
1527 | .stop_tx = qcom_geni_serial_stop_tx_fifo, |
1528 | .start_tx = qcom_geni_serial_start_tx_fifo, |
1529 | .stop_rx = qcom_geni_serial_stop_rx_fifo, |
1530 | .start_rx = qcom_geni_serial_start_rx_fifo, |
1531 | .set_termios = qcom_geni_serial_set_termios, |
1532 | .startup = qcom_geni_serial_startup, |
1533 | .request_port = qcom_geni_serial_request_port, |
1534 | .config_port = qcom_geni_serial_config_port, |
1535 | .shutdown = qcom_geni_serial_shutdown, |
1536 | .type = qcom_geni_serial_get_type, |
1537 | .set_mctrl = qcom_geni_serial_set_mctrl, |
1538 | .get_mctrl = qcom_geni_serial_get_mctrl, |
1539 | #ifdef CONFIG_CONSOLE_POLL |
1540 | .poll_get_char = qcom_geni_serial_get_char, |
1541 | .poll_put_char = qcom_geni_serial_poll_put_char, |
1542 | .poll_init = qcom_geni_serial_port_setup, |
1543 | #endif |
1544 | .pm = qcom_geni_serial_pm, |
1545 | }; |
1546 | |
1547 | static const struct uart_ops qcom_geni_uart_pops = { |
1548 | .tx_empty = qcom_geni_serial_tx_empty, |
1549 | .stop_tx = qcom_geni_serial_stop_tx_dma, |
1550 | .start_tx = qcom_geni_serial_start_tx_dma, |
1551 | .start_rx = qcom_geni_serial_start_rx_dma, |
1552 | .stop_rx = qcom_geni_serial_stop_rx_dma, |
1553 | .set_termios = qcom_geni_serial_set_termios, |
1554 | .startup = qcom_geni_serial_startup, |
1555 | .request_port = qcom_geni_serial_request_port, |
1556 | .config_port = qcom_geni_serial_config_port, |
1557 | .shutdown = qcom_geni_serial_shutdown, |
1558 | .type = qcom_geni_serial_get_type, |
1559 | .set_mctrl = qcom_geni_serial_set_mctrl, |
1560 | .get_mctrl = qcom_geni_serial_get_mctrl, |
1561 | .pm = qcom_geni_serial_pm, |
1562 | }; |
1563 | |
1564 | static int qcom_geni_serial_probe(struct platform_device *pdev) |
1565 | { |
1566 | int ret = 0; |
1567 | int line; |
1568 | struct qcom_geni_serial_port *port; |
1569 | struct uart_port *uport; |
1570 | struct resource *res; |
1571 | int irq; |
1572 | struct uart_driver *drv; |
1573 | const struct qcom_geni_device_data *data; |
1574 | |
1575 | data = of_device_get_match_data(dev: &pdev->dev); |
1576 | if (!data) |
1577 | return -EINVAL; |
1578 | |
1579 | if (data->console) { |
1580 | drv = &qcom_geni_console_driver; |
1581 | line = of_alias_get_id(np: pdev->dev.of_node, stem: "serial" ); |
1582 | } else { |
1583 | drv = &qcom_geni_uart_driver; |
1584 | line = of_alias_get_id(np: pdev->dev.of_node, stem: "serial" ); |
1585 | if (line == -ENODEV) /* compat with non-standard aliases */ |
1586 | line = of_alias_get_id(np: pdev->dev.of_node, stem: "hsuart" ); |
1587 | } |
1588 | |
1589 | port = get_port_from_line(line, console: data->console); |
1590 | if (IS_ERR(ptr: port)) { |
1591 | dev_err(&pdev->dev, "Invalid line %d\n" , line); |
1592 | return PTR_ERR(ptr: port); |
1593 | } |
1594 | |
1595 | uport = &port->uport; |
1596 | /* Don't allow 2 drivers to access the same port */ |
1597 | if (uport->private_data) |
1598 | return -ENODEV; |
1599 | |
1600 | uport->dev = &pdev->dev; |
1601 | port->dev_data = data; |
1602 | port->se.dev = &pdev->dev; |
1603 | port->se.wrapper = dev_get_drvdata(dev: pdev->dev.parent); |
1604 | port->se.clk = devm_clk_get(dev: &pdev->dev, id: "se" ); |
1605 | if (IS_ERR(ptr: port->se.clk)) { |
1606 | ret = PTR_ERR(ptr: port->se.clk); |
1607 | dev_err(&pdev->dev, "Err getting SE Core clk %d\n" , ret); |
1608 | return ret; |
1609 | } |
1610 | |
1611 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1612 | if (!res) |
1613 | return -EINVAL; |
1614 | uport->mapbase = res->start; |
1615 | |
1616 | port->tx_fifo_depth = DEF_FIFO_DEPTH_WORDS; |
1617 | port->rx_fifo_depth = DEF_FIFO_DEPTH_WORDS; |
1618 | port->tx_fifo_width = DEF_FIFO_WIDTH_BITS; |
1619 | |
1620 | if (!data->console) { |
1621 | port->rx_buf = devm_kzalloc(dev: uport->dev, |
1622 | DMA_RX_BUF_SIZE, GFP_KERNEL); |
1623 | if (!port->rx_buf) |
1624 | return -ENOMEM; |
1625 | } |
1626 | |
1627 | ret = geni_icc_get(se: &port->se, NULL); |
1628 | if (ret) |
1629 | return ret; |
1630 | port->se.icc_paths[GENI_TO_CORE].avg_bw = GENI_DEFAULT_BW; |
1631 | port->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW; |
1632 | |
1633 | /* Set BW for register access */ |
1634 | ret = geni_icc_set_bw(se: &port->se); |
1635 | if (ret) |
1636 | return ret; |
1637 | |
1638 | port->name = devm_kasprintf(dev: uport->dev, GFP_KERNEL, |
1639 | fmt: "qcom_geni_serial_%s%d" , |
1640 | uart_console(uport) ? "console" : "uart" , uport->line); |
1641 | if (!port->name) |
1642 | return -ENOMEM; |
1643 | |
1644 | irq = platform_get_irq(pdev, 0); |
1645 | if (irq < 0) |
1646 | return irq; |
1647 | uport->irq = irq; |
1648 | uport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_QCOM_GENI_CONSOLE); |
1649 | |
1650 | if (!data->console) |
1651 | port->wakeup_irq = platform_get_irq_optional(pdev, 1); |
1652 | |
1653 | if (of_property_read_bool(np: pdev->dev.of_node, propname: "rx-tx-swap" )) |
1654 | port->rx_tx_swap = true; |
1655 | |
1656 | if (of_property_read_bool(np: pdev->dev.of_node, propname: "cts-rts-swap" )) |
1657 | port->cts_rts_swap = true; |
1658 | |
1659 | ret = devm_pm_opp_set_clkname(dev: &pdev->dev, name: "se" ); |
1660 | if (ret) |
1661 | return ret; |
1662 | /* OPP table is optional */ |
1663 | ret = devm_pm_opp_of_add_table(dev: &pdev->dev); |
1664 | if (ret && ret != -ENODEV) { |
1665 | dev_err(&pdev->dev, "invalid OPP table in device tree\n" ); |
1666 | return ret; |
1667 | } |
1668 | |
1669 | port->private_data.drv = drv; |
1670 | uport->private_data = &port->private_data; |
1671 | platform_set_drvdata(pdev, data: port); |
1672 | |
1673 | irq_set_status_flags(irq: uport->irq, set: IRQ_NOAUTOEN); |
1674 | ret = devm_request_irq(dev: uport->dev, irq: uport->irq, handler: qcom_geni_serial_isr, |
1675 | IRQF_TRIGGER_HIGH, devname: port->name, dev_id: uport); |
1676 | if (ret) { |
1677 | dev_err(uport->dev, "Failed to get IRQ ret %d\n" , ret); |
1678 | return ret; |
1679 | } |
1680 | |
1681 | ret = uart_add_one_port(reg: drv, port: uport); |
1682 | if (ret) |
1683 | return ret; |
1684 | |
1685 | if (port->wakeup_irq > 0) { |
1686 | device_init_wakeup(dev: &pdev->dev, enable: true); |
1687 | ret = dev_pm_set_dedicated_wake_irq(dev: &pdev->dev, |
1688 | irq: port->wakeup_irq); |
1689 | if (ret) { |
1690 | device_init_wakeup(dev: &pdev->dev, enable: false); |
1691 | uart_remove_one_port(reg: drv, port: uport); |
1692 | return ret; |
1693 | } |
1694 | } |
1695 | |
1696 | return 0; |
1697 | } |
1698 | |
1699 | static int qcom_geni_serial_remove(struct platform_device *pdev) |
1700 | { |
1701 | struct qcom_geni_serial_port *port = platform_get_drvdata(pdev); |
1702 | struct uart_driver *drv = port->private_data.drv; |
1703 | |
1704 | dev_pm_clear_wake_irq(dev: &pdev->dev); |
1705 | device_init_wakeup(dev: &pdev->dev, enable: false); |
1706 | uart_remove_one_port(reg: drv, port: &port->uport); |
1707 | |
1708 | return 0; |
1709 | } |
1710 | |
1711 | static int qcom_geni_serial_sys_suspend(struct device *dev) |
1712 | { |
1713 | struct qcom_geni_serial_port *port = dev_get_drvdata(dev); |
1714 | struct uart_port *uport = &port->uport; |
1715 | struct qcom_geni_private_data *private_data = uport->private_data; |
1716 | |
1717 | /* |
1718 | * This is done so we can hit the lowest possible state in suspend |
1719 | * even with no_console_suspend |
1720 | */ |
1721 | if (uart_console(uport)) { |
1722 | geni_icc_set_tag(se: &port->se, QCOM_ICC_TAG_ACTIVE_ONLY); |
1723 | geni_icc_set_bw(se: &port->se); |
1724 | } |
1725 | return uart_suspend_port(reg: private_data->drv, port: uport); |
1726 | } |
1727 | |
1728 | static int qcom_geni_serial_sys_resume(struct device *dev) |
1729 | { |
1730 | int ret; |
1731 | struct qcom_geni_serial_port *port = dev_get_drvdata(dev); |
1732 | struct uart_port *uport = &port->uport; |
1733 | struct qcom_geni_private_data *private_data = uport->private_data; |
1734 | |
1735 | ret = uart_resume_port(reg: private_data->drv, port: uport); |
1736 | if (uart_console(uport)) { |
1737 | geni_icc_set_tag(se: &port->se, QCOM_ICC_TAG_ALWAYS); |
1738 | geni_icc_set_bw(se: &port->se); |
1739 | } |
1740 | return ret; |
1741 | } |
1742 | |
1743 | static int qcom_geni_serial_sys_hib_resume(struct device *dev) |
1744 | { |
1745 | int ret = 0; |
1746 | struct uart_port *uport; |
1747 | struct qcom_geni_private_data *private_data; |
1748 | struct qcom_geni_serial_port *port = dev_get_drvdata(dev); |
1749 | |
1750 | uport = &port->uport; |
1751 | private_data = uport->private_data; |
1752 | |
1753 | if (uart_console(uport)) { |
1754 | geni_icc_set_tag(se: &port->se, QCOM_ICC_TAG_ALWAYS); |
1755 | geni_icc_set_bw(se: &port->se); |
1756 | ret = uart_resume_port(reg: private_data->drv, port: uport); |
1757 | /* |
1758 | * For hibernation usecase clients for |
1759 | * console UART won't call port setup during restore, |
1760 | * hence call port setup for console uart. |
1761 | */ |
1762 | qcom_geni_serial_port_setup(uport); |
1763 | } else { |
1764 | /* |
1765 | * Peripheral register settings are lost during hibernation. |
1766 | * Update setup flag such that port setup happens again |
1767 | * during next session. Clients of HS-UART will close and |
1768 | * open the port during hibernation. |
1769 | */ |
1770 | port->setup = false; |
1771 | } |
1772 | return ret; |
1773 | } |
1774 | |
1775 | static const struct qcom_geni_device_data qcom_geni_console_data = { |
1776 | .console = true, |
1777 | .mode = GENI_SE_FIFO, |
1778 | }; |
1779 | |
1780 | static const struct qcom_geni_device_data qcom_geni_uart_data = { |
1781 | .console = false, |
1782 | .mode = GENI_SE_DMA, |
1783 | }; |
1784 | |
1785 | static const struct dev_pm_ops qcom_geni_serial_pm_ops = { |
1786 | .suspend = pm_sleep_ptr(qcom_geni_serial_sys_suspend), |
1787 | .resume = pm_sleep_ptr(qcom_geni_serial_sys_resume), |
1788 | .freeze = pm_sleep_ptr(qcom_geni_serial_sys_suspend), |
1789 | .poweroff = pm_sleep_ptr(qcom_geni_serial_sys_suspend), |
1790 | .restore = pm_sleep_ptr(qcom_geni_serial_sys_hib_resume), |
1791 | .thaw = pm_sleep_ptr(qcom_geni_serial_sys_hib_resume), |
1792 | }; |
1793 | |
1794 | static const struct of_device_id qcom_geni_serial_match_table[] = { |
1795 | { |
1796 | .compatible = "qcom,geni-debug-uart" , |
1797 | .data = &qcom_geni_console_data, |
1798 | }, |
1799 | { |
1800 | .compatible = "qcom,geni-uart" , |
1801 | .data = &qcom_geni_uart_data, |
1802 | }, |
1803 | {} |
1804 | }; |
1805 | MODULE_DEVICE_TABLE(of, qcom_geni_serial_match_table); |
1806 | |
1807 | static struct platform_driver qcom_geni_serial_platform_driver = { |
1808 | .remove = qcom_geni_serial_remove, |
1809 | .probe = qcom_geni_serial_probe, |
1810 | .driver = { |
1811 | .name = "qcom_geni_serial" , |
1812 | .of_match_table = qcom_geni_serial_match_table, |
1813 | .pm = &qcom_geni_serial_pm_ops, |
1814 | }, |
1815 | }; |
1816 | |
1817 | static int __init qcom_geni_serial_init(void) |
1818 | { |
1819 | int ret; |
1820 | |
1821 | ret = console_register(drv: &qcom_geni_console_driver); |
1822 | if (ret) |
1823 | return ret; |
1824 | |
1825 | ret = uart_register_driver(uart: &qcom_geni_uart_driver); |
1826 | if (ret) { |
1827 | console_unregister(drv: &qcom_geni_console_driver); |
1828 | return ret; |
1829 | } |
1830 | |
1831 | ret = platform_driver_register(&qcom_geni_serial_platform_driver); |
1832 | if (ret) { |
1833 | console_unregister(drv: &qcom_geni_console_driver); |
1834 | uart_unregister_driver(uart: &qcom_geni_uart_driver); |
1835 | } |
1836 | return ret; |
1837 | } |
1838 | module_init(qcom_geni_serial_init); |
1839 | |
1840 | static void __exit qcom_geni_serial_exit(void) |
1841 | { |
1842 | platform_driver_unregister(&qcom_geni_serial_platform_driver); |
1843 | console_unregister(drv: &qcom_geni_console_driver); |
1844 | uart_unregister_driver(uart: &qcom_geni_uart_driver); |
1845 | } |
1846 | module_exit(qcom_geni_serial_exit); |
1847 | |
1848 | MODULE_DESCRIPTION("Serial driver for GENI based QUP cores" ); |
1849 | MODULE_LICENSE("GPL v2" ); |
1850 | |