xf86-video-intel: src/ivch/ivch.c src/ivch/ivch_reg.h
Keith Packard
keithp at kemper.freedesktop.org
Thu May 17 14:11:50 PDT 2007
src/ivch/ivch.c | 55 +++++++++++++++++++++++++++++++++++++---------------
src/ivch/ivch_reg.h | 14 +++++++++++--
2 files changed, 52 insertions(+), 17 deletions(-)
New commits:
diff-tree a441954630c6cdabbf463bfc3404160f97a04b4f (from c0daa0a982e7074af4b50653b4a45b0a6352b43d)
Author: Keith Packard <keithp at dulcimer.keithp.com>
Date: Thu May 17 14:11:49 2007 -0700
Enable panel fitter on ivch DVO.
Using BIOS source code as a guide, set up the panel fitter on the ivch. This
involves setting the pipe to the panel fixed mode, the DVO to the source
size and assigning vertical and horizontal scaling factors in the ivch
itself.
diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c
index a76e339..e0755c0 100644
--- a/src/ivch/ivch.c
+++ b/src/ivch/ivch.c
@@ -157,8 +157,6 @@ ivch_init(I2CBusPtr b, I2CSlaveAddr addr
struct ivch_priv *priv;
CARD16 temp;
- xf86DrvMsg(b->scrnIndex, X_INFO, "detecting ivch\n");
-
priv = xcalloc(1, sizeof(struct ivch_priv));
if (priv == NULL)
return NULL;
@@ -191,10 +189,6 @@ ivch_init(I2CBusPtr b, I2CSlaveAddr addr
goto out;
}
- ivch_read (priv, VR01, &temp); xf86DrvMsg (priv->d.pI2CBus->scrnIndex, X_INFO,
- "ivch VR01 0x%x\n", temp);
- ivch_read (priv, VR40, &temp); xf86DrvMsg (priv->d.pI2CBus->scrnIndex, X_INFO,
- "ivch VR40 0x%x\n", temp);
return priv;
out:
@@ -250,7 +244,9 @@ ivch_mode_valid(I2CDevPtr d, DisplayMode
if (panel_fixed_mode)
{
- if (!xf86ModesEqual (mode, panel_fixed_mode))
+ if (mode->HDisplay > panel_fixed_mode->HDisplay)
+ return MODE_PANEL;
+ if (mode->VDisplay > panel_fixed_mode->VDisplay)
return MODE_PANEL;
}
@@ -280,8 +276,6 @@ ivch_dpms(I2CDevPtr d, int mode)
else
vr01 &= ~(VR01_LCD_ENABLE | VR01_DVO_ENABLE);
- vr01 &= ~VR01_PANEL_FIT_ENABLE;
-
ivch_write(priv, VR01, vr01);
/* Wait for the panel to make its state transition */
@@ -300,6 +294,27 @@ ivch_dpms(I2CDevPtr d, int mode)
static Bool
ivch_mode_fixup(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode)
{
+ struct ivch_priv *priv = d->DriverPrivate.ptr;
+ DisplayModePtr panel_fixed_mode = priv->panel_fixed_mode;
+
+ /* If we have timings from the BIOS for the panel, put them in
+ * to the adjusted mode. The CRTC will be set up for this mode,
+ * with the panel scaling set up to source from the H/VDisplay
+ * of the original mode.
+ */
+ if (panel_fixed_mode != NULL) {
+ adjusted_mode->HDisplay = panel_fixed_mode->HDisplay;
+ adjusted_mode->HSyncStart = panel_fixed_mode->HSyncStart;
+ adjusted_mode->HSyncEnd = panel_fixed_mode->HSyncEnd;
+ adjusted_mode->HTotal = panel_fixed_mode->HTotal;
+ adjusted_mode->VDisplay = panel_fixed_mode->VDisplay;
+ adjusted_mode->VSyncStart = panel_fixed_mode->VSyncStart;
+ adjusted_mode->VSyncEnd = panel_fixed_mode->VSyncEnd;
+ adjusted_mode->VTotal = panel_fixed_mode->VTotal;
+ adjusted_mode->Clock = panel_fixed_mode->Clock;
+ xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
+ }
+
return TRUE;
}
@@ -310,22 +325,32 @@ ivch_mode_set(I2CDevPtr d, DisplayModePt
CARD16 vr40 = 0;
CARD16 vr01;
- ivch_read (priv, VR01, &vr01);
- /* Disable panel fitting for now, until we can test. */
- if (adjusted_mode->HDisplay != priv->width || adjusted_mode->VDisplay != priv->height)
+ vr01 = 0;
+ vr40 = (VR40_STALL_ENABLE |
+ VR40_VERTICAL_INTERP_ENABLE |
+ VR40_HORIZONTAL_INTERP_ENABLE);
+
+ if (mode->HDisplay != adjusted_mode->HDisplay ||
+ mode->VDisplay != adjusted_mode->VDisplay)
{
+ CARD16 x_ratio, y_ratio;
+
vr01 |= VR01_PANEL_FIT_ENABLE;
- vr40 |= VR40_AUTO_RATIO_ENABLE;
+ vr40 |= VR40_CLOCK_GATING_ENABLE;
+ x_ratio = (((mode->HDisplay - 1) << 16) / (adjusted_mode->HDisplay - 1)) >> 2;
+ y_ratio = (((mode->VDisplay - 1) << 16) / (adjusted_mode->VDisplay - 1)) >> 2;
+ ivch_write (priv, VR42, x_ratio);
+ ivch_write (priv, VR41, y_ratio);
}
else
{
vr01 &= ~VR01_PANEL_FIT_ENABLE;
- vr40 &= ~VR40_AUTO_RATIO_ENABLE;
+ vr40 &= ~VR40_CLOCK_GATING_ENABLE;
}
+ vr40 &= ~VR40_AUTO_RATIO_ENABLE;
ivch_write(priv, VR01, vr01);
ivch_write(priv, VR40, vr40);
- ivch_dpms(d, DPMSModeOn);
ivch_dump_regs(d);
}
diff --git a/src/ivch/ivch_reg.h b/src/ivch/ivch_reg.h
index fe5507a..bcd8c56 100644
--- a/src/ivch/ivch_reg.h
+++ b/src/ivch/ivch_reg.h
@@ -46,6 +46,9 @@
* @{
*/
#define VR01 0x01
+/**
+ * Enable the panel fitter
+ */
# define VR01_PANEL_FIT_ENABLE (1 << 3)
/**
* Enables the LCD display.
@@ -185,26 +188,33 @@
*/
#define VR40 0x40
# define VR40_STALL_ENABLE (1 << 13)
-# define VR40_VERTICAL_INTERP_ENABLE (1 << 11)
+# define VR40_VERTICAL_INTERP_ENABLE (1 << 12)
+# define VR40_ENHANCED_PANEL_FITTING (1 << 11)
# define VR40_HORIZONTAL_INTERP_ENABLE (1 << 10)
# define VR40_AUTO_RATIO_ENABLE (1 << 9)
-# define VR40_PANEL_FIT_ENABLE (1 << 8)
+# define VR40_CLOCK_GATING_ENABLE (1 << 8)
/** @} */
/** @defgroup VR41 Panel Fitting Vertical Ratio
* @{
+ *
+ * (((image_height - 1) << 16) / ((panel_height - 1))) >> 2
*/
/** @} */
+#define VR41 0x41
/** @defgroup VR42 Panel Fitting Horizontal Ratio
* @{
+ * (((image_width - 1) << 16) / ((panel_width - 1))) >> 2
*/
/** @} */
+#define VR42 0x42
/** @defgroup VR43 Horizontal Image Size
* @{
*/
/** @} */
+#define VR43 0x43
/** @defgroup VR44 Panel Fitting Coefficient 0
* @{
More information about the xorg-commit
mailing list