summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arc/Kconfig5
-rw-r--r--arch/arc/config.mk6
-rw-r--r--arch/arc/dts/Makefile1
-rw-r--r--arch/arc/dts/abilis_tb100.dts2
-rw-r--r--arch/arc/dts/axs101.dts2
-rw-r--r--arch/arc/dts/axs103.dts2
-rw-r--r--arch/arc/dts/emdk.dts2
-rw-r--r--arch/arc/dts/hsdk.dts2
-rw-r--r--arch/arc/dts/iot_devkit.dts45
-rw-r--r--arch/arc/dts/nsim.dts2
-rw-r--r--arch/arc/lib/cpu.c35
-rw-r--r--board/synopsys/iot_devkit/Kconfig12
-rw-r--r--board/synopsys/iot_devkit/MAINTAINERS5
-rw-r--r--board/synopsys/iot_devkit/Makefile7
-rw-r--r--board/synopsys/iot_devkit/config.mk2
-rw-r--r--board/synopsys/iot_devkit/iot_devkit.c168
-rw-r--r--board/synopsys/iot_devkit/u-boot.lds77
-rw-r--r--common/Kconfig4
-rw-r--r--common/spl/spl_optee.S2
-rw-r--r--configs/iot_devkit_defconfig38
-rw-r--r--drivers/mtd/nand/spi/Makefile2
-rw-r--r--drivers/mtd/nand/spi/core.c1
-rw-r--r--drivers/mtd/nand/spi/gigadevice.c135
-rw-r--r--drivers/mtd/spi/Kconfig6
-rw-r--r--drivers/mtd/spi/spi_flash_ids.c4
-rw-r--r--drivers/spi/Kconfig8
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/mt7621_spi.c312
-rw-r--r--include/configs/iot_devkit.h84
-rw-r--r--include/linux/mtd/spinand.h1
30 files changed, 962 insertions, 11 deletions
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index d59aa3ae29..b24593e137 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -157,6 +157,10 @@ config TARGET_EMDK
config TARGET_HSDK
bool "Support Synpsys HS DevelopmentKit board"
+config TARGET_IOT_DEVKIT
+ bool "Synopsys Brite IoT Development kit"
+ select CPU_ARCEM6
+
endchoice
source "board/abilis/tb100/Kconfig"
@@ -164,5 +168,6 @@ source "board/synopsys/Kconfig"
source "board/synopsys/axs10x/Kconfig"
source "board/synopsys/emdk/Kconfig"
source "board/synopsys/hsdk/Kconfig"
+source "board/synopsys/iot_devkit/Kconfig"
endmenu
diff --git a/arch/arc/config.mk b/arch/arc/config.mk
index 169e5d7fae..d255c90e35 100644
--- a/arch/arc/config.mk
+++ b/arch/arc/config.mk
@@ -9,21 +9,15 @@ CONFIG_SYS_BIG_ENDIAN = 1
endif
ifdef CONFIG_SYS_LITTLE_ENDIAN
-ARC_CROSS_COMPILE := arc-linux-
PLATFORM_LDFLAGS += -EL
PLATFORM_CPPFLAGS += -mlittle-endian
endif
ifdef CONFIG_SYS_BIG_ENDIAN
-ARC_CROSS_COMPILE := arceb-linux-
PLATFORM_LDFLAGS += -EB
PLATFORM_CPPFLAGS += -mbig-endian
endif
-ifeq ($(CROSS_COMPILE),)
-CROSS_COMPILE := $(ARC_CROSS_COMPILE)
-endif
-
ifdef CONFIG_ARC_MMU_VER
CONFIG_MMU = 1
endif
diff --git a/arch/arc/dts/Makefile b/arch/arc/dts/Makefile
index 491a4f40bb..17e1405c0c 100644
--- a/arch/arc/dts/Makefile
+++ b/arch/arc/dts/Makefile
@@ -6,6 +6,7 @@ dtb-$(CONFIG_TARGET_NSIM) += nsim.dtb
dtb-$(CONFIG_TARGET_TB100) += abilis_tb100.dtb
dtb-$(CONFIG_TARGET_EMDK) += emdk.dtb
dtb-$(CONFIG_TARGET_HSDK) += hsdk.dtb
+dtb-$(CONFIG_TARGET_IOT_DEVKIT) += iot_devkit.dtb
targets += $(dtb-y)
diff --git a/arch/arc/dts/abilis_tb100.dts b/arch/arc/dts/abilis_tb100.dts
index de3e57d246..19e45b9c66 100644
--- a/arch/arc/dts/abilis_tb100.dts
+++ b/arch/arc/dts/abilis_tb100.dts
@@ -7,6 +7,8 @@
#include "skeleton.dtsi"
/ {
+ model = "abilis,tb100";
+
aliases {
console = &uart0;
};
diff --git a/arch/arc/dts/axs101.dts b/arch/arc/dts/axs101.dts
index 13873be320..fc9fa93b74 100644
--- a/arch/arc/dts/axs101.dts
+++ b/arch/arc/dts/axs101.dts
@@ -9,6 +9,8 @@
/ {
+ model = "snps,axs101";
+
chosen {
stdout-path = &uart0;
};
diff --git a/arch/arc/dts/axs103.dts b/arch/arc/dts/axs103.dts
index 81778c8983..6e2dd00fc3 100644
--- a/arch/arc/dts/axs103.dts
+++ b/arch/arc/dts/axs103.dts
@@ -9,6 +9,8 @@
/ {
+ model = "snps,axs103";
+
chosen {
stdout-path = &uart0;
};
diff --git a/arch/arc/dts/emdk.dts b/arch/arc/dts/emdk.dts
index 5e853e3a72..ebe538d06f 100644
--- a/arch/arc/dts/emdk.dts
+++ b/arch/arc/dts/emdk.dts
@@ -7,6 +7,8 @@
#include "skeleton.dtsi"
/ {
+ model = "snps,emdk";
+
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arc/dts/hsdk.dts b/arch/arc/dts/hsdk.dts
index 673bc5b26a..f024b96925 100644
--- a/arch/arc/dts/hsdk.dts
+++ b/arch/arc/dts/hsdk.dts
@@ -8,6 +8,8 @@
#include "dt-bindings/clock/snps,hsdk-cgu.h"
/ {
+ model = "snps,hsdk";
+
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arc/dts/iot_devkit.dts b/arch/arc/dts/iot_devkit.dts
new file mode 100644
index 0000000000..ebf5a950f0
--- /dev/null
+++ b/arch/arc/dts/iot_devkit.dts
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
+ */
+/dts-v1/;
+
+#include "skeleton.dtsi"
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ console = &uart0;
+ };
+
+ cpu_card {
+ core_clk: core_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <144000000>;
+ u-boot,dm-pre-reloc;
+ };
+ };
+
+ uart0: serial0@80014000 {
+ compatible = "snps,dw-apb-uart";
+ clock-frequency = <16000000>;
+ reg = <0x80014000 0x1000>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ usb: usb@f0040000 {
+ compatible = "snps,dwc2";
+ reg = <0xf0040000 0x10000>;
+ phys = <&usbphy>;
+ phy-names = "usb2-phy";
+ };
+
+ usbphy: phy {
+ compatible = "nop-phy";
+ #phy-cells = <0>;
+ };
+};
diff --git a/arch/arc/dts/nsim.dts b/arch/arc/dts/nsim.dts
index 9c1c7aa0eb..243ecb178e 100644
--- a/arch/arc/dts/nsim.dts
+++ b/arch/arc/dts/nsim.dts
@@ -7,6 +7,8 @@
#include "skeleton.dtsi"
/ {
+ model = "snps,nsim";
+
aliases {
console = &arcuart0;
};
diff --git a/arch/arc/lib/cpu.c b/arch/arc/lib/cpu.c
index cb95e06e93..50cd7cdb61 100644
--- a/arch/arc/lib/cpu.c
+++ b/arch/arc/lib/cpu.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
+ * Copyright (C) 2013-2014, 2018 Synopsys, Inc. All rights reserved.
*/
#include <common.h>
@@ -33,3 +33,36 @@ int dram_init(void)
{
return 0;
}
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+const char *decode_identity(void)
+{
+ int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff;
+
+ switch (arcver) {
+ /* ARCompact cores */
+ case 0x32: return "ARC 700 v4.4-4.5";
+ case 0x33: return "ARC 700 v4.6-v4.9";
+ case 0x34: return "ARC 700 v4.10";
+ case 0x35: return "ARC 700 v4.11";
+
+ /* ARCv2 cores */
+ case 0x41: return "ARC EM v1.1a";
+ case 0x42: return "ARC EM v3.0";
+ case 0x43: return "ARC EM v4.0";
+ case 0x50: return "ARC HS v1.0";
+ case 0x51: return "ARC EM v2.0";
+ case 0x52: return "ARC EM v2.1";
+ case 0x53: return "ARC HS v3.0";
+ case 0x54: return "ARC HS v4.0";
+
+ default: return "Unknown ARC core";
+ }
+}
+
+int print_cpuinfo(void)
+{
+ printf("CPU: %s\n", decode_identity());
+ return 0;
+}
+#endif /* CONFIG_DISPLAY_CPUINFO */
diff --git a/board/synopsys/iot_devkit/Kconfig b/board/synopsys/iot_devkit/Kconfig
new file mode 100644
index 0000000000..ad956b20f7
--- /dev/null
+++ b/board/synopsys/iot_devkit/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_IOT_DEVKIT
+
+config SYS_BOARD
+ default "iot_devkit"
+
+config SYS_VENDOR
+ default "synopsys"
+
+config SYS_CONFIG_NAME
+ default "iot_devkit"
+
+endif
diff --git a/board/synopsys/iot_devkit/MAINTAINERS b/board/synopsys/iot_devkit/MAINTAINERS
new file mode 100644
index 0000000000..06457cfa6a
--- /dev/null
+++ b/board/synopsys/iot_devkit/MAINTAINERS
@@ -0,0 +1,5 @@
+IOT DEVKIT BOARD
+M: Alexey Brodkin <abrodkin@synopsys.com>
+S: Maintained
+F: board/synopsys/iot_devkit/
+F: configs/iot_devkit_defconfig
diff --git a/board/synopsys/iot_devkit/Makefile b/board/synopsys/iot_devkit/Makefile
new file mode 100644
index 0000000000..1616024643
--- /dev/null
+++ b/board/synopsys/iot_devkit/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2018 Synopsys, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += iot_devkit.o
diff --git a/board/synopsys/iot_devkit/config.mk b/board/synopsys/iot_devkit/config.mk
new file mode 100644
index 0000000000..120733538a
--- /dev/null
+++ b/board/synopsys/iot_devkit/config.mk
@@ -0,0 +1,2 @@
+PLATFORM_CPPFLAGS += -mlittle-endian -mcode-density -mdiv-rem -mswap -mnorm -mmpy-option=6 -mbarrel-shifter
+LDSCRIPT = $(srctree)/board/synopsys/iot_devkit/u-boot.lds
diff --git a/board/synopsys/iot_devkit/iot_devkit.c b/board/synopsys/iot_devkit/iot_devkit.c
new file mode 100644
index 0000000000..c185d5cdb5
--- /dev/null
+++ b/board/synopsys/iot_devkit/iot_devkit.c
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <dwmmc.h>
+#include <linux/libfdt.h>
+#include <fdtdec.h>
+
+#include <asm/arcregs.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define SYSCON_BASE 0xf000a000
+#define AHBCKDIV (void *)(SYSCON_BASE + 0x04)
+#define APBCKDIV (void *)(SYSCON_BASE + 0x08)
+#define APBCKEN (void *)(SYSCON_BASE + 0x0C)
+#define CLKSEL (void *)(SYSCON_BASE + 0x24)
+#define CLKSTAT (void *)(SYSCON_BASE + 0x28)
+#define PLLCON (void *)(SYSCON_BASE + 0x2C)
+#define APBCKSEL (void *)(SYSCON_BASE + 0x30)
+#define AHBCKEN (void *)(SYSCON_BASE + 0x34)
+#define USBPHY_PLL (void *)(SYSCON_BASE + 0x78)
+#define USBCFG (void *)(SYSCON_BASE + 0x7c)
+
+#define PLL_MASK_0 0xffcfffff
+#define PLL_MASK_1 0xffcfff00
+#define PLL_MASK_2 0xfbcfff00
+
+#define CLKSEL_DEFAULT 0x5a690000
+
+static int set_cpu_freq(unsigned int clk)
+{
+ clk /= 1000000;
+
+ /* Set clk to ext Xtal (LSN value 0) */
+ writel(CLKSEL_DEFAULT, CLKSEL);
+
+ switch (clk) {
+ case 16:
+ /* Bypass mode */
+ return 0;
+
+ case 50:
+ writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
+ /* pll_off=1, M=25, N=1, OD=3, PLL_OUT_CLK=50M */
+ writel((readl(PLLCON) & PLL_MASK_1) | 0x300191, PLLCON);
+ /* pll_off=0, M=25, N=1, OD=3, PLL_OUT_CLK=50M */
+ writel((readl(PLLCON) & PLL_MASK_2) | 0x300191, PLLCON);
+ break;
+
+ case 72:
+ writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
+ /* pll_off=1, M=18, N=1, OD=2, PLL_OUT_CLK=72M */
+ writel((readl(PLLCON) & PLL_MASK_1) | 0x200121, PLLCON);
+ /* pll_off=0, M=18, N=1, OD=2, PLL_OUT_CLK=72M */
+ writel((readl(PLLCON) & PLL_MASK_2) | 0x200121, PLLCON);
+ break;
+
+ case 100:
+ writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
+ /* pll_off=1,M=25, N=1, OD=2, PLL_OUT_CLK=100M */
+ writel((readl(PLLCON) & PLL_MASK_1) | 0x200191, PLLCON);
+ /* pll_off=0,M=25, N=1, OD=2, PLL_OUT_CLK=100M */
+ writel((readl(PLLCON) & PLL_MASK_2) | 0x200191, PLLCON);
+ break;
+
+ case 144:
+ writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
+ /* pll_off=1, M=18, N=1, OD=1, PLL_OUT_CLK=144M */
+ writel((readl(PLLCON) & PLL_MASK_1) | 0x100121, PLLCON);
+ /* pll_off=0, M=18, N=1, OD=1, PLL_OUT_CLK=144M */
+ writel((readl(PLLCON) & PLL_MASK_2) | 0x100121, PLLCON);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ while (!(readl(CLKSTAT) & 0x4))
+ ;
+
+ /* Set clk from PLL on bus (LSN = 1) */
+ writel(CLKSEL_DEFAULT | BIT(0), CLKSEL);
+
+ return 0;
+}
+
+extern u8 __rom_end[];
+extern u8 __ram_start[];
+extern u8 __ram_end[];
+
+/*
+ * Use mach_cpu_init() for .data section copy as board_early_init_f() will be
+ * too late: initf_dm() will use a value of "av_" variable from not yet
+ * initialized (by copy) area.
+ */
+int mach_cpu_init(void)
+{
+ int offset, freq;
+
+ /* Don't relocate U-Boot */
+ gd->flags |= GD_FLG_SKIP_RELOC;
+
+ /* Copy data from ROM to RAM */
+ u8 *src = __rom_end;
+ u8 *dst = __ram_start;
+
+ while (dst < __ram_end)
+ *dst++ = *src++;
+
+ /* Enable debug uart */
+#define DEBUG_UART_BASE 0x80014000
+#define DEBUG_UART_DLF_OFFSET 0xc0
+ write_aux_reg(DEBUG_UART_BASE + DEBUG_UART_DLF_OFFSET, 1);
+
+ offset = fdt_path_offset(gd->fdt_blob, "/cpu_card/core_clk");
+ if (offset < 0)
+ return offset;
+
+ freq = fdtdec_get_int(gd->fdt_blob, offset, "clock-frequency", 0);
+ if (!freq)
+ return -EINVAL;
+
+ /* If CPU freq > 100 MHz, divide eFLASH clock by 2 */
+ if (freq > 100000000) {
+ u32 reg = readl(AHBCKDIV);
+
+ reg &= ~(0xF << 8);
+ reg |= 2 << 8;
+ writel(reg, AHBCKDIV);
+ }
+
+ return set_cpu_freq(freq);
+}
+
+#define ARC_PERIPHERAL_BASE 0xF0000000
+#define SDIO_BASE (ARC_PERIPHERAL_BASE + 0xB000)
+
+int board_mmc_init(bd_t *bis)
+{
+ struct dwmci_host *host = NULL;
+
+ host = malloc(sizeof(struct dwmci_host));
+ if (!host) {
+ printf("dwmci_host malloc fail!\n");
+ return -ENOMEM;
+ }
+
+ memset(host, 0, sizeof(struct dwmci_host));
+ host->name = "Synopsys Mobile storage";
+ host->ioaddr = (void *)SDIO_BASE;
+ host->buswidth = 4;
+ host->dev_index = 0;
+ host->bus_hz = 50000000;
+
+ add_dwmci(host, host->bus_hz / 2, 400000);
+
+ return 0;
+}
+
+int checkboard(void)
+{
+ puts("Board: Synopsys IoT Development Kit\n");
+ return 0;
+};
diff --git a/board/synopsys/iot_devkit/u-boot.lds b/board/synopsys/iot_devkit/u-boot.lds
new file mode 100644
index 0000000000..d083168705
--- /dev/null
+++ b/board/synopsys/iot_devkit/u-boot.lds
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+
+MEMORY {
+ ROM : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE
+ RAM : ORIGIN = RAM_DATA_BASE, LENGTH = RAM_DATA_SIZE
+}
+
+OUTPUT_FORMAT("elf32-littlearc", "elf32-littlearc", "elf32-littlearc")
+OUTPUT_ARCH(arc)
+ENTRY(_start)
+SECTIONS
+{
+ . = CONFIG_SYS_MONITOR_BASE;
+ __image_copy_start = .;
+ .ivt :
+ {
+ __ivt_start = .;
+ KEEP(*(.ivt));
+ __ivt_end = .;
+ } > ROM
+
+ . = ALIGN(1024);
+ .text : {
+ __text_start = .;
+ arch/arc/lib/start.o (.text*)
+ *(.text*)
+ __text_end = .;
+ } > ROM
+
+ . = ALIGN(4);
+ .rodata : {
+ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+ } > ROM
+
+ . = ALIGN(4);
+ .u_boot_list : {
+ KEEP(*(SORT(.u_boot_list*)));
+
+ /* Mark RAM's LMA */
+ . = ALIGN(4);
+ __rom_end = .;
+ } > ROM
+
+ .data : {
+ /* Mark RAM's VMA */
+ . = ALIGN(4);
+
+ /*
+ * Everything between __ram_start and __ram_start will be
+ * copied from ROM to RAM in board_early_init_f().
+ */
+ __ram_start = .;
+
+ *(.data*)
+
+ __ram_end = .;
+ } > RAM AT > ROM
+
+ .bss : {
+ . = ALIGN(1024);
+ __bss_start = .;
+ *(.bss*)
+ __bss_end = .;
+ } > RAM
+
+ /* Keep relocation-related symbols to make linker happy */
+ __rel_dyn_start = .;
+ __rel_dyn_end = .;
+ __image_copy_end = .;
+ __init_end = .;
+}
diff --git a/common/Kconfig b/common/Kconfig
index 41f27a1338..d7300c212f 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -573,7 +573,7 @@ config BOARD_LATE_INIT
config DISPLAY_CPUINFO
bool "Display information about the CPU during start up"
- default y if ARM || NIOS2 || X86 || XTENSA || M68K
+ default y if ARC|| ARM || NIOS2 || X86 || XTENSA || M68K
help
Display information about the CPU that U-Boot is running on
when U-Boot starts up. The function print_cpuinfo() is called
@@ -581,7 +581,7 @@ config DISPLAY_CPUINFO
config DISPLAY_BOARDINFO
bool "Display information about the board during early start up"
- default y if ARM || M68K || MIPS || PPC || SANDBOX || XTENSA
+ default y if ARC || ARM || M68K || MIPS || PPC || SANDBOX || XTENSA
help
Display information about the board that U-Boot is running on
when U-Boot starts up. The board function checkboard() is called
diff --git a/common/spl/spl_optee.S b/common/spl/spl_optee.S
index 86fc398546..8bd1949ddf 100644
--- a/common/spl/spl_optee.S
+++ b/common/spl/spl_optee.S
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2017 Rockchip Electronic Co.,Ltd
*/
diff --git a/configs/iot_devkit_defconfig b/configs/iot_devkit_defconfig
new file mode 100644
index 0000000000..1f0f9c3256
--- /dev/null
+++ b/configs/iot_devkit_defconfig
@@ -0,0 +1,38 @@
+CONFIG_ARC=y
+CONFIG_ISA_ARCV2=y
+CONFIG_CPU_ARCEM6=y
+CONFIG_SYS_ICACHE_OFF=y
+CONFIG_SYS_DCACHE_OFF=y
+CONFIG_TARGET_IOT_DEVKIT=y
+CONFIG_SYS_TEXT_BASE=0x20000000
+CONFIG_SYS_CLK_FREQ=16000000
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
+CONFIG_SYS_PROMPT="IoTDK# "
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_BOOTM is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_NET is not set
+CONFIG_CMD_FAT=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_EMBED=y
+CONFIG_DEFAULT_DEVICE_TREE="iot_devkit"
+CONFIG_ENV_IS_IN_FAT=y
+CONFIG_ENV_FAT_INTERFACE="mmc"
+CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
+CONFIG_DM=y
+CONFIG_MMC=y
+CONFIG_MMC_DW=y
+CONFIG_DM_SERIAL=y
+CONFIG_SYS_NS16550=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_DWC2_BUFFER_SIZE=16
+CONFIG_USB_STORAGE=y
+CONFIG_FS_FAT_MAX_CLUSTSIZE=4096
diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile
index a66edd9199..dd6bacae34 100644
--- a/drivers/mtd/nand/spi/Makefile
+++ b/drivers/mtd/nand/spi/Makefile
@@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
-spinand-objs := core.o macronix.o micron.o winbond.o
+spinand-objs := core.o gigadevice.o macronix.o micron.o winbond.o
obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 362d104846..cb8ffa3fa9 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -830,6 +830,7 @@ static const struct nand_ops spinand_ops = {
};
static const struct spinand_manufacturer *spinand_manufacturers[] = {
+ &gigadevice_spinand_manufacturer,
&macronix_spinand_manufacturer,
&micron_spinand_manufacturer,
&winbond_spinand_manufacturer,
diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
new file mode 100644
index 0000000000..0bade20808
--- /dev/null
+++ b/drivers/mtd/nand/spi/gigadevice.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Stefan Roese <sr@denx.de>
+ *
+ * Derived from drivers/mtd/nand/spi/micron.c
+ * Copyright (c) 2016-2017 Micron Technology, Inc.
+ */
+
+#ifndef __UBOOT__
+#include <linux/device.h>
+#include <linux/kernel.h>
+#endif
+#include <linux/mtd/spinand.h>
+
+#define SPINAND_MFR_GIGADEVICE 0xc8
+
+#define GIGADEVICE_STATUS_ECC_MASK GENMASK(5, 4)
+#define GIGADEVICE_STATUS_ECC_NO_BITFLIPS (0 << 4)
+#define GIGADEVICE_STATUS_ECC_1TO7_BITFLIPS (1 << 4)
+#define GIGADEVICE_STATUS_ECC_8_BITFLIPS (3 << 4)
+
+static SPINAND_OP_VARIANTS(read_cache_variants,
+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
+
+static SPINAND_OP_VARIANTS(write_cache_variants,
+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
+
+static SPINAND_OP_VARIANTS(update_cache_variants,
+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
+ SPINAND_PROG_LOAD(false, 0, NULL, 0));
+
+static int gd5f1gq4u_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section)
+ return -ERANGE;
+
+ region->offset = 64;
+ region->length = 64;
+
+ return 0;
+}
+
+static int gd5f1gq4u_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section)
+ return -ERANGE;
+
+ /* Reserve 2 bytes for the BBM. */
+ region->offset = 2;
+ region->length = 62;
+
+ return 0;
+}
+
+static const struct mtd_ooblayout_ops gd5f1gq4u_ooblayout = {
+ .ecc = gd5f1gq4u_ooblayout_ecc,
+ .free = gd5f1gq4u_ooblayout_free,
+};
+
+static int gd5f1gq4u_ecc_get_status(struct spinand_device *spinand,
+ u8 status)
+{
+ if (status)
+ debug("%s (%d): status=%02x\n", __func__, __LINE__, status);
+
+ switch (status & GIGADEVICE_STATUS_ECC_MASK) {
+ case STATUS_ECC_NO_BITFLIPS:
+ return 0;
+
+ case GIGADEVICE_STATUS_ECC_1TO7_BITFLIPS:
+ return 7;
+
+ case GIGADEVICE_STATUS_ECC_8_BITFLIPS:
+ return 8;
+
+ case STATUS_ECC_UNCOR_ERROR:
+ return -EBADMSG;
+
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static const struct spinand_info gigadevice_spinand_table[] = {
+ SPINAND_INFO("GD5F1GQ4UC", 0xd1,
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+ NAND_ECCREQ(8, 2048),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&gd5f1gq4u_ooblayout,
+ gd5f1gq4u_ecc_get_status)),
+};
+
+static int gigadevice_spinand_detect(struct spinand_device *spinand)
+{
+ u8 *id = spinand->id.data;
+ int ret;
+
+ /*
+ * Gigadevice SPI NAND read ID need a dummy byte,
+ * so the first byte in raw_id is dummy.
+ */
+ if (id[1] != SPINAND_MFR_GIGADEVICE)
+ return 0;
+
+ ret = spinand_match_and_init(spinand, gigadevice_spinand_table,
+ ARRAY_SIZE(gigadevice_spinand_table),
+ id[2]);
+ if (ret)
+ return ret;
+
+ return 1;
+}
+
+static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
+ .detect = gigadevice_spinand_detect,
+};
+
+const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
+ .id = SPINAND_MFR_GIGADEVICE,
+ .name = "GigaDevice",
+ .ops = &gigadevice_spinand_manuf_ops,
+};
diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
index 98485b1236..76d5a1d115 100644
--- a/drivers/mtd/spi/Kconfig
+++ b/drivers/mtd/spi/Kconfig
@@ -96,6 +96,12 @@ config SPI_FLASH_WINBOND
help
Add support for various Winbond SPI flash chips (W25xxx)
+config SPI_FLASH_XMC
+ bool "XMC SPI flash support"
+ help
+ Add support for various XMC (Wuhan Xinxin Semiconductor
+ Manufacturing Corp.) SPI flash chips (XM25xxx)
+
endif
config SPI_FLASH_USE_4K_SECTORS
diff --git a/drivers/mtd/spi/spi_flash_ids.c b/drivers/mtd/spi/spi_flash_ids.c
index e662e4b42e..ad0a0c8150 100644
--- a/drivers/mtd/spi/spi_flash_ids.c
+++ b/drivers/mtd/spi/spi_flash_ids.c
@@ -189,6 +189,10 @@ const struct spi_flash_info spi_flash_ids[] = {
{"w25q256fw", INFO(0xef6019, 0x0, 64 * 1024, 512, RD_FULL | WR_QPP | SECT_4K) },
{"w25q256jw", INFO(0xef7019, 0x0, 64 * 1024, 512, RD_FULL | WR_QPP | SECT_4K) },
#endif
+#ifdef CONFIG_SPI_FLASH_XMC /* Wuhan Xinxin Semiconductor Manufacturing Corp */
+ { "xm25qh64a", INFO(0x207017, 0x0, 64 * 1024, 128, SECT_4K | RD_DUAL | RD_QUAD) },
+ { "xm25qh128a", INFO(0x207018, 0x0, 64 * 1024, 256, SECT_4K | RD_DUAL | RD_QUAD) },
+#endif
{}, /* Empty entry to terminate the list */
/*
* Note:
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 196767a3f6..1df6876e9b 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -116,6 +116,14 @@ config ICH_SPI
access the SPI NOR flash on platforms embedding this Intel
ICH IP core.
+config MT7621_SPI
+ bool "MediaTek MT7621 SPI driver"
+ depends on ARCH_MT7620
+ help
+ Enable the MT7621 SPI driver. This driver can be used to access
+ the SPI NOR flash on platforms embedding this Ralink / MediaTek
+ SPI core, like MT7621/7628/7688.
+
config MVEBU_A3700_SPI
bool "Marvell Armada 3700 SPI driver"
select CLK_ARMADA_3720
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index ee99508766..7242ea7e40 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
obj-$(CONFIG_LPC32XX_SSP) += lpc32xx_ssp.o
obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o
obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
+obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o
obj-$(CONFIG_MVEBU_A3700_SPI) += mvebu_a3700_spi.o
obj-$(CONFIG_MXC_SPI) += mxc_spi.o
obj-$(CONFIG_MXS_SPI) += mxs_spi.o
diff --git a/drivers/spi/mt7621_spi.c b/drivers/spi/mt7621_spi.c
new file mode 100644
index 0000000000..107e58f657
--- /dev/null
+++ b/drivers/spi/mt7621_spi.c
@@ -0,0 +1,312 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Stefan Roese <sr@denx.de>
+ *
+ * Derived from the Linux driver version drivers/spi/spi-mt7621.c
+ * Copyright (C) 2011 Sergiy <piratfm@gmail.com>
+ * Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2014-2015 Felix Fietkau <nbd@nbd.name>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <spi.h>
+#include <wait_bit.h>
+#include <linux/io.h>
+
+#define SPI_MSG_SIZE_MAX 32 /* SPI message chunk size */
+/* Enough for SPI NAND page read / write with page size 2048 bytes */
+#define SPI_MSG_SIZE_OVERALL (2048 + 16)
+
+#define MT7621_SPI_TRANS 0x00
+#define MT7621_SPI_TRANS_START BIT(8)
+#define MT7621_SPI_TRANS_BUSY BIT(16)
+
+#define MT7621_SPI_OPCODE 0x04
+#define MT7621_SPI_DATA0 0x08
+#define MT7621_SPI_DATA4 0x18
+#define MT7621_SPI_MASTER 0x28
+#define MT7621_SPI_MOREBUF 0x2c
+#define MT7621_SPI_POLAR 0x38
+
+#define MT7621_LSB_FIRST BIT(3)
+#define MT7621_CPOL BIT(4)
+#define MT7621_CPHA BIT(5)
+
+#define MASTER_MORE_BUFMODE BIT(2)
+#define MASTER_RS_CLK_SEL GENMASK(27, 16)
+#define MASTER_RS_CLK_SEL_SHIFT 16
+#define MASTER_RS_SLAVE_SEL GENMASK(31, 29)
+
+struct mt7621_spi {
+ void __iomem *base;
+ unsigned int sys_freq;
+ u32 data[(SPI_MSG_SIZE_OVERALL / 4) + 1];
+ int tx_len;
+};
+
+static void mt7621_spi_reset(struct mt7621_spi *rs, int duplex)
+{
+ setbits_le32(rs->base + MT7621_SPI_MASTER,
+ MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE);
+}
+
+static void mt7621_spi_set_cs(struct mt7621_spi *rs, int cs, int enable)
+{
+ u32 val = 0;
+
+ debug("%s: cs#%d -> %s\n", __func__, cs, enable ? "enable" : "disable");
+ if (enable)
+ val = BIT(cs);
+ iowrite32(val, rs->base + MT7621_SPI_POLAR);
+}
+
+static int mt7621_spi_set_mode(struct udevice *bus, uint mode)
+{
+ struct mt7621_spi *rs = dev_get_priv(bus);
+ u32 reg;
+
+ debug("%s: mode=0x%08x\n", __func__, mode);
+ reg = ioread32(rs->base + MT7621_SPI_MASTER);
+
+ reg &= ~MT7621_LSB_FIRST;
+ if (mode & SPI_LSB_FIRST)
+ reg |= MT7621_LSB_FIRST;
+
+ reg &= ~(MT7621_CPHA | MT7621_CPOL);
+ switch (mode & (SPI_CPOL | SPI_CPHA)) {
+ case SPI_MODE_0:
+ break;
+ case SPI_MODE_1:
+ reg |= MT7621_CPHA;
+ break;
+ case SPI_MODE_2:
+ reg |= MT7621_CPOL;
+ break;
+ case SPI_MODE_3:
+ reg |= MT7621_CPOL | MT7621_CPHA;
+ break;
+ }
+ iowrite32(reg, rs->base + MT7621_SPI_MASTER);
+
+ return 0;
+}
+
+static int mt7621_spi_set_speed(struct udevice *bus, uint speed)
+{
+ struct mt7621_spi *rs = dev_get_priv(bus);
+ u32 rate;
+ u32 reg;
+
+ debug("%s: speed=%d\n", __func__, speed);
+ rate = DIV_ROUND_UP(rs->sys_freq, speed);
+ debug("rate:%u\n", rate);
+
+ if (rate > 4097)
+ return -EINVAL;
+
+ if (rate < 2)
+ rate = 2;
+
+ reg = ioread32(rs->base + MT7621_SPI_MASTER);
+ reg &= ~MASTER_RS_CLK_SEL;
+ reg |= (rate - 2) << MASTER_RS_CLK_SEL_SHIFT;
+ iowrite32(reg, rs->base + MT7621_SPI_MASTER);
+
+ return 0;
+}
+
+static inline int mt7621_spi_wait_till_ready(struct mt7621_spi *rs)
+{
+ int ret;
+
+ ret = wait_for_bit_le32(rs->base + MT7621_SPI_TRANS,
+ MT7621_SPI_TRANS_BUSY, 0, 10, 0);
+ if (ret)
+ pr_err("Timeout in %s!\n", __func__);
+
+ return ret;
+}
+
+static int mt7621_spi_xfer(struct udevice *dev, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ struct udevice *bus = dev->parent;
+ struct mt7621_spi *rs = dev_get_priv(bus);
+ const u8 *tx_buf = dout;
+ u8 *ptr = (u8 *)dout;
+ u8 *rx_buf = din;
+ int total_size = bitlen >> 3;
+ int chunk_size;
+ int rx_len = 0;
+ u32 data[(SPI_MSG_SIZE_MAX / 4) + 1] = { 0 };
+ u32 val;
+ int i;
+
+ debug("%s: dout=%p, din=%p, len=%x, flags=%lx\n", __func__, dout, din,
+ total_size, flags);
+
+ /*
+ * This driver only supports half-duplex, so complain and bail out
+ * upon full-duplex messages
+ */
+ if (dout && din) {
+ printf("Only half-duplex SPI transfer supported\n");
+ return -EIO;
+ }
+
+ if (dout) {
+ debug("TX-DATA: ");
+ for (i = 0; i < total_size; i++)
+ debug("%02x ", *ptr++);
+ debug("\n");
+ }
+
+ mt7621_spi_wait_till_ready(rs);
+
+ /*
+ * Set CS active upon start of SPI message. This message can
+ * be split upon multiple calls to this xfer function
+ */
+ if (flags & SPI_XFER_BEGIN)
+ mt7621_spi_set_cs(rs, spi_chip_select(dev), 1);
+
+ while (total_size > 0) {
+ /* Don't exceed the max xfer size */
+ chunk_size = min_t(int, total_size, SPI_MSG_SIZE_MAX);
+
+ /*
+ * We might have some TX data buffered from the last xfer
+ * message. Make sure, that this does not exceed the max
+ * xfer size
+ */
+ if (rs->tx_len > 4)
+ chunk_size -= rs->tx_len;
+ if (din)
+ rx_len = chunk_size;
+
+ if (tx_buf) {
+ /* Check if this message does not exceed the buffer */
+ if ((chunk_size + rs->tx_len) > SPI_MSG_SIZE_OVERALL) {
+ printf("TX message size too big (%d)\n",
+ chunk_size + rs->tx_len);
+ return -EMSGSIZE;
+ }
+
+ /*
+ * Write all TX data into internal buffer to collect
+ * all TX messages into one buffer (might be split into
+ * multiple calls to this function)
+ */
+ for (i = 0; i < chunk_size; i++, rs->tx_len++) {
+ rs->data[rs->tx_len / 4] |=
+ tx_buf[i] << (8 * (rs->tx_len & 3));
+ }
+ }
+
+ if (flags & SPI_XFER_END) {
+ /* Write TX data into controller */
+ if (rs->tx_len) {
+ rs->data[0] = swab32(rs->data[0]);
+ if (rs->tx_len < 4)
+ rs->data[0] >>= (4 - rs->tx_len) * 8;
+
+ for (i = 0; i < rs->tx_len; i += 4) {
+ iowrite32(rs->data[i / 4], rs->base +
+ MT7621_SPI_OPCODE + i);
+ }
+ }
+
+ /* Write length into controller */
+ val = (min_t(int, rs->tx_len, 4) * 8) << 24;
+ if (rs->tx_len > 4)
+ val |= (rs->tx_len - 4) * 8;
+ val |= (rx_len * 8) << 12;
+ iowrite32(val, rs->base + MT7621_SPI_MOREBUF);
+
+ /* Start the xfer */
+ setbits_le32(rs->base + MT7621_SPI_TRANS,
+ MT7621_SPI_TRANS_START);
+
+ /* Wait until xfer is finished on bus */
+ mt7621_spi_wait_till_ready(rs);
+
+ /* Reset TX length and TX buffer for next xfer */
+ rs->tx_len = 0;
+ memset(rs->data, 0, sizeof(rs->data));
+ }
+
+ for (i = 0; i < rx_len; i += 4)
+ data[i / 4] = ioread32(rs->base + MT7621_SPI_DATA0 + i);
+
+ if (rx_len) {
+ debug("RX-DATA: ");
+ for (i = 0; i < rx_len; i++) {
+ rx_buf[i] = data[i / 4] >> (8 * (i & 3));
+ debug("%02x ", rx_buf[i]);
+ }
+ debug("\n");
+ }
+
+ if (tx_buf)
+ tx_buf += chunk_size;
+ if (rx_buf)
+ rx_buf += chunk_size;
+ total_size -= chunk_size;
+ }
+
+ /* Wait until xfer is finished on bus and de-assert CS */
+ mt7621_spi_wait_till_ready(rs);
+ if (flags & SPI_XFER_END)
+ mt7621_spi_set_cs(rs, spi_chip_select(dev), 0);
+
+ return 0;
+}
+
+static int mt7621_spi_probe(struct udevice *dev)
+{
+ struct mt7621_spi *rs = dev_get_priv(dev);
+
+ rs->base = dev_remap_addr(dev);
+ if (!rs->base)
+ return -EINVAL;
+
+ /*
+ * Read input clock via DT for now. At some point this should be
+ * replaced by implementing a clock driver for this SoC and getting
+ * the SPI frequency via this clock driver.
+ */
+ rs->sys_freq = dev_read_u32_default(dev, "clock-frequency", 0);
+ if (!rs->sys_freq) {
+ printf("Please provide clock-frequency!\n");
+ return -EINVAL;
+ }
+
+ mt7621_spi_reset(rs, 0);
+
+ return 0;
+}
+
+static const struct dm_spi_ops mt7621_spi_ops = {
+ .set_mode = mt7621_spi_set_mode,
+ .set_speed = mt7621_spi_set_speed,
+ .xfer = mt7621_spi_xfer,
+ /*
+ * cs_info is not needed, since we require all chip selects to be
+ * in the device tree explicitly
+ */
+};
+
+static const struct udevice_id mt7621_spi_ids[] = {
+ { .compatible = "ralink,mt7621-spi" },
+ { }
+};
+
+U_BOOT_DRIVER(mt7621_spi) = {
+ .name = "mt7621_spi",
+ .id = UCLASS_SPI,
+ .of_match = mt7621_spi_ids,
+ .ops = &mt7621_spi_ops,
+ .priv_auto_alloc_size = sizeof(struct mt7621_spi),
+ .probe = mt7621_spi_probe,
+};
diff --git a/include/configs/iot_devkit.h b/include/configs/iot_devkit.h
new file mode 100644
index 0000000000..4ffe1141d9
--- /dev/null
+++ b/include/configs/iot_devkit.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
+ */
+
+#ifndef _CONFIG_IOT_DEVKIT_H_
+#define _CONFIG_IOT_DEVKIT_H_
+
+#include <linux/sizes.h>
+
+/*
+ * MEMORY MAP
+ *
+ * eFlash: 0x0000_0000 - 0x0008_0000 (512K)
+ * ICCM: 0x2000_0000 - 0x2004_0000 (256K)
+ * SRAM: 0x3000_0000 - 0x3002_0000 (128K)
+ * DCCM: 0x8000_0000 - 0x8002_0000 (128K)
+ * Note: only data goes here, as IFQ cannot fetch instructions from DCCM
+ *
+ *
+ * RAM PARTITIONING
+ *
+ * +-----------+----------+---------------------+-------------+
+ * | <-- Stack | .data | Malloc | Environment |
+ * +-----------+----------+---------------------+-------------+
+ * : : : :\___________/
+ * : : : : |
+ * : : : : CONFIG_ENV_SIZE
+ * : : \____________________/
+ * : : |
+ * : : CONFIG_SYS_MALLOC_LEN
+ * : :
+ * : Specified explicitly by CONFIG_SYS_INIT_SP_ADDR
+ * :
+ * Specified explicitly by CONFIG_SYS_SDRAM_BASE
+ *
+ * NOTES:
+ * - Stack starts from CONFIG_SYS_INIT_SP_ADDR and grows down,
+ * i.e. towards CONFIG_SYS_SDRAM_BASE but nothing stops it from crossing
+ * that CONFIG_SYS_SDRAM_BASE in which case data won't be really saved on
+ * stack any longer and values popped from stack will contain garbage
+ * leading to unexpected behavior, typically but not limited to:
+ * - "Returning" back to bogus caller function
+ * - Reading data from weird addresses
+ */
+
+#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
+
+#define SRAM_BASE 0x30000000
+#define SRAM_SIZE SZ_128K
+
+#define DCCM_BASE 0x80000000
+#define DCCM_SIZE SZ_128K
+
+#define CONFIG_SYS_SDRAM_BASE DCCM_BASE
+#define CONFIG_SYS_SDRAM_SIZE DCCM_SIZE
+
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_32K)
+
+#define CONFIG_SYS_MALLOC_LEN SZ_64K
+#define CONFIG_SYS_BOOTM_LEN SZ_128K
+#define CONFIG_SYS_LOAD_ADDR SRAM_BASE
+
+#define ROM_BASE CONFIG_SYS_MONITOR_BASE
+#define ROM_SIZE SZ_256K
+
+#define RAM_DATA_BASE CONFIG_SYS_INIT_SP_ADDR
+#define RAM_DATA_SIZE CONFIG_SYS_SDRAM_SIZE - \
+ (CONFIG_SYS_INIT_SP_ADDR - \
+ CONFIG_SYS_SDRAM_BASE) - \
+ CONFIG_SYS_MALLOC_LEN - \
+ CONFIG_ENV_SIZE
+
+/* Required by DW MMC driver */
+#define CONFIG_BOUNCE_BUFFER
+
+/*
+ * Environment
+ */
+#define CONFIG_ENV_SIZE SZ_4K
+#define CONFIG_BOOTFILE "app.bin"
+#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
+
+#endif /* _CONFIG_IOT_DEVKIT_H_ */
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 8c9c756179..be01e1e82e 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -201,6 +201,7 @@ struct spinand_manufacturer {
};
/* SPI NAND manufacturers */
+extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
extern const struct spinand_manufacturer macronix_spinand_manufacturer;
extern const struct spinand_manufacturer micron_spinand_manufacturer;
extern const struct spinand_manufacturer winbond_spinand_manufacturer;