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.

DM6446 UART2 questions

I want to use UART 2. The kernel version is 2.6.10_mvl401-davinci_evm-PSP_01_30_00_082

the kernel info is about UART 2 is:

(0x01c40004) = 0x00000085 -> 0x00000085

 

Serial: 8250/16550 driver $Revision: 1.90 $ 2 ports, IRQ sharing disabled

Registering platform device 'serial8250'. Parent at platform

ttyS0 at MMIO 0x1c20000 (irq = 40) is a 16550A

ttyS1 at MMIO 0x1c20800 (irq = 42) is a 16550A

 

The kernel source I changed is as follow:

 

 

 

-static struct plat_serial8250_port serial_platform_data[] = {

+static struct plat_serial8250_port serial_platform_data[2] = {

        {

                .membase        = (char *)IO_ADDRESS(DAVINCI_UART0_BASE),

                .mapbase        = (unsigned long)DAVINCI_UART0_BASE,

@@ -76,6 +76,15 @@ static struct plat_serial8250_port serial_platform_data[] = {

                .uartclk        = DAVINCI_UART_CLK,

        },

        {

+                .membase        = (char *)IO_ADDRESS(DAVINCI_UART2_BASE),

+                .mapbase        = (unsigned long)DAVINCI_UART2_BASE,

+                .irq            = IRQ_UARTINT2,

+                .flags          = UPF_SKIP_TEST,

+                .iotype         = UPIO_MEM32,

+                .regshift       = 2,

+                .uartclk        = DAVINCI_UART_CLK,

+       },

+       {

                .flags  = 0,

        },

 };

@@ -427,6 +436,7 @@ static void board_init(void)

        board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPTC1, 1);

        board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_GPIO, 1);

 

+        board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_UART2, 1);

        /* Turn on WatchDog timer LPSC.  Needed for RESET to work */

        board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TIMER2, 1);

 

