Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1330591 > unrolled thread

[PATCH v2 0/8] MIPS: Add support for OCTEON cn78xx and cn73xx.

Started byDavid Daney <ddaney.cavm@gmail.com>
First post2016-02-09 20:10 +0100
Last post2016-02-09 20:10 +0100
Articles 3 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 0/8] MIPS: Add support for OCTEON cn78xx and cn73xx. David Daney <ddaney.cavm@gmail.com> - 2016-02-09 20:10 +0100
    [PATCH v2 1/8] MIPS: OCTEON: Remove some code limiting NR_IRQS to 255 David Daney <ddaney.cavm@gmail.com> - 2016-02-09 20:10 +0100
    [PATCH v2 7/8] MIPS: OCTEON: Add SMP support for OCTEON cn78xx et al. David Daney <ddaney.cavm@gmail.com> - 2016-02-09 20:10 +0100

#1330591 — [PATCH v2 0/8] MIPS: Add support for OCTEON cn78xx and cn73xx.

FromDavid Daney <ddaney.cavm@gmail.com>
Date2016-02-09 20:10 +0100
Subject[PATCH v2 0/8] MIPS: Add support for OCTEON cn78xx and cn73xx.
Message-ID<r0lPI-8iJ-19@gated-at.bofh.it>
From: David Daney <david.daney@cavium.com>

The OCTEON III cn78xx and cn73xx family of SoCs has some architectural
differences from previous OCTEON processors.

Here we add support for the new interrupt controller and related IPI
machinery.  This is enough to be able to boot an initrd based system
to a command prompt on the serial console.

Still pending are support for: PCI, Watchdog, I2C, Sata, USB,
Ethernet, etc.

This set depends on these two sets:
http://www.linux-mips.org/archives/linux-mips/2016-02/msg00051.html
http://www.linux-mips.org/archives/linux-mips/2016-02/msg00041.html

All patches are to the MIPS tree except the device tree binding
definition.  Probably they could be merged via Ralf's tree if there
were no objections.

Changes from v1: Added Acked-by: Rob Herring to 6/8.  Simplifications
                 suggested by tglx.  Added 8/8.

David Daney (8):
  MIPS: OCTEON: Remove some code limiting NR_IRQS to 255
  MIPS: Select CONFIG_HANDLE_DOMAIN_IRQ and make it work.
  MIPS: OCTEON: Add register definitions for cn73xx, cnf75xx and
    cn78xx.
  MIPS: OCTEON: Add model checking support for cn73xx, cnf75xx and
    cn78xx
  MIPS: OCTEON: Don't attempt to use nonexistent registers on OCTEON
    III models.
  MIPS: OCTEON: Add support for OCTEON III interrupt  controller.
  MIPS: OCTEON: Add SMP support for OCTEON cn78xx et al.
  MIPS: OCTEON: Simplify code in octeon_irq_ciu_gpio_set_type()

 .../devicetree/bindings/mips/cavium/ciu3.txt       |  27 +
 arch/mips/Kconfig                                  |   1 +
 arch/mips/cavium-octeon/csrc-octeon.c              |  13 +-
 arch/mips/cavium-octeon/executive/octeon-model.c   |  82 ++-
 arch/mips/cavium-octeon/octeon-irq.c               | 679 ++++++++++++++++++++-
 arch/mips/cavium-octeon/setup.c                    |  36 +-
 arch/mips/cavium-octeon/smp.c                      | 145 ++++-
 arch/mips/include/asm/irq_regs.h                   |  10 +
 arch/mips/include/asm/octeon/cvmx-ciu3-defs.h      | 353 +++++++++++
 arch/mips/include/asm/octeon/cvmx-fpa-defs.h       |   1 +
 arch/mips/include/asm/octeon/cvmx-mio-defs.h       | 410 ++++++++++++-
 arch/mips/include/asm/octeon/cvmx.h                |  27 +-
 arch/mips/include/asm/octeon/octeon-feature.h      |  19 +-
 arch/mips/include/asm/octeon/octeon-model.h        |   5 +
 arch/mips/include/asm/octeon/octeon.h              |  25 +
 15 files changed, 1750 insertions(+), 83 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mips/cavium/ciu3.txt
 create mode 100644 arch/mips/include/asm/octeon/cvmx-ciu3-defs.h

Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Kumar Gala <galak@codeaurora.org>
Cc: devicetree@vger.kernel.org
Cc: Thomas Gleixner <tglx@linutronix.de>
-- 
1.7.11.7

[toc] | [next] | [standalone]


#1330592 — [PATCH v2 1/8] MIPS: OCTEON: Remove some code limiting NR_IRQS to 255

FromDavid Daney <ddaney.cavm@gmail.com>
Date2016-02-09 20:10 +0100
Subject[PATCH v2 1/8] MIPS: OCTEON: Remove some code limiting NR_IRQS to 255
Message-ID<r0lPK-8iJ-45@gated-at.bofh.it>
In reply to#1330591
From: David Daney <david.daney@cavium.com>

Follow-on patches for OCTEON III will increase the number of irqs to
potentially more than 256.

Increase the width of the octeon_irq_ciu_to_irq to int to be able to
handle this case.  Remove the hacky code that verified that u8 would
not be overflowed.

Signed-off-by: David Daney <david.daney@cavium.com>
---
 arch/mips/cavium-octeon/octeon-irq.c | 27 ++-------------------------
 1 file changed, 2 insertions(+), 25 deletions(-)

diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index 4f9eb05..bc30d3a 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2004-2014 Cavium, Inc.
+ * Copyright (C) 2004-2016 Cavium, Inc.
  */
 
 #include <linux/of_address.h>
@@ -28,7 +28,7 @@ struct octeon_irq_ciu_domain_data {
 	int num_sum;  /* number of sum registers (2 or 3). */
 };
 
