accessing legacy(?) VGA input status register 1 on 945GM/xf86-video-intel

Jesse Barnes jbarnes at
Mon Sep 29 10:19:50 PDT 2008

On Monday, September 29, 2008 4:52 am Theo Veenker wrote:
> Jesse Barnes wrote:
> > On Friday, September 26, 2008 1:36 am Theo Veenker wrote:
> >> Jesse Barnes wrote:
> >>> On Thursday, September 25, 2008 6:00 am Theo Veenker wrote:
> >>>> Hi,
> >>>>
> >>>> I have an application that presents audio-visual stimuli to subjects.
> >>>> To be able to precisely synchronize the audio and graphics the
> >>>> application needs to know when a vsync occurs. My application (from
> >>>> 1994) doesn't yet use libdrm. I'm using a real-time module which
> >>>> (among other things) monitors the vretrace bit in the VGA input status
> >>>> register 1 at 0x3DA and signals the application on each vsync event.
> >>>> It works fine on most graphics hardware.
> >>>>
> >>>> Now I need to make this application work on a laptop with an Intel
> >>>> 945GM. The vretrace bit at IO address 0x3DA doesn't work (under X)
> >>>> unless I connect an external VGA display. Then it works, but it
> >>>> reflects the retrace of the external monitor and not that of the
> >>>> laptop's LCD screen.
> >>>>
> >>>> Since also drmWaitVBlank() didn't work for me on this system, I
> >>>> applied the change hinted in
> >>>> to
> >>>> the xf86-video-intel driver (2.4.2). That makes drmWaitVBlank() work
> >>>> (but only after I briefly run a GL application like glxgears first).
> >>>
> >>> There's some code in the xf86-video-intel driver to disable vblank
> >>> interrupts when no 3D client is running (look for
> >>> want_vblank_interrupts in i830_dri.c, you can either remove the code
> >>> from
> >>> I830DRISetVBlankInterrupt or make that field unconditionally true).
> >>> Maybe that's what you already did.
> >>
> >> Yes that's what I did. With the stock driver drm vblank would only work
> >> while running, for instance, glxgears. After the 'fix' I just need to
> >> run glxgears once and after that it works. I can live with that.
> >>
> >>>> I understand the LCD screen is on pipe B and the VGA screen on pipe A.
> >>>> Can I somehow swap current behaviour so that when I monitor IO address
> >>>> 0x3DA I can detect vretraces for pipe B instead of for pipe A? That
> >>>> would save me the trouble of hacking DRM into this legacy aplication.
> >>>
> >>> I think the status bit in 0x3da will correspond to the pipe VGA is
> >>> assigned to in VGACNTRL (the headers should have the info you need, if
> >>> not check out the docs at
> >>
> >> Thanks for the info. Here is what I did. In i830_driver.c I830PreInit()
> >> below RestoreHWState() I added this:
> >>    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "HACK: setting
> >>
> >> Unfortunately the VGA input status register 1 bit 3 still reflects the
> >> retraces for the external VGA monitor, instead of the laptop's display
> >> panel. So this is problably not correct or I missed something.
> >>
> >> In Xorg.0.log I read "Output VGA is connected to pipe A" and "Output
> >> LVDS is connected to pipe B". Is there a way to swap them, how? And if
> >> so would it make a differrence; I mean is it actually possible to have
> >> the VGA input status register 1 connected to the LVDS?
> >
> > I think so, but given that we disable VGA mode during normal operation,
> > it may be that you need to have pipe B selected at some point *while* VGA
> > mode is active.  OTOH there may be other bits you need to set as well. 
> > You could try searching the docs for the string "VGA" :)
> I'm afraid I'm clueless here as I am not comfortable with the internals of
> the driver. Do you mean I need to be running in VGA mode all the time, or
> do the VGA_PIPE_B_SELECT while temporarily in VGA mode?
> How would one achive that?

I'm not sure, you'd have to play around with it.

> > But if you just want to poll, there's also a bit in the PIPE*STAT regs
> > that indicates whether vblank is active, iirc.
> Thanks. I'm going to check that as well. From kernel space do I need to
> call mmap or pci_request_regions etc to gain access to these registers, or
> can I just access them at the MMIO base address + register offset?

They're part of the regular MMIO BAR on this chip, so if you already have that 
region mapped you can just offset into it to get at the reg.  If you haven't 
already ioremap'd, then yeah you'd have to do that (or just use pci_iomap to 
get at the right BAR), then use the readX/writeX accessor functions on the 
resulting pointer.

Jesse Barnes, Intel Open Source Technology Center

More information about the xorg mailing list