xf86-video-intel: 3 commits - src/common.h src/i810_reg.h src/i830_display.c src/i830_dri.c src/i830_driver.c src/i830.h src/i830_memory.c

Zhenyu Wang zhen at kemper.freedesktop.org
Tue Jan 29 19:14:36 PST 2008


 src/common.h       |    2 +
 src/i810_reg.h     |   24 ++++++++++++
 src/i830.h         |    4 +-
 src/i830_display.c |   89 +++++++++++++++++++++++++++++++++++++++++++++-
 src/i830_dri.c     |  101 ++++++++++++++++++-----------------------------------
 src/i830_driver.c  |   16 ++++++++
 src/i830_memory.c  |   53 ++++++++++++++++++---------
 7 files changed, 202 insertions(+), 87 deletions(-)

New commits:
commit 2e43bec8731ba1b172f7a0bf867bbb5c1adbda2d
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Wed Jan 30 18:59:12 2008 +0800

    Frame buffer compression support on new chipset

diff --git a/src/i810_reg.h b/src/i810_reg.h
index bed3901..7902366 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -2634,4 +2634,28 @@ typedef enum {
 #define FBC_LL_SIZE		(1536)
 #define FBC_LL_PAD		(32)
 
+/* Framebuffer compression version 2 */
+#define DPFC_CB_BASE		0x3200
+#define DPFC_CONTROL		0x3208
+#define   DPFC_CTL_EN		(1<<31)
+#define   DPFC_CTL_PLANEA	(0<<30)
+#define   DPFC_CTL_PLANEB	(1<<30)
+#define   DPFC_CTL_FENCE_EN	(1<<29)
+#define   DPFC_CTL_LIMIT_1X	(0<<6)
+#define   DPFC_CTL_LIMIT_2X	(1<<6)
+#define   DPFC_CTL_LIMIT_4X	(2<<6)
+#define DPFC_RECOMP_CTL		0x320c
+#define   DPFC_RECOMP_STALL_EN	(1<<27)
+#define   DPFC_RECOMP_STALL_WM_SHIFT (16)
+#define   DPFC_RECOMP_STALL_WM_MASK (0x07ff0000)
+#define   DPFC_RECOMP_TIMER_COUNT_SHIFT (0)
+#define   DPFC_RECOMP_TIMER_COUNT_MASK (0x0000003f)
+#define DPFC_STATUS		0x3210
+#define   DPFC_INVAL_SEG_SHIFT  (16)
+#define   DPFC_INVAL_SEG_MASK	(0x07ff0000)
+#define   DPFC_COMP_SEG_SHIFT	(0)
+#define   DPFC_COMP_SEG_MASK	(0x000003ff)
+#define DPFC_STATUS2		0x3214
+#define DPFC_FENCE_YOFF		0x3218
+
 #endif /* _I810_REG_H */
diff --git a/src/i830_display.c b/src/i830_display.c
index f61d3c4..39f3637 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -571,9 +571,11 @@ i830_use_fb_compression(xf86CrtcPtr crtc)
  *   - SR display watermarks must be equal between 16bpp and 32bpp?
  *
  * FIXME: verify above conditions are true
+ *
+ * Enable 8xx style FB compression
  */
 static void
-i830_enable_fb_compression(xf86CrtcPtr crtc)
+i830_enable_fb_compression_8xx(xf86CrtcPtr crtc)
 {
     ScrnInfoPtr pScrn = crtc->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
@@ -629,8 +631,11 @@ i830_enable_fb_compression(xf86CrtcPtr crtc)
 	       'b' : 'a');
 }
 
+/*
+ * Disable 8xx style FB compression
+ */
 static void
-i830_disable_fb_compression(xf86CrtcPtr crtc)
+i830_disable_fb_compression_8xx(xf86CrtcPtr crtc)
 {
     ScrnInfoPtr pScrn = crtc->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
@@ -648,6 +653,86 @@ i830_disable_fb_compression(xf86CrtcPtr crtc)
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on plane %c\n", plane);
 }
 
