xref: /linux/drivers/gpu/drm/xe/xe_gt_freq.c (revision a4871e6201c46c8e1d04308265b4b4c5753c8209)
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:
33  *
34  * device/tile#/gt#/freq0/<item>_freq *read-only* files:
35  * - act_freq: The actual resolved frequency decided by PCODE.
36  * - cur_freq: The current one requested by GuC PC to the PCODE.
37  * - rpn_freq: The Render Performance (RP) N level, which is the minimal one.
38  * - rpe_freq: The Render Performance (RP) E level, which is the efficient one.
39  * - rp0_freq: The Render Performance (RP) 0 level, which is the maximum one.
40  *
41  * device/tile#/gt#/freq0/<item>_freq *read-write* files:
42  * - min_freq: Min frequency request.
43  * - max_freq: Max frequency request.
44  *             If max <= min, then freq_min becomes a fixed frequency request.
45  */
46 
47 static struct xe_guc_pc *
48 dev_to_pc(struct device *dev)
49 {
50 	return &kobj_to_gt(dev->kobj.parent)->uc.guc.pc;
51 }
52 
53 static struct xe_device *
54 dev_to_xe(struct device *dev)
55 {
56 	return gt_to_xe(kobj_to_gt(dev->kobj.parent));
57 }
58 
59 static ssize_t act_freq_show(struct kobject *kobj,
60 			     struct kobj_attribute *attr, char *buf)
61 {
62 	struct device *dev = kobj_to_dev(kobj);
63 	struct xe_guc_pc *pc = dev_to_pc(dev);
64 	u32 freq;
65 
66 	xe_pm_runtime_get(dev_to_xe(dev));
67 	freq = xe_guc_pc_get_act_freq(pc);
68 	xe_pm_runtime_put(dev_to_xe(dev));
69 
70 	return sysfs_emit(buf, "%d\n", freq);
71 }
72 static struct kobj_attribute attr_act_freq = __ATTR_RO(act_freq);
73 
74 static ssize_t cur_freq_show(struct kobject *kobj,
75 			     struct kobj_attribute *attr, char *buf)
76 {
77 	struct device *dev = kobj_to_dev(kobj);
78 	struct xe_guc_pc *pc = dev_to_pc(dev);
79 	u32 freq;
80 	ssize_t ret;
81 
82 	xe_pm_runtime_get(dev_to_xe(dev));
83 	ret = xe_guc_pc_get_cur_freq(pc, &freq);
84 	xe_pm_runtime_put(dev_to_xe(dev));
85 	if (ret)
86 		return ret;
87 
88 	return sysfs_emit(buf, "%d\n", freq);
89 }
90 static struct kobj_attribute attr_cur_freq = __ATTR_RO(cur_freq);
91 
92 static ssize_t rp0_freq_show(struct kobject *kobj,
93 			     struct kobj_attribute *attr, char *buf)
94 {
95 	struct device *dev = kobj_to_dev(kobj);
96 	struct xe_guc_pc *pc = dev_to_pc(dev);
97 	u32 freq;
98 
99 	xe_pm_runtime_get(dev_to_xe(dev));
100 	freq = xe_guc_pc_get_rp0_freq(pc);
101 	xe_pm_runtime_put(dev_to_xe(dev));
102 
103 	return sysfs_emit(buf, "%d\n", freq);
104 }
105 static struct kobj_attribute attr_rp0_freq = __ATTR_RO(rp0_freq);
106 
107 static ssize_t rpe_freq_show(struct kobject *kobj,
108 			     struct kobj_attribute *attr, char *buf)
109 {
110 	struct device *dev = kobj_to_dev(kobj);
111 	struct xe_guc_pc *pc = dev_to_pc(dev);
112 	u32 freq;
113 
114 	xe_pm_runtime_get(dev_to_xe(dev));
115 	freq = xe_guc_pc_get_rpe_freq(pc);
116 	xe_pm_runtime_put(dev_to_xe(dev));
117 
118 	return sysfs_emit(buf, "%d\n", freq);
119 }
120 static struct kobj_attribute attr_rpe_freq = __ATTR_RO(rpe_freq);
121 
122 static ssize_t rpa_freq_show(struct kobject *kobj,
123 			     struct kobj_attribute *attr, char *buf)
124 {
125 	struct device *dev = kobj_to_dev(kobj);
126 	struct xe_guc_pc *pc = dev_to_pc(dev);
127 	u32 freq;
128 
129 	xe_pm_runtime_get(dev_to_xe(dev));
130 	freq = xe_guc_pc_get_rpa_freq(pc);
131 	xe_pm_runtime_put(dev_to_xe(dev));
132 
133 	return sysfs_emit(buf, "%d\n", freq);
134 }
135 static struct kobj_attribute attr_rpa_freq = __ATTR_RO(rpa_freq);
136 
137 static ssize_t rpn_freq_show(struct kobject *kobj,
138 			     struct kobj_attribute *attr, char *buf)
139 {
140 	struct device *dev = kobj_to_dev(kobj);
141 	struct xe_guc_pc *pc = dev_to_pc(dev);
142 
143 	return sysfs_emit(buf, "%d\n", xe_guc_pc_get_rpn_freq(pc));
144 }
145 static struct kobj_attribute attr_rpn_freq = __ATTR_RO(rpn_freq);
146 
147 static ssize_t min_freq_show(struct kobject *kobj,
148 			     struct kobj_attribute *attr, char *buf)
149 {
150 	struct device *dev = kobj_to_dev(kobj);
151 	struct xe_guc_pc *pc = dev_to_pc(dev);
152 	u32 freq;
153 	ssize_t ret;
154 
155 	xe_pm_runtime_get(dev_to_xe(dev));
156 	ret = xe_guc_pc_get_min_freq(pc, &freq);
157 	xe_pm_runtime_put(dev_to_xe(dev));
158 	if (ret)
159 		return ret;
160 
161 	return sysfs_emit(buf, "%d\n", freq);
162 }
163 
164 static ssize_t min_freq_store(struct kobject *kobj,
165 			      struct kobj_attribute *attr, const char *buff, size_t count)
166 {
167 	struct device *dev = kobj_to_dev(kobj);
168 	struct xe_guc_pc *pc = dev_to_pc(dev);
169 	u32 freq;
170 	ssize_t ret;
171 
172 	ret = kstrtou32(buff, 0, &freq);
173 	if (ret)
174 		return ret;
175 
176 	xe_pm_runtime_get(dev_to_xe(dev));
177 	ret = xe_guc_pc_set_min_freq(pc, freq);
178 	xe_pm_runtime_put(dev_to_xe(dev));
179 	if (ret)
180 		return ret;
181 
182 	return count;
183 }
184 static struct kobj_attribute attr_min_freq = __ATTR_RW(min_freq);
185 
186 static ssize_t max_freq_show(struct kobject *kobj,
187 			     struct kobj_attribute *attr, char *buf)
188 {
189 	struct device *dev = kobj_to_dev(kobj);
190 	struct xe_guc_pc *pc = dev_to_pc(dev);
191 	u32 freq;
192 	ssize_t ret;
193 
194 	xe_pm_runtime_get(dev_to_xe(dev));
195 	ret = xe_guc_pc_get_max_freq(pc, &freq);
196 	xe_pm_runtime_put(dev_to_xe(dev));
197 	if (ret)
198 		return ret;
199 
200 	return sysfs_emit(buf, "%d\n", freq);
201 }
202 
203 static ssize_t max_freq_store(struct kobject *kobj,
204 			      struct kobj_attribute *attr, const char *buff, size_t count)
205 {
206 	struct device *dev = kobj_to_dev(kobj);
207 	struct xe_guc_pc *pc = dev_to_pc(dev);
208 	u32 freq;
209 	ssize_t ret;
210 
211 	ret = kstrtou32(buff, 0, &freq);
212 	if (ret)
213 		return ret;
214 
215 	xe_pm_runtime_get(dev_to_xe(dev));
216 	ret = xe_guc_pc_set_max_freq(pc, freq);
217 	xe_pm_runtime_put(dev_to_xe(dev));
218 	if (ret)
219 		return ret;
220 
221 	return count;
222 }
223 static struct kobj_attribute attr_max_freq = __ATTR_RW(max_freq);
224 
225 static const struct attribute *freq_attrs[] = {
226 	&attr_act_freq.attr,
227 	&attr_cur_freq.attr,
228 	&attr_rp0_freq.attr,
229 	&attr_rpa_freq.attr,
230 	&attr_rpe_freq.attr,
231 	&attr_rpn_freq.attr,
232 	&attr_min_freq.attr,
233 	&attr_max_freq.attr,
234 	NULL
235 };
236 
237 static void freq_fini(void *arg)
238 {
239 	struct kobject *kobj = arg;
240 
241 	sysfs_remove_files(kobj, freq_attrs);
242 	kobject_put(kobj);
243 }
244 
245 /**
246  * xe_gt_freq_init - Initialize Xe Freq component
247  * @gt: Xe GT object
248  *
249  * It needs to be initialized after GT Sysfs and GuC PC components are ready.
250  *
251  * Returns: Returns error value for failure and 0 for success.
252  */
253 int xe_gt_freq_init(struct xe_gt *gt)
254 {
255 	struct xe_device *xe = gt_to_xe(gt);
256 	int err;
257 
258 	if (xe->info.skip_guc_pc)
259 		return 0;
260 
261 	gt->freq = kobject_create_and_add("freq0", gt->sysfs);
262 	if (!gt->freq)
263 		return -ENOMEM;
264 
265 	err = sysfs_create_files(gt->freq, freq_attrs);
266 	if (err)
267 		return err;
268 
269 	err = devm_add_action_or_reset(xe->drm.dev, freq_fini, gt->freq);
270 	if (err)
271 		return err;
272 
273 	return xe_gt_throttle_init(gt);
274 }
275