* [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.