diff options
Diffstat (limited to 'target/linux/bcm63xx/patches-5.4/441-mtd-rawnand-brcmnand-support-v2.1-v2.2-controllers.patch')
-rw-r--r-- | target/linux/bcm63xx/patches-5.4/441-mtd-rawnand-brcmnand-support-v2.1-v2.2-controllers.patch | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/target/linux/bcm63xx/patches-5.4/441-mtd-rawnand-brcmnand-support-v2.1-v2.2-controllers.patch b/target/linux/bcm63xx/patches-5.4/441-mtd-rawnand-brcmnand-support-v2.1-v2.2-controllers.patch new file mode 100644 index 0000000000..a212a5bda9 --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/441-mtd-rawnand-brcmnand-support-v2.1-v2.2-controllers.patch @@ -0,0 +1,143 @@ +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -269,6 +269,36 @@ enum brcmnand_reg { + BRCMNAND_FC_BASE, + }; + ++/* BRCMNAND v2.1-v2.2 */ ++static const u16 brcmnand_regs_v21[] = { ++ [BRCMNAND_CMD_START] = 0x04, ++ [BRCMNAND_CMD_EXT_ADDRESS] = 0x08, ++ [BRCMNAND_CMD_ADDRESS] = 0x0c, ++ [BRCMNAND_INTFC_STATUS] = 0x5c, ++ [BRCMNAND_CS_SELECT] = 0x14, ++ [BRCMNAND_CS_XOR] = 0x18, ++ [BRCMNAND_LL_OP] = 0, ++ [BRCMNAND_CS0_BASE] = 0x40, ++ [BRCMNAND_CS1_BASE] = 0, ++ [BRCMNAND_CORR_THRESHOLD] = 0, ++ [BRCMNAND_CORR_THRESHOLD_EXT] = 0, ++ [BRCMNAND_UNCORR_COUNT] = 0, ++ [BRCMNAND_CORR_COUNT] = 0, ++ [BRCMNAND_CORR_EXT_ADDR] = 0x60, ++ [BRCMNAND_CORR_ADDR] = 0x64, ++ [BRCMNAND_UNCORR_EXT_ADDR] = 0x68, ++ [BRCMNAND_UNCORR_ADDR] = 0x6c, ++ [BRCMNAND_SEMAPHORE] = 0x50, ++ [BRCMNAND_ID] = 0x54, ++ [BRCMNAND_ID_EXT] = 0, ++ [BRCMNAND_LL_RDATA] = 0, ++ [BRCMNAND_OOB_READ_BASE] = 0x20, ++ [BRCMNAND_OOB_READ_10_BASE] = 0, ++ [BRCMNAND_OOB_WRITE_BASE] = 0x30, ++ [BRCMNAND_OOB_WRITE_10_BASE] = 0, ++ [BRCMNAND_FC_BASE] = 0x200, ++}; ++ + /* BRCMNAND v3.3-v4.0 */ + static const u16 brcmnand_regs_v33[] = { + [BRCMNAND_CMD_START] = 0x04, +@@ -502,12 +532,16 @@ static int brcmnand_revision_init(struct + { + static const unsigned int block_sizes_v6[] = { 8, 16, 128, 256, 512, 1024, 2048, 0 }; + static const unsigned int block_sizes_v4[] = { 16, 128, 8, 512, 256, 1024, 2048, 0 }; ++ static const unsigned int block_sizes_v2_2[] = { 16, 128, 8, 512, 256, 0 }; ++ static const unsigned int block_sizes_v2_1[] = { 16, 128, 8, 512, 0 }; + static const unsigned int page_sizes_v3_4[] = { 512, 2048, 4096, 8192, 0 }; ++ static const unsigned int page_sizes_v2_2[] = { 512, 2048, 4096, 0 }; ++ static const unsigned int page_sizes_v2_1[] = { 512, 2048, 0 }; + + ctrl->nand_version = nand_readreg(ctrl, 0) & 0xffff; + +- /* Only support v4.0+? */ +- if (ctrl->nand_version < 0x0400) { ++ /* Only support v2.1+ */ ++ if (ctrl->nand_version < 0x0201) { + dev_err(ctrl->dev, "version %#x not supported\n", + ctrl->nand_version); + return -ENODEV; +@@ -524,6 +558,8 @@ static int brcmnand_revision_init(struct + ctrl->reg_offsets = brcmnand_regs_v50; + else if (ctrl->nand_version >= 0x0303) + ctrl->reg_offsets = brcmnand_regs_v33; ++ else if (ctrl->nand_version >= 0x0201) ++ ctrl->reg_offsets = brcmnand_regs_v21; + + /* Chip-select stride */ + if (ctrl->nand_version >= 0x0701) +@@ -549,14 +585,27 @@ static int brcmnand_revision_init(struct + ctrl->max_page_size = 16 * 1024; + ctrl->max_block_size = 2 * 1024 * 1024; + } else { +- ctrl->page_sizes = page_sizes_v3_4; ++ if (ctrl->nand_version >= 0x0304) ++ ctrl->page_sizes = page_sizes_v3_4; ++ else if (ctrl->nand_version >= 0x0202) ++ ctrl->page_sizes = page_sizes_v2_2; ++ else ++ ctrl->page_sizes = page_sizes_v2_1; ++ + if (ctrl->nand_version >= 0x0600) + ctrl->block_sizes = block_sizes_v6; +- else ++ else if (ctrl->nand_version >= 0x0400) + ctrl->block_sizes = block_sizes_v4; ++ else if (ctrl->nand_version >= 0x0202) ++ ctrl->block_sizes = block_sizes_v2_2; ++ else ++ ctrl->block_sizes = block_sizes_v2_1; + + if (ctrl->nand_version < 0x0400) { +- ctrl->max_page_size = 4096; ++ if (ctrl->nand_version < 0x0202) ++ ctrl->max_page_size = 2048; ++ else ++ ctrl->max_page_size = 4096; + ctrl->max_block_size = 512 * 1024; + } + } +@@ -724,6 +773,9 @@ static void brcmnand_wr_corr_thresh(stru + enum brcmnand_reg reg = BRCMNAND_CORR_THRESHOLD; + int cs = host->cs; + ++ if (!ctrl->reg_offsets[reg]) ++ return; ++ + if (ctrl->nand_version == 0x0702) + bits = 7; + else if (ctrl->nand_version >= 0x0600) +@@ -782,8 +834,10 @@ static inline u32 brcmnand_spare_area_ma + return GENMASK(7, 0); + else if (ctrl->nand_version >= 0x0600) + return GENMASK(6, 0); +- else ++ else if (ctrl->nand_version >= 0x0303) + return GENMASK(5, 0); ++ else ++ return GENMASK(4, 0); + } + + #define NAND_ACC_CONTROL_ECC_SHIFT 16 +@@ -2158,9 +2212,11 @@ static int brcmnand_set_cfg(struct brcmn + + tmp = nand_readreg(ctrl, acc_control_offs); + tmp &= ~brcmnand_ecc_level_mask(ctrl); +- tmp |= cfg->ecc_level << NAND_ACC_CONTROL_ECC_SHIFT; + tmp &= ~brcmnand_spare_area_mask(ctrl); +- tmp |= cfg->spare_area_size; ++ if (ctrl->nand_version >= 0x0302) { ++ tmp |= cfg->ecc_level << NAND_ACC_CONTROL_ECC_SHIFT; ++ tmp |= cfg->spare_area_size; ++ } + nand_writereg(ctrl, acc_control_offs, tmp); + + brcmnand_set_sector_size_1k(host, cfg->sector_size_1k); +@@ -2524,6 +2580,8 @@ const struct dev_pm_ops brcmnand_pm_ops + EXPORT_SYMBOL_GPL(brcmnand_pm_ops); + + static const struct of_device_id brcmnand_of_match[] = { ++ { .compatible = "brcm,brcmnand-v2.1" }, ++ { .compatible = "brcm,brcmnand-v2.2" }, + { .compatible = "brcm,brcmnand-v4.0" }, + { .compatible = "brcm,brcmnand-v5.0" }, + { .compatible = "brcm,brcmnand-v6.0" }, |