Merge branch 'master' of git://git.denx.de/u-boot-sh
diff --git a/Makefile b/Makefile
index 73a080c..1d7d5f2 100644
--- a/Makefile
+++ b/Makefile
@@ -1074,7 +1074,10 @@
else
ifneq ($(CONFIG_SPL_FIT_GENERATOR),"")
U_BOOT_ITS := u-boot.its
-$(U_BOOT_ITS): FORCE
+ifeq ($(CONFIG_SPL_FIT_GENERATOR),"arch/arm/mach-rockchip/make_fit_atf.py")
+U_BOOT_ITS_DEPS += u-boot
+endif
+$(U_BOOT_ITS): $(U_BOOT_ITS_DEPS) FORCE
$(srctree)/$(CONFIG_SPL_FIT_GENERATOR) \
$(patsubst %,arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST))) > $@
endif
diff --git a/arch/Kconfig b/arch/Kconfig
index 9b4bcbf..c988c17 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -60,8 +60,20 @@
select SYS_BOOT_GET_KBD
config RISCV
- bool "riscv architecture"
+ bool "RISC-V architecture"
select SUPPORT_OF_CONTROL
+ select OF_CONTROL
+ select DM
+ imply DM_SERIAL
+ imply DM_ETH
+ imply DM_MMC
+ imply DM_SPI
+ imply DM_SPI_FLASH
+ imply BLK
+ imply CLK
+ imply MTD
+ imply TIMER
+ imply CMD_DM
config SANDBOX
bool "Sandbox"
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index d59aa3a..b24593e 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -157,6 +157,10 @@
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/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 169e5d7..d255c90 100644
--- a/arch/arc/config.mk
+++ b/arch/arc/config.mk
@@ -9,21 +9,15 @@
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 491a4f4..17e1405 100644
--- a/arch/arc/dts/Makefile
+++ b/arch/arc/dts/Makefile
@@ -6,6 +6,7 @@
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 de3e57d..19e45b9 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 13873be..fc9fa93 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 81778c8..6e2dd00 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 5e853e3..ebe538d 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 673bc5b..f024b96 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 0000000..ebf5a95
--- /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 9c1c7aa..243ecb1 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 cb95e06..50cd7cd 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 @@
{
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/arch/arm/dts/rk3188-radxarock-u-boot.dtsi b/arch/arm/dts/rk3188-radxarock-u-boot.dtsi
index 013535a..1bb5408 100644
--- a/arch/arm/dts/rk3188-radxarock-u-boot.dtsi
+++ b/arch/arm/dts/rk3188-radxarock-u-boot.dtsi
@@ -11,6 +11,21 @@
u-boot,dm-spl;
};
+&mmc0 {
+ fifo-mode;
+ max-frequency = <16000000>;
+};
+
+&mmc1 {
+ fifo-mode;
+ max-frequency = <16000000>;
+};
+
+&emmc {
+ fifo-mode;
+ max-frequency = <16000000>;
+};
+
&uart2 {
status = "okay";
u-boot,dm-spl;
diff --git a/arch/arm/dts/rk3188-radxarock.dts b/arch/arm/dts/rk3188-radxarock.dts
index ac931e1..6136712 100644
--- a/arch/arm/dts/rk3188-radxarock.dts
+++ b/arch/arm/dts/rk3188-radxarock.dts
@@ -104,6 +104,8 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio3 1 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_pwr>;
startup-delay-us = <100000>;
vin-supply = <&vcc_io>;
};
@@ -334,6 +336,12 @@
};
};
+ sd0 {
+ sdmmc_pwr: sdmmc-pwr {
+ rockchip,pins = <RK_GPIO3 1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
usb {
host_vbus_drv: host-vbus-drv {
rockchip,pins = <0 3 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/arch/arm/mach-rockchip/fit_spl_optee.its b/arch/arm/mach-rockchip/fit_spl_optee.its
new file mode 100644
index 0000000..9be4b3c
--- /dev/null
+++ b/arch/arm/mach-rockchip/fit_spl_optee.its
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017 Rockchip Electronic Co.,Ltd
+ *
+ * Simple U-boot fit source file containing U-Boot, dtb and optee
+ */
+
+/dts-v1/;
+
+/ {
+ description = "Simple image with OP-TEE support";
+ #address-cells = <1>;
+
+ images {
+ uboot@1 {
+ description = "U-Boot";
+ data = /incbin/("../../../u-boot-nodtb.bin");
+ type = "standalone";
+ os = "U-Boot";
+ arch = "arm";
+ compression = "none";
+ load = <0x61000000>;
+ };
+ optee@1 {
+ description = "OP-TEE";
+ data = /incbin/("../../../tee.bin");
+ type = "firmware";
+ arch = "arm";
+ os = "tee";
+ compression = "none";
+ load = <0x68400000>;
+ entry = <0x68400000>;
+ };
+ fdt@1 {
+ description = "dtb";
+ data = /incbin/("../../../u-boot.dtb");
+ type = "flat_dt";
+ compression = "none";
+ };
+ };
+
+ configurations {
+ default = "conf@1";
+ conf@1 {
+ description = "Rockchip armv7 with OP-TEE";
+ firmware = "optee@1";
+ loadables = "uboot@1";
+ fdt = "fdt@1";
+ };
+ };
+};
diff --git a/arch/arm/mach-rockchip/make_fit_atf.py b/arch/arm/mach-rockchip/make_fit_atf.py
index 6b3d920..d1faff1 100755
--- a/arch/arm/mach-rockchip/make_fit_atf.py
+++ b/arch/arm/mach-rockchip/make_fit_atf.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
"""
A script to generate FIT image source for rockchip boards
with ARM Trusted Firmware
@@ -34,7 +34,7 @@
#address-cells = <1>;
images {
- uboot@1 {
+ uboot {
description = "U-Boot (64-bit)";
data = /incbin/("u-boot-nodtb.bin");
type = "standalone";
@@ -43,6 +43,7 @@
compression = "none";
load = <0x%08x>;
};
+
"""
DT_IMAGES_NODE_END="""
@@ -53,23 +54,23 @@
};
"""
-def append_atf_node(file, atf_index, phy_addr):
+def append_atf_node(file, atf_index, phy_addr, elf_entry):
"""
Append ATF DT node to input FIT dts file.
"""
data = 'bl31_0x%08x.bin' % phy_addr
- print >> file, '\t\tatf@%d {' % atf_index
- print >> file, '\t\t\tdescription = \"ARM Trusted Firmware\";'
- print >> file, '\t\t\tdata = /incbin/("%s");' % data
- print >> file, '\t\t\ttype = "firmware";'
- print >> file, '\t\t\tarch = "arm64";'
- print >> file, '\t\t\tos = "arm-trusted-firmware";'
- print >> file, '\t\t\tcompression = "none";'
- print >> file, '\t\t\tload = <0x%08x>;' % phy_addr
+ file.write('\t\tatf_%d {\n' % atf_index)
+ file.write('\t\t\tdescription = \"ARM Trusted Firmware\";\n')
+ file.write('\t\t\tdata = /incbin/("%s");\n' % data)
+ file.write('\t\t\ttype = "firmware";\n')
+ file.write('\t\t\tarch = "arm64";\n')
+ file.write('\t\t\tos = "arm-trusted-firmware";\n')
+ file.write('\t\t\tcompression = "none";\n')
+ file.write('\t\t\tload = <0x%08x>;\n' % phy_addr)
if atf_index == 1:
- print >> file, '\t\t\tentry = <0x%08x>;' % phy_addr
- print >> file, '\t\t};'
- print >> file, ''
+ file.write('\t\t\tentry = <0x%08x>;\n' % elf_entry)
+ file.write('\t\t};\n')
+ file.write('\n')
def append_fdt_node(file, dtbs):
"""
@@ -78,43 +79,43 @@
cnt = 1
for dtb in dtbs:
dtname = os.path.basename(dtb)
- print >> file, '\t\tfdt@%d {' % cnt
- print >> file, '\t\t\tdescription = "%s";' % dtname
- print >> file, '\t\t\tdata = /incbin/("%s");' % dtb
- print >> file, '\t\t\ttype = "flat_dt";'
- print >> file, '\t\t\tcompression = "none";'
- print >> file, '\t\t};'
- print >> file, ''
+ file.write('\t\tfdt_%d {\n' % cnt)
+ file.write('\t\t\tdescription = "%s";\n' % dtname)
+ file.write('\t\t\tdata = /incbin/("%s");\n' % dtb)
+ file.write('\t\t\ttype = "flat_dt";\n')
+ file.write('\t\t\tcompression = "none";\n')
+ file.write('\t\t};\n')
+ file.write('\n')
cnt = cnt + 1
def append_conf_section(file, cnt, dtname, atf_cnt):
- print >> file, '\t\tconfig@%d {' % cnt
- print >> file, '\t\t\tdescription = "%s";' % dtname
- print >> file, '\t\t\tfirmware = "atf@1";'
- print >> file, '\t\t\tloadables = "uboot@1",',
+ file.write('\t\tconfig_%d {\n' % cnt)
+ file.write('\t\t\tdescription = "%s";\n' % dtname)
+ file.write('\t\t\tfirmware = "atf_1";\n')
+ file.write('\t\t\tloadables = "uboot",')
for i in range(1, atf_cnt):
- print >> file, '"atf@%d"' % (i+1),
+ file.write('"atf_%d"' % (i+1))
if i != (atf_cnt - 1):
- print >> file, ',',
+ file.write(',')
else:
- print >> file, ';'
- print >> file, '\t\t\tfdt = "fdt@1";'
- print >> file, '\t\t};'
- print >> file, ''
+ file.write(';\n')
+ file.write('\t\t\tfdt = "fdt_1";\n')
+ file.write('\t\t};\n')
+ file.write('\n')
def append_conf_node(file, dtbs, atf_cnt):
"""
Append configeration nodes.
"""
cnt = 1
- print >> file, '\tconfigurations {'
- print >> file, '\t\tdefault = "config@1";'
+ file.write('\tconfigurations {\n')
+ file.write('\t\tdefault = "config_1";\n')
for dtb in dtbs:
dtname = os.path.basename(dtb)
append_conf_section(file, cnt, dtname, atf_cnt)
cnt = cnt + 1
- print >> file, '\t};'
- print >> file, ''
+ file.write('\t};\n')
+ file.write('\n')
def generate_atf_fit_dts(fit_file_name, bl31_file_name, uboot_file_name, dtbs_file_name):
"""
@@ -127,7 +128,7 @@
num_load_seg = 0
p_paddr = 0xFFFFFFFF
- with open(uboot_file_name) as uboot_file:
+ with open(uboot_file_name, 'rb') as uboot_file:
uboot = ELFFile(uboot_file)
for i in range(uboot.num_segments()):
seg = uboot.get_segment(i)
@@ -137,27 +138,28 @@
assert (p_paddr != 0xFFFFFFFF and num_load_seg == 1)
- print >> fit_file, DT_HEADER % p_paddr
+ fit_file.write(DT_HEADER % p_paddr)
- with open(bl31_file_name) as bl31_file:
+ with open(bl31_file_name, 'rb') as bl31_file:
bl31 = ELFFile(bl31_file)
+ elf_entry = bl31.header['e_entry']
for i in range(bl31.num_segments()):
seg = bl31.get_segment(i)
if ('PT_LOAD' == seg.__getitem__(ELF_SEG_P_TYPE)):
paddr = seg.__getitem__(ELF_SEG_P_PADDR)
p= seg.__getitem__(ELF_SEG_P_PADDR)
- append_atf_node(fit_file, i+1, paddr)
+ append_atf_node(fit_file, i+1, paddr, elf_entry)
atf_cnt = i+1
append_fdt_node(fit_file, dtbs_file_name)
- print >> fit_file, '%s' % DT_IMAGES_NODE_END
+ fit_file.write('%s\n' % DT_IMAGES_NODE_END)
append_conf_node(fit_file, dtbs_file_name, atf_cnt)
- print >> fit_file, '%s' % DT_END
+ fit_file.write('%s\n' % DT_END)
if fit_file_name != sys.stdout:
fit_file.close()
def generate_atf_binary(bl31_file_name):
- with open(bl31_file_name) as bl31_file:
+ with open(bl31_file_name, 'rb') as bl31_file:
bl31 = ELFFile(bl31_file)
num = bl31.num_segments()
@@ -178,17 +180,17 @@
bl31 = ELFFile(bl31_file)
num = bl31.num_segments()
- print 'Number of Segments : %d' % bl31.num_segments()
+ print('Number of Segments : %d' % bl31.num_segments())
for i in range(num):
- print 'Segment %d' % i
+ print('Segment %d' % i)
seg = bl31.get_segment(i)
ptype = seg[ELF_SEG_P_TYPE]
poffset = seg[ELF_SEG_P_OFFSET]
pmemsz = seg[ELF_SEG_P_MEMSZ]
pfilesz = seg[ELF_SEG_P_FILESZ]
- print 'type: %s\nfilesz: %08x\nmemsz: %08x\noffset: %08x' % (ptype, pfilesz, pmemsz, poffset)
+ print('type: %s\nfilesz: %08x\nmemsz: %08x\noffset: %08x' % (ptype, pfilesz, pmemsz, poffset))
paddr = seg[ELF_SEG_P_PADDR]
- print 'paddr: %08x' % paddr
+ print('paddr: %08x' % paddr)
def main():
uboot_elf="./u-boot"
@@ -204,7 +206,7 @@
elif opt == "-b":
bl31_elf=val
elif opt == "-h":
- print __doc__
+ print(__doc__)
sys.exit(2)
dtbs = args
diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager_s10.h b/arch/arm/mach-socfpga/include/mach/reset_manager_s10.h
index 6182d5f..31b73ed 100644
--- a/arch/arm/mach-socfpga/include/mach/reset_manager_s10.h
+++ b/arch/arm/mach-socfpga/include/mach/reset_manager_s10.h
@@ -108,8 +108,6 @@
#define RSTMGR_GPIO1 RSTMGR_DEFINE(2, 25)
#define RSTMGR_SDR RSTMGR_DEFINE(3, 6)
-void socfpga_emac_manage_reset(const unsigned int of_reset_id, u32 state);
-
/* Create a human-readable reference to SoCFPGA reset. */
#define SOCFPGA_RESET(_name) RSTMGR_##_name
diff --git a/arch/arm/mach-socfpga/misc_s10.c b/arch/arm/mach-socfpga/misc_s10.c
index 918baac..e599362 100644
--- a/arch/arm/mach-socfpga/misc_s10.c
+++ b/arch/arm/mach-socfpga/misc_s10.c
@@ -36,7 +36,8 @@
if (!phymode)
return -EINVAL;
- if (!strcmp(phymode, "mii") || !strcmp(phymode, "gmii"))
+ if (!strcmp(phymode, "mii") || !strcmp(phymode, "gmii") ||
+ !strcmp(phymode, "sgmii"))
modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
else if (!strcmp(phymode, "rgmii"))
modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
@@ -58,7 +59,7 @@
struct fdtdec_phandle_args args;
const char *phy_mode;
u32 gmac_index;
- int nodes[2]; /* Max. 3 GMACs */
+ int nodes[3]; /* Max. 3 GMACs */
int ret, count;
int i, node;
diff --git a/arch/arm/mach-socfpga/reset_manager_s10.c b/arch/arm/mach-socfpga/reset_manager_s10.c
index 5cc8336..f176c38 100644
--- a/arch/arm/mach-socfpga/reset_manager_s10.c
+++ b/arch/arm/mach-socfpga/reset_manager_s10.c
@@ -93,41 +93,6 @@
}
}
-/* of_reset_id: emac reset id
- * state: 0 - disable reset, !0 - enable reset
- */
-void socfpga_emac_manage_reset(const unsigned int of_reset_id, u32 state)
-{
- u32 reset_emac;
- u32 reset_emacocp;
-
- /* hardcode this now */
- switch (of_reset_id) {
- case EMAC0_RESET:
- reset_emac = SOCFPGA_RESET(EMAC0);
- reset_emacocp = SOCFPGA_RESET(EMAC0_OCP);
- break;
- case EMAC1_RESET:
- reset_emac = SOCFPGA_RESET(EMAC1);
- reset_emacocp = SOCFPGA_RESET(EMAC1_OCP);
- break;
- case EMAC2_RESET:
- reset_emac = SOCFPGA_RESET(EMAC2);
- reset_emacocp = SOCFPGA_RESET(EMAC2_OCP);
- break;
- default:
- printf("GMAC: Invalid reset ID (%i)!\n", of_reset_id);
- hang();
- break;
- }
-
- /* Reset ECC OCP first */
- socfpga_per_reset(reset_emacocp, state);
-
- /* Release the EMAC controller from reset */
- socfpga_per_reset(reset_emac, state);
-}
-
/*
* Release peripherals from reset based on handoff
*/
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 20a43d8..168ca3d 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -1,4 +1,4 @@
-menu "RISCV architecture"
+menu "RISC-V architecture"
depends on RISCV
config SYS_ARCH
@@ -11,22 +11,26 @@
config TARGET_AX25_AE350
bool "Support ax25-ae350"
+config TARGET_QEMU_VIRT
+ bool "Support QEMU Virt Board"
+
endchoice
source "board/AndesTech/ax25-ae350/Kconfig"
+source "board/emulation/qemu-riscv/Kconfig"
choice
prompt "CPU selection"
default CPU_RISCV_32
config CPU_RISCV_32
- bool "RISCV 32 bit"
+ bool "RISC-V 32-bit"
select 32BIT
help
Choose this option to build an U-Boot for RISCV32 architecture.
config CPU_RISCV_64
- bool "RISCV 64 bit"
+ bool "RISC-V 64-bit"
select 64BIT
help
Choose this option to build an U-Boot for RISCV64 architecture.
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 084888a..8fb6a88 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -3,7 +3,8 @@
# Copyright (C) 2017 Andes Technology Corporation.
# Rick Chen, Andes Technology Corporation <rick@andestech.com>
-head-y := arch/riscv/cpu/$(CPU)/start.o
+head-y := arch/riscv/cpu/start.o
+libs-y += arch/riscv/cpu/
libs-y += arch/riscv/cpu/$(CPU)/
libs-y += arch/riscv/lib/
diff --git a/arch/riscv/config.mk b/arch/riscv/config.mk
index c0b3858..ed9eb0c 100644
--- a/arch/riscv/config.mk
+++ b/arch/riscv/config.mk
@@ -10,20 +10,20 @@
# Rick Chen, Andes Technology Corporation <rick@andestech.com>
#
-ifeq ($(CROSS_COMPILE),)
-CROSS_COMPILE := riscv32-unknown-linux-gnu-
-endif
-
32bit-emul := elf32lriscv
64bit-emul := elf64lriscv
ifdef CONFIG_32BIT
+PLATFORM_CPPFLAGS += -march=rv32ima -mabi=ilp32
PLATFORM_LDFLAGS += -m $(32bit-emul)
+CFLAGS_EFI += -march=rv32ima -mabi=ilp32
EFI_LDS := elf_riscv32_efi.lds
endif
ifdef CONFIG_64BIT
+PLATFORM_CPPFLAGS += -march=rv64ima -mabi=lp64
PLATFORM_LDFLAGS += -m $(64bit-emul)
+CFLAGS_EFI += -march=rv64ima -mabi=lp64
EFI_LDS := elf_riscv64_efi.lds
endif
@@ -31,8 +31,8 @@
-T $(srctree)/examples/standalone/riscv.lds
PLATFORM_CPPFLAGS += -ffixed-gp -fpic
-PLATFORM_RELFLAGS += -fno-common -gdwarf-2 -ffunction-sections
-LDFLAGS_u-boot += --gc-sections -static -pie
+PLATFORM_RELFLAGS += -fno-common -gdwarf-2 -ffunction-sections
+LDFLAGS_u-boot += --gc-sections -static -pie
EFI_CRT0 := crt0_riscv_efi.o
EFI_RELOC := reloc_riscv_efi.o
diff --git a/arch/riscv/cpu/Makefile b/arch/riscv/cpu/Makefile
new file mode 100644
index 0000000..2cc6757
--- /dev/null
+++ b/arch/riscv/cpu/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+
+extra-y = start.o
+
+obj-y += cpu.o
diff --git a/arch/riscv/cpu/ax25/Makefile b/arch/riscv/cpu/ax25/Makefile
index c3f164c..2ab0342 100644
--- a/arch/riscv/cpu/ax25/Makefile
+++ b/arch/riscv/cpu/ax25/Makefile
@@ -3,6 +3,4 @@
# Copyright (C) 2017 Andes Technology Corporation
# Rick Chen, Andes Technology Corporation <rick@andestech.com>
-extra-y = start.o
-
obj-y := cpu.o
diff --git a/arch/riscv/cpu/ax25/cpu.c b/arch/riscv/cpu/ax25/cpu.c
index ab05b57..fddcc15 100644
--- a/arch/riscv/cpu/ax25/cpu.c
+++ b/arch/riscv/cpu/ax25/cpu.c
@@ -6,9 +6,6 @@
/* CPU specific code */
#include <common.h>
-#include <command.h>
-#include <watchdog.h>
-#include <asm/cache.h>
/*
* cleanup_before_linux() is called just before we call linux
@@ -24,9 +21,3 @@
return 0;
}
-
-int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
- disable_interrupts();
- panic("ax25-ae350 wdt not support yet.\n");
-}
diff --git a/arch/riscv/cpu/ax25/u-boot.lds b/arch/riscv/cpu/ax25/u-boot.lds
deleted file mode 100644
index c50b964..0000000
--- a/arch/riscv/cpu/ax25/u-boot.lds
+++ /dev/null
@@ -1,90 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2017 Andes Technology Corporation
- * Rick Chen, Andes Technology Corporation <rick@andestech.com>
- */
-OUTPUT_ARCH("riscv")
-ENTRY(_start)
-
-SECTIONS
-{
- . = ALIGN(4);
- .text :
- {
- arch/riscv/cpu/ax25/start.o (.text)
- }
-
- /* This needs to come before *(.text*) */
- .efi_runtime : {
- __efi_runtime_start = .;
- *(.text.efi_runtime*)
- *(.rodata.efi_runtime*)
- *(.data.efi_runtime*)
- __efi_runtime_stop = .;
- }
-
- .text_rest :
- {
- *(.text*)
- }
-
- . = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
- . = ALIGN(4);
- .data : {
- __global_pointer$ = . + 0x800;
- *(.data*)
- }
- . = ALIGN(4);
-
- .got : {
- __got_start = .;
- *(.got.plt) *(.got)
- __got_end = .;
- }
-
- . = ALIGN(4);
-
- .u_boot_list : {
- KEEP(*(SORT(.u_boot_list*)));
- }
-
- . = ALIGN(4);
-
- .efi_runtime_rel : {
- __efi_runtime_rel_start = .;
- *(.rel*.efi_runtime)
- *(.rel*.efi_runtime.*)
- __efi_runtime_rel_stop = .;
- }
-
- . = ALIGN(4);
-
- /DISCARD/ : { *(.rela.plt*) }
- .rela.dyn : {
- __rel_dyn_start = .;
- *(.rela*)
- __rel_dyn_end = .;
- }
-
- . = ALIGN(4);
-
- .dynsym : {
- __dyn_sym_start = .;
- *(.dynsym)
- __dyn_sym_end = .;
- }
-
- . = ALIGN(4);
-
- _end = .;
-
- .bss : {
- __bss_start = .;
- *(.bss*)
- . = ALIGN(4);
- __bss_end = .;
- }
-
-}
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
new file mode 100644
index 0000000..ae57fb8
--- /dev/null
+++ b/arch/riscv/cpu/cpu.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <common.h>
+#include <asm/csr.h>
+
+enum {
+ ISA_INVALID = 0,
+ ISA_32BIT,
+ ISA_64BIT,
+ ISA_128BIT
+};
+
+static const char * const isa_bits[] = {
+ [ISA_INVALID] = NULL,
+ [ISA_32BIT] = "32",
+ [ISA_64BIT] = "64",
+ [ISA_128BIT] = "128"
+};
+
+static inline bool supports_extension(char ext)
+{
+ return csr_read(misa) & (1 << (ext - 'a'));
+}
+
+int print_cpuinfo(void)
+{
+ char name[32];
+ char *s = name;
+ int bit;
+
+ s += sprintf(name, "rv");
+ bit = csr_read(misa) >> (sizeof(long) * 8 - 2);
+ s += sprintf(s, isa_bits[bit]);
+
+ supports_extension('i') ? *s++ = 'i' : 'r';
+ supports_extension('m') ? *s++ = 'm' : 'i';
+ supports_extension('a') ? *s++ = 'a' : 's';
+ supports_extension('f') ? *s++ = 'f' : 'c';
+ supports_extension('d') ? *s++ = 'd' : '-';
+ supports_extension('c') ? *s++ = 'c' : 'v';
+ *s++ = '\0';
+
+ printf("CPU: %s\n", name);
+
+ return 0;
+}
diff --git a/arch/riscv/cpu/qemu/Makefile b/arch/riscv/cpu/qemu/Makefile
new file mode 100644
index 0000000..258e462
--- /dev/null
+++ b/arch/riscv/cpu/qemu/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+
+obj-y += dram.o
+obj-y += cpu.o
diff --git a/arch/riscv/cpu/qemu/cpu.c b/arch/riscv/cpu/qemu/cpu.c
new file mode 100644
index 0000000..6c7a327
--- /dev/null
+++ b/arch/riscv/cpu/qemu/cpu.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <common.h>
+
+/*
+ * cleanup_before_linux() is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * we disable interrupt and caches.
+ */
+int cleanup_before_linux(void)
+{
+ disable_interrupts();
+
+ /* turn off I/D-cache */
+
+ return 0;
+}
diff --git a/arch/riscv/cpu/qemu/dram.c b/arch/riscv/cpu/qemu/dram.c
new file mode 100644
index 0000000..84d87d2
--- /dev/null
+++ b/arch/riscv/cpu/qemu/dram.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+
+int dram_init(void)
+{
+ return fdtdec_setup_mem_size_base();
+}
+
+int dram_init_banksize(void)
+{
+ return fdtdec_setup_memory_banksize();
+}
diff --git a/arch/riscv/cpu/ax25/start.S b/arch/riscv/cpu/start.S
similarity index 100%
rename from arch/riscv/cpu/ax25/start.S
rename to arch/riscv/cpu/start.S
diff --git a/arch/riscv/cpu/u-boot.lds b/arch/riscv/cpu/u-boot.lds
new file mode 100644
index 0000000..11bc4a7
--- /dev/null
+++ b/arch/riscv/cpu/u-boot.lds
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2017 Andes Technology Corporation
+ * Rick Chen, Andes Technology Corporation <rick@andestech.com>
+ */
+
+OUTPUT_ARCH("riscv")
+ENTRY(_start)
+
+SECTIONS
+{
+ . = ALIGN(4);
+ .text : {
+ arch/riscv/cpu/start.o (.text)
+ }
+
+ /* This needs to come before *(.text*) */
+ .efi_runtime : {
+ __efi_runtime_start = .;
+ *(.text.efi_runtime*)
+ *(.rodata.efi_runtime*)
+ *(.data.efi_runtime*)
+ __efi_runtime_stop = .;
+ }
+
+ .text_rest : {
+ *(.text*)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+ . = ALIGN(4);
+ .data : {
+ __global_pointer$ = . + 0x800;
+ *(.data*)
+ }
+ . = ALIGN(4);
+
+ .got : {
+ __got_start = .;
+ *(.got.plt) *(.got)
+ __got_end = .;
+ }
+
+ . = ALIGN(4);
+
+ .u_boot_list : {
+ KEEP(*(SORT(.u_boot_list*)));
+ }
+
+ . = ALIGN(4);
+
+ .efi_runtime_rel : {
+ __efi_runtime_rel_start = .;
+ *(.rel*.efi_runtime)
+ *(.rel*.efi_runtime.*)
+ __efi_runtime_rel_stop = .;
+ }
+
+ . = ALIGN(4);
+
+ /DISCARD/ : { *(.rela.plt*) }
+ .rela.dyn : {
+ __rel_dyn_start = .;
+ *(.rela*)
+ __rel_dyn_end = .;
+ }
+
+ . = ALIGN(4);
+
+ .dynsym : {
+ __dyn_sym_start = .;
+ *(.dynsym)
+ __dyn_sym_end = .;
+ }
+
+ . = ALIGN(4);
+
+ _end = .;
+
+ .bss : {
+ __bss_start = .;
+ *(.bss*)
+ . = ALIGN(4);
+ __bss_end = .;
+ }
+}
diff --git a/arch/riscv/dts/ae350.dts b/arch/riscv/dts/ae350.dts
index 2927e41..4717ae8 100644
--- a/arch/riscv/dts/ae350.dts
+++ b/arch/riscv/dts/ae350.dts
@@ -1,144 +1,147 @@
/dts-v1/;
/ {
- #address-cells = <2>;
- #size-cells = <2>;
- compatible = "andestech,ax25";
- model = "andestech,ax25";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "andestech,ax25";
+ model = "andestech,ax25";
aliases {
uart0 = &serial0;
spi0 = &spi;
- } ;
+ };
chosen {
bootargs = "console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0xf0300000 debug loglevel=7";
stdout-path = "uart0:38400n8";
- };
+ };
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
- timebase-frequency = <10000000>;
- CPU0: cpu@0 {
- device_type = "cpu";
- reg = <0>;
- status = "okay";
- compatible = "riscv";
- riscv,isa = "rv64imafdc";
- mmu-type = "riscv,sv39";
- clock-frequency = <60000000>;
- CPU0_intc: interrupt-controller {
- #interrupt-cells = <1>;
- interrupt-controller;
- compatible = "riscv,cpu-intc";
- };
- };
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <10000000>;
+
+ CPU0: cpu@0 {
+ device_type = "cpu";
+ reg = <0>;
+ status = "okay";
+ compatible = "riscv";
+ riscv,isa = "rv64imafdc";
+ mmu-type = "riscv,sv39";
+ clock-frequency = <60000000>;
+
+ CPU0_intc: interrupt-controller {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "riscv,cpu-intc";
+ };
+ };
};
memory@0 {
device_type = "memory";
- reg = <0x0 0x00000000 0x0 0x40000000>;
+ reg = <0x0 0x00000000 0x0 0x40000000>;
};
- soc {
- #address-cells = <2>;
- #size-cells = <2>;
- compatible = "andestech,riscv-ae350-soc";
- ranges;
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "andestech,riscv-ae350-soc";
+ ranges;
};
- plmt0@e6000000 {
- compatible = "riscv,plmt0";
- interrupts-extended = <&CPU0_intc 7>;
- reg = <0x0 0xe6000000 0x0 0x100000>;
- };
-
- plic0: interrupt-controller@e4000000 {
- compatible = "riscv,plic0";
- #address-cells = <2>;
- #interrupt-cells = <2>;
- interrupt-controller;
- reg = <0x0 0xe4000000 0x0 0x2000000>;
- riscv,ndev=<31>;
- interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
+ plmt0@e6000000 {
+ compatible = "riscv,plmt0";
+ interrupts-extended = <&CPU0_intc 7>;
+ reg = <0x0 0xe6000000 0x0 0x100000>;
};
- plic1: interrupt-controller@e6400000 {
- compatible = "riscv,plic1";
- #address-cells = <2>;
- #interrupt-cells = <2>;
+ plic0: interrupt-controller@e4000000 {
+ compatible = "riscv,plic0";
+ #address-cells = <2>;
+ #interrupt-cells = <2>;
interrupt-controller;
- reg = <0x0 0xe6400000 0x0 0x400000>;
- riscv,ndev=<1>;
- interrupts-extended = <&CPU0_intc 3>;
- };
+ reg = <0x0 0xe4000000 0x0 0x2000000>;
+ riscv,ndev=<31>;
+ interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
+ };
- spiclk: virt_100mhz {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <100000000>;
- };
+ plic1: interrupt-controller@e6400000 {
+ compatible = "riscv,plic1";
+ #address-cells = <2>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ reg = <0x0 0xe6400000 0x0 0x400000>;
+ riscv,ndev=<1>;
+ interrupts-extended = <&CPU0_intc 3>;
+ };
- timer0: timer@f0400000 {
- compatible = "andestech,atcpit100";
- reg = <0x0 0xf0400000 0x0 0x1000>;
- clock-frequency = <40000000>;
- interrupts = <3 4>;
- interrupt-parent = <&plic0>;
+ spiclk: virt_100mhz {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <100000000>;
+ };
+
+ timer0: timer@f0400000 {
+ compatible = "andestech,atcpit100";
+ reg = <0x0 0xf0400000 0x0 0x1000>;
+ clock-frequency = <40000000>;
+ interrupts = <3 4>;
+ interrupt-parent = <&plic0>;
};
serial0: serial@f0300000 {
compatible = "andestech,uart16550", "ns16550a";
- reg = <0x0 0xf0300000 0x0 0x1000>;
- interrupts = <9 4>;
+ reg = <0x0 0xf0300000 0x0 0x1000>;
+ interrupts = <9 4>;
clock-frequency = <19660800>;
reg-shift = <2>;
reg-offset = <32>;
no-loopback-test = <1>;
- interrupt-parent = <&plic0>;
+ interrupt-parent = <&plic0>;
};
mac0: mac@e0100000 {
compatible = "andestech,atmac100";
- reg = <0x0 0xe0100000 0x0 0x1000>;
- interrupts = <19 4>;
- interrupt-parent = <&plic0>;
+ reg = <0x0 0xe0100000 0x0 0x1000>;
+ interrupts = <19 4>;
+ interrupt-parent = <&plic0>;
};
mmc0: mmc@f0e00000 {
- compatible = "andestech,atfsdc010";
+ compatible = "andestech,atfsdc010";
max-frequency = <100000000>;
- clock-freq-min-max = <400000 100000000>;
+ clock-freq-min-max = <400000 100000000>;
fifo-depth = <0x10>;
- reg = <0x0 0xf0e00000 0x0 0x1000>;
- interrupts = <18 4>;
+ reg = <0x0 0xf0e00000 0x0 0x1000>;
+ interrupts = <18 4>;
cap-sd-highspeed;
- interrupt-parent = <&plic0>;
+ interrupt-parent = <&plic0>;
};
- smc0: smc@e0400000 {
- compatible = "andestech,atfsmc020";
- reg = <0x0 0xe0400000 0x0 0x1000>;
- };
+ smc0: smc@e0400000 {
+ compatible = "andestech,atfsmc020";
+ reg = <0x0 0xe0400000 0x0 0x1000>;
+ };
- nor@0,0 {
- compatible = "cfi-flash";
- reg = <0x0 0x88000000 0x0 0x1000>;
- bank-width = <2>;
- device-width = <1>;
- };
+ nor@0,0 {
+ compatible = "cfi-flash";
+ reg = <0x0 0x88000000 0x0 0x1000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
spi: spi@f0b00000 {
compatible = "andestech,atcspi200";
- reg = <0x0 0xf0b00000 0x0 0x1000>;
+ reg = <0x0 0xf0b00000 0x0 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
num-cs = <1>;
clocks = <&spiclk>;
interrupts = <3 4>;
- interrupt-parent = <&plic0>;
- flash@0 {
+ interrupt-parent = <&plic0>;
+
+ flash@0 {
compatible = "spi-flash";
spi-max-frequency = <50000000>;
reg = <0>;
diff --git a/arch/riscv/include/asm/bootm.h b/arch/riscv/include/asm/bootm.h
deleted file mode 100644
index 6786345..0000000
--- a/arch/riscv/include/asm/bootm.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (c) 2013, Google Inc.
- *
- * Copyright (C) 2011
- * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
- */
-#ifndef NDS32_BOOTM_H
-#define NDS32_BOOTM_H
-
-#include <asm/setup.h>
-
-#endif
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
new file mode 100644
index 0000000..50fccea
--- /dev/null
+++ b/arch/riscv/include/asm/csr.h
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2015 Regents of the University of California
+ *
+ * Taken from Linux arch/riscv/include/asm/csr.h
+ */
+
+#ifndef _ASM_RISCV_CSR_H
+#define _ASM_RISCV_CSR_H
+
+/* Status register flags */
+#define SR_SIE _AC(0x00000002, UL) /* Supervisor Interrupt Enable */
+#define SR_SPIE _AC(0x00000020, UL) /* Previous Supervisor IE */
+#define SR_SPP _AC(0x00000100, UL) /* Previously Supervisor */
+#define SR_SUM _AC(0x00040000, UL) /* Supervisor access User Memory */
+
+#define SR_FS _AC(0x00006000, UL) /* Floating-point Status */
+#define SR_FS_OFF _AC(0x00000000, UL)
+#define SR_FS_INITIAL _AC(0x00002000, UL)
+#define SR_FS_CLEAN _AC(0x00004000, UL)
+#define SR_FS_DIRTY _AC(0x00006000, UL)
+
+#define SR_XS _AC(0x00018000, UL) /* Extension Status */
+#define SR_XS_OFF _AC(0x00000000, UL)
+#define SR_XS_INITIAL _AC(0x00008000, UL)
+#define SR_XS_CLEAN _AC(0x00010000, UL)
+#define SR_XS_DIRTY _AC(0x00018000, UL)
+
+#ifndef CONFIG_64BIT
+#define SR_SD _AC(0x80000000, UL) /* FS/XS dirty */
+#else
+#define SR_SD _AC(0x8000000000000000, UL) /* FS/XS dirty */
+#endif
+
+/* SATP flags */
+#if __riscv_xlen == 32
+#define SATP_PPN _AC(0x003FFFFF, UL)
+#define SATP_MODE_32 _AC(0x80000000, UL)
+#define SATP_MODE SATP_MODE_32
+#else
+#define SATP_PPN _AC(0x00000FFFFFFFFFFF, UL)
+#define SATP_MODE_39 _AC(0x8000000000000000, UL)
+#define SATP_MODE SATP_MODE_39
+#endif
+
+/* Interrupt Enable and Interrupt Pending flags */
+#define SIE_SSIE _AC(0x00000002, UL) /* Software Interrupt Enable */
+#define SIE_STIE _AC(0x00000020, UL) /* Timer Interrupt Enable */
+
+#define EXC_INST_MISALIGNED 0
+#define EXC_INST_ACCESS 1
+#define EXC_BREAKPOINT 3
+#define EXC_LOAD_ACCESS 5
+#define EXC_STORE_ACCESS 7
+#define EXC_SYSCALL 8
+#define EXC_INST_PAGE_FAULT 12
+#define EXC_LOAD_PAGE_FAULT 13
+#define EXC_STORE_PAGE_FAULT 15
+
+#ifndef __ASSEMBLY__
+
+#define csr_swap(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrrw %0, " #csr ", %1" \
+ : "=r" (__v) : "rK" (__v) \
+ : "memory"); \
+ __v; \
+})
+
+#define csr_read(csr) \
+({ \
+ register unsigned long __v; \
+ __asm__ __volatile__ ("csrr %0, " #csr \
+ : "=r" (__v) : \
+ : "memory"); \
+ __v; \
+})
+
+#define csr_write(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrw " #csr ", %0" \
+ : : "rK" (__v) \
+ : "memory"); \
+})
+
+#define csr_read_set(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrrs %0, " #csr ", %1" \
+ : "=r" (__v) : "rK" (__v) \
+ : "memory"); \
+ __v; \
+})
+
+#define csr_set(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrs " #csr ", %0" \
+ : : "rK" (__v) \
+ : "memory"); \
+})
+
+#define csr_read_clear(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrrc %0, " #csr ", %1" \
+ : "=r" (__v) : "rK" (__v) \
+ : "memory"); \
+ __v; \
+})
+
+#define csr_clear(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrc " #csr ", %0" \
+ : : "rK" (__v) \
+ : "memory"); \
+})
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_CSR_H */
diff --git a/arch/riscv/include/asm/encoding.h b/arch/riscv/include/asm/encoding.h
index f237a72..9ea50ce 100644
--- a/arch/riscv/include/asm/encoding.h
+++ b/arch/riscv/include/asm/encoding.h
@@ -128,6 +128,7 @@
((SUPERVISOR) ? PTE_SR(PTE) : PTE_UR(PTE)))
#ifdef __riscv
+
#ifdef CONFIG_64BIT
# define MSTATUS_SD MSTATUS64_SD
# define SSTATUS_SD SSTATUS64_SD
@@ -141,53 +142,10 @@
# define MCAUSE_INT MCAUSE32_INT
# define MCAUSE_CAUSE MCAUSE32_CAUSE
#endif
+
#define RISCV_PGSHIFT 12
#define RISCV_PGSIZE BIT(RISCV_PGSHIFT)
-#ifndef __ASSEMBLER__
+#endif /* __riscv */
-#ifdef __GNUC__
-
-#define read_csr(reg) ({ unsigned long __tmp; \
- asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
- __tmp; })
-
-#define write_csr(reg, _val) ({ \
-typeof(_val) (val) = (_val); \
-if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
- asm volatile ("csrw " #reg ", %0" :: "i"(val)); \
-else \
- asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
-
-#define swap_csr(reg, _val) ({ unsigned long __tmp; \
-typeof(_val) (val) = (_val); \
-if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
- asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \
-else \
- asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \
- __tmp; })
-
-#define set_csr(reg, _bit) ({ unsigned long __tmp; \
-typeof(_bit) (bit) = (_bit); \
-if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
- asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
-else \
- asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
- __tmp; })
-
-#define clear_csr(reg, _bit) ({ unsigned long __tmp; \
-typeof(_bit) (bit) = (_bit); \
-if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
- asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
-else \
- asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
- __tmp; })
-
-#define rdtime() read_csr(time)
-#define rdcycle() read_csr(cycle)
-#define rdinstret() read_csr(instret)
-
-#endif
-#endif
-#endif
-#endif
+#endif /* RISCV_CSR_ENCODING_H */
diff --git a/arch/riscv/include/asm/mach-types.h b/arch/riscv/include/asm/mach-types.h
deleted file mode 100644
index f219ced..0000000
--- a/arch/riscv/include/asm/mach-types.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2017 Andes Technology Corporation
- * Rick Chen, Andes Technology Corporation <rick@andestech.com>
- */
-
-#ifndef __ASM_RISCV_MACH_TYPE_H
-#define __ASM_RISCV_MACH_TYPE_H
-
-#ifndef __ASSEMBLY__
-/* The type of machine we're running on */
-extern unsigned int __machine_arch_type;
-#endif
-
-#define MACH_TYPE_AE350 1
-
-#ifdef CONFIG_ARCH_AE350
-# ifdef machine_arch_type
-# undef machine_arch_type
-# define machine_arch_type __machine_arch_type
-# else
-# define machine_arch_type MACH_TYPE_AE350
-# endif
-# define machine_is_ae350() (machine_arch_type == MACH_TYPE_AE350)
-#else
-# define machine_is_ae350() (1)
-#endif
-
-#endif /* __ASM_RISCV_MACH_TYPE_H */
diff --git a/arch/riscv/include/asm/setup.h b/arch/riscv/include/asm/setup.h
deleted file mode 100644
index ff8de16..0000000
--- a/arch/riscv/include/asm/setup.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * linux/arch/nds32/include/asm/setup.h
- *
- * Copyright (C) 1997-1999 Russell King
- * Copyright (C) 2008 Andes Technology Corporation
- * Copyright (C) 2013 Ken Kuo (ken_kuo@andestech.com)
- * Copyright (C) 2017 Rick Chen (rick@andestech.com)
- *
- * Structure passed to kernel to tell it about the
- * hardware it's running on. See Documentation/arm/Setup
- * for more info.
- */
-#ifndef __RISCV_SETUP_H
-#define __RISCV_SETUP_H
-
-#define COMMAND_LINE_SIZE 256
-
-/* The list ends with an ATAG_NONE node. */
-#define ATAG_NONE 0x00000000
-
-struct tag_header {
- u32 size;
- u32 tag;
-};
-
-/* The list must start with an ATAG_CORE node */
-#define ATAG_CORE 0x54410001
-
-struct tag_core {
- u32 flags; /* bit 0 = read-only */
- u32 pagesize;
- u32 rootdev;
-};
-
-/* it is allowed to have multiple ATAG_MEM nodes */
-#define ATAG_MEM 0x54410002
-
-struct tag_mem32 {
- u32 size;
- u32 start; /* physical start address */
-};
-
-/* VGA text type displays */
-#define ATAG_VIDEOTEXT 0x54410003
-
-struct tag_videotext {
- u8 x;
- u8 y;
- u16 video_page;
- u8 video_mode;
- u8 video_cols;
- u16 video_ega_bx;
- u8 video_lines;
- u8 video_isvga;
- u16 video_points;
-};
-
-/* describes how the ramdisk will be used in kernel */
-#define ATAG_RAMDISK 0x54410004
-
-struct tag_ramdisk {
- u32 flags; /* bit 0 = load, bit 1 = prompt */
- u32 size; /* decompressed ramdisk size in _kilo_ bytes */
- u32 start; /* starting block of floppy-based RAM disk image */
-};
-
-/*
- * this one accidentally used virtual addresses - as such,
- * it's deprecated.
- * describes where the compressed ramdisk image lives (virtual address)
- */
-#define ATAG_INITRD 0x54410005
-
-/* describes where the compressed ramdisk image lives (physical address) */
-#define ATAG_INITRD2 0x54420005
-
-struct tag_initrd {
- u32 start; /* physical start address */
- u32 size; /* size of compressed ramdisk image in bytes */
-};
-
-/* board serial number. "64 bits should be enough for everybody" */
-#define ATAG_SERIAL 0x54410006
-
-struct tag_serialnr {
- u32 low;
- u32 high;
-};
-
-/* board revision */
-#define ATAG_REVISION 0x54410007
-
-struct tag_revision {
- u32 rev;
-};
-
-/* initial values for vesafb-type framebuffers. see struct screen_info
- * in include/linux/tty.h
- */
-#define ATAG_VIDEOLFB 0x54410008
-
-struct tag_videolfb {
- u16 lfb_width;
- u16 lfb_height;
- u16 lfb_depth;
- u16 lfb_linelength;
- u32 lfb_base;
- u32 lfb_size;
- u8 red_size;
- u8 red_pos;
- u8 green_size;
- u8 green_pos;
- u8 blue_size;
- u8 blue_pos;
- u8 rsvd_size;
- u8 rsvd_pos;
-};
-
-/* command line: \0 terminated string */
-#define ATAG_CMDLINE 0x54410009
-
-struct tag_cmdline {
- char cmdline[COMMAND_LINE_SIZE];
-};
-
-struct tag {
- struct tag_header hdr;
- union {
- struct tag_core core;
- struct tag_mem32 mem;
- struct tag_videotext videotext;
- struct tag_ramdisk ramdisk;
- struct tag_initrd initrd;
- struct tag_serialnr serialnr;
- struct tag_revision revision;
- struct tag_videolfb videolfb;
- struct tag_cmdline cmdline;
- } u;
-};
-
-struct tagtable {
- u32 tag;
- int (*parse)(const struct tag *);
-};
-
-#define tag_member_present(_tag, member) \
- typeof(_tag) (tag) = (_tag); \
- ((unsigned long)(&((struct tag *)0L)->member + 1) \
- <= (tag)->hdr.size * 4)
-
-#define tag_next(_t) \
- typeof(_t) (t) = (_t); \
- ((struct tag *)((u32 *)(t) + (t)->hdr.size))
-#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
-
-#define for_each_tag(_t, base) \
- typeof(_t) (t) = (_t); \
- for (t = base; t->hdr.size; t = tag_next(t))
-
-#ifdef __KERNEL__
-
-#define __tag __used __attribute__((__section__(".taglist")))
-#define __tagtable(tag, fn) \
-static struct tagtable __tagtable_##fn __tag = { tag, fn }
-
-/*
- * Memory map description
- */
-#define NR_BANKS 8
-
-struct meminfo {
- int nr_banks;
- struct {
- unsigned long start;
- unsigned long size;
- int node;
- } bank[NR_BANKS];
-};
-
-/*
- * Early command line parameters.
- */
-struct early_params {
- const char *arg;
- void (*fn)(char **p);
-};
-
-#define __early_param(name, fn) \
-static struct early_params __early_##fn __used \
-__attribute__((__section__("__early_param"))) = { name, fn }
-
-#endif
-#endif
diff --git a/arch/riscv/include/asm/u-boot.h b/arch/riscv/include/asm/u-boot.h
index 9e5b32d..3186835 100644
--- a/arch/riscv/include/asm/u-boot.h
+++ b/arch/riscv/include/asm/u-boot.h
@@ -23,7 +23,6 @@
#include <environment.h>
typedef struct bd_info {
- unsigned long bi_arch_number; /* unique id for this board */
unsigned long bi_boot_params; /* where this board expects params */
unsigned long bi_memstart; /* start of DRAM memory */
unsigned long bi_memsize; /* size of DRAM memory in bytes */
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index cc562f9..b58db89 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -10,6 +10,7 @@
obj-$(CONFIG_CMD_GO) += boot.o
obj-y += cache.o
obj-y += interrupts.o
+obj-y += reset.o
obj-y += setjmp.o
# For building EFI apps
diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
index 2610a57..a7a9fb9 100644
--- a/arch/riscv/lib/bootm.c
+++ b/arch/riscv/lib/bootm.c
@@ -11,7 +11,7 @@
#include <image.h>
#include <u-boot/zlib.h>
#include <asm/byteorder.h>
-#include <asm/bootm.h>
+#include <asm/csr.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -26,10 +26,7 @@
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
{
- bd_t *bd = gd->bd;
- char *s;
- int machid = bd->bi_arch_number;
- void (*theKernel)(int arch, uint params);
+ void (*kernel)(ulong hart, void *dtb);
/*
* allow the PREP bootm subcommand, it is required for bootm to work
@@ -40,18 +37,12 @@
if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
return 1;
- theKernel = (void (*)(int, uint))images->ep;
-
- s = env_get("machid");
- if (s) {
- machid = simple_strtoul(s, NULL, 16);
- printf("Using machid 0x%x from environment\n", machid);
- }
+ kernel = (void (*)(ulong, void *))images->ep;
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
debug("## Transferring control to Linux (at address %08lx) ...\n",
- (ulong)theKernel);
+ (ulong)kernel);
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
#ifdef CONFIG_OF_LIBFDT
@@ -67,8 +58,9 @@
printf("\nStarting kernel ...\n\n");
cleanup_before_linux();
+
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
- theKernel(machid, (unsigned long)images->ft_addr);
+ kernel(csr_read(mhartid), images->ft_addr);
/* does not return */
diff --git a/arch/riscv/lib/reset.c b/arch/riscv/lib/reset.c
new file mode 100644
index 0000000..b8cecb3
--- /dev/null
+++ b/arch/riscv/lib/reset.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <common.h>
+#include <command.h>
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ printf("resetting ...\n");
+
+ printf("reset not supported yet\n");
+ hang();
+
+ return 0;
+}
diff --git a/board/AndesTech/ax25-ae350/ax25-ae350.c b/board/AndesTech/ax25-ae350/ax25-ae350.c
index fd5aaa1..5f4ca0f 100644
--- a/board/AndesTech/ax25-ae350/ax25-ae350.c
+++ b/board/AndesTech/ax25-ae350/ax25-ae350.c
@@ -4,7 +4,6 @@
* Rick Chen, Andes Technology Corporation <rick@andestech.com>
*/
-#include <asm/mach-types.h>
#include <common.h>
#if defined(CONFIG_FTMAC100) && !defined(CONFIG_DM_ETH)
#include <netdev.h>
@@ -21,7 +20,6 @@
int board_init(void)
{
- gd->bd->bi_arch_number = MACH_TYPE_AE350;
gd->bd->bi_boot_params = PHYS_SDRAM_0 + 0x400;
return 0;
diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig
new file mode 100644
index 0000000..af23363
--- /dev/null
+++ b/board/emulation/qemu-riscv/Kconfig
@@ -0,0 +1,22 @@
+if TARGET_QEMU_VIRT
+
+config SYS_BOARD
+ default "qemu-riscv"
+
+config SYS_VENDOR
+ default "emulation"
+
+config SYS_CPU
+ default "qemu"
+
+config SYS_CONFIG_NAME
+ default "qemu-riscv"
+
+config SYS_TEXT_BASE
+ default 0x80000000
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ imply SYS_NS16550
+
+endif
diff --git a/board/emulation/qemu-riscv/MAINTAINERS b/board/emulation/qemu-riscv/MAINTAINERS
new file mode 100644
index 0000000..3c6eb4f
--- /dev/null
+++ b/board/emulation/qemu-riscv/MAINTAINERS
@@ -0,0 +1,7 @@
+QEMU RISC-V 'VIRT' BOARD
+M: Bin Meng <bmeng.cn@gmail.com>
+S: Maintained
+F: board/emulation/qemu-riscv/
+F: include/configs/qemu-riscv.h
+F: configs/qemu-riscv32_defconfig
+F: configs/qemu-riscv64_defconfig
diff --git a/board/emulation/qemu-riscv/Makefile b/board/emulation/qemu-riscv/Makefile
new file mode 100644
index 0000000..3f29b90
--- /dev/null
+++ b/board/emulation/qemu-riscv/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+
+obj-y += qemu-riscv.o
diff --git a/board/emulation/qemu-riscv/qemu-riscv.c b/board/emulation/qemu-riscv/qemu-riscv.c
new file mode 100644
index 0000000..041e716
--- /dev/null
+++ b/board/emulation/qemu-riscv/qemu-riscv.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+
+#define MROM_FDT_ADDR 0x1020
+
+int board_init(void)
+{
+ return 0;
+}
+
+void *board_fdt_blob_setup(void)
+{
+ /*
+ * QEMU loads a generated DTB for us immediately
+ * after the reset vectors in the MROM
+ */
+ return (void *)MROM_FDT_ADDR;
+}
diff --git a/board/synopsys/iot_devkit/Kconfig b/board/synopsys/iot_devkit/Kconfig
new file mode 100644
index 0000000..ad956b2
--- /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 0000000..06457cf
--- /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 0000000..1616024
--- /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 0000000..1207335
--- /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 0000000..c185d5c
--- /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 0000000..d083168
--- /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/cmd/bdinfo.c b/cmd/bdinfo.c
index 397dd15..60b4387 100644
--- a/cmd/bdinfo.c
+++ b/cmd/bdinfo.c
@@ -424,9 +424,10 @@
{
bd_t *bd = gd->bd;
- print_num("arch_number", bd->bi_arch_number);
print_bi_boot_params(bd);
print_bi_dram(bd);
+ print_num("relocaddr", gd->relocaddr);
+ print_num("reloc off", gd->reloc_off);
print_eth_ip_addr();
print_baudrate();
diff --git a/common/Kconfig b/common/Kconfig
index 41f27a1..d7300c2 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -573,7 +573,7 @@
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_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/Kconfig b/common/spl/Kconfig
index 18dbc23..d056462 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -832,6 +832,13 @@
Enable access to the AM33xx RTC and select the external 32kHz clock
source.
+config SPL_OPTEE
+ bool "Support OP-TEE Trusted OS"
+ depends on ARM
+ help
+ OP-TEE is an open source Trusted OS which is loaded by SPL.
+ More detail at: https://github.com/OP-TEE/optee_os
+
config TPL
bool
depends on SUPPORT_TPL
diff --git a/common/spl/Makefile b/common/spl/Makefile
index 814081f..a130a5b 100644
--- a/common/spl/Makefile
+++ b/common/spl/Makefile
@@ -21,6 +21,7 @@
obj-$(CONFIG_$(SPL_TPL_)NET_SUPPORT) += spl_net.o
obj-$(CONFIG_$(SPL_TPL_)MMC_SUPPORT) += spl_mmc.o
obj-$(CONFIG_$(SPL_TPL_)ATF) += spl_atf.o
+obj-$(CONFIG_$(SPL_TPL_)OPTEE) += spl_optee.o
obj-$(CONFIG_$(SPL_TPL_)USB_SUPPORT) += spl_usb.o
obj-$(CONFIG_$(SPL_TPL_)FAT_SUPPORT) += spl_fat.o
obj-$(CONFIG_$(SPL_TPL_)EXT_SUPPORT) += spl_ext.o
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 038f2b0..292e659 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -536,6 +536,13 @@
spl_invoke_atf(&spl_image);
break;
#endif
+#if CONFIG_IS_ENABLED(OPTEE)
+ case IH_OS_TEE:
+ debug("Jumping to U-Boot via OP-TEE\n");
+ spl_optee_entry(NULL, NULL, spl_image.fdt_addr,
+ (void *)spl_image.entry_point);
+ break;
+#endif
#ifdef CONFIG_SPL_OS_BOOT
case IH_OS_LINUX:
debug("Jumping to Linux\n");
diff --git a/common/spl/spl_optee.S b/common/spl/spl_optee.S
new file mode 100644
index 0000000..8bd1949
--- /dev/null
+++ b/common/spl/spl_optee.S
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2017 Rockchip Electronic Co.,Ltd
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ENTRY(spl_optee_entry)
+ ldr lr, =CONFIG_SYS_TEXT_BASE
+ mov pc, r3
+ENDPROC(spl_optee_entry)
diff --git a/configs/ax25-ae350_defconfig b/configs/ax25-ae350_defconfig
index d64f078..614ef15 100644
--- a/configs/ax25-ae350_defconfig
+++ b/configs/ax25-ae350_defconfig
@@ -15,30 +15,20 @@
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTP_PREFER_SERVERIP=y
CONFIG_CMD_CACHE=y
-CONFIG_OF_CONTROL=y
CONFIG_OF_BOARD=y
CONFIG_DEFAULT_DEVICE_TREE="ae350"
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_NET_RANDOM_ETHADDR=y
-CONFIG_DM=y
-CONFIG_CLK=y
CONFIG_MMC=y
-CONFIG_DM_MMC=y
CONFIG_FTSDC010=y
CONFIG_FTSDC010_SDIO=y
-CONFIG_MTD=y
CONFIG_MTD_NOR_FLASH=y
CONFIG_CFI_FLASH=y
-CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_DM_ETH=y
CONFIG_FTMAC100=y
CONFIG_BAUDRATE=38400
-CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
CONFIG_SPI=y
-CONFIG_DM_SPI=y
CONFIG_ATCSPI200_SPI=y
-CONFIG_TIMER=y
CONFIG_ATCPIT100_TIMER=y
diff --git a/configs/iot_devkit_defconfig b/configs/iot_devkit_defconfig
new file mode 100644
index 0000000..1f0f9c3
--- /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/configs/qemu-riscv32_defconfig b/configs/qemu-riscv32_defconfig
new file mode 100644
index 0000000..ff1fb1f
--- /dev/null
+++ b/configs/qemu-riscv32_defconfig
@@ -0,0 +1,6 @@
+CONFIG_RISCV=y
+CONFIG_TARGET_QEMU_VIRT=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DISPLAY_BOARDINFO=y
+CONFIG_OF_BOARD=y
diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-riscv64_defconfig
new file mode 100644
index 0000000..d6c1a5d
--- /dev/null
+++ b/configs/qemu-riscv64_defconfig
@@ -0,0 +1,7 @@
+CONFIG_RISCV=y
+CONFIG_TARGET_QEMU_VIRT=y
+CONFIG_CPU_RISCV_64=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DISPLAY_BOARDINFO=y
+CONFIG_OF_BOARD=y
diff --git a/doc/README.qemu-riscv b/doc/README.qemu-riscv
new file mode 100644
index 0000000..e2e4804
--- /dev/null
+++ b/doc/README.qemu-riscv
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+
+U-Boot on QEMU's 'virt' machine on RISC-V
+=========================================
+
+QEMU for RISC-V supports a special 'virt' machine designed for emulation and
+virtualization purposes. This document describes how to run U-Boot under it.
+Both 32-bit 64-bit targets are supported.
+
+The QEMU virt machine models a generic RISC-V virtual machine with support for
+the VirtIO standard networking and block storage devices. It has CLINT, PLIC,
+16550A UART devices in addition to VirtIO and it also uses device-tree to pass
+configuration information to guest software. It implements RISC-V privileged
+architecture spec v1.10.
+
+Building U-Boot
+---------------
+Set the CROSS_COMPILE environment variable as usual, and run:
+
+- For 32-bit RISC-V:
+ make qemu-riscv32_defconfig
+ make
+
+- For 64-bit RISC-V:
+ make qemu-riscv64_defconfig
+ make
+
+Running U-Boot
+--------------
+The minimal QEMU command line to get U-Boot up and running is:
+
+- For 32-bit RISC-V:
+ qemu-system-riscv32 -nographic -machine virt -kernel u-boot
+
+- For 64-bit RISC-V:
+ qemu-system-riscv64 -nographic -machine virt -kernel u-boot
+
+The commands above create targets with 128MiB memory by default.
+A freely configurable amount of RAM can be created via the '-m'
+parameter. For example, '-m 2G' creates 2GiB memory for the target,
+and the memory node in the embedded DTB created by QEMU reflects
+the new setting.
+
+These have been tested in QEMU 3.0.0.
diff --git a/drivers/gpio/dwapb_gpio.c b/drivers/gpio/dwapb_gpio.c
index 0f6574d..68836a7 100644
--- a/drivers/gpio/dwapb_gpio.c
+++ b/drivers/gpio/dwapb_gpio.c
@@ -171,8 +171,7 @@
if (!fdtdec_get_bool(blob, node, "gpio-controller"))
continue;
- plat = NULL;
- plat = calloc(1, sizeof(*plat));
+ plat = devm_kcalloc(dev, 1, sizeof(*plat), GFP_KERNEL);
if (!plat)
return -ENOMEM;
@@ -181,23 +180,17 @@
plat->pins = fdtdec_get_int(blob, node, "snps,nr-gpios", 0);
plat->name = fdt_stringlist_get(blob, node, "bank-name", 0,
NULL);
- if (ret)
- goto err;
ret = device_bind(dev, dev->driver, plat->name,
plat, -1, &subdev);
if (ret)
- goto err;
+ return ret;
dev_set_of_offset(subdev, node);
bank++;
}
return 0;
-
-err:
- free(plat);
- return ret;
}
static int gpio_dwapb_remove(struct udevice *dev)
diff --git a/drivers/i2c/i2c-versatile.c b/drivers/i2c/i2c-versatile.c
new file mode 100644
index 0000000..f523844
--- /dev/null
+++ b/drivers/i2c/i2c-versatile.c
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2018 Arm Ltd.
+ * Author: Liviu Dudau <liviu.dudau@foss.arm.com>
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <i2c.h>
+#include <asm/io.h>
+#include <clk.h>
+#include <linux/io.h>
+
+#define I2C_CONTROL_REG 0x00
+#define I2C_SET_REG 0x00
+#define I2C_CLEAR_REG 0x04
+
+#define SCL BIT(0)
+#define SDA BIT(1)
+
+struct versatile_i2c_priv {
+ phys_addr_t base;
+ u32 delay;
+};
+
+static inline void versatile_sda_set(struct versatile_i2c_priv *priv, u8 state)
+{
+ writel(SDA, priv->base + (state ? I2C_SET_REG : I2C_CLEAR_REG));
+ udelay(priv->delay);
+}
+
+static inline int versatile_sda_get(struct versatile_i2c_priv *priv)
+{
+ int v = !!(readl(priv->base + I2C_CONTROL_REG) & SDA);
+
+ udelay(priv->delay);
+ return v;
+}
+
+static inline void versatile_scl_set(struct versatile_i2c_priv *priv, u8 state)
+{
+ writel(SCL, priv->base + (state ? I2C_SET_REG : I2C_CLEAR_REG));
+ udelay(priv->delay);
+}
+
+static inline int versatile_scl_get(struct versatile_i2c_priv *priv)
+{
+ int v = !!(readl(priv->base + I2C_CONTROL_REG) & SCL);
+
+ udelay(priv->delay);
+ return v;
+}
+
+/* start: SDA goes from high to low while SCL is high */
+static void versatile_i2c_start(struct versatile_i2c_priv *priv)
+{
+ udelay(priv->delay);
+ versatile_sda_set(priv, 1);
+ versatile_scl_set(priv, 1);
+ versatile_sda_set(priv, 0);
+}
+
+/* stop: SDA goes from low to high while SCL is high */
+static void versatile_i2c_stop(struct versatile_i2c_priv *priv)
+{
+ versatile_scl_set(priv, 0);
+ versatile_sda_set(priv, 0);
+ versatile_scl_set(priv, 1);
+ versatile_sda_set(priv, 1);
+}
+
+/* read a bit from the SDA line (data or ACK/NACK) */
+static u8 versatile_i2c_read_bit(struct versatile_i2c_priv *priv)
+{
+ versatile_scl_set(priv, 0);
+ versatile_sda_set(priv, 1);
+ versatile_scl_set(priv, 1);
+ udelay(priv->delay);
+ return (u8)versatile_sda_get(priv);
+}
+
+/* write a bit on the SDA line */
+static void versatile_i2c_write_bit(struct versatile_i2c_priv *priv, u8 bit)
+{
+ versatile_scl_set(priv, 0);
+ versatile_sda_set(priv, bit);
+ versatile_scl_set(priv, 1);
+ udelay(priv->delay);
+}
+
+/* send a reset sequence of 9 clocks with SDA high */
+static void versatile_i2c_reset_bus(struct versatile_i2c_priv *priv)
+{
+ int i;
+
+ for (i = 0; i < 9; i++)
+ versatile_i2c_write_bit(priv, 1);
+
+ versatile_i2c_stop(priv);
+}
+
+/* write byte without start/stop sequence */
+static int versatile_i2c_write_byte(struct versatile_i2c_priv *priv, u8 byte)
+{
+ u8 nak, i;
+
+ for (i = 0; i < 8; i++) {
+ versatile_i2c_write_bit(priv, byte & 0x80);
+ byte <<= 1;
+ }
+
+ /* read ACK */
+ nak = versatile_i2c_read_bit(priv);
+ versatile_scl_set(priv, 0);
+
+ return nak; /* not a nack is an ack */
+}
+
+static int versatile_i2c_read_byte(struct versatile_i2c_priv *priv,
+ u8 *byte, u8 ack)
+{
+ u8 i;
+
+ *byte = 0;
+ for (i = 0; i < 8; i++) {
+ *byte <<= 1;
+ *byte |= versatile_i2c_read_bit(priv);
+ }
+ /* write the nack */
+ versatile_i2c_write_bit(priv, ack);
+
+ return 0;
+}
+
+static int versatile_i2c_send_slave_addr(struct versatile_i2c_priv *priv,
+ struct i2c_msg *msg)
+{
+ u8 addr;
+ int ret;
+
+ if (msg->flags & I2C_M_TEN) {
+ /* 10-bit address, send extended address code first */
+ addr = 0xf0 | ((msg->addr >> 7) & 0x06);
+ ret = versatile_i2c_write_byte(priv, addr);
+ if (ret) {
+ versatile_i2c_stop(priv);
+ return -EIO;
+ }
+
+ /* remaining bits */
+ ret = versatile_i2c_write_byte(priv, msg->addr & 0xff);
+ if (ret) {
+ versatile_i2c_stop(priv);
+ return -EIO;
+ }
+ /* reads need to resend the addr */
+ if (msg->flags & I2C_M_RD) {
+ versatile_i2c_start(priv);
+ addr |= 1;
+ ret = versatile_i2c_write_byte(priv, addr);
+ if (ret) {
+ versatile_i2c_stop(priv);
+ return -EIO;
+ }
+ }
+ } else {
+ /* normal 7-bit address */
+ addr = msg->addr << 1;
+ if (msg->flags & I2C_M_RD)
+ addr |= 1;
+ ret = versatile_i2c_write_byte(priv, addr);
+ if (ret) {
+ versatile_i2c_stop(priv);
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
+static int versatile_i2c_message_xfer(struct versatile_i2c_priv *priv,
+ struct i2c_msg *msg)
+{
+ int i, ret;
+ u8 ack;
+
+ versatile_i2c_start(priv);
+ if (versatile_i2c_send_slave_addr(priv, msg))
+ return -EIO;
+
+ for (i = 0; i < msg->len; i++) {
+ if (msg->flags & I2C_M_RD) {
+ ack = (msg->len - i - 1) == 0 ? 1 : 0;
+ ret = versatile_i2c_read_byte(priv, &msg->buf[i], ack);
+ } else {
+ ret = versatile_i2c_write_byte(priv, msg->buf[i]);
+ }
+
+ if (ret)
+ break;
+ }
+
+ versatile_i2c_stop(priv);
+
+ return ret;
+}
+
+static int versatile_i2c_xfer(struct udevice *bus,
+ struct i2c_msg *msg, int nmsgs)
+{
+ struct versatile_i2c_priv *priv = dev_get_priv(bus);
+ int ret;
+
+ for ( ; nmsgs > 0; nmsgs--, msg++) {
+ ret = versatile_i2c_message_xfer(priv, msg);
+ if (ret)
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+static int versatile_i2c_chip_probe(struct udevice *bus,
+ uint chip, uint chip_flags)
+{
+ /* probe the presence of a slave by writing a 0-size message */
+ struct i2c_msg msg = { .addr = chip, .flags = chip_flags,
+ .len = 0, .buf = NULL };
+ struct versatile_i2c_priv *priv = dev_get_priv(bus);
+
+ return versatile_i2c_message_xfer(priv, &msg);
+}
+
+static int versatile_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
+{
+ struct versatile_i2c_priv *priv = dev_get_priv(bus);
+
+ priv->delay = 1000000 / (speed << 2);
+
+ versatile_i2c_reset_bus(priv);
+
+ return 0;
+}
+
+static int versatile_i2c_probe(struct udevice *dev)
+{
+ struct versatile_i2c_priv *priv = dev_get_priv(dev);
+
+ priv->base = (phys_addr_t)dev_read_addr(dev);
+ priv->delay = 25; /* 25us * 4 = 100kHz */
+ /*
+ * U-Boot still doesn't assign automatically
+ * sequence numbers to devices
+ */
+ dev->req_seq = 1;
+
+ return 0;
+}
+
+static const struct dm_i2c_ops versatile_i2c_ops = {
+ .xfer = versatile_i2c_xfer,
+ .probe_chip = versatile_i2c_chip_probe,
+ .set_bus_speed = versatile_i2c_set_bus_speed,
+};
+
+static const struct udevice_id versatile_i2c_of_match[] = {
+ { .compatible = "arm,versatile-i2c" },
+ { }
+};
+
+U_BOOT_DRIVER(versatile_i2c) = {
+ .name = "i2c-bus-versatile",
+ .id = UCLASS_I2C,
+ .of_match = versatile_i2c_of_match,
+ .probe = versatile_i2c_probe,
+ .priv_auto_alloc_size = sizeof(struct versatile_i2c_priv),
+ .ops = &versatile_i2c_ops,
+};
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 13180fc..3c702b3 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -92,6 +92,24 @@
dwmci_writel(host, DWMCI_BYTCNT, data->blocksize * data->blocks);
}
+static int dwmci_fifo_ready(struct dwmci_host *host, u32 bit, u32 *len)
+{
+ u32 timeout = 20000;
+
+ *len = dwmci_readl(host, DWMCI_STATUS);
+ while (--timeout && (*len & bit)) {
+ udelay(200);
+ *len = dwmci_readl(host, DWMCI_STATUS);
+ }
+
+ if (!timeout) {
+ debug("%s: FIFO underflow timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
{
int ret = 0;
@@ -122,7 +140,12 @@
if (data->flags == MMC_DATA_READ &&
(mask & DWMCI_INTMSK_RXDR)) {
while (size) {
- len = dwmci_readl(host, DWMCI_STATUS);
+ ret = dwmci_fifo_ready(host,
+ DWMCI_FIFO_EMPTY,
+ &len);
+ if (ret < 0)
+ break;
+
len = (len >> DWMCI_FIFO_SHIFT) &
DWMCI_FIFO_MASK;
len = min(size, len);
@@ -136,7 +159,12 @@
} else if (data->flags == MMC_DATA_WRITE &&
(mask & DWMCI_INTMSK_TXDR)) {
while (size) {
- len = dwmci_readl(host, DWMCI_STATUS);
+ ret = dwmci_fifo_ready(host,
+ DWMCI_FIFO_FULL,
+ &len);
+ if (ret < 0)
+ break;
+
len = fifo_depth - ((len >>
DWMCI_FIFO_SHIFT) &
DWMCI_FIFO_MASK);
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c
index f54d95a..bf2d83a 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -156,6 +156,7 @@
}
static const struct udevice_id rockchip_dwmmc_ids[] = {
+ { .compatible = "rockchip,rk2928-dw-mshc" },
{ .compatible = "rockchip,rk3288-dw-mshc" },
{ }
};
diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile
index a66edd9..dd6baca 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 362d104..cb8ffa3 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -830,6 +830,7 @@
};
static const struct spinand_manufacturer *spinand_manufacturers[] = {
+ &gigadevice_spinand_manufacturer,
¯onix_spinand_manufacturer,
µn_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 0000000..0bade20
--- /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 98485b1..76d5a1d1 100644
--- a/drivers/mtd/spi/Kconfig
+++ b/drivers/mtd/spi/Kconfig
@@ -96,6 +96,12 @@
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 e662e4b..ad0a0c8 100644
--- a/drivers/mtd/spi/spi_flash_ids.c
+++ b/drivers/mtd/spi/spi_flash_ids.c
@@ -189,6 +189,10 @@
{"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/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c
index 30a24d1..c01ae75 100644
--- a/drivers/net/gmac_rockchip.c
+++ b/drivers/net/gmac_rockchip.c
@@ -24,6 +24,11 @@
#include <dt-bindings/clock/rk3288-cru.h>
#include "designware.h"
+DECLARE_GLOBAL_DATA_PTR;
+#define DELAY_ENABLE(soc, tx, rx) \
+ (((tx) ? soc##_TXCLK_DLY_ENA_GMAC_ENABLE : soc##_TXCLK_DLY_ENA_GMAC_DISABLE) | \
+ ((rx) ? soc##_RXCLK_DLY_ENA_GMAC_ENABLE : soc##_RXCLK_DLY_ENA_GMAC_DISABLE))
+
/*
* Platform data for the gmac
*
@@ -286,8 +291,7 @@
RK3228_RXCLK_DLY_ENA_GMAC_MASK |
RK3228_TXCLK_DLY_ENA_GMAC_MASK,
RK3228_GMAC_PHY_INTF_SEL_RGMII |
- RK3228_RXCLK_DLY_ENA_GMAC_ENABLE |
- RK3228_TXCLK_DLY_ENA_GMAC_ENABLE);
+ DELAY_ENABLE(RK3228, pdata->tx_delay, pdata->rx_delay));
rk_clrsetreg(&grf->mac_con[0],
RK3228_CLK_RX_DL_CFG_GMAC_MASK |
@@ -310,8 +314,7 @@
RK3288_TXCLK_DLY_ENA_GMAC_MASK |
RK3288_CLK_RX_DL_CFG_GMAC_MASK |
RK3288_CLK_TX_DL_CFG_GMAC_MASK,
- RK3288_RXCLK_DLY_ENA_GMAC_ENABLE |
- RK3288_TXCLK_DLY_ENA_GMAC_ENABLE |
+ DELAY_ENABLE(RK3288, pdata->rx_delay, pdata->tx_delay) |
pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT |
pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT);
}
@@ -350,8 +353,7 @@
RK3328_RXCLK_DLY_ENA_GMAC_MASK |
RK3328_TXCLK_DLY_ENA_GMAC_MASK,
RK3328_GMAC_PHY_INTF_SEL_RGMII |
- RK3328_RXCLK_DLY_ENA_GMAC_MASK |
- RK3328_TXCLK_DLY_ENA_GMAC_ENABLE);
+ DELAY_ENABLE(RK3328, pdata->tx_delay, pdata->rx_delay));
rk_clrsetreg(&grf->mac_con[0],
RK3328_CLK_RX_DL_CFG_GMAC_MASK |
@@ -392,8 +394,7 @@
RK3368_TXCLK_DLY_ENA_GMAC_MASK |
RK3368_CLK_RX_DL_CFG_GMAC_MASK |
RK3368_CLK_TX_DL_CFG_GMAC_MASK,
- RK3368_RXCLK_DLY_ENA_GMAC_ENABLE |
- RK3368_TXCLK_DLY_ENA_GMAC_ENABLE |
+ DELAY_ENABLE(RK3368, pdata->tx_delay, pdata->rx_delay) |
pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT |
pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT);
}
@@ -413,8 +414,7 @@
RK3399_TXCLK_DLY_ENA_GMAC_MASK |
RK3399_CLK_RX_DL_CFG_GMAC_MASK |
RK3399_CLK_TX_DL_CFG_GMAC_MASK,
- RK3399_RXCLK_DLY_ENA_GMAC_ENABLE |
- RK3399_TXCLK_DLY_ENA_GMAC_ENABLE |
+ DELAY_ENABLE(RK3399, pdata->tx_delay, pdata->rx_delay) |
pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT |
pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT);
}
@@ -451,40 +451,86 @@
switch (eth_pdata->phy_interface) {
case PHY_INTERFACE_MODE_RGMII:
- /*
- * If the gmac clock is from internal pll, need to set and
- * check the return value for gmac clock at RGMII mode. If
- * the gmac clock is from external source, the clock rate
- * is not set, because of it is bypassed.
- */
- if (!pdata->clock_input) {
- rate = clk_set_rate(&clk, 125000000);
- if (rate != 125000000)
- return -EINVAL;
- }
-
/* Set to RGMII mode */
if (ops->set_to_rgmii)
ops->set_to_rgmii(pdata);
else
return -EPERM;
- break;
- case PHY_INTERFACE_MODE_RMII:
- /* The commet is the same as RGMII mode */
+ /*
+ * If the gmac clock is from internal pll, need to set and
+ * check the return value for gmac clock at RGMII mode. If
+ * the gmac clock is from external source, the clock rate
+ * is not set, because of it is bypassed.
+ */
+
if (!pdata->clock_input) {
- rate = clk_set_rate(&clk, 50000000);
- if (rate != 50000000)
+ rate = clk_set_rate(&clk, 125000000);
+ if (rate != 125000000)
return -EINVAL;
}
+ break;
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ /* Set to RGMII mode */
+ if (ops->set_to_rgmii) {
+ pdata->tx_delay = 0;
+ pdata->rx_delay = 0;
+ ops->set_to_rgmii(pdata);
+ } else
+ return -EPERM;
+
+ if (!pdata->clock_input) {
+ rate = clk_set_rate(&clk, 125000000);
+ if (rate != 125000000)
+ return -EINVAL;
+ }
+ break;
+
+ case PHY_INTERFACE_MODE_RMII:
/* Set to RMII mode */
if (ops->set_to_rmii)
ops->set_to_rmii(pdata);
else
return -EPERM;
+ if (!pdata->clock_input) {
+ rate = clk_set_rate(&clk, 50000000);
+ if (rate != 50000000)
+ return -EINVAL;
+ }
break;
+
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ /* Set to RGMII_RXID mode */
+ if (ops->set_to_rgmii) {
+ pdata->tx_delay = 0;
+ ops->set_to_rgmii(pdata);
+ } else
+ return -EPERM;
+
+ if (!pdata->clock_input) {
+ rate = clk_set_rate(&clk, 125000000);
+ if (rate != 125000000)
+ return -EINVAL;
+ }
+ break;
+
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ /* Set to RGMII_TXID mode */
+ if (ops->set_to_rgmii) {
+ pdata->rx_delay = 0;
+ ops->set_to_rgmii(pdata);
+ } else
+ return -EPERM;
+
+ if (!pdata->clock_input) {
+ rate = clk_set_rate(&clk, 125000000);
+ if (rate != 125000000)
+ return -EINVAL;
+ }
+ break;
+
default:
debug("NO interface defined!\n");
return -ENXIO;
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 196767a..1df6876 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -116,6 +116,14 @@
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 ee99508..7242ea7 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -33,6 +33,7 @@
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 0000000..107e58f
--- /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 0000000..4ffe114
--- /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/configs/qemu-riscv.h b/include/configs/qemu-riscv.h
new file mode 100644
index 0000000..d279c23
--- /dev/null
+++ b/include/configs/qemu-riscv.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <linux/sizes.h>
+
+#define CONFIG_SYS_SDRAM_BASE 0x80000000
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M)
+
+#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M)
+
+#define CONFIG_SYS_MALLOC_LEN SZ_8M
+
+/* Environment options */
+#define CONFIG_ENV_SIZE SZ_4K
+
+#endif /* __CONFIG_H */
diff --git a/include/dwmmc.h b/include/dwmmc.h
index bc1d6e3..0f9d51b 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -103,6 +103,8 @@
#define DWMCI_CTYPE_8BIT (1 << 16)
/* Status Register */
+#define DWMCI_FIFO_EMPTY (1 << 2)
+#define DWMCI_FIFO_FULL (1 << 3)
#define DWMCI_BUSY (1 << 9)
#define DWMCI_FIFO_MASK 0x1fff
#define DWMCI_FIFO_SHIFT 17
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 8c9c756..be01e1e 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -201,6 +201,7 @@
};
/* 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;
diff --git a/include/spl.h b/include/spl.h
index b42683c..9a439f4 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -289,6 +289,19 @@
void spl_invoke_atf(struct spl_image_info *spl_image);
/**
+ * spl_optee_entry - entry function for optee
+ *
+ * args defind in op-tee project
+ * https://github.com/OP-TEE/optee_os/
+ * core/arch/arm/kernel/generic_entry_a32.S
+ * @arg0: pagestore
+ * @arg1: (ARMv7 standard bootarg #1)
+ * @arg2: device tree address, (ARMv7 standard bootarg #2)
+ * @arg3: non-secure entry address (ARMv7 bootarg #0)
+ */
+void spl_optee_entry(void *arg0, void *arg1, void *arg2, void *arg3);
+
+/**
* board_return_to_bootrom - allow for boards to continue with the boot ROM
*
* If a board (e.g. the Rockchip RK3368 boards) provide some
diff --git a/tools/rkimage.c b/tools/rkimage.c
index a0a3185..ae50de5 100644
--- a/tools/rkimage.c
+++ b/tools/rkimage.c
@@ -15,8 +15,7 @@
static void rkimage_set_header(void *buf, struct stat *sbuf, int ifd,
struct image_tool_params *params)
{
- memcpy(buf + RK_SPL_HDR_START, rkcommon_get_spl_hdr(params),
- RK_SPL_HDR_SIZE);
+ memcpy(buf, rkcommon_get_spl_hdr(params), RK_SPL_HDR_SIZE);
if (rkcommon_need_rc4_spl(params))
rkcommon_rc4_encode_spl(buf, 4, params->file_size);
@@ -36,7 +35,7 @@
U_BOOT_IMAGE_TYPE(
rkimage,
"Rockchip Boot Image support",
- 4,
+ 0,
&header,
rkcommon_check_params,
NULL,
diff --git a/tools/socfpgaimage.c b/tools/socfpgaimage.c
index 390c9bb..72d8b96 100644
--- a/tools/socfpgaimage.c
+++ b/tools/socfpgaimage.c
@@ -191,6 +191,7 @@
if (hdr_csum != sfp_csum)
return -EINVAL;
+ *ver = header_v0.version;
return img_len;
}