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 using DMA fast copy uImage to DDR in uboot

Other Parts Discussed in Thread: OMAPL138

hi.

all

when i start up my board (omapl138),

there is take a long time  to copy uImage and rootfs form spi flash ,

How to using DMA fast copy uImage to DDR in uboot?

now I use CONFIG_OMAP3_DMA,but copy failed!

Thanks

  • Hi Qiuxin,

    What is the size of your uImage and rootfs ?

    Are you using "initramfs" ?

  • Hi

     

    uImage  2M

    rootfs     16M

     

    To rootfs,I using ramdisk. Thanks

  • hi Titusrathinaraj Stalin

    Thanks, I want to know which modify uboot code to realize DMA fast copy way.

  • hi all

    My boot parameters:

    bootargs=mem=82m console=tty0 root=/dev/ram0 rw initrd=0xc3a00000,24M quiet
    bootcmd=sf probe 0 30000000;sf read 0xc1700000 0x380000 0x80000;sf read 0xc0700000 0x80000 0x200000;sf read 0xc3a00000 0x1000000 0x1000000;bootm 0xc0700000

    and 0xc1700000 is kernel-logo,0xc0700000 is kernel,0xc3a00000 is filesystems,which startup 26s .

    I want to add DMA fast copy way to reduce this time. My board is TI  omapL138

    Thanks.

  • Hi Qiuxin,

    Actually we don't have DMA support code for davinci (OMAPL13x) in u-boot but OMAP3 does.

    You can refer the OMAP3 DMA code and modify for davinci DMA.

    http://lists.denx.de/pipermail/u-boot/2011-September/102651.html

    http://lists.denx.de/pipermail/u-boot/2011-September/102651.html

    For bootloader speedup, please refer to the following links.

    http://elinux.org/Boot_Time#Bootloader_speedups

  • hi Titusrathinaraj  Stalin

    This src use nand flash about DMA. I want to use spi flash.they are different about read data form flash,which I copy failed. I use CONFIG_OMAP3_DMA,use drivers/dma/omap3_dma.c ,want to "sf read X X X" for DMA . I modify "drivers/spi/Davinci_spi.c" function "davinci_spi_read",but I can't modify

  • hi Titusrathinaraj  Stalin

    Init function:

    struct dma4_chan cfg;
    omap3_dma_init();

    /* config the channel */
    if (0 != omap3_dma_get_conf_chan(0, &cfg))
    {
    printf("omap3_dma_get_conf_chan failed.\n ");
    }

    cfg.csdp = CSDP_DATA_TYPE_32BIT | CSDP_SRC_BURST_EN_64BYTES |
    CSDP_DST_BURST_EN_64BYTES | CSDP_DST_ENDIAN_LOCK_ADAPT |
    CSDP_DST_ENDIAN_LITTLE | CSDP_SRC_ENDIAN_LOCK_ADAPT |
    CSDP_SRC_ENDIAN_LITTLE;
    cfg.cfn = 1;
    cfg.ccr = CCR_READ_PRIORITY_HIGH | CCR_SRC_AMODE_CONSTANT | CCR_DST_AMODE_POST_INC;
    cfg.cicr = (1 << 5) | (1 << 11) | (1 << 10) | (1 << 8);
    if (0 != omap3_dma_conf_chan(0, &cfg))
    {
    printf("omap3_dma_conf_chan failed.\n ");
    }

  • hi Titusrathinaraj  Stalin

    I want to use davinci_spi_read_dma replace davinci_spi_read about "sf read X X X ",but this function don't realize. 

    static int davinci_spi_read_dma(struct spi_slave *slave, unsigned int len,
    u8 *rxp, unsigned long flags)
    {
    struct davinci_spi_slave *ds = to_davinci_spi(slave);
    unsigned int data1_reg_val;
    printf("davinci_spi_read_dma start...\n");

    /* enable CS hold, CS[n] and clear the data bits */
    data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
    (slave->cs << SPIDAT1_CSNR_SHIFT));

    /* wait till TXFULL is deasserted */
    while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
    ;

    /* preload the TX buffer to avoid clock starvation */
    writel(data1_reg_val, &ds->regs->dat1);

    /* keep reading 1 byte until only 1 byte left */
    /*while ((len--) > 1)
    *rxp++ = davinci_spi_xfer_data(ds, data1_reg_val);*/

    int nRes = 0;
    nRes = omap3_dma_conf_transfer(0, ds, rxp, len);
    rxp += len;
    nRes = omap3_dma_start_transfer(0);
    nRes = omap3_dma_wait_for_transfer(0);

    /* clear CS hold when we reach the end */

    if (flags & SPI_XFER_END)
    data1_reg_val &= ~(1 << SPIDAT1_CSHOLD_SHIFT);

    /* read the last byte */
    *rxp = davinci_spi_xfer_data(ds, data1_reg_val);

    return 0;
    }

  • Hi Qiuxin,

    You have to understand the EDMA concept first and go for code walk through.

    We don't have a DMA support for davinci PSP u-boot release so you have to write your own EDMA driver for davinci with the reference of OMAP3 EDMA3 driver.

    I hope that need to change EDMA channel number and initialization could differ for davinci platform.

  • hi Titusrathinaraj  Stalin

     I watch to examples about spiedma.c in OMAPL_138 kernel,and I add this code to uboot. I use polling method,but in the function "Edma3ComplHandlerIsr", "isIPR = EDMA3GetIntrStatus(SOC_EDMA30CC_0_REGS)" return 0.

    I only use readflash function,as follows:

     

    /* ** This function reads data bytes from SPI Flash. */

    static void ReadFromFlash(volatile u8 *pReadFlash, unsigned int len)

    {    

    unsigned int buffLength = len;    

    unsigned int index = 0;    

    unsigned char *writeFlash = (unsigned char *) malloc (sizeof(unsigned char) * len);

        /* Set the first 4 bytes of writeFlash with SPI Flash Read   ** Instruction Sequence.     */  

      memset(writeFlash, 0, sizeof(unsigned char) * len);    

    writeFlash[0] = SPI_FLASH_READ;    

    writeFlash[1] = SPI_FLASH_ADDR_MSB1;    

    writeFlash[2] = SPI_FLASH_ADDR_MSB0;    

    writeFlash[3] = SPI_FLASH_ADDR_LSB;

        /* Configure the PaRAM registers in EDMA for Transmission.*/    

    SpiTxEdmaParamSet(EDMA3_CHA_SPI1_TX, EDMA3_CHA_SPI1_TX, writeFlash, buffLength);           

    /* Registering Callback Function for Transmission. */    

    cb_Fxn[EDMA3_CHA_SPI1_TX] = &callback;        

    /* Configure the PaRAM registers in EDMA for Reception.*/    

    SpiRxEdmaParamSet(EDMA3_CHA_SPI1_RX, EDMA3_CHA_SPI1_RX, pReadFlash, buffLength, TRUE);        

    /* Registering Callback Function for Reception. */    

    cb_Fxn[EDMA3_CHA_SPI1_RX] = &callback;        

    /* Assert the CSHOLD line corresponding to the SPI Flash. */    

    CSHoldAssert();        

    /* Enable SPI controller to generate DMA events */    

    SPIIntEnable(SOC_SPI_1_REGS, SPI_DMA_REQUEST_ENA_INT);        

    /* Wait until both the flags are set to 1 in the callback function. */   

      while((0 == flagTx) || (0 == flagRx))    

    {  

     Edma3ComplHandlerIsr();   

     Edma3CCErrHandlerIsr();

     }

     /* Disable SPI-EDMA Communication. */     SPIIntDisable(SOC_SPI_1_REGS, SPI_DMA_REQUEST_ENA_INT);

        flagTx = 0;     flagRx = 0;

      free(writeFlash);     

     pReadFlash += 4;  /*4是数据头,数据区*/    

    /* Deassert the CSHOLD line corresponding to the SPI Flash. */    

    CSHoldDeassert();   

    printf("ReadFromFlash end\n");

    }

    for flagTx return 1,but flagRx return 0, what is the matter for this problem. Thanks!