xf86-video-intel: 3 commits - src/i810_reg.h src/i830_display.c src/i830_exa.c src/i830.h src/i830_lvds.c src/i830_memory.c src/i830_reg.h

Jesse Barnes jbarnes at kemper.freedesktop.org
Fri Aug 3 20:45:41 PDT 2007


 src/i810_reg.h     |   12 ++
 src/i830.h         |    2 
 src/i830_display.c |  234 ++++++++++++++++++++++++++++-------------------------
 src/i830_exa.c     |   54 ++++++++++--
 src/i830_lvds.c    |   78 +++++++++++------
 src/i830_memory.c  |    5 -
 src/i830_reg.h     |    7 +
 7 files changed, 247 insertions(+), 145 deletions(-)

New commits:
diff-tree 019dbfda294aaafb28d8bea0fe2f5dadc2ea3e0b (from parents)
Merge: 3d3c0e8c55f639a501c0756948b518abd903d7d0 15f71edba37738f8ba279fa07452fda10cc65298
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Aug 3 20:45:14 2007 -0700

    Merge branch 'master' of ssh://git.freedesktop.org/git/xorg/driver/xf86-video-intel

diff-tree 3d3c0e8c55f639a501c0756948b518abd903d7d0 (from 0da4f2b0cd7203377ad10407928a367b8c6d310e)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Aug 3 20:40:45 2007 -0700

    Tiled rendering & fbc fixes:
      - actually enable tiling in DSP(A|B)CNTR if needed
      - add logic to EXA routines for tiled case (still needs work)
      - enable/disable fbc on DPMS events (meant moving functions higher in file)
      - fix fence register pitch programming (use correct pitch instead of kludged value)

diff --git a/src/i810_reg.h b/src/i810_reg.h
index d1fed22..03e10d6 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -2029,6 +2029,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define DSPBCNTR		0x71180
 #define DISPLAY_PLANE_ENABLE 			(1<<31)
 #define DISPLAY_PLANE_DISABLE			0
+#define DISPLAY_PLANE_TILED			(1<<10)
 #define DISPPLANE_GAMMA_ENABLE			(1<<30)
 #define DISPPLANE_GAMMA_DISABLE			0
 #define DISPPLANE_PIXFORMAT_MASK		(0xf<<26)
@@ -2168,12 +2169,15 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define XY_COLOR_BLT_CMD		((2<<29)|(0x50<<22)|(0x4))
 #define XY_COLOR_BLT_WRITE_ALPHA	(1<<21)
 #define XY_COLOR_BLT_WRITE_RGB		(1<<20)
+#define XY_COLOR_BLT_TILED		(1<<11)
 
 #define XY_SETUP_CLIP_BLT_CMD		((2<<29)|(3<<22)|1)
 
 #define XY_SRC_COPY_BLT_CMD		((2<<29)|(0x53<<22)|6)
 #define XY_SRC_COPY_BLT_WRITE_ALPHA	(1<<21)
 #define XY_SRC_COPY_BLT_WRITE_RGB	(1<<20)
+#define XY_SRC_COPY_BLT_SRC_TILED	(1<<15)
+#define XY_SRC_COPY_BLT_DST_TILED	(1<<11)
 
 #define SRC_COPY_BLT_CMD		((2<<29)|(0x43<<22)|0x4)
 #define SRC_COPY_BLT_WRITE_ALPHA	(1<<21)
diff --git a/src/i830.h b/src/i830.h
index a8de0e6..64a3690 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -407,6 +407,7 @@ typedef struct _I830Rec {
 #ifdef I830_USE_EXA
    unsigned int copy_src_pitch;
    unsigned int copy_src_off;
+   unsigned int copy_src_tiled;
    ExaDriverPtr	EXADriverPtr;
 #endif
 
diff --git a/src/i830_display.c b/src/i830_display.c
index 26873fe..6fe7be7 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -498,6 +498,123 @@ i830_pipe_a_require_deactivate (ScrnInfo
     return;
 }
 
+static Bool
+i830_use_fb_compression(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
+    int pipe = intel_crtc->pipe;
+    int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
+
+    if (!pI830->fb_compression)
+	return FALSE;
+
+    /* Pre-965 only supports plane A */
+    if (!IS_I965GM(pI830) && plane != FBC_CTL_PLANEA)
+	return FALSE;
+
+    /* Need 15, 16, or 32 (w/alpha) pixel format */
+    if (!(pScrn->bitsPerPixel == 16 || /* covers 15 bit mode as well */
+	  pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */
+	return FALSE;
+
+    /*
+     * No checks for pixel multiply, incl. horizontal, or interlaced modes
+     * since they're currently unused.
+     */
+    return TRUE;
+}
+
+/*
+ * Several restrictions:
+ *   - DSP[AB]CNTR - no line duplication && no pixel multiplier
+ *   - pixel format == 15 bit, 16 bit, or 32 bit xRGB_8888
+ *   - no alpha buffer discard
+ *   - no dual wide display
+ *   - progressive mode only (DSP[AB]CNTR)
+ *   - uncompressed fb is <= 2048 in width, 0 mod 8
+ *   - uncompressed fb is <= 1536 in height, 0 mod 2
+ *   - SR display watermarks must be equal between 16bpp and 32bpp?
+ *
+ * FIXME: verify above conditions are true
+ */
+static void
+i830_enable_fb_compression(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
+    uint32_t fbc_ctl = 0;
+    unsigned long compressed_stride;
+    int pipe = intel_crtc->pipe;
+    /* FIXME: plane & pipe might not always be equal */
+    int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
+    unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp;
+    unsigned long interval = 1000;
+
+    if (INREG(FBC_CONTROL) & FBC_CTL_EN) {
+	char cur_pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "fbc already enabled on "
+		   "pipe %c, not enabling on pipe %c\n", cur_pipe, pipe ? 'b' :
+		   'a');
+	return;
+    }
+
+    compressed_stride = pI830->compressed_front_buffer->size /
+	FBC_LL_SIZE;
+
+    if (uncompressed_stride < compressed_stride)
+	compressed_stride = uncompressed_stride;
+
+    /* FBC_CTL wants 64B units */
+    compressed_stride = (compressed_stride / 64) - 1;
+
+    /* Set it up... */
+    /* Wait for compressing bit to clear */
+    while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
+	; /* nothing */
+    i830WaitForVblank(pScrn);
+    OUTREG(FBC_CFB_BASE, pI830->compressed_front_buffer->bus_addr);
+    OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr + 6);
+    OUTREG(FBC_CONTROL2, FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_FULL |
+	   FBC_CTL_CPU_FENCE | plane);
+
+    /* Zero buffers */
+    memset(pI830->FbBase + pI830->compressed_front_buffer->offset, 0,
+	   pI830->compressed_front_buffer->size);
+    memset(pI830->FbBase + pI830->compressed_ll_buffer->offset, 0,
+	   pI830->compressed_ll_buffer->size);
+
+    /* enable it... */
+    fbc_ctl |= FBC_CTL_EN | FBC_CTL_PERIODIC;
+    fbc_ctl |= (compressed_stride & 0xff) << FBC_CTL_STRIDE_SHIFT;
+    fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
+    fbc_ctl |= FBC_CTL_UNCOMPRESSIBLE;
+    OUTREG(FBC_CONTROL, fbc_ctl);
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on plane %c\n", pipe ?
+	       'b' : 'a');
+}
+
+static void
+i830_disable_fb_compression(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    uint32_t fbc_ctl;
+    char pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
+
+    /* Disable compression */
+    fbc_ctl = INREG(FBC_CONTROL);
+    fbc_ctl &= ~FBC_CTL_EN;
+    OUTREG(FBC_CONTROL, fbc_ctl);
+
+    /* 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", pipe);
+}
 
 /**
  * Sets the power management mode of the pipe and plane.
@@ -561,8 +678,16 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mod
 
 	/* Give the overlay scaler a chance to enable if it's on this pipe */
 	i830_crtc_dpms_video(crtc, TRUE);
+
+	/* Reenable compression if needed */
+	if (i830_use_fb_compression(crtc))
+	    i830_enable_fb_compression(crtc);
 	break;
     case DPMSModeOff:
+	/* Shut off compression if in use */
+	if (i830_use_fb_compression(crtc))
+	    i830_disable_fb_compression(crtc);
+
 	/* Give the overlay scaler a chance to disable if it's on this pipe */
 	i830_crtc_dpms_video(crtc, FALSE);
 
@@ -656,112 +781,6 @@ i830_crtc_unlock (xf86CrtcPtr crtc)
 #endif
 }
 
-static Bool
-i830_use_fb_compression(xf86CrtcPtr crtc)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-    I830Ptr pI830 = I830PTR(pScrn);
-    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
-    int pipe = intel_crtc->pipe;
-    int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
-
-    if (!pI830->fb_compression)
-	return FALSE;
-
-    /* Pre-965 only supports plane A */
-    if (!IS_I965GM(pI830) && plane != FBC_CTL_PLANEA)
-	return FALSE;
-
-    /* Need 15, 16, or 32 (w/alpha) pixel format */
-    if (!(pScrn->bitsPerPixel == 16 || /* covers 15 bit mode as well */
-	  pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */
-	return FALSE;
-
-    /*
-     * No checks for pixel multiply, incl. horizontal, or interlaced modes
-     * since they're currently unused.
-     */
-    return TRUE;
-}
-
-/*
- * Several restrictions:
- *   - DSP[AB]CNTR - no line duplication && no pixel multiplier
- *   - pixel format == 15 bit, 16 bit, or 32 bit xRGB_8888
- *   - no alpha buffer discard
- *   - no dual wide display
- *   - progressive mode only (DSP[AB]CNTR)
- *   - uncompressed fb is <= 2048 in width, 0 mod 8
- *   - uncompressed fb is <= 1536 in height, 0 mod 2
- *   - SR display watermarks must be equal between 16bpp and 32bpp?
- *
- * FIXME: verify above conditions are true
- */
-static void
-i830_enable_fb_compression(xf86CrtcPtr crtc)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-    I830Ptr pI830 = I830PTR(pScrn);
-    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
-    uint32_t fbc_ctl;
-    unsigned long compressed_stride;
-    int pipe = intel_crtc->pipe;
-    int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
-    unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp;
-    unsigned long interval = 1000;
-
-    if (INREG(FBC_CONTROL) & FBC_CTL_EN) {
-	char cur_pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
-	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "fbc already enabled on "
-		   "pipe %c, not enabling on pipe %c\n", cur_pipe, pipe ? 'b' :
-		   'a');
-	return;
-    }
-
-    compressed_stride = pI830->compressed_front_buffer->size /
-	FBC_LL_SIZE;
-
-    if (uncompressed_stride < compressed_stride)
-	compressed_stride = uncompressed_stride;
-
-    /* FBC_CTL wants 64B units */
-    compressed_stride = (compressed_stride / 64) - 1;
-
-    /* Set it up... */
-    OUTREG(FBC_CFB_BASE, pI830->compressed_front_buffer->bus_addr);
-    OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr + FBC_LL_PAD);
-    OUTREG(FBC_CONTROL2, FBC_CTL_CPU_FENCE | plane);
-
-    /* enable it... */
-    fbc_ctl = INREG(FBC_CONTROL);
-    fbc_ctl |= FBC_CTL_EN | FBC_CTL_PERIODIC;
-    fbc_ctl |= (compressed_stride & 0xff) << FBC_CTL_STRIDE_SHIFT;
-    fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
-    OUTREG(FBC_CONTROL, fbc_ctl);
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on pipe %c\n", pipe ?
-	       'b' : 'a');
-}
-
-static void
-i830_disable_fb_compression(xf86CrtcPtr crtc)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-    I830Ptr pI830 = I830PTR(pScrn);
-    uint32_t fbc_ctl;
-    char pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
-
-    /* Disable compression */
-    fbc_ctl = INREG(FBC_CONTROL);
-    fbc_ctl &= ~FBC_CTL_EN;
-    OUTREG(FBC_CONTROL, fbc_ctl);
-
-    /* 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", pipe);
-}
-
 static void
 i830_crtc_prepare (xf86CrtcPtr crtc)
 {
@@ -1059,6 +1078,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
     else
 	dspcntr |= DISPPLANE_SEL_PIPE_B;
 
+    if (pI830->tiling)
+	dspcntr |= DISPLAY_PLANE_TILED;
+
     pipeconf = INREG(pipeconf_reg);
     if (pipe == 0 && !IS_I965G(pI830))
     {
diff --git a/src/i830_exa.c b/src/i830_exa.c
index fed4067..5da153e 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -97,6 +97,16 @@ const int I830PatternROP[16] =
     ROP_1
 };
 
+static Bool
+exaPixmapInFrontbuffer(PixmapPtr p)
+{
+    ScreenPtr pScreen = p->drawable.pScreen;
+
+    if (p == pScreen->GetScreenPixmap(pScreen))
+	return TRUE;
+    return FALSE;
+}
+
 /**
  * I830EXASync - wait for a command to finish
  * @pScreen: current screen
@@ -162,16 +172,26 @@ I830EXASolid(PixmapPtr pPixmap, int x1, 
     ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
     unsigned long offset;
+    uint32_t cmd;
 
     offset = exaGetPixmapOffset(pPixmap);  
     
     {
 	BEGIN_LP_RING(6);
+
+	cmd = XY_COLOR_BLT_CMD;
+
 	if (pPixmap->drawable.bitsPerPixel == 32)
-	    OUT_RING(XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA
-			| XY_COLOR_BLT_WRITE_RGB);
-	else
-	    OUT_RING(XY_COLOR_BLT_CMD);
+	    cmd |= XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB;
+
+	if (pI830->tiling && exaPixmapInFrontbuffer(pPixmap)) {
+	    /* Fixup pitch for destination if tiled */
+	    pI830->BR[13] = (ROUND_TO(pI830->BR[13] & 0xffff, 512) >> 2) | 
+		(pI830->BR[13] & 0xffff0000);
+	    cmd |= XY_COLOR_BLT_TILED;
+	}
+
+	OUT_RING(cmd);
 
 	OUT_RING(pI830->BR[13]);
 	OUT_RING((y1 << 16) | (x1 & 0xffff));
@@ -208,6 +228,8 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap,
 
     pI830->copy_src_pitch = exaGetPixmapPitch(pSrcPixmap);
     pI830->copy_src_off = exaGetPixmapOffset(pSrcPixmap);
+    pI830->copy_src_tiled = (pI830->tiling &&
+			     exaPixmapInFrontbuffer(pSrcPixmap));
 
     pI830->BR[13] = exaGetPixmapPitch(pDstPixmap);
     pI830->BR[13] |= I830CopyROP[alu] << 16;
@@ -231,6 +253,7 @@ I830EXACopy(PixmapPtr pDstPixmap, int sr
 {
     ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
+    uint32_t cmd;
     int dst_x2, dst_y2;
     unsigned int dst_off;
 
@@ -242,11 +265,26 @@ I830EXACopy(PixmapPtr pDstPixmap, int sr
     {
 	BEGIN_LP_RING(8);
 
+	cmd = XY_SRC_COPY_BLT_CMD;
+
 	if (pDstPixmap->drawable.bitsPerPixel == 32)
-	    OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
-		     XY_SRC_COPY_BLT_WRITE_RGB);
-	else
-	    OUT_RING(XY_SRC_COPY_BLT_CMD);
+	    cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB;
+
+	if (pI830->tiling && exaPixmapInFrontbuffer(pDstPixmap)) {
+	    /* Fixup pitch for destination if tiled */
+	    pI830->BR[13] = (ROUND_TO(pI830->BR[13] & 0xffff, 512) >> 2) | 
+		(pI830->BR[13] & 0xffff0000);
+	    cmd |= XY_SRC_COPY_BLT_DST_TILED;
+	}
+
+	if (pI830->copy_src_tiled) {
+	    pI830->copy_src_pitch =
+		(ROUND_TO(pI830->copy_src_pitch & 0xffff, 512) >> 2) | 
+		(pI830->copy_src_pitch & 0xffff0000);
+	    cmd |= XY_SRC_COPY_BLT_SRC_TILED;
+	}
+
+	OUT_RING(cmd);
 
 	OUT_RING(pI830->BR[13]);
 	OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff));
diff --git a/src/i830_memory.c b/src/i830_memory.c
index b38a5df..ccd26b3 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1453,11 +1453,6 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr
     assert(tile_format != TILING_NONE);
 
     if (IS_I965G(pI830)) {
-        if (tile_format == TILING_XMAJOR)
-            pitch = 512;
-        else
-            pitch = 128;
- 
 	if (nr < 0 || nr >= FENCE_NEW_NR) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		       "i830_set_fence(): fence %d out of range\n",nr);
diff --git a/src/i830_reg.h b/src/i830_reg.h
index 8a2a98a..df22ed4 100644
--- a/src/i830_reg.h
+++ b/src/i830_reg.h
@@ -36,6 +36,7 @@
 #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
@@ -46,9 +47,15 @@
 #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_LL_SIZE		(1536)
 #define FBC_LL_PAD		(32)
diff-tree 0da4f2b0cd7203377ad10407928a367b8c6d310e (from f403a50afbcef1e54f554481c72037338bd5357c)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Tue Jul 31 16:22:36 2007 -0700

    Legacy backlight changes:
      - add support for 965GM
      - make sure legacy enabled systems don't reduce the range of backlight values we can present to the user

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 248df04..d1fed22 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -822,6 +822,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 # define PP_SEQUENCE_MASK			0x30000000
 
 #define PP_CONTROL	0x61204
+# define POWER_DOWN_ON_RESET			(1 << 1)
 # define POWER_TARGET_ON			(1 << 0)
 
 #define LVDSPP_ON       0x61208
@@ -1066,6 +1067,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
 #define BLC_PWM_CTL		0x61254
 #define BACKLIGHT_MODULATION_FREQ_SHIFT		(17)
+#define BACKLIGHT_MODULATION_FREQ_SHIFT2	(16)
 /**
  * This is the most significant 15 bits of the number of backlight cycles in a
  * complete cycle of the modulated backlight control.
@@ -1073,7 +1075,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * The actual value is this field multiplied by two.
  */
 #define BACKLIGHT_MODULATION_FREQ_MASK		(0x7fff << 17)
+#define BACKLIGHT_MODULATION_FREQ_MASK2		(0xffff << 16)
 #define BLM_LEGACY_MODE				(1 << 16)
+
 /**
  * This is the number of cycles out of the backlight modulation cycle for which
  * the backlight is on.
@@ -1084,6 +1088,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define BACKLIGHT_DUTY_CYCLE_SHIFT		(0)
 #define BACKLIGHT_DUTY_CYCLE_MASK		(0xffff)
 
+/* On 965+ backlight control is in another register */
+#define BLC_PWM_CTL2			0x61250
+#define 	BLM_LEGACY_MODE2	(1 << 30)
+
 #define BLM_CTL			0x61260
 #define BLM_THRESHOLD_0		0x61270
 #define BLM_THRESHOLD_1		0x61274
diff --git a/src/i830.h b/src/i830.h
index bf072a1..a8de0e6 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -532,6 +532,7 @@ typedef struct _I830Rec {
    CARD32 savePaletteB[256];
    CARD32 saveSWF[17];
    CARD32 saveBLC_PWM_CTL;
+   CARD32 saveBLC_PWM_CTL2;
    CARD32 saveFBC_CFB_BASE;
    CARD32 saveFBC_LL_BASE;
    CARD32 saveFBC_CONTROL2;
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 246008b..18e5c2b 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -46,6 +46,30 @@ struct i830_lvds_priv {
     int		    backlight_duty_cycle;
 };
 
+/**
+ * Use legacy backlight controls?
+ *
+ * \param pI830 device in question
+ *
+ * Returns TRUE if legacy backlight should be used, false otherwise.
+ */
+static int
+i830_lvds_backlight_legacy(I830Ptr pI830)
+{
+    CARD32 blc_pwm_ctl, blc_pwm_ctl2;
+
+    /* 965GM+ change the location of the legacy control bit */
+    if (IS_I965GM(pI830)) {
+	blc_pwm_ctl2 = INREG(BLC_PWM_CTL2);
+	if (blc_pwm_ctl2 & BLM_LEGACY_MODE2)
+	    return TRUE;
+    } else {
+	blc_pwm_ctl = INREG(BLC_PWM_CTL);
+	if (blc_pwm_ctl & BLM_LEGACY_MODE)
+	    return TRUE;
+    }
+    return FALSE;
+}
 
 /**
  * Sets the backlight level.
@@ -59,18 +83,12 @@ i830_lvds_set_backlight(xf86OutputPtr ou
     I830Ptr pI830 = I830PTR(pScrn);
     CARD32 blc_pwm_ctl;
 
+    if (i830_lvds_backlight_legacy(pI830))
+	pciWriteByte(pI830->PciTag, LEGACY_BACKLIGHT_BRIGHTNESS, 0xfe);
+
     blc_pwm_ctl = INREG(BLC_PWM_CTL);
-    if (blc_pwm_ctl & BLM_LEGACY_MODE)
-    {
-	pciWriteByte (pI830->PciTag, 
-		      LEGACY_BACKLIGHT_BRIGHTNESS,
-		      level & 0xff);
-    }
-    else
-    {
-	blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
-	OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
-    }
+    blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
+    OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
 }
 
 /**
@@ -82,12 +100,24 @@ i830_lvds_get_max_backlight(xf86OutputPt
     ScrnInfoPtr pScrn = output->scrn;
     I830Ptr	pI830 = I830PTR(pScrn);
     CARD32	pwm_ctl = INREG(BLC_PWM_CTL);
+    CARD32	val;
+
+    if (IS_I965GM(pI830)) {
+	val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK2) >>
+	       BACKLIGHT_MODULATION_FREQ_SHIFT2);
+    } else {
+	val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >>
+	       BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
+    }
     
-    if (pwm_ctl & BLM_LEGACY_MODE)
-	return 0xff;
-    else
-	return ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >>
-		BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
+    /*
+     * 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]
+     */
+    return val;
 }
 
 /**
@@ -138,21 +168,15 @@ i830_lvds_save (xf86OutputPtr output)
     ScrnInfoPtr		    pScrn = output->scrn;
     I830Ptr		    pI830 = I830PTR(pScrn);
 
+    if (IS_I965GM(pI830))
+	pI830->saveBLC_PWM_CTL2 = INREG(BLC_PWM_CTL2);
     pI830->savePP_ON = INREG(LVDSPP_ON);
     pI830->savePP_OFF = INREG(LVDSPP_OFF);
     pI830->savePP_CONTROL = INREG(PP_CONTROL);
     pI830->savePP_CYCLE = INREG(PP_CYCLE);
     pI830->saveBLC_PWM_CTL = INREG(BLC_PWM_CTL);
-    if (pI830->saveBLC_PWM_CTL & BLM_LEGACY_MODE)
-    {
-	dev_priv->backlight_duty_cycle = pciReadByte (pI830->PciTag,
-						      LEGACY_BACKLIGHT_BRIGHTNESS);
-    }
-    else
-    {
-	dev_priv->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL &
-					  BACKLIGHT_DUTY_CYCLE_MASK);
-    }
+    dev_priv->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL &
+				      BACKLIGHT_DUTY_CYCLE_MASK);
 
     /*
      * If the light is off at server startup, just make it full brightness
@@ -167,6 +191,8 @@ i830_lvds_restore(xf86OutputPtr output)
     ScrnInfoPtr	pScrn = output->scrn;
     I830Ptr	pI830 = I830PTR(pScrn);
 
+    if (IS_I965GM(pI830))
+	OUTREG(BLC_PWM_CTL2, pI830->saveBLC_PWM_CTL2);
     OUTREG(BLC_PWM_CTL, pI830->saveBLC_PWM_CTL);
     OUTREG(LVDSPP_ON, pI830->savePP_ON);
     OUTREG(LVDSPP_OFF, pI830->savePP_OFF);


More information about the xorg-commit mailing list