mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-04-02 20:41:31 +00:00
Merge branch 'master' of git://git.denx.de/u-boot-nand-flash
This commit is contained in:
commit
ef184040b7
2 changed files with 62 additions and 48 deletions
|
@ -315,7 +315,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t start, size_t length,
|
||||||
int page;
|
int page;
|
||||||
struct nand_chip *chip = mtd->priv;
|
struct nand_chip *chip = mtd->priv;
|
||||||
|
|
||||||
debug("nand_unlock%s: start: %08llx, length: %d!\n",
|
debug("nand_unlock%s: start: %08llx, length: %zd!\n",
|
||||||
allexcept ? " (allexcept)" : "", start, length);
|
allexcept ? " (allexcept)" : "", start, length);
|
||||||
|
|
||||||
/* select the NAND device */
|
/* select the NAND device */
|
||||||
|
|
|
@ -283,53 +283,55 @@ static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode)
|
||||||
if (bch->ecc_scheme == OMAP_ECC_BCH8_CODE_HW) {
|
if (bch->ecc_scheme == OMAP_ECC_BCH8_CODE_HW) {
|
||||||
wr_mode = BCH_WRAPMODE_1;
|
wr_mode = BCH_WRAPMODE_1;
|
||||||
|
|
||||||
switch (bch->nibbles) {
|
switch (bch->nibbles) {
|
||||||
case ECC_BCH4_NIBBLES:
|
case ECC_BCH4_NIBBLES:
|
||||||
unused_length = 3;
|
unused_length = 3;
|
||||||
break;
|
break;
|
||||||
case ECC_BCH8_NIBBLES:
|
case ECC_BCH8_NIBBLES:
|
||||||
unused_length = 2;
|
unused_length = 2;
|
||||||
break;
|
break;
|
||||||
case ECC_BCH16_NIBBLES:
|
case ECC_BCH16_NIBBLES:
|
||||||
unused_length = 0;
|
unused_length = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This is ecc_size_config for ELM mode.
|
|
||||||
* Here we are using different settings for read and write access and
|
|
||||||
* also depending on BCH strength.
|
|
||||||
*/
|
|
||||||
switch (mode) {
|
|
||||||
case NAND_ECC_WRITE:
|
|
||||||
/* write access only setup eccsize1 config */
|
|
||||||
val = ((unused_length + bch->nibbles) << 22);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NAND_ECC_READ:
|
|
||||||
default:
|
|
||||||
/*
|
/*
|
||||||
* by default eccsize0 selected for ecc1resultsize
|
* This is ecc_size_config for ELM mode. Here we are using
|
||||||
* eccsize0 config.
|
* different settings for read and write access and also
|
||||||
|
* depending on BCH strength.
|
||||||
*/
|
*/
|
||||||
val = (bch->nibbles << 12);
|
switch (mode) {
|
||||||
/* eccsize1 config */
|
case NAND_ECC_WRITE:
|
||||||
val |= (unused_length << 22);
|
/* write access only setup eccsize1 config */
|
||||||
break;
|
val = ((unused_length + bch->nibbles) << 22);
|
||||||
}
|
break;
|
||||||
|
|
||||||
|
case NAND_ECC_READ:
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* by default eccsize0 selected for ecc1resultsize
|
||||||
|
* eccsize0 config.
|
||||||
|
*/
|
||||||
|
val = (bch->nibbles << 12);
|
||||||
|
/* eccsize1 config */
|
||||||
|
val |= (unused_length << 22);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* This ecc_size_config setting is for BCH sw library.
|
* This ecc_size_config setting is for BCH sw library.
|
||||||
*
|
*
|
||||||
* Note: we only support BCH8 currently with BCH sw library!
|
* Note: we only support BCH8 currently with BCH sw library!
|
||||||
* Should be really easy to adobt to BCH4, however some omap3 have
|
* Should be really easy to adobt to BCH4, however some omap3
|
||||||
* flaws with BCH4.
|
* have flaws with BCH4.
|
||||||
*
|
*
|
||||||
* Here we are using wrapping mode 6 both for reading and writing, with:
|
* Here we are using wrapping mode 6 both for reading and
|
||||||
* size0 = 0 (no additional protected byte in spare area)
|
* writing, with:
|
||||||
* size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)
|
* size0 = 0 (no additional protected byte in spare area)
|
||||||
*/
|
* size1 = 32 (skip 32 nibbles = 16 bytes per sector in
|
||||||
val = (32 << 22) | (0 << 12);
|
* spare area)
|
||||||
|
*/
|
||||||
|
val = (32 << 22) | (0 << 12);
|
||||||
}
|
}
|
||||||
/* ecc size configuration */
|
/* ecc size configuration */
|
||||||
writel(val, &gpmc_cfg->ecc_size_config);
|
writel(val, &gpmc_cfg->ecc_size_config);
|
||||||
|
@ -761,7 +763,7 @@ static void __maybe_unused omap_free_bch(struct mtd_info *mtd)
|
||||||
static int omap_select_ecc_scheme(struct nand_chip *nand,
|
static int omap_select_ecc_scheme(struct nand_chip *nand,
|
||||||
enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) {
|
enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) {
|
||||||
struct nand_bch_priv *bch = nand->priv;
|
struct nand_bch_priv *bch = nand->priv;
|
||||||
struct nand_ecclayout *ecclayout = nand->ecc.layout;
|
struct nand_ecclayout *ecclayout = &omap_ecclayout;
|
||||||
int eccsteps = pagesize / SECTOR_BYTES;
|
int eccsteps = pagesize / SECTOR_BYTES;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -774,7 +776,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
|
||||||
bch_priv.type = 0;
|
bch_priv.type = 0;
|
||||||
nand->ecc.mode = NAND_ECC_SOFT;
|
nand->ecc.mode = NAND_ECC_SOFT;
|
||||||
nand->ecc.layout = NULL;
|
nand->ecc.layout = NULL;
|
||||||
nand->ecc.size = pagesize;
|
nand->ecc.size = 0;
|
||||||
bch->ecc_scheme = OMAP_ECC_HAM1_CODE_SW;
|
bch->ecc_scheme = OMAP_ECC_HAM1_CODE_SW;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -789,6 +791,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
|
||||||
bch_priv.control = NULL;
|
bch_priv.control = NULL;
|
||||||
bch_priv.type = 0;
|
bch_priv.type = 0;
|
||||||
/* populate ecc specific fields */
|
/* populate ecc specific fields */
|
||||||
|
memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
|
||||||
nand->ecc.mode = NAND_ECC_HW;
|
nand->ecc.mode = NAND_ECC_HW;
|
||||||
nand->ecc.strength = 1;
|
nand->ecc.strength = 1;
|
||||||
nand->ecc.size = SECTOR_BYTES;
|
nand->ecc.size = SECTOR_BYTES;
|
||||||
|
@ -798,8 +801,12 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
|
||||||
nand->ecc.calculate = omap_calculate_ecc;
|
nand->ecc.calculate = omap_calculate_ecc;
|
||||||
/* define ecc-layout */
|
/* define ecc-layout */
|
||||||
ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
|
ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
|
||||||
for (i = 0; i < ecclayout->eccbytes; i++)
|
for (i = 0; i < ecclayout->eccbytes; i++) {
|
||||||
ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
|
if (nand->options & NAND_BUSWIDTH_16)
|
||||||
|
ecclayout->eccpos[i] = i + 2;
|
||||||
|
else
|
||||||
|
ecclayout->eccpos[i] = i + 1;
|
||||||
|
}
|
||||||
ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
|
ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
|
||||||
ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
|
ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
|
||||||
BADBLOCK_MARKER_LENGTH;
|
BADBLOCK_MARKER_LENGTH;
|
||||||
|
@ -823,6 +830,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
|
||||||
}
|
}
|
||||||
bch_priv.type = ECC_BCH8;
|
bch_priv.type = ECC_BCH8;
|
||||||
/* populate ecc specific fields */
|
/* populate ecc specific fields */
|
||||||
|
memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
|
||||||
nand->ecc.mode = NAND_ECC_HW;
|
nand->ecc.mode = NAND_ECC_HW;
|
||||||
nand->ecc.strength = 8;
|
nand->ecc.strength = 8;
|
||||||
nand->ecc.size = SECTOR_BYTES;
|
nand->ecc.size = SECTOR_BYTES;
|
||||||
|
@ -865,6 +873,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
|
||||||
elm_init();
|
elm_init();
|
||||||
bch_priv.type = ECC_BCH8;
|
bch_priv.type = ECC_BCH8;
|
||||||
/* populate ecc specific fields */
|
/* populate ecc specific fields */
|
||||||
|
memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
|
||||||
nand->ecc.mode = NAND_ECC_HW;
|
nand->ecc.mode = NAND_ECC_HW;
|
||||||
nand->ecc.strength = 8;
|
nand->ecc.strength = 8;
|
||||||
nand->ecc.size = SECTOR_BYTES;
|
nand->ecc.size = SECTOR_BYTES;
|
||||||
|
@ -891,6 +900,11 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
|
||||||
debug("nand: error: ecc scheme not enabled or supported\n");
|
debug("nand: error: ecc scheme not enabled or supported\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* nand_scan_tail() sets ham1 sw ecc; hw ecc layout is set by driver */
|
||||||
|
if (ecc_scheme != OMAP_ECC_HAM1_CODE_SW)
|
||||||
|
nand->ecc.layout = ecclayout;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue