summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeng Fan <peng.fan@nxp.com>2020-07-09 13:52:41 +0800
committerPeng Fan <peng.fan@nxp.com>2020-07-14 15:23:47 +0800
commit7a42bf048932af61e9f095a90edc96da394dee37 (patch)
tree68e51163c887741102a0c781657611cc6c484744
parentd1eee7eed90b8dc3053ddbe223cf4b3e75567b41 (diff)
imx8m: power down fused cores
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>
-rw-r--r--arch/arm/include/asm/arch-imx8m/imx-regs.h158
-rw-r--r--arch/arm/mach-imx/imx8m/soc.c19
2 files changed, 177 insertions, 0 deletions
diff --git a/arch/arm/include/asm/arch-imx8m/imx-regs.h b/arch/arm/include/asm/arch-imx8m/imx-regs.h
index 3cfa169c97..f1c410ec78 100644
--- a/arch/arm/include/asm/arch-imx8m/imx-regs.h
+++ b/arch/arm/include/asm/arch-imx8m/imx-regs.h
@@ -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
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c
index c103bc3ad1..f74a343ed8 100644
--- a/arch/arm/mach-imx/imx8m/soc.c
+++ b/arch/arm/mach-imx/imx8m/soc.c
@@ -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()) {