mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-11 15:37:23 +00:00
Merge branch 'master' of /home/wd/git/u-boot/custodians
* 'master' of /home/wd/git/u-boot/custodians: nand/fsl_elbc: Convert to self-init nand: Introduce CONFIG_SYS_NAND_SELF_INIT nand_spl: store ecc data on the stack mtd/nand: Add ONFI support for FSL NAND controller nand: make 1-bit software ECC configurable nand: Sanitize ONFI strings. nand: Merge changes to BBT from Linux nand driver nand: Merge changes from Linux nand driver nand: cleanup whitespace nand: Add more NAND types from Linux nand driver nand: Merge BCH code from Linux nand driver NAND: Remove additional (CONFIG_SYS)_NAND_MAX_CHIPS NAND: remove NAND_MAX_CHIPS definitions nand_spl_simple: store ecc data on the stack
This commit is contained in:
commit
f57a94c2b5
66 changed files with 3082 additions and 690 deletions
|
@ -120,6 +120,68 @@ Configuration Options:
|
|||
CONFIG_SYS_NAND_MAX_CHIPS
|
||||
The maximum number of NAND chips per device to be supported.
|
||||
|
||||
CONFIG_SYS_NAND_SELF_INIT
|
||||
Traditionally, glue code in drivers/mtd/nand/nand.c has driven
|
||||
the initialization process -- it provides the mtd and nand
|
||||
structs, calls a board init function for a specific device,
|
||||
calls nand_scan(), and registers with mtd.
|
||||
|
||||
This arrangement does not provide drivers with the flexibility to
|
||||
run code between nand_scan_ident() and nand_scan_tail(), or other
|
||||
deviations from the "normal" flow.
|
||||
|
||||
If a board defines CONFIG_SYS_NAND_SELF_INIT, drivers/mtd/nand/nand.c
|
||||
will make one call to board_nand_init(), with no arguments. That
|
||||
function is responsible for calling a driver init function for
|
||||
each NAND device on the board, that performs all initialization
|
||||
tasks except setting mtd->name, and registering with the rest of
|
||||
U-Boot. Those last tasks are accomplished by calling nand_register()
|
||||
on the new mtd device.
|
||||
|
||||
Example of new init to be added to the end of an existing driver
|
||||
init:
|
||||
|
||||
/*
|
||||
* devnum is the device number to be used in nand commands
|
||||
* and in mtd->name. Must be less than
|
||||
* CONFIG_SYS_NAND_MAX_DEVICE.
|
||||
*/
|
||||
mtd = &nand_info[devnum];
|
||||
|
||||
/* chip is struct nand_chip, and is now provided by the driver. */
|
||||
mtd->priv = &chip;
|
||||
|
||||
/*
|
||||
* Fill in appropriate values if this driver uses these fields,
|
||||
* or uses the standard read_byte/write_buf/etc. functions from
|
||||
* nand_base.c that use these fields.
|
||||
*/
|
||||
chip.IO_ADDR_R = ...;
|
||||
chip.IO_ADDR_W = ...;
|
||||
|
||||
if (nand_scan_ident(mtd, CONFIG_SYS_MAX_NAND_CHIPS, NULL))
|
||||
error out
|
||||
|
||||
/*
|
||||
* Insert here any code you wish to run after the chip has been
|
||||
* identified, but before any other I/O is done.
|
||||
*/
|
||||
|
||||
if (nand_scan_tail(mtd))
|
||||
error out
|
||||
|
||||
if (nand_register(devnum))
|
||||
error out
|
||||
|
||||
In addition to providing more flexibility to the driver, it reduces
|
||||
the difference between a U-Boot driver and its Linux counterpart.
|
||||
nand_init() is now reduced to calling board_nand_init() once, and
|
||||
printing a size summary. This should also make it easier to
|
||||
transition to delayed NAND initialization.
|
||||
|
||||
Please convert your driver even if you don't need the extra
|
||||
flexibility, so that one day we can eliminate the old mechanism.
|
||||
|
||||
NOTE:
|
||||
=====
|
||||
|
||||
|
|
|
@ -39,8 +39,9 @@ COBJS-y += nand_bbt.o
|
|||
COBJS-y += nand_ids.o
|
||||
COBJS-y += nand_util.o
|
||||
endif
|
||||
COBJS-y += nand_ecc.o
|
||||
COBJS-$(CONFIG_MTD_ECC_SOFT) += nand_ecc.o
|
||||
COBJS-y += nand_base.o
|
||||
COBJS-$(CONFIG_NAND_ECC_BCH) += nand_bch.o
|
||||
|
||||
COBJS-$(CONFIG_NAND_ATMEL) += atmel_nand.o
|
||||
COBJS-$(CONFIG_DRIVER_NAND_BFIN) += bfin_nand.o
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <nand.h>
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
|
@ -57,7 +58,6 @@ struct fsl_elbc_ctrl;
|
|||
/* mtd information per set */
|
||||
|
||||
struct fsl_elbc_mtd {
|
||||
struct mtd_info mtd;
|
||||
struct nand_chip chip;
|
||||
struct fsl_elbc_ctrl *ctrl;
|
||||
|
||||
|
@ -340,18 +340,21 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
|
|||
|
||||
/* READID must read all 5 possible bytes while CEB is active */
|
||||
case NAND_CMD_READID:
|
||||
vdbg("fsl_elbc_cmdfunc: NAND_CMD_READID.\n");
|
||||
case NAND_CMD_PARAM:
|
||||
vdbg("fsl_elbc_cmdfunc: NAND_CMD 0x%x.\n", command);
|
||||
|
||||
out_be32(&lbc->fir, (FIR_OP_CW0 << FIR_OP0_SHIFT) |
|
||||
(FIR_OP_UA << FIR_OP1_SHIFT) |
|
||||
(FIR_OP_RBW << FIR_OP2_SHIFT));
|
||||
out_be32(&lbc->fcr, NAND_CMD_READID << FCR_CMD0_SHIFT);
|
||||
/* 5 bytes for manuf, device and exts */
|
||||
out_be32(&lbc->fbcr, 5);
|
||||
ctrl->read_bytes = 5;
|
||||
out_be32(&lbc->fcr, command << FCR_CMD0_SHIFT);
|
||||
/*
|
||||
* although currently it's 8 bytes for READID, we always read
|
||||
* the maximum 256 bytes(for PARAM)
|
||||
*/
|
||||
out_be32(&lbc->fbcr, 256);
|
||||
ctrl->read_bytes = 256;
|
||||
ctrl->use_mdr = 1;
|
||||
ctrl->mdr = 0;
|
||||
|
||||
ctrl->mdr = column;
|
||||
set_addr(mtd, 0, 0, 0);
|
||||
fsl_elbc_run_command(mtd);
|
||||
return;
|
||||
|
@ -683,10 +686,13 @@ static void fsl_elbc_ctrl_init(void)
|
|||
elbc_ctrl->addr = NULL;
|
||||
}
|
||||
|
||||
int board_nand_init(struct nand_chip *nand)
|
||||
static int fsl_elbc_chip_init(int devnum, u8 *addr)
|
||||
{
|
||||
struct mtd_info *mtd = &nand_info[devnum];
|
||||
struct nand_chip *nand;
|
||||
struct fsl_elbc_mtd *priv;
|
||||
uint32_t br = 0, or = 0;
|
||||
int ret;
|
||||
|
||||
if (!elbc_ctrl) {
|
||||
fsl_elbc_ctrl_init();
|
||||
|
@ -699,19 +705,19 @@ int board_nand_init(struct nand_chip *nand)
|
|||
return -ENOMEM;
|
||||
|
||||
priv->ctrl = elbc_ctrl;
|
||||
priv->vbase = nand->IO_ADDR_R;
|
||||
priv->vbase = addr;
|
||||
|
||||
/* Find which chip select it is connected to. It'd be nice
|
||||
* if we could pass more than one datum to the NAND driver...
|
||||
*/
|
||||
for (priv->bank = 0; priv->bank < MAX_BANKS; priv->bank++) {
|
||||
phys_addr_t base_addr = virt_to_phys(nand->IO_ADDR_R);
|
||||
phys_addr_t phys_addr = virt_to_phys(addr);
|
||||
|
||||
br = in_be32(&elbc_ctrl->regs->bank[priv->bank].br);
|
||||
or = in_be32(&elbc_ctrl->regs->bank[priv->bank].or);
|
||||
|
||||
if ((br & BR_V) && (br & BR_MSEL) == BR_MS_FCM &&
|
||||
(br & or & BR_BA) == BR_PHYS_ADDR(base_addr))
|
||||
(br & or & BR_BA) == BR_PHYS_ADDR(phys_addr))
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -721,6 +727,9 @@ int board_nand_init(struct nand_chip *nand)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
nand = &priv->chip;
|
||||
mtd->priv = nand;
|
||||
|
||||
elbc_ctrl->chips[priv->bank] = priv;
|
||||
|
||||
/* fill in nand_chip structure */
|
||||
|
@ -791,5 +800,32 @@ int board_nand_init(struct nand_chip *nand)
|
|||
}
|
||||
}
|
||||
|
||||
ret = nand_scan_ident(mtd, 1, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nand_scan_tail(mtd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nand_register(devnum);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SYS_NAND_BASE_LIST
|
||||
#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
|
||||
#endif
|
||||
|
||||
static unsigned long base_address[CONFIG_SYS_MAX_NAND_DEVICE] =
|
||||
CONFIG_SYS_NAND_BASE_LIST;
|
||||
|
||||
void board_nand_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)
|
||||
fsl_elbc_chip_init(i, (u8 *)base_address[i]);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <nand.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef CONFIG_SYS_NAND_BASE_LIST
|
||||
#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
|
||||
|
@ -31,63 +32,84 @@
|
|||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int nand_curr_device = -1;
|
||||
|
||||
|
||||
nand_info_t nand_info[CONFIG_SYS_MAX_NAND_DEVICE];
|
||||
|
||||
#ifndef CONFIG_SYS_NAND_SELF_INIT
|
||||
static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
|
||||
static ulong base_address[CONFIG_SYS_MAX_NAND_DEVICE] = CONFIG_SYS_NAND_BASE_LIST;
|
||||
#endif
|
||||
|
||||
static const char default_nand_name[] = "nand";
|
||||
static __attribute__((unused)) char dev_name[CONFIG_SYS_MAX_NAND_DEVICE][8];
|
||||
static char dev_name[CONFIG_SYS_MAX_NAND_DEVICE][8];
|
||||
|
||||
static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand,
|
||||
ulong base_addr)
|
||||
static unsigned long total_nand_size; /* in kiB */
|
||||
|
||||
/* Register an initialized NAND mtd device with the U-Boot NAND command. */
|
||||
int nand_register(int devnum)
|
||||
{
|
||||
struct mtd_info *mtd;
|
||||
|
||||
if (devnum >= CONFIG_SYS_MAX_NAND_DEVICE)
|
||||
return -EINVAL;
|
||||
|
||||
mtd = &nand_info[devnum];
|
||||
|
||||
sprintf(dev_name[devnum], "nand%d", devnum);
|
||||
mtd->name = dev_name[devnum];
|
||||
|
||||
#ifdef CONFIG_MTD_DEVICE
|
||||
/*
|
||||
* Add MTD device so that we can reference it later
|
||||
* via the mtdcore infrastructure (e.g. ubi).
|
||||
*/
|
||||
add_mtd_device(mtd);
|
||||
#endif
|
||||
|
||||
total_nand_size += mtd->size / 1024;
|
||||
|
||||
if (nand_curr_device == -1)
|
||||
nand_curr_device = devnum;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SYS_NAND_SELF_INIT
|
||||
static void nand_init_chip(int i)
|
||||
{
|
||||
struct mtd_info *mtd = &nand_info[i];
|
||||
struct nand_chip *nand = &nand_chip[i];
|
||||
ulong base_addr = base_address[i];
|
||||
int maxchips = CONFIG_SYS_NAND_MAX_CHIPS;
|
||||
static int __attribute__((unused)) i = 0;
|
||||
|
||||
if (maxchips < 1)
|
||||
maxchips = 1;
|
||||
|
||||
mtd->priv = nand;
|
||||
|
||||
nand->IO_ADDR_R = nand->IO_ADDR_W = (void __iomem *)base_addr;
|
||||
if (board_nand_init(nand) == 0) {
|
||||
if (nand_scan(mtd, maxchips) == 0) {
|
||||
if (!mtd->name)
|
||||
mtd->name = (char *)default_nand_name;
|
||||
#ifdef CONFIG_NEEDS_MANUAL_RELOC
|
||||
else
|
||||
mtd->name += gd->reloc_off;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MTD_DEVICE
|
||||
/*
|
||||
* Add MTD device so that we can reference it later
|
||||
* via the mtdcore infrastructure (e.g. ubi).
|
||||
*/
|
||||
sprintf(dev_name[i], "nand%d", i);
|
||||
mtd->name = dev_name[i++];
|
||||
add_mtd_device(mtd);
|
||||
#endif
|
||||
} else
|
||||
mtd->name = NULL;
|
||||
} else {
|
||||
mtd->name = NULL;
|
||||
mtd->size = 0;
|
||||
}
|
||||
if (board_nand_init(nand))
|
||||
return;
|
||||
|
||||
if (nand_scan(mtd, maxchips))
|
||||
return;
|
||||
|
||||
nand_register(i);
|
||||
}
|
||||
#endif
|
||||
|
||||
void nand_init(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_NAND_SELF_INIT
|
||||
board_nand_init();
|
||||
#else
|
||||
int i;
|
||||
unsigned int size = 0;
|
||||
for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) {
|
||||
nand_init_chip(&nand_info[i], &nand_chip[i], base_address[i]);
|
||||
size += nand_info[i].size / 1024;
|
||||
if (nand_curr_device == -1)
|
||||
nand_curr_device = i;
|
||||
}
|
||||
printf("%u MiB\n", size / 1024);
|
||||
|
||||
for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)
|
||||
nand_init_chip(i);
|
||||
#endif
|
||||
|
||||
printf("%lu MiB\n", total_nand_size / 1024);
|
||||
|
||||
#ifdef CONFIG_SYS_NAND_SELECT_DEVICE
|
||||
/*
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -13,27 +13,36 @@
|
|||
* Description:
|
||||
*
|
||||
* When nand_scan_bbt is called, then it tries to find the bad block table
|
||||
* depending on the options in the bbt descriptor(s). If a bbt is found
|
||||
* then the contents are read and the memory based bbt is created. If a
|
||||
* mirrored bbt is selected then the mirror is searched too and the
|
||||
* versions are compared. If the mirror has a greater version number
|
||||
* than the mirror bbt is used to build the memory based bbt.
|
||||
* depending on the options in the BBT descriptor(s). If no flash based BBT
|
||||
* (NAND_USE_FLASH_BBT) is specified then the device is scanned for factory
|
||||
* marked good / bad blocks. This information is used to create a memory BBT.
|
||||
* Once a new bad block is discovered then the "factory" information is updated
|
||||
* on the device.
|
||||
* If a flash based BBT is specified then the function first tries to find the
|
||||
* BBT on flash. If a BBT is found then the contents are read and the memory
|
||||
* based BBT is created. If a mirrored BBT is selected then the mirror is
|
||||
* searched too and the versions are compared. If the mirror has a greater
|
||||
* version number than the mirror BBT is used to build the memory based BBT.
|
||||
* If the tables are not versioned, then we "or" the bad block information.
|
||||
* If one of the bbt's is out of date or does not exist it is (re)created.
|
||||
* If no bbt exists at all then the device is scanned for factory marked
|
||||
* If one of the BBTs is out of date or does not exist it is (re)created.
|
||||
* If no BBT exists at all then the device is scanned for factory marked
|
||||
* good / bad blocks and the bad block tables are created.
|
||||
*
|
||||
* For manufacturer created bbts like the one found on M-SYS DOC devices
|
||||
* the bbt is searched and read but never created
|
||||
* For manufacturer created BBTs like the one found on M-SYS DOC devices
|
||||
* the BBT is searched and read but never created
|
||||
*
|
||||
* The autogenerated bad block table is located in the last good blocks
|
||||
* The auto generated bad block table is located in the last good blocks
|
||||
* of the device. The table is mirrored, so it can be updated eventually.
|
||||
* The table is marked in the oob area with an ident pattern and a version
|
||||
* number which indicates which of both tables is more up to date.
|
||||
* The table is marked in the OOB area with an ident pattern and a version
|
||||
* number which indicates which of both tables is more up to date. If the NAND
|
||||
* controller needs the complete OOB area for the ECC information then the
|
||||
* option NAND_USE_FLASH_BBT_NO_OOB should be used: it moves the ident pattern
|
||||
* and the version byte into the data area and the OOB area will remain
|
||||
* untouched.
|
||||
*
|
||||
* The table uses 2 bits per block
|
||||
* 11b: block is good
|
||||
* 00b: block is factory marked bad
|
||||
* 11b: block is good
|
||||
* 00b: block is factory marked bad
|
||||
* 01b, 10b: block is marked bad due to wear
|
||||
*
|
||||
* The memory bad block table uses the following scheme:
|
||||
|
@ -55,9 +64,21 @@
|
|||
#include <linux/mtd/compat.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/nand_ecc.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include <asm/errno.h>
|
||||
|
||||
static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = memcmp(buf, td->pattern, td->len);
|
||||
if (!ret)
|
||||
return ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* check_pattern - [GENERIC] check if a pattern is in the buffer
|
||||
* @buf: the buffer to search
|
||||
|
@ -76,6 +97,9 @@ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_desc
|
|||
int i, end = 0;
|
||||
uint8_t *p = buf;
|
||||
|
||||
if (td->options & NAND_BBT_NO_OOB)
|
||||
return check_pattern_no_oob(buf, td);
|
||||
|
||||
end = paglen + td->offs;
|
||||
if (td->options & NAND_BBT_SCANEMPTY) {
|
||||
for (i = 0; i < end; i++) {
|
||||
|
@ -91,6 +115,28 @@ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_desc
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Check both positions 1 and 6 for pattern? */
|
||||
if (td->options & NAND_BBT_SCANBYTE1AND6) {
|
||||
if (td->options & NAND_BBT_SCANEMPTY) {
|
||||
p += td->len;
|
||||
end += NAND_SMALL_BADBLOCK_POS - td->offs;
|
||||
/* Check region between positions 1 and 6 */
|
||||
for (i = 0; i < NAND_SMALL_BADBLOCK_POS - td->offs - td->len;
|
||||
i++) {
|
||||
if (*p++ != 0xff)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
p += NAND_SMALL_BADBLOCK_POS - td->offs;
|
||||
}
|
||||
/* Compare the pattern */
|
||||
for (i = 0; i < td->len; i++) {
|
||||
if (p[i] != td->pattern[i])
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (td->options & NAND_BBT_SCANEMPTY) {
|
||||
p += td->len;
|
||||
end += td->len;
|
||||
|
@ -122,36 +168,74 @@ static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
|
|||
if (p[td->offs + i] != td->pattern[i])
|
||||
return -1;
|
||||
}
|
||||
/* Need to check location 1 AND 6? */
|
||||
if (td->options & NAND_BBT_SCANBYTE1AND6) {
|
||||
for (i = 0; i < td->len; i++) {
|
||||
if (p[NAND_SMALL_BADBLOCK_POS + i] != td->pattern[i])
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_marker_len - compute the length of the marker in data area
|
||||
* @td: BBT descriptor used for computation
|
||||
*
|
||||
* The length will be 0 if the markeris located in OOB area.
|
||||
*/
|
||||
static u32 add_marker_len(struct nand_bbt_descr *td)
|
||||
{
|
||||
u32 len;
|
||||
|
||||
if (!(td->options & NAND_BBT_NO_OOB))
|
||||
return 0;
|
||||
|
||||
len = td->len;
|
||||
if (td->options & NAND_BBT_VERSION)
|
||||
len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* read_bbt - [GENERIC] Read the bad block table starting from page
|
||||
* @mtd: MTD device structure
|
||||
* @buf: temporary buffer
|
||||
* @page: the starting page
|
||||
* @num: the number of bbt descriptors to read
|
||||
* @bits: number of bits per block
|
||||
* @td: the bbt describtion table
|
||||
* @offs: offset in the memory table
|
||||
* @reserved_block_code: Pattern to identify reserved blocks
|
||||
*
|
||||
* Read the bad block table starting from page.
|
||||
*
|
||||
*/
|
||||
static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
|
||||
int bits, int offs, int reserved_block_code)
|
||||
struct nand_bbt_descr *td, int offs)
|
||||
{
|
||||
int res, i, j, act = 0;
|
||||
struct nand_chip *this = mtd->priv;
|
||||
size_t retlen, len, totlen;
|
||||
loff_t from;
|
||||
int bits = td->options & NAND_BBT_NRBITS_MSK;
|
||||
uint8_t msk = (uint8_t) ((1 << bits) - 1);
|
||||
u32 marker_len;
|
||||
int reserved_block_code = td->reserved_block_code;
|
||||
|
||||
totlen = (num * bits) >> 3;
|
||||
marker_len = add_marker_len(td);
|
||||
from = ((loff_t) page) << this->page_shift;
|
||||
|
||||
while (totlen) {
|
||||
len = min(totlen, (size_t) (1 << this->bbt_erase_shift));
|
||||
if (marker_len) {
|
||||
/*
|
||||
* In case the BBT marker is not in the OOB area it
|
||||
* will be just in the first page.
|
||||
*/
|
||||
len -= marker_len;
|
||||
from += marker_len;
|
||||
marker_len = 0;
|
||||
}
|
||||
res = mtd->read(mtd, from, len, &retlen, buf);
|
||||
if (res < 0) {
|
||||
if (retlen != len) {
|
||||
|
@ -170,9 +254,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
|
|||
continue;
|
||||
if (reserved_block_code && (tmp == reserved_block_code)) {
|
||||
printk(KERN_DEBUG "nand_read_bbt: Reserved block at 0x%012llx\n",
|
||||
(loff_t)((offs << 2) +
|
||||
(act >> 1)) <<
|
||||
this->bbt_erase_shift);
|
||||
(loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
|
||||
this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
|
||||
mtd->ecc_stats.bbtblocks++;
|
||||
continue;
|
||||
|
@ -180,8 +262,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
|
|||
/* Leave it for now, if its matured we can move this
|
||||
* message to MTD_DEBUG_LEVEL0 */
|
||||
printk(KERN_DEBUG "nand_read_bbt: Bad block at 0x%012llx\n",
|
||||
(loff_t)((offs << 2) + (act >> 1)) <<
|
||||
this->bbt_erase_shift);
|
||||
(loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
|
||||
/* Factory marked bad or worn out ? */
|
||||
if (tmp == 0)
|
||||
this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
|
||||
|
@ -211,42 +292,86 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
|
|||
{
|
||||
struct nand_chip *this = mtd->priv;
|
||||
int res = 0, i;
|
||||
int bits;
|
||||
|
||||
bits = td->options & NAND_BBT_NRBITS_MSK;
|
||||
if (td->options & NAND_BBT_PERCHIP) {
|
||||
int offs = 0;
|
||||
for (i = 0; i < this->numchips; i++) {
|
||||
if (chip == -1 || chip == i)
|
||||
res = read_bbt (mtd, buf, td->pages[i], this->chipsize >> this->bbt_erase_shift, bits, offs, td->reserved_block_code);
|
||||
res = read_bbt(mtd, buf, td->pages[i],
|
||||
this->chipsize >> this->bbt_erase_shift,
|
||||
td, offs);
|
||||
if (res)
|
||||
return res;
|
||||
offs += this->chipsize >> (this->bbt_erase_shift + 2);
|
||||
}
|
||||
} else {
|
||||
res = read_bbt (mtd, buf, td->pages[0], mtd->size >> this->bbt_erase_shift, bits, 0, td->reserved_block_code);
|
||||
res = read_bbt(mtd, buf, td->pages[0],
|
||||
mtd->size >> this->bbt_erase_shift, td, 0);
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* BBT marker is in the first page, no OOB.
|
||||
*/
|
||||
static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
|
||||
struct nand_bbt_descr *td)
|
||||
{
|
||||
size_t retlen;
|
||||
size_t len;
|
||||
|
||||
len = td->len;
|
||||
if (td->options & NAND_BBT_VERSION)
|
||||
len++;
|
||||
|
||||
return mtd->read(mtd, offs, len, &retlen, buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan read raw data from flash
|
||||
*/
|
||||
static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
|
||||
static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
|
||||
size_t len)
|
||||
{
|
||||
struct mtd_oob_ops ops;
|
||||
int res;
|
||||
|
||||
ops.mode = MTD_OOB_RAW;
|
||||
ops.ooboffs = 0;
|
||||
ops.ooblen = mtd->oobsize;
|
||||
ops.oobbuf = buf;
|
||||
ops.datbuf = buf;
|
||||
ops.len = len;
|
||||
|
||||
return mtd->read_oob(mtd, offs, &ops);
|
||||
|
||||
while (len > 0) {
|
||||
if (len <= mtd->writesize) {
|
||||
ops.oobbuf = buf + len;
|
||||
ops.datbuf = buf;
|
||||
ops.len = len;
|
||||
return mtd->read_oob(mtd, offs, &ops);
|
||||
} else {
|
||||
ops.oobbuf = buf + mtd->writesize;
|
||||
ops.datbuf = buf;
|
||||
ops.len = mtd->writesize;
|
||||
res = mtd->read_oob(mtd, offs, &ops);
|
||||
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
|
||||
buf += mtd->oobsize + mtd->writesize;
|
||||
len -= mtd->writesize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
|
||||
size_t len, struct nand_bbt_descr *td)
|
||||
{
|
||||
if (td->options & NAND_BBT_NO_OOB)
|
||||
return scan_read_raw_data(mtd, buf, offs, td);
|
||||
else
|
||||
return scan_read_raw_oob(mtd, buf, offs, len);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -267,6 +392,15 @@ static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len,
|
|||
return mtd->write_oob(mtd, offs, &ops);
|
||||
}
|
||||
|
||||
static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td)
|
||||
{
|
||||
u32 ver_offs = td->veroffs;
|
||||
|
||||
if (!(td->options & NAND_BBT_NO_OOB))
|
||||
ver_offs += mtd->writesize;
|
||||
return ver_offs;
|
||||
}
|
||||
|
||||
/**
|
||||
* read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
|
||||
* @mtd: MTD device structure
|
||||
|
@ -285,18 +419,18 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
|
|||
|
||||
/* Read the primary version, if available */
|
||||
if (td->options & NAND_BBT_VERSION) {
|
||||
scan_read_raw(mtd, buf, (loff_t)td->pages[0] <<
|
||||
this->page_shift, mtd->writesize);
|
||||
td->version[0] = buf[mtd->writesize + td->veroffs];
|
||||
scan_read_raw(mtd, buf, (loff_t)td->pages[0] << this->page_shift,
|
||||
mtd->writesize, td);
|
||||
td->version[0] = buf[bbt_get_ver_offs(mtd, td)];
|
||||
printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
|
||||
td->pages[0], td->version[0]);
|
||||
}
|
||||
|
||||
/* Read the mirror version, if available */
|
||||
if (md && (md->options & NAND_BBT_VERSION)) {
|
||||
scan_read_raw(mtd, buf, (loff_t)md->pages[0] <<
|
||||
this->page_shift, mtd->writesize);
|
||||
md->version[0] = buf[mtd->writesize + md->veroffs];
|
||||
scan_read_raw(mtd, buf, (loff_t)md->pages[0] << this->page_shift,
|
||||
mtd->writesize, td);
|
||||
md->version[0] = buf[bbt_get_ver_offs(mtd, md)];
|
||||
printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
|
||||
md->pages[0], md->version[0]);
|
||||
}
|
||||
|
@ -312,7 +446,7 @@ static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
|
|||
{
|
||||
int ret, j;
|
||||
|
||||
ret = scan_read_raw(mtd, buf, offs, readlen);
|
||||
ret = scan_read_raw_oob(mtd, buf, offs, readlen);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -376,16 +510,14 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
|
|||
loff_t from;
|
||||
size_t readlen;
|
||||
|
||||
MTDDEBUG (MTD_DEBUG_LEVEL0, "Scanning device for bad blocks\n");
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL0, "Scanning device for bad blocks\n");
|
||||
|
||||
if (bd->options & NAND_BBT_SCANALLPAGES)
|
||||
len = 1 << (this->bbt_erase_shift - this->page_shift);
|
||||
else {
|
||||
if (bd->options & NAND_BBT_SCAN2NDPAGE)
|
||||
len = 2;
|
||||
else
|
||||
len = 1;
|
||||
}
|
||||
else if (bd->options & NAND_BBT_SCAN2NDPAGE)
|
||||
len = 2;
|
||||
else
|
||||
len = 1;
|
||||
|
||||
if (!(bd->options & NAND_BBT_SCANEMPTY)) {
|
||||
/* We need only read few bytes from the OOB area */
|
||||
|
@ -415,9 +547,14 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
|
|||
from = (loff_t)startblock << (this->bbt_erase_shift - 1);
|
||||
}
|
||||
|
||||
if (this->options & NAND_BBT_SCANLASTPAGE)
|
||||
from += mtd->erasesize - (mtd->writesize * len);
|
||||
|
||||
for (i = startblock; i < numblocks;) {
|
||||
int ret;
|
||||
|
||||
BUG_ON(bd->options & NAND_BBT_NO_OOB);
|
||||
|
||||
if (bd->options & NAND_BBT_SCANALLPAGES)
|
||||
ret = scan_block_full(mtd, bd, from, buf, readlen,
|
||||
scanlen, len);
|
||||
|
@ -429,7 +566,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
|
|||
|
||||
if (ret) {
|
||||
this->bbt[i >> 3] |= 0x03 << (i & 0x6);
|
||||
MTDDEBUG (MTD_DEBUG_LEVEL0,
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL0,
|
||||
"Bad eraseblock %d at 0x%012llx\n",
|
||||
i >> 1, (unsigned long long)from);
|
||||
mtd->ecc_stats.badblocks++;
|
||||
|
@ -497,11 +634,12 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
|
|||
loff_t offs = (loff_t)actblock << this->bbt_erase_shift;
|
||||
|
||||
/* Read first page */
|
||||
scan_read_raw(mtd, buf, offs, mtd->writesize);
|
||||
scan_read_raw(mtd, buf, offs, mtd->writesize, td);
|
||||
if (!check_pattern(buf, scanlen, mtd->writesize, td)) {
|
||||
td->pages[i] = actblock << blocktopage;
|
||||
if (td->options & NAND_BBT_VERSION) {
|
||||
td->version[i] = buf[mtd->writesize + td->veroffs];
|
||||
offs = bbt_get_ver_offs(mtd, td);
|
||||
td->version[i] = buf[offs];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -685,12 +823,26 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
|
|||
memset(&buf[offs], 0xff, (size_t) (numblocks >> sft));
|
||||
ooboffs = len + (pageoffs * mtd->oobsize);
|
||||
|
||||
} else if (td->options & NAND_BBT_NO_OOB) {
|
||||
ooboffs = 0;
|
||||
offs = td->len;
|
||||
/* the version byte */
|
||||
if (td->options & NAND_BBT_VERSION)
|
||||
offs++;
|
||||
/* Calc length */
|
||||
len = (size_t) (numblocks >> sft);
|
||||
len += offs;
|
||||
/* Make it page aligned ! */
|
||||
len = ALIGN(len, mtd->writesize);
|
||||
/* Preset the buffer with 0xff */
|
||||
memset(buf, 0xff, len);
|
||||
/* Pattern is located at the begin of first page */
|
||||
memcpy(buf, td->pattern, td->len);
|
||||
} else {
|
||||
/* Calc length */
|
||||
len = (size_t) (numblocks >> sft);
|
||||
/* Make it page aligned ! */
|
||||
len = (len + (mtd->writesize - 1)) &
|
||||
~(mtd->writesize - 1);
|
||||
len = ALIGN(len, mtd->writesize);
|
||||
/* Preset the buffer with 0xff */
|
||||
memset(buf, 0xff, len +
|
||||
(len >> this->page_shift)* mtd->oobsize);
|
||||
|
@ -724,13 +876,14 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
|
|||
if (res < 0)
|
||||
goto outerr;
|
||||
|
||||
res = scan_write_bbt(mtd, to, len, buf, &buf[len]);
|
||||
res = scan_write_bbt(mtd, to, len, buf,
|
||||
td->options & NAND_BBT_NO_OOB ? NULL :
|
||||
&buf[len]);
|
||||
if (res < 0)
|
||||
goto outerr;
|
||||
|
||||
printk(KERN_DEBUG "Bad block table written to 0x%012llx, "
|
||||
"version 0x%02X\n", (unsigned long long)to,
|
||||
td->version[chip]);
|
||||
printk(KERN_DEBUG "Bad block table written to 0x%012llx, version "
|
||||
"0x%02X\n", (unsigned long long)to, td->version[chip]);
|
||||
|
||||
/* Mark it as used */
|
||||
td->pages[chip] = page;
|
||||
|
@ -791,7 +944,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
|
|||
rd2 = NULL;
|
||||
/* Per chip or per device ? */
|
||||
chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
|
||||
/* Mirrored table avilable ? */
|
||||
/* Mirrored table available ? */
|
||||
if (md) {
|
||||
if (td->pages[i] == -1 && md->pages[i] == -1) {
|
||||
writeops = 0x03;
|
||||
|
@ -845,7 +998,8 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
|
|||
continue;
|
||||
|
||||
/* Create the table in memory by scanning the chip(s) */
|
||||
create_bbt(mtd, buf, bd, chipsel);
|
||||
if (!(this->options & NAND_CREATE_EMPTY_BBT))
|
||||
create_bbt(mtd, buf, bd, chipsel);
|
||||
|
||||
td->version[i] = 1;
|
||||
if (md)
|
||||
|
@ -910,8 +1064,7 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
|
|||
newval = oldval | (0x2 << (block & 0x06));
|
||||
this->bbt[(block >> 3)] = newval;
|
||||
if ((oldval != newval) && td->reserved_block_code)
|
||||
nand_update_bbt(mtd, (loff_t)block <<
|
||||
(this->bbt_erase_shift - 1));
|
||||
nand_update_bbt(mtd, (loff_t)block << (this->bbt_erase_shift - 1));
|
||||
continue;
|
||||
}
|
||||
update = 0;
|
||||
|
@ -932,11 +1085,58 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
|
|||
new ones have been marked, then we need to update the stored
|
||||
bbts. This should only happen once. */
|
||||
if (update && td->reserved_block_code)
|
||||
nand_update_bbt(mtd, (loff_t)(block - 2) <<
|
||||
(this->bbt_erase_shift - 1));
|
||||
nand_update_bbt(mtd, (loff_t)(block - 2) << (this->bbt_erase_shift - 1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* verify_bbt_descr - verify the bad block description
|
||||
* @mtd: MTD device structure
|
||||
* @bd: the table to verify
|
||||
*
|
||||
* This functions performs a few sanity checks on the bad block description
|
||||
* table.
|
||||
*/
|
||||
static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
|
||||
{
|
||||
struct nand_chip *this = mtd->priv;
|
||||
u32 pattern_len;
|
||||
u32 bits;
|
||||
u32 table_size;
|
||||
|
||||
if (!bd)
|
||||
return;
|
||||
|
||||
pattern_len = bd->len;
|
||||
bits = bd->options & NAND_BBT_NRBITS_MSK;
|
||||
|
||||
BUG_ON((this->options & NAND_USE_FLASH_BBT_NO_OOB) &&
|
||||
!(this->options & NAND_USE_FLASH_BBT));
|
||||
BUG_ON(!bits);
|
||||
|
||||
if (bd->options & NAND_BBT_VERSION)
|
||||
pattern_len++;
|
||||
|
||||
if (bd->options & NAND_BBT_NO_OOB) {
|
||||
BUG_ON(!(this->options & NAND_USE_FLASH_BBT));
|
||||
BUG_ON(!(this->options & NAND_USE_FLASH_BBT_NO_OOB));
|
||||
BUG_ON(bd->offs);
|
||||
if (bd->options & NAND_BBT_VERSION)
|
||||
BUG_ON(bd->veroffs != bd->len);
|
||||
BUG_ON(bd->options & NAND_BBT_SAVECONTENT);
|
||||
}
|
||||
|
||||
if (bd->options & NAND_BBT_PERCHIP)
|
||||
table_size = this->chipsize >> this->bbt_erase_shift;
|
||||
else
|
||||
table_size = mtd->size >> this->bbt_erase_shift;
|
||||
table_size >>= 3;
|
||||
table_size *= bits;
|
||||
if (bd->options & NAND_BBT_NO_OOB)
|
||||
table_size += pattern_len;
|
||||
BUG_ON(table_size > (1 << this->bbt_erase_shift));
|
||||
}
|
||||
|
||||
/**
|
||||
* nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
|
||||
* @mtd: MTD device structure
|
||||
|
@ -978,6 +1178,8 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
|
|||
}
|
||||
return res;
|
||||
}
|
||||
verify_bbt_descr(mtd, td);
|
||||
verify_bbt_descr(mtd, md);
|
||||
|
||||
/* Allocate a temporary buffer for one eraseblock incl. oob */
|
||||
len = (1 << this->bbt_erase_shift);
|
||||
|
@ -1073,34 +1275,6 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
|
|||
* while scanning a device for factory marked good / bad blocks. */
|
||||
static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
|
||||
|
||||
static struct nand_bbt_descr smallpage_memorybased = {
|
||||
.options = NAND_BBT_SCAN2NDPAGE,
|
||||
.offs = 5,
|
||||
.len = 1,
|
||||
.pattern = scan_ff_pattern
|
||||
};
|
||||
|
||||
static struct nand_bbt_descr largepage_memorybased = {
|
||||
.options = 0,
|
||||
.offs = 0,
|
||||
.len = 2,
|
||||
.pattern = scan_ff_pattern
|
||||
};
|
||||
|
||||
static struct nand_bbt_descr smallpage_flashbased = {
|
||||
.options = NAND_BBT_SCAN2NDPAGE,
|
||||
.offs = 5,
|
||||
.len = 1,
|
||||
.pattern = scan_ff_pattern
|
||||
};
|
||||
|
||||
static struct nand_bbt_descr largepage_flashbased = {
|
||||
.options = NAND_BBT_SCAN2NDPAGE,
|
||||
.offs = 0,
|
||||
.len = 2,
|
||||
.pattern = scan_ff_pattern
|
||||
};
|
||||
|
||||
static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 };
|
||||
|
||||
static struct nand_bbt_descr agand_flashbased = {
|
||||
|
@ -1135,6 +1309,59 @@ static struct nand_bbt_descr bbt_mirror_descr = {
|
|||
.pattern = mirror_pattern
|
||||
};
|
||||
|
||||
static struct nand_bbt_descr bbt_main_no_bbt_descr = {
|
||||
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
|
||||
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP
|
||||
| NAND_BBT_NO_OOB,
|
||||
.len = 4,
|
||||
.veroffs = 4,
|
||||
.maxblocks = 4,
|
||||
.pattern = bbt_pattern
|
||||
};
|
||||
|
||||
static struct nand_bbt_descr bbt_mirror_no_bbt_descr = {
|
||||
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
|
||||
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP
|
||||
| NAND_BBT_NO_OOB,
|
||||
.len = 4,
|
||||
.veroffs = 4,
|
||||
.maxblocks = 4,
|
||||
.pattern = mirror_pattern
|
||||
};
|
||||
|
||||
#define BBT_SCAN_OPTIONS (NAND_BBT_SCANLASTPAGE | NAND_BBT_SCAN2NDPAGE | \
|
||||
NAND_BBT_SCANBYTE1AND6)
|
||||
/**
|
||||
* nand_create_default_bbt_descr - [Internal] Creates a BBT descriptor structure
|
||||
* @this: NAND chip to create descriptor for
|
||||
*
|
||||
* This function allocates and initializes a nand_bbt_descr for BBM detection
|
||||
* based on the properties of "this". The new descriptor is stored in
|
||||
* this->badblock_pattern. Thus, this->badblock_pattern should be NULL when
|
||||
* passed to this function.
|
||||
*
|
||||
*/
|
||||
static int nand_create_default_bbt_descr(struct nand_chip *this)
|
||||
{
|
||||
struct nand_bbt_descr *bd;
|
||||
if (this->badblock_pattern) {
|
||||
printk(KERN_WARNING "BBT descr already allocated; not replacing.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
bd = kzalloc(sizeof(*bd), GFP_KERNEL);
|
||||
if (!bd) {
|
||||
printk(KERN_ERR "nand_create_default_bbt_descr: Out of memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
bd->options = this->options & BBT_SCAN_OPTIONS;
|
||||
bd->offs = this->badblockpos;
|
||||
bd->len = (this->options & NAND_BUSWIDTH_16) ? 2 : 1;
|
||||
bd->pattern = scan_ff_pattern;
|
||||
bd->options |= NAND_BBT_DYNAMICSTRUCT;
|
||||
this->badblock_pattern = bd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nand_default_bbt - [NAND Interface] Select a default bad block table for the device
|
||||
* @mtd: MTD device structure
|
||||
|
@ -1168,20 +1395,22 @@ int nand_default_bbt(struct mtd_info *mtd)
|
|||
if (this->options & NAND_USE_FLASH_BBT) {
|
||||
/* Use the default pattern descriptors */
|
||||
if (!this->bbt_td) {
|
||||
this->bbt_td = &bbt_main_descr;
|
||||
this->bbt_md = &bbt_mirror_descr;
|
||||
}
|
||||
if (!this->badblock_pattern) {
|
||||
this->badblock_pattern = (mtd->writesize > 512) ? &largepage_flashbased : &smallpage_flashbased;
|
||||
if (this->options & NAND_USE_FLASH_BBT_NO_OOB) {
|
||||
this->bbt_td = &bbt_main_no_bbt_descr;
|
||||
this->bbt_md = &bbt_mirror_no_bbt_descr;
|
||||
} else {
|
||||
this->bbt_td = &bbt_main_descr;
|
||||
this->bbt_md = &bbt_mirror_descr;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this->bbt_td = NULL;
|
||||
this->bbt_md = NULL;
|
||||
if (!this->badblock_pattern) {
|
||||
this->badblock_pattern = (mtd->writesize > 512) ?
|
||||
&largepage_memorybased : &smallpage_memorybased;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->badblock_pattern)
|
||||
nand_create_default_bbt_descr(this);
|
||||
|
||||
return nand_scan_bbt(mtd, this->badblock_pattern);
|
||||
}
|
||||
|
||||
|
@ -1202,8 +1431,8 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
|
|||
block = (int)(offs >> (this->bbt_erase_shift - 1));
|
||||
res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
|
||||
|
||||
MTDDEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: "
|
||||
"(block %d) 0x%02x\n", (unsigned int)offs, res, block >> 1);
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
|
||||
(unsigned int)offs, block >> 1, res);
|
||||
|
||||
switch ((int)res) {
|
||||
case 0x00:
|
||||
|
|
236
drivers/mtd/nand/nand_bch.c
Normal file
236
drivers/mtd/nand/nand_bch.c
Normal file
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* This file provides ECC correction for more than 1 bit per block of data,
|
||||
* using binary BCH codes. It relies on the generic BCH library lib/bch.c.
|
||||
*
|
||||
* Copyright © 2011 Ivan Djelic <ivan.djelic@parrot.com>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this file; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
/*#include <asm/io.h>*/
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/nand_bch.h>
|
||||
#include <linux/bch.h>
|
||||
#include <malloc.h>
|
||||
|
||||
/**
|
||||
* struct nand_bch_control - private NAND BCH control structure
|
||||
* @bch: BCH control structure
|
||||
* @ecclayout: private ecc layout for this BCH configuration
|
||||
* @errloc: error location array
|
||||
* @eccmask: XOR ecc mask, allows erased pages to be decoded as valid
|
||||
*/
|
||||
struct nand_bch_control {
|
||||
struct bch_control *bch;
|
||||
struct nand_ecclayout ecclayout;
|
||||
unsigned int *errloc;
|
||||
unsigned char *eccmask;
|
||||
};
|
||||
|
||||
/**
|
||||
* nand_bch_calculate_ecc - [NAND Interface] Calculate ECC for data block
|
||||
* @mtd: MTD block structure
|
||||
* @buf: input buffer with raw data
|
||||
* @code: output buffer with ECC
|
||||
*/
|
||||
int nand_bch_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf,
|
||||
unsigned char *code)
|
||||
{
|
||||
const struct nand_chip *chip = mtd->priv;
|
||||
struct nand_bch_control *nbc = chip->ecc.priv;
|
||||
unsigned int i;
|
||||
|
||||
memset(code, 0, chip->ecc.bytes);
|
||||
encode_bch(nbc->bch, buf, chip->ecc.size, code);
|
||||
|
||||
/* apply mask so that an erased page is a valid codeword */
|
||||
for (i = 0; i < chip->ecc.bytes; i++)
|
||||
code[i] ^= nbc->eccmask[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nand_bch_correct_data - [NAND Interface] Detect and correct bit error(s)
|
||||
* @mtd: MTD block structure
|
||||
* @buf: raw data read from the chip
|
||||
* @read_ecc: ECC from the chip
|
||||
* @calc_ecc: the ECC calculated from raw data
|
||||
*
|
||||
* Detect and correct bit errors for a data byte block
|
||||
*/
|
||||
int nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf,
|
||||
unsigned char *read_ecc, unsigned char *calc_ecc)
|
||||
{
|
||||
const struct nand_chip *chip = mtd->priv;
|
||||
struct nand_bch_control *nbc = chip->ecc.priv;
|
||||
unsigned int *errloc = nbc->errloc;
|
||||
int i, count;
|
||||
|
||||
count = decode_bch(nbc->bch, NULL, chip->ecc.size, read_ecc, calc_ecc,
|
||||
NULL, errloc);
|
||||
if (count > 0) {
|
||||
for (i = 0; i < count; i++) {
|
||||
if (errloc[i] < (chip->ecc.size*8))
|
||||
/* error is located in data, correct it */
|
||||
buf[errloc[i] >> 3] ^= (1 << (errloc[i] & 7));
|
||||
/* else error in ecc, no action needed */
|
||||
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL0, "%s: corrected bitflip %u\n",
|
||||
__func__, errloc[i]);
|
||||
}
|
||||
} else if (count < 0) {
|
||||
printk(KERN_ERR "ecc unrecoverable error\n");
|
||||
count = -1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* nand_bch_init - [NAND Interface] Initialize NAND BCH error correction
|
||||
* @mtd: MTD block structure
|
||||
* @eccsize: ecc block size in bytes
|
||||
* @eccbytes: ecc length in bytes
|
||||
* @ecclayout: output default layout
|
||||
*
|
||||
* Returns:
|
||||
* a pointer to a new NAND BCH control structure, or NULL upon failure
|
||||
*
|
||||
* Initialize NAND BCH error correction. Parameters @eccsize and @eccbytes
|
||||
* are used to compute BCH parameters m (Galois field order) and t (error
|
||||
* correction capability). @eccbytes should be equal to the number of bytes
|
||||
* required to store m*t bits, where m is such that 2^m-1 > @eccsize*8.
|
||||
*
|
||||
* Example: to configure 4 bit correction per 512 bytes, you should pass
|
||||
* @eccsize = 512 (thus, m=13 is the smallest integer such that 2^m-1 > 512*8)
|
||||
* @eccbytes = 7 (7 bytes are required to store m*t = 13*4 = 52 bits)
|
||||
*/
|
||||
struct nand_bch_control *
|
||||
nand_bch_init(struct mtd_info *mtd, unsigned int eccsize, unsigned int eccbytes,
|
||||
struct nand_ecclayout **ecclayout)
|
||||
{
|
||||
unsigned int m, t, eccsteps, i;
|
||||
struct nand_ecclayout *layout;
|
||||
struct nand_bch_control *nbc = NULL;
|
||||
unsigned char *erased_page;
|
||||
|
||||
if (!eccsize || !eccbytes) {
|
||||
printk(KERN_WARNING "ecc parameters not supplied\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
m = fls(1+8*eccsize);
|
||||
t = (eccbytes*8)/m;
|
||||
|
||||
nbc = kzalloc(sizeof(*nbc), GFP_KERNEL);
|
||||
if (!nbc)
|
||||
goto fail;
|
||||
|
||||
nbc->bch = init_bch(m, t, 0);
|
||||
if (!nbc->bch)
|
||||
goto fail;
|
||||
|
||||
/* verify that eccbytes has the expected value */
|
||||
if (nbc->bch->ecc_bytes != eccbytes) {
|
||||
printk(KERN_WARNING "invalid eccbytes %u, should be %u\n",
|
||||
eccbytes, nbc->bch->ecc_bytes);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
eccsteps = mtd->writesize/eccsize;
|
||||
|
||||
/* if no ecc placement scheme was provided, build one */
|
||||
if (!*ecclayout) {
|
||||
|
||||
/* handle large page devices only */
|
||||
if (mtd->oobsize < 64) {
|
||||
printk(KERN_WARNING "must provide an oob scheme for "
|
||||
"oobsize %d\n", mtd->oobsize);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
layout = &nbc->ecclayout;
|
||||
layout->eccbytes = eccsteps*eccbytes;
|
||||
|
||||
/* reserve 2 bytes for bad block marker */
|
||||
if (layout->eccbytes+2 > mtd->oobsize) {
|
||||
printk(KERN_WARNING "no suitable oob scheme available "
|
||||
"for oobsize %d eccbytes %u\n", mtd->oobsize,
|
||||
eccbytes);
|
||||
goto fail;
|
||||
}
|
||||
/* put ecc bytes at oob tail */
|
||||
for (i = 0; i < layout->eccbytes; i++)
|
||||
layout->eccpos[i] = mtd->oobsize-layout->eccbytes+i;
|
||||
|
||||
layout->oobfree[0].offset = 2;
|
||||
layout->oobfree[0].length = mtd->oobsize-2-layout->eccbytes;
|
||||
|
||||
*ecclayout = layout;
|
||||
}
|
||||
|
||||
/* sanity checks */
|
||||
if (8*(eccsize+eccbytes) >= (1 << m)) {
|
||||
printk(KERN_WARNING "eccsize %u is too large\n", eccsize);
|
||||
goto fail;
|
||||
}
|
||||
if ((*ecclayout)->eccbytes != (eccsteps*eccbytes)) {
|
||||
printk(KERN_WARNING "invalid ecc layout\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
nbc->eccmask = kmalloc(eccbytes, GFP_KERNEL);
|
||||
nbc->errloc = kmalloc(t*sizeof(*nbc->errloc), GFP_KERNEL);
|
||||
if (!nbc->eccmask || !nbc->errloc)
|
||||
goto fail;
|
||||
/*
|
||||
* compute and store the inverted ecc of an erased ecc block
|
||||
*/
|
||||
erased_page = kmalloc(eccsize, GFP_KERNEL);
|
||||
if (!erased_page)
|
||||
goto fail;
|
||||
|
||||
memset(erased_page, 0xff, eccsize);
|
||||
memset(nbc->eccmask, 0, eccbytes);
|
||||
encode_bch(nbc->bch, erased_page, eccsize, nbc->eccmask);
|
||||
kfree(erased_page);
|
||||
|
||||
for (i = 0; i < eccbytes; i++)
|
||||
nbc->eccmask[i] ^= 0xff;
|
||||
|
||||
return nbc;
|
||||
fail:
|
||||
nand_bch_free(nbc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* nand_bch_free - [NAND Interface] Release NAND BCH ECC resources
|
||||
* @nbc: NAND BCH control structure
|
||||
*/
|
||||
void nand_bch_free(struct nand_bch_control *nbc)
|
||||
{
|
||||
if (nbc) {
|
||||
free_bch(nbc->bch);
|
||||
kfree(nbc->errloc);
|
||||
kfree(nbc->eccmask);
|
||||
kfree(nbc);
|
||||
}
|
||||
}
|
|
@ -76,9 +76,13 @@ const struct nand_flash_dev nand_flash_ids[] = {
|
|||
|
||||
/*512 Megabit */
|
||||
{"NAND 64MiB 1,8V 8-bit", 0xA2, 0, 64, 0, LP_OPTIONS},
|
||||
{"NAND 64MiB 1,8V 8-bit", 0xA0, 0, 64, 0, LP_OPTIONS},
|
||||
{"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, LP_OPTIONS},
|
||||
{"NAND 64MiB 3,3V 8-bit", 0xD0, 0, 64, 0, LP_OPTIONS},
|
||||
{"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, LP_OPTIONS16},
|
||||
{"NAND 64MiB 1,8V 16-bit", 0xB0, 0, 64, 0, LP_OPTIONS16},
|
||||
{"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, LP_OPTIONS16},
|
||||
{"NAND 64MiB 3,3V 16-bit", 0xC0, 0, 64, 0, LP_OPTIONS16},
|
||||
|
||||
/* 1 Gigabit */
|
||||
{"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, LP_OPTIONS},
|
||||
|
@ -86,6 +90,7 @@ const struct nand_flash_dev nand_flash_ids[] = {
|
|||
{"NAND 128MiB 3,3V 8-bit", 0xD1, 0, 128, 0, LP_OPTIONS},
|
||||
{"NAND 128MiB 1,8V 16-bit", 0xB1, 0, 128, 0, LP_OPTIONS16},
|
||||
{"NAND 128MiB 3,3V 16-bit", 0xC1, 0, 128, 0, LP_OPTIONS16},
|
||||
{"NAND 128MiB 1,8V 16-bit", 0xAD, 0, 128, 0, LP_OPTIONS16},
|
||||
|
||||
/* 2 Gigabit */
|
||||
{"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, LP_OPTIONS},
|
||||
|
@ -111,6 +116,36 @@ const struct nand_flash_dev nand_flash_ids[] = {
|
|||
{"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, LP_OPTIONS16},
|
||||
{"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, LP_OPTIONS16},
|
||||
|
||||
/* 32 Gigabit */
|
||||
{"NAND 4GiB 1,8V 8-bit", 0xA7, 0, 4096, 0, LP_OPTIONS},
|
||||
{"NAND 4GiB 3,3V 8-bit", 0xD7, 0, 4096, 0, LP_OPTIONS},
|
||||
{"NAND 4GiB 1,8V 16-bit", 0xB7, 0, 4096, 0, LP_OPTIONS16},
|
||||
{"NAND 4GiB 3,3V 16-bit", 0xC7, 0, 4096, 0, LP_OPTIONS16},
|
||||
|
||||
/* 64 Gigabit */
|
||||
{"NAND 8GiB 1,8V 8-bit", 0xAE, 0, 8192, 0, LP_OPTIONS},
|
||||
{"NAND 8GiB 3,3V 8-bit", 0xDE, 0, 8192, 0, LP_OPTIONS},
|
||||
{"NAND 8GiB 1,8V 16-bit", 0xBE, 0, 8192, 0, LP_OPTIONS16},
|
||||
{"NAND 8GiB 3,3V 16-bit", 0xCE, 0, 8192, 0, LP_OPTIONS16},
|
||||
|
||||
/* 128 Gigabit */
|
||||
{"NAND 16GiB 1,8V 8-bit", 0x1A, 0, 16384, 0, LP_OPTIONS},
|
||||
{"NAND 16GiB 3,3V 8-bit", 0x3A, 0, 16384, 0, LP_OPTIONS},
|
||||
{"NAND 16GiB 1,8V 16-bit", 0x2A, 0, 16384, 0, LP_OPTIONS16},
|
||||
{"NAND 16GiB 3,3V 16-bit", 0x4A, 0, 16384, 0, LP_OPTIONS16},
|
||||
|
||||
/* 256 Gigabit */
|
||||
{"NAND 32GiB 1,8V 8-bit", 0x1C, 0, 32768, 0, LP_OPTIONS},
|
||||
{"NAND 32GiB 3,3V 8-bit", 0x3C, 0, 32768, 0, LP_OPTIONS},
|
||||
{"NAND 32GiB 1,8V 16-bit", 0x2C, 0, 32768, 0, LP_OPTIONS16},
|
||||
{"NAND 32GiB 3,3V 16-bit", 0x4C, 0, 32768, 0, LP_OPTIONS16},
|
||||
|
||||
/* 512 Gigabit */
|
||||
{"NAND 64GiB 1,8V 8-bit", 0x1E, 0, 65536, 0, LP_OPTIONS},
|
||||
{"NAND 64GiB 3,3V 8-bit", 0x3E, 0, 65536, 0, LP_OPTIONS},
|
||||
{"NAND 64GiB 1,8V 16-bit", 0x2E, 0, 65536, 0, LP_OPTIONS16},
|
||||
{"NAND 64GiB 3,3V 16-bit", 0x4E, 0, 65536, 0, LP_OPTIONS16},
|
||||
|
||||
/*
|
||||
* Renesas AND 1 Gigabit. Those chips do not support extended id and
|
||||
* have a strange page/block layout ! The chosen minimum erasesize is
|
||||
|
|
|
@ -27,6 +27,11 @@ static int nand_ecc_pos[] = CONFIG_SYS_NAND_ECCPOS;
|
|||
static nand_info_t mtd;
|
||||
static struct nand_chip nand_chip;
|
||||
|
||||
#define ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
|
||||
CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define ECCTOTAL (ECCSTEPS * CONFIG_SYS_NAND_ECCBYTES)
|
||||
|
||||
|
||||
#if (CONFIG_SYS_NAND_PAGE_SIZE <= 512)
|
||||
/*
|
||||
* NAND command for small page NAND devices (512)
|
||||
|
@ -145,29 +150,21 @@ static int nand_is_bad_block(int block)
|
|||
static int nand_read_page(int block, int page, uchar *dst)
|
||||
{
|
||||
struct nand_chip *this = mtd.priv;
|
||||
u_char *ecc_calc;
|
||||
u_char *ecc_code;
|
||||
u_char *oob_data;
|
||||
u_char ecc_calc[ECCTOTAL];
|
||||
u_char ecc_code[ECCTOTAL];
|
||||
u_char oob_data[CONFIG_SYS_NAND_OOBSIZE];
|
||||
int i;
|
||||
int eccsize = CONFIG_SYS_NAND_ECCSIZE;
|
||||
int eccbytes = CONFIG_SYS_NAND_ECCBYTES;
|
||||
int eccsteps = CONFIG_SYS_NAND_ECCSTEPS;
|
||||
int eccsteps = ECCSTEPS;
|
||||
uint8_t *p = dst;
|
||||
|
||||
/*
|
||||
* No malloc available for now, just use some temporary locations
|
||||
* in SDRAM
|
||||
*/
|
||||
ecc_calc = (u_char *)(CONFIG_SYS_SDRAM_BASE + 0x10000);
|
||||
ecc_code = ecc_calc + 0x100;
|
||||
oob_data = ecc_calc + 0x200;
|
||||
|
||||
nand_command(block, page, 0, NAND_CMD_READOOB);
|
||||
this->read_buf(&mtd, oob_data, CONFIG_SYS_NAND_OOBSIZE);
|
||||
nand_command(block, page, 0, NAND_CMD_READ0);
|
||||
|
||||
/* Pick the ECC bytes out of the oob data */
|
||||
for (i = 0; i < CONFIG_SYS_NAND_ECCTOTAL; i++)
|
||||
for (i = 0; i < ECCTOTAL; i++)
|
||||
ecc_code[i] = oob_data[nand_ecc_pos[i]];
|
||||
|
||||
|
||||
|
@ -184,24 +181,17 @@ static int nand_read_page(int block, int page, uchar *dst)
|
|||
static int nand_read_page(int block, int page, void *dst)
|
||||
{
|
||||
struct nand_chip *this = mtd.priv;
|
||||
u_char *ecc_calc;
|
||||
u_char *ecc_code;
|
||||
u_char *oob_data;
|
||||
u_char ecc_calc[ECCTOTAL];
|
||||
u_char ecc_code[ECCTOTAL];
|
||||
u_char oob_data[CONFIG_SYS_NAND_OOBSIZE];
|
||||
int i;
|
||||
int eccsize = CONFIG_SYS_NAND_ECCSIZE;
|
||||
int eccbytes = CONFIG_SYS_NAND_ECCBYTES;
|
||||
int eccsteps = CONFIG_SYS_NAND_ECCSTEPS;
|
||||
int eccsteps = ECCSTEPS;
|
||||
uint8_t *p = dst;
|
||||
|
||||
nand_command(block, page, 0, NAND_CMD_READ0);
|
||||
|
||||
/* No malloc available for now, just use some temporary locations
|
||||
* in SDRAM
|
||||
*/
|
||||
ecc_calc = (u_char *)(CONFIG_SYS_SDRAM_BASE + 0x10000);
|
||||
ecc_code = ecc_calc + 0x100;
|
||||
oob_data = ecc_calc + 0x200;
|
||||
|
||||
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
|
||||
if (this->ecc.mode != NAND_ECC_SOFT)
|
||||
this->ecc.hwctl(&mtd, NAND_ECC_READ);
|
||||
|
@ -211,10 +201,10 @@ static int nand_read_page(int block, int page, void *dst)
|
|||
this->read_buf(&mtd, oob_data, CONFIG_SYS_NAND_OOBSIZE);
|
||||
|
||||
/* Pick the ECC bytes out of the oob data */
|
||||
for (i = 0; i < CONFIG_SYS_NAND_ECCTOTAL; i++)
|
||||
for (i = 0; i < ECCTOTAL; i++)
|
||||
ecc_code[i] = oob_data[nand_ecc_pos[i]];
|
||||
|
||||
eccsteps = CONFIG_SYS_NAND_ECCSTEPS;
|
||||
eccsteps = ECCSTEPS;
|
||||
p = dst;
|
||||
|
||||
for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
|
||||
|
|
|
@ -273,11 +273,10 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#define CONFIG_CMD_NAND
|
||||
#define CONFIG_SYS_NAND_BASE_LIST {CONFIG_SYS_NAND_BASE}
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define NAND_MAX_CHIPS 1
|
||||
#define CONFIG_MTD_NAND_VERIFY_WRITE
|
||||
#define CONFIG_CMD_NAND 1
|
||||
#define CONFIG_NAND_FSL_ELBC 1
|
||||
#define CONFIG_SYS_NAND_BLOCK_SIZE (16 * 1024)
|
||||
|
||||
|
|
|
@ -200,9 +200,7 @@
|
|||
|
||||
#define CONFIG_SYS_NAND_ECCSIZE 256
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 3
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define CONFIG_SYS_NAND_OOBSIZE 16
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * CONFIG_SYS_NAND_ECCSTEPS)
|
||||
#define CONFIG_SYS_NAND_ECCPOS {0, 1, 2, 3, 6, 7}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -144,10 +144,9 @@
|
|||
#endif
|
||||
#define CONFIG_SYS_FPGA_BASE 0xFF000000
|
||||
|
||||
#define CONFIG_CMD_NAND
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define NAND_MAX_CHIPS 1
|
||||
#define CONFIG_MTD_NAND_VERIFY_WRITE
|
||||
#define CONFIG_CMD_NAND 1
|
||||
#define CONFIG_NAND_FSL_ELBC 1
|
||||
|
||||
#define CONFIG_SYS_NAND_BR_PRELIM (CONFIG_SYS_NAND_BASE \
|
||||
|
|
|
@ -237,7 +237,6 @@
|
|||
#define CONFIG_NAND_S3C2410
|
||||
#define CONFIG_SYS_S3C2410_NAND_HWECC
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define NAND_MAX_CHIPS 1
|
||||
#define CONFIG_SYS_NAND_BASE 0x4E000000
|
||||
#define CONFIG_S3C24XX_CUSTOM_NAND_TIMING
|
||||
#define CONFIG_S3C24XX_TACLS 1
|
||||
|
|
|
@ -185,9 +185,7 @@
|
|||
|
||||
#define CONFIG_SYS_NAND_ECCSIZE 256
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 3
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define CONFIG_SYS_NAND_OOBSIZE 16
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * CONFIG_SYS_NAND_ECCSTEPS)
|
||||
#define CONFIG_SYS_NAND_ECCPOS {0, 1, 2, 3, 6, 7}
|
||||
|
||||
#ifdef CONFIG_ENV_IS_IN_NAND
|
||||
|
|
|
@ -359,10 +359,6 @@
|
|||
10, 11, 12, 13}
|
||||
#define CONFIG_SYS_NAND_ECCSIZE 512
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 3
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
|
||||
CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
|
||||
CONFIG_SYS_NAND_ECCSTEPS)
|
||||
#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
|
||||
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
|
||||
|
||||
|
|
|
@ -360,10 +360,6 @@
|
|||
10, 11, 12, 13}
|
||||
#define CONFIG_SYS_NAND_ECCSIZE 512
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 3
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
|
||||
CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
|
||||
CONFIG_SYS_NAND_ECCSTEPS)
|
||||
#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
|
||||
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
|
||||
|
||||
|
|
|
@ -247,13 +247,9 @@
|
|||
*/
|
||||
#define CONFIG_CMD_NAND /* enable NAND support */
|
||||
#define CONFIG_JFFS2_NAND /* with JFFS2 on it */
|
||||
|
||||
|
||||
#define CONFIG_NAND_MPC5121_NFC
|
||||
#define CONFIG_SYS_NAND_BASE 0x40000000
|
||||
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define NAND_MAX_CHIPS CONFIG_SYS_MAX_NAND_DEVICE
|
||||
|
||||
/*
|
||||
* Configuration parameters for MPC5121 NAND driver
|
||||
|
|
|
@ -128,7 +128,6 @@
|
|||
|
||||
/* NAND flash */
|
||||
#ifdef CONFIG_CMD_NAND
|
||||
#define CONFIG_NAND_MAX_CHIPS 1
|
||||
#define CONFIG_NAND_ATMEL
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define CONFIG_SYS_NAND_BASE ATMEL_BASE_CS3
|
||||
|
|
|
@ -179,9 +179,7 @@
|
|||
|
||||
#define CONFIG_SYS_NAND_ECCSIZE 256
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 3
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define CONFIG_SYS_NAND_OOBSIZE 16
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * CONFIG_SYS_NAND_ECCSTEPS)
|
||||
#define CONFIG_SYS_NAND_ECCPOS {0, 1, 2, 3, 6, 7}
|
||||
|
||||
#ifdef CONFIG_ENV_IS_IN_NAND
|
||||
|
|
|
@ -70,7 +70,6 @@
|
|||
#define CONFIG_DRIVER_NAND_BFIN
|
||||
#define CONFIG_SYS_NAND_BASE 0 /* not actually used */
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define NAND_MAX_CHIPS 1
|
||||
#define CONFIG_CMD_NAND
|
||||
#endif
|
||||
|
||||
|
|
|
@ -69,7 +69,6 @@
|
|||
#define CONFIG_DRIVER_NAND_BFIN
|
||||
#define CONFIG_SYS_NAND_BASE 0 /* not actually used */
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define NAND_MAX_CHIPS 1
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -69,7 +69,6 @@
|
|||
#define CONFIG_DRIVER_NAND_BFIN
|
||||
#define CONFIG_SYS_NAND_BASE 0 /* not actually used */
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define NAND_MAX_CHIPS 1
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -131,7 +131,6 @@
|
|||
#define CONFIG_DRIVER_NAND_BFIN
|
||||
#define CONFIG_SYS_NAND_BASE 0 /* not actually used */
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define NAND_MAX_CHIPS 1
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -90,7 +90,6 @@
|
|||
#define CONFIG_SYS_NAND_BASE_LIST { 0x02000000, }
|
||||
/* socket has two chipselects, nCE0 gated by address BIT(14) */
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define CONFIG_SYS_NAND_MAX_CHIPS 1
|
||||
|
||||
/* SPI support */
|
||||
#define CONFIG_SPI
|
||||
|
@ -236,9 +235,6 @@
|
|||
#define CONFIG_SYS_NAND_ECCBYTES 10
|
||||
#define CONFIG_SYS_NAND_OOBSIZE 64
|
||||
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
|
||||
CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (40)
|
||||
|
||||
/*
|
||||
* RBL searches from Block n (n = 1..24)
|
||||
|
|
|
@ -197,9 +197,7 @@
|
|||
|
||||
#define CONFIG_SYS_NAND_ECCSIZE 256
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 3
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define CONFIG_SYS_NAND_OOBSIZE 64
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * CONFIG_SYS_NAND_ECCSTEPS)
|
||||
#define CONFIG_SYS_NAND_ECCPOS {40, 41, 42, 43, 44, 45, 46, 47, \
|
||||
48, 49, 50, 51, 52, 53, 54, 55, \
|
||||
56, 57, 58, 59, 60, 61, 62, 63}
|
||||
|
|
|
@ -68,7 +68,6 @@
|
|||
#define CONFIG_BFIN_NFC_CTL_VAL 0x0033
|
||||
#define CONFIG_SYS_NAND_BASE 0 /* not actually used */
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define NAND_MAX_CHIPS 1
|
||||
#define CONFIG_CMD_NAND
|
||||
#endif
|
||||
|
||||
|
|
|
@ -295,7 +295,6 @@
|
|||
|
||||
/* NAND flash */
|
||||
#define CONFIG_NAND_ATMEL
|
||||
#define NAND_MAX_CHIPS 1
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define CONFIG_SYS_NAND_BASE 0x40000000
|
||||
#define CONFIG_SYS_NAND_DBW_8 1
|
||||
|
|
|
@ -115,7 +115,6 @@
|
|||
#define CONFIG_SYS_CLE_MASK 0x10
|
||||
#define CONFIG_SYS_ALE_MASK 0x8
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
|
||||
#define NAND_MAX_CHIPS 1
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USE_NOR
|
||||
|
|
|
@ -182,7 +182,6 @@
|
|||
#define CONFIG_SYS_ALE_MASK 0x8
|
||||
#undef CONFIG_SYS_NAND_HW_ECC
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
|
||||
#define NAND_MAX_CHIPS 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -69,7 +69,6 @@
|
|||
|
||||
#define CONFIG_SYS_NAND_BASE_LIST { 0x02000000, }
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define CONFIG_SYS_NAND_MAX_CHIPS 1
|
||||
|
||||
/* U-Boot command configuration */
|
||||
#include <config_cmd_default.h>
|
||||
|
|
|
@ -343,11 +343,6 @@
|
|||
#define CONFIG_SYS_NAND_ECCSIZE 512
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 3
|
||||
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
|
||||
CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
|
||||
CONFIG_SYS_NAND_ECCSTEPS)
|
||||
|
||||
#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
|
||||
|
||||
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
|
||||
|
|
|
@ -197,7 +197,6 @@
|
|||
#define CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST
|
||||
#define CONFIG_SYS_NAND_USE_FLASH_BBT
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
|
||||
#define NAND_MAX_CHIPS 1
|
||||
#define CONFIG_SYS_64BIT_VSPRINTF /* needed for nand_util.c */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -270,7 +270,6 @@
|
|||
|
||||
/* NAND */
|
||||
|
||||
#define CONFIG_SYS_NAND_MAX_CHIPS 1
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define CONFIG_SYS_NAND_BASE 0x40000000
|
||||
#define CONFIG_SYS_NAND_DBW_8 1
|
||||
|
|
|
@ -115,7 +115,6 @@
|
|||
#define CONFIG_SYS_ALE_MASK 0x8
|
||||
#undef CONFIG_SYS_NAND_HW_ECC
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
|
||||
#define NAND_MAX_CHIPS 1
|
||||
|
||||
#define MTDIDS_DEFAULT "nor0=physmap-flash.0,nand0=davinci_nand.1"
|
||||
#define MTDPARTS_DEFAULT \
|
||||
|
|
|
@ -114,7 +114,6 @@
|
|||
/* Max number of NAND devices */
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define CONFIG_SYS_NAND_BASE_LIST { 0x62000000, }
|
||||
#define NAND_MAX_CHIPS 1
|
||||
/* Block 0--not used by bootcode */
|
||||
#define CONFIG_ENV_OFFSET 0x0
|
||||
|
||||
|
@ -138,11 +137,8 @@
|
|||
#define CONFIG_SYS_NAND_BAD_BLOCK_POS 0
|
||||
#define CONFIG_SYS_NAND_ECCSIZE 512
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 10
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
|
||||
CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define CONFIG_SYS_NAND_OOBSIZE 64
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
|
||||
CONFIG_SYS_NAND_ECCSTEPS)
|
||||
|
||||
#endif /* CONFIG_SYS_USE_NAND */
|
||||
|
||||
/*
|
||||
|
|
|
@ -210,9 +210,7 @@
|
|||
|
||||
#define CONFIG_SYS_NAND_ECCSIZE 256
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 3
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define CONFIG_SYS_NAND_OOBSIZE 16
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * CONFIG_SYS_NAND_ECCSTEPS)
|
||||
#define CONFIG_SYS_NAND_ECCPOS {0, 1, 2, 3, 6, 7}
|
||||
|
||||
#ifdef CONFIG_ENV_IS_IN_NAND
|
||||
|
|
|
@ -133,7 +133,6 @@
|
|||
* NAND Flash configuration
|
||||
*/
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define NAND_MAX_CHIPS 1
|
||||
|
||||
#define BOOTFLASH_START 0x0
|
||||
|
||||
|
|
|
@ -154,7 +154,6 @@
|
|||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define CONFIG_SYS_NAND_BASE 0x60000000
|
||||
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
|
||||
#define NAND_MAX_CHIPS 8
|
||||
|
||||
/* Environment is in NAND */
|
||||
#define CONFIG_ENV_IS_IN_NAND
|
||||
|
|
|
@ -178,9 +178,7 @@
|
|||
#define CONFIG_CMD_NAND
|
||||
#define CONFIG_NAND_MPC5121_NFC
|
||||
#define CONFIG_SYS_NAND_BASE 0x40000000
|
||||
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define NAND_MAX_CHIPS CONFIG_SYS_MAX_NAND_DEVICE
|
||||
|
||||
/*
|
||||
* Configuration parameters for MPC5121 NAND driver
|
||||
|
|
|
@ -242,7 +242,6 @@
|
|||
#define CONFIG_SYS_NAND_BASE 0x40000000
|
||||
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 2
|
||||
#define NAND_MAX_CHIPS CONFIG_SYS_MAX_NAND_DEVICE
|
||||
#define CONFIG_SYS_NAND_SELECT_DEVICE /* driver supports mutipl. chips */
|
||||
|
||||
/*
|
||||
|
|
|
@ -132,7 +132,6 @@
|
|||
*/
|
||||
#ifdef CONFIG_CMD_NAND
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define NAND_MAX_CHIPS 1
|
||||
#define CONFIG_SYS_64BIT_VSPRINTF /* needed for nand_util.c */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -418,10 +418,6 @@
|
|||
10, 11, 12, 13}
|
||||
#define CONFIG_SYS_NAND_ECCSIZE 512
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 3
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
|
||||
CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
|
||||
CONFIG_SYS_NAND_ECCSTEPS)
|
||||
#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
|
||||
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
|
||||
|
||||
|
|
|
@ -121,10 +121,6 @@
|
|||
10, 11, 12, 13}
|
||||
#define CONFIG_SYS_NAND_ECCSIZE 512
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 3
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
|
||||
CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
|
||||
CONFIG_SYS_NAND_ECCSTEPS)
|
||||
#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
|
||||
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
|
||||
|
||||
|
|
|
@ -91,10 +91,6 @@
|
|||
10, 11, 12, 13}
|
||||
#define CONFIG_SYS_NAND_ECCSIZE 512
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 3
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
|
||||
CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
|
||||
CONFIG_SYS_NAND_ECCSTEPS)
|
||||
#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
|
||||
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
|
||||
|
||||
|
|
|
@ -225,9 +225,7 @@
|
|||
#define CONFIG_CMD_NAND /* enable NAND support */
|
||||
#define CONFIG_NAND_MPC5121_NFC
|
||||
#define CONFIG_SYS_NAND_BASE 0x40000000
|
||||
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define NAND_MAX_CHIPS CONFIG_SYS_MAX_NAND_DEVICE
|
||||
#define CONFIG_SYS_NAND_SELECT_DEVICE /* driver supports mutipl. chips */
|
||||
|
||||
/*
|
||||
|
|
|
@ -233,7 +233,6 @@
|
|||
|
||||
/* NAND flash */
|
||||
#define CONFIG_NAND_ATMEL
|
||||
#define NAND_MAX_CHIPS 1
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define CONFIG_SYS_NAND_BASE 0x40000000
|
||||
#define CONFIG_SYS_NAND_DBW_8 1
|
||||
|
|
|
@ -253,7 +253,6 @@
|
|||
/* NAND flash */
|
||||
#ifdef CONFIG_CMD_NAND
|
||||
#define CONFIG_NAND_ATMEL
|
||||
#define CONFIG_SYS_NAND_MAX_CHIPS 1
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define CONFIG_SYS_NAND_BASE 0x40000000
|
||||
#define CONFIG_SYS_NAND_DBW_8 1
|
||||
|
|
|
@ -115,7 +115,6 @@
|
|||
|
||||
/* NAND flash */
|
||||
#ifdef CONFIG_CMD_NAND
|
||||
#define CONFIG_NAND_MAX_CHIPS 1
|
||||
#define CONFIG_NAND_ATMEL
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define CONFIG_SYS_NAND_BASE 0x40000000
|
||||
|
|
|
@ -99,10 +99,6 @@
|
|||
#define CONFIG_SYS_NAND_ECC_POS (6 * NANONOTE_NAND_SIZE)
|
||||
#define CONFIG_SYS_NAND_ECCSIZE 512
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 9
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS \
|
||||
(CONFIG_SYS_NAND_PAGE_SIZE / CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL \
|
||||
(CONFIG_SYS_NAND_ECCBYTES * CONFIG_SYS_NAND_ECCSTEPS)
|
||||
#define CONFIG_SYS_NAND_ECCPOS \
|
||||
{12, 13, 14, 15, 16, 17, 18, 19,\
|
||||
20, 21, 22, 23, 24, 25, 26, 27, \
|
||||
|
@ -117,7 +113,6 @@
|
|||
#define CONFIG_SYS_NAND_OOBSIZE 128
|
||||
#define CONFIG_SYS_NAND_BASE 0xB8000000
|
||||
#define CONFIG_SYS_ONENAND_BASE CONFIG_SYS_NAND_BASE
|
||||
#define NAND_MAX_CHIPS 1
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define CONFIG_SYS_NAND_SELECT_DEVICE 1 /* nand driver supports mutipl.*/
|
||||
#define CONFIG_NAND_SPL_TEXT_BASE 0x80000000
|
||||
|
|
|
@ -205,9 +205,7 @@
|
|||
|
||||
#define CONFIG_SYS_NAND_ECCSIZE 256
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 3
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define CONFIG_SYS_NAND_OOBSIZE 16
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * CONFIG_SYS_NAND_ECCSTEPS)
|
||||
#define CONFIG_SYS_NAND_ECCPOS {0, 1, 2, 3, 6, 7}
|
||||
|
||||
#ifdef CONFIG_ENV_IS_IN_NAND
|
||||
|
|
|
@ -211,7 +211,6 @@
|
|||
#define CONFIG_NAND_S3C2410
|
||||
#define CONFIG_SYS_S3C2410_NAND_HWECC
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define NAND_MAX_CHIPS 1
|
||||
#define CONFIG_SYS_NAND_BASE 0x4E000000
|
||||
#endif
|
||||
|
||||
|
|
|
@ -262,12 +262,8 @@
|
|||
#define CONFIG_SYS_NAND_ECCSIZE CONFIG_SYS_NAND_PAGE_SIZE
|
||||
/* Number of ECC bytes per OOB - S3C6400 calculates 4 bytes ECC in 1-bit mode */
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 4
|
||||
/* Number of ECC-blocks per NAND page */
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / CONFIG_SYS_NAND_ECCSIZE)
|
||||
/* Size of a single OOB region */
|
||||
#define CONFIG_SYS_NAND_OOBSIZE 64
|
||||
/* Number of ECC bytes per page */
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * CONFIG_SYS_NAND_ECCSTEPS)
|
||||
/* ECC byte positions */
|
||||
#define CONFIG_SYS_NAND_ECCPOS {40, 41, 42, 43, 44, 45, 46, 47, \
|
||||
48, 49, 50, 51, 52, 53, 54, 55, \
|
||||
|
|
|
@ -278,11 +278,6 @@
|
|||
#define CONFIG_SYS_NAND_ECCSIZE 256
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 3
|
||||
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
|
||||
CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
|
||||
CONFIG_SYS_NAND_ECCSTEPS)
|
||||
|
||||
#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
|
||||
|
||||
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
|
||||
|
|
|
@ -90,7 +90,6 @@
|
|||
#define CONFIG_CMD_MTDPARTS
|
||||
#define CONFIG_MTD_DEVICE
|
||||
#define CONFIG_JFFS2_NAND
|
||||
#define NAND_MAX_CHIPS 1
|
||||
#define CONFIG_ENV_OFFSET 0x180000
|
||||
|
||||
/*
|
||||
|
|
|
@ -231,7 +231,6 @@
|
|||
|
||||
#define CONFIG_NAND_MXC
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define CONFIG_SYS_NAND_MAX_CHIPS 1
|
||||
|
||||
/*
|
||||
* actually this is nothing someone wants to configure!
|
||||
|
|
79
include/linux/bch.h
Normal file
79
include/linux/bch.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Generic binary BCH encoding/decoding library
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright © 2011 Parrot S.A.
|
||||
*
|
||||
* Author: Ivan Djelic <ivan.djelic@parrot.com>
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This library provides runtime configurable encoding/decoding of binary
|
||||
* Bose-Chaudhuri-Hocquenghem (BCH) codes.
|
||||
*/
|
||||
#ifndef _BCH_H
|
||||
#define _BCH_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/**
|
||||
* struct bch_control - BCH control structure
|
||||
* @m: Galois field order
|
||||
* @n: maximum codeword size in bits (= 2^m-1)
|
||||
* @t: error correction capability in bits
|
||||
* @ecc_bits: ecc exact size in bits, i.e. generator polynomial degree (<=m*t)
|
||||
* @ecc_bytes: ecc max size (m*t bits) in bytes
|
||||
* @a_pow_tab: Galois field GF(2^m) exponentiation lookup table
|
||||
* @a_log_tab: Galois field GF(2^m) log lookup table
|
||||
* @mod8_tab: remainder generator polynomial lookup tables
|
||||
* @ecc_buf: ecc parity words buffer
|
||||
* @ecc_buf2: ecc parity words buffer
|
||||
* @xi_tab: GF(2^m) base for solving degree 2 polynomial roots
|
||||
* @syn: syndrome buffer
|
||||
* @cache: log-based polynomial representation buffer
|
||||
* @elp: error locator polynomial
|
||||
* @poly_2t: temporary polynomials of degree 2t
|
||||
*/
|
||||
struct bch_control {
|
||||
unsigned int m;
|
||||
unsigned int n;
|
||||
unsigned int t;
|
||||
unsigned int ecc_bits;
|
||||
unsigned int ecc_bytes;
|
||||
/* private: */
|
||||
uint16_t *a_pow_tab;
|
||||
uint16_t *a_log_tab;
|
||||
uint32_t *mod8_tab;
|
||||
uint32_t *ecc_buf;
|
||||
uint32_t *ecc_buf2;
|
||||
unsigned int *xi_tab;
|
||||
unsigned int *syn;
|
||||
int *cache;
|
||||
struct gf_poly *elp;
|
||||
struct gf_poly *poly_2t[4];
|
||||
};
|
||||
|
||||
struct bch_control *init_bch(int m, int t, unsigned int prim_poly);
|
||||
|
||||
void free_bch(struct bch_control *bch);
|
||||
|
||||
void encode_bch(struct bch_control *bch, const uint8_t *data,
|
||||
unsigned int len, uint8_t *ecc);
|
||||
|
||||
int decode_bch(struct bch_control *bch, const uint8_t *data, unsigned int len,
|
||||
const uint8_t *recv_ecc, const uint8_t *calc_ecc,
|
||||
const unsigned int *syn, unsigned int *errloc);
|
||||
|
||||
#endif /* _BCH_H */
|
|
@ -11,8 +11,19 @@
|
|||
* Thomas Gleixner <tglx@linuxtronix.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
#ifndef __LINUX_MTD_BBM_H
|
||||
#define __LINUX_MTD_BBM_H
|
||||
|
@ -76,7 +87,7 @@ struct nand_bbt_descr {
|
|||
#define NAND_BBT_PERCHIP 0x00000080
|
||||
/* bbt has a version counter at offset veroffs */
|
||||
#define NAND_BBT_VERSION 0x00000100
|
||||
/* Create a bbt if none axists */
|
||||
/* Create a bbt if none exists */
|
||||
#define NAND_BBT_CREATE 0x00000200
|
||||
/* Search good / bad pattern through all pages of a block */
|
||||
#define NAND_BBT_SCANALLPAGES 0x00000400
|
||||
|
@ -88,6 +99,14 @@ struct nand_bbt_descr {
|
|||
#define NAND_BBT_SAVECONTENT 0x00002000
|
||||
/* Search good / bad pattern on the first and the second page */
|
||||
#define NAND_BBT_SCAN2NDPAGE 0x00004000
|
||||
/* Search good / bad pattern on the last page of the eraseblock */
|
||||
#define NAND_BBT_SCANLASTPAGE 0x00008000
|
||||
/* Chip stores bad block marker on BOTH 1st and 6th bytes of OOB */
|
||||
#define NAND_BBT_SCANBYTE1AND6 0x00100000
|
||||
/* The nand_bbt_descr was created dynamicaly and must be freed */
|
||||
#define NAND_BBT_DYNAMICSTRUCT 0x00200000
|
||||
/* The bad block table does not OOB for marker */
|
||||
#define NAND_BBT_NO_OOB 0x00400000
|
||||
|
||||
/* The maximum number of blocks to scan for a bbt */
|
||||
#define NAND_BBT_SCAN_MAXBLOCKS 4
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* linux/include/linux/mtd/nand.h
|
||||
*
|
||||
* Copyright (c) 2000 David Woodhouse <dwmw2@infradead.org>
|
||||
* Steven J. Hill <sjhill@realitydiluted.com>
|
||||
* Thomas Gleixner <tglx@linutronix.de>
|
||||
* Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org>
|
||||
* Steven J. Hill <sjhill@realitydiluted.com>
|
||||
* Thomas Gleixner <tglx@linutronix.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -18,13 +18,6 @@
|
|||
#ifndef __LINUX_MTD_NAND_H
|
||||
#define __LINUX_MTD_NAND_H
|
||||
|
||||
/* XXX U-BOOT XXX */
|
||||
#if 0
|
||||
#include <linux/wait.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "linux/mtd/compat.h"
|
||||
|
@ -43,17 +36,18 @@ extern int nand_scan_ident(struct mtd_info *mtd, int max_chips,
|
|||
extern int nand_scan_tail(struct mtd_info *mtd);
|
||||
|
||||
/* Free resources held by the NAND device */
|
||||
extern void nand_release (struct mtd_info *mtd);
|
||||
extern void nand_release(struct mtd_info *mtd);
|
||||
|
||||
/* Internal helper for board drivers which need to override command function */
|
||||
extern void nand_wait_ready(struct mtd_info *mtd);
|
||||
|
||||
/* This constant declares the max. oobsize / page, which
|
||||
/*
|
||||
* This constant declares the max. oobsize / page, which
|
||||
* is supported now. If you add a chip with bigger oobsize/page
|
||||
* adjust this accordingly.
|
||||
*/
|
||||
#define NAND_MAX_OOBSIZE 218
|
||||
#define NAND_MAX_PAGESIZE 4096
|
||||
#define NAND_MAX_OOBSIZE 576
|
||||
#define NAND_MAX_PAGESIZE 8192
|
||||
|
||||
/*
|
||||
* Constants for hardware specific CLE/ALE/NCE function
|
||||
|
@ -86,10 +80,14 @@ extern void nand_wait_ready(struct mtd_info *mtd);
|
|||
#define NAND_CMD_SEQIN 0x80
|
||||
#define NAND_CMD_RNDIN 0x85
|
||||
#define NAND_CMD_READID 0x90
|
||||
#define NAND_CMD_PARAM 0xec
|
||||
#define NAND_CMD_ERASE2 0xd0
|
||||
#define NAND_CMD_PARAM 0xec
|
||||
#define NAND_CMD_RESET 0xff
|
||||
|
||||
#define NAND_CMD_LOCK 0x2a
|
||||
#define NAND_CMD_UNLOCK1 0x23
|
||||
#define NAND_CMD_UNLOCK2 0x24
|
||||
|
||||
/* Extended commands for large page devices */
|
||||
#define NAND_CMD_READSTART 0x30
|
||||
#define NAND_CMD_RNDOUTSTART 0xE0
|
||||
|
@ -132,6 +130,7 @@ typedef enum {
|
|||
NAND_ECC_HW,
|
||||
NAND_ECC_HW_SYNDROME,
|
||||
NAND_ECC_HW_OOB_FIRST,
|
||||
NAND_ECC_SOFT_BCH,
|
||||
} nand_ecc_modes_t;
|
||||
|
||||
/*
|
||||
|
@ -148,9 +147,10 @@ typedef enum {
|
|||
#define NAND_GET_DEVICE 0x80
|
||||
|
||||
|
||||
/* Option constants for bizarre disfunctionality and real
|
||||
* features
|
||||
*/
|
||||
/*
|
||||
* Option constants for bizarre disfunctionality and real
|
||||
* features.
|
||||
*/
|
||||
/* Chip can not auto increment pages */
|
||||
#define NAND_NO_AUTOINCR 0x00000001
|
||||
/* Buswitdh is 16 bit */
|
||||
|
@ -161,23 +161,36 @@ typedef enum {
|
|||
#define NAND_CACHEPRG 0x00000008
|
||||
/* Chip has copy back function */
|
||||
#define NAND_COPYBACK 0x00000010
|
||||
/* AND Chip which has 4 banks and a confusing page / block
|
||||
* assignment. See Renesas datasheet for further information */
|
||||
/*
|
||||
* AND Chip which has 4 banks and a confusing page / block
|
||||
* assignment. See Renesas datasheet for further information.
|
||||
*/
|
||||
#define NAND_IS_AND 0x00000020
|
||||
/* Chip has a array of 4 pages which can be read without
|
||||
* additional ready /busy waits */
|
||||
/*
|
||||
* Chip has a array of 4 pages which can be read without
|
||||
* additional ready /busy waits.
|
||||
*/
|
||||
#define NAND_4PAGE_ARRAY 0x00000040
|
||||
/* Chip requires that BBT is periodically rewritten to prevent
|
||||
/*
|
||||
* Chip requires that BBT is periodically rewritten to prevent
|
||||
* bits from adjacent blocks from 'leaking' in altering data.
|
||||
* This happens with the Renesas AG-AND chips, possibly others. */
|
||||
* This happens with the Renesas AG-AND chips, possibly others.
|
||||
*/
|
||||
#define BBT_AUTO_REFRESH 0x00000080
|
||||
/* Chip does not require ready check on read. True
|
||||
/*
|
||||
* Chip does not require ready check on read. True
|
||||
* for all large page devices, as they do not support
|
||||
* autoincrement.*/
|
||||
* autoincrement.
|
||||
*/
|
||||
#define NAND_NO_READRDY 0x00000100
|
||||
/* Chip does not allow subpage writes */
|
||||
#define NAND_NO_SUBPAGE_WRITE 0x00000200
|
||||
|
||||
/* Device is one of 'new' xD cards that expose fake nand command set */
|
||||
#define NAND_BROKEN_XD 0x00000400
|
||||
|
||||
/* Device behaves just like nand, but is readonly */
|
||||
#define NAND_ROM 0x00000800
|
||||
|
||||
/* Options valid for Samsung large page devices */
|
||||
#define NAND_SAMSUNG_LP_OPTIONS \
|
||||
|
@ -196,17 +209,29 @@ typedef enum {
|
|||
#define NAND_CHIPOPTIONS_MSK (0x0000ffff & ~NAND_NO_AUTOINCR)
|
||||
|
||||
/* Non chip related options */
|
||||
/* Use a flash based bad block table. This option is passed to the
|
||||
* default bad block table function. */
|
||||
/*
|
||||
* Use a flash based bad block table. OOB identifier is saved in OOB area.
|
||||
* This option is passed to the default bad block table function.
|
||||
*/
|
||||
#define NAND_USE_FLASH_BBT 0x00010000
|
||||
/* This option skips the bbt scan during initialization. */
|
||||
#define NAND_SKIP_BBTSCAN 0x00020000
|
||||
/* This option is defined if the board driver allocates its own buffers
|
||||
(e.g. because it needs them DMA-coherent */
|
||||
/*
|
||||
* This option is defined if the board driver allocates its own buffers
|
||||
* (e.g. because it needs them DMA-coherent).
|
||||
*/
|
||||
#define NAND_OWN_BUFFERS 0x00040000
|
||||
/* Chip may not exist, so silence any errors in scan */
|
||||
#define NAND_SCAN_SILENT_NODEV 0x00080000
|
||||
/*
|
||||
* If passed additionally to NAND_USE_FLASH_BBT then BBT code will not touch
|
||||
* the OOB area.
|
||||
*/
|
||||
#define NAND_USE_FLASH_BBT_NO_OOB 0x00800000
|
||||
/* Create an empty BBT with no vendor information if the BBT is available */
|
||||
#define NAND_CREATE_EMPTY_BBT 0x01000000
|
||||
|
||||
/* Options set by nand scan */
|
||||
/* bbt has already been read */
|
||||
#define NAND_BBT_SCANNED 0x40000000
|
||||
/* Nand scan has allocated controller struct */
|
||||
#define NAND_CONTROLLER_ALLOC 0x80000000
|
||||
|
||||
|
@ -281,13 +306,13 @@ struct nand_onfi_params {
|
|||
|
||||
#define ONFI_CRC_BASE 0x4F4E
|
||||
|
||||
|
||||
/**
|
||||
* struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices
|
||||
* @lock: protection lock
|
||||
* @active: the mtd device which holds the controller currently
|
||||
* @wq: wait queue to sleep on if a NAND operation is in progress
|
||||
* used instead of the per chip wait queue when a hw controller is available
|
||||
* @wq: wait queue to sleep on if a NAND operation is in
|
||||
* progress used instead of the per chip wait queue
|
||||
* when a hw controller is available.
|
||||
*/
|
||||
struct nand_hw_control {
|
||||
/* XXX U-BOOT XXX */
|
||||
|
@ -308,56 +333,50 @@ struct nand_hw_control {
|
|||
* @prepad: padding information for syndrome based ecc generators
|
||||
* @postpad: padding information for syndrome based ecc generators
|
||||
* @layout: ECC layout control struct pointer
|
||||
* @priv: pointer to private ecc control data
|
||||
* @hwctl: function to control hardware ecc generator. Must only
|
||||
* be provided if an hardware ECC is available
|
||||
* @calculate: function for ecc calculation or readback from ecc hardware
|
||||
* @correct: function for ecc correction, matching to ecc generator (sw/hw)
|
||||
* @read_page_raw: function to read a raw page without ECC
|
||||
* @write_page_raw: function to write a raw page without ECC
|
||||
* @read_page: function to read a page according to the ecc generator requirements
|
||||
* @write_page: function to write a page according to the ecc generator requirements
|
||||
* @read_page: function to read a page according to the ecc generator
|
||||
* requirements.
|
||||
* @read_subpage: function to read parts of the page covered by ECC.
|
||||
* @write_page: function to write a page according to the ecc generator
|
||||
* requirements.
|
||||
* @read_oob: function to read chip OOB data
|
||||
* @write_oob: function to write chip OOB data
|
||||
*/
|
||||
struct nand_ecc_ctrl {
|
||||
nand_ecc_modes_t mode;
|
||||
int steps;
|
||||
int size;
|
||||
int bytes;
|
||||
int total;
|
||||
int prepad;
|
||||
int postpad;
|
||||
nand_ecc_modes_t mode;
|
||||
int steps;
|
||||
int size;
|
||||
int bytes;
|
||||
int total;
|
||||
int prepad;
|
||||
int postpad;
|
||||
struct nand_ecclayout *layout;
|
||||
void (*hwctl)(struct mtd_info *mtd, int mode);
|
||||
int (*calculate)(struct mtd_info *mtd,
|
||||
const uint8_t *dat,
|
||||
uint8_t *ecc_code);
|
||||
int (*correct)(struct mtd_info *mtd, uint8_t *dat,
|
||||
uint8_t *read_ecc,
|
||||
uint8_t *calc_ecc);
|
||||
int (*read_page_raw)(struct mtd_info *mtd,
|
||||
struct nand_chip *chip,
|
||||
uint8_t *buf, int page);
|
||||
void (*write_page_raw)(struct mtd_info *mtd,
|
||||
struct nand_chip *chip,
|
||||
const uint8_t *buf);
|
||||
int (*read_page)(struct mtd_info *mtd,
|
||||
struct nand_chip *chip,
|
||||
uint8_t *buf, int page);
|
||||
int (*read_subpage)(struct mtd_info *mtd,
|
||||
struct nand_chip *chip,
|
||||
uint32_t offs, uint32_t len,
|
||||
uint8_t *buf);
|
||||
void (*write_page)(struct mtd_info *mtd,
|
||||
struct nand_chip *chip,
|
||||
const uint8_t *buf);
|
||||
int (*read_oob)(struct mtd_info *mtd,
|
||||
struct nand_chip *chip,
|
||||
int page,
|
||||
int sndcmd);
|
||||
int (*write_oob)(struct mtd_info *mtd,
|
||||
struct nand_chip *chip,
|
||||
int page);
|
||||
void *priv;
|
||||
void (*hwctl)(struct mtd_info *mtd, int mode);
|
||||
int (*calculate)(struct mtd_info *mtd, const uint8_t *dat,
|
||||
uint8_t *ecc_code);
|
||||
int (*correct)(struct mtd_info *mtd, uint8_t *dat, uint8_t *read_ecc,
|
||||
uint8_t *calc_ecc);
|
||||
int (*read_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
uint8_t *buf, int page);
|
||||
void (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
const uint8_t *buf);
|
||||
int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
uint8_t *buf, int page);
|
||||
int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
uint32_t offs, uint32_t len, uint8_t *buf);
|
||||
void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
const uint8_t *buf);
|
||||
int (*read_oob)(struct mtd_info *mtd, struct nand_chip *chip, int page,
|
||||
int sndcmd);
|
||||
int (*write_oob)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
int page);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -377,125 +396,150 @@ struct nand_buffers {
|
|||
|
||||
/**
|
||||
* struct nand_chip - NAND Private Flash Chip Data
|
||||
* @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device
|
||||
* @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device
|
||||
* @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the
|
||||
* flash device
|
||||
* @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the
|
||||
* flash device.
|
||||
* @read_byte: [REPLACEABLE] read one byte from the chip
|
||||
* @read_word: [REPLACEABLE] read one word from the chip
|
||||
* @write_buf: [REPLACEABLE] write data from the buffer to the chip
|
||||
* @read_buf: [REPLACEABLE] read data from the chip into the buffer
|
||||
* @verify_buf: [REPLACEABLE] verify buffer contents against the chip data
|
||||
* @verify_buf: [REPLACEABLE] verify buffer contents against the chip
|
||||
* data.
|
||||
* @select_chip: [REPLACEABLE] select chip nr
|
||||
* @block_bad: [REPLACEABLE] check, if the block is bad
|
||||
* @block_markbad: [REPLACEABLE] mark the block bad
|
||||
* @cmd_ctrl: [BOARDSPECIFIC] hardwarespecific funtion for controlling
|
||||
* @cmd_ctrl: [BOARDSPECIFIC] hardwarespecific function for controlling
|
||||
* ALE/CLE/nCE. Also used to write command and address
|
||||
* @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line
|
||||
* If set to NULL no access to ready/busy is available and the ready/busy information
|
||||
* is read from the chip status register
|
||||
* @cmdfunc: [REPLACEABLE] hardwarespecific function for writing commands to the chip
|
||||
* @waitfunc: [REPLACEABLE] hardwarespecific function for wait on ready
|
||||
* @init_size: [BOARDSPECIFIC] hardwarespecific function for setting
|
||||
* mtd->oobsize, mtd->writesize and so on.
|
||||
* @id_data contains the 8 bytes values of NAND_CMD_READID.
|
||||
* Return with the bus width.
|
||||
* @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing
|
||||
* device ready/busy line. If set to NULL no access to
|
||||
* ready/busy is available and the ready/busy information
|
||||
* is read from the chip status register.
|
||||
* @cmdfunc: [REPLACEABLE] hardwarespecific function for writing
|
||||
* commands to the chip.
|
||||
* @waitfunc: [REPLACEABLE] hardwarespecific function for wait on
|
||||
* ready.
|
||||
* @ecc: [BOARDSPECIFIC] ecc control ctructure
|
||||
* @buffers: buffer structure for read/write
|
||||
* @hwcontrol: platform-specific hardware control structure
|
||||
* @ops: oob operation operands
|
||||
* @erase_cmd: [INTERN] erase command write function, selectable due to AND support
|
||||
* @erase_cmd: [INTERN] erase command write function, selectable due
|
||||
* to AND support.
|
||||
* @scan_bbt: [REPLACEABLE] function to scan bad block table
|
||||
* @chip_delay: [BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR)
|
||||
* @wq: [INTERN] wait queue to sleep on if a NAND operation is in progress
|
||||
* @chip_delay: [BOARDSPECIFIC] chip dependent delay for transferring
|
||||
* data from array to read regs (tR).
|
||||
* @state: [INTERN] the current state of the NAND device
|
||||
* @oob_poi: poison value buffer
|
||||
* @page_shift: [INTERN] number of address bits in a page (column address bits)
|
||||
* @page_shift: [INTERN] number of address bits in a page (column
|
||||
* address bits).
|
||||
* @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock
|
||||
* @bbt_erase_shift: [INTERN] number of address bits in a bbt entry
|
||||
* @chip_shift: [INTERN] number of address bits in one chip
|
||||
* @datbuf: [INTERN] internal buffer for one page + oob
|
||||
* @oobbuf: [INTERN] oob buffer for one eraseblock
|
||||
* @oobdirty: [INTERN] indicates that oob_buf must be reinitialized
|
||||
* @data_poi: [INTERN] pointer to a data buffer
|
||||
* @options: [BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about
|
||||
* special functionality. See the defines for further explanation
|
||||
* @badblockpos: [INTERN] position of the bad block marker in the oob area
|
||||
* @options: [BOARDSPECIFIC] various chip options. They can partly
|
||||
* be set to inform nand_scan about special functionality.
|
||||
* See the defines for further explanation.
|
||||
* @badblockpos: [INTERN] position of the bad block marker in the oob
|
||||
* area.
|
||||
* @badblockbits: [INTERN] number of bits to left-shift the bad block
|
||||
* number
|
||||
* @cellinfo: [INTERN] MLC/multichip data from chip ident
|
||||
* @numchips: [INTERN] number of physical chips
|
||||
* @chipsize: [INTERN] the size of one chip for multichip arrays
|
||||
* @pagemask: [INTERN] page number mask = number of (pages / chip) - 1
|
||||
* @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf
|
||||
* @pagebuf: [INTERN] holds the pagenumber which is currently in
|
||||
* data_buf.
|
||||
* @subpagesize: [INTERN] holds the subpagesize
|
||||
* @onfi_version: [INTERN] holds the chip ONFI version (BCD encoded),
|
||||
* non 0 if ONFI supported.
|
||||
* @onfi_params: [INTERN] holds the ONFI page parameter when ONFI is
|
||||
* supported, 0 otherwise.
|
||||
* @ecclayout: [REPLACEABLE] the default ecc placement scheme
|
||||
* @bbt: [INTERN] bad block table pointer
|
||||
* @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup
|
||||
* @bbt_td: [REPLACEABLE] bad block table descriptor for flash
|
||||
* lookup.
|
||||
* @bbt_md: [REPLACEABLE] bad block table mirror descriptor
|
||||
* @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan
|
||||
* @controller: [REPLACEABLE] a pointer to a hardware controller structure
|
||||
* which is shared among multiple independend devices
|
||||
* @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial
|
||||
* bad block scan.
|
||||
* @controller: [REPLACEABLE] a pointer to a hardware controller
|
||||
* structure which is shared among multiple independend
|
||||
* devices.
|
||||
* @priv: [OPTIONAL] pointer to private chip date
|
||||
* @errstat: [OPTIONAL] hardware specific function to perform additional error status checks
|
||||
* (determine if errors are correctable)
|
||||
* @errstat: [OPTIONAL] hardware specific function to perform
|
||||
* additional error status checks (determine if errors are
|
||||
* correctable).
|
||||
* @write_page: [REPLACEABLE] High-level page write function
|
||||
*/
|
||||
|
||||
struct nand_chip {
|
||||
void __iomem *IO_ADDR_R;
|
||||
void __iomem *IO_ADDR_W;
|
||||
void __iomem *IO_ADDR_R;
|
||||
void __iomem *IO_ADDR_W;
|
||||
|
||||
uint8_t (*read_byte)(struct mtd_info *mtd);
|
||||
u16 (*read_word)(struct mtd_info *mtd);
|
||||
void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
|
||||
void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
|
||||
int (*verify_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
|
||||
void (*select_chip)(struct mtd_info *mtd, int chip);
|
||||
int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
|
||||
int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
|
||||
void (*cmd_ctrl)(struct mtd_info *mtd, int dat,
|
||||
unsigned int ctrl);
|
||||
int (*dev_ready)(struct mtd_info *mtd);
|
||||
void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);
|
||||
int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);
|
||||
void (*erase_cmd)(struct mtd_info *mtd, int page);
|
||||
int (*scan_bbt)(struct mtd_info *mtd);
|
||||
int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
|
||||
int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
const uint8_t *buf, int page, int cached, int raw);
|
||||
uint8_t (*read_byte)(struct mtd_info *mtd);
|
||||
u16 (*read_word)(struct mtd_info *mtd);
|
||||
void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
|
||||
void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
|
||||
int (*verify_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
|
||||
void (*select_chip)(struct mtd_info *mtd, int chip);
|
||||
int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
|
||||
int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
|
||||
void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl);
|
||||
int (*init_size)(struct mtd_info *mtd, struct nand_chip *this,
|
||||
u8 *id_data);
|
||||
int (*dev_ready)(struct mtd_info *mtd);
|
||||
void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column,
|
||||
int page_addr);
|
||||
int(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);
|
||||
void (*erase_cmd)(struct mtd_info *mtd, int page);
|
||||
int (*scan_bbt)(struct mtd_info *mtd);
|
||||
int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state,
|
||||
int status, int page);
|
||||
int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
const uint8_t *buf, int page, int cached, int raw);
|
||||
|
||||
int chip_delay;
|
||||
unsigned int options;
|
||||
int chip_delay;
|
||||
unsigned int options;
|
||||
|
||||
int page_shift;
|
||||
int phys_erase_shift;
|
||||
int bbt_erase_shift;
|
||||
int chip_shift;
|
||||
int numchips;
|
||||
uint64_t chipsize;
|
||||
int pagemask;
|
||||
int pagebuf;
|
||||
int subpagesize;
|
||||
uint8_t cellinfo;
|
||||
int badblockpos;
|
||||
int onfi_version;
|
||||
int page_shift;
|
||||
int phys_erase_shift;
|
||||
int bbt_erase_shift;
|
||||
int chip_shift;
|
||||
int numchips;
|
||||
uint64_t chipsize;
|
||||
int pagemask;
|
||||
int pagebuf;
|
||||
int subpagesize;
|
||||
uint8_t cellinfo;
|
||||
int badblockpos;
|
||||
int badblockbits;
|
||||
|
||||
int onfi_version;
|
||||
#ifdef CONFIG_SYS_NAND_ONFI_DETECTION
|
||||
struct nand_onfi_params onfi_params;
|
||||
#endif
|
||||
|
||||
int state;
|
||||
int state;
|
||||
|
||||
uint8_t *oob_poi;
|
||||
struct nand_hw_control *controller;
|
||||
struct nand_ecclayout *ecclayout;
|
||||
uint8_t *oob_poi;
|
||||
struct nand_hw_control *controller;
|
||||
struct nand_ecclayout *ecclayout;
|
||||
|
||||
struct nand_ecc_ctrl ecc;
|
||||
struct nand_buffers *buffers;
|
||||
|
||||
struct nand_hw_control hwcontrol;
|
||||
|
||||
struct mtd_oob_ops ops;
|
||||
|
||||
uint8_t *bbt;
|
||||
struct nand_bbt_descr *bbt_td;
|
||||
struct nand_bbt_descr *bbt_md;
|
||||
uint8_t *bbt;
|
||||
struct nand_bbt_descr *bbt_td;
|
||||
struct nand_bbt_descr *bbt_md;
|
||||
|
||||
struct nand_bbt_descr *badblock_pattern;
|
||||
struct nand_bbt_descr *badblock_pattern;
|
||||
|
||||
void *priv;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -539,7 +583,7 @@ struct nand_flash_dev {
|
|||
*/
|
||||
struct nand_manufacturers {
|
||||
int id;
|
||||
char * name;
|
||||
char *name;
|
||||
};
|
||||
|
||||
extern const struct nand_flash_dev nand_flash_ids[];
|
||||
|
@ -552,7 +596,7 @@ extern int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt);
|
|||
extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
|
||||
int allowbbt);
|
||||
extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
size_t * retlen, uint8_t * buf);
|
||||
size_t *retlen, uint8_t *buf);
|
||||
|
||||
/*
|
||||
* Constants for oob configuration
|
||||
|
@ -573,17 +617,20 @@ extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
* @priv: hardware controller specific settings
|
||||
*/
|
||||
struct platform_nand_chip {
|
||||
int nr_chips;
|
||||
int chip_offset;
|
||||
int nr_partitions;
|
||||
struct mtd_partition *partitions;
|
||||
struct nand_ecclayout *ecclayout;
|
||||
int chip_delay;
|
||||
unsigned int options;
|
||||
const char **part_probe_types;
|
||||
void *priv;
|
||||
int nr_chips;
|
||||
int chip_offset;
|
||||
int nr_partitions;
|
||||
struct mtd_partition *partitions;
|
||||
struct nand_ecclayout *ecclayout;
|
||||
int chip_delay;
|
||||
unsigned int options;
|
||||
const char **part_probe_types;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/* Keep gcc happy */
|
||||
struct platform_device;
|
||||
|
||||
/**
|
||||
* struct platform_nand_ctrl - controller level device structure
|
||||
* @hwcontrol: platform specific hardware control structure
|
||||
|
@ -596,12 +643,11 @@ struct platform_nand_chip {
|
|||
* All fields are optional and depend on the hardware driver requirements
|
||||
*/
|
||||
struct platform_nand_ctrl {
|
||||
void (*hwcontrol)(struct mtd_info *mtd, int cmd);
|
||||
int (*dev_ready)(struct mtd_info *mtd);
|
||||
void (*select_chip)(struct mtd_info *mtd, int chip);
|
||||
void (*cmd_ctrl)(struct mtd_info *mtd, int dat,
|
||||
unsigned int ctrl);
|
||||
void *priv;
|
||||
void (*hwcontrol)(struct mtd_info *mtd, int cmd);
|
||||
int (*dev_ready)(struct mtd_info *mtd);
|
||||
void (*select_chip)(struct mtd_info *mtd, int chip);
|
||||
void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl);
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -610,8 +656,8 @@ struct platform_nand_ctrl {
|
|||
* @ctrl: controller level device structure
|
||||
*/
|
||||
struct platform_nand_data {
|
||||
struct platform_nand_chip chip;
|
||||
struct platform_nand_ctrl ctrl;
|
||||
struct platform_nand_chip chip;
|
||||
struct platform_nand_ctrl ctrl;
|
||||
};
|
||||
|
||||
/* Some helpers to access the data structures */
|
||||
|
|
72
include/linux/mtd/nand_bch.h
Normal file
72
include/linux/mtd/nand_bch.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright © 2011 Ivan Djelic <ivan.djelic@parrot.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This file is the header for the NAND BCH ECC implementation.
|
||||
*/
|
||||
|
||||
#ifndef __MTD_NAND_BCH_H__
|
||||
#define __MTD_NAND_BCH_H__
|
||||
|
||||
struct mtd_info;
|
||||
struct nand_bch_control;
|
||||
|
||||
#if defined(CONFIG_NAND_ECC_BCH)
|
||||
|
||||
static inline int mtd_nand_has_bch(void) { return 1; }
|
||||
|
||||
/*
|
||||
* Calculate BCH ecc code
|
||||
*/
|
||||
int nand_bch_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
|
||||
u_char *ecc_code);
|
||||
|
||||
/*
|
||||
* Detect and correct bit errors
|
||||
*/
|
||||
int nand_bch_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc,
|
||||
u_char *calc_ecc);
|
||||
/*
|
||||
* Initialize BCH encoder/decoder
|
||||
*/
|
||||
struct nand_bch_control *
|
||||
nand_bch_init(struct mtd_info *mtd, unsigned int eccsize,
|
||||
unsigned int eccbytes, struct nand_ecclayout **ecclayout);
|
||||
/*
|
||||
* Release BCH encoder/decoder resources
|
||||
*/
|
||||
void nand_bch_free(struct nand_bch_control *nbc);
|
||||
|
||||
#else /* !CONFIG_NAND_ECC_BCH */
|
||||
|
||||
static inline int mtd_nand_has_bch(void) { return 0; }
|
||||
|
||||
static inline int
|
||||
nand_bch_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
|
||||
u_char *ecc_code)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf,
|
||||
unsigned char *read_ecc, unsigned char *calc_ecc)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline struct nand_bch_control *
|
||||
nand_bch_init(struct mtd_info *mtd, unsigned int eccsize,
|
||||
unsigned int eccbytes, struct nand_ecclayout **ecclayout)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void nand_bch_free(struct nand_bch_control *nbc) {}
|
||||
|
||||
#endif /* CONFIG_NAND_ECC_BCH */
|
||||
|
||||
#endif /* __MTD_NAND_BCH_H__ */
|
|
@ -15,6 +15,10 @@
|
|||
|
||||
struct mtd_info;
|
||||
|
||||
#if defined(CONFIG_MTD_ECC_SOFT)
|
||||
|
||||
static inline int mtd_nand_has_ecc_soft(void) { return 1; }
|
||||
|
||||
/*
|
||||
* Calculate 3 byte ECC code for 256 byte block
|
||||
*/
|
||||
|
@ -25,4 +29,25 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
|
|||
*/
|
||||
int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
|
||||
|
||||
#else
|
||||
|
||||
static inline int mtd_nand_has_ecc_soft(void) { return 0; }
|
||||
|
||||
static inline int
|
||||
nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
nand_correct_data(struct mtd_info *mtd,
|
||||
u_char *dat,
|
||||
u_char *read_ecc,
|
||||
u_char *calc_ecc)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __MTD_NAND_ECC_H__ */
|
||||
|
|
|
@ -47,6 +47,10 @@ extern char * strchr(const char *,int);
|
|||
#ifndef __HAVE_ARCH_STRRCHR
|
||||
extern char * strrchr(const char *,int);
|
||||
#endif
|
||||
extern char * skip_spaces(const char *);
|
||||
|
||||
extern char *strim(char *);
|
||||
|
||||
#ifndef __HAVE_ARCH_STRSTR
|
||||
extern char * strstr(const char *,const char *);
|
||||
#endif
|
||||
|
|
|
@ -24,13 +24,29 @@
|
|||
#ifndef _NAND_H_
|
||||
#define _NAND_H_
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/*
|
||||
* All boards using a given driver must convert to self-init
|
||||
* at the same time, so do it here. When all drivers are
|
||||
* converted, this will go away.
|
||||
*/
|
||||
#if defined(CONFIG_NAND_FSL_ELBC)
|
||||
#define CONFIG_SYS_NAND_SELF_INIT
|
||||
#endif
|
||||
|
||||
extern void nand_init(void);
|
||||
|
||||
#include <linux/mtd/compat.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
|
||||
#ifdef CONFIG_SYS_NAND_SELF_INIT
|
||||
void board_nand_init(void);
|
||||
int nand_register(int devnum);
|
||||
#else
|
||||
extern int board_nand_init(struct nand_chip *nand);
|
||||
#endif
|
||||
|
||||
typedef struct mtd_info nand_info_t;
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ LIB = $(obj)libgeneric.o
|
|||
|
||||
ifndef CONFIG_SPL_BUILD
|
||||
COBJS-$(CONFIG_ADDR_MAP) += addr_map.o
|
||||
COBJS-$(CONFIG_BCH) += bch.o
|
||||
COBJS-$(CONFIG_BZIP2) += bzlib.o
|
||||
COBJS-$(CONFIG_BZIP2) += bzlib_crctable.o
|
||||
COBJS-$(CONFIG_BZIP2) += bzlib_decompress.o
|
||||
|
|
39
lib/string.c
39
lib/string.c
|
@ -214,6 +214,45 @@ char * strrchr(const char * s, int c)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* skip_spaces - Removes leading whitespace from @str.
|
||||
* @str: The string to be stripped.
|
||||
*
|
||||
* Returns a pointer to the first non-whitespace character in @str.
|
||||
*/
|
||||
char *skip_spaces(const char *str)
|
||||
{
|
||||
while (isspace(*str))
|
||||
++str;
|
||||
return (char *)str;
|
||||
}
|
||||
|
||||
/**
|
||||
* strim - Removes leading and trailing whitespace from @s.
|
||||
* @s: The string to be stripped.
|
||||
*
|
||||
* Note that the first trailing whitespace is replaced with a %NUL-terminator
|
||||
* in the given string @s. Returns a pointer to the first non-whitespace
|
||||
* character in @s.
|
||||
*/
|
||||
char *strim(char *s)
|
||||
{
|
||||
size_t size;
|
||||
char *end;
|
||||
|
||||
s = skip_spaces(s);
|
||||
size = strlen(s);
|
||||
if (!size)
|
||||
return s;
|
||||
|
||||
end = s + size - 1;
|
||||
while (end >= s && isspace(*end))
|
||||
end--;
|
||||
*(end + 1) = '\0';
|
||||
|
||||
return s;
|
||||
}
|
||||
#ifndef __HAVE_ARCH_STRLEN
|
||||
/**
|
||||
* strlen - Find the length of a string
|
||||
|
|
|
@ -24,6 +24,11 @@
|
|||
|
||||
static int nand_ecc_pos[] = CONFIG_SYS_NAND_ECCPOS;
|
||||
|
||||
#define ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
|
||||
CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define ECCTOTAL (ECCSTEPS * CONFIG_SYS_NAND_ECCBYTES)
|
||||
|
||||
|
||||
#if (CONFIG_SYS_NAND_PAGE_SIZE <= 512)
|
||||
/*
|
||||
* NAND command for small page NAND devices (512)
|
||||
|
@ -139,29 +144,21 @@ static int nand_is_bad_block(struct mtd_info *mtd, int block)
|
|||
static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
|
||||
{
|
||||
struct nand_chip *this = mtd->priv;
|
||||
u_char *ecc_calc;
|
||||
u_char *ecc_code;
|
||||
u_char *oob_data;
|
||||
u_char ecc_calc[ECCTOTAL];
|
||||
u_char ecc_code[ECCTOTAL];
|
||||
u_char oob_data[CONFIG_SYS_NAND_OOBSIZE];
|
||||
int i;
|
||||
int eccsize = CONFIG_SYS_NAND_ECCSIZE;
|
||||
int eccbytes = CONFIG_SYS_NAND_ECCBYTES;
|
||||
int eccsteps = CONFIG_SYS_NAND_ECCSTEPS;
|
||||
int eccsteps = ECCSTEPS;
|
||||
uint8_t *p = dst;
|
||||
|
||||
/*
|
||||
* No malloc available for now, just use some temporary locations
|
||||
* in SDRAM
|
||||
*/
|
||||
ecc_calc = (u_char *)(CONFIG_SYS_SDRAM_BASE + 0x10000);
|
||||
ecc_code = ecc_calc + 0x100;
|
||||
oob_data = ecc_calc + 0x200;
|
||||
|
||||
nand_command(mtd, block, page, 0, NAND_CMD_READOOB);
|
||||
this->read_buf(mtd, oob_data, CONFIG_SYS_NAND_OOBSIZE);
|
||||
nand_command(mtd, block, page, 0, NAND_CMD_READ0);
|
||||
|
||||
/* Pick the ECC bytes out of the oob data */
|
||||
for (i = 0; i < CONFIG_SYS_NAND_ECCTOTAL; i++)
|
||||
for (i = 0; i < ECCTOTAL; i++)
|
||||
ecc_code[i] = oob_data[nand_ecc_pos[i]];
|
||||
|
||||
|
||||
|
@ -178,24 +175,17 @@ static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
|
|||
static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
|
||||
{
|
||||
struct nand_chip *this = mtd->priv;
|
||||
u_char *ecc_calc;
|
||||
u_char *ecc_code;
|
||||
u_char *oob_data;
|
||||
u_char ecc_calc[ECCTOTAL];
|
||||
u_char ecc_code[ECCTOTAL];
|
||||
u_char oob_data[CONFIG_SYS_NAND_OOBSIZE];
|
||||
int i;
|
||||
int eccsize = CONFIG_SYS_NAND_ECCSIZE;
|
||||
int eccbytes = CONFIG_SYS_NAND_ECCBYTES;
|
||||
int eccsteps = CONFIG_SYS_NAND_ECCSTEPS;
|
||||
int eccsteps = ECCSTEPS;
|
||||
uint8_t *p = dst;
|
||||
|
||||
nand_command(mtd, block, page, 0, NAND_CMD_READ0);
|
||||
|
||||
/* No malloc available for now, just use some temporary locations
|
||||
* in SDRAM
|
||||
*/
|
||||
ecc_calc = (u_char *)(CONFIG_SYS_SDRAM_BASE + 0x10000);
|
||||
ecc_code = ecc_calc + 0x100;
|
||||
oob_data = ecc_calc + 0x200;
|
||||
|
||||
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
|
||||
this->ecc.hwctl(mtd, NAND_ECC_READ);
|
||||
this->read_buf(mtd, p, eccsize);
|
||||
|
@ -204,10 +194,10 @@ static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
|
|||
this->read_buf(mtd, oob_data, CONFIG_SYS_NAND_OOBSIZE);
|
||||
|
||||
/* Pick the ECC bytes out of the oob data */
|
||||
for (i = 0; i < CONFIG_SYS_NAND_ECCTOTAL; i++)
|
||||
for (i = 0; i < ECCTOTAL; i++)
|
||||
ecc_code[i] = oob_data[nand_ecc_pos[i]];
|
||||
|
||||
eccsteps = CONFIG_SYS_NAND_ECCSTEPS;
|
||||
eccsteps = ECCSTEPS;
|
||||
p = dst;
|
||||
|
||||
for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
|
||||
|
|
Loading…
Reference in a new issue