summaryrefslogtreecommitdiff
path: root/driver/xf86-video-intel/src
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2008-03-30 13:51:31 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2008-03-30 13:51:31 +0000
commit1d45ca8c03ed27912049f405194382e5ba41674d (patch)
tree26bc625f6ae732c3620142a8e4e5e1d1d4e31fe7 /driver/xf86-video-intel/src
parentd3d2132216a1ffa6e540438c3730b39e100fdbf8 (diff)
Update to Intel driver 2.2.1. But change default accelmethod to XAA.
Tested by landry@, oga@, steven@, jakemsr@.
Diffstat (limited to 'driver/xf86-video-intel/src')
-rw-r--r--driver/xf86-video-intel/src/common.h2
-rw-r--r--driver/xf86-video-intel/src/i810_reg.h1392
-rw-r--r--driver/xf86-video-intel/src/i830.h810
-rw-r--r--driver/xf86-video-intel/src/i830_debug.c220
-rw-r--r--driver/xf86-video-intel/src/i830_display.c104
-rw-r--r--driver/xf86-video-intel/src/i830_dri.c101
-rw-r--r--driver/xf86-video-intel/src/i830_driver.c30
-rw-r--r--driver/xf86-video-intel/src/i830_dvo.c6
-rw-r--r--driver/xf86-video-intel/src/i830_memory.c15
-rw-r--r--driver/xf86-video-intel/src/i830_quirks.c163
-rw-r--r--driver/xf86-video-intel/src/i830_video.c1
11 files changed, 2401 insertions, 443 deletions
diff --git a/driver/xf86-video-intel/src/common.h b/driver/xf86-video-intel/src/common.h
index 3a11e594b..c0af1ad2e 100644
--- a/driver/xf86-video-intel/src/common.h
+++ b/driver/xf86-video-intel/src/common.h
@@ -441,6 +441,8 @@ extern int I810_DEBUG;
#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810) || IS_IGD_GM(pI810))
/* mark chipsets for using gfx VM offset for overlay */
#define OVERLAY_NOPHYSICAL(pI810) (IS_G33CLASS(pI810))
+/* chipsets require graphics mem for hardware status page */
+#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_IGD_GM(pI810))
#define GTT_PAGE_SIZE KB(4)
#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y))
diff --git a/driver/xf86-video-intel/src/i810_reg.h b/driver/xf86-video-intel/src/i810_reg.h
index 4bb5bf140..5170004a7 100644
--- a/driver/xf86-video-intel/src/i810_reg.h
+++ b/driver/xf86-video-intel/src/i810_reg.h
@@ -26,9 +26,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
+/** @file
+ * Register names and fields for Intel graphics.
+ */
+
/*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
+ * Eric Anholt <eric@anholt.net>
*
* based on the i740 driver by
* Kevin E. Martin <kevin@precisioninsight.com>
@@ -94,6 +99,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define LINEAR_MODE_ENABLE 0x02
#define PAGE_MAPPING_ENABLE 0x01
+#define HOTKEY_VBIOS_SWITCH_BLOCK 0x80
+#define HOTKEY_SWITCH 0x20
+#define HOTKEY_TOGGLE 0x10
+
/* Blitter control, p378
*/
#define BITBLT_CNTL 0x7000c
@@ -258,7 +267,28 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define HSYNC_ON 0x00
#define HSYNC_OFF 0x02
-
+#define GPIOA 0x5010
+#define GPIOB 0x5014
+#define GPIOC 0x5018
+#define GPIOD 0x501c
+#define GPIOE 0x5020
+#define GPIOF 0x5024
+#define GPIOG 0x5028
+#define GPIOH 0x502c
+# define GPIO_CLOCK_DIR_MASK (1 << 0)
+# define GPIO_CLOCK_DIR_IN (0 << 1)
+# define GPIO_CLOCK_DIR_OUT (1 << 1)
+# define GPIO_CLOCK_VAL_MASK (1 << 2)
+# define GPIO_CLOCK_VAL_OUT (1 << 3)
+# define GPIO_CLOCK_VAL_IN (1 << 4)
+# define GPIO_CLOCK_PULLUP_DISABLE (1 << 5)
+# define GPIO_DATA_DIR_MASK (1 << 8)
+# define GPIO_DATA_DIR_IN (0 << 9)
+# define GPIO_DATA_DIR_OUT (1 << 9)
+# define GPIO_DATA_VAL_MASK (1 << 10)
+# define GPIO_DATA_VAL_OUT (1 << 11)
+# define GPIO_DATA_VAL_IN (1 << 12)
+# define GPIO_DATA_PULLUP_DISABLE (1 << 13)
/* p317, 319
*/
@@ -269,6 +299,20 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define VCLK_DIVISOR_VGA0 0x6000
#define VCLK_DIVISOR_VGA1 0x6004
#define VCLK_POST_DIV 0x6010
+/** Selects a post divisor of 4 instead of 2. */
+# define VGA1_PD_P2_DIV_4 (1 << 15)
+/** Overrides the p2 post divisor field */
+# define VGA1_PD_P1_DIV_2 (1 << 13)
+# define VGA1_PD_P1_SHIFT 8
+/** P1 value is 2 greater than this field */
+# define VGA1_PD_P1_MASK (0x1f << 8)
+/** Selects a post divisor of 4 instead of 2. */
+# define VGA0_PD_P2_DIV_4 (1 << 7)
+/** Overrides the p2 post divisor field */
+# define VGA0_PD_P1_DIV_2 (1 << 5)
+# define VGA0_PD_P1_SHIFT 0
+/** P1 value is 2 greater than this field */
+# define VGA0_PD_P1_MASK (0x1f << 0)
#define POST_DIV_SELECT 0x70
#define POST_DIV_1 0x00
@@ -302,18 +346,35 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define IPEIR 0x2088
#define IPEHR 0x208C
#define INST_DONE 0x2090
+#define SCPD0 0x209c /* debug */
#define INST_PS 0x20c4
#define IPEIR_I965 0x2064 /* i965 */
#define IPEHR_I965 0x2068 /* i965 */
#define INST_DONE_I965 0x206c
#define INST_PS_I965 0x2070
+
+/* Current active ring head address:
+ */
#define ACTHD 0x2074
+
+/* Current primary/secondary DMA fetch addresses:
+ */
#define DMA_FADD_P 0x2078
+#define DMA_FADD_S 0x20d4
#define INST_DONE_1 0x207c
#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:
+ */
+#define PR0_STR 0x20f0
+#define PR1_STR 0x20f4
+#define PR2_STR 0x20f8
#define WIZ_CTL 0x7c00
#define WIZ_CTL_SINGLE_SUBSPAN (1<<6)
@@ -368,8 +429,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define EIR 0x20B0
#define EMR 0x20B4
#define ESR 0x20B8
-#define IP_ERR 0x0001
-#define ERROR_RESERVED 0xffc6
+# define ERR_VERTEX_MAX (1 << 5) /* lpt/cst */
+# define ERR_PGTBL_ERROR (1 << 4)
+# define ERR_DISPLAY_OVERLAY_UNDERRUN (1 << 3)
+# define ERR_MAIN_MEMORY_REFRESH (1 << 1)
+# define ERR_INSTRUCTION_ERROR (1 << 0)
/* Interrupt Control Registers
@@ -455,6 +519,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define I915G_FENCE_SIZE_32M 0x00000500
#define I915G_FENCE_SIZE_64M 0x00000600
#define I915G_FENCE_SIZE_128M 0x00000700
+#define I965_FENCE_X_MAJOR 0x00000000
+#define I965_FENCE_Y_MAJOR 0x00000002
#define FENCE_PITCH_1 0x00000000
#define FENCE_PITCH_2 0x00000010
#define FENCE_PITCH_4 0x00000020
@@ -471,9 +537,31 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define PGETBL_ADDR_MASK 0xFFFFF000
#define PGETBL_ENABLE_MASK 0x00000001
#define PGETBL_ENABLED 0x00000001
-
-/* Register containing pge table error results, p276
+/** Added in 965G, this field has the actual size of the global GTT */
+#define PGETBL_SIZE_MASK 0x0000000e
+#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)
+
+#define I830_PTE_BASE 0x10000
+#define PTE_ADDRESS_MASK 0xfffff000
+#define PTE_ADDRESS_MASK_HIGH 0x000000f0 /* i915+ */
+#define PTE_MAPPING_TYPE_UNCACHED (0 << 1)
+#define PTE_MAPPING_TYPE_DCACHE (1 << 1) /* i830 only */
+#define PTE_MAPPING_TYPE_CACHED (3 << 1)
+#define PTE_MAPPING_TYPE_MASK (3 << 1)
+#define PTE_VALID (1 << 0)
+
+/** @defgroup PGE_ERR
+ * @{
*/
+/** Page table debug register for i845 */
#define PGE_ERR 0x2024
#define PGE_ERR_ADDR_MASK 0xFFFFF000
#define PGE_ERR_ID_MASK 0x00000038
@@ -493,20 +581,33 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define PGE_ERR_ILLEGAL_TRX 0x00000004
#define PGE_ERR_LOCAL_MEM 0x00000005
#define PGE_ERR_TILED 0x00000006
+/** @} */
-
-
-/* Page table entries loaded via mmio region, p323
+/** @defgroup PGTBL_ER
+ * @{
*/
-#define PTE_BASE 0x10000
-#define PTE_ADDR_MASK 0x3FFFF000
-#define PTE_TYPE_MASK 0x00000006
-#define PTE_LOCAL 0x00000002
-#define PTE_MAIN_UNCACHED 0x00000000
-#define PTE_MAIN_CACHED 0x00000006
-#define PTE_VALID_MASK 0x00000001
-#define PTE_VALID 0x00000001
-
+/** Page table debug register for i945 */
+# define PGTBL_ER 0x2024
+# define PGTBL_ERR_MT_TILING (1 << 27)
+# define PGTBL_ERR_MT_GTT_PTE (1 << 26)
+# define PGTBL_ERR_LC_TILING (1 << 25)
+# define PGTBL_ERR_LC_GTT_PTE (1 << 24)
+# define PGTBL_ERR_BIN_VERTEXDATA_GTT_PTE (1 << 23)
+# define PGTBL_ERR_BIN_INSTRUCTION_GTT_PTE (1 << 22)
+# define PGTBL_ERR_CS_VERTEXDATA_GTT_PTE (1 << 21)
+# define PGTBL_ERR_CS_INSTRUCTION_GTT_PTE (1 << 20)
+# define PGTBL_ERR_CS_GTT (1 << 19)
+# define PGTBL_ERR_OVERLAY_TILING (1 << 18)
+# define PGTBL_ERR_OVERLAY_GTT_PTE (1 << 16)
+# define PGTBL_ERR_DISPC_TILING (1 << 14)
+# define PGTBL_ERR_DISPC_GTT_PTE (1 << 12)
+# define PGTBL_ERR_DISPB_TILING (1 << 10)
+# define PGTBL_ERR_DISPB_GTT_PTE (1 << 8)
+# define PGTBL_ERR_DISPA_TILING (1 << 6)
+# define PGTBL_ERR_DISPA_GTT_PTE (1 << 4)
+# define PGTBL_ERR_HOST_PTE_DATA (1 << 1)
+# define PGTBL_ERR_HOST_GTT_PTE (1 << 0)
+/** @} */
/* Ring buffer registers, p277, overview p19
*/
@@ -713,6 +814,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define VSYNC_A 0x60014
#define PIPEASRC 0x6001c
#define BCLRPAT_A 0x60020
+#define VSYNCSHIFT_A 0x60028
#define HTOTAL_B 0x61000
#define HBLANK_B 0x61004
@@ -722,11 +824,376 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define VSYNC_B 0x61014
#define PIPEBSRC 0x6101c
#define BCLRPAT_B 0x61020
+#define VSYNCSHIFT_B 0x61028
+
+#define PP_STATUS 0x61200
+# define PP_ON (1 << 31)
+/**
+ * Indicates that all dependencies of the panel are on:
+ *
+ * - PLL enabled
+ * - pipe enabled
+ * - LVDS/DVOB/DVOC on
+ */
+# define PP_READY (1 << 30)
+# define PP_SEQUENCE_NONE (0 << 28)
+# define PP_SEQUENCE_ON (1 << 28)
+# define PP_SEQUENCE_OFF (2 << 28)
+# define PP_SEQUENCE_MASK 0x30000000
+
+#define PP_CONTROL 0x61204
+# define POWER_DOWN_ON_RESET (1 << 1)
+# define POWER_TARGET_ON (1 << 0)
+
+#define LVDSPP_ON 0x61208
+#define LVDSPP_OFF 0x6120c
+#define PP_CYCLE 0x61210
+
+#define PFIT_CONTROL 0x61230
+# define PFIT_ENABLE (1 << 31)
+# define PFIT_PIPE_MASK (3 << 29)
+# define PFIT_PIPE_SHIFT 29
+# define VERT_INTERP_DISABLE (0 << 10)
+# define VERT_INTERP_BILINEAR (1 << 10)
+# define VERT_INTERP_MASK (3 << 10)
+# define VERT_AUTO_SCALE (1 << 9)
+# define HORIZ_INTERP_DISABLE (0 << 6)
+# define HORIZ_INTERP_BILINEAR (1 << 6)
+# define HORIZ_INTERP_MASK (3 << 6)
+# define HORIZ_AUTO_SCALE (1 << 5)
+# define PANEL_8TO6_DITHER_ENABLE (1 << 3)
+
+#define PFIT_PGM_RATIOS 0x61234
+# define PFIT_VERT_SCALE_MASK 0xfff00000
+# define PFIT_HORIZ_SCALE_MASK 0x0000fff0
+
+#define PFIT_AUTO_RATIOS 0x61238
#define DPLL_A 0x06014
#define DPLL_B 0x06018
+# define DPLL_VCO_ENABLE (1 << 31)
+# define DPLL_DVO_HIGH_SPEED (1 << 30)
+# define DPLL_SYNCLOCK_ENABLE (1 << 29)
+# define DPLL_VGA_MODE_DIS (1 << 28)
+# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
+# define DPLLB_MODE_LVDS (2 << 26) /* i915 */
+# define DPLL_MODE_MASK (3 << 26)
+# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
+# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
+# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
+# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
+# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
+# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
+/**
+ * The i830 generation, in DAC/serial mode, defines p1 as two plus this
+ * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
+ */
+# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
+/**
+ * The i830 generation, in LVDS mode, defines P1 as the bit number set within
+ * this field (only one bit may be set).
+ */
+# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
+# define DPLL_FPA01_P1_POST_DIV_SHIFT 16
+# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */
+# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
+# define PLL_REF_INPUT_DREFCLK (0 << 13)
+# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
+# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */
+# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
+# define PLL_REF_INPUT_MASK (3 << 13)
+# define PLL_LOAD_PULSE_PHASE_SHIFT 9
+/*
+ * Parallel to Serial Load Pulse phase selection.
+ * Selects the phase for the 10X DPLL clock for the PCIe
+ * digital display port. The range is 4 to 13; 10 or more
+ * is just a flip delay. The default is 6
+ */
+# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
+# define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
+
+/**
+ * SDVO multiplier for 945G/GM. Not used on 965.
+ *
+ * \sa DPLL_MD_UDI_MULTIPLIER_MASK
+ */
+# define SDVO_MULTIPLIER_MASK 0x000000ff
+# define SDVO_MULTIPLIER_SHIFT_HIRES 4
+# define SDVO_MULTIPLIER_SHIFT_VGA 0
+
+/** @defgroup DPLL_MD
+ * @{
+ */
+/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */
+#define DPLL_A_MD 0x0601c
+/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */
+#define DPLL_B_MD 0x06020
+/**
+ * UDI pixel divider, controlling how many pixels are stuffed into a packet.
+ *
+ * Value is pixels minus 1. Must be set to 1 pixel for SDVO.
+ */
+# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
+# define DPLL_MD_UDI_DIVIDER_SHIFT 24
+/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
+# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
+# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
+/**
+ * SDVO/UDI pixel multiplier.
+ *
+ * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
+ * clock rate is 10 times the DPLL clock. At low resolution/refresh rate
+ * modes, the bus rate would be below the limits, so SDVO allows for stuffing
+ * dummy bytes in the datastream at an increased clock rate, with both sides of
+ * the link knowing how many bytes are fill.
+ *
+ * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
+ * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be
+ * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
+ * through an SDVO command.
+ *
+ * This register field has values of multiplication factor minus 1, with
+ * a maximum multiplier of 5 for SDVO.
+ */
+# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
+# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
+/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
+ * This best be set to the default value (3) or the CRT won't work. No,
+ * I don't entirely understand what this does...
+ */
+# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
+# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
+/** @} */
+
+#define DPLL_TEST 0x606c
+# define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
+# define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
+# define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
+# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
+# define DPLLB_TEST_N_BYPASS (1 << 19)
+# define DPLLB_TEST_M_BYPASS (1 << 18)
+# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
+# define DPLLA_TEST_N_BYPASS (1 << 3)
+# define DPLLA_TEST_M_BYPASS (1 << 2)
+# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
+
+#define D_STATE 0x6104
+#define DSPCLK_GATE_D 0x6200
+# 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 */
+# define TVEUNIT_CLOCK_GATE_DISABLE (1 << 20) /* 915-945 */
+# define DVSUNIT_CLOCK_GATE_DISABLE (1 << 19) /* 915-945 */
+# define DSSUNIT_CLOCK_GATE_DISABLE (1 << 18) /* 915-945 */
+# define DDBUNIT_CLOCK_GATE_DISABLE (1 << 17) /* 915-945 */
+# define DPRUNIT_CLOCK_GATE_DISABLE (1 << 16) /* 915-945 */
+# define DPFUNIT_CLOCK_GATE_DISABLE (1 << 15) /* 915-945 */
+# define DPBMUNIT_CLOCK_GATE_DISABLE (1 << 14) /* 915-945 */
+# define DPLSUNIT_CLOCK_GATE_DISABLE (1 << 13) /* 915-945 */
+# define DPLUNIT_CLOCK_GATE_DISABLE (1 << 12) /* 915-945 */
+# define DPOUNIT_CLOCK_GATE_DISABLE (1 << 11)
+# define DPBUNIT_CLOCK_GATE_DISABLE (1 << 10)
+# 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 */
+# define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 915-945 */
+# define OVFUNIT_CLOCK_GATE_DISABLE (1 << 5)
+# define OVBUNIT_CLOCK_GATE_DISABLE (1 << 4)
+/**
+ * This bit must be set on the 830 to prevent hangs when turning off the
+ * overlay scaler.
+ */
+# define OVRUNIT_CLOCK_GATE_DISABLE (1 << 3)
+# define OVCUNIT_CLOCK_GATE_DISABLE (1 << 2)
+# define OVUUNIT_CLOCK_GATE_DISABLE (1 << 1)
+# define ZVUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 830 */
+# define OVLUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 845,865 */
+
+#define RENCLK_GATE_D1 0x6204
+# define BLITTER_CLOCK_GATE_DISABLE (1 << 13) /* 945GM only */
+# define MPEG_CLOCK_GATE_DISABLE (1 << 12) /* 945GM only */
+# define PC_FE_CLOCK_GATE_DISABLE (1 << 11)
+# define PC_BE_CLOCK_GATE_DISABLE (1 << 10)
+# define WINDOWER_CLOCK_GATE_DISABLE (1 << 9)
+# define INTERPOLATOR_CLOCK_GATE_DISABLE (1 << 8)
+# define COLOR_CALCULATOR_CLOCK_GATE_DISABLE (1 << 7)
+# define MOTION_COMP_CLOCK_GATE_DISABLE (1 << 6)
+# define MAG_CLOCK_GATE_DISABLE (1 << 5)
+/** This bit must be unset on 855,865 */
+# define MECI_CLOCK_GATE_DISABLE (1 << 4)
+# define DCMP_CLOCK_GATE_DISABLE (1 << 3)
+# define MEC_CLOCK_GATE_DISABLE (1 << 2)
+# define MECO_CLOCK_GATE_DISABLE (1 << 1)
+/** This bit must be set on 855,865. */
+# define SV_CLOCK_GATE_DISABLE (1 << 0)
+# define I915_MPEG_CLOCK_GATE_DISABLE (1 << 16)
+# define I915_VLD_IP_PR_CLOCK_GATE_DISABLE (1 << 15)
+# define I915_MOTION_COMP_CLOCK_GATE_DISABLE (1 << 14)
+# define I915_BD_BF_CLOCK_GATE_DISABLE (1 << 13)
+# define I915_SF_SE_CLOCK_GATE_DISABLE (1 << 12)
+# define I915_WM_CLOCK_GATE_DISABLE (1 << 11)
+# define I915_IZ_CLOCK_GATE_DISABLE (1 << 10)
+# define I915_PI_CLOCK_GATE_DISABLE (1 << 9)
+# define I915_DI_CLOCK_GATE_DISABLE (1 << 8)
+# define I915_SH_SV_CLOCK_GATE_DISABLE (1 << 7)
+# define I915_PL_DG_QC_FT_CLOCK_GATE_DISABLE (1 << 6)
+# define I915_SC_CLOCK_GATE_DISABLE (1 << 5)
+# define I915_FL_CLOCK_GATE_DISABLE (1 << 4)
+# define I915_DM_CLOCK_GATE_DISABLE (1 << 3)
+# define I915_PS_CLOCK_GATE_DISABLE (1 << 2)
+# define I915_CC_CLOCK_GATE_DISABLE (1 << 1)
+# define I915_BY_CLOCK_GATE_DISABLE (1 << 0)
+
+# define I965_RCZ_CLOCK_GATE_DISABLE (1 << 30)
+/** This bit must always be set on 965G/965GM */
+# define I965_RCC_CLOCK_GATE_DISABLE (1 << 29)
+# define I965_RCPB_CLOCK_GATE_DISABLE (1 << 28)
+# define I965_DAP_CLOCK_GATE_DISABLE (1 << 27)
+# define I965_ROC_CLOCK_GATE_DISABLE (1 << 26)
+# define I965_GW_CLOCK_GATE_DISABLE (1 << 25)
+# define I965_TD_CLOCK_GATE_DISABLE (1 << 24)
+/** This bit must always be set on 965G */
+# define I965_ISC_CLOCK_GATE_DISABLE (1 << 23)
+# define I965_IC_CLOCK_GATE_DISABLE (1 << 22)
+# define I965_EU_CLOCK_GATE_DISABLE (1 << 21)
+# define I965_IF_CLOCK_GATE_DISABLE (1 << 20)
+# define I965_TC_CLOCK_GATE_DISABLE (1 << 19)
+# define I965_SO_CLOCK_GATE_DISABLE (1 << 17)
+# define I965_FBC_CLOCK_GATE_DISABLE (1 << 16)
+# define I965_MARI_CLOCK_GATE_DISABLE (1 << 15)
+# define I965_MASF_CLOCK_GATE_DISABLE (1 << 14)
+# define I965_MAWB_CLOCK_GATE_DISABLE (1 << 13)
+# define I965_EM_CLOCK_GATE_DISABLE (1 << 12)
+# define I965_UC_CLOCK_GATE_DISABLE (1 << 11)
+# define I965_SI_CLOCK_GATE_DISABLE (1 << 6)
+# define I965_MT_CLOCK_GATE_DISABLE (1 << 5)
+# define I965_PL_CLOCK_GATE_DISABLE (1 << 4)
+# define I965_DG_CLOCK_GATE_DISABLE (1 << 3)
+# define I965_QC_CLOCK_GATE_DISABLE (1 << 2)
+# define I965_FT_CLOCK_GATE_DISABLE (1 << 1)
+# define I965_DM_CLOCK_GATE_DISABLE (1 << 0)
+
+#define RENCLK_GATE_D2 0x6208
+#define RAMCLK_GATE_D 0x6210 /* CRL only */
+
+/*
+ * This is a PCI config space register to manipulate backlight brightness
+ * It is used when the BLM_LEGACY_MODE is turned on. When enabled, the first
+ * byte of this config register sets brightness within the range from
+ * 0 to 0xff
+ */
+#define LEGACY_BACKLIGHT_BRIGHTNESS 0xf4
+
+#define BLC_PWM_CTL 0x61254
+#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
+#define BACKLIGHT_MODULATION_FREQ_SHIFT2 (16)
+/**
+ * This is the most significant 15 bits of the number of backlight cycles in a
+ * complete cycle of the modulated backlight control.
+ *
+ * The actual value is this field multiplied by two.
+ */
+#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
+#define BACKLIGHT_MODULATION_FREQ_MASK2 (0xffff << 16)
+#define BLM_LEGACY_MODE (1 << 16)
+
+/**
+ * This is the number of cycles out of the backlight modulation cycle for which
+ * the backlight is on.
+ *
+ * This field must be no greater than the number of cycles in the complete
+ * backlight modulation cycle.
+ */
+#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
+#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
+
+/* On 965+ backlight control is in another register */
+#define BLC_PWM_CTL2 0x61250
+#define BLM_LEGACY_MODE2 (1 << 30)
+
+#define BLM_CTL 0x61260
+#define BLM_THRESHOLD_0 0x61270
+#define BLM_THRESHOLD_1 0x61274
+#define BLM_THRESHOLD_2 0x61278
+#define BLM_THRESHOLD_3 0x6127c
+#define BLM_THRESHOLD_4 0x61280
+#define BLM_THRESHOLD_5 0x61284
+
+#define BLM_ACCUMULATOR_0 0x61290
+#define BLM_ACCUMULATOR_1 0x61294
+#define BLM_ACCUMULATOR_2 0x61298
+#define BLM_ACCUMULATOR_3 0x6129c
+#define BLM_ACCUMULATOR_4 0x612a0
+#define BLM_ACCUMULATOR_5 0x612a4
+
#define FPA0 0x06040
#define FPA1 0x06044
+#define FPB0 0x06048
+#define FPB1 0x0604c
+# define FP_N_DIV_MASK 0x003f0000
+# define FP_N_DIV_SHIFT 16
+# define FP_M1_DIV_MASK 0x00003f00
+# define FP_M1_DIV_SHIFT 8
+# define FP_M2_DIV_MASK 0x0000003f
+# define FP_M2_DIV_SHIFT 0
+
+#define PORT_HOTPLUG_EN 0x61110
+# define SDVOB_HOTPLUG_INT_EN (1 << 26)
+# define SDVOC_HOTPLUG_INT_EN (1 << 25)
+# define TV_HOTPLUG_INT_EN (1 << 18)
+# define CRT_HOTPLUG_INT_EN (1 << 9)
+# define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
+
+#define PORT_HOTPLUG_STAT 0x61114
+# define CRT_HOTPLUG_INT_STATUS (1 << 11)
+# define TV_HOTPLUG_INT_STATUS (1 << 10)
+# define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
+# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
+# define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
+# define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
+# define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
+# define SDVOB_HOTPLUG_INT_STATUS (1 << 6)
+
+#define SDVOB 0x61140
+#define SDVOC 0x61160
+#define SDVO_ENABLE (1 << 31)
+#define SDVO_PIPE_B_SELECT (1 << 30)
+#define SDVO_STALL_SELECT (1 << 29)
+#define SDVO_INTERRUPT_ENABLE (1 << 26)
+/**
+ * 915G/GM SDVO pixel multiplier.
+ *
+ * Programmed value is multiplier - 1, up to 5x.
+ *
+ * \sa DPLL_MD_UDI_MULTIPLIER_MASK
+ */
+#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
+#define SDVO_PORT_MULTIPLY_SHIFT 23
+#define SDVO_PHASE_SELECT_MASK (15 << 19)
+#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
+#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
+#define SDVOC_GANG_MODE (1 << 16)
+#define SDVO_BORDER_ENABLE (1 << 7)
+#define SDVOB_PCIE_CONCURRENCY (1 << 3)
+#define SDVO_DETECTED (1 << 2)
+/* Bits to be preserved when writing */
+#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14))
+#define SDVOC_PRESERVE_MASK (1 << 17)
+
+#define UDIB_SVB_SHB_CODES 0x61144
+#define UDIB_SHA_BLANK_CODES 0x61148
+#define UDIB_START_END_FILL_CODES 0x6114c
+
+
+#define SDVOUDI 0x61150
#define I830_HTOTAL_MASK 0xfff0000
#define I830_HACTIVE_MASK 0x7ff
@@ -770,23 +1237,831 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DVOA 0x61120
#define DVOB 0x61140
#define DVOC 0x61160
-#define DVO_ENABLE (1<<31)
+#define DVO_ENABLE (1 << 31)
+#define DVO_PIPE_B_SELECT (1 << 30)
+#define DVO_PIPE_STALL_UNUSED (0 << 28)
+#define DVO_PIPE_STALL (1 << 28)
+#define DVO_PIPE_STALL_TV (2 << 28)
+#define DVO_PIPE_STALL_MASK (3 << 28)
+#define DVO_USE_VGA_SYNC (1 << 15)
+#define DVO_DATA_ORDER_I740 (0 << 14)
+#define DVO_DATA_ORDER_FP (1 << 14)
+#define DVO_VSYNC_DISABLE (1 << 11)
+#define DVO_HSYNC_DISABLE (1 << 10)
+#define DVO_VSYNC_TRISTATE (1 << 9)
+#define DVO_HSYNC_TRISTATE (1 << 8)
+#define DVO_BORDER_ENABLE (1 << 7)
+#define DVO_DATA_ORDER_GBRG (1 << 6)
+#define DVO_DATA_ORDER_RGGB (0 << 6)
+#define DVO_DATA_ORDER_GBRG_ERRATA (0 << 6)
+#define DVO_DATA_ORDER_RGGB_ERRATA (1 << 6)
+#define DVO_VSYNC_ACTIVE_HIGH (1 << 4)
+#define DVO_HSYNC_ACTIVE_HIGH (1 << 3)
+#define DVO_BLANK_ACTIVE_HIGH (1 << 2)
+#define DVO_OUTPUT_CSTATE_PIXELS (1 << 1) /* SDG only */
+#define DVO_OUTPUT_SOURCE_SIZE_PIXELS (1 << 0) /* SDG only */
+#define DVO_PRESERVE_MASK (0x7<<24)
#define DVOA_SRCDIM 0x61124
#define DVOB_SRCDIM 0x61144
#define DVOC_SRCDIM 0x61164
+#define DVO_SRCDIM_HORIZONTAL_SHIFT 12
+#define DVO_SRCDIM_VERTICAL_SHIFT 0
+/** @defgroup LVDS
+ * @{
+ */
+/**
+ * This register controls the LVDS output enable, pipe selection, and data
+ * format selection.
+ *
+ * All of the clock/data pairs are force powered down by power sequencing.
+ */
#define LVDS 0x61180
+/**
+ * Enables the LVDS port. This bit must be set before DPLLs are enabled, as
+ * the DPLL semantics change when the LVDS is assigned to that pipe.
+ */
+# define LVDS_PORT_EN (1 << 31)
+/** Selects pipe B for LVDS data. Must be set on pre-965. */
+# define LVDS_PIPEB_SELECT (1 << 30)
+
+/* on 965, dithering is enabled in this register, not PFIT_CONTROL */
+# define LVDS_DITHER_ENABLE (1 << 25)
+
+/*
+ * Selects between .0 and .1 formats:
+ *
+ * 0 = 1x18.0, 2x18.0, 1x24.0 or 2x24.0
+ * 1 = 1x24.1 or 2x24.1
+ */
+# define LVDS_DATA_FORMAT_DOT_ONE (1 << 24)
+
+/* Using LE instead of HS on second channel control signal */
+# define LVDS_LE_CONTROL_ENABLE (1 << 23)
+
+/* Using LF instead of VS on second channel control signal */
+# define LVDS_LF_CONTROL_ENABLE (1 << 22)
+
+/* invert vsync signal polarity */
+# define LVDS_VSYNC_POLARITY_INVERT (1 << 21)
+
+/* invert hsync signal polarity */
+# define LVDS_HSYNC_POLARITY_INVERT (1 << 20)
+
+/* invert display enable signal polarity */
+# define LVDS_DE_POLARITY_INVERT (1 << 19)
+
+/*
+ * Control signals for second channel, ignored in single channel modes
+ */
+
+/* send DE, HS, VS on second channel */
+# define LVDS_SECOND_CHANNEL_DE_HS_VS (0 << 17)
+
+# define LVDS_SECOND_CHANNEL_RESERVED (1 << 17)
+
+/* Send zeros instead of DE, HS, VS on second channel */
+# define LVDS_SECOND_CHANNEL_ZEROS (2 << 17)
+
+/* Set DE=0, HS=LE, VS=LF on second channel */
+# define LVDS_SECOND_CHANNEL_HS_VS (3 << 17)
+
+/*
+ * Send duplicate data for channel reserved bits, otherwise send zeros
+ */
+# define LVDS_CHANNEL_DUP_RESERVED (1 << 16)
+
+/*
+ * Enable border for unscaled (or aspect-scaled) display
+ */
+# define LVDS_BORDER_ENABLE (1 << 15)
+
+/*
+ * Tri-state the LVDS buffers when powered down, otherwise
+ * they are set to 0V
+ */
+# define LVDS_POWER_DOWN_TRI_STATE (1 << 10)
+
+/**
+ * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
+ * pixel.
+ */
+# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
+# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
+# define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
+/**
+ * Controls the A3 data pair, which contains the additional LSBs for 24 bit
+ * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
+ * on.
+ */
+# define LVDS_A3_POWER_MASK (3 << 6)
+# define LVDS_A3_POWER_DOWN (0 << 6)
+# define LVDS_A3_POWER_UP (3 << 6)
+/**
+ * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
+ * is set.
+ */
+# define LVDS_CLKB_POWER_MASK (3 << 4)
+# define LVDS_CLKB_POWER_DOWN (0 << 4)
+# define LVDS_CLKB_POWER_UP (3 << 4)
+
+/**
+ * Controls the B0-B3 data pairs. This must be set to match the DPLL p2
+ * setting for whether we are in dual-channel mode. The B3 pair will
+ * additionally only be powered up when LVDS_A3_POWER_UP is set.
+ */
+# define LVDS_B0B3_POWER_MASK (3 << 2)
+# define LVDS_B0B3_POWER_DOWN (0 << 2)
+# define LVDS_B0B3_POWER_UP (3 << 2)
+
+/** @} */
+
+/*
+ * Two channel clock control. Turn this on if you need clkb for two channel mode
+ * Overridden by global LVDS power sequencing
+ */
+
+/* clkb off */
+# define LVDS_CLKB_POWER_DOWN (0 << 4)
+
+/* powered up, but clkb forced to 0 */
+# define LVDS_CLKB_POWER_PARTIAL (1 << 4)
+
+/* clock B running */
+# define LVDS_CLKB_POWER_UP (3 << 4)
+
+/*
+ * Two channel mode B0-B2 control. Sets state when power is on.
+ * Set to POWER_DOWN in single channel mode, other settings enable
+ * two channel mode. The CLKB power control controls whether that clock
+ * is enabled during two channel mode.
+ *
+ */
+/* Everything is off, including B3 and CLKB */
+# define LVDS_B_POWER_DOWN (0 << 2)
+
+/* B0, B1, B2 and data lines forced to 0. timing is active */
+# define LVDS_B_POWER_PARTIAL (1 << 2)
+
+/* data lines active (both timing and colour) */
+# define LVDS_B_POWER_UP (3 << 2)
+
+/** @defgroup TV_CTL
+ * @{
+ */
+#define TV_CTL 0x68000
+/** Enables the TV encoder */
+# define TV_ENC_ENABLE (1 << 31)
+/** Sources the TV encoder input from pipe B instead of A. */
+# define TV_ENC_PIPEB_SELECT (1 << 30)
+/** Outputs composite video (DAC A only) */
+# define TV_ENC_OUTPUT_COMPOSITE (0 << 28)
+/** Outputs SVideo video (DAC B/C) */
+# define TV_ENC_OUTPUT_SVIDEO (1 << 28)
+/** Outputs Component video (DAC A/B/C) */
+# define TV_ENC_OUTPUT_COMPONENT (2 << 28)
+/** Outputs Composite and SVideo (DAC A/B/C) */
+# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE (3 << 28)
+# define TV_TRILEVEL_SYNC (1 << 21)
+/** Enables slow sync generation (945GM only) */
+# define TV_SLOW_SYNC (1 << 20)
+/** Selects 4x oversampling for 480i and 576p */
+# define TV_OVERSAMPLE_4X (0 << 18)
+/** Selects 2x oversampling for 720p and 1080i */
+# define TV_OVERSAMPLE_2X (1 << 18)
+/** Selects no oversampling for 1080p */
+# define TV_OVERSAMPLE_NONE (2 << 18)
+/** Selects 8x oversampling */
+# define TV_OVERSAMPLE_8X (3 << 18)
+/** Selects progressive mode rather than interlaced */
+# define TV_PROGRESSIVE (1 << 17)
+/** Sets the colorburst to PAL mode. Required for non-M PAL modes. */
+# define TV_PAL_BURST (1 << 16)
+/** Field for setting delay of Y compared to C */
+# define TV_YC_SKEW_MASK (7 << 12)
+/** Enables a fix for 480p/576p standard definition modes on the 915GM only */
+# define TV_ENC_SDP_FIX (1 << 11)
+/**
+ * Enables a fix for the 915GM only.
+ *
+ * Not sure what it does.
+ */
+# define TV_ENC_C0_FIX (1 << 10)
+/** Bits that must be preserved by software */
+# define TV_CTL_SAVE ((3 << 8) | (3 << 6))
+# define TV_FUSE_STATE_MASK (3 << 4)
+/** Read-only state that reports all features enabled */
+# define TV_FUSE_STATE_ENABLED (0 << 4)
+/** Read-only state that reports that Macrovision is disabled in hardware*/
+# define TV_FUSE_STATE_NO_MACROVISION (1 << 4)
+/** Read-only state that reports that TV-out is disabled in hardware. */
+# define TV_FUSE_STATE_DISABLED (2 << 4)
+/** Normal operation */
+# define TV_TEST_MODE_NORMAL (0 << 0)
+/** Encoder test pattern 1 - combo pattern */
+# define TV_TEST_MODE_PATTERN_1 (1 << 0)
+/** Encoder test pattern 2 - full screen vertical 75% color bars */
+# define TV_TEST_MODE_PATTERN_2 (2 << 0)
+/** Encoder test pattern 3 - full screen horizontal 75% color bars */
+# define TV_TEST_MODE_PATTERN_3 (3 << 0)
+/** Encoder test pattern 4 - random noise */
+# define TV_TEST_MODE_PATTERN_4 (4 << 0)
+/** Encoder test pattern 5 - linear color ramps */
+# define TV_TEST_MODE_PATTERN_5 (5 << 0)
+/**
+ * This test mode forces the DACs to 50% of full output.
+ *
+ * This is used for load detection in combination with TVDAC_SENSE_MASK
+ */
+# define TV_TEST_MODE_MONITOR_DETECT (7 << 0)
+# define TV_TEST_MODE_MASK (7 << 0)
+/** @} */
+
+/** @defgroup TV_DAC
+ * @{
+ */
+#define TV_DAC 0x68004
+/**
+ * Reports that DAC state change logic has reported change (RO).
+ *
+ * This gets cleared when TV_DAC_STATE_EN is cleared
+*/
+# define TVDAC_STATE_CHG (1 << 31)
+# define TVDAC_SENSE_MASK (7 << 28)
+/** Reports that DAC A voltage is above the detect threshold */
+# define TVDAC_A_SENSE (1 << 30)
+/** Reports that DAC B voltage is above the detect threshold */
+# define TVDAC_B_SENSE (1 << 29)
+/** Reports that DAC C voltage is above the detect threshold */
+# define TVDAC_C_SENSE (1 << 28)
+/**
+ * Enables DAC state detection logic, for load-based TV detection.
+ *
+ * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set
+ * to off, for load detection to work.
+ */
+# define TVDAC_STATE_CHG_EN (1 << 27)
+/** Sets the DAC A sense value to high */
+# define TVDAC_A_SENSE_CTL (1 << 26)
+/** Sets the DAC B sense value to high */
+# define TVDAC_B_SENSE_CTL (1 << 25)
+/** Sets the DAC C sense value to high */
+# define TVDAC_C_SENSE_CTL (1 << 24)
+/** Overrides the ENC_ENABLE and DAC voltage levels */
+# define DAC_CTL_OVERRIDE (1 << 7)
+/** Sets the slew rate. Must be preserved in software */
+# define ENC_TVDAC_SLEW_FAST (1 << 6)
+# define DAC_A_1_3_V (0 << 4)
+# define DAC_A_1_1_V (1 << 4)
+# define DAC_A_0_7_V (2 << 4)
+# define DAC_A_OFF (3 << 4)
+# define DAC_B_1_3_V (0 << 2)
+# define DAC_B_1_1_V (1 << 2)
+# define DAC_B_0_7_V (2 << 2)
+# define DAC_B_OFF (3 << 2)
+# define DAC_C_1_3_V (0 << 0)
+# define DAC_C_1_1_V (1 << 0)
+# define DAC_C_0_7_V (2 << 0)
+# define DAC_C_OFF (3 << 0)
+/** @} */
+
+/**
+ * CSC coefficients are stored in a floating point format with 9 bits of
+ * mantissa and 2 or 3 bits of exponent. The exponent is represented as 2**-n,
+ * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with
+ * -1 (0x3) being the only legal negative value.
+ */
+#define TV_CSC_Y 0x68010
+# define TV_RY_MASK 0x07ff0000
+# define TV_RY_SHIFT 16
+# define TV_GY_MASK 0x00000fff
+# define TV_GY_SHIFT 0
+
+#define TV_CSC_Y2 0x68014
+# define TV_BY_MASK 0x07ff0000
+# define TV_BY_SHIFT 16
+/**
+ * Y attenuation for component video.
+ *
+ * Stored in 1.9 fixed point.
+ */
+# define TV_AY_MASK 0x000003ff
+# define TV_AY_SHIFT 0
+
+#define TV_CSC_U 0x68018
+# define TV_RU_MASK 0x07ff0000
+# define TV_RU_SHIFT 16
+# define TV_GU_MASK 0x000007ff
+# define TV_GU_SHIFT 0
+
+#define TV_CSC_U2 0x6801c
+# define TV_BU_MASK 0x07ff0000
+# define TV_BU_SHIFT 16
+/**
+ * U attenuation for component video.
+ *
+ * Stored in 1.9 fixed point.
+ */
+# define TV_AU_MASK 0x000003ff
+# define TV_AU_SHIFT 0
+
+#define TV_CSC_V 0x68020
+# define TV_RV_MASK 0x0fff0000
+# define TV_RV_SHIFT 16
+# define TV_GV_MASK 0x000007ff
+# define TV_GV_SHIFT 0
+
+#define TV_CSC_V2 0x68024
+# define TV_BV_MASK 0x07ff0000
+# define TV_BV_SHIFT 16
+/**
+ * V attenuation for component video.
+ *
+ * Stored in 1.9 fixed point.
+ */
+# define TV_AV_MASK 0x000007ff
+# define TV_AV_SHIFT 0
+
+/** @defgroup TV_CSC_KNOBS
+ * @{
+ */
+#define TV_CLR_KNOBS 0x68028
+/** 2s-complement brightness adjustment */
+# define TV_BRIGHTNESS_MASK 0xff000000
+# define TV_BRIGHTNESS_SHIFT 24
+/** Contrast adjustment, as a 2.6 unsigned floating point number */
+# define TV_CONTRAST_MASK 0x00ff0000
+# define TV_CONTRAST_SHIFT 16
+/** Saturation adjustment, as a 2.6 unsigned floating point number */
+# define TV_SATURATION_MASK 0x0000ff00
+# define TV_SATURATION_SHIFT 8
+/** Hue adjustment, as an integer phase angle in degrees */
+# define TV_HUE_MASK 0x000000ff
+# define TV_HUE_SHIFT 0
+/** @} */
+
+/** @defgroup TV_CLR_LEVEL
+ * @{
+ */
+#define TV_CLR_LEVEL 0x6802c
+/** Controls the DAC level for black */
+# define TV_BLACK_LEVEL_MASK 0x01ff0000
+# define TV_BLACK_LEVEL_SHIFT 16
+/** Controls the DAC level for blanking */
+# define TV_BLANK_LEVEL_MASK 0x000001ff
+# define TV_BLANK_LEVEL_SHIFT 0
+/* @} */
+
+/** @defgroup TV_H_CTL_1
+ * @{
+ */
+#define TV_H_CTL_1 0x68030
+/** Number of pixels in the hsync. */
+# define TV_HSYNC_END_MASK 0x1fff0000
+# define TV_HSYNC_END_SHIFT 16
+/** Total number of pixels minus one in the line (display and blanking). */
+# define TV_HTOTAL_MASK 0x00001fff
+# define TV_HTOTAL_SHIFT 0
+/** @} */
+
+/** @defgroup TV_H_CTL_2
+ * @{
+ */
+#define TV_H_CTL_2 0x68034
+/** Enables the colorburst (needed for non-component color) */
+# define TV_BURST_ENA (1 << 31)
+/** Offset of the colorburst from the start of hsync, in pixels minus one. */
+# define TV_HBURST_START_SHIFT 16
+# define TV_HBURST_START_MASK 0x1fff0000
+/** Length of the colorburst */
+# define TV_HBURST_LEN_SHIFT 0
+# define TV_HBURST_LEN_MASK 0x0001fff
+/** @} */
+
+/** @defgroup TV_H_CTL_3
+ * @{
+ */
+#define TV_H_CTL_3 0x68038
+/** End of hblank, measured in pixels minus one from start of hsync */
+# define TV_HBLANK_END_SHIFT 16
+# define TV_HBLANK_END_MASK 0x1fff0000
+/** Start of hblank, measured in pixels minus one from start of hsync */
+# define TV_HBLANK_START_SHIFT 0
+# define TV_HBLANK_START_MASK 0x0001fff
+/** @} */
+
+/** @defgroup TV_V_CTL_1
+ * @{
+ */
+#define TV_V_CTL_1 0x6803c
+/** XXX */
+# define TV_NBR_END_SHIFT 16
+# define TV_NBR_END_MASK 0x07ff0000
+/** XXX */
+# define TV_VI_END_F1_SHIFT 8
+# define TV_VI_END_F1_MASK 0x00003f00
+/** XXX */
+# define TV_VI_END_F2_SHIFT 0
+# define TV_VI_END_F2_MASK 0x0000003f
+/** @} */
+
+/** @defgroup TV_V_CTL_2
+ * @{
+ */
+#define TV_V_CTL_2 0x68040
+/** Length of vsync, in half lines */
+# define TV_VSYNC_LEN_MASK 0x07ff0000
+# define TV_VSYNC_LEN_SHIFT 16
+/** Offset of the start of vsync in field 1, measured in one less than the
+ * number of half lines.
+ */
+# define TV_VSYNC_START_F1_MASK 0x00007f00
+# define TV_VSYNC_START_F1_SHIFT 8
+/**
+ * Offset of the start of vsync in field 2, measured in one less than the
+ * number of half lines.
+ */
+# define TV_VSYNC_START_F2_MASK 0x0000007f
+# define TV_VSYNC_START_F2_SHIFT 0
+/** @} */
+
+/** @defgroup TV_V_CTL_3
+ * @{
+ */
+#define TV_V_CTL_3 0x68044
+/** Enables generation of the equalization signal */
+# define TV_EQUAL_ENA (1 << 31)
+/** Length of vsync, in half lines */
+# define TV_VEQ_LEN_MASK 0x007f0000
+# define TV_VEQ_LEN_SHIFT 16
+/** Offset of the start of equalization in field 1, measured in one less than
+ * the number of half lines.
+ */
+# define TV_VEQ_START_F1_MASK 0x0007f00
+# define TV_VEQ_START_F1_SHIFT 8
+/**
+ * Offset of the start of equalization in field 2, measured in one less than
+ * the number of half lines.
+ */
+# define TV_VEQ_START_F2_MASK 0x000007f
+# define TV_VEQ_START_F2_SHIFT 0
+/** @} */
+
+/** @defgroup TV_V_CTL_4
+ * @{
+ */
+#define TV_V_CTL_4 0x68048
+/**
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F1_MASK 0x003f0000
+# define TV_VBURST_START_F1_SHIFT 16
+/**
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F1_MASK 0x000000ff
+# define TV_VBURST_END_F1_SHIFT 0
+/** @} */
+
+/** @defgroup TV_V_CTL_5
+ * @{
+ */
+#define TV_V_CTL_5 0x6804c
+/**
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F2_MASK 0x003f0000
+# define TV_VBURST_START_F2_SHIFT 16
+/**
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F2_MASK 0x000000ff
+# define TV_VBURST_END_F2_SHIFT 0
+/** @} */
+
+/** @defgroup TV_V_CTL_6
+ * @{
+ */
+#define TV_V_CTL_6 0x68050
+/**
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F3_MASK 0x003f0000
+# define TV_VBURST_START_F3_SHIFT 16
+/**
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F3_MASK 0x000000ff
+# define TV_VBURST_END_F3_SHIFT 0
+/** @} */
+
+/** @defgroup TV_V_CTL_7
+ * @{
+ */
+#define TV_V_CTL_7 0x68054
+/**
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F4_MASK 0x003f0000
+# define TV_VBURST_START_F4_SHIFT 16
+/**
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F4_MASK 0x000000ff
+# define TV_VBURST_END_F4_SHIFT 0
+/** @} */
+
+/** @defgroup TV_SC_CTL_1
+ * @{
+ */
+#define TV_SC_CTL_1 0x68060
+/** Turns on the first subcarrier phase generation DDA */
+# define TV_SC_DDA1_EN (1 << 31)
+/** Turns on the first subcarrier phase generation DDA */
+# define TV_SC_DDA2_EN (1 << 30)
+/** Turns on the first subcarrier phase generation DDA */
+# define TV_SC_DDA3_EN (1 << 29)
+/** Sets the subcarrier DDA to reset frequency every other field */
+# define TV_SC_RESET_EVERY_2 (0 << 24)
+/** Sets the subcarrier DDA to reset frequency every fourth field */
+# define TV_SC_RESET_EVERY_4 (1 << 24)
+/** Sets the subcarrier DDA to reset frequency every eighth field */
+# define TV_SC_RESET_EVERY_8 (2 << 24)
+/** Sets the subcarrier DDA to never reset the frequency */
+# define TV_SC_RESET_NEVER (3 << 24)
+/** Sets the peak amplitude of the colorburst.*/
+# define TV_BURST_LEVEL_MASK 0x00ff0000
+# define TV_BURST_LEVEL_SHIFT 16
+/** Sets the increment of the first subcarrier phase generation DDA */
+# define TV_SCDDA1_INC_MASK 0x00000fff
+# define TV_SCDDA1_INC_SHIFT 0
+/** @} */
+
+/** @defgroup TV_SC_CTL_2
+ * @{
+ */
+#define TV_SC_CTL_2 0x68064
+/** Sets the rollover for the second subcarrier phase generation DDA */
+# define TV_SCDDA2_SIZE_MASK 0x7fff0000
+# define TV_SCDDA2_SIZE_SHIFT 16
+/** Sets the increent of the second subcarrier phase generation DDA */
+# define TV_SCDDA2_INC_MASK 0x00007fff
+# define TV_SCDDA2_INC_SHIFT 0
+/** @} */
+
+/** @defgroup TV_SC_CTL_3
+ * @{
+ */
+#define TV_SC_CTL_3 0x68068
+/** Sets the rollover for the third subcarrier phase generation DDA */
+# define TV_SCDDA3_SIZE_MASK 0x7fff0000
+# define TV_SCDDA3_SIZE_SHIFT 16
+/** Sets the increent of the third subcarrier phase generation DDA */
+# define TV_SCDDA3_INC_MASK 0x00007fff
+# define TV_SCDDA3_INC_SHIFT 0
+/** @} */
+
+/** @defgroup TV_WIN_POS
+ * @{
+ */
+#define TV_WIN_POS 0x68070
+/** X coordinate of the display from the start of horizontal active */
+# define TV_XPOS_MASK 0x1fff0000
+# define TV_XPOS_SHIFT 16
+/** Y coordinate of the display from the start of vertical active (NBR) */
+# define TV_YPOS_MASK 0x00000fff
+# define TV_YPOS_SHIFT 0
+/** @} */
+
+/** @defgroup TV_WIN_SIZE
+ * @{
+ */
+#define TV_WIN_SIZE 0x68074
+/** Horizontal size of the display window, measured in pixels*/
+# define TV_XSIZE_MASK 0x1fff0000
+# define TV_XSIZE_SHIFT 16
+/**
+ * Vertical size of the display window, measured in pixels.
+ *
+ * Must be even for interlaced modes.
+ */
+# define TV_YSIZE_MASK 0x00000fff
+# define TV_YSIZE_SHIFT 0
+/** @} */
+
+/** @defgroup TV_FILTER_CTL_1
+ * @{
+ */
+#define TV_FILTER_CTL_1 0x68080
+/**
+ * Enables automatic scaling calculation.
+ *
+ * If set, the rest of the registers are ignored, and the calculated values can
+ * be read back from the register.
+ */
+# define TV_AUTO_SCALE (1 << 31)
+/**
+ * Disables the vertical filter.
+ *
+ * This is required on modes more than 1024 pixels wide */
+# define TV_V_FILTER_BYPASS (1 << 29)
+/** Enables adaptive vertical filtering */
+# define TV_VADAPT (1 << 28)
+# define TV_VADAPT_MODE_MASK (3 << 26)
+/** Selects the least adaptive vertical filtering mode */
+# define TV_VADAPT_MODE_LEAST (0 << 26)
+/** Selects the moderately adaptive vertical filtering mode */
+# define TV_VADAPT_MODE_MODERATE (1 << 26)
+/** Selects the most adaptive vertical filtering mode */
+# define TV_VADAPT_MODE_MOST (3 << 26)
+/**
+ * Sets the horizontal scaling factor.
+ *
+ * This should be the fractional part of the horizontal scaling factor divided
+ * by the oversampling rate. TV_HSCALE should be less than 1, and set to:
+ *
+ * (src width - 1) / ((oversample * dest width) - 1)
+ */
+# define TV_HSCALE_FRAC_MASK 0x00003fff
+# define TV_HSCALE_FRAC_SHIFT 0
+/** @} */
+
+/** @defgroup TV_FILTER_CTL_2
+ * @{
+ */
+#define TV_FILTER_CTL_2 0x68084
+/**
+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1)
+ */
+# define TV_VSCALE_INT_MASK 0x00038000
+# define TV_VSCALE_INT_SHIFT 15
+/**
+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * \sa TV_VSCALE_INT_MASK
+ */
+# define TV_VSCALE_FRAC_MASK 0x00007fff
+# define TV_VSCALE_FRAC_SHIFT 0
+/** @} */
+
+/** @defgroup TV_FILTER_CTL_3
+ * @{
+ */
+#define TV_FILTER_CTL_3 0x68088
+/**
+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1))
+ *
+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
+ */
+# define TV_VSCALE_IP_INT_MASK 0x00038000
+# define TV_VSCALE_IP_INT_SHIFT 15
+/**
+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
+ *
+ * \sa TV_VSCALE_IP_INT_MASK
+ */
+# define TV_VSCALE_IP_FRAC_MASK 0x00007fff
+# define TV_VSCALE_IP_FRAC_SHIFT 0
+/** @} */
+
+/** @defgroup TV_CC_CONTROL
+ * @{
+ */
+#define TV_CC_CONTROL 0x68090
+# define TV_CC_ENABLE (1 << 31)
+/**
+ * Specifies which field to send the CC data in.
+ *
+ * CC data is usually sent in field 0.
+ */
+# define TV_CC_FID_MASK (1 << 27)
+# define TV_CC_FID_SHIFT 27
+/** Sets the horizontal position of the CC data. Usually 135. */
+# define TV_CC_HOFF_MASK 0x03ff0000
+# define TV_CC_HOFF_SHIFT 16
+/** Sets the vertical position of the CC data. Usually 21 */
+# define TV_CC_LINE_MASK 0x0000003f
+# define TV_CC_LINE_SHIFT 0
+/** @} */
+
+/** @defgroup TV_CC_DATA
+ * @{
+ */
+#define TV_CC_DATA 0x68094
+# define TV_CC_RDY (1 << 31)
+/** Second word of CC data to be transmitted. */
+# define TV_CC_DATA_2_MASK 0x007f0000
+# define TV_CC_DATA_2_SHIFT 16
+/** First word of CC data to be transmitted. */
+# define TV_CC_DATA_1_MASK 0x0000007f
+# define TV_CC_DATA_1_SHIFT 0
+/** @}
+ */
+
+/** @{ */
+#define TV_H_LUMA_0 0x68100
+#define TV_H_LUMA_59 0x681ec
+#define TV_H_CHROMA_0 0x68200
+#define TV_H_CHROMA_59 0x682ec
+#define TV_V_LUMA_0 0x68300
+#define TV_V_LUMA_42 0x683a8
+#define TV_V_CHROMA_0 0x68400
+#define TV_V_CHROMA_42 0x684a8
+/** @} */
+
+#define PIPEA_DSL 0x70000
#define PIPEACONF 0x70008
#define PIPEACONF_ENABLE (1<<31)
#define PIPEACONF_DISABLE 0
#define PIPEACONF_DOUBLE_WIDE (1<<30)
+#define I965_PIPECONF_ACTIVE (1<<30)
#define PIPEACONF_SINGLE_WIDE 0
#define PIPEACONF_PIPE_UNLOCKED 0
#define PIPEACONF_PIPE_LOCKED (1<<25)
#define PIPEACONF_PALETTE 0
#define PIPEACONF_GAMMA (1<<24)
+#define PIPECONF_FORCE_BORDER (1<<25)
+#define PIPECONF_PROGRESSIVE (0 << 21)
+#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
+#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
+
+#define PIPEAGCMAXRED 0x70010
+#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
+#define DSPFW2 0x70038
+#define DSPFW3 0x7003c
+/*
+ * The two pipe frame counter registers are not synchronized, so
+ * reading a stable value is somewhat tricky. The following code
+ * should work:
+ *
+ * do {
+ * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> PIPE_FRAME_HIGH_SHIFT;
+ * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >> PIPE_FRAME_LOW_SHIFT);
+ * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> PIPE_FRAME_HIGH_SHIFT);
+ * } while (high1 != high2);
+ * frame = (high1 << 8) | low1;
+ */
+#define PIPEAFRAMEHIGH 0x70040
+#define PIPE_FRAME_HIGH_MASK 0x0000ffff
+#define PIPE_FRAME_HIGH_SHIFT 0
+#define PIPEAFRAMEPIXEL 0x70044
+#define PIPE_FRAME_LOW_MASK 0xff000000
+#define PIPE_FRAME_LOW_SHIFT 24
+/*
+ * Pixel within the current frame is counted in the PIPEAFRAMEPIXEL register
+ * and is 24 bits wide.
+ */
+#define PIPE_PIXEL_MASK 0x00ffffff
+#define PIPE_PIXEL_SHIFT 0
+
+#define PIPEB_DSL 0x71000
#define PIPEBCONF 0x71008
#define PIPEBCONF_ENABLE (1<<31)
@@ -796,10 +2071,18 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define PIPEBCONF_GAMMA (1<<24)
#define PIPEBCONF_PALETTE 0
+#define PIPEBGCMAXRED 0x71010
+#define PIPEBGCMAXGREEN 0x71014
+#define PIPEBGCMAXBLUE 0x71018
+#define PIPEBSTAT 0x71024
+#define PIPEBFRAMEHIGH 0x71040
+#define PIPEBFRAMEPIXEL 0x71044
+
#define DSPACNTR 0x70180
#define DSPBCNTR 0x71180
#define DISPLAY_PLANE_ENABLE (1<<31)
#define DISPLAY_PLANE_DISABLE 0
+#define DISPLAY_PLANE_TILED (1<<10)
#define DISPPLANE_GAMMA_ENABLE (1<<30)
#define DISPPLANE_GAMMA_DISABLE 0
#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
@@ -832,6 +2115,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DSPBADDR DSPBBASE
#define DSPBSTRIDE 0x71188
+#define DSPAKEYVAL 0x70194
+#define DSPAKEYMASK 0x70198
+
#define DSPAPOS 0x7018C /* reserved */
#define DSPASIZE 0x70190
#define DSPBPOS 0x7118C
@@ -843,6 +2129,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DSPBSURF 0x7119C
#define DSPBTILEOFF 0x711A4
+#define VGACNTRL 0x71400
+# define VGA_DISP_DISABLE (1 << 31)
+# define VGA_2X_MODE (1 << 30)
+# define VGA_PIPE_B_SELECT (1 << 29)
+
/* Various masks for reserved bits, etc. */
#define I830_FWATER1_MASK (~((1<<11)|(1<<10)|(1<<9)| \
(1<<8)|(1<<26)|(1<<25)|(1<<24)|(1<<5)|(1<<4)|(1<<3)| \
@@ -880,17 +2171,17 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define I830_GMCH_MEM_128M 0
#define I830_GMCH_GMS_MASK 0x70
-#define I830_GMCH_GMS_DISABLED 0x00
+#define I830_GMCH_GMS_DISABLED 0x00
#define I830_GMCH_GMS_LOCAL 0x10
-#define I830_GMCH_GMS_STOLEN_512 0x20
-#define I830_GMCH_GMS_STOLEN_1024 0x30
-#define I830_GMCH_GMS_STOLEN_8192 0x40
+#define I830_GMCH_GMS_STOLEN_512 0x20
+#define I830_GMCH_GMS_STOLEN_1024 0x30
+#define I830_GMCH_GMS_STOLEN_8192 0x40
#define I830_RDRAM_CHANNEL_TYPE 0x03010
#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)
@@ -899,6 +2190,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4)
#define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4)
#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4)
+#define G33_GMCH_GMS_STOLEN_128M (0x8 << 4)
+#define G33_GMCH_GMS_STOLEN_256M (0x9 << 4)
#define I85X_CAPID 0x44
#define I85X_VARIANT_MASK 0x7
@@ -908,6 +2201,19 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define I852_GME 0x2
#define I852_GM 0x5
+#define I915_GCFGC 0xf0
+#define I915_LOW_FREQUENCY_ENABLE (1 << 7)
+#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
+#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4)
+#define I915_DISPLAY_CLOCK_MASK (7 << 4)
+
+#define I855_HPLLCC 0xc0
+#define I855_CLOCK_CONTROL_MASK (3 << 0)
+#define I855_CLOCK_133_200 (0 << 0)
+#define I855_CLOCK_100_200 (1 << 0)
+#define I855_CLOCK_100_133 (2 << 0)
+#define I855_CLOCK_166_250 (3 << 0)
+
/* BLT commands */
#define COLOR_BLT_CMD ((2<<29)|(0x40<<22)|(0x3))
#define COLOR_BLT_WRITE_ALPHA (1<<21)
@@ -916,17 +2222,22 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|(0x4))
#define XY_COLOR_BLT_WRITE_ALPHA (1<<21)
#define XY_COLOR_BLT_WRITE_RGB (1<<20)
+#define XY_COLOR_BLT_TILED (1<<11)
#define XY_SETUP_CLIP_BLT_CMD ((2<<29)|(3<<22)|1)
#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
+#define XY_SRC_COPY_BLT_SRC_TILED (1<<15)
+#define XY_SRC_COPY_BLT_DST_TILED (1<<11)
#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|0x4)
#define SRC_COPY_BLT_WRITE_ALPHA (1<<21)
#define SRC_COPY_BLT_WRITE_RGB (1<<20)
+#define XY_PAT_BLT_IMMEDIATE ((2<<29)|(0x72<<22))
+
#define XY_MONO_PAT_BLT_CMD ((0x2<<29)|(0x52<<22)|0x7)
#define XY_MONO_PAT_VERT_SEED ((1<<10)|(1<<9)|(1<<8))
#define XY_MONO_PAT_HORT_SEED ((1<<14)|(1<<13)|(1<<12))
@@ -1009,6 +2320,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)
@@ -1324,4 +2637,37 @@ typedef enum {
#define PALETTE_A 0x0a000
#define PALETTE_B 0x0a800
+/* Framebuffer compression */
+#define FBC_CFB_BASE 0x03200 /* 4k page aligned */
+#define FBC_LL_BASE 0x03204 /* 4k page aligned */
+#define FBC_CONTROL 0x03208
+#define FBC_CTL_EN (1<<31)
+#define FBC_CTL_PERIODIC (1<<30)
+#define FBC_CTL_INTERVAL_SHIFT (16)
+#define FBC_CTL_UNCOMPRESSIBLE (1<<14)
+#define FBC_CTL_STRIDE_SHIFT (5)
+#define FBC_CTL_FENCENO (1<<0)
+#define FBC_COMMAND 0x0320c
+#define FBC_CMD_COMPRESS (1<<0)
+#define FBC_STATUS 0x03210
+#define FBC_STAT_COMPRESSING (1<<31)
+#define FBC_STAT_COMPRESSED (1<<30)
+#define FBC_STAT_MODIFIED (1<<29)
+#define FBC_STAT_CURRENT_LINE (1<<0)
+#define FBC_CONTROL2 0x03214
+#define FBC_CTL_FENCE_DBL (0<<4)
+#define FBC_CTL_IDLE_IMM (0<<2)
+#define FBC_CTL_IDLE_FULL (1<<2)
+#define FBC_CTL_IDLE_LINE (2<<2)
+#define FBC_CTL_IDLE_DEBUG (3<<2)
+#define FBC_CTL_CPU_FENCE (1<<1)
+#define FBC_CTL_PLANEA (0<<0)
+#define FBC_CTL_PLANEB (1<<0)
+#define FBC_FENCE_OFF 0x0321b
+#define FBC_MOD_NUM 0x03220
+#define FBC_TAG_DEBUG 0x03300
+
+#define FBC_LL_SIZE (1536)
+#define FBC_LL_PAD (32)
+
#endif /* _I810_REG_H */
diff --git a/driver/xf86-video-intel/src/i830.h b/driver/xf86-video-intel/src/i830.h
index 38a880fb8..132f0893a 100644
--- a/driver/xf86-video-intel/src/i830.h
+++ b/driver/xf86-video-intel/src/i830.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
@@ -57,55 +59,64 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xf86xv.h"
#include "xf86int10.h"
#include "vbe.h"
-#include "vbeModes.h"
#include "vgaHW.h"
-#include "randrstr.h"
+#include "xf86Crtc.h"
+#include "xf86RandR12.h"
+
+#include "xorg-server.h"
+#ifdef XSERVER_LIBPCIACCESS
+#include <pciaccess.h>
+#endif
#ifdef XF86DRI
#include "xf86drm.h"
+#ifdef XF86DRI_MM
+#include "xf86mm.h"
+#endif
#include "sarea.h"
#define _XF86DRI_SERVER_
#include "dri.h"
#include "GL/glxint.h"
#include "i830_dri.h"
+#ifdef DAMAGE
+#include "damage.h"
+#endif
#endif
+#ifdef I830_USE_EXA
+#include "exa.h"
+Bool I830EXAInit(ScreenPtr pScreen);
+#define EXA_LINEAR_EXTRA (64*1024)
+unsigned long long I830TexOffsetStart(PixmapPtr pPix);
+#endif
+
+#ifdef I830_USE_XAA
+Bool I830XAAInit(ScreenPtr pScreen);
+#endif
+
+typedef struct _I830OutputRec I830OutputRec, *I830OutputPtr;
+
#include "common.h"
+#include "i830_sdvo.h"
+#include "i2c_vid.h"
+/* I830 Video support */
#define NEED_REPLIES /* ? */
#define EXTENSION_PROC_ARGS void *
#include "extnsionst.h" /* required */
#include <X11/extensions/panoramiXproto.h> /* required */
-/* I830 Video BIOS support */
-
/*
* The mode handling is based upon the VESA driver written by
* Paulo César Pereira de Andrade <pcpa@conectiva.com.br>.
*/
-#define PIPE_NONE 0<<0
-#define PIPE_CRT 1<<0
-#define PIPE_TV 1<<1
-#define PIPE_DFP 1<<2
-#define PIPE_LFP 1<<3
-#define PIPE_CRT2 1<<4
-#define PIPE_TV2 1<<5
-#define PIPE_DFP2 1<<6
-#define PIPE_LFP2 1<<7
-
-typedef struct _VESARec {
- /* SVGA state */
- pointer state, pstate;
- int statePage, stateSize, stateMode, stateRefresh;
- CARD32 *savedPal;
- int savedScanlinePitch;
- /* Don't try to set the refresh rate for any modes. */
- Bool useDefaultRefresh;
- /* display start */
- int x, y;
-} VESARec, *VESAPtr;
-
+#ifdef XF86DRI
+#define I830_MM_MINPAGES 512
+#define I830_MM_MAXSIZE (32*1024)
+#define I830_KERNEL_MM (1 << 0) /* Initialize the kernel memory manager*/
+#define I830_KERNEL_TEX (1 << 1) /* Allocate texture memory pool */
+#endif
typedef struct _I830Rec *I830Ptr;
@@ -116,30 +127,76 @@ typedef CARD8(*I830ReadIndexedByteFunc)(I830Ptr pI830, IOADDRESS addr,
typedef void (*I830WriteByteFunc)(I830Ptr pI830, IOADDRESS addr, CARD8 value);
typedef CARD8(*I830ReadByteFunc)(I830Ptr pI830, IOADDRESS addr);
-/* Linear region allocated in framebuffer. */
-typedef struct _I830MemPool *I830MemPoolPtr;
-typedef struct _I830MemRange *I830MemRangePtr;
-typedef struct _I830MemRange {
- long Start;
- long End;
- long Size;
- unsigned long Physical;
- unsigned long Offset; /* Offset of AGP-allocated portion */
- unsigned long Alignment;
- int Key;
- I830MemPoolPtr Pool;
-} I830MemRange;
-
-typedef struct _I830MemPool {
- I830MemRange Total;
- I830MemRange Free;
- I830MemRange Fixed;
- I830MemRange Allocated;
-} I830MemPool;
+enum tile_format {
+ TILE_NONE,
+ TILE_XMAJOR,
+ TILE_YMAJOR
+};
+
+/** Record of a linear allocation in the aperture. */
+typedef struct _i830_memory i830_memory;
+struct _i830_memory {
+ /** Offset of the allocation in card VM */
+ unsigned long offset;
+ /** End of the allocation in card VM */
+ unsigned long end;
+ /**
+ * Requested size of the allocation: doesn't count padding.
+ *
+ * Any bound memory will cover offset to (offset + size).
+ */
+ unsigned long size;
+ /**
+ * Allocated aperture size, taking into account padding to allow for
+ * tiling.
+ */
+ unsigned long allocated_size;
+ /**
+ * Physical (or more properly, bus) address of the allocation.
+ * Only set if requested during allocation.
+ */
+ uint64_t bus_addr;
+ /** AGP memory handle */
+ int key;
+ /**
+ * Whether or not the AGP memory (if any) is currently bound.
+ */
+ Bool bound;
+ /**
+ * Offset that the AGP-allocated memory (if any) is to be bound to.
+ *
+ * This is either @offset or pI830->stolen_size
+ */
+ unsigned long agp_offset;
+
+ enum tile_format tiling;
+ /**
+ * Index of the fence register representing the tiled surface, when
+ * bound.
+ */
+ int fence_nr;
+ /** Pitch value in bytes for tiled surfaces */
+ unsigned int pitch;
+
+ /** Description of the allocation, for logging */
+ char *name;
+
+ /** @{
+ * Memory allocator linked list pointers
+ */
+ i830_memory *next;
+ i830_memory *prev;
+ /** @} */
+
+#ifdef XF86DRI_MM
+ drmBO bo;
+ Bool lifetime_fixed_offset;
+#endif
+};
typedef struct {
int tail_mask;
- I830MemRange mem;
+ i830_memory *mem;
unsigned char *virtual_start;
int head;
int tail;
@@ -147,10 +204,6 @@ typedef struct {
} I830RingBuffer;
typedef struct {
- unsigned int Fence[FENCE_NEW_NR * 2];
-} I830RegRec, *I830RegPtr;
-
-typedef struct {
int lastInstance;
int refCount;
ScrnInfoPtr pScrn_1;
@@ -161,51 +214,147 @@ typedef struct {
#endif
} I830EntRec, *I830EntPtr;
-typedef struct _MergedDisplayModeRec {
- DisplayModePtr First;
- DisplayModePtr Second;
- int SecondPosition;
-} I830MergedDisplayModeRec, *I830MergedDisplayModePtr;
-
-typedef struct _I830XineramaData {
- int x;
- int y;
- int width;
- int height;
-} I830XineramaData;
-
-typedef struct _ModePrivateRec {
- I830MergedDisplayModeRec merged;
- VbeModeInfoData vbeData;
-} I830ModePrivateRec, *I830ModePrivatePtr;
+/* store information about an Ixxx DVO */
+/* The i830->i865 use multiple DVOs with multiple i2cs */
+/* the i915, i945 have a single sDVO i2c bus - which is different */
+#define MAX_OUTPUTS 6
+
+#define I830_I2C_BUS_DVO 1
+#define I830_I2C_BUS_SDVO 2
+
+/* these are outputs from the chip - integrated only
+ external chips are via DVO or SDVO output */
+#define I830_OUTPUT_UNUSED 0
+#define I830_OUTPUT_ANALOG 1
+#define I830_OUTPUT_DVO_TMDS 2
+#define I830_OUTPUT_DVO_LVDS 3
+#define I830_OUTPUT_DVO_TVOUT 4
+#define I830_OUTPUT_SDVO 5
+#define I830_OUTPUT_LVDS 6
+#define I830_OUTPUT_TVOUT 7
+
+struct _I830DVODriver {
+ int type;
+ char *modulename;
+ char *fntablename;
+ unsigned int dvo_reg;
+ uint32_t gpio;
+ int address;
+ const char **symbols;
+ I830I2CVidOutputRec *vid_rec;
+ void *dev_priv;
+ pointer modhandle;
+ DisplayModePtr panel_fixed_mode;
+ Bool panel_wants_dither;
+};
+
+extern const char *i830_output_type_names[];
+
+typedef struct _I830CrtcPrivateRec {
+ int pipe;
+ int plane;
+
+ Bool enabled;
+
+ int dpms_mode;
+
+ /* Lookup table values to be set when the CRTC is enabled */
+ CARD8 lut_r[256], lut_g[256], lut_b[256];
+
+ i830_memory *rotate_mem;
+ /* Card virtual address of the cursor */
+ unsigned long cursor_offset;
+ unsigned long cursor_argb_offset;
+ /* Physical or virtual addresses of the cursor for setting in the cursor
+ * registers.
+ */
+ uint64_t cursor_addr;
+ unsigned long cursor_argb_addr;
+ Bool cursor_is_argb;
+} I830CrtcPrivateRec, *I830CrtcPrivatePtr;
+
+#define I830CrtcPrivate(c) ((I830CrtcPrivatePtr) (c)->driver_private)
+
+typedef struct _I830OutputPrivateRec {
+ int type;
+ I2CBusPtr pI2CBus;
+ I2CBusPtr pDDCBus;
+ struct _I830DVODriver *i2c_drv;
+ Bool load_detect_temp;
+ int pipe_mask;
+ int clone_mask;
+ /** Output-private structure. Should replace i2c_drv */
+ void *dev_priv;
+} I830OutputPrivateRec, *I830OutputPrivatePtr;
+
+#define I830OutputPrivate(o) ((I830OutputPrivatePtr) (o)->driver_private)
+
+/** enumeration of 3d consumers so some can maintain invariant state. */
+enum last_3d {
+ LAST_3D_OTHER,
+ LAST_3D_VIDEO,
+ LAST_3D_RENDER,
+ LAST_3D_ROTATION
+};
-typedef struct _region {
- int x0,x1,y0,y1;
-} region;
+/*
+ * Backlight control has some unfortunate properties:
+ * - many machines won't give us brightness change notifications
+ * o brightness hotkeys
+ * o events like AC plug/unplug (can be controlled via _DOS setting)
+ * o ambient light sensor triggered changes
+ * - some machines use the so-called "legacy" backlight interface
+ * o resulting brightness is a combo of LBB and PWM values
+ * o LBB sits in config space
+ * - some machines have ACPI methods for changing brightness
+ * o one of the few ways the X server and firmware can stay in sync
+ * - new machines have the IGD OpRegion interface available
+ * o a reliable way of keeping the firmware and X in sync
+ *
+ * So the real problem is on machines where ACPI or OpRegion methods aren't
+ * available. In that case, problems can occur:
+ * 1) the BIOS and X will have different ideas of what the brightness is,
+ * leading to unexpected results when the brightness is increased or
+ * decreased via hotkey or X protocol
+ * 2) unless X takes the legacy register into account, machines using it
+ * may prevent X from raising the brightness above 0 if the firmware
+ * set LBB to 0
+ * Given these problems, we provide the user with a selection of methods,
+ * so they can choose an ideal one for their platform (assuming our quirk
+ * code picks the wrong one).
+ *
+ * Four different backlight control methods are available:
+ * BCM_NATIVE: only ever touch the native backlight control registers
+ * This method may be susceptible to problem (2) above if the firmware
+ * modifies the legacy registers.
+ * BCM_LEGACY: only ever touch the legacy backlight control registers
+ * This method may be susceptible to problem (1) above if the firmware
+ * also modifies the legacy registers.
+ * BCM_COMBO: try to use both sets
+ * In this case, the driver will try to modify both sets of registers
+ * if needed. To avoid problem (2) above it may set the LBB register
+ * to a non-zero value if the brightness is to be increased. It's still
+ * susceptible to problem (1), but to a lesser extent than the LEGACY only
+ * method.
+ * BCM_KERNEL: use kernel methods for controlling the backlight
+ * This is only available on some platforms, but where present this can
+ * provide the best user experience.
+ */
+enum backlight_control {
+ BCM_NATIVE = 0,
+ BCM_LEGACY,
+ BCM_COMBO,
+ BCM_KERNEL,
+};
typedef struct _I830Rec {
unsigned char *MMIOBase;
+ unsigned char *GTTBase;
unsigned char *FbBase;
int cpp;
- unsigned int bios_version;
-
- Bool newPipeSwitch;
-
- Bool fakeSwitch;
-
- int fixedPipe;
-
- DisplayModePtr currentMode;
-
- Bool Clone;
- int CloneRefresh;
- int CloneHDisplay;
- int CloneVDisplay;
-
I830EntPtr entityPrivate;
- int pipe, origPipe;
int init;
unsigned int bufferOffset; /* for I830SelectBuffer */
@@ -215,98 +364,76 @@ typedef struct _I830Rec {
/* These are set in PreInit and never changed. */
long FbMapSize;
- long TotalVideoRam;
- I830MemRange StolenMemory; /* pre-allocated memory */
- long BIOSMemorySize; /* min stolen pool size */
- int BIOSMemSizeLoc;
-
- /* These change according to what has been allocated. */
- long FreeMemory;
- I830MemRange MemoryAperture;
- I830MemPool StolenPool;
- long allocatedMemory;
-
- /* Regions allocated either from the above pools, or from agpgart. */
- /* for single and dual head configurations */
- I830MemRange FrontBuffer;
- I830MemRange FrontBuffer2;
- I830MemRange Scratch;
- I830MemRange Scratch2;
-
+ long GTTMapSize;
+
+ /**
+ * Linked list of video memory allocations. The head and tail are
+ * dummy entries that bound the allocation area.
+ */
+ i830_memory *memory_list;
+ /** Linked list of buffer object memory allocations */
+ i830_memory *bo_list;
+ long stolen_size; /**< bytes of pre-bound stolen memory */
+ int gtt_acquired; /**< whether we currently own the AGP */
+
+ i830_memory *front_buffer;
+ i830_memory *front_buffer_2;
+ i830_memory *compressed_front_buffer;
+ i830_memory *compressed_ll_buffer;
+ /* One big buffer for all cursors for kernels that support this */
+ i830_memory *cursor_mem;
+ /* separate small buffers for kernels that support this */
+ i830_memory *cursor_mem_classic[2];
+ i830_memory *cursor_mem_argb[2];
+ i830_memory *xaa_scratch;
+ i830_memory *xaa_scratch_2;
+#ifdef I830_USE_EXA
+ i830_memory *exa_offscreen;
+ i830_memory *exa_965_state;
+#endif
/* Regions allocated either from the above pools, or from agpgart. */
- I830MemRange *CursorMem;
- I830MemRange *CursorMemARGB;
I830RingBuffer *LpRing;
-#if REMAP_RESERVED
- I830MemRange Dummy;
-#endif
-
#ifdef I830_XV
/* For Xvideo */
- I830MemRange *OverlayMem;
- I830MemRange LinearMem;
+ i830_memory *overlay_regs;
#endif
- int LinearAlloc;
-
- Bool MergedFB;
- ScrnInfoPtr pScrn_2;
- char *SecondHSync;
- char *SecondVRefresh;
- char *MetaModes;
- int SecondPosition;
- int FirstXOffs, FirstYOffs, SecondXOffs, SecondYOffs;
- int FirstframeX0, FirstframeX1, FirstframeY0, FirstframeY1;
- int MBXNR1XMAX, MBXNR1YMAX, MBXNR2XMAX, MBXNR2YMAX;
- Bool NonRect, HaveNonRect, HaveOffsRegions, MouseRestrictions;
- int maxFirst_X1, maxFirst_X2, maxFirst_Y1, maxFirst_Y2;
- int maxSecond_X1, maxSecond_X2, maxSecond_Y1, maxSecond_Y2;
- region NonRectDead, OffDead1, OffDead2;
- Bool IntelXinerama;
- Bool SecondIsScrn0;
- ExtensionEntry *XineramaExtEntry;
- int I830XineramaVX, I830XineramaVY;
-
XF86ModReqInfo shadowReq; /* to test for later libshadow */
- I830MemRange RotatedMem;
- I830MemRange RotatedMem2;
Rotation rotation;
- int InitialRotation;
- int displayWidth;
void (*PointerMoved)(int, int, int);
CreateScreenResourcesProcPtr CreateScreenResources;
- int *used3D;
- I830MemRange ContextMem;
+ i830_memory *logical_context;
+
#ifdef XF86DRI
- I830MemRange BackBuffer;
- I830MemRange DepthBuffer;
- I830MemRange TexMem;
+ i830_memory *back_buffer;
+ i830_memory *third_buffer;
+ i830_memory *depth_buffer;
+ i830_memory *textures; /**< Compatibility texture memory */
+ i830_memory *memory_manager; /**< DRI memory manager aperture */
+ i830_memory *hw_status; /* for G33 hw status page alloc */
+
int TexGranularity;
int drmMinor;
- Bool have3DWindows;
+ Bool allocate_classic_textures;
- unsigned int front_tiled;
- unsigned int back_tiled;
- unsigned int depth_tiled;
- unsigned int rotated_tiled;
- unsigned int rotated2_tiled;
+ Bool want_vblank_interrupts;
+#ifdef DAMAGE
+ DamagePtr pDamage;
+ RegionRec driRegion;
+#endif
#endif
Bool NeedRingBufferLow;
Bool allowPageFlip;
- Bool disableTiling;
+ Bool TripleBuffer;
+ Bool tiling;
+ Bool fb_compression;
int backPitch;
Bool CursorNeedsPhysical;
- Bool CursorIsARGB;
- CursorPtr pCurs;
-
- int MonType1;
- int MonType2;
- Bool specifiedMonitor;
-
+
DGAModePtr DGAModes;
int numDGAModes;
Bool DGAactive;
@@ -317,28 +444,47 @@ typedef struct _I830Rec {
unsigned long MMIOAddr;
IOADDRESS ioBase;
EntityInfoPtr pEnt;
+#if XSERVER_LIBPCIACCESS
+ struct pci_device *PciInfo;
+#else
pciVideoPtr PciInfo;
PCITAG PciTag;
+#endif
CARD8 variant;
unsigned int BR[20];
- int GttBound;
-
unsigned char **ScanlineColorExpandBuffers;
int NumScanlineColorExpandBuffers;
int nextColorExpandBuf;
- I830RegRec SavedReg;
- I830RegRec ModeReg;
+ Bool fence_used[FENCE_NEW_NR];
+ Bool useEXA;
Bool noAccel;
Bool SWCursor;
- Bool cursorOn;
+#ifdef I830_USE_XAA
XAAInfoRecPtr AccelInfoRec;
- xf86CursorInfoPtr CursorInfoRec;
+
+ /* additional XAA accelerated Composite support */
+ CompositeProcPtr saved_composite;
+ Bool (*xaa_check_composite)(int op, PicturePtr pSrc, PicturePtr pMask,
+ PicturePtr pDst);
+ Bool (*xaa_prepare_composite)(int op, PicturePtr pSrc, PicturePtr pMask,
+ PicturePtr pDst, PixmapPtr pSrcPixmap,
+ PixmapPtr pMaskPixmap, PixmapPtr pDstPixmap);
+ void (*xaa_composite)(PixmapPtr pDst, int xSrc, int ySrc,
+ int xMask, int yMask, int xDst, int yDst,
+ int w, int h);
+ void (*xaa_done_composite)(PixmapPtr pDst);
+#endif
CloseScreenProcPtr CloseScreen;
+#ifdef I830_USE_EXA
+ ExaDriverPtr EXADriverPtr;
+ PixmapPtr pSrcPixmap;
+#endif
+
I830WriteIndexedByteFunc writeControl;
I830ReadIndexedByteFunc readControl;
I830WriteByteFunc writeStandard;
@@ -354,6 +500,14 @@ typedef struct _I830Rec {
Bool *overlayOn;
#endif
+ /* EXA render state */
+ float scale_units[2][2];
+ /** Transform pointers for src/mask, or NULL if identity */
+ PictTransform *transform[2];
+ /* i915 EXA render state */
+ CARD32 mapstate[6];
+ CARD32 samplerstate[6];
+
Bool directRenderingDisabled; /* DRI disabled in PreInit. */
Bool directRenderingEnabled; /* DRI enabled this generation. */
@@ -372,46 +526,13 @@ typedef struct _I830Rec {
/* Broken-out options. */
OptionInfoPtr Options;
- /* Stolen memory support */
Bool StolenOnly;
- /* Video BIOS support. */
- vbeInfoPtr pVbe;
- VbeInfoBlock *vbeInfo;
- VESAPtr vesa;
-
- Bool overrideBIOSMemSize;
- int saveBIOSMemSize;
- int newBIOSMemSize;
- Bool useSWF1;
- int saveSWF1;
-
Bool swfSaved;
CARD32 saveSWF0;
CARD32 saveSWF4;
- /* Use BIOS call 0x5f05 to set the refresh rate. */
- Bool useExtendedRefresh;
-
Bool checkDevices;
- int monitorSwitch;
- int operatingDevices;
- int toggleDevices;
- int savedDevices;
- int lastDevice0, lastDevice1, lastDevice2;
-
- /* These are indexed by the display types */
- Bool displayAttached[NumDisplayTypes];
- Bool displayPresent[NumDisplayTypes];
- BoxRec displaySize[NumDisplayTypes];
-
- /* [0] is Pipe A, [1] is Pipe B. */
- int availablePipes;
- int pipeDevices[MAX_DISPLAY_PIPES];
- /* [0] is display plane A, [1] is display plane B. */
- Bool pipeEnabled[MAX_DISPLAY_PIPES];
- BoxRec pipeDisplaySize[MAX_DISPLAY_PIPES];
- int planeEnabled[MAX_DISPLAY_PIPES];
/* Driver phase/state information */
Bool preinit;
@@ -425,55 +546,146 @@ typedef struct _I830Rec {
int yoffset;
unsigned int SaveGeneration;
- Bool vbeRestoreWorkaround;
- Bool displayInfo;
- Bool devicePresence;
OsTimerPtr devicesTimer;
- CARD32 savedAsurf;
- CARD32 savedBsurf;
+ int ddc2;
+
+ enum backlight_control backlight_control_method;
+
+ CARD32 saveDSPACNTR;
+ CARD32 saveDSPBCNTR;
+ CARD32 savePIPEACONF;
+ CARD32 savePIPEBCONF;
+ CARD32 savePIPEASRC;
+ CARD32 savePIPEBSRC;
+ CARD32 saveFPA0;
+ CARD32 saveFPA1;
+ CARD32 saveDPLL_A;
+ CARD32 saveDPLL_A_MD;
+ CARD32 saveHTOTAL_A;
+ CARD32 saveHBLANK_A;
+ CARD32 saveHSYNC_A;
+ CARD32 saveVTOTAL_A;
+ CARD32 saveVBLANK_A;
+ CARD32 saveVSYNC_A;
+ CARD32 saveBCLRPAT_A;
+ CARD32 saveDSPASTRIDE;
+ CARD32 saveDSPASIZE;
+ CARD32 saveDSPAPOS;
+ CARD32 saveDSPABASE;
+ CARD32 saveDSPASURF;
+ CARD32 saveDSPATILEOFF;
+ CARD32 saveFPB0;
+ CARD32 saveFPB1;
+ CARD32 saveDPLL_B;
+ CARD32 saveDPLL_B_MD;
+ CARD32 saveHTOTAL_B;
+ CARD32 saveHBLANK_B;
+ CARD32 saveHSYNC_B;
+ CARD32 saveVTOTAL_B;
+ CARD32 saveVBLANK_B;
+ CARD32 saveVSYNC_B;
+ CARD32 saveBCLRPAT_B;
+ CARD32 saveDSPBSTRIDE;
+ CARD32 saveDSPBSIZE;
+ CARD32 saveDSPBPOS;
+ CARD32 saveDSPBBASE;
+ CARD32 saveDSPBSURF;
+ CARD32 saveDSPBTILEOFF;
+ CARD32 saveVCLK_DIVISOR_VGA0;
+ CARD32 saveVCLK_DIVISOR_VGA1;
+ CARD32 saveVCLK_POST_DIV;
+ CARD32 saveVGACNTRL;
+ CARD32 saveADPA;
+ CARD32 saveLVDS;
+ CARD32 saveDVOA;
+ CARD32 saveDVOB;
+ CARD32 saveDVOC;
+ CARD32 savePP_ON;
+ CARD32 savePP_OFF;
+ CARD32 savePP_CONTROL;
+ CARD32 savePP_CYCLE;
+ CARD32 savePFIT_CONTROL;
+ CARD32 savePaletteA[256];
+ CARD32 savePaletteB[256];
+ CARD32 saveSWF[17];
+ CARD32 saveBLC_PWM_CTL;
+ CARD32 saveBLC_PWM_CTL2;
+ CARD32 saveFBC_CFB_BASE;
+ CARD32 saveFBC_LL_BASE;
+ CARD32 saveFBC_CONTROL2;
+ CARD32 saveFBC_CONTROL;
+ CARD32 saveFBC_FENCE_OFF;
+
+ enum last_3d *last_3d;
+
+ /** Enables logging of debug output related to mode switching. */
+ Bool debug_modes;
+ unsigned int quirk_flag;
} I830Rec;
#define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
-#define I830REGPTR(p) (&(I830PTR(p)->ModeReg))
#define I830_SELECT_FRONT 0
#define I830_SELECT_BACK 1
#define I830_SELECT_DEPTH 2
+#define I830_SELECT_THIRD 3
/* I830 specific functions */
extern int I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis);
extern void I830SetPIOAccess(I830Ptr pI830);
extern void I830SetMMIOAccess(I830Ptr pI830);
-extern void I830PrintErrorState(ScrnInfoPtr pScrn);
-extern void I965PrintErrorState(ScrnInfoPtr pScrn);
extern void I830Sync(ScrnInfoPtr pScrn);
extern void I830InitHWCursor(ScrnInfoPtr pScrn);
+extern void I830SetPipeCursor (xf86CrtcPtr crtc, Bool force);
extern Bool I830CursorInit(ScreenPtr pScreen);
extern void IntelEmitInvarientState(ScrnInfoPtr pScrn);
extern void I830EmitInvarientState(ScrnInfoPtr pScrn);
extern void I915EmitInvarientState(ScrnInfoPtr pScrn);
extern void I830SelectBuffer(ScrnInfoPtr pScrn, int buffer);
+void i830_update_cursor_offsets(ScrnInfoPtr pScrn);
-extern void I830RefreshRing(ScrnInfoPtr pScrn);
-extern void I830EmitFlush(ScrnInfoPtr pScrn);
+/* CRTC-based cursor functions */
+void
+i830_crtc_load_cursor_image (xf86CrtcPtr crtc, unsigned char *src);
+
+#ifdef ARGB_CURSOR
+void
+i830_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image);
+#endif
-extern Bool I830DGAInit(ScreenPtr pScreen);
+void
+i830_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y);
+
+void
+i830_crtc_show_cursor (xf86CrtcPtr crtc);
+
+void
+i830_crtc_hide_cursor (xf86CrtcPtr crtc);
+
+void
+i830_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg);
+
+extern void i830_refresh_ring(ScrnInfoPtr pScrn);
+extern void I830EmitFlush(ScrnInfoPtr pScrn);
#ifdef I830_XV
extern void I830InitVideo(ScreenPtr pScreen);
-extern void I830VideoSwitchModeBefore(ScrnInfoPtr pScrn, DisplayModePtr mode);
-extern void I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode);
+extern void i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on);
#endif
-extern Bool I830AllocateRotatedBuffer(ScrnInfoPtr pScrn, const int flags);
-extern Bool I830AllocateRotated2Buffer(ScrnInfoPtr pScrn, const int flags);
+int
+i830_crtc_pipe (xf86CrtcPtr crtc);
+
+Bool
+i830_pipe_a_require_activate (ScrnInfoPtr scrn);
+
+void
+i830_pipe_a_require_deactivate (ScrnInfoPtr scrn);
+
#ifdef XF86DRI
extern Bool I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags);
-extern Bool I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags);
-extern Bool I830AllocateDepthBuffer(ScrnInfoPtr pScrn, const int flags);
-extern Bool I830AllocateTextureMemory(ScrnInfoPtr pScrn, const int flags);
extern void I830SetupMemoryTiling(ScrnInfoPtr pScrn);
extern Bool I830DRIScreenInit(ScreenPtr pScreen);
extern Bool I830CheckDRIAvailable(ScrnInfoPtr pScrn);
@@ -481,14 +693,16 @@ extern Bool I830DRIDoMappings(ScreenPtr pScreen);
extern Bool I830DRIResume(ScreenPtr pScreen);
extern void I830DRICloseScreen(ScreenPtr pScreen);
extern Bool I830DRIFinishScreenInit(ScreenPtr pScreen);
-extern Bool I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea);
-extern void I830DRIUnmapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea);
-extern Bool I830DRIMapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea);
extern void I830DRIUnlock(ScrnInfoPtr pScrn);
extern Bool I830DRILock(ScrnInfoPtr pScrn);
extern Bool I830DRISetVBlankInterrupt (ScrnInfoPtr pScrn, Bool on);
+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);
+unsigned long intel_get_pixmap_pitch(PixmapPtr pPix);
extern Bool I830AccelInit(ScreenPtr pScreen);
extern void I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
int ydir, int rop,
@@ -502,75 +716,131 @@ extern void I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
extern void I830SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
int w, int h);
-extern void I830ResetAllocations(ScrnInfoPtr pScrn, const int flags);
+Bool i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset,
+ unsigned long size);
+void i830_allocator_fini(ScrnInfoPtr pScrn);
+i830_memory * i830_allocate_memory(ScrnInfoPtr pScrn, const char *name,
+ unsigned long size, unsigned long alignment,
+ int flags);
+i830_memory *i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name,
+ unsigned long size,
+ unsigned long pitch,
+ unsigned long alignment, int flags,
+ enum tile_format tile_format);
+void i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity,
+ const char *prefix);
+void i830_reset_allocations(ScrnInfoPtr pScrn);
+void i830_free_3d_memory(ScrnInfoPtr pScrn);
+void i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem);
extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn);
-extern long I830GetExcessMemoryAllocations(ScrnInfoPtr pScrn);
-extern Bool I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags);
-extern Bool I830DoPoolAllocation(ScrnInfoPtr pScrn, I830MemPool *pool);
-extern Bool I830FixupOffsets(ScrnInfoPtr pScrn);
-extern Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
-extern Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
-extern unsigned long I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result,
- I830MemPool *pool, long size,
- unsigned long alignment, int flags);
-extern void I830FreeVidMem(ScrnInfoPtr pScrn, I830MemRange *range);
-
-extern void I830PrintAllRegisters(I830RegPtr i830Reg);
-extern void I830ReadAllRegisters(I830Ptr pI830, I830RegPtr i830Reg);
-
-extern void I830ChangeFrontbuffer(ScrnInfoPtr pScrn,int buffer);
+Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn);
+Bool i830_allocate_texture_memory(ScrnInfoPtr pScrn);
+Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn);
+
extern Bool I830IsPrimary(ScrnInfoPtr pScrn);
-extern DisplayModePtr I830GetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe,
- VbeInfoBlock *vbe);
-extern void I830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe);
-extern void I830UnsetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe);
-extern void I830PrintModes(ScrnInfoPtr pScrn);
-extern int I830GetBestRefresh(ScrnInfoPtr pScrn, int refresh);
-extern Bool I830CheckModeSupport(ScrnInfoPtr pScrn, int x, int y, int mode);
-extern Bool I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode);
-extern Bool I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem);
+extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg,
+ char *name);
-/* i830_memory.c */
-Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
-Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
+/* return a mask of output indices matching outputs against type_mask */
+int i830_output_clones (ScrnInfoPtr pScrn, int type_mask);
-/* i830_randr.c */
-Bool I830RandRInit(ScreenPtr pScreen, int rotation);
-Bool I830RandRSetConfig(ScreenPtr pScreen, Rotation rotation, int rate,
- RRScreenSizePtr pSize);
-Rotation I830GetRotation(ScreenPtr pScreen);
+/* i830_display.c */
+Bool
+i830PipeHasType (xf86CrtcPtr crtc, int type);
-/*
- * 12288 is set as the maximum, chosen because it is enough for
- * 1920x1440@32bpp with a 2048 pixel line pitch with some to spare.
- */
-#define I830_MAXIMUM_VBIOS_MEM 12288
-#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024)
-#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024)
+/* i830_crt.c */
+void i830_crt_init(ScrnInfoPtr pScrn);
-/* Flags for memory allocation function */
-#define FROM_ANYWHERE 0x00000000
-#define FROM_POOL_ONLY 0x00000001
-#define FROM_NEW_ONLY 0x00000002
-#define FROM_MASK 0x0000000f
+/* i830_dvo.c */
+void i830_dvo_init(ScrnInfoPtr pScrn);
-#define ALLOCATE_AT_TOP 0x00000010
-#define ALLOCATE_AT_BOTTOM 0x00000020
-#define FORCE_GAPS 0x00000040
+/* i830_lvds.c */
+void i830_lvds_init(ScrnInfoPtr pScrn);
-#define NEED_PHYSICAL_ADDR 0x00000100
-#define ALIGN_BOTH_ENDS 0x00000200
-#define FORCE_LOW 0x00000400
+extern void i830MarkSync(ScrnInfoPtr pScrn);
+extern void i830WaitSync(ScrnInfoPtr pScrn);
-#define ALLOC_NO_TILING 0x00001000
-#define ALLOC_INITIAL 0x00002000
+/* i830_memory.c */
+Bool i830_bind_all_memory(ScrnInfoPtr pScrn);
+Bool i830_unbind_all_memory(ScrnInfoPtr pScrn);
-#define ALLOCATE_DRY_RUN 0x80000000
+Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
+Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
+
+/* i830_modes.c */
+DisplayModePtr i830_ddc_get_modes(xf86OutputPtr output);
+
+/* i830_tv.c */
+void i830_tv_init(ScrnInfoPtr pScrn);
+
+/* i830_render.c */
+Bool i830_check_composite(int op, PicturePtr pSrc, PicturePtr pMask,
+ PicturePtr pDst);
+Bool i830_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMask,
+ PicturePtr pDst, PixmapPtr pSrcPixmap,
+ PixmapPtr pMaskPixmap, PixmapPtr pDstPixmap);
+void i830_composite(PixmapPtr pDst, int srcX, int srcY,
+ int maskX, int maskY, int dstX, int dstY, int w, int h);
+void i830_done_composite(PixmapPtr pDst);
+/* i915_render.c */
+Bool i915_check_composite(int op, PicturePtr pSrc, PicturePtr pMask,
+ PicturePtr pDst);
+Bool i915_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMask,
+ PicturePtr pDst, PixmapPtr pSrcPixmap,
+ PixmapPtr pMaskPixmap, PixmapPtr pDstPixmap);
+/* i965_render.c */
+Bool i965_check_composite(int op, PicturePtr pSrc, PicturePtr pMask,
+ PicturePtr pDst);
+Bool i965_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMask,
+ PicturePtr pDst, PixmapPtr pSrcPixmap,
+ PixmapPtr pMaskPixmap, PixmapPtr pDstPixmap);
+void i965_composite(PixmapPtr pDst, int srcX, int srcY,
+ int maskX, int maskY, int dstX, int dstY, int w, int h);
+
+void
+i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
+ float *x_out, float *y_out);
+
+void i830_enter_render(ScrnInfoPtr);
+
+static inline int i830_fb_compression_supported(I830Ptr pI830)
+{
+ if (!IS_MOBILE(pI830))
+ return FALSE;
+ if (IS_I810(pI830) || IS_I815(pI830) || IS_I830(pI830))
+ return FALSE;
+ /* fbc depends on tiled surface. And we don't support tiled
+ * front buffer with XAA now.
+ */
+ if (!pI830->tiling || (IS_I965G(pI830) && !pI830->useEXA))
+ return FALSE;
+ return TRUE;
+}
+
+Bool i830_pixmap_tiled(PixmapPtr p);
+
+extern const int I830PatternROP[16];
+extern const int I830CopyROP[16];
+
+/* Flags for memory allocation function */
+#define NEED_PHYSICAL_ADDR 0x00000001
+#define ALIGN_BOTH_ENDS 0x00000002
+#define NEED_NON_STOLEN 0x00000004
+#define NEED_LIFETIME_FIXED 0x00000008
+#define ALLOW_SHARING 0x00000010
/* Chipset registers for VIDEO BIOS memory RW access */
#define _855_DRAM_RW_CONTROL 0x58
#define _845_DRAM_RW_CONTROL 0x90
#define DRAM_WRITE 0x33330000
+/* quirk flag definition */
+#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/driver/xf86-video-intel/src/i830_debug.c b/driver/xf86-video-intel/src/i830_debug.c
index 8f8ef9bbb..7d0c0a0c9 100644
--- a/driver/xf86-video-intel/src/i830_debug.c
+++ b/driver/xf86-video-intel/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),
+ 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/driver/xf86-video-intel/src/i830_display.c b/driver/xf86-video-intel/src/i830_display.c
index 0e4262498..8f7c0689f 100644
--- a/driver/xf86-video-intel/src/i830_display.c
+++ b/driver/xf86-video-intel/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
@@ -610,6 +580,7 @@ i830_enable_fb_compression(xf86CrtcPtr crtc)
OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr + 6);
OUTREG(FBC_CONTROL2, FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_FULL |
FBC_CTL_CPU_FENCE | plane);
+ OUTREG(FBC_FENCE_OFF, crtc->y);
/* Zero buffers */
memset(pI830->FbBase + pI830->compressed_front_buffer->offset, 0,
@@ -648,6 +619,51 @@ i830_disable_fb_compression(xf86CrtcPtr crtc)
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on plane %c\n", plane);
}
+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 +740,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);
@@ -1176,14 +1196,6 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
i830PrintPll("chosen", &clock);
}
- if (dpll & DPLL_VCO_ENABLE)
- {
- OUTREG(fp_reg, fp);
- OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
- POSTING_READ(dpll_reg);
- usleep(150);
- }
-
/* The LVDS pin pair needs to be on before the DPLLs are enabled.
* This is an exception to the general rule that mode_set doesn't turn
* things on.
@@ -1192,6 +1204,14 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
{
CARD32 lvds = INREG(LVDS);
+ if (dpll & DPLL_VCO_ENABLE)
+ {
+ OUTREG(fp_reg, fp);
+ OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
+ POSTING_READ(dpll_reg);
+ usleep(150);
+ }
+
lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT;
/* Set the B0-B3 data pairs corresponding to whether we're going to
* set the DPLLs for dual-channel mode or not.
@@ -1338,6 +1358,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 +1639,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/driver/xf86-video-intel/src/i830_dri.c b/driver/xf86-video-intel/src/i830_dri.c
index f52a7c3de..141b970f7 100644
--- a/driver/xf86-video-intel/src/i830_dri.c
+++ b/driver/xf86-video-intel/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/driver/xf86-video-intel/src/i830_driver.c b/driver/xf86-video-intel/src/i830_driver.c
index a9764ad55..41d533060 100644
--- a/driver/xf86-video-intel/src/i830_driver.c
+++ b/driver/xf86-video-intel/src/i830_driver.c
@@ -495,7 +495,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;
@@ -2120,12 +2120,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);
@@ -2177,12 +2179,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);
@@ -3186,6 +3190,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/driver/xf86-video-intel/src/i830_dvo.c b/driver/xf86-video-intel/src/i830_dvo.c
index e6ff6af6c..81d560121 100644
--- a/driver/xf86-video-intel/src/i830_dvo.c
+++ b/driver/xf86-video-intel/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/driver/xf86-video-intel/src/i830_memory.c b/driver/xf86-video-intel/src/i830_memory.c
index 77ec30168..aa7021596 100644
--- a/driver/xf86-video-intel/src/i830_memory.c
+++ b/driver/xf86-video-intel/src/i830_memory.c
@@ -474,6 +474,9 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
/* Can't do TTM on stolen memory */
mmsize -= pI830->stolen_size;
+ if (HWS_NEED_GFX(pI830) && IS_IGD_GM(pI830))
+ mmsize -= HWSTATUS_PAGE_SIZE;
+
/* Create the aperture allocation */
pI830->memory_manager =
i830_allocate_aperture(pScrn, "DRI memory manager",
@@ -1636,16 +1639,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;
@@ -1658,7 +1665,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;
}
diff --git a/driver/xf86-video-intel/src/i830_quirks.c b/driver/xf86-video-intel/src/i830_quirks.c
index 5e6383100..e957845ec 100644
--- a/driver/xf86-video-intel/src/i830_quirks.c
+++ b/driver/xf86-video-intel/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,125 @@ 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;
@@ -59,6 +181,28 @@ 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 */
@@ -77,8 +221,8 @@ static i830_quirk i830_quirk_list[] = {
/* Dell XPS 1330 */
{ PCI_CHIP_I965_GM, 0x1028, 0x0209, quirk_ignore_tv },
- /* Lenovo X60s has no TV output */
- { PCI_CHIP_I945_GM, 0x17aa, 0x201a, quirk_ignore_tv },
+ /* Lenovo Napa TV (use dmi)*/
+ { PCI_CHIP_I945_GM, 0x17aa, SUBSYS_ANY, quirk_lenovo_tv_dmi },
/* Lenovo T61 has no TV output */
{ PCI_CHIP_I965_GM, 0x17aa, 0x20b5, quirk_ignore_tv },
/* Lenovo 3000 v200 */
@@ -91,6 +235,8 @@ static i830_quirk i830_quirk_list[] = {
/* Toshiba Satellite U300 has no TV output */
{ PCI_CHIP_I965_GM, 0x1179, 0xff50, quirk_ignore_tv },
+ /* Toshiba i830M laptop (fix bug 11148) */
+ { PCI_CHIP_I830_M, 0x1179, 0xff00, quirk_ivch_dvob },
/* Samsung Q35 has no TV output */
{ PCI_CHIP_I945_GM, 0x144d, 0xc504, quirk_ignore_tv },
@@ -103,6 +249,9 @@ static i830_quirk i830_quirk_list[] = {
/* ThinkPad X40 needs pipe A force quirk */
{ PCI_CHIP_I855_GM, 0x1014, 0x0557, quirk_pipea_force },
+ /* Sony vaio PCG-r600HFP (fix bug 13722) */
+ { PCI_CHIP_I830_M, 0x104d, 0x8100, quirk_ivch_dvob },
+
{ 0, 0, 0, NULL },
};
@@ -110,6 +259,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 &&
@@ -119,4 +274,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/driver/xf86-video-intel/src/i830_video.c b/driver/xf86-video-intel/src/i830_video.c
index a8f6a6248..a0e40ad26 100644
--- a/driver/xf86-video-intel/src/i830_video.c
+++ b/driver/xf86-video-intel/src/i830_video.c
@@ -475,7 +475,6 @@ i830_overlay_continue(ScrnInfoPtr pScrn, Bool update_filter)
OVERLAY_DEBUG("overlay_continue\n");
}
-
static void
i830_overlay_off(ScrnInfoPtr pScrn)
{