diff options
author | Robin Gong <yibin.gong@nxp.com> | 2016-12-07 11:28:45 +0800 |
---|---|---|
committer | Jason Liu <jason.hui.liu@nxp.com> | 2019-02-12 10:25:22 +0800 |
commit | c072e47d343f4bc664c66aaeee9ed4b545ae2b41 (patch) | |
tree | 00d0b3c719f7a20f7a7088ca5a4aba119ceead7e /arch/arm | |
parent | 7d9c8b6779c0a5dc1f5cd1985abf219e0b9865a3 (diff) |
MLK-13577-1: ARM: imx: mu: support rpmsg/mu on i.mx7ulp
Enable rpmsg/mu support on i.mx7ulp, since some mu register and
rmpsg buffer different as before
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Signed-off-by: Robin Gong <yibin.gong@nxp.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/boot/dts/imx7ulp.dtsi | 3 | ||||
-rw-r--r-- | arch/arm/mach-imx/imx_rpmsg.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-imx/mu.c | 136 |
3 files changed, 77 insertions, 66 deletions
diff --git a/arch/arm/boot/dts/imx7ulp.dtsi b/arch/arm/boot/dts/imx7ulp.dtsi index 284a5c62b1a1..173a3dd4d221 100644 --- a/arch/arm/boot/dts/imx7ulp.dtsi +++ b/arch/arm/boot/dts/imx7ulp.dtsi @@ -157,7 +157,8 @@ mu: mu@40220000 { compatible = "fsl,imx7ulp-mu", "fsl,imx6sx-mu"; reg = <0x40220000 0x1000>; - interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; status = "okay"; }; diff --git a/arch/arm/mach-imx/imx_rpmsg.c b/arch/arm/mach-imx/imx_rpmsg.c index 4566596dcb48..3bff09191e27 100644 --- a/arch/arm/mach-imx/imx_rpmsg.c +++ b/arch/arm/mach-imx/imx_rpmsg.c @@ -280,6 +280,7 @@ static struct imx_rpmsg_vproc imx_rpmsg_vprocs[] = { static const struct of_device_id imx_rpmsg_dt_ids[] = { { .compatible = "fsl,imx6sx-rpmsg", }, { .compatible = "fsl,imx7d-rpmsg", }, + { .compatible = "fsl,imx7ulp-rpmsg", }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, imx_rpmsg_dt_ids); @@ -310,6 +311,9 @@ static int imx_rpmsg_probe(struct platform_device *pdev) rpdev->vring[0] = 0xBFFF0000; rpdev->vring[1] = 0xBFFF8000; } + } else { + rpdev->vring[0] = 0x9FFF0000; + rpdev->vring[1] = 0x9FFF8000; } } else { break; diff --git a/arch/arm/mach-imx/mu.c b/arch/arm/mach-imx/mu.c index c992e586d8bc..fd4c58f9f157 100644 --- a/arch/arm/mach-imx/mu.c +++ b/arch/arm/mach-imx/mu.c @@ -29,6 +29,11 @@ #define MU_ARR1_OFFSET 0x14 #define MU_ASR 0x20 #define MU_ACR 0x24 +#define MX7ULP_MU_TR0 0x20 +#define MX7ULP_MU_RR0 0x40 +#define MX7ULP_MU_RR1 0x44 +#define MX7ULP_MU_SR 0x60 +#define MX7ULP_MU_CR 0x64 #define MU_LPM_HANDSHAKE_INDEX 0 #define MU_RPMSG_HANDSHAKE_INDEX 1 @@ -58,16 +63,12 @@ static struct imx_mu_rpmsg_box mu_rpmsg_box = { static void __iomem *mu_base; static u32 m4_message; -static struct delayed_work rpmsg_work; - -static u32 mu_int_en; static struct delayed_work mu_work, rpmsg_work; static u32 m4_wake_irqs[4]; static bool m4_freq_low; struct irq_domain *domain; static bool m4_in_stop; - void imx_mu_set_m4_run_mode(void) { m4_in_stop = false; @@ -108,34 +109,6 @@ static irqreturn_t mcc_m4_dummy_isr(int irq, void *param) return IRQ_HANDLED; } -int imx_mcc_bsp_int_disable(void) -{ - u32 val; - - /* Disablethe bit31(GIE3) and bit19(GIR3) of MU_ACR */ - mu_int_en = val = readl_relaxed(mu_base + MU_ACR); - val &= ~mu_int_en; - writel_relaxed(val, mu_base + MU_ACR); - - /* flush */ - val = readl_relaxed(mu_base + MU_ACR); - return 0; -} - -int imx_mcc_bsp_int_enable(void) -{ - u32 val; - - /* Enable bit31(GIE3) and bit19(GIR3) of MU_ACR */ - val = readl_relaxed(mu_base + MU_ACR); - val |= mu_int_en; - writel_relaxed(val, mu_base + MU_ACR); - - /* flush */ - val = readl_relaxed(mu_base + MU_ACR); - return 0; -} - static int imx_mu_send_message(unsigned int index, unsigned int data) { u32 val, ep; @@ -144,7 +117,10 @@ static int imx_mu_send_message(unsigned int index, unsigned int data) /* wait for transfer buffer empty, and no event pending */ do { - val = readl_relaxed(mu_base + MU_ASR); + if (cpu_is_imx7ulp()) + val = readl_relaxed(mu_base + MX7ULP_MU_SR); + else + val = readl_relaxed(mu_base + MU_ASR); ep = val & BIT(4); if (time_after(jiffies, timeout)) { pr_err("Waiting MU transmit buffer empty timeout!\n"); @@ -152,12 +128,18 @@ static int imx_mu_send_message(unsigned int index, unsigned int data) } } while (((val & (1 << (20 + 3 - index))) == 0) || (ep == BIT(4))); - writel_relaxed(data, mu_base + index * 0x4 + MU_ATR0_OFFSET); + if (cpu_is_imx7ulp()) + writel_relaxed(data, mu_base + index * 0x4 + MX7ULP_MU_TR0); + else + writel_relaxed(data, mu_base + index * 0x4 + MU_ATR0_OFFSET); /* * make a double check that TEn is not empty after write */ - val = readl_relaxed(mu_base + MU_ASR); + if (cpu_is_imx7ulp()) + val = readl_relaxed(mu_base + MX7ULP_MU_SR); + else + val = readl_relaxed(mu_base + MU_ASR); ep = val & BIT(4); if (((val & (1 << (20 + (3 - index)))) == 0) || (ep == BIT(4))) return 0; @@ -168,7 +150,10 @@ static int imx_mu_send_message(unsigned int index, unsigned int data) * Make sure that TEn flag is changed, after the ATRn is filled up. */ for (i = 0; i < 100; i++) { - val = readl_relaxed(mu_base + MU_ASR); + if (cpu_is_imx7ulp()) + val = readl_relaxed(mu_base + MX7ULP_MU_SR); + else + val = readl_relaxed(mu_base + MU_ASR); ep = val & BIT(4); if (((val & (1 << (20 + 3 - index))) == 0) || (ep == BIT(4))) { /* @@ -267,8 +252,12 @@ static void mu_work_handler(struct work_struct *work) } m4_message = 0; /* enable RIE3 interrupt */ - writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(27), - mu_base + MU_ACR); + if (cpu_is_imx7ulp()) + writel_relaxed(readl_relaxed(mu_base + MX7ULP_MU_CR) | BIT(27), + mu_base + MX7ULP_MU_CR); + else + writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(27), + mu_base + MU_ACR); } int imx_mu_rpmsg_send(unsigned int rpmsg) @@ -280,11 +269,19 @@ 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); + if (cpu_is_imx7ulp()) { + val = readl_relaxed(mu_base + MX7ULP_MU_CR); + if (ready) + writel_relaxed(val | BIT(0), mu_base + MX7ULP_MU_CR); + else + writel_relaxed(val & ~BIT(0), mu_base + MX7ULP_MU_CR); + } else { + 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; } @@ -327,21 +324,34 @@ static irqreturn_t imx_mu_isr(int irq, void *param) { u32 irqs; - irqs = readl_relaxed(mu_base + MU_ASR); + if (cpu_is_imx7ulp()) + irqs = readl_relaxed(mu_base + MX7ULP_MU_SR); + else + irqs = readl_relaxed(mu_base + MU_ASR); /* RPMSG */ if (irqs & (1 << 26)) { /* get message from receive buffer */ - m4_message = readl_relaxed(mu_base + MU_ARR1_OFFSET); + if (cpu_is_imx7ulp()) + m4_message = readl_relaxed(mu_base + MX7ULP_MU_RR1); + else + m4_message = readl_relaxed(mu_base + MU_ARR1_OFFSET); schedule_delayed_work(&rpmsg_work, 0); } if (irqs & (1 << 27)) { /* get message from receive buffer */ - m4_message = readl_relaxed(mu_base + MU_ARR0_OFFSET); + if (cpu_is_imx7ulp()) + m4_message = readl_relaxed(mu_base + MX7ULP_MU_RR0); + else + m4_message = readl_relaxed(mu_base + MU_ARR0_OFFSET); /* disable RIE3 interrupt */ - writel_relaxed(readl_relaxed(mu_base + MU_ACR) & (~BIT(27)), - mu_base + MU_ACR); + if (cpu_is_imx7ulp()) + writel_relaxed(readl_relaxed(mu_base + MX7ULP_MU_CR) + & (~BIT(27)), mu_base + MX7ULP_MU_CR); + else + writel_relaxed(readl_relaxed(mu_base + MU_ACR) + & (~BIT(27)), mu_base + MU_ACR); schedule_delayed_work(&mu_work, 0); } @@ -359,7 +369,11 @@ static int imx_mu_probe(struct platform_device *pdev) mu_base = of_iomap(np, 0); WARN_ON(!mu_base); - irq = platform_get_irq(pdev, 0); + ret = of_device_is_compatible(np, "fsl,imx7ulp-mu"); + if (ret) + irq = platform_get_irq(pdev, 1); + else + irq = platform_get_irq(pdev, 0); ret = request_irq(irq, imx_mu_isr, IRQF_EARLY_RESUME, "imx-mu", &mu_rpmsg_box); if (ret) { @@ -384,31 +398,22 @@ static int imx_mu_probe(struct platform_device *pdev) } } - INIT_DELAYED_WORK(&mu_work, mu_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); /* MU always as a wakeup source for low power mode */ imx_gpcv2_add_m4_wake_up_irq(irq_to_desc(irq)->irq_data.hwirq, true); } else { - INIT_DELAYED_WORK(&mu_work, mu_work_handler); - - /* enable the bit27(RIE3) of MU_ACR */ - writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(27), - mu_base + MU_ACR); - /* enable the bit31(GIE3) of MU_ACR, used for MCC */ - writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(31), - mu_base + MU_ACR); - /* MU always as a wakeup source for low power mode */ imx_gpc_add_m4_wake_up_irq(irq_to_desc(irq)->irq_data.hwirq, true); } + 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), - mu_base + MU_ACR); + if (cpu_is_imx7ulp()) + writel_relaxed(readl_relaxed(mu_base + MX7ULP_MU_CR) | + BIT(26) | BIT(27), mu_base + MX7ULP_MU_CR); + else + writel_relaxed(readl_relaxed(mu_base + MU_ACR) | + BIT(26) | BIT(27), mu_base + MU_ACR); BLOCKING_INIT_NOTIFIER_HEAD(&(mu_rpmsg_box.notifier)); pr_info("MU is ready for cross core communication!\n"); @@ -419,6 +424,7 @@ static int imx_mu_probe(struct platform_device *pdev) static const struct of_device_id imx_mu_ids[] = { { .compatible = "fsl,imx6sx-mu" }, { .compatible = "fsl,imx7d-mu" }, + { .compatible = "fsl,imx7ulp-mu" }, { } }; |