• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2021 Intel Corporation
4  */
5 
6 #define NUM_STEPS 5
7 #define H2G_DELAY 50000
8 #define delay_for_h2g() usleep_range(H2G_DELAY, H2G_DELAY + 10000)
9 #define FREQUENCY_REQ_UNIT	DIV_ROUND_CLOSEST(GT_FREQUENCY_MULTIPLIER, \
10 						  GEN9_FREQ_SCALER)
11 
slpc_set_min_freq(struct intel_guc_slpc * slpc,u32 freq)12 static int slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 freq)
13 {
14 	int ret;
15 
16 	ret = intel_guc_slpc_set_min_freq(slpc, freq);
17 	if (ret)
18 		pr_err("Could not set min frequency to [%u]\n", freq);
19 	else /* Delay to ensure h2g completes */
20 		delay_for_h2g();
21 
22 	return ret;
23 }
24 
slpc_set_max_freq(struct intel_guc_slpc * slpc,u32 freq)25 static int slpc_set_max_freq(struct intel_guc_slpc *slpc, u32 freq)
26 {
27 	int ret;
28 
29 	ret = intel_guc_slpc_set_max_freq(slpc, freq);
30 	if (ret)
31 		pr_err("Could not set maximum frequency [%u]\n",
32 		       freq);
33 	else /* Delay to ensure h2g completes */
34 		delay_for_h2g();
35 
36 	return ret;
37 }
38 
live_slpc_clamp_min(void * arg)39 static int live_slpc_clamp_min(void *arg)
40 {
41 	struct drm_i915_private *i915 = arg;
42 	struct intel_gt *gt = &i915->gt;
43 	struct intel_guc_slpc *slpc = &gt->uc.guc.slpc;
44 	struct intel_rps *rps = &gt->rps;
45 	struct intel_engine_cs *engine;
46 	enum intel_engine_id id;
47 	struct igt_spinner spin;
48 	u32 slpc_min_freq, slpc_max_freq;
49 	int err = 0;
50 
51 	if (!intel_uc_uses_guc_slpc(&gt->uc))
52 		return 0;
53 
54 	if (igt_spinner_init(&spin, gt))
55 		return -ENOMEM;
56 
57 	if (intel_guc_slpc_get_max_freq(slpc, &slpc_max_freq)) {
58 		pr_err("Could not get SLPC max freq\n");
59 		return -EIO;
60 	}
61 
62 	if (intel_guc_slpc_get_min_freq(slpc, &slpc_min_freq)) {
63 		pr_err("Could not get SLPC min freq\n");
64 		return -EIO;
65 	}
66 
67 	if (slpc_min_freq == slpc_max_freq) {
68 		pr_err("Min/Max are fused to the same value\n");
69 		return -EINVAL;
70 	}
71 
72 	intel_gt_pm_wait_for_idle(gt);
73 	intel_gt_pm_get(gt);
74 	for_each_engine(engine, gt, id) {
75 		struct i915_request *rq;
76 		u32 step, min_freq, req_freq;
77 		u32 act_freq, max_act_freq;
78 
79 		if (!intel_engine_can_store_dword(engine))
80 			continue;
81 
82 		/* Go from min to max in 5 steps */
83 		step = (slpc_max_freq - slpc_min_freq) / NUM_STEPS;
84 		max_act_freq = slpc_min_freq;
85 		for (min_freq = slpc_min_freq; min_freq < slpc_max_freq;
86 					min_freq += step) {
87 			err = slpc_set_min_freq(slpc, min_freq);
88 			if (err)
89 				break;
90 
91 			st_engine_heartbeat_disable(engine);
92 
93 			rq = igt_spinner_create_request(&spin,
94 							engine->kernel_context,
95 							MI_NOOP);
96 			if (IS_ERR(rq)) {
97 				err = PTR_ERR(rq);
98 				st_engine_heartbeat_enable(engine);
99 				break;
100 			}
101 
102 			i915_request_add(rq);
103 
104 			if (!igt_wait_for_spinner(&spin, rq)) {
105 				pr_err("%s: Spinner did not start\n",
106 				       engine->name);
107 				igt_spinner_end(&spin);
108 				st_engine_heartbeat_enable(engine);
109 				intel_gt_set_wedged(engine->gt);
110 				err = -EIO;
111 				break;
112 			}
113 
114 			/* Wait for GuC to detect business and raise
115 			 * requested frequency if necessary.
116 			 */
117 			delay_for_h2g();
118 
119 			req_freq = intel_rps_read_punit_req_frequency(rps);
120 
121 			/* GuC requests freq in multiples of 50/3 MHz */
122 			if (req_freq < (min_freq - FREQUENCY_REQ_UNIT)) {
123 				pr_err("SWReq is %d, should be at least %d\n", req_freq,
124 				       min_freq - FREQUENCY_REQ_UNIT);
125 				igt_spinner_end(&spin);
126 				st_engine_heartbeat_enable(engine);
127 				err = -EINVAL;
128 				break;
129 			}
130 
131 			act_freq =  intel_rps_read_actual_frequency(rps);
132 			if (act_freq > max_act_freq)
133 				max_act_freq = act_freq;
134 
135 			igt_spinner_end(&spin);
136 			st_engine_heartbeat_enable(engine);
137 		}
138 
139 		pr_info("Max actual frequency for %s was %d\n",
140 			engine->name, max_act_freq);
141 
142 		/* Actual frequency should rise above min */
143 		if (max_act_freq == slpc_min_freq) {
144 			pr_err("Actual freq did not rise above min\n");
145 			err = -EINVAL;
146 		}
147 
148 		if (err)
149 			break;
150 	}
151 
152 	/* Restore min/max frequencies */
153 	slpc_set_max_freq(slpc, slpc_max_freq);
154 	slpc_set_min_freq(slpc, slpc_min_freq);
155 
156 	if (igt_flush_test(gt->i915))
157 		err = -EIO;
158 
159 	intel_gt_pm_put(gt);
160 	igt_spinner_fini(&spin);
161 	intel_gt_pm_wait_for_idle(gt);
162 
163 	return err;
164 }
165 
live_slpc_clamp_max(void * arg)166 static int live_slpc_clamp_max(void *arg)
167 {
168 	struct drm_i915_private *i915 = arg;
169 	struct intel_gt *gt = &i915->gt;
170 	struct intel_guc_slpc *slpc;
171 	struct intel_rps *rps;
172 	struct intel_engine_cs *engine;
173 	enum intel_engine_id id;
174 	struct igt_spinner spin;
175 	int err = 0;
176 	u32 slpc_min_freq, slpc_max_freq;
177 
178 	slpc = &gt->uc.guc.slpc;
179 	rps = &gt->rps;
180 
181 	if (!intel_uc_uses_guc_slpc(&gt->uc))
182 		return 0;
183 
184 	if (igt_spinner_init(&spin, gt))
185 		return -ENOMEM;
186 
187 	if (intel_guc_slpc_get_max_freq(slpc, &slpc_max_freq)) {
188 		pr_err("Could not get SLPC max freq\n");
189 		return -EIO;
190 	}
191 
192 	if (intel_guc_slpc_get_min_freq(slpc, &slpc_min_freq)) {
193 		pr_err("Could not get SLPC min freq\n");
194 		return -EIO;
195 	}
196 
197 	if (slpc_min_freq == slpc_max_freq) {
198 		pr_err("Min/Max are fused to the same value\n");
199 		return -EINVAL;
200 	}
201 
202 	intel_gt_pm_wait_for_idle(gt);
203 	intel_gt_pm_get(gt);
204 	for_each_engine(engine, gt, id) {
205 		struct i915_request *rq;
206 		u32 max_freq, req_freq;
207 		u32 act_freq, max_act_freq;
208 		u32 step;
209 
210 		if (!intel_engine_can_store_dword(engine))
211 			continue;
212 
213 		/* Go from max to min in 5 steps */
214 		step = (slpc_max_freq - slpc_min_freq) / NUM_STEPS;
215 		max_act_freq = slpc_min_freq;
216 		for (max_freq = slpc_max_freq; max_freq > slpc_min_freq;
217 					max_freq -= step) {
218 			err = slpc_set_max_freq(slpc, max_freq);
219 			if (err)
220 				break;
221 
222 			st_engine_heartbeat_disable(engine);
223 
224 			rq = igt_spinner_create_request(&spin,
225 							engine->kernel_context,
226 							MI_NOOP);
227 			if (IS_ERR(rq)) {
228 				st_engine_heartbeat_enable(engine);
229 				err = PTR_ERR(rq);
230 				break;
231 			}
232 
233 			i915_request_add(rq);
234 
235 			if (!igt_wait_for_spinner(&spin, rq)) {
236 				pr_err("%s: SLPC spinner did not start\n",
237 				       engine->name);
238 				igt_spinner_end(&spin);
239 				st_engine_heartbeat_enable(engine);
240 				intel_gt_set_wedged(engine->gt);
241 				err = -EIO;
242 				break;
243 			}
244 
245 			delay_for_h2g();
246 
247 			/* Verify that SWREQ indeed was set to specific value */
248 			req_freq = intel_rps_read_punit_req_frequency(rps);
249 
250 			/* GuC requests freq in multiples of 50/3 MHz */
251 			if (req_freq > (max_freq + FREQUENCY_REQ_UNIT)) {
252 				pr_err("SWReq is %d, should be at most %d\n", req_freq,
253 				       max_freq + FREQUENCY_REQ_UNIT);
254 				igt_spinner_end(&spin);
255 				st_engine_heartbeat_enable(engine);
256 				err = -EINVAL;
257 				break;
258 			}
259 
260 			act_freq =  intel_rps_read_actual_frequency(rps);
261 			if (act_freq > max_act_freq)
262 				max_act_freq = act_freq;
263 
264 			st_engine_heartbeat_enable(engine);
265 			igt_spinner_end(&spin);
266 
267 			if (err)
268 				break;
269 		}
270 
271 		pr_info("Max actual frequency for %s was %d\n",
272 			engine->name, max_act_freq);
273 
274 		/* Actual frequency should rise above min */
275 		if (max_act_freq == slpc_min_freq) {
276 			pr_err("Actual freq did not rise above min\n");
277 			err = -EINVAL;
278 		}
279 
280 		if (igt_flush_test(gt->i915)) {
281 			err = -EIO;
282 			break;
283 		}
284 
285 		if (err)
286 			break;
287 	}
288 
289 	/* Restore min/max freq */
290 	slpc_set_max_freq(slpc, slpc_max_freq);
291 	slpc_set_min_freq(slpc, slpc_min_freq);
292 
293 	intel_gt_pm_put(gt);
294 	igt_spinner_fini(&spin);
295 	intel_gt_pm_wait_for_idle(gt);
296 
297 	return err;
298 }
299 
intel_slpc_live_selftests(struct drm_i915_private * i915)300 int intel_slpc_live_selftests(struct drm_i915_private *i915)
301 {
302 	static const struct i915_subtest tests[] = {
303 		SUBTEST(live_slpc_clamp_max),
304 		SUBTEST(live_slpc_clamp_min),
305 	};
306 
307 	if (intel_gt_is_wedged(&i915->gt))
308 		return 0;
309 
310 	return i915_live_subtests(tests, i915);
311 }
312