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