forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/gpu/drm/i915/selftests/intel_uncore.c
....@@ -67,6 +67,7 @@
6767 } reg_lists[] = {
6868 { gen8_shadowed_regs, ARRAY_SIZE(gen8_shadowed_regs) },
6969 { gen11_shadowed_regs, ARRAY_SIZE(gen11_shadowed_regs) },
70
+ { gen12_shadowed_regs, ARRAY_SIZE(gen12_shadowed_regs) },
7071 };
7172 const i915_reg_t *reg;
7273 unsigned int i, j;
....@@ -101,6 +102,7 @@
101102 { __chv_fw_ranges, ARRAY_SIZE(__chv_fw_ranges), false },
102103 { __gen9_fw_ranges, ARRAY_SIZE(__gen9_fw_ranges), true },
103104 { __gen11_fw_ranges, ARRAY_SIZE(__gen11_fw_ranges), true },
105
+ { __gen12_fw_ranges, ARRAY_SIZE(__gen12_fw_ranges), true },
104106 };
105107 int err, i;
106108
....@@ -119,16 +121,150 @@
119121 return 0;
120122 }
121123
122
-static int intel_uncore_check_forcewake_domains(struct drm_i915_private *dev_priv)
124
+static int live_forcewake_ops(void *arg)
125
+{
126
+ static const struct reg {
127
+ const char *name;
128
+ unsigned long platforms;
129
+ unsigned int offset;
130
+ } registers[] = {
131
+ {
132
+ "RING_START",
133
+ INTEL_GEN_MASK(6, 7),
134
+ 0x38,
135
+ },
136
+ {
137
+ "RING_MI_MODE",
138
+ INTEL_GEN_MASK(8, BITS_PER_LONG),
139
+ 0x9c,
140
+ }
141
+ };
142
+ const struct reg *r;
143
+ struct intel_gt *gt = arg;
144
+ struct intel_uncore_forcewake_domain *domain;
145
+ struct intel_uncore *uncore = gt->uncore;
146
+ struct intel_engine_cs *engine;
147
+ enum intel_engine_id id;
148
+ intel_wakeref_t wakeref;
149
+ unsigned int tmp;
150
+ int err = 0;
151
+
152
+ GEM_BUG_ON(gt->awake);
153
+
154
+ /* vlv/chv with their pcu behave differently wrt reads */
155
+ if (IS_VALLEYVIEW(gt->i915) || IS_CHERRYVIEW(gt->i915)) {
156
+ pr_debug("PCU fakes forcewake badly; skipping\n");
157
+ return 0;
158
+ }
159
+
160
+ /*
161
+ * Not quite as reliable across the gen as one would hope.
162
+ *
163
+ * Either our theory of operation is incorrect, or there remain
164
+ * external parties interfering with the powerwells.
165
+ *
166
+ * https://bugs.freedesktop.org/show_bug.cgi?id=110210
167
+ */
168
+ if (!IS_ENABLED(CONFIG_DRM_I915_SELFTEST_BROKEN))
169
+ return 0;
170
+
171
+ /* We have to pick carefully to get the exact behaviour we need */
172
+ for (r = registers; r->name; r++)
173
+ if (r->platforms & INTEL_INFO(gt->i915)->gen_mask)
174
+ break;
175
+ if (!r->name) {
176
+ pr_debug("Forcewaked register not known for %s; skipping\n",
177
+ intel_platform_name(INTEL_INFO(gt->i915)->platform));
178
+ return 0;
179
+ }
180
+
181
+ wakeref = intel_runtime_pm_get(uncore->rpm);
182
+
183
+ for_each_fw_domain(domain, uncore, tmp) {
184
+ smp_store_mb(domain->active, false);
185
+ if (!hrtimer_cancel(&domain->timer))
186
+ continue;
187
+
188
+ intel_uncore_fw_release_timer(&domain->timer);
189
+ }
190
+
191
+ for_each_engine(engine, gt, id) {
192
+ i915_reg_t mmio = _MMIO(engine->mmio_base + r->offset);
193
+ u32 __iomem *reg = uncore->regs + engine->mmio_base + r->offset;
194
+ enum forcewake_domains fw_domains;
195
+ u32 val;
196
+
197
+ if (!engine->default_state)
198
+ continue;
199
+
200
+ fw_domains = intel_uncore_forcewake_for_reg(uncore, mmio,
201
+ FW_REG_READ);
202
+ if (!fw_domains)
203
+ continue;
204
+
205
+ for_each_fw_domain_masked(domain, fw_domains, uncore, tmp) {
206
+ if (!domain->wake_count)
207
+ continue;
208
+
209
+ pr_err("fw_domain %s still active, aborting test!\n",
210
+ intel_uncore_forcewake_domain_to_str(domain->id));
211
+ err = -EINVAL;
212
+ goto out_rpm;
213
+ }
214
+
215
+ intel_uncore_forcewake_get(uncore, fw_domains);
216
+ val = readl(reg);
217
+ intel_uncore_forcewake_put(uncore, fw_domains);
218
+
219
+ /* Flush the forcewake release (delayed onto a timer) */
220
+ for_each_fw_domain_masked(domain, fw_domains, uncore, tmp) {
221
+ smp_store_mb(domain->active, false);
222
+ if (hrtimer_cancel(&domain->timer))
223
+ intel_uncore_fw_release_timer(&domain->timer);
224
+
225
+ preempt_disable();
226
+ err = wait_ack_clear(domain, FORCEWAKE_KERNEL);
227
+ preempt_enable();
228
+ if (err) {
229
+ pr_err("Failed to clear fw_domain %s\n",
230
+ intel_uncore_forcewake_domain_to_str(domain->id));
231
+ goto out_rpm;
232
+ }
233
+ }
234
+
235
+ if (!val) {
236
+ pr_err("%s:%s was zero while fw was held!\n",
237
+ engine->name, r->name);
238
+ err = -EINVAL;
239
+ goto out_rpm;
240
+ }
241
+
242
+ /* We then expect the read to return 0 outside of the fw */
243
+ if (wait_for(readl(reg) == 0, 100)) {
244
+ pr_err("%s:%s=%0x, fw_domains 0x%x still up after 100ms!\n",
245
+ engine->name, r->name, readl(reg), fw_domains);
246
+ err = -ETIMEDOUT;
247
+ goto out_rpm;
248
+ }
249
+ }
250
+
251
+out_rpm:
252
+ intel_runtime_pm_put(uncore->rpm, wakeref);
253
+ return err;
254
+}
255
+
256
+static int live_forcewake_domains(void *arg)
123257 {
124258 #define FW_RANGE 0x40000
259
+ struct intel_gt *gt = arg;
260
+ struct intel_uncore *uncore = gt->uncore;
125261 unsigned long *valid;
126262 u32 offset;
127263 int err;
128264
129
- if (!HAS_FPGA_DBG_UNCLAIMED(dev_priv) &&
130
- !IS_VALLEYVIEW(dev_priv) &&
131
- !IS_CHERRYVIEW(dev_priv))
265
+ if (!HAS_FPGA_DBG_UNCLAIMED(gt->i915) &&
266
+ !IS_VALLEYVIEW(gt->i915) &&
267
+ !IS_CHERRYVIEW(gt->i915))
132268 return 0;
133269
134270 /*
....@@ -137,60 +273,62 @@
137273 if (!IS_ENABLED(CONFIG_DRM_I915_SELFTEST_BROKEN))
138274 return 0;
139275
140
- valid = kcalloc(BITS_TO_LONGS(FW_RANGE), sizeof(*valid),
141
- GFP_KERNEL);
276
+ valid = bitmap_zalloc(FW_RANGE, GFP_KERNEL);
142277 if (!valid)
143278 return -ENOMEM;
144279
145
- intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
280
+ intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
146281
147
- check_for_unclaimed_mmio(dev_priv);
282
+ check_for_unclaimed_mmio(uncore);
148283 for (offset = 0; offset < FW_RANGE; offset += 4) {
149284 i915_reg_t reg = { offset };
150285
151
- (void)I915_READ_FW(reg);
152
- if (!check_for_unclaimed_mmio(dev_priv))
286
+ intel_uncore_posting_read_fw(uncore, reg);
287
+ if (!check_for_unclaimed_mmio(uncore))
153288 set_bit(offset, valid);
154289 }
155290
156
- intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
291
+ intel_uncore_forcewake_put(uncore, FORCEWAKE_ALL);
157292
158293 err = 0;
159294 for_each_set_bit(offset, valid, FW_RANGE) {
160295 i915_reg_t reg = { offset };
161296
162297 iosf_mbi_punit_acquire();
163
- intel_uncore_forcewake_reset(dev_priv);
298
+ intel_uncore_forcewake_reset(uncore);
164299 iosf_mbi_punit_release();
165300
166
- check_for_unclaimed_mmio(dev_priv);
301
+ check_for_unclaimed_mmio(uncore);
167302
168
- (void)I915_READ(reg);
169
- if (check_for_unclaimed_mmio(dev_priv)) {
303
+ intel_uncore_posting_read_fw(uncore, reg);
304
+ if (check_for_unclaimed_mmio(uncore)) {
170305 pr_err("Unclaimed mmio read to register 0x%04x\n",
171306 offset);
172307 err = -EINVAL;
173308 }
174309 }
175310
176
- kfree(valid);
311
+ bitmap_free(valid);
177312 return err;
313
+}
314
+
315
+static int live_fw_table(void *arg)
316
+{
317
+ struct intel_gt *gt = arg;
318
+
319
+ /* Confirm the table we load is still valid */
320
+ return intel_fw_table_check(gt->uncore->fw_domains_table,
321
+ gt->uncore->fw_domains_table_entries,
322
+ INTEL_GEN(gt->i915) >= 9);
178323 }
179324
180325 int intel_uncore_live_selftests(struct drm_i915_private *i915)
181326 {
182
- int err;
327
+ static const struct i915_subtest tests[] = {
328
+ SUBTEST(live_fw_table),
329
+ SUBTEST(live_forcewake_ops),
330
+ SUBTEST(live_forcewake_domains),
331
+ };
183332
184
- /* Confirm the table we load is still valid */
185
- err = intel_fw_table_check(i915->uncore.fw_domains_table,
186
- i915->uncore.fw_domains_table_entries,
187
- INTEL_GEN(i915) >= 9);
188
- if (err)
189
- return err;
190
-
191
- err = intel_uncore_check_forcewake_domains(i915);
192
- if (err)
193
- return err;
194
-
195
- return 0;
333
+ return intel_gt_live_subtests(tests, &i915->gt);
196334 }