UART1 RTS active-low imx6dl BSP 6.5.0 / imx7 BSP 6.6.0

Hello,

I have been working with BSP 6.5.0 upstream reference image on iMX6DL colibri.

I am trying to use UART1 with RS485 mode and rts-active-low.

If I use the following dts overlay the kernel won’t boot.
Uboot is able to load the dts and apply the overlays without errors, then the last message on the console is “Starting kernel …”


&iomuxc {

   pinctrl_uart1_my: uart1grp-my {
        fsl,pins = <
            MX6QDL_PAD_CSI0_DAT10__UART1_RX_DATA 0x1b0b1
            MX6QDL_PAD_CSI0_DAT11__UART1_TX_DATA 0x1b0b1
            MX6QDL_PAD_EIM_D19__UART1_RTS_B 0x1b0b1
            MX6QDL_PAD_EIM_D20__UART1_CTS_B 0x1b0b1
        >;
   };
};

&uart1 {
    pinctrl-0 = <&pinctrl_uart1_my>;
    uart-has-rtscts;
    rs485-rts-active-low;
    linux,rs485-enabled-at-boot-time;
    rs485-rts-delay = <0 0>;
    fsl,dte-mode;
    status = "okay";
};

If I comment out the property “rs485-rts-active-low”, the kernel boots, then by configuring the RTS in user space with ioctl (code snippet below), the serial port works fine.

struct serial_rs485 rs485conf;

/* Enable RS485 mode: */
rs485conf.flags |= SER_RS485_ENABLED;

rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);
rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;


if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
...
}

Additional tests:

  • Using the equivalent dts configuration with BSP 6.5.0 and a colibri iMX7D 1G emmc there is no problem
  • Using BSP 6.6.0 and a colibri imx7 1G emmc the same problem shows up.

Am I missing something?

regards

f

As a test, can you insert a rs485-rx-during-tx into the dts and see if things work with the rs485-rts-active-low also enabled?

thanks for your quick reply.

I have tried adding “rs485-rx-during-tx” in the dts with the following configurations:

  • iMX6DL + BSP 6.5.0
  • iMX7D 1G emmc + BSP 6.6.0

The kernel still won’t boot in both cases.

Thanks

f

Bummer…it was a shot in the dark really. I don’t work with any of your modules, so to summarize:

BSP 6.5.0 and a colibri iMX7D 1G emmc - Works
BSP 6.6.0 and a colibri iMX7D 1G emmc - Doesn’t work
iMX6DL - Nothing works

Those first two suggest something between kernel releases. I guess I’d focus there looking at diffs, etc., for the serial stuff.

The third suggests something with the rts line perhaps being used somewhere else in a dts?

Hopefully someone from toradex has some hardware and can do a quick check on their side.

I know…not much help. Good luck!

Hello @elfranzo,

Thanks for reporting this issue!
Also thanks @DaveM for helping in the meantime!
I will try to reproduce this issue and will get back to you as soon as I have an update on the matter. Thanks for understanding!

@DaveM It was worth a try, Thanks anyway.

Actually I still haven’t tried iMX6DL + BSP 6.6.0.

I agree with you, there should have been some changes between BSP 6.5.0 and BSP 6.6.0 for iMX7D while, for iMX6DL probably there is also something else.

@rudhi.tx , thanks! when the feature is enabled after the system has been booted, the serial port works fine. Maybe I am wrong, but this suggests some kind of complex interaction at boot time.

Additional infos:

------------------------------------------------------------
Bootloader:               U-Boot
Kernel version:           6.1.83+git.e5cd595e23c1 #1 SMP Tue Mar 26 22:22:57 UTC 2024
Kernel command line:      root=PARTUUID=ed0b8080-02 ro rootwait console=tty1 console=ttymxc4,115200n8 consoleblank=0
Distro name:              NAME="TDX Wayland with XWayland Upstream"
Distro version:           VERSION_ID=6.6.0-build.12
Distro variant:           -
Hostname:                 colibri-imx7-emmc-06373028
------------------------------------------------------------

Hardware info
------------------------------------------------------------
HW model:                 Toradex Colibri iMX7D 1GB (eMMC) on Colibri Evaluation Board V3
Toradex version:          0039 V1.1A
Serial number:            06373028
Processor arch:           armv7l
------------------------------------------------------------

DTS overlay:

&iomuxc {


   pinctrl_uart1_es1007b: uart1grp-es1007b {
        fsl,pins = <
             MX7D_PAD_UART1_TX_DATA__UART1_DTE_RX 0x79
             MX7D_PAD_UART1_RX_DATA__UART1_DTE_TX 0x79
             MX7D_PAD_SAI2_TX_SYNC__UART1_DTE_RTS    0x79
             MX7D_PAD_SAI2_TX_BCLK__UART1_DTE_CTS    0x79

        >;
   };

};

