Message ID | 20220214213020.685-1-tharvey@gateworks.com |
---|---|
State | New |
Headers | show |
Series | serial: imx: leave IRTS disabled if using modem-control CTS | expand |
On 14.02.2022 22:30, Tim Harvey wrote: > If using modem-control gpios for CTS we must leave IRTS disabled > as otherwise the hardware will only transmit based on the internal RTS > pin routed to it. > > This allows hardware flow control to be used with cts-gpios. This hardware flow control sounds quite limited. Once CTS becomes inactive, the transmitter will still output all characters from TxFIFO. Transmitting whole TxFIFO already sounds quite bad, but that's the best case scenario where gpio interrupt is handled right away without any delay (so more than TxFIFO characters can actually be transmitted). Does the internal RTS default to inactive when it's not pinmuxed to the actual pin? If so, then controlling UCR2_IRTS based on CTS gpio could halt the transmission when the TxFIFO is not empty. Best Regards, Tomasz Mon
On Mon, Feb 14, 2022 at 10:03 PM Tomasz Moń <tomasz.mon@camlingroup.com> wrote: > > On 14.02.2022 22:30, Tim Harvey wrote: > > If using modem-control gpios for CTS we must leave IRTS disabled > > as otherwise the hardware will only transmit based on the internal RTS > > pin routed to it. > > > > This allows hardware flow control to be used with cts-gpios. > > This hardware flow control sounds quite limited. Once CTS becomes > inactive, the transmitter will still output all characters from TxFIFO. > Transmitting whole TxFIFO already sounds quite bad, but that's the best > case scenario where gpio interrupt is handled right away without any > delay (so more than TxFIFO characters can actually be transmitted). > > Does the internal RTS default to inactive when it's not pinmuxed to the > actual pin? If so, then controlling UCR2_IRTS based on CTS gpio could > halt the transmission when the TxFIFO is not empty. > Tomasz, I agree that the increased latency makes using a GPIO for CTS (software controlled) not as good as one pinmuxed into the UART block directly (hardware controlled) but without this patch GPIO for CTS does not work at all because the internal RTS defaults to inactive when its not pinmuxed. For many applications the latency is not an issue. Best Regards, Tim
On 15.02.2022 18:26, Tim Harvey wrote: > On Mon, Feb 14, 2022 at 10:03 PM Tomasz Moń <tomasz.mon@camlingroup.com> wrote: >> This hardware flow control sounds quite limited. Once CTS becomes >> inactive, the transmitter will still output all characters from TxFIFO. >> Transmitting whole TxFIFO already sounds quite bad, but that's the best >> case scenario where gpio interrupt is handled right away without any >> delay (so more than TxFIFO characters can actually be transmitted). >> >> Does the internal RTS default to inactive when it's not pinmuxed to the >> actual pin? If so, then controlling UCR2_IRTS based on CTS gpio could >> halt the transmission when the TxFIFO is not empty. >>> I agree that the increased latency makes using a GPIO for CTS > (software controlled) not as good as one pinmuxed into the UART block > directly (hardware controlled) but without this patch GPIO for CTS > does not work at all because the internal RTS defaults to inactive > when its not pinmuxed. For many applications the latency is not an > issue. I think I didn't write the message clear enough. I agree, that the GPIO handling time is something the user has to accept. Usually this part alone is not that bad though, as many receivers are capable of receiving more than one character after deasserting their RTS output (transmitter CTS input). The general expectation is that the transmitter will output maximum one more character *after* CTS GPIO change is handled by software. This is not the case with current version of the patch. With current version of the patch, after CTS GPIO handler finishes, the UART will continue to transmit up to 32 characters if not using DMA. When DMA is active it is much worse, as it will keep transmitting all data already submitted to dmaengine. As the internal RTS defaults to inactive when its not pinmuxed, the software is able to freeze the TxFIFO (and thus DMA if enabled). To freeze TxFIFO when using CTS GPIO, the software has to clear IRTS bit in UCR2 register. Setting IRTS will thaw the TxFIFO. Best Regards, Tomasz Mon
On Tue, Feb 15, 2022 at 9:45 PM Tomasz Moń <tomasz.mon@camlingroup.com> wrote: > > On 15.02.2022 18:26, Tim Harvey wrote: > > On Mon, Feb 14, 2022 at 10:03 PM Tomasz Moń <tomasz.mon@camlingroup.com> wrote: > >> This hardware flow control sounds quite limited. Once CTS becomes > >> inactive, the transmitter will still output all characters from TxFIFO. > >> Transmitting whole TxFIFO already sounds quite bad, but that's the best > >> case scenario where gpio interrupt is handled right away without any > >> delay (so more than TxFIFO characters can actually be transmitted). > >> > >> Does the internal RTS default to inactive when it's not pinmuxed to the > >> actual pin? If so, then controlling UCR2_IRTS based on CTS gpio could > >> halt the transmission when the TxFIFO is not empty. > >>> I agree that the increased latency makes using a GPIO for CTS > > (software controlled) not as good as one pinmuxed into the UART block > > directly (hardware controlled) but without this patch GPIO for CTS > > does not work at all because the internal RTS defaults to inactive > > when its not pinmuxed. For many applications the latency is not an > > issue. > > I think I didn't write the message clear enough. I agree, that the GPIO > handling time is something the user has to accept. Usually this part > alone is not that bad though, as many receivers are capable of receiving > more than one character after deasserting their RTS output (transmitter > CTS input). > > The general expectation is that the transmitter will output maximum one > more character *after* CTS GPIO change is handled by software. This is > not the case with current version of the patch. > > With current version of the patch, after CTS GPIO handler finishes, the > UART will continue to transmit up to 32 characters if not using DMA. > When DMA is active it is much worse, as it will keep transmitting all > data already submitted to dmaengine. > > As the internal RTS defaults to inactive when its not pinmuxed, the > software is able to freeze the TxFIFO (and thus DMA if enabled). To > freeze TxFIFO when using CTS GPIO, the software has to clear IRTS bit in > UCR2 register. Setting IRTS will thaw the TxFIFO. > Tomasz, Ok - I understand what you are saying. Yes, I should be able to use IRTS to freeze/thaw the transmitter based on it being inactive when not pinmuxed. I will work on a v2. Thanks for the explanation! Best Regards, Tim
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index df8a0c8b8b29..bf2bb987a51f 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -201,6 +201,7 @@ struct imx_port { unsigned int old_status; unsigned int have_rtscts:1; unsigned int have_rtsgpio:1; + unsigned int have_ctsgpio:1; unsigned int dte_mode:1; unsigned int inverted_tx:1; unsigned int inverted_rx:1; @@ -1674,8 +1675,7 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios, if (ucr2 & UCR2_CTS) ucr2 |= UCR2_CTSC; } - - if (termios->c_cflag & CRTSCTS) + if (!sport->have_ctsgpio && termios->c_cflag & CRTSCTS) ucr2 &= ~UCR2_IRTS; if (termios->c_cflag & CSTOPB) ucr2 |= UCR2_STPB; @@ -2227,6 +2227,9 @@ static int imx_uart_probe(struct platform_device *pdev) if (of_get_property(np, "fsl,dte-mode", NULL)) sport->dte_mode = 1; + if (of_get_property(np, "cts-gpios", NULL)) + sport->have_ctsgpio = 1; + if (of_get_property(np, "rts-gpios", NULL)) sport->have_rtsgpio = 1;
If using modem-control gpios for CTS we must leave IRTS disabled as otherwise the hardware will only transmit based on the internal RTS pin routed to it. This allows hardware flow control to be used with cts-gpios. Signed-off-by: Tim Harvey <tharvey@gateworks.com> --- drivers/tty/serial/imx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)