aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2021-08-04 12:50:40 +0530
committerVasant Hegde <hegdevasant@linux.vnet.ibm.com>2021-08-06 11:51:25 +0530
commit891ed8df672ddc3a38b4629aa4087f9930e1669d (patch)
tree02f93eebfb1ff97059d5e85cd6d29342e657b7c3 /hw
parent65714f47fb7e4d0dbf4b7d2befb5c5e86014befd (diff)
downloadskiboot-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.c30
-rw-r--r--hw/dts.c7
-rw-r--r--hw/lpc.c7
-rw-r--r--hw/xscom.c25
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",
diff --git a/hw/dts.c b/hw/dts.c
index b72516a..d8831e4 100644
--- a/hw/dts.c
+++ b/hw/dts.c
@@ -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;
}
diff --git a/hw/lpc.c b/hw/lpc.c
index c2a07a0..bf3ab1f 100644
--- a/hw/lpc.c
+++ b/hw/lpc.c
@@ -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");
diff --git a/hw/xscom.c b/hw/xscom.c
index c97740a..3474572 100644
--- a/hw/xscom.c
+++ b/hw/xscom.c
@@ -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);