diff options
author | Teo Hall <teo.hall@freescale.com> | 2015-10-30 09:00:36 -0500 |
---|---|---|
committer | Teo Hall <teo.hall@freescale.com> | 2015-11-03 12:06:57 -0600 |
commit | e290096e2d5cf7cc855d20a88079fd375873d0ae (patch) | |
tree | d8b4dae480a6550d131b02ee2faf809226fbfaf3 /arch/arm | |
parent | db8aeb24e942ce94ce8fbf9b5412016e71d85dfb (diff) |
MLK-11262-2: ARM: imx: Add MU messages for LPM messages
add LPM messages for:
-M4 reporting state
-M4 Request/Release High Bus Freq
-A7 tell M4 it is ready
Signed-off-by: Teo Hall <teo.hall@freescale.com>
(cherry picked from commit 52234ae38e6e4f2b3452d807dd1c1e199be6350c)
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-imx/common.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-imx/mu.c | 47 |
2 files changed, 45 insertions, 4 deletions
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index a41a00058bf6..cb3873fb2119 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -101,6 +101,8 @@ bool imx_src_is_m4_enabled(void); void mcc_receive_from_mu_buffer(unsigned int index, unsigned int *data); void mcc_send_via_mu_buffer(unsigned int index, unsigned int data); bool imx_mu_is_m4_in_low_freq(void); +bool imx_mu_is_m4_in_stop(void); +int imx_mu_lpm_ready(bool ready); unsigned int imx_gpcv2_is_mf_mix_off(void); int imx_gpc_mf_power_on(unsigned int irq, unsigned int on); #ifdef CONFIG_HAVE_IMX_GPCV2 diff --git a/arch/arm/mach-imx/mu.c b/arch/arm/mach-imx/mu.c index 56ab9ce18a6c..69ae71844e44 100644 --- a/arch/arm/mach-imx/mu.c +++ b/arch/arm/mach-imx/mu.c @@ -47,6 +47,11 @@ #define MU_LPM_M4_WAKEUP_ENABLE_MASK 0xF #define MU_LPM_M4_WAKEUP_ENABLE_SHIFT 0x0 +#define MU_LPM_M4_A7_READY 0xFFFFAAAA +#define MU_LPM_M4_RUN_MODE 0x5A5A0001 +#define MU_LPM_M4_WAIT_MODE 0x5A5A0002 +#define MU_LPM_M4_STOP_MODE 0x5A5A0003 + struct imx_mu_rpmsg_box { const char *name; struct blocking_notifier_head notifier; @@ -62,6 +67,7 @@ static u32 m4_message; static struct delayed_work mu_work, rpmsg_work; static u32 m4_wake_irqs[4]; static bool m4_freq_low; +static bool m4_in_stop; struct imx_sema4_mutex *mcc_shm_ptr; unsigned int imx_mcc_buffer_freed = 0, imx_mcc_buffer_queued = 0; @@ -70,6 +76,11 @@ static DECLARE_WAIT_QUEUE_HEAD(buffer_freed_wait_queue); /* Used for blocking recv */ static DECLARE_WAIT_QUEUE_HEAD(buffer_queued_wait_queue); +bool imx_mu_is_m4_in_stop(void) +{ + return m4_in_stop; +} + bool imx_mu_is_m4_in_low_freq(void) { return m4_freq_low; @@ -163,10 +174,18 @@ static void mu_work_handler(struct work_struct *work) pr_debug("receive M4 message 0x%x\n", m4_message); switch (m4_message) { + case MU_LPM_M4_RUN_MODE: + case MU_LPM_M4_WAIT_MODE: + m4_in_stop = false; + break; + case MU_LPM_M4_STOP_MODE: + m4_in_stop = true; + break; case MU_LPM_M4_REQUEST_HIGH_BUS: request_bus_freq(BUS_FREQ_HIGH); #ifdef CONFIG_SOC_IMX6SX - imx6sx_set_m4_highfreq(true); + if (cpu_is_imx6sx()) + imx6sx_set_m4_highfreq(true); #endif imx_mu_send_message(MU_LPM_HANDSHAKE_INDEX, MU_LPM_BUS_HIGH_READY_FOR_M4); @@ -175,10 +194,12 @@ static void mu_work_handler(struct work_struct *work) case MU_LPM_M4_RELEASE_HIGH_BUS: release_bus_freq(BUS_FREQ_HIGH); #ifdef CONFIG_SOC_IMX6SX - imx6sx_set_m4_highfreq(false); + if (cpu_is_imx6sx()) { + imx6sx_set_m4_highfreq(false); + imx_mu_send_message(MU_LPM_HANDSHAKE_INDEX, + MU_LPM_M4_FREQ_CHANGE_READY); + } #endif - imx_mu_send_message(MU_LPM_HANDSHAKE_INDEX, - MU_LPM_M4_FREQ_CHANGE_READY); m4_freq_low = true; break; default: @@ -219,6 +240,18 @@ int imx_mu_rpmsg_send(unsigned int rpmsg) return imx_mu_send_message(MU_RPMSG_HANDSHAKE_INDEX, rpmsg); } +int imx_mu_lpm_ready(bool ready) +{ + u32 val; + + val = readl_relaxed(mu_base + MU_ACR); + if (ready) + writel_relaxed(val | BIT(0), mu_base + MU_ACR); + else + writel_relaxed(val & ~BIT(0), mu_base + MU_ACR); + return 0; +} + int imx_mu_rpmsg_register_nb(const char *name, struct notifier_block *nb) { if ((name == NULL) || (nb == NULL)) @@ -566,6 +599,12 @@ static int imx_mu_probe(struct platform_device *pdev) /* enable the bit31(GIE3) of MU_ACR, used for MCC */ writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(31), mu_base + MU_ACR); + INIT_DELAYED_WORK(&mu_work, mu_work_handler); + INIT_DELAYED_WORK(&rpmsg_work, rpmsg_work_handler); + /* enable the bit26(RIE1) of MU_ACR */ + writel_relaxed(readl_relaxed(mu_base + MU_ACR) | + BIT(26) | BIT(27), mu_base + MU_ACR); + imx_mu_lpm_ready(true); } else { INIT_DELAYED_WORK(&mu_work, mu_work_handler); |