diff options
Diffstat (limited to 'drivers/video/omap2/dss/dispc.c')
| -rw-r--r-- | drivers/video/omap2/dss/dispc.c | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 6dabf4b2f005..de8bfbac9e26 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, | |||
| 148 | DISPC_VID_ATTRIBUTES(0), | 148 | DISPC_VID_ATTRIBUTES(0), |
| 149 | DISPC_VID_ATTRIBUTES(1) }; | 149 | DISPC_VID_ATTRIBUTES(1) }; |
| 150 | 150 | ||
| 151 | struct dispc_irq_stats { | ||
| 152 | unsigned long last_reset; | ||
| 153 | unsigned irq_count; | ||
| 154 | unsigned irqs[32]; | ||
| 155 | }; | ||
| 156 | |||
| 151 | static struct { | 157 | static struct { |
| 152 | void __iomem *base; | 158 | void __iomem *base; |
| 153 | 159 | ||
| @@ -160,6 +166,11 @@ static struct { | |||
| 160 | struct work_struct error_work; | 166 | struct work_struct error_work; |
| 161 | 167 | ||
| 162 | u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; | 168 | u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; |
| 169 | |||
| 170 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 171 | spinlock_t irq_stats_lock; | ||
| 172 | struct dispc_irq_stats irq_stats; | ||
| 173 | #endif | ||
| 163 | } dispc; | 174 | } dispc; |
| 164 | 175 | ||
| 165 | static void _omap_dispc_set_irqs(void); | 176 | static void _omap_dispc_set_irqs(void); |
| @@ -1443,7 +1454,10 @@ static unsigned long calc_fclk_five_taps(u16 width, u16 height, | |||
| 1443 | do_div(tmp, 2 * out_height * ppl); | 1454 | do_div(tmp, 2 * out_height * ppl); |
| 1444 | fclk = tmp; | 1455 | fclk = tmp; |
| 1445 | 1456 | ||
| 1446 | if (height > 2 * out_height && ppl != out_width) { | 1457 | if (height > 2 * out_height) { |
| 1458 | if (ppl == out_width) | ||
| 1459 | return 0; | ||
| 1460 | |||
| 1447 | tmp = pclk * (height - 2 * out_height) * out_width; | 1461 | tmp = pclk * (height - 2 * out_height) * out_width; |
| 1448 | do_div(tmp, 2 * out_height * (ppl - out_width)); | 1462 | do_div(tmp, 2 * out_height * (ppl - out_width)); |
| 1449 | fclk = max(fclk, (u32) tmp); | 1463 | fclk = max(fclk, (u32) tmp); |
| @@ -1623,7 +1637,7 @@ static int _dispc_setup_plane(enum omap_plane plane, | |||
| 1623 | DSSDBG("required fclk rate = %lu Hz\n", fclk); | 1637 | DSSDBG("required fclk rate = %lu Hz\n", fclk); |
| 1624 | DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate()); | 1638 | DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate()); |
| 1625 | 1639 | ||
| 1626 | if (fclk > dispc_fclk_rate()) { | 1640 | if (!fclk || fclk > dispc_fclk_rate()) { |
| 1627 | DSSERR("failed to set up scaling, " | 1641 | DSSERR("failed to set up scaling, " |
| 1628 | "required fclk rate = %lu Hz, " | 1642 | "required fclk rate = %lu Hz, " |
| 1629 | "current fclk rate = %lu Hz\n", | 1643 | "current fclk rate = %lu Hz\n", |
| @@ -2247,6 +2261,50 @@ void dispc_dump_clocks(struct seq_file *s) | |||
| 2247 | enable_clocks(0); | 2261 | enable_clocks(0); |
| 2248 | } | 2262 | } |
| 2249 | 2263 | ||
| 2264 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 2265 | void dispc_dump_irqs(struct seq_file *s) | ||
| 2266 | { | ||
| 2267 | unsigned long flags; | ||
| 2268 | struct dispc_irq_stats stats; | ||
| 2269 | |||
| 2270 | spin_lock_irqsave(&dispc.irq_stats_lock, flags); | ||
| 2271 | |||
| 2272 | stats = dispc.irq_stats; | ||
| 2273 | memset(&dispc.irq_stats, 0, sizeof(dispc.irq_stats)); | ||
| 2274 | dispc.irq_stats.last_reset = jiffies; | ||
| 2275 | |||
| 2276 | spin_unlock_irqrestore(&dispc.irq_stats_lock, flags); | ||
| 2277 | |||
| 2278 | seq_printf(s, "period %u ms\n", | ||
| 2279 | jiffies_to_msecs(jiffies - stats.last_reset)); | ||
| 2280 | |||
| 2281 | seq_printf(s, "irqs %d\n", stats.irq_count); | ||
| 2282 | #define PIS(x) \ | ||
| 2283 | seq_printf(s, "%-20s %10d\n", #x, stats.irqs[ffs(DISPC_IRQ_##x)-1]); | ||
| 2284 | |||
| 2285 | PIS(FRAMEDONE); | ||
| 2286 | PIS(VSYNC); | ||
| 2287 | PIS(EVSYNC_EVEN); | ||
| 2288 | PIS(EVSYNC_ODD); | ||
| 2289 | PIS(ACBIAS_COUNT_STAT); | ||
| 2290 | PIS(PROG_LINE_NUM); | ||
| 2291 | PIS(GFX_FIFO_UNDERFLOW); | ||
| 2292 | PIS(GFX_END_WIN); | ||
| 2293 | PIS(PAL_GAMMA_MASK); | ||
| 2294 | PIS(OCP_ERR); | ||
| 2295 | PIS(VID1_FIFO_UNDERFLOW); | ||
| 2296 | PIS(VID1_END_WIN); | ||
| 2297 | PIS(VID2_FIFO_UNDERFLOW); | ||
| 2298 | PIS(VID2_END_WIN); | ||
| 2299 | PIS(SYNC_LOST); | ||
| 2300 | PIS(SYNC_LOST_DIGIT); | ||
| 2301 | PIS(WAKEUP); | ||
| 2302 | #undef PIS | ||
| 2303 | } | ||
| 2304 | #else | ||
| 2305 | void dispc_dump_irqs(struct seq_file *s) { } | ||
| 2306 | #endif | ||
| 2307 | |||
| 2250 | void dispc_dump_regs(struct seq_file *s) | 2308 | void dispc_dump_regs(struct seq_file *s) |
| 2251 | { | 2309 | { |
| 2252 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r)) | 2310 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r)) |
| @@ -2665,6 +2723,13 @@ void dispc_irq_handler(void) | |||
| 2665 | 2723 | ||
| 2666 | irqstatus = dispc_read_reg(DISPC_IRQSTATUS); | 2724 | irqstatus = dispc_read_reg(DISPC_IRQSTATUS); |
| 2667 | 2725 | ||
| 2726 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 2727 | spin_lock(&dispc.irq_stats_lock); | ||
| 2728 | dispc.irq_stats.irq_count++; | ||
| 2729 | dss_collect_irq_stats(irqstatus, dispc.irq_stats.irqs); | ||
| 2730 | spin_unlock(&dispc.irq_stats_lock); | ||
| 2731 | #endif | ||
| 2732 | |||
| 2668 | #ifdef DEBUG | 2733 | #ifdef DEBUG |
| 2669 | if (dss_debug) | 2734 | if (dss_debug) |
| 2670 | print_irq_status(irqstatus); | 2735 | print_irq_status(irqstatus); |
| @@ -3012,6 +3077,11 @@ int dispc_init(void) | |||
| 3012 | 3077 | ||
| 3013 | spin_lock_init(&dispc.irq_lock); | 3078 | spin_lock_init(&dispc.irq_lock); |
| 3014 | 3079 | ||
| 3080 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | ||
| 3081 | spin_lock_init(&dispc.irq_stats_lock); | ||
| 3082 | dispc.irq_stats.last_reset = jiffies; | ||
| 3083 | #endif | ||
| 3084 | |||
| 3015 | INIT_WORK(&dispc.error_work, dispc_error_worker); | 3085 | INIT_WORK(&dispc.error_work, dispc_error_worker); |
| 3016 | 3086 | ||
| 3017 | dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS); | 3087 | dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS); |
