[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