xf86-video-intel: Branch 'modesetting' - 8 commits - src/common.h src/i810_reg.h src/i830_accel.c src/i830_debug.c src/i830_debug.h src/i830_display.c src/i830_driver.c src/i830.h src/i830_sdvo.c src/i830_video.c

Eric Anholt anholt at kemper.freedesktop.org
Wed Dec 13 02:05:24 EET 2006


 src/common.h       |    2 
 src/i810_reg.h     |   48 +++++++++
 src/i830.h         |    2 
 src/i830_accel.c   |    3 
 src/i830_debug.c   |  255 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/i830_debug.h   |    4 
 src/i830_display.c |    7 +
 src/i830_driver.c  |  157 --------------------------------
 src/i830_sdvo.c    |   71 +++++++++++---
 src/i830_video.c   |    2 
 10 files changed, 366 insertions(+), 185 deletions(-)

New commits:
diff-tree 7ed1b05922c07ff45a5794a992fd3d59ab55aa73 (from 9776f6c68b3cdd5585e58e677c1b1318d9aedaf4)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Dec 12 16:03:52 2006 -0800

    Fix mac mini SDVO output: write the SDVO[BC] enabled register state twice.

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 7936abd..895639e 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -696,6 +696,12 @@ i830_sdvo_dpms(xf86OutputPtr output, int
 
 	i830_sdvo_set_active_outputs(output, dev_priv->active_outputs);
 
+	/* Do it again!  If we remove this below register write, or the exact
+	 * same one 2 lines up, the mac mini SDVO output doesn't turn on.
+	 */
+	OUTREG(dev_priv->output_device,
+	       INREG(dev_priv->output_device) | SDVO_ENABLE);
+
 	for (i = 0; i < 2; i++)
 	    i830WaitForVblank(pScrn);
 
diff-tree 9776f6c68b3cdd5585e58e677c1b1318d9aedaf4 (from 54823ac39ce9666099d69196694643f04123cb4d)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Dec 12 16:02:47 2006 -0800

    Flush the plane changes in i830_crtc_dpms()
    
    Otherwise, the changes may not have taken effect.

diff --git a/src/i830_display.c b/src/i830_display.c
index f05b5c7..f0aac15 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -487,6 +487,7 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mod
     int pipe = intel_crtc->pipe;
     int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
     int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
+    int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
     int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
     CARD32 temp;
 
@@ -512,6 +513,9 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mod
 	temp = INREG(dspcntr_reg);
 	OUTREG(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
 
+	/* Flush the plane changes */
+	OUTREG(dspbase_reg, INREG(dspbase_reg));
+
 	/* Give the overlay scaler a chance to enable if it's on this pipe */
 	i830_crtc_dpms_video(crtc, TRUE);
 	break;
@@ -526,6 +530,9 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mod
 	/* Disable the VGA plane that we never use */
 	OUTREG(VGACNTRL, VGA_DISP_DISABLE);
 
+	/* Flush the plane changes */
+	OUTREG(dspbase_reg, INREG(dspbase_reg));
+
 	if (!IS_I9XX(pI830)) {
 	    /* Wait for vblank for the disable to take effect */
 	    i830WaitForVblank(pScrn);
diff-tree 54823ac39ce9666099d69196694643f04123cb4d (from ec45d7274333cccd20ad080facc8e995ad7b26b0)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Dec 12 14:38:08 2006 -0800

    Move the SDVO sync detection to after we've turned the port on.

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 8619d02..7936abd 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -556,12 +556,9 @@ i830_sdvo_mode_set(xf86OutputPtr output,
     struct i830_sdvo_priv   *dev_priv = intel_output->dev_priv;
     xf86CrtcPtr	    crtc = output->crtc;
     I830CrtcPrivatePtr	    intel_crtc = crtc->driver_private;
-    Bool input1, input2;
     CARD32 sdvox;
     int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
     int sdvo_pixel_multiply;
-    int i;
-    CARD8 status;
     CARD16 width, height;
     CARD16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
     CARD16 h_sync_offset, v_sync_offset;
@@ -675,18 +672,6 @@ i830_sdvo_mode_set(xf86OutputPtr output,
     }
 
     OUTREG(dev_priv->output_device, sdvox);
-
-    for (i = 0; i < 2; i++)
-	i830WaitForVblank(pScrn);
-
-    status = i830_sdvo_get_trained_inputs(output, &input1, &input2);
-
-    /* Warn if the device reported failure to sync. */
-    if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
-	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		   "First %s output reported failure to sync\n",
-		   SDVO_NAME(dev_priv));
-    }
 }
 
 static void
@@ -699,10 +684,29 @@ i830_sdvo_dpms(xf86OutputPtr output, int
 
     if (mode != DPMSModeOn) {
 	i830_sdvo_set_active_outputs(output, 0);
-	OUTREG(dev_priv->output_device, INREG(dev_priv->output_device) & ~SDVO_ENABLE);
+	OUTREG(dev_priv->output_device,
+	       INREG(dev_priv->output_device) & ~SDVO_ENABLE);
     } else {
-	OUTREG(dev_priv->output_device, INREG(dev_priv->output_device) | SDVO_ENABLE);
+	Bool input1, input2;
+	int i;
+	CARD8 status;
+
+	OUTREG(dev_priv->output_device,
+	       INREG(dev_priv->output_device) | SDVO_ENABLE);
+
 	i830_sdvo_set_active_outputs(output, dev_priv->active_outputs);
+
+	for (i = 0; i < 2; i++)
+	    i830WaitForVblank(pScrn);
+
+	status = i830_sdvo_get_trained_inputs(output, &input1, &input2);
+
+	/* Warn if the device reported failure to sync. */
+	if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "First %s output reported failure to sync\n",
+		       SDVO_NAME(dev_priv));
+	}
     }
 }
 
