summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYe Li <ye.li@nxp.com>2018-04-18 19:34:11 -0700
committerYe Li <ye.li@nxp.com>2018-04-27 06:14:43 -0700
commit3ab7cc26500eb78407bc6454a48f4d5f0ebf4f60 (patch)
tree8001ded1b02f3c508ffbbf7ebad8f87eab426c82
parentf47cbeada06e16c38170b2eb3fd0cdfe0627b3bc (diff)
MLK-18161-12 imx8qm/imx8qxp - Power down devices enabled by uboot before launching the kernel
Make sure that all devices that are powered up by uboot are powered down before bringing up kernel. Else the subsystem/device will never be powered down by SCFW even though from the kernel's point of view it should be powered down. Benefiting from power domain driver, We have implemented the function "power_off_pd_devices" to power off all active devices. No need to explicitly power off them in board_quiesce_devices. Signed-off-by: Ranjani Vaidyanathan <Ranjani.Vaidyanathan@nxp.com> Signed-off-by: Ye Li <ye.li@nxp.com>
-rw-r--r--arch/arm/include/asm/arch-imx8/sys_proto.h1
-rw-r--r--arch/arm/mach-imx/imx8/cpu.c33
-rw-r--r--board/freescale/imx8qm_arm2/imx8qm_arm2.c9
-rw-r--r--board/freescale/imx8qm_mek/imx8qm_mek.c9
-rw-r--r--board/freescale/imx8qxp_arm2/imx8qxp_arm2.c13
-rw-r--r--board/freescale/imx8qxp_mek/imx8qxp_mek.c13
6 files changed, 78 insertions, 0 deletions
diff --git a/arch/arm/include/asm/arch-imx8/sys_proto.h b/arch/arm/include/asm/arch-imx8/sys_proto.h
index 39b9d1984ea..816040c5e92 100644
--- a/arch/arm/include/asm/arch-imx8/sys_proto.h
+++ b/arch/arm/include/asm/arch-imx8/sys_proto.h
@@ -18,3 +18,4 @@ struct pass_over_info_t {
int print_bootinfo(void);
int init_otg_power(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 3bb456cf75a..1fbef0d7257 100644
--- a/arch/arm/mach-imx/imx8/cpu.c
+++ b/arch/arm/mach-imx/imx8/cpu.c
@@ -9,6 +9,8 @@
#include <errno.h>
#include <asm/io.h>
#include <power-domain.h>
+#include <dm/device.h>
+#include <dm/uclass-internal.h>
#include <asm/mach-imx/sci/sci.h>
#include <asm/mach-imx/boot_mode.h>
#include <asm/arch/clock.h>
@@ -1325,3 +1327,34 @@ u64 get_page_table_size(void)
return size;
}
#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_arm2/imx8qm_arm2.c b/board/freescale/imx8qm_arm2/imx8qm_arm2.c
index b675a833e82..01180d7f1d4 100644
--- a/board/freescale/imx8qm_arm2/imx8qm_arm2.c
+++ b/board/freescale/imx8qm_arm2/imx8qm_arm2.c
@@ -506,6 +506,15 @@ int board_init(void)
return 0;
}
+void board_quiesce_devices()
+{
+ const char *power_on_devices[] = {
+ "dma_lpuart0",
+ };
+
+ power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices));
+}
+
void detail_board_ddr_info(void)
{
puts("\nDDR ");
diff --git a/board/freescale/imx8qm_mek/imx8qm_mek.c b/board/freescale/imx8qm_mek/imx8qm_mek.c
index f8faf3b6a67..9ef60ee71bf 100644
--- a/board/freescale/imx8qm_mek/imx8qm_mek.c
+++ b/board/freescale/imx8qm_mek/imx8qm_mek.c
@@ -351,6 +351,15 @@ int board_init(void)
return 0;
}
+void board_quiesce_devices(void)
+{
+ const char *power_on_devices[] = {
+ "dma_lpuart0",
+ };
+
+ power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices));
+}
+
void detail_board_ddr_info(void)
{
puts("\nDDR ");
diff --git a/board/freescale/imx8qxp_arm2/imx8qxp_arm2.c b/board/freescale/imx8qxp_arm2/imx8qxp_arm2.c
index 1059b203304..9e1741bb9ae 100644
--- a/board/freescale/imx8qxp_arm2/imx8qxp_arm2.c
+++ b/board/freescale/imx8qxp_arm2/imx8qxp_arm2.c
@@ -509,6 +509,19 @@ int board_init(void)
return 0;
}
+void board_quiesce_devices()
+{
+ const char *power_on_devices[] = {
+ "dma_lpuart0",
+
+ /* HIFI DSP boot */
+ "audio_sai0",
+ "audio_ocram",
+ };
+
+ power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices));
+}
+
void detail_board_ddr_info(void)
{
puts("\nDDR ");
diff --git a/board/freescale/imx8qxp_mek/imx8qxp_mek.c b/board/freescale/imx8qxp_mek/imx8qxp_mek.c
index ccd89c90a88..e3d15e819b2 100644
--- a/board/freescale/imx8qxp_mek/imx8qxp_mek.c
+++ b/board/freescale/imx8qxp_mek/imx8qxp_mek.c
@@ -495,6 +495,19 @@ int board_init(void)
return 0;
}
+void board_quiesce_devices()
+{
+ const char *power_on_devices[] = {
+ "dma_lpuart0",
+
+ /* HIFI DSP boot */
+ "audio_sai0",
+ "audio_ocram",
+ };
+
+ power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices));
+}
+
void detail_board_ddr_info(void)
{
puts("\nDDR ");