Skip to contentSkip to conversation

Netlogic XLR/XLS/XLP updates

PATCH In review Jayachandran C 2 participants 20 messages Oct 31, 2012 – Nov 28, 2012

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover Netlogic XLR/XLS/XLP updates

Here's is the next patchset for Netlogic XLR/XLS/XLP CPUs. The highlights are:
* Support for XLP multi-chip boards, this feature allows two or four XLPs to be connected using an interconnect(ICI) to form a coherent SMP system with upto 128 cpus (only 64 supported now).
* Support for XLR/XLS fast message network. The XLR/XLS CPU cores talk to the high speed interfaces using a messaging mechanism which uses the co-processor 2 on the CPU core. The code is to intialize the bucket (message queue) sizes, and to distribute credits on the queues to the devices (stations).
* oprofile support for XLR and perf support for XLP (this has been posted a few times)

The patchset also includes few fixes to the XLR/XLS/XLP code.

JC.

Ganesan Ramalingam (1):
MIPS: Netlogic: Support for XLR/XLS Fast Message Network

Jayachandran C (12):
MIPS: Netlogic: select MIPSR2 for XLP
MIPS: Netlogic: Enable SUE bit in cores
MIPS: Netlogic: keep .dtb/.dtb.S until make clean
MIPS: Netlogic: Move fdt init to plat_mem_setup
MIPS: Netlogic: Fix DMA zone selection for 64-bit
MIPS: Netlogic: Fix interrupt table entry init
MIPS: Netlogic: Pass cpuid to early_init_secondary
MIPS: Netlogic: Update PIC access functions
MIPS: Netlogic: Move from u32 cpumask to cpumask_t
MIPS: Netlogic: Support for multi-chip configuration
MIPS: Netlogic: Make number of nodes configurable
MIPS: Netlogic: PIC IRQ handling update for multi-chip

Madhusudan Bhat (1):
MIPS: oprofile: Support for XLR/XLS processors

Zi Shen Lim (1):
MIPS: perf: Add XLP support for hardware perf.

 arch/mips/Kconfig                                |    9 +-
 arch/mips/include/asm/mach-netlogic/irq.h        |    4 +-
 arch/mips/include/asm/mach-netlogic/multi-node.h |   54 ++++
 arch/mips/include/asm/netlogic/common.h          |   51 ++-
 arch/mips/include/asm/netlogic/interrupt.h       |    2 +-
 arch/mips/include/asm/netlogic/mips-extns.h      |  142 +++++++++
 arch/mips/include/asm/netlogic/xlp-hal/pic.h     |   44 +--
 arch/mips/include/asm/netlogic/xlp-hal/sys.h     |    1 -
 arch/mips/include/asm/netlogic/xlr/fmn.h         |  363 ++++++++++++++++++++++
 arch/mips/include/asm/netlogic/xlr/pic.h         |    2 -
 arch/mips/include/asm/netlogic/xlr/xlr.h         |    6 +-
 arch/mips/kernel/perf_event_mipsxx.c             |  124 ++++++++
 arch/mips/netlogic/Kconfig                       |   28 ++
 arch/mips/netlogic/common/irq.c                  |  165 ++++++----
 arch/mips/netlogic/common/smp.c                  |   89 +++---
 arch/mips/netlogic/common/smpboot.S              |    6 +-
 arch/mips/netlogic/dts/Makefile                  |   16 +-
 arch/mips/netlogic/xlp/nlm_hal.c                 |   67 +---
 arch/mips/netlogic/xlp/setup.c                   |   50 +--
 arch/mips/netlogic/xlp/wakeup.c                  |   83 +++--
 arch/mips/netlogic/xlr/Makefile                  |    4 +-
 arch/mips/netlogic/xlr/fmn-config.c              |  290 +++++++++++++++++
 arch/mips/netlogic/xlr/fmn.c                     |  204 ++++++++++++
 arch/mips/netlogic/xlr/setup.c                   |   37 ++-
 arch/mips/netlogic/xlr/wakeup.c                  |   23 +-
 arch/mips/oprofile/Makefile                      |    1 +
 arch/mips/oprofile/common.c                      |    1 +
 arch/mips/oprofile/op_model_mipsxx.c             |   29 ++
 28 files changed, 1620 insertions(+), 275 deletions(-)
 create mode 100644 arch/mips/include/asm/mach-netlogic/multi-node.h
 create mode 100644 arch/mips/include/asm/netlogic/xlr/fmn.h
 create mode 100644 arch/mips/netlogic/xlr/fmn-config.c
 create mode 100644 arch/mips/netlogic/xlr/fmn.c
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH 1/15 MIPS: oprofile: Support for XLR/XLS processors

From: Madhusudan Bhat <[email protected]>

Add support for XLR and XLS processors in MIPS Oprofile code. These processors are multi-threaded and have two counters per core. Each counter can track either all the events in the core (global mode), or events in just one thread.

We use the counters in the global mode, and use only the first thread in each core to handle the configuration etc.

---
 arch/mips/oprofile/Makefile          |    1 +
 arch/mips/oprofile/common.c          |    1 +
 arch/mips/oprofile/op_model_mipsxx.c |   29 +++++++++++++++++++++++++++++
 3 files changed, 31 insertions(+)
arch/mips/oprofile/Makefile +1 -0
index 1208c28..65f5237 100644
@@ -12,5 +12,6 @@ oprofile-$(CONFIG_CPU_MIPS32)		+= op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_MIPS64)		+= op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_R10000)		+= op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_SB1)		+= op_model_mipsxx.o
+oprofile-$(CONFIG_CPU_XLR)		+= op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_RM9000)		+= op_model_rm9000.o
 oprofile-$(CONFIG_CPU_LOONGSON2)	+= op_model_loongson2.o
arch/mips/oprofile/common.c +1 -0
index f80480a..abd5a02 100644
@@ -91,6 +91,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
 	case CPU_R10000:
 	case CPU_R12000:
 	case CPU_R14000:
+	case CPU_XLR:
 		lmodel = &op_model_mipsxx_ops;
 		break;
 
arch/mips/oprofile/op_model_mipsxx.c +29 -0
index 28ea1a4..7862546 100644
@@ -31,8 +31,22 @@
 
 #define M_COUNTER_OVERFLOW		(1UL      << 31)
 
+/* Netlogic XLR specific, count events in all threads in a core */
+#define M_PERFCTL_COUNT_ALL_THREADS	(1UL      << 13)
+
 static int (*save_perf_irq)(void);
 
+/*
+ * XLR has only one set of counters per core. Designate the
+ * first hardware thread in the core for setup and init.
+ * Skip CPUs with non-zero hardware thread id (4 hwt per core)
+ */
+#ifdef CONFIG_CPU_XLR
+#define oprofile_skip_cpu(c)	((cpu_logical_map(c) & 0x3) != 0)
+#else
+#define oprofile_skip_cpu(c)	0
+#endif
+
 #ifdef CONFIG_MIPS_MT_SMP
 static int cpu_has_mipsmt_pertccounters;
 #define WHAT		(M_TC_EN_VPE | \
@@ -152,6 +166,8 @@ static void mipsxx_reg_setup(struct op_counter_config *ctr)
 			reg.control[i] |= M_PERFCTL_USER;
 		if (ctr[i].exl)
 			reg.control[i] |= M_PERFCTL_EXL;
+		if (current_cpu_type() == CPU_XLR)
+			reg.control[i] |= M_PERFCTL_COUNT_ALL_THREADS;
 		reg.counter[i] = 0x80000000 - ctr[i].count;
 	}
 }
