From ee52c0ec4e95fa6e5f35c9cd75005a0c0003fd97 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Jan 2007 16:53:07 -0800 Subject: [PATCH 01/14] Correct typo resulting in a crash with ivch. = != ==. --- src/ivch/ivch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c index 6c5db6c9..085b542a 100644 --- a/src/ivch/ivch.c +++ b/src/ivch/ivch.c @@ -92,7 +92,7 @@ ivch_init(I2CBusPtr b, I2CSlaveAddr addr) xf86DrvMsg(b->scrnIndex, X_INFO, "detecting ivch\n"); priv = xcalloc(1, sizeof(struct ivch_priv)); - if (priv = NULL) + if (priv == NULL) return NULL; priv->d.DevName = "i82807aa \"ivch\" LVDS/CMOS panel controller"; From 5857b4a1693085b8b42dd9560a7c4f5c3c82f862 Mon Sep 17 00:00:00 2001 From: Wang Zhenyu Date: Wed, 10 Jan 2007 15:09:47 +0800 Subject: [PATCH 02/14] Formalize sync interface We should just call i830MarkSync/i830WaitSync in places we need, which care for both XAA and EXA. --- src/i830_driver.c | 5 +---- src/i830_randr.c | 6 +----- src/i830_rotate.c | 11 +++-------- src/i830_video.c | 5 +---- src/i915_video.c | 3 +-- 5 files changed, 7 insertions(+), 23 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 29927985..9bc74b54 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -3016,10 +3016,7 @@ i830AdjustFrame(int scrnIndex, int x, int y, int flags) if (crtc && crtc->enabled) { /* Sync the engine before adjust frame */ - if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) { - (*pI830->AccelInfoRec->Sync)(pScrn); - pI830->AccelInfoRec->NeedToSync = FALSE; - } + i830WaitSync(pScrn); i830PipeSetBase(crtc, output->initial_x + x, output->initial_y + y); } } diff --git a/src/i830_randr.c b/src/i830_randr.c index 533322b2..18f84c49 100644 --- a/src/i830_randr.c +++ b/src/i830_randr.c @@ -627,14 +627,10 @@ xf86RandR12CrtcSet (ScreenPtr pScreen, /* XXX need device-independent mode setting code through an API */ if (changed) { - I830Ptr pI830 = I830PTR(pScrn); crtc->enabled = mode != NULL; /* Sync the engine before adjust mode */ - if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) { - (*pI830->AccelInfoRec->Sync)(pScrn); - pI830->AccelInfoRec->NeedToSync = FALSE; - } + i830WaitSync(pScrn); if (mode) { diff --git a/src/i830_rotate.c b/src/i830_rotate.c index 029f439e..efa76edc 100644 --- a/src/i830_rotate.c +++ b/src/i830_rotate.c @@ -805,10 +805,7 @@ I965UpdateRotate (ScreenPtr pScreen, /* Since we use the same little vertex buffer over and over, sync for * subsequent rectangles. */ - if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) { - (*pI830->AccelInfoRec->Sync)(pScrn); - pI830->AccelInfoRec->NeedToSync = FALSE; - } + i830WaitSync(pScrn); } pbox++; @@ -895,12 +892,10 @@ I965UpdateRotate (ScreenPtr pScreen, ADVANCE_LP_RING(); first_output = FALSE; - if (pI830->AccelInfoRec) - pI830->AccelInfoRec->NeedToSync = TRUE; + i830MarkSync(pScrn); } - if (pI830->AccelInfoRec) - (*pI830->AccelInfoRec->Sync)(pScrn); + i830WaitSync(pScrn); #ifdef XF86DRI if (didLock) I830DRIUnlock(pScrn1); diff --git a/src/i830_video.c b/src/i830_video.c index 6b76faac..652e73d8 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -2358,10 +2358,7 @@ I830PutImage(ScrnInfoPtr pScrn, * acceleration to finish before writing the new video data into * framebuffer. */ - if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) { - (*pI830->AccelInfoRec->Sync)(pScrn); - pI830->AccelInfoRec->NeedToSync = FALSE; - } + i830WaitSync(pScrn); } switch (id) { diff --git a/src/i915_video.c b/src/i915_video.c index 52fe1a51..591b6f82 100644 --- a/src/i915_video.c +++ b/src/i915_video.c @@ -433,7 +433,6 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, ADVANCE_LP_RING(); } - if (pI830->AccelInfoRec) - pI830->AccelInfoRec->NeedToSync = TRUE; + i830MarkSync(pScrn); } From fa383289ac8a6dd1cb359e6f1991cc42beb6ff02 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 4 Jan 2007 14:12:45 -0800 Subject: [PATCH 03/14] EXA: Wait for sync before we set up new state in our static state buffers. --- src/i965_exa_render.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c index 68293cd2..dc3d7bfe 100644 --- a/src/i965_exa_render.c +++ b/src/i965_exa_render.c @@ -404,6 +404,9 @@ I965EXAPrepareComposite(int op, PicturePtr pSrcPicture, binding_table_entries = 2; /* default no mask */ + /* Wait for sync before we start setting up our new state */ + i830WaitSync(pScrn); + /* Set up our layout of state in framebuffer. First the general state: */ next_offset = 0; vs_offset = ALIGN(next_offset, 64); @@ -1024,6 +1027,11 @@ I965EXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, "dstX %d, dstY %d\n", srcX, srcY, srcXend, srcYend, maskX, maskY, maskXend, maskYend, dstX, dstY); + /* Wait for any existing composite rectangles to land before we overwrite + * the VB with the next one. + */ + i830WaitSync(pScrn); + i = 0; /* rect (x2,y2) */ vb[i++] = (float)(srcXend) / pI830->scale_units[0][0]; @@ -1088,4 +1096,9 @@ I965EXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, OUT_RING(0); /* Immediate data high DW */ ADVANCE_LP_RING(); } + + /* Mark sync so we can wait for it before setting up the VB on the next + * rectangle. + */ + i830MarkSync(pScrn); } From d13bc016c0723f1df633ddaf5610ad73003b7c96 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 10 Jan 2007 15:06:56 -0800 Subject: [PATCH 04/14] Correct x/y/pitch limitations in several cases, and detail them in i830_exa.c. This reduces max framebuffer width and increases max framebuffer height on 965, reduces max X/Y on pre-965 EXA (could have caused mis-rendering), and increases max X/Y on 965 EXA (would have prevented acceleration). --- src/i830_driver.c | 15 ++++++------- src/i830_exa.c | 54 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 9bc74b54..20781aa0 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1139,14 +1139,13 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) /* Allocate an xf86CrtcConfig */ xf86CrtcConfigInit (pScrn); xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - - if (IS_I965G(pI830)) - { - max_width = 16384; - max_height = 4096; - } - else - { + + /* See i830_exa.c comments for why we limit the framebuffer size like this. + */ + if (IS_I965G(pI830)) { + max_width = 8192; + max_height = 8192; + } else { max_width = 2048; max_height = 2048; } diff --git a/src/i830_exa.c b/src/i830_exa.c index 4944e409..f11424f2 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -447,13 +447,53 @@ I830EXAInit(ScreenPtr pScreen) /* disable Xv here... */ } - /* i915 3D requires 16 byte alignment (4k if tiled) */ - pI830->EXADriverPtr->pixmapOffsetAlign = 256; - pI830->EXADriverPtr->pixmapPitchAlign = 64; - - /* i845 and i945 2D limits rendering to 65536 lines and pitch of 32768. */ - pI830->EXADriverPtr->maxX = 4095; - pI830->EXADriverPtr->maxY = 4095; + /* Limits are described in the BLT engine chapter under Graphics Data Size + * Limitations, and the descriptions of SURFACE_STATE, 3DSTATE_BUFFER_INFO, + * 3DSTATE_DRAWING_RECTANGLE, 3DSTATE_MAP_INFO, and 3DSTATE_MAP_INFO. + * + * i845 through i965 limits 2D rendering to 65536 lines and pitch of 32768. + * + * i965 limits 3D surface to (2*element size)-aligned offset if un-tiled. + * i965 limits 3D surface to 4kB-aligned offset if tiled. + * i965 limits 3D surfaces to w,h of ?,8192. + * i965 limits 3D surface to pitch of 1B - 128kB. + * i965 limits 3D surface pitch alignment to 512B, only if tiled. + * i965 limits 3D destination drawing rect to w,h of 8192,8192. + * + * i915 limits 3D textures to 4B-aligned offset if un-tiled. + * i915 limits 3D textures to ~4kB-aligned offset if tiled. + * i915 limits 3D textures to width,height of 2048,2048. + * i915 limits 3D textures to pitch of 16B - 8kB, in dwords. + * i915 limits 3D destination to ~4kB-aligned offset if tiled. + * i915 limits 3D destination to pitch of 16B - 8kB, in dwords, if un-tiled. + * i915 limits 3D destination to pitch of 512B - 8kB, in tiles, if tiled. + * i915 limits 3D destination to POT aligned pitch if tiled. + * i915 limits 3D destination drawing rect to w,h of 2048,2048. + * + * i845 limits 3D textures to 4B-aligned offset if un-tiled. + * i845 limits 3D textures to ~4kB-aligned offset if tiled. + * i845 limits 3D textures to width,height of 2048,2048. + * i845 limits 3D textures to pitch of 4B - 8kB, in dwords. + * i845 limits 3D destination to 4B-aligned offset if un-tiled. + * i845 limits 3D destination to ~4kB-aligned offset if tiled. + * i845 limits 3D destination to pitch of 8B - 8kB, in dwords. + * i845 limits 3D destination drawing rect to w,h of 2048,2048. + * + * For the tiled issues, the only tiled buffer we draw to should be + * the front, which will have an appropriate pitch/offset already set up, + * so EXA doesn't need to worry. + */ + if (IS_I965G(pI830)) { + pI830->EXADriverPtr->pixmapOffsetAlign = 4 * 2; + pI830->EXADriverPtr->pixmapPitchAlign = 1; + pI830->EXADriverPtr->maxX = 8192; + pI830->EXADriverPtr->maxY = 8192; + } else { + pI830->EXADriverPtr->pixmapOffsetAlign = 4; + pI830->EXADriverPtr->pixmapPitchAlign = 16; + pI830->EXADriverPtr->maxX = 2048; + pI830->EXADriverPtr->maxY = 2048; + } /* Sync */ pI830->EXADriverPtr->WaitMarker = I830EXASync; From f5d528f8ea27de31054e7f1843e34d8379f811ea Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 11 Jan 2007 10:36:33 -0800 Subject: [PATCH 05/14] Don't limit cachelines to a vertical of 2048, and increase default allocation. The cachelines are used for two things: XAA pixmap cache and XV memory. Only XAA pixmap cache is referred to using an offset pointing at the beginning of the front buffer in rendering, and XAA only uses the 2d BLT engine, which actually has a vertical limit of 65536. So, pixmap cache is now limited to that much vertical. Additionally, the previous cachelines allocation was too small for our advertised XV limits, so video at the limits would fail with BadAlloc. Now, XAA allocates the same approximate amount of offscreen memory as EXA: 3 times the screen size, plus one packed HD video. --- man/i810.man | 7 +++++-- src/common.h | 4 ---- src/i830_memory.c | 35 ++++++++++++++++++----------------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/man/i810.man b/man/i810.man index ff458098..d1ee2da0 100644 --- a/man/i810.man +++ b/man/i810.man @@ -84,9 +84,12 @@ This allows the user to change the amount of graphics memory used for 2D acceleration and video. Decreasing this amount leaves more for 3D textures. Increasing it can improve 2D performance at the expense of 3D performance. +.TP +This option only takes effect when XAA acceleration is enabled. +.TP Default: depends on the resolution, depth, and available video memory. The -driver attempts to allocate at least enough to hold two DVD-sized YUV buffers -by default. The default used for a specific configuration can be found +driver attempts to allocate space for at 3 screenfuls of pixmaps plus an +HD-sized XV video. The default used for a specific configuration can be found by examining the __xservername__ log file. .TP .BI "Option \*qDRI\*q \*q" boolean \*q diff --git a/src/common.h b/src/common.h index 2035862f..561dfac7 100644 --- a/src/common.h +++ b/src/common.h @@ -339,10 +339,6 @@ extern int I810_DEBUG; #define I810_CURSOR_X 64 #define I810_CURSOR_Y I810_CURSOR_X -/* XXX Need to check if these are reasonable. */ -#define MAX_DISPLAY_PITCH 2048 -#define MAX_DISPLAY_HEIGHT 2048 - #define PIPE_NAME(n) ('A' + (n)) #endif /* _INTEL_COMMON_H_ */ diff --git a/src/i830_memory.c b/src/i830_memory.c index af866889..426242a9 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -637,6 +637,13 @@ GetFreeSpace(ScrnInfoPtr pScrn) return extra; } +/* This is the 2D rendering vertical coordinate limit. We can ignore + * the 3D rendering limits in our 2d pixmap cache allocation, because XAA + * doesn't do any 3D rendering to/from the cache lines when using an offset + * at the start of framebuffer. + */ +#define MAX_2D_HEIGHT 65536 + /** * Allocates a framebuffer for a screen. * @@ -698,25 +705,19 @@ I830AllocateFramebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, "maxCacheLines < 0 in I830Allocate2DMemory()\n"); maxCacheLines = 0; } - if (maxCacheLines > (MAX_DISPLAY_HEIGHT - pScrn->virtualY)) - maxCacheLines = MAX_DISPLAY_HEIGHT - pScrn->virtualY; + if (maxCacheLines > (MAX_2D_HEIGHT - pScrn->virtualY)) + maxCacheLines = MAX_2D_HEIGHT - pScrn->virtualY; if (pI830->CacheLines >= 0) { cacheLines = pI830->CacheLines; } else { -#if 1 - /* Make sure there is enough for two DVD sized YUV buffers */ - cacheLines = (pScrn->depth == 24) ? 256 : 384; - if (pScrn->displayWidth <= 1024) - cacheLines *= 2; -#else - /* - * Make sure there is enough for two DVD sized YUV buffers. - * Make that 1.5MB, which is around what was allocated with - * the old algorithm - */ - cacheLines = (MB(1) + KB(512)) / pI830->cpp / pScrn->displayWidth; -#endif + int size; + + size = 3 * lineSize * pScrn->virtualY; + size += 1920 * 1088 * 2 * 2; + size = ROUND_TO_PAGE(size); + + cacheLines = (size + lineSize - 1) / lineSize; } if (cacheLines > maxCacheLines) cacheLines = maxCacheLines; @@ -902,8 +903,8 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) maxFb = pI830->FrontBuffer.Size + extra; lineSize = pScrn->displayWidth * pI830->cpp; maxFb = ROUND_DOWN_TO(maxFb, lineSize); - if (maxFb > lineSize * MAX_DISPLAY_HEIGHT) - maxFb = lineSize * MAX_DISPLAY_HEIGHT; + if (maxFb > lineSize * MAX_2D_HEIGHT) + maxFb = lineSize * MAX_2D_HEIGHT; if (0/*maxFb > pI830->FrontBuffer.Size*/) { unsigned long oldsize; /* From c288aea40775a9cf561fda9912187c3cb5baa419 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 11 Jan 2007 10:39:00 -0800 Subject: [PATCH 06/14] Bug #8845: Unify all our XV ports to 1920x1088 maximum size. This increases the "legacy" size, but that was checked against the 845 documentation which claims support for 2048x2048 as well. It decreases the textured video size, which was running into the limits of the bigrequests extension. The new limits should fit within bigrequests while still supporting HD videos. --- src/i830_video.c | 69 +++++++++++++++--------------------------------- 1 file changed, 21 insertions(+), 48 deletions(-) diff --git a/src/i830_video.c b/src/i830_video.c index 652e73d8..816289e7 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -128,10 +128,19 @@ I830FreeMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear); static Atom xvBrightness, xvContrast, xvSaturation, xvColorKey, xvPipe, xvDoubleBuffer; static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5; +/* Limits for the overlay/textured video source sizes. The actual hardware + * limits are 2048x2048 or better for overlay and both of our textured video + * implementations. However, we run into the bigrequests limit of (currently) + * 4MB, which even the planar format's 2048*2048*1.5 bytes is larger than. + * Conveniently, the HD resolution, even in packed format, takes + * (1920*1088*2) bytes, which is just shy of 4MB. + * + * While the HD resolution is actually 1920x1080, we increase our advertised + * size to 1088 because some software wants to send an image aligned to + * 16-pixel boundaries. + */ #define IMAGE_MAX_WIDTH 1920 #define IMAGE_MAX_HEIGHT 1088 -#define IMAGE_MAX_WIDTH_LEGACY 1024 -#define IMAGE_MAX_HEIGHT_LEGACY 1088 /* overlay debugging printf function */ #if 0 @@ -669,11 +678,6 @@ I830SetupImageVideoOverlay(ScreenPtr pScreen) adapt->name = "Intel(R) Video Overlay"; adapt->nEncodings = 1; adapt->pEncodings = DummyEncoding; - /* update the DummyEncoding for these two chipsets */ - if (IS_845G(pI830) || IS_I830(pI830)) { - adapt->pEncodings->width = IMAGE_MAX_WIDTH_LEGACY; - adapt->pEncodings->height = IMAGE_MAX_HEIGHT_LEGACY; - } adapt->nFormats = NUM_FORMATS; adapt->pFormats = Formats; adapt->nPorts = 1; @@ -777,7 +781,6 @@ static XF86VideoAdaptorPtr I830SetupImageVideoTextured(ScreenPtr pScreen) { XF86VideoAdaptorPtr adapt; - XF86VideoEncodingPtr encoding; XF86AttributePtr attrs; I830PortPrivPtr portPrivs; DevUnion *devUnions; @@ -791,15 +794,13 @@ I830SetupImageVideoTextured(ScreenPtr pScreen) adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec)); portPrivs = xcalloc(nports, sizeof(I830PortPrivRec)); devUnions = xcalloc(nports, sizeof(DevUnion)); - encoding = xcalloc(1, sizeof(XF86VideoEncodingRec)); attrs = xcalloc(nAttributes, sizeof(XF86AttributeRec)); if (adapt == NULL || portPrivs == NULL || devUnions == NULL || - encoding == NULL || attrs == NULL) + attrs == NULL) { xfree(adapt); xfree(portPrivs); xfree(devUnions); - xfree(encoding); xfree(attrs); return NULL; } @@ -808,13 +809,7 @@ I830SetupImageVideoTextured(ScreenPtr pScreen) adapt->flags = 0; adapt->name = "Intel(R) Textured Video"; adapt->nEncodings = 1; - adapt->pEncodings = encoding; - adapt->pEncodings[0].id = 0; - adapt->pEncodings[0].name = "XV_IMAGE"; - adapt->pEncodings[0].width = 2048; - adapt->pEncodings[0].height = 2048; - adapt->pEncodings[0].rate.numerator = 1; - adapt->pEncodings[0].rate.denominator = 1; + adapt->pEncodings = DummyEncoding; adapt->nFormats = NUM_FORMATS; adapt->pFormats = Formats; adapt->nPorts = nports; @@ -2439,26 +2434,16 @@ I830QueryImageAttributes(ScrnInfoPtr pScrn, unsigned short *w, unsigned short *h, int *pitches, int *offsets, Bool textured) { - I830Ptr pI830 = I830PTR(pScrn); int size, tmp; #if 0 ErrorF("I830QueryImageAttributes: w is %d, h is %d\n", *w, *h); #endif - if (!textured) { - if (IS_845G(pI830) || IS_I830(pI830)) { - if (*w > IMAGE_MAX_WIDTH_LEGACY) - *w = IMAGE_MAX_WIDTH_LEGACY; - if (*h > IMAGE_MAX_HEIGHT_LEGACY) - *h = IMAGE_MAX_HEIGHT_LEGACY; - } else { - if (*w > IMAGE_MAX_WIDTH) - *w = IMAGE_MAX_WIDTH; - if (*h > IMAGE_MAX_HEIGHT) - *h = IMAGE_MAX_HEIGHT; - } - } + if (*w > IMAGE_MAX_WIDTH) + *w = IMAGE_MAX_WIDTH; + if (*h > IMAGE_MAX_HEIGHT) + *h = IMAGE_MAX_HEIGHT; *w = (*w + 1) & ~1; if (offsets) @@ -2596,13 +2581,8 @@ I830AllocateSurface(ScrnInfoPtr pScrn, OVERLAY_DEBUG("I830AllocateSurface\n"); - if (IS_845G(pI830) || IS_I830(pI830)) { - if ((w > IMAGE_MAX_WIDTH_LEGACY) || (h > IMAGE_MAX_HEIGHT_LEGACY)) - return BadAlloc; - } else { - if ((w > IMAGE_MAX_WIDTH) || (h > IMAGE_MAX_HEIGHT)) - return BadAlloc; - } + if ((w > IMAGE_MAX_WIDTH) || (h > IMAGE_MAX_HEIGHT)) + return BadAlloc; /* What to do when rotated ?? */ if (pI830->rotation != RR_Rotate_0) @@ -2804,8 +2784,6 @@ static void I830InitOffscreenImages(ScreenPtr pScreen) { XF86OffscreenImagePtr offscreenImages; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); /* need to free this someplace */ if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) { @@ -2820,13 +2798,8 @@ I830InitOffscreenImages(ScreenPtr pScreen) offscreenImages[0].stop = I830StopSurface; offscreenImages[0].setAttribute = I830SetSurfaceAttribute; offscreenImages[0].getAttribute = I830GetSurfaceAttribute; - if (IS_845G(pI830) || IS_I830(pI830)) { - offscreenImages[0].max_width = IMAGE_MAX_WIDTH_LEGACY; - offscreenImages[0].max_height = IMAGE_MAX_HEIGHT_LEGACY; - } else { - offscreenImages[0].max_width = IMAGE_MAX_WIDTH; - offscreenImages[0].max_height = IMAGE_MAX_HEIGHT; - } + offscreenImages[0].max_width = IMAGE_MAX_WIDTH; + offscreenImages[0].max_height = IMAGE_MAX_HEIGHT; offscreenImages[0].num_attributes = 1; offscreenImages[0].attributes = Attributes; From 6874a6f25ac87783d3770f77b9192e2d36d083a3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 11 Jan 2007 12:34:38 -0800 Subject: [PATCH 07/14] Restore legacy overlay size limits, due to card hangs at larger sizes. --- src/i830_video.c | 49 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/src/i830_video.c b/src/i830_video.c index 816289e7..a330eb5f 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -128,12 +128,14 @@ I830FreeMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear); static Atom xvBrightness, xvContrast, xvSaturation, xvColorKey, xvPipe, xvDoubleBuffer; static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5; -/* Limits for the overlay/textured video source sizes. The actual hardware +/* Limits for the overlay/textured video source sizes. The documented hardware * limits are 2048x2048 or better for overlay and both of our textured video * implementations. However, we run into the bigrequests limit of (currently) * 4MB, which even the planar format's 2048*2048*1.5 bytes is larger than. * Conveniently, the HD resolution, even in packed format, takes - * (1920*1088*2) bytes, which is just shy of 4MB. + * (1920*1088*2) bytes, which is just shy of 4MB. Additionally, on the 830 + * and 845, larger sizes resulted in the card hanging, so we keep the limits + * lower there. * * While the HD resolution is actually 1920x1080, we increase our advertised * size to 1088 because some software wants to send an image aligned to @@ -141,6 +143,8 @@ static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5; */ #define IMAGE_MAX_WIDTH 1920 #define IMAGE_MAX_HEIGHT 1088 +#define IMAGE_MAX_WIDTH_LEGACY 1024 +#define IMAGE_MAX_HEIGHT_LEGACY 1088 /* overlay debugging printf function */ #if 0 @@ -678,6 +682,11 @@ I830SetupImageVideoOverlay(ScreenPtr pScreen) adapt->name = "Intel(R) Video Overlay"; adapt->nEncodings = 1; adapt->pEncodings = DummyEncoding; + /* update the DummyEncoding for these two chipsets */ + if (IS_845G(pI830) || IS_I830(pI830)) { + adapt->pEncodings->width = IMAGE_MAX_WIDTH_LEGACY; + adapt->pEncodings->height = IMAGE_MAX_HEIGHT_LEGACY; + } adapt->nFormats = NUM_FORMATS; adapt->pFormats = Formats; adapt->nPorts = 1; @@ -2434,16 +2443,24 @@ I830QueryImageAttributes(ScrnInfoPtr pScrn, unsigned short *w, unsigned short *h, int *pitches, int *offsets, Bool textured) { + I830Ptr pI830 = I830PTR(pScrn); int size, tmp; #if 0 ErrorF("I830QueryImageAttributes: w is %d, h is %d\n", *w, *h); #endif - if (*w > IMAGE_MAX_WIDTH) - *w = IMAGE_MAX_WIDTH; - if (*h > IMAGE_MAX_HEIGHT) - *h = IMAGE_MAX_HEIGHT; + if (IS_845G(pI830) || IS_I830(pI830)) { + if (*w > IMAGE_MAX_WIDTH_LEGACY) + *w = IMAGE_MAX_WIDTH_LEGACY; + if (*h > IMAGE_MAX_HEIGHT_LEGACY) + *h = IMAGE_MAX_HEIGHT_LEGACY; + } else { + if (*w > IMAGE_MAX_WIDTH) + *w = IMAGE_MAX_WIDTH; + if (*h > IMAGE_MAX_HEIGHT) + *h = IMAGE_MAX_HEIGHT; + } *w = (*w + 1) & ~1; if (offsets) @@ -2581,8 +2598,13 @@ I830AllocateSurface(ScrnInfoPtr pScrn, OVERLAY_DEBUG("I830AllocateSurface\n"); - if ((w > IMAGE_MAX_WIDTH) || (h > IMAGE_MAX_HEIGHT)) - return BadAlloc; + if (IS_845G(pI830) || IS_I830(pI830)) { + if ((w > IMAGE_MAX_WIDTH_LEGACY) || (h > IMAGE_MAX_HEIGHT_LEGACY)) + return BadAlloc; + } else { + if ((w > IMAGE_MAX_WIDTH) || (h > IMAGE_MAX_HEIGHT)) + return BadAlloc; + } /* What to do when rotated ?? */ if (pI830->rotation != RR_Rotate_0) @@ -2784,6 +2806,8 @@ static void I830InitOffscreenImages(ScreenPtr pScreen) { XF86OffscreenImagePtr offscreenImages; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); /* need to free this someplace */ if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) { @@ -2798,8 +2822,13 @@ I830InitOffscreenImages(ScreenPtr pScreen) offscreenImages[0].stop = I830StopSurface; offscreenImages[0].setAttribute = I830SetSurfaceAttribute; offscreenImages[0].getAttribute = I830GetSurfaceAttribute; - offscreenImages[0].max_width = IMAGE_MAX_WIDTH; - offscreenImages[0].max_height = IMAGE_MAX_HEIGHT; + if (IS_845G(pI830) || IS_I830(pI830)) { + offscreenImages[0].max_width = IMAGE_MAX_WIDTH_LEGACY; + offscreenImages[0].max_height = IMAGE_MAX_HEIGHT_LEGACY; + } else { + offscreenImages[0].max_width = IMAGE_MAX_WIDTH; + offscreenImages[0].max_height = IMAGE_MAX_HEIGHT; + } offscreenImages[0].num_attributes = 1; offscreenImages[0].attributes = Attributes; From 45696aa29124e2852f94880642e70bb2e0cee827 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 4 Jan 2007 12:34:47 -0800 Subject: [PATCH 08/14] EXA: Use PRIM3D_RECTLIST instead of TRIFAN so we don't get diagonal tearing. A side effect is the reduction in vertex dispatch, which is nice. --- src/i830_exa.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/i830_exa.c b/src/i830_exa.c index f11424f2..f1cd1e36 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -345,9 +345,9 @@ IntelEXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int vertex_count; if (pMask) - vertex_count = 4*6; + vertex_count = 3*6; else - vertex_count = 4*4; + vertex_count = 3*4; BEGIN_LP_RING(6+vertex_count); @@ -357,7 +357,7 @@ IntelEXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, OUT_RING(MI_NOOP); OUT_RING(MI_NOOP); - OUT_RING(PRIM3D_INLINE | PRIM3D_TRIFAN | (vertex_count-1)); + OUT_RING(PRIM3D_INLINE | PRIM3D_RECTLIST | (vertex_count-1)); OUT_RING_F(dstX); OUT_RING_F(dstY); @@ -385,15 +385,6 @@ IntelEXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, OUT_RING_F(maskXend / pI830->scale_units[1][0]); OUT_RING_F(maskYend / pI830->scale_units[1][1]); } - - OUT_RING_F(dstX + w); - OUT_RING_F(dstY); - OUT_RING_F(srcXend / pI830->scale_units[0][0]); - OUT_RING_F(srcY / pI830->scale_units[0][1]); - if (pMask) { - OUT_RING_F(maskXend / pI830->scale_units[1][0]); - OUT_RING_F(maskY / pI830->scale_units[1][1]); - } ADVANCE_LP_RING(); } } From 66c6427cc83e5e381932b0c10743cba4cb9ac883 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 16 Jan 2007 12:54:29 -0800 Subject: [PATCH 09/14] Add a settable backlight property for LVDS. This extends the output funcs to have a callback for when it's time to configure properties, and another for when the server has changed a property whose value isn't pending a mode set. (Pending properties are to be picked up by the driver at mode_set time). --- src/i810_reg.h | 13 +++++ src/i830_lvds.c | 124 ++++++++++++++++++++++++++++++++++++++------ src/i830_randr.c | 21 ++++++++ src/i830_xf86Crtc.h | 15 ++++++ 4 files changed, 156 insertions(+), 17 deletions(-) diff --git a/src/i810_reg.h b/src/i810_reg.h index c2eb8546..33b059d6 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -937,8 +937,21 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define BLC_PWM_CTL 0x61254 #define BACKLIGHT_MODULATION_FREQ_SHIFT (17) +/** + * This is the most significant 15 bits of the number of backlight cycles in a + * complete cycle of the modulated backlight control. + * + * The actual value is this field multiplied by two. + */ #define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) #define BLM_LEGACY_MODE (1 << 16) +/** + * This is the number of cycles out of the backlight modulation cycle for which + * the backlight is on. + * + * This field must be no greater than the number of cycles in the complete + * backlight modulation cycle. + */ #define BACKLIGHT_DUTY_CYCLE_SHIFT (0) #define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) diff --git a/src/i830_lvds.c b/src/i830_lvds.c index 18ac76bf..223c6ab9 100644 --- a/src/i830_lvds.c +++ b/src/i830_lvds.c @@ -32,6 +32,34 @@ #include "xf86.h" #include "i830.h" #include "i830_bios.h" +#include "X11/Xatom.h" + +/** + * Sets the backlight level. + * + * \param level backlight level, from 0 to i830_lvds_get_max_backlight(). + */ +static void +i830_lvds_set_backlight(ScrnInfoPtr pScrn, int level) +{ + I830Ptr pI830 = I830PTR(pScrn); + CARD32 blc_pwm_ctl; + + blc_pwm_ctl = INREG(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; + OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); +} + +/** + * Returns the maximum level of the backlight duty cycle field. + */ +static CARD32 +i830_lvds_get_max_backlight(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + return ((INREG(BLC_PWM_CTL) & BACKLIGHT_MODULATION_FREQ_MASK) >> + BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; +} /** * Sets the power state for the panel. @@ -41,25 +69,16 @@ i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on) { I830Ptr pI830 = I830PTR(pScrn); CARD32 pp_status; - CARD32 blc_pwm_ctl; - int backlight_duty_cycle; - - blc_pwm_ctl = INREG (BLC_PWM_CTL); - backlight_duty_cycle = blc_pwm_ctl & BACKLIGHT_DUTY_CYCLE_MASK; - if (backlight_duty_cycle) - pI830->backlight_duty_cycle = backlight_duty_cycle; if (on) { OUTREG(PP_CONTROL, INREG(PP_CONTROL) | POWER_TARGET_ON); do { pp_status = INREG(PP_STATUS); } while ((pp_status & PP_ON) == 0); - OUTREG(BLC_PWM_CTL, - (blc_pwm_ctl & ~BACKLIGHT_DUTY_CYCLE_MASK) | - pI830->backlight_duty_cycle); + + i830_lvds_set_backlight(pScrn, pI830->backlight_duty_cycle); } else { - OUTREG(BLC_PWM_CTL, - (blc_pwm_ctl & ~BACKLIGHT_DUTY_CYCLE_MASK)); + i830_lvds_set_backlight(pScrn, 0); OUTREG(PP_CONTROL, INREG(PP_CONTROL) & ~POWER_TARGET_ON); do { @@ -99,11 +118,8 @@ i830_lvds_save (xf86OutputPtr output) /* * If the light is off at server startup, just make it full brightness */ - if (pI830->backlight_duty_cycle == 0) { - pI830->backlight_duty_cycle = - (pI830->saveBLC_PWM_CTL & BACKLIGHT_MODULATION_FREQ_MASK) >> - BACKLIGHT_MODULATION_FREQ_SHIFT; - } + if (pI830->backlight_duty_cycle == 0) + pI830->backlight_duty_cycle = i830_lvds_get_max_backlight(pScrn); } static void @@ -294,7 +310,80 @@ i830_lvds_destroy (xf86OutputPtr output) xfree (intel_output); } +#ifdef RANDR_12_INTERFACE +#define BACKLIGHT_NAME "BACKLIGHT" +static Atom backlight_atom; +#endif /* RANDR_12_INTERFACE */ + +static void +i830_lvds_create_resources(xf86OutputPtr output) +{ +#ifdef RANDR_12_INTERFACE + ScrnInfoPtr pScrn = output->scrn; + I830Ptr pI830 = I830PTR(pScrn); + INT32 range[2]; + int data, err; + + /* Set up the backlight property, which takes effect immediately + * and accepts values only within the range. + * + * XXX: Currently, RandR doesn't verify that properties set are + * within the range. + */ + backlight_atom = MakeAtom(BACKLIGHT_NAME, sizeof(BACKLIGHT_NAME) - 1, + TRUE); + + range[0] = 0; + range[1] = i830_lvds_get_max_backlight(pScrn); + err = RRConfigureOutputProperty(output->randr_output, backlight_atom, + FALSE, TRUE, FALSE, 2, range); + if (err != 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "RRConfigureOutputProperty error, %d\n", err); + } + /* Set the current value of the backlight property */ + data = pI830->backlight_duty_cycle; + err = RRChangeOutputProperty(output->randr_output, backlight_atom, + XA_INTEGER, 32, PropModeReplace, 4, &data, + FALSE); + if (err != 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "RRChangeOutputProperty error, %d\n", err); + } + +#endif /* RANDR_12_INTERFACE */ +} + +static Bool +i830_lvds_set_property(xf86OutputPtr output, Atom property, + RRPropertyValuePtr value) +{ + ScrnInfoPtr pScrn = output->scrn; + I830Ptr pI830 = I830PTR(pScrn); + + if (property == backlight_atom) { + INT32 val; + + if (value->type != XA_INTEGER || value->format != 32 || + value->size != 1) + { + return FALSE; + } + + val = *(INT32 *)value->data; + if (val < 0 || val > i830_lvds_get_max_backlight(pScrn)) + return FALSE; + + i830_lvds_set_backlight(pScrn, val); + pI830->backlight_duty_cycle = val; + return TRUE; + } + + return TRUE; +} + static const xf86OutputFuncsRec i830_lvds_output_funcs = { + .create_resources = i830_lvds_create_resources, .dpms = i830_lvds_dpms, .save = i830_lvds_save, .restore = i830_lvds_restore, @@ -303,6 +392,7 @@ static const xf86OutputFuncsRec i830_lvds_output_funcs = { .mode_set = i830_lvds_mode_set, .detect = i830_lvds_detect, .get_modes = i830_lvds_get_modes, + .set_property = i830_lvds_set_property, .destroy = i830_lvds_destroy }; diff --git a/src/i830_randr.c b/src/i830_randr.c index 18f84c49..63888494 100644 --- a/src/i830_randr.c +++ b/src/i830_randr.c @@ -672,6 +672,23 @@ xf86RandR12CrtcSetGamma (ScreenPtr pScreen, return TRUE; } +static Bool +xf86RandR12OutputSetProperty (ScreenPtr pScreen, + RROutputPtr randr_output, + Atom property, + RRPropertyValuePtr value) +{ + xf86OutputPtr output = randr_output->devPrivate; + + /* If we don't have any property handler, then we don't care what the + * user is setting properties to. + */ + if (output->funcs->set_property == NULL) + return TRUE; + + return output->funcs->set_property(output, property, value); +} + /** * Given a list of xf86 modes and a RandR Output object, construct * RandR modes and assign them to the output @@ -861,6 +878,9 @@ xf86RandR12CreateObjects12 (ScreenPtr pScreen) strlen (output->name), output); RROutputAttachScreen (output->randr_output, pScreen); + + if (output->funcs->create_resources != NULL) + output->funcs->create_resources(output); } return TRUE; } @@ -897,6 +917,7 @@ xf86RandR12Init12 (ScreenPtr pScreen) rp->rrScreenSetSize = xf86RandR12ScreenSetSize; rp->rrCrtcSet = xf86RandR12CrtcSet; rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma; + rp->rrOutputSetProperty = xf86RandR12OutputSetProperty; rp->rrSetConfig = NULL; pScrn->PointerMoved = xf86RandR12PointerMoved; if (!xf86RandR12CreateObjects12 (pScreen)) diff --git a/src/i830_xf86Crtc.h b/src/i830_xf86Crtc.h index 8fea162e..b5f2fc20 100644 --- a/src/i830_xf86Crtc.h +++ b/src/i830_xf86Crtc.h @@ -170,6 +170,13 @@ struct _xf86Crtc { }; typedef struct _xf86OutputFuncs { + /** + * Called to allow the output a chance to create properties after the + * RandR objects have been created. + */ + void + (*create_resources)(xf86OutputPtr output); + /** * Turns the output on/off, or sets intermediate power levels if available. * @@ -245,6 +252,14 @@ typedef struct _xf86OutputFuncs { DisplayModePtr (*get_modes)(xf86OutputPtr output); + /** + * Callback when an output's property has changed. + */ + Bool + (*set_property)(xf86OutputPtr output, + Atom property, + RRPropertyValuePtr value); + /** * Clean up driver-specific bits of the output */ From 3094100cdd04560af1b098bbe8024ae5270a10f4 Mon Sep 17 00:00:00 2001 From: Gary Wong Date: Tue, 16 Jan 2007 13:25:24 -0800 Subject: [PATCH 10/14] Bug #9550: Add a quirk for too-high clock from EDID on the EN-7100e. --- src/i830_edid_modes.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/i830_edid_modes.c b/src/i830_edid_modes.c index 249f87a9..1bab4cd8 100644 --- a/src/i830_edid_modes.c +++ b/src/i830_edid_modes.c @@ -52,6 +52,8 @@ typedef enum { DDC_QUIRK_DT_SYNC_HM_VP = 1 << 0, /* First detailed mode is bogus, prefer largest mode at 60hz */ DDC_QUIRK_PREFER_LARGE_60 = 1 << 1, + /* 135MHz clock is too high, drop a bit */ + DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 2 } ddc_quirk_t; static Bool quirk_dt_sync_hm_vp (int scrnIndex, xf86MonPtr DDC) @@ -78,6 +80,16 @@ static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC) return FALSE; } +static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC) +{ + /* Envision Peripherals, Inc. EN-7100e. See bug #9550. */ + if (memcmp (DDC->vendor.name, "EPI", 4) == 0 && + DDC->vendor.prod_id == 59264) + return TRUE; + + return FALSE; +} + typedef struct { Bool (*detect) (int scrnIndex, xf86MonPtr DDC); ddc_quirk_t quirk; @@ -93,6 +105,10 @@ static const ddc_quirk_map_t ddc_quirks[] = { quirk_prefer_large_60, DDC_QUIRK_PREFER_LARGE_60, "Detailed timing is not preferred, use largest mode at 60Hz" }, + { + quirk_135_clock_too_high, DDC_QUIRK_135_CLOCK_TOO_HIGH, + "Recommended 135MHz pixel clock is too high" + }, { NULL, DDC_QUIRK_NONE, "No known quirks" @@ -197,7 +213,11 @@ DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing, if (preferred) Mode->type |= M_T_PREFERRED; - Mode->Clock = timing->clock / 1000.0; + if( ( quirks & DDC_QUIRK_135_CLOCK_TOO_HIGH ) && + timing->clock == 135000000 ) + Mode->Clock = 108880; + else + Mode->Clock = timing->clock / 1000.0; Mode->HDisplay = timing->h_active; Mode->HSyncStart = timing->h_active + timing->h_sync_off; From 7161e824e89a6a69f1277e510f2344ad31721f62 Mon Sep 17 00:00:00 2001 From: Wang Zhenyu Date: Fri, 19 Jan 2007 15:15:19 +0800 Subject: [PATCH 11/14] Fix DRI issue when EXA enabled tell DRI we are smashing the context state. --- src/i965_exa_render.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/i965_exa_render.c b/src/i965_exa_render.c index dc3d7bfe..572efd65 100644 --- a/src/i965_exa_render.c +++ b/src/i965_exa_render.c @@ -369,6 +369,16 @@ I965EXAPrepareComposite(int op, PicturePtr pSrcPicture, CARD32 mask_offset = 0, mask_pitch = 0; CARD32 dst_format, dst_offset, dst_pitch; +#ifdef XF86DRI + if (pI830->directRenderingEnabled) { + drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); + + pSAREAPriv->ctxOwner = DRIGetContext(pScrn->pScreen); + } +#endif + + pI830->last_3d = LAST_3D_RENDER; + src_offset = exaGetPixmapOffset(pSrc); src_pitch = exaGetPixmapPitch(pSrc); dst_offset = exaGetPixmapOffset(pDst); From 8eb861fb61fda78e6c142ffa66c586357aaa2e44 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 22 Jan 2007 15:50:14 +0800 Subject: [PATCH 12/14] Replace the custom SaveScreen function with a generic function calling DPMS. With this, additional power saving occurs with the core screensaver, for example by turning off LVDS backlight. --- src/i830_driver.c | 54 +-------------------------------------------- src/i830_xf86Crtc.c | 22 ++++++++++++++++++ src/i830_xf86Crtc.h | 3 +++ 3 files changed, 26 insertions(+), 53 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 20781aa0..43f47252 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -316,7 +316,6 @@ const char *i830_output_type_names[] = { static void i830AdjustFrame(int scrnIndex, int x, int y, int flags); static Bool I830CloseScreen(int scrnIndex, ScreenPtr pScreen); -static Bool I830SaveScreen(ScreenPtr pScreen, int unblack); static Bool I830EnterVT(int scrnIndex, int flags); static CARD32 I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg); static Bool SaveHWState(ScrnInfoPtr pScrn); @@ -2891,7 +2890,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Not available\n"); #endif - pScreen->SaveScreen = I830SaveScreen; + pScreen->SaveScreen = xf86SaveScreen; pI830->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = I830CloseScreen; @@ -3262,57 +3261,6 @@ I830SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) return ret; } -static Bool -I830SaveScreen(ScreenPtr pScreen, int mode) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); - Bool on = xf86IsUnblank(mode); - CARD32 temp, ctrl, base, surf; - int i; - - DPRINTF(PFX, "I830SaveScreen: %d, on is %s\n", mode, BOOLTOSTRING(on)); - - if (pScrn->vtSema) { - for (i = 0; i < xf86_config->num_crtc; i++) { - if (i == 0) { - ctrl = DSPACNTR; - base = DSPABASE; - surf = DSPASURF; - } else { - ctrl = DSPBCNTR; - base = DSPBADDR; - surf = DSPBSURF; - } - if (xf86_config->crtc[i]->enabled) { - temp = INREG(ctrl); - if (on) - temp |= DISPLAY_PLANE_ENABLE; - else - temp &= ~DISPLAY_PLANE_ENABLE; - OUTREG(ctrl, temp); - /* Flush changes */ - temp = INREG(base); - OUTREG(base, temp); - if (IS_I965G(pI830)) { - temp = INREG(surf); - OUTREG(surf, temp); - } - } - } - - if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) { - if (on) - pI830->CursorInfoRec->ShowCursor(pScrn); - else - pI830->CursorInfoRec->HideCursor(pScrn); - pI830->cursorOn = TRUE; - } - } - return TRUE; -} - static Bool I830CloseScreen(int scrnIndex, ScreenPtr pScreen) { diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c index ceb8f2ef..34fa7369 100644 --- a/src/i830_xf86Crtc.c +++ b/src/i830_xf86Crtc.c @@ -1237,6 +1237,9 @@ xf86DPMSSet(ScrnInfoPtr pScrn, int mode, int flags) xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); int i; + if (!pScrn->vtSema) + return; + if (mode == DPMSModeOff) { for (i = 0; i < config->num_output; i++) { xf86OutputPtr output = config->output[i]; @@ -1260,6 +1263,25 @@ xf86DPMSSet(ScrnInfoPtr pScrn, int mode, int flags) } } +/** + * Implement the screensaver by just calling down into the driver DPMS hooks. + * + * Even for monitors with no DPMS support, by the definition of our DPMS hooks, + * the outputs will still get disabled (blanked). + */ +Bool +xf86SaveScreen(ScreenPtr pScreen, int mode) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + if (xf86IsUnblank(mode)) + xf86DPMSSet(pScrn, DPMSModeOn, 0); + else + xf86DPMSSet(pScrn, DPMSModeOff, 0); + + return TRUE; +} + #ifdef RANDR_12_INTERFACE #define EDID_ATOM_NAME "EDID_DATA" diff --git a/src/i830_xf86Crtc.h b/src/i830_xf86Crtc.h index b5f2fc20..04374b7d 100644 --- a/src/i830_xf86Crtc.h +++ b/src/i830_xf86Crtc.h @@ -452,6 +452,9 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn); void xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags); +Bool +xf86SaveScreen(ScreenPtr pScreen, int mode); + /** * Set the EDID information for the specified output */ From c68dae2705d6e5b05dba7d40b6da112b98b926b4 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 21 Jan 2007 20:22:39 +1100 Subject: [PATCH 13/14] fix building with 7.1 server by hiding stuff inside RANDR_12_INTERFACE --- src/i830_lvds.c | 4 ++++ src/i830_xf86Crtc.h | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/i830_lvds.c b/src/i830_lvds.c index 223c6ab9..0092dedb 100644 --- a/src/i830_lvds.c +++ b/src/i830_lvds.c @@ -354,6 +354,7 @@ i830_lvds_create_resources(xf86OutputPtr output) #endif /* RANDR_12_INTERFACE */ } +#ifdef RANDR_12_INTERFACE static Bool i830_lvds_set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value) @@ -381,6 +382,7 @@ i830_lvds_set_property(xf86OutputPtr output, Atom property, return TRUE; } +#endif /* RANDR_12_INTERFACE */ static const xf86OutputFuncsRec i830_lvds_output_funcs = { .create_resources = i830_lvds_create_resources, @@ -392,7 +394,9 @@ static const xf86OutputFuncsRec i830_lvds_output_funcs = { .mode_set = i830_lvds_mode_set, .detect = i830_lvds_detect, .get_modes = i830_lvds_get_modes, +#ifdef RANDR_12_INTERFACE .set_property = i830_lvds_set_property, +#endif .destroy = i830_lvds_destroy }; diff --git a/src/i830_xf86Crtc.h b/src/i830_xf86Crtc.h index 04374b7d..f8b561a2 100644 --- a/src/i830_xf86Crtc.h +++ b/src/i830_xf86Crtc.h @@ -252,6 +252,7 @@ typedef struct _xf86OutputFuncs { DisplayModePtr (*get_modes)(xf86OutputPtr output); +#ifdef RANDR_12_INTERFACE /** * Callback when an output's property has changed. */ @@ -259,7 +260,7 @@ typedef struct _xf86OutputFuncs { (*set_property)(xf86OutputPtr output, Atom property, RRPropertyValuePtr value); - +#endif /** * Clean up driver-specific bits of the output */ From effe579e691b044e3ce59b41b5c0eaaac4368dda Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 21 Jan 2007 20:23:13 +1100 Subject: [PATCH 14/14] ch7xxx: fix output detection as per datasheet, have no DVI to test this. --- src/ch7xxx/ch7xxx.c | 8 +++++++- src/ch7xxx/ch7xxx_reg.h | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c index 5bfb7c5b..9e2a0055 100644 --- a/src/ch7xxx/ch7xxx.c +++ b/src/ch7xxx/ch7xxx.c @@ -182,7 +182,13 @@ out: static xf86OutputStatus ch7xxx_detect(I2CDevPtr d) { - return XF86OutputStatusUnknown; + struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; + CARD8 cdet; + ch7xxx_read(dev_priv, CH7xxx_CONNECTION_DETECT, &cdet); + + if (cdet & CH7xxx_CDET_DVI) + return XF86OutputStatusConnected; + return XF86OutputStatusDisconnected; } static ModeStatus diff --git a/src/ch7xxx/ch7xxx_reg.h b/src/ch7xxx/ch7xxx_reg.h index c626e1fc..0ec84ea9 100644 --- a/src/ch7xxx/ch7xxx_reg.h +++ b/src/ch7xxx/ch7xxx_reg.h @@ -49,7 +49,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define CH7xxx_IDF_HSP (1<<3) #define CH7xxx_IDF_VSP (1<<4) -#define CH7301_CONNECTION_DETECT 0x20 +#define CH7xxx_CONNECTION_DETECT 0x20 +#define CH7xxx_CDET_DVI (1<<5) + #define CH7301_DAC_CNTL 0x21 #define CH7301_HOTPLUG 0x23 #define CH7xxx_TCTL 0x31