#include <linux/smp.h>
#include <linux/cpumask.h>
#include <linux/io.h>
-#if defined(CONFIG_SMP) || defined(CONFIG_XILINX_AMP_CPU0_MASTER)
+#if defined(CONFIG_SMP) || \
+ defined(CONFIG_XILINX_AMP_CPU0_MASTER) || \
+ defined(CONFIG_ZYNQ_AMP_CPU0_MASTER)
#include <linux/module.h>
#endif
cpumask |= cpumask << 8;
cpumask |= cpumask << 16;
-#ifndef CONFIG_XILINX_AMP_CPU1_SLAVE
+#if !defined(CONFIG_XILINX_AMP_CPU1_SLAVE) && \
+ !defined(CONFIG_ZYNQ_AMP_CPU1_SLAVE)
+
writel_relaxed(0, base + GIC_DIST_CTRL);
/*
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
-#ifndef CONFIG_XILINX_AMP_CPU1_SLAVE
+#if !defined(CONFIG_XILINX_AMP_CPU1_SLAVE) && \
+ !defined(CONFIG_ZYNQ_AMP_CPU1_SLAVE)
+
writel_relaxed(1, base + GIC_DIST_CTRL);
#endif
local_irq_restore(flags);
}
-#if defined(CONFIG_SMP) || defined(CONFIG_XILINX_AMP_CPU0_MASTER) || defined(CONFIG_XILINX_CPU1_TEST)
+#if defined(CONFIG_SMP) || \
+ defined(CONFIG_XILINX_AMP_CPU0_MASTER) || \
+ defined(CONFIG_XILINX_CPU1_TEST) || \
+ defined(CONFIG_ZYNQ_AMP_CPU0_MASTER) || \
+ defined(CONFIG_ZYNQ_CPU1_TEST)
+
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
{
unsigned long map = *cpus_addr(*mask);
#include <mach/clkdev.h>
#include "common.h"
+#define IRQ_TIMERCOUNTER1 69
+#define IRQ_ETH1 77
+#define SDIO1_IRQ 79
+#define IRQ_I2C1 80
+#define IRQ_SPI1 81
+#define IRQ_UART1 82
+
static struct of_device_id zynq_of_bus_ids[] __initdata = {
{ .compatible = "simple-bus", },
{}
void __init xilinx_irq_init(void)
{
gic_init(0, 29, SCU_GIC_DIST_BASE, SCU_GIC_CPU_BASE);
+
+ /* when running in AMP mode on CPU0, allocate unused interrupts to the
+ * other CPU so another OS can run on it, or if just running Linux on
+ * the 2nd CPU as a test, do the same
+ */
+#if defined(CONFIG_XILINX_AMP_CPU0_MASTER) || \
+ defined(CONFIG_ZYNQ_AMP_CPU0_MASTER) || \
+ defined(CONFIG_XILINX_CPU1_TEST)
+
+ pr_info("Xilinx AMP: Setting IRQs to CPU1\n");
+ gic_set_cpu(1, IRQ_TIMERCOUNTER1);
+ gic_set_cpu(1, IRQ_TIMERCOUNTER1 + 1);
+ gic_set_cpu(1, IRQ_UART1);
+ gic_set_cpu(1, IRQ_I2C1);
+ gic_set_cpu(1, IRQ_ETH1);
+ gic_set_cpu(1, IRQ_SPI1);
+ gic_set_cpu(1, SDIO1_IRQ);
+#endif
+
}
/* The minimum devices needed to be mapped before the VM system is up and
#define UART0_PHYS 0xE0000000
#define UART0_VIRT UART0_PHYS
+#define UART1_PHYS 0xE0001000
+#define UART1_VIRT UART1_PHYS
+
#define TTC0_PHYS 0xF8001000
#define TTC0_VIRT TTC0_PHYS
/*
* Mandatory for CONFIG_LL_DEBUG, UART is mapped virtual = physical
+ * When running only on CPU1 or with AMP on CPU1 then use the 2nd
+ * UART
*/
-#define LL_UART_PADDR UART0_PHYS
-#define LL_UART_VADDR UART0_VIRT
+#if defined(CONFIG_XILINX_AMP_CPU1_SLAVE) || \
+ defined(CONFIG_XILINX_CPU1_TEST) || \
+ defined(CONFIG_ZYNQ_AMP_CPU1_SLAVE) || \
+ defined(CONFIG_ZYNQ_CPU1_TEST)
+
+ #define LL_UART_PADDR UART1_PHYS
+ #define LL_UART_VADDR UART1_VIRT
+#else
+ #define LL_UART_PADDR UART0_PHYS
+ #define LL_UART_VADDR UART0_VIRT
+#endif
#endif
#include <mach/zynq_soc.h>
#include "common.h"
-#define IRQ_TIMERCOUNTER0 42
-
/*
* This driver configures the 2 16-bit count-up timers as follows:
*
#define XTTCPSS_CLOCKSOURCE 0 /* Timer 1 as a generic timekeeping */
#define XTTCPSS_CLOCKEVENT 1 /* Timer 2 as a clock event */
-#define XTTCPSS_TIMER_BASE TTC0_BASE
-#define XTTCPCC_EVENT_TIMER_IRQ (IRQ_TIMERCOUNTER0 + 1)
+/* If running on the 2nd CPU then the 2nd timer is used, this code may not
+ * be pushed so it isn't ideal replicating the irq numbers, but they don't want
+ * #defines in header files unless used in multiple locations
+ */
+#if defined(CONFIG_XILINX_AMP_CPU1_SLAVE) || \
+ defined(CONFIG_XILINX_CPU1_TEST) || \
+ defined(CONFIG_ZYNQ_AMP_CPU1_SLAVE) || \
+ defined(CONFIG_ZYNQ_CPU1_TEST)
+
+ #define IRQ_TIMERCOUNTER1 69
+ #define XTTCPSS_TIMER_BASE TTC0_BASE + 0x1000
+ #define XTTCPCC_EVENT_TIMER_IRQ (IRQ_TIMERCOUNTER1 + 1)
+#else
+ #define IRQ_TIMERCOUNTER0 42
+ #define XTTCPSS_TIMER_BASE TTC0_BASE
+ #define XTTCPCC_EVENT_TIMER_IRQ (IRQ_TIMERCOUNTER0 + 1)
+#endif
/*
* Timer Register Offset Definitions of Timer 1, Increment base address by 4
* and use same offsets for Timer 2