&uart1 {
   
    pinctrl-0 = <&pinctrl_uart1_es1007b>;
    assigned-clocks = <&clks IMX7D_UART1_ROOT_SRC>;
    assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>;
    
    uart-has-rtscts;
    rs485-rts-active-low;
   
    linux,rs485-enabled-at-boot-time;
    rs485-rts-delay = <0 0>;
    fsl,dte-mode;
    status = "okay";
};

I have tried a quick diff of the two kernel sources and the only notable difference in imx.c is:

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=6e04a9d30509fb53ba6df5d655ed61d607a7cfda

I don’t know if this can in any way be related to my issue

thanks again

f

I wonder if changing to a gpios scheme for rts/cts makes any difference? Then changing the dts for that kind of control?

That is another odd scenario: I was able to use rts-gpios on UART2 but not on UART1, but this could depend on the fact that the two serial ports have some hw differences on my carrier, or maybe I am doing something wrong. If it worked it could be a nice workaround. A dirtier one is to change the rs485conf flag with a script during system init.

After some more tests, I noticed that you can see this behavior also on UART2 (I tried this with imx7d + bsp 6.6.0)
It the dts contains the combination of uart-has-rtscts + rs485-rts-active-low, the colibri won’t boot even if it is located on a iris board, so this also rules out hw differences.

Does the kernel startup offer any interesting text in DEBUG mode? Sometimes the drivers give a bit of information when startup issues arise even in a working scenario.

I am still working with the BSP reference image from Toradex.
Is it possible to enable more debug messages without recompiling the kernel?

