diff --git a/platform/generic/include/mips/mips-cm.h b/platform/generic/include/mips/mips-cm.h index b3e056e8..84f8619b 100644 --- a/platform/generic/include/mips/mips-cm.h +++ b/platform/generic/include/mips/mips-cm.h @@ -76,6 +76,7 @@ CPC_CX_ACCESSOR_RW(32, CPC_Cx_STAT_CONF, stat_conf) CPS_ACCESSOR_RW(cpc, sz, CPC_OFFSET + (off), name) CPC_ACCESSOR_RW(32, CPC_PWRUP_CTL, pwrup_ctl) +CPC_ACCESSOR_RW(64, CPC_HRTIME, hrtime) CPC_ACCESSOR_RW(32, CPC_CM_STAT_CONF, cm_stat_conf) #endif diff --git a/platform/generic/include/mips/p8700.h b/platform/generic/include/mips/p8700.h index 16918164..4530fdf0 100644 --- a/platform/generic/include/mips/p8700.h +++ b/platform/generic/include/mips/p8700.h @@ -147,6 +147,7 @@ extern const struct p8700_cm_info *p8700_cm_info; /* CPC Block offsets */ #define CPC_PWRUP_CTL 0x0030 +#define CPC_HRTIME 0x0090 #define CPC_CM_STAT_CONF 0x1008 #define CPC_OFF_LOCAL 0x2000 diff --git a/platform/generic/mips/p8700.c b/platform/generic/mips/p8700.c index a0884f21..ffc8520f 100644 --- a/platform/generic/mips/p8700.c +++ b/platform/generic/mips/p8700.c @@ -36,6 +36,19 @@ void mips_p8700_pmp_set(unsigned int n, unsigned long flags, csr_write_num(pmacfg_csr, pmacfg); } +static void mips_p8700_sync_hrtimer(unsigned int cl) +{ + u64 v1, v2, mv, delta; + volatile u64 *my_timer = (volatile u64 *)(p8700_cm_info->gcr_base[cl] + CPC_OFFSET + CPC_HRTIME); + volatile u64 *ref_timer = (volatile u64 *)(p8700_cm_info->gcr_base[0] + CPC_OFFSET + CPC_HRTIME); + + v1 = readq_relaxed(my_timer); + mv = readq_relaxed(ref_timer); + v2 = readq_relaxed(my_timer); + delta = mv - ((v1 / 2) + (v2 / 2)); + writeq_relaxed(readq_relaxed(my_timer) + delta, my_timer); +} + void mips_p8700_power_up_other_cluster(u32 hartid) { unsigned int cl = cpu_cluster(hartid); @@ -48,8 +61,11 @@ void mips_p8700_power_up_other_cluster(u32 hartid) u32 stat = read_cpc_cm_stat_conf(hartid); stat = EXTRACT_FIELD(stat, CPC_Cx_STAT_CONF_SEQ_STATE); - if (stat == CPC_Cx_STAT_CONF_SEQ_STATE_U5) + if (stat == CPC_Cx_STAT_CONF_SEQ_STATE_U5) { + if (cl) /* sync high-res timer to cluster 0 */ + mips_p8700_sync_hrtimer(cl); return; + } cpu_relax(); } sbi_printf("ERROR: Fail to power up cluster %u\n", cl);