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>
This commit is contained in:
committed by
John Crispin
parent
c6c731fe31
commit
15a14cf166
@@ -9,6 +9,8 @@ endef
|
||||
|
||||
DEFAULT_PACKAGES+= \
|
||||
rcw-layerscape-ls1043ardb uboot-layerscape-$(SUBTARGET)-ls1043ardb \
|
||||
fman-layerscape-ls1043ardb
|
||||
fman-layerscape-ls1043ardb \
|
||||
rcw-layerscape-ls1012ardb uboot-layerscape-$(SUBTARGET)-ls1012ardb \
|
||||
kmod-ppfe ppfe-ls1012ardb
|
||||
|
||||
$(eval $(call Profile,Default))
|
||||
|
||||
4
target/linux/layerscape/base-files/etc/rc.local
Normal file
4
target/linux/layerscape/base-files/etc/rc.local
Normal file
@@ -0,0 +1,4 @@
|
||||
# Put your custom commands here that should be executed once
|
||||
# the system init finished. By default this file does nothing.
|
||||
modprobe pfe.ko
|
||||
exit 0
|
||||
@@ -294,3 +294,5 @@ CONFIG_USB=y
|
||||
CONFIG_VITESSE_PHY=y
|
||||
CONFIG_XPS=y
|
||||
CONFIG_ZLIB_INFLATE=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_SPI_FSL_QUADSPI=y
|
||||
|
||||
@@ -25,6 +25,11 @@ define Build/append-ls-dtb
|
||||
dd if=$(DTS_DIR)/$(1).dtb >> $@
|
||||
endef
|
||||
|
||||
define Build/append-ls-rootfs-ext4
|
||||
$(STAGING_DIR_HOST)/bin/make_ext4fs -l $(word 2,$(1)) -b 4096 -i 6000 -m 0 -J $(KDIR)/$(word 1,$(1))-$(word 2,$(1)).root.ext4 $(TARGET_DIR)
|
||||
dd if=$(KDIR)/$(word 1,$(1))-$(word 2,$(1)).root.ext4 >> $@
|
||||
endef
|
||||
|
||||
define Device/Default
|
||||
PROFILES = Default
|
||||
FILESYSTEMS := squashfs
|
||||
@@ -57,4 +62,23 @@ endif
|
||||
endef
|
||||
TARGET_DEVICES += ls1043ardb
|
||||
|
||||
define Device/ls1012ardb
|
||||
DEVICE_TITLE := ls1012ardb-$(SUBTARGET)
|
||||
DEVICE_PACKAGES += rcw-layerscape-ls1012ardb uboot-layerscape-$(SUBTARGET)-ls1012ardb kmod-ppfe ppfe-ls1012ardb
|
||||
ifeq ($(SUBTARGET),64b)
|
||||
DEVICE_DTS = freescale/fsl-ls1012a-rdb
|
||||
endif
|
||||
ifeq ($(SUBTARGET),32b)
|
||||
DEVICE_DTS = ../../../arm64/boot/dts/freescale/fsl-ls1012a-rdb
|
||||
endif
|
||||
IMAGE/firmware.bin = append-ls-rcw $(1) | pad-to 1M | append-ls-uboot $(1) | pad-to 3M | \
|
||||
append-ls-dtb $$(DEVICE_DTS) | pad-to 4M | append-kernel | pad-to 9M | \
|
||||
append-rootfs | pad-to 32M | check-size 33554433
|
||||
IMAGES += firmware.ext4.bin
|
||||
IMAGE/firmware.ext4.bin = append-ls-rcw $(1) | pad-to 1M | append-ls-uboot $(1) | pad-to 3M | \
|
||||
append-ls-dtb $$(DEVICE_DTS) | pad-to 4M | append-kernel | pad-to 9M | \
|
||||
append-ls-rootfs-ext4 $(1) 23M | check-size 33554433
|
||||
endef
|
||||
TARGET_DEVICES += ls1012ardb
|
||||
|
||||
$(eval $(call BuildImage))
|
||||
|
||||
20
target/linux/layerscape/modules.mk
Normal file
20
target/linux/layerscape/modules.mk
Normal file
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# Copyright (C) Jiang Yutang <jiangyutang1978@gmail.com>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
define KernelPackage/ppfe
|
||||
SUBMENU:=$(NETWORK_DEVICES_MENU)
|
||||
TITLE:=Freescale PPFE Driver support
|
||||
KCONFIG:=CONFIG_FSL_PPFE
|
||||
FILES:=$(LINUX_DIR)/drivers/staging/fsl_ppfe/pfe.ko
|
||||
AUTOLOAD:=$(call AutoLoad,35,ppfe)
|
||||
endef
|
||||
|
||||
define KernelPackage/ppfe/description
|
||||
Kernel modules for Freescale PPFE Driver support.
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,ppfe))
|
||||
@@ -0,0 +1,31 @@
|
||||
From f560fdb9d71aaf3adc54341a1650577c78495df9 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Norris <computersforpeace@gmail.com>
|
||||
Date: Fri, 30 Oct 2015 20:33:22 -0700
|
||||
Subject: [PATCH 074/113] mtd: {nand,spi-nor}: assign MTD of_node
|
||||
|
||||
We should pass along our flash DT node to the MTD layer, so it can set
|
||||
up ofpart for us.
|
||||
|
||||
cherry-pick{
|
||||
remove the code:
|
||||
drivers/mtd/nand/nand_base.c | 3 +
|
||||
commit:3e63b26bdd4069c3df2cd7ce7217a21d06801b41
|
||||
}
|
||||
|
||||
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
|
||||
Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com>
|
||||
Signed-off-by: Yuan Yao <yao.yuan@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/spi-nor.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -1217,6 +1217,7 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
mtd->flags |= MTD_NO_ERASE;
|
||||
|
||||
mtd->dev.parent = dev;
|
||||
+ mtd_set_of_node(mtd, np);
|
||||
nor->page_size = info->page_size;
|
||||
mtd->writebufsize = nor->page_size;
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
From f906ec330da9aa83de5382653436be36273c63d3 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Norris <computersforpeace@gmail.com>
|
||||
Date: Fri, 30 Oct 2015 20:33:24 -0700
|
||||
Subject: [PATCH 075/113] mtd: spi-nor: convert to spi_nor_{get,
|
||||
set}_flash_node()
|
||||
|
||||
Used semantic patch with 'make coccicheck MODE=patch COCCI=script.cocci':
|
||||
|
||||
---8<----
|
||||
virtual patch
|
||||
|
||||
@@
|
||||
struct spi_nor b;
|
||||
struct spi_nor *c;
|
||||
expression d;
|
||||
@@
|
||||
(
|
||||
-(b).flash_node = (d)
|
||||
+spi_nor_set_flash_node(&b, d)
|
||||
|
|
||||
-(c)->flash_node = (d)
|
||||
+spi_nor_set_flash_node(c, d)
|
||||
)
|
||||
---8<----
|
||||
|
||||
And a manual conversion for the one use of spi_nor_get_flash_node().
|
||||
|
||||
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
|
||||
Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com>
|
||||
---
|
||||
drivers/mtd/devices/m25p80.c | 2 +-
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 2 +-
|
||||
drivers/mtd/spi-nor/nxp-spifi.c | 2 +-
|
||||
drivers/mtd/spi-nor/spi-nor.c | 2 +-
|
||||
4 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/devices/m25p80.c
|
||||
+++ b/drivers/mtd/devices/m25p80.c
|
||||
@@ -221,7 +221,7 @@ static int m25p_probe(struct spi_device
|
||||
nor->read_reg = m25p80_read_reg;
|
||||
|
||||
nor->dev = &spi->dev;
|
||||
- nor->flash_node = spi->dev.of_node;
|
||||
+ spi_nor_set_flash_node(nor, spi->dev.of_node);
|
||||
nor->priv = flash;
|
||||
|
||||
spi_set_drvdata(spi, flash);
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -1013,7 +1013,7 @@ static int fsl_qspi_probe(struct platfor
|
||||
mtd = &nor->mtd;
|
||||
|
||||
nor->dev = dev;
|
||||
- nor->flash_node = np;
|
||||
+ spi_nor_set_flash_node(nor, np);
|
||||
nor->priv = q;
|
||||
|
||||
/* fill the hooks */
|
||||
--- a/drivers/mtd/spi-nor/nxp-spifi.c
|
||||
+++ b/drivers/mtd/spi-nor/nxp-spifi.c
|
||||
@@ -330,7 +330,7 @@ static int nxp_spifi_setup_flash(struct
|
||||
writel(ctrl, spifi->io_base + SPIFI_CTRL);
|
||||
|
||||
spifi->nor.dev = spifi->dev;
|
||||
- spifi->nor.flash_node = np;
|
||||
+ spi_nor_set_flash_node(&spifi->nor, np);
|
||||
spifi->nor.priv = spifi;
|
||||
spifi->nor.read = nxp_spifi_read;
|
||||
spifi->nor.write = nxp_spifi_write;
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -1111,7 +1111,7 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
const struct flash_info *info = NULL;
|
||||
struct device *dev = nor->dev;
|
||||
struct mtd_info *mtd = &nor->mtd;
|
||||
- struct device_node *np = nor->flash_node;
|
||||
+ struct device_node *np = spi_nor_get_flash_node(nor);
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
From e36da6d0a0841ea3a75d5189057bd020d737e71a Mon Sep 17 00:00:00 2001
|
||||
From: Brian Norris <computersforpeace@gmail.com>
|
||||
Date: Fri, 30 Oct 2015 20:33:26 -0700
|
||||
Subject: [PATCH 076/113] mtd: spi-nor: drop unnecessary partition parser data
|
||||
|
||||
Now that the SPI-NOR/MTD framework pass the 'flash_node' through to the
|
||||
partition parsing code, we don't have to do it ourselves.
|
||||
|
||||
Also convert to mtd_device_register(), since we don't need the 2nd and
|
||||
3rd parameters anymore.
|
||||
|
||||
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
|
||||
Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com>
|
||||
---
|
||||
drivers/mtd/devices/m25p80.c | 8 ++------
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 4 +---
|
||||
drivers/mtd/spi-nor/nxp-spifi.c | 4 +---
|
||||
3 files changed, 4 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/devices/m25p80.c
|
||||
+++ b/drivers/mtd/devices/m25p80.c
|
||||
@@ -197,7 +197,6 @@ static int m25p80_erase(struct spi_nor *
|
||||
*/
|
||||
static int m25p_probe(struct spi_device *spi)
|
||||
{
|
||||
- struct mtd_part_parser_data ppdata;
|
||||
struct flash_platform_data *data;
|
||||
struct m25p *flash;
|
||||
struct spi_nor *nor;
|
||||
@@ -249,11 +248,8 @@ static int m25p_probe(struct spi_device
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- ppdata.of_node = spi->dev.of_node;
|
||||
-
|
||||
- return mtd_device_parse_register(&nor->mtd, NULL, &ppdata,
|
||||
- data ? data->parts : NULL,
|
||||
- data ? data->nr_parts : 0);
|
||||
+ return mtd_device_register(&nor->mtd, data ? data->parts : NULL,
|
||||
+ data ? data->nr_parts : 0);
|
||||
}
|
||||
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -927,7 +927,6 @@ static void fsl_qspi_unprep(struct spi_n
|
||||
static int fsl_qspi_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
- struct mtd_part_parser_data ppdata;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct fsl_qspi *q;
|
||||
struct resource *res;
|
||||
@@ -1038,8 +1037,7 @@ static int fsl_qspi_probe(struct platfor
|
||||
if (ret)
|
||||
goto mutex_failed;
|
||||
|
||||
- ppdata.of_node = np;
|
||||
- ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
|
||||
+ ret = mtd_device_register(mtd, NULL, 0);
|
||||
if (ret)
|
||||
goto mutex_failed;
|
||||
|
||||
--- a/drivers/mtd/spi-nor/nxp-spifi.c
|
||||
+++ b/drivers/mtd/spi-nor/nxp-spifi.c
|
||||
@@ -271,7 +271,6 @@ static void nxp_spifi_dummy_id_read(stru
|
||||
static int nxp_spifi_setup_flash(struct nxp_spifi *spifi,
|
||||
struct device_node *np)
|
||||
{
|
||||
- struct mtd_part_parser_data ppdata;
|
||||
enum read_mode flash_read;
|
||||
u32 ctrl, property;
|
||||
u16 mode = 0;
|
||||
@@ -361,8 +360,7 @@ static int nxp_spifi_setup_flash(struct
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ppdata.of_node = np;
|
||||
- ret = mtd_device_parse_register(&spifi->nor.mtd, NULL, &ppdata, NULL, 0);
|
||||
+ ret = mtd_device_register(&spifi->nor.mtd, NULL, 0);
|
||||
if (ret) {
|
||||
dev_err(spifi->dev, "mtd device parse failed\n");
|
||||
return ret;
|
||||
@@ -0,0 +1,62 @@
|
||||
From a2f87e7df641b482e217f5b0efbaf41f6b8a0cf6 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Norris <computersforpeace@gmail.com>
|
||||
Date: Fri, 30 Oct 2015 20:33:20 -0700
|
||||
Subject: [PATCH 077/113] mtd: add get/set of_node/flash_node helpers
|
||||
|
||||
We are going to begin using the mtd->dev.of_node field for MTD device
|
||||
nodes, so let's add helpers for it. Also, we'll be making some
|
||||
conversions on spi_nor (and nand_chip eventually) too, so get that ready
|
||||
with their own helpers.
|
||||
|
||||
commit:28b8b26b308e656edfa9467867d5f79212da2ec3
|
||||
delete the include/linux/mtd/nand.h
|
||||
just upgrade the code about spi.
|
||||
|
||||
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
|
||||
Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com>
|
||||
Signed-off-by: Yuan Yao <yao.yuan@nxp.com>
|
||||
---
|
||||
include/linux/mtd/mtd.h | 11 +++++++++++
|
||||
include/linux/mtd/spi-nor.h | 11 +++++++++++
|
||||
2 files changed, 22 insertions(+)
|
||||
|
||||
--- a/include/linux/mtd/mtd.h
|
||||
+++ b/include/linux/mtd/mtd.h
|
||||
@@ -258,6 +258,17 @@ struct mtd_info {
|
||||
int usecount;
|
||||
};
|
||||
|
||||
+static inline void mtd_set_of_node(struct mtd_info *mtd,
|
||||
+ struct device_node *np)
|
||||
+{
|
||||
+ mtd->dev.of_node = np;
|
||||
+}
|
||||
+
|
||||
+static inline struct device_node *mtd_get_of_node(struct mtd_info *mtd)
|
||||
+{
|
||||
+ return mtd->dev.of_node;
|
||||
+}
|
||||
+
|
||||
int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
|
||||
int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
|
||||
void **virt, resource_size_t *phys);
|
||||
--- a/include/linux/mtd/spi-nor.h
|
||||
+++ b/include/linux/mtd/spi-nor.h
|
||||
@@ -184,6 +184,17 @@ struct spi_nor {
|
||||
void *priv;
|
||||
};
|
||||
|
||||
+static inline void spi_nor_set_flash_node(struct spi_nor *nor,
|
||||
+ struct device_node *np)
|
||||
+{
|
||||
+ nor->flash_node = np;
|
||||
+}
|
||||
+
|
||||
+static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor)
|
||||
+{
|
||||
+ return nor->flash_node;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* spi_nor_scan() - scan the SPI NOR
|
||||
* @nor: the spi_nor structure
|
||||
@@ -0,0 +1,57 @@
|
||||
From df36b4601bc9f84684249a26eb39b818d6785fb8 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Norris <computersforpeace@gmail.com>
|
||||
Date: Fri, 30 Oct 2015 20:33:27 -0700
|
||||
Subject: [PATCH 078/113] mtd: spi-nor: drop flash_node field
|
||||
|
||||
We can just alias to the MTD of_node.
|
||||
|
||||
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
|
||||
Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/spi-nor.c | 1 -
|
||||
include/linux/mtd/spi-nor.h | 6 ++----
|
||||
2 files changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -1217,7 +1217,6 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
mtd->flags |= MTD_NO_ERASE;
|
||||
|
||||
mtd->dev.parent = dev;
|
||||
- mtd_set_of_node(mtd, np);
|
||||
nor->page_size = info->page_size;
|
||||
mtd->writebufsize = nor->page_size;
|
||||
|
||||
--- a/include/linux/mtd/spi-nor.h
|
||||
+++ b/include/linux/mtd/spi-nor.h
|
||||
@@ -123,7 +123,6 @@ enum spi_nor_option_flags {
|
||||
* @mtd: point to a mtd_info structure
|
||||
* @lock: the lock for the read/write/erase/lock/unlock operations
|
||||
* @dev: point to a spi device, or a spi nor controller device.
|
||||
- * @flash_node: point to a device node describing this flash instance.
|
||||
* @page_size: the page size of the SPI NOR
|
||||
* @addr_width: number of address bytes
|
||||
* @erase_opcode: the opcode for erasing a sector
|
||||
@@ -154,7 +153,6 @@ struct spi_nor {
|
||||
struct mtd_info mtd;
|
||||
struct mutex lock;
|
||||
struct device *dev;
|
||||
- struct device_node *flash_node;
|
||||
u32 page_size;
|
||||
u8 addr_width;
|
||||
u8 erase_opcode;
|
||||
@@ -187,12 +185,12 @@ struct spi_nor {
|
||||
static inline void spi_nor_set_flash_node(struct spi_nor *nor,
|
||||
struct device_node *np)
|
||||
{
|
||||
- nor->flash_node = np;
|
||||
+ mtd_set_of_node(&nor->mtd, np);
|
||||
}
|
||||
|
||||
static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor)
|
||||
{
|
||||
- return nor->flash_node;
|
||||
+ return mtd_get_of_node(&nor->mtd);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -0,0 +1,27 @@
|
||||
From 3ea419cf269832f5743d9b5ad75ece5178b02b09 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Norris <computersforpeace@gmail.com>
|
||||
Date: Fri, 30 Oct 2015 12:56:22 -0700
|
||||
Subject: [PATCH 079/113] mtd: spi-nor: remove unnecessary leading space from
|
||||
dbg print
|
||||
|
||||
As Cyrille noted [1], this line is wrong.
|
||||
|
||||
[1] http://lists.infradead.org/pipermail/linux-mtd/2015-September/061725.html
|
||||
|
||||
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
|
||||
Cc: Cyrille Pitchen <cyrille.pitchen@atmel.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/spi-nor.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -860,7 +860,7 @@ static const struct flash_info *spi_nor_
|
||||
|
||||
tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
|
||||
if (tmp < 0) {
|
||||
- dev_dbg(nor->dev, " error %d reading JEDEC ID\n", tmp);
|
||||
+ dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp);
|
||||
return ERR_PTR(tmp);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
From bd02decd1ad7cc883ce388e769a34a3c402b90c4 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Norris <computersforpeace@gmail.com>
|
||||
Date: Mon, 16 Nov 2015 10:45:30 -0800
|
||||
Subject: [PATCH 080/113] mtd: fsl-quadspi: possible NULL dereference
|
||||
|
||||
It is theoretically possible to probe this driver without a matching
|
||||
device tree, so let's guard against this.
|
||||
|
||||
Also, use the of_device_get_match_data() helper to make this a bit
|
||||
simpler.
|
||||
|
||||
Coverity complained about this one.
|
||||
|
||||
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
|
||||
Acked-by: Han xu <han.xu@freescale.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -269,7 +269,7 @@ struct fsl_qspi {
|
||||
struct clk *clk, *clk_en;
|
||||
struct device *dev;
|
||||
struct completion c;
|
||||
- struct fsl_qspi_devtype_data *devtype_data;
|
||||
+ const struct fsl_qspi_devtype_data *devtype_data;
|
||||
u32 nor_size;
|
||||
u32 nor_num;
|
||||
u32 clk_rate;
|
||||
@@ -933,8 +933,6 @@ static int fsl_qspi_probe(struct platfor
|
||||
struct spi_nor *nor;
|
||||
struct mtd_info *mtd;
|
||||
int ret, i = 0;
|
||||
- const struct of_device_id *of_id =
|
||||
- of_match_device(fsl_qspi_dt_ids, &pdev->dev);
|
||||
|
||||
q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
|
||||
if (!q)
|
||||
@@ -945,7 +943,9 @@ static int fsl_qspi_probe(struct platfor
|
||||
return -ENODEV;
|
||||
|
||||
q->dev = dev;
|
||||
- q->devtype_data = (struct fsl_qspi_devtype_data *)of_id->data;
|
||||
+ q->devtype_data = of_device_get_match_data(dev);
|
||||
+ if (!q->devtype_data)
|
||||
+ return -ENODEV;
|
||||
platform_set_drvdata(pdev, q);
|
||||
|
||||
/* find the resources */
|
||||
@@ -0,0 +1,105 @@
|
||||
From 56bd0e13d8bc3b4486251b10ac9d2ba7434c21ee Mon Sep 17 00:00:00 2001
|
||||
From: Brian Norris <computersforpeace@gmail.com>
|
||||
Date: Tue, 10 Nov 2015 12:15:27 -0800
|
||||
Subject: [PATCH 081/113] mtd: spi-nor: provide default erase_sector
|
||||
implementation
|
||||
|
||||
Some spi-nor drivers perform sector erase by duplicating their
|
||||
write_reg() command. Let's not require that the driver fill this out,
|
||||
and provide a default instead.
|
||||
|
||||
Tested on m25p80.c and Medatek's MT8173 SPI NOR flash driver.
|
||||
|
||||
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/spi-nor.c | 37 +++++++++++++++++++++++++++++++++----
|
||||
include/linux/mtd/spi-nor.h | 3 ++-
|
||||
2 files changed, 35 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -38,6 +38,7 @@
|
||||
#define CHIP_ERASE_2MB_READY_WAIT_JIFFIES (40UL * HZ)
|
||||
|
||||
#define SPI_NOR_MAX_ID_LEN 6
|
||||
+#define SPI_NOR_MAX_ADDR_WIDTH 4
|
||||
|
||||
struct flash_info {
|
||||
char *name;
|
||||
@@ -313,6 +314,29 @@ static void spi_nor_unlock_and_unprep(st
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Initiate the erasure of a single sector
|
||||
+ */
|
||||
+static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
|
||||
+{
|
||||
+ u8 buf[SPI_NOR_MAX_ADDR_WIDTH];
|
||||
+ int i;
|
||||
+
|
||||
+ if (nor->erase)
|
||||
+ return nor->erase(nor, addr);
|
||||
+
|
||||
+ /*
|
||||
+ * Default implementation, if driver doesn't have a specialized HW
|
||||
+ * control
|
||||
+ */
|
||||
+ for (i = nor->addr_width - 1; i >= 0; i--) {
|
||||
+ buf[i] = addr & 0xff;
|
||||
+ addr >>= 8;
|
||||
+ }
|
||||
+
|
||||
+ return nor->write_reg(nor, nor->erase_opcode, buf, nor->addr_width);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Erase an address range on the nor chip. The address range may extend
|
||||
* one or more erase sectors. Return an error is there is a problem erasing.
|
||||
*/
|
||||
@@ -371,10 +395,9 @@ static int spi_nor_erase(struct mtd_info
|
||||
while (len) {
|
||||
write_enable(nor);
|
||||
|
||||
- if (nor->erase(nor, addr)) {
|
||||
- ret = -EIO;
|
||||
+ ret = spi_nor_erase_sector(nor, addr);
|
||||
+ if (ret)
|
||||
goto erase_err;
|
||||
- }
|
||||
|
||||
addr += mtd->erasesize;
|
||||
len -= mtd->erasesize;
|
||||
@@ -1098,7 +1121,7 @@ static int set_quad_mode(struct spi_nor
|
||||
static int spi_nor_check(struct spi_nor *nor)
|
||||
{
|
||||
if (!nor->dev || !nor->read || !nor->write ||
|
||||
- !nor->read_reg || !nor->write_reg || !nor->erase) {
|
||||
+ !nor->read_reg || !nor->write_reg) {
|
||||
pr_err("spi-nor: please fill all the necessary fields!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1299,6 +1322,12 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
nor->addr_width = 3;
|
||||
}
|
||||
|
||||
+ if (nor->addr_width > SPI_NOR_MAX_ADDR_WIDTH) {
|
||||
+ dev_err(dev, "address width is too large: %u\n",
|
||||
+ nor->addr_width);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
nor->read_dummy = spi_nor_read_dummy_cycles(nor);
|
||||
|
||||
dev_info(dev, "%s (%lld Kbytes)\n", info->name,
|
||||
--- a/include/linux/mtd/spi-nor.h
|
||||
+++ b/include/linux/mtd/spi-nor.h
|
||||
@@ -142,7 +142,8 @@ enum spi_nor_option_flags {
|
||||
* @read: [DRIVER-SPECIFIC] read data from the SPI NOR
|
||||
* @write: [DRIVER-SPECIFIC] write data to the SPI NOR
|
||||
* @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR
|
||||
- * at the offset @offs
|
||||
+ * at the offset @offs; if not provided by the driver,
|
||||
+ * spi-nor will send the erase opcode via write_reg()
|
||||
* @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
|
||||
@@ -0,0 +1,31 @@
|
||||
From 30e609daed95664824e95344e85c7eaedd1bfcf3 Mon Sep 17 00:00:00 2001
|
||||
From: Ricardo Ribalda <ricardo.ribalda@gmail.com>
|
||||
Date: Mon, 30 Nov 2015 20:41:17 +0100
|
||||
Subject: [PATCH 083/113] mtd: spi-nor: Fix error message with unrecognized
|
||||
JEDEC
|
||||
|
||||
The error message was:
|
||||
|
||||
m25p80 spi32766.0: unrecognized JEDEC id bytes: 00, 0, 0
|
||||
|
||||
The new error message:
|
||||
|
||||
m25p80 spi32766.0: unrecognized JEDEC id bytes: 00, 00, 00
|
||||
|
||||
Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
|
||||
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/spi-nor.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -894,7 +894,7 @@ static const struct flash_info *spi_nor_
|
||||
return &spi_nor_ids[tmp];
|
||||
}
|
||||
}
|
||||
- dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %2x, %2x\n",
|
||||
+ dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n",
|
||||
id[0], id[1], id[2]);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
From 9e473594776da97245049019f1d1e9608ff1214a Mon Sep 17 00:00:00 2001
|
||||
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Date: Tue, 17 Nov 2015 20:18:54 +0100
|
||||
Subject: [PATCH 084/113] mtd: spi-nor: fix error handling in spi_nor_erase
|
||||
|
||||
The documenting comment of mtd_erase in mtdcore.c states:
|
||||
Device drivers are supposed to call instr->callback() whenever
|
||||
the operation completes, even if it completes with a failure.
|
||||
|
||||
Currently the callback isn't called in case of failure. Fix this.
|
||||
|
||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/spi-nor.c | 8 ++------
|
||||
1 file changed, 2 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -410,17 +410,13 @@ static int spi_nor_erase(struct mtd_info
|
||||
|
||||
write_disable(nor);
|
||||
|
||||
+erase_err:
|
||||
spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
|
||||
|
||||
- instr->state = MTD_ERASE_DONE;
|
||||
+ instr->state = ret ? MTD_ERASE_FAILED : MTD_ERASE_DONE;
|
||||
mtd_erase_callback(instr);
|
||||
|
||||
return ret;
|
||||
-
|
||||
-erase_err:
|
||||
- spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
|
||||
- instr->state = MTD_ERASE_FAILED;
|
||||
- return ret;
|
||||
}
|
||||
|
||||
static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs,
|
||||
@@ -0,0 +1,58 @@
|
||||
From d05c68e35f42a46b352d2a4bdaef9954c946e20a Mon Sep 17 00:00:00 2001
|
||||
From: Fabio Estevam <fabio.estevam@freescale.com>
|
||||
Date: Fri, 20 Nov 2015 16:26:11 -0200
|
||||
Subject: [PATCH 085/113] mtd: spi-nor: Check the return value from read_sr()
|
||||
|
||||
[context adjustment]
|
||||
|
||||
We should better check the return value from read_sr() and
|
||||
propagate it in the case of error.
|
||||
|
||||
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
|
||||
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
|
||||
Integrated-by: Jiang Yutang <yutang.jiang@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/spi-nor.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -478,11 +478,13 @@ static int stm_is_locked_sr(struct spi_n
|
||||
static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
|
||||
{
|
||||
struct mtd_info *mtd = &nor->mtd;
|
||||
- u8 status_old, status_new;
|
||||
+ 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)
|
||||
+ return status_old;
|
||||
|
||||
/* SPI NOR always locks to the end */
|
||||
if (ofs + len != mtd->size) {
|
||||
@@ -528,11 +530,13 @@ static int stm_lock(struct spi_nor *nor,
|
||||
static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
|
||||
{
|
||||
struct mtd_info *mtd = &nor->mtd;
|
||||
- uint8_t status_old, status_new;
|
||||
+ 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)
|
||||
+ return status_old;
|
||||
|
||||
/* Cannot unlock; would unlock larger region than requested */
|
||||
if (stm_is_locked_sr(nor, ofs - mtd->erasesize, mtd->erasesize,
|
||||
@@ -1036,6 +1040,8 @@ static int macronix_quad_enable(struct s
|
||||
int ret, val;
|
||||
|
||||
val = read_sr(nor);
|
||||
+ if (val < 0)
|
||||
+ return val;
|
||||
write_enable(nor);
|
||||
|
||||
write_sr(nor, val | SR_QUAD_EN_MX);
|
||||
@@ -0,0 +1,66 @@
|
||||
From 3a06c61b48fbc23046928275e37a693e1055ae74 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ezequiel=20Garc=C3=ADa?= <ezequiel@vanguardiasur.com.ar>
|
||||
Date: Mon, 28 Dec 2015 17:54:51 -0300
|
||||
Subject: [PATCH 086/113] mtd: spi-nor: wait until lock/unlock operations are
|
||||
ready
|
||||
|
||||
On Micron and Numonyx devices, the status register write command
|
||||
(WRSR), raises a work-in-progress bit (WIP) on the status register.
|
||||
The datasheets for these devices specify that while the status
|
||||
register write is in progress, the status register WIP bit can still
|
||||
be read to check the end of the operation.
|
||||
|
||||
This commit adds a wait_till_ready call on lock/unlock operations,
|
||||
which is required for Micron and Numonyx but should be harmless for
|
||||
others. This is needed to prevent applications from issuing erase or
|
||||
program operations before the unlock operation is completed.
|
||||
|
||||
Reported-by: Stas Sergeev <stsp@list.ru>
|
||||
Signed-off-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
|
||||
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/spi-nor.c | 12 ++++++++++--
|
||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -481,6 +481,7 @@ static int stm_lock(struct spi_nor *nor,
|
||||
int status_old, status_new;
|
||||
u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
|
||||
u8 shift = ffs(mask) - 1, pow, val;
|
||||
+ int ret;
|
||||
|
||||
status_old = read_sr(nor);
|
||||
if (status_old < 0)
|
||||
@@ -519,7 +520,10 @@ static int stm_lock(struct spi_nor *nor,
|
||||
return -EINVAL;
|
||||
|
||||
write_enable(nor);
|
||||
- return write_sr(nor, status_new);
|
||||
+ ret = write_sr(nor, status_new);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ return spi_nor_wait_till_ready(nor);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -533,6 +537,7 @@ static int stm_unlock(struct spi_nor *no
|
||||
int status_old, status_new;
|
||||
u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
|
||||
u8 shift = ffs(mask) - 1, pow, val;
|
||||
+ int ret;
|
||||
|
||||
status_old = read_sr(nor);
|
||||
if (status_old < 0)
|
||||
@@ -569,7 +574,10 @@ static int stm_unlock(struct spi_nor *no
|
||||
return -EINVAL;
|
||||
|
||||
write_enable(nor);
|
||||
- return write_sr(nor, status_new);
|
||||
+ ret = write_sr(nor, status_new);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ return spi_nor_wait_till_ready(nor);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -0,0 +1,400 @@
|
||||
From c58b398221d88ac0db29c3bb7522a4f48dfa102c Mon Sep 17 00:00:00 2001
|
||||
From: Yuan Yao <yao.yuan@freescale.com>
|
||||
Date: Tue, 17 Nov 2015 16:13:47 +0800
|
||||
Subject: [PATCH 087/113] mtd: spi-nor: fsl-quadspi: add big-endian support
|
||||
|
||||
Add R/W functions for big- or little-endian registers:
|
||||
The qSPI controller's endian is independent of the CPU core's endian.
|
||||
So far, the qSPI have two versions for big-endian and little-endian.
|
||||
|
||||
Signed-off-by: Yuan Yao <yao.yuan@nxp.com>
|
||||
Acked-by: Han xu <han.xu@freescale.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 157 +++++++++++++++++++++++--------------
|
||||
1 file changed, 97 insertions(+), 60 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -275,6 +275,7 @@ struct fsl_qspi {
|
||||
u32 clk_rate;
|
||||
unsigned int chip_base_addr; /* We may support two chips. */
|
||||
bool has_second_chip;
|
||||
+ bool big_endian;
|
||||
struct mutex lock;
|
||||
struct pm_qos_request pm_qos_req;
|
||||
};
|
||||
@@ -300,6 +301,28 @@ static inline int needs_wakeup_wait_mode
|
||||
}
|
||||
|
||||
/*
|
||||
+ * R/W functions for big- or little-endian registers:
|
||||
+ * The qSPI controller's endian is independent of the CPU core's endian.
|
||||
+ * So far, although the CPU core is little-endian but the qSPI have two
|
||||
+ * versions for big-endian and little-endian.
|
||||
+ */
|
||||
+static void qspi_writel(struct fsl_qspi *q, u32 val, void __iomem *addr)
|
||||
+{
|
||||
+ if (q->big_endian)
|
||||
+ iowrite32be(val, addr);
|
||||
+ else
|
||||
+ iowrite32(val, addr);
|
||||
+}
|
||||
+
|
||||
+static u32 qspi_readl(struct fsl_qspi *q, void __iomem *addr)
|
||||
+{
|
||||
+ if (q->big_endian)
|
||||
+ return ioread32be(addr);
|
||||
+ else
|
||||
+ return ioread32(addr);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* An IC bug makes us to re-arrange the 32-bit data.
|
||||
* The following chips, such as IMX6SLX, have fixed this bug.
|
||||
*/
|
||||
@@ -310,14 +333,14 @@ static inline u32 fsl_qspi_endian_xchg(s
|
||||
|
||||
static inline void fsl_qspi_unlock_lut(struct fsl_qspi *q)
|
||||
{
|
||||
- writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
|
||||
- writel(QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR);
|
||||
+ qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
|
||||
+ qspi_writel(q, QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR);
|
||||
}
|
||||
|
||||
static inline void fsl_qspi_lock_lut(struct fsl_qspi *q)
|
||||
{
|
||||
- writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
|
||||
- writel(QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR);
|
||||
+ qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
|
||||
+ qspi_writel(q, QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR);
|
||||
}
|
||||
|
||||
static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
|
||||
@@ -326,8 +349,8 @@ static irqreturn_t fsl_qspi_irq_handler(
|
||||
u32 reg;
|
||||
|
||||
/* clear interrupt */
|
||||
- reg = readl(q->iobase + QUADSPI_FR);
|
||||
- writel(reg, q->iobase + QUADSPI_FR);
|
||||
+ reg = qspi_readl(q, q->iobase + QUADSPI_FR);
|
||||
+ qspi_writel(q, reg, q->iobase + QUADSPI_FR);
|
||||
|
||||
if (reg & QUADSPI_FR_TFF_MASK)
|
||||
complete(&q->c);
|
||||
@@ -348,7 +371,7 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
|
||||
/* Clear all the LUT table */
|
||||
for (i = 0; i < QUADSPI_LUT_NUM; i++)
|
||||
- writel(0, base + QUADSPI_LUT_BASE + i * 4);
|
||||
+ qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
|
||||
|
||||
/* Quad Read */
|
||||
lut_base = SEQID_QUAD_READ * 4;
|
||||
@@ -364,14 +387,15 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
dummy = 8;
|
||||
}
|
||||
|
||||
- writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
- writel(LUT0(DUMMY, PAD1, dummy) | LUT1(FSL_READ, PAD4, rxfifo),
|
||||
+ qspi_writel(q, LUT0(DUMMY, PAD1, dummy) | LUT1(FSL_READ, PAD4, rxfifo),
|
||||
base + QUADSPI_LUT(lut_base + 1));
|
||||
|
||||
/* Write enable */
|
||||
lut_base = SEQID_WREN * 4;
|
||||
- writel(LUT0(CMD, PAD1, SPINOR_OP_WREN), base + QUADSPI_LUT(lut_base));
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
|
||||
/* Page Program */
|
||||
lut_base = SEQID_PP * 4;
|
||||
@@ -385,13 +409,15 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
addrlen = ADDR32BIT;
|
||||
}
|
||||
|
||||
- writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
- writel(LUT0(FSL_WRITE, PAD1, 0), base + QUADSPI_LUT(lut_base + 1));
|
||||
+ qspi_writel(q, LUT0(FSL_WRITE, PAD1, 0),
|
||||
+ base + QUADSPI_LUT(lut_base + 1));
|
||||
|
||||
/* Read Status */
|
||||
lut_base = SEQID_RDSR * 4;
|
||||
- writel(LUT0(CMD, PAD1, SPINOR_OP_RDSR) | LUT1(FSL_READ, PAD1, 0x1),
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDSR) |
|
||||
+ LUT1(FSL_READ, PAD1, 0x1),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
|
||||
/* Erase a sector */
|
||||
@@ -400,40 +426,46 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
cmd = q->nor[0].erase_opcode;
|
||||
addrlen = q->nor_size <= SZ_16M ? ADDR24BIT : ADDR32BIT;
|
||||
|
||||
- writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
|
||||
/* Erase the whole chip */
|
||||
lut_base = SEQID_CHIP_ERASE * 4;
|
||||
- writel(LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
|
||||
/* READ ID */
|
||||
lut_base = SEQID_RDID * 4;
|
||||
- writel(LUT0(CMD, PAD1, SPINOR_OP_RDID) | LUT1(FSL_READ, PAD1, 0x8),
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDID) |
|
||||
+ LUT1(FSL_READ, PAD1, 0x8),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
|
||||
/* Write Register */
|
||||
lut_base = SEQID_WRSR * 4;
|
||||
- writel(LUT0(CMD, PAD1, SPINOR_OP_WRSR) | LUT1(FSL_WRITE, PAD1, 0x2),
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRSR) |
|
||||
+ LUT1(FSL_WRITE, PAD1, 0x2),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
|
||||
/* Read Configuration Register */
|
||||
lut_base = SEQID_RDCR * 4;
|
||||
- writel(LUT0(CMD, PAD1, SPINOR_OP_RDCR) | LUT1(FSL_READ, PAD1, 0x1),
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDCR) |
|
||||
+ LUT1(FSL_READ, PAD1, 0x1),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
|
||||
/* Write disable */
|
||||
lut_base = SEQID_WRDI * 4;
|
||||
- writel(LUT0(CMD, PAD1, SPINOR_OP_WRDI), base + QUADSPI_LUT(lut_base));
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRDI),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
|
||||
/* Enter 4 Byte Mode (Micron) */
|
||||
lut_base = SEQID_EN4B * 4;
|
||||
- writel(LUT0(CMD, PAD1, SPINOR_OP_EN4B), base + QUADSPI_LUT(lut_base));
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_EN4B),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
|
||||
/* Enter 4 Byte Mode (Spansion) */
|
||||
lut_base = SEQID_BRWR * 4;
|
||||
- writel(LUT0(CMD, PAD1, SPINOR_OP_BRWR), base + QUADSPI_LUT(lut_base));
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
|
||||
fsl_qspi_lock_lut(q);
|
||||
}
|
||||
@@ -488,15 +520,16 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 c
|
||||
q->chip_base_addr, addr, len, cmd);
|
||||
|
||||
/* save the reg */
|
||||
- reg = readl(base + QUADSPI_MCR);
|
||||
+ reg = qspi_readl(q, base + QUADSPI_MCR);
|
||||
|
||||
- writel(q->memmap_phy + q->chip_base_addr + addr, base + QUADSPI_SFAR);
|
||||
- writel(QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
|
||||
+ qspi_writel(q, q->memmap_phy + q->chip_base_addr + addr,
|
||||
+ base + QUADSPI_SFAR);
|
||||
+ qspi_writel(q, QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
|
||||
base + QUADSPI_RBCT);
|
||||
- writel(reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
|
||||
+ qspi_writel(q, reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
|
||||
|
||||
do {
|
||||
- reg2 = readl(base + QUADSPI_SR);
|
||||
+ reg2 = qspi_readl(q, base + QUADSPI_SR);
|
||||
if (reg2 & (QUADSPI_SR_IP_ACC_MASK | QUADSPI_SR_AHB_ACC_MASK)) {
|
||||
udelay(1);
|
||||
dev_dbg(q->dev, "The controller is busy, 0x%x\n", reg2);
|
||||
@@ -507,21 +540,22 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 c
|
||||
|
||||
/* trigger the LUT now */
|
||||
seqid = fsl_qspi_get_seqid(q, cmd);
|
||||
- writel((seqid << QUADSPI_IPCR_SEQID_SHIFT) | len, base + QUADSPI_IPCR);
|
||||
+ qspi_writel(q, (seqid << QUADSPI_IPCR_SEQID_SHIFT) | len,
|
||||
+ base + QUADSPI_IPCR);
|
||||
|
||||
/* Wait for the interrupt. */
|
||||
if (!wait_for_completion_timeout(&q->c, msecs_to_jiffies(1000))) {
|
||||
dev_err(q->dev,
|
||||
"cmd 0x%.2x timeout, addr@%.8x, FR:0x%.8x, SR:0x%.8x\n",
|
||||
- cmd, addr, readl(base + QUADSPI_FR),
|
||||
- readl(base + QUADSPI_SR));
|
||||
+ cmd, addr, qspi_readl(q, base + QUADSPI_FR),
|
||||
+ qspi_readl(q, base + QUADSPI_SR));
|
||||
err = -ETIMEDOUT;
|
||||
} else {
|
||||
err = 0;
|
||||
}
|
||||
|
||||
/* restore the MCR */
|
||||
- writel(reg, base + QUADSPI_MCR);
|
||||
+ qspi_writel(q, reg, base + QUADSPI_MCR);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -533,7 +567,7 @@ static void fsl_qspi_read_data(struct fs
|
||||
int i = 0;
|
||||
|
||||
while (len > 0) {
|
||||
- tmp = readl(q->iobase + QUADSPI_RBDR + i * 4);
|
||||
+ tmp = qspi_readl(q, q->iobase + QUADSPI_RBDR + i * 4);
|
||||
tmp = fsl_qspi_endian_xchg(q, tmp);
|
||||
dev_dbg(q->dev, "chip addr:0x%.8x, rcv:0x%.8x\n",
|
||||
q->chip_base_addr, tmp);
|
||||
@@ -561,9 +595,9 @@ static inline void fsl_qspi_invalid(stru
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
- reg = readl(q->iobase + QUADSPI_MCR);
|
||||
+ reg = qspi_readl(q, q->iobase + QUADSPI_MCR);
|
||||
reg |= QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK;
|
||||
- writel(reg, q->iobase + QUADSPI_MCR);
|
||||
+ qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
|
||||
|
||||
/*
|
||||
* The minimum delay : 1 AHB + 2 SFCK clocks.
|
||||
@@ -572,7 +606,7 @@ static inline void fsl_qspi_invalid(stru
|
||||
udelay(1);
|
||||
|
||||
reg &= ~(QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK);
|
||||
- writel(reg, q->iobase + QUADSPI_MCR);
|
||||
+ qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
|
||||
}
|
||||
|
||||
static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
|
||||
@@ -586,20 +620,20 @@ static int fsl_qspi_nor_write(struct fsl
|
||||
q->chip_base_addr, to, count);
|
||||
|
||||
/* clear the TX FIFO. */
|
||||
- tmp = readl(q->iobase + QUADSPI_MCR);
|
||||
- writel(tmp | QUADSPI_MCR_CLR_TXF_MASK, q->iobase + QUADSPI_MCR);
|
||||
+ tmp = qspi_readl(q, q->iobase + QUADSPI_MCR);
|
||||
+ qspi_writel(q, tmp | QUADSPI_MCR_CLR_TXF_MASK, q->iobase + QUADSPI_MCR);
|
||||
|
||||
/* fill the TX data to the FIFO */
|
||||
for (j = 0, i = ((count + 3) / 4); j < i; j++) {
|
||||
tmp = fsl_qspi_endian_xchg(q, *txbuf);
|
||||
- writel(tmp, q->iobase + QUADSPI_TBDR);
|
||||
+ qspi_writel(q, tmp, q->iobase + QUADSPI_TBDR);
|
||||
txbuf++;
|
||||
}
|
||||
|
||||
/* fill the TXFIFO upto 16 bytes for i.MX7d */
|
||||
if (needs_fill_txfifo(q))
|
||||
for (; i < 4; i++)
|
||||
- writel(tmp, q->iobase + QUADSPI_TBDR);
|
||||
+ qspi_writel(q, tmp, q->iobase + QUADSPI_TBDR);
|
||||
|
||||
/* Trigger it */
|
||||
ret = fsl_qspi_runcmd(q, opcode, to, count);
|
||||
@@ -615,10 +649,10 @@ static void fsl_qspi_set_map_addr(struct
|
||||
int nor_size = q->nor_size;
|
||||
void __iomem *base = q->iobase;
|
||||
|
||||
- writel(nor_size + q->memmap_phy, base + QUADSPI_SFA1AD);
|
||||
- writel(nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD);
|
||||
- writel(nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD);
|
||||
- writel(nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD);
|
||||
+ qspi_writel(q, nor_size + q->memmap_phy, base + QUADSPI_SFA1AD);
|
||||
+ qspi_writel(q, nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD);
|
||||
+ qspi_writel(q, nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD);
|
||||
+ qspi_writel(q, nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -640,24 +674,26 @@ static void fsl_qspi_init_abh_read(struc
|
||||
int seqid;
|
||||
|
||||
/* AHB configuration for access buffer 0/1/2 .*/
|
||||
- writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR);
|
||||
- writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR);
|
||||
- writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR);
|
||||
+ qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR);
|
||||
+ qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR);
|
||||
+ qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR);
|
||||
/*
|
||||
* Set ADATSZ with the maximum AHB buffer size to improve the
|
||||
* read performance.
|
||||
*/
|
||||
- writel(QUADSPI_BUF3CR_ALLMST_MASK | ((q->devtype_data->ahb_buf_size / 8)
|
||||
- << QUADSPI_BUF3CR_ADATSZ_SHIFT), base + QUADSPI_BUF3CR);
|
||||
+ qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
|
||||
+ ((q->devtype_data->ahb_buf_size / 8)
|
||||
+ << QUADSPI_BUF3CR_ADATSZ_SHIFT),
|
||||
+ base + QUADSPI_BUF3CR);
|
||||
|
||||
/* We only use the buffer3 */
|
||||
- writel(0, base + QUADSPI_BUF0IND);
|
||||
- writel(0, base + QUADSPI_BUF1IND);
|
||||
- writel(0, base + QUADSPI_BUF2IND);
|
||||
+ qspi_writel(q, 0, base + QUADSPI_BUF0IND);
|
||||
+ qspi_writel(q, 0, base + QUADSPI_BUF1IND);
|
||||
+ qspi_writel(q, 0, base + QUADSPI_BUF2IND);
|
||||
|
||||
/* Set the default lut sequence for AHB Read. */
|
||||
seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
|
||||
- writel(seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
|
||||
+ qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
|
||||
q->iobase + QUADSPI_BFGENCR);
|
||||
}
|
||||
|
||||
@@ -713,7 +749,7 @@ static int fsl_qspi_nor_setup(struct fsl
|
||||
return ret;
|
||||
|
||||
/* Reset the module */
|
||||
- writel(QUADSPI_MCR_SWRSTSD_MASK | QUADSPI_MCR_SWRSTHD_MASK,
|
||||
+ qspi_writel(q, QUADSPI_MCR_SWRSTSD_MASK | QUADSPI_MCR_SWRSTHD_MASK,
|
||||
base + QUADSPI_MCR);
|
||||
udelay(1);
|
||||
|
||||
@@ -721,24 +757,24 @@ static int fsl_qspi_nor_setup(struct fsl
|
||||
fsl_qspi_init_lut(q);
|
||||
|
||||
/* Disable the module */
|
||||
- writel(QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
|
||||
+ qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
|
||||
base + QUADSPI_MCR);
|
||||
|
||||
- reg = readl(base + QUADSPI_SMPR);
|
||||
- writel(reg & ~(QUADSPI_SMPR_FSDLY_MASK
|
||||
+ reg = qspi_readl(q, base + QUADSPI_SMPR);
|
||||
+ qspi_writel(q, reg & ~(QUADSPI_SMPR_FSDLY_MASK
|
||||
| QUADSPI_SMPR_FSPHS_MASK
|
||||
| QUADSPI_SMPR_HSENA_MASK
|
||||
| QUADSPI_SMPR_DDRSMP_MASK), base + QUADSPI_SMPR);
|
||||
|
||||
/* Enable the module */
|
||||
- writel(QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK,
|
||||
+ qspi_writel(q, QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK,
|
||||
base + QUADSPI_MCR);
|
||||
|
||||
/* clear all interrupt status */
|
||||
- writel(0xffffffff, q->iobase + QUADSPI_FR);
|
||||
+ qspi_writel(q, 0xffffffff, q->iobase + QUADSPI_FR);
|
||||
|
||||
/* enable the interrupt */
|
||||
- writel(QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
|
||||
+ qspi_writel(q, QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -954,6 +990,7 @@ static int fsl_qspi_probe(struct platfor
|
||||
if (IS_ERR(q->iobase))
|
||||
return PTR_ERR(q->iobase);
|
||||
|
||||
+ q->big_endian = of_property_read_bool(np, "big-endian");
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"QuadSPI-memory");
|
||||
if (!devm_request_mem_region(dev, res->start, resource_size(res),
|
||||
@@ -1101,8 +1138,8 @@ static int fsl_qspi_remove(struct platfo
|
||||
}
|
||||
|
||||
/* disable the hardware */
|
||||
- writel(QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
|
||||
- writel(0x0, q->iobase + QUADSPI_RSER);
|
||||
+ qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
|
||||
+ qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER);
|
||||
|
||||
mutex_destroy(&q->lock);
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
From da44c1517526822e73642fc71b034de8fc7d2b43 Mon Sep 17 00:00:00 2001
|
||||
From: Yuan Yao <yao.yuan@freescale.com>
|
||||
Date: Tue, 17 Nov 2015 16:44:45 +0800
|
||||
Subject: [PATCH 088/113] mtd: spi-nor: fsl-quadspi: add support for ls1021a
|
||||
|
||||
[context adjustment]
|
||||
|
||||
LS1021a also support Freescale Quad SPI controller.
|
||||
Add fsl-quadspi support for ls1021a chip and make SPI_FSL_QUADSPI
|
||||
selectable for LS1021A SOC hardwares.
|
||||
|
||||
Signed-off-by: Yuan Yao <yao.yuan@nxp.com>
|
||||
Acked-by: Han xu <han.xu@freescale.com>
|
||||
Integrated-by: Jiang Yutang <yutang.jiang@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/Kconfig | 2 +-
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 10 ++++++++++
|
||||
2 files changed, 11 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/Kconfig
|
||||
+++ b/drivers/mtd/spi-nor/Kconfig
|
||||
@@ -23,7 +23,7 @@ config MTD_SPI_NOR_USE_4K_SECTORS
|
||||
|
||||
config SPI_FSL_QUADSPI
|
||||
tristate "Freescale Quad SPI controller"
|
||||
- depends on ARCH_MXC || COMPILE_TEST
|
||||
+ depends on ARCH_MXC || SOC_LS1021A || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
help
|
||||
This enables support for the Quad SPI controller in master mode.
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -213,6 +213,7 @@ enum fsl_qspi_devtype {
|
||||
FSL_QUADSPI_IMX6SX,
|
||||
FSL_QUADSPI_IMX7D,
|
||||
FSL_QUADSPI_IMX6UL,
|
||||
+ FSL_QUADSPI_LS1021A,
|
||||
};
|
||||
|
||||
struct fsl_qspi_devtype_data {
|
||||
@@ -258,6 +259,14 @@ static struct fsl_qspi_devtype_data imx6
|
||||
| QUADSPI_QUIRK_4X_INT_CLK,
|
||||
};
|
||||
|
||||
+static struct fsl_qspi_devtype_data ls1021a_data = {
|
||||
+ .devtype = FSL_QUADSPI_LS1021A,
|
||||
+ .rxfifo = 128,
|
||||
+ .txfifo = 64,
|
||||
+ .ahb_buf_size = 1024,
|
||||
+ .driver_data = 0,
|
||||
+};
|
||||
+
|
||||
#define FSL_QSPI_MAX_CHIP 4
|
||||
struct fsl_qspi {
|
||||
struct spi_nor nor[FSL_QSPI_MAX_CHIP];
|
||||
@@ -812,6 +821,7 @@ static const struct of_device_id fsl_qsp
|
||||
{ .compatible = "fsl,imx6sx-qspi", .data = (void *)&imx6sx_data, },
|
||||
{ .compatible = "fsl,imx7d-qspi", .data = (void *)&imx7d_data, },
|
||||
{ .compatible = "fsl,imx6ul-qspi", .data = (void *)&imx6ul_data, },
|
||||
+ { .compatible = "fsl,ls1021a-qspi", .data = (void *)&ls1021a_data, },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids);
|
||||
@@ -0,0 +1,28 @@
|
||||
From 9c6153130081ef2c109e2a243a598f2bc0dc6413 Mon Sep 17 00:00:00 2001
|
||||
From: Yuan Yao <yao.yuan@freescale.com>
|
||||
Date: Tue, 17 Nov 2015 17:06:47 +0800
|
||||
Subject: [PATCH 089/113] mtd: spi-nor: fsl-quadspi: add support for
|
||||
layerscape
|
||||
|
||||
[context adjustment]
|
||||
|
||||
LS1043a and LS2080A in the Layerscape family also support Freescale Quad
|
||||
SPI, make Quad SPI selectable for these hardwares.
|
||||
|
||||
Signed-off-by: Yuan Yao <yao.yuan@nxp.com>
|
||||
Integrated-by: Jiang Yutang <yutang.jiang@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/Kconfig
|
||||
+++ b/drivers/mtd/spi-nor/Kconfig
|
||||
@@ -23,7 +23,7 @@ config MTD_SPI_NOR_USE_4K_SECTORS
|
||||
|
||||
config SPI_FSL_QUADSPI
|
||||
tristate "Freescale Quad SPI controller"
|
||||
- depends on ARCH_MXC || SOC_LS1021A || COMPILE_TEST
|
||||
+ depends on ARCH_MXC || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
help
|
||||
This enables support for the Quad SPI controller in master mode.
|
||||
@@ -0,0 +1,137 @@
|
||||
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
|
||||
@@ -0,0 +1,82 @@
|
||||
From 0a8079b232e9188ba267e37e20f192bed6c2b29b Mon Sep 17 00:00:00 2001
|
||||
From: Michal Suchanek <hramrach@gmail.com>
|
||||
Date: Wed, 2 Dec 2015 10:38:19 +0000
|
||||
Subject: [PATCH 091/113] mtd: spi-nor: change return value of read/write
|
||||
|
||||
Change the return value of spi-nor device read and write methods to
|
||||
allow returning amount of data transferred and errors as
|
||||
read(2)/write(2) does.
|
||||
|
||||
Signed-off-by: Michal Suchanek <hramrach@gmail.com>
|
||||
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@freescale.com>
|
||||
---
|
||||
drivers/mtd/devices/m25p80.c | 5 +++--
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 5 +++--
|
||||
include/linux/mtd/spi-nor.h | 4 ++--
|
||||
3 files changed, 8 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/devices/m25p80.c
|
||||
+++ b/drivers/mtd/devices/m25p80.c
|
||||
@@ -73,7 +73,7 @@ static int m25p80_write_reg(struct spi_n
|
||||
return spi_write(spi, flash->command, len + 1);
|
||||
}
|
||||
|
||||
-static void m25p80_write(struct spi_nor *nor, loff_t to, size_t len,
|
||||
+static ssize_t m25p80_write(struct spi_nor *nor, loff_t to, size_t len,
|
||||
size_t *retlen, const u_char *buf)
|
||||
{
|
||||
struct m25p *flash = nor->priv;
|
||||
@@ -101,6 +101,7 @@ static void m25p80_write(struct spi_nor
|
||||
spi_sync(spi, &m);
|
||||
|
||||
*retlen += m.actual_length - cmd_sz;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static inline unsigned int m25p80_rx_nbits(struct spi_nor *nor)
|
||||
@@ -119,7 +120,7 @@ static inline unsigned int m25p80_rx_nbi
|
||||
* Read an address range from the nor chip. The address range
|
||||
* may be any size provided it is within the physical boundaries.
|
||||
*/
|
||||
-static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len,
|
||||
+static ssize_t m25p80_read(struct spi_nor *nor, loff_t from, size_t len,
|
||||
size_t *retlen, u_char *buf)
|
||||
{
|
||||
struct m25p *flash = nor->priv;
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -868,7 +868,7 @@ static int fsl_qspi_write_reg(struct spi
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static void fsl_qspi_write(struct spi_nor *nor, loff_t to,
|
||||
+static ssize_t fsl_qspi_write(struct spi_nor *nor, loff_t to,
|
||||
size_t len, size_t *retlen, const u_char *buf)
|
||||
{
|
||||
struct fsl_qspi *q = nor->priv;
|
||||
@@ -878,9 +878,10 @@ static void fsl_qspi_write(struct spi_no
|
||||
|
||||
/* invalid the data in the AHB buffer. */
|
||||
fsl_qspi_invalid(q);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
-static int fsl_qspi_read(struct spi_nor *nor, loff_t from,
|
||||
+static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from,
|
||||
size_t len, size_t *retlen, u_char *buf)
|
||||
{
|
||||
struct fsl_qspi *q = nor->priv;
|
||||
--- a/include/linux/mtd/spi-nor.h
|
||||
+++ b/include/linux/mtd/spi-nor.h
|
||||
@@ -170,9 +170,9 @@ struct spi_nor {
|
||||
int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len);
|
||||
int (*write_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len);
|
||||
|
||||
- int (*read)(struct spi_nor *nor, loff_t from,
|
||||
+ ssize_t (*read)(struct spi_nor *nor, loff_t from,
|
||||
size_t len, size_t *retlen, u_char *read_buf);
|
||||
- void (*write)(struct spi_nor *nor, loff_t to,
|
||||
+ ssize_t (*write)(struct spi_nor *nor, loff_t to,
|
||||
size_t len, size_t *retlen, const u_char *write_buf);
|
||||
int (*erase)(struct spi_nor *nor, loff_t offs);
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
From 99768b3062501b05810fb62545279da3a4371ca0 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Suchanek <hramrach@gmail.com>
|
||||
Date: Wed, 2 Dec 2015 10:38:19 +0000
|
||||
Subject: [PATCH 092/113] mtd: fsl-quadspi: return amount of data read/written
|
||||
or error
|
||||
|
||||
Return amount of data read/written or error as read(2)/write(2) does.
|
||||
|
||||
Signed-off-by: Michal Suchanek <hramrach@gmail.com>
|
||||
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@freescale.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 18 +++++++++++-------
|
||||
1 file changed, 11 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -618,7 +618,7 @@ static inline void fsl_qspi_invalid(stru
|
||||
qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
|
||||
}
|
||||
|
||||
-static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
|
||||
+static ssize_t fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
|
||||
u8 opcode, unsigned int to, u32 *txbuf,
|
||||
unsigned count, size_t *retlen)
|
||||
{
|
||||
@@ -647,8 +647,11 @@ static int fsl_qspi_nor_write(struct fsl
|
||||
/* Trigger it */
|
||||
ret = fsl_qspi_runcmd(q, opcode, to, count);
|
||||
|
||||
- if (ret == 0 && retlen)
|
||||
- *retlen += count;
|
||||
+ if (ret == 0) {
|
||||
+ if (retlen)
|
||||
+ *retlen += count;
|
||||
+ return count;
|
||||
+ }
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -860,6 +863,8 @@ static int fsl_qspi_write_reg(struct spi
|
||||
} else if (len > 0) {
|
||||
ret = fsl_qspi_nor_write(q, nor, opcode, 0,
|
||||
(u32 *)buf, len, NULL);
|
||||
+ if (ret > 0)
|
||||
+ return 0;
|
||||
} else {
|
||||
dev_err(q->dev, "invalid cmd %d\n", opcode);
|
||||
ret = -EINVAL;
|
||||
@@ -873,12 +878,12 @@ static ssize_t fsl_qspi_write(struct spi
|
||||
{
|
||||
struct fsl_qspi *q = nor->priv;
|
||||
|
||||
- fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
|
||||
+ ssize_t ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
|
||||
(u32 *)buf, len, retlen);
|
||||
|
||||
/* invalid the data in the AHB buffer. */
|
||||
fsl_qspi_invalid(q);
|
||||
- return 0;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from,
|
||||
@@ -924,8 +929,7 @@ static ssize_t fsl_qspi_read(struct spi_
|
||||
memcpy(buf, q->ahb_addr + q->chip_base_addr + from - q->memmap_offs,
|
||||
len);
|
||||
|
||||
- *retlen += len;
|
||||
- return 0;
|
||||
+ return len;
|
||||
}
|
||||
|
||||
static int fsl_qspi_erase(struct spi_nor *nor, loff_t offs)
|
||||
@@ -0,0 +1,127 @@
|
||||
From 8527843351169d999995d331bbdad75560ccafb2 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Suchanek <hramrach@gmail.com>
|
||||
Date: Wed, 2 Dec 2015 10:38:20 +0000
|
||||
Subject: [PATCH 093/113] mtd: spi-nor: check return value from read/write
|
||||
|
||||
SPI NOR hardware drivers now return useful value from their read/write
|
||||
functions so check them.
|
||||
|
||||
Signed-off-by: Michal Suchanek <hramrach@gmail.com>
|
||||
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@freescale.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/spi-nor.c | 50 +++++++++++++++++++++++++++++------------
|
||||
1 file changed, 36 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -922,7 +922,10 @@ static int spi_nor_read(struct mtd_info
|
||||
ret = nor->read(nor, from, len, retlen, buf);
|
||||
|
||||
spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ);
|
||||
- return ret;
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
@@ -948,10 +951,14 @@ static int sst_write(struct mtd_info *mt
|
||||
nor->program_opcode = SPINOR_OP_BP;
|
||||
|
||||
/* write one byte. */
|
||||
- nor->write(nor, to, 1, retlen, buf);
|
||||
+ ret = nor->write(nor, to, 1, retlen, buf);
|
||||
+ if (ret < 0)
|
||||
+ goto sst_write_err;
|
||||
+ WARN(ret != 1, "While writing 1 byte written %i bytes\n",
|
||||
+ (int)ret);
|
||||
ret = spi_nor_wait_till_ready(nor);
|
||||
if (ret)
|
||||
- goto time_out;
|
||||
+ goto sst_write_err;
|
||||
}
|
||||
to += actual;
|
||||
|
||||
@@ -960,10 +967,14 @@ static int sst_write(struct mtd_info *mt
|
||||
nor->program_opcode = SPINOR_OP_AAI_WP;
|
||||
|
||||
/* write two bytes. */
|
||||
- nor->write(nor, to, 2, retlen, buf + actual);
|
||||
+ ret = nor->write(nor, to, 2, retlen, buf + actual);
|
||||
+ if (ret < 0)
|
||||
+ goto sst_write_err;
|
||||
+ WARN(ret != 2, "While writing 2 bytes written %i bytes\n",
|
||||
+ (int)ret);
|
||||
ret = spi_nor_wait_till_ready(nor);
|
||||
if (ret)
|
||||
- goto time_out;
|
||||
+ goto sst_write_err;
|
||||
to += 2;
|
||||
nor->sst_write_second = true;
|
||||
}
|
||||
@@ -972,21 +983,24 @@ static int sst_write(struct mtd_info *mt
|
||||
write_disable(nor);
|
||||
ret = spi_nor_wait_till_ready(nor);
|
||||
if (ret)
|
||||
- goto time_out;
|
||||
+ goto sst_write_err;
|
||||
|
||||
/* Write out trailing byte if it exists. */
|
||||
if (actual != len) {
|
||||
write_enable(nor);
|
||||
|
||||
nor->program_opcode = SPINOR_OP_BP;
|
||||
- nor->write(nor, to, 1, retlen, buf + actual);
|
||||
-
|
||||
+ ret = nor->write(nor, to, 1, retlen, buf + actual);
|
||||
+ if (ret < 0)
|
||||
+ goto sst_write_err;
|
||||
+ WARN(ret != 1, "While writing 1 byte written %i bytes\n",
|
||||
+ (int)ret);
|
||||
ret = spi_nor_wait_till_ready(nor);
|
||||
if (ret)
|
||||
- goto time_out;
|
||||
+ goto sst_write_err;
|
||||
write_disable(nor);
|
||||
}
|
||||
-time_out:
|
||||
+sst_write_err:
|
||||
spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
|
||||
return ret;
|
||||
}
|
||||
@@ -1015,14 +1029,18 @@ static int spi_nor_write(struct mtd_info
|
||||
|
||||
/* do all the bytes fit onto one page? */
|
||||
if (page_offset + len <= nor->page_size) {
|
||||
- nor->write(nor, to, len, retlen, buf);
|
||||
+ ret = nor->write(nor, to, len, retlen, buf);
|
||||
+ if (ret < 0)
|
||||
+ goto write_err;
|
||||
} else {
|
||||
/* the size of data remaining on the first page */
|
||||
page_size = nor->page_size - page_offset;
|
||||
- nor->write(nor, to, page_size, retlen, buf);
|
||||
+ ret = nor->write(nor, to, page_size, retlen, buf);
|
||||
+ if (ret < 0)
|
||||
+ goto write_err;
|
||||
|
||||
/* write everything in nor->page_size chunks */
|
||||
- for (i = page_size; i < len; i += page_size) {
|
||||
+ for (i = ret; i < len; ) {
|
||||
page_size = len - i;
|
||||
if (page_size > nor->page_size)
|
||||
page_size = nor->page_size;
|
||||
@@ -1033,7 +1051,11 @@ static int spi_nor_write(struct mtd_info
|
||||
|
||||
write_enable(nor);
|
||||
|
||||
- nor->write(nor, to + i, page_size, retlen, buf + i);
|
||||
+ ret = nor->write(nor, to + i, page_size, retlen,
|
||||
+ buf + i);
|
||||
+ if (ret < 0)
|
||||
+ goto write_err;
|
||||
+ i += ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
From a99477d72b500b48cb3614aad0ce096fe4e3f437 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Suchanek <hramrach@gmail.com>
|
||||
Date: Wed, 2 Dec 2015 10:38:20 +0000
|
||||
Subject: [PATCH 094/113] mtd: spi-nor: stop passing around retlen
|
||||
|
||||
[context adjustment]
|
||||
not apply changes of drivers/mtd/devices/m25p80.c
|
||||
#################
|
||||
@@ -74,7 +74,7 @@ static int m25p80_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
|
||||
}
|
||||
|
||||
static ssize_t m25p80_write(struct spi_nor *nor, loff_t to, size_t len,
|
||||
- size_t *retlen, const u_char *buf)
|
||||
+ const u_char *buf)
|
||||
{
|
||||
struct m25p *flash = nor->priv;
|
||||
struct spi_device *spi = flash->spi;
|
||||
@@ -106,7 +106,6 @@ static ssize_t m25p80_write(struct spi_nor *nor, loff_t to, size_t len,
|
||||
ret = m.actual_length - cmd_sz;
|
||||
if (ret < 0)
|
||||
return -EIO;
|
||||
- *retlen += ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -127,7 +126,7 @@ static inline unsigned int m25p80_rx_nbits(struct spi_nor *nor)
|
||||
* may be any size provided it is within the physical boundaries.
|
||||
*/
|
||||
static ssize_t m25p80_read(struct spi_nor *nor, loff_t from, size_t len,
|
||||
- size_t *retlen, u_char *buf)
|
||||
+ u_char *buf)
|
||||
{
|
||||
struct m25p *flash = nor->priv;
|
||||
struct spi_device *spi = flash->spi;
|
||||
@@ -161,7 +160,6 @@ static ssize_t m25p80_read(struct spi_nor *nor, loff_t from, size_t len,
|
||||
ret = m.actual_length - m25p_cmdsz(nor) - dummy;
|
||||
if (ret < 0)
|
||||
return -EIO;
|
||||
- *retlen += ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#################
|
||||
|
||||
Do not pass retlen to hardware driver read/write functions. Update it in
|
||||
spi-nor generic driver instead.
|
||||
|
||||
Signed-off-by: Michal Suchanek <hramrach@gmail.com>
|
||||
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@freescale.com>
|
||||
Integrated-by: Jiang Yutang <yutang.jiang@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 16 ++++++----------
|
||||
drivers/mtd/spi-nor/spi-nor.c | 21 +++++++++++++--------
|
||||
include/linux/mtd/spi-nor.h | 4 ++--
|
||||
3 files changed, 21 insertions(+), 20 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -620,7 +620,7 @@ static inline void fsl_qspi_invalid(stru
|
||||
|
||||
static ssize_t fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
|
||||
u8 opcode, unsigned int to, u32 *txbuf,
|
||||
- unsigned count, size_t *retlen)
|
||||
+ unsigned count)
|
||||
{
|
||||
int ret, i, j;
|
||||
u32 tmp;
|
||||
@@ -647,11 +647,8 @@ static ssize_t fsl_qspi_nor_write(struct
|
||||
/* Trigger it */
|
||||
ret = fsl_qspi_runcmd(q, opcode, to, count);
|
||||
|
||||
- if (ret == 0) {
|
||||
- if (retlen)
|
||||
- *retlen += count;
|
||||
+ if (ret == 0)
|
||||
return count;
|
||||
- }
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -862,7 +859,7 @@ static int fsl_qspi_write_reg(struct spi
|
||||
|
||||
} else if (len > 0) {
|
||||
ret = fsl_qspi_nor_write(q, nor, opcode, 0,
|
||||
- (u32 *)buf, len, NULL);
|
||||
+ (u32 *)buf, len);
|
||||
if (ret > 0)
|
||||
return 0;
|
||||
} else {
|
||||
@@ -874,12 +871,11 @@ static int fsl_qspi_write_reg(struct spi
|
||||
}
|
||||
|
||||
static ssize_t fsl_qspi_write(struct spi_nor *nor, loff_t to,
|
||||
- size_t len, size_t *retlen, const u_char *buf)
|
||||
+ size_t len, const u_char *buf)
|
||||
{
|
||||
struct fsl_qspi *q = nor->priv;
|
||||
-
|
||||
ssize_t ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
|
||||
- (u32 *)buf, len, retlen);
|
||||
+ (u32 *)buf, len);
|
||||
|
||||
/* invalid the data in the AHB buffer. */
|
||||
fsl_qspi_invalid(q);
|
||||
@@ -887,7 +883,7 @@ static ssize_t fsl_qspi_write(struct spi
|
||||
}
|
||||
|
||||
static ssize_t fsl_qspi_read(struct spi_nor *nor, loff_t from,
|
||||
- size_t len, size_t *retlen, u_char *buf)
|
||||
+ size_t len, u_char *buf)
|
||||
{
|
||||
struct fsl_qspi *q = nor->priv;
|
||||
u8 cmd = nor->read_opcode;
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -919,12 +919,13 @@ static int spi_nor_read(struct mtd_info
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- ret = nor->read(nor, from, len, retlen, buf);
|
||||
+ ret = nor->read(nor, from, len, buf);
|
||||
|
||||
spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
+ *retlen += ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -951,7 +952,7 @@ static int sst_write(struct mtd_info *mt
|
||||
nor->program_opcode = SPINOR_OP_BP;
|
||||
|
||||
/* write one byte. */
|
||||
- ret = nor->write(nor, to, 1, retlen, buf);
|
||||
+ ret = nor->write(nor, to, 1, buf);
|
||||
if (ret < 0)
|
||||
goto sst_write_err;
|
||||
WARN(ret != 1, "While writing 1 byte written %i bytes\n",
|
||||
@@ -967,7 +968,7 @@ static int sst_write(struct mtd_info *mt
|
||||
nor->program_opcode = SPINOR_OP_AAI_WP;
|
||||
|
||||
/* write two bytes. */
|
||||
- ret = nor->write(nor, to, 2, retlen, buf + actual);
|
||||
+ ret = nor->write(nor, to, 2, buf + actual);
|
||||
if (ret < 0)
|
||||
goto sst_write_err;
|
||||
WARN(ret != 2, "While writing 2 bytes written %i bytes\n",
|
||||
@@ -990,7 +991,7 @@ static int sst_write(struct mtd_info *mt
|
||||
write_enable(nor);
|
||||
|
||||
nor->program_opcode = SPINOR_OP_BP;
|
||||
- ret = nor->write(nor, to, 1, retlen, buf + actual);
|
||||
+ ret = nor->write(nor, to, 1, buf + actual);
|
||||
if (ret < 0)
|
||||
goto sst_write_err;
|
||||
WARN(ret != 1, "While writing 1 byte written %i bytes\n",
|
||||
@@ -999,8 +1000,10 @@ static int sst_write(struct mtd_info *mt
|
||||
if (ret)
|
||||
goto sst_write_err;
|
||||
write_disable(nor);
|
||||
+ actual += 1;
|
||||
}
|
||||
sst_write_err:
|
||||
+ *retlen += actual;
|
||||
spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
|
||||
return ret;
|
||||
}
|
||||
@@ -1029,15 +1032,17 @@ static int spi_nor_write(struct mtd_info
|
||||
|
||||
/* do all the bytes fit onto one page? */
|
||||
if (page_offset + len <= nor->page_size) {
|
||||
- ret = nor->write(nor, to, len, retlen, buf);
|
||||
+ ret = nor->write(nor, to, len, buf);
|
||||
if (ret < 0)
|
||||
goto write_err;
|
||||
+ *retlen += ret;
|
||||
} else {
|
||||
/* the size of data remaining on the first page */
|
||||
page_size = nor->page_size - page_offset;
|
||||
- ret = nor->write(nor, to, page_size, retlen, buf);
|
||||
+ ret = nor->write(nor, to, page_size, buf);
|
||||
if (ret < 0)
|
||||
goto write_err;
|
||||
+ *retlen += ret;
|
||||
|
||||
/* write everything in nor->page_size chunks */
|
||||
for (i = ret; i < len; ) {
|
||||
@@ -1051,10 +1056,10 @@ static int spi_nor_write(struct mtd_info
|
||||
|
||||
write_enable(nor);
|
||||
|
||||
- ret = nor->write(nor, to + i, page_size, retlen,
|
||||
- buf + i);
|
||||
+ ret = nor->write(nor, to + i, page_size, buf + i);
|
||||
if (ret < 0)
|
||||
goto write_err;
|
||||
+ *retlen += ret;
|
||||
i += ret;
|
||||
}
|
||||
}
|
||||
--- a/include/linux/mtd/spi-nor.h
|
||||
+++ b/include/linux/mtd/spi-nor.h
|
||||
@@ -171,9 +171,9 @@ struct spi_nor {
|
||||
int (*write_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len);
|
||||
|
||||
ssize_t (*read)(struct spi_nor *nor, loff_t from,
|
||||
- size_t len, size_t *retlen, u_char *read_buf);
|
||||
+ size_t len, u_char *read_buf);
|
||||
ssize_t (*write)(struct spi_nor *nor, loff_t to,
|
||||
- size_t len, size_t *retlen, const u_char *write_buf);
|
||||
+ size_t len, const u_char *write_buf);
|
||||
int (*erase)(struct spi_nor *nor, loff_t offs);
|
||||
|
||||
int (*flash_lock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
|
||||
@@ -0,0 +1,100 @@
|
||||
From 93b40e12f7e580a41c4aee5597579cc539fd8544 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Suchanek <hramrach@gmail.com>
|
||||
Date: Wed, 2 Dec 2015 10:38:20 +0000
|
||||
Subject: [PATCH 095/113] mtd: spi-nor: simplify write loop
|
||||
|
||||
The spi-nor write loop assumes that what is passed to the hardware
|
||||
driver write() is what gets written.
|
||||
|
||||
When write() writes less than page size at once data is dropped on the
|
||||
floor. Check the amount of data writen and exit if it does not match
|
||||
requested amount.
|
||||
|
||||
Signed-off-by: Michal Suchanek <hramrach@gmail.com>
|
||||
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@freescale.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/spi-nor.c | 58 ++++++++++++++++++-----------------------
|
||||
1 file changed, 25 insertions(+), 33 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -1017,8 +1017,8 @@ static int spi_nor_write(struct mtd_info
|
||||
size_t *retlen, const u_char *buf)
|
||||
{
|
||||
struct spi_nor *nor = mtd_to_spi_nor(mtd);
|
||||
- u32 page_offset, page_size, i;
|
||||
- int ret;
|
||||
+ size_t page_offset, page_remain, i;
|
||||
+ ssize_t ret;
|
||||
|
||||
dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
|
||||
|
||||
@@ -1026,45 +1026,37 @@ static int spi_nor_write(struct mtd_info
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- write_enable(nor);
|
||||
+ for (i = 0; i < len; ) {
|
||||
+ ssize_t written;
|
||||
|
||||
- page_offset = to & (nor->page_size - 1);
|
||||
-
|
||||
- /* do all the bytes fit onto one page? */
|
||||
- if (page_offset + len <= nor->page_size) {
|
||||
- ret = nor->write(nor, to, len, buf);
|
||||
- if (ret < 0)
|
||||
- goto write_err;
|
||||
- *retlen += ret;
|
||||
- } else {
|
||||
+ page_offset = to & (nor->page_size - 1);
|
||||
+ WARN_ONCE(page_offset,
|
||||
+ "Writing at offset %zu into a NOR page. Writing partial pages may decrease reliability and increase wear of NOR flash.",
|
||||
+ page_offset);
|
||||
/* the size of data remaining on the first page */
|
||||
- page_size = nor->page_size - page_offset;
|
||||
- ret = nor->write(nor, to, page_size, buf);
|
||||
+ page_remain = min_t(size_t,
|
||||
+ nor->page_size - page_offset, len - i);
|
||||
+
|
||||
+ write_enable(nor);
|
||||
+ ret = nor->write(nor, to + i, page_remain, buf + i);
|
||||
if (ret < 0)
|
||||
goto write_err;
|
||||
- *retlen += ret;
|
||||
+ written = ret;
|
||||
|
||||
- /* write everything in nor->page_size chunks */
|
||||
- for (i = ret; i < len; ) {
|
||||
- page_size = len - i;
|
||||
- if (page_size > nor->page_size)
|
||||
- page_size = nor->page_size;
|
||||
-
|
||||
- ret = spi_nor_wait_till_ready(nor);
|
||||
- if (ret)
|
||||
- goto write_err;
|
||||
-
|
||||
- write_enable(nor);
|
||||
-
|
||||
- ret = nor->write(nor, to + i, page_size, buf + i);
|
||||
- if (ret < 0)
|
||||
- goto write_err;
|
||||
- *retlen += ret;
|
||||
- i += ret;
|
||||
+ ret = spi_nor_wait_till_ready(nor);
|
||||
+ if (ret)
|
||||
+ goto write_err;
|
||||
+ *retlen += written;
|
||||
+ i += written;
|
||||
+ if (written != page_remain) {
|
||||
+ dev_err(nor->dev,
|
||||
+ "While writing %zu bytes written %zd bytes\n",
|
||||
+ page_remain, written);
|
||||
+ ret = -EIO;
|
||||
+ goto write_err;
|
||||
}
|
||||
}
|
||||
|
||||
- ret = spi_nor_wait_till_ready(nor);
|
||||
write_err:
|
||||
spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
|
||||
return ret;
|
||||
@@ -0,0 +1,46 @@
|
||||
From b5929f91416d64afacf46c649f38cc8f0eea50d2 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Suchanek <hramrach@gmail.com>
|
||||
Date: Wed, 2 Dec 2015 10:38:20 +0000
|
||||
Subject: [PATCH 096/113] mtd: spi-nor: add read loop
|
||||
|
||||
mtdblock and ubi do not handle the situation when read returns less data
|
||||
than requested. Loop in spi-nor until buffer is filled or an error is
|
||||
returned.
|
||||
|
||||
Signed-off-by: Michal Suchanek <hramrach@gmail.com>
|
||||
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@freescale.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/spi-nor.c | 20 ++++++++++++++------
|
||||
1 file changed, 14 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -919,14 +919,22 @@ static int spi_nor_read(struct mtd_info
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- ret = nor->read(nor, from, len, buf);
|
||||
+ while (len) {
|
||||
+ ret = nor->read(nor, from, len, buf);
|
||||
+ if (ret <= 0)
|
||||
+ goto read_err;
|
||||
|
||||
- spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
+ WARN_ON(ret > len);
|
||||
+ *retlen += ret;
|
||||
+ buf += ret;
|
||||
+ from += ret;
|
||||
+ len -= ret;
|
||||
+ }
|
||||
+ ret = 0;
|
||||
|
||||
- *retlen += ret;
|
||||
- return 0;
|
||||
+read_err:
|
||||
+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
@@ -0,0 +1,87 @@
|
||||
From 5c315652c1b43a6a3abe48c2842cde822ac0ff3c Mon Sep 17 00:00:00 2001
|
||||
From: Yunhui Cui <B56489@freescale.com>
|
||||
Date: Wed, 20 Jan 2016 18:40:31 +0800
|
||||
Subject: [PATCH 097/113] mtd:fsl-quadspi:use the property fields of SPI-NOR
|
||||
|
||||
We can get the read/write/erase opcode from the spi nor framework
|
||||
directly. This patch uses the information stored in the SPI-NOR to
|
||||
remove the hardcode in the fsl_qspi_init_lut().
|
||||
|
||||
Signed-off-by: Yunhui Cui <B56489@freescale.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 40 +++++++++++--------------------------
|
||||
1 file changed, 12 insertions(+), 28 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -373,9 +373,13 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
void __iomem *base = q->iobase;
|
||||
int rxfifo = q->devtype_data->rxfifo;
|
||||
u32 lut_base;
|
||||
- u8 cmd, addrlen, dummy;
|
||||
int i;
|
||||
|
||||
+ struct spi_nor *nor = &q->nor[0];
|
||||
+ u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
|
||||
+ u8 read_op = nor->read_opcode;
|
||||
+ u8 read_dm = nor->read_dummy;
|
||||
+
|
||||
fsl_qspi_unlock_lut(q);
|
||||
|
||||
/* Clear all the LUT table */
|
||||
@@ -385,20 +389,10 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
/* Quad Read */
|
||||
lut_base = SEQID_QUAD_READ * 4;
|
||||
|
||||
- if (q->nor_size <= SZ_16M) {
|
||||
- cmd = SPINOR_OP_READ_1_1_4;
|
||||
- addrlen = ADDR24BIT;
|
||||
- dummy = 8;
|
||||
- } else {
|
||||
- /* use the 4-byte address */
|
||||
- cmd = SPINOR_OP_READ_1_1_4;
|
||||
- addrlen = ADDR32BIT;
|
||||
- dummy = 8;
|
||||
- }
|
||||
-
|
||||
- qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD1, addrlen),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
- qspi_writel(q, LUT0(DUMMY, PAD1, dummy) | LUT1(FSL_READ, PAD4, rxfifo),
|
||||
+ qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
|
||||
+ LUT1(FSL_READ, PAD4, rxfifo),
|
||||
base + QUADSPI_LUT(lut_base + 1));
|
||||
|
||||
/* Write enable */
|
||||
@@ -409,16 +403,8 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
/* Page Program */
|
||||
lut_base = SEQID_PP * 4;
|
||||
|
||||
- if (q->nor_size <= SZ_16M) {
|
||||
- cmd = SPINOR_OP_PP;
|
||||
- addrlen = ADDR24BIT;
|
||||
- } else {
|
||||
- /* use the 4-byte address */
|
||||
- cmd = SPINOR_OP_PP;
|
||||
- addrlen = ADDR32BIT;
|
||||
- }
|
||||
-
|
||||
- qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, nor->program_opcode) |
|
||||
+ LUT1(ADDR, PAD1, addrlen),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
qspi_writel(q, LUT0(FSL_WRITE, PAD1, 0),
|
||||
base + QUADSPI_LUT(lut_base + 1));
|
||||
@@ -432,10 +418,8 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
/* Erase a sector */
|
||||
lut_base = SEQID_SE * 4;
|
||||
|
||||
- cmd = q->nor[0].erase_opcode;
|
||||
- addrlen = q->nor_size <= SZ_16M ? ADDR24BIT : ADDR32BIT;
|
||||
-
|
||||
- qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, nor->erase_opcode) |
|
||||
+ LUT1(ADDR, PAD1, addrlen),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
|
||||
/* Erase the whole chip */
|
||||
@@ -0,0 +1,46 @@
|
||||
From c8f9be7df954fce18e96074af3f07aa5f75399e0 Mon Sep 17 00:00:00 2001
|
||||
From: Yunhui Cui <B56489@freescale.com>
|
||||
Date: Wed, 20 Jan 2016 15:52:25 +0800
|
||||
Subject: [PATCH 098/113] mtd: fsl-quadspi: Rename SEQID_QUAD_READ to
|
||||
SEQID_READ
|
||||
|
||||
There are some read modes for flash, such as NORMAL, FAST,
|
||||
QUAD, DDR QUAD. These modes will use the identical lut table base
|
||||
So rename SEQID_QUAD_READ to SEQID_READ.
|
||||
|
||||
Signed-off-by: Yunhui Cui <B56489@freescale.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -193,7 +193,7 @@
|
||||
#define QUADSPI_LUT_NUM 64
|
||||
|
||||
/* SEQID -- we can have 16 seqids at most. */
|
||||
-#define SEQID_QUAD_READ 0
|
||||
+#define SEQID_READ 0
|
||||
#define SEQID_WREN 1
|
||||
#define SEQID_WRDI 2
|
||||
#define SEQID_RDSR 3
|
||||
@@ -386,8 +386,8 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
for (i = 0; i < QUADSPI_LUT_NUM; i++)
|
||||
qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
|
||||
|
||||
- /* Quad Read */
|
||||
- lut_base = SEQID_QUAD_READ * 4;
|
||||
+ /* Read */
|
||||
+ lut_base = SEQID_READ * 4;
|
||||
|
||||
qspi_writel(q, LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD1, addrlen),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
@@ -468,7 +468,7 @@ static int fsl_qspi_get_seqid(struct fsl
|
||||
{
|
||||
switch (cmd) {
|
||||
case SPINOR_OP_READ_1_1_4:
|
||||
- return SEQID_QUAD_READ;
|
||||
+ return SEQID_READ;
|
||||
case SPINOR_OP_WREN:
|
||||
return SEQID_WREN;
|
||||
case SPINOR_OP_WRDI:
|
||||
@@ -0,0 +1,72 @@
|
||||
From c501cdf57682265b72a8180c06e4a01dc2978375 Mon Sep 17 00:00:00 2001
|
||||
From: Yunhui Cui <B56489@freescale.com>
|
||||
Date: Mon, 1 Feb 2016 18:26:23 +0800
|
||||
Subject: [PATCH 099/113] mtd:spi-nor:fsl-quadspi:Add fast-read mode support
|
||||
|
||||
The qspi driver add generic fast-read mode for different
|
||||
flash venders. There are some different board flash work on
|
||||
different mode, such fast-read, quad-mode.
|
||||
So we have to modify the third entrace parameter of spi_nor_scan().
|
||||
|
||||
Signed-off-by: Yunhui Cui <B56489@freescale.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 27 +++++++++++++++++++++------
|
||||
1 file changed, 21 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -389,11 +389,21 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
/* Read */
|
||||
lut_base = SEQID_READ * 4;
|
||||
|
||||
- qspi_writel(q, LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD1, addrlen),
|
||||
- base + QUADSPI_LUT(lut_base));
|
||||
- qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
|
||||
- LUT1(FSL_READ, PAD4, rxfifo),
|
||||
- base + QUADSPI_LUT(lut_base + 1));
|
||||
+ if (nor->flash_read == SPI_NOR_FAST) {
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, read_op) |
|
||||
+ LUT1(ADDR, PAD1, addrlen),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+ qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
|
||||
+ LUT1(FSL_READ, PAD1, rxfifo),
|
||||
+ base + QUADSPI_LUT(lut_base + 1));
|
||||
+ } else if (nor->flash_read == SPI_NOR_QUAD) {
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, read_op) |
|
||||
+ LUT1(ADDR, PAD1, addrlen),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+ qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
|
||||
+ LUT1(FSL_READ, PAD4, rxfifo),
|
||||
+ base + QUADSPI_LUT(lut_base + 1));
|
||||
+ }
|
||||
|
||||
/* Write enable */
|
||||
lut_base = SEQID_WREN * 4;
|
||||
@@ -468,6 +478,7 @@ static int fsl_qspi_get_seqid(struct fsl
|
||||
{
|
||||
switch (cmd) {
|
||||
case SPINOR_OP_READ_1_1_4:
|
||||
+ case SPINOR_OP_READ_FAST:
|
||||
return SEQID_READ;
|
||||
case SPINOR_OP_WREN:
|
||||
return SEQID_WREN;
|
||||
@@ -964,6 +975,7 @@ static int fsl_qspi_probe(struct platfor
|
||||
struct spi_nor *nor;
|
||||
struct mtd_info *mtd;
|
||||
int ret, i = 0;
|
||||
+ enum read_mode mode = SPI_NOR_QUAD;
|
||||
|
||||
q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
|
||||
if (!q)
|
||||
@@ -1065,7 +1077,10 @@ static int fsl_qspi_probe(struct platfor
|
||||
/* set the chip address for READID */
|
||||
fsl_qspi_set_base_addr(q, nor);
|
||||
|
||||
- ret = spi_nor_scan(nor, NULL, SPI_NOR_QUAD);
|
||||
+ ret = of_property_read_bool(np, "m25p,fast-read");
|
||||
+ mode = (ret) ? SPI_NOR_FAST : SPI_NOR_QUAD;
|
||||
+
|
||||
+ ret = spi_nor_scan(nor, NULL, mode);
|
||||
if (ret)
|
||||
goto mutex_failed;
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
From e892dea7229d56b75c46a76b9039f9e179584a91 Mon Sep 17 00:00:00 2001
|
||||
From: Yunhui Cui <B56489@freescale.com>
|
||||
Date: Mon, 1 Feb 2016 18:48:49 +0800
|
||||
Subject: [PATCH 100/113] mtd:spi_nor: Disable Micron flash HW protection
|
||||
|
||||
For Micron family ,The status register write enable/disable bit,
|
||||
provides hardware data protection for the device.
|
||||
When the enable/disable bit is set to 1, the status register
|
||||
nonvolatile bits become read-only and the WRITE STATUS REGISTER
|
||||
operation will not execute.
|
||||
|
||||
Signed-off-by: Yunhui Cui <B56489@freescale.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/spi-nor.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#define SPI_NOR_MAX_ID_LEN 6
|
||||
#define SPI_NOR_MAX_ADDR_WIDTH 4
|
||||
+#define SPI_NOR_MICRON_WRITE_ENABLE 0x7f
|
||||
|
||||
struct flash_info {
|
||||
char *name;
|
||||
@@ -1237,6 +1238,14 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ if (JEDEC_MFR(info) == SNOR_MFR_MICRON) {
|
||||
+ ret = read_sr(nor);
|
||||
+ ret &= SPI_NOR_MICRON_WRITE_ENABLE;
|
||||
+
|
||||
+ write_enable(nor);
|
||||
+ write_sr(nor, ret);
|
||||
+ }
|
||||
+
|
||||
if (!mtd->name)
|
||||
mtd->name = dev_name(dev);
|
||||
mtd->priv = nor;
|
||||
@@ -0,0 +1,122 @@
|
||||
From acfc6e9b34b3b3ca0d8bbe366dd08b0fac21c740 Mon Sep 17 00:00:00 2001
|
||||
From: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
Date: Tue, 2 Feb 2016 12:21:12 +0800
|
||||
Subject: [PATCH 101/113] mtd: spi-nor: fsl-quadspi: extend support for some
|
||||
special requerment.
|
||||
|
||||
Add extra info in LUT table to support some special requerments.
|
||||
Spansion S25FS-S family flash need some special operations.
|
||||
|
||||
Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 44 +++++++++++++++++++++++++++++++++++--
|
||||
include/linux/mtd/spi-nor.h | 4 ++++
|
||||
2 files changed, 46 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -205,6 +205,9 @@
|
||||
#define SEQID_RDCR 9
|
||||
#define SEQID_EN4B 10
|
||||
#define SEQID_BRWR 11
|
||||
+#define SEQID_RDAR 12
|
||||
+#define SEQID_WRAR 13
|
||||
+
|
||||
|
||||
#define QUADSPI_MIN_IOMAP SZ_4M
|
||||
|
||||
@@ -470,6 +473,28 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
|
||||
+ /*
|
||||
+ * Read any device register.
|
||||
+ * Used for Spansion S25FS-S family flash only.
|
||||
+ */
|
||||
+ lut_base = SEQID_RDAR * 4;
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_SPANSION_RDAR) |
|
||||
+ LUT1(ADDR, PAD1, ADDR24BIT),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+ qspi_writel(q, LUT0(DUMMY, PAD1, 8) | LUT1(FSL_READ, PAD1, 1),
|
||||
+ base + QUADSPI_LUT(lut_base + 1));
|
||||
+
|
||||
+ /*
|
||||
+ * Write any device register.
|
||||
+ * Used for Spansion S25FS-S family flash only.
|
||||
+ */
|
||||
+ lut_base = SEQID_WRAR * 4;
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_SPANSION_WRAR) |
|
||||
+ LUT1(ADDR, PAD1, ADDR24BIT),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+ qspi_writel(q, LUT0(FSL_WRITE, PAD1, 1),
|
||||
+ base + QUADSPI_LUT(lut_base + 1));
|
||||
+
|
||||
fsl_qspi_lock_lut(q);
|
||||
}
|
||||
|
||||
@@ -477,9 +502,15 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
+ case SPINOR_OP_READ4_1_1_4:
|
||||
case SPINOR_OP_READ_1_1_4:
|
||||
case SPINOR_OP_READ_FAST:
|
||||
+ case SPINOR_OP_READ4_FAST:
|
||||
return SEQID_READ;
|
||||
+ case SPINOR_OP_SPANSION_RDAR:
|
||||
+ return SEQID_RDAR;
|
||||
+ case SPINOR_OP_SPANSION_WRAR:
|
||||
+ return SEQID_WRAR;
|
||||
case SPINOR_OP_WREN:
|
||||
return SEQID_WREN;
|
||||
case SPINOR_OP_WRDI:
|
||||
@@ -491,6 +522,7 @@ static int fsl_qspi_get_seqid(struct fsl
|
||||
case SPINOR_OP_CHIP_ERASE:
|
||||
return SEQID_CHIP_ERASE;
|
||||
case SPINOR_OP_PP:
|
||||
+ case SPINOR_OP_PP_4B:
|
||||
return SEQID_PP;
|
||||
case SPINOR_OP_RDID:
|
||||
return SEQID_RDID;
|
||||
@@ -830,8 +862,12 @@ static int fsl_qspi_read_reg(struct spi_
|
||||
{
|
||||
int ret;
|
||||
struct fsl_qspi *q = nor->priv;
|
||||
+ u32 to = 0;
|
||||
+
|
||||
+ if (opcode == SPINOR_OP_SPANSION_RDAR)
|
||||
+ memcpy(&to, nor->cmd_buf, 4);
|
||||
|
||||
- ret = fsl_qspi_runcmd(q, opcode, 0, len);
|
||||
+ ret = fsl_qspi_runcmd(q, opcode, to, len);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -843,9 +879,13 @@ static int fsl_qspi_write_reg(struct spi
|
||||
{
|
||||
struct fsl_qspi *q = nor->priv;
|
||||
int ret;
|
||||
+ u32 to = 0;
|
||||
+
|
||||
+ if (opcode == SPINOR_OP_SPANSION_WRAR)
|
||||
+ memcpy(&to, nor->cmd_buf, 4);
|
||||
|
||||
if (!buf) {
|
||||
- ret = fsl_qspi_runcmd(q, opcode, 0, 1);
|
||||
+ ret = fsl_qspi_runcmd(q, opcode, to, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
--- a/include/linux/mtd/spi-nor.h
|
||||
+++ b/include/linux/mtd/spi-nor.h
|
||||
@@ -74,6 +74,10 @@
|
||||
/* Used for Spansion flashes only. */
|
||||
#define SPINOR_OP_BRWR 0x17 /* Bank register write */
|
||||
|
||||
+/* Used for Spansion S25FS-S family flash only. */
|
||||
+#define SPINOR_OP_SPANSION_RDAR 0x65 /* Read any device register */
|
||||
+#define SPINOR_OP_SPANSION_WRAR 0x71 /* Write any device register */
|
||||
+
|
||||
/* Used for Micron flashes only. */
|
||||
#define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */
|
||||
#define SPINOR_OP_WD_EVCR 0x61 /* Write EVCR register */
|
||||
@@ -0,0 +1,83 @@
|
||||
From d2d88e3432d68b11b0add84bd15a3aadaf44f1c1 Mon Sep 17 00:00:00 2001
|
||||
From: Yunhui Cui <B56489@freescale.com>
|
||||
Date: Mon, 28 Dec 2015 18:25:56 +0800
|
||||
Subject: [PATCH 102/113] mtd: spi-nor: fsl-quadspi:Support qspi for ls2080a
|
||||
|
||||
There is a hardware feature that qspi_amba_base is added
|
||||
internally by SOC design on ls2080a. So as to software, the driver
|
||||
need support to the feature.
|
||||
|
||||
Signed-off-by: Yunhui Cui <B56489@freescale.com>
|
||||
Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 24 ++++++++++++++++++++++--
|
||||
1 file changed, 22 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -41,6 +41,8 @@
|
||||
#define QUADSPI_QUIRK_TKT253890 (1 << 2)
|
||||
/* Controller cannot wake up from wait mode, TKT245618 */
|
||||
#define QUADSPI_QUIRK_TKT245618 (1 << 3)
|
||||
+/* QSPI_AMBA_BASE is internally added by SOC design */
|
||||
+#define QUADSPI_AMBA_BASE_INTERNAL (0x10000)
|
||||
|
||||
/* The registers */
|
||||
#define QUADSPI_MCR 0x00
|
||||
@@ -217,6 +219,7 @@ enum fsl_qspi_devtype {
|
||||
FSL_QUADSPI_IMX7D,
|
||||
FSL_QUADSPI_IMX6UL,
|
||||
FSL_QUADSPI_LS1021A,
|
||||
+ FSL_QUADSPI_LS2080A,
|
||||
};
|
||||
|
||||
struct fsl_qspi_devtype_data {
|
||||
@@ -270,6 +273,14 @@ static struct fsl_qspi_devtype_data ls10
|
||||
.driver_data = 0,
|
||||
};
|
||||
|
||||
+static struct fsl_qspi_devtype_data ls2080a_data = {
|
||||
+ .devtype = FSL_QUADSPI_LS2080A,
|
||||
+ .rxfifo = 128,
|
||||
+ .txfifo = 64,
|
||||
+ .ahb_buf_size = 1024,
|
||||
+ .driver_data = QUADSPI_AMBA_BASE_INTERNAL,
|
||||
+};
|
||||
+
|
||||
#define FSL_QSPI_MAX_CHIP 4
|
||||
struct fsl_qspi {
|
||||
struct spi_nor nor[FSL_QSPI_MAX_CHIP];
|
||||
@@ -312,6 +323,11 @@ static inline int needs_wakeup_wait_mode
|
||||
return q->devtype_data->driver_data & QUADSPI_QUIRK_TKT245618;
|
||||
}
|
||||
|
||||
+static inline int has_added_amba_base_internal(struct fsl_qspi *q)
|
||||
+{
|
||||
+ return q->devtype_data->driver_data & QUADSPI_AMBA_BASE_INTERNAL;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* R/W functions for big- or little-endian registers:
|
||||
* The qSPI controller's endian is independent of the CPU core's endian.
|
||||
@@ -558,8 +574,11 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 c
|
||||
/* save the reg */
|
||||
reg = qspi_readl(q, base + QUADSPI_MCR);
|
||||
|
||||
- qspi_writel(q, q->memmap_phy + q->chip_base_addr + addr,
|
||||
- base + QUADSPI_SFAR);
|
||||
+ if (has_added_amba_base_internal(q))
|
||||
+ qspi_writel(q, q->chip_base_addr + addr, base + QUADSPI_SFAR);
|
||||
+ else
|
||||
+ qspi_writel(q, q->memmap_phy + q->chip_base_addr + addr,
|
||||
+ base + QUADSPI_SFAR);
|
||||
qspi_writel(q, QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
|
||||
base + QUADSPI_RBCT);
|
||||
qspi_writel(q, reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
|
||||
@@ -849,6 +868,7 @@ static const struct of_device_id fsl_qsp
|
||||
{ .compatible = "fsl,imx7d-qspi", .data = (void *)&imx7d_data, },
|
||||
{ .compatible = "fsl,imx6ul-qspi", .data = (void *)&imx6ul_data, },
|
||||
{ .compatible = "fsl,ls1021a-qspi", .data = (void *)&ls1021a_data, },
|
||||
+ { .compatible = "fsl,ls2080a-qspi", .data = (void *)&ls2080a_data, },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids);
|
||||
@@ -0,0 +1,110 @@
|
||||
From 0878404f549021e7fe0a49ae0454cf53fd452add Mon Sep 17 00:00:00 2001
|
||||
From: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
Date: Tue, 2 Feb 2016 12:00:27 +0800
|
||||
Subject: [PATCH 103/113] mtd: spi-nor: Support R/W for S25FS-S family flash
|
||||
|
||||
With the physical sectors combination, S25FS-S family flash
|
||||
requires some special operations for read/write functions.
|
||||
|
||||
Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/spi-nor.c | 60 +++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 60 insertions(+)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -40,6 +40,10 @@
|
||||
#define SPI_NOR_MAX_ID_LEN 6
|
||||
#define SPI_NOR_MAX_ADDR_WIDTH 4
|
||||
#define SPI_NOR_MICRON_WRITE_ENABLE 0x7f
|
||||
+/* Added for S25FS-S family flash */
|
||||
+#define SPINOR_CONFIG_REG3_OFFSET 0x800004
|
||||
+#define CR3V_4KB_ERASE_UNABLE 0x8
|
||||
+#define SPINOR_S25FS_FAMILY_ID 0x81
|
||||
|
||||
struct flash_info {
|
||||
char *name;
|
||||
@@ -73,6 +77,8 @@ struct flash_info {
|
||||
};
|
||||
|
||||
#define JEDEC_MFR(info) ((info)->id[0])
|
||||
+#define EXT_ID(info) ((info)->id[5])
|
||||
+
|
||||
|
||||
static const struct flash_info *spi_nor_match_id(const char *name);
|
||||
|
||||
@@ -784,6 +790,7 @@ static const struct flash_info spi_nor_i
|
||||
*/
|
||||
{ "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
{ "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
+ { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512, 0)},
|
||||
{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
|
||||
{ "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
{ "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
@@ -908,6 +915,53 @@ static const struct flash_info *spi_nor_
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * The S25FS-S family physical sectors may be configured as a
|
||||
+ * hybrid combination of eight 4-kB parameter sectors
|
||||
+ * at the top or bottom of the address space with all
|
||||
+ * but one of the remaining sectors being uniform size.
|
||||
+ * The Parameter Sector Erase commands (20h or 21h) must
|
||||
+ * be used to erase the 4-kB parameter sectors individually.
|
||||
+ * The Sector (uniform sector) Erase commands (D8h or DCh)
|
||||
+ * must be used to erase any of the remaining
|
||||
+ * sectors, including the portion of highest or lowest address
|
||||
+ * sector that is not overlaid by the parameter sectors.
|
||||
+ * The uniform sector erase command has no effect on parameter sectors.
|
||||
+ */
|
||||
+static int spansion_s25fs_disable_4kb_erase(struct spi_nor *nor)
|
||||
+{
|
||||
+ struct fsl_qspi *q;
|
||||
+ u32 cr3v_addr = SPINOR_CONFIG_REG3_OFFSET;
|
||||
+ u8 cr3v = 0x0;
|
||||
+ int ret = 0x0;
|
||||
+
|
||||
+ q = nor->priv;
|
||||
+
|
||||
+ nor->cmd_buf[2] = cr3v_addr >> 16;
|
||||
+ nor->cmd_buf[1] = cr3v_addr >> 8;
|
||||
+ nor->cmd_buf[0] = cr3v_addr >> 0;
|
||||
+
|
||||
+ ret = nor->read_reg(nor, SPINOR_OP_SPANSION_RDAR, &cr3v, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ if (cr3v & CR3V_4KB_ERASE_UNABLE)
|
||||
+ return 0;
|
||||
+ ret = nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ cr3v = CR3V_4KB_ERASE_UNABLE;
|
||||
+ nor->program_opcode = SPINOR_OP_SPANSION_WRAR;
|
||||
+ nor->write(nor, cr3v_addr, 1, &cr3v);
|
||||
+
|
||||
+ ret = nor->read_reg(nor, SPINOR_OP_SPANSION_RDAR, &cr3v, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ if (!(cr3v & CR3V_4KB_ERASE_UNABLE))
|
||||
+ return -EPERM;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
size_t *retlen, u_char *buf)
|
||||
{
|
||||
@@ -1246,6 +1300,12 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
write_sr(nor, ret);
|
||||
}
|
||||
|
||||
+ if (EXT_ID(info) == SPINOR_S25FS_FAMILY_ID) {
|
||||
+ ret = spansion_s25fs_disable_4kb_erase(nor);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
if (!mtd->name)
|
||||
mtd->name = dev_name(dev);
|
||||
mtd->priv = nor;
|
||||
@@ -0,0 +1,112 @@
|
||||
From 23cd071c47c064d56921975d196dc22177069dea Mon Sep 17 00:00:00 2001
|
||||
From: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
Date: Wed, 24 Feb 2016 15:14:01 +0800
|
||||
Subject: [PATCH 104/113] mtd: fsl-quadspi: Add quad mode for flash n25q128
|
||||
|
||||
Add some lut_tables to support quad mode for flash n25q128
|
||||
on the board ls1021a-twr and solve flash Spansion and Micron
|
||||
command conflict.
|
||||
In switch {}, The value of command SPINOR_OP_RD_EVCR and
|
||||
SPINOR_OP_SPANSION_RDAR is the same. They have to share
|
||||
the same seq_id: SEQID_RDAR_OR_RD_EVCR.
|
||||
|
||||
Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 47 ++++++++++++++++++++++++++++---------
|
||||
1 file changed, 36 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -207,9 +207,9 @@
|
||||
#define SEQID_RDCR 9
|
||||
#define SEQID_EN4B 10
|
||||
#define SEQID_BRWR 11
|
||||
-#define SEQID_RDAR 12
|
||||
+#define SEQID_RDAR_OR_RD_EVCR 12
|
||||
#define SEQID_WRAR 13
|
||||
-
|
||||
+#define SEQID_WD_EVCR 14
|
||||
|
||||
#define QUADSPI_MIN_IOMAP SZ_4M
|
||||
|
||||
@@ -393,6 +393,7 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
int rxfifo = q->devtype_data->rxfifo;
|
||||
u32 lut_base;
|
||||
int i;
|
||||
+ const struct fsl_qspi_devtype_data *devtype_data = q->devtype_data;
|
||||
|
||||
struct spi_nor *nor = &q->nor[0];
|
||||
u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
|
||||
@@ -489,16 +490,26 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
|
||||
+
|
||||
/*
|
||||
- * Read any device register.
|
||||
- * Used for Spansion S25FS-S family flash only.
|
||||
+ * Flash Micron and Spansion command confilict
|
||||
+ * use the same value 0x65. But it indicates different meaning.
|
||||
*/
|
||||
- lut_base = SEQID_RDAR * 4;
|
||||
- qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_SPANSION_RDAR) |
|
||||
- LUT1(ADDR, PAD1, ADDR24BIT),
|
||||
- base + QUADSPI_LUT(lut_base));
|
||||
- qspi_writel(q, LUT0(DUMMY, PAD1, 8) | LUT1(FSL_READ, PAD1, 1),
|
||||
- base + QUADSPI_LUT(lut_base + 1));
|
||||
+ lut_base = SEQID_RDAR_OR_RD_EVCR * 4;
|
||||
+ if (devtype_data->devtype == FSL_QUADSPI_LS2080A) {
|
||||
+ /*
|
||||
+ * Read any device register.
|
||||
+ * Used for Spansion S25FS-S family flash only.
|
||||
+ */
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_SPANSION_RDAR) |
|
||||
+ LUT1(ADDR, PAD1, ADDR24BIT),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+ qspi_writel(q, LUT0(DUMMY, PAD1, 8) | LUT1(FSL_READ, PAD1, 1),
|
||||
+ base + QUADSPI_LUT(lut_base + 1));
|
||||
+ } else {
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RD_EVCR),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+ }
|
||||
|
||||
/*
|
||||
* Write any device register.
|
||||
@@ -511,6 +522,11 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
qspi_writel(q, LUT0(FSL_WRITE, PAD1, 1),
|
||||
base + QUADSPI_LUT(lut_base + 1));
|
||||
|
||||
+ /* Write EVCR register */
|
||||
+ lut_base = SEQID_WD_EVCR * 4;
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WD_EVCR),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+
|
||||
fsl_qspi_lock_lut(q);
|
||||
}
|
||||
|
||||
@@ -523,8 +539,15 @@ static int fsl_qspi_get_seqid(struct fsl
|
||||
case SPINOR_OP_READ_FAST:
|
||||
case SPINOR_OP_READ4_FAST:
|
||||
return SEQID_READ;
|
||||
+ /*
|
||||
+ * Spansion & Micron use the same command value 0x65
|
||||
+ * Spansion: SPINOR_OP_SPANSION_RDAR, read any register.
|
||||
+ * Micron: SPINOR_OP_RD_EVCR,
|
||||
+ * read enhanced volatile configuration register.
|
||||
+ * case SPINOR_OP_RD_EVCR:
|
||||
+ */
|
||||
case SPINOR_OP_SPANSION_RDAR:
|
||||
- return SEQID_RDAR;
|
||||
+ return SEQID_RDAR_OR_RD_EVCR;
|
||||
case SPINOR_OP_SPANSION_WRAR:
|
||||
return SEQID_WRAR;
|
||||
case SPINOR_OP_WREN:
|
||||
@@ -550,6 +573,8 @@ static int fsl_qspi_get_seqid(struct fsl
|
||||
return SEQID_EN4B;
|
||||
case SPINOR_OP_BRWR:
|
||||
return SEQID_BRWR;
|
||||
+ case SPINOR_OP_WD_EVCR:
|
||||
+ return SEQID_WD_EVCR;
|
||||
default:
|
||||
if (cmd == q->nor[0].erase_opcode)
|
||||
return SEQID_SE;
|
||||
@@ -0,0 +1,181 @@
|
||||
From 924f021c0344554a4b61746e5c4dcfc91d618ce2 Mon Sep 17 00:00:00 2001
|
||||
From: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
Date: Thu, 18 Feb 2016 16:41:53 +0800
|
||||
Subject: [PATCH 105/113] mtd: spi-nor: add DDR quad read support
|
||||
|
||||
This patch adds the DDR quad read support by the following:
|
||||
|
||||
[1] add SPI_NOR_DDR_QUAD read mode.
|
||||
|
||||
[2] add DDR Quad read opcodes:
|
||||
SPINOR_OP_READ_1_4_4_D / SPINOR_OP_READ4_1_4_4_D
|
||||
|
||||
[3] add set_ddr_quad_mode() to initialize for the DDR quad read.
|
||||
Currently it only works for Spansion NOR.
|
||||
|
||||
[4] set dummy with 6 for Spansion family
|
||||
Test this patch for Spansion s25fl128s NOR flash.
|
||||
|
||||
Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/spi-nor.c | 53 ++++++++++++++++++++++++++++++++++++-----
|
||||
include/linux/mtd/spi-nor.h | 8 +++++--
|
||||
2 files changed, 53 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -73,7 +73,8 @@ struct flash_info {
|
||||
#define SECT_4K_PMC 0x10 /* SPINOR_OP_BE_4K_PMC works uniformly */
|
||||
#define SPI_NOR_DUAL_READ 0x20 /* Flash supports Dual Read */
|
||||
#define SPI_NOR_QUAD_READ 0x40 /* Flash supports Quad Read */
|
||||
-#define USE_FSR 0x80 /* use flag status register */
|
||||
+#define SPI_NOR_DDR_QUAD_READ 0x80 /* Flash supports DDR Quad Read */
|
||||
+#define USE_FSR 0x100 /* use flag status register */
|
||||
};
|
||||
|
||||
#define JEDEC_MFR(info) ((info)->id[0])
|
||||
@@ -144,13 +145,17 @@ static int read_cr(struct spi_nor *nor)
|
||||
* It can be used to support more commands with
|
||||
* different dummy cycle requirements.
|
||||
*/
|
||||
-static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
|
||||
+static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor,
|
||||
+ const struct flash_info *info)
|
||||
{
|
||||
switch (nor->flash_read) {
|
||||
case SPI_NOR_FAST:
|
||||
case SPI_NOR_DUAL:
|
||||
case SPI_NOR_QUAD:
|
||||
return 8;
|
||||
+ case SPI_NOR_DDR_QUAD:
|
||||
+ if (JEDEC_MFR(info) == SNOR_MFR_SPANSION)
|
||||
+ return 6;
|
||||
case SPI_NOR_NORMAL:
|
||||
return 0;
|
||||
}
|
||||
@@ -797,7 +802,8 @@ static const struct flash_info spi_nor_i
|
||||
{ "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
|
||||
{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) },
|
||||
{ "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) },
|
||||
- { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
|
||||
+ { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ
|
||||
+ | SPI_NOR_DDR_QUAD_READ) },
|
||||
{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
{ "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
{ "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) },
|
||||
@@ -1186,6 +1192,23 @@ static int spansion_quad_enable(struct s
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int set_ddr_quad_mode(struct spi_nor *nor, const struct flash_info *info)
|
||||
+{
|
||||
+ int status;
|
||||
+
|
||||
+ switch (JEDEC_MFR(info)) {
|
||||
+ case SNOR_MFR_SPANSION:
|
||||
+ status = spansion_quad_enable(nor);
|
||||
+ if (status) {
|
||||
+ dev_err(nor->dev, "Spansion DDR quad-read not enabled\n");
|
||||
+ return status;
|
||||
+ }
|
||||
+ return status;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info)
|
||||
{
|
||||
int status;
|
||||
@@ -1375,8 +1398,15 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
if (info->flags & SPI_NOR_NO_FR)
|
||||
nor->flash_read = SPI_NOR_NORMAL;
|
||||
|
||||
- /* Quad/Dual-read mode takes precedence over fast/normal */
|
||||
- if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) {
|
||||
+ /* DDR Quad/Quad/Dual-read mode takes precedence over fast/normal */
|
||||
+ if (mode == SPI_NOR_DDR_QUAD && info->flags & SPI_NOR_DDR_QUAD_READ) {
|
||||
+ ret = set_ddr_quad_mode(nor, info);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "DDR quad mode not supported\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ nor->flash_read = SPI_NOR_DDR_QUAD;
|
||||
+ } else if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) {
|
||||
ret = set_quad_mode(nor, info);
|
||||
if (ret) {
|
||||
dev_err(dev, "quad mode not supported\n");
|
||||
@@ -1389,6 +1419,14 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
|
||||
/* Default commands */
|
||||
switch (nor->flash_read) {
|
||||
+ case SPI_NOR_DDR_QUAD:
|
||||
+ if (JEDEC_MFR(info) == SNOR_MFR_SPANSION) { /* Spansion */
|
||||
+ nor->read_opcode = SPINOR_OP_READ_1_4_4_D;
|
||||
+ } else {
|
||||
+ dev_err(dev, "DDR Quad Read is not supported.\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ break;
|
||||
case SPI_NOR_QUAD:
|
||||
nor->read_opcode = SPINOR_OP_READ_1_1_4;
|
||||
break;
|
||||
@@ -1416,6 +1454,9 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
if (JEDEC_MFR(info) == SNOR_MFR_SPANSION) {
|
||||
/* Dedicated 4-byte command set */
|
||||
switch (nor->flash_read) {
|
||||
+ case SPI_NOR_DDR_QUAD:
|
||||
+ nor->read_opcode = SPINOR_OP_READ4_1_4_4_D;
|
||||
+ break;
|
||||
case SPI_NOR_QUAD:
|
||||
nor->read_opcode = SPINOR_OP_READ4_1_1_4;
|
||||
break;
|
||||
@@ -1445,7 +1486,7 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- nor->read_dummy = spi_nor_read_dummy_cycles(nor);
|
||||
+ nor->read_dummy = spi_nor_read_dummy_cycles(nor, info);
|
||||
|
||||
dev_info(dev, "%s (%lld Kbytes)\n", info->name,
|
||||
(long long)mtd->size >> 10);
|
||||
--- a/include/linux/mtd/spi-nor.h
|
||||
+++ b/include/linux/mtd/spi-nor.h
|
||||
@@ -30,10 +30,11 @@
|
||||
|
||||
/*
|
||||
* Note on opcode nomenclature: some opcodes have a format like
|
||||
- * SPINOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number
|
||||
+ * SPINOR_OP_FUNCTION{4,}_x_y_z{_D}. 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.
|
||||
+ * requires a 4-byte (32-bit) address. The suffix of 'D' stands for the
|
||||
+ * DDR mode.
|
||||
*/
|
||||
|
||||
/* Flash opcodes. */
|
||||
@@ -44,6 +45,7 @@
|
||||
#define SPINOR_OP_READ_FAST 0x0b /* Read data bytes (high frequency) */
|
||||
#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual SPI) */
|
||||
#define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad SPI) */
|
||||
+#define SPINOR_OP_READ_1_4_4_D 0xed /* Read data bytes (DDR Quad SPI) */
|
||||
#define SPINOR_OP_PP 0x02 /* Page program (up to 256 bytes) */
|
||||
#define SPINOR_OP_BE_4K 0x20 /* Erase 4KiB block */
|
||||
#define SPINOR_OP_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */
|
||||
@@ -59,6 +61,7 @@
|
||||
#define SPINOR_OP_READ4_FAST 0x0c /* Read data bytes (high frequency) */
|
||||
#define SPINOR_OP_READ4_1_1_2 0x3c /* Read data bytes (Dual SPI) */
|
||||
#define SPINOR_OP_READ4_1_1_4 0x6c /* Read data bytes (Quad SPI) */
|
||||
+#define SPINOR_OP_READ4_1_4_4_D 0xee /* Read data bytes (DDR Quad SPI) */
|
||||
#define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */
|
||||
#define SPINOR_OP_SE_4B 0xdc /* Sector erase (usually 64KiB) */
|
||||
|
||||
@@ -107,6 +110,7 @@ enum read_mode {
|
||||
SPI_NOR_FAST,
|
||||
SPI_NOR_DUAL,
|
||||
SPI_NOR_QUAD,
|
||||
+ SPI_NOR_DDR_QUAD,
|
||||
};
|
||||
|
||||
#define SPI_NOR_MAX_CMD_SIZE 8
|
||||
@@ -0,0 +1,122 @@
|
||||
From 16eb35ceea5b43e6f64c1a869721ea86c0da5260 Mon Sep 17 00:00:00 2001
|
||||
From: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
Date: Thu, 25 Feb 2016 10:19:15 +0800
|
||||
Subject: [PATCH 106/113] mtd: fsl-quadspi: add DDR quad read for Spansion
|
||||
|
||||
Add the DDR quad read support for the fsl-quadspi driver.
|
||||
And, add the Spansion s25fl128s NOR flash ddr quad mode
|
||||
support.
|
||||
|
||||
Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 57 +++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 57 insertions(+)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -296,6 +296,7 @@ struct fsl_qspi {
|
||||
u32 nor_size;
|
||||
u32 nor_num;
|
||||
u32 clk_rate;
|
||||
+ u32 ddr_smp;
|
||||
unsigned int chip_base_addr; /* We may support two chips. */
|
||||
bool has_second_chip;
|
||||
bool big_endian;
|
||||
@@ -423,6 +424,19 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
|
||||
LUT1(FSL_READ, PAD4, rxfifo),
|
||||
base + QUADSPI_LUT(lut_base + 1));
|
||||
+ } else if (nor->flash_read == SPI_NOR_DDR_QUAD) {
|
||||
+ /* read mode : 1-4-4, such as Spansion s25fl128s. */
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, read_op)
|
||||
+ | LUT1(ADDR_DDR, PAD4, addrlen),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+
|
||||
+ qspi_writel(q, LUT0(MODE_DDR, PAD4, 0xff)
|
||||
+ | LUT1(DUMMY, PAD1, read_dm),
|
||||
+ base + QUADSPI_LUT(lut_base + 1));
|
||||
+
|
||||
+ qspi_writel(q, LUT0(FSL_READ_DDR, PAD4, rxfifo)
|
||||
+ | LUT1(JMP_ON_CS, PAD1, 0),
|
||||
+ base + QUADSPI_LUT(lut_base + 2));
|
||||
}
|
||||
|
||||
/* Write enable */
|
||||
@@ -534,6 +548,8 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
+ case SPINOR_OP_READ_1_4_4_D:
|
||||
+ case SPINOR_OP_READ4_1_4_4_D:
|
||||
case SPINOR_OP_READ4_1_1_4:
|
||||
case SPINOR_OP_READ_1_1_4:
|
||||
case SPINOR_OP_READ_FAST:
|
||||
@@ -736,6 +752,32 @@ static void fsl_qspi_set_map_addr(struct
|
||||
}
|
||||
|
||||
/*
|
||||
+ * enable controller ddr quad mode to support different
|
||||
+ * vender flashes ddr quad mode.
|
||||
+ */
|
||||
+static void set_ddr_quad_mode(struct fsl_qspi *q)
|
||||
+{
|
||||
+ u32 reg, reg2;
|
||||
+
|
||||
+ reg = qspi_readl(q, q->iobase + QUADSPI_MCR);
|
||||
+
|
||||
+ /* Firstly, disable the module */
|
||||
+ qspi_writel(q, reg | QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
|
||||
+
|
||||
+ /* Set the Sampling Register for DDR */
|
||||
+ reg2 = qspi_readl(q, q->iobase + QUADSPI_SMPR);
|
||||
+ reg2 &= ~QUADSPI_SMPR_DDRSMP_MASK;
|
||||
+ reg2 |= (((q->ddr_smp) << QUADSPI_SMPR_DDRSMP_SHIFT) &
|
||||
+ QUADSPI_SMPR_DDRSMP_MASK);
|
||||
+ qspi_writel(q, reg2, q->iobase + QUADSPI_SMPR);
|
||||
+
|
||||
+ /* Enable the module again (enable the DDR too) */
|
||||
+ reg |= QUADSPI_MCR_DDR_EN_MASK;
|
||||
+ qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
|
||||
+
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* There are two different ways to read out the data from the flash:
|
||||
* the "IP Command Read" and the "AHB Command Read".
|
||||
*
|
||||
@@ -775,6 +817,11 @@ static void fsl_qspi_init_abh_read(struc
|
||||
seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
|
||||
qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
|
||||
q->iobase + QUADSPI_BFGENCR);
|
||||
+
|
||||
+ /* enable the DDR quad read */
|
||||
+ if (q->nor->flash_read == SPI_NOR_DDR_QUAD)
|
||||
+ set_ddr_quad_mode(q);
|
||||
+
|
||||
}
|
||||
|
||||
/* This function was used to prepare and enable QSPI clock */
|
||||
@@ -1108,6 +1155,12 @@ static int fsl_qspi_probe(struct platfor
|
||||
goto clk_failed;
|
||||
}
|
||||
|
||||
+ /* find ddrsmp value */
|
||||
+ ret = of_property_read_u32(dev->of_node, "fsl,ddr-sampling-point",
|
||||
+ &q->ddr_smp);
|
||||
+ if (ret)
|
||||
+ q->ddr_smp = 0;
|
||||
+
|
||||
/* find the irq */
|
||||
ret = platform_get_irq(pdev, 0);
|
||||
if (ret < 0) {
|
||||
@@ -1164,6 +1217,10 @@ static int fsl_qspi_probe(struct platfor
|
||||
|
||||
ret = of_property_read_bool(np, "m25p,fast-read");
|
||||
mode = (ret) ? SPI_NOR_FAST : SPI_NOR_QUAD;
|
||||
+ /* Can we enable the DDR Quad Read? */
|
||||
+ ret = of_property_read_bool(np, "ddr-quad-read");
|
||||
+ if (ret)
|
||||
+ mode = SPI_NOR_DDR_QUAD;
|
||||
|
||||
ret = spi_nor_scan(nor, NULL, mode);
|
||||
if (ret)
|
||||
@@ -0,0 +1,67 @@
|
||||
From 50aac689d5be0a086f076cd4bc8b14ee0b9ab995 Mon Sep 17 00:00:00 2001
|
||||
From: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
Date: Tue, 8 Mar 2016 14:38:52 +0800
|
||||
Subject: [PATCH 107/113] mtd: fsl-quadspi: disable AHB buffer prefetch
|
||||
|
||||
A-009282: QuadSPI: QuadSPI data pre-fetch can result in incorrect data
|
||||
Affects: QuadSPI
|
||||
Description: With AHB buffer prefetch enabled, the QuadSPI may return
|
||||
incorrect data on the AHB
|
||||
interface. The buffer pre-fetch is enabled if the fetch size as
|
||||
configured either in the LUT or in
|
||||
the BUFxCR register is greater than 8 bytes.
|
||||
Impact: Only 64 bit read allowed.
|
||||
Workaround: Keep the read data size to 64 bits (8 Bytes), which disables
|
||||
the prefetch on the AHB buffer,
|
||||
and prevents this issue from occurring.
|
||||
|
||||
Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 29 +++++++++++++++++++++++------
|
||||
1 file changed, 23 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -794,19 +794,36 @@ static void fsl_qspi_init_abh_read(struc
|
||||
{
|
||||
void __iomem *base = q->iobase;
|
||||
int seqid;
|
||||
+ const struct fsl_qspi_devtype_data *devtype_data = q->devtype_data;
|
||||
|
||||
/* AHB configuration for access buffer 0/1/2 .*/
|
||||
qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR);
|
||||
qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR);
|
||||
qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR);
|
||||
+
|
||||
/*
|
||||
- * Set ADATSZ with the maximum AHB buffer size to improve the
|
||||
- * read performance.
|
||||
+ * Errata: A-009282: QuadSPI data prefetch may result in incorrect data
|
||||
+ * Workaround: Keep the read data size to 64 bits (8 bytes).
|
||||
+ * This disables the prefetch on the AHB buffer and
|
||||
+ * prevents this issue from occurring.
|
||||
*/
|
||||
- qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
|
||||
- ((q->devtype_data->ahb_buf_size / 8)
|
||||
- << QUADSPI_BUF3CR_ADATSZ_SHIFT),
|
||||
- base + QUADSPI_BUF3CR);
|
||||
+ if (devtype_data->devtype == FSL_QUADSPI_LS2080A ||
|
||||
+ devtype_data->devtype == FSL_QUADSPI_LS1021A) {
|
||||
+
|
||||
+ qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
|
||||
+ (1 << QUADSPI_BUF3CR_ADATSZ_SHIFT),
|
||||
+ base + QUADSPI_BUF3CR);
|
||||
+
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Set ADATSZ with the maximum AHB buffer size to improve the
|
||||
+ * read performance.
|
||||
+ */
|
||||
+ qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
|
||||
+ ((q->devtype_data->ahb_buf_size / 8)
|
||||
+ << QUADSPI_BUF3CR_ADATSZ_SHIFT),
|
||||
+ base + QUADSPI_BUF3CR);
|
||||
+ }
|
||||
|
||||
/* We only use the buffer3 */
|
||||
qspi_writel(q, 0, base + QUADSPI_BUF0IND);
|
||||
@@ -0,0 +1,42 @@
|
||||
From d3a8ee41170ff9e5298ff354c77ff99439dfe2bf Mon Sep 17 00:00:00 2001
|
||||
From: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
Date: Thu, 10 Mar 2016 11:33:40 +0800
|
||||
Subject: [PATCH 108/113] mtd: fsl-quadspi: add multi flash chip R/W on
|
||||
ls2080a
|
||||
|
||||
There is a hardware feature that qspi_amba_base is added
|
||||
internally by SOC design on ls2080a. so memmap_phy need not
|
||||
be added in driver. If memmap_phy is added, the flash A1
|
||||
addr space is [0, memmap_phy] which far more than flash size.
|
||||
The AMBA memory will be divided into four parts and assign to
|
||||
every chipselect. Every channel will has two valid chipselects.
|
||||
|
||||
Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 14 ++++++++++----
|
||||
1 file changed, 10 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -744,11 +744,17 @@ static void fsl_qspi_set_map_addr(struct
|
||||
{
|
||||
int nor_size = q->nor_size;
|
||||
void __iomem *base = q->iobase;
|
||||
+ u32 mem_base;
|
||||
|
||||
- qspi_writel(q, nor_size + q->memmap_phy, base + QUADSPI_SFA1AD);
|
||||
- qspi_writel(q, nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD);
|
||||
- qspi_writel(q, nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD);
|
||||
- qspi_writel(q, nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD);
|
||||
+ if (has_added_amba_base_internal(q))
|
||||
+ mem_base = 0x0;
|
||||
+ else
|
||||
+ mem_base = q->memmap_phy;
|
||||
+
|
||||
+ qspi_writel(q, nor_size + mem_base, base + QUADSPI_SFA1AD);
|
||||
+ qspi_writel(q, nor_size * 2 + mem_base, base + QUADSPI_SFA2AD);
|
||||
+ qspi_writel(q, nor_size * 3 + mem_base, base + QUADSPI_SFB1AD);
|
||||
+ qspi_writel(q, nor_size * 4 + mem_base, base + QUADSPI_SFB2AD);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -0,0 +1,36 @@
|
||||
From 70516f60de441829e7813c0b26567c8bda39c011 Mon Sep 17 00:00:00 2001
|
||||
From: Pratiyush Mohan Srivastava <pratiyush.srivastava@nxp.com>
|
||||
Date: Sun, 24 Apr 2016 23:20:26 +0530
|
||||
Subject: [PATCH 109/113] drivers: mtd: spi-nor: Enable QSPI Flash in Kernel
|
||||
|
||||
Enable read from QSPI flash, Write onto QSPI Flash and
|
||||
erase QSPI Flash in Fast mode in Kernel.
|
||||
|
||||
Signed-off-by: Pratiyush Mohan Srivastava <pratiyush.srivastava@nxp.com>
|
||||
Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/spi-nor.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -796,6 +796,7 @@ static const struct flash_info spi_nor_i
|
||||
{ "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
{ "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
{ "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512, 0)},
|
||||
+ { "s25fs512s", INFO6(0x010220, 0x4d0081, 128 * 1024, 512, 0)},
|
||||
{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
|
||||
{ "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
{ "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
@@ -962,9 +963,11 @@ static int spansion_s25fs_disable_4kb_er
|
||||
ret = nor->read_reg(nor, SPINOR_OP_SPANSION_RDAR, &cr3v, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
+/*
|
||||
if (!(cr3v & CR3V_4KB_ERASE_UNABLE))
|
||||
return -EPERM;
|
||||
|
||||
+*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
From 034dd6241b55ab2256eecb845e941fa9b45da38e Mon Sep 17 00:00:00 2001
|
||||
From: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
Date: Thu, 28 Apr 2016 17:03:57 +0800
|
||||
Subject: [PATCH 110/113] mtd: spi-nor: fsl-quad: add flash S25FS extra
|
||||
support
|
||||
|
||||
[context adjustment]
|
||||
not apply changes of arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts
|
||||
|
||||
There are some boards have the same QSPI controller but have
|
||||
different vendor flash, So, the controller can use the same
|
||||
compatible and share the driver, just for a different flash to do
|
||||
the appropriate adaptation. Based on this, we need add the vendor
|
||||
field in spi-nor, Because we will use the field to distribute
|
||||
corresponding LUT for different flash operations.
|
||||
|
||||
Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
Signed-off-by: Pratiyush Mohan Srivastava <pratiyush.srivastava@nxp.com>
|
||||
Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
|
||||
Integrated-by: Jiang Yutang <yutang.jiang@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 47 ++++++++++++++++++++++++++++++-------
|
||||
drivers/mtd/spi-nor/spi-nor.c | 5 ++--
|
||||
include/linux/mtd/spi-nor.h | 1 +
|
||||
3 files changed, 42 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -213,6 +213,9 @@
|
||||
|
||||
#define QUADSPI_MIN_IOMAP SZ_4M
|
||||
|
||||
+#define FLASH_VENDOR_SPANSION_FS "s25fs"
|
||||
+#define SPANSION_S25FS_FAMILY (1 << 1)
|
||||
+
|
||||
enum fsl_qspi_devtype {
|
||||
FSL_QUADSPI_VYBRID,
|
||||
FSL_QUADSPI_IMX6SX,
|
||||
@@ -329,6 +332,18 @@ static inline int has_added_amba_base_in
|
||||
return q->devtype_data->driver_data & QUADSPI_AMBA_BASE_INTERNAL;
|
||||
}
|
||||
|
||||
+static u32 fsl_get_nor_vendor(struct spi_nor *nor)
|
||||
+{
|
||||
+ u32 vendor_id;
|
||||
+
|
||||
+ if (nor->vendor) {
|
||||
+ if (memcmp(nor->vendor, FLASH_VENDOR_SPANSION_FS,
|
||||
+ sizeof(FLASH_VENDOR_SPANSION_FS) - 1))
|
||||
+ vendor_id = SPANSION_S25FS_FAMILY;
|
||||
+ }
|
||||
+ return vendor_id;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* R/W functions for big- or little-endian registers:
|
||||
* The qSPI controller's endian is independent of the CPU core's endian.
|
||||
@@ -394,13 +409,15 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
int rxfifo = q->devtype_data->rxfifo;
|
||||
u32 lut_base;
|
||||
int i;
|
||||
- const struct fsl_qspi_devtype_data *devtype_data = q->devtype_data;
|
||||
+ u32 vendor;
|
||||
|
||||
struct spi_nor *nor = &q->nor[0];
|
||||
u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
|
||||
u8 read_op = nor->read_opcode;
|
||||
u8 read_dm = nor->read_dummy;
|
||||
|
||||
+ vendor = fsl_get_nor_vendor(nor);
|
||||
+
|
||||
fsl_qspi_unlock_lut(q);
|
||||
|
||||
/* Clear all the LUT table */
|
||||
@@ -418,12 +435,25 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
LUT1(FSL_READ, PAD1, rxfifo),
|
||||
base + QUADSPI_LUT(lut_base + 1));
|
||||
} else if (nor->flash_read == SPI_NOR_QUAD) {
|
||||
- qspi_writel(q, LUT0(CMD, PAD1, read_op) |
|
||||
- LUT1(ADDR, PAD1, addrlen),
|
||||
- base + QUADSPI_LUT(lut_base));
|
||||
- qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
|
||||
- LUT1(FSL_READ, PAD4, rxfifo),
|
||||
- base + QUADSPI_LUT(lut_base + 1));
|
||||
+ if (q->nor_size == 0x4000000) {
|
||||
+ read_op = 0xEC;
|
||||
+ qspi_writel(q,
|
||||
+ LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD4, addrlen),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+ qspi_writel(q,
|
||||
+ LUT0(MODE, PAD4, 0xff) | LUT1(DUMMY, PAD4, read_dm),
|
||||
+ base + QUADSPI_LUT(lut_base + 1));
|
||||
+ qspi_writel(q,
|
||||
+ LUT0(FSL_READ, PAD4, rxfifo),
|
||||
+ base + QUADSPI_LUT(lut_base + 2));
|
||||
+ } else {
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, read_op) |
|
||||
+ LUT1(ADDR, PAD1, addrlen),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+ qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
|
||||
+ LUT1(FSL_READ, PAD4, rxfifo),
|
||||
+ base + QUADSPI_LUT(lut_base + 1));
|
||||
+ }
|
||||
} else if (nor->flash_read == SPI_NOR_DDR_QUAD) {
|
||||
/* read mode : 1-4-4, such as Spansion s25fl128s. */
|
||||
qspi_writel(q, LUT0(CMD, PAD1, read_op)
|
||||
@@ -510,7 +540,8 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
* use the same value 0x65. But it indicates different meaning.
|
||||
*/
|
||||
lut_base = SEQID_RDAR_OR_RD_EVCR * 4;
|
||||
- if (devtype_data->devtype == FSL_QUADSPI_LS2080A) {
|
||||
+
|
||||
+ if (vendor == SPANSION_S25FS_FAMILY) {
|
||||
/*
|
||||
* Read any device register.
|
||||
* Used for Spansion S25FS-S family flash only.
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -796,7 +796,6 @@ static const struct flash_info spi_nor_i
|
||||
{ "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
{ "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
{ "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512, 0)},
|
||||
- { "s25fs512s", INFO6(0x010220, 0x4d0081, 128 * 1024, 512, 0)},
|
||||
{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
|
||||
{ "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
{ "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
@@ -963,11 +962,9 @@ static int spansion_s25fs_disable_4kb_er
|
||||
ret = nor->read_reg(nor, SPINOR_OP_SPANSION_RDAR, &cr3v, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
-/*
|
||||
if (!(cr3v & CR3V_4KB_ERASE_UNABLE))
|
||||
return -EPERM;
|
||||
|
||||
-*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1334,6 +1331,8 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
|
||||
if (!mtd->name)
|
||||
mtd->name = dev_name(dev);
|
||||
+ if (info->name)
|
||||
+ nor->vendor = info->name;
|
||||
mtd->priv = nor;
|
||||
mtd->type = MTD_NORFLASH;
|
||||
mtd->writesize = 1;
|
||||
--- a/include/linux/mtd/spi-nor.h
|
||||
+++ b/include/linux/mtd/spi-nor.h
|
||||
@@ -172,6 +172,7 @@ struct spi_nor {
|
||||
bool sst_write_second;
|
||||
u32 flags;
|
||||
u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE];
|
||||
+ char *vendor;
|
||||
|
||||
int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);
|
||||
void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);
|
||||
@@ -0,0 +1,27 @@
|
||||
From 30d34abc80b0a602a1327bdfbddd42d250887049 Mon Sep 17 00:00:00 2001
|
||||
From: Yutang Jiang <yutang.jiang@nxp.com>
|
||||
Date: Fri, 9 Sep 2016 22:56:12 +0800
|
||||
Subject: [PATCH 111/113] mtd: spi-nor: disable 4kb sector erase for s25fl128
|
||||
|
||||
As for s25fl128s flash, the sectors are organized either as a hybrid
|
||||
combination of 4-kB and 64-kB sectors, or as uniform 256-kbyte sectors.
|
||||
we should use the command 0xd8 to erase all bits, not the Parameter 4-kB
|
||||
Sector Erase (P4E) command 0x20.
|
||||
|
||||
Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
Integrated-by: Yutang Jiang <yutang.jiang@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/spi-nor.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -802,7 +802,7 @@ static const struct flash_info spi_nor_i
|
||||
{ "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
|
||||
{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) },
|
||||
{ "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) },
|
||||
- { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ
|
||||
+ { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_QUAD_READ
|
||||
| SPI_NOR_DDR_QUAD_READ) },
|
||||
{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
{ "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
@@ -0,0 +1,29 @@
|
||||
From f1b7824a42505669476f203e126fc26dd1006af2 Mon Sep 17 00:00:00 2001
|
||||
From: Yutang Jiang <yutang.jiang@nxp.com>
|
||||
Date: Fri, 9 Sep 2016 22:57:55 +0800
|
||||
Subject: [PATCH 112/113] driver: spi: fsl-quad: Hang memcpy: Unhandled fault:
|
||||
alignment fault
|
||||
|
||||
vmap/iomap based on whether the buffer is in memory region or reserved region.
|
||||
However, both map it as non-cacheable memory.
|
||||
For armv8 specifically, non-cacheable mapping requests use a memory type
|
||||
that has to be accessed aligned to the request size. memcpy() doesn't guarantee
|
||||
that. memcpy_toio() can guarantee 4-bytes alignment.
|
||||
|
||||
Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
Integrated-by: Yutang Jiang <yutang.jiang@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -1103,7 +1103,7 @@ static ssize_t fsl_qspi_read(struct spi_
|
||||
len);
|
||||
|
||||
/* Read out the data directly from the AHB buffer.*/
|
||||
- memcpy(buf, q->ahb_addr + q->chip_base_addr + from - q->memmap_offs,
|
||||
+ memcpy_toio(buf, q->ahb_addr + q->chip_base_addr + from - q->memmap_offs,
|
||||
len);
|
||||
|
||||
return len;
|
||||
@@ -0,0 +1,49 @@
|
||||
From 6f1195d231ab576809fe2f4cff44a6e48cff2457 Mon Sep 17 00:00:00 2001
|
||||
From: Yutang Jiang <yutang.jiang@nxp.com>
|
||||
Date: Fri, 2 Sep 2016 22:00:16 +0800
|
||||
Subject: [PATCH 113/113] mtd: spi-nor: fsl-quad: move mtd_device_register to
|
||||
the last of probe
|
||||
|
||||
After call mtd_device_register, the mtd devices should be workable immediately.
|
||||
If before finish all of init work call the mtd_device_register, it will not
|
||||
respond work request timely.
|
||||
|
||||
For example, openwrt/lede have a AUTO split special flash partitions mechanism
|
||||
while mtd driver register. So, before call mtd_device_register, must let all of
|
||||
init work ready.
|
||||
|
||||
Signed-off-by: Yutang Jiang <yutang.jiang@nxp.com>
|
||||
---
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 14 ++++++++++----
|
||||
1 file changed, 10 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -1280,10 +1280,6 @@ static int fsl_qspi_probe(struct platfor
|
||||
if (ret)
|
||||
goto mutex_failed;
|
||||
|
||||
- ret = mtd_device_register(mtd, NULL, 0);
|
||||
- if (ret)
|
||||
- goto mutex_failed;
|
||||
-
|
||||
/* Set the correct NOR size now. */
|
||||
if (q->nor_size == 0) {
|
||||
q->nor_size = mtd->size;
|
||||
@@ -1313,6 +1309,16 @@ static int fsl_qspi_probe(struct platfor
|
||||
goto last_init_failed;
|
||||
|
||||
fsl_qspi_clk_disable_unprep(q);
|
||||
+
|
||||
+ for (i = 0; i < q->nor_num; i++) {
|
||||
+ /* skip the holes */
|
||||
+ if (!q->has_second_chip)
|
||||
+ i *= 2;
|
||||
+
|
||||
+ ret = mtd_device_register(&q->nor[i].mtd, NULL, 0);
|
||||
+ if (ret)
|
||||
+ goto last_init_failed;
|
||||
+ }
|
||||
return 0;
|
||||
|
||||
last_init_failed:
|
||||
@@ -0,0 +1,31 @@
|
||||
From 035fe1e511e053c6650f37626deb5da76dcc1d92 Mon Sep 17 00:00:00 2001
|
||||
From: Ying Zhang <ying.zhang22455@nxp.com>
|
||||
Date: Thu, 29 Sep 2016 11:29:48 +0800
|
||||
Subject: [PATCH 119/124] armv8: aarch32: defconfig: Enable CAAM support
|
||||
|
||||
This patch is to enable the driver module for Freescale's Cryptographics
|
||||
Accelerator and Assurance Module (CAAM) and related options.
|
||||
|
||||
Signed-off-by: Alison Wang <alison.wang@nxp.com>
|
||||
---
|
||||
arch/arm/configs/ls_aarch32_defconfig | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/arch/arm/configs/ls_aarch32_defconfig
|
||||
+++ b/arch/arm/configs/ls_aarch32_defconfig
|
||||
@@ -200,8 +200,13 @@ CONFIG_MAGIC_SYSRQ=y
|
||||
# CONFIG_FTRACE is not set
|
||||
CONFIG_PID_IN_CONTEXTIDR=y
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
|
||||
-# CONFIG_CRYPTO_HW is not set
|
||||
+CONFIG_CRYPTO_ANSI_CPRNG=y
|
||||
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
|
||||
+CONFIG_ARM_CRYPTO=y
|
||||
+CONFIG_CRYPTO_SHA1_ARM_NEON=y
|
||||
+CONFIG_CRYPTO_SHA256_ARM=y
|
||||
+CONFIG_CRYPTO_SHA512_ARM_NEON=y
|
||||
+CONFIG_CRYPTO_AES_ARM_BS=y
|
||||
CONFIG_CRC_CCITT=m
|
||||
CONFIG_CRC_T10DIF=y
|
||||
CONFIG_CRC7=m
|
||||
@@ -0,0 +1,23 @@
|
||||
From 027ca2530ce94dd7d9954e57631aa34987db392e Mon Sep 17 00:00:00 2001
|
||||
From: Ying Zhang <ying.zhang22455@nxp.com>
|
||||
Date: Thu, 29 Sep 2016 11:38:36 +0800
|
||||
Subject: [PATCH 120/124] armv8: aarch32: defconfig: Enable firmware loading
|
||||
|
||||
As some modules require userspace firmware loading support, such as
|
||||
PPFE, add this feature in the defconfig for AArch32 on ARMv8.
|
||||
|
||||
Signed-off-by: Alison Wang <alison.wang@nxp.com>
|
||||
---
|
||||
arch/arm/configs/ls_aarch32_defconfig | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
--- a/arch/arm/configs/ls_aarch32_defconfig
|
||||
+++ b/arch/arm/configs/ls_aarch32_defconfig
|
||||
@@ -71,7 +71,6 @@ CONFIG_CAN=y
|
||||
CONFIG_CAN_FLEXCAN=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
-# CONFIG_FW_LOADER is not set
|
||||
CONFIG_DMA_CMA=y
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_CMDLINE_PARTS=y
|
||||
@@ -0,0 +1,29 @@
|
||||
From ff37b165bdb100450c7996c9fac0fad2e6ffe31d Mon Sep 17 00:00:00 2001
|
||||
From: Ying Zhang <ying.zhang22455@nxp.com>
|
||||
Date: Thu, 29 Sep 2016 11:40:37 +0800
|
||||
Subject: [PATCH 121/124] armv8: aarch32: defconfig: Enable support for AHCI
|
||||
SATA
|
||||
|
||||
This patch is to enable support for the Freescale QorIQ AHCI SoC's
|
||||
onboard AHCI SATA.
|
||||
|
||||
Signed-off-by: Alison Wang <alison.wang@nxp.com>
|
||||
---
|
||||
arch/arm/configs/ls_aarch32_defconfig | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
--- a/arch/arm/configs/ls_aarch32_defconfig
|
||||
+++ b/arch/arm/configs/ls_aarch32_defconfig
|
||||
@@ -92,7 +92,12 @@ CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
|
||||
CONFIG_SPI_FSL_QUADSPI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
+CONFIG_CHR_DEV_SG=y
|
||||
CONFIG_ATA=y
|
||||
+CONFIG_SATA_AHCI=y
|
||||
+CONFIG_SATA_AHCI_PLATFORM=y
|
||||
+CONFIG_AHCI_QORIQ=y
|
||||
+CONFIG_SATA_SIL24=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_COUNT=8
|
||||
@@ -0,0 +1,31 @@
|
||||
From 913db32774fe5c818112232823edfda1a706552f Mon Sep 17 00:00:00 2001
|
||||
From: Ying Zhang <ying.zhang22455@nxp.com>
|
||||
Date: Thu, 29 Sep 2016 11:42:40 +0800
|
||||
Subject: [PATCH 122/124] armv8: aarch32: defconfig: Enable USB and related
|
||||
configuration options
|
||||
|
||||
This patch is to enable USB and related configuration options for
|
||||
AArch32 on ARMv8.
|
||||
|
||||
Signed-off-by: Alison Wang <alison.wang@nxp.com>
|
||||
---
|
||||
arch/arm/configs/ls_aarch32_defconfig | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
--- a/arch/arm/configs/ls_aarch32_defconfig
|
||||
+++ b/arch/arm/configs/ls_aarch32_defconfig
|
||||
@@ -154,8 +154,14 @@ CONFIG_MFD_SYSCON=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
+CONFIG_USB_EHCI_HCD=y
|
||||
+CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||
+CONFIG_USB_OHCI_HCD=y
|
||||
+CONFIG_USB_OHCI_HCD_PLATFORM=y
|
||||
+CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_DWC3=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
+CONFIG_USB_ULPI=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
@@ -0,0 +1,59 @@
|
||||
From dbf356cd062d6313f90323a77d4cf7c820dae40f Mon Sep 17 00:00:00 2001
|
||||
From: Ying Zhang <ying.zhang22455@nxp.com>
|
||||
Date: Thu, 29 Sep 2016 13:51:32 +0800
|
||||
Subject: [PATCH 123/124] armv8: aarch32: defconfig: Enable KVM-related
|
||||
configuration options
|
||||
|
||||
This patch is to enable KVM-related configuration options for host and
|
||||
guest.
|
||||
|
||||
Signed-off-by: Alison Wang <alison.wang@nxp.com>
|
||||
---
|
||||
arch/arm/configs/ls_aarch32_defconfig | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
--- a/arch/arm/configs/ls_aarch32_defconfig
|
||||
+++ b/arch/arm/configs/ls_aarch32_defconfig
|
||||
@@ -102,7 +102,11 @@ CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_COUNT=8
|
||||
CONFIG_BLK_DEV_RAM_SIZE=262144
|
||||
+CONFIG_VIRTIO_BLK=y
|
||||
CONFIG_NETDEVICES=y
|
||||
+CONFIG_TUN=y
|
||||
+CONFIG_VIRTIO_NET=y
|
||||
+CONFIG_VHOST_NET=y
|
||||
CONFIG_NET_VENDOR_FREESCALE is not set
|
||||
CONFIG_FSL_BMAN=y
|
||||
CONFIG_FSL_QMAN=y
|
||||
@@ -130,6 +134,8 @@ CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_SERIAL_8250_EXTENDED=y
|
||||
CONFIG_SERIAL_8250_SHARE_IRQ=y
|
||||
+CONFIG_SERIAL_AMBA_PL011=y
|
||||
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
CONFIG_SERIAL_FSL_LPUART=y
|
||||
CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
|
||||
@@ -170,6 +176,7 @@ CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_DS3232=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_FSL_EDMA=y
|
||||
+CONFIG_VIRTIO_PCI=y
|
||||
CONFIG_STAGING=y
|
||||
CONFIG_CLK_QORIQ=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
@@ -191,6 +198,7 @@ CONFIG_VFAT_FS=y
|
||||
CONFIG_NTFS_FS=m
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
+CONFIG_HUGETLBFS=y
|
||||
CONFIG_CONFIGFS_FS=y
|
||||
CONFIG_JFFS2_FS=y
|
||||
CONFIG_NFS_FS=y
|
||||
@@ -221,3 +229,5 @@ CONFIG_CRC_CCITT=m
|
||||
CONFIG_CRC_T10DIF=y
|
||||
CONFIG_CRC7=m
|
||||
CONFIG_LIBCRC32C=m
|
||||
+CONFIG_VIRTUALIZATION=y
|
||||
+CONFIG_KVM=y
|
||||
@@ -0,0 +1,23 @@
|
||||
From 6df7fdf7e0c76df7acc2d1a3a287bf094a94c4ff Mon Sep 17 00:00:00 2001
|
||||
From: Ying Zhang <ying.zhang22455@nxp.com>
|
||||
Date: Thu, 29 Sep 2016 13:55:44 +0800
|
||||
Subject: [PATCH 124/124] armv8: aarch32: defconfig: Enable FTM alarm support
|
||||
|
||||
This patch is to enable FTM alarm support.
|
||||
|
||||
Signed-off-by: Alison Wang <alison.wang@nxp.com>
|
||||
---
|
||||
arch/arm/configs/ls_aarch32_defconfig | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/arch/arm/configs/ls_aarch32_defconfig
|
||||
+++ b/arch/arm/configs/ls_aarch32_defconfig
|
||||
@@ -181,6 +181,8 @@ CONFIG_STAGING=y
|
||||
CONFIG_CLK_QORIQ=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_MEMORY=y
|
||||
+CONFIG_LS_SOC_DRIVERS=y
|
||||
+CONFIG_FTM_ALARM=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PWM_FSL_FTM=y
|
||||
# CONFIG_RESET_CONTROLLER is not set
|
||||
@@ -0,0 +1,880 @@
|
||||
From 70e0080366e76dabf90b713f57fb9fc47aa35557 Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Thu, 11 Aug 2016 10:36:05 +0800
|
||||
Subject: [PATCH 071/113] arm64: dts: add device tree for ls1012a SoC and
|
||||
boards
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This patch is to add device tree for ls1012a SoC and RDB/FREEDOM boards.
|
||||
|
||||
Signed-off-by: Pratiyush Mohan Srivastava <pratiyush.srivastava@nxp.com>
|
||||
Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
|
||||
Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
|
||||
Signed-off-by: Rajesh Bhagat <rajesh.bhagat@nxp.com>
|
||||
Signed-off-by: Alison Wang <alison.wang@nxp.com>
|
||||
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
|
||||
Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@freescale.com>
|
||||
Signed-off-by: Tang Yuantian <yuantian.tang@nxp.com>
|
||||
Signed-off-by: Chenhui Zhao <chenhui.zhao@nxp.com>
|
||||
Signed-off-by: Jia Hongtao <hongtao.jia@nxp.com>
|
||||
Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
|
||||
[yangbolu: integrate]
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
arch/arm64/boot/dts/freescale/Makefile | 2 +
|
||||
arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts | 186 +++++++
|
||||
arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts | 114 +++++
|
||||
arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 526 ++++++++++++++++++++
|
||||
4 files changed, 828 insertions(+)
|
||||
create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts
|
||||
create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts
|
||||
create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
|
||||
|
||||
--- a/arch/arm64/boot/dts/freescale/Makefile
|
||||
+++ b/arch/arm64/boot/dts/freescale/Makefile
|
||||
@@ -2,6 +2,8 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2
|
||||
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-rdb.dtb
|
||||
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-simu.dtb
|
||||
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb.dtb
|
||||
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-rdb.dtb
|
||||
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frdm.dtb
|
||||
|
||||
always := $(dtb-y)
|
||||
subdir-y := $(dts-dirs)
|
||||
--- /dev/null
|
||||
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts
|
||||
@@ -0,0 +1,186 @@
|
||||
+/*
|
||||
+ * Device Tree Include file for Freescale Layerscape-1012A family SoC.
|
||||
+ *
|
||||
+ * Copyright 2016, Freescale Semiconductor Inc.
|
||||
+
|
||||
+ * Redistribution and use in source and binary forms, with or without
|
||||
+ * modification, are permitted provided that the following conditions are met:
|
||||
+ * * Redistributions of source code must retain the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer.
|
||||
+ * * Redistributions in binary form must reproduce the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer in the
|
||||
+ * documentation and/or other materials provided with the distribution.
|
||||
+ * * Neither the name of Freescale Semiconductor nor the
|
||||
+ * names of its contributors may be used to endorse or promote products
|
||||
+ * derived from this software without specific prior written permission.
|
||||
+ *
|
||||
+ *
|
||||
+ * ALTERNATIVELY, this software may be distributed under the terms of the
|
||||
+ * GNU General Public License ("GPL") as published by the Free Software
|
||||
+ * Foundation, either version 2 of that License or (at your option) any
|
||||
+ * later version.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
|
||||
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
|
||||
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+ */
|
||||
+/dts-v1/;
|
||||
+
|
||||
+#include "fsl-ls1012a.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "LS1012A FREEDOM Board";
|
||||
+ compatible = "fsl,ls1012a-frdm", "fsl,ls1012a";
|
||||
+
|
||||
+ aliases {
|
||||
+ crypto = &crypto;
|
||||
+ };
|
||||
+
|
||||
+ sys_mclk: clock-mclk {
|
||||
+ compatible = "fixed-clock";
|
||||
+ #clock-cells = <0>;
|
||||
+ clock-frequency = <25000000>;
|
||||
+ };
|
||||
+
|
||||
+ regulators {
|
||||
+ compatible = "simple-bus";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ reg_1p8v: regulator@0 {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ reg = <0>;
|
||||
+ regulator-name = "1P8V";
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,format = "i2s";
|
||||
+ simple-audio-card,widgets =
|
||||
+ "Microphone", "Microphone Jack",
|
||||
+ "Headphone", "Headphone Jack",
|
||||
+ "Speaker", "Speaker Ext",
|
||||
+ "Line", "Line In Jack";
|
||||
+ simple-audio-card,routing =
|
||||
+ "MIC_IN", "Microphone Jack",
|
||||
+ "Microphone Jack", "Mic Bias",
|
||||
+ "LINE_IN", "Line In Jack",
|
||||
+ "Headphone Jack", "HP_OUT",
|
||||
+ "Speaker Ext", "LINE_OUT";
|
||||
+
|
||||
+ simple-audio-card,cpu {
|
||||
+ sound-dai = <&sai2>;
|
||||
+ frame-master;
|
||||
+ bitclock-master;
|
||||
+ };
|
||||
+
|
||||
+ simple-audio-card,codec {
|
||||
+ sound-dai = <&codec>;
|
||||
+ frame-master;
|
||||
+ bitclock-master;
|
||||
+ system-clock-frequency = <25000000>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&qspi {
|
||||
+ num-cs = <2>;
|
||||
+ bus-num = <0>;
|
||||
+ status = "okay";
|
||||
+ fsl,ddr-sampling-point = <4>;
|
||||
+
|
||||
+ qflash0: s25fs512s@0 {
|
||||
+ compatible = "spansion,m25p80";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ spi-max-frequency = <20000000>;
|
||||
+ m25p,fast-read;
|
||||
+ reg = <0>;
|
||||
+ };
|
||||
+};
|
||||
+&ftm0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2c0 {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ codec: sgtl5000@a {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "fsl,sgtl5000";
|
||||
+ reg = <0xa>;
|
||||
+ VDDA-supply = <®_1p8v>;
|
||||
+ VDDIO-supply = <®_1p8v>;
|
||||
+ clocks = <&sys_mclk 1>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&duart0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+&pfe {
|
||||
+ status = "okay";
|
||||
+ ethernet@0 {
|
||||
+ compatible = "fsl,pfe-gemac-port";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ reg = < 0x0 >; /* GEM_ID */
|
||||
+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */
|
||||
+ fsl,gemac-phy-id = <0x2>; /* PHY_ID */
|
||||
+ fsl,mdio-mux-val = <0x0>;
|
||||
+ local-mac-address = [ 00 1A 2B 3C 4D 5E ];
|
||||
+ phy-mode = "sgmii";
|
||||
+ fsl,pfe-gemac-if-name = "eth0";
|
||||
+ fsl,pfe-phy-if-flags = <0x0>;
|
||||
+ fsl,pfe-gemac-mode = <0x1B00>; /* GEMAC_SW_CONF | GEMAC_SW_FULL_DUPLEX | GEMAC_SW_SPEED_1G */
|
||||
+
|
||||
+ mdio@0 {
|
||||
+ reg = <0x1>; /* enabled/disabled */
|
||||
+ fsl,mdio-phy-mask = <0xFFFFFFF9>;
|
||||
+ };
|
||||
+ };
|
||||
+ ethernet@1 {
|
||||
+ compatible = "fsl,pfe-gemac-port";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ reg = < 0x1 >; /* GEM_ID */
|
||||
+ fsl,gemac-bus-id = < 0x1 >; /* BUS_ID */
|
||||
+ fsl,gemac-phy-id = < 0x1 >; /* PHY_ID */
|
||||
+ fsl,mdio-mux-val = <0x0>;
|
||||
+ local-mac-address = [ 00 AA BB CC DD EE ];
|
||||
+ phy-mode = "sgmii";
|
||||
+ fsl,pfe-gemac-if-name = "eth1";
|
||||
+ fsl,pfe-phy-if-flags = <0x0>;
|
||||
+ fsl,pfe-gemac-mode = <0x1B00>; /* GEMAC_SW_CONF | GEMAC_SW_FULL_DUPLEX | GEMAC_SW_SPEED_1G */
|
||||
+ mdio@0 {
|
||||
+ reg = <0x0>; /* enabled/disabled */
|
||||
+ fsl,mdio-phy-mask = <0xFFFFFFF9>;
|
||||
+ };
|
||||
+
|
||||
+ };
|
||||
+
|
||||
+};
|
||||
+
|
||||
+
|
||||
+&esdhc0 {
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
+&esdhc1 {
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
+&sai2 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts
|
||||
@@ -0,0 +1,114 @@
|
||||
+/*
|
||||
+ * Device Tree Include file for Freescale Layerscape-1012A family SoC.
|
||||
+ *
|
||||
+ * Copyright 2016, Freescale Semiconductor Inc.
|
||||
+
|
||||
+ * Redistribution and use in source and binary forms, with or without
|
||||
+ * modification, are permitted provided that the following conditions are met:
|
||||
+ * * Redistributions of source code must retain the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer.
|
||||
+ * * Redistributions in binary form must reproduce the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer in the
|
||||
+ * documentation and/or other materials provided with the distribution.
|
||||
+ * * Neither the name of Freescale Semiconductor nor the
|
||||
+ * names of its contributors may be used to endorse or promote products
|
||||
+ * derived from this software without specific prior written permission.
|
||||
+ *
|
||||
+ *
|
||||
+ * ALTERNATIVELY, this software may be distributed under the terms of the
|
||||
+ * GNU General Public License ("GPL") as published by the Free Software
|
||||
+ * Foundation, either version 2 of that License or (at your option) any
|
||||
+ * later version.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
|
||||
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
|
||||
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+ */
|
||||
+/dts-v1/;
|
||||
+
|
||||
+#include "fsl-ls1012a.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "LS1012A RDB Board";
|
||||
+ compatible = "fsl,ls1012a-rdb", "fsl,ls1012a";
|
||||
+
|
||||
+ aliases {
|
||||
+ crypto = &crypto;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&qspi {
|
||||
+ num-cs = <2>;
|
||||
+ bus-num = <0>;
|
||||
+ status = "okay";
|
||||
+ fsl,ddr-sampling-point = <4>;
|
||||
+
|
||||
+ qflash0: s25fs512s@0 {
|
||||
+ compatible = "spansion,m25p80";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ spi-max-frequency = <20000000>;
|
||||
+ m25p,fast-read;
|
||||
+ reg = <0>;
|
||||
+ };
|
||||
+};
|
||||
+&ftm0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2c0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&duart0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+&pfe {
|
||||
+ status = "okay";
|
||||
+ ethernet@0 {
|
||||
+ compatible = "fsl,pfe-gemac-port";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ reg = < 0x0 >; /* GEM_ID */
|
||||
+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */
|
||||
+ fsl,gemac-phy-id = <0x2>; /* PHY_ID */
|
||||
+ fsl,mdio-mux-val = <0x0>;
|
||||
+ local-mac-address = [ 00 1A 2B 3C 4D 5E ];
|
||||
+ phy-mode = "sgmii";
|
||||
+ fsl,pfe-gemac-if-name = "eth0";
|
||||
+ fsl,pfe-phy-if-flags = <0x0>;
|
||||
+ fsl,pfe-gemac-mode = <0x1B00>; /* GEMAC_SW_CONF | GEMAC_SW_FULL_DUPLEX | GEMAC_SW_SPEED_1G */
|
||||
+
|
||||
+ mdio@0 {
|
||||
+ reg = <0x1>; /* enabled/disabled */
|
||||
+ fsl,mdio-phy-mask = <0xFFFFFFF9>;
|
||||
+ };
|
||||
+ };
|
||||
+ ethernet@1 {
|
||||
+ compatible = "fsl,pfe-gemac-port";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ reg = < 0x1 >; /* GEM_ID */
|
||||
+ fsl,gemac-bus-id = < 0x1 >; /* BUS_ID */
|
||||
+ fsl,gemac-phy-id = < 0x1 >; /* PHY_ID */
|
||||
+ fsl,mdio-mux-val = <0x0>;
|
||||
+ local-mac-address = [ 00 AA BB CC DD EE ];
|
||||
+ phy-mode = "rgmii";
|
||||
+ fsl,pfe-gemac-if-name = "eth2";
|
||||
+ fsl,pfe-phy-if-flags = <0x0>;
|
||||
+ fsl,pfe-gemac-mode = <0x1B00>; /* GEMAC_SW_CONF | GEMAC_SW_FULL_DUPLEX | GEMAC_SW_SPEED_1G */
|
||||
+ mdio@0 {
|
||||
+ reg = <0x0>; /* enabled/disabled */
|
||||
+ fsl,mdio-phy-mask = <0xFFFFFFF9>;
|
||||
+ };
|
||||
+
|
||||
+ };
|
||||
+
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
|
||||
@@ -0,0 +1,526 @@
|
||||
+/*
|
||||
+ * Device Tree Include file for Freescale Layerscape-1043A family SoC.
|
||||
+ *
|
||||
+ * Copyright 2016, Freescale Semiconductor
|
||||
+ *
|
||||
+ * This file is dual-licensed: you can use it either under the terms
|
||||
+ * of the GPLv2 or the X11 license, at your option. Note that this dual
|
||||
+ * licensing only applies to this file, and not this project as a
|
||||
+ * whole.
|
||||
+ *
|
||||
+ * a) This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation; either version 2 of the
|
||||
+ * License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * Or, alternatively,
|
||||
+ *
|
||||
+ * b) Permission is hereby granted, free of charge, to any person
|
||||
+ * obtaining a copy of this software and associated documentation
|
||||
+ * files (the "Software"), to deal in the Software without
|
||||
+ * restriction, including without limitation the rights to use,
|
||||
+ * copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
+ * sell copies of the Software, and to permit persons to whom the
|
||||
+ * Software is furnished to do so, subject to the following
|
||||
+ * conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be
|
||||
+ * included in all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
+ * OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#include <dt-bindings/thermal/thermal.h>
|
||||
+
|
||||
+/ {
|
||||
+ compatible = "fsl,ls1012a";
|
||||
+ interrupt-parent = <&gic>;
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <2>;
|
||||
+
|
||||
+ cpus {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ /*
|
||||
+ * We expect the enable-method for cpu's to be "psci", but this
|
||||
+ * is dependent on the SoC FW, which will fill this in.
|
||||
+ *
|
||||
+ * Currently supported enable-method is psci v0.2
|
||||
+ */
|
||||
+ cpu0: cpu@0 {
|
||||
+ device_type = "cpu";
|
||||
+ compatible = "arm,cortex-a53";
|
||||
+ reg = <0x0>;
|
||||
+ clocks = <&clockgen 1 0>;
|
||||
+ #cooling-cells = <2>;
|
||||
+ };
|
||||
+
|
||||
+ };
|
||||
+
|
||||
+
|
||||
+ sysclk: sysclk {
|
||||
+ compatible = "fixed-clock";
|
||||
+ #clock-cells = <0>;
|
||||
+ clock-frequency = <100000000>;
|
||||
+ clock-output-names = "sysclk";
|
||||
+ };
|
||||
+
|
||||
+ timer {
|
||||
+ compatible = "arm,armv8-timer";
|
||||
+ interrupts = <1 13 0x1>, /* Physical Secure PPI */
|
||||
+ <1 14 0x1>, /* Physical Non-Secure PPI */
|
||||
+ <1 11 0x1>, /* Virtual PPI */
|
||||
+ <1 10 0x1>; /* Hypervisor PPI */
|
||||
+ arm,reread-timer;
|
||||
+ };
|
||||
+
|
||||
+ pmu {
|
||||
+ compatible = "arm,armv8-pmuv3";
|
||||
+ interrupts = <0 106 0x4>;
|
||||
+ };
|
||||
+
|
||||
+ gic: interrupt-controller@1400000 {
|
||||
+ compatible = "arm,gic-400";
|
||||
+ #interrupt-cells = <3>;
|
||||
+ interrupt-controller;
|
||||
+ reg = <0x0 0x1401000 0 0x1000>, /* GICD */
|
||||
+ <0x0 0x1402000 0 0x2000>, /* GICC */
|
||||
+ <0x0 0x1404000 0 0x2000>, /* GICH */
|
||||
+ <0x0 0x1406000 0 0x2000>; /* GICV */
|
||||
+ interrupts = <1 9 0xf08>;
|
||||
+ };
|
||||
+
|
||||
+ soc {
|
||||
+ compatible = "simple-bus";
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <2>;
|
||||
+ ranges;
|
||||
+
|
||||
+ clockgen: clocking@1ee1000 {
|
||||
+ compatible = "fsl,ls1012a-clockgen";
|
||||
+ reg = <0x0 0x1ee1000 0x0 0x1000>;
|
||||
+ #clock-cells = <2>;
|
||||
+ clocks = <&sysclk>;
|
||||
+ };
|
||||
+
|
||||
+ scfg: scfg@1570000 {
|
||||
+ compatible = "fsl,ls1012a-scfg",
|
||||
+ "fsl,ls1043a-scfg",
|
||||
+ "syscon";
|
||||
+ reg = <0x0 0x1570000 0x0 0x10000>;
|
||||
+ big-endian;
|
||||
+ };
|
||||
+
|
||||
+ crypto: crypto@1700000 {
|
||||
+ compatible = "fsl,sec-v5.4", "fsl,sec-v5.0",
|
||||
+ "fsl,sec-v4.0";
|
||||
+ fsl,sec-era = <8>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ ranges = <0x0 0x00 0x1700000 0x100000>;
|
||||
+ reg = <0x00 0x1700000 0x0 0x100000>;
|
||||
+ interrupts = <0 75 0x4>;
|
||||
+
|
||||
+ sec_jr0: jr@10000 {
|
||||
+ compatible = "fsl,sec-v5.4-job-ring",
|
||||
+ "fsl,sec-v5.0-job-ring",
|
||||
+ "fsl,sec-v4.0-job-ring";
|
||||
+ reg = <0x10000 0x10000>;
|
||||
+ interrupts = <0 71 0x4>;
|
||||
+ };
|
||||
+
|
||||
+ sec_jr1: jr@20000 {
|
||||
+ compatible = "fsl,sec-v5.4-job-ring",
|
||||
+ "fsl,sec-v5.0-job-ring",
|
||||
+ "fsl,sec-v4.0-job-ring";
|
||||
+ reg = <0x20000 0x10000>;
|
||||
+ interrupts = <0 72 0x4>;
|
||||
+ };
|
||||
+
|
||||
+ sec_jr2: jr@30000 {
|
||||
+ compatible = "fsl,sec-v5.4-job-ring",
|
||||
+ "fsl,sec-v5.0-job-ring",
|
||||
+ "fsl,sec-v4.0-job-ring";
|
||||
+ reg = <0x30000 0x10000>;
|
||||
+ interrupts = <0 73 0x4>;
|
||||
+ };
|
||||
+
|
||||
+ sec_jr3: jr@40000 {
|
||||
+ compatible = "fsl,sec-v5.4-job-ring",
|
||||
+ "fsl,sec-v5.0-job-ring",
|
||||
+ "fsl,sec-v4.0-job-ring";
|
||||
+ reg = <0x40000 0x10000>;
|
||||
+ interrupts = <0 74 0x4>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+
|
||||
+ dcfg: dcfg@1ee0000 {
|
||||
+ compatible = "fsl,ls1012a-dcfg",
|
||||
+ "fsl,ls1043a-dcfg",
|
||||
+ "syscon";
|
||||
+ reg = <0x0 0x1ee0000 0x0 0x10000>;
|
||||
+ };
|
||||
+
|
||||
+ reset: reset@1EE00B0 {
|
||||
+ compatible = "fsl,ls-reset";
|
||||
+ reg = <0x0 0x1EE00B0 0x0 0x4>;
|
||||
+ big-endian;
|
||||
+ };
|
||||
+
|
||||
+ rcpm: rcpm@1ee2000 {
|
||||
+ compatible = "fsl,ls1012a-rcpm",
|
||||
+ "fsl,ls1043a-rcpm",
|
||||
+ "fsl,qoriq-rcpm-2.1";
|
||||
+ reg = <0x0 0x1ee2000 0x0 0x10000>;
|
||||
+ };
|
||||
+
|
||||
+ ftm0: ftm0@29d0000 {
|
||||
+ compatible = "fsl,ftm-alarm";
|
||||
+ reg = <0x0 0x29d0000 0x0 0x10000>;
|
||||
+ interrupts = <0 86 0x4>;
|
||||
+ big-endian;
|
||||
+ rcpm-wakeup = <&rcpm 0x00020000 0x0>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ esdhc0: esdhc@1560000 {
|
||||
+ compatible = "fsl,ls1012a-esdhc0", "fsl,esdhc";
|
||||
+ reg = <0x0 0x1560000 0x0 0x10000>;
|
||||
+ interrupts = <0 62 0x4>;
|
||||
+ clock-frequency = <0>;
|
||||
+ voltage-ranges = <1800 1800 3300 3300>;
|
||||
+ sdhci,auto-cmd12;
|
||||
+ big-endian;
|
||||
+ bus-width = <4>;
|
||||
+ };
|
||||
+
|
||||
+ esdhc1: esdhc@1580000 {
|
||||
+ compatible = "fsl,ls1012a-esdhc1", "fsl,esdhc";
|
||||
+ reg = <0x0 0x1580000 0x0 0x10000>;
|
||||
+ interrupts = <0 65 0x4>;
|
||||
+ clock-frequency = <0>;
|
||||
+ voltage-ranges = <1800 1800 3300 3300>;
|
||||
+ sdhci,auto-cmd12;
|
||||
+ big-endian;
|
||||
+ bus-width = <4>;
|
||||
+ };
|
||||
+
|
||||
+ dspi0: dspi@2100000 {
|
||||
+ compatible = "fsl,ls1012a-dspi",
|
||||
+ "fsl,ls1043a-dspi",
|
||||
+ "fsl,ls1021a-v1.0-dspi";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ reg = <0x0 0x2100000 0x0 0x10000>;
|
||||
+ interrupts = <0 64 0x4>;
|
||||
+ clock-names = "dspi";
|
||||
+ clocks = <&clockgen 4 0>;
|
||||
+ spi-num-chipselects = <5>;
|
||||
+ big-endian;
|
||||
+ status = "enabled";
|
||||
+ };
|
||||
+
|
||||
+ qspi: quadspi@1550000 {
|
||||
+ compatible = "fsl,ls1012a-qspi",
|
||||
+ "fsl,ls1043a-qspi",
|
||||
+ "fsl,ls1021a-qspi";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ reg = <0x0 0x1550000 0x0 0x10000>,
|
||||
+ <0x0 0x40000000 0x0 0x4000000>;
|
||||
+ reg-names = "QuadSPI", "QuadSPI-memory";
|
||||
+ interrupts = <0 99 0x4>;
|
||||
+ clock-names = "qspi_en", "qspi";
|
||||
+ clocks = <&clockgen 4 0>, <&clockgen 4 0>;
|
||||
+ big-endian;
|
||||
+ amba-base = <0x42000000>;
|
||||
+ };
|
||||
+
|
||||
+ tmu: tmu@1f00000 {
|
||||
+ compatible = "fsl,qoriq-tmu", "fsl,ls1012a-tmu";
|
||||
+ reg = <0x0 0x1f00000 0x0 0x10000>;
|
||||
+ interrupts = <0 33 0x4>;
|
||||
+ fsl,tmu-range = <0xb0000 0x9002a 0x6004c 0x30062>;
|
||||
+ fsl,tmu-calibration = <0x00000000 0x00000026
|
||||
+ 0x00000001 0x0000002d
|
||||
+ 0x00000002 0x00000032
|
||||
+ 0x00000003 0x00000039
|
||||
+ 0x00000004 0x0000003f
|
||||
+ 0x00000005 0x00000046
|
||||
+ 0x00000006 0x0000004d
|
||||
+ 0x00000007 0x00000054
|
||||
+ 0x00000008 0x0000005a
|
||||
+ 0x00000009 0x00000061
|
||||
+ 0x0000000a 0x0000006a
|
||||
+ 0x0000000b 0x00000071
|
||||
+
|
||||
+ 0x00010000 0x00000025
|
||||
+ 0x00010001 0x0000002c
|
||||
+ 0x00010002 0x00000035
|
||||
+ 0x00010003 0x0000003d
|
||||
+ 0x00010004 0x00000045
|
||||
+ 0x00010005 0x0000004e
|
||||
+ 0x00010006 0x00000057
|
||||
+ 0x00010007 0x00000061
|
||||
+ 0x00010008 0x0000006b
|
||||
+ 0x00010009 0x00000076
|
||||
+
|
||||
+ 0x00020000 0x00000029
|
||||
+ 0x00020001 0x00000033
|
||||
+ 0x00020002 0x0000003d
|
||||
+ 0x00020003 0x00000049
|
||||
+ 0x00020004 0x00000056
|
||||
+ 0x00020005 0x00000061
|
||||
+ 0x00020006 0x0000006d
|
||||
+
|
||||
+ 0x00030000 0x00000021
|
||||
+ 0x00030001 0x0000002a
|
||||
+ 0x00030002 0x0000003c
|
||||
+ 0x00030003 0x0000004e>;
|
||||
+ big-endian;
|
||||
+ #thermal-sensor-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ thermal-zones {
|
||||
+ cpu_thermal: cpu-thermal {
|
||||
+ polling-delay-passive = <1000>;
|
||||
+ polling-delay = <5000>;
|
||||
+
|
||||
+ thermal-sensors = <&tmu 0>;
|
||||
+
|
||||
+ trips {
|
||||
+ cpu_alert: cpu-alert {
|
||||
+ temperature = <85000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "passive";
|
||||
+ };
|
||||
+ cpu_crit: cpu-crit {
|
||||
+ temperature = <95000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "critical";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cooling-maps {
|
||||
+ map0 {
|
||||
+ trip = <&cpu_alert>;
|
||||
+ cooling-device =
|
||||
+ <&cpu0 THERMAL_NO_LIMIT
|
||||
+ THERMAL_NO_LIMIT>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ i2c0: i2c@2180000 {
|
||||
+ compatible = "fsl,vf610-i2c";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ reg = <0x0 0x2180000 0x0 0x10000>;
|
||||
+ interrupts = <0 56 0x4>;
|
||||
+ clock-names = "i2c";
|
||||
+ clocks = <&clockgen 4 0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ i2c1: i2c@2190000 {
|
||||
+ compatible = "fsl,vf610-i2c";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ reg = <0x0 0x2190000 0x0 0x10000>;
|
||||
+ interrupts = <0 57 0x4>;
|
||||
+ clock-names = "i2c";
|
||||
+ clocks = <&clockgen 4 0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+
|
||||
+ duart0: serial@21c0500 {
|
||||
+ compatible = "fsl,ns16550", "ns16550a";
|
||||
+ reg = <0x00 0x21c0500 0x0 0x100>;
|
||||
+ interrupts = <0 54 0x4>;
|
||||
+ clocks = <&clockgen 4 0>;
|
||||
+ };
|
||||
+
|
||||
+ duart1: serial@21c0600 {
|
||||
+ compatible = "fsl,ns16550", "ns16550a";
|
||||
+ reg = <0x00 0x21c0600 0x0 0x100>;
|
||||
+ interrupts = <0 54 0x4>;
|
||||
+ clocks = <&clockgen 4 0>;
|
||||
+ };
|
||||
+
|
||||
+ gpio0: gpio@2300000 {
|
||||
+ compatible = "fsl,qoriq-gpio";
|
||||
+ reg = <0x0 0x2300000 0x0 0x10000>;
|
||||
+ interrupts = <0 66 0x4>;
|
||||
+ gpio-controller;
|
||||
+ #gpio-cells = <2>;
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <2>;
|
||||
+ };
|
||||
+
|
||||
+ gpio1: gpio@2310000 {
|
||||
+ compatible = "fsl,qoriq-gpio";
|
||||
+ reg = <0x0 0x2310000 0x0 0x10000>;
|
||||
+ interrupts = <0 67 0x4>;
|
||||
+ gpio-controller;
|
||||
+ #gpio-cells = <2>;
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <2>;
|
||||
+ };
|
||||
+
|
||||
+ wdog0: wdog@2ad0000 {
|
||||
+ compatible = "fsl,ls1012a-wdt",
|
||||
+ "fsl,ls1043a-wdt",
|
||||
+ "fsl,imx21-wdt";
|
||||
+ reg = <0x0 0x2ad0000 0x0 0x10000>;
|
||||
+ interrupts = <0 83 0x4>;
|
||||
+ clocks = <&clockgen 4 0>;
|
||||
+ clock-names = "wdog";
|
||||
+ big-endian;
|
||||
+ };
|
||||
+
|
||||
+ sai1: sai@2b50000 {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "fsl,vf610-sai";
|
||||
+ reg = <0x0 0x2b50000 0x0 0x10000>;
|
||||
+ interrupts = <0 148 0x4>;
|
||||
+ clocks = <&clockgen 4 3>, <&clockgen 4 3>,
|
||||
+ <&clockgen 4 3>, <&clockgen 4 3>;
|
||||
+ clock-names = "bus", "mclk1", "mclk2", "mclk3";
|
||||
+ dma-names = "tx", "rx";
|
||||
+ dmas = <&edma0 1 47>,
|
||||
+ <&edma0 1 46>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ sai2: sai@2b60000 {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "fsl,vf610-sai";
|
||||
+ reg = <0x0 0x2b60000 0x0 0x10000>;
|
||||
+ interrupts = <0 149 0x4>;
|
||||
+ clocks = <&clockgen 4 3>, <&clockgen 4 3>,
|
||||
+ <&clockgen 4 3>, <&clockgen 4 3>;
|
||||
+ clock-names = "bus", "mclk1", "mclk2", "mclk3";
|
||||
+ dma-names = "tx", "rx";
|
||||
+ dmas = <&edma0 1 45>,
|
||||
+ <&edma0 1 44>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ edma0: edma@2c00000 {
|
||||
+ #dma-cells = <2>;
|
||||
+ compatible = "fsl,vf610-edma";
|
||||
+ reg = <0x0 0x2c00000 0x0 0x10000>,
|
||||
+ <0x0 0x2c10000 0x0 0x10000>,
|
||||
+ <0x0 0x2c20000 0x0 0x10000>;
|
||||
+ interrupts = <0 103 0x4>,
|
||||
+ <0 103 0x4>;
|
||||
+ interrupt-names = "edma-tx", "edma-err";
|
||||
+ dma-channels = <32>;
|
||||
+ big-endian;
|
||||
+ clock-names = "dmamux0", "dmamux1";
|
||||
+ clocks = <&clockgen 4 3>,
|
||||
+ <&clockgen 4 3>;
|
||||
+ };
|
||||
+
|
||||
+ sata: sata@3200000 {
|
||||
+ compatible = "fsl,ls1012a-ahci";
|
||||
+ reg = <0x0 0x3200000 0x0 0x10000>;
|
||||
+ interrupts = <0 69 0x4>;
|
||||
+ clocks = <&clockgen 4 0>;
|
||||
+ };
|
||||
+
|
||||
+ msi2: msi-controller2@1572000 {
|
||||
+ compatible ="fsl,1s1012a-msi", "fsl,1s1021a-msi";
|
||||
+ reg = <0x0 0x1572000 0x0 0x4>,
|
||||
+ <0x0 0x1572004 0x0 0x4>;
|
||||
+ reg-names = "msiir", "msir";
|
||||
+ msi-controller;
|
||||
+ interrupts = <0 126 0x4>;
|
||||
+ };
|
||||
+
|
||||
+ usb@8600000 {
|
||||
+ compatible = "fsl-usb2-dr-v2.5", "fsl-usb2-dr";
|
||||
+ reg = <0x0 0x8600000 0x0 0x1000>;
|
||||
+ interrupts = <0 139 0x4>;
|
||||
+ dr_mode = "host";
|
||||
+ phy_type = "ulpi";
|
||||
+ fsl,usb-erratum-a005697;
|
||||
+ };
|
||||
+
|
||||
+ usb0: usb3@2f00000 {
|
||||
+ compatible = "snps,dwc3";
|
||||
+ reg = <0x0 0x2f00000 0x0 0x10000>;
|
||||
+ interrupts = <0 60 0x4>;
|
||||
+ dr_mode = "host";
|
||||
+ configure-gfladj;
|
||||
+ snps,dis_rxdet_inp3_quirk;
|
||||
+ };
|
||||
+
|
||||
+ pcie@3400000 {
|
||||
+ compatible = "fsl,ls1012a-pcie",
|
||||
+ "fsl,ls1043a-pcie",
|
||||
+ "snps,dw-pcie";
|
||||
+ reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */
|
||||
+ 0x40 0x00000000 0x0 0x00002000>; /* configuration space */
|
||||
+ reg-names = "regs", "config";
|
||||
+ interrupts = <0 118 0x4>, /* controller interrupt */
|
||||
+ <0 117 0x4>; /* PME interrupt */
|
||||
+ interrupt-names = "intr", "pme";
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+ device_type = "pci";
|
||||
+ num-lanes = <4>;
|
||||
+ bus-range = <0x0 0xff>;
|
||||
+ ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */
|
||||
+ 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
|
||||
+ msi-parent = <&msi2>;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ interrupt-map-mask = <0 0 0 7>;
|
||||
+ interrupt-map = <0000 0 0 1 &gic 0 110 0x4>,
|
||||
+ <0000 0 0 2 &gic 0 111 0x4>,
|
||||
+ <0000 0 0 3 &gic 0 112 0x4>,
|
||||
+ <0000 0 0 4 &gic 0 113 0x4>;
|
||||
+ };
|
||||
+ };
|
||||
+ reserved-memory {
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <2>;
|
||||
+ ranges;
|
||||
+
|
||||
+ pfe_reserved: packetbuffer@83400000 {
|
||||
+ reg = <0 0x83400000 0 0xc00000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ pfe: pfe@04000000 {
|
||||
+ compatible = "fsl,pfe";
|
||||
+ ranges = <0x0 0x00 0x04000000 0xc00000
|
||||
+ 0x1 0x00 0x83400000 0xc00000>;
|
||||
+ reg = <0x0 0x90500000 0x0 0x10000>, /* APB 64K */
|
||||
+ <0x0 0x04000000 0x0 0xc00000>, /* AXI 16M */
|
||||
+ <0x0 0x83400000 0x0 0xc00000>, /* PFE DDR 12M */
|
||||
+ <0x0 0x10000000 0x0 0x2000>; /* OCRAM 8K */
|
||||
+ fsl,pfe-num-interfaces = < 0x2 >;
|
||||
+ interrupts = <0 172 0x4>;
|
||||
+ #interrupt-names = "hifirq";
|
||||
+ memory-region = <&pfe_reserved>;
|
||||
+ fsl,pfe-scfg = <&scfg 0>;
|
||||
+ };
|
||||
+
|
||||
+};
|
||||
@@ -0,0 +1,49 @@
|
||||
From f6dcf8936845ea95eba432ee725cec761032fe2a Mon Sep 17 00:00:00 2001
|
||||
From: Ying Zhang <ying.zhang22455@nxp.com>
|
||||
Date: Thu, 29 Sep 2016 10:12:29 +0800
|
||||
Subject: [PATCH 117/124] armv8: aarch32: Run 32-bit Linux for LayerScape SoCs
|
||||
|
||||
This patch adds AArch32 execution state support for LayerScape SoCs.
|
||||
|
||||
Signed-off-by: Ebony Zhu <ebony.zhu@nxp.com>
|
||||
Signed-off-by: Alison Wang <alison.wang@nxp.com>
|
||||
---
|
||||
arch/arm/mach-imx/Makefile | 2 ++
|
||||
arch/arm/mach-imx/mach-layerscape.c | 22 ++++++++++++++++++++++
|
||||
2 files changed, 24 insertions(+)
|
||||
create mode 100644 arch/arm/mach-imx/mach-layerscape.c
|
||||
|
||||
--- a/arch/arm/mach-imx/Makefile
|
||||
+++ b/arch/arm/mach-imx/Makefile
|
||||
@@ -103,4 +103,6 @@ obj-$(CONFIG_SOC_LS1021A) += mach-ls1021
|
||||
|
||||
obj-$(CONFIG_ARCH_LAYERSCAPE) += mach-ls1043a.o
|
||||
|
||||
+obj-$(CONFIG_ARCH_LAYERSCAPE) += mach-layerscape.o
|
||||
+
|
||||
obj-y += devices/
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/mach-imx/mach-layerscape.c
|
||||
@@ -0,0 +1,22 @@
|
||||
+/*
|
||||
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+#include <asm/mach/arch.h>
|
||||
+
|
||||
+#include "common.h"
|
||||
+
|
||||
+static const char * const layerscape_dt_compat[] __initconst = {
|
||||
+ "fsl,ls1043a",
|
||||
+ "fsl,ls1012a",
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+DT_MACHINE_START(LAYERSCAPE, "Freescale LAYERSCAPE")
|
||||
+ .dt_compat = layerscape_dt_compat,
|
||||
+MACHINE_END
|
||||
@@ -0,0 +1,34 @@
|
||||
From 44914d3b7baff0f96c3584e4d46aa992e402ef4f Mon Sep 17 00:00:00 2001
|
||||
From: Ying Zhang <ying.zhang22455@nxp.com>
|
||||
Date: Thu, 29 Sep 2016 11:16:16 +0800
|
||||
Subject: [PATCH 118/124] armv8: aarch32: Add KVM support for AArch32 on ARMv8
|
||||
|
||||
This patch is to add KVM support for AArch32 execution state on ARMv8.
|
||||
|
||||
Signed-off-by: Alison Wang <alison.wang@nxp.com>
|
||||
---
|
||||
arch/arm/include/asm/cputype.h | 2 ++
|
||||
arch/arm/kvm/guest.c | 1 +
|
||||
2 files changed, 3 insertions(+)
|
||||
|
||||
--- a/arch/arm/include/asm/cputype.h
|
||||
+++ b/arch/arm/include/asm/cputype.h
|
||||
@@ -76,6 +76,8 @@
|
||||
#define ARM_CPU_PART_CORTEX_A15 0x4100c0f0
|
||||
#define ARM_CPU_PART_MASK 0xff00fff0
|
||||
|
||||
+#define ARM_CPU_PART_CORTEX_AARCH32_A53 0x4100d030
|
||||
+
|
||||
#define ARM_CPU_XSCALE_ARCH_MASK 0xe000
|
||||
#define ARM_CPU_XSCALE_ARCH_V1 0x2000
|
||||
#define ARM_CPU_XSCALE_ARCH_V2 0x4000
|
||||
--- a/arch/arm/kvm/guest.c
|
||||
+++ b/arch/arm/kvm/guest.c
|
||||
@@ -247,6 +247,7 @@ int __attribute_const__ kvm_target_cpu(v
|
||||
{
|
||||
switch (read_cpuid_part()) {
|
||||
case ARM_CPU_PART_CORTEX_A7:
|
||||
+ case ARM_CPU_PART_CORTEX_AARCH32_A53:
|
||||
return KVM_ARM_TARGET_CORTEX_A7;
|
||||
case ARM_CPU_PART_CORTEX_A15:
|
||||
return KVM_ARM_TARGET_CORTEX_A15;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,61 @@
|
||||
From 9112596c3c7b7b8b1eded3323765fa711dc58e74 Mon Sep 17 00:00:00 2001
|
||||
From: Tang Yuantian <Yuantian.Tang@nxp.com>
|
||||
Date: Thu, 25 Aug 2016 10:38:28 +0800
|
||||
Subject: [PATCH 073/113] ls1012a: added clock configuration
|
||||
|
||||
commit c9c11181191938b77bfd61e5094a63955cf711fd
|
||||
[context adjustment]
|
||||
[don't apply fsl-ls1012a.dtsi]
|
||||
|
||||
Currently ls1012a used the clock configuration of ls1043a's.
|
||||
But there is a little different between them. This patch added
|
||||
ls1012a its own clock configuration.
|
||||
|
||||
Signed-off-by: Tang Yuantian <yuantian.tang@nxp.com>
|
||||
Integrated-by: Zhao Qiang <qiang.zhao@nxp.com>
|
||||
---
|
||||
drivers/clk/clk-qoriq.c | 19 +++++++++++++++++++
|
||||
1 file changed, 19 insertions(+)
|
||||
|
||||
--- a/drivers/clk/clk-qoriq.c
|
||||
+++ b/drivers/clk/clk-qoriq.c
|
||||
@@ -195,6 +195,14 @@ static const struct clockgen_muxinfo t10
|
||||
}
|
||||
};
|
||||
|
||||
+static const struct clockgen_muxinfo ls1012a_cmux = {
|
||||
+ {
|
||||
+ [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
|
||||
+ {},
|
||||
+ [2] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
static const struct clockgen_muxinfo t1040_cmux = {
|
||||
{
|
||||
[0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
|
||||
@@ -475,6 +483,16 @@ static const struct clockgen_chipinfo ch
|
||||
.pll_mask = 0x03,
|
||||
},
|
||||
{
|
||||
+ .compat = "fsl,ls1012a-clockgen",
|
||||
+ .cmux_groups = {
|
||||
+ &ls1012a_cmux
|
||||
+ },
|
||||
+ .cmux_to_group = {
|
||||
+ 0, -1
|
||||
+ },
|
||||
+ .pll_mask = 0x03,
|
||||
+ },
|
||||
+ {
|
||||
.compat = "fsl,ls1043a-clockgen",
|
||||
.init_periph = t2080_init_periph,
|
||||
.cmux_groups = {
|
||||
@@ -1268,6 +1286,7 @@ CLK_OF_DECLARE(qoriq_clockgen_2, "fsl,qo
|
||||
CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init);
|
||||
CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init);
|
||||
CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init);
|
||||
+CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init);
|
||||
|
||||
/* Legacy nodes */
|
||||
CLK_OF_DECLARE(qoriq_sysclk_1, "fsl,qoriq-sysclk-1.0", sysclk_init);
|
||||
@@ -0,0 +1,49 @@
|
||||
From cfe7a6abd3d7e9ffeed8230847bbe2f680757305 Mon Sep 17 00:00:00 2001
|
||||
From: Pratiyush Mohan Srivastava <pratiyush.srivastava@nxp.com>
|
||||
Date: Sun, 24 Apr 2016 23:43:19 +0530
|
||||
Subject: [PATCH 114/123] drivers: PCIE enable for Linux
|
||||
|
||||
[This patch from sdk release, just context adjustment]
|
||||
Add support for PCIE for LS1012A in kernel
|
||||
|
||||
Signed-off-by: Pratiyush Mohan Srivastava <pratiyush.srivastava@nxp.com>
|
||||
Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
|
||||
Integrated-by: Jiang Yutang <yutang.jiang@nxp.com>
|
||||
---
|
||||
drivers/irqchip/irq-ls-scfg-msi.c | 1 +
|
||||
drivers/pci/host/pci-layerscape.c | 7 +++++++
|
||||
2 files changed, 8 insertions(+)
|
||||
|
||||
--- a/drivers/irqchip/irq-ls-scfg-msi.c
|
||||
+++ b/drivers/irqchip/irq-ls-scfg-msi.c
|
||||
@@ -219,6 +219,7 @@ static int ls_scfg_msi_remove(struct pla
|
||||
}
|
||||
|
||||
static const struct of_device_id ls_scfg_msi_id[] = {
|
||||
+ { .compatible = "fsl,ls1012a-msi", },
|
||||
{ .compatible = "fsl,1s1021a-msi", },
|
||||
{ .compatible = "fsl,1s1043a-msi", },
|
||||
{},
|
||||
--- a/drivers/pci/host/pci-layerscape.c
|
||||
+++ b/drivers/pci/host/pci-layerscape.c
|
||||
@@ -192,6 +192,12 @@ static struct ls_pcie_drvdata ls1021_drv
|
||||
.ops = &ls1021_pcie_host_ops,
|
||||
};
|
||||
|
||||
+static struct ls_pcie_drvdata ls1012_drvdata = {
|
||||
+ .lut_offset = 0xC0000,
|
||||
+ .ltssm_shift = 24,
|
||||
+ .ops = &ls_pcie_host_ops,
|
||||
+};
|
||||
+
|
||||
static struct ls_pcie_drvdata ls1043_drvdata = {
|
||||
.lut_offset = 0x10000,
|
||||
.ltssm_shift = 24,
|
||||
@@ -205,6 +211,7 @@ static struct ls_pcie_drvdata ls2080_drv
|
||||
};
|
||||
|
||||
static const struct of_device_id ls_pcie_of_match[] = {
|
||||
+ { .compatible = "fsl,ls1012a-pcie", .data = &ls1012_drvdata },
|
||||
{ .compatible = "fsl,ls1021a-pcie", .data = &ls1021_drvdata },
|
||||
{ .compatible = "fsl,ls1043a-pcie", .data = &ls1043_drvdata },
|
||||
{ .compatible = "fsl,ls2080a-pcie", .data = &ls2080_drvdata },
|
||||
@@ -0,0 +1,30 @@
|
||||
From 5d661761fd2354e4f976c83143a1bf7c1ecad766 Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Tue, 20 Sep 2016 16:07:10 +0800
|
||||
Subject: [PATCH 115/115] PCI: layerscape: call dw_pcie_setup_rc() in host
|
||||
initialization
|
||||
|
||||
A previous patch moved some Root Complex programming from
|
||||
dw_pcie_host_init() to dw_pcie_setup_rc() where it belongs,
|
||||
while the pci-layerscape driver didn't call dw_pcie_setup_rc()
|
||||
anywhere after that. This patch is to add dw_pcie_setup_rc()
|
||||
calling in layerscape host initialization to fix ls1012a pci
|
||||
issue caused by that patch.
|
||||
|
||||
Fixes: c49b76f3c613("PCI: designware: Move Root Complex setup
|
||||
code to dw_pcie_setup_rc()")
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
drivers/pci/host/pci-layerscape.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/pci/host/pci-layerscape.c
|
||||
+++ b/drivers/pci/host/pci-layerscape.c
|
||||
@@ -148,6 +148,7 @@ static void ls_pcie_host_init(struct pci
|
||||
{
|
||||
struct ls_pcie *pcie = to_ls_pcie(pp);
|
||||
|
||||
+ dw_pcie_setup_rc(pp);
|
||||
iowrite32(1, pcie->dbi + PCIE_DBI_RO_WR_EN);
|
||||
ls_pcie_fix_class(pcie);
|
||||
ls_pcie_clear_multifunction(pcie);
|
||||
Reference in New Issue
Block a user