Thu Mar 8 17:38:03 2012 UTC ()
Pull up following revision(s) (requested by nonaka):
	share/man/man4/amdtemp.4: revision 1.6
	share/man/man4/amdtemp.4: revision 1.7
	sys/arch/x86/pci/amdtemp.c: revision 1.13
Added Family 12h support.
Mention AMD Fusion.
Bump date for previous.


(riz)
diff -r1.5 -r1.5.4.1 src/share/man/man4/amdtemp.4
diff -r1.12 -r1.12.8.1 src/sys/arch/x86/pci/amdtemp.c

cvs diff -r1.5 -r1.5.4.1 src/share/man/man4/amdtemp.4 (switch to unified diff)

--- src/share/man/man4/amdtemp.4 2011/08/18 20:55:21 1.5
+++ src/share/man/man4/amdtemp.4 2012/03/08 17:38:03 1.5.4.1
@@ -1,86 +1,86 @@ @@ -1,86 +1,86 @@
1.\" $NetBSD: amdtemp.4,v 1.5 2011/08/18 20:55:21 jakllsch Exp $ 1.\" $NetBSD: amdtemp.4,v 1.5.4.1 2012/03/08 17:38:03 riz Exp $
2.\"- 2.\"-
3.\" Copyright (c) 2008 Christoph Egger 3.\" Copyright (c) 2008 Christoph Egger
4.\" All rights reserved. 4.\" All rights reserved.
5.\" 5.\"
6.\" Redistribution and use in source and binary forms, with or without 6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions 7.\" modification, are permitted provided that the following conditions
8.\" are met: 8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright 9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer. 10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 14.\"
15.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25.\" SUCH DAMAGE. 25.\" SUCH DAMAGE.
26.\" 26.\"
27.\" $FreeBSD: src/share/man/man4/coretemp.4,v 1.4 2007/10/15 20:00:19 netchild Exp $ 27.\" $FreeBSD: src/share/man/man4/coretemp.4,v 1.4 2007/10/15 20:00:19 netchild Exp $
28.\" 28.\"
29.Dd August 18, 2011 29.Dd March 2, 2012
30.Dt AMDTEMP 4 30.Dt AMDTEMP 4
31.Os 31.Os
32.Sh NAME 32.Sh NAME
33.Nm amdtemp 33.Nm amdtemp
34.Nd AMD CPU on-die digital thermal sensor 34.Nd AMD CPU on-die digital thermal sensor
35.Sh SYNOPSIS 35.Sh SYNOPSIS
36.Cd "amdtemp* at pchb?" 36.Cd "amdtemp* at pchb?"
37.Sh DESCRIPTION 37.Sh DESCRIPTION
38The 38The
39.Nm 39.Nm
40driver provides support for the on-die digital thermal sensor present 40driver provides support for the on-die digital thermal sensor present
41on AMD K8, AMD Barcelona, AMD Phenoms, and AMD Griffin CPUs. 41on AMD K8, AMD Barcelona, AMD Phenom, AMD Griffin, and AMD Fusion CPUs.
42.Pp 42.Pp
43These sensors were officially introduced in AMD K8 Revision F processors, 43These sensors were officially introduced in AMD K8 Revision F processors,
44and provide 0.5 degC accuracy. 44and provide 0.5 degC accuracy.
45Precision was improved in Revision 45Precision was improved in Revision
46G chips, which provide two more bits for 0.25 degC steppings. 46G chips, which provide two more bits for 0.25 degC steppings.
47Each core 47Each core
48has two temperature sensors, and there are up to two cores per CPU socket. 48has two temperature sensors, and there are up to two cores per CPU socket.
49.Pp 49.Pp
50AMD Barcelona, AMD Phenom, and AMD Griffin provide 0.125 degC accuracy 50AMD Barcelona, AMD Phenom, AMD Griffin, and AMD Fusion provide 0.125 degC
51and provide one temperature sensor for each CPU socket. 51accuracy and provide one temperature sensor for each CPU socket.
52.Pp 52.Pp
53The 53The
54.Nm 54.Nm
55driver reports temperatures through the 55driver reports temperatures through the
56.Xr envsys 4 56.Xr envsys 4
57API. 57API.
58.Bl -column "Sensor " "Units" "Typical" -offset indent 58.Bl -column "Sensor " "Units" "Typical" -offset indent
59.It Sy "Sensor " Ta Sy "Units" Ta Sy "Typical Use" 59.It Sy "Sensor " Ta Sy "Units" Ta Sy "Typical Use"
60.It Li "CPUN sensor0" Ta "uK" Ta "cpuN temperature" 60.It Li "CPUN sensor0" Ta "uK" Ta "cpuN temperature"
61.El 61.El
62.Sh SEE ALSO 62.Sh SEE ALSO
63.Xr envsys 4 , 63.Xr envsys 4 ,
64.Xr envstat 8 , 64.Xr envstat 8 ,
65.Xr powerd 8 65.Xr powerd 8
66.Sh HISTORY 66.Sh HISTORY
67The 67The
68.Nm 68.Nm
69driver first appeared in 69driver first appeared in
70.Ox 4.4 70.Ox 4.4
71named 71named
72.Dq kate . 72.Dq kate .
73It was then ported to 73It was then ported to
74.Nx 5.0 . 74.Nx 5.0 .
75The driver has been renamed with support for newer AMD CPUs. 75The driver has been renamed with support for newer AMD CPUs.
76.Sh AUTHORS 76.Sh AUTHORS
77.An -nosplit 77.An -nosplit
78The 78The
79.Nm 79.Nm
80driver was written by 80driver was written by
81.An Constantine A. Murenin Aq cnst@openbsd.org 81.An Constantine A. Murenin Aq cnst@openbsd.org
82whilst at the University of Waterloo. 82whilst at the University of Waterloo.
83It was adapted to 83It was adapted to
84.Nx 84.Nx
85by 85by
86.An Christoph Egger . 86.An Christoph Egger .

