imx: imx8qm/imx8qxp: Power down the resources before SPL jump to u-boot
authorPeng Fan <peng.fan@nxp.com>
Tue, 5 May 2020 12:28:40 +0000 (20:28 +0800)
committerStefano Babic <sbabic@denx.de>
Sun, 10 May 2020 18:55:20 +0000 (20:55 +0200)
Make sure that all devices that are powered up by SPL are powered down
before entering into the u-boot. Otherwise the subsystem/device will
never be powered down by SCFW, due to SPL and u-boot are in different
partitions.

Benefiting from power domain driver, this patch implements the function
"imx8_power_off_pd_devices" to power off all active devices.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
arch/arm/include/asm/arch-imx8/sys_proto.h
board/freescale/imx8qm_mek/spl.c
board/freescale/imx8qxp_mek/spl.c
drivers/power/domain/imx8-power-domain-legacy.c

index fc33e6ed184e80260ef9d8110d18d45e7a7d3e21..2a08ef939d312739d9f3bc70137fdd8ffb50f002 100644 (file)
@@ -28,3 +28,4 @@ int print_bootinfo(void);
 int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate);
 int imx8_power_domain_lookup_name(const char *name,
                                  struct power_domain *power_domain);
+void imx8_power_off_pd_devices(const char *permanent_on_devices[], int size);
index cb4006eb2a40dc3cef6fdfd4130f2c8477a5d120..ba99002cf29cfd608f0d1e865e960f6bf29c759c 100644 (file)
@@ -12,6 +12,7 @@
 #include <dm/uclass-internal.h>
 #include <dm/device-internal.h>
 #include <dm/lists.h>
+#include <asm/arch/sys_proto.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -37,6 +38,11 @@ void spl_board_init(void)
        puts("Normal Boot\n");
 }
 
+void spl_board_prepare_for_boot(void)
+{
+       imx8_power_off_pd_devices(NULL, 0);
+}
+
 #ifdef CONFIG_SPL_LOAD_FIT
 int board_fit_config_name_match(const char *name)
 {
index e4e4cbe7163cd46091f77a92ed709ae9bbded823..32b61095b0671689951dda7251dcec7fc6daf51b 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/arch/sci/sci.h>
 #include <asm/arch/imx8-pins.h>
 #include <asm/arch/iomux.h>
+#include <asm/arch/sys_proto.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -55,6 +56,11 @@ void spl_board_init(void)
        puts("Normal Boot\n");
 }
 
+void spl_board_prepare_for_boot(void)
+{
+       imx_power_off_pd_devices(NULL, 0);
+}
+
 #ifdef CONFIG_SPL_LOAD_FIT
 int board_fit_config_name_match(const char *name)
 {
index f679df9e5d1bbe40c0460e916c9308950a31edb9..7ba4056e2d5b48595656f998fa00f8f0ddc7ab9a 100644 (file)
@@ -11,6 +11,7 @@
 #include <asm/arch/power-domain.h>
 #include <dm/device-internal.h>
 #include <dm/device.h>
+#include <dm/uclass-internal.h>
 #include <asm/arch/sci/sci.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -19,6 +20,40 @@ struct imx8_power_domain_priv {
        bool state_on;
 };
 
+static bool check_device_power_off(struct udevice *dev,
+                                  const char *permanent_on_devices[],
+                                  int size)
+{
+       int i;
+
+       for (i = 0; i < size; i++) {
+               if (!strcmp(dev->name, permanent_on_devices[i]))
+                       return false;
+       }
+
+       return true;
+}
+
+void imx8_power_off_pd_devices(const char *permanent_on_devices[], int size)
+{
+       struct udevice *dev;
+       struct power_domain pd;
+
+       for (uclass_find_first_device(UCLASS_POWER_DOMAIN, &dev); dev;
+            uclass_find_next_device(&dev)) {
+               if (!device_active(dev))
+                       continue;
+               /*
+                * Power off active pd devices except the permanent
+                * power on devices
+                */
+               if (check_device_power_off(dev, permanent_on_devices, size)) {
+                       pd.dev = dev;
+                       power_domain_off(&pd);
+               }
+       }
+}
+
 int imx8_power_domain_lookup_name(const char *name,
                                  struct power_domain *power_domain)
 {