summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacky Bai <ping.bai@nxp.com>2020-01-20 13:56:56 +0800
committerJacky Bai <ping.bai@nxp.com>2020-02-09 20:58:49 +0800
commit2a045c8600f2bcab3a7bd7c36c64db49638ed1a9 (patch)
treefc3d5d887db84d349af63b3973441d077f6773d3
parent9dec5b6f55f236304f40f2181e3784c01708a97a (diff)
plat: imx8m: Add the M4 low power audio support on imx8m
Add the M core low power audio support on i.MX8M. Signed-off-by: Jacky Bai <ping.bai@nxp.com>
-rw-r--r--plat/imx/imx8m/gpc_common.c35
-rw-r--r--plat/imx/imx8m/imx8m_psci_common.c22
-rw-r--r--plat/imx/imx8m/imx8mm/gpc.c3
-rw-r--r--plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c2
-rw-r--r--plat/imx/imx8m/imx8mm/include/platform_def.h2
-rw-r--r--plat/imx/imx8m/imx8mn/gpc.c3
-rw-r--r--plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c2
-rw-r--r--plat/imx/imx8m/imx8mn/include/platform_def.h5
-rw-r--r--plat/imx/imx8m/imx8mq/include/platform_def.h2
-rw-r--r--plat/imx/imx8m/include/gpc.h1
10 files changed, 58 insertions, 19 deletions
diff --git a/plat/imx/imx8m/gpc_common.c b/plat/imx/imx8m/gpc_common.c
index 9dc1ec80..85201f80 100644
--- a/plat/imx/imx8m/gpc_common.c
+++ b/plat/imx/imx8m/gpc_common.c
@@ -20,6 +20,10 @@
#define FSL_SIP_CONFIG_GPC_PM_DOMAIN 0x03
+#define M4_LPA_ACTIVE 0x5555
+#define M4_LPA_IDLE 0x0
+#define LPA_STATUS U(0x94)
+
static uint32_t gpc_imr_offset[] = { 0x30, 0x40, 0x1c0, 0x1d0, };
DEFINE_BAKERY_LOCK(gpc_lock);
@@ -31,6 +35,16 @@ struct plat_gic_ctx imx_gicv3_ctx;
#pragma weak imx_set_cpu_lpm
#pragma weak imx_set_cluster_powerdown
+bool imx_m4_lpa_active(void)
+{
+ return mmio_read_32(IMX_SRC_BASE + LPA_STATUS) & M4_LPA_ACTIVE;
+}
+
+bool imx_is_m4_enabled(void)
+{
+ return mmio_read_32(IMX_M4_STATUS) & IMX_M4_ENABLED;
+}
+
void imx_set_cpu_secure_entry(unsigned int core_id, uintptr_t sec_entrypoint)
{
uint64_t temp_base;
@@ -211,6 +225,10 @@ void imx_set_sys_wakeup(unsigned int last_core, bool pdn)
mmio_write_32(IMX_GPC_BASE + gpc_imr_offset[last_core] + i * 4,
irq_mask);
}
+
+ /* enable the MU wakeup */
+ if (imx_is_m4_enabled())
+ mmio_clrbits_32(IMX_GPC_BASE + gpc_imr_offset[last_core] + 0x8, BIT(24));
}
void imx_noc_slot_config(bool pdn)
@@ -232,17 +250,16 @@ void imx_noc_slot_config(bool pdn)
/* this is common for all imx8m soc */
void imx_set_sys_lpm(unsigned int last_core, bool retention)
{
- uint32_t val;
-
- val = mmio_read_32(IMX_GPC_BASE + SLPCR);
- val &= ~(SLPCR_EN_DSM | SLPCR_VSTBY | SLPCR_SBYOS |
- SLPCR_BYPASS_PMIC_READY | SLPCR_A53_FASTWUP_STOP_MODE);
-
if (retention)
- val |= (SLPCR_EN_DSM | SLPCR_VSTBY | SLPCR_SBYOS |
- SLPCR_BYPASS_PMIC_READY);
+ mmio_clrsetbits_32(IMX_GPC_BASE + SLPCR, SLPCR_A53_FASTWUP_STOP_MODE,
+ SLPCR_EN_DSM | SLPCR_VSTBY | SLPCR_SBYOS | SLPCR_BYPASS_PMIC_READY);
+ else
+ mmio_clrsetbits_32(IMX_GPC_BASE + SLPCR, SLPCR_EN_DSM | SLPCR_VSTBY |
+ SLPCR_SBYOS | SLPCR_BYPASS_PMIC_READY, SLPCR_A53_FASTWUP_STOP_MODE);
- mmio_write_32(IMX_GPC_BASE + SLPCR, val);
+ /* mask M4 DSM trigger if M4 is NOT enabled */
+ if (!imx_is_m4_enabled())
+ mmio_setbits_32(IMX_GPC_BASE + LPCR_M4, BIT(31));
/* config wakeup irqs' mask in gpc */
imx_set_sys_wakeup(last_core, retention);
diff --git a/plat/imx/imx8m/imx8m_psci_common.c b/plat/imx/imx8m/imx8m_psci_common.c
index fc649d51..f646de62 100644
--- a/plat/imx/imx8m/imx8m_psci_common.c
+++ b/plat/imx/imx8m/imx8m_psci_common.c
@@ -121,10 +121,13 @@ void imx_domain_suspend(const psci_power_state_t *target_state)
imx_set_cluster_powerdown(core_id, CLUSTER_PWR_STATE(target_state));
if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) {
- imx_set_sys_lpm(core_id, true);
- dram_enter_retention();
- imx_anamix_override(true);
- imx_noc_wrapper_pre_suspend(core_id);
+ if (!imx_m4_lpa_active()) {
+ imx_set_sys_lpm(core_id, true);
+ dram_enter_retention();
+ imx_anamix_override(true);
+ imx_noc_wrapper_pre_suspend(core_id);
+ }
+ imx_set_sys_wakeup(core_id, true);
}
}
@@ -134,10 +137,13 @@ void imx_domain_suspend_finish(const psci_power_state_t *target_state)
unsigned int core_id = MPIDR_AFFLVL0_VAL(mpidr);
if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) {
- imx_noc_wrapper_post_resume(core_id);
- imx_anamix_override(false);
- dram_exit_retention();
- imx_set_sys_lpm(core_id, false);
+ if (!imx_m4_lpa_active()) {
+ imx_noc_wrapper_post_resume(core_id);
+ imx_anamix_override(false);
+ dram_exit_retention();
+ imx_set_sys_lpm(core_id, false);
+ }
+ imx_set_sys_wakeup(core_id, false);
}
if (!is_local_state_run(CLUSTER_PWR_STATE(target_state))) {
diff --git a/plat/imx/imx8m/imx8mm/gpc.c b/plat/imx/imx8m/imx8mm/gpc.c
index afd39051..75e103d7 100644
--- a/plat/imx/imx8m/imx8mm/gpc.c
+++ b/plat/imx/imx8m/imx8mm/gpc.c
@@ -443,8 +443,9 @@ void imx_gpc_init(void)
/* clear DSM by default */
val = mmio_read_32(IMX_GPC_BASE + SLPCR);
val &= ~SLPCR_EN_DSM;
- /* enable the fast wakeup wait mode */
+ /* enable the fast wakeup wait/stop mode */
val |= SLPCR_A53_FASTWUP_WAIT_MODE;
+ val |= SLPCR_A53_FASTWUP_STOP_MODE;
/* clear the RBC */
val &= ~(0x3f << SLPCR_RBC_COUNT_SHIFT);
/* set the STBY_COUNT to 0x5, (128 * 30)us */
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
index 1e7b32fa..1f0e21cb 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
@@ -56,6 +56,8 @@ static const struct imx_rdc_cfg rdc[] = {
RDC_MDAn(0x1, DID1),
/* peripherals domain permission */
+ RDC_PDAPn(70, D1R | D1W),
+ RDC_PDAPn(105, D0R | D0W),
/* memory region */
diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
index 5eedaa02..2d30f680 100644
--- a/plat/imx/imx8m/imx8mm/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mm/include/platform_def.h
@@ -118,6 +118,8 @@
#define SRC_SCR_M4_ENABLE_MASK BIT(3)
#define SRC_SCR_M4C_NON_SCLR_RST_MASK BIT(0)
+#define IMX_M4_STATUS (IMX_SRC_BASE + SRC_M4RCR)
+#define IMX_M4_ENABLED SRC_SCR_M4C_NON_SCLR_RST_MASK
#define SNVS_LPCR U(0x38)
#define SNVS_LPCR_SRTC_ENV BIT(0)
diff --git a/plat/imx/imx8m/imx8mn/gpc.c b/plat/imx/imx8m/imx8mn/gpc.c
index db48f803..246422d9 100644
--- a/plat/imx/imx8m/imx8mn/gpc.c
+++ b/plat/imx/imx8m/imx8mn/gpc.c
@@ -238,8 +238,9 @@ void imx_gpc_init(void)
/* clear DSM by default */
val = mmio_read_32(IMX_GPC_BASE + SLPCR);
val &= ~SLPCR_EN_DSM;
- /* enable the fast wakeup wait mode */
+ /* enable the fast wakeup wait/stop mode */
val |= SLPCR_A53_FASTWUP_WAIT_MODE;
+ val |= SLPCR_A53_FASTWUP_STOP_MODE;
/* clear the RBC */
val &= ~(0x3f << SLPCR_RBC_COUNT_SHIFT);
/* set the STBY_COUNT to 0x5, (128 * 30)us */
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
index 7078767d..0c856c75 100644
--- a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
@@ -55,6 +55,8 @@ static const struct imx_rdc_cfg rdc[] = {
RDC_MDAn(0x1, DID1),
/* peripherals domain permission */
+ RDC_PDAPn(70, D1R | D1W),
+ RDC_PDAPn(105, D0R | D0W),
/* memory region */
RDC_MEM_REGIONn(16, 0x0, 0x0, 0xff),
diff --git a/plat/imx/imx8m/imx8mn/include/platform_def.h b/plat/imx/imx8m/imx8mn/include/platform_def.h
index e90fc8dd..32fb3cc5 100644
--- a/plat/imx/imx8m/imx8mn/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mn/include/platform_def.h
@@ -122,6 +122,11 @@
#define IOMUXC_GPR10 U(0x28)
#define GPR_TZASC_EN BIT(0)
#define GPR_TZASC_EN_LOCK BIT(16)
+#define IOMUXC_GPR22 U(0x58)
+#define GPR_CM7_CPUWAIT BIT(0)
+#define IMX_M4_STATUS (IMX_IOMUX_GPR_BASE + IOMUXC_GPR22)
+#define IMX_M4_ENABLED GPR_CM7_CPUWAIT
+
#define ANAMIX_MISC_CTL U(0x124)
#define DRAM_PLL_CTRL (IMX_ANAMIX_BASE + 0x50)
diff --git a/plat/imx/imx8m/imx8mq/include/platform_def.h b/plat/imx/imx8m/imx8mq/include/platform_def.h
index dba6efc7..4f8a07cd 100644
--- a/plat/imx/imx8m/imx8mq/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mq/include/platform_def.h
@@ -115,6 +115,8 @@
#define SRC_SCR_M4_ENABLE_MASK BIT(3)
#define SRC_SCR_M4C_NON_SCLR_RST_MASK BIT(0)
+#define IMX_M4_STATUS (IMX_SRC_BASE + SRC_M4RCR)
+#define IMX_M4_ENABLED SRC_SCR_M4C_NON_SCLR_RST_MASK
#define SNVS_LPCR U(0x38)
#define SNVS_LPCR_SRTC_ENV BIT(0)
diff --git a/plat/imx/imx8m/include/gpc.h b/plat/imx/imx8m/include/gpc.h
index 66db543e..96878fc1 100644
--- a/plat/imx/imx8m/include/gpc.h
+++ b/plat/imx/imx8m/include/gpc.h
@@ -151,6 +151,7 @@ void imx_anamix_override(bool enter);
void imx_gpc_pm_domain_enable(uint32_t domain_id, bool on);
void imx_noc_wrapper_pre_suspend(unsigned int proc_num);
void imx_noc_wrapper_post_resume(unsigned int proc_num);
+bool imx_m4_lpa_active(void);
#if defined(PLAT_imx8mq)
void imx_gpc_set_a53_core_awake(uint32_t core_id);