xf86-video-intel: Branch 'modesetting' - src/i810_reg.h src/i830_display.c

Eric Anholt anholt at kemper.freedesktop.org
Wed Apr 12 23:28:38 EEST 2006


 src/i810_reg.h     |   22 ++++---
 src/i830_display.c |  148 ++++++++++++++++++++++++++++++++---------------------
 2 files changed, 104 insertions(+), 66 deletions(-)

New commits:
diff-tree d6edffee7d987ef551e1a94d9fac21beb72a9598 (from 59f88955f57cf0f98458b57418dae25cf53ca180)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Apr 12 12:16:51 2006 -0700

    Initial support for pre-i915 PLL programming. Untested.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 6976553..92d9cf9 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -705,16 +705,20 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 # define DPLL_DVO_HIGH_SPEED			(1 << 30)
 # define DPLL_SYNCLOCK_ENABLE			(1 << 29)
 # define DPLL_VGA_MODE_DIS			(1 << 28)
-# define DPLLB_MODE_DAC_SERIAL			(1 << 26)
-# define DPLLB_MODE_LVDS			(2 << 26)
-# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10	(0 << 24)
-# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5		(1 << 24)
-# define DPLLB_LVDS_P2_CLOCK_DIV_14		(0 << 24)
-# define DPLLB_LVDS_P2_CLOCK_DIV_7		(1 << 24)
-# define DPLL_P2_CLOCK_DIV_MASK			0x03000000
-# define DPLL_FPA01_P1_POST_DIV_MASK		0x00ff0000
+# define DPLLB_MODE_DAC_SERIAL			(1 << 26) /* i915 */
+# define DPLLB_MODE_LVDS			(2 << 26) /* i915 */
+# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10	(0 << 24) /* i915 */
+# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5		(1 << 24) /* i915 */
+# define DPLLB_LVDS_P2_CLOCK_DIV_14		(0 << 24) /* i915 */
+# 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 */
+# 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_TVCLKIN			(2 << 13)
+# define PLL_REF_INPUT_TVCLKINA			(1 << 13) /* i830 */
+# define PLL_REF_INPUT_TVCLKINBC		(2 << 13)
 # define PLLB_REF_INPUT_SPREADSPECTRUMIN	(3 << 13)
 # define DISPLAY_RATE_SELECT_FPA1		(1 << 8)
 # define SDVO_MULTIPLIER_MASK			0x000000ff
