ls2080: Exit dpaa only right before exiting U-Boot
authorAlexander Graf <agraf@suse.de>
Thu, 17 Nov 2016 00:02:57 +0000 (01:02 +0100)
committerAlexander Graf <agraf@suse.de>
Thu, 17 Nov 2016 13:18:55 +0000 (14:18 +0100)
On ls2080 we have a separate network fabric component which we need to
shut down before we enter Linux (or any other OS). Along with that also
comes configuration of the fabric using a description file.

Today we always stop and configure the fabric in the boot script and
(again) exit it on device tree generation. This works ok for the normal
booti case, but with bootefi the payload we're running may still want to
access the network.

So let's add a new fsl_mc command that defers configuration and stopping
the hardware to when we actually exit U-Boot, so that we can still use
the fabric from an EFI payload.

For existing boot scripts, nothing should change with this patch.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: York Sun <york.sun@nxp.com>
[agraf: Fix x86 build]

arch/arm/include/asm/u-boot-arm.h
arch/arm/lib/bootm.c
arch/x86/include/asm/u-boot-x86.h
arch/x86/lib/bootm.c
board/freescale/ls2080a/ls2080a.c
board/freescale/ls2080aqds/ls2080aqds.c
board/freescale/ls2080ardb/ls2080ardb.c
drivers/net/fsl-mc/mc.c
lib/efi_loader/efi_boottime.c

index 414042d4039b52b626eeae689b0b5a0e31d59fc5..305a302dfc4b9aff45e4293f03bc5bbbad177ba8 100644 (file)
@@ -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);
index 53c3141322a0de8f30e18c20fd2157483570fe4b..dedcd1e9a4b8d2d3ab4c64f615388011f5123478 100644 (file)
@@ -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();
 }
 
index 031740b708a8f5d660801f816db421af77e0a8fd..4f901f9392c06844644bfb257047b9b18b802014 100644 (file)
@@ -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);
 
index 7cf9de4d7b53e083acda9e0035250568ae1435ba..80fadef34e99c44b6080bcb2f49e257393f00759 100644 (file)
@@ -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");
index d0a88d4ef9d1dbd41bd5943443767e78e03d288e..4f9b9c8a7739525e0c84209fed9b9a1319120cbd 100644 (file)
@@ -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;
index d07ca18af9a6ae029a7b90b5a351aaff8a76fb1c..73a61fd75aa12a3c6f7f2dfcbfca7a9b34bea5e6 100644 (file)
@@ -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;
index 83d9e7ec12c0330c785e53f3acb86d659ceff063..fab44b96baac7f6507bb14b0a3ce02705139f273 100644 (file)
@@ -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;
index 1811b0fe1a3f13d40203013bb4fb3a5a05c66b3e..46b8a6bc69912f4da1868fe6ca3f87d4fe9f8b78 100644 (file)
@@ -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"
 );
index 1fdddf4591c000920a4ea09ad3cd05d798a771c6..51080cbeed2f35d03fb1deb983a0d0a26021a92b 100644 (file)
@@ -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();