Since the driver uses PanelXRes and PanelYRes to calculate stretch ratios, it should try harder to set them. For LVDS, we need to move the xorg.conf check so that it executes before the BIOS check. For DVI, we should read them from the mode that the X server has flagged as being the native one. Even then, PanelXRes and PanelYRes are not guaranteed to be positive, so the driver should verify this before dividing by them.
Another problem with the old panel code was that PanelPwrDly had no sane default. It was also missing the check for Rage Pro 2 which lacks RMX. Signed-off-by: Connor Behan <[email protected]> --- src/r128_driver.c | 35 +++++++++++------------------------ src/r128_output.c | 13 ++++++++++--- src/r128_video.c | 35 +++++++++++++++++++---------------- 3 files changed, 40 insertions(+), 43 deletions(-) diff --git a/src/r128_driver.c b/src/r128_driver.c index 2cbfc81..1110c69 100644 --- a/src/r128_driver.c +++ b/src/r128_driver.c @@ -479,6 +479,10 @@ void R128GetPanelInfoFromBIOS(xf86OutputPtr output) int FPHeader = 0; int i; + r128_output->PanelPwrDly = 200; + xf86GetOptValInteger(info->Options, OPTION_PANEL_WIDTH, &(r128_output->PanelXRes)); + xf86GetOptValInteger(info->Options, OPTION_PANEL_HEIGHT, &(r128_output->PanelYRes)); + if (!info->VBIOS) return; info->FPBIOSstart = 0; @@ -511,8 +515,6 @@ void R128GetPanelInfoFromBIOS(xf86OutputPtr output) } if (!info->FPBIOSstart) return; - xf86GetOptValInteger(info->Options, OPTION_PANEL_WIDTH, &(r128_output->PanelXRes)); - xf86GetOptValInteger(info->Options, OPTION_PANEL_HEIGHT, &(r128_output->PanelYRes)); if (!r128_output->PanelXRes) r128_output->PanelXRes = R128_BIOS16(info->FPBIOSstart + 25); @@ -2850,13 +2852,6 @@ Bool R128InitCrtcRegisters(xf86CrtcPtr crtc, R128SavePtr save, DisplayModePtr mo save->crtc_ext_cntl |= R128_VGA_ATI_LINEAR | R128_XCRT_CNT_EN; - if (info->isDFP && !info->isPro2) { - if (r128_output->PanelXRes < mode->CrtcHDisplay) - mode->HDisplay = mode->CrtcHDisplay = r128_output->PanelXRes; - if (r128_output->PanelYRes < mode->CrtcVDisplay) - mode->VDisplay = mode->CrtcVDisplay = r128_output->PanelYRes; - } - save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0xffff) | (((mode->CrtcHDisplay / 8) - 1) << 16)); @@ -3240,7 +3235,7 @@ Bool R128InitDDARegisters(xf86CrtcPtr crtc, R128SavePtr save, VclkFreq = R128Div(pll->reference_freq * save->feedback_div, pll->reference_div * save->post_div); - if (info->isDFP && !info->isPro2) { + if (info->isDFP && !info->isPro2 && r128_output->PanelXRes > 0) { if (r128_output->PanelXRes != mode->CrtcHDisplay) VclkFreq = (VclkFreq * mode->CrtcHDisplay) / r128_output->PanelXRes; } @@ -3313,7 +3308,7 @@ Bool R128InitDDA2Registers(xf86CrtcPtr crtc, R128SavePtr save, VclkFreq = R128Div(pll->reference_freq * save->feedback_div_2, pll->reference_div * save->post_div_2); - if (info->isDFP && !info->isPro2) { + if (info->isDFP && !info->isPro2 && r128_output->PanelXRes > 0) { if (r128_output->PanelXRes != mode->CrtcHDisplay) VclkFreq = (VclkFreq * mode->CrtcHDisplay) / r128_output->PanelXRes; } @@ -3414,27 +3409,19 @@ ModeStatus R128DoValidMode(xf86OutputPtr output, DisplayModePtr mode, int flags) ScrnInfoPtr pScrn = output->scrn; R128InfoPtr info = R128PTR(pScrn); R128OutputPrivatePtr r128_output = output->driver_private; + int i, j; if (r128_output->MonType == MT_CRT) return MODE_OK; - if (info->isDFP) { - if (r128_output->PanelXRes < mode->CrtcHDisplay || - r128_output->PanelYRes < mode->CrtcVDisplay) - return MODE_NOMODE; - else - return MODE_OK; - } - - if (r128_output->MonType == MT_LCD) { + if (r128_output->MonType == MT_DFP || r128_output->MonType == MT_LCD) { if (mode->Flags & V_INTERLACE) return MODE_NO_INTERLACE; if (mode->Flags & V_DBLSCAN) return MODE_NO_DBLESCAN; } if (r128_output->MonType == MT_LCD && info->VBIOS) { - int i; for (i = info->FPBIOSstart + 64; R128_BIOS16(i) != 0; i += 2) { - int j = R128_BIOS16(i); + j = R128_BIOS16(i); if (mode->CrtcHDisplay == R128_BIOS16(j) && mode->CrtcVDisplay == R128_BIOS16(j + 2)) { @@ -3445,8 +3432,8 @@ ModeStatus R128DoValidMode(xf86OutputPtr output, DisplayModePtr mode, int flags) (float)mode->Clock / 1000); /* Assume we are using expanded mode */ - if (R128_BIOS16(j+5)) j = R128_BIOS16(j+5); - else j += 9; + if (R128_BIOS16(j + 5)) j = R128_BIOS16(j + 5); + else j += 9; mode->Clock = (uint32_t)R128_BIOS16(j) * 10; diff --git a/src/r128_output.c b/src/r128_output.c index 8ef6d45..6c35e78 100644 --- a/src/r128_output.c +++ b/src/r128_output.c @@ -87,7 +87,7 @@ static void r128_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayMode xf86CrtcPtr crtc = output->crtc; R128CrtcPrivatePtr r128_crtc = crtc->driver_private; - if (r128_crtc->crtc_id == 0) + if (r128_crtc->crtc_id == 0 && !info->isPro2) R128InitRMXRegisters(&info->SavedReg, &info->ModeReg, output, adjusted_mode); if (r128_output->MonType == MT_DFP) @@ -97,7 +97,7 @@ static void r128_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayMode else if (r128_output->MonType == MT_CRT) R128InitDACRegisters(&info->SavedReg, &info->ModeReg, output); - if (r128_crtc->crtc_id == 0) + if (r128_crtc->crtc_id == 0 && !info->isPro2) R128RestoreRMXRegisters(pScrn, &info->ModeReg); if (r128_output->MonType == MT_DFP) @@ -305,6 +305,13 @@ DisplayModePtr R128ProbeOutputModes(xf86OutputPtr output) modes = xf86GetDefaultModes(); for (mode = modes; mode != NULL; mode = mode->next) { + if (r128_output->type == OUTPUT_DVI) { + if (mode->type & (M_T_DRIVER | M_T_PREFERRED)) { + r128_output->PanelXRes = mode->HDisplay; + r128_output->PanelYRes = mode->VDisplay; + } + } + xf86SetModeCrtc(mode, INTERLACE_HALVE_V); if (mode->status == MODE_OK) mode->status = R128DoValidMode(output, mode, MODECHECK_FINAL); @@ -459,7 +466,7 @@ Bool R128SetupConnectors(ScrnInfoPtr pScrn) R128I2CInit(output, &r128_output->pI2CBus, output->name); } - if (otypes[i] != OUTPUT_VGA) + if (otypes[i] == OUTPUT_LVDS) R128GetPanelInfoFromBIOS(output); } diff --git a/src/r128_video.c b/src/r128_video.c index dc1f25b..ccb15c3 100644 --- a/src/r128_video.c +++ b/src/r128_video.c @@ -574,16 +574,16 @@ R128CopyData420( uint32_t R128AllocateMemory( - ScrnInfoPtr pScrn, - void **mem_struct, - int size, - int align, - Bool need_accel + ScrnInfoPtr pScrn, + void **mem_struct, + int size, + int align, + Bool need_accel ){ - R128InfoPtr info = R128PTR(pScrn); - ScreenPtr pScreen = xf86ScrnToScreen(pScrn); - Bool do_linear = !need_accel; - uint32_t offset = 0; + R128InfoPtr info = R128PTR(pScrn); + ScreenPtr pScreen = xf86ScrnToScreen(pScrn); + Bool do_linear = !need_accel; + uint32_t offset = 0; #ifdef HAVE_XAA_H if (!info->accel && need_accel) @@ -608,7 +608,7 @@ R128AllocateMemory( offset = area->offset; } #endif - if (!info->useEXA && do_linear) { + if (!info->useEXA && do_linear) { FBLinearPtr linear = *mem_struct; int cpp = info->CurrentLayout.pixel_bytes; @@ -643,9 +643,9 @@ R128AllocateMemory( } offset = linear->offset * cpp; - } + } - return offset; + return offset; } static void @@ -670,7 +670,7 @@ R128DisplayVideo422( int v_inc, h_inc, step_by, tmp, v_inc_shift; int p1_h_accum_init, p23_h_accum_init; int p1_v_accum_init; - Bool rmx_active; + Bool rmx_active = FALSE; R128ECP(pScrn, pPriv); @@ -680,7 +680,8 @@ R128DisplayVideo422( if (pScrn->currentMode->Flags & V_DBLSCAN) v_inc_shift--; - rmx_active = INREG(R128_FP_VERT_STRETCH) & R128_VERT_STRETCH_ENABLE; + if (r128_output->PanelYRes > 0) + rmx_active = INREG(R128_FP_VERT_STRETCH) & R128_VERT_STRETCH_ENABLE; if (rmx_active) { v_inc = ((src_h * pScrn->currentMode->CrtcVDisplay / r128_output->PanelYRes) << v_inc_shift) / drw_h; } else { @@ -756,10 +757,11 @@ R128DisplayVideo420( R128OutputPrivatePtr r128_output = output->driver_private; unsigned char *R128MMIO = info->MMIO; R128PortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; + int v_inc, h_inc, step_by, tmp, leftUV, v_inc_shift; int p1_h_accum_init, p23_h_accum_init; int p1_v_accum_init, p23_v_accum_init; - Bool rmx_active; + Bool rmx_active = FALSE; v_inc_shift = 20; if (pScrn->currentMode->Flags & V_INTERLACE) @@ -767,7 +769,8 @@ R128DisplayVideo420( if (pScrn->currentMode->Flags & V_DBLSCAN) v_inc_shift--; - rmx_active = INREG(R128_FP_VERT_STRETCH) & R128_VERT_STRETCH_ENABLE; + if (r128_output->PanelYRes > 0) + rmx_active = INREG(R128_FP_VERT_STRETCH) & R128_VERT_STRETCH_ENABLE; if (rmx_active) { v_inc = ((src_h * pScrn->currentMode->CrtcVDisplay / r128_output->PanelYRes) << v_inc_shift) / drw_h; } else { -- 2.0.2 _______________________________________________ xorg-driver-ati mailing list [email protected] http://lists.x.org/mailman/listinfo/xorg-driver-ati