diff-tree ec45d7274333cccd20ad080facc8e995ad7b26b0 (from 838af10b85ee8c085c6d2c4fbe18fd90b2be9d3f)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Dec 12 13:54:49 2006 -0800

    Extend the error state reporting to cover ESR and decode PGTBL_ERR for 945.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index ce8407d..7c85cff 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -398,8 +398,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define EIR               0x20B0
 #define EMR               0x20B4
 #define ESR               0x20B8
-#define IP_ERR                    0x0001
-#define ERROR_RESERVED            0xffc6
+# define ERR_VERTEX_MAX				(1 << 5) /* lpt/cst */
+# define ERR_PGTBL_ERROR			(1 << 4)
+# define ERR_DISPLAY_OVERLAY_UNDERRUN		(1 << 3)
+# define ERR_MAIN_MEMORY_REFRESH		(1 << 2)
+# define ERR_INSTRUCTION_ERROR			(1 << 0)
 
 
 /* Interrupt Control Registers 
@@ -507,8 +510,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define PGETBL_SIZE_256KB   (1 << 1)
 #define PGETBL_SIZE_128KB   (2 << 1)
 
-/* Register containing pge table error results, p276
+/** @defgroup PGE_ERR
+ * @{
  */
+/** Page table debug register for i845 */
 #define PGE_ERR          0x2024
 #define PGE_ERR_ADDR_MASK   0xFFFFF000
 #define PGE_ERR_ID_MASK     0x00000038
@@ -528,8 +533,33 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define PGE_ERR_ILLEGAL_TRX 0x00000004
 #define PGE_ERR_LOCAL_MEM   0x00000005
 #define PGE_ERR_TILED       0x00000006
+/** @} */
 
-
+/** @defgroup PGTBL_ER
+ * @{
+ */
+/** Page table debug register for i945 */
+# define PGTBL_ER	0x2024
+# define PGTBL_ERR_MT_TILING			(1 << 27)
+# define PGTBL_ERR_MT_GTT_PTE			(1 << 26)
+# define PGTBL_ERR_LC_TILING			(1 << 25)
+# define PGTBL_ERR_LC_GTT_PTE			(1 << 24)
+# define PGTBL_ERR_BIN_VERTEXDATA_GTT_PTE	(1 << 23)
+# define PGTBL_ERR_BIN_INSTRUCTION_GTT_PTE	(1 << 22)
+# define PGTBL_ERR_CS_VERTEXDATA_GTT_PTE	(1 << 21)
+# define PGTBL_ERR_CS_INSTRUCTION_GTT_PTE	(1 << 20)
+# define PGTBL_ERR_CS_GTT		(1 << 19)
+# define PGTBL_ERR_OVERLAY_TILING		(1 << 18)
+# define PGTBL_ERR_OVERLAY_GTT_PTE		(1 << 16)
+# define PGTBL_ERR_DISPC_TILING			(1 << 14)
+# define PGTBL_ERR_DISPC_GTT_PTE		(1 << 12)
+# define PGTBL_ERR_DISPB_TILING			(1 << 10)
+# define PGTBL_ERR_DISPB_GTT_PTE		(1 << 8)
+# define PGTBL_ERR_DISPA_TILING			(1 << 6)
+# define PGTBL_ERR_DISPA_GTT_PTE		(1 << 4)
+# define PGTBL_ERR_HOST_PTE_DATA		(1 << 1)
+# define PGTBL_ERR_HOST_GTT_PTE			(1 << 0)
+/** @} */
 
 /* Page table entries loaded via mmio region, p323
  */
diff --git a/src/i830_debug.c b/src/i830_debug.c
index 7446a22..25245fb 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -637,17 +637,67 @@ Bool
 i830_check_error_state(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    int errors = 0, fatal = 0;
+    int errors = 0;
     unsigned long temp, head, tail;
 
     if (!I830IsPrimary(pScrn)) return TRUE;
 
-    /* Check first for page table errors */
-    temp = INREG(PGE_ERR);
+    temp = INREG16(ESR);
     if (temp != 0) {
-	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "PGTBL_ER is 0x%08lx\n", temp);
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "ESR is 0x%08lx%s%s%s%s\n", temp,
+		   temp & ERR_VERTEX_MAX ? ", max vertices exceeded" : "",
+		   temp & ERR_PGTBL_ERROR ? ", page table error" : "",
+		   temp & ERR_DISPLAY_OVERLAY_UNDERRUN ?
+		   ", display/overlay underrun" : "",
+		   temp & ERR_INSTRUCTION_ERROR ? ", instruction error" : "");
 	errors++;
     }
+    /* Check first for page table errors */
+    if (!IS_I9XX(pI830)) {
+	temp = INREG(PGE_ERR);
+	if (temp != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		       "PGTBL_ER is 0x%08lx\n", temp);
+	    errors++;
+	}
+    } else {
+	temp = INREG(PGTBL_ER);
+	if (temp != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "PGTBL_ER is 0x%08lx"
+		       "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", temp,
+		       temp & PGTBL_ERR_HOST_GTT_PTE ? ", host gtt pte" : "",
+		       temp & PGTBL_ERR_HOST_PTE_DATA ? ", host pte data" : "",
+		       temp & PGTBL_ERR_DISPA_GTT_PTE ? ", display A pte" : "",
+		       temp & PGTBL_ERR_DISPA_TILING ?
+		       ", display A tiling" : "",
+		       temp & PGTBL_ERR_DISPB_GTT_PTE ? ", display B pte" : "",
+		       temp & PGTBL_ERR_DISPB_TILING ?
+		       ", display B tiling" : "",
+		       temp & PGTBL_ERR_DISPC_GTT_PTE ? ", display C pte" : "",
+		       temp & PGTBL_ERR_DISPC_TILING ?
+		       ", display C tiling" : "",
+		       temp & PGTBL_ERR_OVERLAY_GTT_PTE ?
+		       ", overlay GTT PTE" : "",
+		       temp & PGTBL_ERR_OVERLAY_TILING ?
+		       ", overlay tiling" : "",
+		       temp & PGTBL_ERR_CS_GTT ? ", CS GTT" : "",
+		       temp & PGTBL_ERR_CS_INSTRUCTION_GTT_PTE ?
+		       ", CS instruction GTT PTE" : "",
+		       temp & PGTBL_ERR_CS_VERTEXDATA_GTT_PTE ?
+		       ", CS vertex data GTT PTE" : "",
+		       temp & PGTBL_ERR_BIN_INSTRUCTION_GTT_PTE ?
+		       ", BIN instruction GTT PTE" : "",
+		       temp & PGTBL_ERR_BIN_VERTEXDATA_GTT_PTE ?
+		       ", BIN vertex data GTT PTE" : "",
+		       temp & PGTBL_ERR_LC_GTT_PTE ? ", LC pte" : "",
+		       temp & PGTBL_ERR_LC_TILING ? ", LC tiling" : "",
+		       temp & PGTBL_ERR_MT_GTT_PTE ? ", MT pte" : "",
+		       temp & PGTBL_ERR_MT_TILING ? ", MT tiling" : "");
+	    errors++;
+	}
+    }
     temp = INREG(PGETBL_CTL);
     if (!(temp & 1)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -678,8 +728,5 @@ i830_check_error_state(ScrnInfoPtr pScrn
     }
 #endif
 
-    if (fatal)
-	FatalError("i830_check_error_state: can't recover from the above\n");
-
     return (errors != 0);
 }
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 78804de..d8a9c9b 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3125,7 +3125,10 @@ I830EnterVT(int scrnIndex, int flags)
       if (!I830BindAGPMemory(pScrn))
          return FALSE;
 
-   i830_check_error_state(pScrn);
+   if (i830_check_error_state(pScrn)) {
+      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		 "Existing errors found in hardware state\n");
+   }
 
    ResetState(pScrn, FALSE);
    SetHWOperatingState(pScrn);
diff-tree 838af10b85ee8c085c6d2c4fbe18fd90b2be9d3f (from 668ae6ce3c3c4b93a58749fd44ef32451adb6f9c)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Dec 12 13:45:41 2006 -0800

    Move PrintErrorState and CheckInheritedErrors code to i830_debug.c.

diff --git a/src/common.h b/src/common.h
index dd3fed6..540983b 100644
--- a/src/common.h
+++ b/src/common.h
@@ -96,7 +96,7 @@ extern void I830DPRINTF_stub(const char 
 			     const char *function, const char *fmt, ...);
 
 #ifdef _I830_H_
-#define PrintErrorState I830PrintErrorState
+#define PrintErrorState i830_dump_error_state
 #define WaitRingFunc I830WaitLpRing
 #define RecPtr pI830
 #else
diff --git a/src/i830.h b/src/i830.h
index 64a32dc..292374c 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -499,8 +499,6 @@ typedef struct _I830Rec {
 extern int I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis);
 extern void I830SetPIOAccess(I830Ptr pI830);
 extern void I830SetMMIOAccess(I830Ptr pI830);
-extern void I830PrintErrorState(ScrnInfoPtr pScrn);
-extern void I965PrintErrorState(ScrnInfoPtr pScrn);
 extern void I830Sync(ScrnInfoPtr pScrn);
 extern void I830InitHWCursor(ScrnInfoPtr pScrn);
 extern void I830SetPipeCursor (xf86CrtcPtr crtc, Bool force);
diff --git a/src/i830_accel.c b/src/i830_accel.c
index 6ad62d1..2260b71 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -58,6 +58,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #include "xaarop.h"
 #include "i830.h"
 #include "i810_reg.h"
+#include "i830_debug.h"
 
 int
 I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis)
