diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2021-08-04 12:50:40 +0530 |
---|---|---|
committer | Vasant Hegde <hegdevasant@linux.vnet.ibm.com> | 2021-08-06 11:51:25 +0530 |
commit | 891ed8df672ddc3a38b4629aa4087f9930e1669d (patch) | |
tree | 02f93eebfb1ff97059d5e85cd6d29342e657b7c3 /hw | |
parent | 65714f47fb7e4d0dbf4b7d2befb5c5e86014befd (diff) | |
download | skiboot-891ed8df672ddc3a38b4629aa4087f9930e1669d.zip skiboot-891ed8df672ddc3a38b4629aa4087f9930e1669d.tar.gz skiboot-891ed8df672ddc3a38b4629aa4087f9930e1669d.tar.bz2 |
Initial POWER10 enablement
Co-authored-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Co-authored-by: Vaidyanathan Srinivasan <svaidy@linux.ibm.com>
Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.ibm.com>
Co-authored-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Michael Neuling <mikey@neuling.org>
Co-authored-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Co-authored-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Co-authored-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/chiptod.c | 30 | ||||
-rw-r--r-- | hw/dts.c | 7 | ||||
-rw-r--r-- | hw/lpc.c | 7 | ||||
-rw-r--r-- | hw/xscom.c | 25 |
4 files changed, 58 insertions, 11 deletions
diff --git a/hw/chiptod.c b/hw/chiptod.c index f445fd4..4e62fd7 100644 --- a/hw/chiptod.c +++ b/hw/chiptod.c @@ -959,6 +959,30 @@ bool chiptod_wakeup_resync(void) return false; } +/* + * Fixup for p10 TOD bug workaround. + * + * The TOD may fail to start if all clocks in the system are derived from + * the same reference oscillator. + * + * Avoiding this is pretty easy: Whenever we clear/reset the TOD registers, + * make sure to init bits 26:31 of TOD_SLAVE_PATH_CTRL (0x40005) to 0b111111 + * instead of 0b000000. The value 0 in TOD_S_PATH_CTRL_REG(26:31) must be + * avoided, and if it does get written it must be followed up by writing a + * value of all ones to clean up the resulting bad state before the (nonzero) + * final value can be written. + */ +static void fixup_tod_reg_value(struct chiptod_tod_regs *treg_entry) +{ + int32_t chip_id = this_cpu()->chip_id; + + if (proc_gen != proc_gen_p10) + return; + + if (treg_entry->xscom_addr == TOD_SLAVE_PATH_CTRL) + treg_entry->val[chip_id].data |= PPC_BITMASK(26,31); +} + static int __chiptod_recover_tod_errors(void) { uint64_t terr; @@ -997,8 +1021,12 @@ static int __chiptod_recover_tod_errors(void) return 0; } + fixup_tod_reg_value(&chiptod_tod_regs[i]); + prlog(PR_DEBUG, "Parity error, Restoring TOD register: " - "%08llx\n", chiptod_tod_regs[i].xscom_addr); + "%08llx = %016llx\n", + chiptod_tod_regs[i].xscom_addr, + chiptod_tod_regs[i].val[chip_id].data); if (xscom_writeme(chiptod_tod_regs[i].xscom_addr, chiptod_tod_regs[i].val[chip_id].data)) { prerror("XSCOM error writing 0x%08llx reg.\n", @@ -171,7 +171,11 @@ static void dts_async_read_temp(struct timer *t __unused, void *data, swkup_rc = dctl_set_special_wakeup(cpu); - rc = dts_read_core_temp_p9(cpu->pir, &dts); + if (proc_gen == proc_gen_p9) + rc = dts_read_core_temp_p9(cpu->pir, &dts); + else /* (proc_gen == proc_gen_p10) */ + rc = OPAL_UNSUPPORTED; /* XXX P10 */ + if (!rc) { if (cpu->sensor_attr == SENSOR_DTS_ATTR_TEMP_MAX) *cpu->sensor_data = cpu_to_be64(dts.temp); @@ -219,6 +223,7 @@ static int dts_read_core_temp(u32 pir, struct dts *dts, u8 attr, rc = OPAL_ASYNC_COMPLETION; unlock(&cpu->dts_lock); break; + case proc_gen_p10: /* XXX P10 */ default: rc = OPAL_UNSUPPORTED; } @@ -915,7 +915,8 @@ void lpc_finalize_interrupts(void) if (chip->lpc && chip->psi && (chip->type == PROC_CHIP_P9_NIMBUS || chip->type == PROC_CHIP_P9_CUMULUS || - chip->type == PROC_CHIP_P9P)) + chip->type == PROC_CHIP_P9P || + chip->type == PROC_CHIP_P10)) lpc_create_int_map(chip->lpc, chip->psi->node); } } @@ -959,6 +960,7 @@ static void lpc_init_interrupts_one(struct proc_chip *chip) case PROC_CHIP_P9_NIMBUS: case PROC_CHIP_P9_CUMULUS: case PROC_CHIP_P9P: + case PROC_CHIP_P10: /* On P9, we additionally setup the routing. */ lpc->has_serirq = true; for (i = 0; i < LPC_NUM_SERIRQ; i++) { @@ -1377,7 +1379,8 @@ void lpc_register_client(uint32_t chip_id, has_routes = chip->type == PROC_CHIP_P9_NIMBUS || chip->type == PROC_CHIP_P9_CUMULUS || - chip->type == PROC_CHIP_P9P; + chip->type == PROC_CHIP_P9P || + chip->type == PROC_CHIP_P10; if (policy != IRQ_ATTR_TARGET_OPAL && !has_routes) { prerror("Chip doesn't support OS interrupt policy\n"); @@ -94,7 +94,11 @@ static void xscom_reset(uint32_t gcid, bool need_delay) mtspr(SPR_HMER, HMER_CLR_MASK); /* Setup local and target scom addresses */ - if (proc_gen == proc_gen_p9) { + if (proc_gen == proc_gen_p10) { + recv_status_reg = 0x00090018; + log_reg = 0x0090012; + err_reg = 0x0090013; + } else if (proc_gen == proc_gen_p9) { recv_status_reg = 0x00090018; log_reg = 0x0090012; err_reg = 0x0090013; @@ -497,7 +501,7 @@ static int xscom_indirect_read(uint32_t gcid, uint64_t pcb_addr, uint64_t *val) { uint64_t form = xscom_indirect_form(pcb_addr); - if ((proc_gen == proc_gen_p9) && (form == 1)) + if ((proc_gen >= proc_gen_p9) && (form == 1)) return OPAL_UNSUPPORTED; return xscom_indirect_read_form0(gcid, pcb_addr, val); @@ -565,7 +569,7 @@ static int xscom_indirect_write(uint32_t gcid, uint64_t pcb_addr, uint64_t val) { uint64_t form = xscom_indirect_form(pcb_addr); - if ((proc_gen == proc_gen_p9) && (form == 1)) + if ((proc_gen >= proc_gen_p9) && (form == 1)) return xscom_indirect_write_form1(gcid, pcb_addr, val); return xscom_indirect_write_form0(gcid, pcb_addr, val); @@ -576,7 +580,7 @@ static uint32_t xscom_decode_chiplet(uint32_t partid, uint64_t *pcb_addr) uint32_t gcid = (partid & 0x0fffffff) >> 4; uint32_t core = partid & 0xf; - if (proc_gen == proc_gen_p9) { + if (proc_gen >= proc_gen_p9) { /* XXX Not supported */ *pcb_addr = 0; } else { @@ -821,7 +825,9 @@ int64_t xscom_read_cfam_chipid(uint32_t partid, uint32_t *chip_id) * something up */ if (chip_quirk(QUIRK_NO_F000F)) { - if (proc_gen == proc_gen_p9) + if (proc_gen == proc_gen_p10) + val = 0x120DA04980000000UL; /* P10 DD1.0 */ + else if (proc_gen == proc_gen_p9) val = 0x203D104980000000UL; /* P9 Nimbus DD2.3 */ else val = 0x221EF04980000000UL; /* P8 Murano DD2.1 */ @@ -873,6 +879,10 @@ static void xscom_init_chip_info(struct proc_chip *chip) chip->type = PROC_CHIP_P9P; assert(proc_gen == proc_gen_p9); break; + case 0xda: + chip->type = PROC_CHIP_P10; + assert(proc_gen == proc_gen_p10); + break; default: printf("CHIP: Unknown chip type 0x%02x !!!\n", (unsigned char)(val & 0xff)); @@ -911,7 +921,7 @@ static void xscom_init_chip_info(struct proc_chip *chip) prlog(PR_INFO,"P9 DD%i.%i%d detected\n", 0xf & (chip->ec_level >> 4), chip->ec_level & 0xf, rev); chip->ec_rev = rev; - } + } /* XXX P10 */ } /* @@ -949,7 +959,8 @@ void xscom_init(void) struct proc_chip *chip; const char *chip_name; static const char *chip_names[] = { - "UNKNOWN", "P8E", "P8", "P8NVL", "P9N", "P9C", "P9P" + "UNKNOWN", "P8E", "P8", "P8NVL", "P9N", "P9C", "P9P", + "P10", }; chip = get_chip(gcid); |