diff --git a/src/i830_display.c b/src/i830_display.c
index 8b2c881..c55609d 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -66,10 +66,8 @@ i830PllIsValid(ScrnInfoPtr pScrn, int ou
     I830Ptr pI830 = I830PTR(pScrn);
     int p, m, vco, dotclock;
     int min_m1, max_m1, min_m2, max_m2, min_m, max_m, min_n, max_n;
-    int min_p, max_p;
+    int min_p1, max_p1, min_p, max_p, min_vco, max_vco, min_dot, max_dot;
 
-    min_p = 5;
-    max_p = 80;
     if (pI830->PciInfo->chipType >= PCI_CHIP_I915_G) {
 	min_m1 = 10;
 	max_m1 = 20;
@@ -79,23 +77,36 @@ i830PllIsValid(ScrnInfoPtr pScrn, int ou
 	max_m = 120;
 	min_n = 3;
 	max_n = 8;
+	min_p1 = 1;
+	max_p1 = 8;
 	if (outputs & PIPE_LCD_ACTIVE) {
 	    min_p = 7;
 	    max_p = 98;
+	} else {
+	    min_p = 5;
+	    max_p = 80;
 	}
+	min_vco = 1400000;
+	max_vco = 2800000;
+	min_dot = 20000;
+	max_dot = 400000;
     } else {
-	min_m1 = 16;
-	max_m1 = 24;
-	min_m2 = 7;
-	max_m2 = 11;
-	min_m = 90;
-	max_m = 130;
-	min_n = 4;
-	max_n = 8;
-	if (outputs & PIPE_LCD_ACTIVE) {
-	    min_n = 3;
-	    min_m = 88;
-	}
+	min_m1 = 18;
+	max_m1 = 26;
+	min_m2 = 6;
+	max_m2 = 16;
+	min_m = 96;
+	max_m = 140;
+	min_n = 3;
+	max_n = 16;
+	min_p1 = 2;
+	max_p1 = 18;
+	min_vco = 930000;
+	max_vco = 1400000;
+	min_dot = 20000;
+	max_dot = 350000;
+	min_p = 4;
+	max_p = 128;
     }
 
     p = p1 * p2;
@@ -103,7 +114,7 @@ i830PllIsValid(ScrnInfoPtr pScrn, int ou
     vco = refclk * m / n;
     dotclock = i830_clock(refclk, m1, m2, n, p1, p2);
 
-    if (p1 < 1 || p1 > 8)
+    if (p1 < min_p1 || p1 > max_p1)
 	return FALSE;
     if (p < min_p || p > max_p)
 	return FALSE;
@@ -117,12 +128,12 @@ i830PllIsValid(ScrnInfoPtr pScrn, int ou
 	return FALSE;
     if (n < min_n || n > max_n)
 	return FALSE;
-    if (vco < 1400000 || vco > 2800000)
+    if (vco < min_vco || vco > max_vco)
 	return FALSE;
     /* XXX: We may need to be checking "Dot clock" depending on the multiplier,
      * output, etc., rather than just a single range.
      */
-    if (dotclock < 20000 || dotclock > 400000)
+    if (dotclock < min_dot || dotclock > max_dot)
 	return FALSE;
 
     return TRUE;
@@ -215,36 +226,48 @@ i830FindBestPLL(ScrnInfoPtr pScrn, int o
     I830Ptr pI830 = I830PTR(pScrn);
     int m1, m2, n, p1, p2;
     int err = target;
-    int min_m1, max_m1, min_m2, max_m2;
+    int min_m1, max_m1, min_m2, max_m2, min_n, max_n, min_p1, max_p1;
 
     if (pI830->PciInfo->chipType >= PCI_CHIP_I915_G) {
 	min_m1 = 10;
 	max_m1 = 20;
 	min_m2 = 5;
 	max_m2 = 9;
+	min_n = 3;
+	max_n = 8;
+	min_p1 = 1;
+	max_p1 = 8;
+	if (outputs & PIPE_LCD_ACTIVE) {
+	    if (target < 200000) /* XXX: Is this the right cutoff? */
+		p2 = 14;
+	    else
+		p2 = 7;
+	} else {
+	    if (target < 200000)
+		p2 = 10;
+	    else
+		p2 = 5;
+	}
     } else {
-	min_m1 = 16;
-	max_m1 = 24;
-	min_m2 = 7;
-	max_m2 = 11;
-    }
-
-    if (outputs & PIPE_LCD_ACTIVE) {
-	if (target < 200000) /* XXX: Is this the right cutoff? */
-	    p2 = 14;
-	else
-	    p2 = 7;
-    } else {
-	if (target < 200000)
-	    p2 = 10;
+	min_m1 = 18;
+	max_m1 = 26;
+	min_m2 = 6;
+	max_m2 = 16;
+	min_n = 3;
+	max_n = 16;
+	min_p1 = 2;
+	max_p1 = 18;
+	if (target < 165000)
+	    p2 = 4;
 	else
-	    p2 = 5;
+	    p2 = 2;
     }
 
+
     for (m1 = min_m1; m1 <= max_m1; m1++) {
 	for (m2 = min_m2; m2 < max_m2; m2++) {
-	    for (n = 3; n <= 8; n++) {
-		for (p1 = 1; p1 <= 8; p1++) {
+	    for (n = min_n; n <= max_n; n++) {
+		for (p1 = min_p1; p1 <= max_p1; p1++) {
 		    int clock, this_err;
 
 		    if (!i830PllIsValid(pScrn, outputs, refclk, m1, m2, n,
@@ -309,7 +332,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     CARD32 htot, hblank, hsync, vtot, vblank, vsync, dspcntr;
     CARD32 pipesrc, dspsize, adpa;
     Bool ok;
-    int refclk = 96000, pixel_clock;
+    int refclk, pixel_clock;
     int outputs;
 
     ErrorF("Requested pix clock: %d\n", pMode->Clock);
@@ -385,6 +408,11 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
 	pixel_clock = pI830->panel_fixed_clock;
     }
 
+    if (pI830->PciInfo->chipType >= PCI_CHIP_I915_G) {
+	refclk = 96000;
+    } else {
+	refclk = 48000;
+    }
     ok = i830FindBestPLL(pScrn, outputs, pixel_clock, refclk, &m1, &m2, &n,
 			 &p1, &p2);
     if (!ok) {
@@ -394,28 +422,34 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     }
 
     dpll = DPLL_VCO_ENABLE | DPLL_VGA_MODE_DIS;
-    if (outputs & PIPE_LCD_ACTIVE)
-	dpll |= DPLLB_MODE_LVDS;
-    else
-	dpll |= DPLLB_MODE_DAC_SERIAL;
-
-    dpll |= (1 << (p1 - 1)) << 16;
-    switch (p2) {
-    case 5:
-	dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
-	break;
-    case 7:
-	dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
-	break;
-    case 10:
-	dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
-	break;
-    case 14:
-	dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
-	break;
+    if (pI830->PciInfo->chipType >= PCI_CHIP_I915_G) {
+	if (outputs & PIPE_LCD_ACTIVE)
+	    dpll |= DPLLB_MODE_LVDS;
+	else
+	    dpll |= DPLLB_MODE_DAC_SERIAL;
+	dpll |= (1 << (p1 - 1)) << 16;
+	switch (p2) {
+	case 5:
+	    dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
+	    break;
+	case 7:
+	    dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
+	    break;
+	case 10:
+	    dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
+	    break;
+	case 14:
+	    dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
+	    break;
+	}
+    } else {
+	dpll |= (p1 - 2) << 16;
+	if (p2 == 4)
+	    dpll |= PLL_P2_DIVIDE_BY_4;
     }
+
     if (outputs & (PIPE_TV_ACTIVE | PIPE_TV2_ACTIVE))
-	dpll |= PLL_REF_INPUT_TVCLKIN;
+	dpll |= PLL_REF_INPUT_TVCLKINBC;
     else
 	dpll |= PLL_REF_INPUT_DREFCLK;
     dpll |= SDV0_DEFAULT_MULTIPLIER;



More information about the xorg-commit mailing list