diff options
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 } @@ -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 |