There are 8 UART ports on i.mx6ul and one uniform Linux driver for these UARTs. Form UART1~UART6, there is no special operation or attention to use them. But for UART7/UART8, there is a special rule to enable them.
According to i.mx6ul RM, we can see UART7/8 RTS pins are muxed with ENET TX_CLK pins. When SION bit of ENET_TX_CLK is set, we need switch to other MUX mode as input signal for UARTx_RTS. Otherwise, UARTx_RTS will be interrupted by loopback ENET clock signal. So we should set IOMUXC_UART7_RTS_B_SELECT_INPUT and IOMUXC_UART8_RTS_B_SELECT_INPUT registers to 0x2/03 to avoid ENET clock's conflict no matter whether we enable UART7/8 RTS/CTS function or not.
Let's summarize the different scenarios to enable UART7/8 as follows:
1. ENET driver is disabled and UART7/8 is enabled. There is no special operation to do, just use UART7/8 like other UARTs
2. ENET and UART7/8 are both enabled. There are two use models, RTS/CTS enabled or disabled.
2a. If we enable RTS/CTS feature and configure RTS/CTS pins in the device tree, of course, we should avoid the conflict between UART CTS/RTS pins and ENET TX_CLK pins. There is no special operation to do becuase your RTS/CTS device tree would automatically set IOMUXC_UART7_RTS_B_SELECT_INPUT/ IOMUXC_UART8_RTS_B_SELECT_INPUT register to correct value.
2b. If we don't enable RTS/CTS feature and no RTS/CTS pin configuration in devcie tree, we should manually add code to set IOMUXC_UART7_RTS_B_SELECT_INPUT/ IOMUXC_UART8_RTS_B_SELECT_INPUT register because the default value is 0x0(ENETx_TX_CLK_ALT1)
Here is an example to show how to use UART7 on EVK board in scenario 2b.
1. modify imx6ul-14x14-evk.dts to enable UART7
a. remove all LCD settings to disable lcdif because we configure UART7 TX/RX pin pad to LCD data line
b. add UART7 related settings
&uart7 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart7>;
status = "okay";
};
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog_1>;
....
pinctrl_uart7: uart7grp {
fsl,pins = <
MX6UL_PAD_LCD_DATA16__UART7_DCE_TX 0x1b0b1
MX6UL_PAD_LCD_DATA17__UART7_DCE_RX 0x1b0b1
>;
};
2. add code to set IOMUXC_UART7_RTS_B_SELECT_INPUT register in arch/arm/mach-imx/mach-imx6ul.c
static void __init imx6ul_init_machine(void)
{
struct device *parent;
void __iomem *iomux;
struct device_node *np;
...........
imx6ul_pm_init();
np = of_find_compatible_node(NULL,NULL,"fsl,imx6ul-iomuxc");
iomux = of_iomap(np, 0);
writel_relaxed(0x2,iomux+0x650);
}
3. build zImage and imx6ul-14x14-evk.dtb
4. Test in linux console
root@imx6ulevk: ls /dev/ttymxc* //you can see ttymxc6 is in the list
root@imx6ulevk: echo hello > /dev/ttymxc6
root@imx6ulevk: