Skip to content

Commit 0bd6d36

Browse files
HatsyReigratian
authored andcommitted
pl35x-nand-controller: Enable on-die ECC subpage operations
Existing devices may contain partitions formatted with subpages, but the default PL35X NAND driver does not support them. This commit implements subpage read and write support for on-die ECC devices using the PL35X NAND driver. Signed-off-by: HatsyRei <yan.huan.chng@emerson.com>
1 parent ec1c50c commit 0bd6d36

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,14 @@ static int pl35x_nand_recover_data_hwecc(struct pl35x_nandc *nfc,
499499
return max_bitflips;
500500
}
501501

502+
static int pl35x_nand_write_subpage_raw(struct nand_chip *chip,
503+
uint32_t offset, uint32_t data_len,
504+
const uint8_t *data_buf,
505+
int oob_required, int page)
506+
{
507+
return nand_monolithic_write_page_raw(chip, data_buf, oob_required, page);
508+
}
509+
502510
static int pl35x_nand_write_page_hwecc(struct nand_chip *chip,
503511
const u8 *buf, int oob_required,
504512
int page)
@@ -659,6 +667,12 @@ static int pl35x_nand_read_page_hwecc(struct nand_chip *chip,
659667
return ret;
660668
}
661669

670+
static int pl35x_nand_read_subpage_raw(struct nand_chip *chip, uint32_t data_offs,
671+
uint32_t readlen, uint8_t *bufpoi, int page)
672+
{
673+
return nand_monolithic_read_page_raw(chip, bufpoi, 0, page);
674+
}
675+
662676
static int pl35x_nand_exec_op(struct nand_chip *chip,
663677
const struct nand_subop *subop)
664678
{
@@ -936,6 +950,29 @@ static int pl35x_nand_init_hw_ecc_controller(struct pl35x_nandc *nfc,
936950
return ret;
937951
}
938952

953+
static void pl35x_nand_init_ondie_ecc(struct pl35x_nandc *nfc,
954+
struct nand_chip *chip)
955+
{
956+
struct mtd_info *mtd = nand_to_mtd(chip);
957+
958+
/* Bypass the controller ECC block */
959+
pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_BYPASS);
960+
961+
chip->ecc.strength = 1;
962+
chip->ecc.bytes = 0;
963+
chip->ecc.read_page = nand_monolithic_read_page_raw;
964+
chip->ecc.read_page_raw = nand_monolithic_read_page_raw;
965+
chip->ecc.read_subpage = pl35x_nand_read_subpage_raw;
966+
chip->ecc.write_page = nand_monolithic_write_page_raw;
967+
chip->ecc.write_page_raw = nand_monolithic_write_page_raw;
968+
chip->ecc.write_subpage = pl35x_nand_write_subpage_raw;
969+
chip->ecc.size = mtd->writesize;
970+
971+
/* NAND with on-die ECC supports subpage reads and writes */
972+
chip->options |= NAND_SUBPAGE_READ;
973+
chip->options &= ~(NAND_NO_SUBPAGE_WRITE);
974+
}
975+
939976
static int pl35x_nand_attach_chip(struct nand_chip *chip)
940977
{
941978
const struct nand_ecc_props *requirements =
@@ -970,6 +1007,7 @@ static int pl35x_nand_attach_chip(struct nand_chip *chip)
9701007

9711008
switch (chip->ecc.engine_type) {
9721009
case NAND_ECC_ENGINE_TYPE_ON_DIE:
1010+
pl35x_nand_init_ondie_ecc(nfc, chip);
9731011
/* Keep these legacy BBT descriptors for ON_DIE situations */
9741012
chip->bbt_td = &bbt_main_descr;
9751013
chip->bbt_md = &bbt_mirror_descr;

0 commit comments

Comments
 (0)