xf86-video-intel: Branch 'refs/remotes/origin/intel-batchbuffer' - 36 commits - configure.ac man/intel.man src/ch7017/ch7017.c src/ch7017/ch7017_reg.h src/ch7xxx/ch7xxx.c src/common.h src/i810_reg.h src/i830_accel.c src/i830_debug.c src/i830_display.c src/i830_dri.c src/i830_driver.c src/i830_exa.c src/i830.h src/i830_lvds.c src/i830_memory.c src/i830_reg.h src/i830_tv.c src/i830_video.c src/intel_batchbuffer.c src/scripts/clock.5c src/scripts/clock-graph.5c

Jesse Barnes jbarnes at kemper.freedesktop.org
Mon Dec 10 13:03:24 PST 2007


 configure.ac               |    2 
 man/intel.man              |   10 
 src/ch7017/ch7017.c        |    8 
 src/ch7017/ch7017_reg.h    |    1 
 src/ch7xxx/ch7xxx.c        |    4 
 src/common.h               |    2 
 src/i810_reg.h             |   33 ++
 src/i830.h                 |   62 +++++
 src/i830_accel.c           |   19 -
 src/i830_debug.c           |   11 
 src/i830_display.c         |   21 +
 src/i830_dri.c             |    5 
 src/i830_driver.c          |  128 ++++++-----
 src/i830_exa.c             |    1 
 src/i830_lvds.c            |  503 +++++++++++++++++++++++++++++++++++++++------
 src/i830_memory.c          |   17 -
 src/i830_reg.h             |   31 --
 src/i830_tv.c              |    3 
 src/i830_video.c           |   13 -
 src/intel_batchbuffer.c    |    2 
 src/scripts/clock-graph.5c |    6 
 src/scripts/clock.5c       |    4 
 22 files changed, 672 insertions(+), 214 deletions(-)

New commits:
commit 8b598e979ebd1e5cba82e4485ab5eae25c3f1e36
Author: Kristian Høgsberg <krh at temari.boston.redhat.com>
Date:   Mon Dec 3 13:36:46 2007 -0500

    Remove spurious use of MI_SET_CONTEXT.
    
    The driver uses MI_SET_CONTEXT to save the current state before
    emitting the invariant 3d state.  Nothing ever restores this state though,
    so this patch removes that.  This was also the only remaining use of
    the ring buffer in TTM mode, so we're one step closer to a ring-buffer
    free DDX driver.

diff --git a/src/common.h b/src/common.h
index f558e8f..46bfa8e 100644
--- a/src/common.h
+++ b/src/common.h
@@ -232,7 +232,7 @@ union intfloat {
 
 #define BEGIN_LP_RING(n)						\
 	RING_LOCALS							\
-	DO_LP_RING(n)							\
+	DO_LP_RING(n)
 
 /* Memory mapped register access macros */
 #define INREG8(addr)        *(volatile CARD8  *)(RecPtr->MMIOBase + (addr))
diff --git a/src/i830.h b/src/i830.h
index 9387651..cbc1b93 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -404,8 +404,6 @@ typedef struct _I830Rec {
    void (*PointerMoved)(int, int, int);
    CreateScreenResourcesProcPtr    CreateScreenResources;
 
-   i830_memory *logical_context;
-
 #ifdef XF86DRI
    i830_memory *back_buffer;
    i830_memory *third_buffer;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 6393a61..27df05b 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2254,17 +2254,6 @@ IntelEmitInvarientState(ScrnInfoPtr pScrn)
    if (*pI830->last_3d != LAST_3D_OTHER)
       return;
 
-   ctx_addr = pI830->logical_context->offset;
-   assert((pI830->logical_context->offset & 2047) == 0);
-   {
-      BEGIN_LP_RING(2);
-      OUT_RING(MI_SET_CONTEXT);
-      OUT_RING(pI830->logical_context->offset |
-	       CTXT_NO_RESTORE |
-	       CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE);
-      ADVANCE_LP_RING();
-   }
-
    if (!IS_I965G(pI830))
    {
       if (IS_I9XX(pI830))
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 85b6528..6287bab 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -347,7 +347,6 @@ i830_reset_allocations(ScrnInfoPtr pScrn)
     pI830->exa_offscreen = NULL;
     pI830->exa_965_state = NULL;
     pI830->overlay_regs = NULL;
-    pI830->logical_context = NULL;
 #ifdef XF86DRI
     pI830->back_buffer = NULL;
     pI830->third_buffer = NULL;
@@ -1356,15 +1355,6 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn)
 	pI830->SWCursor = TRUE;
     }
 
-    /* Space for the X Server's 3D context.  32k is fine for right now. */
-    pI830->logical_context = i830_allocate_memory(pScrn, "logical 3D context",
-						  KB(32), GTT_PAGE_SIZE, 0);
-    if (pI830->logical_context == NULL) {
-	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		   "Failed to allocate logical context space.\n");
-	return FALSE;
-    }
-
     /* even in XAA, 965G needs state mem buffer for rendering */
     if (IS_I965G(pI830) && !pI830->noAccel && pI830->exa_965_state == NULL) {
 	pI830->exa_965_state =
commit 773003861226038f2fcfd36b8a97c447e494843a
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Nov 19 11:19:32 2007 +1000

    i830: don't turn irq off before stopping the ring
    
    As otherwise we can't sync on the outstanding fences. This fixes a fence
    lockup on X server exit

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5b75e33..6393a61 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3007,7 +3007,6 @@ I830LeaveVT(int scrnIndex, int flags)
       DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
 
       I830DRISetVBlankInterrupt (pScrn, FALSE);
-      drmCtlUninstHandler(pI830->drmSubFD);
    }
 #endif
 
@@ -3017,6 +3016,12 @@ I830LeaveVT(int scrnIndex, int flags)
 
    i830_stop_ring(pScrn, TRUE);
 
