aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hdata/cpu-common.c26
-rw-r--r--hw/phb4.c12
-rw-r--r--hw/psi.c21
-rw-r--r--hw/slw.c9
4 files changed, 41 insertions, 27 deletions
diff --git a/hdata/cpu-common.c b/hdata/cpu-common.c
index 9a05227..a1a9312 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 a06d38c..fa9e911 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -3399,7 +3399,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;
@@ -3416,8 +3416,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);
@@ -3431,8 +3431,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,
};
@@ -3622,7 +3622,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 ccc3578..571714a 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 4ed8513..ce409f9 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);