[PATCH] clocksource: imx-tpm: Wait for CnV write to take effect

Jacky Bai ping.bai at nxp.com
Mon Oct 9 01:42:35 PDT 2023


The value write into the TPM CnV can only be updated into the HW
when CNT increase. Additional writes to the CnV write buffer are
ignored until the register has been updated. So we need to check
if the CnV has been updated before continue. Wait for 1 CNT cycle
in worst case.

Additionally, current return check is not correct, if a max_delta
need be set, it will return '-ETIME' wrongly due to the 'int' type
cast, so refine the check logic to fix it.

Signed-off-by: Jacky Bai <ping.bai at nxp.com>
---
 drivers/clocksource/timer-imx-tpm.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/clocksource/timer-imx-tpm.c b/drivers/clocksource/timer-imx-tpm.c
index bd64a8a8427f..92c025b70eb6 100644
--- a/drivers/clocksource/timer-imx-tpm.c
+++ b/drivers/clocksource/timer-imx-tpm.c
@@ -83,20 +83,28 @@ static u64 notrace tpm_read_sched_clock(void)
 static int tpm_set_next_event(unsigned long delta,
 				struct clock_event_device *evt)
 {
-	unsigned long next, now;
+	unsigned long next, prev, now;
 
-	next = tpm_read_counter();
-	next += delta;
+	prev = tpm_read_counter();
+	next = prev + delta;
 	writel(next, timer_base + TPM_C0V);
 	now = tpm_read_counter();
 
+	/*
+	 * Need to wait CNT increase at least 1 cycle to make sure
+	 * the C0V has been updated into HW.
+	 */
+	if ((next & 0xffffffff) != readl(timer_base + TPM_C0V))
+		while (now == tpm_read_counter())
+			;
+
 	/*
 	 * NOTE: We observed in a very small probability, the bus fabric
 	 * contention between GPU and A7 may results a few cycles delay
 	 * of writing CNT registers which may cause the min_delta event got
 	 * missed, so we need add a ETIME check here in case it happened.
 	 */
-	return (int)(next - now) <= 0 ? -ETIME : 0;
+	return (now - prev) >= delta ? -ETIME : 0;
 }
 
 static int tpm_set_state_oneshot(struct clock_event_device *evt)
-- 
2.34.1




More information about the linux-arm-kernel mailing list