[PATCH r128 1/3] Restore detailed timing usage
Connor Behan
connor.behan at gmail.com
Fri Aug 8 10:09:01 PDT 2014
Since the RandR commit, we no longer parse the detailed timing table.
However, this code probably should have been moved instead of deleted.
The detect hook is a good place to gather this information for DFP
monitors and the mode_fixup hook is a good place to apply it.
Signed-off-by: Connor Behan <connor.behan at gmail.com>
---
src/r128_output.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/r128_probe.h | 9 +++++++
2 files changed, 81 insertions(+)
diff --git a/src/r128_output.c b/src/r128_output.c
index 8ef6d45..83fcb94 100644
--- a/src/r128_output.c
+++ b/src/r128_output.c
@@ -71,6 +71,40 @@ static int r128_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
static Bool r128_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
{
+ ScrnInfoPtr pScrn = output->scrn;
+ R128InfoPtr info = R128PTR(pScrn);
+ R128OutputPrivatePtr r128_output = output->driver_private;
+ xf86CrtcPtr crtc = output->crtc;
+ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
+
+ int xres = adjusted_mode->CrtcHDisplay;
+ int yres = adjusted_mode->CrtcVDisplay;
+
+ if (r128_crtc->crtc_id != 0 || r128_output->DotClock == 0 || info->isPro2)
+ return TRUE;
+
+ if (r128_output->PanelXRes == xres && r128_output->PanelYRes == yres)
+ return TRUE;
+
+ xf86SetModeCrtc(adjusted_mode, 0);
+ adjusted_mode->HTotal = r128_output->PanelXRes + r128_output->HBlank;
+ adjusted_mode->HSyncStart = r128_output->PanelXRes + r128_output->HOverPlus;
+ adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + r128_output->HSyncWidth;
+ adjusted_mode->VTotal = r128_output->PanelYRes + r128_output->VBlank;
+ adjusted_mode->VSyncStart = r128_output->PanelYRes + r128_output->VOverPlus;
+ adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + r128_output->VSyncWidth;
+
+ xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
+ adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + r128_output->HBlank;
+ adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + r128_output->HOverPlus;
+ adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + r128_output->HSyncWidth;
+ adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + r128_output->VBlank;
+ adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + r128_output->VOverPlus;
+ adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + r128_output->VSyncWidth;
+
+ adjusted_mode->Clock = r128_output->DotClock;
+ adjusted_mode->Flags = r128_output->Flags;
+
return TRUE;
}
@@ -225,6 +259,41 @@ void R128DPMSSetOff(xf86OutputPtr output)
}
}
+static void R128UpdatePanelSize(xf86OutputPtr output)
+{
+ R128OutputPrivatePtr r128_output = output->driver_private;
+ xf86MonPtr ddc = output->MonInfo;
+ int i;
+
+ if (ddc == NULL) return;
+
+ for (i = 0; i < 4; i++) {
+ if (ddc->det_mon[i].type != 0) continue;
+ if (ddc->det_mon[i].section.d_timings.h_active <= 0) continue;
+ if (ddc->det_mon[i].section.d_timings.v_active <= 0) continue;
+
+ struct detailed_timings *d_timings = &ddc->det_mon[i].section.d_timings;
+
+ r128_output->PanelXRes = d_timings->h_active;
+ r128_output->PanelYRes = d_timings->v_active;
+ r128_output->HOverPlus = d_timings->h_sync_off;
+ r128_output->HSyncWidth = d_timings->h_sync_width;
+ r128_output->HBlank = d_timings->h_blanking;
+ r128_output->VOverPlus = d_timings->v_sync_off;
+ r128_output->VSyncWidth = d_timings->v_sync_width;
+ r128_output->VBlank = d_timings->v_blanking;
+ r128_output->Flags = d_timings->interlaced ? V_INTERLACE : 0;
+ r128_output->DotClock = d_timings->clock / 1000;
+
+ switch (d_timings->misc) {
+ case 0: r128_output->Flags |= V_NHSYNC | V_NVSYNC; break;
+ case 1: r128_output->Flags |= V_PHSYNC | V_NVSYNC; break;
+ case 2: r128_output->Flags |= V_NHSYNC | V_PVSYNC; break;
+ case 3: r128_output->Flags |= V_PHSYNC | V_PVSYNC; break;
+ }
+ }
+}
+
static R128MonitorType R128DisplayDDCConnected(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
@@ -280,6 +349,9 @@ static void R128ConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output)
* to handle the non-DDC case. */
if (r128_output->MonType == MT_UNKNOWN)
r128_output->MonType = R128DisplayDDCConnected(output);
+
+ if (r128_output->MonType == MT_DFP)
+ R128UpdatePanelSize(output);
}
DisplayModePtr R128ProbeOutputModes(xf86OutputPtr output)
diff --git a/src/r128_probe.h b/src/r128_probe.h
index 0b54d21..e60892b 100644
--- a/src/r128_probe.h
+++ b/src/r128_probe.h
@@ -140,9 +140,18 @@ typedef struct _R128OutputPrivateRec {
R128MonitorType MonType;
I2CBusPtr pI2CBus;
R128I2CBusRec ddc_i2c;
+ /* Computed values for FPs */
+ int HOverPlus;
+ int HSyncWidth;
+ int HBlank;
+ int VOverPlus;
+ int VSyncWidth;
+ int VBlank;
int PanelXRes;
int PanelYRes;
int PanelPwrDly;
+ int Flags;
+ int DotClock;
} R128OutputPrivateRec, *R128OutputPrivatePtr;
#define R128_MAX_CRTC 2
--
2.0.2
More information about the xorg-driver-ati
mailing list