From 740a73dad1d9a9b0ebf1cc7d6f2a056abad57aaf Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Tue, 20 May 2008 08:54:01 +0800 Subject: [PATCH 01/23] Revert "Add FIFO watermark regs to register dumper" This reverts commit 0c00a638ef57aa9d6a3047176b0bfad733f781f0. Those FIFO watermark regs are 945-ish, and cause problem on G35. --- src/i810_reg.h | 1 - src/i830_debug.c | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/i810_reg.h b/src/i810_reg.h index bc42a4fa..860d1dbe 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -527,7 +527,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define FWATER_BLC 0x20d8 #define FWATER_BLC2 0x20dc -#define FWATER_BLC_SELF 0x20e0 #define MM_BURST_LENGTH 0x00700000 #define MM_FIFO_WATERMARK 0x0001F000 #define LM_BURST_LENGTH 0x00000700 diff --git a/src/i830_debug.c b/src/i830_debug.c index b9f64bf6..074e8b9c 100644 --- a/src/i830_debug.c +++ b/src/i830_debug.c @@ -546,10 +546,6 @@ static struct i830SnapshotRec { DEFINEREG(FBC_FENCE_OFF), DEFINEREG(FBC_MOD_NUM), - DEFINEREG(FWATER_BLC), - DEFINEREG(FWATER_BLC2), - DEFINEREG(FWATER_BLC_SELF), - DEFINEREG2(FPA0, i830_debug_fp), DEFINEREG2(FPA1, i830_debug_fp), DEFINEREG2(DPLL_A, i830_debug_dpll), From 71180653825a1b141a08590e4b767d33d9b5d8c1 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 21 May 2008 11:51:55 -0700 Subject: [PATCH 02/23] Revert "Disable FBC by default on 965GM" This reverts commit 53e3693ef13f31f3fc33bcff7286ab2b03b2d430. Conflicts: src/i830_driver.c - default FBC on for 965+ --- src/i830_driver.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 662b3e43..8d993bac 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2762,8 +2762,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } /* Enable FB compression if possible */ - if (i830_fb_compression_supported(pI830) && !IS_I965GM(pI830) - && !IS_IGD_GM(pI830)) + if (i830_fb_compression_supported(pI830)) pI830->fb_compression = TRUE; else pI830->fb_compression = FALSE; From 165c0865d849b7d280a3a119fe9ae0ad34637df0 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Wed, 21 May 2008 14:56:27 -0700 Subject: [PATCH 03/23] Define DEFFILEMODE for OS'es that don't have it --- src/bios_reader/bios_dumper.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bios_reader/bios_dumper.c b/src/bios_reader/bios_dumper.c index e2f3064e..1353edaa 100644 --- a/src/bios_reader/bios_dumper.c +++ b/src/bios_reader/bios_dumper.c @@ -36,6 +36,10 @@ #include #include +#ifndef DEFFILEMODE +#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) /* 0666*/ +#endif + static void usage(void) { fprintf(stderr, "usage: bios_dumper \n"); From 89bb53cc7a853d88fc34a0ca65ae2b6227a8dd24 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 26 May 2008 09:34:34 -0700 Subject: [PATCH 04/23] Fixup power saving registers Update clock gating disable bits to match docs and allocate a power context memory area so that newer chips can save state and power down the render unit. --- src/i810_reg.h | 3 +++ src/i830.h | 3 +++ src/i830_driver.c | 63 ++++++++++++++++++++++++++++++++++------------- src/i830_memory.c | 18 ++++++++++++++ 4 files changed, 70 insertions(+), 17 deletions(-) diff --git a/src/i810_reg.h b/src/i810_reg.h index 860d1dbe..a357d190 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -490,6 +490,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - new bits for i810 * - new register hwstam (mask) */ +#define PWRCTXA 0x2088 /* 965GM+ only */ +#define PWRCTX_EN (1<<0) #define HWSTAM 0x2098 /* p290 */ #define IER 0x20a0 /* p291 */ #define IIR 0x20a4 /* p292 */ @@ -1150,6 +1152,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define RENCLK_GATE_D2 0x6208 #define RAMCLK_GATE_D 0x6210 /* CRL only */ +#define DEUC 0x6214 /* CRL only */ /* * This is a PCI config space register to manipulate backlight brightness diff --git a/src/i830.h b/src/i830.h index 9d0f727c..82901978 100644 --- a/src/i830.h +++ b/src/i830.h @@ -426,6 +426,8 @@ typedef struct _I830Rec { i830_memory *logical_context; + i830_memory *power_context; + #ifdef XF86DRI i830_memory *back_buffer; i830_memory *third_buffer; @@ -773,6 +775,7 @@ void i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem); extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn); Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn); Bool i830_allocate_texture_memory(ScrnInfoPtr pScrn); +Bool i830_allocate_pwrctx(ScrnInfoPtr pScrn); Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn); #ifdef INTEL_XVMC Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, diff --git a/src/i830_driver.c b/src/i830_driver.c index 8d993bac..df9d7299 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -934,6 +934,40 @@ I830SetupOutputs(ScrnInfoPtr pScrn) } } +static void +i830_init_clock_gating(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + /* Disable clock gating reported to work incorrectly according to the specs. + */ + if (IS_IGD_GM(pI830)) { + OUTREG(RENCLK_GATE_D1, 0); + OUTREG(RENCLK_GATE_D2, 0); + OUTREG(RAMCLK_GATE_D, 0); + OUTREG(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE | + OVRUNIT_CLOCK_GATE_DISABLE | + OVCUNIT_CLOCK_GATE_DISABLE); + } else if (IS_I965GM(pI830)) { + OUTREG(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); + OUTREG(RENCLK_GATE_D2, 0); + OUTREG(DSPCLK_GATE_D, 0); + OUTREG(RAMCLK_GATE_D, 0); + OUTREG16(DEUC, 0); + } else if (IS_I965G(pI830)) { + OUTREG(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | + I965_RCC_CLOCK_GATE_DISABLE | + I965_RCPB_CLOCK_GATE_DISABLE | + I965_ISC_CLOCK_GATE_DISABLE | + I965_FBC_CLOCK_GATE_DISABLE); + OUTREG(RENCLK_GATE_D2, 0); + } else if (IS_I855(pI830) || IS_I865G(pI830)) { + OUTREG(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); + } else if (IS_I830(pI830)) { + OUTREG(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); + } +} + static int I830LVDSPresent(ScrnInfoPtr pScrn) { @@ -1461,6 +1495,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) i830TakeRegSnapshot(pScrn); + i830_init_clock_gating(pScrn); + #if 1 pI830->saveSWF0 = INREG(SWF0); pI830->saveSWF4 = INREG(SWF4); @@ -1901,23 +1937,6 @@ SetHWOperatingState(ScrnInfoPtr pScrn) DPRINTF(PFX, "SetHWOperatingState\n"); - /* Disable clock gating reported to work incorrectly according to the specs. - */ - if (IS_IGD_GM(pI830)) { - OUTREG(RENCLK_GATE_D1, 0); - OUTREG(RENCLK_GATE_D2, 0); - OUTREG(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); - } else if (IS_I965GM(pI830)) { - OUTREG(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); - } else if (IS_I965G(pI830)) { - OUTREG(RENCLK_GATE_D1, - I965_RCC_CLOCK_GATE_DISABLE | I965_ISC_CLOCK_GATE_DISABLE); - } else if (IS_I855(pI830) || IS_I865G(pI830)) { - OUTREG(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); - } else if (IS_I830(pI830)) { - OUTREG(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); - } - i830_start_ring(pScrn); if (!pI830->SWCursor) I830InitHWCursor(pScrn); @@ -2504,6 +2523,10 @@ i830_try_memory_allocation(ScrnInfoPtr pScrn) if (!i830_allocate_2d_memory(pScrn)) goto failed; + if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) + if (!i830_allocate_pwrctx(pScrn)) + goto failed; + if (dri && !i830_allocate_3d_memory(pScrn)) goto failed; @@ -2824,6 +2847,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; } + if (pI830->power_context) + OUTREG(PWRCTXA, pI830->power_context->offset | PWRCTX_EN); + I830UnmapMMIO(pScrn); i830_fixup_mtrrs(pScrn); @@ -3453,6 +3479,9 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen) } #endif + if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) + OUTREG(PWRCTXA, 0); + if (I830IsPrimary(pScrn)) { xf86GARTCloseScreen(scrnIndex); diff --git a/src/i830_memory.c b/src/i830_memory.c index 84db0ef1..02b16794 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -112,6 +112,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* Our hardware status area is just a single page */ #define HWSTATUS_PAGE_SIZE GTT_PAGE_SIZE +#define PWRCTX_SIZE GTT_PAGE_SIZE static i830_memory * i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name, @@ -337,6 +338,7 @@ i830_reset_allocations(ScrnInfoPtr pScrn) pI830->gen4_render_state_mem = NULL; pI830->overlay_regs = NULL; pI830->logical_context = NULL; + pI830->power_context = NULL; #ifdef XF86DRI pI830->back_buffer = NULL; pI830->third_buffer = NULL; @@ -1656,6 +1658,22 @@ i830_allocate_hwstatus(ScrnInfoPtr pScrn) return TRUE; } +Bool +i830_allocate_pwrctx(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + pI830->power_context = i830_allocate_memory(pScrn, "power context", + PWRCTX_SIZE, GTT_PAGE_SIZE, + NEED_LIFETIME_FIXED); + if (!pI830->power_context) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate power context.\n"); + return FALSE; + } + return TRUE; +} + Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn) { From 2e1425246ccc75216247b0c2fa6fce2635db472b Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 26 May 2008 09:40:10 -0700 Subject: [PATCH 05/23] Handle display FIFOs better Add some debug code to catch FIFO underruns, which are normally bugs (unless they occur during mode setting) and remove any plane C FIFO allocations, since we don't use that plane at all. We may eventually need to be a little smarter about this on platforms that use plane C for the popup. --- src/i810_reg.h | 2 ++ src/i830_display.c | 4 ++++ src/i830_driver.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/src/i810_reg.h b/src/i810_reg.h index a357d190..d97780f0 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -2103,6 +2103,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DSPARB 0x70030 +#define DSPARB_CSTART_SHIFT 7 +#define DSPARB_BSTART_SHIFT 0 #define DSPFW1 0x70034 #define DSPFW2 0x70038 #define DSPFW3 0x7003c diff --git a/src/i830_display.c b/src/i830_display.c index 1122721a..2d2d072a 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -1077,6 +1077,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, int dspstride_reg = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE; int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS; int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE; + int pipestat_reg = (pipe == 0) ? PIPEASTAT : PIPEBSTAT; int i; int refclk; intel_clock_t clock; @@ -1376,6 +1377,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, #endif i830WaitForVblank(pScrn); + + /* Clear any FIFO underrun status that may have occurred normally */ + OUTREG(pipestat_reg, INREG(pipestat_reg) | FIFO_UNDERRUN); } diff --git a/src/i830_driver.c b/src/i830_driver.c index df9d7299..0a8ec564 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1934,12 +1934,36 @@ static void SetHWOperatingState(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; DPRINTF(PFX, "SetHWOperatingState\n"); + /* + * Disable outputs & pipes since some of these regs can only be updated + * when they're off. + */ + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + output->funcs->dpms(output, DPMSModeOff); + } + i830WaitForVblank(pScrn); + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + crtc->funcs->dpms(crtc, DPMSModeOff); + } + i830WaitForVblank(pScrn); + i830_start_ring(pScrn); if (!pI830->SWCursor) I830InitHWCursor(pScrn); + + /* + * Fixup FIFO defaults: + * we don't use plane C at all so we can allocate the 96 FIFO RAM + * entries equally between planes A and B. + */ + OUTREG(DSPARB, (95 << DSPARB_CSTART_SHIFT) | (48 << DSPARB_BSTART_SHIFT)); } enum pipe { @@ -2313,6 +2337,10 @@ RestoreHWState(ScrnInfoPtr pScrn) OUTREG(FBC_CONTROL, pI830->saveFBC_CONTROL); } + /* Clear any FIFO underrun status that may have occurred normally */ + OUTREG(PIPEASTAT, INREG(PIPEASTAT) | FIFO_UNDERRUN); + OUTREG(PIPEBSTAT, INREG(PIPEBSTAT) | FIFO_UNDERRUN); + vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS); vgaHWLock(hwp); @@ -2462,6 +2490,22 @@ I830BlockHandler(int i, if (pScrn->vtSema && !pI830->noAccel && !pI830->directRenderingEnabled) I830EmitFlush(pScrn); + /* + * Check for FIFO underruns at block time (which amounts to just + * periodically). If this happens, it means our DSPARB or some other + * memory arbitration setting is wrong for the current configuration + * (except for mode setting, where it may occur naturally). + * Check & ack the condition. + */ + if (INREG(PIPEASTAT) & FIFO_UNDERRUN) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "underrun on pipe A!\n"); + OUTREG(PIPEASTAT, INREG(PIPEASTAT) | FIFO_UNDERRUN); + } + if (INREG(PIPEBSTAT) & FIFO_UNDERRUN) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "underrun on pipe B!\n"); + OUTREG(PIPEBSTAT, INREG(PIPEBSTAT) | FIFO_UNDERRUN); + } + I830VideoBlockHandler(i, blockData, pTimeout, pReadmask); } From 363ccc3dfbf8ab91608d502e0376a43653581856 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 26 May 2008 09:43:40 -0700 Subject: [PATCH 06/23] Fixup FIFO comment What I originally checked in was a bit misleading. --- 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 0a8ec564..1b07064a 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1960,8 +1960,8 @@ SetHWOperatingState(ScrnInfoPtr pScrn) /* * Fixup FIFO defaults: - * we don't use plane C at all so we can allocate the 96 FIFO RAM - * entries equally between planes A and B. + * we don't use plane C at all so we can allocate all but one of the 96 + * FIFO RAM entries equally between planes A and B. */ OUTREG(DSPARB, (95 << DSPARB_CSTART_SHIFT) | (48 << DSPARB_BSTART_SHIFT)); } From bd137a19dc29dd466eac030e040f729ed0807e3f Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 28 May 2008 15:47:47 -0700 Subject: [PATCH 07/23] Fixup DSPARB for 855 & 945 It turns out 855 has a different DSPARB layout than 915+. And 945+ have more FIFO entries, so we have to allocate things differently. So on 855 split the FIFO evenly again between A & B planes, and do the same on 945, where we have a larger FIFO. Fixes an issue reported by Daniel Stone with the previous default value. --- src/i810_reg.h | 2 ++ src/i830_driver.c | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/i810_reg.h b/src/i810_reg.h index d97780f0..9da258a7 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -2105,6 +2105,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DSPARB 0x70030 #define DSPARB_CSTART_SHIFT 7 #define DSPARB_BSTART_SHIFT 0 +#define DSPARB_BEND_SHIFT 9 /* on 855 */ +#define DSPARB_AEND_SHIFT 0 #define DSPFW1 0x70034 #define DSPFW2 0x70038 #define DSPFW3 0x7003c diff --git a/src/i830_driver.c b/src/i830_driver.c index 1b07064a..1041fe3b 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1963,7 +1963,16 @@ SetHWOperatingState(ScrnInfoPtr pScrn) * we don't use plane C at all so we can allocate all but one of the 96 * FIFO RAM entries equally between planes A and B. */ - OUTREG(DSPARB, (95 << DSPARB_CSTART_SHIFT) | (48 << DSPARB_BSTART_SHIFT)); + if (IS_I9XX(pI830)) { + if (IS_I915GM(pI830) || IS_I915G(pI830)) + OUTREG(DSPARB, (95 << DSPARB_CSTART_SHIFT) | + (48 << DSPARB_BSTART_SHIFT)); + else + OUTREG(DSPARB, (127 << DSPARB_CSTART_SHIFT) | + (64 << DSPARB_BSTART_SHIFT)); + } else { + OUTREG(DSPARB, 254 << DSPARB_BEND_SHIFT | 128 << DSPARB_AEND_SHIFT); + } } enum pipe { From 96955003557686469c7ae9f7d42620d2851e6fad Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Tue, 3 Jun 2008 16:13:52 +0800 Subject: [PATCH 08/23] xvmc: remove unused dri drawable --- src/xvmc/Makefile.am | 5 +- src/xvmc/driDrawable.c | 174 ----------------------------------------- src/xvmc/driDrawable.h | 64 --------------- src/xvmc/i915_xvmc.c | 10 --- src/xvmc/intel_xvmc.h | 1 - 5 files changed, 2 insertions(+), 252 deletions(-) delete mode 100644 src/xvmc/driDrawable.c delete mode 100644 src/xvmc/driDrawable.h diff --git a/src/xvmc/Makefile.am b/src/xvmc/Makefile.am index f571743f..f2dab22c 100644 --- a/src/xvmc/Makefile.am +++ b/src/xvmc/Makefile.am @@ -19,9 +19,8 @@ libIntelXvMC_la_SOURCES = intel_xvmc.c \ intel_batchbuffer.h \ xf86dri.c \ xf86dri.h \ - xf86dristr.h \ - driDrawable.c \ - driDrawable.h + xf86dristr.h + libIntelXvMC_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ @XVMCLIB_CFLAGS@ -I$(top_srcdir)/src -DTRUE=1 -DFALSE=0 libIntelXvMC_la_LDFLAGS = -version-number 1:0:0 libIntelXvMC_la_LIBADD = @DRI_LIBS@ diff --git a/src/xvmc/driDrawable.c b/src/xvmc/driDrawable.c deleted file mode 100644 index 83863347..00000000 --- a/src/xvmc/driDrawable.c +++ /dev/null @@ -1,174 +0,0 @@ -/***************************************************************************** - * driDrawable.c: Lean Version of DRI utilities. - * - * Copyright (c) 2005 Thomas Hellstrom. All rights reserved. - * - * 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 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 - * AUTHOR(S) OR COPYRIGHT HOLDER(S) 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. - */ - - -#include -#include -#include "xf86drm.h" -#include "drm.h" -#include "xf86dri.h" -#include "drm_sarea.h" -#include "driDrawable.h" - -static unsigned -drawStamp(volatile drm_sarea_t * pSarea, int index) -{ - return pSarea->drawableTable[index].stamp; -} - -int -getDRIDrawableInfoLocked(void *drawHash, Display * display, int screen, - Drawable draw, unsigned lockFlags, int drmFD, drm_context_t drmContext, - drmAddress sarea, Bool updateInfo, drawableInfo ** info, - unsigned long infoSize) -{ - drawableInfo *drawInfo; - void *res; - drm_drawable_t drmDraw = 0; - volatile drm_sarea_t *pSarea = (drm_sarea_t *) sarea; - drm_clip_rect_t *clipFront, *clipBack; - - int ret; - - if (drmHashLookup(drawHash, (unsigned long)draw, &res)) { - - /* - * The drawable is unknown to us. Create it and put it in the - * hash table. - */ - - DRM_UNLOCK(drmFD, &pSarea->lock, drmContext); - if (!uniDRICreateDrawable(display, screen, draw, &drmDraw)) { - DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags); - return 1; - } - DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags); - - drawInfo = (drawableInfo *) malloc(infoSize); - if (!drawInfo) - return 1; - - drawInfo->drmDraw = drmDraw; - drawInfo->stamp = 0; - drawInfo->clipFront = 0; - drawInfo->clipBack = 0; - - drmHashInsert(drawHash, (unsigned long)draw, drawInfo); - - } else { - drawInfo = res; - } - - drawInfo->touched = FALSE; - while (!drawInfo->clipFront - || drawInfo->stamp != drawStamp(pSarea, drawInfo->index)) { - - /* - * The drawable has been touched since we last got info about it. - * obtain new info from the X server. - */ - - drawInfo->touched = TRUE; - - if (updateInfo || !drawInfo->clipFront) { - DRM_UNLOCK(drmFD, &pSarea->lock, drmContext); - - ret = uniDRIGetDrawableInfo(display, screen, draw, - &drawInfo->index, &drawInfo->stamp, &drawInfo->x, - &drawInfo->y, &drawInfo->w, &drawInfo->h, - &drawInfo->numClipFront, &clipFront, - &drawInfo->backX, &drawInfo->backY, - &drawInfo->numClipBack, &clipBack); - - DRM_LIGHT_LOCK(drmFD, &pSarea->lock, drmContext); - - /* - * Error. Probably the drawable is destroyed. Return error and old values. - */ - - if (!ret) { - free(drawInfo); - drawInfo = NULL; - drmHashDelete(drawHash, (unsigned long)draw); - - DRM_UNLOCK(drmFD, &pSarea->lock, drmContext); - uniDRIDestroyDrawable(display, screen, draw); - DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags); - - return 1; - } - - if (drawInfo->stamp != drawStamp(pSarea, drawInfo->index)) { - - /* - * The info is already outdated. Sigh. Have another go. - */ - - XFree(clipFront); - XFree(clipBack); - continue; - } - - if (drawInfo->clipFront) - XFree(drawInfo->clipFront); - drawInfo->clipFront = clipFront; - if (drawInfo->clipBack) - XFree(drawInfo->clipBack); - drawInfo->clipBack = clipBack; - } else { - if (!drawInfo->clipFront) - drawInfo->clipFront = (drm_clip_rect_t *) ~ 0UL; - drawInfo->stamp = drawStamp(pSarea, drawInfo->index); - } - } - *info = drawInfo; - return 0; -} - -void -driDestroyHashContents(void *drawHash) -{ - unsigned long key; - void *content; - drawableInfo *drawInfo; - - if (drmHashFirst(drawHash, &key, &content) < 1) - return; - drawInfo = (drawableInfo *) content; - if (drawInfo->clipBack) - XFree(drawInfo->clipBack); - if (drawInfo->clipFront) - XFree(drawInfo->clipFront); - free(drawInfo); - while (drmHashNext(drawHash, &key, &content) == 1) { - drawInfo = (drawableInfo *) content; - if (drawInfo->clipBack) - XFree(drawInfo->clipBack); - if (drawInfo->clipFront) - XFree(drawInfo->clipFront); - free(drawInfo); - } - - return; -} diff --git a/src/xvmc/driDrawable.h b/src/xvmc/driDrawable.h deleted file mode 100644 index a758c7c7..00000000 --- a/src/xvmc/driDrawable.h +++ /dev/null @@ -1,64 +0,0 @@ -/***************************************************************************** - * driDrawable.h: Lean Version of DRI utilities. - * - * Copyright (c) 2005 Thomas Hellstrom. All rights reserved. - * - * 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 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 - * AUTHOR(S) OR COPYRIGHT HOLDER(S) 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. - */ - -#ifndef _DRIDRAWABLE_H -#define _DRIDRAWABLE_H - -typedef struct _drawableInfo -{ - drm_drawable_t drmDraw; - unsigned stamp; - unsigned index; - drm_clip_rect_t *clipFront; - drm_clip_rect_t *clipBack; - int x; - int y; - int w; - int h; - int backX; - int backY; - int numClipFront; - int numClipBack; - Bool touched; -} drawableInfo; - -/* - * Get updated info about the drawable "draw". The drawableInfo record returned is malloced - * and administrated internally. Never free it unless you know exactly what you are doing. - * The drm hash table "drawHash" needs to be initialized externally. - */ - -extern int -getDRIDrawableInfoLocked(void *drawHash, Display * display, int screen, - Drawable draw, unsigned lockFlags, int drmFD, drm_context_t drmContext, - drmAddress sarea, Bool updateInfo, drawableInfo ** info, - unsigned long infoSize); - -/* - * Free all resources created by the above function. Typically done on exit. - */ - -extern void driDestroyHashContents(void *drawHash); - -#endif diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c index 20b2e613..f2d8ded9 100644 --- a/src/xvmc/i915_xvmc.c +++ b/src/xvmc/i915_xvmc.c @@ -1608,9 +1608,6 @@ static void i915_release_resource(Display *display, XvMCContext *context) pI915XvMC->ref--; i915_xvmc_unmap_buffers(pI915XvMC); - driDestroyHashContents(pI915XvMC->drawHash); - drmHashDestroy(pI915XvMC->drawHash); - free(pI915XvMC); context->privData = NULL; } @@ -1683,13 +1680,6 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context pSAREA = (drm_sarea_t *)xvmc_driver->sarea_address; pI915XvMC->sarea = (drmI830Sarea*)((char*)pSAREA + pI915XvMC->sarea_priv_offset); - if (NULL == (pI915XvMC->drawHash = drmHashCreate())) { - XVMC_ERR("Could not allocate drawable hash table."); - free(pI915XvMC); - context->privData = NULL; - return BadAlloc; - } - if (i915_xvmc_map_buffers(pI915XvMC)) { i915_xvmc_unmap_buffers(pI915XvMC); free(pI915XvMC); diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h index 55066838..bc863c47 100644 --- a/src/xvmc/intel_xvmc.h +++ b/src/xvmc/intel_xvmc.h @@ -53,7 +53,6 @@ #include #include "xf86dri.h" -#include "driDrawable.h" #include "intel_batchbuffer.h" From 3cc8876db7ba82fa18e8fab4f267ac6e87964c47 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Tue, 3 Jun 2008 16:15:36 +0800 Subject: [PATCH 09/23] xvmc: a little cleanup Also safe check context size to not exceed surface max. --- src/i915_hwmc.c | 36 +++++++++++++++++++++++++----------- src/i915_hwmc.h | 2 +- src/xvmc/i915_xvmc.c | 4 ++-- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c index c3d3c755..50e11068 100644 --- a/src/i915_hwmc.c +++ b/src/i915_hwmc.c @@ -95,8 +95,6 @@ typedef struct _I915XvMC PutImageFuncPtr savePutImage; } I915XvMC, *I915XvMCPtr; -#define ARRARY_SIZE(a) (sizeof(a) / sizeof(a[0])) - /* static int yv12_subpicture_index_list[2] = { @@ -161,6 +159,22 @@ static XF86ImagePtr i915_subpicture_list[2] = }; #endif +/* Check context size not exceed surface type max */ +static void +i915_check_context_size(XvMCContextPtr ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ppSI); i++) { + if (ctx->surface_type_id == ppSI[i]->surface_type_id) { + if (ctx->width > ppSI[i]->max_width) + ctx->width = ppSI[i]->max_width; + if (ctx->height > ppSI[i]->max_height) + ctx->height = ppSI[i]->max_height; + } + } +} + /* * Init and clean up the screen private parts of XvMC. */ @@ -430,6 +444,8 @@ static int i915_xvmc_create_context (ScrnInfoPtr pScrn, XvMCContextPtr pContext, return BadAlloc; } + i915_check_context_size(pContext); + *priv = xcalloc(1, sizeof(I915XvMCCreateContextRec)); contextRec = (I915XvMCCreateContextRec *)*priv; @@ -776,10 +792,9 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn, struct intel_xvmc_command *xvmc_cmd = (struct intel_xvmc_command *)buf; int ret; - if (pI830->XvMCEnabled) { - if (FOURCC_XVMC == id) { - switch (xvmc_cmd->command) { - case INTEL_XVMC_COMMAND_DISPLAY: + if (FOURCC_XVMC == id) { + switch (xvmc_cmd->command) { + case INTEL_XVMC_COMMAND_DISPLAY: if ((xvmc_cmd->srfNo >= I915_XVMC_MAX_SURFACES) || !pXvMC->surfaces[xvmc_cmd->srfNo] || !pXvMC->sfprivs[xvmc_cmd->srfNo]) { @@ -793,10 +808,9 @@ static int i915_xvmc_put_image(ScrnInfoPtr pScrn, id = xvmc_cmd->real_id; pI830->IsXvMCSurface = 1; break; - default: - return 0; - } - } + default: + return 0; + } } ret = pXvMC->savePutImage(pScrn, src_x, src_y, drw_x, drw_y, src_w, src_h, @@ -850,7 +864,7 @@ static void i915_xvmc_fini(ScrnInfoPtr pScrn) static XF86MCAdaptorRec pAdapt = { .name = "Intel(R) Textured Video", - .num_surfaces = ARRARY_SIZE(ppSI), + .num_surfaces = ARRAY_SIZE(ppSI), .surfaces = ppSI, #if 0 .num_subpictures = ARRARY_SIZE(i915_subpicture_list), diff --git a/src/i915_hwmc.h b/src/i915_hwmc.h index 0141fb25..7d90afcc 100644 --- a/src/i915_hwmc.h +++ b/src/i915_hwmc.h @@ -32,7 +32,7 @@ #define STRIDE(w) (((w) + 0x3ff) & ~0x3ff) #define SIZE_Y420(w, h) (h * STRIDE(w)) #define SIZE_UV420(w, h) ((h >> 1) * STRIDE(w >> 1)) -#define SIZE_YUV420(w, h) (h * (STRIDE(w) + STRIDE(w >> 1))) +#define SIZE_YUV420(w, h) (SIZE_Y420(w,h) + SIZE_UV420(w,h) * 2) #define SIZE_XX44(w, h) (h * STRIDE(w)) #define I915_NUM_XVMC_ATTRIBUTES 0x02 diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c index f2d8ded9..b1a17b4e 100644 --- a/src/xvmc/i915_xvmc.c +++ b/src/xvmc/i915_xvmc.c @@ -1987,7 +1987,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context, XVMC_ERR("Invalid Macroblock Parameters found."); break; } - } else { /* Frame Picture */ + } else { /* Field Picture */ switch (mb->motion_type & 3) { case XVMC_PREDICTION_FIELD: /* Field Based */ i915_mc_mpeg_macroblock_1fbmv(context, mb); @@ -2005,7 +2005,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context, XVMC_ERR("Invalid Macroblock Parameters found."); break; } - } /* Field Picture */ + } } intelFlushBatch(TRUE); From 1729a4f29dd52346a9fa997f818d57884047657f Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Wed, 4 Jun 2008 22:25:39 +0800 Subject: [PATCH 10/23] xvmc: move block size lookup helper to generic --- src/xvmc/i915_xvmc.c | 14 +-------- src/xvmc/intel_xvmc.c | 71 +++++++++++++++++++++++++++++++++++++++++++ src/xvmc/intel_xvmc.h | 2 ++ 3 files changed, 74 insertions(+), 13 deletions(-) diff --git a/src/xvmc/i915_xvmc.c b/src/xvmc/i915_xvmc.c index b1a17b4e..519de5a3 100644 --- a/src/xvmc/i915_xvmc.c +++ b/src/xvmc/i915_xvmc.c @@ -38,18 +38,6 @@ #define VOFFSET(surface) (surface->srf.offset + \ SIZE_Y420(surface->width, surface->height)) -/* Lookup tables to speed common calculations */ -static unsigned int mb_bytes[] = { - 000, 128, 128, 256, 128, 256, 256, 384, // 0 - 128, 256, 256, 384, 256, 384, 384, 512, // 1 - 128, 256, 256, 384, 256, 384, 384, 512, // 10 - 256, 384, 384, 512, 384, 512, 512, 640, // 11 - 128, 256, 256, 384, 256, 384, 384, 512, // 100 - 256, 384, 384, 512, 384, 512, 512, 640, // 101 - 256, 384, 384, 512, 384, 512, 512, 640, // 110 - 384, 512, 512, 640, 512, 640, 640, 768 // 111 -}; - typedef union { short s[4]; uint u[2]; @@ -1931,7 +1919,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context, XVMC_INFO("no coded blocks present!"); } - bspm = mb_bytes[mb->coded_block_pattern]; + bspm = mb_bytes_420[mb->coded_block_pattern]; if (!bspm) continue; diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c index 1be8cc6b..f3a83955 100644 --- a/src/xvmc/intel_xvmc.c +++ b/src/xvmc/intel_xvmc.c @@ -26,7 +26,78 @@ */ #include "intel_xvmc.h" +/* global */ struct _intel_xvmc_driver *xvmc_driver = NULL; + +/* Lookup tables to speed common calculations for coded_block_pattern */ +/* each block is ((8*8) * sizeof(short)) */ +unsigned int mb_bytes_420[] = { + 0, /* 0 */ + 128, /* 1 */ + 128, /* 10 */ + 256, /* 11 */ + 128, /* 100 */ + 256, /* 101 */ + 256, /* 110 */ + 384, /* 111 */ + 128, /* 1000 */ + 256, /* 1001 */ + 256, /* 1010 */ + 384, /* 1011 */ + 256, /* 1100 */ + 384, /* 1101 */ + 384, /* 1110 */ + 512, /* 1111 */ + 128, /* 10000 */ + 256, /* 10001 */ + 256, /* 10010 */ + 384, /* 10011 */ + 256, /* 10100 */ + 384, /* 10101 */ + 384, /* 10110 */ + 512, /* 10111 */ + 256, /* 11000 */ + 384, /* 11001 */ + 384, /* 11010 */ + 512, /* 11011 */ + 384, /* 11100 */ + 512, /* 11101 */ + 512, /* 11110 */ + 640, /* 11111 */ + 128, /* 100000 */ + 256, /* 100001 */ + 256, /* 100010 */ + 384, /* 100011 */ + 256, /* 100100 */ + 384, /* 100101 */ + 384, /* 100110 */ + 512, /* 100111 */ + 256, /* 101000 */ + 384, /* 101001 */ + 384, /* 101010 */ + 512, /* 101011 */ + 384, /* 101100 */ + 512, /* 101101 */ + 512, /* 101110 */ + 640, /* 101111 */ + 256, /* 110000 */ + 384, /* 110001 */ + 384, /* 110010 */ + 512, /* 110011 */ + 384, /* 110100 */ + 512, /* 110101 */ + 512, /* 110110 */ + 640, /* 110111 */ + 384, /* 111000 */ + 512, /* 111001 */ + 512, /* 111010 */ + 640, /* 111011 */ + 512, /* 111100 */ + 640, /* 111101 */ + 640, /* 111110 */ + 768 /* 111111 */ +}; + static int error_base; static int event_base; diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h index bc863c47..e5e623ea 100644 --- a/src/xvmc/intel_xvmc.h +++ b/src/xvmc/intel_xvmc.h @@ -249,4 +249,6 @@ static inline const char* intel_xvmc_decoder_string(int flag) extern intel_xvmc_context_ptr intel_xvmc_find_context(XID id); extern intel_xvmc_surface_ptr intel_xvmc_find_surface(XID id); +extern unsigned int mb_bytes_420[64]; + #endif From 64ccc8a036a1d80fc918e9b124d24ce0d26bdbbb Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Wed, 4 Jun 2008 22:30:04 +0800 Subject: [PATCH 11/23] xvmc: add render dump function --- src/xvmc/Makefile.am | 1 + src/xvmc/intel_xvmc.c | 8 +++ src/xvmc/intel_xvmc.h | 9 +++ src/xvmc/intel_xvmc_dump.c | 142 +++++++++++++++++++++++++++++++++++++ 4 files changed, 160 insertions(+) create mode 100644 src/xvmc/intel_xvmc_dump.c diff --git a/src/xvmc/Makefile.am b/src/xvmc/Makefile.am index f2dab22c..345160fb 100644 --- a/src/xvmc/Makefile.am +++ b/src/xvmc/Makefile.am @@ -11,6 +11,7 @@ libI810XvMC_la_LIBADD = @DRI_LIBS@ libIntelXvMC_la_SOURCES = intel_xvmc.c \ intel_xvmc.h \ + intel_xvmc_dump.c \ i915_structs.h \ i915_program.h \ i915_xvmc.c \ diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c index f3a83955..ae357aa5 100644 --- a/src/xvmc/intel_xvmc.c +++ b/src/xvmc/intel_xvmc.c @@ -431,6 +431,8 @@ Status XvMCCreateContext(Display *display, XvPortID port, intelInitBatchBuffer(); + intel_xvmc_dump_open(); + return Success; } @@ -478,6 +480,8 @@ Status XvMCDestroyContext(Display *display, XvMCContext *context) xvmc_driver->fd = -1; intelFiniBatchBuffer(); + + intel_xvmc_dump_close(); } return Success; } @@ -666,6 +670,10 @@ Status XvMCRenderSurface(Display *display, XvMCContext *context, if (!target_surface) return XvMCBadSurface; + intel_xvmc_dump_render(context, picture_structure, target_surface, + past_surface, future_surface, flags, num_macroblocks, + first_macroblock, macroblock_array, blocks); + ret = (xvmc_driver->render_surface)(display, context, picture_structure, target_surface, past_surface, future_surface, flags, num_macroblocks, first_macroblock, macroblock_array, diff --git a/src/xvmc/intel_xvmc.h b/src/xvmc/intel_xvmc.h index e5e623ea..31196238 100644 --- a/src/xvmc/intel_xvmc.h +++ b/src/xvmc/intel_xvmc.h @@ -251,4 +251,13 @@ extern intel_xvmc_surface_ptr intel_xvmc_find_surface(XID id); extern unsigned int mb_bytes_420[64]; +/* dump function */ +extern void intel_xvmc_dump_open(void); +extern void intel_xvmc_dump_close(void); +extern void intel_xvmc_dump_render(XvMCContext *context, unsigned int picture_structure, + XvMCSurface *target_surface, XvMCSurface *past_surface, + XvMCSurface *future_surface, unsigned int flags, + unsigned int num_macroblocks, unsigned int first_macroblock, + XvMCMacroBlockArray *macroblock_array, XvMCBlockArray *blocks); + #endif diff --git a/src/xvmc/intel_xvmc_dump.c b/src/xvmc/intel_xvmc_dump.c new file mode 100644 index 00000000..12fc52a5 --- /dev/null +++ b/src/xvmc/intel_xvmc_dump.c @@ -0,0 +1,142 @@ +/* + * 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: + * Zhenyu Wang + * + */ +#include "intel_xvmc.h" + +#define DUMPFILE "./intel_xvmc_dump" + +static int xvmc_dump = 0; +static FILE *fp = NULL; + +void intel_xvmc_dump_open(void) +{ + char *d = NULL; + + if (xvmc_dump) + return; + + if (d = getenv("INTEL_XVMC_DUMP")) + xvmc_dump = 1; + + if (xvmc_dump) { + fp = fopen(DUMPFILE, "a"); + if (!fp) + xvmc_dump = 0; + } +} + +void intel_xvmc_dump_close(void) +{ + if (xvmc_dump) { + fclose(fp); + xvmc_dump = 0; + } +} + +void intel_xvmc_dump_render(XvMCContext *context, unsigned int picture_structure, + XvMCSurface *target, XvMCSurface *past, XvMCSurface *future, unsigned int flags, + unsigned int num_macroblocks, unsigned int first_macroblock, + XvMCMacroBlockArray *macroblock_array, XvMCBlockArray *blocks) +{ + int i; + XvMCMacroBlock *mb; + + if (!xvmc_dump) + return; + + fprintf(fp, "========== new surface rendering ==========\n"); + fprintf(fp, "Context (id:%d) (surface_type_id:%d) (width:%d) (height:%d)\n", + context->context_id, context->surface_type_id, context->width, context->height); + + if (picture_structure == XVMC_FRAME_PICTURE) + fprintf(fp, "picture structure: frame picture\n"); + else if (picture_structure == XVMC_TOP_FIELD) + fprintf(fp, "picture structure: top field picture (%s)\n", + (flags == XVMC_SECOND_FIELD)?"second":"first"); + else if (picture_structure == XVMC_BOTTOM_FIELD) + fprintf(fp, "picture structure: bottom field picture (%s)\n", + (flags == XVMC_SECOND_FIELD)?"second":"first"); + + if (!past && !future) + fprintf(fp, "picture type: I\n"); + else if (past && !future) + fprintf(fp, "picture type: P\n"); + else if (past && future) + fprintf(fp, "picture type: B\n"); + else + fprintf(fp, "picture type: Bad!\n"); + + fprintf(fp, "target picture: id (%d) width (%d) height (%d)\n", target->surface_id, + target->width, target->height); + if (past) + fprintf(fp, "past picture: id (%d) width (%d) height (%d)\n", past->surface_id, + past->width, past->height); + if (future) + fprintf(fp, "future picture: id (%d) width (%d) height (%d)\n", future->surface_id, + future->width, future->height); + + fprintf(fp, "num macroblocks: %d, first macroblocks %d\n", num_macroblocks, first_macroblock); + + for (i = first_macroblock; i < (first_macroblock + num_macroblocks); i++) { + mb = ¯oblock_array->macro_blocks[i]; + + fprintf(fp, "- MB(%d): ", i); + fprintf(fp, "x (%d) y (%d) ", mb->x, mb->y); + fprintf(fp, "macroblock type ("); + if (mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) + fprintf(fp, "motion_forward "); + if (mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) + fprintf(fp, "motion_backward "); + if (mb->macroblock_type & XVMC_MB_TYPE_PATTERN) + fprintf(fp, "pattern "); + if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) + fprintf(fp, "intra "); + fprintf(fp, ") "); + fprintf(fp, "mc type "); + if (mb->motion_type & XVMC_PREDICTION_FIELD) + fprintf(fp, "(field) "); + else if (mb->motion_type & XVMC_PREDICTION_FRAME) + fprintf(fp, "(frame) "); + else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME) + fprintf(fp, "(dual-prime) "); + else if (mb->motion_type & XVMC_PREDICTION_16x8) + fprintf(fp, "(16x8) "); + else if (mb->motion_type & XVMC_PREDICTION_4MV) + fprintf(fp, "(4MV) "); + else + fprintf(fp, "(none) "); + + if (mb->dct_type == XVMC_DCT_TYPE_FRAME) + fprintf(fp, "dct type (frame) "); + else if (mb->dct_type == XVMC_DCT_TYPE_FIELD) + fprintf(fp, "dct type (field) "); + + fprintf(fp, "coded_block_pattern (0x%x)\n", mb->coded_block_pattern); + + /* XXX mv dump */ + } + +} From c7fee208fd46e143965ea173984d284e1eec2a9b Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Wed, 4 Jun 2008 16:56:50 +0800 Subject: [PATCH 12/23] Fix DSPARB change on 965G From the spec, only 965GM and IGD_GM have 128 FIFO entries. With DSPARB change introduced by commit bd137a, I've got PIPE B underrun when dual-headed on G35 platform. --- 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 1041fe3b..426b20f4 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1964,12 +1964,12 @@ SetHWOperatingState(ScrnInfoPtr pScrn) * FIFO RAM entries equally between planes A and B. */ if (IS_I9XX(pI830)) { - if (IS_I915GM(pI830) || IS_I915G(pI830)) - OUTREG(DSPARB, (95 << DSPARB_CSTART_SHIFT) | - (48 << DSPARB_BSTART_SHIFT)); - else + if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) OUTREG(DSPARB, (127 << DSPARB_CSTART_SHIFT) | (64 << DSPARB_BSTART_SHIFT)); + else + OUTREG(DSPARB, (95 << DSPARB_CSTART_SHIFT) | + (48 << DSPARB_BSTART_SHIFT)); } else { OUTREG(DSPARB, 254 << DSPARB_BEND_SHIFT | 128 << DSPARB_AEND_SHIFT); } From beb72ae5aa053303f5cc419e9c9d7c6db964f160 Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Wed, 4 Jun 2008 16:58:05 +0800 Subject: [PATCH 13/23] Set SDVO sync polarity to default on 965 Fix fd.o bug 15766 --- src/i810_reg.h | 4 ++++ src/i830_sdvo.c | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/i810_reg.h b/src/i810_reg.h index 9da258a7..e0b0c272 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -1252,6 +1252,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) #define SDVOC_GANG_MODE (1 << 16) #define SDVO_BORDER_ENABLE (1 << 7) +/** new with 965, default is to be set */ +#define SDVO_VSYNC_ACTIVE_HIGH (1 << 4) +#define SDVO_HSYNC_ACTIVE_HIGH (1 << 3) +/** 915/945 only, read-only bit */ #define SDVOB_PCIE_CONCURRENCY (1 << 3) #define SDVO_DETECTED (1 << 2) /* Bits to be preserved when writing */ diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c index 23791274..331059bf 100644 --- a/src/i830_sdvo.c +++ b/src/i830_sdvo.c @@ -873,7 +873,9 @@ i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode, /* Set the SDVO control regs. */ if (IS_I965G(pI830)) { - sdvox = SDVO_BORDER_ENABLE; + sdvox = SDVO_BORDER_ENABLE | + SDVO_VSYNC_ACTIVE_HIGH | + SDVO_HSYNC_ACTIVE_HIGH; } else { sdvox = INREG(dev_priv->output_device); switch (dev_priv->output_device) { From 65306cdd71dad71e4ca7229764f81a0880dd70bf Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Jun 2008 11:26:02 -0700 Subject: [PATCH 14/23] Just remove the mprotect kludge. Besides not being #ifdef __linux__ed as requested, some linux kernels break in exciting new ways when you try to mprotect from PROT_NONE back to PROT_READ|PROT_WRITE. Yes, there are bugs in the code we're calling in a bug-exploiting bug workaround. If you want this workaround for the original bug exposed when moving to libpciaccess, it's already in libpciaccess. --- src/i830_driver.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 426b20f4..49f8db9d 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -692,11 +692,6 @@ I830MapMem(ScrnInfoPtr pScrn) (void **) &pI830->FbBase); if (err) return FALSE; - /* KLUDGE ALERT -- rewrite the PTEs to turn off the CD and WT bits */ -#if HAVE_MPROTECT - mprotect (pI830->FbBase, pI830->FbMapSize, PROT_NONE); - mprotect (pI830->FbBase, pI830->FbMapSize, PROT_READ|PROT_WRITE); -#endif #else pI830->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, pI830->PciTag, From 7e51384c973a96366b02ea646392c43574674111 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Jun 2008 11:56:42 -0700 Subject: [PATCH 15/23] Replace a couple of wait-for-ring-idles with a single function to do so. --- src/i830.h | 8 ++++++++ src/i830_accel.c | 2 +- src/i830_driver.c | 6 +++--- src/i830_ring.h | 17 +---------------- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/i830.h b/src/i830.h index 82901978..cac3ef68 100644 --- a/src/i830.h +++ b/src/i830.h @@ -859,6 +859,14 @@ i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform, void i830_enter_render(ScrnInfoPtr); +static inline void +i830_wait_ring_idle(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + I830WaitLpRing(pScrn, pI830->LpRing->mem->size - 8, 0); +} + static inline int i830_fb_compression_supported(I830Ptr pI830) { if (!IS_MOBILE(pI830)) diff --git a/src/i830_accel.c b/src/i830_accel.c index 953a73bc..7784c62a 100644 --- a/src/i830_accel.c +++ b/src/i830_accel.c @@ -201,7 +201,7 @@ I830Sync(ScrnInfoPtr pScrn) ADVANCE_BATCH(); } - I830WaitLpRing(pScrn, pI830->LpRing->mem->size - 8, 0); + i830_wait_ring_idle(pScrn); pI830->LpRing->space = pI830->LpRing->mem->size - 8; pI830->nextColorExpandBuf = 0; diff --git a/src/i830_driver.c b/src/i830_driver.c index 49f8db9d..5af3153a 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1851,7 +1851,7 @@ i830_stop_ring(ScrnInfoPtr pScrn, Bool flush) if (temp & RING_VALID) { i830_refresh_ring(pScrn); I830Sync(pScrn); - DO_RING_IDLE(); + i830_wait_ring_idle(pScrn); } OUTREG(LP_RING + RING_LEN, 0); @@ -3416,10 +3416,10 @@ I830EnterVT(int scrnIndex, int flags) int i; I830DRIResume(screenInfo.screens[scrnIndex]); - + i830_refresh_ring(pScrn); I830Sync(pScrn); - DO_RING_IDLE(); + i830_wait_ring_idle(pScrn); sarea->texAge++; for(i = 0; i < I830_NR_TEX_REGIONS+1 ; i++) diff --git a/src/i830_ring.h b/src/i830_ring.h index cf789eb6..c2078fb4 100644 --- a/src/i830_ring.h +++ b/src/i830_ring.h @@ -75,28 +75,13 @@ union intfloat { pI830->ring_emitting = 0; \ } while (0) -/* - * XXX Note: the head/tail masks are different for 810 and i830. - * If the i810 always sets the higher bits to 0, then this shouldn't be - * a problem. Check this! - */ -#define DO_RING_IDLE() do { \ - int _head; \ - int _tail; \ - do { \ - _head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; \ - _tail = INREG(LP_RING + RING_TAIL) & I830_TAIL_MASK; \ - DELAY(10); \ - } while (_head != _tail); \ -} while (0) - #define BEGIN_LP_RING(n) \ do { \ if (pI830->ring_emitting != 0) \ FatalError("%s: BEGIN_LP_RING called without closing " \ "ADVANCE_LP_RING\n", __FUNCTION__); \ if ((n) > 2 && (I810_DEBUG&DEBUG_ALWAYS_SYNC)) \ - DO_RING_IDLE(); \ + i830_wait_ring_idle(pScrn); \ pI830->ring_emitting = (n) * 4; \ if ((n) & 1) \ pI830->ring_emitting += 4; \ From c2e2fe48113667c683c6e1e9b1237635c41c61c3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Jun 2008 13:21:55 -0700 Subject: [PATCH 16/23] Move DSPARB setup into a separate function, and save/restore it at VT switch. --- src/i830.h | 1 + src/i830_driver.c | 53 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/i830.h b/src/i830.h index cac3ef68..21521533 100644 --- a/src/i830.h +++ b/src/i830.h @@ -582,6 +582,7 @@ typedef struct _I830Rec { enum backlight_control backlight_control_method; + uint32_t saveDSPARB; uint32_t saveDSPACNTR; uint32_t saveDSPBCNTR; uint32_t savePIPEACONF; diff --git a/src/i830_driver.c b/src/i830_driver.c index 5af3153a..34c83c10 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1921,22 +1921,22 @@ i830_refresh_ring(ScrnInfoPtr pScrn) i830MarkSync(pScrn); } -/* - * This should be called everytime the X server gains control of the screen, - * before any video modes are programmed (ScreenInit, EnterVT). +/** + * Sets up the DSPARB register to split the display fifo appropriately between + * the display planes. + * + * Adjusting this register requires that the planes be off, thus as a side + * effect they are disabled by this function. */ static void -SetHWOperatingState(ScrnInfoPtr pScrn) +i830_set_dsparb(ScrnInfoPtr pScrn) { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int i; - DPRINTF(PFX, "SetHWOperatingState\n"); - - /* - * Disable outputs & pipes since some of these regs can only be updated - * when they're off. + /* Disable outputs & pipes since DSPARB can only be updated when they're + * off. */ for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; @@ -1949,12 +1949,7 @@ SetHWOperatingState(ScrnInfoPtr pScrn) } i830WaitForVblank(pScrn); - i830_start_ring(pScrn); - if (!pI830->SWCursor) - I830InitHWCursor(pScrn); - - /* - * Fixup FIFO defaults: + /* Fixup FIFO defaults: * we don't use plane C at all so we can allocate all but one of the 96 * FIFO RAM entries equally between planes A and B. */ @@ -1970,6 +1965,22 @@ SetHWOperatingState(ScrnInfoPtr pScrn) } } +/* + * This should be called everytime the X server gains control of the screen, + * before any video modes are programmed (ScreenInit, EnterVT). + */ +static void +SetHWOperatingState(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + DPRINTF(PFX, "SetHWOperatingState\n"); + + i830_start_ring(pScrn); + if (!pI830->SWCursor) + I830InitHWCursor(pScrn); +} + enum pipe { PIPE_A = 0, PIPE_B, @@ -2034,6 +2045,8 @@ SaveHWState(ScrnInfoPtr pScrn) } /* Save video mode information for native mode-setting. */ + pI830->saveDSPARB = INREG(DSPARB); + pI830->saveDSPACNTR = INREG(DSPACNTR); pI830->savePIPEACONF = INREG(PIPEACONF); pI830->savePIPEASRC = INREG(PIPEASRC); @@ -2164,6 +2177,8 @@ RestoreHWState(ScrnInfoPtr pScrn) if (!IS_I830(pI830) && !IS_845G(pI830)) OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL); + OUTREG(DSPARB, pI830->saveDSPARB); + /* * Pipe regs * To restore the saved state, we first need to program the PLL regs, @@ -3237,7 +3252,6 @@ I830LeaveVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); #ifndef HAVE_FREE_SHADOW int o; #endif @@ -3368,6 +3382,11 @@ I830EnterVT(int scrnIndex, int flags) i830_stop_ring(pScrn, FALSE); SetHWOperatingState(pScrn); + /* Set the DSPARB register. This disables the outputs, which is about to + * happen (likely) in xf86SetDesiredModes anyway. + */ + i830_set_dsparb(pScrn); + /* Clear the framebuffer */ memset(pI830->FbBase + pScrn->fbOffset, 0, pScrn->virtualY * pScrn->displayWidth * pI830->cpp); From adb4f5a5e826e584ab212d23fc8d474c3e7bb8e8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Jun 2008 13:39:08 -0700 Subject: [PATCH 17/23] Remove duplicated i830_stop_ring()/SetHWOperatingState() in EnterVT(). --- src/i830_driver.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 34c83c10..ba0b8a78 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -3400,9 +3400,6 @@ I830EnterVT(int scrnIndex, int flags) } i830DescribeOutputConfiguration(pScrn); - i830_stop_ring(pScrn, TRUE); - SetHWOperatingState(pScrn); - #ifdef XF86DRI if (pI830->directRenderingEnabled) { /* HW status is fixed, we need to set it up before any drm From b65f67b74ff99aea1490d52f170ef4fe80cef6c7 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Jun 2008 13:40:55 -0700 Subject: [PATCH 18/23] Move the remaining two lines of SetHWOperatingState to the caller. --- src/i830_driver.c | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index ba0b8a78..efc3630c 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1965,22 +1965,6 @@ i830_set_dsparb(ScrnInfoPtr pScrn) } } -/* - * This should be called everytime the X server gains control of the screen, - * before any video modes are programmed (ScreenInit, EnterVT). - */ -static void -SetHWOperatingState(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - DPRINTF(PFX, "SetHWOperatingState\n"); - - i830_start_ring(pScrn); - if (!pI830->SWCursor) - I830InitHWCursor(pScrn); -} - enum pipe { PIPE_A = 0, PIPE_B, @@ -3380,7 +3364,9 @@ I830EnterVT(int scrnIndex, int flags) } i830_stop_ring(pScrn, FALSE); - SetHWOperatingState(pScrn); + i830_start_ring(pScrn); + if (!pI830->SWCursor) + I830InitHWCursor(pScrn); /* Set the DSPARB register. This disables the outputs, which is about to * happen (likely) in xf86SetDesiredModes anyway. From b61cb9283185eb5211e84eb7d8e68beea607c2eb Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Jun 2008 13:57:54 -0700 Subject: [PATCH 19/23] Remove gratuitous wait_ring_idle after I830Sync. Syncing implies that. --- src/i830_driver.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index efc3630c..3b8f408a 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1851,7 +1851,6 @@ i830_stop_ring(ScrnInfoPtr pScrn, Bool flush) if (temp & RING_VALID) { i830_refresh_ring(pScrn); I830Sync(pScrn); - i830_wait_ring_idle(pScrn); } OUTREG(LP_RING + RING_LEN, 0); @@ -3421,7 +3420,6 @@ I830EnterVT(int scrnIndex, int flags) i830_refresh_ring(pScrn); I830Sync(pScrn); - i830_wait_ring_idle(pScrn); sarea->texAge++; for(i = 0; i < I830_NR_TEX_REGIONS+1 ; i++) From 8061e5ac27a5f61f940bccc940be922999cc1d3f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Jun 2008 14:09:45 -0700 Subject: [PATCH 20/23] Move BIOS scratch register setup to EnterVT instead of PreInit. We want these to always be set when our driver's in control. They are already appropriately save/restored at leave/entervt. --- src/i830.h | 4 ---- src/i830_driver.c | 39 ++++++++++++++++----------------------- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/i830.h b/src/i830.h index 21521533..3e124d0f 100644 --- a/src/i830.h +++ b/src/i830.h @@ -557,10 +557,6 @@ typedef struct _I830Rec { Bool StolenOnly; - Bool swfSaved; - uint32_t saveSWF0; - uint32_t saveSWF4; - Bool checkDevices; /* Driver phase/state information */ diff --git a/src/i830_driver.c b/src/i830_driver.c index 3b8f408a..0474e575 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -963,6 +963,19 @@ i830_init_clock_gating(ScrnInfoPtr pScrn) } } +static void +i830_init_bios_control(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + /* Set "extended desktop" */ + OUTREG(SWF0, INREG(SWF0) | (1 << 21)); + + /* Set "driver loaded", "OS unknown", "APM 1.2" */ + OUTREG(SWF4, (INREG(SWF4) & ~((3 << 19) | (7 << 16))) | + (1 << 23) | (2 << 16)); +} + static int I830LVDSPresent(ScrnInfoPtr pScrn) { @@ -1021,10 +1034,6 @@ PreInitCleanup(ScrnInfoPtr pScrn) if (pI830->entityPrivate) pI830->entityPrivate->pScrn_2 = NULL; } - if (pI830->swfSaved) { - OUTREG(SWF0, pI830->saveSWF0); - OUTREG(SWF4, pI830->saveSWF4); - } if (pI830->MMIOBase) I830UnmapMMIO(pScrn); I830FreeRec(pScrn); @@ -1492,19 +1501,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) i830_init_clock_gating(pScrn); -#if 1 - pI830->saveSWF0 = INREG(SWF0); - pI830->saveSWF4 = INREG(SWF4); - pI830->swfSaved = TRUE; - - /* Set "extended desktop" */ - OUTREG(SWF0, pI830->saveSWF0 | (1 << 21)); - - /* Set "driver loaded", "OS unknown", "APM 1.2" */ - OUTREG(SWF4, (pI830->saveSWF4 & ~((3 << 19) | (7 << 16))) | - (1 << 23) | (2 << 16)); -#endif - if (DEVICE_ID(pI830->PciInfo) == PCI_CHIP_E7221_G) num_pipe = 1; else @@ -1739,12 +1735,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->noAccel = TRUE; } - /* Don't need MMIO access anymore. */ - if (pI830->swfSaved) { - OUTREG(SWF0, pI830->saveSWF0); - OUTREG(SWF4, pI830->saveSWF4); - } - /* Set display resolution */ xf86SetDpi(pScrn, 0, 0); @@ -3372,6 +3362,9 @@ I830EnterVT(int scrnIndex, int flags) */ i830_set_dsparb(pScrn); + /* Tell the BIOS that we're in control of mode setting now. */ + i830_init_bios_control(pScrn); + /* Clear the framebuffer */ memset(pI830->FbBase + pScrn->fbOffset, 0, pScrn->virtualY * pScrn->displayWidth * pI830->cpp); From e41dc98a0aeec389b221038753056c725ecee1c5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Jun 2008 14:37:26 -0700 Subject: [PATCH 21/23] Initialize clock gating from EnterVT and save/restore it appropriately. --- src/i830.h | 4 ++++ src/i830_driver.c | 26 +++++++++++++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/i830.h b/src/i830.h index 3e124d0f..62e645ab 100644 --- a/src/i830.h +++ b/src/i830.h @@ -649,6 +649,10 @@ typedef struct _I830Rec { uint32_t saveFBC_CONTROL2; uint32_t saveFBC_CONTROL; uint32_t saveFBC_FENCE_OFF; + uint32_t saveRENCLK_GATE_D1; + uint32_t saveRENCLK_GATE_D2; + uint32_t saveDSPCLK_GATE_D; + uint32_t saveRAMCLK_GATE_D; enum last_3d *last_3d; diff --git a/src/i830_driver.c b/src/i830_driver.c index 0474e575..48a64f3f 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1499,8 +1499,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) i830TakeRegSnapshot(pScrn); - i830_init_clock_gating(pScrn); - if (DEVICE_ID(pI830->PciInfo) == PCI_CHIP_E7221_G) num_pipe = 1; else @@ -2093,6 +2091,14 @@ SaveHWState(ScrnInfoPtr pScrn) pI830->saveSWF[15] = INREG(SWF31); pI830->saveSWF[16] = INREG(SWF32); + pI830->saveDSPCLK_GATE_D = INREG(DSPCLK_GATE_D); + pI830->saveRENCLK_GATE_D1 = INREG(RENCLK_GATE_D1); + + if (IS_I965G(pI830)) { + pI830->saveRENCLK_GATE_D2 = INREG(RENCLK_GATE_D2); + pI830->saveRAMCLK_GATE_D = INREG(RAMCLK_GATE_D); + } + if (IS_MOBILE(pI830) && !IS_I830(pI830)) pI830->saveLVDS = INREG(LVDS); pI830->savePFIT_CONTROL = INREG(PFIT_CONTROL); @@ -2152,6 +2158,13 @@ RestoreHWState(ScrnInfoPtr pScrn) OUTREG(DSPARB, pI830->saveDSPARB); + OUTREG(DSPCLK_GATE_D, pI830->saveDSPCLK_GATE_D); + OUTREG(RENCLK_GATE_D1, pI830->saveRENCLK_GATE_D1); + + if (IS_I965G(pI830)) { + OUTREG(RENCLK_GATE_D2, pI830->saveRENCLK_GATE_D2); + OUTREG(RAMCLK_GATE_D, pI830->saveRAMCLK_GATE_D); + } /* * Pipe regs * To restore the saved state, we first need to program the PLL regs, @@ -3164,13 +3177,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); if (IS_I965G(pI830)) { - /* turn off clock gating */ -#if 0 - OUTREG(0x6204, 0x70804000); - OUTREG(0x6208, 0x00000001); -#else - OUTREG(0x6204, 0x70000000); -#endif /* Enable DAP stateless accesses. * Required for all i965 steppings. */ @@ -3365,6 +3371,8 @@ I830EnterVT(int scrnIndex, int flags) /* Tell the BIOS that we're in control of mode setting now. */ i830_init_bios_control(pScrn); + i830_init_clock_gating(pScrn); + /* Clear the framebuffer */ memset(pI830->FbBase + pScrn->fbOffset, 0, pScrn->virtualY * pScrn->displayWidth * pI830->cpp); From ad459b21b7de4a79552ac155803d5930432fb84b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Jun 2008 14:37:59 -0700 Subject: [PATCH 22/23] Remove SVG_WORK_CONTROL init. The bit set is now reserved -- used to be a workaround for early revisions. --- src/i830_driver.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 48a64f3f..03bfe7e0 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -3176,13 +3176,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); - if (IS_I965G(pI830)) { - /* Enable DAP stateless accesses. - * Required for all i965 steppings. - */ - OUTREG(SVG_WORK_CTL, 0x00000010); - } - pI830->starting = FALSE; pI830->closing = FALSE; pI830->suspended = FALSE; From bff180e6cac4452ef491c81855eb12bfa03d0bf3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Jun 2008 14:55:23 -0700 Subject: [PATCH 23/23] Move debug clock printout from ErrorF to X_INFO. --- src/i830_display.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/i830_display.c b/src/i830_display.c index 2d2d072a..56a718de 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -241,13 +241,15 @@ static void intel_clock(I830Ptr pI830, int refclk, intel_clock_t *clock) } static void -i830PrintPll(char *prefix, intel_clock_t *clock) +i830PrintPll(ScrnInfoPtr pScrn, char *prefix, intel_clock_t *clock) { - ErrorF("%s: dotclock %d vco %d ((m %d, m1 %d, m2 %d), n %d, (p %d, p1 %d, p2 %d))\n", - prefix, clock->dot, clock->vco, - clock->m, clock->m1, clock->m2, - clock->n, - clock->p, clock->p1, clock->p2); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "%s: dotclock %d vco %d ((m %d, m1 %d, m2 %d), n %d, " + "(p %d, p1 %d, p2 %d))\n", + prefix, clock->dot, clock->vco, + clock->m, clock->m1, clock->m2, + clock->n, + clock->p, clock->p1, clock->p2); } /** @@ -1268,7 +1270,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, "Adjusted mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); xf86PrintModeline(pScrn->scrnIndex, adjusted_mode); } - i830PrintPll("chosen", &clock); + i830PrintPll(pScrn, "chosen", &clock); } if (dpll & DPLL_VCO_ENABLE) @@ -1764,7 +1766,7 @@ i830_crtc_clock_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc) * configuration being accurate, which it isn't necessarily. */ if (0) - i830PrintPll("probed", &clock); + i830PrintPll(pScrn, "probed", &clock); return clock.dot; }