imx8m: power down fused cores
authorPeng Fan <peng.fan@nxp.com>
Thu, 9 Jul 2020 05:52:41 +0000 (13:52 +0800)
committerPeng Fan <peng.fan@nxp.com>
Tue, 14 Jul 2020 07:23:47 +0000 (15:23 +0800)
For non-Quad SoCs, the fused cpu cores could be powered down in SPL
to save power.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
arch/arm/include/asm/arch-imx8m/imx-regs.h
arch/arm/mach-imx/imx8m/soc.c

index 3cfa169..f1c410e 100644 (file)
@@ -331,5 +331,163 @@ struct bootrom_sw_info {
 #define ROM_SW_INFO_ADDR is_soc_rev(CHIP_REV_1_0) ? \
                (struct bootrom_sw_info **)ROM_SW_INFO_ADDR_A0 : \
                (struct bootrom_sw_info **)ROM_SW_INFO_ADDR_B0
+
+struct gpc_reg {
+       u32 lpcr_bsc;
+       u32 lpcr_ad;
+       u32 lpcr_cpu1;
+       u32 lpcr_cpu2;
+       u32 lpcr_cpu3;
+       u32 slpcr;
+       u32 mst_cpu_mapping;
+       u32 mmdc_cpu_mapping;
+       u32 mlpcr;
+       u32 pgc_ack_sel;
+       u32 pgc_ack_sel_m4;
+       u32 gpc_misc;
+       u32 imr1_core0;
+       u32 imr2_core0;
+       u32 imr3_core0;
+       u32 imr4_core0;
+       u32 imr1_core1;
+       u32 imr2_core1;
+       u32 imr3_core1;
+       u32 imr4_core1;
+       u32 imr1_cpu1;
+       u32 imr2_cpu1;
+       u32 imr3_cpu1;
+       u32 imr4_cpu1;
+       u32 imr1_cpu3;
+       u32 imr2_cpu3;
+       u32 imr3_cpu3;
+       u32 imr4_cpu3;
+       u32 isr1_cpu0;
+       u32 isr2_cpu0;
+       u32 isr3_cpu0;
+       u32 isr4_cpu0;
+       u32 isr1_cpu1;
+       u32 isr2_cpu1;
+       u32 isr3_cpu1;
+       u32 isr4_cpu1;
+       u32 isr1_cpu2;
+       u32 isr2_cpu2;
+       u32 isr3_cpu2;
+       u32 isr4_cpu2;
+       u32 isr1_cpu3;
+       u32 isr2_cpu3;
+       u32 isr3_cpu3;
+       u32 isr4_cpu3;
+       u32 slt0_cfg;
+       u32 slt1_cfg;
+       u32 slt2_cfg;
+       u32 slt3_cfg;
+       u32 slt4_cfg;
+       u32 slt5_cfg;
+       u32 slt6_cfg;
+       u32 slt7_cfg;
+       u32 slt8_cfg;
+       u32 slt9_cfg;
+       u32 slt10_cfg;
+       u32 slt11_cfg;
+       u32 slt12_cfg;
+       u32 slt13_cfg;
+       u32 slt14_cfg;
+       u32 pgc_cpu_0_1_mapping;
+       u32 cpu_pgc_up_trg;
+       u32 mix_pgc_up_trg;
+       u32 pu_pgc_up_trg;
+       u32 cpu_pgc_dn_trg;
+       u32 mix_pgc_dn_trg;
+       u32 pu_pgc_dn_trg;
+       u32 lpcr_bsc2;
+       u32 pgc_cpu_2_3_mapping;
+       u32 lps_cpu0;
+       u32 lps_cpu1;
+       u32 lps_cpu2;
+       u32 lps_cpu3;
+       u32 gpc_gpr;
+       u32 gtor;
+       u32 debug_addr1;
+       u32 debug_addr2;
+       u32 cpu_pgc_up_status1;
+       u32 mix_pgc_up_status0;
+       u32 mix_pgc_up_status1;
+       u32 mix_pgc_up_status2;
+       u32 m4_mix_pgc_up_status0;
+       u32 m4_mix_pgc_up_status1;
+       u32 m4_mix_pgc_up_status2;
+       u32 pu_pgc_up_status0;
+       u32 pu_pgc_up_status1;
+       u32 pu_pgc_up_status2;
+       u32 m4_pu_pgc_up_status0;
+       u32 m4_pu_pgc_up_status1;
+       u32 m4_pu_pgc_up_status2;
+       u32 a53_lp_io_0;
+       u32 a53_lp_io_1;
+       u32 a53_lp_io_2;
+       u32 cpu_pgc_dn_status1;
+       u32 mix_pgc_dn_status0;
+       u32 mix_pgc_dn_status1;
+       u32 mix_pgc_dn_status2;
+       u32 m4_mix_pgc_dn_status0;
+       u32 m4_mix_pgc_dn_status1;
+       u32 m4_mix_pgc_dn_status2;
+       u32 pu_pgc_dn_status0;
+       u32 pu_pgc_dn_status1;
+       u32 pu_pgc_dn_status2;
+       u32 m4_pu_pgc_dn_status0;
+       u32 m4_pu_pgc_dn_status1;
+       u32 m4_pu_pgc_dn_status2;
+       u32 res[3];
+       u32 mix_pdn_flg;
+       u32 pu_pdn_flg;
+       u32 m4_mix_pdn_flg;
+       u32 m4_pu_pdn_flg;
+       u32 imr1_core2;
+       u32 imr2_core2;
+       u32 imr3_core2;
+       u32 imr4_core2;
+       u32 imr1_core3;
+       u32 imr2_core3;
+       u32 imr3_core3;
+       u32 imr4_core3;
+       u32 pgc_ack_sel_pu;
+       u32 pgc_ack_sel_m4_pu;
+       u32 slt15_cfg;
+       u32 slt16_cfg;
+       u32 slt17_cfg;
+       u32 slt18_cfg;
+       u32 slt19_cfg;
+       u32 gpc_pu_pwrhsk;
+       u32 slt0_cfg_pu;
+       u32 slt1_cfg_pu;
+       u32 slt2_cfg_pu;
+       u32 slt3_cfg_pu;
+       u32 slt4_cfg_pu;
+       u32 slt5_cfg_pu;
+       u32 slt6_cfg_pu;
+       u32 slt7_cfg_pu;
+       u32 slt8_cfg_pu;
+       u32 slt9_cfg_pu;
+       u32 slt10_cfg_pu;
+       u32 slt11_cfg_pu;
+       u32 slt12_cfg_pu;
+       u32 slt13_cfg_pu;
+       u32 slt14_cfg_pu;
+       u32 slt15_cfg_pu;
+       u32 slt16_cfg_pu;
+       u32 slt17_cfg_pu;
+       u32 slt18_cfg_pu;
+       u32 slt19_cfg_pu;
+};
+
+struct pgc_reg {
+       u32 pgcr;
+       u32 pgpupscr;
+       u32 pgpdnscr;
+       u32 pgsr;
+       u32 pgauxsw;
+       u32 pgdr;
+};
 #endif
 #endif
index c103bc3..f74a343 100644 (file)
@@ -342,6 +342,25 @@ int arch_cpu_init(void)
        if (IS_ENABLED(CONFIG_SPL_BUILD)) {
                clock_init();
                imx_set_wdog_powerdown(false);
+
+               if (is_imx8md() || is_imx8mmd() || is_imx8mmdl() || is_imx8mms() ||
+                   is_imx8mmsl() || is_imx8mnd() || is_imx8mndl() || is_imx8mns() ||
+                   is_imx8mnsl() || is_imx8mpd()) {
+                       /* Power down cpu core 1, 2 and 3 for iMX8M Dual core or Single core */
+                       struct pgc_reg *pgc_core1 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x840);
+                       struct pgc_reg *pgc_core2 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x880);
+                       struct pgc_reg *pgc_core3 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x8C0);
+                       struct gpc_reg *gpc = (struct gpc_reg *)GPC_BASE_ADDR;
+
+                       writel(0x1, &pgc_core2->pgcr);
+                       writel(0x1, &pgc_core3->pgcr);
+                       if (is_imx8mms() || is_imx8mmsl() || is_imx8mns() || is_imx8mnsl()) {
+                               writel(0x1, &pgc_core1->pgcr);
+                               writel(0xE, &gpc->cpu_pgc_dn_trg);
+                       } else {
+                               writel(0xC, &gpc->cpu_pgc_dn_trg);
+                       }
+               }
        }
 
        if (is_imx8mq()) {