summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Gong <yibin.gong@nxp.com>2016-12-07 11:28:45 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:25:22 +0800
commitc072e47d343f4bc664c66aaeee9ed4b545ae2b41 (patch)
tree00d0b3c719f7a20f7a7088ca5a4aba119ceead7e
parent7d9c8b6779c0a5dc1f5cd1985abf219e0b9865a3 (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>
-rw-r--r--arch/arm/boot/dts/imx7ulp.dtsi3
-rw-r--r--arch/arm/mach-imx/imx_rpmsg.c4
-rw-r--r--arch/arm/mach-imx/mu.c136
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" },
{ }
};