xf86-video-intel: Branch 'xf86-video-intel-2.2-branch' - 6 commits - src/i810_reg.h src/i830_debug.c src/i830_dvo.c src/i830.h src/i830_quirks.c

Jesse Barnes jbarnes at kemper.freedesktop.org
Fri Feb 22 11:55:00 PST 2008


 src/i810_reg.h    |   38 ++++++++++++
 src/i830.h        |    1 
 src/i830_debug.c  |  135 ++++++++++++++++++++++++++++++++++++++++++++
 src/i830_dvo.c    |    8 ++
 src/i830_quirks.c |  163 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 340 insertions(+), 5 deletions(-)

New commits:
commit c81cf678aabbf84bfa4b98d491a5a38179f591f4
Author: Jesse Barnes <root at nietzche.virtuousgeek.org>
Date:   Thu Feb 7 11:56:28 2008 -0800

    Add CACHE_MODE_0 register to dump output

diff --git a/src/i830_debug.c b/src/i830_debug.c
index 38c90ec..7d0c0a0 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -493,6 +493,7 @@ static struct i830SnapshotRec {
     DEFINEREG2(VCLK_DIVISOR_VGA1, i830_debug_fp),
     DEFINEREG2(VCLK_POST_DIV, i830_debug_vga_pd),
     DEFINEREG2(DPLL_TEST, i830_debug_dpll_test),
+    DEFINEREG(CACHE_MODE_0),
     DEFINEREG(D_STATE),
     DEFINEREG2(DSPCLK_GATE_D, i830_debug_dspclk_gate_d),
     DEFINEREG(RENCLK_GATE_D1),
commit db2e848b13368eb9c180cd82494645459a6c0382
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Feb 16 18:16:12 2008 -0800

    Decode DSPCLK_GATE, dump PIPE*STAT, MI_MODE, MI_DISPLAY_POWER_DOWN, MI_ARB_STATE, MI_RDRET_STATE, ECOSKPD

diff --git a/src/i810_reg.h b/src/i810_reg.h
index e69ae0a..5170004 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -365,7 +365,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #define CACHE_MODE_0           0x2120
 #define CACHE_MODE_1           0x2124
+#define MI_MODE		       0x209c
+#define MI_DISPLAY_POWER_DOWN  0x20e0
 #define MI_ARB_STATE           0x20e4
+#define MI_RDRET_STATE	       0x20fc
 
 /* Start addresses for each of the primary rings:
  */
@@ -976,6 +979,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #define D_STATE			0x6104
 #define DSPCLK_GATE_D		0x6200
+# define DPUNIT_B_CLOCK_GATE_DISABLE		(1 << 30) /* 965 */
+# define VSUNIT_CLOCK_GATE_DISABLE		(1 << 29) /* 965 */
+# define VRHUNIT_CLOCK_GATE_DISABLE		(1 << 28) /* 965 */
+# define VRDUNIT_CLOCK_GATE_DISABLE		(1 << 27) /* 965 */
+# define AUDUNIT_CLOCK_GATE_DISABLE		(1 << 26) /* 965 */
+# define DPUNIT_A_CLOCK_GATE_DISABLE		(1 << 25) /* 965 */
+# define DPCUNIT_CLOCK_GATE_DISABLE		(1 << 24) /* 965 */
 # define TVRUNIT_CLOCK_GATE_DISABLE		(1 << 23) /* 915-945 */
 # define TVCUNIT_CLOCK_GATE_DISABLE		(1 << 22) /* 915-945 */
 # define TVFUNIT_CLOCK_GATE_DISABLE		(1 << 21) /* 915-945 */
@@ -990,7 +1000,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 # define DPLUNIT_CLOCK_GATE_DISABLE		(1 << 12) /* 915-945 */
 # define DPOUNIT_CLOCK_GATE_DISABLE		(1 << 11)
 # define DPBUNIT_CLOCK_GATE_DISABLE		(1 << 10)
-# define DPCUNIT_CLOCK_GATE_DISABLE		(1 << 9)
+# define DCUNIT_CLOCK_GATE_DISABLE		(1 << 9)
 # define DPUNIT_CLOCK_GATE_DISABLE		(1 << 8)
 # define VRUNIT_CLOCK_GATE_DISABLE		(1 << 7) /* 915+: reserved */
 # define OVHUNIT_CLOCK_GATE_DISABLE		(1 << 6) /* 830-865 */
@@ -1995,6 +2005,32 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define PIPEAGCMAXGREEN		0x70014
 #define PIPEAGCMAXBLUE		0x70018
 #define PIPEASTAT		0x70024
+# define FIFO_UNDERRUN		(1 << 31)
+# define CRC_ERROR_ENABLE	(1 << 29)
+# define CRC_DONE_ENABLE	(1 << 28)
+# define GMBUS_EVENT_ENABLE	(1 << 27)
+# define VSYNC_INT_ENABLE	(1 << 25)
+# define DLINE_COMPARE_ENABLE	(1 << 24)
+# define DPST_EVENT_ENABLE	(1 << 23)
+# define LBLC_EVENT_ENABLE	(1 << 22)
+# define OFIELD_INT_ENABLE	(1 << 21)
+# define EFIELD_INT_ENABLE	(1 << 20)
+# define SVBLANK_INT_ENABLE	(1 << 18)
+# define VBLANK_INT_ENABLE	(1 << 17)
+# define OREG_UPDATE_ENABLE	(1 << 16)
+# define CRC_ERROR_INT_STATUS	(1 << 13)
+# define CRC_DONE_INT_STATUS	(1 << 12)
+# define GMBUS_INT_STATUS	(1 << 11)
+# define VSYNC_INT_STATUS	(1 << 9)
+# define DLINE_COMPARE_STATUS	(1 << 8)
+# define DPST_EVENT_STATUS	(1 << 7)
+# define LBLC_EVENT_STATUS	(1 << 6)
+# define OFIELD_INT_STATUS	(1 << 5)
+# define EFIELD_INT_STATUS	(1 << 4)
+# define SVBLANK_INT_STATUS	(1 << 2)
+# define VBLANK_INT_STATUS	(1 << 1)
+# define OREG_UPDATE_STATUS	(1 << 0)
+				 
 
 #define DSPARB			0x70030
 #define DSPFW1			0x70034
diff --git a/src/i830_debug.c b/src/i830_debug.c
index 9cf7ba5..38c90ec 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -88,6 +88,61 @@ DEBUGSTRING(i830_debug_pipeconf)
     return XNFprintf("%s, %s", enabled, bit30);
 }
 
