1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2021 Intel Corporation 4 */ 5 6 #include <linux/string_helpers.h> 7 8 #include <drm/drm_cache.h> 9 10 #include "gt/intel_gt.h" 11 #include "gt/intel_gt_regs.h" 12 #include "gt/intel_rps.h" 13 14 #include "i915_drv.h" 15 #include "i915_reg.h" 16 #include "i915_wait_util.h" 17 #include "intel_guc_print.h" 18 #include "intel_guc_slpc.h" 19 #include "intel_mchbar_regs.h" 20 21 /** 22 * DOC: SLPC - Dynamic Frequency management 23 * 24 * Single Loop Power Control (SLPC) is a GuC algorithm that manages 25 * GT frequency based on busyness and how KMD initializes it. SLPC is 26 * almost completely in control after initialization except for a few 27 * scenarios mentioned below. 28 * 29 * KMD uses the concept of waitboost to ramp frequency to RP0 when there 30 * are pending submissions for a context. It achieves this by sending GuC a 31 * request to update the min frequency to RP0. Waitboost is disabled 32 * when the request retires. 33 * 34 * Another form of frequency control happens through per-context hints. 35 * A context can be marked as low latency during creation. That will ensure 36 * that SLPC uses an aggressive frequency ramp when that context is active. 37 * 38 * Power profiles add another level of control to these mechanisms. 39 * When power saving profile is chosen, SLPC will use conservative 40 * thresholds to ramp frequency, thus saving power. KMD will disable 41 * waitboosts as well, which achieves further power savings. Base profile 42 * is default and ensures balanced performance for any workload. 43 * 44 * Lastly, users have some level of control through sysfs, where min/max 45 * frequency values can be altered and the use of efficient freq 46 * can be toggled. 47 */ 48 49 static inline struct intel_guc *slpc_to_guc(struct intel_guc_slpc *slpc) 50 { 51 return container_of(slpc, struct intel_guc, slpc); 52 } 53 54 static inline struct intel_gt *slpc_to_gt(struct intel_guc_slpc *slpc) 55 { 56 return guc_to_gt(slpc_to_guc(slpc)); 57 } 58 59 static inline struct drm_i915_private *slpc_to_i915(struct intel_guc_slpc *slpc) 60 { 61 return slpc_to_gt(slpc)->i915; 62 } 63 64 static bool __detect_slpc_supported(struct intel_guc *guc) 65 { 66 /* GuC SLPC is unavailable for pre-Gen12 */ 67 return guc->submission_supported && 68 GRAPHICS_VER(guc_to_i915(guc)) >= 12; 69 } 70 71 static bool __guc_slpc_selected(struct intel_guc *guc) 72 { 73 if (!intel_guc_slpc_is_supported(guc)) 74 return false; 75 76 return guc->submission_selected; 77 } 78 79 void intel_guc_slpc_init_early(struct intel_guc_slpc *slpc) 80 { 81 struct intel_guc *guc = slpc_to_guc(slpc); 82 83 slpc->supported = __detect_slpc_supported(guc); 84 slpc->selected = __guc_slpc_selected(guc); 85 } 86 87 static void slpc_mem_set_param(struct slpc_shared_data *data, 88 u32 id, u32 value) 89 { 90 GEM_BUG_ON(id >= SLPC_MAX_OVERRIDE_PARAMETERS); 91 /* 92 * When the flag bit is set, corresponding value will be read 93 * and applied by SLPC. 94 */ 95 data->override_params.bits[id >> 5] |= (1 << (id % 32)); 96 data->override_params.values[id] = value; 97 } 98 99 static void slpc_mem_set_enabled(struct slpc_shared_data *data, 100 u8 enable_id, u8 disable_id) 101 { 102 /* 103 * Enabling a param involves setting the enable_id 104 * to 1 and disable_id to 0. 105 */ 106 slpc_mem_set_param(data, enable_id, 1); 107 slpc_mem_set_param(data, disable_id, 0); 108 } 109 110 static void slpc_mem_set_disabled(struct slpc_shared_data *data, 111 u8 enable_id, u8 disable_id) 112 { 113 /* 114 * Disabling a param involves setting the enable_id 115 * to 0 and disable_id to 1. 116 */ 117 slpc_mem_set_param(data, disable_id, 1); 118 slpc_mem_set_param(data, enable_id, 0); 119 } 120 121 static u32 slpc_get_state(struct intel_guc_slpc *slpc) 122 { 123 struct slpc_shared_data *data; 124 125 GEM_BUG_ON(!slpc->vma); 126 127 drm_clflush_virt_range(slpc->vaddr, sizeof(u32)); 128 data = slpc->vaddr; 129 130 return data->header.global_state; 131 } 132 133 static int guc_action_slpc_set_param_nb(struct intel_guc *guc, u8 id, u32 value) 134 { 135 u32 request[] = { 136 GUC_ACTION_HOST2GUC_PC_SLPC_REQUEST, 137 SLPC_EVENT(SLPC_EVENT_PARAMETER_SET, 2), 138 id, 139 value, 140 }; 141 int ret; 142 143 ret = intel_guc_send_nb(guc, request, ARRAY_SIZE(request), 0); 144 145 return ret > 0 ? -EPROTO : ret; 146 } 147 148 static int slpc_set_param_nb(struct intel_guc_slpc *slpc, u8 id, u32 value) 149 { 150 struct intel_guc *guc = slpc_to_guc(slpc); 151 152 GEM_BUG_ON(id >= SLPC_MAX_PARAM); 153 154 return guc_action_slpc_set_param_nb(guc, id, value); 155 } 156 157 static int guc_action_slpc_set_param(struct intel_guc *guc, u8 id, u32 value) 158 { 159 u32 request[] = { 160 GUC_ACTION_HOST2GUC_PC_SLPC_REQUEST, 161 SLPC_EVENT(SLPC_EVENT_PARAMETER_SET, 2), 162 id, 163 value, 164 }; 165 int ret; 166 167 ret = intel_guc_send(guc, request, ARRAY_SIZE(request)); 168 169 return ret > 0 ? -EPROTO : ret; 170 } 171 172 static bool slpc_is_running(struct intel_guc_slpc *slpc) 173 { 174 return slpc_get_state(slpc) == SLPC_GLOBAL_STATE_RUNNING; 175 } 176 177 static int guc_action_slpc_query(struct intel_guc *guc, u32 offset) 178 { 179 u32 request[] = { 180 GUC_ACTION_HOST2GUC_PC_SLPC_REQUEST, 181 SLPC_EVENT(SLPC_EVENT_QUERY_TASK_STATE, 2), 182 offset, 183 0, 184 }; 185 int ret; 186 187 ret = intel_guc_send(guc, request, ARRAY_SIZE(request)); 188 189 return ret > 0 ? -EPROTO : ret; 190 } 191 192 static int slpc_query_task_state(struct intel_guc_slpc *slpc) 193 { 194 struct intel_guc *guc = slpc_to_guc(slpc); 195 u32 offset = intel_guc_ggtt_offset(guc, slpc->vma); 196 int ret; 197 198 ret = guc_action_slpc_query(guc, offset); 199 if (unlikely(ret)) 200 guc_probe_error(guc, "Failed to query task state: %pe\n", ERR_PTR(ret)); 201 202 drm_clflush_virt_range(slpc->vaddr, SLPC_PAGE_SIZE_BYTES); 203 204 return ret; 205 } 206 207 static int slpc_set_param(struct intel_guc_slpc *slpc, u8 id, u32 value) 208 { 209 struct intel_guc *guc = slpc_to_guc(slpc); 210 int ret; 211 212 GEM_BUG_ON(id >= SLPC_MAX_PARAM); 213 214 ret = guc_action_slpc_set_param(guc, id, value); 215 if (ret) 216 guc_probe_error(guc, "Failed to set param %d to %u: %pe\n", 217 id, value, ERR_PTR(ret)); 218 219 return ret; 220 } 221 222 static int slpc_force_min_freq(struct intel_guc_slpc *slpc, u32 freq) 223 { 224 struct intel_guc *guc = slpc_to_guc(slpc); 225 struct drm_i915_private *i915 = slpc_to_i915(slpc); 226 intel_wakeref_t wakeref; 227 int ret = 0; 228 229 lockdep_assert_held(&slpc->lock); 230 231 if (!intel_guc_is_ready(guc)) 232 return -ENODEV; 233 234 /* 235 * This function is a little different as compared to 236 * intel_guc_slpc_set_min_freq(). Softlimit will not be updated 237 * here since this is used to temporarily change min freq, 238 * for example, during a waitboost. Caller is responsible for 239 * checking bounds. 240 */ 241 242 with_intel_runtime_pm(&i915->runtime_pm, wakeref) { 243 /* Non-blocking request will avoid stalls */ 244 ret = slpc_set_param_nb(slpc, 245 SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ, 246 freq); 247 if (ret) 248 guc_notice(guc, "Failed to send set_param for min freq(%d): %pe\n", 249 freq, ERR_PTR(ret)); 250 } 251 252 return ret; 253 } 254 255 static void slpc_boost_work(struct work_struct *work) 256 { 257 struct intel_guc_slpc *slpc = container_of(work, typeof(*slpc), boost_work); 258 int err; 259 260 /* 261 * Raise min freq to boost. It's possible that 262 * this is greater than current max. But it will 263 * certainly be limited by RP0. An error setting 264 * the min param is not fatal. 265 */ 266 mutex_lock(&slpc->lock); 267 if (atomic_read(&slpc->num_waiters)) { 268 err = slpc_force_min_freq(slpc, slpc->boost_freq); 269 if (!err) 270 slpc->num_boosts++; 271 } 272 mutex_unlock(&slpc->lock); 273 } 274 275 int intel_guc_slpc_init(struct intel_guc_slpc *slpc) 276 { 277 struct intel_guc *guc = slpc_to_guc(slpc); 278 u32 size = PAGE_ALIGN(sizeof(struct slpc_shared_data)); 279 int err; 280 281 GEM_BUG_ON(slpc->vma); 282 283 err = intel_guc_allocate_and_map_vma(guc, size, &slpc->vma, (void **)&slpc->vaddr); 284 if (unlikely(err)) { 285 guc_probe_error(guc, "Failed to allocate SLPC struct: %pe\n", ERR_PTR(err)); 286 return err; 287 } 288 289 slpc->max_freq_softlimit = 0; 290 slpc->min_freq_softlimit = 0; 291 slpc->ignore_eff_freq = false; 292 slpc->min_is_rpmax = false; 293 294 slpc->boost_freq = 0; 295 atomic_set(&slpc->num_waiters, 0); 296 slpc->num_boosts = 0; 297 slpc->media_ratio_mode = SLPC_MEDIA_RATIO_MODE_DYNAMIC_CONTROL; 298 299 slpc->power_profile = SLPC_POWER_PROFILES_BASE; 300 301 mutex_init(&slpc->lock); 302 INIT_WORK(&slpc->boost_work, slpc_boost_work); 303 304 return err; 305 } 306 307 static const char *slpc_global_state_to_string(enum slpc_global_state state) 308 { 309 switch (state) { 310 case SLPC_GLOBAL_STATE_NOT_RUNNING: 311 return "not running"; 312 case SLPC_GLOBAL_STATE_INITIALIZING: 313 return "initializing"; 314 case SLPC_GLOBAL_STATE_RESETTING: 315 return "resetting"; 316 case SLPC_GLOBAL_STATE_RUNNING: 317 return "running"; 318 case SLPC_GLOBAL_STATE_SHUTTING_DOWN: 319 return "shutting down"; 320 case SLPC_GLOBAL_STATE_ERROR: 321 return "error"; 322 default: 323 return "unknown"; 324 } 325 } 326 327 static const char *slpc_get_state_string(struct intel_guc_slpc *slpc) 328 { 329 return slpc_global_state_to_string(slpc_get_state(slpc)); 330 } 331 332 static int guc_action_slpc_reset(struct intel_guc *guc, u32 offset) 333 { 334 u32 request[] = { 335 GUC_ACTION_HOST2GUC_PC_SLPC_REQUEST, 336 SLPC_EVENT(SLPC_EVENT_RESET, 2), 337 offset, 338 0, 339 }; 340 int ret; 341 342 ret = intel_guc_send(guc, request, ARRAY_SIZE(request)); 343 344 return ret > 0 ? -EPROTO : ret; 345 } 346 347 static int slpc_reset(struct intel_guc_slpc *slpc) 348 { 349 struct intel_guc *guc = slpc_to_guc(slpc); 350 u32 offset = intel_guc_ggtt_offset(guc, slpc->vma); 351 int ret; 352 353 ret = guc_action_slpc_reset(guc, offset); 354 355 if (unlikely(ret < 0)) { 356 guc_probe_error(guc, "SLPC reset action failed: %pe\n", ERR_PTR(ret)); 357 return ret; 358 } 359 360 if (!ret) { 361 if (wait_for(slpc_is_running(slpc), SLPC_RESET_TIMEOUT_MS)) { 362 guc_probe_error(guc, "SLPC not enabled! State = %s\n", 363 slpc_get_state_string(slpc)); 364 return -EIO; 365 } 366 } 367 368 return 0; 369 } 370 371 static u32 slpc_decode_min_freq(struct intel_guc_slpc *slpc) 372 { 373 struct slpc_shared_data *data = slpc->vaddr; 374 375 GEM_BUG_ON(!slpc->vma); 376 377 return DIV_ROUND_CLOSEST(REG_FIELD_GET(SLPC_MIN_UNSLICE_FREQ_MASK, 378 data->task_state_data.freq) * 379 GT_FREQUENCY_MULTIPLIER, GEN9_FREQ_SCALER); 380 } 381 382 static u32 slpc_decode_max_freq(struct intel_guc_slpc *slpc) 383 { 384 struct slpc_shared_data *data = slpc->vaddr; 385 386 GEM_BUG_ON(!slpc->vma); 387 388 return DIV_ROUND_CLOSEST(REG_FIELD_GET(SLPC_MAX_UNSLICE_FREQ_MASK, 389 data->task_state_data.freq) * 390 GT_FREQUENCY_MULTIPLIER, GEN9_FREQ_SCALER); 391 } 392 393 static void slpc_shared_data_reset(struct intel_guc_slpc *slpc) 394 { 395 struct drm_i915_private *i915 = slpc_to_i915(slpc); 396 struct slpc_shared_data *data = slpc->vaddr; 397 398 memset(data, 0, sizeof(struct slpc_shared_data)); 399 data->header.size = sizeof(struct slpc_shared_data); 400 401 /* Enable only GTPERF task, disable others */ 402 slpc_mem_set_enabled(data, SLPC_PARAM_TASK_ENABLE_GTPERF, 403 SLPC_PARAM_TASK_DISABLE_GTPERF); 404 405 /* 406 * Don't allow balancer related algorithms on platforms before 407 * Xe_LPG, where GuC started to restrict it to TDP limited scenarios. 408 */ 409 if (GRAPHICS_VER_FULL(i915) < IP_VER(12, 70)) { 410 slpc_mem_set_disabled(data, SLPC_PARAM_TASK_ENABLE_BALANCER, 411 SLPC_PARAM_TASK_DISABLE_BALANCER); 412 413 slpc_mem_set_disabled(data, SLPC_PARAM_TASK_ENABLE_DCC, 414 SLPC_PARAM_TASK_DISABLE_DCC); 415 } 416 } 417 418 /** 419 * intel_guc_slpc_set_max_freq() - Set max frequency limit for SLPC. 420 * @slpc: pointer to intel_guc_slpc. 421 * @val: frequency (MHz) 422 * 423 * This function will invoke GuC SLPC action to update the max frequency 424 * limit for unslice. 425 * 426 * Return: 0 on success, non-zero error code on failure. 427 */ 428 int intel_guc_slpc_set_max_freq(struct intel_guc_slpc *slpc, u32 val) 429 { 430 struct drm_i915_private *i915 = slpc_to_i915(slpc); 431 intel_wakeref_t wakeref; 432 int ret; 433 434 if (val < slpc->min_freq || 435 val > slpc->rp0_freq || 436 val < slpc->min_freq_softlimit) 437 return -EINVAL; 438 439 with_intel_runtime_pm(&i915->runtime_pm, wakeref) { 440 ret = slpc_set_param(slpc, 441 SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ, 442 val); 443 444 /* Return standardized err code for sysfs calls */ 445 if (ret) 446 ret = -EIO; 447 } 448 449 if (!ret) 450 slpc->max_freq_softlimit = val; 451 452 return ret; 453 } 454 455 /** 456 * intel_guc_slpc_get_max_freq() - Get max frequency limit for SLPC. 457 * @slpc: pointer to intel_guc_slpc. 458 * @val: pointer to val which will hold max frequency (MHz) 459 * 460 * This function will invoke GuC SLPC action to read the max frequency 461 * limit for unslice. 462 * 463 * Return: 0 on success, non-zero error code on failure. 464 */ 465 int intel_guc_slpc_get_max_freq(struct intel_guc_slpc *slpc, u32 *val) 466 { 467 struct drm_i915_private *i915 = slpc_to_i915(slpc); 468 intel_wakeref_t wakeref; 469 int ret = 0; 470 471 with_intel_runtime_pm(&i915->runtime_pm, wakeref) { 472 /* Force GuC to update task data */ 473 ret = slpc_query_task_state(slpc); 474 475 if (!ret) 476 *val = slpc_decode_max_freq(slpc); 477 } 478 479 return ret; 480 } 481 482 int intel_guc_slpc_set_ignore_eff_freq(struct intel_guc_slpc *slpc, bool val) 483 { 484 struct drm_i915_private *i915 = slpc_to_i915(slpc); 485 intel_wakeref_t wakeref; 486 int ret; 487 488 mutex_lock(&slpc->lock); 489 wakeref = intel_runtime_pm_get(&i915->runtime_pm); 490 491 ret = slpc_set_param(slpc, 492 SLPC_PARAM_IGNORE_EFFICIENT_FREQUENCY, 493 val); 494 if (ret) { 495 guc_probe_error(slpc_to_guc(slpc), "Failed to set efficient freq(%d): %pe\n", 496 val, ERR_PTR(ret)); 497 } else { 498 slpc->ignore_eff_freq = val; 499 500 /* Set min to RPn when we disable efficient freq */ 501 if (val) 502 ret = slpc_set_param(slpc, 503 SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ, 504 slpc->min_freq); 505 } 506 507 intel_runtime_pm_put(&i915->runtime_pm, wakeref); 508 mutex_unlock(&slpc->lock); 509 return ret; 510 } 511 512 /** 513 * intel_guc_slpc_set_min_freq() - Set min frequency limit for SLPC. 514 * @slpc: pointer to intel_guc_slpc. 515 * @val: frequency (MHz) 516 * 517 * This function will invoke GuC SLPC action to update the min unslice 518 * frequency. 519 * 520 * Return: 0 on success, non-zero error code on failure. 521 */ 522 int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val) 523 { 524 struct drm_i915_private *i915 = slpc_to_i915(slpc); 525 intel_wakeref_t wakeref; 526 int ret; 527 528 if (val < slpc->min_freq || 529 val > slpc->rp0_freq || 530 val > slpc->max_freq_softlimit) 531 return -EINVAL; 532 533 /* Need a lock now since waitboost can be modifying min as well */ 534 mutex_lock(&slpc->lock); 535 wakeref = intel_runtime_pm_get(&i915->runtime_pm); 536 537 ret = slpc_set_param(slpc, 538 SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ, 539 val); 540 541 if (!ret) 542 slpc->min_freq_softlimit = val; 543 544 intel_runtime_pm_put(&i915->runtime_pm, wakeref); 545 mutex_unlock(&slpc->lock); 546 547 /* Return standardized err code for sysfs calls */ 548 if (ret) 549 ret = -EIO; 550 551 return ret; 552 } 553 554 /** 555 * intel_guc_slpc_get_min_freq() - Get min frequency limit for SLPC. 556 * @slpc: pointer to intel_guc_slpc. 557 * @val: pointer to val which will hold min frequency (MHz) 558 * 559 * This function will invoke GuC SLPC action to read the min frequency 560 * limit for unslice. 561 * 562 * Return: 0 on success, non-zero error code on failure. 563 */ 564 int intel_guc_slpc_get_min_freq(struct intel_guc_slpc *slpc, u32 *val) 565 { 566 struct drm_i915_private *i915 = slpc_to_i915(slpc); 567 intel_wakeref_t wakeref; 568 int ret = 0; 569 570 with_intel_runtime_pm(&i915->runtime_pm, wakeref) { 571 /* Force GuC to update task data */ 572 ret = slpc_query_task_state(slpc); 573 574 if (!ret) 575 *val = slpc_decode_min_freq(slpc); 576 } 577 578 return ret; 579 } 580 581 int intel_guc_slpc_set_strategy(struct intel_guc_slpc *slpc, u32 val) 582 { 583 struct drm_i915_private *i915 = slpc_to_i915(slpc); 584 intel_wakeref_t wakeref; 585 int ret = 0; 586 587 with_intel_runtime_pm(&i915->runtime_pm, wakeref) 588 ret = slpc_set_param(slpc, 589 SLPC_PARAM_STRATEGIES, 590 val); 591 592 return ret; 593 } 594 595 int intel_guc_slpc_set_media_ratio_mode(struct intel_guc_slpc *slpc, u32 val) 596 { 597 struct drm_i915_private *i915 = slpc_to_i915(slpc); 598 intel_wakeref_t wakeref; 599 int ret = 0; 600 601 if (!HAS_MEDIA_RATIO_MODE(i915)) 602 return -ENODEV; 603 604 with_intel_runtime_pm(&i915->runtime_pm, wakeref) 605 ret = slpc_set_param(slpc, 606 SLPC_PARAM_MEDIA_FF_RATIO_MODE, 607 val); 608 return ret; 609 } 610 611 int intel_guc_slpc_set_power_profile(struct intel_guc_slpc *slpc, u32 val) 612 { 613 struct drm_i915_private *i915 = slpc_to_i915(slpc); 614 intel_wakeref_t wakeref; 615 int ret = 0; 616 617 if (val > SLPC_POWER_PROFILES_POWER_SAVING) 618 return -EINVAL; 619 620 mutex_lock(&slpc->lock); 621 wakeref = intel_runtime_pm_get(&i915->runtime_pm); 622 623 ret = slpc_set_param(slpc, 624 SLPC_PARAM_POWER_PROFILE, 625 val); 626 if (ret) 627 guc_err(slpc_to_guc(slpc), 628 "Failed to set power profile to %d: %pe\n", 629 val, ERR_PTR(ret)); 630 else 631 slpc->power_profile = val; 632 633 intel_runtime_pm_put(&i915->runtime_pm, wakeref); 634 mutex_unlock(&slpc->lock); 635 636 return ret; 637 } 638 639 void intel_guc_pm_intrmsk_enable(struct intel_gt *gt) 640 { 641 u32 pm_intrmsk_mbz = 0; 642 643 /* 644 * Allow GuC to receive ARAT timer expiry event. 645 * This interrupt register is setup by RPS code 646 * when host based Turbo is enabled. 647 */ 648 pm_intrmsk_mbz |= ARAT_EXPIRED_INTRMSK; 649 650 intel_uncore_rmw(gt->uncore, 651 GEN6_PMINTRMSK, pm_intrmsk_mbz, 0); 652 } 653 654 static int slpc_set_softlimits(struct intel_guc_slpc *slpc) 655 { 656 int ret = 0; 657 658 /* 659 * Softlimits are initially equivalent to platform limits 660 * unless they have deviated from defaults, in which case, 661 * we retain the values and set min/max accordingly. 662 */ 663 if (!slpc->max_freq_softlimit) { 664 slpc->max_freq_softlimit = slpc->rp0_freq; 665 slpc_to_gt(slpc)->defaults.max_freq = slpc->max_freq_softlimit; 666 } else if (slpc->max_freq_softlimit != slpc->rp0_freq) { 667 ret = intel_guc_slpc_set_max_freq(slpc, 668 slpc->max_freq_softlimit); 669 } 670 671 if (unlikely(ret)) 672 return ret; 673 674 if (!slpc->min_freq_softlimit) { 675 /* Min softlimit is initialized to RPn */ 676 slpc->min_freq_softlimit = slpc->min_freq; 677 slpc_to_gt(slpc)->defaults.min_freq = slpc->min_freq_softlimit; 678 } else { 679 return intel_guc_slpc_set_min_freq(slpc, 680 slpc->min_freq_softlimit); 681 } 682 683 return 0; 684 } 685 686 static bool is_slpc_min_freq_rpmax(struct intel_guc_slpc *slpc) 687 { 688 int slpc_min_freq; 689 int ret; 690 691 ret = intel_guc_slpc_get_min_freq(slpc, &slpc_min_freq); 692 if (ret) { 693 guc_err(slpc_to_guc(slpc), "Failed to get min freq: %pe\n", ERR_PTR(ret)); 694 return false; 695 } 696 697 if (slpc_min_freq == SLPC_MAX_FREQ_MHZ) 698 return true; 699 else 700 return false; 701 } 702 703 static void update_server_min_softlimit(struct intel_guc_slpc *slpc) 704 { 705 /* For server parts, SLPC min will be at RPMax. 706 * Use min softlimit to clamp it to RP0 instead. 707 */ 708 if (!slpc->min_freq_softlimit && 709 is_slpc_min_freq_rpmax(slpc)) { 710 slpc->min_is_rpmax = true; 711 slpc->min_freq_softlimit = slpc->rp0_freq; 712 (slpc_to_gt(slpc))->defaults.min_freq = slpc->min_freq_softlimit; 713 } 714 } 715 716 static int slpc_use_fused_rp0(struct intel_guc_slpc *slpc) 717 { 718 /* Force SLPC to used platform rp0 */ 719 return slpc_set_param(slpc, 720 SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ, 721 slpc->rp0_freq); 722 } 723 724 static void slpc_get_rp_values(struct intel_guc_slpc *slpc) 725 { 726 struct intel_rps *rps = &slpc_to_gt(slpc)->rps; 727 struct intel_rps_freq_caps caps; 728 729 gen6_rps_get_freq_caps(rps, &caps); 730 slpc->rp0_freq = intel_gpu_freq(rps, caps.rp0_freq); 731 slpc->rp1_freq = intel_gpu_freq(rps, caps.rp1_freq); 732 slpc->min_freq = intel_gpu_freq(rps, caps.min_freq); 733 734 if (!slpc->boost_freq) 735 slpc->boost_freq = slpc->rp0_freq; 736 } 737 738 /* 739 * intel_guc_slpc_enable() - Start SLPC 740 * @slpc: pointer to intel_guc_slpc. 741 * 742 * SLPC is enabled by setting up the shared data structure and 743 * sending reset event to GuC SLPC. Initial data is setup in 744 * intel_guc_slpc_init. Here we send the reset event. We do 745 * not currently need a slpc_disable since this is taken care 746 * of automatically when a reset/suspend occurs and the GuC 747 * CTB is destroyed. 748 * 749 * Return: 0 on success, non-zero error code on failure. 750 */ 751 int intel_guc_slpc_enable(struct intel_guc_slpc *slpc) 752 { 753 struct intel_guc *guc = slpc_to_guc(slpc); 754 int ret; 755 756 GEM_BUG_ON(!slpc->vma); 757 758 slpc_shared_data_reset(slpc); 759 760 ret = slpc_reset(slpc); 761 if (unlikely(ret < 0)) { 762 guc_probe_error(guc, "SLPC Reset event returned: %pe\n", ERR_PTR(ret)); 763 return ret; 764 } 765 766 ret = slpc_query_task_state(slpc); 767 if (unlikely(ret < 0)) 768 return ret; 769 770 intel_guc_pm_intrmsk_enable(slpc_to_gt(slpc)); 771 772 slpc_get_rp_values(slpc); 773 774 /* Handle the case where min=max=RPmax */ 775 update_server_min_softlimit(slpc); 776 777 /* Set SLPC max limit to RP0 */ 778 ret = slpc_use_fused_rp0(slpc); 779 if (unlikely(ret)) { 780 guc_probe_error(guc, "Failed to set SLPC max to RP0: %pe\n", ERR_PTR(ret)); 781 return ret; 782 } 783 784 /* Set cached value of ignore efficient freq */ 785 intel_guc_slpc_set_ignore_eff_freq(slpc, slpc->ignore_eff_freq); 786 787 /* Revert SLPC min/max to softlimits if necessary */ 788 ret = slpc_set_softlimits(slpc); 789 if (unlikely(ret)) { 790 guc_probe_error(guc, "Failed to set SLPC softlimits: %pe\n", ERR_PTR(ret)); 791 return ret; 792 } 793 794 /* Set cached media freq ratio mode */ 795 intel_guc_slpc_set_media_ratio_mode(slpc, slpc->media_ratio_mode); 796 797 /* Enable SLPC Optimized Strategy for compute */ 798 intel_guc_slpc_set_strategy(slpc, SLPC_OPTIMIZED_STRATEGY_COMPUTE); 799 800 /* Set cached value of power_profile */ 801 ret = intel_guc_slpc_set_power_profile(slpc, slpc->power_profile); 802 if (unlikely(ret)) { 803 guc_probe_error(guc, "Failed to set SLPC power profile: %pe\n", ERR_PTR(ret)); 804 return ret; 805 } 806 807 return 0; 808 } 809 810 int intel_guc_slpc_set_boost_freq(struct intel_guc_slpc *slpc, u32 val) 811 { 812 int ret = 0; 813 814 if (val < slpc->min_freq || val > slpc->rp0_freq) 815 return -EINVAL; 816 817 mutex_lock(&slpc->lock); 818 819 if (slpc->boost_freq != val) { 820 /* Apply only if there are active waiters */ 821 if (atomic_read(&slpc->num_waiters)) { 822 ret = slpc_force_min_freq(slpc, val); 823 if (ret) { 824 ret = -EIO; 825 goto done; 826 } 827 } 828 829 slpc->boost_freq = val; 830 } 831 832 done: 833 mutex_unlock(&slpc->lock); 834 return ret; 835 } 836 837 void intel_guc_slpc_dec_waiters(struct intel_guc_slpc *slpc) 838 { 839 /* 840 * Return min back to the softlimit. 841 * This is called during request retire, 842 * so we don't need to fail that if the 843 * set_param fails. 844 */ 845 mutex_lock(&slpc->lock); 846 if (atomic_dec_and_test(&slpc->num_waiters)) 847 slpc_force_min_freq(slpc, slpc->min_freq_softlimit); 848 mutex_unlock(&slpc->lock); 849 } 850 851 int intel_guc_slpc_print_info(struct intel_guc_slpc *slpc, struct drm_printer *p) 852 { 853 struct drm_i915_private *i915 = slpc_to_i915(slpc); 854 struct slpc_shared_data *data = slpc->vaddr; 855 struct slpc_task_state_data *slpc_tasks; 856 intel_wakeref_t wakeref; 857 int ret = 0; 858 859 GEM_BUG_ON(!slpc->vma); 860 861 with_intel_runtime_pm(&i915->runtime_pm, wakeref) { 862 ret = slpc_query_task_state(slpc); 863 864 if (!ret) { 865 slpc_tasks = &data->task_state_data; 866 867 drm_printf(p, "\tSLPC state: %s\n", slpc_get_state_string(slpc)); 868 drm_printf(p, "\tGTPERF task active: %s\n", 869 str_yes_no(slpc_tasks->status & SLPC_GTPERF_TASK_ENABLED)); 870 drm_printf(p, "\tDCC enabled: %s\n", 871 str_yes_no(slpc_tasks->status & 872 SLPC_DCC_TASK_ENABLED)); 873 drm_printf(p, "\tDCC in: %s\n", 874 str_yes_no(slpc_tasks->status & SLPC_IN_DCC)); 875 drm_printf(p, "\tBalancer enabled: %s\n", 876 str_yes_no(slpc_tasks->status & 877 SLPC_BALANCER_ENABLED)); 878 drm_printf(p, "\tIBC enabled: %s\n", 879 str_yes_no(slpc_tasks->status & 880 SLPC_IBC_TASK_ENABLED)); 881 drm_printf(p, "\tBalancer IA LMT enabled: %s\n", 882 str_yes_no(slpc_tasks->status & 883 SLPC_BALANCER_IA_LMT_ENABLED)); 884 drm_printf(p, "\tBalancer IA LMT active: %s\n", 885 str_yes_no(slpc_tasks->status & 886 SLPC_BALANCER_IA_LMT_ACTIVE)); 887 drm_printf(p, "\tMax freq: %u MHz\n", 888 slpc_decode_max_freq(slpc)); 889 drm_printf(p, "\tMin freq: %u MHz\n", 890 slpc_decode_min_freq(slpc)); 891 drm_printf(p, "\twaitboosts: %u\n", 892 slpc->num_boosts); 893 drm_printf(p, "\tBoosts outstanding: %u\n", 894 atomic_read(&slpc->num_waiters)); 895 } 896 } 897 898 return ret; 899 } 900 901 void intel_guc_slpc_fini(struct intel_guc_slpc *slpc) 902 { 903 if (!slpc->vma) 904 return; 905 906 i915_vma_unpin_and_release(&slpc->vma, I915_VMA_RELEASE_MAP); 907 } 908