From 379b49d82ee3304b55ece1f32d95fbeef9e0176a Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Thu, 3 Dec 2015 22:19:05 +0530 Subject: [PATCH 01/21] spi: Get spi-3wire from dts spi-3wire is used when SI/SO signals shared so get the same from dts node and assign to mode on slave plat->mode. Acked-by: Simon Glass Signed-off-by: Jagan Teki --- drivers/spi/spi-uclass.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index 3c7d64ae63..e0f6b25f30 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -378,6 +378,8 @@ int spi_slave_ofdata_to_platdata(const void *blob, int node, mode |= SPI_CPHA; if (fdtdec_get_bool(blob, node, "spi-cs-high")) mode |= SPI_CS_HIGH; + if (fdtdec_get_bool(blob, node, "spi-3wire")) + mode |= SPI_3WIRE; if (fdtdec_get_bool(blob, node, "spi-half-duplex")) mode |= SPI_PREAMBLE; plat->mode = mode; From cd337da21ecea0f34335d3b2d33bcd28d9e3d0d0 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Thu, 3 Dec 2015 22:25:20 +0530 Subject: [PATCH 02/21] spi: ti_qspi: Fix SPI_3WIRE checking using mode SPI_3WIRE is spi mode not spi flags, so this patch fixed the spi-3wire checking throgh mode instead of flags. Cc: Mugunthan V N Acked-by: Simon Glass Signed-off-by: Jagan Teki --- drivers/spi/ti_qspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c index 646dd899d3..5747ed1fa9 100644 --- a/drivers/spi/ti_qspi.c +++ b/drivers/spi/ti_qspi.c @@ -293,7 +293,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, qslave->cmd = 0; qslave->cmd |= QSPI_WLEN(8); qslave->cmd |= QSPI_EN_CS(slave->cs); - if (flags & SPI_3WIRE) + if (qslave->mode & SPI_3WIRE) qslave->cmd |= QSPI_3_PIN; qslave->cmd |= 0xfff; From 53cc647dc63085438510ee3d65de399c92ca3cac Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 30 Nov 2015 17:45:02 +0800 Subject: [PATCH 03/21] imx: mx7dsabresd: Add QSPI support Support qspi flashes for mx7dsabresd 1. introduce pin mux settings 2. enable qspi clock 3. introduce related macro definitions Default QSPI is not enabled, since we need hardware rework to use QSPI, see SPF-28590, page 9: " QSPI signals are muxed with EPDC_D[7:0] When using QSPI: de-populate R388-R391, R396-R399 populate R392-R395, R299, R300 " After hardware rework, define CONFIG_FSL_QSPI in mx7dsabresd.h. qspi flashes can be deteced and read/erase/write. Log info: " => sf probe SF: Detected MX25L51235F with page size 256 Bytes, erase size 64 KiB, total 64 MiB => sf read 0x80000000 0 0x4000000 device 0 whole chip SF: 67108864 bytes @ 0x0 Read: OK => sf erase 0 0x4000000 SF: 67108864 bytes @ 0x0 Erased: OK => sf write 0x80000000 0 0x4000000 device 0 whole chip SF: 67108864 bytes @ 0x0 Written: OK " Cc: Fabio Estevam Cc: Adrian Alonso Reviewed-by: Stefano Babic Reviewed-by: Jagan Teki Signed-off-by: Peng Fan --- board/freescale/mx7dsabresd/mx7dsabresd.c | 30 +++++++++++++++++++++++ include/configs/mx7dsabresd.h | 15 ++++++++++++ 2 files changed, 45 insertions(+) diff --git a/board/freescale/mx7dsabresd/mx7dsabresd.c b/board/freescale/mx7dsabresd/mx7dsabresd.c index 6c863dae5a..f8ae9733fc 100644 --- a/board/freescale/mx7dsabresd/mx7dsabresd.c +++ b/board/freescale/mx7dsabresd/mx7dsabresd.c @@ -44,6 +44,9 @@ DECLARE_GLOBAL_DATA_PTR; #define LCD_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_PU100KOHM | \ PAD_CTL_DSE_3P3V_49OHM) +#define QSPI_PAD_CTRL \ + (PAD_CTL_DSE_3P3V_49OHM | PAD_CTL_PUE | PAD_CTL_PUS_PU47KOHM) + #ifdef CONFIG_SYS_I2C_MXC #define PC MUX_PAD_CTRL(I2C_PAD_CTRL) /* I2C1 for PMIC */ @@ -455,6 +458,29 @@ int board_phy_config(struct phy_device *phydev) } #endif +#ifdef CONFIG_FSL_QSPI +static iomux_v3_cfg_t const quadspi_pads[] = { + MX7D_PAD_EPDC_DATA00__QSPI_A_DATA0 | MUX_PAD_CTRL(QSPI_PAD_CTRL), + MX7D_PAD_EPDC_DATA01__QSPI_A_DATA1 | MUX_PAD_CTRL(QSPI_PAD_CTRL), + MX7D_PAD_EPDC_DATA02__QSPI_A_DATA2 | MUX_PAD_CTRL(QSPI_PAD_CTRL), + MX7D_PAD_EPDC_DATA03__QSPI_A_DATA3 | MUX_PAD_CTRL(QSPI_PAD_CTRL), + MX7D_PAD_EPDC_DATA05__QSPI_A_SCLK | MUX_PAD_CTRL(QSPI_PAD_CTRL), + MX7D_PAD_EPDC_DATA06__QSPI_A_SS0_B | MUX_PAD_CTRL(QSPI_PAD_CTRL), +}; + +int board_qspi_init(void) +{ + /* Set the iomux */ + imx_iomux_v3_setup_multiple_pads(quadspi_pads, + ARRAY_SIZE(quadspi_pads)); + + /* Set the clock */ + set_clk_qspi(); + + return 0; +} +#endif + int board_early_init_f(void) { setup_iomux_uart(); @@ -481,6 +507,10 @@ int board_init(void) setup_lcd(); #endif +#ifdef CONFIG_FSL_QSPI + board_qspi_init(); +#endif + return 0; } diff --git a/include/configs/mx7dsabresd.h b/include/configs/mx7dsabresd.h index cc98547461..22e515cccd 100644 --- a/include/configs/mx7dsabresd.h +++ b/include/configs/mx7dsabresd.h @@ -236,4 +236,19 @@ #define CONFIG_VIDEO_BMP_LOGO #endif +#ifdef CONFIG_FSL_QSPI +#define CONFIG_CMD_SF +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_MACRONIX +#define CONFIG_SPI_FLASH_BAR +#define CONFIG_SF_DEFAULT_BUS 0 +#define CONFIG_SF_DEFAULT_CS 0 +#define CONFIG_SF_DEFAULT_SPEED 40000000 +#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0 +#define FSL_QSPI_FLASH_NUM 1 +#define FSL_QSPI_FLASH_SIZE SZ_64M +#define QSPI0_BASE_ADDR QSPI1_IPS_BASE_ADDR +#define QSPI0_AMBA_BASE QSPI0_ARB_BASE_ADDR +#endif + #endif /* __CONFIG_H */ From 23ef5aea849ce2252086a4f79dde8205afc56a00 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 7 Dec 2015 13:06:54 +0100 Subject: [PATCH 04/21] spi: zynq_spi: Add cadence compatible string Extend compatible list table for cdns,spi-r1p6 compatible string. Reviewed-by: Jagan Teki Signed-off-by: Michal Simek --- drivers/spi/zynq_spi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/spi/zynq_spi.c b/drivers/spi/zynq_spi.c index 6ed2165355..09ae1be7e9 100644 --- a/drivers/spi/zynq_spi.c +++ b/drivers/spi/zynq_spi.c @@ -313,6 +313,7 @@ static const struct dm_spi_ops zynq_spi_ops = { static const struct udevice_id zynq_spi_ids[] = { { .compatible = "xlnx,zynq-spi-r1p6" }, + { .compatible = "cdns,spi-r1p6" }, { } }; From 8e4920e53e1a45658743d79d6fa29a1b44448622 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 7 Dec 2015 11:33:58 +0100 Subject: [PATCH 05/21] spi: Kconfig: Fix correct target name for ZynqMP ZynqMP is using different symbol. Use correct one. Reviewed-by: Jagan Teki Signed-off-by: Michal Simek --- drivers/spi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index a0dbd8b640..2cdb11025f 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -140,7 +140,7 @@ config XILINX_SPI config ZYNQ_SPI bool "Zynq SPI driver" - depends on ARCH_ZYNQ || TARGET_XILINX_ZYNQMP + depends on ARCH_ZYNQ || ARCH_ZYNQMP help Enable the Zynq SPI driver. This driver can be used to access the SPI NOR flash on platforms embedding this Zynq From 3a1adb621b985ebaf2c72ff179190b305577e1de Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Tue, 29 Sep 2015 17:28:20 +0530 Subject: [PATCH 06/21] sf: spi_flash_validate_params => spi_flash_scan Rename spi_flash_validate_params to spi_flash_scan as this code not only deals with params setup but also configure all spi_flash attributes. And also moved all flash related code into spi_flash_scan for future functionality addition. Tested-by: Jagan Teki Tested-by: Bin Meng Reviewed-by: Bin Meng Reviewed-by: Simon Glass Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_probe.c | 147 +++++++++++++++++++------------------ 1 file changed, 76 insertions(+), 71 deletions(-) diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index a619182a75..3da72df165 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -130,13 +130,42 @@ bank_end: } #endif -static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode, - struct spi_flash *flash) +#if CONFIG_IS_ENABLED(OF_CONTROL) +int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) +{ + fdt_addr_t addr; + fdt_size_t size; + int node; + + /* If there is no node, do nothing */ + node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH); + if (node < 0) + return 0; + + addr = fdtdec_get_addr_size(blob, node, "memory-map", &size); + if (addr == FDT_ADDR_T_NONE) { + debug("%s: Cannot decode address\n", __func__); + return 0; + } + + if (flash->size != size) { + debug("%s: Memory map must cover entire device\n", __func__); + return -1; + } + flash->memory_map = map_sysmem(addr, size); + + return 0; +} +#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ + +static int spi_flash_scan(struct spi_slave *spi, u8 *idcode, + struct spi_flash *flash) { const struct spi_flash_params *params; u8 cmd; u16 jedec = idcode[1] << 8 | idcode[2]; u16 ext_jedec = idcode[3] << 8 | idcode[4]; + int ret; /* Validate params from spi_flash_params table */ params = spi_flash_params_table; @@ -158,6 +187,13 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode, return -EPROTONOSUPPORT; } + /* Flash powers up read-only, so clear BP# bits */ +#if defined(CONFIG_SPI_FLASH_ATMEL) || \ + defined(CONFIG_SPI_FLASH_MACRONIX) || \ + defined(CONFIG_SPI_FLASH_SST) + spi_flash_cmd_write_status(flash, 0); +#endif + /* Assign spi data */ flash->spi = spi; flash->name = params->name; @@ -253,6 +289,17 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode, /* Go for default supported write cmd */ flash->write_cmd = CMD_PAGE_PROGRAM; + /* Set the quad enable bit - only for quad commands */ + if ((flash->read_cmd == CMD_READ_QUAD_OUTPUT_FAST) || + (flash->read_cmd == CMD_READ_QUAD_IO_FAST) || + (flash->write_cmd == CMD_QUAD_PAGE_PROGRAM)) { + ret = spi_flash_set_qeb(flash, idcode[0]); + if (ret) { + debug("SF: Fail to set QEB for %02x\n", idcode[0]); + return -EINVAL; + } + } + /* Read dummy_byte: dummy byte is determined based on the * dummy cycles of a particular command. * Fast commands - dummy_byte = dummy_cycles/8 @@ -279,48 +326,41 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode, /* Configure the BAR - discover bank cmds and read current bank */ #ifdef CONFIG_SPI_FLASH_BAR - int ret = spi_flash_read_bank(flash, idcode[0]); + ret = spi_flash_read_bank(flash, idcode[0]); if (ret < 0) return ret; #endif - /* Flash powers up read-only, so clear BP# bits */ -#if defined(CONFIG_SPI_FLASH_ATMEL) || \ - defined(CONFIG_SPI_FLASH_MACRONIX) || \ - defined(CONFIG_SPI_FLASH_SST) - spi_flash_cmd_write_status(flash, 0); +#if CONFIG_IS_ENABLED(OF_CONTROL) + ret = spi_flash_decode_fdt(gd->fdt_blob, flash); + if (ret) { + debug("SF: FDT decode error\n"); + return -EINVAL; + } #endif - return 0; -} +#ifndef CONFIG_SPL_BUILD + printf("SF: Detected %s with page size ", flash->name); + print_size(flash->page_size, ", erase size "); + print_size(flash->erase_size, ", total "); + print_size(flash->size, ""); + if (flash->memory_map) + printf(", mapped at %p", flash->memory_map); + puts("\n"); +#endif -#if CONFIG_IS_ENABLED(OF_CONTROL) -int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) -{ - fdt_addr_t addr; - fdt_size_t size; - int node; - - /* If there is no node, do nothing */ - node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH); - if (node < 0) - return 0; - - addr = fdtdec_get_addr_size(blob, node, "memory-map", &size); - if (addr == FDT_ADDR_T_NONE) { - debug("%s: Cannot decode address\n", __func__); - return 0; +#ifndef CONFIG_SPI_FLASH_BAR + if (((flash->dual_flash == SF_SINGLE_FLASH) && + (flash->size > SPI_FLASH_16MB_BOUN)) || + ((flash->dual_flash > SF_SINGLE_FLASH) && + (flash->size > SPI_FLASH_16MB_BOUN << 1))) { + puts("SF: Warning - Only lower 16MiB accessible,"); + puts(" Full access #define CONFIG_SPI_FLASH_BAR\n"); } +#endif - if (flash->size != size) { - debug("%s: Memory map must cover entire device\n", __func__); - return -1; - } - flash->memory_map = map_sysmem(addr, size); - - return 0; + return ret; } -#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ /** * spi_flash_probe_slave() - Probe for a SPI flash device on a bus @@ -359,47 +399,12 @@ int spi_flash_probe_slave(struct spi_slave *spi, struct spi_flash *flash) print_buffer(0, idcode, 1, sizeof(idcode), 0); #endif - if (spi_flash_validate_params(spi, idcode, flash)) { + ret = spi_flash_scan(spi, idcode, flash); + if (ret) { ret = -EINVAL; goto err_read_id; } - /* Set the quad enable bit - only for quad commands */ - if ((flash->read_cmd == CMD_READ_QUAD_OUTPUT_FAST) || - (flash->read_cmd == CMD_READ_QUAD_IO_FAST) || - (flash->write_cmd == CMD_QUAD_PAGE_PROGRAM)) { - if (spi_flash_set_qeb(flash, idcode[0])) { - debug("SF: Fail to set QEB for %02x\n", idcode[0]); - ret = -EINVAL; - goto err_read_id; - } - } - -#if CONFIG_IS_ENABLED(OF_CONTROL) - if (spi_flash_decode_fdt(gd->fdt_blob, flash)) { - debug("SF: FDT decode error\n"); - ret = -EINVAL; - goto err_read_id; - } -#endif -#ifndef CONFIG_SPL_BUILD - printf("SF: Detected %s with page size ", flash->name); - print_size(flash->page_size, ", erase size "); - print_size(flash->erase_size, ", total "); - print_size(flash->size, ""); - if (flash->memory_map) - printf(", mapped at %p", flash->memory_map); - puts("\n"); -#endif -#ifndef CONFIG_SPI_FLASH_BAR - if (((flash->dual_flash == SF_SINGLE_FLASH) && - (flash->size > SPI_FLASH_16MB_BOUN)) || - ((flash->dual_flash > SF_SINGLE_FLASH) && - (flash->size > SPI_FLASH_16MB_BOUN << 1))) { - puts("SF: Warning - Only lower 16MiB accessible,"); - puts(" Full access #define CONFIG_SPI_FLASH_BAR\n"); - } -#endif #ifdef CONFIG_SPI_FLASH_MTD ret = spi_flash_mtd_register(flash); #endif From 3847c0c18051a7a98982a3ae8ff1446b2b09a9ef Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Fri, 11 Dec 2015 21:36:34 +0530 Subject: [PATCH 07/21] sf: Move spi_flash_scan code to sf_ops Intension is that sf_ops should deals all spi_flash related stuff and sf_probe (which should renamed future) should be an interface layer for spi_flash versus spi drivers. sf_ops => spi_flash interface sf_probe => interface layer vs spi_flash(sf_probe) to spi drivers Tested-by: Jagan Teki Tested-by: Bin Meng Reviewed-by: Bin Meng Reviewed-by: Simon Glass Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_internal.h | 14 ++ drivers/mtd/spi/sf_ops.c | 343 ++++++++++++++++++++++++++++++++++ drivers/mtd/spi/sf_probe.c | 342 --------------------------------- 3 files changed, 357 insertions(+), 342 deletions(-) diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 85c8a89cee..f3eb6f3c46 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -245,4 +245,18 @@ int spi_flash_mtd_register(struct spi_flash *flash); void spi_flash_mtd_unregister(void); #endif +/** + * spi_flash_scan - scan the SPI FLASH + * @spi: the spi slave structure + * @idcode: idcode of spi flash + * @flash: the spi flash structure + * + * The drivers can use this fuction to scan the SPI FLASH. + * In the scanning, it will try to get all the necessary information to + * fill the spi_flash{}. + * + * Return: 0 for success, others for failure. + */ +int spi_flash_scan(struct spi_slave *spi, u8 *idcode, struct spi_flash *flash); + #endif /* _SF_INTERNAL_H_ */ diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index 3a56d7f55c..306db8f56e 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -19,6 +20,8 @@ #include "sf_internal.h" +DECLARE_GLOBAL_DATA_PTR; + static void spi_flash_addr(u32 addr, u8 *cmd) { /* cmd[0] is actual command */ @@ -757,3 +760,343 @@ int stm_unlock(struct spi_flash *flash, u32 ofs, size_t len) return 0; } #endif + + +/* Read commands array */ +static u8 spi_read_cmds_array[] = { + CMD_READ_ARRAY_SLOW, + CMD_READ_ARRAY_FAST, + CMD_READ_DUAL_OUTPUT_FAST, + CMD_READ_DUAL_IO_FAST, + CMD_READ_QUAD_OUTPUT_FAST, + CMD_READ_QUAD_IO_FAST, +}; + +#ifdef CONFIG_SPI_FLASH_MACRONIX +static int spi_flash_set_qeb_mxic(struct spi_flash *flash) +{ + u8 qeb_status; + int ret; + + ret = spi_flash_cmd_read_status(flash, &qeb_status); + if (ret < 0) + return ret; + + if (qeb_status & STATUS_QEB_MXIC) { + debug("SF: mxic: QEB is already set\n"); + } else { + ret = spi_flash_cmd_write_status(flash, STATUS_QEB_MXIC); + if (ret < 0) + return ret; + } + + return ret; +} +#endif + +#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) +static int spi_flash_set_qeb_winspan(struct spi_flash *flash) +{ + u8 qeb_status; + int ret; + + ret = spi_flash_cmd_read_config(flash, &qeb_status); + if (ret < 0) + return ret; + + if (qeb_status & STATUS_QEB_WINSPAN) { + debug("SF: winspan: QEB is already set\n"); + } else { + ret = spi_flash_cmd_write_config(flash, STATUS_QEB_WINSPAN); + if (ret < 0) + return ret; + } + + return ret; +} +#endif + +static int spi_flash_set_qeb(struct spi_flash *flash, u8 idcode0) +{ + switch (idcode0) { +#ifdef CONFIG_SPI_FLASH_MACRONIX + case SPI_FLASH_CFI_MFR_MACRONIX: + return spi_flash_set_qeb_mxic(flash); +#endif +#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) + case SPI_FLASH_CFI_MFR_SPANSION: + case SPI_FLASH_CFI_MFR_WINBOND: + return spi_flash_set_qeb_winspan(flash); +#endif +#ifdef CONFIG_SPI_FLASH_STMICRO + case SPI_FLASH_CFI_MFR_STMICRO: + debug("SF: QEB is volatile for %02x flash\n", idcode0); + return 0; +#endif + default: + printf("SF: Need set QEB func for %02x flash\n", idcode0); + return -1; + } +} + +#ifdef CONFIG_SPI_FLASH_BAR +static int spi_flash_read_bank(struct spi_flash *flash, u8 idcode0) +{ + u8 curr_bank = 0; + int ret; + + if (flash->size <= SPI_FLASH_16MB_BOUN) + goto bank_end; + + switch (idcode0) { + case SPI_FLASH_CFI_MFR_SPANSION: + flash->bank_read_cmd = CMD_BANKADDR_BRRD; + flash->bank_write_cmd = CMD_BANKADDR_BRWR; + default: + flash->bank_read_cmd = CMD_EXTNADDR_RDEAR; + flash->bank_write_cmd = CMD_EXTNADDR_WREAR; + } + + ret = spi_flash_read_common(flash, &flash->bank_read_cmd, 1, + &curr_bank, 1); + if (ret) { + debug("SF: fail to read bank addr register\n"); + return ret; + } + +bank_end: + flash->bank_curr = curr_bank; + return 0; +} +#endif + +#if CONFIG_IS_ENABLED(OF_CONTROL) +int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) +{ + fdt_addr_t addr; + fdt_size_t size; + int node; + + /* If there is no node, do nothing */ + node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH); + if (node < 0) + return 0; + + addr = fdtdec_get_addr_size(blob, node, "memory-map", &size); + if (addr == FDT_ADDR_T_NONE) { + debug("%s: Cannot decode address\n", __func__); + return 0; + } + + if (flash->size != size) { + debug("%s: Memory map must cover entire device\n", __func__); + return -1; + } + flash->memory_map = map_sysmem(addr, size); + + return 0; +} +#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ + +int spi_flash_scan(struct spi_slave *spi, u8 *idcode, struct spi_flash *flash) +{ + const struct spi_flash_params *params; + u8 cmd; + u16 jedec = idcode[1] << 8 | idcode[2]; + u16 ext_jedec = idcode[3] << 8 | idcode[4]; + int ret; + + /* Validate params from spi_flash_params table */ + params = spi_flash_params_table; + for (; params->name != NULL; params++) { + if ((params->jedec >> 16) == idcode[0]) { + if ((params->jedec & 0xFFFF) == jedec) { + if (params->ext_jedec == 0) + break; + else if (params->ext_jedec == ext_jedec) + break; + } + } + } + + if (!params->name) { + printf("SF: Unsupported flash IDs: "); + printf("manuf %02x, jedec %04x, ext_jedec %04x\n", + idcode[0], jedec, ext_jedec); + return -EPROTONOSUPPORT; + } + + /* Flash powers up read-only, so clear BP# bits */ +#if defined(CONFIG_SPI_FLASH_ATMEL) || \ + defined(CONFIG_SPI_FLASH_MACRONIX) || \ + defined(CONFIG_SPI_FLASH_SST) + spi_flash_cmd_write_status(flash, 0); +#endif + + /* Assign spi data */ + flash->spi = spi; + flash->name = params->name; + flash->memory_map = spi->memory_map; + flash->dual_flash = flash->spi->option; + + /* Assign spi flash flags */ + if (params->flags & SST_WR) + flash->flags |= SNOR_F_SST_WR; + + /* Assign spi_flash ops */ +#ifndef CONFIG_DM_SPI_FLASH + flash->write = spi_flash_cmd_write_ops; +#if defined(CONFIG_SPI_FLASH_SST) + if (flash->flags & SNOR_F_SST_WR) { + if (flash->spi->op_mode_tx & SPI_OPM_TX_BP) + flash->write = sst_write_bp; + else + flash->write = sst_write_wp; + } +#endif + flash->erase = spi_flash_cmd_erase_ops; + flash->read = spi_flash_cmd_read_ops; +#endif + + /* lock hooks are flash specific - assign them based on idcode0 */ + switch (idcode[0]) { +#if defined(CONFIG_SPI_FLASH_STMICRO) || defined(CONFIG_SPI_FLASH_SST) + case SPI_FLASH_CFI_MFR_STMICRO: + case SPI_FLASH_CFI_MFR_SST: + flash->flash_lock = stm_lock; + flash->flash_unlock = stm_unlock; + flash->flash_is_locked = stm_is_locked; +#endif + break; + default: + debug("SF: Lock ops not supported for %02x flash\n", idcode[0]); + } + + /* Compute the flash size */ + flash->shift = (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) ? 1 : 0; + /* + * The Spansion S25FL032P and S25FL064P have 256b pages, yet use the + * 0x4d00 Extended JEDEC code. The rest of the Spansion flashes with + * the 0x4d00 Extended JEDEC code have 512b pages. All of the others + * have 256b pages. + */ + if (ext_jedec == 0x4d00) { + if ((jedec == 0x0215) || (jedec == 0x216)) + flash->page_size = 256; + else + flash->page_size = 512; + } else { + flash->page_size = 256; + } + flash->page_size <<= flash->shift; + flash->sector_size = params->sector_size << flash->shift; + flash->size = flash->sector_size * params->nr_sectors << flash->shift; +#ifdef CONFIG_SF_DUAL_FLASH + if (flash->dual_flash & SF_DUAL_STACKED_FLASH) + flash->size <<= 1; +#endif + + /* Compute erase sector and command */ + if (params->flags & SECT_4K) { + flash->erase_cmd = CMD_ERASE_4K; + flash->erase_size = 4096 << flash->shift; + } else if (params->flags & SECT_32K) { + flash->erase_cmd = CMD_ERASE_32K; + flash->erase_size = 32768 << flash->shift; + } else { + flash->erase_cmd = CMD_ERASE_64K; + flash->erase_size = flash->sector_size; + } + + /* Now erase size becomes valid sector size */ + flash->sector_size = flash->erase_size; + + /* Look for the fastest read cmd */ + cmd = fls(params->e_rd_cmd & flash->spi->op_mode_rx); + if (cmd) { + cmd = spi_read_cmds_array[cmd - 1]; + flash->read_cmd = cmd; + } else { + /* Go for default supported read cmd */ + flash->read_cmd = CMD_READ_ARRAY_FAST; + } + + /* Not require to look for fastest only two write cmds yet */ + if (params->flags & WR_QPP && flash->spi->op_mode_tx & SPI_OPM_TX_QPP) + flash->write_cmd = CMD_QUAD_PAGE_PROGRAM; + else + /* Go for default supported write cmd */ + flash->write_cmd = CMD_PAGE_PROGRAM; + + /* Set the quad enable bit - only for quad commands */ + if ((flash->read_cmd == CMD_READ_QUAD_OUTPUT_FAST) || + (flash->read_cmd == CMD_READ_QUAD_IO_FAST) || + (flash->write_cmd == CMD_QUAD_PAGE_PROGRAM)) { + ret = spi_flash_set_qeb(flash, idcode[0]); + if (ret) { + debug("SF: Fail to set QEB for %02x\n", idcode[0]); + return -EINVAL; + } + } + + /* Read dummy_byte: dummy byte is determined based on the + * dummy cycles of a particular command. + * Fast commands - dummy_byte = dummy_cycles/8 + * I/O commands- dummy_byte = (dummy_cycles * no.of lines)/8 + * For I/O commands except cmd[0] everything goes on no.of lines + * based on particular command but incase of fast commands except + * data all go on single line irrespective of command. + */ + switch (flash->read_cmd) { + case CMD_READ_QUAD_IO_FAST: + flash->dummy_byte = 2; + break; + case CMD_READ_ARRAY_SLOW: + flash->dummy_byte = 0; + break; + default: + flash->dummy_byte = 1; + } + +#ifdef CONFIG_SPI_FLASH_STMICRO + if (params->flags & E_FSR) + flash->flags |= SNOR_F_USE_FSR; +#endif + + /* Configure the BAR - discover bank cmds and read current bank */ +#ifdef CONFIG_SPI_FLASH_BAR + ret = spi_flash_read_bank(flash, idcode[0]); + if (ret < 0) + return ret; +#endif + +#if CONFIG_IS_ENABLED(OF_CONTROL) + ret = spi_flash_decode_fdt(gd->fdt_blob, flash); + if (ret) { + debug("SF: FDT decode error\n"); + return -EINVAL; + } +#endif + +#ifndef CONFIG_SPL_BUILD + printf("SF: Detected %s with page size ", flash->name); + print_size(flash->page_size, ", erase size "); + print_size(flash->erase_size, ", total "); + print_size(flash->size, ""); + if (flash->memory_map) + printf(", mapped at %p", flash->memory_map); + puts("\n"); +#endif + +#ifndef CONFIG_SPI_FLASH_BAR + if (((flash->dual_flash == SF_SINGLE_FLASH) && + (flash->size > SPI_FLASH_16MB_BOUN)) || + ((flash->dual_flash > SF_SINGLE_FLASH) && + (flash->size > SPI_FLASH_16MB_BOUN << 1))) { + puts("SF: Warning - Only lower 16MiB accessible,"); + puts(" Full access #define CONFIG_SPI_FLASH_BAR\n"); + } +#endif + + return ret; +} diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 3da72df165..994559d548 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -20,348 +20,6 @@ #include "sf_internal.h" -DECLARE_GLOBAL_DATA_PTR; - -/* Read commands array */ -static u8 spi_read_cmds_array[] = { - CMD_READ_ARRAY_SLOW, - CMD_READ_ARRAY_FAST, - CMD_READ_DUAL_OUTPUT_FAST, - CMD_READ_DUAL_IO_FAST, - CMD_READ_QUAD_OUTPUT_FAST, - CMD_READ_QUAD_IO_FAST, -}; - -#ifdef CONFIG_SPI_FLASH_MACRONIX -static int spi_flash_set_qeb_mxic(struct spi_flash *flash) -{ - u8 qeb_status; - int ret; - - ret = spi_flash_cmd_read_status(flash, &qeb_status); - if (ret < 0) - return ret; - - if (qeb_status & STATUS_QEB_MXIC) { - debug("SF: mxic: QEB is already set\n"); - } else { - ret = spi_flash_cmd_write_status(flash, STATUS_QEB_MXIC); - if (ret < 0) - return ret; - } - - return ret; -} -#endif - -#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) -static int spi_flash_set_qeb_winspan(struct spi_flash *flash) -{ - u8 qeb_status; - int ret; - - ret = spi_flash_cmd_read_config(flash, &qeb_status); - if (ret < 0) - return ret; - - if (qeb_status & STATUS_QEB_WINSPAN) { - debug("SF: winspan: QEB is already set\n"); - } else { - ret = spi_flash_cmd_write_config(flash, STATUS_QEB_WINSPAN); - if (ret < 0) - return ret; - } - - return ret; -} -#endif - -static int spi_flash_set_qeb(struct spi_flash *flash, u8 idcode0) -{ - switch (idcode0) { -#ifdef CONFIG_SPI_FLASH_MACRONIX - case SPI_FLASH_CFI_MFR_MACRONIX: - return spi_flash_set_qeb_mxic(flash); -#endif -#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) - case SPI_FLASH_CFI_MFR_SPANSION: - case SPI_FLASH_CFI_MFR_WINBOND: - return spi_flash_set_qeb_winspan(flash); -#endif -#ifdef CONFIG_SPI_FLASH_STMICRO - case SPI_FLASH_CFI_MFR_STMICRO: - debug("SF: QEB is volatile for %02x flash\n", idcode0); - return 0; -#endif - default: - printf("SF: Need set QEB func for %02x flash\n", idcode0); - return -1; - } -} - -#ifdef CONFIG_SPI_FLASH_BAR -static int spi_flash_read_bank(struct spi_flash *flash, u8 idcode0) -{ - u8 curr_bank = 0; - int ret; - - if (flash->size <= SPI_FLASH_16MB_BOUN) - goto bank_end; - - switch (idcode0) { - case SPI_FLASH_CFI_MFR_SPANSION: - flash->bank_read_cmd = CMD_BANKADDR_BRRD; - flash->bank_write_cmd = CMD_BANKADDR_BRWR; - default: - flash->bank_read_cmd = CMD_EXTNADDR_RDEAR; - flash->bank_write_cmd = CMD_EXTNADDR_WREAR; - } - - ret = spi_flash_read_common(flash, &flash->bank_read_cmd, 1, - &curr_bank, 1); - if (ret) { - debug("SF: fail to read bank addr register\n"); - return ret; - } - -bank_end: - flash->bank_curr = curr_bank; - return 0; -} -#endif - -#if CONFIG_IS_ENABLED(OF_CONTROL) -int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) -{ - fdt_addr_t addr; - fdt_size_t size; - int node; - - /* If there is no node, do nothing */ - node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH); - if (node < 0) - return 0; - - addr = fdtdec_get_addr_size(blob, node, "memory-map", &size); - if (addr == FDT_ADDR_T_NONE) { - debug("%s: Cannot decode address\n", __func__); - return 0; - } - - if (flash->size != size) { - debug("%s: Memory map must cover entire device\n", __func__); - return -1; - } - flash->memory_map = map_sysmem(addr, size); - - return 0; -} -#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ - -static int spi_flash_scan(struct spi_slave *spi, u8 *idcode, - struct spi_flash *flash) -{ - const struct spi_flash_params *params; - u8 cmd; - u16 jedec = idcode[1] << 8 | idcode[2]; - u16 ext_jedec = idcode[3] << 8 | idcode[4]; - int ret; - - /* Validate params from spi_flash_params table */ - params = spi_flash_params_table; - for (; params->name != NULL; params++) { - if ((params->jedec >> 16) == idcode[0]) { - if ((params->jedec & 0xFFFF) == jedec) { - if (params->ext_jedec == 0) - break; - else if (params->ext_jedec == ext_jedec) - break; - } - } - } - - if (!params->name) { - printf("SF: Unsupported flash IDs: "); - printf("manuf %02x, jedec %04x, ext_jedec %04x\n", - idcode[0], jedec, ext_jedec); - return -EPROTONOSUPPORT; - } - - /* Flash powers up read-only, so clear BP# bits */ -#if defined(CONFIG_SPI_FLASH_ATMEL) || \ - defined(CONFIG_SPI_FLASH_MACRONIX) || \ - defined(CONFIG_SPI_FLASH_SST) - spi_flash_cmd_write_status(flash, 0); -#endif - - /* Assign spi data */ - flash->spi = spi; - flash->name = params->name; - flash->memory_map = spi->memory_map; - flash->dual_flash = flash->spi->option; - - /* Assign spi flash flags */ - if (params->flags & SST_WR) - flash->flags |= SNOR_F_SST_WR; - - /* Assign spi_flash ops */ -#ifndef CONFIG_DM_SPI_FLASH - flash->write = spi_flash_cmd_write_ops; -#if defined(CONFIG_SPI_FLASH_SST) - if (flash->flags & SNOR_F_SST_WR) { - if (flash->spi->op_mode_tx & SPI_OPM_TX_BP) - flash->write = sst_write_bp; - else - flash->write = sst_write_wp; - } -#endif - flash->erase = spi_flash_cmd_erase_ops; - flash->read = spi_flash_cmd_read_ops; -#endif - - /* lock hooks are flash specific - assign them based on idcode0 */ - switch (idcode[0]) { -#if defined(CONFIG_SPI_FLASH_STMICRO) || defined(CONFIG_SPI_FLASH_SST) - case SPI_FLASH_CFI_MFR_STMICRO: - case SPI_FLASH_CFI_MFR_SST: - flash->flash_lock = stm_lock; - flash->flash_unlock = stm_unlock; - flash->flash_is_locked = stm_is_locked; -#endif - break; - default: - debug("SF: Lock ops not supported for %02x flash\n", idcode[0]); - } - - /* Compute the flash size */ - flash->shift = (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) ? 1 : 0; - /* - * The Spansion S25FL032P and S25FL064P have 256b pages, yet use the - * 0x4d00 Extended JEDEC code. The rest of the Spansion flashes with - * the 0x4d00 Extended JEDEC code have 512b pages. All of the others - * have 256b pages. - */ - if (ext_jedec == 0x4d00) { - if ((jedec == 0x0215) || (jedec == 0x216)) - flash->page_size = 256; - else - flash->page_size = 512; - } else { - flash->page_size = 256; - } - flash->page_size <<= flash->shift; - flash->sector_size = params->sector_size << flash->shift; - flash->size = flash->sector_size * params->nr_sectors << flash->shift; -#ifdef CONFIG_SF_DUAL_FLASH - if (flash->dual_flash & SF_DUAL_STACKED_FLASH) - flash->size <<= 1; -#endif - - /* Compute erase sector and command */ - if (params->flags & SECT_4K) { - flash->erase_cmd = CMD_ERASE_4K; - flash->erase_size = 4096 << flash->shift; - } else if (params->flags & SECT_32K) { - flash->erase_cmd = CMD_ERASE_32K; - flash->erase_size = 32768 << flash->shift; - } else { - flash->erase_cmd = CMD_ERASE_64K; - flash->erase_size = flash->sector_size; - } - - /* Now erase size becomes valid sector size */ - flash->sector_size = flash->erase_size; - - /* Look for the fastest read cmd */ - cmd = fls(params->e_rd_cmd & flash->spi->op_mode_rx); - if (cmd) { - cmd = spi_read_cmds_array[cmd - 1]; - flash->read_cmd = cmd; - } else { - /* Go for default supported read cmd */ - flash->read_cmd = CMD_READ_ARRAY_FAST; - } - - /* Not require to look for fastest only two write cmds yet */ - if (params->flags & WR_QPP && flash->spi->op_mode_tx & SPI_OPM_TX_QPP) - flash->write_cmd = CMD_QUAD_PAGE_PROGRAM; - else - /* Go for default supported write cmd */ - flash->write_cmd = CMD_PAGE_PROGRAM; - - /* Set the quad enable bit - only for quad commands */ - if ((flash->read_cmd == CMD_READ_QUAD_OUTPUT_FAST) || - (flash->read_cmd == CMD_READ_QUAD_IO_FAST) || - (flash->write_cmd == CMD_QUAD_PAGE_PROGRAM)) { - ret = spi_flash_set_qeb(flash, idcode[0]); - if (ret) { - debug("SF: Fail to set QEB for %02x\n", idcode[0]); - return -EINVAL; - } - } - - /* Read dummy_byte: dummy byte is determined based on the - * dummy cycles of a particular command. - * Fast commands - dummy_byte = dummy_cycles/8 - * I/O commands- dummy_byte = (dummy_cycles * no.of lines)/8 - * For I/O commands except cmd[0] everything goes on no.of lines - * based on particular command but incase of fast commands except - * data all go on single line irrespective of command. - */ - switch (flash->read_cmd) { - case CMD_READ_QUAD_IO_FAST: - flash->dummy_byte = 2; - break; - case CMD_READ_ARRAY_SLOW: - flash->dummy_byte = 0; - break; - default: - flash->dummy_byte = 1; - } - -#ifdef CONFIG_SPI_FLASH_STMICRO - if (params->flags & E_FSR) - flash->flags |= SNOR_F_USE_FSR; -#endif - - /* Configure the BAR - discover bank cmds and read current bank */ -#ifdef CONFIG_SPI_FLASH_BAR - ret = spi_flash_read_bank(flash, idcode[0]); - if (ret < 0) - return ret; -#endif - -#if CONFIG_IS_ENABLED(OF_CONTROL) - ret = spi_flash_decode_fdt(gd->fdt_blob, flash); - if (ret) { - debug("SF: FDT decode error\n"); - return -EINVAL; - } -#endif - -#ifndef CONFIG_SPL_BUILD - printf("SF: Detected %s with page size ", flash->name); - print_size(flash->page_size, ", erase size "); - print_size(flash->erase_size, ", total "); - print_size(flash->size, ""); - if (flash->memory_map) - printf(", mapped at %p", flash->memory_map); - puts("\n"); -#endif - -#ifndef CONFIG_SPI_FLASH_BAR - if (((flash->dual_flash == SF_SINGLE_FLASH) && - (flash->size > SPI_FLASH_16MB_BOUN)) || - ((flash->dual_flash > SF_SINGLE_FLASH) && - (flash->size > SPI_FLASH_16MB_BOUN << 1))) { - puts("SF: Warning - Only lower 16MiB accessible,"); - puts(" Full access #define CONFIG_SPI_FLASH_BAR\n"); - } -#endif - - return ret; -} - /** * spi_flash_probe_slave() - Probe for a SPI flash device on a bus * From 1e90d9fd3148cebcd6f87cbbaed564b878e2b24a Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Tue, 29 Sep 2015 18:06:04 +0530 Subject: [PATCH 08/21] sf: Move read_id code to sf_ops read_id code is related to spi_flash stuff hence moved to sf_ops. Tested-by: Jagan Teki Tested-by: Bin Meng Reviewed-by: Bin Meng Reviewed-by: Simon Glass Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_internal.h | 3 +-- drivers/mtd/spi/sf_ops.c | 21 ++++++++++++++++++--- drivers/mtd/spi/sf_probe.c | 15 +-------------- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index f3eb6f3c46..670429f79a 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -248,7 +248,6 @@ void spi_flash_mtd_unregister(void); /** * spi_flash_scan - scan the SPI FLASH * @spi: the spi slave structure - * @idcode: idcode of spi flash * @flash: the spi flash structure * * The drivers can use this fuction to scan the SPI FLASH. @@ -257,6 +256,6 @@ void spi_flash_mtd_unregister(void); * * Return: 0 for success, others for failure. */ -int spi_flash_scan(struct spi_slave *spi, u8 *idcode, struct spi_flash *flash); +int spi_flash_scan(struct spi_slave *spi, struct spi_flash *flash); #endif /* _SF_INTERNAL_H_ */ diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index 306db8f56e..54c6468e42 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -898,14 +898,29 @@ int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) } #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ -int spi_flash_scan(struct spi_slave *spi, u8 *idcode, struct spi_flash *flash) +int spi_flash_scan(struct spi_slave *spi, struct spi_flash *flash) { const struct spi_flash_params *params; + u16 jedec, ext_jedec; + u8 idcode[5]; u8 cmd; - u16 jedec = idcode[1] << 8 | idcode[2]; - u16 ext_jedec = idcode[3] << 8 | idcode[4]; int ret; + /* Read the ID codes */ + ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode)); + if (ret) { + printf("SF: Failed to get idcodes\n"); + return -EINVAL; + } + +#ifdef DEBUG + printf("SF: Got idcodes\n"); + print_buffer(0, idcode, 1, sizeof(idcode), 0); +#endif + + jedec = idcode[1] << 8 | idcode[2]; + ext_jedec = idcode[3] << 8 | idcode[4]; + /* Validate params from spi_flash_params table */ params = spi_flash_params_table; for (; params->name != NULL; params++) { diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 994559d548..e35b91760f 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -29,7 +29,6 @@ */ int spi_flash_probe_slave(struct spi_slave *spi, struct spi_flash *flash) { - u8 idcode[5]; int ret; /* Setup spi_slave */ @@ -45,19 +44,7 @@ int spi_flash_probe_slave(struct spi_slave *spi, struct spi_flash *flash) return ret; } - /* Read the ID codes */ - ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode)); - if (ret) { - printf("SF: Failed to get idcodes\n"); - goto err_read_id; - } - -#ifdef DEBUG - printf("SF: Got idcodes\n"); - print_buffer(0, idcode, 1, sizeof(idcode), 0); -#endif - - ret = spi_flash_scan(spi, idcode, flash); + ret = spi_flash_scan(spi, flash); if (ret) { ret = -EINVAL; goto err_read_id; From 0edae52f08fe602ebe9ba1d132f91552cac86472 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Wed, 4 Nov 2015 00:27:35 +0530 Subject: [PATCH 09/21] sf: probe: Code cleanup - Move bar read code below the bar write hance both at once place, hence it easy for #ifdef macro only once and readable. - Move read_cmd_array at top Tested-by: Jagan Teki Reviewed-by: Bin Meng Reviewed-by: Simon Glass Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_ops.c | 80 ++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index 54c6468e42..8d6040e71c 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -30,6 +30,16 @@ static void spi_flash_addr(u32 addr, u8 *cmd) cmd[3] = addr >> 0; } +/* Read commands array */ +static u8 spi_read_cmds_array[] = { + CMD_READ_ARRAY_SLOW, + CMD_READ_ARRAY_FAST, + CMD_READ_DUAL_OUTPUT_FAST, + CMD_READ_DUAL_IO_FAST, + CMD_READ_QUAD_OUTPUT_FAST, + CMD_READ_QUAD_IO_FAST, +}; + int spi_flash_cmd_read_status(struct spi_flash *flash, u8 *rs) { int ret; @@ -133,6 +143,35 @@ bar_end: flash->bank_curr = bank_sel; return flash->bank_curr; } + +static int spi_flash_read_bank(struct spi_flash *flash, u8 idcode0) +{ + u8 curr_bank = 0; + int ret; + + if (flash->size <= SPI_FLASH_16MB_BOUN) + goto bank_end; + + switch (idcode0) { + case SPI_FLASH_CFI_MFR_SPANSION: + flash->bank_read_cmd = CMD_BANKADDR_BRRD; + flash->bank_write_cmd = CMD_BANKADDR_BRWR; + default: + flash->bank_read_cmd = CMD_EXTNADDR_RDEAR; + flash->bank_write_cmd = CMD_EXTNADDR_WREAR; + } + + ret = spi_flash_read_common(flash, &flash->bank_read_cmd, 1, + &curr_bank, 1); + if (ret) { + debug("SF: fail to read bank addr register\n"); + return ret; + } + +bank_end: + flash->bank_curr = curr_bank; + return 0; +} #endif #ifdef CONFIG_SF_DUAL_FLASH @@ -762,16 +801,6 @@ int stm_unlock(struct spi_flash *flash, u32 ofs, size_t len) #endif -/* Read commands array */ -static u8 spi_read_cmds_array[] = { - CMD_READ_ARRAY_SLOW, - CMD_READ_ARRAY_FAST, - CMD_READ_DUAL_OUTPUT_FAST, - CMD_READ_DUAL_IO_FAST, - CMD_READ_QUAD_OUTPUT_FAST, - CMD_READ_QUAD_IO_FAST, -}; - #ifdef CONFIG_SPI_FLASH_MACRONIX static int spi_flash_set_qeb_mxic(struct spi_flash *flash) { @@ -839,37 +868,6 @@ static int spi_flash_set_qeb(struct spi_flash *flash, u8 idcode0) } } -#ifdef CONFIG_SPI_FLASH_BAR -static int spi_flash_read_bank(struct spi_flash *flash, u8 idcode0) -{ - u8 curr_bank = 0; - int ret; - - if (flash->size <= SPI_FLASH_16MB_BOUN) - goto bank_end; - - switch (idcode0) { - case SPI_FLASH_CFI_MFR_SPANSION: - flash->bank_read_cmd = CMD_BANKADDR_BRRD; - flash->bank_write_cmd = CMD_BANKADDR_BRWR; - default: - flash->bank_read_cmd = CMD_EXTNADDR_RDEAR; - flash->bank_write_cmd = CMD_EXTNADDR_WREAR; - } - - ret = spi_flash_read_common(flash, &flash->bank_read_cmd, 1, - &curr_bank, 1); - if (ret) { - debug("SF: fail to read bank addr register\n"); - return ret; - } - -bank_end: - flash->bank_curr = curr_bank; - return 0; -} -#endif - #if CONFIG_IS_ENABLED(OF_CONTROL) int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) { From 6fa40e796c212998cd9e3d4a8d192392d0623826 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Tue, 29 Sep 2015 18:26:08 +0530 Subject: [PATCH 10/21] sf: Use static for file-scope functions Use static for file-scope functions and removed them from header files. Tested-by: Jagan Teki Reviewed-by: Bin Meng Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_internal.h | 18 ------------------ drivers/mtd/spi/sf_ops.c | 11 ++++++----- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 670429f79a..8f586eed0d 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -171,12 +171,6 @@ int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len, /* Flash erase(sectors) operation, support all possible erase commands */ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len); -/* Read the status register */ -int spi_flash_cmd_read_status(struct spi_flash *flash, u8 *rs); - -/* Program the status register */ -int spi_flash_cmd_write_status(struct spi_flash *flash, u8 ws); - /* Lock stmicro spi flash region */ int stm_lock(struct spi_flash *flash, u32 ofs, size_t len); @@ -186,12 +180,6 @@ int stm_unlock(struct spi_flash *flash, u32 ofs, size_t len); /* Check if a stmicro spi flash region is completely locked */ int stm_is_locked(struct spi_flash *flash, u32 ofs, size_t len); -/* Read the config register */ -int spi_flash_cmd_read_config(struct spi_flash *flash, u8 *rc); - -/* Program the config register */ -int spi_flash_cmd_write_config(struct spi_flash *flash, u8 wc); - /* Enable writing on the SPI flash */ static inline int spi_flash_cmd_write_enable(struct spi_flash *flash) { @@ -204,12 +192,6 @@ static inline int spi_flash_cmd_write_disable(struct spi_flash *flash) return spi_flash_cmd(flash->spi, CMD_WRITE_DISABLE, NULL, 0); } -/* - * Send the read status command to the device and wait for the wip - * (write-in-progress) bit to clear itself. - */ -int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout); - /* * Used for spi_flash write operation * - SPI claim diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index 8d6040e71c..23a6adb89f 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -40,7 +40,7 @@ static u8 spi_read_cmds_array[] = { CMD_READ_QUAD_IO_FAST, }; -int spi_flash_cmd_read_status(struct spi_flash *flash, u8 *rs) +static int spi_flash_cmd_read_status(struct spi_flash *flash, u8 *rs) { int ret; u8 cmd; @@ -69,7 +69,7 @@ static int read_fsr(struct spi_flash *flash, u8 *fsr) return 0; } -int spi_flash_cmd_write_status(struct spi_flash *flash, u8 ws) +static int spi_flash_cmd_write_status(struct spi_flash *flash, u8 ws) { u8 cmd; int ret; @@ -85,7 +85,7 @@ int spi_flash_cmd_write_status(struct spi_flash *flash, u8 ws) } #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) -int spi_flash_cmd_read_config(struct spi_flash *flash, u8 *rc) +static int spi_flash_cmd_read_config(struct spi_flash *flash, u8 *rc) { int ret; u8 cmd; @@ -100,7 +100,7 @@ int spi_flash_cmd_read_config(struct spi_flash *flash, u8 *rc) return 0; } -int spi_flash_cmd_write_config(struct spi_flash *flash, u8 wc) +static int spi_flash_cmd_write_config(struct spi_flash *flash, u8 wc) { u8 data[2]; u8 cmd; @@ -238,7 +238,8 @@ static int spi_flash_ready(struct spi_flash *flash) return sr && fsr; } -int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout) +static int spi_flash_cmd_wait_ready(struct spi_flash *flash, + unsigned long timeout) { int timebase, ret; From fc335d63b06dc81db45acc77358bdedeeca737c8 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Tue, 29 Sep 2015 19:16:29 +0530 Subject: [PATCH 11/21] sf: Fix Makefile This patch removes unneeded ifdef and fixed accordingly. Reviewed-by: Bin Meng Reviewed-by: Simon Glass Signed-off-by: Jagan Teki --- drivers/mtd/spi/Makefile | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile index cf4e7e1f42..a24f7612ac 100644 --- a/drivers/mtd/spi/Makefile +++ b/drivers/mtd/spi/Makefile @@ -12,11 +12,7 @@ obj-$(CONFIG_SPL_SPI_LOAD) += spi_spl_load.o obj-$(CONFIG_SPL_SPI_BOOT) += fsl_espi_spl.o endif -#ifndef CONFIG_DM_SPI -obj-$(CONFIG_SPI_FLASH) += sf_probe.o -#endif -obj-$(CONFIG_CMD_SF) += sf.o -obj-$(CONFIG_SPI_FLASH) += sf_ops.o sf_params.o +obj-$(CONFIG_SPI_FLASH) += sf_probe.o sf_ops.o sf_params.o sf.o obj-$(CONFIG_SPI_FLASH_DATAFLASH) += sf_dataflash.o obj-$(CONFIG_SPI_FLASH_MTD) += sf_mtd.o obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o From cb37518516420c581877a209a7841f2a5fe6382d Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Tue, 29 Sep 2015 22:29:33 +0530 Subject: [PATCH 12/21] sf: Use simple name for register access functions Most of the register access function are static, so used simple name to represent each. Tested-by: Jagan Teki Reviewed-by: Bin Meng Reviewed-by: Simon Glass Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_ops.c | 52 ++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index 23a6adb89f..853759eeb5 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -40,7 +40,7 @@ static u8 spi_read_cmds_array[] = { CMD_READ_QUAD_IO_FAST, }; -static int spi_flash_cmd_read_status(struct spi_flash *flash, u8 *rs) +static int read_sr(struct spi_flash *flash, u8 *rs) { int ret; u8 cmd; @@ -69,7 +69,7 @@ static int read_fsr(struct spi_flash *flash, u8 *fsr) return 0; } -static int spi_flash_cmd_write_status(struct spi_flash *flash, u8 ws) +static int write_sr(struct spi_flash *flash, u8 ws) { u8 cmd; int ret; @@ -85,7 +85,7 @@ static int spi_flash_cmd_write_status(struct spi_flash *flash, u8 ws) } #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) -static int spi_flash_cmd_read_config(struct spi_flash *flash, u8 *rc) +static int read_cr(struct spi_flash *flash, u8 *rc) { int ret; u8 cmd; @@ -100,13 +100,13 @@ static int spi_flash_cmd_read_config(struct spi_flash *flash, u8 *rc) return 0; } -static int spi_flash_cmd_write_config(struct spi_flash *flash, u8 wc) +static int write_cr(struct spi_flash *flash, u8 wc) { u8 data[2]; u8 cmd; int ret; - ret = spi_flash_cmd_read_status(flash, &data[0]); + ret = read_sr(flash, &data[0]); if (ret < 0) return ret; @@ -123,7 +123,7 @@ static int spi_flash_cmd_write_config(struct spi_flash *flash, u8 wc) #endif #ifdef CONFIG_SPI_FLASH_BAR -static int spi_flash_write_bank(struct spi_flash *flash, u32 offset) +static int spi_flash_write_bar(struct spi_flash *flash, u32 offset) { u8 cmd, bank_sel; int ret; @@ -144,7 +144,7 @@ bar_end: return flash->bank_curr; } -static int spi_flash_read_bank(struct spi_flash *flash, u8 idcode0) +static int spi_flash_read_bar(struct spi_flash *flash, u8 idcode0) { u8 curr_bank = 0; int ret; @@ -175,7 +175,7 @@ bank_end: #endif #ifdef CONFIG_SF_DUAL_FLASH -static void spi_flash_dual_flash(struct spi_flash *flash, u32 *addr) +static void spi_flash_dual(struct spi_flash *flash, u32 *addr) { switch (flash->dual_flash) { case SF_DUAL_STACKED_FLASH: @@ -201,7 +201,7 @@ static int spi_flash_sr_ready(struct spi_flash *flash) u8 sr; int ret; - ret = spi_flash_cmd_read_status(flash, &sr); + ret = read_sr(flash, &sr); if (ret < 0) return ret; @@ -325,10 +325,10 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len) #ifdef CONFIG_SF_DUAL_FLASH if (flash->dual_flash > SF_SINGLE_FLASH) - spi_flash_dual_flash(flash, &erase_addr); + spi_flash_dual(flash, &erase_addr); #endif #ifdef CONFIG_SPI_FLASH_BAR - ret = spi_flash_write_bank(flash, erase_addr); + ret = spi_flash_write_bar(flash, erase_addr); if (ret < 0) return ret; #endif @@ -375,10 +375,10 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset, #ifdef CONFIG_SF_DUAL_FLASH if (flash->dual_flash > SF_SINGLE_FLASH) - spi_flash_dual_flash(flash, &write_addr); + spi_flash_dual(flash, &write_addr); #endif #ifdef CONFIG_SPI_FLASH_BAR - ret = spi_flash_write_bank(flash, write_addr); + ret = spi_flash_write_bar(flash, write_addr); if (ret < 0) return ret; #endif @@ -470,10 +470,10 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, #ifdef CONFIG_SF_DUAL_FLASH if (flash->dual_flash > SF_SINGLE_FLASH) - spi_flash_dual_flash(flash, &read_addr); + spi_flash_dual(flash, &read_addr); #endif #ifdef CONFIG_SPI_FLASH_BAR - ret = spi_flash_write_bank(flash, read_addr); + ret = spi_flash_write_bar(flash, read_addr); if (ret < 0) return ret; bank_sel = flash->bank_curr; @@ -671,7 +671,7 @@ int stm_is_locked(struct spi_flash *flash, u32 ofs, size_t len) int status; u8 sr; - status = spi_flash_cmd_read_status(flash, &sr); + status = read_sr(flash, &sr); if (status < 0) return status; @@ -708,7 +708,7 @@ int stm_lock(struct spi_flash *flash, u32 ofs, size_t len) u8 shift = ffs(mask) - 1, pow, val; int ret; - ret = spi_flash_cmd_read_status(flash, &status_old); + ret = read_sr(flash, &status_old); if (ret < 0) return ret; @@ -745,7 +745,7 @@ int stm_lock(struct spi_flash *flash, u32 ofs, size_t len) if ((status_new & mask) <= (status_old & mask)) return -EINVAL; - spi_flash_cmd_write_status(flash, status_new); + write_sr(flash, status_new); return 0; } @@ -762,7 +762,7 @@ int stm_unlock(struct spi_flash *flash, u32 ofs, size_t len) u8 shift = ffs(mask) - 1, pow, val; int ret; - ret = spi_flash_cmd_read_status(flash, &status_old); + ret = read_sr(flash, &status_old); if (ret < 0) return ret; @@ -795,7 +795,7 @@ int stm_unlock(struct spi_flash *flash, u32 ofs, size_t len) if ((status_new & mask) >= (status_old & mask)) return -EINVAL; - spi_flash_cmd_write_status(flash, status_new); + write_sr(flash, status_new); return 0; } @@ -808,14 +808,14 @@ static int spi_flash_set_qeb_mxic(struct spi_flash *flash) u8 qeb_status; int ret; - ret = spi_flash_cmd_read_status(flash, &qeb_status); + ret = read_sr(flash, &qeb_status); if (ret < 0) return ret; if (qeb_status & STATUS_QEB_MXIC) { debug("SF: mxic: QEB is already set\n"); } else { - ret = spi_flash_cmd_write_status(flash, STATUS_QEB_MXIC); + ret = write_sr(flash, STATUS_QEB_MXIC); if (ret < 0) return ret; } @@ -830,14 +830,14 @@ static int spi_flash_set_qeb_winspan(struct spi_flash *flash) u8 qeb_status; int ret; - ret = spi_flash_cmd_read_config(flash, &qeb_status); + ret = read_cr(flash, &qeb_status); if (ret < 0) return ret; if (qeb_status & STATUS_QEB_WINSPAN) { debug("SF: winspan: QEB is already set\n"); } else { - ret = spi_flash_cmd_write_config(flash, STATUS_QEB_WINSPAN); + ret = write_cr(flash, STATUS_QEB_WINSPAN); if (ret < 0) return ret; } @@ -944,7 +944,7 @@ int spi_flash_scan(struct spi_slave *spi, struct spi_flash *flash) #if defined(CONFIG_SPI_FLASH_ATMEL) || \ defined(CONFIG_SPI_FLASH_MACRONIX) || \ defined(CONFIG_SPI_FLASH_SST) - spi_flash_cmd_write_status(flash, 0); + write_sr(flash, 0); #endif /* Assign spi data */ @@ -1079,7 +1079,7 @@ int spi_flash_scan(struct spi_slave *spi, struct spi_flash *flash) /* Configure the BAR - discover bank cmds and read current bank */ #ifdef CONFIG_SPI_FLASH_BAR - ret = spi_flash_read_bank(flash, idcode[0]); + ret = spi_flash_read_bar(flash, idcode[0]); if (ret < 0) return ret; #endif From 6f9d670d8e9a77553b00c293fd1a8f913a9d7be3 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Wed, 30 Sep 2015 02:01:23 +0530 Subject: [PATCH 13/21] sf: Flash power up read-only based on idcode0 Using macro's for flash power up read-only access code leads wrong behaviour hence use idcode0 for runtime detection, hence the flash which require this functionality gets detected at runtime. Tested-by: Jagan Teki Reviewed-by: Bin Meng Reviewed-by: Simon Glass Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_internal.h | 1 + drivers/mtd/spi/sf_ops.c | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 8f586eed0d..b8692c6147 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -66,6 +66,7 @@ enum spi_nor_option_flags { #define SPI_FLASH_CFI_MFR_MACRONIX 0xc2 #define SPI_FLASH_CFI_MFR_SST 0xbf #define SPI_FLASH_CFI_MFR_WINBOND 0xef +#define SPI_FLASH_CFI_MFR_ATMEL 0x1f /* Erase commands */ #define CMD_ERASE_4K 0x20 diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index 853759eeb5..e5514ab00f 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -941,11 +941,10 @@ int spi_flash_scan(struct spi_slave *spi, struct spi_flash *flash) } /* Flash powers up read-only, so clear BP# bits */ -#if defined(CONFIG_SPI_FLASH_ATMEL) || \ - defined(CONFIG_SPI_FLASH_MACRONIX) || \ - defined(CONFIG_SPI_FLASH_SST) + if (idcode[0] == SPI_FLASH_CFI_MFR_ATMEL || + idcode[0] == SPI_FLASH_CFI_MFR_MACRONIX || + idcode[0] == SPI_FLASH_CFI_MFR_SST) write_sr(flash, 0); -#endif /* Assign spi data */ flash->spi = spi; From 615879ac1a8fa761f931c3353a9a4b933177b5f0 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Wed, 4 Nov 2015 00:40:32 +0530 Subject: [PATCH 14/21] sf: Remove unneeded header includes Removed unneeded header includes in sf_ops and sf_probe Reviewed-by: Bin Meng Reviewed-by: Simon Glass Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_ops.c | 2 -- drivers/mtd/spi/sf_probe.c | 3 --- 2 files changed, 5 deletions(-) diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index e5514ab00f..ef45fc1a7b 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include "sf_internal.h" diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index e35b91760f..f8aad569a9 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -11,12 +11,9 @@ #include #include #include -#include #include -#include #include #include -#include #include "sf_internal.h" From aae00f8bab3af6d353c254d420c069018fd4ffa6 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Thu, 26 Nov 2015 01:03:33 +0530 Subject: [PATCH 15/21] sf: Remove unneeded SST_BP and SST_WP SST parts added on sf_params.c supports both SST_WR which consits of both BP and WP and there is a spi controller ich which supports only BP so the relevent _write hook set based on "slave->op_mode_tx" hence there is no respective change required from flash side hance removed these. Tested-by: Bin Meng Reviewed-by: Bin Meng Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_internal.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index b8692c6147..16dd45bfc6 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -44,13 +44,10 @@ enum { #endif SECT_32K = 1 << 1, E_FSR = 1 << 2, - SST_BP = 1 << 3, - SST_WP = 1 << 4, - WR_QPP = 1 << 5, + SST_WR = 1 << 3, + WR_QPP = 1 << 4, }; -#define SST_WR (SST_BP | SST_WP) - enum spi_nor_option_flags { SNOR_F_SST_WR = (1 << 0), SNOR_F_USE_FSR = (1 << 1), From b6a2c436e0010f80693f1c22d429c969b67792fd Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Fri, 20 Nov 2015 13:00:15 +0530 Subject: [PATCH 16/21] sf: ops: Fix missing break on spansion read_bar For assigning read_bar commands in spansion case, break is missing this patch add that break. Reviewed-by: Simon Glass Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_ops.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index ef45fc1a7b..68f191b55e 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -154,6 +154,7 @@ static int spi_flash_read_bar(struct spi_flash *flash, u8 idcode0) case SPI_FLASH_CFI_MFR_SPANSION: flash->bank_read_cmd = CMD_BANKADDR_BRRD; flash->bank_write_cmd = CMD_BANKADDR_BRWR; + break; default: flash->bank_read_cmd = CMD_EXTNADDR_RDEAR; flash->bank_write_cmd = CMD_EXTNADDR_WREAR; From bfdb07eb4b7547ba63bc71c48be8459538f2d781 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Sun, 6 Dec 2015 21:33:32 +0530 Subject: [PATCH 17/21] sf: sf_probe: Remove spi_slave pointer argument Since spi_slave is a spi pointer in spi_flash{} then assign spi_slave{} pointer to flash->spi and remove spi_slave pointer argument to - spi_flash_probe_slave - spi_flash_scan Tested-by: Jagan Teki Tested-by: Bin Meng Reviewed-by: Bin Meng Reviewed-by: Simon Glass Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_internal.h | 3 +-- drivers/mtd/spi/sf_ops.c | 4 ++-- drivers/mtd/spi/sf_probe.c | 12 +++++++----- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 16dd45bfc6..ed5c391dc2 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -227,7 +227,6 @@ void spi_flash_mtd_unregister(void); /** * spi_flash_scan - scan the SPI FLASH - * @spi: the spi slave structure * @flash: the spi flash structure * * The drivers can use this fuction to scan the SPI FLASH. @@ -236,6 +235,6 @@ void spi_flash_mtd_unregister(void); * * Return: 0 for success, others for failure. */ -int spi_flash_scan(struct spi_slave *spi, struct spi_flash *flash); +int spi_flash_scan(struct spi_flash *flash); #endif /* _SF_INTERNAL_H_ */ diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index 68f191b55e..c065858be0 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -896,8 +896,9 @@ int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) } #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ -int spi_flash_scan(struct spi_slave *spi, struct spi_flash *flash) +int spi_flash_scan(struct spi_flash *flash) { + struct spi_slave *spi = flash->spi; const struct spi_flash_params *params; u16 jedec, ext_jedec; u8 idcode[5]; @@ -946,7 +947,6 @@ int spi_flash_scan(struct spi_slave *spi, struct spi_flash *flash) write_sr(flash, 0); /* Assign spi data */ - flash->spi = spi; flash->name = params->name; flash->memory_map = spi->memory_map; flash->dual_flash = flash->spi->option; diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index f8aad569a9..bf53eef5c2 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -20,12 +20,12 @@ /** * spi_flash_probe_slave() - Probe for a SPI flash device on a bus * - * @spi: Bus to probe * @flashp: Pointer to place to put flash info, which may be NULL if the * space should be allocated */ -int spi_flash_probe_slave(struct spi_slave *spi, struct spi_flash *flash) +int spi_flash_probe_slave(struct spi_flash *flash) { + struct spi_slave *spi = flash->spi; int ret; /* Setup spi_slave */ @@ -41,7 +41,7 @@ int spi_flash_probe_slave(struct spi_slave *spi, struct spi_flash *flash) return ret; } - ret = spi_flash_scan(spi, flash); + ret = spi_flash_scan(flash); if (ret) { ret = -EINVAL; goto err_read_id; @@ -68,7 +68,8 @@ struct spi_flash *spi_flash_probe_tail(struct spi_slave *bus) return NULL; } - if (spi_flash_probe_slave(bus, flash)) { + flash->spi = bus; + if (spi_flash_probe_slave(flash)) { spi_free_slave(bus); free(flash); return NULL; @@ -152,8 +153,9 @@ int spi_flash_std_probe(struct udevice *dev) flash = dev_get_uclass_priv(dev); flash->dev = dev; + flash->spi = slave; debug("%s: slave=%p, cs=%d\n", __func__, slave, plat->cs); - return spi_flash_probe_slave(slave, flash); + return spi_flash_probe_slave(flash); } static const struct dm_spi_flash_ops spi_flash_std_ops = { From 339fd6dca58fcd6175abd1e1c584ee7f3e68d9f6 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Sun, 6 Dec 2015 21:44:12 +0530 Subject: [PATCH 18/21] sf: Use static for file-scope functions Used static for file-scope functions in sf_probe.c Reviewed-by: Bin Meng Reviewed-by: Simon Glass Signed-off-by: Jagan Teki --- drivers/mtd/spi/sf_probe.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index bf53eef5c2..0cafc29123 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -23,7 +23,7 @@ * @flashp: Pointer to place to put flash info, which may be NULL if the * space should be allocated */ -int spi_flash_probe_slave(struct spi_flash *flash) +static int spi_flash_probe_slave(struct spi_flash *flash) { struct spi_slave *spi = flash->spi; int ret; @@ -57,7 +57,7 @@ err_read_id: } #ifndef CONFIG_DM_SPI_FLASH -struct spi_flash *spi_flash_probe_tail(struct spi_slave *bus) +static struct spi_flash *spi_flash_probe_tail(struct spi_slave *bus) { struct spi_flash *flash; @@ -121,7 +121,7 @@ static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len, return spi_flash_cmd_read_ops(flash, offset, len, buf); } -int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len, +static int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len, const void *buf) { struct spi_flash *flash = dev_get_uclass_priv(dev); @@ -138,14 +138,14 @@ int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len, return spi_flash_cmd_write_ops(flash, offset, len, buf); } -int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len) +static int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len) { struct spi_flash *flash = dev_get_uclass_priv(dev); return spi_flash_cmd_erase_ops(flash, offset, len); } -int spi_flash_std_probe(struct udevice *dev) +static int spi_flash_std_probe(struct udevice *dev) { struct spi_slave *slave = dev_get_parent_priv(dev); struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev); From cba65a77c4e75d6e1e3dcaa65b7d509f1a2bb95e Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Sun, 6 Dec 2015 23:29:02 +0530 Subject: [PATCH 19/21] sf: Rename sf_ops.c to spi-flash.c Since all spi-flash core operations are moved into sf_ops.c then it's better to renamed as spi-flash.c Reviewed-by: Bin Meng Reviewed-by: Simon Glass Signed-off-by: Jagan Teki --- drivers/mtd/spi/Makefile | 2 +- drivers/mtd/spi/{sf_ops.c => spi_flash.c} | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) rename drivers/mtd/spi/{sf_ops.c => spi_flash.c} (99%) diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile index a24f7612ac..c665836f95 100644 --- a/drivers/mtd/spi/Makefile +++ b/drivers/mtd/spi/Makefile @@ -12,7 +12,7 @@ obj-$(CONFIG_SPL_SPI_LOAD) += spi_spl_load.o obj-$(CONFIG_SPL_SPI_BOOT) += fsl_espi_spl.o endif -obj-$(CONFIG_SPI_FLASH) += sf_probe.o sf_ops.o sf_params.o sf.o +obj-$(CONFIG_SPI_FLASH) += sf_probe.o spi_flash.o sf_params.o sf.o obj-$(CONFIG_SPI_FLASH_DATAFLASH) += sf_dataflash.o obj-$(CONFIG_SPI_FLASH_MTD) += sf_mtd.o obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/spi_flash.c similarity index 99% rename from drivers/mtd/spi/sf_ops.c rename to drivers/mtd/spi/spi_flash.c index c065858be0..7ffa136f5a 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/spi_flash.c @@ -1,9 +1,10 @@ /* - * SPI flash operations + * SPI Flash Core * - * Copyright (C) 2008 Atmel Corporation - * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik + * Copyright (C) 2015 Jagan Teki * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc. + * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik + * Copyright (C) 2008 Atmel Corporation * * SPDX-License-Identifier: GPL-2.0+ */ From fe94b48de2d1e755f53ade852a5f49917505745e Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Mon, 7 Dec 2015 01:26:13 +0530 Subject: [PATCH 20/21] mailmap: Update Jagan Teki's name and email address Used quite different name's and e-mail address, all of them mapped to standard name and e-mail address. Cc: Tom Rini Reviewed-by: Masahiro Yamada Signed-off-by: Jagan Teki --- .mailmap | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index e1c666334a..2f32fe8ba5 100644 --- a/.mailmap +++ b/.mailmap @@ -13,7 +13,11 @@ Andreas Bießmann Aneesh V Dirk Behme Fabio Estevam -Jagannadha Sutradharudu Teki <402jagan@gmail.com> +Jagan Teki <402jagan@gmail.com> +Jagan Teki +Jagan Teki +Jagan Teki +Jagan Teki Markus Klotzbuecher Prabhakar Kushwaha Rajeshwari Shinde From 76de51a6da0411e1f3e80e1c9a2ef5bfa8e35571 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 11 Dec 2015 12:41:14 +0100 Subject: [PATCH 21/21] spi: xilinx: Add new compatible strings Add xlnx,xps-spi-2.00.a/b which is compatible string listed in the Linux kernel. Remove origin one which has no real background. Signed-off-by: Michal Simek Reviewed-by: Jagan Teki --- drivers/spi/xilinx_spi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index 0713714e52..a951a7753d 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -287,7 +287,8 @@ static const struct dm_spi_ops xilinx_spi_ops = { }; static const struct udevice_id xilinx_spi_ids[] = { - { .compatible = "xlnx,xilinx-spi" }, + { .compatible = "xlnx,xps-spi-2.00.a" }, + { .compatible = "xlnx,xps-spi-2.00.b" }, { } };