Rethinking some NAND interfaces
This commit is contained in:
parent
9986d22e19
commit
448c8572cd
@ -6084,3 +6084,6 @@
|
||||
* drivers/mtd/hamming.c and mtd_nandecc.c and
|
||||
include/nuttx/mtd/hamming.h: Beginning of NAND software ECC
|
||||
calculations. (2013-11-18).
|
||||
* configs/olimex-lpc-h3131: Add support for the Olimex LPC-H3131
|
||||
board. Does not yet boot (2013-11-18).
|
||||
|
||||
|
@ -357,19 +357,35 @@
|
||||
|
||||
/* PMECC Configuration Register */
|
||||
|
||||
#define HSMC_PMECCFG_BCH_ERR_SHIFT (0) /* Bit 0-2: Error Correcting Capability */
|
||||
#define HSMC_PMECCFG_BCH_ERR_MASK (7 << HSMC_PMECCFG_BCH_ERR_SHIFT)
|
||||
# define HSMC_PMECCFG_BCH_ERR_2 (0 << HSMC_PMECCFG_BCH_ERR_SHIFT) /* 2 errors */
|
||||
# define HSMC_PMECCFG_BCH_ERR_4 (1 << HSMC_PMECCFG_BCH_ERR_SHIFT) /* 4 errors */
|
||||
# define HSMC_PMECCFG_BCH_ERR_8 (2 << HSMC_PMECCFG_BCH_ERR_SHIFT) /* 8 errors */
|
||||
# define HSMC_PMECCFG_BCH_ERR_12 (3 << HSMC_PMECCFG_BCH_ERR_SHIFT) /* 12 errors */
|
||||
# define HSMC_PMECCFG_BCH_ERR_24 (4 << HSMC_PMECCFG_BCH_ERR_SHIFT) /* 24 errors */
|
||||
#define HSMC_PMECCFG_SECTORSZ (1 << 4) /* Bit 4: Sector Size */
|
||||
#define HSMC_PMECCFG_BCHERR_SHIFT (0) /* Bit 0-2: Error Correcting Capability */
|
||||
#define HSMC_PMECCFG_BCHERR_MASK (7 << HSMC_PMECCFG_BCHERR_SHIFT)
|
||||
# define HSMC_PMECCFG_BCHERR_2 (0 << HSMC_PMECCFG_BCHERR_SHIFT) /* 2 errors */
|
||||
# define HSMC_PMECCFG_BCHERR_4 (1 << HSMC_PMECCFG_BCHERR_SHIFT) /* 4 errors */
|
||||
# define HSMC_PMECCFG_BCHERR_8 (2 << HSMC_PMECCFG_BCHERR_SHIFT) /* 8 errors */
|
||||
# define HSMC_PMECCFG_BCHERR_12 (3 << HSMC_PMECCFG_BCHERR_SHIFT) /* 12 errors */
|
||||
# define HSMC_PMECCFG_BCHERR_24 (4 << HSMC_PMECCFG_BCHERR_SHIFT) /* 24 errors */
|
||||
#define HSMC_PMECCFG_SECTORSZ_SHIFT (4) /* Bit 4: Sector Size */
|
||||
#define HSMC_PMECCFG_SECTORSZ_MASK (1 << HSMC_PMECCFG_SECTORSZ_SHIFT)
|
||||
# define HSMC_PMECCFG_SECTORSZ_512 (0 << HSMC_PMECCFG_SECTORSZ_SHIFT)
|
||||
# define HSMC_PMECCFG_SECTORSZ_1024 (1 << HSMC_PMECCFG_SECTORSZ_SHIFT)
|
||||
#define HSMC_PMECCFG_PAGESIZE_SHIFT (8) /* Bit 8-9: Number of Sectors in the Page */
|
||||
#define HSMC_PMECCFG_PAGESIZE_MASK (3 << HSMC_PMECCFG_PAGESIZE_SHIFT)
|
||||
#define HSMC_PMECCFG_NANDWR (1 << 12) /* Bit 12: NAND Write Access */
|
||||
#define HSMC_PMECCFG_SPAREEN (1 << 16) /* Bit 16: Spare Enable */
|
||||
#define HSMC_PMECCFG_AUTO (1 << 20) /* Bit 20: Automatic Mode Enable */
|
||||
# define HSMC_PMECCFG_PAGESIZE_1SEC (0 << HSMC_PMECCFG_PAGESIZE_SHIFT) /* 1 sector (5121K) */
|
||||
# define HSMC_PMECCFG_PAGESIZE_2SEC (1 << HSMC_PMECCFG_PAGESIZE_SHIFT) /* 2 sectors (1/2K) */
|
||||
# define HSMC_PMECCFG_PAGESIZE_4SEC (2 << HSMC_PMECCFG_PAGESIZE_SHIFT) /* 4 sectors (2/4K) */
|
||||
# define HSMC_PMECCFG_PAGESIZE_8SEC (3 << HSMC_PMECCFG_PAGESIZE_SHIFT) /* 8 sectors (4/8K) */
|
||||
#define HSMC_PMECCFG_NANDWR_SHIFT (12) /* Bit 12: NAND Write Access */
|
||||
#define HSMC_PMECCFG_NANDWR_MASK (1 << HSMC_PMECCFG_NANDWR_SHIFT)
|
||||
# define HSMC_PMECCFG_NANDWR_READ (0 << HSMC_PMECCFG_NANDWR_SHIFT)
|
||||
# define HSMC_PMECCFG_NANDWR_WRITE (1 << HSMC_PMECCFG_NANDWR_SHIFT)
|
||||
#define HSMC_PMECCFG_SPAREEN_SHIFT (16) /* Bit 16: Spare Enable */
|
||||
#define HSMC_PMECCFG_SPAREEN_MASK (1 << HSMC_PMECCFG_SPAREEN_SHIFT)
|
||||
# define HSMC_PMECCFG_SPARE_DISABLE (0 << HSMC_PMECCFG_SPAREEN_SHIFT)
|
||||
# define HSMC_PMECCFG_SPARE_ENABLE (1 << HSMC_PMECCFG_SPAREEN_SHIFT)
|
||||
#define HSMC_PMECCFG_AUTO_SHIFT (20) /* Bit 20: Automatic Mode Enable */
|
||||
#define HSMC_PMECCFG_AUTO_MASK (1 << HSMC_PMECCFG_AUTO_SHIFT)
|
||||
# define HSMC_PMECCFG_AUTO_DISABLE (0 << HSMC_PMECCFG_AUTO_SHIFT)
|
||||
# define HSMC_PMECCFG_AUTO_ENABLE (1 << HSMC_PMECCFG_AUTO_SHIFT)
|
||||
|
||||
/* PMECC Spare Area Size Register */
|
||||
|
||||
|
@ -64,6 +64,7 @@
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "sam_pmecc.h"
|
||||
#include "sam_nand.h"
|
||||
|
||||
/****************************************************************************
|
||||
@ -92,28 +93,44 @@ struct sam_rawnand_s
|
||||
|
||||
static int nand_readpage_noecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, void *data, void *spare);
|
||||
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
static int nand_readpage_hwecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, void *data, void *spare);
|
||||
static int nand_readpage_pmecc(struct sam_rawnand_s *priv, off_t block,
|
||||
|
||||
#ifdef NAND_HAVE_HSIAO
|
||||
static int nand_readpage_hsiao(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, void *data, void *spare);
|
||||
#endif
|
||||
|
||||
#ifdef NAND_HAVE_PMECC
|
||||
static int nand_readpage_pmecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, void *data);
|
||||
#endif
|
||||
|
||||
static int nand_writepage_noecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, const void *data, const void *spare);
|
||||
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
static int nand_writepage_hwecc(struct sam_rawnand_s *priv, off_t block,
|
||||
|
||||
#ifdef NAND_HAVE_HSIAO
|
||||
static int nand_writepage_hsiao(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, const void *data, const void *spare);
|
||||
#endif
|
||||
|
||||
#ifdef NAND_HAVE_PMECC
|
||||
static int nand_writepage_pmecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, const void *data, const void *spare);
|
||||
unsigned int page, const void *data);
|
||||
#endif
|
||||
|
||||
/* MTD driver methods */
|
||||
|
||||
static int nand_eraseblock(struct nand_raw_s *raw, off_t block);
|
||||
static int nand_rawread(struct nand_raw_s *raw, off_t block,
|
||||
unsigned int page, void *data, void *spare);
|
||||
static int nand_rawwrite(struct nand_raw_s *raw, off_t block,
|
||||
unsigned int page, const void *data, const void *spare);
|
||||
|
||||
#ifdef CONFIG_MTD_NAND_HWECC
|
||||
static int nand_readpage(struct nand_raw_s *raw, off_t block,
|
||||
unsigned int page, void *data, void *spare);
|
||||
static int nand_writepage(struct nand_raw_s *raw, off_t block,
|
||||
unsigned int page, const void *data, const void *spare);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
@ -167,7 +184,7 @@ static int nand_readpage_noecc(struct sam_rawnand_s *priv, off_t block,
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_readpage_hwecc
|
||||
* Name: nand_readpage_hsiao
|
||||
*
|
||||
* Description:
|
||||
* Reads the data and/or the spare areas of a page of a NAND FLASH into the
|
||||
@ -185,14 +202,14 @@ static int nand_readpage_noecc(struct sam_rawnand_s *priv, off_t block,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
static int nand_readpage_hwecc(struct sam_rawnand_s *priv, off_t block,
|
||||
#ifdef NAND_HAVE_HSIAO
|
||||
static int nand_readpage_hsiao(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, void *data, void *spare)
|
||||
{
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_MTD_NAND_BLOCKCHECK */
|
||||
#endif /* NAND_HAVE_HSIAO */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_readpage_pmecc
|
||||
@ -206,21 +223,20 @@ static int nand_readpage_hwecc(struct sam_rawnand_s *priv, off_t block,
|
||||
* block - Number of the block where the page to read resides.
|
||||
* page - Number of the page to read inside the given block.
|
||||
* data - Buffer where the data area will be stored.
|
||||
* spare - Buffer where the spare area will be stored.
|
||||
*
|
||||
* Returned value.
|
||||
* OK is returned in succes; a negated errno value is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
#ifdef NAND_HAVE_PMECC
|
||||
static int nand_readpage_pmecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, void *data, void *spare)
|
||||
unsigned int page, void *data)
|
||||
{
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_MTD_NAND_BLOCKCHECK */
|
||||
#endif /* NAND_HAVE_PMECC */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_writepage_noecc
|
||||
@ -249,7 +265,7 @@ static int nand_writepage_noecc(struct sam_rawnand_s *priv, off_t block,
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_writepage_noecc
|
||||
* Name: nand_writepage_hsaio
|
||||
*
|
||||
* Description:
|
||||
* Writes the data and/or the spare area of a page on a NAND FLASH chip.
|
||||
@ -267,42 +283,58 @@ static int nand_writepage_noecc(struct sam_rawnand_s *priv, off_t block,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
static int nand_writepage_hwecc(struct sam_rawnand_s *priv, off_t block,
|
||||
#ifdef NAND_HAVE_HSIAO
|
||||
static int nand_writepage_hsiao(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, const void *data, const void *spare)
|
||||
{
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
int ret;
|
||||
|
||||
/* Disable the PMECC */
|
||||
|
||||
pmecc_disable();
|
||||
|
||||
/* Perform write operation */
|
||||
# warning Missing logic
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_MTD_NAND_BLOCKCHECK */
|
||||
#endif /* NAND_HAVE_HSIAO */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_writepage_noecc
|
||||
* Name: nand_writepage_pmecc
|
||||
*
|
||||
* Description:
|
||||
* Writes the data and/or the spare area of a page on a NAND FLASH chip.
|
||||
* PMECC calculations are performed.
|
||||
* Writes the data area of a NAND FLASH page, The PMECC module generates
|
||||
* redundancy at encoding time. When a NAND write page operation is
|
||||
* performed. The redundancy is appended to the page and written in the
|
||||
* spare area.
|
||||
*
|
||||
* Input parameters:
|
||||
* priv - Lower-half, private NAND FLASH device state
|
||||
* block - Number of the block where the page to write resides.
|
||||
* page - Number of the page to write inside the given block.
|
||||
* data - Buffer containing the data to be writting
|
||||
* spare - Buffer conatining the spare data to be written.
|
||||
*
|
||||
* Returned value.
|
||||
* OK is returned in succes; a negated errno value is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
#ifdef NAND_HAVE_PMECC
|
||||
static int nand_writepage_pmecc(struct sam_rawnand_s *priv, off_t block,
|
||||
unsigned int page, const void *data, const void *spare)
|
||||
unsigned int page, const void *data)
|
||||
{
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
int ret;
|
||||
|
||||
/* Perform write operation */
|
||||
# warning Missing logic
|
||||
|
||||
/* Disable the PMECC */
|
||||
|
||||
pmecc_disable();
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_MTD_NAND_BLOCKCHECK */
|
||||
#endif /* NAND_HAVE_PMECC */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_eraseblock
|
||||
@ -328,11 +360,11 @@ static int nand_eraseblock(struct nand_raw_s *raw, off_t block)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_readpage
|
||||
* Name: nand_rawread
|
||||
*
|
||||
* Description:
|
||||
* Reads the data and/or the spare areas of a page of a NAND FLASH into the
|
||||
* provided buffers.
|
||||
* provided buffers. This is a raw read of the flash contents.
|
||||
*
|
||||
* Input parameters:
|
||||
* raw - Lower-half, raw NAND FLASH interface
|
||||
@ -346,6 +378,65 @@ static int nand_eraseblock(struct nand_raw_s *raw, off_t block)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int nand_rawread(struct nand_raw_s *raw, off_t block,
|
||||
unsigned int page, void *data, void *spare)
|
||||
{
|
||||
struct sam_rawnand_s *priv = (struct sam_rawnand_s *)raw;
|
||||
DEBUGASSERT(raw);
|
||||
|
||||
return nand_readpage_noecc(priv, block, page, data, spare);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_rawwrite
|
||||
*
|
||||
* Description:
|
||||
* Writes the data and/or the spare area of a page on a NAND FLASH chip.
|
||||
* This is a raw write of the flash contents.
|
||||
*
|
||||
* Input parameters:
|
||||
* raw - Lower-half, raw NAND FLASH interface
|
||||
* block - Number of the block where the page to write resides.
|
||||
* page - Number of the page to write inside the given block.
|
||||
* data - Buffer containing the data to be writting
|
||||
* spare - Buffer containing the spare data to be written.
|
||||
*
|
||||
* Returned value.
|
||||
* OK is returned in succes; a negated errno value is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int nand_rawwrite(struct nand_raw_s *raw, off_t block,
|
||||
unsigned int page, const void *data,
|
||||
const void *spare)
|
||||
{
|
||||
struct sam_rawnand_s *priv = (struct sam_rawnand_s *)raw;
|
||||
DEBUGASSERT(raw);
|
||||
|
||||
return nand_writepage_noecc(priv, block, page, data, spare);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_readpage
|
||||
*
|
||||
* Description:
|
||||
* Reads the data and/or the spare areas of a page of a NAND FLASH into the
|
||||
* provided buffers. Hardware ECC checking will be performed if so
|
||||
* configured.
|
||||
*
|
||||
* Input parameters:
|
||||
* raw - Lower-half, raw 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.
|
||||
* data - Buffer where the data area will be stored.
|
||||
* spare - Buffer where the spare area will be stored.
|
||||
*
|
||||
* Returned value.
|
||||
* OK is returned in succes; a negated errno value is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_MTD_NAND_HWECC
|
||||
static int nand_readpage(struct nand_raw_s *raw, off_t block,
|
||||
unsigned int page, void *data, void *spare)
|
||||
{
|
||||
@ -359,11 +450,19 @@ static int nand_readpage(struct nand_raw_s *raw, off_t block,
|
||||
switch (raw->ecctype)
|
||||
{
|
||||
case NANDECC_NONE:
|
||||
case NANDECC_CHIPECC:
|
||||
return nand_readpage_noecc(priv, block, page, data, spare);
|
||||
case NANDECC_HWECC:
|
||||
return nand_readpage_hwecc(priv, block, page, data, spare);
|
||||
|
||||
#ifdef NAND_HAVE_HSIAO
|
||||
case NANDECC_HSIAO:
|
||||
return nand_readpage_hsiao(priv, block, page, data, spare);
|
||||
#endif
|
||||
|
||||
#ifdef NAND_HAVE_PMECC
|
||||
case NANDECC_PMECC:
|
||||
return nand_readpage_pmecc(priv, block, page, data, spare);
|
||||
DEBUGASSERT(!spare);
|
||||
return nand_readpage_pmecc(priv, block, page, data);
|
||||
#endif
|
||||
|
||||
case NANDECC_SWECC:
|
||||
default:
|
||||
@ -371,12 +470,14 @@ static int nand_readpage(struct nand_raw_s *raw, off_t block,
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_writepage
|
||||
*
|
||||
* Description:
|
||||
* Writes the data and/or the spare area of a page on a NAND FLASH chip.
|
||||
* Hardware ECC checking will be performed if so configured.
|
||||
*
|
||||
* Input parameters:
|
||||
* raw - Lower-half, raw NAND FLASH interface
|
||||
@ -390,6 +491,7 @@ static int nand_readpage(struct nand_raw_s *raw, off_t block,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_MTD_NAND_HWECC
|
||||
static int nand_writepage(struct nand_raw_s *raw, off_t block,
|
||||
unsigned int page, const void *data,
|
||||
const void *spare)
|
||||
@ -404,11 +506,19 @@ static int nand_writepage(struct nand_raw_s *raw, off_t block,
|
||||
switch (raw->ecctype)
|
||||
{
|
||||
case NANDECC_NONE:
|
||||
case NANDECC_CHIPECC:
|
||||
return nand_writepage_noecc(priv, block, page, data, spare);
|
||||
case NANDECC_HWECC:
|
||||
return nand_writepage_hwecc(priv, block, page, data, spare);
|
||||
|
||||
#ifdef NAND_HAVE_HSIAO
|
||||
case NANDECC_HSIAO:
|
||||
return nand_writepage_hsiao(priv, block, page, data, spare);
|
||||
#endif
|
||||
|
||||
#ifdef NAND_HAVE_PMECC
|
||||
case NANDECC_PMECC:
|
||||
return nand_writepage_pmecc(priv, block, page, data, spare);
|
||||
DEBUGASSERT(!spare);
|
||||
return nand_writepage_pmecc(priv, block, page, data);
|
||||
#endif
|
||||
|
||||
case NANDECC_SWECC:
|
||||
default:
|
||||
@ -416,6 +526,7 @@ static int nand_writepage(struct nand_raw_s *raw, off_t block,
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@ -532,8 +643,12 @@ struct mtd_dev_s *sam_nand_initialize(int cs)
|
||||
priv->raw.addraddr = addraddr;
|
||||
priv->raw.dataaddr = dataaddr;
|
||||
priv->raw.eraseblock = nand_eraseblock;
|
||||
priv->raw.rawread = nand_rawread;
|
||||
priv->raw.rawwrite = nand_rawwrite;
|
||||
#ifdef CONFIG_MTD_NAND_HWECC
|
||||
priv->raw.readpage = nand_readpage;
|
||||
priv->raw.writepage = nand_writepage;
|
||||
#endif
|
||||
priv->cs = cs;
|
||||
|
||||
/* Initialize the NAND hardware */
|
||||
|
@ -50,6 +50,40 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
/* Block checking and H/W ECC support must be enabled for HSIAO ECC */
|
||||
|
||||
#if !defined(CONFIG_MTD_NAND_BLOCKCHECK) || !defined(MTD_NAND_HWECC)
|
||||
# undef CONFIG_SAMA5_EBICS0_HSIAO
|
||||
# undef CONFIG_SAMA5_EBICS1_HSIAO
|
||||
# undef CONFIG_SAMA5_EBICS2_HSIAO
|
||||
# undef CONFIG_SAMA5_EBICS3_HSIAO
|
||||
#endif
|
||||
|
||||
/* Disable HSIAO support for any banks not enabled or configured for NAND */
|
||||
|
||||
#if !defined(SAMA5_EBICS0) || !defined(SAMA5_EBICS0_NAND)
|
||||
# undef CONFIG_SAMA5_EBICS0_HSIAO
|
||||
#endif
|
||||
|
||||
#if !defined(SAMA5_EBICS1) || !defined(SAMA5_EBICS1_NAND)
|
||||
# undef CONFIG_SAMA5_EBICS1_HSIAO
|
||||
#endif
|
||||
|
||||
#if !defined(SAMA5_EBICS2) || !defined(SAMA5_EBICS2_NAND)
|
||||
# undef CONFIG_SAMA5_EBICS2_HSIAO
|
||||
#endif
|
||||
|
||||
#if !defined(SAMA5_EBICS3) || !defined(SAMA5_EBICS3_NAND)
|
||||
# undef CONFIG_SAMA5_EBICS3_HSIAO
|
||||
#endif
|
||||
|
||||
#undef NAND_HAVE_HSIAO
|
||||
#if defined(CONFIG_SAMA5_EBICS0_HSIAO) || defined(CONFIG_SAMA5_EBICS1_HSIAO) || \
|
||||
defined(CONFIG_SAMA5_EBICS2_HSIAO) || defined(CONFIG_SAMA5_EBICS3_HSIAO)
|
||||
# define NAND_HAVE_HSIAO
|
||||
#endif
|
||||
|
||||
/* Hardware ECC types. These are extensions to the NANDECC_HWECC value
|
||||
* defined in include/nuttx/mtd/nand_raw.h.
|
||||
*
|
||||
|
242
arch/arm/src/sama5/sam_pmecc.h
Normal file
242
arch/arm/src/sama5/sam_pmecc.h
Normal file
@ -0,0 +1,242 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/sama5/sam_pmecc.h
|
||||
*
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* This logic was based largely on Atmel sample code with modifications for
|
||||
* better integration with NuttX. The Atmel sample code has a BSD
|
||||
* compatibile license that requires this copyright notice:
|
||||
*
|
||||
* Copyright (c) 2010, Atmel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the names NuttX nor Atmel nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_SAMA5_PMECC_H
|
||||
#define __ARCH_ARM_SRC_SAMA5_PMECC_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/mtd/nand_config.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
/* Block checking and H/W ECC support must be enabled for PMECC */
|
||||
|
||||
#if !defined(CONFIG_MTD_NAND_BLOCKCHECK) || !defined(MTD_NAND_HWECC)
|
||||
# undef CONFIG_SAMA5_EBICS0_PMECC
|
||||
# undef CONFIG_SAMA5_EBICS1_PMECC
|
||||
# undef CONFIG_SAMA5_EBICS2_PMECC
|
||||
# undef CONFIG_SAMA5_EBICS3_PMECC
|
||||
#endif
|
||||
|
||||
/* Disable PMECC support for any banks not enabled or configured for NAND */
|
||||
|
||||
#if !defined(SAMA5_EBICS0) || !defined(SAMA5_EBICS0_NAND)
|
||||
# undef CONFIG_SAMA5_EBICS0_PMECC
|
||||
#endif
|
||||
|
||||
#if !defined(SAMA5_EBICS1) || !defined(SAMA5_EBICS1_NAND)
|
||||
# undef CONFIG_SAMA5_EBICS1_PMECC
|
||||
#endif
|
||||
|
||||
#if !defined(SAMA5_EBICS2) || !defined(SAMA5_EBICS2_NAND)
|
||||
# undef CONFIG_SAMA5_EBICS2_PMECC
|
||||
#endif
|
||||
|
||||
#if !defined(SAMA5_EBICS3) || !defined(SAMA5_EBICS3_NAND)
|
||||
# undef CONFIG_SAMA5_EBICS3_PMECC
|
||||
#endif
|
||||
|
||||
/* Count the number of banks that confaigured for NAND with PMECC support
|
||||
* enabled.
|
||||
*/
|
||||
|
||||
#undef NAND_HAVE_PMECC
|
||||
#ifdef CONFIG_SAMA5_EBICS0_PMECC
|
||||
# undef NAND_HAVE_PMECC
|
||||
# define NAND_HAVE_PMECC 1
|
||||
# define NAND_HAVE_EBIS0_PMECC 1
|
||||
#else
|
||||
# define NAND_HAVE_EBIS0_PMECC 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SAMA5_EBICS1_PMECC
|
||||
# undef NAND_HAVE_PMECC
|
||||
# define NAND_HAVE_PMECC 1
|
||||
# define NAND_HAVE_EBIS1_PMECC 1
|
||||
#else
|
||||
# define NAND_HAVE_EBIS1_PMECC 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SAMA5_EBICS2_PMECC
|
||||
# undef NAND_HAVE_PMECC
|
||||
# define NAND_HAVE_PMECC 1
|
||||
# define NAND_HAVE_EBIS2_PMECC 1
|
||||
#else
|
||||
# define NAND_HAVE_EBIS2_PMECC 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SAMA5_EBICS3_PMECC
|
||||
# undef NAND_HAVE_PMECC
|
||||
# define NAND_HAVE_PMECC 1
|
||||
# define NAND_HAVE_EBIS3_PMECC 1
|
||||
#else
|
||||
# define NAND_HAVE_EBIS3_PMECC 0
|
||||
#endif
|
||||
|
||||
/* Count the number of banks using PMECC */
|
||||
|
||||
#define NAND_NPMECC_BANKS \
|
||||
(NAND_HAVE_EBIS0_PMECC + NAND_HAVE_EBIS1_PMECC + \
|
||||
NAND_HAVE_EBIS2_PMECC + NAND_HAVE_EBIS3_PMECC
|
||||
|
||||
/* Compile this logic only if there is at least one CS configure for NAND
|
||||
* and with PMECC support enabled.
|
||||
*/
|
||||
|
||||
#ifdef NAND_HAVE_PMECC
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmecc_lock
|
||||
*
|
||||
* Description:
|
||||
* Get exclusive access to PMECC hardware
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if NAND_NPMECC_BANKS > 1
|
||||
void pmecc_lock(void);
|
||||
#else
|
||||
# define pmecc_lock()
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmecc_unlock
|
||||
*
|
||||
* Description:
|
||||
* Relinquish exclusive access to PMECC hardware
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if NAND_NPMECC_BANKS > 1
|
||||
void pmecc_unlock(void);
|
||||
#else
|
||||
# define pmecc_unlock()
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmecc_enable
|
||||
*
|
||||
* Description:
|
||||
* Enable PMECC
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void pmecc_enable(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmecc_disable
|
||||
*
|
||||
* Description:
|
||||
* Enable PMECC
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void pmecc_disable(void);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* NAND_HAVE_PMECC */
|
||||
/****************************************************************************/
|
||||
/* Stub definitions to minimize conditional compilation when PMECC is
|
||||
* disabled
|
||||
*/
|
||||
|
||||
# define pmecc_lock()
|
||||
# define pmecc_unlock()
|
||||
# define pmecc_enable()
|
||||
# define pmecc_disable()
|
||||
|
||||
#endif /* NAND_HAVE_PMECC */
|
||||
#endif /* __ARCH_ARM_SRC_SAMA5_PMECC_H */
|
@ -197,7 +197,7 @@ static int nand_checkblock(FAR struct nand_dev_s *nand, off_t block)
|
||||
|
||||
/* Read spare area of first page of block */
|
||||
|
||||
ret = NAND_READPAGE(raw, block, 0, 0, spare);
|
||||
ret = NAND_RAWREAD(raw, block, 0, 0, spare);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: Cannot read page #0 of block #%d\n", block);
|
||||
@ -212,7 +212,7 @@ static int nand_checkblock(FAR struct nand_dev_s *nand, off_t block)
|
||||
|
||||
/* Read spare area of second page of block */
|
||||
|
||||
ret = NAND_READPAGE(raw, block, 1, 0, spare);
|
||||
ret = NAND_RAWREAD(raw, block, 1, 0, spare);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: Cannot read page #1 of block #%d\n", block);
|
||||
@ -220,7 +220,7 @@ static int nand_checkblock(FAR struct nand_dev_s *nand, off_t block)
|
||||
}
|
||||
|
||||
nandscheme_readbadblockmarker(scheme, spare, &marker);
|
||||
if (marker != 0xFF)
|
||||
if (marker != 0xff)
|
||||
{
|
||||
return BADBLOCK;
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ int nandecc_readpage(FAR struct nand_dev_s *nand, off_t block,
|
||||
|
||||
/* Start by reading the spare data */
|
||||
|
||||
ret = NAND_READPAGE(raw, block, page, 0, spare);
|
||||
ret = NAND_RAWREAD(raw, block, page, 0, spare);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: Failed to read page:d\n", ret);
|
||||
@ -129,7 +129,7 @@ int nandecc_readpage(FAR struct nand_dev_s *nand, off_t block,
|
||||
|
||||
/* Then reading the data */
|
||||
|
||||
ret = NAND_READPAGE(nand->raw, block, page, data, 0);
|
||||
ret = NAND_RAWREAD(nand->raw, block, page, data, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: Failed to read page:d\n", ret);
|
||||
@ -228,7 +228,7 @@ int nandecc_writepage(FAR struct nand_dev_s *nand, off_t block,
|
||||
|
||||
/* Perform page write operation */
|
||||
|
||||
ret = NAND_WRITEPAGE(nand->raw, block, page, data, spare);
|
||||
ret = NAND_RAWWRITE(nand->raw, block, page, data, spare);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: Failed to write page:d\n", ret);
|
||||
|
@ -53,6 +53,7 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
@ -140,11 +140,11 @@
|
||||
#define NAND_ERASEBLOCK(r,b) ((r)->eraseblock(r,b))
|
||||
|
||||
/****************************************************************************
|
||||
* Name: NAND_READPAGE
|
||||
* Name: NAND_RAWREAD
|
||||
*
|
||||
* Description:
|
||||
* Reads the data and/or the spare areas of a page of a NAND FLASH into the
|
||||
* provided buffers.
|
||||
* provided buffers. This is a raw read of the flash contents.
|
||||
*
|
||||
* Input parameters:
|
||||
* raw - Lower-half, raw NAND FLASH interface
|
||||
@ -158,13 +158,14 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define NAND_READPAGE(r,b,p,d,s) ((r)->readpage(r,b,p,d,s))
|
||||
#define NAND_RAWREAD(r,b,p,d,s) ((r)->rawread(r,b,p,d,s))
|
||||
|
||||
/****************************************************************************
|
||||
* Name: NAND_WRITEPAGE
|
||||
* Name: NAND_RAWWRITE
|
||||
*
|
||||
* Description:
|
||||
* Writes the data and/or the spare area of a page on a NAND FLASH chip.
|
||||
* This is a raw write of the flash contents.
|
||||
*
|
||||
* Input parameters:
|
||||
* raw - Lower-half, raw NAND FLASH interface
|
||||
@ -178,7 +179,58 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define NAND_WRITEPAGE(r,b,p,d,s) ((r)->writepage(r,b,p,d,s))
|
||||
#define NAND_RAWWRITE(r,b,p,d,s) ((r)->rawwrite(r,b,p,d,s))
|
||||
|
||||
/****************************************************************************
|
||||
* Name: NAND_READPAGE
|
||||
*
|
||||
* Description:
|
||||
* Reads the data and/or the spare areas of a page of a NAND FLASH into the
|
||||
* provided buffers. Hardware ECC checking will be performed if so
|
||||
* configured.
|
||||
*
|
||||
* Input parameters:
|
||||
* raw - Lower-half, raw 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.
|
||||
* data - Buffer where the data area will be stored.
|
||||
* spare - Buffer where the spare area will be stored.
|
||||
*
|
||||
* Returned value.
|
||||
* OK is returned in succes; a negated errno value is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef 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))
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: NAND_WRITEPAGE
|
||||
*
|
||||
* Description:
|
||||
* Writes the data and/or the spare area of a page on a NAND FLASH chip.
|
||||
* Hardware ECC checking will be performed if so configured.
|
||||
*
|
||||
* Input parameters:
|
||||
* raw - Lower-half, raw NAND FLASH interface
|
||||
* block - Number of the block where the page to write resides.
|
||||
* page - Number of the page to write inside the given block.
|
||||
* data - Buffer containing the data to be writting
|
||||
* spare - Buffer containing the spare data to be written.
|
||||
*
|
||||
* Returned value.
|
||||
* OK is returned in succes; a negated errno value is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef 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))
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
@ -201,11 +253,19 @@ struct nand_raw_s
|
||||
/* NAND operations */
|
||||
|
||||
CODE int (*eraseblock)(FAR struct nand_raw_s *raw, off_t block);
|
||||
CODE int (*rawread)(FAR struct nand_raw_s *raw, off_t block,
|
||||
unsigned int page, FAR void *data, FAR void *spare);
|
||||
CODE int (*rawwrite)(FAR struct nand_raw_s *raw, off_t block,
|
||||
unsigned int page, FAR const void *data,
|
||||
FAR const void *spare);
|
||||
|
||||
#ifdef CONFIG_MTD_NAND_HWECC
|
||||
CODE int (*readpage)(FAR struct nand_raw_s *raw, off_t block,
|
||||
unsigned int page, FAR void *data, FAR void *spare);
|
||||
CODE int (*writepage)(FAR struct nand_raw_s *raw, off_t block,
|
||||
unsigned int page, FAR const void *data,
|
||||
FAR const void *spare);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
|
||||
/* ECC */
|
||||
|
Loading…
Reference in New Issue
Block a user