nx: Add POWER9 DARN support

Message ID 20170412031645.30010-1-mikey@neuling.org
State Superseded
Headers show

Commit Message

Michael Neuling April 12, 2017, 3:16 a.m.
This sets up the per chip RNG MMIO BAR and points the per core DARN
BAR at it.

This is needed on P9 to enabled the DARN instruction (otherwise it'll
cause a xstop).

This includes a minor rework of some #defines to abstract MMIO
definitions.

Signed-off-by: Michael Neuling <mikey@neuling.org>
---
 hw/nx.c                 | 50 +++++++++++++++++++++++++++++++++++++++++++++++++
 hw/phb4.c               |  2 +-
 include/xscom-p9-regs.h | 11 +++++++++++
 3 files changed, 62 insertions(+), 1 deletion(-)

Patch

diff --git a/hw/nx.c b/hw/nx.c
index 83528d1459..69c37ccd4d 100644
--- a/hw/nx.c
+++ b/hw/nx.c
@@ -21,11 +21,61 @@ 
 #include <io.h>
 #include <cpu.h>
 #include <nx.h>
+#include <chip.h>
+#include <xscom-p9-regs.h>
+
+#define MMIO_CALC(__c, __b) \
+	(MMIO_CHIP_STRIDE * (__c) | __b)
+
+extern void nx_p9_rng_init(void);
+
+void nx_p9_rng_init(void)
+{
+	struct proc_chip *chip;
+	struct cpu_thread *c;
+	uint64_t bar, tmp;
+
+	if (proc_gen != proc_gen_p9)
+		return;
+
+	/*
+	 * Two things we need to setup here:
+	 *
+	 * 1) The per chip BAR for the NX RNG region. The location of
+	 *    this is determined by the global MMIO Map.
+
+	 * 2) The per core BAR for the DARN BAR, which points to the
+	 *    per chip RNG region set in 1.
+	 *
+	 */
+	for_each_chip(chip) {
+		/* 1) NX RNG BAR */
+		bar = MMIO_CALC(chip->id, P9X_NX_MMIO_OFFSET);
+		xscom_write(chip->id, P9X_NX_MMIO_BAR,
+			    bar | P9X_NX_MMIO_BAR_EN);
+		/* Read config register for pace info */
+		xscom_read(chip->id, P9X_NX_RNG_CFG, &tmp);
+		prlog(PR_INFO, "%x NX RNG pace:%lli)\n", chip->id,
+		      0xffff & (tmp >> 2));
+
+		/* 2) DARN BAR */
+		for_each_available_core_in_chip(c, chip->id) {
+			uint64_t addr;
+			addr = XSCOM_ADDR_P9_EX(pir_to_core_id(c->pir),
+						P9X_EX_NCU_DARN_BAR);
+			xscom_write(chip->id, addr,
+				    bar | P9X_EX_NCU_DARN_BAR_EN);
+		}
+	}
+}
+
 
 void nx_init(void)
 {
 	struct dt_node *node;
 
+	nx_p9_rng_init();
+
 	dt_for_each_compatible(dt_root, node, "ibm,power-nx") {
 		nx_create_rng_node(node);
 		nx_create_crypto_node(node);
diff --git a/hw/phb4.c b/hw/phb4.c
index 571f7037e2..99a87c8072 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -53,6 +53,7 @@ 
 #include <chip.h>
 #include <chiptod.h>
 #include <xive.h>
+#include <xscom-p9-regs.h>
 
 /* Enable this to disable error interrupts for debug purposes */
 #define DISABLE_ERR_INTS
@@ -3272,7 +3273,6 @@  static void phb4_create(struct dt_node *np)
 }
 
 /* Hack for assigning global MMIO space */
-#define MMIO_CHIP_STRIDE 0x0000040000000000ULL
 #define	PHB_BAR_BASE     0x000600c3c0000000ULL
 #define	PHB_BAR_SIZE     0x0000000000100000ULL
 #define	ESB_BAR_BASE     0x000600c300000000ULL
diff --git a/include/xscom-p9-regs.h b/include/xscom-p9-regs.h
index 04ec557de4..2dbad44805 100644
--- a/include/xscom-p9-regs.h
+++ b/include/xscom-p9-regs.h
@@ -7,6 +7,17 @@ 
 #define   P9X_EX_NCU_SPEC_BAR_ENABLE		PPC_BIT(0)
 #define   P9X_EX_NCU_SPEC_BAR_256K		PPC_BIT(1)
 #define   P9X_EX_NCU_SPEC_BAR_ADDRMSK		0x0fffffffffffc000ull /* naturally aligned */
+
+#define MMIO_CHIP_STRIDE			0x0000040000000000ull
+
+#define P9X_NX_MMIO_BAR				0x201108d
+#define  P9X_NX_MMIO_BAR_EN			PPC_BIT(52)
+#define  P9X_NX_MMIO_OFFSET			0x00060302031d0000ull
+
+#define P9X_NX_RNG_CFG				0x20110E0
+#define  P9X_NX_RNG_CFG_EN			PPC_BIT(63)
+
 #define P9X_EX_NCU_DARN_BAR			0x11011
+#define  P9X_EX_NCU_DARN_BAR_EN			PPC_BIT(0)
 
 #endif /* __XSCOM_P9_REGS_H__ */