From patchwork Sat Aug 3 01:09:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Daniele Ceraolo Spurio X-Patchwork-Id: 11074265 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 928B614DB for ; Sat, 3 Aug 2019 01:11:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 845102885F for ; Sat, 3 Aug 2019 01:11:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 77C0C288EA; Sat, 3 Aug 2019 01:11:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 22F812885F for ; Sat, 3 Aug 2019 01:11:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 82E406E365; Sat, 3 Aug 2019 01:11:43 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4E6E96E365 for ; Sat, 3 Aug 2019 01:11:41 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Aug 2019 18:11:40 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,340,1559545200"; d="scan'208";a="257146529" Received: from dceraolo-linux.fm.intel.com ([10.1.27.145]) by orsmga001.jf.intel.com with ESMTP; 02 Aug 2019 18:11:40 -0700 From: Daniele Ceraolo Spurio To: intel-gfx@lists.freedesktop.org Date: Fri, 2 Aug 2019 18:09:44 -0700 Message-Id: <20190803010944.10169-1-daniele.ceraolospurio@intel.com> X-Mailer: git-send-email 2.22.0 MIME-Version: 1.0 Subject: [Intel-gfx] [RFC] drm/i915/gt: create a subfolder for GT debugfs X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP The idea is to better organize our debugfs entries by moving the GT-related ones into their own subfolder, similarly to what we did for the kernel code. As an example, this patch moves the GuC/HuC and user_forcewake debugfs, but a few more files can be moved if we decide to go this way (engine status, gt_pm etc). Test updates will also be required to look for the file in the correct place. Very lightly tested and still a bit rough around the edges. Signed-off-by: Daniele Ceraolo Spurio Cc: Chris Wilson Cc: Tvrtko Ursulin --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/gt/intel_gt.h | 7 + drivers/gpu/drm/i915/gt/intel_gt_debugfs.c | 403 +++++++++++++++++++++ drivers/gpu/drm/i915/i915_debugfs.c | 349 +----------------- 4 files changed, 414 insertions(+), 346 deletions(-) create mode 100644 drivers/gpu/drm/i915/gt/intel_gt_debugfs.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 331b19cc8247..7c4108af966f 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -74,6 +74,7 @@ gt-y += \ gt/intel_engine_cs.o \ gt/intel_engine_pm.o \ gt/intel_gt.o \ + gt/intel_gt_debugfs.o \ gt/intel_gt_pm.o \ gt/intel_hangcheck.o \ gt/intel_lrc.o \ diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h b/drivers/gpu/drm/i915/gt/intel_gt.h index 4920cb351f10..68c7d152ff01 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.h +++ b/drivers/gpu/drm/i915/gt/intel_gt.h @@ -11,6 +11,7 @@ #include "intel_reset.h" struct drm_i915_private; +struct dentry; static inline struct intel_gt *uc_to_gt(struct intel_uc *uc) { @@ -57,4 +58,10 @@ static inline bool intel_gt_is_wedged(struct intel_gt *gt) void intel_gt_queue_hangcheck(struct intel_gt *gt); +#ifdef CONFIG_DEBUG_FS +void intel_gt_debugfs_register(struct intel_gt *gt, struct dentry *root); +#else +void intel_gt_debugfs_register(struct intel_gt *gt, struct dentry *root) { return }; +#endif + #endif /* __INTEL_GT_H__ */ diff --git a/drivers/gpu/drm/i915/gt/intel_gt_debugfs.c b/drivers/gpu/drm/i915/gt/intel_gt_debugfs.c new file mode 100644 index 000000000000..4b2f40132e7a --- /dev/null +++ b/drivers/gpu/drm/i915/gt/intel_gt_debugfs.c @@ -0,0 +1,403 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2019 Intel Corporation + */ + +#include "intel_gt.h" +#include "intel_runtime_pm.h" +#include "gt/uc/intel_guc_submission.h" + +#include "i915_drv.h" + +#define DEFINE_GT_SHOW_ATTRIBUTE(x_) \ +DEFINE_SHOW_ATTRIBUTE(x_); \ +static const umode_t x_##_mode = S_IRUGO; + +#define DEFINE_GT_SIMPLE_ATTRIBUTE(x_, format_) \ +DEFINE_SIMPLE_ATTRIBUTE(x_##_fops, x_##_get, x_##_set, format_); \ +static const umode_t x_##_mode = S_IRUGO | S_IWUSR; + +static int i915_huc_load_status_show(struct seq_file *m, void *data) +{ + struct intel_gt *gt = m->private; + intel_wakeref_t wakeref; + struct drm_printer p; + + if (!HAS_GT_UC(gt->i915)) + return -ENODEV; + + p = drm_seq_file_printer(m); + intel_uc_fw_dump(>->uc.huc.fw, &p); + + with_intel_runtime_pm(>->i915->runtime_pm, wakeref) + seq_printf(m, "\nHuC status 0x%08x:\n", + intel_uncore_read(gt->uncore, HUC_STATUS2)); + + return 0; +} +DEFINE_GT_SHOW_ATTRIBUTE(i915_huc_load_status); + +static int i915_guc_load_status_show(struct seq_file *m, void *data) +{ + struct intel_gt *gt = m->private; + intel_wakeref_t wakeref; + struct drm_printer p; + + if (!HAS_GT_UC(gt->i915)) + return -ENODEV; + + p = drm_seq_file_printer(m); + intel_uc_fw_dump(>->uc.guc.fw, &p); + + with_intel_runtime_pm(>->i915->runtime_pm, wakeref) { + u32 tmp = intel_uncore_read(gt->uncore, GUC_STATUS); + u32 i; + + seq_printf(m, "\nGuC status 0x%08x:\n", tmp); + seq_printf(m, "\tBootrom status = 0x%x\n", + (tmp & GS_BOOTROM_MASK) >> GS_BOOTROM_SHIFT); + seq_printf(m, "\tuKernel status = 0x%x\n", + (tmp & GS_UKERNEL_MASK) >> GS_UKERNEL_SHIFT); + seq_printf(m, "\tMIA Core status = 0x%x\n", + (tmp & GS_MIA_MASK) >> GS_MIA_SHIFT); + seq_puts(m, "\nScratch registers:\n"); + for (i = 0; i < 16; i++) { + seq_printf(m, "\t%2d: \t0x%x\n", + i, intel_uncore_read(gt->uncore, SOFT_SCRATCH(i))); + } + } + + return 0; +} +DEFINE_GT_SHOW_ATTRIBUTE(i915_guc_load_status); + +static const char * +stringify_guc_log_type(enum guc_log_buffer_type type) +{ + switch (type) { + case GUC_ISR_LOG_BUFFER: + return "ISR"; + case GUC_DPC_LOG_BUFFER: + return "DPC"; + case GUC_CRASH_DUMP_LOG_BUFFER: + return "CRASH"; + default: + MISSING_CASE(type); + } + + return ""; +} + +static void i915_guc_log_info(struct seq_file *m, + struct intel_gt *gt) +{ + struct intel_guc_log *log = >->uc.guc.log; + enum guc_log_buffer_type type; + + if (!intel_guc_log_relay_enabled(log)) { + seq_puts(m, "GuC log relay disabled\n"); + return; + } + + seq_puts(m, "GuC logging stats:\n"); + + seq_printf(m, "\tRelay full count: %u\n", + log->relay.full_count); + + for (type = GUC_ISR_LOG_BUFFER; type < GUC_MAX_LOG_BUFFER; type++) { + seq_printf(m, "\t%s:\tflush count %10u, overflow count %10u\n", + stringify_guc_log_type(type), + log->stats[type].flush, + log->stats[type].sampled_overflow); + } +} + +static void i915_guc_client_info(struct seq_file *m, + struct intel_gt *gt, + struct intel_guc_client *client) +{ + struct intel_engine_cs *engine; + enum intel_engine_id id; + u64 tot = 0; + + seq_printf(m, "\tPriority %d, GuC stage index: %u, PD offset 0x%x\n", + client->priority, client->stage_id, client->proc_desc_offset); + seq_printf(m, "\tDoorbell id %d, offset: 0x%lx\n", + client->doorbell_id, client->doorbell_offset); + + for_each_engine(engine, gt->i915, id) { + u64 submissions = client->submissions[id]; + tot += submissions; + seq_printf(m, "\tSubmissions: %llu %s\n", + submissions, engine->name); + } + seq_printf(m, "\tTotal: %llu\n", tot); +} + +static int i915_guc_info_show(struct seq_file *m, void *data) +{ + struct intel_gt *gt = m->private; + const struct intel_guc *guc = >->uc.guc; + + if (!intel_uc_supports_guc(>->uc)) + return -ENODEV; + + i915_guc_log_info(m, gt); + + if (!intel_uc_supports_guc_submission(>->uc)) + return 0; + + GEM_BUG_ON(!guc->execbuf_client); + + seq_printf(m, "\nDoorbell map:\n"); + seq_printf(m, "\t%*pb\n", GUC_NUM_DOORBELLS, guc->doorbell_bitmap); + seq_printf(m, "Doorbell next cacheline: 0x%x\n", guc->db_cacheline); + + seq_printf(m, "\nGuC execbuf client @ %p:\n", guc->execbuf_client); + i915_guc_client_info(m, gt, guc->execbuf_client); + + /* Add more as required ... */ + + return 0; +} +DEFINE_GT_SHOW_ATTRIBUTE(i915_guc_info); + +static int i915_guc_stage_pool_show(struct seq_file *m, void *data) +{ + struct intel_gt *gt = m->private; + const struct intel_guc *guc = >->uc.guc; + struct guc_stage_desc *desc = guc->stage_desc_pool_vaddr; + intel_engine_mask_t tmp; + int index; + + if (!intel_uc_supports_guc_submission(>->uc)) + return -ENODEV; + + for (index = 0; index < GUC_MAX_STAGE_DESCRIPTORS; index++, desc++) { + struct intel_engine_cs *engine; + + if (!(desc->attribute & GUC_STAGE_DESC_ATTR_ACTIVE)) + continue; + + seq_printf(m, "GuC stage descriptor %u:\n", index); + seq_printf(m, "\tIndex: %u\n", desc->stage_id); + seq_printf(m, "\tAttribute: 0x%x\n", desc->attribute); + seq_printf(m, "\tPriority: %d\n", desc->priority); + seq_printf(m, "\tDoorbell id: %d\n", desc->db_id); + seq_printf(m, "\tEngines used: 0x%x\n", + desc->engines_used); + seq_printf(m, "\tDoorbell trigger phy: 0x%llx, cpu: 0x%llx, uK: 0x%x\n", + desc->db_trigger_phy, + desc->db_trigger_cpu, + desc->db_trigger_uk); + seq_printf(m, "\tProcess descriptor: 0x%x\n", + desc->process_desc); + seq_printf(m, "\tWorkqueue address: 0x%x, size: 0x%x\n", + desc->wq_addr, desc->wq_size); + seq_putc(m, '\n'); + + for_each_engine(engine, gt->i915, tmp) { + u32 guc_engine_id = engine->guc_id; + struct guc_execlist_context *lrc = + &desc->lrc[guc_engine_id]; + + seq_printf(m, "\t%s LRC:\n", engine->name); + seq_printf(m, "\t\tContext desc: 0x%x\n", + lrc->context_desc); + seq_printf(m, "\t\tContext id: 0x%x\n", lrc->context_id); + seq_printf(m, "\t\tLRCA: 0x%x\n", lrc->ring_lrca); + seq_printf(m, "\t\tRing begin: 0x%x\n", lrc->ring_begin); + seq_printf(m, "\t\tRing end: 0x%x\n", lrc->ring_end); + seq_putc(m, '\n'); + } + } + + return 0; +} +DEFINE_GT_SHOW_ATTRIBUTE(i915_guc_stage_pool); + +static int i915_guc_log_dump(struct seq_file *m, bool dump_load_err) +{ + struct intel_gt *gt = m->private; + struct drm_i915_gem_object *obj = NULL; + u32 *log; + int i = 0; + + if (!HAS_GT_UC(gt->i915)) + return -ENODEV; + + if (dump_load_err) + obj = gt->uc.load_err_log; + else if (gt->uc.guc.log.vma) + obj = gt->uc.guc.log.vma->obj; + + if (!obj) + return 0; + + log = i915_gem_object_pin_map(obj, I915_MAP_WC); + if (IS_ERR(log)) { + DRM_DEBUG("Failed to pin object\n"); + seq_puts(m, "(log data unaccessible)\n"); + return PTR_ERR(log); + } + + for (i = 0; i < obj->base.size / sizeof(u32); i += 4) + seq_printf(m, "0x%08x 0x%08x 0x%08x 0x%08x\n", + *(log + i), *(log + i + 1), + *(log + i + 2), *(log + i + 3)); + + seq_putc(m, '\n'); + + i915_gem_object_unpin_map(obj); + + return 0; +} + +static int i915_guc_log_dump_show(struct seq_file *m, void *data) +{ + return i915_guc_log_dump(m, false); +} +DEFINE_GT_SHOW_ATTRIBUTE(i915_guc_log_dump); + +static int i915_guc_load_err_log_dump_show(struct seq_file *m, void *data) +{ + return i915_guc_log_dump(m, true); +} +DEFINE_GT_SHOW_ATTRIBUTE(i915_guc_load_err_log_dump); + +static int i915_guc_log_level_get(void *data, u64 *val) +{ + struct intel_gt *gt = data; + + if (!intel_uc_supports_guc(>->uc)) + return -ENODEV; + + *val = intel_guc_log_get_level(>->uc.guc.log); + + return 0; +} + +static int i915_guc_log_level_set(void *data, u64 val) +{ + struct intel_gt *gt = data; + + if (!intel_uc_supports_guc(>->uc)) + return -ENODEV; + + return intel_guc_log_set_level(>->uc.guc.log, val); +} +DEFINE_GT_SIMPLE_ATTRIBUTE(i915_guc_log_level, "%lld\n"); + +static int i915_guc_log_relay_open(struct inode *inode, struct file *file) +{ + struct intel_gt *gt = inode->i_private; + + if (!intel_uc_supports_guc(>->uc)) + return -ENODEV; + + file->private_data = >->uc.guc.log; + + return intel_guc_log_relay_open(>->uc.guc.log); +} + +static ssize_t +i915_guc_log_relay_write(struct file *filp, + const char __user *ubuf, + size_t cnt, + loff_t *ppos) +{ + struct intel_guc_log *log = filp->private_data; + + intel_guc_log_relay_flush(log); + + return cnt; +} + +static int i915_guc_log_relay_release(struct inode *inode, struct file *file) +{ + struct intel_gt *gt = inode->i_private; + + intel_guc_log_relay_close(>->uc.guc.log); + + return 0; +} + +static const struct file_operations i915_guc_log_relay_fops = { + .owner = THIS_MODULE, + .open = i915_guc_log_relay_open, + .write = i915_guc_log_relay_write, + .release = i915_guc_log_relay_release, +}; +#define i915_guc_log_relay_mode (S_IRUGO | S_IWUSR) + +static int i915_forcewake_open(struct inode *inode, struct file *file) +{ + struct intel_gt *gt = inode->i_private; + struct intel_uncore *uncore = gt->uncore; + + if (!intel_uncore_has_forcewake(uncore)) + return 0; + + file->private_data = + (void *)(uintptr_t)intel_runtime_pm_get(uncore->rpm); + intel_uncore_forcewake_user_get(uncore); + + return 0; +} + +static int i915_forcewake_release(struct inode *inode, struct file *file) +{ + struct intel_gt *gt = inode->i_private; + struct intel_uncore *uncore = gt->uncore; + + if (!intel_uncore_has_forcewake(uncore)) + return 0; + + intel_uncore_forcewake_user_put(uncore); + intel_runtime_pm_put(uncore->rpm, + (intel_wakeref_t)(uintptr_t)file->private_data); + + return 0; +} + +static const struct file_operations i915_forcewake_user_fops = { + .owner = THIS_MODULE, + .open = i915_forcewake_open, + .release = i915_forcewake_release, +}; +#define i915_forcewake_user_mode S_IRUSR + +#define GT_DEBUGFS(name__) { #name__, &name__##_fops, name__##_mode } +static const struct { + const char *name; + const struct file_operations *fops; + umode_t mode; +#define GT_DEBUGFS(name__) { #name__, &name__##_fops, name__##_mode } +} gt_debugfs_list[] = { + GT_DEBUGFS(i915_guc_info), + GT_DEBUGFS(i915_guc_load_status), + GT_DEBUGFS(i915_guc_log_dump), + GT_DEBUGFS(i915_guc_load_err_log_dump), + GT_DEBUGFS(i915_guc_stage_pool), + GT_DEBUGFS(i915_huc_load_status), + GT_DEBUGFS(i915_guc_log_level), + GT_DEBUGFS(i915_guc_log_relay), + GT_DEBUGFS(i915_forcewake_user), +}; + +void intel_gt_debugfs_register(struct intel_gt *gt, struct dentry *root) +{ + int i; + struct dentry *gt_dentry; + + gt_dentry = debugfs_create_dir("gt", root); + if (WARN_ON(!gt_dentry)) + return; + + for (i = 0; i < ARRAY_SIZE(gt_debugfs_list); i++) { + debugfs_create_file(gt_debugfs_list[i].name, + gt_debugfs_list[i].mode, + gt_dentry, gt, + gt_debugfs_list[i].fops); + } +} diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 461a8dd4cc47..f31ca9eae015 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -39,8 +39,8 @@ #include "display/intel_psr.h" #include "gem/i915_gem_context.h" +#include "gt/intel_gt.h" #include "gt/intel_reset.h" -#include "gt/uc/intel_guc_submission.h" #include "i915_debugfs.h" #include "i915_irq.h" @@ -1859,306 +1859,6 @@ static int i915_llc(struct seq_file *m, void *data) return 0; } -static int i915_huc_load_status_info(struct seq_file *m, void *data) -{ - struct drm_i915_private *dev_priv = node_to_i915(m->private); - intel_wakeref_t wakeref; - struct drm_printer p; - - if (!HAS_GT_UC(dev_priv)) - return -ENODEV; - - p = drm_seq_file_printer(m); - intel_uc_fw_dump(&dev_priv->gt.uc.huc.fw, &p); - - with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) - seq_printf(m, "\nHuC status 0x%08x:\n", I915_READ(HUC_STATUS2)); - - return 0; -} - -static int i915_guc_load_status_info(struct seq_file *m, void *data) -{ - struct drm_i915_private *dev_priv = node_to_i915(m->private); - intel_wakeref_t wakeref; - struct drm_printer p; - - if (!HAS_GT_UC(dev_priv)) - return -ENODEV; - - p = drm_seq_file_printer(m); - intel_uc_fw_dump(&dev_priv->gt.uc.guc.fw, &p); - - with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) { - u32 tmp = I915_READ(GUC_STATUS); - u32 i; - - seq_printf(m, "\nGuC status 0x%08x:\n", tmp); - seq_printf(m, "\tBootrom status = 0x%x\n", - (tmp & GS_BOOTROM_MASK) >> GS_BOOTROM_SHIFT); - seq_printf(m, "\tuKernel status = 0x%x\n", - (tmp & GS_UKERNEL_MASK) >> GS_UKERNEL_SHIFT); - seq_printf(m, "\tMIA Core status = 0x%x\n", - (tmp & GS_MIA_MASK) >> GS_MIA_SHIFT); - seq_puts(m, "\nScratch registers:\n"); - for (i = 0; i < 16; i++) { - seq_printf(m, "\t%2d: \t0x%x\n", - i, I915_READ(SOFT_SCRATCH(i))); - } - } - - return 0; -} - -static const char * -stringify_guc_log_type(enum guc_log_buffer_type type) -{ - switch (type) { - case GUC_ISR_LOG_BUFFER: - return "ISR"; - case GUC_DPC_LOG_BUFFER: - return "DPC"; - case GUC_CRASH_DUMP_LOG_BUFFER: - return "CRASH"; - default: - MISSING_CASE(type); - } - - return ""; -} - -static void i915_guc_log_info(struct seq_file *m, - struct drm_i915_private *dev_priv) -{ - struct intel_guc_log *log = &dev_priv->gt.uc.guc.log; - enum guc_log_buffer_type type; - - if (!intel_guc_log_relay_enabled(log)) { - seq_puts(m, "GuC log relay disabled\n"); - return; - } - - seq_puts(m, "GuC logging stats:\n"); - - seq_printf(m, "\tRelay full count: %u\n", - log->relay.full_count); - - for (type = GUC_ISR_LOG_BUFFER; type < GUC_MAX_LOG_BUFFER; type++) { - seq_printf(m, "\t%s:\tflush count %10u, overflow count %10u\n", - stringify_guc_log_type(type), - log->stats[type].flush, - log->stats[type].sampled_overflow); - } -} - -static void i915_guc_client_info(struct seq_file *m, - struct drm_i915_private *dev_priv, - struct intel_guc_client *client) -{ - struct intel_engine_cs *engine; - enum intel_engine_id id; - u64 tot = 0; - - seq_printf(m, "\tPriority %d, GuC stage index: %u, PD offset 0x%x\n", - client->priority, client->stage_id, client->proc_desc_offset); - seq_printf(m, "\tDoorbell id %d, offset: 0x%lx\n", - client->doorbell_id, client->doorbell_offset); - - for_each_engine(engine, dev_priv, id) { - u64 submissions = client->submissions[id]; - tot += submissions; - seq_printf(m, "\tSubmissions: %llu %s\n", - submissions, engine->name); - } - seq_printf(m, "\tTotal: %llu\n", tot); -} - -static int i915_guc_info(struct seq_file *m, void *data) -{ - struct drm_i915_private *dev_priv = node_to_i915(m->private); - const struct intel_guc *guc = &dev_priv->gt.uc.guc; - - if (!USES_GUC(dev_priv)) - return -ENODEV; - - i915_guc_log_info(m, dev_priv); - - if (!USES_GUC_SUBMISSION(dev_priv)) - return 0; - - GEM_BUG_ON(!guc->execbuf_client); - - seq_printf(m, "\nDoorbell map:\n"); - seq_printf(m, "\t%*pb\n", GUC_NUM_DOORBELLS, guc->doorbell_bitmap); - seq_printf(m, "Doorbell next cacheline: 0x%x\n", guc->db_cacheline); - - seq_printf(m, "\nGuC execbuf client @ %p:\n", guc->execbuf_client); - i915_guc_client_info(m, dev_priv, guc->execbuf_client); - - /* Add more as required ... */ - - return 0; -} - -static int i915_guc_stage_pool(struct seq_file *m, void *data) -{ - struct drm_i915_private *dev_priv = node_to_i915(m->private); - const struct intel_guc *guc = &dev_priv->gt.uc.guc; - struct guc_stage_desc *desc = guc->stage_desc_pool_vaddr; - intel_engine_mask_t tmp; - int index; - - if (!USES_GUC_SUBMISSION(dev_priv)) - return -ENODEV; - - for (index = 0; index < GUC_MAX_STAGE_DESCRIPTORS; index++, desc++) { - struct intel_engine_cs *engine; - - if (!(desc->attribute & GUC_STAGE_DESC_ATTR_ACTIVE)) - continue; - - seq_printf(m, "GuC stage descriptor %u:\n", index); - seq_printf(m, "\tIndex: %u\n", desc->stage_id); - seq_printf(m, "\tAttribute: 0x%x\n", desc->attribute); - seq_printf(m, "\tPriority: %d\n", desc->priority); - seq_printf(m, "\tDoorbell id: %d\n", desc->db_id); - seq_printf(m, "\tEngines used: 0x%x\n", - desc->engines_used); - seq_printf(m, "\tDoorbell trigger phy: 0x%llx, cpu: 0x%llx, uK: 0x%x\n", - desc->db_trigger_phy, - desc->db_trigger_cpu, - desc->db_trigger_uk); - seq_printf(m, "\tProcess descriptor: 0x%x\n", - desc->process_desc); - seq_printf(m, "\tWorkqueue address: 0x%x, size: 0x%x\n", - desc->wq_addr, desc->wq_size); - seq_putc(m, '\n'); - - for_each_engine(engine, dev_priv, tmp) { - u32 guc_engine_id = engine->guc_id; - struct guc_execlist_context *lrc = - &desc->lrc[guc_engine_id]; - - seq_printf(m, "\t%s LRC:\n", engine->name); - seq_printf(m, "\t\tContext desc: 0x%x\n", - lrc->context_desc); - seq_printf(m, "\t\tContext id: 0x%x\n", lrc->context_id); - seq_printf(m, "\t\tLRCA: 0x%x\n", lrc->ring_lrca); - seq_printf(m, "\t\tRing begin: 0x%x\n", lrc->ring_begin); - seq_printf(m, "\t\tRing end: 0x%x\n", lrc->ring_end); - seq_putc(m, '\n'); - } - } - - return 0; -} - -static int i915_guc_log_dump(struct seq_file *m, void *data) -{ - struct drm_info_node *node = m->private; - struct drm_i915_private *dev_priv = node_to_i915(node); - bool dump_load_err = !!node->info_ent->data; - struct drm_i915_gem_object *obj = NULL; - u32 *log; - int i = 0; - - if (!HAS_GT_UC(dev_priv)) - return -ENODEV; - - if (dump_load_err) - obj = dev_priv->gt.uc.load_err_log; - else if (dev_priv->gt.uc.guc.log.vma) - obj = dev_priv->gt.uc.guc.log.vma->obj; - - if (!obj) - return 0; - - log = i915_gem_object_pin_map(obj, I915_MAP_WC); - if (IS_ERR(log)) { - DRM_DEBUG("Failed to pin object\n"); - seq_puts(m, "(log data unaccessible)\n"); - return PTR_ERR(log); - } - - for (i = 0; i < obj->base.size / sizeof(u32); i += 4) - seq_printf(m, "0x%08x 0x%08x 0x%08x 0x%08x\n", - *(log + i), *(log + i + 1), - *(log + i + 2), *(log + i + 3)); - - seq_putc(m, '\n'); - - i915_gem_object_unpin_map(obj); - - return 0; -} - -static int i915_guc_log_level_get(void *data, u64 *val) -{ - struct drm_i915_private *dev_priv = data; - - if (!USES_GUC(dev_priv)) - return -ENODEV; - - *val = intel_guc_log_get_level(&dev_priv->gt.uc.guc.log); - - return 0; -} - -static int i915_guc_log_level_set(void *data, u64 val) -{ - struct drm_i915_private *dev_priv = data; - - if (!USES_GUC(dev_priv)) - return -ENODEV; - - return intel_guc_log_set_level(&dev_priv->gt.uc.guc.log, val); -} - -DEFINE_SIMPLE_ATTRIBUTE(i915_guc_log_level_fops, - i915_guc_log_level_get, i915_guc_log_level_set, - "%lld\n"); - -static int i915_guc_log_relay_open(struct inode *inode, struct file *file) -{ - struct drm_i915_private *dev_priv = inode->i_private; - - if (!USES_GUC(dev_priv)) - return -ENODEV; - - file->private_data = &dev_priv->gt.uc.guc.log; - - return intel_guc_log_relay_open(&dev_priv->gt.uc.guc.log); -} - -static ssize_t -i915_guc_log_relay_write(struct file *filp, - const char __user *ubuf, - size_t cnt, - loff_t *ppos) -{ - struct intel_guc_log *log = filp->private_data; - - intel_guc_log_relay_flush(log); - - return cnt; -} - -static int i915_guc_log_relay_release(struct inode *inode, struct file *file) -{ - struct drm_i915_private *dev_priv = inode->i_private; - - intel_guc_log_relay_close(&dev_priv->gt.uc.guc.log); - - return 0; -} - -static const struct file_operations i915_guc_log_relay_fops = { - .owner = THIS_MODULE, - .open = i915_guc_log_relay_open, - .write = i915_guc_log_relay_write, - .release = i915_guc_log_relay_release, -}; - static int i915_psr_sink_status_show(struct seq_file *m, void *data) { u8 val; @@ -4059,40 +3759,6 @@ static int i915_sseu_status(struct seq_file *m, void *unused) return 0; } -static int i915_forcewake_open(struct inode *inode, struct file *file) -{ - struct drm_i915_private *i915 = inode->i_private; - - if (INTEL_GEN(i915) < 6) - return 0; - - file->private_data = - (void *)(uintptr_t)intel_runtime_pm_get(&i915->runtime_pm); - intel_uncore_forcewake_user_get(&i915->uncore); - - return 0; -} - -static int i915_forcewake_release(struct inode *inode, struct file *file) -{ - struct drm_i915_private *i915 = inode->i_private; - - if (INTEL_GEN(i915) < 6) - return 0; - - intel_uncore_forcewake_user_put(&i915->uncore); - intel_runtime_pm_put(&i915->runtime_pm, - (intel_wakeref_t)(uintptr_t)file->private_data); - - return 0; -} - -static const struct file_operations i915_forcewake_fops = { - .owner = THIS_MODULE, - .open = i915_forcewake_open, - .release = i915_forcewake_release, -}; - static int i915_hpd_storm_ctl_show(struct seq_file *m, void *data) { struct drm_i915_private *dev_priv = m->private; @@ -4385,12 +4051,6 @@ static const struct drm_info_list i915_debugfs_list[] = { {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, {"i915_gem_interrupt", i915_interrupt_info, 0}, {"i915_gem_batch_pool", i915_gem_batch_pool_info, 0}, - {"i915_guc_info", i915_guc_info, 0}, - {"i915_guc_load_status", i915_guc_load_status_info, 0}, - {"i915_guc_log_dump", i915_guc_log_dump, 0}, - {"i915_guc_load_err_log_dump", i915_guc_log_dump, 0, (void *)1}, - {"i915_guc_stage_pool", i915_guc_stage_pool, 0}, - {"i915_huc_load_status", i915_huc_load_status_info, 0}, {"i915_frequency_info", i915_frequency_info, 0}, {"i915_hangcheck_info", i915_hangcheck_info, 0}, {"i915_drpc_info", i915_drpc_info, 0}, @@ -4445,8 +4105,6 @@ static const struct i915_debugfs_files { {"i915_dp_test_data", &i915_displayport_test_data_fops}, {"i915_dp_test_type", &i915_displayport_test_type_fops}, {"i915_dp_test_active", &i915_displayport_test_active_fops}, - {"i915_guc_log_level", &i915_guc_log_level_fops}, - {"i915_guc_log_relay", &i915_guc_log_relay_fops}, {"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops}, {"i915_hpd_short_storm_ctl", &i915_hpd_short_storm_ctl_fops}, {"i915_ipc_status", &i915_ipc_status_fops}, @@ -4459,9 +4117,6 @@ int i915_debugfs_register(struct drm_i915_private *dev_priv) struct drm_minor *minor = dev_priv->drm.primary; int i; - debugfs_create_file("i915_forcewake_user", S_IRUSR, minor->debugfs_root, - to_i915(minor->dev), &i915_forcewake_fops); - for (i = 0; i < ARRAY_SIZE(i915_debugfs_files); i++) { debugfs_create_file(i915_debugfs_files[i].name, S_IRUGO | S_IWUSR, @@ -4470,6 +4125,8 @@ int i915_debugfs_register(struct drm_i915_private *dev_priv) i915_debugfs_files[i].fops); } + intel_gt_debugfs_register(&dev_priv->gt, minor->debugfs_root); + return drm_debugfs_create_files(i915_debugfs_list, I915_DEBUGFS_ENTRIES, minor->debugfs_root, minor);