@@ -162,6 +178,9 @@ static void mipsxx_cpu_setup(void *args)
 {
 	unsigned int counters = op_model_mipsxx_ops.num_counters;
 
+	if (oprofile_skip_cpu(smp_processor_id()))
+		return;
+
 	switch (counters) {
 	case 4:
 		w_c0_perfctrl3(0);
@@ -183,6 +202,9 @@ static void mipsxx_cpu_start(void *args)
 {
 	unsigned int counters = op_model_mipsxx_ops.num_counters;
 
+	if (oprofile_skip_cpu(smp_processor_id()))
+		return;
+
 	switch (counters) {
 	case 4:
 		w_c0_perfctrl3(WHAT | reg.control[3]);
@@ -200,6 +222,9 @@ static void mipsxx_cpu_stop(void *args)
 {
 	unsigned int counters = op_model_mipsxx_ops.num_counters;
 
+	if (oprofile_skip_cpu(smp_processor_id()))
+		return;
+
 	switch (counters) {
 	case 4:
 		w_c0_perfctrl3(0);
@@ -372,6 +397,10 @@ static int __init mipsxx_init(void)
 		op_model_mipsxx_ops.cpu_type = "mips/loongson1";
 		break;
 
+	case CPU_XLR:
+		op_model_mipsxx_ops.cpu_type = "mips/xlr";
+		break;
+
 	default:
 		printk(KERN_ERR "Profiling unsupported for this CPU\n");
 
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH 2/15 MIPS: perf: Add XLP support for hardware perf.

In reply to Jayachandran C

From: Zi Shen Lim <[email protected]>

Add support for XLP performance counters register in perf. Update mips/Kconfig so that perf events can be selected for XLP.

---
 arch/mips/Kconfig                    |    2 +-
 arch/mips/kernel/perf_event_mipsxx.c |  124 ++++++++++++++++++++++++++++++++++
 2 files changed, 125 insertions(+), 1 deletion(-)
arch/mips/Kconfig +1 -1
index 2a84ffd..c40d282 100644
@@ -2168,7 +2168,7 @@ config NODES_SHIFT
 
 config HW_PERF_EVENTS
 	bool "Enable hardware performance counter support for perf events"
-	depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON)
+	depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP)
 	default y
 	help
 	  Enable hardware performance counter support for perf events. If
arch/mips/kernel/perf_event_mipsxx.c +124 -0

148 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#3 lore raw

PATCH 3/15 MIPS: Netlogic: select MIPSR2 for XLP

In reply to Jayachandran C

This allows us to use the r2 optimized code from kernel headers while compilation.

Disable PGD_C0_CONTEXT option for XLP, which does not work.

---
 arch/mips/Kconfig |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/mips/Kconfig +2 -1
index c40d282..346b44d 100644
@@ -1525,6 +1525,7 @@ config CPU_XLP
 	select WEAK_ORDERING
 	select WEAK_REORDERING_BEYOND_LLSC
 	select CPU_HAS_PREFETCH
+	select CPU_MIPSR2
 	help
 	  Netlogic Microsystems XLP processors.
 endchoice
@@ -1738,7 +1739,7 @@ config CPU_SUPPORTS_UNCACHED_ACCELERATED
 	bool
 config MIPS_PGD_C0_CONTEXT
 	bool
-	default y if 64BIT && CPU_MIPSR2
+	default y if 64BIT && CPU_MIPSR2 && !CPU_XLP
 
 #
 # Set to y for ptrace access to watch registers.
Signature · 1 line
1.7.9.5
#4 lore raw

Re: [PATCH 03/15] MIPS: Netlogic: select MIPSR2 for XLP

Quoted 1 line · Jayachandran C

Disable PGD_C0_CONTEXT option for XLP, which does not work.

Why does this not work on XLP?

Ralf

#5 lore raw

Re: [PATCH 03/15] MIPS: Netlogic: select MIPSR2 for XLP

Quoted 6 lines · Ralf Baechle
Quoted 1 line · Jayachandran C

Disable PGD_C0_CONTEXT option for XLP, which does not work.

Why does this not work on XLP?

I see a kernel crash around the time init starts, planning to look at this next. For now, I thought I will enable R2 and disable PGD_C0_CONTEXT so that we get the rest of the R2 stuff for XLP.

JC.

#6 lore raw

Re: [PATCH 03/15] MIPS: Netlogic: select MIPSR2 for XLP

Quoted 11 lines · Jayachandran C.
Quoted 6 lines · Ralf Baechle
Quoted 1 line · Jayachandran C

Disable PGD_C0_CONTEXT option for XLP, which does not work.

Why does this not work on XLP?

I see a kernel crash around the time init starts, planning to look at this next. For now, I thought I will enable R2 and disable PGD_C0_CONTEXT so that we get the rest of the R2 stuff for XLP.

On XLP the XContext PTEbase is [63:55], but the current code tries to use XContext [63:48] to store the processor ID, which will not work.

I can probably work around the issue by changing the shift from 51 to 58, but that would not leave enough space for the 128 cpu config we want to support.

I will send patch to fix this and to use the XLP c0 scratch registers (cop0 $22) in the tlb handlers. But until the PGD_C0_CONTEXT code is updated, this patch is probably the best solution.

JC.

#7 lore raw

PATCH 4/15 MIPS: Netlogic: Enable SUE bit in cores

In reply to Jayachandran C

Enable Speculative Unmap Enable bit, which will enable speculative L2 cache requests for unmapped memory. This should give better performance for kernel code/data which is in KSEG0

---
 arch/mips/netlogic/common/smpboot.S |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/netlogic/common/smpboot.S +1 -1
index a13355c..25c1825 100644
@@ -61,7 +61,7 @@
 	li	t0, LSU_DEFEATURE
 	mfcr	t1, t0
 
-	lui	t2, 0x4080	/* Enable Unaligned Access, L2HPE */
+	lui	t2, 0xc080	/* SUE, Enable Unaligned Access, L2HPE */
 	or	t1, t1, t2
 #ifdef XLP_AX_WORKAROUND
 	li	t2, ~0xe	/* S1RCM */
Signature · 1 line
1.7.9.5
#8 lore raw

PATCH 5/15 MIPS: Netlogic: keep .dtb/.dtb.S until make clean

In reply to Jayachandran C

Provide a .SECONDARY entry for these intermediate files. Otherwise make deletes them, and these files are regenerated for every rebuild.

---
 arch/mips/netlogic/dts/Makefile |   16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)
arch/mips/netlogic/dts/Makefile +13 -3
index 67ae3fe2..40502ff 100644
@@ -1,4 +1,14 @@
-obj-$(CONFIG_DT_XLP_EVP) := xlp_evp.dtb.o
+DTS_FILE		= xlp_evp.dts
+DTB_FILE		= $(patsubst %.dts, %.dtb, $(DTS_FILE))
 
-$(obj)/%.dtb: $(obj)/%.dts
-	$(call if_changed,dtc)
+# built-in dtb
+obj-$(CONFIG_DT_XLP_EVP) := $(DTB_FILE).o
+
+$(obj)/%.dtb: $(src)/%.dts
+	$(call if_changed_dep,dtc)
+
+# Keep intermediate files .dtb and .dtb.S, delete them only at make clean
+KEEP_FILES		= $(DTB_FILE) $(DTB_FILE).S
+clean-files		+= $(KEEP_FILES)
+
+.SECONDARY: $(addprefix $(obj)/, $(KEEP_FILES))
Signature · 1 line
1.7.9.5
#9 lore raw

Re: [PATCH 05/15] MIPS: Netlogic: keep .dtb/.dtb.S until make clean

Quoted 20 lines · Jayachandran C

Provide a .SECONDARY entry for these intermediate files. Otherwise make deletes them, and these files are regenerated for every rebuild.

---
 arch/mips/netlogic/dts/Makefile |   16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)
arch/mips/netlogic/dts/Makefile +3 -3
index 67ae3fe2..40502ff 100644
@@ -1,4 +1,14 @@
-obj-$(CONFIG_DT_XLP_EVP) := xlp_evp.dtb.o
+DTS_FILE		= xlp_evp.dts
+DTB_FILE		= $(patsubst %.dts, %.dtb, $(DTS_FILE))
 
-$(obj)/%.dtb: $(obj)/%.dts
-	$(call if_changed,dtc)
+# built-in dtb

arch/mips/netlogic/dts/Makefile line 14

Quoted 10 lines
arch/mips/netlogic/dts/Makefile +10 -0
+obj-$(CONFIG_DT_XLP_EVP) := $(DTB_FILE).o
+
+$(obj)/%.dtb: $(src)/%.dts
+	$(call if_changed_dep,dtc)
+
+# Keep intermediate files .dtb and .dtb.S, delete them only at make clean
+KEEP_FILES		= $(DTB_FILE) $(DTB_FILE).S
+clean-files		+= $(KEEP_FILES)
+
+.SECONDARY: $(addprefix $(obj)/, $(KEEP_FILES))

This patch conflicts with a patch series by Stephen Warren to centralize the .dts -> .dtb rules that currently exist scattered across arch/.

Ralf

#10 lore raw

PATCH 6/15 MIPS: Netlogic: Move fdt init to plat_mem_setup

In reply to Jayachandran C

At this point early printk is available, so debugging device tree issues is easier.

---
 arch/mips/netlogic/xlp/setup.c |   27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)
arch/mips/netlogic/xlp/setup.c +14 -13
index d899709..b886a50 100644
@@ -68,10 +68,23 @@ static void nlm_linux_exit(void)
 
 void __init plat_mem_setup(void)
 {
+	void *fdtp;
+
 	panic_timeout	= 5;
 	_machine_restart = (void (*)(char *))nlm_linux_exit;
 	_machine_halt	= nlm_linux_exit;
 	pm_power_off	= nlm_linux_exit;
+
+	/*
+	 * If no FDT pointer is passed in, use the built-in FDT.
+	 * device_tree_init() does not handle CKSEG0 pointers in
+	 * 64-bit, so convert pointer.
+	 */
+	fdtp = (void *)(long)fw_arg0;
+	if (!fdtp)
+		fdtp = __dtb_start;
+	fdtp = phys_to_virt(__pa(fdtp));
+	early_init_devtree(fdtp);
 }
 
 const char *get_system_type(void)
@@ -96,23 +109,11 @@ void xlp_mmu_init(void)
 
 void __init prom_init(void)
 {
-	void *fdtp;
-
 	xlp_mmu_init();
 	nlm_hal_init();
 
-	/*
-	 * If no FDT pointer is passed in, use the built-in FDT.
-	 * device_tree_init() does not handle CKSEG0 pointers in
-	 * 64-bit, so convert pointer.
-	 */
-	fdtp = (void *)(long)fw_arg0;
-	if (!fdtp)
-		fdtp = __dtb_start;
-	fdtp = phys_to_virt(__pa(fdtp));
-	early_init_devtree(fdtp);
-
 	nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1));