+#ifdef XF86DRI
+   /* don't disable interrupt before stopping the ring for fencing */
+   if (pI830->directRenderingOpen) {
+      drmCtlUninstHandler(pI830->drmSubFD);
+   }
+#endif
    if (pI830->debug_modes) {
       i830CompareRegsToSnapshot(pScrn, "After LeaveVT");
       i830DumpRegs (pScrn);
commit f47ae44e4dd61af219dfc3cf5a6bc5640e1df083
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Nov 19 11:18:58 2007 +1000

    batchbuffer: fix refresh ring function name

diff --git a/src/intel_batchbuffer.c b/src/intel_batchbuffer.c
index f29f069..be1b9de 100644
--- a/src/intel_batchbuffer.c
+++ b/src/intel_batchbuffer.c
@@ -192,7 +192,7 @@ do_flush_locked(struct intelddx_batchbuffer *batch,
       
    dri_post_submit(batch->buf, &batch->last_fence);
 
-   I830RefreshRing(batch->pScrn);
+   i830_refresh_ring(batch->pScrn);
 }
 
 void
commit e453093c7bfd41770c763e84aa79a66b3a14a750
Merge: 0013905... 7f9ceff...
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Nov 19 11:09:07 2007 +1000

    Merge branch 'master' into intel-batchbuffer

diff --cc src/i830_exa.c
index 6e1c5bd,32c55dd..45a537a
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@@ -35,11 -35,8 +35,10 @@@ SOFTWARE OR THE USE OR OTHER DEALINGS I
  #include "xaarop.h"
  #include "i830.h"
  #include "i810_reg.h"
- #include "i830_reg.h"
  #include <string.h>
  
 +#include "intel_bufmgr_ttm.h"
 +
  #ifdef I830DEBUG
  #define DEBUG_I830FALLBACK 1
  #endif
commit 7f9cefffbf44a2d07b51cc13aaf2d54fcd8f2f22
Author: Alan Hourihane <alanh at tungstengraphics.com>
Date:   Fri Nov 16 15:56:08 2007 +0000

    vendor is CARD8

diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c
index 3c58165..da02ad2 100644
--- a/src/ch7xxx/ch7xxx.c
+++ b/src/ch7xxx/ch7xxx.c
@@ -50,7 +50,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
 static struct ch7xxx_id_struct {
-    int vid;
+    CARD8 vid;
     char *name;
 } ch7xxx_ids[] = { 
 	{ CH7011_VID, "CH7011" },
@@ -77,7 +77,7 @@ struct ch7xxx_priv {
 
 static void ch7xxx_save(I2CDevPtr d);
 
-static char *ch7xxx_get_id(int vid)
+static char *ch7xxx_get_id(CARD8 vid)
 {
     int i;
 
commit 4a2b0f340357c4ca58dc9586fad1337b83966362
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Thu Nov 15 18:36:54 2007 -0800

    Fix typo in 1920x1080 resolution entry

diff --git a/src/i830_tv.c b/src/i830_tv.c
index 524a0d3..14f4089 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1398,7 +1398,7 @@ static struct input_res {
 	{"1280x1024", 1280, 1024},
 	{"848x480", 848, 480},
 	{"1280x720", 1280, 720},
-	{"1920x108", 1920, 1080},
+	{"1920x1080", 1920, 1080},
 };
 
 /**
commit 04b60b6d3436fb57163c23acf335364f0ea2f79c
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Thu Nov 15 11:49:53 2007 -0800

    Bump version to 2.2.0

diff --git a/configure.ac b/configure.ac
index b79aac8..20aebb4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-intel],
-        2.1.99,
+        2.2.0,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-intel)
 
commit 6eecef4fed8a21dfdabef42eb69fd150b96167b2
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Thu Nov 15 10:10:59 2007 -0800

    Adjust default TV out paramaters
    
    According to several users, a default brightness of 0 results in much better TV
    output.  Improved control of these parameters will be provided by Randr1.3,
    which will standardize several output properties across various chips.

diff --git a/src/i830_tv.c b/src/i830_tv.c
index e54786a..524a0d3 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1178,7 +1178,7 @@ i830_tv_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 	    (i830_float_to_csc(color_conversion->bv) << 16) |
 	    (i830_float_to_luma(color_conversion->av)));
 
-    OUTREG(TV_CLR_KNOBS, 0x10606000);
+    OUTREG(TV_CLR_KNOBS, 0x00606000);
     OUTREG(TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
 		(video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
     {
commit 7552d80e367fe38bbc594fe94abd649917fe54d5
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Thu Nov 15 10:07:34 2007 -0800

    Add 1920x1080 mode to TV out
    
    Allows users to use 1080p modes on TV out, see bug #13034.

diff --git a/src/i830_tv.c b/src/i830_tv.c
index ee2538a..e54786a 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1398,6 +1398,7 @@ static struct input_res {
 	{"1280x1024", 1280, 1024},
 	{"848x480", 848, 480},
 	{"1280x720", 1280, 720},
+	{"1920x108", 1920, 1080},
 };
 
 /**
commit e56c166ceb8c1ceddd5020e8de2d0b9d51f535a4
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Nov 15 18:34:18 2007 +0800

    remove unnecessary i830_reg.h includes
    
    i830_reg.h only contains 3d engine cmds for 8XX chips.

diff --git a/src/i830_display.c b/src/i830_display.c
index 223a6aa..0e42624 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -38,7 +38,6 @@
 
 #include "xf86.h"
 #include "i830.h"
-#include "i830_reg.h"
 #include "i830_bios.h"
 #include "i830_display.h"
 #include "i830_debug.h"
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5d56104..7818ee4 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -194,7 +194,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "vbe.h"
 #include "shadow.h"
 #include "i830.h"
-#include "i830_reg.h"
 #include "i830_display.h"
 #include "i830_debug.h"
 #include "i830_bios.h"
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 56bc15e..32c55dd 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -35,7 +35,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "xaarop.h"
 #include "i830.h"
 #include "i810_reg.h"
-#include "i830_reg.h"
 #include <string.h>
 
 #ifdef I830DEBUG
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 1ad4438..85b6528 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -106,7 +106,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "i830.h"
 #include "i810_reg.h"
-#include "i830_reg.h"
 
 #define ALIGN(i,m)    (((i) + (m) - 1) & ~((m) - 1))
 
commit 6f3de19159cd7a2d73ed212add909edb3aedce9c
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Thu Nov 15 18:33:27 2007 +0800

    Move fb compression reg definition into i810_reg.h
    
    where we put MMIO control reg in, and shared with intel_reg_dump
    program.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 598fc8c..a6663a4 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -2596,4 +2596,37 @@ typedef enum {
 #define PALETTE_A		0x0a000
 #define PALETTE_B		0x0a800
 
+/* Framebuffer compression */
+#define FBC_CFB_BASE		0x03200 /* 4k page aligned */
+#define FBC_LL_BASE		0x03204 /* 4k page aligned */
+#define FBC_CONTROL		0x03208
+#define   FBC_CTL_EN		(1<<31)
+#define   FBC_CTL_PERIODIC	(1<<30)
+#define   FBC_CTL_INTERVAL_SHIFT (16)
+#define   FBC_CTL_UNCOMPRESSIBLE (1<<14)
+#define   FBC_CTL_STRIDE_SHIFT	(5)
+#define   FBC_CTL_FENCENO	(1<<0)
+#define FBC_COMMAND		0x0320c
+#define   FBC_CMD_COMPRESS	(1<<0)
+#define FBC_STATUS		0x03210
+#define   FBC_STAT_COMPRESSING	(1<<31)
+#define   FBC_STAT_COMPRESSED	(1<<30)
+#define   FBC_STAT_MODIFIED	(1<<29)
+#define   FBC_STAT_CURRENT_LINE	(1<<0)
+#define FBC_CONTROL2		0x03214
+#define   FBC_CTL_FENCE_DBL	(0<<4)
+#define   FBC_CTL_IDLE_IMM	(0<<2)
+#define   FBC_CTL_IDLE_FULL	(1<<2)
+#define   FBC_CTL_IDLE_LINE	(2<<2)
+#define   FBC_CTL_IDLE_DEBUG	(3<<2)
+#define   FBC_CTL_CPU_FENCE	(1<<1)
+#define   FBC_CTL_PLANEA	(0<<0)
+#define   FBC_CTL_PLANEB	(1<<0)
+#define FBC_FENCE_OFF		0x0321b
+#define FBC_MOD_NUM		0x03220
+#define FBC_TAG_DEBUG		0x03300
+
+#define FBC_LL_SIZE		(1536)
+#define FBC_LL_PAD		(32)
+
 #endif /* _I810_REG_H */
diff --git a/src/i830_debug.c b/src/i830_debug.c
index 6963c89..8f8ef9b 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -36,7 +36,6 @@
 
 #include "xf86.h"
 #include "i830.h"
-#include "i830_reg.h"
 #include "i830_debug.h"
 #include <strings.h>
 
diff --git a/src/i830_reg.h b/src/i830_reg.h
index 4d7736a..7a8df9f 100644
--- a/src/i830_reg.h
+++ b/src/i830_reg.h
@@ -29,39 +29,6 @@
 #ifndef _I830_REG_H_
 #define _I830_REG_H_
 
-/* Framebuffer compression */
-#define FBC_CFB_BASE		0x03200 /* 4k page aligned */
-#define FBC_LL_BASE		0x03204 /* 4k page aligned */
-#define FBC_CONTROL		0x03208
-#define   FBC_CTL_EN		(1<<31)
-#define   FBC_CTL_PERIODIC	(1<<30)
-#define   FBC_CTL_INTERVAL_SHIFT (16)
-#define   FBC_CTL_UNCOMPRESSIBLE (1<<14)
-#define   FBC_CTL_STRIDE_SHIFT	(5)
-#define   FBC_CTL_FENCENO	(1<<0)
-#define FBC_COMMAND		0x0320c
-#define   FBC_CMD_COMPRESS	(1<<0)
-#define FBC_STATUS		0x03210
-#define   FBC_STAT_COMPRESSING	(1<<31)
-#define   FBC_STAT_COMPRESSED	(1<<30)
-#define   FBC_STAT_MODIFIED	(1<<29)
-#define   FBC_STAT_CURRENT_LINE	(1<<0)
-#define FBC_CONTROL2		0x03214
-#define   FBC_CTL_FENCE_DBL	(0<<4)
-#define   FBC_CTL_IDLE_IMM	(0<<2)
-#define   FBC_CTL_IDLE_FULL	(1<<2)
-#define   FBC_CTL_IDLE_LINE	(2<<2)
-#define   FBC_CTL_IDLE_DEBUG	(3<<2)
-#define   FBC_CTL_CPU_FENCE	(1<<1)
-#define   FBC_CTL_PLANEA	(0<<0)
-#define   FBC_CTL_PLANEB	(1<<0)
-#define FBC_FENCE_OFF		0x0321b
-#define FBC_MOD_NUM		0x03220
-#define FBC_TAG_DEBUG		0x03300
-
-#define FBC_LL_SIZE		(1536)
-#define FBC_LL_PAD		(32)
-
 #define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
 
 #define CMD_3D (0x3<<29)
commit e64f4929690a57701241334fbca17e95b39ba3d4
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Wed Nov 14 16:44:34 2007 -0800

    Backlight fixes
    
    Open the "actual_brightness" file as read only, since we only read from it.
    Also set an initial backlight_duty_cycle at init time so we don't set the
    brightness to 0 at startup.

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 0942d1c..a3a56f7 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -295,7 +295,7 @@ i830_lvds_get_backlight_kernel(xf86OutputPtr output)
 
     sprintf(path, "%s/%s/actual_brightness", BACKLIGHT_CLASS,
 	    backlight_interfaces[backlight_index]);
-    fd = open(path, O_RDWR);
+    fd = open(path, O_RDONLY);
     if (fd == -1) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "failed to open %s for backlight "
 		   "control: %s\n", path, strerror(errno));
@@ -1015,6 +1015,8 @@ i830_lvds_init(ScrnInfoPtr pScrn)
 	break;
     }
 
+    dev_priv->backlight_duty_cycle = dev_priv->backlight_max;
+
     return;
 
 disable_exit:
commit 53e3693ef13f31f3fc33bcff7286ab2b03b2d430
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Wed Nov 14 16:24:56 2007 -0800

    Disable FBC by default on 965GM
    
    Several people have reported that they see frequent FBC related display
    corruption on 965GM, so disable it for now.  Users wanting to enable it can use
    the driver option "Framebuffercompression" to override the default.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index abe6932..5d56104 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2449,7 +2449,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
    }
 
    /* Enable FB compression if possible */
-   if (i830_fb_compression_supported(pI830))
+   if (i830_fb_compression_supported(pI830) && !IS_I965GM(pI830))
        pI830->fb_compression = TRUE;
    else
        pI830->fb_compression = FALSE;
commit b2726899bc6ebd108aa4a5dd66fe1d881bb778b3
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Wed Nov 14 15:49:41 2007 -0800

    Add more FBC regs
    
    Needed for the new debug code

diff --git a/src/i830_reg.h b/src/i830_reg.h
index df22ed4..4d7736a 100644
--- a/src/i830_reg.h
+++ b/src/i830_reg.h
@@ -56,6 +56,8 @@
 #define   FBC_CTL_PLANEA	(0<<0)
 #define   FBC_CTL_PLANEB	(1<<0)
 #define FBC_FENCE_OFF		0x0321b
+#define FBC_MOD_NUM		0x03220
+#define FBC_TAG_DEBUG		0x03300
 
 #define FBC_LL_SIZE		(1536)
 #define FBC_LL_PAD		(32)
commit b7bc694c6b98dac17763426d905a22d3ae17a018
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Wed Nov 14 15:46:57 2007 -0800

    Fix kernel get_brightness function
    
    We need to look at "actual_brightness" rather than "brightness".  The former
    contains the brightness value the kernel driver has actually set, while the
    latter is merely what the user requested.

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 694414a..0942d1c 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -293,7 +293,7 @@ i830_lvds_get_backlight_kernel(xf86OutputPtr output)
     char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN];
     int fd;
 
