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?
diff.i810-TV
Description: Binary data
