[Trac #280] Video output is delayed after DCON -> GPU transition
Zarro Boogs per Child
bugtracker at laptop.org
Mon Nov 6 20:40:49 EST 2006
#280: Video output is delayed after DCON -> GPU transition
--------------------------+-------------------------------------------------
Reporter: JordanCrouse | Owner: JordanCrouse
Type: defect | Status: new
Priority: blocker | Milestone: BTest-1
Component: kernel | Resolution:
Keywords: |
--------------------------+-------------------------------------------------
Comment (by dwmw2):
{{{
int gxfb_powerdown(struct fb_info *info) {
struct geodefb_par *par = info->par;
/* Bail if we have already saved our state and powered down */
if (gxfb_powered_down == 1)
return 0;
/* Disable the video hardware */
gx_pm_regs[VC_VCFG] = readl(par->vid_regs + GX_VCFG);
writel(gx_pm_regs[VC_VCFG] & ~0x01, par->vid_regs + GX_VCFG);
/* Black the dacs, turn off horiz / vert sync and turn off crt */
gx_pm_regs[VC_DCFG] = readl(par->vid_regs + GX_DCFG);
writel(gx_pm_regs[VC_DCFG] & ~0x0F, par->vid_regs + GX_DCFG);
/* Turn off the flat panel */
gx_pm_regs[VC_FP_PM] = readl(par->vid_regs + GX_FP_PM);
writel(gx_pm_regs[VC_FP_PM] & ~GX_FP_PM_P, par->vid_regs +
GX_FP_PM);
/* Unlock the DC - this will remain unlocked until power up */
writel(0x4758, par->dc_regs + DC_UNLOCK);
/* Disable video, icon, cursor and the FIFO */
gx_pm_regs[DC_GCFG] = readl(par->dc_regs + DC_GENERAL_CFG);
writel(gx_pm_regs[DC_GCFG] & ~0x0F, par->dc_regs +
DC_GENERAL_CFG);
/* Disable video data enable, graphics data enable and the timing
generator */
gx_pm_regs[DC_DCFG] = readl(par->dc_regs + DC_DISPLAY_CFG);
writel(gx_pm_regs[DC_DCFG] & ~0x19, par->dc_regs +
DC_DISPLAY_CFG);
gxfb_powered_down = 1;
return 0;
}
int gxfb_pre_powerup(struct fb_info *info)
{
struct geodefb_par *par = info->par;
if (gxfb_powered_down == 0)
return 0;
writel(gx_pm_regs[VC_VCFG], par->vid_regs + GX_VCFG);
writel(gx_pm_regs[VC_DCFG], par->vid_regs + GX_DCFG);
writel(gx_pm_regs[VC_FP_PM], par->vid_regs + GX_FP_PM);
msleep(50);
return 0;
}
int gxfb_powerup(struct fb_info *info)
{
struct geodefb_par *par = info->par;
writel(gx_pm_regs[DC_DCFG], par->dc_regs + DC_DISPLAY_CFG);
/* Do this one last because it will turn on the FIFO which will
start the line count */
writel(gx_pm_regs[DC_GCFG], par->dc_regs + DC_GENERAL_CFG);
writel(0x0, par->dc_regs + DC_UNLOCK);
gxfb_powered_down = 0;
return 0;
}
}}}
We call gxfb_pre_powerup(), then wait for the IRQ which indicates the end
of the frame in the signal which we're supposed to be synching up with,
then call gxfb_powerup().
In http://david.woodhou.se/dconvga.png the msleep(50) in
gxfb_pre_powerup() is missing -- we actually enable the output before the
device has finished powering up, at about 85ms into the trace. So the
first vsync pulse is lost, and the one we see at 105ms is actually the
start of the _second_ frame we're supposed to be sending.
Ignore dconvga-2.png where we enable the FIFO in gxfb_pre_powerup() so our
vsync pulses aren't even at the correct times.
In http://david.woodhou.se/dconvga-3.png and
http://david.woodhou.se/dconvga-4.png we have a sufficient delay between
gxfb_pre_powerup() and gxfb_powerup(), so that vsync has actually gone
from its inactive low state to its "ready" high state before we call
gxfb_powerup(), and the first vsync is seen at exactly the right time.
--
Ticket URL: <http://dev.laptop.org/ticket/280#comment:4>
One Laptop Per Child <http://laptop.org/>
More information about the Bugs
mailing list