-    sprintf(path, "%s/%s/brightness", BACKLIGHT_CLASS,
+    sprintf(path, "%s/%s/actual_brightness", BACKLIGHT_CLASS,
 	    backlight_interfaces[backlight_index]);
     fd = open(path, O_RDWR);
     if (fd == -1) {
commit 9ee96ed02aacd953ab58288fddf0fa60f60b668e
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Wed Nov 14 15:44:56 2007 -0800

    Correct FBC debug message
    
    To be consistent, it should say 'plane' rather than 'pipe'.

diff --git a/src/i830_display.c b/src/i830_display.c
index ea10c8a..223a6aa 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -646,7 +646,7 @@ i830_disable_fb_compression(xf86CrtcPtr crtc)
     /* Wait for compressing bit to clear */
     while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
 	; /* nothing */
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on pipe %c\n", plane);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on plane %c\n", plane);
 }
 
 /**
commit 675b9471d84059496ca41d427a4f95d419f82be9
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Wed Nov 14 15:17:05 2007 -0800

    Add FBC registers to register dump output
    
    Just for completeness.

diff --git a/src/i830_debug.c b/src/i830_debug.c
index 0237182..6963c89 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -36,6 +36,7 @@
 
 #include "xf86.h"
 #include "i830.h"
+#include "i830_reg.h"
 #include "i830_debug.h"
 #include <strings.h>
 
@@ -403,6 +404,15 @@ static struct i830SnapshotRec {
     DEFINEREG2(PIPEACONF, i830_debug_pipeconf),
     DEFINEREG2(PIPEASRC, i830_debug_yxminus1),
 
+    DEFINEREG(FBC_CFB_BASE),
+    DEFINEREG(FBC_LL_BASE),
+    DEFINEREG(FBC_CONTROL),
+    DEFINEREG(FBC_COMMAND),
+    DEFINEREG(FBC_STATUS),
+    DEFINEREG(FBC_CONTROL2),
+    DEFINEREG(FBC_FENCE_OFF),
+    DEFINEREG(FBC_MOD_NUM),
+
     DEFINEREG2(FPA0, i830_debug_fp),
     DEFINEREG2(FPA1, i830_debug_fp),
     DEFINEREG2(DPLL_A, i830_debug_dpll),
commit a2a0821e74a61f53cc7f0c41ce629644ad712114
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Wed Nov 14 11:30:20 2007 -0800

    Don't stop ring before restoring hw state
    
    Some of the hw state restoration callbacks may want to use the ring for various
    things like stopping video playback, so leave the ring enabled until we get
    back from RestoreHWState.  Also rename the functions so that their purpose is
    clearer and remove a couple of redundant lines.

diff --git a/src/i830.h b/src/i830.h
index 3abc800..2c1ac86 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -664,7 +664,7 @@ i830_crtc_hide_cursor (xf86CrtcPtr crtc);
 void
 i830_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg);
 
-extern void I830RefreshRing(ScrnInfoPtr pScrn);
+extern void i830_refresh_ring(ScrnInfoPtr pScrn);
 extern void I830EmitFlush(ScrnInfoPtr pScrn);
 
 #ifdef I830_XV
diff --git a/src/i830_accel.c b/src/i830_accel.c
index 4d9ea79..7501c2b 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -249,25 +249,6 @@ I830SelectBuffer(ScrnInfoPtr pScrn, int buffer)
 	     buffer, pI830->bufferOffset);
 }
 
-void
-I830RefreshRing(ScrnInfoPtr pScrn)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-
-   /* If we're reaching RefreshRing as a result of grabbing the DRI lock
-    * before we've set up the ringbuffer, don't bother.
-    */
-   if (pI830->LpRing->mem == NULL)
-       return;
-
-   pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK;
-   pI830->LpRing->tail = INREG(LP_RING + RING_TAIL);
-   pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8);
-   if (pI830->LpRing->space < 0)
-      pI830->LpRing->space += pI830->LpRing->mem->size;
-   i830MarkSync(pScrn);
-}
-
 /* The following function sets up the supported acceleration. Call it
  * from the FbInit() function in the SVGA driver, or before ScreenInit
  * in a monolithic server.
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 4928808..b223b02 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1093,7 +1093,7 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
       if (!pScrn->vtSema)
      	 return;
       pI830->LockHeld = 1;
-      I830RefreshRing(pScrn);
+      i830_refresh_ring(pScrn);
 
       I830EmitFlush(pScrn);
 
@@ -1777,7 +1777,7 @@ I830DRILock(ScrnInfoPtr pScrn)
    if (pI830->directRenderingEnabled && !pI830->LockHeld) {
       DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
       pI830->LockHeld = 1;
-      I830RefreshRing(pScrn);
+      i830_refresh_ring(pScrn);
       return TRUE;
    }
    else
diff --git a/src/i830_driver.c b/src/i830_driver.c
index e000d92..abe6932 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1730,7 +1730,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
  * whoever gets control next should do.
  */
 static void
-ResetState(ScrnInfoPtr pScrn, Bool flush)
+i830_stop_ring(ScrnInfoPtr pScrn, Bool flush)
 {
    I830Ptr pI830 = I830PTR(pScrn);
    unsigned long temp;
@@ -1743,34 +1743,23 @@ ResetState(ScrnInfoPtr pScrn, Bool flush)
       pI830->entityPrivate->RingRunning = 0;
 
    /* Flush the ring buffer (if enabled), then disable it. */
-   /* God this is ugly */
-#define flush_ring() do { \
-      temp = INREG(LP_RING + RING_LEN); \
-      if (temp & RING_VALID) { \
-	 I830RefreshRing(pScrn); \
-	 I830Sync(pScrn); \
-	 DO_RING_IDLE(); \
-      } \
-   } while(0)
-#ifdef I830_USE_XAA
-   if (!pI830->useEXA && flush && pI830->AccelInfoRec)
-       flush_ring();
-#endif
-#ifdef I830_USE_EXA
-   if (pI830->useEXA && flush && pI830->EXADriverPtr)
-       flush_ring();
-#endif
-
-   OUTREG(LP_RING + RING_LEN, 0);
-   OUTREG(LP_RING + RING_HEAD, 0);
-   OUTREG(LP_RING + RING_TAIL, 0);
-   OUTREG(LP_RING + RING_START, 0);
+   if (!pI830->noAccel) {
+      temp = INREG(LP_RING + RING_LEN);
+      if (temp & RING_VALID) {
+	 i830_refresh_ring(pScrn);
+	 I830Sync(pScrn);
+	 DO_RING_IDLE();
+      }
 
-   xf86_hide_cursors (pScrn);
+      OUTREG(LP_RING + RING_LEN, 0);
+      OUTREG(LP_RING + RING_HEAD, 0);
+      OUTREG(LP_RING + RING_TAIL, 0);
+      OUTREG(LP_RING + RING_START, 0);
+   }
 }
 
 static void
-SetRingRegs(ScrnInfoPtr pScrn)
+i830_start_ring(ScrnInfoPtr pScrn)
 {
    I830Ptr pI830 = I830PTR(pScrn);
    unsigned int itemp;
@@ -1807,7 +1796,26 @@ SetRingRegs(ScrnInfoPtr pScrn)
    itemp = (pI830->LpRing->mem->size - 4096) & I830_RING_NR_PAGES;
    itemp |= (RING_NO_REPORT | RING_VALID);
    OUTREG(LP_RING + RING_LEN, itemp);
-   I830RefreshRing(pScrn);
+   i830_refresh_ring(pScrn);
+}
+
+void
+i830_refresh_ring(ScrnInfoPtr pScrn)
+{
+   I830Ptr pI830 = I830PTR(pScrn);
+
+   /* If we're reaching RefreshRing as a result of grabbing the DRI lock
+    * before we've set up the ringbuffer, don't bother.
+    */
+   if (pI830->LpRing->mem == NULL)
+       return;
+
+   pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK;
+   pI830->LpRing->tail = INREG(LP_RING + RING_TAIL);
+   pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8);
+   if (pI830->LpRing->space < 0)
+      pI830->LpRing->space += pI830->LpRing->mem->size;
+   i830MarkSync(pScrn);
 }
 
 /*
@@ -1834,8 +1842,7 @@ SetHWOperatingState(ScrnInfoPtr pScrn)
       OUTREG(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
    }
 
-   if (!pI830->noAccel)
-      SetRingRegs(pScrn);
+   i830_start_ring(pScrn);
    if (!pI830->SWCursor)
       I830InitHWCursor(pScrn);
 }
@@ -3002,10 +3009,10 @@ I830LeaveVT(int scrnIndex, int flags)
 
    xf86_hide_cursors (pScrn);
 
-   ResetState(pScrn, TRUE);
-
    RestoreHWState(pScrn);
 
+   i830_stop_ring(pScrn, TRUE);
+
    if (pI830->debug_modes) {
       i830CompareRegsToSnapshot(pScrn, "After LeaveVT");
       i830DumpRegs (pScrn);
@@ -3078,7 +3085,7 @@ I830EnterVT(int scrnIndex, int flags)
 		 "Existing errors found in hardware state.\n");
    }
 
-   ResetState(pScrn, FALSE);
+   i830_stop_ring(pScrn, FALSE);
    SetHWOperatingState(pScrn);
 
    /* Clear the framebuffer */
@@ -3099,7 +3106,7 @@ I830EnterVT(int scrnIndex, int flags)
    }
    i830DescribeOutputConfiguration(pScrn);
 
-   ResetState(pScrn, TRUE);
+   i830_stop_ring(pScrn, TRUE);
    SetHWOperatingState(pScrn);
 
 #ifdef XF86DRI
@@ -3119,7 +3126,7 @@ I830EnterVT(int scrnIndex, int flags)
 
 	 I830DRIResume(screenInfo.screens[scrnIndex]);
       
-	 I830RefreshRing(pScrn);
+	 i830_refresh_ring(pScrn);
 	 I830Sync(pScrn);
 	 DO_RING_IDLE();
 
commit ad3bc0158d37e98fcbbe6a8e31413c142a260424
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Nov 14 22:46:46 2007 +0800

    Don't enable fbc with XAA or tiling is off.
    
    This slightly reworks my last fbc patch. We don't
    support tiled front buffer with XAA now, so also
    disable fbc on it. If tiled alloc failed, disable
    fbc too.

diff --git a/src/i830.h b/src/i830.h
index 17d2fe2..3abc800 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -805,6 +805,11 @@ static inline int i830_fb_compression_supported(I830Ptr pI830)
 	return FALSE;
     if (IS_I810(pI830) || IS_I815(pI830) || IS_I830(pI830))
 	return FALSE;
+    /* fbc depends on tiled surface. And we don't support tiled
+     * front buffer with XAA now.
+     */
+    if (!pI830->tiling || (IS_I965G(pI830) && !pI830->useEXA))
+	return FALSE;
     return TRUE;
 }
 
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 8d58a08..e000d92 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2554,15 +2554,17 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 			  "Couldn't allocate tiled memory, page flipping "
 			  "disabled\n");
 	    pI830->allowPageFlip = FALSE;
+	    if (pI830->fb_compression)
+	       xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+			  "Couldn't allocate tiled memory, fb compression "
+			  "disabled\n");
+	    pI830->fb_compression = FALSE;
 	 }
 
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		    "Attempting memory allocation with %s buffers.\n",
 		    (i & 1) ? "untiled" : "tiled");
 
