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.

DM368 IPNC - Adding UART1, almost working...

We are trying to set up UART1 on our board, which is based on LeopardBoard DM368, using the Appro IPNC SDK 4.x

I have followed the numerous posts on this forum which show how to setup UART1 via GIO25/GIO34 pins in the kernel, the steps are:

In /ipnc_psp_03_21_00_04/ti-davinci/arch/arm/mach-davinci/dm365.c

static struct clk uart0_clk = {
    .name        = "uart0",
    .parent        = &pll1_aux_clk,
    .lpsc        = DAVINCI_LPSC_UART0,
};

static struct clk uart1_clk = {
    .name        = "uart1",
    .parent        = &pll1_sysclk4,
    .lpsc        = DAVINCI_LPSC_UART1,
};

MUX_CFG(DM365, UART1_TXD, 3,   29,    3,    3,  false)   // GPIO 25 = UART1_TXD
MUX_CFG(DM365, UART1_RXD, 4,   14,    3,    3,  false)     // GPIO 34 = UART1_RXD
MUX_CFG(DM365,    UART1_RTS,    3,   23,    3,    1,     false)
MUX_CFG(DM365,    UART1_CTS,    3,   21,    3,    1,     false)

#define DM365_UART1_BASE    (IO_PHYS + 0x106000)

static struct plat_serial8250_port dm365_serial_platform_data[] = {
    {
        .mapbase    = DAVINCI_UART0_BASE,
        .irq        = IRQ_UARTINT0,
        .flags        = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
                  UPF_IOREMAP,
        .iotype        = UPIO_MEM,
        .regshift    = 2,
    },
    {
        .mapbase    = DM365_UART1_BASE,
        .irq        = IRQ_UARTINT1,
        //.flags        = UPF_IOREMAP,
        .flags        = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
                  UPF_IOREMAP,
        .iotype        = UPIO_MEM,
        .regshift    = 2,
    },
    {
        .flags        = 0
    },
};

static struct platform_device dm365_serial_device = {
    .name            = "serial8250",
    .id            = PLAT8250_DEV_PLATFORM,
    .dev            = {
        .platform_data    = dm365_serial_platform_data,
    },
};

In /ipnc_psp_03_21_00_04/ti-davinci/arch/arm/mach-davinci/board-dm368-ipnc.c

static struct davinci_uart_config uart_config __initdata = {
    .enabled_uarts = (7 << 0),
};

dm368_evm_init() added:

    davinci_cfg_reg(DM365_UART1_TXD);
    davinci_cfg_reg(DM365_UART1_RXD);
    davinci_cfg_reg(DM365_UART1_RTS);
    davinci_cfg_reg(DM365_UART1_CTS);

Before the line davinci_serial_init(&uart_config);

In the boot process it shows the following:

[    0.263546] davinci_serial_init: uart0 initialised
[    0.274028] davinci_serial_init: uart1 initialised
[    0.547812] serial8250.0: ttyS0 at MMIO 0x1c20000 (irq = 40) is a 16550A
[    0.569849] serial8250.0: ttyS1 at MMIO 0x1d06000 (irq = 41) is a 16550A

If I do ls /dev/ I can see ttyS1, if I echo text to /dev/ttyS1 it returns OK but nothing happens (confirmed with oscillioscope), if I do cat /proc/tty/driver/serial
serinfo:1.0 driver revision:
0: uart:16550A mmio:0x01C20000 irq:40 tx:97998 rx:0 CTS|DSR
1: uart:16550A mmio:0x01D06000 irq:41 tx:0 rx:0 DSR

If I try to modify it I get an error:
> stty -F /dev/ttyS1
stty: /dev/ttyS1: Inappropriate ioctl for device


Here's the strange thing: If I modify bootargs to set the console to be ttyS1 (setenv bootargs 'console=ttyS1,115200n8 ....) UART1 works fine and reports:

cat /proc/tty/driver/serial
serinfo:1.0 driver revision:
0: uart:16550A mmio:0x01C20000 irq:40 tx:0 rx:0 CTS|DSR
1: uart:16550A mmio:0x01D06000 irq:41 tx:11563 rx:0 RTS|DTR|DSR

I notice the flow control flags seem to be set in a more sensible state (similar to UART0), it seems like the earlyprintk is doing a better job of initialising the port than the kernel. Can anyone tell me what I've missed or offer any hints?