mtd: Add SPI-NOR core support
Subsystems (6)
v5 cover mtd: Add SPI-NOR core support
Compared to previous patch series this series adds spi-nor core with spi-nor controller drivers are of "mtd uclass"
Why this framework:
Some of the SPI device drivers at drivers/spi not a real spi controllers, Unlike normal/generic SPI controllers they operates only with SPI-NOR flash devices. these were technically termed as SPI-NOR controllers, Ex: drivers/spi/fsl_qspi.c
The problem with these were resides at drivers/spi is entire SPI layer becomes SPI-NOR flash oriented which is absolutely a wrong indication where SPI layer getting effected more with flash operations - So this SPI-NOR core will resolve this issue by separating all SPI-NOR flash operations from spi layer and creats a generic layer called SPI-NOR core which can be used to interact SPI-NOR to SPI driver interface layer and the SPI-NOR controller driver. The idea is taken from Linux spi-nor framework.
Before SPI-NOR:
-----------------------
cmd/sf.c
-----------------------
spi_flash.c
-----------------------
sf_probe.c
-----------------------
spi-uclass
-----------------------
spi drivers
-----------------------
SPI NOR chip
-----------------------
After SPI-NOR:
------------------------------
cmd/sf.c
------------------------------
spi-nor.c
-------------------------------m25p80.c spi nor drivers
-------------------------------
spi-uclass SPI NOR chip
-------------------------------
spi drivers
-------------------------------
SPI NOR chip
-------------------------------
SPI-NOR with MTD:
------------------------------
cmd/sf.c
------------------------------
MTD core
------------------------------
spi-nor.c
-------------------------------m25p80.c spi nor drivers
-------------------------------
spi-uclass SPI NOR chip
-------------------------------
spi drivers
-------------------------------
SPI NOR chip
-------------------------------
drivers/mtd/spi-nor/spi-nor.c: spi-nor core drivers/mtd/spi-nor/m25p80.c: mtd uclass driver
which is an interface layer b/w spi-nor core drivers/spi drivers/mtd/spi-nor/fsl_qspi.c: spi-nor controller driver(mtd uclass)
Changes for v5:
- newly designed changes
Testing:
$ git clone git://git.denx.de/u-boot-spi.git $ cd u-boot-spi $ git checkout -b spi-nor origin/spi-nor
Jagan Teki (32):
mtd: Add m25p80 driver
mtd: Add Kconfig entry for MTD_M25P80
mtd: Add SPI-NOR core support
doc: device-tree-bindings: jedec,spi-nor
mtd: spi-nor: Add Kconfig entry for MTD_SPI_NOR
mtd: spi-nor: Add kconfig for MTD_SPI_NOR_USE_4K_SECTORS
mtd: spi-nor: Add MTD support
mtd: spi-nor: Add spi_nor support in m25p80
mtd: spi-nor: Add dm spi-nor probing
mtd: spi-nor: Add spi_flash_probe for mtd-dm-spi-nor
cmd: sf: Add mtd_info for mtd-dm-spi-nor code
mtd: spi-nor: m25p80: Add spi_nor support for non-dm
spi_flash: Use mtd_info operation for non-dm
mtd: spi-nor: Move spi_read_then_write to spi layer
spi: Rename spi_read_then_write to spi_write_then_read
spi: Drop mode_rx
spi: Drop SPI_RX_FAST
mtd: spi-nor: Rename SPI_FLASH_BAR to SPI_NOR_BAR
mtd: spi-nor: Add Kconfig entry for SPI_NOR_BAR
mtd: spi-nor: Copy spl files from drivers/mtd/spi
mtd: spi-nor: spl: Follow ascending order of include headers
mtd: spi-nor: fsl_espi_spl: Use mtd_info
mtd: spi-nor: spi_spl_load: Use mtd_info
mtd: spi-nor: Add flash vendor Kconfig entries
arm: zynq: Kconfig: Select MTD uclass
arm: zynq: Kconfig: Drop DM_SPI_FLASH
defconfigs: zynq_microzed: Drop CONFIG_SPI_FLASH
defconfig: zynq_microzed: Enable CONFIG_MTD_M25P80
defconfig: zynq_microzed: Enable CONFIG_MTD_SPI_NOR
spl: Add CONFIG_SPL_SPI_NOR_SUPPORT
configs: zynq: Use CONFIG_SPL_SPI_NOR_SUPPORT
configs: zynq: Use CONFIG_SPL_MTD_SUPPORT
Makefile | 1 + arch/arm/Kconfig | 2 +- cmd/sf.c | 38 +- configs/zynq_microzed_defconfig | 3 +- doc/device-tree-bindings/mtd/jedec,spi-nor.txt | 78 ++ drivers/Makefile | 1 + drivers/mtd/Kconfig | 2 + drivers/mtd/spi-nor/Kconfig | 99 ++ drivers/mtd/spi-nor/Makefile | 18 + drivers/mtd/spi-nor/fsl_espi_spl.c | 90 ++ drivers/mtd/spi-nor/m25p80.c | 332 +++++++ drivers/mtd/spi-nor/spi-nor-ids.c | 276 ++++++ drivers/mtd/spi-nor/spi-nor-probe.c | 45 + drivers/mtd/spi-nor/spi-nor.c | 1141 ++++++++++++++++++++++++ drivers/mtd/spi-nor/spi_spl_load.c | 89 ++ drivers/spi/ich.c | 6 +- drivers/spi/spi-uclass.c | 35 +- drivers/spi/spi.c | 24 + drivers/spi/ti_qspi.c | 6 +- include/configs/zynq-common.h | 3 +- include/linux/err.h | 5 + include/linux/mtd/spi-nor.h | 251 ++++++ include/spi.h | 33 +- include/spi_flash.h | 79 +- 24 files changed, 2581 insertions(+), 76 deletions(-) create mode 100644 doc/device-tree-bindings/mtd/jedec,spi-nor.txt create mode 100644 drivers/mtd/spi-nor/Kconfig create mode 100644 drivers/mtd/spi-nor/Makefile create mode 100644 drivers/mtd/spi-nor/fsl_espi_spl.c create mode 100644 drivers/mtd/spi-nor/m25p80.c create mode 100644 drivers/mtd/spi-nor/spi-nor-ids.c create mode 100644 drivers/mtd/spi-nor/spi-nor-probe.c create mode 100644 drivers/mtd/spi-nor/spi-nor.c create mode 100644 drivers/mtd/spi-nor/spi_spl_load.c create mode 100644 include/linux/mtd/spi-nor.h
Signature · 1 line
1.9.1
PATCH v5 1/32 mtd: Add m25p80 driver
This is MTD SPI-NOR driver for ST M25Pxx (and similar) serial flash chips which is written as MTD_UCLASS.
More features will be adding on further patches.
--- Makefile | 1 + drivers/mtd/spi-nor/Makefile | 6 ++++++ drivers/mtd/spi-nor/m25p80.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 drivers/mtd/spi-nor/Makefile create mode 100644 drivers/mtd/spi-nor/m25p80.c
Makefile +1 -0
@@ -637,6 +637,7 @@ libs-$(CONFIG_CMD_NAND) += drivers/mtd/nand/ libs-y += drivers/mtd/onenand/ libs-$(CONFIG_CMD_UBI) += drivers/mtd/ubi/ libs-y += drivers/mtd/spi/ +libs-y += drivers/mtd/spi-nor/ libs-y += drivers/net/ libs-y += drivers/net/phy/ libs-y += drivers/pci/
drivers/mtd/spi-nor/Makefile new file +6 -0
@@ -0,0 +1,6 @@ +# +# Copyright (C) 2016 Jagan Teki <[email protected]> +# +# SPDX-License-Identifier: GPL-2.0+ + +obj-$(CONFIG_MTD_M25P80) += m25p80.o
drivers/mtd/spi-nor/m25p80.c new file +37 -0
@@ -0,0 +1,37 @@ +/* +* MTD SPI-NOR driver for ST M25Pxx (and similar) serial flash chips +* +* Copyright (C) 2016 Jagan Teki <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <spi.h> +#include <linux/mtd/mtd.h> + +static int m25p_probe (struct udevice *dev) +{ +struct spi_slave *spi =dev_get_parent_priv (dev); +struct mtd_info *mtd =dev_get_uclass_priv (dev); + +return 0 ; +} + +static const struct udevice_id m25p_ids[] = { +/* +* Generic compatibility for SPI NOR that can be identified by the +* JEDEC READ ID opcode (0x9F). Use this, if possible. +*/ + { .compatible ="jedec,spi-nor" }, + { } +}; + +U_BOOT_DRIVER (m25p80) = { + .name ="m25p80" , + .id =UCLASS_MTD , + .of_match = m25p_ids, + .probe = m25p_probe, +};
Signature · 1 line
1.9.1
PATCH v5 2/32 mtd: Add Kconfig entry for MTD_M25P80
In reply to Jagan TekiAdded Kconfig entry for MTD_M25P80
--- drivers/mtd/spi-nor/Kconfig | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 drivers/mtd/spi-nor/Kconfig
drivers/mtd/spi-nor/Kconfig new file +15 -0
@@ -0,0 +1,15 @@ +config MTD_M25P80 + tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)" + help + This enables access to most modern SPI flash chips, used for + program and data storage. Series supported include Atmel AT26DF, + Spansion S25SL, SST 25VF, ST M25P, and Winbond W25X. Other chips + are supported as well. See the driver source for the current list, + or to add other chips. + + Note that the original DataFlash chips (AT45 series, not AT26DF), + need an entirely different driver. + + Set up your spi devices with the right board-specific platform data, + if you want to specify device partitioning or to use a device which + doesn't support the JEDEC ID instruction.
Signature · 1 line
1.9.1
PATCH v5 3/32 mtd: Add SPI-NOR core support
In reply to Jagan TekiSome of the SPI device drivers at drivers/spi not a real spi controllers, Unlike normal/generic SPI controllers they operates only with SPI-NOR flash devices. these were technically termed as SPI-NOR controllers, Ex: drivers/spi/fsl_qspi.c
The problem with these were resides at drivers/spi is entire SPI layer becomes SPI-NOR flash oriented which is absolutely a wrong indication where SPI layer getting effected more with flash operations - So this SPI-NOR core will resolve this issue by separating all SPI-NOR flash operations from spi layer and creats a generic layer called SPI-NOR core which can be used to interact SPI-NOR to SPI driver interface layer and the SPI-NOR controller driver. The idea is taken from Linux spi-nor framework.
Before SPI-NOR:
----------------------- cmd_sf.c ----------------------- spi_flash.c ----------------------- sf_probe.c ----------------------- spi-uclass ----------------------- spi drivers ----------------------- SPI NOR chip -----------------------
After SPI-NOR:
------------------------------ cmd_sf.c ------------------------------ spi-nor.c ------------------------------- m25p80.c spi nor drivers ------------------------------- spi-uclass SPI NOR chip ------------------------------- spi drivers ------------------------------- SPI NOR chip -------------------------------
--- drivers/mtd/Kconfig | 2 + drivers/mtd/spi-nor/Makefile | 5 + drivers/mtd/spi-nor/spi-nor-ids.c | 276 ++++++++++ drivers/mtd/spi-nor/spi-nor.c | 1084 +++++++++++++++++++++++++++++++++++++ include/linux/err.h | 5 + include/linux/mtd/spi-nor.h | 251 +++++++++ 6 files changed, 1623 insertions(+) create mode 100644 drivers/mtd/spi-nor/spi-nor-ids.c create mode 100644 drivers/mtd/spi-nor/spi-nor.c create mode 100644 include/linux/mtd/spi-nor.h
drivers/mtd/Kconfig +2 -0
@@ -33,3 +33,5 @@ endmenu source "drivers/mtd/nand/Kconfig" source "drivers/mtd/spi/Kconfig" + +source "drivers/mtd/spi-nor/Kconfig"
drivers/mtd/spi-nor/Makefile +5 -0
@@ -3,4 +3,9 @@ # # SPDX-License-Identifier: GPL-2.0+ +ifdef CONFIG_MTD_SPI_NOR +obj-y += spi-nor.o +obj-y += spi-nor-ids.o +endif + obj-$(CONFIG_MTD_M25P80) += m25p80.o
drivers/mtd/spi-nor/spi-nor-ids.c new file +276 -0
276 lines not on this page · raw message
drivers/mtd/spi-nor/spi-nor.c new file +1084 -0
1,084 lines not on this page · raw message
include/linux/err.h +5 -0
@@ -36,6 +36,11 @@ static inline long IS_ERR(const void *ptr)return IS_ERR_VALUE ((unsigned long )ptr); } +static inline bool IS_ERR_OR_NULL (const void *ptr) +{ +return !ptr ||IS_ERR_VALUE ((unsigned long )ptr); +} +/** * ERR_CAST - Explicitly cast an error-valued pointer to another pointer type * @ptr: The pointer to cast.
include/linux/mtd/spi-nor.h new file +251 -0
251 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v5 4/32 doc: device-tree-bindings: jedec, spi-nor
In reply to Jagan TekiSince m25p80 follows similar naming convention as Linux, hence added jedec, spi-nor device tree bindings from Linux.
--- doc/device-tree-bindings/mtd/jedec,spi-nor.txt | 78 ++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 doc/device-tree-bindings/mtd/jedec,spi-nor.txt
doc/device-tree-bindings/mtd/jedec,spi-nor.txt new file +78 -0
@@ -0,0 +1,78 @@ +* SPI NOR flash: ST M25Pxx (and similar) serial flash chips + +Required properties: +- #address-cells, #size-cells : Must be present if the device has sub-nodes + representing partitions. +- compatible : May include a device-specific string consisting of the + manufacturer and name of the chip. A list of supported chip + names follows. + Must also include "jedec,spi-nor" for any SPI NOR flash that can + be identified by the JEDEC READ ID opcode (0x9F). + + Supported chip names: + at25df321a + at25df641 + at26df081a + mr25h256 + mx25l4005a + mx25l1606e + mx25l6405d + mx25l12805d + mx25l25635e + n25q064 + n25q128a11 + n25q128a13 + n25q512a + s25fl256s1 + s25fl512s + s25sl12801 + s25fl008k + s25fl064k + sst25vf040b + m25p40 + m25p80 + m25p16 + m25p32 + m25p64 + m25p128 + w25x80 + w25x32 + w25q32 + w25q32dw + w25q80bl + w25q128 + w25q256 + + The following chip names have been used historically to + designate quirky versions of flash chips that do not support the + JEDEC READ ID opcode (0x9F): + m25p05-nonjedec + m25p10-nonjedec + m25p20-nonjedec + m25p40-nonjedec + m25p80-nonjedec + m25p16-nonjedec + m25p32-nonjedec + m25p64-nonjedec + m25p128-nonjedec + +- reg : Chip-Select number +- spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at + +Optional properties: +- m25p,fast-read : Use the "fast read" opcode to read data from the chip instead + of the usual "read" opcode. This opcode is not supported by + all chips and support for it can not be detected at runtime. + Refer to your chips' datasheet to check if this is supported + by your chip. + +Example: + + flash: m25p80 at 0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spansion,m25p80", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; + m25p,fast-read; + };
Signature · 1 line
1.9.1
PATCH v5 5/32 mtd: spi-nor: Add Kconfig entry for MTD_SPI_NOR
In reply to Jagan TekiAdded kconfig entry for MTD_SPI_NOR
--- drivers/mtd/spi-nor/Kconfig | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
drivers/mtd/spi-nor/Kconfig +18 -0
@@ -1,3 +1,19 @@ +menuconfig MTD_SPI_NOR + tristate "SPI-NOR device support" + help + This is the core SPI NOR framework which can be used to interact SPI-NOR + to SPI driver interface layer and the SPI-NOR controller driver. + + Unlike normal/generic spi controllers, they are few controllers which are + exclusively used to connect SPI-NOR devices, called SPI-NOR controllers. + So technically these controllers shouldn't reside at drivers/spi as these + may effect the generic SPI bus functionalities, so this SPI-NOR core acts + as a common core framework between the generic SPI controller drivers vs + SPI-NOR controller drivers for SPI-NOR device access. Note that from SPI-NOR + core to SPI drivers there should be an interface layer. + +if MTD_SPI_NOR + config MTD_M25P80 tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)" help
@@ -13,3 +29,5 @@ config MTD_M25P80 Set up your spi devices with the right board-specific platform data, if you want to specify device partitioning or to use a device which doesn't support the JEDEC ID instruction. + +endif # MTD_SPI_NOR
Signature · 1 line
1.9.1
PATCH v5 6/32 mtd: spi-nor: Add kconfig for MTD_SPI_NOR_USE_4K_SECTORS
In reply to Jagan TekiAdded kconfig entry for MTD_SPI_NOR_USE_4K_SECTORS.
--- drivers/mtd/spi-nor/Kconfig | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/mtd/spi-nor/Kconfig +14 -0
@@ -30,4 +30,18 @@ config MTD_M25P80 if you want to specify device partitioning or to use a device which doesn't support the JEDEC ID instruction. +config MTD_SPI_NOR_USE_4K_SECTORS + bool "Use small 4096 B erase sectors" + default y + help + Many flash memories support erasing small (4096 B) sectors. Depending + on the usage this feature may provide performance gain in comparison + to erasing whole blocks (32/64 KiB). + Changing a small part of the flash's contents is usually faster with + small sectors. On the other hand erasing should be faster when using + 64 KiB block instead of 16 ? 4 KiB sectors. + + Please note that some tools/drivers/filesystems may not work with + 4096 B erase size (e.g. UBIFS requires 15 KiB as a minimum). + endif # MTD_SPI_NOR
Signature · 1 line
1.9.1
PATCH v5 7/32 mtd: spi-nor: Add MTD support
In reply to Jagan TekiThis patch adds mtd_info support to spi-nor core instead of using legacy spi_flash{}.
SPI-NOR with MTD:
------------------------------ cmd_sf.c ------------------------------ MTD core ------------------------------ spi-nor.c ------------------------------- m25p80.c spi nor drivers ------------------------------- spi-uclass SPI NOR chip ------------------------------- spi drivers ------------------------------- SPI NOR chip -------------------------------
--- drivers/mtd/spi-nor/spi-nor.c | 273 +++++++++++++++++++++++++----------------- 1 file changed, 165 insertions(+), 108 deletions(-)
drivers/mtd/spi-nor/spi-nor.c +165 -108
@@ -7,6 +7,7 @@*/ #include <common.h> +#include <div64.h> #include <dm.h> #include <errno.h> #include <malloc.h>
@@ -14,6 +15,7 @@#include <linux/math64.h> #include <linux/log2.h> +#include <linux/mtd/mtd.h> #include <linux/mtd/spi-nor.h> DECLARE_GLOBAL_DATA_PTR ;
@@ -209,10 +211,11 @@ bar_end:static int spi_nor_read_bar (struct spi_nor *nor,const struct spi_nor_info *info) { +struct mtd_info *mtd = nor->mtd;u8 curr_bank =0 ;int ret; -if (flash->size <=SNOR_16MB_BOUN ) +if (mtd->size <=SNOR_16MB_BOUN ) goto bar_end;switch (JEDEC_MFR (info)) {
@@ -240,12 +243,12 @@ bar_end:#ifdef CONFIG_SF_DUAL_FLASH static void spi_nor_dual (struct spi_nor *nor,u32 *addr) { -struct spi_flash *flash = nor->flash; +struct mtd_info *mtd = nor->mtd;switch (nor->dual) {case SNOR_DUAL_STACKED : -if (*addr >= (flash->size >>1 )) { - *addr -= flash->size >>1 ; +if (*addr >= (mtd->size >>1 )) { + *addr -= mtd->size >>1 ; nor->flags |=SNOR_F_U_PAGE ; }else { nor->flags &= ~SNOR_F_U_PAGE ;
@@ -263,8 +266,9 @@ static void spi_nor_dual(struct spi_nor *nor, u32 *addr)#if defined(CONFIG_SPI_FLASH_STMICRO ) || defined(CONFIG_SPI_FLASH_SST )static void stm_get_locked_range (struct spi_nor *nor,u8 sr,loff_t *ofs, -u32 *len) +uint64_t *len) { +struct mtd_info *mtd = nor->mtd;u8 mask =SR_BP2 |SR_BP1 |SR_BP0 ;int shift =ffs (mask) -1 ;int pow;
@@ -275,18 +279,19 @@ static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs, *len =0 ; }else { pow = ((sr & mask) ^ mask) >> shift; - *len = flash->size >> pow; - *ofs = flash->size - *len; + *len = mtd->size >> pow; + *ofs = mtd->size - *len; } }/* * Return 1 if the entire region is locked, 0 otherwise */ -static int stm_is_locked_sr (struct spi_nor *nor,u32 ofs,u32 len,u8 sr) +static int stm_is_locked_sr (struct spi_nor *nor,loff_t ofs,uint64_t len, +u8 sr) {loff_t lock_offs; -u32 lock_len; +uint64_t lock_len;stm_get_locked_range (nor, sr, &lock_offs, &lock_len);
@@ -294,24 +299,6 @@ static int stm_is_locked_sr(struct spi_nor *nor, u32 ofs, u32 len, u8 sr) }/* -* Check if a region of the flash is (completely) locked. See stm_lock() for -* more info. -* -* Returns 1 if entire region is locked, 0 if any portion is unlocked, and -* negative on errors. -*/ -static int stm_is_locked (struct spi_nor *nor,u32 ofs,size_t len) -{ -int status; - - status =read_sr (nor); -if (status <0 ) -return status; - -return stm_is_locked_sr (nor, ofs, len, status); -} - -/* * Lock a region of the flash. Compatible with ST Micro and similar flash. * Supports only the block protection bits BP{0,1,2} in the status register * (SR). Does not support these features found in newer SR bitfields:
@@ -334,9 +321,10 @@ static int stm_is_locked(struct spi_nor *nor, u32 ofs, size_t len)* * Returns negative on errors, 0 on success. */ -static int stm_lock (struct spi_nor *nor,u32 ofs,size_t len) +static int stm_lock (struct spi_nor *nor,loff_t ofs,uint64_t len) { -u8 status_old, status_new; +struct mtd_info *mtd = nor->mtd; +int status_old, status_new;u8 mask =SR_BP2 |SR_BP1 |SR_BP0 ;u8 shift =ffs (mask) -1 , pow, val;
@@ -345,12 +333,12 @@ static int stm_lock(struct spi_nor *nor, u32 ofs, size_t len)return status_old;/* SPI NOR always locks to the end */ -if (ofs + len != flash->size) { +if (ofs + len != mtd->size) {/* Does combined region extend to end? */ -if (!stm_is_locked_sr (nor, ofs + len, flash->size - ofs - len, +if (!stm_is_locked_sr (nor, ofs + len, mtd->size - ofs - len, status_old))return -EINVAL ; - len = flash->size - ofs; + len = mtd->size - ofs; }/*
@@ -362,11 +350,10 @@ static int stm_lock(struct spi_nor *nor, u32 ofs, size_t len)* * pow = ceil(log2(size / len)) = log2(size) - floor(log2(len)) */ - pow =ilog2 (flash->size) -ilog2 (len); + pow =ilog2 (mtd->size) -ilog2 (len); val = mask - (pow << shift);if (val & ~mask)return -EINVAL ; -/* Don't "lock" with no region! */ if (!(val & mask))return -EINVAL ;
@@ -386,20 +373,22 @@ static int stm_lock(struct spi_nor *nor, u32 ofs, size_t len)* * Returns negative on errors, 0 on success. */ -static int stm_unlock (struct spi_nor *nor,u32 ofs,size_t len) +static int stm_unlock (struct spi_nor *nor,loff_t ofs,uint64_t len) { -uint8_t status_old, status_new; +struct mtd_info *mtd = nor->mtd; +int status_old, status_new;u8 mask =SR_BP2 |SR_BP1 |SR_BP0 ;u8 shift =ffs (mask) -1 , pow, val; status_old =read_sr (nor); -if (status_old <0 ) +if (status_old <0 )return status_old;/* Cannot unlock; would unlock larger region than requested */ -if (stm_is_locked_sr (nor, status_old, ofs - flash->erase_size, - nor->erase_size)) +if (stm_is_locked_sr (nor, status_old, ofs - mtd->erasesize, + mtd->erasesize))return -EINVAL ; +/* * Need largest pow such that: *
@@ -409,8 +398,8 @@ static int stm_unlock(struct spi_nor *nor, u32 ofs, size_t len)* * pow = floor(log2(size / len)) = log2(size) - ceil(log2(len)) */ - pow =ilog2 (flash->size) -order_base_2 (flash->size - (ofs + len)); -if (ofs + len == flash->size) { + pow =ilog2 (mtd->size) -order_base_2 (mtd->size - (ofs + len)); +if (ofs + len == mtd->size) { val =0 ;/* fully unlocked */ }else { val = mask - (pow << shift);
@@ -428,8 +417,47 @@ static int stm_unlock(struct spi_nor *nor, u32 ofs, size_t len)write_enable (nor); return write_sr(nor, status_new); } + +/* +* Check if a region of the flash is (completely) locked. See stm_lock() for +* more info. +* +* Returns 1 if entire region is locked, 0 if any portion is unlocked, and +* negative on errors. +*/ +static int stm_is_locked (struct spi_nor *nor,loff_t ofs,uint64_t len) +{ +int status; + + status =read_sr (nor); +if (status <0 ) +return status; + +return stm_is_locked_sr (nor, ofs, len, status); +}#endif +static int spi_nor_lock (struct mtd_info *mtd,loff_t ofs,uint64_t len) +{ +struct spi_nor *nor = mtd->priv; + +return nor->flash_lock (nor, ofs, len); +} + +static int spi_nor_unlock (struct mtd_info *mtd,loff_t ofs,uint64_t len) +{ +struct spi_nor *nor = mtd->priv; + +return nor->flash_unlock (nor, ofs, len); +} + +static int spi_nor_is_locked (struct mtd_info *mtd,loff_t ofs,uint64_t len) +{ +struct spi_nor *nor = mtd->priv; + +return nor->flash_is_locked (nor, ofs, len); +} +static const struct spi_nor_info *spi_nor_id (struct spi_nor *nor) {int tmp;
@@ -455,30 +483,32 @@ static const struct spi_nor_info *spi_nor_id(struct spi_nor *nor)return ERR_PTR (-ENODEV ); } -static int spi_nor_erase (struct spi_flash *flash,u32 offset,size_t len) +static int spi_nor_erase (struct mtd_info *mtd,struct erase_info *instr) { -struct spi_nor *nor = flash->nor; -u32 erase_size, erase_addr; +struct spi_nor *nor = mtd->priv; +u32 addr, len, erase_addr;u8 cmd[SNOR_MAX_CMD_SIZE ]; +uint32_t rem;int ret =-1 ; - erase_size = nor->erase_size; -if (offset % erase_size || len % erase_size) { -debug ("spi-nor: Erase offset/length not multiple of erase size\n" ); -return -1 ; - } +div_u64_rem (instr->len, mtd->erasesize, &rem); +if (rem) +return -EINVAL ; + + addr = instr->addr; + len = instr->len; -if (flash->flash_is_locked) { -if (flash->flash_is_locked (flash, offset, len) >0 ) { +if (mtd->_is_locked) { +if (mtd->_is_locked (mtd, addr, len) >0 ) {printf ("offset 0x%x is protected and cannot be erased\n" , - offset); + addr);return -EINVAL ; } } - cmd[0 ] = flash->erase_opcode; + cmd[0 ] = nor->erase_opcode;while (len) { - erase_addr = offset; + erase_addr = addr;#ifdef CONFIG_SF_DUAL_FLASH if (nor->dual >SNOR_DUAL_SINGLE )
@@ -498,39 +528,47 @@ static int spi_nor_erase(struct spi_flash *flash, u32 offset, size_t len) ret = nor->write (nor, cmd,sizeof (cmd),NULL ,0 );if (ret <0 ) -break ; + goto erase_err; ret =spi_nor_wait_till_ready (nor,SNOR_READY_WAIT_ERASE );if (ret <0 ) -return ret; + goto erase_err; - offset += erase_size; - len -= erase_size; + addr += mtd->erasesize; + len -= mtd->erasesize; } +write_disable (nor); + + instr->state =MTD_ERASE_DONE ; +mtd_erase_callback (instr); + +return ret; + +erase_err: + instr->state =MTD_ERASE_FAILED ;return ret; } -int spi_nor_write (struct spi_flash *flash,u32 offset, -size_t len,const void *buf) +static int spi_nor_write (struct mtd_info *mtd,loff_t offset,size_t len, +size_t *retlen,const u_char *buf) { -struct spi_nor *nor = flash->nor; -unsigned long byte_addr, page_size; -u32 write_addr; +struct spi_nor *nor = mtd->priv; +u32 byte_addr, page_size, write_addr;size_t chunk_len, actual;u8 cmd[SNOR_MAX_CMD_SIZE ];int ret =-1 ; - page_size = nor->page_size; - -if (flash->flash_is_locked) { -if (flash->flash_is_locked (flash, offset, len) >0 ) { -printf ("offset 0x%x is protected and cannot be written\n" , +if (mtd->_is_locked) { +if (mtd->_is_locked (mtd, offset, len) >0 ) { +printf ("offset 0x%llx is protected and cannot be written\n" , offset);return -EINVAL ; } } + page_size = nor->page_size; + cmd[0 ] = nor->program_opcode;for (actual =0 ; actual < len; actual += chunk_len) { write_addr = offset;
@@ -568,14 +606,16 @@ int spi_nor_write(struct spi_flash *flash, u32 offset,return ret; offset += chunk_len; + *retlen += chunk_len; }return ret; } -int spi_nor_read (struct spi_flash *flash,u32 offset,size_t len,void *data) +static int spi_nor_read (struct mtd_info *mtd,loff_t from,size_t len, +size_t *retlen,u_char *buf) { -struct spi_nor *nor = flash->nor; +struct spi_nor *nor = mtd->priv;u32 remain_len, read_len, read_addr;u8 *cmd, cmdsz;int bank_sel =0 ;
@@ -583,7 +623,7 @@ int spi_nor_read(struct spi_flash *flash, u32 offset, size_t len, void *data)/* Handle memory-mapped SPI */ if (nor->memory_map) { - ret = nor->read_mmap (nor, data, nor->memory_map + offset, len); + ret = nor->read_mmap (nor, buf, nor->memory_map + from, len);if (ret) {debug ("spi-nor: mmap read failed\n" );return ret;
@@ -601,7 +641,7 @@ int spi_nor_read(struct spi_flash *flash, u32 offset, size_t len, void *data) cmd[0 ] = nor->read_opcode;while (len) { - read_addr = offset; + read_addr = from;#ifdef CONFIG_SF_DUAL_FLASH if (nor->dual >SNOR_DUAL_SINGLE )
@@ -614,7 +654,7 @@ int spi_nor_read(struct spi_flash *flash, u32 offset, size_t len, void *data) bank_sel = nor->bank_curr;#endif remain_len = ((SNOR_16MB_BOUN << nor->shift) * - (bank_sel +1 )) - offset; + (bank_sel +1 )) - from;if (len < remain_len) read_len = len;else
@@ -622,13 +662,14 @@ int spi_nor_read(struct spi_flash *flash, u32 offset, size_t len, void *data)spi_nor_addr (read_addr, cmd); - ret = nor->read (nor, cmd, cmdsz, data, read_len); + ret = nor->read (nor, cmd, cmdsz, buf, read_len);if (ret <0 )break ; - offset += read_len; + from += read_len; len -= read_len; - data += read_len; + buf += read_len; + *retlen += read_len; }free (cmd);
@@ -636,7 +677,8 @@ int spi_nor_read(struct spi_flash *flash, u32 offset, size_t len, void *data) } #ifdef CONFIG_SPI_FLASH_SST -static int sst_byte_write(struct spi_nor *nor, u32 offset, const void *buf) +static int sst_byte_write(struct spi_nor *nor, u32 offset, + const void *buf, size_t *retlen) { int ret; u8 cmd[4] = {
@@ -657,12 +699,15 @@ static int sst_byte_write(struct spi_nor *nor, u32 offset, const void *buf)if (ret)return ret; + *retlen +=1 ; +return spi_nor_wait_till_ready (nor,SNOR_READY_WAIT_PROG ); } -int sst_write_wp (struct spi_nor *nor,u32 offset,size_t len,const void *buf) +static int sst_write_wp (struct mtd_info *mtd,loff_t offset,size_t len, +size_t *retlen,const u_char *buf) { -struct spi_nor *nor = flash->nor; +struct spi_nor *nor = mtd->priv;size_t actual, cmd_len;int ret;u8 cmd[4 ];
@@ -670,7 +715,7 @@ int sst_write_wp(struct spi_nor *nor, u32 offset, size_t len, const void *buf)/* If the data is not word aligned, write out leading single byte */ actual = offset %2 ;if (actual) { - ret =sst_byte_write (nor, offset, buf); + ret =sst_byte_write (nor, offset, buf, retlen);if (ret) goto done; }
@@ -687,7 +732,7 @@ int sst_write_wp(struct spi_nor *nor, u32 offset, size_t len, const void *buf) cmd[3 ] = offset;for (; actual < len -1 ; actual +=2 ) { -debug ("spi-nor: 0x%p => cmd = { 0x%02x 0x%06x }\n" , +debug ("spi-nor: 0x%p => cmd = { 0x%02x 0x%06llx }\n" , buf + actual, cmd[0 ], offset); ret = nor->write (nor, cmd, cmd_len, buf + actual,2 );
@@ -702,6 +747,7 @@ int sst_write_wp(struct spi_nor *nor, u32 offset, size_t len, const void *buf) cmd_len =1 ; offset +=2 ; + *retlen +=2 ; }if (!ret)
@@ -715,14 +761,15 @@ int sst_write_wp(struct spi_nor *nor, u32 offset, size_t len, const void *buf)return ret; } -int sst_write_bp (struct spi_nor *nor,u32 offset,size_t len,const void *buf) +static int sst_write_bp (struct mtd_info *mtd,loff_t offset,size_t len, +size_t *retlen,const u_char *buf) { -struct spi_nor *nor = flash->nor; +struct spi_nor *nor = mtd->priv;size_t actual;int ret;for (actual =0 ; actual < len; actual++) { - ret =sst_byte_write (nor, offset, buf + actual); + ret =sst_byte_write (nor, offset, buf + actual, retlen);if (ret) {debug ("spi-nor: sst byte program failed\n" );break ;
@@ -853,6 +900,7 @@ static int set_quad_mode(struct spi_nor *nor, const struct spi_nor_info *info)#if CONFIG_IS_ENABLED (OF_CONTROL )int spi_nor_decode_fdt (const void *blob,struct spi_nor *nor) { +struct mtd_info *mtd = nor->mtd;fdt_addr_t addr;fdt_size_t size;int node;
@@ -868,7 +916,7 @@ int spi_nor_decode_fdt(const void *blob, struct spi_nor *nor)return 0 ; } -if (flash->size != size) { +if (mtd->size != size) {debug ("%s: Memory map must cover entire device\n" , __func__);return -1 ; }
@@ -891,6 +939,7 @@ static int spi_nor_check(struct spi_nor *nor)int spi_nor_scan (struct spi_nor *nor) { +struct mtd_info *mtd = nor->mtd;const struct spi_nor_info *info =NULL ;static u8 flash_read_cmd[] = {SNOR_OP_READ ,
@@ -921,7 +970,13 @@ int spi_nor_scan(struct spi_nor *nor)write_sr (nor,0 ); } - flash->name = info->name; + mtd->name = info->name; + mtd->priv = nor; + mtd->type =MTD_NORFLASH ; + mtd->writesize =1 ; + mtd->flags =MTD_CAP_NORFLASH ; + mtd->_erase = spi_nor_erase; + mtd->_read = spi_nor_read;if (info->flags &USE_FSR ) nor->flags |=SNOR_F_USE_FSR ;
@@ -929,15 +984,13 @@ int spi_nor_scan(struct spi_nor *nor)if (info->flags &SST_WRITE ) nor->flags |=SNOR_F_SST_WRITE ; - flash->write = spi_nor_write; - flash->erase = spi_nor_erase; - flash->read = spi_nor_read; + mtd->_write = spi_nor_write;#if defined(CONFIG_SPI_FLASH_SST )if (nor->flags &SNOR_F_SST_WRITE ) {if (nor->mode &SNOR_WRITE_1_1_BYTE ) - flash->write = sst_write_bp; + mtd->_write = sst_write_bp;else - flash->write = sst_write_wp; + mtd->_write = sst_write_wp; }#endif
@@ -951,10 +1004,10 @@ int spi_nor_scan(struct spi_nor *nor) }#endif -if (flash->flash_lock && flash->flash_unlock && flash->flash_is_locked) { - flash->flash_lock = spi_nor_lock; - flash->flash_unlock = spi_nor_unlock; - flash->flash_is_locked = spi_nor_is_locked; +if (nor->flash_lock && nor->flash_unlock && nor->flash_is_locked) { + mtd->_lock = spi_nor_lock; + mtd->_unlock = spi_nor_unlock; + mtd->_is_locked = spi_nor_is_locked; }/* Compute the flash size */
@@ -972,30 +1025,30 @@ int spi_nor_scan(struct spi_nor *nor) nor->page_size =512 ; } nor->page_size <<= nor->shift; - flash->sector_size = info->sector_size << nor->shift; - flash->size = flash->sector_size * info->n_sectors << nor->shift; + mtd->writebufsize = nor->page_size; + mtd->size = (info->sector_size * info->n_sectors) << nor->shift;#ifdef CONFIG_SF_DUAL_FLASH if (nor->dual &SNOR_DUAL_STACKED ) - flash->size <<=1 ; + mtd->size <<=1 ;#endif #ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS /* prefer "small sector" erase if possible */ if (info->flags &SECT_4K ) { nor->erase_opcode =SNOR_OP_BE_4K ; - nor->erase_size =4096 << nor->shift; + mtd->erasesize =4096 << nor->shift; }else if (info->flags &SECT_4K_PMC ) { nor->erase_opcode =SNOR_OP_BE_4K_PMC ; - nor->erase_size =4096 ; + mtd->erasesize =4096 ; } else#endif { nor->erase_opcode =SNOR_OP_SE ; - nor->erase_size = flash->sector_size; + mtd->erasesize = info->sector_size << nor->shift; } -/* Now erase size becomes valid sector size */ - flash->sector_size = nor->erase_size; +if (info->flags &SPI_NOR_NO_ERASE ) + mtd->flags |=MTD_NO_ERASE ;/* Look for the fastest read cmd */ cmd =fls (info->flash_read & nor->read_mode);
@@ -1007,6 +1060,10 @@ int spi_nor_scan(struct spi_nor *nor) nor->read_opcode =SNOR_OP_READ_FAST ; } +/* Some devices cannot do fast-read */ +if (info->flags &SPI_NOR_NO_FR ) + nor->read_opcode =SNOR_OP_READ ; +/* Not require to look for fastest only two write cmds yet */ if (info->flags &SNOR_WRITE_QUAD && nor->mode &SNOR_WRITE_1_1_4 ) nor->program_opcode =SNOR_OP_QPP ;
@@ -1061,10 +1118,10 @@ int spi_nor_scan(struct spi_nor *nor)#endif #ifndef CONFIG_SPL_BUILD -printf ("spi-nor: detected %s with page size " , flash->name); +printf ("spi-nor: detected %s with page size " , mtd->name);print_size (nor->page_size,", erase size " ); -print_size (nor->erase_size,", total " ); -print_size (flash->size,"" ); +print_size (mtd->erasesize,", total " ); +print_size (mtd->size,"" );if (nor->memory_map)printf (", mapped at %p" , nor->memory_map);puts ("\n" );
@@ -1072,9 +1129,9 @@ int spi_nor_scan(struct spi_nor *nor)#ifndef CONFIG_SPI_FLASH_BAR if (((nor->dual ==SNOR_DUAL_SINGLE ) && - (flash->size >SNOR_16MB_BOUN )) || + (mtd->size >SNOR_16MB_BOUN )) || ((nor->dual >SNOR_DUAL_SINGLE ) && - (flash->size >SNOR_16MB_BOUN <<1 ))) { + (mtd->size >SNOR_16MB_BOUN <<1 ))) {puts ("spi-nor: Warning - Only lower 16MiB accessible," );puts (" Full access #define CONFIG_SPI_FLASH_BAR\n" ); }
Signature · 1 line
1.9.1
PATCH v5 8/32 mtd: spi-nor: Add spi_nor support in m25p80
In reply to Jagan Tekim25p80 is flash interface for spi-nor core and drivers/spi so add spi_nor{} functionalities like
- allocate spi_nor{}
- basic initilization
- install hooks
- call to spi-nor core, using spi_nor_scan
- register with mtd core
--- drivers/mtd/spi-nor/m25p80.c | 236 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+)
drivers/mtd/spi-nor/m25p80.c +236 -0
@@ -10,14 +10,249 @@#include <dm.h> #include <errno.h> #include <spi.h> + +#include <dm/device-internal.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/spi-nor.h> + +struct m25p { +struct spi_slave *spi; +struct spi_nor spi_nor; +}; + +static int spi_read_then_write (struct spi_slave *spi,const u8 *cmd, +size_t cmd_len,const u8 *data_out, +u8 *data_in,size_t data_len) +{ +unsigned long flags =SPI_XFER_BEGIN ; +int ret; + +if (data_len ==0 ) + flags |=SPI_XFER_END ; + + ret =spi_xfer (spi, cmd_len *8 , cmd,NULL , flags); +if (ret) { +debug ("SF: Failed to send command (%zu bytes): %d\n" , + cmd_len, ret); + }else if (data_len !=0 ) { + ret =spi_xfer (spi, data_len *8 , data_out, data_in, +SPI_XFER_END ); +if (ret) +debug ("SF: Failed to transfer %zu bytes of data: %d\n" , + data_len, ret); + } + +return ret; +} + +static int m25p80_read_reg (struct spi_nor *nor,u8 cmd,u8 *val,int len) +{ +struct m25p *flash = nor->priv; +struct spi_slave *spi = flash->spi; +int ret; + + ret =spi_claim_bus (spi); +if (ret <0 ) { +debug ("m25p80: unable to claim SPI bus\n" ); +return ret; + } + +if (nor->flags &SNOR_F_U_PAGE ) + spi->flags |=SPI_XFER_U_PAGE ; + + ret =spi_read_then_write (spi, &cmd,1 ,NULL , val, len); +if (ret <0 ) { +debug ("m25p80: error %d reading register %x\n" , ret, cmd); +return ret; + } + +spi_release_bus (spi); + +return ret; +} + +static int m25p80_write_reg (struct spi_nor *nor,u8 cmd,u8 *buf,int len) +{ +struct m25p *flash = nor->priv; +struct spi_slave *spi = flash->spi; +int ret; + + ret =spi_claim_bus (spi); +if (ret <0 ) { +debug ("m25p80: unable to claim SPI bus\n" ); +return ret; + } + +if (nor->flags &SNOR_F_U_PAGE ) + spi->flags |=SPI_XFER_U_PAGE ; + + ret =spi_read_then_write (spi, &cmd,1 , buf,NULL , len); +if (ret <0 ) { +debug ("m25p80: error %d writing register %x\n" , ret, cmd); +return ret; + } + +spi_release_bus (spi); + +return ret; +} + +void __weak flash_copy_mmap (void *data,void *offset,size_t len) +{ +memcpy (data, offset, len); +} + +static int m25p80_read_mmap (struct spi_nor *nor,void *data, +void *offset,size_t len) +{ +struct m25p *flash = nor->priv; +struct spi_slave *spi = flash->spi; +int ret; + + ret =spi_claim_bus (spi); +if (ret) { +debug ("m25p80: unable to claim SPI bus\n" ); +return ret; + } + +spi_xfer (spi,0 ,NULL ,NULL ,SPI_XFER_MMAP ); +flash_copy_mmap (data, offset, len); +spi_xfer (spi,0 ,NULL ,NULL ,SPI_XFER_MMAP_END ); + +spi_release_bus (spi); + +return ret; +} + +static int m25p80_read (struct spi_nor *nor,const u8 *cmd,size_t cmd_len, +void *data,size_t data_len) +{ +struct m25p *flash = nor->priv; +struct spi_slave *spi = flash->spi; +int ret; + + ret =spi_claim_bus (spi); +if (ret <0 ) { +debug ("m25p80: unable to claim SPI bus\n" ); +return ret; + } + +if (nor->flags &SNOR_F_U_PAGE ) + spi->flags |=SPI_XFER_U_PAGE ; + + ret =spi_read_then_write (spi, cmd, cmd_len,NULL , data, data_len); +if (ret <0 ) { +debug ("m25p80: error %d reading %x\n" , ret, *cmd); +return ret; + } + +spi_release_bus (spi); + +return ret; +} + +static int m25p80_write (struct spi_nor *nor,const u8 *cmd,size_t cmd_len, +const void *data,size_t data_len) +{ +struct m25p *flash = nor->priv; +struct spi_slave *spi = flash->spi; +int ret; + + ret =spi_claim_bus (spi); +if (ret <0 ) { +debug ("m25p80: unable to claim SPI bus\n" ); +return ret; + } + +if (nor->flags &SNOR_F_U_PAGE ) + spi->flags |=SPI_XFER_U_PAGE ; + + ret =spi_read_then_write (spi, cmd, cmd_len, data,NULL , data_len); +if (ret <0 ) { +debug ("m25p80: error %d writing %x\n" , ret, *cmd); +return ret; + } + +spi_release_bus (spi); + +return ret; +}static int m25p_probe (struct udevice *dev) {struct spi_slave *spi =dev_get_parent_priv (dev);struct mtd_info *mtd =dev_get_uclass_priv (dev); +struct m25p *flash =dev_get_priv (dev); +struct spi_nor *nor; +int ret; + + nor = &flash->spi_nor; + +/* install hooks */ + nor->read_mmap = m25p80_read_mmap; + nor->read = m25p80_read; + nor->write = m25p80_write; + nor->read_reg = m25p80_read_reg; + nor->write_reg = m25p80_write_reg; + + nor->mtd = mtd; + nor->priv = flash; + flash->spi = spi; + +/* claim spi bus */ + ret =spi_claim_bus (spi); +if (ret) { +debug ("m25p80: failed to claim SPI bus: %d\n" , ret); +return ret; + } + +switch (spi->mode_rx) { +case SPI_RX_SLOW : + nor->read_mode =SNOR_READ ; +break ; +case SPI_RX_DUAL : + nor->read_mode =SNOR_READ_1_1_2 ; +break ; +case SPI_RX_QUAD : + nor->read_mode =SNOR_READ_1_1_4 ; +break ; + } + +switch (spi->mode) { +case SPI_TX_BYTE : + nor->mode =SNOR_WRITE_1_1_BYTE ; +break ; +case SPI_TX_QUAD : + nor->mode =SNOR_WRITE_1_1_4 ; +break ; + } + + nor->memory_map = spi->memory_map; + nor->max_write_size = spi->max_write_size; + +/* TODO: unrelated to spi_slave{} */ +if (spi->option &SPI_CONN_DUAL_SHARED ) + nor->dual =SNOR_DUAL_STACKED ; +else if (spi->option &SPI_CONN_DUAL_SEPARATED ) + nor->dual =SNOR_DUAL_PARALLEL ; + + ret =spi_nor_scan (nor); +if (ret) + goto err_scan; + + ret =add_mtd_device (mtd); +if (ret) + goto err_mtd;return 0 ; + +err_scan: +spi_release_bus (spi); +err_mtd: +spi_free_slave (spi); +device_remove (dev); +return ret; }static const struct udevice_id m25p_ids[] = {
@@ -34,4 +269,5 @@ U_BOOT_DRIVER(m25p80) = { .id = UCLASS_MTD, .of_match = m25p_ids, .probe = m25p_probe, + .priv_auto_alloc_size = sizeof(struct m25p), };
Signature · 1 line
1.9.1
PATCH v5 9/32 mtd: spi-nor: Add dm spi-nor probing
In reply to Jagan TekiThis patch adds driver-model probe from cmd_sf through MTD_DM_SPI_NOR which is depends on MTD and DM_SPI uclass.
--- cmd/sf.c | 4 ++-- drivers/mtd/spi-nor/Kconfig | 5 +++++ drivers/mtd/spi-nor/Makefile | 2 ++ drivers/mtd/spi-nor/spi-nor-probe.c | 30 ++++++++++++++++++++++++++++++ include/spi_flash.h | 6 ++++++ 5 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 drivers/mtd/spi-nor/spi-nor-probe.c
cmd/sf.c +2 -2
@@ -85,7 +85,7 @@ static int do_spi_flash_probe(int argc, char * const argv[])unsigned int speed =CONFIG_SF_DEFAULT_SPEED ;unsigned int mode =CONFIG_SF_DEFAULT_MODE ;char *endp; -#ifdef CONFIG_DM_SPI_FLASH +#if defined(CONFIG_DM_SPI_FLASH ) || defined (CONFIG_MTD_DM_SPI_NOR )struct udevice *new, *bus_dev;int ret;#else
@@ -118,7 +118,7 @@ static int do_spi_flash_probe(int argc, char * const argv[])return -1 ; } -#ifdef CONFIG_DM_SPI_FLASH +#if defined(CONFIG_DM_SPI_FLASH ) || defined (CONFIG_MTD_DM_SPI_NOR )/* Remove the old device, otherwise probe will just be a nop */ ret =spi_find_bus_and_cs (bus, cs, &bus_dev, &new);if (!ret) {
drivers/mtd/spi-nor/Kconfig +5 -0
@@ -1,5 +1,6 @@ menuconfig MTD_SPI_NOR tristate "SPI-NOR device support" + select MTD_DM_SPI_NOR help This is the core SPI NOR framework which can be used to interact SPI-NOR to SPI driver interface layer and the SPI-NOR controller driver.
@@ -12,6 +13,10 @@ menuconfig MTD_SPI_NOR SPI-NOR controller drivers for SPI-NOR device access. Note that from SPI-NOR core to SPI drivers there should be an interface layer. +config MTD_DM_SPI_NOR + tristate + depends on DM_SPI && MTD + if MTD_SPI_NOR config MTD_M25P80
drivers/mtd/spi-nor/Makefile +2 -0
@@ -6,6 +6,8 @@ ifdef CONFIG_MTD_SPI_NOR obj-y += spi-nor.o obj-y += spi-nor-ids.o + +obj-$(CONFIG_MTD_DM_SPI_NOR) += spi-nor-probe.o endif obj-$(CONFIG_MTD_M25P80) += m25p80.o
drivers/mtd/spi-nor/spi-nor-probe.c new file +30 -0
@@ -0,0 +1,30 @@ +/* +* Copyright (c) 2014 Google, Inc +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <common.h> +#include <dm.h> +#include <spi.h> +#include <spi_flash.h> + +int spi_flash_probe_bus_cs (unsigned int busnum,unsigned int cs, +unsigned int max_hz,unsigned int spi_mode, +struct udevice **devp) +{ +struct spi_slave *slave; +struct udevice *bus; +char name[30 ], *str; +int ret; + +snprintf (name,sizeof (name),"spi-nor@%d:%d" , busnum, cs); + str =strdup (name); + ret =spi_get_bus_and_cs (busnum, cs, max_hz, spi_mode, +"m25p80" , str, &bus, &slave); +if (ret) +return ret; + + *devp = slave->dev; +return 0 ; +}
include/spi_flash.h +6 -0
@@ -190,6 +190,12 @@ int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs,void sandbox_sf_unbind_emul (struct sandbox_state *state,int busnum,int cs); +#elif CONFIG_MTD_DM_SPI_NOR + +int spi_flash_probe_bus_cs (unsigned int busnum,unsigned int cs, +unsigned int max_hz,unsigned int spi_mode, +struct udevice **devp); +#else struct spi_flash *spi_flash_probe (unsigned int bus,unsigned int cs,unsigned int max_hz,unsigned int spi_mode);
Signature · 1 line
1.9.1
PATCH v5 10/32 mtd: spi-nor: Add spi_flash_probe for mtd-dm-spi-nor
In reply to Jagan TekiWhile probing spi-nor in SPL spi_flash_probe is needed, so add the flash probe code in spi-nor-probe.c
--- drivers/mtd/spi-nor/spi-nor-probe.c | 15 +++++++++++++++ include/spi_flash.h | 4 ++++ 2 files changed, 19 insertions(+)
drivers/mtd/spi-nor/spi-nor-probe.c +15 -0
@@ -9,6 +9,21 @@#include <spi.h> #include <spi_flash.h> +/* +* TODO(sjg at chromium.org): This is an old-style function. We should remove +* it when all SPI flash drivers use dm +*/ +spi_flash_t *spi_flash_probe (unsigned int bus,unsigned int cs, +unsigned int max_hz,unsigned int spi_mode) +{ +struct udevice *dev; + +if (spi_flash_probe_bus_cs (bus, cs, max_hz, spi_mode, &dev)) +return NULL ; + +return dev_get_uclass_priv (dev); +} +int spi_flash_probe_bus_cs (unsigned int busnum,unsigned int cs,unsigned int max_hz,unsigned int spi_mode,struct udevice **devp)
include/spi_flash.h +4 -0
@@ -196,6 +196,10 @@ int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs, unsigned int max_hz, unsigned int spi_mode, struct udevice **devp); +/* Compatibility function - this is the old U-Boot API */ +spi_flash_t *spi_flash_probe (unsigned int bus,unsigned int cs, +unsigned int max_hz,unsigned int spi_mode); +#else struct spi_flash *spi_flash_probe (unsigned int bus,unsigned int cs,unsigned int max_hz,unsigned int spi_mode);
Signature · 1 line
1.9.1
PATCH v5 11/32 cmd: sf: Add mtd_info for mtd-dm-spi-nor code
In reply to Jagan TekiThis patch adds support for mtd_info operations handling from cmd/sf.c
--- cmd/sf.c | 34 +++++++++++++++++----------------- include/spi_flash.h | 48 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 53 insertions(+), 29 deletions(-)
cmd/sf.c +17 -17
@@ -19,7 +19,7 @@#include <asm/io.h> #include <dm/device-internal.h> -static struct spi_flash *flash; +static spi_flash_t *flash;/* * This function computes the length argument for the erase command.
@@ -53,8 +53,8 @@ static int sf_parse_len_arg(char *arg, ulong *len)if (ep == arg || *ep !='\0' )return -1 ; -if (round_up_len && flash->sector_size >0 ) - *len =ROUND (len_arg, flash->sector_size); +if (round_up_len && flash->erasesize >0 ) + *len =ROUND (len_arg, flash->erasesize);else *len = len_arg;
@@ -89,7 +89,7 @@ static int do_spi_flash_probe(int argc, char * const argv[])struct udevice *new, *bus_dev;int ret;#else -struct spi_flash *new; +spi_flash_t *new;#endif if (argc >=2 ) {
@@ -166,15 +166,15 @@ static int do_spi_flash_probe(int argc, char * const argv[])* @param skipped Count of skipped data (incremented by this function) * @return NULL if OK, else a string containing the stage which failed */ -static const char *spi_flash_update_block (struct spi_flash *flash,u32 offset, +static const char *spi_flash_update_block (spi_flash_t *flash,u32 offset,size_t len,const char *buf,char *cmp_buf,size_t *skipped) {char *ptr = (char *)buf; -debug ("offset=%#x, sector_size=%#x, len=%#zx\n" , - offset, flash->sector_size, len); +debug ("offset=%#x, erasesize=%#x, len=%#zx\n" , + offset, flash->erasesize, len);/* Read the entire sector so to allow for rewriting */ -if (spi_flash_read (flash, offset, flash->sector_size, cmp_buf)) +if (spi_flash_read (flash, offset, flash->erasesize, cmp_buf))return "read" ;/* Compare only what is meaningful (len) */ if (memcmp (cmp_buf, buf, len) ==0 ) {
@@ -184,15 +184,15 @@ static const char *spi_flash_update_block(struct spi_flash *flash, u32 offset,return NULL ; }/* Erase the entire sector */ -if (spi_flash_erase (flash, offset, flash->sector_size)) +if (spi_flash_erase (flash, offset, flash->erasesize))return "erase" ;/* If it's a partial sector, copy the data into the temp-buffer */ -if (len != flash->sector_size) { +if (len != flash->erasesize) {memcpy (cmp_buf, buf, len); ptr = cmp_buf; }/* Write one complete sector */ -if (spi_flash_write (flash, offset, flash->sector_size, ptr)) +if (spi_flash_write (flash, offset, flash->erasesize, ptr))return "write" ;return NULL ;
@@ -208,7 +208,7 @@ static const char *spi_flash_update_block(struct spi_flash *flash, u32 offset,* @param buf buffer to write from * @return 0 if ok, 1 on error */ -static int spi_flash_update (struct spi_flash *flash,u32 offset, +static int spi_flash_update (spi_flash_t *flash,u32 offset,size_t len,const char *buf) {const char *err_oper =NULL ;
@@ -223,12 +223,12 @@ static int spi_flash_update(struct spi_flash *flash, u32 offset,if (end - buf >=200 ) scale = (end - buf) /100 ; - cmp_buf =memalign (ARCH_DMA_MINALIGN , flash->sector_size); + cmp_buf =memalign (ARCH_DMA_MINALIGN , flash->erasesize);if (cmp_buf) {ulong last_update =get_timer (0 );for (; buf < end && !err_oper; buf += todo, offset += todo) { - todo =min_t (size_t, end - buf, flash->sector_size); + todo =min_t (size_t, end - buf, flash->erasesize);if (get_timer (last_update) >100 ) { printf(" \rUpdating, %zu%% %lu B/s", 100 - (end - buf) / scale,
@@ -280,7 +280,7 @@ static int do_spi_flash_read_write(int argc, char * const argv[])/* Consistency checking */ if (offset + len > flash->size) { -printf ("ERROR: attempting %s past flash size (%#x)\n" , +printf ("ERROR: attempting %s past flash size (%#llx)\n" , argv[0 ], flash->size);return 1 ; }
@@ -336,7 +336,7 @@ static int do_spi_flash_erase(int argc, char * const argv[])/* Consistency checking */ if (offset + size > flash->size) { -printf ("ERROR: attempting %s past flash size (%#x)\n" , +printf ("ERROR: attempting %s past flash size (%#llx)\n" , argv[0 ], flash->size);return 1 ; }
@@ -436,7 +436,7 @@ static void spi_test_next_stage(struct test_info *test)* @param vbuf Verification buffer * @return 0 if ok, -1 on error */ -static int spi_flash_test (struct spi_flash *flash,uint8_t *buf,ulong len, +static int spi_flash_test (spi_flash_t *flash,uint8_t *buf,ulong len,ulong offset,uint8_t *vbuf) {struct test_info test;
include/spi_flash.h +36 -12
66 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v5 12/32 mtd: spi-nor: m25p80: Add spi_nor support for non-dm
In reply to Jagan TekiLike adding spi_nor support for dm-driven code in m25p80 add the same way for non-dm code as well.
- allocate spi_nor{}
- basic initilization
- install hooks
- call to spi-nor core, using spi_nor_scan
- register with mtd core
--- drivers/mtd/spi-nor/m25p80.c | 108 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 96 insertions(+), 12 deletions(-)
drivers/mtd/spi-nor/m25p80.c +96 -12
@@ -19,6 +19,9 @@struct m25p {struct spi_slave *spi;struct spi_nor spi_nor; +#ifndef CONFIG_MTD_DM_SPI_NOR +struct mtd_info mtd; +#endif }; static int spi_read_then_write(struct spi_slave *spi, const u8 *cmd,
@@ -179,16 +182,13 @@ static int m25p80_write(struct spi_nor *nor, const u8 *cmd, size_t cmd_len,return ret; } -static int m25p_probe (struct udevice *dev) +static int m25p80_spi_nor (struct spi_nor *nor) { -struct spi_slave *spi =dev_get_parent_priv (dev); -struct mtd_info *mtd =dev_get_uclass_priv (dev); -struct m25p *flash =dev_get_priv (dev); -struct spi_nor *nor; +struct mtd_info *mtd = nor->mtd; +struct m25p *flash = nor->priv; +struct spi_slave *spi = flash->spi;int ret; - nor = &flash->spi_nor; -/* install hooks */ nor->read_mmap = m25p80_read_mmap; nor->read = m25p80_read;
@@ -196,10 +196,6 @@ static int m25p_probe(struct udevice *dev) nor->read_reg = m25p80_read_reg; nor->write_reg = m25p80_write_reg; - nor->mtd = mtd; - nor->priv = flash; - flash->spi = spi; -/* claim spi bus */ ret =spi_claim_bus (spi);if (ret) {
@@ -251,10 +247,33 @@ err_scan:spi_release_bus (spi); err_mtd:spi_free_slave (spi); -device_remove (dev);return ret; } +#ifdef CONFIG_MTD_DM_SPI_NOR +static int m25p_probe (struct udevice *dev) +{ +struct spi_slave *spi =dev_get_parent_priv (dev); +struct mtd_info *mtd =dev_get_uclass_priv (dev); +struct m25p *flash =dev_get_priv (dev); +struct spi_nor *nor; +int ret; + + nor = &flash->spi_nor; + + nor->mtd = mtd; + nor->priv = flash; + flash->spi = spi; + + ret =m25p80_spi_nor (nor); +if (ret) { +device_remove (dev); +return ret; + } + +return 0 ; +} +static const struct udevice_id m25p_ids[] = {/* * Generic compatibility for SPI NOR that can be identified by the
@@ -271,3 +290,68 @@ U_BOOT_DRIVER(m25p80) = { .probe = m25p_probe, .priv_auto_alloc_size = sizeof(struct m25p), }; + +#else + +static struct mtd_info *m25p80_probe_tail (struct spi_slave *bus) +{ +struct m25p *flash; +struct spi_nor *nor; +int ret; + + flash =calloc (1 ,sizeof (*flash)); +if (!flash) { +debug ("mp25p80: failed to allocate m25p\n" ); +return NULL ; + } + + nor = &flash->spi_nor; + nor->mtd = &flash->mtd; + + nor->priv = flash; + flash->spi = bus; + + ret =m25p80_spi_nor (nor); +if (ret) { +free (flash); +return NULL ; + } + +return nor->mtd; +} + +struct mtd_info *spi_flash_probe (unsigned int busnum,unsigned int cs, +unsigned int max_hz,unsigned int spi_mode) +{ +struct spi_slave *bus; + + bus =spi_setup_slave (busnum, cs, max_hz, spi_mode); +if (!bus) +return NULL ; +return m25p80_probe_tail (bus); +} + +#ifdef CONFIG_OF_SPI_FLASH +struct mtd_info *spi_flash_probe_fdt (const void *blob,int slave_node, +int spi_node) +{ +struct spi_slave *bus; + + bus =spi_setup_slave_fdt (blob, slave_node, spi_node); +if (!bus) +return NULL ; +return m25p80_probe_tail (bus); +} +#endif + +void spi_flash_free (struct mtd_info *info) +{ +struct spi_nor *nor = info->priv; +struct m25p *flash = nor->priv; + +del_mtd_device (info); +spi_free_slave (flash->spi); +free (flash); +} + +#endif /* CONFIG_MTD_DM_SPI_NOR */
Signature · 1 line
1.9.1
PATCH v5 13/32 spi_flash: Use mtd_info operation for non-dm
In reply to Jagan TekiSince non-dm code in m25p80 handling spi_nor along with mtd, hence use the mtd_info operation from user commands instead of legacy spi_flash{} ops.
--- include/spi_flash.h | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-)
include/spi_flash.h +4 -19
@@ -191,7 +191,9 @@ int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs,void sandbox_sf_unbind_emul (struct sandbox_state *state,int busnum,int cs); -#elif CONFIG_MTD_DM_SPI_NOR +#endif + +#ifdef CONFIG_MTD_DM_SPI_NOR typedef struct mtd_info spi_flash_t ;
@@ -254,24 +256,7 @@ struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node,void spi_flash_free (struct spi_flash *flash); -static inline int spi_flash_read (struct spi_flash *flash,u32 offset, -size_t len,void *buf) -{ -return flash->read (flash, offset, len, buf); -} - -static inline int spi_flash_write (struct spi_flash *flash,u32 offset, -size_t len,const void *buf) -{ -return flash->write (flash, offset, len, buf); -} - -static inline int spi_flash_erase (struct spi_flash *flash,u32 offset, -size_t len) -{ -return flash->erase (flash, offset, len); -} -#endif +#endif /* CONFIG_MTD_DM_SPI_NOR */ void spi_boot (void )__noreturn ;void spi_spl_load_image (uint32_t offs,unsigned int size,void *vdst);
Signature · 1 line
1.9.1
PATCH v5 14/32 mtd: spi-nor: Move spi_read_then_write to spi layer
In reply to Jagan TekiSince spi_read_then_write is doing spi operations like setting up commands, tx and rx through spi_xfer, So it is meanfull to have this definition at spi layer and flash layer should use this whenever required.
--- drivers/mtd/spi-nor/m25p80.c | 25 ------------------------- drivers/spi/spi-uclass.c | 25 +++++++++++++++++++++++++ drivers/spi/spi.c | 25 +++++++++++++++++++++++++ include/spi.h | 5 +++++ 4 files changed, 55 insertions(+), 25 deletions(-)
drivers/mtd/spi-nor/m25p80.c +0 -25
@@ -24,31 +24,6 @@ struct m25p {#endif }; -static int spi_read_then_write (struct spi_slave *spi,const u8 *cmd, -size_t cmd_len,const u8 *data_out, -u8 *data_in,size_t data_len) -{ -unsigned long flags =SPI_XFER_BEGIN ; -int ret; - -if (data_len ==0 ) - flags |=SPI_XFER_END ; - - ret =spi_xfer (spi, cmd_len *8 , cmd,NULL , flags); -if (ret) { -debug ("SF: Failed to send command (%zu bytes): %d\n" , - cmd_len, ret); - }else if (data_len !=0 ) { - ret =spi_xfer (spi, data_len *8 , data_out, data_in, -SPI_XFER_END ); -if (ret) -debug ("SF: Failed to transfer %zu bytes of data: %d\n" , - data_len, ret); - } - -return ret; -} -static int m25p80_read_reg (struct spi_nor *nor,u8 cmd,u8 *val,int len) {struct m25p *flash = nor->priv;
drivers/spi/spi-uclass.c +25 -0
@@ -95,6 +95,31 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,return spi_get_ops (bus)->xfer (dev, bitlen, dout, din, flags); } +int spi_read_then_write (struct spi_slave *spi,const u8 *cmd, +size_t cmd_len,const u8 *data_out, +u8 *data_in,size_t data_len) +{ +unsigned long flags =SPI_XFER_BEGIN ; +int ret; + +if (data_len ==0 ) + flags |=SPI_XFER_END ; + + ret =spi_xfer (spi, cmd_len *8 , cmd,NULL , flags); +if (ret) { +debug ("spi: failed to send command (%zu bytes): %d\n" , + cmd_len, ret); + }else if (data_len !=0 ) { + ret =spi_xfer (spi, data_len *8 , data_out, data_in, +SPI_XFER_END ); +if (ret) +debug ("spi: failed to transfer %zu bytes of data: %d\n" , + data_len, ret); + } + +return ret; +} +static int spi_post_bind (struct udevice *dev) {/* Scan the bus for devices */
drivers/spi/spi.c +25 -0
@@ -39,6 +39,31 @@ void *spi_do_alloc_slave(int offset, int size, unsigned int bus,return ptr; } +int spi_read_then_write (struct spi_slave *spi,const u8 *cmd, +size_t cmd_len,const u8 *data_out, +u8 *data_in,size_t data_len) +{ +unsigned long flags =SPI_XFER_BEGIN ; +int ret; + +if (data_len ==0 ) + flags |=SPI_XFER_END ; + + ret =spi_xfer (spi, cmd_len *8 , cmd,NULL , flags); +if (ret) { +debug ("spi: failed to send command (%zu bytes): %d\n" , + cmd_len, ret); + }else if (data_len !=0 ) { + ret =spi_xfer (spi, data_len *8 , data_out, data_in, +SPI_XFER_END ); +if (ret) +debug ("spi: failed to transfer %zu bytes of data: %d\n" , + data_len, ret); + } + +return ret; +} +#ifdef CONFIG_OF_SPI struct spi_slave *spi_base_setup_slave_fdt (const void *blob,int busnum,int node)
include/spi.h +5 -0
@@ -265,6 +265,11 @@ int spi_set_wordlen(struct spi_slave *slave, unsigned int wordlen);int spi_xfer (struct spi_slave *slave,unsigned int bitlen,const void *dout,void *din,unsigned long flags); +/* spi_write_then_read - SPI synchronous read followed by write */ +int spi_read_then_write (struct spi_slave *spi,const u8 *cmd, +size_t cmd_len,const u8 *data_out, +u8 *data_in,size_t data_len); +/* Copy memory mapped data */ void spi_flash_copy_mmap (void *data,void *offset,size_t len);
Signature · 1 line
1.9.1
PATCH v5 15/32 spi: Rename spi_read_then_write to spi_write_then_read
In reply to Jagan TekiSince spi_read_then_write moved into spi layer, the meaning of data transfer is also change from read_then_write to write_then_read, this means first spi will write the opcode through and then read the respective buffer.
--- drivers/mtd/spi-nor/m25p80.c | 8 ++++---- drivers/spi/spi-uclass.c | 19 +++++++++---------- drivers/spi/spi.c | 19 +++++++++---------- include/spi.h | 23 +++++++++++++++++++---- 4 files changed, 41 insertions(+), 28 deletions(-)
drivers/mtd/spi-nor/m25p80.c +4 -4
@@ -39,7 +39,7 @@ static int m25p80_read_reg(struct spi_nor *nor, u8 cmd, u8 *val, int len)if (nor->flags &SNOR_F_U_PAGE ) spi->flags |=SPI_XFER_U_PAGE ; - ret =spi_read_then_write (spi, &cmd,1 ,NULL , val, len); + ret =spi_write_then_read (spi, &cmd,1 ,NULL , val, len);if (ret <0 ) {debug ("m25p80: error %d reading register %x\n" , ret, cmd);return ret;
@@ -65,7 +65,7 @@ static int m25p80_write_reg(struct spi_nor *nor, u8 cmd, u8 *buf, int len)if (nor->flags &SNOR_F_U_PAGE ) spi->flags |=SPI_XFER_U_PAGE ; - ret =spi_read_then_write (spi, &cmd,1 , buf,NULL , len); + ret =spi_write_then_read (spi, &cmd,1 , buf,NULL , len);if (ret <0 ) {debug ("m25p80: error %d writing register %x\n" , ret, cmd);return ret;
@@ -119,7 +119,7 @@ static int m25p80_read(struct spi_nor *nor, const u8 *cmd, size_t cmd_len,if (nor->flags &SNOR_F_U_PAGE ) spi->flags |=SPI_XFER_U_PAGE ; - ret =spi_read_then_write (spi, cmd, cmd_len,NULL , data, data_len); + ret =spi_write_then_read (spi, cmd, cmd_len,NULL , data, data_len);if (ret <0 ) {debug ("m25p80: error %d reading %x\n" , ret, *cmd);return ret;
@@ -146,7 +146,7 @@ static int m25p80_write(struct spi_nor *nor, const u8 *cmd, size_t cmd_len,if (nor->flags &SNOR_F_U_PAGE ) spi->flags |=SPI_XFER_U_PAGE ; - ret =spi_read_then_write (spi, cmd, cmd_len, data,NULL , data_len); + ret =spi_write_then_read (spi, cmd, cmd_len, data,NULL , data_len);if (ret <0 ) {debug ("m25p80: error %d writing %x\n" , ret, *cmd);return ret;
drivers/spi/spi-uclass.c +9 -10
@@ -95,26 +95,25 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,return spi_get_ops (bus)->xfer (dev, bitlen, dout, din, flags); } -int spi_read_then_write (struct spi_slave *spi,const u8 *cmd, -size_t cmd_len,const u8 *data_out, -u8 *data_in,size_t data_len) +int spi_write_then_read (struct spi_slave *slave,const u8 *opcode, +size_t n_opcode,const u8 *txbuf,u8 *rxbuf, +size_t n_buf) {unsigned long flags =SPI_XFER_BEGIN ;int ret; -if (data_len ==0 ) +if (n_buf ==0 ) flags |=SPI_XFER_END ; - ret =spi_xfer (spi, cmd_len *8 , cmd,NULL , flags); + ret =spi_xfer (slave, n_opcode *8 , opcode,NULL , flags);if (ret) {debug ("spi: failed to send command (%zu bytes): %d\n" , - cmd_len, ret); - }else if (data_len !=0 ) { - ret =spi_xfer (spi, data_len *8 , data_out, data_in, -SPI_XFER_END ); + n_opcode, ret); + }else if (n_buf !=0 ) { + ret =spi_xfer (slave, n_buf *8 , txbuf, rxbuf,SPI_XFER_END );if (ret)debug ("spi: failed to transfer %zu bytes of data: %d\n" , - data_len, ret); + n_buf, ret); }return ret;
drivers/spi/spi.c +9 -10
@@ -39,26 +39,25 @@ void *spi_do_alloc_slave(int offset, int size, unsigned int bus,return ptr; } -int spi_read_then_write (struct spi_slave *spi,const u8 *cmd, -size_t cmd_len,const u8 *data_out, -u8 *data_in,size_t data_len) +int spi_write_then_read (struct spi_slave *slave,const u8 *opcode, +size_t n_opcode,const u8 *txbuf,u8 *rxbuf, +size_t n_buf) {unsigned long flags =SPI_XFER_BEGIN ;int ret; -if (data_len ==0 ) +if (n_buf ==0 ) flags |=SPI_XFER_END ; - ret =spi_xfer (spi, cmd_len *8 , cmd,NULL , flags); + ret =spi_xfer (slave, n_opcode *8 , opcode,NULL , flags);if (ret) {debug ("spi: failed to send command (%zu bytes): %d\n" , - cmd_len, ret); - }else if (data_len !=0 ) { - ret =spi_xfer (spi, data_len *8 , data_out, data_in, -SPI_XFER_END ); + n_opcode, ret); + }else if (n_buf !=0 ) { + ret =spi_xfer (slave, n_buf *8 , txbuf, rxbuf,SPI_XFER_END );if (ret)debug ("spi: failed to transfer %zu bytes of data: %d\n" , - data_len, ret); + n_buf, ret); }return ret;
include/spi.h +19 -4
@@ -265,10 +265,25 @@ int spi_set_wordlen(struct spi_slave *slave, unsigned int wordlen);int spi_xfer (struct spi_slave *slave,unsigned int bitlen,const void *dout,void *din,unsigned long flags); -/* spi_write_then_read - SPI synchronous read followed by write */ -int spi_read_then_write (struct spi_slave *spi,const u8 *cmd, -size_t cmd_len,const u8 *data_out, -u8 *data_in,size_t data_len); +/** +* spi_write_then_read - SPI synchronous write followed by read +* +* This performs a half duplex transaction in which the first transaction +* is to send the opcode and if the length of buf is non-zero then it start +* the second transaction as tx or rx based on the need from respective slave. +* +* @slave: slave device with which opcode/data will be exchanged +* @opcode: opcode used for specific transfer +* @n_opcode: size of opcode, in bytes +* @txbuf: buffer into which data to be written +* @rxbuf: buffer into which data will be read +* @n_buf: size of buf (whether it's [tx|rx]buf), in bytes +* +* Returns: 0 on success, not 0 on failure +*/ +int spi_write_then_read (struct spi_slave *slave,const u8 *opcode, +size_t n_opcode,const u8 *txbuf,u8 *rxbuf, +size_t n_buf);/* Copy memory mapped data */ void spi_flash_copy_mmap (void *data,void *offset,size_t len);
Signature · 1 line
1.9.1
PATCH v5 16/32 spi: Drop mode_rx
In reply to Jagan Tekimp2580 will take care of tx and rx mode's so there is no need to differentiate these into spi layer level hence replaced all mode_rx macros with mode.
--- drivers/mtd/spi-nor/m25p80.c | 2 +- drivers/spi/ich.c | 6 ++---- drivers/spi/spi-uclass.c | 11 ++++------- drivers/spi/ti_qspi.c | 6 +++--- include/spi.h | 14 ++++---------- 5 files changed, 14 insertions(+), 25 deletions(-)
drivers/mtd/spi-nor/m25p80.c +1 -1
@@ -178,7 +178,7 @@ static int m25p80_spi_nor(struct spi_nor *nor)return ret; } -switch (spi->mode_rx) { +switch (spi->mode) {case SPI_RX_SLOW : nor->read_mode =SNOR_READ ;break ;
drivers/spi/ich.c +2 -4
@@ -678,10 +678,8 @@ static int ich_spi_child_pre_probe(struct udevice *dev)* ICH 7 SPI controller only supports array read command * and byte program command for SST flash */ -if (plat->ich_version ==PCHV_7 ) { - slave->mode_rx =SPI_RX_SLOW ; - slave->mode =SPI_TX_BYTE ; - } +if (plat->ich_version ==PCHV_7 ) + slave->mode =SPI_TX_BYTE |SPI_RX_SLOW ;return 0 ; }
drivers/spi/spi-uclass.c +4 -7
@@ -181,7 +181,6 @@ static int spi_child_pre_probe(struct udevice *dev) slave->max_hz = plat->max_hz; slave->mode = plat->mode; - slave->mode_rx = plat->mode_rx;return 0 ; }
@@ -393,7 +392,7 @@ void spi_free_slave(struct spi_slave *slave)int spi_slave_ofdata_to_platdata (const void *blob,int node,struct dm_spi_slave_platdata *plat) { -int mode =0 , mode_rx =0 ; +int mode =0 ;int value; plat->cs =fdtdec_get_int (blob, node,"reg" ,-1 );
@@ -425,24 +424,22 @@ int spi_slave_ofdata_to_platdata(const void *blob, int node,break ; } - plat->mode = mode; - value =fdtdec_get_uint (blob, node,"spi-rx-bus-width" ,1 );switch (value) {case 1 :break ;case 2 : - mode_rx |=SPI_RX_DUAL ; + mode |=SPI_RX_DUAL ;break ;case 4 : - mode_rx |=SPI_RX_QUAD ; + mode |=SPI_RX_QUAD ;break ;default :error ("spi-rx-bus-width %d not supported\n" , value);break ; } - plat->mode_rx = mode_rx; + plat->mode = mode;return 0 ; }
drivers/spi/ti_qspi.c +3 -3
@@ -338,7 +338,7 @@ static void ti_spi_setup_spi_register(struct ti_qspi_priv *priv)QSPI_SETUP0_NUM_D_BYTES_8_BITS |QSPI_SETUP0_READ_QUAD |QSPI_CMD_WRITE | QSPI_NUM_DUMMY_BITS); - slave->mode_rx =SPI_RX_QUAD ; + slave->mode |=SPI_RX_QUAD ;#else memval |=QSPI_CMD_READ |QSPI_SETUP0_NUM_A_BYTES | QSPI_SETUP0_NUM_D_BYTES_NO_BITS |
@@ -422,7 +422,7 @@ static void __ti_qspi_setup_memorymap(struct ti_qspi_priv *priv, bool enable) {u32 memval; -u32 mode = slave->mode_rx & (SPI_RX_QUAD |SPI_RX_DUAL ); +u32 mode = slave->mode & (SPI_RX_QUAD |SPI_RX_DUAL );if (!enable) {writel (0 , &priv->base->setup0);
@@ -436,7 +436,7 @@ static void __ti_qspi_setup_memorymap(struct ti_qspi_priv *priv, memval |=QSPI_CMD_READ_QUAD ; memval |=QSPI_SETUP0_NUM_D_BYTES_8_BITS ; memval |=QSPI_SETUP0_READ_QUAD ; - slave->mode_rx =SPI_RX_QUAD ; + slave->mode |=SPI_RX_QUAD ;break ;case SPI_RX_DUAL : memval |=QSPI_CMD_READ_DUAL ;
include/spi.h +4 -10
@@ -26,12 +26,10 @@#define SPI_TX_BYTE BIT(8)/* transmit with 1 wire byte */ #define SPI_TX_DUAL BIT(9)/* transmit with 2 wires */ #define SPI_TX_QUAD BIT(10)/* transmit with 4 wires */ - -/* SPI mode_rx flags */ -#define SPI_RX_SLOW BIT(0)/* receive with 1 wire slow */ -#define SPI_RX_FAST BIT(1)/* receive with 1 wire fast */ -#define SPI_RX_DUAL BIT(2)/* receive with 2 wires */ -#define SPI_RX_QUAD BIT(3)/* receive with 4 wires */ +#define SPI_RX_SLOW BIT(11)/* receive with 1 wire slow */ +#define SPI_RX_FAST BIT(12)/* receive with 1 wire fast */ +#define SPI_RX_DUAL BIT(13)/* receive with 2 wires */ +#define SPI_RX_QUAD BIT(14)/* receive with 4 wires */ /* SPI bus connection options - see enum spi_dual_flash */ #define SPI_CONN_DUAL_SHARED (1 << 0)
@@ -61,13 +59,11 @@ struct dm_spi_bus {* @cs: Chip select number (0..n-1) * @max_hz: Maximum bus speed that this slave can tolerate * @mode: SPI mode to use for this device (see SPI mode flags) -* @mode_rx: SPI RX mode to use for this slave (see SPI mode_rx flags) */ struct dm_spi_slave_platdata {unsigned int cs;uint max_hz;uint mode; -u8 mode_rx; };#endif /* CONFIG_DM_SPI */
@@ -94,7 +90,6 @@ struct dm_spi_slave_platdata {* bus (bus->seq) so does not need to be stored * @cs: ID of the chip select connected to the slave. * @mode: SPI mode to use for this slave (see SPI mode flags) -* @mode_rx: SPI RX mode to use for this slave (see SPI mode_rx flags) * @wordlen: Size of SPI word in number of bits * @max_write_size: If non-zero, the maximum number of bytes which can * be written at once, excluding command bytes.
@@ -112,7 +107,6 @@ struct spi_slave {unsigned int cs;#endif uint mode; -u8 mode_rx;unsigned int wordlen;unsigned int max_write_size;void *memory_map;
Signature · 1 line
1.9.1
PATCH v5 17/32 spi: Drop SPI_RX_FAST
In reply to Jagan TekiSPI_RX_FAST at spi layer used for spi-nor core to find the fastest read mode, but this handling is taking care at m25p80 hence removed the same at spi layer level.
--- include/spi.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
include/spi.h +2 -3
@@ -27,9 +27,8 @@#define SPI_TX_DUAL BIT(9)/* transmit with 2 wires */ #define SPI_TX_QUAD BIT(10)/* transmit with 4 wires */ #define SPI_RX_SLOW BIT(11)/* receive with 1 wire slow */ -#define SPI_RX_FAST BIT(12)/* receive with 1 wire fast */ -#define SPI_RX_DUAL BIT(13)/* receive with 2 wires */ -#define SPI_RX_QUAD BIT(14)/* receive with 4 wires */ +#define SPI_RX_DUAL BIT(12)/* receive with 2 wires */ +#define SPI_RX_QUAD BIT(13)/* receive with 4 wires */ /* SPI bus connection options - see enum spi_dual_flash */ #define SPI_CONN_DUAL_SHARED (1 << 0)
Signature · 1 line
1.9.1
PATCH v5 18/32 mtd: spi-nor: Rename SPI_FLASH_BAR to SPI_NOR_BAR
In reply to Jagan TekiRenamed SPI_FLASH_BAR to SPI_NOR_BAR
--- drivers/mtd/spi-nor/spi-nor.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/mtd/spi-nor/spi-nor.c +7 -7
@@ -181,7 +181,7 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor, unsigned long timeout)return -ETIMEDOUT ; } -#ifdef CONFIG_SPI_FLASH_BAR +#ifdef CONFIG_SPI_NOR_BAR static int spi_nor_write_bar (struct spi_nor *nor,u32 offset) {u8 bank_sel;
@@ -514,7 +514,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)if (nor->dual >SNOR_DUAL_SINGLE )spi_nor_dual (nor, &erase_addr);#endif -#ifdef CONFIG_SPI_FLASH_BAR +#ifdef CONFIG_SPI_NOR_BAR ret =spi_nor_write_bar (nor, erase_addr);if (ret <0 )return ret;
@@ -577,7 +577,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t offset, size_t len,if (nor->dual >SNOR_DUAL_SINGLE )spi_nor_dual (nor, &write_addr);#endif -#ifdef CONFIG_SPI_FLASH_BAR +#ifdef CONFIG_SPI_NOR_BAR ret =spi_nor_write_bar (nor, write_addr);if (ret <0 )return ret;
@@ -647,7 +647,7 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,if (nor->dual >SNOR_DUAL_SINGLE )spi_nor_dual (nor, &read_addr);#endif -#ifdef CONFIG_SPI_FLASH_BAR +#ifdef CONFIG_SPI_NOR_BAR ret =spi_nor_write_bar (nor, read_addr);if (ret <0 )return ret;
@@ -1103,7 +1103,7 @@ int spi_nor_scan(struct spi_nor *nor) }/* Configure the BAR - discover bank cmds and read current bank */ -#ifdef CONFIG_SPI_FLASH_BAR +#ifdef CONFIG_SPI_NOR_BAR ret =spi_nor_read_bar (nor, info);if (ret <0 )return ret;
@@ -1127,13 +1127,13 @@ int spi_nor_scan(struct spi_nor *nor)puts ("\n" );#endif -#ifndef CONFIG_SPI_FLASH_BAR +#ifndef CONFIG_SPI_NOR_BAR if (((nor->dual ==SNOR_DUAL_SINGLE ) && (mtd->size >SNOR_16MB_BOUN )) || ((nor->dual >SNOR_DUAL_SINGLE ) && (mtd->size >SNOR_16MB_BOUN <<1 ))) {puts ("spi-nor: Warning - Only lower 16MiB accessible," ); -puts (" Full access #define CONFIG_SPI_FLASH_BAR\n" ); +puts (" Full access #define CONFIG_SPI_NOR_BAR\n" ); }#endif
Signature · 1 line
1.9.1
PATCH v5 19/32 mtd: spi-nor: Add Kconfig entry for SPI_NOR_BAR
In reply to Jagan TekiAdded kconfig entry for SPI_NOR_BAR
--- drivers/mtd/spi-nor/Kconfig | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/mtd/spi-nor/Kconfig +7 -0
@@ -49,4 +49,11 @@ config MTD_SPI_NOR_USE_4K_SECTORS Please note that some tools/drivers/filesystems may not work with 4096 B erase size (e.g. UBIFS requires 15 KiB as a minimum). +config SPI_NOR_BAR + bool "SPI NOR Bank/Extended address register support" + help + Enable the SPI NOR Bank/Extended address register support. + Bank/Extended address registers are used to access the flash + which has size > 16MiB in 3-byte addressing. + endif # MTD_SPI_NOR
Signature · 1 line
1.9.1
PATCH v5 20/32 mtd: spi-nor: Copy spl files from drivers/mtd/spi
In reply to Jagan TekiCopy spl files from drivers/mtd/spi to spi-nor,
more changes will added on future patches.
--- drivers/mtd/spi-nor/Makefile | 5 +++ drivers/mtd/spi-nor/fsl_espi_spl.c | 90 ++++++++++++++++++++++++++++++++++++++ drivers/mtd/spi-nor/spi_spl_load.c | 90 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 185 insertions(+) create mode 100644 drivers/mtd/spi-nor/fsl_espi_spl.c create mode 100644 drivers/mtd/spi-nor/spi_spl_load.c
drivers/mtd/spi-nor/Makefile +5 -0
@@ -3,6 +3,11 @@ # # SPDX-License-Identifier: GPL-2.0+ +ifdef CONFIG_SPL_BUILD +obj-$(CONFIG_SPL_SPI_LOAD) += spi_spl_load.o +obj-$(CONFIG_SPL_SPI_BOOT) += fsl_espi_spl.o +endif + ifdef CONFIG_MTD_SPI_NOR obj-y += spi-nor.o obj-y += spi-nor-ids.o
drivers/mtd/spi-nor/fsl_espi_spl.c new file +90 -0
90 lines not on this page · raw message
drivers/mtd/spi-nor/spi_spl_load.c new file +90 -0
90 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v5 21/32 mtd: spi-nor: spl: Follow ascending order of include headers
In reply to Jagan TekiUse ascending order while including headers files.
--- drivers/mtd/spi-nor/fsl_espi_spl.c | 2 +- drivers/mtd/spi-nor/spi_spl_load.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/mtd/spi-nor/fsl_espi_spl.c +1 -1
@@ -5,8 +5,8 @@*/ #include <common.h> -#include <spi_flash.h> #include <malloc.h> +#include <spi_flash.h> #define ESPI_BOOT_IMAGE_SIZE 0x48#define ESPI_BOOT_IMAGE_ADDR 0x50
drivers/mtd/spi-nor/spi_spl_load.c +1 -1
@@ -10,9 +10,9 @@*/ #include <common.h> +#include <errno.h> #include <spi.h> #include <spi_flash.h> -#include <errno.h> #include <spl.h> #ifdef CONFIG_SPL_OS_BOOT
Signature · 1 line
1.9.1
PATCH v5 22/32 mtd: spi-nor: fsl_espi_spl: Use mtd_info
In reply to Jagan TekiReplace spi_flash{} with mtd_info{}
--- drivers/mtd/spi-nor/fsl_espi_spl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mtd/spi-nor/fsl_espi_spl.c +2 -2
@@ -14,7 +14,7 @@void spi_spl_load_image (uint32_t offs,unsigned int size,void *vdst) { -struct spi_flash *flash; +spi_flash_t *flash; flash =spi_flash_probe (CONFIG_ENV_SPI_BUS ,CONFIG_ENV_SPI_CS ,CONFIG_ENV_SPI_MAX_HZ ,CONFIG_ENV_SPI_MODE );
@@ -38,7 +38,7 @@ void spi_boot(void)#ifndef CONFIG_FSL_CORENET unsigned char *buf =NULL ;#endif -struct spi_flash *flash; +spi_flash_t *flash; flash =spi_flash_probe (CONFIG_ENV_SPI_BUS ,CONFIG_ENV_SPI_CS ,CONFIG_ENV_SPI_MAX_HZ ,CONFIG_ENV_SPI_MODE );
Signature · 1 line
1.9.1
PATCH v5 23/32 mtd: spi-nor: spi_spl_load: Use mtd_info
In reply to Jagan TekiReplace spi_flash{} with mtd_info{}
--- drivers/mtd/spi-nor/spi_spl_load.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/mtd/spi-nor/spi_spl_load.c +2 -3
@@ -20,8 +20,7 @@* Load the kernel, check for a valid header we can parse, and if found load * the kernel and then device tree. */ -static int spi_load_image_os (struct spi_flash *flash, -struct image_header *header) +static int spi_load_image_os (spi_flash_t *flash,struct image_header *header) {/* Read for a header, parse or error out. */ spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS, 0x40,
@@ -52,7 +51,7 @@ static int spi_load_image_os(struct spi_flash *flash,int spl_spi_load_image (void ) {int err =0 ; -struct spi_flash *flash; +spi_flash_t *flash;struct image_header *header;/*
Signature · 1 line
1.9.1
PATCH v5 24/32 mtd: spi-nor: Add flash vendor Kconfig entries
In reply to Jagan TekiAdded flash vendor kconfig entries from drivers/mtd/spi
--- drivers/mtd/spi-nor/Kconfig | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+)
drivers/mtd/spi-nor/Kconfig +40 -0
@@ -56,4 +56,44 @@ config SPI_NOR_BAR Bank/Extended address registers are used to access the flash which has size > 16MiB in 3-byte addressing. +config SPI_FLASH_ATMEL + bool "Atmel SPI flash support" + help + Add support for various Atmel SPI flash chips (AT45xxx and AT25xxx) + +config SPI_FLASH_EON + bool "EON SPI flash support" + help + Add support for various EON SPI flash chips (EN25xxx) + +config SPI_FLASH_GIGADEVICE + bool "GigaDevice SPI flash support" + help + Add support for various GigaDevice SPI flash chips (GD25xxx) + +config SPI_FLASH_MACRONIX + bool "Macronix SPI flash support" + help + Add support for various Macronix SPI flash chips (MX25Lxxx) + +config SPI_FLASH_SPANSION + bool "Spansion SPI flash support" + help + Add support for various Spansion SPI flash chips (S25FLxxx) + +config SPI_FLASH_STMICRO + bool "STMicro SPI flash support" + help + Add support for various STMicro SPI flash chips (M25Pxxx and N25Qxxx) + +config SPI_FLASH_SST + bool "SST SPI flash support" + help + Add support for various SST SPI flash chips (SST25xxx) + +config SPI_FLASH_WINBOND + bool "Winbond SPI flash support" + help + Add support for various Winbond SPI flash chips (W25xxx) + endif # MTD_SPI_NOR
Signature · 1 line
1.9.1
PATCH v5 25/32 arm: zynq: Kconfig: Select MTD uclass
In reply to Jagan TekiSince SPI-NOR core relies on MTD uclass.
--- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/arm/Kconfig +1 -0
@@ -565,6 +565,7 @@ config ARCH_ZYNQ select DM_MMC select DM_SPI select DM_SERIAL + select MTD select DM_SPI_FLASH select SPL_SEPARATE_BSS if SPL
Signature · 1 line
1.9.1
PATCH v5 26/32 arm: zynq: Kconfig: Drop DM_SPI_FLASH
In reply to Jagan TekiDrop using legacy DM_SPI_FLASH.
--- arch/arm/Kconfig | 1 - 1 file changed, 1 deletion(-)
arch/arm/Kconfig +0 -1
@@ -566,7 +566,6 @@ config ARCH_ZYNQ select DM_SPI select DM_SERIAL select MTD - select DM_SPI_FLASH select SPL_SEPARATE_BSS if SPL config ARCH_ZYNQMP
Signature · 1 line
1.9.1
PATCH v5 27/32 defconfigs: zynq_microzed: Drop CONFIG_SPI_FLASH
In reply to Jagan TekiDrop using legacy spi_flash core.
--- configs/zynq_microzed_defconfig | 1 - 1 file changed, 1 deletion(-)
configs/zynq_microzed_defconfig +0 -1
@@ -13,7 +13,6 @@ CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM_SEQ_ALIAS=y -CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_WINBOND=y
Signature · 1 line
1.9.1
PATCH v5 28/32 defconfig: zynq_microzed: Enable CONFIG_MTD_M25P80
In reply to Jagan TekiUse m25p80 which is flash interface layer between spi-nor core vs drivers/spi
--- configs/zynq_microzed_defconfig | 1 + 1 file changed, 1 insertion(+)
configs/zynq_microzed_defconfig +1 -0
@@ -18,3 +18,4 @@ CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_WINBOND=y CONFIG_ZYNQ_GEM=y CONFIG_ZYNQ_QSPI=y +CONFIG_MTD_M25P80=y
Signature · 1 line
1.9.1
PATCH v5 29/32 defconfig: zynq_microzed: Enable CONFIG_MTD_SPI_NOR
In reply to Jagan TekiEnabled SPI-NOR core support
--- configs/zynq_microzed_defconfig | 1 + 1 file changed, 1 insertion(+)
configs/zynq_microzed_defconfig +1 -0
@@ -19,3 +19,4 @@ CONFIG_SPI_FLASH_WINBOND=y CONFIG_ZYNQ_GEM=y CONFIG_ZYNQ_QSPI=y CONFIG_MTD_M25P80=y +CONFIG_MTD_SPI_NOR=y
Signature · 1 line
1.9.1
PATCH v5 30/32 spl: Add CONFIG_SPL_SPI_NOR_SUPPORT
In reply to Jagan TekiAdd SPL support for SPI-NOR flash.
--- drivers/Makefile | 1 + 1 file changed, 1 insertion(+)
drivers/Makefile +1 -0
@@ -18,6 +18,7 @@ obj-$(CONFIG_ARMADA_38X) += ddr/marvell/a38x/ obj-$(CONFIG_ARMADA_XP) += ddr/marvell/axp/ obj-$(CONFIG_ALTERA_SDRAM) += ddr/altera/ obj-$(CONFIG_SPL_SERIAL_SUPPORT) += serial/ +obj-$(CONFIG_SPL_SPI_NOR_SUPPORT) += mtd/spi-nor/ obj-$(CONFIG_SPL_SPI_FLASH_SUPPORT) += mtd/spi/ obj-$(CONFIG_SPL_SPI_SUPPORT) += spi/ obj-$(CONFIG_SPL_POWER_SUPPORT) += power/ power/pmic/
Signature · 1 line
1.9.1
PATCH v5 31/32 configs: zynq: Use CONFIG_SPL_SPI_NOR_SUPPORT
In reply to Jagan TekiUse SPI-NOR SPL support for zynq boards.
--- include/configs/zynq-common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/configs/zynq-common.h +1 -1
@@ -346,7 +346,7 @@#ifdef CONFIG_ZYNQ_QSPI #define CONFIG_SPL_SPI_SUPPORT #define CONFIG_SPL_SPI_LOAD -#define CONFIG_SPL_SPI_FLASH_SUPPORT +#define CONFIG_SPL_SPI_NOR_SUPPORT #define CONFIG_SYS_SPI_U_BOOT_OFFS 0x100000#define CONFIG_SYS_SPI_ARGS_OFFS 0x200000#define CONFIG_SYS_SPI_ARGS_SIZE 0x80000
Signature · 1 line
1.9.1
PATCH v5 32/32 configs: zynq: Use CONFIG_SPL_MTD_SUPPORT
In reply to Jagan TekiSince SPI-NOR depends on MTD core enable the same for SPI-NOR SPL.
--- include/configs/zynq-common.h | 1 + 1 file changed, 1 insertion(+)
include/configs/zynq-common.h +1 -0
@@ -347,6 +347,7 @@#define CONFIG_SPL_SPI_SUPPORT #define CONFIG_SPL_SPI_LOAD #define CONFIG_SPL_SPI_NOR_SUPPORT +#define CONFIG_SPL_MTD_SUPPORT #define CONFIG_SYS_SPI_U_BOOT_OFFS 0x100000#define CONFIG_SYS_SPI_ARGS_OFFS 0x200000#define CONFIG_SYS_SPI_ARGS_SIZE 0x80000
Signature · 1 line
1.9.1