dm: Generic MTD Subsystem/SPI-NOR
Subsystems (6)
v9 cover dm: Generic MTD Subsystem/SPI-NOR
The previous series [1] [2] are added SPI-NOR on top of mtd/spi where it bypassing DM_SPI_FLASH and use the existing mtd core (which is non-dm), I feel this is moving in a reverse direction where adding new feature with the help of non-dm mtd core support and also few of the spi drivers are not fully dm-driven.
Previous design series[3]: keep the mtd/spi as it is and start adding spi-nor features separately. The idea here is to add the dm features to MTD first and then add UCLASS_MTD spi-nor drivers so-that the commands are interfacing to spi-nor through dm-driven MTD core to spi-nor.
This series adding a new command 'mtd.c' which is common for all MTD devices SPI-NOR, SPI-NOR(master) and Parallel NOR with dm-driven.
SPI-NOR and Parallel NOR:
------------------------
------------------------------------
mtd.c
------------------------------------
mtd-uclass
------------------------------------
SPI-NOR Core CFI FLASH
------------------------------------m25p80.c zynq_qspi
-----------------------------------
spi-uclass SPI NOR chip
-----------------------------------
spi drivers
-----------------------------------
SPI NOR chip
-----------------------------------
drivers/mtd/spi-nor/
- Add dm mtd operations
- spi-nor.c: Add basic SPI-NOR core like erase/read/write ops and lock's will add later
- m25p80.c: spi-nor to spi divers interface layer drivers/spi-nor
- zynq_qspi.c: zynq qspi spi-nor controller driver.
Current Status:
--------------
- SPI-NOR Controller design flow working, see Log
TODO:
----
- SPI-NOR with SPI bus
- Parallel NOR.
Log:
----
Zynq> mtd
mtd - MTD Sub-system
Usage:
mtd list - show list of MTD devices mtd info - show current MTD device info mtd probe devnum - probe the 'devnum' MTD device mtd erase offset len - erase 'len' bytes from 'offset' mtd write addr to len - write 'len' bytes to 'to' from 'addr' mtd read addr from len - read 'len' bytes from 'from' to 'addr'
Zynq> mtd list
MTD 1: spi-nor at e000d000
Zynq>
MTD 1: spi-nor at e000d000
Zynq> mtd list
MTD 1: spi-nor at e000d000
Zynq> mtd probe 0
failing to set MTD device 0
Zynq> mtd probe 1
SPI-NOR: detected s25fl128s_64k with page size 256 Bytes, erase size 64 KiB, total 16 MiB Zynq> mtd info
MTD Device 1: s25fl128s_64k
Page size: 256 B Erase size: 64 KiB Size: 16 MiB
Zynq> mtd list
MTD 1: spi-nor at e000d000 (active 1)
Zynq> mtd erase 0xE00000 0x100000
MTD: 1048576 bytes @ 0xe00000 Erased: OK
Zynq> mw.b 0x100 0xaa 0x100000
Zynq> mtd write 0x100 0xE00000 0x100000
device 0 offset 0xe00000, size 0x100000
MTD: 1048576 bytes @ 0xe00000 Written: OK
Zynq> mtd read 0x3000000 0xE00000 0x100000
device 0 offset 0xe00000, size 0x100000
MTD: 1048576 bytes @ 0xe00000 Read: OK
Zynq> cmp.b 0x3000000 0x100 0x100000
Total of 1048576 byte(s) were the same
Testing:
-------
$ git clone git://git.denx.de/u-boot-spi.git $ cd u-boot-spi $ git checkout -b mtd origin/mtd-working
[1] http://lists.denx.de/pipermail/u-boot/2016-March/249286.html
[2] http://lists.denx.de/pipermail/u-boot/2016-February/245418.html
[3] [PATCH RFC v8 00/16] SPI-NOR/MTD addition
Jagan Teki (21):
dm: mtd: Add dm mtd core ops
mtd: Add SPI-NOR core support
mtd: spi-nor: Kconfig: Add MTD_SPI_NOR entry
mtd: spi-nor: Kconfig: Add MTD_SPI_NOR_USE_4K_SECTORS
mtd: spi-nor: Kconfig: Add SPI_NOR_MISC entry
mtd: spi-nor: Kconfig: Add SPI_NOR_MACRONIX entry
mtd: spi-nor: Kconfig: Add SPI_NOR_SPANSION entry
mtd: spi-nor: Kconfig: Add SPI_NOR_STMICRO entry
mtd: spi-nor: Kconfig: Add SPI_NOR_SST entry
mtd: spi-nor: Kconfig: Add SPI_NOR_WINBOND entry
spi: Add spi_write_then_read
mtd: spi-nor: Add m25p80 driver
mtd: spi-nor: Kconfig: Add MTD_M25P80 entry
mtd: spi-nor: Add zynq qspinor driver
mtd: spi-nor: zynq_qspi: Kconfig: Add MTD_ZYNQ
mtd: spi-nor: Add 4-byte addresswidth support
dm: mtd: Add uclass_driver.flags
dm: mtd: Add post_bind
cmd: Add mtd command support
arm: dts: zynq: Add zynq-qspinor node
dm: zynq: microzed: Enable MTD/SPI-NOR
Makefile | 1 + arch/arm/dts/zynq-7000.dtsi | 12 + arch/arm/dts/zynq-microzed.dts | 6 + cmd/Kconfig | 6 + cmd/Makefile | 1 + cmd/mtd.c | 285 ++++++++++++++++ configs/zynq_microzed_defconfig | 14 +- drivers/mtd/Kconfig | 2 + drivers/mtd/Makefile | 2 +- drivers/mtd/mtd-uclass.c | 93 +++++ drivers/mtd/spi-nor/Kconfig | 89 +++++ drivers/mtd/spi-nor/Makefile | 15 + drivers/mtd/spi-nor/m25p80.c | 218 ++++++++++++ drivers/mtd/spi-nor/spi-nor-ids.c | 176 ++++++++++ drivers/mtd/spi-nor/spi-nor.c | 684 +++++++++++++++++++++++++++++++++++++ drivers/mtd/spi-nor/zynq_qspinor.c | 641 ++++++++++++++++++++++++++++++++++ drivers/spi/spi-uclass.c | 24 ++ include/linux/err.h | 5 + include/linux/mtd/spi-nor.h | 211 ++++++++++++ include/mtd.h | 63 ++++ include/spi.h | 20 ++ 21 files changed, 2562 insertions(+), 6 deletions(-) create mode 100644 cmd/mtd.c create mode 100644 drivers/mtd/spi-nor/Kconfig create mode 100644 drivers/mtd/spi-nor/Makefile 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.c create mode 100644 drivers/mtd/spi-nor/zynq_qspinor.c create mode 100644 include/linux/mtd/spi-nor.h
Signature · 1 line
2.7.4
PATCH v9 1/21 dm: mtd: Add dm mtd core ops
- Add generic dm_mtd operations
- Add mtd_read|erase|write_dm
- Add add_mtd_device_dm
The respetive MTD_UCLASS drivers must install the hooks to these dm_mtd_ops and other core ops are act as a interface b/w drivers vs command code.
--- drivers/mtd/mtd-uclass.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ include/mtd.h | 54 ++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+)
drivers/mtd/mtd-uclass.c +72 -0
@@ -1,4 +1,5 @@/* +* Copyright (C) 2016 Jagan Teki <[email protected]> * Copyright (C) 2015 Thomas Chou <[email protected]> * * SPDX-License-Identifier: GPL-2.0+
@@ -8,6 +9,77 @@#include <dm.h> #include <errno.h> #include <mtd.h> +#include <linux/log2.h> + +int dm_mtd_read (struct udevice *dev,loff_t from,size_t len,size_t *retlen, +u_char *buf) +{ +struct mtd_info *mtd =mtd_get_info (dev); + + *retlen =0 ; +if (from <0 || from > mtd->size || len > mtd->size - from) +return -EINVAL ; +if (!len) +return 0 ; + +return mtd_get_ops (dev)->_read (dev, from, len, retlen, buf); +} + +int dm_mtd_erase (struct udevice *dev,struct erase_info *instr) +{ +struct mtd_info *mtd =mtd_get_info (dev); + +if (instr->addr > mtd->size || instr->len > mtd->size - instr->addr) +return -EINVAL ; +if (!(mtd->flags &MTD_WRITEABLE )) +return -EROFS ; + instr->fail_addr =MTD_FAIL_ADDR_UNKNOWN ; +if (!instr->len) { + instr->state =MTD_ERASE_DONE ; +return 0 ; + } + +return mtd_get_ops (dev)->_erase (dev, instr); +} + +int dm_mtd_write (struct udevice *dev,loff_t to,size_t len,size_t *retlen, +const u_char *buf) +{ +struct mtd_info *mtd =mtd_get_info (dev); + + *retlen =0 ; +if (to <0 || to > mtd->size || len > mtd->size - to) +return -EINVAL ; +if (!mtd_get_ops (dev)->_write || !(mtd->flags &MTD_WRITEABLE )) +return -EROFS ; +if (!len) +return 0 ; + +return mtd_get_ops (dev)->_write (dev, to, len, retlen, buf); +} + +int dm_add_mtd_device (struct udevice *dev) +{ +struct mtd_info *mtd =mtd_get_info (dev); + +BUG_ON (mtd->writesize ==0 ); + mtd->usecount =0 ; + +if (is_power_of_2 (mtd->erasesize)) + mtd->erasesize_shift =ffs (mtd->erasesize) -1 ; +else + mtd->erasesize_shift =0 ; + +if (is_power_of_2 (mtd->writesize)) + mtd->writesize_shift =ffs (mtd->writesize) -1 ; +else + mtd->writesize_shift =0 ; + + mtd->erasesize_mask = (1 << mtd->erasesize_shift) -1 ; + mtd->writesize_mask = (1 << mtd->writesize_shift) -1 ; + +return 0 ; +}/* * Implement a MTD uclass which should include most flash drivers.
include/mtd.h +54 -0
58 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH v9 1/21 dm: mtd: Add dm mtd core ops
Hi Jagan,
Quoted 8 lines · Jagan Teki
- Add generic
dm_mtdoperations
- Add mtd_read|erase|write_dm
- Addadd_mtd_device_dmThe respetive
MTD_UCLASSdrivers must install the hooks to thesedm_mtd_opsand other core ops are act as a interface b/w drivers vs command code.
Quoted 5 lines
Signed-off-by Jagan Teki <[email protected]>--- drivers/mtd/mtd-uclass.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ include/mtd.h | 54 ++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+)
But please see changes below.
Quoted 94 lines
drivers/mtd/mtd-uclass.c +72
-0@@ -1,4 +1,5 @@/* +* Copyright (C) 2016 Jagan Teki <[email protected]> * Copyright (C) 2015 Thomas Chou <[email protected]> * * SPDX-License-Identifier: GPL-2.0+ @@ -8,6 +9,77 @@#include <dm.h> #include <errno.h> #include <mtd.h> +#include <linux/log2.h> + +int dm_mtd_read (struct udevice *dev,loff_t from,size_t len,size_t *retlen, +u_char *buf) +{ +struct mtd_info *mtd =mtd_get_info (dev); + + *retlen =0 ; +if (from <0 || from > mtd->size || len > mtd->size - from) +return -EINVAL ; +if (!len) +return 0 ; + +return mtd_get_ops (dev)->_read (dev, from, len, retlen, buf); +} + +int dm_mtd_erase (struct udevice *dev,struct erase_info *instr) +{ +struct mtd_info *mtd =mtd_get_info (dev); + +if (instr->addr > mtd->size || instr->len > mtd->size - instr->addr) +return -EINVAL ; +if (!(mtd->flags &MTD_WRITEABLE )) +return -EROFS ; + instr->fail_addr =MTD_FAIL_ADDR_UNKNOWN ; +if (!instr->len) { + instr->state =MTD_ERASE_DONE ; +return 0 ; + } + +return mtd_get_ops (dev)->_erase (dev, instr); +} + +int dm_mtd_write (struct udevice *dev,loff_t to,size_t len,size_t *retlen, +const u_char *buf) +{ +struct mtd_info *mtd =mtd_get_info (dev); + + *retlen =0 ; +if (to <0 || to > mtd->size || len > mtd->size - to) +return -EINVAL ; +if (!mtd_get_ops (dev)->_write || !(mtd->flags &MTD_WRITEABLE )) +return -EROFS ; +if (!len) +return 0 ; + +return mtd_get_ops (dev)->_write (dev, to, len, retlen, buf); +} + +int dm_add_mtd_device (struct udevice *dev) +{ +struct mtd_info *mtd =mtd_get_info (dev); + +BUG_ON (mtd->writesize ==0 ); + mtd->usecount =0 ; + +if (is_power_of_2 (mtd->erasesize)) + mtd->erasesize_shift =ffs (mtd->erasesize) -1 ; +else + mtd->erasesize_shift =0 ; + +if (is_power_of_2 (mtd->writesize)) + mtd->writesize_shift =ffs (mtd->writesize) -1 ; +else + mtd->writesize_shift =0 ; + + mtd->erasesize_mask = (1 << mtd->erasesize_shift) -1 ; + mtd->writesize_mask = (1 << mtd->writesize_shift) -1 ; + +return 0 ; +}/* * Implement a MTD uclass which should include most flash drivers. include/mtd.h +0
-0
include/mtd.h static inline struct mtd_info *mtd_get_info(struct udevice *dev) · line 28
Quoted 9 lines
include/mtd.h +6
-0@@ -20,4 +20,58 @@ static inline struct mtd_info *mtd_get_info(struct udevice *dev)return dev_get_uclass_priv (dev); } +struct dm_mtd_ops { +int (*_erase)(struct udevice *dev,struct erase_info *instr); +int (*_read)(struct udevice *dev,loff_t from,size_t len, +size_t *retlen,u_char *buf); +int (*_write)(struct udevice *dev,loff_t to,size_t len, +size_t *retlen,const u_char *buf);
Please add detailed comments to the struct and each method. Also can you drop the underscore?
Quoted 50 lines
include/mtd.h +48
-1+}; + +/* Access the serial operations for a device */ +#define mtd_get_ops (dev) ((struct dm_mtd_ops *)(dev)->driver->ops) + +/** +* dm_mtd_read() - Read data from MTD device +* +* @dev: MTD device +* @from: Offset into device in bytes to read from +* @len: Length of bytes to read +* @retlen: Length of return bytes read to +* @buf: Buffer to put the data that is read +* @return 0 if OK, -ve on error +*/ +int dm_mtd_read (struct udevice *dev,loff_t from,size_t len,size_t *retlen, +u_char *buf); + +/** +* dm_mtd_write() - Write data to MTD device +* +* @dev: MTD device +* @to: Offset into device in bytes to write to +* @len: Length of bytes to write +* @retlen: Length of return bytes to write to +* @buf: Buffer containing bytes to write +* @return 0 if OK, -ve on error +*/ +int dm_mtd_write (struct udevice *dev,loff_t to,size_t len,size_t *retlen, +const u_char *buf); + +/** +* dm_mtd_erase() - Erase blocks of the MTD device +* +* @dev: MTD device +* @instr: Erase info details of MTD device +* @return 0 if OK, -ve on error +*/ +int dm_mtd_erase (struct udevice *dev,struct erase_info *instr); + +/** +* dm_add_mtd_device() - Add MTD device +* +* @dev: MTD device +* @return 0 if OK, -ve on error +*/ +int dm_add_mtd_device (struct udevice *dev); +#endif /* _MTD_H_ */ --
Quoted 2 lines
2.7.4
Regards,
Simon
PATCH v9 2/21 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.
------------------------------
cmd_sf.c
------------------------------
mtd-uclass
-------------------------------
SPI-NOR Core
-------------------------------m25p80.c zynq_qspi
-------------------------------
spi-uclass SPI NOR chip
-------------------------------
spi drivers
-------------------------------
SPI NOR chip
-------------------------------
--- Makefile | 1 + drivers/mtd/spi-nor/Makefile | 9 + drivers/mtd/spi-nor/spi-nor-ids.c | 176 +++++++++++ drivers/mtd/spi-nor/spi-nor.c | 648 ++++++++++++++++++++++++++++++++++++++ include/linux/err.h | 5 + include/linux/mtd/spi-nor.h | 207 ++++++++++++ 6 files changed, 1046 insertions(+) create mode 100644 drivers/mtd/spi-nor/Makefile 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
Makefile +1 -0
@@ -642,6 +642,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 +9 -0
@@ -0,0 +1,9 @@ +# +# Copyright (C) 2016 Jagan Teki <[email protected]> +# +# SPDX-License-Identifier: GPL-2.0+ + +## spi-nor core +ifdef CONFIG_MTD_SPI_NOR +obj-y += spi-nor.o spi-nor-ids.o +endif
drivers/mtd/spi-nor/spi-nor-ids.c new file +176 -0
176 lines not on this page · raw message
drivers/mtd/spi-nor/spi-nor.c new file +648 -0
648 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 +207 -0
207 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH v9 2/21 mtd: Add SPI-NOR core support
Hi Jagan,
Quoted 44 lines · Jagan Teki
Some of the SPI device drivers at
drivers/spinot 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.cThe problem with these were resides at
drivers/spiis 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.------------------------------
cmd_sf.c
------------------------------
mtd-uclass
-------------------------------
SPI-NOR Core
-------------------------------m25p80.czynq_qspi
-------------------------------
spi-uclass SPI NOR chip
-------------------------------
spi drivers
-------------------------------
SPI NOR chip
-------------------------------Signed-off-by Jagan Teki <[email protected]>--- Makefile | 1 + drivers/mtd/spi-nor/Makefile | 9 + drivers/mtd/spi-nor/spi-nor-ids.c | 176 +++++++++++ drivers/mtd/spi-nor/spi-nor.c | 648 ++++++++++++++++++++++++++++++++++++++ include/linux/err.h | 5 + include/linux/mtd/spi-nor.h | 207 ++++++++++++ 6 files changed, 1046 insertions(+) create mode 100644 drivers/mtd/spi-nor/Makefile 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
[...]
Quoted 184 lines
include/linux/mtd/spi-nor.h new file +178
-0@@ -0,0 +1,207 @@ +/* +* SPI NOR Core header file. +* +* Copyright (C) 2016 Jagan Teki <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __MTD_SPI_NOR_H +#define __MTD_SPI_NOR_H + +#include <common.h> + +/* + * Manufacturer IDs + * + * The first byte returned from the flash after sending opcode SPINOR_OP_RDID. + * Sometimes these are the same as CFI IDs, but sometimes they aren't. + */ +#define SNOR_MFR_ATMEL 0x1f +#define SNOR_MFR_MACRONIX 0xc2 +#define SNOR_MFR_MICRON 0x20 /* ST Micro <--> Micron */ +#define SNOR_MFR_SPANSION 0x01 +#define SNOR_MFR_SST 0xbf +#define SNOR_MFR_WINBOND 0xef + +/** + * SPI NOR opcodes. + * + * Note on opcode nomenclature: some opcodes have a format like + * SNOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number + * of I/O lines used for the opcode, address, and data (respectively). The + * FUNCTION has an optional suffix of '4', to represent an opcode which + * requires a 4-byte (32-bit) address. + */ +#define SNOR_OP_WRDI 0x04 /* Write disable */ +#define SNOR_OP_WREN 0x06 /* Write enable */ +#define SNOR_OP_RDSR 0x05 /* Read status register */ +#define SNOR_OP_WRSR 0x01 /* Write status register 1 byte */ +#define SNOR_OP_READ 0x03 /* Read data bytes (low frequency) */ +#define SNOR_OP_READ_FAST 0x0b /* Read data bytes (high frequency) */ +#define SNOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual SPI) */ +#define SNOR_OP_READ_1_1_2_IO 0xbb /* Read data bytes (Dual IO SPI) */ +#define SNOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad SPI) */ +#define SNOR_OP_READ_1_1_4_IO 0xeb /* Read data bytes (Quad IO SPI) */ +#define SNOR_OP_BRWR 0x17 /* Bank register write */ +#define SNOR_OP_BRRD 0x16 /* Bank register read */ +#define SNOR_OP_WREAR 0xC5 /* Write extended address register */ +#define SNOR_OP_RDEAR 0xC8 /* Read extended address register */ +#define SNOR_OP_PP 0x02 /* Page program (up to 256 bytes) */ +#define SNOR_OP_QPP 0x32 /* Quad Page program */ +#define SNOR_OP_BE_4K 0x20 /* Erase 4KiB block */ +#define SNOR_OP_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */ +#define SNOR_OP_BE_32K 0x52 /* Erase 32KiB block */ +#define SPINOR_OP_CHIP_ERASE 0xc7 /* Erase whole flash chip */ +#define SNOR_OP_SE 0xd8 /* Sector erase (usually 64KiB) */ +#define SNOR_OP_RDID 0x9f /* Read JEDEC ID */ +#define SNOR_OP_RDCR 0x35 /* Read configuration register */ +#define SNOR_OP_RDFSR 0x70 /* Read flag status register */ + +/* Used for SST flashes only. */ +#define SNOR_OP_BP 0x02 /* Byte program */ +#define SNOR_OP_AAI_WP 0xad /* Auto addr increment word program */ + +/* Status Register bits. */ +#define SR_WIP BIT(0) /* Write in progress */ +#define SR_WEL BIT(1) /* Write enable latch */ + +/* meaning of other SR_* bits may differ between vendors */ +#define SR_BP0 BIT(2) /* Block protect 0 */ +#define SR_BP1 BIT(3) /* Block protect 1 */ +#define SR_BP2 BIT(4) /* Block protect 2 */ +#define SR_SRWD BIT(7) /* SR write protect */ + +#define SR_QUAD_EN_MX BIT(6) /* Macronix Quad I/O */ + +/* Flag Status Register bits */ +#define FSR_READY BIT(7) + +/* Configuration Register bits. */ +#define CR_QUAD_EN_SPAN BIT(1) /* Spansion/Winbond Quad I/O */ + +/* Flash timeout values */ +#define SNOR_READY_WAIT_PROG (2 * CONFIG_SYS_HZ) +#define SNOR_READY_WAIT_ERASE (5 * CONFIG_SYS_HZ) +#define SNOR_MAX_CMD_SIZE 4 +#define SNOR_16MB_BOUN 0x1000000 + +enum snor_option_flags { + SNOR_F_SST_WRITE = BIT(0), + SNOR_F_USE_FSR = BIT(1), + SNOR_F_U_PAGE = BIT(1), +}; + +enum mode { + SNOR_READ = BIT(0), + SNOR_READ_1_1_2 = BIT(1), + SNOR_READ_1_1_4 = BIT(2), + SNOR_READ_1_1_2_IO = BIT(3), + SNOR_READ_1_1_4_IO = BIT(4), + SNOR_WRITE_1_1_BYTE = BIT(5), + SNOR_WRITE_1_1_4 = BIT(6), +}; + +#define JEDEC_MFR(info) ((info)->id[0]) +#define JEDEC_ID(info) (((info)->id[1]) << 8 | ((info)->id[2])) +#define JEDEC_EXT(info) (((info)->id[3]) << 8 | ((info)->id[4])) +#define SPI_NOR_MAX_ID_LEN 6 + +struct spi_nor_info { + char *name; + + /* + * This array stores the ID bytes. + * The first three bytes are the JEDIC ID. + * JEDEC ID zero means "no ID" (mostly older chips). + */ + u8 id[SPI_NOR_MAX_ID_LEN]; + u8 id_len; + + /* The size listed here is what works with SNOR_OP_SE, which isn't + * necessarily called a "sector" by the vendor. + */ + unsigned sector_size; + u16 n_sectors; + + u16 page_size; + + u16 flags; +#define SECT_4K BIT(0) +#define E_FSR BIT(1) +#define SST_WR BIT(2) +#define WR_QPP BIT(3) +#define RD_QUAD BIT(4) +#define RD_DUAL BIT(5) +#define RD_QUADIO BIT(6) +#define RD_DUALIO BIT(7) +#define RD_FULL (RD_QUAD | RD_DUAL | RD_QUADIO | RD_DUALIO) +}; + +extern const struct spi_nor_info spi_nor_ids[]; + +/** + * struct spi_nor - Structure for defining a the SPI NOR layer + * + * @dev: SPI NOR device + * @name: name of the SPI NOR device + * @page_size: the page size of the SPI NOR + * @addr_width: number of address bytes + * @erase_opcode: the opcode for erasing a sector + * @read_opcode: the read opcode + * @read_dummy: the dummy bytes needed by the read operation + * @program_opcode: the program opcode + * @max_write_size: If non-zero, the maximum number of bytes which can + * be written at once, excluding command bytes. + * @flags: flag options for the current SPI-NOR (SNOR_F_*) + * @mode: read, write mode or any other mode bits. + * @read_mode: read mode. + * @cmd_buf: used by the write_reg + * @read_reg: [DRIVER-SPECIFIC] read out the register + * @write_reg: [DRIVER-SPECIFIC] write data to the register + * @read: [DRIVER-SPECIFIC] read data from the SPI NOR + * @write: [DRIVER-SPECIFIC] write data to the SPI NOR + * @memory_map: address of read-only SPI NOR access + * @priv: the private data + */ +struct spi_nor { + struct udevice *dev; + const char *name; + u32 page_size; + u8 addr_width; + u8 erase_opcode; + u8 read_opcode; + u8 read_dummy; + u8 program_opcode; + u32 max_write_size; + u32 flags; + u8 mode;
include/linux/mtd/spi-nor.h line 188
Quoted 10 lines
include/linux/mtd/spi-nor.h new file +10
-0+u8 read_mode; +u8 cmd_buf[SNOR_MAX_CMD_SIZE ]; + +int (*read_reg)(struct spi_nor *nor,u8 cmd,u8 *val,int len); +int (*write_reg)(struct spi_nor *nor,u8 cmd,u8 *data,int len); + +int (*read)(struct spi_nor *nor,loff_t from,size_t len, +u_char *read_buf); +int (*write)(struct spi_nor *nor,loff_t to,size_t len, +const u_char *write_buf);
Sos is SPI_NOR a uclass? It seems like you have different drivers for it, and so it should be. Perhaps the SPI_NOR uclass should be a child of the MTD uclass?
Quoted 20 lines
include/linux/mtd/spi-nor.h new file +19
-1+ +void *memory_map; + void *priv; +}; + +/** +* spi_nor_scan() - scan the SPI NOR +* +* @dev: SPI NOR device +* +* The drivers can use this fuction to scan the SPI NOR. +* In the scanning, it will try to get all the necessary information to +* fill the mtd_info{} and the spi_nor{}. +* +* @return 0 if OK, -ve on error +*/ +int spi_nor_scan (struct udevice *dev); + +#endif /* __MTD_SPI_NOR_H */ --
Quoted 2 lines
2.7.4
Regards,
Simon
PATCH v9 3/21 mtd: spi-nor: Kconfig: Add MTD_SPI_NOR entry
In reply to Jagan TekiAdded CONFIG_MTD_SPI_NOR kconfig entry
--- drivers/mtd/Kconfig | 2 ++ drivers/mtd/spi-nor/Kconfig | 14 ++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 drivers/mtd/spi-nor/Kconfig
drivers/mtd/Kconfig +2 -0
@@ -41,4 +41,6 @@ source "drivers/mtd/nand/Kconfig" source "drivers/mtd/spi/Kconfig" +source "drivers/mtd/spi-nor/Kconfig" + source "drivers/mtd/ubi/Kconfig"
drivers/mtd/spi-nor/Kconfig new file +14 -0
@@ -0,0 +1,14 @@ +menuconfig MTD_SPI_NOR + tristate "SPI-NOR device support" + depends on MTD + 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.
Signature · 1 line
2.7.4
PATCH v9 3/21 mtd: spi-nor: Kconfig: Add MTD_SPI_NOR entry
Quoted 8 lines · Jagan Teki
Added
CONFIG_MTD_SPI_NORkconfig entrySigned-off-by Jagan Teki <[email protected]>--- drivers/mtd/Kconfig | 2 ++ drivers/mtd/spi-nor/Kconfig | 14 ++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 drivers/mtd/spi-nor/Kconfig
PATCH v9 4/21 mtd: spi-nor: Kconfig: Add MTD_SPI_NOR_USE_4K_SECTORS
In reply to Jagan TekiAdded CONFIG_MTD_SPI_NOR_USE_4K_SECTORS kconfig entry
--- drivers/mtd/spi-nor/Kconfig | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
drivers/mtd/spi-nor/Kconfig +18 -0
@@ -12,3 +12,21 @@ menuconfig MTD_SPI_NOR 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_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
2.7.4
PATCH v9 4/21 mtd: spi-nor: Kconfig: Add MTD_SPI_NOR_USE_4K_SECTORS
Quoted 6 lines · Jagan Teki
Added
CONFIG_MTD_SPI_NOR_USE_4K_SECTORSkconfig entrySigned-off-by Jagan Teki <[email protected]>--- drivers/mtd/spi-nor/Kconfig | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
PATCH v9 5/21 mtd: spi-nor: Kconfig: Add SPI_NOR_MISC entry
In reply to Jagan TekiAdded CONFIG_SPI_NOR_MISC kconfig entry
--- drivers/mtd/spi-nor/Kconfig | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/mtd/spi-nor/Kconfig +6 -0
@@ -29,4 +29,10 @@ 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_MISC + bool "Miscellaneous SPI NOR flash's support" + help + Add SPI-NOR support for various flash chips like Atmel, EON, + GigaDevice, and ISSI. + endif # MTD_SPI_NOR
Signature · 1 line
2.7.4
PATCH v9 5/21 mtd: spi-nor: Kconfig: Add SPI_NOR_MISC entry
Quoted 6 lines · Jagan Teki
Added
CONFIG_SPI_NOR_MISCkconfig entrySigned-off-by Jagan Teki <[email protected]>--- drivers/mtd/spi-nor/Kconfig | 6 ++++++ 1 file changed, 6 insertions(+)
PATCH v9 6/21 mtd: spi-nor: Kconfig: Add SPI_NOR_MACRONIX entry
In reply to Jagan TekiAdded CONFIG_SPI_NOR_MACRONIX kconfig entry
--- drivers/mtd/spi-nor/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
drivers/mtd/spi-nor/Kconfig +5 -0
@@ -35,4 +35,9 @@ config SPI_NOR_MISC Add SPI-NOR support for various flash chips like Atmel, EON, GigaDevice, and ISSI. +config SPI_NOR_MACRONIX + bool "Macronix SPI NOR flash support" + help + Add support for various Macronix SPI flash chips (MX25Lxxx) + endif # MTD_SPI_NOR
Signature · 1 line
2.7.4
PATCH v9 6/21 mtd: spi-nor: Kconfig: Add SPI_NOR_MACRONIX entry
Quoted 6 lines · Jagan Teki
Added
CONFIG_SPI_NOR_MACRONIXkconfig entrySigned-off-by Jagan Teki <[email protected]>--- drivers/mtd/spi-nor/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
PATCH v9 7/21 mtd: spi-nor: Kconfig: Add SPI_NOR_SPANSION entry
In reply to Jagan TekiAdded CONFIG_SPI_NOR_SPANSION kconfig entry
--- drivers/mtd/spi-nor/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
drivers/mtd/spi-nor/Kconfig +5 -0
@@ -40,4 +40,9 @@ config SPI_NOR_MACRONIX help Add support for various Macronix SPI flash chips (MX25Lxxx) +config SPI_NOR_SPANSION + bool "Spansion SPI NOR flash support" + help + Add support for various Spansion SPI flash chips (S25FLxxx) + endif # MTD_SPI_NOR
Signature · 1 line
2.7.4
PATCH v9 7/21 mtd: spi-nor: Kconfig: Add SPI_NOR_SPANSION entry
Quoted 6 lines · Jagan Teki
Added
CONFIG_SPI_NOR_SPANSIONkconfig entrySigned-off-by Jagan Teki <[email protected]>--- drivers/mtd/spi-nor/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
PATCH v9 8/21 mtd: spi-nor: Kconfig: Add SPI_NOR_STMICRO entry
In reply to Jagan TekiAdded CONFIG_SPI_NOR_STMICRO kconfig entry
--- drivers/mtd/spi-nor/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
drivers/mtd/spi-nor/Kconfig +5 -0
@@ -45,4 +45,9 @@ config SPI_NOR_SPANSION help Add support for various Spansion SPI flash chips (S25FLxxx) +config SPI_NOR_STMICRO + bool "STMicro SPI NOR flash support" + help + Add support for various STMicro SPI flash chips (M25Pxxx and N25Qxxx) + endif # MTD_SPI_NOR
Signature · 1 line
2.7.4
PATCH v9 8/21 mtd: spi-nor: Kconfig: Add SPI_NOR_STMICRO entry
Quoted 6 lines · Jagan Teki
Added
CONFIG_SPI_NOR_STMICROkconfig entrySigned-off-by Jagan Teki <[email protected]>--- drivers/mtd/spi-nor/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
PATCH v9 9/21 mtd: spi-nor: Kconfig: Add SPI_NOR_SST entry
In reply to Jagan TekiAdded CONFIG_SPI_NOR_SST kconfig entry
--- drivers/mtd/spi-nor/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
drivers/mtd/spi-nor/Kconfig +5 -0
@@ -50,4 +50,9 @@ config SPI_NOR_STMICRO help Add support for various STMicro SPI flash chips (M25Pxxx and N25Qxxx) +config SPI_NOR_SST + bool "SST SPI NOR flash support" + help + Add support for various SST SPI flash chips (SST25xxx) + endif # MTD_SPI_NOR
Signature · 1 line
2.7.4
PATCH v9 9/21 mtd: spi-nor: Kconfig: Add SPI_NOR_SST entry
Quoted 6 lines · Jagan Teki
Added
CONFIG_SPI_NOR_SSTkconfig entrySigned-off-by Jagan Teki <[email protected]>--- drivers/mtd/spi-nor/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
PATCH v9 10/21 mtd: spi-nor: Kconfig: Add SPI_NOR_WINBOND entry
In reply to Jagan TekiAdded CONFIG_SPI_NOR_WINBOND kconfig entry
--- drivers/mtd/spi-nor/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
drivers/mtd/spi-nor/Kconfig +5 -0
@@ -55,4 +55,9 @@ config SPI_NOR_SST help Add support for various SST SPI flash chips (SST25xxx) +config SPI_NOR_WINBOND + bool "Winbond SPI NOR flash support" + help + Add support for various Winbond SPI flash chips (W25xxx) + endif # MTD_SPI_NOR
Signature · 1 line
2.7.4
PATCH v9 10/21 mtd: spi-nor: Kconfig: Add SPI_NOR_WINBOND entry
Quoted 6 lines · Jagan Teki
Added
CONFIG_SPI_NOR_WINBONDkconfig entrySigned-off-by Jagan Teki <[email protected]>--- drivers/mtd/spi-nor/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
PATCH v9 11/21 spi: Add spi_write_then_read
In reply to Jagan TekiAdd support for SPI synchronous write followed by read, this is common interface call from spi-nor to spi drivers.
--- drivers/spi/spi-uclass.c | 24 ++++++++++++++++++++++++ include/spi.h | 20 ++++++++++++++++++++ 2 files changed, 44 insertions(+)
drivers/spi/spi-uclass.c +24 -0
@@ -108,6 +108,30 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,return dm_spi_xfer (slave->dev, bitlen, dout, din, flags); } +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 (n_buf ==0 ) + flags |=SPI_XFER_END ; + + ret =spi_xfer (slave, n_opcode *8 , opcode,NULL , flags); +if (ret) { +debug ("spi: failed to send command (%zu bytes): %d\n" , + 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" , + n_buf, ret); + } + +return ret; +} +static int spi_child_post_bind (struct udevice *dev) {struct dm_spi_slave_platdata *plat =dev_get_parent_platdata (dev);
include/spi.h +20 -0
@@ -258,6 +258,26 @@ 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 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
2.7.4
PATCH v9 11/21 spi: Add spi_write_then_read
Quoted 8 lines · Jagan Teki
Add support for SPI synchronous write followed by read, this is common interface call from spi-nor to spi drivers.
Signed-off-by Jagan Teki <[email protected]>--- drivers/spi/spi-uclass.c | 24 ++++++++++++++++++++++++ include/spi.h | 20 ++++++++++++++++++++ 2 files changed, 44 insertions(+)
PATCH v9 12/21 mtd: spi-nor: Add m25p80 driver
In reply to Jagan TekiThis is MTD SPI-NOR driver for ST M25Pxx (and similar) serial flash chips which is written as MTD_UCLASS.
--- drivers/mtd/spi-nor/Makefile | 3 + drivers/mtd/spi-nor/m25p80.c | 217 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 220 insertions(+) create mode 100644 drivers/mtd/spi-nor/m25p80.c
drivers/mtd/spi-nor/Makefile +3 -0
@@ -7,3 +7,6 @@ ifdef CONFIG_MTD_SPI_NOR obj-y += spi-nor.o spi-nor-ids.o endif + +## spi-nor to spi interface driver +obj-$(CONFIG_MTD_M25P80) += m25p80.o
drivers/mtd/spi-nor/m25p80.c new file +217 -0
217 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH v9 12/21 mtd: spi-nor: Add m25p80 driver
Hi Jagan,
Quoted 26 lines · Jagan Teki
This is MTD SPI-NOR driver for ST M25Pxx (and similar) serial flash chips which is written as
MTD_UCLASS.Signed-off-by Jagan Teki <[email protected]>--- drivers/mtd/spi-nor/Makefile | 3 + drivers/mtd/spi-nor/m25p80.c | 217 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 220 insertions(+) create mode 100644 drivers/mtd/spi-nor/m25p80.cdrivers/mtd/spi-nor/Makefile +3
-0@@ -7,3 +7,6 @@ ifdef CONFIG_MTD_SPI_NOR obj-y += spi-nor.o spi-nor-ids.o endif + +## spi-nor to spi interface driver +obj-$(CONFIG_MTD_M25P80) += m25p80.odrivers/mtd/spi-nor/m25p80.c new file +0
-0
[...]
Quoted 5 lines
drivers/mtd/spi-nor/m25p80.c new file +5
-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. +*/
drivers/mtd/spi-nor/m25p80.c line 216
Quoted 10 lines
drivers/mtd/spi-nor/m25p80.c new file +10
-0+ { .compatible = "jedec,spi-nor" }, + { } +}; + +U_BOOT_DRIVER (m25p80) = { + .name ="m25p80" , + .id =UCLASS_MTD , + .of_match = m25p_ids, + .probe = m25p_probe, + .priv_auto_alloc_size =sizeof (struct m25p ),
Should this not have some MTD operations from the UCLASS_MTD? i.e. struct dm_mtd_ops?
Quoted 4 lines
+};
--
2.7.4
Regards,
Simon
PATCH v9 13/21 mtd: spi-nor: Kconfig: Add MTD_M25P80 entry
In reply to Jagan TekiAdd CONFIG_MTD_M25P80 kconfig entry
--- drivers/mtd/spi-nor/Kconfig | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
drivers/mtd/spi-nor/Kconfig +17 -0
@@ -15,6 +15,23 @@ menuconfig MTD_SPI_NOR if MTD_SPI_NOR +config MTD_M25P80 + tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)" + depends on DM_SPI + 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. + config MTD_SPI_NOR_USE_4K_SECTORS bool "Use small 4096 B erase sectors" default y
Signature · 1 line
2.7.4
PATCH v9 13/21 mtd: spi-nor: Kconfig: Add MTD_M25P80 entry
Quoted 6 lines · Jagan Teki
Add
CONFIG_MTD_M25P80kconfig entrySigned-off-by Jagan Teki <[email protected]>--- drivers/mtd/spi-nor/Kconfig | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
PATCH v9 14/21 mtd: spi-nor: Add zynq qspinor driver
In reply to Jagan TekiZynq qspinor controller is works similar way as generic spi controller with additional features that make this controller work more specific to flash chips as salve devices.
Why, zynq qspi written as spi-nor controller driver.
(1) dual flash:
This describes two/dual memories are connected with a single chip select line from a controller like dual stack and dual parallel connections see doc/SPI/README.dual-flash for more details.
Adding this support to spi-nor core looks quite managable and other generic code might effect and more over this is controller specific.
--- drivers/mtd/spi-nor/Makefile | 3 + drivers/mtd/spi-nor/zynq_qspinor.c | 641 +++++++++++++++++++++++++++++++++++++ 2 files changed, 644 insertions(+) create mode 100644 drivers/mtd/spi-nor/zynq_qspinor.c
drivers/mtd/spi-nor/Makefile +3 -0
@@ -10,3 +10,6 @@ endif ## spi-nor to spi interface driver obj-$(CONFIG_MTD_M25P80) += m25p80.o + +## spi-nor drivers +obj-$(CONFIG_MTD_ZYNQ_QSPI) += zynq_qspinor.o
drivers/mtd/spi-nor/zynq_qspinor.c new file +641 -0
641 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH v9 15/21 mtd: spi-nor: zynq_qspi: Kconfig: Add MTD_ZYNQ
In reply to Jagan TekiAdd CONFIG_MTD_ZYNQ_QSPI kconfig entry
--- drivers/mtd/spi-nor/Kconfig | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/mtd/spi-nor/Kconfig +9 -0
@@ -46,6 +46,15 @@ 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 MTD_ZYNQ_QSPI + bool "Zynq QSPI NOR controller driver" + depends on ARCH_ZYNQ + help + Enable the Zynq Quad-SPI (QSPI) driver. This driver can be + used to access the SPI NOR flash on platforms embedding this + Zynq QSPI IP core. This IP is used to connect the flash in + 4-bit qspi, 8-bit dual stacked and shared 4-bit dual parallel. + config SPI_NOR_MISC bool "Miscellaneous SPI NOR flash's support" help
Signature · 1 line
2.7.4
PATCH v9 16/21 mtd: spi-nor: Add 4-byte addresswidth support
In reply to Jagan TekiAdd 4-byte address supports, so-that SPI-NOR chips has > 16MiB should accessible.
--- drivers/mtd/spi-nor/m25p80.c | 1 + drivers/mtd/spi-nor/spi-nor.c | 36 ++++++++++++++++++++++++++++++++++++ include/linux/mtd/spi-nor.h | 6 +++++- 3 files changed, 42 insertions(+), 1 deletion(-)
drivers/mtd/spi-nor/m25p80.c +1 -0
@@ -31,6 +31,7 @@ static void m25p_addr2cmd(struct spi_nor *nor, unsigned int addr, u8 *cmd) cmd[1 ] = addr >> (nor->addr_width *8 -8 ); cmd[2 ] = addr >> (nor->addr_width *8 -16 ); cmd[3 ] = addr >> (nor->addr_width *8 -24 ); + cmd[4 ] = addr >> (nor->addr_width *8 -32 ); }static int m25p_cmdsz (struct spi_nor *nor)
drivers/mtd/spi-nor/spi-nor.c +36 -0
@@ -378,6 +378,36 @@ static int sst_write_bp(struct udevice *dev, loff_t to, size_t len, }#endif +/* Enable/disable 4-byte addressing mode. */ +static int set_4byte (struct spi_nor *nor,const struct spi_nor_info *info, +int enable) +{ +int status; +bool need_wren = false; +u8 cmd; + +switch (JEDEC_MFR (info)) { +case SNOR_MFR_MICRON : +/* Some Micron need WREN command; all will accept it */ + need_wren = true; +case SNOR_MFR_MACRONIX : +case SNOR_MFR_WINBOND : +if (need_wren) +write_enable (nor); + + cmd = enable ?SNOR_OP_EN4B :SNOR_OP_EX4B ; + status = nor->write_reg (nor, cmd,NULL ,0 ); +if (need_wren) +write_disable (nor); + +return status; +default : +/* Spansion style */ + nor->cmd_buf[0 ] = enable <<7 ; +return nor->write_reg (nor,SNOR_OP_BRWR , nor->cmd_buf,1 ); + } +} +#ifdef CONFIG_SPI_NOR_MACRONIX static int macronix_quad_enable (struct spi_nor *nor) {
@@ -613,6 +643,12 @@ int spi_nor_scan(struct udevice *dev) } nor->addr_width =3 ; +if (mtd->size >SNOR_16MB_BOUN ) { + nor->addr_width =4 ; + ret =set_4byte (nor, info, true); +if (ret) +return ret; + }/* Dummy cycles for read */ switch (nor->read_opcode) {
include/linux/mtd/spi-nor.h +5 -1
@@ -62,6 +62,10 @@#define SNOR_OP_BP 0x02/* Byte program */ #define SNOR_OP_AAI_WP 0xad/* Auto addr increment word program */ +/* Used for Macronix and Winbond flashes. */ +#define SNOR_OP_EN4B 0xb7/* Enter 4-byte mode */ +#define SNOR_OP_EX4B 0xe9/* Exit 4-byte mode */ +/* Status Register bits. */ #define SR_WIP BIT(0)/* Write in progress */ #define SR_WEL BIT(1)/* Write enable latch */
@@ -83,7 +87,7 @@/* Flash timeout values */ #define SNOR_READY_WAIT_PROG (2 * CONFIG_SYS_HZ)#define SNOR_READY_WAIT_ERASE (5 * CONFIG_SYS_HZ) -#define SNOR_MAX_CMD_SIZE 4 +#define SNOR_MAX_CMD_SIZE 6#define SNOR_16MB_BOUN 0x1000000enum snor_option_flags {
Signature · 1 line
2.7.4
PATCH v9 17/21 dm: mtd: Add uclass_driver.flags
In reply to Jagan TekiAdd flags for mtd-uclass driver.
--- drivers/mtd/mtd-uclass.c | 1 + 1 file changed, 1 insertion(+)
drivers/mtd/mtd-uclass.c +1 -0
@@ -89,5 +89,6 @@ int dm_add_mtd_device(struct udevice *dev)UCLASS_DRIVER (mtd) = { .id =UCLASS_MTD , .name ="mtd" , + .flags =DM_UC_FLAG_SEQ_ALIAS , .per_device_auto_alloc_size =sizeof (struct mtd_info ), };
Signature · 1 line
2.7.4
PATCH v9 17/21 dm: mtd: Add uclass_driver.flags
Quoted 6 lines · Jagan Teki
Add flags for mtd-uclass driver.
Signed-off-by Jagan Teki <[email protected]>--- drivers/mtd/mtd-uclass.c | 1 + 1 file changed, 1 insertion(+)
PATCH v9 18/21 dm: mtd: Add post_bind
In reply to Jagan TekiAdd .post_bind on mtd-uclass driver
--- drivers/mtd/mtd-uclass.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/mtd/mtd-uclass.c +3 -0
@@ -11,6 +11,8 @@#include <mtd.h> #include <linux/log2.h> +#include <dm/device-internal.h> +int dm_mtd_read (struct udevice *dev,loff_t from,size_t len,size_t *retlen,u_char *buf) {
@@ -90,5 +92,6 @@ UCLASS_DRIVER(mtd) = { .id = UCLASS_MTD, .name = "mtd", .flags = DM_UC_FLAG_SEQ_ALIAS, + .post_bind = dm_scan_fdt_dev, .per_device_auto_alloc_size = sizeof(struct mtd_info), };
Signature · 1 line
2.7.4
PATCH v9 18/21 dm: mtd: Add post_bind
Quoted 6 lines · Jagan Teki
Add .post_bind on mtd-uclass driver
Signed-off-by Jagan Teki <[email protected]>--- drivers/mtd/mtd-uclass.c | 3 +++ 1 file changed, 3 insertions(+)
PATCH v9 19/21 cmd: Add mtd command support
In reply to Jagan Tekicmd/mtd.c is a generic command to access all low level MTD devices, like SPI-NOR, Parallel NOR and NAND.
This is implemented based on u-boot driver model, so any new driver added for using this command must follow dm principles.
--- cmd/Kconfig | 6 + cmd/Makefile | 1 + cmd/mtd.c | 285 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/mtd/Makefile | 2 +- drivers/mtd/mtd-uclass.c | 17 +++ include/mtd.h | 9 ++ 6 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 cmd/mtd.c
cmd/Kconfig +6 -0
@@ -706,6 +706,12 @@ config CMD_FS_GENERIC fs types. endmenu +config CMD_MTD + bool "Generic command for accessing MTD devices" + help + Command to support MTD devices accessing. + MTD devices like SPI-NOR, Parallel NOR and NAND. + config CMD_UBI tristate "Enable UBI - Unsorted block images commands" select CRC32
cmd/Makefile +1 -0
@@ -95,6 +95,7 @@ obj-$(CONFIG_CMD_MISC) += misc.o obj-$(CONFIG_CMD_MMC) += mmc.o obj-$(CONFIG_CMD_MMC_SPI) += mmc_spi.o obj-$(CONFIG_MP) += mp.o +obj-$(CONFIG_CMD_MTD) += mtd.o obj-$(CONFIG_CMD_MTDPARTS) += mtdparts.o obj-$(CONFIG_CMD_NAND) += nand.o obj-$(CONFIG_CMD_NET) += net.o
cmd/mtd.c new file +285 -0
285 lines not on this page · raw message
drivers/mtd/Makefile +1 -1
@@ -8,7 +8,7 @@ ifneq (,$(findstring y,$(CONFIG_MTD_DEVICE)$(CONFIG_CMD_NAND)$(CONFIG_CMD_ONENAND)$(CONFIG_CMD_SF))) obj-y += mtdcore.o mtd_uboot.o endif -obj-$(CONFIG_MTD) += mtd-uclass.o +obj-$(CONFIG_MTD) += mtd-uclass.o mtd_uboot.o obj-$(CONFIG_MTD_PARTITIONS) += mtdpart.o obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o obj-$(CONFIG_ALTERA_QSPI) += altera_qspi.o
drivers/mtd/mtd-uclass.c +17 -0
@@ -83,6 +83,23 @@ int dm_add_mtd_device(struct udevice *dev)return 0 ; } +int dm_mtd_probe (struct udevice *dev,struct udevice **devp) +{ + *devp =NULL ; +int ret; + + ret =device_probe (dev); +debug ("%s: device_probe: ret=%d\n" , __func__, ret); +if (ret) + goto err; + + *devp = dev; +return 0 ; +err: +device_unbind (dev); +return ret; +} +/* * Implement a MTD uclass which should include most flash drivers. * The uclass private is pointed to mtd_info.
include/mtd.h +9 -0
@@ -74,4 +74,13 @@ int dm_mtd_erase(struct udevice *dev, struct erase_info *instr);*/ int dm_add_mtd_device (struct udevice *dev); +/** +* dm_mtd_probe() - Probe MTD device +* +* @dev: MTD device +* @devp: MTD device pointer +* @return 0 if OK, -ve on error +*/ +int dm_mtd_probe (struct udevice *dev,struct udevice **devp); +#endif /* _MTD_H_ */
Signature · 1 line
2.7.4
PATCH v9 19/21 cmd: Add mtd command support
Quoted 7 lines · Jagan Teki
cmd/mtd.cis a generic command to access all low level MTD devices, like SPI-NOR, Parallel NOR and NAND.This is implemented based on u-boot driver model, so any new driver added for using this command must follow dm principles.
Signed-off-by Jagan Teki <[email protected]>
Quoted 9 lines
--- cmd/Kconfig | 6 + cmd/Makefile | 1 + cmd/mtd.c | 285 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/mtd/Makefile | 2 +- drivers/mtd/mtd-uclass.c | 17 +++ include/mtd.h | 9 ++ 6 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 cmd/mtd.c
PATCH v9 20/21 arm: dts: zynq: Add zynq-qspinor node
In reply to Jagan Teki--- arch/arm/dts/zynq-7000.dtsi | 12 ++++++++++++ 1 file changed, 12 insertions(+)
arch/arm/dts/zynq-7000.dtsi +12 -0
@@ -206,6 +206,18 @@ #size-cells = <0>; }; + qspinor: spi-nor at e000d000 { + clock-names = "ref_clk", "pclk"; + clocks = <&clkc 10>, <&clkc 43>; + compatible = "xlnx,zynq-qspinor-1.0"; + status = "disabled"; + interrupt-parent = <&intc>; + interrupts = <0 19 4>; + reg = <0xe000d000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + }; + gem0: ethernet at e000b000 { compatible = "cdns,zynq-gem", "cdns,gem"; reg = <0xe000b000 0x1000>;
Signature · 1 line
2.7.4
PATCH v9 21/21 dm: zynq: microzed: Enable MTD/SPI-NOR
In reply to Jagan Teki- Enable MTD driver model
- Enable cmd/mtd.c
- Enable SPI-NOR
- Enable MTD_ZYNQ_QSPI
- Add mtd1 alias for qspinor node
- Disable SPI_FLASH
Log:
----
Zynq> mtd
mtd - MTD Sub-system
Usage:
mtd list - show list of MTD devices mtd info - show current MTD device info mtd probe devnum - probe the 'devnum' MTD device mtd erase offset len - erase 'len' bytes from 'offset' mtd write addr to len - write 'len' bytes to 'to' from 'addr' mtd read addr from len - read 'len' bytes from 'from' to 'addr'
Zynq> mtd list
MTD 1: spi-nor at e000d000
Zynq>
MTD 1: spi-nor at e000d000
Zynq> mtd list
MTD 1: spi-nor at e000d000
Zynq> mtd probe 0
failing to set MTD device 0
Zynq> mtd probe 1
SPI-NOR: detected s25fl128s_64k with page size 256 Bytes, erase size 64 KiB, total 16 MiB Zynq> mtd info
MTD Device 1: s25fl128s_64k
Page size: 256 B Erase size: 64 KiB Size: 16 MiB
Zynq> mtd list
MTD 1: spi-nor at e000d000 (active 1) Zynq> mtd erase 0xE00000 0x100000
MTD: 1048576 bytes @ 0xe00000 Erased: OK Zynq> mw.b 0x100 0xaa 0x100000 Zynq> mtd write 0x100 0xE00000 0x100000 device 0 offset 0xe00000, size 0x100000
MTD: 1048576 bytes @ 0xe00000 Written: OK Zynq> mtd read 0x3000000 0xE00000 0x100000 device 0 offset 0xe00000, size 0x100000
MTD: 1048576 bytes @ 0xe00000 Read: OK Zynq> cmp.b 0x3000000 0x100 0x100000 Total of 1048576 byte(s) were the same
--- arch/arm/dts/zynq-microzed.dts | 6 ++++++ configs/zynq_microzed_defconfig | 14 +++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-)
arch/arm/dts/zynq-microzed.dts +6 -0
@@ -15,6 +15,7 @@ aliases { serial0 = &uart1; spi0 = &qspi; + mtd1 = &qspinor; mmc0 = &sdhci0; };
@@ -43,6 +44,11 @@ status = "okay"; }; +&qspinor { + u-boot,dm-pre-reloc; + status = "okay"; +}; + &uart1 { u-boot,dm-pre-reloc; status = "okay";
configs/zynq_microzed_defconfig +9 -5
@@ -11,6 +11,7 @@ CONFIG_SYS_PROMPT="Zynq> " # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set CONFIG_CMD_MMC=y +CONFIG_CMD_MTD=y CONFIG_CMD_SF=y CONFIG_CMD_USB=y CONFIG_CMD_DFU=y
@@ -31,13 +32,16 @@ CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_DFU_MMC=y CONFIG_DFU_RAM=y CONFIG_ZYNQ_SDHCI=y -CONFIG_SPI_FLASH=y -CONFIG_SPI_FLASH_BAR=y -CONFIG_SPI_FLASH_SPANSION=y -CONFIG_SPI_FLASH_STMICRO=y -CONFIG_SPI_FLASH_WINBOND=y CONFIG_ZYNQ_GEM=y CONFIG_ZYNQ_QSPI=y +CONFIG_MTD=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_ZYNQ_QSPI=y +CONFIG_SPI_NOR_STMICRO=y +CONFIG_SPI_NOR_SPANSION=y +CONFIG_SPI_NOR_SST=y +CONFIG_SPI_NOR_WINBOND=y +CONFIG_SPI_NOR_MACRONIX=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_ULPI_VIEWPORT=y
Signature · 1 line
2.7.4
v9 cover dm: Generic MTD Subsystem/SPI-NOR
In reply to Jagan TekiHi Jagan,
Quoted 154 lines · Jagan Teki
The previous series [1] [2] are added SPI-NOR on top of mtd/spi where it bypassing
DM_SPI_FLASHand use the existing mtd core (which is non-dm), I feel this is moving in a reverse direction where adding new feature with the help of non-dm mtd core support and also few of the spi drivers are not fully dm-driven.Previous design series[3]: keep the mtd/spi as it is and start adding spi-nor features separately. The idea here is to add the dm features to MTD first and then add
UCLASS_MTDspi-nor drivers so-that the commands are interfacing to spi-nor through dm-driven MTD core to spi-nor.This series adding a new command '
mtd.c' which is common for all MTD devices SPI-NOR, SPI-NOR(master) and Parallel NOR with dm-driven.SPI-NOR and Parallel NOR:
------------------------------------------------------------
mtd.c
------------------------------------
mtd-uclass
------------------------------------
SPI-NOR Core CFI FLASH
------------------------------------m25p80.czynq_qspi
-----------------------------------
spi-uclass SPI NOR chip
-----------------------------------
spi drivers
-----------------------------------
SPI NOR chip
-----------------------------------
drivers/mtd/spi-nor/- Add dm mtd operations
-spi-nor.c: Add basic SPI-NOR core like erase/read/write ops and lock's will add later
-m25p80.c: spi-nor to spi divers interface layerdrivers/spi-nor
-zynq_qspi.c: zynq qspi spi-nor controller driver.Current Status:
--------------
- SPI-NOR Controller design flow working, see LogTODO:
----
- SPI-NOR with SPI bus
- Parallel NOR.Log:
----
Zynq> mtd
mtd - MTD Sub-systemUsage:
mtd list - show list of MTD devices mtd info - show current MTD device info mtd probe devnum - probe the 'devnum' MTD device mtd erase offset len - erase 'len' bytes from 'offset' mtd write addr to len - write 'len' bytes to 'to' from 'addr' mtd read addr from len - read 'len' bytes from 'from' to 'addr'Zynq> mtd list
MTD 1: spi-nor ate000d000
Zynq>
MTD 1: spi-nor ate000d000
Zynq> mtd list
MTD 1: spi-nor ate000d000
Zynq> mtd probe 0
failing to set MTD device 0
Zynq> mtd probe 1
SPI-NOR: detecteds25fl128s_64kwith page size 256 Bytes, erase size 64 KiB, total 16 MiB Zynq> mtd info
MTD Device 1:s25fl128s_64kPage size: 256 B Erase size: 64 KiB Size: 16 MiBZynq> mtd list
MTD 1: spi-nor ate000d000(active 1)
Zynq> mtd erase0xE000000x100000
MTD: 1048576 bytes @0xe00000Erased: OK
Zynq> mw.b0x1000xaa0x100000
Zynq> mtd write0x1000xE000000x100000
device 0 offset0xe00000, size0x100000
MTD: 1048576 bytes @0xe00000Written: OK
Zynq> mtd read0x30000000xE000000x100000
device 0 offset0xe00000, size0x100000
MTD: 1048576 bytes @0xe00000Read: OK
Zynq> cmp.b0x30000000x1000x100000
Total of 1048576 byte(s) were the sameTesting:
-------$ git clone git://git.denx.de/u-boot-spi.git $ cd u-boot-spi $ git checkout -b mtd origin/mtd-working[1] http://lists.denx.de/pipermail/u-boot/2016-March/249286.html
[2] http://lists.denx.de/pipermail/u-boot/2016-February/245418.html
[3] [PATCH RFC v8 00/16] SPI-NOR/MTD additionJagan Teki (21):
dm: mtd: Add dm mtd core ops
mtd: Add SPI-NOR core support
mtd: spi-nor:Kconfig: AddMTD_SPI_NORentry
mtd: spi-nor:Kconfig: AddMTD_SPI_NOR_USE_4K_SECTORS
mtd: spi-nor:Kconfig: AddSPI_NOR_MISCentry
mtd: spi-nor:Kconfig: AddSPI_NOR_MACRONIXentry
mtd: spi-nor:Kconfig: AddSPI_NOR_SPANSIONentry
mtd: spi-nor:Kconfig: AddSPI_NOR_STMICROentry
mtd: spi-nor:Kconfig: AddSPI_NOR_SSTentry
mtd: spi-nor:Kconfig: AddSPI_NOR_WINBONDentry
spi: Addspi_write_then_read
mtd: spi-nor: Add m25p80 driver
mtd: spi-nor:Kconfig: AddMTD_M25P80entry
mtd: spi-nor: Add zynq qspinor driver
mtd: spi-nor:zynq_qspi:Kconfig: AddMTD_ZYNQ
mtd: spi-nor: Add 4-byte addresswidth support
dm: mtd: Add uclass_driver.flags
dm: mtd: Addpost_bind
cmd: Add mtd command support
arm: dts: zynq: Add zynq-qspinor node
dm: zynq: microzed: Enable MTD/SPI-NORMakefile | 1 + arch/arm/dts/zynq-7000.dtsi | 12 + arch/arm/dts/zynq-microzed.dts | 6 + cmd/Kconfig | 6 + cmd/Makefile | 1 + cmd/mtd.c | 285 ++++++++++++++++ configs/zynq_microzed_defconfig | 14 +- drivers/mtd/Kconfig | 2 + drivers/mtd/Makefile | 2 +- drivers/mtd/mtd-uclass.c | 93 +++++ drivers/mtd/spi-nor/Kconfig | 89 +++++ drivers/mtd/spi-nor/Makefile | 15 + drivers/mtd/spi-nor/m25p80.c | 218 ++++++++++++ drivers/mtd/spi-nor/spi-nor-ids.c | 176 ++++++++++ drivers/mtd/spi-nor/spi-nor.c | 684 +++++++++++++++++++++++++++++++++++++ drivers/mtd/spi-nor/zynq_qspinor.c | 641 ++++++++++++++++++++++++++++++++++ drivers/spi/spi-uclass.c | 24 ++ include/linux/err.h | 5 + include/linux/mtd/spi-nor.h | 211 ++++++++++++ include/mtd.h | 63 ++++ include/spi.h | 20 ++ 21 files changed, 2562 insertions(+), 6 deletions(-) create mode 100644 cmd/mtd.c create mode 100644 drivers/mtd/spi-nor/Kconfig create mode 100644 drivers/mtd/spi-nor/Makefile 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.c create mode 100644 drivers/mtd/spi-nor/zynq_qspinor.c create mode 100644 include/linux/mtd/spi-nor.h
Quoted 3 lines
--
2.7.4
To me this series is much easier to understand than previously.
Is there a sandbox MTD driver for use in tests?
Regards,
Simon