SAMA5 NAND: Retrofit trim page logic

This commit is contained in:
Gregory Nutt 2013-11-24 14:57:30 -06:00
parent 23d767a19e
commit f6bef28d96
4 changed files with 152 additions and 39 deletions

View File

@ -3039,6 +3039,7 @@ config SAMA5_EBICS0_NAND
bool "NAND Flash"
select MTD
select MTD_NAND
select SAMA5_HAVE_NAND
endchoice # CS0 Memory Type
@ -3061,6 +3062,7 @@ config SAMA5_EBICS0_SWECC
config SAMA5_EBICS0_PMECC
bool "NAND H/W PMECC Support"
depends on MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC
select SAMA5_HAVE_PMECC
---help---
Enable hardware assisted support for ECC calculations
@ -3120,6 +3122,7 @@ config SAMA5_EBICS1_NAND
bool "NAND Flash"
select MTD
select MTD_NAND
select SAMA5_HAVE_NAND
endchoice # CS1 Memory Type
@ -3142,6 +3145,7 @@ config SAMA5_EBICS1_SWECC
config SAMA5_EBICS1_PMECC
bool "NAND H/W PMECC Support"
depends on MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC
select SAMA5_HAVE_PMECC
---help---
Enable hardware assisted support for ECC calculations
@ -3201,6 +3205,7 @@ config SAMA5_EBICS2_NAND
bool "NAND Flash"
select MTD
select MTD_NAND
select SAMA5_HAVE_NAND
endchoice # CS2 Memory Type
@ -3223,6 +3228,7 @@ config SAMA5_EBICS2_SWECC
config SAMA5_EBICS2_PMECC
bool "NAND H/W PMECC Support"
depends on MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC
select SAMA5_HAVE_PMECC
---help---
Enable hardware assisted support for ECC calculations
@ -3282,6 +3288,7 @@ config SAMA5_EBICS3_NAND
bool "NAND Flash"
select MTD
select MTD_NAND
select SAMA5_HAVE_NAND
endchoice # CS3 Memory Type
@ -3304,6 +3311,7 @@ config SAMA5_EBICS3_SWECC
config SAMA5_EBICS3_PMECC
bool "NAND H/W PMECC Support"
depends on MTD_NAND_BLOCKCHECK && MTD_NAND_HWECC
select SAMA5_HAVE_PMECC
---help---
Enable hardware assisted support for ECC calculations
@ -3316,7 +3324,15 @@ config SAMA5_EBICS3_CHIPECC
endchoice # NAND ECC type
endif # SAMA5_EBICS3
if SAMA5_EBICS0_NAND || SAMA5_EBICS1_NAND || SAMA5_EBICS2_NAND || SAMA5_EBICS3_NAND
config SAMA5_HAVE_NAND
bool
default n
config SAMA5_HAVE_PMECC
bool
default n
if SAMA5_HAVE_NAND
config SAMA5_NAND_READYBUSY
bool "NAND Ready/Busy"
@ -3336,15 +3352,23 @@ config SAMA5_NAND_CE
void board_nand_ce(int cs, bool enable);
if SAMA5_EBICS0_NAND || SAMA5_EBICS1_NAND || SAMA5_EBICS2_NAND || SAMA5_EBICS3_NAND
if SAMA5_HAVE_PMECC
config MTD_NAND_MAX_PMECCSIZE
int "Max H/W ECC size"
default 200
depends on MTD_NAND_HWECC
---help---
Maximum HW ECC size
config SAMA5_PMECC_TRIMPAGE
bool "Trim page support"
default n
---help---
Support page trimming. This behavior was found to fix both UBI and
JFFS2 images written to cleanly erased NAND partitions. NOTE:
Nothing in the code base now uses these trim pages. Option support
is provided in case it becomes necessary in the future.
config SAMA5_PMECC_EMBEDDEDALGO
bool "ROM ECC detection/correction"
default y
@ -3386,9 +3410,8 @@ config SAMA5_PMECC_GALOIS_TABLE1024_ROMADDR
address unless you know what you are doing.
endif # SAMA5_PMECC_GALOIS_ROMTABLES
endif # SAMA5_EBICS*_PMECC
endif # SAMA5_EBICS*_NAND
endif # SAMA5_HAVE_PMECC
endif # SAMA5_HAVE_NAND
endmenu # External Memory Configuration
choice

View File

@ -179,7 +179,7 @@ static int nand_smc_read16(uintptr_t src, uint8_t *dest,
static int nand_read(struct sam_nandcs_s *priv, bool nfcsram,
uint8_t *buffer, size_t buflen);
#ifdef NAND_HAVE_PMECC
#ifdef CONFIG_SAMA5_HAVE_PMECC
static int nand_read_pmecc(struct sam_nandcs_s *priv, off_t block,
unsigned int page, void *data);
#endif
@ -198,7 +198,7 @@ static int nand_write(struct sam_nandcs_s *priv, bool nfcsram,
static int nand_readpage_noecc(struct sam_nandcs_s *priv, off_t block,
unsigned int page, void *data, void *spare);
#ifdef NAND_HAVE_PMECC
#ifdef CONFIG_SAMA5_HAVE_PMECC
static int nand_readpage_pmecc(struct sam_nandcs_s *priv, off_t block,
unsigned int page, void *data);
#endif
@ -206,7 +206,7 @@ static int nand_readpage_pmecc(struct sam_nandcs_s *priv, off_t block,
static int nand_writepage_noecc(struct sam_nandcs_s *priv, off_t block,
unsigned int page, const void *data, const void *spare);
#ifdef NAND_HAVE_PMECC
#ifdef CONFIG_SAMA5_HAVE_PMECC
static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block,
unsigned int page, const void *data);
#endif
@ -1246,7 +1246,7 @@ static int nand_read(struct sam_nandcs_s *priv, bool nfcsram,
*
****************************************************************************/
#ifdef NAND_HAVE_PMECC
#ifdef CONFIG_SAMA5_HAVE_PMECC
static int nand_read_pmecc(struct sam_nandcs_s *priv, off_t block,
unsigned int page, void *data)
{
@ -1619,7 +1619,7 @@ static int nand_readpage_noecc(struct sam_nandcs_s *priv, off_t block,
*
****************************************************************************/
#ifdef NAND_HAVE_PMECC
#ifdef CONFIG_SAMA5_HAVE_PMECC
static int nand_readpage_pmecc(struct sam_nandcs_s *priv, off_t block,
unsigned int page, void *data)
{
@ -1684,7 +1684,7 @@ static int nand_readpage_pmecc(struct sam_nandcs_s *priv, off_t block,
nand_unlock();
return ret;
}
#endif /* NAND_HAVE_PMECC */
#endif /* CONFIG_SAMA5_HAVE_PMECC */
/****************************************************************************
* Name: nand_writepage_noecc
@ -1845,7 +1845,7 @@ static int nand_writepage_noecc(struct sam_nandcs_s *priv, off_t block,
*
****************************************************************************/
#ifdef NAND_HAVE_PMECC
#ifdef CONFIG_SAMA5_HAVE_PMECC
static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block,
unsigned int page, const void *data)
{
@ -1953,8 +1953,8 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block,
eccpersector = (pmecc_get_eccsize()) / sectersperpage;
sectornumber = 1 << pmecc_get_pagesize();
#if 0 /* REVISIT. See original Atmel RawNandFlash.c */
if (isNandTrimffs() && page >= NandGetTrimPage())
#ifdef CONFIG_SAMA5_PMECC_TRIMPAGE
if (nand_trrimffs(priv) && page >= nand_get_trimpage(priv))
{
/* This behaviour was found to fix both UBI and JFFS2 images written to
* cleanly erased NAND partitions
@ -2000,7 +2000,7 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block,
nand_unlock();
return ret;
}
#endif /* NAND_HAVE_PMECC */
#endif /* CONFIG_SAMA5_HAVE_PMECC */
/****************************************************************************
* Name: nand_eraseblock
@ -2202,7 +2202,7 @@ static int nand_readpage(struct nand_raw_s *raw, off_t block,
case NANDECC_CHIPECC:
ret = nand_readpage_noecc(priv, block, page, data, spare);
#ifdef NAND_HAVE_PMECC
#ifdef CONFIG_SAMA5_HAVE_PMECC
case NANDECC_PMECC:
DEBUGASSERT(!spare);
ret = nand_readpage_pmecc(priv, block, page, data);
@ -2266,7 +2266,7 @@ static int nand_writepage(struct nand_raw_s *raw, off_t block,
case NANDECC_CHIPECC:
ret = nand_writepage_noecc(priv, block, page, data, spare);
#ifdef NAND_HAVE_PMECC
#ifdef CONFIG_SAMA5_HAVE_PMECC
case NANDECC_PMECC:
DEBUGASSERT(!spare);
ret = nand_writepage_pmecc(priv, block, page, data);
@ -2505,7 +2505,7 @@ struct mtd_dev_s *sam_nand_initialize(int cs)
nand_putreg(SAM_HSMC_CTRL, HSMC_CTRL_NFCEN);
#ifdef NAND_HAVE_PMECC
#ifdef CONFIG_SAMA5_HAVE_PMECC
/* Perform one-time initialization of the PMECC */
pmecc_initialize();

View File

@ -188,30 +188,30 @@
* enabled.
*/
#undef HAVE_NAND
#undef CONFIG_SAMA5_HAVE_NAND
#ifdef CONFIG_SAMA5_EBICS0_NAND
# define HAVE_NAND 1
# define CONFIG_SAMA5_HAVE_NAND 1
# define NAND_HAVE_EBICS0 1
#else
# define NAND_HAVE_EBICS0 0
#endif
#ifdef CONFIG_SAMA5_EBICS1_NAND
# define HAVE_NAND 1
# define CONFIG_SAMA5_HAVE_NAND 1
# define NAND_HAVE_EBICS1 1
#else
# define NAND_HAVE_EBICS1 0
#endif
#ifdef CONFIG_SAMA5_EBICS2_NAND
# define HAVE_NAND 1
# define CONFIG_SAMA5_HAVE_NAND 1
# define NAND_HAVE_EBICS2 1
#else
# define NAND_HAVE_EBICS2 0
#endif
#ifdef CONFIG_SAMA5_EBICS3_NAND
# define HAVE_NAND 1
# define CONFIG_SAMA5_HAVE_NAND 1
# define NAND_HAVE_EBICS3 1
#else
# define NAND_HAVE_EBICS3 0
@ -222,7 +222,7 @@
#define NAND_NBANKS \
(NAND_HAVE_EBICS0 + NAND_HAVE_EBICS1 + NAND_HAVE_EBICS2 + NAND_HAVE_EBICS3)
#ifdef HAVE_NAND
#ifdef CONFIG_SAMA5_HAVE_NAND
/****************************************************************************
* Public Types
@ -242,6 +242,10 @@ struct sam_nandcs_s
uint8_t cs; /* Chip select number (0..3) */
volatile bool dmadone; /* True: DMA has completed */
sem_t waitsem; /* Used to wait for DMA done */
#ifdef CONFIG_SAMA5_PMECC_TRIMPAGE
bool dropjss; /* Enable page trimming */
uint16_t g_trimpage; /* Trim page number boundary */
#endif
DMA_HANDLE dma; /* DMA channel assigned to this CS */
int result; /* The result of the DMA */
@ -259,7 +263,7 @@ struct sam_nand_s
volatile bool rbedge; /* True: Ready/busy edge detected */
sem_t waitsem; /* Used to wait for one of the above states */
#ifdef NAND_HAVE_PMECC
#ifdef CONFIG_SAMA5_HAVE_PMECC
uint8_t ecctab[CONFIG_MTD_NAND_MAX_PMECCSIZE];
#endif
@ -446,11 +450,101 @@ static inline void nand_putreg(uintptr_t regaddr, uint32_t regval)
putreg32(regval, regaddr);
}
/****************************************************************************
* Name: nand_trimffs_enable
*
* Description:
* Set current trimffs status.
*
* Input Parameters:
*
* Returned Value:
*
*
****************************************************************************/
#ifdef CONFIG_SAMA5_PMECC_TRIMPAGE
static inline void nand_trimffs_enable(struct sam_nandcs_s *priv, bool enable)
{
priv->dropjss = enable;
}
#else
# define nand_trimffs_enable(p,e)
#endif
/****************************************************************************
* Name: nand_trrimffs
*
* Description:
* Get current trimffs status.
*
* Input Parameters:
*
* Returned Value:
*
*
****************************************************************************/
#ifdef CONFIG_SAMA5_PMECC_TRIMPAGE
static inline bool nand_trrimffs(struct sam_nandcs_s *priv)
{
return priv->dropjss;
}
#else
# define nand_trrimffs(p) (false)
#endif
/****************************************************************************
* Name: nand_set_trimpage
*
* Description:
* Set current trimffs page.
*
* Input Parameters:
* page - Start trim page.
*
* Returned Value:
*
*
****************************************************************************/
#ifdef CONFIG_SAMA5_PMECC_TRIMPAGE
static inline void nand_set_trimpage(struct sam_nandcs_s *priv, uint16_t page)
{
priv->trimpage = page;
}
#else
# define nand_set_trimpage(p,t)
#endif
/****************************************************************************
* Name: nand_get_trimpage
*
* Description:
* Get current trimffs page.
*
* Input Parameters:
* None
*
* Returned Value:
* Start trim page.
*
****************************************************************************/
#ifdef CONFIG_SAMA5_PMECC_TRIMPAGE
uint16_t nand_get_trimpage(struct sam_nandcs_s *priv)
{
return priv->trimpage;
}
#else
# define nand_get_trimpage(p) (0)
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* HAVE_NAND */
#endif /* CONFIG_SAMA5_HAVE_NAND */
#endif /* __ARCH_ARM_SRC_SAMA5_SAM_NAND_H */

View File

@ -87,34 +87,30 @@
* enabled.
*/
#undef NAND_HAVE_PMECC
#undef CONFIG_SAMA5_HAVE_PMECC
#ifdef CONFIG_SAMA5_EBICS0_PMECC
# undef NAND_HAVE_PMECC
# define NAND_HAVE_PMECC 1
# define CONFIG_SAMA5_HAVE_PMECC 1
# define NAND_HAVE_EBICS0_PMECC 1
#else
# define NAND_HAVE_EBICS0_PMECC 0
#endif
#ifdef CONFIG_SAMA5_EBICS1_PMECC
# undef NAND_HAVE_PMECC
# define NAND_HAVE_PMECC 1
# define CONFIG_SAMA5_HAVE_PMECC 1
# define NAND_HAVE_EBICS1_PMECC 1
#else
# define NAND_HAVE_EBICS1_PMECC 0
#endif
#ifdef CONFIG_SAMA5_EBICS2_PMECC
# undef NAND_HAVE_PMECC
# define NAND_HAVE_PMECC 1
# define CONFIG_SAMA5_HAVE_PMECC 1
# define NAND_HAVE_EBICS2_PMECC 1
#else
# define NAND_HAVE_EBICS2_PMECC 0
#endif
#ifdef CONFIG_SAMA5_EBICS3_PMECC
# undef NAND_HAVE_PMECC
# define NAND_HAVE_PMECC 1
# define CONFIG_SAMA5_HAVE_PMECC 1
# define NAND_HAVE_EBICS3_PMECC 1
#else
# define NAND_HAVE_EBICS3_PMECC 0
@ -130,7 +126,7 @@
* and with PMECC support enabled.
*/
#ifdef NAND_HAVE_PMECC
#ifdef CONFIG_SAMA5_HAVE_PMECC
/* Maximum PMECC size */
@ -381,7 +377,7 @@ uint32_t pmecc_get_pagesize(void);
}
#endif
#else /* NAND_HAVE_PMECC */
#else /* CONFIG_SAMA5_HAVE_PMECC */
/****************************************************************************/
/* Stub definitions to minimize conditional compilation when PMECC is
* disabled
@ -396,5 +392,5 @@ uint32_t pmecc_get_pagesize(void);
# define pmecc_get_eccsize() (0)
# define pmecc_get_pagesize() (0)
#endif /* NAND_HAVE_PMECC */
#endif /* CONFIG_SAMA5_HAVE_PMECC */
#endif /* __ARCH_ARM_SRC_SAMA5_PMECC_H */