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 return ret; 119 120 ctdp_level->pkg_tdp = resp & GENMASK(14, 0); 121 ctdp_level->tdp_ratio = (resp & GENMASK(23, 16)) >> 16; 122 123 debug_printf( 124 "cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO resp:%x tdp_ratio:%d pkg_tdp:%d\n", 125 cpu, config_index, resp, ctdp_level->tdp_ratio, 126 ctdp_level->pkg_tdp); 127 return 0; 128 } 129 130 int isst_get_pwr_info(int cpu, int config_index, 131 struct isst_pkg_ctdp_level_info *ctdp_level) 132 { 133 unsigned int resp; 134 int ret; 135 136 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_PWR_INFO, 137 0, config_index, &resp); 138 if (ret) 139 return ret; 140 141 ctdp_level->pkg_max_power = resp & GENMASK(14, 0); 142 ctdp_level->pkg_min_power = (resp & GENMASK(30, 16)) >> 16; 143 144 debug_printf( 145 "cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO resp:%x pkg_max_power:%d pkg_min_power:%d\n", 146 cpu, config_index, resp, ctdp_level->pkg_max_power, 147 ctdp_level->pkg_min_power); 148 149 return 0; 150 } 151 152 void isst_get_uncore_p0_p1_info(int cpu, int config_index, 153 struct isst_pkg_ctdp_level_info *ctdp_level) 154 { 155 unsigned int resp; 156 int ret; 157 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 158 CONFIG_TDP_GET_UNCORE_P0_P1_INFO, 0, 159 config_index, &resp); 160 if (ret) { 161 ctdp_level->uncore_p0 = 0; 162 ctdp_level->uncore_p1 = 0; 163 return; 164 } 165 166 ctdp_level->uncore_p0 = resp & GENMASK(7, 0); 167 ctdp_level->uncore_p1 = (resp & GENMASK(15, 8)) >> 8; 168 debug_printf( 169 "cpu:%d ctdp:%d CONFIG_TDP_GET_UNCORE_P0_P1_INFO resp:%x uncore p0:%d uncore p1:%d\n", 170 cpu, config_index, resp, ctdp_level->uncore_p0, 171 ctdp_level->uncore_p1); 172 } 173 174 void isst_get_p1_info(int cpu, int config_index, 175 struct isst_pkg_ctdp_level_info *ctdp_level) 176 { 177 unsigned int resp; 178 int ret; 179 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_P1_INFO, 0, 180 config_index, &resp); 181 if (ret) { 182 ctdp_level->sse_p1 = 0; 183 ctdp_level->avx2_p1 = 0; 184 ctdp_level->avx512_p1 = 0; 185 return; 186 } 187 188 ctdp_level->sse_p1 = resp & GENMASK(7, 0); 189 ctdp_level->avx2_p1 = (resp & GENMASK(15, 8)) >> 8; 190 ctdp_level->avx512_p1 = (resp & GENMASK(23, 16)) >> 16; 191 debug_printf( 192 "cpu:%d ctdp:%d CONFIG_TDP_GET_P1_INFO resp:%x sse_p1:%d avx2_p1:%d avx512_p1:%d\n", 193 cpu, config_index, resp, ctdp_level->sse_p1, 194 ctdp_level->avx2_p1, ctdp_level->avx512_p1); 195 } 196 197 void isst_get_uncore_mem_freq(int cpu, int config_index, 198 struct isst_pkg_ctdp_level_info *ctdp_level) 199 { 200 unsigned int resp; 201 int ret; 202 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_MEM_FREQ, 203 0, config_index, &resp); 204 if (ret) { 205 ctdp_level->mem_freq = 0; 206 return; 207 } 208 209 ctdp_level->mem_freq = resp & GENMASK(7, 0); 210 debug_printf( 211 "cpu:%d ctdp:%d CONFIG_TDP_GET_MEM_FREQ resp:%x uncore mem_freq:%d\n", 212 cpu, config_index, resp, ctdp_level->mem_freq); 213 } 214 215 int isst_get_tjmax_info(int cpu, int config_index, 216 struct isst_pkg_ctdp_level_info *ctdp_level) 217 { 218 unsigned int resp; 219 int ret; 220 221 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_TJMAX_INFO, 222 0, config_index, &resp); 223 if (ret) 224 return ret; 225 226 ctdp_level->t_proc_hot = resp & GENMASK(7, 0); 227 228 debug_printf( 229 "cpu:%d ctdp:%d CONFIG_TDP_GET_TJMAX_INFO resp:%x t_proc_hot:%d\n", 230 cpu, config_index, resp, ctdp_level->t_proc_hot); 231 232 return 0; 233 } 234 235 int isst_get_coremask_info(int cpu, int config_index, 236 struct isst_pkg_ctdp_level_info *ctdp_level) 237 { 238 unsigned int resp; 239 int i, ret; 240 241 ctdp_level->cpu_count = 0; 242 for (i = 0; i < 2; ++i) { 243 unsigned long long mask; 244 int cpu_count = 0; 245 246 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 247 CONFIG_TDP_GET_CORE_MASK, 0, 248 (i << 8) | config_index, &resp); 249 if (ret) 250 return ret; 251 252 debug_printf( 253 "cpu:%d ctdp:%d mask:%d CONFIG_TDP_GET_CORE_MASK resp:%x\n", 254 cpu, config_index, i, resp); 255 256 mask = (unsigned long long)resp << (32 * i); 257 set_cpu_mask_from_punit_coremask(cpu, mask, 258 ctdp_level->core_cpumask_size, 259 ctdp_level->core_cpumask, 260 &cpu_count); 261 ctdp_level->cpu_count += cpu_count; 262 debug_printf("cpu:%d ctdp:%d mask:%d cpu count:%d\n", cpu, 263 config_index, i, ctdp_level->cpu_count); 264 } 265 266 return 0; 267 } 268 269 int isst_get_get_trl_from_msr(int cpu, int *trl) 270 { 271 unsigned long long msr_trl; 272 int ret; 273 274 ret = isst_send_msr_command(cpu, 0x1AD, 0, &msr_trl); 275 if (ret) 276 return ret; 277 278 trl[0] = msr_trl & GENMASK(7, 0); 279 trl[1] = (msr_trl & GENMASK(15, 8)) >> 8; 280 trl[2] = (msr_trl & GENMASK(23, 16)) >> 16; 281 trl[3] = (msr_trl & GENMASK(31, 24)) >> 24; 282 trl[4] = (msr_trl & GENMASK(39, 32)) >> 32; 283 trl[5] = (msr_trl & GENMASK(47, 40)) >> 40; 284 trl[6] = (msr_trl & GENMASK(55, 48)) >> 48; 285 trl[7] = (msr_trl & GENMASK(63, 56)) >> 56; 286 287 return 0; 288 } 289 290 int isst_get_get_trl(int cpu, int level, int avx_level, int *trl) 291 { 292 unsigned int req, resp; 293 int ret; 294 295 req = level | (avx_level << 16); 296 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 297 CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req, 298 &resp); 299 if (ret) 300 return ret; 301 302 debug_printf( 303 "cpu:%d CONFIG_TDP_GET_TURBO_LIMIT_RATIOS req:%x resp:%x\n", 304 cpu, req, resp); 305 306 trl[0] = resp & GENMASK(7, 0); 307 trl[1] = (resp & GENMASK(15, 8)) >> 8; 308 trl[2] = (resp & GENMASK(23, 16)) >> 16; 309 trl[3] = (resp & GENMASK(31, 24)) >> 24; 310 311 req = level | BIT(8) | (avx_level << 16); 312 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 313 CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req, 314 &resp); 315 if (ret) 316 return ret; 317 318 debug_printf("cpu:%d CONFIG_TDP_GET_TURBO_LIMIT req:%x resp:%x\n", cpu, 319 req, resp); 320 321 trl[4] = resp & GENMASK(7, 0); 322 trl[5] = (resp & GENMASK(15, 8)) >> 8; 323 trl[6] = (resp & GENMASK(23, 16)) >> 16; 324 trl[7] = (resp & GENMASK(31, 24)) >> 24; 325 326 return 0; 327 } 328 329 int isst_get_trl_bucket_info(int cpu, unsigned long long *buckets_info) 330 { 331 int ret; 332 333 debug_printf("cpu:%d bucket info via MSR\n", cpu); 334 335 *buckets_info = 0; 336 337 ret = isst_send_msr_command(cpu, 0x1ae, 0, buckets_info); 338 if (ret) 339 return ret; 340 341 debug_printf("cpu:%d bucket info via MSR successful 0x%llx\n", cpu, 342 *buckets_info); 343 344 return 0; 345 } 346 347 int isst_set_tdp_level_msr(int cpu, int tdp_level) 348 { 349 unsigned long long level = tdp_level; 350 int ret; 351 352 debug_printf("cpu: tdp_level via MSR %d\n", cpu, tdp_level); 353 354 if (isst_get_config_tdp_lock_status(cpu)) { 355 debug_printf("cpu: tdp_locked %d\n", cpu); 356 return -1; 357 } 358 359 if (tdp_level > 2) 360 return -1; /* invalid value */ 361 362 ret = isst_send_msr_command(cpu, 0x64b, 1, &level); 363 if (ret) 364 return ret; 365 366 debug_printf("cpu: tdp_level via MSR successful %d\n", cpu, tdp_level); 367 368 return 0; 369 } 370 371 int isst_set_tdp_level(int cpu, int tdp_level) 372 { 373 unsigned int resp; 374 int ret; 375 376 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_SET_LEVEL, 0, 377 tdp_level, &resp); 378 if (ret) 379 return isst_set_tdp_level_msr(cpu, tdp_level); 380 381 return 0; 382 } 383 384 int isst_get_pbf_info(int cpu, int level, struct isst_pbf_info *pbf_info) 385 { 386 int i, ret, core_cnt, max; 387 unsigned int req, resp; 388 389 pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask); 390 391 core_cnt = get_core_count(get_physical_package_id(cpu), get_physical_die_id(cpu)); 392 max = core_cnt > 32 ? 2 : 1; 393 394 for (i = 0; i < max; ++i) { 395 unsigned long long mask; 396 int count; 397 398 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 399 CONFIG_TDP_PBF_GET_CORE_MASK_INFO, 400 0, (i << 8) | level, &resp); 401 if (ret) 402 break; 403 404 debug_printf( 405 "cpu:%d CONFIG_TDP_PBF_GET_CORE_MASK_INFO resp:%x\n", 406 cpu, resp); 407 408 mask = (unsigned long long)resp << (32 * i); 409 set_cpu_mask_from_punit_coremask(cpu, mask, 410 pbf_info->core_cpumask_size, 411 pbf_info->core_cpumask, 412 &count); 413 } 414 415 req = level; 416 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 417 CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO, 0, req, 418 &resp); 419 if (ret) 420 return ret; 421 422 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO resp:%x\n", cpu, 423 resp); 424 425 pbf_info->p1_low = resp & 0xff; 426 pbf_info->p1_high = (resp & GENMASK(15, 8)) >> 8; 427 428 req = level; 429 ret = isst_send_mbox_command( 430 cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TDP_INFO, 0, req, &resp); 431 if (ret) 432 return ret; 433 434 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TDP_INFO resp:%x\n", cpu, resp); 435 436 pbf_info->tdp = resp & 0xffff; 437 438 req = level; 439 ret = isst_send_mbox_command( 440 cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TJ_MAX_INFO, 0, req, &resp); 441 if (ret) 442 return ret; 443 444 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TJ_MAX_INFO resp:%x\n", cpu, 445 resp); 446 pbf_info->t_control = (resp >> 8) & 0xff; 447 pbf_info->t_prochot = resp & 0xff; 448 449 return 0; 450 } 451 452 void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info) 453 { 454 free_cpu_set(pbf_info->core_cpumask); 455 } 456 457 int isst_set_pbf_fact_status(int cpu, int pbf, int enable) 458 { 459 struct isst_pkg_ctdp pkg_dev; 460 struct isst_pkg_ctdp_level_info ctdp_level; 461 int current_level; 462 unsigned int req = 0, resp; 463 int ret; 464 465 ret = isst_get_ctdp_levels(cpu, &pkg_dev); 466 if (ret) 467 debug_printf("cpu:%d No support for dynamic ISST\n", cpu); 468 469 current_level = pkg_dev.current_level; 470 471 ret = isst_get_ctdp_control(cpu, current_level, &ctdp_level); 472 if (ret) 473 return ret; 474 475 if (pbf) { 476 if (ctdp_level.fact_enabled) 477 req = BIT(16); 478 479 if (enable) 480 req |= BIT(17); 481 else 482 req &= ~BIT(17); 483 } else { 484 if (ctdp_level.pbf_enabled) 485 req = BIT(17); 486 487 if (enable) 488 req |= BIT(16); 489 else 490 req &= ~BIT(16); 491 } 492 493 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 494 CONFIG_TDP_SET_TDP_CONTROL, 0, req, &resp); 495 if (ret) 496 return ret; 497 498 debug_printf("cpu:%d CONFIG_TDP_SET_TDP_CONTROL pbf/fact:%d req:%x\n", 499 cpu, pbf, req); 500 501 return 0; 502 } 503 504 int isst_get_fact_bucket_info(int cpu, int level, 505 struct isst_fact_bucket_info *bucket_info) 506 { 507 unsigned int resp; 508 int i, k, ret; 509 510 for (i = 0; i < 2; ++i) { 511 int j; 512 513 ret = isst_send_mbox_command( 514 cpu, CONFIG_TDP, 515 CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES, 0, 516 (i << 8) | level, &resp); 517 if (ret) 518 return ret; 519 520 debug_printf( 521 "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES index:%d level:%d resp:%x\n", 522 cpu, i, level, resp); 523 524 for (j = 0; j < 4; ++j) { 525 bucket_info[j + (i * 4)].high_priority_cores_count = 526 (resp >> (j * 8)) & 0xff; 527 } 528 } 529 530 for (k = 0; k < 3; ++k) { 531 for (i = 0; i < 2; ++i) { 532 int j; 533 534 ret = isst_send_mbox_command( 535 cpu, CONFIG_TDP, 536 CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS, 0, 537 (k << 16) | (i << 8) | level, &resp); 538 if (ret) 539 return ret; 540 541 debug_printf( 542 "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS index:%d level:%d avx:%d resp:%x\n", 543 cpu, i, level, k, resp); 544 545 for (j = 0; j < 4; ++j) { 546 switch (k) { 547 case 0: 548 bucket_info[j + (i * 4)].sse_trl = 549 (resp >> (j * 8)) & 0xff; 550 break; 551 case 1: 552 bucket_info[j + (i * 4)].avx_trl = 553 (resp >> (j * 8)) & 0xff; 554 break; 555 case 2: 556 bucket_info[j + (i * 4)].avx512_trl = 557 (resp >> (j * 8)) & 0xff; 558 break; 559 default: 560 break; 561 } 562 } 563 } 564 } 565 566 return 0; 567 } 568 569 int isst_get_fact_info(int cpu, int level, struct isst_fact_info *fact_info) 570 { 571 unsigned int resp; 572 int ret; 573 574 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 575 CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO, 0, 576 level, &resp); 577 if (ret) 578 return ret; 579 580 debug_printf("cpu:%d CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO resp:%x\n", 581 cpu, resp); 582 583 fact_info->lp_clipping_ratio_license_sse = resp & 0xff; 584 fact_info->lp_clipping_ratio_license_avx2 = (resp >> 8) & 0xff; 585 fact_info->lp_clipping_ratio_license_avx512 = (resp >> 16) & 0xff; 586 587 ret = isst_get_fact_bucket_info(cpu, level, fact_info->bucket_info); 588 589 return ret; 590 } 591 592 int isst_set_trl(int cpu, unsigned long long trl) 593 { 594 int ret; 595 596 if (!trl) 597 trl = 0xFFFFFFFFFFFFFFFFULL; 598 599 ret = isst_send_msr_command(cpu, 0x1AD, 1, &trl); 600 if (ret) 601 return ret; 602 603 return 0; 604 } 605 606 int isst_set_trl_from_current_tdp(int cpu, unsigned long long trl) 607 { 608 unsigned long long msr_trl; 609 int ret; 610 611 if (trl) { 612 msr_trl = trl; 613 } else { 614 struct isst_pkg_ctdp pkg_dev; 615 int trl[8]; 616 int i; 617 618 ret = isst_get_ctdp_levels(cpu, &pkg_dev); 619 if (ret) 620 return ret; 621 622 ret = isst_get_get_trl(cpu, pkg_dev.current_level, 0, trl); 623 if (ret) 624 return ret; 625 626 msr_trl = 0; 627 for (i = 0; i < 8; ++i) { 628 unsigned long long _trl = trl[i]; 629 630 msr_trl |= (_trl << (i * 8)); 631 } 632 } 633 ret = isst_send_msr_command(cpu, 0x1AD, 1, &msr_trl); 634 if (ret) 635 return ret; 636 637 return 0; 638 } 639 640 /* Return 1 if locked */ 641 int isst_get_config_tdp_lock_status(int cpu) 642 { 643 unsigned long long tdp_control = 0; 644 int ret; 645 646 ret = isst_send_msr_command(cpu, 0x64b, 0, &tdp_control); 647 if (ret) 648 return ret; 649 650 ret = !!(tdp_control & BIT(31)); 651 652 return ret; 653 } 654 655 void isst_get_process_ctdp_complete(int cpu, struct isst_pkg_ctdp *pkg_dev) 656 { 657 int i; 658 659 if (!pkg_dev->processed) 660 return; 661 662 for (i = 0; i < pkg_dev->levels; ++i) { 663 struct isst_pkg_ctdp_level_info *ctdp_level; 664 665 ctdp_level = &pkg_dev->ctdp_level[i]; 666 if (ctdp_level->pbf_support) 667 free_cpu_set(ctdp_level->pbf_info.core_cpumask); 668 free_cpu_set(ctdp_level->core_cpumask); 669 } 670 } 671 672 int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) 673 { 674 int i, ret; 675 676 if (pkg_dev->processed) 677 return 0; 678 679 ret = isst_get_ctdp_levels(cpu, pkg_dev); 680 if (ret) 681 return ret; 682 683 debug_printf("cpu: %d ctdp enable:%d current level: %d levels:%d\n", 684 cpu, pkg_dev->enabled, pkg_dev->current_level, 685 pkg_dev->levels); 686 687 for (i = 0; i <= pkg_dev->levels; ++i) { 688 struct isst_pkg_ctdp_level_info *ctdp_level; 689 690 if (tdp_level != 0xff && i != tdp_level) 691 continue; 692 693 debug_printf("cpu:%d Get Information for TDP level:%d\n", cpu, 694 i); 695 ctdp_level = &pkg_dev->ctdp_level[i]; 696 697 ctdp_level->level = i; 698 ctdp_level->control_cpu = cpu; 699 ctdp_level->pkg_id = get_physical_package_id(cpu); 700 ctdp_level->die_id = get_physical_die_id(cpu); 701 702 ret = isst_get_ctdp_control(cpu, i, ctdp_level); 703 if (ret) 704 continue; 705 706 pkg_dev->processed = 1; 707 ctdp_level->processed = 1; 708 709 if (ctdp_level->pbf_support) { 710 ret = isst_get_pbf_info(cpu, i, &ctdp_level->pbf_info); 711 if (!ret) 712 ctdp_level->pbf_found = 1; 713 } 714 715 if (ctdp_level->fact_support) { 716 ret = isst_get_fact_info(cpu, i, 717 &ctdp_level->fact_info); 718 if (ret) 719 return ret; 720 } 721 722 if (!pkg_dev->enabled) { 723 int freq; 724 725 freq = get_cpufreq_base_freq(cpu); 726 if (freq > 0) { 727 ctdp_level->sse_p1 = freq / 100000; 728 ctdp_level->tdp_ratio = ctdp_level->sse_p1; 729 } 730 731 isst_get_get_trl_from_msr(cpu, ctdp_level->trl_sse_active_cores); 732 isst_get_trl_bucket_info(cpu, &ctdp_level->buckets_info); 733 continue; 734 } 735 736 ret = isst_get_tdp_info(cpu, i, ctdp_level); 737 if (ret) 738 return ret; 739 740 ret = isst_get_pwr_info(cpu, i, ctdp_level); 741 if (ret) 742 return ret; 743 744 ret = isst_get_tjmax_info(cpu, i, ctdp_level); 745 if (ret) 746 return ret; 747 748 ctdp_level->core_cpumask_size = 749 alloc_cpu_set(&ctdp_level->core_cpumask); 750 ret = isst_get_coremask_info(cpu, i, ctdp_level); 751 if (ret) 752 return ret; 753 754 ret = isst_get_trl_bucket_info(cpu, &ctdp_level->buckets_info); 755 if (ret) 756 return ret; 757 758 ret = isst_get_get_trl(cpu, i, 0, 759 ctdp_level->trl_sse_active_cores); 760 if (ret) 761 return ret; 762 763 ret = isst_get_get_trl(cpu, i, 1, 764 ctdp_level->trl_avx_active_cores); 765 if (ret) 766 return ret; 767 768 ret = isst_get_get_trl(cpu, i, 2, 769 ctdp_level->trl_avx_512_active_cores); 770 if (ret) 771 return ret; 772 773 isst_get_uncore_p0_p1_info(cpu, i, ctdp_level); 774 isst_get_p1_info(cpu, i, ctdp_level); 775 isst_get_uncore_mem_freq(cpu, i, ctdp_level); 776 } 777 778 return 0; 779 } 780 781 int isst_clos_get_clos_information(int cpu, int *enable, int *type) 782 { 783 unsigned int resp; 784 int ret; 785 786 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, 787 &resp); 788 if (ret) 789 return ret; 790 791 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp); 792 793 if (resp & BIT(1)) 794 *enable = 1; 795 else 796 *enable = 0; 797 798 if (resp & BIT(2)) 799 *type = 1; 800 else 801 *type = 0; 802 803 return 0; 804 } 805 806 int isst_pm_qos_config(int cpu, int enable_clos, int priority_type) 807 { 808 unsigned int req, resp; 809 int ret; 810 811 if (!enable_clos) { 812 struct isst_pkg_ctdp pkg_dev; 813 struct isst_pkg_ctdp_level_info ctdp_level; 814 815 ret = isst_get_ctdp_levels(cpu, &pkg_dev); 816 if (ret) { 817 debug_printf("isst_get_ctdp_levels\n"); 818 return ret; 819 } 820 821 ret = isst_get_ctdp_control(cpu, pkg_dev.current_level, 822 &ctdp_level); 823 if (ret) 824 return ret; 825 826 if (ctdp_level.fact_enabled) { 827 debug_printf("Turbo-freq feature must be disabled first\n"); 828 return -EINVAL; 829 } 830 ret = isst_write_pm_config(cpu, 0); 831 if (ret) 832 perror("isst_write_pm_config\n"); 833 } else { 834 ret = isst_write_pm_config(cpu, 1); 835 if (ret) 836 perror("isst_write_pm_config\n"); 837 } 838 839 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, 840 &resp); 841 if (ret) 842 return ret; 843 844 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp); 845 846 req = resp; 847 848 if (enable_clos) 849 req = req | BIT(1); 850 else 851 req = req & ~BIT(1); 852 853 if (priority_type) 854 req = req | BIT(2); 855 else 856 req = req & ~BIT(2); 857 858 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 859 BIT(MBOX_CMD_WRITE_BIT), req, &resp); 860 if (ret) 861 return ret; 862 863 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG priority type:%d req:%x\n", cpu, 864 priority_type, req); 865 866 return 0; 867 } 868 869 int isst_pm_get_clos(int cpu, int clos, struct isst_clos_config *clos_config) 870 { 871 unsigned int resp; 872 int ret; 873 874 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0, 875 &resp); 876 if (ret) 877 return ret; 878 879 clos_config->pkg_id = get_physical_package_id(cpu); 880 clos_config->die_id = get_physical_die_id(cpu); 881 882 clos_config->epp = resp & 0x0f; 883 clos_config->clos_prop_prio = (resp >> 4) & 0x0f; 884 clos_config->clos_min = (resp >> 8) & 0xff; 885 clos_config->clos_max = (resp >> 16) & 0xff; 886 clos_config->clos_desired = (resp >> 24) & 0xff; 887 888 return 0; 889 } 890 891 int isst_set_clos(int cpu, int clos, struct isst_clos_config *clos_config) 892 { 893 unsigned int req, resp; 894 unsigned int param; 895 int ret; 896 897 req = clos_config->epp & 0x0f; 898 req |= (clos_config->clos_prop_prio & 0x0f) << 4; 899 req |= (clos_config->clos_min & 0xff) << 8; 900 req |= (clos_config->clos_max & 0xff) << 16; 901 req |= (clos_config->clos_desired & 0xff) << 24; 902 903 param = BIT(MBOX_CMD_WRITE_BIT) | clos; 904 905 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req, 906 &resp); 907 if (ret) 908 return ret; 909 910 debug_printf("cpu:%d CLOS_PM_CLOS param:%x req:%x\n", cpu, param, req); 911 912 return 0; 913 } 914 915 int isst_clos_get_assoc_status(int cpu, int *clos_id) 916 { 917 unsigned int resp; 918 unsigned int param; 919 int core_id, ret; 920 921 core_id = find_phy_core_num(cpu); 922 param = core_id; 923 924 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0, 925 &resp); 926 if (ret) 927 return ret; 928 929 debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x resp:%x\n", cpu, param, 930 resp); 931 *clos_id = (resp >> 16) & 0x03; 932 933 return 0; 934 } 935 936 int isst_clos_associate(int cpu, int clos_id) 937 { 938 unsigned int req, resp; 939 unsigned int param; 940 int core_id, ret; 941 942 req = (clos_id & 0x03) << 16; 943 core_id = find_phy_core_num(cpu); 944 param = BIT(MBOX_CMD_WRITE_BIT) | core_id; 945 946 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 947 req, &resp); 948 if (ret) 949 return ret; 950 951 debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x req:%x\n", cpu, param, 952 req); 953 954 return 0; 955 } 956