I think I finally found the time to look at this.
The diff below now makes sure we only touch the
OVRACT registers when the CRT timings are used
ie. if TV/LCD is off or bit 28 (use VGA Mode) is 1.

Please apply this to a version of the i810 driver
from CVS head and test it thoroughly.

Regards,
        Egbert.


Sottek, Matthew J writes:
 > I'll try to summarize.
 > 
 > The OVRACT register controls how the overlay lines up with the TV/LCD
 > output.
 > This alignment needs to be calculated based on the horizontal timings being
 > used on the TV.
 > 
 > On an i810/i815 the video bios will program the timings for the TV
 > controller
 > if it is used as the primary output device. The CRT timings are then
 > centered
 > in the TV timings which allows XFree to display on the TV using one, fixed,
 > TV resolution that was chosen by the vbios.
 > 
 > Since this mechanism was designed for compatibility with VGA, DOS etc, the
 > vbios is not programming the OVRACT register... this register was being set
 > in Set Mode which made it work for at least one TV controller in at least
 > one mode.
 > 
 > If we base the OVRACT register programming on the sync timings set by the
 > vbios you can probably make it work for everyone.
 > 
 > If the TV is active:
 >    Regs 0x60000-0x60023 control the timings in use by the GMCH is bit 28
 >     in lcdtv_c is 0 (This is usually the case). The CRTC timings are
 >     centered in these values if bit 29 is 1 (usual case)
 >    OVRACT needs to be programmed off the TV regs if they are in use.
 > If the TV is not active
 >    CRTC regs control the timings
 >    OVRACT needs to be programmed off the CRTC regs
 > 
 > For an LCD the vbios may or may not be using the LCD/TV timings depending
 > on the capabilities of the LCD device. I suggest checking bit 28 of
 > lcdtv_c to make sure that the TV regs are in use. The centering probably
 > doesn't matter because the end timings are still those in the TV regs.
 > 
 > At this point, if this works for both of you, I suggest committing it and
 > asking for lots of testing. You will have a lot of permutations of
 > LCD encoders, LCD displays, and TV encoders that may all behave
 > differently. Only widespread testing will indicate if it is an
 > improvement.
 > 
 > Egbert,
 >   Wherever you end up putting this you can probably replace any other
 > programming of OVRACT. Just make sure that if you switch away or change
 > modes for any reason that you read the timings again. A stand alone TV
 > driver could have changed them.
 > 
 > 
 >  -Matt
 > 
 > 
 > File : xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c
 >     Somewhere near line 1522
 >  
 >      unsigned int lcdtv_c=0;
 >      unsigned int tv_htotal=0;
 >   
 >      /* OVRACT Register */
 >      lcdtv_c = INREG(0x60018);
 >      tv_htotal = INREG(0x60000);
 >  
 >      if((lcdtv_c & 0x80000000) &&
 >         (~lcdtv_c & 0x20000000) &&
 >         (tv_htotal)) {
 >        i810Reg->OverlayActiveStart = (temp>>16) - 31; 
 >        i810Reg->OverlayActiveEnd = (temp & 0x3ff) - 31; 
 >      } else {
 >        i810Reg->OverlayActiveStart = mode->CrtcHTotal - 32; 
 >        i810Reg->OverlayActiveEnd = mode->CrtcHDisplay - 32; 
 >      }
 > 
 > 
 > -----Original Message-----
 > From: Egbert Eich [mailto:eich@;XFree86.Org]
 > Sent: Wednesday, October 16, 2002 5:44 AM
 > To: [EMAIL PROTECTED]
 > Cc: Sebastien BASTARD
 > Subject: RE: [Xpert]!! Correction for i810 driver !!
 > 
 > 
 > Hi Matthew,
 > 
 > thanks for following up on this.
 > 
 > Sottek, Matthew J writes:
 >  > Egbert,
 >  >   Actually... I'm thinking there is a problem with this way too. We need
 >  > another "if" in there. i.e.
 >  > 
 >  > if((tv is on) && (vbios left a set of TV timings for us)) {
 >  >    use TV regs;
 >  > } else {
 >  >    use crt regs;
 >  > }
 >  > 
 >  > Otherwise we might end up using the TV timings even when the display is
 > not
 >  > on
 >  > the TV (depending on what the vbios does when using CRT in a system that
 > has
 >  > a TV controller).
 > 
 > 
 > Yes, I suspected something like this. 
 > 
 >  > 
 >  > Check the LCDTV_C register (offset 0x60018) bit 31. If it is set then
 >  > the TV is in use. So try this one:
 >  > 
 >  > File : xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c
 >  >    Somewhere near line 1522
 >  >  
 >  > 
 >  >     unsigned int lcdtv_c=0;
 >  >     unsigned int tv_htotal=0;
 >  >  
 >  >     /* OVRACT Register */
 >  >     lcdtv_c = INREG(0x60018);
 >  >     tv_htotal = INREG(0x60000);
 >  > 
 >  >     if((lcdtv_c & 0x80000000) && (tv_htotal)) {
 >  >       i810Reg->OverlayActiveStart = (temp>>16) - 31; 
 >  >       i810Reg->OverlayActiveEnd = (temp & 0x3ff) - 31; 
 >  >     } else {
 >  >       i810Reg->OverlayActiveStart = mode->CrtcHTotal - 32; 
 >  >       i810Reg->OverlayActiveEnd = mode->CrtcHDisplay - 32; 
 >  >     }
 >  > 
 >  > 
 > 
 > We may need more changes than that.
 > 
 > It is still not clear to me if the change in
 > the OverlayActiveStart and OverlayActiveEnd settings
 > will do on an LCD. 
 > In the end we are just reducing the ActiveStart and
 > ActiveEnd registers by 31. I don't see why we need to
 > do this.
 > Also we read out the values in SetMode. When this function
 > gets called the values of these regsiters may not be the
 > original ones set by the BIOS any more as SetMode()
 > may be called several times.
 > We need to grab the value in PreInit() - or if the
 > BIOS may change them behind our back - save and compare
 > the value we have set and refresh it in case it has
 > changed.
 > However I won't implement this until I understand better
 > why we have to touch these values in the first place.
 > 
 > Sebastien, could you please check what happens when these
 > these values are left the way the BIOS set them?


Attachment: diff.i810-TV
Description: Binary data

Reply via email to