For non ONFI NAND chips we decode the page layout from the extended ID information from NAND (basically what nand_decode_ext_id() does in the MTD layer). For some chips this information is not entirely correct though. For example some Toshiba chips have this quirk: /* * Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per * 512B page. For Toshiba SLC, we decode the 5th/6th byte as * follows: * - ID byte 6, bits[2:0]: 100b -> 43nm, 101b -> 32nm, * 110b -> 24nm * - ID byte 5, bit[7]: 1 -> BENAND, 0 -> raw SLC */ if (chip->id.len >= 6 && nand_is_slc(chip) && (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ && !(chip->id.data[4] & TOSHIBA_NAND_ID4_IS_BENAND) /* !BENAND */) { memorg->oobsize = 32 * memorg->pagesize >> 9; mtd->oobsize = memorg->oobsize; } We could try and add these kind of quirks into the xload code, but we already have the correct information in the FCB. So as long as the initial information from the ID is enough to read the FCB, we can use the information containekd therein for further reading from the NAND. Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> --- arch/arm/mach-imx/xload-gpmi-nand.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm/mach-imx/xload-gpmi-nand.c b/arch/arm/mach-imx/xload-gpmi-nand.c index 543ec108ba..af20c11fa6 100644 --- a/arch/arm/mach-imx/xload-gpmi-nand.c +++ b/arch/arm/mach-imx/xload-gpmi-nand.c @@ -1020,6 +1020,8 @@ static int __maybe_unused imx6_nand_load_image(struct imx_nand_params *params, }; int ret; struct fcb_block *fcb; + void __iomem *bch_regs = info->bch_base; + u32 fl0, fl1; info->dma_channel = &pchan; @@ -1047,6 +1049,21 @@ static int __maybe_unused imx6_nand_load_image(struct imx_nand_params *params, fcb->Firmware2_startingPage); pr_debug("PagesInFW2: 0x%08x\n", fcb->PagesInFirmware2); + info->organization.oobsize = fcb->TotalPageSize - fcb->PageDataSize; + info->organization.pagesize = fcb->PageDataSize; + + fl0 = FIELD_PREP(BCH_FLASHLAYOUT0_NBLOCKS, fcb->NumEccBlocksPerPage) | + FIELD_PREP(BCH_FLASHLAYOUT0_META_SIZE, fcb->MetadataBytes) | + FIELD_PREP(IMX6_BCH_FLASHLAYOUT0_ECC0, fcb->EccBlock0EccType) | + (fcb->BCHType ? BCH_FLASHLAYOUT0_GF13_0_GF14_1 : 0) | + FIELD_PREP(BCH_FLASHLAYOUT0_DATA0_SIZE, fcb->EccBlock0Size / 4); + fl1 = FIELD_PREP(BCH_FLASHLAYOUT1_PAGE_SIZE, fcb->TotalPageSize) | + FIELD_PREP(IMX6_BCH_FLASHLAYOUT1_ECCN, fcb->EccBlockNEccType) | + (fcb->BCHType ? BCH_FLASHLAYOUT1_GF13_0_GF14_1 : 0) | + FIELD_PREP(BCH_FLASHLAYOUT1_DATAN_SIZE, fcb->EccBlockNSize / 4); + writel(fl0, bch_regs + BCH_FLASH0LAYOUT0); + writel(fl1, bch_regs + BCH_FLASH0LAYOUT1); + get_dbbt(info, databuf); ret = read_firmware(info, fcb->Firmware1_startingPage, dest, len); -- 2.30.2