Lines Matching +full:cts +full:- +full:rts +full:- +full:swap
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2017-2018, The Linux foundation. All rights reserved.
18 #include <linux/soc/qcom/geni-se.h>
24 #include <dt-bindings/interconnect/qcom,icc.h>
90 /* UART pin swap value */
192 struct platform_device *pdev = to_platform_device(uport->dev); in qcom_geni_serial_request_port()
195 uport->membase = devm_platform_ioremap_resource(pdev, 0); in qcom_geni_serial_request_port()
196 if (IS_ERR(uport->membase)) in qcom_geni_serial_request_port()
197 return PTR_ERR(uport->membase); in qcom_geni_serial_request_port()
198 port->se.base = uport->membase; in qcom_geni_serial_request_port()
205 uport->type = PORT_MSM; in qcom_geni_serial_config_port()
218 geni_ios = readl(uport->membase + SE_GENI_IOS); in qcom_geni_serial_get_mctrl()
236 port->loopback = RX_TX_CTS_RTS_SORTED; in qcom_geni_serial_set_mctrl()
238 if (!(mctrl & TIOCM_RTS) && !uport->suspended) in qcom_geni_serial_set_mctrl()
240 writel(uart_manual_rfr, uport->membase + SE_UART_MANUAL_RFR); in qcom_geni_serial_set_mctrl()
254 return ERR_PTR(-ENXIO); in get_port_from_line()
262 return readl(uport->membase + SE_GENI_STATUS) & M_GENI_CMD_ACTIVE; in qcom_geni_serial_main_active()
267 return readl(uport->membase + SE_GENI_STATUS) & S_GENI_CMD_ACTIVE; in qcom_geni_serial_secondary_active()
276 struct qcom_geni_private_data *private_data = uport->private_data; in qcom_geni_serial_poll_bit()
278 if (private_data->drv) { in qcom_geni_serial_poll_bit()
280 if (port->poll_timeout_us) in qcom_geni_serial_poll_bit()
281 timeout_us = port->poll_timeout_us; in qcom_geni_serial_poll_bit()
290 reg = readl(uport->membase + offset); in qcom_geni_serial_poll_bit()
294 timeout_us -= 10; in qcom_geni_serial_poll_bit()
303 writel(xmit_size, uport->membase + SE_UART_TX_TRANS_LEN); in qcom_geni_serial_setup_tx()
305 writel(m_cmd, uport->membase + SE_GENI_M_CMD0); in qcom_geni_serial_setup_tx()
316 writel(M_GENI_CMD_ABORT, uport->membase + in qcom_geni_serial_poll_tx_done()
322 writel(irq_clear, uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_poll_tx_done()
329 writel(S_GENI_CMD_ABORT, uport->membase + SE_GENI_S_CMD_CTRL_REG); in qcom_geni_serial_abort_rx()
332 writel(irq_clear, uport->membase + SE_GENI_S_IRQ_CLEAR); in qcom_geni_serial_abort_rx()
333 writel(FORCE_DEFAULT, uport->membase + GENI_FORCE_DEFAULT_REG); in qcom_geni_serial_abort_rx()
339 struct qcom_geni_private_data *private_data = uport->private_data; in qcom_geni_serial_get_char()
344 if (!private_data->poll_cached_bytes_cnt) { in qcom_geni_serial_get_char()
345 status = readl(uport->membase + SE_GENI_M_IRQ_STATUS); in qcom_geni_serial_get_char()
346 writel(status, uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_get_char()
348 status = readl(uport->membase + SE_GENI_S_IRQ_STATUS); in qcom_geni_serial_get_char()
349 writel(status, uport->membase + SE_GENI_S_IRQ_CLEAR); in qcom_geni_serial_get_char()
351 status = readl(uport->membase + SE_GENI_RX_FIFO_STATUS); in qcom_geni_serial_get_char()
361 private_data->poll_cached_bytes_cnt = in qcom_geni_serial_get_char()
365 if (private_data->poll_cached_bytes_cnt == 0) in qcom_geni_serial_get_char()
366 private_data->poll_cached_bytes_cnt = BYTES_PER_FIFO_WORD; in qcom_geni_serial_get_char()
368 private_data->poll_cached_bytes = in qcom_geni_serial_get_char()
369 readl(uport->membase + SE_GENI_RX_FIFOn); in qcom_geni_serial_get_char()
372 private_data->poll_cached_bytes_cnt--; in qcom_geni_serial_get_char()
373 ret = private_data->poll_cached_bytes & 0xff; in qcom_geni_serial_get_char()
374 private_data->poll_cached_bytes >>= 8; in qcom_geni_serial_get_char()
382 writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG); in qcom_geni_serial_poll_put_char()
386 writel(c, uport->membase + SE_GENI_TX_FIFOn); in qcom_geni_serial_poll_put_char()
387 writel(M_TX_FIFO_WATERMARK_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_poll_put_char()
396 if (!port->setup) { in qcom_geni_serial_poll_init()
403 geni_se_setup_s_cmd(&port->se, UART_START_READ, 0); in qcom_geni_serial_poll_init()
412 struct qcom_geni_private_data *private_data = uport->private_data; in qcom_geni_serial_wr_char()
414 private_data->write_cached_bytes = in qcom_geni_serial_wr_char()
415 (private_data->write_cached_bytes >> 8) | (ch << 24); in qcom_geni_serial_wr_char()
416 private_data->write_cached_bytes_cnt++; in qcom_geni_serial_wr_char()
418 if (private_data->write_cached_bytes_cnt == BYTES_PER_FIFO_WORD) { in qcom_geni_serial_wr_char()
419 writel(private_data->write_cached_bytes, in qcom_geni_serial_wr_char()
420 uport->membase + SE_GENI_TX_FIFOn); in qcom_geni_serial_wr_char()
421 private_data->write_cached_bytes_cnt = 0; in qcom_geni_serial_wr_char()
429 struct qcom_geni_private_data *private_data = uport->private_data; in __qcom_geni_serial_console_write()
443 writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG); in __qcom_geni_serial_console_write()
447 size_t avail = DEF_FIFO_DEPTH_WORDS - DEF_TX_WM; in __qcom_geni_serial_console_write()
458 chars_to_write = min_t(size_t, count - i, avail / 2); in __qcom_geni_serial_console_write()
461 writel(M_TX_FIFO_WATERMARK_EN, uport->membase + in __qcom_geni_serial_console_write()
466 if (private_data->write_cached_bytes_cnt) { in __qcom_geni_serial_console_write()
467 private_data->write_cached_bytes >>= BITS_PER_BYTE * in __qcom_geni_serial_console_write()
468 (BYTES_PER_FIFO_WORD - private_data->write_cached_bytes_cnt); in __qcom_geni_serial_console_write()
469 writel(private_data->write_cached_bytes, in __qcom_geni_serial_console_write()
470 uport->membase + SE_GENI_TX_FIFOn); in __qcom_geni_serial_console_write()
471 private_data->write_cached_bytes_cnt = 0; in __qcom_geni_serial_console_write()
487 WARN_ON(co->index < 0 || co->index >= GENI_UART_CONS_PORTS); in qcom_geni_serial_console_write()
489 port = get_port_from_line(co->index, true); in qcom_geni_serial_console_write()
493 uport = &port->uport; in qcom_geni_serial_console_write()
495 locked = spin_trylock_irqsave(&uport->lock, flags); in qcom_geni_serial_console_write()
497 spin_lock_irqsave(&uport->lock, flags); in qcom_geni_serial_console_write()
499 geni_status = readl(uport->membase + SE_GENI_STATUS); in qcom_geni_serial_console_write()
503 geni_se_cancel_m_cmd(&port->se); in qcom_geni_serial_console_write()
506 geni_se_abort_m_cmd(&port->se); in qcom_geni_serial_console_write()
509 writel(M_CMD_ABORT_EN, uport->membase + in qcom_geni_serial_console_write()
512 writel(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_console_write()
513 } else if ((geni_status & M_GENI_CMD_ACTIVE) && !port->tx_remaining) { in qcom_geni_serial_console_write()
520 if (!uart_circ_empty(&uport->state->xmit)) { in qcom_geni_serial_console_write()
521 irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_console_write()
523 uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_console_write()
529 if (port->tx_remaining) in qcom_geni_serial_console_write()
530 qcom_geni_serial_setup_tx(uport, port->tx_remaining); in qcom_geni_serial_console_write()
533 spin_unlock_irqrestore(&uport->lock, flags); in qcom_geni_serial_console_write()
543 tport = &uport->state->port; in handle_rx_console()
546 int chunk = min_t(int, bytes - i, BYTES_PER_FIFO_WORD); in handle_rx_console()
548 ioread32_rep(uport->membase + SE_GENI_RX_FIFOn, buf, 1); in handle_rx_console()
556 uport->icount.rx++; in handle_rx_console()
557 if (port->brk && buf[c] == 0) { in handle_rx_console()
558 port->brk = false; in handle_rx_console()
582 struct tty_port *tport = &uport->state->port; in handle_rx_uart()
585 ret = tty_insert_flip_string(tport, port->rx_buf, bytes); in handle_rx_uart()
587 dev_err(uport->dev, "%s:Unable to push data ret %d_bytes %d\n", in handle_rx_uart()
591 uport->icount.rx += ret; in handle_rx_uart()
597 return !readl(uport->membase + SE_GENI_TX_FIFO_STATUS); in qcom_geni_serial_tx_empty()
608 if (port->tx_dma_addr) { in qcom_geni_serial_stop_tx_dma()
609 geni_se_tx_dma_unprep(&port->se, port->tx_dma_addr, in qcom_geni_serial_stop_tx_dma()
610 port->tx_remaining); in qcom_geni_serial_stop_tx_dma()
611 port->tx_dma_addr = 0; in qcom_geni_serial_stop_tx_dma()
612 port->tx_remaining = 0; in qcom_geni_serial_stop_tx_dma()
615 geni_se_cancel_m_cmd(&port->se); in qcom_geni_serial_stop_tx_dma()
620 geni_se_abort_m_cmd(&port->se); in qcom_geni_serial_stop_tx_dma()
624 dev_err_ratelimited(uport->dev, "M_CMD_ABORT_EN not set"); in qcom_geni_serial_stop_tx_dma()
625 writel(M_CMD_ABORT_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_stop_tx_dma()
628 writel(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_stop_tx_dma()
634 struct circ_buf *xmit = &uport->state->xmit; in qcom_geni_serial_start_tx_dma()
638 if (port->tx_dma_addr) in qcom_geni_serial_start_tx_dma()
644 xmit_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); in qcom_geni_serial_start_tx_dma()
648 ret = geni_se_tx_dma_prep(&port->se, &xmit->buf[xmit->tail], in qcom_geni_serial_start_tx_dma()
649 xmit_size, &port->tx_dma_addr); in qcom_geni_serial_start_tx_dma()
651 dev_err(uport->dev, "unable to start TX SE DMA: %d\n", ret); in qcom_geni_serial_start_tx_dma()
656 port->tx_remaining = xmit_size; in qcom_geni_serial_start_tx_dma()
667 irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_start_tx_fifo()
670 writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG); in qcom_geni_serial_start_tx_fifo()
671 writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_start_tx_fifo()
679 irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_stop_tx_fifo()
681 writel(0, uport->membase + SE_GENI_TX_WATERMARK_REG); in qcom_geni_serial_stop_tx_fifo()
682 writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_stop_tx_fifo()
687 geni_se_cancel_m_cmd(&port->se); in qcom_geni_serial_stop_tx_fifo()
690 geni_se_abort_m_cmd(&port->se); in qcom_geni_serial_stop_tx_fifo()
693 writel(M_CMD_ABORT_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_stop_tx_fifo()
695 writel(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_stop_tx_fifo()
706 status = readl(uport->membase + SE_GENI_RX_FIFO_STATUS); in qcom_geni_serial_handle_rx_fifo()
714 total_bytes = BYTES_PER_FIFO_WORD * (word_cnt - 1); in qcom_geni_serial_handle_rx_fifo()
728 irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN); in qcom_geni_serial_stop_rx_fifo()
730 writel(irq_en, uport->membase + SE_GENI_S_IRQ_EN); in qcom_geni_serial_stop_rx_fifo()
732 irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_stop_rx_fifo()
734 writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_stop_rx_fifo()
739 geni_se_cancel_s_cmd(&port->se); in qcom_geni_serial_stop_rx_fifo()
746 s_irq_status = readl(uport->membase + SE_GENI_S_IRQ_STATUS); in qcom_geni_serial_stop_rx_fifo()
750 writel(s_irq_status, uport->membase + SE_GENI_S_IRQ_CLEAR); in qcom_geni_serial_stop_rx_fifo()
764 geni_se_setup_s_cmd(&port->se, UART_START_READ, 0); in qcom_geni_serial_start_rx_fifo()
766 irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN); in qcom_geni_serial_start_rx_fifo()
768 writel(irq_en, uport->membase + SE_GENI_S_IRQ_EN); in qcom_geni_serial_start_rx_fifo()
770 irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_start_rx_fifo()
772 writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_start_rx_fifo()
783 geni_se_cancel_s_cmd(&port->se); in qcom_geni_serial_stop_rx_dma()
788 uport->membase + SE_DMA_RX_IRQ_CLR); in qcom_geni_serial_stop_rx_dma()
792 writel(1, uport->membase + SE_DMA_RX_FSM_RST); in qcom_geni_serial_stop_rx_dma()
796 uport->membase + SE_DMA_RX_IRQ_CLR); in qcom_geni_serial_stop_rx_dma()
799 if (port->rx_dma_addr) { in qcom_geni_serial_stop_rx_dma()
800 geni_se_rx_dma_unprep(&port->se, port->rx_dma_addr, in qcom_geni_serial_stop_rx_dma()
802 port->rx_dma_addr = 0; in qcom_geni_serial_stop_rx_dma()
814 geni_se_setup_s_cmd(&port->se, UART_START_READ, UART_PARAM_RFR_OPEN); in qcom_geni_serial_start_rx_dma()
816 ret = geni_se_rx_dma_prep(&port->se, port->rx_buf, in qcom_geni_serial_start_rx_dma()
818 &port->rx_dma_addr); in qcom_geni_serial_start_rx_dma()
820 dev_err(uport->dev, "unable to start RX SE DMA: %d\n", ret); in qcom_geni_serial_start_rx_dma()
834 if (!port->rx_dma_addr) in qcom_geni_serial_handle_rx_dma()
837 geni_se_rx_dma_unprep(&port->se, port->rx_dma_addr, DMA_RX_BUF_SIZE); in qcom_geni_serial_handle_rx_dma()
838 port->rx_dma_addr = 0; in qcom_geni_serial_handle_rx_dma()
840 rx_in = readl(uport->membase + SE_DMA_RX_LEN_IN); in qcom_geni_serial_handle_rx_dma()
842 dev_warn(uport->dev, "serial engine reports 0 RX bytes in!\n"); in qcom_geni_serial_handle_rx_dma()
849 ret = geni_se_rx_dma_prep(&port->se, port->rx_buf, in qcom_geni_serial_handle_rx_dma()
851 &port->rx_dma_addr); in qcom_geni_serial_handle_rx_dma()
853 dev_err(uport->dev, "unable to start RX SE DMA: %d\n", ret); in qcom_geni_serial_handle_rx_dma()
860 uport->ops->start_rx(uport); in qcom_geni_serial_start_rx()
865 uport->ops->stop_rx(uport); in qcom_geni_serial_stop_rx()
870 uport->ops->stop_tx(uport); in qcom_geni_serial_stop_tx()
877 struct circ_buf *xmit = &uport->state->xmit; in qcom_geni_serial_send_chunk_fifo()
886 buf[c] = xmit->buf[xmit->tail]; in qcom_geni_serial_send_chunk_fifo()
890 iowrite32_rep(uport->membase + SE_GENI_TX_FIFOn, buf, 1); in qcom_geni_serial_send_chunk_fifo()
892 remaining -= tx_bytes; in qcom_geni_serial_send_chunk_fifo()
893 port->tx_remaining -= tx_bytes; in qcom_geni_serial_send_chunk_fifo()
901 struct circ_buf *xmit = &uport->state->xmit; in qcom_geni_serial_handle_tx_fifo()
908 status = readl(uport->membase + SE_GENI_TX_FIFO_STATUS); in qcom_geni_serial_handle_tx_fifo()
912 pending = port->tx_remaining; in qcom_geni_serial_handle_tx_fifo()
922 avail = port->tx_fifo_depth - (status & TX_FIFO_WC); in qcom_geni_serial_handle_tx_fifo()
929 if (!port->tx_remaining) { in qcom_geni_serial_handle_tx_fifo()
931 port->tx_remaining = pending; in qcom_geni_serial_handle_tx_fifo()
933 irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_handle_tx_fifo()
936 uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_handle_tx_fifo()
947 uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_handle_tx_fifo()
950 if (!port->tx_remaining) { in qcom_geni_serial_handle_tx_fifo()
951 irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_handle_tx_fifo()
954 uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_handle_tx_fifo()
964 struct circ_buf *xmit = &uport->state->xmit; in qcom_geni_serial_handle_tx_dma()
966 uart_xmit_advance(uport, port->tx_remaining); in qcom_geni_serial_handle_tx_dma()
967 geni_se_tx_dma_unprep(&port->se, port->tx_dma_addr, port->tx_remaining); in qcom_geni_serial_handle_tx_dma()
968 port->tx_dma_addr = 0; in qcom_geni_serial_handle_tx_dma()
969 port->tx_remaining = 0; in qcom_geni_serial_handle_tx_dma()
989 struct tty_port *tport = &uport->state->port; in qcom_geni_serial_isr()
992 if (uport->suspended) in qcom_geni_serial_isr()
995 spin_lock(&uport->lock); in qcom_geni_serial_isr()
997 m_irq_status = readl(uport->membase + SE_GENI_M_IRQ_STATUS); in qcom_geni_serial_isr()
998 s_irq_status = readl(uport->membase + SE_GENI_S_IRQ_STATUS); in qcom_geni_serial_isr()
999 dma_tx_status = readl(uport->membase + SE_DMA_TX_IRQ_STAT); in qcom_geni_serial_isr()
1000 dma_rx_status = readl(uport->membase + SE_DMA_RX_IRQ_STAT); in qcom_geni_serial_isr()
1001 geni_status = readl(uport->membase + SE_GENI_STATUS); in qcom_geni_serial_isr()
1002 dma = readl(uport->membase + SE_GENI_DMA_MODE_EN); in qcom_geni_serial_isr()
1003 m_irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_isr()
1004 writel(m_irq_status, uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_isr()
1005 writel(s_irq_status, uport->membase + SE_GENI_S_IRQ_CLEAR); in qcom_geni_serial_isr()
1006 writel(dma_tx_status, uport->membase + SE_DMA_TX_IRQ_CLR); in qcom_geni_serial_isr()
1007 writel(dma_rx_status, uport->membase + SE_DMA_RX_IRQ_CLR); in qcom_geni_serial_isr()
1013 uport->icount.overrun++; in qcom_geni_serial_isr()
1019 uport->icount.parity++; in qcom_geni_serial_isr()
1022 uport->icount.brk++; in qcom_geni_serial_isr()
1023 port->brk = true; in qcom_geni_serial_isr()
1035 uport->icount.parity++; in qcom_geni_serial_isr()
1040 uport->icount.brk++; in qcom_geni_serial_isr()
1065 u32 old_rx_fifo_depth = port->rx_fifo_depth; in setup_fifos()
1067 uport = &port->uport; in setup_fifos()
1068 port->tx_fifo_depth = geni_se_get_tx_fifo_depth(&port->se); in setup_fifos()
1069 port->tx_fifo_width = geni_se_get_tx_fifo_width(&port->se); in setup_fifos()
1070 port->rx_fifo_depth = geni_se_get_rx_fifo_depth(&port->se); in setup_fifos()
1071 uport->fifosize = in setup_fifos()
1072 (port->tx_fifo_depth * port->tx_fifo_width) / BITS_PER_BYTE; in setup_fifos()
1074 if (port->rx_buf && (old_rx_fifo_depth != port->rx_fifo_depth) && port->rx_fifo_depth) { in setup_fifos()
1080 port->rx_buf = devm_krealloc(uport->dev, port->rx_buf, in setup_fifos()
1081 port->rx_fifo_depth * sizeof(u32), in setup_fifos()
1083 if (!port->rx_buf) in setup_fifos()
1084 return -ENOMEM; in setup_fifos()
1093 disable_irq(uport->irq); in qcom_geni_serial_shutdown()
1110 proto = geni_se_read_proto(&port->se); in qcom_geni_serial_port_setup()
1112 dev_err(uport->dev, "Invalid FW loaded, proto: %d\n", proto); in qcom_geni_serial_port_setup()
1113 return -ENXIO; in qcom_geni_serial_port_setup()
1122 writel(rxstale, uport->membase + SE_UART_RX_STALE_CNT); in qcom_geni_serial_port_setup()
1124 pin_swap = readl(uport->membase + SE_UART_IO_MACRO_CTRL); in qcom_geni_serial_port_setup()
1125 if (port->rx_tx_swap) { in qcom_geni_serial_port_setup()
1129 if (port->cts_rts_swap) { in qcom_geni_serial_port_setup()
1133 /* Configure this register if RX-TX, CTS-RTS pins are swapped */ in qcom_geni_serial_port_setup()
1134 if (port->rx_tx_swap || port->cts_rts_swap) in qcom_geni_serial_port_setup()
1135 writel(pin_swap, uport->membase + SE_UART_IO_MACRO_CTRL); in qcom_geni_serial_port_setup()
1143 geni_se_config_packing(&port->se, BITS_PER_BYTE, BYTES_PER_FIFO_WORD, in qcom_geni_serial_port_setup()
1145 geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2); in qcom_geni_serial_port_setup()
1146 geni_se_select_mode(&port->se, port->dev_data->mode); in qcom_geni_serial_port_setup()
1147 port->setup = true; in qcom_geni_serial_port_setup()
1157 if (!port->setup) { in qcom_geni_serial_startup()
1167 enable_irq(uport->irq); in qcom_geni_serial_startup()
1189 freq = clk_round_rate(clk, mult - offset); in find_clk_rate_in_tol()
1192 if (freq < mult - offset) in find_clk_rate_in_tol()
1196 * Re-calculate div in case rounding skipped rates but we in find_clk_rate_in_tol()
1202 achieved >= desired_clk - abs_tol) { in find_clk_rate_in_tol()
1257 ver = geni_se_get_qup_hw_version(&port->se); in qcom_geni_serial_set_termios()
1261 clk_rate = get_clk_div_rate(port->se.clk, baud, in qcom_geni_serial_set_termios()
1264 dev_err(port->se.dev, in qcom_geni_serial_set_termios()
1270 dev_dbg(port->se.dev, "desired_rate = %u, clk_rate = %lu, clk_div = %u\n", in qcom_geni_serial_set_termios()
1273 uport->uartclk = clk_rate; in qcom_geni_serial_set_termios()
1274 port->clk_rate = clk_rate; in qcom_geni_serial_set_termios()
1275 dev_pm_opp_set_rate(uport->dev, clk_rate); in qcom_geni_serial_set_termios()
1285 port->se.icc_paths[GENI_TO_CORE].avg_bw = avg_bw_core; in qcom_geni_serial_set_termios()
1286 port->se.icc_paths[CPU_TO_GENI].avg_bw = Bps_to_icc(baud); in qcom_geni_serial_set_termios()
1287 geni_icc_set_bw(&port->se); in qcom_geni_serial_set_termios()
1290 tx_trans_cfg = readl(uport->membase + SE_UART_TX_TRANS_CFG); in qcom_geni_serial_set_termios()
1291 tx_parity_cfg = readl(uport->membase + SE_UART_TX_PARITY_CFG); in qcom_geni_serial_set_termios()
1292 rx_trans_cfg = readl(uport->membase + SE_UART_RX_TRANS_CFG); in qcom_geni_serial_set_termios()
1293 rx_parity_cfg = readl(uport->membase + SE_UART_RX_PARITY_CFG); in qcom_geni_serial_set_termios()
1294 if (termios->c_cflag & PARENB) { in qcom_geni_serial_set_termios()
1299 if (termios->c_cflag & PARODD) { in qcom_geni_serial_set_termios()
1302 } else if (termios->c_cflag & CMSPAR) { in qcom_geni_serial_set_termios()
1317 bits_per_char = tty_get_char_size(termios->c_cflag); in qcom_geni_serial_set_termios()
1320 if (termios->c_cflag & CSTOPB) in qcom_geni_serial_set_termios()
1326 if (termios->c_cflag & CRTSCTS) in qcom_geni_serial_set_termios()
1332 uart_update_timeout(uport, termios->c_cflag, baud); in qcom_geni_serial_set_termios()
1336 * the FIFO, two-word intermediate transfer register and shift in qcom_geni_serial_set_termios()
1342 timeout += 3 * timeout / port->tx_fifo_depth; in qcom_geni_serial_set_termios()
1343 WRITE_ONCE(port->poll_timeout_us, timeout); in qcom_geni_serial_set_termios()
1347 writel(port->loopback, in qcom_geni_serial_set_termios()
1348 uport->membase + SE_UART_LOOPBACK_CFG); in qcom_geni_serial_set_termios()
1349 writel(tx_trans_cfg, uport->membase + SE_UART_TX_TRANS_CFG); in qcom_geni_serial_set_termios()
1350 writel(tx_parity_cfg, uport->membase + SE_UART_TX_PARITY_CFG); in qcom_geni_serial_set_termios()
1351 writel(rx_trans_cfg, uport->membase + SE_UART_RX_TRANS_CFG); in qcom_geni_serial_set_termios()
1352 writel(rx_parity_cfg, uport->membase + SE_UART_RX_PARITY_CFG); in qcom_geni_serial_set_termios()
1353 writel(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN); in qcom_geni_serial_set_termios()
1354 writel(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN); in qcom_geni_serial_set_termios()
1355 writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN); in qcom_geni_serial_set_termios()
1356 writel(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG); in qcom_geni_serial_set_termios()
1357 writel(ser_clk_cfg, uport->membase + GENI_SER_S_CLK_CFG); in qcom_geni_serial_set_termios()
1371 if (co->index >= GENI_UART_CONS_PORTS || co->index < 0) in qcom_geni_console_setup()
1372 return -ENXIO; in qcom_geni_console_setup()
1374 port = get_port_from_line(co->index, true); in qcom_geni_console_setup()
1376 pr_err("Invalid line %d\n", co->index); in qcom_geni_console_setup()
1380 uport = &port->uport; in qcom_geni_console_setup()
1382 if (unlikely(!uport->membase)) in qcom_geni_console_setup()
1383 return -ENXIO; in qcom_geni_console_setup()
1385 if (!port->setup) { in qcom_geni_console_setup()
1400 struct earlycon_device *dev = con->data; in qcom_geni_serial_earlycon_write()
1402 __qcom_geni_serial_console_write(&dev->port, s, n); in qcom_geni_serial_earlycon_write()
1409 struct earlycon_device *dev = con->data; in qcom_geni_serial_earlycon_read()
1410 struct uart_port *uport = &dev->port; in qcom_geni_serial_earlycon_read()
1428 con->read = qcom_geni_serial_earlycon_read; in qcom_geni_serial_enable_early_read()
1440 struct uart_port *uport = &dev->port; in qcom_geni_serial_earlycon_setup()
1445 u32 stop_bit_len = 0; /* Default stop bit length - 1 bit */ in qcom_geni_serial_earlycon_setup()
1449 if (!uport->membase) in qcom_geni_serial_earlycon_setup()
1450 return -EINVAL; in qcom_geni_serial_earlycon_setup()
1452 uport->private_data = &earlycon_private_data; in qcom_geni_serial_earlycon_setup()
1455 se.base = uport->membase; in qcom_geni_serial_earlycon_setup()
1457 return -ENXIO; in qcom_geni_serial_earlycon_setup()
1473 geni_se_init(&se, DEF_FIFO_DEPTH_WORDS / 2, DEF_FIFO_DEPTH_WORDS - 2); in qcom_geni_serial_earlycon_setup()
1476 writel(tx_trans_cfg, uport->membase + SE_UART_TX_TRANS_CFG); in qcom_geni_serial_earlycon_setup()
1477 writel(tx_parity_cfg, uport->membase + SE_UART_TX_PARITY_CFG); in qcom_geni_serial_earlycon_setup()
1478 writel(rx_trans_cfg, uport->membase + SE_UART_RX_TRANS_CFG); in qcom_geni_serial_earlycon_setup()
1479 writel(rx_parity_cfg, uport->membase + SE_UART_RX_PARITY_CFG); in qcom_geni_serial_earlycon_setup()
1480 writel(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN); in qcom_geni_serial_earlycon_setup()
1481 writel(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN); in qcom_geni_serial_earlycon_setup()
1482 writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN); in qcom_geni_serial_earlycon_setup()
1484 dev->con->write = qcom_geni_serial_earlycon_write; in qcom_geni_serial_earlycon_setup()
1485 dev->con->setup = NULL; in qcom_geni_serial_earlycon_setup()
1486 qcom_geni_serial_enable_early_read(&se, dev->con); in qcom_geni_serial_earlycon_setup()
1490 OF_EARLYCON_DECLARE(qcom_geni, "qcom,geni-debug-uart",
1509 .index = -1,
1548 geni_icc_enable(&port->se); in qcom_geni_serial_pm()
1549 if (port->clk_rate) in qcom_geni_serial_pm()
1550 dev_pm_opp_set_rate(uport->dev, port->clk_rate); in qcom_geni_serial_pm()
1551 geni_se_resources_on(&port->se); in qcom_geni_serial_pm()
1554 geni_se_resources_off(&port->se); in qcom_geni_serial_pm()
1555 dev_pm_opp_set_rate(uport->dev, 0); in qcom_geni_serial_pm()
1556 geni_icc_disable(&port->se); in qcom_geni_serial_pm()
1610 data = of_device_get_match_data(&pdev->dev); in qcom_geni_serial_probe()
1612 return -EINVAL; in qcom_geni_serial_probe()
1614 if (data->console) { in qcom_geni_serial_probe()
1616 line = of_alias_get_id(pdev->dev.of_node, "serial"); in qcom_geni_serial_probe()
1619 line = of_alias_get_id(pdev->dev.of_node, "serial"); in qcom_geni_serial_probe()
1620 if (line == -ENODEV) /* compat with non-standard aliases */ in qcom_geni_serial_probe()
1621 line = of_alias_get_id(pdev->dev.of_node, "hsuart"); in qcom_geni_serial_probe()
1624 port = get_port_from_line(line, data->console); in qcom_geni_serial_probe()
1626 dev_err(&pdev->dev, "Invalid line %d\n", line); in qcom_geni_serial_probe()
1630 uport = &port->uport; in qcom_geni_serial_probe()
1632 if (uport->private_data) in qcom_geni_serial_probe()
1633 return -ENODEV; in qcom_geni_serial_probe()
1635 uport->dev = &pdev->dev; in qcom_geni_serial_probe()
1636 port->dev_data = data; in qcom_geni_serial_probe()
1637 port->se.dev = &pdev->dev; in qcom_geni_serial_probe()
1638 port->se.wrapper = dev_get_drvdata(pdev->dev.parent); in qcom_geni_serial_probe()
1639 port->se.clk = devm_clk_get(&pdev->dev, "se"); in qcom_geni_serial_probe()
1640 if (IS_ERR(port->se.clk)) { in qcom_geni_serial_probe()
1641 ret = PTR_ERR(port->se.clk); in qcom_geni_serial_probe()
1642 dev_err(&pdev->dev, "Err getting SE Core clk %d\n", ret); in qcom_geni_serial_probe()
1648 return -EINVAL; in qcom_geni_serial_probe()
1649 uport->mapbase = res->start; in qcom_geni_serial_probe()
1651 port->tx_fifo_depth = DEF_FIFO_DEPTH_WORDS; in qcom_geni_serial_probe()
1652 port->rx_fifo_depth = DEF_FIFO_DEPTH_WORDS; in qcom_geni_serial_probe()
1653 port->tx_fifo_width = DEF_FIFO_WIDTH_BITS; in qcom_geni_serial_probe()
1655 if (!data->console) { in qcom_geni_serial_probe()
1656 port->rx_buf = devm_kzalloc(uport->dev, in qcom_geni_serial_probe()
1658 if (!port->rx_buf) in qcom_geni_serial_probe()
1659 return -ENOMEM; in qcom_geni_serial_probe()
1662 ret = geni_icc_get(&port->se, NULL); in qcom_geni_serial_probe()
1665 port->se.icc_paths[GENI_TO_CORE].avg_bw = GENI_DEFAULT_BW; in qcom_geni_serial_probe()
1666 port->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW; in qcom_geni_serial_probe()
1669 ret = geni_icc_set_bw(&port->se); in qcom_geni_serial_probe()
1673 port->name = devm_kasprintf(uport->dev, GFP_KERNEL, in qcom_geni_serial_probe()
1675 uart_console(uport) ? "console" : "uart", uport->line); in qcom_geni_serial_probe()
1676 if (!port->name) in qcom_geni_serial_probe()
1677 return -ENOMEM; in qcom_geni_serial_probe()
1682 uport->irq = irq; in qcom_geni_serial_probe()
1683 uport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_QCOM_GENI_CONSOLE); in qcom_geni_serial_probe()
1685 if (!data->console) in qcom_geni_serial_probe()
1686 port->wakeup_irq = platform_get_irq_optional(pdev, 1); in qcom_geni_serial_probe()
1688 if (of_property_read_bool(pdev->dev.of_node, "rx-tx-swap")) in qcom_geni_serial_probe()
1689 port->rx_tx_swap = true; in qcom_geni_serial_probe()
1691 if (of_property_read_bool(pdev->dev.of_node, "cts-rts-swap")) in qcom_geni_serial_probe()
1692 port->cts_rts_swap = true; in qcom_geni_serial_probe()
1694 ret = devm_pm_opp_set_clkname(&pdev->dev, "se"); in qcom_geni_serial_probe()
1698 ret = devm_pm_opp_of_add_table(&pdev->dev); in qcom_geni_serial_probe()
1699 if (ret && ret != -ENODEV) { in qcom_geni_serial_probe()
1700 dev_err(&pdev->dev, "invalid OPP table in device tree\n"); in qcom_geni_serial_probe()
1704 port->private_data.drv = drv; in qcom_geni_serial_probe()
1705 uport->private_data = &port->private_data; in qcom_geni_serial_probe()
1708 irq_set_status_flags(uport->irq, IRQ_NOAUTOEN); in qcom_geni_serial_probe()
1709 ret = devm_request_irq(uport->dev, uport->irq, qcom_geni_serial_isr, in qcom_geni_serial_probe()
1710 IRQF_TRIGGER_HIGH, port->name, uport); in qcom_geni_serial_probe()
1712 dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret); in qcom_geni_serial_probe()
1720 if (port->wakeup_irq > 0) { in qcom_geni_serial_probe()
1721 device_init_wakeup(&pdev->dev, true); in qcom_geni_serial_probe()
1722 ret = dev_pm_set_dedicated_wake_irq(&pdev->dev, in qcom_geni_serial_probe()
1723 port->wakeup_irq); in qcom_geni_serial_probe()
1725 device_init_wakeup(&pdev->dev, false); in qcom_geni_serial_probe()
1737 struct uart_driver *drv = port->private_data.drv; in qcom_geni_serial_remove()
1739 dev_pm_clear_wake_irq(&pdev->dev); in qcom_geni_serial_remove()
1740 device_init_wakeup(&pdev->dev, false); in qcom_geni_serial_remove()
1741 uart_remove_one_port(drv, &port->uport); in qcom_geni_serial_remove()
1749 struct uart_port *uport = &port->uport; in qcom_geni_serial_sys_suspend()
1750 struct qcom_geni_private_data *private_data = uport->private_data; in qcom_geni_serial_sys_suspend()
1757 geni_icc_set_tag(&port->se, QCOM_ICC_TAG_ACTIVE_ONLY); in qcom_geni_serial_sys_suspend()
1758 geni_icc_set_bw(&port->se); in qcom_geni_serial_sys_suspend()
1760 return uart_suspend_port(private_data->drv, uport); in qcom_geni_serial_sys_suspend()
1767 struct uart_port *uport = &port->uport; in qcom_geni_serial_sys_resume()
1768 struct qcom_geni_private_data *private_data = uport->private_data; in qcom_geni_serial_sys_resume()
1770 ret = uart_resume_port(private_data->drv, uport); in qcom_geni_serial_sys_resume()
1772 geni_icc_set_tag(&port->se, QCOM_ICC_TAG_ALWAYS); in qcom_geni_serial_sys_resume()
1773 geni_icc_set_bw(&port->se); in qcom_geni_serial_sys_resume()
1795 .compatible = "qcom,geni-debug-uart",
1799 .compatible = "qcom,geni-uart",