0001
0002
0003
0004
0005
0006
0007 #include "isst.h"
0008
0009 int isst_write_pm_config(int cpu, int cp_state)
0010 {
0011 unsigned int req, resp;
0012 int ret;
0013
0014 if (cp_state)
0015 req = BIT(16);
0016 else
0017 req = 0;
0018
0019 ret = isst_send_mbox_command(cpu, WRITE_PM_CONFIG, PM_FEATURE, 0, req,
0020 &resp);
0021 if (ret)
0022 return ret;
0023
0024 debug_printf("cpu:%d WRITE_PM_CONFIG resp:%x\n", cpu, resp);
0025
0026 return 0;
0027 }
0028
0029 int isst_read_pm_config(int cpu, int *cp_state, int *cp_cap)
0030 {
0031 unsigned int resp;
0032 int ret;
0033
0034 ret = isst_send_mbox_command(cpu, READ_PM_CONFIG, PM_FEATURE, 0, 0,
0035 &resp);
0036 if (ret)
0037 return ret;
0038
0039 debug_printf("cpu:%d READ_PM_CONFIG resp:%x\n", cpu, resp);
0040
0041 *cp_state = resp & BIT(16);
0042 *cp_cap = resp & BIT(0) ? 1 : 0;
0043
0044 return 0;
0045 }
0046
0047 int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev)
0048 {
0049 unsigned int resp;
0050 int ret;
0051
0052 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
0053 CONFIG_TDP_GET_LEVELS_INFO, 0, 0, &resp);
0054 if (ret) {
0055 pkg_dev->levels = 0;
0056 pkg_dev->locked = 1;
0057 pkg_dev->current_level = 0;
0058 pkg_dev->version = 0;
0059 pkg_dev->enabled = 0;
0060 return 0;
0061 }
0062
0063 debug_printf("cpu:%d CONFIG_TDP_GET_LEVELS_INFO resp:%x\n", cpu, resp);
0064
0065 pkg_dev->version = resp & 0xff;
0066 pkg_dev->levels = (resp >> 8) & 0xff;
0067 pkg_dev->current_level = (resp >> 16) & 0xff;
0068 pkg_dev->locked = !!(resp & BIT(24));
0069 pkg_dev->enabled = !!(resp & BIT(31));
0070
0071 return 0;
0072 }
0073
0074 int isst_get_ctdp_control(int cpu, int config_index,
0075 struct isst_pkg_ctdp_level_info *ctdp_level)
0076 {
0077 int cp_state, cp_cap;
0078 unsigned int resp;
0079 int ret;
0080
0081 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
0082 CONFIG_TDP_GET_TDP_CONTROL, 0,
0083 config_index, &resp);
0084 if (ret)
0085 return ret;
0086
0087 ctdp_level->fact_support = resp & BIT(0);
0088 ctdp_level->pbf_support = !!(resp & BIT(1));
0089 ctdp_level->fact_enabled = !!(resp & BIT(16));
0090 ctdp_level->pbf_enabled = !!(resp & BIT(17));
0091
0092 ret = isst_read_pm_config(cpu, &cp_state, &cp_cap);
0093 if (ret) {
0094 debug_printf("cpu:%d pm_config is not supported \n", cpu);
0095 } else {
0096 debug_printf("cpu:%d pm_config SST-CP state:%d cap:%d \n", cpu, cp_state, cp_cap);
0097 ctdp_level->sst_cp_support = cp_cap;
0098 ctdp_level->sst_cp_enabled = cp_state;
0099 }
0100
0101 debug_printf(
0102 "cpu:%d CONFIG_TDP_GET_TDP_CONTROL resp:%x fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n",
0103 cpu, resp, ctdp_level->fact_support, ctdp_level->pbf_support,
0104 ctdp_level->fact_enabled, ctdp_level->pbf_enabled);
0105
0106 return 0;
0107 }
0108
0109 int isst_get_tdp_info(int cpu, int config_index,
0110 struct isst_pkg_ctdp_level_info *ctdp_level)
0111 {
0112 unsigned int resp;
0113 int ret;
0114
0115 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO,
0116 0, config_index, &resp);
0117 if (ret) {
0118 isst_display_error_info_message(1, "Invalid level, Can't get TDP information at level", 1, config_index);
0119 return ret;
0120 }
0121
0122 ctdp_level->pkg_tdp = resp & GENMASK(14, 0);
0123 ctdp_level->tdp_ratio = (resp & GENMASK(23, 16)) >> 16;
0124
0125 debug_printf(
0126 "cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO resp:%x tdp_ratio:%d pkg_tdp:%d\n",
0127 cpu, config_index, resp, ctdp_level->tdp_ratio,
0128 ctdp_level->pkg_tdp);
0129 return 0;
0130 }
0131
0132 int isst_get_pwr_info(int cpu, int config_index,
0133 struct isst_pkg_ctdp_level_info *ctdp_level)
0134 {
0135 unsigned int resp;
0136 int ret;
0137
0138 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_PWR_INFO,
0139 0, config_index, &resp);
0140 if (ret)
0141 return ret;
0142
0143 ctdp_level->pkg_max_power = resp & GENMASK(14, 0);
0144 ctdp_level->pkg_min_power = (resp & GENMASK(30, 16)) >> 16;
0145
0146 debug_printf(
0147 "cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO resp:%x pkg_max_power:%d pkg_min_power:%d\n",
0148 cpu, config_index, resp, ctdp_level->pkg_max_power,
0149 ctdp_level->pkg_min_power);
0150
0151 return 0;
0152 }
0153
0154 void isst_get_uncore_p0_p1_info(int cpu, int config_index,
0155 struct isst_pkg_ctdp_level_info *ctdp_level)
0156 {
0157 unsigned int resp;
0158 int ret;
0159 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
0160 CONFIG_TDP_GET_UNCORE_P0_P1_INFO, 0,
0161 config_index, &resp);
0162 if (ret) {
0163 ctdp_level->uncore_p0 = 0;
0164 ctdp_level->uncore_p1 = 0;
0165 return;
0166 }
0167
0168 ctdp_level->uncore_p0 = resp & GENMASK(7, 0);
0169 ctdp_level->uncore_p1 = (resp & GENMASK(15, 8)) >> 8;
0170 debug_printf(
0171 "cpu:%d ctdp:%d CONFIG_TDP_GET_UNCORE_P0_P1_INFO resp:%x uncore p0:%d uncore p1:%d\n",
0172 cpu, config_index, resp, ctdp_level->uncore_p0,
0173 ctdp_level->uncore_p1);
0174 }
0175
0176 void isst_get_p1_info(int cpu, int config_index,
0177 struct isst_pkg_ctdp_level_info *ctdp_level)
0178 {
0179 unsigned int resp;
0180 int ret;
0181 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_P1_INFO, 0,
0182 config_index, &resp);
0183 if (ret) {
0184 ctdp_level->sse_p1 = 0;
0185 ctdp_level->avx2_p1 = 0;
0186 ctdp_level->avx512_p1 = 0;
0187 return;
0188 }
0189
0190 ctdp_level->sse_p1 = resp & GENMASK(7, 0);
0191 ctdp_level->avx2_p1 = (resp & GENMASK(15, 8)) >> 8;
0192 ctdp_level->avx512_p1 = (resp & GENMASK(23, 16)) >> 16;
0193 debug_printf(
0194 "cpu:%d ctdp:%d CONFIG_TDP_GET_P1_INFO resp:%x sse_p1:%d avx2_p1:%d avx512_p1:%d\n",
0195 cpu, config_index, resp, ctdp_level->sse_p1,
0196 ctdp_level->avx2_p1, ctdp_level->avx512_p1);
0197 }
0198
0199 void isst_get_uncore_mem_freq(int cpu, int config_index,
0200 struct isst_pkg_ctdp_level_info *ctdp_level)
0201 {
0202 unsigned int resp;
0203 int ret;
0204
0205 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_MEM_FREQ,
0206 0, config_index, &resp);
0207 if (ret) {
0208 ctdp_level->mem_freq = 0;
0209 return;
0210 }
0211
0212 ctdp_level->mem_freq = resp & GENMASK(7, 0);
0213 if (is_spr_platform()) {
0214 ctdp_level->mem_freq *= 200;
0215 } else if (is_icx_platform()) {
0216 if (ctdp_level->mem_freq < 7) {
0217 ctdp_level->mem_freq = (12 - ctdp_level->mem_freq) * 133.33 * 2 * 10;
0218 ctdp_level->mem_freq /= 10;
0219 if (ctdp_level->mem_freq % 10 > 5)
0220 ctdp_level->mem_freq++;
0221 } else {
0222 ctdp_level->mem_freq = 0;
0223 }
0224 } else {
0225 ctdp_level->mem_freq = 0;
0226 }
0227 debug_printf(
0228 "cpu:%d ctdp:%d CONFIG_TDP_GET_MEM_FREQ resp:%x uncore mem_freq:%d\n",
0229 cpu, config_index, resp, ctdp_level->mem_freq);
0230 }
0231
0232 int isst_get_tjmax_info(int cpu, int config_index,
0233 struct isst_pkg_ctdp_level_info *ctdp_level)
0234 {
0235 unsigned int resp;
0236 int ret;
0237
0238 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_TJMAX_INFO,
0239 0, config_index, &resp);
0240 if (ret)
0241 return ret;
0242
0243 ctdp_level->t_proc_hot = resp & GENMASK(7, 0);
0244
0245 debug_printf(
0246 "cpu:%d ctdp:%d CONFIG_TDP_GET_TJMAX_INFO resp:%x t_proc_hot:%d\n",
0247 cpu, config_index, resp, ctdp_level->t_proc_hot);
0248
0249 return 0;
0250 }
0251
0252 int isst_get_coremask_info(int cpu, int config_index,
0253 struct isst_pkg_ctdp_level_info *ctdp_level)
0254 {
0255 unsigned int resp;
0256 int i, ret;
0257
0258 ctdp_level->cpu_count = 0;
0259 for (i = 0; i < 2; ++i) {
0260 unsigned long long mask;
0261 int cpu_count = 0;
0262
0263 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
0264 CONFIG_TDP_GET_CORE_MASK, 0,
0265 (i << 8) | config_index, &resp);
0266 if (ret)
0267 return ret;
0268
0269 debug_printf(
0270 "cpu:%d ctdp:%d mask:%d CONFIG_TDP_GET_CORE_MASK resp:%x\n",
0271 cpu, config_index, i, resp);
0272
0273 mask = (unsigned long long)resp << (32 * i);
0274 set_cpu_mask_from_punit_coremask(cpu, mask,
0275 ctdp_level->core_cpumask_size,
0276 ctdp_level->core_cpumask,
0277 &cpu_count);
0278 ctdp_level->cpu_count += cpu_count;
0279 debug_printf("cpu:%d ctdp:%d mask:%d cpu count:%d\n", cpu,
0280 config_index, i, ctdp_level->cpu_count);
0281 }
0282
0283 return 0;
0284 }
0285
0286 int isst_get_get_trl_from_msr(int cpu, int *trl)
0287 {
0288 unsigned long long msr_trl;
0289 int ret;
0290
0291 ret = isst_send_msr_command(cpu, 0x1AD, 0, &msr_trl);
0292 if (ret)
0293 return ret;
0294
0295 trl[0] = msr_trl & GENMASK(7, 0);
0296 trl[1] = (msr_trl & GENMASK(15, 8)) >> 8;
0297 trl[2] = (msr_trl & GENMASK(23, 16)) >> 16;
0298 trl[3] = (msr_trl & GENMASK(31, 24)) >> 24;
0299 trl[4] = (msr_trl & GENMASK(39, 32)) >> 32;
0300 trl[5] = (msr_trl & GENMASK(47, 40)) >> 40;
0301 trl[6] = (msr_trl & GENMASK(55, 48)) >> 48;
0302 trl[7] = (msr_trl & GENMASK(63, 56)) >> 56;
0303
0304 return 0;
0305 }
0306
0307 int isst_get_get_trl(int cpu, int level, int avx_level, int *trl)
0308 {
0309 unsigned int req, resp;
0310 int ret;
0311
0312 req = level | (avx_level << 16);
0313 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
0314 CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req,
0315 &resp);
0316 if (ret)
0317 return ret;
0318
0319 debug_printf(
0320 "cpu:%d CONFIG_TDP_GET_TURBO_LIMIT_RATIOS req:%x resp:%x\n",
0321 cpu, req, resp);
0322
0323 trl[0] = resp & GENMASK(7, 0);
0324 trl[1] = (resp & GENMASK(15, 8)) >> 8;
0325 trl[2] = (resp & GENMASK(23, 16)) >> 16;
0326 trl[3] = (resp & GENMASK(31, 24)) >> 24;
0327
0328 req = level | BIT(8) | (avx_level << 16);
0329 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
0330 CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req,
0331 &resp);
0332 if (ret)
0333 return ret;
0334
0335 debug_printf("cpu:%d CONFIG_TDP_GET_TURBO_LIMIT req:%x resp:%x\n", cpu,
0336 req, resp);
0337
0338 trl[4] = resp & GENMASK(7, 0);
0339 trl[5] = (resp & GENMASK(15, 8)) >> 8;
0340 trl[6] = (resp & GENMASK(23, 16)) >> 16;
0341 trl[7] = (resp & GENMASK(31, 24)) >> 24;
0342
0343 return 0;
0344 }
0345
0346 int isst_get_trl_bucket_info(int cpu, unsigned long long *buckets_info)
0347 {
0348 int ret;
0349
0350 debug_printf("cpu:%d bucket info via MSR\n", cpu);
0351
0352 *buckets_info = 0;
0353
0354 ret = isst_send_msr_command(cpu, 0x1ae, 0, buckets_info);
0355 if (ret)
0356 return ret;
0357
0358 debug_printf("cpu:%d bucket info via MSR successful 0x%llx\n", cpu,
0359 *buckets_info);
0360
0361 return 0;
0362 }
0363
0364 int isst_set_tdp_level_msr(int cpu, int tdp_level)
0365 {
0366 unsigned long long level = tdp_level;
0367 int ret;
0368
0369 debug_printf("cpu: tdp_level via MSR %d\n", cpu, tdp_level);
0370
0371 if (isst_get_config_tdp_lock_status(cpu)) {
0372 isst_display_error_info_message(1, "tdp_locked", 0, 0);
0373 return -1;
0374 }
0375
0376 if (tdp_level > 2)
0377 return -1;
0378
0379 ret = isst_send_msr_command(cpu, 0x64b, 1, &level);
0380 if (ret)
0381 return ret;
0382
0383 debug_printf("cpu: tdp_level via MSR successful %d\n", cpu, tdp_level);
0384
0385 return 0;
0386 }
0387
0388 int isst_set_tdp_level(int cpu, int tdp_level)
0389 {
0390 unsigned int resp;
0391 int ret;
0392
0393
0394 if (isst_get_config_tdp_lock_status(cpu)) {
0395 isst_display_error_info_message(1, "TDP is locked", 0, 0);
0396 return -1;
0397
0398 }
0399
0400 ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_SET_LEVEL, 0,
0401 tdp_level, &resp);
0402 if (ret) {
0403 isst_display_error_info_message(1, "Set TDP level failed for level", 1, tdp_level);
0404 return ret;
0405 }
0406
0407 return 0;
0408 }
0409
0410 int isst_get_pbf_info(int cpu, int level, struct isst_pbf_info *pbf_info)
0411 {
0412 struct isst_pkg_ctdp_level_info ctdp_level;
0413 struct isst_pkg_ctdp pkg_dev;
0414 int i, ret, max_punit_core, max_mask_index;
0415 unsigned int req, resp;
0416
0417 ret = isst_get_ctdp_levels(cpu, &pkg_dev);
0418 if (ret) {
0419 isst_display_error_info_message(1, "Failed to get number of levels", 0, 0);
0420 return ret;
0421 }
0422
0423 if (level > pkg_dev.levels) {
0424 isst_display_error_info_message(1, "Invalid level", 1, level);
0425 return -1;
0426 }
0427
0428 ret = isst_get_ctdp_control(cpu, level, &ctdp_level);
0429 if (ret)
0430 return ret;
0431
0432 if (!ctdp_level.pbf_support) {
0433 isst_display_error_info_message(1, "base-freq feature is not present at this level", 1, level);
0434 return -1;
0435 }
0436
0437 pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask);
0438
0439 max_punit_core = get_max_punit_core_id(get_physical_package_id(cpu), get_physical_die_id(cpu));
0440 max_mask_index = max_punit_core > 32 ? 2 : 1;
0441
0442 for (i = 0; i < max_mask_index; ++i) {
0443 unsigned long long mask;
0444 int count;
0445
0446 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
0447 CONFIG_TDP_PBF_GET_CORE_MASK_INFO,
0448 0, (i << 8) | level, &resp);
0449 if (ret)
0450 break;
0451
0452 debug_printf(
0453 "cpu:%d CONFIG_TDP_PBF_GET_CORE_MASK_INFO resp:%x\n",
0454 cpu, resp);
0455
0456 mask = (unsigned long long)resp << (32 * i);
0457 set_cpu_mask_from_punit_coremask(cpu, mask,
0458 pbf_info->core_cpumask_size,
0459 pbf_info->core_cpumask,
0460 &count);
0461 }
0462
0463 req = level;
0464 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
0465 CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO, 0, req,
0466 &resp);
0467 if (ret)
0468 return ret;
0469
0470 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO resp:%x\n", cpu,
0471 resp);
0472
0473 pbf_info->p1_low = resp & 0xff;
0474 pbf_info->p1_high = (resp & GENMASK(15, 8)) >> 8;
0475
0476 req = level;
0477 ret = isst_send_mbox_command(
0478 cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TDP_INFO, 0, req, &resp);
0479 if (ret)
0480 return ret;
0481
0482 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TDP_INFO resp:%x\n", cpu, resp);
0483
0484 pbf_info->tdp = resp & 0xffff;
0485
0486 req = level;
0487 ret = isst_send_mbox_command(
0488 cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TJ_MAX_INFO, 0, req, &resp);
0489 if (ret)
0490 return ret;
0491
0492 debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TJ_MAX_INFO resp:%x\n", cpu,
0493 resp);
0494 pbf_info->t_control = (resp >> 8) & 0xff;
0495 pbf_info->t_prochot = resp & 0xff;
0496
0497 return 0;
0498 }
0499
0500 void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info)
0501 {
0502 free_cpu_set(pbf_info->core_cpumask);
0503 }
0504
0505 int isst_set_pbf_fact_status(int cpu, int pbf, int enable)
0506 {
0507 struct isst_pkg_ctdp pkg_dev;
0508 struct isst_pkg_ctdp_level_info ctdp_level;
0509 int current_level;
0510 unsigned int req = 0, resp;
0511 int ret;
0512
0513 ret = isst_get_ctdp_levels(cpu, &pkg_dev);
0514 if (ret)
0515 debug_printf("cpu:%d No support for dynamic ISST\n", cpu);
0516
0517 current_level = pkg_dev.current_level;
0518
0519 ret = isst_get_ctdp_control(cpu, current_level, &ctdp_level);
0520 if (ret)
0521 return ret;
0522
0523 if (pbf) {
0524 if (ctdp_level.fact_enabled)
0525 req = BIT(16);
0526
0527 if (enable)
0528 req |= BIT(17);
0529 else
0530 req &= ~BIT(17);
0531 } else {
0532
0533 if (enable && !ctdp_level.sst_cp_enabled)
0534 isst_display_error_info_message(0, "Make sure to execute before: core-power enable", 0, 0);
0535
0536 if (ctdp_level.pbf_enabled)
0537 req = BIT(17);
0538
0539 if (enable)
0540 req |= BIT(16);
0541 else
0542 req &= ~BIT(16);
0543 }
0544
0545 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
0546 CONFIG_TDP_SET_TDP_CONTROL, 0, req, &resp);
0547 if (ret)
0548 return ret;
0549
0550 debug_printf("cpu:%d CONFIG_TDP_SET_TDP_CONTROL pbf/fact:%d req:%x\n",
0551 cpu, pbf, req);
0552
0553 return 0;
0554 }
0555
0556 int isst_get_fact_bucket_info(int cpu, int level,
0557 struct isst_fact_bucket_info *bucket_info)
0558 {
0559 unsigned int resp;
0560 int i, k, ret;
0561
0562 for (i = 0; i < 2; ++i) {
0563 int j;
0564
0565 ret = isst_send_mbox_command(
0566 cpu, CONFIG_TDP,
0567 CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES, 0,
0568 (i << 8) | level, &resp);
0569 if (ret)
0570 return ret;
0571
0572 debug_printf(
0573 "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES index:%d level:%d resp:%x\n",
0574 cpu, i, level, resp);
0575
0576 for (j = 0; j < 4; ++j) {
0577 bucket_info[j + (i * 4)].high_priority_cores_count =
0578 (resp >> (j * 8)) & 0xff;
0579 }
0580 }
0581
0582 for (k = 0; k < 3; ++k) {
0583 for (i = 0; i < 2; ++i) {
0584 int j;
0585
0586 ret = isst_send_mbox_command(
0587 cpu, CONFIG_TDP,
0588 CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS, 0,
0589 (k << 16) | (i << 8) | level, &resp);
0590 if (ret)
0591 return ret;
0592
0593 debug_printf(
0594 "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS index:%d level:%d avx:%d resp:%x\n",
0595 cpu, i, level, k, resp);
0596
0597 for (j = 0; j < 4; ++j) {
0598 switch (k) {
0599 case 0:
0600 bucket_info[j + (i * 4)].sse_trl =
0601 (resp >> (j * 8)) & 0xff;
0602 break;
0603 case 1:
0604 bucket_info[j + (i * 4)].avx_trl =
0605 (resp >> (j * 8)) & 0xff;
0606 break;
0607 case 2:
0608 bucket_info[j + (i * 4)].avx512_trl =
0609 (resp >> (j * 8)) & 0xff;
0610 break;
0611 default:
0612 break;
0613 }
0614 }
0615 }
0616 }
0617
0618 return 0;
0619 }
0620
0621 int isst_get_fact_info(int cpu, int level, int fact_bucket, struct isst_fact_info *fact_info)
0622 {
0623 struct isst_pkg_ctdp_level_info ctdp_level;
0624 struct isst_pkg_ctdp pkg_dev;
0625 unsigned int resp;
0626 int j, ret, print;
0627
0628 ret = isst_get_ctdp_levels(cpu, &pkg_dev);
0629 if (ret) {
0630 isst_display_error_info_message(1, "Failed to get number of levels", 0, 0);
0631 return ret;
0632 }
0633
0634 if (level > pkg_dev.levels) {
0635 isst_display_error_info_message(1, "Invalid level", 1, level);
0636 return -1;
0637 }
0638
0639 ret = isst_get_ctdp_control(cpu, level, &ctdp_level);
0640 if (ret)
0641 return ret;
0642
0643 if (!ctdp_level.fact_support) {
0644 isst_display_error_info_message(1, "turbo-freq feature is not present at this level", 1, level);
0645 return -1;
0646 }
0647
0648 ret = isst_send_mbox_command(cpu, CONFIG_TDP,
0649 CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO, 0,
0650 level, &resp);
0651 if (ret)
0652 return ret;
0653
0654 debug_printf("cpu:%d CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO resp:%x\n",
0655 cpu, resp);
0656
0657 fact_info->lp_clipping_ratio_license_sse = resp & 0xff;
0658 fact_info->lp_clipping_ratio_license_avx2 = (resp >> 8) & 0xff;
0659 fact_info->lp_clipping_ratio_license_avx512 = (resp >> 16) & 0xff;
0660
0661 ret = isst_get_fact_bucket_info(cpu, level, fact_info->bucket_info);
0662 if (ret)
0663 return ret;
0664
0665 print = 0;
0666 for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) {
0667 if (fact_bucket != 0xff && fact_bucket != j)
0668 continue;
0669
0670 if (!fact_info->bucket_info[j].high_priority_cores_count)
0671 break;
0672
0673 print = 1;
0674 }
0675 if (!print) {
0676 isst_display_error_info_message(1, "Invalid bucket", 0, 0);
0677 return -1;
0678 }
0679
0680 return 0;
0681 }
0682
0683 int isst_get_trl(int cpu, unsigned long long *trl)
0684 {
0685 int ret;
0686
0687 ret = isst_send_msr_command(cpu, 0x1AD, 0, trl);
0688 if (ret)
0689 return ret;
0690
0691 return 0;
0692 }
0693
0694 int isst_set_trl(int cpu, unsigned long long trl)
0695 {
0696 int ret;
0697
0698 if (!trl)
0699 trl = 0xFFFFFFFFFFFFFFFFULL;
0700
0701 ret = isst_send_msr_command(cpu, 0x1AD, 1, &trl);
0702 if (ret)
0703 return ret;
0704
0705 return 0;
0706 }
0707
0708 int isst_set_trl_from_current_tdp(int cpu, unsigned long long trl)
0709 {
0710 unsigned long long msr_trl;
0711 int ret;
0712
0713 if (trl) {
0714 msr_trl = trl;
0715 } else {
0716 struct isst_pkg_ctdp pkg_dev;
0717 int trl[8];
0718 int i;
0719
0720 ret = isst_get_ctdp_levels(cpu, &pkg_dev);
0721 if (ret)
0722 return ret;
0723
0724 ret = isst_get_get_trl(cpu, pkg_dev.current_level, 0, trl);
0725 if (ret)
0726 return ret;
0727
0728 msr_trl = 0;
0729 for (i = 0; i < 8; ++i) {
0730 unsigned long long _trl = trl[i];
0731
0732 msr_trl |= (_trl << (i * 8));
0733 }
0734 }
0735 ret = isst_send_msr_command(cpu, 0x1AD, 1, &msr_trl);
0736 if (ret)
0737 return ret;
0738
0739 return 0;
0740 }
0741
0742
0743 int isst_get_config_tdp_lock_status(int cpu)
0744 {
0745 unsigned long long tdp_control = 0;
0746 int ret;
0747
0748 ret = isst_send_msr_command(cpu, 0x64b, 0, &tdp_control);
0749 if (ret)
0750 return ret;
0751
0752 ret = !!(tdp_control & BIT(31));
0753
0754 return ret;
0755 }
0756
0757 void isst_get_process_ctdp_complete(int cpu, struct isst_pkg_ctdp *pkg_dev)
0758 {
0759 int i;
0760
0761 if (!pkg_dev->processed)
0762 return;
0763
0764 for (i = 0; i < pkg_dev->levels; ++i) {
0765 struct isst_pkg_ctdp_level_info *ctdp_level;
0766
0767 ctdp_level = &pkg_dev->ctdp_level[i];
0768 if (ctdp_level->pbf_support)
0769 free_cpu_set(ctdp_level->pbf_info.core_cpumask);
0770 free_cpu_set(ctdp_level->core_cpumask);
0771 }
0772 }
0773
0774 int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
0775 {
0776 int i, ret, valid = 0;
0777
0778 if (pkg_dev->processed)
0779 return 0;
0780
0781 ret = isst_get_ctdp_levels(cpu, pkg_dev);
0782 if (ret)
0783 return ret;
0784
0785 debug_printf("cpu: %d ctdp enable:%d current level: %d levels:%d\n",
0786 cpu, pkg_dev->enabled, pkg_dev->current_level,
0787 pkg_dev->levels);
0788
0789 if (tdp_level != 0xff && tdp_level > pkg_dev->levels) {
0790 isst_display_error_info_message(1, "Invalid level", 0, 0);
0791 return -1;
0792 }
0793
0794 if (!pkg_dev->enabled)
0795 isst_display_error_info_message(0, "perf-profile feature is not supported, just base-config level 0 is valid", 0, 0);
0796
0797 for (i = 0; i <= pkg_dev->levels; ++i) {
0798 struct isst_pkg_ctdp_level_info *ctdp_level;
0799
0800 if (tdp_level != 0xff && i != tdp_level)
0801 continue;
0802
0803 debug_printf("cpu:%d Get Information for TDP level:%d\n", cpu,
0804 i);
0805 ctdp_level = &pkg_dev->ctdp_level[i];
0806
0807 ctdp_level->level = i;
0808 ctdp_level->control_cpu = cpu;
0809 ctdp_level->pkg_id = get_physical_package_id(cpu);
0810 ctdp_level->die_id = get_physical_die_id(cpu);
0811
0812 ret = isst_get_ctdp_control(cpu, i, ctdp_level);
0813 if (ret)
0814 continue;
0815
0816 valid = 1;
0817 pkg_dev->processed = 1;
0818 ctdp_level->processed = 1;
0819
0820 if (ctdp_level->pbf_support) {
0821 ret = isst_get_pbf_info(cpu, i, &ctdp_level->pbf_info);
0822 if (!ret)
0823 ctdp_level->pbf_found = 1;
0824 }
0825
0826 if (ctdp_level->fact_support) {
0827 ret = isst_get_fact_info(cpu, i, 0xff,
0828 &ctdp_level->fact_info);
0829 if (ret)
0830 return ret;
0831 }
0832
0833 if (!pkg_dev->enabled && is_skx_based_platform()) {
0834 int freq;
0835
0836 freq = get_cpufreq_base_freq(cpu);
0837 if (freq > 0) {
0838 ctdp_level->sse_p1 = freq / 100000;
0839 ctdp_level->tdp_ratio = ctdp_level->sse_p1;
0840 }
0841
0842 isst_get_get_trl_from_msr(cpu, ctdp_level->trl_sse_active_cores);
0843 isst_get_trl_bucket_info(cpu, &ctdp_level->buckets_info);
0844 continue;
0845 }
0846
0847 ret = isst_get_tdp_info(cpu, i, ctdp_level);
0848 if (ret)
0849 return ret;
0850
0851 ret = isst_get_pwr_info(cpu, i, ctdp_level);
0852 if (ret)
0853 return ret;
0854
0855 ret = isst_get_tjmax_info(cpu, i, ctdp_level);
0856 if (ret)
0857 return ret;
0858
0859 ctdp_level->core_cpumask_size =
0860 alloc_cpu_set(&ctdp_level->core_cpumask);
0861 ret = isst_get_coremask_info(cpu, i, ctdp_level);
0862 if (ret)
0863 return ret;
0864
0865 ret = isst_get_trl_bucket_info(cpu, &ctdp_level->buckets_info);
0866 if (ret)
0867 return ret;
0868
0869 ret = isst_get_get_trl(cpu, i, 0,
0870 ctdp_level->trl_sse_active_cores);
0871 if (ret)
0872 return ret;
0873
0874 ret = isst_get_get_trl(cpu, i, 1,
0875 ctdp_level->trl_avx_active_cores);
0876 if (ret)
0877 return ret;
0878
0879 ret = isst_get_get_trl(cpu, i, 2,
0880 ctdp_level->trl_avx_512_active_cores);
0881 if (ret)
0882 return ret;
0883
0884 isst_get_uncore_p0_p1_info(cpu, i, ctdp_level);
0885 isst_get_p1_info(cpu, i, ctdp_level);
0886 isst_get_uncore_mem_freq(cpu, i, ctdp_level);
0887 }
0888
0889 if (!valid)
0890 isst_display_error_info_message(0, "Invalid level, Can't get TDP control information at specified levels on cpu", 1, cpu);
0891
0892 return 0;
0893 }
0894
0895 int isst_clos_get_clos_information(int cpu, int *enable, int *type)
0896 {
0897 unsigned int resp;
0898 int ret;
0899
0900 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0,
0901 &resp);
0902 if (ret)
0903 return ret;
0904
0905 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp);
0906
0907 if (resp & BIT(1))
0908 *enable = 1;
0909 else
0910 *enable = 0;
0911
0912 if (resp & BIT(2))
0913 *type = 1;
0914 else
0915 *type = 0;
0916
0917 return 0;
0918 }
0919
0920 int isst_pm_qos_config(int cpu, int enable_clos, int priority_type)
0921 {
0922 unsigned int req, resp;
0923 int ret;
0924
0925 if (!enable_clos) {
0926 struct isst_pkg_ctdp pkg_dev;
0927 struct isst_pkg_ctdp_level_info ctdp_level;
0928
0929 ret = isst_get_ctdp_levels(cpu, &pkg_dev);
0930 if (ret) {
0931 debug_printf("isst_get_ctdp_levels\n");
0932 return ret;
0933 }
0934
0935 ret = isst_get_ctdp_control(cpu, pkg_dev.current_level,
0936 &ctdp_level);
0937 if (ret)
0938 return ret;
0939
0940 if (ctdp_level.fact_enabled) {
0941 isst_display_error_info_message(1, "Ignoring request, turbo-freq feature is still enabled", 0, 0);
0942 return -EINVAL;
0943 }
0944 ret = isst_write_pm_config(cpu, 0);
0945 if (ret)
0946 isst_display_error_info_message(0, "WRITE_PM_CONFIG command failed, ignoring error", 0, 0);
0947 } else {
0948 ret = isst_write_pm_config(cpu, 1);
0949 if (ret)
0950 isst_display_error_info_message(0, "WRITE_PM_CONFIG command failed, ignoring error", 0, 0);
0951 }
0952
0953 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0,
0954 &resp);
0955 if (ret) {
0956 isst_display_error_info_message(1, "CLOS_PM_QOS_CONFIG command failed", 0, 0);
0957 return ret;
0958 }
0959
0960 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp);
0961
0962 req = resp;
0963
0964 if (enable_clos)
0965 req = req | BIT(1);
0966 else
0967 req = req & ~BIT(1);
0968
0969 if (priority_type > 1)
0970 isst_display_error_info_message(1, "Invalid priority type: Changing type to ordered", 0, 0);
0971
0972 if (priority_type)
0973 req = req | BIT(2);
0974 else
0975 req = req & ~BIT(2);
0976
0977 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG,
0978 BIT(MBOX_CMD_WRITE_BIT), req, &resp);
0979 if (ret)
0980 return ret;
0981
0982 debug_printf("cpu:%d CLOS_PM_QOS_CONFIG priority type:%d req:%x\n", cpu,
0983 priority_type, req);
0984
0985 return 0;
0986 }
0987
0988 int isst_pm_get_clos(int cpu, int clos, struct isst_clos_config *clos_config)
0989 {
0990 unsigned int resp;
0991 int ret;
0992
0993 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0,
0994 &resp);
0995 if (ret)
0996 return ret;
0997
0998 clos_config->pkg_id = get_physical_package_id(cpu);
0999 clos_config->die_id = get_physical_die_id(cpu);
1000
1001 clos_config->epp = resp & 0x0f;
1002 clos_config->clos_prop_prio = (resp >> 4) & 0x0f;
1003 clos_config->clos_min = (resp >> 8) & 0xff;
1004 clos_config->clos_max = (resp >> 16) & 0xff;
1005 clos_config->clos_desired = (resp >> 24) & 0xff;
1006
1007 return 0;
1008 }
1009
1010 int isst_set_clos(int cpu, int clos, struct isst_clos_config *clos_config)
1011 {
1012 unsigned int req, resp;
1013 unsigned int param;
1014 int ret;
1015
1016 req = clos_config->epp & 0x0f;
1017 req |= (clos_config->clos_prop_prio & 0x0f) << 4;
1018 req |= (clos_config->clos_min & 0xff) << 8;
1019 req |= (clos_config->clos_max & 0xff) << 16;
1020 req |= (clos_config->clos_desired & 0xff) << 24;
1021
1022 param = BIT(MBOX_CMD_WRITE_BIT) | clos;
1023
1024 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req,
1025 &resp);
1026 if (ret)
1027 return ret;
1028
1029 debug_printf("cpu:%d CLOS_PM_CLOS param:%x req:%x\n", cpu, param, req);
1030
1031 return 0;
1032 }
1033
1034 int isst_clos_get_assoc_status(int cpu, int *clos_id)
1035 {
1036 unsigned int resp;
1037 unsigned int param;
1038 int core_id, ret;
1039
1040 core_id = find_phy_core_num(cpu);
1041 param = core_id;
1042
1043 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0,
1044 &resp);
1045 if (ret)
1046 return ret;
1047
1048 debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x resp:%x\n", cpu, param,
1049 resp);
1050 *clos_id = (resp >> 16) & 0x03;
1051
1052 return 0;
1053 }
1054
1055 int isst_clos_associate(int cpu, int clos_id)
1056 {
1057 unsigned int req, resp;
1058 unsigned int param;
1059 int core_id, ret;
1060
1061 req = (clos_id & 0x03) << 16;
1062 core_id = find_phy_core_num(cpu);
1063 param = BIT(MBOX_CMD_WRITE_BIT) | core_id;
1064
1065 ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param,
1066 req, &resp);
1067 if (ret)
1068 return ret;
1069
1070 debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x req:%x\n", cpu, param,
1071 req);
1072
1073 return 0;
1074 }