@@ -99,7 +100,7 @@ I830WaitLpRing(ScrnInfoPtr pScrn, int n,
       } else if (now - start > timeout_millis) {
 	 ErrorF("Error in I830WaitLpRing(), now is %d, start is %d\n", now,
 		start);
-	 I830PrintErrorState(pScrn);
+	 i830_dump_error_state(pScrn);
 	 ErrorF("space: %d wanted %d\n", ring->space, n);
 #ifdef XF86DRI
 	 if (pI830->directRenderingEnabled) {
diff --git a/src/i830_debug.c b/src/i830_debug.c
index c2096a5..7446a22 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -522,3 +522,164 @@ void i830DumpRegs (ScrnInfoPtr pScrn)
     }
     xf86DrvMsg (pScrn->scrnIndex, X_INFO, "DumpRegsEnd\n");
 }
+
+/* Famous last words
+ */
+void
+i830_dump_error_state(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n",
+	   (unsigned long)INREG(PGETBL_CTL), (unsigned long)INREG(PGE_ERR));
+
+    ErrorF("ipeir: %lx iphdr: %lx\n", (unsigned long)INREG(IPEIR),
+	   (unsigned long)INREG(IPEHR));
+
+    ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n",
+	   (unsigned long)INREG(LP_RING + RING_TAIL),
+	   (unsigned long)INREG(LP_RING + RING_HEAD) & HEAD_ADDR,
+	   (unsigned long)INREG(LP_RING + RING_LEN),
+	   (unsigned long)INREG(LP_RING + RING_START));
+
+    ErrorF("eir: %x esr: %x emr: %x\n",
+	   INREG16(EIR), INREG16(ESR), INREG16(EMR));
+
+    ErrorF("instdone: %x instpm: %x\n", INREG16(INST_DONE), INREG8(INST_PM));
+
+    ErrorF("memmode: %lx instps: %lx\n", (unsigned long)INREG(MEMMODE),
+	   (unsigned long)INREG(INST_PS));
+
+    ErrorF("hwstam: %x ier: %x imr: %x iir: %x\n",
+	   INREG16(HWSTAM), INREG16(IER), INREG16(IMR), INREG16(IIR));
+}
+
+void
+i965_dump_error_state(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n",
+	   INREG(PGETBL_CTL), INREG(PGE_ERR));
+
+    ErrorF("ipeir: %lx iphdr: %lx\n", INREG(IPEIR_I965), INREG(IPEHR_I965));
+
+    ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n",
+	   INREG(LP_RING + RING_TAIL),
+	   INREG(LP_RING + RING_HEAD) & HEAD_ADDR,
+	   INREG(LP_RING + RING_LEN), INREG(LP_RING + RING_START));
+
+    ErrorF("Err ID (eir): %x Err Status (esr): %x Err Mask (emr): %x\n",
+	   (int)INREG(EIR), (int)INREG(ESR), (int)INREG(EMR));
+
+    ErrorF("instdone: %x instdone_1: %x\n", (int)INREG(INST_DONE_I965),
+	   (int)INREG(INST_DONE_1));
+    ErrorF("instpm: %x\n", (int)INREG(INST_PM));
+
+    ErrorF("memmode: %lx instps: %lx\n", INREG(MEMMODE), INREG(INST_PS_I965));
+
+    ErrorF("HW Status mask (hwstam): %x\nIRQ enable (ier): %x "
+	   "imr: %x iir: %x\n",
+	   (int)INREG(HWSTAM), (int)INREG(IER), (int)INREG(IMR),
+	   (int)INREG(IIR));
+
+    ErrorF("acthd: %lx dma_fadd_p: %lx\n", INREG(ACTHD), INREG(DMA_FADD_P));
+    ErrorF("ecoskpd: %lx excc: %lx\n", INREG(ECOSKPD), INREG(EXCC));
+
+    ErrorF("cache_mode: %x/%x\n", (int)INREG(CACHE_MODE_0),
+	   (int)INREG(CACHE_MODE_1));
+    ErrorF("mi_arb_state: %x\n", (int)INREG(MI_ARB_STATE));
+
+    ErrorF("IA_VERTICES_COUNT_QW %x/%x\n",
+	   (int)INREG(IA_VERTICES_COUNT_QW),
+	   (int)INREG(IA_VERTICES_COUNT_QW+4));
+    ErrorF("IA_PRIMITIVES_COUNT_QW %x/%x\n",
+	   (int)INREG(IA_PRIMITIVES_COUNT_QW),
+	   (int)INREG(IA_PRIMITIVES_COUNT_QW+4));
+
+    ErrorF("VS_INVOCATION_COUNT_QW %x/%x\n",
+	   (int)INREG(VS_INVOCATION_COUNT_QW),
+	   (int)INREG(VS_INVOCATION_COUNT_QW+4));
+
+    ErrorF("GS_INVOCATION_COUNT_QW %x/%x\n",
+	   (int)INREG(GS_INVOCATION_COUNT_QW),
+	   (int)INREG(GS_INVOCATION_COUNT_QW+4));
+    ErrorF("GS_PRIMITIVES_COUNT_QW %x/%x\n",
+	   (int)INREG(GS_PRIMITIVES_COUNT_QW),
+	   (int)INREG(GS_PRIMITIVES_COUNT_QW+4));
+
+    ErrorF("CL_INVOCATION_COUNT_QW %x/%x\n",
+	   (int)INREG(CL_INVOCATION_COUNT_QW),
+	   (int)INREG(CL_INVOCATION_COUNT_QW+4));
+    ErrorF("CL_PRIMITIVES_COUNT_QW %x/%x\n",
+	   (int)INREG(CL_PRIMITIVES_COUNT_QW),
+	   (int)INREG(CL_PRIMITIVES_COUNT_QW+4));
+
+    ErrorF("PS_INVOCATION_COUNT_QW %x/%x\n",
+	   (int)INREG(PS_INVOCATION_COUNT_QW),
+	   (int)INREG(PS_INVOCATION_COUNT_QW+4));
+    ErrorF("PS_DEPTH_COUNT_QW %x/%x\n",
+	   (int)INREG(PS_DEPTH_COUNT_QW),
+	   (int)INREG(PS_DEPTH_COUNT_QW+4));
+
+    ErrorF("WIZ_CTL %x\n", (int)INREG(WIZ_CTL));
+    ErrorF("TS_CTL %x  TS_DEBUG_DATA %x\n", (int)INREG(TS_CTL),
+	   (int)INREG(TS_DEBUG_DATA));
+    ErrorF("TD_CTL %x / %x\n", (int)INREG(TD_CTL), (int)INREG(TD_CTL2));
+}
+
+/**
+ * Checks the hardware error state bits.
+ *
+ * \return TRUE if any errors were found.
+ */
+Bool
+i830_check_error_state(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    int errors = 0, fatal = 0;
+    unsigned long temp, head, tail;
+
+    if (!I830IsPrimary(pScrn)) return TRUE;
+
+    /* Check first for page table errors */
+    temp = INREG(PGE_ERR);
+    if (temp != 0) {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "PGTBL_ER is 0x%08lx\n", temp);
+	errors++;
+    }
+    temp = INREG(PGETBL_CTL);
+    if (!(temp & 1)) {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "PGTBL_CTL (0x%08lx) indicates GTT is disabled\n", temp);
+	errors++;
+    }
+    temp = INREG(LP_RING + RING_LEN);
+    if (temp & 1) {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "PRB0_CTL (0x%08lx) indicates ring buffer enabled\n", temp);
+	errors++;
+    }
+    head = INREG(LP_RING + RING_HEAD);
+    tail = INREG(LP_RING + RING_TAIL);
+    if ((tail & I830_TAIL_MASK) != (head & I830_HEAD_MASK)) {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "PRB0_HEAD (0x%08lx) and PRB0_TAIL (0x%08lx) indicate "
+		   "ring buffer not flushed\n", head, tail);
+	errors++;
+    }
+
+#if 0
+    if (errors) {
+	if (IS_I965G(pI830))
+	    i965_dump_error_state(pScrn);
+	else
+	    i830_dump_error_state(pScrn);
+    }
+#endif
+
+    if (fatal)
+	FatalError("i830_check_error_state: can't recover from the above\n");
+
+    return (errors != 0);
+}
diff --git a/src/i830_debug.h b/src/i830_debug.h
index a365085..2d2e72b 100644
--- a/src/i830_debug.h
+++ b/src/i830_debug.h
@@ -28,3 +28,7 @@
 void i830TakeRegSnapshot(ScrnInfoPtr pScrn);
 void i830CompareRegsToSnapshot(ScrnInfoPtr pScrn, char *where);
 void i830DumpRegs (ScrnInfoPtr pScrn);