+
 #ifdef CONFIG_SMP
 	nlm_wakeup_secondary_cpus(0xffffffff);
 
Signature · 1 line
1.7.9.5
#11 lore raw

PATCH 7/15 MIPS: Netlogic: Fix DMA zone selection for 64-bit

In reply to Jayachandran C

Fix Kconfig for both XLR and XLP to select ZONE_DMA32 (instead of ZONE_DMA) in case of 64-bit compilation. This can be used for devices that can only do DMA to 32-bit address. ZONE_DMA is not useful on XLR or XLP.

---
 arch/mips/Kconfig |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/mips/Kconfig +2 -2
index 346b44d..890ae91 100644
@@ -800,7 +800,7 @@ config NLM_XLR_BOARD
 	select CSRC_R4K
 	select IRQ_CPU
 	select ARCH_SUPPORTS_MSI
-	select ZONE_DMA if 64BIT
+	select ZONE_DMA32 if 64BIT
 	select SYNC_R4K
 	select SYS_HAS_EARLY_PRINTK
 	select USB_ARCH_HAS_OHCI if USB_SUPPORT
@@ -828,7 +828,7 @@ config NLM_XLP_BOARD
 	select CEVT_R4K
 	select CSRC_R4K
 	select IRQ_CPU
-	select ZONE_DMA if 64BIT
+	select ZONE_DMA32 if 64BIT
 	select SYNC_R4K
 	select SYS_HAS_EARLY_PRINTK
 	select USE_OF
Signature · 1 line
1.7.9.5
#12 lore raw

PATCH 8/15 MIPS: Netlogic: Fix interrupt table entry init

In reply to Jayachandran C

Used the hardware thread id passed in while writing to IRT in nlm_pic_init_irt()

---
 arch/mips/include/asm/netlogic/xlp-hal/pic.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/include/asm/netlogic/xlp-hal/pic.h +1 -1
index ad8b802..49ee15c 100644
@@ -404,7 +404,7 @@ nlm_pic_ack(uint64_t base, int irt_num)
 static inline void
 nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt)
 {
-	nlm_pic_write_irt_direct(base, irt, 0, 0, 0, irq, 0);
+	nlm_pic_write_irt_direct(base, irt, 0, 0, 0, irq, hwt);
 }
 
 extern uint64_t nlm_pic_base;
Signature · 1 line
1.7.9.5
#13 lore raw

PATCH 9/15 MIPS: Netlogic: Pass cpuid to early_init_secondary

In reply to Jayachandran C

The cpuid was not passed into early_init_secondary even though the comment indicated that it will be. Fix this.

---
 arch/mips/netlogic/common/smp.c     |    2 +-
 arch/mips/netlogic/common/smpboot.S |    4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)
arch/mips/netlogic/common/smp.c +1 -1
index fab316d..cd39f54 100644
@@ -98,7 +98,7 @@ void nlm_early_init_secondary(int cpu)
 	change_c0_config(CONF_CM_CMASK, 0x3);
 	write_c0_ebase((uint32_t)nlm_common_ebase);
 #ifdef CONFIG_CPU_XLP
-	if (hard_smp_processor_id() % 4 == 0)
+	if (cpu % 4 == 0)
 		xlp_mmu_init();
 #endif
 }
arch/mips/netlogic/common/smpboot.S +3 -1
index 25c1825..a0b7487 100644
@@ -186,7 +186,7 @@ EXPORT(nlm_boot_siblings)
 	* jump to the secondary wait function.
 	*/
 	mfc0	v0, CP0_EBASE, 1
-	andi	v0, 0x7f		/* v0 <- node/core */
+	andi	v0, 0x3ff		/* v0 <- node/core */
 
 	/* Init MMU in the first thread after changing THREAD_MODE
 	 * register (Ax Errata?)
@@ -263,6 +263,8 @@ NESTED(nlm_boot_secondary_cpus, 16, sp)
 	PTR_L	gp, 0(t1)
 
 	/* a0 has the processor id */
+	mfc0	a0, CP0_EBASE, 1
+	andi	a0, 0x3ff		/* a0 <- node/core */
 	PTR_LA	t0, nlm_early_init_secondary
 	jalr	t0
 	nop
Signature · 1 line
1.7.9.5
#14 lore raw

PATCH 10/15 MIPS: Netlogic: Update PIC access functions

In reply to Jayachandran C

Remove unused and trivial PIC accesss functions, update nlm_pic_send_ipi() and nlm_set_irt_to_cpu() to use similar logic, and use correct type for reg in nlm_pic_disable_irt().

---
 arch/mips/include/asm/netlogic/xlp-hal/pic.h |   40 +++++---------------------
 1 file changed, 7 insertions(+), 33 deletions(-)
arch/mips/include/asm/netlogic/xlp-hal/pic.h +7 -33
index 49ee15c..061e071 100644
@@ -273,36 +273,16 @@ nlm_pic_read_irt(uint64_t base, int irt_index)
 	return nlm_read_pic_reg(base, PIC_IRT(irt_index));
 }
 
-static inline uint64_t
-nlm_pic_read_control(uint64_t base)
-{
-	return nlm_read_pic_reg(base, PIC_CTRL);
-}
-
-static inline void
-nlm_pic_write_control(uint64_t base, uint64_t control)
-{
-	nlm_write_pic_reg(base, PIC_CTRL, control);
-}
-
-static inline void
-nlm_pic_update_control(uint64_t base, uint64_t control)
-{
-	uint64_t val;
-
-	val = nlm_read_pic_reg(base, PIC_CTRL);
-	nlm_write_pic_reg(base, PIC_CTRL, control | val);
-}
-
 static inline void
 nlm_set_irt_to_cpu(uint64_t base, int irt, int cpu)
 {
 	uint64_t val;
 
 	val = nlm_read_pic_reg(base, PIC_IRT(irt));
-	val |= cpu & 0xf;
-	if (cpu > 15)
-		val |= 1 << 16;
+	/* clear cpuset and mask */
+	val &= ~((0x7ull << 16) | 0xffff);
+	/* set DB, cpuset and cpumask */
+	val |= (1 << 19) | ((cpu >> 4) << 16) | (1 << (cpu & 0xf));
 	nlm_write_pic_reg(base, PIC_IRT(irt), val);
 }
 
@@ -369,7 +349,7 @@ nlm_pic_enable_irt(uint64_t base, int irt)
 static inline void
 nlm_pic_disable_irt(uint64_t base, int irt)
 {
-	uint32_t reg;
+	uint64_t reg;
 
 	reg = nlm_read_pic_reg(base, PIC_IRT(irt));
 	nlm_write_pic_reg(base, PIC_IRT(irt), reg & ~((uint64_t)1 << 31));
@@ -379,15 +359,9 @@ static inline void
 nlm_pic_send_ipi(uint64_t base, int hwt, int irq, int nmi)
 {
 	uint64_t ipi;
-	int	node, ncpu;
-
-	node = hwt / 32;
-	ncpu = hwt & 0x1f;
-	ipi = ((uint64_t)nmi << 31) | (irq << 20) | (node << 17) |
-		(1 << (ncpu & 0xf));
-	if (ncpu > 15)
-		ipi |= 0x10000; /* Setting bit 16 to select cpus 16-31 */
 
+	ipi = (nmi << 31) | (irq << 20);
+	ipi |= ((hwt >> 4) << 16) | (1 << (hwt & 0xf)); /* cpuset and mask */
 	nlm_write_pic_reg(base, PIC_IPI_CTL, ipi);
 }
 
Signature · 1 line
1.7.9.5
#15 lore raw

PATCH 11/15 MIPS: Netlogic: Move from u32 cpumask to cpumask_t

In reply to Jayachandran C

Initial code to support more than 32 cpus. The platform CPU mask is updated from 32-bit mask to cpumask_t. Convert places that use cpu_/cpus_ functions to use cpumask_* functions.

---
 arch/mips/include/asm/netlogic/common.h |    7 ++-
 arch/mips/netlogic/common/smp.c         |   39 ++++++++--------
 arch/mips/netlogic/xlp/setup.c          |    6 ++-
 arch/mips/netlogic/xlp/wakeup.c         |   77 ++++++++++++++++++++-----------
 arch/mips/netlogic/xlr/setup.c          |   10 ++--
 arch/mips/netlogic/xlr/wakeup.c         |    2 +-
 6 files changed, 86 insertions(+), 55 deletions(-)
arch/mips/include/asm/netlogic/common.h +5 -2
index fdd2f44..fd735bc 100644
@@ -45,6 +45,8 @@
 #define	BOOT_NMI_HANDLER	8
 
 #ifndef __ASSEMBLY__
+#include <linux/cpumask.h>
+
 struct irq_desc;
 extern struct plat_smp_ops nlm_smp_ops;
 extern char nlm_reset_entry[], nlm_reset_entry_end[];
@@ -52,7 +54,7 @@ void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc);
 void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc);
 void nlm_smp_irq_init(void);
 void nlm_boot_secondary_cpus(void);
-int nlm_wakeup_secondary_cpus(u32 wakeup_mask);
+int nlm_wakeup_secondary_cpus(void);
 void nlm_rmiboot_preboot(void);
 
 static inline void
@@ -71,6 +73,7 @@ unsigned int nlm_get_cpu_frequency(void);
 
 extern unsigned long nlm_common_ebase;
 extern int nlm_threads_per_core;
-extern uint32_t nlm_cpumask, nlm_coremask;
+extern uint32_t nlm_coremask;
+extern cpumask_t nlm_cpumask;
 #endif
 #endif /* _NETLOGIC_COMMON_H_ */
arch/mips/netlogic/common/smp.c +20 -19
index cd39f54..4fe8992 100644
@@ -160,9 +160,9 @@ void __init nlm_smp_setup(void)
 	int num_cpus, i;
 
 	boot_cpu = hard_smp_processor_id();
-	cpus_clear(phys_cpu_present_map);
+	cpumask_clear(&phys_cpu_present_map);
 
-	cpu_set(boot_cpu, phys_cpu_present_map);
+	cpumask_set_cpu(boot_cpu, &phys_cpu_present_map);
 	__cpu_number_map[boot_cpu] = 0;
 	__cpu_logical_map[0] = boot_cpu;
 	set_cpu_possible(0, true);
@@ -174,7 +174,7 @@ void __init nlm_smp_setup(void)
 		 * it is only set for ASPs (see smpboot.S)
 		 */
 		if (nlm_cpu_ready[i]) {
-			cpu_set(i, phys_cpu_present_map);
+			cpumask_set_cpu(i, &phys_cpu_present_map);
 			__cpu_number_map[i] = num_cpus;
 			__cpu_logical_map[num_cpus] = i;
 			set_cpu_possible(num_cpus, true);
@@ -183,19 +183,22 @@ void __init nlm_smp_setup(void)
 	}
 
 	pr_info("Phys CPU present map: %lx, possible map %lx\n",
-		(unsigned long)phys_cpu_present_map.bits[0],
+		(unsigned long)cpumask_bits(&phys_cpu_present_map)[0],
 		(unsigned long)cpumask_bits(cpu_possible_mask)[0]);
 
 	pr_info("Detected %i Slave CPU(s)\n", num_cpus);
 	nlm_set_nmi_handler(nlm_boot_secondary_cpus);
 }
 
-static int nlm_parse_cpumask(u32 cpu_mask)
+static int nlm_parse_cpumask(cpumask_t *wakeup_mask)
 {
 	uint32_t core0_thr_mask, core_thr_mask;
-	int threadmode, i;
+	int threadmode, i, j;
 
-	core0_thr_mask = cpu_mask & 0xf;
+	core0_thr_mask = 0;
+	for (i = 0; i < 4; i++)
+		if (cpumask_test_cpu(i, wakeup_mask))
+			core0_thr_mask |= (1 << i);
 	switch (core0_thr_mask) {
 	case 1:
 		nlm_threads_per_core = 1;
@@ -214,25 +217,23 @@ static int nlm_parse_cpumask(u32 cpu_mask)
 	}
 
 	/* Verify other cores CPU masks */
-	nlm_coremask = 1;
-	nlm_cpumask = core0_thr_mask;
-	for (i = 1; i < 8; i++) {
-		core_thr_mask = (cpu_mask >> (i * 4)) & 0xf;
-		if (core_thr_mask) {
-			if (core_thr_mask != core0_thr_mask)
+	for (i = 0; i < NR_CPUS; i += 4) {
+		core_thr_mask = 0;
+		for (j = 0; j < 4; j++)
+			if (cpumask_test_cpu(i + j, wakeup_mask))
+				core_thr_mask |= (1 << j);
+		if (core_thr_mask != 0 && core_thr_mask != core0_thr_mask)
 				goto unsupp;
-			nlm_coremask |= 1 << i;
-			nlm_cpumask |= core0_thr_mask << (4 * i);
-		}
 	}
 	return threadmode;
 
 unsupp:
-	panic("Unsupported CPU mask %x\n", cpu_mask);
+	panic("Unsupported CPU mask %lx\n",
+		(unsigned long)cpumask_bits(wakeup_mask)[0]);
 	return 0;
 }
 
-int __cpuinit nlm_wakeup_secondary_cpus(u32 wakeup_mask)
+int __cpuinit nlm_wakeup_secondary_cpus(void)
 {
 	unsigned long reset_vec;
 	char *reset_data;
@@ -244,7 +245,7 @@ int __cpuinit nlm_wakeup_secondary_cpus(u32 wakeup_mask)
 			(nlm_reset_entry_end - nlm_reset_entry));
 
 	/* verify the mask and setup core config variables */
-	threadmode = nlm_parse_cpumask(wakeup_mask);
+	threadmode = nlm_parse_cpumask(&nlm_cpumask);
 
 	/* Setup CPU init parameters */
 	reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS);
arch/mips/netlogic/xlp/setup.c +4 -2
index b886a50..9f8d360 100644
@@ -55,7 +55,8 @@
 unsigned long nlm_common_ebase = 0x0;
 
 /* default to uniprocessor */
-uint32_t nlm_coremask = 1, nlm_cpumask  = 1;
+uint32_t nlm_coremask = 1;
+cpumask_t nlm_cpumask = CPU_MASK_CPU0;
 int  nlm_threads_per_core = 1;
 extern u32 __dtb_start[];
 
@@ -115,7 +116,8 @@ void __init prom_init(void)
 	nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1));
 
 #ifdef CONFIG_SMP
-	nlm_wakeup_secondary_cpus(0xffffffff);
+	cpumask_setall(&nlm_cpumask);
+	nlm_wakeup_secondary_cpus();
 
 	/* update TLB size after waking up threads */
 	current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1;
arch/mips/netlogic/xlp/wakeup.c +49 -28

99 lines not on this page · raw message

arch/mips/netlogic/xlr/setup.c +7 -3
index 81b1d31..8fca680 100644
@@ -57,8 +57,9 @@ struct psb_info nlm_prom_info;
 unsigned long nlm_common_ebase = 0x0;
 
 /* default to uniprocessor */
-uint32_t nlm_coremask = 1, nlm_cpumask  = 1;
+uint32_t nlm_coremask = 1;
 int  nlm_threads_per_core = 1;
+cpumask_t nlm_cpumask = CPU_MASK_CPU0;
 
 static void __init nlm_early_serial_setup(void)
 {
@@ -178,7 +179,7 @@ static void prom_add_memory(void)
 
 void __init prom_init(void)
 {
-	int *argv, *envp;		/* passed as 32 bit ptrs */
+	int i, *argv, *envp;		/* passed as 32 bit ptrs */
 	struct psb_info *prom_infop;
 
 	/* truncate to 32 bit and sign extend all args */
@@ -195,7 +196,10 @@ void __init prom_init(void)
 	prom_add_memory();
 
 #ifdef CONFIG_SMP
-	nlm_wakeup_secondary_cpus(nlm_prom_info.online_cpu_map);
+	for (i = 0; i < 32; i++)
+		if (nlm_prom_info.online_cpu_map & (1 << i))
+			cpumask_set_cpu(i, &nlm_cpumask);
+	nlm_wakeup_secondary_cpus();
 	register_smp_ops(&nlm_smp_ops);
 #endif
 }
arch/mips/netlogic/xlr/wakeup.c +1 -1
index db5d987..0878924 100644
@@ -59,7 +59,7 @@ int __cpuinit xlr_wakeup_secondary_cpus(void)
 	boot_cpu = hard_smp_processor_id();
 	nlm_set_nmi_handler(nlm_rmiboot_preboot);
 	for (i = 0; i < NR_CPUS; i++) {
-		if (i == boot_cpu || (nlm_cpumask & (1u << i)) == 0)
+		if (i == boot_cpu || !cpumask_test_cpu(i, &nlm_cpumask))
 			continue;
 		nlm_pic_send_ipi(nlm_pic_base, i, 1, 1); /* send NMI */
 	}
Signature · 1 line
1.7.9.5
#16 lore raw

PATCH 12/15 MIPS: Netlogic: Support for multi-chip configuration

In reply to Jayachandran C

Upto 4 Netlogic XLP SoCs can be connected over ICI links to form a coherent multi-node system. Each SoC has its own set of on-chip devices including PIC. To support this, add a per SoC stucture and use it for the PIC and SYS block addresses instead of using global variables.

---
 arch/mips/include/asm/netlogic/common.h      |   42 +++++++++++++++++---
 arch/mips/include/asm/netlogic/mips-extns.h  |    5 +++
 arch/mips/include/asm/netlogic/xlp-hal/pic.h |    1 -
 arch/mips/include/asm/netlogic/xlp-hal/sys.h |    1 -
 arch/mips/include/asm/netlogic/xlr/pic.h     |    2 -
 arch/mips/netlogic/common/irq.c              |   55 +++++++++++++++++---------
 arch/mips/netlogic/common/smp.c              |   47 +++++++++++++---------
 arch/mips/netlogic/xlp/nlm_hal.c             |   29 +++++++-------
 arch/mips/netlogic/xlp/setup.c               |   17 ++++----
 arch/mips/netlogic/xlp/wakeup.c              |   22 +++++++----
 arch/mips/netlogic/xlr/setup.c               |   20 ++++++----
 arch/mips/netlogic/xlr/wakeup.c              |   21 +++++++++-
 12 files changed, 176 insertions(+), 86 deletions(-)
arch/mips/include/asm/netlogic/common.h +37 -5
index fd735bc..2eb39fa 100644
@@ -46,10 +46,10 @@
 
 #ifndef __ASSEMBLY__
 #include <linux/cpumask.h>
+#include <linux/spinlock.h>
+#include <asm/irq.h>
 
 struct irq_desc;
-extern struct plat_smp_ops nlm_smp_ops;
-extern char nlm_reset_entry[], nlm_reset_entry_end[];
 void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc);
 void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc);
 void nlm_smp_irq_init(void);
@@ -70,10 +70,42 @@ nlm_set_nmi_handler(void *handler)
  * Misc.
  */
 unsigned int nlm_get_cpu_frequency(void);
+void nlm_node_init(int node);
+extern struct plat_smp_ops nlm_smp_ops;
+extern char nlm_reset_entry[], nlm_reset_entry_end[];
 
-extern unsigned long nlm_common_ebase;
-extern int nlm_threads_per_core;
-extern uint32_t nlm_coremask;
+extern unsigned int nlm_threads_per_core;
 extern cpumask_t nlm_cpumask;
+
+struct nlm_soc_info {
+	unsigned long coremask;	/* cores enabled on the soc */
+	unsigned long ebase;
+	uint64_t irqmask;
+	uint64_t sysbase;	/* only for XLP */
+	uint64_t picbase;
+	spinlock_t piclock;
+};
+
+#define NLM_CORES_PER_NODE	8
+#define NLM_THREADS_PER_CORE	4
+#define NLM_CPUS_PER_NODE	(NLM_CORES_PER_NODE * NLM_THREADS_PER_CORE)
+#define	nlm_get_node(i)		(&nlm_nodes[i])
+#define NLM_NR_NODES		1
+#define	nlm_current_node()	(&nlm_nodes[0])
+
+struct irq_data;
+uint64_t nlm_pci_irqmask(int node);
+void nlm_set_pic_extra_ack(int node, int irq,  void (*xack)(struct irq_data *));
+
+/*
+ * The NR_IRQs is divided between nodes, each of them has a separate irq space
+ */
+static inline int nlm_irq_to_xirq(int node, int irq)
+{
+	return node * NR_IRQS / NLM_NR_NODES + irq;
+}
+
+extern struct nlm_soc_info nlm_nodes[NLM_NR_NODES];
+extern int nlm_cpu_ready[];
 #endif
 #endif /* _NETLOGIC_COMMON_H_ */
arch/mips/include/asm/netlogic/mips-extns.h +5 -0
index 8c53d0b..c9f6de5 100644
@@ -73,4 +73,9 @@ static inline int hard_smp_processor_id(void)
 	return __read_32bit_c0_register($15, 1) & 0x3ff;
 }
 
+static inline int nlm_nodeid(void)
+{
+	return (__read_32bit_c0_register($15, 1) >> 5) & 0x3;
+}
+
 #endif /*_ASM_NLM_MIPS_EXTS_H */
arch/mips/include/asm/netlogic/xlp-hal/pic.h +0 -1
index 061e071..857a967 100644
@@ -381,7 +381,6 @@ nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt)
 	nlm_pic_write_irt_direct(base, irt, 0, 0, 0, irq, hwt);
 }
 
-extern uint64_t nlm_pic_base;
 int nlm_irq_to_irt(int irq);
 int nlm_irt_to_irq(int irt);
 
arch/mips/include/asm/netlogic/xlp-hal/sys.h +0 -1
index 21432f7..258e8cc 100644
@@ -124,6 +124,5 @@
 #define	nlm_get_sys_pcibase(node) nlm_pcicfg_base(XLP_IO_SYS_OFFSET(node))
 #define	nlm_get_sys_regbase(node) (nlm_get_sys_pcibase(node) + XLP_IO_PCI_HDRSZ)
 
-extern uint64_t nlm_sys_base;
 #endif
 #endif
arch/mips/include/asm/netlogic/xlr/pic.h +0 -2
index 868013e..9a691b1 100644
@@ -258,7 +258,5 @@ nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt)
 	nlm_write_reg(base, PIC_IRT_1(irt),
 		(1 << 30) | (1 << 6) | irq);
 }
-
-extern uint64_t nlm_pic_base;
 #endif
 #endif /* _ASM_NLM_XLR_PIC_H */
arch/mips/netlogic/common/irq.c +36 -19

138 lines not on this page · raw message

arch/mips/netlogic/common/smp.c +29 -18

108 lines not on this page · raw message

arch/mips/netlogic/xlp/nlm_hal.c +15 -14
index 6c65ac7..d3a26e7 100644
@@ -40,23 +40,23 @@
 #include <asm/mipsregs.h>
 #include <asm/time.h>
 
+#include <asm/netlogic/common.h>
 #include <asm/netlogic/haldefs.h>
 #include <asm/netlogic/xlp-hal/iomap.h>
 #include <asm/netlogic/xlp-hal/xlp.h>
 #include <asm/netlogic/xlp-hal/pic.h>
 #include <asm/netlogic/xlp-hal/sys.h>
 
