summaryrefslogtreecommitdiff
path: root/drivers/video/tegra
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/tegra')
-rw-r--r--drivers/video/tegra/host/debug.c67
-rw-r--r--drivers/video/tegra/host/host1x/host1x_debug.c117
2 files changed, 134 insertions, 50 deletions
diff --git a/drivers/video/tegra/host/debug.c b/drivers/video/tegra/host/debug.c
index 8a26f92c79f6..820eac85521d 100644
--- a/drivers/video/tegra/host/debug.c
+++ b/drivers/video/tegra/host/debug.c
@@ -106,13 +106,53 @@ static void show_all(struct nvhost_master *m, struct output *o)
nvhost_get_chip_ops()->debug.show_mlocks(m, o);
show_syncpts(m, o);
nvhost_debug_output(o, "---- channels ----\n");
- bus_for_each_dev(&(nvhost_bus_get())->nvhost_bus_type, NULL, o, show_channels);
+ bus_for_each_dev(&(nvhost_bus_get())->nvhost_bus_type, NULL, o,
+ show_channels);
nvhost_module_idle(m->dev);
}
#ifdef CONFIG_DEBUG_FS
-static int nvhost_debug_show(struct seq_file *s, void *unused)
+static int show_channels_no_fifo(struct device *dev, void *data)
+{
+ struct nvhost_channel *ch;
+ struct nvhost_device *nvdev = to_nvhost_device(dev);
+ struct output *o = data;
+ struct nvhost_master *m;
+
+ if (nvdev == NULL)
+ return 0;
+
+ m = nvhost_get_host(nvdev);
+ ch = nvdev->channel;
+ if (ch) {
+ mutex_lock(&ch->reflock);
+ if (ch->refcount) {
+ mutex_lock(&ch->cdma.lock);
+ nvhost_get_chip_ops()->debug.show_channel_cdma(m,
+ ch, o, nvdev->index);
+ mutex_unlock(&ch->cdma.lock);
+ }
+ mutex_unlock(&ch->reflock);
+ }
+
+ return 0;
+}
+
+static void show_all_no_fifo(struct nvhost_master *m, struct output *o)
+{
+ nvhost_module_busy(m->dev);
+
+ nvhost_get_chip_ops()->debug.show_mlocks(m, o);
+ show_syncpts(m, o);
+ nvhost_debug_output(o, "---- channels ----\n");
+ bus_for_each_dev(&(nvhost_bus_get())->nvhost_bus_type, NULL, o,
+ show_channels_no_fifo);
+
+ nvhost_module_idle(m->dev);
+}
+
+static int nvhost_debug_show_all(struct seq_file *s, void *unused)
{
struct output o = {
.fn = write_to_seqfile,
@@ -121,6 +161,27 @@ static int nvhost_debug_show(struct seq_file *s, void *unused)
show_all(s->private, &o);
return 0;
}
+static int nvhost_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 nvhost_debug_open_all(struct inode *inode, struct file *file)
+{
+ return single_open(file, nvhost_debug_show_all, inode->i_private);
+}
+
+static const struct file_operations nvhost_debug_all_fops = {
+ .open = nvhost_debug_open_all,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
static int nvhost_debug_open(struct inode *inode, struct file *file)
{
@@ -140,6 +201,8 @@ void nvhost_debug_init(struct nvhost_master *master)
debugfs_create_file("status", S_IRUGO, de,
master, &nvhost_debug_fops);
+ debugfs_create_file("status_all", S_IRUGO, de,
+ master, &nvhost_debug_all_fops);
debugfs_create_u32("null_kickoff_pid", S_IRUGO|S_IWUSR, de,
&nvhost_debug_null_kickoff_pid);
diff --git a/drivers/video/tegra/host/host1x/host1x_debug.c b/drivers/video/tegra/host/host1x/host1x_debug.c
index a5574a0fb60a..7de342298c4d 100644
--- a/drivers/video/tegra/host/host1x/host1x_debug.c
+++ b/drivers/video/tegra/host/host1x/host1x_debug.c
@@ -28,8 +28,8 @@
#include "host1x_hardware.h"
#include "nvhost_cdma.h"
#include "nvhost_channel.h"
-#include "../../nvmap/nvmap.h"
#include "host1x_cdma.h"
+#include "nvhost_job.h"
#define NVHOST_DEBUG_MAX_PAGE_OFFSET 102400
@@ -160,6 +160,34 @@ static void show_channel_word(struct output *o, int *state, int *count,
}
}
+static void do_show_channel_gather(struct output *o,
+ phys_addr_t phys_addr,
+ u32 words, struct nvhost_cdma *cdma,
+ phys_addr_t pin_addr, u32 *map_addr)
+{
+ /* Map dmaget cursor to corresponding nvmap_handle */
+ u32 offset;
+ int state, count, i;
+
+ offset = phys_addr - pin_addr;
+ /*
+ * Sometimes we're given different hardware address to the same
+ * page - in these cases the offset will get an invalid number and
+ * we just have to bail out.
+ */
+ if (offset > NVHOST_DEBUG_MAX_PAGE_OFFSET) {
+ nvhost_debug_output(o, "[address mismatch]\n");
+ } else {
+ /* GATHER buffer starts always with commands */
+ state = NVHOST_DBG_STATE_CMD;
+ for (i = 0; i < words; i++)
+ show_channel_word(o, &state, &count,
+ phys_addr + i * 4,
+ *(map_addr + offset/4 + i),
+ cdma);
+ }
+}
+
static void show_channel_gather(struct output *o, u32 addr,
phys_addr_t phys_addr,
u32 words, struct nvhost_cdma *cdma)
@@ -171,10 +199,8 @@ static void show_channel_gather(struct output *o, u32 addr,
struct nvmap_client_handle *nvmap = &pb->nvmap[cur/8];
u32 *map_addr, offset;
phys_addr_t pin_addr;
- int state, count, i;
- if (!nvmap->handle || !nvmap->client
- || atomic_read(&nvmap->handle->handle->ref) < 1) {
+ if (!nvmap || !nvmap->handle || !nvmap->client) {
nvhost_debug_output(o, "[already deallocated]\n");
return;
}
@@ -194,51 +220,13 @@ static void show_channel_gather(struct output *o, u32 addr,
}
offset = phys_addr - pin_addr;
- /*
- * Sometimes we're given different hardware address to the same
- * page - in these cases the offset will get an invalid number and
- * we just have to bail out.
- */
- if (offset > NVHOST_DEBUG_MAX_PAGE_OFFSET) {
- nvhost_debug_output(o, "[address mismatch]\n");
- } else {
- /* GATHER buffer starts always with commands */
- state = NVHOST_DBG_STATE_CMD;
- for (i = 0; i < words; i++)
- show_channel_word(o, &state, &count,
- phys_addr + i * 4,
- *(map_addr + offset/4 + i),
- cdma);
- }
+ do_show_channel_gather(o, phys_addr, words, cdma,
+ pin_addr, map_addr);
nvmap_unpin(nvmap->client, nvmap->handle);
nvmap_munmap(nvmap->handle, map_addr);
#endif
}
-static void show_channel_pair(struct output *o, u32 addr,
- u32 w0, u32 w1, struct nvhost_cdma *cdma)
-{
- int state = NVHOST_DBG_STATE_CMD;
- int count;
-
- show_channel_word(o, &state, &count, addr, w0, cdma);
- show_channel_word(o, &state, &count, addr+4, w1, cdma);
-}
-
-/**
- * Retrieve the op pair at a slot offset from a DMA address
- */
-static void cdma_peek(struct nvhost_cdma *cdma,
- u32 dmaget, int slot, u32 *out)
-{
- u32 offset = dmaget - cdma->push_buffer.phys;
- u32 *p = cdma->push_buffer.mapped;
-
- offset = ((offset + slot * 8) & (PUSH_BUFFER_SIZE - 1)) >> 2;
- out[0] = p[offset];
- out[1] = p[offset + 1];
-}
-
u32 previous_oppair(struct nvhost_cdma *cdma, u32 cur)
{
u32 pb = cdma->push_buffer.phys;
@@ -248,6 +236,42 @@ u32 previous_oppair(struct nvhost_cdma *cdma, u32 cur)
return prev;
}
+void show_channel_gathers(struct output *o, struct nvhost_cdma *cdma)
+{
+ struct nvhost_job *job;
+
+ list_for_each_entry(job, &cdma->sync_queue, list) {
+ int i;
+ nvhost_debug_output(o, "\n%p: JOB, syncpt_id=%d, syncpt_val=%d,"
+ " first_get=%08x, timeout=%d, ctx=%p,"
+ " num_slots=%d, num_handles=%d\n",
+ job,
+ job->syncpt_id,
+ job->syncpt_end,
+ job->first_get,
+ job->timeout,
+ job->hwctx,
+ job->num_slots,
+ job->num_unpins);
+
+ for (i = 0; i < job->num_gathers; i++) {
+ struct nvhost_job_gather *g = &job->gathers[i];
+ u32 *mapped = nvmap_mmap(g->ref);
+ if (!mapped) {
+ nvhost_debug_output(o, "[could not mmap]\n");
+ continue;
+ }
+
+ nvhost_debug_output(o, " GATHER at %08x, %d words\n",
+ g->mem, g->words);
+
+ do_show_channel_gather(o, g->mem + g->offset,
+ g->words, cdma, g->mem, mapped);
+ nvmap_munmap(g->ref, mapped);
+ }
+ }
+}
+
static void t20_debug_show_channel_cdma(struct nvhost_master *m,
struct nvhost_channel *ch, struct output *o, int chid)
{
@@ -256,7 +280,6 @@ static void t20_debug_show_channel_cdma(struct nvhost_master *m,
u32 dmaput, dmaget, dmactrl;
u32 cbstat, cbread;
u32 val, base, baseval;
- u32 pbw[2];
dmaput = readl(channel->aperture + HOST1X_CHANNEL_DMAPUT);
dmaget = readl(channel->aperture + HOST1X_CHANNEL_DMAGET);
@@ -305,9 +328,7 @@ static void t20_debug_show_channel_cdma(struct nvhost_master *m,
dmaput, dmaget, dmactrl);
nvhost_debug_output(o, "CBREAD %08x, CBSTAT %08x\n", cbread, cbstat);
- cdma_peek(cdma, dmaget, -1, pbw);
- show_channel_pair(o, previous_oppair(cdma, dmaget),
- pbw[0], pbw[1], &channel->cdma);
+ show_channel_gathers(o, cdma);
nvhost_debug_output(o, "\n");
}