From 273a60fe62c6768efd5e3c521c0b36dcc1b793ae Mon Sep 17 00:00:00 2001 From: Vincent Wiemann Date: Sun, 4 Feb 2018 17:42:48 +0100 Subject: [PATCH] ramips-mt7621: Add support for ZBT-WG3526-32M (#1296) including backport of mtd patches. The general flash issue (32MB) was discussed here: https://gist.github.com/dmke/d389bc364b3f73f525076eaee0019dc1 The resulting patch was the following: http://lists.infradead.org/pipermail/linux-mtd/2016-December/070889.html Another patch by nbd168 added the required mtd read operations for supporting ZBT-WG3526-32M: https://github.com/lede-project/source/commit/22d982e#diff-3835f027e16e6416090c1833bc732af3 --- ...d-4-byte-addressing-on-w25q256-flash.patch | 456 ++++++++++++++++++ ...are-ZBT-WG3526-for-hardware-variants.patch | 99 ++++ ...igineo-AC1200-Pro-to-ZBT-WG3526-32MB.patch | 193 ++++++++ targets/ramips-mt7621 | 6 +- 4 files changed, 753 insertions(+), 1 deletion(-) create mode 100644 patches/lede/0064-ramips-mtd-spi-nor-add-support-for-switching-between-3-byte-and-4-byte-addressing-on-w25q256-flash.patch create mode 100644 patches/lede/0065-ramips-prepare-ZBT-WG3526-for-hardware-variants.patch create mode 100644 patches/lede/0066-ramips-rename-Digineo-AC1200-Pro-to-ZBT-WG3526-32MB.patch diff --git a/patches/lede/0064-ramips-mtd-spi-nor-add-support-for-switching-between-3-byte-and-4-byte-addressing-on-w25q256-flash.patch b/patches/lede/0064-ramips-mtd-spi-nor-add-support-for-switching-between-3-byte-and-4-byte-addressing-on-w25q256-flash.patch new file mode 100644 index 00000000..db75be88 --- /dev/null +++ b/patches/lede/0064-ramips-mtd-spi-nor-add-support-for-switching-between-3-byte-and-4-byte-addressing-on-w25q256-flash.patch @@ -0,0 +1,456 @@ +From: Vincent Wiemann +Date: Sat, 6 Jan 2018 04:33:09 +0100 +Subject: ramips: mtd: spi-nor: add support for switching between 3-byte and 4-byte addressing on w25q256 flash + +CAUTION! NEEDS TESTING! +Tries to backport switching between 3-byte and 4-byte addressing on w25q256 flash from Lede master (62ede4f78389c313a8004e79330a7d055eda2f7d) by Felix Fietkau. + +Applied patches: +mtd: spi-nor: rename SPINOR_OP_* macros of the 4-byte address op codes +mtd: spi-nor: add a stateless method to support memory size above 128Mib +mtd: spi-nor: add w25q256 3b-mode-switch +mtd: add chunked read-io to m25p80 + +On some devices the flash chip needs to be in 3-byte addressing mode during +reboot, otherwise the boot loader will fail to start. +This mode however does not allow regular reads/writes onto the upper 16M +half. W25Q256 has separate read commands for reading from >16M, however +it does not have any separate write commands. +This patch changes the code to leave the chip in 3-byte mode most of the +time and only switch during erase/write cycles that go to >16M +addresses. + +Signed-off-by: Vincent Wiemann (me@bibbl.com) + +diff --git a/target/linux/ramips/patches-4.4/400-mtd-spi-nor-add-w25q256-3b-mode-switch.patch b/target/linux/ramips/patches-4.4/400-mtd-spi-nor-add-w25q256-3b-mode-switch.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..5399f547e4edd0eb1cfee8c1ec5b35e69c692ee9 +--- /dev/null ++++ b/target/linux/ramips/patches-4.4/400-mtd-spi-nor-add-w25q256-3b-mode-switch.patch +@@ -0,0 +1,399 @@ ++--- a/drivers/mtd/devices/serial_flash_cmds.h +++++ b/drivers/mtd/devices/serial_flash_cmds.h ++@@ -18,19 +18,12 @@ ++ #define SPINOR_OP_RDVCR 0x85 ++ ++ /* JEDEC Standard - Serial Flash Discoverable Parmeters (SFDP) Commands */ ++-#define SPINOR_OP_READ_1_2_2 0xbb /* DUAL I/O READ */ ++-#define SPINOR_OP_READ_1_4_4 0xeb /* QUAD I/O READ */ ++- ++ #define SPINOR_OP_WRITE 0x02 /* PAGE PROGRAM */ ++ #define SPINOR_OP_WRITE_1_1_2 0xa2 /* DUAL INPUT PROGRAM */ ++ #define SPINOR_OP_WRITE_1_2_2 0xd2 /* DUAL INPUT EXT PROGRAM */ ++ #define SPINOR_OP_WRITE_1_1_4 0x32 /* QUAD INPUT PROGRAM */ ++ #define SPINOR_OP_WRITE_1_4_4 0x12 /* QUAD INPUT EXT PROGRAM */ ++ ++-/* READ commands with 32-bit addressing */ ++-#define SPINOR_OP_READ4_1_2_2 0xbc ++-#define SPINOR_OP_READ4_1_4_4 0xec ++- ++ /* Configuration flags */ ++ #define FLASH_FLAG_SINGLE 0x000000ff ++ #define FLASH_FLAG_READ_WRITE 0x00000001 ++--- a/drivers/mtd/devices/st_spi_fsm.c +++++ b/drivers/mtd/devices/st_spi_fsm.c ++@@ -507,13 +507,13 @@ static struct seq_rw_config n25q_read3_c ++ * - 'FAST' variants configured for 8 dummy cycles (see note above.) ++ */ ++ static struct seq_rw_config n25q_read4_configs[] = { ++- {FLASH_FLAG_READ_1_4_4, SPINOR_OP_READ4_1_4_4, 0, 4, 4, 0x00, 0, 8}, ++- {FLASH_FLAG_READ_1_1_4, SPINOR_OP_READ4_1_1_4, 0, 1, 4, 0x00, 0, 8}, ++- {FLASH_FLAG_READ_1_2_2, SPINOR_OP_READ4_1_2_2, 0, 2, 2, 0x00, 0, 8}, ++- {FLASH_FLAG_READ_1_1_2, SPINOR_OP_READ4_1_1_2, 0, 1, 2, 0x00, 0, 8}, ++- {FLASH_FLAG_READ_FAST, SPINOR_OP_READ4_FAST, 0, 1, 1, 0x00, 0, 8}, ++- {FLASH_FLAG_READ_WRITE, SPINOR_OP_READ4, 0, 1, 1, 0x00, 0, 0}, ++- {0x00, 0, 0, 0, 0, 0x00, 0, 0}, +++ {FLASH_FLAG_READ_1_4_4, SPINOR_OP_READ_1_4_4_4B, 0, 4, 4, 0x00, 0, 8}, +++ {FLASH_FLAG_READ_1_1_4, SPINOR_OP_READ_1_1_4_4B, 0, 1, 4, 0x00, 0, 8}, +++ {FLASH_FLAG_READ_1_2_2, SPINOR_OP_READ_1_2_2_4B, 0, 2, 2, 0x00, 0, 8}, +++ {FLASH_FLAG_READ_1_1_2, SPINOR_OP_READ_1_1_2_4B, 0, 1, 2, 0x00, 0, 8}, +++ {FLASH_FLAG_READ_FAST, SPINOR_OP_READ_FAST_4B, 0, 1, 1, 0x00, 0, 8}, +++ {FLASH_FLAG_READ_WRITE, SPINOR_OP_READ_4B, 0, 1, 1, 0x00, 0, 0}, +++ {0x00, 0, 0, 0, 0, 0x00, 0, 0}, ++ }; ++ ++ /* ++@@ -553,13 +553,13 @@ static int stfsm_mx25_en_32bit_addr_seq( ++ * entering a state that is incompatible with the SPIBoot Controller. ++ */ ++ static struct seq_rw_config stfsm_s25fl_read4_configs[] = { ++- {FLASH_FLAG_READ_1_4_4, SPINOR_OP_READ4_1_4_4, 0, 4, 4, 0x00, 2, 4}, ++- {FLASH_FLAG_READ_1_1_4, SPINOR_OP_READ4_1_1_4, 0, 1, 4, 0x00, 0, 8}, ++- {FLASH_FLAG_READ_1_2_2, SPINOR_OP_READ4_1_2_2, 0, 2, 2, 0x00, 4, 0}, ++- {FLASH_FLAG_READ_1_1_2, SPINOR_OP_READ4_1_1_2, 0, 1, 2, 0x00, 0, 8}, ++- {FLASH_FLAG_READ_FAST, SPINOR_OP_READ4_FAST, 0, 1, 1, 0x00, 0, 8}, ++- {FLASH_FLAG_READ_WRITE, SPINOR_OP_READ4, 0, 1, 1, 0x00, 0, 0}, ++- {0x00, 0, 0, 0, 0, 0x00, 0, 0}, +++ {FLASH_FLAG_READ_1_4_4, SPINOR_OP_READ_1_4_4_4B, 0, 4, 4, 0x00, 2, 4}, +++ {FLASH_FLAG_READ_1_1_4, SPINOR_OP_READ_1_1_4_4B, 0, 1, 4, 0x00, 0, 8}, +++ {FLASH_FLAG_READ_1_2_2, SPINOR_OP_READ_1_2_2_4B, 0, 2, 2, 0x00, 4, 0}, +++ {FLASH_FLAG_READ_1_1_2, SPINOR_OP_READ_1_1_2_4B, 0, 1, 2, 0x00, 0, 8}, +++ {FLASH_FLAG_READ_FAST, SPINOR_OP_READ_FAST_4B, 0, 1, 1, 0x00, 0, 8}, +++ {FLASH_FLAG_READ_WRITE, SPINOR_OP_READ_4B, 0, 1, 1, 0x00, 0, 0}, +++ {0x00, 0, 0, 0, 0, 0x00, 0, 0}, ++ }; ++ ++ static struct seq_rw_config stfsm_s25fl_write4_configs[] = { ++--- a/drivers/mtd/spi-nor/spi-nor.c +++++ b/drivers/mtd/spi-nor/spi-nor.c ++@@ -69,6 +69,14 @@ struct flash_info { ++ #define SPI_NOR_QUAD_READ 0x40 /* Flash supports Quad Read */ ++ #define USE_FSR 0x80 /* use flag status register */ ++ #define SPI_NOR_HAS_LOCK 0x100 /* Flash supports lock/unlock via SR */ +++#define SPI_NOR_4B_OPCODES 0x200 /* +++ * Use dedicated 4byte address op codes +++ * to support memory size above 128Mib. +++ */ +++#define SPI_NOR_4B_READ_OP 0x400 /* +++ * Like SPI_NOR_4B_OPCODES, but for read +++ * op code only. +++ */ ++ }; ++ ++ #define JEDEC_MFR(info) ((info)->id[0]) ++@@ -182,6 +190,89 @@ static inline struct spi_nor *mtd_to_spi ++ return mtd->priv; ++ } ++ +++ +++static u8 spi_nor_convert_opcode(u8 opcode, const u8 table[][2], size_t size) +++{ +++ size_t i; +++ +++ for (i = 0; i < size; i++) +++ if (table[i][0] == opcode) +++ return table[i][1]; +++ +++ /* No conversion found, keep input op code. */ +++ return opcode; +++} +++ +++static inline u8 spi_nor_convert_3to4_read(u8 opcode) +++{ +++ static const u8 spi_nor_3to4_read[][2] = { +++ { SPINOR_OP_READ, SPINOR_OP_READ_4B }, +++ { SPINOR_OP_READ_FAST, SPINOR_OP_READ_FAST_4B }, +++ { SPINOR_OP_READ_1_1_2, SPINOR_OP_READ_1_1_2_4B }, +++ { SPINOR_OP_READ_1_2_2, SPINOR_OP_READ_1_2_2_4B }, +++ { SPINOR_OP_READ_1_1_4, SPINOR_OP_READ_1_1_4_4B }, +++ { SPINOR_OP_READ_1_4_4, SPINOR_OP_READ_1_4_4_4B }, +++ }; +++ +++ return spi_nor_convert_opcode(opcode, spi_nor_3to4_read, +++ ARRAY_SIZE(spi_nor_3to4_read)); +++} +++ +++static inline u8 spi_nor_convert_3to4_program(u8 opcode) +++{ +++ static const u8 spi_nor_3to4_program[][2] = { +++ { SPINOR_OP_PP, SPINOR_OP_PP_4B }, +++ { SPINOR_OP_PP_1_1_4, SPINOR_OP_PP_1_1_4_4B }, +++ { SPINOR_OP_PP_1_4_4, SPINOR_OP_PP_1_4_4_4B }, +++ }; +++ +++ return spi_nor_convert_opcode(opcode, spi_nor_3to4_program, +++ ARRAY_SIZE(spi_nor_3to4_program)); +++} +++ +++static inline u8 spi_nor_convert_3to4_erase(u8 opcode) +++{ +++ static const u8 spi_nor_3to4_erase[][2] = { +++ { SPINOR_OP_BE_4K, SPINOR_OP_BE_4K_4B }, +++ { SPINOR_OP_BE_32K, SPINOR_OP_BE_32K_4B }, +++ { SPINOR_OP_SE, SPINOR_OP_SE_4B }, +++ }; +++ +++ return spi_nor_convert_opcode(opcode, spi_nor_3to4_erase, +++ ARRAY_SIZE(spi_nor_3to4_erase)); +++} +++ +++static void spi_nor_set_4byte_read(struct spi_nor *nor, +++ const struct flash_info *info) +++{ +++ nor->addr_width = 3; +++ nor->ext_addr = 0; +++ nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode); +++ nor->flags |= SNOR_F_4B_EXT_ADDR; +++} +++ +++ +++ +++static void spi_nor_set_4byte_opcodes(struct spi_nor *nor, +++ const struct flash_info *info) +++{ +++ /* Do some manufacturer fixups first */ +++ switch (JEDEC_MFR(info)) { +++ case SNOR_MFR_SPANSION: +++ /* No small sector erase for 4-byte command set */ +++ nor->erase_opcode = SPINOR_OP_SE; +++ nor->mtd.erasesize = info->sector_size; +++ break; +++ +++ default: +++ break; +++ } +++ +++ nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode); +++ nor->program_opcode = spi_nor_convert_3to4_program(nor->program_opcode); +++ nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode); +++} +++ ++ /* Enable/disable 4-byte addressing mode. */ ++ static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info, ++ int enable) ++@@ -313,6 +404,36 @@ static void spi_nor_unlock_and_unprep(st ++ mutex_unlock(&nor->lock); ++ } ++ +++static int spi_nor_check_ext_addr(struct spi_nor *nor, u32 addr) +++{ +++ bool ext_addr; +++ int ret; +++ u8 cmd; +++ +++ if (!(nor->flags & SNOR_F_4B_EXT_ADDR)) +++ return 0; +++ +++ ext_addr = !!(addr & 0xff000000); +++ if (nor->ext_addr == ext_addr) +++ return 0; +++ +++ cmd = ext_addr ? SPINOR_OP_EN4B : SPINOR_OP_EX4B; +++ write_enable(nor); +++ ret = nor->write_reg(nor, cmd, NULL, 0); +++ if (ret) +++ return ret; +++ +++ cmd = 0; +++ ret = nor->write_reg(nor, SPINOR_OP_WREAR, &cmd, 1); +++ if (ret) +++ return ret; +++ +++ nor->addr_width = 3 + ext_addr; +++ nor->ext_addr = ext_addr; +++ write_disable(nor); +++ return 0; +++} +++ ++ /* ++ * Erase an address range on the nor chip. The address range may extend ++ * one or more erase sectors. Return an error is there is a problem erasing. ++@@ -338,6 +459,10 @@ static int spi_nor_erase(struct mtd_info ++ if (ret) ++ return ret; ++ +++ ret = spi_nor_check_ext_addr(nor, addr + len); +++ if (ret) +++ return ret; +++ ++ /* whole-chip erase? */ ++ if (len == mtd->size) { ++ unsigned long timeout; ++@@ -396,6 +521,7 @@ static int spi_nor_erase(struct mtd_info ++ return ret; ++ ++ erase_err: +++ spi_nor_check_ext_addr(nor, 0); ++ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE); ++ instr->state = MTD_ERASE_FAILED; ++ return ret; ++@@ -585,7 +711,9 @@ static int spi_nor_lock(struct mtd_info ++ if (ret) ++ return ret; ++ +++ spi_nor_check_ext_addr(nor, ofs + len); ++ ret = nor->flash_lock(nor, ofs, len); +++ spi_nor_check_ext_addr(nor, 0); ++ ++ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK); ++ return ret; ++@@ -600,7 +728,9 @@ static int spi_nor_unlock(struct mtd_inf ++ if (ret) ++ return ret; ++ +++ spi_nor_check_ext_addr(nor, ofs + len); ++ ret = nor->flash_unlock(nor, ofs, len); +++ spi_nor_check_ext_addr(nor, 0); ++ ++ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK); ++ return ret; ++@@ -851,7 +981,7 @@ static const struct flash_info spi_nor_i ++ { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, ++ { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, ++ { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, ++- { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) }, +++ { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_READ_OP) }, ++ ++ /* Catalyst / On Semiconductor -- non-JEDEC */ ++ { "cat25c11", CAT25_INFO( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, ++@@ -898,8 +1028,23 @@ static int spi_nor_read(struct mtd_info ++ if (ret) ++ return ret; ++ +++ if (nor->flags & SNOR_F_4B_EXT_ADDR) +++ nor->addr_width = 4; +++ ++ ret = nor->read(nor, from, len, retlen, buf); ++ +++ if (nor->flags & SNOR_F_4B_EXT_ADDR) { +++ u8 val = 0; +++ +++ if ((from + len) & 0xff000000) { +++ write_enable(nor); +++ nor->write_reg(nor, SPINOR_OP_WREAR, &val, 1); +++ write_disable(nor); +++ } +++ +++ nor->addr_width = 3; +++ } +++ ++ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ); ++ return ret; ++ } ++@@ -988,6 +1133,10 @@ static int spi_nor_write(struct mtd_info ++ if (ret) ++ return ret; ++ +++ ret = spi_nor_check_ext_addr(nor, to + len); +++ if (ret < 0) +++ return ret; +++ ++ write_enable(nor); ++ ++ page_offset = to & (nor->page_size - 1); ++@@ -1018,6 +1167,7 @@ static int spi_nor_write(struct mtd_info ++ ++ ret = spi_nor_wait_till_ready(nor); ++ write_err: +++ spi_nor_check_ext_addr(nor, 0); ++ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE); ++ return ret; ++ } ++@@ -1366,27 +1516,12 @@ int spi_nor_scan(struct spi_nor *nor, co ++ else if (mtd->size > 0x1000000) { ++ /* enable 4-byte addressing if the device exceeds 16MiB */ ++ nor->addr_width = 4; ++- if (JEDEC_MFR(info) == SNOR_MFR_SPANSION) { ++- /* Dedicated 4-byte command set */ ++- switch (nor->flash_read) { ++- case SPI_NOR_QUAD: ++- nor->read_opcode = SPINOR_OP_READ4_1_1_4; ++- break; ++- case SPI_NOR_DUAL: ++- nor->read_opcode = SPINOR_OP_READ4_1_1_2; ++- break; ++- case SPI_NOR_FAST: ++- nor->read_opcode = SPINOR_OP_READ4_FAST; ++- break; ++- case SPI_NOR_NORMAL: ++- nor->read_opcode = SPINOR_OP_READ4; ++- break; ++- } ++- nor->program_opcode = SPINOR_OP_PP_4B; ++- /* No small sector erase for 4-byte command set */ ++- nor->erase_opcode = SPINOR_OP_SE_4B; ++- mtd->erasesize = info->sector_size; ++- } else +++ if (info->flags & SPI_NOR_4B_READ_OP) +++ spi_nor_set_4byte_read(nor, info); +++ else if (JEDEC_MFR(info) == SNOR_MFR_SPANSION || +++ info->flags & SPI_NOR_4B_OPCODES) +++ spi_nor_set_4byte_opcodes(nor, info); +++ else ++ set_4byte(nor, info, 1); ++ } else { ++ nor->addr_width = 3; ++--- a/include/linux/mtd/spi-nor.h +++++ b/include/linux/mtd/spi-nor.h ++@@ -42,9 +42,13 @@ ++ #define SPINOR_OP_WRSR 0x01 /* Write status register 1 byte */ ++ #define SPINOR_OP_READ 0x03 /* Read data bytes (low frequency) */ ++ #define SPINOR_OP_READ_FAST 0x0b /* Read data bytes (high frequency) */ ++-#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual SPI) */ ++-#define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad SPI) */ +++#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual Output SPI) */ +++#define SPINOR_OP_READ_1_2_2 0xbb /* Read data bytes (Dual I/O SPI) */ +++#define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad Output SPI) */ +++#define SPINOR_OP_READ_1_4_4 0xeb /* Read data bytes (Quad I/O SPI) */ ++ #define SPINOR_OP_PP 0x02 /* Page program (up to 256 bytes) */ +++#define SPINOR_OP_PP_1_1_4 0x32 /* Quad page program */ +++#define SPINOR_OP_PP_1_4_4 0x38 /* Quad page program */ ++ #define SPINOR_OP_BE_4K 0x20 /* Erase 4KiB block */ ++ #define SPINOR_OP_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */ ++ #define SPINOR_OP_BE_32K 0x52 /* Erase 32KiB block */ ++@@ -55,11 +59,17 @@ ++ #define SPINOR_OP_RDFSR 0x70 /* Read flag status register */ ++ ++ /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */ ++-#define SPINOR_OP_READ4 0x13 /* Read data bytes (low frequency) */ ++-#define SPINOR_OP_READ4_FAST 0x0c /* Read data bytes (high frequency) */ ++-#define SPINOR_OP_READ4_1_1_2 0x3c /* Read data bytes (Dual SPI) */ ++-#define SPINOR_OP_READ4_1_1_4 0x6c /* Read data bytes (Quad SPI) */ +++#define SPINOR_OP_READ_4B 0x13 /* Read data bytes (low frequency) */ +++#define SPINOR_OP_READ_FAST_4B 0x0c /* Read data bytes (high frequency) */ +++#define SPINOR_OP_READ_1_1_2_4B 0x3c /* Read data bytes (Dual Output SPI) */ +++#define SPINOR_OP_READ_1_2_2_4B 0xbc /* Read data bytes (Dual I/O SPI) */ +++#define SPINOR_OP_READ_1_1_4_4B 0x6c /* Read data bytes (Quad Output SPI) */ +++#define SPINOR_OP_READ_1_4_4_4B 0xec /* Read data bytes (Quad I/O SPI) */ ++ #define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */ +++#define SPINOR_OP_PP_1_1_4_4B 0x34 /* Quad page program */ +++#define SPINOR_OP_PP_1_4_4_4B 0x3e /* Quad page program */ +++#define SPINOR_OP_BE_4K_4B 0x21 /* Erase 4KiB block */ +++#define SPINOR_OP_BE_32K_4B 0x5c /* Erase 32KiB block */ ++ #define SPINOR_OP_SE_4B 0xdc /* Sector erase (usually 64KiB) */ ++ ++ /* Used for SST flashes only. */ ++@@ -70,6 +80,7 @@ ++ /* Used for Macronix and Winbond flashes. */ ++ #define SPINOR_OP_EN4B 0xb7 /* Enter 4-byte mode */ ++ #define SPINOR_OP_EX4B 0xe9 /* Exit 4-byte mode */ +++#define SPINOR_OP_WREAR 0xc5 /* Write extended address register */ ++ ++ /* Used for Spansion flashes only. */ ++ #define SPINOR_OP_BRWR 0x17 /* Bank register write */ ++@@ -117,6 +128,7 @@ enum spi_nor_ops { ++ enum spi_nor_option_flags { ++ SNOR_F_USE_FSR = BIT(0), ++ SNOR_F_SST = BIT(1), +++ SNOR_F_4B_EXT_ADDR = BIT(5), ++ }; ++ ++ /** ++@@ -166,6 +178,7 @@ struct spi_nor { ++ enum read_mode flash_read; ++ bool sst_write_second; ++ u32 flags; +++ u8 ext_addr; ++ u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE]; ++ ++ int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops); +diff --git a/target/linux/ramips/patches-4.4/401-mtd-add-chunked-read-io-to-m25p80.patch b/target/linux/ramips/patches-4.4/401-mtd-add-chunked-read-io-to-m25p80.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..b6111abad7063951c07688c66854fa743daeb6c6 +--- /dev/null ++++ b/target/linux/ramips/patches-4.4/401-mtd-add-chunked-read-io-to-m25p80.patch +@@ -0,0 +1,21 @@ ++--- a/drivers/mtd/spi-nor/spi-nor.c +++++ b/drivers/mtd/spi-nor/spi-nor.c ++@@ -1176,6 +1176,7 @@ static int spi_nor_chunked_write(struct ++ size_t *_retlen, const u_char *_buf) ++ { ++ struct spi_nor *nor = mtd_to_spi_nor(mtd); +++ u32 addr_width = nor->addr_width + !!(nor->flags & SNOR_F_4B_EXT_ADDR); ++ int chunk_size; ++ int retlen = 0; ++ int ret; ++@@ -1184,8 +1185,8 @@ static int spi_nor_chunked_write(struct ++ if (!chunk_size) ++ chunk_size = _len; ++ ++- if (nor->addr_width > 3) ++- chunk_size -= nor->addr_width - 3; +++ if (addr_width > 3) +++ chunk_size -= addr_width - 3; ++ ++ while (retlen < _len) { ++ size_t len = min_t(int, chunk_size, _len - retlen); diff --git a/patches/lede/0065-ramips-prepare-ZBT-WG3526-for-hardware-variants.patch b/patches/lede/0065-ramips-prepare-ZBT-WG3526-for-hardware-variants.patch new file mode 100644 index 00000000..00b54070 --- /dev/null +++ b/patches/lede/0065-ramips-prepare-ZBT-WG3526-for-hardware-variants.patch @@ -0,0 +1,99 @@ +From: Mathias Kresin +Date: Fri, 7 Apr 2017 23:52:27 +0200 +Subject: ramips: prepare ZBT-WG3526 for hardware variants + +The ZBT-WG3526 is available with 16 or 32 MByte of flash. Rename the +current supported 16MByte version to indicate which flash size variant +is supported. + +Signed-off-by: Mathias Kresin + +Conflicts (Resolved): + target/linux/ramips/image/mt7621.mk + +Signed-off-by: Vincent Wiemann + +further adjustments for backport to lede-17.01 branch + +Signed-off-by: Andreas Ziegler + +diff --git a/target/linux/ramips/base-files/lib/ramips.sh b/target/linux/ramips/base-files/lib/ramips.sh +index b1091f66b2897a19bd01d4a26a1b3647656fa62b..8e27a79fc1744d6bed9db8d930207c418899cab1 100755 +--- a/target/linux/ramips/base-files/lib/ramips.sh ++++ b/target/linux/ramips/base-files/lib/ramips.sh +@@ -637,8 +637,8 @@ ramips_board_detect() { + *"ZBT-WG2626") + name="zbt-wg2626" + ;; +- *"ZBT-WG3526") +- name="zbt-wg3526" ++ *"ZBT-WG3526 (16M)") ++ name="zbt-wg3526-16M" + ;; + *"ZBT-WR8305RT") + name="zbt-wr8305rt" +diff --git a/target/linux/ramips/dts/ZBT-WG3526-16M.dts b/target/linux/ramips/dts/ZBT-WG3526-16M.dts +new file mode 100644 +index 0000000000000000000000000000000000000000..fb644502071d6641194c66baf552035937f35669 +--- /dev/null ++++ b/target/linux/ramips/dts/ZBT-WG3526-16M.dts +@@ -0,0 +1,15 @@ ++/dts-v1/; ++ ++#include "ZBT-WG3526.dtsi" ++ ++/ { ++ model = "ZBT-WG3526 (16M)"; ++}; ++ ++&firmware { ++ reg = <0x50000 0xfb0000>; ++}; ++ ++&status_led { ++ label = "zbt-wg3526:green:status"; ++}; +diff --git a/target/linux/ramips/dts/ZBT-WG3526.dts b/target/linux/ramips/dts/ZBT-WG3526.dts +deleted file mode 100644 +index c361bdd827bffdc24405b1a1b191403ebeec46d0..0000000000000000000000000000000000000000 +--- a/target/linux/ramips/dts/ZBT-WG3526.dts ++++ /dev/null +@@ -1,15 +0,0 @@ +-/dts-v1/; +- +-#include "ZBT-WG3526.dtsi" +- +-/ { +- model = "ZBT-WG3526"; +-}; +- +-&firmware { +- reg = <0x50000 0xfb0000>; +-}; +- +-&status_led { +- label = "zbt-wg3526:green:status"; +-}; +diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk +index 8218bea84410536151a216cd2cc0300369ad977a..cabc86b28eb040f0d1e58d917e6edc4a97e80db7 100644 +--- a/target/linux/ramips/image/mt7621.mk ++++ b/target/linux/ramips/image/mt7621.mk +@@ -226,13 +226,14 @@ define Device/zbt-wg2626 + endef + TARGET_DEVICES += zbt-wg2626 + +-define Device/zbt-wg3526 +- DTS := ZBT-WG3526 ++define Device/zbt-wg3526-16M ++ DTS := ZBT-WG3526-16M + IMAGE_SIZE := $(ralink_default_fw_size_16M) +- DEVICE_TITLE := ZBT WG3526 ++ SUPPORTED_DEVICES += zbt-wg3526 ++ DEVICE_TITLE := ZBT WG3526 (16MB flash) + DEVICE_PACKAGES := kmod-usb3 kmod-usb-ledtrig-usbport kmod-ata-core kmod-ata-ahci + endef +-TARGET_DEVICES += zbt-wg3526 ++TARGET_DEVICES += zbt-wg3526-16M + + # FIXME: is this still needed? + define Image/Prepare diff --git a/patches/lede/0066-ramips-rename-Digineo-AC1200-Pro-to-ZBT-WG3526-32MB.patch b/patches/lede/0066-ramips-rename-Digineo-AC1200-Pro-to-ZBT-WG3526-32MB.patch new file mode 100644 index 00000000..e87812e7 --- /dev/null +++ b/patches/lede/0066-ramips-rename-Digineo-AC1200-Pro-to-ZBT-WG3526-32MB.patch @@ -0,0 +1,193 @@ +From: Mathias Kresin +Date: Sat, 1 Apr 2017 10:46:44 +0200 +Subject: ramips: rename Digineo AC1200 Pro to ZBT-WG3526 32MB + +The Digineo AC1200 Pro is the 32MB flash variant of the ZBT-WG3526 with +unpopulated/exposed sdhci slot. Rename to board to the OEM/ODM name and +add the sdhci kernel module to use it for multiple clones. + +Signed-off-by: Mathias Kresin + +Conflicts (Resolved): + target/linux/ramips/base-files/etc/diag.sh + +Signed-off-by: Vincent Wiemann + +further adjustments for backport to lede-17.01 branch + +Signed-off-by: Andreas Ziegler + +diff --git a/target/linux/ramips/base-files/etc/board.d/02_network b/target/linux/ramips/base-files/etc/board.d/02_network +index 5a4042339c6761703578e014612062ac78babd9d..b9c8fe774fedab34267a8635033b9235d9d6c3aa 100755 +--- a/target/linux/ramips/base-files/etc/board.d/02_network ++++ b/target/linux/ramips/base-files/etc/board.d/02_network +@@ -70,7 +70,6 @@ ramips_setup_interfaces() + ucidef_set_interface_lan "eth0.2" + ;; + 3g-6200n|\ +- ac1200pro|\ + ai-br100|\ + d240|\ + db-wrt01|\ +diff --git a/target/linux/ramips/base-files/etc/diag.sh b/target/linux/ramips/base-files/etc/diag.sh +index 9dbd6c4141d7facef2108cbb5cf3a7057522c88e..c4f521954c74635c61f42558f0d9b71f0f671c22 100644 +--- a/target/linux/ramips/base-files/etc/diag.sh ++++ b/target/linux/ramips/base-files/etc/diag.sh +@@ -59,7 +59,10 @@ get_status_led() { + wn3000rpv3) + status_led="$board:red:power" + ;; +- ac1200pro|\ ++ ai-br100|\ ++ ht-tm02) ++ status_led="$board:blue:wlan" ++ ;; + all0239-3g|\ + dcs-930|\ + dir-300-b1|\ +@@ -85,10 +88,6 @@ get_status_led() { + zbt-wg3526) + status_led="$board:green:status" + ;; +- ai-br100|\ +- ht-tm02) +- status_led="$board:blue:wlan" +- ;; + atp-52b|\ + ip2202) + status_led="$board:green:run" +diff --git a/target/linux/ramips/base-files/lib/ramips.sh b/target/linux/ramips/base-files/lib/ramips.sh +index 8e27a79fc1744d6bed9db8d930207c418899cab1..b9279a5a1e9baf55ca7f59dbb22ac0b0b7b01db4 100755 +--- a/target/linux/ramips/base-files/lib/ramips.sh ++++ b/target/linux/ramips/base-files/lib/ramips.sh +@@ -130,9 +130,6 @@ ramips_board_detect() { + *"DCS-930L B1") + name="dcs-930l-b1" + ;; +- *"Digineo AC1200 Pro") +- name="ac1200pro" +- ;; + *"DIR-300 B1") + name="dir-300-b1" + ;; +@@ -640,6 +637,9 @@ ramips_board_detect() { + *"ZBT-WG3526 (16M)") + name="zbt-wg3526-16M" + ;; ++ *"ZBT-WG3526 (32M)") ++ name="zbt-wg3526-32M" ++ ;; + *"ZBT-WR8305RT") + name="zbt-wr8305rt" + ;; +diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh +index d3efc2dd37ed855a1c0e966e448b67ae73324d5f..a45275077df8fa317c38adc8f0ab12fd4b0ecb83 100755 +--- a/target/linux/ramips/base-files/lib/upgrade/platform.sh ++++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh +@@ -17,7 +17,6 @@ platform_check_image() { + 3g150b|\ + 3g300m|\ + a5-v11|\ +- ac1200pro|\ + ai-br100|\ + air3gii|\ + all0239-3g|\ +diff --git a/target/linux/ramips/dts/AC1200pro.dts b/target/linux/ramips/dts/AC1200pro.dts +deleted file mode 100644 +index fbec81844025cf2a6544dec8dfeca02fce89fdc1..0000000000000000000000000000000000000000 +--- a/target/linux/ramips/dts/AC1200pro.dts ++++ /dev/null +@@ -1,15 +0,0 @@ +-/dts-v1/; +- +-#include "ZBT-WG3526.dtsi" +- +-/ { +- model = "Digineo AC1200 Pro"; +-}; +- +-&firmware { +- reg = <0x50000 0x1fb0000>; +-}; +- +-&status_led { +- label = "ac1200pro:green:status"; +-}; +diff --git a/target/linux/ramips/dts/ZBT-WG3526-16M.dts b/target/linux/ramips/dts/ZBT-WG3526-16M.dts +index fb644502071d6641194c66baf552035937f35669..1e2f1525028f69468257cd8af8d5bad0319bc551 100644 +--- a/target/linux/ramips/dts/ZBT-WG3526-16M.dts ++++ b/target/linux/ramips/dts/ZBT-WG3526-16M.dts +@@ -9,7 +9,3 @@ + &firmware { + reg = <0x50000 0xfb0000>; + }; +- +-&status_led { +- label = "zbt-wg3526:green:status"; +-}; +diff --git a/target/linux/ramips/dts/ZBT-WG3526-32M.dts b/target/linux/ramips/dts/ZBT-WG3526-32M.dts +new file mode 100644 +index 0000000000000000000000000000000000000000..99a4b45824ba4ee6c1a1c81615291c8efde1a7ac +--- /dev/null ++++ b/target/linux/ramips/dts/ZBT-WG3526-32M.dts +@@ -0,0 +1,11 @@ ++/dts-v1/; ++ ++#include "ZBT-WG3526.dtsi" ++ ++/ { ++ model = "ZBT-WG3526 (32M)"; ++}; ++ ++&firmware { ++ reg = <0x50000 0x1fb0000>; ++}; +diff --git a/target/linux/ramips/dts/ZBT-WG3526.dtsi b/target/linux/ramips/dts/ZBT-WG3526.dtsi +index 582e42083920c465588f14e59e10eafe735640fb..5e195fb8120d3a66f19acf83c9f76bb4b1ec3e7e 100644 +--- a/target/linux/ramips/dts/ZBT-WG3526.dtsi ++++ b/target/linux/ramips/dts/ZBT-WG3526.dtsi +@@ -35,7 +35,8 @@ + gpio-leds { + compatible = "gpio-leds"; + +- status_led: status { ++ status { ++ label = "zbt-wg3526:green:status"; + gpios = <&gpio0 24 1>; + }; + }; +diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk +index cabc86b28eb040f0d1e58d917e6edc4a97e80db7..aa84d78b9e42259cbee7de6c052fa7ab500a040a 100644 +--- a/target/linux/ramips/image/mt7621.mk ++++ b/target/linux/ramips/image/mt7621.mk +@@ -34,14 +34,6 @@ define Device/11acnas + endef + TARGET_DEVICES += 11acnas + +-define Device/ac1200pro +- DTS := AC1200pro +- IMAGE_SIZE := $(ralink_default_fw_size_32M) +- DEVICE_TITLE := Digineo AC1200 Pro +- DEVICE_PACKAGES := kmod-usb3 kmod-ata-core kmod-ata-ahci +-endef +-TARGET_DEVICES += ac1200pro +- + define Device/dir-860l-b1 + DTS := DIR-860L-B1 + BLOCKSIZE := 64k +@@ -235,6 +227,15 @@ define Device/zbt-wg3526-16M + endef + TARGET_DEVICES += zbt-wg3526-16M + ++define Device/zbt-wg3526-32M ++ DTS := ZBT-WG3526-32M ++ IMAGE_SIZE := $(ralink_default_fw_size_32M) ++ SUPPORTED_DEVICES += ac1200pro ++ DEVICE_TITLE := ZBT WG3526 (32MB flash) ++ DEVICE_PACKAGES := kmod-usb3 kmod-usb-ledtrig-usbport kmod-ata-core kmod-ata-ahci kmod-sdhci-mt7620 ++endef ++TARGET_DEVICES += zbt-wg3526-32M ++ + # FIXME: is this still needed? + define Image/Prepare + #define Build/Compile diff --git a/targets/ramips-mt7621 b/targets/ramips-mt7621 index 33d4e1b5..08a82690 100644 --- a/targets/ramips-mt7621 +++ b/targets/ramips-mt7621 @@ -14,7 +14,11 @@ factory ## ZBT -device zbt-wg3526 zbt-wg3526 # BROKEN: Untested +device zbt-wg3526-16m zbt-wg3526-16M # BROKEN: Untested +factory +manifest_alias zbt-wg3526 + +device zbt-wg3526-32m zbt-wg3526-32M # BROKEN: Untested factory fi