xref: /linux/drivers/hwmon/k10temp.c (revision a925e9c47e15bfc731b4e9a7c373c43edbe7f4ca)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * k10temp.c - AMD Family 10h/11h/12h/14h/15h/16h/17h
4  *		processor hardware monitoring
5  *
6  * Copyright (c) 2009 Clemens Ladisch <clemens@ladisch.de>
7  * Copyright (c) 2020 Guenter Roeck <linux@roeck-us.net>
8  *
9  * Implementation notes:
10  * - CCD register address information as well as the calculation to
11  *   convert raw register values is from https://github.com/ocerman/zenpower.
12  *   The information is not confirmed from chip datasheets, but experiments
13  *   suggest that it provides reasonable temperature values.
14  */
15 
16 #include <linux/bitops.h>
17 #include <linux/err.h>
18 #include <linux/hwmon.h>
19 #include <linux/init.h>
20 #include <linux/module.h>
21 #include <linux/pci.h>
22 #include <linux/pci_ids.h>
23 
24 #include <asm/amd/node.h>
25 #include <asm/cpuid/api.h>
26 #include <asm/processor.h>
27 
28 MODULE_DESCRIPTION("AMD Family 10h+ CPU core temperature monitor");
29 MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
30 MODULE_LICENSE("GPL");
31 
32 static bool force;
33 module_param(force, bool, 0444);
34 MODULE_PARM_DESC(force, "force loading on processors with erratum 319");
35 
36 #ifndef PCI_DEVICE_ID_AMD_15H_M70H_NB_F3
37 #define PCI_DEVICE_ID_AMD_15H_M70H_NB_F3	0x15b3
38 #endif
39 
40 /* CPUID function 0x80000001, ebx */
41 #define CPUID_PKGTYPE_MASK	GENMASK(31, 28)
42 #define CPUID_PKGTYPE_F		0x00000000
43 #define CPUID_PKGTYPE_AM2R2_AM3	0x10000000
44 
45 /* DRAM controller (PCI function 2) */
46 #define REG_DCT0_CONFIG_HIGH		0x094
47 #define  DDR3_MODE			BIT(8)
48 
49 /* miscellaneous (PCI function 3) */
50 #define REG_HARDWARE_THERMAL_CONTROL	0x64
51 #define  HTC_ENABLE			BIT(0)
52 
53 #define REG_REPORTED_TEMPERATURE	0xa4
54 
55 #define REG_NORTHBRIDGE_CAPABILITIES	0xe8
56 #define  NB_CAP_HTC			BIT(10)
57 
58 /*
59  * For F15h M60h and M70h, REG_HARDWARE_THERMAL_CONTROL
60  * and REG_REPORTED_TEMPERATURE have been moved to
61  * D0F0xBC_xD820_0C64 [Hardware Temperature Control]
62  * D0F0xBC_xD820_0CA4 [Reported Temperature Control]
63  */
64 #define F15H_M60H_HARDWARE_TEMP_CTRL_OFFSET	0xd8200c64
65 #define F15H_M60H_REPORTED_TEMP_CTRL_OFFSET	0xd8200ca4
66 
67 /* Common for Zen CPU families (Family 17h, 19h and 1Ah) */
68 #define ZEN_REPORTED_TEMP_CTRL_BASE		0x00059800
69 
70 #define ZEN_CCD_TEMP(offset, x)			(ZEN_REPORTED_TEMP_CTRL_BASE + \
71 						 (offset) + ((x) * 4))
72 #define ZEN_CCD_TEMP_VALID			BIT(11)
73 #define ZEN_CCD_TEMP_MASK			GENMASK(10, 0)
74 
75 #define ZEN_CUR_TEMP_SHIFT			21
76 #define ZEN_CUR_TEMP_RANGE_SEL_MASK		BIT(19)
77 #define ZEN_CUR_TEMP_TJ_SEL_MASK		GENMASK(17, 16)
78 
79 /*
80  * AMD's Industrial processor 3255 supports temperature from -40 deg to 105 deg Celsius.
81  * Use the model name to identify 3255 CPUs and set a flag to display negative temperature.
82  * Do not round off to zero for negative Tctl or Tdie values if the flag is set
83  */
84 #define AMD_I3255_STR				"3255"
85 
86 /*
87  * PCI Device IDs for AMD's Family 17h-based SOCs.
88  * Defining locally as IDs are not shared.
89  */
90 #define PCI_DEVICE_ID_AMD_17H_M90H_DF_F3	0x1663
91 
92 /*
93  * PCI Device IDs for AMD's Family 1Ah-based SOCs.
94  * Defining locally as IDs are not shared.
95  */
96 #define PCI_DEVICE_ID_AMD_1AH_M50H_DF_F3	0x12cb
97 #define PCI_DEVICE_ID_AMD_1AH_M80H_DF_F3	0x1243
98 #define PCI_DEVICE_ID_AMD_1AH_M90H_DF_F3	0x127b
99 
100 struct k10temp_data {
101 	struct pci_dev *pdev;
102 	void (*read_htcreg)(struct pci_dev *pdev, u32 *regval);
103 	void (*read_tempreg)(struct pci_dev *pdev, u32 *regval);
104 	int temp_offset;
105 	u32 temp_adjust_mask;
106 	u32 show_temp;
107 	bool is_zen;
108 	u32 ccd_offset;
109 	bool disp_negative;
110 };
111 
112 #define TCTL_BIT	0
113 #define TDIE_BIT	1
114 #define TCCD_BIT(x)	((x) + 2)
115 
116 #define HAVE_TEMP(d, channel)	((d)->show_temp & BIT(channel))
117 
118 struct tctl_offset {
119 	u8 model;
120 	char const *id;
121 	int offset;
122 };
123 
124 static const struct tctl_offset tctl_offset_table[] = {
125 	{ 0x17, "AMD Ryzen 5 1600X", 20000 },
126 	{ 0x17, "AMD Ryzen 7 1700X", 20000 },
127 	{ 0x17, "AMD Ryzen 7 1800X", 20000 },
128 	{ 0x17, "AMD Ryzen 7 2700X", 10000 },
129 	{ 0x17, "AMD Ryzen Threadripper 19", 27000 }, /* 19{00,20,50}X */
130 	{ 0x17, "AMD Ryzen Threadripper 29", 27000 }, /* 29{20,50,70,90}[W]X */
131 };
132 
133 static void read_htcreg_pci(struct pci_dev *pdev, u32 *regval)
134 {
135 	pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL, regval);
136 }
137 
138 static void read_tempreg_pci(struct pci_dev *pdev, u32 *regval)
139 {
140 	pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, regval);
141 }
142 
143 static void amd_nb_index_read(struct pci_dev *pdev, unsigned int devfn,
144 			      unsigned int base, int offset, u32 *val)
145 {
146 	pci_bus_write_config_dword(pdev->bus, devfn,
147 				   base, offset);
148 	pci_bus_read_config_dword(pdev->bus, devfn,
149 				  base + 4, val);
150 }
151 
152 static void read_htcreg_nb_f15(struct pci_dev *pdev, u32 *regval)
153 {
154 	amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8,
155 			  F15H_M60H_HARDWARE_TEMP_CTRL_OFFSET, regval);
156 }
157 
158 static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval)
159 {
160 	amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8,
161 			  F15H_M60H_REPORTED_TEMP_CTRL_OFFSET, regval);
162 }
163 
164 static u16 amd_pci_dev_to_node_id(struct pci_dev *pdev)
165 {
166 	return PCI_SLOT(pdev->devfn) - AMD_NODE0_PCI_SLOT;
167 }
168 
169 static void read_tempreg_nb_zen(struct pci_dev *pdev, u32 *regval)
170 {
171 	if (amd_smn_read(amd_pci_dev_to_node_id(pdev),
172 			 ZEN_REPORTED_TEMP_CTRL_BASE, regval))
173 		*regval = 0;
174 }
175 
176 static int read_ccd_temp_reg(struct k10temp_data *data, int ccd, u32 *regval)
177 {
178 	u16 node_id = amd_pci_dev_to_node_id(data->pdev);
179 
180 	return amd_smn_read(node_id, ZEN_CCD_TEMP(data->ccd_offset, ccd), regval);
181 }
182 
183 static long get_raw_temp(struct k10temp_data *data)
184 {
185 	u32 regval;
186 	long temp;
187 
188 	data->read_tempreg(data->pdev, &regval);
189 	temp = (regval >> ZEN_CUR_TEMP_SHIFT) * 125;
190 	if ((regval & data->temp_adjust_mask) ||
191 	    (regval & ZEN_CUR_TEMP_TJ_SEL_MASK) == ZEN_CUR_TEMP_TJ_SEL_MASK)
192 		temp -= 49000;
193 	return temp;
194 }
195 
196 static const char *k10temp_temp_label[] = {
197 	"Tctl",
198 	"Tdie",
199 	"Tccd1",
200 	"Tccd2",
201 	"Tccd3",
202 	"Tccd4",
203 	"Tccd5",
204 	"Tccd6",
205 	"Tccd7",
206 	"Tccd8",
207 	"Tccd9",
208 	"Tccd10",
209 	"Tccd11",
210 	"Tccd12",
211 	"Tccd13",
212 	"Tccd14",
213 	"Tccd15",
214 	"Tccd16",
215 };
216 
217 static int k10temp_read_labels(struct device *dev,
218 			       enum hwmon_sensor_types type,
219 			       u32 attr, int channel, const char **str)
220 {
221 	switch (type) {
222 	case hwmon_temp:
223 		*str = k10temp_temp_label[channel];
224 		break;
225 	default:
226 		return -EOPNOTSUPP;
227 	}
228 	return 0;
229 }
230 
231 static int k10temp_read_temp(struct device *dev, u32 attr, int channel,
232 			     long *val)
233 {
234 	struct k10temp_data *data = dev_get_drvdata(dev);
235 	int ret = -EOPNOTSUPP;
236 	u32 regval;
237 
238 	switch (attr) {
239 	case hwmon_temp_input:
240 		switch (channel) {
241 		case 0:		/* Tctl */
242 			*val = get_raw_temp(data);
243 			if (*val < 0 && !data->disp_negative)
244 				*val = 0;
245 			break;
246 		case 1:		/* Tdie */
247 			*val = get_raw_temp(data) - data->temp_offset;
248 			if (*val < 0 && !data->disp_negative)
249 				*val = 0;
250 			break;
251 		case 2 ... 17:		/* Tccd{1-16} */
252 			ret = read_ccd_temp_reg(data, channel - 2, &regval);
253 
254 			if (ret)
255 				return ret;
256 
257 			*val = (regval & ZEN_CCD_TEMP_MASK) * 125 - 49000;
258 			break;
259 		default:
260 			return ret;
261 		}
262 		break;
263 	case hwmon_temp_max:
264 		*val = 70 * 1000;
265 		break;
266 	case hwmon_temp_crit:
267 		data->read_htcreg(data->pdev, &regval);
268 		*val = ((regval >> 16) & 0x7f) * 500 + 52000;
269 		break;
270 	case hwmon_temp_crit_hyst:
271 		data->read_htcreg(data->pdev, &regval);
272 		*val = (((regval >> 16) & 0x7f)
273 			- ((regval >> 24) & 0xf)) * 500 + 52000;
274 		break;
275 	default:
276 		return ret;
277 	}
278 	return 0;
279 }
280 
281 static int k10temp_read(struct device *dev, enum hwmon_sensor_types type,
282 			u32 attr, int channel, long *val)
283 {
284 	switch (type) {
285 	case hwmon_temp:
286 		return k10temp_read_temp(dev, attr, channel, val);
287 	default:
288 		return -EOPNOTSUPP;
289 	}
290 }
291 
292 static umode_t k10temp_is_visible(const void *drvdata,
293 				  enum hwmon_sensor_types type,
294 				  u32 attr, int channel)
295 {
296 	const struct k10temp_data *data = drvdata;
297 	struct pci_dev *pdev = data->pdev;
298 	u32 reg;
299 
300 	switch (type) {
301 	case hwmon_temp:
302 		switch (attr) {
303 		case hwmon_temp_input:
304 			if (!HAVE_TEMP(data, channel))
305 				return 0;
306 			break;
307 		case hwmon_temp_max:
308 			if (channel || data->is_zen)
309 				return 0;
310 			break;
311 		case hwmon_temp_crit:
312 		case hwmon_temp_crit_hyst:
313 			if (channel || !data->read_htcreg)
314 				return 0;
315 
316 			pci_read_config_dword(pdev,
317 					      REG_NORTHBRIDGE_CAPABILITIES,
318 					      &reg);
319 			if (!(reg & NB_CAP_HTC))
320 				return 0;
321 
322 			data->read_htcreg(data->pdev, &reg);
323 			if (!(reg & HTC_ENABLE))
324 				return 0;
325 			break;
326 		case hwmon_temp_label:
327 			/* Show temperature labels only on Zen CPUs */
328 			if (!data->is_zen || !HAVE_TEMP(data, channel))
329 				return 0;
330 			break;
331 		default:
332 			return 0;
333 		}
334 		break;
335 	default:
336 		return 0;
337 	}
338 	return 0444;
339 }
340 
341 static bool has_erratum_319(struct pci_dev *pdev)
342 {
343 	u32 pkg_type, reg_dram_cfg;
344 
345 	if (boot_cpu_data.x86 != 0x10)
346 		return false;
347 
348 	/*
349 	 * Erratum 319: The thermal sensor of Socket F/AM2+ processors
350 	 *              may be unreliable.
351 	 */
352 	pkg_type = cpuid_ebx(0x80000001) & CPUID_PKGTYPE_MASK;
353 	if (pkg_type == CPUID_PKGTYPE_F)
354 		return true;
355 	if (pkg_type != CPUID_PKGTYPE_AM2R2_AM3)
356 		return false;
357 
358 	/* DDR3 memory implies socket AM3, which is good */
359 	pci_bus_read_config_dword(pdev->bus,
360 				  PCI_DEVFN(PCI_SLOT(pdev->devfn), 2),
361 				  REG_DCT0_CONFIG_HIGH, &reg_dram_cfg);
362 	if (reg_dram_cfg & DDR3_MODE)
363 		return false;
364 
365 	/*
366 	 * Unfortunately it is possible to run a socket AM3 CPU with DDR2
367 	 * memory. We blacklist all the cores which do exist in socket AM2+
368 	 * format. It still isn't perfect, as RB-C2 cores exist in both AM2+
369 	 * and AM3 formats, but that's the best we can do.
370 	 */
371 	return boot_cpu_data.x86_model < 4 ||
372 	       (boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_stepping <= 2);
373 }
374 
375 static const struct hwmon_channel_info * const k10temp_info[] = {
376 	HWMON_CHANNEL_INFO(temp,
377 			   HWMON_T_INPUT | HWMON_T_MAX |
378 			   HWMON_T_CRIT | HWMON_T_CRIT_HYST |
379 			   HWMON_T_LABEL,
380 			   HWMON_T_INPUT | HWMON_T_LABEL,
381 			   HWMON_T_INPUT | HWMON_T_LABEL,
382 			   HWMON_T_INPUT | HWMON_T_LABEL,
383 			   HWMON_T_INPUT | HWMON_T_LABEL,
384 			   HWMON_T_INPUT | HWMON_T_LABEL,
385 			   HWMON_T_INPUT | HWMON_T_LABEL,
386 			   HWMON_T_INPUT | HWMON_T_LABEL,
387 			   HWMON_T_INPUT | HWMON_T_LABEL,
388 			   HWMON_T_INPUT | HWMON_T_LABEL,
389 			   HWMON_T_INPUT | HWMON_T_LABEL,
390 			   HWMON_T_INPUT | HWMON_T_LABEL,
391 			   HWMON_T_INPUT | HWMON_T_LABEL,
392 			   HWMON_T_INPUT | HWMON_T_LABEL,
393 			   HWMON_T_INPUT | HWMON_T_LABEL,
394 			   HWMON_T_INPUT | HWMON_T_LABEL,
395 			   HWMON_T_INPUT | HWMON_T_LABEL,
396 			   HWMON_T_INPUT | HWMON_T_LABEL),
397 	NULL
398 };
399 
400 static const struct hwmon_ops k10temp_hwmon_ops = {
401 	.is_visible = k10temp_is_visible,
402 	.read = k10temp_read,
403 	.read_string = k10temp_read_labels,
404 };
405 
406 static const struct hwmon_chip_info k10temp_chip_info = {
407 	.ops = &k10temp_hwmon_ops,
408 	.info = k10temp_info,
409 };
410 
411 static void k10temp_get_ccd_support(struct k10temp_data *data, int limit)
412 {
413 	u32 regval;
414 	int i;
415 
416 	for (i = 0; i < limit; i++) {
417 		/*
418 		 * Ignore inaccessible CCDs.
419 		 *
420 		 * Some systems will return a register value of 0, and the TEMP_VALID
421 		 * bit check below will naturally fail.
422 		 *
423 		 * Other systems will return a PCI_ERROR_RESPONSE (0xFFFFFFFF) for
424 		 * the register value. And this will incorrectly pass the TEMP_VALID
425 		 * bit check.
426 		 */
427 		if (read_ccd_temp_reg(data, i, &regval))
428 			continue;
429 
430 		if (regval & ZEN_CCD_TEMP_VALID)
431 			data->show_temp |= BIT(TCCD_BIT(i));
432 	}
433 }
434 
435 static int k10temp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
436 {
437 	int unreliable = has_erratum_319(pdev);
438 	struct device *dev = &pdev->dev;
439 	struct k10temp_data *data;
440 	struct device *hwmon_dev;
441 	int i;
442 
443 	if (unreliable) {
444 		if (!force) {
445 			dev_err(dev,
446 				"unreliable CPU thermal sensor; monitoring disabled\n");
447 			return -ENODEV;
448 		}
449 		dev_warn(dev,
450 			 "unreliable CPU thermal sensor; check erratum 319\n");
451 	}
452 
453 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
454 	if (!data)
455 		return -ENOMEM;
456 
457 	data->pdev = pdev;
458 	data->show_temp |= BIT(TCTL_BIT);	/* Always show Tctl */
459 
460 	if (boot_cpu_data.x86 == 0x17 &&
461 	    strstr(boot_cpu_data.x86_model_id, AMD_I3255_STR)) {
462 		data->disp_negative = true;
463 	}
464 
465 	data->is_zen = cpu_feature_enabled(X86_FEATURE_ZEN);
466 	if (data->is_zen) {
467 		data->temp_adjust_mask = ZEN_CUR_TEMP_RANGE_SEL_MASK;
468 		data->read_tempreg = read_tempreg_nb_zen;
469 	} else if (boot_cpu_data.x86 == 0x15 &&
470 	    ((boot_cpu_data.x86_model & 0xf0) == 0x60 ||
471 	     (boot_cpu_data.x86_model & 0xf0) == 0x70)) {
472 		data->read_htcreg = read_htcreg_nb_f15;
473 		data->read_tempreg = read_tempreg_nb_f15;
474 	} else {
475 		data->read_htcreg = read_htcreg_pci;
476 		data->read_tempreg = read_tempreg_pci;
477 	}
478 
479 	if (boot_cpu_data.x86 == 0x17) {
480 		switch (boot_cpu_data.x86_model) {
481 		case 0x1:	/* Zen */
482 		case 0x8:	/* Zen+ */
483 		case 0x11:	/* Zen APU */
484 		case 0x18:	/* Zen+ APU */
485 			data->ccd_offset = 0x154;
486 			k10temp_get_ccd_support(data, 4);
487 			break;
488 		case 0x31:	/* Zen2 Threadripper */
489 		case 0x47:	/* Cyan Skillfish */
490 		case 0x60:	/* Renoir */
491 		case 0x68:	/* Lucienne */
492 		case 0x71:	/* Zen2 */
493 			data->ccd_offset = 0x154;
494 			k10temp_get_ccd_support(data, 8);
495 			break;
496 		case 0xa0 ... 0xaf:
497 			data->ccd_offset = 0x300;
498 			k10temp_get_ccd_support(data, 8);
499 			break;
500 		}
501 	} else if (boot_cpu_data.x86 == 0x19) {
502 		switch (boot_cpu_data.x86_model) {
503 		case 0x0 ... 0x1:	/* Zen3 SP3/TR */
504 		case 0x8:		/* Zen3 TR Chagall */
505 		case 0x21:		/* Zen3 Ryzen Desktop */
506 		case 0x50 ... 0x5f:	/* Green Sardine */
507 			data->ccd_offset = 0x154;
508 			k10temp_get_ccd_support(data, 8);
509 			break;
510 		case 0x40 ... 0x4f:	/* Yellow Carp */
511 			data->ccd_offset = 0x300;
512 			k10temp_get_ccd_support(data, 8);
513 			break;
514 		case 0x60 ... 0x6f:
515 		case 0x70 ... 0x7f:
516 			data->ccd_offset = 0x308;
517 			k10temp_get_ccd_support(data, 8);
518 			break;
519 		case 0x10 ... 0x1f:
520 		case 0xa0 ... 0xaf:
521 			data->ccd_offset = 0x300;
522 			k10temp_get_ccd_support(data, 12);
523 			break;
524 		}
525 	} else if (boot_cpu_data.x86 == 0x1a) {
526 		switch (boot_cpu_data.x86_model) {
527 		case 0x00 ... 0x1f:	/* Zen5 Turin */
528 			data->ccd_offset = 0x1F0;
529 			k10temp_get_ccd_support(data, 16);
530 			break;
531 		case 0x40 ... 0x4f:	/* Zen5 Ryzen Desktop */
532 			data->ccd_offset = 0x308;
533 			k10temp_get_ccd_support(data, 8);
534 			break;
535 		}
536 	}
537 
538 	for (i = 0; i < ARRAY_SIZE(tctl_offset_table); i++) {
539 		const struct tctl_offset *entry = &tctl_offset_table[i];
540 
541 		if (boot_cpu_data.x86 == entry->model &&
542 		    strstr(boot_cpu_data.x86_model_id, entry->id)) {
543 			data->show_temp |= BIT(TDIE_BIT);	/* show Tdie */
544 			data->temp_offset = entry->offset;
545 			break;
546 		}
547 	}
548 
549 	hwmon_dev = devm_hwmon_device_register_with_info(dev, "k10temp", data,
550 							 &k10temp_chip_info,
551 							 NULL);
552 	return PTR_ERR_OR_ZERO(hwmon_dev);
553 }
554 
555 static const struct pci_device_id k10temp_id_table[] = {
556 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
557 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) },
558 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) },
559 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) },
560 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) },
561 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F3) },
562 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F3) },
563 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M70H_NB_F3) },
564 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
565 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
566 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
567 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) },
568 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) },
569 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M40H_DF_F3) },
570 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F3) },
571 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) },
572 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M90H_DF_F3) },
573 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_MA0H_DF_F3) },
574 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_DF_F3) },
575 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M10H_DF_F3) },
576 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M40H_DF_F3) },
577 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F3) },
578 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M60H_DF_F3) },
579 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M70H_DF_F3) },
580 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) },
581 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3) },
582 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3) },
583 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M50H_DF_F3) },
584 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F3) },
585 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F3) },
586 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M80H_DF_F3) },
587 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M90H_DF_F3) },
588 	{}
589 };
590 MODULE_DEVICE_TABLE(pci, k10temp_id_table);
591 
592 static struct pci_driver k10temp_driver = {
593 	.name = "k10temp",
594 	.id_table = k10temp_id_table,
595 	.probe = k10temp_probe,
596 };
597 
598 module_pci_driver(k10temp_driver);
599