+void i830_dump_error_state(ScrnInfoPtr pScrn);
+void i965_dump_error_state(ScrnInfoPtr pScrn);
+Bool i830_check_error_state(ScrnInfoPtr pScrn);
+
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 46973e7..78804de 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1948,61 +1948,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
 }
 
 /*
- * As the name says.  Check that the initial state is reasonable.
- * If any unrecoverable problems are found, bail out here.
- */
-static Bool
-CheckInheritedState(ScrnInfoPtr pScrn)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-   int errors = 0, fatal = 0;
-   unsigned long temp, head, tail;
-
-   if (!I830IsPrimary(pScrn)) return TRUE;
-
-   /* Check first for page table errors */
-   temp = INREG(PGE_ERR);
-   if (temp != 0) {
-      xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "PGTBL_ER is 0x%08lx\n", temp);
-      errors++;
-   }
-   temp = INREG(PGETBL_CTL);
-   if (!(temp & 1)) {
-      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		 "PGTBL_CTL (0x%08lx) indicates GTT is disabled\n", temp);
-      errors++;
-   }
-   temp = INREG(LP_RING + RING_LEN);
-   if (temp & 1) {
-      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		 "PRB0_CTL (0x%08lx) indicates ring buffer enabled\n", temp);
-      errors++;
-   }
-   head = INREG(LP_RING + RING_HEAD);
-   tail = INREG(LP_RING + RING_TAIL);
-   if ((tail & I830_TAIL_MASK) != (head & I830_HEAD_MASK)) {
-      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		 "PRB0_HEAD (0x%08lx) and PRB0_TAIL (0x%08lx) indicate "
-		 "ring buffer not flushed\n", head, tail);
-      errors++;
-   }
-
-#if 0
-   if (errors) {
-      if (IS_I965G(pI830))
-         I965PrintErrorState(pScrn);
-      else
-         I830PrintErrorState(pScrn);
-   }
-#endif
-
-   if (fatal)
-      FatalError("CheckInheritedState: can't recover from the above\n");
-
-   return (errors != 0);
-}
-
-/*
  * Reset registers that it doesn't make sense to save/restore to a sane state.
  * This is basically the ring buffer and fence registers.  Restoring these
  * doesn't make sense without restoring GTT mappings.  This is something that
@@ -2366,103 +2311,6 @@ InitRegisterRec(ScrnInfoPtr pScrn)
       i830Reg->Fence[i] = 0;
 }
 
-/* Famous last words
- */
-void
-I830PrintErrorState(ScrnInfoPtr pScrn)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-
-   ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n",
-	  (unsigned long)INREG(PGETBL_CTL), (unsigned long)INREG(PGE_ERR));
-
-   ErrorF("ipeir: %lx iphdr: %lx\n", (unsigned long)INREG(IPEIR), 
-	  (unsigned long)INREG(IPEHR));
-
-   ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n",
-	  (unsigned long)INREG(LP_RING + RING_TAIL),
-	  (unsigned long)INREG(LP_RING + RING_HEAD) & HEAD_ADDR,
-	  (unsigned long)INREG(LP_RING + RING_LEN), 
-	  (unsigned long)INREG(LP_RING + RING_START));
-
-   ErrorF("eir: %x esr: %x emr: %x\n",
-	  INREG16(EIR), INREG16(ESR), INREG16(EMR));
-
-   ErrorF("instdone: %x instpm: %x\n", INREG16(INST_DONE), INREG8(INST_PM));
-
-   ErrorF("memmode: %lx instps: %lx\n", (unsigned long)INREG(MEMMODE), 
-	  (unsigned long)INREG(INST_PS));
-
-   ErrorF("hwstam: %x ier: %x imr: %x iir: %x\n",
-	  INREG16(HWSTAM), INREG16(IER), INREG16(IMR), INREG16(IIR));
-}
-
-void
-I965PrintErrorState(ScrnInfoPtr pScrn)
-{
-   I830Ptr pI830 = I830PTR(pScrn);
-
-   ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n",
-	  INREG(PGETBL_CTL), INREG(PGE_ERR));
-
-   ErrorF("ipeir: %lx iphdr: %lx\n", INREG(IPEIR_I965), INREG(IPEHR_I965));
-
-   ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n",
-	  INREG(LP_RING + RING_TAIL),
-	  INREG(LP_RING + RING_HEAD) & HEAD_ADDR,
-	  INREG(LP_RING + RING_LEN), INREG(LP_RING + RING_START));
-
-   ErrorF("Err ID (eir): %x Err Status (esr): %x Err Mask (emr): %x\n",
-	  (int)INREG(EIR), (int)INREG(ESR), (int)INREG(EMR));
-
-   ErrorF("instdone: %x instdone_1: %x\n", (int)INREG(INST_DONE_I965),
-	  (int)INREG(INST_DONE_1));
-   ErrorF("instpm: %x\n", (int)INREG(INST_PM));
-
-   ErrorF("memmode: %lx instps: %lx\n", INREG(MEMMODE), INREG(INST_PS_I965));
-
-   ErrorF("HW Status mask (hwstam): %x\nIRQ enable (ier): %x imr: %x iir: %x\n",
-	  (int)INREG(HWSTAM), (int)INREG(IER), (int)INREG(IMR),
-	  (int)INREG(IIR));
-
-   ErrorF("acthd: %lx dma_fadd_p: %lx\n", INREG(ACTHD), INREG(DMA_FADD_P));
-   ErrorF("ecoskpd: %lx excc: %lx\n", INREG(ECOSKPD), INREG(EXCC));
-
-   ErrorF("cache_mode: %x/%x\n", (int)INREG(CACHE_MODE_0),
-	  (int)INREG(CACHE_MODE_1));
-   ErrorF("mi_arb_state: %x\n", (int)INREG(MI_ARB_STATE));
-
-   ErrorF("IA_VERTICES_COUNT_QW %x/%x\n", (int)INREG(IA_VERTICES_COUNT_QW),
-	  (int)INREG(IA_VERTICES_COUNT_QW+4));
-   ErrorF("IA_PRIMITIVES_COUNT_QW %x/%x\n", (int)INREG(IA_PRIMITIVES_COUNT_QW),
-	  (int)INREG(IA_PRIMITIVES_COUNT_QW+4));
-
-   ErrorF("VS_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(VS_INVOCATION_COUNT_QW),
-	  (int)INREG(VS_INVOCATION_COUNT_QW+4));
-
-   ErrorF("GS_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(GS_INVOCATION_COUNT_QW),
-	  (int)INREG(GS_INVOCATION_COUNT_QW+4));
-   ErrorF("GS_PRIMITIVES_COUNT_QW %x/%x\n", (int)INREG(GS_PRIMITIVES_COUNT_QW),
-	  (int)INREG(GS_PRIMITIVES_COUNT_QW+4));
-
-   ErrorF("CL_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(CL_INVOCATION_COUNT_QW),
-	  (int)INREG(CL_INVOCATION_COUNT_QW+4));
-   ErrorF("CL_PRIMITIVES_COUNT_QW %x/%x\n", (int)INREG(CL_PRIMITIVES_COUNT_QW),
-	  (int)INREG(CL_PRIMITIVES_COUNT_QW+4));
-
-   ErrorF("PS_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(PS_INVOCATION_COUNT_QW),
-	  (int)INREG(PS_INVOCATION_COUNT_QW+4));
-   ErrorF("PS_DEPTH_COUNT_QW %x/%x\n", (int)INREG(PS_DEPTH_COUNT_QW),
-	  (int)INREG(PS_DEPTH_COUNT_QW+4));
-
-   ErrorF("WIZ_CTL %x\n", (int)INREG(WIZ_CTL));
-   ErrorF("TS_CTL %x  TS_DEBUG_DATA %x\n", (int)INREG(TS_CTL),
-	  (int)INREG(TS_DEBUG_DATA));
-   ErrorF("TD_CTL %x / %x\n", (int)INREG(TD_CTL), (int)INREG(TD_CTL2));
-
-   
-}
-
 static void
 I830PointerMoved(int index, int x, int y)
 {
@@ -3277,7 +3125,7 @@ I830EnterVT(int scrnIndex, int flags)
       if (!I830BindAGPMemory(pScrn))
          return FALSE;
 
-   CheckInheritedState(pScrn);
+   i830_check_error_state(pScrn);
 
    ResetState(pScrn, FALSE);
    SetHWOperatingState(pScrn);
diff --git a/src/i830_video.c b/src/i830_video.c
index 986d36a..5979415 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2794,7 +2794,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoP
    if (pI830->AccelInfoRec)
       (*pI830->AccelInfoRec->Sync)(pScrn);
 #if WATCH_STATS
-   I830PrintErrorState (pScrn);
+   i830_dump_error_state (pScrn);
 #endif
 }
 
diff-tree 668ae6ce3c3c4b93a58749fd44ef32451adb6f9c (from 91a538beadc17155be395ea2c8109a0958a969bd)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Dec 12 11:39:40 2006 -0800

    Set the SDVO port to on before sending the SDVO output on command.

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 077e6c1..8619d02 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -701,8 +701,8 @@ i830_sdvo_dpms(xf86OutputPtr output, int
 	i830_sdvo_set_active_outputs(output, 0);
 	OUTREG(dev_priv->output_device, INREG(dev_priv->output_device) & ~SDVO_ENABLE);
     } else {
-	i830_sdvo_set_active_outputs(output, dev_priv->active_outputs);
 	OUTREG(dev_priv->output_device, INREG(dev_priv->output_device) | SDVO_ENABLE);
+	i830_sdvo_set_active_outputs(output, dev_priv->active_outputs);
     }
 }
 
diff-tree 91a538beadc17155be395ea2c8109a0958a969bd (from ce54538b905eb329f45c1b9b15e95ddce4a7927f)
Author: Eric Anholt <eric at anholt.net>
Date:   Sat Dec 9 15:58:47 2006 -0800

    More debugging output for SDVO.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index d525024..ce8407d 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -888,6 +888,16 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 /** @} */
 
 #define DPLL_TEST		0x606c
