summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--platform/generic/include/mips/mips-cm.h1
-rw-r--r--platform/generic/include/mips/p8700.h1
-rw-r--r--platform/generic/mips/p8700.c18
3 files changed, 19 insertions, 1 deletions
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);