This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Console UART spews garbage after kernel re-initialization of UART

I have a DM8148 system with the console on UART 4. I have everything working from U-boot up to the kernel, except a point during boot after the kernel re-initializes the UART. There are some messages I need to see just after this garbage starts so I need to fix this problem.

The corruption appears on the scope as normal data at the right bitrate, except some bit periods are 1.5x the normal length, causing framing errors. It also puzzles me that the problem goes away later on in the boot process.

Here's what it's giving during boot:
...
Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
omap_uart.0: ttyO0 at MMIO 0x48020000 (irq = 72) is a OMAP UART0
console [ttyO4] enabled, bootconsole disabled
omap_uart.4: ttyO4 at MMIO 0x481a8000 (irq = 45) is a OMAP UART4
<garbage starts here>
~50 lines
<garbage ends>
VFS: Mounted root (ubifs filesystem) on device 0:14.
devtmpfs: mounted
Freeing init memory: 232K
Failed to execute /init. Attempting defaults...
INIT: version 2.86 booting
Please wait: booting...
Error opening /dev/fb0: No such file or directory
Starting udev
PHY: 0:01 - Link is Up - 0/Half
PHY: 0:01 - Link is Down
...

I've traced the problem down to a call to serial_omap_pm(... ,0 , -1) in the serial drivers, specifically when it writes UART_LCR_CONF_MODE_B (0xBF) to the UART_LCR register, the problem starts occurring.

Is it possible that I'm not initializing the current power management state properly in the UART driver? If it passed 0 instead of -1, it wouldn't perform the problem writes.

Regards,
David

  • Wait, am I seeing this right.. is that driver outputting a message to the serial console, and then -- without first fully draining the TX fifo and serializer -- proceeding to put the UART into configuration mode?  That definitely looks like a recipe for garbage output.

    In general, I really don't understand why the TRM's procedures (apparently followed here by the driver) keep toggling bit 4 (UART_EFR_ECB) of EFR instead of setting it once and never touching it again afterwards, especially since you cannot safely access EFR while the UART is in operation.

  • Found the problem! The serial_omap_console_ports structure in omap-serial.c wasn't big enough to handle UART4/5

    Fix:

    in omap-serial.c, to enable use of UARTs 4 and 5, change
    static struct uart_omap_port *serial_omap_console_ports[4];
    to
    static struct uart_omap_port *serial_omap_console_ports[6];

    This also solved a problem where during switch from bootconsole to regular console, a few console lines came out UART0 when they should have come out UART4.