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_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev) 10 { 11 unsigned int resp; 12 int ret; 13 14 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 15 CONFIG_TDP_GET_LEVELS_INFO, 0, 0, &resp); 16 if (ret) 17 return ret; 18 19 debug_printf("cpu:%d CONFIG_TDP_GET_LEVELS_INFO resp:%x\n", cpu, resp); 20 21 pkg_dev->version = resp & 0xff; 22 pkg_dev->levels = (resp >> 8) & 0xff; 23 pkg_dev->current_level = (resp >> 16) & 0xff; 24 pkg_dev->locked = !!(resp & BIT(24)); 25 pkg_dev->enabled = !!(resp & BIT(31)); 26 27 return 0; 28 } 29 30 int isst_get_ctdp_control(int cpu, int config_index, 31 struct isst_pkg_ctdp_level_info *ctdp_level) 32 { 33 unsigned int resp; 34 int ret; 35 36 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 37 CONFIG_TDP_GET_TDP_CONTROL, 0, 38 config_index, &resp); 39 if (ret) 40 return ret; 41 42 ctdp_level->fact_support = resp & BIT(0); 43 ctdp_level->pbf_support = !!(resp & BIT(1)); 44 ctdp_level->fact_enabled = !!(resp & BIT(16)); 45 ctdp_level->pbf_enabled = !!(resp & BIT(17)); 46 47 debug_printf( 48 "cpu:%d CONFIG_TDP_GET_TDP_CONTROL resp:%x fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n", 49 cpu, resp, ctdp_level->fact_support, ctdp_level->pbf_support, 50 ctdp_level->fact_enabled, ctdp_level->pbf_enabled); 51 52 return 0; 53 } 54 55 int isst_get_tdp_info(int cpu, int config_index, 56 struct isst_pkg_ctdp_level_info *ctdp_level) 57 { 58 unsigned int resp; 59 int ret; 60 61 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO, 62 0, config_index, &resp); 63 if (ret) 64 return ret; 65 66 ctdp_level->pkg_tdp = resp & GENMASK(14, 0); 67 ctdp_level->tdp_ratio = (resp & GENMASK(23, 16)) >> 16; 68 69 debug_printf( 70 "cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO resp:%x tdp_ratio:%d pkg_tdp:%d\n", 71 cpu, config_index, resp, ctdp_level->tdp_ratio, 72 ctdp_level->pkg_tdp); 73 return 0; 74 } 75 76 int isst_get_pwr_info(int cpu, int config_index, 77 struct isst_pkg_ctdp_level_info *ctdp_level) 78 { 79 unsigned int resp; 80 int ret; 81 82 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_PWR_INFO, 83 0, config_index, &resp); 84 if (ret) 85 return ret; 86 87 ctdp_level->pkg_max_power = resp & GENMASK(14, 0); 88 ctdp_level->pkg_min_power = (resp & GENMASK(30, 16)) >> 16; 89 90 debug_printf( 91 "cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO resp:%x pkg_max_power:%d pkg_min_power:%d\n", 92 cpu, config_index, resp, ctdp_level->pkg_max_power, 93 ctdp_level->pkg_min_power); 94 95 return 0; 96 } 97 98 int isst_get_tjmax_info(int cpu, int config_index, 99 struct isst_pkg_ctdp_level_info *ctdp_level) 100 { 101 unsigned int resp; 102 int ret; 103 104 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_TJMAX_INFO, 105 0, config_index, &resp); 106 if (ret) 107 return ret; 108 109 ctdp_level->t_proc_hot = resp & GENMASK(7, 0); 110 111 debug_printf( 112 "cpu:%d ctdp:%d CONFIG_TDP_GET_TJMAX_INFO resp:%x t_proc_hot:%d\n", 113 cpu, config_index, resp, ctdp_level->t_proc_hot); 114 115 return 0; 116 } 117 118 int isst_get_coremask_info(int cpu, int config_index, 119 struct isst_pkg_ctdp_level_info *ctdp_level) 120 { 121 unsigned int resp; 122 int i, ret; 123 124 ctdp_level->cpu_count = 0; 125 for (i = 0; i < 2; ++i) { 126 unsigned long long mask; 127 int cpu_count = 0; 128 129 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 130 CONFIG_TDP_GET_CORE_MASK, 0, 131 (i << 8) | config_index, &resp); 132 if (ret) 133 return ret; 134 135 debug_printf( 136 "cpu:%d ctdp:%d mask:%d CONFIG_TDP_GET_CORE_MASK resp:%x\n", 137 cpu, config_index, i, resp); 138 139 mask = (unsigned long long)resp << (32 * i); 140 set_cpu_mask_from_punit_coremask(cpu, mask, 141 ctdp_level->core_cpumask_size, 142 ctdp_level->core_cpumask, 143 &cpu_count); 144 ctdp_level->cpu_count += cpu_count; 145 debug_printf("cpu:%d ctdp:%d mask:%d cpu count:%d\n", cpu, 146 config_index, i, ctdp_level->cpu_count); 147 } 148 149 return 0; 150 } 151 152 int isst_get_get_trl(int cpu, int level, int avx_level, int *trl) 153 { 154 unsigned int req, resp; 155 int ret; 156 157 req = level | (avx_level << 16); 158 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 159 CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req, 160 &resp); 161 if (ret) 162 return ret; 163 164 debug_printf( 165 "cpu:%d CONFIG_TDP_GET_TURBO_LIMIT_RATIOS req:%x resp:%x\n", 166 cpu, req, resp); 167 168 trl[0] = resp & GENMASK(7, 0); 169 trl[1] = (resp & GENMASK(15, 8)) >> 8; 170 trl[2] = (resp & GENMASK(23, 16)) >> 16; 171 trl[3] = (resp & GENMASK(31, 24)) >> 24; 172 173 req = level | BIT(8) | (avx_level << 16); 174 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 175 CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req, 176 &resp); 177 if (ret) 178 return ret; 179 180 debug_printf("cpu:%d CONFIG_TDP_GET_TURBO_LIMIT req:%x resp:%x\n", cpu, 181 req, resp); 182 183 trl[4] = resp & GENMASK(7, 0); 184 trl[5] = (resp & GENMASK(15, 8)) >> 8; 185 trl[6] = (resp & GENMASK(23, 16)) >> 16; 186 trl[7] = (resp & GENMASK(31, 24)) >> 24; 187 188 return 0; 189 } 190 191 int isst_get_trl_bucket_info(int cpu, unsigned long long *buckets_info) 192 { 193 int ret; 194 195 debug_printf("cpu:%d bucket info via MSR\n", cpu); 196 197 *buckets_info = 0; 198 199 ret = isst_send_msr_command(cpu, 0x1ae, 0, buckets_info); 200 if (ret) 201 return ret; 202 203 debug_printf("cpu:%d bucket info via MSR successful 0x%llx\n", cpu, 204 *buckets_info); 205 206 return 0; 207 } 208 209 int isst_set_tdp_level_msr(int cpu, int tdp_level) 210 { 211 unsigned long long level = tdp_level; 212 int ret; 213 214 debug_printf("cpu: tdp_level via MSR %d\n", cpu, tdp_level); 215 216 if (isst_get_config_tdp_lock_status(cpu)) { 217 debug_printf("cpu: tdp_locked %d\n", cpu); 218 return -1; 219 } 220 221 if (tdp_level > 2) 222 return -1; /* invalid value */ 223 224 ret = isst_send_msr_command(cpu, 0x64b, 1, &level); 225 if (ret) 226 return ret; 227 228 debug_printf("cpu: tdp_level via MSR successful %d\n", cpu, tdp_level); 229 230 return 0; 231 } 232 233 int isst_set_tdp_level(int cpu, int tdp_level) 234 { 235 unsigned int resp; 236 int ret; 237 238 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_SET_LEVEL, 0, 239 tdp_level, &resp); 240 if (ret) 241 return isst_set_tdp_level_msr(cpu, tdp_level); 242 243 return 0; 244 } 245 246 int isst_get_pbf_info(int cpu, int level, struct isst_pbf_info *pbf_info) 247 { 248 unsigned int req, resp; 249 int i, ret; 250 251 pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask); 252 253 for (i = 0; i < 2; ++i) { 254 unsigned long long mask; 255 int count; 256 257 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 258 CONFIG_TDP_PBF_GET_CORE_MASK_INFO, 259 0, (i << 8) | level, &resp); 260 if (ret) 261 return ret; 262 263 debug_printf( 264 "cpu:%d CONFIG_TDP_PBF_GET_CORE_MASK_INFO resp:%x\n", 265 cpu, resp); 266 267 mask = (unsigned long long)resp << (32 * i); 268 set_cpu_mask_from_punit_coremask(cpu, mask, 269 pbf_info->core_cpumask_size, 270 pbf_info->core_cpumask, 271 &count); 272 } 273 274 req = level; 275 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 276 CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO, 0, req, 277 &resp); 278 if (ret) 279 return ret; 280 281 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO resp:%x\n", cpu, 282 resp); 283 284 pbf_info->p1_low = resp & 0xff; 285 pbf_info->p1_high = (resp & GENMASK(15, 8)) >> 8; 286 287 req = level; 288 ret = isst_send_mbox_command( 289 cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TDP_INFO, 0, req, &resp); 290 if (ret) 291 return ret; 292 293 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TDP_INFO resp:%x\n", cpu, resp); 294 295 pbf_info->tdp = resp & 0xffff; 296 297 req = level; 298 ret = isst_send_mbox_command( 299 cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TJ_MAX_INFO, 0, req, &resp); 300 if (ret) 301 return ret; 302 303 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TJ_MAX_INFO resp:%x\n", cpu, 304 resp); 305 pbf_info->t_control = (resp >> 8) & 0xff; 306 pbf_info->t_prochot = resp & 0xff; 307 308 return 0; 309 } 310 311 void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info) 312 { 313 free_cpu_set(pbf_info->core_cpumask); 314 } 315 316 int isst_set_pbf_fact_status(int cpu, int pbf, int enable) 317 { 318 struct isst_pkg_ctdp pkg_dev; 319 struct isst_pkg_ctdp_level_info ctdp_level; 320 int current_level; 321 unsigned int req = 0, resp; 322 int ret; 323 324 ret = isst_get_ctdp_levels(cpu, &pkg_dev); 325 if (ret) 326 return ret; 327 328 current_level = pkg_dev.current_level; 329 330 ret = isst_get_ctdp_control(cpu, current_level, &ctdp_level); 331 if (ret) 332 return ret; 333 334 if (pbf) { 335 if (ctdp_level.fact_enabled) 336 req = BIT(16); 337 338 if (enable) 339 req |= BIT(17); 340 else 341 req &= ~BIT(17); 342 } else { 343 if (ctdp_level.pbf_enabled) 344 req = BIT(17); 345 346 if (enable) 347 req |= BIT(16); 348 else 349 req &= ~BIT(16); 350 } 351 352 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 353 CONFIG_TDP_SET_TDP_CONTROL, 0, req, &resp); 354 if (ret) 355 return ret; 356 357 debug_printf("cpu:%d CONFIG_TDP_SET_TDP_CONTROL pbf/fact:%d req:%x\n", 358 cpu, pbf, req); 359 360 return 0; 361 } 362 363 int isst_get_fact_bucket_info(int cpu, int level, 364 struct isst_fact_bucket_info *bucket_info) 365 { 366 unsigned int resp; 367 int i, k, ret; 368 369 for (i = 0; i < 2; ++i) { 370 int j; 371 372 ret = isst_send_mbox_command( 373 cpu, CONFIG_TDP, 374 CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES, 0, 375 (i << 8) | level, &resp); 376 if (ret) 377 return ret; 378 379 debug_printf( 380 "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES index:%d level:%d resp:%x\n", 381 cpu, i, level, resp); 382 383 for (j = 0; j < 4; ++j) { 384 bucket_info[j + (i * 4)].high_priority_cores_count = 385 (resp >> (j * 8)) & 0xff; 386 } 387 } 388 389 for (k = 0; k < 3; ++k) { 390 for (i = 0; i < 2; ++i) { 391 int j; 392 393 ret = isst_send_mbox_command( 394 cpu, CONFIG_TDP, 395 CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS, 0, 396 (k << 16) | (i << 8) | level, &resp); 397 if (ret) 398 return ret; 399 400 debug_printf( 401 "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS index:%d level:%d avx:%d resp:%x\n", 402 cpu, i, level, k, resp); 403 404 for (j = 0; j < 4; ++j) { 405 switch (k) { 406 case 0: 407 bucket_info[j + (i * 4)].sse_trl = 408 (resp >> (j * 8)) & 0xff; 409 break; 410 case 1: 411 bucket_info[j + (i * 4)].avx_trl = 412 (resp >> (j * 8)) & 0xff; 413 break; 414 case 2: 415 bucket_info[j + (i * 4)].avx512_trl = 416 (resp >> (j * 8)) & 0xff; 417 break; 418 default: 419 break; 420 } 421 } 422 } 423 } 424 425 return 0; 426 } 427 428 int isst_get_fact_info(int cpu, int level, struct isst_fact_info *fact_info) 429 { 430 unsigned int resp; 431 int ret; 432 433 ret = isst_send_mbox_command(cpu, CONFIG_TDP, 434 CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO, 0, 435 level, &resp); 436 if (ret) 437 return ret; 438 439 debug_printf("cpu:%d CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO resp:%x\n", 440 cpu, resp); 441 442 fact_info->lp_clipping_ratio_license_sse = resp & 0xff; 443 fact_info->lp_clipping_ratio_license_avx2 = (resp >> 8) & 0xff; 444 fact_info->lp_clipping_ratio_license_avx512 = (resp >> 16) & 0xff; 445 446 ret = isst_get_fact_bucket_info(cpu, level, fact_info->bucket_info); 447 448 return ret; 449 } 450 451 int isst_set_trl(int cpu, unsigned long long trl) 452 { 453 int ret; 454 455 if (!trl) 456 trl = 0xFFFFFFFFFFFFFFFFULL; 457 458 ret = isst_send_msr_command(cpu, 0x1AD, 1, &trl); 459 if (ret) 460 return ret; 461 462 return 0; 463 } 464 465 int isst_set_trl_from_current_tdp(int cpu, unsigned long long trl) 466 { 467 unsigned long long msr_trl; 468 int ret; 469 470 if (trl) { 471 msr_trl = trl; 472 } else { 473 struct isst_pkg_ctdp pkg_dev; 474 int trl[8]; 475 int i; 476 477 ret = isst_get_ctdp_levels(cpu, &pkg_dev); 478 if (ret) 479 return ret; 480 481 ret = isst_get_get_trl(cpu, pkg_dev.current_level, 0, trl); 482 if (ret) 483 return ret; 484 485 msr_trl = 0; 486 for (i = 0; i < 8; ++i) { 487 unsigned long long _trl = trl[i]; 488 489 msr_trl |= (_trl << (i * 8)); 490 } 491 } 492 ret = isst_send_msr_command(cpu, 0x1AD, 1, &msr_trl); 493 if (ret) 494 return ret; 495 496 return 0; 497 } 498 499 /* Return 1 if locked */ 500 int isst_get_config_tdp_lock_status(int cpu) 501 { 502 unsigned long long tdp_control = 0; 503 int ret; 504 505 ret = isst_send_msr_command(cpu, 0x64b, 0, &tdp_control); 506 if (ret) 507 return ret; 508 509 ret = !!(tdp_control & BIT(31)); 510 511 return ret; 512 } 513 514 void isst_get_process_ctdp_complete(int cpu, struct isst_pkg_ctdp *pkg_dev) 515 { 516 int i; 517 518 if (!pkg_dev->processed) 519 return; 520 521 for (i = 0; i < pkg_dev->levels; ++i) { 522 struct isst_pkg_ctdp_level_info *ctdp_level; 523 524 ctdp_level = &pkg_dev->ctdp_level[i]; 525 if (ctdp_level->pbf_support) 526 free_cpu_set(ctdp_level->pbf_info.core_cpumask); 527 free_cpu_set(ctdp_level->core_cpumask); 528 } 529 } 530 531 int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) 532 { 533 int i, ret; 534 535 if (pkg_dev->processed) 536 return 0; 537 538 ret = isst_get_ctdp_levels(cpu, pkg_dev); 539 if (ret) 540 return ret; 541 542 debug_printf("cpu: %d ctdp enable:%d current level: %d levels:%d\n", 543 cpu, pkg_dev->enabled, pkg_dev->current_level, 544 pkg_dev->levels); 545 546 for (i = 0; i <= pkg_dev->levels; ++i) { 547 struct isst_pkg_ctdp_level_info *ctdp_level; 548 549 if (tdp_level != 0xff && i != tdp_level) 550 continue; 551 552 debug_printf("cpu:%d Get Information for TDP level:%d\n", cpu, 553 i); 554 ctdp_level = &pkg_dev->ctdp_level[i]; 555 556 ctdp_level->processed = 1; 557 ctdp_level->level = i; 558 ctdp_level->control_cpu = cpu; 559 ctdp_level->pkg_id = get_physical_package_id(cpu); 560 ctdp_level->die_id = get_physical_die_id(cpu); 561 562 ret = isst_get_ctdp_control(cpu, i, ctdp_level); 563 if (ret) 564 return ret; 565 566 ret = isst_get_tdp_info(cpu, i, ctdp_level); 567 if (ret) 568 return ret; 569 570 ret = isst_get_pwr_info(cpu, i, ctdp_level); 571 if (ret) 572 return ret; 573 574 ret = isst_get_tjmax_info(cpu, i, ctdp_level); 575 if (ret) 576 return ret; 577 578 ctdp_level->core_cpumask_size = 579 alloc_cpu_set(&ctdp_level->core_cpumask); 580 ret = isst_get_coremask_info(cpu, i, ctdp_level); 581 if (ret) 582 return ret; 583 584 ret = isst_get_trl_bucket_info(cpu, &ctdp_level->buckets_info); 585 if (ret) 586 return ret; 587 588 ret = isst_get_get_trl(cpu, i, 0, 589 ctdp_level->trl_sse_active_cores); 590 if (ret) 591 return ret; 592 593 ret = isst_get_get_trl(cpu, i, 1, 594 ctdp_level->trl_avx_active_cores); 595 if (ret) 596 return ret; 597 598 ret = isst_get_get_trl(cpu, i, 2, 599 ctdp_level->trl_avx_512_active_cores); 600 if (ret) 601 return ret; 602 603 if (ctdp_level->pbf_support) { 604 ret = isst_get_pbf_info(cpu, i, &ctdp_level->pbf_info); 605 if (!ret) 606 ctdp_level->pbf_found = 1; 607 } 608 609 if (ctdp_level->fact_support) { 610 ret = isst_get_fact_info(cpu, i, 611 &ctdp_level->fact_info); 612 if (ret) 613 return ret; 614 } 615 } 616 617 pkg_dev->processed = 1; 618 619 return 0; 620 } 621 622 int isst_clos_get_clos_information(int cpu, int *enable, int *type) 623 { 624 unsigned int resp; 625 int ret; 626 627 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, 628 &resp); 629 if (ret) 630 return ret; 631 632 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp); 633 634 if (resp & BIT(1)) 635 *enable = 1; 636 else 637 *enable = 0; 638 639 if (resp & BIT(2)) 640 *type = 1; 641 else 642 *type = 0; 643 644 return 0; 645 } 646 647 int isst_pm_qos_config(int cpu, int enable_clos, int priority_type) 648 { 649 unsigned int req, resp; 650 int ret; 651 652 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, 653 &resp); 654 if (ret) 655 return ret; 656 657 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp); 658 659 req = resp; 660 661 if (enable_clos) 662 req = req | BIT(1); 663 else 664 req = req & ~BIT(1); 665 666 if (priority_type) 667 req = req | BIT(2); 668 else 669 req = req & ~BIT(2); 670 671 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 672 BIT(MBOX_CMD_WRITE_BIT), req, &resp); 673 if (ret) 674 return ret; 675 676 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG priority type:%d req:%x\n", cpu, 677 priority_type, req); 678 679 return 0; 680 } 681 682 int isst_pm_get_clos(int cpu, int clos, struct isst_clos_config *clos_config) 683 { 684 unsigned int resp; 685 int ret; 686 687 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0, 688 &resp); 689 if (ret) 690 return ret; 691 692 clos_config->pkg_id = get_physical_package_id(cpu); 693 clos_config->die_id = get_physical_die_id(cpu); 694 695 clos_config->epp = resp & 0x0f; 696 clos_config->clos_prop_prio = (resp >> 4) & 0x0f; 697 clos_config->clos_min = (resp >> 8) & 0xff; 698 clos_config->clos_max = (resp >> 16) & 0xff; 699 clos_config->clos_desired = (resp >> 24) & 0xff; 700 701 return 0; 702 } 703 704 int isst_set_clos(int cpu, int clos, struct isst_clos_config *clos_config) 705 { 706 unsigned int req, resp; 707 unsigned int param; 708 int ret; 709 710 req = clos_config->epp & 0x0f; 711 req |= (clos_config->clos_prop_prio & 0x0f) << 4; 712 req |= (clos_config->clos_min & 0xff) << 8; 713 req |= (clos_config->clos_max & 0xff) << 16; 714 req |= (clos_config->clos_desired & 0xff) << 24; 715 716 param = BIT(MBOX_CMD_WRITE_BIT) | clos; 717 718 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req, 719 &resp); 720 if (ret) 721 return ret; 722 723 debug_printf("cpu:%d CLOS_PM_CLOS param:%x req:%x\n", cpu, param, req); 724 725 return 0; 726 } 727 728 int isst_clos_get_assoc_status(int cpu, int *clos_id) 729 { 730 unsigned int resp; 731 unsigned int param; 732 int core_id, ret; 733 734 core_id = find_phy_core_num(cpu); 735 param = core_id; 736 737 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0, 738 &resp); 739 if (ret) 740 return ret; 741 742 debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x resp:%x\n", cpu, param, 743 resp); 744 *clos_id = (resp >> 16) & 0x03; 745 746 return 0; 747 } 748 749 int isst_clos_associate(int cpu, int clos_id) 750 { 751 unsigned int req, resp; 752 unsigned int param; 753 int core_id, ret; 754 755 req = (clos_id & 0x03) << 16; 756 core_id = find_phy_core_num(cpu); 757 param = BIT(MBOX_CMD_WRITE_BIT) | core_id; 758 759 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 760 req, &resp); 761 if (ret) 762 return ret; 763 764 debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x req:%x\n", cpu, param, 765 req); 766 767 return 0; 768 } 769