SAMA5 NAND: Fix some PMECC setup logic
This commit is contained in:
parent
68ccbc0855
commit
ae01f868b2
|
@ -1739,9 +1739,7 @@ static int nand_read_pmecc(struct sam_nandcs_s *priv, off_t block,
|
|||
|
||||
/* Start a Data Phase */
|
||||
|
||||
regval = nand_getreg(SAM_HSMC_PMECCTRL);
|
||||
regval |= HSMC_PMECCTRL_DATA;
|
||||
nand_putreg(SAM_HSMC_PMECCTRL, regval);
|
||||
nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_DATA);
|
||||
|
||||
regval = nand_getreg(SAM_HSMC_PMECCEADDR);
|
||||
ret = nand_read(priv, true, (uint8_t *)data, pagesize + (regval + 1));
|
||||
|
@ -2088,6 +2086,7 @@ static int nand_readpage_pmecc(struct sam_nandcs_s *priv, off_t block,
|
|||
int ret;
|
||||
int i;
|
||||
|
||||
fvdbg("block=%d page=%d data=%p\n", (int)block, page, data);
|
||||
DEBUGASSERT(priv && data);
|
||||
|
||||
/* Make sure that we have exclusive access to the PMECC and that the PMECC
|
||||
|
@ -2095,7 +2094,12 @@ static int nand_readpage_pmecc(struct sam_nandcs_s *priv, off_t block,
|
|||
*/
|
||||
|
||||
pmecc_lock();
|
||||
pmecc_configure(priv, 0, false);
|
||||
ret = pmecc_configure(priv, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: pmecc_configure failed: %d\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Start by reading the spare data */
|
||||
|
||||
|
@ -2340,13 +2344,19 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block,
|
|||
int ret = 0;
|
||||
|
||||
fvdbg("block=%d page=%d data=%p\n", (int)block, page, data);
|
||||
DEBUGASSERT(priv && data);
|
||||
|
||||
/* Make sure that we have exclusive access to the PMECC and that the PMECC
|
||||
* is properly configured for this CS.
|
||||
*/
|
||||
|
||||
pmecc_lock();
|
||||
pmecc_configure(priv, 0, false);
|
||||
ret = pmecc_configure(priv, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: pmecc_configure failed: %d\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Calculate the start page address */
|
||||
|
||||
|
@ -2409,9 +2419,7 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block,
|
|||
|
||||
/* Start a data phase */
|
||||
|
||||
regval = nand_getreg(SAM_HSMC_PMECCTRL);
|
||||
regval |= HSMC_PMECCTRL_DATA;
|
||||
nand_putreg(SAM_HSMC_PMECCTRL, regval);
|
||||
nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_DATA);
|
||||
|
||||
regval = nand_getreg(SAM_HSMC_PMECCFG);
|
||||
regval |= HSMC_PMECCFG_NANDWR_WRITE;
|
||||
|
|
|
@ -57,6 +57,9 @@
|
|||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/mtd/nand_model.h>
|
||||
#include <nuttx/mtd/nand_scheme.h>
|
||||
|
||||
#include "sam_pmecc.h"
|
||||
#include "sam_nand.h"
|
||||
|
||||
|
@ -83,12 +86,6 @@
|
|||
|
||||
#define PMECC_MAX_CORRECTABILITY 25
|
||||
|
||||
/* Start address of ECC cvalue in spare zone, this must not be 0 since bad
|
||||
* block tags are at address 0.
|
||||
*/
|
||||
|
||||
#define PMECC_ECC_DEFAULT_STARTOFFSET 2
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
@ -753,44 +750,44 @@ static uint32_t pmecc_correctionalgo(uint32_t isr, uint32_t data)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pmecc_bcherr512(uint8_t nsectors, uint16_t sparesize)
|
||||
static int pmecc_bcherr512(uint8_t nsectors, uint16_t eccsize)
|
||||
{
|
||||
/* 39-bytes per 512 byte sector are required correctability of 24 errors */
|
||||
|
||||
if (sparesize <= 39 * ((unsigned int)nsectors))
|
||||
if (eccsize >= 39 * ((unsigned int)nsectors))
|
||||
{
|
||||
return BCH_ERR24;
|
||||
}
|
||||
|
||||
/* 20-bytes per 512 byte sector are required correctability of 12 errors */
|
||||
|
||||
else if (sparesize <= (20 * (unsigned int)nsectors))
|
||||
else if (eccsize >= (20 * (unsigned int)nsectors))
|
||||
{
|
||||
return BCH_ERR12;
|
||||
}
|
||||
|
||||
/* 13-bytes per 512 byte sector are required correctability of 8 errors */
|
||||
|
||||
else if (sparesize <= (13 * (unsigned int)nsectors))
|
||||
else if (eccsize >= (13 * (unsigned int)nsectors))
|
||||
{
|
||||
return BCH_ERR8;
|
||||
}
|
||||
|
||||
/* 7-bytes per 512 byte sector are required correctability of 4 errors */
|
||||
|
||||
else if (sparesize <= (7 *(unsigned int) nsectors))
|
||||
else if (eccsize >= (7 *(unsigned int) nsectors))
|
||||
{
|
||||
return BCH_ERR4;
|
||||
}
|
||||
|
||||
/* 4-bytes per 512 byte sector are required correctability of 2 errors */
|
||||
|
||||
else if (sparesize <= (4 *(unsigned int) nsectors))
|
||||
else if (eccsize >= (4 *(unsigned int) nsectors))
|
||||
{
|
||||
return BCH_ERR2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -801,123 +798,156 @@ static int pmecc_bcherr512(uint8_t nsectors, uint16_t sparesize)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pmecc_bcherr1k(uint8_t nsectors, uint16_t sparesize)
|
||||
static int pmecc_bcherr1k(uint8_t nsectors, uint16_t eccsize)
|
||||
{
|
||||
/* 42-bytes per 1024 byte sector are required correctability of 24 errors */
|
||||
|
||||
if (sparesize <= 42 * ((unsigned int)nsectors))
|
||||
if (eccsize >= 42 * ((unsigned int)nsectors))
|
||||
{
|
||||
return BCH_ERR24;
|
||||
}
|
||||
|
||||
/* 21-bytes per 1024 byte sector are required correctability of 12 errors */
|
||||
|
||||
else if (sparesize <= (20 * (unsigned int)nsectors))
|
||||
else if (eccsize >= (21 * (unsigned int)nsectors))
|
||||
{
|
||||
return BCH_ERR12;
|
||||
}
|
||||
|
||||
/* 14-bytes per 1024 byte sector are required correctability of 8 errors */
|
||||
|
||||
else if (sparesize <= (13 * (unsigned int)nsectors))
|
||||
else if (eccsize >= (14 * (unsigned int)nsectors))
|
||||
{
|
||||
return BCH_ERR8;
|
||||
}
|
||||
|
||||
/* 7-bytes per 1024 byte sector are required correctability of 4 errors */
|
||||
|
||||
else if (sparesize <= (7 *(unsigned int) nsectors))
|
||||
else if (eccsize >= (7 *(unsigned int) nsectors))
|
||||
{
|
||||
return BCH_ERR4;
|
||||
}
|
||||
|
||||
/* 4-bytes per 1024 byte sector are required correctability of 2 errors */
|
||||
|
||||
else if (sparesize <= (4 *(unsigned int) nsectors))
|
||||
else if (eccsize >= (4 *(unsigned int) nsectors))
|
||||
{
|
||||
return BCH_ERR2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmecc_pagelayout
|
||||
*
|
||||
* Description:
|
||||
* Given the data size and the spare size, determine the optimal sector
|
||||
* size and correctability.
|
||||
* Given the size of the data region and the size of the ECC region,
|
||||
* determine the optimal sector size and correctability.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void pmecc_pagelayout(uint16_t datasize, uint16_t sparesize,
|
||||
uint16_t offset)
|
||||
static int pmecc_pagelayout(uint16_t datasize, uint16_t eccsize)
|
||||
{
|
||||
uint16_t correctability512;
|
||||
uint16_t correctability1K;
|
||||
uint8_t nsectors512;
|
||||
uint8_t nsectors1k;
|
||||
uint8_t bcherr512;
|
||||
uint8_t bcherr1k;
|
||||
uint8_t bcherr;
|
||||
int bcherr512;
|
||||
int bcherr1k;
|
||||
int selector;
|
||||
|
||||
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(datasize != 0 && offset > 0);
|
||||
|
||||
/* Decrease the spare size by the offset */
|
||||
|
||||
sparesize -= offset;
|
||||
fvdbg("datasize=%d eccsize=%d\n", datasize, eccsize);
|
||||
DEBUGASSERT(datasize > 0 && eccsize > 0);
|
||||
|
||||
/* Try for 512 byte sectors */
|
||||
|
||||
DEBUGASSERT((datasize & 0x000001ff) == 0 && datasize >= 512);
|
||||
|
||||
selector = 0;
|
||||
nsectors512 = (datasize >> 9);
|
||||
bcherr512 = pmecc_bcherr512(nsectors512, sparesize);
|
||||
bcherr512 = pmecc_bcherr512(nsectors512, eccsize);
|
||||
if (bcherr512 < 0)
|
||||
{
|
||||
fdbg("WARNING: Cannot realize 512B sectors\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
selector = 1;
|
||||
}
|
||||
|
||||
fvdbg("nsectors512=%d bcherr512=%d selector=%d\n",
|
||||
nsectors512, bcherr512, selector);
|
||||
|
||||
/* Try for 1024 byte sectors */
|
||||
|
||||
if ((datasize & 0x000003ff) == 0)
|
||||
{
|
||||
nsectors1k = (datasize >> 9);
|
||||
bcherr1k = pmecc_bcherr1k(nsectors1k, sparesize);
|
||||
nsectors1k = (datasize >> 10);
|
||||
bcherr1k = pmecc_bcherr1k(nsectors1k, eccsize);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsectors1k = 0;
|
||||
bcherr1k = 0;
|
||||
bcherr1k = -EINVAL;
|
||||
}
|
||||
|
||||
/* Now pick the best (most likely 1024) */
|
||||
|
||||
DEBUGASSERT(bcherr512 > 0 || bcherr1k > 0);
|
||||
if (bcherr1k == 0)
|
||||
if (bcherr1k < 0)
|
||||
{
|
||||
g_pmecc.sector1k = false;
|
||||
g_pmecc.nsectors = nsectors512;
|
||||
bcherr = bcherr512;
|
||||
fdbg("WARNING: Cannot realize 1KB sectors\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
correctability512 = nsectors512 * g_correctability[bcherr512];
|
||||
correctability1K = nsectors1k * g_correctability[bcherr1k];
|
||||
if (correctability512 >= correctability1K)
|
||||
selector |= 2;
|
||||
}
|
||||
|
||||
fvdbg("nsectors1k=%d bcherr1k=%d selector=%d\n",
|
||||
nsectors1k, bcherr1k, selector);
|
||||
|
||||
/* Now pick the best (most likely 1024) */
|
||||
|
||||
DEBUGASSERT(bcherr512 >= 0 || bcherr1k >= 0);
|
||||
switch (selector)
|
||||
{
|
||||
case 1: /* 512B sectors possible; 1KB sectors not possible */
|
||||
{
|
||||
g_pmecc.sector1k = false;
|
||||
g_pmecc.nsectors = nsectors512;
|
||||
bcherr = bcherr512;
|
||||
DEBUGASSERT(bcherr512 >= 0);
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
case 3: /* Both 512B and 1KB sectors possible */
|
||||
{
|
||||
correctability512 = nsectors512 * g_correctability[bcherr512];
|
||||
correctability1K = nsectors1k * g_correctability[bcherr1k];
|
||||
|
||||
/* Use 1K sectors unless we can do better with 512B sectors */
|
||||
|
||||
if (correctability512 > correctability1K)
|
||||
{
|
||||
g_pmecc.sector1k = false;
|
||||
g_pmecc.nsectors = nsectors512;
|
||||
bcherr = bcherr512;
|
||||
DEBUGASSERT(bcherr512 >= 0);
|
||||
break;
|
||||
}
|
||||
} /* Otherwise, fall through for the 1KB sectors */
|
||||
|
||||
case 2: /* 512B sectors not possible; 1KB sectors possible */
|
||||
{
|
||||
g_pmecc.sector1k = true;
|
||||
g_pmecc.nsectors = nsectors1k;
|
||||
bcherr = bcherr1k;
|
||||
DEBUGASSERT(bcherr1k >= 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0: /* Either 512B and 1KB sectors possible */
|
||||
default:
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/* Save the correctability value */
|
||||
|
@ -927,6 +957,11 @@ static void pmecc_pagelayout(uint16_t datasize, uint16_t sparesize,
|
|||
/* And the correctly shifted BCH_ERR register value */
|
||||
|
||||
g_pmecc.desc.bcherr = ((uint32_t)bcherr << HSMC_PMECCFG_BCHERR_SHIFT);
|
||||
|
||||
fvdbg("sector1k=%d nsectors=%d bcherr=%d correctability=%d\n",
|
||||
g_pmecc.sector1k, g_pmecc.nsectors, bcherr, g_pmecc.correctability);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -963,7 +998,6 @@ void pmecc_initialize(void)
|
|||
*
|
||||
* Input Parameters:
|
||||
* priv - Pointer to a struct sam_nandcs_s instance.
|
||||
* eccoffset - offset of the first ecc byte in spare zone.
|
||||
* protected - True: The spare area is protected with the last sector of
|
||||
* data.
|
||||
* False: The spare area is skipped in read or write mode.
|
||||
|
@ -973,11 +1007,16 @@ void pmecc_initialize(void)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int pmecc_configure(struct sam_nandcs_s *priv, uint16_t eccoffset,
|
||||
bool protected)
|
||||
int pmecc_configure(struct sam_nandcs_s *priv, bool protected)
|
||||
{
|
||||
struct nand_model_s *model;
|
||||
unsigned int sectorsperpage = 0;
|
||||
uint16_t eccoffset;
|
||||
uint16_t eccsize;
|
||||
uint32_t regval;
|
||||
int ret;
|
||||
|
||||
fvdbg("protected=%d configured=%d\n", protected, g_pmecc.configured);
|
||||
|
||||
/* Check if we need to re-configure */
|
||||
|
||||
|
@ -989,19 +1028,21 @@ int pmecc_configure(struct sam_nandcs_s *priv, uint16_t eccoffset,
|
|||
{
|
||||
/* No, we are already configured */
|
||||
|
||||
fvdbg("Already configured\n");
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Make sure that the requested offset greater than or equal to the
|
||||
* minimum. The first few bytes of the spare ares is reserved for
|
||||
* bad block indications. Therefore, ECC data must begin at an offset
|
||||
* to skip over the bad block indicators.
|
||||
/* Get a convenience pointer to the NAND model */
|
||||
|
||||
model = &priv->raw.model;
|
||||
|
||||
/* Get the offset and size of the ECC information in the spare area from
|
||||
* the NAND scheme.
|
||||
*/
|
||||
|
||||
if (eccoffset < PMECC_ECC_DEFAULT_STARTOFFSET)
|
||||
{
|
||||
eccoffset = PMECC_ECC_DEFAULT_STARTOFFSET;
|
||||
}
|
||||
DEBUGASSERT(model->scheme);
|
||||
eccoffset = nandscheme_eccoffset(model->scheme);
|
||||
eccsize = nandscheme_eccsize(model->scheme);
|
||||
|
||||
/* Get the number of sectors and the error correction per sector. This
|
||||
* function will set the following structure values in order to get the
|
||||
|
@ -1013,7 +1054,12 @@ int pmecc_configure(struct sam_nandcs_s *priv, uint16_t eccoffset,
|
|||
* g_pmecc.desc.bcherr : The BCH_ERR value for the PMECC CFG register
|
||||
*/
|
||||
|
||||
pmecc_pagelayout(priv->raw.model.pagesize, priv->raw.model.sparesize, eccoffset);
|
||||
ret = pmecc_pagelayout(priv->raw.model.pagesize, eccsize);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: pmecc_pagelayout failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Number of Sectors in one Page */
|
||||
|
||||
|
@ -1048,6 +1094,9 @@ int pmecc_configure(struct sam_nandcs_s *priv, uint16_t eccoffset,
|
|||
#endif
|
||||
}
|
||||
|
||||
fvdbg("sectorsz=%08x sectorsperpage=%d mm=%d\n",
|
||||
g_pmecc.desc.sectorsz, sectorsperpage, g_pmecc.desc.mm);
|
||||
|
||||
switch (sectorsperpage)
|
||||
{
|
||||
case 1:
|
||||
|
@ -1063,28 +1112,43 @@ int pmecc_configure(struct sam_nandcs_s *priv, uint16_t eccoffset,
|
|||
g_pmecc.desc.pagesize = HSMC_PMECCFG_PAGESIZE_8SEC;
|
||||
break;
|
||||
default:
|
||||
fdbg("ERROR: Unsupported sectors per page: %d\n", sectorsperpage);
|
||||
fdbg("ERROR: Unsupported sectors per page: %d\n", sectorsperpage);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
g_pmecc.desc.nn = (1 << g_pmecc.desc.mm) - 1;
|
||||
|
||||
fvdbg("pagesize=%08x nn=%d\n", g_pmecc.desc.pagesize, g_pmecc.desc.nn);
|
||||
|
||||
/* Real value of ECC bit number correction (2, 4, 8, 12, 24) */
|
||||
|
||||
g_pmecc.desc.tt = g_pmecc.correctability;
|
||||
if (((g_pmecc.desc.mm * g_pmecc.correctability) % 8) == 0)
|
||||
if (((g_pmecc.desc.mm * g_pmecc.correctability) & 7) == 0)
|
||||
{
|
||||
g_pmecc.desc.eccsize = ((g_pmecc.desc.mm * g_pmecc.correctability) / 8) * sectorsperpage;
|
||||
g_pmecc.desc.eccsize =
|
||||
((g_pmecc.desc.mm * g_pmecc.correctability) >> 3) * sectorsperpage;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pmecc.desc.eccsize = (((g_pmecc.desc.mm * g_pmecc.correctability) / 8) + 1) * sectorsperpage;
|
||||
g_pmecc.desc.eccsize =
|
||||
(((g_pmecc.desc.mm * g_pmecc.correctability) >> 3) + 1) * sectorsperpage;
|
||||
}
|
||||
|
||||
fvdbg("mm=%d correctability=%d eccsize=%d\n",
|
||||
g_pmecc.desc.mm, g_pmecc.correctability, g_pmecc.desc.eccsize);
|
||||
|
||||
g_pmecc.desc.eccstart = eccoffset;
|
||||
g_pmecc.desc.eccend = eccoffset + g_pmecc.desc.eccsize;
|
||||
|
||||
fvdbg("eccstart=%d eccend=%d sparesize=%d\n",
|
||||
g_pmecc.desc.eccstart, g_pmecc.desc.eccend,
|
||||
priv->raw.model.sparesize);
|
||||
|
||||
if (g_pmecc.desc.eccend > priv->raw.model.sparesize)
|
||||
{
|
||||
fdbg("ERROR: No room for ECC in spare bytes %d > %d\n",
|
||||
g_pmecc.desc.eccend, priv->raw.model.sparesize);
|
||||
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
@ -1144,7 +1208,7 @@ int pmecc_configure(struct sam_nandcs_s *priv, uint16_t eccoffset,
|
|||
#if NAND_NPMECC_BANKS > 1
|
||||
g_pmecc.cs = priv->cs;
|
||||
#endif
|
||||
return 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -65,6 +65,16 @@
|
|||
# undef CONFIG_SAMA5_EBICS3_PMECC
|
||||
#endif
|
||||
|
||||
/* Only CS3 can support NAND. The rest of what follows is a fantasy */
|
||||
|
||||
# undef CONFIG_SAMA5_EBICS0_NAND
|
||||
# undef CONFIG_SAMA5_EBICS1_NAND
|
||||
# undef CONFIG_SAMA5_EBICS2_NAND
|
||||
|
||||
# undef CONFIG_SAMA5_EBICS0_PMECC
|
||||
# undef CONFIG_SAMA5_EBICS1_PMECC
|
||||
# undef CONFIG_SAMA5_EBICS2_PMECC
|
||||
|
||||
/* Disable PMECC support for any banks not enabled or configured for NAND */
|
||||
|
||||
#if !defined(CONFIG_SAMA5_EBICS0) || !defined(CONFIG_SAMA5_EBICS0_NAND)
|
||||
|
@ -310,7 +320,6 @@ void pmecc_initialize(void);
|
|||
*
|
||||
* Input Parameters:
|
||||
* priv - Pointer to a struct sam_nandcs_s instance.
|
||||
* eccoffset - offset of the first ecc byte in spare zone.
|
||||
* protected - True: The spare area is protected with the last sector of
|
||||
* data.
|
||||
* False: The spare area is skipped in read or write mode.
|
||||
|
@ -321,8 +330,7 @@ void pmecc_initialize(void);
|
|||
****************************************************************************/
|
||||
|
||||
struct sam_nandcs_s;
|
||||
int pmecc_configure(struct sam_nandcs_s *priv, uint16_t eccoffset,
|
||||
bool protected);
|
||||
int pmecc_configure(struct sam_nandcs_s *priv, bool protected);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pmecc_correction
|
||||
|
@ -405,7 +413,7 @@ void pmecc_buildgf(uint32_t mm, int16_t* indexof, int16_t* alphato);
|
|||
# define pmecc_enable()
|
||||
# define pmecc_disable()
|
||||
# define pmecc_initialize()
|
||||
# define pmecc_configure(a,b,c) (0)
|
||||
# define pmecc_configure(a,b) (0)
|
||||
# define pmecc_get_eccsize() (0)
|
||||
# define pmecc_get_pagesize() (0)
|
||||
|
||||
|
|
|
@ -440,7 +440,7 @@ Creating and Using NORBOOT
|
|||
7. An option is to use the SAM-BA tool to write the NORBOOT image into
|
||||
Serial FLASH. Then, the system will boot from Serial FLASH by
|
||||
copying the NORBOOT image in SRAM which will run and then start the
|
||||
image in NOR FLASH automatically.
|
||||
image in NOR FLASH automatically. This is a very convenient usage!
|
||||
|
||||
NOTES: (1) There is jumper on the CM module that must be closed to
|
||||
enable use of the AT25 Serial Flash. (2) If using SAM-BA, make sure
|
||||
|
@ -1278,7 +1278,8 @@ NOR FLASH Support
|
|||
STATUS: I have been unable to execute these configurations from NOR FLASH
|
||||
by closing the BMS jumper (J9). As far as I can tell, this jumper does
|
||||
nothing on my board??? So I have been using the norboot configuration
|
||||
exclusively to start the program-under-test in NOR FLASH (see below).
|
||||
exclusively to start the program-under-test in NOR FLASH (see the section
|
||||
entitled "Creating and Using NORBOOT" above.)
|
||||
|
||||
SDRAM Support
|
||||
=============
|
||||
|
@ -1397,6 +1398,10 @@ NAND Support
|
|||
or Serial FLASH is a problem: In that case, the code always ends up
|
||||
in the SAM-BA bootloader.
|
||||
|
||||
My understanding is that you can enable JTAG in this case by simply
|
||||
entering any data on the DBG serial port. I have not tried this.
|
||||
Instead, I just changed to boot from Serial Flash:
|
||||
|
||||
2. Booting from Serial Flash. The work around for this case is to put
|
||||
the NORBOOT image into Serial FLASH. Then, the system will boot from
|
||||
Serial FLASH by copying the NORBOOT image in SRAM which will run and
|
||||
|
@ -2698,7 +2703,8 @@ Configurations
|
|||
- Waits for you to break in with GDB.
|
||||
|
||||
At that point, you can set the PC and begin executing from NOR FLASH
|
||||
under debug control.
|
||||
under debug control. See the section entitled "Creating and Using
|
||||
NORBOOT" above.
|
||||
|
||||
NOTES:
|
||||
|
||||
|
|
|
@ -75,16 +75,17 @@ config MTD_CONFIG_ERASEDVALUE
|
|||
|
||||
comment "MTD Device Drivers"
|
||||
|
||||
config MTD_NAND
|
||||
bool "Enable NAND support"
|
||||
default n
|
||||
---help---
|
||||
Enable support for NAND FLASH devices.
|
||||
|
||||
config ARCH_NAND_HWECC
|
||||
bool
|
||||
default n
|
||||
|
||||
menuconfig MTD_NAND
|
||||
bool "MTD NAND support"
|
||||
default n
|
||||
---help---
|
||||
Enable support for NAND FLASH devices.
|
||||
|
||||
if MTD_NAND
|
||||
|
||||
config MTD_NAND_MAXNUMBLOCKS
|
||||
|
|
|
@ -65,11 +65,11 @@ struct nand_scheme_s
|
|||
uint8_t eccsize; /* Number of bytes of ECC correction */
|
||||
uint8_t nxbytes; /* Number of extra bytes */
|
||||
|
||||
/* ECC byte positions */
|
||||
/* ECC byte position offsets */
|
||||
|
||||
uint8_t eccbytepos[CONFIG_MTD_NAND_MAXSPAREECCBYTES];
|
||||
|
||||
/* Extra byte positions */
|
||||
/* Extra byte position offsets */
|
||||
|
||||
uint8_t xbytepos[CONFIG_MTD_NAND_MAXSPAREEXTRABYTES];
|
||||
};
|
||||
|
@ -138,6 +138,41 @@ void nandscheme_readbadblockmarker(FAR const struct nand_scheme_s *scheme,
|
|||
void nandscheme_writebadblockmarker(FAR const struct nand_scheme_s *scheme,
|
||||
FAR uint8_t *spare, uint8_t marker);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nandscheme_eccoffset
|
||||
*
|
||||
* Description:
|
||||
* Return the offset to the first byte of ECC information. This define
|
||||
* makes the assumption that the first byte of the eccbytepos[] array
|
||||
* is an offset to beginning of the ECC area. This might not necessarily
|
||||
* be true!
|
||||
*
|
||||
* Input Parameters:
|
||||
* scheme Pointer to a nand_scheme_s instance.
|
||||
*
|
||||
* Returned Values:
|
||||
* Offset in the spare area to the first ECC byte
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define nandscheme_eccoffset(s) ((s)->eccbytepos[0])
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nandscheme_eccsize
|
||||
*
|
||||
* Description:
|
||||
* Return the size of the ECC information in the spare area
|
||||
*
|
||||
* Input Parameters:
|
||||
* scheme Pointer to a nand_scheme_s instance.
|
||||
*
|
||||
* Returned Values:
|
||||
* Size of the ECC information in the spare area.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define nandscheme_eccsize(s) ((s)->eccsize)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nandscheme_readecc
|
||||
*
|
||||
|
@ -176,6 +211,41 @@ void nandscheme_readecc(FAR const struct nand_scheme_s *scheme,
|
|||
void nandscheme_writeecc(FAR const struct nand_scheme_s *scheme,
|
||||
FAR uint8_t *spare, FAR const uint8_t *ecc);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nandscheme_xoffset
|
||||
*
|
||||
* Description:
|
||||
* Return the offset to the first byte of extra information. This define
|
||||
* makes the assumption that the first byte of the xbytepos[] array
|
||||
* is an offset to the beginning of the extra information area. This
|
||||
* might not necessarily be true!
|
||||
*
|
||||
* Input Parameters:
|
||||
* scheme Pointer to a nand_scheme_s instance.
|
||||
*
|
||||
* Returned Values:
|
||||
* Offset in the spare area to the first extra byte
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define nandscheme_xoffset(s) ((s)->xbytepos[0])
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nandscheme_xsize
|
||||
*
|
||||
* Description:
|
||||
* Return the size of the extra information in the spare area
|
||||
*
|
||||
* Input Parameters:
|
||||
* scheme Pointer to a nand_scheme_s instance.
|
||||
*
|
||||
* Returned Values:
|
||||
* Size of the extra information in the spare area.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define nandscheme_xsize(s) ((s)->nxbytes)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nandscheme_readextra
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue