xref: /linux/drivers/accel/habanalabs/common/hwmon.c (revision 84b9b44b)
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(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(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(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 
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 
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 
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 
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 
582 	dev_dbg(hdev->dev, "get temp, ctl 0x%x, sensor %d, type %d\n",
583 		pkt.ctl, pkt.sensor_index, pkt.type);
584 
585 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
586 						0, &result);
587 
588 	*value = (long) result;
589 
590 	if (rc) {
591 		dev_err(hdev->dev,
592 			"Failed to get temperature from sensor %d, error %d\n",
593 			sensor_index, rc);
594 		*value = 0;
595 	}
596 
597 	return rc;
598 }
599 
600 int hl_set_temperature(struct hl_device *hdev,
601 			int sensor_index, u32 attr, long value)
602 {
603 	struct cpucp_packet pkt;
604 	int rc;
605 
606 	memset(&pkt, 0, sizeof(pkt));
607 
608 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_TEMPERATURE_SET <<
609 				CPUCP_PKT_CTL_OPCODE_SHIFT);
610 	pkt.sensor_index = __cpu_to_le16(sensor_index);
611 	pkt.type = __cpu_to_le16(attr);
612 	pkt.value = __cpu_to_le64(value);
613 
614 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
615 						0, NULL);
616 
617 	if (rc)
618 		dev_err(hdev->dev,
619 			"Failed to set temperature of sensor %d, error %d\n",
620 			sensor_index, rc);
621 
622 	return rc;
623 }
624 
625 int hl_get_voltage(struct hl_device *hdev,
626 			int sensor_index, u32 attr, long *value)
627 {
628 	struct cpucp_packet pkt;
629 	u64 result;
630 	int rc;
631 
632 	memset(&pkt, 0, sizeof(pkt));
633 
634 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_VOLTAGE_GET <<
635 				CPUCP_PKT_CTL_OPCODE_SHIFT);
636 	pkt.sensor_index = __cpu_to_le16(sensor_index);
637 	pkt.type = __cpu_to_le16(attr);
638 
639 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
640 						0, &result);
641 
642 	*value = (long) result;
643 
644 	if (rc) {
645 		dev_err(hdev->dev,
646 			"Failed to get voltage from sensor %d, error %d\n",
647 			sensor_index, rc);
648 		*value = 0;
649 	}
650 
651 	return rc;
652 }
653 
654 int hl_get_current(struct hl_device *hdev,
655 			int sensor_index, u32 attr, long *value)
656 {
657 	struct cpucp_packet pkt;
658 	u64 result;
659 	int rc;
660 
661 	memset(&pkt, 0, sizeof(pkt));
662 
663 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_CURRENT_GET <<
664 				CPUCP_PKT_CTL_OPCODE_SHIFT);
665 	pkt.sensor_index = __cpu_to_le16(sensor_index);
666 	pkt.type = __cpu_to_le16(attr);
667 
668 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
669 						0, &result);
670 
671 	*value = (long) result;
672 
673 	if (rc) {
674 		dev_err(hdev->dev,
675 			"Failed to get current from sensor %d, error %d\n",
676 			sensor_index, rc);
677 		*value = 0;
678 	}
679 
680 	return rc;
681 }
682 
683 int hl_get_fan_speed(struct hl_device *hdev,
684 			int sensor_index, u32 attr, long *value)
685 {
686 	struct cpucp_packet pkt;
687 	u64 result;
688 	int rc;
689 
690 	memset(&pkt, 0, sizeof(pkt));
691 
692 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_FAN_SPEED_GET <<
693 				CPUCP_PKT_CTL_OPCODE_SHIFT);
694 	pkt.sensor_index = __cpu_to_le16(sensor_index);
695 	pkt.type = __cpu_to_le16(attr);
696 
697 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
698 						0, &result);
699 
700 	*value = (long) result;
701 
702 	if (rc) {
703 		dev_err(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 		dev_err(hdev->dev,
733 			"Failed to get pwm info from sensor %d, error %d\n",
734 			sensor_index, rc);
735 		*value = 0;
736 	}
737 
738 	return rc;
739 }
740 
741 void hl_set_pwm_info(struct hl_device *hdev, int sensor_index, u32 attr,
742 			long value)
743 {
744 	struct cpucp_packet pkt;
745 	int rc;
746 
747 	memset(&pkt, 0, sizeof(pkt));
748 
749 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_PWM_SET <<
750 				CPUCP_PKT_CTL_OPCODE_SHIFT);
751 	pkt.sensor_index = __cpu_to_le16(sensor_index);
752 	pkt.type = __cpu_to_le16(attr);
753 	pkt.value = cpu_to_le64(value);
754 
755 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
756 						0, NULL);
757 
758 	if (rc)
759 		dev_err(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 
781 	if (rc)
782 		dev_err(hdev->dev,
783 			"Failed to set voltage of sensor %d, error %d\n",
784 			sensor_index, rc);
785 
786 	return rc;
787 }
788 
789 int hl_set_current(struct hl_device *hdev,
790 			int sensor_index, u32 attr, long value)
791 {
792 	struct cpucp_packet pkt;
793 	int rc;
794 
795 	memset(&pkt, 0, sizeof(pkt));
796 
797 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_CURRENT_SET <<
798 				CPUCP_PKT_CTL_OPCODE_SHIFT);
799 	pkt.sensor_index = __cpu_to_le16(sensor_index);
800 	pkt.type = __cpu_to_le16(attr);
801 	pkt.value = __cpu_to_le64(value);
802 
803 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
804 						0, NULL);
805 
806 	if (rc)
807 		dev_err(hdev->dev,
808 			"Failed to set current of sensor %d, error %d\n",
809 			sensor_index, rc);
810 
811 	return rc;
812 }
813 
814 int hl_set_power(struct hl_device *hdev,
815 			int sensor_index, u32 attr, long value)
816 {
817 	struct cpucp_packet pkt;
818 	struct asic_fixed_properties *prop = &hdev->asic_prop;
819 	int rc;
820 
821 	memset(&pkt, 0, sizeof(pkt));
822 
823 	if (prop->use_get_power_for_reset_history)
824 		pkt.ctl = cpu_to_le32(CPUCP_PACKET_POWER_GET <<
825 				CPUCP_PKT_CTL_OPCODE_SHIFT);
826 	else
827 		pkt.ctl = cpu_to_le32(CPUCP_PACKET_POWER_SET <<
828 				CPUCP_PKT_CTL_OPCODE_SHIFT);
829 
830 	pkt.sensor_index = __cpu_to_le16(sensor_index);
831 	pkt.type = __cpu_to_le16(attr);
832 	pkt.value = __cpu_to_le64(value);
833 
834 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
835 						0, NULL);
836 
837 	if (rc)
838 		dev_err(hdev->dev,
839 			"Failed to set power of sensor %d, error %d\n",
840 			sensor_index, rc);
841 
842 	return rc;
843 }
844 
845 int hl_get_power(struct hl_device *hdev,
846 			int sensor_index, u32 attr, long *value)
847 {
848 	struct cpucp_packet pkt;
849 	u64 result;
850 	int rc;
851 
852 	memset(&pkt, 0, sizeof(pkt));
853 
854 	pkt.ctl = cpu_to_le32(CPUCP_PACKET_POWER_GET <<
855 				CPUCP_PKT_CTL_OPCODE_SHIFT);
856 	pkt.sensor_index = __cpu_to_le16(sensor_index);
857 	pkt.type = __cpu_to_le16(attr);
858 
859 	rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
860 						0, &result);
861 
862 	*value = (long) result;
863 
864 	if (rc) {
865 		dev_err(hdev->dev,
866 			"Failed to get power of sensor %d, error %d\n",
867 			sensor_index, rc);
868 		*value = 0;
869 	}
870 
871 	return rc;
872 }
873 
874 int hl_hwmon_init(struct hl_device *hdev)
875 {
876 	struct device *dev = hdev->pdev ? &hdev->pdev->dev : hdev->dev;
877 	struct asic_fixed_properties *prop = &hdev->asic_prop;
878 	int rc;
879 
880 	if ((hdev->hwmon_initialized) || !(hdev->cpu_queues_enable))
881 		return 0;
882 
883 	if (hdev->hl_chip_info->info) {
884 		hdev->hl_chip_info->ops = &hl_hwmon_ops;
885 
886 		hdev->hwmon_dev = hwmon_device_register_with_info(dev,
887 					prop->cpucp_info.card_name, hdev,
888 					hdev->hl_chip_info, NULL);
889 		if (IS_ERR(hdev->hwmon_dev)) {
890 			rc = PTR_ERR(hdev->hwmon_dev);
891 			dev_err(hdev->dev,
892 				"Unable to register hwmon device: %d\n", rc);
893 			return rc;
894 		}
895 
896 		dev_info(hdev->dev, "%s: add sensors information\n",
897 			dev_name(hdev->hwmon_dev));
898 
899 		hdev->hwmon_initialized = true;
900 	} else {
901 		dev_info(hdev->dev, "no available sensors\n");
902 	}
903 
904 	return 0;
905 }
906 
907 void hl_hwmon_fini(struct hl_device *hdev)
908 {
909 	if (!hdev->hwmon_initialized)
910 		return;
911 
912 	hwmon_device_unregister(hdev->hwmon_dev);
913 }
914 
915 void hl_hwmon_release_resources(struct hl_device *hdev)
916 {
917 	const struct hwmon_channel_info * const *channel_info_arr;
918 	int i = 0;
919 
920 	if (!hdev->hl_chip_info->info)
921 		return;
922 
923 	channel_info_arr = hdev->hl_chip_info->info;
924 
925 	while (channel_info_arr[i]) {
926 		kfree(channel_info_arr[i]->config);
927 		kfree(channel_info_arr[i]);
928 		i++;
929 	}
930 
931 	kfree(channel_info_arr);
932 
933 	hdev->hl_chip_info->info = NULL;
934 }
935