+static void
+i830_disable_fb_compression2(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    uint32_t dpfc_ctl;
+    char plane = (INREG(DPFC_CONTROL) & DPFC_CTL_PLANEB) ? 'b' : 'a';
+
+    /* Disable compression */
+    dpfc_ctl = INREG(DPFC_CONTROL);
+    dpfc_ctl &= ~DPFC_CTL_EN;
+    OUTREG(DPFC_CONTROL, dpfc_ctl);
+    i830WaitForVblank(pScrn);
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc2 disabled on plane %c\n", plane);
+}
+
+static void
+i830_enable_fb_compression2(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
+    int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB);
+    unsigned long stall_watermark = 200, frames = 50;
+
+    if (INREG(DPFC_CONTROL) & DPFC_CTL_EN) {
+	char cur_plane = (INREG(DPFC_CONTROL) & DPFC_CTL_PLANEB) ? 'b' : 'a';
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "fbc2 already enabled on "
+		   "plane %c, not enabling on plane %c\n", cur_plane,
+		   plane ? 'b' : 'a');
+	return;
+    }
+
+    /* Set it up... */
+    i830_disable_fb_compression2(crtc);
+    OUTREG(DPFC_CB_BASE, pI830->compressed_front_buffer->offset);
+    /* Update i830_memory.c too if compression ratio changes */
+    OUTREG(DPFC_CONTROL, plane | DPFC_CTL_FENCE_EN | DPFC_CTL_LIMIT_4X |
+	   pI830->front_buffer->fence_nr);
+    OUTREG(DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN |
+	   (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) |
+	   (frames << DPFC_RECOMP_TIMER_COUNT_SHIFT));
+    OUTREG(DPFC_FENCE_YOFF, crtc->y);
+
+    /* Zero buffers */
+    memset(pI830->FbBase + pI830->compressed_front_buffer->offset, 0,
+	   pI830->compressed_front_buffer->size);
+
+    /* enable it... */
+    OUTREG(DPFC_CONTROL, INREG(DPFC_CONTROL) | DPFC_CTL_EN);
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc2 enabled on plane %c\n", plane ?
+	       'b' : 'a');
+}
+
+static void
+i830_enable_fb_compression(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (IS_IGD_GM(pI830))
+	return i830_enable_fb_compression2(crtc);
+
+    i830_enable_fb_compression_8xx(crtc);
+}
+
+static void
+i830_disable_fb_compression(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (IS_IGD_GM(pI830))
+	return i830_disable_fb_compression2(crtc);
+
+    i830_disable_fb_compression_8xx(crtc);
+}
+
 /**
  * Sets the power management mode of the pipe and plane.
  *
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 07e4010..d97ca0b 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1274,6 +1274,13 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn)
 static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
+    unsigned long compressed_size;
+    unsigned long fb_height;
+
+    if (pScrn->virtualX > pScrn->virtualY)
+	fb_height = pScrn->virtualX;
+    else
+	fb_height = pScrn->virtualY;
 
     /* Only mobile chips since 845 support this feature */
     if (!IS_MOBILE(pI830)) {
@@ -1281,11 +1288,12 @@ static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
 	goto out;
     }
 
-    /* Clear out any stale state */
-    OUTREG(FBC_CFB_BASE, 0);
-    OUTREG(FBC_LL_BASE, 0);
-    OUTREG(FBC_CONTROL2, 0);
-    OUTREG(FBC_CONTROL, 0);
+    if (IS_IGD_GM(pI830)) {
+	/* Update i830_display.c too if compression ratio changes */
+	compressed_size = fb_height * (pScrn->displayWidth / 4);
+    } else {
+	compressed_size = MB(6);
+    }
 
     /*
      * Compressed framebuffer limitations:
@@ -1300,21 +1308,23 @@ static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
      */
     pI830->compressed_front_buffer =
 	i830_allocate_memory(pScrn, "compressed frame buffer",
-			     MB(6), KB(4), NEED_PHYSICAL_ADDR);
+			     compressed_size, KB(4), NEED_PHYSICAL_ADDR);
 
     if (!pI830->compressed_front_buffer) {
 	pI830->fb_compression = FALSE;
 	goto out;
     }
 
-    pI830->compressed_ll_buffer =
-	i830_allocate_memory(pScrn, "compressed ll buffer",
-			     FBC_LL_SIZE + FBC_LL_PAD, KB(4),
-			     NEED_PHYSICAL_ADDR);
-    if (!pI830->compressed_ll_buffer) {
-	i830_free_memory(pScrn, pI830->compressed_front_buffer);
-	pI830->fb_compression = FALSE;
-	goto out;
+    if (!IS_IGD_GM(pI830)) {
+	pI830->compressed_ll_buffer =
+	    i830_allocate_memory(pScrn, "compressed ll buffer",
+				 FBC_LL_SIZE + FBC_LL_PAD, KB(4),
+				 NEED_PHYSICAL_ADDR);
+	if (!pI830->compressed_ll_buffer) {
+	    i830_free_memory(pScrn, pI830->compressed_front_buffer);
+	    pI830->fb_compression = FALSE;
+	    goto out;
+	}
     }
 
 out:
commit bf629466a46c4037ec7b7cc5ee16be947618bd68
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Jan 30 18:55:20 2008 +0800

    hardware status page initialization rework
    
    Order hardware status page setup more reasonable after
    all memory bound, in case new chipset requires non-stolen
    page and that could be bound then.
    
    Also clean up drm irq handler install function, and put
    first install in starting stage later than status page setup,
    so we won't make device cry for uninitialized status page.

diff --git a/src/i830.h b/src/i830.h
index 9adbaf7..e55e110 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -695,7 +695,9 @@ extern Bool I830DRIFinishScreenInit(ScreenPtr pScreen);
 extern void I830DRIUnlock(ScrnInfoPtr pScrn);
 extern Bool I830DRILock(ScrnInfoPtr pScrn);
 extern Bool I830DRISetVBlankInterrupt (ScrnInfoPtr pScrn, Bool on);
-Bool i830_update_dri_buffers(ScrnInfoPtr pScrn);
+extern Bool i830_update_dri_buffers(ScrnInfoPtr pScrn);
+extern Bool I830DRISetHWS(ScrnInfoPtr pScrn);
+extern Bool I830DRIInstIrqHandler(ScrnInfoPtr pScrn);
 #endif
 
 unsigned long intel_get_pixmap_offset(PixmapPtr pPix);
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 3400b38..141b970 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -236,18 +236,18 @@ I830SetParam(ScrnInfoPtr pScrn, int param, int value)
    return TRUE;
 }
 
-static Bool
-I830SetHWS(ScrnInfoPtr pScrn, int addr)
+Bool
+I830DRISetHWS(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     drmI830HWS hws;
 
-    hws.addr = addr;
+    hws.addr = pI830->hw_status->offset;
 
     if (drmCommandWrite(pI830->drmSubFD, DRM_I830_HWS_PAGE_ADDR,
 		&hws, sizeof(drmI830HWS))) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		"G33 status page initialization Failed\n");
+		"hw status page initialization Failed\n");
 	return FALSE;
     }
     return TRUE;
@@ -813,12 +813,6 @@ I830DRIDoMappings(ScreenPtr pScreen)
       return FALSE;
    }
 
-   if (HWS_NEED_GFX(pI830)) {
-       if (!I830SetHWS(pScrn, pI830->hw_status->offset)) {
-	   DRICloseScreen(pScreen);
-	   return FALSE;
-       }
-   }
    /* init to zero to be safe */
    sarea->front_handle = 0;
    sarea->back_handle = 0;
@@ -881,18 +875,12 @@ I830DRIDoMappings(ScreenPtr pScreen)
 }
 
 Bool
-I830DRIResume(ScreenPtr pScreen)
+I830DRIInstIrqHandler(ScrnInfoPtr pScrn)
 {
-   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    I830Ptr pI830 = I830PTR(pScrn);
    I830DRIPtr pI830DRI = (I830DRIPtr) pI830->pDRIInfo->devPrivate;
 
-   DPRINTF(PFX, "I830DRIResume\n");
-
-   I830ResumeDma(pScrn);
-
-   {
-      pI830DRI->irq = drmGetInterruptFromBusID(pI830->drmSubFD,
+   pI830DRI->irq = drmGetInterruptFromBusID(pI830->drmSubFD,
 #if XSERVER_LIBPCIACCESS
 					       ((pI830->PciInfo->domain << 8) |
 						pI830->PciInfo->bus),
@@ -908,19 +896,31 @@ I830DRIResume(ScreenPtr pScreen)
 #endif
 					       );
 
-      if (drmCtlInstHandler(pI830->drmSubFD, pI830DRI->irq)) {
-	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		    "[drm] failure adding irq handler\n");
-	 pI830DRI->irq = 0;
-	 return FALSE;
-      }
-      else
-	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		    "[drm] dma control initialized, using IRQ %d\n",
-		    pI830DRI->irq);
-   }
+   if (drmCtlInstHandler(pI830->drmSubFD, pI830DRI->irq)) {
+       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+	       "[drm] failure adding irq handler\n");
+       pI830DRI->irq = 0;
+       return FALSE;
+   } else
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "[drm] dma control initialized, using IRQ %d\n",
+	       pI830DRI->irq);
 
-   return FALSE;
+   return TRUE;
+}
+
+Bool
+I830DRIResume(ScreenPtr pScreen)
+{
+   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+   DPRINTF(PFX, "I830DRIResume\n");
+
+   I830ResumeDma(pScrn);
+
+   I830DRIInstIrqHandler(pScrn);
+
+   return TRUE;
 }
 
 void
@@ -976,47 +976,16 @@ I830DestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
 Bool
 I830DRIFinishScreenInit(ScreenPtr pScreen)
 {
-   ScrnInfoPtr        pScrn = xf86Screens[pScreen->myNum];
-   I830Ptr pI830 = I830PTR(pScrn);
-
    DPRINTF(PFX, "I830DRIFinishScreenInit\n");
 
    if (!DRIFinishScreenInit(pScreen))
       return FALSE;
 
-   /* Okay now initialize the dma engine */
-   {
-      I830DRIPtr pI830DRI = (I830DRIPtr) pI830->pDRIInfo->devPrivate;
-
-      pI830DRI->irq = drmGetInterruptFromBusID(pI830->drmSubFD,
-#if XSERVER_LIBPCIACCESS
-					       ((pI830->PciInfo->domain << 8) |
-						pI830->PciInfo->bus),
-					       pI830->PciInfo->dev,
-					       pI830->PciInfo->func
-#else
-					       ((pciConfigPtr) pI830->
-						PciInfo->thisCard)->busnum,
-					       ((pciConfigPtr) pI830->
-						PciInfo->thisCard)->devnum,
-					       ((pciConfigPtr) pI830->
-						PciInfo->thisCard)->funcnum
-#endif
-					       );
-
-      if (drmCtlInstHandler(pI830->drmSubFD, pI830DRI->irq)) {
-	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		    "[drm] failure adding irq handler\n");
-	 pI830DRI->irq = 0;
-	 DRICloseScreen(pScreen);
-	 return FALSE;
-      }
-      else
-	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		    "[drm] dma control initialized, using IRQ %d\n",
-		    pI830DRI->irq);
-	 return TRUE;
-   }
+   /* move irq initialize later in EnterVT, as then we
+    * would finish binding possible hw status page, which
+    * requires irq ctrl ioctl not be called that early.
+    */
+   return TRUE;
 }
 
 #ifdef DAMAGE
diff --git a/src/i830_driver.c b/src/i830_driver.c
index dffc630..a3c64de 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3184,6 +3184,22 @@ I830EnterVT(int scrnIndex, int flags)
 
 #ifdef XF86DRI
    if (pI830->directRenderingEnabled) {
+       /* HW status is fixed, we need to set it up before any drm
+	* operation which accessing that page, like irq install, etc.
+	*/
+       if (pI830->starting) {
+	   if (HWS_NEED_GFX(pI830) && !I830DRISetHWS(pScrn)) {
+		   xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "Fail to setup hardware status page.\n");
+		   I830DRICloseScreen(pScrn->pScreen);
+		   return FALSE;
+	   }
+	   if (!I830DRIInstIrqHandler(pScrn)) {
+	       I830DRICloseScreen(pScrn->pScreen);
+	       return FALSE;
+	   }
+       }
+
       /* Update buffer offsets in sarea and mappings, since buffer offsets
        * may have changed.
        */
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 8a5262f..07e4010 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -468,6 +468,9 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
 	/* Can't do TTM on stolen memory */
 	mmsize -= pI830->stolen_size;
 
