Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2010 Google, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Author: Erik Gilling <konkers@android.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 2011-2013 NVIDIA Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "dev.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "channel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) static DEFINE_MUTEX(debug_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) unsigned int host1x_debug_trace_cmdbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) static pid_t host1x_debug_force_timeout_pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) static u32 host1x_debug_force_timeout_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) static u32 host1x_debug_force_timeout_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) void host1x_debug_output(struct output *o, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	len = vsnprintf(o->buf, sizeof(o->buf), fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	o->fn(o->ctx, o->buf, len, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) void host1x_debug_cont(struct output *o, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	len = vsnprintf(o->buf, sizeof(o->buf), fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	o->fn(o->ctx, o->buf, len, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) static int show_channel(struct host1x_channel *ch, void *data, bool show_fifo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	struct host1x *m = dev_get_drvdata(ch->dev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	struct output *o = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	mutex_lock(&ch->cdma.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	mutex_lock(&debug_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	if (show_fifo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		host1x_hw_show_channel_fifo(m, ch, o);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	host1x_hw_show_channel_cdma(m, ch, o);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	mutex_unlock(&debug_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	mutex_unlock(&ch->cdma.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) static void show_syncpts(struct host1x *m, struct output *o)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	host1x_debug_output(o, "---- syncpts ----\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	for (i = 0; i < host1x_syncpt_nb_pts(m); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		u32 max = host1x_syncpt_read_max(m->syncpt + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		u32 min = host1x_syncpt_load(m->syncpt + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		if (!min && !max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		host1x_debug_output(o, "id %u (%s) min %d max %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 				    i, m->syncpt[i].name, min, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	for (i = 0; i < host1x_syncpt_nb_bases(m); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		u32 base_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		base_val = host1x_syncpt_load_wait_base(m->syncpt + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		if (base_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			host1x_debug_output(o, "waitbase id %u val %d\n", i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 					    base_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	host1x_debug_output(o, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) static void show_all(struct host1x *m, struct output *o, bool show_fifo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	host1x_hw_show_mlocks(m, o);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	show_syncpts(m, o);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	host1x_debug_output(o, "---- channels ----\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	for (i = 0; i < m->info->nb_channels; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		struct host1x_channel *ch = host1x_channel_get_index(m, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		if (ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			show_channel(ch, o, show_fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			host1x_channel_put(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static int host1x_debug_show_all(struct seq_file *s, void *unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	struct output o = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		.fn = write_to_seqfile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		.ctx = s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	show_all(s->private, &o, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static int host1x_debug_show(struct seq_file *s, void *unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	struct output o = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		.fn = write_to_seqfile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		.ctx = s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	show_all(s->private, &o, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int host1x_debug_open_all(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	return single_open(file, host1x_debug_show_all, inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static const struct file_operations host1x_debug_all_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	.open = host1x_debug_open_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	.read = seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	.llseek = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	.release = single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static int host1x_debug_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	return single_open(file, host1x_debug_show, inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static const struct file_operations host1x_debug_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	.open = host1x_debug_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	.read = seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	.llseek = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	.release = single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static void host1x_debugfs_init(struct host1x *host1x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	struct dentry *de = debugfs_create_dir("tegra-host1x", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	/* Store the created entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	host1x->debugfs = de;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	debugfs_create_file("status", S_IRUGO, de, host1x, &host1x_debug_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	debugfs_create_file("status_all", S_IRUGO, de, host1x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 			    &host1x_debug_all_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	debugfs_create_u32("trace_cmdbuf", S_IRUGO|S_IWUSR, de,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			   &host1x_debug_trace_cmdbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	host1x_hw_debug_init(host1x, de);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	debugfs_create_u32("force_timeout_pid", S_IRUGO|S_IWUSR, de,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 			   &host1x_debug_force_timeout_pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	debugfs_create_u32("force_timeout_val", S_IRUGO|S_IWUSR, de,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 			   &host1x_debug_force_timeout_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	debugfs_create_u32("force_timeout_channel", S_IRUGO|S_IWUSR, de,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			   &host1x_debug_force_timeout_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static void host1x_debugfs_exit(struct host1x *host1x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	debugfs_remove_recursive(host1x->debugfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) void host1x_debug_init(struct host1x *host1x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	if (IS_ENABLED(CONFIG_DEBUG_FS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		host1x_debugfs_init(host1x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) void host1x_debug_deinit(struct host1x *host1x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	if (IS_ENABLED(CONFIG_DEBUG_FS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		host1x_debugfs_exit(host1x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) void host1x_debug_dump(struct host1x *host1x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	struct output o = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		.fn = write_to_printk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	show_all(host1x, &o, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) void host1x_debug_dump_syncpts(struct host1x *host1x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	struct output o = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		.fn = write_to_printk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	show_syncpts(host1x, &o);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }