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.

PROCESSOR-SDK-AM62X: Nand speed configurations in U-Boot

Part Number: PROCESSOR-SDK-AM62X
Other Parts Discussed in Thread: SK-AM62-LP

Tool/software:

Dear TI team,

Kindly support on the following topic:

1) GPMC Nand speed configurations from U-Boot device tree:

Context:

We are trying to optimize DFU flashing time in U-Boot, and we are using SDKLA v8.6, and GPMC Nand write speed in U-Boot is not as excepted (very low).

Expected behavior:

We expected to achieve at least minimum 8 MB/s (Miga byte / second) for GPMC Nand chip write speed in U-Boot.

Actual behavior:

The Nand chip write speed in U-Boot during copying data from DDR RAM to GPMC Nand is 0.4MB/s (Miga byte / second).

Questions:

1.a) How to configure U-Boot device tree to set max Nand chip read/write speed?

1.b) How to apply our application NAND/GPMC configuration (shown below) in U-Boot device tree?  Check footnote [1] for our failed trial to do so.

/*
 *  Copyright (C) 2021 Texas Instruments Incorporated
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*
 * Auto generated file
 */

#include "ti_drivers_config.h"
#include <drivers/device_manager/sciclient.h>

/*
 * GPMC
 */

/* Regions restricted for DMA. We should use CPU memcpy in these cases */
static GPMC_AddrRegion gGpmcDmaRestrictRegions[] =
{
    {
        .regionStartAddr = CSL_WKUP_R5FSS0_ATCM_BASE,
        .regionSize      = CSL_WKUP_R5FSS0_ATCM_SIZE,
    },
    {
        .regionStartAddr = CSL_WKUP_R5FSS0_BTCM_BASE,
        .regionSize      = CSL_WKUP_R5FSS0_BTCM_SIZE,
    },
    {
        .regionStartAddr = CSL_MCU_M4FSS0_IRAM_BASE,
        .regionSize      = CSL_MCU_M4FSS0_IRAM_SIZE,
    },
    {
        .regionStartAddr = CSL_MCU_M4FSS0_DRAM_BASE,
        .regionSize      = CSL_MCU_M4FSS0_DRAM_SIZE,
    },
    {
        .regionStartAddr = 0xFFFFFFFFU,
        .regionSize      = 0U,
    }
};


/* GPMC attributes */
static GPMC_HwAttrs gGpmcAttrs[CONFIG_GPMC_NUM_INSTANCES] =
{
    {
        .gpmcBaseAddr         = CSL_GPMC0_CFG_BASE,
        .dataBaseAddr         = CSL_GPMC0_DATA_BASE,
        .elmBaseAddr          = CSL_ELM0_BASE,
        .inputClkFreq         = 133333333U,
        .intrNum              = 103U,
        .intrPriority         = 4U,
        .chipSelBaseAddr      = 0x50000000U,
        .chipSelAddrSize      = GPMC_CS_MASK_ADDR_SIZE_16MB,
        .clkDivider           = CSL_GPMC_CONFIG1_GPMCFCLKDIVIDER_DIVBY1,
        .waitPinNum           = CSL_GPMC_CONFIG1_WAITPINSELECT_W0,
        .addrDataMux          = CSL_GPMC_CONFIG1_MUXADDDATA_NONMUX,
        .timeLatency          = CSL_GPMC_CONFIG1_TIMEPARAGRANULARITY_X1,
        .waitPinPol           = CSL_GPMC_CONFIG_WAIT0PINPOLARITY_W0ACTIVEL,
        .timingParams         =
        {
            .csOnTime               =   0U,
            .csRdOffTime            =   5U,
            .csWrOffTime            =   6U,
            .advOnTime              =   0U,
            .advRdOffTime           =   4U,
            .advWrOffTime           =   4U,
            .advAadMuxOnTime        =   0U,
            .advAadMuxRdOffTime     =   0U,
            .advAadMuxWrOffTime     =   0U,
            .weOnTtime              =   0U,
            .weOffTime              =   3U,
            .oeOnTime               =   1U,
            .oeOffTime              =   4U,
            .oeAadMuxOnTime         =   0U,
            .oeAadMuxOffTime        =   0U,
            .pageBurstAccess        =   0U,
            .rdAccessTime           =   5U,
            .wrAcessTime            =   6U,
            .rdCycleTime            =   5U,
            .wrCycleTime            =   5U,
            .wrDataOnMuxBusTime     =   0U,
            .cycle2CycleDelay       =   0U,
            .busTurnAroundTime      =   0U,
            .cycleDelaySameChipSel  =   CSL_GPMC_CONFIG6_CYCLE2CYCLESAMECSEN_NOC2CDELAY,
            .cycleDelayDiffChipSel  =   CSL_GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN_NOC2CDELAY,
        },
        .eccAlgo                =   GPMC_NAND_ECC_ALGO_BCH_8BIT,
        .readType               =   CSL_GPMC_CONFIG1_READTYPE_RDASYNC,
        .csExDelay              =   CSL_GPMC_CONFIG2_CSEXTRADELAY_NOTDELAYED,
        .accessType             =   CSL_GPMC_CONFIG1_READMULTIPLE_RDSINGLE,
        .optimisedAccess        =   CSL_GPMC_PREFETCH_CONFIG1_ENABLEOPTIMIZEDACCESS_OPTDISABLED,
        .dmaRestrictedRegions   =   gGpmcDmaRestrictRegions,
    },
};
/* GPMC objects - initialized by the driver */
static GPMC_Object gGpmcObjects[CONFIG_GPMC_NUM_INSTANCES];
/* GPMC driver configuration */
GPMC_Config gGpmcConfig[CONFIG_GPMC_NUM_INSTANCES] =
{
    {
        &gGpmcAttrs[CONFIG_GPMC0],
        &gGpmcObjects[CONFIG_GPMC0],
    },
};

