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