Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic Implement a HPET based DELAY().
details: https://anonhg.NetBSD.org/src/rev/d19fea7aca35
branches: trunk
changeset: 971425:d19fea7aca35
user: ad <ad%NetBSD.org@localhost>
date: Thu Apr 23 20:33:57 2020 +0000
description:
Implement a HPET based DELAY().
diffstat:
sys/dev/ic/hpet.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++-----
sys/dev/ic/hpetvar.h | 7 ++++++-
2 files changed, 53 insertions(+), 6 deletions(-)
diffs (150 lines):
diff -r 39ea5143f16d -r d19fea7aca35 sys/dev/ic/hpet.c
--- a/sys/dev/ic/hpet.c Thu Apr 23 19:24:53 2020 +0000
+++ b/sys/dev/ic/hpet.c Thu Apr 23 20:33:57 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hpet.c,v 1.13 2011/10/31 12:47:15 yamt Exp $ */
+/* $NetBSD: hpet.c,v 1.14 2020/04/23 20:33:57 ad Exp $ */
/*
* Copyright (c) 2006 Nicolas Joly
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hpet.c,v 1.13 2011/10/31 12:47:15 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hpet.c,v 1.14 2020/04/23 20:33:57 ad Exp $");
#include <sys/systm.h>
#include <sys/device.h>
@@ -43,6 +43,7 @@
#include <sys/timetc.h>
#include <sys/bus.h>
+#include <sys/lock.h>
#include <dev/ic/hpetreg.h>
#include <dev/ic/hpetvar.h>
@@ -50,9 +51,12 @@
static u_int hpet_get_timecount(struct timecounter *);
static bool hpet_resume(device_t, const pmf_qual_t *);
+static struct hpet_softc *hpet0 __read_mostly;
+
int
hpet_detach(device_t dv, int flags)
{
+#if 0 /* XXX DELAY() is based off this, detaching is not a good idea. */
struct hpet_softc *sc = device_private(dv);
int rc;
@@ -64,6 +68,9 @@
bus_space_write_4(sc->sc_memt, sc->sc_memh, HPET_CONFIG, sc->sc_config);
return 0;
+#else
+ return EBUSY;
+#endif
}
void
@@ -84,8 +91,8 @@
tc->tc_counter_mask = 0xffffffff;
/* Get frequency */
- val = bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_PERIOD);
- if (val == 0 || val > HPET_PERIOD_MAX) {
+ sc->sc_period = bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_PERIOD);
+ if (sc->sc_period == 0 || sc->sc_period > HPET_PERIOD_MAX) {
aprint_error_dev(dv, "invalid timer period\n");
return;
}
@@ -104,7 +111,7 @@
}
}
- tmp = (1000000000000000ULL * 2) / val;
+ tmp = (1000000000000000ULL * 2) / sc->sc_period;
tc->tc_frequency = (tmp / 2) + (tmp & 1);
/* Enable timer */
@@ -120,6 +127,9 @@
if (!pmf_device_register(dv, NULL, hpet_resume))
aprint_error_dev(dv, "couldn't establish power handler\n");
+
+ if (device_unit(dv) == 0)
+ hpet0 = sc;
}
static u_int
@@ -143,6 +153,38 @@
return true;
}
+bool
+hpet_delay_p(void)
+{
+
+ return hpet0 != NULL;
+}
+
+void
+hpet_delay(unsigned int us)
+{
+ struct hpet_softc *sc;
+ uint32_t ntick, otick;
+ 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.
+ */
+ 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;
+
+ while (delta > 0) {
+ SPINLOCK_BACKOFF_HOOK;
+ ntick = bus_space_read_4(sc->sc_memt, sc->sc_memh,
+ HPET_MCOUNT_LO);
+ delta -= (uint32_t)(ntick - otick);
+ otick = ntick;
+ }
+}
+
MODULE(MODULE_CLASS_DRIVER, hpet, NULL);
#ifdef _MODULE
diff -r 39ea5143f16d -r d19fea7aca35 sys/dev/ic/hpetvar.h
--- a/sys/dev/ic/hpetvar.h Thu Apr 23 19:24:53 2020 +0000
+++ b/sys/dev/ic/hpetvar.h Thu Apr 23 20:33:57 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hpetvar.h,v 1.4 2011/06/14 16:33:51 jruoho Exp $ */
+/* $NetBSD: hpetvar.h,v 1.5 2020/04/23 20:33:57 ad Exp $ */
/*
* Copyright (c) 2006 Nicolas Joly
@@ -31,6 +31,8 @@
#ifndef _DEV_IC_HPETVAR_H_
#define _DEV_IC_HPETVAR_H_
+#include <sys/timetc.h>
+
struct hpet_softc {
bus_size_t sc_mems;
bus_space_tag_t sc_memt;
@@ -38,10 +40,13 @@
bool sc_mapped;
uint32_t sc_config;
+ int32_t sc_period;
struct timecounter sc_tc;
};
void hpet_attach_subr(device_t);
int hpet_detach(device_t, int flags);
+void hpet_delay(unsigned int);
+bool hpet_delay_p(void);
#endif /* _DEV_IC_HPETVAR_H_ */
Home |
Main Index |
Thread Index |
Old Index