Support for the 24/32bit timer in the AMD 768 Power Management

Controller, to try it use `sysctl -w kern.timecounter.hardware=amdpm`.

From OpenBSD.
This commit is contained in:
xtraeme 2006-06-17 15:05:15 +00:00
parent 62496a150d
commit be705fc9c7
2 changed files with 53 additions and 3 deletions

View File

@ -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 <sys/cdefs.h>
__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 <sys/callout.h>
#include <sys/rnd.h>
#ifdef __HAVE_TIMECOUNTER
#include <sys/timetc.h>
#include <machine/bus.h>
#endif
#include <dev/i2c/i2cvar.h>
#include <dev/pci/pcivar.h>
@ -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

View File

@ -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 */