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.

How to config UART1&UART2 in DM6467T

Hello, Everyone

I want to use UART1 and UART2 in DM6467T, My Linux Kernel is 2.6.32, it is download from TI's website

I found "uart_config" in board-dm646x-evm.c as following:

.enabled_uarts = (1 << 0),

and I modified it to:

.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),

at the same time, I removed "dm646x_init_cir_device()" in evm_init(in board-dm646x-evm.c).

and then, I unchecked the option of "DaVinci HD CIR driver" in "make xconfig"

I just modified above 3 places, I don't know is there any error, and is there any more places need changing ?

I hope help and suggestions from TI's experts

Thank you very much

  • I meet some trouble, is there anyone would tell me how to config these correctly ?

    Thank you very much

  • up, Is there anyone would help me ?

  • I don' t have a DM6467T. General things to check for are pinmux and clock.

    Linux does not appear to do much pinmux config. See arch/arm/mach-davinci/dm646x.c for davinci_cfg_reg() calls. Clocks should be handled by the UART driver code.

    U-boot pinmux and clocks UART 0. See board/davinci/dm6467evm/dm6467evm.c.

    How is it not working? What is tests are you using? Which version of Linux and U-Boot are you using?

  • I don't know the version of my u-boot, but It is download from TI's website, its name is "u-boot-dm646x"

    my Linux kernel is 2.6.32, it is download from TI's website too

    I've track the kernel, I found davinci_cfg_reg has been called, when the kernel enable the clocks for uart1 and uart2

    Now, I take more modifcations, I set pinmux1 to 0x14, set 0x01C40048 to 0, set MDR1 of uart1 and uart2 to 0.

    I can't send and receive data through ttyS1 and ttyS2 after I execute open("/dev/ttyS1", 0_RDWR) and open("/dev/ttyS2", 0_RDWR)

    I found some errors in cat /proc/tty/driver/serial just after open("/dev/ttyS1", 0_RDWR) and open("/dev/ttyS2", 0_RDWR), without any other operations

    serinfo:1.0 driver revision:
    0: uart:ST16654 mmio:0x01C20000 irq:40 tx:9910 rx:245 RTS|DTR
    1: uart:ST16654 mmio:0x01C20400 irq:41 tx:2 rx:1 brk:1 DSR
    2: uart:ST16654 mmio:0x01C20800 irq:42 tx:2 rx:1 brk:1 DSR

    just open and no other operation, why the tx, rx, brk is abnormal ?

    I found the "tx" is always changing(++) when I execute write, but there is not any data is transfered to the terminal.

  • The odd values would suggest everything is not quite setup. Or something else is overwriting your settings.

    I had to look up 0x01C4004. That's VDD3P3V_PWDN. Note that Linux uses virtual memory. Writing to address 0x01C4004 might not actually get to that physical memory location. I think you have to look around for the Linux module that maps virtual memory to that location and use that modules code.

    Similiarly for MDR1.  Some init flags for those UARTs should handle the MDR1. Hard part is finding the init flags in the data structures.

    To check the pinmc settings, try setting the kernel options:

    "Multiplexing debug output"
    "Warn about pins the bootloader didn't set up"

    Watch the bootup messages for pinmux prints.

  • 0x01C40004 is PINMUX1, and 0x01C40048 is VDD3P3V_PWDN as the description of TI's datasheet(SPRS605C).

    I set 0x01C40048 and 0x01C40004 as following:

    __raw_writel(0, IO_ADDRESS(0x01C40048))  ;

    __raw_writel(0x15, IO_ADDRESS(0x01C40004))  ;

    Is there any error in the above codes?

    I've open the two options you metioned, the result as following:

    MUX: Setting register STSOMUX_DISABLE
               PINMUX0 (0x00000000) = 0x00000000 -> 0x00000000
    MUX: Setting register STSIMUX_DISABLE
               PINMUX0 (0x00000000) = 0x00000000 -> 0x00000000
    MUX: Setting register PTSOMUX_DISABLE
               PINMUX0 (0x00000000) = 0x00000000 -> 0x00000000
    MUX: Setting register PTSIMUX_DISABLE
               PINMUX0 (0x00000000) = 0x00000000 -> 0x00000000
    MUX: initialized ATAEN
    MUX: Setting register ATAEN
               PINMUX0 (0x00000000) = 0x00000000 -> 0x00000001
    Shaquille, 0x01C40048 = 0x00000000
    Shaquille, 0x01C40000 = 0x00000001
    Shaquille, 0x01C40004 = 0x00000015

    the red words are added by myself

    The setting of MDR1 is added in davinci_serial_reset of serial.c(in mach-davinci folder), the details as following:

    static void __init davinci_serial_reset(struct plat_serial8250_port *p)
    {
     unsigned int pwremu = 0;

     serial_write_reg(p, UART_IER, 0);  /* disable all interrupts */

     /* reset both transmitter and receiver: bits 14,13 = UTRST, URRST */
     /*
     serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu) ;
     mdelay(10);

     pwremu |= (0x3 << 13);
     pwremu |= 0x1;
     serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
     */
    //Shaquille Added serial_write_reg 20120912 Start
     serial_write_reg(p, 0x08, 0) ;
    //Shaquille Added serial_write_reg 20120912 End

     if (cpu_is_davinci_dm646x())
      serial_write_reg(p, UART_DM646X_SCR,
         UART_DM646X_SCR_TX_WATERMARK);
    }

    the red words is the setting for MDR1, Is there any error ?

  • I cannot say if your code is correct. No experience with the IO_ADDRESS macro. No experience with the MDR1 register but your serial init code looks okay. Without knowing what all the macros resolve to, I tend to use existing code as a base. Somelike this:

    ----arch/arm/mach-davinci/include/mach/mux.h----
    ...
    enum davinci_dm646x_index {
      /* ATA function */
      DM646X_ATAEN,
    ...
      DM646X_PTSIMUX_SERIAL,
    ...
      /* UART Control */
      DM646X_UART2_FLOW,     /* Add */
      DM646X_UART2_NO_FLOW,  /* Add */
      DM646X_IRDA_CIR_UART2, /* Add */
      DM646X_GPIO_UART2,     /* Add */
      DM646X_UART1_FLOW,     /* Add */
      DM646X_UART1_NO_FLOW,  /* Add */
      DM646X_IRDA_CIR_UART1, /* Add */
      DM646X_GPIO_UART1,     /* Add */
      DM646X_UART0_FLOW,     /* Add */
      DM646X_UART0_NO_FLOW,  /* Add */
      DM646X_IRDA_CIR_UART0, /* Add */
    };


    ----arch/arm/mach-davinci/davinci.h----
    ...
    void dm646x_setup_vpif(struct vpif_display_config *,
                   struct vpif_capture_config *);
    void dm646x_setup_uart_hw(void); /* Add */
    #endif /*__DAVINCI_H */

    ----arch/arm/mach-davinci/dm646x.c----
    ...
    #define DAVINCI_VPIF_BASE(0x01C12000)

    #define VDD3P3V_VID_MASK (BIT_MASK(3) | BIT_MASK(2) | BIT_MASK(1) |\
                              BIT_MASK(0))
    #define VSCLKDIS_MASK (BIT_MASK(11) | BIT_MASK(10) | BIT_MASK(9) |\
                           BIT_MASK(8))

    /* UART 1 and 2 both no flow control */                   /* Add */
    #define VDD3P3V_UART_MASK (BIT_MASK(8) | BIT_MASK(6))     /* Add */
    ...
    static const struct mux_config dm646x_pins[] = {
    #ifdef CONFIG_DAVINCI_MUX
    MUX_CFG(DM646X, ATAEN,            0,  0,  5,  1, true)
    ...
    MUX_CFG(DM646X, PTSIMUX_SERIAL,   0, 16,  3,  3, true)

    MUX_CFG(DM646X, UART2_FLOW,    1,  4,  3,  0, true) /* Add */
    MUX_CFG(DM646X, UART2_NO_FLOW, 1,  4,  3,  1, true) /* Add */
    MUX_CFG(DM646X, IRDA_CIR_UART2,1,  4,  3,  2, true) /* Add */
    MUX_CFG(DM646X, GPIO_UART2,    1,  4,  3,  3, true) /* Add */

    MUX_CFG(DM646X, UART1_FLOW,    1,  2,  3,  0, true) /* Add */
    MUX_CFG(DM646X, UART1_NO_FLOW, 1,  2,  3,  1, true) /* Add */
    MUX_CFG(DM646X, IRDA_CIR_UART1,1,  2,  3,  2, true) /* Add */
    MUX_CFG(DM646X, GPIO_UART1,    1,  2,  3,  3, true) /* Add */

    MUX_CFG(DM646X, UART0_FLOW,    1,  0,  3,  0, true) /* Add */
    MUX_CFG(DM646X, UART0_NO_FLOW, 1,  0,  3,  1, true) /* Add */
    MUX_CFG(DM646X, IRDA_CIR_UART0,1,  0,  3,  2, true) /* Add */
    #endif
    };
    ...
    void dm646x_setup_uart_hw(void)                                /* Add */
    {                                                              /* Add */
      unsigned int value;                                          /* Add */
                                                                   /* Add */
      value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN));/* Add */
      value &= ~VDD3P3V_UART_MASK;                                 /* Add */
      __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN));/* Add */
                                                                   /* Add */
      davinci_cfg_reg(DM646X_UART1_NO_FLOW);                       /* Add */
      davinci_cfg_reg(DM646X_UART2_NO_FLOW);                       /* Add */
    }                                                              /* Add */
    ...
    ---arch_arm_mach-davinci_board-dm646x-evm.c---
    ...
    static __init void evm_init(void)
    {
      struct davinci_soc_info *soc_info = &davinci_soc_info;

      evm_init_i2c();
      dm646x_setup_uart_hw(); /* Add */
      ...
    }
    ...
    The PSC module should automatically be handled by the serial init code.

    It might also be the case that some driver loads up after the kernel will overwrite your settings. The pimux debug would suggest that the PINMUX0 is all zeros. Which should mean your UART pins are controlled by PINMUX1. But again, a loadable module loaded late in the boot process could overwrite your settings.