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