From patchwork Tue May 5 12:28:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 245129 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Tue, 5 May 2020 20:28:40 +0800 Subject: [PATCH 04/10] imx: imx8qm/imx8qxp: Power down the resources before SPL jump to u-boot In-Reply-To: <20200505122846.15992-1-peng.fan@nxp.com> References: <20200505122846.15992-1-peng.fan@nxp.com> Message-ID: <20200505122846.15992-5-peng.fan@nxp.com> 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 --- arch/arm/include/asm/arch-imx8/sys_proto.h | 1 + board/freescale/imx8qm_mek/spl.c | 6 +++++ board/freescale/imx8qxp_mek/spl.c | 6 +++++ drivers/power/domain/imx8-power-domain-legacy.c | 35 +++++++++++++++++++++++++ 4 files changed, 48 insertions(+) diff --git a/arch/arm/include/asm/arch-imx8/sys_proto.h b/arch/arm/include/asm/arch-imx8/sys_proto.h index fc33e6ed18..2a08ef939d 100644 --- a/arch/arm/include/asm/arch-imx8/sys_proto.h +++ b/arch/arm/include/asm/arch-imx8/sys_proto.h @@ -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); diff --git a/board/freescale/imx8qm_mek/spl.c b/board/freescale/imx8qm_mek/spl.c index cb4006eb2a..ba99002cf2 100644 --- a/board/freescale/imx8qm_mek/spl.c +++ b/board/freescale/imx8qm_mek/spl.c @@ -12,6 +12,7 @@ #include #include #include +#include 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) { diff --git a/board/freescale/imx8qxp_mek/spl.c b/board/freescale/imx8qxp_mek/spl.c index e4e4cbe716..32b61095b0 100644 --- a/board/freescale/imx8qxp_mek/spl.c +++ b/board/freescale/imx8qxp_mek/spl.c @@ -17,6 +17,7 @@ #include #include #include +#include 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) { diff --git a/drivers/power/domain/imx8-power-domain-legacy.c b/drivers/power/domain/imx8-power-domain-legacy.c index f679df9e5d..7ba4056e2d 100644 --- a/drivers/power/domain/imx8-power-domain-legacy.c +++ b/drivers/power/domain/imx8-power-domain-legacy.c @@ -11,6 +11,7 @@ #include #include #include +#include #include 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) {