xref: /linux/drivers/gpu/drm/xe/xe_gt_freq.c (revision f2161d5f1aae21a42b0a64d87e10cb31db423f42)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2023 Intel Corporation
4  */
5 
6 #include "xe_gt_freq.h"
7 
8 #include <linux/kobject.h>
9 #include <linux/sysfs.h>
10 
11 #include <drm/drm_managed.h>
12 #include <drm/drm_print.h>
13 
14 #include "xe_gt_sysfs.h"
15 #include "xe_gt_throttle.h"
16 #include "xe_gt_types.h"
17 #include "xe_guc_pc.h"
18 #include "xe_pm.h"
19 
20 /**
21  * DOC: Xe GT Frequency Management
22  *
23  * This component is responsible for the raw GT frequency management, including
24  * the sysfs API.
25  *
26  * Underneath, Xe enables GuC SLPC automated frequency management. GuC is then
27  * allowed to request PCODE any frequency between the Minimum and the Maximum
28  * selected by this component. Furthermore, it is important to highlight that
29  * PCODE is the ultimate decision maker of the actual running frequency, based
30  * on thermal and other running conditions.
31  *
32  * Xe's Freq provides a sysfs API for frequency management under
33  * ``<device>/tile#/gt#/freq0/`` directory.
34  *
35  * **Read-only** attributes:
36  *
37  * - ``act_freq``: The actual resolved frequency decided by PCODE.
38  * - ``cur_freq``: The current one requested by GuC PC to the PCODE.
39  * - ``rpn_freq``: The Render Performance (RP) N level, which is the minimal one.
40  * - ``rpa_freq``: The Render Performance (RP) A level, which is the achievable one.
41  *                 Calculated by PCODE at runtime based on multiple running conditions
42  * - ``rpe_freq``: The Render Performance (RP) E level, which is the efficient one.
43  *                 Calculated by PCODE at runtime based on multiple running conditions
44  * - ``rp0_freq``: The Render Performance (RP) 0 level, which is the maximum one.
45  *
46  * **Read-write** attributes:
47  *
48  * - ``min_freq``: Min frequency request.
49  * - ``max_freq``: Max frequency request.
50  *                 If max <= min, then freq_min becomes a fixed frequency
51  *                 request.
52  */
53 
54 static struct xe_guc_pc *
dev_to_pc(struct device * dev)55 dev_to_pc(struct device *dev)
56 {
57 	return &kobj_to_gt(dev->kobj.parent)->uc.guc.pc;
58 }
59 
60 static struct xe_device *
dev_to_xe(struct device * dev)61 dev_to_xe(struct device *dev)
62 {
63 	return gt_to_xe(kobj_to_gt(dev->kobj.parent));
64 }
65 
act_freq_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)66 static ssize_t act_freq_show(struct kobject *kobj,
67 			     struct kobj_attribute *attr, char *buf)
68 {
69 	struct device *dev = kobj_to_dev(kobj);
70 	struct xe_guc_pc *pc = dev_to_pc(dev);
71 	u32 freq;
72 
73 	xe_pm_runtime_get(dev_to_xe(dev));
74 	freq = xe_guc_pc_get_act_freq(pc);
75 	xe_pm_runtime_put(dev_to_xe(dev));
76 
77 	return sysfs_emit(buf, "%d\n", freq);
78 }
79 static struct kobj_attribute attr_act_freq = __ATTR_RO(act_freq);
80 
cur_freq_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)81 static ssize_t cur_freq_show(struct kobject *kobj,
82 			     struct kobj_attribute *attr, char *buf)
83 {
84 	struct device *dev = kobj_to_dev(kobj);
85 	struct xe_guc_pc *pc = dev_to_pc(dev);
86 	u32 freq;
87 	ssize_t ret;
88 
89 	xe_pm_runtime_get(dev_to_xe(dev));
90 	ret = xe_guc_pc_get_cur_freq(pc, &freq);
91 	xe_pm_runtime_put(dev_to_xe(dev));
92 	if (ret)
93 		return ret;
94 
95 	return sysfs_emit(buf, "%d\n", freq);
96 }
97 static struct kobj_attribute attr_cur_freq = __ATTR_RO(cur_freq);
98 
rp0_freq_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)99 static ssize_t rp0_freq_show(struct kobject *kobj,
100 			     struct kobj_attribute *attr, char *buf)
101 {
102 	struct device *dev = kobj_to_dev(kobj);
103 	struct xe_guc_pc *pc = dev_to_pc(dev);
104 
105 	return sysfs_emit(buf, "%d\n", xe_guc_pc_get_rp0_freq(pc));
106 }
107 static struct kobj_attribute attr_rp0_freq = __ATTR_RO(rp0_freq);
108 
rpe_freq_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)109 static ssize_t rpe_freq_show(struct kobject *kobj,
110 			     struct kobj_attribute *attr, char *buf)
111 {
112 	struct device *dev = kobj_to_dev(kobj);
113 	struct xe_guc_pc *pc = dev_to_pc(dev);
114 	u32 freq;
115 
116 	xe_pm_runtime_get(dev_to_xe(dev));
117 	freq = xe_guc_pc_get_rpe_freq(pc);
118 	xe_pm_runtime_put(dev_to_xe(dev));
119 
120 	return sysfs_emit(buf, "%d\n", freq);
121 }
122 static struct kobj_attribute attr_rpe_freq = __ATTR_RO(rpe_freq);
123 
rpa_freq_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)124 static ssize_t rpa_freq_show(struct kobject *kobj,
125 			     struct kobj_attribute *attr, char *buf)
126 {
127 	struct device *dev = kobj_to_dev(kobj);
128 	struct xe_guc_pc *pc = dev_to_pc(dev);
129 	u32 freq;
130 
131 	xe_pm_runtime_get(dev_to_xe(dev));
132 	freq = xe_guc_pc_get_rpa_freq(pc);
133 	xe_pm_runtime_put(dev_to_xe(dev));
134 
135 	return sysfs_emit(buf, "%d\n", freq);
136 }
137 static struct kobj_attribute attr_rpa_freq = __ATTR_RO(rpa_freq);
138 
rpn_freq_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)139 static ssize_t rpn_freq_show(struct kobject *kobj,
140 			     struct kobj_attribute *attr, char *buf)
141 {
142 	struct device *dev = kobj_to_dev(kobj);
143 	struct xe_guc_pc *pc = dev_to_pc(dev);
144 
145 	return sysfs_emit(buf, "%d\n", xe_guc_pc_get_rpn_freq(pc));
146 }
147 static struct kobj_attribute attr_rpn_freq = __ATTR_RO(rpn_freq);
148 
min_freq_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)149 static ssize_t min_freq_show(struct kobject *kobj,
150 			     struct kobj_attribute *attr, char *buf)
151 {
152 	struct device *dev = kobj_to_dev(kobj);
153 	struct xe_guc_pc *pc = dev_to_pc(dev);
154 	u32 freq;
155 	ssize_t ret;
156 
157 	xe_pm_runtime_get(dev_to_xe(dev));
158 	ret = xe_guc_pc_get_min_freq(pc, &freq);
159 	xe_pm_runtime_put(dev_to_xe(dev));
160 	if (ret)
161 		return ret;
162 
163 	return sysfs_emit(buf, "%d\n", freq);
164 }
165 
min_freq_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buff,size_t count)166 static ssize_t min_freq_store(struct kobject *kobj,
167 			      struct kobj_attribute *attr, const char *buff, size_t count)
168 {
169 	struct device *dev = kobj_to_dev(kobj);
170 	struct xe_guc_pc *pc = dev_to_pc(dev);
171 	u32 freq;
172 	ssize_t ret;
173 
174 	ret = kstrtou32(buff, 0, &freq);
175 	if (ret)
176 		return ret;
177 
178 	xe_pm_runtime_get(dev_to_xe(dev));
179 	ret = xe_guc_pc_set_min_freq(pc, freq);
180 	xe_pm_runtime_put(dev_to_xe(dev));
181 	if (ret)
182 		return ret;
183 
184 	return count;
185 }
186 static struct kobj_attribute attr_min_freq = __ATTR_RW(min_freq);
187 
max_freq_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)188 static ssize_t max_freq_show(struct kobject *kobj,
189 			     struct kobj_attribute *attr, char *buf)
190 {
191 	struct device *dev = kobj_to_dev(kobj);
192 	struct xe_guc_pc *pc = dev_to_pc(dev);
193 	u32 freq;
194 	ssize_t ret;
195 
196 	xe_pm_runtime_get(dev_to_xe(dev));
197 	ret = xe_guc_pc_get_max_freq(pc, &freq);
198 	xe_pm_runtime_put(dev_to_xe(dev));
199 	if (ret)
200 		return ret;
201 
202 	return sysfs_emit(buf, "%d\n", freq);
203 }
204 
max_freq_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buff,size_t count)205 static ssize_t max_freq_store(struct kobject *kobj,
206 			      struct kobj_attribute *attr, const char *buff, size_t count)
207 {
208 	struct device *dev = kobj_to_dev(kobj);
209 	struct xe_guc_pc *pc = dev_to_pc(dev);
210 	u32 freq;
211 	ssize_t ret;
212 
213 	ret = kstrtou32(buff, 0, &freq);
214 	if (ret)
215 		return ret;
216 
217 	xe_pm_runtime_get(dev_to_xe(dev));
218 	ret = xe_guc_pc_set_max_freq(pc, freq);
219 	xe_pm_runtime_put(dev_to_xe(dev));
220 	if (ret)
221 		return ret;
222 
223 	return count;
224 }
225 static struct kobj_attribute attr_max_freq = __ATTR_RW(max_freq);
226 
power_profile_show(struct kobject * kobj,struct kobj_attribute * attr,char * buff)227 static ssize_t power_profile_show(struct kobject *kobj,
228 				  struct kobj_attribute *attr,
229 				  char *buff)
230 {
231 	struct device *dev = kobj_to_dev(kobj);
232 
233 	xe_guc_pc_get_power_profile(dev_to_pc(dev), buff);
234 
235 	return strlen(buff);
236 }
237 
power_profile_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buff,size_t count)238 static ssize_t power_profile_store(struct kobject *kobj,
239 				   struct kobj_attribute *attr,
240 				   const char *buff, size_t count)
241 {
242 	struct device *dev = kobj_to_dev(kobj);
243 	struct xe_guc_pc *pc = dev_to_pc(dev);
244 	int err;
245 
246 	xe_pm_runtime_get(dev_to_xe(dev));
247 	err = xe_guc_pc_set_power_profile(pc, buff);
248 	xe_pm_runtime_put(dev_to_xe(dev));
249 
250 	return err ?: count;
251 }
252 static struct kobj_attribute attr_power_profile = __ATTR_RW(power_profile);
253 
254 static const struct attribute *freq_attrs[] = {
255 	&attr_act_freq.attr,
256 	&attr_cur_freq.attr,
257 	&attr_rp0_freq.attr,
258 	&attr_rpa_freq.attr,
259 	&attr_rpe_freq.attr,
260 	&attr_rpn_freq.attr,
261 	&attr_min_freq.attr,
262 	&attr_max_freq.attr,
263 	&attr_power_profile.attr,
264 	NULL
265 };
266 
freq_fini(void * arg)267 static void freq_fini(void *arg)
268 {
269 	struct kobject *kobj = arg;
270 
271 	sysfs_remove_files(kobj, freq_attrs);
272 	kobject_put(kobj);
273 }
274 
275 /**
276  * xe_gt_freq_init - Initialize Xe Freq component
277  * @gt: Xe GT object
278  *
279  * It needs to be initialized after GT Sysfs and GuC PC components are ready.
280  *
281  * Returns: Returns error value for failure and 0 for success.
282  */
xe_gt_freq_init(struct xe_gt * gt)283 int xe_gt_freq_init(struct xe_gt *gt)
284 {
285 	struct xe_device *xe = gt_to_xe(gt);
286 	int err;
287 
288 	if (xe->info.skip_guc_pc)
289 		return 0;
290 
291 	gt->freq = kobject_create_and_add("freq0", gt->sysfs);
292 	if (!gt->freq)
293 		return -ENOMEM;
294 
295 	err = sysfs_create_files(gt->freq, freq_attrs);
296 	if (err) {
297 		kobject_put(gt->freq);
298 		return err;
299 	}
300 
301 	err = devm_add_action_or_reset(xe->drm.dev, freq_fini, gt->freq);
302 	if (err)
303 		return err;
304 
305 	return xe_gt_throttle_init(gt);
306 }
307