@@ -436,8 +446,10 @@ static void board_init(void)

 

 static void dm644x_setup_pinmux(unsigned int id)

 {

@@ -468,6 +480,9 @@ static void dm644x_setup_pinmux(unsigned int id)

                davinci_cfg_reg(DM644X_VLINQEN);

                davinci_cfg_reg(DM644X_VLINQWD);

                break;

+        case DAVINCI_LPSC_UART2:

+                davinci_cfg_reg(DM644X_UART2);

+                break;

        default:

                break;

 

diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c

index d7a6398..e4b0266 100755

--- a/arch/arm/mach-davinci/clock.c

+++ b/arch/arm/mach-davinci/clock.c

@@ -259,6 +259,12 @@ static struct clk davinci_dm644x_clks[] = {

                .lpsc = DAVINCI_LPSC_UART0,

                .usecount = 1,

        },

 

 

"+        {       

+                .name = "UART2",

+                .rate = &fixedrate,

+                .lpsc = DAVINCI_LPSC_UART2,

+                .usecount = 1,

+        },     

        {

                .name = "EMACCLK",

                .rate = &commonrate,

diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c

index 96ef251..0c7d2ad 100644

--- a/arch/arm/mach-davinci/mux.c

+++ b/arch/arm/mach-davinci/mux.c

@@ -79,6 +79,9 @@ int __init_or_module davinci_cfg_reg(const unsigned long index)

 

                if (tmp1 != tmp2)

                        warn = 1;

+//lemon add

+                printk("      %s (0x%08x) = 0x%08x -> 0x%08x\n",

+                       cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg);

 

                davinci_writel(reg, cfg->mux_reg);

                spin_unlock_irqrestore(&mux_spin_lock, flags);

diff --git a/arch/arm/mach-davinci/mux_cfg.c b/arch/arm/mach-davinci/mux_cfg.c

index dac2d27..20fb494 100644

--- a/arch/arm/mach-davinci/mux_cfg.c

+++ b/arch/arm/mach-davinci/mux_cfg.c

@@ -59,6 +59,7 @@ MUX_CFG("RGB666",              0,   22,    1,   1,     1)

 

 MUX_CFG("LOEEN",                0,   24,    1,   1,     1)

 MUX_CFG("LFLDEN",               0,   25,    1,   1,     0)

+MUX_CFG("UART2",                 1,   2,     1,   1,     1)

 };

 

 struct pin_config __initdata_or_module davinci_dm646x_pins[] = {

diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c

index c3090e9..6d60de3 100755

--- a/arch/arm/mach-davinci/serial.c

+++ b/arch/arm/mach-davinci/serial.c

@@ -47,14 +47,17 @@ static inline unsigned int davinci_serial_in(struct plat_serial8250_port *up,

                                             int offset)

 {

        offset <<= up->regshift;

-       return (unsigned int)__raw_readb(up->membase + offset);

+        return (unsigned int)__raw_readw(up->membase + offset);

+//     return (unsigned int)__raw_readb(up->membase + offset);

 }

 

 static inline void davinci_serial_outp(struct plat_serial8250_port *p,

                                       int offset, int value)

 {

        offset <<= p->regshift;

-       __raw_writeb(value, p->membase + offset);

+//     __raw_writeb(value, p->membase + offset);

+        __raw_writew(value, p->membase + offset);

+

 }

 

 static void __init davinci_serial_reset(struct plat_serial8250_port *p)

@@ -95,14 +98,17 @@ void __init davinci_serial_init(struct platform_device *pdev)

 

        memset(uart_name, 0, sizeof(uart_name));

        for (p = dev->platform_data; p && p->flags; p++) {

-               switch (p->mapbase) {

+               printk("p:%x;%d\n",p,p->flags);

+                printk("********************base address:%x\n",p->mapbase);            

+switch (p->mapbase) {

                case DAVINCI_UART0_BASE:

                        uart = 0;

                        break;

                case DAVINCI_UART1_BASE:

                        uart = 1;

                        break;

-               case DM644X_UART2_BASE:

+               case DAVINCI_UART2_BASE:

+               //case DM644X_UART2_BASE:

                case DM355_UART2_BASE:

                        uart = 2;

                        break;

diff --git a/include/asm-arm/arch-davinci/hardware.h b/include/asm-arm/arch-davinci/hardware.h

index 4bb782c..6883191 100755

--- a/include/asm-arm/arch-davinci/hardware.h

+++ b/include/asm-arm/arch-davinci/hardware.h

@@ -44,6 +44,7 @@

 #define DAVINCI_DMA_3PTC1_BASE                 (0x01C10400)

 #define DAVINCI_UART0_BASE                     (0x01C20000)

 #define DAVINCI_UART1_BASE                     (0x01C20400)

+#define DAVINCI_UART2_BASE                      (0x01C20800)

 #define DAVINCI_I2C_BASE                       (0x01C21000)

 #define DAVINCI_TIMER0_BASE                    (0x01C21400)

 #define DAVINCI_TIMER1_BASE                    (0x01C21800)

@@ -84,7 +85,7 @@

 #define DAVINCI_VLYNQ_REMOTE_BASE              (0x0C000000)

 

 #define DM644X_ASYNC_EMIF_CNTRL_BASE           (0x01E00000)

-#define DM644X_UART2_BASE                      (0x01C20800)

+//#define DM644X_UART2_BASE                    (0x01C20800)

 #define DM644X_DDR2_CNTL_BASE                  (0x20000000)

 

 #define DM355_MMC1_BASE                                (0x01E00000)

diff --git a/include/asm-arm/arch-davinci/mux.h b/include/asm-arm/arch-davinci/mux.h

index 24ecebf..d1fd175 100644

--- a/include/asm-arm/arch-davinci/mux.h

+++ b/include/asm-arm/arch-davinci/mux.h

@@ -96,6 +96,7 @@ enum davinci_dm644x_index {

        /* LCD */

        DM644X_LOEEN,

        DM644X_LFLDEN,

+       DM644X_UART2,

 };

 

 

Now after

root@192.168.1.162:~# mknod /dev/ttyS1 c 4 65                       

root@192.168.1.162:~# stty sane 115200 raw -echo crtscts < /dev/ttyS1

root@192.168.1.162:~# stty -a < /dev/ttyS1

speed 115200 baud; rows 0; columns 0; line = 0;

intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;

eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;

lnext = ^V; flush = ^O; min = 1; time = 0;

-parenb -parodd cs8 hupcl -cstopb cread clocal crtscts

-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon

-ixoff -iuclc -ixany -imaxbel

-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0

ff0

-isig -icanon iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt

echoctl echoke

root@192.168.1.162:~# cat /proc/tty/driver/serial

serinfo:1.0 driver revision:

0: uart:16550A port:00000000 irq:40 tx:2667 rx:175 RTS|CTS|DTR|DSR

1: uart:16550A port:00000000 irq:42 tx:0 rx:0 CTS|DSR

root@192.168.1.162:~# echo "this is test" > /dev/ttyS1

root@192.168.1.162:~# 

root@192.168.1.162:~# cat /proc/tty/driver/serial     

serinfo:1.0 driver revision:

0: uart:16550A port:00000000 irq:40 tx:3012 rx:216 RTS|CTS|DTR|DSR

1: uart:16550A port:00000000 irq:42 tx:0 rx:0 CTS|DSR

 

I write data on the remote terminal which connect to uart 2

But there is no ack.

and we can find there is no change on "tx"

So  I think there is still some problem about my driver.

 

 

 

  • Is there any bug about it?

  • The platform I used is DM6446. The hardware is designed by ourselves. 

    Does the kernel still have some bugs?

    Or something wrong with my hardware?

  • I have not done this myself, but one of our customers has successfully done this using the following article. 

    http://www.mail-archive.com/davinci-linux-open-source@linux.davincidsp.com/msg02308.html

    Not sure if this was all that was required, but it was a significant part.. I can see from your code that you have some of these steps implemented though not exactly the same.  I would review this article carefully.

    Also, I will try moving your question to DM64xx forums as this thread was originally started for DM3x devices and I want to avoid confusion, not to mention that we want other users find this posrt when they search DM64xx forums.

  • NINGMENG CHEN said:

    The platform I used is DM6446. The hardware is designed by ourselves. 

    From a hardware perspective, The DM6446 device can support 3 UARTs and they have been tested; our EVM only has UART0 exposed via 9-pin serial connector (other UARTs available via daughter card (DCx) connectors on EVM).

    From a software perspective, the software is written for our EVM and only UART0 is enabled by default, primarily because the 2.6.10 kernel supported one UART, newer kernels support more than one UART, hence many of the software changes in the link I sent previously are what was learned from newer kernels. 

    I would recommend getting this working on oue EVM first, and then transitioning to your own board.

  • It should add the following operation on the board-evm.c file to reset the UART2.

       

       board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TIMER2, 1);

     

          davinci_serial_init(&serial_device);

    +    

    +     volatile int *ptr_pgmgt,*ptr_ier;

    +        ptr_pgmgt = (volatile int *)IO_ADDRESS(DAVINCI_UART2_BASE+0x30) ;

    +        ptr_ier =(volatile int *)IO_ADDRESS(DAVINCI_UART2_BASE+0x4);

    +        *ptr_pgmgt      =       0x0; //reset tx and rx

    +        *ptr_ier                = 0x0; //disable int

    +        int del=0;

    +        for(del=0; del <100000 ; del++)  // For delay

    +        *ptr_pgmgt =0x6001;  

  • I make your recommended kernel change in order to support UART1 in my kernel.

    I compiled  gain the kernel, but I still see only the ttyS0 instead of both :

    ttyS0 at MMIO 0x1c20000 (irq = 40) is a 16550A.

    What I forget?

  • I have a problem with serial interface UART1 on Davinci DM6446

    I try to change the kernel driver (see blelow ) , but I still get erroe while I use - > cat /dev/tts/1

    Please, any Idea??

    ------- at davinci.c ----------
     
    *(unsigned int*) (PSC_ADDR+0xA00+4*19) = *(unsigned int*)
    (PSC_ADDR+0xA00+4*19) | 0x003; //for power on
    *(unsigned int*) (PSC_ADDR+0xA00+4*20) = *(unsigned int*)
    (PSC_ADDR+0xA00+4*20) | 0x003; //for power on
    *(unsigned int*) (PSC_ADDR+0xA00+4*21) = *(unsigned int*)
    (PSC_ADDR+0xA00+4*21) | 0x003; //for power on
    #define UART0PWREMU_MGMT     0x01c20030
            *(volatile unsigned int*) UART0PWREMU_MGMT = 0x0000E003; //UART 0
     
    #define UART1PWREMU_MGMT     0x01c20430
            *(volatile unsigned int*) UART1PWREMU_MGMT = 0x0000E003; //UART 1
     
    #define UART2PWREMU_MGMT     0x01c20830
            *(volatile unsigned int*) UART2PWREMU_MGMT = 0x0000E003; //UART 2
    #define PINMUX0     0x01C40000
    #define PINMUX4     0x01C40004
     
            /* Enable UART0 MUX lines */
            *(volatile unsigned int *)PINMUX4 |= 0x7;//1; //uart0,1,2 enable;
     
     
    ----------davinci.c end-----------
     
    In kernel, i set power and clock( board-emv.c, serial.c , clock.c )
     
    at board-emv.c, I add power enable for UART ( Already bootloader set, but I
    set )
     
     board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_UART0, 1);
     board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_UART1, 1);
     board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_UART2, 1);
     
    at serial.c, I am add serial_platform_data for UART1 and 2
     
    static struct uart_port serial_platform_data[] = {
    {
     .membase  = (unsigned char __iomem *)IO_ADDRESS(DAVINCI_UART0_BASE),
     .mapbase  = (unsigned long)DAVINCI_UART0_BASE,
     .iotype   = UPIO_MEM,
     .irq      = IRQ_UARTINT0,
     .uartclk  = 27000000,
     .regshift = 2,
     .type     = PORT_16550A,
    }
    ,
    {
            .membase  = (unsigned char __iomem *)IO_ADDRESS(DAVINCI_UART1_BASE),
            .mapbase  = (unsigned long)DAVINCI_UART1_BASE,
            .iotype   = UPIO_MEM,
            .irq      = IRQ_UARTINT1,
            .uartclk  = 27000000,
            .regshift = 2,
            .type     = PORT_16550A,
    }
    ,
    {
            .membase  = (unsigned char __iomem *)IO_ADDRESS(DAVINCI_UART2_BASE),
            .mapbase  = (unsigned long)DAVINCI_UART2_BASE,
            .iotype   = UPIO_MEM,
            .irq      = IRQ_UARTINT2,
            .uartclk  = 27000000,
            .regshift = 2,
            .type     = PORT_16550A,
    }
    };
     
    and then, at davinci_serial_init(void)
    {
        early_serial_settup(&serial_platform_data[0]);
    //    early_serial_settup(&serial_platform_data[1]);  // This line is error
    , Kernel holding...
    //    early_serial_settup(&serial_platform_data[2]); //  This line is error
    , Kernel holding...
    }
     
    At clock.c . I add UART1, UART2 clock enable function
     
     
    #define DAVINCI_MAX_CLK 11 //9  add for UART1,2
     
    ///
      {
       .name = "UART0",
       .rate = &fixedrate,
       .enable   = 1,
       .maxuse   = 1,
       .lpsc = DAVINCI_LPSC_UART0,
      },
      {
       .name = "UART1",
       .rate = &fixedrate,
       .enable   = 1,
       .maxuse   = 1,
       .lpsc = DAVINCI_LPSC_UART1,
      },
      {
       .name = "UART2",
       .rate = &fixedrate,
       .enable   = 1,
       .maxuse   = 1,
       .lpsc = DAVINCI_LPSC_UART2,
      },  
      {
       .name = "EMACCLK",
       .rate = &commonrate,
       .lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
       .maxuse   = 1,
      },

  • I look up this like but I found that I do not have some function who mentioned there ( clock.c  -- >> board_setup_peripheral function )

    I think I need first off all to synchronize my files ( clock.c, serial.c mux.c etc.) NO?.

    How do I do it?

  • What's your kernel version?

  • Montavista 2.6.10_mvl401

  • Where did you get your kernel source code?  If you got this from one of our DVSDKs, which version?  Our earlier DVSDKs were all based on 2.6.10 MV kernel, but hey are very different when you consider the patches applied on top of this base kernel.

  • We buy it from Montavista, and I update it from TI website DM6446 to 4.0.1.

    I useing DVSDK 1_30_00_40

  • Dear Juan ,

    I try to fixed this and change the files (serial.c mux_cfg.c clock.c board-evm.c)  I try it and I saw the message below on bootloader:

    ttyS0 at MMIO 0x1c20000 (irq = 40) is a 16550A
    ttyS1 at MMIO 0x1c20400 (irq = 41) is a 16550A

    And while I run command line :

    root@192.168.10.33:~# stty -a < /dev/sttyS1
    -bash: /dev/sttyS1: No such file or directory
    root@192.168.10.33:~# mknod /dev/ttyS1 c 4 65
    root@192.168.10.33:~# stty sane 19200 raw -echo crtscts < /dev/ttyS1
    root@192.168.10.33:~# stty -a < /dev/ttyS1
    speed 19200 baud; rows 0; columns 0; line = 0;
    intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
    werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
    -parenb -parodd cs8 hupcl -cstopb cread clocal crtscts
    -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel
    -opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
    -isig -icanon iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

    But, then I tried send or receive data to the HyperTerminal.

    " echo "this is test" > /dev/ttyS1"

    I didn't see anything on HyperTerminal.

  • Dear Juan

    I also test the COM IRQ by command line:

    root@192.168.10.33:~# cat /proc/tty/driver/serial
    serinfo:1.0 driver revision:
    0: uart:16550A port:00000000 irq:40 tx:1482 rx:2 RTS|CTS|DTR|DSR
    1: uart:16550A port:00000000 irq:41 tx:0 rx:0 CTS|DSR
    root@192.168.10.33:~# echo this > /dev/ttyS1
    root@192.168.10.33:~# cat /proc/tty/driver/serial
    serinfo:1.0 driver revision:
    0: uart:16550A port:00000000 irq:40 tx:1482 rx:2 RTS|CTS|DTR|DSR
    1: uart:16550A port:00000000 irq:41 tx:0 rx:0 CTS|DSR

     

    thanks

  • so it seems you have made some progress.  at this point, I would recommend you hook up an oscilloscope to uart1 pins and see if there is any activity at the pins.  this should tell us if the software is simply misreporting data (in which case we still need to fix the software) or if indeed there is nothing happening. 

  • Thanks,

    You meaning UART1 pin on D Type or DSP pin??

    Is there possibility that  MUX is not set correct and can be the element problem?

  • The main data-sheet suggests UART2 is multiplexed with VPFE interface; therefore, PINMUX1 register needs to be set appropriately if you have not done this already.  Also, the data-sheet should tell you which pins on DM6446 correspond to UART2; these pins should be exposed via DC4 connector on EVM (see EVM Tech ref manual for details on pin mapping to DC4 connector: http://c6000.spectrumdigital.com/davincievm/revf/ )

  • I"m sorry if I confuse you,but I definitely confused also.

    I want to use with two serial port on my application.

    1. COM0 == UART0 == ( /dev/tts/0) // work fine

    2. COM1 == UART1 == (/dev/tts/1) // don`t work

    I din`t need UART2 == COM2 !!!

    Do I need to change or set any Driner or MUX to support COM0 & COM1

    So,as you know COM1 don`t get IRQ or cn`t send & receive data,  what sould I need do now?

  • The main data sheet describes PINMUX requirements for UART1 as well.  see http://focus.ti.com/docs/prod/folders/print/tms320dm6446.html

    The pins that make up UART1 interface are also exposed via EVM, thought thru a different DC connector, see EVM Tech Ref for more details http://c6000.spectrumdigital.com/davincievm/revf/

    That said, I would still recommend you try to connect an oscilloscope and see if there is any activity on the pins when you send and receive data; this should help us narrow down the problem.

  • Hi Juan Gonzales

    I would like to get your advice.

    I try to use COM1 & COM2 on my application Read/Write :

    open("/dev/tts/0", O_RDWR) /// COM0

    open("/dev/tts/1", O_RDWR) /// COM1

    and I set the bootargs : console=ttyS0,115200n8 ......

    but the debug print from the application and the kernel are rider also the serial out.

    what sould I need to do?

     

    Eran Segal

  • Hi Juan Gonzales

    I need your help.

    I need a interrupt based code for DM6446 uart code.

    This will help me.

    I dont need the code for uart but this will help me for developing other application for DM6446.

    I am waiting for your reply

    Regards,

    Rafaqat Raja


  • Eran said:

    open("/dev/tts/0", O_RDWR) /// COM0

    open("/dev/tts/1", O_RDWR) /// COM1

    and I set the bootargs : console=ttyS0,115200n8 ......

    but the debug print from the application and the kernel are rider also the serial out.

    Hi Eran,

    Apologies for the delayed response, but I have changed roles and I am no longer spending much time monitoring these forums; one of my colleages alerted me to this thread so I thought I would jump in and let you know of my role change (~ 2 months ago). 

    Does this mean you have both UART0 and UART1 working and you just want to change the default standard output of the system such that Linux does not dump debug info into the serial port you are trying to use?  If so, I believe the 'console' setting in your bootargs should do the trick.  This should allow you to use one of the UARTS as standard system output, and the other for your application.  Optionally, you can run a full blown GUI based OS along with a keyboard and mouse connected to the EVM and have the standrad output be the display (freeing your UART ports); this option would require a little more work.

     

  • Raja,

    I have changed roles and unfortunately my current role does not allow me to closely monitor these forums any longer.  I am not sure if you have had a chance to look at the following article (you seem new to this particular forum thread)

    http://linux.omap.com/pipermail/davinci-linux-open-source/2007-April/003097.html

    please note that our Linux driver source code already includes interrupt based sample reference code for DM6446 UART. 

  • Hai,

    I am new to DM6437. What would be the action get performed by CCS with that of DM6437?

    What were the initial setup need to be made to run DM6437?

     

  • Hai,

    I am intended to know the procedural steps need to made for live video tracking using DM6437?

    How to interface the external device with DM6437?

    Pls help me out?