5
5
*
6
6
* Copyright (c) 2009 Clemens Ladisch <[email protected] >
7
7
* Copyright (c) 2020 Guenter Roeck <[email protected] >
8
+ *
9
+ * Implementation notes:
10
+ * - CCD1 and CCD2 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.
8
14
*/
9
15
10
16
#include <linux/bitops.h>
@@ -61,6 +67,8 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
61
67
62
68
/* F17h M01h Access througn SMN */
63
69
#define F17H_M01H_REPORTED_TEMP_CTRL_OFFSET 0x00059800
70
+ #define F17H_M70H_CCD1_TEMP 0x00059954
71
+ #define F17H_M70H_CCD2_TEMP 0x00059958
64
72
65
73
#define CUR_TEMP_SHIFT 21
66
74
#define CUR_TEMP_RANGE_SEL_MASK BIT(19)
@@ -72,6 +80,8 @@ struct k10temp_data {
72
80
int temp_offset ;
73
81
u32 temp_adjust_mask ;
74
82
bool show_tdie ;
83
+ bool show_tccd1 ;
84
+ bool show_tccd2 ;
75
85
};
76
86
77
87
struct tctl_offset {
@@ -143,6 +153,8 @@ static long get_raw_temp(struct k10temp_data *data)
143
153
const char * k10temp_temp_label [] = {
144
154
"Tdie" ,
145
155
"Tctl" ,
156
+ "Tccd1" ,
157
+ "Tccd2" ,
146
158
};
147
159
148
160
static int k10temp_read_labels (struct device * dev ,
@@ -172,6 +184,16 @@ static int k10temp_read(struct device *dev, enum hwmon_sensor_types type,
172
184
if (* val < 0 )
173
185
* val = 0 ;
174
186
break ;
187
+ case 2 : /* Tccd1 */
188
+ amd_smn_read (amd_pci_dev_to_node_id (data -> pdev ),
189
+ F17H_M70H_CCD1_TEMP , & regval );
190
+ * val = (regval & 0xfff ) * 125 - 305000 ;
191
+ break ;
192
+ case 3 : /* Tccd2 */
193
+ amd_smn_read (amd_pci_dev_to_node_id (data -> pdev ),
194
+ F17H_M70H_CCD2_TEMP , & regval );
195
+ * val = (regval & 0xfff ) * 125 - 305000 ;
196
+ break ;
175
197
default :
176
198
return - EOPNOTSUPP ;
177
199
}
@@ -206,8 +228,24 @@ static umode_t k10temp_is_visible(const void *_data,
206
228
case hwmon_temp :
207
229
switch (attr ) {
208
230
case hwmon_temp_input :
209
- if (channel && !data -> show_tdie )
231
+ switch (channel ) {
232
+ case 0 : /* Tdie, or Tctl if we don't show it */
233
+ break ;
234
+ case 1 : /* Tctl */
235
+ if (!data -> show_tdie )
236
+ return 0 ;
237
+ break ;
238
+ case 2 : /* Tccd1 */
239
+ if (!data -> show_tccd1 )
240
+ return 0 ;
241
+ break ;
242
+ case 3 : /* Tccd2 */
243
+ if (!data -> show_tccd2 )
244
+ return 0 ;
245
+ break ;
246
+ default :
210
247
return 0 ;
248
+ }
211
249
break ;
212
250
case hwmon_temp_max :
213
251
if (channel )
@@ -229,8 +267,24 @@ static umode_t k10temp_is_visible(const void *_data,
229
267
return 0 ;
230
268
break ;
231
269
case hwmon_temp_label :
270
+ /* No labels if we don't show the die temperature */
232
271
if (!data -> show_tdie )
233
272
return 0 ;
273
+ switch (channel ) {
274
+ case 0 : /* Tdie */
275
+ case 1 : /* Tctl */
276
+ break ;
277
+ case 2 : /* Tccd1 */
278
+ if (!data -> show_tccd1 )
279
+ return 0 ;
280
+ break ;
281
+ case 3 : /* Tccd2 */
282
+ if (!data -> show_tccd2 )
283
+ return 0 ;
284
+ break ;
285
+ default :
286
+ return 0 ;
287
+ }
234
288
break ;
235
289
default :
236
290
return 0 ;
@@ -281,6 +335,8 @@ static const struct hwmon_channel_info *k10temp_info[] = {
281
335
HWMON_T_INPUT | HWMON_T_MAX |
282
336
HWMON_T_CRIT | HWMON_T_CRIT_HYST |
283
337
HWMON_T_LABEL ,
338
+ HWMON_T_INPUT | HWMON_T_LABEL ,
339
+ HWMON_T_INPUT | HWMON_T_LABEL ,
284
340
HWMON_T_INPUT | HWMON_T_LABEL ),
285
341
NULL
286
342
};
@@ -326,9 +382,31 @@ static int k10temp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
326
382
data -> read_htcreg = read_htcreg_nb_f15 ;
327
383
data -> read_tempreg = read_tempreg_nb_f15 ;
328
384
} else if (boot_cpu_data .x86 == 0x17 || boot_cpu_data .x86 == 0x18 ) {
385
+ u32 regval ;
386
+
329
387
data -> temp_adjust_mask = CUR_TEMP_RANGE_SEL_MASK ;
330
388
data -> read_tempreg = read_tempreg_nb_f17 ;
331
389
data -> show_tdie = true;
390
+
391
+ switch (boot_cpu_data .x86_model ) {
392
+ case 0x1 : /* Zen */
393
+ case 0x8 : /* Zen+ */
394
+ case 0x11 : /* Zen APU */
395
+ case 0x18 : /* Zen+ APU */
396
+ break ;
397
+ case 0x31 : /* Zen2 Threadripper */
398
+ case 0x71 : /* Zen2 */
399
+ amd_smn_read (amd_pci_dev_to_node_id (pdev ),
400
+ F17H_M70H_CCD1_TEMP , & regval );
401
+ if (regval & 0xfff )
402
+ data -> show_tccd1 = true;
403
+
404
+ amd_smn_read (amd_pci_dev_to_node_id (pdev ),
405
+ F17H_M70H_CCD2_TEMP , & regval );
406
+ if (regval & 0xfff )
407
+ data -> show_tccd2 = true;
408
+ break ;
409
+ }
332
410
} else {
333
411
data -> read_htcreg = read_htcreg_pci ;
334
412
data -> read_tempreg = read_tempreg_pci ;
0 commit comments