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/chiptod.c | |
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/chiptod.c')
-rw-r--r-- | hw/chiptod.c | 30 |
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", |