SAMA5 NAND: Still debugging

This commit is contained in:
Gregory Nutt 2013-11-28 12:21:33 -06:00
parent f171394ba9
commit 1ea447867a
10 changed files with 66 additions and 37 deletions

View file

@ -48,7 +48,7 @@
#include "sam_pmecc.h"
#ifndef CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES
#if defined(CONFIG_SAMA5_HAVE_PMECC) && !defined(CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES)
/**********************************************************************************************************************************
* Public Data
@ -2116,4 +2116,4 @@ const uint16_t pmecc_gf_1024[2][PMECC_GF_SIZEOF_1024] =
}
};
#endif /* CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES */
#endif /* CONFIG_SAMA5_HAVE_PMECC && !CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES */

View file

@ -48,7 +48,7 @@
#include "sam_pmecc.h"
#ifndef CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES
#if defined(CONFIG_SAMA5_HAVE_PMECC) && !defined(CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES)
/**********************************************************************************************************************************
* Public Data
@ -1092,4 +1092,4 @@ const uint16_t pmecc_gf512[2][PMECC_GF_SIZEOF_512] =
}
};
#endif /* CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES */
#endif /* CONFIG_SAMA5_HAVE_PMECC && !CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES */

View file

@ -1420,7 +1420,7 @@ static int nand_read_pmecc(struct sam_nandcs_s *priv, off_t block,
regval = nand_getreg(SAM_HSMC_PMECCTRL);
regval |= HSMC_PMECCTRL_DATA;
nand_putreg(SAM_HSMC_PMECCFG, regval);
nand_putreg(SAM_HSMC_PMECCTRL, regval);
regval = nand_getreg(SAM_HSMC_PMECCEADDR);
ret = nand_read(priv, true, (uint8_t *)data, pagesize + (regval + 1));
@ -2612,7 +2612,9 @@ struct mtd_dev_s *sam_nand_initialize(int cs)
{
/* Initialize the global nand state structure */
#if NAND_NBANKS > 1
sem_init(&g_nand.exclsem, 0, 1);
#endif
sem_init(&g_nand.waitsem, 0, 0);
/* Enable the NAND FLASH Controller (The NFC is always used) */
@ -2627,9 +2629,9 @@ struct mtd_dev_s *sam_nand_initialize(int cs)
#else
/* Disable the PMECC if it is not being used */
nand_putreg(SAM_SMC_PMECCTRL, HSMC_PMECCTRL_RST);
nand_putreg(SAM_SMC_PMECCTRL, HSMC_PMECCTRL_DISABLE);
nand_putreg(SAM_SMC_PMECCFG, 0);
nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_RST);
nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_DISABLE);
nand_putreg(SAM_HSMC_PMECCFG, 0);
#endif
/* Attach the CAN interrupt handler */
@ -2743,8 +2745,8 @@ bool nand_checkreg(bool wr, uintptr_t regaddr, uint32_t regval)
/* Save information about the new access */
g_nand.wr = wr;
g_nand.regval = regval;
g_nand.wr = wr;
g_nand.regval = regval;
g_nand.regadddr = regaddr;
g_nand.ntimes = 0;
}

View file

@ -268,11 +268,13 @@ struct sam_nandcs_s
struct sam_nand_s
{
bool initialized; /* True: One time initialization is complete */
#if NAND_NBANKS > 1
sem_t exclsem; /* Enforce exclusive access to the SMC hardware */
#endif
/* Dynamic state */
volatile bool cmddone; /* True: NFC commnad has completed */
volatile bool cmddone; /* True: NFC command has completed */
volatile bool xfrdone; /* True: Transfer has completed */
volatile bool rbedge; /* True: Ready/busy edge detected */
sem_t waitsem; /* Used to wait for one of the above states */

View file

@ -60,6 +60,12 @@
#include "sam_pmecc.h"
#include "sam_nand.h"
/* Compile this logic only if there is at least one CS configure for NAND
* and with PMECC support enabled.
*/
#ifdef CONFIG_SAMA5_HAVE_PMECC
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@ -1411,3 +1417,5 @@ void pmecc_buildgf(uint32_t mm, int16_t* indexof, int16_t* alphato)
indexof[0] = -1;
}
#endif /* CONFIG_SAMA5_PMECC_GALOIS_CUSTOM */
#endif /* CONFIG_SAMA5_HAVE_PMECC */

View file

