aboutsummaryrefslogtreecommitdiff
path: root/hw/chiptod.c
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/chiptod.c
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/chiptod.c')
-rw-r--r--hw/chiptod.c30
1 files changed, 29 insertions, 1 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",