From 2a045c8600f2bcab3a7bd7c36c64db49638ed1a9 Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Mon, 20 Jan 2020 13:56:56 +0800 Subject: 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 --- plat/imx/imx8m/gpc_common.c | 35 +++++++++++++++++++++------- plat/imx/imx8m/imx8m_psci_common.c | 22 ++++++++++------- plat/imx/imx8m/imx8mm/gpc.c | 3 ++- plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c | 2 ++ plat/imx/imx8m/imx8mm/include/platform_def.h | 2 ++ plat/imx/imx8m/imx8mn/gpc.c | 3 ++- plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c | 2 ++ plat/imx/imx8m/imx8mn/include/platform_def.h | 5 ++++ plat/imx/imx8m/imx8mq/include/platform_def.h | 2 ++ plat/imx/imx8m/include/gpc.h | 1 + 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); -- cgit v1.2.3