Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.2.
  1// SPDX-License-Identifier: MIT
  2/*
  3 * Copyright © 2023 Intel Corporation
  4 */
  5
  6#include <drm/drm_managed.h>
  7
  8#include <regs/xe_gt_regs.h>
  9#include "xe_device.h"
 10#include "xe_gt.h"
 11#include "xe_gt_sysfs.h"
 12#include "xe_gt_throttle.h"
 13#include "xe_mmio.h"
 14#include "xe_pm.h"
 15
 16/**
 17 * DOC: Xe GT Throttle
 18 *
 19 * Provides sysfs entries and other helpers for frequency throttle reasons in GT
 20 *
 21 * device/gt#/freq0/throttle/status - Overall status
 22 * device/gt#/freq0/throttle/reason_pl1 - Frequency throttle due to PL1
 23 * device/gt#/freq0/throttle/reason_pl2 - Frequency throttle due to PL2
 24 * device/gt#/freq0/throttle/reason_pl4 - Frequency throttle due to PL4, Iccmax etc.
 25 * device/gt#/freq0/throttle/reason_thermal - Frequency throttle due to thermal
 26 * device/gt#/freq0/throttle/reason_prochot - Frequency throttle due to prochot
 27 * device/gt#/freq0/throttle/reason_ratl - Frequency throttle due to RATL
 28 * device/gt#/freq0/throttle/reason_vr_thermalert - Frequency throttle due to VR THERMALERT
 29 * device/gt#/freq0/throttle/reason_vr_tdc -  Frequency throttle due to VR TDC
 30 */
 31
 32static struct xe_gt *
 33dev_to_gt(struct device *dev)
 34{
 35	return kobj_to_gt(dev->kobj.parent);
 36}
 37
 38u32 xe_gt_throttle_get_limit_reasons(struct xe_gt *gt)
 39{
 40	u32 reg;
 41
 42	xe_pm_runtime_get(gt_to_xe(gt));
 43	if (xe_gt_is_media_type(gt))
 44		reg = xe_mmio_read32(&gt->mmio, MTL_MEDIA_PERF_LIMIT_REASONS);
 45	else
 46		reg = xe_mmio_read32(&gt->mmio, GT0_PERF_LIMIT_REASONS);
 47	xe_pm_runtime_put(gt_to_xe(gt));
 48
 49	return reg;
 50}
 51
 52static u32 read_status(struct xe_gt *gt)
 53{
 54	u32 status = xe_gt_throttle_get_limit_reasons(gt) & GT0_PERF_LIMIT_REASONS_MASK;
 55
 56	return status;
 57}
 58
 59static u32 read_reason_pl1(struct xe_gt *gt)
 60{
 61	u32 pl1 = xe_gt_throttle_get_limit_reasons(gt) & POWER_LIMIT_1_MASK;
 62
 63	return pl1;
 64}
 65
 66static u32 read_reason_pl2(struct xe_gt *gt)
 67{
 68	u32 pl2 = xe_gt_throttle_get_limit_reasons(gt) & POWER_LIMIT_2_MASK;
 69
 70	return pl2;
 71}
 72
 73static u32 read_reason_pl4(struct xe_gt *gt)
 74{
 75	u32 pl4 = xe_gt_throttle_get_limit_reasons(gt) & POWER_LIMIT_4_MASK;
 76
 77	return pl4;
 78}
 79
 80static u32 read_reason_thermal(struct xe_gt *gt)
 81{
 82	u32 thermal = xe_gt_throttle_get_limit_reasons(gt) & THERMAL_LIMIT_MASK;
 83
 84	return thermal;
 85}
 86
 87static u32 read_reason_prochot(struct xe_gt *gt)
 88{
 89	u32 prochot = xe_gt_throttle_get_limit_reasons(gt) & PROCHOT_MASK;
 90
 91	return prochot;
 92}
 93
 94static u32 read_reason_ratl(struct xe_gt *gt)
 95{
 96	u32 ratl = xe_gt_throttle_get_limit_reasons(gt) & RATL_MASK;
 97
 98	return ratl;
 99}
