diff options
-rw-r--r-- | hdata/cpu-common.c | 26 | ||||
-rw-r--r-- | hw/phb4.c | 12 | ||||
-rw-r--r-- | hw/psi.c | 21 | ||||
-rw-r--r-- | hw/slw.c | 9 |
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: @@ -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) @@ -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); } } @@ -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); |