diff --git a/sys/dev/pci/amdpm.c b/sys/dev/pci/amdpm.c index 01b5b4aaf121..0b43fc1a416a 100644 --- a/sys/dev/pci/amdpm.c +++ b/sys/dev/pci/amdpm.c @@ -1,4 +1,4 @@ -/* $NetBSD: amdpm.c,v 1.11 2006/02/19 02:24:20 tls Exp $ */ +/* $NetBSD: amdpm.c,v 1.12 2006/06/17 15:05:15 xtraeme Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: amdpm.c,v 1.11 2006/02/19 02:24:20 tls Exp $"); +__KERNEL_RCSID(0, "$NetBSD: amdpm.c,v 1.12 2006/06/17 15:05:15 xtraeme Exp $"); #include "opt_amdpm.h" @@ -48,6 +48,11 @@ __KERNEL_RCSID(0, "$NetBSD: amdpm.c,v 1.11 2006/02/19 02:24:20 tls Exp $"); #include #include +#ifdef __HAVE_TIMECOUNTER +#include +#include +#endif + #include #include @@ -60,6 +65,23 @@ __KERNEL_RCSID(0, "$NetBSD: amdpm.c,v 1.11 2006/02/19 02:24:20 tls Exp $"); static void amdpm_rnd_callout(void *); +#ifdef __HAVE_TIMECOUNTER +uint32_t amdpm_get_timecount(struct timecounter *); + +#ifndef AMDPM_FREQUENCY +#define AMDPM_FREQUENCY 3579545 +#endif + +static struct timecounter amdpm_timecounter = { + amdpm_get_timecount, + 0, + 0xffffff, + AMDPM_FREQUENCY, + "amdpm", + 1000 +}; +#endif + #ifdef AMDPM_RND_COUNTERS #define AMDPM_RNDCNT_INCR(ev) (ev)->ev_count++ #else @@ -128,6 +150,19 @@ amdpm_attach(struct device *parent, struct device *self, void *aux) return; } +#ifdef __HAVE_TIMECOUNTER + if ((reg & AMDPM_TMRRST) == 0 && (reg & AMDPM_STOPTMR) == 0 && + PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_PBC768_PMC) { + aprint_normal(": %d-bit timer at %" PRIu64 "Hz", + (reg & AMDPM_TMR32) ? 32 : 24, + amdpm_timecounter.tc_frequency); + + if (reg & AMDPM_TMR32) + amdpm_timecounter.tc_counter_mask = 0xffffffffu; + tc_init(&amdpm_timecounter); + } +#endif + /* try to attach devices on the smbus */ if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_PBC8111_ACPI) { amdpm_smbus_attach(sc); @@ -208,3 +243,13 @@ amdpm_rnd_callout(void *v) AMDPM_RNDCNT_INCR(&sc->sc_rnd_miss); callout_reset(&sc->sc_rnd_ch, 1, amdpm_rnd_callout, sc); } + +#ifdef __HAVE_TIMECOUNTER +uint32_t +amdpm_get_timecount(struct timecounter *tc) +{ + struct amdpm_softc *sc = tc->tc_priv; + + return bus_space_read_4(sc->sc_iot, sc->sc_ioh, AMDPM_TMR); +} +#endif diff --git a/sys/dev/pci/amdpmreg.h b/sys/dev/pci/amdpmreg.h index e71b25bb7099..aba97517c28c 100644 --- a/sys/dev/pci/amdpmreg.h +++ b/sys/dev/pci/amdpmreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: amdpmreg.h,v 1.1 2002/06/02 02:44:28 enami Exp $ */ +/* $NetBSD: amdpmreg.h,v 1.2 2006/06/17 15:05:15 xtraeme Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -40,9 +40,12 @@ /* 0x40: General Configuration 1 Register */ #define AMDPM_RNGEN 0x00000080 /* random number generator enable */ +#define AMDPM_STOPTMR 0x00000040 /* stop free-running timer */ /* 0x41: General Configuration 2 Register */ #define AMDPM_PMIOEN 0x00008000 /* system management IO space enable */ +#define AMDPM_TMRRST 0x00004000 /* reset free-running timer */ +#define AMDPM_TMR32 0x00000800 /* extended (32 bit) timer enable */ /* 0x42: SCI Interrupt Configuration Register */ /* 0x43: Previous Power State Register */ @@ -53,6 +56,8 @@ #define AMDPM_PMSIZE 256 /* PMxx space size */ /* Registers in PMxx space */ +#define AMDPM_TMR 0x08 /* 24/32 bit timer register */ + #define AMDPM_RNGDATA 0xf0 /* 32 bit random data register */ #define AMDPM_RNGSTAT 0xf4 /* RNG status register */ #define AMDPM_RNGDONE 0x00000001 /* Random number generation complete */