xf86-video-intel: 2 commits - src/ch7017/ch7017.c src/ch7017/ch7017_reg.h src/i830_dvo.c src/i830.h

Eric Anholt anholt at kemper.freedesktop.org
Mon Oct 1 17:30:12 PDT 2007


 src/ch7017/ch7017.c     |   52 ++++++++++++++++++++++++++++--------------------
 src/ch7017/ch7017_reg.h |   13 +++++++++++-
 src/i830.h              |    1 
 src/i830_dvo.c          |   10 +++++++--
 4 files changed, 52 insertions(+), 24 deletions(-)

New commits:
diff-tree 04e936935f0b0045600241424f1d04a6721a2432 (from 263d48ad93a0fb7100729d0c6e0443797c20c80a)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Oct 1 17:29:35 2007 -0700

    Bring the CH7017 driver closer to spec.
    
    This is also closer to what my hardware is programmed with, except for some
    very confusing off-by-one bugs in an unexpected direction.

diff --git a/src/ch7017/ch7017.c b/src/ch7017/ch7017.c
index ceb8a2a..f8e2b31 100644
--- a/src/ch7017/ch7017.c
+++ b/src/ch7017/ch7017.c
@@ -50,6 +50,7 @@ struct ch7017_priv {
     CARD8 save_hapi;
     CARD8 save_vali;
     CARD8 save_valo;
+    CARD8 save_ailo;
     CARD8 save_lvds_pll_vco;
     CARD8 save_feedback_div;
     CARD8 save_lvds_control_2;
@@ -157,31 +158,34 @@ ch7017_mode_set(I2CDevPtr d, DisplayMode
     ch7017_dump_regs(d);
 
     /* LVDS PLL settings from page 75 of 7017-7017ds.pdf*/
-    if (mode->Clock < 50000) {
-	lvds_pll_feedback_div = 45;
-	lvds_pll_vco_control = (2 << 4) | (3 << 0);
-	outputs_enable = (0 << 0); /* XXX: enables */
+    if (mode->Clock < 100000) {
+	outputs_enable = CH7017_LVDS_CHANNEL_A | CH7017_CHARGE_PUMP_LOW;
+	lvds_pll_feedback_div = CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED |
+	    (2 << CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT) |
+	    (13 << CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT);
+	lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED |
+	    (2 << CH7017_LVDS_PLL_VCO_SHIFT) |
+	    (3 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT);
 	lvds_control_2 = (1 << CH7017_LOOP_FILTER_SHIFT) |
 	    (0 << CH7017_PHASE_DETECTOR_SHIFT);
-    } else if (mode->Clock < 100000) {
-	lvds_pll_feedback_div = 45;
-	lvds_pll_vco_control = (2 << 4) | (3 << 0);
-	outputs_enable = (0 << 0); /* XXX: enables */
-	lvds_control_2 = (1 << CH7017_LOOP_FILTER_SHIFT) |
-	    (0 << CH7017_PHASE_DETECTOR_SHIFT);
-    } else if (mode->Clock < 160000) {
+    } else {
+	outputs_enable = CH7017_LVDS_CHANNEL_A | CH7017_CHARGE_PUMP_HIGH;
+	lvds_pll_feedback_div = CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED |
+	    (2 << CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT) |
+	    (3 << CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT);
 	lvds_pll_feedback_div = 35;
-	outputs_enable = (3 << 0); /* XXX: enables */
 	lvds_control_2 = (3 << CH7017_LOOP_FILTER_SHIFT) |
 	    (0 << CH7017_PHASE_DETECTOR_SHIFT);
-	if (1) { /* XXX: dual panel */
-	    lvds_pll_vco_control = (2 << 4) | (13 << 0);
+	if (1) { /* XXX: dual channel panel detection.  Assume yes for now. */
+	    outputs_enable |= CH7017_LVDS_CHANNEL_B;
+	    lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED |
+		(2 << CH7017_LVDS_PLL_VCO_SHIFT) |
+		(13 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT);
 	} else {
-	    lvds_pll_vco_control = (1 << 4) | (13 << 0);
+	    lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED |
+		(1 << CH7017_LVDS_PLL_VCO_SHIFT) |
+		(13 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT);
 	}
-    } else {
-	FatalError("Invalid mode clock (%.1fMHz)\n",
-		   (float)mode->Clock / 1000.0);
     }
 
     horizontal_active_pixel_input = mode->HDisplay & 0x00ff;
@@ -189,10 +193,11 @@ ch7017_mode_set(I2CDevPtr d, DisplayMode
     vertical_active_line_output = mode->VDisplay & 0x00ff;
     horizontal_active_pixel_output = mode->HDisplay & 0x00ff;
 
-    active_input_line_output = ((mode->HDisplay & 0x0700) >> 9) |
-	((mode->VDisplay & 0x0700) >> 8);
+    active_input_line_output = ((mode->HDisplay & 0x0700) >> 8) |
+	(((mode->VDisplay & 0x0700) >> 8) << 3);
 
-    lvds_power_down = (mode->HDisplay & 0x0f00) >> 8;
+    lvds_power_down = CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED |
+	(mode->HDisplay & 0x0700) >> 8;
 
     ch7017_dpms(d, DPMSModeOff);
     ch7017_write(priv, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT,
@@ -201,6 +206,8 @@ ch7017_mode_set(I2CDevPtr d, DisplayMode
 		    horizontal_active_pixel_output);
     ch7017_write(priv, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT,
 		    vertical_active_line_output);
+    ch7017_write(priv, CH7017_ACTIVE_INPUT_LINE_OUTPUT,
+		 active_input_line_output);
     ch7017_write(priv, CH7017_LVDS_PLL_VCO_CONTROL, lvds_pll_vco_control);
     ch7017_write(priv, CH7017_LVDS_PLL_FEEDBACK_DIV, lvds_pll_feedback_div);
     ch7017_write(priv, CH7017_LVDS_CONTROL_2, lvds_control_2);
@@ -261,6 +268,7 @@ do {							\
     DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT);
     DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT);
     DUMP(CH7017_VERTICAL_ACTIVE_LINE_OUTPUT);
+    DUMP(CH7017_ACTIVE_INPUT_LINE_OUTPUT);
     DUMP(CH7017_LVDS_PLL_VCO_CONTROL);
     DUMP(CH7017_LVDS_PLL_FEEDBACK_DIV);
     DUMP(CH7017_LVDS_CONTROL_2);
@@ -275,6 +283,7 @@ ch7017_save(I2CDevPtr d)
 
     ch7017_read(priv, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT, &priv->save_hapi);
     ch7017_read(priv, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT, &priv->save_valo);
+    ch7017_read(priv, CH7017_ACTIVE_INPUT_LINE_OUTPUT, &priv->save_ailo);
     ch7017_read(priv, CH7017_LVDS_PLL_VCO_CONTROL, &priv->save_lvds_pll_vco);
     ch7017_read(priv, CH7017_LVDS_PLL_FEEDBACK_DIV, &priv->save_feedback_div);
     ch7017_read(priv, CH7017_LVDS_CONTROL_2, &priv->save_lvds_control_2);
@@ -293,6 +302,7 @@ ch7017_restore(I2CDevPtr d)
 
     ch7017_write(priv, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT, priv->save_hapi);
     ch7017_write(priv, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT, priv->save_valo);
+    ch7017_write(priv, CH7017_ACTIVE_INPUT_LINE_OUTPUT, priv->save_ailo);
     ch7017_write(priv, CH7017_LVDS_PLL_VCO_CONTROL, priv->save_lvds_pll_vco);
     ch7017_write(priv, CH7017_LVDS_PLL_FEEDBACK_DIV, priv->save_feedback_div);
     ch7017_write(priv, CH7017_LVDS_CONTROL_2, priv->save_lvds_control_2);
diff --git a/src/ch7017/ch7017_reg.h b/src/ch7017/ch7017_reg.h
index 89f81cc..3344c4e 100644
--- a/src/ch7017/ch7017_reg.h
+++ b/src/ch7017/ch7017_reg.h
@@ -99,11 +99,12 @@
 
 #define CH7017_LVDS_POWER_DOWN		0x63
 /** High bits of horizontal active pixel output */
-#define CH7017_LVDS_HAP_HIGH_MASK	(0xf << 0)
+#define CH7017_LVDS_HAP_HIGH_MASK	(0x7 << 0)
 /** Enables the LVDS power down state transition */
 #define CH7017_LVDS_POWER_DOWN_EN	(1 << 6)
 /** Enables the LVDS upscaler */
 #define CH7017_LVDS_UPSCALER_EN		(1 << 7)
+#define CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED 0x08
 
 #define CH7017_LVDS_ENCODING		0x64
 #define CH7017_LVDS_DITHER_2D		(1 << 2)
@@ -127,10 +128,20 @@
 #define CH7017_GPIO_DRIVER_TYPE		0x6c
 #define CH7017_GPIO_DATA		0x6d
 #define CH7017_GPIO_DIRECTION_CONTROL	0x6e
+
 #define CH7017_LVDS_PLL_FEEDBACK_DIV	0x71
+# define CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT 4
+# define CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT 0
+# define CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED 0x80
+
 #define CH7017_LVDS_PLL_VCO_CONTROL	0x72
+# define CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED 0x80
+# define CH7017_LVDS_PLL_VCO_SHIFT	4
+# define CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT 0
 
 #define CH7017_OUTPUTS_ENABLE		0x73
+# define CH7017_CHARGE_PUMP_LOW		0x0
+# define CH7017_CHARGE_PUMP_HIGH	0x3
 # define CH7017_LVDS_CHANNEL_A		(1 << 3)
 # define CH7017_LVDS_CHANNEL_B		(1 << 4)
 # define CH7017_TV_DAC_A		(1 << 5)
diff-tree 263d48ad93a0fb7100729d0c6e0443797c20c80a (from 219354af212c7b68c20df689692c55331e36a705)
Author: Eric Anholt <eric at anholt.net>
Date:   Mon Oct 1 16:23:30 2007 -0700

    Fix probing of the sample CH7017 device I found by allowing GPIO overrides.
    
    It may be that the LVDS chips need to be DVOA and GPIOB only on mobility
    devices with them, and DVOC/GPIOE on non-mobility like this 845.  But until
    more examples are found, just make this one device probe.

diff --git a/src/i830.h b/src/i830.h
index b1f1f68..0a4b4a7 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -221,6 +221,7 @@ struct _I830DVODriver {
    char *modulename;
    char *fntablename;
    unsigned int dvo_reg;
+   uint32_t gpio;
    int address;
    const char **symbols;
    I830I2CVidOutputRec *vid_rec;
diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 8ba38bd..e6ff6af 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -99,9 +99,10 @@ struct _I830DVODriver i830_dvo_drivers[]
 	.type = I830_OUTPUT_DVO_LVDS,
 	.modulename = "ch7017",
 	.fntablename = "ch7017_methods",
-	.dvo_reg = DVOA,
+	.dvo_reg = DVOC,
 	.address = 0xea,
 	.symbols = ch7017_symbols,
+	.gpio = GPIOE,
     }
 };
 
@@ -430,7 +431,12 @@ i830_dvo_init(ScrnInfoPtr pScrn)
 	ret_ptr = NULL;
 	drv->vid_rec = LoaderSymbol(drv->fntablename);
 
-	if (drv->type == I830_OUTPUT_DVO_LVDS)
+	/* Allow the I2C driver info to specify the GPIO to be used in
+	 * special cases, but otherwise default to what's defined in the spec.
+	 */
+	if (drv->gpio != 0)
+	    gpio = drv->gpio;
+	else if (drv->type == I830_OUTPUT_DVO_LVDS)
 	    gpio = GPIOB;
 	else
 	    gpio = GPIOE;


More information about the xorg-commit mailing list