SAMA5 NAND: A few bug fixes for integration. Still lots more to do

This commit is contained in:
Gregory Nutt 2013-11-27 11:04:40 -06:00
parent 1fed0407b3
commit 5fb0062d2d
10 changed files with 57 additions and 61 deletions

View File

@ -3058,20 +3058,20 @@ config SAMA5_EBICS0_ECCNONE
config SAMA5_EBICS0_SWECC
bool "Software ECC"
depends on MTD_NAND_BLOCKCHECK && MTD_NAND_SWECC
depends on MTD_NAND_SWECC
---help---
ECC is performed by higher level software logic
config SAMA5_EBICS0_PMECC
bool "NAND H/W PMECC Support"
depends on MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC
depends on MTD_NAND_HWECC
select SAMA5_HAVE_PMECC
---help---
Enable hardware assisted support for ECC calculations
config SAMA5_EBICS0_CHIPECC
bool "Embedded chip ECC"
depends on MTD_NAND_BLOCKCHECK && MTD_NAND_EMBEDDEDECC
depends on MTD_NAND_EMBEDDEDECC
---help---
Some NAND devices have internal, embedded ECC function.
@ -3141,20 +3141,20 @@ config SAMA5_EBICS1_ECCNONE
config SAMA5_EBICS1_SWECC
bool "Software ECC"
depends on MTD_NAND_BLOCKCHECK && MTD_NAND_SWECC
depends on MTD_NAND_SWECC
---help---
ECC is performed by higher level software logic
config SAMA5_EBICS1_PMECC
bool "NAND H/W PMECC Support"
depends on MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC
depends on MTD_NAND_HWECC
select SAMA5_HAVE_PMECC
---help---
Enable hardware assisted support for ECC calculations
config SAMA5_EBICS1_CHIPECC
bool "Embedded chip ECC"
depends on MTD_NAND_BLOCKCHECK && MTD_NAND_EMBEDDEDECC
depends on MTD_NAND_EMBEDDEDECC
---help---
Some NAND devices have internal, embedded ECC function.
@ -3224,20 +3224,20 @@ config SAMA5_EBICS2_ECCNONE
config SAMA5_EBICS2_SWECC
bool "Software ECC"
depends on MTD_NAND_BLOCKCHECK && MTD_NAND_SWECC
depends on MTD_NAND_SWECC
---help---
ECC is performed by higher level software logic
config SAMA5_EBICS2_PMECC
bool "NAND H/W PMECC Support"
depends on MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC
depends on MTD_NAND_HWECC
select SAMA5_HAVE_PMECC
---help---
Enable hardware assisted support for ECC calculations
config SAMA5_EBICS2_CHIPECC
bool "Embedded chip ECC"
depends on MTD_NAND_BLOCKCHECK && MTD_NAND_EMBEDDEDECC
depends on MTD_NAND_EMBEDDEDECC
---help---
Some NAND devices have internal, embedded ECC function.
@ -3307,20 +3307,20 @@ config SAMA5_EBICS3_ECCNONE
config SAMA5_EBICS3_SWECC
bool "Software ECC"
depends on MTD_NAND_BLOCKCHECK && MTD_NAND_SWECC
depends on MTD_NAND_SWECC
---help---
ECC is performed by higher level software logic
config SAMA5_EBICS3_PMECC
bool "NAND H/W PMECC Support"
depends on MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC
depends on MTD_NAND_HWECC
select SAMA5_HAVE_PMECC
---help---
Enable hardware assisted support for ECC calculations
config SAMA5_EBICS3_CHIPECC
bool "Embedded chip ECC"
depends on MTD_NAND_BLOCKCHECK && MTD_NAND_EMBEDDEDECC
depends on MTD_NAND_EMBEDDEDECC
---help---
Some NAND devices have internal, embedded ECC function.

View File

@ -1003,7 +1003,7 @@ static void nand_dmacallback(DMA_HANDLE handle, void *arg, int result)
#ifdef CONFIG_SAMA5_NAND_DMA
static int nand_dma_read(struct sam_nandcs_s *priv,
uintptr_t vsrc, uintptr_t vdest, size_t nbytes,
uintptr_t vsrc, uintptr_t vdest, size_t nbytes,
uint32_t dmaflags)
{
uint32_t psrc;
@ -2356,9 +2356,6 @@ static int nand_readpage(struct nand_raw_s *raw, off_t block,
/* Read the page */
#ifndef CONFIG_MTD_NAND_BLOCKCHECK
ret = nand_readpage_noecc(priv, block, page, data, spare);
#else
DEBUGASSERT(raw->ecctype != NANDECC_SWECC);
switch (raw->ecctype)
{
@ -2376,7 +2373,6 @@ static int nand_readpage(struct nand_raw_s *raw, off_t block,
default:
ret = -EINVAL;
}
#endif
nand_unlock();
return ret;
@ -2420,9 +2416,6 @@ static int nand_writepage(struct nand_raw_s *raw, off_t block,
/* Write the page */
#ifndef CONFIG_MTD_NAND_BLOCKCHECK
ret = nand_writepage_noecc(priv, block, page, data, spare);
#else
DEBUGASSERT(raw->ecctype != NANDECC_SWECC);
switch (raw->ecctype)
{
@ -2440,7 +2433,6 @@ static int nand_writepage(struct nand_raw_s *raw, off_t block,
default:
ret = -EINVAL;
}
#endif
nand_unlock();
return ret;

View File

@ -90,19 +90,19 @@
# define SAMA5_EBICS0_ECCTYPE NANDECC_NONE
# elif defined(CONFIG_SAMA5_EBICS0_SWECC)
# if !defined(CONFIG_MTD_NAND_BLOCKCHECK) || !defined(CONFIG_MTD_NAND_SWECC)
# ifndef CONFIG_MTD_NAND_SWECC
# error CONFIG_SAMA5_EBICS0_SWECC is an invalid selection
# endif
# define SAMA5_EBICS0_ECCTYPE NANDECC_SWECC
# elif defined(CONFIG_SAMA5_EBICS0_PMECC)
# if !defined(CONFIG_MTD_NAND_BLOCKCHECK) || !defined(CONFIG_MTD_NAND_HWECC)
# ifndef CONFIG_MTD_NAND_HWECC
# error CONFIG_SAMA5_EBICS0_PMECC is an invalid selection
# endif
# define SAMA5_EBICS0_ECCTYPE NANDECC_PMECC
# elif defined(CONFIG_SAMA5_EBICS0_CHIPECC)
# if !defined(CONFIG_MTD_NAND_BLOCKCHECK) || !defined(CONFIG_MTD_NAND_EMBEDDEDECC)
# ifndef CONFIG_MTD_NAND_EMBEDDEDECC
# error CONFIG_SAMA5_EBICS0_CHIPECC is an invalid selection
# endif
# define SAMA5_EBICS0_ECCTYPE NANDECC_CHIPECC
@ -117,19 +117,19 @@
# define SAMA5_EBICS1_ECCTYPE NANDECC_NONE
# elif defined(CONFIG_SAMA5_EBICS1_SWECC)
# if !defined(CONFIG_MTD_NAND_BLOCKCHECK) || !defined(CONFIG_MTD_NAND_SWECC)
# ifndef CONFIG_MTD_NAND_SWECC
# error CONFIG_SAMA5_EBICS1_SWECC is an invalid selection
# endif
# define SAMA5_EBICS1_ECCTYPE NANDECC_SWECC
# elif defined(CONFIG_SAMA5_EBICS1_PMECC)
# if !defined(CONFIG_MTD_NAND_BLOCKCHECK) || !defined(CONFIG_MTD_NAND_HWECC)
# ifndef CONFIG_MTD_NAND_HWECC
# error CONFIG_SAMA5_EBICS1_PMECC is an invalid selection
# endif
# define SAMA5_EBICS1_ECCTYPE NANDECC_PMECC
# elif defined(CONFIG_SAMA5_EBICS1_CHIPECC)
# if !defined(CONFIG_MTD_NAND_BLOCKCHECK) || !defined(CONFIG_MTD_NAND_EMBEDDEDECC)
# ifndef CONFIG_MTD_NAND_EMBEDDEDECC
# error CONFIG_SAMA5_EBICS1_CHIPECC is an invalid selection
# endif
# define SAMA5_EBICS1_ECCTYPE NANDECC_CHIPECC
@ -144,19 +144,19 @@
# define SAMA5_EBICS2_ECCTYPE NANDECC_NONE
# elif defined(CONFIG_SAMA5_EBICS2_SWECC
# if !defined(CONFIG_MTD_NAND_BLOCKCHECK) || !defined(CONFIG_MTD_NAND_SWECC)
# ifndef CONFIG_MTD_NAND_SWECC
# error CONFIG_SAMA5_EBICS2_SWECC is an invalid selection
# endif
# define SAMA5_EBICS2_ECCTYPE NANDECC_SWECC
# elif defined(CONFIG_SAMA5_EBICS2_PMECC)
# if !defined(CONFIG_MTD_NAND_BLOCKCHECK) || !defined(CONFIG_MTD_NAND_HWECC)
# ifndef CONFIG_MTD_NAND_HWECC
# error CONFIG_SAMA5_EBICS2_PMECC is an invalid selection
# endif
# define SAMA5_EBICS2_ECCTYPE NANDECC_PMECC
# elif defined(CONFIG_SAMA5_EBICS2_CHIPECC)
# if !defined(CONFIG_MTD_NAND_BLOCKCHECK) || !defined(CONFIG_MTD_NAND_EMBEDDEDECC)
# ifndef CONFIG_MTD_NAND_EMBEDDEDECC
# error CONFIG_SAMA5_EBICS2_CHIPECC is an invalid selection
# endif
# define SAMA5_EBICS2_ECCTYPE NANDECC_CHIPECC
@ -171,19 +171,19 @@
# define SAMA5_EBICS3_ECCTYPE NANDECC_NONE
# elif defined(CONFIG_SAMA5_EBICS3_SWECC)
# if !defined(CONFIG_MTD_NAND_BLOCKCHECK) || !defined(CONFIG_MTD_NAND_SWECC)
# ifndef CONFIG_MTD_NAND_SWECC
# error CONFIG_SAMA5_EBICS3_SWECC is an invalid selection
# endif
# define SAMA5_EBICS3_ECCTYPE NANDECC_SWECC
# elif defined(CONFIG_SAMA5_EBICS3_PMECC)
# if !defined(CONFIG_MTD_NAND_BLOCKCHECK) || !defined(CONFIG_MTD_NAND_HWECC)
# ifndef CONFIG_MTD_NAND_HWECC
# error CONFIG_SAMA5_EBICS3_PMECC is an invalid selection
# endif
# define SAMA5_EBICS3_ECCTYPE NANDECC_PMECC
# elif defined(CONFIG_SAMA5_EBICS3_CHIPECC)
# if !defined(CONFIG_MTD_NAND_BLOCKCHECK) || !defined(CONFIG_MTD_NAND_EMBEDDEDECC)
# ifndef CONFIG_MTD_NAND_EMBEDDEDECC
# error CONFIG_SAMA5_EBICS3_CHIPECC is an invalid selection
# endif
# define SAMA5_EBICS3_ECCTYPE NANDECC_CHIPECC
@ -255,7 +255,7 @@ struct sam_nandcs_s
#ifdef CONFIG_SAMA5_PMECC_TRIMPAGE
bool dropjss; /* Enable page trimming */
uint16_t g_trimpage; /* Trim page number boundary */
uint16_t trimpage; /* Trim page number boundary */
#endif
#ifdef CONFIG_SAMA5_NAND_DMA

View File

@ -855,11 +855,13 @@ static void pmecc_pagelayout(uint16_t datasize, uint16_t sparesize,
uint8_t bcherr1k;
uint8_t bcherr;
fvdbg("datasize=%d sparesize=%d offset=%d\n", datasize, sparesize, offset);
/* ECC must not start at address zero, since bad block tags are at offset
* zero.
*/
DEBUGASSERT(offset > 0);
DEBUGASSERT(datasize != 0 && offset > 0);
/* Decrease the spare size by the offset */
@ -867,14 +869,14 @@ static void pmecc_pagelayout(uint16_t datasize, uint16_t sparesize,
/* Try for 512 byte sectors */
DEBUGASSERT((datasize & 0xfffffe00) == 0 && datasize >= 512);
DEBUGASSERT((datasize & 0x000001ff) == 0 && datasize >= 512);
nsectors512 = (datasize >> 9);
bcherr512 = pmecc_bcherr512(nsectors512, sparesize);
/* Try for 1024 byte sectors */
if ((datasize & 0xfffffc00) == 0)
if ((datasize & 0x000003ff) == 0)
{
nsectors1k = (datasize >> 9);
bcherr1k = pmecc_bcherr1k(nsectors1k, sparesize);
@ -1014,14 +1016,14 @@ int pmecc_configure(struct sam_nandcs_s *priv, uint16_t eccoffset,
/* 1024 bytes per sector */
g_pmecc.desc.sectorsz = HSMC_PMECCFG_SECTORSZ_1024;
sectorsperpage = (priv->raw.model.pagesize >> 10);
g_pmecc.desc.mm = 14;
sectorsperpage = (priv->raw.model.pagesize >> 10);
g_pmecc.desc.mm = 14;
#if defined (CONFIG_SAMA5_PMECC_GALOIS_TABLE1024_ROMADDR) && defined (CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES)
g_pmecc.desc.alphato = (int16_t *)&(pmecc_gf1024[PMECC_GF_SIZEOF_1024]);
g_pmecc.desc.indexof = (int16_t *)&(pmecc_gf1024[0]);
g_pmecc.desc.alphato = (int16_t *)&(pmecc_gf1024[PMECC_GF_SIZEOF_1024]);
g_pmecc.desc.indexof = (int16_t *)&(pmecc_gf1024[0]);
#else
g_pmecc.desc.alphato = (int16_t *)&(pmecc_gf1024[PMECC_GF_ALPHA_TO]);
g_pmecc.desc.indexof = (int16_t *)&(pmecc_gf1024[PMECC_GF_INDEX_OF]);
g_pmecc.desc.alphato = (int16_t *)&(pmecc_gf1024[PMECC_GF_ALPHA_TO]);
g_pmecc.desc.indexof = (int16_t *)&(pmecc_gf1024[PMECC_GF_INDEX_OF]);
#endif
}
else
@ -1029,14 +1031,14 @@ int pmecc_configure(struct sam_nandcs_s *priv, uint16_t eccoffset,
/* 512 bytes per sector */
g_pmecc.desc.sectorsz = HSMC_PMECCFG_SECTORSZ_512;
sectorsperpage = (priv->raw.model.pagesize >> 9);
g_pmecc.desc.mm = 13;
sectorsperpage = (priv->raw.model.pagesize >> 9);
g_pmecc.desc.mm = 13;
#if defined (CONFIG_SAMA5_PMECC_GALOIS_TABLE512_ROMADDR) && defined (CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES)
g_pmecc.desc.alphato = (int16_t *)&(pmecc_gf512[PMECC_GF_SIZEOF_512]);
g_pmecc.desc.indexof = (int16_t *)&(pmecc_gf512[0]);
g_pmecc.desc.alphato = (int16_t *)&(pmecc_gf512[PMECC_GF_SIZEOF_512]);
g_pmecc.desc.indexof = (int16_t *)&(pmecc_gf512[0]);
#else
g_pmecc.desc.alphato = (int16_t *)&(pmecc_gf512[PMECC_GF_ALPHA_TO]);
g_pmecc.desc.indexof = (int16_t *)&(pmecc_gf512[PMECC_GF_INDEX_OF]);
g_pmecc.desc.alphato = (int16_t *)&(pmecc_gf512[PMECC_GF_ALPHA_TO]);
g_pmecc.desc.indexof = (int16_t *)&(pmecc_gf512[PMECC_GF_INDEX_OF]);
#endif
}

View File

@ -58,7 +58,7 @@
/* Configuration ************************************************************/
/* Block checking and H/W ECC support must be enabled for PMECC */
#if !defined(CONFIG_MTD_NAND_BLOCKCHECK) || !defined(CONFIG_MTD_NAND_HWECC)
#ifndef CONFIG_MTD_NAND_HWECC
# undef CONFIG_SAMA5_EBICS0_PMECC
# undef CONFIG_SAMA5_EBICS1_PMECC
# undef CONFIG_SAMA5_EBICS2_PMECC

View File

@ -676,7 +676,7 @@ NAND Support
Drivers -> Memory Technology Device (MTD) Support
CONFIG_MTD=y : Enable MTD support
CONFIG_MTD_NAND=y : Enable NAND support
CONFIG_MTD_NAND_BLOCKCHECK=y : Enable bad block checking support
CONFIG_MTD_NAND_BLOCKCHECK=n : Interferes with NXFFS bad block checking
CONFIG_MTD_NAND_HWECC=y : Use H/W ECC calculation
Defaults for all other NAND settings should be okay

View File

@ -123,8 +123,6 @@ config MTD_NAND_BLOCKCHECK
---help---
Enable support for ECC and bad block checking.
if MTD_NAND_BLOCKCHECK
config MTD_NAND_SWECC
bool "Sofware ECC support"
default n if ARCH_NAND_HWECC
@ -145,8 +143,6 @@ config MTD_NAND_MAXSPAREEXTRABYTES
---help---
Maximum number of extra free bytes inside the spare area of a page.
endif # MTD_NAND_BLOCKCHECK
config MTD_NAND_EMBEDDEDECC
bool "Support devices with Embedded ECC"
default n

View File

@ -47,7 +47,7 @@ endif
ifeq ($(CONFIG_MTD_NAND),y)
CSRCS += mtd_nand.c mtd_onfi.c mtd_nandscheme.c mtd_nandmodel.c mtd_modeltab.c
ifeq ($(CONFIG_MTD_NAND_BLOCKCHECK),y)
ifeq ($(CONFIG_MTD_NAND_SWECC),y)
CSRCS += mtd_nandecc.c hamming.c
endif
endif

View File

@ -95,7 +95,7 @@ static int nand_checkblock(FAR struct nand_dev_s *nand, off_t block);
static int nand_devscan(FAR struct nand_dev_s *nand);
#else
# define nand_checkblock(n,b) (GOODBLOCK)
# define nand_devscan(n)
# define nand_devscan(n) (0)
#endif
/* Misc. NAND helpers */
@ -237,6 +237,11 @@ static int nand_checkblock(FAR struct nand_dev_s *nand, off_t block)
* Description:
* Scans the device to retrieve or create block status information.
*
* Currently, this functin does nothing but scan the NAND and eat up time.
* This is a goot thing to do if you are debugging NAND, but otherwise,
* just a waste of time. This logic could, however, be integrated into
* some bad block checking logic at sometime in the future.
*
* Input Parameters:
* nand - Pointer to a struct nand_dev_s instance.
*
@ -245,7 +250,8 @@ static int nand_checkblock(FAR struct nand_dev_s *nand, off_t block)
*
****************************************************************************/
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
//#ifdef CONFIG_MTD_NAND_BLOCKCHECK
#if defined(CONFIG_MTD_NAND_BLOCKCHECK) && defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
static int nand_devscan(FAR struct nand_dev_s *nand)
{
FAR struct nand_raw_s *raw;

View File

@ -201,7 +201,7 @@
*
****************************************************************************/
#ifdef MTD_NAND_HWECC
#ifdef CONFIG_MTD_NAND_HWECC
# define NAND_READPAGE(r,b,p,d,s) ((r)->readpage(r,b,p,d,s))
#else
# define NAND_READPAGE(r,b,p,d,s) ((r)->rawread(r,b,p,d,s))
@ -226,7 +226,7 @@
*
****************************************************************************/
#ifdef MTD_NAND_HWECC
#ifdef CONFIG_MTD_NAND_HWECC
# define NAND_WRITEPAGE(r,b,p,d,s) ((r)->writepage(r,b,p,d,s))
#else
# define NAND_WRITEPAGE(r,b,p,d,s) ((r)->rawwrite(r,b,p,d,s))
@ -268,7 +268,7 @@ struct nand_raw_s
FAR const void *spare);
#endif
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
#if defined(CONFIG_MTD_NAND_SWECC) || defined(CONFIG_MTD_NAND_HWECC)
/* ECC working buffers*/
uint8_t spare[CONFIG_MTD_NAND_MAXPAGESPARESIZE];