[PATCHv6 4/9] gpu: host1x: Add debug support

2013-03-08 Thread Terje Bergstrom
Add support for host1x debugging. Adds debugfs entries, and dumps
channel state to UART in case of stuck job.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile |1 +
 drivers/gpu/host1x/cdma.c   |5 +
 drivers/gpu/host1x/debug.c  |  210 +
 drivers/gpu/host1x/debug.h  |   51 +
 drivers/gpu/host1x/dev.c|3 +
 drivers/gpu/host1x/dev.h|   42 
 drivers/gpu/host1x/hw/cdma_hw.c |3 +
 drivers/gpu/host1x/hw/channel_hw.c  |   27 ++-
 drivers/gpu/host1x/hw/debug_hw.c|  322 +++
 drivers/gpu/host1x/hw/host1x01.c|2 +
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |   18 ++
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|  115 ++
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |6 +
 drivers/gpu/host1x/hw/syncpt_hw.c   |1 +
 drivers/gpu/host1x/syncpt.c |5 +
 15 files changed, 810 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/debug.c
 create mode 100644 drivers/gpu/host1x/debug.h
 create mode 100644 drivers/gpu/host1x/hw/debug_hw.c

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 7278bf3..dfc6f35 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -7,6 +7,7 @@ host1x-y = \
cdma.o \
channel.o \
job.o \
+   debug.o \
memmgr.o \
hw/host1x01.o

diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
index a45bb94..f3167bf 100644
--- a/drivers/gpu/host1x/cdma.c
+++ b/drivers/gpu/host1x/cdma.c
@@ -29,6 +29,7 @@
 #include "cdma.h"
 #include "channel.h"
 #include "dev.h"
+#include "debug.h"
 #include "job.h"
 #include "memmgr.h"

@@ -438,6 +439,10 @@ void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, 
u32 op2)
struct push_buffer *pb = &cdma->push_buffer;
u32 slots_free = cdma->slots_free;

+   if (host1x_debug_trace_cmdbuf)
+   trace_host1x_cdma_push(dev_name(cdma_to_channel(cdma)->dev),
+  op1, op2);
+
if (slots_free == 0) {
host1x_hw_cdma_flush(host1x, cdma);
slots_free = host1x_cdma_wait_locked(cdma,
diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c
new file mode 100644
index 000..cb8aff9
--- /dev/null
+++ b/drivers/gpu/host1x/debug.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Erik Gilling 
+ *
+ * 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 
+#include 
+#include 
+
+#include 
+
+#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 = host1x_get_host(ch->dev);
+   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, "

[PATCHv6 4/9] gpu: host1x: Add debug support

2013-03-08 Thread Terje Bergstrom
Add support for host1x debugging. Adds debugfs entries, and dumps
channel state to UART in case of stuck job.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile |1 +
 drivers/gpu/host1x/cdma.c   |5 +
 drivers/gpu/host1x/debug.c  |  210 +
 drivers/gpu/host1x/debug.h  |   51 +
 drivers/gpu/host1x/dev.c|3 +
 drivers/gpu/host1x/dev.h|   42 
 drivers/gpu/host1x/hw/cdma_hw.c |3 +
 drivers/gpu/host1x/hw/channel_hw.c  |   27 ++-
 drivers/gpu/host1x/hw/debug_hw.c|  322 +++
 drivers/gpu/host1x/hw/host1x01.c|2 +
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |   18 ++
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|  115 ++
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |6 +
 drivers/gpu/host1x/hw/syncpt_hw.c   |1 +
 drivers/gpu/host1x/syncpt.c |5 +
 15 files changed, 810 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/debug.c
 create mode 100644 drivers/gpu/host1x/debug.h
 create mode 100644 drivers/gpu/host1x/hw/debug_hw.c

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 7278bf3..dfc6f35 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -7,6 +7,7 @@ host1x-y = \
cdma.o \
channel.o \
job.o \
+   debug.o \
memmgr.o \
hw/host1x01.o
 
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
index a45bb94..f3167bf 100644
--- a/drivers/gpu/host1x/cdma.c
+++ b/drivers/gpu/host1x/cdma.c
@@ -29,6 +29,7 @@
 #include "cdma.h"
 #include "channel.h"
 #include "dev.h"
+#include "debug.h"
 #include "job.h"
 #include "memmgr.h"
 
@@ -438,6 +439,10 @@ void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, 
u32 op2)
struct push_buffer *pb = &cdma->push_buffer;
u32 slots_free = cdma->slots_free;
 
+   if (host1x_debug_trace_cmdbuf)
+   trace_host1x_cdma_push(dev_name(cdma_to_channel(cdma)->dev),
+  op1, op2);
+
if (slots_free == 0) {
host1x_hw_cdma_flush(host1x, cdma);
slots_free = host1x_cdma_wait_locked(cdma,
diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c
new file mode 100644
index 000..cb8aff9
--- /dev/null
+++ b/drivers/gpu/host1x/debug.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Erik Gilling 
+ *
+ * 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 
+#include 
+#include 
+
+#include 
+
+#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 = host1x_get_host(ch->dev);
+   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