Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: MIT
  2/*
  3 * Copyright © 2020 Intel Corporation
  4 */
  5
  6#include <linux/fs.h>
  7#include <drm/drm_print.h>
  8
  9#include "gt/intel_gt_debugfs.h"
 10#include "intel_guc.h"
 11#include "intel_guc_log.h"
 12#include "intel_guc_log_debugfs.h"
 13#include "intel_uc.h"
 14
 15static u32 obj_to_guc_log_dump_size(struct drm_i915_gem_object *obj)
 16{
 17	u32 size;
 18
 19	if (!obj)
 20		return PAGE_SIZE;
 21
 22	/* "0x%08x 0x%08x 0x%08x 0x%08x\n" => 16 bytes -> 44 chars => x2.75 */
 23	size = ((obj->base.size * 11) + 3) / 4;
 24
 25	/* Add padding for final blank line, any extra header info, etc. */
 26	size = PAGE_ALIGN(size + PAGE_SIZE);
 27
 28	return size;
 29}
 30
 31static u32 guc_log_dump_size(struct intel_guc_log *log)
 32{
 33	struct intel_guc *guc = log_to_guc(log);
 34
 35	if (!intel_guc_is_supported(guc))
 36		return PAGE_SIZE;
 37
 38	if (!log->vma)
 39		return PAGE_SIZE;
 40
 41	return obj_to_guc_log_dump_size(log->vma->obj);
 42}
 43
 44static int guc_log_dump_show(struct seq_file *m, void *data)
 45{
 46	struct drm_printer p = drm_seq_file_printer(m);
 47	int ret;
 48
 49	ret = intel_guc_log_dump(m->private, &p, false);
 50
 51	if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) && seq_has_overflowed(m))
 52		pr_warn_once("preallocated size:%zx for %s exceeded\n",
 53			     m->size, __func__);
 54
 55	return ret;
 56}
 57DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE_WITH_SIZE(guc_log_dump, guc_log_dump_size);
 58
 59static u32 guc_load_err_dump_size(struct intel_guc_log *log)
 60{
 61	struct intel_guc *guc = log_to_guc(log);
 62	struct intel_uc *uc = container_of(guc, struct intel_uc, guc);
 63
 64	if (!intel_guc_is_supported(guc))
 65		return PAGE_SIZE;
 66
 67	return obj_to_guc_log_dump_size(uc->load_err_log);
 68}
 69
 70static int guc_load_err_log_dump_show(struct seq_file *m, void *data)
 71{
 72	struct drm_printer p = drm_seq_file_printer(m);
 73
 74	if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) && seq_has_overflowed(m))
 75		pr_warn_once("preallocated size:%zx for %s exceeded\n",
 76			     m->size, __func__);
 77
 78	return intel_guc_log_dump(m->private, &p, true);
 79}
 80DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE_WITH_SIZE(guc_load_err_log_dump, guc_load_err_dump_size);
 81
 82static int guc_log_level_get(void *data, u64 *val)
 83{
 84	struct intel_guc_log *log = data;
 85
 86	if (!log->vma)
 87		return -ENODEV;
 88
 89	*val = intel_guc_log_get_level(log);
 90
 91	return 0;
 92}
 93
 94static int guc_log_level_set(void *data, u64 val)
 95{
 96	struct intel_guc_log *log = data;
 97
 98	if (!log->vma)
 99		return -ENODEV;
100
101	return intel_guc_log_set_level(log, val);
102}
103
104DEFINE_SIMPLE_ATTRIBUTE(guc_log_level_fops,
105			guc_log_level_get, guc_log_level_set,
106			"%lld\n");
107
108static int guc_log_relay_open(struct inode *inode, struct file *file)
109{
110	struct intel_guc_log *log = inode->i_private;
111
112	if (!intel_guc_is_ready(log_to_guc(log)))
113		return -ENODEV;
114
115	file->private_data = log;
116
117	return intel_guc_log_relay_open(log);
118}
119
120static ssize_t
121guc_log_relay_write(struct file *filp,
122		    const char __user *ubuf,
123		    size_t cnt,
124		    loff_t *ppos)
125{
126	struct intel_guc_log *log = filp->private_data;
127	int val;
128	int ret;
129
130	ret = kstrtoint_from_user(ubuf, cnt, 0, &val);
131	if (ret < 0)
132		return ret;
133
134	/*
135	 * Enable and start the guc log relay on value of 1.
136	 * Flush log relay for any other value.
137	 */
138	if (val == 1)
139		ret = intel_guc_log_relay_start(log);
140	else
141		intel_guc_log_relay_flush(log);
142
143	return ret ?: cnt;
144}
145
146static int guc_log_relay_release(struct inode *inode, struct file *file)
147{
148	struct intel_guc_log *log = inode->i_private;
149
150	intel_guc_log_relay_close(log);
151	return 0;
152}
153
154static const struct file_operations guc_log_relay_fops = {
155	.owner = THIS_MODULE,
156	.open = guc_log_relay_open,
157	.write = guc_log_relay_write,
158	.release = guc_log_relay_release,
159};
160
161void intel_guc_log_debugfs_register(struct intel_guc_log *log,
162				    struct dentry *root)
163{
164	static const struct intel_gt_debugfs_file files[] = {
165		{ "guc_log_dump", &guc_log_dump_fops, NULL },
166		{ "guc_load_err_log_dump", &guc_load_err_log_dump_fops, NULL },
167		{ "guc_log_level", &guc_log_level_fops, NULL },
168		{ "guc_log_relay", &guc_log_relay_fops, NULL },
169	};
170
171	if (!intel_guc_is_supported(log_to_guc(log)))
172		return;
173
174	intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), log);
175}