From 09a235af0f216052d3101b153c18be1fa75abf15 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 25 Aug 2008 16:38:17 -0700 Subject: [PATCH 01/52] Update version to 2.4.97 for first 2.5 test release --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index e6a2f6fb..ab1936d0 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ AC_PREREQ(2.57) AC_INIT([xf86-video-intel], - 2.4.99.0, + 2.4.97.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xf86-video-intel) From 94a86fa51a931f0059ea17728f857ec92cec5b16 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 25 Aug 2008 16:59:03 -0700 Subject: [PATCH 02/52] Fix UXA build for distcheck Was missing proper path info in CFLAGS. --- configure.ac | 2 ++ src/Makefile.am | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ab1936d0..86bb80fd 100644 --- a/configure.ac +++ b/configure.ac @@ -183,6 +183,8 @@ else fi AC_SUBST([XMODES_CFLAGS]) +UXA_CFLAGS='-I$(top_srcdir)/uxa' +AC_SUBST([UXA_CFLAGS]) SAVE_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $XORG_CFLAGS" diff --git a/src/Makefile.am b/src/Makefile.am index 1b1b67c8..97feea41 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -31,7 +31,7 @@ SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164 tfp410 $(REGDUMPER) # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRM_CFLAGS@ @DRI_CFLAGS@ \ - @PCIACCESS_CFLAGS@ -I../uxa \ + @PCIACCESS_CFLAGS@ @UXA_CFLAGS@ \ @XMODES_CFLAGS@ -DI830_XV -DI830_USE_XAA -DI830_USE_EXA -DI830_USE_UXA intel_drv_la_LTLIBRARIES = intel_drv.la From f9c625e1e5ddfff06b38fdd4e596fd8eae5934d5 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Thu, 11 Sep 2008 15:35:27 +0800 Subject: [PATCH 03/52] Disable render standby Render standby is known to cause possible hang issue on some mobile chips, so always disable it. --- src/i810_reg.h | 3 +++ src/i830_driver.c | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/i810_reg.h b/src/i810_reg.h index 9a85d09e..5b90e12e 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -2838,4 +2838,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_driver.c b/src/i830_driver.c index 491ec5e3..bab86a54 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -3012,6 +3012,23 @@ 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) { @@ -3291,6 +3308,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) i830_init_bufmgr(pScrn); + i830_disable_render_standby(pScrn); + DPRINTF(PFX, "assert( if(!I830EnterVT(scrnIndex, 0)) )\n"); if (pI830->accel <= ACCEL_XAA) { From ec17c88a0ed7c9cf4ad68aa52a7a891946a1c0f4 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Thu, 11 Sep 2008 16:14:47 +0800 Subject: [PATCH 04/52] Add support for G41 chipset G41 is another 4 series chipset like G45/43. --- src/common.h | 7 ++++++- src/i810_driver.c | 4 ++++ src/i830_driver.c | 5 +++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index ece1def0..840d30ab 100644 --- a/src/common.h +++ b/src/common.h @@ -323,6 +323,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 +360,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_driver.c b/src/i810_driver.c index 856f5eca..a7f408c4 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 } }; @@ -812,6 +815,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/i830_driver.c b/src/i830_driver.c index bab86a54..e48e20ec 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -254,6 +254,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 +282,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} }; @@ -1267,6 +1269,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; From e2743a409a02978ca8e953dbbeeb96f61bbd5ce6 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 12 Sep 2008 14:22:48 -0700 Subject: [PATCH 05/52] Only BO map render state if kernel mode setting is active We'll probably end up doing this differently, but avoid this path for now. --- src/i965_render.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i965_render.c b/src/i965_render.c index a4334c65..7dee5f3f 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -1450,7 +1450,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 +1474,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); } From 188d58dac9a87b56dbc34ec219cd196928bbcf64 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 16 Sep 2008 11:49:39 -0700 Subject: [PATCH 06/52] Put back check for pI830->hw_status in setting hws in non-GEM mode. Fixes crashes on non-GEM systems with physical hardware status page. Bug #17540 --- src/i830_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index e48e20ec..5e505cf2 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -3693,7 +3693,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); From 62b75df84c893bf28e20014cf88ce45064611dc9 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 16 Sep 2008 13:21:43 -0700 Subject: [PATCH 07/52] Move bufmgr init earlier so it's available at I830DRIDoMappings time. Fixes a crash with non-GEM mode. Bug #17540. --- src/i830_driver.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 5e505cf2..9bf0a64f 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -3254,6 +3254,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 @@ -3287,13 +3295,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 { @@ -3311,8 +3312,6 @@ 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"); From 0a2d17f7c2ea9b695df1855aab4ccc519546d8e5 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 16 Sep 2008 11:49:39 -0700 Subject: [PATCH 08/52] Put back check for pI830->hw_status in setting hws in non-GEM mode. Fixes crashes on non-GEM systems with physical hardware status page. Bug #17540 (cherry picked from commit 188d58dac9a87b56dbc34ec219cd196928bbcf64) --- src/i830_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index e48e20ec..5e505cf2 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -3693,7 +3693,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); From 043b6e71b83eb05339a6f8c4814e6941f8b9695a Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 16 Sep 2008 13:21:43 -0700 Subject: [PATCH 09/52] Move bufmgr init earlier so it's available at I830DRIDoMappings time. Fixes a crash with non-GEM mode. Bug #17540. (cherry picked from commit 62b75df84c893bf28e20014cf88ce45064611dc9) --- src/i830_driver.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 5e505cf2..9bf0a64f 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -3254,6 +3254,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 @@ -3287,13 +3295,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 { @@ -3311,8 +3312,6 @@ 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"); From bc36608e321e01a2be792688b4b734bb7c0667f7 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Thu, 18 Sep 2008 10:42:33 +0800 Subject: [PATCH 10/52] Check display stride limit when allocate front buffer --- src/i830_memory.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/i830_memory.c b/src/i830_memory.c index 2cbdd17a..ecfdf2a2 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -157,6 +157,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) { @@ -1200,6 +1223,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 */ From 1fbe4d602816c9dfc5fba917b9fdc257d8d025b0 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Thu, 18 Sep 2008 15:37:00 +0800 Subject: [PATCH 11/52] Bug #17277: fix upscaling limit Oh duh (i830_video.c): /* Clamp dst width & height to 7x of src (overlay limit) */ if(drw_w > (src_w * 7)) drw_w = src_w * 7; if(drw_h > (src_h * 7)) drw_h = src_h * 7; The condition I see in the documentation appears to be src_h/drw_h < 8, that is, src_h < 8*drw_h. It appears this was "fixed" incorrectly in e784e152. It seems difficult to believe that this limitation would exist at all for the texture unit. --- src/i830_video.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/i830_video.c b/src/i830_video.c index 5e6ebd77..6645daae 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; From 2f93cfbc7e96acc32efb5e1ca49b817a81cba6e3 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Fri, 19 Sep 2008 15:20:55 +0800 Subject: [PATCH 12/52] Fix output detection for DVI-I For CRT this trys to probe all possible port for EDID and detects got confirmed by EDID's d/a type bit. For HDMI/DVI, also using EDID d/a type bit to ensure it should handle the connect or not. --- src/i830_crt.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- src/i830_hdmi.c | 10 +++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/i830_crt.c b/src/i830_crt.c index 8274c0cc..5812e2b7 100644 --- a/src/i830_crt.c +++ b/src/i830_crt.c @@ -410,6 +410,49 @@ 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. */ + if (gpio_reg != GPIOA) + 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); + 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; + + /* 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: + 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 +463,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, 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 From 10909d9b665864bda2b1654de009d556cd068726 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 22 Sep 2008 13:11:55 -0700 Subject: [PATCH 13/52] Add Cappuccino SlimPRO SP625F to no LVDS quirks list Looks like this platform might contain VBTs that indicate an LFP is present even though it isn't. Intended to fix bz #11368. --- src/i830_quirks.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/i830_quirks.c b/src/i830_quirks.c index 089e458f..a3b23863 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 }, From 6a46022df57d09109fc119fedce99c156715a4d4 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 22 Sep 2008 13:26:58 -0700 Subject: [PATCH 14/52] Add no TV out quirk for HP Compaq nx6110 Hopefully we can fix the VBT parsing code so we don't need this, but for the time being it seems necessary. Fixes bz #17683. --- src/i830_quirks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/i830_quirks.c b/src/i830_quirks.c index a3b23863..528b5646 100644 --- a/src/i830_quirks.c +++ b/src/i830_quirks.c @@ -281,6 +281,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 }, From 204a6281aa59e29027793ba5c84a5d9af7dc9e90 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 22 Sep 2008 18:38:03 -0700 Subject: [PATCH 15/52] Revert "Add no TV out quirk for HP Compaq nx6110" This reverts commit 6a46022df57d09109fc119fedce99c156715a4d4. It should have been attributed to Bryce. --- src/i830_quirks.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/i830_quirks.c b/src/i830_quirks.c index 528b5646..a3b23863 100644 --- a/src/i830_quirks.c +++ b/src/i830_quirks.c @@ -281,8 +281,6 @@ 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 }, From afa630b448e5993850433c9f0b129758ec4d37b5 Mon Sep 17 00:00:00 2001 From: Bryce Harrington Date: Mon, 22 Sep 2008 18:38:35 -0700 Subject: [PATCH 16/52] Add TV out quirk for HP Compaq nx6110 Adds a TV out quirk for HP Compaq nx6110. Fixes bz #17683. --- src/i830_quirks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/i830_quirks.c b/src/i830_quirks.c index a3b23863..528b5646 100644 --- a/src/i830_quirks.c +++ b/src/i830_quirks.c @@ -281,6 +281,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 }, From a428892b76dba4c55e2ae28933d30e98d9fd646d Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 23 Sep 2008 12:36:11 -0700 Subject: [PATCH 17/52] Update supported hardware list --- man/intel.man | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/intel.man b/man/intel.man index 6969a159..8419f2df 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 From d8a007b056e3d6c3e132ecac06368b21d2ac4123 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Fri, 26 Sep 2008 09:44:59 +0800 Subject: [PATCH 18/52] Bug #16515: Fix VT switch with DVI on G45 On DVI, centered VGA mode is used instead of native mode VGA, and PLL on pipe is used instead of VGA PLL setting. So make sure PLL settled down in restore time. --- src/i830_driver.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/i830_driver.c b/src/i830_driver.c index 9bf0a64f..1317c1d1 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2359,12 +2359,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); @@ -2420,12 +2423,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); From d6b2696f9ac14a81598e0147698209ad428fd45d Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Fri, 26 Sep 2008 09:53:03 +0800 Subject: [PATCH 19/52] Do force CRT detect sequence twice on 4 series chipset --- src/i830_crt.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/i830_crt.c b/src/i830_crt.c index 5812e2b7..2e70eb8d 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) { From 1cc15ba454fdf54a7dea9da066e0a023a4742fab Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Fri, 26 Sep 2008 10:01:52 +0800 Subject: [PATCH 20/52] Render register clock gating disable fix on 4 series chipset --- src/i810_reg.h | 3 +++ src/i830_driver.c | 14 ++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/i810_reg.h b/src/i810_reg.h index 5b90e12e..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 */ diff --git a/src/i830_driver.c b/src/i830_driver.c index 1317c1d1..389775f4 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -965,12 +965,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); From 11d304e99c0e11c28901ec28115d9c8b81a2b9cc Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Sun, 28 Sep 2008 10:08:26 +0800 Subject: [PATCH 21/52] Bug #16631: add option for SDVO force detect Some ADD2 card doesn't get SDVO detect status setup right, which disabled outputs on those cards. This adds a new option "ForceSDVODetect" to probe all SDVO ports anyway. --- man/intel.man | 6 ++++++ src/i830.h | 4 ++++ src/i830_driver.c | 12 ++++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/man/intel.man b/man/intel.man index 8419f2df..115b35ac 100644 --- a/man/intel.man +++ b/man/intel.man @@ -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/i830.h b/src/i830.h index 5fb7e24b..491dfd00 100644 --- a/src/i830.h +++ b/src/i830.h @@ -714,6 +714,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)) diff --git a/src/i830_driver.c b/src/i830_driver.c index 389775f4..ce7b623f 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -316,6 +316,7 @@ typedef enum { #ifdef INTEL_XVMC OPTION_XVMC, #endif + OPTION_FORCE_SDVO_DETECT, } I830Opts; static OptionInfoRec I830Options[] = { @@ -342,6 +343,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* */ @@ -915,14 +917,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)) @@ -1464,6 +1466,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; } From 836d24f2cc3836fbd1695cf1f88c2af975b4862c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 29 Sep 2008 19:02:51 -0700 Subject: [PATCH 22/52] Use uintptr_t instead of uint64_t to hold pointer value --- src/i830_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830_video.c b/src/i830_video.c index 6645daae..316bc61e 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -2398,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; From f082e877d54dbafa437fd05e9c07e870cd513be9 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 30 Sep 2008 12:06:46 -0700 Subject: [PATCH 23/52] Work around gcc uninitialized variable warnings GCC isn't smart enough to analyze the control flow and figure out that these are false positives, but initializing them shouldn't hurt, so work around it. --- src/i830_driver.c | 2 +- uxa/uxa-glyphs.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index ce7b623f..53219c39 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -3058,7 +3058,7 @@ 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; 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; From f315e9d1ad92562195ce42b956d4be6b31e8a13e Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 30 Sep 2008 12:07:52 -0700 Subject: [PATCH 24/52] Use -Werror by default --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index e276f0e1..e8c634c7 100644 --- a/configure.ac +++ b/configure.ac @@ -203,7 +203,7 @@ dnl Use lots of warning flags with GCC WARN_CFLAGS="" if test "x$GCC" = "xyes"; then - WARN_CFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes \ + WARN_CFLAGS="-Wall -Werror -Wpointer-arith -Wstrict-prototypes \ -Wmissing-prototypes -Wmissing-declarations \ -Wnested-externs -fno-strict-aliasing" fi From fa2586a40f20e73ec7420466638e8f595e0da987 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 30 Sep 2008 12:46:20 -0700 Subject: [PATCH 25/52] Use VBT LFP info pointers by default On some machines it appears that the LFP info pointers give us more accurate panel info than if we index into the LFP data table using the panel type index. Early reports indicate that using the pointers doesn't cause regressions, so switch to them by default to help 8xx machines. Fixes bug 17310 (and hopefully 17658 too). --- src/i830_bios.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/i830_bios.c b/src/i830_bios.c index ff49025d..2cb0b07b 100644 --- a/src/i830_bios.c +++ b/src/i830_bios.c @@ -88,8 +88,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 +104,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)); From a4568740ee296bc392843fd324d2a047e7862187 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 30 Sep 2008 12:48:32 -0700 Subject: [PATCH 26/52] Be more verbose about panel data in VBIOS dumper Dump more panel data, including number of expected entries. Had to refactor things a bit, but now each function should get size information so further checking can be added more easily. --- src/bios_reader/bios_reader.c | 157 ++++++++++++++++++++++++---------- 1 file changed, 114 insertions(+), 43 deletions(-) diff --git a/src/bios_reader/bios_reader.c b/src/bios_reader/bios_reader.c index 9e053170..29c3edb0 100644 --- a/src/bios_reader/bios_reader.c +++ b/src/bios_reader/bios_reader.c @@ -59,42 +59,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; + 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; + /* 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; + 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; - if (!data) + block = find_section(BDB_GENERAL_FEATURES); + + if (!block) return; + features = block->data; + printf("General features block:\n"); printf("\tPanel fitting: "); @@ -133,16 +157,24 @@ 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; + unsigned char *lvds_data; - if (!data) + block = find_section(BDB_GENERAL_DEFINITIONS); + + if (!block) return; + defs = block->data; + lvds_data = defs->tv_or_lvds_info; + printf("General definitions block:\n"); printf("\tCRT DDC GMBUS addr: 0x%02x\n", defs->crt_ddc_gmbus_pin); @@ -157,15 +189,22 @@ static void dump_general_definitions(void *data) lvds_data += 33; if (lvds_present) printf("\tLFP DDC GMBUS addr: 0x%02x\n", lvds_data[19]); + + free(block); } -static void dump_lvds_options(void *data) +static void dump_lvds_options(void) { - struct bdb_lvds_options *options = data; + struct bdb_block *block; + struct bdb_lvds_options *options; - if (!data) + block = find_section(BDB_LVDS_OPTIONS); + + if (!block) return; + options = block->data; + printf("LVDS options block:\n"); panel_type = options->panel_type; @@ -178,19 +217,51 @@ 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; - int i; + struct bdb_block *block; + struct bdb_lvds_lfp_data_ptrs *ptrs; + struct lvds_fp_timing *fp_timing; - if (!data) + block = find_section(BDB_LVDS_LFP_DATA_PTRS); + if (!block) return; - printf("LVDS panel data block (preferred block marked with '*'):\n"); + ptrs = block->data; + fp_timing = (struct lvds_fp_timing *)((uint8_t *)bdb + + ptrs->ptr[panel_type].fp_timing_offset); - for (i = 0; i < 16; i++) { + 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; + + block = find_section(BDB_LVDS_LFP_DATA); + if (!block) + 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 < 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 +269,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,14 +295,13 @@ 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; @@ -240,7 +310,7 @@ int main(int argc, char **argv) printf("usage: %s \n", argv[0]); return 1; } - + filename = argv[1]; fd = open(filename, O_RDONLY); @@ -281,10 +351,11 @@ int main(int argc, char **argv) printf("BDB sig: %16s\n", bdb->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); + dump_general_features(); + dump_general_definitions(); + dump_lvds_options(); + dump_lvds_data(); + dump_lvds_ptr_data(); return 0; } From 497b7420c4a76df553ed53322a390a1c754ce30c Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Tue, 30 Sep 2008 12:53:11 -0700 Subject: [PATCH 27/52] Fix ordering of VGA vs. plane disable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From the Intel 965 Programmer’s Reference Manual, volume 3, chapter 2.2.2 "Mode Switch Programming Sequence". The disable sequence should be: - Disable planes (VGA or hires) - Disable pipe - Disable VGA display in 0x71400 bit 31 This patch implements that order plus waits for a vblank at the end. Fixes bug #17756. --- src/i830_display.c | 48 ++++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/i830_display.c b/src/i830_display.c index ed49fb0e..0632f3a3 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 + */ + + /* 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); + } + + 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)) { - /* 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); - } - - if (!IS_I9XX(pI830)) { - /* Wait for vblank for the disable to take effect */ - i830WaitForVblank(pScrn); - } - /* 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; } From bf8a3ffeaa4df9ecbad7abff9a44d714de2fa104 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 30 Sep 2008 16:59:02 -0700 Subject: [PATCH 28/52] Revert "Use -Werror by default" This reverts commit f315e9d1ad92562195ce42b956d4be6b31e8a13e. The world isn't ready for a warning free build. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index e8c634c7..e276f0e1 100644 --- a/configure.ac +++ b/configure.ac @@ -203,7 +203,7 @@ dnl Use lots of warning flags with GCC WARN_CFLAGS="" if test "x$GCC" = "xyes"; then - WARN_CFLAGS="-Wall -Werror -Wpointer-arith -Wstrict-prototypes \ + WARN_CFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes \ -Wmissing-prototypes -Wmissing-declarations \ -Wnested-externs -fno-strict-aliasing" fi From b7279f1be1b913c1c6ee8ebfb95c97800217a821 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 1 Oct 2008 15:26:39 -0700 Subject: [PATCH 29/52] Examine picture repeatType as well as repeat field. The existing switch statement was switching on the Boolean repeat field rather than the correct repeatType field. This had not caused any problem before as only two possible repeat values were supported (RepeatNone = 0 and RepeatNormal = 1) so they were always the same as the repeat field. Soon, however, we'll be supporting more repeat types, so we'll need to switch on the correct value. --- src/i965_render.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/i965_render.c b/src/i965_render.c index 7dee5f3f..b4a2a73c 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -828,9 +828,12 @@ 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, int repeat_type) { - switch (repeat) { + if (repeat == 0) + return SAMPLER_STATE_EXTEND_NONE; + + switch (repeat_type) { case RepeatNone: return SAMPLER_STATE_EXTEND_NONE; case RepeatNormal: @@ -1010,17 +1013,19 @@ 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->repeat, + 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->repeat, + 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; From 128223ee9b7880e640056475462eca9a88415492 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 1 Oct 2008 15:29:04 -0700 Subject: [PATCH 30/52] Add support for RepeatPad and RepeatReflect. It's quite simple to support these modes---we simply need to turn on the support for them in the hardware. These changes have been verified with the extend-pad and extend-reflect tests in cairo's test suite. However, this currently required using a custom-modified version of cairo. The issue is that released versions of cairo, (and even cairo master so far), don't pass RepeatPad and RepeatReflect to Render, (due to various bugs and workarounds in cairo and pixman). I do plan to fix those issues in cairo, so that in a future release of cairo, (1.8.2 perhaps?), the cairo test suite will usefully test these new repeat modes in our driver. --- src/i965_render.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/i965_render.c b/src/i965_render.c index b4a2a73c..498fa1f8 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->repeat && 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; @@ -596,6 +598,16 @@ 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); @@ -838,6 +850,10 @@ sampler_state_extend_from_picture (int repeat, int repeat_type) 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; } From ab2b70f831314f81a581bfb1e48d059a3a2b0b06 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 1 Oct 2008 16:05:16 -0700 Subject: [PATCH 31/52] Prefer repeatType field over using both repeat and repeatType. Eric informed me that the repeat field exists only for backwards compatibility with old drivers that weren't prepared for values other than 0 or 1 here. Since we are, we can just ignore that field and examine only repeatType. So the code's a (tiny) bit simpler this way. --- src/i965_render.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/i965_render.c b/src/i965_render.c index 498fa1f8..2b59e91d 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 > RepeatReflect) + if (pPict->repeatType > RepeatReflect) I830FALLBACK("extended repeat (%d) not supported\n", pPict->repeatType); @@ -840,11 +840,8 @@ sampler_state_filter_from_picture (int filter) } static sampler_state_extend_t -sampler_state_extend_from_picture (int repeat, int repeat_type) +sampler_state_extend_from_picture (int repeat_type) { - if (repeat == 0) - return SAMPLER_STATE_EXTEND_NONE; - switch (repeat_type) { case RepeatNone: return SAMPLER_STATE_EXTEND_NONE; @@ -1029,8 +1026,7 @@ 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, - pSrcPicture->repeatType); + src_extend = sampler_state_extend_from_picture (pSrcPicture->repeatType); if (src_extend < 0) I830FALLBACK ("Bad src repeat 0x%x\n", pSrcPicture->repeatType); @@ -1038,8 +1034,7 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, 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, - pMaskPicture->repeatType); + mask_extend = sampler_state_extend_from_picture (pMaskPicture->repeatType); if (mask_extend < 0) I830FALLBACK ("Bad mask repeat 0x%x\n", pMaskPicture->repeatType); } else { From 8304b405e0dc2f31fd2d2fd82e150ba502ab74e2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 29 Sep 2008 17:37:28 -0700 Subject: [PATCH 32/52] Eliminate INT10 call to get BIOS contents libpciaccess (and the old X server PCI code as well) provides a function to get the ROM contents. Code to use that was already present in the driver and used if the INT10 function failed. Skip the INT10 and just use libpciaccess as that eliminates several module loads and scary use of vm86. Signed-off-by: Keith Packard --- src/common.h | 17 ----------------- src/i810.h | 3 ++- src/i810_driver.c | 10 +--------- src/i830.h | 2 -- src/i830_bios.c | 41 +++++++++++++++++++---------------------- src/i830_driver.c | 9 --------- src/i830_modes.c | 1 - 7 files changed, 22 insertions(+), 61 deletions(-) diff --git a/src/common.h b/src/common.h index 840d30ab..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; 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 a7f408c4..cc28ad8b 100644 --- a/src/i810_driver.c +++ b/src/i810_driver.c @@ -342,14 +342,6 @@ const char *I810ddcSymbols[] = { NULL }; -const char *I810int10Symbols[] = { - "xf86ExecX86int10", - "xf86InitInt10", - "xf86Int10AllocPages", - "xf86int10Addr", - NULL -}; - const char *I810xaaSymbols[] = { "XAACreateInfoRec", "XAADestroyInfoRec", @@ -518,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 diff --git a/src/i830.h b/src/i830.h index 491dfd00..5b782369 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" diff --git a/src/i830_bios.c b/src/i830_bios.c index 2cb0b07b..726fe30f 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) { @@ -180,34 +177,34 @@ 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; +#else +#define INTEL_VBIOS_SIZE (64 * 1024) /* XXX */ + size = INTEL_VBIOS_SIZE; +#endif + if (size == 0) + return -1; + 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) + return -1; #else - xf86ReadPciBIOS(0, pI830->PciTag, 0, bios, INTEL_VBIOS_SIZE); + /* xf86ReadPciBIOS returns the length read */ + ret = xf86ReadPciBIOS(0, pI830->PciTag, 0, bios, size); + if (ret <= 0) + 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_driver.c b/src/i830_driver.c index 53219c39..3a2a9a40 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 -#include "vbe.h" #include "shadow.h" #include "i830.h" #include "i830_display.h" @@ -441,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 (); @@ -1420,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; 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 * Eric Anholt * - * $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 From f1dbc266ccfe26c6b9a272e40a5bbe9afaa4f2e0 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 2 Oct 2008 14:45:12 -0700 Subject: [PATCH 33/52] Work around libpciaccess reporting a 0 rom size by guessing. I required the following patch on top of this to work around libpciaccess brokenness. libpciaccess reports 0 rom size if there's no rom resource, even if the rom file exists in sysfs. --- src/i830_bios.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/i830_bios.c b/src/i830_bios.c index 726fe30f..007530dc 100644 --- a/src/i830_bios.c +++ b/src/i830_bios.c @@ -159,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 * @@ -182,25 +184,35 @@ i830_bios_init(ScrnInfoPtr pScrn) #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 -#define INTEL_VBIOS_SIZE (64 * 1024) /* XXX */ size = INTEL_VBIOS_SIZE; #endif - if (size == 0) - return -1; bios = xalloc(size); if (bios == NULL) return -1; #if XSERVER_LIBPCIACCESS ret = pci_device_read_rom (pI830->PciInfo, bios); - if (ret != 0) + 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 returns the length read */ ret = xf86ReadPciBIOS(0, pI830->PciTag, 0, bios, size); - if (ret <= 0) + if (ret <= 0) { + xfree (bios); return -1; + } #endif vbt_off = INTEL_BIOS_16(0x1a); From 76c9ece36e6400fd10f364ee330faea470e2da64 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 2 Oct 2008 20:40:14 -0700 Subject: [PATCH 34/52] Fallback to software for RepeatNone with transformed RGB-only pictures. We wish it wouldn't, but the hardware ignores the alpha in the BorderColor we set when the source picture format has no alpha in it, (and it uses alpha of 1.0 where we want 0.0). For now, fallback for these cases. This gives a correct result, but obviously is not as fast as we would like. This fixes bug #16820: [EXA] Composition result in black for areas outside of source-surface bounds https://bugs.freedesktop.org/show_bug.cgi?id=16820 --- src/i965_render.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/i965_render.c b/src/i965_render.c index 2b59e91d..709f3fdb 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -254,6 +254,42 @@ i965_check_composite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, if (!i965_get_dest_format(pDstPicture, &tmp1)) I830FALLBACK("Get Color buffer format\n"); + /* There's an infelicity of the 965 with respect to implementing + * RepeatNone for a source picture without alpha. The hardware's + * CLAMP_BORDER mode in this case doesn't match what Render, (and + * everyone, really), wants. Render expects that samples outside + * the bounds of the source picture will be transparent, but the + * hardware is documented as follows: + * + * For surface formats with one or more channels missing, the + * value from the border color is not used for the missing + * channels, resulting in these channels resulting in the + * overall default value (0 for colors and 1 for alpha) + * regardless of whether border color is chosen. + * + * [Intel 965 PRM; Volume 4; Section 4.7.4 SAMPLER_BORDER_COLOR_STATE] + * + * It's that hard-coding of "1 for alpha" that kills us. Until we + * figure out a way to get the hardware to do what we want, we'll + * fall back to software. We fall back only if the operator uses + * the source alpha, the source format has no alpha, and there's + * a transform. + * + * For more complicated scenarios where there's a transform, but + * it won't actually result in any sampling outside the source + * picture, we'll have to rely on a higher layer, + * (ReduceCompositeOp in render/picture.c), that actually has + * access to the coordinates, to simplify the operator from Over + * to Source, for example. + */ + if (i965_blend_op[op].src_alpha && + (PICT_FORMAT_A(pSrcPicture->format) == 0) && + pSrcPicture->transform) + { + I830FALLBACK("No support for alpha (RepeatNone) for an RGB-only picture\n"); + } + + return TRUE; } From 21cce1998a10db520c390eb5061814867564c583 Mon Sep 17 00:00:00 2001 From: Shuang He Date: Mon, 6 Oct 2008 09:48:21 +0800 Subject: [PATCH 35/52] Fix a typo in G965 texture video code --- src/i965_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; From 175b30e3828266a89021c2439119545099d72715 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 6 Oct 2008 12:48:07 -0700 Subject: [PATCH 36/52] Revert "Fallback to software for RepeatNone with transformed RGB-only pictures." This reverts commit 76c9ece36e6400fd10f364ee330faea470e2da64. We've learned a new technique that should let us avoid this fallback to software. See following commit. --- src/i965_render.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/src/i965_render.c b/src/i965_render.c index 709f3fdb..2b59e91d 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -254,42 +254,6 @@ i965_check_composite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, if (!i965_get_dest_format(pDstPicture, &tmp1)) I830FALLBACK("Get Color buffer format\n"); - /* There's an infelicity of the 965 with respect to implementing - * RepeatNone for a source picture without alpha. The hardware's - * CLAMP_BORDER mode in this case doesn't match what Render, (and - * everyone, really), wants. Render expects that samples outside - * the bounds of the source picture will be transparent, but the - * hardware is documented as follows: - * - * For surface formats with one or more channels missing, the - * value from the border color is not used for the missing - * channels, resulting in these channels resulting in the - * overall default value (0 for colors and 1 for alpha) - * regardless of whether border color is chosen. - * - * [Intel 965 PRM; Volume 4; Section 4.7.4 SAMPLER_BORDER_COLOR_STATE] - * - * It's that hard-coding of "1 for alpha" that kills us. Until we - * figure out a way to get the hardware to do what we want, we'll - * fall back to software. We fall back only if the operator uses - * the source alpha, the source format has no alpha, and there's - * a transform. - * - * For more complicated scenarios where there's a transform, but - * it won't actually result in any sampling outside the source - * picture, we'll have to rely on a higher layer, - * (ReduceCompositeOp in render/picture.c), that actually has - * access to the coordinates, to simplify the operator from Over - * to Source, for example. - */ - if (i965_blend_op[op].src_alpha && - (PICT_FORMAT_A(pSrcPicture->format) == 0) && - pSrcPicture->transform) - { - I830FALLBACK("No support for alpha (RepeatNone) for an RGB-only picture\n"); - } - - return TRUE; } From 98ca9e2af1b0a67ed91e10cf661af70dfba44d43 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 6 Oct 2008 13:16:37 -0700 Subject: [PATCH 37/52] Rename default_color to border_color This is consistent with the documentation, (and just plain makes more sense). --- src/brw_structs.h | 6 +++--- src/i965_render.c | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/brw_structs.h b/src/brw_structs.h index ef7906b4..553aeebb 100644 --- a/src/brw_structs.h +++ b/src/brw_structs.h @@ -840,7 +840,7 @@ struct brw_wm_unit_state float global_depth_offset_scale; }; -struct brw_sampler_default_color { +struct brw_sampler_border_color { float color[4]; }; @@ -857,7 +857,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 +876,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/i965_render.c b/src/i965_render.c index 2b59e91d..4bffe0d7 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -496,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_border_color sampler_border_color; + PAD64 (brw_sampler_border_color, 0); /* Index by [src_blend][dst_blend] */ brw_cc_unit_state_padded cc_state[BRW_BLENDFACTOR_COUNT] @@ -566,13 +566,13 @@ 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 */ + sampler_state->ss0.border_color_mode = 0; /* GL mode */ switch(filter) { default: @@ -610,8 +610,8 @@ sampler_state_init (struct brw_sampler_state *sampler_state, 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 */ } @@ -735,12 +735,12 @@ gen4_state_init (struct gen4_render_state *render_state) 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 */ + memset(&card_state->sampler_border_color, 0, + sizeof(card_state->sampler_border_color)); + card_state->sampler_border_color.color[0] = 0.0; /* R */ + card_state->sampler_border_color.color[1] = 0.0; /* G */ + card_state->sampler_border_color.color[2] = 0.0; /* B */ + card_state->sampler_border_color.color[3] = 0.0; /* A */ card_state->cc_viewport.min_depth = -1.e35; card_state->cc_viewport.max_depth = 1.e35; @@ -760,12 +760,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)); } } } From 260cbcfe61868175ba3e649ce07d43f57601f9be Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 6 Oct 2008 13:17:59 -0700 Subject: [PATCH 38/52] Document and use 'legacy' border color mode It's very convenient that the hardware supports this non-default mode since it's exactly what is specified by the Render extension. This provides a more efficient means of fixing bug #16820: [EXA] Composition result in black for areas outside of source-surface bo https://bugs.freedesktop.org/show_bug.cgi?id=16820 without the software fallback we had in the earlier fix, (commit 76c9ece36e6400fd10f364ee330faea470e2da64 ). --- src/brw_defines.h | 3 +++ src/brw_structs.h | 18 +++++++++++++++++- src/i965_render.c | 19 +++++++++++-------- 3 files changed, 31 insertions(+), 9 deletions(-) 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 553aeebb..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_border_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 { diff --git a/src/i965_render.c b/src/i965_render.c index 4bffe0d7..9ee273c0 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -496,8 +496,8 @@ typedef struct _gen4_state { [SAMPLER_STATE_FILTER_COUNT] [SAMPLER_STATE_EXTEND_COUNT][2]; - struct brw_sampler_border_color sampler_border_color; - PAD64 (brw_sampler_border_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] @@ -572,7 +572,10 @@ sampler_state_init (struct brw_sampler_state *sampler_state, memset(sampler_state, 0, sizeof(*sampler_state)); sampler_state->ss0.lod_preclamp = 1; /* GL mode */ - sampler_state->ss0.border_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: @@ -734,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) */ + /* 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.0; /* R */ - card_state->sampler_border_color.color[1] = 0.0; /* G */ - card_state->sampler_border_color.color[2] = 0.0; /* B */ - card_state->sampler_border_color.color[3] = 0.0; /* A */ + 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; From 979bb109c6d76fe18b9e29f55afb2548f890bbfe Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 6 Oct 2008 16:05:46 -0700 Subject: [PATCH 39/52] Document more VBIOS functionality Document a few more VBT structures and comment on VBIOS communication a bit. There should be enough there now for a sufficiently motivated developer to start implementing support for hotkeys and other features on pre-IGD OpRegion machines. --- src/bios_reader/bios_reader.c | 86 ++++++++++++++--- src/i830_bios.h | 172 ++++++++++++++++++++++++++++++++-- 2 files changed, 238 insertions(+), 20 deletions(-) diff --git a/src/bios_reader/bios_reader.c b/src/bios_reader/bios_reader.c index 29c3edb0..61b492d2 100644 --- a/src/bios_reader/bios_reader.c +++ b/src/bios_reader/bios_reader.c @@ -165,7 +165,9 @@ static void dump_general_definitions(void) { struct bdb_block *block; struct bdb_general_definitions *defs; - unsigned char *lvds_data; + struct child_device_config *child; + int i; + char child_id[11]; block = find_section(BDB_GENERAL_DEFINITIONS); @@ -173,7 +175,6 @@ static void dump_general_definitions(void) return; defs = block->data; - lvds_data = defs->tv_or_lvds_info; printf("General definitions block:\n"); @@ -185,10 +186,53 @@ static void dump_general_definitions(void) 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_child_devices(void) +{ + struct bdb_block *block; + struct bdb_child_devices *child_devs; + struct child_device_config *child; + int i; + + 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); } @@ -199,9 +243,10 @@ static void dump_lvds_options(void) struct bdb_lvds_options *options; block = find_section(BDB_LVDS_OPTIONS); - - if (!block) + if (!block) { + printf("No LVDS options block\n"); return; + } options = block->data; @@ -228,8 +273,10 @@ static void dump_lvds_ptr_data(void) struct lvds_fp_timing *fp_timing; block = find_section(BDB_LVDS_LFP_DATA_PTRS); - if (!block) + if (!block) { + printf("No LFP data pointers block\n"); return; + } ptrs = block->data; fp_timing = (struct lvds_fp_timing *)((uint8_t *)bdb + @@ -252,8 +299,10 @@ static void dump_lvds_data(void) int i; block = find_section(BDB_LVDS_LFP_DATA); - if (!block) + if (!block) { + printf("No LVDS data block\n"); return; + } lvds_data = block->data; num_entries = block->size / sizeof(struct bdb_lvds_lfp_data_entry); @@ -305,6 +354,8 @@ int main(int argc, char **argv) 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 \n", argv[0]); @@ -348,11 +399,24 @@ 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); + 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(); diff --git a/src/i830_bios.h b/src/i830_bios.h index 6c8bd935..0a1f4ba6 100644 --- a/src/i830_bios.h +++ b/src/i830_bios.h @@ -117,9 +117,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 +218,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 +251,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 +330,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]; @@ -257,6 +398,19 @@ int i830_bios_init(ScrnInfoPtr pScrn); /* * 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 +489,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) From 080d36648f92d3b9a559e5458687fa82afab411f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 1 Oct 2008 16:13:09 -0700 Subject: [PATCH 40/52] Add support for RepeatPad and RepeatReflect to 915 and 830-class Render accel. --- src/i830_render.c | 22 ++++++++++++++++++---- src/i915_render.c | 23 ++++++++++++++++++----- 2 files changed, 36 insertions(+), 9 deletions(-) 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/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: From 3621183cf4acef23414e8d69c34b1e587f52ec67 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 6 Oct 2008 16:59:16 -0700 Subject: [PATCH 41/52] Fix bios_reader build against old servers. The server's pci_device structure ends up conflicting with libpciaccess's. Just don't include the server structure for this non-server tool. --- src/bios_reader/Makefile.am | 3 ++- src/bios_reader/bios_reader.c | 3 +++ src/i830_bios.h | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) 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 61b492d2..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" diff --git a/src/i830_bios.h b/src/i830_bios.h index 0a1f4ba6..39706ac6 100644 --- a/src/i830_bios.h +++ b/src/i830_bios.h @@ -29,7 +29,9 @@ #define _I830_BIOS_H_ #include +#ifndef REG_DUMPER #include +#endif struct vbt_header { char signature[20]; /**< Always starts with 'VBT$' */ @@ -393,7 +395,9 @@ 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 From 3a4151b69daa478ac6edf042d604ee41e8429c0d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 6 Oct 2008 17:00:08 -0700 Subject: [PATCH 42/52] Fix driver build against server 1.4.2. This disables UXA and DRM modesetting pre-1.5, due to privates handling issues. --- Makefile.am | 7 ++++++- configure.ac | 9 +++++++++ src/Makefile.am | 9 ++++++--- src/i830_accel.c | 6 +++++- src/i830_driver.c | 2 ++ src/i830_exa.c | 25 ++++++++++++++++--------- 6 files changed, 44 insertions(+), 14 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 86bb80fd..d5db3a94 100644 --- a/configure.ac +++ b/configure.ac @@ -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/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/i830_accel.c b/src/i830_accel.c index 386e653f..a9b30059 100644 --- a/src/i830_accel.c +++ b/src/i830_accel.c @@ -331,9 +331,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_driver.c b/src/i830_driver.c index 3a2a9a40..933c8b87 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2693,8 +2693,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 diff --git a/src/i830_exa.c b/src/i830_exa.c index fd29df11..e03f2de1 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -726,14 +726,6 @@ I830EXAInit(ScreenPtr pScreen) return TRUE; } -static int uxa_pixmap_index; - -static void -i830_uxa_set_pixmap_bo (PixmapPtr pixmap, dri_bo *bo) -{ - dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, bo); -} - dri_bo * i830_get_pixmap_bo(PixmapPtr pixmap) { @@ -741,17 +733,31 @@ 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 int uxa_pixmap_index; + +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) { @@ -937,6 +943,7 @@ i830_uxa_init (ScreenPtr pScreen) return TRUE; } +#endif /* I830_USE_UXA */ #ifdef XF86DRI From 111dd151dedf535464d638461f9485ec2939780e Mon Sep 17 00:00:00 2001 From: Lukas Hejtmanek Date: Tue, 7 Oct 2008 15:07:08 +0200 Subject: [PATCH 43/52] Fix driver build against server master. Broken by 3a4151b69daa478ac6edf042d604ee41e8429c0d --- src/i830_exa.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/i830_exa.c b/src/i830_exa.c index e03f2de1..86231595 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -726,6 +726,10 @@ I830EXAInit(ScreenPtr pScreen) return TRUE; } +#ifdef I830_USE_UXA +static int uxa_pixmap_index; +#endif + dri_bo * i830_get_pixmap_bo(PixmapPtr pixmap) { @@ -750,7 +754,6 @@ i830_get_pixmap_bo(PixmapPtr pixmap) } #if defined(I830_USE_UXA) -static int uxa_pixmap_index; static void i830_uxa_set_pixmap_bo (PixmapPtr pixmap, dri_bo *bo) From 74571363539426abeb0a1af11f3bb545d91ed6c2 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Wed, 8 Oct 2008 15:36:10 +0800 Subject: [PATCH 44/52] Put forware VBIOS data parsing i830_bios_init() is called too late after output init, which makes bios data mostly useless, and caused all TV init fail as tv_present flag is not set. --- src/i830_driver.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 933c8b87..c1d61f4f 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1895,6 +1895,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) { @@ -1914,10 +1918,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. From 4128b01ec84ffa0f03c335c36738f383376d9381 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Thu, 9 Oct 2008 09:19:41 +0800 Subject: [PATCH 45/52] Remove Lenovo T61 TV quirk BIOS already says no integrated TV, and this quirk blocks TV on R61i which has the same subdevice id as T61. --- src/i830_quirks.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/i830_quirks.c b/src/i830_quirks.c index 528b5646..12cab861 100644 --- a/src/i830_quirks.c +++ b/src/i830_quirks.c @@ -258,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 }, From d24010b7b3f2419beb40dc5ae1e8aeb3e04b5a93 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 9 Oct 2008 14:29:04 -0700 Subject: [PATCH 46/52] Disable frame buffer compression by default for GM965. We haven't found a way to make FBC work reliably with GM965 yet, (it often fails to notice CPU writes). This appears to be a specific problem with this device, (as we haven't gotten similar bug reports for subsequent devices such as GM45). So FBC is now disabled by default for GM965 but can still be enabled with the FrameBufferCompression option for experimenting/debugging. This resolves bug #16257: [GM965 EXA] Frame-buffer compression broken for CPU writes (XPutImage) https://bugs.freedesktop.org/show_bug.cgi?id=16257 --- src/i830.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/i830.h b/src/i830.h index 5b782369..89f19d20 100644 --- a/src/i830.h +++ b/src/i830.h @@ -950,6 +950,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; } From d09d938bf26ea0c44352ff6e7a57ba43f4047fdb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 9 Oct 2008 18:17:13 -0700 Subject: [PATCH 47/52] i830 nondrm batch buffer insertion was missing ADVANCE_LP_RING() call The ring commands to insert a batch buffer to the ring in i830 form were not terminated by a call to ADVANCE_LP_RING(). This surely would have caused chaos. Signed-off-by: Keith Packard --- src/i830_batchbuffer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c index 3727f0ea..b7b8f18e 100644 --- a/src/i830_batchbuffer.c +++ b/src/i830_batchbuffer.c @@ -64,6 +64,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; } From 140451abb41fbd68d5aac4736c1cf1ec2805dd9e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 9 Oct 2008 18:18:34 -0700 Subject: [PATCH 48/52] For non-DRM, add NOOPs after BATCH_BUFFER_START to verify completion In non-DRM mode, the driver waits for the hardware by checking the ring pointers; when the ring is empty, it assumes the hardware is idle. However, the hardware updates the ring pointers before executing a command, so if the MI_BATCH_BUFFER_START is the last command in the ring, the driver will think the hardware is idle while it may still be processing the contents of the batch buffer. Placing NOOPs after the BATCH_BUFFER_START allows the driver to know that the hardware has completed the batch buffer. Signed-off-by: Keith Packard --- src/i830_batchbuffer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c index b7b8f18e..cd8f687f 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; From 6cb4150160bb1e1365773561fb53294ad9248a0e Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Sun, 12 Oct 2008 08:07:44 +0800 Subject: [PATCH 49/52] Bug #17892: Fix possible crash in CRT probe Introduced in patch for DVI-I CRT probe, if no EDID CRT monitor is connected, origin code destroys default DDC bus which causes crash in later get_modes call. Change it to setup and destroy DDC bus as needed in get_modes, so we always reprobe and get current state. --- src/i830_crt.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/i830_crt.c b/src/i830_crt.c index 2e70eb8d..479fbe5b 100644 --- a/src/i830_crt.c +++ b/src/i830_crt.c @@ -338,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; } /** @@ -428,18 +434,19 @@ i830_get_edid(xf86OutputPtr output, int gpio_reg, char *gpio_str) xf86MonPtr edid_mon = NULL; /* Set up the DDC bus. */ - if (gpio_reg != GPIOA) - I830I2CInit(output->scrn, &intel_output->pDDCBus, gpio_reg, gpio_str); + 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; } @@ -448,6 +455,7 @@ 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. */ @@ -458,6 +466,11 @@ i830_crt_get_modes (xf86OutputPtr output) 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); @@ -509,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"); } From 1c6ea4ab4772453da915306045add8d147d567f2 Mon Sep 17 00:00:00 2001 From: Julien Cristau Date: Sun, 12 Oct 2008 15:10:22 +0200 Subject: [PATCH 50/52] Typo fix Reported by Tomas Carnecky on IRC --- src/i830_memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830_memory.c b/src/i830_memory.c index ecfdf2a2..505564f5 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -757,7 +757,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; } From e7e49bed7e254256f8cc0d4afcdfadc6dadf19e6 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 14 Oct 2008 10:38:05 -0700 Subject: [PATCH 51/52] Add a GTT dumper for G4x debugging. --- src/reg_dumper/Makefile.am | 13 ++++- src/reg_dumper/gtt.c | 98 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 src/reg_dumper/gtt.c 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 + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#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; +} From 4dd00681dd0f9fce8dfd4592b46418edbbd2eeb4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 14 Oct 2008 11:33:33 -0700 Subject: [PATCH 52/52] Fix broken stolen memory counting on G4X. On the GM45 we were assuming too little stolen memory (mostly harmless, except when it wasn't, until the AGP fix), and on the G45 we were assuming too much stolen memory, which was quite harmful when we touched the page that didn't get mapped. Future stolen memory accounting should use src/reg_dumper/intel_gtt before and after enabling AGP on the chipset to confirm that only the GTT entries not mapped to stolen are replaced, and that all of the unmapped GTT entries are replaced with the constant scratch page. --- src/i830_driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index c1d61f4f..eaf5d27b 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -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) {