aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2021-01-15 07:23:50 -0500
committerTom Rini <trini@konsulko.com>2021-01-15 07:23:50 -0500
commitb47e293b71dd87294abf62b59cae81222f6056df (patch)
tree32ce823dce6c14d17f820e3c66549ca09fd051bc
parent35772ff4f63a302e0b873096372c70292fb0af79 (diff)
parent40551cf99c237f93d9e0e07b6dd8f31b3868a0f0 (diff)
downloadu-boot-WIP/15Jan2021.zip
u-boot-WIP/15Jan2021.tar.gz
u-boot-WIP/15Jan2021.tar.bz2
Merge branch '2021.04-rc' of https://github.com/lftan/u-bootWIP/15Jan2021
- Add ATF flow for SoC64 devices - Update socfpgaimage to support print header and update padding flow
-rw-r--r--Makefile5
-rw-r--r--arch/arm/dts/socfpga_agilex-u-boot.dtsi4
-rw-r--r--arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi120
-rw-r--r--arch/arm/dts/socfpga_stratix10-u-boot.dtsi8
-rwxr-xr-xarch/arm/dts/socfpga_stratix10_socdk-u-boot.dtsi4
-rw-r--r--arch/arm/mach-socfpga/Kconfig4
-rw-r--r--arch/arm/mach-socfpga/Makefile5
-rw-r--r--arch/arm/mach-socfpga/board.c12
-rw-r--r--arch/arm/mach-socfpga/include/mach/secure_reg_helper.h19
-rw-r--r--arch/arm/mach-socfpga/include/mach/smc_api.h13
-rw-r--r--arch/arm/mach-socfpga/lowlevel_init_soc64.S76
-rw-r--r--arch/arm/mach-socfpga/mailbox_s10.c5
-rw-r--r--arch/arm/mach-socfpga/reset_manager_s10.c13
-rw-r--r--arch/arm/mach-socfpga/secure_reg_helper.c89
-rw-r--r--arch/arm/mach-socfpga/smc_api.c56
-rw-r--r--arch/arm/mach-socfpga/wrap_pll_config_s10.c3
-rw-r--r--configs/socfpga_agilex_atf_defconfig72
-rw-r--r--configs/socfpga_stratix10_atf_defconfig74
-rw-r--r--drivers/fpga/intel_sdm_mb.c139
-rw-r--r--drivers/mmc/ca_dw_mmc.c4
-rw-r--r--drivers/mmc/dw_mmc.c9
-rw-r--r--drivers/mmc/exynos_dw_mmc.c4
-rw-r--r--drivers/mmc/nexell_dw_mmc.c4
-rw-r--r--drivers/mmc/socfpga_dw_mmc.c18
-rw-r--r--drivers/net/dwmac_socfpga.c37
-rw-r--r--include/configs/socfpga_common.h2
-rw-r--r--include/configs/socfpga_soc64_common.h24
-rw-r--r--include/dwmmc.h2
-rw-r--r--include/linux/intel-smc.h573
-rw-r--r--tools/socfpgaimage.c86
30 files changed, 1447 insertions, 37 deletions
diff --git a/Makefile b/Makefile
index 902a976..cef149d 100644
--- a/Makefile
+++ b/Makefile
@@ -1583,7 +1583,10 @@ u-boot.spr: spl/u-boot-spl.img u-boot.img FORCE
ifneq ($(CONFIG_ARCH_SOCFPGA),)
quiet_cmd_gensplx4 = GENSPLX4 $@
-cmd_gensplx4 = cat spl/u-boot-spl.sfp spl/u-boot-spl.sfp \
+cmd_gensplx4 = $(OBJCOPY) -I binary -O binary --gap-fill=0x0 \
+ --pad-to=$(CONFIG_SPL_PAD_TO) \
+ spl/u-boot-spl.sfp spl/u-boot-spl.sfp && \
+ cat spl/u-boot-spl.sfp spl/u-boot-spl.sfp \
spl/u-boot-spl.sfp spl/u-boot-spl.sfp > $@ || { rm -f $@; false; }
spl/u-boot-splx4.sfp: spl/u-boot-spl.sfp FORCE
$(call if_changed,gensplx4)
diff --git a/arch/arm/dts/socfpga_agilex-u-boot.dtsi b/arch/arm/dts/socfpga_agilex-u-boot.dtsi
index f0528a9..08f7cf7 100644
--- a/arch/arm/dts/socfpga_agilex-u-boot.dtsi
+++ b/arch/arm/dts/socfpga_agilex-u-boot.dtsi
@@ -2,9 +2,11 @@
/*
* U-Boot additions
*
- * Copyright (C) 2019 Intel Corporation <www.intel.com>
+ * Copyright (C) 2019-2020 Intel Corporation <www.intel.com>
*/
+#include "socfpga_soc64_fit-u-boot.dtsi"
+
/{
memory {
#address-cells = <2>;
diff --git a/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi b/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi
new file mode 100644
index 0000000..cf36559
--- /dev/null
+++ b/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * U-Boot additions
+ *
+ * Copyright (C) 2020 Intel Corporation <www.intel.com>
+ */
+
+#if defined(CONFIG_FIT)
+
+/ {
+ binman: binman {
+ multiple-images;
+ };
+};
+
+&binman {
+ u-boot {
+ filename = "u-boot.itb";
+ fit {
+ fit,external-offset = <CONFIG_FIT_EXTERNAL_OFFSET>;
+ description = "FIT with firmware and bootloader";
+ #address-cells = <1>;
+
+ images {
+ uboot {
+ description = "U-Boot SoC64";
+ type = "standalone";
+ os = "U-Boot";
+ arch = "arm64";
+ compression = "none";
+ load = <0x00200000>;
+
+ uboot_blob: blob-ext {
+ filename = "u-boot-nodtb.bin";
+ };
+ };
+
+ atf {
+ description = "ARM Trusted Firmware";
+ type = "firmware";
+ os = "arm-trusted-firmware";
+ arch = "arm64";
+ compression = "none";
+ load = <0x00001000>;
+ entry = <0x00001000>;
+
+ atf_blob: blob-ext {
+ filename = "bl31.bin";
+ };
+ };
+
+ fdt {
+ description = "U-Boot SoC64 flat device-tree";
+ type = "flat_dt";
+ compression = "none";
+
+ uboot_fdt_blob: blob-ext {
+ filename = "u-boot.dtb";
+ };
+ };
+ };
+
+ configurations {
+ default = "conf";
+ conf {
+ description = "Intel SoC64 FPGA";
+ firmware = "atf";
+ loadables = "uboot";
+ fdt = "fdt";
+ };
+ };
+ };
+ };
+
+ kernel {
+ filename = "kernel.itb";
+ fit {
+ description = "FIT with Linux kernel image and FDT blob";
+ #address-cells = <1>;
+
+ images {
+ kernel {
+ description = "Linux Kernel";
+ type = "kernel";
+ arch = "arm64";
+ os = "linux";
+ compression = "none";
+ load = <0x4080000>;
+ entry = <0x4080000>;
+
+ kernel_blob: blob-ext {
+ filename = "Image";
+ };
+ };
+
+ fdt {
+ description = "Linux DTB";
+ type = "flat_dt";
+ arch = "arm64";
+ compression = "none";
+
+ kernel_fdt_blob: blob-ext {
+ filename = "linux.dtb";
+ };
+ };
+ };
+
+ configurations {
+ default = "conf";
+ conf {
+ description = "Intel SoC64 FPGA";
+ kernel = "kernel";
+ fdt = "fdt";
+ };
+ };
+ };
+ };
+};
+
+#endif
diff --git a/arch/arm/dts/socfpga_stratix10-u-boot.dtsi b/arch/arm/dts/socfpga_stratix10-u-boot.dtsi
new file mode 100644
index 0000000..3e3a378
--- /dev/null
+++ b/arch/arm/dts/socfpga_stratix10-u-boot.dtsi
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * U-Boot additions
+ *
+ * Copyright (C) 2020 Intel Corporation <www.intel.com>
+ */
+
+#include "socfpga_soc64_fit-u-boot.dtsi"
diff --git a/arch/arm/dts/socfpga_stratix10_socdk-u-boot.dtsi b/arch/arm/dts/socfpga_stratix10_socdk-u-boot.dtsi
index 2669abb..61df425 100755
--- a/arch/arm/dts/socfpga_stratix10_socdk-u-boot.dtsi
+++ b/arch/arm/dts/socfpga_stratix10_socdk-u-boot.dtsi
@@ -2,9 +2,11 @@
/*
* U-Boot additions
*
- * Copyright (C) 2019 Intel Corporation <www.intel.com>
+ * Copyright (C) 2019-2020 Intel Corporation <www.intel.com>
*/
+#include "socfpga_stratix10-u-boot.dtsi"
+
/{
aliases {
spi0 = &qspi;
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
index 26f2cf8..4d4ff16 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -33,7 +33,7 @@ config TARGET_SOCFPGA_AGILEX
bool
select ARMV8_MULTIENTRY
select ARMV8_SET_SMPEN
- select ARMV8_SPIN_TABLE
+ select BINMAN if SPL_ATF
select CLK
select FPGA_INTEL_SDM_MAILBOX
select NCORE_CACHE
@@ -79,7 +79,7 @@ config TARGET_SOCFPGA_STRATIX10
bool
select ARMV8_MULTIENTRY
select ARMV8_SET_SMPEN
- select ARMV8_SPIN_TABLE
+ select BINMAN if SPL_ATF
select FPGA_INTEL_SDM_MAILBOX
choice
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
index 418f543..82b681d 100644
--- a/arch/arm/mach-socfpga/Makefile
+++ b/arch/arm/mach-socfpga/Makefile
@@ -29,6 +29,7 @@ endif
ifdef CONFIG_TARGET_SOCFPGA_STRATIX10
obj-y += clock_manager_s10.o
+obj-y += lowlevel_init_soc64.o
obj-y += mailbox_s10.o
obj-y += misc_s10.o
obj-y += mmu-arm64_s10.o
@@ -41,6 +42,7 @@ endif
ifdef CONFIG_TARGET_SOCFPGA_AGILEX
obj-y += clock_manager_agilex.o
+obj-y += lowlevel_init_soc64.o
obj-y += mailbox_s10.o
obj-y += misc_s10.o
obj-y += mmu-arm64_s10.o
@@ -70,6 +72,9 @@ ifdef CONFIG_TARGET_SOCFPGA_AGILEX
obj-y += firewall.o
obj-y += spl_agilex.o
endif
+else
+obj-$(CONFIG_SPL_ATF) += secure_reg_helper.o
+obj-$(CONFIG_SPL_ATF) += smc_api.o
endif
ifdef CONFIG_TARGET_SOCFPGA_GEN5
diff --git a/arch/arm/mach-socfpga/board.c b/arch/arm/mach-socfpga/board.c
index 340abf9..7993c27 100644
--- a/arch/arm/mach-socfpga/board.c
+++ b/arch/arm/mach-socfpga/board.c
@@ -13,7 +13,7 @@
#include <asm/arch/clock_manager.h>
#include <asm/arch/misc.h>
#include <asm/io.h>
-
+#include <log.h>
#include <usb.h>
#include <usb/dwc2_udc.h>
@@ -87,3 +87,13 @@ int g_dnl_board_usb_cable_connected(void)
return 1;
}
#endif
+
+#ifdef CONFIG_SPL_BUILD
+__weak int board_fit_config_name_match(const char *name)
+{
+ /* Just empty function now - can't decide what to choose */
+ debug("%s: %s\n", __func__, name);
+
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-socfpga/include/mach/secure_reg_helper.h b/arch/arm/mach-socfpga/include/mach/secure_reg_helper.h
new file mode 100644
index 0000000..d5a1112
--- /dev/null
+++ b/arch/arm/mach-socfpga/include/mach/secure_reg_helper.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2020 Intel Corporation <www.intel.com>
+ *
+ */
+
+#ifndef _SECURE_REG_HELPER_H_
+#define _SECURE_REG_HELPER_H_
+
+#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC 1
+#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0 2
+#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC1 3
+#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC2 4
+
+int socfpga_secure_reg_read32(u32 id, u32 *val);
+int socfpga_secure_reg_write32(u32 id, u32 val);
+int socfpga_secure_reg_update32(u32 id, u32 mask, u32 val);
+
+#endif /* _SECURE_REG_HELPER_H_ */
diff --git a/arch/arm/mach-socfpga/include/mach/smc_api.h b/arch/arm/mach-socfpga/include/mach/smc_api.h
new file mode 100644
index 0000000..bbefdd8
--- /dev/null
+++ b/arch/arm/mach-socfpga/include/mach/smc_api.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Intel Corporation
+ */
+
+#ifndef _SMC_API_H_
+#define _SMC_API_H_
+
+int invoke_smc(u32 func_id, u64 *args, int arg_len, u64 *ret_arg, int ret_len);
+int smc_send_mailbox(u32 cmd, u32 len, u32 *arg, u8 urgent, u32 *resp_buf_len,
+ u32 *resp_buf);
+
+#endif /* _SMC_API_H_ */
diff --git a/arch/arm/mach-socfpga/lowlevel_init_soc64.S b/arch/arm/mach-socfpga/lowlevel_init_soc64.S
new file mode 100644
index 0000000..612ea8a
--- /dev/null
+++ b/arch/arm/mach-socfpga/lowlevel_init_soc64.S
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2020 Intel Corporation. All rights reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/macro.h>
+
+ENTRY(lowlevel_init)
+ mov x29, lr /* Save LR */
+
+#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
+wait_for_atf:
+ ldr x4, =CPU_RELEASE_ADDR
+ ldr x5, [x4]
+ cbz x5, slave_wait_atf
+ br x5
+slave_wait_atf:
+ branch_if_slave x0, wait_for_atf
+#else
+ branch_if_slave x0, 1f
+#endif
+ ldr x0, =GICD_BASE
+ bl gic_init_secure
+1:
+#if defined(CONFIG_GICV3)
+ ldr x0, =GICR_BASE
+ bl gic_init_secure_percpu
+#elif defined(CONFIG_GICV2)
+ ldr x0, =GICD_BASE
+ ldr x1, =GICC_BASE
+ bl gic_init_secure_percpu
+#endif
+#endif
+
+#ifdef CONFIG_ARMV8_MULTIENTRY
+ branch_if_master x0, x1, 2f
+
+ /*
+ * Slave should wait for master clearing spin table.
+ * This sync prevent slaves observing incorrect
+ * value of spin table and jumping to wrong place.
+ */
+#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
+#ifdef CONFIG_GICV2
+ ldr x0, =GICC_BASE
+#endif
+ bl gic_wait_for_interrupt
+#endif
+
+ /*
+ * All slaves will enter EL2 and optionally EL1.
+ */
+ adr x4, lowlevel_in_el2
+ ldr x5, =ES_TO_AARCH64
+ bl armv8_switch_to_el2
+
+lowlevel_in_el2:
+#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
+ adr x4, lowlevel_in_el1
+ ldr x5, =ES_TO_AARCH64
+ bl armv8_switch_to_el1
+
+lowlevel_in_el1:
+#endif
+
+#endif /* CONFIG_ARMV8_MULTIENTRY */
+
+2:
+ mov lr, x29 /* Restore LR */
+ ret
+ENDPROC(lowlevel_init)
diff --git a/arch/arm/mach-socfpga/mailbox_s10.c b/arch/arm/mach-socfpga/mailbox_s10.c
index 18d4492..429444f 100644
--- a/arch/arm/mach-socfpga/mailbox_s10.c
+++ b/arch/arm/mach-socfpga/mailbox_s10.c
@@ -11,6 +11,7 @@
#include <asm/arch/mailbox_s10.h>
#include <asm/arch/system_manager.h>
#include <asm/secure.h>
+#include <asm/system.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -398,6 +399,9 @@ error:
int mbox_reset_cold(void)
{
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
+ psci_system_reset();
+#else
int ret;
ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_REBOOT_HPS, MBOX_CMD_DIRECT,
@@ -406,6 +410,7 @@ int mbox_reset_cold(void)
/* mailbox sent failure, wait for watchdog to kick in */
hang();
}
+#endif
return 0;
}
diff --git a/arch/arm/mach-socfpga/reset_manager_s10.c b/arch/arm/mach-socfpga/reset_manager_s10.c
index 3746e6a..af8f2c0 100644
--- a/arch/arm/mach-socfpga/reset_manager_s10.c
+++ b/arch/arm/mach-socfpga/reset_manager_s10.c
@@ -5,11 +5,14 @@
*/
#include <common.h>
+#include <hang.h>
#include <asm/io.h>
#include <asm/arch/reset_manager.h>
+#include <asm/arch/smc_api.h>
#include <asm/arch/system_manager.h>
#include <dt-bindings/reset/altr,rst-mgr-s10.h>
#include <linux/iopoll.h>
+#include <linux/intel-smc.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -55,6 +58,15 @@ void socfpga_per_reset_all(void)
void socfpga_bridges_reset(int enable)
{
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
+ u64 arg = enable;
+
+ int ret = invoke_smc(INTEL_SIP_SMC_HPS_SET_BRIDGES, &arg, 1, NULL, 0);
+ if (ret) {
+ printf("SMC call failed with error %d in %s.\n", ret, __func__);
+ return;
+ }
+#else
u32 reg;
if (enable) {
@@ -101,6 +113,7 @@ void socfpga_bridges_reset(int enable)
/* Disable NOC timeout */
writel(0, socfpga_get_sysmgr_addr() + SYSMGR_SOC64_NOC_TIMEOUT);
}
+#endif
}
/*
diff --git a/arch/arm/mach-socfpga/secure_reg_helper.c b/arch/arm/mach-socfpga/secure_reg_helper.c
new file mode 100644
index 0000000..0d4f45f
--- /dev/null
+++ b/arch/arm/mach-socfpga/secure_reg_helper.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <common.h>
+#include <hang.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/arch/misc.h>
+#include <asm/arch/secure_reg_helper.h>
+#include <asm/arch/smc_api.h>
+#include <asm/arch/system_manager.h>
+#include <linux/errno.h>
+#include <linux/intel-smc.h>
+
+int socfpga_secure_convert_reg_id_to_addr(u32 id, phys_addr_t *reg_addr)
+{
+ switch (id) {
+ case SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC:
+ *reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_SDMMC;
+ break;
+ case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0:
+ *reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC0;
+ break;
+ case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC1:
+ *reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC1;
+ break;
+ case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC2:
+ *reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC2;
+ break;
+ default:
+ return -EADDRNOTAVAIL;
+ }
+ return 0;
+}
+
+int socfpga_secure_reg_read32(u32 id, u32 *val)
+{
+ int ret;
+ u64 ret_arg;
+ u64 args[1];
+
+ phys_addr_t reg_addr;
+ ret = socfpga_secure_convert_reg_id_to_addr(id, &reg_addr);
+ if (ret)
+ return ret;
+
+ args[0] = (u64)reg_addr;
+ ret = invoke_smc(INTEL_SIP_SMC_REG_READ, args, 1, &ret_arg, 1);
+ if (ret)
+ return ret;
+
+ *val = (u32)ret_arg;
+
+ return 0;
+}
+
+int socfpga_secure_reg_write32(u32 id, u32 val)
+{
+ int ret;
+ u64 args[2];
+
+ phys_addr_t reg_addr;
+ ret = socfpga_secure_convert_reg_id_to_addr(id, &reg_addr);
+ if (ret)
+ return ret;
+
+ args[0] = (u64)reg_addr;
+ args[1] = val;
+ return invoke_smc(INTEL_SIP_SMC_REG_WRITE, args, 2, NULL, 0);
+}
+
+int socfpga_secure_reg_update32(u32 id, u32 mask, u32 val)
+{
+ int ret;
+ u64 args[3];
+
+ phys_addr_t reg_addr;
+ ret = socfpga_secure_convert_reg_id_to_addr(id, &reg_addr);
+ if (ret)
+ return ret;
+
+ args[0] = (u64)reg_addr;
+ args[1] = mask;
+ args[2] = val;
+ return invoke_smc(INTEL_SIP_SMC_REG_UPDATE, args, 3, NULL, 0);
+}
diff --git a/arch/arm/mach-socfpga/smc_api.c b/arch/arm/mach-socfpga/smc_api.c
new file mode 100644
index 0000000..085daba
--- /dev/null
+++ b/arch/arm/mach-socfpga/smc_api.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <common.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <linux/intel-smc.h>
+
+int invoke_smc(u32 func_id, u64 *args, int arg_len, u64 *ret_arg, int ret_len)
+{
+ struct pt_regs regs;
+
+ memset(&regs, 0, sizeof(regs));
+ regs.regs[0] = func_id;
+
+ if (args)
+ memcpy(&regs.regs[1], args, arg_len * sizeof(*args));
+
+ smc_call(&regs);
+
+ if (ret_arg)
+ memcpy(ret_arg, &regs.regs[1], ret_len * sizeof(*ret_arg));
+
+ return regs.regs[0];
+}
+
+int smc_send_mailbox(u32 cmd, u32 len, u32 *arg, u8 urgent, u32 *resp_buf_len,
+ u32 *resp_buf)
+{
+ int ret;
+ u64 args[6];
+ u64 resp[3];
+
+ args[0] = cmd;
+ args[1] = (u64)arg;
+ args[2] = len;
+ args[3] = urgent;
+ args[4] = (u64)resp_buf;
+ if (resp_buf_len)
+ args[5] = *resp_buf_len;
+ else
+ args[5] = 0;
+
+ ret = invoke_smc(INTEL_SIP_SMC_MBOX_SEND_CMD, args, ARRAY_SIZE(args),
+ resp, ARRAY_SIZE(resp));
+
+ if (ret == INTEL_SIP_SMC_STATUS_OK && resp_buf && resp_buf_len) {
+ if (!resp[0])
+ *resp_buf_len = resp[1];
+ }
+
+ return (int)resp[0];
+}
diff --git a/arch/arm/mach-socfpga/wrap_pll_config_s10.c b/arch/arm/mach-socfpga/wrap_pll_config_s10.c
index 3da8579..049c571 100644
--- a/arch/arm/mach-socfpga/wrap_pll_config_s10.c
+++ b/arch/arm/mach-socfpga/wrap_pll_config_s10.c
@@ -12,6 +12,7 @@
const struct cm_config * const cm_get_default_config(void)
{
+#ifdef CONFIG_SPL_BUILD
struct cm_config *cm_handoff_cfg = (struct cm_config *)
(S10_HANDOFF_CLOCK + S10_HANDOFF_OFFSET_DATA);
u32 *conversion = (u32 *)cm_handoff_cfg;
@@ -26,7 +27,7 @@ const struct cm_config * const cm_get_default_config(void)
} else if (handoff_clk == S10_HANDOFF_MAGIC_CLOCK) {
return cm_handoff_cfg;
}
-
+#endif
return NULL;
}
diff --git a/configs/socfpga_agilex_atf_defconfig b/configs/socfpga_agilex_atf_defconfig
new file mode 100644
index 0000000..ad87a80
--- /dev/null
+++ b/configs/socfpga_agilex_atf_defconfig
@@ -0,0 +1,72 @@
+CONFIG_ARM=y
+CONFIG_ARM_SMCCC=y
+CONFIG_SPL_LDSCRIPT="arch/arm/mach-socfpga/u-boot-spl-soc64.lds"
+CONFIG_ARCH_SOCFPGA=y
+CONFIG_SYS_TEXT_BASE=0x200000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_ENV_SIZE=0x1000
+CONFIG_ENV_OFFSET=0x200
+CONFIG_DM_GPIO=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_TARGET_SOCFPGA_AGILEX_SOCDK=y
+CONFIG_IDENT_STRING="socfpga_agilex"
+CONFIG_SPL_FS_FAT=y
+CONFIG_SPL_TEXT_BASE=0xFFE00000
+CONFIG_FIT=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_LOAD_FIT_ADDRESS=0x02000000
+# CONFIG_USE_SPL_FIT_GENERATOR is not set
+CONFIG_BOOTDELAY=5
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="earlycon"
+CONFIG_SPL_CACHE=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x02000000
+CONFIG_SPL_ATF=y
+CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="SOCFPGA_AGILEX # "
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_DEFAULT_DEVICE_TREE="socfpga_agilex_socdk"
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_ALTERA_SDRAM=y
+CONFIG_DWAPB_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_DW=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_DW=y
+CONFIG_MTD=y
+CONFIG_SF_DEFAULT_MODE=0x2003
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_PHY_MICREL=y
+CONFIG_PHY_MICREL_KSZ90X1=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_MII=y
+CONFIG_DM_RESET=y
+CONFIG_SPI=y
+CONFIG_CADENCE_QSPI=y
+CONFIG_DESIGNWARE_SPI=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_STORAGE=y
+CONFIG_DESIGNWARE_WATCHDOG=y
+CONFIG_WDT=y
+# CONFIG_SPL_USE_TINY_PRINTF is not set
+CONFIG_PANIC_HANG=y
diff --git a/configs/socfpga_stratix10_atf_defconfig b/configs/socfpga_stratix10_atf_defconfig
new file mode 100644
index 0000000..1005ba9
--- /dev/null
+++ b/configs/socfpga_stratix10_atf_defconfig
@@ -0,0 +1,74 @@
+CONFIG_ARM=y
+CONFIG_ARM_SMCCC=y
+CONFIG_SPL_LDSCRIPT="arch/arm/mach-socfpga/u-boot-spl-soc64.lds"
+CONFIG_ARCH_SOCFPGA=y
+CONFIG_SYS_TEXT_BASE=0x200000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_ENV_SIZE=0x1000
+CONFIG_ENV_OFFSET=0x200
+CONFIG_DM_GPIO=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_TARGET_SOCFPGA_STRATIX10_SOCDK=y
+CONFIG_IDENT_STRING="socfpga_stratix10"
+CONFIG_SPL_FS_FAT=y
+CONFIG_SPL_TEXT_BASE=0xFFE00000
+CONFIG_FIT=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_LOAD_FIT_ADDRESS=0x02000000
+# CONFIG_USE_SPL_FIT_GENERATOR is not set
+CONFIG_BOOTDELAY=5
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="earlycon"
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x02000000
+CONFIG_SPL_ATF=y
+CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="SOCFPGA_STRATIX10 # "
+CONFIG_CMD_MEMTEST=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_DEFAULT_DEVICE_TREE="socfpga_stratix10_socdk"
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_ALTERA_SDRAM=y
+CONFIG_FPGA_INTEL_PR=y
+CONFIG_DWAPB_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_DW=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_DW=y
+CONFIG_MTD=y
+CONFIG_SF_DEFAULT_MODE=0x2003
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_PHY_MICREL=y
+CONFIG_PHY_MICREL_KSZ90X1=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_MII=y
+CONFIG_DM_RESET=y
+CONFIG_SPI=y
+CONFIG_CADENCE_QSPI=y
+CONFIG_DESIGNWARE_SPI=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_STORAGE=y
+CONFIG_DESIGNWARE_WATCHDOG=y
+CONFIG_WDT=y
+# CONFIG_SPL_USE_TINY_PRINTF is not set
+CONFIG_PANIC_HANG=y
diff --git a/drivers/fpga/intel_sdm_mb.c b/drivers/fpga/intel_sdm_mb.c
index 9a1dc2c..f5fd9a1 100644
--- a/drivers/fpga/intel_sdm_mb.c
+++ b/drivers/fpga/intel_sdm_mb.c
@@ -8,11 +8,149 @@
#include <log.h>
#include <watchdog.h>
#include <asm/arch/mailbox_s10.h>
+#include <asm/arch/smc_api.h>
#include <linux/delay.h>
+#include <linux/intel-smc.h>
#define RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS 60000
#define RECONFIG_STATUS_INTERVAL_DELAY_US 1000000
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
+
+#define BITSTREAM_CHUNK_SIZE 0xFFFF0
+#define RECONFIG_STATUS_POLL_RETRY_MAX 100
+
+/*
+ * Polling the FPGA configuration status.
+ * Return 0 for success, non-zero for error.
+ */
+static int reconfig_status_polling_resp(void)
+{
+ int ret;
+ unsigned long start = get_timer(0);
+
+ while (1) {
+ ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_ISDONE, NULL, 0,
+ NULL, 0);
+
+ if (!ret)
+ return 0; /* configuration success */
+
+ if (ret != INTEL_SIP_SMC_STATUS_BUSY)
+ return ret;
+
+ if (get_timer(start) > RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS)
+ return -ETIMEDOUT; /* time out */
+
+ puts(".");
+ udelay(RECONFIG_STATUS_INTERVAL_DELAY_US);
+ WATCHDOG_RESET();
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int send_bitstream(const void *rbf_data, size_t rbf_size)
+{
+ int i;
+ u64 res_buf[3];
+ u64 args[2];
+ u32 xfer_count = 0;
+ int ret, wr_ret = 0, retry = 0;
+ size_t buf_size = (rbf_size > BITSTREAM_CHUNK_SIZE) ?
+ BITSTREAM_CHUNK_SIZE : rbf_size;
+
+ while (rbf_size || xfer_count) {
+ if (!wr_ret && rbf_size) {
+ args[0] = (u64)rbf_data;
+ args[1] = buf_size;
+ wr_ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_WRITE,
+ args, 2, NULL, 0);
+
+ debug("wr_ret = %d, rbf_data = %p, buf_size = %08lx\n",
+ wr_ret, rbf_data, buf_size);
+
+ if (wr_ret)
+ continue;
+
+ rbf_size -= buf_size;
+ rbf_data += buf_size;
+
+ if (buf_size >= rbf_size)
+ buf_size = rbf_size;
+
+ xfer_count++;
+ puts(".");
+ } else {
+ ret = invoke_smc(
+ INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE,
+ NULL, 0, res_buf, ARRAY_SIZE(res_buf));
+ if (!ret) {
+ for (i = 0; i < ARRAY_SIZE(res_buf); i++) {
+ if (!res_buf[i])
+ break;
+ xfer_count--;
+ wr_ret = 0;
+ retry = 0;
+ }
+ } else if (ret !=
+ INTEL_SIP_SMC_STATUS_BUSY)
+ return ret;
+ else if (!xfer_count)
+ return INTEL_SIP_SMC_STATUS_ERROR;
+
+ if (++retry >= RECONFIG_STATUS_POLL_RETRY_MAX)
+ return -ETIMEDOUT;
+
+ udelay(20000);
+ }
+ WATCHDOG_RESET();
+ }
+
+ return 0;
+}
+
+/*
+ * This is the interface used by FPGA driver.
+ * Return 0 for success, non-zero for error.
+ */
+int intel_sdm_mb_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size)
+{
+ int ret;
+ u64 arg = 1;
+
+ debug("Invoking FPGA_CONFIG_START...\n");
+
+ ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_START, &arg, 1, NULL, 0);
+
+ if (ret) {
+ puts("Failure in RECONFIG mailbox command!\n");
+ return ret;
+ }
+
+ ret = send_bitstream(rbf_data, rbf_size);
+ if (ret) {
+ puts("Error sending bitstream!\n");
+ return ret;
+ }
+
+ /* Make sure we don't send MBOX_RECONFIG_STATUS too fast */
+ udelay(RECONFIG_STATUS_INTERVAL_DELAY_US);
+
+ debug("Polling with MBOX_RECONFIG_STATUS...\n");
+ ret = reconfig_status_polling_resp();
+ if (ret) {
+ puts("FPGA reconfiguration failed!");
+ return ret;
+ }
+
+ puts("FPGA reconfiguration OK!\n");
+
+ return ret;
+}
+
+#else
+
static const struct mbox_cfgstat_state {
int err_no;
const char *error_name;
@@ -286,3 +424,4 @@ int intel_sdm_mb_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size)
return ret;
}
+#endif
diff --git a/drivers/mmc/ca_dw_mmc.c b/drivers/mmc/ca_dw_mmc.c
index fad2ff5..2b79356 100644
--- a/drivers/mmc/ca_dw_mmc.c
+++ b/drivers/mmc/ca_dw_mmc.c
@@ -40,7 +40,7 @@ struct ca_dwmmc_priv_data {
u8 ds;
};
-static void ca_dwmci_clksel(struct dwmci_host *host)
+static int ca_dwmci_clksel(struct dwmci_host *host)
{
struct ca_dwmmc_priv_data *priv = host->priv;
u32 val = readl(priv->sd_dll_reg);
@@ -52,6 +52,8 @@ static void ca_dwmci_clksel(struct dwmci_host *host)
val |= SD_CLK_SEL_100MHZ;
writel(val, priv->sd_dll_reg);
+
+ return 0;
}
static void ca_dwmci_board_init(struct dwmci_host *host)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 7702f4b..7c8a312 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -496,8 +496,13 @@ static int dwmci_set_ios(struct mmc *mmc)
dwmci_writel(host, DWMCI_UHS_REG, regs);
- if (host->clksel)
- host->clksel(host);
+ if (host->clksel) {
+ int ret;
+
+ ret = host->clksel(host);
+ if (ret)
+ return ret;
+ }
#if CONFIG_IS_ENABLED(DM_REGULATOR)
if (mmc->vqmmc_supply) {
diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
index 3aa9fb3..2fc1ef1 100644
--- a/drivers/mmc/exynos_dw_mmc.c
+++ b/drivers/mmc/exynos_dw_mmc.c
@@ -44,7 +44,7 @@ struct dwmci_exynos_priv_data {
* Function used as callback function to initialise the
* CLKSEL register for every mmc channel.
*/
-static void exynos_dwmci_clksel(struct dwmci_host *host)
+static int exynos_dwmci_clksel(struct dwmci_host *host)
{
#ifdef CONFIG_DM_MMC
struct dwmci_exynos_priv_data *priv =
@@ -53,6 +53,8 @@ static void exynos_dwmci_clksel(struct dwmci_host *host)
struct dwmci_exynos_priv_data *priv = host->priv;
#endif
dwmci_writel(host, DWMCI_CLKSEL, priv->sdr_timing);
+
+ return 0;
}
unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq)
diff --git a/drivers/mmc/nexell_dw_mmc.c b/drivers/mmc/nexell_dw_mmc.c
index 753c89d..2723e48 100644
--- a/drivers/mmc/nexell_dw_mmc.c
+++ b/drivers/mmc/nexell_dw_mmc.c
@@ -51,7 +51,7 @@ struct nexell_dwmmc_priv {
struct clk *clk_get(const char *id);
-static void nx_dw_mmc_clksel(struct dwmci_host *host)
+static int nx_dw_mmc_clksel(struct dwmci_host *host)
{
/* host->priv is pointer to "struct udevice" */
struct nexell_dwmmc_priv *priv = dev_get_priv(host->priv);
@@ -65,6 +65,8 @@ static void nx_dw_mmc_clksel(struct dwmci_host *host)
DWMCI_SET_DRV_CLK(DWMCI_SHIFT_0) | DWMCI_SET_DIV_RATIO(3);
dwmci_writel(host, DWMCI_CLKSEL, val);
+
+ return 0;
}
static void nx_dw_mmc_reset(int ch)
diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c
index dc008c5..aa0d3a2 100644
--- a/drivers/mmc/socfpga_dw_mmc.c
+++ b/drivers/mmc/socfpga_dw_mmc.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <log.h>
#include <asm/arch/clock_manager.h>
+#include <asm/arch/secure_reg_helper.h>
#include <asm/arch/system_manager.h>
#include <clk.h>
#include <dm.h>
@@ -13,6 +14,7 @@
#include <errno.h>
#include <fdtdec.h>
#include <dm/device_compat.h>
+#include <linux/intel-smc.h>
#include <linux/libfdt.h>
#include <linux/err.h>
#include <malloc.h>
@@ -46,7 +48,7 @@ static void socfpga_dwmci_reset(struct udevice *dev)
reset_deassert_bulk(&reset_bulk);
}
-static void socfpga_dwmci_clksel(struct dwmci_host *host)
+static int socfpga_dwmci_clksel(struct dwmci_host *host)
{
struct dwmci_socfpga_priv_data *priv = host->priv;
u32 sdmmc_mask = ((priv->smplsel & 0x7) << SYSMGR_SDMMC_SMPLSEL_SHIFT) |
@@ -58,14 +60,28 @@ static void socfpga_dwmci_clksel(struct dwmci_host *host)
debug("%s: drvsel %d smplsel %d\n", __func__,
priv->drvsel, priv->smplsel);
+
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
+ int ret;
+
+ ret = socfpga_secure_reg_write32(SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC,
+ sdmmc_mask);
+ if (ret) {
+ printf("DWMMC: Failed to set clksel via SMC call");
+ return ret;
+ }
+#else
writel(sdmmc_mask, socfpga_get_sysmgr_addr() + SYSMGR_SDMMC);
debug("%s: SYSMGR_SDMMCGRP_CTRL_REG = 0x%x\n", __func__,
readl(socfpga_get_sysmgr_addr() + SYSMGR_SDMMC));
+#endif
/* Enable SDMMC clock */
setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_PERPLL_EN,
CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK);
+
+ return 0;
}
static int socfpga_dwmmc_get_clk_rate(struct udevice *dev)
diff --git a/drivers/net/dwmac_socfpga.c b/drivers/net/dwmac_socfpga.c
index 939f199..82fdff5 100644
--- a/drivers/net/dwmac_socfpga.c
+++ b/drivers/net/dwmac_socfpga.c
@@ -6,6 +6,8 @@
*/
#include <common.h>
+#include <asm/arch/secure_reg_helper.h>
+#include <asm/arch/system_manager.h>
#include <asm/io.h>
#include <dm.h>
#include <clk.h>
@@ -17,8 +19,6 @@
#include <dm/device_compat.h>
#include <linux/err.h>
-#include <asm/arch/system_manager.h>
-
struct dwmac_socfpga_plat {
struct dw_eth_pdata dw_eth_pdata;
void *phy_intf;
@@ -64,6 +64,32 @@ static int dwmac_socfpga_of_to_plat(struct udevice *dev)
return designware_eth_of_to_plat(dev);
}
+static int dwmac_socfpga_do_setphy(struct udevice *dev, u32 modereg)
+{
+ struct dwmac_socfpga_plat *pdata = dev_get_plat(dev);
+ u32 modemask = SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << pdata->reg_shift;
+
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
+ u32 index = ((u64)pdata->phy_intf - socfpga_get_sysmgr_addr() -
+ SYSMGR_SOC64_EMAC0) >> 2;
+
+ u32 id = SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0 + index;
+
+ int ret = socfpga_secure_reg_update32(id,
+ modemask,
+ modereg << pdata->reg_shift);
+ if (ret) {
+ dev_err(dev, "Failed to set PHY register via SMC call\n");
+ return ret;
+ }
+#else
+ clrsetbits_le32(pdata->phy_intf, modemask,
+ modereg << pdata->reg_shift);
+#endif
+
+ return 0;
+}
+
static int dwmac_socfpga_probe(struct udevice *dev)
{
struct dwmac_socfpga_plat *pdata = dev_get_plat(dev);
@@ -71,7 +97,6 @@ static int dwmac_socfpga_probe(struct udevice *dev)
struct reset_ctl_bulk reset_bulk;
int ret;
u32 modereg;
- u32 modemask;
switch (edata->phy_interface) {
case PHY_INTERFACE_MODE_MII:
@@ -97,9 +122,9 @@ static int dwmac_socfpga_probe(struct udevice *dev)
reset_assert_bulk(&reset_bulk);
- modemask = SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << pdata->reg_shift;
- clrsetbits_le32(pdata->phy_intf, modemask,
- modereg << pdata->reg_shift);
+ ret = dwmac_socfpga_do_setphy(dev, modereg);
+ if (ret)
+ return ret;
reset_release_bulk(&reset_bulk);
diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h
index 3d71759..62b327c 100644
--- a/include/configs/socfpga_common.h
+++ b/include/configs/socfpga_common.h
@@ -22,8 +22,10 @@
#if defined(CONFIG_TARGET_SOCFPGA_GEN5)
#define CONFIG_SYS_INIT_RAM_ADDR 0xFFFF0000
#define CONFIG_SYS_INIT_RAM_SIZE SOCFPGA_PHYS_OCRAM_SIZE
+#define CONFIG_SPL_PAD_TO 0x10000
#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10)
#define CONFIG_SYS_INIT_RAM_ADDR 0xFFE00000
+#define CONFIG_SPL_PAD_TO 0x40000
/* SPL memory allocation configuration, this is for FAT implementation */
#ifndef CONFIG_SYS_SPL_MALLOC_SIZE
#define CONFIG_SYS_SPL_MALLOC_SIZE 0x10000
diff --git a/include/configs/socfpga_soc64_common.h b/include/configs/socfpga_soc64_common.h
index fb5e2e8..fdcd7d3 100644
--- a/include/configs/socfpga_soc64_common.h
+++ b/include/configs/socfpga_soc64_common.h
@@ -40,9 +40,14 @@
*/
#define CONFIG_SYS_INIT_RAM_ADDR 0xFFE00000
#define CONFIG_SYS_INIT_RAM_SIZE 0x40000
+#ifdef CONFIG_SPL_BUILD
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR \
+ CONFIG_SYS_INIT_RAM_SIZE \
- S10_HANDOFF_SIZE)
+#else
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE \
+ + 0x100000)
+#endif
#define CONFIG_SYS_INIT_SP_OFFSET (CONFIG_SYS_INIT_SP_ADDR)
#define CONFIG_SYS_MALLOC_LEN (5 * 1024 * 1024)
@@ -78,12 +83,20 @@ unsigned int cm_get_qspi_controller_clk_hz(void);
* CONFIG_BOOTARGS goes into the environment value "bootargs".
* Do note the value will override also the chosen node in FDT blob.
*/
+
+#ifdef CONFIG_FIT
+#define CONFIG_BOOTFILE "kernel.itb"
+#define CONFIG_BOOTCOMMAND "run fatscript; run mmcfitload;run linux_qspi_enable;" \
+ "run mmcfitboot"
+#else
+#define CONFIG_BOOTFILE "Image"
#define CONFIG_BOOTCOMMAND "run fatscript; run mmcload;run linux_qspi_enable;" \
"run mmcboot"
+#endif
#define CONFIG_EXTRA_ENV_SETTINGS \
"loadaddr=" __stringify(CONFIG_SYS_LOAD_ADDR) "\0" \
- "bootfile=Image\0" \
+ "bootfile=" CONFIG_BOOTFILE "\0" \
"fdt_addr=8000000\0" \
"fdtimage=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
"mmcroot=/dev/mmcblk0p2\0" \
@@ -93,6 +106,11 @@ unsigned int cm_get_qspi_controller_clk_hz(void);
"mmcload=mmc rescan;" \
"load mmc 0:1 ${loadaddr} ${bootfile};" \
"load mmc 0:1 ${fdt_addr} ${fdtimage}\0" \
+ "mmcfitboot=setenv bootargs " CONFIG_BOOTARGS \
+ " root=${mmcroot} rw rootwait;" \
+ "bootm ${loadaddr}\0" \
+ "mmcfitload=mmc rescan;" \
+ "load mmc 0:1 ${loadaddr} ${bootfile}\0" \
"linux_qspi_enable=if sf probe; then " \
"echo Enabling QSPI at Linux DTB...;" \
"fdt addr ${fdt_addr}; fdt resize;" \
@@ -193,6 +211,10 @@ unsigned int cm_get_l4_sys_free_clk_hz(void);
- CONFIG_SYS_SPL_MALLOC_SIZE)
/* SPL SDMMC boot support */
+#ifdef CONFIG_SPL_LOAD_FIT
+#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.itb"
+#else
#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img"
+#endif
#endif /* __CONFIG_SOCFPGA_SOC64_COMMON_H__ */
diff --git a/include/dwmmc.h b/include/dwmmc.h
index 51ab74e..5fc8ed8 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -174,7 +174,7 @@ struct dwmci_host {
struct mmc *mmc;
void *priv;
- void (*clksel)(struct dwmci_host *host);
+ int (*clksel)(struct dwmci_host *host);
void (*board_init)(struct dwmci_host *host);
/**
diff --git a/include/linux/intel-smc.h b/include/linux/intel-smc.h
new file mode 100644
index 0000000..cacb410
--- /dev/null
+++ b/include/linux/intel-smc.h
@@ -0,0 +1,573 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2017-2018, Intel Corporation
+ */
+
+#ifndef __INTEL_SMC_H
+#define __INTEL_SMC_H
+
+#include <linux/arm-smccc.h>
+#include <linux/bitops.h>
+
+/*
+ * This file defines the Secure Monitor Call (SMC) message protocol used for
+ * service layer driver in normal world (EL1) to communicate with secure
+ * monitor software in Secure Monitor Exception Level 3 (EL3).
+ *
+ * This file is shared with secure firmware (FW) which is out of u-boot tree.
+ *
+ * An ARM SMC instruction takes a function identifier and up to 6 64-bit
+ * register values as arguments, and can return up to 4 64-bit register
+ * values. The operation of the secure monitor is determined by the parameter
+ * values passed in through registers.
+
+ * EL1 and EL3 communicates pointer as physical address rather than the
+ * virtual address.
+ */
+
+/*
+ * Functions specified by ARM SMC Calling convention:
+ *
+ * FAST call executes atomic operations, returns when the requested operation
+ * has completed.
+ * STD call starts a operation which can be preempted by a non-secure
+ * interrupt. The call can return before the requested operation has
+ * completed.
+ *
+ * a0..a7 is used as register names in the descriptions below, on arm32
+ * that translates to r0..r7 and on arm64 to w0..w7.
+ */
+
+#define INTEL_SIP_SMC_STD_CALL_VAL(func_num) \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, ARM_SMCCC_SMC_64, \
+ ARM_SMCCC_OWNER_SIP, (func_num))
+
+#define INTEL_SIP_SMC_FAST_CALL_VAL(func_num) \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \
+ ARM_SMCCC_OWNER_SIP, (func_num))
+
+/*
+ * Return values in INTEL_SIP_SMC_* call
+ *
+ * INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION:
+ * Secure monitor software doesn't recognize the request.
+ *
+ * INTEL_SIP_SMC_STATUS_OK:
+ * SMC call completed successfully,
+ * In case of FPGA configuration write operation, it means secure monitor
+ * software can accept the next chunk of FPGA configuration data.
+ *
+ * INTEL_SIP_SMC_STATUS_BUSY:
+ * In case of FPGA configuration write operation, it means secure monitor
+ * software is still processing previous data & can't accept the next chunk
+ * of data. Service driver needs to issue
+ * INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE call to query the
+ * completed block(s).
+ *
+ * INTEL_SIP_SMC_STATUS_ERROR:
+ * There is error during the SMC call process.
+ *
+ * INTEL_SIP_SMC_REG_ERROR:
+ * There is error during a read or write operation of the protected
+ * registers.
+ */
+#define INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION 0xFFFFFFFF
+#define INTEL_SIP_SMC_STATUS_OK 0x0
+#define INTEL_SIP_SMC_STATUS_BUSY 0x1
+#define INTEL_SIP_SMC_STATUS_REJECTED 0x2
+#define INTEL_SIP_SMC_STATUS_ERROR 0x4
+#define INTEL_SIP_SMC_REG_ERROR 0x5
+#define INTEL_SIP_SMC_RSU_ERROR 0x7
+
+/*
+ * Request INTEL_SIP_SMC_FPGA_CONFIG_START
+ *
+ * Sync call used by service driver at EL1 to request the FPGA in EL3 to
+ * be prepare to receive a new configuration.
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_FPGA_CONFIG_START.
+ * a1: flag for full or partial configuration
+ * 0 full reconfiguration.
+ * 1 partial reconfiguration.
+ * a2-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK, or INTEL_SIP_SMC_STATUS_ERROR.
+ * a1-3: not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_START 1
+#define INTEL_SIP_SMC_FPGA_CONFIG_START \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_START)
+
+/*
+ * Request INTEL_SIP_SMC_FPGA_CONFIG_WRITE
+ *
+ * Async call used by service driver at EL1 to provide FPGA configuration data
+ * to secure world.
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_FPGA_CONFIG_WRITE.
+ * a1: 64bit physical address of the configuration data memory block
+ * a2: Size of configuration data block.
+ * a3-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_BUSY,
+ * INTEL_SIP_SMC_STATUS_REJECTED or INTEL_SIP_SMC_STATUS_ERROR.
+ * a1: 64bit physical address of 1st completed memory block if any completed
+ * block, otherwise zero value.
+ * a2: 64bit physical address of 2nd completed memory block if any completed
+ * block, otherwise zero value.
+ * a3: 64bit physical address of 3rd completed memory block if any completed
+ * block, otherwise zero value.
+ */
+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_WRITE 2
+#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE \
+ INTEL_SIP_SMC_STD_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_WRITE)
+
+/*
+ * Request INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE
+ *
+ * Sync call used by service driver at EL1 to track the completed write
+ * transactions. This request is called after INTEL_SIP_SMC_FPGA_CONFIG_WRITE
+ * call returns INTEL_SIP_SMC_STATUS_BUSY.
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE.
+ * a1-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_BUSY or
+ * INTEL_SIP_SMC_STATUS_ERROR.
+ * a1: 64bit physical address of 1st completed memory block.
+ * a2: 64bit physical address of 2nd completed memory block if
+ * any completed block, otherwise zero value.
+ * a3: 64bit physical address of 3rd completed memory block if
+ * any completed block, otherwise zero value.
+ */
+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE 3
+#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE \
+INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)
+
+/*
+ * Request INTEL_SIP_SMC_FPGA_CONFIG_ISDONE
+ *
+ * Sync call used by service driver at EL1 to inform secure world that all
+ * data are sent, to check whether or not the secure world had completed
+ * the FPGA configuration process.
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_FPGA_CONFIG_ISDONE.
+ * a1-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_BUSY or
+ * INTEL_SIP_SMC_STATUS_ERROR.
+ * a1-3: not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_ISDONE 4
+#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_ISDONE)
+
+/*
+ * Request INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM
+ *
+ * Sync call used by service driver at EL1 to query the physical address of
+ * memory block reserved by secure monitor software.
+ *
+ * Call register usage:
+ * a0:INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM.
+ * a1-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_STATUS_ERROR.
+ * a1: start of physical address of reserved memory block.
+ * a2: size of reserved memory block.
+ * a3: not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_GET_MEM 5
+#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_GET_MEM)
+
+/*
+ * Request INTEL_SIP_SMC_FPGA_CONFIG_LOOPBACK
+ *
+ * For SMC loop-back mode only, used for internal integration, debugging
+ * or troubleshooting.
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_FPGA_CONFIG_LOOPBACK.
+ * a1-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_STATUS_ERROR.
+ * a1-3: not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_LOOPBACK 6
+#define INTEL_SIP_SMC_FPGA_CONFIG_LOOPBACK \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_LOOPBACK)
+
+/*
+ * Request INTEL_SIP_SMC_REG_READ
+ *
+ * Read a protected register using SMCCC
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_REG_READ.
+ * a1: register address.
+ * a2-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REG_ERROR.
+ * a1: Value in the register
+ * a2-3: not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_REG_READ 7
+#define INTEL_SIP_SMC_REG_READ \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_READ)
+
+/*
+ * Request INTEL_SIP_SMC_REG_WRITE
+ *
+ * Write a protected register using SMCCC
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_REG_WRITE.
+ * a1: register address
+ * a2: value to program into register.
+ * a3-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REG_ERROR.
+ * a1-3: not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_REG_WRITE 8
+#define INTEL_SIP_SMC_REG_WRITE \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_WRITE)
+
+/*
+ * Request INTEL_SIP_SMC_FUNCID_REG_UPDATE
+ *
+ * Update one or more bits in a protected register using a
+ * read-modify-write operation.
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_REG_UPDATE.
+ * a1: register address
+ * a2: Write Mask.
+ * a3: Value to write.
+ * a4-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REG_ERROR.
+ * a1-3: Not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_REG_UPDATE 9
+#define INTEL_SIP_SMC_REG_UPDATE \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_UPDATE)
+
+/*
+* Request INTEL_SIP_SMC_RSU_STATUS
+*
+* Sync call used by service driver at EL1 to query the RSU status
+*
+* Call register usage:
+* a0 INTEL_SIP_SMC_RSU_STATUS
+* a1-7 not used
+*
+* Return status
+* a0: Current Image
+* a1: Last Failing Image
+* a2: Version [width 32 bit] | State [width 32 bit]
+* a3: Error details [width 32 bit] | Error location [width 32 bit]
+*
+* Or
+*
+* a0: INTEL_SIP_SMC_RSU_ERROR
+*/
+#define INTEL_SIP_SMC_FUNCID_RSU_STATUS 11
+#define INTEL_SIP_SMC_RSU_STATUS \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_STATUS)
+
+/*
+* Request INTEL_SIP_SMC_RSU_UPDATE
+*
+* Sync call used by service driver at EL1 to tell you next reboot is RSU_UPDATE
+*
+* Call register usage:
+* a0 INTEL_SIP_SMC_RSU_UPDATE
+* a1 64bit physical address of the configuration data memory in flash
+* a2-7 not used
+*
+* Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+*/
+#define INTEL_SIP_SMC_FUNCID_RSU_UPDATE 12
+#define INTEL_SIP_SMC_RSU_UPDATE \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_UPDATE)
+
+/*
+ * Request INTEL_SIP_SMC_ECC_DBE
+ *
+ * Sync call used by service driver at EL1 alert EL3 that a Double Bit
+ * ECC error has occurred.
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_ECC_DBE
+ * a1 SysManager Double Bit Error value
+ * a2-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ */
+#define INTEL_SIP_SMC_FUNCID_ECC_DBE 13
+#define INTEL_SIP_SMC_ECC_DBE \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_ECC_DBE)
+
+/*
+* Request INTEL_SIP_SMC_RSU_NOTIFY
+*
+* Sync call used by service driver at EL1 to report HPS software execution stage
+*
+* Call register usage:
+* a0 INTEL_SIP_SMC_RSU_NOTIFY
+* a1 32bit HPS software execution stage
+* a2-7 not used
+*
+* Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REG_ERROR.
+*/
+#define INTEL_SIP_SMC_FUNCID_RSU_NOTIFY 14
+#define INTEL_SIP_SMC_RSU_NOTIFY \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_NOTIFY)
+
+/*
+ * Request INTEL_SIP_SMC_RSU_RETRY_COUNTER
+ *
+ * Sync call used by service driver at EL1 to query the RSU retry counter
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_RSU_RETRY_COUNTER
+ * a1-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_RSU_ERROR.
+ * a1 retry counter
+*/
+#define INTEL_SIP_SMC_FUNCID_RSU_RETRY_COUNTER 15
+#define INTEL_SIP_SMC_RSU_RETRY_COUNTER \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_RETRY_COUNTER)
+
+/*
+ * Request INTEL_SIP_SMC_RSU_DCMF_VERSION
+ *
+ * Sync call used by service driver at EL1 to query DCMF version
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_RSU_DCMF_VERSION
+ * a1-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ * a1 dcmf1 version | dcmf0 version
+ * a2 dcmf3 version | dcmf2 version
+ *
+ * Or
+ *
+ * a0 INTEL_SIP_SMC_RSU_ERROR
+ */
+#define INTEL_SIP_SMC_FUNCID_RSU_DCMF_VERSION 16
+#define INTEL_SIP_SMC_RSU_DCMF_VERSION \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_DCMF_VERSION)
+
+/*
+ * Request INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION
+ *
+ * Sync call used by SSBL (EL2) to copy DCMF version to ATF memory
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION
+ * a1 dcmf1 version | dcmf0 version
+ * a2 dcmf3 version | dcmf2 version
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ */
+#define INTEL_SIP_SMC_FUNCID_RSU_COPY_DCMF_VERSION 17
+#define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_COPY_DCMF_VERSION)
+
+/*
+ * Request INTEL_SIP_SMC_RSU_MAX_RETRY
+ *
+ * Sync call used by service driver at EL1 to query max_retry parameter
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_RSU_MAX_RETRY
+ * a1-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ * a1 max_retry
+ *
+ * Or
+ *
+ * a0 INTEL_SIP_SMC_RSU_ERROR
+ */
+#define INTEL_SIP_SMC_FUNCID_RSU_MAX_RETRY 18
+#define INTEL_SIP_SMC_RSU_MAX_RETRY \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_MAX_RETRY)
+
+/*
+ * Request INTEL_SIP_SMC_RSU_COPY_MAX_RETRY
+ *
+ * Sync call used by SSBL (EL2) to copy RSU 'max retry' to ATF memory
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_RSU_COPY_MAX_RETRY
+ * a1 max retry
+ * a2-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ */
+#define INTEL_SIP_SMC_FUNCID_RSU_COPY_MAX_RETRY 19
+#define INTEL_SIP_SMC_RSU_COPY_MAX_RETRY \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_COPY_MAX_RETRY)
+
+/*
+ * Request INTEL_SIP_SMC_RSU_DCMF_STATUS
+ *
+ * Sync call used by service driver at EL1 to query DCMF status
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_RSU_DCMF_STATUS
+ * a1-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ * a1 dcmf3 status | dcmf2 status | dcmf1 status | dcmf0 status
+ *
+ * Or
+ *
+ * a0 INTEL_SIP_SMC_RSU_ERROR
+ */
+#define INTEL_SIP_SMC_FUNCID_RSU_DCMF_STATUS 20
+#define INTEL_SIP_SMC_RSU_DCMF_STATUS \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_DCMF_STATUS)
+
+/*
+ * Request INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS
+ *
+ * Sync call used by SSBL (EL2) to copy RSU 'dcmf status' to ATF memory
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS
+ * a1 dcmf status
+ * a2-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ */
+#define INTEL_SIP_SMC_FUNCID_RSU_COPY_DCMF_STATUS 21
+#define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_COPY_DCMF_STATUS)
+
+/*
+ * Request INTEL_SIP_SMC_HPS_SET_BRIDGES
+ *
+ * Enable/disable the SoC FPGA bridges
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_HPS_SET_BRIDGES
+ * a1 Set bridges status:
+ * 0 - Disable
+ * 1 - Enable
+ * a2-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ */
+#define INTEL_SIP_SMC_FUNCID_HPS_SET_BRIDGES 50
+#define INTEL_SIP_SMC_HPS_SET_BRIDGES \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_HPS_SET_BRIDGES)
+
+/*
+ * Request INTEL_SIP_SMC_MBOX_SEND_CMD
+ *
+ * Send mailbox command to SDM
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_MBOX_SEND_CMD
+ * a1 Mailbox command
+ * a2 64bit physical address pointer to command's arguments
+ * a3 Length of the argument
+ * a4 Urgent command:
+ * 0 - Disable
+ * 1 - Enable
+ * a5 64bit physical address pointer to a buffer for receiving responses
+ * a6 Length of the buffer
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_STATUS_ERROR
+ * a1 Status of mailbox response
+ * a2 Received length in the buffer
+ */
+#define INTEL_SIP_SMC_FUNCID_MBOX_SEND_CMD 60
+#define INTEL_SIP_SMC_MBOX_SEND_CMD \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_MBOX_SEND_CMD)
+
+/*
+ * Request INTEL_SIP_SMC_HPS_SET_PHYINTF
+ *
+ * Select EMACx PHY interface
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_HPS_SET_PHYINTF
+ * a1 EMAC number:
+ * 0 - EMAC0
+ * 1 - EMAC1
+ * 2 - EMAC2
+ * a2 Type of PHY interface:
+ * 0 - GMII_MII
+ * 1 - RGMII
+ * 2 - RMII
+ * 3 - RESET
+ * a3-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_STATUS_ERROR
+ */
+#define INTEL_SIP_SMC_FUNCID_HPS_SET_PHYINTF 61
+#define INTEL_SIP_SMC_HPS_SET_PHYINTF \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_HPS_SET_PHYINTF)
+
+/*
+ * Request INTEL_SIP_SMC_HPS_SET_SDMMC_CCLK
+ *
+ * Select which phase shift of the clocks (drvsel & smplsel) for SDMMC
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_HPS_SET_SDMMC_CCLK
+ * a1 Select which phase shift of the clock for cclk_in_drv (drvsel):
+ * 0 - 0 degree
+ * 1 - 45 degrees
+ * 2 - 90 degrees
+ * 3 - 135 degrees
+ * 4 - 180 degrees
+ * 5 - 225 degrees
+ * 6 - 270 degrees
+ * 7 - 315 degrees
+ * a2 Select which phase shift of the clock for cclk_in_sample (smplsel):
+ * (Same as above)
+ * a3-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ */
+#define INTEL_SIP_SMC_FUNCID_HPS_SET_SDMMC_CCLK 62
+#define INTEL_SIP_SMC_HPS_SET_SDMMC_CCLK \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_HPS_SET_SDMMC_CCLK)
+
+#endif
diff --git a/tools/socfpgaimage.c b/tools/socfpgaimage.c
index 3ba3c93..eba812f 100644
--- a/tools/socfpgaimage.c
+++ b/tools/socfpgaimage.c
@@ -61,6 +61,7 @@
#define HEADER_OFFSET 0x40
#define VALIDATION_WORD 0x31305341
+#define IMAGE_ALIGN 16
/* Minimum and default entry point offset */
#define ENTRY_POINT_OFFSET 0x14
@@ -97,7 +98,7 @@ static unsigned int sfp_hdr_size(uint8_t ver)
return 0;
}
-static unsigned int sfp_pad_size(uint8_t ver)
+static unsigned int sfp_max_size(uint8_t ver)
{
if (ver == 0)
return sizeof(buffer_v0);
@@ -106,6 +107,12 @@ static unsigned int sfp_pad_size(uint8_t ver)
return 0;
}
+static unsigned int sfp_aligned_len(uint32_t size)
+{
+ /* Add 4 bytes for CRC and align to 16 bytes */
+ return ALIGN(size + sizeof(uint32_t), IMAGE_ALIGN);
+}
+
/*
* The header checksum is just a very simple checksum over
* the header area.
@@ -208,22 +215,24 @@ static int sfp_sign_buffer(uint8_t *buf, uint8_t ver, uint8_t flags,
struct image_tool_params *params)
{
uint32_t calc_crc;
+ uint32_t crc_off;
/* Align the length up */
- len = ALIGN(len, 4);
+ len = sfp_aligned_len(len);
- /* Build header, adding 4 bytes to length to hold the CRC32. */
- sfp_build_header(buf + HEADER_OFFSET, ver, flags, len + 4, params);
+ /* Build header */
+ sfp_build_header(buf + HEADER_OFFSET, ver, flags, len, params);
/* Calculate and apply the CRC */
- calc_crc = ~pbl_crc32(0, (char *)buf, len);
+ crc_off = len - sizeof(uint32_t); /* at last 4 bytes of image */
+ calc_crc = ~pbl_crc32(0, (char *)buf, crc_off);
- *((uint32_t *)(buf + len)) = cpu_to_le32(calc_crc);
+ *((uint32_t *)(buf + crc_off)) = cpu_to_le32(calc_crc);
if (!pad_64k)
return len + 4;
- return sfp_pad_size(ver);
+ return sfp_max_size(ver);
}
/* Verify that the buffer looks sane */
@@ -240,7 +249,7 @@ static int sfp_verify_buffer(const uint8_t *buf)
return -1;
}
- if (len < HEADER_OFFSET || len > sfp_pad_size(ver)) {
+ if (len < HEADER_OFFSET || len > sfp_max_size(ver)) {
debug("Invalid header length (%i)\n", len);
return -1;
}
@@ -274,12 +283,51 @@ static int socfpgaimage_verify_header(unsigned char *ptr, int image_size,
return sfp_verify_buffer(ptr);
}
+static void socfpgaimage_print_header_v0(struct socfpga_header_v0 *header)
+{
+ printf("Image Type\t: Cyclone V / Arria V SoC Image\n");
+ printf("Validation word\t: 0x%08x\n",
+ le32_to_cpu(header->validation));
+ printf("Version\t\t: 0x%08x\n", header->version);
+ printf("Flags\t\t: 0x%08x\n", header->flags);
+ printf("Program length\t: 0x%08x\n",
+ le16_to_cpu(header->length_u32));
+ printf("Header checksum\t: 0x%08x\n",
+ le16_to_cpu(header->checksum));
+}
+
+static void socfpgaimage_print_header_v1(struct socfpga_header_v1 *header)
+{
+ printf("Image Type\t: Arria 10 SoC Image\n");
+ printf("Validation word\t: 0x%08x\n",
+ le32_to_cpu(header->validation));
+ printf("Version\t\t: 0x%08x\n", header->version);
+ printf("Flags\t\t: 0x%08x\n", header->flags);
+ printf("Header length\t: 0x%08x\n",
+ le16_to_cpu(header->header_u8));
+ printf("Program length\t: 0x%08x\n",
+ le32_to_cpu(header->length_u8));
+ printf("Program entry\t: 0x%08x\n",
+ le32_to_cpu(header->entry_offset));
+ printf("Header checksum\t: 0x%08x\n",
+ le16_to_cpu(header->checksum));
+}
+
static void socfpgaimage_print_header(const void *ptr)
{
- if (sfp_verify_buffer(ptr) == 0)
- printf("Looks like a sane SOCFPGA preloader\n");
- else
+ const void *header = ptr + HEADER_OFFSET;
+ struct socfpga_header_v0 *header_v0;
+
+ if (sfp_verify_buffer(ptr) == 0) {
+ header_v0 = (struct socfpga_header_v0 *)header;
+
+ if (header_v0->version == 0)
+ socfpgaimage_print_header_v0(header_v0);
+ else
+ socfpgaimage_print_header_v1((struct socfpga_header_v1 *)header);
+ } else {
printf("Not a sane SOCFPGA preloader\n");
+ }
}
static int socfpgaimage_check_params_v0(struct image_tool_params *params)
@@ -328,19 +376,25 @@ static int socfpgaimage_check_image_types_v1(uint8_t type)
* To work in with the mkimage framework, we do some ugly stuff...
*
* First, socfpgaimage_vrec_header() is called.
- * We prepend a fake header big enough to make the file sfp_pad_size().
+ * We prepend a fake header big enough to include crc32 and align image to 16
+ * bytes.
* This gives us enough space to do what we want later.
*
* Next, socfpgaimage_set_header() is called.
* We fix up the buffer by moving the image to the start of the buffer.
- * We now have some room to do what we need (add CRC and padding).
+ * We now have some room to do what we need (add CRC).
*/
static int data_size;
static int sfp_fake_header_size(unsigned int size, uint8_t ver)
{
- return sfp_pad_size(ver) - size;
+ unsigned int align_size;
+
+ align_size = sfp_aligned_len(size);
+
+ /* extra bytes needed */
+ return align_size - size;
}
static int sfp_vrec_header(struct image_tool_params *params,
@@ -350,7 +404,7 @@ static int sfp_vrec_header(struct image_tool_params *params,
if (params->datafile &&
stat(params->datafile, &sbuf) == 0 &&
- sbuf.st_size <= (sfp_pad_size(ver) - sizeof(uint32_t))) {
+ sbuf.st_size <= (sfp_max_size(ver) - sizeof(uint32_t))) {
data_size = sbuf.st_size;
tparams->header_size = sfp_fake_header_size(data_size, ver);
}
@@ -378,7 +432,7 @@ static void sfp_set_header(void *ptr, unsigned char ver,
/*
* This function is called after vrec_header() has been called.
* At this stage we have the sfp_fake_header_size() dummy bytes
- * followed by data_size image bytes. Total = sfp_pad_size().
+ * followed by data_size image bytes.
* We need to fix the buffer by moving the image bytes back to
* the beginning of the buffer, then actually do the signing stuff...
*/