All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support
@ 2016-02-10 19:07 Jagan Teki
  2016-02-10 19:07 ` [U-Boot] [PATCH v5 01/32] mtd: Add m25p80 driver Jagan Teki
                   ` (31 more replies)
  0 siblings, 32 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:07 UTC (permalink / raw)
  To: u-boot

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

-- 
1.9.1

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 01/32] mtd: Add m25p80 driver
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
@ 2016-02-10 19:07 ` Jagan Teki
  2016-02-10 19:07 ` [U-Boot] [PATCH v5 02/32] mtd: Add Kconfig entry for MTD_M25P80 Jagan Teki
                   ` (30 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:07 UTC (permalink / raw)
  To: u-boot

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 <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 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

diff --git a/Makefile b/Makefile
index 430dd4f..f299a24 100644
--- a/Makefile
+++ b/Makefile
@@ -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/
diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
new file mode 100644
index 0000000..a4c19e3
--- /dev/null
+++ b/drivers/mtd/spi-nor/Makefile
@@ -0,0 +1,6 @@
+#
+# Copyright (C) 2016 Jagan Teki <jteki@openedev.com>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+
+obj-$(CONFIG_MTD_M25P80)	+= m25p80.o
diff --git a/drivers/mtd/spi-nor/m25p80.c b/drivers/mtd/spi-nor/m25p80.c
new file mode 100644
index 0000000..833a9c3
--- /dev/null
+++ b/drivers/mtd/spi-nor/m25p80.c
@@ -0,0 +1,37 @@
+/*
+ * MTD SPI-NOR driver for ST M25Pxx (and similar) serial flash chips
+ *
+ * Copyright (C) 2016 Jagan Teki <jteki@openedev.com>
+ *
+ * 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,
+};
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 02/32] mtd: Add Kconfig entry for MTD_M25P80
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
  2016-02-10 19:07 ` [U-Boot] [PATCH v5 01/32] mtd: Add m25p80 driver Jagan Teki
@ 2016-02-10 19:07 ` Jagan Teki
  2016-02-10 19:07 ` [U-Boot] [PATCH v5 03/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (29 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:07 UTC (permalink / raw)
  To: u-boot

Added Kconfig entry for MTD_M25P80

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 drivers/mtd/spi-nor/Kconfig | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 create mode 100644 drivers/mtd/spi-nor/Kconfig

diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
new file mode 100644
index 0000000..d32486c
--- /dev/null
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -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.
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 03/32] mtd: Add SPI-NOR core support
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
  2016-02-10 19:07 ` [U-Boot] [PATCH v5 01/32] mtd: Add m25p80 driver Jagan Teki
  2016-02-10 19:07 ` [U-Boot] [PATCH v5 02/32] mtd: Add Kconfig entry for MTD_M25P80 Jagan Teki
@ 2016-02-10 19:07 ` Jagan Teki
  2016-02-10 19:07 ` [U-Boot] [PATCH v5 04/32] doc: device-tree-bindings: jedec, spi-nor Jagan Teki
                   ` (28 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:07 UTC (permalink / raw)
  To: u-boot

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 <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 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

diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index c58841e..2c8846b 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -33,3 +33,5 @@ endmenu
 source "drivers/mtd/nand/Kconfig"
 
 source "drivers/mtd/spi/Kconfig"
+
+source "drivers/mtd/spi-nor/Kconfig"
diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
index a4c19e3..9ab6e3d 100644
--- a/drivers/mtd/spi-nor/Makefile
+++ b/drivers/mtd/spi-nor/Makefile
@@ -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
diff --git a/drivers/mtd/spi-nor/spi-nor-ids.c b/drivers/mtd/spi-nor/spi-nor-ids.c
new file mode 100644
index 0000000..2599731
--- /dev/null
+++ b/drivers/mtd/spi-nor/spi-nor-ids.c
@@ -0,0 +1,276 @@
+/*
+ * SPI NOR ID's.
+ * Cloned most of the code from the sf_params.c and Linux spi-nor framework.
+ *
+ * Copyright (C) 2016 Jagan Teki <jteki@openedev.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <linux/mtd/spi-nor.h>
+
+/* Used when the "_ext_id" is two bytes at most */
+#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flash_read, _flags)	\
+		.id = {							\
+			((_jedec_id) >> 16) & 0xff,			\
+			((_jedec_id) >> 8) & 0xff,			\
+			(_jedec_id) & 0xff,				\
+			((_ext_id) >> 8) & 0xff,			\
+			(_ext_id) & 0xff,				\
+			},						\
+		.id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))),	\
+		.sector_size = (_sector_size),				\
+		.n_sectors = (_n_sectors),				\
+		.page_size = 256,					\
+		.flash_read = _flash_read,					\
+		.flags = (_flags),
+
+#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flash_read, _flags)	\
+		.id = {							\
+			((_jedec_id) >> 16) & 0xff,			\
+			((_jedec_id) >> 8) & 0xff,			\
+			(_jedec_id) & 0xff,				\
+			((_ext_id) >> 16) & 0xff,			\
+			((_ext_id) >> 8) & 0xff,			\
+			(_ext_id) & 0xff,				\
+			},						\
+		.id_len = 6,						\
+		.sector_size = (_sector_size),				\
+		.n_sectors = (_n_sectors),				\
+		.page_size = 256,					\
+		.flash_read = _flash_read,					\
+		.flags = (_flags),
+
+#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flash_read, _flags)	\
+		.sector_size = (_sector_size),				\
+		.n_sectors = (_n_sectors),				\
+		.page_size = (_page_size),				\
+		.addr_width = (_addr_width),				\
+		.flash_read = _flash_read,					\
+		.flags = (_flags),
+
+/* NOTE: double check command sets and memory organization when you add
+ * more nor chips.  This current list focusses on newer chips, which
+ * have been converging on command sets which including JEDEC ID.
+ *
+ * All newly added entries should describe *hardware* and should use SECT_4K
+ * (or SECT_4K_PMC) if hardware supports erasing 4 KiB sectors. For usage
+ * scenarios excluding small sectors there is config option that can be
+ * disabled: CONFIG_MTD_SPI_NOR_USE_4K_SECTORS.
+ * For historical (and compatibility) reasons (before we got above config) some
+ * old entries may be missing 4K flag.
+ */
+const struct spi_nor_info spi_nor_ids[] = {
+#ifdef CONFIG_SPI_FLASH_ATMEL		/* ATMEL */
+	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
+	{ "at25fs010",  INFO(0x1f6601, 0, 32 * 1024,   4, SNOR_READ_BASE, SECT_4K) },
+	{ "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SNOR_READ_BASE, SECT_4K) },
+
+	{ "at25df041a", INFO(0x1f4401, 0, 64 * 1024,   8, SNOR_READ_BASE, SECT_4K) },
+	{ "at25df321a", INFO(0x1f4701, 0, 64 * 1024,  64, SNOR_READ_BASE, SECT_4K) },
+	{ "at25df641",  INFO(0x1f4800, 0, 64 * 1024, 128, SNOR_READ_BASE, SECT_4K) },
+
+	{ "at26f004",   INFO(0x1f0400, 0, 64 * 1024,  8, SNOR_READ_BASE, SECT_4K) },
+	{ "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SNOR_READ_BASE, SECT_4K) },
+	{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SNOR_READ_BASE, SECT_4K) },
+	{ "at26df321",  INFO(0x1f4700, 0, 64 * 1024, 64, SNOR_READ_BASE, SECT_4K) },
+
+	{ "at45db011d",	INFO(0x1f2200, 0, 64 * 1024,   4, SNOR_READ_BASE, SECT_4K) },
+	{ "at45db021d",	INFO(0x1f2300, 0, 64 * 1024,   8, SNOR_READ_BASE, SECT_4K) },
+	{ "at45db041d",	INFO(0x1f2400, 0, 64 * 1024,   8, SNOR_READ_BASE, SECT_4K) },
+	{ "at45db081d",	INFO(0x1f2500, 0, 64 * 1024,  16, SNOR_READ_BASE, SECT_4K) },
+	{ "at45db161d",	INFO(0x1f2600, 0, 64 * 1024,  32, SNOR_READ_BASE, SECT_4K) },
+	{ "at45db321d",	INFO(0x1f2700, 0, 64 * 1024,  64, SNOR_READ_BASE, SECT_4K) },
+	{ "at45db641d",	INFO(0x1f2800, 0, 64 * 1024, 128, SNOR_READ_BASE, SECT_4K) },
+#endif
+#ifdef CONFIG_SPI_FLASH_EON		/* EON */
+	/* EON -- en25xxx */
+	{ "en25f32",    INFO(0x1c3116, 0, 64 * 1024,   64, SNOR_READ_BASE, SECT_4K) },
+	{ "en25p32",    INFO(0x1c2016, 0, 64 * 1024,   64, SNOR_READ_BASE, 0) },
+	{ "en25q32b",   INFO(0x1c3016, 0, 64 * 1024,   64, SNOR_READ_BASE, 0) },
+	{ "en25p64",    INFO(0x1c2017, 0, 64 * 1024,  128, SNOR_READ_BASE, 0) },
+	{ "en25q64",    INFO(0x1c3017, 0, 64 * 1024,  128, SNOR_READ_BASE, SECT_4K) },
+	{ "en25q128b",	INFO(0x1c3018, 0, 64 * 1024,  256, SNOR_READ_BASE, 0) },
+	{ "en25qh128",  INFO(0x1c7018, 0, 64 * 1024,  256, SNOR_READ_BASE, 0) },
+	{ "en25qh256",  INFO(0x1c7019, 0, 64 * 1024,  512, SNOR_READ_BASE, 0) },
+	{ "en25s64",	INFO(0x1c3817, 0, 64 * 1024,  128, SNOR_READ_BASE, SECT_4K) },
+#endif
+	/* ESMT */
+	{ "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SNOR_READ_BASE, SECT_4K) },
+
+	/* Everspin */
+	{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SNOR_READ_BASE, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "mr25h10",  CAT25_INFO(128 * 1024, 1, 256, 3, SNOR_READ_BASE, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+
+	/* Fujitsu */
+	{ "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SNOR_READ_BASE, SPI_NOR_NO_ERASE) },
+
+#ifdef CONFIG_SPI_FLASH_GIGADEVICE	/* GIGADEVICE */
+	/* GigaDevice */
+	{ "gd25q32", INFO(0xc84016, 0, 64 * 1024,  64, SNOR_READ_BASE, SECT_4K) },
+	{ "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, SNOR_READ_BASE, SECT_4K) },
+	{ "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, SNOR_READ_BASE, SECT_4K) },
+	{ "gd25lq32", INFO(0xc86016, 0,	64 * 1024,  64, SNOR_READ_BASE, SECT_4K) },
+#endif
+	/* Intel/Numonyx -- xxxs33b */
+	{ "160s33b",  INFO(0x898911, 0, 64 * 1024,  32, SNOR_READ_BASE, 0) },
+	{ "320s33b",  INFO(0x898912, 0, 64 * 1024,  64, SNOR_READ_BASE, 0) },
+	{ "640s33b",  INFO(0x898913, 0, 64 * 1024, 128, SNOR_READ_BASE, 0) },
+
+#ifdef CONFIG_SPI_FLASH_ISSI		/* ISSI */
+	/* ISSI */
+	{ "is25cd512", INFO(0x7f9d20, 0, 32 * 1024,   2, SNOR_READ_BASE, SECT_4K) },
+	{ "is25lp032", INFO(0x9d6016, 0, 64 * 1024,  64, SNOR_READ_BASE, 0) },
+	{ "is25lp064", INFO(0x9d6017, 0, 64 * 1024, 128, SNOR_READ_BASE, 0) },
+	{ "is25lp128", INFO(0x9d6018, 0, 64 * 1024, 256, SNOR_READ_BASE, 0) },
+#endif
+#ifdef CONFIG_SPI_FLASH_MACRONIX	/* MACRONIX */
+	/* Macronix */
+	{ "mx25l512e",   INFO(0xc22010, 0, 64 * 1024,   1, SNOR_READ_BASE, SECT_4K) },
+	{ "mx25l2005a",  INFO(0xc22012, 0, 64 * 1024,   4, SNOR_READ_BASE, SECT_4K) },
+	{ "mx25l4005a",  INFO(0xc22013, 0, 64 * 1024,   8, SNOR_READ_BASE, SECT_4K) },
+	{ "mx25l8005",   INFO(0xc22014, 0, 64 * 1024,  16, SNOR_READ_BASE, 0) },
+	{ "mx25l1606e",  INFO(0xc22015, 0, 64 * 1024,  32, SNOR_READ_BASE, SECT_4K) },
+	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, SNOR_READ_BASE, 0) },
+	{ "mx25l3255e",  INFO(0xc29e16, 0, 64 * 1024,  64, SNOR_READ_BASE, SECT_4K) },
+	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, SNOR_READ_BASE, 0) },
+	{ "mx25u6435f",  INFO(0xc22537, 0, 64 * 1024, 128, SNOR_READ_BASE, SECT_4K) },
+	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "mx66l1g55g",  INFO(0xc2261b, 0, 64 * 1024, 2048, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+#endif
+#ifdef CONFIG_SPI_FLASH_STMICRO		/* STMICRO */
+	/* Micron */
+	{ "n25q032",	 INFO(0x20ba16, 0, 64 * 1024,   64, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K) },
+	{ "n25q064a",    INFO(0x20bb17, 0, 64 * 1024,  128, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K) },
+	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K) },
+	{ "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K | USE_FSR) },
+	{ "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K | USE_FSR) },
+	{ "n25q00",      INFO(0x20ba21, 0, 64 * 1024, 2048, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K | USE_FSR) },
+#endif
+	/* PMC */
+	{ "pm25lv512",   INFO(0,        0, 32 * 1024,    2, SNOR_READ_BASE, SECT_4K_PMC) },
+	{ "pm25lv010",   INFO(0,        0, 32 * 1024,    4, SNOR_READ_BASE, SECT_4K_PMC) },
+	{ "pm25lq032",   INFO(0x7f9d46, 0, 64 * 1024,   64, SNOR_READ_BASE, SECT_4K) },
+
+#ifdef CONFIG_SPI_FLASH_SPANSION	/* SPANSION */
+	/* Spansion -- single (large) sector size only, at least
+	 * for the chips listed here (without boot sectors).
+	 */
+	{ "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, SNOR_READ_FULL, 0) },
+	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, SNOR_READ_FULL, 0) },
+	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SNOR_READ_FULL, 0) },
+	{ "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, SNOR_READ_FULL, 0) },
+	{ "s25fl512s1", INFO(0x010220, 0x4d01,  64 * 1024, 1024, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "s25fl512s2", INFO(0x010220, 0x4f00, 256 * 1024, 256, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "s25fl128s",	INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, SNOR_READ_FULL, SNOR_WRITE_QUAD) },
+	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, SNOR_READ_BASE, 0) },
+	{ "s25sl008a",  INFO(0x010213,      0,  64 * 1024,  16, SNOR_READ_BASE, 0) },
+	{ "s25sl016a",  INFO(0x010214,      0,  64 * 1024,  32, SNOR_READ_BASE, 0) },
+	{ "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64, SNOR_READ_BASE, 0) },
+	{ "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128, SNOR_READ_BASE, 0) },
+	{ "s25fl008k",  INFO(0xef4014,      0,  64 * 1024,  16, SNOR_READ_BASE, SECT_4K) },
+	{ "s25fl016k",  INFO(0xef4015,      0,  64 * 1024,  32, SNOR_READ_BASE, SECT_4K) },
+	{ "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128, SNOR_READ_BASE, SECT_4K) },
+	{ "s25fl132k",  INFO(0x014016,      0,  64 * 1024,  64, SNOR_READ_BASE, SECT_4K) },
+	{ "s25fl164k",  INFO(0x014017,      0,  64 * 1024, 128, SNOR_READ_BASE, SECT_4K) },
+	{ "s25fl204k",  INFO(0x014013,      0,  64 * 1024,   8, SNOR_READ_BASE, SECT_4K) },
+#endif
+#ifdef CONFIG_SPI_FLASH_SST		/* SST */
+	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
+	{ "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8, SNOR_READ_BASE, SECT_4K | SST_WRITE) },
+	{ "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SNOR_READ_BASE, SECT_4K | SST_WRITE) },
+	{ "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SNOR_READ_BASE, SECT_4K | SST_WRITE) },
+	{ "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SNOR_READ_BASE, SECT_4K | SST_WRITE) },
+	{ "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128, SNOR_READ_BASE, SECT_4K) },
+	{ "sst25wf512",  INFO(0xbf2501, 0, 64 * 1024,  1, SNOR_READ_BASE, SECT_4K | SST_WRITE) },
+	{ "sst25wf010",  INFO(0xbf2502, 0, 64 * 1024,  2, SNOR_READ_BASE, SECT_4K | SST_WRITE) },
+	{ "sst25wf020",  INFO(0xbf2503, 0, 64 * 1024,  4, SNOR_READ_BASE, SECT_4K | SST_WRITE) },
+	{ "sst25wf040",	 INFO(0xbf2504, 0, 64 * 1024,  8, SNOR_READ_BASE, SECT_4K | SST_WRITE) },
+	{ "sst25wf020a", INFO(0x621612, 0, 64 * 1024,  4, SNOR_READ_BASE, SECT_4K) },
+	{ "sst25wf040b", INFO(0x621613, 0, 64 * 1024,  8, SNOR_READ_BASE, SECT_4K) },
+	{ "sst25wf040",  INFO(0xbf2504, 0, 64 * 1024,  8, SNOR_READ_BASE, SECT_4K | SST_WRITE) },
+	{ "sst25wf080",  INFO(0xbf2505, 0, 64 * 1024, 16, SNOR_READ_BASE, SECT_4K | SST_WRITE) },
+#endif
+#ifdef CONFIG_SPI_FLASH_STMICRO		/* STMICRO */
+	/* ST Microelectronics -- newer production may have feature updates */
+	{ "m25p05",  INFO(0x202010,  0,  32 * 1024,   2, SNOR_READ_BASE, 0) },
+	{ "m25p10",  INFO(0x202011,  0,  32 * 1024,   4, SNOR_READ_BASE, 0) },
+	{ "m25p20",  INFO(0x202012,  0,  64 * 1024,   4, SNOR_READ_BASE, 0) },
+	{ "m25p40",  INFO(0x202013,  0,  64 * 1024,   8, SNOR_READ_BASE, 0) },
+	{ "m25p80",  INFO(0x202014,  0,  64 * 1024,  16, SNOR_READ_BASE, 0) },
+	{ "m25p16",  INFO(0x202015,  0,  64 * 1024,  32, SNOR_READ_BASE, 0) },
+	{ "m25p32",  INFO(0x202016,  0,  64 * 1024,  64, SNOR_READ_BASE, 0) },
+	{ "m25p64",  INFO(0x202017,  0,  64 * 1024, 128, SNOR_READ_BASE, 0) },
+	{ "m25p128", INFO(0x202018,  0, 256 * 1024,  64, SNOR_READ_BASE, 0) },
+
+	{ "m25p05-nonjedec",  INFO(0, 0,  32 * 1024,   2, SNOR_READ_BASE, 0) },
+	{ "m25p10-nonjedec",  INFO(0, 0,  32 * 1024,   4, SNOR_READ_BASE, 0) },
+	{ "m25p20-nonjedec",  INFO(0, 0,  64 * 1024,   4, SNOR_READ_BASE, 0) },
+	{ "m25p40-nonjedec",  INFO(0, 0,  64 * 1024,   8, SNOR_READ_BASE, 0) },
+	{ "m25p80-nonjedec",  INFO(0, 0,  64 * 1024,  16, SNOR_READ_BASE, 0) },
+	{ "m25p16-nonjedec",  INFO(0, 0,  64 * 1024,  32, SNOR_READ_BASE, 0) },
+	{ "m25p32-nonjedec",  INFO(0, 0,  64 * 1024,  64, SNOR_READ_BASE, 0) },
+	{ "m25p64-nonjedec",  INFO(0, 0,  64 * 1024, 128, SNOR_READ_BASE, 0) },
+	{ "m25p128-nonjedec", INFO(0, 0, 256 * 1024,  64, SNOR_READ_BASE, 0) },
+
+	{ "m45pe10", INFO(0x204011,  0, 64 * 1024,    2, SNOR_READ_BASE, 0) },
+	{ "m45pe80", INFO(0x204014,  0, 64 * 1024,   16, SNOR_READ_BASE, 0) },
+	{ "m45pe16", INFO(0x204015,  0, 64 * 1024,   32, SNOR_READ_BASE, 0) },
+
+	{ "m25pe20", INFO(0x208012,  0, 64 * 1024,  4, SNOR_READ_BASE, 0) },
+	{ "m25pe80", INFO(0x208014,  0, 64 * 1024, 16, SNOR_READ_BASE, 0) },
+	{ "m25pe16", INFO(0x208015,  0, 64 * 1024, 32, SNOR_READ_BASE, SECT_4K) },
+
+	{ "m25px16",    INFO(0x207115,  0, 64 * 1024, 32, SNOR_READ_BASE, SECT_4K) },
+	{ "m25px32",    INFO(0x207116,  0, 64 * 1024, 64, SNOR_READ_BASE, SECT_4K) },
+	{ "m25px32-s0", INFO(0x207316,  0, 64 * 1024, 64, SNOR_READ_BASE, SECT_4K) },
+	{ "m25px32-s1", INFO(0x206316,  0, 64 * 1024, 64, SNOR_READ_BASE, SECT_4K) },
+	{ "m25px64",    INFO(0x207117,  0, 64 * 1024, 128, SNOR_READ_BASE, 0) },
+	{ "m25px80",    INFO(0x207114,  0, 64 * 1024, 16, SNOR_READ_BASE, 0) },
+#endif
+#ifdef CONFIG_SPI_FLASH_WINBOND		/* WINBOND */
+	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
+	{ "W25P80", INFO(0xef2014, 0, 64 * 1024, 16, SNOR_READ_BASE, 0) },
+	{ "W25P16", INFO(0xef2015, 0, 64 * 1024, 32, SNOR_READ_BASE, 0) },
+	{ "W25P32", INFO(0xef2016, 0, 64 * 1024, 64, SNOR_READ_BASE, 0) },
+	{ "w25x05", INFO(0xef3010, 0, 64 * 1024,  1, SNOR_READ_BASE, SECT_4K) },
+	{ "w25x10", INFO(0xef3011, 0, 64 * 1024,  2, SNOR_READ_BASE, SECT_4K) },
+	{ "w25x20", INFO(0xef3012, 0, 64 * 1024,  4, SNOR_READ_BASE, SECT_4K) },
+	{ "w25x40", INFO(0xef3013, 0, 64 * 1024,  8, SNOR_READ_BASE, SECT_4K) },
+	{ "w25x80", INFO(0xef3014, 0, 64 * 1024,  16, SNOR_READ_BASE, SECT_4K) },
+	{ "w25x16", INFO(0xef3015, 0, 64 * 1024,  32, SNOR_READ_BASE, SECT_4K) },
+	{ "w25x32", INFO(0xef3016, 0, 64 * 1024,  64, SNOR_READ_BASE, SECT_4K) },
+	{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SNOR_READ_BASE, SECT_4K) },
+	{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024,  16, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K) },
+	{" w25q16cl", INFO(0xef4015, 0,	64 * 1024,  32, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K) },
+	{ "w25q32", INFO(0xef4016, 0, 64 * 1024,  64, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K) },
+	{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K) },
+	{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K) },
+	{ "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K) },
+	{ "w25q80", INFO(0xef5014, 0, 64 * 1024,  16, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K) },
+	{ "w25q16dw", INFO(0xef6015, 0, 64 * 1024,  32, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K) },
+	{ "w25q32dw", INFO(0xef6016, 0, 64 * 1024,  64, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K) },
+	{ "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K) },
+	{ "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256, SNOR_READ_FULL, SNOR_WRITE_QUAD | SECT_4K) },
+#endif
+	/* Catalyst / On Semiconductor -- non-JEDEC */
+	{ "cat25c11", CAT25_INFO(  16, 8, 16, 1, SNOR_READ_BASE, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25c03", CAT25_INFO(  32, 8, 16, 2, SNOR_READ_BASE, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25c09", CAT25_INFO( 128, 8, 32, 2, SNOR_READ_BASE, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25c17", CAT25_INFO( 256, 8, 32, 2, SNOR_READ_BASE, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25128", CAT25_INFO(2048, 8, 64, 2, SNOR_READ_BASE, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ },
+};
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
new file mode 100644
index 0000000..f142ae4
--- /dev/null
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -0,0 +1,1084 @@
+/*
+ * SPI NOR Core - cloned most of the code from the spi_flash.c
+ *
+ * Copyright (C) 2016 Jagan Teki <jteki@openedev.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <malloc.h>
+#include <mapmem.h>
+
+#include <linux/math64.h>
+#include <linux/log2.h>
+#include <linux/mtd/spi-nor.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Set write enable latch with Write Enable command */
+static inline int write_enable(struct spi_nor *nor)
+{
+	return nor->write_reg(nor, SNOR_OP_WREN, NULL, 0);
+}
+
+/* Re-set write enable latch with Write Disable command */
+static inline int write_disable(struct spi_nor *nor)
+{
+	return nor->write_reg(nor, SNOR_OP_WRDI, NULL, 0);
+}
+
+static void spi_nor_addr(u32 addr, u8 *cmd)
+{
+	/* cmd[0] is actual command */
+	cmd[1] = addr >> 16;
+	cmd[2] = addr >> 8;
+	cmd[3] = addr >> 0;
+}
+
+static int read_sr(struct spi_nor *nor)
+{
+	u8 sr;
+	int ret;
+
+	ret = nor->read_reg(nor, SNOR_OP_RDSR, &sr, 1);
+	if (ret < 0) {
+		debug("spi-nor: fail to read status register\n");
+		return ret;
+	}
+
+	return sr;
+}
+
+static int read_fsr(struct spi_nor *nor)
+{
+	u8 fsr;
+	int ret;
+
+	ret = nor->read_reg(nor, SNOR_OP_RDFSR, &fsr, 1);
+	if (ret < 0) {
+		debug("spi-nor: fail to read flag status register\n");
+		return ret;
+	}
+
+	return fsr;
+}
+
+static int write_sr(struct spi_nor *nor, u8 ws)
+{
+	nor->cmd_buf[0] = ws;
+	return nor->write_reg(nor, SNOR_OP_WRSR, nor->cmd_buf, 1);
+}
+
+#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND)
+static int read_cr(struct spi_nor *nor)
+{
+	u8 cr;
+	int ret;
+
+	ret = nor->read_reg(nor, SNOR_OP_RDCR, &cr, 1);
+	if (ret < 0) {
+		debug("spi-nor: fail to read config register\n");
+		return ret;
+	}
+
+	return cr;
+}
+
+/*
+ * Write status Register and configuration register with 2 bytes
+ * - First byte will be written to the status register.
+ * - Second byte will be written to the configuration register.
+ * Return negative if error occured.
+ */
+static int write_sr_cr(struct spi_nor *nor, u16 val)
+{
+	nor->cmd_buf[0] = val & 0xff;
+	nor->cmd_buf[1] = (val >> 8);
+
+	return nor->write_reg(nor, SNOR_OP_WRSR, nor->cmd_buf, 2);
+}
+#endif
+
+#ifdef CONFIG_SPI_FLASH_STMICRO
+static int read_evcr(struct spi_nor *nor)
+{
+	u8 evcr;
+	int ret;
+
+	ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &evcr, 1);
+	if (ret < 0) {
+		debug("spi-nor: fail to read EVCR\n");
+		return ret;
+	}
+
+	return evcr;
+}
+
+static int write_evcr(struct spi_nor *nor, u8 evcr)
+{
+	nor->cmd_buf[0] = evcr;
+	return nor->write_reg(nor, SPINOR_OP_WD_EVCR, nor->cmd_buf, 1);
+}
+#endif
+
+static int spi_nor_sr_ready(struct spi_nor *nor)
+{
+	int sr = read_sr(nor);
+	if (sr < 0)
+		return sr;
+	else
+		return !(sr & SR_WIP);
+}
+
+static int spi_nor_fsr_ready(struct spi_nor *nor)
+{
+	int fsr = read_fsr(nor);
+	if (fsr < 0)
+		return fsr;
+	else
+		return fsr & FSR_READY;
+}
+
+static int spi_nor_ready(struct spi_nor *nor)
+{
+	int sr, fsr;
+
+	sr = spi_nor_sr_ready(nor);
+	if (sr < 0)
+		return sr;
+
+	fsr = 1;
+	if (nor->flags & SNOR_F_USE_FSR) {
+		fsr = spi_nor_fsr_ready(nor);
+		if (fsr < 0)
+			return fsr;
+	}
+
+	return sr && fsr;
+}
+
+static int spi_nor_wait_till_ready(struct spi_nor *nor, unsigned long timeout)
+{
+	int timebase, ret;
+
+	timebase = get_timer(0);
+
+	while (get_timer(timebase) < timeout) {
+		ret = spi_nor_ready(nor);
+		if (ret < 0)
+			return ret;
+		if (ret)
+			return 0;
+	}
+
+	printf("spi-nor: Timeout!\n");
+
+	return -ETIMEDOUT;
+}
+
+#ifdef CONFIG_SPI_FLASH_BAR
+static int spi_nor_write_bar(struct spi_nor *nor, u32 offset)
+{
+	u8 bank_sel;
+	int ret;
+
+	bank_sel = offset / (SNOR_16MB_BOUN << nor->shift);
+	if (bank_sel == nor->bank_curr)
+		goto bar_end;
+
+	write_enable(nor);
+
+	nor->cmd_buf[0] = bank_sel;
+	ret = nor->write_reg(nor, nor->bar_program_opcode, nor->cmd_buf, 1);
+	if (ret < 0) {
+		debug("spi-nor: fail to write bank register\n");
+		return ret;
+	}
+
+	ret = spi_nor_wait_till_ready(nor, SNOR_READY_WAIT_PROG);
+	if (ret < 0)
+		return ret;
+
+bar_end:
+	nor->bank_curr = bank_sel;
+	return nor->bank_curr;
+}
+
+static int spi_nor_read_bar(struct spi_nor *nor, const struct spi_nor_info *info)
+{
+	u8 curr_bank = 0;
+	int ret;
+
+	if (flash->size <= SNOR_16MB_BOUN)
+		goto bar_end;
+
+	switch (JEDEC_MFR(info)) {
+	case SNOR_MFR_SPANSION:
+		nor->bar_read_opcode = SNOR_OP_BRRD;
+		nor->bar_program_opcode = SNOR_OP_BRWR;
+		break;
+	default:
+		nor->bar_read_opcode = SNOR_OP_RDEAR;
+		nor->bar_program_opcode = SNOR_OP_WREAR;
+	}
+
+	ret = nor->read_reg(nor, nor->bar_read_opcode, &curr_bank, 1);
+	if (ret) {
+		debug("spi-nor: fail to read bank addr register\n");
+		return ret;
+	}
+
+bar_end:
+	nor->bank_curr = curr_bank;
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_SF_DUAL_FLASH
+static void spi_nor_dual(struct spi_nor *nor, u32 *addr)
+{
+	struct spi_flash *flash = nor->flash;
+
+	switch (nor->dual) {
+	case SNOR_DUAL_STACKED:
+		if (*addr >= (flash->size >> 1)) {
+			*addr -= flash->size >> 1;
+			nor->flags |= SNOR_F_U_PAGE;
+		} else {
+			nor->flags &= ~SNOR_F_U_PAGE;
+		}
+		break;
+	case SNOR_DUAL_PARALLEL:
+		*addr >>= nor->shift;
+		break;
+	default:
+		debug("spi-nor: Unsupported dual_flash=%d\n", nor->dual);
+		break;
+	}
+}
+#endif
+
+#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)
+{
+	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+	int shift = ffs(mask) - 1;
+	int pow;
+
+	if (!(sr & mask)) {
+		/* No protection */
+		*ofs = 0;
+		*len = 0;
+	} else {
+		pow = ((sr & mask) ^ mask) >> shift;
+		*len = flash->size >> pow;
+		*ofs = flash->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)
+{
+	loff_t lock_offs;
+	u32 lock_len;
+
+	stm_get_locked_range(nor, sr, &lock_offs, &lock_len);
+
+	return (ofs + len <= lock_offs + lock_len) && (ofs >= lock_offs);
+}
+
+/*
+ * 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:
+ *   - TB: top/bottom protect - only handle TB=0 (top protect)
+ *   - SEC: sector/block protect - only handle SEC=0 (block protect)
+ *   - CMP: complement protect - only support CMP=0 (range is not complemented)
+ *
+ * Sample table portion for 8MB flash (Winbond w25q64fw):
+ *
+ *   SEC  |  TB   |  BP2  |  BP1  |  BP0  |  Prot Length  | Protected Portion
+ *  --------------------------------------------------------------------------
+ *    X   |   X   |   0   |   0   |   0   |  NONE         | NONE
+ *    0   |   0   |   0   |   0   |   1   |  128 KB       | Upper 1/64
+ *    0   |   0   |   0   |   1   |   0   |  256 KB       | Upper 1/32
+ *    0   |   0   |   0   |   1   |   1   |  512 KB       | Upper 1/16
+ *    0   |   0   |   1   |   0   |   0   |  1 MB         | Upper 1/8
+ *    0   |   0   |   1   |   0   |   1   |  2 MB         | Upper 1/4
+ *    0   |   0   |   1   |   1   |   0   |  4 MB         | Upper 1/2
+ *    X   |   X   |   1   |   1   |   1   |  8 MB         | ALL
+ *
+ * Returns negative on errors, 0 on success.
+ */
+static int stm_lock(struct spi_nor *nor, u32 ofs, size_t len)
+{
+	u8 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)
+		return status_old;
+
+	/* SPI NOR always locks to the end */
+	if (ofs + len != flash->size) {
+		/* Does combined region extend to end? */
+		if (!stm_is_locked_sr(nor, ofs + len, flash->size - ofs - len,
+				      status_old))
+			return -EINVAL;
+		len = flash->size - ofs;
+	}
+
+	/*
+	 * Need smallest pow such that:
+	 *
+	 *   1 / (2^pow) <= (len / size)
+	 *
+	 * so (assuming power-of-2 size) we do:
+	 *
+	 *   pow = ceil(log2(size / len)) = log2(size) - floor(log2(len))
+	 */
+	pow = ilog2(flash->size) - ilog2(len);
+	val = mask - (pow << shift);
+	if (val & ~mask)
+		return -EINVAL;
+
+	/* Don't "lock" with no region! */
+	if (!(val & mask))
+		return -EINVAL;
+
+	status_new = (status_old & ~mask) | val;
+
+	/* Only modify protection if it will not unlock other areas */
+	if ((status_new & mask) <= (status_old & mask))
+		return -EINVAL;
+
+	write_enable(nor);
+	return write_sr(nor, status_new);
+}
+
+/*
+ * Unlock a region of the flash. See stm_lock() for more info
+ *
+ * Returns negative on errors, 0 on success.
+ */
+static int stm_unlock(struct spi_nor *nor, u32 ofs, size_t len)
+{
+	uint8_t 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)
+		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))
+		return -EINVAL;
+	/*
+	 * Need largest pow such that:
+	 *
+	 *   1 / (2^pow) >= (len / size)
+	 *
+	 * so (assuming power-of-2 size) we do:
+	 *
+	 *   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) {
+		val = 0; /* fully unlocked */
+	} else {
+		val = mask - (pow << shift);
+		/* Some power-of-two sizes are not supported */
+		if (val & ~mask)
+			return -EINVAL;
+	}
+
+	status_new = (status_old & ~mask) | val;
+
+	/* Only modify protection if it will not lock other areas */
+	if ((status_new & mask) >= (status_old & mask))
+		return -EINVAL;
+
+	write_enable(nor);
+	return write_sr(nor, status_new);
+}
+#endif
+
+static const struct spi_nor_info *spi_nor_id(struct spi_nor *nor)
+{
+	int				tmp;
+	u8				id[SPI_NOR_MAX_ID_LEN];
+	const struct spi_nor_info	*info;
+
+	tmp = nor->read_reg(nor, SNOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
+	if (tmp < 0) {
+		printf("spi-nor: error %d reading JEDEC ID\n", tmp);
+		return ERR_PTR(tmp);
+	}
+
+	info = spi_nor_ids;
+	for (; info->name != NULL; info++) {
+		if (info->id_len) {
+			if (!memcmp(info->id, id, info->id_len))
+				return info;
+		}
+	}
+
+	printf("spi-nor: unrecognized JEDEC id bytes: %02x, %2x, %2x\n",
+	       id[0], id[1], id[2]);
+	return ERR_PTR(-ENODEV);
+}
+
+static int spi_nor_erase(struct spi_flash *flash, u32 offset, size_t len)
+{
+	struct spi_nor *nor = flash->nor;
+	u32 erase_size, erase_addr;
+	u8 cmd[SNOR_MAX_CMD_SIZE];
+	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;
+	}
+
+	if (flash->flash_is_locked) {
+		if (flash->flash_is_locked(flash, offset, len) > 0) {
+			printf("offset 0x%x is protected and cannot be erased\n",
+			       offset);
+			return -EINVAL;
+		}
+	}
+
+	cmd[0] = flash->erase_opcode;
+	while (len) {
+		erase_addr = offset;
+
+#ifdef CONFIG_SF_DUAL_FLASH
+		if (nor->dual > SNOR_DUAL_SINGLE)
+			spi_nor_dual(nor, &erase_addr);
+#endif
+#ifdef CONFIG_SPI_FLASH_BAR
+		ret = spi_nor_write_bar(nor, erase_addr);
+		if (ret < 0)
+			return ret;
+#endif
+		spi_nor_addr(erase_addr, cmd);
+
+		debug("spi-nor: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
+		      cmd[2], cmd[3], erase_addr);
+
+		write_enable(nor);
+
+		ret = nor->write(nor, cmd, sizeof(cmd), NULL, 0);
+		if (ret < 0)
+			break;
+
+		ret = spi_nor_wait_till_ready(nor, SNOR_READY_WAIT_ERASE);
+		if (ret < 0)
+			return ret;
+
+		offset += erase_size;
+		len -= erase_size;
+	}
+
+	return ret;
+}
+
+int spi_nor_write(struct spi_flash *flash, u32 offset,
+		  size_t len, const void *buf)
+{
+	struct spi_nor *nor = flash->nor;
+	unsigned long byte_addr, page_size;
+	u32 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",
+			       offset);
+			return -EINVAL;
+		}
+	}
+
+	cmd[0] = nor->program_opcode;
+	for (actual = 0; actual < len; actual += chunk_len) {
+		write_addr = offset;
+
+#ifdef CONFIG_SF_DUAL_FLASH
+		if (nor->dual > SNOR_DUAL_SINGLE)
+			spi_nor_dual(nor, &write_addr);
+#endif
+#ifdef CONFIG_SPI_FLASH_BAR
+		ret = spi_nor_write_bar(nor, write_addr);
+		if (ret < 0)
+			return ret;
+#endif
+		byte_addr = offset % page_size;
+		chunk_len = min(len - actual, (size_t)(page_size - byte_addr));
+
+		if (nor->max_write_size)
+			chunk_len = min(chunk_len,
+					(size_t)nor->max_write_size);
+
+		spi_nor_addr(write_addr, cmd);
+
+		debug("spi-nor: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
+		      buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
+
+		write_enable(nor);
+
+		ret = nor->write(nor, cmd, sizeof(cmd),
+				 buf + actual, chunk_len);
+		if (ret < 0)
+			break;
+
+		ret = spi_nor_wait_till_ready(nor, SNOR_READY_WAIT_PROG);
+		if (ret < 0)
+			return ret;
+
+		offset += chunk_len;
+	}
+
+	return ret;
+}
+
+int spi_nor_read(struct spi_flash *flash, u32 offset, size_t len, void *data)
+{
+	struct spi_nor *nor = flash->nor;
+	u32 remain_len, read_len, read_addr;
+	u8 *cmd, cmdsz;
+	int bank_sel = 0;
+	int ret = -1;
+
+	/* Handle memory-mapped SPI */
+	if (nor->memory_map) {
+		ret = nor->read_mmap(nor, data, nor->memory_map + offset, len);
+		if (ret) {
+			debug("spi-nor: mmap read failed\n");
+			return ret;
+		}
+
+		return ret;
+	}
+
+	cmdsz = SNOR_MAX_CMD_SIZE + nor->read_dummy;
+	cmd = calloc(1, cmdsz);
+	if (!cmd) {
+		debug("spi-nor: Failed to allocate cmd\n");
+		return -ENOMEM;
+	}
+
+	cmd[0] = nor->read_opcode;
+	while (len) {
+		read_addr = offset;
+
+#ifdef CONFIG_SF_DUAL_FLASH
+		if (nor->dual > SNOR_DUAL_SINGLE)
+			spi_nor_dual(nor, &read_addr);
+#endif
+#ifdef CONFIG_SPI_FLASH_BAR
+		ret = spi_nor_write_bar(nor, read_addr);
+		if (ret < 0)
+			return ret;
+		bank_sel = nor->bank_curr;
+#endif
+		remain_len = ((SNOR_16MB_BOUN << nor->shift) *
+				(bank_sel + 1)) - offset;
+		if (len < remain_len)
+			read_len = len;
+		else
+			read_len = remain_len;
+
+		spi_nor_addr(read_addr, cmd);
+
+		ret = nor->read(nor, cmd, cmdsz, data, read_len);
+		if (ret < 0)
+			break;
+
+		offset += read_len;
+		len -= read_len;
+		data += read_len;
+	}
+
+	free(cmd);
+	return ret;
+}
+
+#ifdef CONFIG_SPI_FLASH_SST
+static int sst_byte_write(struct spi_nor *nor, u32 offset, const void *buf)
+{
+	int ret;
+	u8 cmd[4] = {
+		SNOR_OP_BP,
+		offset >> 16,
+		offset >> 8,
+		offset,
+	};
+
+	debug("spi-nor: 0x%p => cmd = { 0x%02x 0x%06x }\n",
+	      buf, cmd[0], offset);
+
+	ret = write_enable(nor);
+	if (ret)
+		return ret;
+
+	ret = nor->write(nor, cmd, sizeof(cmd), buf, 1);
+	if (ret)
+		return ret;
+
+	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)
+{
+	struct spi_nor *nor = flash->nor;
+	size_t actual, cmd_len;
+	int ret;
+	u8 cmd[4];
+
+	/* If the data is not word aligned, write out leading single byte */
+	actual = offset % 2;
+	if (actual) {
+		ret = sst_byte_write(nor, offset, buf);
+		if (ret)
+			goto done;
+	}
+	offset += actual;
+
+	ret = write_enable(nor);
+	if (ret)
+		goto done;
+
+	cmd_len = 4;
+	cmd[0] = SNOR_OP_AAI_WP;
+	cmd[1] = offset >> 16;
+	cmd[2] = offset >> 8;
+	cmd[3] = offset;
+
+	for (; actual < len - 1; actual += 2) {
+		debug("spi-nor: 0x%p => cmd = { 0x%02x 0x%06x }\n",
+		      buf + actual, cmd[0], offset);
+
+		ret = nor->write(nor, cmd, cmd_len, buf + actual, 2);
+		if (ret) {
+			debug("spi-nor: sst word program failed\n");
+			break;
+		}
+
+		ret = spi_nor_wait_till_ready(nor, SNOR_READY_WAIT_PROG);
+		if (ret)
+			break;
+
+		cmd_len = 1;
+		offset += 2;
+	}
+
+	if (!ret)
+		ret = write_disable(nor);
+
+	/* If there is a single trailing byte, write it out */
+	if (!ret && actual != len)
+		ret = sst_byte_write(nor, offset, buf + actual);
+
+ done:
+	return ret;
+}
+
+int sst_write_bp(struct spi_nor *nor, u32 offset, size_t len, const void *buf)
+{
+	struct spi_nor *nor = flash->nor;
+	size_t actual;
+	int ret;
+
+	for (actual = 0; actual < len; actual++) {
+		ret = sst_byte_write(nor, offset, buf + actual);
+		if (ret) {
+			debug("spi-nor: sst byte program failed\n");
+			break;
+		}
+		offset++;
+	}
+
+	if (!ret)
+		ret = write_disable(nor);
+
+	return ret;
+}
+#endif
+
+#ifdef CONFIG_SPI_FLASH_MACRONIX
+static int macronix_quad_enable(struct spi_nor *nor)
+{
+	int ret, val;
+
+	val = read_sr(nor);
+	if (val < 0)
+		return val;
+
+	if (val & SR_QUAD_EN_MX)
+		return 0;
+
+	write_enable(nor);
+
+	ret = write_sr(nor, val | SR_QUAD_EN_MX);
+	if (ret < 0)
+		return ret;
+
+	if (spi_nor_wait_till_ready(nor, SNOR_READY_WAIT_PROG))
+		return 1;
+
+	ret = read_sr(nor);
+	if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
+		printf("spi-nor: Macronix Quad bit not set\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#endif
+
+#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND)
+static int spansion_quad_enable(struct spi_nor *nor)
+{
+	int ret, val;
+
+	val = read_cr(nor);
+	if (val < 0)
+		return val;
+
+	if (val & CR_QUAD_EN_SPAN)
+		return 0;
+
+	write_enable(nor);
+
+	ret = write_sr_cr(nor, val | CR_QUAD_EN_SPAN);
+	if (ret < 0)
+		return ret;
+
+	if (spi_nor_wait_till_ready(nor, SNOR_READY_WAIT_PROG))
+		return 1;
+
+	/* read back and check it */
+	ret = read_cr(nor);
+	if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
+		printf("spi-nor: Spansion Quad bit not set\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_SPI_FLASH_STMICRO
+static int micron_quad_enable(struct spi_nor *nor)
+{
+	int ret, val;
+
+	val = read_evcr(nor);
+	if (val < 0)
+		return val;
+
+	if (!(val & EVCR_QUAD_EN_MICRON))
+		return 0;
+
+	ret = write_evcr(nor, val & ~EVCR_QUAD_EN_MICRON);
+	if (ret < 0)
+		return ret;
+
+	/* read EVCR and check it */
+	ret = read_evcr(nor);
+	if (!(ret > 0 && !(ret & EVCR_QUAD_EN_MICRON))) {
+		printf("spi-nor: Micron EVCR Quad bit not clear\n");
+		return -EINVAL;
+	}
+
+	return ret;
+}
+#endif
+
+static int set_quad_mode(struct spi_nor *nor, const struct spi_nor_info *info)
+{
+	switch (JEDEC_MFR(info)) {
+#ifdef CONFIG_SPI_FLASH_MACRONIX
+	case SNOR_MFR_MACRONIX:
+		return macronix_quad_enable(nor);
+#endif
+#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND)
+	case SNOR_MFR_SPANSION:
+	case SNOR_MFR_WINBOND:
+		return spansion_quad_enable(nor);
+#endif
+#ifdef CONFIG_SPI_FLASH_STMICRO
+	case SNOR_MFR_MICRON:
+		return micron_quad_enable(nor);
+#endif
+	default:
+		printf("spi-nor: Need set QEB func for %02x flash\n",
+		       JEDEC_MFR(info));
+		return -1;
+	}
+}
+
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+int spi_nor_decode_fdt(const void *blob, struct spi_nor *nor)
+{
+	fdt_addr_t addr;
+	fdt_size_t size;
+	int node;
+
+	/* If there is no node, do nothing */
+	node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH);
+	if (node < 0)
+		return 0;
+
+	addr = fdtdec_get_addr_size(blob, node, "memory-map", &size);
+	if (addr == FDT_ADDR_T_NONE) {
+		debug("%s: Cannot decode address\n", __func__);
+		return 0;
+	}
+
+	if (flash->size != size) {
+		debug("%s: Memory map must cover entire device\n", __func__);
+		return -1;
+	}
+	nor->memory_map = map_sysmem(addr, size);
+
+	return 0;
+}
+#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */
+
+static int spi_nor_check(struct spi_nor *nor)
+{
+	if (!nor->read || !nor->write ||
+	    !nor->read_reg || !nor->write_reg) {
+		pr_err("spi-nor: please fill all the necessary fields!\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int spi_nor_scan(struct spi_nor *nor)
+{
+	const struct spi_nor_info *info = NULL;
+	static u8 flash_read_cmd[] = {
+		SNOR_OP_READ,
+		SNOR_OP_READ_FAST,
+		SNOR_OP_READ_1_1_2,
+		SNOR_OP_READ_1_1_4,
+		SNOR_OP_READ_1_1_2_IO,
+		SNOR_OP_READ_1_1_4_IO };
+	u8 cmd;
+	int ret;
+
+	ret = spi_nor_check(nor);
+	if (ret)
+		return ret;
+
+	info = spi_nor_id(nor);
+	if (IS_ERR_OR_NULL(info))
+		return -ENOENT;
+
+	/*
+	 * Atmel, SST, Macronix, and others serial NOR tend to power up
+	 * with the software protection bits set
+	 */
+	if (JEDEC_MFR(info) == SNOR_MFR_ATMEL ||
+	    JEDEC_MFR(info) == SNOR_MFR_MACRONIX ||
+	    JEDEC_MFR(info) == SNOR_MFR_SST) {
+		write_enable(nor);
+		write_sr(nor, 0);
+	}
+
+	flash->name = info->name;
+
+	if (info->flags & USE_FSR)
+		nor->flags |= SNOR_F_USE_FSR;
+
+	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;
+#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;
+		else
+			flash->write = sst_write_wp;
+	}
+#endif
+
+#if defined(CONFIG_SPI_FLASH_STMICRO) || defined(CONFIG_SPI_FLASH_SST)
+	/* NOR protection support for STmicro/Micron chips and similar */
+	if (JEDEC_MFR(info) == SNOR_MFR_MICRON ||
+	    JEDEC_MFR(info) == SNOR_MFR_SST) {
+		nor->flash_lock = stm_lock;
+		nor->flash_unlock = stm_unlock;
+		nor->flash_is_locked = stm_is_locked;
+	}
+#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;
+	}
+
+	/* Compute the flash size */
+	nor->shift = (nor->dual & SNOR_DUAL_PARALLEL) ? 1 : 0;
+	nor->page_size = info->page_size;
+	/*
+	 * The Spansion S25FL032P and S25FL064P have 256b pages, yet use the
+	 * 0x4d00 Extended JEDEC code. The rest of the Spansion flashes with
+	 * the 0x4d00 Extended JEDEC code have 512b pages. All of the others
+	 * have 256b pages.
+	 */
+	if (JEDEC_EXT(info) == 0x4d00) {
+		if ((JEDEC_ID(info) != 0x0215) &&
+		    (JEDEC_ID(info) != 0x0216))
+			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;
+#ifdef CONFIG_SF_DUAL_FLASH
+	if (nor->dual & SNOR_DUAL_STACKED)
+		flash->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;
+	} else if (info->flags & SECT_4K_PMC) {
+		nor->erase_opcode = SNOR_OP_BE_4K_PMC;
+		nor->erase_size = 4096;
+	} else
+#endif
+	{
+		nor->erase_opcode = SNOR_OP_SE;
+		nor->erase_size = flash->sector_size;
+	}
+
+	/* Now erase size becomes valid sector size */
+	flash->sector_size = nor->erase_size;
+
+	/* Look for the fastest read cmd */
+	cmd = fls(info->flash_read & nor->read_mode);
+	if (cmd) {
+		cmd = flash_read_cmd[cmd - 1];
+		nor->read_opcode = cmd;
+	} else {
+		/* Go for default supported read cmd */
+		nor->read_opcode = SNOR_OP_READ_FAST;
+	}
+
+	/* 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;
+	else
+		/* Go for default supported write cmd */
+		nor->program_opcode = SNOR_OP_PP;
+
+	/* Set the quad enable bit - only for quad commands */
+	if ((nor->read_opcode == SNOR_OP_READ_1_1_4) ||
+	    (nor->read_opcode == SNOR_OP_READ_1_1_4_IO) ||
+	    (nor->program_opcode == SNOR_OP_QPP)) {
+		ret = set_quad_mode(nor, info);
+		if (ret) {
+			debug("spi-nor: quad mode not supported for %02x\n",
+			      JEDEC_MFR(info));
+			return ret;
+		}
+	}
+
+	/* read_dummy: dummy byte is determined based on the
+	 * dummy cycles of a particular command.
+	 * Fast commands - read_dummy = dummy_cycles/8
+	 * I/O commands- read_dummy = (dummy_cycles * no.of lines)/8
+	 * For I/O commands except cmd[0] everything goes on no.of lines
+	 * based on particular command but incase of fast commands except
+	 * data all go on single line irrespective of command.
+	 */
+	switch (nor->read_opcode) {
+	case SNOR_OP_READ_1_1_4_IO:
+		nor->read_dummy = 2;
+		break;
+	case SNOR_OP_READ:
+		nor->read_dummy = 0;
+		break;
+	default:
+		nor->read_dummy = 1;
+	}
+
+	/* Configure the BAR - discover bank cmds and read current bank */
+#ifdef CONFIG_SPI_FLASH_BAR
+	ret = spi_nor_read_bar(nor, info);
+	if (ret < 0)
+		return ret;
+#endif
+
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+	ret = spi_nor_decode_fdt(gd->fdt_blob, nor);
+	if (ret) {
+		debug("spi-nor: FDT decode error\n");
+		return -EINVAL;
+	}
+#endif
+
+#ifndef CONFIG_SPL_BUILD
+	printf("spi-nor: detected %s with page size ", flash->name);
+	print_size(nor->page_size, ", erase size ");
+	print_size(nor->erase_size, ", total ");
+	print_size(flash->size, "");
+	if (nor->memory_map)
+		printf(", mapped at %p", nor->memory_map);
+	puts("\n");
+#endif
+
+#ifndef CONFIG_SPI_FLASH_BAR
+	if (((nor->dual == SNOR_DUAL_SINGLE) &&
+	     (flash->size > SNOR_16MB_BOUN)) ||
+	     ((nor->dual > SNOR_DUAL_SINGLE) &&
+	     (flash->size > SNOR_16MB_BOUN << 1))) {
+		puts("spi-nor: Warning - Only lower 16MiB accessible,");
+		puts(" Full access #define CONFIG_SPI_FLASH_BAR\n");
+	}
+#endif
+
+	return ret;
+}
diff --git a/include/linux/err.h b/include/linux/err.h
index 5b3c8bc..1bba498 100644
--- a/include/linux/err.h
+++ b/include/linux/err.h
@@ -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.
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
new file mode 100644
index 0000000..664c9ae
--- /dev/null
+++ b/include/linux/mtd/spi-nor.h
@@ -0,0 +1,251 @@
+/*
+ * SPI NOR Core header file.
+ *
+ * Copyright (C) 2016 Jagan Teki <jteki@openedev.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __MTD_SPI_NOR_H
+#define __MTD_SPI_NOR_H
+
+#include <linux/bitops.h>
+#include <linux/types.h>
+
+/*
+ * Manufacturer IDs
+ *
+ * The first byte returned from the flash after sending opcode SPINOR_OP_RDID.
+ * Sometimes these are the same as CFI IDs, but sometimes they aren't.
+ */
+#define SNOR_MFR_ATMEL		0x1f
+#define SNOR_MFR_MACRONIX	0xc2
+#define SNOR_MFR_MICRON		0x20	/* ST Micro <--> Micron */
+#define SNOR_MFR_SPANSION	0x01
+#define SNOR_MFR_SST		0xbf
+#define SNOR_MFR_WINBOND	0xef
+
+/**
+ * SPI NOR opcodes.
+ *
+ * Note on opcode nomenclature: some opcodes have a format like
+ * SNOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number
+ * of I/O lines used for the opcode, address, and data (respectively). The
+ * FUNCTION has an optional suffix of '4', to represent an opcode which
+ * requires a 4-byte (32-bit) address.
+ */
+#define SNOR_OP_WRDI		0x04	/* Write disable */
+#define SNOR_OP_WREN		0x06	/* Write enable */
+#define SNOR_OP_RDSR		0x05	/* Read status register */
+#define SNOR_OP_WRSR		0x01	/* Write status register 1 byte */
+#define SNOR_OP_READ		0x03	/* Read data bytes (low frequency) */
+#define SNOR_OP_READ_FAST	0x0b	/* Read data bytes (high frequency) */
+#define SNOR_OP_READ_1_1_2	0x3b	/* Read data bytes (Dual SPI) */
+#define SNOR_OP_READ_1_1_2_IO	0xbb	/* Read data bytes (Dual IO SPI) */
+#define SNOR_OP_READ_1_1_4	0x6b	/* Read data bytes (Quad SPI) */
+#define SNOR_OP_READ_1_1_4_IO	0xeb	/* Read data bytes (Quad IO SPI) */
+#define SNOR_OP_BRWR		0x17	/* Bank register write */
+#define SNOR_OP_BRRD		0x16	/* Bank register read */
+#define SNOR_OP_WREAR		0xC5	/* Write extended address register */
+#define SNOR_OP_RDEAR		0xC8	/* Read extended address register */
+#define SNOR_OP_PP		0x02	/* Page program (up to 256 bytes) */
+#define SNOR_OP_QPP		0x32	/* Quad Page program */
+#define SNOR_OP_BE_4K		0x20	/* Erase 4KiB block */
+#define SNOR_OP_BE_4K_PMC	0xd7    /* Erase 4KiB block on PMC chips */
+#define SNOR_OP_SE		0xd8	/* Sector erase (usually 64KiB) */
+#define SNOR_OP_RDID		0x9f	/* Read JEDEC ID */
+#define SNOR_OP_RDCR		0x35	/* Read configuration register */
+#define SNOR_OP_RDFSR		0x70	/* Read flag status register */
+
+/* Used for SST flashes only. */
+#define SNOR_OP_BP		0x02	/* Byte program */
+#define SNOR_OP_AAI_WP		0xad	/* Auto addr increment word program */
+
+/* Used for Micron flashes only. */
+#define SPINOR_OP_RD_EVCR      0x65    /* Read EVCR register */
+#define SPINOR_OP_WD_EVCR      0x61    /* Write EVCR register */
+
+/* Status Register bits. */
+#define SR_WIP			BIT(0)	/* Write in progress */
+#define SR_WEL			BIT(1)	/* Write enable latch */
+
+/* meaning of other SR_* bits may differ between vendors */
+#define SR_BP0			BIT(2)	/* Block protect 0 */
+#define SR_BP1			BIT(3)	/* Block protect 1 */
+#define SR_BP2			BIT(4)	/* Block protect 2 */
+#define SR_SRWD			BIT(7)	/* SR write protect */
+
+#define SR_QUAD_EN_MX		BIT(6)	/* Macronix Quad I/O */
+
+/* Enhanced Volatile Configuration Register bits */
+#define EVCR_QUAD_EN_MICRON	BIT(7)	/* Micron Quad I/O */
+
+/* Flag Status Register bits */
+#define FSR_READY		BIT(7)
+
+/* Configuration Register bits. */
+#define CR_QUAD_EN_SPAN		BIT(1)	/* Spansion/Winbond Quad I/O */
+
+/* Flash timeout values */
+#define SNOR_READY_WAIT_PROG	(2 * CONFIG_SYS_HZ)
+#define SNOR_READY_WAIT_ERASE	(5 * CONFIG_SYS_HZ)
+#define SNOR_MAX_CMD_SIZE	4	/* opcode + 3-byte address */
+#define SNOR_16MB_BOUN		0x1000000
+
+enum snor_dual {
+	SNOR_DUAL_SINGLE	= 0,
+	SNOR_DUAL_STACKED	= BIT(0),
+	SNOR_DUAL_PARALLEL	= BIT(1),
+};
+
+enum snor_option_flags {
+	SNOR_F_SST_WRITE	= BIT(0),
+	SNOR_F_USE_FSR		= BIT(1),
+	SNOR_F_U_PAGE		= BIT(1),
+};
+
+enum write_mode {
+	SNOR_WRITE_1_1_BYTE	= BIT(0),
+	SNOR_WRITE_1_1_4	= BIT(1),
+};
+
+enum read_mode {
+	SNOR_READ		= BIT(0),
+	SNOR_READ_FAST		= BIT(1),
+	SNOR_READ_1_1_2		= BIT(2),
+	SNOR_READ_1_1_4		= BIT(3),
+	SNOR_READ_1_1_2_IO	= BIT(4),
+	SNOR_READ_1_1_4_IO	= BIT(5),
+};
+
+#define SNOR_READ_BASE		(SNOR_READ | SNOR_READ_FAST)
+#define SNOR_READ_FULL		(SNOR_READ_BASE | SNOR_READ_1_1_2 | \
+				 SNOR_READ_1_1_4 | SNOR_READ_1_1_2_IO | \
+				 SNOR_READ_1_1_4_IO)
+
+#define JEDEC_MFR(info)		((info)->id[0])
+#define JEDEC_ID(info)		(((info)->id[1]) << 8 | ((info)->id[2]))
+#define JEDEC_EXT(info)		(((info)->id[3]) << 8 | ((info)->id[4]))
+#define SPI_NOR_MAX_ID_LEN	6
+
+struct spi_nor_info {
+	char		*name;
+
+	/*
+	 * This array stores the ID bytes.
+	 * The first three bytes are the JEDIC ID.
+	 * JEDEC ID zero means "no ID" (mostly older chips).
+	 */
+	u8		id[SPI_NOR_MAX_ID_LEN];
+	u8		id_len;
+
+	/* The size listed here is what works with SNOR_OP_SE, which isn't
+	 * necessarily called a "sector" by the vendor.
+	 */
+	unsigned	sector_size;
+	u16		n_sectors;
+
+	u16		page_size;
+	u16		addr_width;
+
+	/* Enum list for read modes */
+	enum read_mode	flash_read;
+
+	u16		flags;
+#define	SECT_4K			BIT(0)	/* SNOR_OP_BE_4K works uniformly */
+#define	SPI_NOR_NO_ERASE	BIT(1)	/* No erase command needed */
+#define	SST_WRITE		BIT(2)	/* use SST byte programming */
+#define	SPI_NOR_NO_FR		BIT(3)	/* Can't do fastread */
+#define	SECT_4K_PMC		BIT(4)	/* SNOR_OP_BE_4K_PMC works uniformly */
+#define	USE_FSR			BIT(5)	/* use flag status register */
+#define SNOR_WRITE_QUAD		BIT(6)	/* Flash supports Quad Read */
+};
+
+extern const struct spi_nor_info spi_nor_ids[];
+
+/**
+ * struct spi_nor - Structure for defining a the SPI NOR layer
+ *
+ * @mtd:		point to a mtd_info structure
+ * @name:		name of the SPI NOR device
+ * @page_size:		the page size of the SPI NOR
+ * @erase_opcode:	the opcode for erasing a sector
+ * @read_opcode:	the read opcode
+ * @read_dummy:		the dummy bytes needed by the read operation
+ * @program_opcode:	the program opcode
+ * @bar_read_opcode:	the read opcode for bank/extended address registers
+ * @bar_program_opcode:	the program opcode for bank/extended address registers
+ * @bar_curr:		indicates current flash bank
+ * @dual:		indicates dual flash memories - dual stacked, parallel
+ * @shift:		flash shift useful in dual parallel
+ * @max_write_size:	If non-zero, the maximum number of bytes which can
+ *			be written at once, excluding command bytes.
+ * @flags:		flag options for the current SPI-NOR (SNOR_F_*)
+ * @mode:		write mode or any other mode bits.
+ * @read_mode:		read mode.
+ * @cmd_buf:		used by the write_reg
+ * @read_reg:		[DRIVER-SPECIFIC] read out the register
+ * @write_reg:		[DRIVER-SPECIFIC] write data to the register
+ * @read_mmap:		[DRIVER-SPECIFIC] read data from the mmapped SPI NOR
+ * @read:		[DRIVER-SPECIFIC] read data from the SPI NOR
+ * @write:		[DRIVER-SPECIFIC] write data to the SPI NOR
+ * @flash_lock:		[FLASH-SPECIFIC] lock a region of the SPI NOR
+ * @flash_unlock:	[FLASH-SPECIFIC] unlock a region of the SPI NOR
+ * @flash_is_locked:	[FLASH-SPECIFIC] check if a region of the SPI NOR is
+ * @memory_map:		address of read-only SPI NOR access
+ * @priv:		the private data
+ */
+struct spi_nor {
+	struct mtd_info		*mtd;
+	const char		*name;
+	u32			page_size;
+	u8			erase_opcode;
+	u8			read_opcode;
+	u8			read_dummy;
+	u8			program_opcode;
+#ifdef CONFIG_SPI_FLASH_BAR
+	u8			bar_read_opcode;
+	u8			bar_program_opcode;
+	u8			bank_curr;
+#endif
+	u8			dual;
+	u8			shift;
+	u32			max_write_size;
+	u32			flags;
+	u8			mode;
+	u8			read_mode;
+	u8			cmd_buf[SNOR_MAX_CMD_SIZE];
+
+	int (*read_reg)(struct spi_nor *nor, u8 cmd, u8 *val, int len);
+	int (*write_reg)(struct spi_nor *nor, u8 cmd, u8 *data, int len);
+
+	int (*read_mmap)(struct spi_nor *nor, void *data, void *offset,
+			size_t len);
+	int (*read)(struct spi_nor *nor, const u8 *opcode, size_t cmd_len,
+			void *data, size_t data_len);
+	int (*write)(struct spi_nor *nor, const u8 *cmd, size_t cmd_len,
+			const void *data, size_t data_len);
+
+	int (*flash_lock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
+	int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
+	int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len);
+
+	void *memory_map;
+	void *priv;
+};
+
+/**
+ * spi_nor_scan() - scan the SPI NOR
+ * @nor:	the spi_nor structure
+ *
+ * The drivers can use this fuction to scan the SPI NOR.
+ * In the scanning, it will try to get all the necessary information to
+ * fill the mtd_info{} and the spi_nor{}.
+ *
+ * The chip type name can be provided through the @name parameter.
+ *
+ * Return: 0 for success, others for failure.
+ */
+int spi_nor_scan(struct spi_nor *nor);
+
+#endif /* __MTD_SPI_NOR_H */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 04/32] doc: device-tree-bindings: jedec, spi-nor
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (2 preceding siblings ...)
  2016-02-10 19:07 ` [U-Boot] [PATCH v5 03/32] mtd: Add SPI-NOR core support Jagan Teki
@ 2016-02-10 19:07 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 05/32] mtd: spi-nor: Add Kconfig entry for MTD_SPI_NOR Jagan Teki
                   ` (27 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:07 UTC (permalink / raw)
  To: u-boot

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

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 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

diff --git a/doc/device-tree-bindings/mtd/jedec,spi-nor.txt b/doc/device-tree-bindings/mtd/jedec,spi-nor.txt
new file mode 100644
index 0000000..2c91c03
--- /dev/null
+++ b/doc/device-tree-bindings/mtd/jedec,spi-nor.txt
@@ -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;
+	};
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 05/32] mtd: spi-nor: Add Kconfig entry for MTD_SPI_NOR
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (3 preceding siblings ...)
  2016-02-10 19:07 ` [U-Boot] [PATCH v5 04/32] doc: device-tree-bindings: jedec, spi-nor Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 06/32] mtd: spi-nor: Add kconfig for MTD_SPI_NOR_USE_4K_SECTORS Jagan Teki
                   ` (26 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

Added kconfig entry for MTD_SPI_NOR

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 drivers/mtd/spi-nor/Kconfig | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index d32486c..f0ea9f9 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 06/32] mtd: spi-nor: Add kconfig for MTD_SPI_NOR_USE_4K_SECTORS
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (4 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 05/32] mtd: spi-nor: Add Kconfig entry for MTD_SPI_NOR Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 07/32] mtd: spi-nor: Add MTD support Jagan Teki
                   ` (25 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

Added kconfig entry for MTD_SPI_NOR_USE_4K_SECTORS.

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 drivers/mtd/spi-nor/Kconfig | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index f0ea9f9..374cdcb 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 07/32] mtd: spi-nor: Add MTD support
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (5 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 06/32] mtd: spi-nor: Add kconfig for MTD_SPI_NOR_USE_4K_SECTORS Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 08/32] mtd: spi-nor: Add spi_nor support in m25p80 Jagan Teki
                   ` (24 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

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 <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 273 +++++++++++++++++++++++++-----------------
 1 file changed, 165 insertions(+), 108 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index f142ae4..3b42b69 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -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");
 	}
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 08/32] mtd: spi-nor: Add spi_nor support in m25p80
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (6 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 07/32] mtd: spi-nor: Add MTD support Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 09/32] mtd: spi-nor: Add dm spi-nor probing Jagan Teki
                   ` (23 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

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 <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 drivers/mtd/spi-nor/m25p80.c | 236 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 236 insertions(+)

diff --git a/drivers/mtd/spi-nor/m25p80.c b/drivers/mtd/spi-nor/m25p80.c
index 833a9c3..57e54d0 100644
--- a/drivers/mtd/spi-nor/m25p80.c
+++ b/drivers/mtd/spi-nor/m25p80.c
@@ -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),
 };
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 09/32] mtd: spi-nor: Add dm spi-nor probing
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (7 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 08/32] mtd: spi-nor: Add spi_nor support in m25p80 Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 10/32] mtd: spi-nor: Add spi_flash_probe for mtd-dm-spi-nor Jagan Teki
                   ` (22 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

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 <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 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

diff --git a/cmd/sf.c b/cmd/sf.c
index 42862d9..e4d1274 100644
--- a/cmd/sf.c
+++ b/cmd/sf.c
@@ -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) {
diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index 374cdcb..59bb943 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -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
diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
index 9ab6e3d..71e7ae2 100644
--- a/drivers/mtd/spi-nor/Makefile
+++ b/drivers/mtd/spi-nor/Makefile
@@ -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
diff --git a/drivers/mtd/spi-nor/spi-nor-probe.c b/drivers/mtd/spi-nor/spi-nor-probe.c
new file mode 100644
index 0000000..c808a7d
--- /dev/null
+++ b/drivers/mtd/spi-nor/spi-nor-probe.c
@@ -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;
+}
diff --git a/include/spi_flash.h b/include/spi_flash.h
index d0ce9e7..a458820 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -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);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 10/32] mtd: spi-nor: Add spi_flash_probe for mtd-dm-spi-nor
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (8 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 09/32] mtd: spi-nor: Add dm spi-nor probing Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 11/32] cmd: sf: Add mtd_info for mtd-dm-spi-nor code Jagan Teki
                   ` (21 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

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 <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 drivers/mtd/spi-nor/spi-nor-probe.c | 15 +++++++++++++++
 include/spi_flash.h                 |  4 ++++
 2 files changed, 19 insertions(+)

diff --git a/drivers/mtd/spi-nor/spi-nor-probe.c b/drivers/mtd/spi-nor/spi-nor-probe.c
index c808a7d..9bc61ea 100644
--- a/drivers/mtd/spi-nor/spi-nor-probe.c
+++ b/drivers/mtd/spi-nor/spi-nor-probe.c
@@ -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)
diff --git a/include/spi_flash.h b/include/spi_flash.h
index a458820..1dcce13 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -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);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 11/32] cmd: sf: Add mtd_info for mtd-dm-spi-nor code
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (9 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 10/32] mtd: spi-nor: Add spi_flash_probe for mtd-dm-spi-nor Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 12/32] mtd: spi-nor: m25p80: Add spi_nor support for non-dm Jagan Teki
                   ` (20 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

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

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 cmd/sf.c            | 34 +++++++++++++++++-----------------
 include/spi_flash.h | 48 ++++++++++++++++++++++++++++++++++++------------
 2 files changed, 53 insertions(+), 29 deletions(-)

diff --git a/cmd/sf.c b/cmd/sf.c
index e4d1274..5dd7177 100644
--- a/cmd/sf.c
+++ b/cmd/sf.c
@@ -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;
diff --git a/include/spi_flash.h b/include/spi_flash.h
index 1dcce13..719a6e3 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -12,6 +12,7 @@
 
 #include <dm.h>	/* Because we dereference struct udevice here */
 #include <linux/types.h>
+#include <linux/mtd/mtd.h>
 
 #ifndef CONFIG_SF_DEFAULT_SPEED
 # define CONFIG_SF_DEFAULT_SPEED	1000000
@@ -192,6 +193,41 @@ void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs);
 
 #elif CONFIG_MTD_DM_SPI_NOR
 
+typedef struct mtd_info spi_flash_t;
+
+static inline int spi_flash_read(spi_flash_t *info, u32 offset,
+				 size_t len, void *buf)
+{
+	return mtd_read(info, offset, len, &len, (u_char *)buf);
+}
+
+static inline int spi_flash_write(spi_flash_t *info, u32 offset,
+				  size_t len, const void *buf)
+{
+	return mtd_write(info, offset, len, &len, (u_char *)buf);
+}
+
+static inline int spi_flash_erase(spi_flash_t *info, u32 offset, size_t len)
+{
+	struct erase_info instr;
+
+	instr.mtd = info;
+	instr.addr = offset;
+	instr.len = len;
+	instr.callback = 0;
+
+	return mtd_erase(info, &instr);
+}
+
+static inline int spi_flash_protect(spi_flash_t *info, u32 ofs,
+				    u32 len, bool prot)
+{
+	if (prot)
+		return mtd_lock(info, ofs, len);
+	else
+		return mtd_unlock(info, ofs, len);
+}
+
 int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
 			   unsigned int max_hz, unsigned int spi_mode,
 			   struct udevice **devp);
@@ -237,18 +273,6 @@ static inline int spi_flash_erase(struct spi_flash *flash, u32 offset,
 }
 #endif
 
-static inline int spi_flash_protect(struct spi_flash *flash, u32 ofs, u32 len,
-					bool prot)
-{
-	if (!flash->flash_lock || !flash->flash_unlock)
-		return -EOPNOTSUPP;
-
-	if (prot)
-		return flash->flash_lock(flash, ofs, len);
-	else
-		return flash->flash_unlock(flash, ofs, len);
-}
-
 void spi_boot(void) __noreturn;
 void spi_spl_load_image(uint32_t offs, unsigned int size, void *vdst);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 12/32] mtd: spi-nor: m25p80: Add spi_nor support for non-dm
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (10 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 11/32] cmd: sf: Add mtd_info for mtd-dm-spi-nor code Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 13/32] spi_flash: Use mtd_info operation " Jagan Teki
                   ` (19 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

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 <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 drivers/mtd/spi-nor/m25p80.c | 108 ++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 96 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/spi-nor/m25p80.c b/drivers/mtd/spi-nor/m25p80.c
index 57e54d0..f0340a5 100644
--- a/drivers/mtd/spi-nor/m25p80.c
+++ b/drivers/mtd/spi-nor/m25p80.c
@@ -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 */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 13/32] spi_flash: Use mtd_info operation for non-dm
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (11 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 12/32] mtd: spi-nor: m25p80: Add spi_nor support for non-dm Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 14/32] mtd: spi-nor: Move spi_read_then_write to spi layer Jagan Teki
                   ` (18 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

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 <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 include/spi_flash.h | 23 ++++-------------------
 1 file changed, 4 insertions(+), 19 deletions(-)

diff --git a/include/spi_flash.h b/include/spi_flash.h
index 719a6e3..77939bd 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -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);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 14/32] mtd: spi-nor: Move spi_read_then_write to spi layer
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (12 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 13/32] spi_flash: Use mtd_info operation " Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 15/32] spi: Rename spi_read_then_write to spi_write_then_read Jagan Teki
                   ` (17 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

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 <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 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(-)

diff --git a/drivers/mtd/spi-nor/m25p80.c b/drivers/mtd/spi-nor/m25p80.c
index f0340a5..4aefe93 100644
--- a/drivers/mtd/spi-nor/m25p80.c
+++ b/drivers/mtd/spi-nor/m25p80.c
@@ -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;
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 677c020..7728eac 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -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 */
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 7d81fbd..a050386 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -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)
diff --git a/include/spi.h b/include/spi.h
index 4b88d39..19589aa 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -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);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 15/32] spi: Rename spi_read_then_write to spi_write_then_read
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (13 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 14/32] mtd: spi-nor: Move spi_read_then_write to spi layer Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 16/32] spi: Drop mode_rx Jagan Teki
                   ` (16 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

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 <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 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(-)

diff --git a/drivers/mtd/spi-nor/m25p80.c b/drivers/mtd/spi-nor/m25p80.c
index 4aefe93..7e2702d 100644
--- a/drivers/mtd/spi-nor/m25p80.c
+++ b/drivers/mtd/spi-nor/m25p80.c
@@ -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;
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 7728eac..0dfdd8b 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -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;
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index a050386..c8051f9 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -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;
diff --git a/include/spi.h b/include/spi.h
index 19589aa..dd0b11b 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -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);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 16/32] spi: Drop mode_rx
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (14 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 15/32] spi: Rename spi_read_then_write to spi_write_then_read Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 17/32] spi: Drop SPI_RX_FAST Jagan Teki
                   ` (15 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

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 <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 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(-)

diff --git a/drivers/mtd/spi-nor/m25p80.c b/drivers/mtd/spi-nor/m25p80.c
index 7e2702d..58e879c 100644
--- a/drivers/mtd/spi-nor/m25p80.c
+++ b/drivers/mtd/spi-nor/m25p80.c
@@ -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;
diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index e543b8f..5f03508 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -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;
 }
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 0dfdd8b..ed6c771 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -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;
 }
diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c
index b5c974c..d9d65b4 100644
--- a/drivers/spi/ti_qspi.c
+++ b/drivers/spi/ti_qspi.c
@@ -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;
diff --git a/include/spi.h b/include/spi.h
index dd0b11b..61fefa4 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -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;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 17/32] spi: Drop SPI_RX_FAST
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (15 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 16/32] spi: Drop mode_rx Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 18/32] mtd: spi-nor: Rename SPI_FLASH_BAR to SPI_NOR_BAR Jagan Teki
                   ` (14 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

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 <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 include/spi.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/include/spi.h b/include/spi.h
index 61fefa4..9af2fbb 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -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)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 18/32] mtd: spi-nor: Rename SPI_FLASH_BAR to SPI_NOR_BAR
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (16 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 17/32] spi: Drop SPI_RX_FAST Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 19/32] mtd: spi-nor: Add Kconfig entry for SPI_NOR_BAR Jagan Teki
                   ` (13 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

Renamed SPI_FLASH_BAR to SPI_NOR_BAR

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 3b42b69..32d5cbc 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -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
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 19/32] mtd: spi-nor: Add Kconfig entry for SPI_NOR_BAR
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (17 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 18/32] mtd: spi-nor: Rename SPI_FLASH_BAR to SPI_NOR_BAR Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 20/32] mtd: spi-nor: Copy spl files from drivers/mtd/spi Jagan Teki
                   ` (12 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

Added kconfig entry for SPI_NOR_BAR

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 drivers/mtd/spi-nor/Kconfig | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index 59bb943..43f59b7 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 20/32] mtd: spi-nor: Copy spl files from drivers/mtd/spi
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (18 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 19/32] mtd: spi-nor: Add Kconfig entry for SPI_NOR_BAR Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 21/32] mtd: spi-nor: spl: Follow ascending order of include headers Jagan Teki
                   ` (11 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

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

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 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

diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
index 71e7ae2..4d27811 100644
--- a/drivers/mtd/spi-nor/Makefile
+++ b/drivers/mtd/spi-nor/Makefile
@@ -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
diff --git a/drivers/mtd/spi-nor/fsl_espi_spl.c b/drivers/mtd/spi-nor/fsl_espi_spl.c
new file mode 100644
index 0000000..b915469
--- /dev/null
+++ b/drivers/mtd/spi-nor/fsl_espi_spl.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <spi_flash.h>
+#include <malloc.h>
+
+#define ESPI_BOOT_IMAGE_SIZE	0x48
+#define ESPI_BOOT_IMAGE_ADDR	0x50
+#define CONFIG_CFG_DATA_SECTOR	0
+
+void spi_spl_load_image(uint32_t offs, unsigned int size, void *vdst)
+{
+	struct spi_flash *flash;
+
+	flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
+			CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
+	if (flash == NULL) {
+		puts("\nspi_flash_probe failed");
+		hang();
+	}
+
+	spi_flash_read(flash, offs, size, vdst);
+}
+
+/*
+ * The main entry for SPI booting. It's necessary that SDRAM is already
+ * configured and available since this code loads the main U-Boot image
+ * from SPI into SDRAM and starts it from there.
+ */
+void spi_boot(void)
+{
+	void (*uboot)(void) __noreturn;
+	u32 offset, code_len, copy_len = 0;
+#ifndef CONFIG_FSL_CORENET
+	unsigned char *buf = NULL;
+#endif
+	struct spi_flash *flash;
+
+	flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
+			CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
+	if (flash == NULL) {
+		puts("\nspi_flash_probe failed");
+		hang();
+	}
+
+#ifdef CONFIG_FSL_CORENET
+	offset = CONFIG_SYS_SPI_FLASH_U_BOOT_OFFS;
+	code_len = CONFIG_SYS_SPI_FLASH_U_BOOT_SIZE;
+#else
+	/*
+	* Load U-Boot image from SPI flash into RAM
+	*/
+	buf = malloc(flash->page_size);
+	if (buf == NULL) {
+		puts("\nmalloc failed");
+		hang();
+	}
+	memset(buf, 0, flash->page_size);
+
+	spi_flash_read(flash, CONFIG_CFG_DATA_SECTOR,
+		       flash->page_size, (void *)buf);
+	offset = *(u32 *)(buf + ESPI_BOOT_IMAGE_ADDR);
+	/* Skip spl code */
+	offset += CONFIG_SYS_SPI_FLASH_U_BOOT_OFFS;
+	/* Get the code size from offset 0x48 */
+	code_len = *(u32 *)(buf + ESPI_BOOT_IMAGE_SIZE);
+	/* Skip spl code */
+	code_len = code_len - CONFIG_SPL_MAX_SIZE;
+#endif
+	/* copy code to DDR */
+	printf("Loading second stage boot loader ");
+	while (copy_len <= code_len) {
+		spi_flash_read(flash, offset + copy_len, 0x2000,
+			       (void *)(CONFIG_SYS_SPI_FLASH_U_BOOT_DST
+			       + copy_len));
+		copy_len = copy_len + 0x2000;
+		putc('.');
+	}
+
+	/*
+	* Jump to U-Boot image
+	*/
+	flush_cache(CONFIG_SYS_SPI_FLASH_U_BOOT_DST, code_len);
+	uboot = (void *)CONFIG_SYS_SPI_FLASH_U_BOOT_START;
+	(*uboot)();
+}
diff --git a/drivers/mtd/spi-nor/spi_spl_load.c b/drivers/mtd/spi-nor/spi_spl_load.c
new file mode 100644
index 0000000..ca56fe9
--- /dev/null
+++ b/drivers/mtd/spi-nor/spi_spl_load.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2011 OMICRON electronics GmbH
+ *
+ * based on drivers/mtd/nand/nand_spl_load.c
+ *
+ * Copyright (C) 2011
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <spi.h>
+#include <spi_flash.h>
+#include <errno.h>
+#include <spl.h>
+
+#ifdef CONFIG_SPL_OS_BOOT
+/*
+ * 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)
+{
+	/* Read for a header, parse or error out. */
+	spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS, 0x40,
+		       (void *)header);
+
+	if (image_get_magic(header) != IH_MAGIC)
+		return -1;
+
+	spl_parse_image_header(header);
+
+	spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS,
+		       spl_image.size, (void *)spl_image.load_addr);
+
+	/* Read device tree. */
+	spi_flash_read(flash, CONFIG_SYS_SPI_ARGS_OFFS,
+		       CONFIG_SYS_SPI_ARGS_SIZE,
+		       (void *)CONFIG_SYS_SPL_ARGS_ADDR);
+
+	return 0;
+}
+#endif
+
+/*
+ * The main entry for SPI booting. It's necessary that SDRAM is already
+ * configured and available since this code loads the main U-Boot image
+ * from SPI into SDRAM and starts it from there.
+ */
+int spl_spi_load_image(void)
+{
+	int err = 0;
+	struct spi_flash *flash;
+	struct image_header *header;
+
+	/*
+	 * Load U-Boot image from SPI flash into RAM
+	 */
+
+	flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+				CONFIG_SF_DEFAULT_CS,
+				CONFIG_SF_DEFAULT_SPEED,
+				CONFIG_SF_DEFAULT_MODE);
+	if (!flash) {
+		puts("SPI probe failed.\n");
+		return -ENODEV;
+	}
+
+	/* use CONFIG_SYS_TEXT_BASE as temporary storage area */
+	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
+
+#ifdef CONFIG_SPL_OS_BOOT
+	if (spl_start_uboot() || spi_load_image_os(flash, header))
+#endif
+	{
+		/* Load u-boot, mkimage header is 64 bytes. */
+		err = spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, 0x40,
+				     (void *)header);
+		if (err)
+			return err;
+
+		spl_parse_image_header(header);
+		err = spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS,
+			       spl_image.size, (void *)spl_image.load_addr);
+	}
+
+	return err;
+}
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 21/32] mtd: spi-nor: spl: Follow ascending order of include headers
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (19 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 20/32] mtd: spi-nor: Copy spl files from drivers/mtd/spi Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 22/32] mtd: spi-nor: fsl_espi_spl: Use mtd_info Jagan Teki
                   ` (10 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

Use ascending order while including headers files.

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 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(-)

diff --git a/drivers/mtd/spi-nor/fsl_espi_spl.c b/drivers/mtd/spi-nor/fsl_espi_spl.c
index b915469..7c40245 100644
--- a/drivers/mtd/spi-nor/fsl_espi_spl.c
+++ b/drivers/mtd/spi-nor/fsl_espi_spl.c
@@ -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
diff --git a/drivers/mtd/spi-nor/spi_spl_load.c b/drivers/mtd/spi-nor/spi_spl_load.c
index ca56fe9..285b6da 100644
--- a/drivers/mtd/spi-nor/spi_spl_load.c
+++ b/drivers/mtd/spi-nor/spi_spl_load.c
@@ -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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 22/32] mtd: spi-nor: fsl_espi_spl: Use mtd_info
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (20 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 21/32] mtd: spi-nor: spl: Follow ascending order of include headers Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 23/32] mtd: spi-nor: spi_spl_load: " Jagan Teki
                   ` (9 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

Replace spi_flash{} with mtd_info{}

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 drivers/mtd/spi-nor/fsl_espi_spl.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/spi-nor/fsl_espi_spl.c b/drivers/mtd/spi-nor/fsl_espi_spl.c
index 7c40245..93b0b2e 100644
--- a/drivers/mtd/spi-nor/fsl_espi_spl.c
+++ b/drivers/mtd/spi-nor/fsl_espi_spl.c
@@ -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);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 23/32] mtd: spi-nor: spi_spl_load: Use mtd_info
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (21 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 22/32] mtd: spi-nor: fsl_espi_spl: Use mtd_info Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 24/32] mtd: spi-nor: Add flash vendor Kconfig entries Jagan Teki
                   ` (8 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

Replace spi_flash{} with mtd_info{}

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 drivers/mtd/spi-nor/spi_spl_load.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi_spl_load.c b/drivers/mtd/spi-nor/spi_spl_load.c
index 285b6da..9f33826 100644
--- a/drivers/mtd/spi-nor/spi_spl_load.c
+++ b/drivers/mtd/spi-nor/spi_spl_load.c
@@ -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;
 
 	/*
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 24/32] mtd: spi-nor: Add flash vendor Kconfig entries
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (22 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 23/32] mtd: spi-nor: spi_spl_load: " Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 25/32] arm: zynq: Kconfig: Select MTD uclass Jagan Teki
                   ` (7 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

Added flash vendor kconfig entries from drivers/mtd/spi

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 drivers/mtd/spi-nor/Kconfig | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index 43f59b7..219306f 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 25/32] arm: zynq: Kconfig: Select MTD uclass
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (23 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 24/32] mtd: spi-nor: Add flash vendor Kconfig entries Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 26/32] arm: zynq: Kconfig: Drop DM_SPI_FLASH Jagan Teki
                   ` (6 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

Since SPI-NOR core relies on MTD uclass.

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 arch/arm/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d2dbb1a..2dc2191 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -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
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 26/32] arm: zynq: Kconfig: Drop DM_SPI_FLASH
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (24 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 25/32] arm: zynq: Kconfig: Select MTD uclass Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 27/32] defconfigs: zynq_microzed: Drop CONFIG_SPI_FLASH Jagan Teki
                   ` (5 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

Drop using legacy DM_SPI_FLASH.

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 arch/arm/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2dc2191..b26dddb 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 27/32] defconfigs: zynq_microzed: Drop CONFIG_SPI_FLASH
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (25 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 26/32] arm: zynq: Kconfig: Drop DM_SPI_FLASH Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 28/32] defconfig: zynq_microzed: Enable CONFIG_MTD_M25P80 Jagan Teki
                   ` (4 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

Drop using legacy spi_flash core.

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 configs/zynq_microzed_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig
index a3a66ec..c181537 100644
--- a/configs/zynq_microzed_defconfig
+++ b/configs/zynq_microzed_defconfig
@@ -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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 28/32] defconfig: zynq_microzed: Enable CONFIG_MTD_M25P80
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (26 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 27/32] defconfigs: zynq_microzed: Drop CONFIG_SPI_FLASH Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 29/32] defconfig: zynq_microzed: Enable CONFIG_MTD_SPI_NOR Jagan Teki
                   ` (3 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

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

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 configs/zynq_microzed_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig
index c181537..79f2913 100644
--- a/configs/zynq_microzed_defconfig
+++ b/configs/zynq_microzed_defconfig
@@ -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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 29/32] defconfig: zynq_microzed: Enable CONFIG_MTD_SPI_NOR
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (27 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 28/32] defconfig: zynq_microzed: Enable CONFIG_MTD_M25P80 Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 30/32] spl: Add CONFIG_SPL_SPI_NOR_SUPPORT Jagan Teki
                   ` (2 subsequent siblings)
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

Enabled SPI-NOR core support

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 configs/zynq_microzed_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig
index 79f2913..db02ba3 100644
--- a/configs/zynq_microzed_defconfig
+++ b/configs/zynq_microzed_defconfig
@@ -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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 30/32] spl: Add CONFIG_SPL_SPI_NOR_SUPPORT
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (28 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 29/32] defconfig: zynq_microzed: Enable CONFIG_MTD_SPI_NOR Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 31/32] configs: zynq: Use CONFIG_SPL_SPI_NOR_SUPPORT Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 32/32] configs: zynq: Use CONFIG_SPL_MTD_SUPPORT Jagan Teki
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

Add SPL support for SPI-NOR flash.

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 drivers/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/Makefile b/drivers/Makefile
index e7eab66..1d179b9 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -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/
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 31/32] configs: zynq: Use CONFIG_SPL_SPI_NOR_SUPPORT
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (29 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 30/32] spl: Add CONFIG_SPL_SPI_NOR_SUPPORT Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 32/32] configs: zynq: Use CONFIG_SPL_MTD_SUPPORT Jagan Teki
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

Use SPI-NOR SPL support for zynq boards.

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 include/configs/zynq-common.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h
index e8c3ef0..7427d22 100644
--- a/include/configs/zynq-common.h
+++ b/include/configs/zynq-common.h
@@ -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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [U-Boot] [PATCH v5 32/32] configs: zynq: Use CONFIG_SPL_MTD_SUPPORT
  2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
                   ` (30 preceding siblings ...)
  2016-02-10 19:08 ` [U-Boot] [PATCH v5 31/32] configs: zynq: Use CONFIG_SPL_SPI_NOR_SUPPORT Jagan Teki
@ 2016-02-10 19:08 ` Jagan Teki
  31 siblings, 0 replies; 33+ messages in thread
From: Jagan Teki @ 2016-02-10 19:08 UTC (permalink / raw)
  To: u-boot

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

Cc: Simon Glass <sjg@chromium.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Jagan Teki <jteki@openedev.com>
---
 include/configs/zynq-common.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h
index 7427d22..582b2a3 100644
--- a/include/configs/zynq-common.h
+++ b/include/configs/zynq-common.h
@@ -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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2016-02-10 19:08 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-10 19:07 [U-Boot] [PATCH v5 00/32] mtd: Add SPI-NOR core support Jagan Teki
2016-02-10 19:07 ` [U-Boot] [PATCH v5 01/32] mtd: Add m25p80 driver Jagan Teki
2016-02-10 19:07 ` [U-Boot] [PATCH v5 02/32] mtd: Add Kconfig entry for MTD_M25P80 Jagan Teki
2016-02-10 19:07 ` [U-Boot] [PATCH v5 03/32] mtd: Add SPI-NOR core support Jagan Teki
2016-02-10 19:07 ` [U-Boot] [PATCH v5 04/32] doc: device-tree-bindings: jedec, spi-nor Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 05/32] mtd: spi-nor: Add Kconfig entry for MTD_SPI_NOR Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 06/32] mtd: spi-nor: Add kconfig for MTD_SPI_NOR_USE_4K_SECTORS Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 07/32] mtd: spi-nor: Add MTD support Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 08/32] mtd: spi-nor: Add spi_nor support in m25p80 Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 09/32] mtd: spi-nor: Add dm spi-nor probing Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 10/32] mtd: spi-nor: Add spi_flash_probe for mtd-dm-spi-nor Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 11/32] cmd: sf: Add mtd_info for mtd-dm-spi-nor code Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 12/32] mtd: spi-nor: m25p80: Add spi_nor support for non-dm Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 13/32] spi_flash: Use mtd_info operation " Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 14/32] mtd: spi-nor: Move spi_read_then_write to spi layer Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 15/32] spi: Rename spi_read_then_write to spi_write_then_read Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 16/32] spi: Drop mode_rx Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 17/32] spi: Drop SPI_RX_FAST Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 18/32] mtd: spi-nor: Rename SPI_FLASH_BAR to SPI_NOR_BAR Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 19/32] mtd: spi-nor: Add Kconfig entry for SPI_NOR_BAR Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 20/32] mtd: spi-nor: Copy spl files from drivers/mtd/spi Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 21/32] mtd: spi-nor: spl: Follow ascending order of include headers Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 22/32] mtd: spi-nor: fsl_espi_spl: Use mtd_info Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 23/32] mtd: spi-nor: spi_spl_load: " Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 24/32] mtd: spi-nor: Add flash vendor Kconfig entries Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 25/32] arm: zynq: Kconfig: Select MTD uclass Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 26/32] arm: zynq: Kconfig: Drop DM_SPI_FLASH Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 27/32] defconfigs: zynq_microzed: Drop CONFIG_SPI_FLASH Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 28/32] defconfig: zynq_microzed: Enable CONFIG_MTD_M25P80 Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 29/32] defconfig: zynq_microzed: Enable CONFIG_MTD_SPI_NOR Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 30/32] spl: Add CONFIG_SPL_SPI_NOR_SUPPORT Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 31/32] configs: zynq: Use CONFIG_SPL_SPI_NOR_SUPPORT Jagan Teki
2016-02-10 19:08 ` [U-Boot] [PATCH v5 32/32] configs: zynq: Use CONFIG_SPL_MTD_SUPPORT Jagan Teki

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.