-	 if (!pI830->tiling && pI830->fb_compression)
-	     pI830->fb_compression = FALSE;
-
 	 if (i830_allocate_2d_memory(pScrn) &&
 	     i830_allocate_3d_memory(pScrn))
 	 {
commit 26194e19e1c80615697016e25640d4c8c244353f
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Tue Nov 13 22:26:40 2007 -0800

    Review PLL spreadsheet and update register ranges.
    
    The PLL spreadsheet makes the precise register ranges allowed for each mode
    quite clear, and shows a few inaccuracies in the b-spec. In particular, the
    N register value may range from 1 to 6 instead of 3 to 8. This should close
    the gap we've seen in the reachable frequencies.

diff --git a/src/i830_display.c b/src/i830_display.c
index d988b86..ea10c8a 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -100,14 +100,26 @@ typedef struct {
 #define I9XX_DOT_MAX		 400000
 #define I9XX_VCO_MIN		1400000
 #define I9XX_VCO_MAX		2800000
-#define I9XX_N_MIN		      3
-#define I9XX_N_MAX		      8
+
+/* Haven't found any reason to go this fast, but newer chips support it */
+#define I96X_VCO_MAX		3200000
+
+/*
+ * These values are taken from the broadwater/crestline PLL spreadsheet.
+ * All of the defines here are for the programmed register value, not
+ * the 'counter' value (e.g. Ncounter = Nregister + 2)
+ */
+#define I9XX_N_MIN		      1
+#define I9XX_N_MAX		      6
 #define I9XX_M_MIN		     70
 #define I9XX_M_MAX		    120
+
+/* these two come from the calm1 macro */
 #define I9XX_M1_MIN		     10
-#define I9XX_M1_MAX		     20
+#define I9XX_M1_MAX		     22
 #define I9XX_M2_MIN		      5
 #define I9XX_M2_MAX		      9
+
 #define I9XX_P_SDVO_DAC_MIN	      5
 #define I9XX_P_SDVO_DAC_MAX	     80
 #define I9XX_P_LVDS_MIN		      7
diff --git a/src/scripts/clock-graph.5c b/src/scripts/clock-graph.5c
index e39e559..324febf 100644
--- a/src/scripts/clock-graph.5c
+++ b/src/scripts/clock-graph.5c
@@ -9,7 +9,7 @@ int max_vco = 2800000000;
 int min = 0xffffffff;
 int max = 0;
 
-int max_clocks = 1000;
+int max_clocks = 2000;
 int[4][max_clocks] clocks;
 int[4][max_clocks] vcos;
 int[4] clock_count = {0...};
@@ -35,9 +35,9 @@ void calc_p2(int p2i)
 		max_p = 80;
 	}
 
-	for (int m1 = 10; m1 <= 20; m1++) {
+	for (int m1 = 10; m1 <= 22; m1++) {
 		for (int m2 = 5; m2 <= 9; m2++) {
-			for (int n = 3; n <= 8; n++) {
+			for (int n = 1; n <= 5; n++) {
 				for (int p1 = 1; p1 <= 8; p1++) {
 					int ref = 96000000;
 					int m = 5 * (m1 + 2) + (m2 + 2);
diff --git a/src/scripts/clock.5c b/src/scripts/clock.5c
index 8ee9d90..c83c689 100644
--- a/src/scripts/clock.5c
+++ b/src/scripts/clock.5c
@@ -11,9 +11,9 @@ if (p2 == 7 || p2 == 14) {
 	max_p = 80;
 }
 
-for (int m1 = 10; m1 <= 20; m1++) {
+for (int m1 = 10; m1 <= 22; m1++) {
 	for (int m2 = 5; m2 <= 9; m2++) {
-		for (int n = 3; n <= 8; n++) {
+		for (int n = 1; n <= 6; n++) {
 			for (int p1 = 1; p1 <= 8; p1++) {
 				int ref = 96000000;
 				int m = 5 * (m1 + 2) + (m2 + 2);
commit 581509321e51becb8ee6ddcfaa15a2a713c9ef8e
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Nov 14 22:16:04 2007 +0800

    Remove one redundant line.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index debe539..8d58a08 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2606,8 +2606,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
       pI830->directRenderingEnabled = FALSE;
    }
 
-   pScrn->displayWidth = pScrn->displayWidth;
-
 #ifdef HAS_MTRR_SUPPORT
    {
       int fd;
commit 8cea3c8cfa86600b5f2c3e1f21c19d4b2a320fd4
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Nov 14 22:13:30 2007 +0800

    Don't setup fb compression if fb is not tiling

diff --git a/src/i830_driver.c b/src/i830_driver.c
index fdbf9ec..debe539 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2560,6 +2560,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 		    "Attempting memory allocation with %s buffers.\n",
 		    (i & 1) ? "untiled" : "tiled");
 
+	 if (!pI830->tiling && pI830->fb_compression)
+	     pI830->fb_compression = FALSE;
+
 	 if (i830_allocate_2d_memory(pScrn) &&
 	     i830_allocate_3d_memory(pScrn))
 	 {
commit 539b669d6e23833a917a9b0d3a355d4283e0b76a
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Tue Nov 13 17:59:54 2007 -0800

    Remove harmless error message
    
    This really isn't an error in general.  If vblank pipe setup really fails for
    some reason, it'll be obvious enough when the user tries to use vblank events
    for something.
    
    Patch from Hong Liu.

diff --git a/src/i830_dri.c b/src/i830_dri.c
index 4d3458f..4928808 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1762,7 +1762,6 @@ I830DRISetVBlankInterrupt (ScrnInfoPtr pScrn, Bool on)
 	}
 	if (drmCommandWrite(pI830->drmSubFD, DRM_I830_SET_VBLANK_PIPE,
 			    &pipe, sizeof (pipe))) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I830 Vblank Pipe Setup Failed %d\n", pipe.pipe);
 	    return FALSE;
 	}
     }
commit 43fbc547786cf26514f95bce79fab58a66c291bf
Author: Jesse Barnes <jbarnes at jbarnes-mobile.amr.corp.intel.com>
Date:   Mon Nov 12 12:23:41 2007 -0800

    Improve backlight control
    
    This commit fixes backlight support for several platforms.
    
    Except on recent machines supporting the IGD OpRegion specification,
    backlight control is rather platform specific.  In some cases, we can
    program the native backlight control regsiters directly without any
    trouble.  On others, we need to use the legacy backlight control
    register.  On still others, we need a combination of the two.  And on
    some platforms, none of the above will work, so we go through the
    kernel backlight interface, which provides a platform specific driver
    for backlight control.

diff --git a/man/intel.man b/man/intel.man
index 963c6a2..6245736 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -184,7 +184,9 @@ The 830M and newer driver supports the following outputs through RandR 1.2:
 Analog VGA output
 .TP
 .BI "LVDS"
-Laptop panel
+Laptop panel.  Properties:
+  BACKLIGHT - set backlight level
+  BACKLIGHT_CONTROL - set backlight level control method (i.e. use kernel interfaces, native LVDS power register, legacy register, or combination)
 .TP
 .BI "TV"
 Integrated TV output
diff --git a/src/i830.h b/src/i830.h
index 57f0544..17d2fe2 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -295,6 +295,57 @@ enum last_3d {
     LAST_3D_ROTATION
 };
 
+/*
+ * Backlight control has some unfortunate properties:
+ *   - many machines won't give us brightness change notifications
+ *     o brightness hotkeys
+ *     o events like AC plug/unplug (can be controlled via _DOS setting)
+ *     o ambient light sensor triggered changes
+ *   - some machines use the so-called "legacy" backlight interface
+ *     o resulting brightness is a combo of LBB and PWM values
+ *     o LBB sits in config space
+ *   - some machines have ACPI methods for changing brightness
+ *     o one of the few ways the X server and firmware can stay in sync
+ *   - new machines have the IGD OpRegion interface available
+ *     o a reliable way of keeping the firmware and X in sync
+ *
+ * So the real problem is on machines where ACPI or OpRegion methods aren't
+ * available.  In that case, problems can occur:
+ *   1) the BIOS and X will have different ideas of what the brightness is,
+ *      leading to unexpected results when the brightness is increased or
+ *      decreased via hotkey or X protocol
+ *   2) unless X takes the legacy register into account, machines using it
+ *      may prevent X from raising the brightness above 0 if the firmware
+ *      set LBB to 0
+ * Given these problems, we provide the user with a selection of methods,
+ * so they can choose an ideal one for their platform (assuming our quirk
+ * code picks the wrong one).
+ *
+ * Four different methods are available:
+ *   NATIVE:  only ever touch the native backlight control registers
+ *     This method may be susceptible to problem (2) above if the firmware
+ *     modifies the legacy registers.
+ *   LEGACY:  only ever touch the legacy backlight control registers
+ *     This method may be susceptible to problem (1) above if the firmware
+ *     also modifies the legacy registers.
+ *   COMBO:  try to use both sets
+ *     In this case, the driver will try to modify both sets of registers
+ *     if needed.  To avoid problem (2) above it may set the LBB register
+ *     to a non-zero value if the brightness is to be increased.  It's still
+ *     susceptible to problem (1), but to a lesser extent than the LEGACY only
+ *     method.
+ *   KERNEL:  use kernel methods for controlling the backlight
+ *     This is only available on some platforms, but where present this can
+ *     provide the best user experience.
+ */
+
+enum backlight_control {
+    NATIVE = 0,
+    LEGACY,
+    COMBO,
+    KERNEL,
+};
+
 typedef struct _I830Rec {
    unsigned char *MMIOBase;
    unsigned char *GTTBase;
@@ -498,6 +549,8 @@ typedef struct _I830Rec {
 
    int ddc2;
 
+   enum backlight_control backlight_control_method;
+
    CARD32 saveDSPACNTR;
    CARD32 saveDSPBCNTR;
    CARD32 savePIPEACONF;
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 0b6b192..694414a 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -29,6 +29,15 @@
 #include "config.h"
 #endif
 
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
 #include "xf86.h"
 #include "i830.h"
 #include "i830_bios.h"
@@ -44,67 +53,113 @@ struct i830_lvds_priv {
 
     /* restore backlight to this value */
     int		    backlight_duty_cycle;
+
+    void (*set_backlight)(xf86OutputPtr output, int level);
+    int (*get_backlight)(xf86OutputPtr output);
+    int backlight_max;
 };
 
-/**
- * Use legacy backlight controls?
- *
- * \param pI830 device in question
- *
- * Returns TRUE if legacy backlight should be used, false otherwise.
+#define BACKLIGHT_CLASS "/sys/class/backlight"
+
+/*
+ * List of available kernel interfaces in priority order
  */
-static int
-i830_lvds_backlight_legacy(I830Ptr pI830)
+static char *backlight_interfaces[] = {
+    "thinkpad_screen",
+    "acpi_video1",
+    "acpi_video0",
+    NULL,
+};
+
+/*
+ * Must be long enough for BACKLIGHT_CLASS + '/' + longest in above table +
+ * '/' + "max_backlight"
+ */
+#define BACKLIGHT_PATH_LEN 80
+/* Enough for 8 digits of backlight + '\n' + '\0' */
+#define BACKLIGHT_VALUE_LEN 10
+
+static int backlight_index;
+
+static Bool
+i830_kernel_backlight_available(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    struct stat buf;
+    char path[BACKLIGHT_PATH_LEN];
+    int i;
+
+    for (i = 0; backlight_interfaces[i] != NULL; i++) {
+	sprintf(path, "%s/%s", BACKLIGHT_CLASS, backlight_interfaces[i]);
+	if (!stat(path, &buf)) {
+	    backlight_index = i;
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "found backlight control "
+		       "method %s\n", path);
+	    return 1;
+	}
+    }
+
+    return 0;
+}
+
+/* Try to figure out which backlight control method to use */
+static void
+i830_set_lvds_backlight_method(xf86OutputPtr output)
 {
+    ScrnInfoPtr pScrn = output->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
     CARD32 blc_pwm_ctl, blc_pwm_ctl2;
+    enum backlight_control method = NATIVE; /* Default to native */
 
-    /* 965GM+ change the location of the legacy control bit */
-    if (IS_I965GM(pI830)) {
+    if (i830_kernel_backlight_available(output)) {
+	    method = KERNEL;
+    } else if (IS_I965GM(pI830)) {
 	blc_pwm_ctl2 = INREG(BLC_PWM_CTL2);
 	if (blc_pwm_ctl2 & BLM_LEGACY_MODE2)
-	    return TRUE;
+	    method = COMBO;
     } else {
 	blc_pwm_ctl = INREG(BLC_PWM_CTL);
 	if (blc_pwm_ctl & BLM_LEGACY_MODE)
-	    return TRUE;
+	    method = COMBO;
     }
-    return FALSE;
+
+    pI830->backlight_control_method = method;
 }
 
-/**
- * Sets the backlight level.
- *
- * \param level backlight level, from 0 to i830_lvds_get_max_backlight().
+/*
+ * Native methods
  */
 static void
-i830_lvds_set_backlight(xf86OutputPtr output, int level)
+i830_lvds_set_backlight_native(xf86OutputPtr output, int level)
 {
     ScrnInfoPtr pScrn = output->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
     CARD32 blc_pwm_ctl;
 
-    if (i830_lvds_backlight_legacy(pI830))
-#if XSERVER_LIBPCIACCESS
-	pci_device_cfg_write_u8 (pI830->PciInfo, 0xfe, LEGACY_BACKLIGHT_BRIGHTNESS);
-#else
-	pciWriteByte(pI830->PciTag, LEGACY_BACKLIGHT_BRIGHTNESS, 0xfe);
-#endif
-
     blc_pwm_ctl = INREG(BLC_PWM_CTL);
     blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
     OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
 }
 
-/**
- * Returns the maximum level of the backlight duty cycle field.
- */
-static CARD32
-i830_lvds_get_max_backlight(xf86OutputPtr output)
+static int
+i830_lvds_get_backlight_native(xf86OutputPtr output)
 {
     ScrnInfoPtr pScrn = output->scrn;
-    I830Ptr	pI830 = I830PTR(pScrn);
-    CARD32	pwm_ctl = INREG(BLC_PWM_CTL);
-    CARD32	val;
+    I830Ptr pI830 = I830PTR(pScrn);
+    CARD32 blc_pwm_ctl;
+
+    blc_pwm_ctl = INREG(BLC_PWM_CTL);
+    blc_pwm_ctl &= BACKLIGHT_DUTY_CYCLE_MASK;
+    return blc_pwm_ctl;
+}
+
+static int
+i830_lvds_get_backlight_max_native(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    CARD32 pwm_ctl = INREG(BLC_PWM_CTL);
+    int val;
 
     if (IS_I965GM(pI830)) {
 	val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK2) >>
@@ -113,15 +168,179 @@ i830_lvds_get_max_backlight(xf86OutputPtr output)
 	val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >>
 	       BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
     }
-    
+
+    return val;
+}
+
+/*
+ * Legacy methods
+ */
+static void
+i830_lvds_set_backlight_legacy(xf86OutputPtr output, int level)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+
+#if XSERVER_LIBPCIACCESS
+    pci_device_cfg_write_u8(pI830->PciInfo, level,
+			    LEGACY_BACKLIGHT_BRIGHTNESS);
+#else
+    pciWriteByte(pI830->PciTag, LEGACY_BACKLIGHT_BRIGHTNESS, level);
+#endif
+}
+
+static int
+i830_lvds_get_backlight_legacy(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    CARD8 lbb;
+
+#if XSERVER_LIBPCIACCESS
+    pci_device_cfg_read_u8(pI830->PciInfo, &lbb, LEGACY_BACKLIGHT_BRIGHTNESS);
+#else
+    lbb = pciReadByte(pI830->PciTag, LEGACY_BACKLIGHT_BRIGHTNESS);
+#endif
+
+    return lbb;
+}
+
+/*
+ * Combo methods
+ */
+static void
+i830_lvds_set_backlight_combo(xf86OutputPtr output, int level)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    CARD32 blc_pwm_ctl;
+    CARD8 lbb;
+
+#if XSERVER_LIBPCIACCESS
+    pci_device_cfg_read_u8(pI830->PciInfo, &lbb, LEGACY_BACKLIGHT_BRIGHTNESS);
+#else
+    lbb = pciReadByte(pI830->PciTag, LEGACY_BACKLIGHT_BRIGHTNESS);
+#endif
     /*
-     * In legacy control mode, backlight value is calculated:
-     * if (LBB[7:0] != 0xff)
-     *     backlight = BLC_PWM_CTL[15:0] *  BPC[7:0]
-     * else
-     *     backlight = BLC_PWM_CTL[15:0]
+     * If LBB is zero and we're shooting for a non-zero brightness level,
+     * we have to increase LBB by at least 1.
      */
-    return val;
+    if (!lbb && level) {
+#if XSERVER_LIBPCIACCESS
+	pci_device_cfg_write_u8(pI830->PciInfo, 1,
+				LEGACY_BACKLIGHT_BRIGHTNESS);
+#else
+	pciWriteByte(pI830->PciTag, LEGACY_BACKLIGHT_BRIGHTNESS, 1);
+#endif
+    }
+
+    blc_pwm_ctl = INREG(BLC_PWM_CTL);
+    blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
+    OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
+}
+
+static int
+i830_lvds_get_backlight_combo(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    CARD32 blc_pwm_ctl;
+
+    blc_pwm_ctl = INREG(BLC_PWM_CTL);
+    blc_pwm_ctl &= BACKLIGHT_DUTY_CYCLE_MASK;
+    return blc_pwm_ctl;
+}
+
+/*
+ * Kernel methods
+ */
+static void
+i830_lvds_set_backlight_kernel(xf86OutputPtr output, int level)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN];
+    int fd, len, ret;
+
+    len = snprintf(val, BACKLIGHT_VALUE_LEN, "%d\n", level);
+    if (len > BACKLIGHT_VALUE_LEN) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "backlight value too large: %d\n",
+		   level);
+	return;
+    }
+
+    sprintf(path, "%s/%s/brightness", BACKLIGHT_CLASS,
+	    backlight_interfaces[backlight_index]);
+    fd = open(path, O_RDWR);
+    if (fd == -1) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "failed to open %s for backlight "
+		   "control: %s\n", path, strerror(errno));
+	return;
+    }
+
+    ret = write(fd, val, len);
+    if (ret == -1) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "write to %s for backlight "
+		   "control failed: %s\n", path, strerror(errno));
+    }
+
+    close(fd);
+}
+
+static int
+i830_lvds_get_backlight_kernel(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN];
+    int fd;
+
+    sprintf(path, "%s/%s/brightness", BACKLIGHT_CLASS,
+	    backlight_interfaces[backlight_index]);
+    fd = open(path, O_RDWR);
+    if (fd == -1) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "failed to open %s for backlight "
+		   "control: %s\n", path, strerror(errno));
+	return 0;
+    }
+
+    if (read(fd, val, BACKLIGHT_VALUE_LEN) == -1)
+	goto out_err;
+
+    close(fd);
+    return atoi(val);
+
+out_err:
+    close(fd);
+    return 0;
+}
+
+static int
+i830_lvds_get_backlight_max_kernel(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN];
+    int fd, max = 0;
+
+    sprintf(path, "%s/%s/max_brightness", BACKLIGHT_CLASS,
+	    backlight_interfaces[backlight_index]);
+    fd = open(path, O_RDONLY);
+    if (fd == -1) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "failed to open %s for backlight "
+		   "control: %s\n", path, strerror(errno));
+	return 0;
+    }
+
+    if (read(fd, val, BACKLIGHT_VALUE_LEN) == -1)
+	goto out_err;
+
+    close(fd);
+
+    max = atoi(val);
+    
+    return max;
+
+out_err:
+    close(fd);
+    return 0;
 }
 
 /**
@@ -142,9 +361,9 @@ i830SetLVDSPanelPower(xf86OutputPtr output, Bool on)
 	    pp_status = INREG(PP_STATUS);
 	} while ((pp_status & PP_ON) == 0);
 
-	i830_lvds_set_backlight(output, dev_priv->backlight_duty_cycle);
+	dev_priv->set_backlight(output, dev_priv->backlight_duty_cycle);
     } else {
-	i830_lvds_set_backlight(output, 0);
+	dev_priv->set_backlight(output, 0);
 
 	OUTREG(PP_CONTROL, INREG(PP_CONTROL) & ~POWER_TARGET_ON);
 	do {
@@ -179,14 +398,13 @@ i830_lvds_save (xf86OutputPtr output)
     pI830->savePP_CONTROL = INREG(PP_CONTROL);
     pI830->savePP_CYCLE = INREG(PP_CYCLE);
     pI830->saveBLC_PWM_CTL = INREG(BLC_PWM_CTL);
-    dev_priv->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL &
-				      BACKLIGHT_DUTY_CYCLE_MASK);
+    dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output);
 
     /*
      * If the light is off at server startup, just make it full brightness
      */
     if (dev_priv->backlight_duty_cycle == 0)