cvs diff -r1.12 -r1.12.8.1 src/sys/arch/x86/pci/amdtemp.c (switch to unified diff)

--- src/sys/arch/x86/pci/amdtemp.c 2011/07/31 22:04:07 1.12
+++ src/sys/arch/x86/pci/amdtemp.c 2012/03/08 17:38:03 1.12.8.1
@@ -1,554 +1,557 @@ @@ -1,554 +1,557 @@
1/* $NetBSD: amdtemp.c,v 1.12 2011/07/31 22:04:07 jmcneill Exp $ */ 1/* $NetBSD: amdtemp.c,v 1.12.8.1 2012/03/08 17:38:03 riz Exp $ */
2/* $OpenBSD: kate.c,v 1.2 2008/03/27 04:52:03 cnst Exp $ */ 2/* $OpenBSD: kate.c,v 1.2 2008/03/27 04:52:03 cnst Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 * Copyright (c) 2008 The NetBSD Foundation, Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Christoph Egger. 9 * by Christoph Egger.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * Copyright (c) 2008 Constantine A. Murenin <cnst+openbsd@bugmail.mojo.ru> 34 * Copyright (c) 2008 Constantine A. Murenin <cnst+openbsd@bugmail.mojo.ru>
35 * 35 *
36 * Permission to use, copy, modify, and distribute this software for any 36 * Permission to use, copy, modify, and distribute this software for any
37 * purpose with or without fee is hereby granted, provided that the above 37 * purpose with or without fee is hereby granted, provided that the above
38 * copyright notice and this permission notice appear in all copies. 38 * copyright notice and this permission notice appear in all copies.
39 * 39 *
40 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 40 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
41 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 41 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
42 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 42 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
43 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 43 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
44 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 44 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
45 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 45 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
46 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 46 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
47 */ 47 */
48 48
49 49
50#include <sys/cdefs.h> 50#include <sys/cdefs.h>
51__KERNEL_RCSID(0, "$NetBSD: amdtemp.c,v 1.12 2011/07/31 22:04:07 jmcneill Exp $ "); 51__KERNEL_RCSID(0, "$NetBSD: amdtemp.c,v 1.12.8.1 2012/03/08 17:38:03 riz Exp $ ");
52 52
53#include <sys/param.h> 53#include <sys/param.h>
54#include <sys/bus.h> 54#include <sys/bus.h>
55#include <sys/cpu.h> 55#include <sys/cpu.h>
56#include <sys/systm.h> 56#include <sys/systm.h>
57#include <sys/device.h> 57#include <sys/device.h>
58#include <sys/kmem.h> 58#include <sys/kmem.h>
59#include <sys/module.h> 59#include <sys/module.h>
60 60
61#include <machine/specialreg.h> 61#include <machine/specialreg.h>
62 62
63#include <dev/pci/pcireg.h> 63#include <dev/pci/pcireg.h>
64#include <dev/pci/pcivar.h> 64#include <dev/pci/pcivar.h>
65#include <dev/pci/pcidevs.h> 65#include <dev/pci/pcidevs.h>
66 66
67#include <dev/sysmon/sysmonvar.h> 67#include <dev/sysmon/sysmonvar.h>
68 68
69/* 69/*
70 * AMD K8: 70 * AMD K8:
71 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf 71 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf
72 * AMD K8 Errata: #141 72 * AMD K8 Errata: #141
73 * http://support.amd.com/us/Processor_TechDocs/33610_PUB_Rev3%2042v3.pdf 73 * http://support.amd.com/us/Processor_TechDocs/33610_PUB_Rev3%2042v3.pdf
74 * 74 *
75 * Family10h: 75 * Family10h:
76 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/31116.PDF 76 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/31116.PDF
77 * Family10h Errata: #319 77 * Family10h Errata: #319
78 * http://support.amd.com/de/Processor_TechDocs/41322.pdf 78 * http://support.amd.com/de/Processor_TechDocs/41322.pdf
79 * 79 *
80 * Family11h: 80 * Family11h:
81 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/41256.pdf 81 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/41256.pdf
82 */ 82 */
83 83
84/* AMD Processors, Function 3 -- Miscellaneous Control 84/* AMD Processors, Function 3 -- Miscellaneous Control
85 */ 85 */
86 86
87/* Function 3 Registers */ 87/* Function 3 Registers */
88#define THERMTRIP_STAT_R 0xe4 88#define THERMTRIP_STAT_R 0xe4
89#define NORTHBRIDGE_CAP_R 0xe8 89#define NORTHBRIDGE_CAP_R 0xe8
90#define CPUID_FAMILY_MODEL_R 0xfc 90#define CPUID_FAMILY_MODEL_R 0xfc
91 91
92/* 92/*
93 * AMD NPT Family 0Fh Processors, Function 3 -- Miscellaneous Control 93 * AMD NPT Family 0Fh Processors, Function 3 -- Miscellaneous Control
94 */ 94 */
95 95
96/* Bits within Thermtrip Status Register */ 96/* Bits within Thermtrip Status Register */
97#define K8_THERM_SENSE_SEL (1 << 6) 97#define K8_THERM_SENSE_SEL (1 << 6)
98#define K8_THERM_SENSE_CORE_SEL (1 << 2) 98#define K8_THERM_SENSE_CORE_SEL (1 << 2)
99 99
100/* Flip core and sensor selection bits */ 100/* Flip core and sensor selection bits */
101#define K8_T_SEL_C0(v) (v |= K8_THERM_SENSE_CORE_SEL) 101#define K8_T_SEL_C0(v) (v |= K8_THERM_SENSE_CORE_SEL)
102#define K8_T_SEL_C1(v) (v &= ~(K8_THERM_SENSE_CORE_SEL)) 102#define K8_T_SEL_C1(v) (v &= ~(K8_THERM_SENSE_CORE_SEL))
103#define K8_T_SEL_S0(v) (v &= ~(K8_THERM_SENSE_SEL)) 103#define K8_T_SEL_S0(v) (v &= ~(K8_THERM_SENSE_SEL))
104#define K8_T_SEL_S1(v) (v |= K8_THERM_SENSE_SEL) 104#define K8_T_SEL_S1(v) (v |= K8_THERM_SENSE_SEL)
105 105
106 106
107 107
108/* 108/*
109 * AMD Family 10h Processors, Function 3 -- Miscellaneous Control 109 * AMD Family 10h Processors, Function 3 -- Miscellaneous Control
110 */ 110 */
111 111
112/* Function 3 Registers */ 112/* Function 3 Registers */
113#define F10_TEMPERATURE_CTL_R 0xa4 113#define F10_TEMPERATURE_CTL_R 0xa4
114 114
115/* Bits within Reported Temperature Control Register */ 115/* Bits within Reported Temperature Control Register */
116#define F10_TEMP_CURTEMP (1 << 21) 116#define F10_TEMP_CURTEMP (1 << 21)
117 117
118/* 118/*
119 * Revision Guide for AMD NPT Family 0Fh Processors, 119 * Revision Guide for AMD NPT Family 0Fh Processors,
120 * Publication # 33610, Revision 3.30, February 2008 120 * Publication # 33610, Revision 3.30, February 2008
121 */ 121 */
122#define K8_SOCKET_F 1 /* Server */ 122#define K8_SOCKET_F 1 /* Server */
123#define K8_SOCKET_AM2 2 /* Desktop */ 123#define K8_SOCKET_AM2 2 /* Desktop */
124#define K8_SOCKET_S1 3 /* Laptop */ 124#define K8_SOCKET_S1 3 /* Laptop */
125 125
126static const struct { 126static const struct {
127 const char rev[5]; 127 const char rev[5];
128 const struct { 128 const struct {
129 const pcireg_t cpuid; 129 const pcireg_t cpuid;
130 const uint8_t socket; 130 const uint8_t socket;
131 } cpu[5]; 131 } cpu[5];
132} amdtemp_core[] = { 132} amdtemp_core[] = {
133 { "BH-F", { { 0x00040FB0, K8_SOCKET_AM2 }, /* F2 */ 133 { "BH-F", { { 0x00040FB0, K8_SOCKET_AM2 }, /* F2 */
134 { 0x00040F80, K8_SOCKET_S1 }, /* F2 */ 134 { 0x00040F80, K8_SOCKET_S1 }, /* F2 */
135 { 0, 0 }, { 0, 0 }, { 0, 0 } } }, 135 { 0, 0 }, { 0, 0 }, { 0, 0 } } },
136 { "DH-F", { { 0x00040FF0, K8_SOCKET_AM2 }, /* F2 */ 136 { "DH-F", { { 0x00040FF0, K8_SOCKET_AM2 }, /* F2 */
137 { 0x00040FC0, K8_SOCKET_S1 }, /* F2 */ 137 { 0x00040FC0, K8_SOCKET_S1 }, /* F2 */
138 { 0x00050FF0, K8_SOCKET_AM2 }, /* F2, F3 */ 138 { 0x00050FF0, K8_SOCKET_AM2 }, /* F2, F3 */
139 { 0, 0 }, { 0, 0 } } }, 139 { 0, 0 }, { 0, 0 } } },
140 { "JH-F", { { 0x00040F10, K8_SOCKET_F }, /* F2, F3 */ 140 { "JH-F", { { 0x00040F10, K8_SOCKET_F }, /* F2, F3 */
141 { 0x00040F30, K8_SOCKET_AM2 }, /* F2, F3 */ 141 { 0x00040F30, K8_SOCKET_AM2 }, /* F2, F3 */
142 { 0x000C0F10, K8_SOCKET_F }, /* F3 */ 142 { 0x000C0F10, K8_SOCKET_F }, /* F3 */
143 { 0, 0 }, { 0, 0 } } }, 143 { 0, 0 }, { 0, 0 } } },
144 { "BH-G", { { 0x00060FB0, K8_SOCKET_AM2 }, /* G1, G2 */ 144 { "BH-G", { { 0x00060FB0, K8_SOCKET_AM2 }, /* G1, G2 */
145 { 0x00060F80, K8_SOCKET_S1 }, /* G1, G2 */ 145 { 0x00060F80, K8_SOCKET_S1 }, /* G1, G2 */
146 { 0, 0 }, { 0, 0 }, { 0, 0 } } }, 146 { 0, 0 }, { 0, 0 }, { 0, 0 } } },
147 { "DH-G", { { 0x00060FF0, K8_SOCKET_AM2 }, /* G1, G2 */ 147 { "DH-G", { { 0x00060FF0, K8_SOCKET_AM2 }, /* G1, G2 */
148 { 0x00060FC0, K8_SOCKET_S1 }, /* G2 */ 148 { 0x00060FC0, K8_SOCKET_S1 }, /* G2 */
149 { 0x00070FF0, K8_SOCKET_AM2 }, /* G1, G2 */ 149 { 0x00070FF0, K8_SOCKET_AM2 }, /* G1, G2 */
150 { 0x00070FC0, K8_SOCKET_S1 }, /* G2 */ 150 { 0x00070FC0, K8_SOCKET_S1 }, /* G2 */
151 { 0, 0 } } } 151 { 0, 0 } } }
152}; 152};
153 153
154 154
155struct amdtemp_softc { 155struct amdtemp_softc {
156 pci_chipset_tag_t sc_pc; 156 pci_chipset_tag_t sc_pc;
157 pcitag_t sc_pcitag; 157 pcitag_t sc_pcitag;
158 158
159 struct sysmon_envsys *sc_sme; 159 struct sysmon_envsys *sc_sme;
160 envsys_data_t *sc_sensor; 160 envsys_data_t *sc_sensor;
161 size_t sc_sensor_len; 161 size_t sc_sensor_len;
162 162
163 char sc_rev; 163 char sc_rev;
164 int8_t sc_numsensors; 164 int8_t sc_numsensors;
165 uint32_t sc_family; 165 uint32_t sc_family;
166 int32_t sc_adjustment; 166 int32_t sc_adjustment;
167}; 167};
168 168
169 169
170static int amdtemp_match(device_t, cfdata_t, void *); 170static int amdtemp_match(device_t, cfdata_t, void *);
171static void amdtemp_attach(device_t, device_t, void *); 171static void amdtemp_attach(device_t, device_t, void *);
172static int amdtemp_detach(device_t, int); 172static int amdtemp_detach(device_t, int);
173 173
174static void amdtemp_k8_init(struct amdtemp_softc *, pcireg_t); 174static void amdtemp_k8_init(struct amdtemp_softc *, pcireg_t);
175static void amdtemp_k8_setup_sensors(struct amdtemp_softc *, int); 175static void amdtemp_k8_setup_sensors(struct amdtemp_softc *, int);
176static void amdtemp_k8_refresh(struct sysmon_envsys *, envsys_data_t *); 176static void amdtemp_k8_refresh(struct sysmon_envsys *, envsys_data_t *);
177 177
178static void amdtemp_family10_init(struct amdtemp_softc *); 178static void amdtemp_family10_init(struct amdtemp_softc *);
179static void amdtemp_family10_setup_sensors(struct amdtemp_softc *, int); 179static void amdtemp_family10_setup_sensors(struct amdtemp_softc *, int);
180static void amdtemp_family10_refresh(struct sysmon_envsys *, envsys_data_t *); 180static void amdtemp_family10_refresh(struct sysmon_envsys *, envsys_data_t *);
181 181
182CFATTACH_DECL_NEW(amdtemp, sizeof(struct amdtemp_softc), 182CFATTACH_DECL_NEW(amdtemp, sizeof(struct amdtemp_softc),
183 amdtemp_match, amdtemp_attach, amdtemp_detach, NULL); 183 amdtemp_match, amdtemp_attach, amdtemp_detach, NULL);
184 184
185static int 185static int
186amdtemp_match(device_t parent, cfdata_t match, void *aux) 186amdtemp_match(device_t parent, cfdata_t match, void *aux)
187{ 187{
188 struct pci_attach_args *pa = aux; 188 struct pci_attach_args *pa = aux;
189 pcireg_t cpu_signature; 189 pcireg_t cpu_signature;
190 uint32_t family; 190 uint32_t family;
191 191
192 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_AMD) 192 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_AMD)
193 return 0; 193 return 0;
194 194
195 switch (PCI_PRODUCT(pa->pa_id)) { 195 switch (PCI_PRODUCT(pa->pa_id)) {
196 case PCI_PRODUCT_AMD_AMD64_MISC: 196 case PCI_PRODUCT_AMD_AMD64_MISC:
197 case PCI_PRODUCT_AMD_AMD64_F10_MISC: 197 case PCI_PRODUCT_AMD_AMD64_F10_MISC:
198 case PCI_PRODUCT_AMD_AMD64_F11_MISC: 198 case PCI_PRODUCT_AMD_AMD64_F11_MISC:
199 case PCI_PRODUCT_AMD_F14_NB: 199 case PCI_PRODUCT_AMD_F14_NB: /* Family12h too */
200 break; 200 break;
201 default: 201 default:
202 return 0; 202 return 0;
203 } 203 }
204 204
205 cpu_signature = pci_conf_read(pa->pa_pc, 205 cpu_signature = pci_conf_read(pa->pa_pc,
206 pa->pa_tag, CPUID_FAMILY_MODEL_R); 206 pa->pa_tag, CPUID_FAMILY_MODEL_R);
207 207
208 /* This CPUID northbridge register has been introduced 208 /* This CPUID northbridge register has been introduced
209 * in Revision F */ 209 * in Revision F */
210 if (cpu_signature == 0x0) 210 if (cpu_signature == 0x0)
211 return 0; 211 return 0;
212 212
213 family = CPUID2FAMILY(cpu_signature); 213 family = CPUID2FAMILY(cpu_signature);
214 if (family == 0xf) 214 if (family == 0xf)
215 family += CPUID2EXTFAMILY(cpu_signature); 215 family += CPUID2EXTFAMILY(cpu_signature);
216 216
217 /* Errata #319: This has been fixed in Revision C2. */ 217 /* Errata #319: This has been fixed in Revision C2. */
218 if (family == 0x10) { 218 if (family == 0x10) {
219 if (CPUID2MODEL(cpu_signature) < 4) 219 if (CPUID2MODEL(cpu_signature) < 4)
220 return 0; 220 return 0;
221 if (CPUID2MODEL(cpu_signature) == 4 221 if (CPUID2MODEL(cpu_signature) == 4
222 && CPUID2STEPPING(cpu_signature) < 2) 222 && CPUID2STEPPING(cpu_signature) < 2)
223 return 0; 223 return 0;
224 } 224 }
225 225
226 226
227 /* Not yet supported CPUs */ 227 /* Not yet supported CPUs */
228 if (family > 0x14) 228 if (family > 0x14)
229 return 0; 229 return 0;
230 230
231 return 2; /* supercede pchb(4) */ 231 return 2; /* supercede pchb(4) */
232} 232}
233 233
234static void 234static void
235amdtemp_attach(device_t parent, device_t self, void *aux) 235amdtemp_attach(device_t parent, device_t self, void *aux)
236{ 236{
237 struct amdtemp_softc *sc = device_private(self); 237 struct amdtemp_softc *sc = device_private(self);
238 struct pci_attach_args *pa = aux; 238 struct pci_attach_args *pa = aux;
239 pcireg_t cpu_signature; 239 pcireg_t cpu_signature;
240 int error; 240 int error;
241 uint8_t i; 241 uint8_t i;
242 242
243 aprint_naive("\n"); 243 aprint_naive("\n");
244 aprint_normal(": AMD CPU Temperature Sensors"); 244 aprint_normal(": AMD CPU Temperature Sensors");
245 245
246 cpu_signature = pci_conf_read(pa->pa_pc, 246 cpu_signature = pci_conf_read(pa->pa_pc,
247 pa->pa_tag, CPUID_FAMILY_MODEL_R); 247 pa->pa_tag, CPUID_FAMILY_MODEL_R);
248 248
249 /* If we hit this, then match routine is wrong. */ 249 /* If we hit this, then match routine is wrong. */
250 KASSERT(cpu_signature != 0x0); 250 KASSERT(cpu_signature != 0x0);
251 251
252 sc->sc_family = CPUID2FAMILY(cpu_signature); 252 sc->sc_family = CPUID2FAMILY(cpu_signature);
253 sc->sc_family += CPUID2EXTFAMILY(cpu_signature); 253 sc->sc_family += CPUID2EXTFAMILY(cpu_signature);
254 254
255 KASSERT(sc->sc_family >= 0xf); 255 KASSERT(sc->sc_family >= 0xf);
256 256
257 sc->sc_sme = NULL; 257 sc->sc_sme = NULL;
258 sc->sc_sensor = NULL; 258 sc->sc_sensor = NULL;
259 259
260 sc->sc_pc = pa->pa_pc; 260 sc->sc_pc = pa->pa_pc;
261 sc->sc_pcitag = pa->pa_tag; 261 sc->sc_pcitag = pa->pa_tag;
262 sc->sc_adjustment = 0; 262 sc->sc_adjustment = 0;
263 263
264 switch (sc->sc_family) { 264 switch (sc->sc_family) {
265 case 0xf: /* AMD K8 NPT */ 265 case 0xf: /* AMD K8 NPT */
266 amdtemp_k8_init(sc, cpu_signature); 266 amdtemp_k8_init(sc, cpu_signature);
267 break; 267 break;
268 268
269 case 0x10: /* AMD Barcelona/Phenom */ 269 case 0x10: /* AMD Barcelona/Phenom */
270 case 0x11: /* AMD Griffin */ 270 case 0x11: /* AMD Griffin */
271 case 0x14: /* AMD Fusion */ 271 case 0x12: /* AMD Lynx/Sabine (Llano) */
 272 case 0x14: /* AMD Brazos (Ontario/Zacate/Desna) */
272 amdtemp_family10_init(sc); 273 amdtemp_family10_init(sc);
273 break; 274 break;
274 275
275 default: 276 default:
276 aprint_normal(", family 0x%x not supported\n", 277 aprint_normal(", family 0x%x not supported\n",
277 sc->sc_family); 278 sc->sc_family);
278 return; 279 return;
279 } 280 }
280 281
281 aprint_normal("\n"); 282 aprint_normal("\n");
282 283
283 if (sc->sc_adjustment != 0) 284 if (sc->sc_adjustment != 0)
284 aprint_debug_dev(self, "Workaround enabled\n"); 285 aprint_debug_dev(self, "Workaround enabled\n");
285 286
286 sc->sc_sme = sysmon_envsys_create(); 287 sc->sc_sme = sysmon_envsys_create();
287 sc->sc_sensor_len = sizeof(envsys_data_t) * sc->sc_numsensors; 288 sc->sc_sensor_len = sizeof(envsys_data_t) * sc->sc_numsensors;
288 sc->sc_sensor = kmem_zalloc(sc->sc_sensor_len, KM_SLEEP); 289 sc->sc_sensor = kmem_zalloc(sc->sc_sensor_len, KM_SLEEP);
289 290
290 if (sc->sc_sensor == NULL) 291 if (sc->sc_sensor == NULL)
291 goto bad; 292 goto bad;
292 293
293 switch (sc->sc_family) { 294 switch (sc->sc_family) {
294 case 0xf: 295 case 0xf:
295 amdtemp_k8_setup_sensors(sc, device_unit(self)); 296 amdtemp_k8_setup_sensors(sc, device_unit(self));
296 break; 297 break;
297 case 0x10: 298 case 0x10:
298 case 0x11: 299 case 0x11:
 300 case 0x12:
299 case 0x14: 301 case 0x14:
300 amdtemp_family10_setup_sensors(sc, device_unit(self)); 302 amdtemp_family10_setup_sensors(sc, device_unit(self));
301 break; 303 break;
302 } 304 }
303 305
304 /* 306 /*
305 * Set properties in sensors. 307 * Set properties in sensors.
306 */ 308 */
307 for (i = 0; i < sc->sc_numsensors; i++) { 309 for (i = 0; i < sc->sc_numsensors; i++) {
308 if (sysmon_envsys_sensor_attach(sc->sc_sme, 310 if (sysmon_envsys_sensor_attach(sc->sc_sme,
309 &sc->sc_sensor[i])) 311 &sc->sc_sensor[i]))
310 goto bad; 312 goto bad;
311 } 313 }
312 314
313 /* 315 /*
314 * Register the sysmon_envsys device. 316 * Register the sysmon_envsys device.
315 */ 317 */
316 sc->sc_sme->sme_name = device_xname(self); 318 sc->sc_sme->sme_name = device_xname(self);
317 sc->sc_sme->sme_cookie = sc; 319 sc->sc_sme->sme_cookie = sc;
318 320
319 switch (sc->sc_family) { 321 switch (sc->sc_family) {
320 case 0xf: 322 case 0xf:
321 sc->sc_sme->sme_refresh = amdtemp_k8_refresh; 323 sc->sc_sme->sme_refresh = amdtemp_k8_refresh;
322 break; 324 break;
323 case 0x10: 325 case 0x10:
324 case 0x11: 326 case 0x11:
 327 case 0x12:
325 case 0x14: 328 case 0x14:
326 sc->sc_sme->sme_refresh = amdtemp_family10_refresh; 329 sc->sc_sme->sme_refresh = amdtemp_family10_refresh;
327 break; 330 break;
328 } 331 }
329 332
330 error = sysmon_envsys_register(sc->sc_sme); 333 error = sysmon_envsys_register(sc->sc_sme);
331 if (error) { 334 if (error) {
332 aprint_error_dev(self, "unable to register with sysmon " 335 aprint_error_dev(self, "unable to register with sysmon "
333 "(error=%d)\n", error); 336 "(error=%d)\n", error);
334 goto bad; 337 goto bad;
335 } 338 }
336 339
337 (void)pmf_device_register(self, NULL, NULL); 340 (void)pmf_device_register(self, NULL, NULL);
338 341
339 return; 342 return;
340 343
341bad: 344bad:
342 if (sc->sc_sme != NULL) { 345 if (sc->sc_sme != NULL) {
343 sysmon_envsys_destroy(sc->sc_sme); 346 sysmon_envsys_destroy(sc->sc_sme);
344 sc->sc_sme = NULL; 347 sc->sc_sme = NULL;
345 } 348 }
346 349
347 if (sc->sc_sensor != NULL) { 350 if (sc->sc_sensor != NULL) {
348 kmem_free(sc->sc_sensor, sc->sc_sensor_len); 351 kmem_free(sc->sc_sensor, sc->sc_sensor_len);
349 sc->sc_sensor = NULL; 352 sc->sc_sensor = NULL;
350 } 353 }
351} 354}
352 355
353static int 356static int
354amdtemp_detach(device_t self, int flags) 357amdtemp_detach(device_t self, int flags)
355{ 358{
356 struct amdtemp_softc *sc = device_private(self); 359 struct amdtemp_softc *sc = device_private(self);
357 360
358 if (sc->sc_sme != NULL) 361 if (sc->sc_sme != NULL)
359 sysmon_envsys_unregister(sc->sc_sme); 362 sysmon_envsys_unregister(sc->sc_sme);
360 363
361 if (sc->sc_sensor != NULL) 364 if (sc->sc_sensor != NULL)
362 kmem_free(sc->sc_sensor, sc->sc_sensor_len); 365 kmem_free(sc->sc_sensor, sc->sc_sensor_len);
363 366
364 return 0; 367 return 0;
365} 368}
366 369
367static void 370static void
368amdtemp_k8_init(struct amdtemp_softc *sc, pcireg_t cpu_signature) 371amdtemp_k8_init(struct amdtemp_softc *sc, pcireg_t cpu_signature)
369{ 372{
370 pcireg_t data; 373 pcireg_t data;
371 uint32_t cmpcap; 374 uint32_t cmpcap;
372 uint8_t i, j; 375 uint8_t i, j;
373 376
374 aprint_normal(" (K8"); 377 aprint_normal(" (K8");
375 378
376 for (i = 0; i < __arraycount(amdtemp_core) && sc->sc_rev == '\0'; i++) { 379 for (i = 0; i < __arraycount(amdtemp_core) && sc->sc_rev == '\0'; i++) {
377 for (j = 0; amdtemp_core[i].cpu[j].cpuid != 0; j++) { 380 for (j = 0; amdtemp_core[i].cpu[j].cpuid != 0; j++) {
378 if ((cpu_signature & ~0xf) 381 if ((cpu_signature & ~0xf)
379 != amdtemp_core[i].cpu[j].cpuid) 382 != amdtemp_core[i].cpu[j].cpuid)
380 continue; 383 continue;
381 384
382 sc->sc_rev = amdtemp_core[i].rev[3]; 385 sc->sc_rev = amdtemp_core[i].rev[3];
383 aprint_normal(": core rev %.4s%.1x", 386 aprint_normal(": core rev %.4s%.1x",
384 amdtemp_core[i].rev, 387 amdtemp_core[i].rev,
385 CPUID2STEPPING(cpu_signature)); 388 CPUID2STEPPING(cpu_signature));
386 389
387 switch (amdtemp_core[i].cpu[j].socket) { 390 switch (amdtemp_core[i].cpu[j].socket) {
388 case K8_SOCKET_AM2: 391 case K8_SOCKET_AM2:
389 if (sc->sc_rev == 'G') 392 if (sc->sc_rev == 'G')
390 sc->sc_adjustment = 21000000; 393 sc->sc_adjustment = 21000000;
391 aprint_normal(", socket AM2"); 394 aprint_normal(", socket AM2");
392 break; 395 break;
393 case K8_SOCKET_S1: 396 case K8_SOCKET_S1:
394 aprint_normal(", socket S1"); 397 aprint_normal(", socket S1");
395 break; 398 break;
396 case K8_SOCKET_F: 399 case K8_SOCKET_F:
397 aprint_normal(", socket F"); 400 aprint_normal(", socket F");
398 break; 401 break;
399 } 402 }
400 } 403 }
401 } 404 }
402 405
403 if (sc->sc_rev == '\0') { 406 if (sc->sc_rev == '\0') {
404 /* CPUID Family Model Register was introduced in 407 /* CPUID Family Model Register was introduced in
405 * Revision F */ 408 * Revision F */
406 sc->sc_rev = 'G'; /* newer than E, assume G */ 409 sc->sc_rev = 'G'; /* newer than E, assume G */
407 aprint_normal(": cpuid 0x%x", cpu_signature); 410 aprint_normal(": cpuid 0x%x", cpu_signature);
408 } 411 }
409 412
410 aprint_normal(")"); 413 aprint_normal(")");
411 414
412 data = pci_conf_read(sc->sc_pc, sc->sc_pcitag, NORTHBRIDGE_CAP_R); 415 data = pci_conf_read(sc->sc_pc, sc->sc_pcitag, NORTHBRIDGE_CAP_R);
413 cmpcap = (data >> 12) & 0x3; 416 cmpcap = (data >> 12) & 0x3;
414 417
415 sc->sc_numsensors = cmpcap ? 4 : 2; 418 sc->sc_numsensors = cmpcap ? 4 : 2;
416} 419}
417 420
418 421
419static void 422static void
420amdtemp_k8_setup_sensors(struct amdtemp_softc *sc, int dv_unit) 423amdtemp_k8_setup_sensors(struct amdtemp_softc *sc, int dv_unit)
421{ 424{
422 uint8_t i; 425 uint8_t i;
423 426
424 /* There are two sensors per CPU core. So we use the 427 /* There are two sensors per CPU core. So we use the
425 * device unit as socket counter to correctly enumerate 428 * device unit as socket counter to correctly enumerate
426 * the CPUs on multi-socket machines. 429 * the CPUs on multi-socket machines.
427 */ 430 */
428 dv_unit *= (sc->sc_numsensors / 2); 431 dv_unit *= (sc->sc_numsensors / 2);
429 for (i = 0; i < sc->sc_numsensors; i++) { 432 for (i = 0; i < sc->sc_numsensors; i++) {
430 sc->sc_sensor[i].units = ENVSYS_STEMP; 433 sc->sc_sensor[i].units = ENVSYS_STEMP;
431 sc->sc_sensor[i].state = ENVSYS_SVALID; 434 sc->sc_sensor[i].state = ENVSYS_SVALID;
432 435
433 snprintf(sc->sc_sensor[i].desc, sizeof(sc->sc_sensor[i].desc), 436 snprintf(sc->sc_sensor[i].desc, sizeof(sc->sc_sensor[i].desc),
434 "CPU%u Sensor%u", dv_unit + (i / 2), i % 2); 437 "CPU%u Sensor%u", dv_unit + (i / 2), i % 2);
435 } 438 }
436} 439}
437 440
438 441
439static void 442static void
440amdtemp_k8_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 443amdtemp_k8_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
441{ 444{
442 struct amdtemp_softc *sc = sme->sme_cookie; 445 struct amdtemp_softc *sc = sme->sme_cookie;
443 pcireg_t status, match, tmp; 446 pcireg_t status, match, tmp;
444 uint32_t value; 447 uint32_t value;
445 448
446 status = pci_conf_read(sc->sc_pc, sc->sc_pcitag, THERMTRIP_STAT_R); 449 status = pci_conf_read(sc->sc_pc, sc->sc_pcitag, THERMTRIP_STAT_R);
447 450
448 switch(edata->sensor) { /* sensor number */ 451 switch(edata->sensor) { /* sensor number */
449 case 0: /* Core 0 Sensor 0 */ 452 case 0: /* Core 0 Sensor 0 */
450 K8_T_SEL_C0(status); 453 K8_T_SEL_C0(status);
451 K8_T_SEL_S0(status); 454 K8_T_SEL_S0(status);
452 break; 455 break;
453 case 1: /* Core 0 Sensor 1 */ 456 case 1: /* Core 0 Sensor 1 */
454 K8_T_SEL_C0(status); 457 K8_T_SEL_C0(status);
455 K8_T_SEL_S1(status); 458 K8_T_SEL_S1(status);
456 break; 459 break;
457 case 2: /* Core 1 Sensor 0 */ 460 case 2: /* Core 1 Sensor 0 */
458 K8_T_SEL_C1(status); 461 K8_T_SEL_C1(status);
459 K8_T_SEL_S0(status); 462 K8_T_SEL_S0(status);
460 break; 463 break;
461 case 3: /* Core 1 Sensor 1 */ 464 case 3: /* Core 1 Sensor 1 */
462 K8_T_SEL_C1(status); 465 K8_T_SEL_C1(status);
463 K8_T_SEL_S1(status); 466 K8_T_SEL_S1(status);
464 break; 467 break;
465 } 468 }
466 469
467 match = status & (K8_THERM_SENSE_CORE_SEL | K8_THERM_SENSE_SEL); 470 match = status & (K8_THERM_SENSE_CORE_SEL | K8_THERM_SENSE_SEL);
468 pci_conf_write(sc->sc_pc, sc->sc_pcitag, THERMTRIP_STAT_R, status); 471 pci_conf_write(sc->sc_pc, sc->sc_pcitag, THERMTRIP_STAT_R, status);
469 status = pci_conf_read(sc->sc_pc, sc->sc_pcitag, THERMTRIP_STAT_R); 472 status = pci_conf_read(sc->sc_pc, sc->sc_pcitag, THERMTRIP_STAT_R);
470 tmp = status & (K8_THERM_SENSE_CORE_SEL | K8_THERM_SENSE_SEL); 473 tmp = status & (K8_THERM_SENSE_CORE_SEL | K8_THERM_SENSE_SEL);
471 474
472 value = 0x3ff & (status >> 14); 475 value = 0x3ff & (status >> 14);
473 if (sc->sc_rev != 'G') 476 if (sc->sc_rev != 'G')
474 value &= ~0x3; 477 value &= ~0x3;
475 478
476 edata->state = ENVSYS_SINVALID; 479 edata->state = ENVSYS_SINVALID;
477 if ((tmp == match) && ((value & ~0x3) != 0)) { 480 if ((tmp == match) && ((value & ~0x3) != 0)) {
478 edata->state = ENVSYS_SVALID; 481 edata->state = ENVSYS_SVALID;
479 edata->value_cur = (value * 250000 - 49000000) + 273150000 482 edata->value_cur = (value * 250000 - 49000000) + 273150000
480 + sc->sc_adjustment; 483 + sc->sc_adjustment;
481 } 484 }
482} 485}
483 486
484 487
485static void 488static void
486amdtemp_family10_init(struct amdtemp_softc *sc) 489amdtemp_family10_init(struct amdtemp_softc *sc)
487{ 490{
488 aprint_normal(" (Family%02xh)", sc->sc_family); 491 aprint_normal(" (Family%02xh)", sc->sc_family);
489 492
490 sc->sc_numsensors = 1; 493 sc->sc_numsensors = 1;
491} 494}
492 495
493static void 496static void
494amdtemp_family10_setup_sensors(struct amdtemp_softc *sc, int dv_unit) 497amdtemp_family10_setup_sensors(struct amdtemp_softc *sc, int dv_unit)
495{ 498{
496 /* sanity check for future enhancements */ 499 /* sanity check for future enhancements */
497 KASSERT(sc->sc_numsensors == 1); 500 KASSERT(sc->sc_numsensors == 1);
498 501
499 /* There's one sensor per memory controller (= socket) 502 /* There's one sensor per memory controller (= socket)
500 * so we use the device unit as socket counter 503 * so we use the device unit as socket counter
501 * to correctly enumerate the CPUs 504 * to correctly enumerate the CPUs
502 */ 505 */
503 sc->sc_sensor[0].units = ENVSYS_STEMP; 506 sc->sc_sensor[0].units = ENVSYS_STEMP;
504 sc->sc_sensor[0].state = ENVSYS_SVALID; 507 sc->sc_sensor[0].state = ENVSYS_SVALID;
505 508
506 snprintf(sc->sc_sensor[0].desc, sizeof(sc->sc_sensor[0].desc), 509 snprintf(sc->sc_sensor[0].desc, sizeof(sc->sc_sensor[0].desc),
507 "cpu%u temperature", dv_unit); 510 "cpu%u temperature", dv_unit);
508} 511}
509 512
510 513
511static void 514static void
512amdtemp_family10_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 515amdtemp_family10_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
513{ 516{
514 struct amdtemp_softc *sc = sme->sme_cookie; 517 struct amdtemp_softc *sc = sme->sme_cookie;
515 pcireg_t status; 518 pcireg_t status;
516 uint32_t value; 519 uint32_t value;
517 520
518 status = pci_conf_read(sc->sc_pc, 521 status = pci_conf_read(sc->sc_pc,
519 sc->sc_pcitag, F10_TEMPERATURE_CTL_R); 522 sc->sc_pcitag, F10_TEMPERATURE_CTL_R);
520 523
521 value = (status >> 21); 524 value = (status >> 21);
522 525
523 edata->state = ENVSYS_SVALID; 526 edata->state = ENVSYS_SVALID;
524 edata->value_cur = (value * 125000) + 273150000; /* From C to uK. */ 527 edata->value_cur = (value * 125000) + 273150000; /* From C to uK. */
525} 528}
526 529
527MODULE(MODULE_CLASS_DRIVER, amdtemp, NULL); 530MODULE(MODULE_CLASS_DRIVER, amdtemp, NULL);
528 531
529#ifdef _MODULE 532#ifdef _MODULE
530#include "ioconf.c" 533#include "ioconf.c"
531#endif 534#endif
532 535
533static int 536static int
534amdtemp_modcmd(modcmd_t cmd, void *aux) 537amdtemp_modcmd(modcmd_t cmd, void *aux)
535{ 538{
536 int error = 0; 539 int error = 0;
537 540
538 switch (cmd) { 541 switch (cmd) {
539 case MODULE_CMD_INIT: 542 case MODULE_CMD_INIT:
540#ifdef _MODULE 543#ifdef _MODULE
541 error = config_init_component(cfdriver_ioconf_amdtemp, 544 error = config_init_component(cfdriver_ioconf_amdtemp,
542 cfattach_ioconf_amdtemp, cfdata_ioconf_amdtemp); 545 cfattach_ioconf_amdtemp, cfdata_ioconf_amdtemp);
543#endif 546#endif
544 return error; 547 return error;
545 case MODULE_CMD_FINI: 548 case MODULE_CMD_FINI:
546#ifdef _MODULE 549#ifdef _MODULE
547 error = config_fini_component(cfdriver_ioconf_amdtemp, 550 error = config_fini_component(cfdriver_ioconf_amdtemp,
548 cfattach_ioconf_amdtemp, cfdata_ioconf_amdtemp); 551 cfattach_ioconf_amdtemp, cfdata_ioconf_amdtemp);
549#endif 552#endif
550 return error; 553 return error;
551 default: 554 default:
552 return ENOTTY; 555 return ENOTTY;
553 } 556 }
554} 557}