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