-/* These addresses are computed by the nlm_hal_init() */
-uint64_t nlm_io_base;
-uint64_t nlm_sys_base;
-uint64_t nlm_pic_base;
-
 /* Main initialization */
-void nlm_hal_init(void)
+void nlm_node_init(int node)
 {
-	nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE);
-	nlm_sys_base = nlm_get_sys_regbase(0);	/* node 0 */
-	nlm_pic_base = nlm_get_pic_regbase(0);	/* node 0 */
+	struct nlm_soc_info *nodep;
+
+	nodep = nlm_get_node(node);
+	nodep->sysbase = nlm_get_sys_regbase(node);
+	nodep->picbase = nlm_get_pic_regbase(node);
+	nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1));
+	spin_lock_init(&nodep->piclock);
 }
 
 int nlm_irq_to_irt(int irq)
@@ -138,14 +138,15 @@ int nlm_irt_to_irq(int irt)
 	}
 }
 
-unsigned int nlm_get_core_frequency(int core)
+unsigned int nlm_get_core_frequency(int node, int core)
 {
 	unsigned int pll_divf, pll_divr, dfs_div, ext_div;
 	unsigned int rstval, dfsval, denom;
-	uint64_t num;
+	uint64_t num, sysbase;
 
-	rstval = nlm_read_sys_reg(nlm_sys_base, SYS_POWER_ON_RESET_CFG);
-	dfsval = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIV_VALUE);
+	sysbase = nlm_get_node(node)->sysbase;
+	rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG);
+	dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE);
 	pll_divf = ((rstval >> 10) & 0x7f) + 1;
 	pll_divr = ((rstval >> 8)  & 0x3) + 1;
 	ext_div  = ((rstval >> 30) & 0x3) + 1;
@@ -159,5 +160,5 @@ unsigned int nlm_get_core_frequency(int core)
 
 unsigned int nlm_get_cpu_frequency(void)
 {
-	return nlm_get_core_frequency(0);
+	return nlm_get_core_frequency(0, 0);
 }
arch/mips/netlogic/xlp/setup.c +8 -9
index 9f8d360..465b8d6 100644
@@ -52,17 +52,17 @@
 #include <asm/netlogic/xlp-hal/xlp.h>
 #include <asm/netlogic/xlp-hal/sys.h>
 
-unsigned long nlm_common_ebase = 0x0;
-
-/* default to uniprocessor */
-uint32_t nlm_coremask = 1;
+uint64_t nlm_io_base;
+struct nlm_soc_info nlm_nodes[NLM_NR_NODES];
 cpumask_t nlm_cpumask = CPU_MASK_CPU0;
-int  nlm_threads_per_core = 1;
+unsigned int nlm_threads_per_core;
 extern u32 __dtb_start[];
 
 static void nlm_linux_exit(void)
 {
-	nlm_write_sys_reg(nlm_sys_base, SYS_CHIP_RESET, 1);
+	uint64_t sysbase = nlm_get_node(0)->sysbase;
+
+	nlm_write_sys_reg(sysbase, SYS_CHIP_RESET, 1);
 	for ( ; ; )
 		cpu_wait();
 }
@@ -110,10 +110,9 @@ void xlp_mmu_init(void)
 
 void __init prom_init(void)
 {
+	nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE);
 	xlp_mmu_init();
-	nlm_hal_init();
-
-	nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1));
+	nlm_node_init(0);
 
 #ifdef CONFIG_SMP
 	cpumask_setall(&nlm_cpumask);
arch/mips/netlogic/xlp/wakeup.c +14 -8
index 88ce38d..cb90106 100644
@@ -79,32 +79,38 @@ static int xlp_wakeup_core(uint64_t sysbase, int core)
 
 static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
 {
-	uint64_t syspcibase, sysbase;
+	struct nlm_soc_info *nodep;
+	uint64_t syspcibase;
 	uint32_t syscoremask;
-	int core, n;
+	int core, n, cpu;
 
-	for (n = 0; n < 4; n++) {
+	for (n = 0; n < NLM_NR_NODES; n++) {
 		syspcibase = nlm_get_sys_pcibase(n);
 		if (nlm_read_reg(syspcibase, 0) == 0xffffffff)
 			break;
 
 		/* read cores in reset from SYS and account for boot cpu */
-		sysbase = nlm_get_sys_regbase(n);
-		syscoremask = nlm_read_sys_reg(sysbase, SYS_CPU_RESET);
+		nlm_node_init(n);
+		nodep = nlm_get_node(n);
+		syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET);
 		if (n == 0)
 			syscoremask |= 1;
 
-		for (core = 0; core < 8; core++) {
+		for (core = 0; core < NLM_CORES_PER_NODE; core++) {
 			/* see if the core exists */
 			if ((syscoremask & (1 << core)) == 0)
 				continue;
 
 			/* see if at least the first thread is enabled */
-			if (!cpumask_test_cpu((n * 8 + core) * 4, wakeup_mask))
+			cpu = (n * NLM_CORES_PER_NODE + core)
+						* NLM_THREADS_PER_CORE;
+			if (!cpumask_test_cpu(cpu, wakeup_mask))
 				continue;
 
 			/* wake up the core */
-			if (!xlp_wakeup_core(sysbase, core))
+			if (xlp_wakeup_core(nodep->sysbase, core))
+				nodep->coremask |= 1u << core;
+			else
 				pr_err("Failed to enable core %d\n", core);
 		}
 	}
arch/mips/netlogic/xlr/setup.c +13 -7
index 8fca680..696d424 100644
@@ -51,14 +51,11 @@
 #include <asm/netlogic/xlr/gpio.h>
 
 uint64_t nlm_io_base = DEFAULT_NETLOGIC_IO_BASE;
-uint64_t nlm_pic_base;
 struct psb_info nlm_prom_info;
 
-unsigned long nlm_common_ebase = 0x0;
-
 /* default to uniprocessor */
-uint32_t nlm_coremask = 1;
-int  nlm_threads_per_core = 1;
+unsigned int  nlm_threads_per_core = 1;
+struct nlm_soc_info nlm_nodes[NLM_NR_NODES];
 cpumask_t nlm_cpumask = CPU_MASK_CPU0;
 
 static void __init nlm_early_serial_setup(void)
@@ -177,6 +174,16 @@ static void prom_add_memory(void)
 	}
 }
 
+static void nlm_init_node(void)
+{
+	struct nlm_soc_info *nodep;
+
+	nodep = nlm_current_node();
+	nodep->picbase = nlm_mmio_base(NETLOGIC_IO_PIC_OFFSET);
+	nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1));
+	spin_lock_init(&nodep->piclock);
+}
+
 void __init prom_init(void)
 {
 	int i, *argv, *envp;		/* passed as 32 bit ptrs */
@@ -188,11 +195,10 @@ void __init prom_init(void)
 	prom_infop = (struct psb_info *)(long)(int)fw_arg3;
 
 	nlm_prom_info = *prom_infop;
-	nlm_pic_base = nlm_mmio_base(NETLOGIC_IO_PIC_OFFSET);
+	nlm_init_node();
 
 	nlm_early_serial_setup();
 	build_arcs_cmdline(argv);
-	nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1));
 	prom_add_memory();
 
 #ifdef CONFIG_SMP
arch/mips/netlogic/xlr/wakeup.c +19 -2
index 0878924..3ebf741 100644
@@ -33,6 +33,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/delay.h>
 #include <linux/threads.h>
 
 #include <asm/asm.h>
