diff options
Diffstat (limited to 'src')
38 files changed, 1722 insertions, 641 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index b2b08f2e..a5c036e8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,8 +30,8 @@ SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164 tfp410 $(REGDUMPER) # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ @XMODES_CFLAGS@ \ - -DI830_XV -DI830_USE_XAA -DI830_USE_EXA +AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ @PCIACCESS_CFLAGS@ \ + @XMODES_CFLAGS@ -DI830_XV -DI830_USE_XAA -DI830_USE_EXA intel_drv_la_LTLIBRARIES = intel_drv.la intel_drv_la_LDFLAGS = -module -avoid-version diff --git a/src/bios_reader/Makefile.am b/src/bios_reader/Makefile.am index 76ad15f7..c4da9573 100644 --- a/src/bios_reader/Makefile.am +++ b/src/bios_reader/Makefile.am @@ -1,4 +1,4 @@ -AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @XMODES_CFLAGS@ +AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @XMODES_CFLAGS@ @PCIACCESS_CFLAGS@ noinst_PROGRAMS = bios_reader $(BIOS_DUMPER) @@ -7,7 +7,6 @@ BIOS_DUMPER = bios_dumper bios_dumper_SOURCES = bios_dumper.c -bios_dumper_CFLAGS = $(PCIACCESS_CFLAGS) bios_dumper_LDADD = $(PCIACCESS_LIBS) endif diff --git a/src/brw_structs.h b/src/brw_structs.h index 7a18b91c..ef7906b4 100644 --- a/src/brw_structs.h +++ b/src/brw_structs.h @@ -832,9 +832,8 @@ struct brw_wm_unit_state unsigned int program_computes_depth:1; unsigned int program_uses_killpixel:1; unsigned int legacy_line_rast: 1; - unsigned int pad1:1; - unsigned int max_threads:6; - unsigned int pad2:1; + unsigned int transposed_urb_read:1; + unsigned int max_threads:7; } wm5; float global_depth_offset_constant; @@ -977,6 +976,13 @@ struct brw_surface_state unsigned int min_array_elt:9; unsigned int min_lod:4; } ss4; + + struct { + unsigned int pad:20; + unsigned int y_offset:4; + unsigned int pad2:1; + unsigned int x_offset:7; + } ss5; }; diff --git a/src/ch7017/Makefile.am b/src/ch7017/Makefile.am index 71c50853..fef4d373 100644 --- a/src/ch7017/Makefile.am +++ b/src/ch7017/Makefile.am @@ -3,7 +3,8 @@ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @WARN_CFLAGS@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ +AM_CFLAGS = @WARN_CFLAGS@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \ + @PCIACCESS_CFLAGS@ ch7017_la_LTLIBRARIES = ch7017.la ch7017_la_LDFLAGS = -module -avoid-version diff --git a/src/ch7017/ch7017.c b/src/ch7017/ch7017.c index 6fc34223..76f9cf77 100644 --- a/src/ch7017/ch7017.c +++ b/src/ch7017/ch7017.c @@ -313,7 +313,7 @@ ch7017_restore(I2CDevPtr d) ch7017_write(priv, CH7017_POWER_MANAGEMENT, priv->save_power_management); } -I830I2CVidOutputRec ch7017_methods = { +_X_EXPORT I830I2CVidOutputRec ch7017_methods = { .init = ch7017_init, .detect = ch7017_detect, .mode_valid = ch7017_mode_valid, diff --git a/src/ch7xxx/Makefile.am b/src/ch7xxx/Makefile.am index fdf6e9e5..9f936116 100644 --- a/src/ch7xxx/Makefile.am +++ b/src/ch7xxx/Makefile.am @@ -3,7 +3,8 @@ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @WARN_CFLAGS@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ +AM_CFLAGS = @WARN_CFLAGS@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \ + @PCIACCESS_CFLAGS@ ch7xxx_la_LTLIBRARIES = ch7xxx.la ch7xxx_la_LDFLAGS = -module -avoid-version diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c index da02ad24..51fa78e6 100644 --- a/src/ch7xxx/ch7xxx.c +++ b/src/ch7xxx/ch7xxx.c @@ -306,7 +306,7 @@ ch7xxx_restore(I2CDevPtr d) ch7xxx_write(dev_priv, CH7xxx_PM, dev_priv->save_PM); } -I830I2CVidOutputRec CH7xxxVidOutput = { +_X_EXPORT I830I2CVidOutputRec CH7xxxVidOutput = { .init = ch7xxx_init, .detect = ch7xxx_detect, .mode_valid = ch7xxx_mode_valid, diff --git a/src/common.h b/src/common.h index 40ea038e..09f28f88 100644 --- a/src/common.h +++ b/src/common.h @@ -298,6 +298,16 @@ extern int I810_DEBUG; #define PCI_CHIP_I815_BRIDGE 0x1130 #endif +#ifndef PCI_CHIP_I830_M +#define PCI_CHIP_I830_M 0x3577 +#define PCI_CHIP_I830_M_BRIDGE 0x3575 +#endif + +#ifndef PCI_CHIP_845_G +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_845_G_BRIDGE 0x2560 +#endif + #ifndef PCI_CHIP_I855_GM #define PCI_CHIP_I855_GM 0x3582 #define PCI_CHIP_I855_GM_BRIDGE 0x3580 @@ -339,9 +349,9 @@ extern int I810_DEBUG; #define PCI_CHIP_I945_GME_BRIDGE 0x27AC #endif -#ifndef PCI_CHIP_I965_G_1 -#define PCI_CHIP_I965_G_1 0x2982 -#define PCI_CHIP_I965_G_1_BRIDGE 0x2980 +#ifndef PCI_CHIP_G35_G +#define PCI_CHIP_G35_G 0x2982 +#define PCI_CHIP_G35_G_BRIDGE 0x2980 #endif #ifndef PCI_CHIP_I965_Q @@ -384,6 +394,11 @@ extern int I810_DEBUG; #define PCI_CHIP_Q33_G_BRIDGE 0x29D0 #endif +#ifndef PCI_CHIP_IGD_GM +#define PCI_CHIP_IGD_GM 0x2A42 +#define PCI_CHIP_IGD_GM_BRIDGE 0x2A40 +#endif + #if XSERVER_LIBPCIACCESS #define I810_MEMBASE(p,n) (p)->regions[(n)].base_addr #define VENDOR_ID(p) (p)->vendor_id @@ -415,16 +430,19 @@ extern int I810_DEBUG; #define IS_I915GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I915_GM) #define IS_I945G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_G) #define IS_I945GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_GME) +#define IS_IGD_GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IGD_GM) #define IS_I965GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME) -#define IS_I965G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_G_1 || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_Q || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I946_GZ || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME) +#define IS_I965G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G35_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_Q || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I946_GZ || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME || IS_IGD_GM(pI810)) #define IS_G33CLASS(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G33_G ||\ DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q35_G ||\ DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q33_G) #define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810) || IS_G33CLASS(pI810)) -#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810)) +#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)) +#define OVERLAY_NOPHYSICAL(pI810) (IS_G33CLASS(pI810) || IS_I965G(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/i810_driver.c b/src/i810_driver.c index a6c13ed7..53121a6a 100644 --- a/src/i810_driver.c +++ b/src/i810_driver.c @@ -144,7 +144,7 @@ static const struct pci_id_match intel_device_match[] = { INTEL_DEVICE_MATCH (PCI_CHIP_I945_GM, 0 ), INTEL_DEVICE_MATCH (PCI_CHIP_I945_GME, 0 ), INTEL_DEVICE_MATCH (PCI_CHIP_I965_G, 0 ), - INTEL_DEVICE_MATCH (PCI_CHIP_I965_G_1, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_G35_G, 0 ), INTEL_DEVICE_MATCH (PCI_CHIP_I965_Q, 0 ), INTEL_DEVICE_MATCH (PCI_CHIP_I946_GZ, 0 ), INTEL_DEVICE_MATCH (PCI_CHIP_I965_GM, 0 ), @@ -152,6 +152,7 @@ static const struct pci_id_match intel_device_match[] = { INTEL_DEVICE_MATCH (PCI_CHIP_G33_G, 0 ), INTEL_DEVICE_MATCH (PCI_CHIP_Q35_G, 0 ), INTEL_DEVICE_MATCH (PCI_CHIP_Q33_G, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_IGD_GM, 0 ), { 0, 0, 0 }, }; @@ -196,7 +197,7 @@ static SymTabRec I810Chipsets[] = { {PCI_CHIP_I945_GM, "945GM"}, {PCI_CHIP_I945_GME, "945GME"}, {PCI_CHIP_I965_G, "965G"}, - {PCI_CHIP_I965_G_1, "965G"}, + {PCI_CHIP_G35_G, "G35"}, {PCI_CHIP_I965_Q, "965Q"}, {PCI_CHIP_I946_GZ, "946GZ"}, {PCI_CHIP_I965_GM, "965GM"}, @@ -204,6 +205,7 @@ static SymTabRec I810Chipsets[] = { {PCI_CHIP_G33_G, "G33"}, {PCI_CHIP_Q35_G, "Q35"}, {PCI_CHIP_Q33_G, "Q33"}, + {PCI_CHIP_IGD_GM, "Intel Integrated Graphics Device"}, {-1, NULL} }; @@ -225,7 +227,7 @@ static PciChipsets I810PciChipsets[] = { {PCI_CHIP_I945_GM, PCI_CHIP_I945_GM, RES_SHARED_VGA}, {PCI_CHIP_I945_GME, PCI_CHIP_I945_GME, RES_SHARED_VGA}, {PCI_CHIP_I965_G, PCI_CHIP_I965_G, RES_SHARED_VGA}, - {PCI_CHIP_I965_G_1, PCI_CHIP_I965_G_1, RES_SHARED_VGA}, + {PCI_CHIP_G35_G, PCI_CHIP_G35_G, RES_SHARED_VGA}, {PCI_CHIP_I965_Q, PCI_CHIP_I965_Q, RES_SHARED_VGA}, {PCI_CHIP_I946_GZ, PCI_CHIP_I946_GZ, RES_SHARED_VGA}, {PCI_CHIP_I965_GM, PCI_CHIP_I965_GM, RES_SHARED_VGA}, @@ -233,6 +235,7 @@ static PciChipsets I810PciChipsets[] = { {PCI_CHIP_G33_G, PCI_CHIP_G33_G, RES_SHARED_VGA}, {PCI_CHIP_Q35_G, PCI_CHIP_Q35_G, RES_SHARED_VGA}, {PCI_CHIP_Q33_G, PCI_CHIP_Q33_G, RES_SHARED_VGA}, + {PCI_CHIP_IGD_GM, PCI_CHIP_IGD_GM, RES_SHARED_VGA}, {-1, -1, RES_UNDEFINED } }; @@ -788,7 +791,7 @@ I810Probe(DriverPtr drv, int flags) case PCI_CHIP_I945_GM: case PCI_CHIP_I945_GME: case PCI_CHIP_I965_G: - case PCI_CHIP_I965_G_1: + case PCI_CHIP_G35_G: case PCI_CHIP_I965_Q: case PCI_CHIP_I946_GZ: case PCI_CHIP_I965_GM: @@ -796,6 +799,7 @@ I810Probe(DriverPtr drv, int flags) case PCI_CHIP_G33_G: case PCI_CHIP_Q35_G: case PCI_CHIP_Q33_G: + case PCI_CHIP_IGD_GM: xf86SetEntitySharable(usedChips[i]); /* Allocate an entity private if necessary */ @@ -950,7 +954,7 @@ I810PreInit(ScrnInfoPtr pScrn, int flags) pScrn->monitor = pScrn->confScreen->monitor; flags24 = Support24bppFb | PreferConvert32to24 | SupportConvert32to24; - if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) { + if (!xf86SetDepthBpp(pScrn, 16, 0, 16, flags24)) { return FALSE; } else { switch (pScrn->depth) { diff --git a/src/i810_reg.h b/src/i810_reg.h index a6663a44..d5b6805e 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -290,6 +290,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # define GPIO_DATA_VAL_IN (1 << 12) # define GPIO_DATA_PULLUP_DISABLE (1 << 13) +/* GMBus registers for hardware-assisted (non-bitbanging) I2C access */ +#define GMBUS0 0x5100 +#define GMBUS1 0x5104 +#define GMBUS2 0x5108 +#define GMBUS3 0x510c +#define GMBUS4 0x5110 +#define GMBUS5 0x5120 + /* p317, 319 */ #define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */ @@ -351,6 +359,18 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define IPEIR_I965 0x2064 /* i965 */ #define IPEHR_I965 0x2068 /* i965 */ #define INST_DONE_I965 0x206c +# define I965_SF_DONE (1 << 23) +# define I965_SE_DONE (1 << 22) +# define I965_WM_DONE (1 << 21) +# define I965_TEXTURE_FETCH_DONE (1 << 14) +# define I965_SAMPLER_CACHE_DONE (1 << 12) +# define I965_FILTER_DONE (1 << 11) +# define I965_PS_DONE (1 << 9) +# define I965_CC_DONE (1 << 8) +# define I965_MAP_FILTER_DONE (1 << 7) +# define I965_MAP_L2_IDLE (1 << 6) +# define I965_CP_DONE (1 << 1) +# define I965_RING_0_ENABLE (1 << 0) #define INST_PS_I965 0x2070 /* Current active ring head address: @@ -365,7 +385,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: */ @@ -539,6 +562,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define PGETBL_SIZE_512KB (0 << 1) #define PGETBL_SIZE_256KB (1 << 1) #define PGETBL_SIZE_128KB (2 << 1) +#define PGETBL_SIZE_1MB (3 << 1) +#define PGETBL_SIZE_2MB (4 << 1) +#define PGETBL_SIZE_1_5MB (5 << 1) #define G33_PGETBL_SIZE_MASK (3 << 8) #define G33_PGETBL_SIZE_1M (1 << 8) #define G33_PGETBL_SIZE_2M (2 << 8) @@ -973,6 +999,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 */ @@ -987,7 +1020,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 */ @@ -1992,6 +2025,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 @@ -2131,7 +2190,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define I830_GMCH_MEM_64M 0x1 #define I830_GMCH_MEM_128M 0 -#define I830_GMCH_GMS_MASK 0xF0 +#define I830_GMCH_GMS_MASK 0x70 #define I830_GMCH_GMS_DISABLED 0x00 #define I830_GMCH_GMS_LOCAL 0x10 #define I830_GMCH_GMS_STOLEN_512 0x20 @@ -2142,7 +2201,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define I830_RDRAM_ND(x) (((x) & 0x20) >> 5) #define I830_RDRAM_DDT(x) (((x) & 0x18) >> 3) -#define I855_GMCH_GMS_MASK (0x7 << 4) +#define I855_GMCH_GMS_MASK (0xF << 4) #define I855_GMCH_GMS_DISABLED 0x00 #define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) #define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) @@ -2281,6 +2340,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define BRW_STATE_SIP BRW_3D(0, 1, 2) #define BRW_PIPELINE_SELECT BRW_3D(0, 1, 4) +#define NEW_PIPELINE_SELECT BRW_3D(1, 1, 4) + #define BRW_MEDIA_STATE_POINTERS BRW_3D(2, 0, 0) #define BRW_MEDIA_OBJECT BRW_3D(2, 1, 0) @@ -2629,4 +2690,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 */ @@ -40,6 +40,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define I830DEBUG #endif +#include <stdint.h> + #ifndef REMAP_RESERVED #define REMAP_RESERVED 0 #endif @@ -626,6 +628,7 @@ typedef struct _I830Rec { CARD32 saveFBC_LL_BASE; CARD32 saveFBC_CONTROL2; CARD32 saveFBC_CONTROL; + CARD32 saveFBC_FENCE_OFF; enum last_3d *last_3d; @@ -705,7 +708,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); @@ -850,6 +855,8 @@ extern const int I830CopyROP[16]; #define QUIRK_IGNORE_TV 0x00000001 #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_accel.c b/src/i830_accel.c index 7501c2b7..fdc713be 100644 --- a/src/i830_accel.c +++ b/src/i830_accel.c @@ -173,6 +173,9 @@ I830Sync(ScrnInfoPtr pScrn) if (I810_DEBUG & (DEBUG_VERBOSE_ACCEL | DEBUG_VERBOSE_SYNC)) ErrorF("I830Sync\n"); + if (pI830->noAccel) + return; + #ifdef XF86DRI /* VT switching tries to do this. */ diff --git a/src/i830_crt.c b/src/i830_crt.c index cd71dc59..82a774aa 100644 --- a/src/i830_crt.c +++ b/src/i830_crt.c @@ -380,6 +380,7 @@ i830_crt_detect(xf86OutputPtr output) out: i830ReleaseLoadDetectPipe (output, dpms_mode); + return status; } diff --git a/src/i830_debug.c b/src/i830_debug.c index 8f8ef9bb..f589de73 100644 --- a/src/i830_debug.c +++ b/src/i830_debug.c @@ -25,6 +25,8 @@ * */ +#include <inttypes.h> + #ifdef REG_DUMPER #include "reg_dumper/reg_dumper.h" @@ -86,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, @@ -191,7 +248,11 @@ DEBUGSTRING(i830_debug_dpll) mode = "LVDS"; p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> DPLL_FPA01_P1_POST_DIV_SHIFT); - p2 = 14; + if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) + p2 = 7; + else + p2 = 14; + } else { mode = "DAC/serial"; if (val & PLL_P1_DIVIDE_BY_TWO) { @@ -334,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) { @@ -362,8 +493,9 @@ 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), - 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 */ @@ -402,6 +534,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), @@ -434,6 +567,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), @@ -488,6 +622,11 @@ static struct i830SnapshotRec { DEFINEREG(TV_H_CHROMA_0), DEFINEREG(TV_H_CHROMA_59), + DEFINEREG(MI_MODE), + /* DEFINEREG(MI_DISPLAY_POWER_DOWN), CRL only */ + 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), @@ -595,6 +734,7 @@ static void i830DumpAR(ScrnInfoPtr pScrn) } INREG8(st01); OUTREG8(0x3c0, orig_arx); + INREG8(st01); /* switch back to index mode */ } void i830DumpRegs (ScrnInfoPtr pScrn) @@ -689,6 +829,19 @@ void i830DumpRegs (ScrnInfoPtr pScrn) xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "p1 out of range\n"); break; } + + switch ((dpll >> 13) & 0x3) { + case 0: + ref = 96000; + break; + case 3: + ref = 100000; + break; + default: + ref = 0; + xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "ref out of range\n"); + break; + } } else { @@ -726,18 +879,19 @@ void i830DumpRegs (ScrnInfoPtr pScrn) else p1 = ((dpll >> 16) & 0x3f) + 2; } - } - switch ((dpll >> 13) & 0x3) { - case 0: - ref = 96000; - break; - case 3: - ref = 100000; - break; - default: - ref = 0; - xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "ref out of range\n"); - break; + + switch ((dpll >> 13) & 0x3) { + case 0: + ref = 48000; + break; + case 3: + ref = 66000; + break; + default: + ref = 0; + xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "ref out of range\n"); + break; + } } if (IS_I965G(pI830)) { phase = (dpll >> 9) & 0xf; @@ -786,8 +940,8 @@ i830_dump_ring(ScrnInfoPtr pScrn) mask = pI830->LpRing->tail_mask; virt = pI830->LpRing->virtual_start; - ErrorF ("Ring at virtual 0x%x head 0x%x tail 0x%x count %d\n", - (unsigned int) virt, head, tail, (((tail + mask + 1) - head) & mask) >> 2); + ErrorF ("Ring at virtual %p head 0x%x tail 0x%x count %d\n", + virt, head, tail, (((tail + mask + 1) - head) & mask) >> 2); for (ring = (head - 128) & mask; ring != ((head + 4) & mask); ring = (ring + 4) & mask) { @@ -803,25 +957,25 @@ 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("pgetbl_ctl: 0x%" PRIx32 "getbl_err: 0x%" PRIx32 "\n", + INREG(PGETBL_CTL), INREG(PGE_ERR)); - ErrorF("ipeir: %lx iphdr: %lx\n", (unsigned long)INREG(IPEIR), - (unsigned long)INREG(IPEHR)); + ErrorF("ipeir: %" PRIx32 " iphdr: %" PRIx32 "\n", INREG(IPEIR), + 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("LP ring tail: %" PRIx32 " head: %" PRIx32 " len: %" PRIx32 " start %" PRIx32 "\n", + INREG(LP_RING + RING_TAIL), + INREG(LP_RING + RING_HEAD) & HEAD_ADDR, + INREG(LP_RING + RING_LEN), + 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("memmode: %" PRIx32 " instps: %" PRIx32 "\n", INREG(MEMMODE), + INREG(INST_PS)); ErrorF("hwstam: %x ier: %x imr: %x iir: %x\n", INREG16(HWSTAM), INREG16(IER), INREG16(IMR), INREG16(IIR)); @@ -833,12 +987,12 @@ i965_dump_error_state(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n", + ErrorF("pgetbl_ctl: 0x%" PRIx32 " pgetbl_err: 0x%" PRIx32 "\n", INREG(PGETBL_CTL), INREG(PGE_ERR)); - ErrorF("ipeir: %lx iphdr: %lx\n", INREG(IPEIR_I965), INREG(IPEHR_I965)); + ErrorF("ipeir: %" PRIx32 " iphdr: %" PRIx32 "\n", INREG(IPEIR_I965), INREG(IPEHR_I965)); - ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n", + ErrorF("LP ring tail: %" PRIx32 " head: %" PRIx32 " len: %" PRIx32 " start %" PRIx32 "\n", INREG(LP_RING + RING_TAIL), INREG(LP_RING + RING_HEAD) & HEAD_ADDR, INREG(LP_RING + RING_LEN), INREG(LP_RING + RING_START)); @@ -850,15 +1004,15 @@ i965_dump_error_state(ScrnInfoPtr pScrn) (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("memmode: %" PRIx32 " instps: %" PRIx32 "\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("acthd: %" PRIx32 " dma_fadd_p: %" PRIx32 "\n", INREG(ACTHD), INREG(DMA_FADD_P)); + ErrorF("ecoskpd: %" PRIx32 " excc: %" PRIx32 "\n", INREG(ECOSKPD), INREG(EXCC)); ErrorF("cache_mode: %x/%x\n", (int)INREG(CACHE_MODE_0), (int)INREG(CACHE_MODE_1)); diff --git a/src/i830_display.c b/src/i830_display.c index 0e426249..ea6d067d 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -529,36 +529,6 @@ i830_display_tiled(xf86CrtcPtr crtc) return FALSE; } -static Bool -i830_use_fb_compression(xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - int plane = (intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB); - - if (!pI830->fb_compression) - return FALSE; - - if (!i830_display_tiled(crtc)) - return FALSE; - - /* Pre-965 only supports plane A */ - if (!IS_I965GM(pI830) && plane != FBC_CTL_PLANEA) - return FALSE; - - /* Need 15, 16, or 32 (w/alpha) pixel format */ - if (!(pScrn->bitsPerPixel == 16 || /* covers 15 bit mode as well */ - pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */ - return FALSE; - - /* - * No checks for pixel multiply, incl. horizontal, or interlaced modes - * since they're currently unused. - */ - return TRUE; -} - /* * Several restrictions: * - DSP[AB]CNTR - no line duplication && no pixel multiplier @@ -571,9 +541,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); @@ -608,8 +580,9 @@ i830_enable_fb_compression(xf86CrtcPtr crtc) i830WaitForVblank(pScrn); OUTREG(FBC_CFB_BASE, pI830->compressed_front_buffer->bus_addr); OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr + 6); - OUTREG(FBC_CONTROL2, FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_FULL | + OUTREG(FBC_CONTROL2, FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | FBC_CTL_CPU_FENCE | plane); + OUTREG(FBC_FENCE_OFF, crtc->y); /* Zero buffers */ memset(pI830->FbBase + pI830->compressed_front_buffer->offset, 0, @@ -629,8 +602,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 +624,131 @@ 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); +} + +static Bool +i830_use_fb_compression(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + I830Ptr pI830 = I830PTR(pScrn); + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + int plane = (intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB); + int i, count = 0; + + /* Only available on one pipe at a time */ + for (i = 0; i < xf86_config->num_crtc; i++) { + if (xf86_config->crtc[i]->enabled) + count++; + } + + /* Here we disable it to catch one->two pipe enabled configs */ + if (count > 1) { + if (i830_fb_compression_supported(pI830)) + i830_disable_fb_compression(crtc); + return FALSE; + } + + if (!pI830->fb_compression) + return FALSE; + + if (!i830_display_tiled(crtc)) + return FALSE; + + /* Pre-965 only supports plane A */ + if (!IS_I965GM(pI830) && plane != FBC_CTL_PLANEA) + return FALSE; + + /* Need 15, 16, or 32 (w/alpha) pixel format */ + if (!(pScrn->bitsPerPixel == 16 || /* covers 15 bit mode as well */ + pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */ + return FALSE; + + /* + * No checks for pixel multiply, incl. horizontal, or interlaced modes + * since they're currently unused. + */ + return TRUE; +} + /** * Sets the power management mode of the pipe and plane. * @@ -724,6 +825,10 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) /* Give the overlay scaler a chance to disable if it's on this pipe */ i830_crtc_dpms_video(crtc, FALSE); + /* May need to leave pipe A on */ + if ((pipe == 0) && (pI830->quirk_flag & QUIRK_PIPEA_FORCE)) + return; + /* Disable the VGA plane that we never use */ OUTREG(VGACNTRL, VGA_DISP_DISABLE); @@ -1171,7 +1276,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, if (!xf86ModesEqual(mode, adjusted_mode)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Adjusted mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); - xf86PrintModeline(pScrn->scrnIndex, mode); + xf86PrintModeline(pScrn->scrnIndex, adjusted_mode); } i830PrintPll("chosen", &clock); } @@ -1338,6 +1443,7 @@ i830_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height) "Couldn't allocate shadow memory for rotated CRTC\n"); return NULL; } + memset(pI830->FbBase + intel_crtc->rotate_mem->offset, 0, size); return pI830->FbBase + intel_crtc->rotate_mem->offset; } @@ -1618,7 +1724,12 @@ i830_crtc_clock_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc) if (is_lvds) { clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> DPLL_FPA01_P1_POST_DIV_SHIFT); - clock.p2 = 14; + + /* if LVDS is dual-channel, p2 = 7 */ + if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) + clock.p2 = 7; + else + clock.p2 = 14; if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) i8xx_clock(66000, &clock); /* XXX: might not be 66MHz */ diff --git a/src/i830_dri.c b/src/i830_dri.c index f52a7c3d..141b970f 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 (IS_G33CLASS(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 1b0d07ab..41362d94 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -241,7 +241,7 @@ static SymTabRec I830Chipsets[] = { {PCI_CHIP_I945_GM, "945GM"}, {PCI_CHIP_I945_GME, "945GME"}, {PCI_CHIP_I965_G, "965G"}, - {PCI_CHIP_I965_G_1, "965G"}, + {PCI_CHIP_G35_G, "G35"}, {PCI_CHIP_I965_Q, "965Q"}, {PCI_CHIP_I946_GZ, "946GZ"}, {PCI_CHIP_I965_GM, "965GM"}, @@ -249,6 +249,7 @@ static SymTabRec I830Chipsets[] = { {PCI_CHIP_G33_G, "G33"}, {PCI_CHIP_Q35_G, "Q35"}, {PCI_CHIP_Q33_G, "Q33"}, + {PCI_CHIP_IGD_GM, "Intel Integrated Graphics Device"}, {-1, NULL} }; @@ -264,7 +265,7 @@ static PciChipsets I830PciChipsets[] = { {PCI_CHIP_I945_GM, PCI_CHIP_I945_GM, RES_SHARED_VGA}, {PCI_CHIP_I945_GME, PCI_CHIP_I945_GME, RES_SHARED_VGA}, {PCI_CHIP_I965_G, PCI_CHIP_I965_G, RES_SHARED_VGA}, - {PCI_CHIP_I965_G_1, PCI_CHIP_I965_G_1, RES_SHARED_VGA}, + {PCI_CHIP_G35_G, PCI_CHIP_G35_G, RES_SHARED_VGA}, {PCI_CHIP_I965_Q, PCI_CHIP_I965_Q, RES_SHARED_VGA}, {PCI_CHIP_I946_GZ, PCI_CHIP_I946_GZ, RES_SHARED_VGA}, {PCI_CHIP_I965_GM, PCI_CHIP_I965_GM, RES_SHARED_VGA}, @@ -272,6 +273,7 @@ static PciChipsets I830PciChipsets[] = { {PCI_CHIP_G33_G, PCI_CHIP_G33_G, RES_SHARED_VGA}, {PCI_CHIP_Q35_G, PCI_CHIP_Q35_G, RES_SHARED_VGA}, {PCI_CHIP_Q33_G, PCI_CHIP_Q33_G, RES_SHARED_VGA}, + {PCI_CHIP_IGD_GM, PCI_CHIP_IGD_GM, RES_SHARED_VGA}, {-1, -1, RES_UNDEFINED} }; @@ -301,6 +303,7 @@ typedef enum { OPTION_INTELTEXPOOL, #endif OPTION_TRIPLEBUFFER, + OPTION_FORCEENABLEPIPEA, #ifdef INTEL_XVMC OPTION_XVMC, #endif @@ -326,6 +329,7 @@ static OptionInfoRec I830Options[] = { {OPTION_INTELTEXPOOL,"Legacy3D", OPTV_BOOLEAN, {0}, FALSE}, #endif {OPTION_TRIPLEBUFFER, "TripleBuffer", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_FORCEENABLEPIPEA, "ForceEnablePipeA", OPTV_BOOLEAN, {0}, FALSE}, #ifdef INTEL_XVMC {OPTION_XVMC, "XvMC", OPTV_BOOLEAN, {0}, TRUE}, #endif @@ -464,6 +468,15 @@ I830DetectMemory(ScrnInfoPtr pScrn) case PGETBL_SIZE_128KB: gtt_size = 128; break; + case PGETBL_SIZE_1MB: + gtt_size = 1024; + break; + case PGETBL_SIZE_2MB: + gtt_size = 2048; + break; + case PGETBL_SIZE_1_5MB: + gtt_size = 1024 + 512; + break; default: FatalError("Unknown GTT size value: %08x\n", (int)INREG(PGETBL_CTL)); } @@ -493,7 +506,7 @@ I830DetectMemory(ScrnInfoPtr pScrn) range = gtt_size + 4; if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + switch (gmch_ctrl & I855_GMCH_GMS_MASK) { case I855_GMCH_GMS_STOLEN_1M: memsize = MB(1) - KB(range); break; @@ -518,11 +531,11 @@ I830DetectMemory(ScrnInfoPtr pScrn) memsize = MB(64) - KB(range); break; case G33_GMCH_GMS_STOLEN_128M: - if (IS_G33CLASS(pI830)) + if (IS_I9XX(pI830)) memsize = MB(128) - KB(range); break; case G33_GMCH_GMS_STOLEN_256M: - if (IS_G33CLASS(pI830)) + if (IS_I9XX(pI830)) memsize = MB(256) - KB(range); break; } @@ -608,8 +621,13 @@ I830MapMMIO(ScrnInfoPtr pScrn) if (IS_I965G(pI830)) { - gttaddr = pI830->MMIOAddr + (512 * 1024); - pI830->GTTMapSize = 512 * 1024; + if (IS_IGD_GM(pI830)) { + gttaddr = pI830->MMIOAddr + MB(2); + pI830->GTTMapSize = MB(2); + } else { + gttaddr = pI830->MMIOAddr + KB(512); + pI830->GTTMapSize = KB(512); + } } else { @@ -1029,6 +1047,211 @@ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode) pI830->writeControl(pI830, GRX, 0x18, gr18); } +static Bool +i830_detect_chipset(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + MessageType from = X_PROBED; + const char *chipname; + uint32_t capid; + int fb_bar, mmio_bar; + + switch (DEVICE_ID(pI830->PciInfo)) { + case PCI_CHIP_I830_M: + chipname = "830M"; + break; + case PCI_CHIP_845_G: + chipname = "845G"; + break; + case PCI_CHIP_I855_GM: + /* Check capid register to find the chipset variant */ +#if XSERVER_LIBPCIACCESS + pci_device_cfg_read_u32 (pI830->PciInfo, &capid, I85X_CAPID); +#else + capid = pciReadLong (pI830->PciTag, I85X_CAPID); +#endif + pI830->variant = (capid >> I85X_VARIANT_SHIFT) & I85X_VARIANT_MASK; + switch (pI830->variant) { + case I855_GM: + chipname = "855GM"; + break; + case I855_GME: + chipname = "855GME"; + break; + case I852_GM: + chipname = "852GM"; + break; + case I852_GME: + chipname = "852GME"; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Unknown 852GM/855GM variant: 0x%x)\n", pI830->variant); + chipname = "852GM/855GM (unknown variant)"; + break; + } + break; + case PCI_CHIP_I865_G: + chipname = "865G"; + break; + case PCI_CHIP_I915_G: + chipname = "915G"; + break; + case PCI_CHIP_E7221_G: + chipname = "E7221 (i915)"; + break; + case PCI_CHIP_I915_GM: + chipname = "915GM"; + break; + case PCI_CHIP_I945_G: + chipname = "945G"; + break; + case PCI_CHIP_I945_GM: + chipname = "945GM"; + break; + case PCI_CHIP_I945_GME: + chipname = "945GME"; + break; + case PCI_CHIP_I965_G: + chipname = "965G"; + break; + case PCI_CHIP_G35_G: + chipname = "G35"; + break; + case PCI_CHIP_I965_Q: + chipname = "965Q"; + break; + case PCI_CHIP_I946_GZ: + chipname = "946GZ"; + break; + case PCI_CHIP_I965_GM: + chipname = "965GM"; + break; + case PCI_CHIP_I965_GME: + chipname = "965GME/GLE"; + break; + case PCI_CHIP_G33_G: + chipname = "G33"; + break; + case PCI_CHIP_Q35_G: + chipname = "Q35"; + break; + case PCI_CHIP_Q33_G: + chipname = "Q33"; + break; + case PCI_CHIP_IGD_GM: + chipname = "Intel Integrated Graphics Device"; + break; + default: + chipname = "unknown chipset"; + break; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Integrated Graphics Chipset: Intel(R) %s\n", chipname); + + /* Set the Chipset and ChipRev, allowing config file entries to override. */ + if (pI830->pEnt->device->chipset && *pI830->pEnt->device->chipset) { + pScrn->chipset = pI830->pEnt->device->chipset; + from = X_CONFIG; + } else if (pI830->pEnt->device->chipID >= 0) { + pScrn->chipset = (char *)xf86TokenToString(I830Chipsets, + pI830->pEnt->device->chipID); + from = X_CONFIG; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", + pI830->pEnt->device->chipID); + DEVICE_ID(pI830->PciInfo) = pI830->pEnt->device->chipID; + } else { + from = X_PROBED; + pScrn->chipset = (char *)xf86TokenToString(I830Chipsets, + DEVICE_ID(pI830->PciInfo)); + } + + if (pI830->pEnt->device->chipRev >= 0) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", + pI830->pEnt->device->chipRev); + } + + xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", + (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i8xx"); + + /* Now that we know the chipset, figure out the resource base addrs */ + if (IS_I9XX(pI830)) { + fb_bar = 2; + mmio_bar = 0; + } else { + fb_bar = 0; + mmio_bar = 1; + } + + if (pI830->pEnt->device->MemBase != 0) { + pI830->LinearAddr = pI830->pEnt->device->MemBase; + from = X_CONFIG; + } else { + pI830->LinearAddr = I810_MEMBASE (pI830->PciInfo, fb_bar); + if (pI830->LinearAddr == 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No valid FB address in PCI config space\n"); + PreInitCleanup(pScrn); + return FALSE; + } + } + + xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", + (unsigned long)pI830->LinearAddr); + + if (pI830->pEnt->device->IOBase != 0) { + pI830->MMIOAddr = pI830->pEnt->device->IOBase; + from = X_CONFIG; + } else { + pI830->MMIOAddr = I810_MEMBASE (pI830->PciInfo, mmio_bar); + if (pI830->MMIOAddr == 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No valid MMIO address in PCI config space\n"); + PreInitCleanup(pScrn); + return FALSE; + } + } + + xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n", + (unsigned long)pI830->MMIOAddr); + + /* Now figure out mapsize on 8xx chips */ + if (IS_I830(pI830) || IS_845G(pI830)) { +#if XSERVER_LIBPCIACCESS + uint16_t gmch_ctrl; + struct pci_device *bridge; + + bridge = intel_host_bridge (); + pci_device_cfg_read_u16 (bridge, &gmch_ctrl, I830_GMCH_CTRL); +#else + PCITAG bridge; + CARD16 gmch_ctrl; + + bridge = pciTag(0, 0, 0); /* This is always the host bridge */ + gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL); +#endif + if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { + pI830->FbMapSize = 0x8000000; + } else { + pI830->FbMapSize = 0x4000000; /* 64MB - has this been tested ?? */ + } + } else { + if (IS_I9XX(pI830)) { +#if XSERVER_LIBPCIACCESS + pI830->FbMapSize = pI830->PciInfo->regions[fb_bar].size; +#else + pI830->FbMapSize = 1UL << pciGetBaseSize(pI830->PciTag, 2, TRUE, + NULL); +#endif + } else { + /* 128MB aperture for later i8xx series. */ + pI830->FbMapSize = 0x8000000; + } + } + + return TRUE; +} + /** * This is called per zaphod head (so usually just once) to do initialization * before the Screen is created. @@ -1050,11 +1273,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) int i; char *s; pointer pVBEModule = NULL; - const char *chipname; int num_pipe; int max_width, max_height; - uint32_t capid; - int fb_bar, mmio_bar; if (pScrn->numEntities != 1) return FALSE; @@ -1188,164 +1408,14 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->debug_modes = FALSE; } + if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE)) + pI830->quirk_flag |= QUIRK_PIPEA_FORCE; + /* We have to use PIO to probe, because we haven't mapped yet. */ I830SetPIOAccess(pI830); - switch (DEVICE_ID(pI830->PciInfo)) { - case PCI_CHIP_I830_M: - chipname = "830M"; - break; - case PCI_CHIP_845_G: - chipname = "845G"; - break; - case PCI_CHIP_I855_GM: - /* Check capid register to find the chipset variant */ -#if XSERVER_LIBPCIACCESS - pci_device_cfg_read_u32 (pI830->PciInfo, &capid, I85X_CAPID); -#else - capid = pciReadLong (pI830->PciTag, I85X_CAPID); -#endif - pI830->variant = (capid >> I85X_VARIANT_SHIFT) & I85X_VARIANT_MASK; - switch (pI830->variant) { - case I855_GM: - chipname = "855GM"; - break; - case I855_GME: - chipname = "855GME"; - break; - case I852_GM: - chipname = "852GM"; - break; - case I852_GME: - chipname = "852GME"; - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Unknown 852GM/855GM variant: 0x%x)\n", pI830->variant); - chipname = "852GM/855GM (unknown variant)"; - break; - } - break; - case PCI_CHIP_I865_G: - chipname = "865G"; - break; - case PCI_CHIP_I915_G: - chipname = "915G"; - break; - case PCI_CHIP_E7221_G: - chipname = "E7221 (i915)"; - break; - case PCI_CHIP_I915_GM: - chipname = "915GM"; - break; - case PCI_CHIP_I945_G: - chipname = "945G"; - break; - case PCI_CHIP_I945_GM: - chipname = "945GM"; - break; - case PCI_CHIP_I945_GME: - chipname = "945GME"; - break; - case PCI_CHIP_I965_G: - case PCI_CHIP_I965_G_1: - chipname = "965G"; - break; - case PCI_CHIP_I965_Q: - chipname = "965Q"; - break; - case PCI_CHIP_I946_GZ: - chipname = "946GZ"; - break; - case PCI_CHIP_I965_GM: - chipname = "965GM"; - break; - case PCI_CHIP_I965_GME: - chipname = "965GME/GLE"; - break; - case PCI_CHIP_G33_G: - chipname = "G33"; - break; - case PCI_CHIP_Q35_G: - chipname = "Q35"; - break; - case PCI_CHIP_Q33_G: - chipname = "Q33"; - break; - default: - chipname = "unknown chipset"; - break; - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Integrated Graphics Chipset: Intel(R) %s\n", chipname); - - /* Set the Chipset and ChipRev, allowing config file entries to override. */ - if (pI830->pEnt->device->chipset && *pI830->pEnt->device->chipset) { - pScrn->chipset = pI830->pEnt->device->chipset; - from = X_CONFIG; - } else if (pI830->pEnt->device->chipID >= 0) { - pScrn->chipset = (char *)xf86TokenToString(I830Chipsets, - pI830->pEnt->device->chipID); - from = X_CONFIG; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", - pI830->pEnt->device->chipID); - DEVICE_ID(pI830->PciInfo) = pI830->pEnt->device->chipID; - } else { - from = X_PROBED; - pScrn->chipset = (char *)xf86TokenToString(I830Chipsets, - DEVICE_ID(pI830->PciInfo)); - } - - if (pI830->pEnt->device->chipRev >= 0) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", - pI830->pEnt->device->chipRev); - } - - xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", - (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i8xx"); - - if (IS_I9XX(pI830)) - { - fb_bar = 2; - mmio_bar = 0; - } - else - { - fb_bar = 0; - mmio_bar = 1; - } - - if (pI830->pEnt->device->MemBase != 0) { - pI830->LinearAddr = pI830->pEnt->device->MemBase; - from = X_CONFIG; - } else { - pI830->LinearAddr = I810_MEMBASE (pI830->PciInfo, fb_bar); - if (pI830->LinearAddr == 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid FB address in PCI config space\n"); - PreInitCleanup(pScrn); - return FALSE; - } - } - - xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", - (unsigned long)pI830->LinearAddr); - - if (pI830->pEnt->device->IOBase != 0) { - pI830->MMIOAddr = pI830->pEnt->device->IOBase; - from = X_CONFIG; - } else { - pI830->MMIOAddr = I810_MEMBASE (pI830->PciInfo, mmio_bar); - if (pI830->MMIOAddr == 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid MMIO address in PCI config space\n"); - PreInitCleanup(pScrn); - return FALSE; - } - } - - xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n", - (unsigned long)pI830->MMIOAddr); + if (!i830_detect_chipset(pScrn)) + return FALSE; /* check quirks */ i830_fixup_devices(pScrn); @@ -1365,39 +1435,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) } xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height); - if (IS_I830(pI830) || IS_845G(pI830)) { -#if XSERVER_LIBPCIACCESS - uint16_t gmch_ctrl; - struct pci_device *bridge; - - bridge = intel_host_bridge (); - pci_device_cfg_read_u16 (bridge, &gmch_ctrl, I830_GMCH_CTRL); -#else - PCITAG bridge; - CARD16 gmch_ctrl; - - bridge = pciTag(0, 0, 0); /* This is always the host bridge */ - gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL); -#endif - if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { - pI830->FbMapSize = 0x8000000; - } else { - pI830->FbMapSize = 0x4000000; /* 64MB - has this been tested ?? */ - } - } else { - if (IS_I9XX(pI830)) { -#if XSERVER_LIBPCIACCESS - pI830->FbMapSize = pI830->PciInfo->regions[fb_bar].size; -#else - pI830->FbMapSize = 1UL << pciGetBaseSize(pI830->PciTag, 2, TRUE, - NULL); -#endif - } else { - /* 128MB aperture for later i8xx series. */ - pI830->FbMapSize = 0x8000000; - } - } - /* Some of the probing needs MMIO access, so map it here. */ I830MapMMIO(pScrn); @@ -1923,6 +1960,7 @@ SaveHWState(ScrnInfoPtr pScrn) pI830->saveFBC_LL_BASE = INREG(FBC_LL_BASE); pI830->saveFBC_CONTROL2 = INREG(FBC_CONTROL2); pI830->saveFBC_CONTROL = INREG(FBC_CONTROL); + pI830->saveFBC_FENCE_OFF = INREG(FBC_FENCE_OFF); } /* Save video mode information for native mode-setting. */ @@ -2110,12 +2148,14 @@ RestoreHWState(ScrnInfoPtr pScrn) * enabled if pipe A is actually on (otherwise we have a bug in the initial * state). */ - if (pI830->saveDSPACNTR & DISPPLANE_SEL_PIPE_A) { + if ((pI830->saveDSPACNTR & DISPPLANE_SEL_PIPE_MASK) == + DISPPLANE_SEL_PIPE_A) { OUTREG(DSPACNTR, pI830->saveDSPACNTR); OUTREG(DSPABASE, INREG(DSPABASE)); i830WaitForVblank(pScrn); } - if (pI830->saveDSPBCNTR & DISPPLANE_SEL_PIPE_A) { + if ((pI830->saveDSPBCNTR & DISPPLANE_SEL_PIPE_MASK) == + DISPPLANE_SEL_PIPE_A) { OUTREG(DSPBCNTR, pI830->saveDSPBCNTR); OUTREG(DSPBBASE, INREG(DSPBBASE)); i830WaitForVblank(pScrn); @@ -2167,12 +2207,14 @@ RestoreHWState(ScrnInfoPtr pScrn) * Note that pipe B may be disabled, and in that case, the plane * should also be disabled or we must have had a bad initial state. */ - if (pI830->saveDSPACNTR & DISPPLANE_SEL_PIPE_B) { + if ((pI830->saveDSPACNTR & DISPPLANE_SEL_PIPE_MASK) == + DISPPLANE_SEL_PIPE_B) { OUTREG(DSPACNTR, pI830->saveDSPACNTR); OUTREG(DSPABASE, INREG(DSPABASE)); i830WaitForVblank(pScrn); } - if (pI830->saveDSPBCNTR & DISPPLANE_SEL_PIPE_B) { + if ((pI830->saveDSPBCNTR & DISPPLANE_SEL_PIPE_MASK) == + DISPPLANE_SEL_PIPE_B) { OUTREG(DSPBCNTR, pI830->saveDSPBCNTR); OUTREG(DSPBBASE, INREG(DSPBBASE)); i830WaitForVblank(pScrn); @@ -2203,6 +2245,7 @@ RestoreHWState(ScrnInfoPtr pScrn) if (pI830->fb_compression) { OUTREG(FBC_CFB_BASE, pI830->saveFBC_CFB_BASE); OUTREG(FBC_LL_BASE, pI830->saveFBC_LL_BASE); + OUTREG(FBC_FENCE_OFF, pI830->saveFBC_FENCE_OFF); OUTREG(FBC_CONTROL2, pI830->saveFBC_CONTROL2); OUTREG(FBC_CONTROL, pI830->saveFBC_CONTROL); } @@ -2344,11 +2387,191 @@ I830BlockHandler(int i, (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); + pI830->BlockHandler = pScreen->BlockHandler; pScreen->BlockHandler = I830BlockHandler; I830VideoBlockHandler(i, blockData, pTimeout, pReadmask); } +static void +i830_fixup_mtrrs(ScrnInfoPtr pScrn) +{ +#ifdef HAS_MTRR_SUPPORT + I830Ptr pI830 = I830PTR(pScrn); + int fd; + struct mtrr_gentry gentry; + struct mtrr_sentry sentry; + + if ( ( fd = open ("/proc/mtrr", O_RDONLY, 0) ) != -1 ) { + for (gentry.regnum = 0; ioctl (fd, MTRRIOC_GET_ENTRY, &gentry) == 0; + ++gentry.regnum) { + + if (gentry.size < 1) { + /* DISABLED */ + continue; + } + + /* Check the MTRR range is one we like and if not - remove it. + * The Xserver common layer will then setup the right range + * for us. + */ + if (gentry.base == pI830->LinearAddr && + gentry.size < pI830->FbMapSize) { + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Removing bad MTRR range (base 0x%lx, size 0x%x)\n", + gentry.base, gentry.size); + + sentry.base = gentry.base; + sentry.size = gentry.size; + sentry.type = gentry.type; + + if (ioctl (fd, MTRRIOC_DEL_ENTRY, &sentry) == -1) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to remove bad MTRR range\n"); + } + } + } + close(fd); + } +#endif +} + +static Bool +i830_try_memory_allocation(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + Bool tiled = pI830->tiling; + Bool dri = pI830->directRenderingEnabled; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Attempting memory allocation with %stiled buffers.\n", + tiled ? "" : "un"); + + if (!i830_allocate_2d_memory(pScrn)) + goto failed; + + if (dri && !i830_allocate_3d_memory(pScrn)) + goto failed; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%siled allocation successful.\n", + tiled ? "T" : "Unt"); + return TRUE; + +failed: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%siled allocation failed.\n", + tiled ? "T" : "Unt"); + return FALSE; +} + +/* + * Try to allocate memory in several ways: + * 1) If direct rendering is enabled, try to allocate enough memory for tiled + * surfaces by rounding up the display width to a tileable one. + * 2) If that fails or the allocations themselves fail, try again with untiled + * allocations (if this works DRI will stay enabled). + * 3) And if all else fails, disable DRI and try just 2D allocations. + * 4) Give up and fail ScreenInit. + */ +static Bool +i830_memory_init(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + int savedDisplayWidth = pScrn->displayWidth; + int i; + Bool tiled = FALSE; + + /* + * Adjust the display width to allow for front buffer tiling if possible + */ + if (pI830->tiling) { + if (IS_I965G(pI830)) { + int tile_pixels = 512 / pI830->cpp; + pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) & + ~(tile_pixels - 1); + tiled = TRUE; + } else { + /* Good pitches to allow tiling. Don't care about pitches < 1024 + * pixels. + */ + static const int pitches[] = { + 1024, + 2048, + 4096, + 8192, + 0 + }; + + for (i = 0; pitches[i] != 0; i++) { + if (pitches[i] >= pScrn->displayWidth) { + pScrn->displayWidth = pitches[i]; + tiled = TRUE; + break; + } + } + } + } + /* Set up our video memory allocator for the chosen videoRam */ + if (!i830_allocator_init(pScrn, 0, pScrn->videoRam * KB(1))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't initialize video memory allocator\n"); + PreInitCleanup(pScrn); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, + pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT, + "VideoRam: %d KB\n", pScrn->videoRam); + + if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES, + &(pI830->CacheLines))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n", + pI830->CacheLines); + } else { + pI830->CacheLines = -1; + } + + /* Tiled first if we got a good displayWidth */ + if (tiled) { + if (i830_try_memory_allocation(pScrn)) + return TRUE; + else { + i830_reset_allocations(pScrn); + pI830->tiling = FALSE; + } + } + + /* If tiling fails we have to disable page flipping & FBC */ + pScrn->displayWidth = savedDisplayWidth; + if (pI830->allowPageFlip) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Couldn't allocate tiled memory, page flipping " + "disabled\n"); + pI830->allowPageFlip = FALSE; + if (pI830->fb_compression) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Couldn't allocate tiled memory, fb compression " + "disabled\n"); + pI830->fb_compression = FALSE; + + /* Try again, but leave DRI enabled */ + if (pI830->directRenderingEnabled) { + if (i830_try_memory_allocation(pScrn)) + return TRUE; + else { + i830_reset_allocations(pScrn); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Couldn't allocate 3D memory, " + "disabling DRI.\n"); + pI830->directRenderingEnabled = FALSE; + } + } + + if (i830_try_memory_allocation(pScrn)) + return TRUE; + + return FALSE; +} + static Bool I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { @@ -2358,8 +2581,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) VisualPtr visual; I830Ptr pI8301 = NULL; unsigned long sys_mem; - int i, c; - Bool allocation_done = FALSE; + int c; MessageType from; #ifdef XF86DRI xf86CrtcConfigPtr config; @@ -2458,11 +2680,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } #ifdef XF86DRI - /* Check for appropriate bpp and module support to initialize DRI. */ - if (!I830CheckDRIAvailable(pScrn)) { - pI830->directRenderingDisabled = TRUE; - } - /* If DRI hasn't been explicitly disabled, try to initialize it. * It will be used by the memory allocator. */ @@ -2474,26 +2691,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->directRenderingEnabled = FALSE; #endif - /* Set up our video memory allocator for the chosen videoRam */ - if (!i830_allocator_init(pScrn, 0, pScrn->videoRam * KB(1))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't initialize video memory allocator\n"); - PreInitCleanup(pScrn); - return FALSE; - } - - xf86DrvMsg(pScrn->scrnIndex, - pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT, - "VideoRam: %d KB\n", pScrn->videoRam); - - if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES, - &(pI830->CacheLines))) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n", - pI830->CacheLines); - } else { - pI830->CacheLines = -1; - } - /* Enable tiling by default */ pI830->tiling = TRUE; @@ -2506,7 +2703,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } /* Enable FB compression if possible */ - if (i830_fb_compression_supported(pI830) && !IS_I965GM(pI830)) + if (i830_fb_compression_supported(pI830) && !IS_I965GM(pI830) + && !IS_IGD_GM(pI830)) pI830->fb_compression = TRUE; else pI830->fb_compression = FALSE; @@ -2550,16 +2748,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->last_3d = pI8301->last_3d; } - /* Need MMIO mapped to do GTT lookups during memory allocation. */ - I830MapMMIO(pScrn); - -#if defined(XF86DRI) - /* - * If DRI is potentially usable, check if there is enough memory available - * for it, and if there's also enough to allow tiling to be enabled. - */ - - #ifdef I830_XV /* * Set this so that the overlay allocation is factored in when @@ -2568,103 +2756,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->XvEnabled = !pI830->XvDisabled; #endif - if (pI830->directRenderingEnabled) { - int savedDisplayWidth = pScrn->displayWidth; - Bool tiled = FALSE; - - if (IS_I965G(pI830)) { - int tile_pixels = 512 / pI830->cpp; - pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) & - ~(tile_pixels - 1); - tiled = TRUE; - } else { - /* Good pitches to allow tiling. Don't care about pitches < 1024 - * pixels. - */ - static const int pitches[] = { - 1024, - 2048, - 4096, - 8192, - 0 - }; - - for (i = 0; pitches[i] != 0; i++) { - if (pitches[i] >= pScrn->displayWidth) { - pScrn->displayWidth = pitches[i]; - tiled = TRUE; - break; - } - } - } - - /* Attempt two rounds of allocation to get 2d and 3d memory to fit: - * - * 0: untiled - * 1: tiled - */ - -#define MM_TURNS 2 - for (i = 0; i < MM_TURNS; i++) { - if (!tiled && i == 0) - continue; - - if (i >= 1) { - /* For further allocations, disable tiling */ - pI830->tiling = FALSE; - pScrn->displayWidth = savedDisplayWidth; - if (pI830->allowPageFlip) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Couldn't allocate tiled memory, page flipping " - "disabled\n"); - pI830->allowPageFlip = FALSE; - if (pI830->fb_compression) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Couldn't allocate tiled memory, fb compression " - "disabled\n"); - pI830->fb_compression = FALSE; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Attempting memory allocation with %s buffers.\n", - (i & 1) ? "untiled" : "tiled"); - - if (i830_allocate_2d_memory(pScrn) && - i830_allocate_3d_memory(pScrn)) - { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Success.\n"); - if (pScrn->displayWidth != savedDisplayWidth) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Increasing the scanline pitch to allow tiling mode " - "(%d -> %d).\n", - savedDisplayWidth, pScrn->displayWidth); - } - allocation_done = TRUE; - break; - } - - i830_reset_allocations(pScrn); - } - - if (i == MM_TURNS) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Not enough video memory. Disabling DRI.\n"); - pI830->directRenderingEnabled = FALSE; - } - } -#endif - - if (!allocation_done) { - if (!i830_allocate_2d_memory(pScrn)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't allocate video memory\n"); - return FALSE; - } - allocation_done = TRUE; - } - - I830UnmapMMIO(pScrn); - if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support DRI with frame buffer width > 2048.\n"); @@ -2672,46 +2763,18 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->directRenderingEnabled = FALSE; } -#ifdef HAS_MTRR_SUPPORT - { - int fd; - struct mtrr_gentry gentry; - struct mtrr_sentry sentry; - - if ( ( fd = open ("/proc/mtrr", O_RDONLY, 0) ) != -1 ) { - for (gentry.regnum = 0; ioctl (fd, MTRRIOC_GET_ENTRY, &gentry) == 0; - ++gentry.regnum) { - - if (gentry.size < 1) { - /* DISABLED */ - continue; - } - - /* Check the MTRR range is one we like and if not - remove it. - * The Xserver common layer will then setup the right range - * for us. - */ - if (gentry.base == pI830->LinearAddr && - gentry.size < pI830->FbMapSize) { + /* Need MMIO mapped to do GTT lookups during memory allocation. */ + I830MapMMIO(pScrn); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Removing bad MTRR range (base 0x%lx, size 0x%x)\n", - gentry.base, gentry.size); + if (!i830_memory_init(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate video memory\n"); + return FALSE; + } - sentry.base = gentry.base; - sentry.size = gentry.size; - sentry.type = gentry.type; + I830UnmapMMIO(pScrn); - if (ioctl (fd, MTRRIOC_DEL_ENTRY, &sentry) == -1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to remove bad MTRR range\n"); - } - } - } - close(fd); - } - } -#endif + i830_fixup_mtrrs(pScrn); pI830->starting = TRUE; @@ -2798,7 +2861,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) * alone in that case. * Also make sure the DRM can handle the swap. */ - if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && + if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_IGD_GM(pI830) && (!pI830->directRenderingEnabled || (pI830->directRenderingEnabled && pI830->drmMinor >= 10))) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings " @@ -2923,9 +2986,25 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->directRenderingEnabled = I830DRIFinishScreenInit(pScreen); #endif + /* Must force it before EnterVT, so we are in control of VT and + * later memory should be bound when allocating, e.g rotate_mem */ + pScrn->vtSema = TRUE; + if (!I830EnterVT(scrnIndex, 0)) return FALSE; + pI830->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = I830BlockHandler; + + pScreen->SaveScreen = xf86SaveScreen; + pI830->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = I830CloseScreen; + pI830->CreateScreenResources = pScreen->CreateScreenResources; + pScreen->CreateScreenResources = i830CreateScreenResources; + + if (!xf86CrtcScreenInit (pScreen)) + return FALSE; + DPRINTF(PFX, "assert( if(!miCreateDefColormap(pScreen)) )\n"); if (!miCreateDefColormap(pScreen)) return FALSE; @@ -2962,18 +3041,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Not available\n"); #endif - pI830->BlockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = I830BlockHandler; - - pScreen->SaveScreen = xf86SaveScreen; - pI830->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = I830CloseScreen; - pI830->CreateScreenResources = pScreen->CreateScreenResources; - pScreen->CreateScreenResources = i830CreateScreenResources; - if (!xf86CrtcScreenInit (pScreen)) - return FALSE; - /* Wrap pointer motion to flip touch screen around */ pI830->PointerMoved = pScrn->PointerMoved; pScrn->PointerMoved = I830PointerMoved; @@ -3174,6 +3242,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_dvo.c b/src/i830_dvo.c index e6ff6af6..81d56012 100644 --- a/src/i830_dvo.c +++ b/src/i830_dvo.c @@ -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_i2c.c b/src/i830_i2c.c index da8f38e6..33a75a81 100644 --- a/src/i830_i2c.c +++ b/src/i830_i2c.c @@ -88,7 +88,7 @@ static void i830_getscl(I2CBusPtr b, int *state) OUTREG(b->DriverPrivate.uval, GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK); OUTREG(b->DriverPrivate.uval, 0); val = INREG(b->DriverPrivate.uval); - *state = ((val & GPIO_DATA_VAL_IN) != 0); + *state = ((val & GPIO_CLOCK_VAL_IN) != 0); } static int i830_getsda(I2CBusPtr b) @@ -346,6 +346,7 @@ Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name) { I2CBusPtr pI2CBus; + I830Ptr pI830 = I830PTR(pScrn); pI2CBus = xf86CreateI2CBusRec(); @@ -379,6 +380,12 @@ I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name) pI2CBus->AcknTimeout = 40; pI2CBus->RiseFallTime = 20; + /* Disable the GMBUS, which we won't use. If it is left enabled (for + * example, by Mac Mini EFI initialization), GPIO access to the pins it + * uses gets disabled. + */ + OUTREG(GMBUS0, 0); + if (!xf86I2CBusInit(pI2CBus)) return FALSE; diff --git a/src/i830_lvds.c b/src/i830_lvds.c index c58a7e0a..8359e39f 100644 --- a/src/i830_lvds.c +++ b/src/i830_lvds.c @@ -113,7 +113,7 @@ i830_set_lvds_backlight_method(xf86OutputPtr output) if (i830_kernel_backlight_available(output)) { method = BCM_KERNEL; - } else if (IS_I965GM(pI830)) { + } else if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) { blc_pwm_ctl2 = INREG(BLC_PWM_CTL2); if (blc_pwm_ctl2 & BLM_LEGACY_MODE2) method = BCM_LEGACY; @@ -161,7 +161,7 @@ i830_lvds_get_backlight_max_native(xf86OutputPtr output) CARD32 pwm_ctl = INREG(BLC_PWM_CTL); int val; - if (IS_I965GM(pI830)) { + if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) { val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK2) >> BACKLIGHT_MODULATION_FREQ_SHIFT2); } else { @@ -234,6 +234,12 @@ i830_lvds_set_backlight_combo(xf86OutputPtr output, int level) #endif } + /* + * Don't set the lowest bit in combo configs since it can act as a flag for + * max brightness. + */ + level <<= 1; + blc_pwm_ctl = INREG(BLC_PWM_CTL); blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); @@ -248,7 +254,17 @@ i830_lvds_get_backlight_combo(xf86OutputPtr output) blc_pwm_ctl = INREG(BLC_PWM_CTL); blc_pwm_ctl &= BACKLIGHT_DUTY_CYCLE_MASK; - return blc_pwm_ctl; + + /* Since we don't use the low bit when using combo, the value is halved */ + + return blc_pwm_ctl >> 1; +} + +static int +i830_lvds_get_backlight_max_combo(xf86OutputPtr output) +{ + /* Since we don't set the low bit when using combo, the range is halved */ + return i830_lvds_get_backlight_max_native(output) >> 1; } /* @@ -356,6 +372,17 @@ i830SetLVDSPanelPower(xf86OutputPtr output, Bool on) CARD32 pp_status; if (on) { + /* + * If we're going from off->on we may need to turn on the backlight. + * We should use the saved value whenever possible, but on some + * machines 0 is a valid backlight value (due to an external backlight + * controller for example), so on them, when turning LVDS back on, + * they'll always re-maximize the brightness. + */ + if (!(INREG(PP_CONTROL) & POWER_TARGET_ON) && + dev_priv->backlight_duty_cycle == 0) + dev_priv->backlight_duty_cycle = dev_priv->backlight_max; + OUTREG(PP_CONTROL, INREG(PP_CONTROL) | POWER_TARGET_ON); do { pp_status = INREG(PP_STATUS); @@ -397,7 +424,7 @@ i830_lvds_save (xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; I830Ptr pI830 = I830PTR(pScrn); - if (IS_I965GM(pI830)) + if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) pI830->saveBLC_PWM_CTL2 = INREG(BLC_PWM_CTL2); pI830->savePP_ON = INREG(LVDSPP_ON); pI830->savePP_OFF = INREG(LVDSPP_OFF); @@ -413,7 +440,7 @@ i830_lvds_restore(xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; I830Ptr pI830 = I830PTR(pScrn); - if (IS_I965GM(pI830)) + if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) OUTREG(BLC_PWM_CTL2, pI830->saveBLC_PWM_CTL2); OUTREG(BLC_PWM_CTL, pI830->saveBLC_PWM_CTL); OUTREG(LVDSPP_ON, pI830->savePP_ON); @@ -661,7 +688,7 @@ i830_lvds_set_backlight_control(xf86OutputPtr output) dev_priv->set_backlight = i830_lvds_set_backlight_combo; dev_priv->get_backlight = i830_lvds_get_backlight_combo; dev_priv->backlight_max = - i830_lvds_get_backlight_max_native(output); + i830_lvds_get_backlight_max_combo(output); break; case BCM_KERNEL: dev_priv->set_backlight = i830_lvds_set_backlight_kernel; @@ -824,6 +851,35 @@ i830_lvds_set_property(xf86OutputPtr output, Atom property, } #endif /* RANDR_12_INTERFACE */ +#ifdef RANDR_13_INTERFACE +static Bool +i830_lvds_get_property(xf86OutputPtr output, Atom property) +{ + ScrnInfoPtr pScrn = output->scrn; + I830Ptr pI830 = I830PTR(pScrn); + I830OutputPrivatePtr intel_output = output->driver_private; + struct i830_lvds_priv *dev_priv = intel_output->dev_priv; + int ret; + + /* + * Only need to update properties that might change out from under + * us. The others will be cached by the randr core code. + */ + if (property == backlight_atom) { + int val; + val = dev_priv->get_backlight(output); + dev_priv->backlight_duty_cycle = val; + ret = RRChangeOutputProperty(output->randr_output, backlight_atom, + XA_INTEGER, 32, PropModeReplace, 1, &val, + FALSE, TRUE); + if (ret != Success) + return FALSE; + } + + return TRUE; +} +#endif /* RANDR_13_INTERFACE */ + static const xf86OutputFuncsRec i830_lvds_output_funcs = { .create_resources = i830_lvds_create_resources, .dpms = i830_lvds_dpms, @@ -839,6 +895,9 @@ static const xf86OutputFuncsRec i830_lvds_output_funcs = { #ifdef RANDR_12_INTERFACE .set_property = i830_lvds_set_property, #endif +#ifdef RANDR_13_INTERFACE + .get_property = i830_lvds_get_property, +#endif .destroy = i830_lvds_destroy }; @@ -1003,7 +1062,7 @@ i830_lvds_init(ScrnInfoPtr pScrn) case BCM_COMBO: dev_priv->set_backlight = i830_lvds_set_backlight_combo; dev_priv->get_backlight = i830_lvds_get_backlight_combo; - dev_priv->backlight_max = i830_lvds_get_backlight_max_native(output); + dev_priv->backlight_max = i830_lvds_get_backlight_max_combo(output); break; case BCM_KERNEL: dev_priv->set_backlight = i830_lvds_set_backlight_kernel; diff --git a/src/i830_memory.c b/src/i830_memory.c index 146a46ae..ce6d7afe 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -97,8 +97,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #endif #include <assert.h> +#include <inttypes.h> #include <string.h> #include <errno.h> +#include <sys/types.h> #include <sys/mman.h> #include "xf86.h" @@ -273,12 +275,16 @@ i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem) I830Ptr pI830 = I830PTR(pScrn); drmBOUnreference(pI830->drmSubFD, &mem->bo); - if (pI830->bo_list == mem) + if (pI830->bo_list == mem) { pI830->bo_list = mem->next; - if (mem->next) - mem->next->prev = NULL; - if (mem->prev) - mem->prev->next = NULL; + if (mem->next) + mem->next->prev = NULL; + } else { + if (mem->prev) + mem->prev->next = mem->next; + if (mem->next) + mem->next->prev = mem->prev; + } xfree(mem->name); xfree(mem); return; @@ -464,10 +470,13 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size) ROUND_TO(HWCURSOR_SIZE_ARGB, GTT_PAGE_SIZE)); } if (pI830->fb_compression) - mmsize -= MB(6); + mmsize -= MB(6) + ROUND_TO_PAGE(FBC_LL_SIZE + FBC_LL_PAD); /* 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", @@ -595,8 +604,8 @@ i830_get_stolen_physical(ScrnInfoPtr pScrn, unsigned long offset, if ((scan - offset) != (scan_physical - physical)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Non-contiguous GTT entries: (%ld,0x16%llx) vs " - "(%ld,0x%16llx)\n", + "Non-contiguous GTT entries: (%ld,0x16%" PRIx64 ") vs " + "(%ld,0x%" PRIx64 ")\n", scan, scan_physical, offset, physical); return -1; } @@ -944,7 +953,7 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) if (mem->bus_addr != 0) snprintf(phys_suffix, sizeof(phys_suffix), - ", 0x%016llx physical\n", mem->bus_addr); + ", 0x%016" PRIx64 " physical\n", mem->bus_addr); if (mem->tiling == TILE_XMAJOR) tile_suffix = " X tiled"; else if (mem->tiling == TILE_YMAJOR) @@ -1035,15 +1044,13 @@ i830_allocate_overlay(ScrnInfoPtr pScrn) if (!OVERLAY_NOPHYSICAL(pI830)) flags |= NEED_PHYSICAL_ADDR; - if (!IS_I965G(pI830)) { - pI830->overlay_regs = i830_allocate_memory(pScrn, "overlay registers", - OVERLAY_SIZE, GTT_PAGE_SIZE, - flags); - if (pI830->overlay_regs == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to allocate Overlay register space.\n"); - /* This failure isn't fatal. */ - } + pI830->overlay_regs = i830_allocate_memory(pScrn, "overlay registers", + OVERLAY_SIZE, GTT_PAGE_SIZE, + flags); + if (pI830->overlay_regs == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate Overlay register space.\n"); + /* This failure isn't fatal. */ } return TRUE; @@ -1271,6 +1278,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)) { @@ -1278,11 +1292,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: @@ -1297,21 +1312,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: @@ -1630,16 +1647,20 @@ 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). */ - pI830->hw_status = i830_allocate_memory(pScrn, "G33 hw status", - HWSTATUS_PAGE_SIZE, GTT_PAGE_SIZE, NEED_LIFETIME_FIXED); + 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, flags); 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 +1673,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; } @@ -1929,7 +1950,8 @@ i830_bind_all_memory(ScrnInfoPtr pScrn) } #endif } - i830_update_cursor_offsets(pScrn); + if (!pI830->SWCursor) + i830_update_cursor_offsets(pScrn); return TRUE; } diff --git a/src/i830_quirks.c b/src/i830_quirks.c index 87d9a8a0..67202214 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,130 @@ 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) {\ + xfree(i830_dmi_data[field]); 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 void 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]); + i830_dmi_data[i] = NULL; + } + return; + } + } + + 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(); +} + +#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; +} + static void quirk_ignore_tv (I830Ptr pI830) { pI830->quirk_flag |= QUIRK_IGNORE_TV; @@ -54,37 +181,85 @@ 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; +} + +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 */ { PCI_CHIP_I945_GM, 0xa0a0, SUBSYS_ANY, quirk_ignore_lvds }, + { PCI_CHIP_I965_GM, 0xa0a0, SUBSYS_ANY, quirk_ignore_lvds }, { PCI_CHIP_I965_GM, 0x8086, 0x1999, quirk_ignore_lvds }, /* Apple Mac mini has no lvds, but macbook pro does */ { PCI_CHIP_I945_GM, 0x8086, 0x7270, quirk_mac_mini }, - + + /* Clevo M720R has no tv output */ + { PCI_CHIP_I965_GM, 0x1558, 0x0721, quirk_ignore_tv }, + /* Dell Latitude X1 */ { PCI_CHIP_I915_GM, 0x1028, 0x01a3, quirk_ignore_tv }, /* 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 */ { PCI_CHIP_I965_GM, 0x17aa, 0x3c18, quirk_ignore_tv }, - + /* Panasonic Toughbook CF-Y4 has no TV output */ { PCI_CHIP_I915_GM, 0x10f7, 0x8338, quirk_ignore_tv }, /* Panasonic Toughbook CF-Y7 has no TV output */ { PCI_CHIP_I965_GM, 0x10f7, 0x8338, quirk_ignore_tv }, - + /* 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 }, + + /* Motion Computing M1200 reported on irc */ + { PCI_CHIP_I830_M, 0x14c0, 0x0012, quirk_ivch_dvob }, /* Samsung Q35 has no TV output */ { PCI_CHIP_I945_GM, 0x144d, 0xc504, quirk_ignore_tv }, + /* Samsung Q45 has no TV output */ + { PCI_CHIP_I965_GM, 0x144d, 0xc510, quirk_ignore_tv }, + + /* HP Compaq 6730s has no TV output */ + { PCI_CHIP_IGD_GM, 0x103c, 0x30e8, quirk_ignore_tv }, + + /* Dell Latitude D500 needs pipe A force quirk */ + { PCI_CHIP_I855_GM, 0x1028, 0x0152, quirk_pipea_force }, + /* Dell Inspiron 510m needs pipe A force quirk */ + { PCI_CHIP_I855_GM, 0x1028, 0x0164, quirk_pipea_force }, + + /* 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 }, }; @@ -92,6 +267,12 @@ void i830_fixup_devices(ScrnInfoPtr scrn) { I830Ptr pI830 = I830PTR(scrn); i830_quirk_ptr p = i830_quirk_list; + int i; + + i830_dmi_scan(); + + if (0) + i830_dmi_dump(); while (p && p->chipType != 0) { if (DEVICE_ID(pI830->PciInfo) == p->chipType && @@ -101,4 +282,8 @@ void i830_fixup_devices(ScrnInfoPtr scrn) p->hook(pI830); ++p; } + + for (i = 0; i < dmi_data_max; i++) + if (i830_dmi_data[i]) + xfree(i830_dmi_data[i]); } diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c index 6b7037e2..d0c65f28 100644 --- a/src/i830_sdvo.c +++ b/src/i830_sdvo.c @@ -727,7 +727,7 @@ i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode, } /* Set the SDVO control regs. */ - if (IS_I965GM(pI830)) { + if (IS_I965G(pI830)) { sdvox = SDVO_BORDER_ENABLE; } else { sdvox = INREG(dev_priv->output_device); @@ -1100,8 +1100,10 @@ i830_sdvo_get_modes(xf86OutputPtr output) { ScrnInfoPtr pScrn = output->scrn; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - DisplayModePtr modes; + DisplayModePtr modes = NULL; xf86OutputPtr crt; + I830OutputPrivatePtr intel_output; + xf86MonPtr edid_mon = NULL; modes = i830_ddc_get_modes(output); if (modes != NULL) @@ -1113,11 +1115,17 @@ i830_sdvo_get_modes(xf86OutputPtr output) * analog when we fail at finding it the right way. */ crt = xf86_config->output[0]; - if (crt->funcs->detect(crt) == XF86OutputStatusDisconnected) { - return crt->funcs->get_modes(crt); + intel_output = crt->driver_private; + if (intel_output->type == I830_OUTPUT_ANALOG && + crt->funcs->detect(crt) == XF86OutputStatusDisconnected) { + edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus); + } + if (edid_mon) { + xf86OutputSetEDID(output, edid_mon); + modes = xf86OutputGetEDIDModes(output); } - return NULL; + return modes; } static void diff --git a/src/i830_tv.c b/src/i830_tv.c index 14f4089d..9add367a 100644 --- a/src/i830_tv.c +++ b/src/i830_tv.c @@ -580,7 +580,7 @@ const static tv_mode_t tv_modes[] = { { .name = "576p", .clock = 107520, - .refresh = 59.94, + .refresh = 50.0, .oversample = TV_OVERSAMPLE_4X, .component_only = 1, diff --git a/src/i830_video.c b/src/i830_video.c index 967fda92..6b685f0c 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -50,6 +50,7 @@ #include "config.h" #endif +#include <inttypes.h> #include <math.h> #include <string.h> #include <assert.h> @@ -383,7 +384,7 @@ i830_overlay_switch_to_crtc (ScrnInfoPtr pScrn, xf86CrtcPtr crtc) I830CrtcPrivatePtr intel_crtc = crtc->driver_private; int pipeconf_reg = intel_crtc->pipe == 0 ? PIPEACONF : PIPEBCONF; - if (INREG(pipeconf_reg) & PIPEACONF_DOUBLE_WIDE) + if (!IS_I965G(pI830) && (INREG(pipeconf_reg) & PIPEACONF_DOUBLE_WIDE)) pPriv->overlayOK = FALSE; else pPriv->overlayOK = TRUE; @@ -395,7 +396,7 @@ i830_overlay_switch_to_crtc (ScrnInfoPtr pScrn, xf86CrtcPtr crtc) if (i830PipeHasType(crtc, I830_OUTPUT_LVDS)) { - int vtotal_reg = intel_crtc->pipe ? VTOTAL_A : VTOTAL_B; + int vtotal_reg = intel_crtc->pipe == 0 ? VTOTAL_A : VTOTAL_B; CARD32 size = intel_crtc->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC); CARD32 active; CARD32 hsize, vsize; @@ -494,7 +495,8 @@ i830_overlay_continue(ScrnInfoPtr pScrn, Bool update_filter) flip_addr = pI830->overlay_regs->bus_addr; if (update_filter) flip_addr |= OFC_UPDATE; - OVERLAY_DEBUG ("overlay_continue cmd 0x%08lx -> 0x%08lx sta 0x%08lx\n", + OVERLAY_DEBUG ("overlay_continue cmd 0x%08" PRIx32 " -> 0x%08" PRIx32 + " sta 0x%08" PRIx32 "\n", overlay->OCMD, INREG(OCMD_REGISTER), INREG(DOVSTA)); BEGIN_LP_RING(4); OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE); @@ -534,7 +536,7 @@ i830_overlay_off(ScrnInfoPtr pScrn) */ { overlay->OCMD &= ~OVERLAY_ENABLE; - OVERLAY_DEBUG ("overlay_off cmd 0x%08lx -> 0x%08lx sta 0x%08lx\n", + OVERLAY_DEBUG ("overlay_off cmd 0x%08" PRIx32 " -> 0x%08" PRIx32 " sta 0x%08" PRIx32 "\n", overlay->OCMD, INREG(OCMD_REGISTER), INREG(DOVSTA)); BEGIN_LP_RING(6); OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE); @@ -610,8 +612,7 @@ I830InitVideo(ScreenPtr pScreen) } /* Set up overlay video if we can do it at this depth. */ - if (!IS_I965G(pI830) && pScrn->bitsPerPixel != 8 && - pI830->overlay_regs != NULL) + if (pScrn->bitsPerPixel != 8 && pI830->overlay_regs != NULL) { overlayAdaptor = I830SetupImageVideoOverlay(pScreen); if (overlayAdaptor != NULL) { @@ -717,7 +718,7 @@ I830ResetVideo(ScrnInfoPtr pScrn) { int i; for (i = 0x30000; i < 0x31000; i += 4) - ErrorF("0x%x 0x%lx\n", i, INREG(i)); + ErrorF("0x%x 0x%" PRIx32 "\n", i, INREG(i)); } #endif } @@ -889,6 +890,8 @@ I830SetupImageVideoOverlay(ScreenPtr pScreen) pPriv->gamma0 = 0x080808; pPriv->doubleBuffer = 1; + pPriv->rotation = RR_Rotate_0; + /* gotta uninit this someplace */ REGION_NULL(pScreen, &pPriv->clip); @@ -994,6 +997,8 @@ I830SetupImageVideoTextured(ScreenPtr pScreen) pPriv->currentBuf = 0; pPriv->doubleBuffer = 0; + pPriv->rotation = RR_Rotate_0; + /* gotta uninit this someplace, XXX: shouldn't be necessary for textured */ REGION_NULL(pScreen, &pPriv->clip); @@ -1249,7 +1254,7 @@ I830CopyPackedData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, else dst = pI830->FbBase + pPriv->YBuf1offset; - switch (pI830->rotation) { + switch (pPriv->rotation) { case RR_Rotate_0: w <<= 1; for (i = 0; i < h; i++) { @@ -1411,7 +1416,7 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, else dst1 = pI830->FbBase + pPriv->YBuf1offset; - switch (pI830->rotation) { + switch (pPriv->rotation) { case RR_Rotate_0: for (i = 0; i < h; i++) { memcpy(dst1, src1, w); @@ -1466,7 +1471,7 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, dst2 = pI830->FbBase + pPriv->VBuf1offset; } - switch (pI830->rotation) { + switch (pPriv->rotation) { case RR_Rotate_0: for (i = 0; i < h / 2; i++) { memcpy(dst2, src2, w / 2); @@ -1522,7 +1527,7 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, dst3 = pI830->FbBase + pPriv->UBuf1offset; } - switch (pI830->rotation) { + switch (pPriv->rotation) { case RR_Rotate_0: for (i = 0; i < h / 2; i++) { memcpy(dst3, src3, w / 2); @@ -1821,6 +1826,10 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, return; switch (crtc->rotation & 0xf) { + /* for overlay, we should take it from crtc's screen + * coordinate to current crtc's display mode. + * yeah, a bit confusing. + */ case RR_Rotate_0: dstBox->x1 -= crtc->x; dstBox->x2 -= crtc->x; @@ -1830,10 +1839,10 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, case RR_Rotate_90: tmp = dstBox->x1; dstBox->x1 = dstBox->y1 - crtc->x; - dstBox->y1 = pScrn->virtualY - tmp - crtc->y; + dstBox->y1 = pScrn->virtualX - tmp - crtc->y; tmp = dstBox->x2; dstBox->x2 = dstBox->y2 - crtc->x; - dstBox->y2 = pScrn->virtualY - tmp - crtc->y; + dstBox->y2 = pScrn->virtualX - tmp - crtc->y; tmp = dstBox->y1; dstBox->y1 = dstBox->y2; dstBox->y2 = tmp; @@ -1848,10 +1857,10 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, break; case RR_Rotate_270: tmp = dstBox->x1; - dstBox->x1 = pScrn->virtualX - dstBox->y1 - crtc->x; + dstBox->x1 = pScrn->virtualY - dstBox->y1 - crtc->x; dstBox->y1 = tmp - crtc->y; tmp = dstBox->x2; - dstBox->x2 = pScrn->virtualX - dstBox->y2 - crtc->x; + dstBox->x2 = pScrn->virtualY - dstBox->y2 - crtc->x; dstBox->y2 = tmp - crtc->y; tmp = dstBox->x1; dstBox->x1 = dstBox->x2; @@ -1947,7 +1956,7 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, overlay->OBUF_1V = pPriv->VBuf1offset; } - OVERLAY_DEBUG("pos: 0x%lx, size: 0x%lx\n", + OVERLAY_DEBUG("pos: 0x%" PRIx32 ", size: 0x%" PRIx32 "\n", overlay->DWINPOS, overlay->DWINSZ); OVERLAY_DEBUG("dst: %d x %d, src: %d x %d\n", drw_w, drw_h, src_w, src_h); @@ -2109,7 +2118,7 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, OCMD |= BUFFER1; overlay->OCMD = OCMD; - OVERLAY_DEBUG("OCMD is 0x%lx\n", OCMD); + OVERLAY_DEBUG("OCMD is 0x%" PRIx32 "\n", OCMD); /* make sure the overlay is on */ i830_overlay_on (pScrn); @@ -2283,6 +2292,17 @@ I830PutImage(ScrnInfoPtr pScrn, width, height)) return Success; + if (!pPriv->textured) { + /* texture video handles rotation differently. */ + if (crtc) + pPriv->rotation = crtc->rotation; + else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Fail to clip video to any crtc!\n"); + return Success; + } + } + destId = id; switch (id) { case FOURCC_YV12: @@ -2323,7 +2343,7 @@ I830PutImage(ScrnInfoPtr pScrn, switch (destId) { case FOURCC_YV12: case FOURCC_I420: - if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { + if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { dstPitch = ((height / 2) + pitchAlignMask) & ~pitchAlignMask; size = dstPitch * width * 3; } else { @@ -2334,7 +2354,7 @@ I830PutImage(ScrnInfoPtr pScrn, case FOURCC_UYVY: case FOURCC_YUY2: default: - if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { + if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { dstPitch = ((height << 1) + pitchAlignMask) & ~pitchAlignMask; size = dstPitch * width; } else { @@ -2384,7 +2404,7 @@ I830PutImage(ScrnInfoPtr pScrn, /* fixup pointers */ pPriv->YBuf0offset = pPriv->buf->offset; - if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { + if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width); pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2); if(pPriv->doubleBuffer) { @@ -2599,10 +2619,6 @@ I830VideoBlockHandler(int i, pointer blockData, pointer pTimeout, if (pI830->adaptor == NULL) return; - /* No overlay scaler on the 965. */ - if (IS_I965G(pI830)) - return; - pPriv = GET_PORT_PRIVATE(pScrn); if (pPriv->videoStatus & TIMER_MASK) { @@ -2882,10 +2898,6 @@ i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on) if (pI830->adaptor == NULL) return; - /* No overlay scaler on the 965. */ - if (IS_I965G(pI830)) - return; - pPriv = GET_PORT_PRIVATE(pScrn); if (crtc != pPriv->current_crtc) diff --git a/src/i830_video.h b/src/i830_video.h index e67831d8..17689138 100644 --- a/src/i830_video.h +++ b/src/i830_video.h @@ -65,6 +65,7 @@ typedef struct { int oneLineMode; int scaleRatio; Bool textured; + Rotation rotation; /* should remove I830->rotation later*/ } I830PortPrivRec, *I830PortPrivPtr; #define GET_PORT_PRIVATE(pScrn) \ diff --git a/src/i965_render.c b/src/i965_render.c index ad3b53ef..4b1d7f3e 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -907,6 +907,7 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, src_sampler_offset) >> 5; wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */ wm_state->wm5.max_threads = PS_MAX_THREADS - 1; + wm_state->wm5.transposed_urb_read = 0; wm_state->wm5.thread_dispatch_enable = 1; /* just use 16-pixel dispatch (4 subspans), don't need to change kernel * start point @@ -933,7 +934,10 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, BEGIN_LP_RING(12); /* Match Mesa driver setup */ - OUT_RING(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D); + if (IS_IGD_GM(pI830)) + OUT_RING(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D); + else + OUT_RING(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D); OUT_RING(BRW_CS_URB_STATE | 0); OUT_RING((0 << 4) | /* URB Entry Allocation Size */ diff --git a/src/i965_video.c b/src/i965_video.c index 03572703..928b52b7 100644 --- a/src/i965_video.c +++ b/src/i965_video.c @@ -509,7 +509,10 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, { BEGIN_LP_RING(12); /* Match Mesa driver setup */ - OUT_RING(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D); + if (IS_IGD_GM(pI830)) + OUT_RING(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D); + else + OUT_RING(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D); /* Mesa does this. Who knows... */ OUT_RING(BRW_CS_URB_STATE | 0); diff --git a/src/ivch/Makefile.am b/src/ivch/Makefile.am index 1dc9cb35..8b12b093 100644 --- a/src/ivch/Makefile.am +++ b/src/ivch/Makefile.am @@ -3,7 +3,8 @@ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @WARN_CFLAGS@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ +AM_CFLAGS = @WARN_CFLAGS@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \ + @PCIACCESS_CFLAGS@ ivch_la_LTLIBRARIES = ivch.la ivch_la_LDFLAGS = -module -avoid-version diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c index eb5dc21c..820919fb 100644 --- a/src/ivch/ivch.c +++ b/src/ivch/ivch.c @@ -358,7 +358,7 @@ ivch_restore(I2CDevPtr d) } -I830I2CVidOutputRec ivch_methods = { +_X_EXPORT I830I2CVidOutputRec ivch_methods = { .init = ivch_init, .dpms = ivch_dpms, .save = ivch_save, diff --git a/src/reg_dumper/.gitignore b/src/reg_dumper/.gitignore index 1b38d5c6..f72a165e 100644 --- a/src/reg_dumper/.gitignore +++ b/src/reg_dumper/.gitignore @@ -1 +1,3 @@ +intel_idle intel_reg_dumper +intel_stepping diff --git a/src/reg_dumper/Makefile.am b/src/reg_dumper/Makefile.am index aee26d0e..b840b244 100644 --- a/src/reg_dumper/Makefile.am +++ b/src/reg_dumper/Makefile.am @@ -1,4 +1,4 @@ -noinst_PROGRAMS = intel_reg_dumper +noinst_PROGRAMS = intel_reg_dumper intel_idle intel_stepping intel_reg_dumper_SOURCES = \ main.c \ @@ -6,7 +6,19 @@ intel_reg_dumper_SOURCES = \ xprintf.c \ ../i830_debug.c +intel_idle_SOURCES = \ + idle.c \ + reg_dumper.h \ + xprintf.c \ + ../i830_debug.c + +intel_stepping_SOURCES = \ + stepping.c + intel_reg_dumper_LDADD = $(PCIACCESS_LIBS) +intel_idle_LDADD = $(PCIACCESS_LIBS) +intel_stepping_LDADD = $(PCIACCESS_LIBS) -intel_reg_dumper_CFLAGS = $(PCIACCESS_CFLAGS) $(WARN_CFLAGS) \ +AM_CFLAGS = $(PCIACCESS_CFLAGS) $(WARN_CFLAGS) \ -I$(srcdir)/.. -DREG_DUMPER + diff --git a/src/reg_dumper/idle.c b/src/reg_dumper/idle.c new file mode 100644 index 00000000..0077bf45 --- /dev/null +++ b/src/reg_dumper/idle.c @@ -0,0 +1,177 @@ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Eric Anholt <eric@anholt.net> + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <pciaccess.h> +#include <err.h> +#include <unistd.h> + +#include "reg_dumper.h" +#include "../i810_reg.h" + +struct idle_flags { + uint32_t instdone_flag; + char *name; + unsigned int count; +}; + +struct idle_flags i965_idle_flags[] = { + {I965_SF_DONE, "SF"}, + {I965_SE_DONE, "SE"}, + {I965_WM_DONE, "WM"}, + {I965_TEXTURE_FETCH_DONE, "texture fetch"}, + {I965_SAMPLER_CACHE_DONE, "sampler cache"}, + {I965_FILTER_DONE, "filter"}, + {I965_PS_DONE, "PS"}, + {I965_CC_DONE, "CC"}, + {I965_MAP_FILTER_DONE, "map filter"}, + {I965_MAP_L2_IDLE, "map L2"}, + {I965_CP_DONE, "CP"}, + {0, "other"}, +}; + +/* Fills in the "other" field's idle flags */ +static void +setup_other_flags(struct idle_flags *idle_flags, int idle_flag_count) +{ + uint32_t other_idle_flags; + int i; + + other_idle_flags = ~(I965_RING_0_ENABLE); + for (i = 0; i < idle_flag_count - 1; i++) { + other_idle_flags &= ~idle_flags[i].instdone_flag; + } + idle_flags[i].instdone_flag = other_idle_flags; + +} + +int main(int argc, char **argv) +{ + struct pci_device *dev; + I830Rec i830; + I830Ptr pI830 = &i830; + ScrnInfoRec scrn; + int err, mmio_bar; + void *mmio; + struct idle_flags *idle_flags; + int idle_flag_count; + + err = pci_system_init(); + if (err != 0) { + fprintf(stderr, "Couldn't initialize PCI system: %s\n", strerror(err)); + exit(1); + } + + /* Grab the graphics card */ + dev = pci_device_find_by_slot(0, 0, 2, 0); + if (dev == NULL) + errx(1, "Couldn't find graphics card"); + + err = pci_device_probe(dev); + if (err != 0) { + fprintf(stderr, "Couldn't probe graphics card: %s\n", strerror(err)); + exit(1); + } + + if (dev->vendor_id != 0x8086) + errx(1, "Graphics card is non-intel"); + + i830.PciInfo = &i830.pci_info_rec; + i830.PciInfo->chipType = dev->device_id; + + i830.pci_dev = dev; + + mmio_bar = IS_I9XX((&i830)) ? 0 : 1; + + err = pci_device_map_range (dev, + dev->regions[mmio_bar].base_addr, + dev->regions[mmio_bar].size, + PCI_DEV_MAP_FLAG_WRITABLE, + &mmio); + + if (err != 0) { + fprintf(stderr, "Couldn't map MMIO region: %s\n", strerror(err)); + exit(1); + } + i830.mmio = mmio; + + scrn.scrnIndex = 0; + scrn.pI830 = &i830; + + /* if (IS_I965) { */ + idle_flags = i965_idle_flags; + idle_flag_count = sizeof(i965_idle_flags) / sizeof(i965_idle_flags[0]); + + setup_other_flags(idle_flags, idle_flag_count); + + for (;;) { + int i, j; + + for (i = 0; i < 100; i++) { + uint32_t instdone = INREG(INST_DONE_I965); + + for (j = 0; j < idle_flag_count; j++) { + if ((instdone & idle_flags[j].instdone_flag) == 0) + idle_flags[j].count++; + } + + usleep (10000); + } + + for (j = 0; j < idle_flag_count; j++) { + printf("%15s: %3d\n", idle_flags[j].name, idle_flags[j].count); + idle_flags[j].count = 0; + } + printf("\n"); + } + + return 0; +} + +void xf86DrvMsg(int scrnIndex, int severity, const char *format, ...) +{ + va_list va; + + switch (severity) { + case X_INFO: + printf("(II): "); + break; + case X_WARNING: + printf("(WW): "); + break; + case X_ERROR: + printf("(EE): "); + break; + } + + va_start(va, format); + vprintf(format, va); + va_end(va); +} diff --git a/src/reg_dumper/stepping.c b/src/reg_dumper/stepping.c new file mode 100644 index 00000000..dd0cb427 --- /dev/null +++ b/src/reg_dumper/stepping.c @@ -0,0 +1,137 @@ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Eric Anholt <eric@anholt.net> + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <pciaccess.h> +#include <err.h> +#include "common.h" + +int main(int argc, char **argv) +{ + struct pci_device *dev, *bridge; + int err; + uint8_t stepping; + char *step_desc = "??"; + + err = pci_system_init(); + if (err != 0) { + fprintf(stderr, "Couldn't initialize PCI system: %s\n", strerror(err)); + exit(1); + } + + /* Grab the graphics card */ + dev = pci_device_find_by_slot(0, 0, 2, 0); + if (dev == NULL) + errx(1, "Couldn't find graphics card"); + + err = pci_device_probe(dev); + if (err != 0) { + fprintf(stderr, "Couldn't probe graphics card: %s\n", strerror(err)); + exit(1); + } + + if (dev->vendor_id != 0x8086) + errx(1, "Graphics card is non-intel"); + + bridge = pci_device_find_by_slot(0, 0, 0, 0); + if (dev == NULL) + errx(1, "Couldn't bridge"); + + err = pci_device_cfg_read_u8(bridge, &stepping, 8); + if (err != 0) { + fprintf(stderr, "Couldn't read revision ID: %s\n", strerror(err)); + exit(1); + } + + switch (dev->device_id) { + case PCI_CHIP_I915_G: + if (stepping < 0x04) + step_desc = "<B1"; + else if (stepping == 0x04) + step_desc = "B1"; + else if (stepping == 0x0e) + step_desc = "C2"; + else if (stepping > 0x0e) + step_desc = ">C2"; + else + step_desc = ">B1 <C2"; + break; + case PCI_CHIP_I915_GM: + if (stepping < 0x03) + step_desc = "<B1"; + else if (stepping == 0x03) + step_desc = "B1/C0"; + else if (stepping == 0x04) + step_desc = "C1/C2"; + else + step_desc = ">C2"; + break; + case PCI_CHIP_I945_GM: + if (stepping < 0x03) + step_desc = "<A3"; + else if (stepping == 0x03) + step_desc = "A3"; + else + step_desc = ">A3"; + break; + case PCI_CHIP_I965_G: + case PCI_CHIP_I965_Q: + if (stepping < 0x02) + step_desc = "<C1"; + else if (stepping == 0x02) + step_desc = "C1/C2"; + else + step_desc = ">C2"; + break; + case PCI_CHIP_I965_GM: + if (stepping < 0x03) + step_desc = "<C0"; + else if (stepping == 0x03) + step_desc = "C0"; + else + step_desc = ">C0"; + break; + case PCI_CHIP_G35_G: + if (stepping < 0x03) + step_desc = "<E0"; + else if (stepping == 0x03) + step_desc = "E0"; + else + step_desc = ">E0"; + break; + } + + printf("Vendor: 0x%04x, Device: 0x%04x, Revision: 0x%02x (%s)\n", + dev->vendor_id, + dev->device_id, + stepping, + step_desc); + return 0; +} diff --git a/src/sil164/Makefile.am b/src/sil164/Makefile.am index 497ee9f7..7b179ab9 100644 --- a/src/sil164/Makefile.am +++ b/src/sil164/Makefile.am @@ -3,7 +3,8 @@ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @WARN_CFLAGS@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ +AM_CFLAGS = @WARN_CFLAGS@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \ + @PCIACCESS_CFLAGS@ sil164_la_LTLIBRARIES = sil164.la sil164_la_LDFLAGS = -module -avoid-version diff --git a/src/sil164/sil164.c b/src/sil164/sil164.c index 12fe8e2e..f7d414a2 100644 --- a/src/sil164/sil164.c +++ b/src/sil164/sil164.c @@ -237,7 +237,7 @@ sil164_restore(I2CDevPtr d) } -I830I2CVidOutputRec SIL164VidOutput = { +_X_EXPORT I830I2CVidOutputRec SIL164VidOutput = { .init = sil164_init, .detect = sil164_detect, .mode_valid = sil164_mode_valid, diff --git a/src/tfp410/Makefile.am b/src/tfp410/Makefile.am index 89a27d03..0dbc0212 100644 --- a/src/tfp410/Makefile.am +++ b/src/tfp410/Makefile.am @@ -3,7 +3,8 @@ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @WARN_CFLAGS@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ +AM_CFLAGS = @WARN_CFLAGS@ @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \ + @PCIACCESS_CFLAGS@ tfp410_la_LTLIBRARIES = tfp410.la tfp410_la_LDFLAGS = -module -avoid-version diff --git a/src/tfp410/tfp410.c b/src/tfp410/tfp410.c index b79fd2a8..bb038cdb 100644 --- a/src/tfp410/tfp410.c +++ b/src/tfp410/tfp410.c @@ -259,7 +259,7 @@ tfp410_restore(I2CDevPtr d) tfp410WriteByte(tfp, TFP410_CTL_1, tfp->SavedReg.ctl1); } -I830I2CVidOutputRec TFP410VidOutput = { +_X_EXPORT I830I2CVidOutputRec TFP410VidOutput = { .init = tfp410_init, .detect = tfp410_detect, .mode_valid = tfp410_mode_valid, |