diff --git a/device/config/chips/v851s/configs/fastboot_sl100_back/linux/config-4.9 b/device/config/chips/v851s/configs/fastboot_sl100_back/linux/config-4.9 index cf8e4c56a..cae5b017d 100755 --- a/device/config/chips/v851s/configs/fastboot_sl100_back/linux/config-4.9 +++ b/device/config/chips/v851s/configs/fastboot_sl100_back/linux/config-4.9 @@ -757,6 +757,7 @@ CONFIG_MTD_SPI_NOR=y # CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set # CONFIG_SPI_CADENCE_QUADSPI is not set # CONFIG_SPI_FLASH_SR is not set +# CONFIG_SPI_FLASH_DEFAULT_LOCK is not set # CONFIG_MTD_UBI is not set CONFIG_DTC=y CONFIG_OF=y diff --git a/device/config/chips/v851s/configs/fastboot_sl100_back/linux/config-4.9_recovery b/device/config/chips/v851s/configs/fastboot_sl100_back/linux/config-4.9_recovery index afd8c47c7..021529e4b 100755 --- a/device/config/chips/v851s/configs/fastboot_sl100_back/linux/config-4.9_recovery +++ b/device/config/chips/v851s/configs/fastboot_sl100_back/linux/config-4.9_recovery @@ -757,6 +757,7 @@ CONFIG_MTD_SPI_NOR=y # CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set # CONFIG_SPI_CADENCE_QUADSPI is not set # CONFIG_SPI_FLASH_SR is not set +# CONFIG_SPI_FLASH_DEFAULT_LOCK is not set # CONFIG_MTD_UBI is not set CONFIG_DTC=y CONFIG_OF=y diff --git a/device/config/chips/v851s3/configs/fastboot_sl100_front/board.dts b/device/config/chips/v851s3/configs/fastboot_sl100_front/board.dts index db2171800..f25e8fb76 100755 --- a/device/config/chips/v851s3/configs/fastboot_sl100_front/board.dts +++ b/device/config/chips/v851s3/configs/fastboot_sl100_front/board.dts @@ -24,7 +24,7 @@ /*bootargs = "earlyprintk=sunxi-uart,0x02500000 clk_ignore_unused initcall_debug=0 console=ttyS0,115200 loglevel=6 lpj=240000 root=/dev/mtdblock4 rootwait init=/files/pseudo_init rdinit=/rdinit partitions=env@mtdblock1:env-redund@mtdblock2:boot@mtdblock3:rootfs@mtdblock4:extend@mtdblock5:rootfs_data@mtdblock6:UDISK@mtdblock7 coherent_pool=16K androidboot.hardware=sun8iw21p1 boot_type=3 androidboot.boot_type=3 gpt=1 mbr_offset=2080768 bootreason=unknow";*/ /* for OTA recovery system:(kernel rootfs extend) */ - bootargs = "earlyprintk=sunxi-uart,0x02500000 clk_ignore_unused initcall_debug=0 console=ttyS0,115200 loglevel=1 lpj=240000 root=/dev/mtdblock4 rootwait init=/files/pseudo_init rdinit=/rdinit partitions=env@mtdblock1:env-redund@mtdblock2:boot@mtdblock3:rootfs@mtdblock4:extend@mtdblock5:recovery@mtdblock6:rootfs_data@mtdblock7:UDISK@mtdblock8 coherent_pool=16K androidboot.hardware=sun8iw21p1 boot_type=3 androidboot.boot_type=3 gpt=1 mbr_offset=2080768 bootreason=unknow"; + bootargs = "earlyprintk=sunxi-uart,0x02500000 clk_ignore_unused initcall_debug=0 console=ttyS0,115200 loglevel=1 lpj=240000 root=/dev/mtdblock4 rootwait init=/files/pseudo_init rdinit=/rdinit partitions=env@mtdblock1:env-redund@mtdblock2:boot@mtdblock3:rootfs@mtdblock4:extend@mtdblock5:recovery@mtdblock6:UDISK@mtdblock7 coherent_pool=16K androidboot.hardware=sun8iw21p1 boot_type=3 androidboot.boot_type=3 gpt=1 mbr_offset=2080768 bootreason=unknow"; /* for OTA recovery system:(kernel rootfs extend appImg recoveryImg) */ diff --git a/device/config/chips/v851s3/configs/fastboot_sl100_front/linux/config-4.9 b/device/config/chips/v851s3/configs/fastboot_sl100_front/linux/config-4.9 index daead19ee..f9bebb5d6 100755 --- a/device/config/chips/v851s3/configs/fastboot_sl100_front/linux/config-4.9 +++ b/device/config/chips/v851s3/configs/fastboot_sl100_front/linux/config-4.9 @@ -762,6 +762,7 @@ CONFIG_MTD_SPI_NOR=y # CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set # CONFIG_SPI_CADENCE_QUADSPI is not set # CONFIG_SPI_FLASH_SR is not set +CONFIG_SPI_FLASH_DEFAULT_LOCK=y # CONFIG_MTD_UBI is not set CONFIG_DTC=y CONFIG_OF=y diff --git a/device/config/chips/v851s3/configs/fastboot_sl100_front/linux/config-4.9_recovery b/device/config/chips/v851s3/configs/fastboot_sl100_front/linux/config-4.9_recovery index 5c3681465..b8ddd79f3 100755 --- a/device/config/chips/v851s3/configs/fastboot_sl100_front/linux/config-4.9_recovery +++ b/device/config/chips/v851s3/configs/fastboot_sl100_front/linux/config-4.9_recovery @@ -765,6 +765,7 @@ CONFIG_MTD_SPI_NOR=y # CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set # CONFIG_SPI_CADENCE_QUADSPI is not set # CONFIG_SPI_FLASH_SR is not set +# CONFIG_SPI_FLASH_DEFAULT_LOCK is not set # CONFIG_MTD_UBI is not set CONFIG_DTC=y CONFIG_OF=y diff --git a/device/config/chips/v851s3/configs/fastboot_sl100_front/linux/sys_partition_nor.fex b/device/config/chips/v851s3/configs/fastboot_sl100_front/linux/sys_partition_nor.fex index 84818e85f..057729de4 100755 --- a/device/config/chips/v851s3/configs/fastboot_sl100_front/linux/sys_partition_nor.fex +++ b/device/config/chips/v851s3/configs/fastboot_sl100_front/linux/sys_partition_nor.fex @@ -30,6 +30,7 @@ size = 16 ; 2、name最大12个字符 ; 3、size = 0, 将创建一个无大小的空分区 ; 4、为了安全和效率考虑,分区大小最好保证为16M字节的整数倍 +; 5、size 128 = 64KB 扇区512byte py_nor_flash ;******************************************************************************************************** [partition_start] @@ -47,13 +48,13 @@ size = 16 [partition] name = boot - size = 6144 + size = 9728 downloadfile = "boot.fex" user_type = 0x8000 [partition] name = rootfs - size = 20480 + size = 24064 downloadfile = "rootfs.fex" user_type = 0x8000 @@ -81,10 +82,10 @@ size = 16 ; downloadfile = "recoveryimg.fex" ; user_type = 0x8000 -[partition] - name = rootfs_data - size = 2048 - user_type = 0x8000 +;[partition] +; name = rootfs_data +; size = 2048 +; user_type = 0x8000 diff --git a/lichee/brandy-2.0/u-boot-2018/drivers/mtd/spi/spi-nor-core.c b/lichee/brandy-2.0/u-boot-2018/drivers/mtd/spi/spi-nor-core.c index 573fd3f06..4c874b9e4 100644 --- a/lichee/brandy-2.0/u-boot-2018/drivers/mtd/spi/spi-nor-core.c +++ b/lichee/brandy-2.0/u-boot-2018/drivers/mtd/spi/spi-nor-core.c @@ -3873,6 +3873,9 @@ static int spi_nor_setup(struct spi_nor *nor, const struct flash_info *info, static int sunxi_lock_init(struct spi_nor *nor) { + uint8_t mask = 0; + uint8_t status1 = 0; + uint8_t status2 = 0; struct mtd_info *mtd = &nor->mtd; const struct flash_info *info = nor->info; @@ -3884,6 +3887,67 @@ static int sunxi_lock_init(struct spi_nor *nor) if (sunxi_individual_lock_is_enable(nor)) sunxi_individual_unlock_global(nor); + + if (JEDEC_MFR(nor->info) == SNOR_MFR_PUYA) + { + if (nor->info->id[2] == 0x19) // py25q256hb id:0x852019 + { + status1 = (uint8_t)read_sr(nor); + /* check cmp first */ + status2 = (uint8_t)read_sr2(nor); + // if ((status2 < 0) || (status1 < 0)) + // { + // printf("read err!:%x %x\n", status1, status2); + // } + if (status2 & (SR2_CMP_GD)) // cmp=1 + { + mask = (SR_BP2 | SR_BP3); + status1 |= mask; + printf("cmp=1\n"); + } + else // cmp=0 + { + printf("cmp=0\n"); + mask = (uint8_t) ~(SR_BP0 | SR_BP1 | SR_BP2 | SR_BP3); + status1 &= mask; + } + if (write_sr_and_check(nor, status1, mask) != 0) + { + printf("py_unlock sr err!:%x\n", status1); + return -1; + } + return 0; + } + else if (nor->info->id[2] == 0x18) // py25q128ha id:0x852018 + { + status1 = (uint8_t)read_sr(nor); + /* check cmp first */ + status2 = (uint8_t)read_sr2(nor); + // if ((status2 < 0) || (status1 < 0)) + // { + // printf("read err!:%x %x\n", status1, status2); + // } + if (status2 & (SR2_CMP_GD)) // cmp=1 + { + mask = (SR_BP0 | SR_BP1 | SR_BP2); + status1 |= mask; + printf("cmp=1\n"); + } + else // cmp=0 + { + printf("cmp=0\n"); + mask = (uint8_t) ~(SR_BP0 | SR_BP1 | SR_BP2); + status1 &= mask; + } + if (write_sr_and_check(nor, status1, mask) != 0) + { + printf("py_unlock sr err!:%x\n", status1); + return -1; + } + return 0; + } + } + if (JEDEC_MFR(info) == SNOR_MFR_ST || JEDEC_MFR(info) == SNOR_MFR_MICRON || JEDEC_MFR(info) == SNOR_MFR_SST) diff --git a/lichee/linux-4.9/drivers/mtd/spi-nor/Kconfig b/lichee/linux-4.9/drivers/mtd/spi-nor/Kconfig index 2ec9c4a7d..388c2924c 100644 --- a/lichee/linux-4.9/drivers/mtd/spi-nor/Kconfig +++ b/lichee/linux-4.9/drivers/mtd/spi-nor/Kconfig @@ -81,4 +81,10 @@ config SPI_FLASH_SR help when set, enable security register write, read, earse functions. +config SPI_FLASH_DEFAULT_LOCK + bool "SPI FLASH default lock" + default n + help + when set, norflash will be protected after kernel run + endif # MTD_SPI_NOR diff --git a/lichee/linux-4.9/drivers/mtd/spi-nor/spif-nor.c b/lichee/linux-4.9/drivers/mtd/spi-nor/spif-nor.c index fc2c662a1..99e14d6f1 100644 --- a/lichee/linux-4.9/drivers/mtd/spi-nor/spif-nor.c +++ b/lichee/linux-4.9/drivers/mtd/spi-nor/spif-nor.c @@ -507,6 +507,42 @@ static int read_sr(struct spi_nor *nor) return nor->bouncebuf[0]; } +/* + * Read the PUYA status register 2, returning its value in the location + * Return the status register value. + * Returns negative if error occurred. + */ +static int read_puya_sr2(struct spi_nor *nor) +{ + int ret; + + ret = nor->read_reg(nor, SPINOR_OP_RDSR2, nor->bouncebuf, 1); + if (ret < 0) { + pr_err("error %d reading SR\n", (int) ret); + return ret; + } + + return nor->bouncebuf[0]; +} + +/* + * Read the PUYA configuration register, returning its value in the location + * Return the status register value. + * Returns negative if error occurred. + */ +static int read_puya_cr(struct spi_nor *nor) +{ + int ret; + + ret = nor->read_reg(nor, SPINOR_OP_RDSR3, nor->bouncebuf, 1); + if (ret < 0) { + pr_err("error %d reading SR\n", (int) ret); + return ret; + } + + return nor->bouncebuf[0]; +} + /* * Read the flag status register, returning its value in the location * Return the status register value. @@ -553,6 +589,26 @@ static int write_sr(struct spi_nor *nor, u8 val) return nor->write_reg(nor, SPINOR_OP_WRSR, nor->bouncebuf, 1); } +/* + * Write status register2 1 byte + * Returns negative if error occurred. + */ +static int write_puya_sr2(struct spi_nor *nor, u8 val) +{ + nor->bouncebuf[0] = val; + return nor->write_reg(nor, SPINOR_OP_WRSR2, nor->bouncebuf, 1); +} + +/* + * Write configuration register 1 byte + * Returns negative if error occurred. + */ +static int write_puya_cr(struct spi_nor *nor, u8 val) +{ + nor->bouncebuf[0] = val; + return nor->write_reg(nor, SPINOR_OP_WRSR3, nor->bouncebuf, 1); +} + /* * Set write enable latch with Write Enable command. * Returns negative if error occurred. @@ -1401,6 +1457,48 @@ static int write_sr_and_check(struct spi_nor *nor, u8 status_new, u8 mask) return ((ret & mask) != (status_new & mask)) ? -EIO : 0; } +/* Write status register2 and ensure bits in mask match written values */ +static int write_sr2_and_check(struct spi_nor *nor, u8 status_new, u8 mask) +{ + int ret; + + write_enable(nor); + ret = write_puya_sr2(nor, status_new); + if (ret) + return ret; + + ret = spi_nor_wait_till_ready(nor); + if (ret) + return ret; + + ret = read_puya_sr2(nor); + if (ret < 0) + return ret; + + return ((ret & status_new) != (status_new & status_new)) ? -EIO : 0; +} + +/* Write configuration register and ensure bits in mask match written values */ +static int write_cr_and_check(struct spi_nor *nor, u8 status_new, u8 mask) +{ + int ret; + + write_enable(nor); + ret = write_puya_cr(nor, status_new); + if (ret) + return ret; + + ret = spi_nor_wait_till_ready(nor); + if (ret) + return ret; + + ret = read_puya_cr(nor); + if (ret < 0) + return ret; + + return ((ret & mask) != (status_new & mask)) ? -EIO : 0; +} + static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs, uint64_t *len) { @@ -1672,6 +1770,175 @@ static const struct spi_nor_locking_ops stm_locking_ops = { .is_locked = stm_is_locked, }; +/* unlock except UDISK */ +/* 解锁先判断CMP位,再决定sr2应该写什么 */ +static int py_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) +{ + uint8_t mask = 0; + uint8_t status1 = 0; + uint8_t status2 = 0; + + if (nor->info->id[2] == 0x19) // py25q256hb id:0x852019 + { + status1 = (uint8_t)read_sr(nor); + /* check cmp first */ + status2 = (uint8_t)read_puya_sr2(nor); + // if ((status2 < 0) || (status1 < 0)) + // { + // pr_emerg("py_lock read err!:%x %x\n", status1, status2); + // return -1; + // } + if (status2 & (SR2_CMP_GD)) // cmp=1 + { + mask = (SR_BP2 | SR_BP3); + status1 |= mask; + } + else // cmp=0 + { + mask = (uint8_t) ~(SR_BP0 | SR_BP1 | SR_BP2 | SR_BP3); + status1 &= mask; + } + if (write_sr_and_check(nor, status1, mask) != 0) + { + pr_emerg("py_unlock sr err!:%x\n", status1); + return -1; + } + return 0; + } + else if (nor->info->id[2] == 0x18) // py25q128ha id:0x852018 + { + pr_emerg("not support py25q128ha yet\n"); + return -1; + } + return -1; +} + +/* lock except UDISK */ +/* 上锁先判断CMP位,然后配置CMP位确保为1(cmp default值需要改变)再写sr2 */ +/* 第一次上电会调用这个函数更改CMP位,只要上电过一次,flash就会改成CMP=1 */ +static int py_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) +{ + uint8_t status1 = 0; + uint8_t status2 = 0; + uint8_t status_cr = 0; + uint8_t mask = 0; + if (nor->info->id[2] == 0x19) // py25q256hb id:0x852019 + { + /* read old sr1 and sr2 */ + status2 = (uint8_t)read_puya_sr2(nor); + status1 = (uint8_t)read_sr(nor); + status_cr = (uint8_t)read_puya_cr(nor); + // if ((status2 < 0) || (status1 < 0) || (status_cr < 0)) + // { + // pr_emerg("py_lock read err!:%x %x %x\n", status1, status2, status_cr); + // return -1; + // } + + if ((status2 & SR2_CMP_GD) == 0) // set cmp=1 if it's not 1 + { + /* first write sr2 CMP=1 */ + status2 |= (SR2_CMP_GD); + if (write_sr2_and_check(nor, status2, status2) != 0) + { + pr_emerg("py_lock sr2 err!:%x\n", status2); + return -1; + } + } + + if ((status_cr & SR_WPS_EN_WINBOND) != 0) // set wps=0 if it's not 0 + { + /* first write CR WPS=0 */ + status_cr &= ~(SR_WPS_EN_WINBOND); + if (write_cr_and_check(nor, status_cr, status_cr) != 0) + { + pr_emerg("py_lock cr err!:%x\n", status_cr); + return -1; + } + } + + /* sr1 lower 3/4 24MB except UDISK */ + mask |= (SR_BP3); + mask &= ~(SR_BP0 | SR_BP1 | SR_BP2 | SR_BP4); + // 0x7c 0111 1100 Status Register BP0~BP4,只判断这几位 + if ((status1 & 0x7c) != mask) + { + status1 |= (SR_BP3); + status1 &= ~(SR_BP0 | SR_BP1 | SR_BP2 | SR_BP4); + if (write_sr_and_check(nor, status1, mask) != 0) + { + pr_emerg("py_lock sr err!:%x\n", status1); + return -1; + } + } + + return 0; + } + else if (nor->info->id[2] == 0x18) // py25q128ha id:0x852018 + { + // pr_emerg("not support py25q128ha yet\n"); + return -1; + } + return -1; +} + +/* + * Check if the flash is locked. py_is_locked for + * more info. + * + * Returns 1 if entire region is locked, 0 is unlocked, and + * negative on errors. + */ +static int py_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len) +{ + uint8_t mask = 0; + uint8_t status1 = 0; + uint8_t status2 = 0; + if (nor->info->id[2] == 0x19) // py25q256hb id:0x852019 + { + status1 = (uint8_t)read_sr(nor); + /* check cmp first */ + status2 = (uint8_t)read_puya_sr2(nor); + // if ((status2 < 0) || (status1 < 0)) + // { + // pr_emerg("py_lock read err!:%x %x\n", status1, status2); + // return -1; + // } + /* unlock status mask */ + if (status2 & (SR2_CMP_GD)) // cmp=1 + { + mask = (SR_BP2 | SR_BP3); + /* TODO:还有一种情况也算unlock,但是暂时未使用 */ + } + else // cmp=0 + { + mask &= ~(SR_BP0 | SR_BP1 | SR_BP2 | SR_BP3); + } + + if ((status1 & 0x7c) != mask) + { + // printk(KERN_EMERG "lock\n"); + return 1; + } + else + { + // printk(KERN_EMERG "unlock\n"); + return 0; + } + } + else if (nor->info->id[2] == 0x18) // py25q128ha id:0x852018 + { + pr_emerg("not support py25q128ha yet\n"); + return -1; + } + return -1; +} + +static const struct spi_nor_locking_ops puya_locking_ops = { + .lock = py_lock, + .unlock = py_unlock, + .is_locked = py_is_locked, +}; + static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { struct spi_nor *nor = mtd_to_spi_nor(mtd); @@ -2091,6 +2358,78 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor) return spi_nor_clear_sr_bp(nor); } +/** + * HAS : spi_nor_puya_clear_sr_bp() - clear the Status Register Block Protection + * bits on puya flashes. + * @nor: pointer to a 'struct spi_nor' + * 前提WPS=0,根据sr寄存器CMP位,判断应该写什么解锁 + * + * + * Return: 0 on success, -errno otherwise. + */ +static int spi_nor_puya_clear_sr_bp(struct spi_nor *nor) +{ + uint8_t mask = 0; + uint8_t status1 = 0; + uint8_t status2 = 0; + + if (nor->info->id[2] == 0x19) // py25q256hb id:0x852019 + { + status1 = (uint8_t)read_sr(nor); + /* check cmp first */ + status2 = (uint8_t)read_puya_sr2(nor); + // if ((status1 < 0) || (status2 < 0)) + // { + // pr_emerg("clear_sr_bp read err!:%x %x\n", status1, status2); + // return -1; + // } + if (status2 & (SR2_CMP_GD)) // cmp=1 + { + mask = (SR_BP2 | SR_BP3); + status1 |= mask; + } + else // cmp=0 + { + mask = (uint8_t) ~(SR_BP0 | SR_BP1 | SR_BP2 | SR_BP3); + status1 &= mask; + } + if (write_sr_and_check(nor, status1, status1) != 0) + { + pr_emerg("clear_sr_bp sr err!:%x\n", status1); + return -1; + } + + return 0; + } + else if (nor->info->id[2] == 0x18) // py25q128ha id:0x852018 + { + status1 = (uint8_t)read_sr(nor); + /* check cmp first */ + status2 = (uint8_t)read_puya_sr2(nor); + // if ((status2 < 0) || (status1 < 0)) + // { + // printf("clear_sr_bp err!:%x %x\n", status1, status2); + // } + if (status2 & (SR2_CMP_GD)) // cmp=1 + { + mask = (SR_BP0 | SR_BP1 | SR_BP2); + status1 |= mask; + } + else // cmp=0 + { + mask = (uint8_t) ~(SR_BP0 | SR_BP1 | SR_BP2); + status1 &= mask; + } + if (write_sr_and_check(nor, status1, mask) != 0) + { + pr_emerg("clear_sr_bp sr err!:%x\n", status1); + return -1; + } + return 0; + } + return -1; +} + /* Used when the "_ext_id" is two bytes at most */ #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ .id = { \ @@ -2575,11 +2914,11 @@ static const struct flash_info spi_nor_ids[] = { { "XM25QH128C", INFO(0x204018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, /* PUYA */ - { "py25q128ha", INFO(0x852018, 0, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_IO_MODE | USE_RX_DTR) }, + { "py25q128ha", INFO(0x852018, 0, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_IO_MODE | USE_RX_DTR | SPI_NOR_HAS_LOCK) }, { "p25q128", INFO(0x856018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "p25q64h", INFO(0x856017, 0x0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "p25q32h", INFO(0x856016, 0x0, 64 * 1024, 64, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "py25q256hb", INFO(0x852019, 0x0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | USE_IO_MODE | USE_RX_DTR) }, + { "py25q256hb", INFO(0x852019, 0x0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | USE_IO_MODE | USE_RX_DTR | SPI_NOR_HAS_LOCK) }, /*Zetta*/ { "zd25q64b", INFO(0xba3217, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, @@ -4696,7 +5035,16 @@ static void spi_nor_late_init_params(struct spi_nor *nor) * the default ones. */ if (nor->flags & SNOR_F_HAS_LOCK && !nor->params.locking_ops) - nor->params.locking_ops = &stm_locking_ops; + { + if (JEDEC_MFR(nor->info) == SNOR_MFR_PUYA) + { + nor->params.locking_ops = &puya_locking_ops; + } + else // use default + { + nor->params.locking_ops = &stm_locking_ops; + } + } } /** @@ -4773,6 +5121,7 @@ static int spi_nor_init(struct spi_nor *nor) { int err; +#ifndef CONFIG_SPI_FLASH_DEFAULT_LOCK if (nor->clear_sr_bp) { if (nor->params.quad_enable == spansion_quad_enable) nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp; @@ -4784,12 +5133,17 @@ static int spi_nor_init(struct spi_nor *nor) return err; } } +#endif err = spi_nor_quad_enable(nor); if (err) { dev_err(nor->dev, "quad mode not supported\n"); return err; } +#if defined(CONFIG_SPI_FLASH_DEFAULT_LOCK) + /* 上电就给flash特定区域上锁 */ + nor->mtd._lock(&nor->mtd, 0, 0); +#endif if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES)) { /* @@ -5419,11 +5773,23 @@ int spif_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up * with the software protection bits set. */ - if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL || - JEDEC_MFR(nor->info) == SNOR_MFR_INTEL || - JEDEC_MFR(nor->info) == SNOR_MFR_SST || - nor->info->flags & SPI_NOR_HAS_LOCK) - nor->clear_sr_bp = spi_nor_clear_sr_bp; + if (nor->info->flags & SPI_NOR_HAS_LOCK) + { + if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL || + JEDEC_MFR(nor->info) == SNOR_MFR_INTEL || + JEDEC_MFR(nor->info) == SNOR_MFR_SST) + { + nor->clear_sr_bp = spi_nor_clear_sr_bp; + } + else if (JEDEC_MFR(nor->info) == SNOR_MFR_PUYA) + { + nor->clear_sr_bp = spi_nor_puya_clear_sr_bp; + } + else + { + nor->clear_sr_bp = NULL; + } + } /* Init flash parameters based on flash_info struct and SFDP */ spi_nor_init_params(nor); diff --git a/target/allwinner/v851s3-fastboot_sl100_front/busybox-init-base-ota-files/APP/SL100FRONTPANEL b/target/allwinner/v851s3-fastboot_sl100_front/busybox-init-base-ota-files/APP/SL100FRONTPANEL index 8384e85e6..812cc564a 100755 Binary files a/target/allwinner/v851s3-fastboot_sl100_front/busybox-init-base-ota-files/APP/SL100FRONTPANEL and b/target/allwinner/v851s3-fastboot_sl100_front/busybox-init-base-ota-files/APP/SL100FRONTPANEL differ