Rethinking some NAND interfaces

This commit is contained in:
Gregory Nutt
2013-11-19 08:50:12 -06:00
parent 9986d22e19
commit 448c8572cd
9 changed files with 531 additions and 60 deletions
+3
View File
@@ -6084,3 +6084,6 @@
* drivers/mtd/hamming.c and mtd_nandecc.c and * drivers/mtd/hamming.c and mtd_nandecc.c and
include/nuttx/mtd/hamming.h: Beginning of NAND software ECC include/nuttx/mtd/hamming.h: Beginning of NAND software ECC
calculations. (2013-11-18). calculations. (2013-11-18).
* configs/olimex-lpc-h3131: Add support for the Olimex LPC-H3131
board. Does not yet boot (2013-11-18).
+27 -11
View File
@@ -357,19 +357,35 @@
/* PMECC Configuration Register */ /* PMECC Configuration Register */
#define HSMC_PMECCFG_BCH_ERR_SHIFT (0) /* Bit 0-2: Error Correcting Capability */ #define HSMC_PMECCFG_BCHERR_SHIFT (0) /* Bit 0-2: Error Correcting Capability */
#define HSMC_PMECCFG_BCH_ERR_MASK (7 << HSMC_PMECCFG_BCH_ERR_SHIFT) #define HSMC_PMECCFG_BCHERR_MASK (7 << HSMC_PMECCFG_BCHERR_SHIFT)
# define HSMC_PMECCFG_BCH_ERR_2 (0 << HSMC_PMECCFG_BCH_ERR_SHIFT) /* 2 errors */ # define HSMC_PMECCFG_BCHERR_2 (0 << HSMC_PMECCFG_BCHERR_SHIFT) /* 2 errors */
# define HSMC_PMECCFG_BCH_ERR_4 (1 << HSMC_PMECCFG_BCH_ERR_SHIFT) /* 4 errors */ # define HSMC_PMECCFG_BCHERR_4 (1 << HSMC_PMECCFG_BCHERR_SHIFT) /* 4 errors */
# define HSMC_PMECCFG_BCH_ERR_8 (2 << HSMC_PMECCFG_BCH_ERR_SHIFT) /* 8 errors */ # define HSMC_PMECCFG_BCHERR_8 (2 << HSMC_PMECCFG_BCHERR_SHIFT) /* 8 errors */
# define HSMC_PMECCFG_BCH_ERR_12 (3 << HSMC_PMECCFG_BCH_ERR_SHIFT) /* 12 errors */ # define HSMC_PMECCFG_BCHERR_12 (3 << HSMC_PMECCFG_BCHERR_SHIFT) /* 12 errors */
# define HSMC_PMECCFG_BCH_ERR_24 (4 << HSMC_PMECCFG_BCH_ERR_SHIFT) /* 24 errors */ # define HSMC_PMECCFG_BCHERR_24 (4 << HSMC_PMECCFG_BCHERR_SHIFT) /* 24 errors */
#define HSMC_PMECCFG_SECTORSZ (1 << 4) /* Bit 4: Sector Size */ #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_SHIFT (8) /* Bit 8-9: Number of Sectors in the Page */
#define HSMC_PMECCFG_PAGESIZE_MASK (3 << HSMC_PMECCFG_PAGESIZE_SHIFT) #define HSMC_PMECCFG_PAGESIZE_MASK (3 << HSMC_PMECCFG_PAGESIZE_SHIFT)
#define HSMC_PMECCFG_NANDWR (1 << 12) /* Bit 12: NAND Write Access */ # define HSMC_PMECCFG_PAGESIZE_1SEC (0 << HSMC_PMECCFG_PAGESIZE_SHIFT) /* 1 sector (5121K) */
#define HSMC_PMECCFG_SPAREEN (1 << 16) /* Bit 16: Spare Enable */ # define HSMC_PMECCFG_PAGESIZE_2SEC (1 << HSMC_PMECCFG_PAGESIZE_SHIFT) /* 2 sectors (1/2K) */
#define HSMC_PMECCFG_AUTO (1 << 20) /* Bit 20: Automatic Mode Enable */ # 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 */ /* PMECC Spare Area Size Register */
+153 -38
View File
@@ -64,6 +64,7 @@
#include <arch/board/board.h> #include <arch/board/board.h>
#include "sam_pmecc.h"
#include "sam_nand.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, static int nand_readpage_noecc(struct sam_rawnand_s *priv, off_t block,
unsigned int page, void *data, void *spare); 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, #ifdef NAND_HAVE_HSIAO
unsigned int page, void *data, void *spare); static int nand_readpage_hsiao(struct sam_rawnand_s *priv, off_t block,
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, void *spare);
#endif #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, static int nand_writepage_noecc(struct sam_rawnand_s *priv, off_t block,
unsigned int page, const void *data, const void *spare); 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); 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, 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 #endif
/* MTD driver methods */ /* MTD driver methods */
static int nand_eraseblock(struct nand_raw_s *raw, off_t block); 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, static int nand_readpage(struct nand_raw_s *raw, off_t block,
unsigned int page, void *data, void *spare); unsigned int page, void *data, void *spare);
static int nand_writepage(struct nand_raw_s *raw, off_t block, static int nand_writepage(struct nand_raw_s *raw, off_t block,
unsigned int page, const void *data, const void *spare); unsigned int page, const void *data, const void *spare);
#endif
/**************************************************************************** /****************************************************************************
* Private Data * 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: * Description:
* Reads the data and/or the spare areas of a page of a NAND FLASH into the * 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 #ifdef NAND_HAVE_HSIAO
static int nand_readpage_hwecc(struct sam_rawnand_s *priv, off_t block, static int nand_readpage_hsiao(struct sam_rawnand_s *priv, off_t block,
unsigned int page, void *data, void *spare) unsigned int page, void *data, void *spare)
{ {
#warning Missing logic #warning Missing logic
return -ENOSYS; return -ENOSYS;
} }
#endif /* CONFIG_MTD_NAND_BLOCKCHECK */ #endif /* NAND_HAVE_HSIAO */
/**************************************************************************** /****************************************************************************
* Name: nand_readpage_pmecc * 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. * block - Number of the block where the page to read resides.
* page - Number of the page to read inside the given block. * page - Number of the page to read inside the given block.
* data - Buffer where the data area will be stored. * data - Buffer where the data area will be stored.
* spare - Buffer where the spare area will be stored.
* *
* Returned value. * Returned value.
* OK is returned in succes; a negated errno value is returned on failure. * 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, 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 #warning Missing logic
return -ENOSYS; return -ENOSYS;
} }
#endif /* CONFIG_MTD_NAND_BLOCKCHECK */ #endif /* NAND_HAVE_PMECC */
/**************************************************************************** /****************************************************************************
* Name: nand_writepage_noecc * 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: * Description:
* Writes the data and/or the spare area of a page on a NAND FLASH chip. * 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 #ifdef NAND_HAVE_HSIAO
static int nand_writepage_hwecc(struct sam_rawnand_s *priv, off_t block, static int nand_writepage_hsiao(struct sam_rawnand_s *priv, off_t block,
unsigned int page, const void *data, const void *spare) unsigned int page, const void *data, const void *spare)
{ {
#warning Missing logic int ret;
return -ENOSYS;
/* 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: * Description:
* Writes the data and/or the spare area of a page on a NAND FLASH chip. * Writes the data area of a NAND FLASH page, The PMECC module generates
* PMECC calculations are performed. * 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: * Input parameters:
* priv - Lower-half, private NAND FLASH device state * priv - Lower-half, private NAND FLASH device state
* block - Number of the block where the page to write resides. * block - Number of the block where the page to write resides.
* page - Number of the page to write inside the given block. * page - Number of the page to write inside the given block.
* data - Buffer containing the data to be writting * data - Buffer containing the data to be writting
* spare - Buffer conatining the spare data to be written.
* *
* Returned value. * Returned value.
* OK is returned in succes; a negated errno value is returned on failure. * 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, 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 int ret;
return -ENOSYS;
/* 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 * 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: * Description:
* Reads the data and/or the spare areas of a page of a NAND FLASH into the * 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: * Input parameters:
* raw - Lower-half, raw NAND FLASH interface * 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, static int nand_readpage(struct nand_raw_s *raw, off_t block,
unsigned int page, void *data, void *spare) 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) switch (raw->ecctype)
{ {
case NANDECC_NONE: case NANDECC_NONE:
case NANDECC_CHIPECC:
return nand_readpage_noecc(priv, block, page, data, spare); 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: 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: case NANDECC_SWECC:
default: default:
@@ -371,12 +470,14 @@ static int nand_readpage(struct nand_raw_s *raw, off_t block,
} }
#endif #endif
} }
#endif
/**************************************************************************** /****************************************************************************
* Name: nand_writepage * Name: nand_writepage
* *
* Description: * Description:
* Writes the data and/or the spare area of a page on a NAND FLASH chip. * 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: * Input parameters:
* raw - Lower-half, raw NAND FLASH interface * 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, static int nand_writepage(struct nand_raw_s *raw, off_t block,
unsigned int page, const void *data, unsigned int page, const void *data,
const void *spare) const void *spare)
@@ -404,11 +506,19 @@ static int nand_writepage(struct nand_raw_s *raw, off_t block,
switch (raw->ecctype) switch (raw->ecctype)
{ {
case NANDECC_NONE: case NANDECC_NONE:
case NANDECC_CHIPECC:
return nand_writepage_noecc(priv, block, page, data, spare); 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: 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: case NANDECC_SWECC:
default: default:
@@ -416,6 +526,7 @@ static int nand_writepage(struct nand_raw_s *raw, off_t block,
} }
#endif #endif
} }
#endif
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
@@ -532,8 +643,12 @@ struct mtd_dev_s *sam_nand_initialize(int cs)
priv->raw.addraddr = addraddr; priv->raw.addraddr = addraddr;
priv->raw.dataaddr = dataaddr; priv->raw.dataaddr = dataaddr;
priv->raw.eraseblock = nand_eraseblock; 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.readpage = nand_readpage;
priv->raw.writepage = nand_writepage; priv->raw.writepage = nand_writepage;
#endif
priv->cs = cs; priv->cs = cs;
/* Initialize the NAND hardware */ /* Initialize the NAND hardware */
+34
View File
@@ -50,6 +50,40 @@
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * 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 /* Hardware ECC types. These are extensions to the NANDECC_HWECC value
* defined in include/nuttx/mtd/nand_raw.h. * defined in include/nuttx/mtd/nand_raw.h.
* *
+242
View 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 */
+3 -3
View File
@@ -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 */ /* 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) if (ret < 0)
{ {
fdbg("ERROR: Cannot read page #0 of block #%d\n", block); 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 */ /* 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) if (ret < 0)
{ {
fdbg("ERROR: Cannot read page #1 of block #%d\n", block); 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); nandscheme_readbadblockmarker(scheme, spare, &marker);
if (marker != 0xFF) if (marker != 0xff)
{ {
return BADBLOCK; return BADBLOCK;
} }
+3 -3
View File
@@ -120,7 +120,7 @@ int nandecc_readpage(FAR struct nand_dev_s *nand, off_t block,
/* Start by reading the spare data */ /* 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) if (ret < 0)
{ {
fdbg("ERROR: Failed to read page:d\n", ret); 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 */ /* 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) if (ret < 0)
{ {
fdbg("ERROR: Failed to read page:d\n", ret); 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 */ /* 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) if (ret < 0)
{ {
fdbg("ERROR: Failed to write page:d\n", ret); fdbg("ERROR: Failed to write page:d\n", ret);
+1
View File
@@ -53,6 +53,7 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
+65 -5
View File
@@ -140,11 +140,11 @@
#define NAND_ERASEBLOCK(r,b) ((r)->eraseblock(r,b)) #define NAND_ERASEBLOCK(r,b) ((r)->eraseblock(r,b))
/**************************************************************************** /****************************************************************************
* Name: NAND_READPAGE * Name: NAND_RAWREAD
* *
* Description: * Description:
* Reads the data and/or the spare areas of a page of a NAND FLASH into the * 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: * Input parameters:
* raw - Lower-half, raw NAND FLASH interface * 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: * Description:
* Writes the data and/or the spare area of a page on a NAND FLASH chip. * 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: * Input parameters:
* raw - Lower-half, raw NAND FLASH interface * 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 * Public Types
@@ -201,11 +253,19 @@ struct nand_raw_s
/* NAND operations */ /* NAND operations */
CODE int (*eraseblock)(FAR struct nand_raw_s *raw, off_t block); 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, CODE int (*readpage)(FAR struct nand_raw_s *raw, off_t block,
unsigned int page, FAR void *data, FAR void *spare); unsigned int page, FAR void *data, FAR void *spare);
CODE int (*writepage)(FAR struct nand_raw_s *raw, off_t block, CODE int (*writepage)(FAR struct nand_raw_s *raw, off_t block,
unsigned int page, FAR const void *data, unsigned int page, FAR const void *data,
FAR const void *spare); FAR const void *spare);
#endif
#ifdef CONFIG_MTD_NAND_BLOCKCHECK #ifdef CONFIG_MTD_NAND_BLOCKCHECK
/* ECC */ /* ECC */