+# define DPLLB_TEST_SDVO_DIV_1			(0 << 22)
+# define DPLLB_TEST_SDVO_DIV_2			(1 << 22)
+# define DPLLB_TEST_SDVO_DIV_4			(2 << 22)
+# define DPLLB_TEST_SDVO_DIV_MASK		(3 << 22)
+# define DPLLB_TEST_N_BYPASS			(1 << 19)
+# define DPLLB_TEST_M_BYPASS			(1 << 18)
+# define DPLLB_INPUT_BUFFER_ENABLE		(1 << 16)
+# define DPLLA_TEST_N_BYPASS			(1 << 3)
+# define DPLLA_TEST_M_BYPASS			(1 << 2)
+# define DPLLA_INPUT_BUFFER_ENABLE		(1 << 0)
 
 #define D_STATE			0x6104
 #define DSPCLK_GATE_D		0x6200
diff --git a/src/i830_debug.c b/src/i830_debug.c
index 8c8b95e..c2096a5 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -160,8 +160,8 @@ DEBUGSTRING(i830_debug_dpll)
     }
     if (IS_I945G(pI830) || IS_I945GM(pI830)) {
 	sprintf(sdvoextra, ", SDVO mult %d",
-		(int)(val & SDVO_MULTIPLIER_MASK) >>
-		SDVO_MULTIPLIER_SHIFT_HIRES);
+		(int)((val & SDVO_MULTIPLIER_MASK) >>
+		SDVO_MULTIPLIER_SHIFT_HIRES) + 1);
     } else {
 	sdvoextra[0] = '\0';
     }
@@ -172,6 +172,22 @@ DEBUGSTRING(i830_debug_dpll)
 		     fpextra, sdvoextra);
 }
 
