Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/accel/habanalabs/common/hwmon.c
26436 views
1
// SPDX-License-Identifier: GPL-2.0
2
3
/*
4
* Copyright 2016-2019 HabanaLabs, Ltd.
5
* All Rights Reserved.
6
*/
7
8
#include "habanalabs.h"
9
10
#include <linux/pci.h>
11
#include <linux/hwmon.h>
12
13
#define HWMON_NR_SENSOR_TYPES (hwmon_max)
14
15
#ifdef _HAS_HWMON_HWMON_T_ENABLE
16
17
static u32 fixup_flags_legacy_fw(struct hl_device *hdev, enum hwmon_sensor_types type,
18
u32 cpucp_flags)
19
{
20
u32 flags;
21
22
switch (type) {
23
case hwmon_temp:
24
flags = (cpucp_flags << 1) | HWMON_T_ENABLE;
25
break;
26
27
case hwmon_in:
28
flags = (cpucp_flags << 1) | HWMON_I_ENABLE;
29
break;
30
31
case hwmon_curr:
32
flags = (cpucp_flags << 1) | HWMON_C_ENABLE;
33
break;
34
35
case hwmon_fan:
36
flags = (cpucp_flags << 1) | HWMON_F_ENABLE;
37
break;
38
39
case hwmon_power:
40
flags = (cpucp_flags << 1) | HWMON_P_ENABLE;
41
break;
42
43
case hwmon_pwm:
44
/* enable bit was here from day 1, so no need to adjust */
45
flags = cpucp_flags;
46
break;
47
48
default:
49
dev_err_ratelimited(hdev->dev, "unsupported h/w sensor type %d\n", type);
50
flags = cpucp_flags;
51
break;
52
}
53
54
return flags;
55
}
56
57
static u32 fixup_attr_legacy_fw(u32 attr)
58
{
59
return (attr - 1);
60
}
61
62
#else
63
64
static u32 fixup_flags_legacy_fw(struct hl_device *hdev, enum hwmon_sensor_types type,
65
u32 cpucp_flags)
66
{
67
return cpucp_flags;
68
}
69
70
static u32 fixup_attr_legacy_fw(u32 attr)
71
{
72
return attr;
73
}
74
75
#endif /* !_HAS_HWMON_HWMON_T_ENABLE */
76
77
static u32 adjust_hwmon_flags(struct hl_device *hdev, enum hwmon_sensor_types type, u32 cpucp_flags)
78
{
79
u32 flags, cpucp_input_val;
80
bool use_cpucp_enum;
81
82
use_cpucp_enum = (hdev->asic_prop.fw_app_cpu_boot_dev_sts0 &
83
CPU_BOOT_DEV_STS0_MAP_HWMON_EN) ? true : false;
84
85
/* If f/w is using it's own enum, we need to check if the properties values are aligned.
86
* If not, it means we need to adjust the values to the new format that is used in the
87
* kernel since 5.6 (enum values were incremented by 1 by adding a new enable value).
88
*/
89
if (use_cpucp_enum) {
90
switch (type) {
91
case hwmon_temp:
92
cpucp_input_val = cpucp_temp_input;
93
if (cpucp_input_val == hwmon_temp_input)
94
flags = cpucp_flags;
95
else
96
flags = (cpucp_flags << 1) | HWMON_T_ENABLE;
97
break;
98
99
case hwmon_in:
100
cpucp_input_val = cpucp_in_input;
101
if (cpucp_input_val == hwmon_in_input)
102
flags = cpucp_flags;
103
else
104
flags = (cpucp_flags << 1) | HWMON_I_ENABLE;
105
break;
106
107
case hwmon_curr:
108
cpucp_input_val = cpucp_curr_input;
109
if (cpucp_input_val == hwmon_curr_input)
110
flags = cpucp_flags;
111
else
112
flags = (cpucp_flags << 1) | HWMON_C_ENABLE;
113
break;
114
115
case hwmon_fan:
116
cpucp_input_val = cpucp_fan_input;
117
if (cpucp_input_val == hwmon_fan_input)
118
flags = cpucp_flags;
119
else
120
flags = (cpucp_flags << 1) | HWMON_F_ENABLE;
121
break;
122
123
case hwmon_pwm:
124
/* enable bit was here from day 1, so no need to adjust */
125
flags = cpucp_flags;
126
break;
127
128
case hwmon_power:
129
cpucp_input_val = CPUCP_POWER_INPUT;
130
if (cpucp_input_val == hwmon_power_input)
131
flags = cpucp_flags;
132
else
133
flags = (cpucp_flags << 1) | HWMON_P_ENABLE;
134
break;
135
136
default:
137
dev_err_ratelimited(hdev->dev, "unsupported h/w sensor type %d\n", type);
138
flags = cpucp_flags;
139
break;
140
}
141
} else {
142
flags = fixup_flags_legacy_fw(hdev, type, cpucp_flags);
143
}
144
145
return flags;
146
}
147
148
int hl_build_hwmon_channel_info(struct hl_device *hdev, struct cpucp_sensor *sensors_arr)
149
{
150
u32 num_sensors_for_type, flags, num_active_sensor_types = 0, arr_size = 0, *curr_arr;
151
u32 sensors_by_type_next_index[HWMON_NR_SENSOR_TYPES] = {0};
152
u32 *sensors_by_type[HWMON_NR_SENSOR_TYPES] = {NULL};
153
struct hwmon_channel_info **channels_info;
154
u32 counts[HWMON_NR_SENSOR_TYPES] = {0};
155
enum hwmon_sensor_types type;
156
int rc, i, j;
157
158
for (i = 0 ; i < CPUCP_MAX_SENSORS ; i++) {
159
type = le32_to_cpu(sensors_arr[i].type);
160
161
if ((type == 0) && (sensors_arr[i].flags == 0))
162
break;
163
164
if (type >= HWMON_NR_SENSOR_TYPES) {
165
dev_err_ratelimited(hdev->dev,
166
"Got wrong sensor type %d from device\n", type);
167
return -EINVAL;
168
}
169
170
counts[type]++;
171
arr_size++;
172
}
173
174
for (i = 0 ; i < HWMON_NR_SENSOR_TYPES ; i++) {
175
if (counts[i] == 0)
176
continue;
177
178
num_sensors_for_type = counts[i] + 1;
179
dev_dbg(hdev->dev, "num_sensors_for_type %d = %d\n", i, num_sensors_for_type);
180
181
curr_arr = kcalloc(num_sensors_for_type, sizeof(*curr_arr), GFP_KERNEL);
182
if (!curr_arr) {
183
rc = -ENOMEM;
184
goto sensors_type_err;
185
}
186
187
num_active_sensor_types++;
188
sensors_by_type[i] = curr_arr;
189
}
190
191
for (i = 0 ; i < arr_size ; i++) {
192
type = le32_to_cpu(sensors_arr[i].type);
193
curr_arr = sensors_by_type[type];
194
flags = adjust_hwmon_flags(hdev, type, le32_to_cpu(sensors_arr[i].flags));
195
curr_arr[sensors_by_type_next_index[type]++] = flags;
196
}
197
198
channels_info = kcalloc(num_active_sensor_types + 1, sizeof(struct hwmon_channel_info *),
199
GFP_KERNEL);
200
if (!channels_info) {
201
rc = -ENOMEM;
202
goto channels_info_array_err;
203
}
204
205
for (i = 0 ; i < num_active_sensor_types ; i++) {
206
channels_info[i] = kzalloc(sizeof(*channels_info[i]), GFP_KERNEL);
207
if (!channels_info[i]) {
208
rc = -ENOMEM;
209
goto channel_info_err;
210
}
211
}
212
213
for (i = 0, j = 0 ; i < HWMON_NR_SENSOR_TYPES ; i++) {
214
if (!sensors_by_type[i])
215
continue;
216
217
channels_info[j]->type = i;
218
channels_info[j]->config = sensors_by_type[i];
219
j++;
220
}
221
222
hdev->hl_chip_info->info = (const struct hwmon_channel_info **)channels_info;
223
224
return 0;
225
226
channel_info_err:
227
for (i = 0 ; i < num_active_sensor_types ; i++) {
228
if (channels_info[i]) {
229
kfree(channels_info[i]->config);
230
kfree(channels_info[i]);
231
}
232
}
233
kfree(channels_info);
234
235
channels_info_array_err:
236
sensors_type_err:
237
for (i = 0 ; i < HWMON_NR_SENSOR_TYPES ; i++)
238
kfree(sensors_by_type[i]);
239
240
return rc;
241
}
242
243
static int hl_read(struct device *dev, enum hwmon_sensor_types type,
244
u32 attr, int channel, long *val)
245
{
246
struct hl_device *hdev = dev_get_drvdata(dev);
247
bool use_cpucp_enum;
248
u32 cpucp_attr;
249
int rc;
250
251
if (!hl_device_operational(hdev, NULL))
252
return -ENODEV;
253
254
use_cpucp_enum = (hdev->asic_prop.fw_app_cpu_boot_dev_sts0 &
255
CPU_BOOT_DEV_STS0_MAP_HWMON_EN) ? true : false;
256
257
switch (type) {
258
case hwmon_temp:
259
switch (attr) {
260
case hwmon_temp_input:
261
cpucp_attr = cpucp_temp_input;
262
break;
263
case hwmon_temp_max:
264
cpucp_attr = cpucp_temp_max;
265
break;
266
case hwmon_temp_crit:
267
cpucp_attr = cpucp_temp_crit;
268
break;
269
case hwmon_temp_max_hyst:
270
cpucp_attr = cpucp_temp_max_hyst;
271
break;
272
case hwmon_temp_crit_hyst:
273
cpucp_attr = cpucp_temp_crit_hyst;
274
break;
275
case hwmon_temp_offset:
276
cpucp_attr = cpucp_temp_offset;
277
break;
278
case hwmon_temp_highest:
279
cpucp_attr = cpucp_temp_highest;
280
break;
281
default:
282
return -EINVAL;
283
}
284
285
if (use_cpucp_enum)
286
rc = hl_get_temperature(hdev, channel, cpucp_attr, val);
287
else
288
rc = hl_get_temperature(hdev, channel, fixup_attr_legacy_fw(attr), val);
289
break;
290
case hwmon_in:
291
switch (attr) {
292
case hwmon_in_input:
293
cpucp_attr = cpucp_in_input;
294
break;
295
case hwmon_in_min:
296
cpucp_attr = cpucp_in_min;
297
break;
298
case hwmon_in_max:
299
cpucp_attr = cpucp_in_max;
300
break;
301
case hwmon_in_highest:
302
cpucp_attr = cpucp_in_highest;
303
break;
304
default:
305
return -EINVAL;
306
}
307
308
if (use_cpucp_enum)
309
rc = hl_get_voltage(hdev, channel, cpucp_attr, val);
310
else
311
rc = hl_get_voltage(hdev, channel, fixup_attr_legacy_fw(attr), val);
312
break;
313
case hwmon_curr:
314
switch (attr) {
315
case hwmon_curr_input:
316
cpucp_attr = cpucp_curr_input;
317
break;
318
case hwmon_curr_min:
319
cpucp_attr = cpucp_curr_min;
320
break;
321
case hwmon_curr_max:
322
cpucp_attr = cpucp_curr_max;
323
break;
324
case hwmon_curr_highest:
325
cpucp_attr = cpucp_curr_highest;
326
break;
327
default:
328
return -EINVAL;
329
}
330
331
if (use_cpucp_enum)
332
rc = hl_get_current(hdev, channel, cpucp_attr, val);
333
else
334
rc = hl_get_current(hdev, channel, fixup_attr_legacy_fw(attr), val);
335
break;
336
case hwmon_fan:
337
switch (attr) {
338
case hwmon_fan_input:
339
cpucp_attr = cpucp_fan_input;
340
break;
341
case hwmon_fan_min:
342
cpucp_attr = cpucp_fan_min;
343
break;
344
case hwmon_fan_max:
345
cpucp_attr = cpucp_fan_max;
346
break;
347
default:
348
return -EINVAL;
349
}
350
351
if (use_cpucp_enum)
352
rc = hl_get_fan_speed(hdev, channel, cpucp_attr, val);
353
else
354
rc = hl_get_fan_speed(hdev, channel, fixup_attr_legacy_fw(attr), val);
355
break;
356
case hwmon_pwm:
357
switch (attr) {
358
case hwmon_pwm_input:
359
cpucp_attr = cpucp_pwm_input;
360
break;
361
case hwmon_pwm_enable:
362
cpucp_attr = cpucp_pwm_enable;
363
break;
364
default:
365
return -EINVAL;
366
}
367
368
if (use_cpucp_enum)
369
rc = hl_get_pwm_info(hdev, channel, cpucp_attr, val);
370
else
371
/* no need for fixup as pwm was aligned from day 1 */
372
rc = hl_get_pwm_info(hdev, channel, attr, val);
373
break;
374
case hwmon_power:
375
switch (attr) {
376
case hwmon_power_input:
377
cpucp_attr = CPUCP_POWER_INPUT;
378
break;
379
case hwmon_power_input_highest:
380
cpucp_attr = CPUCP_POWER_INPUT_HIGHEST;
381
break;
382
default:
383
return -EINVAL;
384
}
385
386
if (use_cpucp_enum)
387
rc = hl_get_power(hdev, channel, cpucp_attr, val);
388
else
389
rc = hl_get_power(hdev, channel, fixup_attr_legacy_fw(attr), val);
390
break;
391
default:
392
return -EINVAL;
393
}
394
return rc;
395
}
396
397
static int hl_write(struct device *dev, enum hwmon_sensor_types type,
398
u32 attr, int channel, long val)
399
{
400
struct hl_device *hdev = dev_get_drvdata(dev);
401
u32 cpucp_attr;
402
bool use_cpucp_enum = (hdev->asic_prop.fw_app_cpu_boot_dev_sts0 &
403
CPU_BOOT_DEV_STS0_MAP_HWMON_EN) ? true : false;
404
405
if (!hl_device_operational(hdev, NULL))
406
return -ENODEV;
407
408
switch (type) {
409
case hwmon_temp:
410
switch (attr) {
411
case hwmon_temp_offset:
412
cpucp_attr = cpucp_temp_offset;
413
break;
414
case hwmon_temp_reset_history:
415
cpucp_attr = cpucp_temp_reset_history;
416
break;
417
default:
418
return -EINVAL;
419
}
420
421
if (use_cpucp_enum)
422
hl_set_temperature(hdev, channel, cpucp_attr, val);
423
else
424
hl_set_temperature(hdev, channel, fixup_attr_legacy_fw(attr), val);
425
break;
426
case hwmon_pwm:
427
switch (attr) {
428
case hwmon_pwm_input:
429
cpucp_attr = cpucp_pwm_input;
430
break;
431
case hwmon_pwm_enable:
432
cpucp_attr = cpucp_pwm_enable;
433
break;
434
default:
435
return -EINVAL;
436
}
437
438
if (use_cpucp_enum)
439
hl_set_pwm_info(hdev, channel, cpucp_attr, val);
440
else
441
/* no need for fixup as pwm was aligned from day 1 */
442
hl_set_pwm_info(hdev, channel, attr, val);
443
break;
444
case hwmon_in:
445
switch (attr) {
446
case hwmon_in_reset_history:
447
cpucp_attr = cpucp_in_reset_history;
448
break;
449
default:
450
return -EINVAL;
451
}
452
453
if (use_cpucp_enum)
454
hl_set_voltage(hdev, channel, cpucp_attr, val);
455
else
456
hl_set_voltage(hdev, channel, fixup_attr_legacy_fw(attr), val);
457
break;
458
case hwmon_curr:
459
switch (attr) {
460
case hwmon_curr_reset_history:
461
cpucp_attr = cpucp_curr_reset_history;
462
break;
463
default:
464
return -EINVAL;
465
}
466
467
if (use_cpucp_enum)
468
hl_set_current(hdev, channel, cpucp_attr, val);
469
else
470
hl_set_current(hdev, channel, fixup_attr_legacy_fw(attr), val);
471
break;
472
case hwmon_power:
473
switch (attr) {
474
case hwmon_power_reset_history:
475
cpucp_attr = CPUCP_POWER_RESET_INPUT_HISTORY;
476
break;
477
default:
478
return -EINVAL;
479
}
480
481
if (use_cpucp_enum)
482
hl_set_power(hdev, channel, cpucp_attr, val);
483
else
484
hl_set_power(hdev, channel, fixup_attr_legacy_fw(attr), val);
485
break;
486
default:
487
return -EINVAL;
488
}
489
return 0;
490
}
491
492
static umode_t hl_is_visible(const void *data, enum hwmon_sensor_types type,
493
u32 attr, int channel)
494
{
495
switch (type) {
496
case hwmon_temp:
497
switch (attr) {
498
case hwmon_temp_input:
499
case hwmon_temp_max:
500
case hwmon_temp_max_hyst:
501
case hwmon_temp_crit:
502
case hwmon_temp_crit_hyst:
503
case hwmon_temp_highest:
504
return 0444;
505
case hwmon_temp_offset:
506
return 0644;
507
case hwmon_temp_reset_history:
508
return 0200;
509
}
510
break;
511
case hwmon_in:
512
switch (attr) {
513
case hwmon_in_input:
514
case hwmon_in_min:
515
case hwmon_in_max:
516
case hwmon_in_highest:
517
return 0444;
518
case hwmon_in_reset_history:
519
return 0200;
520
}
521
break;
522
case hwmon_curr:
523
switch (attr) {
524
case hwmon_curr_input:
525
case hwmon_curr_min:
526
case hwmon_curr_max:
527
case hwmon_curr_highest:
528
return 0444;
529
case hwmon_curr_reset_history:
530
return 0200;
531
}
532
break;
533
case hwmon_fan:
534
switch (attr) {
535
case hwmon_fan_input:
536
case hwmon_fan_min:
537
case hwmon_fan_max:
538
return 0444;
539
}
540
break;
541
case hwmon_pwm:
542
switch (attr) {
543
case hwmon_pwm_input:
544
case hwmon_pwm_enable:
545
return 0644;
546
}
547
break;
548
case hwmon_power:
549
switch (attr) {
550
case hwmon_power_input:
551
case hwmon_power_input_highest:
552
return 0444;
553
case hwmon_power_reset_history:
554
return 0200;
555
}
556
break;
557
default:
558
break;
559
}
560
return 0;
561
}
562
563
static const struct hwmon_ops hl_hwmon_ops = {
564
.is_visible = hl_is_visible,
565
.read = hl_read,
566
.write = hl_write
567
};
568
569
int hl_get_temperature(struct hl_device *hdev,
570
int sensor_index, u32 attr, long *value)
571
{
572
struct cpucp_packet pkt;
573
u64 result;
574
int rc;
575
576
memset(&pkt, 0, sizeof(pkt));
577
578
pkt.ctl = cpu_to_le32(CPUCP_PACKET_TEMPERATURE_GET <<
579
CPUCP_PKT_CTL_OPCODE_SHIFT);
580
pkt.sensor_index = __cpu_to_le16(sensor_index);
581
pkt.type = __cpu_to_le16(attr);
582
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
583
0, &result);
584
585
*value = (long) result;
586
587
if (rc) {
588
if (rc != -EAGAIN)
589
dev_err_ratelimited(hdev->dev,
590
"Failed to get temperature from sensor %d, error %d\n",
591
sensor_index, rc);
592
*value = 0;
593
}
594
595
return rc;
596
}
597
598
int hl_set_temperature(struct hl_device *hdev,
599
int sensor_index, u32 attr, long value)
600
{
601
struct cpucp_packet pkt;
602
int rc;
603
604
memset(&pkt, 0, sizeof(pkt));
605
606
pkt.ctl = cpu_to_le32(CPUCP_PACKET_TEMPERATURE_SET <<
607
CPUCP_PKT_CTL_OPCODE_SHIFT);
608
pkt.sensor_index = __cpu_to_le16(sensor_index);
609
pkt.type = __cpu_to_le16(attr);
610
pkt.value = __cpu_to_le64(value);
611
612
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
613
0, NULL);
614
if (rc && rc != -EAGAIN)
615
dev_err_ratelimited(hdev->dev,
616
"Failed to set temperature of sensor %d, error %d\n",
617
sensor_index, rc);
618
619
return rc;
620
}
621
622
int hl_get_voltage(struct hl_device *hdev,
623
int sensor_index, u32 attr, long *value)
624
{
625
struct cpucp_packet pkt;
626
u64 result;
627
int rc;
628
629
memset(&pkt, 0, sizeof(pkt));
630
631
pkt.ctl = cpu_to_le32(CPUCP_PACKET_VOLTAGE_GET <<
632
CPUCP_PKT_CTL_OPCODE_SHIFT);
633
pkt.sensor_index = __cpu_to_le16(sensor_index);
634
pkt.type = __cpu_to_le16(attr);
635
636
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
637
0, &result);
638
639
*value = (long) result;
640
641
if (rc) {
642
if (rc != -EAGAIN)
643
dev_err_ratelimited(hdev->dev,
644
"Failed to get voltage from sensor %d, error %d\n",
645
sensor_index, rc);
646
*value = 0;
647
}
648
649
return rc;
650
}
651
652
int hl_get_current(struct hl_device *hdev,
653
int sensor_index, u32 attr, long *value)
654
{
655
struct cpucp_packet pkt;
656
u64 result;
657
int rc;
658
659
memset(&pkt, 0, sizeof(pkt));
660
661
pkt.ctl = cpu_to_le32(CPUCP_PACKET_CURRENT_GET <<
662
CPUCP_PKT_CTL_OPCODE_SHIFT);
663
pkt.sensor_index = __cpu_to_le16(sensor_index);
664
pkt.type = __cpu_to_le16(attr);
665
666
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
667
0, &result);
668
669
*value = (long) result;
670
671
if (rc) {
672
if (rc != -EAGAIN)
673
dev_err_ratelimited(hdev->dev,
674
"Failed to get current from sensor %d, error %d\n",
675
sensor_index, rc);
676
*value = 0;
677
}
678
679
return rc;
680
}
681
682
int hl_get_fan_speed(struct hl_device *hdev,
683
int sensor_index, u32 attr, long *value)
684
{
685
struct cpucp_packet pkt;
686
u64 result;
687
int rc;
688
689
memset(&pkt, 0, sizeof(pkt));
690
691
pkt.ctl = cpu_to_le32(CPUCP_PACKET_FAN_SPEED_GET <<
692
CPUCP_PKT_CTL_OPCODE_SHIFT);
693
pkt.sensor_index = __cpu_to_le16(sensor_index);
694
pkt.type = __cpu_to_le16(attr);
695
696
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
697
0, &result);
698
699
*value = (long) result;
700
701
if (rc) {
702
if (rc != -EAGAIN)
703
dev_err_ratelimited(hdev->dev,
704
"Failed to get fan speed from sensor %d, error %d\n",
705
sensor_index, rc);
706
*value = 0;
707
}
708
709
return rc;
710
}
711
712
int hl_get_pwm_info(struct hl_device *hdev,
713
int sensor_index, u32 attr, long *value)
714
{
715
struct cpucp_packet pkt;
716
u64 result;
717
int rc;
718
719
memset(&pkt, 0, sizeof(pkt));
720
721
pkt.ctl = cpu_to_le32(CPUCP_PACKET_PWM_GET <<
722
CPUCP_PKT_CTL_OPCODE_SHIFT);
723
pkt.sensor_index = __cpu_to_le16(sensor_index);
724
pkt.type = __cpu_to_le16(attr);
725
726
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
727
0, &result);
728
729
*value = (long) result;
730
731
if (rc) {
732
if (rc != -EAGAIN)
733
dev_err_ratelimited(hdev->dev,
734
"Failed to get pwm info from sensor %d, error %d\n",
735
sensor_index, rc);
736
*value = 0;
737
}
738
739
return rc;
740
}
741
742
void hl_set_pwm_info(struct hl_device *hdev, int sensor_index, u32 attr,
743
long value)
744
{
745
struct cpucp_packet pkt;
746
int rc;
747
748
memset(&pkt, 0, sizeof(pkt));
749
750
pkt.ctl = cpu_to_le32(CPUCP_PACKET_PWM_SET <<
751
CPUCP_PKT_CTL_OPCODE_SHIFT);
752
pkt.sensor_index = __cpu_to_le16(sensor_index);
753
pkt.type = __cpu_to_le16(attr);
754
pkt.value = cpu_to_le64(value);
755
756
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
757
0, NULL);
758
if (rc && rc != -EAGAIN)
759
dev_err_ratelimited(hdev->dev,
760
"Failed to set pwm info to sensor %d, error %d\n",
761
sensor_index, rc);
762
}
763
764
int hl_set_voltage(struct hl_device *hdev,
765
int sensor_index, u32 attr, long value)
766
{
767
struct cpucp_packet pkt;
768
int rc;
769
770
memset(&pkt, 0, sizeof(pkt));
771
772
pkt.ctl = cpu_to_le32(CPUCP_PACKET_VOLTAGE_SET <<
773
CPUCP_PKT_CTL_OPCODE_SHIFT);
774
pkt.sensor_index = __cpu_to_le16(sensor_index);
775
pkt.type = __cpu_to_le16(attr);
776
pkt.value = __cpu_to_le64(value);
777
778
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
779
0, NULL);
780
if (rc && rc != -EAGAIN)
781
dev_err_ratelimited(hdev->dev,
782
"Failed to set voltage of sensor %d, error %d\n",
783
sensor_index, rc);
784
785
return rc;
786
}
787
788
int hl_set_current(struct hl_device *hdev,
789
int sensor_index, u32 attr, long value)
790
{
791
struct cpucp_packet pkt;
792
int rc;
793
794
memset(&pkt, 0, sizeof(pkt));
795
796
pkt.ctl = cpu_to_le32(CPUCP_PACKET_CURRENT_SET <<
797
CPUCP_PKT_CTL_OPCODE_SHIFT);
798
pkt.sensor_index = __cpu_to_le16(sensor_index);
799
pkt.type = __cpu_to_le16(attr);
800
pkt.value = __cpu_to_le64(value);
801
802
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), 0, NULL);
803
if (rc && rc != -EAGAIN)
804
dev_err_ratelimited(hdev->dev,
805
"Failed to set current of sensor %d, error %d\n",
806
sensor_index, rc);
807
808
return rc;
809
}
810
811
int hl_set_power(struct hl_device *hdev,
812
int sensor_index, u32 attr, long value)
813
{
814
struct cpucp_packet pkt;
815
struct asic_fixed_properties *prop = &hdev->asic_prop;
816
int rc;
817
818
memset(&pkt, 0, sizeof(pkt));
819
820
if (prop->use_get_power_for_reset_history)
821
pkt.ctl = cpu_to_le32(CPUCP_PACKET_POWER_GET <<
822
CPUCP_PKT_CTL_OPCODE_SHIFT);
823
else
824
pkt.ctl = cpu_to_le32(CPUCP_PACKET_POWER_SET <<
825
CPUCP_PKT_CTL_OPCODE_SHIFT);
826
827
pkt.sensor_index = __cpu_to_le16(sensor_index);
828
pkt.type = __cpu_to_le16(attr);
829
pkt.value = __cpu_to_le64(value);
830
831
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
832
0, NULL);
833
if (rc && rc != -EAGAIN)
834
dev_err_ratelimited(hdev->dev,
835
"Failed to set power of sensor %d, error %d\n",
836
sensor_index, rc);
837
838
return rc;
839
}
840
841
int hl_get_power(struct hl_device *hdev,
842
int sensor_index, u32 attr, long *value)
843
{
844
struct cpucp_packet pkt;
845
u64 result;
846
int rc;
847
848
memset(&pkt, 0, sizeof(pkt));
849
850
pkt.ctl = cpu_to_le32(CPUCP_PACKET_POWER_GET <<
851
CPUCP_PKT_CTL_OPCODE_SHIFT);
852
pkt.sensor_index = __cpu_to_le16(sensor_index);
853
pkt.type = __cpu_to_le16(attr);
854
855
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
856
0, &result);
857
858
*value = (long) result;
859
860
if (rc) {
861
if (rc != -EAGAIN)
862
dev_err_ratelimited(hdev->dev,
863
"Failed to get power of sensor %d, error %d\n",
864
sensor_index, rc);
865
*value = 0;
866
}
867
868
return rc;
869
}
870
871
int hl_hwmon_init(struct hl_device *hdev)
872
{
873
struct device *dev = hdev->pdev ? &hdev->pdev->dev : hdev->dev;
874
struct asic_fixed_properties *prop = &hdev->asic_prop;
875
int rc;
876
877
if ((hdev->hwmon_initialized) || !(hdev->cpu_queues_enable))
878
return 0;
879
880
if (hdev->hl_chip_info->info) {
881
hdev->hl_chip_info->ops = &hl_hwmon_ops;
882
883
hdev->hwmon_dev = hwmon_device_register_with_info(dev,
884
prop->cpucp_info.card_name, hdev,
885
hdev->hl_chip_info, NULL);
886
if (IS_ERR(hdev->hwmon_dev)) {
887
rc = PTR_ERR(hdev->hwmon_dev);
888
dev_err(hdev->dev,
889
"Unable to register hwmon device: %d\n", rc);
890
return rc;
891
}
892
893
dev_info(hdev->dev, "%s: add sensors information\n",
894
dev_name(hdev->hwmon_dev));
895
896
hdev->hwmon_initialized = true;
897
} else {
898
dev_info(hdev->dev, "no available sensors\n");
899
}
900
901
return 0;
902
}
903
904
void hl_hwmon_fini(struct hl_device *hdev)
905
{
906
if (!hdev->hwmon_initialized)
907
return;
908
909
hwmon_device_unregister(hdev->hwmon_dev);
910
}
911
912
void hl_hwmon_release_resources(struct hl_device *hdev)
913
{
914
const struct hwmon_channel_info * const *channel_info_arr;
915
int i = 0;
916
917
if (!hdev->hl_chip_info->info)
918
return;
919
920
channel_info_arr = hdev->hl_chip_info->info;
921
922
while (channel_info_arr[i]) {
923
kfree(channel_info_arr[i]->config);
924
kfree(channel_info_arr[i]);
925
i++;
926
}
927
928
kfree(channel_info_arr);
929
930
hdev->hl_chip_info->info = NULL;
931
}
932
933