You can start by pasting the output of ‘dmesg’ here during a “good” and “bad” boot (ya, I know the bad boot is a lockup, but just being complete :wink:

Ok thanks to your hint I tried something I hadn’t tried before.
I set up the console on ttymxc1 so I managed to see what happens during the bad boot.

As you can see below rcu_sched detects a CPU stall.
This happens just after serial setup and a message from imx-uart

[ 0.259892] imx-uart 30860000.serial: low-active RTS not possible when receiver is off, enabling receiver

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 6.1.83+git.e5cd595e23c1 (oe-user@oe-host) (arm-tdx-linux-gnueabi-gcc (GCC) 11.4.0, GNU 4
[    0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
[    0.000000] CPU: div instructions available: patching division code
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] OF: fdt: Machine model: Toradex Colibri iMX7D 1GB (eMMC) on Colibri Evaluation Board V3
[    0.000000] Memory policy: Data cache writealloc
[    0.000000] cma: Reserved 256 MiB at 0xb0000000
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000080000000-0x00000000afffffff]
[    0.000000]   HighMem  [mem 0x00000000b0000000-0x00000000bfffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000080000000-0x00000000bfffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x00000000bfffffff]
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.0 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: Trusted OS migration not required
[    0.000000] psci: SMC Calling Convention v1.0
[    0.000000] percpu: Embedded 13 pages/cpu s21908 r8192 d23148 u53248
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 260608
[    0.000000] Kernel command line: root=PARTUUID=ed0b8080-02 ro rootwait console=tty1 console=ttymxc1,115200n8 cons0
[    0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes, linear)
[    0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 758052K/1048576K available (11264K kernel code, 1238K rwdata, 3900K rodata, 1024K init, 438K )
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu:     RCU event tracing is enabled.
[    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2.
[    0.000000]  Tracing variant of Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=2
[    0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[    0.000000] GIC: Using split EOI/Deactivate mode
[    0.000000] rcu: srcu_init: Setting srcu_struct sizes based on contention.
[    0.000000] arch_timer: cp15 timer(s) running at 8.00MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x1d854df40, max_idle_ns: 440795202s
[    0.000002] sched_clock: 56 bits at 8MHz, resolution 125ns, wraps every 2199023255500ns
[    0.000018] Switching to timer-based delay loop, resolution 125ns
[    0.000471] Switching to timer-based delay loop, resolution 41ns
[    0.000486] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 89478484971ns
[    0.000512] clocksource: mxc_timer1: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635851949 ns
[    0.002115] Console: colour dummy device 80x30
[    0.002685] printk: console [tty1] enabled
[    0.002740] Calibrating delay loop (skipped), value calculated using timer frequency.. 48.00 BogoMIPS (lpj=240000)
[    0.002781] CPU: Testing write buffer coherency: ok
[    0.002852] pid_max: default: 32768 minimum: 301
[    0.003072] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes, linear)
[    0.003116] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes, linear)
[    0.004248] CPU0: update cpu_capacity 1024
[    0.004288] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
[    0.005348] cblist_init_generic: Setting adjustable number of callback queues.
[    0.005388] cblist_init_generic: Setting shift to 1 and lim to 1.
[    0.005564] Setting up static identity map for 0x80100000 - 0x80100078
[    0.005745] rcu: Hierarchical SRCU implementation.
[    0.005769] rcu:     Max phase no-delay instances is 1000.
[    0.007221] smp: Bringing up secondary CPUs ...
[    0.008263] CPU1: update cpu_capacity 1024
[    0.008276] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
[    0.008427] smp: Brought up 1 node, 2 CPUs
[    0.008487] SMP: Total of 2 processors activated (96.00 BogoMIPS).
[    0.008511] CPU: All CPU(s) started in HYP mode.
[    0.008527] CPU: Virtualization extensions available.
[    0.009204] devtmpfs: initialized
[    0.020573] VFP support v0.3: implementor 41 architecture 2 part 30 variant 7 rev 5
[    0.020878] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.020928] futex hash table entries: 512 (order: 3, 32768 bytes, linear)
[    0.031201] pinctrl core: initialized pinctrl subsystem
[    0.033222] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[    0.039870] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.041369] thermal_sys: Registered thermal governor 'step_wise'
[    0.041466] cpuidle: using governor menu
[    0.042138] hw-breakpoint: found 5 (+1 reserved) breakpoint and 4 watchpoint registers.
[    0.042184] hw-breakpoint: maximum watchpoint size is 8 bytes.
[    0.049018] platform soc: Fixed dependency cycle(s) with /soc/bus@30000000/gpc@303a0000
[    0.051494] platform 302c0000.pinctrl: Fixed dependency cycle(s) with /soc/bus@30000000/pinctrl@302c0000/gpiolpsrp
[    0.051749] imx7d-pinctrl 302c0000.pinctrl: initialized IMX pinctrl driver
[    0.052369] platform 30330000.pinctrl: Fixed dependency cycle(s) with /soc/bus@30000000/pinctrl@30330000/gpio4grp
[    0.052425] platform 30330000.pinctrl: Fixed dependency cycle(s) with /soc/bus@30000000/pinctrl@30330000/gpio3grp
[    0.052472] platform 30330000.pinctrl: Fixed dependency cycle(s) with /soc/bus@30000000/pinctrl@30330000/gpio2grp
[    0.052517] platform 30330000.pinctrl: Fixed dependency cycle(s) with /soc/bus@30000000/pinctrl@30330000/gpio1grp
[    0.053194] imx7d-pinctrl 30330000.pinctrl: initialized IMX pinctrl driver
[    0.065312] platform 30730000.lcdif: Fixed dependency cycle(s) with /panel-dpi
[    0.065450] platform panel-dpi: Fixed dependency cycle(s) with /soc/bus@30400000/lcdif@30730000
[    0.078725] kprobes: kprobe jump-optimization is enabled. All kprobes are optimized if possible.
[    0.095747] SCSI subsystem initialized
[    0.096139] usbcore: registered new interface driver usbfs
[    0.096215] usbcore: registered new interface driver hub
[    0.096293] usbcore: registered new device driver usb
[    0.096451] usb_phy_generic usbphynop1: supply vcc not found, using dummy regulator
[    0.096638] usb_phy_generic usbphynop1: dummy supplies not allowed for exclusive requests
[    0.096679] usb_phy_generic usbphynop1: dummy supplies not allowed for exclusive requests
[    0.097000] usb_phy_generic usbphynop2: supply vcc not found, using dummy regulator
[    0.097188] usb_phy_generic usbphynop2: dummy supplies not allowed for exclusive requests
[    0.097228] usb_phy_generic usbphynop2: dummy supplies not allowed for exclusive requests
[    0.099122] i2c i2c-0: IMX I2C adapter registered
[    0.100795] i2c i2c-3: IMX I2C adapter registered
[    0.101137] mc: Linux media interface: v0.10
[    0.101230] videodev: Linux video capture interface: v2.00
[    0.101360] pps_core: LinuxPPS API ver. 1 registered
[    0.101383] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    0.101427] PTP clock support registered
[    0.102107] Advanced Linux Sound Architecture Driver Initialized.
[    0.102959] Bluetooth: Core ver 2.22
[    0.103031] NET: Registered PF_BLUETOOTH protocol family
[    0.103055] Bluetooth: HCI device and connection manager initialized
[    0.103082] Bluetooth: HCI socket layer initialized
[    0.103107] Bluetooth: L2CAP socket layer initialized
[    0.103143] Bluetooth: SCO socket layer initialized
[    0.103901] clocksource: Switched to clocksource arch_sys_counter
[    0.104241] VFS: Disk quotas dquot_6.6.0
[    0.104330] VFS: Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
[    0.116108] NET: Registered PF_INET protocol family
[    0.116507] IP idents hash table entries: 16384 (order: 5, 131072 bytes, linear)
[    0.119259] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes, linear)
[    0.119324] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
[    0.119361] TCP established hash table entries: 8192 (order: 3, 32768 bytes, linear)
[    0.119469] TCP bind hash table entries: 8192 (order: 5, 131072 bytes, linear)
[    0.119745] TCP: Hash tables configured (established 8192 bind 8192)
[    0.119890] UDP hash table entries: 512 (order: 2, 16384 bytes, linear)
[    0.119974] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear)
[    0.120217] NET: Registered PF_UNIX/PF_LOCAL protocol family
[    0.120860] RPC: Registered named UNIX socket transport module.
[    0.120898] RPC: Registered udp transport module.
[    0.120917] RPC: Registered tcp transport module.
[    0.120934] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.120962] PCI: CLS 0 bytes, default 64
[    0.122192] hw perfevents: enabled with armv7_cortex_a7 PMU driver, 5 counters available
[    0.123766] Initialise system trusted keyrings
[    0.124126] workingset: timestamp_bits=30 max_order=18 bucket_order=0
[    0.130200] NFS: Registering the id_resolver key type
[    0.130354] Key type id_resolver registered
[    0.130375] Key type id_legacy registered
[    0.130480] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[    0.130508] nfs4flexfilelayout_init: NFSv4 Flexfile Layout Driver Registering...
[    0.248382] Key type asymmetric registered
[    0.248418] Asymmetric key parser 'x509' registered
[    0.248623] bounce: pool size: 64 pages
[    0.248735] io scheduler mq-deadline registered
[    0.248761] io scheduler kyber registered
[    0.255500] mxs-dma 33000000.dma-controller: initialized
[    0.259892] imx-uart 30860000.serial: low-active RTS not possible when receiver is off, enabling receiver
[    0.260015] 30860000.serial: ttymxc0 at MMIO 0x30860000 (irq = 271, base_baud = 1500000) is a IMX
[    0.261109] 30890000.serial: ttymxc1 at MMIO 0x30890000 (irq = 272, base_baud = 1500000) is a IMX
[    1.193318] printk: console [ttymxc1] enabled
[    1.198704] 30880000.serial: ttymxc2 at MMIO 0x30880000 (irq = 273, base_baud = 1500000) is a IMX
[    1.208560] 30a70000.serial: ttymxc4 at MMIO 0x30a70000 (irq = 274, base_baud = 1500000) is a IMX
[    1.226559] Stack Depot allocating hash table of 65536 entries with kvcalloc
[   21.273891] rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
[   21.279848] rcu:     0-....: (13 ticks this GP) idle=067c/0/0x1 softirq=15/17 fqs=1050
[   21.287532]  (detected by 1, t=2102 jiffies, g=-1183, q=29 ncpus=2)
[   21.293818] Sending NMI from CPU 1 to CPUs 0:
[   21.298193] NMI backtrace for cpu 0
[   21.298207] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.1.83+git.e5cd595e23c1 #1
[   21.298219] Hardware name: Freescale i.MX7 Dual (Device Tree)
[   21.298228] PC is at arch_cpu_idle+0x30/0x3c
[   21.298266] LR is at arch_cpu_idle+0x2c/0x3c
[   21.298282] pc : [<c0108260>]    lr : [<c010825c>]    psr: 60000013
[   21.298289] sp : c1201f48  ip : 00000000  fp : c1205068
[   21.298297] r10: c1165cb0  r9 : 00000000  r8 : 00000000
[   21.298303] r7 : c120505c  r6 : c1205010  r5 : 00000000  r4 : c1208a40
[   21.298311] r3 : c0119740  r2 : 00000000  r1 : 00000679  r0 : 00000005
[   21.298320] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[   21.298331] Control: 10c5387d  Table: 8000406a  DAC: 00000051
[   21.298364]  arch_cpu_idle from default_idle_call+0x24/0x34
[   21.298400]  default_idle_call from do_idle+0x1ec/0x2a8
[   21.298424]  do_idle from cpu_startup_entry+0x28/0x2c
[   21.298440]  cpu_startup_entry from rest_init+0x90/0xac
[   21.298467]  rest_init from arch_post_acpi_subsys_init+0x0/0x8

I think you probably need to really try and figure out why you can’t use gpios for your rs-485 rts control for uart1. Using “built-in” control is fraught with peril :wink: