Re: Fix for dispc's error "omapfb omapfb: irq error status 4020"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Nov 13, 2008 at 4:06 PM, Tomi Valkeinen
<tomi.valkeinen@xxxxxxxxx> wrote:
> Hi,
>
> On Fri, 2008-11-07 at 12:55 -0800, ext Rick Bronson wrote:
>> Folks,
>>
>>   Please take a look at this change to drivers/video/omap/dispc.c.  It
>> addresses a problem seen on some boots of OMAP's.  On about 1 in 30
>> boots one gets an endless stream of interrupts from the
>> DISPC_IRQ_SYNC_LOST bit in the DISPC_IRQSTATUS register.  The
>> following messages are printed.
>>
>>  omapfb omapfb: irq error status 4020
>
> Can you try the patch below if it fixes this problem for you? On my new
> display subsystem adding a sleep between enabling clocks and doing the
> soft reset removed the problem.
>
> I tried a bit with different sleep times. With 1ms sleep I still got
> sync losts. With 10ms I didn't, but I went safe and put 40ms.

Unfortunately sleeping there doesn't help for pandora. I've tried
10ms, 40ms, 400ms (this seems to be used by DSS2 now).

However because we are also setting up the display in u-boot for
pandora, I can hook up irq handler early and wait for frame done irq
before resetting DSS (patch attached). With this I've done ~50 reboots
now and hadn't got any sync lost interrupts yet.

In case display is not enabled in bootloader waiting for interrupt
just times out there, so no harm made. This probably could substitute
that sleep, so maybe this solution could be considered for DSS2.
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index c140c21..e73d04a 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -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));

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux