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