+DEBUGSTRING(i830_debug_pipestat)
+{
+    char *_FIFO_UNDERRUN = val & FIFO_UNDERRUN ? " FIFO_UNDERRUN" : "";
+    char *_CRC_ERROR_ENABLE = val & CRC_ERROR_ENABLE ? " CRC_ERROR_ENABLE" : "";
+    char *_CRC_DONE_ENABLE = val & CRC_DONE_ENABLE ? " CRC_DONE_ENABLE" : "";
+    char *_GMBUS_EVENT_ENABLE = val & GMBUS_EVENT_ENABLE ? " GMBUS_EVENT_ENABLE" : "";
+    char *_VSYNC_INT_ENABLE = val & VSYNC_INT_ENABLE ? " VSYNC_INT_ENABLE" : "";
+    char *_DLINE_COMPARE_ENABLE = val & DLINE_COMPARE_ENABLE ? " DLINE_COMPARE_ENABLE" : "";
+    char *_DPST_EVENT_ENABLE = val & DPST_EVENT_ENABLE ? " DPST_EVENT_ENABLE" : "";
+    char *_LBLC_EVENT_ENABLE = val & LBLC_EVENT_ENABLE ? " LBLC_EVENT_ENABLE" : "";
+    char *_OFIELD_INT_ENABLE = val & OFIELD_INT_ENABLE ? " OFIELD_INT_ENABLE" : "";
+    char *_EFIELD_INT_ENABLE = val & EFIELD_INT_ENABLE ? " EFIELD_INT_ENABLE" : "";
+    char *_SVBLANK_INT_ENABLE = val & SVBLANK_INT_ENABLE ? " SVBLANK_INT_ENABLE" : "";
+    char *_VBLANK_INT_ENABLE = val & VBLANK_INT_ENABLE ? " VBLANK_INT_ENABLE" : "";
+    char *_OREG_UPDATE_ENABLE = val & OREG_UPDATE_ENABLE ? " OREG_UPDATE_ENABLE" : "";
+    char *_CRC_ERROR_INT_STATUS = val & CRC_ERROR_INT_STATUS ? " CRC_ERROR_INT_STATUS" : "";
+    char *_CRC_DONE_INT_STATUS = val & CRC_DONE_INT_STATUS ? " CRC_DONE_INT_STATUS" : "";
+    char *_GMBUS_INT_STATUS = val & GMBUS_INT_STATUS ? " GMBUS_INT_STATUS" : "";
+    char *_VSYNC_INT_STATUS = val & VSYNC_INT_STATUS ? " VSYNC_INT_STATUS" : "";
+    char *_DLINE_COMPARE_STATUS = val & DLINE_COMPARE_STATUS ? " DLINE_COMPARE_STATUS" : "";
+    char *_DPST_EVENT_STATUS = val & DPST_EVENT_STATUS ? " DPST_EVENT_STATUS" : "";
+    char *_LBLC_EVENT_STATUS = val & LBLC_EVENT_STATUS ? " LBLC_EVENT_STATUS" : "";
+    char *_OFIELD_INT_STATUS = val & OFIELD_INT_STATUS ? " OFIELD_INT_STATUS" : "";
+    char *_EFIELD_INT_STATUS = val & EFIELD_INT_STATUS ? " EFIELD_INT_STATUS" : "";
+    char *_SVBLANK_INT_STATUS = val & SVBLANK_INT_STATUS ? " SVBLANK_INT_STATUS" : "";
+    char *_VBLANK_INT_STATUS = val & VBLANK_INT_STATUS ? " VBLANK_INT_STATUS" : "";
+    char *_OREG_UPDATE_STATUS = val & OREG_UPDATE_STATUS ? " OREG_UPDATE_STATUS" : "";
+    return XNFprintf("status:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+		     _FIFO_UNDERRUN,
+		     _CRC_ERROR_ENABLE,
+		     _CRC_DONE_ENABLE,
+		     _GMBUS_EVENT_ENABLE,
+		     _VSYNC_INT_ENABLE,
+		     _DLINE_COMPARE_ENABLE,
+		     _DPST_EVENT_ENABLE,
+		     _LBLC_EVENT_ENABLE,
+		     _OFIELD_INT_ENABLE,
+		     _EFIELD_INT_ENABLE,
+		     _SVBLANK_INT_ENABLE,
+		     _VBLANK_INT_ENABLE,
+		     _OREG_UPDATE_ENABLE,
+		     _CRC_ERROR_INT_STATUS,
+		     _CRC_DONE_INT_STATUS,
+		     _GMBUS_INT_STATUS,
+		     _VSYNC_INT_STATUS,
+		     _DLINE_COMPARE_STATUS,
+		     _DPST_EVENT_STATUS,
+		     _LBLC_EVENT_STATUS,
+		     _OFIELD_INT_STATUS,
+		     _EFIELD_INT_STATUS,
+		     _SVBLANK_INT_STATUS,
+		     _VBLANK_INT_STATUS,
+		     _OREG_UPDATE_STATUS);
+}
+
 DEBUGSTRING(i830_debug_hvtotal)
 {
     return XNFprintf("%d active, %d total", (val & 0xffff) + 1,
@@ -340,6 +395,76 @@ DEBUGSTRING(i830_debug_sdvo)
 		     enable, pipe, stall, detected, sdvoextra, gang);
 }
 
+DEBUGSTRING(i830_debug_dspclk_gate_d)
+{
+    char *DPUNIT_B = val & DPUNIT_B_CLOCK_GATE_DISABLE ? " DPUNIT_B" : "";
+    char *VSUNIT = val & VSUNIT_CLOCK_GATE_DISABLE ? " VSUNIT" : "";
+    char *VRHUNIT = val & VRHUNIT_CLOCK_GATE_DISABLE ? " VRHUNIT" : "";
+    char *VRDUNIT = val & VRDUNIT_CLOCK_GATE_DISABLE ? " VRDUNIT" : "";
+    char *AUDUNIT = val & AUDUNIT_CLOCK_GATE_DISABLE ? " AUDUNIT" : "";
+    char *DPUNIT_A = val & DPUNIT_A_CLOCK_GATE_DISABLE ? " DPUNIT_A" : "";
+    char *DPCUNIT = val & DPCUNIT_CLOCK_GATE_DISABLE ? " DPCUNIT" : "";
+    char *TVRUNIT = val & TVRUNIT_CLOCK_GATE_DISABLE ? " TVRUNIT" : "";
+    char *TVCUNIT = val & TVCUNIT_CLOCK_GATE_DISABLE ? " TVCUNIT" : "";
+    char *TVFUNIT = val & TVFUNIT_CLOCK_GATE_DISABLE ? " TVFUNIT" : "";
+    char *TVEUNIT = val & TVEUNIT_CLOCK_GATE_DISABLE ? " TVEUNIT" : "";
+    char *DVSUNIT = val & DVSUNIT_CLOCK_GATE_DISABLE ? " DVSUNIT" : "";
+    char *DSSUNIT = val & DSSUNIT_CLOCK_GATE_DISABLE ? " DSSUNIT" : "";
+    char *DDBUNIT = val & DDBUNIT_CLOCK_GATE_DISABLE ? " DDBUNIT" : "";
+    char *DPRUNIT = val & DPRUNIT_CLOCK_GATE_DISABLE ? " DPRUNIT" : "";
+    char *DPFUNIT = val & DPFUNIT_CLOCK_GATE_DISABLE ? " DPFUNIT" : "";
+    char *DPBMUNIT = val & DPBMUNIT_CLOCK_GATE_DISABLE ? " DPBMUNIT" : "";
+    char *DPLSUNIT = val & DPLSUNIT_CLOCK_GATE_DISABLE ? " DPLSUNIT" : "";
+    char *DPLUNIT = val & DPLUNIT_CLOCK_GATE_DISABLE ? " DPLUNIT" : "";
+    char *DPOUNIT = val & DPOUNIT_CLOCK_GATE_DISABLE ? " DPOUNIT" : "";
+    char *DPBUNIT = val & DPBUNIT_CLOCK_GATE_DISABLE ? " DPBUNIT" : "";
+    char *DCUNIT = val & DCUNIT_CLOCK_GATE_DISABLE ? " DCUNIT" : "";
+    char *DPUNIT = val & DPUNIT_CLOCK_GATE_DISABLE ? " DPUNIT" : "";
+    char *VRUNIT = val & VRUNIT_CLOCK_GATE_DISABLE ? " VRUNIT" : "";
+    char *OVHUNIT = val & OVHUNIT_CLOCK_GATE_DISABLE ? " OVHUNIT" : "";
+    char *DPIOUNIT = val & DPIOUNIT_CLOCK_GATE_DISABLE ? " DPIOUNIT" : "";
+    char *OVFUNIT = val & OVFUNIT_CLOCK_GATE_DISABLE ? " OVFUNIT" : "";
+    char *OVBUNIT = val & OVBUNIT_CLOCK_GATE_DISABLE ? " OVBUNIT" : "";
+    char *OVRUNIT = val & OVRUNIT_CLOCK_GATE_DISABLE ? " OVRUNIT" : "";
+    char *OVCUNIT = val & OVCUNIT_CLOCK_GATE_DISABLE ? " OVCUNIT" : "";
+    char *OVUUNIT = val & OVUUNIT_CLOCK_GATE_DISABLE ? " OVUUNIT" : "";
+    char *OVLUNIT = val & OVLUNIT_CLOCK_GATE_DISABLE ? " OVLUNIT" : "";
+
+    return XNFprintf ("clock gates disabled:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+		      DPUNIT_B,
+		      VSUNIT,
+		      VRHUNIT,
+		      VRDUNIT,
+		      AUDUNIT,
+		      DPUNIT_A,
+		      DPCUNIT,
+		      TVRUNIT,
+		      TVCUNIT,
+		      TVFUNIT,
+		      TVEUNIT,
+		      DVSUNIT,
+		      DSSUNIT,
+		      DDBUNIT,
+		      DPRUNIT,
+		      DPFUNIT,
+		      DPBMUNIT,
+		      DPLSUNIT,
+		      DPLUNIT,
+		      DPOUNIT,
+		      DPBUNIT,
+		      DCUNIT,
+		      DPUNIT,
+		      VRUNIT,
+		      OVHUNIT,
+		      DPIOUNIT,
+		      OVFUNIT,
+		      OVBUNIT,
+		      OVRUNIT,
+		      OVCUNIT,
+		      OVUUNIT,
+		      OVLUNIT);
+}
+
 #if 0
 DEBUGSTRING(i810_debug_fence_new)
 {
@@ -369,7 +494,7 @@ static struct i830SnapshotRec {
     DEFINEREG2(VCLK_POST_DIV, i830_debug_vga_pd),
     DEFINEREG2(DPLL_TEST, i830_debug_dpll_test),
     DEFINEREG(D_STATE),
-    DEFINEREG(DSPCLK_GATE_D),
+    DEFINEREG2(DSPCLK_GATE_D, i830_debug_dspclk_gate_d),
     DEFINEREG(RENCLK_GATE_D1),
     DEFINEREG(RENCLK_GATE_D2),
 /*  DEFINEREG(RAMCLK_GATE_D),	CRL only */
@@ -408,6 +533,7 @@ static struct i830SnapshotRec {
     DEFINEREG(DSPATILEOFF),
     DEFINEREG2(PIPEACONF, i830_debug_pipeconf),
     DEFINEREG2(PIPEASRC, i830_debug_yxminus1),
+    DEFINEREG2(PIPEASTAT, i830_debug_pipestat),
 
     DEFINEREG(FBC_CFB_BASE),
     DEFINEREG(FBC_LL_BASE),
@@ -440,6 +566,7 @@ static struct i830SnapshotRec {
     DEFINEREG(DSPBTILEOFF),
     DEFINEREG2(PIPEBCONF, i830_debug_pipeconf),
     DEFINEREG2(PIPEBSRC, i830_debug_yxminus1),
+    DEFINEREG2(PIPEBSTAT, i830_debug_pipestat),
 
     DEFINEREG2(FPB0, i830_debug_fp),
     DEFINEREG2(FPB1, i830_debug_fp),
@@ -494,6 +621,11 @@ static struct i830SnapshotRec {
     DEFINEREG(TV_H_CHROMA_0),
     DEFINEREG(TV_H_CHROMA_59),
 
+    DEFINEREG(MI_MODE),
+    DEFINEREG(MI_DISPLAY_POWER_DOWN),
+    DEFINEREG(MI_ARB_STATE),
+    DEFINEREG(MI_RDRET_STATE),
+    DEFINEREG(ECOSKPD),
 #if 0
     DEFINEREG2(FENCE_NEW + 0, i810_debug_fence_new),
     DEFINEREG2(FENCE_NEW + 8, i810_debug_fence_new),
commit b85c0992938e85e2228e69a3d9bfdd14958c0f4f
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Fri Feb 22 11:41:25 2008 -0800

    Add quirk for DVO channel selection
    
    Some machines want DVOA, some DVOB.  We can use this quirk to differentiate
    them until we come up with a better solution.  Patch from Hong Liu.
    
    Fixes #13722.

diff --git a/src/i830.h b/src/i830.h
index 05b0358..132f089 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -840,6 +840,7 @@ extern const int I830CopyROP[16];
 #define QUIRK_IGNORE_LVDS		0x00000002
 #define QUIRK_IGNORE_MACMINI_LVDS 	0x00000004
 #define QUIRK_PIPEA_FORCE		0x00000008
+#define QUIRK_IVCH_NEED_DVOB		0x00000010
 extern void i830_fixup_devices(ScrnInfoPtr);
 
 #endif /* _I830_H_ */
diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index e7342b0..81d5601 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -83,7 +83,7 @@ struct _I830DVODriver i830_dvo_drivers[] =
 	.type = I830_OUTPUT_DVO_LVDS,
 	.modulename = "ivch",
 	.fntablename = "ivch_methods",
-	.dvo_reg = DVOB,
+	.dvo_reg = DVOA,
 	.address = 0x04, /* Might also be 0x44, 0x84, 0xc4 */
 	.symbols = ivch_symbols
     },
@@ -398,6 +398,7 @@ i830_dvo_get_current_mode (xf86OutputPtr output)
 void
 i830_dvo_init(ScrnInfoPtr pScrn)
 {
+    I830Ptr pI830 = I830PTR(pScrn);
     I830OutputPrivatePtr intel_output;
     int ret;
     int i;
@@ -431,6 +432,11 @@ i830_dvo_init(ScrnInfoPtr pScrn)
 	ret_ptr = NULL;
 	drv->vid_rec = LoaderSymbol(drv->fntablename);
 
+	if (!strcmp(drv->modulename, "ivch") &&
+	    pI830->quirk_flag & QUIRK_IVCH_NEED_DVOB) {
+	    drv->dvo_reg = DVOB;
+	}
+
 	/* Allow the I2C driver info to specify the GPIO to be used in
 	 * special cases, but otherwise default to what's defined in the spec.
 	 */
diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 875bf67..e957845 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -198,6 +198,11 @@ static void quirk_lenovo_tv_dmi (I830Ptr pI830)
 	pI830->quirk_flag |= QUIRK_IGNORE_TV;
 }
 
+static void quirk_ivch_dvob (I830Ptr pI830)
+{
+	pI830->quirk_flag |= QUIRK_IVCH_NEED_DVOB;
+}
+
 /* keep this list sorted by OEM, then by chip ID */
 static i830_quirk i830_quirk_list[] = {
     /* Aopen mini pc */
@@ -230,6 +235,8 @@ static i830_quirk i830_quirk_list[] = {
 
     /* Toshiba Satellite U300 has no TV output */
     { PCI_CHIP_I965_GM, 0x1179, 0xff50, quirk_ignore_tv },
+    /* Toshiba i830M laptop (fix bug 11148) */
+    { PCI_CHIP_I830_M, 0x1179, 0xff00, quirk_ivch_dvob },
 
     /* Samsung Q35 has no TV output */
     { PCI_CHIP_I945_GM, 0x144d, 0xc504, quirk_ignore_tv },
@@ -242,6 +249,9 @@ static i830_quirk i830_quirk_list[] = {
     /* ThinkPad X40 needs pipe A force quirk */
     { PCI_CHIP_I855_GM, 0x1014, 0x0557, quirk_pipea_force },
 
+    /* Sony vaio PCG-r600HFP (fix bug 13722) */
+    { PCI_CHIP_I830_M, 0x104d, 0x8100, quirk_ivch_dvob },
+
     { 0, 0, 0, NULL },
 };
 
commit 5073b4026c536f6e5f0c8c5a741a1852b4480f31
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Tue Feb 19 21:13:45 2008 +0800

    Don't leak memory if no DMI info is provided by kernel

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 32ec9ae..875bf67 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -71,7 +71,10 @@ static void i830_dmi_store_##field(void) \
 {\
     FILE *f = NULL;\
     f = fopen(DMIID_FILE(field), "r");\
-    if (f == NULL) { i830_dmi_data[field] = NULL; return;}\
+    if (f == NULL) {\
+	xfree(i830_dmi_data[field]); i830_dmi_data[field] = NULL;\
+	return;\
+    }\
     fread(i830_dmi_data[field], 64, 1, f);\
     fclose(f);\
 }
@@ -95,7 +98,7 @@ I830_DMI_FIELD_FUNC(chassis_version);
 I830_DMI_FIELD_FUNC(chassis_serial);
 I830_DMI_FIELD_FUNC(chassis_asset_tag);
 
-static int i830_dmi_scan(void)
+static void i830_dmi_scan(void)
 {
     int i;
 
@@ -103,9 +106,11 @@ static int i830_dmi_scan(void)
 	i830_dmi_data[i] = xcalloc(64, sizeof(char));
 	if (!i830_dmi_data[i]) {
 	    int j;
-	    for (j = 0; j < i; j++)
+	    for (j = 0; j < i; j++) {
 		xfree(i830_dmi_data[j]);
-	    return -1;
+		i830_dmi_data[i] = NULL;
+	    }
+	    return;
 	}
     }
 
@@ -127,8 +132,6 @@ static int i830_dmi_scan(void)
     i830_dmi_store_chassis_version();
     i830_dmi_store_chassis_serial();
     i830_dmi_store_chassis_asset_tag();
-
-    return 0;
 }
 
 #define DMIID_DUMP(field) \
@@ -246,9 +249,9 @@ void i830_fixup_devices(ScrnInfoPtr scrn)
 {
     I830Ptr pI830 = I830PTR(scrn);
     i830_quirk_ptr p = i830_quirk_list;
-    int i, ret;
+    int i;
 
-    ret = i830_dmi_scan();
+    i830_dmi_scan();
 
     if (0)
 	i830_dmi_dump();
@@ -262,8 +265,7 @@ void i830_fixup_devices(ScrnInfoPtr scrn)
 	++p;
     }
 
-    if (!ret) {
-	for (i = 0; i < dmi_data_max; i++)
+    for (i = 0; i < dmi_data_max; i++)
+	if (i830_dmi_data[i])
 	    xfree(i830_dmi_data[i]);
-    }
 }
commit 3709962b91402027f2a73f732d1eb935f7d714b9
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Mon Feb 18 14:35:06 2008 +0800

    Fix Lenovo X60 TV quirk
    
    Z61 has same subsys ids with X60, but does have one S-video
    TV out. Use DMI info instead to quirk TV on X60, X60s.

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index de213c8..32ec9ae 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -178,6 +178,23 @@ static void quirk_mac_mini (I830Ptr pI830)
     pI830->quirk_flag |= QUIRK_IGNORE_MACMINI_LVDS;
 }
 
+static void quirk_lenovo_tv_dmi (I830Ptr pI830)
+{
+    /* X60, X60s has no TV output.
+     * Z61 has S-video TV output.
+     * And they have same subsys ids...
+     *
+     * http://www-307.ibm.com/pc/support/site.wss/MIGR-45120.html
+     * http://www.thinkwiki.org/wiki/List_of_DMI_IDs
+     */
+    if (!i830_dmi_data[bios_version]) {
+	ErrorF("Failed to load DMI info, X60 TV quirk not applied.\n");
+	return;
+    }
+    if (!strncmp(i830_dmi_data[bios_version], "7B", 2))
+	pI830->quirk_flag |= QUIRK_IGNORE_TV;
+}
+
 /* keep this list sorted by OEM, then by chip ID */
 static i830_quirk i830_quirk_list[] = {
     /* Aopen mini pc */
@@ -196,8 +213,8 @@ static i830_quirk i830_quirk_list[] = {
     /* Dell XPS 1330 */
     { PCI_CHIP_I965_GM, 0x1028, 0x0209, quirk_ignore_tv },
 
-    /* Lenovo X60s has no TV output */
-    { PCI_CHIP_I945_GM, 0x17aa, 0x201a, quirk_ignore_tv },
+    /* Lenovo Napa TV (use dmi)*/
+    { PCI_CHIP_I945_GM, 0x17aa, SUBSYS_ANY, quirk_lenovo_tv_dmi },
     /* Lenovo T61 has no TV output */
     { PCI_CHIP_I965_GM, 0x17aa, 0x20b5, quirk_ignore_tv },
     /* Lenovo 3000 v200 */
commit 866ae8873613a51ca09973f77aa1ea62477b54a1
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Mon Feb 18 14:32:32 2008 +0800

    Add DMI info for i830 quirks
    
    Linux kernel has CONFIG_DMIID to export dmi info
    through sysfs.

diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 5e63831..de213c8 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -32,6 +32,9 @@
 
 #define SUBSYS_ANY (~0)
 
+#define DMIID_DIR "/sys/class/dmi/id/"
+#define DMIID_FILE(x) (DMIID_DIR # x)
+
 typedef struct {
     int chipType;
     int subsysVendor;
@@ -39,6 +42,122 @@ typedef struct {
     void (*hook)(I830Ptr);
 } i830_quirk, *i830_quirk_ptr;
 
+enum i830_dmi_data_t {
+    bios_vendor,
+    bios_version,
+    bios_date,
+    sys_vendor,
+    product_name,
+    product_version,
+    product_serial,
+    product_uuid,
+    board_vendor,
+    board_name,
+    board_version,
+    board_serial,
+    board_asset_tag,
+    chassis_vendor,
+    chassis_type,
+    chassis_version,
+    chassis_serial,
+    chassis_asset_tag,
+    dmi_data_max,
+};
+
+static char *i830_dmi_data[dmi_data_max];
+
+#define I830_DMI_FIELD_FUNC(field) \
+static void i830_dmi_store_##field(void) \
+{\
+    FILE *f = NULL;\
+    f = fopen(DMIID_FILE(field), "r");\
+    if (f == NULL) { i830_dmi_data[field] = NULL; return;}\
+    fread(i830_dmi_data[field], 64, 1, f);\
+    fclose(f);\
+}
+
+I830_DMI_FIELD_FUNC(bios_vendor);
+I830_DMI_FIELD_FUNC(bios_version);
+I830_DMI_FIELD_FUNC(bios_date);
+I830_DMI_FIELD_FUNC(sys_vendor);
+I830_DMI_FIELD_FUNC(product_name);
+I830_DMI_FIELD_FUNC(product_version);
+I830_DMI_FIELD_FUNC(product_serial);
+I830_DMI_FIELD_FUNC(product_uuid);
+I830_DMI_FIELD_FUNC(board_vendor);
+I830_DMI_FIELD_FUNC(board_name);
+I830_DMI_FIELD_FUNC(board_version);
+I830_DMI_FIELD_FUNC(board_serial);
+I830_DMI_FIELD_FUNC(board_asset_tag);
+I830_DMI_FIELD_FUNC(chassis_vendor);
+I830_DMI_FIELD_FUNC(chassis_type);
+I830_DMI_FIELD_FUNC(chassis_version);
+I830_DMI_FIELD_FUNC(chassis_serial);
+I830_DMI_FIELD_FUNC(chassis_asset_tag);
+
+static int i830_dmi_scan(void)
+{
+    int i;
+
+    for (i = 0; i < dmi_data_max; i++) {
+	i830_dmi_data[i] = xcalloc(64, sizeof(char));
+	if (!i830_dmi_data[i]) {
+	    int j;
+	    for (j = 0; j < i; j++)
+		xfree(i830_dmi_data[j]);
+	    return -1;
+	}
+    }
+
+    i830_dmi_store_bios_vendor();
+    i830_dmi_store_bios_version();
+    i830_dmi_store_bios_date();
+    i830_dmi_store_sys_vendor();
+    i830_dmi_store_product_name();
+    i830_dmi_store_product_version();
+    i830_dmi_store_product_serial();
+    i830_dmi_store_product_uuid();
+    i830_dmi_store_board_vendor();
+    i830_dmi_store_board_name();
+    i830_dmi_store_board_version();
+    i830_dmi_store_board_serial();
+    i830_dmi_store_board_asset_tag();
+    i830_dmi_store_chassis_vendor();
+    i830_dmi_store_chassis_type();
+    i830_dmi_store_chassis_version();
+    i830_dmi_store_chassis_serial();
+    i830_dmi_store_chassis_asset_tag();
+
+    return 0;
+}
+
+#define DMIID_DUMP(field) \
+    ErrorF("\t" # field ": %s", i830_dmi_data[field] ?\
+	    i830_dmi_data[field] : "unknown")
+
+static void i830_dmi_dump(void)
+{
+    ErrorF("i830_dmi_dump:\n");
+    DMIID_DUMP(bios_vendor);
+    DMIID_DUMP(bios_version);
+    DMIID_DUMP(bios_date);
+    DMIID_DUMP(sys_vendor);
+    DMIID_DUMP(product_name);
+    DMIID_DUMP(product_version);
+    DMIID_DUMP(product_serial);
+    DMIID_DUMP(product_uuid);
+    DMIID_DUMP(board_vendor);
+    DMIID_DUMP(board_name);
+    DMIID_DUMP(board_version);
+    DMIID_DUMP(board_serial);
+    DMIID_DUMP(board_asset_tag);
+    DMIID_DUMP(chassis_vendor);
+    DMIID_DUMP(chassis_type);
+    DMIID_DUMP(chassis_version);
+    DMIID_DUMP(chassis_serial);
+    DMIID_DUMP(chassis_asset_tag);
+}
+
 static void quirk_pipea_force (I830Ptr pI830)
 {
     pI830->quirk_flag |= QUIRK_PIPEA_FORCE;
@@ -110,6 +229,12 @@ void i830_fixup_devices(ScrnInfoPtr scrn)
 {
     I830Ptr pI830 = I830PTR(scrn);
     i830_quirk_ptr p = i830_quirk_list;
+    int i, ret;
+
+    ret = i830_dmi_scan();
+
+    if (0)
+	i830_dmi_dump();
 
     while (p && p->chipType != 0) {
 	if (DEVICE_ID(pI830->PciInfo) == p->chipType &&
@@ -119,4 +244,9 @@ void i830_fixup_devices(ScrnInfoPtr scrn)
 	    p->hook(pI830);
 	++p;
     }
+
+    if (!ret) {
+	for (i = 0; i < dmi_data_max; i++)
+	    xfree(i830_dmi_data[i]);
+    }
 }


More information about the xorg-commit mailing list