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;