On Thu, Jan 6, 2022 at 3:55 PM Tim Harvey <tharvey@xxxxxxxxxxxxx> wrote: > > Greetings, > > I have long used modem control lines via GPIO with the IMX driver for > RS485 via rts-gpios in the scenario where an RS485 transceiver > transmit enable is connected to a GPIO representing RTS. > > Therefore I 'thought' that one could use rts-gpios and cts-gpios for > hardware flow control on an IMX UART but it appears I may be wrong as > when I define those along with 'uart-has-rtscts' UART communication > ceases between the IMX and a device using hardware flow control. > > As an example take the following which describes a UART with RTSCTS > flow control connected to a broadcom Bluetooth HCI radio: > > The following works: > &uart4 { > pinctrl-names = "default"; > pinctrl-0 = <&pinctrl_uart4>,<&pinctrl_bten>; > uart-has-rtscts; > status = "okay"; > > bluetooth { > compatible = "brcm,bcm4330-bt"; > shutdown-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; > }; > }; > > &iomuxc { > pinctrl_bten: btengrp { > fsl,pins = < > MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b1 > >; > }; > > pinctrl_uart4: uart4grp { > fsl,pins = < > MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b1 > MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1b0b1 > MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B 0x1b0b1 > MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B 0x1b0b1 > >; > }; > }; > > The following where I've replaced the RTS/CTS with gpio does not work: > &uart4 { > pinctrl-names = "default"; > pinctrl-0 = <&pinctrl_uart4>,<&pinctrl_bten>; > rts-gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; > cts-gpios = <&gpio6 3 GPIO_ACTIVE_LOW>; > uart-has-rtscts; > status = "okay"; > > bluetooth { > compatible = "brcm,bcm4330-bt"; > shutdown-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; > }; > }; > > &iomuxc { > pinctrl_bten: btengrp { > fsl,pins = < > MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b1 > >; > }; > > pinctrl_uart4: uart4grp { > fsl,pins = < > MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b1 > MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1b0b1 > MX6QDL_PAD_CSI0_DAT16__GPIO6_IO02 0x1b0b1 > MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03 0x1b0b1 > >; > }; > }; > > In the above example of course I could simply use the version that > works but the reason I want to use rts-gpios and cts-gpios is that I > have cases where I don't have access to the RTS/CTS pinmux options and > thus can only use gpio's. > > I'm hoping perhaps I just have something misconfigured or that perhaps > something simple is missing from drivers/tty/serial/imx.c in order to > use gpio's as hardware flow control. I've tried flipping the rts/cts > gpios and polarity in case I had something simply backwards but that > still did not work. > > Any ideas or suggestions? > > Best regards, > > Tim Adding some previous main committers to imx uart driver and mctrl feature to cc. >From looking over drivers/tty/serial/imx.c, serial_core.c, and serial_mctrl_gpio.c I see that rts-gpios is the 'output' from the IMX so I need to flip my gpios as: cts-gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; // input to IMX from BT_UART_RTS_L output on brcm chip rts-gpios = <&gpio6 3 GPIO_ACTIVE_LOW>; // output from IMX to BT_UART_CTS_L input on brcm chip I see the following happening when the brcm bluetooth uart driver initializes: mctrl_gpio_init registers irq handler for cts gpio (gpio6 2) mctrl_gpio_init configures output for rts gpio (gpio6 3) uart_change_speed is called and sets CRTSCTS enabled and calls stop_tx (imx_uart_stop_tx) mctrl_gpio_irq_handle is called and it sees CTS=1 then calls uart_handle_cts_change which calls start_tx So I believe the CTS input is handled correctly but I see nothing that asserts the RTS output. The imx.c driver has imx_uart_rts_active and imx_uart_rts_inactive which call mctrl_gpio_set to manipulate the RTS output yet this is only done when the UART is configured for RS485 mode to handle the case where RTS is used as an output to enable the RS485 transmit enable. So I believe in order to support using gpios for rts/cts in the imx uart driver I must find the right place to call imx_uart_rts_active and imx_uart_rts_inactive when the FIFO is not full and full respectively. I'm not that familiar with the Linux uart driver framework - am I on the right track and if so any ideas where this is best done? Best Regards, Tim