Skip to contentSkip to conversation

mtd: Add SPI-NOR core support

PATCH Superseded Jagan Teki 1 participant 33 messages Feb 10, 2016

Subsystems (6)

v5 of 7 Superseded Latest is v7 →

lore
Share & tools
lore

Jagan Teki

author
#0 lore raw

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
author
#1 lore raw

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.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 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
index 430dd4f..f299a24 100644
@@ -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
new file mode 100644
index 0000000..a4c19e3
@@ -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
new file mode 100644
index 0000000..833a9c3
@@ -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
author
#2 lore raw

PATCH v5 2/32 mtd: Add Kconfig entry for MTD_M25P80

In reply to Jagan Teki

Added Kconfig entry for MTD_M25P80

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 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
new file mode 100644
index 0000000..d32486c
@@ -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
author
#3 lore raw

PATCH v5 3/32 mtd: Add SPI-NOR core support

In reply to Jagan Teki

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
	-------------------------------
Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 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
index c58841e..2c8846b 100644
@@ -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
index a4c19e3..9ab6e3d 100644
@@ -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
index 5b3c8bc..1bba498 100644
@@ -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
author
#4 lore raw

PATCH v5 4/32 doc: device-tree-bindings: jedec, spi-nor

In reply to Jagan Teki

Since m25p80 follows similar naming convention as Linux, hence added jedec, spi-nor device tree bindings from Linux.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 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
new file mode 100644
index 0000000..2c91c03
@@ -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
author
#5 lore raw

PATCH v5 5/32 mtd: spi-nor: Add Kconfig entry for MTD_SPI_NOR

In reply to Jagan Teki

Added kconfig entry for MTD_SPI_NOR

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 drivers/mtd/spi-nor/Kconfig | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
drivers/mtd/spi-nor/Kconfig +18 -0
index d32486c..f0ea9f9 100644
@@ -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
author
#6 lore raw

PATCH v5 6/32 mtd: spi-nor: Add kconfig for MTD_SPI_NOR_USE_4K_SECTORS

In reply to Jagan Teki

Added kconfig entry for MTD_SPI_NOR_USE_4K_SECTORS.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 drivers/mtd/spi-nor/Kconfig | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
drivers/mtd/spi-nor/Kconfig +14 -0
index f0ea9f9..374cdcb 100644
@@ -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
author
#7 lore raw

PATCH v5 7/32 mtd: spi-nor: Add MTD support

In reply to Jagan Teki

This 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
	-------------------------------
Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 drivers/mtd/spi-nor/spi-nor.c | 273 +++++++++++++++++++++++++-----------------
 1 file changed, 165 insertions(+), 108 deletions(-)
drivers/mtd/spi-nor/spi-nor.c +165 -108
index f142ae4..3b42b69 100644
@@ -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
author
#8 lore raw

PATCH v5 8/32 mtd: spi-nor: Add spi_nor support in m25p80

In reply to Jagan Teki

m25p80 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

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 drivers/mtd/spi-nor/m25p80.c | 236 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 236 insertions(+)
drivers/mtd/spi-nor/m25p80.c +236 -0
index 833a9c3..57e54d0 100644
@@ -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
author
#9 lore raw

PATCH v5 9/32 mtd: spi-nor: Add dm spi-nor probing

In reply to Jagan Teki

This patch adds driver-model probe from cmd_sf through MTD_DM_SPI_NOR which is depends on MTD and DM_SPI uclass.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 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
index 42862d9..e4d1274 100644
@@ -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
index 374cdcb..59bb943 100644
@@ -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
index 9ab6e3d..71e7ae2 100644
@@ -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
new file mode 100644
index 0000000..c808a7d
@@ -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
index d0ce9e7..a458820 100644
@@ -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
author
#10 lore raw

PATCH v5 10/32 mtd: spi-nor: Add spi_flash_probe for mtd-dm-spi-nor

In reply to Jagan Teki

While probing spi-nor in SPL spi_flash_probe is needed, so add the flash probe code in spi-nor-probe.c

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 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
index c808a7d..9bc61ea 100644
@@ -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
index a458820..1dcce13 100644
@@ -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
author
#11 lore raw

PATCH v5 11/32 cmd: sf: Add mtd_info for mtd-dm-spi-nor code

