NAND fixes:
- Add a quirk for a bunch of broken Macronix chips - Fix nand_block_bad() when chip->ecc.read_oob() returns a positive value encoding the number of bitflips - Fix OOB handling in the MXC driver fo V2.1 controllers - Flag the ONFI_FEATURE_ON_DIE_ECC as supported in the Micron driver - Hardcode clk rate in the denali_dt driver to address a bad DT representation (the proper fix will be queued for 4.19) SPI NOR fixes: - Add an ULL constant to some ID definitions so that the ID is not truncated on 32-bit platforms MTD fixes: - Fix the sector unlocking logic in the CFI driver -----BEGIN PGP SIGNATURE----- iQI5BAABCAAjBQJbNJHjHBxib3Jpcy5icmV6aWxsb25AYm9vdGxpbi5jb20ACgkQ Ze02AX4ItwBEFBAAw65L3Su2REWkqWe0x2lfT/OB61CUd7NlLLifjjxWj6ysRrlO BiomFoeXITlDPNMWLMYygzm7e8Lf2+Nb59pM4aMS/V+Yech6HD6j8qld7IJrz7/U YBRUNTKTfkc1jI2KothXWWLcltAtS0XzADTs+Lxn5BZ0a4idFay/iqeB/wDIwZ/T dQi08OrlbZ/H3ggLN7PoCK+vRnamjpnLecYdkHSMNP/T0msKPT6UJxZaoTZURBlq qeI6rClcwFlfjYFV70UchgjeD++rhE1cy14jO38dodbpPl3qoRiqsFi3kFHjn+a1 b+nJXIQWL5U1NzWiVNwxQHpoeRHU39Cpg1VxMcAjtkHJxnHKZ9C+dkYZXYAmchfv QYD0cd7KlmYgHNBjYKlUeBdS/X1qnTYx7su/69YavxgPzscaFuOHS8AgctvmJJhc dMxDJR29lgtKOOB+AsNo+8wRtZpEef3pE/s14QZmR7/71tIAxBVVlakWCH3ND3NJ 7lTL8BT8bAp0v2EcEMghyc71ryT0gCZdSHMOvJ/bQadnB//LTT9aXkDW2IdRHfQ0 DyBtnHlZxudYLZJ/uIB8zsoYY852rYYFaJ/H5gUafQdZ+8NWT7zYdlizXtzGxcEF Eq8CxDdbKmVSwpic/Nfl5i5T7zs9BOST3UkG/yiimx9X+GlSAGTRaKv7JIw= =BjBU -----END PGP SIGNATURE----- Merge tag 'mtd/fixes-for-4.18-rc3' of git://git.infradead.org/linux-mtd Pull mtd fixes from Boris Brezillon: "NAND fixes: - add a quirk for a bunch of broken Macronix chips - fix nand_block_bad() when chip->ecc.read_oob() returns a positive value encoding the number of bitflips - fix OOB handling in the MXC driver fo V2.1 controllers - flag the ONFI_FEATURE_ON_DIE_ECC as supported in the Micron driver - hardcode clk rate in the denali_dt driver to address a bad DT representation (the proper fix will be queued for 4.19) SPI NOR fixes: - add an ULL constant to some ID definitions so that the ID is not truncated on 32-bit platforms MTD fixes: - fix the sector unlocking logic in the CFI driver" * tag 'mtd/fixes-for-4.18-rc3' of git://git.infradead.org/linux-mtd: mtd: rawnand: denali_dt: set clk_x_rate to 200 MHz unconditionally mtd: dataflash: Use ULL suffix for 64-bit constants mtd: cfi_cmdset_0002: Avoid walking all chips when unlocking. mtd: cfi_cmdset_0002: Fix unlocking requests crossing a chip boudary mtd: cfi_cmdset_0002: fix SEGV unlocking multiple chips mtd: cfi_cmdset_0002: Use right chip in do_ppb_xxlock() mtd: rawnand: All AC chips have a broken GET_FEATURES(TIMINGS). mtd: rawnand: fix return value check for bad block status mtd: rawnand: mxc: set spare area size register explicitly mtd: rawnand: micron: add ONFI_FEATURE_ON_DIE_ECC to supported features
This commit is contained in:
commit
c7e1d692ea
|
@ -2526,7 +2526,7 @@ static int cfi_atmel_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
|||
|
||||
struct ppb_lock {
|
||||
struct flchip *chip;
|
||||
loff_t offset;
|
||||
unsigned long adr;
|
||||
int locked;
|
||||
};
|
||||
|
||||
|
@ -2544,8 +2544,9 @@ static int __maybe_unused do_ppb_xxlock(struct map_info *map,
|
|||
unsigned long timeo;
|
||||
int ret;
|
||||
|
||||
adr += chip->start;
|
||||
mutex_lock(&chip->mutex);
|
||||
ret = get_chip(map, chip, adr + chip->start, FL_LOCKING);
|
||||
ret = get_chip(map, chip, adr, FL_LOCKING);
|
||||
if (ret) {
|
||||
mutex_unlock(&chip->mutex);
|
||||
return ret;
|
||||
|
@ -2563,8 +2564,8 @@ static int __maybe_unused do_ppb_xxlock(struct map_info *map,
|
|||
|
||||
if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) {
|
||||
chip->state = FL_LOCKING;
|
||||
map_write(map, CMD(0xA0), chip->start + adr);
|
||||
map_write(map, CMD(0x00), chip->start + adr);
|
||||
map_write(map, CMD(0xA0), adr);
|
||||
map_write(map, CMD(0x00), adr);
|
||||
} else if (thunk == DO_XXLOCK_ONEBLOCK_UNLOCK) {
|
||||
/*
|
||||
* Unlocking of one specific sector is not supported, so we
|
||||
|
@ -2602,7 +2603,7 @@ static int __maybe_unused do_ppb_xxlock(struct map_info *map,
|
|||
map_write(map, CMD(0x00), chip->start);
|
||||
|
||||
chip->state = FL_READY;
|
||||
put_chip(map, chip, adr + chip->start);
|
||||
put_chip(map, chip, adr);
|
||||
mutex_unlock(&chip->mutex);
|
||||
|
||||
return ret;
|
||||
|
@ -2659,9 +2660,9 @@ static int __maybe_unused cfi_ppb_unlock(struct mtd_info *mtd, loff_t ofs,
|
|||
* sectors shall be unlocked, so lets keep their locking
|
||||
* status at "unlocked" (locked=0) for the final re-locking.
|
||||
*/
|
||||
if ((adr < ofs) || (adr >= (ofs + len))) {
|
||||
if ((offset < ofs) || (offset >= (ofs + len))) {
|
||||
sect[sectors].chip = &cfi->chips[chipnum];
|
||||
sect[sectors].offset = offset;
|
||||
sect[sectors].adr = adr;
|
||||
sect[sectors].locked = do_ppb_xxlock(
|
||||
map, &cfi->chips[chipnum], adr, 0,
|
||||
DO_XXLOCK_ONEBLOCK_GETLOCK);
|
||||
|
@ -2675,6 +2676,8 @@ static int __maybe_unused cfi_ppb_unlock(struct mtd_info *mtd, loff_t ofs,
|
|||
i++;
|
||||
|
||||
if (adr >> cfi->chipshift) {
|
||||
if (offset >= (ofs + len))
|
||||
break;
|
||||
adr = 0;
|
||||
chipnum++;
|
||||
|
||||
|
@ -2705,7 +2708,7 @@ static int __maybe_unused cfi_ppb_unlock(struct mtd_info *mtd, loff_t ofs,
|
|||
*/
|
||||
for (i = 0; i < sectors; i++) {
|
||||
if (sect[i].locked)
|
||||
do_ppb_xxlock(map, sect[i].chip, sect[i].offset, 0,
|
||||
do_ppb_xxlock(map, sect[i].chip, sect[i].adr, 0,
|
||||
DO_XXLOCK_ONEBLOCK_LOCK);
|
||||
}
|
||||
|
||||
|
|
|
@ -733,8 +733,8 @@ static struct flash_info dataflash_data[] = {
|
|||
{ "AT45DB642x", 0x1f2800, 8192, 1056, 11, SUP_POW2PS},
|
||||
{ "at45db642d", 0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS},
|
||||
|
||||
{ "AT45DB641E", 0x1f28000100, 32768, 264, 9, SUP_EXTID | SUP_POW2PS},
|
||||
{ "at45db641e", 0x1f28000100, 32768, 256, 8, SUP_EXTID | SUP_POW2PS | IS_POW2PS},
|
||||
{ "AT45DB641E", 0x1f28000100ULL, 32768, 264, 9, SUP_EXTID | SUP_POW2PS},
|
||||
{ "at45db641e", 0x1f28000100ULL, 32768, 256, 8, SUP_EXTID | SUP_POW2PS | IS_POW2PS},
|
||||
};
|
||||
|
||||
static struct flash_info *jedec_lookup(struct spi_device *spi,
|
||||
|
|
|
@ -123,7 +123,11 @@ static int denali_dt_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
denali->clk_x_rate = clk_get_rate(dt->clk);
|
||||
/*
|
||||
* Hardcode the clock rate for the backward compatibility.
|
||||
* This works for both SOCFPGA and UniPhier.
|
||||
*/
|
||||
denali->clk_x_rate = 200000000;
|
||||
|
||||
ret = denali_init(denali);
|
||||
if (ret)
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#define NFC_V1_V2_CONFIG (host->regs + 0x0a)
|
||||
#define NFC_V1_V2_ECC_STATUS_RESULT (host->regs + 0x0c)
|
||||
#define NFC_V1_V2_RSLTMAIN_AREA (host->regs + 0x0e)
|
||||
#define NFC_V1_V2_RSLTSPARE_AREA (host->regs + 0x10)
|
||||
#define NFC_V21_RSLTSPARE_AREA (host->regs + 0x10)
|
||||
#define NFC_V1_V2_WRPROT (host->regs + 0x12)
|
||||
#define NFC_V1_UNLOCKSTART_BLKADDR (host->regs + 0x14)
|
||||
#define NFC_V1_UNLOCKEND_BLKADDR (host->regs + 0x16)
|
||||
|
@ -1274,6 +1274,9 @@ static void preset_v2(struct mtd_info *mtd)
|
|||
writew(config1, NFC_V1_V2_CONFIG1);
|
||||
/* preset operation */
|
||||
|
||||
/* spare area size in 16-bit half-words */
|
||||
writew(mtd->oobsize / 2, NFC_V21_RSLTSPARE_AREA);
|
||||
|
||||
/* Unlock the internal RAM Buffer */
|
||||
writew(0x2, NFC_V1_V2_CONFIG);
|
||||
|
||||
|
|
|
@ -440,7 +440,7 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs)
|
|||
|
||||
for (; page < page_end; page++) {
|
||||
res = chip->ecc.read_oob(mtd, chip, page);
|
||||
if (res)
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
bad = chip->oob_poi[chip->badblockpos];
|
||||
|
|
|
@ -17,23 +17,47 @@
|
|||
|
||||
#include <linux/mtd/rawnand.h>
|
||||
|
||||
/*
|
||||
* Macronix AC series does not support using SET/GET_FEATURES to change
|
||||
* the timings unlike what is declared in the parameter page. Unflag
|
||||
* this feature to avoid unnecessary downturns.
|
||||
*/
|
||||
static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip)
|
||||
{
|
||||
unsigned int i;
|
||||
static const char * const broken_get_timings[] = {
|
||||
"MX30LF1G18AC",
|
||||
"MX30LF1G28AC",
|
||||
"MX30LF2G18AC",
|
||||
"MX30LF2G28AC",
|
||||
"MX30LF4G18AC",
|
||||
"MX30LF4G28AC",
|
||||
"MX60LF8G18AC",
|
||||
};
|
||||
|
||||
if (!chip->parameters.supports_set_get_features)
|
||||
return;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(broken_get_timings); i++) {
|
||||
if (!strcmp(broken_get_timings[i], chip->parameters.model))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(broken_get_timings))
|
||||
return;
|
||||
|
||||
bitmap_clear(chip->parameters.get_feature_list,
|
||||
ONFI_FEATURE_ADDR_TIMING_MODE, 1);
|
||||
bitmap_clear(chip->parameters.set_feature_list,
|
||||
ONFI_FEATURE_ADDR_TIMING_MODE, 1);
|
||||
}
|
||||
|
||||
static int macronix_nand_init(struct nand_chip *chip)
|
||||
{
|
||||
if (nand_is_slc(chip))
|
||||
chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
|
||||
|
||||
/*
|
||||
* MX30LF2G18AC chip does not support using SET/GET_FEATURES to change
|
||||
* the timings unlike what is declared in the parameter page. Unflag
|
||||
* this feature to avoid unnecessary downturns.
|
||||
*/
|
||||
if (chip->parameters.supports_set_get_features &&
|
||||
!strcmp("MX30LF2G18AC", chip->parameters.model)) {
|
||||
bitmap_clear(chip->parameters.get_feature_list,
|
||||
ONFI_FEATURE_ADDR_TIMING_MODE, 1);
|
||||
bitmap_clear(chip->parameters.set_feature_list,
|
||||
ONFI_FEATURE_ADDR_TIMING_MODE, 1);
|
||||
}
|
||||
macronix_nand_fix_broken_get_timings(chip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -66,7 +66,9 @@ static int micron_nand_onfi_init(struct nand_chip *chip)
|
|||
|
||||
if (p->supports_set_get_features) {
|
||||
set_bit(ONFI_FEATURE_ADDR_READ_RETRY, p->set_feature_list);
|
||||
set_bit(ONFI_FEATURE_ON_DIE_ECC, p->set_feature_list);
|
||||
set_bit(ONFI_FEATURE_ADDR_READ_RETRY, p->get_feature_list);
|
||||
set_bit(ONFI_FEATURE_ON_DIE_ECC, p->get_feature_list);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue