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