-	dev_priv->backlight_duty_cycle = i830_lvds_get_max_backlight(output);
+	dev_priv->backlight_duty_cycle = dev_priv->backlight_max;
 }
 
 static void
@@ -390,31 +608,105 @@ i830_lvds_destroy (xf86OutputPtr output)
 #ifdef RANDR_12_INTERFACE
 #define BACKLIGHT_NAME	"BACKLIGHT"
 static Atom backlight_atom;
+
+/*
+ * Backlight control lets the user select how the driver should manage
+ * backlight changes:  using the legacy interface, the native interface,
+ * or not at all.
+ */
+#define BACKLIGHT_CONTROL_NAME "BACKLIGHT_CONTROL"
+#define NUM_BACKLIGHT_CONTROL_METHODS 4
+static char *backlight_control_names[] = {
+    "native",
+    "legacy",
+    "combination",
+    "kernel",
+};
+static Atom backlight_control_atom;
+static Atom backlight_control_name_atoms[NUM_BACKLIGHT_CONTROL_METHODS];
+
+static int
+i830_backlight_control_lookup(char *name)
+{
+    int i;
+
+    for (i = 0; i < NUM_BACKLIGHT_CONTROL_METHODS; i++)
+	if (!strcmp(name, backlight_control_names[i]))
+	    return i;
+
+    return -1;
+}
+
+static Bool
+i830_lvds_set_backlight_control(xf86OutputPtr output)
+{
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_lvds_priv   *dev_priv = intel_output->dev_priv;
+
+    switch (pI830->backlight_control_method) {
+    case NATIVE:
+	dev_priv->set_backlight = i830_lvds_set_backlight_native;
+	dev_priv->get_backlight = i830_lvds_get_backlight_native;
+	dev_priv->backlight_max =
+	    i830_lvds_get_backlight_max_native(output);
+	break;
+    case LEGACY:
+	dev_priv->set_backlight = i830_lvds_set_backlight_legacy;
+	dev_priv->get_backlight = i830_lvds_get_backlight_legacy;
+	dev_priv->backlight_max = 0xff;
+	break;
+    case COMBO:
+	dev_priv->set_backlight = i830_lvds_set_backlight_combo;
+	dev_priv->get_backlight = i830_lvds_get_backlight_combo;
+	dev_priv->backlight_max =
+	    i830_lvds_get_backlight_max_native(output);
+	break;
+    case KERNEL:
+	dev_priv->set_backlight = i830_lvds_set_backlight_kernel;
+	dev_priv->get_backlight = i830_lvds_get_backlight_kernel;
+	dev_priv->backlight_max =
+	    i830_lvds_get_backlight_max_kernel(output);
+	break;
+    default:
+	/*
+	 * Should be impossible to get here unless the caller set a bogus
+	 * backlight_control_method
+	 */
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "error: bad backlight control "
+		   "method\n");
+	break;
+    }
+
+    return Success;
+}
 #endif /* RANDR_12_INTERFACE */
 
 static void
 i830_lvds_create_resources(xf86OutputPtr output)
 {
 #ifdef RANDR_12_INTERFACE
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
     I830OutputPrivatePtr    intel_output = output->driver_private;
     struct i830_lvds_priv   *dev_priv = intel_output->dev_priv;
-    ScrnInfoPtr		    pScrn = output->scrn;
-    INT32		    range[2];
-    int			    data, err;
+    INT32		    backlight_range[2];
+    int			    data, err, i;
 
     /* Set up the backlight property, which takes effect immediately
-     * and accepts values only within the range.
+     * and accepts values only within the backlight_range.
      *
      * XXX: Currently, RandR doesn't verify that properties set are
-     * within the range.
+     * within the backlight_range.
      */
     backlight_atom = MakeAtom(BACKLIGHT_NAME, sizeof(BACKLIGHT_NAME) - 1,
 	TRUE);
 
-    range[0] = 0;
-    range[1] = i830_lvds_get_max_backlight(output);
+    backlight_range[0] = 0;
+    backlight_range[1] = dev_priv->backlight_max;
     err = RRConfigureOutputProperty(output->randr_output, backlight_atom,
-				    FALSE, TRUE, FALSE, 2, range);
+				    FALSE, TRUE, FALSE, 2, backlight_range);
     if (err != 0) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "RRConfigureOutputProperty error, %d\n", err);
