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 if (api_version() > 2) { 198 ctdp_level->fact_support = info.sst_tf_support & BIT(config_index); 199 ctdp_level->pbf_support = info.sst_bf_support & BIT(config_index); 200 } else { 201 ctdp_level->fact_support = info.sst_tf_support; 202 ctdp_level->pbf_support = info.sst_bf_support; 203 } 204 205 ctdp_level->fact_enabled = !!(info.feature_state & BIT(1)); 206 ctdp_level->pbf_enabled = !!(info.feature_state & BIT(0)); 207 208 core_power_info.get_set = 0; 209 core_power_info.socket_id = id->pkg; 210 core_power_info.power_domain_id = id->punit; 211 212 ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &core_power_info); 213 if (ret == -1) 214 return ret; 215 216 ctdp_level->sst_cp_support = core_power_info.supported; 217 ctdp_level->sst_cp_enabled = core_power_info.enable; 218 219 debug_printf 220 ("cpu:%d CONFIG_TDP_GET_TDP_CONTROL fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n", 221 id->cpu, ctdp_level->fact_support, ctdp_level->pbf_support, 222 ctdp_level->fact_enabled, ctdp_level->pbf_enabled); 223 224 return 0; 225 } 226 227 static int tpmi_get_tdp_info(struct isst_id *id, int config_index, 228 struct isst_pkg_ctdp_level_info *ctdp_level) 229 { 230 struct isst_perf_level_data_info info; 231 int ret; 232 233 info.socket_id = id->pkg; 234 info.power_domain_id = id->punit; 235 info.level = config_index; 236 237 ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info); 238 if (ret == -1) 239 return ret; 240 241 ctdp_level->pkg_tdp = info.thermal_design_power_w; 242 ctdp_level->tdp_ratio = info.tdp_ratio; 243 ctdp_level->sse_p1 = info.base_freq_mhz; 244 ctdp_level->avx2_p1 = info.base_freq_avx2_mhz; 245 ctdp_level->avx512_p1 = info.base_freq_avx512_mhz; 246 ctdp_level->amx_p1 = info.base_freq_amx_mhz; 247 248 ctdp_level->t_proc_hot = info.tjunction_max_c; 249 ctdp_level->mem_freq = info.max_memory_freq_mhz; 250 ctdp_level->cooling_type = info.cooling_type; 251 252 ctdp_level->uncore_p0 = info.p0_fabric_freq_mhz; 253 ctdp_level->uncore_p1 = info.p1_fabric_freq_mhz; 254 ctdp_level->uncore_pm = info.pm_fabric_freq_mhz; 255 256 debug_printf 257 ("cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO tdp_ratio:%d pkg_tdp:%d ctdp_level->t_proc_hot:%d\n", 258 id->cpu, config_index, ctdp_level->tdp_ratio, ctdp_level->pkg_tdp, 259 ctdp_level->t_proc_hot); 260 261 return 0; 262 } 263 264 static int tpmi_get_pwr_info(struct isst_id *id, int config_index, 265 struct isst_pkg_ctdp_level_info *ctdp_level) 266 { 267 /* TBD */ 268 ctdp_level->pkg_max_power = 0; 269 ctdp_level->pkg_min_power = 0; 270 271 debug_printf 272 ("cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO pkg_max_power:%d pkg_min_power:%d\n", 273 id->cpu, config_index, ctdp_level->pkg_max_power, 274 ctdp_level->pkg_min_power); 275 276 return 0; 277 } 278 279 int tpmi_get_coremask_info(struct isst_id *id, int config_index, 280 struct isst_pkg_ctdp_level_info *ctdp_level) 281 { 282 struct isst_perf_level_cpu_mask info; 283 int ret, cpu_count; 284 285 info.socket_id = id->pkg; 286 info.power_domain_id = id->punit; 287 info.level = config_index; 288 info.punit_cpu_map = 1; 289 290 ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_CPU_MASK, &info); 291 if (ret == -1) 292 return ret; 293 294 set_cpu_mask_from_punit_coremask(id, info.mask, 295 ctdp_level->core_cpumask_size, 296 ctdp_level->core_cpumask, &cpu_count); 297 ctdp_level->cpu_count = cpu_count; 298 299 debug_printf("cpu:%d ctdp:%d core_mask ino cpu count:%d\n", 300 id->cpu, config_index, ctdp_level->cpu_count); 301 302 return 0; 303 } 304 305 static int tpmi_get_get_trls(struct isst_id *id, int config_index, 306 struct isst_pkg_ctdp_level_info *ctdp_level) 307 { 308 struct isst_perf_level_data_info info; 309 int ret, i, j; 310 311 info.socket_id = id->pkg; 312 info.power_domain_id = id->punit; 313 info.level = config_index; 314 315 ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info); 316 if (ret == -1) 317 return ret; 318 319 if (info.max_buckets > TRL_MAX_BUCKETS) 320 info.max_buckets = TRL_MAX_BUCKETS; 321 322 if (info.max_trl_levels > TRL_MAX_LEVELS) 323 info.max_trl_levels = TRL_MAX_LEVELS; 324 325 for (i = 0; i < info.max_trl_levels; ++i) 326 for (j = 0; j < info.max_buckets; ++j) 327 ctdp_level->trl_ratios[i][j] = info.trl_freq_mhz[i][j]; 328 329 return 0; 330 } 331 332 static int tpmi_get_get_trl(struct isst_id *id, int level, int config_index, 333 int *trl) 334 { 335 struct isst_pkg_ctdp_level_info ctdp_level; 336 int ret, i; 337 338 ret = tpmi_get_get_trls(id, config_index, &ctdp_level); 339 if (ret) 340 return ret; 341 342 /* FIX ME: Just return for level 0 */ 343 for (i = 0; i < 8; ++i) 344 trl[i] = ctdp_level.trl_ratios[0][i]; 345 346 return 0; 347 } 348 349 static int tpmi_get_trl_bucket_info(struct isst_id *id, int config_index, 350 unsigned long long *buckets_info) 351 { 352 struct isst_perf_level_data_info info; 353 unsigned char *mask = (unsigned char *)buckets_info; 354 int ret, i; 355 356 info.socket_id = id->pkg; 357 info.power_domain_id = id->punit; 358 info.level = config_index; 359 360 ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info); 361 if (ret == -1) 362 return ret; 363 364 if (info.max_buckets > TRL_MAX_BUCKETS) 365 info.max_buckets = TRL_MAX_BUCKETS; 366 367 for (i = 0; i < info.max_buckets; ++i) 368 mask[i] = info.bucket_core_counts[i]; 369 370 debug_printf("cpu:%d TRL bucket info: 0x%llx\n", id->cpu, 371 *buckets_info); 372 373 return 0; 374 } 375 376 static int tpmi_set_tdp_level(struct isst_id *id, int tdp_level) 377 { 378 struct isst_perf_level_control info; 379 int ret; 380 381 info.socket_id = id->pkg; 382 info.power_domain_id = id->punit; 383 info.level = tdp_level; 384 385 ret = tpmi_process_ioctl(ISST_IF_PERF_SET_LEVEL, &info); 386 if (ret == -1) 387 return ret; 388 389 return 0; 390 } 391 392 static int _pbf_get_coremask_info(struct isst_id *id, int config_index, 393 struct isst_pbf_info *pbf_info) 394 { 395 struct isst_perf_level_cpu_mask info; 396 int ret, cpu_count; 397 398 info.socket_id = id->pkg; 399 info.power_domain_id = id->punit; 400 info.level = config_index; 401 info.punit_cpu_map = 1; 402 403 ret = tpmi_process_ioctl(ISST_IF_GET_BASE_FREQ_CPU_MASK, &info); 404 if (ret == -1) 405 return ret; 406 407 set_cpu_mask_from_punit_coremask(id, info.mask, 408 pbf_info->core_cpumask_size, 409 pbf_info->core_cpumask, &cpu_count); 410 411 debug_printf("cpu:%d ctdp:%d pbf core_mask info cpu count:%d\n", 412 id->cpu, config_index, cpu_count); 413 414 return 0; 415 } 416 417 static int tpmi_get_pbf_info(struct isst_id *id, int level, 418 struct isst_pbf_info *pbf_info) 419 { 420 struct isst_base_freq_info info; 421 int ret; 422 423 info.socket_id = id->pkg; 424 info.power_domain_id = id->punit; 425 info.level = level; 426 427 ret = tpmi_process_ioctl(ISST_IF_GET_BASE_FREQ_INFO, &info); 428 if (ret == -1) 429 return ret; 430 431 pbf_info->p1_low = info.low_base_freq_mhz; 432 pbf_info->p1_high = info.high_base_freq_mhz; 433 pbf_info->tdp = info.thermal_design_power_w; 434 pbf_info->t_prochot = info.tjunction_max_c; 435 436 debug_printf("cpu:%d ctdp:%d pbf info:%d:%d:%d:%d\n", 437 id->cpu, level, pbf_info->p1_low, pbf_info->p1_high, 438 pbf_info->tdp, pbf_info->t_prochot); 439 440 return _pbf_get_coremask_info(id, level, pbf_info); 441 } 442 443 static int tpmi_set_pbf_fact_status(struct isst_id *id, int pbf, int enable) 444 { 445 struct isst_pkg_ctdp pkg_dev; 446 struct isst_pkg_ctdp_level_info ctdp_level; 447 int current_level; 448 struct isst_perf_feature_control info; 449 int ret; 450 451 ret = isst_get_ctdp_levels(id, &pkg_dev); 452 if (ret) 453 debug_printf("cpu:%d No support for dynamic ISST\n", id->cpu); 454 455 current_level = pkg_dev.current_level; 456 457 ret = isst_get_ctdp_control(id, current_level, &ctdp_level); 458 if (ret) 459 return ret; 460 461 info.socket_id = id->pkg; 462 info.power_domain_id = id->punit; 463 464 info.feature = 0; 465 466 if (pbf) { 467 if (ctdp_level.fact_enabled) 468 info.feature |= BIT(1); 469 470 if (enable) 471 info.feature |= BIT(0); 472 else 473 info.feature &= ~BIT(0); 474 } else { 475 476 if (enable && !ctdp_level.sst_cp_enabled) 477 isst_display_error_info_message(0, 478 "Make sure to execute before: core-power enable", 479 0, 0); 480 481 if (ctdp_level.pbf_enabled) 482 info.feature |= BIT(0); 483 484 if (enable) 485 info.feature |= BIT(1); 486 else 487 info.feature &= ~BIT(1); 488 } 489 490 ret = tpmi_process_ioctl(ISST_IF_PERF_SET_FEATURE, &info); 491 if (ret == -1) 492 return ret; 493 494 return 0; 495 } 496 497 static int tpmi_get_fact_info(struct isst_id *id, int level, int fact_bucket, 498 struct isst_fact_info *fact_info) 499 { 500 struct isst_turbo_freq_info info; 501 int i, j; 502 int ret; 503 504 info.socket_id = id->pkg; 505 info.power_domain_id = id->punit; 506 info.level = level; 507 508 ret = tpmi_process_ioctl(ISST_IF_GET_TURBO_FREQ_INFO, &info); 509 if (ret == -1) 510 return ret; 511 512 for (i = 0; i < info.max_clip_freqs; ++i) 513 fact_info->lp_ratios[i] = info.lp_clip_freq_mhz[i]; 514 515 if (info.max_buckets > TRL_MAX_BUCKETS) 516 info.max_buckets = TRL_MAX_BUCKETS; 517 518 if (info.max_trl_levels > TRL_MAX_LEVELS) 519 info.max_trl_levels = TRL_MAX_LEVELS; 520 521 for (i = 0; i < info.max_trl_levels; ++i) { 522 for (j = 0; j < info.max_buckets; ++j) 523 fact_info->bucket_info[j].hp_ratios[i] = 524 info.trl_freq_mhz[i][j]; 525 } 526 527 for (i = 0; i < info.max_buckets; ++i) 528 fact_info->bucket_info[i].hp_cores = info.bucket_core_counts[i]; 529 530 return 0; 531 } 532 533 static void _set_uncore_min_max(struct isst_id *id, int max, int freq) 534 { 535 DIR *dir; 536 FILE *filep; 537 struct dirent *entry; 538 char buffer[512]; 539 unsigned int tmp_id; 540 int ret; 541 542 dir = opendir("/sys/devices/system/cpu/intel_uncore_frequency/"); 543 if (!dir) 544 return; 545 546 while ((entry = readdir(dir)) != NULL ) { 547 /* Check domain_id */ 548 snprintf(buffer, sizeof(buffer), 549 "/sys/devices/system/cpu/intel_uncore_frequency/%s/domain_id", entry->d_name); 550 551 filep = fopen(buffer, "r"); 552 if (!filep) 553 goto end; 554 555 ret = fscanf(filep, "%u", &tmp_id); 556 fclose(filep); 557 if (ret != 1) 558 goto end; 559 560 if (tmp_id != id->punit) 561 continue; 562 563 /* Check package_id */ 564 snprintf(buffer, sizeof(buffer), 565 "/sys/devices/system/cpu/intel_uncore_frequency/%s/package_id", entry->d_name); 566 567 filep = fopen(buffer, "r"); 568 if (!filep) 569 goto end; 570 571 ret = fscanf(filep, "%u", &tmp_id); 572 fclose(filep); 573 574 if (ret != 1) 575 goto end; 576 577 if (tmp_id != id->pkg) 578 continue; 579 580 /* Found the right sysfs path, adjust and quit */ 581 if (max) 582 snprintf(buffer, sizeof(buffer), 583 "/sys/devices/system/cpu/intel_uncore_frequency/%s/max_freq_khz", entry->d_name); 584 else 585 snprintf(buffer, sizeof(buffer), 586 "/sys/devices/system/cpu/intel_uncore_frequency/%s/min_freq_khz", entry->d_name); 587 588 filep = fopen(buffer, "w"); 589 if (!filep) 590 goto end; 591 592 fprintf(filep, "%d\n", freq); 593 fclose(filep); 594 break; 595 } 596 597 end: 598 closedir(dir); 599 } 600 601 static void tpmi_adjust_uncore_freq(struct isst_id *id, int config_index, 602 struct isst_pkg_ctdp_level_info *ctdp_level) 603 { 604 struct isst_perf_level_data_info info; 605 int ret; 606 607 info.socket_id = id->pkg; 608 info.power_domain_id = id->punit; 609 info.level = config_index; 610 611 ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info); 612 if (ret == -1) 613 return; 614 615 ctdp_level->uncore_p0 = info.p0_fabric_freq_mhz; 616 ctdp_level->uncore_p1 = info.p1_fabric_freq_mhz; 617 ctdp_level->uncore_pm = info.pm_fabric_freq_mhz; 618 619 if (ctdp_level->uncore_pm) 620 _set_uncore_min_max(id, 0, ctdp_level->uncore_pm * 100000); 621 622 if (ctdp_level->uncore_p0) 623 _set_uncore_min_max(id, 1, ctdp_level->uncore_p0 * 100000); 624 625 return; 626 } 627 628 static int tpmi_get_clos_information(struct isst_id *id, int *enable, int *type) 629 { 630 struct isst_core_power info; 631 int ret; 632 633 info.get_set = 0; 634 info.socket_id = id->pkg; 635 info.power_domain_id = id->punit; 636 ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info); 637 if (ret == -1) 638 return ret; 639 640 *enable = info.enable; 641 *type = info.priority_type; 642 643 return 0; 644 } 645 646 static int tpmi_pm_qos_config(struct isst_id *id, int enable_clos, 647 int priority_type) 648 { 649 struct isst_core_power info; 650 int i, ret, saved_punit; 651 652 info.get_set = 1; 653 info.socket_id = id->pkg; 654 info.power_domain_id = id->punit; 655 info.enable = enable_clos; 656 info.priority_type = priority_type; 657 658 saved_punit = id->punit; 659 660 /* Set for all other dies also. This is per package setting */ 661 for (i = 0; i < MAX_PUNIT_PER_DIE; i++) { 662 id->punit = i; 663 if (isst_is_punit_valid(id)) { 664 info.power_domain_id = i; 665 ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info); 666 if (ret == -1) { 667 id->punit = saved_punit; 668 return ret; 669 } 670 } 671 } 672 673 id->punit = saved_punit; 674 675 return 0; 676 } 677 678 int tpmi_pm_get_clos(struct isst_id *id, int clos, 679 struct isst_clos_config *clos_config) 680 { 681 struct isst_clos_param info; 682 int ret; 683 684 info.get_set = 0; 685 info.socket_id = id->pkg; 686 info.power_domain_id = id->punit; 687 info.clos = clos; 688 689 ret = tpmi_process_ioctl(ISST_IF_CLOS_PARAM, &info); 690 if (ret == -1) 691 return ret; 692 693 clos_config->epp = 0; 694 clos_config->clos_prop_prio = info.prop_prio; 695 clos_config->clos_min = info.min_freq_mhz; 696 clos_config->clos_max = info.max_freq_mhz; 697 clos_config->clos_desired = 0; 698 699 debug_printf("cpu:%d clos:%d min:%d max:%d\n", id->cpu, clos, 700 clos_config->clos_min, clos_config->clos_max); 701 702 return 0; 703 } 704 705 int tpmi_set_clos(struct isst_id *id, int clos, 706 struct isst_clos_config *clos_config) 707 { 708 struct isst_clos_param info; 709 int i, ret, saved_punit; 710 711 info.get_set = 1; 712 info.socket_id = id->pkg; 713 info.power_domain_id = id->punit; 714 info.clos = clos; 715 info.prop_prio = clos_config->clos_prop_prio; 716 717 info.min_freq_mhz = clos_config->clos_min; 718 info.max_freq_mhz = clos_config->clos_max; 719 720 if (info.min_freq_mhz <= 0xff) 721 info.min_freq_mhz *= 100; 722 if (info.max_freq_mhz <= 0xff) 723 info.max_freq_mhz *= 100; 724 725 saved_punit = id->punit; 726 727 /* Set for all other dies also. This is per package setting */ 728 for (i = 0; i < MAX_PUNIT_PER_DIE; i++) { 729 id->punit = i; 730 if (isst_is_punit_valid(id)) { 731 info.power_domain_id = i; 732 ret = tpmi_process_ioctl(ISST_IF_CLOS_PARAM, &info); 733 if (ret == -1) { 734 id->punit = saved_punit; 735 return ret; 736 } 737 } 738 } 739 740 id->punit = saved_punit; 741 742 debug_printf("set cpu:%d clos:%d min:%d max:%d\n", id->cpu, clos, 743 clos_config->clos_min, clos_config->clos_max); 744 745 return 0; 746 } 747 748 static int tpmi_clos_get_assoc_status(struct isst_id *id, int *clos_id) 749 { 750 struct isst_if_clos_assoc_cmds assoc_cmds; 751 int ret; 752 753 assoc_cmds.cmd_count = 1; 754 assoc_cmds.get_set = 0; 755 assoc_cmds.punit_cpu_map = 1; 756 assoc_cmds.assoc_info[0].logical_cpu = find_phy_core_num(id->cpu); 757 assoc_cmds.assoc_info[0].socket_id = id->pkg; 758 assoc_cmds.assoc_info[0].power_domain_id = id->punit; 759 760 ret = tpmi_process_ioctl(ISST_IF_CLOS_ASSOC, &assoc_cmds); 761 if (ret == -1) 762 return ret; 763 764 *clos_id = assoc_cmds.assoc_info[0].clos; 765 766 return 0; 767 } 768 769 static int tpmi_clos_associate(struct isst_id *id, int clos_id) 770 { 771 struct isst_if_clos_assoc_cmds assoc_cmds; 772 int ret; 773 774 assoc_cmds.cmd_count = 1; 775 assoc_cmds.get_set = 1; 776 assoc_cmds.punit_cpu_map = 1; 777 assoc_cmds.assoc_info[0].logical_cpu = find_phy_core_num(id->cpu); 778 assoc_cmds.assoc_info[0].clos = clos_id; 779 assoc_cmds.assoc_info[0].socket_id = id->pkg; 780 assoc_cmds.assoc_info[0].power_domain_id = id->punit; 781 782 ret = tpmi_process_ioctl(ISST_IF_CLOS_ASSOC, &assoc_cmds); 783 if (ret == -1) 784 return ret; 785 786 return 0; 787 } 788 789 static struct isst_platform_ops tpmi_ops = { 790 .get_disp_freq_multiplier = tpmi_get_disp_freq_multiplier, 791 .get_trl_max_levels = tpmi_get_trl_max_levels, 792 .get_trl_level_name = tpmi_get_trl_level_name, 793 .update_platform_param = tpmi_update_platform_param, 794 .is_punit_valid = tpmi_is_punit_valid, 795 .read_pm_config = tpmi_read_pm_config, 796 .get_config_levels = tpmi_get_config_levels, 797 .get_ctdp_control = tpmi_get_ctdp_control, 798 .get_tdp_info = tpmi_get_tdp_info, 799 .get_pwr_info = tpmi_get_pwr_info, 800 .get_coremask_info = tpmi_get_coremask_info, 801 .get_get_trl = tpmi_get_get_trl, 802 .get_get_trls = tpmi_get_get_trls, 803 .get_trl_bucket_info = tpmi_get_trl_bucket_info, 804 .set_tdp_level = tpmi_set_tdp_level, 805 .get_pbf_info = tpmi_get_pbf_info, 806 .set_pbf_fact_status = tpmi_set_pbf_fact_status, 807 .get_fact_info = tpmi_get_fact_info, 808 .adjust_uncore_freq = tpmi_adjust_uncore_freq, 809 .get_clos_information = tpmi_get_clos_information, 810 .pm_qos_config = tpmi_pm_qos_config, 811 .pm_get_clos = tpmi_pm_get_clos, 812 .set_clos = tpmi_set_clos, 813 .clos_get_assoc_status = tpmi_clos_get_assoc_status, 814 .clos_associate = tpmi_clos_associate, 815 }; 816 817 struct isst_platform_ops *tpmi_get_platform_ops(void) 818 { 819 return &tpmi_ops; 820 } 821