@@ -50,18 +51,34 @@
 
 int __cpuinit xlr_wakeup_secondary_cpus(void)
 {
-	unsigned int i, boot_cpu;
+	struct nlm_soc_info *nodep;
+	unsigned int i, j, boot_cpu;
 
 	/*
 	 *  In case of RMI boot, hit with NMI to get the cores
 	 *  from bootloader to linux code.
 	 */
+	nodep = nlm_get_node(0);
 	boot_cpu = hard_smp_processor_id();
 	nlm_set_nmi_handler(nlm_rmiboot_preboot);
 	for (i = 0; i < NR_CPUS; i++) {
 		if (i == boot_cpu || !cpumask_test_cpu(i, &nlm_cpumask))
 			continue;
-		nlm_pic_send_ipi(nlm_pic_base, i, 1, 1); /* send NMI */
+		nlm_pic_send_ipi(nodep->picbase, i, 1, 1); /* send NMI */
+	}
+
+	/* Fill up the coremask early */
+	nodep->coremask = 1;
+	for (i = 1; i < NLM_CORES_PER_NODE; i++) {
+		for (j = 1000000; j > 0; j--) {
+			if (nlm_cpu_ready[i * NLM_THREADS_PER_CORE])
+				break;
+			udelay(10);
+		}
+		if (j != 0)
+			nodep->coremask |= (1u << i);
+		else
+			pr_err("Failed to wakeup core %d\n", i);
 	}
 
 	return 0;
Signature · 1 line
1.7.9.5
#17 lore raw

PATCH 13/15 MIPS: Netlogic: Make number of nodes configurable

In reply to Jayachandran C

There can be 1, 2 or 4 SoCs(nodes) in a multi-chip XLP board. Add an option for multi-chip boards in case of XLP, and make the number of nodes configurable.

---
 arch/mips/include/asm/mach-netlogic/irq.h        |    4 +-
 arch/mips/include/asm/mach-netlogic/multi-node.h |   54 ++++++++++++++++++++++
 arch/mips/include/asm/netlogic/common.h          |    9 ++--
 arch/mips/netlogic/Kconfig                       |   28 +++++++++++
 4 files changed, 90 insertions(+), 5 deletions(-)
 create mode 100644 arch/mips/include/asm/mach-netlogic/multi-node.h
arch/mips/include/asm/mach-netlogic/irq.h +3 -1
index b590245..868ed8a 100644
@@ -8,7 +8,9 @@
 #ifndef __ASM_NETLOGIC_IRQ_H
 #define __ASM_NETLOGIC_IRQ_H
 
-#define NR_IRQS			64
+#include <asm/mach-netlogic/multi-node.h>
+#define NR_IRQS			(64 * NLM_NR_NODES)
+
 #define MIPS_CPU_IRQ_BASE	0
 
 #endif /* __ASM_NETLOGIC_IRQ_H */
arch/mips/include/asm/mach-netlogic/multi-node.h new file +54 -0

54 lines not on this page · raw message

arch/mips/include/asm/netlogic/common.h +5 -4
index 2eb39fa..3c6814e 100644
@@ -48,6 +48,7 @@
 #include <linux/cpumask.h>
 #include <linux/spinlock.h>
 #include <asm/irq.h>
+#include <asm/mach-netlogic/multi-node.h>
 
 struct irq_desc;
 void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc);
@@ -86,12 +87,12 @@ struct nlm_soc_info {
 	spinlock_t piclock;
 };
 
-#define NLM_CORES_PER_NODE	8
-#define NLM_THREADS_PER_CORE	4
-#define NLM_CPUS_PER_NODE	(NLM_CORES_PER_NODE * NLM_THREADS_PER_CORE)
 #define	nlm_get_node(i)		(&nlm_nodes[i])
-#define NLM_NR_NODES		1
+#ifdef CONFIG_CPU_XLR
 #define	nlm_current_node()	(&nlm_nodes[0])
+#else
+#define nlm_current_node()	(&nlm_nodes[nlm_nodeid()])
+#endif
 
 struct irq_data;
 uint64_t nlm_pci_irqmask(int node);
arch/mips/netlogic/Kconfig +28 -0
index 8059eb7..3c05bf9 100644
@@ -9,6 +9,34 @@ config DT_XLP_EVP
 	  This DTB will be used if the firmware does not pass in a DTB
           pointer to the kernel.  The corresponding DTS file is at
           arch/mips/netlogic/dts/xlp_evp.dts
+
+config NLM_MULTINODE
+	bool "Support for multi-chip boards"
+	depends on NLM_XLP_BOARD
+	default n
+	help
+	  Add support for boards with 2 or 4 XLPs connected over ICI.
+
+if NLM_MULTINODE
+choice
+	prompt "Number of XLPs on the board"
+	default NLM_MULTINODE_2
+	help
+	  In the multi-node case, specify the number of SoCs on the board.
+
+config NLM_MULTINODE_2
+	bool "Dual-XLP board"
+	help
+	  Support boards with upto two XLPs connected over ICI.
+
+config NLM_MULTINODE_4
+	bool "Quad-XLP board"
+	help
+	  Support boards with upto four XLPs connected over ICI.
+
+endchoice
+
+endif
 endif
 
 config NLM_COMMON
Signature · 1 line
1.7.9.5
#18 lore raw

PATCH 14/15 MIPS: Netlogic: PIC IRQ handling update for multi-chip

In reply to Jayachandran C

Create struct nlm_pic_irq for interrupts handled by the PIC. This simplifies IRQ handling for multi-SoC as well as the single SoC cases. Also split the setup of percpu and PIC interrupts so that we can configure the PIC interrupts for every node.

---
 arch/mips/include/asm/netlogic/common.h      |    2 +-
 arch/mips/include/asm/netlogic/xlp-hal/pic.h |    1 -
 arch/mips/netlogic/common/irq.c              |  170 +++++++++++++++-----------
 arch/mips/netlogic/common/smp.c              |    7 +-
 arch/mips/netlogic/xlp/nlm_hal.c             |   38 ------
 5 files changed, 103 insertions(+), 115 deletions(-)
arch/mips/include/asm/netlogic/common.h +1 -1
index 3c6814e..1fee7ef 100644
@@ -53,7 +53,7 @@
 struct irq_desc;
 void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc);
 void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc);
-void nlm_smp_irq_init(void);
+void nlm_smp_irq_init(int hwcpuid);
 void nlm_boot_secondary_cpus(void);
 int nlm_wakeup_secondary_cpus(void);
 void nlm_rmiboot_preboot(void);
arch/mips/include/asm/netlogic/xlp-hal/pic.h +0 -1
index 857a967..b2e53a5 100644
@@ -382,7 +382,6 @@ nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt)
 }
 
 int nlm_irq_to_irt(int irq);
-int nlm_irt_to_irq(int irt);
 
 #endif /* __ASSEMBLY__ */
 #endif /* _NLM_HAL_PIC_H */
arch/mips/netlogic/common/irq.c +97 -73

246 lines not on this page · raw message

arch/mips/netlogic/common/smp.c +5 -2
index e40b467..0315b29 100644
@@ -114,8 +114,11 @@ void nlm_early_init_secondary(int cpu)
  */
 static void __cpuinit nlm_init_secondary(void)
 {
-	current_cpu_data.core = hard_smp_processor_id() / NLM_THREADS_PER_CORE;
-	nlm_smp_irq_init();
+	int hwtid;
+
+	hwtid = hard_smp_processor_id();
+	current_cpu_data.core = hwtid / NLM_THREADS_PER_CORE;
+	nlm_smp_irq_init(hwtid);
 }
 
 void nlm_prepare_cpus(unsigned int max_cpus)
arch/mips/netlogic/xlp/nlm_hal.c +0 -38
index d3a26e7..529e747 100644
@@ -100,44 +100,6 @@ int nlm_irq_to_irt(int irq)
 	}
 }
 
