From 59969da7c8ef1908b0e70c800a6b3222c6e36d2b Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Fri, 10 Jan 2020 15:31:52 +0800 Subject: plat: imx8mq: Add anamix pll override setting for DSM mode Add the anamix PLL override setting for DSM mode support, so that the PLL can be power down in DSM mode to save power. Signed-off-by: Jacky Bai --- plat/imx/imx8m/gpc_common.c | 6 ++---- plat/imx/imx8m/imx8mq/gpc.c | 30 ++++++++++++++++++++++++++++++ plat/imx/imx8m/imx8mq/imx8mq_psci.c | 6 ++++-- plat/imx/imx8m/include/gpc.h | 5 +++++ 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/plat/imx/imx8m/gpc_common.c b/plat/imx/imx8m/gpc_common.c index fa058cc8..bd3163a4 100644 --- a/plat/imx/imx8m/gpc_common.c +++ b/plat/imx/imx8m/gpc_common.c @@ -256,10 +256,6 @@ void imx_clear_rbc_count(void) } #define MAX_PLL_NUM 10 -struct pll_override { - uint32_t reg; - uint32_t override_mask; -}; struct pll_override pll[MAX_PLL_NUM] = { {.reg = 0x0, .override_mask = (1 << 12) | (1 << 8), }, @@ -275,6 +271,8 @@ struct pll_override pll[MAX_PLL_NUM] = { }; #define PLL_BYPASS BIT(4) + +#pragma weak imx_anamix_override void imx_anamix_override(bool enter) { int i; diff --git a/plat/imx/imx8m/imx8mq/gpc.c b/plat/imx/imx8m/imx8mq/gpc.c index c15c8739..2baa027e 100644 --- a/plat/imx/imx8m/imx8mq/gpc.c +++ b/plat/imx/imx8m/imx8mq/gpc.c @@ -292,6 +292,36 @@ void imx_set_cluster_powerdown(unsigned int last_core, uint8_t power_state) } } +#define MAX_PLL_NUM 12 + +struct pll_override imx8mq_pll[MAX_PLL_NUM] = { + {.reg = 0x0, .override_mask = 0x140000, }, + {.reg = 0x8, .override_mask = 0x140000, }, + {.reg = 0x10, .override_mask = 0x140000, }, + {.reg = 0x18, .override_mask = 0x140000, }, + {.reg = 0x20, .override_mask = 0x140000, }, + {.reg = 0x28, .override_mask = 0x140000, }, + {.reg = 0x30, .override_mask = 0x1555540, }, + {.reg = 0x3c, .override_mask = 0x1555540, }, + {.reg = 0x48, .override_mask = 0x140, }, + {.reg = 0x54, .override_mask = 0x140, }, + {.reg = 0x60, .override_mask = 0x140, }, + {.reg = 0x70, .override_mask = 0xa, }, +}; + +void imx_anamix_override(bool enter) +{ + int i; + + /* enable the pll override bit before entering DSM mode */ + for (i = 0; i < MAX_PLL_NUM; i++) { + if (enter) + mmio_setbits_32(IMX_ANAMIX_BASE + imx8mq_pll[i].reg, imx8mq_pll[i].override_mask); + else + mmio_clrbits_32(IMX_ANAMIX_BASE + imx8mq_pll[i].reg, imx8mq_pll[i].override_mask); + } +} + int imx_gpc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, diff --git a/plat/imx/imx8m/imx8mq/imx8mq_psci.c b/plat/imx/imx8m/imx8mq/imx8mq_psci.c index 2d7befe2..a2ed2077 100644 --- a/plat/imx/imx8m/imx8mq/imx8mq_psci.c +++ b/plat/imx/imx8m/imx8mq/imx8mq_psci.c @@ -72,13 +72,14 @@ void imx_domain_suspend(const psci_power_state_t *target_state) } if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) - imx_set_cluster_powerdown(core_id, true); + imx_set_cluster_powerdown(core_id, CLUSTER_PWR_STATE(target_state)); else imx_set_cluster_standby(true); if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) { imx_set_sys_lpm(core_id, true); dram_enter_retention(); + imx_anamix_override(true); } } @@ -90,13 +91,14 @@ void imx_domain_suspend_finish(const psci_power_state_t *target_state) /* check the system level status */ if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) { dram_exit_retention(); + imx_anamix_override(true); imx_set_sys_lpm(core_id, false); imx_clear_rbc_count(); } /* check the cluster level power status */ if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) - imx_set_cluster_powerdown(core_id, false); + imx_set_cluster_powerdown(core_id, PSCI_LOCAL_STATE_RUN); else imx_set_cluster_standby(false); diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h index 4e870303..016e55d1 100644 --- a/plat/imx/imx8m/include/gpc.h +++ b/plat/imx/imx8m/include/gpc.h @@ -117,6 +117,11 @@ struct imx_pwr_domain { bool init_on; }; +struct pll_override { + uint32_t reg; + uint32_t override_mask; +}; + DECLARE_BAKERY_LOCK(gpc_lock); /* function declare */ -- cgit v1.2.3