Module Name:    src
Committed By:   ad
Date:           Fri Apr 24 22:25:07 UTC 2020

Modified Files:
        src/sys/dev/ic: hpet.c

Log Message:
On attach figure out how long a single read of the counter register takes
and use that for the adjustment in hpet_delay().


To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/ic/hpet.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ic/hpet.c
diff -u src/sys/dev/ic/hpet.c:1.14 src/sys/dev/ic/hpet.c:1.15
--- src/sys/dev/ic/hpet.c:1.14	Thu Apr 23 20:33:57 2020
+++ src/sys/dev/ic/hpet.c	Fri Apr 24 22:25:07 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: hpet.c,v 1.14 2020/04/23 20:33:57 ad Exp $ */
+/* $NetBSD: hpet.c,v 1.15 2020/04/24 22:25:07 ad Exp $ */
 
 /*
  * Copyright (c) 2006 Nicolas Joly
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hpet.c,v 1.14 2020/04/23 20:33:57 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hpet.c,v 1.15 2020/04/24 22:25:07 ad Exp $");
 
 #include <sys/systm.h>
 #include <sys/device.h>
@@ -79,7 +79,7 @@ hpet_attach_subr(device_t dv)
 	struct hpet_softc *sc = device_private(dv);
 	struct timecounter *tc;
 	uint64_t tmp;
-	uint32_t val;
+	uint32_t val, sval, eval;
 	int i;
 
 	tc = &sc->sc_tc;
@@ -130,6 +130,19 @@ hpet_attach_subr(device_t dv)
 
 	if (device_unit(dv) == 0)
 		hpet0 = sc;
+
+	/*
+	 * Determine approximately how long it takes to read the counter
+	 * register once, and compute an ajustment for hpet_delay() based on
+	 * that.
+	 */
+	(void)bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_MCOUNT_LO);
+	sval = bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_MCOUNT_LO);
+	for (i = 0; i < 998; i++)
+		(void)bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_MCOUNT_LO);
+	eval = bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_MCOUNT_LO);
+	val = eval - sval;
+	sc->sc_adj = (int64_t)val * sc->sc_period / 1000;
 }
 
 static u_int
@@ -168,13 +181,13 @@ hpet_delay(unsigned int us)
 	int64_t delta;
 
 	/*
-	 * Read timer before slow division.  Assume that each read of the
-	 * HPET costs ~500ns.  Aim for the middle and subtract 750ns for
-	 * overhead.
+	 * Read timer before slow division.  Convert microseconds to
+	 * femtoseconds, subtract the cost of 1 counter register access,
+	 * and convert to HPET units.
 	 */
 	sc = hpet0;
 	otick = bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_MCOUNT_LO);
-	delta = (((int64_t)us * 1000000000) - 750000000) / sc->sc_period;
+	delta = (((int64_t)us * 1000000000) - sc->sc_adj) / sc->sc_period;
 
 	while (delta > 0) {
 		SPINLOCK_BACKOFF_HOOK;

Reply via email to