[PATCH r128] Improve panel code

Connor Behan connor.behan at gmail.com
Sun Aug 10 18:27:06 PDT 2014


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 <connor.behan at gmail.com>
---
 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



More information about the xorg-driver-ati mailing list