100
101static u32 read_reason_vr_thermalert(struct xe_gt *gt)
102{
103	u32 thermalert = xe_gt_throttle_get_limit_reasons(gt) & VR_THERMALERT_MASK;
104
105	return thermalert;
106}
107
108static u32 read_reason_vr_tdc(struct xe_gt *gt)
109{
110	u32 tdc = xe_gt_throttle_get_limit_reasons(gt) & VR_TDC_MASK;
111
112	return tdc;
113}
114
115static ssize_t status_show(struct device *dev,
116			   struct device_attribute *attr,
117			   char *buff)
118{
119	struct xe_gt *gt = dev_to_gt(dev);
120	bool status = !!read_status(gt);
121
122	return sysfs_emit(buff, "%u\n", status);
123}
124static DEVICE_ATTR_RO(status);
125
126static ssize_t reason_pl1_show(struct device *dev,
127			       struct device_attribute *attr,
128			       char *buff)
129{
130	struct xe_gt *gt = dev_to_gt(dev);
131	bool pl1 = !!read_reason_pl1(gt);
132
133	return sysfs_emit(buff, "%u\n", pl1);
134}
135static DEVICE_ATTR_RO(reason_pl1);
136
137static ssize_t reason_pl2_show(struct device *dev,
138			       struct device_attribute *attr,
139			       char *buff)
140{
141	struct xe_gt *gt = dev_to_gt(dev);
142	bool pl2 = !!read_reason_pl2(gt);
143
144	return sysfs_emit(buff, "%u\n", pl2);
145}
146static DEVICE_ATTR_RO(reason_pl2);
147
148static ssize_t reason_pl4_show(struct device *dev,
149			       struct device_attribute *attr,
150			       char *buff)
151{
152	struct xe_gt *gt = dev_to_gt(dev);
153	bool pl4 = !!read_reason_pl4(gt);
154
155	return sysfs_emit(buff, "%u\n", pl4);
156}
157static DEVICE_ATTR_RO(reason_pl4);
158
159static ssize_t reason_thermal_show(struct device *dev,
160				   struct device_attribute *attr,
161				   char *buff)
162{
163	struct xe_gt *gt = dev_to_gt(dev);
164	bool thermal = !!read_reason_thermal(gt);
165
166	return sysfs_emit(buff, "%u\n", thermal);
167}
168static DEVICE_ATTR_RO(reason_thermal);
169
170static ssize_t reason_prochot_show(struct device *dev,
171				   struct device_attribute *attr,
172				   char *buff)
173{
174	struct xe_gt *gt = dev_to_gt(dev);
175	bool prochot = !!read_reason_prochot(gt);
176
177	return sysfs_emit(buff, "%u\n", prochot);
178}
179static DEVICE_ATTR_RO(reason_prochot);
180
181static ssize_t reason_ratl_show(struct device *dev,
182				struct device_attribute *attr,
183				char *buff)
184{
185	struct xe_gt *gt = dev_to_gt(dev);
186	bool ratl = !!read_reason_ratl(gt);
187
188	return sysfs_emit(buff, "%u\n", ratl);
189}
190static DEVICE_ATTR_RO(reason_ratl);
191
192static ssize_t reason_vr_thermalert_show(struct device *dev,
193					 struct device_attribute *attr,
194					 char *buff)
195{
196	struct xe_gt *gt = dev_to_gt(dev);
197	bool thermalert = !!read_reason_vr_thermalert(gt);
198
199	return sysfs_emit(buff, "%u\n", thermalert);
200}
201static DEVICE_ATTR_RO(reason_vr_thermalert);
202
203static ssize_t reason_vr_tdc_show(struct device *dev,
204				  struct device_attribute *attr,
205				  char *buff)
206{
207	struct xe_gt *gt = dev_to_gt(dev);
208	bool tdc = !!read_reason_vr_tdc(gt);
209
210	return sysfs_emit(buff, "%u\n", tdc);
211}
212static DEVICE_ATTR_RO(reason_vr_tdc);
213
214static struct attribute *throttle_attrs[] = {
215	&dev_attr_status.attr,
216	&dev_attr_reason_pl1.attr,
217	&dev_attr_reason_pl2.attr,
218	&dev_attr_reason_pl4.attr,
219	&dev_attr_reason_thermal.attr,
220	&dev_attr_reason_prochot.attr,
221	&dev_attr_reason_ratl.attr,
222	&dev_attr_reason_vr_thermalert.attr,
223	&dev_attr_reason_vr_tdc.attr,
224	NULL
225};
226
227static const struct attribute_group throttle_group_attrs = {
228	.name = "throttle",
229	.attrs = throttle_attrs,
230};
231
232static void gt_throttle_sysfs_fini(void *arg)
233{
234	struct xe_gt *gt = arg;
235
236	sysfs_remove_group(gt->freq, &throttle_group_attrs);
237}
238
239int xe_gt_throttle_init(struct xe_gt *gt)
240{
241	struct xe_device *xe = gt_to_xe(gt);
242	int err;
243
244	err = sysfs_create_group(gt->freq, &throttle_group_attrs);
245	if (err)
246		return err;
247
248	return devm_add_action_or_reset(xe->drm.dev, gt_throttle_sysfs_fini, gt);
249}