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