cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

intel_gt_sysfs_pm.c (15586B)


      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_rc6.h"
     18#include "intel_rps.h"
     19
     20enum intel_gt_sysfs_op {
     21	INTEL_GT_SYSFS_MIN = 0,
     22	INTEL_GT_SYSFS_MAX,
     23};
     24
     25static int
     26sysfs_gt_attribute_w_func(struct device *dev, struct device_attribute *attr,
     27			  int (func)(struct intel_gt *gt, u32 val), u32 val)
     28{
     29	struct intel_gt *gt;
     30	int ret;
     31
     32	if (!is_object_gt(&dev->kobj)) {
     33		int i;
     34		struct drm_i915_private *i915 = kdev_minor_to_i915(dev);
     35
     36		for_each_gt(gt, i915, i) {
     37			ret = func(gt, val);
     38			if (ret)
     39				break;
     40		}
     41	} else {
     42		gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name);
     43		ret = func(gt, val);
     44	}
     45
     46	return ret;
     47}
     48
     49static u32
     50sysfs_gt_attribute_r_func(struct device *dev, struct device_attribute *attr,
     51			  u32 (func)(struct intel_gt *gt),
     52			  enum intel_gt_sysfs_op op)
     53{
     54	struct intel_gt *gt;
     55	u32 ret;
     56
     57	ret = (op == INTEL_GT_SYSFS_MAX) ? 0 : (u32) -1;
     58
     59	if (!is_object_gt(&dev->kobj)) {
     60		int i;
     61		struct drm_i915_private *i915 = kdev_minor_to_i915(dev);
     62
     63		for_each_gt(gt, i915, i) {
     64			u32 val = func(gt);
     65
     66			switch (op) {
     67			case INTEL_GT_SYSFS_MIN:
     68				if (val < ret)
     69					ret = val;
     70				break;
     71
     72			case INTEL_GT_SYSFS_MAX:
     73				if (val > ret)
     74					ret = val;
     75				break;
     76			}
     77		}
     78	} else {
     79		gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name);
     80		ret = func(gt);
     81	}
     82
     83	return ret;
     84}
     85
     86/* RC6 interfaces will show the minimum RC6 residency value */
     87#define sysfs_gt_attribute_r_min_func(d, a, f) \
     88		sysfs_gt_attribute_r_func(d, a, f, INTEL_GT_SYSFS_MIN)
     89
     90/* Frequency interfaces will show the maximum frequency value */
     91#define sysfs_gt_attribute_r_max_func(d, a, f) \
     92		sysfs_gt_attribute_r_func(d, a, f, INTEL_GT_SYSFS_MAX)
     93
     94#ifdef CONFIG_PM
     95static u32 get_residency(struct intel_gt *gt, i915_reg_t reg)
     96{
     97	intel_wakeref_t wakeref;
     98	u64 res = 0;
     99
    100	with_intel_runtime_pm(gt->uncore->rpm, wakeref)
    101		res = intel_rc6_residency_us(&gt->rc6, reg);
    102
    103	return DIV_ROUND_CLOSEST_ULL(res, 1000);
    104}
    105
    106static ssize_t rc6_enable_show(struct device *dev,
    107			       struct device_attribute *attr,
    108			       char *buff)
    109{
    110	struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name);
    111	u8 mask = 0;
    112
    113	if (HAS_RC6(gt->i915))
    114		mask |= BIT(0);
    115	if (HAS_RC6p(gt->i915))
    116		mask |= BIT(1);
    117	if (HAS_RC6pp(gt->i915))
    118		mask |= BIT(2);
    119
    120	return sysfs_emit(buff, "%x\n", mask);
    121}
    122
    123static u32 __rc6_residency_ms_show(struct intel_gt *gt)
    124{
    125	return get_residency(gt, GEN6_GT_GFX_RC6);
    126}
    127
    128static ssize_t rc6_residency_ms_show(struct device *dev,
    129				     struct device_attribute *attr,
    130				     char *buff)
    131{
    132	u32 rc6_residency = sysfs_gt_attribute_r_min_func(dev, attr,
    133						      __rc6_residency_ms_show);
    134
    135	return sysfs_emit(buff, "%u\n", rc6_residency);
    136}
    137
    138static u32 __rc6p_residency_ms_show(struct intel_gt *gt)
    139{
    140	return get_residency(gt, GEN6_GT_GFX_RC6p);
    141}
    142
    143static ssize_t rc6p_residency_ms_show(struct device *dev,
    144				      struct device_attribute *attr,
    145				      char *buff)
    146{
    147	u32 rc6p_residency = sysfs_gt_attribute_r_min_func(dev, attr,
    148						__rc6p_residency_ms_show);
    149
    150	return sysfs_emit(buff, "%u\n", rc6p_residency);
    151}
    152
    153static u32 __rc6pp_residency_ms_show(struct intel_gt *gt)
    154{
    155	return get_residency(gt, GEN6_GT_GFX_RC6pp);
    156}
    157
    158static ssize_t rc6pp_residency_ms_show(struct device *dev,
    159				       struct device_attribute *attr,
    160				       char *buff)
    161{
    162	u32 rc6pp_residency = sysfs_gt_attribute_r_min_func(dev, attr,
    163						__rc6pp_residency_ms_show);
    164
    165	return sysfs_emit(buff, "%u\n", rc6pp_residency);
    166}
    167
    168static u32 __media_rc6_residency_ms_show(struct intel_gt *gt)
    169{
    170	return get_residency(gt, VLV_GT_MEDIA_RC6);
    171}
    172
    173static ssize_t media_rc6_residency_ms_show(struct device *dev,
    174					   struct device_attribute *attr,
    175					   char *buff)
    176{
    177	u32 rc6_residency = sysfs_gt_attribute_r_min_func(dev, attr,
    178						__media_rc6_residency_ms_show);
    179
    180	return sysfs_emit(buff, "%u\n", rc6_residency);
    181}
    182
    183static DEVICE_ATTR_RO(rc6_enable);
    184static DEVICE_ATTR_RO(rc6_residency_ms);
    185static DEVICE_ATTR_RO(rc6p_residency_ms);
    186static DEVICE_ATTR_RO(rc6pp_residency_ms);
    187static DEVICE_ATTR_RO(media_rc6_residency_ms);
    188
    189static struct attribute *rc6_attrs[] = {
    190	&dev_attr_rc6_enable.attr,
    191	&dev_attr_rc6_residency_ms.attr,
    192	NULL
    193};
    194
    195static struct attribute *rc6p_attrs[] = {
    196	&dev_attr_rc6p_residency_ms.attr,
    197	&dev_attr_rc6pp_residency_ms.attr,
    198	NULL
    199};
    200
    201static struct attribute *media_rc6_attrs[] = {
    202	&dev_attr_media_rc6_residency_ms.attr,
    203	NULL
    204};
    205
    206static const struct attribute_group rc6_attr_group[] = {
    207	{ .attrs = rc6_attrs, },
    208	{ .name = power_group_name, .attrs = rc6_attrs, },
    209};
    210
    211static const struct attribute_group rc6p_attr_group[] = {
    212	{ .attrs = rc6p_attrs, },
    213	{ .name = power_group_name, .attrs = rc6p_attrs, },
    214};
    215
    216static const struct attribute_group media_rc6_attr_group[] = {
    217	{ .attrs = media_rc6_attrs, },
    218	{ .name = power_group_name, .attrs = media_rc6_attrs, },
    219};
    220
    221static int __intel_gt_sysfs_create_group(struct kobject *kobj,
    222					 const struct attribute_group *grp)
    223{
    224	return is_object_gt(kobj) ?
    225	       sysfs_create_group(kobj, &grp[0]) :
    226	       sysfs_merge_group(kobj, &grp[1]);
    227}
    228
    229static void intel_sysfs_rc6_init(struct intel_gt *gt, struct kobject *kobj)
    230{
    231	int ret;
    232
    233	if (!HAS_RC6(gt->i915))
    234		return;
    235
    236	ret = __intel_gt_sysfs_create_group(kobj, rc6_attr_group);
    237	if (ret)
    238		drm_warn(&gt->i915->drm,
    239			 "failed to create gt%u RC6 sysfs files (%pe)\n",
    240			 gt->info.id, ERR_PTR(ret));
    241
    242	/*
    243	 * cannot use the is_visible() attribute because
    244	 * the upper object inherits from the parent group.
    245	 */
    246	if (HAS_RC6p(gt->i915)) {
    247		ret = __intel_gt_sysfs_create_group(kobj, rc6p_attr_group);
    248		if (ret)
    249			drm_warn(&gt->i915->drm,
    250				 "failed to create gt%u RC6p sysfs files (%pe)\n",
    251				 gt->info.id, ERR_PTR(ret));
    252	}
    253
    254	if (IS_VALLEYVIEW(gt->i915) || IS_CHERRYVIEW(gt->i915)) {
    255		ret = __intel_gt_sysfs_create_group(kobj, media_rc6_attr_group);
    256		if (ret)
    257			drm_warn(&gt->i915->drm,
    258				 "failed to create media %u RC6 sysfs files (%pe)\n",
    259				 gt->info.id, ERR_PTR(ret));
    260	}
    261}
    262#else
    263static void intel_sysfs_rc6_init(struct intel_gt *gt, struct kobject *kobj)
    264{
    265}
    266#endif /* CONFIG_PM */
    267
    268static u32 __act_freq_mhz_show(struct intel_gt *gt)
    269{
    270	return intel_rps_read_actual_frequency(&gt->rps);
    271}
    272
    273static ssize_t act_freq_mhz_show(struct device *dev,
    274				 struct device_attribute *attr, char *buff)
    275{
    276	u32 actual_freq = sysfs_gt_attribute_r_max_func(dev, attr,
    277						    __act_freq_mhz_show);
    278
    279	return sysfs_emit(buff, "%u\n", actual_freq);
    280}
    281
    282static u32 __cur_freq_mhz_show(struct intel_gt *gt)
    283{
    284	return intel_rps_get_requested_frequency(&gt->rps);
    285}
    286
    287static ssize_t cur_freq_mhz_show(struct device *dev,
    288				 struct device_attribute *attr, char *buff)
    289{
    290	u32 cur_freq = sysfs_gt_attribute_r_max_func(dev, attr,
    291						 __cur_freq_mhz_show);
    292
    293	return sysfs_emit(buff, "%u\n", cur_freq);
    294}
    295
    296static u32 __boost_freq_mhz_show(struct intel_gt *gt)
    297{
    298	return intel_rps_get_boost_frequency(&gt->rps);
    299}
    300
    301static ssize_t boost_freq_mhz_show(struct device *dev,
    302				   struct device_attribute *attr,
    303				   char *buff)
    304{
    305	u32 boost_freq = sysfs_gt_attribute_r_max_func(dev, attr,
    306						   __boost_freq_mhz_show);
    307
    308	return sysfs_emit(buff, "%u\n", boost_freq);
    309}
    310
    311static int __boost_freq_mhz_store(struct intel_gt *gt, u32 val)
    312{
    313	return intel_rps_set_boost_frequency(&gt->rps, val);
    314}
    315
    316static ssize_t boost_freq_mhz_store(struct device *dev,
    317				    struct device_attribute *attr,
    318				    const char *buff, size_t count)
    319{
    320	ssize_t ret;
    321	u32 val;
    322
    323	ret = kstrtou32(buff, 0, &val);
    324	if (ret)
    325		return ret;
    326
    327	return sysfs_gt_attribute_w_func(dev, attr,
    328					 __boost_freq_mhz_store, val) ?: count;
    329}
    330
    331static u32 __rp0_freq_mhz_show(struct intel_gt *gt)
    332{
    333	return intel_rps_get_rp0_frequency(&gt->rps);
    334}
    335
    336static ssize_t RP0_freq_mhz_show(struct device *dev,
    337				 struct device_attribute *attr, char *buff)
    338{
    339	u32 rp0_freq = sysfs_gt_attribute_r_max_func(dev, attr,
    340						     __rp0_freq_mhz_show);
    341
    342	return sysfs_emit(buff, "%u\n", rp0_freq);
    343}
    344
    345static u32 __rp1_freq_mhz_show(struct intel_gt *gt)
    346{
    347	return intel_rps_get_rp1_frequency(&gt->rps);
    348}
    349
    350static ssize_t RP1_freq_mhz_show(struct device *dev,
    351				 struct device_attribute *attr, char *buff)
    352{
    353	u32 rp1_freq = sysfs_gt_attribute_r_max_func(dev, attr,
    354						     __rp1_freq_mhz_show);
    355
    356	return sysfs_emit(buff, "%u\n", rp1_freq);
    357}
    358
    359static u32 __rpn_freq_mhz_show(struct intel_gt *gt)
    360{
    361	return intel_rps_get_rpn_frequency(&gt->rps);
    362}
    363
    364static ssize_t RPn_freq_mhz_show(struct device *dev,
    365				 struct device_attribute *attr, char *buff)
    366{
    367	u32 rpn_freq = sysfs_gt_attribute_r_max_func(dev, attr,
    368						     __rpn_freq_mhz_show);
    369
    370	return sysfs_emit(buff, "%u\n", rpn_freq);
    371}
    372
    373static u32 __max_freq_mhz_show(struct intel_gt *gt)
    374{
    375	return intel_rps_get_max_frequency(&gt->rps);
    376}
    377
    378static ssize_t max_freq_mhz_show(struct device *dev,
    379				 struct device_attribute *attr, char *buff)
    380{
    381	u32 max_freq = sysfs_gt_attribute_r_max_func(dev, attr,
    382						     __max_freq_mhz_show);
    383
    384	return sysfs_emit(buff, "%u\n", max_freq);
    385}
    386
    387static int __set_max_freq(struct intel_gt *gt, u32 val)
    388{
    389	return intel_rps_set_max_frequency(&gt->rps, val);
    390}
    391
    392static ssize_t max_freq_mhz_store(struct device *dev,
    393				  struct device_attribute *attr,
    394				  const char *buff, size_t count)
    395{
    396	int ret;
    397	u32 val;
    398
    399	ret = kstrtou32(buff, 0, &val);
    400	if (ret)
    401		return ret;
    402
    403	ret = sysfs_gt_attribute_w_func(dev, attr, __set_max_freq, val);
    404
    405	return ret ?: count;
    406}
    407
    408static u32 __min_freq_mhz_show(struct intel_gt *gt)
    409{
    410	return intel_rps_get_min_frequency(&gt->rps);
    411}
    412
    413static ssize_t min_freq_mhz_show(struct device *dev,
    414				 struct device_attribute *attr, char *buff)
    415{
    416	u32 min_freq = sysfs_gt_attribute_r_min_func(dev, attr,
    417						     __min_freq_mhz_show);
    418
    419	return sysfs_emit(buff, "%u\n", min_freq);
    420}
    421
    422static int __set_min_freq(struct intel_gt *gt, u32 val)
    423{
    424	return intel_rps_set_min_frequency(&gt->rps, val);
    425}
    426
    427static ssize_t min_freq_mhz_store(struct device *dev,
    428				  struct device_attribute *attr,
    429				  const char *buff, size_t count)
    430{
    431	int ret;
    432	u32 val;
    433
    434	ret = kstrtou32(buff, 0, &val);
    435	if (ret)
    436		return ret;
    437
    438	ret = sysfs_gt_attribute_w_func(dev, attr, __set_min_freq, val);
    439
    440	return ret ?: count;
    441}
    442
    443static u32 __vlv_rpe_freq_mhz_show(struct intel_gt *gt)
    444{
    445	struct intel_rps *rps = &gt->rps;
    446
    447	return intel_gpu_freq(rps, rps->efficient_freq);
    448}
    449
    450static ssize_t vlv_rpe_freq_mhz_show(struct device *dev,
    451				     struct device_attribute *attr, char *buff)
    452{
    453	u32 rpe_freq = sysfs_gt_attribute_r_max_func(dev, attr,
    454						 __vlv_rpe_freq_mhz_show);
    455
    456	return sysfs_emit(buff, "%u\n", rpe_freq);
    457}
    458
    459#define INTEL_GT_RPS_SYSFS_ATTR(_name, _mode, _show, _store) \
    460	static struct device_attribute dev_attr_gt_##_name = __ATTR(gt_##_name, _mode, _show, _store); \
    461	static struct device_attribute dev_attr_rps_##_name = __ATTR(rps_##_name, _mode, _show, _store)
    462
    463#define INTEL_GT_RPS_SYSFS_ATTR_RO(_name)				\
    464		INTEL_GT_RPS_SYSFS_ATTR(_name, 0444, _name##_show, NULL)
    465#define INTEL_GT_RPS_SYSFS_ATTR_RW(_name)				\
    466		INTEL_GT_RPS_SYSFS_ATTR(_name, 0644, _name##_show, _name##_store)
    467
    468/* The below macros generate static structures */
    469INTEL_GT_RPS_SYSFS_ATTR_RO(act_freq_mhz);
    470INTEL_GT_RPS_SYSFS_ATTR_RO(cur_freq_mhz);
    471INTEL_GT_RPS_SYSFS_ATTR_RW(boost_freq_mhz);
    472INTEL_GT_RPS_SYSFS_ATTR_RO(RP0_freq_mhz);
    473INTEL_GT_RPS_SYSFS_ATTR_RO(RP1_freq_mhz);
    474INTEL_GT_RPS_SYSFS_ATTR_RO(RPn_freq_mhz);
    475INTEL_GT_RPS_SYSFS_ATTR_RW(max_freq_mhz);
    476INTEL_GT_RPS_SYSFS_ATTR_RW(min_freq_mhz);
    477
    478static DEVICE_ATTR_RO(vlv_rpe_freq_mhz);
    479
    480#define GEN6_ATTR(s) { \
    481		&dev_attr_##s##_act_freq_mhz.attr, \
    482		&dev_attr_##s##_cur_freq_mhz.attr, \
    483		&dev_attr_##s##_boost_freq_mhz.attr, \
    484		&dev_attr_##s##_max_freq_mhz.attr, \
    485		&dev_attr_##s##_min_freq_mhz.attr, \
    486		&dev_attr_##s##_RP0_freq_mhz.attr, \
    487		&dev_attr_##s##_RP1_freq_mhz.attr, \
    488		&dev_attr_##s##_RPn_freq_mhz.attr, \
    489		NULL, \
    490	}
    491
    492#define GEN6_RPS_ATTR GEN6_ATTR(rps)
    493#define GEN6_GT_ATTR  GEN6_ATTR(gt)
    494
    495static const struct attribute * const gen6_rps_attrs[] = GEN6_RPS_ATTR;
    496static const struct attribute * const gen6_gt_attrs[]  = GEN6_GT_ATTR;
    497
    498static ssize_t punit_req_freq_mhz_show(struct device *dev,
    499				       struct device_attribute *attr,
    500				       char *buff)
    501{
    502	struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name);
    503	u32 preq = intel_rps_read_punit_req_frequency(&gt->rps);
    504
    505	return sysfs_emit(buff, "%u\n", preq);
    506}
    507
    508struct intel_gt_bool_throttle_attr {
    509	struct attribute attr;
    510	ssize_t (*show)(struct device *dev, struct device_attribute *attr,
    511			char *buf);
    512	i915_reg_t reg32;
    513	u32 mask;
    514};
    515
    516static ssize_t throttle_reason_bool_show(struct device *dev,
    517					 struct device_attribute *attr,
    518					 char *buff)
    519{
    520	struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, 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(&gt->rps, t_attr->reg32, 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__) \
    529struct intel_gt_bool_throttle_attr attr_##sysfs_func__ = { \
    530	.attr = { .name = __stringify(sysfs_func__), .mode = 0444 }, \
    531	.show = throttle_reason_bool_show, \
    532	.reg32 = GT0_PERF_LIMIT_REASONS, \
    533	.mask = mask__, \
    534}
    535
    536static DEVICE_ATTR_RO(punit_req_freq_mhz);
    537static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_status, GT0_PERF_LIMIT_REASONS_MASK);
    538static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_pl1, POWER_LIMIT_1_MASK);
    539static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_pl2, POWER_LIMIT_2_MASK);
    540static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_pl4, POWER_LIMIT_4_MASK);
    541static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_thermal, THERMAL_LIMIT_MASK);
    542static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_prochot, PROCHOT_MASK);
    543static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_ratl, RATL_MASK);
    544static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_vr_thermalert, VR_THERMALERT_MASK);
    545static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_vr_tdc, VR_TDC_MASK);
    546
    547static const struct attribute *freq_attrs[] = {
    548	&dev_attr_punit_req_freq_mhz.attr,
    549	&attr_throttle_reason_status.attr,
    550	&attr_throttle_reason_pl1.attr,
    551	&attr_throttle_reason_pl2.attr,
    552	&attr_throttle_reason_pl4.attr,
    553	&attr_throttle_reason_thermal.attr,
    554	&attr_throttle_reason_prochot.attr,
    555	&attr_throttle_reason_ratl.attr,
    556	&attr_throttle_reason_vr_thermalert.attr,
    557	&attr_throttle_reason_vr_tdc.attr,
    558	NULL
    559};
    560
    561static int intel_sysfs_rps_init(struct intel_gt *gt, struct kobject *kobj,
    562				const struct attribute * const *attrs)
    563{
    564	int ret;
    565
    566	if (GRAPHICS_VER(gt->i915) < 6)
    567		return 0;
    568
    569	ret = sysfs_create_files(kobj, attrs);
    570	if (ret)
    571		return ret;
    572
    573	if (IS_VALLEYVIEW(gt->i915) || IS_CHERRYVIEW(gt->i915))
    574		ret = sysfs_create_file(kobj, &dev_attr_vlv_rpe_freq_mhz.attr);
    575
    576	return ret;
    577}
    578
    579void intel_gt_sysfs_pm_init(struct intel_gt *gt, struct kobject *kobj)
    580{
    581	int ret;
    582
    583	intel_sysfs_rc6_init(gt, kobj);
    584
    585	ret = is_object_gt(kobj) ?
    586	      intel_sysfs_rps_init(gt, kobj, gen6_rps_attrs) :
    587	      intel_sysfs_rps_init(gt, kobj, gen6_gt_attrs);
    588	if (ret)
    589		drm_warn(&gt->i915->drm,
    590			 "failed to create gt%u RPS sysfs files (%pe)",
    591			 gt->info.id, ERR_PTR(ret));
    592
    593	/* end of the legacy interfaces */
    594	if (!is_object_gt(kobj))
    595		return;
    596
    597	ret = sysfs_create_files(kobj, freq_attrs);
    598	if (ret)
    599		drm_warn(&gt->i915->drm,
    600			 "failed to create gt%u throttle sysfs files (%pe)",
    601			 gt->info.id, ERR_PTR(ret));
    602}