[PATCH v2 16/20] platform: generic: mips p8700: synchronize hi-res timers

Vladimir Kondratiev vladimir.kondratiev at mobileye.com
Sun Jan 18 03:37:58 PST 2026


There's high-resolution (1GHz) timer found in the p8700 cluster.
This timer used for precise time measurement by platform specific
software.

Synchronize this proprietary timers to reference in cluster 0.
Procedure borrowed from the aclint mtimer.

Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev at mobileye.com>
---
 platform/generic/include/mips/mips-cm.h |  1 +
 platform/generic/include/mips/p8700.h   |  1 +
 platform/generic/mips/p8700.c           | 18 +++++++++++++++++-
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/platform/generic/include/mips/mips-cm.h b/platform/generic/include/mips/mips-cm.h
index b3e056e8f9a64b9a44cfc43e505d9a8b698c49fa..84f8619b4a1bf2183e70ea151fb447e1c7bffe94 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 169181642716a2dea4b417db910895bd1960a5ec..4530fdf06fd91a3f1f8a2e0ae3c1db2d8f0bec69 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 a0884f211ca121a13f0f17f31319934527cd4209..5ce6dacd42a361a6b2faaab67f740f239f1303fa 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);

-- 
2.43.0




More information about the opensbi mailing list