+DEBUGSTRING(i830_debug_dpll_test)
+{
+    char *dpllandiv = val & DPLLA_TEST_N_BYPASS ? ", DPLLA N bypassed" : "";
+    char *dpllamdiv = val & DPLLA_TEST_M_BYPASS ? ", DPLLA M bypassed" : "";
+    char *dpllainput = val & DPLLA_INPUT_BUFFER_ENABLE ?
+	"" : ", DPLLA input buffer disabled";
+    char *dpllbndiv = val & DPLLB_TEST_N_BYPASS ? ", DPLLB N bypassed" : "";
+    char *dpllbmdiv = val & DPLLB_TEST_M_BYPASS ? ", DPLLB M bypassed" : "";
+    char *dpllbinput = val & DPLLB_INPUT_BUFFER_ENABLE ?
+	"" : ", DPLLB input buffer disabled";
+
+    return XNFprintf("%s%s%s%s%s%s",
+		     dpllandiv, dpllamdiv, dpllainput,
+		     dpllbndiv, dpllbmdiv, dpllbinput);
+}
+
 DEBUGSTRING(i830_debug_lvds)
 {
     char pipe = val & LVDS_PIPEB_SELECT ? 'B' : 'A';
@@ -180,6 +196,27 @@ DEBUGSTRING(i830_debug_lvds)
     return XNFprintf("%s, pipe %c", enable, pipe);
 }
 
+DEBUGSTRING(i830_debug_sdvo)
+{
+    char *enable = val & SDVO_ENABLE ? "enabled" : "disabled";
+    char pipe = val & SDVO_PIPE_B_SELECT ? 'B' : 'A';
+    char *stall = val & SDVO_STALL_SELECT ? "enabled" : "disabled";
+    char *detected = val & SDVO_DETECTED ? "" : "not ";
+    char *gang = val & SDVOC_GANG_MODE ? ", gang mode" : "";
+    char sdvoextra[20];
+
+    if (IS_I915G(pI830) || IS_I915GM(pI830)) {
+	sprintf(sdvoextra, ", SDVO mult %d",
+		(int)((val & SDVO_PORT_MULTIPLY_MASK) >>
+		SDVO_PORT_MULTIPLY_SHIFT) + 1);
+    } else {
+	sdvoextra[0] = '\0';
+    }
+
+    return XNFprintf("%s, pipe %c, stall %s, %sdetected%s%s",
+		     enable, pipe, stall, detected, sdvoextra, gang);
+}
+
 #define DEFINEREG(reg) \
 	{ reg, #reg, NULL, 0 }
 #define DEFINEREG2(reg, func) \
@@ -194,14 +231,14 @@ static struct i830SnapshotRec {
     DEFINEREG(VCLK_DIVISOR_VGA0),
     DEFINEREG(VCLK_DIVISOR_VGA1),
     DEFINEREG(VCLK_POST_DIV),
-    DEFINEREG(DPLL_TEST),
+    DEFINEREG2(DPLL_TEST, i830_debug_dpll_test),
     DEFINEREG(D_STATE),
     DEFINEREG(DSPCLK_GATE_D),
     DEFINEREG(RENCLK_GATE_D1),
     DEFINEREG(RENCLK_GATE_D2),
 /*  DEFINEREG(RAMCLK_GATE_D),	CRL only */
-    DEFINEREG(SDVOB),
-    DEFINEREG(SDVOC),
+    DEFINEREG2(SDVOB, i830_debug_sdvo),
+    DEFINEREG2(SDVOC, i830_debug_sdvo),
 /*    DEFINEREG(UDIB_SVB_SHB_CODES), CRL only */
 /*    DEFINEREG(UDIB_SHA_BLANK_CODES), CRL only */
     DEFINEREG(SDVOUDI),
diff-tree ce54538b905eb329f45c1b9b15e95ddce4a7927f (from c8c1fb64ccecfb88f9923ad65c9898aa44692260)
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Dec 8 08:26:30 2006 -0800

    Add a hack for DDC on my Mac Mini.

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 87dc9d9..077e6c1 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -983,6 +983,31 @@ i830_sdvo_detect(xf86OutputPtr output)
 	return XF86OutputStatusDisconnected;
 }
 
+static DisplayModePtr
+i830_sdvo_get_modes(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    DisplayModePtr modes;
+    xf86OutputPtr crt;
+
+    modes = i830_ddc_get_modes(output);
+    if (modes != NULL)
+	return NULL;
+
+    /* Mac mini hack.  On this device, I get DDC through the analog, which
+     * load-detects as disconnected.  I fail to DDC through the SDVO DDC,
+     * but it does load-detect as connected.  So, just steal the DDC bits from
+     * analog when we fail at finding it the right way.
+     */
+    crt = pI830->xf86_config.output[0];
+    if (crt->funcs->detect(crt) == XF86OutputStatusDisconnected) {
+	return crt->funcs->get_modes(crt);
+    }
+
+    return NULL;
+}
+
 static void
 i830_sdvo_destroy (xf86OutputPtr output)
 {
@@ -1007,7 +1032,7 @@ static const xf86OutputFuncsRec i830_sdv
     .mode_fixup = i830_sdvo_mode_fixup,
     .mode_set = i830_sdvo_mode_set,
     .detect = i830_sdvo_detect,
-    .get_modes = i830_ddc_get_modes,
+    .get_modes = i830_sdvo_get_modes,
     .destroy = i830_sdvo_destroy
 };
 



More information about the xorg-commit mailing list