[U-Boot,v2,6/7] imx8qm/imx8qxp: Power down the resources before SPL jump to u-boot
diff mbox series

Message ID 1562147167-27330-6-git-send-email-ye.li@nxp.com
State New
Delegated to: Stefano Babic
Headers show
Series
  • [U-Boot,v2,1/7] imx8: Add lpcg driver for iMX8QM/QXP
Related show

Commit Message

Ye Li July 3, 2019, 9:46 a.m. UTC
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
"power_off_pd_devices" to power off all active devices.

Signed-off-by: Ye Li <ye.li@nxp.com>
---
Changes in v2:
 - New patch in v2 to fix clock set parent failure in u-boot, due to SPL does not
   power off the resource.
 
 arch/arm/include/asm/arch-imx8/sys_proto.h |  1 +
 arch/arm/mach-imx/imx8/cpu.c               | 34 ++++++++++++++++++++++++++++++
 board/freescale/imx8qm_mek/spl.c           |  6 ++++++
 board/freescale/imx8qxp_mek/spl.c          |  6 ++++++
 4 files changed, 47 insertions(+)

Patch
diff mbox series

diff --git a/arch/arm/include/asm/arch-imx8/sys_proto.h b/arch/arm/include/asm/arch-imx8/sys_proto.h
index 73ffaba..fd00e8f 100644
--- a/arch/arm/include/asm/arch-imx8/sys_proto.h
+++ b/arch/arm/include/asm/arch-imx8/sys_proto.h
@@ -17,3 +17,4 @@  struct pass_over_info_t {
 
 enum boot_device get_boot_device(void);
 int print_bootinfo(void);
+void power_off_pd_devices(const char* permanent_on_devices[], int size);
diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c
index f2fa262..f03729b 100644
--- a/arch/arm/mach-imx/imx8/cpu.c
+++ b/arch/arm/mach-imx/imx8/cpu.c
@@ -11,6 +11,9 @@ 
 #include <dm/lists.h>
 #include <dm/uclass.h>
 #include <errno.h>
+#include <power-domain.h>
+#include <dm/device.h>
+#include <dm/uclass-internal.h>
 #include <thermal.h>
 #include <asm/arch/sci/sci.h>
 #include <asm/arch/sys_proto.h>
@@ -696,3 +699,34 @@  U_BOOT_DRIVER(cpu_imx8_drv) = {
 	.flags		= DM_FLAG_PRE_RELOC,
 };
 #endif
+
+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 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)) {
+			/* 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);
+			}
+		}
+	}
+}
diff --git a/board/freescale/imx8qm_mek/spl.c b/board/freescale/imx8qm_mek/spl.c
index 95ce9f3..a3f2faa 100644
--- a/board/freescale/imx8qm_mek/spl.c
+++ b/board/freescale/imx8qm_mek/spl.c
@@ -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;
 
@@ -53,6 +54,11 @@  void spl_board_init(void)
 	puts("Normal Boot\n");
 }
 
+void spl_board_prepare_for_boot(void)
+{
+	power_off_pd_devices(NULL, 0);
+}
+
 #ifdef CONFIG_SPL_LOAD_FIT
 int board_fit_config_name_match(const char *name)
 {
diff --git a/board/freescale/imx8qxp_mek/spl.c b/board/freescale/imx8qxp_mek/spl.c
index cb4006e..f947838 100644
--- a/board/freescale/imx8qxp_mek/spl.c
+++ b/board/freescale/imx8qxp_mek/spl.c
@@ -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)
+{
+	power_off_pd_devices(NULL, 0);
+}
+
 #ifdef CONFIG_SPL_LOAD_FIT
 int board_fit_config_name_match(const char *name)
 {