xf86-video-intel: Branch 'modesetting' - 2 commits - configure.ac src/common.h src/i810_reg.h src/i830_debug.c src/i830_display.c src/Makefile.am

Eric Anholt anholt at kemper.freedesktop.org
Thu Mar 1 02:33:07 EET 2007


 configure.ac       |    4 +
 src/Makefile.am    |    6 +-
 src/common.h       |    2 
 src/i810_reg.h     |   25 +++++++++
 src/i830_debug.c   |   98 ++++++++++++++++++++++++++++++++-------
 src/i830_display.c |  133 ++++++++++++++++++++++++++++++++++++-----------------
 6 files changed, 209 insertions(+), 59 deletions(-)

New commits:
diff-tree 1f5d1666c8386ca4597c6f2c1ec239f9d821da4c (from cd1d4b398ec91d551bdaaa26c769e5e6a9442df1)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Feb 28 16:27:55 2007 -0800

    Add a non-installed command line tool using libpciaccess to dump registers.
    
    This reuses the i830_debug.c code, so we can run that from the console or from
    the BIOS-based X server to debug some remaining issues.

diff --git a/configure.ac b/configure.ac
index 395e9d4..775e87f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -87,6 +87,9 @@ XORG_DRIVER_CHECK_EXT(DPMSExtension, xex
 PKG_CHECK_MODULES(XORG, [xorg-server xproto xvmc fontsproto $REQUIRED_MODULES])
 sdkdir=$(pkg-config --variable=sdkdir xorg-server)
 
+PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.5.0], have_pciaccess=yes, have_pciaccess=no)
+AM_CONDITIONAL(HAVE_PCIACCESS, test "x$have_pciaccess" = xyes)
+
 # Checks for libraries.
 
 # Checks for header files.
@@ -200,6 +203,7 @@ AC_OUTPUT([
 	src/ch7017/Makefile
 	src/ch7xxx/Makefile
 	src/ivch/Makefile
+	src/reg_dumper/Makefile
 	src/sil164/Makefile
 	man/Makefile
 ])
diff --git a/src/Makefile.am b/src/Makefile.am
index adb4c42..c65c1e7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,7 +18,11 @@
 #  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 #  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164
+if HAVE_PCIACCESS
+REGDUMPER = reg_dumper
+endif
+
+SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164 $(REGDUMPER)
 
 # this is obnoxious:
 # -module lets us name the module exactly how we want
diff --git a/src/common.h b/src/common.h
index 91e31b5..8f42bde 100644
--- a/src/common.h
+++ b/src/common.h
@@ -72,6 +72,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define DELAY(x) do {;} while (0)
 #endif
 
+#ifndef REG_DUMPER
 /* I830 hooks for the I810 driver setup/probe. */
 extern const OptionInfoRec *I830AvailableOptions(int chipid, int busid);
 extern void I830InitpScrn(ScrnInfoPtr pScrn);
@@ -242,6 +243,7 @@ extern int I810_DEBUG;
 #define DEBUG_ALWAYS_SYNC    0x80
 #define DEBUG_VERBOSE_DRI    0x100
 #define DEBUG_VERBOSE_BIOS   0x200
+#endif /* !REG_DUMPER */
 
 /* Size of the mmio region.
  */
diff --git a/src/i830_debug.c b/src/i830_debug.c
index de36a04..dccaa7e 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -25,6 +25,11 @@
  *
  */
 
+#ifdef REG_DUMPER
+#include "reg_dumper/reg_dumper.h"
+
+#else
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -34,6 +39,10 @@
 #include "i830_debug.h"
 #include <strings.h>
 
+#endif
+
+#include "i810_reg.h"
+
 #define DEBUGSTRING(func) static char *func(I830Ptr pI830, int reg, CARD32 val)
 
 DEBUGSTRING(i830_debug_xyminus1)
@@ -410,6 +419,7 @@ static struct i830SnapshotRec {
 #undef DEFINEREG
 #define NUM_I830_SNAPSHOTREGS (sizeof(i830_snapshot) / sizeof(i830_snapshot[0]))
 
+#ifndef REG_DUMPER
 void i830TakeRegSnapshot(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
@@ -454,6 +464,7 @@ void i830CompareRegsToSnapshot(ScrnInfoP
 	}
     }
 }
+#endif /* !REG_DUMPER */
 
 static void i830DumpIndexed (ScrnInfoPtr pScrn, char *name, int id, int val, int min, int max)
 {
@@ -587,6 +598,7 @@ void i830DumpRegs (ScrnInfoPtr pScrn)
     xf86DrvMsg (pScrn->scrnIndex, X_INFO, "DumpRegsEnd\n");
 }
 
