From c1d264e84e92a637b73a0db7be7e973fee816ccd Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 3 Feb 2021 17:53:57 +0100 Subject: spi: imx: Implement set_speed The set_speed() callback should configure the bus speed, make it so. Signed-off-by: Marek Vasut Cc: Stefano Babic Reviewed-by: Jagan Teki Reviewed-by: Bin Meng --- drivers/spi/mxc_spi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/mxc_spi.c index bb68eb90e9..f3dddbdbd7 100644 --- a/drivers/spi/mxc_spi.c +++ b/drivers/spi/mxc_spi.c @@ -662,7 +662,10 @@ static int mxc_spi_release_bus(struct udevice *dev) static int mxc_spi_set_speed(struct udevice *bus, uint speed) { - /* Nothing to do */ + struct mxc_spi_slave *mxcs = dev_get_plat(bus); + + mxcs->max_hz = speed; + return 0; } -- cgit v1.2.3 From eb69d797d36788ede4304b42bb981c61aa1c2ad3 Mon Sep 17 00:00:00 2001 From: Alper Nebi Yasak Date: Sat, 31 Oct 2020 19:20:12 +0300 Subject: mtd: spi-nor-ids: Add Gigadevice GD25LQ64C Add GD25LQ24C 64Mbit chip to spi-nor id table. This chip is used on rk3399-gru-kevin: => sf probe SF: Detected gd25lq64c with page size 256 Bytes, erase size 4 KiB, total 8 MiB => sf erase 0x600000 0x200000 SF: 2097152 bytes @ 0x600000 Erased: OK => sf test 0x700000 0x1000 SPI flash test: 0 erase: 52 ticks, 76 KiB/s 0.608 Mbps 1 check: 5 ticks, 800 KiB/s 6.400 Mbps 2 write: 14 ticks, 285 KiB/s 2.280 Mbps 3 read: 3 ticks, 1333 KiB/s 10.664 Mbps Test passed 0 erase: 52 ticks, 76 KiB/s 0.608 Mbps 1 check: 5 ticks, 800 KiB/s 6.400 Mbps 2 write: 14 ticks, 285 KiB/s 2.280 Mbps 3 read: 3 ticks, 1333 KiB/s 10.664 Mbps The values are the same as in Linux, except adjusted for the U-Boot definition of INFO(). Signed-off-by: Alper Nebi Yasak Reviewed-by: Jagan Teki --- drivers/mtd/spi/spi-nor-ids.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c index 5bd5dd3003..26eac62f59 100644 --- a/drivers/mtd/spi/spi-nor-ids.c +++ b/drivers/mtd/spi/spi-nor-ids.c @@ -107,6 +107,11 @@ const struct flash_info spi_nor_ids[] = { SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, + { + INFO("gd25lq64c", 0xc86017, 0, 64 * 1024, 128, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, { INFO("gd25q128", 0xc84018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -- cgit v1.2.3 From 6770c96fe59eca919805904c48fafac97720be74 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 6 Jan 2021 20:58:54 +0800 Subject: mtd: spi-nor.h: Change spaces to tabs U-Boot coding convention prefers tabs over spaces. Signed-off-by: Bin Meng Reviewed-by: Jagan Teki --- include/linux/mtd/spi-nor.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 4a8e19ee4f..0c438e9c89 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -48,13 +48,13 @@ #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_READ_1_1_8 0x8b /* Read data bytes (Octal Output SPI) */ -#define SPINOR_OP_READ_1_8_8 0xcb /* Read data bytes (Octal I/O SPI) */ +#define SPINOR_OP_READ_1_1_8 0x8b /* Read data bytes (Octal Output SPI) */ +#define SPINOR_OP_READ_1_8_8 0xcb /* Read data bytes (Octal 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_PP_1_1_8 0x82 /* Octal page program */ -#define SPINOR_OP_PP_1_8_8 0xc2 /* Octal page program */ +#define SPINOR_OP_PP_1_1_8 0x82 /* Octal page program */ +#define SPINOR_OP_PP_1_8_8 0xc2 /* Octal 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 */ @@ -75,13 +75,13 @@ #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_READ_1_1_8_4B 0x7c /* Read data bytes (Octal Output SPI) */ -#define SPINOR_OP_READ_1_8_8_4B 0xcc /* Read data bytes (Octal I/O SPI) */ +#define SPINOR_OP_READ_1_1_8_4B 0x7c /* Read data bytes (Octal Output SPI) */ +#define SPINOR_OP_READ_1_8_8_4B 0xcc /* Read data bytes (Octal 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_PP_1_1_8_4B 0x84 /* Octal page program */ -#define SPINOR_OP_PP_1_8_8_4B 0x8e /* Octal page program */ +#define SPINOR_OP_PP_1_1_8_4B 0x84 /* Octal page program */ +#define SPINOR_OP_PP_1_8_8_4B 0x8e /* Octal 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) */ @@ -122,8 +122,8 @@ #define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */ /* Used for Micron flashes only. */ -#define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */ -#define SPINOR_OP_WD_EVCR 0x61 /* Write EVCR register */ +#define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */ +#define SPINOR_OP_WD_EVCR 0x61 /* Write EVCR register */ /* Status Register bits. */ #define SR_WIP BIT(0) /* Write in progress */ -- cgit v1.2.3 From de76ae36f622177e9af38b158d7f2f753d826d2c Mon Sep 17 00:00:00 2001 From: Su Baocheng Date: Mon, 25 Jan 2021 10:59:05 +0800 Subject: mtd: spi-nor-ids: Add support of flash protection to w25q128 The NOR flash w25q128 denoted by JEDEC ID 0xef4018 actually represents various models. From Winbond's website, I could only find 3 types of them: W25Q128JV-IQ/JQ datasheet:https://www.winbond.com/resource-files/ w25q128jv%20revg%2004082019%20plus.pdf W25Q128FV (SPI Mode) datasheet: https://www.winbond.com/resource-files/ w25q128fv%20rev.m%2005132016%20kms.pdf W25Q128BV datesheet: https://www.winbond.com/resource-files/ w25q128bv_revh_100313_wo_automotive.pdf According to the datasheets, all of these 3 types support BP(0,1,2) and TB bits in the status register (SR), so it could reuse the flash protection logic for ST Micro. So it should be safe to add the SPI_NOR_HAS_LOCK and SPI_NOR_HAS_TB flags to the w25q128 entry of spi_nor_ids table. Signed-off-by: Su Baocheng [jagan: remove comments in spi-nor-ids.c] Signed-off-by: Jagan Teki Reviewed-by: Jagan Teki --- drivers/mtd/spi/spi-nor-ids.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c index 26eac62f59..2b57797954 100644 --- a/drivers/mtd/spi/spi-nor-ids.c +++ b/drivers/mtd/spi/spi-nor-ids.c @@ -324,7 +324,10 @@ const struct flash_info spi_nor_ids[] = { { INFO("w25q80bl", 0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { INFO("w25q16cl", 0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { INFO("w25q64cv", 0xef4017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { INFO("w25q128", 0xef4018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { INFO("w25q128", 0xef4018, 0, 64 * 1024, 256, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, { INFO("w25q256", 0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { INFO("w25m512jw", 0xef6119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { INFO("w25m512jv", 0xef7119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -- cgit v1.2.3 From 90d76f812b29c88f47279eca034da70d30a798d9 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Mon, 18 Jan 2021 15:32:49 -0600 Subject: spi: nxp_fspi: Fix error reporting On the i.MX8M Mini, ret = clk_set_rate() sets ret to the value of the rate the clock was able to set. When checking for errors, it only checks that it is not NULL. Since positive numbers are not errors, only check for negative numbers when handling errors. Fixes: 383fded70c4f ("spi: nxp_fspi: new driver for the FlexSPI controller") Signed-off-by: Adam Ford Reviewed-by: Pratyush Yadav Reviewed-by: Jagan Teki --- drivers/spi/nxp_fspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/nxp_fspi.c b/drivers/spi/nxp_fspi.c index 012f304595..6c5bad4c2c 100644 --- a/drivers/spi/nxp_fspi.c +++ b/drivers/spi/nxp_fspi.c @@ -823,7 +823,7 @@ static int nxp_fspi_default_setup(struct nxp_fspi *f) /* the default frequency, we will change it later if necessary. */ ret = clk_set_rate(&f->clk, 20000000); - if (ret) + if (ret < 0) return ret; ret = nxp_fspi_clk_prep_enable(f); @@ -914,7 +914,7 @@ static int nxp_fspi_set_speed(struct udevice *bus, uint speed) nxp_fspi_clk_disable_unprep(f); ret = clk_set_rate(&f->clk, speed); - if (ret) + if (ret < 0) return ret; ret = nxp_fspi_clk_prep_enable(f); -- cgit v1.2.3 From 1bb8ca3b4b3debfa6b42f3430c81c00c3807cafe Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Thu, 4 Feb 2021 23:11:06 -0500 Subject: cmd: sf: Display errno on erase failure If there is an error while erasing SPI flash, no errno is displayed. This makes it difficult to determine the cause of the error. This change mirrors the logic for write errors above. Signed-off-by: Sean Anderson Reviewed-by: Bin Meng Reviewed-by: Pratyush Yadav Reviewed-by: Jagan Teki --- cmd/sf.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cmd/sf.c b/cmd/sf.c index c0d6a8f8a0..de80fcd38b 100644 --- a/cmd/sf.c +++ b/cmd/sf.c @@ -344,8 +344,11 @@ static int do_spi_flash_erase(int argc, char *const argv[]) } ret = spi_flash_erase(flash, offset, size); - printf("SF: %zu bytes @ %#x Erased: %s\n", (size_t)size, (u32)offset, - ret ? "ERROR" : "OK"); + printf("SF: %zu bytes @ %#x Erased: ", (size_t)size, (u32)offset); + if (ret) + printf("ERROR %d\n", ret); + else + printf("OK\n"); return ret == 0 ? 0 : 1; } -- cgit v1.2.3 From 9bc772812d333c43a244cb15ddba0c919f4daccf Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Thu, 4 Feb 2021 23:11:07 -0500 Subject: cmd: sf: Print error on test failure The sf test command is used to test spi flashes (and spi masters). Printing the exact error code is very helpful to those debugging the spi stack. Signed-off-by: Sean Anderson Reviewed-by: Bin Meng Reviewed-by: Pratyush Yadav Reviewed-by: Jagan Teki --- cmd/sf.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/cmd/sf.c b/cmd/sf.c index de80fcd38b..46346fb9d4 100644 --- a/cmd/sf.c +++ b/cmd/sf.c @@ -445,20 +445,22 @@ static int spi_flash_test(struct spi_flash *flash, uint8_t *buf, ulong len, ulong offset, uint8_t *vbuf) { struct test_info test; - int i; + int err, i; printf("SPI flash test:\n"); memset(&test, '\0', sizeof(test)); test.base_ms = get_timer(0); test.bytes = len; - if (spi_flash_erase(flash, offset, len)) { - printf("Erase failed\n"); + err = spi_flash_erase(flash, offset, len); + if (err) { + printf("Erase failed (err = %d)\n", err); return -1; } spi_test_next_stage(&test); - if (spi_flash_read(flash, offset, len, vbuf)) { - printf("Check read failed\n"); + err = spi_flash_read(flash, offset, len, vbuf); + if (err) { + printf("Check read failed (err = %d)\n", err); return -1; } for (i = 0; i < len; i++) { @@ -471,15 +473,17 @@ static int spi_flash_test(struct spi_flash *flash, uint8_t *buf, ulong len, } spi_test_next_stage(&test); - if (spi_flash_write(flash, offset, len, buf)) { - printf("Write failed\n"); + err = spi_flash_write(flash, offset, len, buf); + if (err) { + printf("Write failed (err = %d)\n", err); return -1; } memset(vbuf, '\0', len); spi_test_next_stage(&test); - if (spi_flash_read(flash, offset, len, vbuf)) { - printf("Read failed\n"); + err = spi_flash_read(flash, offset, len, vbuf); + if (err) { + printf("Read failed (ret = %d)\n", err); return -1; } spi_test_next_stage(&test); -- cgit v1.2.3 From a95d878adebe1e8cc06090c6a38a85ff73390e29 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Thu, 4 Feb 2021 23:11:08 -0500 Subject: mtd: spi-nor-core: Fix typo in documentation This line should come before the docs for the next function. Fixes: 7aeedac0153 ("mtd: spi: Port SPI NOR framework from Linux") Signed-off-by: Sean Anderson Reviewed-by: Bin Meng Reviewed-by: Pratyush Yadav Reviewed-by: Jagan Teki --- include/linux/mtd/spi-nor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 0c438e9c89..c3e38e499e 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -302,8 +302,8 @@ struct spi_flash { * @flash_lock: [FLASH-SPECIFIC] lock a region of the SPI NOR * @flash_unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR * @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is - * @quad_enable: [FLASH-SPECIFIC] enables SPI NOR quad mode * completely locked + * @quad_enable: [FLASH-SPECIFIC] enables SPI NOR quad mode * @priv: the private data */ struct spi_nor { -- cgit v1.2.3 From 12926f46fdf443144451416939074c688b2c43a4 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Thu, 11 Feb 2021 13:05:47 +0100 Subject: mtd: nand: spi: Only one dummy byte in QUADIO The datasheet only lists one dummy byte in the 0xEB operation for the following chips: * GD5F1GQ4xExxG * GD5F1GQ4xFxxG * GD5F1GQ4UAYIG * GD5F4GQ4UAYIG Reto Schneider: - Linux patch ported to U-Boot - Checked for compatibility with GD5F1GQ4xBxxG - Fixed operation code in original commit message (0xEH -> 0xEB) Signed-off-by: Reto Schneider Reviewed-by: Stefan Roese Acked-by: Jagan Teki --- drivers/mtd/nand/spi/gigadevice.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c index 0b228dcb5b..5de0ebbb7b 100644 --- a/drivers/mtd/nand/spi/gigadevice.c +++ b/drivers/mtd/nand/spi/gigadevice.c @@ -20,7 +20,7 @@ #define GD5FXGQ4XEXXG_REG_STATUS2 0xf0 static SPINAND_OP_VARIANTS(read_cache_variants, - SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), -- cgit v1.2.3 From 783a15b35131abc599ec6deca55cf841d2e7c208 Mon Sep 17 00:00:00 2001 From: Reto Schneider Date: Thu, 11 Feb 2021 13:05:48 +0100 Subject: mtd: nand: spi: Support GigaDevice 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 form 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: Stefan Roese Acked-by: Jagan Teki --- drivers/mtd/nand/spi/gigadevice.c | 79 ++++++++++++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 10 deletions(-) diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c index 5de0ebbb7b..a2c93486f4 100644 --- a/drivers/mtd/nand/spi/gigadevice.c +++ b/drivers/mtd/nand/spi/gigadevice.c @@ -17,9 +17,13 @@ #define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4) #define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4) -#define GD5FXGQ4XEXXG_REG_STATUS2 0xf0 +#define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS (1 << 4) +#define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS (3 << 4) -static SPINAND_OP_VARIANTS(read_cache_variants, +#define GD5FXGQXXEXXG_REG_STATUS2 0xf0 + +/* Q4 devices, QUADIO: Dummy bytes valid for 1 and 2 GBit variants */ +static SPINAND_OP_VARIANTS(gd5fxgq4_read_cache_variants, SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), @@ -27,6 +31,15 @@ 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)); +/* Q5 devices, QUADIO: Dummy bytes only valid for 1 GBit variants */ +static SPINAND_OP_VARIANTS(gd5f1gq5_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), + 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(write_cache_variants, SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), SPINAND_PROG_LOAD(true, 0, NULL, 0)); @@ -35,7 +48,7 @@ static SPINAND_OP_VARIANTS(update_cache_variants, SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), SPINAND_PROG_LOAD(false, 0, NULL, 0)); -static int gd5fxgq4xexxg_ooblayout_ecc(struct mtd_info *mtd, int section, +static int gd5fxgqxxexxg_ooblayout_ecc(struct mtd_info *mtd, int section, struct mtd_oob_region *region) { if (section) @@ -47,7 +60,7 @@ static int gd5fxgq4xexxg_ooblayout_ecc(struct mtd_info *mtd, int section, return 0; } -static int gd5fxgq4xexxg_ooblayout_free(struct mtd_info *mtd, int section, +static int gd5fxgqxxexxg_ooblayout_free(struct mtd_info *mtd, int section, struct mtd_oob_region *region) { if (section) @@ -64,7 +77,7 @@ static int gd5fxgq4xexxg_ecc_get_status(struct spinand_device *spinand, u8 status) { u8 status2; - struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQ4XEXXG_REG_STATUS2, + struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2, &status2); int ret; @@ -102,21 +115,67 @@ static int gd5fxgq4xexxg_ecc_get_status(struct spinand_device *spinand, return -EINVAL; } -static const struct mtd_ooblayout_ops gd5fxgq4xexxg_ooblayout = { - .ecc = gd5fxgq4xexxg_ooblayout_ecc, - .rfree = gd5fxgq4xexxg_ooblayout_free, +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->slave, &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 const struct mtd_ooblayout_ops gd5fxgqxxexxg_ooblayout = { + .ecc = gd5fxgqxxexxg_ooblayout_ecc, + .rfree = gd5fxgqxxexxg_ooblayout_free, }; static const struct spinand_info gigadevice_spinand_table[] = { SPINAND_INFO("GD5F1GQ4UExxG", 0xd1, NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), NAND_ECCREQ(8, 512), - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + SPINAND_INFO_OP_VARIANTS(&gd5fxgq4_read_cache_variants, &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&gd5fxgq4xexxg_ooblayout, + SPINAND_ECCINFO(&gd5fxgqxxexxg_ooblayout, gd5fxgq4xexxg_ecc_get_status)), + SPINAND_INFO("GD5F1GQ5UExxG", 0x51, + NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), + NAND_ECCREQ(4, 512), + SPINAND_INFO_OP_VARIANTS(&gd5f1gq5_read_cache_variants, + &write_cache_variants, + &update_cache_variants), + 0, + SPINAND_ECCINFO(&gd5fxgqxxexxg_ooblayout, + gd5fxgq5xexxg_ecc_get_status)), }; static int gigadevice_spinand_detect(struct spinand_device *spinand) -- cgit v1.2.3