In reply to Jagan Teki

This patch adds support for mtd_info operations handling from cmd/sf.c

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 cmd/sf.c            | 34 +++++++++++++++++-----------------
 include/spi_flash.h | 48 ++++++++++++++++++++++++++++++++++++------------
 2 files changed, 53 insertions(+), 29 deletions(-)
cmd/sf.c +17 -17
index e4d1274..5dd7177 100644
@@ -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
author
#12 lore raw

PATCH v5 12/32 mtd: spi-nor: m25p80: Add spi_nor support for non-dm

In reply to Jagan Teki

Like 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

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 drivers/mtd/spi-nor/m25p80.c | 108 ++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 96 insertions(+), 12 deletions(-)
drivers/mtd/spi-nor/m25p80.c +96 -12
index 57e54d0..f0340a5 100644
@@ -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
author
#13 lore raw

PATCH v5 13/32 spi_flash: Use mtd_info operation for non-dm

In reply to Jagan Teki

Since 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.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 include/spi_flash.h | 23 ++++-------------------
 1 file changed, 4 insertions(+), 19 deletions(-)
include/spi_flash.h +4 -19
index 719a6e3..77939bd 100644
@@ -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
author
#14 lore raw

PATCH v5 14/32 mtd: spi-nor: Move spi_read_then_write to spi layer

In reply to Jagan Teki

Since 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.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 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
index f0340a5..4aefe93 100644
@@ -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
index 677c020..7728eac 100644
@@ -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
index 7d81fbd..a050386 100644
@@ -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
index 4b88d39..19589aa 100644
@@ -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
author
#15 lore raw

PATCH v5 15/32 spi: Rename spi_read_then_write to spi_write_then_read

In reply to Jagan Teki

Since 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.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 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
index 4aefe93..7e2702d 100644
@@ -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
index 7728eac..0dfdd8b 100644
@@ -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
index a050386..c8051f9 100644
@@ -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
index 19589aa..dd0b11b 100644
@@ -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
author
#16 lore raw

PATCH v5 16/32 spi: Drop mode_rx

In reply to Jagan Teki

mp2580 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.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 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
index 7e2702d..58e879c 100644
@@ -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
index e543b8f..5f03508 100644
@@ -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
index 0dfdd8b..ed6c771 100644
@@ -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
index b5c974c..d9d65b4 100644
@@ -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
index dd0b11b..61fefa4 100644
@@ -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
author
#17 lore raw

PATCH v5 17/32 spi: Drop SPI_RX_FAST

In reply to Jagan Teki

SPI_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.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 include/spi.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
include/spi.h +2 -3
index 61fefa4..9af2fbb 100644
@@ -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
author
#18 lore raw

PATCH v5 18/32 mtd: spi-nor: Rename SPI_FLASH_BAR to SPI_NOR_BAR

In reply to Jagan Teki

Renamed SPI_FLASH_BAR to SPI_NOR_BAR

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 drivers/mtd/spi-nor/spi-nor.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/mtd/spi-nor/spi-nor.c +7 -7
index 3b42b69..32d5cbc 100644
@@ -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
author
#19 lore raw

PATCH v5 19/32 mtd: spi-nor: Add Kconfig entry for SPI_NOR_BAR

In reply to Jagan Teki

Added kconfig entry for SPI_NOR_BAR

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 drivers/mtd/spi-nor/Kconfig | 7 +++++++
 1 file changed, 7 insertions(+)
drivers/mtd/spi-nor/Kconfig +7 -0
index 59bb943..43f59b7 100644
@@ -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
author
#20 lore raw

PATCH v5 20/32 mtd: spi-nor: Copy spl files from drivers/mtd/spi

In reply to Jagan Teki

Copy spl files from drivers/mtd/spi to spi-nor,
more changes will added on future patches.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 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
index 71e7ae2..4d27811 100644
@@ -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
author
#21 lore raw

PATCH v5 21/32 mtd: spi-nor: spl: Follow ascending order of include headers

In reply to Jagan Teki

Use ascending order while including headers files.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 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
index b915469..7c40245 100644
@@ -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
index ca56fe9..285b6da 100644
@@ -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
author
#22 lore raw

PATCH v5 22/32 mtd: spi-nor: fsl_espi_spl: Use mtd_info