+#ifndef REG_DUMPER
 /* Famous last words
  */
 void
@@ -799,3 +811,4 @@ i830_check_error_state(ScrnInfoPtr pScrn
 
     return (errors != 0);
 }
+#endif /* !REG_DUMPER */
diff-tree cd1d4b398ec91d551bdaaa26c769e5e6a9442df1 (from 3e8e75e5d83a2fa7e9fc6e9a3fbb07dac548ea5a)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Feb 28 09:47:38 2007 -0800

    Many fixes to mode_get, mode_set, clock limits, and register dumps on i855.
    
    This should fix a number of issues with i855s, particularly with integrated
    LVDS panels.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 46d473d..6a9c11e 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -299,6 +299,20 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define VCLK_DIVISOR_VGA0   0x6000
 #define VCLK_DIVISOR_VGA1   0x6004
 #define VCLK_POST_DIV	    0x6010
+/** Selects a post divisor of 4 instead of 2. */
+# define VGA1_PD_P2_DIV_4	(1 << 15)
+/** Overrides the p2 post divisor field */
+# define VGA1_PD_P1_DIV_2	(1 << 13)
+# define VGA1_PD_P1_SHIFT	8
+/** P1 value is 2 greater than this field */
+# define VGA1_PD_P1_MASK	(0x1f << 8)
+/** Selects a post divisor of 4 instead of 2. */
+# define VGA0_PD_P2_DIV_4	(1 << 7)
+/** Overrides the p2 post divisor field */
+# define VGA0_PD_P1_DIV_2	(1 << 5)
+# define VGA0_PD_P1_SHIFT	0
+/** P1 value is 2 greater than this field */
+# define VGA0_PD_P1_MASK	(0x1f << 0)
 
 #define POST_DIV_SELECT        0x70
 #define POST_DIV_1             0x00
@@ -847,9 +861,18 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 # define DPLLB_LVDS_P2_CLOCK_DIV_7		(1 << 24) /* i915 */
 # define DPLL_P2_CLOCK_DIV_MASK			0x03000000 /* i915 */
 # define DPLL_FPA01_P1_POST_DIV_MASK		0x00ff0000 /* i915 */
+/**
+ *  The i830 generation, in DAC/serial mode, defines p1 as two plus this
+ * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
+ */
+# define DPLL_FPA01_P1_POST_DIV_MASK_I830	0x001f0000
+/**
+ * The i830 generation, in LVDS mode, defines P1 as the bit number set within
+ * this field (only one bit may be set).
+ */
+# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS	0x003f0000
 # define DPLL_FPA01_P1_POST_DIV_SHIFT		16
 # define PLL_P2_DIVIDE_BY_4			(1 << 23) /* i830, required in DVO non-gang */
-# define DPLL_FPA01_P1_POS_DIV_MASK_I830	0x001f0000 /* i830 */
 # define PLL_P1_DIVIDE_BY_TWO			(1 << 21) /* i830 */
 # define PLL_REF_INPUT_DREFCLK			(0 << 13)
 # define PLL_REF_INPUT_TVCLKINA			(1 << 13) /* i830 */
diff --git a/src/i830_debug.c b/src/i830_debug.c
index 6716eaa..de36a04 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -102,6 +102,28 @@ DEBUGSTRING(i830_debug_fp)
 		     ((val & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT));
 }
 
