summaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/dispc.c
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@nokia.com>2009-12-17 13:35:21 +0100
committerTomi Valkeinen <tomi.valkeinen@nokia.com>2010-01-08 14:32:18 +0100
commitdfc0fd8d8850ef11951ba6c251e06096d1b5a0bd (patch)
treeb80a85226218abbb562c93b7777de8bbda2c5db2 /drivers/video/omap2/dss/dispc.c
parentOMAP: DSS2: DSI: print debug DCS cmd in hex (diff)
downloadlinux-dfc0fd8d8850ef11951ba6c251e06096d1b5a0bd.tar.xz
linux-dfc0fd8d8850ef11951ba6c251e06096d1b5a0bd.zip
OMAP: DSS2: Collect interrupt statistics
Collect interrupt statistics, printable via debugfs: debugfs/omapdss/dispc_irq debugfs/omapdss/dsi_irq The counters are reset when printed. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Diffstat (limited to 'drivers/video/omap2/dss/dispc.c')
-rw-r--r--drivers/video/omap2/dss/dispc.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 6dabf4b2f005..e2e0f9ae7353 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -148,6 +148,12 @@ static const struct dispc_reg dispc_reg_att[] = { DISPC_GFX_ATTRIBUTES,
DISPC_VID_ATTRIBUTES(0),
DISPC_VID_ATTRIBUTES(1) };
+struct dispc_irq_stats {
+ unsigned long last_reset;
+ unsigned irq_count;
+ unsigned irqs[32];
+};
+
static struct {
void __iomem *base;
@@ -160,6 +166,11 @@ static struct {
struct work_struct error_work;
u32 ctx[DISPC_SZ_REGS / sizeof(u32)];
+
+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
+ spinlock_t irq_stats_lock;
+ struct dispc_irq_stats irq_stats;
+#endif
} dispc;
static void _omap_dispc_set_irqs(void);
@@ -2247,6 +2258,50 @@ void dispc_dump_clocks(struct seq_file *s)
enable_clocks(0);
}
+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
+void dispc_dump_irqs(struct seq_file *s)
+{
+ unsigned long flags;
+ struct dispc_irq_stats stats;
+
+ spin_lock_irqsave(&dispc.irq_stats_lock, flags);
+
+ stats = dispc.irq_stats;
+ memset(&dispc.irq_stats, 0, sizeof(dispc.irq_stats));
+ dispc.irq_stats.last_reset = jiffies;
+
+ spin_unlock_irqrestore(&dispc.irq_stats_lock, flags);
+
+ seq_printf(s, "period %u ms\n",
+ jiffies_to_msecs(jiffies - stats.last_reset));
+
+ seq_printf(s, "irqs %d\n", stats.irq_count);
+#define PIS(x) \
+ seq_printf(s, "%-20s %10d\n", #x, stats.irqs[ffs(DISPC_IRQ_##x)-1]);
+
+ PIS(FRAMEDONE);
+ PIS(VSYNC);
+ PIS(EVSYNC_EVEN);
+ PIS(EVSYNC_ODD);
+ PIS(ACBIAS_COUNT_STAT);
+ PIS(PROG_LINE_NUM);
+ PIS(GFX_FIFO_UNDERFLOW);
+ PIS(GFX_END_WIN);
+ PIS(PAL_GAMMA_MASK);
+ PIS(OCP_ERR);
+ PIS(VID1_FIFO_UNDERFLOW);
+ PIS(VID1_END_WIN);
+ PIS(VID2_FIFO_UNDERFLOW);
+ PIS(VID2_END_WIN);
+ PIS(SYNC_LOST);
+ PIS(SYNC_LOST_DIGIT);
+ PIS(WAKEUP);
+#undef PIS
+}
+#else
+void dispc_dump_irqs(struct seq_file *s) { }
+#endif
+
void dispc_dump_regs(struct seq_file *s)
{
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r))
@@ -2665,6 +2720,13 @@ void dispc_irq_handler(void)
irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
+ spin_lock(&dispc.irq_stats_lock);
+ dispc.irq_stats.irq_count++;
+ dss_collect_irq_stats(irqstatus, dispc.irq_stats.irqs);
+ spin_unlock(&dispc.irq_stats_lock);
+#endif
+
#ifdef DEBUG
if (dss_debug)
print_irq_status(irqstatus);
@@ -3012,6 +3074,11 @@ int dispc_init(void)
spin_lock_init(&dispc.irq_lock);
+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
+ spin_lock_init(&dispc.irq_stats_lock);
+ dispc.irq_stats.last_reset = jiffies;
+#endif
+
INIT_WORK(&dispc.error_work, dispc_error_worker);
dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS);