Commit 3ab7cc26500eb78407bc6454a48f4d5f0ebf4f60

Authored by Ye Li
1 parent f47cbeada0

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>

Showing 6 changed files with 78 additions and 0 deletions Side-by-side Diff

arch/arm/include/asm/arch-imx8/sys_proto.h
... ... @@ -18,4 +18,5 @@
18 18  
19 19 int print_bootinfo(void);
20 20 int init_otg_power(void);
  21 +void power_off_pd_devices(const char* permanent_on_devices[], int size);
arch/arm/mach-imx/imx8/cpu.c
... ... @@ -9,6 +9,8 @@
9 9 #include <errno.h>
10 10 #include <asm/io.h>
11 11 #include <power-domain.h>
  12 +#include <dm/device.h>
  13 +#include <dm/uclass-internal.h>
12 14 #include <asm/mach-imx/sci/sci.h>
13 15 #include <asm/mach-imx/boot_mode.h>
14 16 #include <asm/arch/clock.h>
... ... @@ -1325,4 +1327,35 @@
1325 1327 return size;
1326 1328 }
1327 1329 #endif
  1330 +
  1331 +static bool check_device_power_off(struct udevice *dev,
  1332 + const char* permanent_on_devices[], int size)
  1333 +{
  1334 + int i;
  1335 +
  1336 + for (i = 0; i < size; i++) {
  1337 + if (!strcmp(dev->name, permanent_on_devices[i]))
  1338 + return false;
  1339 + }
  1340 +
  1341 + return true;
  1342 +}
  1343 +
  1344 +void power_off_pd_devices(const char* permanent_on_devices[], int size)
  1345 +{
  1346 + struct udevice *dev;
  1347 + struct power_domain pd;
  1348 +
  1349 + for (uclass_find_first_device(UCLASS_POWER_DOMAIN, &dev); dev;
  1350 + uclass_find_next_device(&dev)) {
  1351 +
  1352 + if (device_active(dev)) {
  1353 + /* Power off active pd devices except the permanent power on devices */
  1354 + if (check_device_power_off(dev, permanent_on_devices, size)) {
  1355 + pd.dev = dev;
  1356 + power_domain_off(&pd);
  1357 + }
  1358 + }
  1359 + }
  1360 +}
board/freescale/imx8qm_arm2/imx8qm_arm2.c
... ... @@ -506,6 +506,15 @@
506 506 return 0;
507 507 }
508 508  
  509 +void board_quiesce_devices()
  510 +{
  511 + const char *power_on_devices[] = {
  512 + "dma_lpuart0",
  513 + };
  514 +
  515 + power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices));
  516 +}
  517 +
509 518 void detail_board_ddr_info(void)
510 519 {
511 520 puts("\nDDR ");
board/freescale/imx8qm_mek/imx8qm_mek.c
... ... @@ -351,6 +351,15 @@
351 351 return 0;
352 352 }
353 353  
  354 +void board_quiesce_devices(void)
  355 +{
  356 + const char *power_on_devices[] = {
  357 + "dma_lpuart0",
  358 + };
  359 +
  360 + power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices));
  361 +}
  362 +
354 363 void detail_board_ddr_info(void)
355 364 {
356 365 puts("\nDDR ");
board/freescale/imx8qxp_arm2/imx8qxp_arm2.c
... ... @@ -509,6 +509,19 @@
509 509 return 0;
510 510 }
511 511  
  512 +void board_quiesce_devices()
  513 +{
  514 + const char *power_on_devices[] = {
  515 + "dma_lpuart0",
  516 +
  517 + /* HIFI DSP boot */
  518 + "audio_sai0",
  519 + "audio_ocram",
  520 + };
  521 +
  522 + power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices));
  523 +}
  524 +
512 525 void detail_board_ddr_info(void)
513 526 {
514 527 puts("\nDDR ");
board/freescale/imx8qxp_mek/imx8qxp_mek.c
... ... @@ -495,6 +495,19 @@
495 495 return 0;
496 496 }
497 497  
  498 +void board_quiesce_devices()
  499 +{
  500 + const char *power_on_devices[] = {
  501 + "dma_lpuart0",
  502 +
  503 + /* HIFI DSP boot */
  504 + "audio_sai0",
  505 + "audio_ocram",
  506 + };
  507 +
  508 + power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices));
  509 +}
  510 +
498 511 void detail_board_ddr_info(void)
499 512 {
500 513 puts("\nDDR ");