-static __read_mostly u8 octeon_irq_ciu_to_irq[8][64];
+static __read_mostly int octeon_irq_ciu_to_irq[8][64];
 
 struct octeon_ciu_chip_data {
 	union {
@@ -1158,16 +1158,6 @@ static struct irq_chip *octeon_irq_ciu_chip;
 static struct irq_chip *octeon_irq_ciu_chip_edge;
 static struct irq_chip *octeon_irq_gpio_chip;
 
-static bool octeon_irq_virq_in_range(unsigned int virq)
-{
-	/* We cannot let it overflow the mapping array. */
-	if (virq < (1ul << 8 * sizeof(octeon_irq_ciu_to_irq[0][0])))
-		return true;
-
-	WARN_ONCE(true, "virq out of range %u.\n", virq);
-	return false;
-}
-
 static int octeon_irq_ciu_map(struct irq_domain *d,
 			      unsigned int virq, irq_hw_number_t hw)
 {
@@ -1176,13 +1166,6 @@ static int octeon_irq_ciu_map(struct irq_domain *d,
 	unsigned int bit = hw & 63;
 	struct octeon_irq_ciu_domain_data *dd = d->host_data;
 
-	if (!octeon_irq_virq_in_range(virq))
-		return -EINVAL;
-
-	/* Don't map irq if it is reserved for GPIO. */
-	if (line == 0 && bit >= 16 && bit <32)
-		return 0;
-
 	if (line >= dd->num_sum || octeon_irq_ciu_to_irq[line][bit] != 0)
 		return -EINVAL;
 
@@ -1215,9 +1198,6 @@ static int octeon_irq_gpio_map(struct irq_domain *d,
 	unsigned int line, bit;
 	int r;
 
-	if (!octeon_irq_virq_in_range(virq))
-		return -EINVAL;
-
 	line = (hw + gpiod->base_hwirq) >> 6;
 	bit = (hw + gpiod->base_hwirq) & 63;
 	if (line > ARRAY_SIZE(octeon_irq_ciu_to_irq) ||
@@ -1899,9 +1879,6 @@ static int octeon_irq_ciu2_map(struct irq_domain *d,
 	unsigned int line = hw >> 6;
 	unsigned int bit = hw & 63;
 
-	if (!octeon_irq_virq_in_range(virq))
-		return -EINVAL;
-
 	/*
 	 * Don't map irq if it is reserved for GPIO.
 	 * (Line 7 are the GPIO lines.)
-- 
1.7.11.7

[toc] | [prev] | [next] | [standalone]


#1330593 — [PATCH v2 7/8] MIPS: OCTEON: Add SMP support for OCTEON cn78xx et al.

FromDavid Daney <ddaney.cavm@gmail.com>
Date2016-02-09 20:10 +0100
Subject[PATCH v2 7/8] MIPS: OCTEON: Add SMP support for OCTEON cn78xx et al.
Message-ID<r0lPK-8iJ-49@gated-at.bofh.it>
In reply to#1330591
From: David Daney <david.daney@cavium.com>

OCTEON chips with the CIU3 interrupt controller use a different IPI
mechanism that previous models.

Add plat_smp_ops for the cn78xx and probing code to choose between the
two types of ops.

Signed-off-by: David Daney <david.daney@cavium.com>
---
 arch/mips/cavium-octeon/setup.c       |   4 +-
 arch/mips/cavium-octeon/smp.c         | 145 +++++++++++++++++++++++++++++++---
 arch/mips/include/asm/octeon/octeon.h |   6 ++
 3 files changed, 139 insertions(+), 16 deletions(-)

diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 54a214e..8ffc1f1 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -43,8 +43,6 @@
 #include <asm/octeon/cvmx-mio-defs.h>
 #include <asm/octeon/cvmx-rst-defs.h>
 
-extern struct plat_smp_ops octeon_smp_ops;
-
 #ifdef CONFIG_PCI
 extern void pci_console_init(const char *arg);
 #endif
@@ -888,7 +886,7 @@ void __init prom_init(void)
 #endif
 
 	octeon_user_io_init();
-	register_smp_ops(&octeon_smp_ops);
+	octeon_setup_smp();
 }
 
 /* Exclude a single page from the regions obtained in plat_mem_setup. */
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
index b0f9a0a..29d1da5 100644
--- a/arch/mips/cavium-octeon/smp.c
+++ b/arch/mips/cavium-octeon/smp.c
@@ -30,25 +30,55 @@ uint64_t octeon_bootloader_entry_addr;
 EXPORT_SYMBOL(octeon_bootloader_entry_addr);
 #endif
 
+static void octeon_icache_flush(void)
+{
+	asm volatile ("synci 0($0)\n");
+}
+
+static void (*octeon_message_functions[8])(void) = {
+	scheduler_ipi,
+	generic_smp_call_function_interrupt,
+	octeon_icache_flush,
+};
+
 static irqreturn_t mailbox_interrupt(int irq, void *dev_id)
 {
-	const int coreid = cvmx_get_core_num();
-	uint64_t action;
+	u64 mbox_clrx = CVMX_CIU_MBOX_CLRX(cvmx_get_core_num());
+	u64 action;
+	int i;
+
+	/*
+	 * Make sure the function array initialization remains
+	 * correct.
+	 */
+	BUILD_BUG_ON(SMP_RESCHEDULE_YOURSELF != (1 << 0));
+	BUILD_BUG_ON(SMP_CALL_FUNCTION       != (1 << 1));
+	BUILD_BUG_ON(SMP_ICACHE_FLUSH        != (1 << 2));
+
+	/*
+	 * Load the mailbox register to figure out what we're supposed
+	 * to do.
+	 */
+	action = cvmx_read_csr(mbox_clrx);
 
-	/* Load the mailbox register to figure out what we're supposed to do */
-	action = cvmx_read_csr(CVMX_CIU_MBOX_CLRX(coreid)) & 0xffff;
+	if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+		action &= 0xff;
+	else
+		action &= 0xffff;
 
 	/* Clear the mailbox to clear the interrupt */
-	cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), action);
+	cvmx_write_csr(mbox_clrx, action);
 
-	if (action & SMP_CALL_FUNCTION)
-		generic_smp_call_function_interrupt();
-	if (action & SMP_RESCHEDULE_YOURSELF)
-		scheduler_ipi();
+	for (i = 0; i < ARRAY_SIZE(octeon_message_functions) && action;) {
+		if (action & 1) {
+			void (*fn)(void) = octeon_message_functions[i];
 
-	/* Check if we've been told to flush the icache */
-	if (action & SMP_ICACHE_FLUSH)
-		asm volatile ("synci 0($0)\n");
+			if (fn)
+				fn();
+		}
+		action >>= 1;
+		i++;
+	}
 	return IRQ_HANDLED;
 }
 
@@ -102,10 +132,10 @@ static void octeon_smp_setup(void)
 	const int coreid = cvmx_get_core_num();
 	int cpus;
 	int id;
-	int core_mask = octeon_get_boot_coremask();
 	struct cvmx_sysinfo *sysinfo = cvmx_sysinfo_get();
 
 #ifdef CONFIG_HOTPLUG_CPU
+	int core_mask = octeon_get_boot_coremask();
 	unsigned int num_cores = cvmx_octeon_num_cores();
 #endif
 
@@ -390,3 +420,92 @@ struct plat_smp_ops octeon_smp_ops = {
 	.cpu_die		= octeon_cpu_die,
 #endif
 };
+
+static irqreturn_t octeon_78xx_reched_interrupt(int irq, void *dev_id)
+{
+	scheduler_ipi();
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t octeon_78xx_call_function_interrupt(int irq, void *dev_id)
+{
+	generic_smp_call_function_interrupt();
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t octeon_78xx_icache_flush_interrupt(int irq, void *dev_id)
+{
+	octeon_icache_flush();
+	return IRQ_HANDLED;
+}
+
+/*
+ * Callout to firmware before smp_init
+ */
+static void octeon_78xx_prepare_cpus(unsigned int max_cpus)
+{
+	if (request_irq(OCTEON_IRQ_MBOX0 + 0,
+			octeon_78xx_reched_interrupt,
+			IRQF_PERCPU | IRQF_NO_THREAD, "Scheduler",
+			octeon_78xx_reched_interrupt)) {
+		panic("Cannot request_irq for SchedulerIPI");
+	}
+	if (request_irq(OCTEON_IRQ_MBOX0 + 1,
+			octeon_78xx_call_function_interrupt,
+			IRQF_PERCPU | IRQF_NO_THREAD, "SMP-Call",
+			octeon_78xx_call_function_interrupt)) {
+		panic("Cannot request_irq for SMP-Call");
+	}
+	if (request_irq(OCTEON_IRQ_MBOX0 + 2,
+			octeon_78xx_icache_flush_interrupt,
+			IRQF_PERCPU | IRQF_NO_THREAD, "ICache-Flush",
+			octeon_78xx_icache_flush_interrupt)) {
+		panic("Cannot request_irq for ICache-Flush");
+	}
+}
+
+static void octeon_78xx_send_ipi_single(int cpu, unsigned int action)
+{
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		if (action & 1)
+			octeon_ciu3_mbox_send(cpu, i);
+		action >>= 1;
+	}
+}
+
+static void octeon_78xx_send_ipi_mask(const struct cpumask *mask,
+				      unsigned int action)
+{
+	unsigned int cpu;
+
+	for_each_cpu(cpu, mask)
+		octeon_78xx_send_ipi_single(cpu, action);
+}
+
+static struct plat_smp_ops octeon_78xx_smp_ops = {
+	.send_ipi_single	= octeon_78xx_send_ipi_single,
+	.send_ipi_mask		= octeon_78xx_send_ipi_mask,
+	.init_secondary		= octeon_init_secondary,
+	.smp_finish		= octeon_smp_finish,
+	.boot_secondary		= octeon_boot_secondary,
+	.smp_setup		= octeon_smp_setup,
+	.prepare_cpus		= octeon_78xx_prepare_cpus,
+#ifdef CONFIG_HOTPLUG_CPU
+	.cpu_disable		= octeon_cpu_disable,
+	.cpu_die		= octeon_cpu_die,
+#endif
+};
+
+void __init octeon_setup_smp(void)
+{
+	struct plat_smp_ops *ops;
+
+	if (octeon_has_feature(OCTEON_FEATURE_CIU3))
+		ops = &octeon_78xx_smp_ops;
+	else
+		ops = &octeon_smp_ops;
+
+	register_smp_ops(ops);
+}
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
index 53d51ae..07c0516 100644
--- a/arch/mips/include/asm/octeon/octeon.h
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -299,6 +299,12 @@ static inline void octeon_npi_write32(uint64_t address, uint32_t val)
 	cvmx_read64_uint32(address ^ 4);
 }
 
+#ifdef CONFIG_SMP
+void octeon_setup_smp(void);
+#else
+static inline void octeon_setup_smp(void) {}
+#endif
+
 struct irq_domain;
 struct device_node;
 struct irq_data;
-- 
1.7.11.7

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web