@@ -429,6 +721,32 @@ i830_lvds_create_resources(xf86OutputPtr output)
 		   "RRChangeOutputProperty error, %d\n", err);
     }
 
+    /*
+     * Now setup the control selection property
+     */
+    backlight_control_atom = MakeAtom(BACKLIGHT_CONTROL_NAME,
+				      sizeof(BACKLIGHT_CONTROL_NAME) - 1, TRUE);
+    for (i = 0; i < NUM_BACKLIGHT_CONTROL_METHODS; i++) {
+	backlight_control_name_atoms[i] =
+	    MakeAtom(backlight_control_names[i],
+		     strlen(backlight_control_names[i]), TRUE);
+    }
+    err = RRConfigureOutputProperty(output->randr_output,
+				    backlight_control_atom, TRUE, FALSE, FALSE,
+				    NUM_BACKLIGHT_CONTROL_METHODS,
+				    (INT32 *)backlight_control_name_atoms);
+    if (err != 0) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "RRConfigureOutputProperty error, %d\n", err);
+    }
+    err = RRChangeOutputProperty(output->randr_output, backlight_control_atom,
+				 XA_ATOM, 32, PropModeReplace, 1,
+				 &backlight_control_name_atoms[pI830->backlight_control_method],
+				 FALSE, TRUE);
+    if (err != 0) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "failed to set backlight control, %d\n", err);
+    }
 #endif /* RANDR_12_INTERFACE */
 }
 
@@ -437,6 +755,8 @@ static Bool
 i830_lvds_set_property(xf86OutputPtr output, Atom property,
 		       RRPropertyValuePtr value)
 {
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
     I830OutputPrivatePtr    intel_output = output->driver_private;
     struct i830_lvds_priv   *dev_priv = intel_output->dev_priv;
     
@@ -450,15 +770,54 @@ i830_lvds_set_property(xf86OutputPtr output, Atom property,
 	}
 
 	val = *(INT32 *)value->data;
-	if (val < 0 || val > i830_lvds_get_max_backlight(output))
+	if (val < 0 || val > dev_priv->backlight_max)
 	    return FALSE;
 
-	if (val != dev_priv->backlight_duty_cycle)
-	{
-	    i830_lvds_set_backlight(output, val);
+	if (val != dev_priv->backlight_duty_cycle) {
+	    dev_priv->set_backlight(output, val);
 	    dev_priv->backlight_duty_cycle = val;
 	}
 	return TRUE;
+    } else if (property == backlight_control_atom) {
+	INT32		    	backlight_range[2];
+	Atom			atom;
+	char			*name;
+	int			ret, data;
+
+	if (value->type != XA_ATOM || value->format != 32 || value->size != 1)
+	    return FALSE;
+
+	memcpy(&atom, value->data, 4);
+	name = NameForAtom(atom);
+	
+	ret = i830_backlight_control_lookup(name);
+	if (ret < 0)
+	    return FALSE;
+
+	pI830->backlight_control_method = ret;
+	i830_lvds_set_backlight_control(output);
+
+	/*
+	 * Update the backlight atom since the range and value may have changed
+	 */
+	backlight_range[0] = 0;
+	backlight_range[1] = dev_priv->backlight_max;
+	ret = RRConfigureOutputProperty(output->randr_output, backlight_atom,
+					FALSE, TRUE, FALSE, 2, backlight_range);
+	if (ret != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRConfigureOutputProperty error, %d\n", ret);
+	}
+	/* Set the current value of the backlight property */
+	data = dev_priv->get_backlight(output);
+	ret = RRChangeOutputProperty(output->randr_output, backlight_atom,
+				     XA_INTEGER, 32, PropModeReplace, 1, &data,
+				     FALSE, TRUE);
+	if (ret != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRChangeOutputProperty error, %d\n", ret);
+	}
+	return TRUE;
     }
 
     return TRUE;
@@ -628,6 +987,34 @@ i830_lvds_init(ScrnInfoPtr pScrn)
 	}
     }
 
+    i830_set_lvds_backlight_method(output);
+
+    switch (pI830->backlight_control_method) {
+    case NATIVE:
+	dev_priv->set_backlight = i830_lvds_set_backlight_native;
+	dev_priv->get_backlight = i830_lvds_get_backlight_native;
+	dev_priv->backlight_max = i830_lvds_get_backlight_max_native(output);
+	break;
+    case LEGACY:
+	dev_priv->set_backlight = i830_lvds_set_backlight_legacy;
+	dev_priv->get_backlight = i830_lvds_get_backlight_legacy;
+	dev_priv->backlight_max = 0xff;
+	break;
+    case COMBO:
+	dev_priv->set_backlight = i830_lvds_set_backlight_combo;
+	dev_priv->get_backlight = i830_lvds_get_backlight_combo;
+	dev_priv->backlight_max = i830_lvds_get_backlight_max_native(output);
+	break;
+    case KERNEL:
+	dev_priv->set_backlight = i830_lvds_set_backlight_kernel;
+	dev_priv->get_backlight = i830_lvds_get_backlight_kernel;
+	dev_priv->backlight_max = i830_lvds_get_backlight_max_kernel(output);
+	break;
+    default:
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "bad backlight control method\n");
+	break;
+    }
+
     return;
 
 disable_exit:
commit 10988c5e6ec0f3c40d56bbf209b7976627cca706
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Mon Nov 12 09:19:22 2007 -0800

    Fix typo in PLL enable check
    
    Check against DPLL_A instead of DPLL_B before writing PIPEACONF.
    
    Thanks to Colin Guthrie for his sharp eyes.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index eacaefc..fdbf9ec 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2056,8 +2056,8 @@ RestoreHWState(ScrnInfoPtr pScrn)
     * Make sure the DPLL is active and not in VGA mode or the
     * write of PIPEnCONF may cause a crash
     */
-   if ((pI830->saveDPLL_B & DPLL_VCO_ENABLE) &&
-       (pI830->saveDPLL_B & DPLL_VGA_MODE_DIS))
+   if ((pI830->saveDPLL_A & DPLL_VCO_ENABLE) &&
+       (pI830->saveDPLL_A & DPLL_VGA_MODE_DIS))
 	   OUTREG(PIPEACONF, pI830->savePIPEACONF);
    i830WaitForVblank(pScrn);
    OUTREG(DSPACNTR, pI830->saveDSPACNTR);
