Lines Matching +full:geni +full:- +full:se +full:- +full:qup
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2017-2018, The Linux foundation. All rights reserved.
19 #include <linux/soc/qcom/geni-se.h>
25 #include <dt-bindings/interconnect/qcom,icc.h>
27 /* UART specific GENI registers */
128 struct geni_se se; member
208 * qcom_geni_set_rs485_mode - Set RTS pin state for RS485 mode
217 if (!(uport->rs485.flags & SER_RS485_ENABLED)) in qcom_geni_set_rs485_mode()
222 if (uport->rs485.flags & flag) in qcom_geni_set_rs485_mode()
227 writel(rfr, uport->membase + SE_UART_MANUAL_RFR); in qcom_geni_set_rs485_mode()
232 struct platform_device *pdev = to_platform_device(uport->dev); in qcom_geni_serial_request_port()
235 uport->membase = devm_platform_ioremap_resource(pdev, 0); in qcom_geni_serial_request_port()
236 if (IS_ERR(uport->membase)) in qcom_geni_serial_request_port()
237 return PTR_ERR(uport->membase); in qcom_geni_serial_request_port()
238 port->se.base = uport->membase; in qcom_geni_serial_request_port()
245 uport->type = PORT_MSM; in qcom_geni_serial_config_port()
258 geni_ios = readl(uport->membase + SE_GENI_IOS); in qcom_geni_serial_get_mctrl()
276 port->loopback = RX_TX_CTS_RTS_SORTED; in qcom_geni_serial_set_mctrl()
278 if (!(mctrl & TIOCM_RTS) && !uport->suspended) in qcom_geni_serial_set_mctrl()
280 writel(uart_manual_rfr, uport->membase + SE_UART_MANUAL_RFR); in qcom_geni_serial_set_mctrl()
295 return ERR_PTR(-ENXIO); in get_port_from_line()
307 return ERR_PTR(-ENXIO); in get_port_from_line()
316 return readl(uport->membase + SE_GENI_STATUS) & M_GENI_CMD_ACTIVE; in qcom_geni_serial_main_active()
321 return readl(uport->membase + SE_GENI_STATUS) & S_GENI_CMD_ACTIVE; in qcom_geni_serial_secondary_active()
330 struct qcom_geni_private_data *private_data = uport->private_data; in qcom_geni_serial_poll_bitfield()
332 if (private_data->drv) { in qcom_geni_serial_poll_bitfield()
334 if (port->poll_timeout_us) in qcom_geni_serial_poll_bitfield()
335 timeout_us = port->poll_timeout_us; in qcom_geni_serial_poll_bitfield()
344 reg = readl(uport->membase + offset); in qcom_geni_serial_poll_bitfield()
348 timeout_us -= 10; in qcom_geni_serial_poll_bitfield()
363 writel(xmit_size, uport->membase + SE_UART_TX_TRANS_LEN); in qcom_geni_serial_setup_tx()
365 writel(m_cmd, uport->membase + SE_GENI_M_CMD0); in qcom_geni_serial_setup_tx()
375 writel(M_GENI_CMD_ABORT, uport->membase + in qcom_geni_serial_poll_tx_done()
379 writel(M_CMD_ABORT_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_poll_tx_done()
387 writel(S_GENI_CMD_ABORT, uport->membase + SE_GENI_S_CMD_CTRL_REG); in qcom_geni_serial_abort_rx()
390 writel(irq_clear, uport->membase + SE_GENI_S_IRQ_CLEAR); in qcom_geni_serial_abort_rx()
391 writel(FORCE_DEFAULT, uport->membase + GENI_FORCE_DEFAULT_REG); in qcom_geni_serial_abort_rx()
397 struct qcom_geni_private_data *private_data = uport->private_data; in qcom_geni_serial_get_char()
402 if (!private_data->poll_cached_bytes_cnt) { in qcom_geni_serial_get_char()
403 status = readl(uport->membase + SE_GENI_M_IRQ_STATUS); in qcom_geni_serial_get_char()
404 writel(status, uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_get_char()
406 status = readl(uport->membase + SE_GENI_S_IRQ_STATUS); in qcom_geni_serial_get_char()
407 writel(status, uport->membase + SE_GENI_S_IRQ_CLEAR); in qcom_geni_serial_get_char()
409 status = readl(uport->membase + SE_GENI_RX_FIFO_STATUS); in qcom_geni_serial_get_char()
419 private_data->poll_cached_bytes_cnt = in qcom_geni_serial_get_char()
423 if (private_data->poll_cached_bytes_cnt == 0) in qcom_geni_serial_get_char()
424 private_data->poll_cached_bytes_cnt = BYTES_PER_FIFO_WORD; in qcom_geni_serial_get_char()
426 private_data->poll_cached_bytes = in qcom_geni_serial_get_char()
427 readl(uport->membase + SE_GENI_RX_FIFOn); in qcom_geni_serial_get_char()
430 private_data->poll_cached_bytes_cnt--; in qcom_geni_serial_get_char()
431 ret = private_data->poll_cached_bytes & 0xff; in qcom_geni_serial_get_char()
432 private_data->poll_cached_bytes >>= 8; in qcom_geni_serial_get_char()
445 writel(M_CMD_DONE_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_poll_put_char()
447 writel(c, uport->membase + SE_GENI_TX_FIFOn); in qcom_geni_serial_poll_put_char()
456 if (!port->setup) { in qcom_geni_serial_poll_init()
463 geni_se_setup_s_cmd(&port->se, UART_START_READ, 0); in qcom_geni_serial_poll_init()
475 port->tx_queued); in qcom_geni_serial_drain_fifo()
480 struct qcom_geni_private_data *private_data = uport->private_data; in qcom_geni_serial_wr_char()
482 private_data->write_cached_bytes = in qcom_geni_serial_wr_char()
483 (private_data->write_cached_bytes >> 8) | (ch << 24); in qcom_geni_serial_wr_char()
484 private_data->write_cached_bytes_cnt++; in qcom_geni_serial_wr_char()
486 if (private_data->write_cached_bytes_cnt == BYTES_PER_FIFO_WORD) { in qcom_geni_serial_wr_char()
487 writel(private_data->write_cached_bytes, in qcom_geni_serial_wr_char()
488 uport->membase + SE_GENI_TX_FIFOn); in qcom_geni_serial_wr_char()
489 private_data->write_cached_bytes_cnt = 0; in qcom_geni_serial_wr_char()
497 struct qcom_geni_private_data *private_data = uport->private_data; in __qcom_geni_serial_console_write()
511 writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG); in __qcom_geni_serial_console_write()
512 writel(M_CMD_DONE_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); in __qcom_geni_serial_console_write()
516 size_t avail = DEF_FIFO_DEPTH_WORDS - DEF_TX_WM; in __qcom_geni_serial_console_write()
527 chars_to_write = min_t(size_t, count - i, avail / 2); in __qcom_geni_serial_console_write()
530 writel(M_TX_FIFO_WATERMARK_EN, uport->membase + in __qcom_geni_serial_console_write()
535 if (private_data->write_cached_bytes_cnt) { in __qcom_geni_serial_console_write()
536 private_data->write_cached_bytes >>= BITS_PER_BYTE * in __qcom_geni_serial_console_write()
537 (BYTES_PER_FIFO_WORD - private_data->write_cached_bytes_cnt); in __qcom_geni_serial_console_write()
538 writel(private_data->write_cached_bytes, in __qcom_geni_serial_console_write()
539 uport->membase + SE_GENI_TX_FIFOn); in __qcom_geni_serial_console_write()
540 private_data->write_cached_bytes_cnt = 0; in __qcom_geni_serial_console_write()
555 WARN_ON(co->index < 0 || co->index >= GENI_UART_CONS_PORTS); in qcom_geni_serial_console_write()
557 port = get_port_from_line(co->index, true); in qcom_geni_serial_console_write()
561 uport = &port->uport; in qcom_geni_serial_console_write()
567 m_irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_console_write()
568 s_irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN); in qcom_geni_serial_console_write()
569 writel(0, uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_console_write()
570 writel(0, uport->membase + SE_GENI_S_IRQ_EN); in qcom_geni_serial_console_write()
574 if (!locked || port->tx_remaining == 0) in qcom_geni_serial_console_write()
584 writel(m_irq_en, uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_console_write()
585 writel(s_irq_en, uport->membase + SE_GENI_S_IRQ_EN); in qcom_geni_serial_console_write()
598 tport = &uport->state->port; in handle_rx_console()
601 int chunk = min_t(int, bytes - i, BYTES_PER_FIFO_WORD); in handle_rx_console()
603 ioread32_rep(uport->membase + SE_GENI_RX_FIFOn, buf, 1); in handle_rx_console()
611 uport->icount.rx++; in handle_rx_console()
612 if (port->brk && buf[c] == 0) { in handle_rx_console()
613 port->brk = false; in handle_rx_console()
637 struct tty_port *tport = &uport->state->port; in handle_rx_uart()
640 ret = tty_insert_flip_string(tport, port->rx_buf, bytes); in handle_rx_uart()
642 dev_err_ratelimited(uport->dev, "failed to push data (%d < %u)\n", in handle_rx_uart()
645 uport->icount.rx += ret; in handle_rx_uart()
651 return !readl(uport->membase + SE_GENI_TX_FIFO_STATUS); in qcom_geni_serial_tx_empty()
662 if (port->tx_dma_addr) { in qcom_geni_serial_stop_tx_dma()
663 geni_se_tx_dma_unprep(&port->se, port->tx_dma_addr, in qcom_geni_serial_stop_tx_dma()
664 port->tx_remaining); in qcom_geni_serial_stop_tx_dma()
665 port->tx_dma_addr = 0; in qcom_geni_serial_stop_tx_dma()
666 port->tx_remaining = 0; in qcom_geni_serial_stop_tx_dma()
669 geni_se_cancel_m_cmd(&port->se); in qcom_geni_serial_stop_tx_dma()
674 geni_se_abort_m_cmd(&port->se); in qcom_geni_serial_stop_tx_dma()
678 dev_err_ratelimited(uport->dev, "M_CMD_ABORT_EN not set"); in qcom_geni_serial_stop_tx_dma()
679 writel(M_CMD_ABORT_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_stop_tx_dma()
682 writel(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_stop_tx_dma()
688 struct tty_port *tport = &uport->state->port; in qcom_geni_serial_start_tx_dma()
693 if (port->tx_dma_addr) in qcom_geni_serial_start_tx_dma()
696 if (kfifo_is_empty(&tport->xmit_fifo)) in qcom_geni_serial_start_tx_dma()
699 xmit_size = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail, in qcom_geni_serial_start_tx_dma()
706 ret = geni_se_tx_dma_prep(&port->se, tail, xmit_size, in qcom_geni_serial_start_tx_dma()
707 &port->tx_dma_addr); in qcom_geni_serial_start_tx_dma()
709 dev_err(uport->dev, "unable to start TX SE DMA: %d\n", ret); in qcom_geni_serial_start_tx_dma()
714 port->tx_remaining = xmit_size; in qcom_geni_serial_start_tx_dma()
730 writel(M_CMD_DONE_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_start_tx_fifo()
732 writel(c, uport->membase + SE_GENI_TX_FIFOn); in qcom_geni_serial_start_tx_fifo()
736 irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_start_tx_fifo()
738 writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG); in qcom_geni_serial_start_tx_fifo()
739 writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_start_tx_fifo()
746 irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_stop_tx_fifo()
748 writel(0, uport->membase + SE_GENI_TX_WATERMARK_REG); in qcom_geni_serial_stop_tx_fifo()
749 writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_stop_tx_fifo()
756 geni_se_cancel_m_cmd(&port->se); in __qcom_geni_serial_cancel_tx_cmd()
759 geni_se_abort_m_cmd(&port->se); in __qcom_geni_serial_cancel_tx_cmd()
762 writel(M_CMD_ABORT_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); in __qcom_geni_serial_cancel_tx_cmd()
764 writel(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); in __qcom_geni_serial_cancel_tx_cmd()
776 port->tx_remaining = 0; in qcom_geni_serial_cancel_tx_cmd()
777 port->tx_queued = 0; in qcom_geni_serial_cancel_tx_cmd()
788 status = readl(uport->membase + SE_GENI_RX_FIFO_STATUS); in qcom_geni_serial_handle_rx_fifo()
796 total_bytes = BYTES_PER_FIFO_WORD * (word_cnt - 1); in qcom_geni_serial_handle_rx_fifo()
810 irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN); in qcom_geni_serial_stop_rx_fifo()
812 writel(irq_en, uport->membase + SE_GENI_S_IRQ_EN); in qcom_geni_serial_stop_rx_fifo()
814 irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_stop_rx_fifo()
816 writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_stop_rx_fifo()
821 geni_se_cancel_s_cmd(&port->se); in qcom_geni_serial_stop_rx_fifo()
828 s_irq_status = readl(uport->membase + SE_GENI_S_IRQ_STATUS); in qcom_geni_serial_stop_rx_fifo()
832 writel(s_irq_status, uport->membase + SE_GENI_S_IRQ_CLEAR); in qcom_geni_serial_stop_rx_fifo()
846 geni_se_setup_s_cmd(&port->se, UART_START_READ, 0); in qcom_geni_serial_start_rx_fifo()
848 irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN); in qcom_geni_serial_start_rx_fifo()
850 writel(irq_en, uport->membase + SE_GENI_S_IRQ_EN); in qcom_geni_serial_start_rx_fifo()
852 irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_start_rx_fifo()
854 writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_start_rx_fifo()
865 geni_se_cancel_s_cmd(&port->se); in qcom_geni_serial_stop_rx_dma()
870 uport->membase + SE_DMA_RX_IRQ_CLR); in qcom_geni_serial_stop_rx_dma()
874 writel(1, uport->membase + SE_DMA_RX_FSM_RST); in qcom_geni_serial_stop_rx_dma()
878 uport->membase + SE_DMA_RX_IRQ_CLR); in qcom_geni_serial_stop_rx_dma()
881 if (port->rx_dma_addr) { in qcom_geni_serial_stop_rx_dma()
882 geni_se_rx_dma_unprep(&port->se, port->rx_dma_addr, in qcom_geni_serial_stop_rx_dma()
884 port->rx_dma_addr = 0; in qcom_geni_serial_stop_rx_dma()
896 geni_se_setup_s_cmd(&port->se, UART_START_READ, UART_PARAM_RFR_OPEN); in qcom_geni_serial_start_rx_dma()
898 ret = geni_se_rx_dma_prep(&port->se, port->rx_buf, in qcom_geni_serial_start_rx_dma()
900 &port->rx_dma_addr); in qcom_geni_serial_start_rx_dma()
902 dev_err(uport->dev, "unable to start RX SE DMA: %d\n", ret); in qcom_geni_serial_start_rx_dma()
916 if (!port->rx_dma_addr) in qcom_geni_serial_handle_rx_dma()
919 geni_se_rx_dma_unprep(&port->se, port->rx_dma_addr, DMA_RX_BUF_SIZE); in qcom_geni_serial_handle_rx_dma()
920 port->rx_dma_addr = 0; in qcom_geni_serial_handle_rx_dma()
922 rx_in = readl(uport->membase + SE_DMA_RX_LEN_IN); in qcom_geni_serial_handle_rx_dma()
924 dev_warn(uport->dev, "serial engine reports 0 RX bytes in!\n"); in qcom_geni_serial_handle_rx_dma()
931 ret = geni_se_rx_dma_prep(&port->se, port->rx_buf, in qcom_geni_serial_handle_rx_dma()
933 &port->rx_dma_addr); in qcom_geni_serial_handle_rx_dma()
935 dev_err(uport->dev, "unable to start RX SE DMA: %d\n", ret); in qcom_geni_serial_handle_rx_dma()
942 uport->ops->start_rx(uport); in qcom_geni_serial_start_rx()
947 uport->ops->stop_rx(uport); in qcom_geni_serial_stop_rx()
952 uport->ops->stop_tx(uport); in qcom_geni_serial_stop_tx()
968 iowrite32_rep(uport->membase + SE_GENI_TX_FIFOn, buf, 1); in qcom_geni_serial_send_chunk_fifo()
970 remaining -= tx_bytes; in qcom_geni_serial_send_chunk_fifo()
971 port->tx_remaining -= tx_bytes; in qcom_geni_serial_send_chunk_fifo()
979 struct tty_port *tport = &uport->state->port; in qcom_geni_serial_handle_tx_fifo()
986 status = readl(uport->membase + SE_GENI_TX_FIFO_STATUS); in qcom_geni_serial_handle_tx_fifo()
990 pending = port->tx_remaining; in qcom_geni_serial_handle_tx_fifo()
992 pending = kfifo_len(&tport->xmit_fifo); in qcom_geni_serial_handle_tx_fifo()
1001 avail = port->tx_fifo_depth - (status & TX_FIFO_WC); in qcom_geni_serial_handle_tx_fifo()
1003 avail = port->tx_fifo_depth; in qcom_geni_serial_handle_tx_fifo()
1013 port->tx_remaining = pending; in qcom_geni_serial_handle_tx_fifo()
1014 port->tx_queued = 0; in qcom_geni_serial_handle_tx_fifo()
1016 irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_handle_tx_fifo()
1019 uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_handle_tx_fifo()
1023 port->tx_queued += chunk; in qcom_geni_serial_handle_tx_fifo()
1031 uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_handle_tx_fifo()
1034 if (!port->tx_remaining) { in qcom_geni_serial_handle_tx_fifo()
1035 irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_handle_tx_fifo()
1038 uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_handle_tx_fifo()
1041 if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS) in qcom_geni_serial_handle_tx_fifo()
1048 struct tty_port *tport = &uport->state->port; in qcom_geni_serial_handle_tx_dma()
1050 uart_xmit_advance(uport, port->tx_remaining); in qcom_geni_serial_handle_tx_dma()
1051 geni_se_tx_dma_unprep(&port->se, port->tx_dma_addr, port->tx_remaining); in qcom_geni_serial_handle_tx_dma()
1052 port->tx_dma_addr = 0; in qcom_geni_serial_handle_tx_dma()
1053 port->tx_remaining = 0; in qcom_geni_serial_handle_tx_dma()
1055 if (!kfifo_is_empty(&tport->xmit_fifo)) in qcom_geni_serial_handle_tx_dma()
1058 if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS) in qcom_geni_serial_handle_tx_dma()
1073 struct tty_port *tport = &uport->state->port; in qcom_geni_serial_isr()
1076 if (uport->suspended) in qcom_geni_serial_isr()
1081 m_irq_status = readl(uport->membase + SE_GENI_M_IRQ_STATUS); in qcom_geni_serial_isr()
1082 s_irq_status = readl(uport->membase + SE_GENI_S_IRQ_STATUS); in qcom_geni_serial_isr()
1083 dma_tx_status = readl(uport->membase + SE_DMA_TX_IRQ_STAT); in qcom_geni_serial_isr()
1084 dma_rx_status = readl(uport->membase + SE_DMA_RX_IRQ_STAT); in qcom_geni_serial_isr()
1085 geni_status = readl(uport->membase + SE_GENI_STATUS); in qcom_geni_serial_isr()
1086 dma = readl(uport->membase + SE_GENI_DMA_MODE_EN); in qcom_geni_serial_isr()
1087 m_irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); in qcom_geni_serial_isr()
1088 writel(m_irq_status, uport->membase + SE_GENI_M_IRQ_CLEAR); in qcom_geni_serial_isr()
1089 writel(s_irq_status, uport->membase + SE_GENI_S_IRQ_CLEAR); in qcom_geni_serial_isr()
1090 writel(dma_tx_status, uport->membase + SE_DMA_TX_IRQ_CLR); in qcom_geni_serial_isr()
1091 writel(dma_rx_status, uport->membase + SE_DMA_RX_IRQ_CLR); in qcom_geni_serial_isr()
1097 uport->icount.overrun++; in qcom_geni_serial_isr()
1103 uport->icount.parity++; in qcom_geni_serial_isr()
1106 uport->icount.brk++; in qcom_geni_serial_isr()
1107 port->brk = true; in qcom_geni_serial_isr()
1121 uport->icount.parity++; in qcom_geni_serial_isr()
1126 uport->icount.brk++; in qcom_geni_serial_isr()
1151 u32 old_rx_fifo_depth = port->rx_fifo_depth; in setup_fifos()
1153 uport = &port->uport; in setup_fifos()
1154 port->tx_fifo_depth = geni_se_get_tx_fifo_depth(&port->se); in setup_fifos()
1155 port->tx_fifo_width = geni_se_get_tx_fifo_width(&port->se); in setup_fifos()
1156 port->rx_fifo_depth = geni_se_get_rx_fifo_depth(&port->se); in setup_fifos()
1157 uport->fifosize = in setup_fifos()
1158 (port->tx_fifo_depth * port->tx_fifo_width) / BITS_PER_BYTE; in setup_fifos()
1160 if (port->rx_buf && (old_rx_fifo_depth != port->rx_fifo_depth) && port->rx_fifo_depth) { in setup_fifos()
1166 port->rx_buf = devm_krealloc(uport->dev, port->rx_buf, in setup_fifos()
1167 port->rx_fifo_depth * sizeof(u32), in setup_fifos()
1169 if (!port->rx_buf) in setup_fifos()
1170 return -ENOMEM; in setup_fifos()
1179 disable_irq(uport->irq); in qcom_geni_serial_shutdown()
1202 proto = geni_se_read_proto(&port->se); in qcom_geni_serial_port_setup()
1204 dev_err(uport->dev, "Invalid FW loaded, proto: %d\n", proto); in qcom_geni_serial_port_setup()
1205 return -ENXIO; in qcom_geni_serial_port_setup()
1214 writel(rxstale, uport->membase + SE_UART_RX_STALE_CNT); in qcom_geni_serial_port_setup()
1216 pin_swap = readl(uport->membase + SE_UART_IO_MACRO_CTRL); in qcom_geni_serial_port_setup()
1217 if (port->rx_tx_swap) { in qcom_geni_serial_port_setup()
1221 if (port->cts_rts_swap) { in qcom_geni_serial_port_setup()
1225 /* Configure this register if RX-TX, CTS-RTS pins are swapped */ in qcom_geni_serial_port_setup()
1226 if (port->rx_tx_swap || port->cts_rts_swap) in qcom_geni_serial_port_setup()
1227 writel(pin_swap, uport->membase + SE_UART_IO_MACRO_CTRL); in qcom_geni_serial_port_setup()
1235 geni_se_config_packing(&port->se, BITS_PER_BYTE, BYTES_PER_FIFO_WORD, in qcom_geni_serial_port_setup()
1237 geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2); in qcom_geni_serial_port_setup()
1238 geni_se_select_mode(&port->se, port->dev_data->mode); in qcom_geni_serial_port_setup()
1239 port->setup = true; in qcom_geni_serial_port_setup()
1249 if (!port->setup) { in qcom_geni_serial_startup()
1259 enable_irq(uport->irq); in qcom_geni_serial_startup()
1281 freq = clk_round_rate(clk, mult - offset); in find_clk_rate_in_tol()
1284 if (freq < mult - offset) in find_clk_rate_in_tol()
1288 * Re-calculate div in case rounding skipped rates but we in find_clk_rate_in_tol()
1294 achieved >= desired_clk - abs_tol) { in find_clk_rate_in_tol()
1336 ver = geni_se_get_qup_hw_version(&port->se); in geni_serial_set_rate()
1340 clk_rate = get_clk_div_rate(port->se.clk, baud, in geni_serial_set_rate()
1343 dev_err(port->se.dev, in geni_serial_set_rate()
1346 return -EINVAL; in geni_serial_set_rate()
1349 dev_dbg(port->se.dev, "desired_rate = %u, clk_rate = %lu, clk_div = %u\n", in geni_serial_set_rate()
1352 uport->uartclk = clk_rate; in geni_serial_set_rate()
1353 port->clk_rate = clk_rate; in geni_serial_set_rate()
1354 dev_pm_opp_set_rate(uport->dev, clk_rate); in geni_serial_set_rate()
1364 port->se.icc_paths[GENI_TO_CORE].avg_bw = avg_bw_core; in geni_serial_set_rate()
1365 port->se.icc_paths[CPU_TO_GENI].avg_bw = Bps_to_icc(baud); in geni_serial_set_rate()
1366 geni_icc_set_bw(&port->se); in geni_serial_set_rate()
1368 writel(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG); in geni_serial_set_rate()
1369 writel(ser_clk_cfg, uport->membase + GENI_SER_S_CLK_CFG); in geni_serial_set_rate()
1376 struct device *perf_dev = port->pd_list->pd_devs[DOMAIN_IDX_PERF]; in geni_serial_set_level()
1384 * +---------------------+--------------------+ in geni_serial_set_level()
1386 * +---------------------+--------------------+ in geni_serial_set_level()
1403 * +---------------------+--------------------+ in geni_serial_set_level()
1427 ret = port->dev_data->set_rate(uport, baud); in qcom_geni_serial_set_termios()
1432 tx_trans_cfg = readl(uport->membase + SE_UART_TX_TRANS_CFG); in qcom_geni_serial_set_termios()
1433 tx_parity_cfg = readl(uport->membase + SE_UART_TX_PARITY_CFG); in qcom_geni_serial_set_termios()
1434 rx_trans_cfg = readl(uport->membase + SE_UART_RX_TRANS_CFG); in qcom_geni_serial_set_termios()
1435 rx_parity_cfg = readl(uport->membase + SE_UART_RX_PARITY_CFG); in qcom_geni_serial_set_termios()
1436 if (termios->c_cflag & PARENB) { in qcom_geni_serial_set_termios()
1441 if (termios->c_cflag & PARODD) { in qcom_geni_serial_set_termios()
1444 } else if (termios->c_cflag & CMSPAR) { in qcom_geni_serial_set_termios()
1459 bits_per_char = tty_get_char_size(termios->c_cflag); in qcom_geni_serial_set_termios()
1462 if (termios->c_cflag & CSTOPB) in qcom_geni_serial_set_termios()
1468 if (termios->c_cflag & CRTSCTS) in qcom_geni_serial_set_termios()
1474 uart_update_timeout(uport, termios->c_cflag, baud); in qcom_geni_serial_set_termios()
1478 * the FIFO, two-word intermediate transfer register and shift in qcom_geni_serial_set_termios()
1484 timeout += 3 * timeout / port->tx_fifo_depth; in qcom_geni_serial_set_termios()
1485 WRITE_ONCE(port->poll_timeout_us, timeout); in qcom_geni_serial_set_termios()
1489 writel(port->loopback, in qcom_geni_serial_set_termios()
1490 uport->membase + SE_UART_LOOPBACK_CFG); in qcom_geni_serial_set_termios()
1491 writel(tx_trans_cfg, uport->membase + SE_UART_TX_TRANS_CFG); in qcom_geni_serial_set_termios()
1492 writel(tx_parity_cfg, uport->membase + SE_UART_TX_PARITY_CFG); in qcom_geni_serial_set_termios()
1493 writel(rx_trans_cfg, uport->membase + SE_UART_RX_TRANS_CFG); in qcom_geni_serial_set_termios()
1494 writel(rx_parity_cfg, uport->membase + SE_UART_RX_PARITY_CFG); in qcom_geni_serial_set_termios()
1495 writel(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN); in qcom_geni_serial_set_termios()
1496 writel(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN); in qcom_geni_serial_set_termios()
1497 writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN); in qcom_geni_serial_set_termios()
1511 if (co->index >= GENI_UART_CONS_PORTS || co->index < 0) in qcom_geni_console_setup()
1512 return -ENXIO; in qcom_geni_console_setup()
1514 port = get_port_from_line(co->index, true); in qcom_geni_console_setup()
1516 pr_err("Invalid line %d\n", co->index); in qcom_geni_console_setup()
1520 uport = &port->uport; in qcom_geni_console_setup()
1522 if (unlikely(!uport->membase)) in qcom_geni_console_setup()
1523 return -ENXIO; in qcom_geni_console_setup()
1525 if (!port->setup) { in qcom_geni_console_setup()
1540 struct earlycon_device *dev = con->data; in qcom_geni_serial_earlycon_write()
1542 __qcom_geni_serial_console_write(&dev->port, s, n); in qcom_geni_serial_earlycon_write()
1549 struct earlycon_device *dev = con->data; in qcom_geni_serial_earlycon_read()
1550 struct uart_port *uport = &dev->port; in qcom_geni_serial_earlycon_read()
1564 static void __init qcom_geni_serial_enable_early_read(struct geni_se *se, in qcom_geni_serial_enable_early_read() argument
1567 geni_se_setup_s_cmd(se, UART_START_READ, 0); in qcom_geni_serial_enable_early_read()
1568 con->read = qcom_geni_serial_earlycon_read; in qcom_geni_serial_enable_early_read()
1571 static inline void qcom_geni_serial_enable_early_read(struct geni_se *se, in qcom_geni_serial_enable_early_read() argument
1580 struct uart_port *uport = &dev->port; in qcom_geni_serial_earlycon_setup()
1585 u32 stop_bit_len = 0; /* Default stop bit length - 1 bit */ in qcom_geni_serial_earlycon_setup()
1587 struct geni_se se; in qcom_geni_serial_earlycon_setup() local
1589 if (!uport->membase) in qcom_geni_serial_earlycon_setup()
1590 return -EINVAL; in qcom_geni_serial_earlycon_setup()
1592 uport->private_data = &earlycon_private_data; in qcom_geni_serial_earlycon_setup()
1594 memset(&se, 0, sizeof(se)); in qcom_geni_serial_earlycon_setup()
1595 se.base = uport->membase; in qcom_geni_serial_earlycon_setup()
1596 if (geni_se_read_proto(&se) != GENI_SE_UART) in qcom_geni_serial_earlycon_setup()
1597 return -ENXIO; in qcom_geni_serial_earlycon_setup()
1611 geni_se_config_packing(&se, BITS_PER_BYTE, BYTES_PER_FIFO_WORD, in qcom_geni_serial_earlycon_setup()
1613 geni_se_init(&se, DEF_FIFO_DEPTH_WORDS / 2, DEF_FIFO_DEPTH_WORDS - 2); in qcom_geni_serial_earlycon_setup()
1614 geni_se_select_mode(&se, GENI_SE_FIFO); in qcom_geni_serial_earlycon_setup()
1616 writel(tx_trans_cfg, uport->membase + SE_UART_TX_TRANS_CFG); in qcom_geni_serial_earlycon_setup()
1617 writel(tx_parity_cfg, uport->membase + SE_UART_TX_PARITY_CFG); in qcom_geni_serial_earlycon_setup()
1618 writel(rx_trans_cfg, uport->membase + SE_UART_RX_TRANS_CFG); in qcom_geni_serial_earlycon_setup()
1619 writel(rx_parity_cfg, uport->membase + SE_UART_RX_PARITY_CFG); in qcom_geni_serial_earlycon_setup()
1620 writel(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN); in qcom_geni_serial_earlycon_setup()
1621 writel(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN); in qcom_geni_serial_earlycon_setup()
1622 writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN); in qcom_geni_serial_earlycon_setup()
1624 dev->con->write = qcom_geni_serial_earlycon_write; in qcom_geni_serial_earlycon_setup()
1625 dev->con->setup = NULL; in qcom_geni_serial_earlycon_setup()
1626 qcom_geni_serial_enable_early_read(&se, dev->con); in qcom_geni_serial_earlycon_setup()
1630 OF_EARLYCON_DECLARE(qcom_geni, "qcom,geni-debug-uart",
1649 .index = -1,
1683 ret = geni_icc_enable(&port->se); in geni_serial_resources_on()
1687 ret = geni_se_resources_on(&port->se); in geni_serial_resources_on()
1689 geni_icc_disable(&port->se); in geni_serial_resources_on()
1693 if (port->clk_rate) in geni_serial_resources_on()
1694 dev_pm_opp_set_rate(uport->dev, port->clk_rate); in geni_serial_resources_on()
1704 dev_pm_opp_set_rate(uport->dev, 0); in geni_serial_resources_off()
1705 ret = geni_se_resources_off(&port->se); in geni_serial_resources_off()
1709 geni_icc_disable(&port->se); in geni_serial_resources_off()
1724 ret = dev_pm_domain_attach_list(port->se.dev, in geni_serial_pwr_init()
1725 &port->dev_data->pd_data, &port->pd_list); in geni_serial_pwr_init()
1727 return -EINVAL; in geni_serial_pwr_init()
1737 port->se.clk = devm_clk_get(port->se.dev, "se"); in geni_serial_resource_init()
1738 if (IS_ERR(port->se.clk)) { in geni_serial_resource_init()
1739 ret = PTR_ERR(port->se.clk); in geni_serial_resource_init()
1740 dev_err(port->se.dev, "Err getting SE Core clk %d\n", ret); in geni_serial_resource_init()
1744 ret = geni_icc_get(&port->se, NULL); in geni_serial_resource_init()
1748 port->se.icc_paths[GENI_TO_CORE].avg_bw = GENI_DEFAULT_BW; in geni_serial_resource_init()
1749 port->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW; in geni_serial_resource_init()
1752 ret = geni_icc_set_bw(&port->se); in geni_serial_resource_init()
1756 ret = devm_pm_opp_set_clkname(port->se.dev, "se"); in geni_serial_resource_init()
1761 ret = devm_pm_opp_of_add_table(port->se.dev); in geni_serial_resource_init()
1762 if (ret && ret != -ENODEV) { in geni_serial_resource_init()
1763 dev_err(port->se.dev, "invalid OPP table in device tree\n"); in geni_serial_resource_init()
1779 pm_runtime_resume_and_get(uport->dev); in qcom_geni_serial_pm()
1782 pm_runtime_put_sync(uport->dev); in qcom_geni_serial_pm()
1787 * qcom_geni_rs485_config - Configure RS485 settings for the UART port
1855 data = of_device_get_match_data(&pdev->dev); in qcom_geni_serial_probe()
1857 return -EINVAL; in qcom_geni_serial_probe()
1859 if (data->console) { in qcom_geni_serial_probe()
1861 line = of_alias_get_id(pdev->dev.of_node, "serial"); in qcom_geni_serial_probe()
1864 line = of_alias_get_id(pdev->dev.of_node, "serial"); in qcom_geni_serial_probe()
1865 if (line == -ENODEV) /* compat with non-standard aliases */ in qcom_geni_serial_probe()
1866 line = of_alias_get_id(pdev->dev.of_node, "hsuart"); in qcom_geni_serial_probe()
1869 port = get_port_from_line(line, data->console); in qcom_geni_serial_probe()
1871 dev_err(&pdev->dev, "Invalid line %d\n", line); in qcom_geni_serial_probe()
1875 uport = &port->uport; in qcom_geni_serial_probe()
1877 if (uport->private_data) in qcom_geni_serial_probe()
1878 return -ENODEV; in qcom_geni_serial_probe()
1880 uport->dev = &pdev->dev; in qcom_geni_serial_probe()
1881 port->dev_data = data; in qcom_geni_serial_probe()
1882 port->se.dev = &pdev->dev; in qcom_geni_serial_probe()
1883 port->se.wrapper = dev_get_drvdata(pdev->dev.parent); in qcom_geni_serial_probe()
1885 ret = port->dev_data->resources_init(uport); in qcom_geni_serial_probe()
1891 ret = -EINVAL; in qcom_geni_serial_probe()
1895 uport->mapbase = res->start; in qcom_geni_serial_probe()
1897 uport->rs485_config = qcom_geni_rs485_config; in qcom_geni_serial_probe()
1898 uport->rs485_supported = qcom_geni_rs485_supported; in qcom_geni_serial_probe()
1899 port->tx_fifo_depth = DEF_FIFO_DEPTH_WORDS; in qcom_geni_serial_probe()
1900 port->rx_fifo_depth = DEF_FIFO_DEPTH_WORDS; in qcom_geni_serial_probe()
1901 port->tx_fifo_width = DEF_FIFO_WIDTH_BITS; in qcom_geni_serial_probe()
1903 if (!data->console) { in qcom_geni_serial_probe()
1904 port->rx_buf = devm_kzalloc(uport->dev, in qcom_geni_serial_probe()
1906 if (!port->rx_buf) { in qcom_geni_serial_probe()
1907 ret = -ENOMEM; in qcom_geni_serial_probe()
1912 port->name = devm_kasprintf(uport->dev, GFP_KERNEL, in qcom_geni_serial_probe()
1914 uart_console(uport) ? "console" : "uart", uport->line); in qcom_geni_serial_probe()
1915 if (!port->name) { in qcom_geni_serial_probe()
1916 ret = -ENOMEM; in qcom_geni_serial_probe()
1926 uport->irq = irq; in qcom_geni_serial_probe()
1927 uport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_QCOM_GENI_CONSOLE); in qcom_geni_serial_probe()
1929 if (!data->console) in qcom_geni_serial_probe()
1930 port->wakeup_irq = platform_get_irq_optional(pdev, 1); in qcom_geni_serial_probe()
1932 if (of_property_read_bool(pdev->dev.of_node, "rx-tx-swap")) in qcom_geni_serial_probe()
1933 port->rx_tx_swap = true; in qcom_geni_serial_probe()
1935 if (of_property_read_bool(pdev->dev.of_node, "cts-rts-swap")) in qcom_geni_serial_probe()
1936 port->cts_rts_swap = true; in qcom_geni_serial_probe()
1938 port->private_data.drv = drv; in qcom_geni_serial_probe()
1939 uport->private_data = &port->private_data; in qcom_geni_serial_probe()
1942 irq_set_status_flags(uport->irq, IRQ_NOAUTOEN); in qcom_geni_serial_probe()
1943 ret = devm_request_irq(uport->dev, uport->irq, qcom_geni_serial_isr, in qcom_geni_serial_probe()
1944 IRQF_TRIGGER_HIGH, port->name, uport); in qcom_geni_serial_probe()
1946 dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret); in qcom_geni_serial_probe()
1954 devm_pm_runtime_enable(port->se.dev); in qcom_geni_serial_probe()
1960 if (port->wakeup_irq > 0) { in qcom_geni_serial_probe()
1961 device_init_wakeup(&pdev->dev, true); in qcom_geni_serial_probe()
1962 ret = dev_pm_set_dedicated_wake_irq(&pdev->dev, in qcom_geni_serial_probe()
1963 port->wakeup_irq); in qcom_geni_serial_probe()
1965 device_init_wakeup(&pdev->dev, false); in qcom_geni_serial_probe()
1966 ida_free(&port_ida, uport->line); in qcom_geni_serial_probe()
1975 dev_pm_domain_detach_list(port->pd_list); in qcom_geni_serial_probe()
1982 struct uart_port *uport = &port->uport; in qcom_geni_serial_remove()
1983 struct uart_driver *drv = port->private_data.drv; in qcom_geni_serial_remove()
1985 dev_pm_clear_wake_irq(&pdev->dev); in qcom_geni_serial_remove()
1986 device_init_wakeup(&pdev->dev, false); in qcom_geni_serial_remove()
1987 ida_free(&port_ida, uport->line); in qcom_geni_serial_remove()
1988 uart_remove_one_port(drv, &port->uport); in qcom_geni_serial_remove()
1989 dev_pm_domain_detach_list(port->pd_list); in qcom_geni_serial_remove()
1995 struct uart_port *uport = &port->uport; in qcom_geni_serial_runtime_suspend()
1998 if (port->dev_data->power_state) in qcom_geni_serial_runtime_suspend()
1999 ret = port->dev_data->power_state(uport, false); in qcom_geni_serial_runtime_suspend()
2007 struct uart_port *uport = &port->uport; in qcom_geni_serial_runtime_resume()
2010 if (port->dev_data->power_state) in qcom_geni_serial_runtime_resume()
2011 ret = port->dev_data->power_state(uport, true); in qcom_geni_serial_runtime_resume()
2019 struct uart_port *uport = &port->uport; in qcom_geni_serial_suspend()
2020 struct qcom_geni_private_data *private_data = uport->private_data; in qcom_geni_serial_suspend()
2027 geni_icc_set_tag(&port->se, QCOM_ICC_TAG_ACTIVE_ONLY); in qcom_geni_serial_suspend()
2028 geni_icc_set_bw(&port->se); in qcom_geni_serial_suspend()
2030 return uart_suspend_port(private_data->drv, uport); in qcom_geni_serial_suspend()
2037 struct uart_port *uport = &port->uport; in qcom_geni_serial_resume()
2038 struct qcom_geni_private_data *private_data = uport->private_data; in qcom_geni_serial_resume()
2040 ret = uart_resume_port(private_data->drv, uport); in qcom_geni_serial_resume()
2042 geni_icc_set_tag(&port->se, QCOM_ICC_TAG_ALWAYS); in qcom_geni_serial_resume()
2043 geni_icc_set_bw(&port->se); in qcom_geni_serial_resume()
2096 .compatible = "qcom,geni-debug-uart",
2100 .compatible = "qcom,sa8255p-geni-debug-uart",
2104 .compatible = "qcom,geni-uart",
2108 .compatible = "qcom,sa8255p-geni-uart",
2156 MODULE_DESCRIPTION("Serial driver for GENI based QUP cores");