]> Git Repo - linux.git/blob - drivers/gpu/drm/i915/i915_debugfs.c
Merge tag 'cxl-for-6.0' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl
[linux.git] / drivers / gpu / drm / i915 / i915_debugfs.c
1 /*
2  * Copyright © 2008 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * Authors:
24  *    Eric Anholt <[email protected]>
25  *    Keith Packard <[email protected]>
26  *
27  */
28
29 #include <linux/sched/mm.h>
30 #include <linux/sort.h>
31 #include <linux/string_helpers.h>
32
33 #include <drm/drm_debugfs.h>
34
35 #include "gem/i915_gem_context.h"
36 #include "gt/intel_gt.h"
37 #include "gt/intel_gt_buffer_pool.h"
38 #include "gt/intel_gt_clock_utils.h"
39 #include "gt/intel_gt_debugfs.h"
40 #include "gt/intel_gt_pm.h"
41 #include "gt/intel_gt_pm_debugfs.h"
42 #include "gt/intel_gt_regs.h"
43 #include "gt/intel_gt_requests.h"
44 #include "gt/intel_rc6.h"
45 #include "gt/intel_reset.h"
46 #include "gt/intel_rps.h"
47 #include "gt/intel_sseu_debugfs.h"
48
49 #include "i915_debugfs.h"
50 #include "i915_debugfs_params.h"
51 #include "i915_driver.h"
52 #include "i915_irq.h"
53 #include "i915_scheduler.h"
54 #include "intel_mchbar_regs.h"
55 #include "intel_pm.h"
56
57 static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node)
58 {
59         return to_i915(node->minor->dev);
60 }
61
62 static int i915_capabilities(struct seq_file *m, void *data)
63 {
64         struct drm_i915_private *i915 = node_to_i915(m->private);
65         struct drm_printer p = drm_seq_file_printer(m);
66
67         seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(i915));
68
69         intel_device_info_print_static(INTEL_INFO(i915), &p);
70         intel_device_info_print_runtime(RUNTIME_INFO(i915), &p);
71         i915_print_iommu_status(i915, &p);
72         intel_gt_info_print(&to_gt(i915)->info, &p);
73         intel_driver_caps_print(&i915->caps, &p);
74
75         kernel_param_lock(THIS_MODULE);
76         i915_params_dump(&i915->params, &p);
77         kernel_param_unlock(THIS_MODULE);
78
79         return 0;
80 }
81
82 static char get_tiling_flag(struct drm_i915_gem_object *obj)
83 {
84         switch (i915_gem_object_get_tiling(obj)) {
85         default:
86         case I915_TILING_NONE: return ' ';
87         case I915_TILING_X: return 'X';
88         case I915_TILING_Y: return 'Y';
89         }
90 }
91
92 static char get_global_flag(struct drm_i915_gem_object *obj)
93 {
94         return READ_ONCE(obj->userfault_count) ? 'g' : ' ';
95 }
96
97 static char get_pin_mapped_flag(struct drm_i915_gem_object *obj)
98 {
99         return obj->mm.mapping ? 'M' : ' ';
100 }
101
102 static const char *
103 stringify_page_sizes(unsigned int page_sizes, char *buf, size_t len)
104 {
105         size_t x = 0;
106
107         switch (page_sizes) {
108         case 0:
109                 return "";
110         case I915_GTT_PAGE_SIZE_4K:
111                 return "4K";
112         case I915_GTT_PAGE_SIZE_64K:
113                 return "64K";
114         case I915_GTT_PAGE_SIZE_2M:
115                 return "2M";
116         default:
117                 if (!buf)
118                         return "M";
119
120                 if (page_sizes & I915_GTT_PAGE_SIZE_2M)
121                         x += snprintf(buf + x, len - x, "2M, ");
122                 if (page_sizes & I915_GTT_PAGE_SIZE_64K)
123                         x += snprintf(buf + x, len - x, "64K, ");
124                 if (page_sizes & I915_GTT_PAGE_SIZE_4K)
125                         x += snprintf(buf + x, len - x, "4K, ");
126                 buf[x-2] = '\0';
127
128                 return buf;
129         }
130 }
131
132 static const char *stringify_vma_type(const struct i915_vma *vma)
133 {
134         if (i915_vma_is_ggtt(vma))
135                 return "ggtt";
136
137         if (i915_vma_is_dpt(vma))
138                 return "dpt";
139
140         return "ppgtt";
141 }
142
143 static const char *i915_cache_level_str(struct drm_i915_private *i915, int type)
144 {
145         switch (type) {
146         case I915_CACHE_NONE: return " uncached";
147         case I915_CACHE_LLC: return HAS_LLC(i915) ? " LLC" : " snooped";
148         case I915_CACHE_L3_LLC: return " L3+LLC";
149         case I915_CACHE_WT: return " WT";
150         default: return "";
151         }
152 }
153
154 void
155 i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
156 {
157         struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
158         struct i915_vma *vma;
159         int pin_count = 0;
160
161         seq_printf(m, "%pK: %c%c%c %8zdKiB %02x %02x %s%s%s",
162                    &obj->base,
163                    get_tiling_flag(obj),
164                    get_global_flag(obj),
165                    get_pin_mapped_flag(obj),
166                    obj->base.size / 1024,
167                    obj->read_domains,
168                    obj->write_domain,
169                    i915_cache_level_str(dev_priv, obj->cache_level),
170                    obj->mm.dirty ? " dirty" : "",
171                    obj->mm.madv == I915_MADV_DONTNEED ? " purgeable" : "");
172         if (obj->base.name)
173                 seq_printf(m, " (name: %d)", obj->base.name);
174
175         spin_lock(&obj->vma.lock);
176         list_for_each_entry(vma, &obj->vma.list, obj_link) {
177                 if (!drm_mm_node_allocated(&vma->node))
178                         continue;
179
180                 spin_unlock(&obj->vma.lock);
181
182                 if (i915_vma_is_pinned(vma))
183                         pin_count++;
184
185                 seq_printf(m, " (%s offset: %08llx, size: %08llx, pages: %s",
186                            stringify_vma_type(vma),
187                            vma->node.start, vma->node.size,
188                            stringify_page_sizes(vma->resource->page_sizes_gtt,
189                                                 NULL, 0));
190                 if (i915_vma_is_ggtt(vma) || i915_vma_is_dpt(vma)) {
191                         switch (vma->ggtt_view.type) {
192                         case I915_GGTT_VIEW_NORMAL:
193                                 seq_puts(m, ", normal");
194                                 break;
195
196                         case I915_GGTT_VIEW_PARTIAL:
197                                 seq_printf(m, ", partial [%08llx+%x]",
198                                            vma->ggtt_view.partial.offset << PAGE_SHIFT,
199                                            vma->ggtt_view.partial.size << PAGE_SHIFT);
200                                 break;
201
202                         case I915_GGTT_VIEW_ROTATED:
203                                 seq_printf(m, ", rotated [(%ux%u, src_stride=%u, dst_stride=%u, offset=%u), (%ux%u, src_stride=%u, dst_stride=%u, offset=%u)]",
204                                            vma->ggtt_view.rotated.plane[0].width,
205                                            vma->ggtt_view.rotated.plane[0].height,
206                                            vma->ggtt_view.rotated.plane[0].src_stride,
207                                            vma->ggtt_view.rotated.plane[0].dst_stride,
208                                            vma->ggtt_view.rotated.plane[0].offset,
209                                            vma->ggtt_view.rotated.plane[1].width,
210                                            vma->ggtt_view.rotated.plane[1].height,
211                                            vma->ggtt_view.rotated.plane[1].src_stride,
212                                            vma->ggtt_view.rotated.plane[1].dst_stride,
213                                            vma->ggtt_view.rotated.plane[1].offset);
214                                 break;
215
216                         case I915_GGTT_VIEW_REMAPPED:
217                                 seq_printf(m, ", remapped [(%ux%u, src_stride=%u, dst_stride=%u, offset=%u), (%ux%u, src_stride=%u, dst_stride=%u, offset=%u)]",
218                                            vma->ggtt_view.remapped.plane[0].width,
219                                            vma->ggtt_view.remapped.plane[0].height,
220                                            vma->ggtt_view.remapped.plane[0].src_stride,
221                                            vma->ggtt_view.remapped.plane[0].dst_stride,
222                                            vma->ggtt_view.remapped.plane[0].offset,
223                                            vma->ggtt_view.remapped.plane[1].width,
224                                            vma->ggtt_view.remapped.plane[1].height,
225                                            vma->ggtt_view.remapped.plane[1].src_stride,
226                                            vma->ggtt_view.remapped.plane[1].dst_stride,
227                                            vma->ggtt_view.remapped.plane[1].offset);
228                                 break;
229
230                         default:
231                                 MISSING_CASE(vma->ggtt_view.type);
232                                 break;
233                         }
234                 }
235                 if (vma->fence)
236                         seq_printf(m, " , fence: %d", vma->fence->id);
237                 seq_puts(m, ")");
238
239                 spin_lock(&obj->vma.lock);
240         }
241         spin_unlock(&obj->vma.lock);
242
243         seq_printf(m, " (pinned x %d)", pin_count);
244         if (i915_gem_object_is_stolen(obj))
245                 seq_printf(m, " (stolen: %08llx)", obj->stolen->start);
246         if (i915_gem_object_is_framebuffer(obj))
247                 seq_printf(m, " (fb)");
248 }
249
250 static int i915_gem_object_info(struct seq_file *m, void *data)
251 {
252         struct drm_i915_private *i915 = node_to_i915(m->private);
253         struct drm_printer p = drm_seq_file_printer(m);
254         struct intel_memory_region *mr;
255         enum intel_region_id id;
256
257         seq_printf(m, "%u shrinkable [%u free] objects, %llu bytes\n",
258                    i915->mm.shrink_count,
259                    atomic_read(&i915->mm.free_count),
260                    i915->mm.shrink_memory);
261         for_each_memory_region(mr, i915, id)
262                 intel_memory_region_debug(mr, &p);
263
264         return 0;
265 }
266
267 #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
268 static ssize_t gpu_state_read(struct file *file, char __user *ubuf,
269                               size_t count, loff_t *pos)
270 {
271         struct i915_gpu_coredump *error;
272         ssize_t ret;
273         void *buf;
274
275         error = file->private_data;
276         if (!error)
277                 return 0;
278
279         /* Bounce buffer required because of kernfs __user API convenience. */
280         buf = kmalloc(count, GFP_KERNEL);
281         if (!buf)
282                 return -ENOMEM;
283
284         ret = i915_gpu_coredump_copy_to_buffer(error, buf, *pos, count);
285         if (ret <= 0)
286                 goto out;
287
288         if (!copy_to_user(ubuf, buf, ret))
289                 *pos += ret;
290         else
291                 ret = -EFAULT;
292
293 out:
294         kfree(buf);
295         return ret;
296 }
297
298 static int gpu_state_release(struct inode *inode, struct file *file)
299 {
300         i915_gpu_coredump_put(file->private_data);
301         return 0;
302 }
303
304 static int i915_gpu_info_open(struct inode *inode, struct file *file)
305 {
306         struct drm_i915_private *i915 = inode->i_private;
307         struct i915_gpu_coredump *gpu;
308         intel_wakeref_t wakeref;
309
310         gpu = NULL;
311         with_intel_runtime_pm(&i915->runtime_pm, wakeref)
312                 gpu = i915_gpu_coredump(to_gt(i915), ALL_ENGINES, CORE_DUMP_FLAG_NONE);
313
314         if (IS_ERR(gpu))
315                 return PTR_ERR(gpu);
316
317         file->private_data = gpu;
318         return 0;
319 }
320
321 static const struct file_operations i915_gpu_info_fops = {
322         .owner = THIS_MODULE,
323         .open = i915_gpu_info_open,
324         .read = gpu_state_read,
325         .llseek = default_llseek,
326         .release = gpu_state_release,
327 };
328
329 static ssize_t
330 i915_error_state_write(struct file *filp,
331                        const char __user *ubuf,
332                        size_t cnt,
333                        loff_t *ppos)
334 {
335         struct i915_gpu_coredump *error = filp->private_data;
336
337         if (!error)
338                 return 0;
339
340         drm_dbg(&error->i915->drm, "Resetting error state\n");
341         i915_reset_error_state(error->i915);
342
343         return cnt;
344 }
345
346 static int i915_error_state_open(struct inode *inode, struct file *file)
347 {
348         struct i915_gpu_coredump *error;
349
350         error = i915_first_error_state(inode->i_private);
351         if (IS_ERR(error))
352                 return PTR_ERR(error);
353
354         file->private_data  = error;
355         return 0;
356 }
357
358 static const struct file_operations i915_error_state_fops = {
359         .owner = THIS_MODULE,
360         .open = i915_error_state_open,
361         .read = gpu_state_read,
362         .write = i915_error_state_write,
363         .llseek = default_llseek,
364         .release = gpu_state_release,
365 };
366 #endif
367
368 static int i915_frequency_info(struct seq_file *m, void *unused)
369 {
370         struct drm_i915_private *i915 = node_to_i915(m->private);
371         struct intel_gt *gt = to_gt(i915);
372         struct drm_printer p = drm_seq_file_printer(m);
373
374         intel_gt_pm_frequency_dump(gt, &p);
375
376         return 0;
377 }
378
379 static const char *swizzle_string(unsigned swizzle)
380 {
381         switch (swizzle) {
382         case I915_BIT_6_SWIZZLE_NONE:
383                 return "none";
384         case I915_BIT_6_SWIZZLE_9:
385                 return "bit9";
386         case I915_BIT_6_SWIZZLE_9_10:
387                 return "bit9/bit10";
388         case I915_BIT_6_SWIZZLE_9_11:
389                 return "bit9/bit11";
390         case I915_BIT_6_SWIZZLE_9_10_11:
391                 return "bit9/bit10/bit11";
392         case I915_BIT_6_SWIZZLE_9_17:
393                 return "bit9/bit17";
394         case I915_BIT_6_SWIZZLE_9_10_17:
395                 return "bit9/bit10/bit17";
396         case I915_BIT_6_SWIZZLE_UNKNOWN:
397                 return "unknown";
398         }
399
400         return "bug";
401 }
402
403 static int i915_swizzle_info(struct seq_file *m, void *data)
404 {
405         struct drm_i915_private *dev_priv = node_to_i915(m->private);
406         struct intel_uncore *uncore = &dev_priv->uncore;
407         intel_wakeref_t wakeref;
408
409         seq_printf(m, "bit6 swizzle for X-tiling = %s\n",
410                    swizzle_string(to_gt(dev_priv)->ggtt->bit_6_swizzle_x));
411         seq_printf(m, "bit6 swizzle for Y-tiling = %s\n",
412                    swizzle_string(to_gt(dev_priv)->ggtt->bit_6_swizzle_y));
413
414         if (dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES)
415                 seq_puts(m, "L-shaped memory detected\n");
416
417         /* On BDW+, swizzling is not used. See detect_bit_6_swizzle() */
418         if (GRAPHICS_VER(dev_priv) >= 8 || IS_VALLEYVIEW(dev_priv))
419                 return 0;
420
421         wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
422
423         if (IS_GRAPHICS_VER(dev_priv, 3, 4)) {
424                 seq_printf(m, "DDC = 0x%08x\n",
425                            intel_uncore_read(uncore, DCC));
426                 seq_printf(m, "DDC2 = 0x%08x\n",
427                            intel_uncore_read(uncore, DCC2));
428                 seq_printf(m, "C0DRB3 = 0x%04x\n",
429                            intel_uncore_read16(uncore, C0DRB3_BW));
430                 seq_printf(m, "C1DRB3 = 0x%04x\n",
431                            intel_uncore_read16(uncore, C1DRB3_BW));
432         } else if (GRAPHICS_VER(dev_priv) >= 6) {
433                 seq_printf(m, "MAD_DIMM_C0 = 0x%08x\n",
434                            intel_uncore_read(uncore, MAD_DIMM_C0));
435                 seq_printf(m, "MAD_DIMM_C1 = 0x%08x\n",
436                            intel_uncore_read(uncore, MAD_DIMM_C1));
437                 seq_printf(m, "MAD_DIMM_C2 = 0x%08x\n",
438                            intel_uncore_read(uncore, MAD_DIMM_C2));
439                 seq_printf(m, "TILECTL = 0x%08x\n",
440                            intel_uncore_read(uncore, TILECTL));
441                 if (GRAPHICS_VER(dev_priv) >= 8)
442                         seq_printf(m, "GAMTARBMODE = 0x%08x\n",
443                                    intel_uncore_read(uncore, GAMTARBMODE));
444                 else
445                         seq_printf(m, "ARB_MODE = 0x%08x\n",
446                                    intel_uncore_read(uncore, ARB_MODE));
447                 seq_printf(m, "DISP_ARB_CTL = 0x%08x\n",
448                            intel_uncore_read(uncore, DISP_ARB_CTL));
449         }
450
451         intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
452
453         return 0;
454 }
455
456 static int i915_rps_boost_info(struct seq_file *m, void *data)
457 {
458         struct drm_i915_private *dev_priv = node_to_i915(m->private);
459         struct intel_rps *rps = &to_gt(dev_priv)->rps;
460
461         seq_printf(m, "RPS enabled? %s\n",
462                    str_yes_no(intel_rps_is_enabled(rps)));
463         seq_printf(m, "RPS active? %s\n",
464                    str_yes_no(intel_rps_is_active(rps)));
465         seq_printf(m, "GPU busy? %s\n", str_yes_no(to_gt(dev_priv)->awake));
466         seq_printf(m, "Boosts outstanding? %d\n",
467                    atomic_read(&rps->num_waiters));
468         seq_printf(m, "Interactive? %d\n", READ_ONCE(rps->power.interactive));
469         seq_printf(m, "Frequency requested %d, actual %d\n",
470                    intel_gpu_freq(rps, rps->cur_freq),
471                    intel_rps_read_actual_frequency(rps));
472         seq_printf(m, "  min hard:%d, soft:%d; max soft:%d, hard:%d\n",
473                    intel_gpu_freq(rps, rps->min_freq),
474                    intel_gpu_freq(rps, rps->min_freq_softlimit),
475                    intel_gpu_freq(rps, rps->max_freq_softlimit),
476                    intel_gpu_freq(rps, rps->max_freq));
477         seq_printf(m, "  idle:%d, efficient:%d, boost:%d\n",
478                    intel_gpu_freq(rps, rps->idle_freq),
479                    intel_gpu_freq(rps, rps->efficient_freq),
480                    intel_gpu_freq(rps, rps->boost_freq));
481
482         seq_printf(m, "Wait boosts: %d\n", READ_ONCE(rps->boosts));
483
484         return 0;
485 }
486
487 static int i915_runtime_pm_status(struct seq_file *m, void *unused)
488 {
489         struct drm_i915_private *dev_priv = node_to_i915(m->private);
490         struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
491
492         if (!HAS_RUNTIME_PM(dev_priv))
493                 seq_puts(m, "Runtime power management not supported\n");
494
495         seq_printf(m, "Runtime power status: %s\n",
496                    str_enabled_disabled(!dev_priv->power_domains.init_wakeref));
497
498         seq_printf(m, "GPU idle: %s\n", str_yes_no(!to_gt(dev_priv)->awake));
499         seq_printf(m, "IRQs disabled: %s\n",
500                    str_yes_no(!intel_irqs_enabled(dev_priv)));
501 #ifdef CONFIG_PM
502         seq_printf(m, "Usage count: %d\n",
503                    atomic_read(&dev_priv->drm.dev->power.usage_count));
504 #else
505         seq_printf(m, "Device Power Management (CONFIG_PM) disabled\n");
506 #endif
507         seq_printf(m, "PCI device power state: %s [%d]\n",
508                    pci_power_name(pdev->current_state),
509                    pdev->current_state);
510
511         if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)) {
512                 struct drm_printer p = drm_seq_file_printer(m);
513
514                 print_intel_runtime_pm_wakeref(&dev_priv->runtime_pm, &p);
515         }
516
517         return 0;
518 }
519
520 static int i915_engine_info(struct seq_file *m, void *unused)
521 {
522         struct drm_i915_private *i915 = node_to_i915(m->private);
523         struct intel_engine_cs *engine;
524         intel_wakeref_t wakeref;
525         struct drm_printer p;
526
527         wakeref = intel_runtime_pm_get(&i915->runtime_pm);
528
529         seq_printf(m, "GT awake? %s [%d], %llums\n",
530                    str_yes_no(to_gt(i915)->awake),
531                    atomic_read(&to_gt(i915)->wakeref.count),
532                    ktime_to_ms(intel_gt_get_awake_time(to_gt(i915))));
533         seq_printf(m, "CS timestamp frequency: %u Hz, %d ns\n",
534                    to_gt(i915)->clock_frequency,
535                    to_gt(i915)->clock_period_ns);
536
537         p = drm_seq_file_printer(m);
538         for_each_uabi_engine(engine, i915)
539                 intel_engine_dump(engine, &p, "%s\n", engine->name);
540
541         intel_gt_show_timelines(to_gt(i915), &p, i915_request_show_with_schedule);
542
543         intel_runtime_pm_put(&i915->runtime_pm, wakeref);
544
545         return 0;
546 }
547
548 static int i915_wa_registers(struct seq_file *m, void *unused)
549 {
550         struct drm_i915_private *i915 = node_to_i915(m->private);
551         struct intel_engine_cs *engine;
552
553         for_each_uabi_engine(engine, i915) {
554                 const struct i915_wa_list *wal = &engine->ctx_wa_list;
555                 const struct i915_wa *wa;
556                 unsigned int count;
557
558                 count = wal->count;
559                 if (!count)
560                         continue;
561
562                 seq_printf(m, "%s: Workarounds applied: %u\n",
563                            engine->name, count);
564
565                 for (wa = wal->list; count--; wa++)
566                         seq_printf(m, "0x%X: 0x%08X, mask: 0x%08X\n",
567                                    i915_mmio_reg_offset(wa->reg),
568                                    wa->set, wa->clr);
569
570                 seq_printf(m, "\n");
571         }
572
573         return 0;
574 }
575
576 static int i915_wedged_get(void *data, u64 *val)
577 {
578         struct drm_i915_private *i915 = data;
579
580         return intel_gt_debugfs_reset_show(to_gt(i915), val);
581 }
582
583 static int i915_wedged_set(void *data, u64 val)
584 {
585         struct drm_i915_private *i915 = data;
586         intel_gt_debugfs_reset_store(to_gt(i915), val);
587
588         return 0;
589 }
590
591 DEFINE_SIMPLE_ATTRIBUTE(i915_wedged_fops,
592                         i915_wedged_get, i915_wedged_set,
593                         "%llu\n");
594
595 static int
596 i915_perf_noa_delay_set(void *data, u64 val)
597 {
598         struct drm_i915_private *i915 = data;
599
600         /*
601          * This would lead to infinite waits as we're doing timestamp
602          * difference on the CS with only 32bits.
603          */
604         if (intel_gt_ns_to_clock_interval(to_gt(i915), val) > U32_MAX)
605                 return -EINVAL;
606
607         atomic64_set(&i915->perf.noa_programming_delay, val);
608         return 0;
609 }
610
611 static int
612 i915_perf_noa_delay_get(void *data, u64 *val)
613 {
614         struct drm_i915_private *i915 = data;
615
616         *val = atomic64_read(&i915->perf.noa_programming_delay);
617         return 0;
618 }
619
620 DEFINE_SIMPLE_ATTRIBUTE(i915_perf_noa_delay_fops,
621                         i915_perf_noa_delay_get,
622                         i915_perf_noa_delay_set,
623                         "%llu\n");
624
625 #define DROP_UNBOUND    BIT(0)
626 #define DROP_BOUND      BIT(1)
627 #define DROP_RETIRE     BIT(2)
628 #define DROP_ACTIVE     BIT(3)
629 #define DROP_FREED      BIT(4)
630 #define DROP_SHRINK_ALL BIT(5)
631 #define DROP_IDLE       BIT(6)
632 #define DROP_RESET_ACTIVE       BIT(7)
633 #define DROP_RESET_SEQNO        BIT(8)
634 #define DROP_RCU        BIT(9)
635 #define DROP_ALL (DROP_UNBOUND  | \
636                   DROP_BOUND    | \
637                   DROP_RETIRE   | \
638                   DROP_ACTIVE   | \
639                   DROP_FREED    | \
640                   DROP_SHRINK_ALL |\
641                   DROP_IDLE     | \
642                   DROP_RESET_ACTIVE | \
643                   DROP_RESET_SEQNO | \
644                   DROP_RCU)
645 static int
646 i915_drop_caches_get(void *data, u64 *val)
647 {
648         *val = DROP_ALL;
649
650         return 0;
651 }
652 static int
653 gt_drop_caches(struct intel_gt *gt, u64 val)
654 {
655         int ret;
656
657         if (val & DROP_RESET_ACTIVE &&
658             wait_for(intel_engines_are_idle(gt), I915_IDLE_ENGINES_TIMEOUT))
659                 intel_gt_set_wedged(gt);
660
661         if (val & DROP_RETIRE)
662                 intel_gt_retire_requests(gt);
663
664         if (val & (DROP_IDLE | DROP_ACTIVE)) {
665                 ret = intel_gt_wait_for_idle(gt, MAX_SCHEDULE_TIMEOUT);
666                 if (ret)
667                         return ret;
668         }
669
670         if (val & DROP_IDLE) {
671                 ret = intel_gt_pm_wait_for_idle(gt);
672                 if (ret)
673                         return ret;
674         }
675
676         if (val & DROP_RESET_ACTIVE && intel_gt_terminally_wedged(gt))
677                 intel_gt_handle_error(gt, ALL_ENGINES, 0, NULL);
678
679         if (val & DROP_FREED)
680                 intel_gt_flush_buffer_pool(gt);
681
682         return 0;
683 }
684
685 static int
686 i915_drop_caches_set(void *data, u64 val)
687 {
688         struct drm_i915_private *i915 = data;
689         unsigned int flags;
690         int ret;
691
692         DRM_DEBUG("Dropping caches: 0x%08llx [0x%08llx]\n",
693                   val, val & DROP_ALL);
694
695         ret = gt_drop_caches(to_gt(i915), val);
696         if (ret)
697                 return ret;
698
699         fs_reclaim_acquire(GFP_KERNEL);
700         flags = memalloc_noreclaim_save();
701         if (val & DROP_BOUND)
702                 i915_gem_shrink(NULL, i915, LONG_MAX, NULL, I915_SHRINK_BOUND);
703
704         if (val & DROP_UNBOUND)
705                 i915_gem_shrink(NULL, i915, LONG_MAX, NULL, I915_SHRINK_UNBOUND);
706
707         if (val & DROP_SHRINK_ALL)
708                 i915_gem_shrink_all(i915);
709         memalloc_noreclaim_restore(flags);
710         fs_reclaim_release(GFP_KERNEL);
711
712         if (val & DROP_RCU)
713                 rcu_barrier();
714
715         if (val & DROP_FREED)
716                 i915_gem_drain_freed_objects(i915);
717
718         return 0;
719 }
720
721 DEFINE_SIMPLE_ATTRIBUTE(i915_drop_caches_fops,
722                         i915_drop_caches_get, i915_drop_caches_set,
723                         "0x%08llx\n");
724
725 static int i915_sseu_status(struct seq_file *m, void *unused)
726 {
727         struct drm_i915_private *i915 = node_to_i915(m->private);
728         struct intel_gt *gt = to_gt(i915);
729
730         return intel_sseu_status(m, gt);
731 }
732
733 static int i915_forcewake_open(struct inode *inode, struct file *file)
734 {
735         struct drm_i915_private *i915 = inode->i_private;
736         intel_gt_pm_debugfs_forcewake_user_open(to_gt(i915));
737
738         return 0;
739 }
740
741 static int i915_forcewake_release(struct inode *inode, struct file *file)
742 {
743         struct drm_i915_private *i915 = inode->i_private;
744         intel_gt_pm_debugfs_forcewake_user_release(to_gt(i915));
745
746         return 0;
747 }
748
749 static const struct file_operations i915_forcewake_fops = {
750         .owner = THIS_MODULE,
751         .open = i915_forcewake_open,
752         .release = i915_forcewake_release,
753 };
754
755 static const struct drm_info_list i915_debugfs_list[] = {
756         {"i915_capabilities", i915_capabilities, 0},
757         {"i915_gem_objects", i915_gem_object_info, 0},
758         {"i915_frequency_info", i915_frequency_info, 0},
759         {"i915_swizzle_info", i915_swizzle_info, 0},
760         {"i915_runtime_pm_status", i915_runtime_pm_status, 0},
761         {"i915_engine_info", i915_engine_info, 0},
762         {"i915_wa_registers", i915_wa_registers, 0},
763         {"i915_sseu_status", i915_sseu_status, 0},
764         {"i915_rps_boost_info", i915_rps_boost_info, 0},
765 };
766 #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
767
768 static const struct i915_debugfs_files {
769         const char *name;
770         const struct file_operations *fops;
771 } i915_debugfs_files[] = {
772         {"i915_perf_noa_delay", &i915_perf_noa_delay_fops},
773         {"i915_wedged", &i915_wedged_fops},
774         {"i915_gem_drop_caches", &i915_drop_caches_fops},
775 #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
776         {"i915_error_state", &i915_error_state_fops},
777         {"i915_gpu_info", &i915_gpu_info_fops},
778 #endif
779 };
780
781 void i915_debugfs_register(struct drm_i915_private *dev_priv)
782 {
783         struct drm_minor *minor = dev_priv->drm.primary;
784         int i;
785
786         i915_debugfs_params(dev_priv);
787
788         debugfs_create_file("i915_forcewake_user", S_IRUSR, minor->debugfs_root,
789                             to_i915(minor->dev), &i915_forcewake_fops);
790         for (i = 0; i < ARRAY_SIZE(i915_debugfs_files); i++) {
791                 debugfs_create_file(i915_debugfs_files[i].name,
792                                     S_IRUGO | S_IWUSR,
793                                     minor->debugfs_root,
794                                     to_i915(minor->dev),
795                                     i915_debugfs_files[i].fops);
796         }
797
798         drm_debugfs_create_files(i915_debugfs_list,
799                                  I915_DEBUGFS_ENTRIES,
800                                  minor->debugfs_root, minor);
801 }
This page took 0.081584 seconds and 4 git commands to generate.