diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2008-03-30 13:51:31 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2008-03-30 13:51:31 +0000 |
commit | 1d45ca8c03ed27912049f405194382e5ba41674d (patch) | |
tree | 26bc625f6ae732c3620142a8e4e5e1d1d4e31fe7 /driver/xf86-video-intel/src | |
parent | d3d2132216a1ffa6e540438c3730b39e100fdbf8 (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.h | 2 | ||||
-rw-r--r-- | driver/xf86-video-intel/src/i810_reg.h | 1392 | ||||
-rw-r--r-- | driver/xf86-video-intel/src/i830.h | 810 | ||||
-rw-r--r-- | driver/xf86-video-intel/src/i830_debug.c | 220 | ||||
-rw-r--r-- | driver/xf86-video-intel/src/i830_display.c | 104 | ||||
-rw-r--r-- | driver/xf86-video-intel/src/i830_dri.c | 101 | ||||
-rw-r--r-- | driver/xf86-video-intel/src/i830_driver.c | 30 | ||||
-rw-r--r-- | driver/xf86-video-intel/src/i830_dvo.c | 6 | ||||
-rw-r--r-- | driver/xf86-video-intel/src/i830_memory.c | 15 | ||||
-rw-r--r-- | driver/xf86-video-intel/src/i830_quirks.c | 163 | ||||
-rw-r--r-- | driver/xf86-video-intel/src/i830_video.c | 1 |
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) { |