diff --git a/arch/arm/include/asm/u-boot-arm.h b/arch/arm/include/asm/u-boot-arm.h index 414042d4039b52b626eeae689b0b5a0e31d59fc5..305a302dfc4b9aff45e4293f03bc5bbbad177ba8 100644 --- a/arch/arm/include/asm/u-boot-arm.h +++ b/arch/arm/include/asm/u-boot-arm.h @@ -37,6 +37,7 @@ int arch_early_init_r(void); /* board/.../... */ int board_init(void); void dram_init_banksize (void); +void board_quiesce_devices(void); /* cpu/.../interrupt.c */ int arch_interrupt_init (void); diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 53c3141322a0de8f30e18c20fd2157483570fe4b..dedcd1e9a4b8d2d3ab4c64f615388011f5123478 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -64,6 +64,10 @@ void arch_lmb_reserve(struct lmb *lmb) gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp); } +__weak void board_quiesce_devices(void) +{ +} + /** * announce_and_cleanup() - Print message and prepare for kernel boot * @@ -84,6 +88,9 @@ static void announce_and_cleanup(int fake) #ifdef CONFIG_USB_DEVICE udc_disconnect(); #endif + + board_quiesce_devices(); + cleanup_before_linux(); } diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index 031740b708a8f5d660801f816db421af77e0a8fd..4f901f9392c06844644bfb257047b9b18b802014 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -74,6 +74,7 @@ static inline __attribute__((no_instrument_function)) uint64_t rdtsc(void) /* board/... */ void timer_set_tsc_base(uint64_t new_base); uint64_t timer_get_tsc(void); +void board_quiesce_devices(void); void quick_ram_check(void); diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c index 7cf9de4d7b53e083acda9e0035250568ae1435ba..80fadef34e99c44b6080bcb2f49e257393f00759 100644 --- a/arch/x86/lib/bootm.c +++ b/arch/x86/lib/bootm.c @@ -26,6 +26,10 @@ DECLARE_GLOBAL_DATA_PTR; #define COMMAND_LINE_OFFSET 0x9000 +__weak void board_quiesce_devices(void) +{ +} + void bootm_announce_and_cleanup(void) { printf("\nStarting kernel ...\n\n"); diff --git a/board/freescale/ls2080a/ls2080a.c b/board/freescale/ls2080a/ls2080a.c index d0a88d4ef9d1dbd41bd5943443767e78e03d288e..4f9b9c8a7739525e0c84209fed9b9a1319120cbd 100644 --- a/board/freescale/ls2080a/ls2080a.c +++ b/board/freescale/ls2080a/ls2080a.c @@ -102,6 +102,11 @@ void fdt_fixup_board_enet(void *fdt) else fdt_status_fail(fdt, offset); } + +void board_quiesce_devices(void) +{ + fsl_mc_ldpaa_exit(gd->bd); +} #endif #ifdef CONFIG_OF_BOARD_SETUP @@ -122,7 +127,6 @@ int ft_board_setup(void *blob, bd_t *bd) #ifdef CONFIG_FSL_MC_ENET fdt_fixup_board_enet(blob); - fsl_mc_ldpaa_exit(bd); #endif return 0; diff --git a/board/freescale/ls2080aqds/ls2080aqds.c b/board/freescale/ls2080aqds/ls2080aqds.c index d07ca18af9a6ae029a7b90b5a351aaff8a76fb1c..73a61fd75aa12a3c6f7f2dfcbfca7a9b34bea5e6 100644 --- a/board/freescale/ls2080aqds/ls2080aqds.c +++ b/board/freescale/ls2080aqds/ls2080aqds.c @@ -292,14 +292,16 @@ void fdt_fixup_board_enet(void *fdt) else fdt_status_fail(fdt, offset); } + +void board_quiesce_devices(void) +{ + fsl_mc_ldpaa_exit(gd->bd); +} #endif #ifdef CONFIG_OF_BOARD_SETUP int ft_board_setup(void *blob, bd_t *bd) { -#ifdef CONFIG_FSL_MC_ENET - int err; -#endif u64 base[CONFIG_NR_DRAM_BANKS]; u64 size[CONFIG_NR_DRAM_BANKS]; @@ -317,9 +319,6 @@ int ft_board_setup(void *blob, bd_t *bd) #ifdef CONFIG_FSL_MC_ENET fdt_fixup_board_enet(blob); - err = fsl_mc_ldpaa_exit(bd); - if (err) - return err; #endif return 0; diff --git a/board/freescale/ls2080ardb/ls2080ardb.c b/board/freescale/ls2080ardb/ls2080ardb.c index 83d9e7ec12c0330c785e53f3acb86d659ceff063..fab44b96baac7f6507bb14b0a3ce02705139f273 100644 --- a/board/freescale/ls2080ardb/ls2080ardb.c +++ b/board/freescale/ls2080ardb/ls2080ardb.c @@ -256,14 +256,16 @@ void fdt_fixup_board_enet(void *fdt) else fdt_status_fail(fdt, offset); } + +void board_quiesce_devices(void) +{ + fsl_mc_ldpaa_exit(gd->bd); +} #endif #ifdef CONFIG_OF_BOARD_SETUP int ft_board_setup(void *blob, bd_t *bd) { -#ifdef CONFIG_FSL_MC_ENET - int err; -#endif u64 base[CONFIG_NR_DRAM_BANKS]; u64 size[CONFIG_NR_DRAM_BANKS]; @@ -281,9 +283,6 @@ int ft_board_setup(void *blob, bd_t *bd) #ifdef CONFIG_FSL_MC_ENET fdt_fixup_board_enet(blob); - err = fsl_mc_ldpaa_exit(bd); - if (err) - return err; #endif return 0; diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index 1811b0fe1a3f13d40203013bb4fb3a5a05c66b3e..46b8a6bc69912f4da1868fe6ca3f87d4fe9f8b78 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -40,6 +40,7 @@ int child_dprc_id; struct fsl_dpbp_obj *dflt_dpbp = NULL; struct fsl_dpio_obj *dflt_dpio = NULL; struct fsl_dpni_obj *dflt_dpni = NULL; +static u64 mc_lazy_dpl_addr; #ifdef DEBUG void dump_ram_words(const char *title, void *addr) @@ -572,6 +573,9 @@ int mc_apply_dpl(u64 mc_dpl_addr) u64 mc_ram_addr = mc_get_dram_addr(); size_t mc_ram_size = mc_get_dram_block_size(); + if (!mc_dpl_addr) + return -1; + error = load_mc_dpl(mc_ram_addr, mc_ram_size, mc_dpl_addr); if (error != 0) return error; @@ -1156,6 +1160,11 @@ int fsl_mc_ldpaa_exit(bd_t *bd) { int err = 0; + if (bd && mc_lazy_dpl_addr && !fsl_mc_ldpaa_exit(NULL)) { + mc_apply_dpl(mc_lazy_dpl_addr); + mc_lazy_dpl_addr = 0; + } + /* MC is not loaded intentionally, So return success. */ if (bd && get_mc_boot_status() != 0) return 0; @@ -1259,6 +1268,7 @@ static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } break; + case 'l': case 'a': { u64 mc_dpl_addr; @@ -1279,8 +1289,17 @@ static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return -ENODEV; } - if (!fsl_mc_ldpaa_exit(NULL)) - err = mc_apply_dpl(mc_dpl_addr); + if (argv[1][0] == 'l') { + /* + * We will do the actual dpaa exit and dpl apply + * later from announce_and_cleanup(). + */ + mc_lazy_dpl_addr = mc_dpl_addr; + } else { + /* The user wants it applied now */ + if (!fsl_mc_ldpaa_exit(NULL)) + err = mc_apply_dpl(mc_dpl_addr); + } break; } default: @@ -1298,5 +1317,6 @@ U_BOOT_CMD( "DPAA2 command to manage Management Complex (MC)", "start mc [FW_addr] [DPC_addr] - Start Management Complex\n" "fsl_mc apply DPL [DPL_addr] - Apply DPL file\n" + "fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n" "fsl_mc start aiop [FW_addr] - Start AIOP\n" ); diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 1fdddf4591c000920a4ea09ad3cd05d798a771c6..51080cbeed2f35d03fb1deb983a0d0a26021a92b 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -538,6 +538,8 @@ static efi_status_t EFIAPI efi_exit_boot_services(void *image_handle, { EFI_ENTRY("%p, %ld", image_handle, map_key); + board_quiesce_devices(); + /* Fix up caches for EFI payloads if necessary */ efi_exit_caches();