* Mark Kettenis <[email protected]> [2012-06-03 08:51:03]:
> > Date: Sat, 2 Jun 2012 15:36:22 -0400
> > From: Matt Dainty <[email protected]>
> > 
> > As before but with the verbosity of the attach line tuned down a notch
> > and not printing extra ':'s as pointed out by Theo. So now it looks
> > like this:
> > 
> > ---8<---
> > tcpcib0 at pci0 dev 31 function 0 "Intel E600 LPC" rev 0x00: 14318179 Hz 
> > timer, watchdog
> > ---8<---
> > 
> > Matt
> 
> I've committed the part to remove the unecessary tcpcib_wdt_unlock()
> calls, since it's better to have that committed as a seperate diff.
> 
> I'm looking at the HPET stuff now.  Can you regenerate your diff and
> post it here (after my commit has percolated to your anoncvs mirror)
> for people who want to try it?

Sure, here it is.

Matt

--- sys/dev/pci/tcpcib.c.orig   Thu May 31 14:17:23 2012
+++ sys/dev/pci/tcpcib.c        Wed May 30 16:21:13 2012
@@ -17,12 +17,13 @@
  */
 
 /*
- * Intel Atom E600 series LPC bridge also containing watchdog
+ * Intel Atom E600 series LPC bridge also containing HPET and watchdog
  */
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/device.h>
+#include <sys/timetc.h>
 
 #include <machine/bus.h>
 
@@ -52,18 +53,42 @@
 #define        E600_WDT_WDTLR_ENABLE   (1 << 1)        /* Watchdog Timer 
Enable */
 #define        E600_WDT_WDTLR_TIMEOUT  (1 << 2)        /* WDT Timeout 
Configuration */
 
+#define        E600_HPET_BASE          0xfed00000      /* HPET register base */
+#define        E600_HPET_SIZE          0x00000400      /* HPET register size */
+
+#define        E600_HPET_GCID          0x000           /* Capabilities and ID 
*/
+#define        E600_HPET_GCID_WIDTH    (1 << 13)       /* Counter Size */
+#define        E600_HPET_PERIOD        0x004           /* Counter Tick Period 
*/
+#define        E600_HPET_GC            0x010           /* General 
Configuration */
+#define        E600_HPET_GC_ENABLE     (1 << 0)        /* Overall Enable */
+#define        E600_HPET_GIS           0x020           /* General Interrupt 
Status */
+#define        E600_HPET_MCV           0x0f0           /* Main Counter Value */
+#define        E600_HPET_T0C           0x100           /* Timer 0 Config and 
Capabilities */
+#define        E600_HPET_T0CV          0x108           /* Timer 0 Comparator 
Value */
+#define        E600_HPET_T1C           0x120           /* Timer 1 Config and 
Capabilities */
+#define        E600_HPET_T1CV          0x128           /* Timer 1 Comparator 
Value */
+#define        E600_HPET_T2C           0x140           /* Timer 2 Config and 
Capabilities */
+#define        E600_HPET_T2CV          0x148           /* Timer 2 Comparator 
Value */
+
 struct tcpcib_softc {
        struct device sc_dev;
 
        /* Keep track of which parts of the hardware are active */
        int sc_active;
 #define        E600_WDT_ACTIVE         (1 << 0)
+#define        E600_HPET_ACTIVE        (1 << 1)
 
        /* Watchdog interface */
        bus_space_tag_t sc_wdt_iot;
        bus_space_handle_t sc_wdt_ioh;
 
        int sc_wdt_period;
+
+       /* High Precision Event Timer */
+       bus_space_tag_t sc_hpet_iot;
+       bus_space_handle_t sc_hpet_ioh;
+
+       struct timecounter sc_hpet_timecounter;
 };
 
 struct cfdriver tcpcib_cd = {
@@ -79,6 +104,8 @@
 void    tcpcib_wdt_start(struct tcpcib_softc *);
 void    tcpcib_wdt_stop(struct tcpcib_softc *);
 
+u_int   tcpcib_hpet_get_timecount(struct timecounter *tc);
+
 struct cfattach tcpcib_ca = {
        sizeof(struct tcpcib_softc), tcpcib_match, tcpcib_attach,
        NULL, tcpcib_activate
@@ -157,10 +184,38 @@
 {
        struct tcpcib_softc *sc = (struct tcpcib_softc *)self;
        struct pci_attach_args *pa = aux;
+       struct timecounter *tc = &sc->sc_hpet_timecounter;
        u_int32_t reg, wdtbase;
 
        sc->sc_active = 0;
 
+       /* High Precision Event Timer */
+       sc->sc_hpet_iot = pa->pa_memt;
+       if (bus_space_map(sc->sc_hpet_iot, E600_HPET_BASE, E600_HPET_SIZE, 0,
+           &sc->sc_hpet_ioh) == 0) {
+               tc->tc_get_timecount = tcpcib_hpet_get_timecount;
+               /* XXX 64-bit counter is not supported! */
+               tc->tc_counter_mask = 0xffffffff;
+
+               reg = bus_space_read_4(sc->sc_hpet_iot, sc->sc_hpet_ioh,
+                   E600_HPET_PERIOD);
+               /* femtosecs -> Hz */
+               tc->tc_frequency = 1000000000000000ULL / reg;
+
+               tc->tc_name = sc->sc_dev.dv_xname;
+               tc->tc_quality = 1000;
+               tc->tc_priv = sc;
+               tc_init(tc);
+
+               /* Enable counting */
+               bus_space_write_4(sc->sc_hpet_iot, sc->sc_hpet_ioh,
+                   E600_HPET_GC, E600_HPET_GC_ENABLE);
+
+               sc->sc_active |= E600_HPET_ACTIVE;
+
+               printf(": %llu Hz timer", tc->tc_frequency);
+       }
+
        /* Map Watchdog I/O space */
        reg = pci_conf_read(pa->pa_pc, pa->pa_tag, E600_LPC_WDTBA);
        wdtbase = reg & 0xffff;
@@ -169,10 +224,11 @@
                if (PCI_MAPREG_IO_ADDR(wdtbase) == 0 ||
                    bus_space_map(sc->sc_wdt_iot, PCI_MAPREG_IO_ADDR(wdtbase),
                    E600_WDT_SIZE, 0, &sc->sc_wdt_ioh)) {
-                       printf(": can't map watchdog I/O space");
+                       printf("%c can't map watchdog I/O space",
+                           sc->sc_active ? ',' : ':');
                        goto corepcib;
                }
-               printf(": watchdog");
+               printf("%c watchdog", sc->sc_active ? ',' : ':');
 
                /* Check for reboot on timeout */
                reg = bus_space_read_1(sc->sc_wdt_iot, sc->sc_wdt_ioh,
@@ -232,6 +288,9 @@
                        } else
                                tcpcib_wdt_stop(sc);
                }
+               if (sc->sc_active & E600_HPET_ACTIVE)
+                       bus_space_write_4(sc->sc_hpet_iot, sc->sc_hpet_ioh,
+                           E600_HPET_GC, E600_HPET_GC_ENABLE);
                break;
        }
        return (0);
@@ -263,4 +322,14 @@
        sc->sc_wdt_period = period;
 
        return (period);
+}
+
+u_int
+tcpcib_hpet_get_timecount(struct timecounter *tc)
+{
+       struct tcpcib_softc *sc = tc->tc_priv;
+
+       /* XXX 64-bit counter is not supported! */
+       return bus_space_read_4(sc->sc_hpet_iot, sc->sc_hpet_ioh,
+           E600_HPET_MCV);
 }
--- share/man/man4/man4.i386/tcpcib.4.orig      Wed May 30 12:38:14 2012
+++ share/man/man4/man4.i386/tcpcib.4   Wed May 30 16:23:42 2012
@@ -19,7 +19,7 @@
 .Os
 .Sh NAME
 .Nm tcpcib
-.Nd Intel Atom E600 series LPC bridge and watchdog timer
+.Nd Intel Atom E600 series LPC bridge, timecounter and watchdog timer
 .Sh SYNOPSIS
 .Cd "tcpcib* at pci?"
 .Cd "isa* at tcpcib?"
@@ -27,7 +27,11 @@
 The
 .Nm
 driver provides support for the Intel Atom E600 series LPC bridge and
-provides the standard
+implements a 64-bit 14.3 MHz timecounter using the HPET timer.
+.Pp
+The
+.Nm
+driver also provides the standard
 .Xr watchdog 4
 interface to the watchdog timer and may be used with
 .Xr watchdogd 8 .
@@ -60,6 +64,6 @@
 .Sh BUGS
 Apart from the core
 .Xr pcib 4
-functionality and the
+functionality, timecounter and the
 .Xr watchdog 4
 interface, the driver doesn't support any other aspects of the hardware.
--- share/man/man4/man4.amd64/tcpcib.4.orig     Wed May 30 12:55:24 2012
+++ share/man/man4/man4.amd64/tcpcib.4  Wed May 30 16:23:34 2012
@@ -19,7 +19,7 @@
 .Os
 .Sh NAME
 .Nm tcpcib
-.Nd Intel Atom E600 series LPC bridge and watchdog timer
+.Nd Intel Atom E600 series LPC bridge, timecounter and watchdog timer
 .Sh SYNOPSIS
 .Cd "tcpcib* at pci?"
 .Cd "isa* at tcpcib?"
@@ -27,7 +27,11 @@
 The
 .Nm
 driver provides support for the Intel Atom E600 series LPC bridge and
-provides the standard
+implements a 64-bit 14.3 MHz timecounter using the HPET timer.
+.Pp
+The
+.Nm
+driver also provides the standard
 .Xr watchdog 4
 interface to the watchdog timer and may be used with
 .Xr watchdogd 8 .
@@ -60,6 +64,6 @@
 .Sh BUGS
 Apart from the core
 .Xr pcib 4
-functionality and the
+functionality, timecounter and the
 .Xr watchdog 4
 interface, the driver doesn't support any other aspects of the hardware.

Reply via email to