commit ab2055ebb20aa6de121fa377e488ce91913035ae
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Fri Nov 9 13:55:46 2007 -0800

    Add 'ret' variable to i830_allocator_init
    
    Needed in the XF86DRI_MM case.

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 7e9fb4f..1ad4438 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -476,6 +476,8 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
 				   ALIGN_BOTH_ENDS | NEED_NON_STOLEN);
 
 	if (pI830->memory_manager != NULL) {
+	    int ret;
+
 	    /* Tell the kernel to manage it */
 	    ret = drmMMInit(pI830->drmSubFD,
 			    pI830->memory_manager->offset / GTT_PAGE_SIZE,
commit 24280edbdf54e9559b26ea27c1b005eea73f51bc
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Fri Nov 9 13:53:58 2007 -0800

    Fixup warnings
    
    Remove unused 'ret' variable, move pI830 under #ifdef XF86DRI_MM in
    i830_allocate_memory.

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 7b89c40..7e9fb4f 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -389,7 +389,6 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     i830_memory *start, *end;
-    int ret;
 #ifdef XF86DRI_MM
     int dri_major, dri_minor, dri_patch;
 #endif
@@ -824,10 +823,11 @@ i830_memory *
 i830_allocate_memory(ScrnInfoPtr pScrn, const char *name,
 		     unsigned long size, unsigned long alignment, int flags)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
     i830_memory *mem;
 
 #ifdef XF86DRI_MM
+    I830Ptr pI830 = I830PTR(pScrn);
+
     if (pI830->memory_manager && !(flags & NEED_PHYSICAL_ADDR) &&
 	!(flags & NEED_LIFETIME_FIXED))
     {
commit 4fe507957bf826d81a71cd63af17c5547d1023a1
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Fri Nov 9 13:51:11 2007 -0800

    Remove unused 'palette_enable' variable

diff --git a/src/i830_debug.c b/src/i830_debug.c
index 54dff29..0237182 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -564,7 +564,7 @@ static void i830DumpAR(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     int i;
-    uint16_t st01, palette_enable = 0;
+    uint16_t st01;
     unsigned char orig_arx, msr;
 
     msr = INREG8(0x3cc);
commit 62404a9c9c0d98efb69ac96209dea17331e0489c
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Fri Nov 9 07:55:01 2007 -0800

    Update man page to reflect EXA by default

diff --git a/man/intel.man b/man/intel.man
index efe34d7..963c6a2 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -168,9 +168,9 @@ Default for i830 and above: Disabled.
 .TP
 .BI "Option \*qAccelMethod\*q \*q" string \*q
 Choose acceleration architecture, either "XAA" or "EXA".  XAA is the old
-(but stable) XFree86 based acceleration architecture.  EXA is a newer and
-simpler acceleration architecture designed to better accelerate the X Render
-extension.  Default: "XAA".
+XFree86 based acceleration architecture.  EXA is a newer and simpler
+acceleration architecture designed to better accelerate the X Render extension.
+Default: "EXA".
 .TP
 .BI "Option \*qModeDebug\*q \*q" boolean \*q
 Enable printing of additional debugging information about modesetting to
commit 177924e879564b7e9e70fd607141978bfd053fff
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Thu Nov 8 18:16:48 2007 -0800

    Bump driver version to 2.1.99 in preparation for 2.2 release

diff --git a/configure.ac b/configure.ac
index 1e6ffe0..b79aac8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-intel],
-        2.1.0,
+        2.1.99,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-intel)
 
commit cb4e5796f0537ea5e0e646d473930c7b826c85d8
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Thu Nov 8 18:13:47 2007 -0800

    Default to EXA
    
    If EXA is compiled into the driver, default to using it for acceleration.
    Hopefully we can remove XAA entirely one day.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index e8fe3b4..eacaefc 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1430,17 +1430,17 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
     * If either XAA or EXA (exclusive) is compiled in, default to it.
     * 
     * If both are compiled in, and the user didn't specify noAccel, use the
-    * config option AccelMethod to determine which to use, defaulting to XAA
+    * config option AccelMethod to determine which to use, defaulting to EXA
     * if none is specified, or if the string was unrecognized.
     *
     * All this *could* go away if we removed XAA support from this driver,
     * for example. :)
     */
    if (!pI830->noAccel) {
-#if (defined(I830_USE_EXA) && defined(I830_USE_XAA)) || !defined(I830_USE_EXA)
-       pI830->useEXA = FALSE;
-#else
+#ifdef I830_USE_EXA
        pI830->useEXA = TRUE;
+#else
+       pI830->useEXA = FALSE;
 #endif
 #if defined(I830_USE_XAA) && defined(I830_USE_EXA)
        int from = X_DEFAULT;
commit 43a59ab26b09fcc24de1ed7bd770bb622f899ceb
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Thu Nov 8 16:52:41 2007 -0800

    Clear current video crtc on DPMS off
    
    When calling the video DPMS off function, make sure we zero out the current
    crtc so that it will be properly re-set up next time video is turned on.
    
    Fix from Peter Clifton with changes by Keith Packard.

diff --git a/src/i830_video.c b/src/i830_video.c
index 73ae771..5325bbd 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2832,15 +2832,14 @@ i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on)
     if (crtc != pPriv->current_crtc)
 	return;
 
-    /* Check if it's the crtc the overlay is on */
-    if (on) {
-	i830_overlay_switch_to_crtc (pScrn, crtc);
-    } else {
+    /* Check if it's the crtc the overlay is off */
+    if (!on) {
 	/* We stop the video when mode switching, so we don't lock up
 	 * the engine. The overlayOK will determine whether we can re-enable
 	 * with the current video on completion of the mode switch.
 	 */
 	I830StopVideo(pScrn, pPriv, TRUE);
+	pPriv->current_crtc = NULL;
 	pPriv->overlayOK = FALSE;
 	pPriv->oneLineMode = FALSE;
     }
commit e784e152a8e84b6e447b55a5c7019e7b47e17621
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Thu Nov 8 16:37:53 2007 -0800

    Fix overlay destination clamping
    
    The overlay width & height scaling clamp check was reversed.  Fix that and
    update the comment.

diff --git a/src/i830_video.c b/src/i830_video.c
index 255444b..73ae771 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2216,11 +2216,11 @@ I830PutImage(ScrnInfoPtr pScrn,
 	pI830->entityPrivate->XvInUse = i830_crtc_pipe (pPriv->current_crtc);;
     }
 
-    /* overlay limits */
-    if(src_w > (drw_w * 7))
+    /* Clamp dst width & height to 7x of src (overlay limit) */
+    if(drw_w > (src_w * 7))
 	drw_w = src_w * 7;
 
-    if(src_h > (drw_h * 7))
+    if(drw_h > (src_h * 7))
 	drw_h = src_h * 7;
 
     /* Clip */
commit b8770f710729d616b3ac72544aa522161a78f819
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Thu Nov 8 16:19:01 2007 -0800

    Setup 3D state at EnterVT time
    
    In the absence of full suspend/resume support in the kernel, we have to
    save/restore state in Enter/LeaveVT.  For 8xx chips, 3D state may be lost
    during suspend/resume, so re-emit the basic setup at EnterVT time.
    
    Patch from Peter Clifton.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 53c7845..e8fe3b4 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3141,8 +3141,9 @@ I830EnterVT(int scrnIndex, int flags)
    if (pI830->checkDevices)
       pI830->devicesTimer = TimerSet(NULL, 0, 1000, I830CheckDevicesTimer, pScrn);
 
-   /* Mark 3D state as being clobbered */
+   /* Mark 3D state as being clobbered and setup the basics */
    *pI830->last_3d = LAST_3D_OTHER;
+   IntelEmitInvarientState(pScrn);
 
    return TRUE;
 }
commit 5f92b4c2db9712496b829ee239468e3d14e27d2f
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Nov 8 13:31:51 2007 -0800

    Bug #12059: Add ch7019 to the list of supported devices for ch7017.
    
    While I'm here, fix the chip description to be LVDS instead of TMDS in i2c
    device.

diff --git a/src/ch7017/ch7017.c b/src/ch7017/ch7017.c
index f8e2b31..6fc3422 100644
--- a/src/ch7017/ch7017.c
+++ b/src/ch7017/ch7017.c
@@ -99,7 +99,7 @@ ch7017_init(I2CBusPtr b, I2CSlaveAddr addr)
     if (priv == NULL)
 	return NULL;
 
-    priv->d.DevName = "CH7017/7018 TMDS Controller";
+    priv->d.DevName = "CH7017/7018/7019 LVDS Controller";
     priv->d.SlaveAddr = addr;
     priv->d.pI2CBus = b;
     priv->d.StartTimeout = b->StartTimeout;
@@ -111,9 +111,11 @@ ch7017_init(I2CBusPtr b, I2CSlaveAddr addr)
     if (!xf86I2CReadByte(&priv->d, CH7017_DEVICE_ID, &val))
 	goto fail;
 
-    if (val != CH7017_DEVICE_ID_VALUE && val != CH7018_DEVICE_ID_VALUE) {
+    if (val != CH7017_DEVICE_ID_VALUE &&
+	val != CH7018_DEVICE_ID_VALUE &&
+	val != CH7019_DEVICE_ID_VALUE) {
 	xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
-		   "ch7017 not detected, got %d: from %s Slave %d.\n",
+		   "ch701x not detected, got %d: from %s Slave %d.\n",
 		   val, priv->d.pI2CBus->BusName, priv->d.SlaveAddr);
 	goto fail;
     }
diff --git a/src/ch7017/ch7017_reg.h b/src/ch7017/ch7017_reg.h
index 3344c4e..7b536bd 100644
--- a/src/ch7017/ch7017_reg.h
+++ b/src/ch7017/ch7017_reg.h
@@ -69,6 +69,7 @@
 #define CH7017_DEVICE_ID		0x4b
 #define CH7017_DEVICE_ID_VALUE		0x1b
 #define CH7018_DEVICE_ID_VALUE		0x1a
+#define CH7019_DEVICE_ID_VALUE		0x19
 
 #define CH7017_XCLK_D2_ADJUST		0x53
 #define CH7017_UP_SCALER_COEFF_0	0x55
commit eecd3ccedee6c4acf101591f7e60673660379e62
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Thu Nov 8 09:31:08 2007 -0800

    Check DPLL status before writing PIPEnCONF regs
    
    If the DPLL isn't enabled or is in VGA mode, writing the PIPEnCONF registers
    may cause a hang or crash.  So ensure the DPLL is in the proper state before
    writing them.
    
    Another excellent fix from Peter Clifton.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 488232d..53c7845 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2052,7 +2052,13 @@ RestoreHWState(ScrnInfoPtr pScrn)
       OUTREG(DSPASURF, pI830->saveDSPASURF);
       OUTREG(DSPATILEOFF, pI830->saveDSPATILEOFF);
    }
-   OUTREG(PIPEACONF, pI830->savePIPEACONF);
+   /*
+    * Make sure the DPLL is active and not in VGA mode or the
+    * write of PIPEnCONF may cause a crash
+    */
+   if ((pI830->saveDPLL_B & DPLL_VCO_ENABLE) &&
+       (pI830->saveDPLL_B & DPLL_VGA_MODE_DIS))
+	   OUTREG(PIPEACONF, pI830->savePIPEACONF);
    i830WaitForVblank(pScrn);
    OUTREG(DSPACNTR, pI830->saveDSPACNTR);
    OUTREG(DSPABASE, INREG(DSPABASE));
@@ -2092,7 +2098,13 @@ RestoreHWState(ScrnInfoPtr pScrn)
 	 OUTREG(DSPBSURF, pI830->saveDSPBSURF);
 	 OUTREG(DSPBTILEOFF, pI830->saveDSPBTILEOFF);
       }
-      OUTREG(PIPEBCONF, pI830->savePIPEBCONF);
+
+      /*
+       * See PIPEnCONF note above
+       */
+      if ((pI830->saveDPLL_B & DPLL_VCO_ENABLE) &&
+	  (pI830->saveDPLL_B & DPLL_VGA_MODE_DIS))
+	      OUTREG(PIPEBCONF, pI830->savePIPEBCONF);
       i830WaitForVblank(pScrn);
       OUTREG(DSPBCNTR, pI830->saveDSPBCNTR);
       OUTREG(DSPBBASE, INREG(DSPBBASE));


More information about the xorg-commit mailing list