> Date: Mon, 4 Jun 2012 09:26:13 -0400
> From: Matt Dainty <[email protected]>
> 
> * 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.

Thanks,

I committed this now, with one small change, increasing the quality of
the timecounter to 2000.  The amdpcib(4) driver does that as well, and
it makes sense to trust real hardware a bit more than the acpi based
timecounter.  Even though the HPET probably won't attach because
acpihpet(4) already stole the device.

Thanks again,

Mark

> --- 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