MLK-13577-1: ARM: imx: mu: support rpmsg/mu on i.mx7ulp
authorRobin Gong <yibin.gong@nxp.com>
Wed, 7 Dec 2016 03:28:45 +0000 (11:28 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 19:57:54 +0000 (14:57 -0500)
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>
arch/arm/boot/dts/imx7ulp.dtsi
arch/arm/mach-imx/imx_rpmsg.c
arch/arm/mach-imx/mu.c

index b3e9f35..a1e895a 100644 (file)
                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";
                };
 
index f58f856..39cfb0a 100644 (file)
@@ -274,6 +274,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);
@@ -304,6 +305,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;
index c992e58..fd4c58f 100644 (file)
 #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" },
        { }
 };