1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Intel Speed Select -- Enumerate and control features for TPMI Interface 4 * Copyright (c) 2022 Intel Corporation. 5 */ 6 7 #include <linux/isst_if.h> 8 #include "isst.h" 9 10 int tpmi_process_ioctl(int ioctl_no, void *info) 11 { 12 const char *pathname = "/dev/isst_interface"; 13 int fd; 14 15 if (is_debug_enabled()) { 16 debug_printf("Issue IOCTL: "); 17 switch (ioctl_no) { 18 case ISST_IF_CORE_POWER_STATE: 19 debug_printf("ISST_IF_CORE_POWER_STATE\n"); 20 break; 21 case ISST_IF_CLOS_PARAM: 22 debug_printf("ISST_IF_CLOS_PARAM\n"); 23 break; 24 case ISST_IF_CLOS_ASSOC: 25 debug_printf("ISST_IF_CLOS_ASSOC\n"); 26 break; 27 case ISST_IF_PERF_LEVELS: 28 debug_printf("ISST_IF_PERF_LEVELS\n"); 29 break; 30 case ISST_IF_PERF_SET_LEVEL: 31 debug_printf("ISST_IF_PERF_SET_LEVEL\n"); 32 break; 33 case ISST_IF_PERF_SET_FEATURE: 34 debug_printf("ISST_IF_PERF_SET_FEATURE\n"); 35 break; 36 case ISST_IF_GET_PERF_LEVEL_INFO: 37 debug_printf("ISST_IF_GET_PERF_LEVEL_INFO\n"); 38 break; 39 case ISST_IF_GET_PERF_LEVEL_CPU_MASK: 40 debug_printf("ISST_IF_GET_PERF_LEVEL_CPU_MASK\n"); 41 break; 42 case ISST_IF_GET_BASE_FREQ_INFO: 43 debug_printf("ISST_IF_GET_BASE_FREQ_INFO\n"); 44 break; 45 case ISST_IF_GET_BASE_FREQ_CPU_MASK: 46 debug_printf("ISST_IF_GET_BASE_FREQ_CPU_MASK\n"); 47 break; 48 case ISST_IF_GET_TURBO_FREQ_INFO: 49 debug_printf("ISST_IF_GET_TURBO_FREQ_INFO\n"); 50 break; 51 case ISST_IF_COUNT_TPMI_INSTANCES: 52 debug_printf("ISST_IF_COUNT_TPMI_INSTANCES\n"); 53 break; 54 default: 55 debug_printf("%d\n", ioctl_no); 56 break; 57 } 58 } 59 60 fd = open(pathname, O_RDWR); 61 if (fd < 0) 62 return -1; 63 64 if (ioctl(fd, ioctl_no, info) == -1) { 65 debug_printf("IOCTL %d Failed\n", ioctl_no); 66 close(fd); 67 return -1; 68 } 69 70 close(fd); 71 72 return 0; 73 } 74 75 static int tpmi_get_disp_freq_multiplier(void) 76 { 77 return 1; 78 } 79 80 static int tpmi_get_trl_max_levels(void) 81 { 82 return TRL_MAX_LEVELS; 83 } 84 85 static char *tpmi_get_trl_level_name(int level) 86 { 87 switch (level) { 88 case 0: 89 return "level-0"; 90 case 1: 91 return "level-1"; 92 case 2: 93 return "level-2"; 94 case 3: 95 return "level-3"; 96 case 4: 97 return "level-4"; 98 case 5: 99 return "level-5"; 100 case 6: 101 return "level-6"; 102 case 7: 103 return "level-7"; 104 default: 105 return NULL; 106 } 107 } 108 109 110 static void tpmi_update_platform_param(enum isst_platform_param param, int value) 111 { 112 /* No params need to be updated for now */ 113 } 114 115 static int tpmi_is_punit_valid(struct isst_id *id) 116 { 117 struct isst_tpmi_instance_count info; 118 int ret; 119 120 if (id->punit < 0) 121 return 0; 122 123 info.socket_id = id->pkg; 124 ret = tpmi_process_ioctl(ISST_IF_COUNT_TPMI_INSTANCES, &info); 125 if (ret == -1) 126 return 0; 127 128 if (info.valid_mask & BIT(id->punit)) 129 return 1; 130 131 return 0; 132 } 133 134 static int tpmi_read_pm_config(struct isst_id *id, int *cp_state, int *cp_cap) 135 { 136 struct isst_core_power info; 137 int ret; 138 139 info.get_set = 0; 140 info.socket_id = id->pkg; 141 info.power_domain_id = id->punit; 142 ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info); 143 if (ret == -1) 144 return ret; 145 146 *cp_state = info.enable; 147 *cp_cap = info.supported; 148 149 return 0; 150 } 151 152 int tpmi_get_config_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev) 153 { 154 struct isst_perf_level_info info; 155 int ret; 156 157 info.socket_id = id->pkg; 158 info.power_domain_id = id->punit; 159 160 ret = tpmi_process_ioctl(ISST_IF_PERF_LEVELS, &info); 161 if (ret == -1) 162 return ret; 163 164 pkg_dev->version = info.feature_rev; 165 pkg_dev->levels = info.max_level; 166 pkg_dev->locked = info.locked; 167 pkg_dev->current_level = info.current_level; 168 pkg_dev->locked = info.locked; 169 pkg_dev->enabled = info.enabled; 170 171 return 0; 172 } 173 174 static int tpmi_get_ctdp_control(struct isst_id *id, int config_index, 175 struct isst_pkg_ctdp_level_info *ctdp_level) 176 { 177 struct isst_core_power core_power_info; 178 struct isst_perf_level_info info; 179 int level_mask; 180 int ret; 181 182 info.socket_id = id->pkg; 183 info.power_domain_id = id->punit; 184 185 ret = tpmi_process_ioctl(ISST_IF_PERF_LEVELS, &info); 186 if (ret == -1) 187 return -1; 188 189 if (config_index != 0xff) 190 level_mask = 1 << config_index; 191 else 192 level_mask = config_index; 193 194 if (!(info.level_mask & level_mask)) 195 return -1; 196 197 ctdp_level->fact_support = info.sst_tf_support; 198 ctdp_level->pbf_support = info.sst_bf_support; 199 ctdp_level->fact_enabled = !!(info.feature_state & BIT(1)); 200 ctdp_level->pbf_enabled = !!(info.feature_state & BIT(0)); 201 202 core_power_info.get_set = 0; 203 core_power_info.socket_id = id->pkg; 204 core_power_info.power_domain_id = id->punit; 205 206 ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &core_power_info); 207 if (ret == -1) 208 return ret; 209 210 ctdp_level->sst_cp_support = core_power_info.supported; 211 ctdp_level->sst_cp_enabled = core_power_info.enable; 212 213 debug_printf 214 ("cpu:%d CONFIG_TDP_GET_TDP_CONTROL fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n", 215 id->cpu, ctdp_level->fact_support, ctdp_level->pbf_support, 216 ctdp_level->fact_enabled, ctdp_level->pbf_enabled); 217 218 return 0; 219 } 220 221 static int tpmi_get_tdp_info(struct isst_id *id, int config_index, 222 struct isst_pkg_ctdp_level_info *ctdp_level) 223 { 224 struct isst_perf_level_data_info info; 225 int ret; 226 227 info.socket_id = id->pkg; 228 info.power_domain_id = id->punit; 229 info.level = config_index; 230 231 ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info); 232 if (ret == -1) 233 return ret; 234 235 ctdp_level->pkg_tdp = info.thermal_design_power_w; 236 ctdp_level->tdp_ratio = info.tdp_ratio; 237 ctdp_level->sse_p1 = info.base_freq_mhz; 238 ctdp_level->avx2_p1 = info.base_freq_avx2_mhz; 239 ctdp_level->avx512_p1 = info.base_freq_avx512_mhz; 240 ctdp_level->amx_p1 = info.base_freq_amx_mhz; 241 242 ctdp_level->t_proc_hot = info.tjunction_max_c; 243 ctdp_level->mem_freq = info.max_memory_freq_mhz; 244 ctdp_level->cooling_type = info.cooling_type; 245 246 ctdp_level->uncore_p0 = info.p0_fabric_freq_mhz; 247 ctdp_level->uncore_p1 = info.p1_fabric_freq_mhz; 248 ctdp_level->uncore_pm = info.pm_fabric_freq_mhz; 249 250 debug_printf 251 ("cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO tdp_ratio:%d pkg_tdp:%d ctdp_level->t_proc_hot:%d\n", 252 id->cpu, config_index, ctdp_level->tdp_ratio, ctdp_level->pkg_tdp, 253 ctdp_level->t_proc_hot); 254 255 return 0; 256 } 257 258 static int tpmi_get_pwr_info(struct isst_id *id, int config_index, 259 struct isst_pkg_ctdp_level_info *ctdp_level) 260 { 261 /* TBD */ 262 ctdp_level->pkg_max_power = 0; 263 ctdp_level->pkg_min_power = 0; 264 265 debug_printf 266 ("cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO pkg_max_power:%d pkg_min_power:%d\n", 267 id->cpu, config_index, ctdp_level->pkg_max_power, 268 ctdp_level->pkg_min_power); 269 270 return 0; 271 } 272 273 int tpmi_get_coremask_info(struct isst_id *id, int config_index, 274 struct isst_pkg_ctdp_level_info *ctdp_level) 275 { 276 struct isst_perf_level_cpu_mask info; 277 int ret, cpu_count; 278 279 info.socket_id = id->pkg; 280 info.power_domain_id = id->punit; 281 info.level = config_index; 282 info.punit_cpu_map = 1; 283 284 ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_CPU_MASK, &info); 285 if (ret == -1) 286 return ret; 287 288 set_cpu_mask_from_punit_coremask(id, info.mask, 289 ctdp_level->core_cpumask_size, 290 ctdp_level->core_cpumask, &cpu_count); 291 ctdp_level->cpu_count = cpu_count; 292 293 debug_printf("cpu:%d ctdp:%d core_mask ino cpu count:%d\n", 294 id->cpu, config_index, ctdp_level->cpu_count); 295 296 return 0; 297 } 298 299 static int tpmi_get_get_trls(struct isst_id *id, int config_index, 300 struct isst_pkg_ctdp_level_info *ctdp_level) 301 { 302 struct isst_perf_level_data_info info; 303 int ret, i, j; 304 305 info.socket_id = id->pkg; 306 info.power_domain_id = id->punit; 307 info.level = config_index; 308 309 ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info); 310 if (ret == -1) 311 return ret; 312 313 if (info.max_buckets > TRL_MAX_BUCKETS) 314 info.max_buckets = TRL_MAX_BUCKETS; 315 316 if (info.max_trl_levels > TRL_MAX_LEVELS) 317 info.max_trl_levels = TRL_MAX_LEVELS; 318 319 for (i = 0; i < info.max_trl_levels; ++i) 320 for (j = 0; j < info.max_buckets; ++j) 321 ctdp_level->trl_ratios[i][j] = info.trl_freq_mhz[i][j]; 322 323 return 0; 324 } 325 326 static int tpmi_get_get_trl(struct isst_id *id, int level, int config_index, 327 int *trl) 328 { 329 struct isst_pkg_ctdp_level_info ctdp_level; 330 int ret, i; 331 332 ret = tpmi_get_get_trls(id, config_index, &ctdp_level); 333 if (ret) 334 return ret; 335 336 /* FIX ME: Just return for level 0 */ 337 for (i = 0; i < 8; ++i) 338 trl[i] = ctdp_level.trl_ratios[0][i]; 339 340 return 0; 341 } 342 343 static int tpmi_get_trl_bucket_info(struct isst_id *id, int config_index, 344 unsigned long long *buckets_info) 345 { 346 struct isst_perf_level_data_info info; 347 unsigned char *mask = (unsigned char *)buckets_info; 348 int ret, i; 349 350 info.socket_id = id->pkg; 351 info.power_domain_id = id->punit; 352 info.level = config_index; 353 354 ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info); 355 if (ret == -1) 356 return ret; 357 358 if (info.max_buckets > TRL_MAX_BUCKETS) 359 info.max_buckets = TRL_MAX_BUCKETS; 360 361 for (i = 0; i < info.max_buckets; ++i) 362 mask[i] = info.bucket_core_counts[i]; 363 364 debug_printf("cpu:%d TRL bucket info: 0x%llx\n", id->cpu, 365 *buckets_info); 366 367 return 0; 368 } 369 370 static int tpmi_set_tdp_level(struct isst_id *id, int tdp_level) 371 { 372 struct isst_perf_level_control info; 373 int ret; 374 375 info.socket_id = id->pkg; 376 info.power_domain_id = id->punit; 377 info.level = tdp_level; 378 379 ret = tpmi_process_ioctl(ISST_IF_PERF_SET_LEVEL, &info); 380 if (ret == -1) 381 return ret; 382 383 return 0; 384 } 385 386 static int _pbf_get_coremask_info(struct isst_id *id, int config_index, 387 struct isst_pbf_info *pbf_info) 388 { 389 struct isst_perf_level_cpu_mask info; 390 int ret, cpu_count; 391 392 info.socket_id = id->pkg; 393 info.power_domain_id = id->punit; 394 info.level = config_index; 395 info.punit_cpu_map = 1; 396 397 ret = tpmi_process_ioctl(ISST_IF_GET_BASE_FREQ_CPU_MASK, &info); 398 if (ret == -1) 399 return ret; 400 401 set_cpu_mask_from_punit_coremask(id, info.mask, 402 pbf_info->core_cpumask_size, 403 pbf_info->core_cpumask, &cpu_count); 404 405 debug_printf("cpu:%d ctdp:%d pbf core_mask info cpu count:%d\n", 406 id->cpu, config_index, cpu_count); 407 408 return 0; 409 } 410 411 static int tpmi_get_pbf_info(struct isst_id *id, int level, 412 struct isst_pbf_info *pbf_info) 413 { 414 struct isst_base_freq_info info; 415 int ret; 416 417 info.socket_id = id->pkg; 418 info.power_domain_id = id->punit; 419 info.level = level; 420 421 ret = tpmi_process_ioctl(ISST_IF_GET_BASE_FREQ_INFO, &info); 422 if (ret == -1) 423 return ret; 424 425 pbf_info->p1_low = info.low_base_freq_mhz; 426 pbf_info->p1_high = info.high_base_freq_mhz; 427 pbf_info->tdp = info.thermal_design_power_w; 428 pbf_info->t_prochot = info.tjunction_max_c; 429 430 debug_printf("cpu:%d ctdp:%d pbf info:%d:%d:%d:%d\n", 431 id->cpu, level, pbf_info->p1_low, pbf_info->p1_high, 432 pbf_info->tdp, pbf_info->t_prochot); 433 434 return _pbf_get_coremask_info(id, level, pbf_info); 435 } 436 437 static int tpmi_set_pbf_fact_status(struct isst_id *id, int pbf, int enable) 438 { 439 struct isst_pkg_ctdp pkg_dev; 440 struct isst_pkg_ctdp_level_info ctdp_level; 441 int current_level; 442 struct isst_perf_feature_control info; 443 int ret; 444 445 ret = isst_get_ctdp_levels(id, &pkg_dev); 446 if (ret) 447 debug_printf("cpu:%d No support for dynamic ISST\n", id->cpu); 448 449 current_level = pkg_dev.current_level; 450 451 ret = isst_get_ctdp_control(id, current_level, &ctdp_level); 452 if (ret) 453 return ret; 454 455 info.socket_id = id->pkg; 456 info.power_domain_id = id->punit; 457 458 info.feature = 0; 459 460 if (pbf) { 461 if (ctdp_level.fact_enabled) 462 info.feature |= BIT(1); 463 464 if (enable) 465 info.feature |= BIT(0); 466 else 467 info.feature &= ~BIT(0); 468 } else { 469 470 if (enable && !ctdp_level.sst_cp_enabled) 471 isst_display_error_info_message(0, 472 "Make sure to execute before: core-power enable", 473 0, 0); 474 475 if (ctdp_level.pbf_enabled) 476 info.feature |= BIT(0); 477 478 if (enable) 479 info.feature |= BIT(1); 480 else 481 info.feature &= ~BIT(1); 482 } 483 484 ret = tpmi_process_ioctl(ISST_IF_PERF_SET_FEATURE, &info); 485 if (ret == -1) 486 return ret; 487 488 return 0; 489 } 490 491 static int tpmi_get_fact_info(struct isst_id *id, int level, int fact_bucket, 492 struct isst_fact_info *fact_info) 493 { 494 struct isst_turbo_freq_info info; 495 int i, j; 496 int ret; 497 498 info.socket_id = id->pkg; 499 info.power_domain_id = id->punit; 500 info.level = level; 501 502 ret = tpmi_process_ioctl(ISST_IF_GET_TURBO_FREQ_INFO, &info); 503 if (ret == -1) 504 return ret; 505 506 for (i = 0; i < info.max_clip_freqs; ++i) 507 fact_info->lp_ratios[i] = info.lp_clip_freq_mhz[i]; 508 509 if (info.max_buckets > TRL_MAX_BUCKETS) 510 info.max_buckets = TRL_MAX_BUCKETS; 511 512 if (info.max_trl_levels > TRL_MAX_LEVELS) 513 info.max_trl_levels = TRL_MAX_LEVELS; 514 515 for (i = 0; i < info.max_trl_levels; ++i) { 516 for (j = 0; j < info.max_buckets; ++j) 517 fact_info->bucket_info[j].hp_ratios[i] = 518 info.trl_freq_mhz[i][j]; 519 } 520 521 for (i = 0; i < info.max_buckets; ++i) 522 fact_info->bucket_info[i].hp_cores = info.bucket_core_counts[i]; 523 524 return 0; 525 } 526 527 static void _set_uncore_min_max(struct isst_id *id, int max, int freq) 528 { 529 DIR *dir; 530 FILE *filep; 531 struct dirent *entry; 532 char buffer[512]; 533 unsigned int tmp_id; 534 int ret; 535 536 dir = opendir("/sys/devices/system/cpu/intel_uncore_frequency/"); 537 if (!dir) 538 return; 539 540 while ((entry = readdir(dir)) != NULL ) { 541 /* Check domain_id */ 542 snprintf(buffer, sizeof(buffer), 543 "/sys/devices/system/cpu/intel_uncore_frequency/%s/domain_id", entry->d_name); 544 545 filep = fopen(buffer, "r"); 546 if (!filep) 547 goto end; 548 549 ret = fscanf(filep, "%u", &tmp_id); 550 fclose(filep); 551 if (ret != 1) 552 goto end; 553 554 if (tmp_id != id->punit) 555 continue; 556 557 /* Check package_id */ 558 snprintf(buffer, sizeof(buffer), 559 "/sys/devices/system/cpu/intel_uncore_frequency/%s/package_id", entry->d_name); 560 561 filep = fopen(buffer, "r"); 562 if (!filep) 563 goto end; 564 565 ret = fscanf(filep, "%u", &tmp_id); 566 fclose(filep); 567 568 if (ret != 1) 569 goto end; 570 571 if (tmp_id != id->pkg) 572 continue; 573 574 /* Found the right sysfs path, adjust and quit */ 575 if (max) 576 snprintf(buffer, sizeof(buffer), 577 "/sys/devices/system/cpu/intel_uncore_frequency/%s/max_freq_khz", entry->d_name); 578 else 579 snprintf(buffer, sizeof(buffer), 580 "/sys/devices/system/cpu/intel_uncore_frequency/%s/min_freq_khz", entry->d_name); 581 582 filep = fopen(buffer, "w"); 583 if (!filep) 584 goto end; 585 586 fprintf(filep, "%d\n", freq); 587 fclose(filep); 588 break; 589 } 590 591 end: 592 closedir(dir); 593 } 594 595 static void tpmi_adjust_uncore_freq(struct isst_id *id, int config_index, 596 struct isst_pkg_ctdp_level_info *ctdp_level) 597 { 598 struct isst_perf_level_data_info info; 599 int ret; 600 601 info.socket_id = id->pkg; 602 info.power_domain_id = id->punit; 603 info.level = config_index; 604 605 ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info); 606 if (ret == -1) 607 return; 608 609 ctdp_level->uncore_p0 = info.p0_fabric_freq_mhz; 610 ctdp_level->uncore_p1 = info.p1_fabric_freq_mhz; 611 ctdp_level->uncore_pm = info.pm_fabric_freq_mhz; 612 613 if (ctdp_level->uncore_pm) 614 _set_uncore_min_max(id, 0, ctdp_level->uncore_pm * 100000); 615 616 if (ctdp_level->uncore_p0) 617 _set_uncore_min_max(id, 1, ctdp_level->uncore_p0 * 100000); 618 619 return; 620 } 621 622 static int tpmi_get_clos_information(struct isst_id *id, int *enable, int *type) 623 { 624 struct isst_core_power info; 625 int ret; 626 627 info.get_set = 0; 628 info.socket_id = id->pkg; 629 info.power_domain_id = id->punit; 630 ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info); 631 if (ret == -1) 632 return ret; 633 634 *enable = info.enable; 635 *type = info.priority_type; 636 637 return 0; 638 } 639 640 static int tpmi_pm_qos_config(struct isst_id *id, int enable_clos, 641 int priority_type) 642 { 643 struct isst_core_power info; 644 int i, ret, saved_punit; 645 646 info.get_set = 1; 647 info.socket_id = id->pkg; 648 info.power_domain_id = id->punit; 649 info.enable = enable_clos; 650 info.priority_type = priority_type; 651 652 saved_punit = id->punit; 653 654 /* Set for all other dies also. This is per package setting */ 655 for (i = 0; i < MAX_PUNIT_PER_DIE; i++) { 656 id->punit = i; 657 if (isst_is_punit_valid(id)) { 658 info.power_domain_id = i; 659 ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info); 660 if (ret == -1) { 661 id->punit = saved_punit; 662 return ret; 663 } 664 } 665 } 666 667 id->punit = saved_punit; 668 669 return 0; 670 } 671 672 int tpmi_pm_get_clos(struct isst_id *id, int clos, 673 struct isst_clos_config *clos_config) 674 { 675 struct isst_clos_param info; 676 int ret; 677 678 info.get_set = 0; 679 info.socket_id = id->pkg; 680 info.power_domain_id = id->punit; 681 info.clos = clos; 682 683 ret = tpmi_process_ioctl(ISST_IF_CLOS_PARAM, &info); 684 if (ret == -1) 685 return ret; 686 687 clos_config->epp = 0; 688 clos_config->clos_prop_prio = info.prop_prio; 689 clos_config->clos_min = info.min_freq_mhz; 690 clos_config->clos_max = info.max_freq_mhz; 691 clos_config->clos_desired = 0; 692 693 debug_printf("cpu:%d clos:%d min:%d max:%d\n", id->cpu, clos, 694 clos_config->clos_min, clos_config->clos_max); 695 696 return 0; 697 } 698 699 int tpmi_set_clos(struct isst_id *id, int clos, 700 struct isst_clos_config *clos_config) 701 { 702 struct isst_clos_param info; 703 int i, ret, saved_punit; 704 705 info.get_set = 1; 706 info.socket_id = id->pkg; 707 info.power_domain_id = id->punit; 708 info.clos = clos; 709 info.prop_prio = clos_config->clos_prop_prio; 710 711 info.min_freq_mhz = clos_config->clos_min; 712 info.max_freq_mhz = clos_config->clos_max; 713 714 if (info.min_freq_mhz <= 0xff) 715 info.min_freq_mhz *= 100; 716 if (info.max_freq_mhz <= 0xff) 717 info.max_freq_mhz *= 100; 718 719 saved_punit = id->punit; 720 721 /* Set for all other dies also. This is per package setting */ 722 for (i = 0; i < MAX_PUNIT_PER_DIE; i++) { 723 id->punit = i; 724 if (isst_is_punit_valid(id)) { 725 info.power_domain_id = i; 726 ret = tpmi_process_ioctl(ISST_IF_CLOS_PARAM, &info); 727 if (ret == -1) { 728 id->punit = saved_punit; 729 return ret; 730 } 731 } 732 } 733 734 id->punit = saved_punit; 735 736 debug_printf("set cpu:%d clos:%d min:%d max:%d\n", id->cpu, clos, 737 clos_config->clos_min, clos_config->clos_max); 738 739 return 0; 740 } 741 742 static int tpmi_clos_get_assoc_status(struct isst_id *id, int *clos_id) 743 { 744 struct isst_if_clos_assoc_cmds assoc_cmds; 745 int ret; 746 747 assoc_cmds.cmd_count = 1; 748 assoc_cmds.get_set = 0; 749 assoc_cmds.punit_cpu_map = 1; 750 assoc_cmds.assoc_info[0].logical_cpu = find_phy_core_num(id->cpu); 751 assoc_cmds.assoc_info[0].socket_id = id->pkg; 752 assoc_cmds.assoc_info[0].power_domain_id = id->punit; 753 754 ret = tpmi_process_ioctl(ISST_IF_CLOS_ASSOC, &assoc_cmds); 755 if (ret == -1) 756 return ret; 757 758 *clos_id = assoc_cmds.assoc_info[0].clos; 759 760 return 0; 761 } 762 763 static int tpmi_clos_associate(struct isst_id *id, int clos_id) 764 { 765 struct isst_if_clos_assoc_cmds assoc_cmds; 766 int ret; 767 768 assoc_cmds.cmd_count = 1; 769 assoc_cmds.get_set = 1; 770 assoc_cmds.punit_cpu_map = 1; 771 assoc_cmds.assoc_info[0].logical_cpu = find_phy_core_num(id->cpu); 772 assoc_cmds.assoc_info[0].clos = clos_id; 773 assoc_cmds.assoc_info[0].socket_id = id->pkg; 774 assoc_cmds.assoc_info[0].power_domain_id = id->punit; 775 776 ret = tpmi_process_ioctl(ISST_IF_CLOS_ASSOC, &assoc_cmds); 777 if (ret == -1) 778 return ret; 779 780 return 0; 781 } 782 783 static struct isst_platform_ops tpmi_ops = { 784 .get_disp_freq_multiplier = tpmi_get_disp_freq_multiplier, 785 .get_trl_max_levels = tpmi_get_trl_max_levels, 786 .get_trl_level_name = tpmi_get_trl_level_name, 787 .update_platform_param = tpmi_update_platform_param, 788 .is_punit_valid = tpmi_is_punit_valid, 789 .read_pm_config = tpmi_read_pm_config, 790 .get_config_levels = tpmi_get_config_levels, 791 .get_ctdp_control = tpmi_get_ctdp_control, 792 .get_tdp_info = tpmi_get_tdp_info, 793 .get_pwr_info = tpmi_get_pwr_info, 794 .get_coremask_info = tpmi_get_coremask_info, 795 .get_get_trl = tpmi_get_get_trl, 796 .get_get_trls = tpmi_get_get_trls, 797 .get_trl_bucket_info = tpmi_get_trl_bucket_info, 798 .set_tdp_level = tpmi_set_tdp_level, 799 .get_pbf_info = tpmi_get_pbf_info, 800 .set_pbf_fact_status = tpmi_set_pbf_fact_status, 801 .get_fact_info = tpmi_get_fact_info, 802 .adjust_uncore_freq = tpmi_adjust_uncore_freq, 803 .get_clos_information = tpmi_get_clos_information, 804 .pm_qos_config = tpmi_pm_qos_config, 805 .pm_get_clos = tpmi_pm_get_clos, 806 .set_clos = tpmi_set_clos, 807 .clos_get_assoc_status = tpmi_clos_get_assoc_status, 808 .clos_associate = tpmi_clos_associate, 809 }; 810 811 struct isst_platform_ops *tpmi_get_platform_ops(void) 812 { 813 return &tpmi_ops; 814 } 815