uint32_t gGpmcConfigNum = CONFIG_GPMC_NUM_INSTANCES;




#include <drivers/gpmc/v0/dma/gpmc_dma.h>
#include <drivers/gpmc/v0/dma/udma/gpmc_dma_udma.h>
#include <drivers/udma.h>


/*
 * GPMC UDMA Blockcopy Parameters
 */
#define GPMC_UDMA_BLK_COPY_CH_RING_ELEM_CNT (1U)
#define GPMC_UDMA_BLK_COPY_CH_RING_MEM_SIZE (((GPMC_UDMA_BLK_COPY_CH_RING_ELEM_CNT * 8U) + UDMA_CACHELINE_ALIGNMENT) & ~(UDMA_CACHELINE_ALIGNMENT - 1U))
#define GPMC_UDMA_BLK_COPY_CH_TRPD_MEM_SIZE (UDMA_GET_TRPD_TR15_SIZE(1U))
#define GPMC_UDMA_NUM_BLKCOPY_CH (1U)

/* GPMC UDMA Blockcopy Channel Objects */
static Udma_ChObject gGpmcUdmaBlkCopyChObj[GPMC_UDMA_NUM_BLKCOPY_CH];

/* GPMC UDMA Blockcopy Channel Ring Mem */
static uint8_t gGpmcUdmaBlkCopyCh0RingMem[GPMC_UDMA_BLK_COPY_CH_RING_MEM_SIZE] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));

/* GPMC UDMA Blockcopy Channel TRPD Mem */
static uint8_t gGpmcUdmaBlkCopyCh0TrpdMem[GPMC_UDMA_BLK_COPY_CH_TRPD_MEM_SIZE] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));

GpmcDma_UdmaArgs gGpmcUdma0Args =
{
    .drvHandle     = &gUdmaDrvObj[CONFIG_UDMA0],
    .chHandle      = &gGpmcUdmaBlkCopyChObj[0],
    .trpdMem       = &gGpmcUdmaBlkCopyCh0TrpdMem,
    .trpdMemSize   = GPMC_UDMA_BLK_COPY_CH_TRPD_MEM_SIZE,
    .ringMem       = &gGpmcUdmaBlkCopyCh0RingMem,
    .ringMemSize   = GPMC_UDMA_BLK_COPY_CH_RING_MEM_SIZE,
    .ringElemCount = GPMC_UDMA_BLK_COPY_CH_RING_ELEM_CNT,
    .localEventID  = 26,
};
GPMC_DmaConfig gGpmcDmaConfig[CONFIG_GPMC_NUM_DMA_INSTANCES] =
{
    {
        .fxns        = &gGpmcDmaUdmaFxns,
        .gpmcDmaArgs = (void *)&gGpmcUdma0Args,
    }
};

uint32_t gGpmcDmaConfigNum = CONFIG_GPMC_NUM_DMA_INSTANCES;



/*
 * UDMA
 */
/* UDMA driver instance object */
Udma_DrvObject          gUdmaDrvObj[CONFIG_UDMA_NUM_INSTANCES];
/* UDMA driver instance init params */
static Udma_InitPrms    gUdmaInitPrms[CONFIG_UDMA_NUM_INSTANCES] =
{
    {
        .instId             = UDMA_INST_ID_BCDMA_0,
        .skipGlobalEventReg = TRUE,
        .virtToPhyFxn       = Udma_defaultVirtToPhyFxn,
        .phyToVirtFxn       = Udma_defaultPhyToVirtFxn,
    },
};

/*
 * I2C
 */
/* I2C atrributes */
static I2C_HwAttrs gI2cHwAttrs[CONFIG_I2C_NUM_INSTANCES] =
{
    {
        .baseAddr       = CSL_I2C0_CFG_BASE,
        .intNum         = 193,
        .eventId        = 0,
        .funcClk        = 96000000U,
        .enableIntr     = 0,
        .ownTargetAddr   =
        {
            0x1C,
            0x1C,
            0x1C,
            0x1C,
        },
    },
};
/* I2C objects - initialized by the driver */
static I2C_Object gI2cObjects[CONFIG_I2C_NUM_INSTANCES];
/* I2C driver configuration */
I2C_Config gI2cConfig[CONFIG_I2C_NUM_INSTANCES] =
{
    {
        .object = &gI2cObjects[CONFIG_I2C0],
        .hwAttrs = &gI2cHwAttrs[CONFIG_I2C0]
    },
};

uint32_t gI2cConfigNum = CONFIG_I2C_NUM_INSTANCES;

/*
 * UART
 */

/* UART atrributes */
static UART_Attrs gUartAttrs[CONFIG_UART_NUM_INSTANCES] =
{
    {
        .baseAddr           = CSL_WKUP_UART0_BASE,
        .inputClkFreq       = 96000000U,
    },
};
/* UART objects - initialized by the driver */
static UART_Object gUartObjects[CONFIG_UART_NUM_INSTANCES];
/* UART driver configuration */
UART_Config gUartConfig[CONFIG_UART_NUM_INSTANCES] =
{
    {
        &gUartAttrs[CONFIG_UART0],
        &gUartObjects[CONFIG_UART0],
    },
};

uint32_t gUartConfigNum = CONFIG_UART_NUM_INSTANCES;

#include <drivers/uart/v0/dma/uart_dma.h>


UART_DmaConfig gUartDmaConfig[CONFIG_UART_NUM_DMA_INSTANCES] =
{
};

uint32_t gUartDmaConfigNum = CONFIG_UART_NUM_DMA_INSTANCES;


void Drivers_uartInit(void)
{
    UART_init();
}

void Pinmux_init();
void PowerClock_init(void);
void PowerClock_deinit(void);

/*
 * Common Functions
 */
void System_init(void)
{
    /* DPL init sets up address transalation unit, on some CPUs this is needed
     * to access SCICLIENT services, hence this needs to happen first
     */
    Dpl_init();
    /* We should do sciclient init before we enable power and clock to the peripherals */
    /* SCICLIENT init */
    {

        int32_t retVal = SystemP_SUCCESS;

        retVal = Sciclient_direct_init();
        DebugP_assertNoLog(SystemP_SUCCESS == retVal);

    }
    PowerClock_init();
    /* Now we can do pinmux */
    Pinmux_init();
    /* finally we initialize all peripheral drivers */
    GPMC_init();
    /* UDMA */
    {
        uint32_t        instId;
        int32_t         retVal = UDMA_SOK;

        for(instId = 0U; instId < CONFIG_UDMA_NUM_INSTANCES; instId++)
        {
            retVal += Udma_init(&gUdmaDrvObj[instId], &gUdmaInitPrms[instId]);
            DebugP_assert(UDMA_SOK == retVal);
        }
    }
    I2C_init();
    Drivers_uartInit();
}

void System_deinit(void)
{
    GPMC_deinit();
    /* UDMA */
    {
        uint32_t        instId;
        int32_t         retVal = UDMA_SOK;

        for(instId = 0U; instId < CONFIG_UDMA_NUM_INSTANCES; instId++)
        {
            retVal += Udma_deinit(&gUdmaDrvObj[instId]);
            DebugP_assert(UDMA_SOK == retVal);
        }
    }
    I2C_deinit();
    UART_deinit();
    PowerClock_deinit();
    /* SCICLIENT deinit */
    {
        int32_t         retVal = SystemP_SUCCESS;

        retVal = Sciclient_deinit();
        DebugP_assertNoLog(SystemP_SUCCESS == retVal);
    }
    Dpl_deinit();
}

This is the uboot device tree code:

// SPDX-License-Identifier: GPL-2.0
/**
 * DT overlay for HSE NAND expansion card on AM62X LP-SK
 *
 * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
 */

#ifdef CONFIG_NAND_OMAP_GPMC
&elm0 {
	u-boot,dm-spl;
	status = "okay";
};

&main_pmx0 {
	gpmc0_pins_default: gpmc0-pins-default {
	       pinctrl-single,pins = <
		       AM62X_IOPAD(0x003c, PIN_INPUT, 0) /* (M25) GPMC0_AD0 */
		       AM62X_IOPAD(0x0040, PIN_INPUT, 0) /* (N23) GPMC0_AD1 */
		       AM62X_IOPAD(0x0044, PIN_INPUT, 0) /* (N24) GPMC0_AD2 */
		       AM62X_IOPAD(0x0048, PIN_INPUT, 0) /* (N25) GPMC0_AD3 */
		       AM62X_IOPAD(0x004c, PIN_INPUT, 0) /* (P24) GPMC0_AD4 */
		       AM62X_IOPAD(0x0050, PIN_INPUT, 0) /* (P22) GPMC0_AD5 */
		       AM62X_IOPAD(0x0054, PIN_INPUT, 0) /* (P21) GPMC0_AD6 */
		       AM62X_IOPAD(0x0058, PIN_INPUT, 0) /* (R23) GPMC0_AD7 */
		       AM62X_IOPAD(0x0084, PIN_OUTPUT, 0) /* (L23) GPMC0_ADVn_ALE */
		       AM62X_IOPAD(0x0088, PIN_OUTPUT, 0) /* (L24) GPMC0_OEn_REn */
		       AM62X_IOPAD(0x008c, PIN_OUTPUT, 0) /* (L25) GPMC0_WEn */
		       AM62X_IOPAD(0x0090, PIN_OUTPUT, 0) /* (M24) GPMC0_BE0n_CLE */
		       AM62X_IOPAD(0x00a8, PIN_OUTPUT, 0) /* (M21) GPMC0_CSn0 */
		       AM62X_IOPAD(0x0098, PIN_INPUT, 0) /* (U23) GPMC0_WAIT0 */
		>;
		u-boot,dm-spl;
	};
};

&gpmc0 {
	pinctrl-names = "default";
	status = "okay";
	pinctrl-0 = <&gpmc0_pins_default>;
	ranges = <0 0 0x00 0x51000000 0x01000000>; /* CS0 space. Min partition = 16MB */
	#address-cells = <2>;
	#size-cells = <1>;
	u-boot,dm-spl;

	nand0_0: nand@0,0 {
		compatible = "ti,am64-nand";
		reg = <0 0 64>;         /* device IO registers */
		interrupt-parent = <&gpmc0>;
		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
			     <1 IRQ_TYPE_NONE>; /* termcount */
		rb-gpios = <&gpmc0 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
		ti,nand-xfer-type = "prefetch-polled";
		ti,nand-ecc-opt = "bch8";       /* BCH8: Bootrom limitation */
		ti,elm-id = <&elm0>;
		nand-bus-width = <8>;
		gpmc,device-width = <1>;
		gpmc,sync-clk-ps = <0>;
		gpmc,cs-on-ns = <0>;
		gpmc,cs-rd-off-ns = <40>;
		gpmc,cs-wr-off-ns = <40>;
		gpmc,adv-on-ns = <0>;
		gpmc,adv-rd-off-ns = <25>;
		gpmc,adv-wr-off-ns = <25>;
		gpmc,we-on-ns = <0>;
		gpmc,we-off-ns = <20>;
		gpmc,oe-on-ns = <3>;
		gpmc,oe-off-ns = <30>;
		gpmc,access-ns = <30>;
		gpmc,rd-cycle-ns = <40>;
		gpmc,wr-cycle-ns = <40>;
		gpmc,bus-turnaround-ns = <0>;
		gpmc,cycle2cycle-delay-ns = <0>;
		gpmc,clk-activation-ns = <0>;
		gpmc,wr-access-ns = <40>;
		gpmc,wr-data-mux-bus-ns = <0>;
		u-boot,dm-spl;
	};
};


#endif

Thanks in advance.

This thread is created upon request from TI team in this previous thread:
https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1456727/processor-sdk-am62x-dfu-u-boot-flashing-speed-optimization-questions/5593398#5593398

FYI:

_________________________________________________________________________________________

Foot notes:

[1] I applied the nand chip configurations in uboot device tree as follow:

But I founded that I'm receiving wrong information from nand chip it seems that I'm reading wrong block size.

So, that I'm getting a bad block error because I'm reading the bad block marker from wrong location.

Attached Nand chip Datasheet:

2023_05_31-m79a_2gb_parallel_nand_auto (1).pdf

  • Dear TI team, could you please help us assign it on the right team, since this topic is heated?

     

    CC:

  • Hi Mohamed & Islam,
    I tested with Linux SDK 10.0.7.4 on "SK-AM62-LP + gpmc-nand daughter card"
    - boot USB-DFU boot mode
    - stop @u-boot prompt
    - read/write 32MB from/to GPMC-NAND to/from DDR

    where MT29F8G08ADAFAH4 is on the gpmc-nand daughter card as listed
    [ 1.713540] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xd3
    [ 1.719965] nand: Micron MT29F8G08ADAFAH4
    [ 1.723993] nand: 1024 MiB, SLC, erase size: 256 KiB, page size: 4096, OOB size: 256
    [ 1.731797] nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme

    The gpmc-nand read/write throughput(refer to the attached log)
    - ~11MB/s for reading from gpmc-nand to DDR
    - ~6MB/s for writing to gpmc-nand writer from DDR

    Best,
    -Hong

    U-Boot SPL 2024.04-dirty (Jan 08 2025 - 15:29:16 -0600)
    SYSFW ABI: 4.0 (firmware rev 0x000a '10.0.8--v10.00.08 (Fiery Fox)')
    SPL initial stack usage: 13392 bytes
    Trying to boot from DFU
    ###########################################################DOWNLOAD ... OK
    Ctrl+C to exit ...
    Authentication passed
    Authentication passed
    Authentication passed
    Loading Environment from nowhere... OK
    init_env from device 10 not supported!
    Authentication passed
    Authentication passed
    Starting ATF on ARM64 core...
    
    NOTICE:  BL31: v2.10.0(release):v2.10.0-367-g00f1ec6b87-dirty
    NOTICE:  BL31: Built : 16:09:05, Feb  9 2024
    
    U-Boot SPL 2024.04-dirty (Jan 08 2025 - 15:29:47 -0600)
    SYSFW ABI: 4.0 (firmware rev 0x000a '10.0.8--v10.00.08 (Fiery Fox)')
    SPL initial stack usage: 1904 bytes
    Trying to boot from DFU
    #####DOWNLOAD ... OK
    Ctrl+C to exit ...
    Authentication passed
    Authentication passed
    
    
    U-Boot 2024.04-dirty (Jan 08 2025 - 15:29:47 -0600)
    
    SoC:   AM62X SR1.0 HS-FS
    Model: Texas Instruments AM62x LP SK
    EEPROM not available at 0x50, trying to read at 0x51
    Board: AM62-LP-SKEVM rev E2
    DRAM:  2 GiB
    Core:  83 devices, 32 uclasses, devicetree: separate
    NAND:  1024 MiB
    MMC:   mmc@fa10000: 0, mmc@fa00000: 1
    Loading Environment from nowhere... OK
    In:    serial
    Out:   serial
    Err:   serial
    Net:   eth0: ethernet@8000000port@1
    Hit any key to stop autoboot:  0
    => time nand read ${loadaddr} 0x0 0x2000000
    
    NAND read: device 0 offset 0x0, size 0x2000000
     33554432 bytes read: OK
    
    time: 2.898 seconds
    => time nand write ${loadaddr} 0x0 0x2000000
    
    NAND write: device 0 offset 0x0, size 0x2000000
     33554432 bytes written: OK
    
    time: 5.241 seconds
    =>
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

  • Hello 

    1) Can you please share with us your U-Boot device tree configurations? Does your Nand configurations are the same as our configurations above?

    Notes:
    * We are able to get Nand read speed of 11 MB/Sec as your measurement.

    * Our Nand chip is "MT29F2G08ABBGAH4 " [Datasheet is attached above]

    Thanks

  • Hi Yasser,
    I tested with Linux SDK 10.0.7.4 w/o code change.
    This is the gpmc-nand dtsi file for SK-AM62-LP board.
    https://git.ti.com/cgit/ti-u-boot/ti-u-boot/tree/arch/arm/dts/k3-am62-lp-sk-nand.dtsi?h=10.00.07
    Best,
    -Hong