-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for host1x debugging. Adds debugfs entries, and dumps channel state to UART in case of stuck job. Signed-off-by: Arto Merilainen <amerilainen@nvidia.com> Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: Thierry Reding <thierry.reding@avionic-design.de> Tested-by: Thierry Reding <thierry.reding@avionic-design.de> Tested-by: Erik Faye-Lund <kusmabite@gmail.com> Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
- Loading branch information
Terje Bergstrom
authored and
Thierry Reding
committed
Apr 22, 2013
1 parent
6579324
commit 6236451
Showing
15 changed files
with
807 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ host1x-y = \ | |
cdma.o \ | ||
channel.o \ | ||
job.o \ | ||
debug.o \ | ||
hw/host1x01.o | ||
|
||
obj-$(CONFIG_TEGRA_HOST1X) += host1x.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
/* | ||
* Copyright (C) 2010 Google, Inc. | ||
* Author: Erik Gilling <konkers@android.com> | ||
* | ||
* Copyright (C) 2011-2013 NVIDIA Corporation | ||
* | ||
* This software is licensed under the terms of the GNU General Public | ||
* License version 2, as published by the Free Software Foundation, and | ||
* may be copied, distributed, and modified under those terms. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
*/ | ||
|
||
#include <linux/debugfs.h> | ||
#include <linux/seq_file.h> | ||
#include <linux/uaccess.h> | ||
|
||
#include <linux/io.h> | ||
|
||
#include "dev.h" | ||
#include "debug.h" | ||
#include "channel.h" | ||
|
||
unsigned int host1x_debug_trace_cmdbuf; | ||
|
||
static pid_t host1x_debug_force_timeout_pid; | ||
static u32 host1x_debug_force_timeout_val; | ||
static u32 host1x_debug_force_timeout_channel; | ||
|
||
void host1x_debug_output(struct output *o, const char *fmt, ...) | ||
{ | ||
va_list args; | ||
int len; | ||
|
||
va_start(args, fmt); | ||
len = vsnprintf(o->buf, sizeof(o->buf), fmt, args); | ||
va_end(args); | ||
o->fn(o->ctx, o->buf, len); | ||
} | ||
|
||
static int show_channels(struct host1x_channel *ch, void *data, bool show_fifo) | ||
{ | ||
struct host1x *m = dev_get_drvdata(ch->dev->parent); | ||
struct output *o = data; | ||
|
||
mutex_lock(&ch->reflock); | ||
if (ch->refcount) { | ||
mutex_lock(&ch->cdma.lock); | ||
if (show_fifo) | ||
host1x_hw_show_channel_fifo(m, ch, o); | ||
host1x_hw_show_channel_cdma(m, ch, o); | ||
mutex_unlock(&ch->cdma.lock); | ||
} | ||
mutex_unlock(&ch->reflock); | ||
|
||
return 0; | ||
} | ||
|
||
static void show_syncpts(struct host1x *m, struct output *o) | ||
{ | ||
int i; | ||
host1x_debug_output(o, "---- syncpts ----\n"); | ||
for (i = 0; i < host1x_syncpt_nb_pts(m); i++) { | ||
u32 max = host1x_syncpt_read_max(m->syncpt + i); | ||
u32 min = host1x_syncpt_load(m->syncpt + i); | ||
if (!min && !max) | ||
continue; | ||
host1x_debug_output(o, "id %d (%s) min %d max %d\n", | ||
i, m->syncpt[i].name, min, max); | ||
} | ||
|
||
for (i = 0; i < host1x_syncpt_nb_bases(m); i++) { | ||
u32 base_val; | ||
base_val = host1x_syncpt_load_wait_base(m->syncpt + i); | ||
if (base_val) | ||
host1x_debug_output(o, "waitbase id %d val %d\n", i, | ||
base_val); | ||
} | ||
|
||
host1x_debug_output(o, "\n"); | ||
} | ||
|
||
static void show_all(struct host1x *m, struct output *o) | ||
{ | ||
struct host1x_channel *ch; | ||
|
||
host1x_hw_show_mlocks(m, o); | ||
show_syncpts(m, o); | ||
host1x_debug_output(o, "---- channels ----\n"); | ||
|
||
host1x_for_each_channel(m, ch) | ||
show_channels(ch, o, true); | ||
} | ||
|
||
#ifdef CONFIG_DEBUG_FS | ||
static void show_all_no_fifo(struct host1x *host1x, struct output *o) | ||
{ | ||
struct host1x_channel *ch; | ||
|
||
host1x_hw_show_mlocks(host1x, o); | ||
show_syncpts(host1x, o); | ||
host1x_debug_output(o, "---- channels ----\n"); | ||
|
||
host1x_for_each_channel(host1x, ch) | ||
show_channels(ch, o, false); | ||
} | ||
|
||
static int host1x_debug_show_all(struct seq_file *s, void *unused) | ||
{ | ||
struct output o = { | ||
.fn = write_to_seqfile, | ||
.ctx = s | ||
}; | ||
show_all(s->private, &o); | ||
return 0; | ||
} | ||
|
||
static int host1x_debug_show(struct seq_file *s, void *unused) | ||
{ | ||
struct output o = { | ||
.fn = write_to_seqfile, | ||
.ctx = s | ||
}; | ||
show_all_no_fifo(s->private, &o); | ||
return 0; | ||
} | ||
|
||
static int host1x_debug_open_all(struct inode *inode, struct file *file) | ||
{ | ||
return single_open(file, host1x_debug_show_all, inode->i_private); | ||
} | ||
|
||
static const struct file_operations host1x_debug_all_fops = { | ||
.open = host1x_debug_open_all, | ||
.read = seq_read, | ||
.llseek = seq_lseek, | ||
.release = single_release, | ||
}; | ||
|
||
static int host1x_debug_open(struct inode *inode, struct file *file) | ||
{ | ||
return single_open(file, host1x_debug_show, inode->i_private); | ||
} | ||
|
||
static const struct file_operations host1x_debug_fops = { | ||
.open = host1x_debug_open, | ||
.read = seq_read, | ||
.llseek = seq_lseek, | ||
.release = single_release, | ||
}; | ||
|
||
void host1x_debug_init(struct host1x *host1x) | ||
{ | ||
struct dentry *de = debugfs_create_dir("tegra-host1x", NULL); | ||
|
||
if (!de) | ||
return; | ||
|
||
/* Store the created entry */ | ||
host1x->debugfs = de; | ||
|
||
debugfs_create_file("status", S_IRUGO, de, host1x, &host1x_debug_fops); | ||
debugfs_create_file("status_all", S_IRUGO, de, host1x, | ||
&host1x_debug_all_fops); | ||
|
||
debugfs_create_u32("trace_cmdbuf", S_IRUGO|S_IWUSR, de, | ||
&host1x_debug_trace_cmdbuf); | ||
|
||
host1x_hw_debug_init(host1x, de); | ||
|
||
debugfs_create_u32("force_timeout_pid", S_IRUGO|S_IWUSR, de, | ||
&host1x_debug_force_timeout_pid); | ||
debugfs_create_u32("force_timeout_val", S_IRUGO|S_IWUSR, de, | ||
&host1x_debug_force_timeout_val); | ||
debugfs_create_u32("force_timeout_channel", S_IRUGO|S_IWUSR, de, | ||
&host1x_debug_force_timeout_channel); | ||
} | ||
|
||
void host1x_debug_deinit(struct host1x *host1x) | ||
{ | ||
debugfs_remove_recursive(host1x->debugfs); | ||
} | ||
#else | ||
void host1x_debug_init(struct host1x *host1x) | ||
{ | ||
} | ||
void host1x_debug_deinit(struct host1x *host1x) | ||
{ | ||
} | ||
#endif | ||
|
||
void host1x_debug_dump(struct host1x *host1x) | ||
{ | ||
struct output o = { | ||
.fn = write_to_printk | ||
}; | ||
show_all(host1x, &o); | ||
} | ||
|
||
void host1x_debug_dump_syncpts(struct host1x *host1x) | ||
{ | ||
struct output o = { | ||
.fn = write_to_printk | ||
}; | ||
show_syncpts(host1x, &o); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* Tegra host1x Debug | ||
* | ||
* Copyright (c) 2011-2013 NVIDIA Corporation. | ||
* | ||
* This program is free software; you can redistribute it and/or modify it | ||
* under the terms and conditions of the GNU General Public License, | ||
* version 2, as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
* more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
#ifndef __HOST1X_DEBUG_H | ||
#define __HOST1X_DEBUG_H | ||
|
||
#include <linux/debugfs.h> | ||
#include <linux/seq_file.h> | ||
|
||
struct host1x; | ||
|
||
struct output { | ||
void (*fn)(void *ctx, const char *str, size_t len); | ||
void *ctx; | ||
char buf[256]; | ||
}; | ||
|
||
static inline void write_to_seqfile(void *ctx, const char *str, size_t len) | ||
{ | ||
seq_write((struct seq_file *)ctx, str, len); | ||
} | ||
|
||
static inline void write_to_printk(void *ctx, const char *str, size_t len) | ||
{ | ||
pr_info("%s", str); | ||
} | ||
|
||
void __printf(2, 3) host1x_debug_output(struct output *o, const char *fmt, ...); | ||
|
||
extern unsigned int host1x_debug_trace_cmdbuf; | ||
|
||
void host1x_debug_init(struct host1x *host1x); | ||
void host1x_debug_deinit(struct host1x *host1x); | ||
void host1x_debug_dump(struct host1x *host1x); | ||
void host1x_debug_dump_syncpts(struct host1x *host1x); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.