summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hilber <sparkie@lowbyte.de>2009-06-04 21:28:56 +0200
committerPaul Menzel <paulepanter@users.sourceforge.net>2009-06-07 22:05:46 +0200
commita7690d9f0b9a3e0628f51635ba78117b614edf1b (patch)
treefe1765356de2f07519ce9f6252e3d18f25a861fd
parentcf0c3f7feea8dd8273bb6f1738c254ecddd24a81 (diff)
downloadxf86-video-intel-frc-upstream-unstable-with-frc-patches.tar.gz
xf86-video-intel-frc-upstream-unstable-with-frc-patches.tar.bz2
Support for HDMI 1600x1200 50Hz interlaced resolution.upstream-unstable-with-frc-patches
- now supports HDMI 1600x1200 50Hz interlaced resolution - adjustment control now operates at lower speed which is still fairly sufficient Signed-off-by: Thomas Hilber <sparkie@lowbyte.de> Signed-off-by: Paul Menzel <paulepanter@users.sourceforge.net>
-rw-r--r--src/i830_driver.c13
-rw-r--r--src/i830_sdvo.c7
-rw-r--r--src/i830_video.c126
3 files changed, 94 insertions, 52 deletions
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 563d2fb7..1a7d26a7 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2021,13 +2021,14 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
}
/*
- * sync_fields only works with
- * ModeLine "1440x576_50i" 27.75 1440 1488 1609 1769 576 580 585 625 -hsync -vsync interlace
+ * sync_fields currently only works with these modelines
+ * ModeLine "1440x576_50i" 27.75 1440 1488 1609 1769 576 580 585 625 -hsync -vsync interlace
+ * Modeline "1600x1200_50i" 65.92 1600 1696 1864 2131 1200 1203 1207 1238 -hsync +vsync interlace
*/
- if ((pScrn->currentMode->Clock != 27750
- || pScrn->currentMode->HDisplay != 1440
- || pScrn->currentMode->VDisplay != 576)
- && pI830->sync_fields) {
+ if (pI830->sync_fields &&
+ ((pScrn->currentMode->Clock != 27750 || pScrn->currentMode->HDisplay != 1440 || pScrn->currentMode->VDisplay != 576) &&
+ (pScrn->currentMode->Clock != 65920 || pScrn->currentMode->HDisplay != 1600 || pScrn->currentMode->VDisplay != 1200)
+ ) ) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support sync fields with current timing, disabled\n");
pI830->sync_fields = 0;
}
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 29ccd4e5..0e702392 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -1701,7 +1701,14 @@ i830_sdvo_detect(xf86OutputPtr output)
return XF86OutputStatusUnknown;
if (response == 0)
+ /*
+ * allow Xserver to run even without a CRT connected
+ */
+#if 0
return XF86OutputStatusDisconnected;
+#else
+ return XF86OutputStatusConnected;
+#endif
if (i830_sdvo_multifunc_encoder(output)) {
if (dev_priv->attached_output != response) {
diff --git a/src/i830_video.c b/src/i830_video.c
index f870be5d..74e92f16 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -3031,12 +3031,12 @@ i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on)
*/
#define SYF_DISP_DRIFT_FACTOR 1
-/* NOT CURRENTLY USED
+/*
* to allow for smooth adaption also on slower devices we delimit maximum
* trim change per step size.
* this implements some kind of low pass filter for our VCO input.
*/
-#define SYF_MAX_TRIM_REL 1000
+#define SYF_MAX_TRIM_REL 1
/*
* maximum absolute trim values allowed due to current
@@ -3078,7 +3078,7 @@ i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on)
struct _I830_s {
int SYF_debug;
} I830 = {
- 1,
+ 801,
}, *pI830 = &I830;
#else
@@ -3092,12 +3092,20 @@ struct _I830_s {
#define OC_FIELD (1 << 19)
-typedef struct _syf {
+typedef struct _syf_t {
int log;
int cnt;
int trim;
int drift;
int spoint;
+
+ /* HW specific */
+ int lfield;
+ int deadln;
+ int dyzone;
+ int tshift;
+ int hsync_a;
+ int htotal_a;
} syf_t;
extern void log_graph(int, int);
@@ -3109,10 +3117,10 @@ log_graph(val, symb)
static char meter[sizeof(headr)];
if (!symb || symb == 1) {
- time_t t; struct tm *tm;
+ time_t t; struct tm *tm;
- time(&t); tm = localtime(&t);
- ErrorF("%02d:%02d:%02d %s", tm->tm_hour, tm->tm_min, tm->tm_sec, symb ? meter : headr);
+ time(&t); tm = localtime(&t);
+ ErrorF("%02d:%02d:%02d %s", tm->tm_hour, tm->tm_min, tm->tm_sec, symb ? meter : headr);
memset(meter, '-', sizeof(headr) - 1);
return;
}
@@ -3135,21 +3143,43 @@ void
vga_sync_fields(pI830)
I830Ptr pI830;
{
- static int vbl_usec_prev = ~0;
- static int htotal_a, hsync_a;
static syf_t syf;
+ static int vbl_usec_prev = ~0;
int dovsta, dovsta_1, pipea_dsl, pipea_dsl_1, trim, vbl_usec;
/* --- 8< --- */
- if (!htotal_a) {
- htotal_a = INREG(HTOTAL_A);
- hsync_a = INREG(HSYNC_A);
+ if (!syf.htotal_a) {
+ syf.htotal_a = INREG(HTOTAL_A);
+ syf.hsync_a = INREG(HSYNC_A);
+ switch (syf.htotal_a & 0x0000ffff) {
+ case 1439:
+ syf.lfield = 313;
+ syf.deadln = 287;
+ syf.dyzone = 32;
+ syf.tshift = 6;
+ break;
+ case 1599:
+ syf.lfield = 619;
+ syf.deadln = 599;
+ syf.dyzone = 0;
+ syf.tshift = 5;
+ break;
+ }
}
- trim = (INREG(HTOTAL_A) >> 16) - (htotal_a >> 16);
+ trim = (INREG(HTOTAL_A) >> 16) - (syf.htotal_a >> 16);
/*
* the chip does not provide current field status directly.
* but we can derive that from xor'ed dovsta and pipea_dsl contents.
+ * _______________ ________
+ * ____| |_______________| !(dovsta & OC_FIELD)
+ * ____ ___________ ___________ ____
+ * |___| |___| |___| pipea_dsl < DEADLN
+ * ________ 287 _______________
+ * |_______________| |____ field status
+ * 0 313
+ *
+ * "1440x576_50i" 27.75 1440 1488 1609 1769 576 580 585 625 -hsync -vsync interlace
*
* DOVSTA 0x80104000 PIPEA_DSL 0x00000000 0 0 0
* [...]
@@ -3164,21 +3194,26 @@ vga_sync_fields(pI830)
* [...]
* DOVSTA 0x80104000 PIPEA_DSL 0x00000138 312 625 40000
* DOVSTA 0x80104000 PIPEA_DSL 0x00000000 0 0 0
- * _______________ ________
- * ____| |_______________| !(dovsta & OC_FIELD)
- * ____ ___________ ___________ ____
- * |___| |___| |___| pipea_dsl < DEADLN
- * ________ _______________
- * |_______________| |____ field status
*
- * 0 287 313
+ * "1600x1200_50i" 65.92 1600 1696 1864 2131 1200 1203 1207 1238 -hsync +vsync interlace
+ *
+ * DOVSTA 0x80104000 PIPEA_DSL 0x00000000 0 0 0
+ * [...]
+ * DOVSTA 0x80100000 PIPEA_DSL 0x00000256 598 598 19136
+ * DOVSTA 0x80185000 PIPEA_DSL 0x00000257 599 599 19168
+ * [...]
+ * DOVSTA 0x80184000 PIPEA_DSL 0x0000026a 618 618 19776
+ * DOVSTA 0x80180000 PIPEA_DSL 0x00000000 0 619 19808
+ * [...]
+ * DOVSTA 0x80184000 PIPEA_DSL 0x00000256 598 1217 38944
+ * DOVSTA 0x80105000 PIPEA_DSL 0x00000257 599 1218 38976
+ * [...]
+ * DOVSTA 0x80100000 PIPEA_DSL 0x0000026a 618 1237 39584
+ * DOVSTA 0x80104000 PIPEA_DSL 0x00000000 0 0 0
*/
-#define LFIELD 313
-#define DEADLN 287
-#define DYZONE 32
-#define SHIFTV (LFIELD - DEADLN)
-#define LFRAME (LFIELD << 1)
+#define SHIFTV (syf.lfield - syf.deadln)
+#define LFRAME (syf.lfield << 1)
/*
* the next few lines implement a simple glitch detection/correction
@@ -3187,13 +3222,12 @@ vga_sync_fields(pI830)
pipea_dsl = INREG(PIPEA_DSL);
dovsta_1 = INREG(DOVSTA);
pipea_dsl_1 = INREG(PIPEA_DSL);
-
if ((dovsta ^ dovsta_1) & OC_FIELD && pipea_dsl == pipea_dsl_1) {
dovsta = ~dovsta;
}
/* 287 + 26 (+ 313) == 313 (626) */
- vbl_usec = ((pipea_dsl < DEADLN ^ !(dovsta & OC_FIELD)) * LFIELD + pipea_dsl + SHIFTV) % LFRAME << 6;
+ vbl_usec = ((pipea_dsl < syf.deadln ^ !(dovsta & OC_FIELD)) * syf.lfield + pipea_dsl + SHIFTV) % LFRAME << syf.tshift;
if (vbl_usec_prev == ~0) {
vbl_usec_prev = vbl_usec;
@@ -3205,14 +3239,14 @@ vga_sync_fields(pI830)
return;
#endif
}
- if (pI830->SYF_debug) {
- if (abs(vbl_usec - vbl_usec_prev) > pI830->SYF_debug) {
- log_graph(vbl_usec - vbl_usec_prev, '%'); ++syf.log;
- }
- if (abs(vbl_usec - SYF_SYNC_POINT) > pI830->SYF_debug) {
- log_graph(vbl_usec - SYF_SYNC_POINT, ':'); ++syf.log;
- }
- }
+ if (pI830->SYF_debug) {
+ if (abs(vbl_usec - vbl_usec_prev) > pI830->SYF_debug) {
+ log_graph(vbl_usec - vbl_usec_prev, '%'); ++syf.log;
+ }
+ if (abs(vbl_usec - SYF_SYNC_POINT) > pI830->SYF_debug) {
+ log_graph(vbl_usec - SYF_SYNC_POINT, ':'); ++syf.log;
+ }
+ }
#ifndef STANDALONE
@@ -3230,7 +3264,7 @@ vga_sync_fields(pI830)
* 18368
*/
if (SYF_PAL_FIELD_CYCLE - vbl_usec > 0) {
- usleep(SYF_PAL_FIELD_CYCLE - vbl_usec + DYZONE);
+ usleep(SYF_PAL_FIELD_CYCLE - vbl_usec + syf.dyzone);
}
#endif
syf.spoint += vbl_usec - SYF_SYNC_POINT;
@@ -3244,13 +3278,13 @@ vga_sync_fields(pI830)
syf.trim = min(syf.trim, SYF_MAX_TRIM_REL);
if (pI830->SYF_debug & 1 || syf.log) {
- log_graph(0, '+');
- log_graph(syf.spoint, '|');
- log_graph(syf.drift, '*');
- log_graph(0, 1);
- ErrorF("%7d %7d [%3d%+4d]\n",
- syf.drift, syf.spoint, (char)(trim & 0xff), syf.trim);
- }
+ log_graph(0, '+');
+ log_graph(syf.spoint, '|');
+ log_graph(syf.drift, '*');
+ log_graph(0, 1);
+ ErrorF("%7d %7d [%3d%+4d]\n",
+ syf.drift, syf.spoint, (char)(trim & 0xff), syf.trim);
+ }
syf.spoint = 0;
syf.drift = 0;
syf.log = 0;
@@ -3267,9 +3301,9 @@ vga_sync_fields(pI830)
}
if (trim != t) {
t <<= 16;
- OUTREG(HTOTAL_A, htotal_a + t);
- OUTREG(HBLANK_A, htotal_a + t);
- OUTREG(HSYNC_A, hsync_a + (t << 1));
+ OUTREG(HTOTAL_A, syf.htotal_a + t);
+ OUTREG(HBLANK_A, syf.htotal_a + t);
+ OUTREG(HSYNC_A, syf.hsync_a + (t << 1));
OUTREG(PIPEACONF, INREG(PIPEACONF));
}
}