xserver-xorg-video-intel: Changes to 'upstream-experimental'
Rebased ref, commits from common ancestor:
commit 121bd7ff7cfd9a43fbb61fa56f06ba2d2b55035e
Author: Carl Worth <cworth@cworth.org>
Date: Fri Apr 10 14:08:00 2009 -0700
Increment version to 2.6.99.903 for release
diff --git a/configure.ac b/configure.ac
index 7d38cad..8cca400 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
AC_PREREQ(2.57)
AC_INIT([xf86-video-intel],
- 2.6.99.902,
+ 2.6.99.903,
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
xf86-video-intel)
commit ec8ef3b2984cef581ea7fa745a76fe6f97a952dd
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
Date: Wed Apr 8 15:49:00 2009 -0700
Don't enable kernel execbuf fencing w/EXA
If we enable kernel execbuf fence register management, it's best if the
kernel manages all fence registers. This works fine if the accel
method is managing pixmaps or doesn't use offscreen pixmaps. However
with EXA, pixmap accesses are done relative to the framebuffer BAR
mapping (pI830->FbBase) and the Screen pixmap address. So if we try to
set the screen pixmap to point at a GTT mapped (and therefore properly
fenced) address, later calls to intel_get_pixmap_offset() will call
into EXA, which will use the pseudo-random pixmap addr and the EXA
offscreen base addr (which is really just FbBase) to calculate the
offset. This will fail. So disable kernel fence reg management in the
EXA case (this is easier than adding proper EXA pixmap management to
xf86-video-intel, and makes more sense since we'll be removing EXA soon
anyway).
Fixes FDO #21027.
Also happens to fix FDO #21029 (as tested by Carl Worth <cworth@cworth.org).
(cherry picked from commit 620e97bbd6a811ad69b8ac94df1fe2c9edf65549)
diff --git a/src/i830_memory.c b/src/i830_memory.c
index e3314c5..0f8d90d 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -533,14 +533,15 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
struct drm_i915_gem_init init;
int ret;
- sp.param = I915_SETPARAM_NUM_USED_FENCES;
- sp.value = 0; /* kernel gets them all */
-
- ret = drmCommandWrite(pI830->drmSubFD, DRM_I915_SETPARAM, &sp,
- sizeof(sp));
- if (ret == 0)
- pI830->kernel_exec_fencing = TRUE;
-
+ if (pI830->accel == ACCEL_UXA) {
+ sp.param = I915_SETPARAM_NUM_USED_FENCES;
+ sp.value = 0; /* kernel gets them all */
+
+ ret = drmCommandWrite(pI830->drmSubFD, DRM_I915_SETPARAM,
+ &sp, sizeof(sp));
+ if (ret == 0)
+ pI830->kernel_exec_fencing = TRUE;
+ }
init.gtt_start = pI830->memory_manager->offset;
init.gtt_end = pI830->memory_manager->offset +
pI830->memory_manager->size;
commit 404fdcc5bc9dd32d39112d8a49a5617dbb886a40
Author: Shuang He <shuang.he@intel.com>
Date: Tue Apr 7 12:31:07 2009 -0700
Fix value for MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW
Since the change to scan-line based video sync, (rather than vblank-
based), we've only been getting tear-free video on one of the two
pipes. This fixes that bug by using the correct constant for waiting
on PIPEA.
(cherry picked from commit 0a0731c11d10392cdc55ecc04e4e3575c8b3fe57)
diff --git a/src/i810_reg.h b/src/i810_reg.h
index c964569..5211400 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -2442,7 +2442,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define MI_WAIT_FOR_PIPEB_VBLANK (1<<7)
#define MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW (1<<5)
#define MI_WAIT_FOR_PIPEA_VBLANK (1<<3)
-#define MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW (1<<2)
+#define MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW (1<<1)
/* Set the scan line for MI_WAIT_FOR_PIPE?_SCAN_LINE_WINDOW */
#define MI_LOAD_SCAN_LINES_INCL (0x12<<23)
commit 7b74b77557aa4100017ef3f9d344fb4071ae8470
Author: Carl Worth <cworth@cworth.org>
Date: Mon Apr 6 14:36:33 2009 -0700
Don't clip video to CRTC in the case of textured video
Since we're not limited by a single overlay plane on a single pipe,
we want to not clip at all, (so that the correct video appears on
both pipes).
This fixes bug #20980 which shows a video spanning two pipes
being rendered incorrectly.
(cherry picked from commit 940c2aad4d174b6609bdc49f8c99a4bc37926516)
diff --git a/src/i830_video.c b/src/i830_video.c
index 13f3ab1..4ed3047 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2146,7 +2146,8 @@ i830_clip_video_helper (ScrnInfoPtr pScrn,
pPriv->desired_crtc,
&crtc_box);
- if (crtc)
+ /* For textured video, we don't actually want to clip at all. */
+ if (crtc && !pPriv->textured)
{
REGION_INIT (pScreen, &crtc_region_local, &crtc_box, 1);
crtc_region = &crtc_region_local;
commit d8ce818c4e4ca0c348c16ead1b747165bce4bedb
Author: Zhenyu Wang <zhenyu.z.wang@intel.com>
Date: Tue Apr 7 10:53:08 2009 +0800
quirk LVDS on ibase MB890 855GM board
fix bug #19529
(cherry picked from commit 63b4b5efac936c674dedad8125a8dbac4f000908)
diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 8680baf..78292f7 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -236,6 +236,17 @@ static void quirk_msi_lvds_dmi (I830Ptr pI830)
}
}
+static void quirk_ibase_lvds (I830Ptr pI830)
+{
+ if (!i830_dmi_data[board_name]) {
+ ErrorF("Failed to load DMI info, iBase LVDS quirk not applied.\n");
+ return;
+ }
+ if (!strncmp(i830_dmi_data[board_name], "i855-W83627HF", 13)) {
+ pI830->quirk_flag |= QUIRK_IGNORE_LVDS;
+ }
+}
+
static void quirk_ivch_dvob (I830Ptr pI830)
{
pI830->quirk_flag |= QUIRK_IVCH_NEED_DVOB;
@@ -379,6 +390,9 @@ static i830_quirk i830_quirk_list[] = {
/* #19239: Mirrus Centrino laptop */
{ PCI_CHIP_I915_GM, 0x1584, 0x9800, quirk_broken_acpi_lid },
+ /* #19529: iBase MB890 board */
+ { PCI_CHIP_I855_GM, 0x8086, 0x3582, quirk_ibase_lvds },
+
{ 0, 0, 0, NULL },
};
commit 3e5586cace98f73a9f8403a6446d380899ecbce9
Author: Carl Worth <cworth@cworth.org>
Date: Mon Apr 6 14:02:08 2009 -0700
Fix new video sync-to-blank code for multi-head
We need to account for a non-zero Y offset for the CRTC. Without
this, we don't sync to the correct region, so tearing becomes
visible again.
(cherry picked from commit 5d9d9a2e466474a0508a15b294a91507ccb3ccc1)
diff --git a/src/i830_video.c b/src/i830_video.c
index 3331dd3..13f3ab1 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2517,6 +2517,7 @@ I830PutImage(ScrnInfoPtr pScrn,
if (sync) {
BoxPtr box;
+ int y1, y2;
int event, pipe;
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
@@ -2529,14 +2530,16 @@ I830PutImage(ScrnInfoPtr pScrn,
}
box = REGION_EXTENTS(unused, clipBoxes);
+ y1 = box->y1 - crtc->y;
+ y2 = box->y2 - crtc->y;
BEGIN_BATCH(5);
/* The documentation says that the LOAD_SCAN_LINES command
* always comes in pairs. Don't ask me why. */
OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | pipe);
- OUT_BATCH((box->y1 << 16) | box->y2);
+ OUT_BATCH((y1 << 16) | y2);
OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | pipe);
- OUT_BATCH((box->y1 << 16) | box->y2);
+ OUT_BATCH((y1 << 16) | y2);
OUT_BATCH(MI_WAIT_FOR_EVENT | event);
ADVANCE_BATCH();
}
commit 4e9b75175be791c6098ef79be8e04a8c3baa40f9
Author: Ma Ling <ling.ma@intel.com>
Date: Tue Mar 17 10:33:15 2009 +0800
Use best PLL timing values for G4X platform
construct function to find precise parameters from internal spreadsheet
table on G4X platform.
Signed-off-by: Ma Ling <ling.ma@intel.com>
(cherry picked from commit 7c94227dd4fa2164bebb36234958053bf1d26c12)
diff --git a/src/i830_display.c b/src/i830_display.c
index c280d26..dd1310f 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -67,10 +67,13 @@ typedef struct {
#define INTEL_P2_NUM 2
-typedef struct {
+typedef struct intel_limit intel_limit_t;
+struct intel_limit {
intel_range_t dot, vco, n, m, m1, m2, p, p1;
intel_p2_t p2;
-} intel_limit_t;
+ Bool (* find_pll)(const intel_limit_t *, xf86CrtcPtr,
+ int, int, intel_clock_t *);
+};
#define I8XX_DOT_MIN 25000
#define I8XX_DOT_MAX 350000
@@ -236,6 +239,13 @@ typedef struct {
#define G4X_P2_DUAL_LVDS_FAST 7
#define G4X_P2_DUAL_LVDS_LIMIT 0
+static Bool
+intel_find_pll_i8xx_and_i9xx(const intel_limit_t *, xf86CrtcPtr,
+ int, int, intel_clock_t *);
+static Bool
+intel_find_pll_g4x(const intel_limit_t *, xf86CrtcPtr,
+ int, int, intel_clock_t *);
+
static const intel_limit_t intel_limits[] = {
{ /* INTEL_LIMIT_I8XX_DVO_DAC */
.dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX },
@@ -248,6 +258,7 @@ static const intel_limit_t intel_limits[] = {
.p1 = { .min = I8XX_P1_MIN, .max = I8XX_P1_MAX },
.p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
.p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST },
+ .find_pll = intel_find_pll_i8xx_and_i9xx,
},
{ /* INTEL_LIMIT_I8XX_LVDS */
.dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX },
@@ -260,6 +271,7 @@ static const intel_limit_t intel_limits[] = {
.p1 = { .min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX },
.p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
.p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST },
+ .find_pll = intel_find_pll_i8xx_and_i9xx,
},
{ /* INTEL_LIMIT_I9XX_SDVO_DAC */
.dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
@@ -272,6 +284,7 @@ static const intel_limit_t intel_limits[] = {
.p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
.p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
.p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
+ .find_pll = intel_find_pll_i8xx_and_i9xx,
},
{ /* INTEL_LIMIT_I9XX_LVDS */
.dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
@@ -287,6 +300,7 @@ static const intel_limit_t intel_limits[] = {
*/
.p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
.p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST },
+ .find_pll = intel_find_pll_i8xx_and_i9xx,
},
{ /* INTEL_LIMIT_IGD_SDVO */
.dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX},
@@ -299,6 +313,7 @@ static const intel_limit_t intel_limits[] = {
.p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
.p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
.p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
+ .find_pll = intel_find_pll_i8xx_and_i9xx,
},
{ /* INTEL_LIMIT_IGD_LVDS */
.dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
@@ -312,6 +327,7 @@ static const intel_limit_t intel_limits[] = {
/* IGD only supports single-channel mode. */
.p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
.p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW },
+ .find_pll = intel_find_pll_i8xx_and_i9xx,
},
/* below parameter and function is for G4X Chipset Family*/
{ /* INTEL_LIMIT_G4X_SDVO */
@@ -326,6 +342,7 @@ static const intel_limit_t intel_limits[] = {
.p2 = { .dot_limit = G4X_P2_SDVO_LIMIT,
.p2_slow = G4X_P2_SDVO_SLOW,
.p2_fast = G4X_P2_SDVO_FAST },
+ .find_pll = intel_find_pll_g4x,
},
{ /* INTEL_LIMIT_G4X_HDMI_DAC */
.dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX },
@@ -339,6 +356,7 @@ static const intel_limit_t intel_limits[] = {
.p2 = { .dot_limit = G4X_P2_HDMI_DAC_LIMIT,
.p2_slow = G4X_P2_HDMI_DAC_SLOW,
.p2_fast = G4X_P2_HDMI_DAC_FAST },
+ .find_pll = intel_find_pll_g4x,
},
{ /* INTEL_LIMIT_G4X_SINGLE_LVDS */
.dot = { .min = G4X_DOT_SINGLE_LVDS_MIN,
@@ -360,6 +378,7 @@ static const intel_limit_t intel_limits[] = {
.p2 = { .dot_limit = G4X_P2_SINGLE_LVDS_LIMIT,
.p2_slow = G4X_P2_SINGLE_LVDS_SLOW,
.p2_fast = G4X_P2_SINGLE_LVDS_FAST },
+ .find_pll = intel_find_pll_g4x,
},
{ /* INTEL_LIMIT_G4X_DUAL_LVDS */
.dot = { .min = G4X_DOT_DUAL_LVDS_MIN,
@@ -381,6 +400,7 @@ static const intel_limit_t intel_limits[] = {
.p2 = { .dot_limit = G4X_P2_DUAL_LVDS_LIMIT,
.p2_slow = G4X_P2_DUAL_LVDS_SLOW,
.p2_fast = G4X_P2_DUAL_LVDS_FAST },
+ .find_pll = intel_find_pll_g4x,
},
};
@@ -547,18 +567,13 @@ i830PllIsValid(xf86CrtcPtr crtc, intel_clock_t *clock)
return TRUE;
}
-/**
- * Returns a set of divisors for the desired target clock with the given
- * refclk, or FALSE. The returned values represent the clock equation:
- * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
- */
static Bool
-i830FindBestPLL(xf86CrtcPtr crtc, int target, int refclk, intel_clock_t *best_clock)
+intel_find_pll_i8xx_and_i9xx(const intel_limit_t * limit, xf86CrtcPtr crtc,
+ int target, int refclk, intel_clock_t *best_clock)
{
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
- intel_clock_t clock;
- const intel_limit_t *limit = intel_limit (crtc);
+ intel_clock_t clock;
int err = target;
if (i830PipeHasType(crtc, I830_OUTPUT_LVDS))
@@ -610,6 +625,64 @@ i830FindBestPLL(xf86CrtcPtr crtc, int target, int refclk, intel_clock_t *best_cl
return (err != target);
}
+static Bool
+intel_find_pll_g4x(const intel_limit_t * limit, xf86CrtcPtr crtc,
+ int target, int refclk, intel_clock_t *best_clock)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ intel_clock_t clock;
+ int max_n;
+ Bool found = FALSE;
+ int err_most = target * 0.0048;
+
+ if (i830PipeHasType(crtc, I830_OUTPUT_LVDS))
+ {
+ /* For LVDS, if the panel is on, just rely on its current settings for
+ * dual-channel. We haven't figured out how to reliably set up
+ * different single/dual channel state, if we even can.
+ */
+ if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP)
+ clock.p2 = limit->p2.p2_fast;
+ else
+ clock.p2 = limit->p2.p2_slow;
+ } else {
+ if (target < limit->p2.dot_limit)
+ clock.p2 = limit->p2.p2_slow;
+ else
+ clock.p2 = limit->p2.p2_fast;
+ }
+
+ max_n = limit->n.max;
+ /* based on hardware requirement prefer smaller n to precision */
+ for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
+ /* based on hardware requirement prefere larger m1,m2, p1*/
+ for (clock.m1 = limit->m1.max;
+ clock.m1 >= limit->m1.min; clock.m1--) {
+ for (clock.m2 = limit->m2.max;
+ clock.m2 >= limit->m2.min; clock.m2--) {
+ for (clock.p1 = limit->p1.max;
+ clock.p1 >= limit->p1.min; clock.p1--) {
+ int this_err;
+
+ intel_clock (pI830, refclk, &clock);
+ if (!i830PllIsValid(crtc, &clock))
+ continue;
+ this_err = abs(clock.dot - target) ;
+ if (this_err < err_most) {
+ memcpy(best_clock, &clock, sizeof(intel_clock_t));
+ err_most = this_err;
+ /* prefer smaller n to precision */
+ max_n = clock.n;
+ found = TRUE;
+ }
+ }
+ }
+ }
+ }
+ return found;
+}
+
void
i830WaitForVblank(ScrnInfoPtr pScreen)
{
@@ -1513,6 +1586,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
uint32_t dpll = 0, fp = 0, dspcntr, pipeconf, lvds_bits = 0;
Bool ok, is_sdvo = FALSE, is_dvo = FALSE;
Bool is_crt = FALSE, is_lvds = FALSE, is_tv = FALSE;
+ const intel_limit_t *limit;
/* Set up some convenient bools for what outputs are connected to
* our pipe, used in DPLL setup.
@@ -1565,7 +1639,13 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
refclk = 48000;
}
- ok = i830FindBestPLL(crtc, adjusted_mode->Clock, refclk, &clock);
+ /*
+ * Returns a set of divisors for the desired target clock with the given
+ * refclk, or FALSE. The returned values represent the clock equation:
+ * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+ */
+ limit = intel_limit (crtc);
+ ok = limit->find_pll(limit, crtc, adjusted_mode->Clock, refclk, &clock);
if (!ok)
FatalError("Couldn't find PLL settings for mode!\n");
commit 3428e2fd4be337359278f7ab1dc0d9945d6fee34
Author: Ma Ling <ling.ma@intel.com>
Date: Tue Mar 17 10:41:02 2009 +0800
Define documented PLL timing limits for G4X platform
These timings on G4X platform were specified by internal spreadsheet from the chipset group.
Signed-off-by: Ma Ling <ling.ma@intel.com>
(cherry picked from commit 48db5bde9298f1126dfb42f4be8a3d61166abfd8)
diff --git a/src/i830_display.c b/src/i830_display.c
index 43ea4d4..c280d26 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -153,6 +153,88 @@ typedef struct {
#define INTEL_LIMIT_I9XX_LVDS 3
#define INTEL_LIMIT_IGD_SDVO_DAC 4
#define INTEL_LIMIT_IGD_LVDS 5
+#define INTEL_LIMIT_G4X_SDVO 6
+#define INTEL_LIMIT_G4X_HDMI_DAC 7
+#define INTEL_LIMIT_G4X_SINGLE_LVDS 8
+#define INTEL_LIMIT_G4X_DUAL_LVDS 9
+
+/*The parameter is for SDVO on G4x platform*/
+#define G4X_VCO_MIN 1750000
+#define G4X_VCO_MAX 3500000
+#define G4X_DOT_SDVO_MIN 25000
+#define G4X_DOT_SDVO_MAX 270000
+#define G4X_N_SDVO_MIN 1
+#define G4X_N_SDVO_MAX 4
+#define G4X_M_SDVO_MIN 104
+#define G4X_M_SDVO_MAX 138
+#define G4X_M1_SDVO_MIN 17
+#define G4X_M1_SDVO_MAX 23
+#define G4X_M2_SDVO_MIN 5
+#define G4X_M2_SDVO_MAX 11
+#define G4X_P_SDVO_MIN 10
+#define G4X_P_SDVO_MAX 30
+#define G4X_P1_SDVO_MIN 1
+#define G4X_P1_SDVO_MAX 3
+#define G4X_P2_SDVO_SLOW 10
+#define G4X_P2_SDVO_FAST 10
+#define G4X_P2_SDVO_LIMIT 270000
+
+/*The parameter is for HDMI_DAC on G4x platform*/
+#define G4X_DOT_HDMI_DAC_MIN 22000
+#define G4X_DOT_HDMI_DAC_MAX 400000
+#define G4X_N_HDMI_DAC_MIN 1
+#define G4X_N_HDMI_DAC_MAX 4
+#define G4X_M_HDMI_DAC_MIN 104
+#define G4X_M_HDMI_DAC_MAX 138
+#define G4X_M1_HDMI_DAC_MIN 16
+#define G4X_M1_HDMI_DAC_MAX 23
+#define G4X_M2_HDMI_DAC_MIN 5
+#define G4X_M2_HDMI_DAC_MAX 11
+#define G4X_P_HDMI_DAC_MIN 5
+#define G4X_P_HDMI_DAC_MAX 80
+#define G4X_P1_HDMI_DAC_MIN 1
+#define G4X_P1_HDMI_DAC_MAX 8
+#define G4X_P2_HDMI_DAC_SLOW 10
+#define G4X_P2_HDMI_DAC_FAST 5
+#define G4X_P2_HDMI_DAC_LIMIT 165000
+
+/*The parameter is for SINGLE_LVDS on G4x platform*/
+#define G4X_DOT_SINGLE_LVDS_MIN 20000
+#define G4X_DOT_SINGLE_LVDS_MAX 115000
+#define G4X_N_SINGLE_LVDS_MIN 1
+#define G4X_N_SINGLE_LVDS_MAX 3
+#define G4X_M_SINGLE_LVDS_MIN 104
+#define G4X_M_SINGLE_LVDS_MAX 138
+#define G4X_M1_SINGLE_LVDS_MIN 17
+#define G4X_M1_SINGLE_LVDS_MAX 23
+#define G4X_M2_SINGLE_LVDS_MIN 5
+#define G4X_M2_SINGLE_LVDS_MAX 11
+#define G4X_P_SINGLE_LVDS_MIN 28
+#define G4X_P_SINGLE_LVDS_MAX 112
+#define G4X_P1_SINGLE_LVDS_MIN 2
+#define G4X_P1_SINGLE_LVDS_MAX 8
+#define G4X_P2_SINGLE_LVDS_SLOW 14
+#define G4X_P2_SINGLE_LVDS_FAST 14
+#define G4X_P2_SINGLE_LVDS_LIMIT 0
+
+/*The parameter is for DUAL_LVDS on G4x platform*/
+#define G4X_DOT_DUAL_LVDS_MIN 80000
+#define G4X_DOT_DUAL_LVDS_MAX 224000
+#define G4X_N_DUAL_LVDS_MIN 1
+#define G4X_N_DUAL_LVDS_MAX 3
+#define G4X_M_DUAL_LVDS_MIN 104
+#define G4X_M_DUAL_LVDS_MAX 138
+#define G4X_M1_DUAL_LVDS_MIN 17
+#define G4X_M1_DUAL_LVDS_MAX 23
+#define G4X_M2_DUAL_LVDS_MIN 5
+#define G4X_M2_DUAL_LVDS_MAX 11
+#define G4X_P_DUAL_LVDS_MIN 14
+#define G4X_P_DUAL_LVDS_MAX 42
+#define G4X_P1_DUAL_LVDS_MIN 2
+#define G4X_P1_DUAL_LVDS_MAX 6
+#define G4X_P2_DUAL_LVDS_SLOW 7
+#define G4X_P2_DUAL_LVDS_FAST 7
+#define G4X_P2_DUAL_LVDS_LIMIT 0
static const intel_limit_t intel_limits[] = {
{ /* INTEL_LIMIT_I8XX_DVO_DAC */
@@ -231,15 +313,108 @@ static const intel_limit_t intel_limits[] = {
.p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
.p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW },
},
+ /* below parameter and function is for G4X Chipset Family*/
+ { /* INTEL_LIMIT_G4X_SDVO */
+ .dot = { .min = G4X_DOT_SDVO_MIN, .max = G4X_DOT_SDVO_MAX },
+ .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX},
+ .n = { .min = G4X_N_SDVO_MIN, .max = G4X_N_SDVO_MAX },
+ .m = { .min = G4X_M_SDVO_MIN, .max = G4X_M_SDVO_MAX },
+ .m1 = { .min = G4X_M1_SDVO_MIN, .max = G4X_M1_SDVO_MAX },
+ .m2 = { .min = G4X_M2_SDVO_MIN, .max = G4X_M2_SDVO_MAX },
+ .p = { .min = G4X_P_SDVO_MIN, .max = G4X_P_SDVO_MAX },
+ .p1 = { .min = G4X_P1_SDVO_MIN, .max = G4X_P1_SDVO_MAX},
+ .p2 = { .dot_limit = G4X_P2_SDVO_LIMIT,
+ .p2_slow = G4X_P2_SDVO_SLOW,
+ .p2_fast = G4X_P2_SDVO_FAST },
+ },
+ { /* INTEL_LIMIT_G4X_HDMI_DAC */
+ .dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX },
+ .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX},
+ .n = { .min = G4X_N_HDMI_DAC_MIN, .max = G4X_N_HDMI_DAC_MAX },
+ .m = { .min = G4X_M_HDMI_DAC_MIN, .max = G4X_M_HDMI_DAC_MAX },
+ .m1 = { .min = G4X_M1_HDMI_DAC_MIN, .max = G4X_M1_HDMI_DAC_MAX },
+ .m2 = { .min = G4X_M2_HDMI_DAC_MIN, .max = G4X_M2_HDMI_DAC_MAX },
+ .p = { .min = G4X_P_HDMI_DAC_MIN, .max = G4X_P_HDMI_DAC_MAX },
+ .p1 = { .min = G4X_P1_HDMI_DAC_MIN, .max = G4X_P1_HDMI_DAC_MAX},
+ .p2 = { .dot_limit = G4X_P2_HDMI_DAC_LIMIT,
+ .p2_slow = G4X_P2_HDMI_DAC_SLOW,
+ .p2_fast = G4X_P2_HDMI_DAC_FAST },
+ },
+ { /* INTEL_LIMIT_G4X_SINGLE_LVDS */
+ .dot = { .min = G4X_DOT_SINGLE_LVDS_MIN,
+ .max = G4X_DOT_SINGLE_LVDS_MAX },
+ .vco = { .min = G4X_VCO_MIN,
+ .max = G4X_VCO_MAX },
+ .n = { .min = G4X_N_SINGLE_LVDS_MIN,
+ .max = G4X_N_SINGLE_LVDS_MAX },
+ .m = { .min = G4X_M_SINGLE_LVDS_MIN,
+ .max = G4X_M_SINGLE_LVDS_MAX },
+ .m1 = { .min = G4X_M1_SINGLE_LVDS_MIN,
+ .max = G4X_M1_SINGLE_LVDS_MAX },
+ .m2 = { .min = G4X_M2_SINGLE_LVDS_MIN,
+ .max = G4X_M2_SINGLE_LVDS_MAX },
+ .p = { .min = G4X_P_SINGLE_LVDS_MIN,
+ .max = G4X_P_SINGLE_LVDS_MAX },
+ .p1 = { .min = G4X_P1_SINGLE_LVDS_MIN,
+ .max = G4X_P1_SINGLE_LVDS_MAX },
+ .p2 = { .dot_limit = G4X_P2_SINGLE_LVDS_LIMIT,
+ .p2_slow = G4X_P2_SINGLE_LVDS_SLOW,
+ .p2_fast = G4X_P2_SINGLE_LVDS_FAST },
+ },
+ { /* INTEL_LIMIT_G4X_DUAL_LVDS */
+ .dot = { .min = G4X_DOT_DUAL_LVDS_MIN,
+ .max = G4X_DOT_DUAL_LVDS_MAX },
+ .vco = { .min = G4X_VCO_MIN,
+ .max = G4X_VCO_MAX},
+ .n = { .min = G4X_N_DUAL_LVDS_MIN,
+ .max = G4X_N_DUAL_LVDS_MAX },
+ .m = { .min = G4X_M_DUAL_LVDS_MIN,
+ .max = G4X_M_DUAL_LVDS_MAX },
+ .m1 = { .min = G4X_M1_DUAL_LVDS_MIN,
+ .max = G4X_M1_DUAL_LVDS_MAX },
+ .m2 = { .min = G4X_M2_DUAL_LVDS_MIN,
+ .max = G4X_M2_DUAL_LVDS_MAX },
+ .p = { .min = G4X_P_DUAL_LVDS_MIN,
+ .max = G4X_P_DUAL_LVDS_MAX },
+ .p1 = { .min = G4X_P1_DUAL_LVDS_MIN,
+ .max = G4X_P1_DUAL_LVDS_MAX},
+ .p2 = { .dot_limit = G4X_P2_DUAL_LVDS_LIMIT,
+ .p2_slow = G4X_P2_DUAL_LVDS_SLOW,
+ .p2_fast = G4X_P2_DUAL_LVDS_FAST },
+ },
};
+static const intel_limit_t *intel_limit_g4x (xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ const intel_limit_t *limit;
+
+ if (i830PipeHasType (crtc, I830_OUTPUT_LVDS)) {
+ if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) {
+ /* LVDS with dual channel */
+ limit = &intel_limits[INTEL_LIMIT_G4X_DUAL_LVDS];
+ } else /* LVDS with single channel */
+ limit = &intel_limits[INTEL_LIMIT_G4X_SINGLE_LVDS];
+ } else if (i830PipeHasType (crtc, I830_OUTPUT_HDMI) ||
+ i830PipeHasType (crtc, I830_OUTPUT_ANALOG)) {
+ limit = &intel_limits[INTEL_LIMIT_G4X_HDMI_DAC];
+ } else if (i830PipeHasType (crtc, I830_OUTPUT_SDVO)) {
+ limit = &intel_limits[INTEL_LIMIT_G4X_SDVO];
+ } else /* The option is for other outputs */
+ limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
+ return limit;
+}
+
static const intel_limit_t *intel_limit (xf86CrtcPtr crtc)
{
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
const intel_limit_t *limit;
- if (IS_I9XX(pI830) && !IS_IGD(pI830)) {
+ if (IS_G4X(pI830)) {
+ limit = intel_limit_g4x(crtc);
+ } else if (IS_I9XX(pI830) && !IS_IGD(pI830)) {
if (i830PipeHasType (crtc, I830_OUTPUT_LVDS))
limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS];
else
commit 3b29eb99259ea7b84bd41bff623b027dbe28ffba
Author: Carl Worth <cworth@cworth.org>
Date: Mon Apr 6 11:31:20 2009 -0700
Remove support for 'auto'(-1) value of XV_SYNC_TO_VBLANK
We previously had a heurstic here where we would only sync to vblank
for windows that covered more than 25% of the screen. We don't need
this anymore since the new approach to sync, (WAIT_FOR_SCANLINE_WINDOW),
is not excessively costly for small windows.
(cherry picked from commit 3d4ee3cac1d63dfdf7b54c8ba577f3b77637499f)
diff --git a/man/intel.man b/man/intel.man
index ffe69a1..6ccacda 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -451,10 +451,11 @@ You can use the "xvattr" tool to query/set those attributes at runtime.
.SS "XV_SYNC_TO_VBLANK"
XV_SYNC_TO_VBLANK is used to control whether textured adapter synchronizes
-the screen update to the vblank to eliminate tearing. It has three
-values 'auto'(-1), 'off'(0) and 'on(1). 'off' means never sync, 'on' means
-always sync, no matter what size, and 'auto' means sync if the Xv image is
-more than quarter of the pixels on the screen. The default is 'auto'(-1).
+the screen update to the vblank to eliminate tearing. It is a Boolean
+attribute with values of 0 (never sync) or 1 (always sync). An historic
+value of -1 (sync for large windows only) will now be interpreted as 1,
+(since the current approach for sync is not costly even with small
+video windows).
.SS "XV_BRIGHTNESS"
diff --git a/src/i830_video.c b/src/i830_video.c
index 3dde5b4..3331dd3 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1019,7 +1019,7 @@ I830SetupImageVideoTextured(ScreenPtr pScreen)
pPriv->doubleBuffer = 0;
pPriv->rotation = RR_Rotate_0;
- pPriv->SyncToVblank = -1;
+ pPriv->SyncToVblank = 1;
/* gotta uninit this someplace, XXX: shouldn't be necessary for textured */
REGION_NULL(pScreen, &pPriv->clip);
@@ -2513,23 +2513,6 @@ I830PutImage(ScrnInfoPtr pScrn,
sync = FALSE;
} else if (pPriv->SyncToVblank == 0) {
sync = FALSE;
- } else if (pPriv->SyncToVblank == -1) {
- BoxRec crtc_box;
- BoxPtr pbox;
- int nbox, crtc_area, coverage = 0;
-
- i830_crtc_box(crtc, &crtc_box);
- crtc_area = i830_box_area(&crtc_box);
- pbox = REGION_RECTS(clipBoxes);
- nbox = REGION_NUM_RECTS(clipBoxes);
-
- while (nbox--) {
- coverage += i830_box_area(pbox);
- pbox++;
- }
-
- if ((coverage << 2) < crtc_area)
- sync = FALSE;
}
if (sync) {
commit 5dd2777ce836bdf55b53ed763728705d4d686673
Author: Carl Worth <cworth@cworth.org>
Date: Mon Apr 6 11:16:40 2009 -0700
Use WAIT_FOR_SCAN_LINE instead of WAIT_FOR_VBLANK
Either way, the goal is tear-free video playing. But waiting for
a scan-line window not only has the advantage of being cheaper
for small windows, but also avoids hanging the GPU in the case
of the pipe getting turned off, (by screensaver, for example),
while a batch is waiting for a VBLANK that will never occur.
This fixes that GPU hang.
(cherry picked from commit bc3312fd7c03d09a231dfebfe390fe668ad15d1e)
diff --git a/src/i810_reg.h b/src/i810_reg.h
index 3114b42..c964569 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -2435,12 +2435,19 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define MI_OVERLAY_FLIP_OFF (2<<21)
/* Wait for Events */
-#define MI_WAIT_FOR_EVENT (0x03<<23)
-#define MI_WAIT_FOR_PIPEB_SVBLANK (1<<18)
-#define MI_WAIT_FOR_PIPEA_SVBLANK (1<<17)
-#define MI_WAIT_FOR_OVERLAY_FLIP (1<<16)
-#define MI_WAIT_FOR_PIPEB_VBLANK (1<<7)
-#define MI_WAIT_FOR_PIPEA_VBLANK (1<<3)
+#define MI_WAIT_FOR_EVENT (0x03<<23)
+#define MI_WAIT_FOR_PIPEB_SVBLANK (1<<18)
+#define MI_WAIT_FOR_PIPEA_SVBLANK (1<<17)
+#define MI_WAIT_FOR_OVERLAY_FLIP (1<<16)
+#define MI_WAIT_FOR_PIPEB_VBLANK (1<<7)
+#define MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW (1<<5)
+#define MI_WAIT_FOR_PIPEA_VBLANK (1<<3)
+#define MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW (1<<2)
+
+/* Set the scan line for MI_WAIT_FOR_PIPE?_SCAN_LINE_WINDOW */
+#define MI_LOAD_SCAN_LINES_INCL (0x12<<23)
+#define MI_LOAD_SCAN_LINES_DISPLAY_PIPEA (0)
+#define MI_LOAD_SCAN_LINES_DISPLAY_PIPEB (0x1<<20)
/* Flush */
#define MI_FLUSH (0x04<<23)
diff --git a/src/i830_video.c b/src/i830_video.c
index 3f3aaac..3dde5b4 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2533,24 +2533,28 @@ I830PutImage(ScrnInfoPtr pScrn,
}
if (sync) {
- I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
- int event;
-
- if (IS_I965G(pI830)) {
- if (intel_crtc->pipe == 0)
- event = MI_WAIT_FOR_PIPEA_SVBLANK;
- else
- event = MI_WAIT_FOR_PIPEB_SVBLANK;
- } else {
- if (intel_crtc->pipe == 0)
- event = MI_WAIT_FOR_PIPEA_VBLANK;
- else
- event = MI_WAIT_FOR_PIPEB_VBLANK;
- }
+ BoxPtr box;
+ int event, pipe;
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+
+ if (intel_crtc->pipe == 0) {
+ event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
+ pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEA;
+ } else {
+ event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
+ pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEB;
+ }
+
+ box = REGION_EXTENTS(unused, clipBoxes);
- BEGIN_BATCH(2);
+ BEGIN_BATCH(5);
+ /* The documentation says that the LOAD_SCAN_LINES command
+ * always comes in pairs. Don't ask me why. */
+ OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | pipe);
+ OUT_BATCH((box->y1 << 16) | box->y2);
+ OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | pipe);
+ OUT_BATCH((box->y1 << 16) | box->y2);
OUT_BATCH(MI_WAIT_FOR_EVENT | event);
- OUT_BATCH(MI_NOOP);
ADVANCE_BATCH();
}
commit 5944f5e32511984b11decc0df6074600e1989934
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
Date: Fri Apr 3 11:15:18 2009 -0700
Fix offset in begin_gtt_access case
Don't use bo->virtual in the begin_gtt_access case, use the framebuffer
mapping and bo offset instead.
Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
(cherry picked from commit 6cd914ef315036ce8e91c7b6492994353e8ed2d8)
diff --git a/src/i830_driver.c b/src/i830_driver.c
index d7ee615..32ca6c9 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -846,11 +846,12 @@ i830_update_front_offset(ScrnInfoPtr pScrn)
if (drm_intel_gem_bo_map_gtt(bo))
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: bo map failed\n",
__FUNCTION__);
+ data = bo->virtual;
} else {
/* Will already be pinned by bind_all_memory in this case */
drm_intel_gem_bo_start_gtt_access(bo, 1);
+ data = pI830->FbBase + bo->offset;
}
- data = bo->virtual;
}
}
if (!pScreen->ModifyPixmapHeader(pScreen->GetScreenPixmap(pScreen),
diff --git a/src/i830_exa.c b/src/i830_exa.c
index fc4e66c..39011bc 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -867,12 +867,13 @@ i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access)
__FUNCTION__);
return FALSE;
}
+ pixmap->devPrivate.ptr = bo->virtual;
} else { /* or not... */
if (drm_intel_bo_pin(bo, 4096) != 0)
return FALSE;
drm_intel_gem_bo_start_gtt_access(bo, access == UXA_ACCESS_RW);
+ pixmap->devPrivate.ptr = i830->FbBase + bo->offset;
}
- pixmap->devPrivate.ptr = bo->virtual;
}
return TRUE;
}
commit 633c24bc20ed96b1f9ef954bfd722e3ab504ea93
Author: Zhenyu Wang <zhenyu.z.wang@intel.com>
Date: Wed Apr 1 10:11:35 2009 +0800
SDVO: fix output flag dumping for unknown type
Found by Hugo Jacques <hugo.jacques@verint.com>
(cherry picked from commit fad714c40078d22fff82dc0692a344f66ddf9680)
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 79d49d9..a7b5171 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -1605,7 +1605,7 @@ i830_sdvo_output_setup (xf86OutputPtr output, uint16_t flag)
xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_WARNING,
"%s: Unknown SDVO output type (0x%02x%02x)\n",
SDVO_NAME(dev_priv),
- bytes[0], bytes[1]);
+ bytes[1], bytes[0]);
name_prefix="Unknown";
}
commit 6501f8e5e91f3f87348d590e42a4860fea2cfddc
Author: Hugo Jacques <hugo.jacques@verint.com>
Date: Wed Apr 1 10:10:05 2009 +0800
SDVO: add composite TV out support
(cherry picked from commit 00de1757dd5776962bdd4c8968181878c2ebf4c9)
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 254b866..79d49d9 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -1570,6 +1570,14 @@ i830_sdvo_output_setup (xf86OutputPtr output, uint16_t flag)
dev_priv->is_tv = TRUE;
intel_output->needs_tv_clock = TRUE;
}
+ else if (flag & SDVO_OUTPUT_CVBS0)
+ {
+ dev_priv->controlled_output = SDVO_OUTPUT_CVBS0;
+ output->subpixel_order = SubPixelHorizontalRGB; /* XXX */
+ name_prefix="TV";
+ dev_priv->is_tv = TRUE;
+ intel_output->needs_tv_clock = TRUE;
+ }
else if (flag & SDVO_OUTPUT_RGB0)
{
dev_priv->controlled_output = SDVO_OUTPUT_RGB0;
commit 10b5014c42dc055d9559ee112cc7a017e887d813
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
Date: Tue Mar 31 07:50:10 2009 -0700
Match GTT unmap with map in KMS rotation case
Missed this when the GTT unmap call was added. If we don't do this we
trigger an assertion in libdrm, since the buffer has never been mapped
normally.
Fixes bug #20943.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
(cherry picked from commit 087f72e1f5d7d11b8795ba80a842874f5a9bb01d)
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index e485256..a276ff7 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -372,7 +372,7 @@ drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *dat
* unbound. */
drmModeRmFB(drmmode->fd, drmmode_crtc->rotate_fb_id);
drmmode_crtc->rotate_fb_id = 0;
- drm_intel_bo_unmap(drmmode_crtc->rotate_bo);
+ drm_intel_gem_bo_unmap_gtt(drmmode_crtc->rotate_bo);
dri_bo_unreference(drmmode_crtc->rotate_bo);
drmmode_crtc->rotate_bo = NULL;
}
commit 26cab64654bdf68095412d0aaba157774d1ca16b
Author: Zhenyu Wang <zhenyu.z.wang@intel.com>
Date: Tue Mar 31 13:49:44 2009 +0800
Disable LVDS detect methods
Both methods ACPI lid and SWF bit have issues in LVDS detect from
wider testing. Fallback to origin code.
(cherry picked from commit 4f046af760b92c07f59664359453933fb5358e3d)
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 7569e99..7fc0bce 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -881,6 +881,13 @@ i830_lvds_mode_set(xf86OutputPtr output, DisplayModePtr mode,
static xf86OutputStatus
i830_lvds_detect(xf86OutputPtr output)
{
+ /* Fallback to origin, mark LVDS always connected.
+ * From wider tests, we have seen both broken cases with
+ * ACPI lid and SWF bit. So disable them for now until we
+ * get a reliable way for LVDS detect.
+ */
+ return XF86OutputStatusConnected;
+
enum lid_status lid;
lid = i830_lvds_acpi_lid_open(output);
commit d43016865c670d9281c6b664094fb41a252fbdc0
Author: Albert Damen <albrt@gmx.net>
Date: Mon Mar 30 11:38:02 2009 -0700
Non-GEM allocations incorrectly force TILE_NONE (bug 20797)
With -intel 2.6.3 performance was very bad when using a non gem enabled kernel
(2.6.27) and EXA. For example sauerbraten ran with 4 fps and screensaver GLBlur
with 1 fps. With -intel 2.6.1 performance was good using the same kernel.
Reply to: