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.

OMAP3530 GPMC Prefetch

HI,

To improve performance, we are trying to enable GPMC prefetch to access NAND (on CS0), however, we don't seem to get it to work.  The prefetch engine seems retrieving the first 64 bytes from NAND, since the GPMC_PREFETCH_STATUS  FIFOPOINTER is 0x40, and COUNTVALUE decreased by 0x40; but when the driver reads the data, the data do not seem returning from the FIFO, instead, it appears a direct access to the NAND, so that the second 64 bytes were returned.  And the FIFOPOINTER and COUNTVALUE does not change afterwards, as if the first 64 bytes were stuck in the FIFO. Am I missing anything here?

Here is the code:

#ifdef OMAP_NAND_PREFETCH

#define ENABLE_PREFETCH          (1<<7)

#define PREFETCH_FIFOTHRESHOLD   (0x40<<8)

static Boolean gpmc_prefetch_enable(uint32_t len, Boolean is_write)

{

    if (*pGPMC_PREFETCH_CONTROL)

        return false;   /* still busy */

    *pGPMC_PREFETCH_CONFIG1 = PREFETCH_FIFOTHRESHOLD | ENABLE_PREFETCH | (1 & is_write);

    *pGPMC_PREFETCH_CONFIG2 = len;

    /* wait until the device is ready */

    while (nand_busy(part));

     *pGPMC_PREFETCH_CONTROL = 1; /* start the engine */

     return true;

}

 

static void gpmc_prefetch_reset()

{

    *pGPMC_PREFETCH_CONTROL = 0; /* stop the engine */

    *pGPMC_PREFETCH_CONFIG1 = 0; /* disable prefetch */

}

 

static int32_t gpmc_prefetch_status()

{

    return *pGPMC_PREFETCH_STATUS;

}

#endif

 

void nand_read_data(const NandChip* part, uint8_t* data, uint32_t len)

{

    uint32_t i, *data_ptr, count, j=0;

 

    data_ptr = (uint32_t *)data;

#ifdef OMAP_NAND_PREFETCH

    if (gpmc_prefetch_enable(len, false))

    {

        do {

            count = (gpmc_prefetch_status() >> 24) & 0x7F; /* number of available bytes */

            for (i=0; i<count; i+=4)

            {

                data_ptr[j++] = *pGPMC_NAND_DATA;

            }

            len -= count;

        } while (len);

        gpmc_prefetch_reset();

    }

    else /* prefetch engine is busy, use direct access */

#endif 

    for (i=0; i<len; i+=4) {

        data_ptr[(i>>2)] = *pGPMC_NAND_DATA;

    }

}

 

Thanks in advance,

Bin

 

 

  • bing39062 said:
                for (i=0; i<count; i+=4)
                {
                    data_ptr[j++] = *pGPMC_NAND_DATA;
                }

    Here's a snippet from the TRM:

    When the ENABLEENGINE bit is set, any host access to this chip-select is rerouted to the FIFO input. Directly accessing the NAND device linked to this chip-select from the host  is still possible through the GPMC.GPMC_NAND_COMMAND_i, GPMC.GPMC_NAND_ADDRESS_i, and GPMC.GPMC_NAND_DATA_i registers (where i = 0 to 7).

    I assume your variable pGPMC_NAND_DATA is pointing to one of the GPMC_NAND_DATA_i registers.  According to the snippet above that will bypass the FIFO and directly access the NAND.  In order to access the FIFO you need to access the chip select space.

     

  • Brad, that was what I missed, thanks a lot!

    Bin

  • Hi Brad,

    I'm facing the same problem. I understand that we need to access FIFO directly and read from it instead of reading from gpmc nand data(x) register. Since you're saying we need to access the chip select space, is it the same as accessing FIFO directly? If so, which is the chip select space?

    Thanks.

  • The "chip select space" will be a combination of the global GPMC address space and your programming of the GPMC.  If you look in Chapter 2 Memory Mapping from the TRM you can find that the first GB of the address space (0x0000_0000 - 0x3FFF_FFFF).  However, a given chip select will not occupy that entire gigabyte.  The offset within that space (BASEADDR) and the size of the space (MASKADDRESS) are programmed inside the GPMC_CONFIG7_i register.

  • Alright, thanks for the valuable info. But does this mean that the prefetch FIFO buffer is mapped to the start of this BASEADDR? If not then how can a read issued to this location be the same as reading from the FIFO. 

  • Rajath Shetty said:
    Alright, thanks for the valuable info. But does this mean that the prefetch FIFO buffer is mapped to the start of this BASEADDR? If not then how can a read issued to this location be the same as reading from the FIFO. 

    Correct.  GPMC_PREFETCH_CONFIG1.ENGINECSSELECTOR assigns the prefetch engine to a specific chip select space.  BASEADDR defines where that chip select space begins.