Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ce0fefc authored by Vineet Gupta's avatar Vineet Gupta
Browse files

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: default avatarVineet Gupta <vgupta@synopsys.com>
parent 1001354c
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -186,14 +186,6 @@ if SMP
config ARC_HAS_COH_CACHES
	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
	int "Maximum number of CPUs (2-4096)"
	range 2 4096
@@ -211,6 +203,15 @@ config ARC_SMP_HALT_ON_RESET

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
	bool "Enable Cache Support"
	default y
+16 −0
Original line number Diff line number Diff line
@@ -55,6 +55,22 @@ struct mcip_cmd {
#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
 *
+11 −20
Original line number Diff line number Diff line
@@ -15,11 +15,12 @@
#include <asm/mcip.h>
#include <asm/setup.h>

static char smp_cpuinfo_buf[128];
static int idu_detected;

static DEFINE_RAW_SPINLOCK(mcip_lock);

#ifdef CONFIG_SMP

static char smp_cpuinfo_buf[128];

static void mcip_setup_per_cpu(int cpu)
{
	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)
{
	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
	} mp;
	struct 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"));

	cpuinfo_arc700[0].extn.gfrc = mp.gfrc;
	idu_detected = mp.idu;

	if (mp.dbg) {
		__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,
};

#endif

/***************************************************************************
 * 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 */
	int nr_irqs = of_irq_count(intc);
	int i, irq;
	struct mcip_bcr mp;

	READ_BCR(ARC_REG_MCIP_BCR, mp);

	if (!idu_detected)
	if (!mp.idu)
		panic("IDU not detected, but DeviceTree using it");

	pr_info("MCIP: IDU referenced from Devicetree %d irqs\n", nr_irqs);