@ -258,7 +258,7 @@ static void compute256(FAR const uint8_t *data, FAR uint8_t *code)
code[1] = (~(uint32_t)code[1]);
code[2] = (~(uint32_t)code[2]);
fvdbg("Computed code = %02X %02X %02X\n", code[0], code[1], code[2]);
fvdbg("Computed code: %02x %02x %02x\n", code[0], code[1], code[2]);
}
/****************************************************************************

View file

@ -104,18 +104,18 @@ static uint32_t nand_chipid(struct nand_raw_s *raw);
static int nand_eraseblock(FAR struct nand_dev_s *nand,
off_t block, bool scrub);
static int nand_readpage(FAR struct nand_dev_s *nand, off_t block,
unsigned int page, FAR uint8_t *buf);
unsigned int page, FAR uint8_t *data);
static int nand_writepage(FAR struct nand_dev_s *nand, off_t block,
unsigned int page, FAR const void *buf);
unsigned int page, FAR const void *data);
/* MTD driver methods */
static int nand_erase(struct mtd_dev_s *dev, off_t startblock,
size_t nblocks);
static ssize_t nand_bread(struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, uint8_t *buf);
size_t nblocks, uint8_t *buffer);
static ssize_t nand_bwrite(struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, const uint8_t *buf);
size_t nblocks, const uint8_t *buffer);
static int nand_ioctl(struct mtd_dev_s *dev, int cmd,
unsigned long arg);
@ -450,7 +450,7 @@ static int nand_eraseblock(FAR struct nand_dev_s *nand, off_t block,
* nand - Upper-half, NAND FLASH interface
* block - Number of the block where the page to read resides.
* page - Number of the page to read inside the given block.
* buf - Buffer where the data area will be stored.
* data - Buffer where the data area will be stored.
*
* Returned value.
* OK is returned in success; a negated errno value is returned on failure.
@ -458,8 +458,10 @@ static int nand_eraseblock(FAR struct nand_dev_s *nand, off_t block,
****************************************************************************/
static int nand_readpage(FAR struct nand_dev_s *nand, off_t block,
unsigned int page, FAR uint8_t *buf)
unsigned int page, FAR uint8_t *data)
{
fvdbg("block=%d page=%d data=%p\n", (int)block, page, data);
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
/* Check that the block is not BAD if data is requested */
@ -468,6 +470,7 @@ static int nand_readpage(FAR struct nand_dev_s *nand, off_t block,
fdbg("ERROR: Block is BAD\n");
return -EAGAIN;
}
#endif
#ifdef CONFIG_MTD_NAND_SWECC
/* nandecc_readpage will handle the software ECC case */
@ -477,7 +480,7 @@ static int nand_readpage(FAR struct nand_dev_s *nand, off_t block,
{
/* Read data with software ECC verification */
return nandecc_readpage(nand, block, page, buf, NULL);
return nandecc_readpage(nand, block, page, data, NULL);
}
/* The lower half will handle the No ECC and all hardware assisted
@ -485,10 +488,9 @@ static int nand_readpage(FAR struct nand_dev_s *nand, off_t block,
*/
else
#endif
#endif
{
return NAND_READPAGE(nand->raw, block, page, buf, NULL);
return NAND_READPAGE(nand->raw, block, page, data, NULL);
}
}
@ -503,7 +505,7 @@ static int nand_readpage(FAR struct nand_dev_s *nand, off_t block,
* nand - Upper-half, NAND FLASH interface
* block - Number of the block where the page to read resides.
* page - Number of the page to read inside the given block.
* buf - Buffer where the data area will be stored.
* data - Buffer where the data area will be stored.
*
* Returned value.
* OK is returned in success; a negated errno value is returned on failure.
@ -511,7 +513,7 @@ static int nand_readpage(FAR struct nand_dev_s *nand, off_t block,
****************************************************************************/
static int nand_writepage(FAR struct nand_dev_s *nand, off_t block,
unsigned int page, FAR const void *buf)
unsigned int page, FAR const void *data)
{
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
/* Check that the block is good */
@ -530,7 +532,7 @@ static int nand_writepage(FAR struct nand_dev_s *nand, off_t block,
{
/* Write data with software ECC calculation */
return nandecc_writepage(nand, block, page, buf, NULL);
return nandecc_writepage(nand, block, page, data, NULL);
}
/* The lower half will handle the No ECC and all hardware assisted
@ -541,7 +543,7 @@ static int nand_writepage(FAR struct nand_dev_s *nand, off_t block,
#endif
#endif
{
return NAND_WRITEPAGE(nand->raw, block, page, buf, NULL);
return NAND_WRITEPAGE(nand->raw, block, page, data, NULL);
}
}
@ -594,7 +596,7 @@ static int nand_erase(struct mtd_dev_s *dev, off_t startblock,
****************************************************************************/
static ssize_t nand_bread(struct mtd_dev_s *dev, off_t startpage,
size_t npages, FAR uint8_t *buf)
size_t npages, FAR uint8_t *buffer)
{
FAR struct nand_dev_s *nand = (FAR struct nand_dev_s *)dev;
FAR struct nand_raw_s *raw;
@ -638,7 +640,7 @@ static ssize_t nand_bread(struct mtd_dev_s *dev, off_t startpage,
{
/* Read the next page from NAND */
ret = nand_readpage(nand, block, page, buf);
ret = nand_readpage(nand, block, page, buffer);
if (ret < 0)
{
fdbg("ERROR: nand_readpage failed block=%ld page=%d: %d\n",
@ -665,7 +667,7 @@ static ssize_t nand_bread(struct mtd_dev_s *dev, off_t startpage,
/* Increment the buffer point by the size of one page */
buf += pagesize;
buffer += pagesize;
}
nand_unlock(nand);
@ -685,7 +687,7 @@ errout_with_lock:
****************************************************************************/
static ssize_t nand_bwrite(struct mtd_dev_s *dev, off_t startpage,
size_t npages, const uint8_t *buf)
size_t npages, const uint8_t *buffer)
{
FAR struct nand_dev_s *nand = (FAR struct nand_dev_s *)dev;
FAR struct nand_raw_s *raw;
@ -729,7 +731,7 @@ static ssize_t nand_bwrite(struct mtd_dev_s *dev, off_t startpage,
{
/* Write the next page into NAND */
ret = nand_writepage(nand, block, page, buf);
ret = nand_writepage(nand, block, page, buffer);
if (ret < 0)
{
fdbg("ERROR: nand_writepage failed block=%ld page=%d: %d\n",
@ -756,7 +758,7 @@ static ssize_t nand_bwrite(struct mtd_dev_s *dev, off_t startpage,
/* Increment the buffer point by the size of one page */
buf += pagesize;
buffer += pagesize;
}
nand_unlock(nand);

View file

@ -97,6 +97,8 @@ int nandecc_readpage(FAR struct nand_dev_s *nand, off_t block,
unsigned int sparesize;
int ret;
fvdbg("block=%d page=%d data=%p spare=%d\n", (int)block, page, data, spare);
/* Get convenience pointers */
DEBUGASSERT(nand && nand->raw);
@ -146,7 +148,7 @@ int nandecc_readpage(FAR struct nand_dev_s *nand, off_t block,
ret = hamming_verify256x(data, pagesize, raw->ecc);
if (ret && (ret != HAMMING_ERROR_SINGLEBIT))
{
fdbg("ERROR: Blockd paged Unrecoverable error:d\n",
fdbg("ERROR: Block=%d page=%d Unrecoverable error: %d\n",
block, page, ret);
return -EIO;
}
@ -187,6 +189,8 @@ int nandecc_writepage(FAR struct nand_dev_s *nand, off_t block,
unsigned int sparesize;
int ret;
fvdbg("block=%d page=%d data=%p spare=%d\n", (int)block, page, data, spare);
/* Get convenience pointers */
DEBUGASSERT(nand && nand->raw);

View file

@ -311,7 +311,8 @@ struct nxffs_blkstats_s
off_t ngood; /* Number of good FLASH blocks found */
off_t nbad; /* Number of well-formatted FLASH blocks marked as bad */
off_t nunformat; /* Number of unformatted FLASH blocks */
off_t ncorrupt; /* Number of blocks with correupted format info */
off_t ncorrupt; /* Number of blocks with corrupted format info */
off_t nbadread; /* Number of blocks that could not be read */
};
/****************************************************************************

View file

@ -107,8 +107,19 @@ int nxffs_blockstats(FAR struct nxffs_volume_s *volume,
ret = MTD_BREAD(volume->mtd, ioblock, volume->blkper, volume->pack);
if (ret < volume->blkper)
{
fdbg("Failed to read erase block %d: %d\n", ioblock / volume->blkper, -ret);
return ret;
/* This should not happen at all on most FLASH. A bad read will
* happen normally with a NAND device that has uncorrectable blocks.
* So, just for NAND, we keep the count of unreadable blocks.
*/
fdbg("Failed to read erase block %d: %d\n",
ioblock / volume->blkper, ret);
/* Declare all blocks in the eraseblock as bad */
stats->nblocks += volume->blkper;
stats->nbadread += volume->blkper;
continue;
}
/* Process each logical block */
@ -146,7 +157,6 @@ int nxffs_blockstats(FAR struct nxffs_volume_s *volume,
fdbg(" Bad blocks: %d\n", stats->nbad);
fdbg(" Unformatted blocks: %d\n", stats->nunformat);
fdbg(" Corrupt blocks: %d\n", stats->ncorrupt);
fdbg(" Undreadable blocks: %d\n", stats->nbadread);
return OK;
}