Skip to content

Commit ea690ad

Browse files
Johan Jonkermiquelraynal
authored andcommitted
mtd: rawnand: rockchip: Align hwecc vs. raw page helper layouts
Currently, read/write_page_hwecc() and read/write_page_raw() are not aligned: there is a mismatch in the OOB bytes which are not read/written at the same offset in both cases (raw vs. hwecc). This is a real problem when relying on the presence of the Page Addresses (PA) when using the NAND chip as a boot device, as the BootROM expects additional data in the OOB area at specific locations. Rockchip boot blocks are written per 4 x 512 byte sectors per page. Each page with boot blocks must have a page address (PA) pointer in OOB to the next page. Pages are written in a pattern depending on the NAND chip ID. Generate boot block page address and pattern for hwecc in user space and copy PA data to/from the already reserved last 4 bytes before ECC in the chip->oob_poi data layout. Align the different helpers. This change breaks existing jffs2 users. Fixes: 058e0e8 ("mtd: rawnand: rockchip: NFC driver for RK3308, RK2928 and others") Signed-off-by: Johan Jonker <jbx6244@gmail.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/5e782c08-862b-51ae-47ff-3299940928ca@gmail.com
1 parent d0ca3b9 commit ea690ad

File tree

1 file changed

+21
-13
lines changed

1 file changed

+21
-13
lines changed

drivers/mtd/nand/raw/rockchip-nand-controller.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf,
598598
int pages_per_blk = mtd->erasesize / mtd->writesize;
599599
int ret = 0, i, boot_rom_mode = 0;
600600
dma_addr_t dma_data, dma_oob;
601-
u32 reg;
601+
u32 tmp;
602602
u8 *oob;
603603

604604
nand_prog_page_begin_op(chip, page, 0, NULL, 0);
@@ -625,6 +625,13 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf,
625625
*
626626
* 0xFF 0xFF 0xFF 0xFF | BBM OOB1 OOB2 OOB3 | ...
627627
*
628+
* The code here just swaps the first 4 bytes with the last
629+
* 4 bytes without losing any data.
630+
*
631+
* The chip->oob_poi data layout:
632+
*
633+
* BBM OOB1 OOB2 OOB3 |......| PA0 PA1 PA2 PA3
634+
*
628635
* Configure the ECC algorithm supported by the boot ROM.
629636
*/
630637
if ((page < (pages_per_blk * rknand->boot_blks)) &&
@@ -635,21 +642,17 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf,
635642
}
636643

637644
for (i = 0; i < ecc->steps; i++) {
638-
if (!i) {
639-
reg = 0xFFFFFFFF;
640-
} else {
645+
if (!i)
646+
oob = chip->oob_poi + (ecc->steps - 1) * NFC_SYS_DATA_SIZE;
647+
else
641648
oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE;
642-
reg = oob[0] | oob[1] << 8 | oob[2] << 16 |
643-
oob[3] << 24;
644-
}
645649

646-
if (!i && boot_rom_mode)
647-
reg = (page & (pages_per_blk - 1)) * 4;
650+
tmp = oob[0] | oob[1] << 8 | oob[2] << 16 | oob[3] << 24;
648651

649652
if (nfc->cfg->type == NFC_V9)
650-
nfc->oob_buf[i] = reg;
653+
nfc->oob_buf[i] = tmp;
651654
else
652-
nfc->oob_buf[i * (oob_step / 4)] = reg;
655+
nfc->oob_buf[i * (oob_step / 4)] = tmp;
653656
}
654657

655658
dma_data = dma_map_single(nfc->dev, (void *)nfc->page_buf,
@@ -812,12 +815,17 @@ static int rk_nfc_read_page_hwecc(struct nand_chip *chip, u8 *buf, int oob_on,
812815
goto timeout_err;
813816
}
814817

815-
for (i = 1; i < ecc->steps; i++) {
816-
oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE;
818+
for (i = 0; i < ecc->steps; i++) {
819+
if (!i)
820+
oob = chip->oob_poi + (ecc->steps - 1) * NFC_SYS_DATA_SIZE;
821+
else
822+
oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE;
823+
817824
if (nfc->cfg->type == NFC_V9)
818825
tmp = nfc->oob_buf[i];
819826
else
820827
tmp = nfc->oob_buf[i * (oob_step / 4)];
828+
821829
*oob++ = (u8)tmp;
822830
*oob++ = (u8)(tmp >> 8);
823831
*oob++ = (u8)(tmp >> 16);

0 commit comments

Comments
 (0)