RADEONValidateDDCModes() issue

Benjamin Herrenschmidt benh at kernel.crashing.org
Thu Nov 11 15:38:02 PST 2004


Hi !

I'm fixing various issues in the radeon driver, mostly happening on PPC,
along with adding a couple of options that will be useful there. Among
those issues, I need to remove the test of UseBiosDividers in
RADEONValidateDDCModes(). Can someone explain me why this test is here
in the first place ?

The fact that we use a fixed set of dividers (& so pixel clock) doesn't
impact the actual panel size not the modes we can use for it with RMX...
or is that meant to prevent UpdatePanelSize from updating the panel
infos ? In that case, I need to change the logic a bit, since when we
don't get the panel infos from ROM, we don't have a dotclock, which
breaks ValidateFPModes(). The "guess" of dotclock via the VESA modes is
no use for non-std size panels (apple ones), so we need to fetch the dot
clock from the detailed timing. I typically added a mecanism for
fetching it from UpdatePanelSize().

In addition, I've added a "LVDSProbePLL" option that "probes" the PPLL
setting at launch time and sets UseBiosDividers with that value. This is
necessary to keep the proper PLL value from the firmware on PPCs where
we don't get that value from the BIOS. This triggers the problem above
though, sine UseBiosDividers gets set, ValidateDDCMode would no longer
find the DDC modes, thus UpdatePanelSize wouldn't be called, and thus I
never get a chance to set the DotClock -> ValidateFPModes fails.

So I removed that test, added a DotClockGuessed member to "info" which
is set when the dotclocked has been guessed by the VESA mode search
algorithm (meaning it may not be right), and now let UpdatePanelSize fix
the dotclock properly from the detailed timing table.

Here's the UpdatePanelSize() code:

static void RADEONUpdatePanelSize(ScrnInfoPtr pScrn)
{
    int             j;
    RADEONInfoPtr   info = RADEONPTR (pScrn);
    xf86MonPtr      ddc  = pScrn->monitor->DDC;
    DisplayModePtr  p;

    /* Go thru detailed timing table first */
    for (j = 0; j < 4; j++) {
	if (ddc->det_mon[j].type == 0) {
	    struct detailed_timings *d_timings =
		&ddc->det_mon[j].section.d_timings;
	    int match = 0;

	    /* If we didn't get a panel clock or guessed one, try to match the
	     * mode with the panel size. We do that because we _need_ a panel
	     * clock, or ValidateFPModes will fail, even when UseBiosDividers
	     * is set.
	     */
	    if ((info->DotClock == 0 || info->DotClockGuessed) &&
		info->PanelXRes == d_timings->h_active &&
		info->PanelYRes == d_timings->v_active)
	        match = 1;
	    
	    /* If we don't have a BIOS provided panel data, check for panel size
	     */
	    if (info->PanelXRes < d_timings->h_active &&
		  info->PanelYRes < d_timings->v_active &&
		  !info->UseBiosDividers)) {
		info->PanelXRes  = d_timings->h_active;
		info->PanelYRes  = d_timings->v_active;
		info->DotClock   = d_timings->clock / 1000;
		info->HOverPlus  = d_timings->h_sync_off;
		info->HSyncWidth = d_timings->h_sync_width;
		info->HBlank     = d_timings->h_blanking;
		info->VOverPlus  = d_timings->v_sync_off;
		info->VSyncWidth = d_timings->v_sync_width;
		info->VBlank     = d_timings->v_blanking;
	    }
	}
    }
    if (info->UseBiosDividers)
        return;

    /* Search thru standard VESA modes from EDID */

   .../...

I didn't change the rest of the function.

Any comment ? I'll propose a patch adding those changes later today.

Ben.





More information about the xorg mailing list