+	if (HWS_NEED_GFX(pI830) && IS_IGD_GM(pI830))
+	    mmsize -= HWSTATUS_PAGE_SIZE;
+
 	/* Create the aperture allocation */
 	pI830->memory_manager =
 	    i830_allocate_aperture(pScrn, "DRI memory manager",
@@ -1630,13 +1633,17 @@ static Bool
 i830_allocate_hwstatus(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
+    int flags;
 
     /* The current DRM will leak the HWS mapping if we update the address
      * after init (at best), so allocate it fixed for its lifetime
      * (i.e. not through buffer objects).
      */
+    flags = NEED_LIFETIME_FIXED;
+    if (IS_IGD_GM(pI830))
+	    flags |= NEED_NON_STOLEN;
     pI830->hw_status = i830_allocate_memory(pScrn, "HW status",
-	    HWSTATUS_PAGE_SIZE, GTT_PAGE_SIZE, NEED_LIFETIME_FIXED);
+	    HWSTATUS_PAGE_SIZE, GTT_PAGE_SIZE, flags);
     if (pI830->hw_status == NULL) {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		"Failed to allocate hw status page.\n");
commit 04032dad28baab80131edbe8fe58aade8149bb71
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Jan 30 18:52:32 2008 +0800

    Wrap up chipsets which needs graphics address for status page
    
    Also add support on new chipset.

diff --git a/src/common.h b/src/common.h
index 3a11e59..c0af1ad 100644
--- a/src/common.h
+++ b/src/common.h
@@ -441,6 +441,8 @@ extern int I810_DEBUG;
 #define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810) || IS_IGD_GM(pI810))
 /* mark chipsets for using gfx VM offset for overlay */
 #define OVERLAY_NOPHYSICAL(pI810) (IS_G33CLASS(pI810))
+/* chipsets require graphics mem for hardware status page */
+#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_IGD_GM(pI810))
 
 #define GTT_PAGE_SIZE			KB(4)
 #define ROUND_TO(x, y)			(((x) + (y) - 1) / (y) * (y))
diff --git a/src/i830_dri.c b/src/i830_dri.c
index f52a7c3..3400b38 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -813,7 +813,7 @@ I830DRIDoMappings(ScreenPtr pScreen)
       return FALSE;
    }
 
-   if (IS_G33CLASS(pI830)) {
+   if (HWS_NEED_GFX(pI830)) {
        if (!I830SetHWS(pScrn, pI830->hw_status->offset)) {
 	   DRICloseScreen(pScreen);
 	   return FALSE;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 85b6528..8a5262f 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1635,11 +1635,11 @@ i830_allocate_hwstatus(ScrnInfoPtr pScrn)
      * after init (at best), so allocate it fixed for its lifetime
      * (i.e. not through buffer objects).
      */
-    pI830->hw_status = i830_allocate_memory(pScrn, "G33 hw status",
+    pI830->hw_status = i830_allocate_memory(pScrn, "HW status",
 	    HWSTATUS_PAGE_SIZE, GTT_PAGE_SIZE, NEED_LIFETIME_FIXED);
     if (pI830->hw_status == NULL) {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		"Failed to allocate hw status page for G33.\n");
+		"Failed to allocate hw status page.\n");
 	return FALSE;
     }
     return TRUE;
@@ -1652,7 +1652,7 @@ i830_allocate_3d_memory(ScrnInfoPtr pScrn)
 
     DPRINTF(PFX, "i830_allocate_3d_memory\n");
 
-    if (IS_G33CLASS(pI830)) {
+    if (HWS_NEED_GFX(pI830)) {
 	if (!i830_allocate_hwstatus(pScrn))
 	    return FALSE;
     }


More information about the xorg-commit mailing list