diff options
84 files changed, 2049 insertions, 578 deletions
@@ -1074,7 +1074,10 @@ U_BOOT_ITS = $(subst ",,$(CONFIG_SPL_FIT_SOURCE)) 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 9b4bcbf2fd2..c988c17f378 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -60,8 +60,20 @@ config PPC 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 d59aa3ae291..b24593e137b 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -157,6 +157,10 @@ config TARGET_EMDK config TARGET_HSDK bool "Support Synpsys HS DevelopmentKit board" +config TARGET_IOT_DEVKIT + bool "Synopsys Brite IoT Development kit" + select CPU_ARCEM6 + endchoice source "board/abilis/tb100/Kconfig" @@ -164,5 +168,6 @@ source "board/synopsys/Kconfig" source "board/synopsys/axs10x/Kconfig" source "board/synopsys/emdk/Kconfig" source "board/synopsys/hsdk/Kconfig" +source "board/synopsys/iot_devkit/Kconfig" endmenu diff --git a/arch/arc/config.mk b/arch/arc/config.mk index 169e5d7fae8..d255c90e354 100644 --- a/arch/arc/config.mk +++ b/arch/arc/config.mk @@ -9,21 +9,15 @@ CONFIG_SYS_BIG_ENDIAN = 1 endif ifdef CONFIG_SYS_LITTLE_ENDIAN -ARC_CROSS_COMPILE := arc-linux- PLATFORM_LDFLAGS += -EL PLATFORM_CPPFLAGS += -mlittle-endian endif ifdef CONFIG_SYS_BIG_ENDIAN -ARC_CROSS_COMPILE := arceb-linux- PLATFORM_LDFLAGS += -EB PLATFORM_CPPFLAGS += -mbig-endian endif -ifeq ($(CROSS_COMPILE),) -CROSS_COMPILE := $(ARC_CROSS_COMPILE) -endif - ifdef CONFIG_ARC_MMU_VER CONFIG_MMU = 1 endif diff --git a/arch/arc/dts/Makefile b/arch/arc/dts/Makefile index 491a4f40bbc..17e1405c0c4 100644 --- a/arch/arc/dts/Makefile +++ b/arch/arc/dts/Makefile @@ -6,6 +6,7 @@ dtb-$(CONFIG_TARGET_NSIM) += nsim.dtb dtb-$(CONFIG_TARGET_TB100) += abilis_tb100.dtb dtb-$(CONFIG_TARGET_EMDK) += emdk.dtb dtb-$(CONFIG_TARGET_HSDK) += hsdk.dtb +dtb-$(CONFIG_TARGET_IOT_DEVKIT) += iot_devkit.dtb targets += $(dtb-y) diff --git a/arch/arc/dts/abilis_tb100.dts b/arch/arc/dts/abilis_tb100.dts index de3e57d2461..19e45b9c663 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 13873be320b..fc9fa93b74c 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 81778c89839..6e2dd00fc37 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 5e853e3a728..ebe538d06f8 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 673bc5b26ae..f024b96925e 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 00000000000..ebf5a950f0f --- /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 9c1c7aa0eb4..243ecb178e4 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 cb95e06e931..50cd7cdb610 100644 --- a/arch/arc/lib/cpu.c +++ b/arch/arc/lib/cpu.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * Copyright (C) 2013-2014, 2018 Synopsys, Inc. All rights reserved. */ #include <common.h> @@ -33,3 +33,36 @@ int dram_init(void) { return 0; } + +#ifdef CONFIG_DISPLAY_CPUINFO +const char *decode_identity(void) +{ + int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff; + + switch (arcver) { + /* ARCompact cores */ + case 0x32: return "ARC 700 v4.4-4.5"; + case 0x33: return "ARC 700 v4.6-v4.9"; + case 0x34: return "ARC 700 v4.10"; + case 0x35: return "ARC 700 v4.11"; + + /* ARCv2 cores */ + case 0x41: return "ARC EM v1.1a"; + case 0x42: return "ARC EM v3.0"; + case 0x43: return "ARC EM v4.0"; + case 0x50: return "ARC HS v1.0"; + case 0x51: return "ARC EM v2.0"; + case 0x52: return "ARC EM v2.1"; + case 0x53: return "ARC HS v3.0"; + case 0x54: return "ARC HS v4.0"; + + default: return "Unknown ARC core"; + } +} + +int print_cpuinfo(void) +{ + printf("CPU: %s\n", decode_identity()); + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */ diff --git a/arch/arm/dts/rk3188-radxarock-u-boot.dtsi b/arch/arm/dts/rk3188-radxarock-u-boot.dtsi index 013535abcd2..1bb5408592e 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 ac931e14af1..61367126ba8 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 00000000000..9be4b3c8d2f --- /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 6b3d9201c9f..d1faff1957b 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 @@ DT_HEADER="""// SPDX-License-Identifier: GPL-2.0+ OR X11 #address-cells = <1>; images { - uboot@1 { + uboot { description = "U-Boot (64-bit)"; data = /incbin/("u-boot-nodtb.bin"); type = "standalone"; @@ -43,6 +43,7 @@ DT_HEADER="""// SPDX-License-Identifier: GPL-2.0+ OR X11 compression = "none"; load = <0x%08x>; }; + """ DT_IMAGES_NODE_END=""" @@ -53,23 +54,23 @@ DT_END=""" }; """ -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 @@ def append_fdt_node(file, dtbs): 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 @@ def generate_atf_fit_dts(fit_file_name, bl31_file_name, uboot_file_name, dtbs_fi 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 @@ def generate_atf_fit_dts(fit_file_name, bl31_file_name, uboot_file_name, dtbs_fi 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 @@ def get_bl31_segments_info(bl31_file_name): 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 @@ def main(): 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 6182d5fa3f4..31b73edabe2 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 @@ struct socfpga_reset_manager { #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 918baac5025..e599362f145 100644 --- a/arch/arm/mach-socfpga/misc_s10.c +++ b/arch/arm/mach-socfpga/misc_s10.c @@ -36,7 +36,8 @@ static u32 socfpga_phymode_setup(u32 gmac_index, const char *phymode) 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 @@ static int socfpga_set_phymode(void) 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 5cc83367407..f176c384951 100644 --- a/arch/arm/mach-socfpga/reset_manager_s10.c +++ b/arch/arm/mach-socfpga/reset_manager_s10.c @@ -93,41 +93,6 @@ void socfpga_bridges_reset(int enable) } } -/* 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 20a43d88e37..168ca3de7ce 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 @@ choice 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 084888ad8bf..8fb6a889d8d 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 c0b3858edd9..ed9eb0c24cd 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 @@ CONFIG_STANDALONE_LOAD_ADDR = 0x00000000 \ -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 00000000000..2cc6757fcf8 --- /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 c3f164c1226..2ab0342fe85 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 ab05b57d4fb..fddcc156c3d 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 @@ int cleanup_before_linux(void) 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/cpu.c b/arch/riscv/cpu/cpu.c new file mode 100644 index 00000000000..ae57fb83132 --- /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 00000000000..258e4620dd4 --- /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 00000000000..6c7a32755a6 --- /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 00000000000..84d87d2a7f6 --- /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 index 7cd7755190c..7cd7755190c 100644 --- a/arch/riscv/cpu/ax25/start.S +++ b/arch/riscv/cpu/start.S diff --git a/arch/riscv/cpu/ax25/u-boot.lds b/arch/riscv/cpu/u-boot.lds index c50b9642f1a..11bc4a738b6 100644 --- a/arch/riscv/cpu/ax25/u-boot.lds +++ b/arch/riscv/cpu/u-boot.lds @@ -3,28 +3,27 @@ * 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) + .text : { + arch/riscv/cpu/start.o (.text) } /* This needs to come before *(.text*) */ .efi_runtime : { - __efi_runtime_start = .; + __efi_runtime_start = .; *(.text.efi_runtime*) *(.rodata.efi_runtime*) *(.data.efi_runtime*) - __efi_runtime_stop = .; + __efi_runtime_stop = .; } - .text_rest : - { + .text_rest : { *(.text*) } @@ -39,10 +38,10 @@ SECTIONS . = ALIGN(4); .got : { - __got_start = .; - *(.got.plt) *(.got) - __got_end = .; - } + __got_start = .; + *(.got.plt) *(.got) + __got_end = .; + } . = ALIGN(4); @@ -50,41 +49,40 @@ SECTIONS KEEP(*(SORT(.u_boot_list*))); } - . = ALIGN(4); + . = ALIGN(4); .efi_runtime_rel : { - __efi_runtime_rel_start = .; + __efi_runtime_rel_start = .; *(.rel*.efi_runtime) *(.rel*.efi_runtime.*) - __efi_runtime_rel_stop = .; + __efi_runtime_rel_stop = .; } - . = ALIGN(4); + . = ALIGN(4); - /DISCARD/ : { *(.rela.plt*) } - .rela.dyn : { - __rel_dyn_start = .; - *(.rela*) - __rel_dyn_end = .; - } + /DISCARD/ : { *(.rela.plt*) } + .rela.dyn : { + __rel_dyn_start = .; + *(.rela*) + __rel_dyn_end = .; + } - . = ALIGN(4); + . = ALIGN(4); - .dynsym : { - __dyn_sym_start = .; - *(.dynsym) - __dyn_sym_end = .; - } + .dynsym : { + __dyn_sym_start = .; + *(.dynsym) + __dyn_sym_end = .; + } - . = ALIGN(4); + . = ALIGN(4); _end = .; .bss : { - __bss_start = .; - *(.bss*) + __bss_start = .; + *(.bss*) . = ALIGN(4); __bss_end = .; } - } diff --git a/arch/riscv/dts/ae350.dts b/arch/riscv/dts/ae350.dts index 2927e4151b0..4717ae88bc0 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>; - }; + 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>; + 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>; }; - plic1: interrupt-controller@e6400000 { - compatible = "riscv,plic1"; - #address-cells = <2>; - #interrupt-cells = <2>; + 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>; - }; + reg = <0x0 0xe6400000 0x0 0x400000>; + riscv,ndev=<1>; + interrupts-extended = <&CPU0_intc 3>; + }; - spiclk: virt_100mhz { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <100000000>; - }; + 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>; + 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 67863458ecf..00000000000 --- 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 00000000000..50fccea5c8f --- /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 f237a72f062..9ea50ce6407 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__ - -#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 /* __riscv */ -#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 f219cedfd31..00000000000 --- 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 ff8de167c64..00000000000 --- 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 9e5b32d33ed..3186835e0ad 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 cc562f935a7..b58db897522 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o 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 2610a57bbff..a7a9fb921b6 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 arch_fixup_fdt(void *blob) 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 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) 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 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) 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 00000000000..b8cecb309dc --- /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 fd5aaa1579a..5f4ca0f5a74 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 @@ DECLARE_GLOBAL_DATA_PTR; 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 00000000000..af23363fcf7 --- /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 00000000000..3c6eb4f844a --- /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 00000000000..3f29b90a417 --- /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 00000000000..041e716c9bf --- /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 00000000000..ad956b20f77 --- /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 00000000000..06457cfa6ae --- /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 00000000000..16160246438 --- /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 00000000000..120733538a4 --- /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 00000000000..c185d5cdb5c --- /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 00000000000..d0831687055 --- /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 397dd1595bd..60b438766d3 100644 --- a/cmd/bdinfo.c +++ b/cmd/bdinfo.c @@ -424,9 +424,10 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { 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 41f27a13383..d7300c212f5 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -573,7 +573,7 @@ config BOARD_LATE_INIT config DISPLAY_CPUINFO bool "Display information about the CPU during start up" - default y if ARM || NIOS2 || X86 || XTENSA || M68K + default y if ARC|| ARM || NIOS2 || X86 || XTENSA || M68K help Display information about the CPU that U-Boot is running on when U-Boot starts up. The function print_cpuinfo() is called @@ -581,7 +581,7 @@ config DISPLAY_CPUINFO config DISPLAY_BOARDINFO bool "Display information about the board during early start up" - default y if ARM || M68K || MIPS || PPC || SANDBOX || XTENSA + default y if ARC || ARM || M68K || MIPS || PPC || SANDBOX || XTENSA help Display information about the board that U-Boot is running on when U-Boot starts up. The board function checkboard() is called diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 18dbc238bf6..d0564621d4d 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -832,6 +832,13 @@ config SPL_AM33XX_ENABLE_RTC32K_OSC 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 814081fedab..a130a5be4b0 100644 --- a/common/spl/Makefile +++ b/common/spl/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_$(SPL_TPL_)UBI) += spl_ubi.o 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 038f2b0e83c..292e659c9ac 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -536,6 +536,13 @@ void board_init_r(gd_t *dummy1, ulong dummy2) 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 00000000000..8bd1949ddf3 --- /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 d64f078481b..614ef15dc76 100644 --- a/configs/ax25-ae350_defconfig +++ b/configs/ax25-ae350_defconfig @@ -15,30 +15,20 @@ CONFIG_CMD_SF_TEST=y # 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 00000000000..1f0f9c32567 --- /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 00000000000..ff1fb1f30ec --- /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 00000000000..d6c1a5d646a --- /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 00000000000..e2e48049174 --- /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 0f6574d5da1..68836a79021 100644 --- a/drivers/gpio/dwapb_gpio.c +++ b/drivers/gpio/dwapb_gpio.c @@ -171,8 +171,7 @@ static int gpio_dwapb_bind(struct udevice *dev) 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 @@ static int gpio_dwapb_bind(struct udevice *dev) 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 00000000000..f523844204a --- /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 13180fc0d69..3c702b3ed81 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -92,6 +92,24 @@ static void dwmci_prepare_data(struct dwmci_host *host, 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 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) 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 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) } 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 f54d95a881a..bf2d83a52c5 100644 --- a/drivers/mmc/rockchip_dw_mmc.c +++ b/drivers/mmc/rockchip_dw_mmc.c @@ -156,6 +156,7 @@ static int rockchip_dwmmc_bind(struct udevice *dev) } 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 a66edd9199d..dd6bacae34d 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 362d1048465..cb8ffa3fa96 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -830,6 +830,7 @@ static const struct nand_ops spinand_ops = { }; static const struct spinand_manufacturer *spinand_manufacturers[] = { + &gigadevice_spinand_manufacturer, ¯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 00000000000..0bade208084 --- /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 98485b12365..76d5a1d1152 100644 --- a/drivers/mtd/spi/Kconfig +++ b/drivers/mtd/spi/Kconfig @@ -96,6 +96,12 @@ config SPI_FLASH_WINBOND help Add support for various Winbond SPI flash chips (W25xxx) +config SPI_FLASH_XMC + bool "XMC SPI flash support" + help + Add support for various XMC (Wuhan Xinxin Semiconductor + Manufacturing Corp.) SPI flash chips (XM25xxx) + endif config SPI_FLASH_USE_4K_SECTORS diff --git a/drivers/mtd/spi/spi_flash_ids.c b/drivers/mtd/spi/spi_flash_ids.c index e662e4b42ea..ad0a0c81501 100644 --- a/drivers/mtd/spi/spi_flash_ids.c +++ b/drivers/mtd/spi/spi_flash_ids.c @@ -189,6 +189,10 @@ const struct spi_flash_info spi_flash_ids[] = { {"w25q256fw", INFO(0xef6019, 0x0, 64 * 1024, 512, RD_FULL | WR_QPP | SECT_4K) }, {"w25q256jw", INFO(0xef7019, 0x0, 64 * 1024, 512, RD_FULL | WR_QPP | SECT_4K) }, #endif +#ifdef CONFIG_SPI_FLASH_XMC /* Wuhan Xinxin Semiconductor Manufacturing Corp */ + { "xm25qh64a", INFO(0x207017, 0x0, 64 * 1024, 128, SECT_4K | RD_DUAL | RD_QUAD) }, + { "xm25qh128a", INFO(0x207018, 0x0, 64 * 1024, 256, SECT_4K | RD_DUAL | RD_QUAD) }, +#endif {}, /* Empty entry to terminate the list */ /* * Note: diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index 30a24d1947e..c01ae758c76 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 @@ static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 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 @@ static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 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 @@ static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 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 @@ static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 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 @@ static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 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 @@ static int gmac_rockchip_probe(struct udevice *dev) switch (eth_pdata->phy_interface) { case PHY_INTERFACE_MODE_RGMII: + /* Set to RGMII mode */ + if (ops->set_to_rgmii) + ops->set_to_rgmii(pdata); + else + return -EPERM; + /* * 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; } + break; + case PHY_INTERFACE_MODE_RGMII_ID: /* Set to RGMII mode */ - if (ops->set_to_rgmii) + if (ops->set_to_rgmii) { + pdata->tx_delay = 0; + pdata->rx_delay = 0; ops->set_to_rgmii(pdata); - else + } else return -EPERM; - break; - case PHY_INTERFACE_MODE_RMII: - /* The commet is the same as RGMII mode */ 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_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 196767a3f6c..1df6876e9bd 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -116,6 +116,14 @@ config ICH_SPI access the SPI NOR flash on platforms embedding this Intel ICH IP core. +config MT7621_SPI + bool "MediaTek MT7621 SPI driver" + depends on ARCH_MT7620 + help + Enable the MT7621 SPI driver. This driver can be used to access + the SPI NOR flash on platforms embedding this Ralink / MediaTek + SPI core, like MT7621/7628/7688. + config MVEBU_A3700_SPI bool "Marvell Armada 3700 SPI driver" select CLK_ARMADA_3720 diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index ee995087662..7242ea7e404 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o obj-$(CONFIG_LPC32XX_SSP) += lpc32xx_ssp.o obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o +obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o obj-$(CONFIG_MVEBU_A3700_SPI) += mvebu_a3700_spi.o obj-$(CONFIG_MXC_SPI) += mxc_spi.o obj-$(CONFIG_MXS_SPI) += mxs_spi.o diff --git a/drivers/spi/mt7621_spi.c b/drivers/spi/mt7621_spi.c new file mode 100644 index 00000000000..107e58f657b --- /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 00000000000..4ffe1141d92 --- /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 00000000000..d279c233b2c --- /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 bc1d6e3abbc..0f9d51b5579 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 8c9c7561797..be01e1e82e5 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -201,6 +201,7 @@ struct spinand_manufacturer { }; /* SPI NAND manufacturers */ +extern const struct spinand_manufacturer gigadevice_spinand_manufacturer; extern const struct spinand_manufacturer macronix_spinand_manufacturer; extern const struct spinand_manufacturer micron_spinand_manufacturer; extern const struct spinand_manufacturer winbond_spinand_manufacturer; diff --git a/include/spl.h b/include/spl.h index b42683c9e71..9a439f468b9 100644 --- a/include/spl.h +++ b/include/spl.h @@ -289,6 +289,19 @@ int spl_mmc_load_image(struct spl_image_info *spl_image, 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 a0a3185370b..ae50de55c93 100644 --- a/tools/rkimage.c +++ b/tools/rkimage.c @@ -15,8 +15,7 @@ static uint32_t header; 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 @@ static int rkimage_check_image_type(uint8_t type) 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 390c9bb4025..72d8b96f541 100644 --- a/tools/socfpgaimage.c +++ b/tools/socfpgaimage.c @@ -191,6 +191,7 @@ static int sfp_verify_header(const uint8_t *buf, uint8_t *ver) if (hdr_csum != sfp_csum) return -EINVAL; + *ver = header_v0.version; return img_len; } |