summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--arch/arm/Kconfig3
-rw-r--r--arch/arm/dts/socfpga_agilex5-u-boot.dtsi17
-rw-r--r--arch/arm/dts/socfpga_agilex5_socdk-u-boot.dtsi26
-rw-r--r--arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi5
-rw-r--r--arch/arm/mach-socfpga/Makefile2
-rw-r--r--arch/arm/mach-socfpga/board.c13
-rw-r--r--arch/arm/mach-socfpga/include/mach/base_addr_soc64.h1
-rw-r--r--arch/arm/mach-socfpga/include/mach/mailbox_s10.h4
-rw-r--r--arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h18
-rw-r--r--arch/arm/mach-socfpga/mailbox_s10.c12
-rw-r--r--arch/arm/mach-socfpga/misc_soc64.c4
-rw-r--r--arch/arm/mach-socfpga/mmu-arm64_s10.c14
-rw-r--r--arch/arm/mach-socfpga/reset_manager_s10.c236
-rw-r--r--arch/arm/mach-socfpga/spl_agilex.c6
-rw-r--r--arch/arm/mach-socfpga/spl_agilex5.c6
-rw-r--r--arch/arm/mach-socfpga/spl_n5x.c6
-rw-r--r--arch/arm/mach-socfpga/spl_s10.c6
-rw-r--r--configs/socfpga_agilex5_defconfig6
-rw-r--r--configs/socfpga_agilex5_vab_defconfig3
-rw-r--r--drivers/ddr/altera/iossm_mailbox.c225
-rw-r--r--drivers/ddr/altera/iossm_mailbox.h11
-rw-r--r--drivers/ddr/altera/sdram_agilex5.c19
-rw-r--r--drivers/ddr/altera/sdram_soc64.c54
-rw-r--r--drivers/net/phy/Kconfig34
-rw-r--r--drivers/net/phy/Makefile1
-rw-r--r--drivers/net/phy/air_en8811h.c783
-rw-r--r--drivers/reset/reset-socfpga.c3
-rw-r--r--fs/exfat/io.c124
-rw-r--r--fs/exfat/lookup.c3
-rw-r--r--fs/fs.c1
-rw-r--r--fs/squashfs/sqfs.c10
-rw-r--r--include/exfat.h1
-rw-r--r--include/linux/intel-smc.h15
-rw-r--r--test/py/tests/test_fs/conftest.py2
-rw-r--r--test/py/tests/test_fs/test_basic.py13
36 files changed, 693 insertions, 995 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index a0b06e9ee24..9d5af7ebca4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -157,6 +157,7 @@ S: Maintained
T: git https://source.denx.de/u-boot/custodians/u-boot-socfpga.git
F: drivers/ddr/altera/
F: arch/arm/mach-socfpga/
+F: configs/socfpga_agilex5_vab_defconfig
F: drivers/sysreset/sysreset_socfpga*
ARM AMLOGIC SOC SUPPORT
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d8c99d3ab19..df373d38a55 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1138,6 +1138,7 @@ config ARCH_SOCFPGA
select DM_SERIAL
select GPIO_EXTRA_HEADER
select ENABLE_ARM_SOC_BOOT0_HOOK if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10
+ select LMB_ARCH_MEM_MAP if TARGET_SOCFPGA_SOC64
select OF_CONTROL
select SPL_DM_RESET if DM_RESET
select SPL_DM_SERIAL
@@ -1171,8 +1172,6 @@ config ARCH_SOCFPGA
imply SPL_DM_SPI_FLASH
imply SPL_LIBDISK_SUPPORT
imply SPL_MMC
- imply SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
- imply SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE
imply SPL_SPI_FLASH_SUPPORT
imply SPL_SPI
imply L2X0_CACHE
diff --git a/arch/arm/dts/socfpga_agilex5-u-boot.dtsi b/arch/arm/dts/socfpga_agilex5-u-boot.dtsi
index 8d6503dd091..874e71b5ca4 100644
--- a/arch/arm/dts/socfpga_agilex5-u-boot.dtsi
+++ b/arch/arm/dts/socfpga_agilex5-u-boot.dtsi
@@ -208,7 +208,8 @@
intel,offset-settings =
/* DMIUSMCTCR */
<0x00000300 0x00000001 0x00000003>,
- <0x00000300 0x00000003 0x00000003>;
+ <0x00000300 0x00000003 0x00000003>,
+ <0x00000308 0x00000004 0x0000001F>;
bootph-all;
};
@@ -218,7 +219,8 @@
intel,offset-settings =
/* DMIUSMCTCR */
<0x00000300 0x00000001 0x00000003>,
- <0x00000300 0x00000003 0x00000003>;
+ <0x00000300 0x00000003 0x00000003>,
+ <0x00000308 0x00000004 0x0000001F>;
bootph-all;
};
};
@@ -673,6 +675,17 @@
bootph-all;
};
+&gpio1 {
+ /* Configure GPIO 1 pin 3 as output pin with value 0 during GPIO probe */
+ portb: gpio-controller@0{
+ sdio_sel {
+ gpio-hog;
+ gpios = <3 GPIO_ACTIVE_HIGH>;
+ output-low;
+ };
+ };
+};
+
&i2c0 {
reset-names = "i2c";
};
diff --git a/arch/arm/dts/socfpga_agilex5_socdk-u-boot.dtsi b/arch/arm/dts/socfpga_agilex5_socdk-u-boot.dtsi
index d7ab58267eb..8d7dc0945ab 100644
--- a/arch/arm/dts/socfpga_agilex5_socdk-u-boot.dtsi
+++ b/arch/arm/dts/socfpga_agilex5_socdk-u-boot.dtsi
@@ -25,34 +25,44 @@
/*
* Both Memory base address and size default info is retrieved from HW setting.
* Reconfiguration / Overwrite these info can be done with examples below.
- */
- /*
+ *
+ * When LPDDR ECC is enabled, the last 1/8 of the memory region must
+ * be reserved for the Inline ECC buffer.
+ *
* Example for memory size with 2GB:
* memory {
* reg = <0x0 0x80000000 0x0 0x80000000>;
* };
- */
- /*
+ *
* Example for memory size with 8GB:
* memory {
* reg = <0x0 0x80000000 0x0 0x80000000>,
* <0x8 0x80000000 0x1 0x80000000>;
* };
- */
- /*
+ *
* Example for memory size with 32GB:
* memory {
* reg = <0x0 0x80000000 0x0 0x80000000>,
* <0x8 0x80000000 0x7 0x80000000>;
* };
- */
- /*
+ *
* Example for memory size with 512GB:
* memory {
* reg = <0x0 0x80000000 0x0 0x80000000>,
* <0x8 0x80000000 0x7 0x80000000>,
* <0x88 0x00000000 0x78 0x00000000>;
* };
+ *
+ * Example for memory size with 2GB with LPDDR Inline ECC ON:
+ * memory {
+ * reg = <0x0 0x80000000 0x0 0x70000000>;
+ * };
+ *
+ * Example for memory size with 8GB with LPDDR Inline ECC ON:
+ * memory {
+ * reg = <0x0 0x80000000 0x0 0x80000000>,
+ * <0x8 0x80000000 0x1 0x40000000>;
+ * };
*/
chosen {
diff --git a/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi b/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi
index 15306db6002..93a8e0697d6 100644
--- a/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi
+++ b/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi
@@ -106,8 +106,13 @@
arch = "arm64";
os = "linux";
compression = "none";
+ #if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5)
+ load = <0x86000000>;
+ entry = <0x86000000>;
+ #else
load = <0x6000000>;
entry = <0x6000000>;
+ #endif
kernel_blob: blob-ext {
filename = "Image";
};
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
index 22d48dfae1c..c43fdee4a48 100644
--- a/arch/arm/mach-socfpga/Makefile
+++ b/arch/arm/mach-socfpga/Makefile
@@ -68,6 +68,8 @@ obj-y += altera-sysmgr.o
obj-y += ccu_ncore3.o
obj-y += system_manager_soc64.o
obj-y += timer_s10.o
+obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH) += secure_vab.o
+obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH) += vab.o
endif
ifdef CONFIG_TARGET_SOCFPGA_N5X
diff --git a/arch/arm/mach-socfpga/board.c b/arch/arm/mach-socfpga/board.c
index 27072e53135..8506d510413 100644
--- a/arch/arm/mach-socfpga/board.c
+++ b/arch/arm/mach-socfpga/board.c
@@ -195,3 +195,16 @@ void board_prep_linux(struct bootm_headers *images)
}
}
#endif
+
+#if CONFIG_IS_ENABLED(LMB_ARCH_MEM_MAP)
+void lmb_arch_add_memory(void)
+{
+ int i;
+ struct bd_info *bd = gd->bd;
+
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ if (bd->bi_dram[i].size)
+ lmb_add(bd->bi_dram[i].start, bd->bi_dram[i].size);
+ }
+}
+#endif
diff --git a/arch/arm/mach-socfpga/include/mach/base_addr_soc64.h b/arch/arm/mach-socfpga/include/mach/base_addr_soc64.h
index 65721098b2b..5ac868a281b 100644
--- a/arch/arm/mach-socfpga/include/mach/base_addr_soc64.h
+++ b/arch/arm/mach-socfpga/include/mach/base_addr_soc64.h
@@ -51,6 +51,7 @@
#else
#define SOCFPGA_FW_MPU_DDR_SCR_ADDRESS 0xf8020100
#endif
+#define SOCFPGA_F2SDRAM_MGR_ADDRESS 0xf8024000
#define SOCFPGA_SMMU_ADDRESS 0xfa000000
#define SOCFPGA_MAILBOX_ADDRESS 0xffa30000
#define SOCFPGA_UART0_ADDRESS 0xffc02000
diff --git a/arch/arm/mach-socfpga/include/mach/mailbox_s10.h b/arch/arm/mach-socfpga/include/mach/mailbox_s10.h
index 45cc9912f94..2099c51b682 100644
--- a/arch/arm/mach-socfpga/include/mach/mailbox_s10.h
+++ b/arch/arm/mach-socfpga/include/mach/mailbox_s10.h
@@ -128,6 +128,7 @@ enum ALT_SDM_MBOX_RESP_CODE {
#define MBOX_QSPI_CLOSE 51
#define MBOX_QSPI_DIRECT 59
#define MBOX_REBOOT_HPS 71
+#define MBOX_HPS_STAGE_NOTIFY 93
/* Mailbox registers */
#define MBOX_CIN 0 /* command valid offset */
@@ -385,6 +386,8 @@ enum MBOX_CFGSTAT_MINOR_ERR_CODE {
#define RCF_SOFTFUNC_STATUS_SEU_ERROR BIT(3)
#define RCF_PIN_STATUS_NSTATUS BIT(31)
+#define HPS_EXECUTION_STATE_FSBL 0
+
int mbox_send_cmd(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg, u8 urgent,
u32 *resp_buf_len, u32 *resp_buf);
int mbox_send_cmd_psci(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg,
@@ -401,6 +404,7 @@ int mbox_qspi_open(void);
#endif
int mbox_reset_cold(void);
+int mbox_hps_stage_notify(u32 execution_stage);
int mbox_get_fpga_config_status(u32 cmd);
int mbox_get_fpga_config_status_psci(u32 cmd);
#endif /* _MAILBOX_S10_H_ */
diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h b/arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h
index 058fdd6e548..4b010be9ee8 100644
--- a/arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h
+++ b/arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h
@@ -10,9 +10,12 @@
void reset_deassert_peripherals_handoff(void);
int cpu_has_been_warmreset(void);
void print_reset_info(void);
-void socfpga_bridges_reset(int enable);
+void socfpga_bridges_reset(int enable, unsigned int mask);
#define RSTMGR_SOC64_STATUS 0x00
+#define RSTMGR_SOC64_HDSKEN 0x10
+#define RSTMGR_SOC64_HDSKREQ 0x14
+#define RSTMGR_SOC64_HDSKACK 0x18
#define RSTMGR_SOC64_MPUMODRST 0x20
#define RSTMGR_SOC64_PER0MODRST 0x24
#define RSTMGR_SOC64_PER1MODRST 0x28
@@ -20,8 +23,17 @@ void socfpga_bridges_reset(int enable);
#define RSTMGR_MPUMODRST_CORE0 0
#define RSTMGR_PER0MODRST_OCP_MASK 0x0020bf00
-#define RSTMGR_BRGMODRST_DDRSCH_MASK 0X00000040
-#define RSTMGR_BRGMODRST_FPGA2SOC_MASK 0x00000004
+
+#define RSTMGR_BRGMODRST_SOC2FPGA_MASK BIT(0)
+#define RSTMGR_BRGMODRST_LWSOC2FPGA_MASK BIT(1)
+#define RSTMGR_BRGMODRST_FPGA2SOC_MASK BIT(2)
+#define RSTMGR_BRGMODRST_F2SDRAM0_MASK BIT(3)
+#define RSTMGR_BRGMODRST_F2SDRAM1_MASK BIT(4)
+#define RSTMGR_BRGMODRST_F2SDRAM2_MASK BIT(5)
+#define RSTMGR_BRGMODRST_DDRSCH_MASK BIT(6)
+
+#define RSTMGR_HDSKEN_FPGAHSEN BIT(2)
+#define RSTMGR_HDSKREQ_FPGAHSREQ BIT(2)
/* SDM, Watchdogs and MPU warm reset mask */
#define RSTMGR_STAT_SDMWARMRST 0x2
diff --git a/arch/arm/mach-socfpga/mailbox_s10.c b/arch/arm/mach-socfpga/mailbox_s10.c
index b69bd3e47ec..f9c34e85711 100644
--- a/arch/arm/mach-socfpga/mailbox_s10.c
+++ b/arch/arm/mach-socfpga/mailbox_s10.c
@@ -6,6 +6,7 @@
#include <asm/arch/clock_manager.h>
#include <asm/arch/mailbox_s10.h>
+#include <asm/arch/smc_api.h>
#include <asm/arch/system_manager.h>
#include <asm/global_data.h>
#include <asm/io.h>
@@ -474,6 +475,17 @@ int __secure mbox_send_cmd_psci(u8 id, u32 cmd, u8 is_indirect, u32 len,
urgent, resp_buf_len, resp_buf);
}
+int mbox_hps_stage_notify(u32 execution_stage)
+{
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
+ return smc_send_mailbox(MBOX_HPS_STAGE_NOTIFY, 1, &execution_stage,
+ 0, 0, NULL);
+#else
+ return mbox_send_cmd(MBOX_ID_UBOOT, MBOX_HPS_STAGE_NOTIFY,
+ MBOX_CMD_DIRECT, 1, &execution_stage, 0, 0, NULL);
+#endif
+}
+
int mbox_send_cmd_only(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg)
{
return mbox_send_cmd_only_common(id, cmd, is_indirect, len, arg);
diff --git a/arch/arm/mach-socfpga/misc_soc64.c b/arch/arm/mach-socfpga/misc_soc64.c
index e0b2b4237e1..4f080f4f0b3 100644
--- a/arch/arm/mach-socfpga/misc_soc64.c
+++ b/arch/arm/mach-socfpga/misc_soc64.c
@@ -61,7 +61,7 @@ void save_boot_params(unsigned long r0, unsigned long r1, unsigned long r2,
#if defined(CONFIG_DISPLAY_CPUINFO)
int print_cpuinfo(void)
{
- printf("CPU: Intel FPGA SoCFPGA Platform (ARMv8 64bit Cortex-%s)\n",
+ printf("CPU: Altera FPGA SoCFPGA Platform (ARMv8 64bit Cortex-%s)\n",
IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5) ? "A55/A76" : "A53");
return 0;
@@ -107,5 +107,5 @@ void do_bridge_reset(int enable, unsigned int mask)
return;
}
- socfpga_bridges_reset(enable);
+ socfpga_bridges_reset(enable, mask);
}
diff --git a/arch/arm/mach-socfpga/mmu-arm64_s10.c b/arch/arm/mach-socfpga/mmu-arm64_s10.c
index b8e40d9a788..1dc44ab4797 100644
--- a/arch/arm/mach-socfpga/mmu-arm64_s10.c
+++ b/arch/arm/mach-socfpga/mmu-arm64_s10.c
@@ -58,6 +58,20 @@ static struct mm_region socfpga_agilex5_mem_map[] = {
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE,
}, {
+ /* MEM 30GB */
+ .virt = 0x880000000UL,
+ .phys = 0x880000000UL,
+ .size = 0x780000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE,
+ }, {
+ /* MEM 480GB */
+ .virt = 0x8800000000UL,
+ .phys = 0x8800000000UL,
+ .size = 0x7800000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE,
+ }, {
/* List terminator */
},
};
diff --git a/arch/arm/mach-socfpga/reset_manager_s10.c b/arch/arm/mach-socfpga/reset_manager_s10.c
index a634c11a028..abb62a9b49f 100644
--- a/arch/arm/mach-socfpga/reset_manager_s10.c
+++ b/arch/arm/mach-socfpga/reset_manager_s10.c
@@ -1,21 +1,34 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2016-2018 Intel Corporation <www.intel.com>
+ * Copyright (C) 2025 Altera Corporation <www.altera.com>
*
*/
+#include <errno.h>
#include <hang.h>
#include <asm/global_data.h>
#include <asm/io.h>
+#include <asm/secure.h>
#include <asm/arch/reset_manager.h>
#include <asm/arch/smc_api.h>
#include <asm/arch/system_manager.h>
+#include <asm/arch/timer.h>
#include <dt-bindings/reset/altr,rst-mgr-s10.h>
+#include <exports.h>
#include <linux/iopoll.h>
#include <linux/intel-smc.h>
+#include <wait_bit.h>
DECLARE_GLOBAL_DATA_PTR;
+#define TIMEOUT_300MS 300
+
+/* F2S manager registers */
+#define F2SDRAM_SIDEBAND_FLAGINSTATUS0 0x14
+#define F2SDRAM_SIDEBAND_FLAGOUTSET0 0x50
+#define F2SDRAM_SIDEBAND_FLAGOUTCLR0 0x54
+
/* Assert or de-assert SoCFPGA reset manager reset. */
void socfpga_per_reset(u32 reset, int set)
{
@@ -56,66 +69,213 @@ void socfpga_per_reset_all(void)
writel(0xffffffff, socfpga_get_rstmgr_addr() + RSTMGR_SOC64_PER1MODRST);
}
-void socfpga_bridges_reset(int enable)
+static void socfpga_f2s_bridges_reset(int enable, unsigned int mask)
{
-#if !defined(CONFIG_XPL_BUILD) && defined(CONFIG_SPL_ATF)
- u64 arg = enable;
+ int ret;
+ u32 brg_mask;
+ u32 flagout_idlereq = 0;
+ u32 flagoutset_fdrain = 0;
+ u32 flagoutset_en = 0;
+ u32 flaginstatus_idleack = 0;
+ u32 flaginstatus_respempty = 0;
+
+ if (CONFIG_IS_ENABLED(TARGET_SOCFPGA_STRATIX10)) {
+ /* Support fpga2soc and f2sdram */
+ brg_mask = mask & (RSTMGR_BRGMODRST_FPGA2SOC_MASK |
+ RSTMGR_BRGMODRST_F2SDRAM0_MASK |
+ RSTMGR_BRGMODRST_F2SDRAM1_MASK |
+ RSTMGR_BRGMODRST_F2SDRAM2_MASK);
- 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__);
+ if (brg_mask & RSTMGR_BRGMODRST_F2SDRAM0_MASK) {
+ flagout_idlereq |= BIT(0);
+ flaginstatus_idleack |= BIT(1);
+ flagoutset_fdrain |= BIT(2);
+ flagoutset_en |= BIT(1);
+ flaginstatus_respempty |= BIT(3);
+ }
+
+ if (brg_mask & RSTMGR_BRGMODRST_F2SDRAM1_MASK) {
+ flagout_idlereq |= BIT(3);
+ flaginstatus_idleack |= BIT(5);
+ flagoutset_fdrain |= BIT(5);
+ flagoutset_en |= BIT(4);
+ flaginstatus_respempty |= BIT(7);
+ }
+
+ if (brg_mask & RSTMGR_BRGMODRST_F2SDRAM2_MASK) {
+ flagout_idlereq |= BIT(6);
+ flaginstatus_idleack |= BIT(9);
+ flagoutset_fdrain |= BIT(8);
+ flagoutset_en |= BIT(7);
+ flaginstatus_respempty |= BIT(11);
+ }
+ } else {
+ /* Support fpga2soc only */
+ brg_mask = mask & RSTMGR_BRGMODRST_FPGA2SOC_MASK;
+ if (brg_mask & RSTMGR_BRGMODRST_FPGA2SOC_MASK) {
+ flagout_idlereq |= BIT(0);
+ flaginstatus_idleack |= BIT(1);
+ flagoutset_fdrain |= BIT(2);
+ flagoutset_en |= BIT(1);
+ flaginstatus_respempty |= BIT(3);
+ }
+ }
+
+ /* mask is not set, return here */
+ if (!brg_mask)
return;
+
+ if (enable) {
+ clrbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST,
+ brg_mask);
+ setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+ F2SDRAM_SIDEBAND_FLAGOUTCLR0,
+ flagout_idlereq);
+
+ /* Wait for mpfe noc idleack to 0 */
+ wait_for_bit_le32((u32 *)(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+ F2SDRAM_SIDEBAND_FLAGINSTATUS0),
+ flaginstatus_idleack, false, TIMEOUT_300MS, false);
+
+ setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+ F2SDRAM_SIDEBAND_FLAGOUTCLR0,
+ flagoutset_fdrain);
+ setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+ F2SDRAM_SIDEBAND_FLAGOUTSET0, flagoutset_en);
+
+ udelay(1); /* wait 1us */
+ } else {
+ if (readl((socfpga_get_rstmgr_addr() +
+ RSTMGR_SOC64_BRGMODRST) & brg_mask)) {
+ /* Bridge cannot be reset twice */
+ return;
+ }
+
+ setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_HDSKEN,
+ RSTMGR_HDSKEN_FPGAHSEN);
+ setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_HDSKREQ,
+ RSTMGR_HDSKREQ_FPGAHSREQ);
+
+ /* Wait for FPGA ack the handshake request to 1 */
+ wait_for_bit_le32((u32 *)(socfpga_get_rstmgr_addr() +
+ RSTMGR_SOC64_HDSKACK), RSTMGR_HDSKREQ_FPGAHSREQ,
+ true, TIMEOUT_300MS, false);
+
+ setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+ F2SDRAM_SIDEBAND_FLAGOUTCLR0, flagoutset_en);
+
+ udelay(1);
+
+ /* Requests MPFE NoC to idle */
+ setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+ F2SDRAM_SIDEBAND_FLAGOUTSET0, flagout_idlereq);
+
+ /* Force F2S bridge to drain */
+ setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+ F2SDRAM_SIDEBAND_FLAGOUTSET0, flagoutset_fdrain);
+
+ /* Wait for respond queue empty status to 1 (resp idle) */
+ ret = wait_for_bit_le32((u32 *)(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+ F2SDRAM_SIDEBAND_FLAGINSTATUS0),
+ flaginstatus_respempty, true,
+ TIMEOUT_300MS, false);
+
+ /* Confirm again */
+ if (!ret)
+ ret = wait_for_bit_le32((u32 *)
+ (SOCFPGA_F2SDRAM_MGR_ADDRESS +
+ F2SDRAM_SIDEBAND_FLAGINSTATUS0),
+ flaginstatus_respempty, true,
+ TIMEOUT_300MS, false);
+
+ setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST,
+ brg_mask & ~RSTMGR_BRGMODRST_FPGA2SOC_MASK);
+ clrbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_HDSKREQ,
+ RSTMGR_HDSKREQ_FPGAHSREQ);
+ setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+ F2SDRAM_SIDEBAND_FLAGOUTCLR0,
+ flagout_idlereq);
}
-#else
- u32 reg;
+}
+
+static void socfpga_s2f_bridges_reset(int enable, unsigned int mask)
+{
+ unsigned int noc_mask = 0;
+ unsigned int brg_mask = 0;
+
+ if (mask & RSTMGR_BRGMODRST_SOC2FPGA_MASK) {
+ noc_mask = SYSMGR_NOC_H2F_MSK;
+ brg_mask = RSTMGR_BRGMODRST_SOC2FPGA_MASK;
+ }
+
+ if (mask & RSTMGR_BRGMODRST_LWSOC2FPGA_MASK) {
+ noc_mask |= SYSMGR_NOC_LWH2F_MSK;
+ brg_mask |= RSTMGR_BRGMODRST_LWSOC2FPGA_MASK;
+ }
+
+ /* s2f mask is not set, return here */
+ if (!brg_mask)
+ return;
if (enable) {
/* clear idle request to all bridges */
setbits_le32(socfpga_get_sysmgr_addr() +
- SYSMGR_SOC64_NOC_IDLEREQ_CLR, ~0);
+ SYSMGR_SOC64_NOC_IDLEREQ_CLR, noc_mask);
- /* Release all bridges from reset state */
+ /* Release SOC2FPGA bridges from reset state */
clrbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST,
- ~0);
+ brg_mask);
- /* Poll until all idleack to 0 */
- read_poll_timeout(readl, reg, !reg, 1000, 300000,
- socfpga_get_sysmgr_addr() +
- SYSMGR_SOC64_NOC_IDLEACK);
+ /* Wait for all NOC master ack to 0 */
+ wait_for_bit_le32((u32 *)(socfpga_get_sysmgr_addr() +
+ SYSMGR_SOC64_NOC_IDLEACK), noc_mask, false,
+ TIMEOUT_300MS, false);
} else {
/* set idle request to all bridges */
- writel(~0,
- socfpga_get_sysmgr_addr() +
- SYSMGR_SOC64_NOC_IDLEREQ_SET);
+ setbits_le32(socfpga_get_sysmgr_addr() +
+ SYSMGR_SOC64_NOC_IDLEREQ_SET, noc_mask);
/* Enable the NOC timeout */
writel(1, socfpga_get_sysmgr_addr() + SYSMGR_SOC64_NOC_TIMEOUT);
- /* Poll until all idleack to 1 */
- read_poll_timeout(readl, reg,
- reg == (SYSMGR_NOC_H2F_MSK |
- SYSMGR_NOC_LWH2F_MSK),
- 1000, 300000,
- socfpga_get_sysmgr_addr() +
- SYSMGR_SOC64_NOC_IDLEACK);
-
- /* Poll until all idlestatus to 1 */
- read_poll_timeout(readl, reg,
- reg == (SYSMGR_NOC_H2F_MSK |
- SYSMGR_NOC_LWH2F_MSK),
- 1000, 300000,
- socfpga_get_sysmgr_addr() +
- SYSMGR_SOC64_NOC_IDLESTATUS);
-
- /* Reset all bridges (except NOR DDR scheduler & F2S) */
+ /* Wait for all NOC master ack to 1 */
+ wait_for_bit_le32((u32 *)(socfpga_get_sysmgr_addr() +
+ SYSMGR_SOC64_NOC_IDLEACK), noc_mask, true,
+ TIMEOUT_300MS, false);
+
+ /* Wait for all NOC master idlestatus to 1 */
+ wait_for_bit_le32((u32 *)(socfpga_get_sysmgr_addr() +
+ SYSMGR_SOC64_NOC_IDLESTATUS), noc_mask, true,
+ TIMEOUT_300MS, false);
+
+ /* Reset all SOC2FPGA bridges */
setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST,
- ~(RSTMGR_BRGMODRST_DDRSCH_MASK |
- RSTMGR_BRGMODRST_FPGA2SOC_MASK));
+ brg_mask);
/* Disable NOC timeout */
writel(0, socfpga_get_sysmgr_addr() + SYSMGR_SOC64_NOC_TIMEOUT);
}
-#endif
+}
+
+void socfpga_bridges_reset(int enable, unsigned int mask)
+{
+ if (!IS_ENABLED(CONFIG_XPL_BUILD) && IS_ENABLED(CONFIG_SPL_ATF)) {
+ u64 arg[2];
+ int ret;
+
+ /* Set bit-1 to indicate has mask value in arg[1]. */
+ arg[0] = (enable & BIT(0)) | BIT(1);
+ arg[1] = mask;
+
+ ret = invoke_smc(INTEL_SIP_SMC_HPS_SET_BRIDGES, arg,
+ ARRAY_SIZE(arg), NULL, 0);
+ if (ret)
+ printf("Failed to %s the HPS bridges, check bridges availability. Status %d.\n",
+ enable ? "enable" : "disable", ret);
+ } else {
+ socfpga_s2f_bridges_reset(enable, mask);
+ socfpga_f2s_bridges_reset(enable, mask);
+ }
}
/*
diff --git a/arch/arm/mach-socfpga/spl_agilex.c b/arch/arm/mach-socfpga/spl_agilex.c
index 52617a39cca..91c27a5543d 100644
--- a/arch/arm/mach-socfpga/spl_agilex.c
+++ b/arch/arm/mach-socfpga/spl_agilex.c
@@ -50,6 +50,10 @@ void board_init_f(ulong dummy)
timer_init();
+ mbox_init();
+
+ mbox_hps_stage_notify(HPS_EXECUTION_STATE_FSBL);
+
sysmgr_pinmux_init();
ret = uclass_get_device(UCLASS_CLK, 0, &dev);
@@ -77,8 +81,6 @@ void board_init_f(ulong dummy)
}
#endif
- mbox_init();
-
#ifdef CONFIG_CADENCE_QSPI
mbox_qspi_open();
#endif
diff --git a/arch/arm/mach-socfpga/spl_agilex5.c b/arch/arm/mach-socfpga/spl_agilex5.c
index 3451611082d..a9aad5350d2 100644
--- a/arch/arm/mach-socfpga/spl_agilex5.c
+++ b/arch/arm/mach-socfpga/spl_agilex5.c
@@ -62,6 +62,10 @@ void board_init_f(ulong dummy)
timer_init();
+ mbox_init();
+
+ mbox_hps_stage_notify(HPS_EXECUTION_STATE_FSBL);
+
ret = uclass_get_device(UCLASS_CLK, 0, &dev);
if (ret) {
debug("Clock init failed: %d\n", ret);
@@ -100,8 +104,6 @@ void board_init_f(ulong dummy)
}
}
- mbox_init();
-
if (IS_ENABLED(CONFIG_CADENCE_QSPI))
mbox_qspi_open();
diff --git a/arch/arm/mach-socfpga/spl_n5x.c b/arch/arm/mach-socfpga/spl_n5x.c
index 5ff137e5c6f..81283ef7162 100644
--- a/arch/arm/mach-socfpga/spl_n5x.c
+++ b/arch/arm/mach-socfpga/spl_n5x.c
@@ -49,6 +49,10 @@ void board_init_f(ulong dummy)
timer_init();
+ mbox_init();
+
+ mbox_hps_stage_notify(HPS_EXECUTION_STATE_FSBL);
+
sysmgr_pinmux_init();
preloader_console_init();
@@ -84,8 +88,6 @@ void board_init_f(ulong dummy)
}
#endif
- mbox_init();
-
#ifdef CONFIG_CADENCE_QSPI
mbox_qspi_open();
#endif
diff --git a/arch/arm/mach-socfpga/spl_s10.c b/arch/arm/mach-socfpga/spl_s10.c
index 53852cb7443..fa83ff96adc 100644
--- a/arch/arm/mach-socfpga/spl_s10.c
+++ b/arch/arm/mach-socfpga/spl_s10.c
@@ -52,6 +52,10 @@ void board_init_f(ulong dummy)
socfpga_per_reset(SOCFPGA_RESET(OSC1TIMER0), 0);
timer_init();
+ mbox_init();
+
+ mbox_hps_stage_notify(HPS_EXECUTION_STATE_FSBL);
+
sysmgr_pinmux_init();
/* configuring the HPS clocks */
@@ -84,8 +88,6 @@ void board_init_f(ulong dummy)
}
#endif
- mbox_init();
-
#ifdef CONFIG_CADENCE_QSPI
mbox_qspi_open();
#endif
diff --git a/configs/socfpga_agilex5_defconfig b/configs/socfpga_agilex5_defconfig
index 8f327e5f2ab..4ac0a5d9b99 100644
--- a/configs/socfpga_agilex5_defconfig
+++ b/configs/socfpga_agilex5_defconfig
@@ -1,6 +1,7 @@
CONFIG_ARM=y
CONFIG_ARCH_SOCFPGA=y
CONFIG_TEXT_BASE=0x80200000
+CONFIG_SPL_GPIO=y
CONFIG_NR_DRAM_BANKS=3
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80300000
@@ -31,6 +32,8 @@ CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyS0,115200 initrd=0x90000000 root=/dev/ram0 rw init=/sbin/init ramdisk_size=10000000 earlycon panic=-1 nosmp kvm-arm.mode=nvhe"
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_BLOBLIST=y
+CONFIG_BLOBLIST_FIXED=y
+CONFIG_BLOBLIST_ADDR=0x7e000
CONFIG_BLOBLIST_SIZE=0x1000
CONFIG_SPL_MAX_SIZE=0x40000
CONFIG_HANDOFF=y
@@ -73,6 +76,8 @@ CONFIG_BOOTFILE="kernel.itb"
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_SPL_ALTERA_SDRAM=y
+CONFIG_GPIO_HOG=y
+CONFIG_SPL_GPIO_HOG=y
CONFIG_DWAPB_GPIO=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_DW=y
@@ -82,6 +87,7 @@ CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY_MARVELL=y
CONFIG_DWC_ETH_XGMAC=y
CONFIG_RGMII=y
CONFIG_SYS_NS16550_MEM32=y
diff --git a/configs/socfpga_agilex5_vab_defconfig b/configs/socfpga_agilex5_vab_defconfig
new file mode 100644
index 00000000000..a5f4b335760
--- /dev/null
+++ b/configs/socfpga_agilex5_vab_defconfig
@@ -0,0 +1,3 @@
+#include <configs/socfpga_agilex5_defconfig>
+
+CONFIG_SOCFPGA_SECURE_VAB_AUTH=y
diff --git a/drivers/ddr/altera/iossm_mailbox.c b/drivers/ddr/altera/iossm_mailbox.c
index db9435db657..fc09dde3f9e 100644
--- a/drivers/ddr/altera/iossm_mailbox.c
+++ b/drivers/ddr/altera/iossm_mailbox.c
@@ -10,6 +10,7 @@
#include <asm/arch/base_addr_soc64.h>
#include <asm/io.h>
#include <linux/bitfield.h>
+#include <linux/sizes.h>
#include "iossm_mailbox.h"
#define TIMEOUT_120000MS 120000
@@ -87,6 +88,7 @@
/* offset info of ECC_ENABLE_INTF */
#define INTF_ECC_ENABLE_TYPE_MASK GENMASK(1, 0)
+#define INTF_ECC_TYPE_MASK BIT(8)
/* cmd opcode BIST_MEM_INIT_START, BIST performed on full memory address range */
#define BIST_FULL_MEM BIT(6)
@@ -96,6 +98,7 @@
/* offset info of ECC_ERR_STATUS */
#define ECC_ERR_COUNTER_MASK GENMASK(15, 0)
+#define ECC_ERR_OVERFLOW_MASK GENMASK(31, 16)
/* offset info of ECC_ERR_DATA */
#define ECC_ERR_IP_TYPE_MASK GENMASK(24, 22)
@@ -104,9 +107,15 @@
#define ECC_ERR_TYPE_MASK GENMASK(9, 6)
#define ECC_ERR_ADDR_UPPER_MASK GENMASK(5, 0)
#define ECC_ERR_ADDR_LOWER_MASK GENMASK(31, 0)
+#define ECC_FULL_ADDR_UPPER_MASK GENMASK(63, 32)
+#define ECC_FULL_ADDR_LOWER_MASK GENMASK(31, 0)
#define MAX_ECC_ERR_INFO_COUNT 16
+#define BIST_START_ADDR_SPACE_MASK GENMASK(5, 0)
+#define BIST_START_ADDR_LOW_MASK GENMASK(31, 0)
+#define BIST_START_ADDR_HIGH_MASK GENMASK(37, 32)
+
#define IO96B_MB_REQ_SETUP(v, w, x, y, z) \
usr_req.ip_type = v; \
usr_req.ip_id = w; \
@@ -161,6 +170,24 @@ struct ecc_err_info {
u32 addr_lower;
};
+struct ecc_overflow_error_desc {
+ int bit;
+ const char *msg;
+};
+
+static const struct ecc_overflow_error_desc ecc_overflow_errors[] = {
+ { 0, " - Single-bit error\n" },
+ { 1, " - Multiple single-bit errors\n" },
+ { 2, " - Double-bit error\n" },
+ { 3, " - Multiple double-bit errors\n" },
+ { 8, " - Single-bit error during ECC scrubbing\n" },
+ { 9, " - Write link ECC single-bit error (LPDDR5 only)\n" },
+ { 10, " - Write link ECC double-bit error (LPDDR5 only)\n" },
+ { 11, " - Read link ECC single-bit error (LPDDR5 only)\n" },
+ { 12, " - Read link ECC double-bit error (LPDDR5 only)\n" },
+ { 13, " - RMW read link ECC double-bit error (LPDDR5 only)\n" },
+};
+
static int is_ddr_csr_clkgen_locked(u8 io96b_pll)
{
int ret = 0;
@@ -512,7 +539,7 @@ int get_mem_width_info(struct io96b_info *io96b_ctrl)
{
int i, j, ret = 0;
u32 mem_width_info;
- u16 memory_size, total_memory_size = 0;
+ phys_size_t memory_size, total_memory_size = 0;
u32 mem_total_capacity_intf_offset[MAX_MEM_INTERFACE_SUPPORTED] = {
IOSSM_MEM_TOTAL_CAPACITY_INTF0_OFFSET,
@@ -526,8 +553,11 @@ int get_mem_width_info(struct io96b_info *io96b_ctrl)
mem_width_info = readl(io96b_ctrl->io96b[i].io96b_csr_addr +
mem_total_capacity_intf_offset[j]);
- memory_size = memory_size +
- FIELD_GET(INTF_CAPACITY_GBITS_MASK, mem_width_info);
+ io96b_ctrl->io96b[i].mb_ctrl.memory_size[j] =
+ FIELD_GET(INTF_CAPACITY_GBITS_MASK, mem_width_info) * SZ_1G / SZ_8;
+
+ if (io96b_ctrl->io96b[i].mb_ctrl.memory_size[j] != 0)
+ memory_size += io96b_ctrl->io96b[i].mb_ctrl.memory_size[j];
}
if (!memory_size) {
@@ -536,8 +566,6 @@ int get_mem_width_info(struct io96b_info *io96b_ctrl)
goto err;
}
- io96b_ctrl->io96b[i].size = memory_size;
-
total_memory_size = total_memory_size + memory_size;
}
@@ -556,7 +584,7 @@ int ecc_enable_status(struct io96b_info *io96b_ctrl)
{
int i, j, ret = 0;
u32 ecc_enable_intf;
- bool ecc_stat, ecc_stat_set = false;
+ bool ecc_status, ecc_status_set = false, inline_ecc = false;
u32 ecc_enable_intf_offset[MAX_MEM_INTERFACE_SUPPORTED] = {
IOSSM_ECC_ENABLE_INTF0_OFFSET,
@@ -565,6 +593,7 @@ int ecc_enable_status(struct io96b_info *io96b_ctrl)
/* Initialize ECC status */
io96b_ctrl->ecc_status = false;
+ io96b_ctrl->inline_ecc = false;
/* Get and ensure all memory interface(s) same ECC status */
for (i = 0; i < io96b_ctrl->num_instance; i++) {
@@ -572,15 +601,21 @@ int ecc_enable_status(struct io96b_info *io96b_ctrl)
ecc_enable_intf = readl(io96b_ctrl->io96b[i].io96b_csr_addr +
ecc_enable_intf_offset[j]);
- ecc_stat = (FIELD_GET(INTF_ECC_ENABLE_TYPE_MASK, ecc_enable_intf)
+ ecc_status = (FIELD_GET(INTF_ECC_ENABLE_TYPE_MASK, ecc_enable_intf)
== 0) ? false : true;
+ inline_ecc = FIELD_GET(INTF_ECC_TYPE_MASK, ecc_enable_intf);
+
+ if (!ecc_status_set) {
+ io96b_ctrl->ecc_status = ecc_status;
+
+ if (io96b_ctrl->ecc_status)
+ io96b_ctrl->inline_ecc = inline_ecc;
- if (!ecc_stat_set) {
- io96b_ctrl->ecc_status = ecc_stat;
- ecc_stat_set = true;
+ ecc_status_set = true;
}
- if (ecc_stat != io96b_ctrl->ecc_status) {
+ if (ecc_status != io96b_ctrl->ecc_status ||
+ (io96b_ctrl->ecc_status && inline_ecc != io96b_ctrl->inline_ecc)) {
printf("%s: Mismatch DDR ECC status on IO96B_%d\n", __func__, i);
ret = -EINVAL;
@@ -614,16 +649,28 @@ bool ecc_interrupt_status(struct io96b_info *io96b_ctrl)
{
int i, j;
u32 ecc_err_status;
- u16 ecc_err_counter;
+ u16 ecc_err_counter, ecc_overflow_status;
bool ecc_error_flag = false;
/* Get ECC double-bit error status */
for (i = 0; i < io96b_ctrl->num_instance; i++) {
ecc_err_status = readl(io96b_ctrl->io96b[i].io96b_csr_addr +
IOSSM_ECC_ERR_STATUS_OFFSET);
+
ecc_err_counter = FIELD_GET(ECC_ERR_COUNTER_MASK, ecc_err_status);
- debug("%s: ECC error number detected on IO96B_%d: %d\n",
- __func__, i, ecc_err_counter);
+ log_err("%s: ECC error number detected on IO96B_%d: %d\n",
+ __func__, i, ecc_err_counter);
+
+ ecc_overflow_status = FIELD_GET(ECC_ERR_OVERFLOW_MASK, ecc_err_status);
+ if (ecc_overflow_status != 0) {
+ log_err("ECC Error Overflow Flags:\n");
+
+ for (int i = 0; i < ARRAY_SIZE(ecc_overflow_errors); i++) {
+ if (ecc_overflow_status & BIT(ecc_overflow_errors[i].bit)) {
+ log_err("%s", ecc_overflow_errors[i].msg);
+ }
+ }
+ }
if (ecc_err_counter != 0) {
phys_addr_t address;
@@ -647,15 +694,20 @@ bool ecc_interrupt_status(struct io96b_info *io96b_ctrl)
ecc_err_data);
err_info.addr_lower = readl(address + sizeof(u32));
- debug("%s: ECC double-bit error detected on IO96B_%d:\n",
- __func__, i);
- debug("- error info address :0x%llx\n", address);
- debug("- error ip type: %d\n", err_info.ip_type);
- debug("- error instance id: %d\n", err_info.instance_id);
- debug("- error source id: %d\n", err_info.source_id);
- debug("- error type: %d\n", err_info.err_type);
- debug("- error address upper: 0x%x\n", err_info.addr_upper);
- debug("- error address lower: 0x%x\n", err_info.addr_lower);
+ log_err(" %s: DDR ECC Error Detected on IO96B_%d number:%d\n",
+ __func__, i, j);
+ log_err(" - error info address :0x%llx\n", address);
+ log_err(" - error ip type: %d\n", err_info.ip_type);
+ log_err(" - error instance id: %d\n", err_info.instance_id);
+ log_err(" - error source id: %d\n", err_info.source_id);
+ log_err(" - error type: %s\n",
+ is_double_bit_error(err_info.err_type) ?
+ "Double-bit error" : "Single-bit error");
+ log_err(" - error address: 0x%016llx\n",
+ (u64)FIELD_PREP(ECC_FULL_ADDR_UPPER_MASK,
+ err_info.addr_upper) |
+ FIELD_PREP(ECC_FULL_ADDR_LOWER_MASK,
+ err_info.addr_lower));
if (is_double_bit_error(err_info.err_type)) {
if (!ecc_error_flag)
@@ -668,12 +720,12 @@ bool ecc_interrupt_status(struct io96b_info *io96b_ctrl)
}
if (ecc_error_flag)
- printf("\n%s: ECC double-bit error detected!\n", __func__);
+ log_err("\n%s: ECC double-bit error detected!\n", __func__);
return ecc_error_flag;
}
-int bist_mem_init_start(struct io96b_info *io96b_ctrl)
+int out_of_band_bist_mem_init_start(struct io96b_info *io96b_ctrl)
{
struct io96b_mb_req usr_req;
struct io96b_mb_resp usr_resp;
@@ -746,3 +798,126 @@ int bist_mem_init_start(struct io96b_info *io96b_ctrl)
err:
return ret;
}
+
+int bist_mem_init_by_addr(struct io96b_info *io96b_ctrl, int inst_id, int intf_id,
+ phys_addr_t base_addr, phys_size_t size)
+{
+ struct io96b_mb_req usr_req;
+ struct io96b_mb_resp usr_resp;
+ int n, ret = 0;
+ bool bist_start, bist_success;
+ u32 mem_exp, mem_init_status_intf, start;
+ phys_size_t chunk_size;
+
+ u32 mem_init_status_offset[MAX_MEM_INTERFACE_SUPPORTED] = {
+ IOSSM_MEM_INIT_STATUS_INTF0_OFFSET,
+ IOSSM_MEM_INIT_STATUS_INTF1_OFFSET
+ };
+
+ /* Check if size is a power of 2 */
+ if (size == 0 || (size & (size - 1)) != 0) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ mem_exp = 0;
+ chunk_size = size;
+
+ while (chunk_size >>= 1)
+ mem_exp++;
+
+ /* Start memory initialization BIST on the specified address range */
+ IO96B_MB_REQ_SETUP(io96b_ctrl->io96b[inst_id].mb_ctrl.ip_type[intf_id],
+ io96b_ctrl->io96b[inst_id].mb_ctrl.ip_id[intf_id],
+ CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_START, 0);
+
+ /* CMD_PARAM_0 bit[5:0] = mem_exp */
+ /* CMD_PARAM_0 bit[6]: 0 - on the specified address range */
+ usr_req.cmd_param[0] = FIELD_PREP(BIST_START_ADDR_SPACE_MASK, mem_exp);
+ /* Extract address fields START_ADDR[31:0] */
+ usr_req.cmd_param[1] = FIELD_GET(BIST_START_ADDR_LOW_MASK, base_addr);
+ /* Extract address fields START_ADDR[37:32] */
+ usr_req.cmd_param[2] = FIELD_GET(BIST_START_ADDR_HIGH_MASK, base_addr);
+ /* Initialize memory to all zeros */
+ usr_req.cmd_param[3] = 0;
+
+ bist_start = false;
+ bist_success = false;
+
+ /* Send request to DDR controller */
+ debug("%s:Initializing memory: Addr=0x%llx, Size=2^%u\n", __func__,
+ base_addr, mem_exp);
+ ret = io96b_mb_req(io96b_ctrl->io96b[inst_id].io96b_csr_addr,
+ usr_req, 0, &usr_resp);
+ if (ret)
+ goto err;
+
+ bist_start = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+ & BIT(0);
+
+ if (!bist_start) {
+ printf("%s: Failed to initialize memory on IO96B_%d\n", __func__,
+ inst_id);
+ printf("%s: BIST_MEM_INIT_START Error code 0x%lx\n", __func__,
+ IOSSM_STATUS_CMD_RESPONSE_ERROR(usr_resp.cmd_resp_status));
+
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /* Polling for the initiated memory initialization BIST status */
+ start = get_timer(0);
+ while (!bist_success) {
+ udelay(1);
+
+ mem_init_status_intf = readl(io96b_ctrl->io96b[inst_id].io96b_csr_addr +
+ mem_init_status_offset[intf_id]);
+
+ bist_success = FIELD_GET(INTF_BIST_STATUS_MASK, mem_init_status_intf);
+
+ if (!bist_success && (get_timer(start) > TIMEOUT)) {
+ printf("%s: Timeout initialize memory on IO96B_%d\n",
+ __func__, inst_id);
+ printf("%s: BIST_MEM_INIT_STATUS Error code 0x%lx\n",
+ __func__,
+ IOSSM_STATUS_CMD_RESPONSE_ERROR(usr_resp.cmd_resp_status));
+
+ ret = -ETIMEDOUT;
+ goto err;
+ }
+ }
+
+ debug("%s:DDR memory initializationat 0x%llx completed.\n", __func__, base_addr);
+
+err:
+ return ret;
+}
+
+int inline_ecc_bist_mem_init(struct io96b_info *io96b_ctrl)
+{
+ int i, j, ret = 0;
+
+ /* Memory initialization BIST performed on all memory interfaces */
+ for (i = 0; i < io96b_ctrl->num_instance; i++) {
+ for (j = 0; j < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; j++) {
+ ret = bist_mem_init_by_addr(io96b_ctrl, i, j, 0,
+ io96b_ctrl->io96b[i].mb_ctrl.memory_size[j]);
+ if (ret) {
+ printf("Error: Memory init failed at Instance %d, Interface %d\n",
+ i, j);
+ goto err;
+ }
+ }
+ }
+
+err:
+ return ret;
+}
+
+int bist_mem_init_start(struct io96b_info *io96b_ctrl)
+{
+ if (io96b_ctrl->inline_ecc)
+ return inline_ecc_bist_mem_init(io96b_ctrl);
+ else
+ return out_of_band_bist_mem_init_start(io96b_ctrl);
+}
diff --git a/drivers/ddr/altera/iossm_mailbox.h b/drivers/ddr/altera/iossm_mailbox.h
index 6f794781d30..02d1db28e20 100644
--- a/drivers/ddr/altera/iossm_mailbox.h
+++ b/drivers/ddr/altera/iossm_mailbox.h
@@ -40,11 +40,13 @@ enum iossm_mailbox_cmd_opcode {
* @num_mem_interface: Number of memory interfaces instantiated
* @ip_type: IP type implemented on the IO96B
* @ip_instance_id: IP identifier for every IP instance implemented on the IO96B
+ * @memory_size[2]: Memory size for every IP instance implemented on the IO96B
*/
struct io96b_mb_ctrl {
u32 num_mem_interface;
u32 ip_type[2];
u32 ip_id[2];
+ phys_size_t memory_size[2];
};
/* CMD_REQ Register Definition */
@@ -53,6 +55,9 @@ struct io96b_mb_ctrl {
#define CMD_TYPE_MASK GENMASK(23, 16)
#define CMD_OPCODE_MASK GENMASK(15, 0)
+/* Computes the Inline ECC data region size */
+#define CALC_INLINE_ECC_HW_SIZE(size) (((size) * 7) / 8)
+
/*
* IOSSM mailbox request
* @ip_type: IP type for the specified memory interface
@@ -83,13 +88,11 @@ struct io96b_mb_resp {
/*
* IO96B instance specific information
*
- * @size: Memory size
* @io96b_csr_addr: IO96B instance CSR address
* @cal_status: IO96B instance calibration status
* @mb_ctrl: IOSSM mailbox required information
*/
struct io96b_instance {
- u16 size;
phys_addr_t io96b_csr_addr;
bool cal_status;
struct io96b_mb_ctrl mb_ctrl;
@@ -102,6 +105,7 @@ struct io96b_instance {
* @overall_cal_status: Overall calibration status for all IO96B instance(s)
* @ddr_type: DDR memory type
* @ecc_status: ECC enable status (false = disabled, true = enabled)
+ * @inline_ecc: Inline ECC or Out of Band ECC (false = Out of Band ECC, true = Inline ECC)
* @overall_size: Total DDR memory size
* @io96b[]: IO96B instance specific information
* @ckgen_lock: IO96B GEN PLL lock (false = not locked, true = locked)
@@ -115,7 +119,8 @@ struct io96b_info {
bool overall_cal_status;
const char *ddr_type;
bool ecc_status;
- u16 overall_size;
+ bool inline_ecc;
+ phys_size_t overall_size;
struct io96b_instance io96b[MAX_IO96B_SUPPORTED];
bool ckgen_lock;
u8 num_port;
diff --git a/drivers/ddr/altera/sdram_agilex5.c b/drivers/ddr/altera/sdram_agilex5.c
index 801a6bbab46..ee66c72157a 100644
--- a/drivers/ddr/altera/sdram_agilex5.c
+++ b/drivers/ddr/altera/sdram_agilex5.c
@@ -291,7 +291,14 @@ int sdram_mmr_init_full(struct udevice *dev)
goto err;
}
- hw_size = (phys_size_t)io96b_ctrl->overall_size * SZ_1G / SZ_8;
+ ret = ecc_enable_status(io96b_ctrl);
+ if (ret) {
+ printf("DDR: Failed to get ECC enabled status\n");
+
+ goto err;
+ }
+
+ hw_size = io96b_ctrl->overall_size;
/* Get bank configuration from devicetree */
ret = fdtdec_decode_ram_size(gd->fdt_blob, NULL, 0, NULL,
@@ -303,6 +310,9 @@ int sdram_mmr_init_full(struct udevice *dev)
goto err;
}
+ if (io96b_ctrl->inline_ecc)
+ hw_size = CALC_INLINE_ECC_HW_SIZE(hw_size);
+
if (gd->ram_size > hw_size) {
printf("DDR: Warning: DRAM size from device tree (%lld MiB) exceeds\n",
gd->ram_size >> 20);
@@ -355,13 +365,6 @@ int sdram_mmr_init_full(struct udevice *dev)
printf("%s: %lld MiB\n", io96b_ctrl->ddr_type, gd->ram_size >> 20);
- ret = ecc_enable_status(io96b_ctrl);
- if (ret) {
- printf("DDR: Failed to get ECC enabled status\n");
-
- goto err;
- }
-
/* Is HPS cold or warm reset? If yes, Skip full memory initialization if ECC
* enabled to preserve memory content
*/
diff --git a/drivers/ddr/altera/sdram_soc64.c b/drivers/ddr/altera/sdram_soc64.c
index c8c9211adce..27fbe80ed41 100644
--- a/drivers/ddr/altera/sdram_soc64.c
+++ b/drivers/ddr/altera/sdram_soc64.c
@@ -185,35 +185,51 @@ void sdram_init_ecc_bits(struct bd_info *bd)
void sdram_size_check(struct bd_info *bd)
{
phys_size_t total_ram_check = 0;
- phys_size_t ram_check = 0;
- phys_addr_t start = 0;
- phys_size_t size, remaining_size;
int bank;
/* Sanity check ensure correct SDRAM size specified */
debug("DDR: Running SDRAM size sanity check\n");
for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
+ phys_size_t ram_check = 0;
+ phys_addr_t start = 0;
+ phys_size_t remaining_size;
+
start = bd->bi_dram[bank].start;
remaining_size = bd->bi_dram[bank].size;
+ debug("Checking bank %d: start=0x%llx, size=0x%llx\n",
+ bank, start, remaining_size);
+
while (ram_check < bd->bi_dram[bank].size) {
- size = min((phys_addr_t)SZ_1G,
- (phys_addr_t)remaining_size);
-
- /*
- * Ensure the size is power of two, this is requirement
- * to run get_ram_size() / memory test
- */
- if (size != 0 && ((size & (size - 1)) == 0)) {
- ram_check += get_ram_size((void *)
- (start + ram_check), size);
- remaining_size = bd->bi_dram[bank].size -
- ram_check;
- } else {
- puts("DDR: Memory test requires SDRAM size ");
- puts("in power of two!\n");
+ phys_size_t size, test_size, detected_size;
+
+ size = min((phys_addr_t)SZ_1G, (phys_addr_t)remaining_size);
+
+ if (size < SZ_8) {
+ puts("Invalid size: Memory size required to be multiple\n");
+ puts("of 64-Bit word!\n");
hang();
}
+
+ /* Adjust size to the nearest power of two to support get_ram_size() */
+ test_size = SZ_8;
+
+ while (test_size * 2 <= size)
+ test_size *= 2;
+
+ debug("Testing memory at 0x%llx with size 0x%llx\n",
+ start + ram_check, test_size);
+ detected_size = get_ram_size((void *)(start + ram_check), test_size);
+
+ if (detected_size != test_size) {
+ debug("Detected size 0x%llx doesn’t match the test size 0x%llx!\n",
+ detected_size, test_size);
+ puts("Memory testing failed!\n");
+ hang();
+ }
+
+ ram_check += detected_size;
+ remaining_size = bd->bi_dram[bank].size - ram_check;
}
total_ram_check += ram_check;
@@ -249,7 +265,7 @@ phys_size_t sdram_calculate_size(struct altera_sdram_plat *plat)
DRAMADDRW_CFG_ROW_ADDR_WIDTH(dramaddrw) +
DRAMADDRW_CFG_COL_ADDR_WIDTH(dramaddrw));
- size *= (2 << (hmc_ecc_readl(plat, DDRIOCTRL) &
+ size *= ((phys_size_t)2 << (hmc_ecc_readl(plat, DDRIOCTRL) &
DDR_HMC_DDRIOCTRL_IOSIZE_MSK));
return size;
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 5b4cf30b0a3..3132718e4f8 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -79,40 +79,6 @@ config PHY_ADIN
help
Add support for configuring RGMII on Analog Devices ADIN PHYs.
-menuconfig PHY_AIROHA
- bool "Airoha Ethernet PHYs support"
-
-config PHY_AIROHA_EN8811H
- bool "Airoha Ethernet EN8811H support"
- depends on PHY_AIROHA
- help
- AIROHA EN8811H supported.
-
-choice
- prompt "Location of the Airoha PHY firmware"
- default PHY_AIROHA_FW_IN_MMC
- depends on PHY_AIROHA_EN8811H
-
-config PHY_AIROHA_FW_IN_MMC
- bool "Airoha firmware in MMC boot1 partition"
-
-endchoice
-
-config AIROHA_FW_ADDR
- hex "Airoha Firmware Address"
- depends on PHY_AIROHA_EN8811H
- default 0x0
-
-config AIROHA_MD32_DM_SIZE
- hex "Airoha Firmware MD32 DM Size"
- depends on PHY_AIROHA_EN8811H
- default 0x4000
-
-config AIROHA_MD32_DSP_SIZE
- hex "Airoha Firmware MD32 DSP Size"
- depends on PHY_AIROHA_EN8811H
- default 0x20000
-
menuconfig PHY_AQUANTIA
bool "Aquantia Ethernet PHYs support"
select PHY_GIGE
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 87dee3c15b9..2487f366e1c 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -11,7 +11,6 @@ obj-$(CONFIG_MV88E6352_SWITCH) += mv88e6352.o
obj-$(CONFIG_PHYLIB) += phy.o
obj-$(CONFIG_PHYLIB_10G) += generic_10g.o
obj-$(CONFIG_PHY_ADIN) += adin.o
-obj-$(CONFIG_PHY_AIROHA_EN8811H) += air_en8811h.o
obj-$(CONFIG_PHY_AQUANTIA) += aquantia.o
obj-$(CONFIG_PHY_ATHEROS) += atheros.o
obj-$(CONFIG_PHY_BROADCOM) += broadcom.o
diff --git a/drivers/net/phy/air_en8811h.c b/drivers/net/phy/air_en8811h.c
deleted file mode 100644
index 96bb24418a0..00000000000
--- a/drivers/net/phy/air_en8811h.c
+++ /dev/null
@@ -1,783 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Driver for the Airoha EN8811H 2.5 Gigabit PHY.
- *
- * Limitations of the EN8811H:
- * - Only full duplex supported
- * - Forced speed (AN off) is not supported by hardware (100Mbps)
- *
- * Source originated from linux air_en8811h.c
- *
- * Copyright (C) 2025 Airoha Technology Corp.
- */
-#include <phy.h>
-#include <errno.h>
-#include <malloc.h>
-#include <asm/unaligned.h>
-#include <linux/iopoll.h>
-#include <dm/device_compat.h>
-#include <linux/bitops.h>
-#include <mmc.h>
-
-#define EN8811H_PHY_ID 0x03a2a411
-
-#define AIR_FW_ADDR_DM 0x00000000
-#define AIR_FW_ADDR_DSP 0x00100000
-
-#define EN8811H_MD32_DM_SIZE 0x4000
-#define EN8811H_MD32_DSP_SIZE 0x20000
-
- #define EN8811H_FW_CTRL_1 0x0f0018
- #define EN8811H_FW_CTRL_1_START 0x0
- #define EN8811H_FW_CTRL_1_FINISH 0x1
- #define EN8811H_FW_CTRL_2 0x800000
- #define EN8811H_FW_CTRL_2_LOADING BIT(11)
-
- /* MII Registers */
- #define AIR_AUX_CTRL_STATUS 0x1d
- #define AIR_AUX_CTRL_STATUS_SPEED_MASK GENMASK(4, 2)
- #define AIR_AUX_CTRL_STATUS_SPEED_100 0x4
- #define AIR_AUX_CTRL_STATUS_SPEED_1000 0x8
- #define AIR_AUX_CTRL_STATUS_SPEED_2500 0xc
-
-#define AIR_EXT_PAGE_ACCESS 0x1f
-#define AIR_PHY_PAGE_STANDARD 0x0000
-#define AIR_PHY_PAGE_EXTENDED_4 0x0004
-
-/* MII Registers Page 4*/
-#define AIR_BPBUS_MODE 0x10
-#define AIR_BPBUS_MODE_ADDR_FIXED 0x0000
-#define AIR_BPBUS_MODE_ADDR_INCR BIT(15)
-#define AIR_BPBUS_WR_ADDR_HIGH 0x11
-#define AIR_BPBUS_WR_ADDR_LOW 0x12
-#define AIR_BPBUS_WR_DATA_HIGH 0x13
-#define AIR_BPBUS_WR_DATA_LOW 0x14
-#define AIR_BPBUS_RD_ADDR_HIGH 0x15
-#define AIR_BPBUS_RD_ADDR_LOW 0x16
-#define AIR_BPBUS_RD_DATA_HIGH 0x17
-#define AIR_BPBUS_RD_DATA_LOW 0x18
-
-/* Registers on MDIO_MMD_VEND1 */
-#define EN8811H_PHY_FW_STATUS 0x8009
-#define EN8811H_PHY_READY 0x02
-
-/* Registers on MDIO_MMD_VEND2 */
-#define AIR_PHY_LED_BCR 0x021
-#define AIR_PHY_LED_BCR_MODE_MASK GENMASK(1, 0)
-#define AIR_PHY_LED_BCR_TIME_TEST BIT(2)
-#define AIR_PHY_LED_BCR_CLK_EN BIT(3)
-#define AIR_PHY_LED_BCR_EXT_CTRL BIT(15)
-
-#define AIR_PHY_LED_DUR_ON 0x022
-
-#define AIR_PHY_LED_DUR_BLINK 0x023
-
-#define AIR_PHY_LED_ON(i) (0x024 + ((i) * 2))
-#define AIR_PHY_LED_ON_MASK (GENMASK(6, 0) | BIT(8))
-#define AIR_PHY_LED_ON_LINK1000 BIT(0)
-#define AIR_PHY_LED_ON_LINK100 BIT(1)
-#define AIR_PHY_LED_ON_LINK10 BIT(2)
-#define AIR_PHY_LED_ON_LINKDOWN BIT(3)
-#define AIR_PHY_LED_ON_FDX BIT(4) /* Full duplex */
-#define AIR_PHY_LED_ON_HDX BIT(5) /* Half duplex */
-#define AIR_PHY_LED_ON_FORCE_ON BIT(6)
-#define AIR_PHY_LED_ON_LINK2500 BIT(8)
-#define AIR_PHY_LED_ON_POLARITY BIT(14)
-#define AIR_PHY_LED_ON_ENABLE BIT(15)
-
-#define AIR_PHY_LED_BLINK(i) (0x025 + ((i) * 2))
-#define AIR_PHY_LED_BLINK_1000TX BIT(0)
-#define AIR_PHY_LED_BLINK_1000RX BIT(1)
-#define AIR_PHY_LED_BLINK_100TX BIT(2)
-#define AIR_PHY_LED_BLINK_100RX BIT(3)
-#define AIR_PHY_LED_BLINK_10TX BIT(4)
-#define AIR_PHY_LED_BLINK_10RX BIT(5)
-#define AIR_PHY_LED_BLINK_COLLISION BIT(6)
-#define AIR_PHY_LED_BLINK_RX_CRC_ERR BIT(7)
-#define AIR_PHY_LED_BLINK_RX_IDLE_ERR BIT(8)
-#define AIR_PHY_LED_BLINK_FORCE_BLINK BIT(9)
-#define AIR_PHY_LED_BLINK_2500TX BIT(10)
-#define AIR_PHY_LED_BLINK_2500RX BIT(11)
-
-#define EN8811H_FW_VERSION 0x3b3c
-
-#define EN8811H_POLARITY 0xca0f8
-#define EN8811H_POLARITY_TX_NORMAL BIT(0)
-#define EN8811H_POLARITY_RX_REVERSE BIT(1)
-
-#define EN8811H_CLK_CGM 0xcf958
-#define EN8811H_CLK_CGM_CKO BIT(26)
-#define EN8811H_HWTRAP1 0xcf914
-#define EN8811H_HWTRAP1_CKO BIT(12)
-
-#define air_upper_16_bits(n) ((u16)((n) >> 16))
-#define air_lower_16_bits(n) ((u16)((n) & 0xffff))
-
-/* Led definitions */
-#define EN8811H_LED_COUNT 3
-
-/* Default LED setup:
- * GPIO5 <-> LED0 On: Link detected
- * GPIO4 <-> LED1 On: Link detected at 2500 and 1000 Mbps
- * GPIO3 <-> LED2 On: Link detected at 2500 and 100 Mbps
- */
-#define AIR_DEFAULT_TRIGGER_LED0 (AIR_PHY_LED_ON_LINK2500 | \
- AIR_PHY_LED_ON_LINK1000 | \
- AIR_PHY_LED_ON_LINK100)
-#define AIR_DEFAULT_TRIGGER_LED1 (AIR_PHY_LED_ON_LINK2500 | \
- AIR_PHY_LED_ON_LINK1000 | \
- AIR_PHY_LED_BLINK_2500TX | \
- AIR_PHY_LED_BLINK_2500RX | \
- AIR_PHY_LED_BLINK_1000TX | \
- AIR_PHY_LED_BLINK_1000RX)
-#define AIR_DEFAULT_TRIGGER_LED2 (AIR_PHY_LED_ON_LINK2500 | \
- AIR_PHY_LED_ON_LINK100 | \
- AIR_PHY_LED_BLINK_2500TX | \
- AIR_PHY_LED_BLINK_2500RX | \
- AIR_PHY_LED_BLINK_100TX | \
- AIR_PHY_LED_BLINK_100RX)
-
-struct led {
- unsigned long rules;
-};
-
-enum {
- AIR_PHY_LED_DUR_BLINK_32MS,
- AIR_PHY_LED_DUR_BLINK_64MS,
- AIR_PHY_LED_DUR_BLINK_128MS,
- AIR_PHY_LED_DUR_BLINK_256MS,
- AIR_PHY_LED_DUR_BLINK_512MS,
- AIR_PHY_LED_DUR_BLINK_1024MS,
-};
-
-enum {
- AIR_LED_DISABLE,
- AIR_LED_ENABLE,
-};
-
-enum {
- AIR_ACTIVE_LOW,
- AIR_ACTIVE_HIGH,
-};
-
-enum {
- AIR_LED_MODE_DISABLE,
- AIR_LED_MODE_USER_DEFINE,
-};
-
-#define AIR_PHY_LED_DUR_UNIT 781
-#define AIR_PHY_LED_DUR (AIR_PHY_LED_DUR_UNIT << AIR_PHY_LED_DUR_BLINK_64MS)
-
-struct en8811h_priv {
- int firmware_version;
- bool mcu_needs_restart;
- struct led led[EN8811H_LED_COUNT];
-};
-
-static int air_phy_read_page(struct phy_device *phydev)
-{
- return phy_read(phydev, MDIO_DEVAD_NONE, AIR_EXT_PAGE_ACCESS);
-}
-
-static int air_phy_write_page(struct phy_device *phydev, int page)
-{
- return phy_write(phydev, MDIO_DEVAD_NONE, AIR_EXT_PAGE_ACCESS, page);
-}
-
-int air_phy_select_page(struct phy_device *phydev, int page)
-{
- int ret, oldpage;
-
- oldpage = air_phy_read_page(phydev);
- if (oldpage < 0)
- return oldpage;
-
- if (oldpage != page) {
- ret = air_phy_write_page(phydev, page);
- if (ret < 0)
- return ret;
- }
-
- return oldpage;
-}
-
-int air_phy_restore_page(struct phy_device *phydev, int oldpage, int ret)
-{
- int r;
-
- if (oldpage >= 0) {
- r = air_phy_write_page(phydev, oldpage);
-
- if (ret >= 0 && r < 0)
- ret = r;
- } else {
- ret = oldpage;
- }
-
- return ret;
-}
-
-static int air_buckpbus_reg_write(struct phy_device *phydev,
- u32 pbus_address, u32 pbus_data)
-{
- int ret, saved_page;
-
- saved_page = air_phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
-
- if (saved_page >= 0) {
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_FIXED);
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH,
- air_upper_16_bits(pbus_address));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW,
- air_lower_16_bits(pbus_address));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH,
- air_upper_16_bits(pbus_data));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW,
- air_lower_16_bits(pbus_data));
- if (ret < 0)
- goto restore_page;
- }
-
-restore_page:
- if (ret < 0)
- printf("%s 0x%08x failed: %d\n", __func__,
- pbus_address, ret);
-
- return air_phy_restore_page(phydev, saved_page, ret);
-}
-
-static int air_buckpbus_reg_read(struct phy_device *phydev,
- u32 pbus_address, u32 *pbus_data)
-{
- int pbus_data_low, pbus_data_high;
- int ret = 0, saved_page;
-
- saved_page = air_phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
-
- if (saved_page >= 0) {
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_FIXED);
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_HIGH,
- air_upper_16_bits(pbus_address));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_LOW,
- air_lower_16_bits(pbus_address));
- if (ret < 0)
- goto restore_page;
-
- pbus_data_high = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_HIGH);
- if (pbus_data_high < 0) {
- ret = pbus_data_high;
- goto restore_page;
- }
-
- pbus_data_low = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_LOW);
- if (pbus_data_low < 0) {
- ret = pbus_data_low;
- goto restore_page;
- }
-
- *pbus_data = pbus_data_low | (pbus_data_high << 16);
- }
-
-restore_page:
- if (ret < 0)
- printf("%s 0x%08x failed: %d\n", __func__,
- pbus_address, ret);
-
- return air_phy_restore_page(phydev, saved_page, ret);
-}
-
-static int air_buckpbus_reg_modify(struct phy_device *phydev,
- u32 pbus_address, u32 mask, u32 set)
-{
- int pbus_data_low, pbus_data_high;
- u32 pbus_data_old, pbus_data_new;
- int ret = 0, saved_page;
-
- saved_page = air_phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
-
- if (saved_page >= 0) {
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_FIXED);
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_HIGH,
- air_upper_16_bits(pbus_address));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_LOW,
- air_lower_16_bits(pbus_address));
- if (ret < 0)
- goto restore_page;
-
- pbus_data_high = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_HIGH);
- if (pbus_data_high < 0)
- return pbus_data_high;
-
- pbus_data_low = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_LOW);
- if (pbus_data_low < 0)
- return pbus_data_low;
-
- pbus_data_old = pbus_data_low | (pbus_data_high << 16);
- pbus_data_new = (pbus_data_old & ~mask) | set;
- if (pbus_data_new == pbus_data_old)
- return 0;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH,
- air_upper_16_bits(pbus_address));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW,
- air_lower_16_bits(pbus_address));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH,
- air_upper_16_bits(pbus_data_new));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW,
- air_lower_16_bits(pbus_data_new));
- if (ret < 0)
- goto restore_page;
- }
-
-restore_page:
- if (ret < 0)
- printf("%s 0x%08x failed: %d\n", __func__,
- pbus_address, ret);
-
- return air_phy_restore_page(phydev, saved_page, ret);
-}
-
-static int air_write_buf(struct phy_device *phydev, unsigned long address,
- unsigned long array_size, const unsigned char *buffer)
-{
- unsigned int offset;
- int ret, saved_page;
- u16 val;
-
- saved_page = air_phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
-
- if (saved_page >= 0) {
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_INCR);
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH,
- air_upper_16_bits(address));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW,
- air_lower_16_bits(address));
- if (ret < 0)
- goto restore_page;
-
- for (offset = 0; offset < array_size; offset += 4) {
- val = get_unaligned_le16(&buffer[offset + 2]);
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH, val);
- if (ret < 0)
- goto restore_page;
-
- val = get_unaligned_le16(&buffer[offset]);
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW, val);
- if (ret < 0)
- goto restore_page;
- }
- }
-
-restore_page:
- if (ret < 0)
- printf("%s 0x%08lx failed: %d\n", __func__,
- address, ret);
-
- return air_phy_restore_page(phydev, saved_page, ret);
-}
-
-__weak ulong *en8811h_get_fw_addr(void)
-{
- return (ulong *)CONFIG_AIROHA_FW_ADDR;
-}
-
-static int en8811h_wait_mcu_ready(struct phy_device *phydev)
-{
- int ret, reg_value;
-
- /* Because of mdio-lock, may have to wait for multiple loads */
- ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
- EN8811H_PHY_FW_STATUS, reg_value,
- reg_value == EN8811H_PHY_READY,
- 20000, 7500000, true);
- if (ret) {
- printf("MCU not ready: 0x%x\n", reg_value);
- return -ENODEV;
- }
-
- return 0;
-}
-
-static int en8811h_load_firmware(struct phy_device *phydev)
-{
- int ret;
- char *addr = NULL;
- struct en8811h_priv *priv = phydev->priv;
- int dev = CONFIG_SYS_MMC_ENV_DEV;
- u32 cnt = (CONFIG_AIROHA_MD32_DM_SIZE +
- CONFIG_AIROHA_MD32_DSP_SIZE) / 512;
- ulong airoha_fw_addr = (ulong)en8811h_get_fw_addr();
- u32 blk = airoha_fw_addr / 512;
-
- addr = malloc(CONFIG_AIROHA_MD32_DM_SIZE + CONFIG_AIROHA_MD32_DSP_SIZE);
- if (!addr) {
- puts("cannot allocated buffer for firmware.\n");
- return -ENOMEM;
- }
-
- if (IS_ENABLED(CONFIG_PHY_AIROHA_FW_IN_MMC)) {
- struct mmc *mmc = find_mmc_device(dev);
-
- if (!mmc) {
- puts("Failed to find MMC device for Airoha ucode\n");
- goto en8811h_load_firmware_out;
- }
-
- printf("MMC read: dev # %u, block # %u, count %u ...\n",
- dev, blk, cnt);
-
- if (mmc_init(mmc)) {
- puts("initializing MMC device failed.\n");
- goto en8811h_load_firmware_out;
- }
-
- ret = mmc_set_part_conf(mmc, 1, 2, 2);
- if (ret) {
- puts("cannot access eMMC boot1 hw partition.\n");
- goto en8811h_load_firmware_out;
- }
-
- (void)blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);
-
- mmc_set_part_conf(mmc, 1, 1, 0);
-
- } else {
- puts("EN8811H firmware loading not implemented");
- free(addr);
- addr = NULL;
- return -EOPNOTSUPP;
- }
-
- ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
- EN8811H_FW_CTRL_1_START);
- if (ret < 0)
- return ret;
-
- ret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,
- EN8811H_FW_CTRL_2_LOADING,
- EN8811H_FW_CTRL_2_LOADING);
- if (ret < 0)
- return ret;
-
- ret = air_write_buf(phydev, AIR_FW_ADDR_DM, CONFIG_AIROHA_MD32_DM_SIZE, addr);
- if (ret < 0)
- goto en8811h_load_firmware_out;
-
- ret = air_write_buf(phydev, AIR_FW_ADDR_DSP, CONFIG_AIROHA_MD32_DSP_SIZE,
- addr + CONFIG_AIROHA_MD32_DM_SIZE);
- if (ret < 0)
- goto en8811h_load_firmware_out;
-
- ret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,
- EN8811H_FW_CTRL_2_LOADING, 0);
- if (ret < 0)
- return ret;
-
- ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
- EN8811H_FW_CTRL_1_FINISH);
- if (ret < 0)
- return ret;
-
- ret = en8811h_wait_mcu_ready(phydev);
-
- air_buckpbus_reg_read(phydev, EN8811H_FW_VERSION,
- &priv->firmware_version);
- printf("MD32 firmware version: %08x\n",
- priv->firmware_version);
-
-en8811h_load_firmware_out:
- free(addr);
- if (ret < 0)
- printf("Firmware loading failed: %d\n", ret);
-
- return ret;
-}
-
-static int en8811h_restart_mcu(struct phy_device *phydev)
-{
- int ret;
-
- ret = phy_write_mmd(phydev, 0x1e, 0x8009, 0x0);
- if (ret < 0)
- return ret;
-
- ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
- EN8811H_FW_CTRL_1_START);
- if (ret < 0)
- return ret;
-
- return air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
- EN8811H_FW_CTRL_1_FINISH);
-}
-
-static int air_led_hw_control_set(struct phy_device *phydev,
- u8 index, unsigned long rules)
-{
- struct en8811h_priv *priv = phydev->priv;
- u16 on = 0, blink = 0;
- int ret;
-
- if (index >= EN8811H_LED_COUNT)
- return -EINVAL;
-
- on |= rules & (AIR_PHY_LED_ON_LINK100 |
- AIR_PHY_LED_ON_LINK1000 |
- AIR_PHY_LED_ON_LINK2500);
-
- blink |= rules & (AIR_PHY_LED_BLINK_100TX |
- AIR_PHY_LED_BLINK_100RX |
- AIR_PHY_LED_BLINK_1000TX |
- AIR_PHY_LED_BLINK_1000RX |
- AIR_PHY_LED_BLINK_2500TX |
- AIR_PHY_LED_BLINK_2500RX);
-
- if (blink || on) {
- on &= ~AIR_PHY_LED_ON_FORCE_ON;
- blink &= ~AIR_PHY_LED_BLINK_FORCE_BLINK;
- } else {
- priv->led[index].rules = 0;
- }
-
- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_ON(index),
- AIR_PHY_LED_ON_MASK, on);
- if (ret < 0)
- return ret;
-
- return phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BLINK(index),
- blink);
-}
-
-static int air_led_init(struct phy_device *phydev, u8 index, u8 state, u8 pol)
-{
- int val = 0;
- int err;
-
- if (index >= EN8811H_LED_COUNT)
- return -EINVAL;
-
- if (state == AIR_LED_ENABLE)
- val |= AIR_PHY_LED_ON_ENABLE;
- else
- val &= ~AIR_PHY_LED_ON_ENABLE;
-
- if (pol == AIR_ACTIVE_HIGH)
- val |= AIR_PHY_LED_ON_POLARITY;
- else
- val &= ~AIR_PHY_LED_ON_POLARITY;
-
- err = phy_write_mmd(phydev, 0x1f, AIR_PHY_LED_ON(index), val);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-static int air_leds_init(struct phy_device *phydev, int num, int dur, int mode)
-{
- int ret, i;
- struct en8811h_priv *priv = phydev->priv;
-
- ret = phy_write_mmd(phydev, 0x1f, AIR_PHY_LED_DUR_BLINK, dur);
- if (ret < 0)
- return ret;
-
- ret = phy_write_mmd(phydev, 0x1f, AIR_PHY_LED_DUR_ON, dur >> 1);
- if (ret < 0)
- return ret;
-
- switch (mode) {
- case AIR_LED_MODE_DISABLE:
- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR,
- AIR_PHY_LED_BCR_EXT_CTRL |
- AIR_PHY_LED_BCR_MODE_MASK, 0);
- break;
- case AIR_LED_MODE_USER_DEFINE:
- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR,
- AIR_PHY_LED_BCR_EXT_CTRL |
- AIR_PHY_LED_BCR_CLK_EN,
- AIR_PHY_LED_BCR_EXT_CTRL |
- AIR_PHY_LED_BCR_CLK_EN);
- if (ret < 0)
- return ret;
- break;
- default:
- printf("LED mode %d is not supported\n", mode);
- return -EINVAL;
- }
-
- for (i = 0; i < num; ++i) {
- ret = air_led_init(phydev, i, AIR_LED_ENABLE, AIR_ACTIVE_HIGH);
- if (ret < 0) {
- printf("LED%d init failed: %d\n", i, ret);
- return ret;
- }
- air_led_hw_control_set(phydev, i, priv->led[i].rules);
- }
-
- return 0;
-}
-
-static int en8811h_config(struct phy_device *phydev)
-{
- ofnode node = phy_get_ofnode(phydev);
- struct en8811h_priv *priv = phydev->priv;
- int ret = 0;
- u32 pbus_value = 0;
-
- /* If restart happened in .probe(), no need to restart now */
- if (priv->mcu_needs_restart) {
- ret = en8811h_restart_mcu(phydev);
- if (ret < 0)
- return ret;
- } else {
- ret = en8811h_load_firmware(phydev);
- if (ret) {
- printf("Load firmware fail.\n");
- return ret;
- }
- /* Next calls to .config() mcu needs to restart */
- priv->mcu_needs_restart = true;
- }
-
- ret = phy_write_mmd(phydev, 0x1e, 0x800c, 0x0);
- ret |= phy_write_mmd(phydev, 0x1e, 0x800d, 0x0);
- ret |= phy_write_mmd(phydev, 0x1e, 0x800e, 0x1101);
- ret |= phy_write_mmd(phydev, 0x1e, 0x800f, 0x0002);
- if (ret < 0)
- return ret;
-
- /* Serdes polarity */
- pbus_value = 0;
- if (ofnode_read_bool(node, "airoha,pnswap-rx"))
- pbus_value |= EN8811H_POLARITY_RX_REVERSE;
- else
- pbus_value &= ~EN8811H_POLARITY_RX_REVERSE;
- if (ofnode_read_bool(node, "airoha,pnswap-tx"))
- pbus_value &= ~EN8811H_POLARITY_TX_NORMAL;
- else
- pbus_value |= EN8811H_POLARITY_TX_NORMAL;
- ret = air_buckpbus_reg_modify(phydev, EN8811H_POLARITY,
- EN8811H_POLARITY_RX_REVERSE |
- EN8811H_POLARITY_TX_NORMAL, pbus_value);
- if (ret < 0)
- return ret;
-
- ret = air_leds_init(phydev, EN8811H_LED_COUNT, AIR_PHY_LED_DUR,
- AIR_LED_MODE_USER_DEFINE);
- if (ret < 0) {
- printf("Failed to disable leds: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-static int en8811h_parse_status(struct phy_device *phydev)
-{
- int ret = 0, reg_value;
-
- phydev->duplex = DUPLEX_FULL;
-
- reg_value = phy_read(phydev, MDIO_DEVAD_NONE, AIR_AUX_CTRL_STATUS);
- if (reg_value < 0)
- return reg_value;
-
- switch (reg_value & AIR_AUX_CTRL_STATUS_SPEED_MASK) {
- case AIR_AUX_CTRL_STATUS_SPEED_2500:
- phydev->speed = SPEED_2500;
- break;
- case AIR_AUX_CTRL_STATUS_SPEED_1000:
- phydev->speed = SPEED_1000;
- break;
- case AIR_AUX_CTRL_STATUS_SPEED_100:
- phydev->speed = SPEED_100;
- break;
- default:
- printf("Auto-neg error, defaulting to 100M/FD\n");
- phydev->speed = SPEED_100;
- break;
- }
-
- return ret;
-}
-
-static int en8811h_startup(struct phy_device *phydev)
-{
- int ret = 0;
-
- ret = genphy_update_link(phydev);
- if (ret)
- return ret;
-
- return en8811h_parse_status(phydev);
-}
-
-static int en8811h_probe(struct phy_device *phydev)
-{
- struct en8811h_priv *priv;
-
- priv = malloc(sizeof(*priv));
- if (!priv)
- return -ENOMEM;
- memset(priv, 0, sizeof(*priv));
-
- priv->led[0].rules = AIR_DEFAULT_TRIGGER_LED0;
- priv->led[1].rules = AIR_DEFAULT_TRIGGER_LED1;
- priv->led[2].rules = AIR_DEFAULT_TRIGGER_LED2;
-
- /* mcu has just restarted after firmware load */
- priv->mcu_needs_restart = false;
-
- phydev->priv = priv;
-
- return 0;
-}
-
-U_BOOT_PHY_DRIVER(en8811h) = {
- .name = "Airoha EN8811H",
- .uid = EN8811H_PHY_ID,
- .mask = 0x0ffffff0,
- .config = &en8811h_config,
- .probe = &en8811h_probe,
- .startup = &en8811h_startup,
- .shutdown = &genphy_shutdown,
-};
diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c
index 76d108080d9..e57729f0ef9 100644
--- a/drivers/reset/reset-socfpga.c
+++ b/drivers/reset/reset-socfpga.c
@@ -23,6 +23,7 @@
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/sizes.h>
+#include <linux/kconfig.h>
#define BANK_INCREMENT 4
#define NR_BANKS 8
@@ -114,6 +115,8 @@ static int socfpga_reset_remove(struct udevice *dev)
if (socfpga_reset_keep_enabled()) {
puts("Deasserting all peripheral resets\n");
writel(0, data->modrst_base + 4);
+ if (IS_ENABLED(CONFIG_TARGET_SOCFPGA_ARRIA10))
+ writel(0, data->modrst_base + 8);
}
return 0;
diff --git a/fs/exfat/io.c b/fs/exfat/io.c
index 81e82829c72..c56f5675987 100644
--- a/fs/exfat/io.c
+++ b/fs/exfat/io.c
@@ -597,15 +597,13 @@ ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node,
}
#ifdef __UBOOT__
+#define PATH_MAX FS_DIRENT_NAME_LEN
+
struct exfat_dir_stream {
+ char dirname[PATH_MAX];
struct fs_dir_stream fs_dirs;
struct fs_dirent dirent;
-
- struct exfat_node* node;
- struct exfat_iterator it;
- /* State tracker flags for emulated . and .. dirents */
- bool dot;
- bool dotdot;
+ int offset;
};
int exfat_fs_probe(struct blk_desc *fs_dev_desc,
@@ -626,8 +624,6 @@ error:
return ret;
}
-#define PATH_MAX FS_DIRENT_NAME_LEN
-
/* Adapted from uclibc 1.0.35 */
static char *exfat_realpath(const char *path, char got_path[])
{
@@ -721,31 +717,31 @@ int exfat_lookup_realpath(struct exfat* ef, struct exfat_node** node,
int exfat_fs_opendir(const char *filename, struct fs_dir_stream **dirsp)
{
struct exfat_dir_stream *dirs;
+ struct exfat_node *dnode;
int err;
- dirs = calloc(1, sizeof(*dirs));
- if (!dirs)
- return -ENOMEM;
-
- err = exfat_lookup_realpath(&ctxt.ef, &dirs->node, filename);
+ err = exfat_lookup_realpath(&ctxt.ef, &dnode, filename);
if (err)
- goto err_out;
+ return err;
- if (!(dirs->node->attrib & EXFAT_ATTRIB_DIR)) {
+ if (!(dnode->attrib & EXFAT_ATTRIB_DIR))
err = -ENOTDIR;
- goto err_out;
- }
- err = exfat_opendir(&ctxt.ef, dirs->node, &dirs->it);
+ exfat_put_node(&ctxt.ef, dnode);
+
if (err)
- goto err_out;
+ return err;
+
+ dirs = calloc(1, sizeof(*dirs));
+ if (!dirs)
+ return -ENOMEM;
+
+ strcpy(dirs->dirname, filename);
+ dirs->offset = -1;
*dirsp = &dirs->fs_dirs;
return 0;
-err_out:
- free(dirs);
- return err;
}
int exfat_fs_readdir(struct fs_dir_stream *fs_dirs, struct fs_dirent **dentp)
@@ -753,50 +749,77 @@ int exfat_fs_readdir(struct fs_dir_stream *fs_dirs, struct fs_dirent **dentp)
struct exfat_dir_stream *dirs =
container_of(fs_dirs, struct exfat_dir_stream, fs_dirs);
struct fs_dirent *dent = &dirs->dirent;
- struct exfat_node* node;
+ struct exfat_node *dnode, *node;
+ struct exfat_iterator it;
+ int offset = 0;
+ int err;
+
+ err = exfat_lookup_realpath(&ctxt.ef, &dnode, dirs->dirname);
+ if (err)
+ return err;
+
+ if (!(dnode->attrib & EXFAT_ATTRIB_DIR)) {
+ err = -ENOTDIR;
+ goto err_out;
+ }
/* Emulate current directory ./ */
- if (!dirs->dot) {
- dirs->dot = true;
+ if (dirs->offset == -1) {
+ dirs->offset++;
snprintf(dent->name, FS_DIRENT_NAME_LEN, ".");
dent->type = FS_DT_DIR;
*dentp = dent;
- return 0;
+ goto err_out;
}
/* Emulate parent directory ../ */
- if (!dirs->dotdot) {
- dirs->dotdot = true;
+ if (dirs->offset == 0) {
+ dirs->offset++;
snprintf(dent->name, FS_DIRENT_NAME_LEN, "..");
dent->type = FS_DT_DIR;
*dentp = dent;
- return 0;
+ goto err_out;
}
+ err = exfat_opendir(&ctxt.ef, dnode, &it);
+ if (err)
+ goto err_out;
+
+ *dentp = NULL;
+
/* Read actual directory content */
- node = exfat_readdir(&dirs->it);
- if (!node) { /* No more content, reset . and .. emulation */
- dirs->dot = false;
- dirs->dotdot = false;
- return 1;
- }
+ while ((node = exfat_readdir(&it))) {
+ if (dirs->offset != ++offset) {
+ exfat_put_node(&ctxt.ef, node);
+ continue;
+ }
- exfat_get_name(node, dent->name);
- if (node->attrib & EXFAT_ATTRIB_DIR) {
- dent->type = FS_DT_DIR;
- } else {
- dent->type = FS_DT_REG;
- dent->size = node->size;
+ exfat_get_name(node, dent->name);
+ if (node->attrib & EXFAT_ATTRIB_DIR) {
+ dent->type = FS_DT_DIR;
+ } else {
+ dent->type = FS_DT_REG;
+ dent->size = node->size;
+ }
+ exfat_put_node(&ctxt.ef, node);
+ *dentp = dent;
+ dirs->offset++;
+ break;
}
- *dentp = dent;
+ exfat_closedir(&ctxt.ef, &it);
- return 0;
+err_out:
+ exfat_put_node(&ctxt.ef, dnode);
+ return err;
}
void exfat_fs_closedir(struct fs_dir_stream *fs_dirs)
{
- free(fs_dirs);
+ struct exfat_dir_stream *dirs =
+ container_of(fs_dirs, struct exfat_dir_stream, fs_dirs);
+
+ free(dirs);
}
int exfat_fs_ls(const char *dirname)
@@ -852,11 +875,11 @@ int exfat_fs_exists(const char *filename)
err = exfat_lookup_realpath(&ctxt.ef, &node, filename);
if (err)
- return err;
+ return 0;
exfat_put_node(&ctxt.ef, node);
- return 0;
+ return 1;
}
int exfat_fs_size(const char *filename, loff_t *size)
@@ -898,9 +921,7 @@ int exfat_fs_read(const char *filename, void *buf, loff_t offset, loff_t len,
*actread = sz;
- exfat_put_node(&ctxt.ef, node);
-
- return exfat_flush_node(&ctxt.ef, node);
+ err = exfat_flush_node(&ctxt.ef, node);
exit:
exfat_put_node(&ctxt.ef, node);
return err;
@@ -992,6 +1013,11 @@ exit:
return err;
}
+int exfat_fs_rename(const char *old_path, const char *new_path)
+{
+ return exfat_rename(&ctxt.ef, old_path, new_path);
+}
+
void exfat_fs_close(void)
{
exfat_unmount(&ctxt.ef);
diff --git a/fs/exfat/lookup.c b/fs/exfat/lookup.c
index 9867aab95f3..1d9aae9e036 100644
--- a/fs/exfat/lookup.c
+++ b/fs/exfat/lookup.c
@@ -218,8 +218,9 @@ int exfat_split(struct exfat* ef, struct exfat_node** parent,
exfat_put_node(ef, *parent);
*parent = *node;
}
+#ifndef __UBOOT__
exfat_bug("impossible");
-#ifdef __UBOOT__
+#else
return 0;
#endif
}
diff --git a/fs/fs.c b/fs/fs.c
index 0b62217fd59..1f36872fb9a 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -401,6 +401,7 @@ static struct fstype_info fstypes[] = {
.ln = fs_ln_unsupported,
.unlink = exfat_fs_unlink,
.mkdir = exfat_fs_mkdir,
+ .rename = exfat_fs_rename,
},
#endif
{
diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c
index 7c364686f14..2dcdd60f683 100644
--- a/fs/squashfs/sqfs.c
+++ b/fs/squashfs/sqfs.c
@@ -949,7 +949,7 @@ static int sqfs_opendir_nest(const char *filename, struct fs_dir_stream **dirsp)
goto out;
}
- token_list = malloc(token_count * sizeof(char *));
+ token_list = calloc(token_count, sizeof(char *));
if (!token_list) {
ret = -EINVAL;
goto out;
@@ -987,9 +987,11 @@ static int sqfs_opendir_nest(const char *filename, struct fs_dir_stream **dirsp)
*dirsp = (struct fs_dir_stream *)dirs;
out:
- for (j = 0; j < token_count; j++)
- free(token_list[j]);
- free(token_list);
+ if (token_list) {
+ for (j = 0; j < token_count; j++)
+ free(token_list[j]);
+ free(token_list);
+ }
free(pos_list);
free(path);
if (ret) {
diff --git a/include/exfat.h b/include/exfat.h
index 7e43beeb348..75fce5b6566 100644
--- a/include/exfat.h
+++ b/include/exfat.h
@@ -20,5 +20,6 @@ int exfat_fs_unlink(const char *filename);
int exfat_fs_mkdir(const char *dirname);
int exfat_fs_write(const char *filename, void *buf, loff_t offset,
loff_t len, loff_t *actwrite);
+int exfat_fs_rename(const char *old_path, const char *new_path);
#endif /* _EXFAT_H */
diff --git a/include/linux/intel-smc.h b/include/linux/intel-smc.h
index a54eff43add..6455335bae4 100644
--- a/include/linux/intel-smc.h
+++ b/include/linux/intel-smc.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2017-2018, Intel Corporation
+ * Copyright (C) 2025 Altera Corporation <www.altera.com>
*/
#ifndef __INTEL_SMC_H
@@ -482,10 +483,16 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)
* Call register usage:
* a0 INTEL_SIP_SMC_HPS_SET_BRIDGES
* a1 Set bridges status:
- * 0 - Disable
- * 1 - Enable
- * a2-7 not used
- *
+ * Bit 0: 0 - Disable, 1 - Enable
+ * Bit 1: 1 - Has mask value in a2
+ * a2 Mask value
+ * Bit 0: soc2fpga
+ * Bit 1: lwhps2fpga
+ * Bit 2: fpga2soc
+ * Bit 3: f2sdram0 (For Stratix 10 only)
+ * Bit 4: f2sdram1 (For Stratix 10 only)
+ * Bit 5: f2sdram2 (For Stratix 10 only)
+ * a3-7 not used
* Return status
* a0 INTEL_SIP_SMC_STATUS_OK
*/
diff --git a/test/py/tests/test_fs/conftest.py b/test/py/tests/test_fs/conftest.py
index c73fb4abbcb..0205048e73a 100644
--- a/test/py/tests/test_fs/conftest.py
+++ b/test/py/tests/test_fs/conftest.py
@@ -17,7 +17,7 @@ supported_fs_fat = ['fat12', 'fat16']
supported_fs_mkdir = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
supported_fs_unlink = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
supported_fs_symlink = ['ext4']
-supported_fs_rename = ['fat12', 'fat16', 'fat32']
+supported_fs_rename = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic']
#
# Filesystem test specific setup
diff --git a/test/py/tests/test_fs/test_basic.py b/test/py/tests/test_fs/test_basic.py
index 64a3b50f52a..88b163ce305 100644
--- a/test/py/tests/test_fs/test_basic.py
+++ b/test/py/tests/test_fs/test_basic.py
@@ -35,6 +35,19 @@ class TestFsBasic(object):
'%sls host 0:0 invalid_d' % fs_cmd_prefix)
assert('' == output)
+ with ubman.log.section('Test Case 1c - test -e'):
+ # Test Case 1 - test -e
+ output = ubman.run_command_list([
+ 'host bind 0 %s' % fs_img,
+ 'test -e host 0:0 1MB.file && echo PASS'])
+ assert('PASS' in ''.join(output))
+
+ with ubman.log.section('Test Case 1d - test -e (invalid file)'):
+ # In addition, test with a nonexistent file to see if we crash.
+ output = ubman.run_command(
+ 'test -e host 0:0 2MB.file || echo PASS')
+ assert('PASS' in ''.join(output))
+
def test_fs2(self, ubman, fs_obj_basic):
"""
Test Case 2 - size command for a small file