[Skiboot] [PATCH] Ensure P9 DD1 workarounds apply only to Nimbus

Michael Neuling mikey at neuling.org
Thu Jun 15 15:12:40 AEST 2017


The workarounds for P9 DD1 are only needed for Nimbus. P9 Cumulus will
be DD1 but don't need these same workarounds.

This patch ensures the P9 DD1 workarounds only apply to Nimbus. It
also renames some things to make clear what's what.

Signed-off-by: Michael Neuling <mikey at neuling.org>
---
 hdata/cpu-common.c | 26 +++++++++++++++++++-------
 hw/phb4.c          | 12 ++++++------
 hw/psi.c           | 21 +++++++++++----------
 hw/slw.c           |  9 +++++----
 4 files changed, 41 insertions(+), 27 deletions(-)

diff --git a/hdata/cpu-common.c b/hdata/cpu-common.c
index 9a05227f5a..a1a9312184 100644
--- a/hdata/cpu-common.c
+++ b/hdata/cpu-common.c
@@ -21,6 +21,18 @@
 
 #include "hdata.h"
 
+static bool is_power9n(uint32_t version)
+{
+	/*
+	 * Bit 13 tells us:
+	 *   0 = Scale out (aka Nimbus)
+	 *   1 = Scale up  (aka Cumulus)
+	 */
+	if ((version >> 13) & 1)
+		return false;
+	return true;
+}
+
 struct dt_node * add_core_common(struct dt_node *cpus,
 				 const struct sppcia_cpu_cache *cache,
 				 const struct sppaca_cpu_timebase *tb,
@@ -42,7 +54,7 @@ struct dt_node * add_core_common(struct dt_node *cpus,
 	       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 	       0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00,
 	};
-	const uint8_t pa_features_p9_dd1[] = {
+	const uint8_t pa_features_p9n_dd1[] = {
 	       64, 0,
 	       0xf6, 0x3f, 0xc7, 0xc0, 0x80, 0xd0, 0x80, 0x00, /*  0 ..  7 */
 	       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*  8 .. 15 */
@@ -53,7 +65,7 @@ struct dt_node * add_core_common(struct dt_node *cpus,
 	       0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 48 .. 55 */
 	       0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, /* 56 .. 63 */
 	};
-	const uint8_t pa_features_p9_dd2[] = {
+	const uint8_t pa_features_p9[] = {
 	       64, 0,
 	       0xf6, 0x3f, 0xc7, 0xc0, 0x80, 0xd0, 0x80, 0x00, /*  0 ..  7 */
 	       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*  8 .. 15 */
@@ -99,12 +111,12 @@ struct dt_node * add_core_common(struct dt_node *cpus,
 		break;
 	case PVR_TYPE_P9:
 		name = "PowerPC,POWER9";
-		if (PVR_VERS_MAJ(version) == 1) {
-			pa_features = pa_features_p9_dd1;
-			pa_features_size = sizeof(pa_features_p9_dd1);
+		if ((PVR_VERS_MAJ(version) == 1) && is_power9n(version)) {
+			pa_features = pa_features_p9n_dd1;
+			pa_features_size = sizeof(pa_features_p9n_dd1);
 		} else {
-			pa_features = pa_features_p9_dd2;
-			pa_features_size = sizeof(pa_features_p9_dd2);
+			pa_features = pa_features_p9;
+			pa_features_size = sizeof(pa_features_p9);
 		}
 		break;
 	default:
diff --git a/hw/phb4.c b/hw/phb4.c
index 7bcbc931fc..061ce17d84 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -3409,7 +3409,7 @@ static uint64_t phb4_lsi_attributes(struct irq_source *is __unused,
 	return IRQ_ATTR_TARGET_LINUX;
 }
 
-static int64_t phb4_dd1_lsi_set_xive(struct irq_source *is, uint32_t isn,
+static int64_t phb4_ndd1_lsi_set_xive(struct irq_source *is, uint32_t isn,
 				     uint16_t server, uint8_t priority)
 {
 	struct phb4 *p = is->data;
@@ -3426,8 +3426,8 @@ static int64_t phb4_dd1_lsi_set_xive(struct irq_source *is, uint32_t isn,
 	/* XXX FIXME: A quick mask/umask can make us shoot an interrupt
 	 * more than once to a queue. We need to keep track better.
 	 *
-	 * Thankfully, this is only on DD1 and for LSIs, so will go away
-	 * soon enough.
+	 * Thankfully, this is only on Nimubs DD1 and for LSIs, so
+	 * will go away soon enough.
 	 */
 	if (priority == 0xff)
 		out_be64(p->regs + PHB_IODA_DATA0, IODA3_LIST_Q);
@@ -3441,8 +3441,8 @@ static int64_t phb4_dd1_lsi_set_xive(struct irq_source *is, uint32_t isn,
 	return 0;
 }
 
-static const struct irq_source_ops phb4_dd1_lsi_ops = {
-	.set_xive = phb4_dd1_lsi_set_xive,
+static const struct irq_source_ops phb4_ndd1_lsi_ops = {
+	.set_xive = phb4_ndd1_lsi_set_xive,
 	.interrupt = phb4_err_interrupt,
 	.attributes = phb4_lsi_attributes,
 };
@@ -3632,7 +3632,7 @@ static void phb4_create(struct dt_node *np)
 				XIVE_SRC_LSI | XIVE_SRC_SHIFT_BUG,
 				p,
 				(p->rev == PHB4_REV_NIMBUS_DD10) ?
-				&phb4_dd1_lsi_ops : &phb4_lsi_ops);
+				&phb4_ndd1_lsi_ops : &phb4_lsi_ops);
 
 	/* Platform additional setup */
 	if (platform.pci_setup_phb)
diff --git a/hw/psi.c b/hw/psi.c
index ccc3578e2b..571714ae60 100644
--- a/hw/psi.c
+++ b/hw/psi.c
@@ -663,7 +663,7 @@ static char *psi_p9_irq_name(struct irq_source *is, uint32_t isn)
 	return strdup(names[idx]);
 }
 
-static void psi_p9_irq_dd1_eoi(struct irq_source *is, uint32_t isn)
+static void psi_p9_irq_ndd1_eoi(struct irq_source *is, uint32_t isn)
 {
 	struct psi *psi = is->data;
 	unsigned int idx = isn & 0xf;
@@ -674,11 +674,11 @@ static void psi_p9_irq_dd1_eoi(struct irq_source *is, uint32_t isn)
 	__xive_source_eoi(is, isn);
 }
 
-static const struct irq_source_ops psi_p9_dd1_irq_ops = {
+static const struct irq_source_ops psi_p9_ndd1_irq_ops = {
 	.interrupt = psihb_p9_interrupt,
 	.attributes = psi_p9_irq_attributes,
 	.name = psi_p9_irq_name,
-	.eoi = psi_p9_irq_dd1_eoi,
+	.eoi = psi_p9_irq_ndd1_eoi,
 };
 
 static const struct irq_source_ops psi_p9_irq_ops = {
@@ -822,7 +822,7 @@ static void psi_init_p8_interrupts(struct psi *psi)
 static void psi_init_p9_interrupts(struct psi *psi)
 {
 	struct proc_chip *c;
-	bool is_dd2;
+	bool is_p9ndd1;
 	u64 val;
 
 	/* Reset irq handling and switch to ESB mode */
@@ -856,22 +856,23 @@ static void psi_init_p9_interrupts(struct psi *psi)
 
 	/* Register sources */
 	c = next_chip(NULL);
-	is_dd2 = (c && c->ec_level >= 0x20);
+	is_p9ndd1 = (c && c->ec_level >= 0x10 &&
+		     c->type == PROC_CHIP_P9_NIMBUS);
 
-	if (is_dd2) {
+	if (is_p9ndd1) {
 		prlog(PR_DEBUG,
-		      "PSI[0x%03x]: Interrupts sources registered for P9 DD2.x\n",
+		      "PSI[0x%03x]: Interrupts sources registered for P9N DD1.x\n",
 		      psi->chip_id);
 		xive_register_hw_source(psi->interrupt, P9_PSI_NUM_IRQS,
 					12, psi->esb_mmio, XIVE_SRC_LSI,
-					psi, &psi_p9_irq_ops);
+					psi, &psi_p9_ndd1_irq_ops);
 	} else {
 		prlog(PR_DEBUG,
-		      "PSI[0x%03x]: Interrupts sources registered for P9 DD1.x\n",
+		      "PSI[0x%03x]: Interrupts sources registered for P9 DD2.x\n",
 		      psi->chip_id);
 		xive_register_hw_source(psi->interrupt, P9_PSI_NUM_IRQS,
 					12, psi->esb_mmio, XIVE_SRC_LSI,
-					psi, &psi_p9_dd1_irq_ops);
+					psi, &psi_p9_irq_ops);
 	}
 }
 
diff --git a/hw/slw.c b/hw/slw.c
index 4ed851366b..ce409f9ae6 100644
--- a/hw/slw.c
+++ b/hw/slw.c
@@ -650,7 +650,7 @@ static struct cpu_idle_states power9_cpu_idle_states[] = {
 };
 
 /* Idle states supported for P9 DD1 */
-static struct cpu_idle_states power9_dd1_cpu_idle_states[] = {
+static struct cpu_idle_states power9_ndd1_cpu_idle_states[] = {
 	{
 		.name = "stop0_lite",
 		.latency_ns = 200,
@@ -750,9 +750,10 @@ void add_cpu_idle_state_properties(void)
 	assert(chip);
 	if (chip->type == PROC_CHIP_P9_NIMBUS ||
 	    chip->type == PROC_CHIP_P9_CUMULUS) {
-		if (chip->ec_level == 0x10) {
-			states = power9_dd1_cpu_idle_states;
-			nr_states = ARRAY_SIZE(power9_dd1_cpu_idle_states);
+		if ((chip->ec_level == 0x10) &&
+		    (chip->type == PROC_CHIP_P9_NIMBUS)) {
+			states = power9_ndd1_cpu_idle_states;
+			nr_states = ARRAY_SIZE(power9_ndd1_cpu_idle_states);
 		} else {
 			states = power9_cpu_idle_states;
 			nr_states = ARRAY_SIZE(power9_cpu_idle_states);
-- 
2.11.0



More information about the Skiboot mailing list