SAMA5 NAND: Still debugging
This commit is contained in:
parent
f171394ba9
commit
1ea447867a
10 changed files with 66 additions and 37 deletions
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue