Skip to content

Commit 9fa3c4b

Browse files
Roja Rani Yarubandigregkh
authored andcommitted
tty: serial: qcom_geni_serial: Fix GPIO swapping with workaround
Add capability to support RX-TX, CTS-RTS pins swap in HW. Configure UART_IO_MACRO_CTRL register accordingly if RX-TX pair or CTS-RTS pair or both pairs swapped. Signed-off-by: Roja Rani Yarubandi <[email protected]> Reviewed-by: Stephen Boyd <[email protected]> Tested-by: Matthias Kaehlcke <[email protected]> Reviewed-by: Matthias Kaehlcke <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 97cbaf2 commit 9fa3c4b

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

drivers/tty/serial/qcom_geni_serial.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
/* UART specific GENI registers */
2323
#define SE_UART_LOOPBACK_CFG 0x22c
24+
#define SE_UART_IO_MACRO_CTRL 0x240
2425
#define SE_UART_TX_TRANS_CFG 0x25c
2526
#define SE_UART_TX_WORD_LEN 0x268
2627
#define SE_UART_TX_STOP_BIT_LEN 0x26c
@@ -95,6 +96,12 @@
9596
#define CTS_RTS_SORTED BIT(1)
9697
#define RX_TX_CTS_RTS_SORTED (RX_TX_SORTED | CTS_RTS_SORTED)
9798

99+
/* UART pin swap value */
100+
#define DEFAULT_IO_MACRO_IO0_IO1_MASK GENMASK(3, 0)
101+
#define IO_MACRO_IO0_SEL 0x3
102+
#define DEFAULT_IO_MACRO_IO2_IO3_MASK GENMASK(15, 4)
103+
#define IO_MACRO_IO2_IO3_SWAP 0x4640
104+
98105
#ifdef CONFIG_CONSOLE_POLL
99106
#define CONSOLE_RX_BYTES_PW 1
100107
#else
@@ -119,6 +126,8 @@ struct qcom_geni_serial_port {
119126

120127
unsigned int tx_remaining;
121128
int wakeup_irq;
129+
bool rx_tx_swap;
130+
bool cts_rts_swap;
122131
};
123132

124133
static const struct uart_ops qcom_geni_console_pops;
@@ -836,6 +845,7 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
836845
struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
837846
u32 rxstale = DEFAULT_BITS_PER_CHAR * STALE_TIMEOUT;
838847
u32 proto;
848+
u32 pin_swap;
839849

840850
if (uart_console(uport)) {
841851
port->tx_bytes_pw = 1;
@@ -856,6 +866,20 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
856866
get_tx_fifo_size(port);
857867

858868
writel(rxstale, uport->membase + SE_UART_RX_STALE_CNT);
869+
870+
pin_swap = readl(uport->membase + SE_UART_IO_MACRO_CTRL);
871+
if (port->rx_tx_swap) {
872+
pin_swap &= ~DEFAULT_IO_MACRO_IO2_IO3_MASK;
873+
pin_swap |= IO_MACRO_IO2_IO3_SWAP;
874+
}
875+
if (port->cts_rts_swap) {
876+
pin_swap &= ~DEFAULT_IO_MACRO_IO0_IO1_MASK;
877+
pin_swap |= IO_MACRO_IO0_SEL;
878+
}
879+
/* Configure this register if RX-TX, CTS-RTS pins are swapped */
880+
if (port->rx_tx_swap || port->cts_rts_swap)
881+
writel(pin_swap, uport->membase + SE_UART_IO_MACRO_CTRL);
882+
859883
/*
860884
* Make an unconditional cancel on the main sequencer to reset
861885
* it else we could end up in data loss scenarios.
@@ -1299,6 +1323,12 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
12991323
if (!console)
13001324
port->wakeup_irq = platform_get_irq_optional(pdev, 1);
13011325

1326+
if (of_property_read_bool(pdev->dev.of_node, "rx-tx-swap"))
1327+
port->rx_tx_swap = true;
1328+
1329+
if (of_property_read_bool(pdev->dev.of_node, "cts-rts-swap"))
1330+
port->cts_rts_swap = true;
1331+
13021332
uport->private_data = drv;
13031333
platform_set_drvdata(pdev, port);
13041334
port->handle_rx = console ? handle_rx_console : handle_rx_uart;

0 commit comments

Comments
 (0)