[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-intel: Changes to 'upstream-experimental'



 configure.ac                 |   18 +-
 man/intel.man                |   26 ++
 src/i810_reg.h               |   25 ++
 src/i830.h                   |    5 
 src/i830_bios.c              |    8 
 src/i830_crt.c               |    2 
 src/i830_display.c           |    3 
 src/i830_dri.c               |    2 
 src/i830_driver.c            |   33 +--
 src/i830_dvo.c               |    2 
 src/i830_exa.c               |   55 ++++--
 src/i830_lvds.c              |  374 ++++++++++++++++++++++++++++++++++++++-----
 src/i830_memory.c            |   22 --
 src/i830_render.c            |  118 ++++++++-----
 src/i830_sdvo.c              |    2 
 src/i830_tv.c                |    2 
 src/i830_video.c             |   24 +-
 src/i830_xaa.c               |    2 
 src/i915_hwmc.c              |    5 
 src/i915_render.c            |   10 +
 src/i965_render.c            |   42 ++--
 src/reg_dumper/idle.c        |   13 -
 src/xvmc/Makefile.am         |    2 
 src/xvmc/i915_xvmc.c         |   29 +--
 src/xvmc/intel_batchbuffer.c |   15 -
 src/xvmc/intel_xvmc.c        |    4 
 src/xvmc/intel_xvmc.h        |    1 
 src/xvmc/xf86dri.c           |   73 ++------
 src/xvmc/xf86dri.h           |   31 ++-
 29 files changed, 664 insertions(+), 284 deletions(-)

New commits:
commit 21783ec9dfad9aae0837fd2d8eb313a77f031046
Author: Zhenyu Wang <zhenyu.z.wang@intel.com>
Date:   Mon Mar 31 10:03:24 2008 +0800

    Bump version 2.2.99.902
    
    2.3-rc2

diff --git a/configure.ac b/configure.ac
index 871cd26..4439bca 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-intel],
-        2.2.99.901,
+        2.2.99.902,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-intel)
 

commit ead2e3ff2b3f3c961d4d7a5b4c64ccd2f754d275
Author: Zhenyu Wang <zhenyu.z.wang@intel.com>
Date:   Mon Mar 31 10:02:52 2008 +0800

    Use xfree() for bios memory

diff --git a/src/i830_bios.c b/src/i830_bios.c
index 0a28fb4..02837d2 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -270,7 +270,7 @@ i830_bios_get_aim_data_block (ScrnInfoPtr pScrn, int aim, int data_block)
     aim_off = vbt->aim_offset[aim];
     if (!aim_off)
     {
-	free (bios);
+	xfree (bios);
 	return NULL;
     }
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "aim_off %d\n", aim_off);
@@ -284,15 +284,15 @@ i830_bios_get_aim_data_block (ScrnInfoPtr pScrn, int aim, int data_block)
 	    unsigned char   *aim = malloc (aimdb_block->aimdb_size + sizeof (struct aimdb_block));
 	    if (!aim)
 	    {
-		free (bios);
+		xfree (bios);
 		return NULL;
 	    }
 	    memcpy (aim, aimdb_block, aimdb_block->aimdb_size + sizeof (struct aimdb_block));
-	    free (bios);
+	    xfree (bios);
 	    return aim;
 	}
 	bdb_off += aimdb_block->aimdb_size + sizeof (struct aimdb_block);
     }
-    free (bios);
+    xfree (bios);
     return NULL;
 }

commit 9835c2e987f4544206591f2f9c43e5a08e2e51bf
Author: Keith Packard <keithp@keithp.com>
Date:   Sat Mar 29 14:27:35 2008 -0700

    Disable cursors while switching modes
    (cherry picked from commit 7dcb6e627449c80cea9812462ce6a3e125bd1240)

diff --git a/src/i830_display.c b/src/i830_display.c
index 5e52aac..6a2d1d7 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -901,9 +901,12 @@ i830_crtc_unlock (xf86CrtcPtr crtc)
 static void
 i830_crtc_prepare (xf86CrtcPtr crtc)
 {
+    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
     /* Temporarily turn off FB compression during modeset */
     if (i830_use_fb_compression(crtc))
         i830_disable_fb_compression(crtc);
+    if (intel_crtc->enabled)
+	crtc->funcs->hide_cursor (crtc);
     crtc->funcs->dpms (crtc, DPMSModeOff);
 }
 

commit 46b771b2530f80218bc1ac8df10685ac13350c0f
Author: Eric Anholt <eric@anholt.net>
Date:   Fri Mar 28 15:15:26 2008 -0700

    Add a "total" field to intel_idle output (set when any unit is busy).
    (cherry picked from commit d50264fc7c4e0f80d9cc68dfdf322f68520a0f1e)

diff --git a/src/reg_dumper/idle.c b/src/reg_dumper/idle.c
index 0077bf4..bc9dbb7 100644
--- a/src/reg_dumper/idle.c
+++ b/src/reg_dumper/idle.c
@@ -54,22 +54,24 @@ struct idle_flags i965_idle_flags[] = {
     {I965_MAP_FILTER_DONE, "map filter"},
     {I965_MAP_L2_IDLE, "map L2"},
     {I965_CP_DONE, "CP"},
+    {0, "total"},
     {0, "other"},
 };
 
-/* Fills in the "other" field's idle flags */
+/* Fills in the "other" and "total" fields' idle flags */
 static void
 setup_other_flags(struct idle_flags *idle_flags, int idle_flag_count)
 {
-    uint32_t other_idle_flags;
+    uint32_t other_idle_flags, total_idle_flags = 0;
     int i;
 
     other_idle_flags = ~(I965_RING_0_ENABLE);
-    for (i = 0; i < idle_flag_count - 1; i++) {
+    for (i = 0; i < idle_flag_count - 2; i++) {
 	other_idle_flags &= ~idle_flags[i].instdone_flag;
+	total_idle_flags |= idle_flags[i].instdone_flag;
     }
+    idle_flags[i - 1].instdone_flag = total_idle_flags;
     idle_flags[i].instdone_flag = other_idle_flags;
-
 }
 
 int main(int argc, char **argv)
@@ -138,7 +140,8 @@ int main(int argc, char **argv)
 	    uint32_t instdone = INREG(INST_DONE_I965);
 
 	    for (j = 0; j < idle_flag_count; j++) {
-		if ((instdone & idle_flags[j].instdone_flag) == 0)
+		if ((instdone & idle_flags[j].instdone_flag) !=
+		    idle_flags[j].instdone_flag)
 		    idle_flags[j].count++;
 	    }
 

commit ca694544247695864493ce67613f07bb19d272fd
Author: Jesse Barnes <jbarnes@hobbes.virtuousgeek.org>
Date:   Fri Mar 28 13:23:02 2008 -0700

    Use combo backlight control rather than pure legacy
    
    If the legacy bit is set, use both the BLC_PWM_CTL and LBB regs to control the
    backlight, rather than just LBB.  Looks like more platforms want that than what
    the current code does.  Note that kernel provided interfaces will always be
    used if available, so this shouldn't affect users with /sys/class/backlight
    interfaces at all.
    
    Fixes #14721.
    (cherry picked from commit 1450acd046d47e1739a3ffbd146c73ad2974a935)

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 28a51d9..33b4f26 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -133,11 +133,11 @@ i830_set_lvds_backlight_method(xf86OutputPtr output)
     } else if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) {
 	blc_pwm_ctl2 = INREG(BLC_PWM_CTL2);
 	if (blc_pwm_ctl2 & BLM_LEGACY_MODE2)
-	    method = BCM_LEGACY;
+	    method = BCM_COMBO;
     } else {
 	blc_pwm_ctl = INREG(BLC_PWM_CTL);
 	if (blc_pwm_ctl & BLM_LEGACY_MODE)
-	    method = BCM_LEGACY;
+	    method = BCM_COMBO;
     }
 
     pI830->backlight_control_method = method;

commit dafda8b4582c218782da59d5ac3c82a70a91762f
Author: Matthias Hopf <mhopf@suse.de>
Date:   Wed Jan 9 16:08:57 2008 +0100

    Fix obviously wrong verification of DRI_SUPPORTS_CLIP_NOTIFY.
    (cherry picked from commit 3414313ac9d0faa95797ee18cc33afa231ec7581)

diff --git a/src/i830_dri.c b/src/i830_dri.c
index 3493eb9..4361ad0 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -135,7 +135,7 @@ static void I830DRITransitionSingleToMulti3d(ScreenPtr pScreen);
 #define DRI_DRIVER_FRAMEBUFFER_MAP 0
 #endif
 
-#ifdef DRI_SUPPORTS_CLIP_NOTIFY
+#if DRI_SUPPORTS_CLIP_NOTIFY
 static void I830DRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num);
 #endif
 

commit 6e8c89452ff9a9fe9a99734706e68b89ad8768fe
Author: Matthias Hopf <mhopf@suse.de>
Date:   Wed Jan 9 14:40:49 2008 +0100

    Fix obviously stray '(' in non-I830_USE_EXA case.
    (cherry picked from commit c40f195f2dc3467259b4588e087aac9741003ebf)

diff --git a/src/i830_xaa.c b/src/i830_xaa.c
index 0df7f98..c9c26b0 100644
--- a/src/i830_xaa.c
+++ b/src/i830_xaa.c
@@ -326,7 +326,7 @@ I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
      */
     pI830->BR[13] |= (I830PatternROP[rop] << 16);
 #else
-    pI830->BR[13] |= ((XAAGetPatternROP(rop) << 16);
+    pI830->BR[13] |= (XAAGetPatternROP(rop) << 16);
 #endif
 
     pI830->BR[16] = color;

commit 5ddebfd1e603ca515b0e74fd78f3c8b1f395bafe
Author: Zhenyu Wang <zhenyu.z.wang@intel.com>
Date:   Fri Mar 28 11:41:24 2008 +0800

    Disable DRI earlier if fb width > 2048
    (cherry picked from commit 7bba2c13310ed5ac22a355a3cc0ec8b7afaa79cf)

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 60ca63a..5866d67 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2681,6 +2681,12 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
       pScrn->videoRam &= ~3;
    }
 
+   if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) {
+      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		 "Cannot support DRI with frame buffer width > 2048.\n");
+      pI830->directRenderingDisabled = TRUE;
+   }
+
 #ifdef XF86DRI
    /* If DRI hasn't been explicitly disabled, try to initialize it.
     * It will be used by the memory allocator.
@@ -2758,12 +2764,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     pI830->XvEnabled = !pI830->XvDisabled;
 #endif
 
-   if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) {
-      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		 "Cannot support DRI with frame buffer width > 2048.\n");
-      pI830->tiling = FALSE;
-      pI830->directRenderingEnabled = FALSE;
-   }
 
    /* Need MMIO mapped to do GTT lookups during memory allocation. */
    I830MapMMIO(pScrn);

commit 6477799cb1c98f8b0105be37a96194f27de388ae
Author: Zhenyu Wang <zhenyu.z.wang@intel.com>
Date:   Fri Mar 28 11:29:40 2008 +0800

    Disable overlay on new mobile chipset
    
    It's gone, really.
    (cherry picked from commit b1f358ba97473b792ec2b7ed5170152faebe7262)

diff --git a/src/i830_driver.c b/src/i830_driver.c
index e6fff24..60ca63a 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2823,7 +2823,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 		    "needs 2D acceleration.\n");
 	 pI830->XvEnabled = FALSE;
       }
