Possible fix for omapfb irq errors
authorGrazvydas Ignotas <notasas@gmail.com>
Fri, 9 Jan 2009 22:01:07 +0000 (00:01 +0200)
committerGrazvydas Ignotas <notasas@gmail.com>
Fri, 9 Jan 2009 22:01:07 +0000 (00:01 +0200)
tested with at least 50 boots now

drivers/video/omap/dispc.c

index c140c21..e73d04a 100644 (file)
@@ -1398,10 +1398,31 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
        }
 #endif
 
+       l = dispc_read_reg(DISPC_IRQSTATUS);
+       dispc_write_reg(DISPC_IRQSTATUS, l);
+
+       recalc_irq_mask();
+
+       if ((r = request_irq(INT_24XX_DSS_IRQ, omap_dispc_irq_handler,
+                          0, MODULE_NAME, fbdev)) < 0) {
+               dev_err(dispc.fbdev->dev, "can't get DSS IRQ\n");
+               goto fail1;
+       }
+
        if (!skip_init) {
                /* Reset monitoring works only w/ the 54M clk */
                enable_digit_clocks(1);
 
+               /* We have to wait here to avoid occasional SYNC LOST errors */
+               MOD_REG_FLD(DISPC_IRQENABLE, 1, 1);
+               omap_dispc_enable_lcd_out(0);   /* if bootloader enabled it */
+               if (!wait_for_completion_timeout(&dispc.frame_done,
+                               msecs_to_jiffies(400))) {
+                       dev_err(dispc.fbdev->dev,
+                               "timeout waiting for FRAME DONE\n");
+               }
+               MOD_REG_FLD(DISPC_IRQENABLE, 1, 0);
+
                /* Soft reset */
                MOD_REG_FLD(DISPC_SYSCONFIG, 1 << 1, 1 << 1);
 
@@ -1410,7 +1431,7 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
                                dev_err(dispc.fbdev->dev, "soft reset failed\n");
                                r = -ENODEV;
                                enable_digit_clocks(0);
-                               goto fail1;
+                               goto fail2;
                        }
                }
 
@@ -1429,16 +1450,6 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
        l |= 1 << 9;
        dispc_write_reg(DISPC_CONFIG, l);
 
-       l = dispc_read_reg(DISPC_IRQSTATUS);
-       dispc_write_reg(DISPC_IRQSTATUS, l);
-
-       recalc_irq_mask();
-
-       if ((r = request_irq(INT_24XX_DSS_IRQ, omap_dispc_irq_handler,
-                          0, MODULE_NAME, fbdev)) < 0) {
-               dev_err(dispc.fbdev->dev, "can't get DSS IRQ\n");
-               goto fail1;
-       }
 
        /* L3 firewall setting: enable access to OCM RAM */
        __raw_writel(0x402000b0, IO_ADDRESS(0x680050a0));