Subject: Re: VIA VT82C686A and VT8231 testers wanted
To: Juan RP <juan@xtrarom.org>
From: Nicolas Joly <njoly@pasteur.fr>
List: netbsd-users
Date: 01/14/2007 23:10:29
--Qxx1br4bt0+wmkIi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On Sun, Jan 14, 2007 at 12:22:19AM +0100, Juan RP wrote:
> On Sat, 13 Jan 2007 23:43:16 +0100
> Nicolas Joly <njoly@pasteur.fr> wrote:
>
> > I just tested it on a HP Pavillion 7825, which has a VIA VT86C686A
> > chipset; and i can report that it works (dmesg attached).
> >
> > In the mean time, i noted a few things:
> >
> > 1) dmesg output can be improved (by removing some extra newlines).
> >
> > [...]
> > uhub1: 2 ports with 2 removable, self powered
> > viaenv0 at pci0 dev 7 function 4
> > : VIA VT82C686A Hardware Monitor
> > timecounter: Timecounter "viaenv0" frequency 3579545 Hz quality 1000
> > viaenv0 24-bit timer
> >
> > auvia0 at pci0 dev 7 function 5: VIA Technologies VT82C686A AC'97
> > Audio (rev H) [...]
>
> Fixed.
Unfortunately, the empty line remains. Here is a slightly modified
version of your patch i currently use.
I prefer to systematically print the chipset/function description, and
eventually add some extra messages when things goes wrong.
--
Nicolas Joly
Biological Software and Databanks.
Institut Pasteur, Paris.
--Qxx1br4bt0+wmkIi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="netbsd-viaenv.diff"
Index: sys/dev/pci/files.pci
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/files.pci,v
retrieving revision 1.275
diff -u -r1.275 files.pci
--- sys/dev/pci/files.pci 17 Dec 2006 23:02:06 -0000 1.275
+++ sys/dev/pci/files.pci 14 Jan 2007 21:49:46 -0000
@@ -660,15 +660,10 @@
attach btvmeii at pci
file dev/pci/btvmeii.c btvmeii
-# VT86C686A power management
-device viapm {}
-attach viapm at pci
-file dev/pci/viapm.c viapm
-
-# hardware monitoring part of viapm
-device viaenv: sysmon_envsys
-attach viaenv at viapm
-file dev/pci/viaenv.c viaenv needs-flag
+# VIA VT82C686A/VT8231 PM Timer and Hardware Monitor
+device viaenv: acpipmtimer, sysmon_envsys
+attach viaenv at pci
+file dev/pci/viaenv.c viaenv
# Intel PIIX4 power management controller
device piixpm: i2cbus, acpipmtimer
Index: sys/dev/pci/viaenv.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/viaenv.c,v
retrieving revision 1.17
diff -u -r1.17 viaenv.c
--- sys/dev/pci/viaenv.c 16 Nov 2006 01:33:10 -0000 1.17
+++ sys/dev/pci/viaenv.c 14 Jan 2007 21:49:48 -0000
@@ -32,7 +32,10 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-/* driver for the hardware monitoring part of the VIA VT82C686A */
+/*
+ * Driver for the hardware monitoring and power management timer
+ * in the VIA VT82C686A and VT8231 South Bridges.
+ */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: viaenv.c,v 1.17 2006/11/16 01:33:10 christos Exp $");
@@ -40,22 +43,22 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
-#include <sys/ioctl.h>
-#include <sys/kthread.h>
-#include <sys/lock.h>
-#include <sys/errno.h>
#include <sys/device.h>
+#ifdef __HAVE_TIMECOUNTER
+#include <machine/bus.h>
+#include <dev/ic/acpipmtimer.h>
+#endif
+
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
-
-#include <dev/pci/viapmvar.h>
+#include <dev/pci/pcidevs.h>
#include <dev/sysmon/sysmonvar.h>
#ifdef VIAENV_DEBUG
unsigned int viaenv_debug = 0;
-#define DPRINTF(X) do { if(viaenv_debug) printf X ; } while(0)
+#define DPRINTF(X) do { if (viaenv_debug) printf X ; } while(0)
#else
#define DPRINTF(X)
#endif
@@ -66,11 +69,12 @@
struct device sc_dev;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
+ bus_space_handle_t sc_pm_ioh;
int sc_fan_div[2]; /* fan RPM divisor */
- struct envsys_tre_data sc_data[VIANUMSENSORS];
- struct envsys_basic_info sc_info[VIANUMSENSORS];
+ envsys_tre_data_t sc_data[VIANUMSENSORS];
+ envsys_basic_info_t sc_info[VIANUMSENSORS];
struct simplelock sc_slock;
struct timeval sc_lastread;
@@ -88,20 +92,36 @@
{ 1, 0, ENVSYS_SAMPS }, /* none */
};
-static int viaenv_gtredata(struct sysmon_envsys *,
- struct envsys_tre_data *);
-static int viaenv_streinfo(struct sysmon_envsys *,
- struct envsys_basic_info *);
+/* autoconf(9) glue */
+static int viaenv_match(struct device *, struct cfdata *, void *);
+static void viaenv_attach(struct device *, struct device *, void *);
+
+CFATTACH_DECL(viaenv, sizeof(struct viaenv_softc),
+ viaenv_match, viaenv_attach, NULL, NULL);
+
+/* envsys(4) glue */
+static int viaenv_gtredata(struct sysmon_envsys *, envsys_tre_data_t *);
+static int viaenv_streinfo(struct sysmon_envsys *, envsys_basic_info_t *);
+
+static int val_to_uK(unsigned int);
+static int val_to_rpm(unsigned int, int);
+static long val_to_uV(unsigned int, int);
static int
-viaenv_match(struct device *parent, struct cfdata *match,
- void *aux)
+viaenv_match(struct device *parent, struct cfdata *match, void *aux)
{
- struct viapm_attach_args *va = aux;
+ struct pci_attach_args *pa = (struct pci_attach_args *)aux;
- if (va->va_type == VIAPM_HWMON)
+ if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_VIATECH)
+ return 0;
+
+ switch (PCI_PRODUCT(pa->pa_id)) {
+ case PCI_PRODUCT_VIATECH_VT82C686A_SMB:
+ case PCI_PRODUCT_VIATECH_VT8231_PWR:
return 1;
- return 0;
+ default:
+ return 0;
+ }
}
/*
@@ -198,13 +218,21 @@
#define VIAENV_TLOW 0x49 /* temperature low order value */
#define VIAENV_TIRQ 0x4b /* temperature interrupt configuration */
+#define VIAENV_GENCFG 0x40 /* general configuration */
+#define VIAENV_GENCFG_TMR32 (1 << 11) /* 32-bit PM timer */
+#define VIAENV_GENCFG_PMEN (1 << 15) /* enable PM I/O space */
+#define VIAENV_PMBASE 0x48 /* power management I/O space base */
+#define VIAENV_PMSIZE 128 /* HWM and power management I/O space size */
+#define VIAENV_PM_TMR 0x08 /* PM timer */
+#define VIAENV_HWMON_CONF 0x70 /* HWMon I/O base */
+#define VIAENV_HWMON_CTL 0x74 /* HWMon control register */
static void
viaenv_refresh_sensor_data(struct viaenv_softc *sc)
{
static const struct timeval onepointfive = { 1, 500000 };
struct timeval t, utv;
- u_int8_t v, v2;
+ uint8_t v, v2;
int i;
/* Read new values at most once every 1.5 seconds. */
@@ -267,30 +295,44 @@
static void
viaenv_attach(struct device *parent, struct device *self, void *aux)
{
- struct viapm_attach_args *va = aux;
- struct viaenv_softc *sc = (struct viaenv_softc *) self;
+ struct viaenv_softc *sc = (struct viaenv_softc *)self;
+ struct pci_attach_args *pa = (struct pci_attach_args *)aux;
pcireg_t iobase, control;
int i;
- iobase = pci_conf_read(va->va_pc, va->va_tag, va->va_offset);
- if ((iobase & 0xff80) == 0) {
- printf(": disabled\n");
- return;
+ aprint_naive("\n");
+ aprint_normal(": VIA Technologies ");
+ switch (PCI_PRODUCT(pa->pa_id)) {
+ case PCI_PRODUCT_VIATECH_VT82C686A_SMB:
+ aprint_normal("VT82C686A Hardware Monitor\n");
+ break;
+ case PCI_PRODUCT_VIATECH_VT8231_PWR:
+ aprint_normal("VT8231 Hardware Monitor\n");
+ break;
+ default:
+ aprint_normal("Unknown Hardware Monitor\n");
+ break;
}
- control = pci_conf_read(va->va_pc, va->va_tag, va->va_offset + 4);
- /* If the device is disabled, turn it on */
- if ((control & 1) == 0)
- pci_conf_write(va->va_pc, va->va_tag, va->va_offset + 4,
- control | 1);
-
- sc->sc_iot = va->va_iot;
- if (bus_space_map(sc->sc_iot, iobase & 0xff80, 128, 0, &sc->sc_ioh)) {
- printf(": failed to map i/o\n");
- return;
+
+ iobase = pci_conf_read(pa->pa_pc, pa->pa_tag, VIAENV_HWMON_CONF);
+ DPRINTF(("%s: iobase 0x%x\n", sc->sc_dev.dv_xname, iobase));
+ control = pci_conf_read(pa->pa_pc, pa->pa_tag, VIAENV_HWMON_CTL);
+
+ /* Check if the Hardware Monitor enable bit is set */
+ if ((control & 1) == 0) {
+ aprint_normal("%s : Hardware Monitor disabled\n",
+ sc->sc_dev.dv_xname);
+ goto nohwm;
}
- printf("\n");
- simple_lock_init(&sc->sc_slock);
+ /* Map Hardware Monitor I/O space */
+ sc->sc_iot = pa->pa_iot;
+ if (bus_space_map(sc->sc_iot, iobase & 0xff80,
+ VIAENV_PMSIZE, 0, &sc->sc_ioh)) {
+ aprint_error("%s: failed to map I/O space\n",
+ sc->sc_dev.dv_xname);
+ goto nohwm;
+ }
/* Initialize sensors */
for (i = 0; i < VIANUMSENSORS; ++i) {
@@ -300,33 +342,38 @@
sc->sc_data[i].warnflags = ENVSYS_WARN_OK;
}
- for (i = 0; i <= 2; i++) {
+ for (i = 0; i <= 2; i++)
sc->sc_data[i].units = sc->sc_info[i].units = ENVSYS_STEMP;
- }
- strcpy(sc->sc_info[0].desc, "TSENS1");
- strcpy(sc->sc_info[1].desc, "TSENS2");
- strcpy(sc->sc_info[2].desc, "TSENS3");
- for (i = 3; i <= 4; i++) {
- sc->sc_data[i].units = sc->sc_info[i].units = ENVSYS_SFANRPM;
- }
- strcpy(sc->sc_info[3].desc, "FAN1");
- strcpy(sc->sc_info[4].desc, "FAN2");
+#define COPYDESCR(x, y) \
+ do { \
+ strlcpy((x), (y), sizeof(x)); \
+ } while (0)
+
+ COPYDESCR(sc->sc_info[0].desc, "TSENS1");
+ COPYDESCR(sc->sc_info[1].desc, "TSENS2");
+ COPYDESCR(sc->sc_info[2].desc, "TSENS3");
- for (i = 5; i <= 9; ++i) {
- sc->sc_data[i].units = sc->sc_info[i].units =
- ENVSYS_SVOLTS_DC;
- sc->sc_info[i].rfact = 1; /* what is this used for? */
- }
- strcpy(sc->sc_info[5].desc, "VSENS1"); /* CPU core (2V) */
- strcpy(sc->sc_info[6].desc, "VSENS2"); /* NB core? (2.5V) */
- strcpy(sc->sc_info[7].desc, "Vcore"); /* Vcore (3.3V) */
- strcpy(sc->sc_info[8].desc, "VSENS3"); /* VSENS3 (5V) */
- strcpy(sc->sc_info[9].desc, "VSENS4"); /* VSENS4 (12V) */
+ for (i = 3; i <= 4; i++)
+ sc->sc_data[i].units = sc->sc_info[i].units = ENVSYS_SFANRPM;
+
+ COPYDESCR(sc->sc_info[3].desc, "FAN1");
+ COPYDESCR(sc->sc_info[4].desc, "FAN2");
+
+ for (i = 5; i <= 9; ++i)
+ sc->sc_data[i].units = sc->sc_info[i].units = ENVSYS_SVOLTS_DC;
+
+ COPYDESCR(sc->sc_info[5].desc, "VSENS1"); /* CPU core (2V) */
+ COPYDESCR(sc->sc_info[6].desc, "VSENS2"); /* NB core? (2.5V) */
+ COPYDESCR(sc->sc_info[7].desc, "Vcore"); /* Vcore (3.3V) */
+ COPYDESCR(sc->sc_info[8].desc, "VSENS3"); /* VSENS3 (5V) */
+ COPYDESCR(sc->sc_info[9].desc, "VSENS4"); /* VSENS4 (12V) */
/* Get initial set of sensor values. */
viaenv_refresh_sensor_data(sc);
+#undef COPYDESCR
+
/*
* Hook into the System Monitor.
*/
@@ -344,13 +391,39 @@
if (sysmon_envsys_register(&sc->sc_sysmon))
printf("%s: unable to register with sysmon\n",
sc->sc_dev.dv_xname);
-}
-CFATTACH_DECL(viaenv, sizeof(struct viaenv_softc),
- viaenv_match, viaenv_attach, NULL, NULL);
+nohwm:
+#ifdef __HAVE_TIMECOUNTER
+ /* Check if power management I/O space is enabled */
+ control = pci_conf_read(pa->pa_pc, pa->pa_tag, VIAENV_GENCFG);
+ if ((control & VIAENV_GENCFG_PMEN) == 0) {
+ aprint_normal("%s: Power Managament controller disabled\n",
+ sc->sc_dev.dv_xname);
+ goto nopm;
+ }
+
+ /* Map power management I/O space */
+ iobase = pci_conf_read(pa->pa_pc, pa->pa_tag, VIAENV_PMBASE);
+ if (bus_space_map(sc->sc_iot, PCI_MAPREG_IO_ADDR(iobase),
+ VIAENV_PMSIZE, 0, &sc->sc_pm_ioh)) {
+ aprint_error("%s: failed to map PM I/O space\n",
+ sc->sc_dev.dv_xname);
+ goto nopm;
+ }
+
+ /* Attach our PM timer with the generic acpipmtimer function */
+ acpipmtimer_attach(&sc->sc_dev, sc->sc_iot, sc->sc_pm_ioh,
+ VIAENV_PM_TMR,
+ ((control & VIAENV_GENCFG_TMR32) ? ACPIPMT_32BIT : 0));
+
+nopm:
+#endif /* __HAVE_TIMECOUNTER */
+ /*XXX Avoid label at end of compound */
+ return;
+}
static int
-viaenv_gtredata(struct sysmon_envsys *sme, struct envsys_tre_data *tred)
+viaenv_gtredata(struct sysmon_envsys *sme, envsys_tre_data_t *tred)
{
struct viaenv_softc *sc = sme->sme_cookie;
@@ -361,16 +434,14 @@
simple_unlock(&sc->sc_slock);
- return (0);
+ return 0;
}
static int
-viaenv_streinfo(struct sysmon_envsys *sme,
- struct envsys_basic_info *binfo)
+viaenv_streinfo(struct sysmon_envsys *sme, envsys_basic_info_t *binfo)
{
-
- /* XXX Not implemented */
+ /* Not implemented */
binfo->validflags = 0;
- return (0);
+ return 0;
}
--Qxx1br4bt0+wmkIi--