-      if (!IS_I9XX(pI830) && pI830->overlay_regs == NULL) {
+      if (!IS_IGD_GM(pI830) && pI830->overlay_regs == NULL) {
 	  xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		     "Disabling Xv because the overlay register buffer "
 		      "allocation failed.\n");
diff --git a/src/i830_memory.c b/src/i830_memory.c
index a38ee78..6835a6f 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -445,7 +445,7 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
 	/* Overlay and cursors, if physical, need to be allocated outside
 	 * of the kernel memory manager.
 	 */
-	if (!OVERLAY_NOPHYSICAL(pI830) && !IS_I965G(pI830)) {
+	if (!OVERLAY_NOPHYSICAL(pI830) && !IS_IGD_GM(pI830)) {
 	    mmsize -= ROUND_TO(OVERLAY_SIZE, GTT_PAGE_SIZE);
 	}
 	if (pI830->CursorNeedsPhysical) {
@@ -1025,6 +1025,9 @@ i830_allocate_overlay(ScrnInfoPtr pScrn)
     if (!pI830->XvEnabled)
 	return TRUE;
 
+    if (IS_IGD_GM(pI830))
+	return TRUE;
+
     if (!OVERLAY_NOPHYSICAL(pI830))
 	flags |= NEED_PHYSICAL_ADDR;
 
diff --git a/src/i830_video.c b/src/i830_video.c
index 04ce0d6..68bcc88 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -617,7 +617,8 @@ I830InitVideo(ScreenPtr pScreen)
     }
 
     /* Set up overlay video if we can do it at this depth. */
-    if (pScrn->bitsPerPixel != 8 && pI830->overlay_regs != NULL)
+    if (!IS_IGD_GM(pI830) && pScrn->bitsPerPixel != 8 &&
+	    pI830->overlay_regs != NULL)
     {
 	overlayAdaptor = I830SetupImageVideoOverlay(pScreen);
 	if (overlayAdaptor != NULL) {
@@ -2634,6 +2635,7 @@ I830VideoBlockHandler(int i, pointer blockData, pointer pTimeout,
     I830Ptr pI830 = I830PTR(pScrn);
     I830PortPrivPtr pPriv;
 
+    /* no overlay */
     if (pI830->adaptor == NULL)
         return;
 
@@ -2913,6 +2915,7 @@ i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on)
     I830Ptr pI830 = I830PTR(pScrn);
     I830PortPrivPtr pPriv;
 
+    /* no overlay */
     if (pI830->adaptor == NULL)
 	return;
 

commit 687b0567533ac085f545430a3762dd980049116e
Author: Jesse Barnes <jbarnes@hobbes.virtuousgeek.org>
Date:   Wed Mar 19 11:59:15 2008 -0700

    Fixup backlight control and panel fitting property names
    
    They should be listed as lower case, since that's what you'd pass to xrandr.
    (cherry picked from commit 52d6ced652059989e6d9780a149488ccd16e3a22)

diff --git a/man/intel.man b/man/intel.man
index b1bb777..69af25e 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -214,19 +214,19 @@ By adjusting the BACKLIGHT property, the brightness on the LVDS output can be ad
 .TP 2
 The driver will attempt to automatically detect the backlight control method for your platform.  If this fails however, you can select another method which may allow you to control your backlight.  Available methods include:
 .PP
-.B NATIVE
+.B native
 .TP 4
 Intel chipsets include backlight control registers, which on some platforms may be wired to control the backlight directly.  This method uses those registers.
 .PP
-.B LEGACY
+.B legacy
 .TP 4
 The legacy backlight control registers exist in PCI configuration space, and have fewer available backlight levels than the native registers.  However, some platforms are wired this way and so need to use this method.
 .PP
-.B COMBO
+.B combo
 .TP 4
 This method attempts to use the native registers where possible, resorting to the legacy, configuration space registers only to enable the backlight if needed.  On platforms that have both wired this can be a good choice as it allows the fine grained backlight control of the native interface.
 .PP
-.B KERNEL
+.B kernel
 .TP 4
 On some system, the kernel may provide a backlight control driver.  In that case, using the kernel interfaces is preferable, as the same driver may respond to hotkey events or external APIs.
 
@@ -236,15 +236,15 @@ On some system, the kernel may provide a backlight control driver.  In that case
 .TP 2
 By default, the driver will attempt to upscale resolutions smaller than the LCD's native size while preserving the aspect ratio.  Other modes are available however:
 .PP
-.B CENTER
+.B center
 .TP 4
 Simply center the image on-screen, without scaling.
 .PP
-.B FULL_ASPECT
+.B full_aspect
 .TP 4
 The default mode.  Try to upscale the image to the screen size, while preserving aspect ratio.  May result in letterboxing or pillar-boxing with some resolutions.
 .PP
-.B FULL
+.B full
 .TP 4
 Upscale the image to the native screen size without regard to aspect ratio.  In this mode, the full screen image may appear distorted in some resolutions.
 

commit 5a06388bf83c97f49565ad482161645f996492c7
Author: Jesse Barnes <jbarnes@nietzche.virtuousgeek.org>
Date:   Thu Mar 13 18:12:00 2008 -0700

    Initial panel fitting changes
    
    Basic support for panel fitting.
    (cherry picked from commit 05cf07071e25f84dec3476a9bed7235ed50cd249)

diff --git a/man/intel.man b/man/intel.man
index c26264f..b1bb777 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -230,6 +230,24 @@ This method attempts to use the native registers where possible, resorting to th
 .TP 4
 On some system, the kernel may provide a backlight control driver.  In that case, using the kernel interfaces is preferable, as the same driver may respond to hotkey events or external APIs.
 
+.PP
+.B PANEL_FITTING
+- control LCD panel fitting
+.TP 2
+By default, the driver will attempt to upscale resolutions smaller than the LCD's native size while preserving the aspect ratio.  Other modes are available however:
+.PP
+.B CENTER
+.TP 4
+Simply center the image on-screen, without scaling.
+.PP
+.B FULL_ASPECT
+.TP 4
+The default mode.  Try to upscale the image to the screen size, while preserving aspect ratio.  May result in letterboxing or pillar-boxing with some resolutions.
+.PP
+.B FULL
+.TP 4
+Upscale the image to the native screen size without regard to aspect ratio.  In this mode, the full screen image may appear distorted in some resolutions.
+
 .SS "TV"
 Integrated TV output.  Available properties include:
 
diff --git a/src/i810_reg.h b/src/i810_reg.h
index d5b6805..d799e77 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -871,8 +871,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #define PFIT_CONTROL	0x61230
 # define PFIT_ENABLE				(1 << 31)
-# define PFIT_PIPE_MASK				(3 << 29)
-# define PFIT_PIPE_SHIFT			29
+/* Pre-965 */
 # define VERT_INTERP_DISABLE			(0 << 10)
 # define VERT_INTERP_BILINEAR			(1 << 10)
 # define VERT_INTERP_MASK			(3 << 10)
@@ -882,12 +881,30 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 # define HORIZ_INTERP_MASK			(3 << 6)
 # define HORIZ_AUTO_SCALE			(1 << 5)
 # define PANEL_8TO6_DITHER_ENABLE		(1 << 3)
+/* 965+ */
+# define PFIT_PIPE_MASK				(3 << 29)
+# define PFIT_PIPE_SHIFT			29
+# define PFIT_SCALING_MODE_MASK			(7 << 26)
+#  define PFIT_SCALING_AUTO			(0 << 26)
+#  define PFIT_SCALING_PROGRAMMED		(1 << 26)
+#  define PFIT_SCALING_PILLAR			(2 << 26)
+#  define PFIT_SCALING_LETTER			(3 << 26)
+# define PFIT_FILTER_SELECT_MASK		(3 << 24)
+#  define PFIT_FILTER_FUZZY			(0 << 24)
+#  define PFIT_FILTER_CRISP			(1 << 24)
+#  define PFIT_FILTER_MEDIAN			(2 << 24)
 
 #define PFIT_PGM_RATIOS	0x61234
+/* Pre-965 */
+# define PFIT_VERT_SCALE_SHIFT			20
 # define PFIT_VERT_SCALE_MASK			0xfff00000
+# define PFIT_HORIZ_SCALE_SHIFT			4
 # define PFIT_HORIZ_SCALE_MASK			0x0000fff0
-
-#define PFIT_AUTO_RATIOS	0x61238
+/* 965+ */
+# define PFIT_VERT_SCALE_SHIFT_965		16
+# define PFIT_VERT_SCALE_MASK_965		0x1fff0000
+# define PFIT_HORIZ_SCALE_SHIFT_965		0
+# define PFIT_HORIZ_SCALE_MASK_965		0x00001fff
 
 #define DPLL_A		0x06014
 #define DPLL_B		0x06018
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 772a8b8..28a51d9 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -44,12 +44,25 @@
 #include "i830_display.h"
 #include "X11/Xatom.h"
 
+/*
+ * Three panel fitting modes:
+ * CENTER - center image on screen, don't scale
+ * FULL_ASPECT - scale image to fit screen, but preserve aspect ratio
+ * FULL - scale image to fit screen without regard to aspect ratio
+ */
+enum pfit_mode {
+    CENTER = 0,
+    FULL_ASPECT,
+    FULL,
+};
+
 struct i830_lvds_priv {
     /* The BIOS's fixed timings for the LVDS */
     DisplayModePtr panel_fixed_mode;
     
     /* The panel needs dithering enabled */
     Bool	    panel_wants_dither;
+    Bool	    need_border;
 
     /* restore backlight to this value */
     int		    backlight_duty_cycle;
@@ -57,6 +70,9 @@ struct i830_lvds_priv {
     void (*set_backlight)(xf86OutputPtr output, int level);
     int (*get_backlight)(xf86OutputPtr output);
     int backlight_max;
+    enum pfit_mode fitting_mode;
+    uint32_t pfit_control;
+    uint32_t pfit_pgm_ratios;
 };
 
 #define BACKLIGHT_CLASS "/sys/class/backlight"
@@ -481,7 +497,13 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
     ScrnInfoPtr		    pScrn = output->scrn;
     xf86CrtcConfigPtr	    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     I830CrtcPrivatePtr	    intel_crtc = output->crtc->driver_private;
+    I830Ptr		    pI830 = I830PTR(pScrn);
+    uint32_t		    pfit_control = 0, pfit_pgm_ratios = 0;
+    float		    panel_ratio, desired_ratio, vert_scale, horiz_scale;
+    float		    horiz_ratio, vert_ratio;
+    int left_border = 0, right_border = 0, top_border = 0, bottom_border = 0;
     int i;
+    Bool border = 0;
 
     for (i = 0; i < xf86_config->num_output; i++) {
 	xf86OutputPtr other_output = xf86_config->output[i];
@@ -500,24 +522,207 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 	return FALSE;
     }
 
+    /* If we don't have a panel mode there's not much we can do */
+    if (dev_priv->panel_fixed_mode == NULL)
+	return TRUE;
+
     /* 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 (dev_priv->panel_fixed_mode != NULL) {
-	adjusted_mode->HDisplay = dev_priv->panel_fixed_mode->HDisplay;
-	adjusted_mode->HSyncStart = dev_priv->panel_fixed_mode->HSyncStart;
-	adjusted_mode->HSyncEnd = dev_priv->panel_fixed_mode->HSyncEnd;
-	adjusted_mode->HTotal = dev_priv->panel_fixed_mode->HTotal;
-	adjusted_mode->VDisplay = dev_priv->panel_fixed_mode->VDisplay;
-	adjusted_mode->VSyncStart = dev_priv->panel_fixed_mode->VSyncStart;
-	adjusted_mode->VSyncEnd = dev_priv->panel_fixed_mode->VSyncEnd;
-	adjusted_mode->VTotal = dev_priv->panel_fixed_mode->VTotal;
-	adjusted_mode->Clock = dev_priv->panel_fixed_mode->Clock;
-	xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
+    adjusted_mode->HDisplay = dev_priv->panel_fixed_mode->HDisplay;
+    adjusted_mode->HSyncStart = dev_priv->panel_fixed_mode->HSyncStart;
+    adjusted_mode->HSyncEnd = dev_priv->panel_fixed_mode->HSyncEnd;
+    adjusted_mode->HTotal = dev_priv->panel_fixed_mode->HTotal;
+    adjusted_mode->VDisplay = dev_priv->panel_fixed_mode->VDisplay;
+    adjusted_mode->VSyncStart = dev_priv->panel_fixed_mode->VSyncStart;
+    adjusted_mode->VSyncEnd = dev_priv->panel_fixed_mode->VSyncEnd;
+    adjusted_mode->VTotal = dev_priv->panel_fixed_mode->VTotal;
+    adjusted_mode->Clock = dev_priv->panel_fixed_mode->Clock;
+    xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
+
+    /* Native modes don't need fitting */
+    if (adjusted_mode->HDisplay == mode->HDisplay &&
+	adjusted_mode->VDisplay == mode->VDisplay) {
+	pfit_control = 0;
+	pfit_pgm_ratios = 0;
+	border = 0;
+	goto out;
+    }
+
+    /* Basic panel fitting options */
+    if (!IS_I965G(pI830)) {
+	if (dev_priv->panel_wants_dither)
+	    pfit_control |= PANEL_8TO6_DITHER_ENABLE;
+    } else {
+	pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) |
+	    PFIT_FILTER_FUZZY;
     }
 
+    /*
+     * Deal with panel fitting options.  Figure out how to stretch the image
+     * based on its aspect ratio & the current panel fitting mode.
+     */
+    panel_ratio = (float)adjusted_mode->HDisplay /
+ 	(float)adjusted_mode->VDisplay;
+    desired_ratio = (float)mode->HDisplay /
+	(float)mode->VDisplay;
+
+    /*
+     * Enable automatic panel scaling for non-native modes so that they fill
+     * the screen.  Should be enabled before the pipe is enabled, according to
+     * register description and PRM.
+     */
+    /* Change the value here to see the borders for debugging */
+    OUTREG(BCLRPAT_A, 0);
+    OUTREG(BCLRPAT_B, 0);
+    switch (dev_priv->fitting_mode) {
+    case CENTER:
+	/*
+	 * For centered modes, we have to calculate border widths & heights and
+	 * modify the values programmed into the CRTC.  Also need to make sure
+	 * LVDS borders are enabled (see i830_display.c).
+	 */
+	left_border =
+	    (dev_priv->panel_fixed_mode->HDisplay - mode->HDisplay) / 2;
+	right_border = left_border;
+	if (mode->HDisplay & 1)
+	    right_border++;
+	top_border =
+	    (dev_priv->panel_fixed_mode->VDisplay - mode->VDisplay) / 2;
+	bottom_border = top_border;
+	if (mode->VDisplay & 1)
+	    bottom_border++;
+
+	/* Set active & border values */
+	adjusted_mode->CrtcHDisplay = mode->HDisplay;
+	adjusted_mode->CrtcHBlankStart = mode->HDisplay + right_border - 1;
+	adjusted_mode->CrtcHBlankEnd = adjusted_mode->CrtcHTotal -
+	    left_border - 1;
+	adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHBlankStart;
+	adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHBlankEnd;
+	adjusted_mode->CrtcVDisplay = mode->VDisplay;
+	adjusted_mode->CrtcVBlankStart = mode->VDisplay + bottom_border - 1;
+	adjusted_mode->CrtcVBlankEnd = adjusted_mode->CrtcVTotal -
+	    top_border - 1;
+	adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVBlankStart;
+	adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVBlankEnd;
+	border = 1;
+	break;
+    case FULL_ASPECT:
+	/* Scale but preserve aspect ratio */
+	pfit_control |= PFIT_ENABLE;
+	if (IS_I965G(pI830)) {
+	    /*
+	     * 965+ is easy, it does everything in hw
+	     */
+	    if (panel_ratio > desired_ratio)
+		pfit_control |= PFIT_SCALING_PILLAR;
+	    else if (panel_ratio < desired_ratio)
+		pfit_control |= PFIT_SCALING_LETTER;
+	    else
+		pfit_control |= PFIT_SCALING_AUTO;
+	} else {
+	    /*
+	     * For earlier chips we have to calculate the scaling ratio
+	     * by hand and program it into the PFIT_PGM_RATIOS reg.
+	     */
+	    uint32_t horiz_bits, vert_bits, bits = 12;
+
+	    horiz_ratio = ((float)mode->HDisplay) /
+		((float)adjusted_mode->HDisplay);
+	    vert_ratio = ((float)mode->VDisplay) /
+		((float)adjusted_mode->VDisplay);
+
+	    horiz_scale = ((float)adjusted_mode->HDisplay) /
+		((float)mode->HDisplay);
+	    vert_scale = ((float)adjusted_mode->VDisplay) /
+		((float)mode->VDisplay);
+
+	    /* Retain aspect ratio */
+	    if (panel_ratio > desired_ratio) { /* Pillar */
+		unsigned long scaled_width = (float)mode->HDisplay * vert_scale;
+
+		horiz_ratio = vert_ratio;
+		pfit_control |= VERT_AUTO_SCALE | VERT_INTERP_BILINEAR |
+		    HORIZ_INTERP_BILINEAR;
+
+		/* Pillar will have left/right borders */
+		left_border =  (dev_priv->panel_fixed_mode->HDisplay -
+				scaled_width) / 2;
+		right_border = left_border;
+		if (mode->HDisplay & 1) /* odd resolutions */
+		    right_border++;
+
+		adjusted_mode->CrtcHDisplay = scaled_width;
+		adjusted_mode->CrtcHBlankStart = scaled_width +
+		    right_border - 1;
+		adjusted_mode->CrtcHBlankEnd = adjusted_mode->CrtcHTotal -
+		    left_border - 1;
+		adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHBlankStart;
+		adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHBlankEnd;
+		border = 1;
+	    } else if (panel_ratio < desired_ratio) { /* Letter */
+		unsigned long scaled_height = (float)mode->VDisplay *
+		    horiz_scale;
+
+		vert_ratio = horiz_ratio;
+		pfit_control |= HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |
+		    HORIZ_INTERP_BILINEAR;
+
+		/* Letterbox will have top/bottom borders */
+		top_border = (dev_priv->panel_fixed_mode->VDisplay -
+			      mode->VDisplay) / 2;
+		bottom_border = top_border;
+		if (mode->VDisplay & 1)
+		    bottom_border++;
+
+		adjusted_mode->CrtcVDisplay = scaled_height;
+		adjusted_mode->CrtcVBlankStart = scaled_height +
+		    bottom_border - 1;
+		adjusted_mode->CrtcVBlankEnd = adjusted_mode->CrtcVTotal -
+		    top_border - 1;
+		adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVBlankStart;
+		adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVBlankEnd;
+		border = 1;
+	    } else { /* Aspects match, let hw scale both directions */
+		pfit_control |= VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
+		    VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR;
+	    }
+
+	    horiz_bits = 0.5 + (1 << bits) * horiz_ratio;
+	    vert_bits = 0.5 + (1 << bits) * vert_ratio;
+
+	    pfit_pgm_ratios = (((vert_bits << PFIT_VERT_SCALE_SHIFT) &
+				PFIT_VERT_SCALE_MASK) |
+			       ((horiz_bits << PFIT_HORIZ_SCALE_SHIFT) &
+				PFIT_HORIZ_SCALE_MASK));
+	}
+	break;
+    case FULL:
+	/*
+	 * Full scaling, even if it changes the aspect ratio.  Fortunately
+	 * this is all done for us in hw.
+	 */
+	pfit_control |= PFIT_ENABLE;
+	if (IS_I965G(pI830))
+	    pfit_control |= PFIT_SCALING_AUTO;
+	else
+	    pfit_control |= VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
+		VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR;
+	break;
+    default:
+	/* shouldn't happen */
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "error: bad fitting mode\n");
+	break;
+    }
+  
+out:
+    dev_priv->pfit_control = pfit_control;
+    dev_priv->pfit_pgm_ratios = pfit_pgm_ratios;
+    dev_priv->need_border = border;
+
     /* XXX: It would be nice to support lower refresh rates on the
      * panels to reduce power consumption, and perhaps match the
      * user's requested refresh rate.
@@ -527,42 +732,43 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 }
 
 static void
-i830_lvds_mode_set(xf86OutputPtr output, DisplayModePtr mode,
-		   DisplayModePtr adjusted_mode)
+i830_lvds_prepare(xf86OutputPtr output)
 {
     I830OutputPrivatePtr    intel_output = output->driver_private;
     struct i830_lvds_priv   *dev_priv = intel_output->dev_priv;
     ScrnInfoPtr		    pScrn = output->scrn;
     I830Ptr		    pI830 = I830PTR(pScrn);
-    I830CrtcPrivatePtr	    intel_crtc = output->crtc->driver_private;
-    uint32_t		    pfit_control;
+    uint32_t		    lvds;
 
-    /* The LVDS pin pair will already have been turned on in
-     * i830_crtc_mode_set since it has a large impact on the DPLL settings.
-     */
+    lvds = INREG(LVDS);
 
-    /* Enable automatic panel scaling for non-native modes so that they fill
-     * the screen.  Should be enabled before the pipe is enabled, according to
-     * register description and PRM.
+    i830_lvds_dpms(output, DPMSModeOff);
+    /*
+     * ->prepare will be called after the CRTC is off but before
+     * we set the mode, so program the PFIT regs here.
      */
-    if (mode->HDisplay != adjusted_mode->HDisplay ||
-	mode->VDisplay != adjusted_mode->VDisplay)
-    {
-	pfit_control = PFIT_ENABLE |
-	    VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
-	    VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR;
-    } else {
-	pfit_control = 0;
-    }
+    if (dev_priv->need_border)
+	OUTREG(LVDS, lvds | LVDS_BORDER_ENABLE);
+    else
+	OUTREG(LVDS, lvds & (~LVDS_BORDER_ENABLE));
+}
 
-    if (!IS_I965G(pI830)) {
-	if (dev_priv->panel_wants_dither)
-	    pfit_control |= PANEL_8TO6_DITHER_ENABLE;
-    } else {
-	pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT;
-    }
+static void
+i830_lvds_mode_set(xf86OutputPtr output, DisplayModePtr mode,
+		   DisplayModePtr adjusted_mode)
+{
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_lvds_priv   *dev_priv = intel_output->dev_priv;
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
 
-    OUTREG(PFIT_CONTROL, pfit_control);
+    /*
+     * PFIT must be enabled/disabled while LVDS is on but pipes are still off
+     */
+    OUTREG(PFIT_PGM_RATIOS, dev_priv->pfit_pgm_ratios);
+    OUTREG(PFIT_CONTROL, dev_priv->pfit_control);
+    /* It's harmless to turn on the LVDS if it's already on */
+    i830_lvds_dpms(output, DPMSModeOn);
 }
 
 /**
@@ -653,6 +859,17 @@ static char *backlight_control_names[] = {
 static Atom backlight_control_atom;
 static Atom backlight_control_name_atoms[NUM_BACKLIGHT_CONTROL_METHODS];
 
+#define PANEL_FITTING_NAME "PANEL_FITTING"
+#define NUM_PANEL_FITTING_TYPES 3
+static char *panel_fitting_names[] = {
+    "center",
+    "full_aspect",
+    "full",
+};
+static Atom panel_fitting_atom;
+static Atom panel_fitting_name_atoms[NUM_PANEL_FITTING_TYPES];
+
+
 static int
 i830_backlight_control_lookup(char *name)
 {
@@ -709,6 +926,18 @@ i830_lvds_set_backlight_control(xf86OutputPtr output)
 
     return Success;
 }
+
+static int
+i830_panel_fitting_lookup(char *name)
+{
+    int i;
+
+    for (i = 0; i < NUM_PANEL_FITTING_TYPES; i++)
+	if (!strcmp(name, panel_fitting_names[i]))
+	    return i;
+
+    return -1;
+}
 #endif /* RANDR_12_INTERFACE */
 
 static void
@@ -775,6 +1004,33 @@ i830_lvds_create_resources(xf86OutputPtr output)
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "failed to set backlight control, %d\n", err);
     }
+
+    /*
+     * Panel fitting control
+     */
+    panel_fitting_atom = MakeAtom(PANEL_FITTING_NAME,
+				  sizeof(PANEL_FITTING_NAME) - 1, TRUE);
+    for (i = 0; i < NUM_PANEL_FITTING_TYPES; i++) {
+	panel_fitting_name_atoms[i] = MakeAtom(panel_fitting_names[i],
+					       strlen(panel_fitting_names[i]),
+					       TRUE);
+    }
+    err = RRConfigureOutputProperty(output->randr_output,
+				    panel_fitting_atom, TRUE, FALSE, FALSE,
+				    NUM_PANEL_FITTING_TYPES,
+				    (INT32 *)panel_fitting_name_atoms);
+    if (err != 0) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "RRConfigureOutputProperty error, %d\n", err);
+    }
+    err = RRChangeOutputProperty(output->randr_output, panel_fitting_atom,
+				 XA_ATOM, 32, PropModeReplace, 1,
+				 &panel_fitting_name_atoms[dev_priv->fitting_mode],
+				 FALSE, TRUE);
+    if (err != 0) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "failed to set panel fitting mode, %d\n", err);
+    }   
 #endif /* RANDR_12_INTERFACE */
 }
 
@@ -846,6 +1102,36 @@ i830_lvds_set_property(xf86OutputPtr output, Atom property,
 		       "RRChangeOutputProperty error, %d\n", ret);
 	}
 	return TRUE;
+    } else if (property == panel_fitting_atom) {
+	Atom			atom;
+	char			*name;
+	int			ret;
+
+	if (value->type != XA_ATOM || value->format != 32 || value->size != 1)
+	    return FALSE;
+
+	memcpy(&atom, value->data, 4);
+	name = NameForAtom(atom);
+	
+	ret = i830_panel_fitting_lookup(name);
+	if (ret < 0)
+	    return FALSE;
+
+	dev_priv->fitting_mode = ret;
+
+	if (output->crtc) {
+	    xf86CrtcPtr crtc = output->crtc;
+	    if (crtc->enabled) {
+		if (!xf86CrtcSetMode(crtc, &crtc->desiredMode,
+				     crtc->desiredRotation,
+				     crtc->desiredX, crtc->desiredY)) {
+		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			       "Failed to set mode after panel fitting change!\n");
+		    return FALSE;
+		}
+	    }
+	}
+	return TRUE;
     }
 
     return TRUE;
@@ -898,7 +1184,7 @@ static const xf86OutputFuncsRec i830_lvds_output_funcs = {
     .restore = i830_lvds_restore,
     .mode_valid = i830_lvds_mode_valid,
     .mode_fixup = i830_lvds_mode_fixup,
-    .prepare = i830_output_prepare,
+    .prepare = i830_lvds_prepare,
     .mode_set = i830_lvds_mode_set,
     .commit = i830_output_commit,
     .detect = i830_lvds_detect,
@@ -1090,6 +1376,12 @@ i830_lvds_init(ScrnInfoPtr pScrn)
 
     dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output);
 
+    /*
+     * Default to filling the whole screen if the mode is less than the
+     * native size, without breaking aspect ratio.
+     */
+    dev_priv->fitting_mode = FULL_ASPECT;
+
     return;
 
 disable_exit:

commit 249d16a81b405d76706f2de203a775766b708303
Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>
Date:   Wed Mar 26 10:11:36 2008 +0800

    More compile warning fixes.
    
    o Check for RANDR_GET_CRTC_INTERFACE before defining functions that
      are used only if it is defined.
    o Declare a variable before code, and rename it from ret to xvmc_status
      to better describe it.
    o if 0 some static functions not used.
    o Don't declare some unused variables.
    o Declare as static some functions that are used only in the file defining it.
    o Add a default/fallback return True to the Bool function
      src/xvmc/intel_batchbuffer.c:intelInitBatchBuffer().
    o Ansify src/xvmc/xf86dri.c.
    o Add missing prototype to src/xvmc/xf86dri.h and follow pattern of other
      headers by adding "extern" before function prototype.
    (cherry picked from commit c13efdd3d6d3846078766814b57306a7519bce18)

diff --git a/src/i830_crt.c b/src/i830_crt.c
index d1ed3a8..2a99f9c 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -391,6 +391,7 @@ i830_crt_destroy (xf86OutputPtr output)


Reply to: