A Rockchip NAND Flash Controller (NFC) supports multiple
flash devices. The SoC boot ROM only checks for NAND chip 0
and with reduced ECC strength. Currently only the read page
functions have this condition check added in the U-Boot
driver.
The rk_nfc_write_page_hwecc function together with a wrongly
placed rockchip,boot-blks property writes these blocks at
any NAND with reduced strength. The rk_nfc_read_page_hwecc
function however does this only for chip 0. Resulting in a
a ECC strength mismatch between what's written and read for
U-Boot applications.
rockchip,boot-blks and rockchip,boot-ecc-strength properties
require the nand-is-boot-medium property to be set in the Linux
driver. When the nand-is-boot-medium property is omitted or accidently
placed in an other NAND node with the required properties than for
chip 0 there is a ECC strength mismatch between what's written
and read between Linux and U-Boot.
Fix by adding the same condition to all read and write page
functions by dropping the existing 'selected_bank == 0' check
and use the NAND_IS_BOOT_MEDIUM option that was introduced to
U-Boot more recently than this driver to behave
identically to the Linux driver.
Fixes: b12dc5d6fa76 ("mtd: nand: NFC drivers for RK3308, RK2928 and others")
Signed-off-by: Johan Jonker <[email protected]>
Tested-by: Hüseyin BIYIK <[email protected]>
Reviewed-by: Simon Glass <[email protected]>
---
Changed V3: (Quentin)
reorder the condition
remove redundant sentence
providing the use case and misbehavior
Changed V2: (Simon)
fix typos
reword
---
drivers/mtd/nand/raw/rockchip_nfc.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/mtd/nand/raw/rockchip_nfc.c
b/drivers/mtd/nand/raw/rockchip_nfc.c
index ea8e67d1a23e..d23a651f3692 100644
--- a/drivers/mtd/nand/raw/rockchip_nfc.c
+++ b/drivers/mtd/nand/raw/rockchip_nfc.c
@@ -440,7 +440,8 @@ static int rk_nfc_write_page_raw(struct mtd_info *mtd,
int i, pages_per_blk;
pages_per_blk = mtd->erasesize / mtd->writesize;
- if ((page < (pages_per_blk * rknand->boot_blks)) &&
+ if ((chip->options & NAND_IS_BOOT_MEDIUM) &&
+ (page < (pages_per_blk * rknand->boot_blks)) &&
rknand->boot_ecc != ecc->strength) {
/*
* There's currently no method to notify the MTD framework that
@@ -560,7 +561,8 @@ static int rk_nfc_write_page_hwecc(struct mtd_info *mtd,
*
* Configure the ECC algorithm supported by the boot ROM.
*/
- if (page < (pages_per_blk * rknand->boot_blks)) {
+ if ((page < (pages_per_blk * rknand->boot_blks)) &&
+ (chip->options & NAND_IS_BOOT_MEDIUM)) {
boot_rom_mode = 1;
if (rknand->boot_ecc != ecc->strength)
rk_nfc_hw_ecc_setup(chip, rknand->boot_ecc);
@@ -624,8 +626,8 @@ static int rk_nfc_read_page_raw(struct mtd_info *mtd,
int i, pages_per_blk;
pages_per_blk = mtd->erasesize / mtd->writesize;
- if ((page < (pages_per_blk * rknand->boot_blks)) &&
- nfc->selected_bank == 0 &&
+ if ((chip->options & NAND_IS_BOOT_MEDIUM) &&
+ (page < (pages_per_blk * rknand->boot_blks)) &&
rknand->boot_ecc != ecc->strength) {
/*
* There's currently no method to notify the MTD framework that
@@ -700,8 +702,8 @@ static int rk_nfc_read_page_hwecc(struct mtd_info *mtd,
* are used by the boot ROM.
* Configure the ECC algorithm supported by the boot ROM.
*/
- if (page < (pages_per_blk * rknand->boot_blks) &&
- nfc->selected_bank == 0) {
+ if ((page < (pages_per_blk * rknand->boot_blks)) &&
+ (chip->options & NAND_IS_BOOT_MEDIUM)) {
boot_rom_mode = 1;
if (rknand->boot_ecc != ecc->strength)
rk_nfc_hw_ecc_setup(chip, rknand->boot_ecc);
--
2.39.5