openwrt/target/linux/layerscape/patches-4.4/1090-mtd-spi-nor-Add-SPI-NOR-layer-PM-support.patch
Yutang Jiang 15a14cf166 layerscape: add 64b/32b target for ls1012ardb device
The QorIQ LS1012A processor, optimized for battery-backed or
USB-powered, integrates a single ARM Cortex-A53 core with a hardware
packet forwarding engine and high-speed interfaces to deliver
line-rate networking performance.
QorIQ LS1012A Reference Design System (LS1012ARDB) is a high-performance
development platform, with a complete debugging environment.
The LS1012ARDB board supports the QorIQ LS1012A processor and is
optimized to support the high-bandwidth DDR3L memory and
a full complement of high-speed SerDes ports.

LEDE/OPENWRT will auto strip executable program file while make. So we
need select CONFIG_NO_STRIP=y while make menuconfig to avoid the ppfe network
fiemware be destroyed, then run make to build ls1012ardb firmware.

The fsl-quadspi flash with jffs2 fs is unstable and arise some failed message.
This issue have noticed the IP owner for investigate, hope he can solve it
earlier. So the ls1012ardb now also provide a xx-firmware.ext4.bin as default
firmware, and the uboot bootcmd will run wrtboot_ext4rfs for "rootfstype=ext4"
bootargs.

Signed-off-by: Yutang Jiang <yutang.jiang@nxp.com>
2016-10-31 17:00:10 +01:00

138 lines
3.7 KiB
Diff

From 2c5a3db21926e9ebfd7a32e3c36a3256ed84903c Mon Sep 17 00:00:00 2001
From: Hou Zhiqiang <Zhiqiang.Hou@freescale.com>
Date: Thu, 19 Nov 2015 20:25:24 +0800
Subject: [PATCH 090/113] mtd: spi-nor: Add SPI NOR layer PM support
[context adjustment]
Add the Power Management API in SPI NOR framework.
The Power Management system will turn off power supply to SPI flash
when system suspending, and then the SPI flash will be in the reset
state after system resuming. As a result, the status&configurations
of SPI flash driver will mismatch with its current hardware state.
So reinitialize SPI flash to make sure it is resumed to the correct
state.
And the SPI NOR layer just do common configuration depending on the
records in structure spi_nor.
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@freescale.com>
Integrated-by: Jiang Yutang <yutang.jiang@nxp.com>
---
drivers/mtd/spi-nor/spi-nor.c | 74 ++++++++++++++++++++++++++++++++++-------
include/linux/mtd/spi-nor.h | 9 +++++
2 files changed, 71 insertions(+), 12 deletions(-)
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1139,6 +1139,26 @@ static int spi_nor_check(struct spi_nor
return 0;
}
+/*
+ * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
+ * with the software protection bits set
+ */
+static int spi_nor_unprotect_on_powerup(struct spi_nor *nor)
+{
+ const struct flash_info *info = NULL;
+ int ret = 0;
+
+ info = spi_nor_read_id(nor);
+ if (JEDEC_MFR(info) == SNOR_MFR_ATMEL ||
+ JEDEC_MFR(info) == SNOR_MFR_INTEL ||
+ JEDEC_MFR(info) == SNOR_MFR_SST) {
+ write_enable(nor);
+ ret = write_sr(nor, 0);
+ }
+
+ return ret;
+}
+
int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
{
const struct flash_info *info = NULL;
@@ -1186,18 +1206,9 @@ int spi_nor_scan(struct spi_nor *nor, co
mutex_init(&nor->lock);
- /*
- * Atmel, SST, Intel/Numonyx, 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_INTEL ||
- JEDEC_MFR(info) == SNOR_MFR_MACRONIX ||
- JEDEC_MFR(info) == SNOR_MFR_SST) {
- write_enable(nor);
- write_sr(nor, 0);
- }
+ ret = spi_nor_unprotect_on_powerup(nor);
+ if (ret)
+ return ret;
if (!mtd->name)
mtd->name = dev_name(dev);
@@ -1363,6 +1374,45 @@ int spi_nor_scan(struct spi_nor *nor, co
}
EXPORT_SYMBOL_GPL(spi_nor_scan);
+static int spi_nor_hw_reinit(struct spi_nor *nor)
+{
+ const struct flash_info *info = NULL;
+ struct device *dev = nor->dev;
+ int ret;
+
+ info = spi_nor_read_id(nor);
+
+ ret = spi_nor_unprotect_on_powerup(nor);
+ if (ret)
+ return ret;
+
+ if (nor->flash_read == SPI_NOR_QUAD) {
+ ret = set_quad_mode(nor, info);
+ if (ret) {
+ dev_err(dev, "quad mode not supported\n");
+ return ret;
+ }
+ }
+
+ if (nor->addr_width == 4 &&
+ JEDEC_MFR(info) != SNOR_MFR_SPANSION)
+ set_4byte(nor, info, 1);
+
+ return 0;
+}
+
+int spi_nor_suspend(struct spi_nor *nor)
+{
+ return 0;
+}
+EXPORT_SYMBOL_GPL(spi_nor_suspend);
+
+int spi_nor_resume(struct spi_nor *nor)
+{
+ return spi_nor_hw_reinit(nor);
+}
+EXPORT_SYMBOL_GPL(spi_nor_resume);
+
static const struct flash_info *spi_nor_match_id(const char *name)
{
const struct flash_info *id = spi_nor_ids;
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -210,4 +210,13 @@ static inline struct device_node *spi_no
*/
int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode);
+/**
+ * spi_nor_suspend/resume() - the SPI NOR layer PM API
+ * @nor: the spi_nor structure
+ *
+ * Return: 0 for success, others for failure.
+ */
+int spi_nor_suspend(struct spi_nor *nor);
+int spi_nor_resume(struct spi_nor *nor);
+
#endif