diff options
author | Kristian Høgsberg <krh@redhat.com> | 2008-10-14 23:13:40 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@redhat.com> | 2008-10-14 23:13:40 -0400 |
commit | 282f51c3f0e5bc2cedd2f60f458ca2662290d471 (patch) | |
tree | 3bd89c1d2effcc7b8e1b2b9c805244806b3546bc | |
parent | 8a54e3be5c5057fe8e3c52c03401fdada7978c45 (diff) | |
parent | 4dd00681dd0f9fce8dfd4592b46418edbbd2eeb4 (diff) |
Merge commit 'origin/master' into HEAD
-rw-r--r-- | Makefile.am | 7 | ||||
-rw-r--r-- | configure.ac | 11 | ||||
-rw-r--r-- | man/intel.man | 8 | ||||
-rw-r--r-- | src/Makefile.am | 9 | ||||
-rw-r--r-- | src/bios_reader/Makefile.am | 3 | ||||
-rw-r--r-- | src/bios_reader/bios_reader.c | 234 | ||||
-rw-r--r-- | src/brw_defines.h | 3 | ||||
-rw-r--r-- | src/brw_structs.h | 22 | ||||
-rw-r--r-- | src/common.h | 24 | ||||
-rw-r--r-- | src/i810.h | 3 | ||||
-rw-r--r-- | src/i810_driver.c | 14 | ||||
-rw-r--r-- | src/i810_reg.h | 6 | ||||
-rw-r--r-- | src/i830.h | 13 | ||||
-rw-r--r-- | src/i830_accel.c | 6 | ||||
-rw-r--r-- | src/i830_batchbuffer.c | 5 | ||||
-rw-r--r-- | src/i830_bios.c | 66 | ||||
-rw-r--r-- | src/i830_bios.h | 176 | ||||
-rw-r--r-- | src/i830_crt.c | 74 | ||||
-rw-r--r-- | src/i830_display.c | 48 | ||||
-rw-r--r-- | src/i830_driver.c | 98 | ||||
-rw-r--r-- | src/i830_exa.c | 24 | ||||
-rw-r--r-- | src/i830_hdmi.c | 10 | ||||
-rw-r--r-- | src/i830_memory.c | 31 | ||||
-rw-r--r-- | src/i830_modes.c | 1 | ||||
-rw-r--r-- | src/i830_quirks.c | 7 | ||||
-rw-r--r-- | src/i830_render.c | 22 | ||||
-rw-r--r-- | src/i830_video.c | 16 | ||||
-rw-r--r-- | src/i915_render.c | 23 | ||||
-rw-r--r-- | src/i965_render.c | 67 | ||||
-rw-r--r-- | src/i965_video.c | 2 | ||||
-rw-r--r-- | src/reg_dumper/Makefile.am | 13 | ||||
-rw-r--r-- | src/reg_dumper/gtt.c | 98 | ||||
-rw-r--r-- | uxa/uxa-glyphs.c | 4 |
33 files changed, 913 insertions, 235 deletions
diff --git a/Makefile.am b/Makefile.am index 5db07de9..896427f3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,7 +19,12 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. AUTOMAKE_OPTIONS = foreign -SUBDIRS = uxa src man + +if BUILD_UXA +UXA_DIR = uxa +endif + +SUBDIRS = $(UXA_DIR) src man EXTRA_DIST = README DISTCLEANFILES = doltcompile diff --git a/configure.ac b/configure.ac index 161005eb..0789e2a3 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ AC_PREREQ(2.57) AC_INIT([xf86-video-intel], - 2.5.96.0, + 2.4.97.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xf86-video-intel) @@ -84,6 +84,8 @@ XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) # Checks for pkg-config packages PKG_CHECK_MODULES(XORG, [xorg-server xproto fontsproto $REQUIRED_MODULES]) +PKG_CHECK_MODULES(UXA, [xorg-server >= 1.5], [BUILD_UXA=yes], [BUILD_UXA=no]) + sdkdir=$(pkg-config --variable=sdkdir xorg-server) drm_cflags=$(pkg-config --cflags libdrm) @@ -108,6 +110,8 @@ if test x$DRI != xno; then AC_CHECK_HEADER(xf86drmMode.h, [DRM_MODE=yes],[DRM_MODE=no] [#include "stdint.h"]) + dnl exaGetPixmapDriverPrivate required for DRM_MODE. + PKG_CHECK_MODULES(DRM_MODE, [xorg-server >= 1.5], [], [DRM_MODE=no]) if test "x$DRM_MODE" = xyes; then AC_DEFINE(XF86DRM_MODE,1,[DRM kernel modesetting]) fi @@ -124,6 +128,11 @@ if test x$DRI = xauto; then fi AC_MSG_RESULT([$DRI]) +AM_CONDITIONAL(BUILD_UXA, test $BUILD_UXA = yes) +if test "$BUILD_UXA" = yes; then + AC_DEFINE(I830_USE_UXA, 1, [UMA Acceleration Architecture support]) +fi + AC_CHECK_HEADER(xf86Modes.h,[XMODES=yes],[XMODES=no],[#include "xorg-server.h"]) AC_CHECK_DECL(XSERVER_LIBPCIACCESS, [XSERVER_LIBPCIACCESS=yes],[XSERVER_LIBPCIACCESS=no], diff --git a/man/intel.man b/man/intel.man index 6969a159..115b35ac 100644 --- a/man/intel.man +++ b/man/intel.man @@ -25,7 +25,7 @@ the 830M and later. .B intel supports the i810, i810-DC100, i810e, i815, i830M, 845G, 852GM, 855GM, 865G, 915G, 915GM, 945G, 945GM, 965G, 965Q, 946GZ, 965GM, 945GME, -G33, Q33, and Q35 chipsets. +G33, Q33, Q35, G35, GM45, G45, Q45, G43 and G41 chipsets. .SH CONFIGURATION DETAILS Please refer to __xconfigfile__(__filemansuffix__) for general configuration @@ -222,6 +222,12 @@ information. Enable XvMC driver. Current support MPEG2 MC on 915/945 and G33 series. User should provide absolute path to libIntelXvMC.so in XvMCConfig file. Default: Disabled. +.TP +.BI "Option \*qForceSDVODetect\*q \*q" boolean \*q +Instead of depending on SDVO detect status bit to initialize SDVO outputs, +this option trys to ignore that status bit and try to probe on all SDVO +ports anyway. Try this if some output is not detected on your ADD2 card. +Use of this option will slow down your startup time. Default: Disabled. .SH OUTPUT CONFIGURATION On 830M and better chipsets, the driver supports runtime configuration of diff --git a/src/Makefile.am b/src/Makefile.am index 8966bd68..9b322151 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -32,14 +32,17 @@ SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164 tfp410 $(REGDUMPER) AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRM_CFLAGS@ @DRI_CFLAGS@ \ @PCIACCESS_CFLAGS@ @UXA_CFLAGS@ \ - @XMODES_CFLAGS@ -DI830_XV -DI830_USE_XAA -DI830_USE_EXA -DI830_USE_UXA + @XMODES_CFLAGS@ -DI830_XV -DI830_USE_XAA -DI830_USE_EXA intel_drv_la_LTLIBRARIES = intel_drv.la intel_drv_la_LDFLAGS = -module -avoid-version intel_drv_ladir = @moduledir@/drivers -intel_drv_la_LIBADD = -lm ../uxa/libuxa.la +intel_drv_la_LIBADD = -lm -ldrm_intel +if BUILD_UXA +intel_drv_la_LIBADD += ../uxa/libuxa.la +endif if XSERVER_LIBPCIACCESS -intel_drv_la_LIBADD += @PCIACCESS_LIBS@ @DRM_LIBS@ -ldrm_intel +intel_drv_la_LIBADD += @PCIACCESS_LIBS@ @DRM_LIBS@ endif XMODE_SRCS=\ diff --git a/src/bios_reader/Makefile.am b/src/bios_reader/Makefile.am index c85081e7..9f1c45a5 100644 --- a/src/bios_reader/Makefile.am +++ b/src/bios_reader/Makefile.am @@ -1,4 +1,5 @@ -AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @XMODES_CFLAGS@ @PCIACCESS_CFLAGS@ +AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @XMODES_CFLAGS@ @PCIACCESS_CFLAGS@ \ + -DREG_DUMPER noinst_PROGRAMS = bios_reader $(BIOS_DUMPER) $(SWF_DUMPER) diff --git a/src/bios_reader/bios_reader.c b/src/bios_reader/bios_reader.c index 9e053170..2a6906d4 100644 --- a/src/bios_reader/bios_reader.c +++ b/src/bios_reader/bios_reader.c @@ -38,6 +38,9 @@ #include "../i830_bios.h" +typedef uint8_t CARD8; +typedef uint16_t CARD16; +typedef uint32_t CARD32; #define _PARSE_EDID_ #include "edid.h" @@ -59,42 +62,66 @@ struct _fake_i830 *pI830 = &I830; #define YESNO(val) ((val) ? "yes" : "no") +struct bdb_block { + uint8_t id; + uint16_t size; + void *data; +}; + +struct bdb_header *bdb; static int tv_present; static int lvds_present; static int panel_type; -static void *find_section(struct bdb_header *bdb, int section_id) +static struct bdb_block *find_section(int section_id) { - unsigned char *base = (unsigned char *)bdb; - int index = 0; - uint16_t total, current_size; - unsigned char current_id; - - /* skip to first section */ - index += bdb->header_size; - total = bdb->bdb_size; - - /* walk the sections looking for section_id */ - while (index < total) { - current_id = *(base + index); - index++; - current_size = *((uint16_t *)(base + index)); - index += 2; - if (current_id == section_id) - return base + index; - index += current_size; + struct bdb_block *block; + unsigned char *base = (unsigned char *)bdb; + int index = 0; + uint16_t total, current_size; + unsigned char current_id; + + /* skip to first section */ + index += bdb->header_size; + total = bdb->bdb_size; + + block = malloc(sizeof(*block)); + if (!block) { + fprintf(stderr, "out of memory\n"); + exit(-1); + } + + /* walk the sections looking for section_id */ + while (index < total) { + current_id = *(base + index); + index++; + current_size = *((uint16_t *)(base + index)); + index += 2; + if (current_id == section_id) { + block->id = current_id; + block->size = current_size; + block->data = base + index; + return block; } + index += current_size; + } - return NULL; + free(block); + return NULL; } -static void dump_general_features(void *data) +static void dump_general_features(void) { - struct bdb_general_features *features = data; + struct bdb_general_features *features; + struct bdb_block *block; + + block = find_section(BDB_GENERAL_FEATURES); - if (!data) + if (!block) return; + features = block->data; + printf("General features block:\n"); printf("\tPanel fitting: "); @@ -133,16 +160,25 @@ static void dump_general_features(void *data) tv_present = 1; /* should be based on whether TV DAC exists */ lvds_present = 1; /* should be based on IS_MOBILE() */ + + free(block); } -static void dump_general_definitions(void *data) +static void dump_general_definitions(void) { - struct bdb_general_definitions *defs = data; - unsigned char *lvds_data = defs->tv_or_lvds_info; + struct bdb_block *block; + struct bdb_general_definitions *defs; + struct child_device_config *child; + int i; + char child_id[11]; - if (!data) + block = find_section(BDB_GENERAL_DEFINITIONS); + + if (!block) return; + defs = block->data; + printf("General definitions block:\n"); printf("\tCRT DDC GMBUS addr: 0x%02x\n", defs->crt_ddc_gmbus_pin); @@ -153,18 +189,69 @@ static void dump_general_definitions(void *data) printf("\tBoot display type: 0x%02x%02x\n", defs->boot_display[1], defs->boot_display[0]); printf("\tTV data block present: %s\n", YESNO(tv_present)); - if (tv_present) - lvds_data += 33; - if (lvds_present) - printf("\tLFP DDC GMBUS addr: 0x%02x\n", lvds_data[19]); + for (i = 0; i < 4; i++) { + child = &defs->devices[i]; + if (!child->device_type) { + printf("\tChild device %d not present\n", i); + continue; + } + strncpy(child_id, (char *)child->device_id, 10); + child_id[10] = 0; + printf("\tChild %d device info:\n", i); + printf("\t\tSignature: %s\n", child_id); + printf("\t\tAIM offset: %d\n", child->addin_offset); + printf("\t\tDVO port: 0x%02x\n", child->dvo_port); + } + + free(block); } -static void dump_lvds_options(void *data) +static void dump_child_devices(void) { - struct bdb_lvds_options *options = data; + struct bdb_block *block; + struct bdb_child_devices *child_devs; + struct child_device_config *child; + int i; - if (!data) + block = find_section(BDB_CHILD_DEVICE_TABLE); + if (!block) { + printf("No child device table found\n"); return; + } + + child_devs = block->data; + + printf("Child devices block:\n"); + for (i = 0; i < DEVICE_CHILD_SIZE; i++) { + child = &child_devs->children[i]; + /* Skip nonexistent children */ + if (!child->device_type) + continue; + printf("\tChild device %d\n", i); + printf("\t\tType: 0x%04x\n", child->device_type); + printf("\t\tDVO port: 0x%02x\n", child->dvo_port); + printf("\t\tI2C pin: 0x%02x\n", child->i2c_pin); + printf("\t\tSlave addr: 0x%02x\n", child->slave_addr); + printf("\t\tDDC pin: 0x%02x\n", child->ddc_pin); + printf("\t\tDVO config: 0x%02x\n", child->dvo_cfg); + printf("\t\tDVO wiring: 0x%02x\n", child->dvo_wiring); + } + + free(block); +} + +static void dump_lvds_options(void) +{ + struct bdb_block *block; + struct bdb_lvds_options *options; + + block = find_section(BDB_LVDS_OPTIONS); + if (!block) { + printf("No LVDS options block\n"); + return; + } + + options = block->data; printf("LVDS options block:\n"); @@ -178,19 +265,55 @@ static void dump_lvds_options(void *data) printf("\tPFIT enhanced text mode: %s\n", YESNO(options->pfit_text_mode_enhanced)); printf("\tPFIT mode: %d\n", options->pfit_mode); + + free(block); } -static void dump_lvds_data(void *data, unsigned char *base) +static void dump_lvds_ptr_data(void) { - struct bdb_lvds_lfp_data *lvds_data = data; + struct bdb_block *block; + struct bdb_lvds_lfp_data_ptrs *ptrs; + struct lvds_fp_timing *fp_timing; + + block = find_section(BDB_LVDS_LFP_DATA_PTRS); + if (!block) { + printf("No LFP data pointers block\n"); + return; + } + + ptrs = block->data; + fp_timing = (struct lvds_fp_timing *)((uint8_t *)bdb + + ptrs->ptr[panel_type].fp_timing_offset); + + printf("LVDS timing pointer data:\n"); + printf(" Number of entries: %d\n", ptrs->lvds_entries); + + printf("\tpanel type %02i: %dx%d\n", panel_type, fp_timing->x_res, + fp_timing->y_res); + + free(block); +} + +static void dump_lvds_data(void) +{ + struct bdb_block *block; + struct bdb_lvds_lfp_data *lvds_data; + int num_entries; int i; - if (!data) + block = find_section(BDB_LVDS_LFP_DATA); + if (!block) { + printf("No LVDS data block\n"); return; + } + + lvds_data = block->data; + num_entries = block->size / sizeof(struct bdb_lvds_lfp_data_entry); printf("LVDS panel data block (preferred block marked with '*'):\n"); + printf(" Number of entries: %d\n", num_entries); - for (i = 0; i < 16; i++) { + for (i = 0; i < num_entries; i++) { struct bdb_lvds_lfp_data_entry *lfp_data = &lvds_data->data[i]; uint8_t *timing_data = (uint8_t *)&lfp_data->dvo_timing; char marker; @@ -198,13 +321,13 @@ static void dump_lvds_data(void *data, unsigned char *base) if (i == panel_type) marker = '*'; else - continue; + marker = ' '; printf("%c\tpanel type %02i: %dx%d clock %d\n", marker, i, lfp_data->fp_timing.x_res, lfp_data->fp_timing.y_res, _PIXEL_CLOCK(timing_data)); printf("\t\tinfo:\n"); - printf("\t\t LVDS: 0x%08lx\n", + printf("\t\t LVDS: 0x%08lx\n", (unsigned long)lfp_data->fp_timing.lvds_reg_val); printf("\t\t PP_ON_DELAYS: 0x%08lx\n", (unsigned long)lfp_data->fp_timing.pp_on_reg_val); @@ -224,23 +347,24 @@ static void dump_lvds_data(void *data, unsigned char *base) _V_SYNC_OFF(timing_data), _V_SYNC_WIDTH(timing_data)); } - + free(block); } int main(int argc, char **argv) { int fd; struct vbt_header *vbt = NULL; - struct bdb_header *bdb; int vbt_off, bdb_off, i; char *filename = "bios"; struct stat finfo; + struct bdb_block *block; + char signature[17]; if (argc != 2) { printf("usage: %s <rom file>\n", argv[0]); return 1; } - + filename = argv[1]; fd = open(filename, O_RDONLY); @@ -278,13 +402,27 @@ int main(int argc, char **argv) bdb_off = vbt_off + vbt->bdb_offset; bdb = (struct bdb_header *)(pI830->VBIOS + bdb_off); - printf("BDB sig: %16s\n", bdb->signature); + strncpy(signature, (char *)bdb->signature, 16); + signature[16] = 0; + printf("BDB sig: %s\n", signature); printf("BDB vers: %d.%d\n", bdb->version / 100, bdb->version % 100); - dump_general_features(find_section(bdb, BDB_GENERAL_FEATURES)); - dump_general_definitions(find_section(bdb, BDB_GENERAL_DEFINITIONS)); - dump_lvds_options(find_section(bdb, BDB_LVDS_OPTIONS)); - dump_lvds_data(find_section(bdb, BDB_LVDS_LFP_DATA), (unsigned char *)bdb); + printf("Available sections: "); + for (i = 0; i < 256; i++) { + block = find_section(i); + if (!block) + continue; + printf("%d ", i); + free(block); + } + printf("\n"); + + dump_general_features(); + dump_general_definitions(); +// dump_child_devices(); + dump_lvds_options(); + dump_lvds_data(); + dump_lvds_ptr_data(); return 0; } diff --git a/src/brw_defines.h b/src/brw_defines.h index 13cb4396..0df2491c 100644 --- a/src/brw_defines.h +++ b/src/brw_defines.h @@ -466,6 +466,9 @@ #define BRW_SURFACE_BUFFER 4 #define BRW_SURFACE_NULL 7 +#define BRW_BORDER_COLOR_MODE_DEFAULT 0 +#define BRW_BORDER_COLOR_MODE_LEGACY 1 + #define BRW_TEXCOORDMODE_WRAP 0 #define BRW_TEXCOORDMODE_MIRROR 1 #define BRW_TEXCOORDMODE_CLAMP 2 diff --git a/src/brw_structs.h b/src/brw_structs.h index ef7906b4..022915d1 100644 --- a/src/brw_structs.h +++ b/src/brw_structs.h @@ -840,10 +840,26 @@ struct brw_wm_unit_state float global_depth_offset_scale; }; -struct brw_sampler_default_color { +/* The hardware supports two different modes for border color. The + * default (OpenGL) mode uses floating-point color channels, while the + * legacy mode uses 4 bytes. + * + * More significantly, the legacy mode respects the components of the + * border color for channels not present in the source, (whereas the + * default mode will ignore the border color's alpha channel and use + * alpha==1 for an RGB source, for example). + * + * The legacy mode matches the semantics specified by the Render + * extension. + */ +struct brw_sampler_default_border_color { float color[4]; }; +struct brw_sampler_legacy_border_color { + uint8_t color[4]; +}; + struct brw_sampler_state { @@ -857,7 +873,7 @@ struct brw_sampler_state unsigned int base_level:5; unsigned int pad:1; unsigned int lod_preclamp:1; - unsigned int default_color_mode:1; + unsigned int border_color_mode:1; unsigned int pad0:1; unsigned int disable:1; } ss0; @@ -876,7 +892,7 @@ struct brw_sampler_state struct { unsigned int pad:5; - unsigned int default_color_pointer:27; + unsigned int border_color_pointer:27; } ss2; struct diff --git a/src/common.h b/src/common.h index ece1def0..acd5f4a2 100644 --- a/src/common.h +++ b/src/common.h @@ -81,8 +81,6 @@ extern void I830InitpScrn(ScrnInfoPtr pScrn); extern int I830EntityIndex; extern const char *I810vgahwSymbols[]; extern const char *I810ramdacSymbols[]; -extern const char *I810int10Symbols[]; -extern const char *I810vbeSymbols[]; extern const char *I810ddcSymbols[]; extern const char *I810fbSymbols[]; extern const char *I810xaaSymbols[]; @@ -106,21 +104,6 @@ extern void I830DPRINTF_stub(const char *filename, int line, #define RecPtr pI810 #endif -/* BIOS debug macro */ -#define xf86ExecX86int10_wrapper(pInt, pScrn) do { \ - ErrorF("Executing (ax == 0x%x) BIOS call at %s:%d\n", pInt->ax, __FILE__, __LINE__); \ - if (I810_DEBUG & DEBUG_VERBOSE_BIOS) { \ - ErrorF("Checking Error state before execution\n"); \ - PrintErrorState(pScrn); \ - } \ - xf86ExecX86int10(pInt); \ - if(I810_DEBUG & DEBUG_VERBOSE_BIOS) { \ - ErrorF("Checking Error state after execution\n"); \ - usleep(50000); \ - PrintErrorState(pScrn); \ - } \ -} while (0) - static inline void memset_volatile(volatile void *b, int c, size_t len) { int i; @@ -323,6 +306,11 @@ extern int I810_DEBUG; #define PCI_CHIP_Q45_G_BRIDGE 0x2E10 #endif +#ifndef PCI_CHIP_G41_G +#define PCI_CHIP_G41_G 0x2E32 +#define PCI_CHIP_G41_G_BRIDGE 0x2E30 +#endif + #if XSERVER_LIBPCIACCESS #define I810_MEMBASE(p,n) (p)->regions[(n)].base_addr #define VENDOR_ID(p) (p)->vendor_id @@ -355,7 +343,7 @@ extern int I810_DEBUG; #define IS_I945G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_G) #define IS_I945GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_GME) #define IS_GM45(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_GM45_GM) -#define IS_G4X(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IGD_E_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G45_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q45_G) +#define IS_G4X(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IGD_E_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G45_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q45_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G41_G) #define IS_I965GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME) #define IS_I965G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G35_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_Q || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I946_GZ || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME || IS_GM45(pI810) || IS_G4X(pI810)) #define IS_G33CLASS(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G33_G ||\ @@ -47,7 +47,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xaa.h" #include "xf86Cursor.h" #include "xf86xv.h" -#include "xf86int10.h" #include "vbe.h" #include "vgaHW.h" @@ -276,6 +275,8 @@ typedef struct _I810Rec { int drmMinor; } I810Rec; +extern const char *I810vbeSymbols[]; + #define I810PTR(p) ((I810Ptr)((p)->driverPrivate)) #define I810_SELECT_FRONT 0 diff --git a/src/i810_driver.c b/src/i810_driver.c index 856f5eca..cc28ad8b 100644 --- a/src/i810_driver.c +++ b/src/i810_driver.c @@ -156,6 +156,7 @@ static const struct pci_id_match intel_device_match[] = { INTEL_DEVICE_MATCH (PCI_CHIP_IGD_E_G, 0 ), INTEL_DEVICE_MATCH (PCI_CHIP_G45_G, 0 ), INTEL_DEVICE_MATCH (PCI_CHIP_Q45_G, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_G41_G, 0 ), { 0, 0, 0 }, }; @@ -212,6 +213,7 @@ static SymTabRec I810Chipsets[] = { {PCI_CHIP_IGD_E_G, "Intel Integrated Graphics Device"}, {PCI_CHIP_G45_G, "G45/G43"}, {PCI_CHIP_Q45_G, "Q45/Q43"}, + {PCI_CHIP_G41_G, "G41"}, {-1, NULL} }; @@ -245,6 +247,7 @@ static PciChipsets I810PciChipsets[] = { {PCI_CHIP_IGD_E_G, PCI_CHIP_IGD_E_G, RES_SHARED_VGA}, {PCI_CHIP_G45_G, PCI_CHIP_G45_G, RES_SHARED_VGA}, {PCI_CHIP_Q45_G, PCI_CHIP_Q45_G, RES_SHARED_VGA}, + {PCI_CHIP_G41_G, PCI_CHIP_G41_G, RES_SHARED_VGA}, {-1, -1, RES_UNDEFINED } }; @@ -339,14 +342,6 @@ const char *I810ddcSymbols[] = { NULL }; -const char *I810int10Symbols[] = { - "xf86ExecX86int10", - "xf86InitInt10", - "xf86Int10AllocPages", - "xf86int10Addr", - NULL -}; - const char *I810xaaSymbols[] = { "XAACreateInfoRec", "XAADestroyInfoRec", @@ -515,7 +510,7 @@ i810Setup(pointer module, pointer opts, int *errmaj, int *errmin) #endif I810shadowFBSymbols, I810vbeSymbols, vbeOptionalSymbols, - I810ddcSymbols, I810int10Symbols, NULL); + I810ddcSymbols, NULL); /* * The return value must be non-NULL on success even though there @@ -812,6 +807,7 @@ I810Probe(DriverPtr drv, int flags) case PCI_CHIP_IGD_E_G: case PCI_CHIP_G45_G: case PCI_CHIP_Q45_G: + case PCI_CHIP_G41_G: xf86SetEntitySharable(usedChips[i]); /* Allocate an entity private if necessary */ diff --git a/src/i810_reg.h b/src/i810_reg.h index 9a85d09e..6458008c 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -1167,6 +1167,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # define I965_DM_CLOCK_GATE_DISABLE (1 << 0) #define RENCLK_GATE_D2 0x6208 +#define VF_UNIT_CLOCK_GATE_DISABLE (1 << 9) +#define GS_UNIT_CLOCK_GATE_DISABLE (1 << 7) +#define CL_UNIT_CLOCK_GATE_DISABLE (1 << 6) #define RAMCLK_GATE_D 0x6210 /* CRL only */ #define DEUC 0x6214 /* CRL only */ @@ -2838,4 +2841,7 @@ typedef enum { #define PEG_BAND_GAP_DATA 0x14d68 +#define MCHBAR_RENDER_STANDBY 0x111B8 +#define RENDER_STANDBY_ENABLE (1 << 30) + #endif /* _I810_REG_H */ @@ -56,8 +56,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xaa.h" #include "xf86Cursor.h" #include "xf86xv.h" -#include "xf86int10.h" -#include "vbe.h" #include "vgaHW.h" #include "xf86Crtc.h" #include "xf86RandR12.h" @@ -720,6 +718,10 @@ typedef struct _I830Rec { /** Enables logging of debug output related to mode switching. */ Bool debug_modes; unsigned int quirk_flag; + + /* User option to ignore SDVO detect bit status, in case some outputs + not detected on SDVO, so let driver try its best. */ + Bool force_sdvo_detect; } I830Rec; #define I830PTR(p) ((I830Ptr)((p)->driverPrivate)) @@ -959,6 +961,13 @@ static inline int i830_fb_compression_supported(I830Ptr pI830) */ if (!pI830->tiling || (IS_I965G(pI830) && pI830->accel <= ACCEL_XAA)) return FALSE; + /* We have not gotten FBC to work consistently on 965GM. Our best + * working theory right now is that FBC simply isn't reliable on + * that device. See this bug report for more details: + * https://bugs.freedesktop.org/show_bug.cgi?id=16257 + */ + if (IS_I965GM(pI830)) + return FALSE; return TRUE; } diff --git a/src/i830_accel.c b/src/i830_accel.c index c6044a56..c935af63 100644 --- a/src/i830_accel.c +++ b/src/i830_accel.c @@ -332,9 +332,13 @@ I830AccelInit(ScreenPtr pScreen) pI830->accel_max_y = 2048; } switch (pI830->accel) { -#ifdef I830_USE_UXA case ACCEL_UXA: +#ifdef I830_USE_UXA return i830_uxa_init(pScreen); +#else + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "UXA not built in, falling back to EXA.\n"); + return I830EXAInit(pScreen); #endif #ifdef I830_USE_EXA case ACCEL_EXA: diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c index 47fc331b..9ae2141b 100644 --- a/src/i830_batchbuffer.c +++ b/src/i830_batchbuffer.c @@ -45,9 +45,11 @@ intel_nondrm_exec(dri_bo *bo, unsigned int used, void *priv) ScrnInfoPtr pScrn = priv; I830Ptr pI830 = I830PTR(pScrn); - BEGIN_LP_RING(2); + BEGIN_LP_RING(4); OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); OUT_RING(bo->offset); + OUT_RING(MI_NOOP); + OUT_RING(MI_NOOP); ADVANCE_LP_RING(); return 0; @@ -64,6 +66,7 @@ intel_nondrm_exec_i830(dri_bo *bo, unsigned int used, void *priv) OUT_RING(bo->offset); OUT_RING(bo->offset + pI830->batch_used - 4); OUT_RING(MI_NOOP); + ADVANCE_LP_RING(); return 0; } diff --git a/src/i830_bios.c b/src/i830_bios.c index ff49025d..007530dc 100644 --- a/src/i830_bios.c +++ b/src/i830_bios.c @@ -47,9 +47,6 @@ (bios[_addr + 2] << 16) \ (bios[_addr + 3] << 24)) -/* XXX */ -#define INTEL_VBIOS_SIZE (64 * 1024) - static void * find_section(struct bdb_header *bdb, int section_id) { @@ -88,8 +85,8 @@ static void parse_panel_data(I830Ptr pI830, struct bdb_header *bdb) { struct bdb_lvds_options *lvds_options; - struct bdb_lvds_lfp_data *lvds_lfp_data; - struct bdb_lvds_lfp_data_entry *entry; + struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs; + int timing_offset; DisplayModePtr fixed_mode; unsigned char *timing_ptr; @@ -104,12 +101,13 @@ parse_panel_data(I830Ptr pI830, struct bdb_header *bdb) if (lvds_options->panel_type == 0xff) return; - lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA); - if (!lvds_lfp_data) + lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS); + if (!lvds_lfp_data_ptrs) return; - entry = &lvds_lfp_data->data[lvds_options->panel_type]; - timing_ptr = (unsigned char *)&entry->dvo_timing; + timing_offset = + lvds_lfp_data_ptrs->ptr[lvds_options->panel_type].dvo_timing_offset; + timing_ptr = (unsigned char *)bdb + timing_offset; fixed_mode = xnfalloc(sizeof(DisplayModeRec)); memset(fixed_mode, 0, sizeof(*fixed_mode)); @@ -161,6 +159,8 @@ parse_general_features(I830Ptr pI830, struct bdb_header *bdb) } } +#define INTEL_VBIOS_SIZE (64 * 1024) /* XXX */ + /** * i830_bios_init - map VBIOS, find VBT * @@ -179,34 +179,44 @@ i830_bios_init(ScrnInfoPtr pScrn) struct bdb_header *bdb; int vbt_off, bdb_off; unsigned char *bios; - vbeInfoPtr pVbe; - pointer pVBEModule = NULL; + int ret; + int size; - bios = xalloc(INTEL_VBIOS_SIZE); +#if XSERVER_LIBPCIACCESS + size = pI830->PciInfo->rom_size; + if (size == 0) { + size = INTEL_VBIOS_SIZE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "libpciaccess reported 0 rom size, guessing %dkB\n", + size / 1024); + } +#else + size = INTEL_VBIOS_SIZE; +#endif + bios = xalloc(size); if (bios == NULL) return -1; - /* Load vbe module */ - if (!(pVBEModule = xf86LoadSubModule(pScrn, "vbe"))) - return FALSE; - xf86LoaderReqSymLists(I810vbeSymbols, NULL); - - pVbe = VBEInit(NULL, pI830->pEnt->index); - if (pVbe != NULL) { - memcpy(bios, xf86int10Addr(pVbe->pInt10, - pVbe->pInt10->BIOSseg << 4), - INTEL_VBIOS_SIZE); - vbeFree (pVbe); - } else { #if XSERVER_LIBPCIACCESS - pci_device_read_rom (pI830->PciInfo, bios); + ret = pci_device_read_rom (pI830->PciInfo, bios); + if (ret != 0) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "libpciaccess failed to read %dkB video BIOS: %s\n", + size / 1024, strerror(-ret)); + xfree (bios); + return -1; + } #else - xf86ReadPciBIOS(0, pI830->PciTag, 0, bios, INTEL_VBIOS_SIZE); -#endif + /* xf86ReadPciBIOS returns the length read */ + ret = xf86ReadPciBIOS(0, pI830->PciTag, 0, bios, size); + if (ret <= 0) { + xfree (bios); + return -1; } +#endif vbt_off = INTEL_BIOS_16(0x1a); - if (vbt_off >= INTEL_VBIOS_SIZE) { + if (vbt_off >= size) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Bad VBT offset: 0x%x\n", vbt_off); xfree(bios); diff --git a/src/i830_bios.h b/src/i830_bios.h index 6c8bd935..39706ac6 100644 --- a/src/i830_bios.h +++ b/src/i830_bios.h @@ -29,7 +29,9 @@ #define _I830_BIOS_H_ #include <stdint.h> +#ifndef REG_DUMPER #include <xf86str.h> +#endif struct vbt_header { char signature[20]; /**< Always starts with 'VBT$' */ @@ -117,9 +119,96 @@ struct bdb_general_features { unsigned char rsvd11:6; /* finish byte */ } __attribute__((packed)); +#define GPIO_PIN_NONE 0x00 /* "N/A" */ +#define GPIO_PIN_I2C 0x01 /* "I2C GPIO pins" */ +#define GPIO_PIN_CRT_DDC 0x02 /* "Analog CRT DDC GPIO pins" */ +/* 915+ */ +#define GPIO_PIN_LVDS 0x03 /* "Integrated LVDS DDC GPIO pins" */ +#define GPIO_PIN_SDVO_I2C 0x05 /* "sDVO I2C GPIO pins" */ +#define GPIO_PIN_SDVO_DDC1 0x1D /* "SDVO DDC1 GPIO pins" */ +#define GPIO_PIN_SDVO_DDC2 0x2D /* "SDVO DDC2 GPIO pins" */ +/* pre-915 */ +#define GPIO_PIN_DVI_LVDS 0x03 /* "DVI/LVDS DDC GPIO pins" */ +#define GPIO_PIN_ADD_I2C 0x05 /* "ADDCARD I2C GPIO pins" */ +#define GPIO_PIN_ADD_DDC 0x04 /* "ADDCARD DDC GPIO pins" */ +#define GPIO_PIN_ADD_DDC_I2C 0x06 /* "ADDCARD DDC/I2C GPIO pins" */ + +/* Pre 915 */ +#define DEVICE_TYPE_NONE 0x00 +#define DEVICE_TYPE_CRT 0x01 +#define DEVICE_TYPE_TV 0x09 +#define DEVICE_TYPE_EFP 0x12 +#define DEVICE_TYPE_LFP 0x22 +/* On 915+ */ +#define DEVICE_TYPE_CRT_DPMS 0x6001 +#define DEVICE_TYPE_CRT_DPMS_HOTPLUG 0x4001 +#define DEVICE_TYPE_TV_COMPOSITE 0x0209 +#define DEVICE_TYPE_TV_MACROVISION 0x0289 +#define DEVICE_TYPE_TV_RF_COMPOSITE 0x020c +#define DEVICE_TYPE_TV_SVIDEO_COMPOSITE 0x0609 +#define DEVICE_TYPE_TV_SCART 0x0209 +#define DEVICE_TYPE_TV_CODEC_HOTPLUG_PWR 0x6009 +#define DEVICE_TYPE_EFP_HOTPLUG_PWR 0x6012 +#define DEVICE_TYPE_EFP_DVI_HOTPLUG_PWR 0x6052 +#define DEVICE_TYPE_EFP_DVI_I 0x6053 +#define DEVICE_TYPE_EFP_DVI_D_DUAL 0x6152 +#define DEVICE_TYPE_EFP_DVI_D_HDCP 0x60d2 +#define DEVICE_TYPE_OPENLDI_HOTPLUG_PWR 0x6062 +#define DEVICE_TYPE_OPENLDI_DUALPIX 0x6162 +#define DEVICE_TYPE_LFP_PANELLINK 0x5012 +#define DEVICE_TYPE_LFP_CMOS_PWR 0x5042 +#define DEVICE_TYPE_LFP_LVDS_PWR 0x5062 +#define DEVICE_TYPE_LFP_LVDS_DUAL 0x5162 +#define DEVICE_TYPE_LFP_LVDS_DUAL_HDCP 0x51e2 + +#define DEVICE_CFG_NONE 0x00 +#define DEVICE_CFG_12BIT_DVOB 0x01 +#define DEVICE_CFG_12BIT_DVOC 0x02 +#define DEVICE_CFG_24BIT_DVOBC 0x09 +#define DEVICE_CFG_24BIT_DVOCB 0x0a +#define DEVICE_CFG_DUAL_DVOB 0x11 +#define DEVICE_CFG_DUAL_DVOC 0x12 +#define DEVICE_CFG_DUAL_DVOBC 0x13 +#define DEVICE_CFG_DUAL_LINK_DVOBC 0x19 +#define DEVICE_CFG_DUAL_LINK_DVOCB 0x1a + +#define DEVICE_WIRE_NONE 0x00 +#define DEVICE_WIRE_DVOB 0x01 +#define DEVICE_WIRE_DVOC 0x02 +#define DEVICE_WIRE_DVOBC 0x03 +#define DEVICE_WIRE_DVOBB 0x05 +#define DEVICE_WIRE_DVOCC 0x06 +#define DEVICE_WIRE_DVOB_MASTER 0x0d +#define DEVICE_WIRE_DVOC_MASTER 0x0e + +#define DEVICE_PORT_DVOA 0x00 /* none on 845+ */ +#define DEVICE_PORT_DVOB 0x01 +#define DEVICE_PORT_DVOC 0x02 + +struct child_device_config { + uint16_t handle; + uint16_t device_type; /* See DEVICE_TYPE_* above */ + uint8_t device_id[10]; + uint16_t addin_offset; + uint8_t dvo_port; /* See DEVICE_PORT_* above */ + uint8_t i2c_pin; + uint8_t slave_addr; + uint8_t ddc_pin; + uint16_t edid_ptr; + uint8_t dvo_cfg; /* See DEVICE_CFG_* above */ + uint8_t dvo2_port; + uint8_t i2c2_pin; + uint8_t slave2_addr; + uint8_t ddc2_pin; + uint8_t capabilities; + uint8_t dvo_wiring; /* See DEVICE_WIRE_* above */ + uint8_t dvo2_wiring; + uint16_t extended_type; + uint8_t dvo_function; +} __attribute__((packed)); + struct bdb_general_definitions { - /* DDC GPIO */ - unsigned char crt_ddc_gmbus_pin; + unsigned char crt_ddc_gmbus_pin; /* see GPIO_PIN_* above */ /* DPMS bits */ unsigned char dpms_acpi:1; @@ -131,15 +220,25 @@ struct bdb_general_definitions { unsigned char boot_display[2]; unsigned char child_dev_size; - /* device info */ - unsigned char tv_or_lvds_info[33]; - unsigned char dev1[33]; - unsigned char dev2[33]; - unsigned char dev3[33]; - unsigned char dev4[33]; + /* + * Device info: + * If TV is present, it'll be at devices[0] + * LVDS will be next, either devices[0] or [1], if present + * Max total will be 6, but could be as few as 4 if both + * TV and LVDS are missing, so be careful when interpreting + * [4] and [5]. + */ + struct child_device_config devices[6]; /* may be another device block here on some platforms */ } __attribute__((packed)); +#define DEVICE_CHILD_SIZE 7 + +struct bdb_child_devices { + uint8_t child_structure_size; + struct child_device_config children[DEVICE_CHILD_SIZE]; +} __attribute__((packed)); + struct bdb_lvds_options { uint8_t panel_type; uint8_t rsvd1; @@ -154,6 +253,16 @@ struct bdb_lvds_options { uint8_t rsvd4; } __attribute__((packed)); +/* 915+ only */ +struct bdb_tv_features { + /* need to verify bit ordering */ + uint16_t under_over_scan_via_yprpb:2; + uint16_t rsvd1:10; + uint16_t under_over_scan_via_dvi:2; + uint16_t add_overscan_mode:1; + uint16_t rsvd2:1; +} __attribute__((packed)); + struct lvds_fp_timing { uint16_t x_res; uint16_t y_res; @@ -223,6 +332,40 @@ struct bdb_lvds_lfp_data { struct bdb_lvds_lfp_data_entry data[16]; } __attribute__((packed)); +#define BACKLIGHT_TYPE_NONE 0 +#define BACKLIGHT_TYPE_I2C 1 +#define BACKLIGHT_TYPE_PWM 2 + +#define BACKLIGHT_GMBUS_100KHZ 0 +#define BACKLIGHT_GMBUS_50KHZ 1 +#define BACKLIGHT_GMBUS_400KHZ 2 +#define BACKLIGHT_GMBUS_1MHZ 3 + +struct backlight_info { + uint8_t inverter_type:2; /* see BACKLIGHT_TYPE_* above */ + uint8_t inverter_polarity:1; /* 1 means 0 is max, 255 is min */ + uint8_t gpio_pins:3; /* see GPIO_PIN_* above */ + uint8_t gmbus_speed:2; + uint16_t pwm_frequency; /* in Hz */ + uint8_t min_brightness; + /* Next two are only for 915+ systems */ + uint8_t i2c_addr; + uint8_t i2c_cmd; +} __attribute((packed)); + +struct bdb_backlight_control { + uint8_t row_size; + struct backlight_info lfps[16]; +} __attribute__((packed)); + +struct bdb_bia { + uint8_t bia_enable:1; + uint8_t bia_level:3; + uint8_t rsvd1:3; + uint8_t als_enable:1; + uint8_t als_response_data[20]; +} __attribute((packed)); + struct aimdb_header { char signature[16]; char oem_device[20]; @@ -252,11 +395,26 @@ struct vch_bdb_22 { struct vch_panel_data panels[16]; } __attribute__((packed)); +#ifndef REG_DUMPER int i830_bios_init(ScrnInfoPtr pScrn); +#endif /* * Driver<->VBIOS interaction occurs through scratch bits in * GR18 & SWF*. + * + * The VBIOS/firmware will signal to the gfx driver through the ASLE interrupt + * (visible in the interupt regs at bit 0) when it wants something done. + * + * Pre-965: + * The gfx driver can make calls to the VBIOS/firmware through an SMI request, + * generated by writing to offset 0xe0 of the device's config space (see the + * publically available 915 PRM for details). + * + * 965 and above: + * IGD OpRegion requests to the VBIOS/firmware are made using SWSCI, which can + * be triggered by writing to offset 0xe4 (see the publically available + * 965 graphics PRM for details). */ /* GR18 bits are set on display switch and hotkey events */ @@ -335,7 +493,7 @@ int i830_bios_init(ScrnInfoPtr pScrn); #define SWF14_GFX_PFIT_EN (1<<31) #define SWF14_TEXT_PFIT_EN (1<<30) -#define SWF14_LID_STATUS_CLOSED (1<<29) /* 0 here means open */ +#define SWF14_LID_SWITCH_EN (1<<29) #define SWF14_POPUP_EN (1<<28) #define SWF14_DISPLAY_HOLDOFF (1<<27) #define SWF14_DISP_DETECT_EN (1<<26) diff --git a/src/i830_crt.c b/src/i830_crt.c index 8274c0cc..479fbe5b 100644 --- a/src/i830_crt.c +++ b/src/i830_crt.c @@ -161,6 +161,14 @@ i830_crt_detect_hotplug(xf86OutputPtr output) uint32_t temp; const int timeout_ms = 1000; int starttime, curtime; + int tries = 1; + + /* On 4 series, CRT detect sequence need to be done twice for safe. */ + if (IS_G4X(pI830)) + tries = 2; + +retry: + tries--; temp = INREG(PORT_HOTPLUG_EN); @@ -173,6 +181,9 @@ i830_crt_detect_hotplug(xf86OutputPtr output) break; } + if (tries > 0) + goto retry; + if ((INREG(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) == CRT_HOTPLUG_MONITOR_COLOR) { @@ -327,13 +338,19 @@ i830_crt_detect_load (xf86CrtcPtr crtc, static Bool i830_crt_detect_ddc(xf86OutputPtr output) { + ScrnInfoPtr pScrn = output->scrn; I830OutputPrivatePtr i830_output = output->driver_private; + Bool detect; /* CRT should always be at 0, but check anyway */ if (i830_output->type != I830_OUTPUT_ANALOG) return FALSE; - return xf86I2CProbeAddress(i830_output->pDDCBus, 0x00A0); + I830I2CInit(pScrn, &i830_output->pDDCBus, GPIOA, "CRTDDC_A"); + detect = xf86I2CProbeAddress(i830_output->pDDCBus, 0x00A0); + xf86DestroyI2CBusRec(i830_output->pDDCBus, TRUE, TRUE); + + return detect; } /** @@ -410,6 +427,56 @@ i830_crt_get_crtc(xf86OutputPtr output) } #endif +static xf86MonPtr +i830_get_edid(xf86OutputPtr output, int gpio_reg, char *gpio_str) +{ + I830OutputPrivatePtr intel_output = output->driver_private; + xf86MonPtr edid_mon = NULL; + + /* Set up the DDC bus. */ + I830I2CInit(output->scrn, &intel_output->pDDCBus, gpio_reg, gpio_str); + + edid_mon = xf86OutputGetEDID (output, intel_output->pDDCBus); + + if (!edid_mon || DIGITAL(edid_mon->features.input_type)) { + xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE); + intel_output->pDDCBus = NULL; + if (edid_mon) { + xfree(edid_mon); + edid_mon = NULL; + } + } + + return edid_mon; +} + +static DisplayModePtr +i830_crt_get_modes (xf86OutputPtr output) +{ + DisplayModePtr modes; + xf86MonPtr edid_mon = NULL; + I830OutputPrivatePtr intel_output = output->driver_private; + + /* Try to probe normal CRT port, and also digital port for output + in DVI-I mode. */ + if ((edid_mon = i830_get_edid(output, GPIOA, "CRTDDC_A"))) + goto found; + if ((edid_mon = i830_get_edid(output, GPIOD, "CRTDDC_D"))) + goto found; + if ((edid_mon = i830_get_edid(output, GPIOE, "CRTDDC_E"))) + goto found; +found: + /* Destroy DDC bus after probe, so every other new probe will + scan all ports again */ + if (intel_output->pDDCBus) + xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE); + + xf86OutputSetEDID (output, edid_mon); + + modes = xf86OutputGetEDIDModes (output); + return modes; +} + static const xf86OutputFuncsRec i830_crt_output_funcs = { .dpms = i830_crt_dpms, .save = i830_crt_save, @@ -420,7 +487,7 @@ static const xf86OutputFuncsRec i830_crt_output_funcs = { .mode_set = i830_crt_mode_set, .commit = i830_output_commit, .detect = i830_crt_detect, - .get_modes = i830_ddc_get_modes, + .get_modes = i830_crt_get_modes, .destroy = i830_crt_destroy, #ifdef RANDR_GET_CRTC_INTERFACE .get_crtc = i830_crt_get_crtc, @@ -455,7 +522,4 @@ i830_crt_init(ScrnInfoPtr pScrn) output->driver_private = i830_output; output->interlaceAllowed = FALSE; output->doubleScanAllowed = FALSE; - - /* Set up the DDC bus. */ - I830I2CInit(pScrn, &i830_output->pDDCBus, GPIOA, "CRTDDC_A"); } diff --git a/src/i830_display.c b/src/i830_display.c index 3257b797..95ce51e7 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -857,27 +857,31 @@ 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); - /* Disable the VGA plane that we never use */ - OUTREG(VGACNTRL, VGA_DISP_DISABLE); + /* + * The documentation says : + * - Disable planes (VGA or hires) + * - Disable pipe + * - Disable VGA display + */ - /* May need to leave pipe A on */ - if ((pipe != 0) || !(pI830->quirk_flag & QUIRK_PIPEA_FORCE)) + /* Disable display plane */ + temp = INREG(dspcntr_reg); + if ((temp & DISPLAY_PLANE_ENABLE) != 0) { - /* Disable display plane */ - temp = INREG(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) != 0) - { - OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - OUTREG(dspbase_reg, INREG(dspbase_reg)); - POSTING_READ(dspbase_reg); - } + OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); + /* Flush the plane changes */ + OUTREG(dspbase_reg, INREG(dspbase_reg)); + POSTING_READ(dspbase_reg); + } - if (!IS_I9XX(pI830)) { - /* Wait for vblank for the disable to take effect */ - i830WaitForVblank(pScrn); - } + if (!IS_I9XX(pI830)) { + /* Wait for vblank for the disable to take effect */ + i830WaitForVblank(pScrn); + } + /* May need to leave pipe A on */ + if ((pipe != 0) || !(pI830->quirk_flag & QUIRK_PIPEA_FORCE)) + { /* Next, disable display pipes */ temp = INREG(pipeconf_reg); if ((temp & PIPEACONF_ENABLE) != 0) { @@ -893,9 +897,15 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) OUTREG(dpll_reg, temp & ~DPLL_VCO_ENABLE); POSTING_READ(dpll_reg); } + + /* Wait for the clocks to turn off. */ + usleep(150); } - /* Wait for the clocks to turn off. */ - usleep(150); + + /* Disable the VGA plane that we never use. */ + OUTREG(VGACNTRL, VGA_DISP_DISABLE); + i830WaitForVblank(pScrn); + break; } diff --git a/src/i830_driver.c b/src/i830_driver.c index 9f76b7c4..46e33bfa 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -191,7 +191,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "dixstruct.h" #include "xf86xv.h" #include <X11/extensions/Xv.h> -#include "vbe.h" #include "shadow.h" #include "i830.h" #include "i830_display.h" @@ -254,6 +253,7 @@ static SymTabRec I830Chipsets[] = { {PCI_CHIP_IGD_E_G, "Intel Integrated Graphics Device"}, {PCI_CHIP_G45_G, "G45/G43"}, {PCI_CHIP_Q45_G, "Q45/Q43"}, + {PCI_CHIP_G41_G, "G41"}, {-1, NULL} }; @@ -281,6 +281,7 @@ static PciChipsets I830PciChipsets[] = { {PCI_CHIP_IGD_E_G, PCI_CHIP_IGD_E_G, RES_SHARED_VGA}, {PCI_CHIP_G45_G, PCI_CHIP_G45_G, RES_SHARED_VGA}, {PCI_CHIP_Q45_G, PCI_CHIP_Q45_G, RES_SHARED_VGA}, + {PCI_CHIP_G41_G, PCI_CHIP_G41_G, RES_SHARED_VGA}, {-1, -1, RES_UNDEFINED} }; @@ -314,6 +315,7 @@ typedef enum { #ifdef INTEL_XVMC OPTION_XVMC, #endif + OPTION_FORCE_SDVO_DETECT, } I830Opts; static OptionInfoRec I830Options[] = { @@ -340,6 +342,7 @@ static OptionInfoRec I830Options[] = { #ifdef INTEL_XVMC {OPTION_XVMC, "XvMC", OPTV_BOOLEAN, {0}, TRUE}, #endif + {OPTION_FORCE_SDVO_DETECT, "ForceSDVODetect", OPTV_BOOLEAN, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; /* *INDENT-ON* */ @@ -437,9 +440,6 @@ I830DetectMemory(ScrnInfoPtr pScrn) uint16_t gmch_ctrl; int memsize = 0, gtt_size; int range; -#if 0 - VbeInfoBlock *vbeInfo; -#endif #if XSERVER_LIBPCIACCESS struct pci_device *bridge = intel_host_bridge (); @@ -502,8 +502,8 @@ I830DetectMemory(ScrnInfoPtr pScrn) range = gtt_size + 4; /* new 4 series hardware has seperate GTT stolen with GFX stolen */ - if (IS_G4X(pI830)) - range = 0; + if (IS_G4X(pI830) || IS_GM45(pI830)) + range = 4; if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { switch (gmch_ctrl & I855_GMCH_GMS_MASK) { @@ -913,14 +913,14 @@ I830SetupOutputs(ScrnInfoPtr pScrn) i830_lvds_init(pScrn); if (IS_I9XX(pI830)) { - if (INREG(SDVOB) & SDVO_DETECTED) { + if ((INREG(SDVOB) & SDVO_DETECTED) || pI830->force_sdvo_detect) { Bool found = i830_sdvo_init(pScrn, SDVOB); if (!found && SUPPORTS_INTEGRATED_HDMI(pI830)) i830_hdmi_init(pScrn, SDVOB); } - if (INREG(SDVOC) & SDVO_DETECTED) { + if ((INREG(SDVOC) & SDVO_DETECTED) || pI830->force_sdvo_detect) { Bool found = i830_sdvo_init(pScrn, SDVOC); if (!found && SUPPORTS_INTEGRATED_HDMI(pI830)) @@ -963,12 +963,18 @@ i830_init_clock_gating(ScrnInfoPtr pScrn) /* Disable clock gating reported to work incorrectly according to the specs. */ if (IS_GM45(pI830) || IS_G4X(pI830)) { + uint32_t dspclk_gate; OUTREG(RENCLK_GATE_D1, 0); - OUTREG(RENCLK_GATE_D2, 0); + OUTREG(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | + GS_UNIT_CLOCK_GATE_DISABLE | + CL_UNIT_CLOCK_GATE_DISABLE); OUTREG(RAMCLK_GATE_D, 0); - OUTREG(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE | - OVRUNIT_CLOCK_GATE_DISABLE | - OVCUNIT_CLOCK_GATE_DISABLE); + dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | + OVRUNIT_CLOCK_GATE_DISABLE | + OVCUNIT_CLOCK_GATE_DISABLE; + if (IS_GM45(pI830)) + dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; + OUTREG(DSPCLK_GATE_D, dspclk_gate); } else if (IS_I965GM(pI830)) { OUTREG(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); OUTREG(RENCLK_GATE_D2, 0); @@ -1267,6 +1273,9 @@ i830_detect_chipset(ScrnInfoPtr pScrn) case PCI_CHIP_Q45_G: chipname = "Q45/Q43"; break; + case PCI_CHIP_G41_G: + chipname = "G41"; + break; default: chipname = "unknown chipset"; break; @@ -1407,11 +1416,6 @@ I830LoadSyms(ScrnInfoPtr pScrn) if (pI830->use_drm_mode) return TRUE; - /* Load int10 module */ - if (!xf86LoadSubModule(pScrn, "int10")) - return FALSE; - xf86LoaderReqSymLists(I810int10Symbols, NULL); - /* The vgahw module should be loaded here when needed */ if (!xf86LoadSubModule(pScrn, "vgahw")) return FALSE; @@ -1453,6 +1457,12 @@ I830GetEarlyOptions(ScrnInfoPtr pScrn) if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE)) pI830->quirk_flag |= QUIRK_PIPEA_FORCE; + if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCE_SDVO_DETECT, FALSE)) { + pI830->force_sdvo_detect = TRUE; + } else { + pI830->force_sdvo_detect = FALSE; + } + return TRUE; } @@ -1886,6 +1896,10 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) if (!i830_detect_chipset(pScrn)) return FALSE; + if (i830_bios_init(pScrn)) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VBIOS initialization failed.\n"); + I830PreInitCrtcConfig(pScrn); if (pI830->use_drm_mode) { @@ -1905,10 +1919,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } - if (i830_bios_init(pScrn)) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VBIOS initialization failed.\n"); - /* * XXX If we knew the pre-initialised GTT format for certain, we could * probably figure out the physical address even in the StolenOnly case. @@ -2363,12 +2373,15 @@ RestoreHWState(ScrnInfoPtr pScrn) /* If the pipe A PLL is active, we can restore the pipe & plane config */ if (pI830->saveDPLL_A & DPLL_VCO_ENABLE) { + OUTREG(FPA0, pI830->saveFPA0); OUTREG(DPLL_A, pI830->saveDPLL_A & ~DPLL_VCO_ENABLE); + POSTING_READ(DPLL_A); usleep(150); } OUTREG(FPA0, pI830->saveFPA0); OUTREG(FPA1, pI830->saveFPA1); OUTREG(DPLL_A, pI830->saveDPLL_A); + POSTING_READ(DPLL_A); i830_dpll_settle(); if (IS_I965G(pI830)) OUTREG(DPLL_A_MD, pI830->saveDPLL_A_MD); @@ -2424,12 +2437,15 @@ RestoreHWState(ScrnInfoPtr pScrn) /* If the pipe B PLL is active, we can restore the pipe & plane config */ if (pI830->saveDPLL_B & DPLL_VCO_ENABLE) { + OUTREG(FPB0, pI830->saveFPB0); OUTREG(DPLL_B, pI830->saveDPLL_B & ~DPLL_VCO_ENABLE); + POSTING_READ(DPLL_B); usleep(150); } OUTREG(FPB0, pI830->saveFPB0); OUTREG(FPB1, pI830->saveFPB1); OUTREG(DPLL_B, pI830->saveDPLL_B); + POSTING_READ(DPLL_B); i830_dpll_settle(); if (IS_I965G(pI830)) OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD); @@ -2686,8 +2702,10 @@ I830BlockHandler(int i, pI830->need_mi_flush = FALSE; } +#ifdef I830_USE_UXA if (pI830->accel == ACCEL_UXA) i830_uxa_block_handler (pScreen); +#endif /* * Check for FIFO underruns at block time (which amounts to just * periodically). If this happens, it means our DSPARB or some other @@ -3021,11 +3039,28 @@ I830SwapPipes(ScrnInfoPtr pScrn) } } +static void +i830_disable_render_standby(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + uint32_t render_standby; + + /* Render Standby might cause hang issue, try always disable it.*/ + if (IS_I965GM(pI830) || IS_GM45(pI830)) { + render_standby = INREG(MCHBAR_RENDER_STANDBY); + if (render_standby & RENDER_STANDBY_ENABLE) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disable render standby.\n"); + OUTREG(MCHBAR_RENDER_STANDBY, + (render_standby & (~RENDER_STANDBY_ENABLE))); + } + } +} + static Bool I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { ScrnInfoPtr pScrn; - vgaHWPtr hwp; + vgaHWPtr hwp = NULL; I830Ptr pI830; VisualPtr visual; I830Ptr pI8301 = NULL; @@ -3242,6 +3277,14 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } #endif + if (!pI830->use_drm_mode) { + DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n"); + if (!I830MapMem(pScrn)) + return FALSE; + pScrn->memPhysBase = (unsigned long)pI830->FbBase; + } + i830_init_bufmgr(pScrn); + #ifdef XF86DRI /* * Setup DRI after visuals have been established, but before fbScreenInit @@ -3275,13 +3318,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->allowPageFlip ? "en" : "dis"); #endif - if (!pI830->use_drm_mode) { - DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n"); - if (!I830MapMem(pScrn)) - return FALSE; - pScrn->memPhysBase = (unsigned long)pI830->FbBase; - } - if (I830IsPrimary(pScrn)) { pScrn->fbOffset = pI830->front_buffer->offset; } else { @@ -3299,7 +3335,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; } - i830_init_bufmgr(pScrn); + i830_disable_render_standby(pScrn); DPRINTF(PFX, "assert( if(!I830EnterVT(scrnIndex, 0)) )\n"); @@ -3685,7 +3721,7 @@ I830EnterVT(int scrnIndex, int flags) * operation which accessing that page, like irq install, etc. */ if (pI830->starting && !pI830->memory_manager) { - if (!I830DRISetHWS(pScrn)) { + if (pI830->hw_status != NULL && !I830DRISetHWS(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Fail to setup hardware status page.\n"); I830DRICloseScreen(pScrn->pScreen); diff --git a/src/i830_exa.c b/src/i830_exa.c index 566dca3a..17ea86c8 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -726,13 +726,9 @@ I830EXAInit(ScreenPtr pScreen) return TRUE; } +#ifdef I830_USE_UXA static int uxa_pixmap_index; - -static void -i830_uxa_set_pixmap_bo (PixmapPtr pixmap, dri_bo *bo) -{ - dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, bo); -} +#endif dri_bo * i830_get_pixmap_bo(PixmapPtr pixmap) @@ -741,17 +737,30 @@ i830_get_pixmap_bo(PixmapPtr pixmap) ScrnInfoPtr scrn = xf86Screens[screen->myNum]; I830Ptr i830 = I830PTR(scrn); +#ifdef I830_USE_UXA if (i830->accel == ACCEL_UXA) { return dixLookupPrivate(&pixmap->devPrivates, &uxa_pixmap_index); - } else if (i830->accel == ACCEL_EXA) { + } +#endif +#ifdef XF86DRM_MODE + if (i830->accel == ACCEL_EXA) { struct i830_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pixmap); return driver_priv ? driver_priv->bo : NULL; } +#endif return NULL; } +#if defined(I830_USE_UXA) + +static void +i830_uxa_set_pixmap_bo (PixmapPtr pixmap, dri_bo *bo) +{ + dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, bo); +} + static Bool i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access) { @@ -939,6 +948,7 @@ i830_uxa_init (ScreenPtr pScreen) return TRUE; } +#endif /* I830_USE_UXA */ #ifdef XF86DRI diff --git a/src/i830_hdmi.c b/src/i830_hdmi.c index d56eec90..44e5c056 100644 --- a/src/i830_hdmi.c +++ b/src/i830_hdmi.c @@ -139,6 +139,8 @@ i830_hdmi_detect(xf86OutputPtr output) struct i830_hdmi_priv *dev_priv = intel_output->dev_priv; I830Ptr pI830 = I830PTR(pScrn); uint32_t temp, bit; + xf86OutputStatus status; + xf86MonPtr edid_mon; /* For G4X, PEG_BAND_GAP_DATA 3:0 must first be written 0xd. * Failure to do so will result in spurious interrupts being @@ -171,9 +173,15 @@ i830_hdmi_detect(xf86OutputPtr output) } if ((INREG(PORT_HOTPLUG_STAT) & bit) != 0) - return XF86OutputStatusConnected; + status = XF86OutputStatusConnected; else return XF86OutputStatusDisconnected; + + edid_mon = xf86OutputGetEDID (output, intel_output->pDDCBus); + if (!edid_mon || !DIGITAL(edid_mon->features.input_type)) + status = XF86OutputStatusDisconnected; + xfree(edid_mon); + return status; } static void diff --git a/src/i830_memory.c b/src/i830_memory.c index aa89b39d..276f9007 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -158,6 +158,29 @@ i830_get_fence_size(ScrnInfoPtr pScrn, unsigned long size) } static Bool +i830_check_display_stride(ScrnInfoPtr pScrn, int stride, Bool tiling) +{ + I830Ptr pI830 = I830PTR(pScrn); + int limit = KB(32); + + /* 8xx spec has always 8K limit, but tests show larger limit in + non-tiling mode, which makes large monitor work. */ + if ((IS_845G(pI830) || IS_I85X(pI830)) && tiling) + limit = KB(8); + + if (IS_I915(pI830) && tiling) + limit = KB(8); + + if (IS_I965G(pI830) && tiling) + limit = KB(16); + + if (stride <= limit) + return TRUE; + else + return FALSE; +} + +static Bool i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) { I830Ptr pI830 = I830PTR(pScrn); @@ -736,7 +759,7 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name, return NULL; mem->name = xstrdup(name); - if (name == NULL) { + if (mem->name == NULL) { xfree(mem); return NULL; } @@ -1202,6 +1225,12 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, else tiling = pI830->tiling; + if (!i830_check_display_stride(pScrn, pitch, tiling)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Front buffer stride %d kB " + "exceed display limit\n", pitch/1024); + return NULL; + } + /* Attempt to allocate it tiled first if we have page flipping on. */ if (tiling && IsTileable(pScrn, pitch)) { /* XXX: probably not the case on 965 */ diff --git a/src/i830_modes.c b/src/i830_modes.c index 06921a50..4aa493ea 100644 --- a/src/i830_modes.c +++ b/src/i830_modes.c @@ -31,7 +31,6 @@ * Authors: David Dawes <dawes@xfree86.org> * Eric Anholt <eric.anholt@intel.com> * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/vbe/vbeModes.c,v 1.6 2002/11/02 01:38:25 dawes Exp $ */ /* * Modified by Alan Hourihane <alanh@tungstengraphics.com> diff --git a/src/i830_quirks.c b/src/i830_quirks.c index 089e458f..12cab861 100644 --- a/src/i830_quirks.c +++ b/src/i830_quirks.c @@ -229,6 +229,9 @@ static i830_quirk i830_quirk_list[] = { { PCI_CHIP_I965_GM, 0xa0a0, SUBSYS_ANY, quirk_ignore_lvds }, { PCI_CHIP_I965_GM, 0x8086, 0x1999, quirk_ignore_lvds }, + /* Cappuccino SlimPRO SP625F, bz #11368 */ + { PCI_CHIP_I855_GM, 0x8086, 0x3582, quirk_ignore_lvds }, + /* Apple Mac mini has no lvds, but macbook pro does */ { PCI_CHIP_I945_GM, 0x8086, 0x7270, quirk_mac_mini }, @@ -255,8 +258,6 @@ static i830_quirk i830_quirk_list[] = { /* Lenovo Napa TV (use dmi)*/ { PCI_CHIP_I945_GM, 0x17aa, SUBSYS_ANY, quirk_lenovo_tv_dmi }, - /* Lenovo T61 has no TV output */ - { PCI_CHIP_I965_GM, 0x17aa, 0x20b5, quirk_ignore_tv }, /* Lenovo 3000 v200 */ { PCI_CHIP_I965_GM, 0x17aa, 0x3c18, quirk_ignore_tv }, @@ -278,6 +279,8 @@ static i830_quirk i830_quirk_list[] = { /* Samsung Q45 has no TV output */ { PCI_CHIP_I965_GM, 0x144d, 0xc510, quirk_ignore_tv }, + /* HP Compaq nx6110 has no TV output */ + { PCI_CHIP_I915_GM, 0x103c, 0x099c, quirk_ignore_tv }, /* HP Compaq 6730s has no TV output */ { PCI_CHIP_GM45_GM, 0x103c, 0x30e8, quirk_ignore_tv }, diff --git a/src/i830_render.c b/src/i830_render.c index c1ce856a..7b05daab 100644 --- a/src/i830_render.c +++ b/src/i830_render.c @@ -244,8 +244,8 @@ static Bool i830_check_composite_texture(PicturePtr pPict, int unit) I830FALLBACK("Unsupported picture format 0x%x\n", (int)pPict->format); - if (pPict->repeat && pPict->repeatType != RepeatNormal) - I830FALLBACK("unsupport repeat type\n"); + if (pPict->repeatType > RepeatReflect) + I830FALLBACK("Unsupported picture repeat %d\n", pPict->repeatType); if (pPict->filter != PictFilterNearest && pPict->filter != PictFilterBilinear) @@ -276,7 +276,7 @@ i830_texture_setup(PicturePtr pPict, PixmapPtr pPix, int unit) ScrnInfoPtr pScrn = xf86Screens[pPict->pDrawable->pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); uint32_t format, pitch, filter; - uint32_t wrap_mode = TEXCOORDMODE_CLAMP_BORDER; + uint32_t wrap_mode; pitch = intel_get_pixmap_pitch(pPix); pI830->scale_units[unit][0] = pPix->drawable.width; @@ -285,8 +285,22 @@ i830_texture_setup(PicturePtr pPict, PixmapPtr pPix, int unit) format = i8xx_get_card_format(pPict); - if (pPict->repeat) + switch (pPict->repeatType) { + case RepeatNone: + wrap_mode = TEXCOORDMODE_CLAMP_BORDER; + break; + case RepeatNormal: wrap_mode = TEXCOORDMODE_WRAP; + break; + case RepeatPad: + wrap_mode = TEXCOORDMODE_CLAMP; + break; + case RepeatReflect: + wrap_mode = TEXCOORDMODE_MIRROR; + break; + default: + FatalError("Unkown repeat type %d\n", pPict->repeatType); + } switch (pPict->filter) { case PictFilterNearest: diff --git a/src/i830_video.c b/src/i830_video.c index 5e6ebd77..316bc61e 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -2245,12 +2245,16 @@ I830PutImage(ScrnInfoPtr pScrn, pI830->entityPrivate->XvInUse = i830_crtc_pipe (pPriv->current_crtc);; } - /* Clamp dst width & height to 7x of src (overlay limit) */ - if(drw_w > (src_w * 7)) - drw_w = src_w * 7; + if (!pPriv->textured) { + /* If dst width and height are less than 1/8th the src size, the + * src/dst scale factor becomes larger than 8 and doesn't fit in + * the scale register. */ + if(src_w >= (drw_w * 8)) + drw_w = src_w/7; - if(drw_h > (src_h * 7)) - drw_h = src_h * 7; + if(src_h >= (drw_h * 8)) + drw_h = src_h/7; + } /* Clip */ x1 = src_x; @@ -2394,7 +2398,7 @@ I830PutImage(ScrnInfoPtr pScrn, /* fixup pointers */ #ifdef INTEL_XVMC if (id == FOURCC_XVMC && IS_I915(pI830)) { - pPriv->YBuf0offset = (uint32_t)((uint64_t)buf); + pPriv->YBuf0offset = (uint32_t)((uintptr_t)buf); pPriv->VBuf0offset = pPriv->YBuf0offset + (dstPitch2 * height); pPriv->UBuf0offset = pPriv->VBuf0offset + (dstPitch * height / 2); destId = FOURCC_YV12; diff --git a/src/i915_render.c b/src/i915_render.c index 970c42ad..039db3bf 100644 --- a/src/i915_render.c +++ b/src/i915_render.c @@ -201,9 +201,8 @@ static Bool i915_check_composite_texture(PicturePtr pPict, int unit) I830FALLBACK("Unsupported picture format 0x%x\n", (int)pPict->format); - if (pPict->repeat && pPict->repeatType != RepeatNormal) - I830FALLBACK("extended repeat (%d) not supported\n", - pPict->repeatType); + if (pPict->repeatType > RepeatReflect) + I830FALLBACK("Unsupported picture repeat %d\n", pPict->repeatType); if (pPict->filter != PictFilterNearest && pPict->filter != PictFilterBilinear) @@ -252,7 +251,7 @@ i915_texture_setup(PicturePtr pPict, PixmapPtr pPix, int unit) I830Ptr pI830 = I830PTR(pScrn); uint32_t format, pitch, filter; int w, h, i; - uint32_t wrap_mode = TEXCOORDMODE_CLAMP_BORDER; + uint32_t wrap_mode; pitch = intel_get_pixmap_pitch(pPix); w = pPict->pDrawable->width; @@ -270,8 +269,22 @@ i915_texture_setup(PicturePtr pPict, PixmapPtr pPix, int unit) I830FALLBACK("unknown texture format\n"); format = i915_tex_formats[i].card_fmt; - if (pPict->repeat) + switch (pPict->repeatType) { + case RepeatNone: + wrap_mode = TEXCOORDMODE_CLAMP_BORDER; + break; + case RepeatNormal: wrap_mode = TEXCOORDMODE_WRAP; + break; + case RepeatPad: + wrap_mode = TEXCOORDMODE_CLAMP_EDGE; + break; + case RepeatReflect: + wrap_mode = TEXCOORDMODE_MIRROR; + break; + default: + FatalError("Unkown repeat type %d\n", pPict->repeatType); + } switch (pPict->filter) { case PictFilterNearest: diff --git a/src/i965_render.c b/src/i965_render.c index a4334c65..9ee273c0 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -209,7 +209,7 @@ static Bool i965_check_composite_texture(PicturePtr pPict, int unit) I830FALLBACK("Unsupported picture format 0x%x\n", (int)pPict->format); - if (pPict->repeat && pPict->repeatType != RepeatNormal) + if (pPict->repeatType > RepeatReflect) I830FALLBACK("extended repeat (%d) not supported\n", pPict->repeatType); @@ -427,6 +427,8 @@ typedef enum { typedef enum { SAMPLER_STATE_EXTEND_NONE, SAMPLER_STATE_EXTEND_REPEAT, + SAMPLER_STATE_EXTEND_PAD, + SAMPLER_STATE_EXTEND_REFLECT, SAMPLER_STATE_EXTEND_COUNT } sampler_state_extend_t; @@ -494,8 +496,8 @@ typedef struct _gen4_state { [SAMPLER_STATE_FILTER_COUNT] [SAMPLER_STATE_EXTEND_COUNT][2]; - struct brw_sampler_default_color sampler_default_color; - PAD64 (brw_sampler_default_color, 0); + struct brw_sampler_legacy_border_color sampler_border_color; + PAD64 (brw_sampler_legacy_border_color, 0); /* Index by [src_blend][dst_blend] */ brw_cc_unit_state_padded cc_state[BRW_BLENDFACTOR_COUNT] @@ -564,13 +566,16 @@ static void sampler_state_init (struct brw_sampler_state *sampler_state, sampler_state_filter_t filter, sampler_state_extend_t extend, - int default_color_offset) + int border_color_offset) { /* PS kernel use this sampler */ memset(sampler_state, 0, sizeof(*sampler_state)); sampler_state->ss0.lod_preclamp = 1; /* GL mode */ - sampler_state->ss0.default_color_mode = 0; /* GL mode */ + + /* We use the legacy mode to get the semantics specified by + * the Render extension. */ + sampler_state->ss0.border_color_mode = BRW_BORDER_COLOR_MODE_LEGACY; switch(filter) { default: @@ -596,10 +601,20 @@ sampler_state_init (struct brw_sampler_state *sampler_state, sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_WRAP; sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP; break; + case SAMPLER_STATE_EXTEND_PAD: + sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; + sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP; + sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP; + break; + case SAMPLER_STATE_EXTEND_REFLECT: + sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_MIRROR; + sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_MIRROR; + sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_MIRROR; + break; } - assert((default_color_offset & 31) == 0); - sampler_state->ss2.default_color_pointer = default_color_offset >> 5; + assert((border_color_offset & 31) == 0); + sampler_state->ss2.border_color_pointer = border_color_offset >> 5; sampler_state->ss3.chroma_key_enable = 0; /* disable chromakey */ } @@ -722,13 +737,13 @@ gen4_state_init (struct gen4_render_state *render_state) card_state->vs_state.vs6.vs_enable = 0; card_state->vs_state.vs6.vert_cache_disable = 1; - /* Set up the sampler default color (always transparent black) */ - memset(&card_state->sampler_default_color, 0, - sizeof(card_state->sampler_default_color)); - card_state->sampler_default_color.color[0] = 0.0; /* R */ - card_state->sampler_default_color.color[1] = 0.0; /* G */ - card_state->sampler_default_color.color[2] = 0.0; /* B */ - card_state->sampler_default_color.color[3] = 0.0; /* A */ + /* Set up the sampler border color (always transparent black) */ + memset(&card_state->sampler_border_color, 0, + sizeof(card_state->sampler_border_color)); + card_state->sampler_border_color.color[0] = 0; /* R */ + card_state->sampler_border_color.color[1] = 0; /* G */ + card_state->sampler_border_color.color[2] = 0; /* B */ + card_state->sampler_border_color.color[3] = 0; /* A */ card_state->cc_viewport.min_depth = -1.e35; card_state->cc_viewport.max_depth = 1.e35; @@ -748,12 +763,12 @@ gen4_state_init (struct gen4_render_state *render_state) i, j, state_base_offset + offsetof (gen4_state_t, - sampler_default_color)); + sampler_border_color)); sampler_state_init (&card_state->sampler_state[i][j][k][l][1], k, l, state_base_offset + offsetof (gen4_state_t, - sampler_default_color)); + sampler_border_color)); } } } @@ -828,13 +843,17 @@ sampler_state_filter_from_picture (int filter) } static sampler_state_extend_t -sampler_state_extend_from_picture (int repeat) +sampler_state_extend_from_picture (int repeat_type) { - switch (repeat) { + switch (repeat_type) { case RepeatNone: return SAMPLER_STATE_EXTEND_NONE; case RepeatNormal: return SAMPLER_STATE_EXTEND_REPEAT; + case RepeatPad: + return SAMPLER_STATE_EXTEND_PAD; + case RepeatReflect: + return SAMPLER_STATE_EXTEND_REFLECT; default: return -1; } @@ -1010,17 +1029,17 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, src_filter = sampler_state_filter_from_picture (pSrcPicture->filter); if (src_filter < 0) I830FALLBACK ("Bad src filter 0x%x\n", pSrcPicture->filter); - src_extend = sampler_state_extend_from_picture (pSrcPicture->repeat); + src_extend = sampler_state_extend_from_picture (pSrcPicture->repeatType); if (src_extend < 0) - I830FALLBACK ("Bad src repeat 0x%x\n", pSrcPicture->repeat); + I830FALLBACK ("Bad src repeat 0x%x\n", pSrcPicture->repeatType); if (pMaskPicture) { mask_filter = sampler_state_filter_from_picture (pMaskPicture->filter); if (mask_filter < 0) I830FALLBACK ("Bad mask filter 0x%x\n", pMaskPicture->filter); - mask_extend = sampler_state_extend_from_picture (pMaskPicture->repeat); + mask_extend = sampler_state_extend_from_picture (pMaskPicture->repeatType); if (mask_extend < 0) - I830FALLBACK ("Bad mask repeat 0x%x\n", pMaskPicture->repeat); + I830FALLBACK ("Bad mask repeat 0x%x\n", pMaskPicture->repeatType); } else { mask_filter = SAMPLER_STATE_FILTER_NEAREST; mask_extend = SAMPLER_STATE_EXTEND_NONE; @@ -1450,7 +1469,7 @@ gen4_render_state_init(ScrnInfoPtr pScrn) render_state->card_state_offset = pI830->gen4_render_state_mem->offset; - if (pI830->gen4_render_state_mem->bo) { + if (pI830->use_drm_mode) { ret = dri_bo_map(pI830->gen4_render_state_mem->bo, 1); if (ret) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, @@ -1474,7 +1493,7 @@ gen4_render_state_cleanup(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - if (pI830->gen4_render_state_mem->bo) { + if (pI830->use_drm_mode) { dri_bo_unmap(pI830->gen4_render_state_mem->bo); dri_bo_unreference(pI830->gen4_render_state_mem->bo); } diff --git a/src/i965_video.c b/src/i965_video.c index 4c79259b..78f69ee5 100644 --- a/src/i965_video.c +++ b/src/i965_video.c @@ -254,7 +254,7 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, ps_kernel_static = &ps_kernel_planar_static[0][0]; ps_kernel_static_size = sizeof (ps_kernel_planar_static); src_width[1] = src_width[0] = width; - src_width[1] = src_height[0] = height; + src_height[1] = src_height[0] = height; src_pitch[1] = src_pitch[0] = video_pitch * 2; src_width[4] = src_width[5] = src_width[2] = src_width[3] = width / 2; src_height[4] = src_height[5] = src_height[2] = src_height[3] = height / 2; diff --git a/src/reg_dumper/Makefile.am b/src/reg_dumper/Makefile.am index 11275814..b04395a7 100644 --- a/src/reg_dumper/Makefile.am +++ b/src/reg_dumper/Makefile.am @@ -1,4 +1,9 @@ -noinst_PROGRAMS = intel_reg_dumper intel_idle intel_stepping intel_statuspage intel_hotplug +noinst_PROGRAMS = intel_reg_dumper \ + intel_gtt \ + intel_idle \ + intel_stepping \ + intel_statuspage \ + intel_hotplug intel_reg_dumper_SOURCES = \ main.c \ @@ -6,6 +11,11 @@ intel_reg_dumper_SOURCES = \ xprintf.c \ ../i830_debug.c +intel_gtt_SOURCES = \ + gtt.c \ + reg_dumper.h \ + util.c + intel_idle_SOURCES = \ idle.c \ reg_dumper.h \ @@ -28,6 +38,7 @@ intel_statuspage_SOURCES = \ intel_hotplug_LDADD = $(PCIACCESS_LIBS) intel_reg_dumper_LDADD = $(PCIACCESS_LIBS) +intel_gtt_LDADD = $(PCIACCESS_LIBS) intel_idle_LDADD = $(PCIACCESS_LIBS) intel_stepping_LDADD = $(PCIACCESS_LIBS) intel_statuspage_LDADD = $(PCIACCESS_LIBS) diff --git a/src/reg_dumper/gtt.c b/src/reg_dumper/gtt.c new file mode 100644 index 00000000..cf9e37a6 --- /dev/null +++ b/src/reg_dumper/gtt.c @@ -0,0 +1,98 @@ +/* + * Copyright © 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Eric Anholt <eric@anholt.net> + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <pciaccess.h> +#include <err.h> +#include <unistd.h> + +#include "reg_dumper.h" +#include "../i810_reg.h" + +#define INGTT(offset) INREG(gtt_base + (offset) / (KB(4) / 4)) + +int main(int argc, char **argv) +{ + I830Rec i830; + I830Ptr pI830 = &i830; + int gtt_base, start, aper_size; + intel_i830rec_init(pI830); + + if (IS_G4X(pI830) || IS_GM45(pI830)) + gtt_base = MB(2); + else { + printf("Unsupported chipset for gtt dumper\n"); + } + + aper_size = MB(256); + for (start = 0; start < aper_size; start += KB(4)) { + uint32_t start_pte = INGTT(start); + uint32_t end; + int constant_length = 0; + int linear_length = 0; + + /* Check if it's a linear sequence */ + for (end = start + KB(4); end < aper_size; end += KB(4)) { + uint32_t end_pte = INGTT(end); + if (end_pte == start_pte + (end - start)) + linear_length++; + else + break; + } + if (linear_length > 0) { + printf("0x%08x - 0x%08x: linear from " + "0x%08x to 0x%08x\n", + start, end - KB(4), + start_pte, start_pte + (end - start) - KB(4)); + start = end - KB(4); + continue; + } + + /* Check if it's a constant sequence */ + for (end = start + KB(4); end < aper_size; end += KB(4)) { + uint32_t end_pte = INGTT(end); + if (end_pte == start_pte) + constant_length++; + else + break; + } + if (constant_length > 0) { + printf("0x%08x - 0x%08x: constant 0x%08x\n", + start, end - KB(4), + start_pte); + start = end - KB(4); + continue; + } + + printf("0x%08x: 0x%08x\n", start, start_pte); + } + + return 0; +} diff --git a/uxa/uxa-glyphs.c b/uxa/uxa-glyphs.c index 364fcfbc..dc518568 100644 --- a/uxa/uxa-glyphs.c +++ b/uxa/uxa-glyphs.c @@ -668,6 +668,10 @@ uxa_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs) x = 0; y = 0; + extents.x1 = 0; + extents.y1 = 0; + extents.x2 = 0; + extents.y2 = 0; while (nlist--) { x += list->xOff; y += list->yOff; |