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