1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Intel Speed Select -- Enumerate and control features 4 * Copyright (c) 2019 Intel Corporation. 5 */ 6 7 #include "isst.h" 8 9 int isst_write_pm_config(int cpu, int cp_state) 10 { 11 unsigned int req, resp; 12 int ret; 13 14 if (cp_state) 15 req = BIT(16); 16 else 17 req = 0; 18 19 ret = isst_send_mbox_command(cpu, WRITE_PM_CONFIG, PM_FEATURE, 0, req, 20 &resp); 21 if (ret) 22 return ret; 23 24 debug_printf("cpu:%d WRITE_PM_CONFIG resp:%x\n", cpu, resp); 25 26 return 0; 27 } 28 29 int isst_read_pm_config(int cpu, int *cp_state, int *cp_cap) 30 { 31 unsigned int resp; 32 int ret; 33 34 ret = isst_send_mbox_command(cpu, READ_PM_CONFIG, PM_FEATURE, 0, 0, 35 &resp); 36 if (ret) 37 return ret; 38 39 debug_printf("cpu:%d READ_PM_CONFIG resp:%x\n", cpu, resp); 40 41 *cp_state = resp & BIT(16); 42 *cp_cap = resp & BIT(0) ? 1 : 0; 43 44 return 0; 45 } 46 47 int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev) 48 { 49 unsigned int resp; 50 int ret; 51 52 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 53 CONFIG_TDP_GET_LEVELS_INFO, 0, 0, &resp); 54 if (ret) { 55 pkg_dev->levels = 0; 56 pkg_dev->locked = 1; 57 pkg_dev->current_level = 0; 58 pkg_dev->version = 0; 59 pkg_dev->enabled = 0; 60 return 0; 61 } 62 63 debug_printf("cpu:%d CONFIG_TDP_GET_LEVELS_INFO resp:%x\n", cpu, resp); 64 65 pkg_dev->version = resp & 0xff; 66 pkg_dev->levels = (resp >> 8) & 0xff; 67 pkg_dev->current_level = (resp >> 16) & 0xff; 68 pkg_dev->locked = !!(resp & BIT(24)); 69 pkg_dev->enabled = !!(resp & BIT(31)); 70 71 return 0; 72 } 73 74 int isst_get_ctdp_control(int cpu, int config_index, 75 struct isst_pkg_ctdp_level_info *ctdp_level) 76 { 77 int cp_state, cp_cap; 78 unsigned int resp; 79 int ret; 80 81 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 82 CONFIG_TDP_GET_TDP_CONTROL, 0, 83 config_index, &resp); 84 if (ret) 85 return ret; 86 87 ctdp_level->fact_support = resp & BIT(0); 88 ctdp_level->pbf_support = !!(resp & BIT(1)); 89 ctdp_level->fact_enabled = !!(resp & BIT(16)); 90 ctdp_level->pbf_enabled = !!(resp & BIT(17)); 91 92 ret = isst_read_pm_config(cpu, &cp_state, &cp_cap); 93 if (ret) { 94 debug_printf("cpu:%d pm_config is not supported \n", cpu); 95 } else { 96 debug_printf("cpu:%d pm_config SST-CP state:%d cap:%d \n", cpu, cp_state, cp_cap); 97 ctdp_level->sst_cp_support = cp_cap; 98 ctdp_level->sst_cp_enabled = cp_state; 99 } 100 101 debug_printf( 102 "cpu:%d CONFIG_TDP_GET_TDP_CONTROL resp:%x fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n", 103 cpu, resp, ctdp_level->fact_support, ctdp_level->pbf_support, 104 ctdp_level->fact_enabled, ctdp_level->pbf_enabled); 105 106 return 0; 107 } 108 109 int isst_get_tdp_info(int cpu, int config_index, 110 struct isst_pkg_ctdp_level_info *ctdp_level) 111 { 112 unsigned int resp; 113 int ret; 114 115 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO, 116 0, config_index, &resp); 117 if (ret) { 118 isst_display_error_info_message(1, "Invalid level, Can't get TDP information at level", 1, config_index); 119 return ret; 120 } 121 122 ctdp_level->pkg_tdp = resp & GENMASK(14, 0); 123 ctdp_level->tdp_ratio = (resp & GENMASK(23, 16)) >> 16; 124 125 debug_printf( 126 "cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO resp:%x tdp_ratio:%d pkg_tdp:%d\n", 127 cpu, config_index, resp, ctdp_level->tdp_ratio, 128 ctdp_level->pkg_tdp); 129 return 0; 130 } 131 132 int isst_get_pwr_info(int cpu, int config_index, 133 struct isst_pkg_ctdp_level_info *ctdp_level) 134 { 135 unsigned int resp; 136 int ret; 137 138 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_PWR_INFO, 139 0, config_index, &resp); 140 if (ret) 141 return ret; 142 143 ctdp_level->pkg_max_power = resp & GENMASK(14, 0); 144 ctdp_level->pkg_min_power = (resp & GENMASK(30, 16)) >> 16; 145 146 debug_printf( 147 "cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO resp:%x pkg_max_power:%d pkg_min_power:%d\n", 148 cpu, config_index, resp, ctdp_level->pkg_max_power, 149 ctdp_level->pkg_min_power); 150 151 return 0; 152 } 153 154 void isst_get_uncore_p0_p1_info(int cpu, int config_index, 155 struct isst_pkg_ctdp_level_info *ctdp_level) 156 { 157 unsigned int resp; 158 int ret; 159 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 160 CONFIG_TDP_GET_UNCORE_P0_P1_INFO, 0, 161 config_index, &resp); 162 if (ret) { 163 ctdp_level->uncore_p0 = 0; 164 ctdp_level->uncore_p1 = 0; 165 return; 166 } 167 168 ctdp_level->uncore_p0 = resp & GENMASK(7, 0); 169 ctdp_level->uncore_p1 = (resp & GENMASK(15, 8)) >> 8; 170 debug_printf( 171 "cpu:%d ctdp:%d CONFIG_TDP_GET_UNCORE_P0_P1_INFO resp:%x uncore p0:%d uncore p1:%d\n", 172 cpu, config_index, resp, ctdp_level->uncore_p0, 173 ctdp_level->uncore_p1); 174 } 175 176 void isst_get_p1_info(int cpu, int config_index, 177 struct isst_pkg_ctdp_level_info *ctdp_level) 178 { 179 unsigned int resp; 180 int ret; 181 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_P1_INFO, 0, 182 config_index, &resp); 183 if (ret) { 184 ctdp_level->sse_p1 = 0; 185 ctdp_level->avx2_p1 = 0; 186 ctdp_level->avx512_p1 = 0; 187 return; 188 } 189 190 ctdp_level->sse_p1 = resp & GENMASK(7, 0); 191 ctdp_level->avx2_p1 = (resp & GENMASK(15, 8)) >> 8; 192 ctdp_level->avx512_p1 = (resp & GENMASK(23, 16)) >> 16; 193 debug_printf( 194 "cpu:%d ctdp:%d CONFIG_TDP_GET_P1_INFO resp:%x sse_p1:%d avx2_p1:%d avx512_p1:%d\n", 195 cpu, config_index, resp, ctdp_level->sse_p1, 196 ctdp_level->avx2_p1, ctdp_level->avx512_p1); 197 } 198 199 void isst_get_uncore_mem_freq(int cpu, int config_index, 200 struct isst_pkg_ctdp_level_info *ctdp_level) 201 { 202 unsigned int resp; 203 int ret; 204 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_MEM_FREQ, 205 0, config_index, &resp); 206 if (ret) { 207 ctdp_level->mem_freq = 0; 208 return; 209 } 210 211 ctdp_level->mem_freq = resp & GENMASK(7, 0); 212 debug_printf( 213 "cpu:%d ctdp:%d CONFIG_TDP_GET_MEM_FREQ resp:%x uncore mem_freq:%d\n", 214 cpu, config_index, resp, ctdp_level->mem_freq); 215 } 216 217 int isst_get_tjmax_info(int cpu, int config_index, 218 struct isst_pkg_ctdp_level_info *ctdp_level) 219 { 220 unsigned int resp; 221 int ret; 222 223 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_TJMAX_INFO, 224 0, config_index, &resp); 225 if (ret) 226 return ret; 227 228 ctdp_level->t_proc_hot = resp & GENMASK(7, 0); 229 230 debug_printf( 231 "cpu:%d ctdp:%d CONFIG_TDP_GET_TJMAX_INFO resp:%x t_proc_hot:%d\n", 232 cpu, config_index, resp, ctdp_level->t_proc_hot); 233 234 return 0; 235 } 236 237 int isst_get_coremask_info(int cpu, int config_index, 238 struct isst_pkg_ctdp_level_info *ctdp_level) 239 { 240 unsigned int resp; 241 int i, ret; 242 243 ctdp_level->cpu_count = 0; 244 for (i = 0; i < 2; ++i) { 245 unsigned long long mask; 246 int cpu_count = 0; 247 248 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 249 CONFIG_TDP_GET_CORE_MASK, 0, 250 (i << 8) | config_index, &resp); 251 if (ret) 252 return ret; 253 254 debug_printf( 255 "cpu:%d ctdp:%d mask:%d CONFIG_TDP_GET_CORE_MASK resp:%x\n", 256 cpu, config_index, i, resp); 257 258 mask = (unsigned long long)resp << (32 * i); 259 set_cpu_mask_from_punit_coremask(cpu, mask, 260 ctdp_level->core_cpumask_size, 261 ctdp_level->core_cpumask, 262 &cpu_count); 263 ctdp_level->cpu_count += cpu_count; 264 debug_printf("cpu:%d ctdp:%d mask:%d cpu count:%d\n", cpu, 265 config_index, i, ctdp_level->cpu_count); 266 } 267 268 return 0; 269 } 270 271 int isst_get_get_trl_from_msr(int cpu, int *trl) 272 { 273 unsigned long long msr_trl; 274 int ret; 275 276 ret = isst_send_msr_command(cpu, 0x1AD, 0, &msr_trl); 277 if (ret) 278 return ret; 279 280 trl[0] = msr_trl & GENMASK(7, 0); 281 trl[1] = (msr_trl & GENMASK(15, 8)) >> 8; 282 trl[2] = (msr_trl & GENMASK(23, 16)) >> 16; 283 trl[3] = (msr_trl & GENMASK(31, 24)) >> 24; 284 trl[4] = (msr_trl & GENMASK(39, 32)) >> 32; 285 trl[5] = (msr_trl & GENMASK(47, 40)) >> 40; 286 trl[6] = (msr_trl & GENMASK(55, 48)) >> 48; 287 trl[7] = (msr_trl & GENMASK(63, 56)) >> 56; 288 289 return 0; 290 } 291 292 int isst_get_get_trl(int cpu, int level, int avx_level, int *trl) 293 { 294 unsigned int req, resp; 295 int ret; 296 297 req = level | (avx_level << 16); 298 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 299 CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req, 300 &resp); 301 if (ret) 302 return ret; 303 304 debug_printf( 305 "cpu:%d CONFIG_TDP_GET_TURBO_LIMIT_RATIOS req:%x resp:%x\n", 306 cpu, req, resp); 307 308 trl[0] = resp & GENMASK(7, 0); 309 trl[1] = (resp & GENMASK(15, 8)) >> 8; 310 trl[2] = (resp & GENMASK(23, 16)) >> 16; 311 trl[3] = (resp & GENMASK(31, 24)) >> 24; 312 313 req = level | BIT(8) | (avx_level << 16); 314 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 315 CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req, 316 &resp); 317 if (ret) 318 return ret; 319 320 debug_printf("cpu:%d CONFIG_TDP_GET_TURBO_LIMIT req:%x resp:%x\n", cpu, 321 req, resp); 322 323 trl[4] = resp & GENMASK(7, 0); 324 trl[5] = (resp & GENMASK(15, 8)) >> 8; 325 trl[6] = (resp & GENMASK(23, 16)) >> 16; 326 trl[7] = (resp & GENMASK(31, 24)) >> 24; 327 328 return 0; 329 } 330 331 int isst_get_trl_bucket_info(int cpu, unsigned long long *buckets_info) 332 { 333 int ret; 334 335 debug_printf("cpu:%d bucket info via MSR\n", cpu); 336 337 *buckets_info = 0; 338 339 ret = isst_send_msr_command(cpu, 0x1ae, 0, buckets_info); 340 if (ret) 341 return ret; 342 343 debug_printf("cpu:%d bucket info via MSR successful 0x%llx\n", cpu, 344 *buckets_info); 345 346 return 0; 347 } 348 349 int isst_set_tdp_level_msr(int cpu, int tdp_level) 350 { 351 unsigned long long level = tdp_level; 352 int ret; 353 354 debug_printf("cpu: tdp_level via MSR %d\n", cpu, tdp_level); 355 356 if (isst_get_config_tdp_lock_status(cpu)) { 357 isst_display_error_info_message(1, "tdp_locked", 0, 0); 358 return -1; 359 } 360 361 if (tdp_level > 2) 362 return -1; /* invalid value */ 363 364 ret = isst_send_msr_command(cpu, 0x64b, 1, &level); 365 if (ret) 366 return ret; 367 368 debug_printf("cpu: tdp_level via MSR successful %d\n", cpu, tdp_level); 369 370 return 0; 371 } 372 373 int isst_set_tdp_level(int cpu, int tdp_level) 374 { 375 unsigned int resp; 376 int ret; 377 378 379 if (isst_get_config_tdp_lock_status(cpu)) { 380 isst_display_error_info_message(1, "TDP is locked", 0, 0); 381 return -1; 382 383 } 384 385 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_SET_LEVEL, 0, 386 tdp_level, &resp); 387 if (ret) { 388 isst_display_error_info_message(1, "Set TDP level failed for level", 1, tdp_level); 389 return ret; 390 } 391 392 return 0; 393 } 394 395 int isst_get_pbf_info(int cpu, int level, struct isst_pbf_info *pbf_info) 396 { 397 struct isst_pkg_ctdp_level_info ctdp_level; 398 struct isst_pkg_ctdp pkg_dev; 399 int i, ret, max_punit_core, max_mask_index; 400 unsigned int req, resp; 401 402 ret = isst_get_ctdp_levels(cpu, &pkg_dev); 403 if (ret) { 404 isst_display_error_info_message(1, "Failed to get number of levels", 0, 0); 405 return ret; 406 } 407 408 if (level > pkg_dev.levels) { 409 isst_display_error_info_message(1, "Invalid level", 1, level); 410 return -1; 411 } 412 413 ret = isst_get_ctdp_control(cpu, level, &ctdp_level); 414 if (ret) 415 return ret; 416 417 if (!ctdp_level.pbf_support) { 418 isst_display_error_info_message(1, "base-freq feature is not present at this level", 1, level); 419 return -1; 420 } 421 422 pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask); 423 424 max_punit_core = get_max_punit_core_id(get_physical_package_id(cpu), get_physical_die_id(cpu)); 425 max_mask_index = max_punit_core > 32 ? 2 : 1; 426 427 for (i = 0; i < max_mask_index; ++i) { 428 unsigned long long mask; 429 int count; 430 431 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 432 CONFIG_TDP_PBF_GET_CORE_MASK_INFO, 433 0, (i << 8) | level, &resp); 434 if (ret) 435 break; 436 437 debug_printf( 438 "cpu:%d CONFIG_TDP_PBF_GET_CORE_MASK_INFO resp:%x\n", 439 cpu, resp); 440 441 mask = (unsigned long long)resp << (32 * i); 442 set_cpu_mask_from_punit_coremask(cpu, mask, 443 pbf_info->core_cpumask_size, 444 pbf_info->core_cpumask, 445 &count); 446 } 447 448 req = level; 449 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 450 CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO, 0, req, 451 &resp); 452 if (ret) 453 return ret; 454 455 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO resp:%x\n", cpu, 456 resp); 457 458 pbf_info->p1_low = resp & 0xff; 459 pbf_info->p1_high = (resp & GENMASK(15, 8)) >> 8; 460 461 req = level; 462 ret = isst_send_mbox_command( 463 cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TDP_INFO, 0, req, &resp); 464 if (ret) 465 return ret; 466 467 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TDP_INFO resp:%x\n", cpu, resp); 468 469 pbf_info->tdp = resp & 0xffff; 470 471 req = level; 472 ret = isst_send_mbox_command( 473 cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TJ_MAX_INFO, 0, req, &resp); 474 if (ret) 475 return ret; 476 477 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TJ_MAX_INFO resp:%x\n", cpu, 478 resp); 479 pbf_info->t_control = (resp >> 8) & 0xff; 480 pbf_info->t_prochot = resp & 0xff; 481 482 return 0; 483 } 484 485 void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info) 486 { 487 free_cpu_set(pbf_info->core_cpumask); 488 } 489 490 int isst_set_pbf_fact_status(int cpu, int pbf, int enable) 491 { 492 struct isst_pkg_ctdp pkg_dev; 493 struct isst_pkg_ctdp_level_info ctdp_level; 494 int current_level; 495 unsigned int req = 0, resp; 496 int ret; 497 498 ret = isst_get_ctdp_levels(cpu, &pkg_dev); 499 if (ret) 500 debug_printf("cpu:%d No support for dynamic ISST\n", cpu); 501 502 current_level = pkg_dev.current_level; 503 504 ret = isst_get_ctdp_control(cpu, current_level, &ctdp_level); 505 if (ret) 506 return ret; 507 508 if (pbf) { 509 if (ctdp_level.fact_enabled) 510 req = BIT(16); 511 512 if (enable) 513 req |= BIT(17); 514 else 515 req &= ~BIT(17); 516 } else { 517 518 if (enable && !ctdp_level.sst_cp_enabled) 519 isst_display_error_info_message(0, "Make sure to execute before: core-power enable", 0, 0); 520 521 if (ctdp_level.pbf_enabled) 522 req = BIT(17); 523 524 if (enable) 525 req |= BIT(16); 526 else 527 req &= ~BIT(16); 528 } 529 530 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 531 CONFIG_TDP_SET_TDP_CONTROL, 0, req, &resp); 532 if (ret) 533 return ret; 534 535 debug_printf("cpu:%d CONFIG_TDP_SET_TDP_CONTROL pbf/fact:%d req:%x\n", 536 cpu, pbf, req); 537 538 return 0; 539 } 540 541 int isst_get_fact_bucket_info(int cpu, int level, 542 struct isst_fact_bucket_info *bucket_info) 543 { 544 unsigned int resp; 545 int i, k, ret; 546 547 for (i = 0; i < 2; ++i) { 548 int j; 549 550 ret = isst_send_mbox_command( 551 cpu, CONFIG_TDP, 552 CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES, 0, 553 (i << 8) | level, &resp); 554 if (ret) 555 return ret; 556 557 debug_printf( 558 "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES index:%d level:%d resp:%x\n", 559 cpu, i, level, resp); 560 561 for (j = 0; j < 4; ++j) { 562 bucket_info[j + (i * 4)].high_priority_cores_count = 563 (resp >> (j * 8)) & 0xff; 564 } 565 } 566 567 for (k = 0; k < 3; ++k) { 568 for (i = 0; i < 2; ++i) { 569 int j; 570 571 ret = isst_send_mbox_command( 572 cpu, CONFIG_TDP, 573 CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS, 0, 574 (k << 16) | (i << 8) | level, &resp); 575 if (ret) 576 return ret; 577 578 debug_printf( 579 "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS index:%d level:%d avx:%d resp:%x\n", 580 cpu, i, level, k, resp); 581 582 for (j = 0; j < 4; ++j) { 583 switch (k) { 584 case 0: 585 bucket_info[j + (i * 4)].sse_trl = 586 (resp >> (j * 8)) & 0xff; 587 break; 588 case 1: 589 bucket_info[j + (i * 4)].avx_trl = 590 (resp >> (j * 8)) & 0xff; 591 break; 592 case 2: 593 bucket_info[j + (i * 4)].avx512_trl = 594 (resp >> (j * 8)) & 0xff; 595 break; 596 default: 597 break; 598 } 599 } 600 } 601 } 602 603 return 0; 604 } 605 606 int isst_get_fact_info(int cpu, int level, int fact_bucket, struct isst_fact_info *fact_info) 607 { 608 struct isst_pkg_ctdp_level_info ctdp_level; 609 struct isst_pkg_ctdp pkg_dev; 610 unsigned int resp; 611 int j, ret, print; 612 613 ret = isst_get_ctdp_levels(cpu, &pkg_dev); 614 if (ret) { 615 isst_display_error_info_message(1, "Failed to get number of levels", 0, 0); 616 return ret; 617 } 618 619 if (level > pkg_dev.levels) { 620 isst_display_error_info_message(1, "Invalid level", 1, level); 621 return -1; 622 } 623 624 ret = isst_get_ctdp_control(cpu, level, &ctdp_level); 625 if (ret) 626 return ret; 627 628 if (!ctdp_level.fact_support) { 629 isst_display_error_info_message(1, "turbo-freq feature is not present at this level", 1, level); 630 return -1; 631 } 632 633 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 634 CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO, 0, 635 level, &resp); 636 if (ret) 637 return ret; 638 639 debug_printf("cpu:%d CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO resp:%x\n", 640 cpu, resp); 641 642 fact_info->lp_clipping_ratio_license_sse = resp & 0xff; 643 fact_info->lp_clipping_ratio_license_avx2 = (resp >> 8) & 0xff; 644 fact_info->lp_clipping_ratio_license_avx512 = (resp >> 16) & 0xff; 645 646 ret = isst_get_fact_bucket_info(cpu, level, fact_info->bucket_info); 647 if (ret) 648 return ret; 649 650 print = 0; 651 for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) { 652 if (fact_bucket != 0xff && fact_bucket != j) 653 continue; 654 655 if (!fact_info->bucket_info[j].high_priority_cores_count) 656 break; 657 658 print = 1; 659 } 660 if (!print) { 661 isst_display_error_info_message(1, "Invalid bucket", 0, 0); 662 return -1; 663 } 664 665 return 0; 666 } 667 668 int isst_get_trl(int cpu, unsigned long long *trl) 669 { 670 int ret; 671 672 ret = isst_send_msr_command(cpu, 0x1AD, 0, trl); 673 if (ret) 674 return ret; 675 676 return 0; 677 } 678 679 int isst_set_trl(int cpu, unsigned long long trl) 680 { 681 int ret; 682 683 if (!trl) 684 trl = 0xFFFFFFFFFFFFFFFFULL; 685 686 ret = isst_send_msr_command(cpu, 0x1AD, 1, &trl); 687 if (ret) 688 return ret; 689 690 return 0; 691 } 692 693 int isst_set_trl_from_current_tdp(int cpu, unsigned long long trl) 694 { 695 unsigned long long msr_trl; 696 int ret; 697 698 if (trl) { 699 msr_trl = trl; 700 } else { 701 struct isst_pkg_ctdp pkg_dev; 702 int trl[8]; 703 int i; 704 705 ret = isst_get_ctdp_levels(cpu, &pkg_dev); 706 if (ret) 707 return ret; 708 709 ret = isst_get_get_trl(cpu, pkg_dev.current_level, 0, trl); 710 if (ret) 711 return ret; 712 713 msr_trl = 0; 714 for (i = 0; i < 8; ++i) { 715 unsigned long long _trl = trl[i]; 716 717 msr_trl |= (_trl << (i * 8)); 718 } 719 } 720 ret = isst_send_msr_command(cpu, 0x1AD, 1, &msr_trl); 721 if (ret) 722 return ret; 723 724 return 0; 725 } 726 727 /* Return 1 if locked */ 728 int isst_get_config_tdp_lock_status(int cpu) 729 { 730 unsigned long long tdp_control = 0; 731 int ret; 732 733 ret = isst_send_msr_command(cpu, 0x64b, 0, &tdp_control); 734 if (ret) 735 return ret; 736 737 ret = !!(tdp_control & BIT(31)); 738 739 return ret; 740 } 741 742 void isst_get_process_ctdp_complete(int cpu, struct isst_pkg_ctdp *pkg_dev) 743 { 744 int i; 745 746 if (!pkg_dev->processed) 747 return; 748 749 for (i = 0; i < pkg_dev->levels; ++i) { 750 struct isst_pkg_ctdp_level_info *ctdp_level; 751 752 ctdp_level = &pkg_dev->ctdp_level[i]; 753 if (ctdp_level->pbf_support) 754 free_cpu_set(ctdp_level->pbf_info.core_cpumask); 755 free_cpu_set(ctdp_level->core_cpumask); 756 } 757 } 758 759 int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) 760 { 761 int i, ret, valid = 0; 762 763 if (pkg_dev->processed) 764 return 0; 765 766 ret = isst_get_ctdp_levels(cpu, pkg_dev); 767 if (ret) 768 return ret; 769 770 debug_printf("cpu: %d ctdp enable:%d current level: %d levels:%d\n", 771 cpu, pkg_dev->enabled, pkg_dev->current_level, 772 pkg_dev->levels); 773 774 if (tdp_level != 0xff && tdp_level > pkg_dev->levels) { 775 isst_display_error_info_message(1, "Invalid level", 0, 0); 776 return -1; 777 } 778 779 if (!pkg_dev->enabled) 780 isst_display_error_info_message(0, "perf-profile feature is not supported, just base-config level 0 is valid", 0, 0); 781 782 for (i = 0; i <= pkg_dev->levels; ++i) { 783 struct isst_pkg_ctdp_level_info *ctdp_level; 784 785 if (tdp_level != 0xff && i != tdp_level) 786 continue; 787 788 debug_printf("cpu:%d Get Information for TDP level:%d\n", cpu, 789 i); 790 ctdp_level = &pkg_dev->ctdp_level[i]; 791 792 ctdp_level->level = i; 793 ctdp_level->control_cpu = cpu; 794 ctdp_level->pkg_id = get_physical_package_id(cpu); 795 ctdp_level->die_id = get_physical_die_id(cpu); 796 797 ret = isst_get_ctdp_control(cpu, i, ctdp_level); 798 if (ret) 799 continue; 800 801 valid = 1; 802 pkg_dev->processed = 1; 803 ctdp_level->processed = 1; 804 805 if (ctdp_level->pbf_support) { 806 ret = isst_get_pbf_info(cpu, i, &ctdp_level->pbf_info); 807 if (!ret) 808 ctdp_level->pbf_found = 1; 809 } 810 811 if (ctdp_level->fact_support) { 812 ret = isst_get_fact_info(cpu, i, 0xff, 813 &ctdp_level->fact_info); 814 if (ret) 815 return ret; 816 } 817 818 if (!pkg_dev->enabled && is_skx_based_platform()) { 819 int freq; 820 821 freq = get_cpufreq_base_freq(cpu); 822 if (freq > 0) { 823 ctdp_level->sse_p1 = freq / 100000; 824 ctdp_level->tdp_ratio = ctdp_level->sse_p1; 825 } 826 827 isst_get_get_trl_from_msr(cpu, ctdp_level->trl_sse_active_cores); 828 isst_get_trl_bucket_info(cpu, &ctdp_level->buckets_info); 829 continue; 830 } 831 832 ret = isst_get_tdp_info(cpu, i, ctdp_level); 833 if (ret) 834 return ret; 835 836 ret = isst_get_pwr_info(cpu, i, ctdp_level); 837 if (ret) 838 return ret; 839 840 ret = isst_get_tjmax_info(cpu, i, ctdp_level); 841 if (ret) 842 return ret; 843 844 ctdp_level->core_cpumask_size = 845 alloc_cpu_set(&ctdp_level->core_cpumask); 846 ret = isst_get_coremask_info(cpu, i, ctdp_level); 847 if (ret) 848 return ret; 849 850 ret = isst_get_trl_bucket_info(cpu, &ctdp_level->buckets_info); 851 if (ret) 852 return ret; 853 854 ret = isst_get_get_trl(cpu, i, 0, 855 ctdp_level->trl_sse_active_cores); 856 if (ret) 857 return ret; 858 859 ret = isst_get_get_trl(cpu, i, 1, 860 ctdp_level->trl_avx_active_cores); 861 if (ret) 862 return ret; 863 864 ret = isst_get_get_trl(cpu, i, 2, 865 ctdp_level->trl_avx_512_active_cores); 866 if (ret) 867 return ret; 868 869 isst_get_uncore_p0_p1_info(cpu, i, ctdp_level); 870 isst_get_p1_info(cpu, i, ctdp_level); 871 isst_get_uncore_mem_freq(cpu, i, ctdp_level); 872 } 873 874 if (!valid) 875 isst_display_error_info_message(0, "Invalid level, Can't get TDP control information at specified levels on cpu", 1, cpu); 876 877 return 0; 878 } 879 880 int isst_clos_get_clos_information(int cpu, int *enable, int *type) 881 { 882 unsigned int resp; 883 int ret; 884 885 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, 886 &resp); 887 if (ret) 888 return ret; 889 890 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp); 891 892 if (resp & BIT(1)) 893 *enable = 1; 894 else 895 *enable = 0; 896 897 if (resp & BIT(2)) 898 *type = 1; 899 else 900 *type = 0; 901 902 return 0; 903 } 904 905 int isst_pm_qos_config(int cpu, int enable_clos, int priority_type) 906 { 907 unsigned int req, resp; 908 int ret; 909 910 if (!enable_clos) { 911 struct isst_pkg_ctdp pkg_dev; 912 struct isst_pkg_ctdp_level_info ctdp_level; 913 914 ret = isst_get_ctdp_levels(cpu, &pkg_dev); 915 if (ret) { 916 debug_printf("isst_get_ctdp_levels\n"); 917 return ret; 918 } 919 920 ret = isst_get_ctdp_control(cpu, pkg_dev.current_level, 921 &ctdp_level); 922 if (ret) 923 return ret; 924 925 if (ctdp_level.fact_enabled) { 926 isst_display_error_info_message(1, "Ignoring request, turbo-freq feature is still enabled", 0, 0); 927 return -EINVAL; 928 } 929 ret = isst_write_pm_config(cpu, 0); 930 if (ret) 931 isst_display_error_info_message(0, "WRITE_PM_CONFIG command failed, ignoring error", 0, 0); 932 } else { 933 ret = isst_write_pm_config(cpu, 1); 934 if (ret) 935 isst_display_error_info_message(0, "WRITE_PM_CONFIG command failed, ignoring error", 0, 0); 936 } 937 938 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, 939 &resp); 940 if (ret) { 941 isst_display_error_info_message(1, "CLOS_PM_QOS_CONFIG command failed", 0, 0); 942 return ret; 943 } 944 945 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp); 946 947 req = resp; 948 949 if (enable_clos) 950 req = req | BIT(1); 951 else 952 req = req & ~BIT(1); 953 954 if (priority_type > 1) 955 isst_display_error_info_message(1, "Invalid priority type: Changing type to ordered", 0, 0); 956 957 if (priority_type) 958 req = req | BIT(2); 959 else 960 req = req & ~BIT(2); 961 962 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 963 BIT(MBOX_CMD_WRITE_BIT), req, &resp); 964 if (ret) 965 return ret; 966 967 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG priority type:%d req:%x\n", cpu, 968 priority_type, req); 969 970 return 0; 971 } 972 973 int isst_pm_get_clos(int cpu, int clos, struct isst_clos_config *clos_config) 974 { 975 unsigned int resp; 976 int ret; 977 978 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0, 979 &resp); 980 if (ret) 981 return ret; 982 983 clos_config->pkg_id = get_physical_package_id(cpu); 984 clos_config->die_id = get_physical_die_id(cpu); 985 986 clos_config->epp = resp & 0x0f; 987 clos_config->clos_prop_prio = (resp >> 4) & 0x0f; 988 clos_config->clos_min = (resp >> 8) & 0xff; 989 clos_config->clos_max = (resp >> 16) & 0xff; 990 clos_config->clos_desired = (resp >> 24) & 0xff; 991 992 return 0; 993 } 994 995 int isst_set_clos(int cpu, int clos, struct isst_clos_config *clos_config) 996 { 997 unsigned int req, resp; 998 unsigned int param; 999 int ret; 1000 1001 req = clos_config->epp & 0x0f; 1002 req |= (clos_config->clos_prop_prio & 0x0f) << 4; 1003 req |= (clos_config->clos_min & 0xff) << 8; 1004 req |= (clos_config->clos_max & 0xff) << 16; 1005 req |= (clos_config->clos_desired & 0xff) << 24; 1006 1007 param = BIT(MBOX_CMD_WRITE_BIT) | clos; 1008 1009 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req, 1010 &resp); 1011 if (ret) 1012 return ret; 1013 1014 debug_printf("cpu:%d CLOS_PM_CLOS param:%x req:%x\n", cpu, param, req); 1015 1016 return 0; 1017 } 1018 1019 int isst_clos_get_assoc_status(int cpu, int *clos_id) 1020 { 1021 unsigned int resp; 1022 unsigned int param; 1023 int core_id, ret; 1024 1025 core_id = find_phy_core_num(cpu); 1026 param = core_id; 1027 1028 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0, 1029 &resp); 1030 if (ret) 1031 return ret; 1032 1033 debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x resp:%x\n", cpu, param, 1034 resp); 1035 *clos_id = (resp >> 16) & 0x03; 1036 1037 return 0; 1038 } 1039 1040 int isst_clos_associate(int cpu, int clos_id) 1041 { 1042 unsigned int req, resp; 1043 unsigned int param; 1044 int core_id, ret; 1045 1046 req = (clos_id & 0x03) << 16; 1047 core_id = find_phy_core_num(cpu); 1048 param = BIT(MBOX_CMD_WRITE_BIT) | core_id; 1049 1050 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 1051 req, &resp); 1052 if (ret) 1053 return ret; 1054 1055 debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x req:%x\n", cpu, param, 1056 req); 1057 1058 return 0; 1059 } 1060