In reply to Jagan Teki

Replace spi_flash{} with mtd_info{}

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 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
index 7c40245..93b0b2e 100644
@@ -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
author
#23 lore raw

PATCH v5 23/32 mtd: spi-nor: spi_spl_load: Use mtd_info

In reply to Jagan Teki

Replace spi_flash{} with mtd_info{}

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 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
index 285b6da..9f33826 100644
@@ -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
author
#24 lore raw

PATCH v5 24/32 mtd: spi-nor: Add flash vendor Kconfig entries

In reply to Jagan Teki

Added flash vendor kconfig entries from drivers/mtd/spi

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 drivers/mtd/spi-nor/Kconfig | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)
drivers/mtd/spi-nor/Kconfig +40 -0
index 43f59b7..219306f 100644
@@ -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
author
#25 lore raw

PATCH v5 25/32 arm: zynq: Kconfig: Select MTD uclass

In reply to Jagan Teki

Since SPI-NOR core relies on MTD uclass.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 arch/arm/Kconfig | 1 +
 1 file changed, 1 insertion(+)
arch/arm/Kconfig +1 -0
index d2dbb1a..2dc2191 100644
@@ -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
author
#26 lore raw

PATCH v5 26/32 arm: zynq: Kconfig: Drop DM_SPI_FLASH

In reply to Jagan Teki

Drop using legacy DM_SPI_FLASH.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 arch/arm/Kconfig | 1 -
 1 file changed, 1 deletion(-)
arch/arm/Kconfig +0 -1
index 2dc2191..b26dddb 100644
@@ -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
author
#27 lore raw

PATCH v5 27/32 defconfigs: zynq_microzed: Drop CONFIG_SPI_FLASH

In reply to Jagan Teki

Drop using legacy spi_flash core.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 configs/zynq_microzed_defconfig | 1 -
 1 file changed, 1 deletion(-)
configs/zynq_microzed_defconfig +0 -1
index a3a66ec..c181537 100644
@@ -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
author
#28 lore raw

PATCH v5 28/32 defconfig: zynq_microzed: Enable CONFIG_MTD_M25P80

In reply to Jagan Teki

Use m25p80 which is flash interface layer between spi-nor core vs drivers/spi

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 configs/zynq_microzed_defconfig | 1 +
 1 file changed, 1 insertion(+)
configs/zynq_microzed_defconfig +1 -0
index c181537..79f2913 100644
@@ -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
author
#29 lore raw

PATCH v5 29/32 defconfig: zynq_microzed: Enable CONFIG_MTD_SPI_NOR

In reply to Jagan Teki

Enabled SPI-NOR core support

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 configs/zynq_microzed_defconfig | 1 +
 1 file changed, 1 insertion(+)
configs/zynq_microzed_defconfig +1 -0
index 79f2913..db02ba3 100644
@@ -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
author
#30 lore raw

PATCH v5 30/32 spl: Add CONFIG_SPL_SPI_NOR_SUPPORT

In reply to Jagan Teki

Add SPL support for SPI-NOR flash.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 drivers/Makefile | 1 +
 1 file changed, 1 insertion(+)
drivers/Makefile +1 -0
index e7eab66..1d179b9 100644
@@ -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
author
#31 lore raw

PATCH v5 31/32 configs: zynq: Use CONFIG_SPL_SPI_NOR_SUPPORT

In reply to Jagan Teki

Use SPI-NOR SPL support for zynq boards.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 include/configs/zynq-common.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/configs/zynq-common.h +1 -1
index e8c3ef0..7427d22 100644
@@ -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
author
#32 lore raw

PATCH v5 32/32 configs: zynq: Use CONFIG_SPL_MTD_SUPPORT

In reply to Jagan Teki

Since SPI-NOR depends on MTD core enable the same for SPI-NOR SPL.

Cc Simon Glass <[email protected]>
Cc Bin Meng <[email protected]>
Cc Mugunthan V N <[email protected]>
Cc Michal Simek <[email protected]>
Cc Siva Durga Prasad Paladugu <[email protected]>
---
 include/configs/zynq-common.h | 1 +
 1 file changed, 1 insertion(+)
include/configs/zynq-common.h +1 -0
index 7427d22..582b2a3 100644
@@ -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