-int nlm_irt_to_irq(int irt)
-{
-	switch (irt) {
-	case PIC_IRT_UART_0_INDEX:
-		return PIC_UART_0_IRQ;
-	case PIC_IRT_UART_1_INDEX:
-		return PIC_UART_1_IRQ;
-	case PIC_IRT_PCIE_LINK_0_INDEX:
-	       return PIC_PCIE_LINK_0_IRQ;
-	case PIC_IRT_PCIE_LINK_1_INDEX:
-	       return PIC_PCIE_LINK_1_IRQ;
-	case PIC_IRT_PCIE_LINK_2_INDEX:
-	       return PIC_PCIE_LINK_2_IRQ;
-	case PIC_IRT_PCIE_LINK_3_INDEX:
-	       return PIC_PCIE_LINK_3_IRQ;
-	case PIC_IRT_EHCI_0_INDEX:
-		return PIC_EHCI_0_IRQ;
-	case PIC_IRT_EHCI_1_INDEX:
-		return PIC_EHCI_1_IRQ;
-	case PIC_IRT_OHCI_0_INDEX:
-		return PIC_OHCI_0_IRQ;
-	case PIC_IRT_OHCI_1_INDEX:
-		return PIC_OHCI_1_IRQ;
-	case PIC_IRT_OHCI_2_INDEX:
-		return PIC_OHCI_2_IRQ;
-	case PIC_IRT_OHCI_3_INDEX:
-		return PIC_OHCI_3_IRQ;
-	case PIC_IRT_MMC_INDEX:
-	       return PIC_MMC_IRQ;
-	case PIC_IRT_I2C_0_INDEX:
-		return PIC_I2C_0_IRQ;
-	case PIC_IRT_I2C_1_INDEX:
-		return PIC_I2C_1_IRQ;
-	default:
-		return -1;
-	}
-}
-
 unsigned int nlm_get_core_frequency(int node, int core)
 {
 	unsigned int pll_divf, pll_divr, dfs_div, ext_div;
Signature · 1 line
1.7.9.5
#19 lore raw

PATCH 15/15 MIPS: Netlogic: Support for XLR/XLS Fast Message Network

In reply to Jayachandran C

From: Ganesan Ramalingam <[email protected]>

On XLR/XLS, the cpu cores communicate with fast on-chip devices (e.g. network accelerator, security engine etc.) using the Fast Messaging Network(FMN). The FMN queues and credits needs to be configured and intialized before it can be used.

The co-processor 2 on XLR/XLS CPU cores has registers for FMN access, and the XLR/XLS has custom instructions for sending and loading messages. The FMN can deliver also per-cpu interrupts when messages are available at the CPU.

This patch adds FMN initialization, adds interrupt setup and handling, and also provides support for sending and receiving FMN messages.

---
 arch/mips/include/asm/netlogic/common.h     |    1 +
 arch/mips/include/asm/netlogic/interrupt.h  |    2 +-
 arch/mips/include/asm/netlogic/mips-extns.h |  137 ++++++++++
 arch/mips/include/asm/netlogic/xlr/fmn.h    |  363 +++++++++++++++++++++++++++
 arch/mips/include/asm/netlogic/xlr/xlr.h    |    6 +-
 arch/mips/netlogic/common/irq.c             |    8 +-
 arch/mips/netlogic/common/smp.c             |    4 +-
 arch/mips/netlogic/xlp/setup.c              |    4 +
 arch/mips/netlogic/xlr/Makefile             |    4 +-
 arch/mips/netlogic/xlr/fmn-config.c         |  290 +++++++++++++++++++++
 arch/mips/netlogic/xlr/fmn.c                |  204 +++++++++++++++
 arch/mips/netlogic/xlr/setup.c              |    9 +
 12 files changed, 1020 insertions(+), 12 deletions(-)
 create mode 100644 arch/mips/include/asm/netlogic/xlr/fmn.h
 create mode 100644 arch/mips/netlogic/xlr/fmn-config.c
 create mode 100644 arch/mips/netlogic/xlr/fmn.c
arch/mips/include/asm/netlogic/common.h +1 -0
index 1fee7ef..42bfd5f 100644
@@ -57,6 +57,7 @@ void nlm_smp_irq_init(int hwcpuid);
 void nlm_boot_secondary_cpus(void);
 int nlm_wakeup_secondary_cpus(void);
 void nlm_rmiboot_preboot(void);
+void nlm_percpu_init(int hwcpuid);
 
 static inline void
 nlm_set_nmi_handler(void *handler)
arch/mips/include/asm/netlogic/interrupt.h +1 -1
index a85aadb..ed5993d 100644
@@ -39,7 +39,7 @@
 
 #define IRQ_IPI_SMP_FUNCTION	3
 #define IRQ_IPI_SMP_RESCHEDULE	4
-#define IRQ_MSGRING		6
+#define IRQ_FMN			5
 #define IRQ_TIMER		7
 
 #endif
arch/mips/include/asm/netlogic/mips-extns.h +137 -0

141 lines not on this page · raw message

arch/mips/include/asm/netlogic/xlr/fmn.h new file +363 -0

363 lines not on this page · raw message

arch/mips/include/asm/netlogic/xlr/xlr.h +2 -4
index ff4a17b..c1667e0 100644
@@ -51,10 +51,8 @@ static inline unsigned int nlm_chip_is_xls_b(void)
 	return ((prid & 0xf000) == 0x4000);
 }
 
-/*
- *  XLR chip types
- */
- /* The XLS product line has chip versions 0x[48c]? */
+/*  XLR chip types */
+/* The XLS product line has chip versions 0x[48c]? */
 static inline unsigned int nlm_chip_is_xls(void)
 {
 	uint32_t prid = read_c0_prid();
arch/mips/netlogic/common/irq.c +6 -2
index b89d5a6..00dcc7a 100644
@@ -58,6 +58,7 @@
 #elif defined(CONFIG_CPU_XLR)
 #include <asm/netlogic/xlr/iomap.h>
 #include <asm/netlogic/xlr/pic.h>
+#include <asm/netlogic/xlr/fmn.h>
 #else
 #error "Unknown CPU"
 #endif
@@ -68,8 +69,8 @@
 #else
 #define SMP_IRQ_MASK	0
 #endif
-#define PERCPU_IRQ_MASK	(SMP_IRQ_MASK | (1ull << IRQ_TIMER))
-
+#define PERCPU_IRQ_MASK	(SMP_IRQ_MASK | (1ull << IRQ_TIMER) | \
+				(1ull << IRQ_FMN))
 
 struct nlm_pic_irq {
 	void	(*extra_ack)(struct irq_data *);
@@ -241,6 +242,9 @@ void __init arch_init_irq(void)
 	nlm_init_percpu_irqs();
 	nlm_init_node_irqs(0);
 	write_c0_eimr(nlm_current_node()->irqmask);
+#if defined(CONFIG_CPU_XLR)
+	nlm_setup_fmn_irq();
+#endif
 }
 
 void nlm_smp_irq_init(int hwcpuid)
arch/mips/netlogic/common/smp.c +1 -3
index 0315b29..a080d9e 100644
@@ -118,6 +118,7 @@ static void __cpuinit nlm_init_secondary(void)
 
 	hwtid = hard_smp_processor_id();
 	current_cpu_data.core = hwtid / NLM_THREADS_PER_CORE;
+	nlm_percpu_init(hwtid);
 	nlm_smp_irq_init(hwtid);
 }
 
@@ -129,9 +130,6 @@ void nlm_prepare_cpus(unsigned int max_cpus)
 
 void nlm_smp_finish(void)
 {
-#ifdef notyet
-	nlm_common_msgring_cpu_init();
-#endif
 	local_irq_enable();
 }
 
arch/mips/netlogic/xlp/setup.c +4 -0
index 465b8d6..4894d62 100644
@@ -108,6 +108,10 @@ void xlp_mmu_init(void)
 		(13 + (ffz(PM_DEFAULT_MASK >> 13) / 2)));
 }
 
+void nlm_percpu_init(int hwcpuid)
+{
+}
+
 void __init prom_init(void)
 {
 	nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE);
arch/mips/netlogic/xlr/Makefile +2 -2
index c287dea..05902bc 100644
@@ -1,2 +1,2 @@
-obj-y				+= setup.o platform.o platform-flash.o
-obj-$(CONFIG_SMP)		+= wakeup.o
+obj-y			+=  fmn.o fmn-config.o setup.o platform.o platform-flash.o
+obj-$(CONFIG_SMP)	+= wakeup.o
arch/mips/netlogic/xlr/fmn-config.c new file +290 -0

290 lines not on this page · raw message

arch/mips/netlogic/xlr/fmn.c new file +204 -0

204 lines not on this page · raw message

arch/mips/netlogic/xlr/setup.c +9 -0
index 696d424..4e7f49d 100644
@@ -49,6 +49,7 @@
 #include <asm/netlogic/xlr/iomap.h>
 #include <asm/netlogic/xlr/pic.h>
 #include <asm/netlogic/xlr/gpio.h>
+#include <asm/netlogic/xlr/fmn.h>
 
 uint64_t nlm_io_base = DEFAULT_NETLOGIC_IO_BASE;
 struct psb_info nlm_prom_info;
@@ -111,6 +112,12 @@ void __init prom_free_prom_memory(void)
 	/* Nothing yet */
 }
 
+void nlm_percpu_init(int hwcpuid)
+{
+	if (hwcpuid % 4 == 0)
+		xlr_percpu_fmn_init();
+}
+
 static void __init build_arcs_cmdline(int *argv)
 {
 	int i, remain, len;
@@ -208,4 +215,6 @@ void __init prom_init(void)
 	nlm_wakeup_secondary_cpus();
 	register_smp_ops(&nlm_smp_ops);
 #endif
+	xlr_board_info_setup();
+	xlr_percpu_fmn_init();
 }
Signature · 1 line
1.7.9.5