selftest_slpc.c (7173B)
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 12static 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 25static 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 39static int live_slpc_clamp_min(void *arg) 40{ 41 struct drm_i915_private *i915 = arg; 42 struct intel_gt *gt = to_gt(i915); 43 struct intel_guc_slpc *slpc = >->uc.guc.slpc; 44 struct intel_rps *rps = >->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(>->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 166static int live_slpc_clamp_max(void *arg) 167{ 168 struct drm_i915_private *i915 = arg; 169 struct intel_gt *gt = to_gt(i915); 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 = >->uc.guc.slpc; 179 rps = >->rps; 180 181 if (!intel_uc_uses_guc_slpc(>->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 300int 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(to_gt(i915))) 308 return 0; 309 310 return i915_live_subtests(tests, i915); 311}