1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #include <drm/drm_device.h> 7 #include <linux/sysfs.h> 8 #include <linux/printk.h> 9 10 #include "i915_drv.h" 11 #include "i915_reg.h" 12 #include "i915_sysfs.h" 13 #include "intel_gt.h" 14 #include "intel_gt_regs.h" 15 #include "intel_gt_sysfs.h" 16 #include "intel_gt_sysfs_pm.h" 17 #include "intel_pcode.h" 18 #include "intel_rc6.h" 19 #include "intel_rps.h" 20 21 enum intel_gt_sysfs_op { 22 INTEL_GT_SYSFS_MIN = 0, 23 INTEL_GT_SYSFS_MAX, 24 }; 25 26 static int 27 sysfs_gt_attribute_w_func(struct kobject *kobj, struct attribute *attr, 28 int (func)(struct intel_gt *gt, u32 val), u32 val) 29 { 30 struct intel_gt *gt; 31 int ret; 32 33 if (!is_object_gt(kobj)) { 34 int i; 35 struct device *dev = kobj_to_dev(kobj); 36 struct drm_i915_private *i915 = kdev_minor_to_i915(dev); 37 38 for_each_gt(gt, i915, i) { 39 ret = func(gt, val); 40 if (ret) 41 break; 42 } 43 } else { 44 gt = intel_gt_sysfs_get_drvdata(kobj, attr->name); 45 ret = func(gt, val); 46 } 47 48 return ret; 49 } 50 51 static u32 52 sysfs_gt_attribute_r_func(struct kobject *kobj, struct attribute *attr, 53 u32 (func)(struct intel_gt *gt), 54 enum intel_gt_sysfs_op op) 55 { 56 struct intel_gt *gt; 57 u32 ret; 58 59 ret = (op == INTEL_GT_SYSFS_MAX) ? 0 : (u32) -1; 60 61 if (!is_object_gt(kobj)) { 62 int i; 63 struct device *dev = kobj_to_dev(kobj); 64 struct drm_i915_private *i915 = kdev_minor_to_i915(dev); 65 66 for_each_gt(gt, i915, i) { 67 u32 val = func(gt); 68 69 switch (op) { 70 case INTEL_GT_SYSFS_MIN: 71 if (val < ret) 72 ret = val; 73 break; 74 75 case INTEL_GT_SYSFS_MAX: 76 if (val > ret) 77 ret = val; 78 break; 79 } 80 } 81 } else { 82 gt = intel_gt_sysfs_get_drvdata(kobj, attr->name); 83 ret = func(gt); 84 } 85 86 return ret; 87 } 88 89 /* RC6 interfaces will show the minimum RC6 residency value */ 90 #define sysfs_gt_attribute_r_min_func(d, a, f) \ 91 sysfs_gt_attribute_r_func(d, a, f, INTEL_GT_SYSFS_MIN) 92 93 /* Frequency interfaces will show the maximum frequency value */ 94 #define sysfs_gt_attribute_r_max_func(d, a, f) \ 95 sysfs_gt_attribute_r_func(d, a, f, INTEL_GT_SYSFS_MAX) 96 97 #define INTEL_GT_SYSFS_SHOW(_name, _attr_type) \ 98 static ssize_t _name##_show_common(struct kobject *kobj, \ 99 struct attribute *attr, char *buff) \ 100 { \ 101 u32 val = sysfs_gt_attribute_r_##_attr_type##_func(kobj, attr, \ 102 __##_name##_show); \ 103 \ 104 return sysfs_emit(buff, "%u\n", val); \ 105 } \ 106 static ssize_t _name##_show(struct kobject *kobj, \ 107 struct kobj_attribute *attr, char *buff) \ 108 { \ 109 return _name ##_show_common(kobj, &attr->attr, buff); \ 110 } \ 111 static ssize_t _name##_dev_show(struct device *dev, \ 112 struct device_attribute *attr, char *buff) \ 113 { \ 114 return _name##_show_common(&dev->kobj, &attr->attr, buff); \ 115 } 116 117 #define INTEL_GT_SYSFS_STORE(_name, _func) \ 118 static ssize_t _name##_store_common(struct kobject *kobj, \ 119 struct attribute *attr, \ 120 const char *buff, size_t count) \ 121 { \ 122 int ret; \ 123 u32 val; \ 124 \ 125 ret = kstrtou32(buff, 0, &val); \ 126 if (ret) \ 127 return ret; \ 128 \ 129 ret = sysfs_gt_attribute_w_func(kobj, attr, _func, val); \ 130 \ 131 return ret ?: count; \ 132 } \ 133 static ssize_t _name##_store(struct kobject *kobj, \ 134 struct kobj_attribute *attr, const char *buff, \ 135 size_t count) \ 136 { \ 137 return _name##_store_common(kobj, &attr->attr, buff, count); \ 138 } \ 139 static ssize_t _name##_dev_store(struct device *dev, \ 140 struct device_attribute *attr, \ 141 const char *buff, size_t count) \ 142 { \ 143 return _name##_store_common(&dev->kobj, &attr->attr, buff, count); \ 144 } 145 146 #define INTEL_GT_SYSFS_SHOW_MAX(_name) INTEL_GT_SYSFS_SHOW(_name, max) 147 #define INTEL_GT_SYSFS_SHOW_MIN(_name) INTEL_GT_SYSFS_SHOW(_name, min) 148 149 #define INTEL_GT_ATTR_RW(_name) \ 150 static struct kobj_attribute attr_##_name = __ATTR_RW(_name) 151 152 #define INTEL_GT_ATTR_RO(_name) \ 153 static struct kobj_attribute attr_##_name = __ATTR_RO(_name) 154 155 #define INTEL_GT_DUAL_ATTR_RW(_name) \ 156 static struct device_attribute dev_attr_##_name = __ATTR(_name, 0644, \ 157 _name##_dev_show, \ 158 _name##_dev_store); \ 159 INTEL_GT_ATTR_RW(_name) 160 161 #define INTEL_GT_DUAL_ATTR_RO(_name) \ 162 static struct device_attribute dev_attr_##_name = __ATTR(_name, 0444, \ 163 _name##_dev_show, \ 164 NULL); \ 165 INTEL_GT_ATTR_RO(_name) 166 167 #ifdef CONFIG_PM 168 static u32 get_residency(struct intel_gt *gt, i915_reg_t reg) 169 { 170 intel_wakeref_t wakeref; 171 u64 res = 0; 172 173 with_intel_runtime_pm(gt->uncore->rpm, wakeref) 174 res = intel_rc6_residency_us(>->rc6, reg); 175 176 return DIV_ROUND_CLOSEST_ULL(res, 1000); 177 } 178 179 static u8 get_rc6_mask(struct intel_gt *gt) 180 { 181 u8 mask = 0; 182 183 if (HAS_RC6(gt->i915)) 184 mask |= BIT(0); 185 if (HAS_RC6p(gt->i915)) 186 mask |= BIT(1); 187 if (HAS_RC6pp(gt->i915)) 188 mask |= BIT(2); 189 190 return mask; 191 } 192 193 static ssize_t rc6_enable_show(struct kobject *kobj, 194 struct kobj_attribute *attr, 195 char *buff) 196 { 197 struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); 198 199 return sysfs_emit(buff, "%x\n", get_rc6_mask(gt)); 200 } 201 202 static ssize_t rc6_enable_dev_show(struct device *dev, 203 struct device_attribute *attr, 204 char *buff) 205 { 206 struct intel_gt *gt = intel_gt_sysfs_get_drvdata(&dev->kobj, attr->attr.name); 207 208 return sysfs_emit(buff, "%x\n", get_rc6_mask(gt)); 209 } 210 211 static u32 __rc6_residency_ms_show(struct intel_gt *gt) 212 { 213 return get_residency(gt, GEN6_GT_GFX_RC6); 214 } 215 216 static u32 __rc6p_residency_ms_show(struct intel_gt *gt) 217 { 218 return get_residency(gt, GEN6_GT_GFX_RC6p); 219 } 220 221 static u32 __rc6pp_residency_ms_show(struct intel_gt *gt) 222 { 223 return get_residency(gt, GEN6_GT_GFX_RC6pp); 224 } 225 226 static u32 __media_rc6_residency_ms_show(struct intel_gt *gt) 227 { 228 return get_residency(gt, VLV_GT_MEDIA_RC6); 229 } 230 231 INTEL_GT_SYSFS_SHOW_MIN(rc6_residency_ms); 232 INTEL_GT_SYSFS_SHOW_MIN(rc6p_residency_ms); 233 INTEL_GT_SYSFS_SHOW_MIN(rc6pp_residency_ms); 234 INTEL_GT_SYSFS_SHOW_MIN(media_rc6_residency_ms); 235 236 INTEL_GT_DUAL_ATTR_RO(rc6_enable); 237 INTEL_GT_DUAL_ATTR_RO(rc6_residency_ms); 238 INTEL_GT_DUAL_ATTR_RO(rc6p_residency_ms); 239 INTEL_GT_DUAL_ATTR_RO(rc6pp_residency_ms); 240 INTEL_GT_DUAL_ATTR_RO(media_rc6_residency_ms); 241 242 static struct attribute *rc6_attrs[] = { 243 &attr_rc6_enable.attr, 244 &attr_rc6_residency_ms.attr, 245 NULL 246 }; 247 248 static struct attribute *rc6p_attrs[] = { 249 &attr_rc6p_residency_ms.attr, 250 &attr_rc6pp_residency_ms.attr, 251 NULL 252 }; 253 254 static struct attribute *media_rc6_attrs[] = { 255 &attr_media_rc6_residency_ms.attr, 256 NULL 257 }; 258 259 static struct attribute *rc6_dev_attrs[] = { 260 &dev_attr_rc6_enable.attr, 261 &dev_attr_rc6_residency_ms.attr, 262 NULL 263 }; 264 265 static struct attribute *rc6p_dev_attrs[] = { 266 &dev_attr_rc6p_residency_ms.attr, 267 &dev_attr_rc6pp_residency_ms.attr, 268 NULL 269 }; 270 271 static struct attribute *media_rc6_dev_attrs[] = { 272 &dev_attr_media_rc6_residency_ms.attr, 273 NULL 274 }; 275 276 static const struct attribute_group rc6_attr_group[] = { 277 { .attrs = rc6_attrs, }, 278 { .name = power_group_name, .attrs = rc6_dev_attrs, }, 279 }; 280 281 static const struct attribute_group rc6p_attr_group[] = { 282 { .attrs = rc6p_attrs, }, 283 { .name = power_group_name, .attrs = rc6p_dev_attrs, }, 284 }; 285 286 static const struct attribute_group media_rc6_attr_group[] = { 287 { .attrs = media_rc6_attrs, }, 288 { .name = power_group_name, .attrs = media_rc6_dev_attrs, }, 289 }; 290 291 static int __intel_gt_sysfs_create_group(struct kobject *kobj, 292 const struct attribute_group *grp) 293 { 294 return is_object_gt(kobj) ? 295 sysfs_create_group(kobj, &grp[0]) : 296 sysfs_merge_group(kobj, &grp[1]); 297 } 298 299 static void intel_sysfs_rc6_init(struct intel_gt *gt, struct kobject *kobj) 300 { 301 int ret; 302 303 if (!HAS_RC6(gt->i915)) 304 return; 305 306 ret = __intel_gt_sysfs_create_group(kobj, rc6_attr_group); 307 if (ret) 308 drm_warn(>->i915->drm, 309 "failed to create gt%u RC6 sysfs files (%pe)\n", 310 gt->info.id, ERR_PTR(ret)); 311 312 /* 313 * cannot use the is_visible() attribute because 314 * the upper object inherits from the parent group. 315 */ 316 if (HAS_RC6p(gt->i915)) { 317 ret = __intel_gt_sysfs_create_group(kobj, rc6p_attr_group); 318 if (ret) 319 drm_warn(>->i915->drm, 320 "failed to create gt%u RC6p sysfs files (%pe)\n", 321 gt->info.id, ERR_PTR(ret)); 322 } 323 324 if (IS_VALLEYVIEW(gt->i915) || IS_CHERRYVIEW(gt->i915)) { 325 ret = __intel_gt_sysfs_create_group(kobj, media_rc6_attr_group); 326 if (ret) 327 drm_warn(>->i915->drm, 328 "failed to create media %u RC6 sysfs files (%pe)\n", 329 gt->info.id, ERR_PTR(ret)); 330 } 331 } 332 #else 333 static void intel_sysfs_rc6_init(struct intel_gt *gt, struct kobject *kobj) 334 { 335 } 336 #endif /* CONFIG_PM */ 337 338 static u32 __act_freq_mhz_show(struct intel_gt *gt) 339 { 340 return intel_rps_read_actual_frequency(>->rps); 341 } 342 343 static u32 __cur_freq_mhz_show(struct intel_gt *gt) 344 { 345 return intel_rps_get_requested_frequency(>->rps); 346 } 347 348 static u32 __boost_freq_mhz_show(struct intel_gt *gt) 349 { 350 return intel_rps_get_boost_frequency(>->rps); 351 } 352 353 static int __boost_freq_mhz_store(struct intel_gt *gt, u32 val) 354 { 355 return intel_rps_set_boost_frequency(>->rps, val); 356 } 357 358 static u32 __RP0_freq_mhz_show(struct intel_gt *gt) 359 { 360 return intel_rps_get_rp0_frequency(>->rps); 361 } 362 363 static u32 __RPn_freq_mhz_show(struct intel_gt *gt) 364 { 365 return intel_rps_get_rpn_frequency(>->rps); 366 } 367 368 static u32 __RP1_freq_mhz_show(struct intel_gt *gt) 369 { 370 return intel_rps_get_rp1_frequency(>->rps); 371 } 372 373 static u32 __max_freq_mhz_show(struct intel_gt *gt) 374 { 375 return intel_rps_get_max_frequency(>->rps); 376 } 377 378 static int __set_max_freq(struct intel_gt *gt, u32 val) 379 { 380 return intel_rps_set_max_frequency(>->rps, val); 381 } 382 383 static u32 __min_freq_mhz_show(struct intel_gt *gt) 384 { 385 return intel_rps_get_min_frequency(>->rps); 386 } 387 388 static int __set_min_freq(struct intel_gt *gt, u32 val) 389 { 390 return intel_rps_set_min_frequency(>->rps, val); 391 } 392 393 static u32 __vlv_rpe_freq_mhz_show(struct intel_gt *gt) 394 { 395 struct intel_rps *rps = >->rps; 396 397 return intel_gpu_freq(rps, rps->efficient_freq); 398 } 399 400 INTEL_GT_SYSFS_SHOW_MAX(act_freq_mhz); 401 INTEL_GT_SYSFS_SHOW_MAX(boost_freq_mhz); 402 INTEL_GT_SYSFS_SHOW_MAX(cur_freq_mhz); 403 INTEL_GT_SYSFS_SHOW_MAX(RP0_freq_mhz); 404 INTEL_GT_SYSFS_SHOW_MAX(RP1_freq_mhz); 405 INTEL_GT_SYSFS_SHOW_MAX(RPn_freq_mhz); 406 INTEL_GT_SYSFS_SHOW_MAX(max_freq_mhz); 407 INTEL_GT_SYSFS_SHOW_MIN(min_freq_mhz); 408 INTEL_GT_SYSFS_SHOW_MAX(vlv_rpe_freq_mhz); 409 INTEL_GT_SYSFS_STORE(boost_freq_mhz, __boost_freq_mhz_store); 410 INTEL_GT_SYSFS_STORE(max_freq_mhz, __set_max_freq); 411 INTEL_GT_SYSFS_STORE(min_freq_mhz, __set_min_freq); 412 413 #define INTEL_GT_RPS_SYSFS_ATTR(_name, _mode, _show, _store, _show_dev, _store_dev) \ 414 static struct device_attribute dev_attr_gt_##_name = __ATTR(gt_##_name, _mode, \ 415 _show_dev, _store_dev); \ 416 static struct kobj_attribute attr_rps_##_name = __ATTR(rps_##_name, _mode, \ 417 _show, _store) 418 419 #define INTEL_GT_RPS_SYSFS_ATTR_RO(_name) \ 420 INTEL_GT_RPS_SYSFS_ATTR(_name, 0444, _name##_show, NULL, \ 421 _name##_dev_show, NULL) 422 #define INTEL_GT_RPS_SYSFS_ATTR_RW(_name) \ 423 INTEL_GT_RPS_SYSFS_ATTR(_name, 0644, _name##_show, _name##_store, \ 424 _name##_dev_show, _name##_dev_store) 425 426 /* The below macros generate static structures */ 427 INTEL_GT_RPS_SYSFS_ATTR_RO(act_freq_mhz); 428 INTEL_GT_RPS_SYSFS_ATTR_RO(cur_freq_mhz); 429 INTEL_GT_RPS_SYSFS_ATTR_RW(boost_freq_mhz); 430 INTEL_GT_RPS_SYSFS_ATTR_RO(RP0_freq_mhz); 431 INTEL_GT_RPS_SYSFS_ATTR_RO(RP1_freq_mhz); 432 INTEL_GT_RPS_SYSFS_ATTR_RO(RPn_freq_mhz); 433 INTEL_GT_RPS_SYSFS_ATTR_RW(max_freq_mhz); 434 INTEL_GT_RPS_SYSFS_ATTR_RW(min_freq_mhz); 435 INTEL_GT_RPS_SYSFS_ATTR_RO(vlv_rpe_freq_mhz); 436 437 #define GEN6_ATTR(p, s) { \ 438 &p##attr_##s##_act_freq_mhz.attr, \ 439 &p##attr_##s##_cur_freq_mhz.attr, \ 440 &p##attr_##s##_boost_freq_mhz.attr, \ 441 &p##attr_##s##_max_freq_mhz.attr, \ 442 &p##attr_##s##_min_freq_mhz.attr, \ 443 &p##attr_##s##_RP0_freq_mhz.attr, \ 444 &p##attr_##s##_RP1_freq_mhz.attr, \ 445 &p##attr_##s##_RPn_freq_mhz.attr, \ 446 NULL, \ 447 } 448 449 #define GEN6_RPS_ATTR GEN6_ATTR(, rps) 450 #define GEN6_GT_ATTR GEN6_ATTR(dev_, gt) 451 452 static const struct attribute * const gen6_rps_attrs[] = GEN6_RPS_ATTR; 453 static const struct attribute * const gen6_gt_attrs[] = GEN6_GT_ATTR; 454 455 static ssize_t punit_req_freq_mhz_show(struct kobject *kobj, 456 struct kobj_attribute *attr, 457 char *buff) 458 { 459 struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); 460 u32 preq = intel_rps_read_punit_req_frequency(>->rps); 461 462 return sysfs_emit(buff, "%u\n", preq); 463 } 464 465 struct intel_gt_bool_throttle_attr { 466 struct attribute attr; 467 ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, 468 char *buf); 469 i915_reg_t (*reg32)(struct intel_gt *gt); 470 u32 mask; 471 }; 472 473 static ssize_t throttle_reason_bool_show(struct kobject *kobj, 474 struct kobj_attribute *attr, 475 char *buff) 476 { 477 struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); 478 struct intel_gt_bool_throttle_attr *t_attr = 479 (struct intel_gt_bool_throttle_attr *) attr; 480 bool val = rps_read_mask_mmio(>->rps, t_attr->reg32(gt), t_attr->mask); 481 482 return sysfs_emit(buff, "%u\n", val); 483 } 484 485 #define INTEL_GT_RPS_BOOL_ATTR_RO(sysfs_func__, mask__) \ 486 struct intel_gt_bool_throttle_attr attr_##sysfs_func__ = { \ 487 .attr = { .name = __stringify(sysfs_func__), .mode = 0444 }, \ 488 .show = throttle_reason_bool_show, \ 489 .reg32 = intel_gt_perf_limit_reasons_reg, \ 490 .mask = mask__, \ 491 } 492 493 INTEL_GT_ATTR_RO(punit_req_freq_mhz); 494 static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_status, GT0_PERF_LIMIT_REASONS_MASK); 495 static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_pl1, POWER_LIMIT_1_MASK); 496 static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_pl2, POWER_LIMIT_2_MASK); 497 static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_pl4, POWER_LIMIT_4_MASK); 498 static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_thermal, THERMAL_LIMIT_MASK); 499 static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_prochot, PROCHOT_MASK); 500 static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_ratl, RATL_MASK); 501 static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_vr_thermalert, VR_THERMALERT_MASK); 502 static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_vr_tdc, VR_TDC_MASK); 503 504 static const struct attribute *throttle_reason_attrs[] = { 505 &attr_throttle_reason_status.attr, 506 &attr_throttle_reason_pl1.attr, 507 &attr_throttle_reason_pl2.attr, 508 &attr_throttle_reason_pl4.attr, 509 &attr_throttle_reason_thermal.attr, 510 &attr_throttle_reason_prochot.attr, 511 &attr_throttle_reason_ratl.attr, 512 &attr_throttle_reason_vr_thermalert.attr, 513 &attr_throttle_reason_vr_tdc.attr, 514 NULL 515 }; 516 517 /* 518 * Scaling for multipliers (aka frequency factors). 519 * The format of the value in the register is u8.8. 520 * 521 * The presentation to userspace is inspired by the perf event framework. 522 * See: 523 * Documentation/ABI/testing/sysfs-bus-event_source-devices-events 524 * for description of: 525 * /sys/bus/event_source/devices/<pmu>/events/<event>.scale 526 * 527 * Summary: Expose two sysfs files for each multiplier. 528 * 529 * 1. File <attr> contains a raw hardware value. 530 * 2. File <attr>.scale contains the multiplicative scale factor to be 531 * used by userspace to compute the actual value. 532 * 533 * So userspace knows that to get the frequency_factor it multiplies the 534 * provided value by the specified scale factor and vice-versa. 535 * 536 * That way there is no precision loss in the kernel interface and API 537 * is future proof should one day the hardware register change to u16.u16, 538 * on some platform. (Or any other fixed point representation.) 539 * 540 * Example: 541 * File <attr> contains the value 2.5, represented as u8.8 0x0280, which 542 * is comprised of: 543 * - an integer part of 2 544 * - a fractional part of 0x80 (representing 0x80 / 2^8 == 0x80 / 256). 545 * File <attr>.scale contains a string representation of floating point 546 * value 0.00390625 (which is (1 / 256)). 547 * Userspace computes the actual value: 548 * 0x0280 * 0.00390625 -> 2.5 549 * or converts an actual value to the value to be written into <attr>: 550 * 2.5 / 0.00390625 -> 0x0280 551 */ 552 553 #define U8_8_VAL_MASK 0xffff 554 #define U8_8_SCALE_TO_VALUE "0.00390625" 555 556 static ssize_t freq_factor_scale_show(struct kobject *kobj, 557 struct kobj_attribute *attr, 558 char *buff) 559 { 560 return sysfs_emit(buff, "%s\n", U8_8_SCALE_TO_VALUE); 561 } 562 563 static u32 media_ratio_mode_to_factor(u32 mode) 564 { 565 /* 0 -> 0, 1 -> 256, 2 -> 128 */ 566 return !mode ? mode : 256 / mode; 567 } 568 569 static ssize_t media_freq_factor_show(struct kobject *kobj, 570 struct kobj_attribute *attr, 571 char *buff) 572 { 573 struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); 574 struct intel_guc_slpc *slpc = >->uc.guc.slpc; 575 intel_wakeref_t wakeref; 576 u32 mode; 577 578 /* 579 * Retrieve media_ratio_mode from GEN6_RPNSWREQ bit 13 set by 580 * GuC. GEN6_RPNSWREQ:13 value 0 represents 1:2 and 1 represents 1:1 581 */ 582 if (IS_XEHPSDV(gt->i915) && 583 slpc->media_ratio_mode == SLPC_MEDIA_RATIO_MODE_DYNAMIC_CONTROL) { 584 /* 585 * For XEHPSDV dynamic mode GEN6_RPNSWREQ:13 does not contain 586 * the media_ratio_mode, just return the cached media ratio 587 */ 588 mode = slpc->media_ratio_mode; 589 } else { 590 with_intel_runtime_pm(gt->uncore->rpm, wakeref) 591 mode = intel_uncore_read(gt->uncore, GEN6_RPNSWREQ); 592 mode = REG_FIELD_GET(GEN12_MEDIA_FREQ_RATIO, mode) ? 593 SLPC_MEDIA_RATIO_MODE_FIXED_ONE_TO_ONE : 594 SLPC_MEDIA_RATIO_MODE_FIXED_ONE_TO_TWO; 595 } 596 597 return sysfs_emit(buff, "%u\n", media_ratio_mode_to_factor(mode)); 598 } 599 600 static ssize_t media_freq_factor_store(struct kobject *kobj, 601 struct kobj_attribute *attr, 602 const char *buff, size_t count) 603 { 604 struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); 605 struct intel_guc_slpc *slpc = >->uc.guc.slpc; 606 u32 factor, mode; 607 int err; 608 609 err = kstrtou32(buff, 0, &factor); 610 if (err) 611 return err; 612 613 for (mode = SLPC_MEDIA_RATIO_MODE_DYNAMIC_CONTROL; 614 mode <= SLPC_MEDIA_RATIO_MODE_FIXED_ONE_TO_TWO; mode++) 615 if (factor == media_ratio_mode_to_factor(mode)) 616 break; 617 618 if (mode > SLPC_MEDIA_RATIO_MODE_FIXED_ONE_TO_TWO) 619 return -EINVAL; 620 621 err = intel_guc_slpc_set_media_ratio_mode(slpc, mode); 622 if (!err) { 623 slpc->media_ratio_mode = mode; 624 DRM_DEBUG("Set slpc->media_ratio_mode to %d", mode); 625 } 626 return err ?: count; 627 } 628 629 static ssize_t media_RP0_freq_mhz_show(struct kobject *kobj, 630 struct kobj_attribute *attr, 631 char *buff) 632 { 633 struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); 634 u32 val; 635 int err; 636 637 err = snb_pcode_read_p(gt->uncore, XEHP_PCODE_FREQUENCY_CONFIG, 638 PCODE_MBOX_FC_SC_READ_FUSED_P0, 639 PCODE_MBOX_DOMAIN_MEDIAFF, &val); 640 641 if (err) 642 return err; 643 644 /* Fused media RP0 read from pcode is in units of 50 MHz */ 645 val *= GT_FREQUENCY_MULTIPLIER; 646 647 return sysfs_emit(buff, "%u\n", val); 648 } 649 650 static ssize_t media_RPn_freq_mhz_show(struct kobject *kobj, 651 struct kobj_attribute *attr, 652 char *buff) 653 { 654 struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name); 655 u32 val; 656 int err; 657 658 err = snb_pcode_read_p(gt->uncore, XEHP_PCODE_FREQUENCY_CONFIG, 659 PCODE_MBOX_FC_SC_READ_FUSED_PN, 660 PCODE_MBOX_DOMAIN_MEDIAFF, &val); 661 662 if (err) 663 return err; 664 665 /* Fused media RPn read from pcode is in units of 50 MHz */ 666 val *= GT_FREQUENCY_MULTIPLIER; 667 668 return sysfs_emit(buff, "%u\n", val); 669 } 670 671 INTEL_GT_ATTR_RW(media_freq_factor); 672 static struct kobj_attribute attr_media_freq_factor_scale = 673 __ATTR(media_freq_factor.scale, 0444, freq_factor_scale_show, NULL); 674 INTEL_GT_ATTR_RO(media_RP0_freq_mhz); 675 INTEL_GT_ATTR_RO(media_RPn_freq_mhz); 676 677 static const struct attribute *media_perf_power_attrs[] = { 678 &attr_media_freq_factor.attr, 679 &attr_media_freq_factor_scale.attr, 680 &attr_media_RP0_freq_mhz.attr, 681 &attr_media_RPn_freq_mhz.attr, 682 NULL 683 }; 684 685 static ssize_t 686 default_min_freq_mhz_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) 687 { 688 struct intel_gt *gt = kobj_to_gt(kobj->parent); 689 690 return sysfs_emit(buf, "%u\n", gt->defaults.min_freq); 691 } 692 693 static struct kobj_attribute default_min_freq_mhz = 694 __ATTR(rps_min_freq_mhz, 0444, default_min_freq_mhz_show, NULL); 695 696 static ssize_t 697 default_max_freq_mhz_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) 698 { 699 struct intel_gt *gt = kobj_to_gt(kobj->parent); 700 701 return sysfs_emit(buf, "%u\n", gt->defaults.max_freq); 702 } 703 704 static struct kobj_attribute default_max_freq_mhz = 705 __ATTR(rps_max_freq_mhz, 0444, default_max_freq_mhz_show, NULL); 706 707 static const struct attribute * const rps_defaults_attrs[] = { 708 &default_min_freq_mhz.attr, 709 &default_max_freq_mhz.attr, 710 NULL 711 }; 712 713 static int intel_sysfs_rps_init(struct intel_gt *gt, struct kobject *kobj) 714 { 715 const struct attribute * const *attrs; 716 struct attribute *vlv_attr; 717 int ret; 718 719 if (GRAPHICS_VER(gt->i915) < 6) 720 return 0; 721 722 if (is_object_gt(kobj)) { 723 attrs = gen6_rps_attrs; 724 vlv_attr = &attr_rps_vlv_rpe_freq_mhz.attr; 725 } else { 726 attrs = gen6_gt_attrs; 727 vlv_attr = &dev_attr_gt_vlv_rpe_freq_mhz.attr; 728 } 729 730 ret = sysfs_create_files(kobj, attrs); 731 if (ret) 732 return ret; 733 734 if (IS_VALLEYVIEW(gt->i915) || IS_CHERRYVIEW(gt->i915)) 735 ret = sysfs_create_file(kobj, vlv_attr); 736 737 return ret; 738 } 739 740 void intel_gt_sysfs_pm_init(struct intel_gt *gt, struct kobject *kobj) 741 { 742 int ret; 743 744 intel_sysfs_rc6_init(gt, kobj); 745 746 ret = intel_sysfs_rps_init(gt, kobj); 747 if (ret) 748 drm_warn(>->i915->drm, 749 "failed to create gt%u RPS sysfs files (%pe)", 750 gt->info.id, ERR_PTR(ret)); 751 752 /* end of the legacy interfaces */ 753 if (!is_object_gt(kobj)) 754 return; 755 756 ret = sysfs_create_file(kobj, &attr_punit_req_freq_mhz.attr); 757 if (ret) 758 drm_warn(>->i915->drm, 759 "failed to create gt%u punit_req_freq_mhz sysfs (%pe)", 760 gt->info.id, ERR_PTR(ret)); 761 762 if (i915_mmio_reg_valid(intel_gt_perf_limit_reasons_reg(gt))) { 763 ret = sysfs_create_files(kobj, throttle_reason_attrs); 764 if (ret) 765 drm_warn(>->i915->drm, 766 "failed to create gt%u throttle sysfs files (%pe)", 767 gt->info.id, ERR_PTR(ret)); 768 } 769 770 if (HAS_MEDIA_RATIO_MODE(gt->i915) && intel_uc_uses_guc_slpc(>->uc)) { 771 ret = sysfs_create_files(kobj, media_perf_power_attrs); 772 if (ret) 773 drm_warn(>->i915->drm, 774 "failed to create gt%u media_perf_power_attrs sysfs (%pe)\n", 775 gt->info.id, ERR_PTR(ret)); 776 } 777 778 ret = sysfs_create_files(gt->sysfs_defaults, rps_defaults_attrs); 779 if (ret) 780 drm_warn(>->i915->drm, 781 "failed to add gt%u rps defaults (%pe)\n", 782 gt->info.id, ERR_PTR(ret)); 783 } 784