summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2008-10-14 23:13:40 -0400
committerKristian Høgsberg <krh@redhat.com>2008-10-14 23:13:40 -0400
commit282f51c3f0e5bc2cedd2f60f458ca2662290d471 (patch)
tree3bd89c1d2effcc7b8e1b2b9c805244806b3546bc
parent8a54e3be5c5057fe8e3c52c03401fdada7978c45 (diff)
parent4dd00681dd0f9fce8dfd4592b46418edbbd2eeb4 (diff)
Merge commit 'origin/master' into HEAD
-rw-r--r--Makefile.am7
-rw-r--r--configure.ac11
-rw-r--r--man/intel.man8
-rw-r--r--src/Makefile.am9
-rw-r--r--src/bios_reader/Makefile.am3
-rw-r--r--src/bios_reader/bios_reader.c234
-rw-r--r--src/brw_defines.h3
-rw-r--r--src/brw_structs.h22
-rw-r--r--src/common.h24
-rw-r--r--src/i810.h3
-rw-r--r--src/i810_driver.c14
-rw-r--r--src/i810_reg.h6
-rw-r--r--src/i830.h13
-rw-r--r--src/i830_accel.c6
-rw-r--r--src/i830_batchbuffer.c5
-rw-r--r--src/i830_bios.c66
-rw-r--r--src/i830_bios.h176
-rw-r--r--src/i830_crt.c74
-rw-r--r--src/i830_display.c48
-rw-r--r--src/i830_driver.c98
-rw-r--r--src/i830_exa.c24
-rw-r--r--src/i830_hdmi.c10
-rw-r--r--src/i830_memory.c31
-rw-r--r--src/i830_modes.c1
-rw-r--r--src/i830_quirks.c7
-rw-r--r--src/i830_render.c22
-rw-r--r--src/i830_video.c16
-rw-r--r--src/i915_render.c23
-rw-r--r--src/i965_render.c67
-rw-r--r--src/i965_video.c2
-rw-r--r--src/reg_dumper/Makefile.am13
-rw-r--r--src/reg_dumper/gtt.c98
-rw-r--r--uxa/uxa-glyphs.c4
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 ||\
diff --git a/src/i810.h b/src/i810.h
index e7331f6d..7ea20439 100644
--- a/src/i810.h
+++ b/src/i810.h
@@ -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 */
diff --git a/src/i830.h b/src/i830.h
index bfc5ac61..55db7728 100644
--- a/src/i830.h
+++ b/src/i830.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;