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