From abf24a9990dbc5d61094c8b4602e1c22b010f3e5 Mon Sep 17 00:00:00 2001 From: hanwckf Date: Fri, 21 Oct 2022 10:33:42 +0800 Subject: [PATCH] kernel: add mtk patches --- ...t-procedure-for-different-read-id-op.patch | 708 ++++++++++++++++++ ...and-gigadevice-Support-GD5F1GQ5UExxG.patch | 173 +++++ ...acronix-Add-support-for-MX31LF1GE4BC.patch | 40 + ...acronix-Add-support-for-MX31UF1GE4BC.patch | 40 + ...acronix-Add-support-for-MX35LFxGE4AD.patch | 50 ++ ...acronix-Add-support-for-MX35LFxG24AD.patch | 58 ++ ...ix-Add-support-for-serial-NAND-flash.patch | 170 +++++ ...d-Quad-support-for-serial-NAND-flash.patch | 88 +++ ...-layout-structure-and-function-names.patch | 83 ++ ...e-the-SPI-NAND-device-MT29F2G01ABAGD.patch | 29 + ...cron-Add-new-Micron-SPI-NAND-devices.patch | 59 ++ ...AND-device-with-Continuous-Read-mode.patch | 79 ++ ...-M70A-series-Micron-SPI-NAND-devices.patch | 48 ++ ...-SPI-NAND-devices-with-multiple-dies.patch | 109 +++ ...inand-micron-Use-more-specific-names.patch | 159 ++++ ...icron-Add-support-for-MT29F2G01AAAED.patch | 104 +++ ...me-to-change-suffix-and-prefix-8Gbit.patch | 170 +++++ ...a-Support-for-new-Kioxia-Serial-NAND.patch | 205 +++++ ...16-spi-add-power-control-when-set_cs.patch | 47 ++ .../499-mtd-add-nmbm-support.patch | 21 + .../500-ubi-add-configurable-rootdev.patch | 35 + 21 files changed, 2475 insertions(+) create mode 100644 target/linux/generic/backport-5.4/408-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch create mode 100644 target/linux/generic/backport-5.4/411-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch create mode 100644 target/linux/generic/backport-5.4/430-mtd-spinand-macronix-Add-support-for-MX31LF1GE4BC.patch create mode 100644 target/linux/generic/backport-5.4/431-mtd-spinand-macronix-Add-support-for-MX31UF1GE4BC.patch create mode 100644 target/linux/generic/backport-5.4/432-mtd-spinand-macronix-Add-support-for-MX35LFxGE4AD.patch create mode 100644 target/linux/generic/backport-5.4/433-mtd-spinand-macronix-Add-support-for-MX35LFxG24AD.patch create mode 100644 target/linux/generic/backport-5.4/434-mtd-spinand-macronix-Add-support-for-serial-NAND-flash.patch create mode 100644 target/linux/generic/backport-5.4/435-mtd-spinand-macronix-Add-Quad-support-for-serial-NAND-flash.patch create mode 100644 target/linux/generic/backport-5.4/450-mtd-spinand-micron-Generalize-the-OOB-layout-structure-and-function-names.patch create mode 100644 target/linux/generic/backport-5.4/451-mtd-spinand-micron-Describe-the-SPI-NAND-device-MT29F2G01ABAGD.patch create mode 100644 target/linux/generic/backport-5.4/452-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices.patch create mode 100644 target/linux/generic/backport-5.4/453-mtd-spinand-micron-identify-SPI-NAND-device-with-Continuous-Read-mode.patch create mode 100644 target/linux/generic/backport-5.4/454-mtd-spinand-micron-Add-M70A-series-Micron-SPI-NAND-devices.patch create mode 100644 target/linux/generic/backport-5.4/455-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices-with-multiple-dies.patch create mode 100644 target/linux/generic/backport-5.4/456-mtd-spinand-micron-Use-more-specific-names.patch create mode 100644 target/linux/generic/backport-5.4/457-mtd-spinand-micron-Add-support-for-MT29F2G01AAAED.patch create mode 100644 target/linux/generic/backport-5.4/470-mtd-spinand-toshiba-Rename-function-name-to-change-suffix-and-prefix-8Gbit.patch create mode 100644 target/linux/generic/backport-5.4/471-mtd-spinand-toshiba-Support-for-new-Kioxia-Serial-NAND.patch create mode 100644 target/linux/generic/backport-5.4/827-v5.16-spi-add-power-control-when-set_cs.patch create mode 100644 target/linux/generic/pending-5.4/499-mtd-add-nmbm-support.patch create mode 100644 target/linux/generic/pending-5.4/500-ubi-add-configurable-rootdev.patch diff --git a/target/linux/generic/backport-5.4/408-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch b/target/linux/generic/backport-5.4/408-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch new file mode 100644 index 0000000000..e4e283ceb8 --- /dev/null +++ b/target/linux/generic/backport-5.4/408-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch @@ -0,0 +1,708 @@ +--- a/drivers/mtd/nand/spi/core.c ++++ b/drivers/mtd/nand/spi/core.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -370,10 +371,11 @@ out: + return status & STATUS_BUSY ? -ETIMEDOUT : 0; + } + +-static int spinand_read_id_op(struct spinand_device *spinand, u8 *buf) ++static int spinand_read_id_op(struct spinand_device *spinand, u8 naddr, ++ u8 ndummy, u8 *buf) + { +- struct spi_mem_op op = SPINAND_READID_OP(0, spinand->scratchbuf, +- SPINAND_MAX_ID_LEN); ++ struct spi_mem_op op = SPINAND_READID_OP( ++ naddr, ndummy, spinand->scratchbuf, SPINAND_MAX_ID_LEN); + int ret; + + ret = spi_mem_exec_op(spinand->spimem, &op); +@@ -760,24 +762,62 @@ static const struct spinand_manufacturer + &winbond_spinand_manufacturer, + }; + +-static int spinand_manufacturer_detect(struct spinand_device *spinand) ++static int spinand_manufacturer_match(struct spinand_device *spinand, ++ enum spinand_readid_method rdid_method) + { ++ u8 *id = spinand->id.data; + unsigned int i; + int ret; + + for (i = 0; i < ARRAY_SIZE(spinand_manufacturers); i++) { +- ret = spinand_manufacturers[i]->ops->detect(spinand); +- if (ret > 0) { +- spinand->manufacturer = spinand_manufacturers[i]; +- return 0; +- } else if (ret < 0) { +- return ret; +- } +- } ++ const struct spinand_manufacturer *manufacturer = ++ spinand_manufacturers[i]; ++ ++ if (id[0] != manufacturer->id) ++ continue; + ++ ret = spinand_match_and_init(spinand, ++ manufacturer->chips, ++ manufacturer->nchips, ++ rdid_method); ++ if (ret < 0) ++ continue; ++ ++ spinand->manufacturer = manufacturer; ++ return 0; ++ } + return -ENOTSUPP; + } + ++static int spinand_id_detect(struct spinand_device *spinand) ++{ ++ u8 *id = spinand->id.data; ++ int ret; ++ ++ ret = spinand_read_id_op(spinand, 0, 0, id); ++ if (ret) ++ return ret; ++ ret = spinand_manufacturer_match(spinand, SPINAND_READID_METHOD_OPCODE); ++ if (!ret) ++ return 0; ++ ++ ret = spinand_read_id_op(spinand, 1, 0, id); ++ if (ret) ++ return ret; ++ ret = spinand_manufacturer_match(spinand, ++ SPINAND_READID_METHOD_OPCODE_ADDR); ++ if (!ret) ++ return 0; ++ ++ ret = spinand_read_id_op(spinand, 0, 1, id); ++ if (ret) ++ return ret; ++ ret = spinand_manufacturer_match(spinand, ++ SPINAND_READID_METHOD_OPCODE_DUMMY); ++ ++ return ret; ++} ++ + static int spinand_manufacturer_init(struct spinand_device *spinand) + { + if (spinand->manufacturer->ops->init) +@@ -833,9 +873,9 @@ spinand_select_op_variant(struct spinand + * @spinand: SPI NAND object + * @table: SPI NAND device description table + * @table_size: size of the device description table ++ * @rdid_method: read id method to match + * +- * Should be used by SPI NAND manufacturer drivers when they want to find a +- * match between a device ID retrieved through the READ_ID command and an ++ * Match between a device ID retrieved through the READ_ID command and an + * entry in the SPI NAND description table. If a match is found, the spinand + * object will be initialized with information provided by the matching + * spinand_info entry. +@@ -844,8 +884,10 @@ spinand_select_op_variant(struct spinand + */ + int spinand_match_and_init(struct spinand_device *spinand, + const struct spinand_info *table, +- unsigned int table_size, u16 devid) ++ unsigned int table_size, ++ enum spinand_readid_method rdid_method) + { ++ u8 *id = spinand->id.data; + struct nand_device *nand = spinand_to_nand(spinand); + unsigned int i; + +@@ -853,13 +895,17 @@ int spinand_match_and_init(struct spinan + const struct spinand_info *info = &table[i]; + const struct spi_mem_op *op; + +- if (devid != info->devid) ++ if (rdid_method != info->devid.method) ++ continue; ++ ++ if (memcmp(id + 1, info->devid.id, info->devid.len)) + continue; + + nand->memorg = table[i].memorg; + nand->eccreq = table[i].eccreq; + spinand->eccinfo = table[i].eccinfo; + spinand->flags = table[i].flags; ++ spinand->id.len = 1 + table[i].devid.len; + spinand->select_target = table[i].select_target; + + op = spinand_select_op_variant(spinand, +@@ -896,13 +942,7 @@ static int spinand_detect(struct spinand + if (ret) + return ret; + +- ret = spinand_read_id_op(spinand, spinand->id.data); +- if (ret) +- return ret; +- +- spinand->id.len = SPINAND_MAX_ID_LEN; +- +- ret = spinand_manufacturer_detect(spinand); ++ ret = spinand_id_detect(spinand); + if (ret) { + dev_err(dev, "unknown raw ID %*phN\n", SPINAND_MAX_ID_LEN, + spinand->id.data); +--- a/drivers/mtd/nand/spi/gigadevice.c ++++ b/drivers/mtd/nand/spi/gigadevice.c +@@ -195,7 +195,8 @@ static int gd5fxgq4ufxxg_ecc_get_status( + } + + static const struct spinand_info gigadevice_spinand_table[] = { +- SPINAND_INFO("GD5F1GQ4xA", 0xF1, ++ SPINAND_INFO("GD5F1GQ4xA", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1), + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -204,7 +205,8 @@ static const struct spinand_info gigadev + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, + gd5fxgq4xa_ecc_get_status)), +- SPINAND_INFO("GD5F2GQ4xA", 0xF2, ++ SPINAND_INFO("GD5F2GQ4xA", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2), + NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -213,7 +215,8 @@ static const struct spinand_info gigadev + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, + gd5fxgq4xa_ecc_get_status)), +- SPINAND_INFO("GD5F4GQ4xA", 0xF4, ++ SPINAND_INFO("GD5F4GQ4xA", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4), + NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -222,7 +225,8 @@ static const struct spinand_info gigadev + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, + gd5fxgq4xa_ecc_get_status)), +- SPINAND_INFO("GD5F1GQ4UExxG", 0xd1, ++ SPINAND_INFO("GD5F1GQ4UExxG", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -231,7 +235,8 @@ static const struct spinand_info gigadev + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout, + gd5fxgq4uexxg_ecc_get_status)), +- SPINAND_INFO("GD5F1GQ4UFxxG", 0xb148, ++ SPINAND_INFO("GD5F1GQ4UFxxG", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, +@@ -242,39 +247,13 @@ static const struct spinand_info gigadev + gd5fxgq4ufxxg_ecc_get_status)), + }; + +-static int gigadevice_spinand_detect(struct spinand_device *spinand) +-{ +- u8 *id = spinand->id.data; +- u16 did; +- int ret; +- +- /* +- * Earlier GDF5-series devices (A,E) return [0][MID][DID] +- * Later (F) devices return [MID][DID1][DID2] +- */ +- +- if (id[0] == SPINAND_MFR_GIGADEVICE) +- did = (id[1] << 8) + id[2]; +- else if (id[0] == 0 && id[1] == SPINAND_MFR_GIGADEVICE) +- did = id[2]; +- else +- return 0; +- +- ret = spinand_match_and_init(spinand, gigadevice_spinand_table, +- ARRAY_SIZE(gigadevice_spinand_table), +- did); +- if (ret) +- return ret; +- +- return 1; +-} +- + static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = { +- .detect = gigadevice_spinand_detect, + }; + + const struct spinand_manufacturer gigadevice_spinand_manufacturer = { + .id = SPINAND_MFR_GIGADEVICE, + .name = "GigaDevice", ++ .chips = gigadevice_spinand_table, ++ .nchips = ARRAY_SIZE(gigadevice_spinand_table), + .ops = &gigadevice_spinand_manuf_ops, + }; +--- a/drivers/mtd/nand/spi/macronix.c ++++ b/drivers/mtd/nand/spi/macronix.c +@@ -99,7 +99,8 @@ static int mx35lf1ge4ab_ecc_get_status(s + } + + static const struct spinand_info macronix_spinand_table[] = { +- SPINAND_INFO("MX35LF1GE4AB", 0x12, ++ SPINAND_INFO("MX35LF1GE4AB", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x12), + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(4, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -108,7 +109,8 @@ static const struct spinand_info macroni + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), +- SPINAND_INFO("MX35LF2GE4AB", 0x22, ++ SPINAND_INFO("MX35LF2GE4AB", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22), + NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1), + NAND_ECCREQ(4, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -118,33 +120,13 @@ static const struct spinand_info macroni + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), + }; + +-static int macronix_spinand_detect(struct spinand_device *spinand) +-{ +- u8 *id = spinand->id.data; +- int ret; +- +- /* +- * Macronix SPI NAND read ID needs a dummy byte, so the first byte in +- * raw_id is garbage. +- */ +- if (id[1] != SPINAND_MFR_MACRONIX) +- return 0; +- +- ret = spinand_match_and_init(spinand, macronix_spinand_table, +- ARRAY_SIZE(macronix_spinand_table), +- id[2]); +- if (ret) +- return ret; +- +- return 1; +-} +- + static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = { +- .detect = macronix_spinand_detect, + }; + + const struct spinand_manufacturer macronix_spinand_manufacturer = { + .id = SPINAND_MFR_MACRONIX, + .name = "Macronix", ++ .chips = macronix_spinand_table, ++ .nchips = ARRAY_SIZE(macronix_spinand_table), + .ops = ¯onix_spinand_manuf_ops, + }; +--- a/drivers/mtd/nand/spi/micron.c ++++ b/drivers/mtd/nand/spi/micron.c +@@ -91,7 +91,8 @@ static int mt29f2g01abagd_ecc_get_status + } + + static const struct spinand_info micron_spinand_table[] = { +- SPINAND_INFO("MT29F2G01ABAGD", 0x24, ++ SPINAND_INFO("MT29F2G01ABAGD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -102,32 +103,13 @@ static const struct spinand_info micron_ + mt29f2g01abagd_ecc_get_status)), + }; + +-static int micron_spinand_detect(struct spinand_device *spinand) +-{ +- u8 *id = spinand->id.data; +- int ret; +- +- /* +- * Micron SPI NAND read ID need a dummy byte, +- * so the first byte in raw_id is dummy. +- */ +- if (id[1] != SPINAND_MFR_MICRON) +- return 0; +- +- ret = spinand_match_and_init(spinand, micron_spinand_table, +- ARRAY_SIZE(micron_spinand_table), id[2]); +- if (ret) +- return ret; +- +- return 1; +-} +- + static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = { +- .detect = micron_spinand_detect, + }; + + const struct spinand_manufacturer micron_spinand_manufacturer = { + .id = SPINAND_MFR_MICRON, + .name = "Micron", ++ .chips = micron_spinand_table, ++ .nchips = ARRAY_SIZE(micron_spinand_table), + .ops = µn_spinand_manuf_ops, + }; +--- a/drivers/mtd/nand/spi/paragon.c ++++ b/drivers/mtd/nand/spi/paragon.c +@@ -97,7 +97,8 @@ static const struct mtd_ooblayout_ops pn + + + static const struct spinand_info paragon_spinand_table[] = { +- SPINAND_INFO("PN26G01A", 0xe1, ++ SPINAND_INFO("PN26G01A", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xe1), + NAND_MEMORG(1, 2048, 128, 64, 1024, 21, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -106,7 +107,8 @@ static const struct spinand_info paragon + 0, + SPINAND_ECCINFO(&pn26g0xa_ooblayout, + pn26g0xa_ecc_get_status)), +- SPINAND_INFO("PN26G02A", 0xe2, ++ SPINAND_INFO("PN26G02A", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xe2), + NAND_MEMORG(1, 2048, 128, 64, 2048, 41, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -117,31 +119,13 @@ static const struct spinand_info paragon + pn26g0xa_ecc_get_status)), + }; + +-static int paragon_spinand_detect(struct spinand_device *spinand) +-{ +- u8 *id = spinand->id.data; +- int ret; +- +- /* Read ID returns [0][MID][DID] */ +- +- if (id[1] != SPINAND_MFR_PARAGON) +- return 0; +- +- ret = spinand_match_and_init(spinand, paragon_spinand_table, +- ARRAY_SIZE(paragon_spinand_table), +- id[2]); +- if (ret) +- return ret; +- +- return 1; +-} +- + static const struct spinand_manufacturer_ops paragon_spinand_manuf_ops = { +- .detect = paragon_spinand_detect, + }; + + const struct spinand_manufacturer paragon_spinand_manufacturer = { + .id = SPINAND_MFR_PARAGON, + .name = "Paragon", ++ .chips = paragon_spinand_table, ++ .nchips = ARRAY_SIZE(paragon_spinand_table), + .ops = ¶gon_spinand_manuf_ops, + }; +--- a/drivers/mtd/nand/spi/toshiba.c ++++ b/drivers/mtd/nand/spi/toshiba.c +@@ -95,7 +95,8 @@ static int tc58cxgxsx_ecc_get_status(str + + static const struct spinand_info toshiba_spinand_table[] = { + /* 3.3V 1Gb */ +- SPINAND_INFO("TC58CVG0S3", 0xC2, ++ SPINAND_INFO("TC58CVG0S3", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC2), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -105,7 +106,8 @@ static const struct spinand_info toshiba + SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, + tc58cxgxsx_ecc_get_status)), + /* 3.3V 2Gb */ +- SPINAND_INFO("TC58CVG1S3", 0xCB, ++ SPINAND_INFO("TC58CVG1S3", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -115,7 +117,8 @@ static const struct spinand_info toshiba + SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, + tc58cxgxsx_ecc_get_status)), + /* 3.3V 4Gb */ +- SPINAND_INFO("TC58CVG2S0", 0xCD, ++ SPINAND_INFO("TC58CVG2S0", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD), + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -125,7 +128,8 @@ static const struct spinand_info toshiba + SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, + tc58cxgxsx_ecc_get_status)), + /* 1.8V 1Gb */ +- SPINAND_INFO("TC58CYG0S3", 0xB2, ++ SPINAND_INFO("TC58CYG0S3", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -135,7 +139,8 @@ static const struct spinand_info toshiba + SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, + tc58cxgxsx_ecc_get_status)), + /* 1.8V 2Gb */ +- SPINAND_INFO("TC58CYG1S3", 0xBB, ++ SPINAND_INFO("TC58CYG1S3", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -145,7 +150,8 @@ static const struct spinand_info toshiba + SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, + tc58cxgxsx_ecc_get_status)), + /* 1.8V 4Gb */ +- SPINAND_INFO("TC58CYG2S0", 0xBD, ++ SPINAND_INFO("TC58CYG2S0", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD), + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -156,33 +162,13 @@ static const struct spinand_info toshiba + tc58cxgxsx_ecc_get_status)), + }; + +-static int toshiba_spinand_detect(struct spinand_device *spinand) +-{ +- u8 *id = spinand->id.data; +- int ret; +- +- /* +- * Toshiba SPI NAND read ID needs a dummy byte, +- * so the first byte in id is garbage. +- */ +- if (id[1] != SPINAND_MFR_TOSHIBA) +- return 0; +- +- ret = spinand_match_and_init(spinand, toshiba_spinand_table, +- ARRAY_SIZE(toshiba_spinand_table), +- id[2]); +- if (ret) +- return ret; +- +- return 1; +-} +- + static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = { +- .detect = toshiba_spinand_detect, + }; + + const struct spinand_manufacturer toshiba_spinand_manufacturer = { + .id = SPINAND_MFR_TOSHIBA, + .name = "Toshiba", ++ .chips = toshiba_spinand_table, ++ .nchips = ARRAY_SIZE(toshiba_spinand_table), + .ops = &toshiba_spinand_manuf_ops, + }; +--- a/drivers/mtd/nand/spi/winbond.c ++++ b/drivers/mtd/nand/spi/winbond.c +@@ -75,7 +75,8 @@ static int w25m02gv_select_target(struct + } + + static const struct spinand_info winbond_spinand_table[] = { +- SPINAND_INFO("W25M02GV", 0xAB, ++ SPINAND_INFO("W25M02GV", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab), + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2), + NAND_ECCREQ(1, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -84,7 +85,8 @@ static const struct spinand_info winbond + 0, + SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL), + SPINAND_SELECT_TARGET(w25m02gv_select_target)), +- SPINAND_INFO("W25N01GV", 0xAA, ++ SPINAND_INFO("W25N01GV", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa), + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(1, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +@@ -94,31 +96,6 @@ static const struct spinand_info winbond + SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)), + }; + +-/** +- * winbond_spinand_detect - initialize device related part in spinand_device +- * struct if it is a Winbond device. +- * @spinand: SPI NAND device structure +- */ +-static int winbond_spinand_detect(struct spinand_device *spinand) +-{ +- u8 *id = spinand->id.data; +- int ret; +- +- /* +- * Winbond SPI NAND read ID need a dummy byte, +- * so the first byte in raw_id is dummy. +- */ +- if (id[1] != SPINAND_MFR_WINBOND) +- return 0; +- +- ret = spinand_match_and_init(spinand, winbond_spinand_table, +- ARRAY_SIZE(winbond_spinand_table), id[2]); +- if (ret) +- return ret; +- +- return 1; +-} +- + static int winbond_spinand_init(struct spinand_device *spinand) + { + struct nand_device *nand = spinand_to_nand(spinand); +@@ -138,12 +115,13 @@ static int winbond_spinand_init(struct s + } + + static const struct spinand_manufacturer_ops winbond_spinand_manuf_ops = { +- .detect = winbond_spinand_detect, + .init = winbond_spinand_init, + }; + + const struct spinand_manufacturer winbond_spinand_manufacturer = { + .id = SPINAND_MFR_WINBOND, + .name = "Winbond", ++ .chips = winbond_spinand_table, ++ .nchips = ARRAY_SIZE(winbond_spinand_table), + .ops = &winbond_spinand_manuf_ops, + }; +--- a/include/linux/mtd/spinand.h ++++ b/include/linux/mtd/spinand.h +@@ -32,9 +32,9 @@ + SPI_MEM_OP_NO_DUMMY, \ + SPI_MEM_OP_NO_DATA) + +-#define SPINAND_READID_OP(ndummy, buf, len) \ ++#define SPINAND_READID_OP(naddr, ndummy, buf, len) \ + SPI_MEM_OP(SPI_MEM_OP_CMD(0x9f, 1), \ +- SPI_MEM_OP_NO_ADDR, \ ++ SPI_MEM_OP_ADDR(naddr, 0, 1), \ + SPI_MEM_OP_DUMMY(ndummy, 1), \ + SPI_MEM_OP_DATA_IN(len, buf, 1)) + +@@ -176,37 +176,46 @@ struct spinand_device; + * @data: buffer containing the id bytes. Currently 4 bytes large, but can + * be extended if required + * @len: ID length +- * +- * struct_spinand_id->data contains all bytes returned after a READ_ID command, +- * including dummy bytes if the chip does not emit ID bytes right after the +- * READ_ID command. The responsibility to extract real ID bytes is left to +- * struct_manufacurer_ops->detect(). + */ + struct spinand_id { + u8 data[SPINAND_MAX_ID_LEN]; + int len; + }; + ++enum spinand_readid_method { ++ SPINAND_READID_METHOD_OPCODE, ++ SPINAND_READID_METHOD_OPCODE_ADDR, ++ SPINAND_READID_METHOD_OPCODE_DUMMY, ++}; ++ ++/** ++ * struct spinand_devid - SPI NAND device id structure ++ * @id: device id of current chip ++ * @len: number of bytes in device id ++ * @method: method to read chip id ++ * There are 3 possible variants: ++ * SPINAND_READID_METHOD_OPCODE: chip id is returned immediately ++ * after read_id opcode. ++ * SPINAND_READID_METHOD_OPCODE_ADDR: chip id is returned after ++ * read_id opcode + 1-byte address. ++ * SPINAND_READID_METHOD_OPCODE_DUMMY: chip id is returned after ++ * read_id opcode + 1 dummy byte. ++ */ ++struct spinand_devid { ++ const u8 *id; ++ const u8 len; ++ const enum spinand_readid_method method; ++}; ++ + /** + * struct manufacurer_ops - SPI NAND manufacturer specific operations +- * @detect: detect a SPI NAND device. Every time a SPI NAND device is probed +- * the core calls the struct_manufacurer_ops->detect() hook of each +- * registered manufacturer until one of them return 1. Note that +- * the first thing to check in this hook is that the manufacturer ID +- * in struct_spinand_device->id matches the manufacturer whose +- * ->detect() hook has been called. Should return 1 if there's a +- * match, 0 if the manufacturer ID does not match and a negative +- * error code otherwise. When true is returned, the core assumes +- * that properties of the NAND chip (spinand->base.memorg and +- * spinand->base.eccreq) have been filled + * @init: initialize a SPI NAND device + * @cleanup: cleanup a SPI NAND device + * + * Each SPI NAND manufacturer driver should implement this interface so that +- * NAND chips coming from this vendor can be detected and initialized properly. ++ * NAND chips coming from this vendor can be initialized properly. + */ + struct spinand_manufacturer_ops { +- int (*detect)(struct spinand_device *spinand); + int (*init)(struct spinand_device *spinand); + void (*cleanup)(struct spinand_device *spinand); + }; +@@ -215,11 +224,16 @@ struct spinand_manufacturer_ops { + * struct spinand_manufacturer - SPI NAND manufacturer instance + * @id: manufacturer ID + * @name: manufacturer name ++ * @devid_len: number of bytes in device ID ++ * @chips: supported SPI NANDs under current manufacturer ++ * @nchips: number of SPI NANDs available in chips array + * @ops: manufacturer operations + */ + struct spinand_manufacturer { + u8 id; + char *name; ++ const struct spinand_info *chips; ++ const size_t nchips; + const struct spinand_manufacturer_ops *ops; + }; + +@@ -291,7 +305,7 @@ struct spinand_ecc_info { + */ + struct spinand_info { + const char *model; +- u16 devid; ++ struct spinand_devid devid; + u32 flags; + struct nand_memory_organization memorg; + struct nand_ecc_req eccreq; +@@ -305,6 +319,13 @@ struct spinand_info { + unsigned int target); + }; + ++#define SPINAND_ID(__method, ...) \ ++ { \ ++ .id = (const u8[]){ __VA_ARGS__ }, \ ++ .len = sizeof((u8[]){ __VA_ARGS__ }), \ ++ .method = __method, \ ++ } ++ + #define SPINAND_INFO_OP_VARIANTS(__read, __write, __update) \ + { \ + .read_cache = __read, \ +@@ -451,9 +472,10 @@ static inline void spinand_set_of_node(s + nanddev_set_of_node(&spinand->base, np); + } + +-int spinand_match_and_init(struct spinand_device *dev, ++int spinand_match_and_init(struct spinand_device *spinand, + const struct spinand_info *table, +- unsigned int table_size, u16 devid); ++ unsigned int table_size, ++ enum spinand_readid_method rdid_method); + + int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val); + int spinand_select_target(struct spinand_device *spinand, unsigned int target); diff --git a/target/linux/generic/backport-5.4/411-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch b/target/linux/generic/backport-5.4/411-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch new file mode 100644 index 0000000000..d4e9497c13 --- /dev/null +++ b/target/linux/generic/backport-5.4/411-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch @@ -0,0 +1,173 @@ +From 469b992489852b500d39048aa0013639dfe9f2e6 Mon Sep 17 00:00:00 2001 +From: Reto Schneider +Date: Thu, 11 Feb 2021 12:36:19 +0100 +Subject: [PATCH] mtd: spinand: gigadevice: Support GD5F1GQ5UExxG + +The relevant changes to the already existing GD5F1GQ4UExxG support has +been determined by consulting the GigaDevice product change notice +AN-0392-10, version 1.0 from November 30, 2020. + +As the overlaps are huge, variable names have been generalized +accordingly. + +Apart from the lowered ECC strength (4 instead of 8 bits per 512 bytes), +the new device ID, and the extra quad IO dummy byte, no changes had to +be taken into account. + +New hardware features are not supported, namely: + - Power on reset + - Unique ID + - Double transfer rate (DTR) + - Parameter page + - Random data quad IO + +The inverted semantic of the "driver strength" register bits, defaulting +to 100% instead of 50% for the Q5 devices, got ignored as the driver has +never touched them anyway. + +The no longer supported "read from cache during block erase" +functionality is not reflected as the current SPI NAND core does not +support it anyway. + +Implementation has been tested on MediaTek MT7688 based GARDENA smart +Gateways using both, GigaDevice GD5F1GQ5UEYIG and GD5F1GQ4UBYIG. + +Signed-off-by: Reto Schneider +Reviewed-by: Frieder Schrempf +Reviewed-by: Stefan Roese +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20210211113619.3502-1-code@reto-schneider.ch +--- + drivers/mtd/nand/spi/gigadevice.c | 69 +++++++++++++++++++++++++++---- + 1 file changed, 60 insertions(+), 9 deletions(-) + +diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c +index 33c67403c4aa1e..1dd1c589809341 100644 +--- a/drivers/mtd/nand/spi/gigadevice.c ++++ b/drivers/mtd/nand/spi/gigadevice.c +@@ -13,7 +13,10 @@ + #define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4) + #define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4) + +-#define GD5FXGQ4UEXXG_REG_STATUS2 0xf0 ++#define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS (1 << 4) ++#define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS (3 << 4) ++ ++#define GD5FXGQXXEXXG_REG_STATUS2 0xf0 + + #define GD5FXGQ4UXFXXG_STATUS_ECC_MASK (7 << 4) + #define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS (0 << 4) +@@ -102,7 +105,7 @@ static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand, + return -EINVAL; + } + +-static int gd5fxgq4_variant2_ooblayout_ecc(struct mtd_info *mtd, int section, ++static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section, + struct mtd_oob_region *region) + { + if (section) +@@ -114,7 +117,7 @@ static int gd5fxgq4_variant2_ooblayout_ecc(struct mtd_info *mtd, int section, + return 0; + } + +-static int gd5fxgq4_variant2_ooblayout_free(struct mtd_info *mtd, int section, ++static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section, + struct mtd_oob_region *region) + { + if (section) +@@ -127,9 +130,10 @@ static int gd5fxgq4_variant2_ooblayout_free(struct mtd_info *mtd, int section, + return 0; + } + +-static const struct mtd_ooblayout_ops gd5fxgq4_variant2_ooblayout = { +- .ecc = gd5fxgq4_variant2_ooblayout_ecc, +- .free = gd5fxgq4_variant2_ooblayout_free, ++/* Valid for Q4/Q5 and Q6 (untested) devices */ ++static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = { ++ .ecc = gd5fxgqx_variant2_ooblayout_ecc, ++ .free = gd5fxgqx_variant2_ooblayout_free, + }; + + static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section, +@@ -165,7 +169,7 @@ static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand, + u8 status) + { + u8 status2; +- struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQ4UEXXG_REG_STATUS2, ++ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2, + &status2); + int ret; + +@@ -203,6 +207,43 @@ static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand, + return -EINVAL; + } + ++static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand, ++ u8 status) ++{ ++ u8 status2; ++ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2, ++ &status2); ++ int ret; ++ ++ switch (status & STATUS_ECC_MASK) { ++ case STATUS_ECC_NO_BITFLIPS: ++ return 0; ++ ++ case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS: ++ /* ++ * Read status2 register to determine a more fine grained ++ * bit error status ++ */ ++ ret = spi_mem_exec_op(spinand->spimem, &op); ++ if (ret) ++ return ret; ++ ++ /* ++ * 1 ... 4 bits are flipped (and corrected) ++ */ ++ /* bits sorted this way (1...0): ECCSE1, ECCSE0 */ ++ return ((status2 & STATUS_ECC_MASK) >> 4) + 1; ++ ++ case STATUS_ECC_UNCOR_ERROR: ++ return -EBADMSG; ++ ++ default: ++ break; ++ } ++ ++ return -EINVAL; ++} ++ + static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand, + u8 status) + { +@@ -282,7 +323,7 @@ static const struct spinand_info gigadevice_spinand_table[] = { + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, +- SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout, ++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq4uexxg_ecc_get_status)), + SPINAND_INFO("GD5F1GQ4UFxxG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48), +@@ -292,8 +333,18 @@ static const struct spinand_info gigadevice_spinand_table[] = { + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, +- SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout, ++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq4ufxxg_ecc_get_status)), ++ SPINAND_INFO("GD5F1GQ5UExxG", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51), ++ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(4, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, ++ gd5fxgq5xexxg_ecc_get_status)), + }; + + static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = { diff --git a/target/linux/generic/backport-5.4/430-mtd-spinand-macronix-Add-support-for-MX31LF1GE4BC.patch b/target/linux/generic/backport-5.4/430-mtd-spinand-macronix-Add-support-for-MX31LF1GE4BC.patch new file mode 100644 index 0000000000..3292a6b9a8 --- /dev/null +++ b/target/linux/generic/backport-5.4/430-mtd-spinand-macronix-Add-support-for-MX31LF1GE4BC.patch @@ -0,0 +1,40 @@ +From 051e070d0a019df6be9e21be1fb63352e4c4412e Mon Sep 17 00:00:00 2001 +From: YouChing Lin +Date: Wed, 22 Jul 2020 16:02:57 +0800 +Subject: [PATCH] mtd: spinand: macronix: Add support for MX31LF1GE4BC + +The Macronix MX31LF1GE4BC is a 3V, 1Gbit (128MB) serial +NAND flash device. + +Validated by read, erase, read back, write and read back +on Xilinx Zynq PicoZed FPGA board which included +Macronix SPI Host (driver/spi/spi-mxic.c). + +Signed-off-by: YouChing Lin +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/1595404978-31079-2-git-send-email-ycllin@mxic.com.tw +--- + drivers/mtd/nand/spi/macronix.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c +index 9ff8debd599418..9ae48ce1c46f91 100644 +--- a/drivers/mtd/nand/spi/macronix.c ++++ b/drivers/mtd/nand/spi/macronix.c +@@ -119,6 +119,16 @@ static const struct spinand_info macronix_spinand_table[] = { + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), ++ SPINAND_INFO("MX31LF1GE4BC", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e), ++ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0 /*SPINAND_HAS_QE_BIT*/, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, ++ mx35lf1ge4ab_ecc_get_status)), + }; + + static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = { diff --git a/target/linux/generic/backport-5.4/431-mtd-spinand-macronix-Add-support-for-MX31UF1GE4BC.patch b/target/linux/generic/backport-5.4/431-mtd-spinand-macronix-Add-support-for-MX31UF1GE4BC.patch new file mode 100644 index 0000000000..9f48d4a176 --- /dev/null +++ b/target/linux/generic/backport-5.4/431-mtd-spinand-macronix-Add-support-for-MX31UF1GE4BC.patch @@ -0,0 +1,40 @@ +From 75b049bb7f89a58a25592f17baf91d703f0f548e Mon Sep 17 00:00:00 2001 +From: YouChing Lin +Date: Wed, 22 Jul 2020 16:02:58 +0800 +Subject: [PATCH] mtd: spinand: macronix: Add support for MX31UF1GE4BC + +The Macronix MX31UF1GE4BC is a 1.8V, 1Gbit (128MB) serial +NAND flash device. + +Validated by read, erase, read back, write and read back +on Xilinx Zynq PicoZed FPGA board which included +Macronix SPI Host (driver/spi/spi-mxic.c). + +Signed-off-by: YouChing Lin +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/1595404978-31079-3-git-send-email-ycllin@mxic.com.tw +--- + drivers/mtd/nand/spi/macronix.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c +index 9ae48ce1c46f91..8e801e4c3a006f 100644 +--- a/drivers/mtd/nand/spi/macronix.c ++++ b/drivers/mtd/nand/spi/macronix.c +@@ -129,6 +129,16 @@ static const struct spinand_info macronix_spinand_table[] = { + 0 /*SPINAND_HAS_QE_BIT*/, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), ++ SPINAND_INFO("MX31UF1GE4BC", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9e), ++ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0 /*SPINAND_HAS_QE_BIT*/, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, ++ mx35lf1ge4ab_ecc_get_status)), + }; + + static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = { diff --git a/target/linux/generic/backport-5.4/432-mtd-spinand-macronix-Add-support-for-MX35LFxGE4AD.patch b/target/linux/generic/backport-5.4/432-mtd-spinand-macronix-Add-support-for-MX35LFxGE4AD.patch new file mode 100644 index 0000000000..313b373d5f --- /dev/null +++ b/target/linux/generic/backport-5.4/432-mtd-spinand-macronix-Add-support-for-MX35LFxGE4AD.patch @@ -0,0 +1,50 @@ +From 5ece78de88739b4c68263e9f2582380c1fd8314f Mon Sep 17 00:00:00 2001 +From: YouChing Lin +Date: Thu, 5 Nov 2020 15:23:40 +0800 +Subject: [PATCH] mtd: spinand: macronix: Add support for MX35LFxGE4AD + +The Macronix MX35LF2GE4AD / MX35LF4GE4AD are 3V, 2G / 4Gbit serial +SLC NAND flash device (with on-die ECC). + +Validated by read, erase, read back, write, read back and nandtest +on Xilinx Zynq PicoZed FPGA board which included Macronix SPI Host +(drivers/spi/spi-mxic.c). + +Signed-off-by: YouChing Lin +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/1604561020-13499-1-git-send-email-ycllin@mxic.com.tw +--- + drivers/mtd/nand/spi/macronix.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c +index 8e801e4c3a006f..3786b1b03b3b4b 100644 +--- a/drivers/mtd/nand/spi/macronix.c ++++ b/drivers/mtd/nand/spi/macronix.c +@@ -119,6 +119,26 @@ static const struct spinand_info macronix_spinand_table[] = { + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), ++ SPINAND_INFO("MX35LF2GE4AD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x26), ++ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, ++ mx35lf1ge4ab_ecc_get_status)), ++ SPINAND_INFO("MX35LF4GE4AD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x37), ++ NAND_MEMORG(1, 4096, 128, 64, 2048, 40, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, ++ mx35lf1ge4ab_ecc_get_status)), + SPINAND_INFO("MX31LF1GE4BC", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e), + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), diff --git a/target/linux/generic/backport-5.4/433-mtd-spinand-macronix-Add-support-for-MX35LFxG24AD.patch b/target/linux/generic/backport-5.4/433-mtd-spinand-macronix-Add-support-for-MX35LFxG24AD.patch new file mode 100644 index 0000000000..e323a53f62 --- /dev/null +++ b/target/linux/generic/backport-5.4/433-mtd-spinand-macronix-Add-support-for-MX35LFxG24AD.patch @@ -0,0 +1,58 @@ +From ee4e0eafa43cfd9008722fe15e17b8bf62fb6e8d Mon Sep 17 00:00:00 2001 +From: YouChing Lin +Date: Thu, 10 Dec 2020 11:22:09 +0800 +Subject: [PATCH] mtd: spinand: macronix: Add support for MX35LFxG24AD + +The Macronix MX35LF1G24AD(/2G24AD/4G24AD) are 3V, 1G/2G/4Gbit serial +SLC NAND flash device (without on-die ECC). + +Validated by read, erase, read back, write, read back on Xilinx Zynq +PicoZed FPGA board which included Macronix SPI Host(drivers/spi/spi-mxic.c) +& S/W BCH ecc(drivers/mtd/nand/ecc-sw-bch.c) with bug fixing patch +(mtd: nand: ecc-bch: Fix the size of calc_buf/code_buf of the BCH). + +Signed-off-by: YouChing Lin +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/1607570529-22341-3-git-send-email-ycllin@mxic.com.tw +--- + drivers/mtd/nand/spi/macronix.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c +index 3786b1b03b3b4b..6701aaa21a49df 100644 +--- a/drivers/mtd/nand/spi/macronix.c ++++ b/drivers/mtd/nand/spi/macronix.c +@@ -139,6 +139,33 @@ static const struct spinand_info macronix_spinand_table[] = { + 0, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), ++ SPINAND_INFO("MX35LF1G24AD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14), ++ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), ++ SPINAND_INFO("MX35LF2G24AD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24), ++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), ++ SPINAND_INFO("MX35LF4G24AD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35), ++ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), + SPINAND_INFO("MX31LF1GE4BC", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e), + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), diff --git a/target/linux/generic/backport-5.4/434-mtd-spinand-macronix-Add-support-for-serial-NAND-flash.patch b/target/linux/generic/backport-5.4/434-mtd-spinand-macronix-Add-support-for-serial-NAND-flash.patch new file mode 100644 index 0000000000..99000843b2 --- /dev/null +++ b/target/linux/generic/backport-5.4/434-mtd-spinand-macronix-Add-support-for-serial-NAND-flash.patch @@ -0,0 +1,170 @@ +From c374839f9b4475173e536d1eaddff45cb481dbdf Mon Sep 17 00:00:00 2001 +From: Jaime Liao +Date: Thu, 20 May 2021 09:45:08 +0800 +Subject: [PATCH] mtd: spinand: macronix: Add support for serial NAND flash + +Macronix NAND Flash devices are available in different configurations +and densities. + +MX"35" means SPI NAND +MX35"LF"/"UF" , LF means 3V and UF meands 1.8V +MX35LF"2G" , 2G means 2Gbits +MX35LF2G"E4"/"24"/"14", +E4 means internal ECC and Quad I/O(x4) +24 means 8-bit ecc requirement and Quad I/O(x4) +14 means 4-bit ecc requirement and Quad I/O(x4) + +MX35LF2G14AC is 3V 2Gbit serial NAND flash device +(without on-die ECC) +https://www.mxic.com.tw/Lists/Datasheet/Attachments/7926/MX35LF2G14AC,%203V,%202Gb,%20v1.1.pdf + +MX35UF4G24AD is 1.8V 4Gbit serial NAND flash device +(without on-die ECC) +https://www.mxic.com.tw/Lists/Datasheet/Attachments/7980/MX35UF4G24AD,%201.8V,%204Gb,%20v0.00.pdf + +MX35UF4GE4AD/MX35UF2GE4AD are 1.8V 4G/2Gbit serial +NAND flash device with 8-bit on-die ECC +https://www.mxic.com.tw/Lists/Datasheet/Attachments/7983/MX35UF4GE4AD,%201.8V,%204Gb,%20v0.00.pdf + +MX35UF2GE4AC/MX35UF1GE4AC are 1.8V 2G/1Gbit serial +NAND flash device with 8-bit on-die ECC +https://www.mxic.com.tw/Lists/Datasheet/Attachments/7974/MX35UF2GE4AC,%201.8V,%202Gb,%20v1.0.pdf + +MX35UF2G14AC/MX35UF1G14AC are 1.8V 2G/1Gbit serial +NAND flash device (without on-die ECC) +https://www.mxic.com.tw/Lists/Datasheet/Attachments/7931/MX35UF2G14AC,%201.8V,%202Gb,%20v1.1.pdf + +Validated via normal(default) and QUAD mode by read, erase, read back, +on Xilinx Zynq PicoZed FPGA board which included Macronix +SPI Host(drivers/spi/spi-mxic.c). + +Signed-off-by: Jaime Liao +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/1621475108-22523-1-git-send-email-jaimeliao@mxic.com.tw +--- + drivers/mtd/nand/spi/macronix.c | 112 ++++++++++++++++++++++++++++++++ + 1 file changed, 112 insertions(+) + +diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c +index 6701aaa21a49df..a9890350db0293 100644 +--- a/drivers/mtd/nand/spi/macronix.c ++++ b/drivers/mtd/nand/spi/macronix.c +@@ -186,6 +186,118 @@ static const struct spinand_info macronix_spinand_table[] = { + 0 /*SPINAND_HAS_QE_BIT*/, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), ++ ++ SPINAND_INFO("MX35LF2G14AC", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x20), ++ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1), ++ NAND_ECCREQ(4, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, ++ mx35lf1ge4ab_ecc_get_status)), ++ SPINAND_INFO("MX35UF4G24AD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb5), ++ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, ++ mx35lf1ge4ab_ecc_get_status)), ++ SPINAND_INFO("MX35UF4GE4AD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb7), ++ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, ++ mx35lf1ge4ab_ecc_get_status)), ++ SPINAND_INFO("MX35UF2G14AC", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa0), ++ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1), ++ NAND_ECCREQ(4, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, ++ mx35lf1ge4ab_ecc_get_status)), ++ SPINAND_INFO("MX35UF2G24AD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa4), ++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, ++ mx35lf1ge4ab_ecc_get_status)), ++ SPINAND_INFO("MX35UF2GE4AD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa6), ++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, ++ mx35lf1ge4ab_ecc_get_status)), ++ SPINAND_INFO("MX35UF2GE4AC", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa2), ++ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), ++ NAND_ECCREQ(4, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, ++ mx35lf1ge4ab_ecc_get_status)), ++ SPINAND_INFO("MX35UF1G14AC", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x90), ++ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(4, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, ++ mx35lf1ge4ab_ecc_get_status)), ++ SPINAND_INFO("MX35UF1G24AD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x94), ++ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, ++ mx35lf1ge4ab_ecc_get_status)), ++ SPINAND_INFO("MX35UF1GE4AD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x96), ++ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, ++ mx35lf1ge4ab_ecc_get_status)), ++ SPINAND_INFO("MX35UF1GE4AC", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92), ++ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(4, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, ++ mx35lf1ge4ab_ecc_get_status)), ++ + }; + + static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = { diff --git a/target/linux/generic/backport-5.4/435-mtd-spinand-macronix-Add-Quad-support-for-serial-NAND-flash.patch b/target/linux/generic/backport-5.4/435-mtd-spinand-macronix-Add-Quad-support-for-serial-NAND-flash.patch new file mode 100644 index 0000000000..cc6900afdb --- /dev/null +++ b/target/linux/generic/backport-5.4/435-mtd-spinand-macronix-Add-Quad-support-for-serial-NAND-flash.patch @@ -0,0 +1,88 @@ +From 6f802696c2faf0119781fc3b7977a4eedf9ab239 Mon Sep 17 00:00:00 2001 +From: Jaime Liao +Date: Mon, 9 Aug 2021 09:27:52 +0800 +Subject: [PATCH] mtd: spinand: macronix: Add Quad support for serial NAND + flash + +Adding FLAG "SPINAND_HAS_QE_BIT" for Quad mode support on Macronix +Serial Flash. +Validated via normal(default) and QUAD mode by read, erase, read back, +on Xilinx Zynq PicoZed FPGA board which included Macronix +SPI Host(drivers/spi/spi-mxic.c). + +Signed-off-by: Jaime Liao +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/1628472472-32008-1-git-send-email-jaimeliao@mxic.com.tw +--- + drivers/mtd/nand/spi/macronix.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c +index a9890350db0293..3f31f1381a62c0 100644 +--- a/drivers/mtd/nand/spi/macronix.c ++++ b/drivers/mtd/nand/spi/macronix.c +@@ -126,7 +126,7 @@ static const struct spinand_info macronix_spinand_table[] = { + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), +- 0, ++ SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), + SPINAND_INFO("MX35LF4GE4AD", +@@ -136,7 +136,7 @@ static const struct spinand_info macronix_spinand_table[] = { + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), +- 0, ++ SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), + SPINAND_INFO("MX35LF1G24AD", +@@ -146,16 +146,16 @@ static const struct spinand_info macronix_spinand_table[] = { + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), +- 0, ++ SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), + SPINAND_INFO("MX35LF2G24AD", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24), +- NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), ++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), +- 0, ++ SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), + SPINAND_INFO("MX35LF4G24AD", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35), +@@ -164,7 +164,7 @@ static const struct spinand_info macronix_spinand_table[] = { + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), +- 0, ++ SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), + SPINAND_INFO("MX31LF1GE4BC", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e), +@@ -173,7 +173,7 @@ static const struct spinand_info macronix_spinand_table[] = { + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), +- 0 /*SPINAND_HAS_QE_BIT*/, ++ SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), + SPINAND_INFO("MX31UF1GE4BC", +@@ -183,7 +183,7 @@ static const struct spinand_info macronix_spinand_table[] = { + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), +- 0 /*SPINAND_HAS_QE_BIT*/, ++ SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), + diff --git a/target/linux/generic/backport-5.4/450-mtd-spinand-micron-Generalize-the-OOB-layout-structure-and-function-names.patch b/target/linux/generic/backport-5.4/450-mtd-spinand-micron-Generalize-the-OOB-layout-structure-and-function-names.patch new file mode 100644 index 0000000000..b4fcfbc6d1 --- /dev/null +++ b/target/linux/generic/backport-5.4/450-mtd-spinand-micron-Generalize-the-OOB-layout-structure-and-function-names.patch @@ -0,0 +1,83 @@ +From d3137043440fb1faaaf2481184f35b9ed0c1f2c2 Mon Sep 17 00:00:00 2001 +From: Shivamurthy Shastri +Date: Wed, 11 Mar 2020 18:57:30 +0100 +Subject: [PATCH] mtd: spinand: micron: Generalize the OOB layout structure and + function names + +In order to add new Micron SPI NAND devices, we generalized the OOB +layout structure and function names. + +Signed-off-by: Shivamurthy Shastri +Reviewed-by: Boris Brezillon +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-2-sshivamurthy@micron.com +--- + drivers/mtd/nand/spi/micron.c | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c +index f56f81325e10ac..cc1ee68421c8e1 100644 +--- a/drivers/mtd/nand/spi/micron.c ++++ b/drivers/mtd/nand/spi/micron.c +@@ -34,38 +34,38 @@ static SPINAND_OP_VARIANTS(update_cache_variants, + SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), + SPINAND_PROG_LOAD(false, 0, NULL, 0)); + +-static int mt29f2g01abagd_ooblayout_ecc(struct mtd_info *mtd, int section, +- struct mtd_oob_region *region) ++static int micron_8_ooblayout_ecc(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *region) + { + if (section) + return -ERANGE; + +- region->offset = 64; +- region->length = 64; ++ region->offset = mtd->oobsize / 2; ++ region->length = mtd->oobsize / 2; + + return 0; + } + +-static int mt29f2g01abagd_ooblayout_free(struct mtd_info *mtd, int section, +- struct mtd_oob_region *region) ++static int micron_8_ooblayout_free(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *region) + { + if (section) + return -ERANGE; + + /* Reserve 2 bytes for the BBM. */ + region->offset = 2; +- region->length = 62; ++ region->length = (mtd->oobsize / 2) - 2; + + return 0; + } + +-static const struct mtd_ooblayout_ops mt29f2g01abagd_ooblayout = { +- .ecc = mt29f2g01abagd_ooblayout_ecc, +- .free = mt29f2g01abagd_ooblayout_free, ++static const struct mtd_ooblayout_ops micron_8_ooblayout = { ++ .ecc = micron_8_ooblayout_ecc, ++ .free = micron_8_ooblayout_free, + }; + +-static int mt29f2g01abagd_ecc_get_status(struct spinand_device *spinand, +- u8 status) ++static int micron_8_ecc_get_status(struct spinand_device *spinand, ++ u8 status) + { + switch (status & MICRON_STATUS_ECC_MASK) { + case STATUS_ECC_NO_BITFLIPS: +@@ -99,8 +99,8 @@ static const struct spinand_info micron_spinand_table[] = { + &write_cache_variants, + &update_cache_variants), + 0, +- SPINAND_ECCINFO(&mt29f2g01abagd_ooblayout, +- mt29f2g01abagd_ecc_get_status)), ++ SPINAND_ECCINFO(µn_8_ooblayout, ++ micron_8_ecc_get_status)), + }; + + static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = { diff --git a/target/linux/generic/backport-5.4/451-mtd-spinand-micron-Describe-the-SPI-NAND-device-MT29F2G01ABAGD.patch b/target/linux/generic/backport-5.4/451-mtd-spinand-micron-Describe-the-SPI-NAND-device-MT29F2G01ABAGD.patch new file mode 100644 index 0000000000..31141db92b --- /dev/null +++ b/target/linux/generic/backport-5.4/451-mtd-spinand-micron-Describe-the-SPI-NAND-device-MT29F2G01ABAGD.patch @@ -0,0 +1,29 @@ +From 8511a3a9937e30949b34bea46c3dc3f65d11034b Mon Sep 17 00:00:00 2001 +From: Shivamurthy Shastri +Date: Wed, 11 Mar 2020 18:57:31 +0100 +Subject: [PATCH] mtd: spinand: micron: Describe the SPI NAND device + MT29F2G01ABAGD + +Add the SPI NAND device MT29F2G01ABAGD series number, size and voltage +details as a comment. + +Signed-off-by: Shivamurthy Shastri +Reviewed-by: Boris Brezillon +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-3-sshivamurthy@micron.com +--- + drivers/mtd/nand/spi/micron.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c +index cc1ee68421c8e1..4727933c894bc8 100644 +--- a/drivers/mtd/nand/spi/micron.c ++++ b/drivers/mtd/nand/spi/micron.c +@@ -91,6 +91,7 @@ static int micron_8_ecc_get_status(struct spinand_device *spinand, + } + + static const struct spinand_info micron_spinand_table[] = { ++ /* M79A 2Gb 3.3V */ + SPINAND_INFO("MT29F2G01ABAGD", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1), diff --git a/target/linux/generic/backport-5.4/452-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices.patch b/target/linux/generic/backport-5.4/452-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices.patch new file mode 100644 index 0000000000..be3a3b197a --- /dev/null +++ b/target/linux/generic/backport-5.4/452-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices.patch @@ -0,0 +1,59 @@ +From a15335a17f4abf48ed9739c3b119232f9392cb60 Mon Sep 17 00:00:00 2001 +From: Shivamurthy Shastri +Date: Wed, 11 Mar 2020 18:57:32 +0100 +Subject: [PATCH] mtd: spinand: micron: Add new Micron SPI NAND devices + +Add device table for M79A and M78A series Micron SPI NAND devices. + +Signed-off-by: Shivamurthy Shastri +Reviewed-by: Boris Brezillon +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-4-sshivamurthy@micron.com +--- + drivers/mtd/nand/spi/micron.c | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c +index 4727933c894bc8..26925714a9fbac 100644 +--- a/drivers/mtd/nand/spi/micron.c ++++ b/drivers/mtd/nand/spi/micron.c +@@ -102,6 +102,39 @@ static const struct spinand_info micron_spinand_table[] = { + 0, + SPINAND_ECCINFO(µn_8_ooblayout, + micron_8_ecc_get_status)), ++ /* M79A 2Gb 1.8V */ ++ SPINAND_INFO("MT29F2G01ABBGD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25), ++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(µn_8_ooblayout, ++ micron_8_ecc_get_status)), ++ /* M78A 1Gb 3.3V */ ++ SPINAND_INFO("MT29F1G01ABAFD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14), ++ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(µn_8_ooblayout, ++ micron_8_ecc_get_status)), ++ /* M78A 1Gb 1.8V */ ++ SPINAND_INFO("MT29F1G01ABAFD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15), ++ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(µn_8_ooblayout, ++ micron_8_ecc_get_status)), + }; + + static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = { diff --git a/target/linux/generic/backport-5.4/453-mtd-spinand-micron-identify-SPI-NAND-device-with-Continuous-Read-mode.patch b/target/linux/generic/backport-5.4/453-mtd-spinand-micron-identify-SPI-NAND-device-with-Continuous-Read-mode.patch new file mode 100644 index 0000000000..59a42348c3 --- /dev/null +++ b/target/linux/generic/backport-5.4/453-mtd-spinand-micron-identify-SPI-NAND-device-with-Continuous-Read-mode.patch @@ -0,0 +1,79 @@ +From 0bc68af9137dc3f30b161de4ce546c7799f88d1e Mon Sep 17 00:00:00 2001 +From: Shivamurthy Shastri +Date: Wed, 11 Mar 2020 18:57:33 +0100 +Subject: [PATCH] mtd: spinand: micron: identify SPI NAND device with + Continuous Read mode + +Add SPINAND_HAS_CR_FEAT_BIT flag to identify the SPI NAND device with +the Continuous Read mode. + +Some of the Micron SPI NAND devices have the "Continuous Read" feature +enabled by default, which does not fit the subsystem needs. + +In this mode, the READ CACHE command doesn't require the starting column +address. The device always output the data starting from the first +column of the cache register, and once the end of the cache register +reached, the data output continues through the next page. With the +continuous read mode, it is possible to read out the entire block using +a single READ command, and once the end of the block reached, the output +pins become High-Z state. However, during this mode the read command +doesn't output the OOB area. + +Hence, we disable the feature at probe time. + +Signed-off-by: Shivamurthy Shastri +Reviewed-by: Boris Brezillon +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-5-sshivamurthy@micron.com +--- + drivers/mtd/nand/spi/micron.c | 16 ++++++++++++++++ + include/linux/mtd/spinand.h | 1 + + 2 files changed, 17 insertions(+) + +diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c +index 26925714a9fbac..956f7710aca263 100644 +--- a/drivers/mtd/nand/spi/micron.c ++++ b/drivers/mtd/nand/spi/micron.c +@@ -18,6 +18,8 @@ + #define MICRON_STATUS_ECC_4TO6_BITFLIPS (3 << 4) + #define MICRON_STATUS_ECC_7TO8_BITFLIPS (5 << 4) + ++#define MICRON_CFG_CR BIT(0) ++ + static SPINAND_OP_VARIANTS(read_cache_variants, + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), +@@ -137,7 +139,21 @@ static const struct spinand_info micron_spinand_table[] = { + micron_8_ecc_get_status)), + }; + ++static int micron_spinand_init(struct spinand_device *spinand) ++{ ++ /* ++ * M70A device series enable Continuous Read feature at Power-up, ++ * which is not supported. Disable this bit to avoid any possible ++ * failure. ++ */ ++ if (spinand->flags & SPINAND_HAS_CR_FEAT_BIT) ++ return spinand_upd_cfg(spinand, MICRON_CFG_CR, 0); ++ ++ return 0; ++} ++ + static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = { ++ .init = micron_spinand_init, + }; + + const struct spinand_manufacturer micron_spinand_manufacturer = { +diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h +index f4c4ae87181b27..1077c45721ff25 100644 +--- a/include/linux/mtd/spinand.h ++++ b/include/linux/mtd/spinand.h +@@ -284,6 +284,7 @@ struct spinand_ecc_info { + }; + + #define SPINAND_HAS_QE_BIT BIT(0) ++#define SPINAND_HAS_CR_FEAT_BIT BIT(1) + + /** + * struct spinand_info - Structure used to describe SPI NAND chips diff --git a/target/linux/generic/backport-5.4/454-mtd-spinand-micron-Add-M70A-series-Micron-SPI-NAND-devices.patch b/target/linux/generic/backport-5.4/454-mtd-spinand-micron-Add-M70A-series-Micron-SPI-NAND-devices.patch new file mode 100644 index 0000000000..158492f1dd --- /dev/null +++ b/target/linux/generic/backport-5.4/454-mtd-spinand-micron-Add-M70A-series-Micron-SPI-NAND-devices.patch @@ -0,0 +1,48 @@ +From a7e5daccc310c3b892ae5e598cadb7a9274c2547 Mon Sep 17 00:00:00 2001 +From: Shivamurthy Shastri +Date: Wed, 11 Mar 2020 18:57:34 +0100 +Subject: [PATCH] mtd: spinand: micron: Add M70A series Micron SPI NAND devices + +Add device table for M70A series Micron SPI NAND devices. + +Signed-off-by: Shivamurthy Shastri +Reviewed-by: Boris Brezillon +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-6-sshivamurthy@micron.com +--- + drivers/mtd/nand/spi/micron.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c +index 956f7710aca263..d6fd630087822c 100644 +--- a/drivers/mtd/nand/spi/micron.c ++++ b/drivers/mtd/nand/spi/micron.c +@@ -137,6 +137,28 @@ static const struct spinand_info micron_spinand_table[] = { + 0, + SPINAND_ECCINFO(µn_8_ooblayout, + micron_8_ecc_get_status)), ++ /* M70A 4Gb 3.3V */ ++ SPINAND_INFO("MT29F4G01ABAFD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x34), ++ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_CR_FEAT_BIT, ++ SPINAND_ECCINFO(µn_8_ooblayout, ++ micron_8_ecc_get_status)), ++ /* M70A 4Gb 1.8V */ ++ SPINAND_INFO("MT29F4G01ABBFD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35), ++ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_CR_FEAT_BIT, ++ SPINAND_ECCINFO(µn_8_ooblayout, ++ micron_8_ecc_get_status)), + }; + + static int micron_spinand_init(struct spinand_device *spinand) diff --git a/target/linux/generic/backport-5.4/455-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices-with-multiple-dies.patch b/target/linux/generic/backport-5.4/455-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices-with-multiple-dies.patch new file mode 100644 index 0000000000..8f8f1da15a --- /dev/null +++ b/target/linux/generic/backport-5.4/455-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices-with-multiple-dies.patch @@ -0,0 +1,109 @@ +From 9f9ae0c253c1e058fbc845e26c4a32a7d777f0dc Mon Sep 17 00:00:00 2001 +From: Shivamurthy Shastri +Date: Wed, 11 Mar 2020 18:57:35 +0100 +Subject: [PATCH] mtd: spinand: micron: Add new Micron SPI NAND devices with + multiple dies + +Add device table for new Micron SPI NAND devices, which have multiple +dies. + +Also, enable support to select the dies. + +Signed-off-by: Shivamurthy Shastri +Reviewed-by: Boris Brezillon +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-7-sshivamurthy@micron.com +--- + drivers/mtd/nand/spi/micron.c | 58 +++++++++++++++++++++++++++++++++++ + 1 file changed, 58 insertions(+) + +diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c +index d6fd630087822c..5d370cfcdaaaa9 100644 +--- a/drivers/mtd/nand/spi/micron.c ++++ b/drivers/mtd/nand/spi/micron.c +@@ -20,6 +20,14 @@ + + #define MICRON_CFG_CR BIT(0) + ++/* ++ * As per datasheet, die selection is done by the 6th bit of Die ++ * Select Register (Address 0xD0). ++ */ ++#define MICRON_DIE_SELECT_REG 0xD0 ++ ++#define MICRON_SELECT_DIE(x) ((x) << 6) ++ + static SPINAND_OP_VARIANTS(read_cache_variants, + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), +@@ -66,6 +74,20 @@ static const struct mtd_ooblayout_ops micron_8_ooblayout = { + .free = micron_8_ooblayout_free, + }; + ++static int micron_select_target(struct spinand_device *spinand, ++ unsigned int target) ++{ ++ struct spi_mem_op op = SPINAND_SET_FEATURE_OP(MICRON_DIE_SELECT_REG, ++ spinand->scratchbuf); ++ ++ if (target > 1) ++ return -EINVAL; ++ ++ *spinand->scratchbuf = MICRON_SELECT_DIE(target); ++ ++ return spi_mem_exec_op(spinand->spimem, &op); ++} ++ + static int micron_8_ecc_get_status(struct spinand_device *spinand, + u8 status) + { +@@ -137,6 +159,18 @@ static const struct spinand_info micron_spinand_table[] = { + 0, + SPINAND_ECCINFO(µn_8_ooblayout, + micron_8_ecc_get_status)), ++ /* M79A 4Gb 3.3V */ ++ SPINAND_INFO("MT29F4G01ADAGD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x36), ++ NAND_MEMORG(1, 2048, 128, 64, 2048, 80, 2, 1, 2), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(µn_8_ooblayout, ++ micron_8_ecc_get_status), ++ SPINAND_SELECT_TARGET(micron_select_target)), + /* M70A 4Gb 3.3V */ + SPINAND_INFO("MT29F4G01ABAFD", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x34), +@@ -159,6 +193,30 @@ static const struct spinand_info micron_spinand_table[] = { + SPINAND_HAS_CR_FEAT_BIT, + SPINAND_ECCINFO(µn_8_ooblayout, + micron_8_ecc_get_status)), ++ /* M70A 8Gb 3.3V */ ++ SPINAND_INFO("MT29F8G01ADAFD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x46), ++ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_CR_FEAT_BIT, ++ SPINAND_ECCINFO(µn_8_ooblayout, ++ micron_8_ecc_get_status), ++ SPINAND_SELECT_TARGET(micron_select_target)), ++ /* M70A 8Gb 1.8V */ ++ SPINAND_INFO("MT29F8G01ADBFD", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x47), ++ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ SPINAND_HAS_CR_FEAT_BIT, ++ SPINAND_ECCINFO(µn_8_ooblayout, ++ micron_8_ecc_get_status), ++ SPINAND_SELECT_TARGET(micron_select_target)), + }; + + static int micron_spinand_init(struct spinand_device *spinand) diff --git a/target/linux/generic/backport-5.4/456-mtd-spinand-micron-Use-more-specific-names.patch b/target/linux/generic/backport-5.4/456-mtd-spinand-micron-Use-more-specific-names.patch new file mode 100644 index 0000000000..ec03ffeab3 --- /dev/null +++ b/target/linux/generic/backport-5.4/456-mtd-spinand-micron-Use-more-specific-names.patch @@ -0,0 +1,159 @@ +From bdb84a22b02b0c2ca76bb3e3e16942338f67999b Mon Sep 17 00:00:00 2001 +From: Thirumalesha Narasimhappa +Date: Sun, 8 Nov 2020 19:37:34 +0800 +Subject: [PATCH] mtd: spinand: micron: Use more specific names + +Rename the read/write/update of SPINAND_OP_VARIANTS() to more +specialized names. + +Signed-off-by: Thirumalesha Narasimhappa +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20201108113735.2533-2-nthirumalesha7@gmail.com +--- + drivers/mtd/nand/spi/micron.c | 60 +++++++++++++++++------------------ + 1 file changed, 30 insertions(+), 30 deletions(-) + +diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c +index 5d370cfcdaaaa9..afe3ba37dcfb8e 100644 +--- a/drivers/mtd/nand/spi/micron.c ++++ b/drivers/mtd/nand/spi/micron.c +@@ -28,7 +28,7 @@ + + #define MICRON_SELECT_DIE(x) ((x) << 6) + +-static SPINAND_OP_VARIANTS(read_cache_variants, ++static SPINAND_OP_VARIANTS(quadio_read_cache_variants, + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), +@@ -36,11 +36,11 @@ static SPINAND_OP_VARIANTS(read_cache_variants, + SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); + +-static SPINAND_OP_VARIANTS(write_cache_variants, ++static SPINAND_OP_VARIANTS(x4_write_cache_variants, + SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), + SPINAND_PROG_LOAD(true, 0, NULL, 0)); + +-static SPINAND_OP_VARIANTS(update_cache_variants, ++static SPINAND_OP_VARIANTS(x4_update_cache_variants, + SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), + SPINAND_PROG_LOAD(false, 0, NULL, 0)); + +@@ -120,9 +120,9 @@ static const struct spinand_info micron_spinand_table[] = { + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1), + NAND_ECCREQ(8, 512), +- SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +- &write_cache_variants, +- &update_cache_variants), ++ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, ++ &x4_write_cache_variants, ++ &x4_update_cache_variants), + 0, + SPINAND_ECCINFO(µn_8_ooblayout, + micron_8_ecc_get_status)), +@@ -131,9 +131,9 @@ static const struct spinand_info micron_spinand_table[] = { + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1), + NAND_ECCREQ(8, 512), +- SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +- &write_cache_variants, +- &update_cache_variants), ++ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, ++ &x4_write_cache_variants, ++ &x4_update_cache_variants), + 0, + SPINAND_ECCINFO(µn_8_ooblayout, + micron_8_ecc_get_status)), +@@ -142,9 +142,9 @@ static const struct spinand_info micron_spinand_table[] = { + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(8, 512), +- SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +- &write_cache_variants, +- &update_cache_variants), ++ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, ++ &x4_write_cache_variants, ++ &x4_update_cache_variants), + 0, + SPINAND_ECCINFO(µn_8_ooblayout, + micron_8_ecc_get_status)), +@@ -153,9 +153,9 @@ static const struct spinand_info micron_spinand_table[] = { + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(8, 512), +- SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +- &write_cache_variants, +- &update_cache_variants), ++ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, ++ &x4_write_cache_variants, ++ &x4_update_cache_variants), + 0, + SPINAND_ECCINFO(µn_8_ooblayout, + micron_8_ecc_get_status)), +@@ -164,9 +164,9 @@ static const struct spinand_info micron_spinand_table[] = { + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x36), + NAND_MEMORG(1, 2048, 128, 64, 2048, 80, 2, 1, 2), + NAND_ECCREQ(8, 512), +- SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +- &write_cache_variants, +- &update_cache_variants), ++ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, ++ &x4_write_cache_variants, ++ &x4_update_cache_variants), + 0, + SPINAND_ECCINFO(µn_8_ooblayout, + micron_8_ecc_get_status), +@@ -176,9 +176,9 @@ static const struct spinand_info micron_spinand_table[] = { + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x34), + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), +- SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +- &write_cache_variants, +- &update_cache_variants), ++ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, ++ &x4_write_cache_variants, ++ &x4_update_cache_variants), + SPINAND_HAS_CR_FEAT_BIT, + SPINAND_ECCINFO(µn_8_ooblayout, + micron_8_ecc_get_status)), +@@ -187,9 +187,9 @@ static const struct spinand_info micron_spinand_table[] = { + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35), + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), +- SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +- &write_cache_variants, +- &update_cache_variants), ++ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, ++ &x4_write_cache_variants, ++ &x4_update_cache_variants), + SPINAND_HAS_CR_FEAT_BIT, + SPINAND_ECCINFO(µn_8_ooblayout, + micron_8_ecc_get_status)), +@@ -198,9 +198,9 @@ static const struct spinand_info micron_spinand_table[] = { + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x46), + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2), + NAND_ECCREQ(8, 512), +- SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +- &write_cache_variants, +- &update_cache_variants), ++ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, ++ &x4_write_cache_variants, ++ &x4_update_cache_variants), + SPINAND_HAS_CR_FEAT_BIT, + SPINAND_ECCINFO(µn_8_ooblayout, + micron_8_ecc_get_status), +@@ -210,9 +210,9 @@ static const struct spinand_info micron_spinand_table[] = { + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x47), + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2), + NAND_ECCREQ(8, 512), +- SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +- &write_cache_variants, +- &update_cache_variants), ++ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants, ++ &x4_write_cache_variants, ++ &x4_update_cache_variants), + SPINAND_HAS_CR_FEAT_BIT, + SPINAND_ECCINFO(µn_8_ooblayout, + micron_8_ecc_get_status), diff --git a/target/linux/generic/backport-5.4/457-mtd-spinand-micron-Add-support-for-MT29F2G01AAAED.patch b/target/linux/generic/backport-5.4/457-mtd-spinand-micron-Add-support-for-MT29F2G01AAAED.patch new file mode 100644 index 0000000000..ecd2b71b05 --- /dev/null +++ b/target/linux/generic/backport-5.4/457-mtd-spinand-micron-Add-support-for-MT29F2G01AAAED.patch @@ -0,0 +1,104 @@ +From 8c573d9419bf61f7b66b6114f1171f3a8a4a0e38 Mon Sep 17 00:00:00 2001 +From: Thirumalesha Narasimhappa +Date: Sun, 8 Nov 2020 19:37:35 +0800 +Subject: [PATCH] mtd: spinand: micron: Add support for MT29F2G01AAAED + +The MT29F2G01AAAED is a single die, 2Gb Micron SPI NAND Flash with 4-bit +ECC + +Signed-off-by: Thirumalesha Narasimhappa +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20201108113735.2533-3-nthirumalesha7@gmail.com +--- + drivers/mtd/nand/spi/micron.c | 64 +++++++++++++++++++++++++++++++++++ + 1 file changed, 64 insertions(+) + +diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c +index afe3ba37dcfb8e..50b7295bc92226 100644 +--- a/drivers/mtd/nand/spi/micron.c ++++ b/drivers/mtd/nand/spi/micron.c +@@ -44,6 +44,19 @@ static SPINAND_OP_VARIANTS(x4_update_cache_variants, + SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), + SPINAND_PROG_LOAD(false, 0, NULL, 0)); + ++/* Micron MT29F2G01AAAED Device */ ++static SPINAND_OP_VARIANTS(x4_read_cache_variants, ++ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), ++ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), ++ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), ++ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); ++ ++static SPINAND_OP_VARIANTS(x1_write_cache_variants, ++ SPINAND_PROG_LOAD(true, 0, NULL, 0)); ++ ++static SPINAND_OP_VARIANTS(x1_update_cache_variants, ++ SPINAND_PROG_LOAD(false, 0, NULL, 0)); ++ + static int micron_8_ooblayout_ecc(struct mtd_info *mtd, int section, + struct mtd_oob_region *region) + { +@@ -74,6 +87,47 @@ static const struct mtd_ooblayout_ops micron_8_ooblayout = { + .free = micron_8_ooblayout_free, + }; + ++static int micron_4_ooblayout_ecc(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *region) ++{ ++ struct spinand_device *spinand = mtd_to_spinand(mtd); ++ ++ if (section >= spinand->base.memorg.pagesize / ++ mtd->ecc_step_size) ++ return -ERANGE; ++ ++ region->offset = (section * 16) + 8; ++ region->length = 8; ++ ++ return 0; ++} ++ ++static int micron_4_ooblayout_free(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *region) ++{ ++ struct spinand_device *spinand = mtd_to_spinand(mtd); ++ ++ if (section >= spinand->base.memorg.pagesize / ++ mtd->ecc_step_size) ++ return -ERANGE; ++ ++ if (section) { ++ region->offset = 16 * section; ++ region->length = 8; ++ } else { ++ /* section 0 has two bytes reserved for the BBM */ ++ region->offset = 2; ++ region->length = 6; ++ } ++ ++ return 0; ++} ++ ++static const struct mtd_ooblayout_ops micron_4_ooblayout = { ++ .ecc = micron_4_ooblayout_ecc, ++ .free = micron_4_ooblayout_free, ++}; ++ + static int micron_select_target(struct spinand_device *spinand, + unsigned int target) + { +@@ -217,6 +271,16 @@ static const struct spinand_info micron_spinand_table[] = { + SPINAND_ECCINFO(µn_8_ooblayout, + micron_8_ecc_get_status), + SPINAND_SELECT_TARGET(micron_select_target)), ++ /* M69A 2Gb 3.3V */ ++ SPINAND_INFO("MT29F2G01AAAED", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9F), ++ NAND_MEMORG(1, 2048, 64, 64, 2048, 80, 2, 1, 1), ++ NAND_ECCREQ(4, 512), ++ SPINAND_INFO_OP_VARIANTS(&x4_read_cache_variants, ++ &x1_write_cache_variants, ++ &x1_update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(µn_4_ooblayout, NULL)), + }; + + static int micron_spinand_init(struct spinand_device *spinand) diff --git a/target/linux/generic/backport-5.4/470-mtd-spinand-toshiba-Rename-function-name-to-change-suffix-and-prefix-8Gbit.patch b/target/linux/generic/backport-5.4/470-mtd-spinand-toshiba-Rename-function-name-to-change-suffix-and-prefix-8Gbit.patch new file mode 100644 index 0000000000..80672e6d9c --- /dev/null +++ b/target/linux/generic/backport-5.4/470-mtd-spinand-toshiba-Rename-function-name-to-change-suffix-and-prefix-8Gbit.patch @@ -0,0 +1,170 @@ +From 6b49e58d6d9dab031a16af2af5439f28a37c4cd9 Mon Sep 17 00:00:00 2001 +From: Yoshio Furuyama +Date: Tue, 24 Mar 2020 15:49:44 +0900 +Subject: [PATCH] mtd: spinand: toshiba: Rename function name to change suffix + and prefix (8Gbit) + +The suffix was changed from "G" to "J" to classify between 1st generation +and 2nd generation serial NAND devices (which now belong to the Kioxia +brand). +As reference that's +1st generation device of 1Gbit product is "TC58CVG0S3HRAIG" +2nd generation device of 1Gbit product is "TC58CVG0S3HRAIJ". + +The 8Gbit type "TH58CxG3S0HRAIJ" is new to Kioxia's serial NAND lineup and +the prefix was changed from "TC58" to "TH58". + +Thus the functions were renamed from tc58cxgxsx_*() to tx58cxgxsxraix_*(). + +Signed-off-by: Yoshio Furuyama +Reviewed-by: Frieder Schrempf +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/0dedd9869569a17625822dba87878254d253ba0e.1584949601.git.ytc-mb-yfuruyama7@kioxia.com +--- + drivers/mtd/nand/spi/toshiba.c | 60 +++++++++++++++++----------------- + 1 file changed, 30 insertions(+), 30 deletions(-) + +--- a/drivers/mtd/nand/spi/toshiba.c ++++ b/drivers/mtd/nand/spi/toshiba.c +@@ -25,8 +25,8 @@ static SPINAND_OP_VARIANTS(write_cache_v + static SPINAND_OP_VARIANTS(update_cache_variants, + SPINAND_PROG_LOAD(false, 0, NULL, 0)); + +-static int tc58cxgxsx_ooblayout_ecc(struct mtd_info *mtd, int section, +- struct mtd_oob_region *region) ++static int tx58cxgxsxraix_ooblayout_ecc(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *region) + { + if (section > 0) + return -ERANGE; +@@ -37,8 +37,8 @@ static int tc58cxgxsx_ooblayout_ecc(stru + return 0; + } + +-static int tc58cxgxsx_ooblayout_free(struct mtd_info *mtd, int section, +- struct mtd_oob_region *region) ++static int tx58cxgxsxraix_ooblayout_free(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *region) + { + if (section > 0) + return -ERANGE; +@@ -50,13 +50,13 @@ static int tc58cxgxsx_ooblayout_free(str + return 0; + } + +-static const struct mtd_ooblayout_ops tc58cxgxsx_ooblayout = { +- .ecc = tc58cxgxsx_ooblayout_ecc, +- .free = tc58cxgxsx_ooblayout_free, ++static const struct mtd_ooblayout_ops tx58cxgxsxraix_ooblayout = { ++ .ecc = tx58cxgxsxraix_ooblayout_ecc, ++ .free = tx58cxgxsxraix_ooblayout_free, + }; + +-static int tc58cxgxsx_ecc_get_status(struct spinand_device *spinand, +- u8 status) ++static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand, ++ u8 status) + { + struct nand_device *nand = spinand_to_nand(spinand); + u8 mbf = 0; +@@ -95,7 +95,7 @@ static int tc58cxgxsx_ecc_get_status(str + + static const struct spinand_info toshiba_spinand_table[] = { + /* 3.3V 1Gb */ +- SPINAND_INFO("TC58CVG0S3", ++ SPINAND_INFO("TC58CVG0S3HRAIG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC2), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(8, 512), +@@ -103,10 +103,10 @@ static const struct spinand_info toshiba + &write_cache_variants, + &update_cache_variants), + 0, +- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, +- tc58cxgxsx_ecc_get_status)), ++ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, ++ tx58cxgxsxraix_ecc_get_status)), + /* 3.3V 2Gb */ +- SPINAND_INFO("TC58CVG1S3", ++ SPINAND_INFO("TC58CVG1S3HRAIG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), +@@ -114,10 +114,10 @@ static const struct spinand_info toshiba + &write_cache_variants, + &update_cache_variants), + 0, +- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, +- tc58cxgxsx_ecc_get_status)), ++ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, ++ tx58cxgxsxraix_ecc_get_status)), + /* 3.3V 4Gb */ +- SPINAND_INFO("TC58CVG2S0", ++ SPINAND_INFO("TC58CVG2S0HRAIG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD), + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), +@@ -125,10 +125,21 @@ static const struct spinand_info toshiba + &write_cache_variants, + &update_cache_variants), + 0, +- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, +- tc58cxgxsx_ecc_get_status)), ++ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, ++ tx58cxgxsxraix_ecc_get_status)), ++ /* 3.3V 4Gb */ ++ SPINAND_INFO("TC58CVG2S0HRAIJ", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xED), ++ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, ++ tx58cxgxsxraix_ecc_get_status)), + /* 1.8V 1Gb */ +- SPINAND_INFO("TC58CYG0S3", ++ SPINAND_INFO("TC58CYG0S3HRAIG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(8, 512), +@@ -136,10 +147,10 @@ static const struct spinand_info toshiba + &write_cache_variants, + &update_cache_variants), + 0, +- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, +- tc58cxgxsx_ecc_get_status)), ++ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, ++ tx58cxgxsxraix_ecc_get_status)), + /* 1.8V 2Gb */ +- SPINAND_INFO("TC58CYG1S3", ++ SPINAND_INFO("TC58CYG1S3HRAIG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), +@@ -147,10 +158,10 @@ static const struct spinand_info toshiba + &write_cache_variants, + &update_cache_variants), + 0, +- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, +- tc58cxgxsx_ecc_get_status)), ++ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, ++ tx58cxgxsxraix_ecc_get_status)), + /* 1.8V 4Gb */ +- SPINAND_INFO("TC58CYG2S0", ++ SPINAND_INFO("TC58CYG2S0HRAIG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD), + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), +@@ -158,8 +169,8 @@ static const struct spinand_info toshiba + &write_cache_variants, + &update_cache_variants), + 0, +- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout, +- tc58cxgxsx_ecc_get_status)), ++ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, ++ tx58cxgxsxraix_ecc_get_status)), + }; + + static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = { diff --git a/target/linux/generic/backport-5.4/471-mtd-spinand-toshiba-Support-for-new-Kioxia-Serial-NAND.patch b/target/linux/generic/backport-5.4/471-mtd-spinand-toshiba-Support-for-new-Kioxia-Serial-NAND.patch new file mode 100644 index 0000000000..ffa1ad8986 --- /dev/null +++ b/target/linux/generic/backport-5.4/471-mtd-spinand-toshiba-Support-for-new-Kioxia-Serial-NAND.patch @@ -0,0 +1,205 @@ +From 798fcdd010006e87b3154d6454c657af7b033002 Mon Sep 17 00:00:00 2001 +From: Yoshio Furuyama +Date: Tue, 24 Mar 2020 15:49:55 +0900 +Subject: [PATCH] mtd: spinand: toshiba: Support for new Kioxia Serial NAND + +Add support for new Kioxia products. +The new Kioxia products support program load x4 command, and have +HOLD_D bit which is equivalent to QE bit. + +Signed-off-by: Yoshio Furuyama +Reviewed-by: Frieder Schrempf +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/aa69e455beedc5ce0d7141359b9364ed8aec9e65.1584949601.git.ytc-mb-yfuruyama7@kioxia.com +--- + drivers/mtd/nand/spi/toshiba.c | 128 ++++++++++++++++++++++++++++----- + 1 file changed, 111 insertions(+), 17 deletions(-) + +diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c +index 5d217dd4b2539a..bc801d83343e5c 100644 +--- a/drivers/mtd/nand/spi/toshiba.c ++++ b/drivers/mtd/nand/spi/toshiba.c +@@ -20,6 +20,18 @@ static SPINAND_OP_VARIANTS(read_cache_variants, + SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); + ++static SPINAND_OP_VARIANTS(write_cache_x4_variants, ++ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), ++ SPINAND_PROG_LOAD(true, 0, NULL, 0)); ++ ++static SPINAND_OP_VARIANTS(update_cache_x4_variants, ++ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), ++ SPINAND_PROG_LOAD(false, 0, NULL, 0)); ++ ++/** ++ * Backward compatibility for 1st generation Serial NAND devices ++ * which don't support Quad Program Load operation. ++ */ + static SPINAND_OP_VARIANTS(write_cache_variants, + SPINAND_PROG_LOAD(true, 0, NULL, 0)); + +@@ -95,7 +107,7 @@ static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand, + } + + static const struct spinand_info toshiba_spinand_table[] = { +- /* 3.3V 1Gb */ ++ /* 3.3V 1Gb (1st generation) */ + SPINAND_INFO("TC58CVG0S3HRAIG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC2), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), +@@ -106,7 +118,7 @@ static const struct spinand_info toshiba_spinand_table[] = { + 0, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), +- /* 3.3V 2Gb */ ++ /* 3.3V 2Gb (1st generation) */ + SPINAND_INFO("TC58CVG1S3HRAIG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), +@@ -117,7 +129,7 @@ static const struct spinand_info toshiba_spinand_table[] = { + 0, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), +- /* 3.3V 4Gb */ ++ /* 3.3V 4Gb (1st generation) */ + SPINAND_INFO("TC58CVG2S0HRAIG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD), + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), +@@ -128,18 +140,7 @@ static const struct spinand_info toshiba_spinand_table[] = { + 0, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), +- /* 3.3V 4Gb */ +- SPINAND_INFO("TC58CVG2S0HRAIJ", +- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xED), +- NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), +- NAND_ECCREQ(8, 512), +- SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +- &write_cache_variants, +- &update_cache_variants), +- 0, +- SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, +- tx58cxgxsxraix_ecc_get_status)), +- /* 1.8V 1Gb */ ++ /* 1.8V 1Gb (1st generation) */ + SPINAND_INFO("TC58CYG0S3HRAIG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), +@@ -150,7 +151,7 @@ static const struct spinand_info toshiba_spinand_table[] = { + 0, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), +- /* 1.8V 2Gb */ ++ /* 1.8V 2Gb (1st generation) */ + SPINAND_INFO("TC58CYG1S3HRAIG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), +@@ -161,7 +162,7 @@ static const struct spinand_info toshiba_spinand_table[] = { + 0, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), +- /* 1.8V 4Gb */ ++ /* 1.8V 4Gb (1st generation) */ + SPINAND_INFO("TC58CYG2S0HRAIG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD), + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), +@@ -172,6 +173,99 @@ static const struct spinand_info toshiba_spinand_table[] = { + 0, + SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, + tx58cxgxsxraix_ecc_get_status)), ++ ++ /* ++ * 2nd generation serial nand has HOLD_D which is equivalent to ++ * QE_BIT. ++ */ ++ /* 3.3V 1Gb (2nd generation) */ ++ SPINAND_INFO("TC58CVG0S3HRAIJ", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE2), ++ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_x4_variants, ++ &update_cache_x4_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, ++ tx58cxgxsxraix_ecc_get_status)), ++ /* 3.3V 2Gb (2nd generation) */ ++ SPINAND_INFO("TC58CVG1S3HRAIJ", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEB), ++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_x4_variants, ++ &update_cache_x4_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, ++ tx58cxgxsxraix_ecc_get_status)), ++ /* 3.3V 4Gb (2nd generation) */ ++ SPINAND_INFO("TC58CVG2S0HRAIJ", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xED), ++ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_x4_variants, ++ &update_cache_x4_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, ++ tx58cxgxsxraix_ecc_get_status)), ++ /* 3.3V 8Gb (2nd generation) */ ++ SPINAND_INFO("TH58CVG3S0HRAIJ", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4), ++ NAND_MEMORG(1, 4096, 256, 64, 4096, 80, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_x4_variants, ++ &update_cache_x4_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, ++ tx58cxgxsxraix_ecc_get_status)), ++ /* 1.8V 1Gb (2nd generation) */ ++ SPINAND_INFO("TC58CYG0S3HRAIJ", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD2), ++ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_x4_variants, ++ &update_cache_x4_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, ++ tx58cxgxsxraix_ecc_get_status)), ++ /* 1.8V 2Gb (2nd generation) */ ++ SPINAND_INFO("TC58CYG1S3HRAIJ", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDB), ++ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_x4_variants, ++ &update_cache_x4_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, ++ tx58cxgxsxraix_ecc_get_status)), ++ /* 1.8V 4Gb (2nd generation) */ ++ SPINAND_INFO("TC58CYG2S0HRAIJ", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDD), ++ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_x4_variants, ++ &update_cache_x4_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, ++ tx58cxgxsxraix_ecc_get_status)), ++ /* 1.8V 8Gb (2nd generation) */ ++ SPINAND_INFO("TH58CYG3S0HRAIJ", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD4), ++ NAND_MEMORG(1, 4096, 256, 64, 4096, 80, 1, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_x4_variants, ++ &update_cache_x4_variants), ++ SPINAND_HAS_QE_BIT, ++ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, ++ tx58cxgxsxraix_ecc_get_status)), + }; + + static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = { diff --git a/target/linux/generic/backport-5.4/827-v5.16-spi-add-power-control-when-set_cs.patch b/target/linux/generic/backport-5.4/827-v5.16-spi-add-power-control-when-set_cs.patch new file mode 100644 index 0000000000..f3e7940d29 --- /dev/null +++ b/target/linux/generic/backport-5.4/827-v5.16-spi-add-power-control-when-set_cs.patch @@ -0,0 +1,47 @@ +drivers: spi: backport PM improvement for SPI framework + +Fix PM improvement for SPI framework. +As to set_cs takes effect immediately, power spi +is needed when setup spi. + +(cherry picked from commit d948e6ca189985495a21cd622c31e30e72b6b688) +Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/spi/spi.c?h=v5.16-rc4&id=d948e6ca189985495a21cd622c31e30e72b6b688 +(cherry picked from commit 57a9460705f105e1d79d1410c5cfe285beda8986) +Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/spi/spi.c?h=v5.16-rc4&id=57a9460705f105e1d79d1410c5cfe285beda8986 + +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -3170,7 +3170,29 @@ int spi_setup(struct spi_device *spi) + if (spi->controller->setup) + status = spi->controller->setup(spi); + +- spi_set_cs(spi, false); ++ if (spi->controller->auto_runtime_pm && spi->controller->set_cs) { ++ status = pm_runtime_get_sync(spi->controller->dev.parent); ++ if (status < 0) { ++ pm_runtime_put_noidle(spi->controller->dev.parent); ++ dev_err(&spi->controller->dev, "Failed to power device: %d\n", ++ status); ++ return status; ++ } ++ ++ /* ++ * We do not want to return positive value from pm_runtime_get, ++ * there are many instances of devices calling spi_setup() and ++ * checking for a non-zero return value instead of a negative ++ * return value. ++ */ ++ status = 0; ++ ++ spi_set_cs(spi, false); ++ pm_runtime_mark_last_busy(spi->controller->dev.parent); ++ pm_runtime_put_autosuspend(spi->controller->dev.parent); ++ } else { ++ spi_set_cs(spi, false); ++ } + + if (spi->rt && !spi->controller->rt) { + spi->controller->rt = true; +-- +2.18.0 + diff --git a/target/linux/generic/pending-5.4/499-mtd-add-nmbm-support.patch b/target/linux/generic/pending-5.4/499-mtd-add-nmbm-support.patch new file mode 100644 index 0000000000..5cbaae2b7b --- /dev/null +++ b/target/linux/generic/pending-5.4/499-mtd-add-nmbm-support.patch @@ -0,0 +1,21 @@ +--- a/drivers/mtd/Kconfig ++++ b/drivers/mtd/Kconfig +@@ -228,6 +228,8 @@ source "drivers/mtd/ubi/Kconfig" + + source "drivers/mtd/hyperbus/Kconfig" + ++source "drivers/mtd/nmbm/Kconfig" ++ + source "drivers/mtd/composite/Kconfig" + + endif # MTD +--- a/drivers/mtd/Makefile ++++ b/drivers/mtd/Makefile +@@ -33,5 +33,7 @@ obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ + obj-$(CONFIG_MTD_UBI) += ubi/ + obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/ + ++obj-y += nmbm/ ++ + # Composite drivers must be loaded last + obj-y += composite/ diff --git a/target/linux/generic/pending-5.4/500-ubi-add-configurable-rootdev.patch b/target/linux/generic/pending-5.4/500-ubi-add-configurable-rootdev.patch new file mode 100644 index 0000000000..e0102c7568 --- /dev/null +++ b/target/linux/generic/pending-5.4/500-ubi-add-configurable-rootdev.patch @@ -0,0 +1,35 @@ +--- a/drivers/mtd/ubi/block.c ++++ b/drivers/mtd/ubi/block.c +@@ -97,6 +97,12 @@ static DEFINE_IDR(ubiblock_minor_idr); + static DEFINE_MUTEX(devices_mutex); + static int ubiblock_major; + ++static char rootfs_volume[256] = "rootfs"; ++module_param_string(rootfs_volume, rootfs_volume, sizeof(rootfs_volume), 0444); ++ ++static bool no_default_rootdev; ++module_param(no_default_rootdev, bool, 0444); ++ + static int __init ubiblock_set_param(const char *val, + const struct kernel_param *kp) + { +@@ -460,8 +466,9 @@ int ubiblock_create(struct ubi_volume_in + dev->ubi_num, dev->vol_id, vi->name); + mutex_unlock(&devices_mutex); + +- if (!strcmp(vi->name, "rootfs") && ++ if (!strcmp(vi->name, rootfs_volume) && + IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && ++ !no_default_rootdev && + ROOT_DEV == 0) { + pr_notice("ubiblock: device ubiblock%d_%d (%s) set to be root filesystem\n", + dev->ubi_num, dev->vol_id, vi->name); +@@ -681,7 +688,7 @@ static void __init ubiblock_create_auto_ + struct ubi_volume_info vi; + + for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) { +- desc = ubi_open_volume_nm(ubi_num, "rootfs", UBI_READONLY); ++ desc = ubi_open_volume_nm(ubi_num, rootfs_volume, UBI_READONLY); + if (IS_ERR(desc)) + continue; +