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 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 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 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 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 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 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 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 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 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 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 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 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 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 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