+DEBUGSTRING(i830_debug_vga_pd)
+{
+    int vga0_p1, vga0_p2, vga1_p1, vga1_p2;
+
+    /* XXX: i9xx version */
+
+    if (val & VGA0_PD_P1_DIV_2)
+	vga0_p1 = 2;
+    else
+	vga0_p1 = ((val & VGA0_PD_P1_MASK) >> VGA0_PD_P1_SHIFT) + 2;
+    vga0_p2 = (val & VGA0_PD_P2_DIV_4) ? 4 : 2;
+
+    if (val & VGA1_PD_P1_DIV_2)
+	vga1_p1 = 2;
+    else
+	vga1_p1 = ((val & VGA1_PD_P1_MASK) >> VGA1_PD_P1_SHIFT) + 2;
+    vga1_p2 = (val & VGA1_PD_P2_DIV_4) ? 4 : 2;
+
+    return XNFprintf("vga0 p1 = %d, p2 = %d, vga1 p1 = %d, p2 = %d",
+		     vga0_p1, vga0_p2, vga1_p1, vga1_p2);
+}
+
 DEBUGSTRING(i830_debug_pp_status)
 {
     char *status = val & PP_ON ? "on" : "off";
@@ -140,18 +162,44 @@ DEBUGSTRING(i830_debug_dpll)
     char sdvoextra[20];
     int p1, p2 = 0;
 
-    p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK) >>
-	     DPLL_FPA01_P1_POST_DIV_SHIFT);
-    switch (val & DPLL_MODE_MASK) {
-    case DPLLB_MODE_DAC_SERIAL:
-	mode = "dac/serial";
-	p2 = val & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10;
-	break;
-    case DPLLB_MODE_LVDS:
-	mode = "LVDS";
-	p2 = val & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14;
-	break;
+    if (IS_I9XX(pI830)) {
+	p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK) >>
+		 DPLL_FPA01_P1_POST_DIV_SHIFT);
+	switch (val & DPLL_MODE_MASK) {
+	case DPLLB_MODE_DAC_SERIAL:
+	    mode = "DAC/serial";
+	    p2 = val & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10;
+	    break;
+	case DPLLB_MODE_LVDS:
+	    mode = "LVDS";
+	    p2 = val & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14;
+	    break;
+	}
+    } else {
+	Bool is_lvds = (INREG(LVDS) & LVDS_PORT_EN) && (reg == DPLL_B);
+
+	if (val & PLL_P2_DIVIDE_BY_4)
+	    p2 = 4;
+	else
+	    p2 = 2;
+
+	if (is_lvds) {
+	    mode = "LVDS";
+	    /* Map the bit number set from (1, 6) to (-1, 4). */
+	    p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
+		     DPLL_FPA01_P1_POST_DIV_SHIFT);
+	} else {
+	    mode = "DAC/serial";
+	    if (val & PLL_P1_DIVIDE_BY_TWO) {
+		p1 = 2;
+	    } else {
+		/* Map the number in the field to (1, 31) */
+		p1 = ((val & DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
+		      DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
+	    }
+	}
     }
+
     switch (val & PLL_REF_INPUT_MASK) {
     case PLL_REF_INPUT_DREFCLK:
 	clock = "default";
@@ -162,7 +210,12 @@ DEBUGSTRING(i830_debug_dpll)
     case PLL_REF_INPUT_TVCLKINBC:
 	clock = "TV B/C";
 	break;
+    case PLLB_REF_INPUT_SPREADSPECTRUMIN:
+	if (reg == DPLL_B)
+	    clock = "spread spectrum";
+	break;
     }
+
     if (IS_I945G(pI830) || IS_I945GM(pI830)) {
 	sprintf(sdvoextra, ", SDVO mult %d",
 		(int)((val & SDVO_MULTIPLIER_MASK) >>
@@ -171,9 +224,9 @@ DEBUGSTRING(i830_debug_dpll)
 	sdvoextra[0] = '\0';
     }
 
-    return XNFprintf("%s, %s%s, %s mode, %s clock, p1 = %d, "
+    return XNFprintf("%s, %s%s, %s clock, %s mode, p1 = %d, "
 		     "p2 = %d%s%s",
-		     enabled, dvomode, vgamode, mode, clock, p1, p2,
+		     enabled, dvomode, vgamode, clock, mode, p1, p2,
 		     fpextra, sdvoextra);
 }
 
@@ -233,9 +286,9 @@ static struct i830SnapshotRec {
     char *(*debug_output)(I830Ptr pI830, int reg, CARD32 val);
     CARD32 val;
 } i830_snapshot[] = {
-    DEFINEREG(VCLK_DIVISOR_VGA0),
-    DEFINEREG(VCLK_DIVISOR_VGA1),
-    DEFINEREG(VCLK_POST_DIV),
+    DEFINEREG2(VCLK_DIVISOR_VGA0, i830_debug_fp),
+    DEFINEREG2(VCLK_DIVISOR_VGA1, i830_debug_fp),
+    DEFINEREG2(VCLK_POST_DIV, i830_debug_vga_pd),
     DEFINEREG2(DPLL_TEST, i830_debug_dpll_test),
     DEFINEREG(D_STATE),
     DEFINEREG(DSPCLK_GATE_D),
diff --git a/src/i830_display.c b/src/i830_display.c
index a1660e3..e9666de 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -85,10 +85,15 @@ typedef struct {
 #define I8XX_M2_MAX		     16
 #define I8XX_P_MIN		      4
 #define I8XX_P_MAX		    128
+/* LVDS p1 value can go from 1 to 6, while DAC goes from 2 to 33.  These
+ * values below get 2 added in the clock calculations.
+ */
 #define I8XX_P1_MIN		      0
-#define I8XX_P1_MAX		     30
-#define I8XX_P2_SLOW		      1
-#define I8XX_P2_FAST		      0
+#define I8XX_P1_MAX		     31
+#define I8XX_P1_LVDS_MIN	      -1
+#define I8XX_P1_LVDS_MAX	      4
+#define I8XX_P2_SLOW		      1	/* this is a bit shift amount */
+#define I8XX_P2_FAST		      0	/* this is a bit shift amount */
 #define I8XX_P2_SLOW_LIMIT	 165000
 
 #define I9XX_DOT_MIN		  20000
@@ -116,12 +121,13 @@ typedef struct {
 #define I9XX_P2_LVDS_FAST		      7
 #define I9XX_P2_LVDS_SLOW_LIMIT		 112000
 
-#define INTEL_LIMIT_I8XX	    0
-#define INTEL_LIMIT_I9XX_SDVO_DAC   1
-#define INTEL_LIMIT_I9XX_LVDS	    2
+#define INTEL_LIMIT_I8XX_DVO_DAC    0
+#define INTEL_LIMIT_I8XX_LVDS	    1
+#define INTEL_LIMIT_I9XX_SDVO_DAC   2
+#define INTEL_LIMIT_I9XX_LVDS	    3
 
 static const intel_limit_t intel_limits[] = {
-    {
+    { /* INTEL_LIMIT_I8XX_DVO_DAC */
         .dot = { .min = I8XX_DOT_MIN,		.max = I8XX_DOT_MAX },
         .vco = { .min = I8XX_VCO_MIN,		.max = I8XX_VCO_MAX },
         .n   = { .min = I8XX_N_MIN,		.max = I8XX_N_MAX },
@@ -133,7 +139,19 @@ static const intel_limit_t intel_limits[
 	.p2  = { .dot_limit = I8XX_P2_SLOW_LIMIT,
 		 .p2_slow = I8XX_P2_SLOW,	.p2_fast = I8XX_P2_FAST },
     },
-    {
+    { /* INTEL_LIMIT_I8XX_LVDS */
+        .dot = { .min = I8XX_DOT_MIN,		.max = I8XX_DOT_MAX },
+        .vco = { .min = I8XX_VCO_MIN,		.max = I8XX_VCO_MAX },
+        .n   = { .min = I8XX_N_MIN,		.max = I8XX_N_MAX },
+        .m   = { .min = I8XX_M_MIN,		.max = I8XX_M_MAX },
+        .m1  = { .min = I8XX_M1_MIN,		.max = I8XX_M1_MAX },
+        .m2  = { .min = I8XX_M2_MIN,		.max = I8XX_M2_MAX },
+        .p   = { .min = I8XX_P_MIN,		.max = I8XX_P_MAX },
+        .p1  = { .min = I8XX_P1_LVDS_MIN,	.max = I8XX_P1_LVDS_MAX },
+	.p2  = { .dot_limit = I8XX_P2_SLOW_LIMIT,
+		 .p2_slow = I8XX_P2_FAST,	.p2_fast = I8XX_P2_FAST },
+    },
+    { /* INTEL_LIMIT_I9XX_SDVO_DAC */
         .dot = { .min = I9XX_DOT_MIN,		.max = I9XX_DOT_MAX },
         .vco = { .min = I9XX_VCO_MIN,		.max = I9XX_VCO_MAX },
         .n   = { .min = I9XX_N_MIN,		.max = I9XX_N_MAX },
@@ -145,7 +163,7 @@ static const intel_limit_t intel_limits[
 	.p2  = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
 		 .p2_slow = I9XX_P2_SDVO_DAC_SLOW,	.p2_fast = I9XX_P2_SDVO_DAC_FAST },
     },
-    {
+    { /* INTEL_LIMIT_I9XX_LVDS */
         .dot = { .min = I9XX_DOT_MIN,		.max = I9XX_DOT_MAX },
         .vco = { .min = I9XX_VCO_MIN,		.max = I9XX_VCO_MAX },
         .n   = { .min = I9XX_N_MIN,		.max = I9XX_N_MAX },
@@ -168,15 +186,18 @@ static const intel_limit_t *intel_limit 
     I830Ptr	pI830 = I830PTR(pScrn);
     const intel_limit_t *limit;
 
-    if (IS_I9XX(pI830)) 
-    {
+    if (IS_I9XX(pI830)) {
 	if (i830PipeHasType (crtc, I830_OUTPUT_LVDS))
 	    limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS];
 	else
 	    limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
+    } else {
+	if (i830PipeHasType (crtc, I830_OUTPUT_LVDS))
+	    limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS];
+	else
+	    limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC];
     }
-    else
-        limit = &intel_limits[INTEL_LIMIT_I8XX];
+
     return limit;
 }
 
@@ -792,7 +813,15 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 	if (IS_I965G(pI830))
 	    dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
     } else {
-	dpll |= clock.p1 << 16;
+	if (is_lvds) {
+	    /* map (-1 to 4) to ((1 << 0) to (1 << 5)). */
+	    dpll |= (1 << (clock.p1 + 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
+	} else {
+	    if (clock.p1 == 0)
+		dpll |= PLL_P1_DIVIDE_BY_TWO;
+	    else
+		dpll |= clock.p1 << DPLL_FPA01_P1_POST_DIV_SHIFT;
+	}
 	dpll |= clock.p2 << 23;
     }
 
@@ -1250,35 +1279,59 @@ i830_crtc_clock_get(ScrnInfoPtr pScrn, x
     clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
     clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
     clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
-    clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
-		   DPLL_FPA01_P1_POST_DIV_SHIFT);
-    switch (dpll & DPLL_MODE_MASK) {
-    case DPLLB_MODE_DAC_SERIAL:
-	clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10;
-	break;
-    case DPLLB_MODE_LVDS:
-	clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14;
-	break;
-    default:
-	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		   "Unknown DPLL mode %08x in programmed mode\n",
-		   (int)(dpll & DPLL_MODE_MASK));
-	return 0;
-    }
-    
-    /* XXX: Handle the 100Mhz refclk */
-    if (IS_I9XX(pI830))
+    if (IS_I9XX(pI830)) {
+	clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
+		       DPLL_FPA01_P1_POST_DIV_SHIFT);
+
+	switch (dpll & DPLL_MODE_MASK) {
+	case DPLLB_MODE_DAC_SERIAL:
+	    clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10;
+	    break;
+	case DPLLB_MODE_LVDS:
+	    clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14;
+	    break;
+	default:
+	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		       "Unknown DPLL mode %08x in programmed mode\n",
+		       (int)(dpll & DPLL_MODE_MASK));
+	    return 0;
+	}
+
+	/* XXX: Handle the 100Mhz refclk */
 	i9xx_clock(96000, &clock);
-    else
-	i9xx_clock(48000, &clock);
+    } else {
+	Bool is_lvds = (pipe == 1) && (INREG(LVDS) & LVDS_PORT_EN);
 
-    if (!i830PllIsValid(crtc, &clock)) {
-	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		   "Bad clock found programmed in pipe %c\n",
-		   pipe == 0 ? 'A' : 'B');
-	i830PrintPll("", &clock);
+	if (is_lvds) {
+	    /* Map the bit number set from (1, 6) to (-1, 4). */
+	    clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
+			   DPLL_FPA01_P1_POST_DIV_SHIFT) - 2;
+	    clock.p2 = 0;
+	} else {
+	    if (dpll & PLL_P1_DIVIDE_BY_TWO) {
+		clock.p1 = 0;
+	    } else {
+		/* Map the number in the field to (1, 31) */
+		clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
+		    DPLL_FPA01_P1_POST_DIV_SHIFT);
+	    }
+	    if (dpll & PLL_P2_DIVIDE_BY_4)
+		clock.p2 = 1;
+	    else
+		clock.p2 = 0;
+	}
+
+	/* XXX: Deal with other refclocks */
+	i8xx_clock(48000, &clock);
     }
 
+    /* XXX: It would be nice to validate the clocks, but we can't reuse
+     * i830PllIsValid() because it relies on the xf86_config output
+     * configuration being accurate, which it isn't necessarily.
+     */
+    if (0)
+	i830PrintPll("probed", &clock);
+
     return clock.dot;
 }
 
@@ -1299,8 +1352,6 @@ i830_crtc_mode_get(ScrnInfoPtr pScrn, xf
     if (mode == NULL)
 	return NULL;
 
-    memset(mode, 0, sizeof(*mode));
-
     mode->Clock = i830_crtc_clock_get(pScrn, crtc);
     mode->HDisplay = (htot & 0xffff) + 1;
     mode->HTotal = ((htot & 0xffff0000) >> 16) + 1;



More information about the xorg-commit mailing list