#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
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;
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;
/* 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");
}
} 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;
* 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))) {
/*
}
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)
{
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;
}
{
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);
}
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) {
}
}
- 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");
static const struct of_device_id imx_mu_ids[] = {
{ .compatible = "fsl,imx6sx-mu" },
{ .compatible = "fsl,imx7d-mu" },
+ { .compatible = "fsl,imx7ulp-mu" },
{ }
};