ARCv2: intc: untangle SMP, MCIP and IDU
The IDU intc is technically part of MCIP (Multi-core IP) hence historically was only available in a SMP hardware build (and thus only in a SMP kernel build). Now that hardware restriction has been lifted, so a UP kernel needs to support it. This requires breaking mcip.c into parts which are strictly SMP (inter-core interrupts) and IDU which in reality is just another intc and thus has no bearing on SMP. This change allows IDU in UP builds and with a suitable device tree, we can have the cascaded intc system ARCv2 core intc <---> ARCv2 IDU intc <---> periperals Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
This commit is contained in:
parent
1001354ca3
commit
3ce0fefc51
|
@ -186,14 +186,6 @@ if SMP
|
||||||
config ARC_HAS_COH_CACHES
|
config ARC_HAS_COH_CACHES
|
||||||
def_bool n
|
def_bool n
|
||||||
|
|
||||||
config ARC_MCIP
|
|
||||||
bool "ARConnect Multicore IP (MCIP) Support "
|
|
||||||
depends on ISA_ARCV2
|
|
||||||
help
|
|
||||||
This IP block enables SMP in ARC-HS38 cores.
|
|
||||||
It provides for cross-core interrupts, multi-core debug
|
|
||||||
hardware semaphores, shared memory,....
|
|
||||||
|
|
||||||
config NR_CPUS
|
config NR_CPUS
|
||||||
int "Maximum number of CPUs (2-4096)"
|
int "Maximum number of CPUs (2-4096)"
|
||||||
range 2 4096
|
range 2 4096
|
||||||
|
@ -211,6 +203,15 @@ config ARC_SMP_HALT_ON_RESET
|
||||||
|
|
||||||
endif #SMP
|
endif #SMP
|
||||||
|
|
||||||
|
config ARC_MCIP
|
||||||
|
bool "ARConnect Multicore IP (MCIP) Support "
|
||||||
|
depends on ISA_ARCV2
|
||||||
|
default y if SMP
|
||||||
|
help
|
||||||
|
This IP block enables SMP in ARC-HS38 cores.
|
||||||
|
It provides for cross-core interrupts, multi-core debug
|
||||||
|
hardware semaphores, shared memory,....
|
||||||
|
|
||||||
menuconfig ARC_CACHE
|
menuconfig ARC_CACHE
|
||||||
bool "Enable Cache Support"
|
bool "Enable Cache Support"
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -55,6 +55,22 @@ struct mcip_cmd {
|
||||||
#define IDU_M_DISTRI_DEST 0x2
|
#define IDU_M_DISTRI_DEST 0x2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mcip_bcr {
|
||||||
|
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||||
|
unsigned int pad3:8,
|
||||||
|
idu:1, llm:1, num_cores:6,
|
||||||
|
iocoh:1, gfrc:1, dbg:1, pad2:1,
|
||||||
|
msg:1, sem:1, ipi:1, pad:1,
|
||||||
|
ver:8;
|
||||||
|
#else
|
||||||
|
unsigned int ver:8,
|
||||||
|
pad:1, ipi:1, sem:1, msg:1,
|
||||||
|
pad2:1, dbg:1, gfrc:1, iocoh:1,
|
||||||
|
num_cores:6, llm:1, idu:1,
|
||||||
|
pad3:8;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MCIP programming model
|
* MCIP programming model
|
||||||
*
|
*
|
||||||
|
|
|
@ -15,11 +15,12 @@
|
||||||
#include <asm/mcip.h>
|
#include <asm/mcip.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
|
|
||||||
static char smp_cpuinfo_buf[128];
|
|
||||||
static int idu_detected;
|
|
||||||
|
|
||||||
static DEFINE_RAW_SPINLOCK(mcip_lock);
|
static DEFINE_RAW_SPINLOCK(mcip_lock);
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
|
||||||
|
static char smp_cpuinfo_buf[128];
|
||||||
|
|
||||||
static void mcip_setup_per_cpu(int cpu)
|
static void mcip_setup_per_cpu(int cpu)
|
||||||
{
|
{
|
||||||
smp_ipi_irq_setup(cpu, IPI_IRQ);
|
smp_ipi_irq_setup(cpu, IPI_IRQ);
|
||||||
|
@ -86,21 +87,7 @@ static void mcip_ipi_clear(int irq)
|
||||||
|
|
||||||
static void mcip_probe_n_setup(void)
|
static void mcip_probe_n_setup(void)
|
||||||
{
|
{
|
||||||
struct mcip_bcr {
|
struct mcip_bcr mp;
|
||||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
|
||||||
unsigned int pad3:8,
|
|
||||||
idu:1, llm:1, num_cores:6,
|
|
||||||
iocoh:1, gfrc:1, dbg:1, pad2:1,
|
|
||||||
msg:1, sem:1, ipi:1, pad:1,
|
|
||||||
ver:8;
|
|
||||||
#else
|
|
||||||
unsigned int ver:8,
|
|
||||||
pad:1, ipi:1, sem:1, msg:1,
|
|
||||||
pad2:1, dbg:1, gfrc:1, iocoh:1,
|
|
||||||
num_cores:6, llm:1, idu:1,
|
|
||||||
pad3:8;
|
|
||||||
#endif
|
|
||||||
} mp;
|
|
||||||
|
|
||||||
READ_BCR(ARC_REG_MCIP_BCR, mp);
|
READ_BCR(ARC_REG_MCIP_BCR, mp);
|
||||||
|
|
||||||
|
@ -114,7 +101,6 @@ static void mcip_probe_n_setup(void)
|
||||||
IS_AVAIL1(mp.gfrc, "GFRC"));
|
IS_AVAIL1(mp.gfrc, "GFRC"));
|
||||||
|
|
||||||
cpuinfo_arc700[0].extn.gfrc = mp.gfrc;
|
cpuinfo_arc700[0].extn.gfrc = mp.gfrc;
|
||||||
idu_detected = mp.idu;
|
|
||||||
|
|
||||||
if (mp.dbg) {
|
if (mp.dbg) {
|
||||||
__mcip_cmd_data(CMD_DEBUG_SET_SELECT, 0, 0xf);
|
__mcip_cmd_data(CMD_DEBUG_SET_SELECT, 0, 0xf);
|
||||||
|
@ -130,6 +116,8 @@ struct plat_smp_ops plat_smp_ops = {
|
||||||
.ipi_clear = mcip_ipi_clear,
|
.ipi_clear = mcip_ipi_clear,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* ARCv2 Interrupt Distribution Unit (IDU)
|
* ARCv2 Interrupt Distribution Unit (IDU)
|
||||||
*
|
*
|
||||||
|
@ -295,8 +283,11 @@ idu_of_init(struct device_node *intc, struct device_node *parent)
|
||||||
/* Read IDU BCR to confirm nr_irqs */
|
/* Read IDU BCR to confirm nr_irqs */
|
||||||
int nr_irqs = of_irq_count(intc);
|
int nr_irqs = of_irq_count(intc);
|
||||||
int i, irq;
|
int i, irq;
|
||||||
|
struct mcip_bcr mp;
|
||||||
|
|
||||||
if (!idu_detected)
|
READ_BCR(ARC_REG_MCIP_BCR, mp);
|
||||||
|
|
||||||
|
if (!mp.idu)
|
||||||
panic("IDU not detected, but DeviceTree using it");
|
panic("IDU not detected, but DeviceTree using it");
|
||||||
|
|
||||||
pr_info("MCIP: IDU referenced from Devicetree %d irqs\n", nr_irqs);
|
pr_info("MCIP: IDU referenced from Devicetree %d irqs\n", nr_irqs);
|
||||||
|
|
Loading…
Reference in New Issue