forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/hwmon/k10temp.c
....@@ -1,25 +1,21 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
2
- * k10temp.c - AMD Family 10h/11h/12h/14h/15h/16h processor hardware monitoring
3
+ * k10temp.c - AMD Family 10h/11h/12h/14h/15h/16h/17h
4
+ * processor hardware monitoring
35 *
46 * Copyright (c) 2009 Clemens Ladisch <clemens@ladisch.de>
7
+ * Copyright (c) 2020 Guenter Roeck <linux@roeck-us.net>
58 *
6
- *
7
- * This driver is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License; either
9
- * version 2 of the License, or (at your option) any later version.
10
- *
11
- * This driver is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
- * See the GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this driver; if not, see <http://www.gnu.org/licenses/>.
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.
1814 */
1915
16
+#include <linux/bitops.h>
2017 #include <linux/err.h>
2118 #include <linux/hwmon.h>
22
-#include <linux/hwmon-sysfs.h>
2319 #include <linux/init.h>
2420 #include <linux/module.h>
2521 #include <linux/pci.h>
....@@ -43,22 +39,22 @@
4339 #endif
4440
4541 /* CPUID function 0x80000001, ebx */
46
-#define CPUID_PKGTYPE_MASK 0xf0000000
42
+#define CPUID_PKGTYPE_MASK GENMASK(31, 28)
4743 #define CPUID_PKGTYPE_F 0x00000000
4844 #define CPUID_PKGTYPE_AM2R2_AM3 0x10000000
4945
5046 /* DRAM controller (PCI function 2) */
5147 #define REG_DCT0_CONFIG_HIGH 0x094
52
-#define DDR3_MODE 0x00000100
48
+#define DDR3_MODE BIT(8)
5349
5450 /* miscellaneous (PCI function 3) */
5551 #define REG_HARDWARE_THERMAL_CONTROL 0x64
56
-#define HTC_ENABLE 0x00000001
52
+#define HTC_ENABLE BIT(0)
5753
5854 #define REG_REPORTED_TEMPERATURE 0xa4
5955
6056 #define REG_NORTHBRIDGE_CAPABILITIES 0xe8
61
-#define NB_CAP_HTC 0x00000400
57
+#define NB_CAP_HTC BIT(10)
6258
6359 /*
6460 * For F15h M60h and M70h, REG_HARDWARE_THERMAL_CONTROL
....@@ -69,8 +65,35 @@
6965 #define F15H_M60H_HARDWARE_TEMP_CTRL_OFFSET 0xd8200c64
7066 #define F15H_M60H_REPORTED_TEMP_CTRL_OFFSET 0xd8200ca4
7167
72
-/* F17h M01h Access througn SMN */
73
-#define F17H_M01H_REPORTED_TEMP_CTRL_OFFSET 0x00059800
68
+/* Common for Zen CPU families (Family 17h and 18h) */
69
+#define ZEN_REPORTED_TEMP_CTRL_OFFSET 0x00059800
70
+
71
+#define ZEN_CCD_TEMP(x) (0x00059954 + ((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
+
78
+#define ZEN_SVI_BASE 0x0005A000
79
+
80
+/* F17h thermal registers through SMN */
81
+#define F17H_M01H_SVI_TEL_PLANE0 (ZEN_SVI_BASE + 0xc)
82
+#define F17H_M01H_SVI_TEL_PLANE1 (ZEN_SVI_BASE + 0x10)
83
+#define F17H_M31H_SVI_TEL_PLANE0 (ZEN_SVI_BASE + 0x14)
84
+#define F17H_M31H_SVI_TEL_PLANE1 (ZEN_SVI_BASE + 0x10)
85
+
86
+#define F17H_M01H_CFACTOR_ICORE 1000000 /* 1A / LSB */
87
+#define F17H_M01H_CFACTOR_ISOC 250000 /* 0.25A / LSB */
88
+#define F17H_M31H_CFACTOR_ICORE 1000000 /* 1A / LSB */
89
+#define F17H_M31H_CFACTOR_ISOC 310000 /* 0.31A / LSB */
90
+
91
+/* F19h thermal registers through SMN */
92
+#define F19H_M01_SVI_TEL_PLANE0 (ZEN_SVI_BASE + 0x14)
93
+#define F19H_M01_SVI_TEL_PLANE1 (ZEN_SVI_BASE + 0x10)
94
+
95
+#define F19H_M01H_CFACTOR_ICORE 1000000 /* 1A / LSB */
96
+#define F19H_M01H_CFACTOR_ISOC 310000 /* 0.31A / LSB */
7497
7598 struct k10temp_data {
7699 struct pci_dev *pdev;
....@@ -78,8 +101,16 @@
78101 void (*read_tempreg)(struct pci_dev *pdev, u32 *regval);
79102 int temp_offset;
80103 u32 temp_adjust_mask;
81
- bool show_tdie;
104
+ u32 show_temp;
105
+ bool is_zen;
82106 };
107
+
108
+#define TCTL_BIT 0
109
+#define TDIE_BIT 1
110
+#define TCCD_BIT(x) ((x) + 2)
111
+
112
+#define HAVE_TEMP(d, channel) ((d)->show_temp & BIT(channel))
113
+#define HAVE_TDIE(d) HAVE_TEMP(d, TDIE_BIT)
83114
84115 struct tctl_offset {
85116 u8 model;
....@@ -129,135 +160,156 @@
129160 F15H_M60H_REPORTED_TEMP_CTRL_OFFSET, regval);
130161 }
131162
132
-static void read_tempreg_nb_f17(struct pci_dev *pdev, u32 *regval)
163
+static void read_tempreg_nb_zen(struct pci_dev *pdev, u32 *regval)
133164 {
134165 amd_smn_read(amd_pci_dev_to_node_id(pdev),
135
- F17H_M01H_REPORTED_TEMP_CTRL_OFFSET, regval);
166
+ ZEN_REPORTED_TEMP_CTRL_OFFSET, regval);
136167 }
137168
138
-static unsigned int get_raw_temp(struct k10temp_data *data)
169
+static long get_raw_temp(struct k10temp_data *data)
139170 {
140
- unsigned int temp;
141171 u32 regval;
172
+ long temp;
142173
143174 data->read_tempreg(data->pdev, &regval);
144
- temp = (regval >> 21) * 125;
175
+ temp = (regval >> ZEN_CUR_TEMP_SHIFT) * 125;
145176 if (regval & data->temp_adjust_mask)
146177 temp -= 49000;
147178 return temp;
148179 }
149180
150
-static ssize_t temp1_input_show(struct device *dev,
151
- struct device_attribute *attr, char *buf)
181
+static const char *k10temp_temp_label[] = {
182
+ "Tctl",
183
+ "Tdie",
184
+ "Tccd1",
185
+ "Tccd2",
186
+ "Tccd3",
187
+ "Tccd4",
188
+ "Tccd5",
189
+ "Tccd6",
190
+ "Tccd7",
191
+ "Tccd8",
192
+};
193
+
194
+static int k10temp_read_labels(struct device *dev,
195
+ enum hwmon_sensor_types type,
196
+ u32 attr, int channel, const char **str)
197
+{
198
+ switch (type) {
199
+ case hwmon_temp:
200
+ *str = k10temp_temp_label[channel];
201
+ break;
202
+ default:
203
+ return -EOPNOTSUPP;
204
+ }
205
+ return 0;
206
+}
207
+
208
+static int k10temp_read_temp(struct device *dev, u32 attr, int channel,
209
+ long *val)
152210 {
153211 struct k10temp_data *data = dev_get_drvdata(dev);
154
- unsigned int temp = get_raw_temp(data);
155
-
156
- if (temp > data->temp_offset)
157
- temp -= data->temp_offset;
158
- else
159
- temp = 0;
160
-
161
- return sprintf(buf, "%u\n", temp);
162
-}
163
-
164
-static ssize_t temp2_input_show(struct device *dev,
165
- struct device_attribute *devattr, char *buf)
166
-{
167
- struct k10temp_data *data = dev_get_drvdata(dev);
168
- unsigned int temp = get_raw_temp(data);
169
-
170
- return sprintf(buf, "%u\n", temp);
171
-}
172
-
173
-static ssize_t temp_label_show(struct device *dev,
174
- struct device_attribute *devattr, char *buf)
175
-{
176
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
177
-
178
- return sprintf(buf, "%s\n", attr->index ? "Tctl" : "Tdie");
179
-}
180
-
181
-static ssize_t temp1_max_show(struct device *dev,
182
- struct device_attribute *attr, char *buf)
183
-{
184
- return sprintf(buf, "%d\n", 70 * 1000);
185
-}
186
-
187
-static ssize_t show_temp_crit(struct device *dev,
188
- struct device_attribute *devattr, char *buf)
189
-{
190
- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
191
- struct k10temp_data *data = dev_get_drvdata(dev);
192
- int show_hyst = attr->index;
193212 u32 regval;
194
- int value;
195213
196
- data->read_htcreg(data->pdev, &regval);
197
- value = ((regval >> 16) & 0x7f) * 500 + 52000;
198
- if (show_hyst)
199
- value -= ((regval >> 24) & 0xf) * 500;
200
- return sprintf(buf, "%d\n", value);
214
+ switch (attr) {
215
+ case hwmon_temp_input:
216
+ switch (channel) {
217
+ case 0: /* Tctl */
218
+ *val = get_raw_temp(data);
219
+ if (*val < 0)
220
+ *val = 0;
221
+ break;
222
+ case 1: /* Tdie */
223
+ *val = get_raw_temp(data) - data->temp_offset;
224
+ if (*val < 0)
225
+ *val = 0;
226
+ break;
227
+ case 2 ... 9: /* Tccd{1-8} */
228
+ amd_smn_read(amd_pci_dev_to_node_id(data->pdev),
229
+ ZEN_CCD_TEMP(channel - 2), &regval);
230
+ *val = (regval & ZEN_CCD_TEMP_MASK) * 125 - 49000;
231
+ break;
232
+ default:
233
+ return -EOPNOTSUPP;
234
+ }
235
+ break;
236
+ case hwmon_temp_max:
237
+ *val = 70 * 1000;
238
+ break;
239
+ case hwmon_temp_crit:
240
+ data->read_htcreg(data->pdev, &regval);
241
+ *val = ((regval >> 16) & 0x7f) * 500 + 52000;
242
+ break;
243
+ case hwmon_temp_crit_hyst:
244
+ data->read_htcreg(data->pdev, &regval);
245
+ *val = (((regval >> 16) & 0x7f)
246
+ - ((regval >> 24) & 0xf)) * 500 + 52000;
247
+ break;
248
+ default:
249
+ return -EOPNOTSUPP;
250
+ }
251
+ return 0;
201252 }
202253
203
-static DEVICE_ATTR_RO(temp1_input);
204
-static DEVICE_ATTR_RO(temp1_max);
205
-static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, NULL, 0);
206
-static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_crit, NULL, 1);
207
-
208
-static SENSOR_DEVICE_ATTR(temp1_label, 0444, temp_label_show, NULL, 0);
209
-static DEVICE_ATTR_RO(temp2_input);
210
-static SENSOR_DEVICE_ATTR(temp2_label, 0444, temp_label_show, NULL, 1);
211
-
212
-static umode_t k10temp_is_visible(struct kobject *kobj,
213
- struct attribute *attr, int index)
254
+static int k10temp_read(struct device *dev, enum hwmon_sensor_types type,
255
+ u32 attr, int channel, long *val)
214256 {
215
- struct device *dev = container_of(kobj, struct device, kobj);
216
- struct k10temp_data *data = dev_get_drvdata(dev);
257
+ switch (type) {
258
+ case hwmon_temp:
259
+ return k10temp_read_temp(dev, attr, channel, val);
260
+ default:
261
+ return -EOPNOTSUPP;
262
+ }
263
+}
264
+
265
+static umode_t k10temp_is_visible(const void *_data,
266
+ enum hwmon_sensor_types type,
267
+ u32 attr, int channel)
268
+{
269
+ const struct k10temp_data *data = _data;
217270 struct pci_dev *pdev = data->pdev;
218271 u32 reg;
219272
220
- switch (index) {
221
- case 0 ... 1: /* temp1_input, temp1_max */
273
+ switch (type) {
274
+ case hwmon_temp:
275
+ switch (attr) {
276
+ case hwmon_temp_input:
277
+ if (!HAVE_TEMP(data, channel))
278
+ return 0;
279
+ break;
280
+ case hwmon_temp_max:
281
+ if (channel || data->is_zen)
282
+ return 0;
283
+ break;
284
+ case hwmon_temp_crit:
285
+ case hwmon_temp_crit_hyst:
286
+ if (channel || !data->read_htcreg)
287
+ return 0;
288
+
289
+ pci_read_config_dword(pdev,
290
+ REG_NORTHBRIDGE_CAPABILITIES,
291
+ &reg);
292
+ if (!(reg & NB_CAP_HTC))
293
+ return 0;
294
+
295
+ data->read_htcreg(data->pdev, &reg);
296
+ if (!(reg & HTC_ENABLE))
297
+ return 0;
298
+ break;
299
+ case hwmon_temp_label:
300
+ /* Show temperature labels only on Zen CPUs */
301
+ if (!data->is_zen || !HAVE_TEMP(data, channel))
302
+ return 0;
303
+ break;
304
+ default:
305
+ return 0;
306
+ }
307
+ break;
222308 default:
223
- break;
224
- case 2 ... 3: /* temp1_crit, temp1_crit_hyst */
225
- if (!data->read_htcreg)
226
- return 0;
227
-
228
- pci_read_config_dword(pdev, REG_NORTHBRIDGE_CAPABILITIES,
229
- &reg);
230
- if (!(reg & NB_CAP_HTC))
231
- return 0;
232
-
233
- data->read_htcreg(data->pdev, &reg);
234
- if (!(reg & HTC_ENABLE))
235
- return 0;
236
- break;
237
- case 4 ... 6: /* temp1_label, temp2_input, temp2_label */
238
- if (!data->show_tdie)
239
- return 0;
240
- break;
309
+ return 0;
241310 }
242
- return attr->mode;
311
+ return 0444;
243312 }
244
-
245
-static struct attribute *k10temp_attrs[] = {
246
- &dev_attr_temp1_input.attr,
247
- &dev_attr_temp1_max.attr,
248
- &sensor_dev_attr_temp1_crit.dev_attr.attr,
249
- &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
250
- &sensor_dev_attr_temp1_label.dev_attr.attr,
251
- &dev_attr_temp2_input.attr,
252
- &sensor_dev_attr_temp2_label.dev_attr.attr,
253
- NULL
254
-};
255
-
256
-static const struct attribute_group k10temp_group = {
257
- .attrs = k10temp_attrs,
258
- .is_visible = k10temp_is_visible,
259
-};
260
-__ATTRIBUTE_GROUPS(k10temp);
261313
262314 static bool has_erratum_319(struct pci_dev *pdev)
263315 {
....@@ -293,8 +345,55 @@
293345 (boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_stepping <= 2);
294346 }
295347
296
-static int k10temp_probe(struct pci_dev *pdev,
297
- const struct pci_device_id *id)
348
+static const struct hwmon_channel_info *k10temp_info[] = {
349
+ HWMON_CHANNEL_INFO(temp,
350
+ HWMON_T_INPUT | HWMON_T_MAX |
351
+ HWMON_T_CRIT | HWMON_T_CRIT_HYST |
352
+ HWMON_T_LABEL,
353
+ HWMON_T_INPUT | HWMON_T_LABEL,
354
+ HWMON_T_INPUT | HWMON_T_LABEL,
355
+ HWMON_T_INPUT | HWMON_T_LABEL,
356
+ HWMON_T_INPUT | HWMON_T_LABEL,
357
+ HWMON_T_INPUT | HWMON_T_LABEL,
358
+ HWMON_T_INPUT | HWMON_T_LABEL,
359
+ HWMON_T_INPUT | HWMON_T_LABEL,
360
+ HWMON_T_INPUT | HWMON_T_LABEL,
361
+ HWMON_T_INPUT | HWMON_T_LABEL),
362
+ HWMON_CHANNEL_INFO(in,
363
+ HWMON_I_INPUT | HWMON_I_LABEL,
364
+ HWMON_I_INPUT | HWMON_I_LABEL),
365
+ HWMON_CHANNEL_INFO(curr,
366
+ HWMON_C_INPUT | HWMON_C_LABEL,
367
+ HWMON_C_INPUT | HWMON_C_LABEL),
368
+ NULL
369
+};
370
+
371
+static const struct hwmon_ops k10temp_hwmon_ops = {
372
+ .is_visible = k10temp_is_visible,
373
+ .read = k10temp_read,
374
+ .read_string = k10temp_read_labels,
375
+};
376
+
377
+static const struct hwmon_chip_info k10temp_chip_info = {
378
+ .ops = &k10temp_hwmon_ops,
379
+ .info = k10temp_info,
380
+};
381
+
382
+static void k10temp_get_ccd_support(struct pci_dev *pdev,
383
+ struct k10temp_data *data, int limit)
384
+{
385
+ u32 regval;
386
+ int i;
387
+
388
+ for (i = 0; i < limit; i++) {
389
+ amd_smn_read(amd_pci_dev_to_node_id(pdev),
390
+ ZEN_CCD_TEMP(i), &regval);
391
+ if (regval & ZEN_CCD_TEMP_VALID)
392
+ data->show_temp |= BIT(TCCD_BIT(i));
393
+ }
394
+}
395
+
396
+static int k10temp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
298397 {
299398 int unreliable = has_erratum_319(pdev);
300399 struct device *dev = &pdev->dev;
....@@ -317,16 +416,42 @@
317416 return -ENOMEM;
318417
319418 data->pdev = pdev;
419
+ data->show_temp |= BIT(TCTL_BIT); /* Always show Tctl */
320420
321421 if (boot_cpu_data.x86 == 0x15 &&
322422 ((boot_cpu_data.x86_model & 0xf0) == 0x60 ||
323423 (boot_cpu_data.x86_model & 0xf0) == 0x70)) {
324424 data->read_htcreg = read_htcreg_nb_f15;
325425 data->read_tempreg = read_tempreg_nb_f15;
326
- } else if (boot_cpu_data.x86 == 0x17) {
327
- data->temp_adjust_mask = 0x80000;
328
- data->read_tempreg = read_tempreg_nb_f17;
329
- data->show_tdie = true;
426
+ } else if (boot_cpu_data.x86 == 0x17 || boot_cpu_data.x86 == 0x18) {
427
+ data->temp_adjust_mask = ZEN_CUR_TEMP_RANGE_SEL_MASK;
428
+ data->read_tempreg = read_tempreg_nb_zen;
429
+ data->show_temp |= BIT(TDIE_BIT); /* show Tdie */
430
+ data->is_zen = true;
431
+
432
+ switch (boot_cpu_data.x86_model) {
433
+ case 0x1: /* Zen */
434
+ case 0x8: /* Zen+ */
435
+ case 0x11: /* Zen APU */
436
+ case 0x18: /* Zen+ APU */
437
+ k10temp_get_ccd_support(pdev, data, 4);
438
+ break;
439
+ case 0x31: /* Zen2 Threadripper */
440
+ case 0x71: /* Zen2 */
441
+ k10temp_get_ccd_support(pdev, data, 8);
442
+ break;
443
+ }
444
+ } else if (boot_cpu_data.x86 == 0x19) {
445
+ data->temp_adjust_mask = ZEN_CUR_TEMP_RANGE_SEL_MASK;
446
+ data->read_tempreg = read_tempreg_nb_zen;
447
+ data->show_temp |= BIT(TDIE_BIT);
448
+ data->is_zen = true;
449
+
450
+ switch (boot_cpu_data.x86_model) {
451
+ case 0x0 ... 0x1: /* Zen3 */
452
+ k10temp_get_ccd_support(pdev, data, 8);
453
+ break;
454
+ }
330455 } else {
331456 data->read_htcreg = read_htcreg_pci;
332457 data->read_tempreg = read_tempreg_pci;
....@@ -342,8 +467,9 @@
342467 }
343468 }
344469
345
- hwmon_dev = devm_hwmon_device_register_with_groups(dev, "k10temp", data,
346
- k10temp_groups);
470
+ hwmon_dev = devm_hwmon_device_register_with_info(dev, "k10temp", data,
471
+ &k10temp_chip_info,
472
+ NULL);
347473 return PTR_ERR_OR_ZERO(hwmon_dev);
348474 }
349475
....@@ -360,6 +486,11 @@
360486 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
361487 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
362488 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) },
489
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) },
490
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F3) },
491
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) },
492
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_DF_F3) },
493
+ { PCI_VDEVICE(HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) },
363494 {}
364495 };
365496 MODULE_DEVICE_TABLE(pci, k10temp_id_table);