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