diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c index a76e339f..e0755c05 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, DisplayModePtr mode) 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, DisplayModePtr mode, DisplayModePtr adjusted_mode) 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 fe5507a8..bcd8c56a 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 * @{