linux/tools/power/x86/intel-speed-select/isst-core.c
<<
>>
Prefs
   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
   9int 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
  30int 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
  55int 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
  76int 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
  98int 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
 118int 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
 152int 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
 191int isst_set_tdp_level_msr(int cpu, int tdp_level)
 192{
 193        int ret;
 194
 195        debug_printf("cpu: tdp_level via MSR %d\n", cpu, tdp_level);
 196
 197        if (isst_get_config_tdp_lock_status(cpu)) {
 198                debug_printf("cpu: tdp_locked %d\n", cpu);
 199                return -1;
 200        }
 201
 202        if (tdp_level > 2)
 203                return -1; /* invalid value */
 204
 205        ret = isst_send_msr_command(cpu, 0x64b, 1,
 206                                    (unsigned long long *)&tdp_level);
 207        if (ret)
 208                return ret;
 209
 210        debug_printf("cpu: tdp_level via MSR successful %d\n", cpu, tdp_level);
 211
 212        return 0;
 213}
 214
 215int isst_set_tdp_level(int cpu, int tdp_level)
 216{
 217        unsigned int resp;
 218        int ret;
 219
 220        ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_SET_LEVEL, 0,
 221                                     tdp_level, &resp);
 222        if (ret)
 223                return isst_set_tdp_level_msr(cpu, tdp_level);
 224
 225        return 0;
 226}
 227
 228int isst_get_pbf_info(int cpu, int level, struct isst_pbf_info *pbf_info)
 229{
 230        unsigned int req, resp;
 231        int i, ret;
 232
 233        pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask);
 234
 235        for (i = 0; i < 2; ++i) {
 236                unsigned long long mask;
 237                int count;
 238
 239                ret = isst_send_mbox_command(cpu, CONFIG_TDP,
 240                                             CONFIG_TDP_PBF_GET_CORE_MASK_INFO,
 241                                             0, (i << 8) | level, &resp);
 242                if (ret)
 243                        return ret;
 244
 245                debug_printf(
 246                        "cpu:%d CONFIG_TDP_PBF_GET_CORE_MASK_INFO resp:%x\n",
 247                        cpu, resp);
 248
 249                mask = (unsigned long long)resp << (32 * i);
 250                set_cpu_mask_from_punit_coremask(cpu, mask,
 251                                                 pbf_info->core_cpumask_size,
 252                                                 pbf_info->core_cpumask,
 253                                                 &count);
 254        }
 255
 256        req = level;
 257        ret = isst_send_mbox_command(cpu, CONFIG_TDP,
 258                                     CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO, 0, req,
 259                                     &resp);
 260        if (ret)
 261                return ret;
 262
 263        debug_printf("cpu:%d CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO resp:%x\n", cpu,
 264                     resp);
 265
 266        pbf_info->p1_low = resp & 0xff;
 267        pbf_info->p1_high = (resp & GENMASK(15, 8)) >> 8;
 268
 269        req = level;
 270        ret = isst_send_mbox_command(
 271                cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TDP_INFO, 0, req, &resp);
 272        if (ret)
 273                return ret;
 274
 275        debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TDP_INFO resp:%x\n", cpu, resp);
 276
 277        pbf_info->tdp = resp & 0xffff;
 278
 279        req = level;
 280        ret = isst_send_mbox_command(
 281                cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TJ_MAX_INFO, 0, req, &resp);
 282        if (ret)
 283                return ret;
 284
 285        debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TJ_MAX_INFO resp:%x\n", cpu,
 286                     resp);
 287        pbf_info->t_control = (resp >> 8) & 0xff;
 288        pbf_info->t_prochot = resp & 0xff;
 289
 290        return 0;
 291}
 292
 293void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info)
 294{
 295        free_cpu_set(pbf_info->core_cpumask);
 296}
 297
 298int isst_set_pbf_fact_status(int cpu, int pbf, int enable)
 299{
 300        struct isst_pkg_ctdp pkg_dev;
 301        struct isst_pkg_ctdp_level_info ctdp_level;
 302        int current_level;
 303        unsigned int req = 0, resp;
 304        int ret;
 305
 306        ret = isst_get_ctdp_levels(cpu, &pkg_dev);
 307        if (ret)
 308                return ret;
 309
 310        current_level = pkg_dev.current_level;
 311
 312        ret = isst_get_ctdp_control(cpu, current_level, &ctdp_level);
 313        if (ret)
 314                return ret;
 315
 316        if (pbf) {
 317                if (ctdp_level.fact_enabled)
 318                        req = BIT(16);
 319
 320                if (enable)
 321                        req |= BIT(17);
 322                else
 323                        req &= ~BIT(17);
 324        } else {
 325                if (ctdp_level.pbf_enabled)
 326                        req = BIT(17);
 327
 328                if (enable)
 329                        req |= BIT(16);
 330                else
 331                        req &= ~BIT(16);
 332        }
 333
 334        ret = isst_send_mbox_command(cpu, CONFIG_TDP,
 335                                     CONFIG_TDP_SET_TDP_CONTROL, 0, req, &resp);
 336        if (ret)
 337                return ret;
 338
 339        debug_printf("cpu:%d CONFIG_TDP_SET_TDP_CONTROL pbf/fact:%d req:%x\n",
 340                     cpu, pbf, req);
 341
 342        return 0;
 343}
 344
 345int isst_get_fact_bucket_info(int cpu, int level,
 346                              struct isst_fact_bucket_info *bucket_info)
 347{
 348        unsigned int resp;
 349        int i, k, ret;
 350
 351        for (i = 0; i < 2; ++i) {
 352                int j;
 353
 354                ret = isst_send_mbox_command(
 355                        cpu, CONFIG_TDP,
 356                        CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES, 0,
 357                        (i << 8) | level, &resp);
 358                if (ret)
 359                        return ret;
 360
 361                debug_printf(
 362                        "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES index:%d level:%d resp:%x\n",
 363                        cpu, i, level, resp);
 364
 365                for (j = 0; j < 4; ++j) {
 366                        bucket_info[j + (i * 4)].high_priority_cores_count =
 367                                (resp >> (j * 8)) & 0xff;
 368                }
 369        }
 370
 371        for (k = 0; k < 3; ++k) {
 372                for (i = 0; i < 2; ++i) {
 373                        int j;
 374
 375                        ret = isst_send_mbox_command(
 376                                cpu, CONFIG_TDP,
 377                                CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS, 0,
 378                                (k << 16) | (i << 8) | level, &resp);
 379                        if (ret)
 380                                return ret;
 381
 382                        debug_printf(
 383                                "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS index:%d level:%d avx:%d resp:%x\n",
 384                                cpu, i, level, k, resp);
 385
 386                        for (j = 0; j < 4; ++j) {
 387                                switch (k) {
 388                                case 0:
 389                                        bucket_info[j + (i * 4)].sse_trl =
 390                                                (resp >> (j * 8)) & 0xff;
 391                                        break;
 392                                case 1:
 393                                        bucket_info[j + (i * 4)].avx_trl =
 394                                                (resp >> (j * 8)) & 0xff;
 395                                        break;
 396                                case 2:
 397                                        bucket_info[j + (i * 4)].avx512_trl =
 398                                                (resp >> (j * 8)) & 0xff;
 399                                        break;
 400                                default:
 401                                        break;
 402                                }
 403                        }
 404                }
 405        }
 406
 407        return 0;
 408}
 409
 410int isst_get_fact_info(int cpu, int level, struct isst_fact_info *fact_info)
 411{
 412        unsigned int resp;
 413        int ret;
 414
 415        ret = isst_send_mbox_command(cpu, CONFIG_TDP,
 416                                     CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO, 0,
 417                                     level, &resp);
 418        if (ret)
 419                return ret;
 420
 421        debug_printf("cpu:%d CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO resp:%x\n",
 422                     cpu, resp);
 423
 424        fact_info->lp_clipping_ratio_license_sse = resp & 0xff;
 425        fact_info->lp_clipping_ratio_license_avx2 = (resp >> 8) & 0xff;
 426        fact_info->lp_clipping_ratio_license_avx512 = (resp >> 16) & 0xff;
 427
 428        ret = isst_get_fact_bucket_info(cpu, level, fact_info->bucket_info);
 429
 430        return ret;
 431}
 432
 433int isst_set_trl(int cpu, unsigned long long trl)
 434{
 435        int ret;
 436
 437        if (!trl)
 438                trl = 0xFFFFFFFFFFFFFFFFULL;
 439
 440        ret = isst_send_msr_command(cpu, 0x1AD, 1, &trl);
 441        if (ret)
 442                return ret;
 443
 444        return 0;
 445}
 446
 447int isst_set_trl_from_current_tdp(int cpu, unsigned long long trl)
 448{
 449        unsigned long long msr_trl;
 450        int ret;
 451
 452        if (trl) {
 453                msr_trl = trl;
 454        } else {
 455                struct isst_pkg_ctdp pkg_dev;
 456                int trl[8];
 457                int i;
 458
 459                ret = isst_get_ctdp_levels(cpu, &pkg_dev);
 460                if (ret)
 461                        return ret;
 462
 463                ret = isst_get_get_trl(cpu, pkg_dev.current_level, 0, trl);
 464                if (ret)
 465                        return ret;
 466
 467                msr_trl = 0;
 468                for (i = 0; i < 8; ++i) {
 469                        unsigned long long _trl = trl[i];
 470
 471                        msr_trl |= (_trl << (i * 8));
 472                }
 473        }
 474        ret = isst_send_msr_command(cpu, 0x1AD, 1, &msr_trl);
 475        if (ret)
 476                return ret;
 477
 478        return 0;
 479}
 480
 481/* Return 1 if locked */
 482int isst_get_config_tdp_lock_status(int cpu)
 483{
 484        unsigned long long tdp_control = 0;
 485        int ret;
 486
 487        ret = isst_send_msr_command(cpu, 0x64b, 0, &tdp_control);
 488        if (ret)
 489                return ret;
 490
 491        ret = !!(tdp_control & BIT(31));
 492
 493        return ret;
 494}
 495
 496void isst_get_process_ctdp_complete(int cpu, struct isst_pkg_ctdp *pkg_dev)
 497{
 498        int i;
 499
 500        if (!pkg_dev->processed)
 501                return;
 502
 503        for (i = 0; i < pkg_dev->levels; ++i) {
 504                struct isst_pkg_ctdp_level_info *ctdp_level;
 505
 506                ctdp_level = &pkg_dev->ctdp_level[i];
 507                if (ctdp_level->pbf_support)
 508                        free_cpu_set(ctdp_level->pbf_info.core_cpumask);
 509                free_cpu_set(ctdp_level->core_cpumask);
 510        }
 511}
 512
 513int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
 514{
 515        int i, ret;
 516
 517        if (pkg_dev->processed)
 518                return 0;
 519
 520        ret = isst_get_ctdp_levels(cpu, pkg_dev);
 521        if (ret)
 522                return ret;
 523
 524        debug_printf("cpu: %d ctdp enable:%d current level: %d levels:%d\n",
 525                     cpu, pkg_dev->enabled, pkg_dev->current_level,
 526                     pkg_dev->levels);
 527
 528        for (i = 0; i <= pkg_dev->levels; ++i) {
 529                struct isst_pkg_ctdp_level_info *ctdp_level;
 530
 531                if (tdp_level != 0xff && i != tdp_level)
 532                        continue;
 533
 534                debug_printf("cpu:%d Get Information for TDP level:%d\n", cpu,
 535                             i);
 536                ctdp_level = &pkg_dev->ctdp_level[i];
 537
 538                ctdp_level->processed = 1;
 539                ctdp_level->level = i;
 540                ctdp_level->control_cpu = cpu;
 541                ctdp_level->pkg_id = get_physical_package_id(cpu);
 542                ctdp_level->die_id = get_physical_die_id(cpu);
 543
 544                ret = isst_get_ctdp_control(cpu, i, ctdp_level);
 545                if (ret)
 546                        return ret;
 547
 548                ret = isst_get_tdp_info(cpu, i, ctdp_level);
 549                if (ret)
 550                        return ret;
 551
 552                ret = isst_get_pwr_info(cpu, i, ctdp_level);
 553                if (ret)
 554                        return ret;
 555
 556                ret = isst_get_tjmax_info(cpu, i, ctdp_level);
 557                if (ret)
 558                        return ret;
 559
 560                ctdp_level->core_cpumask_size =
 561                        alloc_cpu_set(&ctdp_level->core_cpumask);
 562                ret = isst_get_coremask_info(cpu, i, ctdp_level);
 563                if (ret)
 564                        return ret;
 565
 566                ret = isst_get_get_trl(cpu, i, 0,
 567                                       ctdp_level->trl_sse_active_cores);
 568                if (ret)
 569                        return ret;
 570
 571                ret = isst_get_get_trl(cpu, i, 1,
 572                                       ctdp_level->trl_avx_active_cores);
 573                if (ret)
 574                        return ret;
 575
 576                ret = isst_get_get_trl(cpu, i, 2,
 577                                       ctdp_level->trl_avx_512_active_cores);
 578                if (ret)
 579                        return ret;
 580
 581                if (ctdp_level->pbf_support) {
 582                        ret = isst_get_pbf_info(cpu, i, &ctdp_level->pbf_info);
 583                        if (!ret)
 584                                ctdp_level->pbf_found = 1;
 585                }
 586
 587                if (ctdp_level->fact_support) {
 588                        ret = isst_get_fact_info(cpu, i,
 589                                                 &ctdp_level->fact_info);
 590                        if (ret)
 591                                return ret;
 592                }
 593        }
 594
 595        pkg_dev->processed = 1;
 596
 597        return 0;
 598}
 599
 600int isst_pm_qos_config(int cpu, int enable_clos, int priority_type)
 601{
 602        unsigned int req, resp;
 603        int ret;
 604
 605        ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0,
 606                                     &resp);
 607        if (ret)
 608                return ret;
 609
 610        debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp);
 611
 612        req = resp;
 613
 614        if (enable_clos)
 615                req = req | BIT(1);
 616        else
 617                req = req & ~BIT(1);
 618
 619        if (priority_type)
 620                req = req | BIT(2);
 621        else
 622                req = req & ~BIT(2);
 623
 624        ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG,
 625                                     BIT(MBOX_CMD_WRITE_BIT), req, &resp);
 626        if (ret)
 627                return ret;
 628
 629        debug_printf("cpu:%d CLOS_PM_QOS_CONFIG priority type:%d req:%x\n", cpu,
 630                     priority_type, req);
 631
 632        return 0;
 633}
 634
 635int isst_pm_get_clos(int cpu, int clos, struct isst_clos_config *clos_config)
 636{
 637        unsigned int resp;
 638        int ret;
 639
 640        ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0,
 641                                     &resp);
 642        if (ret)
 643                return ret;
 644
 645        clos_config->pkg_id = get_physical_package_id(cpu);
 646        clos_config->die_id = get_physical_die_id(cpu);
 647
 648        clos_config->epp = resp & 0x0f;
 649        clos_config->clos_prop_prio = (resp >> 4) & 0x0f;
 650        clos_config->clos_min = (resp >> 8) & 0xff;
 651        clos_config->clos_max = (resp >> 16) & 0xff;
 652        clos_config->clos_desired = (resp >> 24) & 0xff;
 653
 654        return 0;
 655}
 656
 657int isst_set_clos(int cpu, int clos, struct isst_clos_config *clos_config)
 658{
 659        unsigned int req, resp;
 660        unsigned int param;
 661        int ret;
 662
 663        req = clos_config->epp & 0x0f;
 664        req |= (clos_config->clos_prop_prio & 0x0f) << 4;
 665        req |= (clos_config->clos_min & 0xff) << 8;
 666        req |= (clos_config->clos_max & 0xff) << 16;
 667        req |= (clos_config->clos_desired & 0xff) << 24;
 668
 669        param = BIT(MBOX_CMD_WRITE_BIT) | clos;
 670
 671        ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req,
 672                                     &resp);
 673        if (ret)
 674                return ret;
 675
 676        debug_printf("cpu:%d CLOS_PM_CLOS param:%x req:%x\n", cpu, param, req);
 677
 678        return 0;
 679}
 680
 681int isst_clos_get_assoc_status(int cpu, int *clos_id)
 682{
 683        unsigned int resp;
 684        unsigned int param;
 685        int core_id, ret;
 686
 687        core_id = find_phy_core_num(cpu);
 688        param = core_id;
 689
 690        ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0,
 691                                     &resp);
 692        if (ret)
 693                return ret;
 694
 695        debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x resp:%x\n", cpu, param,
 696                     resp);
 697        *clos_id = (resp >> 16) & 0x03;
 698
 699        return 0;
 700}
 701
 702int isst_clos_associate(int cpu, int clos_id)
 703{
 704        unsigned int req, resp;
 705        unsigned int param;
 706        int core_id, ret;
 707
 708        req = (clos_id & 0x03) << 16;
 709        core_id = find_phy_core_num(cpu);
 710        param = BIT(MBOX_CMD_WRITE_BIT) | core_id;
 711
 712        ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param,
 713                                     req, &resp);
 714        if (ret)
 715                return ret;
 716
 717        debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x req:%x\n", cpu, param,
 718                     req);
 719
 720        return 0;
 721}
 722