summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Packard <keithp@gamba.jf.intel.com>2007-03-03 21:02:17 -0800
committerKeith Packard <keithp@gamba.jf.intel.com>2007-03-03 21:02:17 -0800
commit0fa3d4f51b5ee0dba3882fd74b6ac4e7da708f8f (patch)
tree7c309acf14e8fb78dc5f3337672f42cf93904ee1 /src
parent10655c4674cdac8a231c50dd9afc5d43fe43b4bd (diff)
parentfd52d635603b7093c5a2b7fa9c987cf59f9be27c (diff)
Merge branch 'modesetting' into crestline
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am117
-rw-r--r--src/bios_reader/Makefile.am2
-rw-r--r--src/ch7017/Makefile.am2
-rw-r--r--src/ch7017/ch7017.c2
-rw-r--r--src/ch7xxx/Makefile.am2
-rw-r--r--src/ch7xxx/ch7xxx.c2
-rw-r--r--src/common.h39
-rw-r--r--src/exa_sf_mask.g4a16
-rw-r--r--src/exa_sf_mask_prog.h16
-rw-r--r--src/exa_wm_maskca.g4a202
-rw-r--r--src/exa_wm_maskca_prog.h95
-rw-r--r--src/exa_wm_maskca_srcalpha.g4a202
-rw-r--r--src/exa_wm_maskca_srcalpha_prog.h95
-rw-r--r--src/i810.h5
-rw-r--r--src/i810_driver.c19
-rw-r--r--src/i810_reg.h43
-rw-r--r--src/i830.h208
-rw-r--r--src/i830_accel.c12
-rw-r--r--src/i830_bios.c26
-rw-r--r--src/i830_bios.h3
-rw-r--r--src/i830_crt.c2
-rw-r--r--src/i830_cursor.c19
-rw-r--r--src/i830_debug.c106
-rw-r--r--src/i830_dga.c447
-rw-r--r--src/i830_display.c350
-rw-r--r--src/i830_display.h1
-rw-r--r--src/i830_dri.c85
-rw-r--r--src/i830_driver.c855
-rw-r--r--src/i830_edid_modes.c340
-rw-r--r--src/i830_exa.c101
-rw-r--r--src/i830_lvds.c114
-rw-r--r--src/i830_memory.c3019
-rw-r--r--src/i830_modes.c2
-rw-r--r--src/i830_randr.c950
-rw-r--r--src/i830_randr.h37
-rw-r--r--src/i830_render.c28
-rw-r--r--src/i830_sdvo.c3
-rw-r--r--src/i830_video.c37
-rw-r--r--src/i830_xaa.c26
-rw-r--r--src/i830_xf86Crtc.h534
-rw-r--r--src/i830_xf86Modes.c636
-rw-r--r--src/i830_xf86Modes.h82
-rw-r--r--src/i830_xf86Rename.h66
-rw-r--r--src/i830_xf86Rotate.c402
-rw-r--r--src/i830_xf86cvt.c307
-rw-r--r--src/i965_render.c93
-rw-r--r--src/ivch/Makefile.am2
-rw-r--r--src/ivch/ivch.c2
-rw-r--r--src/reg_dumper/.gitignore1
-rw-r--r--src/reg_dumper/Makefile.am12
-rw-r--r--src/reg_dumper/main.c105
-rw-r--r--src/reg_dumper/reg_dumper.h89
-rw-r--r--src/reg_dumper/xprintf.c60
-rw-r--r--src/sil164/Makefile.am2
-rw-r--r--src/sil164/sil164.c2
55 files changed, 3537 insertions, 6488 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 7656e02e..c65c1e73 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,21 +18,49 @@
# 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.
-SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164
+if HAVE_PCIACCESS
+REGDUMPER = reg_dumper
+endif
+
+SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164 $(REGDUMPER)
# this is obnoxious:
# -module lets us name the module exactly how we want
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
-AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \
+
+AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ @XMODES_CFLAGS@ \
-DI830_XV -DI830_USE_XAA -DI830_USE_EXA
-i810_drv_la_LTLIBRARIES = i810_drv.la
-i810_drv_la_LDFLAGS = -module -avoid-version
-i810_drv_ladir = @moduledir@/drivers
+intel_drv_la_LTLIBRARIES = intel_drv.la
+intel_drv_la_LDFLAGS = -module -avoid-version
+intel_drv_ladir = @moduledir@/drivers
-i810_drv_la_SOURCES = \
+XMODE_SRCS=\
+ local_xf86Rename.h \
+ parser/xf86Parser.h \
+ parser/xf86Optrec.h \
+ modes/xf86Modes.h \
+ modes/xf86Modes.c \
+ modes/xf86cvt.c \
+ modes/xf86Crtc.h \
+ modes/xf86Crtc.c \
+ modes/xf86EdidModes.c \
+ modes/xf86RandR12.c \
+ modes/xf86RandR12.h \
+ modes/xf86Rename.h \
+ modes/xf86Rotate.c \
+ modes/xf86DiDGA.c
+
+INTEL_DRI_SRCS = \
+ i810_dri.c \
+ i810_dri.h \
+ i830_dri.c \
+ i810_hwmc.c \
+ i830_dri.h
+
+intel_drv_la_SOURCES = \
brw_defines.h \
brw_structs.h \
sf_prog.h \
@@ -59,12 +87,10 @@ i810_drv_la_SOURCES = \
i830_cursor.c \
i830_debug.c \
i830_debug.h \
- i830_dga.c \
i830_display.c \
i830_display.h \
i830_driver.c \
i830_dvo.c \
- i830_edid_modes.c \
i830.h \
i830_i2c.c \
i830_io.c \
@@ -74,17 +100,10 @@ i810_drv_la_SOURCES = \
i830_video.c \
i830_video.h \
i830_reg.h \
- i830_randr.c \
i830_sdvo.c \
i830_sdvo.h \
i830_sdvo_regs.h \
i830_tv.c \
- i830_xf86Modes.h \
- i830_xf86Modes.c \
- i830_xf86cvt.c \
- i830_xf86Crtc.h \
- i830_xf86Crtc.c \
- i830_xf86Rotate.c \
i915_3d.c \
i915_3d.h \
i915_reg.h \
@@ -96,30 +115,72 @@ i810_drv_la_SOURCES = \
i915_render.c \
i965_render.c
+INTEL_G4A = \
+ packed_yuv_sf.g4a \
+ packed_yuv_wm.g4a \
+ exa_sf.g4a \
+ exa_sf_mask.g4a \
+ exa_wm_maskca.g4a \
+ exa_wm_maskca_srcalpha.g4a \
+ exa_wm_masknoca.g4a \
+ exa_wm_nomask.g4a
+
+INTEL_G4H = \
+ sf_prog.h \
+ wm_prog.h \
+ exa_sf_mask_prog.h \
+ exa_sf_prog.h \
+ exa_wm_maskca_prog.h \
+ exa_wm_maskca_srcalpha_prog.h \
+ exa_wm_masknoca_prog.h \
+ exa_wm_nomask_prog.h
+
+EXTRA_DIST = \
+ $(XMODE_SRCS) \
+ $(INTEL_G4A) \
+ $(INTEL_G4H) \
+ $(INTEL_DRI_SRCS)
+
if HAVE_GEN4ASM
+
sf_prog.h: packed_yuv_sf.g4a
intel-gen4asm -o sf_prog.h packed_yuv_sf.g4a
+
wm_prog.h: packed_yuv_wm.g4a
intel-gen4asm -o wm_prog.h packed_yuv_wm.g4a
-exa_sf_prog.h: exa_sf.g4a
- intel-gen4asm -o exa_sf_prog.h exa_sf.g4a
+
exa_sf_mask_prog.h: exa_sf_mask.g4a
intel-gen4asm -o exa_sf_mask_prog.h exa_sf_mask.g4a
-exa_wm_nomask_prog.h: exa_wm_nomask.g4a
- intel-gen4asm -o exa_wm_nomask_prog.h exa_wm_nomask.g4a
+
+exa_sf_prog.h: exa_sf.g4a
+ intel-gen4asm -o exa_sf_prog.h exa_sf.g4a
+
+exa_wm_maskca_prog.h: exa_wm_maskca.g4a
+ intel-gen4asm -o exa_wm_maskca_prog.h exa_wm_maskca.g4a
+
+exa_wm_maskca_srcalpha_prog.h: exa_wm_maskca_srcalpha.g4a
+ intel-gen4asm -o exa_wm_maskca_srcalpha_prog.h exa_wm_maskca_srcalpha.g4a
+
exa_wm_masknoca_prog.h: exa_wm_masknoca.g4a
intel-gen4asm -o exa_wm_masknoca_prog.h exa_wm_masknoca.g4a
+
+exa_wm_nomask_prog.h: exa_wm_nomask.g4a
+ intel-gen4asm -o exa_wm_nomask_prog.h exa_wm_nomask.g4a
+
+endif
+
+if XMODES
+intel_drv_la_SOURCES += \
+ $(XMODE_SRCS)
endif
if DRI
-i810_drv_la_SOURCES += \
- i810_dri.c \
- i810_dri.h \
- i830_dri.c \
- i810_hwmc.c \
- i830_dri.h
+intel_drv_la_SOURCES += \
+ $(INTEL_DRI_SRCS)
endif
-EXTRA_DIST = \
- packed_yuv_sf.g4a \
- packed_yuv_wm.g4a
+install-data-local: install-intel_drv_laLTLIBRARIES
+ (cd $(DESTDIR)$(intel_drv_ladir) && rm -f i810_drv.so && ln -s intel_drv.so i810_drv.so)
+
+uninstall-local:
+ (cd $(DESTDIR)$(intel_drv_ladir) && rm -f i810_drv.so)
diff --git a/src/bios_reader/Makefile.am b/src/bios_reader/Makefile.am
index f18a00c3..a5c81a6c 100644
--- a/src/bios_reader/Makefile.am
+++ b/src/bios_reader/Makefile.am
@@ -1,4 +1,4 @@
-AM_CFLAGS = @XORG_CFLAGS@
+AM_CFLAGS = @XORG_CFLAGS@ @XMODES_CFLAGS@
noinst_PROGRAMS = bios_reader
diff --git a/src/ch7017/Makefile.am b/src/ch7017/Makefile.am
index 9cf2fa49..7fbb4408 100644
--- a/src/ch7017/Makefile.am
+++ b/src/ch7017/Makefile.am
@@ -3,7 +3,7 @@
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
-AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@
+AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes
ch7017_la_LTLIBRARIES = ch7017.la
ch7017_la_LDFLAGS = -module -avoid-version
diff --git a/src/ch7017/ch7017.c b/src/ch7017/ch7017.c
index 28bce0d2..019dcea0 100644
--- a/src/ch7017/ch7017.c
+++ b/src/ch7017/ch7017.c
@@ -37,7 +37,7 @@
#include "compiler.h"
#include "miscstruct.h"
#include "xf86i2c.h"
-#include "../i830_xf86Crtc.h"
+#include "xf86Crtc.h"
#define DPMS_SERVER
#include <X11/extensions/dpms.h>
diff --git a/src/ch7xxx/Makefile.am b/src/ch7xxx/Makefile.am
index 7f3b1e1e..b827bf8e 100644
--- a/src/ch7xxx/Makefile.am
+++ b/src/ch7xxx/Makefile.am
@@ -3,7 +3,7 @@
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
-AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/../
+AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes
ch7xxx_la_LTLIBRARIES = ch7xxx.la
ch7xxx_la_LDFLAGS = -module -avoid-version
diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c
index 161aebf4..9ce581fa 100644
--- a/src/ch7xxx/ch7xxx.c
+++ b/src/ch7xxx/ch7xxx.c
@@ -37,7 +37,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "compiler.h"
#include "miscstruct.h"
#include "xf86i2c.h"
-#include "i830_xf86Crtc.h"
+#include "xf86Crtc.h"
#define DPMS_SERVER
#include <X11/extensions/dpms.h>
diff --git a/src/common.h b/src/common.h
index cc682395..fa2a197b 100644
--- a/src/common.h
+++ b/src/common.h
@@ -72,6 +72,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DELAY(x) do {;} while (0)
#endif
+#ifndef REG_DUMPER
/* I830 hooks for the I810 driver setup/probe. */
extern const OptionInfoRec *I830AvailableOptions(int chipid, int busid);
extern void I830InitpScrn(ScrnInfoPtr pScrn);
@@ -130,6 +131,43 @@ extern void I830DPRINTF_stub(const char *filename, int line,
outring &= ringmask; \
} while (0)
+static inline void memset_volatile(volatile void *b, int c, size_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ ((volatile char *)b)[i] = c;
+}
+
+static inline void memcpy_volatile(volatile void *dst, const void *src,
+ size_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ ((volatile char *)dst)[i] = ((volatile char *)src)[i];
+}
+
+/** Copies a given number of bytes to the ring */
+#define OUT_RING_COPY(n, ptr) do { \
+ if (I810_DEBUG & DEBUG_VERBOSE_RING) \
+ ErrorF("OUT_RING_DATA %d bytes\n", n); \
+ memcpy_volatile(virt + outring, ptr, n); \
+ outring += n; \
+ ringused += n; \
+ outring &= ringmask; \
+} while (0)
+
+/** Pads the ring with a given number of zero bytes */
+#define OUT_RING_PAD(n) do { \
+ if (I810_DEBUG & DEBUG_VERBOSE_RING) \
+ ErrorF("OUT_RING_PAD %d bytes\n", n); \
+ memset_volatile(virt + outring, 0, n); \
+ outring += n; \
+ ringused += n; \
+ outring &= ringmask; \
+} while (0)
+
union intfloat {
float f;
unsigned int ui;
@@ -242,6 +280,7 @@ extern int I810_DEBUG;
#define DEBUG_ALWAYS_SYNC 0x80
#define DEBUG_VERBOSE_DRI 0x100
#define DEBUG_VERBOSE_BIOS 0x200
+#endif /* !REG_DUMPER */
/* Size of the mmio region.
*/
diff --git a/src/exa_sf_mask.g4a b/src/exa_sf_mask.g4a
index ab519cee..a7e2d324 100644
--- a/src/exa_sf_mask.g4a
+++ b/src/exa_sf_mask.g4a
@@ -22,25 +22,25 @@ mul (1) g7<1>F g7<0,1,0>F g6<0,1,0>F { align1 };
/* Cy[0] */
mul (1) g7.4<1>F g7.4<0,1,0>F g6.4<0,1,0>F { align1 };
/* Cx[2] */
-mul (1) g7.16<1>F g7.16<0,1,0>F g6<0,1,0>F { align1 };
+mul (1) g7.8<1>F g7.8<0,1,0>F g6<0,1,0>F { align1 };
/* Cy[2] */
-mul (1) g7.20<1>F g7.20<0,1,0>F g6.4<0,1,0>F { align1 };
+mul (1) g7.12<1>F g7.12<0,1,0>F g6.4<0,1,0>F { align1 };
/* src Cx[0], Cx[1] */
mov (8) m1<1>F g7<0,1,0>F { align1 };
/* mask Cx[2], Cx[3] */
-mov (1) m1.8<1>F g7.16<0,1,0>F { align1 };
-mov (1) m1.12<1>F g7.16<0,1,0>F { align1 };
+mov (1) m1.8<1>F g7.8<0,1,0>F { align1 };
+mov (1) m1.12<1>F g7.8<0,1,0>F { align1 };
/* src Cy[0], Cy[1] */
mov (8) m2<1>F g7.4<0,1,0>F { align1 };
/* mask Cy[2], Cy[3] */
-mov (1) m2.8<1>F g7.20<0,1,0>F { align1 };
-mov (1) m2.12<1>F g7.20<0,1,0>F { align1 };
+mov (1) m2.8<1>F g7.12<0,1,0>F { align1 };
+mov (1) m2.12<1>F g7.12<0,1,0>F { align1 };
/* src Co[0], Co[1] */
mov (8) m3<1>F g3<8,8,1>F { align1 };
/* mask Co[2], Co[3] */
-mov (1) m3.8<1>F g3.16<0,1,0>F { align1 };
-mov (1) m3.12<1>F g3.20<0,1,0>F { align1 };
+mov (1) m3.8<1>F g3.8<0,1,0>F { align1 };
+mov (1) m3.12<1>F g3.12<0,1,0>F { align1 };
send (8) 0 null g0<8,8,1>F urb 0 transpose used complete mlen 4 rlen 0 { align1 EOT };
nop;
diff --git a/src/exa_sf_mask_prog.h b/src/exa_sf_mask_prog.h
index cd7f460a..4e9114d6 100644
--- a/src/exa_sf_mask_prog.h
+++ b/src/exa_sf_mask_prog.h
@@ -3,17 +3,17 @@
{ 0x00600040, 0x20e077bd, 0x008d0080, 0x008d4060 },
{ 0x00000041, 0x20e077bd, 0x000000e0, 0x000000c0 },
{ 0x00000041, 0x20e477bd, 0x000000e4, 0x000000c4 },
- { 0x00000041, 0x20f077bd, 0x000000f0, 0x000000c0 },
- { 0x00000041, 0x20f477bd, 0x000000f4, 0x000000c4 },
+ { 0x00000041, 0x20e877bd, 0x000000e8, 0x000000c0 },
+ { 0x00000041, 0x20ec77bd, 0x000000ec, 0x000000c4 },
{ 0x00600001, 0x202003be, 0x000000e0, 0x00000000 },
- { 0x00000001, 0x202803be, 0x000000f0, 0x00000000 },
- { 0x00000001, 0x202c03be, 0x000000f0, 0x00000000 },
+ { 0x00000001, 0x202803be, 0x000000e8, 0x00000000 },
+ { 0x00000001, 0x202c03be, 0x000000e8, 0x00000000 },
{ 0x00600001, 0x204003be, 0x000000e4, 0x00000000 },
- { 0x00000001, 0x204803be, 0x000000f4, 0x00000000 },
- { 0x00000001, 0x204c03be, 0x000000f4, 0x00000000 },
+ { 0x00000001, 0x204803be, 0x000000ec, 0x00000000 },
+ { 0x00000001, 0x204c03be, 0x000000ec, 0x00000000 },
{ 0x00600001, 0x206003be, 0x008d0060, 0x00000000 },
- { 0x00000001, 0x206803be, 0x00000070, 0x00000000 },
- { 0x00000001, 0x206c03be, 0x00000074, 0x00000000 },
+ { 0x00000001, 0x206803be, 0x00000068, 0x00000000 },
+ { 0x00000001, 0x206c03be, 0x0000006c, 0x00000000 },
{ 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 },
{ 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
{ 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
diff --git a/src/exa_wm_maskca.g4a b/src/exa_wm_maskca.g4a
new file mode 100644
index 00000000..fa923f6c
--- /dev/null
+++ b/src/exa_wm_maskca.g4a
@@ -0,0 +1,202 @@
+/*
+ * This's for exa composite operation in no mask picture case.
+ * The simplest case is just sending what src picture has to dst picture.
+ * XXX: This is still experimental, and should be fixed to support multiple texture
+ * map, and conditional mul actions.
+ */
+
+/* I think this should be same as in g4a program for texture video,
+ as we also use 16-pixel dispatch. and SF scale in g3 is useful for us. */
+
+/* The initial payload of the thread is always g0.
+ * WM_URB (incoming URB entries) is g3
+ As mask texture coeffient needs extra setup urb starting from g4, we should
+ shift this location.
+
+ * X0_R is g4->g6
+ * X1_R is g5->g7
+ * Y0_R is g6->g8
+ * Y1_R is g7->g9
+
+ * X0: {ss0.x, ss0.x+1, ss0.x, ss0.x+1, ss1.x, ss1.x+1, ss1.x, ss1.x+y}
+ * Y0: {ss0.y, ss0.y, ss0.y+1, ss0.y+1, ss1.y, ss1.y, ss1.y+1, ss1.y+1}
+ * X1: {ss2.x, ss2.x+1, ss2.x, ss2.x+1, ss3.x, ss3.x+1, ss3.x, ss3.x+y}
+ * Y1: {ss2.y, ss2.y, ss2.y+1, ss2.y+1, ss3.y, ss3.y, ss3.y+1, ss3.y+1}
+ */
+
+/* multitexture program with src and mask texture */
+/* - load src texture */
+/* - load mask texture */
+/* - mul src.X with mask's alpha */
+/* - write out src.X */
+
+ /* Set up ss0.x coordinates*/
+mov (1) g6<1>F g1.8<0,1,0>UW { align1 };
+add (1) g6.4<1>F g1.8<0,1,0>UW 1UB { align1 };
+mov (1) g6.8<1>F g1.8<0,1,0>UW { align1 };
+add (1) g6.12<1>F g1.8<0,1,0>UW 1UB { align1 };
+ /* Set up ss0.y coordinates */
+mov (1) g8<1>F g1.10<0,1,0>UW { align1 };
+mov (1) g8.4<1>F g1.10<0,1,0>UW { align1 };
+add (1) g8.8<1>F g1.10<0,1,0>UW 1UB { align1 };
+add (1) g8.12<1>F g1.10<0,1,0>UW 1UB { align1 };
+ /* set up ss1.x coordinates */
+mov (1) g6.16<1>F g1.12<0,1,0>UW { align1 };
+add (1) g6.20<1>F g1.12<0,1,0>UW 1UB { align1 };
+mov (1) g6.24<1>F g1.12<0,1,0>UW { align1 };
+add (1) g6.28<1>F g1.12<0,1,0>UW 1UB { align1 };
+ /* set up ss1.y coordinates */
+mov (1) g8.16<1>F g1.14<0,1,0>UW { align1 };
+mov (1) g8.20<1>F g1.14<0,1,0>UW { align1 };
+add (1) g8.24<1>F g1.14<0,1,0>UW 1UB { align1 };
+add (1) g8.28<1>F g1.14<0,1,0>UW 1UB { align1 };
+ /* Set up ss2.x coordinates */
+mov (1) g7<1>F g1.16<0,1,0>UW { align1 };
+add (1) g7.4<1>F g1.16<0,1,0>UW 1UB { align1 };
+mov (1) g7.8<1>F g1.16<0,1,0>UW { align1 };
+add (1) g7.12<1>F g1.16<0,1,0>UW 1UB { align1 };
+ /* Set up ss2.y coordinates */
+mov (1) g9<1>F g1.18<0,1,0>UW { align1 };
+mov (1) g9.4<1>F g1.18<0,1,0>UW { align1 };
+add (1) g9.8<1>F g1.18<0,1,0>UW 1UB { align1 };
+add (1) g9.12<1>F g1.18<0,1,0>UW 1UB { align1 };
+ /* Set up ss3.x coordinates */
+mov (1) g7.16<1>F g1.20<0,1,0>UW { align1 };
+add (1) g7.20<1>F g1.20<0,1,0>UW 1UB { align1 };
+mov (1) g7.24<1>F g1.20<0,1,0>UW { align1 };
+add (1) g7.28<1>F g1.20<0,1,0>UW 1UB { align1 };
+ /* Set up ss3.y coordinates */
+mov (1) g9.16<1>F g1.22<0,1,0>UW { align1 };
+mov (1) g9.20<1>F g1.22<0,1,0>UW { align1 };
+add (1) g9.24<1>F g1.22<0,1,0>UW 1UB { align1 };
+add (1) g9.28<1>F g1.22<0,1,0>UW 1UB { align1 };
+
+ /* Now, map these screen space coordinates into texture coordinates. */
+/* This is for src texture */
+/* I don't want to change origin ssX coords, as it will be used later in mask */
+/* so store tex coords in g10, g11, g12, g13 */
+
+ /* subtract screen-space X origin of vertex 0. */
+add (8) g10<1>F g6<8,8,1>F -g1<0,1,0>F { align1 };
+add (8) g11<1>F g7<8,8,1>F -g1<0,1,0>F { align1 };
+ /* scale by texture X increment */
+/* Cx[0] */
+mul (8) g10<1>F g10<8,8,1>F g3<0,1,0>F { align1 };
+mul (8) g11<1>F g11<8,8,1>F g3<0,1,0>F { align1 };
+ /* add in texture X offset */
+/* Co[0] */
+add (8) g10<1>F g10<8,8,1>F g3.12<0,1,0>F { align1 };
+add (8) g11<1>F g11<8,8,1>F g3.12<0,1,0>F { align1 };
+ /* subtract screen-space Y origin of vertex 0. */
+add (8) g12<1>F g8<8,8,1>F -g1.4<0,1,0>F { align1 };
+add (8) g13<1>F g9<8,8,1>F -g1.4<0,1,0>F { align1 };
+ /* scale by texture Y increment */
+/* Cy[0] */
+mul (8) g12<1>F g12<8,8,1>F g3.4<0,1,0>F { align1 };
+mul (8) g13<1>F g13<8,8,1>F g3.4<0,1,0>F { align1 };
+ /* add in texture Y offset */
+/* Co[1] */
+add (8) g12<1>F g12<8,8,1>F g3.28<0,1,0>F { align1 };
+add (8) g13<1>F g13<8,8,1>F g3.28<0,1,0>F { align1 };
+
+/* prepare sampler read back gX register, which would be written back to output */
+
+/* use simd16 sampler, param 0 is u, param 1 is v. */
+/* 'payload' loading, assuming tex coord start from g4 */
+mov (8) m1<1>F g10<8,8,1>F { align1 };
+mov (8) m2<1>F g11<8,8,1>F { align1 }; /* param 0 u in m1, m2 */
+mov (8) m3<1>F g12<8,8,1>F { align1 };
+mov (8) m4<1>F g13<8,8,1>F { align1 }; /* param 1 v in m3, m4 */
+
+/* m0 will be copied with g0, as it contains send desc */
+/* emit sampler 'send' cmd */
+
+/* src texture readback: g14-g21 */
+send (16) 0 /* msg reg index */
+ g14<1>UW /* readback */
+ g0<8,8,1>UW /* copy to msg start reg*/
+ sampler (1,0,F) /* sampler message description,
+ (binding_table,sampler_index,datatype).
+ here(src->dst) we should use src_sampler and
+ src_surface */
+ mlen 5 rlen 8 { align1 }; /* required message len 5, readback len 8 */
+
+mov (8) g21<1>UD g21<8,8,1>UD { align1 }; /* wait sampler return */
+
+/* sampler mask texture, use g10, g11, g12, g13 */
+ /* subtract screen-space X origin of vertex 0. */
+add (8) g10<1>F g6<8,8,1>F -g1<0,1,0>F { align1 };
+add (8) g11<1>F g7<8,8,1>F -g1<0,1,0>F { align1 };
+ /* scale by texture X increment */
+/* Cx[2] */
+mul (8) g10<1>F g10<8,8,1>F g4<0,1,0>F { align1 };
+mul (8) g11<1>F g11<8,8,1>F g4<0,1,0>F { align1 };
+ /* add in texture X offset */
+/* Co[2] */
+add (8) g10<1>F g10<8,8,1>F g4.12<0,1,0>F { align1 };
+add (8) g11<1>F g11<8,8,1>F g4.12<0,1,0>F { align1 };
+ /* subtract screen-space Y origin of vertex 0. */
+add (8) g12<1>F g8<8,8,1>F -g1.4<0,1,0>F { align1 };
+add (8) g13<1>F g9<8,8,1>F -g1.4<0,1,0>F { align1 };
+ /* scale by texture Y increment */
+/* Cy[2] */
+mul (8) g12<1>F g12<8,8,1>F g4.4<0,1,0>F { align1 };
+mul (8) g13<1>F g13<8,8,1>F g4.4<0,1,0>F { align1 };
+ /* add in texture Y offset */
+/* Co[3] */
+add (8) g12<1>F g12<8,8,1>F g4.28<0,1,0>F { align1 };
+add (8) g13<1>F g13<8,8,1>F g4.28<0,1,0>F { align1 };
+
+mov (8) m1<1>F g10<8,8,1>F { align1 };
+mov (8) m2<1>F g11<8,8,1>F { align1 };
+mov (8) m3<1>F g12<8,8,1>F { align1 };
+mov (8) m4<1>F g13<8,8,1>F { align1 };
+
+/* mask sampler g22-g29 */
+/* binding_table (2), sampler (1) */
+send (16) 0 g22<1>UW g0<8,8,1>UW sampler (2,1,F) mlen 5 rlen 8 { align1 };
+mov (8) g29<1>UD g29<8,8,1>UD { align1 }; /* wait sampler return */
+
+/* mul mask's channel to src, then write out src */
+mul (8) g14<1>F g14<8,8,1>F g22<8,8,1>F { align1 };
+mul (8) g15<1>F g15<8,8,1>F g23<8,8,1>F { align1 };
+mul (8) g16<1>F g16<8,8,1>F g24<8,8,1>F { align1 };
+mul (8) g17<1>F g17<8,8,1>F g25<8,8,1>F { align1 };
+mul (8) g18<1>F g18<8,8,1>F g26<8,8,1>F { align1 };
+mul (8) g19<1>F g19<8,8,1>F g27<8,8,1>F { align1 };
+mul (8) g20<1>F g20<8,8,1>F g28<8,8,1>F { align1 };
+mul (8) g21<1>F g21<8,8,1>F g29<8,8,1>F { align1 };
+
+/* prepare data in m2-m5 for subspan(1,0), m6-m9 for subspan(3,2), then it's ready to write */
+mov (8) m2<1>F g14<8,8,1>F { align1 };
+mov (8) m3<1>F g16<8,8,1>F { align1 };
+mov (8) m4<1>F g18<8,8,1>F { align1 };
+mov (8) m5<1>F g20<8,8,1>F { align1 };
+mov (8) m6<1>F g15<8,8,1>F { align1 };
+mov (8) m7<1>F g17<8,8,1>F { align1 };
+mov (8) m8<1>F g19<8,8,1>F { align1 };
+mov (8) m9<1>F g21<8,8,1>F { align1 };
+
+/* m0, m1 are all direct passed by PS thread payload */
+mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable };
+
+/* write */
+send (16) 0 acc0<1>UW g0<8,8,1>UW write (
+ 0, /* binding_table */
+ 8, /* pixel scordboard clear, msg type simd16 single source */
+ 4, /* render target write */
+ 0 /* no write commit message */
+ )
+ mlen 10
+ rlen 0
+ { align1 EOT };
+
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
diff --git a/src/exa_wm_maskca_prog.h b/src/exa_wm_maskca_prog.h
new file mode 100644
index 00000000..d936412c
--- /dev/null
+++ b/src/exa_wm_maskca_prog.h
@@ -0,0 +1,95 @@
+ { 0x00000001, 0x20c0013d, 0x00000028, 0x00000000 },
+ { 0x00000040, 0x20c40d3d, 0x00000028, 0x00000001 },
+ { 0x00000001, 0x20c8013d, 0x00000028, 0x00000000 },
+ { 0x00000040, 0x20cc0d3d, 0x00000028, 0x00000001 },
+ { 0x00000001, 0x2100013d, 0x0000002a, 0x00000000 },
+ { 0x00000001, 0x2104013d, 0x0000002a, 0x00000000 },
+ { 0x00000040, 0x21080d3d, 0x0000002a, 0x00000001 },
+ { 0x00000040, 0x210c0d3d, 0x0000002a, 0x00000001 },
+ { 0x00000001, 0x20d0013d, 0x0000002c, 0x00000000 },
+ { 0x00000040, 0x20d40d3d, 0x0000002c, 0x00000001 },
+ { 0x00000001, 0x20d8013d, 0x0000002c, 0x00000000 },
+ { 0x00000040, 0x20dc0d3d, 0x0000002c, 0x00000001 },
+ { 0x00000001, 0x2110013d, 0x0000002e, 0x00000000 },
+ { 0x00000001, 0x2114013d, 0x0000002e, 0x00000000 },
+ { 0x00000040, 0x21180d3d, 0x0000002e, 0x00000001 },
+ { 0x00000040, 0x211c0d3d, 0x0000002e, 0x00000001 },
+ { 0x00000001, 0x20e0013d, 0x00000030, 0x00000000 },
+ { 0x00000040, 0x20e40d3d, 0x00000030, 0x00000001 },
+ { 0x00000001, 0x20e8013d, 0x00000030, 0x00000000 },
+ { 0x00000040, 0x20ec0d3d, 0x00000030, 0x00000001 },
+ { 0x00000001, 0x2120013d, 0x00000032, 0x00000000 },
+ { 0x00000001, 0x2124013d, 0x00000032, 0x00000000 },
+ { 0x00000040, 0x21280d3d, 0x00000032, 0x00000001 },
+ { 0x00000040, 0x212c0d3d, 0x00000032, 0x00000001 },
+ { 0x00000001, 0x20f0013d, 0x00000034, 0x00000000 },
+ { 0x00000040, 0x20f40d3d, 0x00000034, 0x00000001 },
+ { 0x00000001, 0x20f8013d, 0x00000034, 0x00000000 },
+ { 0x00000040, 0x20fc0d3d, 0x00000034, 0x00000001 },
+ { 0x00000001, 0x2130013d, 0x00000036, 0x00000000 },
+ { 0x00000001, 0x2134013d, 0x00000036, 0x00000000 },
+ { 0x00000040, 0x21380d3d, 0x00000036, 0x00000001 },
+ { 0x00000040, 0x213c0d3d, 0x00000036, 0x00000001 },
+ { 0x00600040, 0x214077bd, 0x008d00c0, 0x00004020 },
+ { 0x00600040, 0x216077bd, 0x008d00e0, 0x00004020 },
+ { 0x00600041, 0x214077bd, 0x008d0140, 0x00000060 },
+ { 0x00600041, 0x216077bd, 0x008d0160, 0x00000060 },
+ { 0x00600040, 0x214077bd, 0x008d0140, 0x0000006c },
+ { 0x00600040, 0x216077bd, 0x008d0160, 0x0000006c },
+ { 0x00600040, 0x218077bd, 0x008d0100, 0x00004024 },
+ { 0x00600040, 0x21a077bd, 0x008d0120, 0x00004024 },
+ { 0x00600041, 0x218077bd, 0x008d0180, 0x00000064 },
+ { 0x00600041, 0x21a077bd, 0x008d01a0, 0x00000064 },
+ { 0x00600040, 0x218077bd, 0x008d0180, 0x0000007c },
+ { 0x00600040, 0x21a077bd, 0x008d01a0, 0x0000007c },
+ { 0x00600001, 0x202003be, 0x008d0140, 0x00000000 },
+ { 0x00600001, 0x204003be, 0x008d0160, 0x00000000 },
+ { 0x00600001, 0x206003be, 0x008d0180, 0x00000000 },
+ { 0x00600001, 0x208003be, 0x008d01a0, 0x00000000 },
+ { 0x00800031, 0x21c01d29, 0x008d0000, 0x02580001 },
+ { 0x00600001, 0x22a00021, 0x008d02a0, 0x00000000 },
+ { 0x00600040, 0x214077bd, 0x008d00c0, 0x00004020 },
+ { 0x00600040, 0x216077bd, 0x008d00e0, 0x00004020 },
+ { 0x00600041, 0x214077bd, 0x008d0140, 0x00000080 },
+ { 0x00600041, 0x216077bd, 0x008d0160, 0x00000080 },
+ { 0x00600040, 0x214077bd, 0x008d0140, 0x0000008c },
+ { 0x00600040, 0x216077bd, 0x008d0160, 0x0000008c },
+ { 0x00600040, 0x218077bd, 0x008d0100, 0x00004024 },
+ { 0x00600040, 0x21a077bd, 0x008d0120, 0x00004024 },
+ { 0x00600041, 0x218077bd, 0x008d0180, 0x00000084 },
+ { 0x00600041, 0x21a077bd, 0x008d01a0, 0x00000084 },
+ { 0x00600040, 0x218077bd, 0x008d0180, 0x0000009c },
+ { 0x00600040, 0x21a077bd, 0x008d01a0, 0x0000009c },
+ { 0x00600001, 0x202003be, 0x008d0140, 0x00000000 },
+ { 0x00600001, 0x204003be, 0x008d0160, 0x00000000 },
+ { 0x00600001, 0x206003be, 0x008d0180, 0x00000000 },
+ { 0x00600001, 0x208003be, 0x008d01a0, 0x00000000 },
+ { 0x00800031, 0x22c01d29, 0x008d0000, 0x02580102 },
+ { 0x00600001, 0x23a00021, 0x008d03a0, 0x00000000 },
+ { 0x00600041, 0x21c077bd, 0x008d01c0, 0x008d02c0 },
+ { 0x00600041, 0x21e077bd, 0x008d01e0, 0x008d02e0 },
+ { 0x00600041, 0x220077bd, 0x008d0200, 0x008d0300 },
+ { 0x00600041, 0x222077bd, 0x008d0220, 0x008d0320 },
+ { 0x00600041, 0x224077bd, 0x008d0240, 0x008d0340 },
+ { 0x00600041, 0x226077bd, 0x008d0260, 0x008d0360 },
+ { 0x00600041, 0x228077bd, 0x008d0280, 0x008d0380 },
+ { 0x00600041, 0x22a077bd, 0x008d02a0, 0x008d03a0 },
+ { 0x00600001, 0x204003be, 0x008d01c0, 0x00000000 },
+ { 0x00600001, 0x206003be, 0x008d0200, 0x00000000 },
+ { 0x00600001, 0x208003be, 0x008d0240, 0x00000000 },
+ { 0x00600001, 0x20a003be, 0x008d0280, 0x00000000 },
+ { 0x00600001, 0x20c003be, 0x008d01e0, 0x00000000 },
+ { 0x00600001, 0x20e003be, 0x008d0220, 0x00000000 },
+ { 0x00600001, 0x210003be, 0x008d0260, 0x00000000 },
+ { 0x00600001, 0x212003be, 0x008d02a0, 0x00000000 },
+ { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 },
+ { 0x00800031, 0x24001d28, 0x008d0000, 0x85a04800 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
diff --git a/src/exa_wm_maskca_srcalpha.g4a b/src/exa_wm_maskca_srcalpha.g4a
new file mode 100644
index 00000000..e233968c
--- /dev/null
+++ b/src/exa_wm_maskca_srcalpha.g4a
@@ -0,0 +1,202 @@
+/*
+ * This's for exa composite operation in no mask picture case.
+ * The simplest case is just sending what src picture has to dst picture.
+ * XXX: This is still experimental, and should be fixed to support multiple texture
+ * map, and conditional mul actions.
+ */
+
+/* I think this should be same as in g4a program for texture video,
+ as we also use 16-pixel dispatch. and SF scale in g3 is useful for us. */
+
+/* The initial payload of the thread is always g0.
+ * WM_URB (incoming URB entries) is g3
+ As mask texture coeffient needs extra setup urb starting from g4, we should
+ shift this location.
+
+ * X0_R is g4->g6
+ * X1_R is g5->g7
+ * Y0_R is g6->g8
+ * Y1_R is g7->g9
+
+ * X0: {ss0.x, ss0.x+1, ss0.x, ss0.x+1, ss1.x, ss1.x+1, ss1.x, ss1.x+y}
+ * Y0: {ss0.y, ss0.y, ss0.y+1, ss0.y+1, ss1.y, ss1.y, ss1.y+1, ss1.y+1}
+ * X1: {ss2.x, ss2.x+1, ss2.x, ss2.x+1, ss3.x, ss3.x+1, ss3.x, ss3.x+y}
+ * Y1: {ss2.y, ss2.y, ss2.y+1, ss2.y+1, ss3.y, ss3.y, ss3.y+1, ss3.y+1}
+ */
+
+/* multitexture program with src and mask texture */
+/* - load src texture */
+/* - load mask texture */
+/* - mul src.X with mask's alpha */
+/* - write out src.X */
+
+ /* Set up ss0.x coordinates*/
+mov (1) g6<1>F g1.8<0,1,0>UW { align1 };
+add (1) g6.4<1>F g1.8<0,1,0>UW 1UB { align1 };
+mov (1) g6.8<1>F g1.8<0,1,0>UW { align1 };
+add (1) g6.12<1>F g1.8<0,1,0>UW 1UB { align1 };
+ /* Set up ss0.y coordinates */
+mov (1) g8<1>F g1.10<0,1,0>UW { align1 };
+mov (1) g8.4<1>F g1.10<0,1,0>UW { align1 };
+add (1) g8.8<1>F g1.10<0,1,0>UW 1UB { align1 };
+add (1) g8.12<1>F g1.10<0,1,0>UW 1UB { align1 };
+ /* set up ss1.x coordinates */
+mov (1) g6.16<1>F g1.12<0,1,0>UW { align1 };
+add (1) g6.20<1>F g1.12<0,1,0>UW 1UB { align1 };
+mov (1) g6.24<1>F g1.12<0,1,0>UW { align1 };
+add (1) g6.28<1>F g1.12<0,1,0>UW 1UB { align1 };
+ /* set up ss1.y coordinates */
+mov (1) g8.16<1>F g1.14<0,1,0>UW { align1 };
+mov (1) g8.20<1>F g1.14<0,1,0>UW { align1 };
+add (1) g8.24<1>F g1.14<0,1,0>UW 1UB { align1 };
+add (1) g8.28<1>F g1.14<0,1,0>UW 1UB { align1 };
+ /* Set up ss2.x coordinates */
+mov (1) g7<1>F g1.16<0,1,0>UW { align1 };
+add (1) g7.4<1>F g1.16<0,1,0>UW 1UB { align1 };
+mov (1) g7.8<1>F g1.16<0,1,0>UW { align1 };
+add (1) g7.12<1>F g1.16<0,1,0>UW 1UB { align1 };
+ /* Set up ss2.y coordinates */
+mov (1) g9<1>F g1.18<0,1,0>UW { align1 };
+mov (1) g9.4<1>F g1.18<0,1,0>UW { align1 };
+add (1) g9.8<1>F g1.18<0,1,0>UW 1UB { align1 };
+add (1) g9.12<1>F g1.18<0,1,0>UW 1UB { align1 };
+ /* Set up ss3.x coordinates */
+mov (1) g7.16<1>F g1.20<0,1,0>UW { align1 };
+add (1) g7.20<1>F g1.20<0,1,0>UW 1UB { align1 };
+mov (1) g7.24<1>F g1.20<0,1,0>UW { align1 };
+add (1) g7.28<1>F g1.20<0,1,0>UW 1UB { align1 };
+ /* Set up ss3.y coordinates */
+mov (1) g9.16<1>F g1.22<0,1,0>UW { align1 };
+mov (1) g9.20<1>F g1.22<0,1,0>UW { align1 };
+add (1) g9.24<1>F g1.22<0,1,0>UW 1UB { align1 };
+add (1) g9.28<1>F g1.22<0,1,0>UW 1UB { align1 };
+
+ /* Now, map these screen space coordinates into texture coordinates. */
+/* This is for src texture */
+/* I don't want to change origin ssX coords, as it will be used later in mask */
+/* so store tex coords in g10, g11, g12, g13 */
+
+ /* subtract screen-space X origin of vertex 0. */
+add (8) g10<1>F g6<8,8,1>F -g1<0,1,0>F { align1 };
+add (8) g11<1>F g7<8,8,1>F -g1<0,1,0>F { align1 };
+ /* scale by texture X increment */
+/* Cx[0] */
+mul (8) g10<1>F g10<8,8,1>F g3<0,1,0>F { align1 };
+mul (8) g11<1>F g11<8,8,1>F g3<0,1,0>F { align1 };
+ /* add in texture X offset */
+/* Co[0] */
+add (8) g10<1>F g10<8,8,1>F g3.12<0,1,0>F { align1 };
+add (8) g11<1>F g11<8,8,1>F g3.12<0,1,0>F { align1 };
+ /* subtract screen-space Y origin of vertex 0. */
+add (8) g12<1>F g8<8,8,1>F -g1.4<0,1,0>F { align1 };
+add (8) g13<1>F g9<8,8,1>F -g1.4<0,1,0>F { align1 };
+ /* scale by texture Y increment */
+/* Cy[0] */
+mul (8) g12<1>F g12<8,8,1>F g3.4<0,1,0>F { align1 };
+mul (8) g13<1>F g13<8,8,1>F g3.4<0,1,0>F { align1 };
+ /* add in texture Y offset */
+/* Co[1] */
+add (8) g12<1>F g12<8,8,1>F g3.28<0,1,0>F { align1 };
+add (8) g13<1>F g13<8,8,1>F g3.28<0,1,0>F { align1 };
+
+/* prepare sampler read back gX register, which would be written back to output */
+
+/* use simd16 sampler, param 0 is u, param 1 is v. */
+/* 'payload' loading, assuming tex coord start from g4 */
+mov (8) m1<1>F g10<8,8,1>F { align1 };
+mov (8) m2<1>F g11<8,8,1>F { align1 }; /* param 0 u in m1, m2 */
+mov (8) m3<1>F g12<8,8,1>F { align1 };
+mov (8) m4<1>F g13<8,8,1>F { align1 }; /* param 1 v in m3, m4 */
+
+/* m0 will be copied with g0, as it contains send desc */
+/* emit sampler 'send' cmd */
+
+/* src texture readback: g14-g21 */
+send (16) 0 /* msg reg index */
+ g14<1>UW /* readback */
+ g0<8,8,1>UW /* copy to msg start reg*/
+ sampler (1,0,F) /* sampler message description,
+ (binding_table,sampler_index,datatype).
+ here(src->dst) we should use src_sampler and
+ src_surface */
+ mlen 5 rlen 8 { align1 }; /* required message len 5, readback len 8 */
+
+mov (8) g21<1>UD g21<8,8,1>UD { align1 }; /* wait sampler return */
+
+/* sampler mask texture, use g10, g11, g12, g13 */
+ /* subtract screen-space X origin of vertex 0. */
+add (8) g10<1>F g6<8,8,1>F -g1<0,1,0>F { align1 };
+add (8) g11<1>F g7<8,8,1>F -g1<0,1,0>F { align1 };
+ /* scale by texture X increment */
+/* Cx[2] */
+mul (8) g10<1>F g10<8,8,1>F g4<0,1,0>F { align1 };
+mul (8) g11<1>F g11<8,8,1>F g4<0,1,0>F { align1 };
+ /* add in texture X offset */
+/* Co[2] */
+add (8) g10<1>F g10<8,8,1>F g4.12<0,1,0>F { align1 };
+add (8) g11<1>F g11<8,8,1>F g4.12<0,1,0>F { align1 };
+ /* subtract screen-space Y origin of vertex 0. */
+add (8) g12<1>F g8<8,8,1>F -g1.4<0,1,0>F { align1 };
+add (8) g13<1>F g9<8,8,1>F -g1.4<0,1,0>F { align1 };
+ /* scale by texture Y increment */
+/* Cy[2] */
+mul (8) g12<1>F g12<8,8,1>F g4.4<0,1,0>F { align1 };
+mul (8) g13<1>F g13<8,8,1>F g4.4<0,1,0>F { align1 };
+ /* add in texture Y offset */
+/* Co[3] */
+add (8) g12<1>F g12<8,8,1>F g4.28<0,1,0>F { align1 };
+add (8) g13<1>F g13<8,8,1>F g4.28<0,1,0>F { align1 };
+
+mov (8) m1<1>F g10<8,8,1>F { align1 };
+mov (8) m2<1>F g11<8,8,1>F { align1 };
+mov (8) m3<1>F g12<8,8,1>F { align1 };
+mov (8) m4<1>F g13<8,8,1>F { align1 };
+
+/* mask sampler g22-g29 */
+/* binding_table (2), sampler (1) */
+send (16) 0 g22<1>UW g0<8,8,1>UW sampler (2,1,F) mlen 5 rlen 8 { align1 };
+mov (8) g29<1>UD g29<8,8,1>UD { align1 }; /* wait sampler return */
+
+/* src channel has no more use, src.A * mask.C */
+mul (8) g14<1>F g22<8,8,1>F g20<8,8,1>F { align1 };
+mul (8) g15<1>F g23<8,8,1>F g21<8,8,1>F { align1 };
+mul (8) g16<1>F g24<8,8,1>F g20<8,8,1>F { align1 };
+mul (8) g17<1>F g25<8,8,1>F g21<8,8,1>F { align1 };
+mul (8) g18<1>F g26<8,8,1>F g20<8,8,1>F { align1 };
+mul (8) g19<1>F g27<8,8,1>F g21<8,8,1>F { align1 };
+mul (8) g20<1>F g28<8,8,1>F g20<8,8,1>F { align1 };
+mul (8) g21<1>F g29<8,8,1>F g21<8,8,1>F { align1 };
+
+/* prepare data in m2-m5 for subspan(1,0), m6-m9 for subspan(3,2), then it's ready to write */
+mov (8) m2<1>F g14<8,8,1>F { align1 };
+mov (8) m3<1>F g16<8,8,1>F { align1 };
+mov (8) m4<1>F g18<8,8,1>F { align1 };
+mov (8) m5<1>F g20<8,8,1>F { align1 };
+mov (8) m6<1>F g15<8,8,1>F { align1 };
+mov (8) m7<1>F g17<8,8,1>F { align1 };
+mov (8) m8<1>F g19<8,8,1>F { align1 };
+mov (8) m9<1>F g21<8,8,1>F { align1 };
+
+/* m0, m1 are all direct passed by PS thread payload */
+mov (8) m1<1>UD g1<8,8,1>UD { align1 mask_disable };
+
+/* write */
+send (16) 0 acc0<1>UW g0<8,8,1>UW write (
+ 0, /* binding_table */
+ 8, /* pixel scordboard clear, msg type simd16 single source */
+ 4, /* render target write */
+ 0 /* no write commit message */
+ )
+ mlen 10
+ rlen 0
+ { align1 EOT };
+
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
+nop;
diff --git a/src/exa_wm_maskca_srcalpha_prog.h b/src/exa_wm_maskca_srcalpha_prog.h
new file mode 100644
index 00000000..d83b119f
--- /dev/null
+++ b/src/exa_wm_maskca_srcalpha_prog.h
@@ -0,0 +1,95 @@
+ { 0x00000001, 0x20c0013d, 0x00000028, 0x00000000 },
+ { 0x00000040, 0x20c40d3d, 0x00000028, 0x00000001 },
+ { 0x00000001, 0x20c8013d, 0x00000028, 0x00000000 },
+ { 0x00000040, 0x20cc0d3d, 0x00000028, 0x00000001 },
+ { 0x00000001, 0x2100013d, 0x0000002a, 0x00000000 },
+ { 0x00000001, 0x2104013d, 0x0000002a, 0x00000000 },
+ { 0x00000040, 0x21080d3d, 0x0000002a, 0x00000001 },
+ { 0x00000040, 0x210c0d3d, 0x0000002a, 0x00000001 },
+ { 0x00000001, 0x20d0013d, 0x0000002c, 0x00000000 },
+ { 0x00000040, 0x20d40d3d, 0x0000002c, 0x00000001 },
+ { 0x00000001, 0x20d8013d, 0x0000002c, 0x00000000 },
+ { 0x00000040, 0x20dc0d3d, 0x0000002c, 0x00000001 },
+ { 0x00000001, 0x2110013d, 0x0000002e, 0x00000000 },
+ { 0x00000001, 0x2114013d, 0x0000002e, 0x00000000 },
+ { 0x00000040, 0x21180d3d, 0x0000002e, 0x00000001 },
+ { 0x00000040, 0x211c0d3d, 0x0000002e, 0x00000001 },
+ { 0x00000001, 0x20e0013d, 0x00000030, 0x00000000 },
+ { 0x00000040, 0x20e40d3d, 0x00000030, 0x00000001 },
+ { 0x00000001, 0x20e8013d, 0x00000030, 0x00000000 },
+ { 0x00000040, 0x20ec0d3d, 0x00000030, 0x00000001 },
+ { 0x00000001, 0x2120013d, 0x00000032, 0x00000000 },
+ { 0x00000001, 0x2124013d, 0x00000032, 0x00000000 },
+ { 0x00000040, 0x21280d3d, 0x00000032, 0x00000001 },
+ { 0x00000040, 0x212c0d3d, 0x00000032, 0x00000001 },
+ { 0x00000001, 0x20f0013d, 0x00000034, 0x00000000 },
+ { 0x00000040, 0x20f40d3d, 0x00000034, 0x00000001 },
+ { 0x00000001, 0x20f8013d, 0x00000034, 0x00000000 },
+ { 0x00000040, 0x20fc0d3d, 0x00000034, 0x00000001 },
+ { 0x00000001, 0x2130013d, 0x00000036, 0x00000000 },
+ { 0x00000001, 0x2134013d, 0x00000036, 0x00000000 },
+ { 0x00000040, 0x21380d3d, 0x00000036, 0x00000001 },
+ { 0x00000040, 0x213c0d3d, 0x00000036, 0x00000001 },
+ { 0x00600040, 0x214077bd, 0x008d00c0, 0x00004020 },
+ { 0x00600040, 0x216077bd, 0x008d00e0, 0x00004020 },
+ { 0x00600041, 0x214077bd, 0x008d0140, 0x00000060 },
+ { 0x00600041, 0x216077bd, 0x008d0160, 0x00000060 },
+ { 0x00600040, 0x214077bd, 0x008d0140, 0x0000006c },
+ { 0x00600040, 0x216077bd, 0x008d0160, 0x0000006c },
+ { 0x00600040, 0x218077bd, 0x008d0100, 0x00004024 },
+ { 0x00600040, 0x21a077bd, 0x008d0120, 0x00004024 },
+ { 0x00600041, 0x218077bd, 0x008d0180, 0x00000064 },
+ { 0x00600041, 0x21a077bd, 0x008d01a0, 0x00000064 },
+ { 0x00600040, 0x218077bd, 0x008d0180, 0x0000007c },
+ { 0x00600040, 0x21a077bd, 0x008d01a0, 0x0000007c },
+ { 0x00600001, 0x202003be, 0x008d0140, 0x00000000 },
+ { 0x00600001, 0x204003be, 0x008d0160, 0x00000000 },
+ { 0x00600001, 0x206003be, 0x008d0180, 0x00000000 },
+ { 0x00600001, 0x208003be, 0x008d01a0, 0x00000000 },
+ { 0x00800031, 0x21c01d29, 0x008d0000, 0x02580001 },
+ { 0x00600001, 0x22a00021, 0x008d02a0, 0x00000000 },
+ { 0x00600040, 0x214077bd, 0x008d00c0, 0x00004020 },
+ { 0x00600040, 0x216077bd, 0x008d00e0, 0x00004020 },
+ { 0x00600041, 0x214077bd, 0x008d0140, 0x00000080 },
+ { 0x00600041, 0x216077bd, 0x008d0160, 0x00000080 },
+ { 0x00600040, 0x214077bd, 0x008d0140, 0x0000008c },
+ { 0x00600040, 0x216077bd, 0x008d0160, 0x0000008c },
+ { 0x00600040, 0x218077bd, 0x008d0100, 0x00004024 },
+ { 0x00600040, 0x21a077bd, 0x008d0120, 0x00004024 },
+ { 0x00600041, 0x218077bd, 0x008d0180, 0x00000084 },
+ { 0x00600041, 0x21a077bd, 0x008d01a0, 0x00000084 },
+ { 0x00600040, 0x218077bd, 0x008d0180, 0x0000009c },
+ { 0x00600040, 0x21a077bd, 0x008d01a0, 0x0000009c },
+ { 0x00600001, 0x202003be, 0x008d0140, 0x00000000 },
+ { 0x00600001, 0x204003be, 0x008d0160, 0x00000000 },
+ { 0x00600001, 0x206003be, 0x008d0180, 0x00000000 },
+ { 0x00600001, 0x208003be, 0x008d01a0, 0x00000000 },
+ { 0x00800031, 0x22c01d29, 0x008d0000, 0x02580102 },
+ { 0x00600001, 0x23a00021, 0x008d03a0, 0x00000000 },
+ { 0x00600041, 0x21c077bd, 0x008d02c0, 0x008d0280 },
+ { 0x00600041, 0x21e077bd, 0x008d02e0, 0x008d02a0 },
+ { 0x00600041, 0x220077bd, 0x008d0300, 0x008d0280 },
+ { 0x00600041, 0x222077bd, 0x008d0320, 0x008d02a0 },
+ { 0x00600041, 0x224077bd, 0x008d0340, 0x008d0280 },
+ { 0x00600041, 0x226077bd, 0x008d0360, 0x008d02a0 },
+ { 0x00600041, 0x228077bd, 0x008d0380, 0x008d0280 },
+ { 0x00600041, 0x22a077bd, 0x008d03a0, 0x008d02a0 },
+ { 0x00600001, 0x204003be, 0x008d01c0, 0x00000000 },
+ { 0x00600001, 0x206003be, 0x008d0200, 0x00000000 },
+ { 0x00600001, 0x208003be, 0x008d0240, 0x00000000 },
+ { 0x00600001, 0x20a003be, 0x008d0280, 0x00000000 },
+ { 0x00600001, 0x20c003be, 0x008d01e0, 0x00000000 },
+ { 0x00600001, 0x20e003be, 0x008d0220, 0x00000000 },
+ { 0x00600001, 0x210003be, 0x008d0260, 0x00000000 },
+ { 0x00600001, 0x212003be, 0x008d02a0, 0x00000000 },
+ { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 },
+ { 0x00800031, 0x24001d28, 0x008d0000, 0x85a04800 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
diff --git a/src/i810.h b/src/i810.h
index 852a64a9..614de52c 100644
--- a/src/i810.h
+++ b/src/i810.h
@@ -62,8 +62,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "common.h"
#define I810_VERSION 4000
-#define I810_NAME "I810"
-#define I810_DRIVER_NAME "i810"
+#define I810_NAME "intel"
+#define I810_DRIVER_NAME "intel"
+#define I810_LEGACY_DRIVER_NAME "i810"
/* HWMC Surfaces */
#define I810_MAX_SURFACES 7
diff --git a/src/i810_driver.c b/src/i810_driver.c
index ab3a2008..b32e07c2 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -386,6 +386,21 @@ int I830EntityIndex = -1;
static MODULESETUPPROTO(i810Setup);
+static XF86ModuleVersionInfo intelVersRec = {
+ "intel",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ INTEL_VERSION_MAJOR, INTEL_VERSION_MINOR, INTEL_VERSION_PATCH,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0, 0, 0, 0}
+};
+
+_X_EXPORT XF86ModuleData intelModuleData = { &intelVersRec, i810Setup, NULL };
+
static XF86ModuleVersionInfo i810VersRec = {
"i810",
MODULEVENDORSTRING,
@@ -523,7 +538,9 @@ I810Probe(DriverPtr drv, int flags)
* driver, and return if there are none.
*/
if ((numDevSections =
- xf86MatchDevice(I810_DRIVER_NAME, &devSections)) <= 0) {
+ xf86MatchDevice(I810_DRIVER_NAME, &devSections)) <= 0 &&
+ (numDevSections =
+ xf86MatchDevice(I810_LEGACY_DRIVER_NAME, &devSections)) <= 0) {
return FALSE;
}
diff --git a/src/i810_reg.h b/src/i810_reg.h
index 68cce930..d63be025 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -299,6 +299,20 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define VCLK_DIVISOR_VGA0 0x6000
#define VCLK_DIVISOR_VGA1 0x6004
#define VCLK_POST_DIV 0x6010
+/** Selects a post divisor of 4 instead of 2. */
+# define VGA1_PD_P2_DIV_4 (1 << 15)
+/** Overrides the p2 post divisor field */
+# define VGA1_PD_P1_DIV_2 (1 << 13)
+# define VGA1_PD_P1_SHIFT 8
+/** P1 value is 2 greater than this field */
+# define VGA1_PD_P1_MASK (0x1f << 8)
+/** Selects a post divisor of 4 instead of 2. */
+# define VGA0_PD_P2_DIV_4 (1 << 7)
+/** Overrides the p2 post divisor field */
+# define VGA0_PD_P1_DIV_2 (1 << 5)
+# define VGA0_PD_P1_SHIFT 0
+/** P1 value is 2 greater than this field */
+# define VGA0_PD_P1_MASK (0x1f << 0)
#define POST_DIV_SELECT 0x70
#define POST_DIV_1 0x00
@@ -488,6 +502,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define I915G_FENCE_SIZE_32M 0x00000500
#define I915G_FENCE_SIZE_64M 0x00000600
#define I915G_FENCE_SIZE_128M 0x00000700
+#define I965_FENCE_X_MAJOR 0x00000000
+#define I965_FENCE_Y_MAJOR 0x00000002
#define FENCE_PITCH_1 0x00000000
#define FENCE_PITCH_2 0x00000010
#define FENCE_PITCH_4 0x00000020
@@ -845,9 +861,18 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
+/**
+ * The i830 generation, in DAC/serial mode, defines p1 as two plus this
+ * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
+ */
+# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
+/**
+ * The i830 generation, in LVDS mode, defines P1 as the bit number set within
+ * this field (only one bit may be set).
+ */
+# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
# define DPLL_FPA01_P1_POST_DIV_SHIFT 16
# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */
-# define DPLL_FPA01_P1_POS_DIV_MASK_I830 0x001f0000 /* i830 */
# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
# define PLL_REF_INPUT_DREFCLK (0 << 13)
# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
@@ -1690,6 +1715,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define PIPEACONF_ENABLE (1<<31)
#define PIPEACONF_DISABLE 0
#define PIPEACONF_DOUBLE_WIDE (1<<30)
+#define I965_PIPECONF_ACTIVE (1<<30)
#define PIPEACONF_SINGLE_WIDE 0
#define PIPEACONF_PIPE_UNLOCKED 0
#define PIPEACONF_PIPE_LOCKED (1<<25)
@@ -1848,6 +1874,19 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define I852_GME 0x2
#define I852_GM 0x5
+#define I915_GCFGC 0xf0
+#define I915_LOW_FREQUENCY_ENABLE (1 << 7)
+#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
+#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4)
+#define I915_DISPLAY_CLOCK_MASK (7 << 4)
+
+#define I855_HPLLCC 0xc0
+#define I855_CLOCK_CONTROL_MASK (3 << 0)
+#define I855_CLOCK_133_200 (0 << 0)
+#define I855_CLOCK_100_200 (1 << 0)
+#define I855_CLOCK_100_133 (2 << 0)
+#define I855_CLOCK_166_250 (3 << 0)
+
/* BLT commands */
#define COLOR_BLT_CMD ((2<<29)|(0x40<<22)|(0x3))
#define COLOR_BLT_WRITE_ALPHA (1<<21)
@@ -1867,6 +1906,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define SRC_COPY_BLT_WRITE_ALPHA (1<<21)
#define SRC_COPY_BLT_WRITE_RGB (1<<20)
+#define XY_PAT_BLT_IMMEDIATE ((2<<29)|(0x72<<22))
+
#define XY_MONO_PAT_BLT_CMD ((0x2<<29)|(0x52<<22)|0x7)
#define XY_MONO_PAT_VERT_SEED ((1<<10)|(1<<9)|(1<<8))
#define XY_MONO_PAT_HORT_SEED ((1<<14)|(1<<13)|(1<<12))
diff --git a/src/i830.h b/src/i830.h
index 42933f92..08d9e3ed 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -58,8 +58,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xf86int10.h"
#include "vbe.h"
#include "vgaHW.h"
-#include "i830_xf86Crtc.h"
-#include "i830_randr.h"
+#include "xf86Crtc.h"
+#include "xf86RandR12.h"
#ifdef XF86DRI
#include "xf86drm.h"
@@ -113,30 +113,52 @@ typedef CARD8(*I830ReadIndexedByteFunc)(I830Ptr pI830, IOADDRESS addr,
typedef void (*I830WriteByteFunc)(I830Ptr pI830, IOADDRESS addr, CARD8 value);
typedef CARD8(*I830ReadByteFunc)(I830Ptr pI830, IOADDRESS addr);
-/* Linear region allocated in framebuffer. */
-typedef struct _I830MemPool *I830MemPoolPtr;
-typedef struct _I830MemRange *I830MemRangePtr;
-typedef struct _I830MemRange {
- long Start;
- long End;
- long Size;
- unsigned long Physical;
- unsigned long Offset; /* Offset of AGP-allocated portion */
- unsigned long Alignment;
- int Key;
- I830MemPoolPtr Pool;
-} I830MemRange;
-
-typedef struct _I830MemPool {
- I830MemRange Total;
- I830MemRange Free;
- I830MemRange Fixed;
- I830MemRange Allocated;
-} I830MemPool;
+/** Record of a linear allocation in the aperture. */
+typedef struct _i830_memory i830_memory;
+struct _i830_memory {
+ /** Offset of the allocation in card VM */
+ unsigned long offset;
+ /** End of the allocation in card VM */
+ unsigned long end;
+ /**
+ * Requested size of the allocation: doesn't count padding.
+ *
+ * Any bound memory will cover offset to (offset + size).
+ */
+ unsigned long size;
+ /**
+ * Physical (or more properly, bus) address of the allocation.
+ * Only set if requested during allocation.
+ */
+ unsigned long bus_addr;
+ /** AGP memory handle */
+ int key;
+ /**
+ * Whether or not the AGP memory (if any) is currently bound.
+ */
+ Bool bound;
+ /**
+ * Offset that the AGP-allocated memory (if any) is to be bound to.
+ *
+ * This is either @offset or pI830->stolen_size
+ */
+ unsigned long agp_offset;
+
+ /** Description of the allocation, for logging */
+ char *name;
+
+ /** @{
+ * Memory allocator linked list pointers
+ */
+ i830_memory *next;
+ i830_memory *prev;
+ /** @} */
+
+};
typedef struct {
int tail_mask;
- I830MemRange mem;
+ i830_memory *mem;
unsigned char *virtual_start;
int head;
int tail;
@@ -144,10 +166,6 @@ typedef struct {
} I830RingBuffer;
typedef struct {
- unsigned int Fence[FENCE_NEW_NR * 2];
-} I830RegRec, *I830RegPtr;
-
-typedef struct {
int lastInstance;
int refCount;
ScrnInfoPtr pScrn_1;
@@ -206,8 +224,8 @@ typedef struct _I830CrtcPrivateRec {
ExaOffscreenArea *rotate_mem_exa;
#endif
- I830MemRange cursor_mem;
- I830MemRange cursor_mem_argb;
+ i830_memory *cursor_mem;
+ i830_memory *cursor_mem_argb;
} I830CrtcPrivateRec, *I830CrtcPrivatePtr;
#define I830CrtcPrivate(c) ((I830CrtcPrivatePtr) (c)->driver_private)
@@ -232,21 +250,6 @@ enum last_3d {
LAST_3D_ROTATION
};
-#if 0
-typedef struct _I830PipeRec {
- Bool enabled;
- int x;
- int y;
- Bool cursorInRange;
- Bool cursorShown;
- DisplayModeRec curMode;
- DisplayModeRec desiredMode;
-#ifdef RANDR_12_INTERFACE
- RRCrtcPtr randr_crtc;
-#endif
-} I830PipeRec, *I830PipePtr;
-#endif
-
typedef struct _I830Rec {
unsigned char *MMIOBase;
unsigned char *FbBase;
@@ -264,50 +267,41 @@ typedef struct _I830Rec {
/* These are set in PreInit and never changed. */
long FbMapSize;
- long TotalVideoRam;
- I830MemRange StolenMemory; /* pre-allocated memory */
- /* These change according to what has been allocated. */
- long FreeMemory;
- I830MemRange MemoryAperture;
- I830MemPool StolenPool;
- long allocatedMemory;
+ i830_memory *memory_list; /**< Linked list of video memory allocations */
+ long stolen_size; /**< bytes of pre-bound stolen memory */
+ int gtt_acquired; /**< whether we currently own the AGP */
- /* Regions allocated either from the above pools, or from agpgart. */
- /* for single and dual head configurations */
- I830MemRange FrontBuffer;
- I830MemRange FrontBuffer2;
- I830MemRange Scratch;
- I830MemRange Scratch2;
+ i830_memory *front_buffer;
+ i830_memory *front_buffer_2;
+ i830_memory *xaa_scratch;
+ i830_memory *xaa_scratch_2;
#ifdef I830_USE_EXA
- I830MemRange Offscreen;
- I830MemRange EXAStateMem; /* specific exa state for G965 */
+ i830_memory *exa_offscreen;
+ i830_memory *exa_965_state;
#endif
/* Regions allocated either from the above pools, or from agpgart. */
I830RingBuffer *LpRing;
-#if REMAP_RESERVED
- I830MemRange Dummy;
-#endif
-
#ifdef I830_XV
/* For Xvideo */
- I830MemRange *OverlayMem;
- I830MemRange LinearMem;
+ i830_memory *overlay_regs;
+ i830_memory *xaa_linear;
#endif
unsigned long LinearAlloc;
XF86ModReqInfo shadowReq; /* to test for later libshadow */
Rotation rotation;
- int displayWidth;
void (*PointerMoved)(int, int, int);
CreateScreenResourcesProcPtr CreateScreenResources;
int *used3D;
- I830MemRange ContextMem;
+ i830_memory *logical_context;
#ifdef XF86DRI
- I830MemRange BackBuffer;
- I830MemRange DepthBuffer;
- I830MemRange TexMem;
+ i830_memory *back_buffer;
+ i830_memory *depth_buffer;
+ i830_memory *textures; /**< Compatibility texture memory */
+ i830_memory *memory_manager; /**< DRI memory manager aperture */
+
int TexGranularity;
int drmMinor;
Bool have3DWindows;
@@ -345,13 +339,21 @@ typedef struct _I830Rec {
unsigned int BR[20];
- int GttBound;
-
unsigned char **ScanlineColorExpandBuffers;
int NumScanlineColorExpandBuffers;
int nextColorExpandBuf;
- I830RegRec ModeReg;
+ /**
+ * Values to be programmed into the fence registers.
+ *
+ * Pre-965, this is a list of FENCE_NR (8) CARD32 registers that
+ * contain their start, size, and pitch. On the 965, it is a list of
+ * FENCE_NEW_NR CARD32s for the start and pitch fields (low 32 bits) of
+ * the fence registers followed by FENCE_NEW_NR CARD32s for the end fields
+ * (high 32 bits) of the fence registers.
+ */
+ unsigned int fence[FENCE_NEW_NR * 2];
+ unsigned int next_fence;
Bool useEXA;
Bool noAccel;
@@ -422,7 +424,6 @@ typedef struct _I830Rec {
/* Broken-out options. */
OptionInfoPtr Options;
- /* Stolen memory support */
Bool StolenOnly;
Bool swfSaved;
@@ -514,7 +515,6 @@ typedef struct _I830Rec {
} I830Rec;
#define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
-#define I830REGPTR(p) (&(I830PTR(p)->ModeReg))
#define I830_SELECT_FRONT 0
#define I830_SELECT_BACK 1
@@ -536,9 +536,6 @@ extern void I830SelectBuffer(ScrnInfoPtr pScrn, int buffer);
extern void I830RefreshRing(ScrnInfoPtr pScrn);
extern void I830EmitFlush(ScrnInfoPtr pScrn);
-extern Bool I830DGAReInit(ScreenPtr pScreen);
-extern Bool I830DGAInit(ScreenPtr pScreen);
-
#ifdef I830_XV
extern void I830InitVideo(ScreenPtr pScreen);
extern void i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on);
@@ -546,9 +543,6 @@ extern void i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on);
#ifdef XF86DRI
extern Bool I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags);
-extern Bool I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags);
-extern Bool I830AllocateDepthBuffer(ScrnInfoPtr pScrn, const int flags);
-extern Bool I830AllocateTextureMemory(ScrnInfoPtr pScrn, const int flags);
extern void I830SetupMemoryTiling(ScrnInfoPtr pScrn);
extern Bool I830DRIScreenInit(ScreenPtr pScreen);
extern Bool I830CheckDRIAvailable(ScrnInfoPtr pScrn);
@@ -579,32 +573,28 @@ extern void I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
extern void I830SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
int w, int h);
-extern void I830ResetAllocations(ScrnInfoPtr pScrn, const int flags);
+Bool i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset,
+ unsigned long size);
+void i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity,
+ const char *prefix);
+void i830_reset_allocations(ScrnInfoPtr pScrn);
+void i830_free_3d_memory(ScrnInfoPtr pScrn);
+void i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem);
extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn);
-extern long I830GetExcessMemoryAllocations(ScrnInfoPtr pScrn);
-extern Bool I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags);
-extern Bool I830DoPoolAllocation(ScrnInfoPtr pScrn, I830MemPool *pool);
-extern Bool I830FixupOffsets(ScrnInfoPtr pScrn);
-extern Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
-extern Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
-extern unsigned long I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result,
- I830MemPool *pool, long size,
- unsigned long alignment, int flags);
-extern void I830FreeVidMem(ScrnInfoPtr pScrn, I830MemRange *range);
-
-extern void I830PrintAllRegisters(I830RegPtr i830Reg);
-extern void I830ReadAllRegisters(I830Ptr pI830, I830RegPtr i830Reg);
-
-extern void I830ChangeFrontbuffer(ScrnInfoPtr pScrn,int buffer);
+Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn);
+Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn);
+
extern Bool I830IsPrimary(ScrnInfoPtr pScrn);
-extern Bool I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem);
extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg,
char *name);
/* return a mask of output indices matching outputs against type_mask */
int i830_output_clones (ScrnInfoPtr pScrn, int type_mask);
+/* i830_bios.c */
+DisplayModePtr i830_bios_get_panel_mode(ScrnInfoPtr pScrn);
+
/* i830_display.c */
Bool
i830PipeHasType (xf86CrtcPtr crtc, int type);
@@ -622,6 +612,9 @@ extern void i830MarkSync(ScrnInfoPtr pScrn);
extern void i830WaitSync(ScrnInfoPtr pScrn);
/* i830_memory.c */
+Bool i830_bind_all_memory(ScrnInfoPtr pScrn);
+Bool i830_unbind_all_memory(ScrnInfoPtr pScrn);
+
Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
#ifdef I830_USE_XAA
@@ -671,23 +664,8 @@ extern const int I830PatternROP[16];
extern const int I830CopyROP[16];
/* Flags for memory allocation function */
-#define FROM_ANYWHERE 0x00000000
-#define FROM_POOL_ONLY 0x00000001
-#define FROM_NEW_ONLY 0x00000002
-#define FROM_MASK 0x0000000f
-
-#define ALLOCATE_AT_TOP 0x00000010
-#define ALLOCATE_AT_BOTTOM 0x00000020
-#define FORCE_GAPS 0x00000040
-
-#define NEED_PHYSICAL_ADDR 0x00000100
-#define ALIGN_BOTH_ENDS 0x00000200
-#define FORCE_LOW 0x00000400
-
-#define ALLOC_NO_TILING 0x00001000
-#define ALLOC_INITIAL 0x00002000
-
-#define ALLOCATE_DRY_RUN 0x80000000
+#define NEED_PHYSICAL_ADDR 0x00000001
+#define ALIGN_BOTH_ENDS 0x00000002
/* Chipset registers for VIDEO BIOS memory RW access */
#define _855_DRAM_RW_CONTROL 0x58
diff --git a/src/i830_accel.c b/src/i830_accel.c
index db3168a8..49a9c134 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -117,7 +117,7 @@ I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis)
ring->space = ring->head - (ring->tail + 8);
if (ring->space < 0)
- ring->space += ring->mem.Size;
+ ring->space += ring->mem->size;
iters++;
now = GetTimeInMillis();
@@ -195,9 +195,9 @@ I830Sync(ScrnInfoPtr pScrn)
ADVANCE_LP_RING();
}
- I830WaitLpRing(pScrn, pI830->LpRing->mem.Size - 8, 0);
+ I830WaitLpRing(pScrn, pI830->LpRing->mem->size - 8, 0);
- pI830->LpRing->space = pI830->LpRing->mem.Size - 8;
+ pI830->LpRing->space = pI830->LpRing->mem->size - 8;
pI830->nextColorExpandBuf = 0;
}
@@ -226,10 +226,10 @@ I830SelectBuffer(ScrnInfoPtr pScrn, int buffer)
switch (buffer) {
#ifdef XF86DRI
case I830_SELECT_BACK:
- pI830->bufferOffset = pI830->BackBuffer.Start;
+ pI830->bufferOffset = pI830->back_buffer->offset;
break;
case I830_SELECT_DEPTH:
- pI830->bufferOffset = pI830->DepthBuffer.Start;
+ pI830->bufferOffset = pI830->depth_buffer->offset;
break;
#endif
default:
@@ -252,7 +252,7 @@ I830RefreshRing(ScrnInfoPtr pScrn)
pI830->LpRing->tail = INREG(LP_RING + RING_TAIL);
pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8);
if (pI830->LpRing->space < 0)
- pI830->LpRing->space += pI830->LpRing->mem.Size;
+ pI830->LpRing->space += pI830->LpRing->mem->size;
i830MarkSync(pScrn);
}
diff --git a/src/i830_bios.c b/src/i830_bios.c
index a9ef474d..cb886b54 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -122,8 +122,16 @@ i830GetBIOS(ScrnInfoPtr pScrn)
return bios;
}
-Bool
-i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn)
+/**
+ * Returns the BIOS's fixed panel mode.
+ *
+ * Note that many BIOSes will have the appropriate tables for a panel even when
+ * a panel is not attached. Additionally, many BIOSes adjust table sizes or
+ * offsets, such that this parsing fails. Thus, almost any other method for
+ * detecting the panel mode is preferable.
+ */
+DisplayModePtr
+i830_bios_get_panel_mode(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
struct vbt_header *vbt;
@@ -131,12 +139,11 @@ i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn)
int vbt_off, bdb_off, bdb_block_off, block_size;
int panel_type = -1;
unsigned char *bios;
- Bool found_panel_info = FALSE;
bios = i830GetBIOS(pScrn);
if (bios == NULL)
- return FALSE;
+ return NULL;
vbt_off = INTEL_BIOS_16(0x1a);
vbt = (struct vbt_header *)(bios + vbt_off);
@@ -146,7 +153,7 @@ i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn)
if (memcmp(bdb->signature, "BIOS_DATA_BLOCK ", 16) != 0) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Bad BDB signature\n");
xfree(bios);
- return FALSE;
+ return NULL;
}
for (bdb_block_off = bdb->header_size; bdb_block_off < bdb->bdb_size;
@@ -163,7 +170,6 @@ i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn)
id = INTEL_BIOS_8(start);
block_size = INTEL_BIOS_16(start + 1) + 3;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found BDB block type %d\n", id);
switch (id) {
case 40:
lvds1 = (struct lvds_bdb_1 *)(bios + start);
@@ -227,13 +233,11 @@ i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn)
"Found panel mode in BIOS VBT tables:\n");
xf86PrintModeline(pScrn->scrnIndex, fixed_mode);
- pI830->panel_fixed_mode = fixed_mode;
-
- found_panel_info = TRUE;
- break;
+ xfree(bios);
+ return fixed_mode;
}
}
xfree(bios);
- return found_panel_info;
+ return NULL;
}
diff --git a/src/i830_bios.h b/src/i830_bios.h
index 9bd0db8a..881d5c86 100644
--- a/src/i830_bios.h
+++ b/src/i830_bios.h
@@ -114,6 +114,3 @@ struct lvds_bdb_2 {
CARD8 table_size; /* not sure on this one */
struct lvds_bdb_2_entry panels[16];
} __attribute__((packed));
-
-Bool
-i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn);
diff --git a/src/i830_crt.c b/src/i830_crt.c
index 573e6526..77061653 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -31,7 +31,7 @@
#include "xf86.h"
#include "i830.h"
-#include "i830_xf86Modes.h"
+#include "xf86Modes.h"
#include "i830_display.h"
static void
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index 464eb6dd..85785112 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -88,20 +88,20 @@ I830SetPipeCursorBase (xf86CrtcPtr crtc)
I830Ptr pI830 = I830PTR(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int cursor_base = (pipe == 0 ? CURSOR_A_BASE : CURSOR_B_BASE);
- I830MemRange *cursor_mem;
+ i830_memory *cursor_mem;
if (pipe >= xf86_config->num_crtc)
FatalError("Bad pipe number for cursor base setting\n");
if (pI830->CursorIsARGB)
- cursor_mem = &intel_crtc->cursor_mem_argb;
+ cursor_mem = intel_crtc->cursor_mem_argb;
else
- cursor_mem = &intel_crtc->cursor_mem;
+ cursor_mem = intel_crtc->cursor_mem;
if (pI830->CursorNeedsPhysical) {
- OUTREG(cursor_base, cursor_mem->Physical);
+ OUTREG(cursor_base, cursor_mem->bus_addr);
} else {
- OUTREG(cursor_base, cursor_mem->Start);
+ OUTREG(cursor_base, cursor_mem->offset);
}
}
@@ -281,7 +281,7 @@ I830CRTCLoadCursorImage(xf86CrtcPtr crtc, unsigned char *src)
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
- CARD8 *pcurs = (CARD8 *) (pI830->FbBase + intel_crtc->cursor_mem.Start);
+ CARD8 *pcurs = (CARD8 *) (pI830->FbBase + intel_crtc->cursor_mem->offset);
int x, y;
DPRINTF(PFX, "I830LoadCursorImage\n");
@@ -372,7 +372,7 @@ static Bool I830UseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs)
for (i = 0; i < xf86_config->num_crtc; i++) {
I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private;
- if (!intel_crtc->cursor_mem_argb.Start)
+ if (intel_crtc->cursor_mem_argb == NULL)
return FALSE;
}
@@ -389,7 +389,8 @@ static void I830CRTCLoadCursorARGB (xf86CrtcPtr crtc, CursorPtr pCurs)
{
I830Ptr pI830 = I830PTR(crtc->scrn);
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
- CARD32 *dst = (CARD32 *) (pI830->FbBase + intel_crtc->cursor_mem_argb.Start);
+ CARD32 *dst = (CARD32 *) (pI830->FbBase +
+ intel_crtc->cursor_mem_argb->offset);
CARD32 *image = (CARD32 *)pCurs->bits->argb;
int x, y, w, h;
@@ -510,7 +511,7 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
hotspoty = I810_CURSOR_Y;
break;
case RR_Rotate_270:
- thisx = mode->VDisplay - (root_y - crtc->y);
+ thisx = mode->HDisplay - (root_y - crtc->y);
thisy = (root_x - crtc->x);
hotspotx = I810_CURSOR_Y;
break;
diff --git a/src/i830_debug.c b/src/i830_debug.c
index e0be0a4a..dccaa7ea 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -25,6 +25,11 @@
*
*/
+#ifdef REG_DUMPER
+#include "reg_dumper/reg_dumper.h"
+
+#else
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -34,6 +39,10 @@
#include "i830_debug.h"
#include <strings.h>
+#endif
+
+#include "i810_reg.h"
+
#define DEBUGSTRING(func) static char *func(I830Ptr pI830, int reg, CARD32 val)
DEBUGSTRING(i830_debug_xyminus1)
@@ -69,8 +78,12 @@ DEBUGSTRING(i830_debug_dspcntr)
DEBUGSTRING(i830_debug_pipeconf)
{
char *enabled = val & PIPEACONF_ENABLE ? "enabled" : "disabled";
- char *wide = val & PIPEACONF_DOUBLE_WIDE ? "double-wide" : "single-wide";
- return XNFprintf("%s, %s", enabled, wide);
+ char *bit30;
+ if (IS_I965G(pI830))
+ bit30 = val & I965_PIPECONF_ACTIVE ? "active" : "inactive";
+ else
+ bit30 = val & PIPEACONF_DOUBLE_WIDE ? "double-wide" : "single-wide";
+ return XNFprintf("%s, %s", enabled, bit30);
}
DEBUGSTRING(i830_debug_hvtotal)
@@ -98,6 +111,28 @@ DEBUGSTRING(i830_debug_fp)
((val & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT));
}
+DEBUGSTRING(i830_debug_vga_pd)
+{
+ int vga0_p1, vga0_p2, vga1_p1, vga1_p2;
+
+ /* XXX: i9xx version */
+
+ if (val & VGA0_PD_P1_DIV_2)
+ vga0_p1 = 2;
+ else
+ vga0_p1 = ((val & VGA0_PD_P1_MASK) >> VGA0_PD_P1_SHIFT) + 2;
+ vga0_p2 = (val & VGA0_PD_P2_DIV_4) ? 4 : 2;
+
+ if (val & VGA1_PD_P1_DIV_2)
+ vga1_p1 = 2;
+ else
+ vga1_p1 = ((val & VGA1_PD_P1_MASK) >> VGA1_PD_P1_SHIFT) + 2;
+ vga1_p2 = (val & VGA1_PD_P2_DIV_4) ? 4 : 2;
+
+ return XNFprintf("vga0 p1 = %d, p2 = %d, vga1 p1 = %d, p2 = %d",
+ vga0_p1, vga0_p2, vga1_p1, vga1_p2);
+}
+
DEBUGSTRING(i830_debug_pp_status)
{
char *status = val & PP_ON ? "on" : "off";
@@ -136,18 +171,44 @@ DEBUGSTRING(i830_debug_dpll)
char sdvoextra[20];
int p1, p2 = 0;
- p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK) >>
- DPLL_FPA01_P1_POST_DIV_SHIFT);
- switch (val & DPLL_MODE_MASK) {
- case DPLLB_MODE_DAC_SERIAL:
- mode = "dac/serial";
- p2 = val & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10;
- break;
- case DPLLB_MODE_LVDS:
- mode = "LVDS";
- p2 = val & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14;
- break;
+ if (IS_I9XX(pI830)) {
+ p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK) >>
+ DPLL_FPA01_P1_POST_DIV_SHIFT);
+ switch (val & DPLL_MODE_MASK) {
+ case DPLLB_MODE_DAC_SERIAL:
+ mode = "DAC/serial";
+ p2 = val & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10;
+ break;
+ case DPLLB_MODE_LVDS:
+ mode = "LVDS";
+ p2 = val & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14;
+ break;
+ }
+ } else {
+ Bool is_lvds = (INREG(LVDS) & LVDS_PORT_EN) && (reg == DPLL_B);
+
+ if (val & PLL_P2_DIVIDE_BY_4)
+ p2 = 4;
+ else
+ p2 = 2;
+
+ if (is_lvds) {
+ mode = "LVDS";
+ /* Map the bit number set from (1, 6) to (-1, 4). */
+ p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
+ DPLL_FPA01_P1_POST_DIV_SHIFT);
+ } else {
+ mode = "DAC/serial";
+ if (val & PLL_P1_DIVIDE_BY_TWO) {
+ p1 = 2;
+ } else {
+ /* Map the number in the field to (1, 31) */
+ p1 = ((val & DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
+ DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
+ }
+ }
}
+
switch (val & PLL_REF_INPUT_MASK) {
case PLL_REF_INPUT_DREFCLK:
clock = "default";
@@ -158,7 +219,12 @@ DEBUGSTRING(i830_debug_dpll)
case PLL_REF_INPUT_TVCLKINBC:
clock = "TV B/C";
break;
+ case PLLB_REF_INPUT_SPREADSPECTRUMIN:
+ if (reg == DPLL_B)
+ clock = "spread spectrum";
+ break;
}
+
if (IS_I945G(pI830) || IS_I945GM(pI830)) {
sprintf(sdvoextra, ", SDVO mult %d",
(int)((val & SDVO_MULTIPLIER_MASK) >>
@@ -167,9 +233,9 @@ DEBUGSTRING(i830_debug_dpll)
sdvoextra[0] = '\0';
}
- return XNFprintf("%s, %s%s, %s mode, %s clock, p1 = %d, "
+ return XNFprintf("%s, %s%s, %s clock, %s mode, p1 = %d, "
"p2 = %d%s%s",
- enabled, dvomode, vgamode, mode, clock, p1, p2,
+ enabled, dvomode, vgamode, clock, mode, p1, p2,
fpextra, sdvoextra);
}
@@ -229,9 +295,9 @@ static struct i830SnapshotRec {
char *(*debug_output)(I830Ptr pI830, int reg, CARD32 val);
CARD32 val;
} i830_snapshot[] = {
- DEFINEREG(VCLK_DIVISOR_VGA0),
- DEFINEREG(VCLK_DIVISOR_VGA1),
- DEFINEREG(VCLK_POST_DIV),
+ DEFINEREG2(VCLK_DIVISOR_VGA0, i830_debug_fp),
+ DEFINEREG2(VCLK_DIVISOR_VGA1, i830_debug_fp),
+ DEFINEREG2(VCLK_POST_DIV, i830_debug_vga_pd),
DEFINEREG2(DPLL_TEST, i830_debug_dpll_test),
DEFINEREG(D_STATE),
DEFINEREG(DSPCLK_GATE_D),
@@ -353,6 +419,7 @@ static struct i830SnapshotRec {
#undef DEFINEREG
#define NUM_I830_SNAPSHOTREGS (sizeof(i830_snapshot) / sizeof(i830_snapshot[0]))
+#ifndef REG_DUMPER
void i830TakeRegSnapshot(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
@@ -397,6 +464,7 @@ void i830CompareRegsToSnapshot(ScrnInfoPtr pScrn, char *where)
}
}
}
+#endif /* !REG_DUMPER */
static void i830DumpIndexed (ScrnInfoPtr pScrn, char *name, int id, int val, int min, int max)
{
@@ -530,6 +598,7 @@ void i830DumpRegs (ScrnInfoPtr pScrn)
xf86DrvMsg (pScrn->scrnIndex, X_INFO, "DumpRegsEnd\n");
}
+#ifndef REG_DUMPER
/* Famous last words
*/
void
@@ -742,3 +811,4 @@ i830_check_error_state(ScrnInfoPtr pScrn)
return (errors != 0);
}
+#endif /* !REG_DUMPER */
diff --git a/src/i830_dga.c b/src/i830_dga.c
deleted file mode 100644
index 6d071ac3..00000000
--- a/src/i830_dga.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Copyright 2000 by Alan Hourihane, Sychdyn, North Wales, UK.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Alan Hourihane not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Alan Hourihane makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- *
- * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
- */
-/*
- * Reformatted with GNU indent (2.2.8), using the following options:
- *
- * -bad -bap -c41 -cd0 -ncdb -ci6 -cli0 -cp0 -ncs -d0 -di3 -i3 -ip3 -l78
- * -lp -npcs -psl -sob -ss -br -ce -sc -hnl
- *
- * This provides a good match with the original i810 code and preferred
- * XFree86 formatting conventions.
- *
- * When editing this driver, please follow the existing formatting, and edit
- * with <TAB> characters expanded at 8-column intervals.
- */
-
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dga.c,v 1.2 2002/11/05 02:01:18 dawes Exp $ */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "xf86Pci.h"
-#include "xf86PciInfo.h"
-#include "xaa.h"
-#include "xaalocal.h"
-#include "i830.h"
-#include "i810_reg.h"
-#include "dgaproc.h"
-#include "vgaHW.h"
-
-static Bool I830_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
- int *, int *, int *);
-static void I830_CloseFramebuffer(ScrnInfoPtr pScrn);
-static Bool I830_SetMode(ScrnInfoPtr, DGAModePtr);
-static void I830_Sync(ScrnInfoPtr);
-static int I830_GetViewport(ScrnInfoPtr);
-static void I830_SetViewport(ScrnInfoPtr, int, int, int);
-static void I830_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
-static void I830_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
-
-#if 0
-static void I830_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
- unsigned long);
-#endif
-
-static
-DGAFunctionRec I830DGAFuncs = {
- I830_OpenFramebuffer,
- I830_CloseFramebuffer,
- I830_SetMode,
- I830_SetViewport,
- I830_GetViewport,
- I830_Sync,
- I830_FillRect,
- I830_BlitRect,
-#if 0
- I830_BlitTransRect
-#else
- NULL
-#endif
-};
-
-static DGAModePtr
-I830DGAModes (ScreenPtr pScreen, int *nump)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- I830Ptr pI830 = I830PTR(pScrn);
- DGAModePtr modes = NULL, newmodes = NULL, currentMode;
- DisplayModePtr pMode, firstMode;
- int Bpp = pScrn->bitsPerPixel >> 3;
- int num = 0;
-
- pMode = firstMode = pScrn->modes;
-
- while (pMode) {
-
- newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec));
-
- if (!newmodes) {
- xfree(modes);
- return NULL;
- }
- modes = newmodes;
-
- currentMode = modes + num;
- num++;
-
- currentMode->mode = pMode;
- currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
- if (!pI830->noAccel)
- currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
- if (pMode->Flags & V_DBLSCAN)
- currentMode->flags |= DGA_DOUBLESCAN;
- if (pMode->Flags & V_INTERLACE)
- currentMode->flags |= DGA_INTERLACED;
- currentMode->byteOrder = pScrn->imageByteOrder;
- currentMode->depth = pScrn->depth;
- currentMode->bitsPerPixel = pScrn->bitsPerPixel;
- currentMode->red_mask = pScrn->mask.red;
- currentMode->green_mask = pScrn->mask.green;
- currentMode->blue_mask = pScrn->mask.blue;
- currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor;
- currentMode->viewportWidth = pMode->HDisplay;
- currentMode->viewportHeight = pMode->VDisplay;
- currentMode->xViewportStep = (Bpp == 3) ? 2 : 1;
- currentMode->yViewportStep = 1;
- currentMode->viewportFlags = DGA_FLIP_RETRACE;
- currentMode->offset = 0;
- if (I830IsPrimary(pScrn)) {
- currentMode->address = pI830->FbBase + pI830->FrontBuffer.Start;
- } else {
- I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
- currentMode->address = pI830->FbBase + pI8301->FrontBuffer2.Start;
- }
-
- currentMode->bytesPerScanline = ((pI830->displayWidth * Bpp) + 3) & ~3L;
- if (I830IsPrimary(pScrn)) {
- currentMode->imageWidth = pI830->FbMemBox.x2;
- currentMode->imageHeight = pI830->FbMemBox.y2;
- } else {
- I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
- currentMode->imageWidth = pI8301->FbMemBox2.x2;
- currentMode->imageHeight = pI8301->FbMemBox2.y2;
- }
- currentMode->pixmapWidth = currentMode->imageWidth;
- currentMode->pixmapHeight = currentMode->imageHeight;
- currentMode->maxViewportX = currentMode->imageWidth -
- currentMode->viewportWidth;
- /* this might need to get clamped to some maximum */
- currentMode->maxViewportY = currentMode->imageHeight -
- currentMode->viewportHeight;
-
- pMode = pMode->next;
- if (pMode == firstMode)
- break;
- }
- *nump = num;
- return modes;
-}
-
-Bool
-I830DGAReInit(ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- I830Ptr pI830 = I830PTR(pScrn);
- int num;
- DGAModePtr modes;
-
- modes = I830DGAModes (pScreen, &num);
- if (!modes)
- return FALSE;
-
- if (pI830->DGAModes)
- xfree (pI830->DGAModes);
-
- pI830->numDGAModes = num;
- pI830->DGAModes = modes;
- return DGAReInitModes (pScreen, modes, num);
-}
-
-Bool
-I830DGAInit(ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- I830Ptr pI830 = I830PTR(pScrn);
- int num;
- DGAModePtr modes;
-
- modes = I830DGAModes (pScreen, &num);
- if (!modes)
- return FALSE;
-
- pI830->numDGAModes = num;
- pI830->DGAModes = modes;
-
- return DGAInit(pScreen, &I830DGAFuncs, modes, num);
-}
-
-static DisplayModePtr I830SavedDGAModes[MAXSCREENS];
-
-static Bool
-I830_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
-{
- int index = pScrn->pScreen->myNum;
- I830Ptr pI830 = I830PTR(pScrn);
-
- MARKER();
-
- if (!pMode) { /* restore the original mode */
- DPRINTF(PFX, "Restoring original mode (from DGA mode)\n");
- if (pI830->DGAactive) {
- I830_CloseFramebuffer(pScrn);
- pScrn->currentMode = I830SavedDGAModes[index];
- pScrn->SwitchMode(index, pScrn->currentMode, 0);
- pScrn->AdjustFrame(index, 0, 0, 0);
- pI830->DGAactive = FALSE;
- }
- } else {
- if (!pI830->DGAactive) {
- DPRINTF(PFX, "Setting DGA mode\n");
- I830SavedDGAModes[index] = pScrn->currentMode;
- pI830->DGAactive = TRUE;
- if (I830IsPrimary(pScrn)) {
- pScrn->fbOffset = pI830->FrontBuffer.Start;
- }
- else {
- I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
- pScrn->fbOffset = pI8301->FrontBuffer2.Start;
- }
- pScrn->displayWidth = pI830->displayWidth;
- I830SelectBuffer(pScrn, I830_SELECT_FRONT);
- }
-
- pScrn->SwitchMode(index, pMode->mode, 0);
- }
-
- return TRUE;
-}
-
-static int
-I830_GetViewport(ScrnInfoPtr pScrn)
-{
- I830Ptr pI830 = I830PTR(pScrn);
-
- MARKER();
-
- return pI830->DGAViewportStatus;
-}
-
-static void
-I830_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- vgaHWPtr hwp = VGAHWPTR(pScrn);
-
- MARKER();
-
- pScrn->AdjustFrame(pScrn->pScreen->myNum, x, y, flags);
-
- /* wait for retrace */
- while ((hwp->readST01(hwp) & 0x08)) ;
- while (!(hwp->readST01(hwp) & 0x08)) ;
-
- pI830->DGAViewportStatus = 0;
-}
-
-static void
-I830_FillRect(ScrnInfoPtr pScrn,
- int x, int y, int w, int h, unsigned long color)
-{
-#ifdef I830_USE_XAA
- I830Ptr pI830 = I830PTR(pScrn);
-
- MARKER();
-
- if (pI830->AccelInfoRec) {
- (*pI830->AccelInfoRec->SetupForSolidFill) (pScrn, color, GXcopy, ~0);
- (*pI830->AccelInfoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h);
- SET_SYNC_FLAG(pI830->AccelInfoRec);
- }
-#endif
-}
-
-static void
-I830_Sync(ScrnInfoPtr pScrn)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
-
- MARKER();
-
- if (pI830->noAccel)
- return;
-
- if (IS_I965G(pI830))
- flags = 0;
-
- BEGIN_LP_RING(2);
- OUT_RING(MI_FLUSH | flags);
- OUT_RING(MI_NOOP); /* pad to quadword */
- ADVANCE_LP_RING();
-
- I830WaitLpRing(pScrn, pI830->LpRing->mem.Size - 8, 0);
-
- pI830->LpRing->space = pI830->LpRing->mem.Size - 8;
- pI830->nextColorExpandBuf = 0;
-}
-
-static void
-I830_BlitRect(ScrnInfoPtr pScrn,
- int srcx, int srcy, int w, int h, int dstx, int dsty)
-{
-#ifdef I830_USE_XAA
- I830Ptr pI830 = I830PTR(pScrn);
-
- MARKER();
-
- if (pI830->AccelInfoRec) {
- int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
- int ydir = (srcy < dsty) ? -1 : 1;
-
- (*pI830->AccelInfoRec->SetupForScreenToScreenCopy) (pScrn, xdir, ydir,
- GXcopy, ~0, -1);
- (*pI830->AccelInfoRec->SubsequentScreenToScreenCopy) (pScrn, srcx, srcy,
- dstx, dsty, w, h);
- SET_SYNC_FLAG(pI830->AccelInfoRec);
- }
-#endif
-}
-
-#if 0
-static void
-I830_BlitTransRect(ScrnInfoPtr pScrn,
- int srcx, int srcy,
- int w, int h, int dstx, int dsty, unsigned long color)
-{
-
- MARKER();
-
- /* this one should be separate since the XAA function would
- * prohibit usage of ~0 as the key */
-}
-#endif
-
-static Bool
-I830_OpenFramebuffer(ScrnInfoPtr pScrn,
- char **name,
- unsigned char **mem, int *size, int *offset, int *flags)
-{
- I830Ptr pI830 = I830PTR(pScrn);
-
- MARKER();
-
- *name = NULL; /* no special device */
- if (I830IsPrimary(pScrn)) {
- *size = pI830->FrontBuffer.Size;
- *mem = (unsigned char *)(pI830->LinearAddr + pI830->FrontBuffer.Start);
- pScrn->fbOffset = pI830->FrontBuffer.Start;
- }
- else {
- I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
- *size = pI8301->FrontBuffer2.Size;
- *mem = (unsigned char *)(pI8301->LinearAddr + pI8301->FrontBuffer2.Start);
- pScrn->fbOffset = pI8301->FrontBuffer2.Start;
- }
- pScrn->displayWidth = pI830->displayWidth;
- I830SelectBuffer(pScrn, I830_SELECT_FRONT);
- *offset = 0;
- *flags = DGA_NEED_ROOT;
-
- DPRINTF(PFX,
- " mem == 0x%.8x (pI830->LinearAddr)\n"
- "size == %lu (pI830->FbMapSize)\n", *mem, *size);
-
- return TRUE;
-}
-
-static void
-I830_CloseFramebuffer(ScrnInfoPtr pScrn)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- int i;
- /* Good pitches to allow tiling. Don't care about pitches < 1024. */
- static const int pitches[] = {
-/*
- 128 * 2,
- 128 * 4,
-*/
- 128 * 8,
- 128 * 16,
- 128 * 32,
- 128 * 64,
- 0
- };
-
- if (I830IsPrimary(pScrn)) {
- pScrn->fbOffset = pI830->FrontBuffer.Start;
- } else {
- I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
-
- pScrn->fbOffset = pI8301->FrontBuffer2.Start;
- }
- I830SelectBuffer(pScrn, I830_SELECT_FRONT);
-
- switch (pI830->rotation) {
- case RR_Rotate_0:
- pScrn->displayWidth = pI830->displayWidth;
- break;
- case RR_Rotate_90:
- pScrn->displayWidth = pScrn->pScreen->width;
- break;
- case RR_Rotate_180:
- pScrn->displayWidth = pI830->displayWidth;
- break;
- case RR_Rotate_270:
- pScrn->displayWidth = pScrn->pScreen->width;
- break;
- }
-
- /* As DRI doesn't run on the secondary head, we know that disableTiling
- * is always TRUE.
- */
- if (I830IsPrimary(pScrn) && !pI830->disableTiling) {
-#if 0
- int dWidth = pScrn->displayWidth; /* save current displayWidth */
-#endif
-
- for (i = 0; pitches[i] != 0; i++) {
- if (pitches[i] >= pScrn->displayWidth) {
- pScrn->displayWidth = pitches[i];
- break;
- }
- }
-
- /*
- * If the displayWidth is a tilable pitch, test if there's enough
- * memory available to enable tiling.
- */
- if (pScrn->displayWidth == pitches[i]) {
- /* TODO */
- }
- }
-
-}
diff --git a/src/i830_display.c b/src/i830_display.c
index 82029850..e9666de0 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -41,7 +41,7 @@
#include "i830_bios.h"
#include "i830_display.h"
#include "i830_debug.h"
-#include "i830_xf86Modes.h"
+#include "xf86Modes.h"
typedef struct {
/* given values */
@@ -85,10 +85,15 @@ typedef struct {
#define I8XX_M2_MAX 16
#define I8XX_P_MIN 4
#define I8XX_P_MAX 128
+/* LVDS p1 value can go from 1 to 6, while DAC goes from 2 to 33. These
+ * values below get 2 added in the clock calculations.
+ */
#define I8XX_P1_MIN 0
-#define I8XX_P1_MAX 30
-#define I8XX_P2_SLOW 1
-#define I8XX_P2_FAST 0
+#define I8XX_P1_MAX 31
+#define I8XX_P1_LVDS_MIN -1
+#define I8XX_P1_LVDS_MAX 4
+#define I8XX_P2_SLOW 1 /* this is a bit shift amount */
+#define I8XX_P2_FAST 0 /* this is a bit shift amount */
#define I8XX_P2_SLOW_LIMIT 165000
#define I9XX_DOT_MIN 20000
@@ -116,12 +121,13 @@ typedef struct {
#define I9XX_P2_LVDS_FAST 7
#define I9XX_P2_LVDS_SLOW_LIMIT 112000
-#define INTEL_LIMIT_I8XX 0
-#define INTEL_LIMIT_I9XX_SDVO_DAC 1
-#define INTEL_LIMIT_I9XX_LVDS 2
+#define INTEL_LIMIT_I8XX_DVO_DAC 0
+#define INTEL_LIMIT_I8XX_LVDS 1
+#define INTEL_LIMIT_I9XX_SDVO_DAC 2
+#define INTEL_LIMIT_I9XX_LVDS 3
static const intel_limit_t intel_limits[] = {
- {
+ { /* INTEL_LIMIT_I8XX_DVO_DAC */
.dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX },
.vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX },
.n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX },
@@ -133,7 +139,19 @@ static const intel_limit_t intel_limits[] = {
.p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
.p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST },
},
- {
+ { /* INTEL_LIMIT_I8XX_LVDS */
+ .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX },
+ .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX },
+ .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX },
+ .m = { .min = I8XX_M_MIN, .max = I8XX_M_MAX },
+ .m1 = { .min = I8XX_M1_MIN, .max = I8XX_M1_MAX },
+ .m2 = { .min = I8XX_M2_MIN, .max = I8XX_M2_MAX },
+ .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX },
+ .p1 = { .min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX },
+ .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
+ .p2_slow = I8XX_P2_FAST, .p2_fast = I8XX_P2_FAST },
+ },
+ { /* INTEL_LIMIT_I9XX_SDVO_DAC */
.dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
.vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX },
.n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX },
@@ -145,7 +163,7 @@ static const intel_limit_t intel_limits[] = {
.p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
.p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
},
- {
+ { /* INTEL_LIMIT_I9XX_LVDS */
.dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
.vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX },
.n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX },
@@ -168,15 +186,18 @@ static const intel_limit_t *intel_limit (xf86CrtcPtr crtc)
I830Ptr pI830 = I830PTR(pScrn);
const intel_limit_t *limit;
- if (IS_I9XX(pI830))
- {
+ if (IS_I9XX(pI830)) {
if (i830PipeHasType (crtc, I830_OUTPUT_LVDS))
limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS];
else
limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
+ } else {
+ if (i830PipeHasType (crtc, I830_OUTPUT_LVDS))
+ limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS];
+ else
+ limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC];
}
- else
- limit = &intel_limits[INTEL_LIMIT_I8XX];
+
return limit;
}
@@ -342,14 +363,19 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y)
int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
- if (crtc->rotatedPixmap != NULL) {
- Start = (char *)crtc->rotatedPixmap->devPrivate.ptr -
- (char *)pI830->FbBase;
+ if (pI830->front_buffer == NULL) {
+ /* During startup we may be called as part of monitor detection while
+ * there is no memory allocation done, so just supply a dummy base
+ * address.
+ */
+ Start = 0;
+ } else if (crtc->rotatedData != NULL) {
+ Start = (char *)crtc->rotatedData - (char *)pI830->FbBase;
} else if (I830IsPrimary(pScrn)) {
- Start = pI830->FrontBuffer.Start;
+ Start = pI830->front_buffer->offset;
} else {
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
- Start = pI8301->FrontBuffer2.Start;
+ Start = pI8301->front_buffer_2->offset;
}
if (IS_I965G(pI830)) {
@@ -591,6 +617,86 @@ i830_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
return TRUE;
}
+/** Returns the core display clock speed for i830 - i945 */
+static int
+i830_get_core_clock_speed(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ /* Core clock values taken from the published datasheets.
+ * The 830 may go up to 166 Mhz, which we should check.
+ */
+ if (IS_I945G(pI830))
+ return 400000;
+ else if (IS_I915G(pI830))
+ return 333000;
+ else if (IS_I945GM(pI830) || IS_845G(pI830))
+ return 200000;
+ else if (IS_I915GM(pI830)) {
+ CARD16 gcfgc = pciReadWord(pI830->PciTag, I915_GCFGC);
+
+ if (gcfgc & I915_LOW_FREQUENCY_ENABLE)
+ return 133000;
+ else {
+ switch (gcfgc & I915_DISPLAY_CLOCK_MASK) {
+ case I915_DISPLAY_CLOCK_333_MHZ:
+ return 333000;
+ default:
+ case I915_DISPLAY_CLOCK_190_200_MHZ:
+ return 190000;
+ }
+ }
+ } else if (IS_I865G(pI830))
+ return 266000;
+ else if (IS_I855(pI830)) {
+ PCITAG bridge = pciTag(0, 0, 0); /* This is always the host bridge */
+ CARD16 hpllcc = pciReadWord(bridge, I855_HPLLCC);
+
+ /* Assume that the hardware is in the high speed state. This
+ * should be the default.
+ */
+ switch (hpllcc & I855_CLOCK_CONTROL_MASK) {
+ case I855_CLOCK_133_200:
+ case I855_CLOCK_100_200:
+ return 200000;
+ case I855_CLOCK_166_250:
+ return 250000;
+ case I855_CLOCK_100_133:
+ return 133000;
+ }
+ } else /* 852, 830 */
+ return 133000;
+
+ return 0; /* Silence gcc warning */
+}
+
+/**
+ * Return the pipe currently connected to the panel fitter,
+ * or -1 if the panel fitter is not present or not in use
+ */
+static int
+i830_panel_fitter_pipe (I830Ptr pI830)
+{
+ CARD32 pfit_control;
+
+ /* i830 doesn't have a panel fitter */
+ if (IS_I830(pI830))
+ return -1;
+
+ pfit_control = INREG(PFIT_CONTROL);
+
+ /* See if the panel fitter is in use */
+ if ((pfit_control & PFIT_ENABLE) == 0)
+ return -1;
+
+ /* 965 can place panel fitter on either pipe */
+ if (IS_I965G(pI830))
+ return (pfit_control >> 29) & 0x3;
+
+ /* older chips can only use pipe 1 */
+ return 1;
+}
+
/**
* Sets up registers for the given mode/adjusted_mode pair.
*
@@ -707,7 +813,15 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
if (IS_I965G(pI830))
dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
} else {
- dpll |= clock.p1 << 16;
+ if (is_lvds) {
+ /* map (-1 to 4) to ((1 << 0) to (1 << 5)). */
+ dpll |= (1 << (clock.p1 + 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
+ } else {
+ if (clock.p1 == 0)
+ dpll |= PLL_P1_DIVIDE_BY_TWO;
+ else
+ dpll |= clock.p1 << DPLL_FPA01_P1_POST_DIV_SHIFT;
+ }
dpll |= clock.p2 << 23;
}
@@ -749,23 +863,15 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
dspcntr |= DISPPLANE_SEL_PIPE_B;
pipeconf = INREG(pipeconf_reg);
- if (pipe == 0)
+ if (pipe == 0 && !IS_I965G(pI830))
{
- /*
- * The docs say this is needed when the dot clock is > 90% of the
- * core speed. Core speeds are indicated by bits in the PCI
- * config space, but that's a pain to go read, so we just guess
- * based on the hardware age. AGP hardware is assumed to run
- * at 133MHz while PCI-E hardware is assumed to run at 200MHz
+ /* Enable pixel doubling when the dot clock is > 90% of the (display)
+ * core speed.
+ *
+ * XXX: No double-wide on 915GM pipe B. Is that the only reason for the
+ * pipe == 0 check?
*/
- int core_clock;
-
- if (IS_I9XX(pI830))
- core_clock = 200000;
- else
- core_clock = 133000;
-
- if (mode->Clock > core_clock * 9 / 10)
+ if (mode->Clock > i830_get_core_clock_speed(pScrn) * 9 / 10)
pipeconf |= PIPEACONF_DOUBLE_WIDE;
else
pipeconf &= ~PIPEACONF_DOUBLE_WIDE;
@@ -786,7 +892,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
}
/* Disable the panel fitter if it was on our pipe */
- if (!IS_I830(pI830) && ((INREG(PFIT_CONTROL) >> 29) & 0x3) == pipe)
+ if (i830_panel_fitter_pipe (pI830) == pipe)
OUTREG(PFIT_CONTROL, 0);
i830PrintPll("chosen", &clock);
@@ -886,25 +992,22 @@ i830_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
}
/**
- * Creates a locked-in-framebuffer pixmap of the given width and height for
- * this CRTC's rotated shadow framebuffer.
- *
- * The current implementation uses fixed buffers allocated at startup at the
- * maximal size.
+ * Allocates memory for a locked-in-framebuffer shadow of the given
+ * width and height for this CRTC's rotated shadow framebuffer.
*/
-static PixmapPtr
-i830_crtc_shadow_create(xf86CrtcPtr crtc, int width, int height)
+
+static void *
+i830_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
{
ScrnInfoPtr pScrn = crtc->scrn;
ScreenPtr pScreen = pScrn->pScreen;
I830Ptr pI830 = I830PTR(pScrn);
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
unsigned long rotate_pitch;
- PixmapPtr rotate_pixmap;
unsigned long rotate_offset;
int align = KB(4), size;
- rotate_pitch = pI830->displayWidth * pI830->cpp;
+ rotate_pitch = pScrn->displayWidth * pI830->cpp;
size = rotate_pitch * height;
#ifdef I830_USE_EXA
@@ -944,17 +1047,37 @@ i830_crtc_shadow_create(xf86CrtcPtr crtc, int width, int height)
"Couldn't allocate shadow memory for rotated CRTC\n");
return NULL;
}
- rotate_offset = pI830->FrontBuffer.Start +
+ rotate_offset = pI830->front_buffer->offset +
intel_crtc->rotate_mem_xaa->offset * pI830->cpp;
}
#endif /* I830_USE_XAA */
+ return pI830->FbBase + rotate_offset;
+}
+
+/**
+ * Creates a pixmap for this CRTC's rotated shadow framebuffer.
+ */
+static PixmapPtr
+i830_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long rotate_pitch;
+ PixmapPtr rotate_pixmap;
+
+ if (!data)
+ data = i830_crtc_shadow_allocate (crtc, width, height);
+
+ rotate_pitch = pScrn->displayWidth * pI830->cpp;
+
rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen,
width, height,
pScrn->depth,
pScrn->bitsPerPixel,
rotate_pitch,
- pI830->FbBase + rotate_offset);
+ data);
+
if (rotate_pixmap == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Couldn't allocate shadow pixmap for rotated CRTC\n");
@@ -963,25 +1086,30 @@ i830_crtc_shadow_create(xf86CrtcPtr crtc, int width, int height)
}
static void
-i830_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap)
+i830_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
{
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
- FreeScratchPixmapHeader(rotate_pixmap);
+ if (rotate_pixmap)
+ FreeScratchPixmapHeader(rotate_pixmap);
+
+ if (data)
+ {
#ifdef I830_USE_EXA
- if (pI830->useEXA && intel_crtc->rotate_mem_exa != NULL) {
- exaOffscreenFree(pScrn->pScreen, intel_crtc->rotate_mem_exa);
- intel_crtc->rotate_mem_exa = NULL;
- }
+ if (pI830->useEXA && intel_crtc->rotate_mem_exa != NULL) {
+ exaOffscreenFree(pScrn->pScreen, intel_crtc->rotate_mem_exa);
+ intel_crtc->rotate_mem_exa = NULL;
+ }
#endif /* I830_USE_EXA */
#ifdef I830_USE_XAA
- if (!pI830->useEXA) {
- xf86FreeOffscreenLinear(intel_crtc->rotate_mem_xaa);
- intel_crtc->rotate_mem_xaa = NULL;
- }
+ if (!pI830->useEXA) {
+ xf86FreeOffscreenLinear(intel_crtc->rotate_mem_xaa);
+ intel_crtc->rotate_mem_xaa = NULL;
+ }
#endif /* I830_USE_XAA */
+ }
}
@@ -1132,6 +1260,113 @@ i830ReleaseLoadDetectPipe(xf86OutputPtr output)
}
}
+/* Returns the clock of the currently programmed mode of the given pipe. */
+static int
+i830_crtc_clock_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ int pipe = intel_crtc->pipe;
+ CARD32 dpll = INREG((pipe == 0) ? DPLL_A : DPLL_B);
+ CARD32 fp;
+ intel_clock_t clock;
+
+ if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
+ fp = INREG((pipe == 0) ? FPA0 : FPB0);
+ else
+ fp = INREG((pipe == 0) ? FPA1 : FPB1);
+
+ clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
+ clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
+ clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
+ if (IS_I9XX(pI830)) {
+ clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
+ DPLL_FPA01_P1_POST_DIV_SHIFT);
+
+ switch (dpll & DPLL_MODE_MASK) {
+ case DPLLB_MODE_DAC_SERIAL:
+ clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10;
+ break;
+ case DPLLB_MODE_LVDS:
+ clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Unknown DPLL mode %08x in programmed mode\n",
+ (int)(dpll & DPLL_MODE_MASK));
+ return 0;
+ }
+
+ /* XXX: Handle the 100Mhz refclk */
+ i9xx_clock(96000, &clock);
+ } else {
+ Bool is_lvds = (pipe == 1) && (INREG(LVDS) & LVDS_PORT_EN);
+
+ if (is_lvds) {
+ /* Map the bit number set from (1, 6) to (-1, 4). */
+ clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
+ DPLL_FPA01_P1_POST_DIV_SHIFT) - 2;
+ clock.p2 = 0;
+ } else {
+ if (dpll & PLL_P1_DIVIDE_BY_TWO) {
+ clock.p1 = 0;
+ } else {
+ /* Map the number in the field to (1, 31) */
+ clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
+ DPLL_FPA01_P1_POST_DIV_SHIFT);
+ }
+ if (dpll & PLL_P2_DIVIDE_BY_4)
+ clock.p2 = 1;
+ else
+ clock.p2 = 0;
+ }
+
+ /* XXX: Deal with other refclocks */
+ i8xx_clock(48000, &clock);
+ }
+
+ /* XXX: It would be nice to validate the clocks, but we can't reuse
+ * i830PllIsValid() because it relies on the xf86_config output
+ * configuration being accurate, which it isn't necessarily.
+ */
+ if (0)
+ i830PrintPll("probed", &clock);
+
+ return clock.dot;
+}
+
+/** Returns the currently programmed mode of the given pipe. */
+DisplayModePtr
+i830_crtc_mode_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ int pipe = intel_crtc->pipe;
+ DisplayModePtr mode;
+ int htot = INREG((pipe == 0) ? HTOTAL_A : HTOTAL_B);
+ int hsync = INREG((pipe == 0) ? HSYNC_A : HSYNC_B);
+ int vtot = INREG((pipe == 0) ? VTOTAL_A : VTOTAL_B);
+ int vsync = INREG((pipe == 0) ? VSYNC_A : VSYNC_B);
+
+ mode = xcalloc(1, sizeof(DisplayModeRec));
+ if (mode == NULL)
+ return NULL;
+
+ mode->Clock = i830_crtc_clock_get(pScrn, crtc);
+ mode->HDisplay = (htot & 0xffff) + 1;
+ mode->HTotal = ((htot & 0xffff0000) >> 16) + 1;
+ mode->HSyncStart = (hsync & 0xffff) + 1;
+ mode->HSyncEnd = ((hsync & 0xffff0000) >> 16) + 1;
+ mode->VDisplay = (vtot & 0xffff) + 1;
+ mode->VTotal = ((vtot & 0xffff0000) >> 16) + 1;
+ mode->VSyncStart = (vsync & 0xffff) + 1;
+ mode->VSyncEnd = ((vsync & 0xffff0000) >> 16) + 1;
+ xf86SetModeDefaultName(mode);
+ xf86SetModeCrtc(mode, 0);
+
+ return mode;
+}
+
static const xf86CrtcFuncsRec i830_crtc_funcs = {
.dpms = i830_crtc_dpms,
.save = NULL, /* XXX */
@@ -1142,6 +1377,7 @@ static const xf86CrtcFuncsRec i830_crtc_funcs = {
.mode_set = i830_crtc_mode_set,
.gamma_set = i830_crtc_gamma_set,
.shadow_create = i830_crtc_shadow_create,
+ .shadow_allocate = i830_crtc_shadow_allocate,
.shadow_destroy = i830_crtc_shadow_destroy,
.destroy = NULL, /* XXX */
};
diff --git a/src/i830_display.h b/src/i830_display.h
index dc800553..dbd1ea8e 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -39,3 +39,4 @@ xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output);
void i830ReleaseLoadDetectPipe(xf86OutputPtr output);
void i830_crtc_init(ScrnInfoPtr pScrn, int pipe);
void i830_crtc_load_lut(xf86CrtcPtr crtc);
+DisplayModePtr i830_crtc_mode_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc);
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 70e7e491..f81251a5 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -145,22 +145,22 @@ I830InitDma(ScrnInfoPtr pScrn)
memset(&info, 0, sizeof(drmI830Init));
info.func = I830_INIT_DMA;
- info.ring_start = ring->mem.Start + pI830->LinearAddr;
- info.ring_end = ring->mem.End + pI830->LinearAddr;
- info.ring_size = ring->mem.Size;
+ info.ring_start = ring->mem->offset + pI830->LinearAddr;
+ info.ring_end = ring->mem->end + pI830->LinearAddr;
+ info.ring_size = ring->mem->size;
info.mmio_offset = (unsigned int)pI830DRI->regs;
info.sarea_priv_offset = sizeof(XF86DRISAREARec);
- info.front_offset = pI830->FrontBuffer.Start;
- info.back_offset = pI830->BackBuffer.Start;
- info.depth_offset = pI830->DepthBuffer.Start;
+ info.front_offset = pI830->front_buffer->offset;
+ info.back_offset = pI830->back_buffer->offset;
+ info.depth_offset = pI830->depth_buffer->offset;
info.w = pScrn->virtualX;
info.h = pScrn->virtualY;
- info.pitch = pI830->displayWidth;
- info.back_pitch = pI830->displayWidth;
- info.depth_pitch = pI830->displayWidth;
+ info.pitch = pScrn->displayWidth;
+ info.back_pitch = pScrn->displayWidth;
+ info.depth_pitch = pScrn->displayWidth;
info.cpp = pI830->cpp;
if (drmCommandWrite(pI830->drmSubFD, DRM_I830_INIT,
@@ -509,7 +509,7 @@ I830DRIScreenInit(ScreenPtr pScreen)
pDRIInfo->ddxDriverPatchVersion = I830_PATCHLEVEL;
#if 1 /* Remove this soon - see bug 5714 */
pDRIInfo->frameBufferPhysicalAddress = (char *) pI830->LinearAddr +
- pI830->FrontBuffer.Start;
+ pI830->front_buffer->offset;
pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth *
pScrn->virtualY * pI830->cpp);
#else
@@ -654,21 +654,18 @@ I830DRIScreenInit(ScreenPtr pScreen)
return FALSE;
}
pI830->drmMinor = version->version_minor;
- if (!(pI830->mmModeFlags & I830_KERNEL_TEX)) {
-#ifdef XF86DRI_MM
- if ((version->version_major > 1) ||
- ((version->version_minor >= 7) &&
- (version->version_major == 1))) {
- pI830->mmModeFlags |= I830_KERNEL_MM;
- } else
-#endif
- {
- pI830->mmModeFlags |= I830_KERNEL_TEX;
- }
- } else {
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "Not enabling the DRM memory manager.\n");
- }
+ if (version->version_minor < 7) {
+ if (pI830->mmModeFlags & I830_KERNEL_MM) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "DRM version %d.%d older than required 1.7 for "
+ "DRM memory manager. Disabling.\n",
+ version->version_major, version->version_minor);
+ pI830->mmModeFlags &= ~I830_KERNEL_MM;
+
+ i830_free_memory(pScrn, pI830->memory_manager);
+ pI830->memory_manager = NULL;
+ }
+ }
drmFreeVersion(version);
}
}
@@ -829,8 +826,8 @@ I830DRIDoMappings(ScreenPtr pScreen)
(int)pI830DRI->regs);
if (drmAddMap(pI830->drmSubFD,
- (drm_handle_t)pI830->LpRing->mem.Start + pI830->LinearAddr,
- pI830->LpRing->mem.Size, DRM_AGP, 0,
+ (drm_handle_t)pI830->LpRing->mem->offset + pI830->LinearAddr,
+ pI830->LpRing->mem->size, DRM_AGP, 0,
(drmAddress) &pI830->ring_map) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[drm] drmAddMap(ring_map) failed. Disabling DRI\n");
@@ -1325,10 +1322,10 @@ I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
OUT_RING(br13);
OUT_RING((pbox->y1 << 16) | pbox->x1);
OUT_RING((pbox->y2 << 16) | pbox->x2);
- OUT_RING(pI830->BackBuffer.Start);
+ OUT_RING(pI830->back_buffer->offset);
OUT_RING((pbox->y1 << 16) | pbox->x1);
OUT_RING(br13 & 0xffff);
- OUT_RING(pI830->FrontBuffer.Start);
+ OUT_RING(pI830->front_buffer->offset);
ADVANCE_LP_RING();
}
}
@@ -1360,10 +1357,10 @@ I830EnablePageFlip(ScreenPtr pScreen)
OUT_RING(br13);
OUT_RING(0);
OUT_RING((pScrn->virtualY << 16) | pScrn->virtualX);
- OUT_RING(pI830->BackBuffer.Start);
+ OUT_RING(pI830->back_buffer->offset);
OUT_RING(0);
OUT_RING(br13 & 0xffff);
- OUT_RING(pI830->FrontBuffer.Start);
+ OUT_RING(pI830->front_buffer->offset);
ADVANCE_LP_RING();
pSAREAPriv->pf_active = 1;
@@ -1448,11 +1445,12 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
sarea->depth_tiled = pI830->depth_tiled;
sarea->rotated_tiled = FALSE;
- sarea->front_offset = pI830->FrontBuffer.Start;
- /* Don't use FrontBuffer.Size here as it includes the pixmap cache area
+ sarea->front_offset = pI830->front_buffer->offset;
+ /* Don't use front_buffer->size here as it includes the pixmap cache area
* Instead, calculate the entire framebuffer.
*/
- sarea->front_size = pI830->displayWidth * pScrn->virtualY * pI830->cpp;
+ sarea->front_size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY *
+ pI830->cpp);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"[drm] init sarea width,height = %d x %d (pitch %d)\n",
@@ -1460,12 +1458,17 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
sarea->width = pScreen->width;
sarea->height = pScreen->height;
- sarea->back_offset = pI830->BackBuffer.Start;
- sarea->back_size = pI830->BackBuffer.Size;
- sarea->depth_offset = pI830->DepthBuffer.Start;
- sarea->depth_size = pI830->DepthBuffer.Size;
- sarea->tex_offset = pI830->TexMem.Start;
- sarea->tex_size = pI830->TexMem.Size;
+ sarea->back_offset = pI830->back_buffer->offset;
+ sarea->back_size = pI830->back_buffer->size;
+ sarea->depth_offset = pI830->depth_buffer->offset;
+ sarea->depth_size = pI830->depth_buffer->size;
+ if (pI830->textures != NULL) {
+ sarea->tex_offset = pI830->textures->offset;
+ sarea->tex_size = pI830->textures->size;
+ } else {
+ sarea->tex_offset = 0;
+ sarea->tex_size = 0;
+ }
sarea->log_tex_granularity = pI830->TexGranularity;
sarea->pitch = pScrn->displayWidth;
sarea->virtualX = pScrn->virtualX;
@@ -1477,7 +1480,7 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
sarea->rotation = 0;
sarea->rotated_offset = -1;
sarea->rotated_size = 0;
- sarea->rotated_pitch = pI830->displayWidth;
+ sarea->rotated_pitch = pScrn->displayWidth;
success = I830DRIMapScreenRegions(pScrn, sarea);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 701abd70..e0887260 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -536,7 +536,7 @@ I830MapMem(ScrnInfoPtr pScrn)
return FALSE;
if (I830IsPrimary(pScrn))
- pI830->LpRing->virtual_start = pI830->FbBase + pI830->LpRing->mem.Start;
+ pI830->LpRing->virtual_start = pI830->FbBase + pI830->LpRing->mem->offset;
return TRUE;
}
@@ -754,18 +754,6 @@ PreInitCleanup(ScrnInfoPtr pScrn)
if (I830IsPrimary(pScrn)) {
if (pI830->entityPrivate)
pI830->entityPrivate->pScrn_1 = NULL;
- if (pI830->LpRing)
- xfree(pI830->LpRing);
- pI830->LpRing = NULL;
- if (pI830->OverlayMem)
- xfree(pI830->OverlayMem);
- pI830->OverlayMem = NULL;
- if (pI830->overlayOn)
- xfree(pI830->overlayOn);
- pI830->overlayOn = NULL;
- if (pI830->used3D)
- xfree(pI830->used3D);
- pI830->used3D = NULL;
} else {
if (pI830->entityPrivate)
pI830->entityPrivate->pScrn_2 = NULL;
@@ -817,27 +805,13 @@ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode)
pI830->writeControl(pI830, GRX, 0x18, gr18);
}
-#ifdef XF86DRI
-static void
-I830ReduceMMSize(ScrnInfoPtr pScrn, unsigned long newSize,
- const char *reason)
-{
- I830Ptr pI830 = I830PTR(pScrn);
-
- newSize = ROUND_DOWN_TO(newSize, GTT_PAGE_SIZE);
- if (newSize / GTT_PAGE_SIZE > I830_MM_MINPAGES) {
- pI830->mmSize = newSize / 1024;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "DRM memory manager aperture size is reduced to %d kiB\n"
- "\t%s\n", pI830->mmSize, reason);
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "DRM memory manager will be disabled\n\t%s\n", reason);
- pI830->mmSize = 0;
- }
-}
-#endif
-
+/**
+ * This is called per zaphod head (so usually just once) to do initialization
+ * before the Screen is created.
+ *
+ * This code generally covers probing, module loading, option handling
+ * card mapping, and RandR setup.
+ */
static Bool
I830PreInit(ScrnInfoPtr pScrn, int flags)
{
@@ -848,18 +822,14 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
rgb defaultWeight = { 0, 0, 0 };
EntityInfoPtr pEnt;
I830EntPtr pI830Ent = NULL;
- int mem;
int flags24;
int i;
char *s;
pointer pVBEModule = NULL;
- Bool enable;
const char *chipname;
+ Bool enable;
int num_pipe;
int max_width, max_height;
-#ifdef XF86DRI
- unsigned long savedMMSize;
-#endif
if (pScrn->numEntities != 1)
return FALSE;
@@ -898,7 +868,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
pI830->SaveGeneration = -1;
pI830->pEnt = pEnt;
- pI830->displayWidth = 640; /* default it */
+ pScrn->displayWidth = 640; /* default it */
if (pI830->pEnt->location.type != BUS_PCI)
return FALSE;
@@ -1192,41 +1162,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n",
num_pipe, num_pipe > 1 ? "s" : "");
- /*
- * Get the pre-allocated (stolen) memory size.
- */
- pI830->StolenMemory.Size = I830DetectMemory(pScrn);
- pI830->StolenMemory.Start = 0;
- pI830->StolenMemory.End = pI830->StolenMemory.Size;
-
- /* Find the maximum amount of agpgart memory available. */
- if (I830IsPrimary(pScrn)) {
- mem = I830CheckAvailableMemory(pScrn);
- pI830->StolenOnly = FALSE;
- } else {
- /* videoRam isn't used on the second head, but faked */
- mem = pI830->entityPrivate->pScrn_1->videoRam;
- pI830->StolenOnly = TRUE;
- }
-
- if (mem <= 0) {
- if (pI830->StolenMemory.Size <= 0) {
- /* Shouldn't happen. */
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "/dev/agpgart is either not available, or no memory "
- "is available\nfor allocation, "
- "and no pre-allocated memory is available.\n");
- PreInitCleanup(pScrn);
- return FALSE;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "/dev/agpgart is either not available, or no memory "
- "is available\nfor allocation. "
- "Using pre-allocated memory only.\n");
- mem = 0;
- pI830->StolenOnly = TRUE;
- }
-
if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) {
pI830->noAccel = TRUE;
}
@@ -1290,8 +1225,11 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
if (!pI830->directRenderingDisabled) {
Bool tmp = FALSE;
- if (IS_I965G(pI830))
- pI830->mmModeFlags |= I830_KERNEL_TEX;
+ pI830->mmModeFlags |= I830_KERNEL_TEX;
+#ifdef XF86DRI_MM
+ if (!IS_I965G(pI830))
+ pI830->mmModeFlags |= I830_KERNEL_MM;
+#endif
from = X_PROBED;
if (xf86GetOptValBool(pI830->Options,
@@ -1303,14 +1241,12 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
pI830->mmModeFlags &= ~I830_KERNEL_TEX;
}
}
- if (from == X_CONFIG ||
- (pI830->mmModeFlags & I830_KERNEL_TEX)) {
- xf86DrvMsg(pScrn->scrnIndex, from,
- "Will %stry to allocate texture pool "
- "for old Mesa 3D driver.\n",
- (pI830->mmModeFlags & I830_KERNEL_TEX) ?
- "" : "not ");
- }
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Will %stry to allocate texture pool "
+ "for old Mesa 3D driver.\n",
+ (pI830->mmModeFlags & I830_KERNEL_TEX) ?
+ "" : "not ");
+
pI830->mmSize = I830_MM_MAXSIZE;
from = X_INFO;
if (xf86GetOptValInteger(pI830->Options, OPTION_INTELMMSIZE,
@@ -1329,18 +1265,15 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
pI830->LinearAlloc = 0;
if (xf86GetOptValULong(pI830->Options, OPTION_LINEARALLOC,
&(pI830->LinearAlloc))) {
- if (pI830->LinearAlloc > 0)
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Allocating %luKbytes of memory\n",
- pI830->LinearAlloc);
- else
+ if (pI830->LinearAlloc < 0)
pI830->LinearAlloc = 0;
}
I830PreInitDDC(pScrn);
- I830SetupOutputs(pScrn);
for (i = 0; i < num_pipe; i++) {
i830_crtc_init(pScrn, i);
}
+ I830SetupOutputs(pScrn);
SaveHWState(pScrn);
/* Do an initial detection of the outputs while none are configured on yet.
@@ -1363,8 +1296,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
}
RestoreHWState(pScrn);
- pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
-
/* XXX This should go away, replaced by xf86Crtc.c support for it */
pI830->rotation = RR_Rotate_0;
@@ -1389,77 +1320,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
} else
pI830->checkDevices = FALSE;
- /*
- * The "VideoRam" config file parameter specifies the maximum amount of
- * memory that will be used/allocated. When not present, we allow the
- * driver to allocate as much memory as it wishes to satisfy its
- * allocations, but if agpgart support isn't available (StolenOnly == TRUE),
- * it gets limited to the amount of pre-allocated ("stolen") memory.
- */
- if (!pI830->pEnt->device->videoRam) {
- from = X_DEFAULT;
- pScrn->videoRam = pI830->FbMapSize / KB(1);
- } else {
- from = X_CONFIG;
- pScrn->videoRam = pI830->pEnt->device->videoRam;
- }
-
- /* Make sure it's on a page boundary */
- if (pScrn->videoRam & 3) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VideoRam reduced to %d KB "
- "(page aligned - was %d KB)\n",
- pScrn->videoRam & ~3, pScrn->videoRam);
- pScrn->videoRam &= ~3;
- }
-
- DPRINTF(PFX,
- "Available memory: %dk\n"
- "Requested memory: %dk\n", mem, pScrn->videoRam);
-
-
- if (mem + (pI830->StolenMemory.Size / 1024) < pScrn->videoRam) {
- pScrn->videoRam = mem + (pI830->StolenMemory.Size / 1024);
- from = X_PROBED;
- if (mem + (pI830->StolenMemory.Size / 1024) <
- pI830->pEnt->device->videoRam) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "VideoRAM reduced to %d kByte "
- "(limited to available sysmem)\n", pScrn->videoRam);
- }
- }
-
- if (pScrn->videoRam > pI830->FbMapSize / 1024) {
- pScrn->videoRam = pI830->FbMapSize / 1024;
- if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam)
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "VideoRam reduced to %d kByte (limited to aperture size)\n",
- pScrn->videoRam);
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "Pre-allocated VideoRam: %ld kByte\n",
- pI830->StolenMemory.Size / 1024);
- xf86DrvMsg(pScrn->scrnIndex, from, "Potential VideoRam: %d kByte\n",
- pScrn->videoRam);
-
- pI830->TotalVideoRam = KB(pScrn->videoRam);
-
- /*
- * If the requested videoRam amount is less than the stolen memory size,
- * reduce the stolen memory size accordingly.
- */
- if (pI830->StolenMemory.Size > pI830->TotalVideoRam) {
- pI830->StolenMemory.Size = pI830->TotalVideoRam;
- pI830->StolenMemory.End = pI830->TotalVideoRam;
- }
-
- if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES,
- &(pI830->CacheLines))) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n",
- pI830->CacheLines);
- } else {
- pI830->CacheLines = -1;
- }
+ pI830->stolen_size = I830DetectMemory(pScrn);
pI830->XvDisabled =
!xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE);
@@ -1505,24 +1366,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
}
}
- /* Alloc our pointers for the primary head */
- if (I830IsPrimary(pScrn)) {
- pI830->LpRing = xalloc(sizeof(I830RingBuffer));
- pI830->OverlayMem = xalloc(sizeof(I830MemRange));
- pI830->overlayOn = xalloc(sizeof(Bool));
- pI830->used3D = xalloc(sizeof(int));
- if (!pI830->LpRing ||
- !pI830->OverlayMem || !pI830->overlayOn || !pI830->used3D) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Could not allocate primary data structures.\n");
- PreInitCleanup(pScrn);
- return FALSE;
- }
- *pI830->overlayOn = FALSE;
- if (pI830->entityPrivate)
- pI830->entityPrivate->XvInUse = -1;
- }
-
/* Check if the HW cursor needs physical address. */
if (IS_MOBILE(pI830) || IS_I9XX(pI830))
pI830->CursorNeedsPhysical = TRUE;
@@ -1532,9 +1375,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
if (IS_I965G(pI830))
pI830->CursorNeedsPhysical = FALSE;
- /* Force ring buffer to be in low memory for all chipsets */
- pI830->NeedRingBufferLow = TRUE;
-
/*
* XXX If we knew the pre-initialised GTT format for certain, we could
* probably figure out the physical address even in the StolenOnly case.
@@ -1553,21 +1393,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
pI830->SWCursor = TRUE;
}
- /*
- * Reduce the maximum videoram available for video modes by the ring buffer,
- * minimum scratch space and HW cursor amounts.
- */
- if (!pI830->SWCursor) {
- pScrn->videoRam -= (HWCURSOR_SIZE / 1024);
- pScrn->videoRam -= (HWCURSOR_SIZE_ARGB / 1024);
- }
- if (!pI830->XvDisabled)
- pScrn->videoRam -= (OVERLAY_SIZE / 1024);
- if (!pI830->noAccel) {
- pScrn->videoRam -= (PRIMARY_RINGBUFFER_SIZE / 1024);
- pScrn->videoRam -= (MIN_SCRATCH_BUFFER_SIZE / 1024);
- }
-
if (!xf86RandR12PreInit (pScrn))
{
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
@@ -1582,187 +1407,11 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
}
pScrn->currentMode = pScrn->modes;
- pI830->disableTiling = FALSE;
-
- /*
- * If DRI is potentially usable, check if there is enough memory available
- * for it, and if there's also enough to allow tiling to be enabled.
- */
-
-#if defined(XF86DRI)
- if (!I830CheckDRIAvailable(pScrn)) {
- pI830->directRenderingDisabled = TRUE;
- pI830->mmSize = 0;
- } else if (pScrn->videoRam > pI830->FbMapSize / 1024 - pI830->mmSize) {
- I830ReduceMMSize(pScrn, pI830->FbMapSize - KB(pScrn->videoRam),
- "to make room for video memory");
- }
-
- if (I830IsPrimary(pScrn) && !pI830->directRenderingDisabled) {
- int savedDisplayWidth = pScrn->displayWidth;
- int memNeeded = 0;
- Bool tiled = FALSE;
-
-#ifdef I830_XV
- /*
- * Set this so that the overlay allocation is factored in when
- * appropriate.
- */
- pI830->XvEnabled = !pI830->XvDisabled;
-#endif
-
- if (IS_I965G(pI830)) {
- int tile_pixels = 512 / pI830->cpp;
- pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) &
- ~(tile_pixels - 1);
- tiled = TRUE;
- } else {
- /* Good pitches to allow tiling. Don't care about pitches < 1024. */
- static const int pitches[] = {
- KB(1),
- KB(2),
- KB(4),
- KB(8),
- 0
- };
-
- for (i = 0; pitches[i] != 0; i++) {
- if (pitches[i] >= pScrn->displayWidth) {
- pScrn->displayWidth = pitches[i];
- tiled = TRUE;
- break;
- }
- }
- }
-
- /*
- * If the displayWidth is a tilable pitch, test if there's enough
- * memory available to enable tiling.
- */
- savedMMSize = pI830->mmSize;
- if (tiled) {
- retry_dryrun:
- I830ResetAllocations(pScrn, 0);
- if (I830Allocate2DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_INITIAL) &&
- I830Allocate3DMemory(pScrn, ALLOCATE_DRY_RUN)) {
- memNeeded = I830GetExcessMemoryAllocations(pScrn);
- if (memNeeded > 0 || pI830->MemoryAperture.Size < 0) {
- if (memNeeded > 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "%d kBytes additional video memory is "
- "required to\n\tenable tiling mode for DRI.\n",
- (memNeeded + 1023) / 1024);
- }
- if (pI830->MemoryAperture.Size < 0) {
- if (KB(pI830->mmSize) > I830_MM_MINPAGES * GTT_PAGE_SIZE) {
- I830ReduceMMSize(pScrn, I830_MM_MINPAGES * GTT_PAGE_SIZE,
- "to make room in AGP aperture for tiling.");
- goto retry_dryrun;
- }
- /* XXX */
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Allocation with DRI tiling enabled would "
- "exceed the\n"
- "\tmemory aperture size (%ld kB) by %ld kB.\n"
- "\tReduce VideoRam amount to avoid this!\n",
- pI830->FbMapSize / 1024,
- -pI830->MemoryAperture.Size / 1024);
- }
- pScrn->displayWidth = savedDisplayWidth;
- pI830->allowPageFlip = FALSE;
- } else if (pScrn->displayWidth != savedDisplayWidth) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Increasing the scanline pitch to allow tiling mode "
- "(%d -> %d).\n",
- savedDisplayWidth, pScrn->displayWidth);
- }
- } else {
- memNeeded = 0;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Unexpected dry run allocation failure (1).\n");
- }
- }
- if (memNeeded > 0 || pI830->MemoryAperture.Size < 0) {
- /*
- * Tiling can't be enabled. Check if there's enough memory for DRI
- * without tiling.
- */
- pI830->mmSize = savedMMSize;
- pI830->disableTiling = TRUE;
- retry_dryrun2:
- I830ResetAllocations(pScrn, 0);
- if (I830Allocate2DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_INITIAL) &&
- I830Allocate3DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_NO_TILING)) {
- memNeeded = I830GetExcessMemoryAllocations(pScrn);
- if (memNeeded > 0 || pI830->MemoryAperture.Size < 0) {
- if (memNeeded > 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "%d kBytes additional video memory is required "
- "to enable DRI.\n",
- (memNeeded + 1023) / 1024);
- }
- if (pI830->MemoryAperture.Size < 0) {
- if (KB(pI830->mmSize) > I830_MM_MINPAGES * GTT_PAGE_SIZE) {
- I830ReduceMMSize(pScrn, I830_MM_MINPAGES * GTT_PAGE_SIZE,
- "to save AGP aperture space for video memory.");
- goto retry_dryrun2;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Allocation with DRI enabled would "
- "exceed the\n"
- "\tmemory aperture size (%ld kB) by %ld kB.\n"
- "\tReduce VideoRam amount to avoid this!\n",
- pI830->FbMapSize / 1024,
- -pI830->MemoryAperture.Size / 1024);
- }
- pI830->mmSize = 0;
- pI830->directRenderingDisabled = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DRI.\n");
- }
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Unexpected dry run allocation failure (2).\n");
- }
- }
- } else
-#endif
- pI830->disableTiling = TRUE; /* no DRI - so disableTiling */
-
- if (pI830->pEnt->device->videoRam == 0) {
- int default_videoram;
-
- /* Now that we've sized the allocations, reduce our default VideoRam
- * allocation from the aperture size to just what we need to cover our
- * allocations. Only, put in some slop for alignment and such.
- */
- default_videoram = pI830->StolenPool.Total.Size + pI830->allocatedMemory;
- default_videoram += KB(512); /* slop */
- /* align to 1MB increments */
- default_videoram = (default_videoram + MB(1) - 1) / MB(1) * MB(1);
-
- if (default_videoram < KB(pScrn->videoRam)) {
- pScrn->videoRam = default_videoram / KB(1);
- pI830->TotalVideoRam = KB(pScrn->videoRam);
- }
- }
- xf86DrvMsg(pScrn->scrnIndex,
- pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT,
- "VideoRam: %d KB\n", pScrn->videoRam);
-
- if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Cannot support DRI with frame buffer width > 2048.\n");
- pI830->disableTiling = TRUE;
- pI830->directRenderingDisabled = TRUE;
- }
-
if (!IS_I965G(pI830) && pScrn->virtualY > 2048) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support > 2048 vertical lines. disabling acceleration.\n");
pI830->noAccel = TRUE;
}
- pI830->displayWidth = pScrn->displayWidth;
-
/* Don't need MMIO access anymore. */
if (pI830->swfSaved) {
OUTREG(SWF0, pI830->saveSWF0);
@@ -1939,18 +1588,18 @@ SetFenceRegs(ScrnInfoPtr pScrn)
if (IS_I965G(pI830)) {
for (i = 0; i < FENCE_NEW_NR; i++) {
- OUTREG(FENCE_NEW + i * 8, pI830->ModeReg.Fence[i]);
- OUTREG(FENCE_NEW + 4 + i * 8, pI830->ModeReg.Fence[i+FENCE_NEW_NR]);
+ OUTREG(FENCE_NEW + i * 8, pI830->fence[i]);
+ OUTREG(FENCE_NEW + 4 + i * 8, pI830->fence[i+FENCE_NEW_NR]);
if (I810_DEBUG & DEBUG_VERBOSE_VGA) {
- ErrorF("Fence Start Register : %x\n", pI830->ModeReg.Fence[i]);
- ErrorF("Fence End Register : %x\n", pI830->ModeReg.Fence[i+FENCE_NEW_NR]);
+ ErrorF("Fence Start Register : %x\n", pI830->fence[i]);
+ ErrorF("Fence End Register : %x\n", pI830->fence[i+FENCE_NEW_NR]);
}
}
} else {
for (i = 0; i < FENCE_NR; i++) {
- OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]);
+ OUTREG(FENCE + i * 4, pI830->fence[i]);
if (I810_DEBUG & DEBUG_VERBOSE_VGA)
- ErrorF("Fence Register : %x\n", pI830->ModeReg.Fence[i]);
+ ErrorF("Fence Register : %x\n", pI830->fence[i]);
}
}
}
@@ -1975,25 +1624,22 @@ SetRingRegs(ScrnInfoPtr pScrn)
OUTREG(LP_RING + RING_TAIL, 0);
OUTREG(LP_RING + RING_HEAD, 0);
- if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) !=
- pI830->LpRing->mem.Start) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "I830SetRingRegs: Ring buffer start (%lx) violates its "
- "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK);
- }
+ assert((pI830->LpRing->mem->offset & I830_RING_START_MASK) ==
+ pI830->LpRing->mem->offset);
+
/* Don't care about the old value. Reserved bits must be zero anyway. */
- itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK;
+ itemp = pI830->LpRing->mem->offset;
OUTREG(LP_RING + RING_START, itemp);
- if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) !=
- pI830->LpRing->mem.Size - 4096) {
+ if (((pI830->LpRing->mem->size - 4096) & I830_RING_NR_PAGES) !=
+ pI830->LpRing->mem->size - 4096) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its "
- "mask (%x)\n", pI830->LpRing->mem.Size - 4096,
+ "mask (%x)\n", pI830->LpRing->mem->size - 4096,
I830_RING_NR_PAGES);
}
/* Don't care about the old value. Reserved bits must be zero anyway. */
- itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES;
+ itemp = (pI830->LpRing->mem->size - 4096) & I830_RING_NR_PAGES;
itemp |= (RING_NO_REPORT | RING_VALID);
OUTREG(LP_RING + RING_LEN, itemp);
I830RefreshRing(pScrn);
@@ -2251,13 +1897,12 @@ static void
InitRegisterRec(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
- I830RegPtr i830Reg = &pI830->ModeReg;
int i;
if (!I830IsPrimary(pScrn)) return;
for (i = 0; i < 8; i++)
- i830Reg->Fence[i] = 0;
+ pI830->fence[i] = 0;
}
static void
@@ -2366,14 +2011,12 @@ IntelEmitInvarientState(ScrnInfoPtr pScrn)
}
#endif
- ctx_addr = pI830->ContextMem.Start;
- /* Align to a 2k boundry */
- ctx_addr = ((ctx_addr + 2048 - 1) / 2048) * 2048;
-
+ ctx_addr = pI830->logical_context->offset;
+ assert((pI830->logical_context->offset & 2047) == 0);
{
BEGIN_LP_RING(2);
OUT_RING(MI_SET_CONTEXT);
- OUT_RING(ctx_addr |
+ OUT_RING(pI830->logical_context->offset |
CTXT_NO_RESTORE |
CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE);
ADVANCE_LP_RING();
@@ -2473,15 +2116,263 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
I830Ptr pI830;
VisualPtr visual;
I830Ptr pI8301 = NULL;
+ unsigned long sys_mem;
+ int i;
+ Bool allocation_done = FALSE;
+ MessageType from;
#ifdef XF86DRI
Bool driDisabled;
+ unsigned long savedMMSize;
#endif
pScrn = xf86Screens[pScreen->myNum];
pI830 = I830PTR(pScrn);
hwp = VGAHWPTR(pScrn);
- pScrn->displayWidth = pI830->displayWidth;
+ pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
+
+ /*
+ * The "VideoRam" config file parameter specifies the maximum amount of
+ * memory that will be used/allocated. When not present, we allow the
+ * driver to allocate as much memory as it wishes to satisfy its
+ * allocations, but if agpgart support isn't available, it gets limited
+ * to the amount of pre-allocated ("stolen") memory.
+ *
+ * Note that in using this value for allocator initialization, we're
+ * limiting aperture allocation to the VideoRam option, rather than limiting
+ * actual memory allocation, so alignment and things will cause less than
+ * VideoRam to be actually used.
+ */
+ if (pI830->pEnt->device->videoRam == 0) {
+ from = X_DEFAULT;
+ pScrn->videoRam = pI830->FbMapSize / KB(1);
+ } else {
+ from = X_CONFIG;
+ pScrn->videoRam = pI830->pEnt->device->videoRam;
+ }
+
+ /* Limit videoRam to how much we might be able to allocate from AGP */
+ sys_mem = I830CheckAvailableMemory(pScrn);
+ if (sys_mem == -1) {
+ if (pScrn->videoRam > pI830->stolen_size / KB(1)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "/dev/agpgart is either not available, or no memory "
+ "is available\nfor allocation. "
+ "Using pre-allocated memory only.\n");
+ pScrn->videoRam = pI830->stolen_size / KB(1);
+ }
+ pI830->StolenOnly = TRUE;
+ } else {
+ if (sys_mem + (pI830->stolen_size / 1024) < pScrn->videoRam) {
+ pScrn->videoRam = sys_mem + (pI830->stolen_size / 1024);
+ from = X_PROBED;
+ if (sys_mem + (pI830->stolen_size / 1024) <
+ pI830->pEnt->device->videoRam)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "VideoRAM reduced to %d kByte "
+ "(limited to available sysmem)\n", pScrn->videoRam);
+ }
+ }
+ }
+
+ /* Limit video RAM to the actual aperture size */
+ if (pScrn->videoRam > pI830->FbMapSize / 1024) {
+ pScrn->videoRam = pI830->FbMapSize / 1024;
+ if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "VideoRam reduced to %d kByte (limited to aperture "
+ "size)\n",
+ pScrn->videoRam);
+ }
+ }
+
+ /* Make sure it's on a page boundary */
+ if (pScrn->videoRam & 3) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VideoRam reduced to %d KB "
+ "(page aligned - was %d KB)\n",
+ pScrn->videoRam & ~3, pScrn->videoRam);
+ pScrn->videoRam &= ~3;
+ }
+
+ /* Set up our video memory allocator for the chosen videoRam */
+ if (!i830_allocator_init(pScrn, 0, pScrn->videoRam * KB(1))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Couldn't initialize video memory allocator\n");
+ PreInitCleanup(pScrn);
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex,
+ pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT,
+ "VideoRam: %d KB\n", pScrn->videoRam);
+
+ if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES,
+ &(pI830->CacheLines))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n",
+ pI830->CacheLines);
+ } else {
+ pI830->CacheLines = -1;
+ }
+
+ pI830->disableTiling = FALSE;
+
+ if (I830IsPrimary(pScrn)) {
+ /* Alloc our pointers for the primary head */
+ if (!pI830->LpRing)
+ pI830->LpRing = xcalloc(1, sizeof(I830RingBuffer));
+ if (!pI830->overlayOn)
+ pI830->overlayOn = xalloc(sizeof(Bool));
+ if (!pI830->used3D)
+ pI830->used3D = xalloc(sizeof(int));
+ if (!pI830->LpRing || !pI830->overlayOn || !pI830->used3D) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not allocate primary data structures.\n");
+ return FALSE;
+ }
+ *pI830->overlayOn = FALSE;
+ if (pI830->entityPrivate)
+ pI830->entityPrivate->XvInUse = -1;
+ } else {
+ /* Make our second head point to the first heads structures */
+ pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ pI830->LpRing = pI8301->LpRing;
+ pI830->overlay_regs = pI8301->overlay_regs;
+ pI830->overlayOn = pI8301->overlayOn;
+ pI830->used3D = pI8301->used3D;
+ }
+
+#if defined(XF86DRI)
+ /*
+ * If DRI is potentially usable, check if there is enough memory available
+ * for it, and if there's also enough to allow tiling to be enabled.
+ */
+
+ if (!I830CheckDRIAvailable(pScrn)) {
+ pI830->directRenderingDisabled = TRUE;
+ pI830->mmSize = 0;
+ }
+
+ if (!pI830->directRenderingDisabled) {
+ int savedDisplayWidth = pScrn->displayWidth;
+ Bool tiled = FALSE;
+
+#ifdef I830_XV
+ /*
+ * Set this so that the overlay allocation is factored in when
+ * appropriate.
+ */
+ pI830->XvEnabled = !pI830->XvDisabled;
+#endif
+
+ if (IS_I965G(pI830)) {
+ int tile_pixels = 512 / pI830->cpp;
+ pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) &
+ ~(tile_pixels - 1);
+ tiled = TRUE;
+ } else {
+ /* Good pitches to allow tiling. Don't care about pitches < 1024
+ * pixels.
+ */
+ static const int pitches[] = {
+ 1024,
+ 2048,
+ 4096,
+ 8192,
+ 0
+ };
+
+ for (i = 0; pitches[i] != 0; i++) {
+ if (pitches[i] >= pScrn->displayWidth) {
+ pScrn->displayWidth = pitches[i];
+ tiled = TRUE;
+ break;
+ }
+ }
+ }
+
+ /* Attempt several rounds of allocation to get 2d and 3d memory to fit:
+ *
+ * 0: tiled, large memory manager
+ * 1: tiled, small memory manager
+ * 2: untiled, large
+ * 3: untiled, small
+ */
+
+ pI830->disableTiling = FALSE;
+ savedMMSize = pI830->mmSize;
+ for (i = 0; i < 4; i++) {
+ if (!tiled && i < 2)
+ continue;
+
+ if (i >= 2) {
+ /* For further allocations, disable tiling */
+ pI830->disableTiling = TRUE;
+ pScrn->displayWidth = savedDisplayWidth;
+ pI830->allowPageFlip = FALSE;
+ }
+
+ if (i & 1) {
+ /* For this allocation, switch to a smaller DRI memory manager
+ * size.
+ */
+ pI830->mmSize = I830_MM_MINPAGES * GTT_PAGE_SIZE;
+ } else {
+ pI830->mmSize = savedMMSize;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Attempting memory allocation with %s buffers and \n"
+ "\t %s DRI memory manager reservation:\n",
+ (i & 2) ? "untiled" : "tiled",
+ (i & 1) ? "small" : "large");
+
+ if (i830_allocate_2d_memory(pScrn) &&
+ i830_allocate_3d_memory(pScrn))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Success.\n");
+ if (pScrn->displayWidth != savedDisplayWidth) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Increasing the scanline pitch to allow tiling mode "
+ "(%d -> %d).\n",
+ savedDisplayWidth, pScrn->displayWidth);
+ }
+ allocation_done = TRUE;
+ break;
+ }
+
+ i830_reset_allocations(pScrn);
+ }
+
+ if (i == 4) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Not enough video memory. Disabling DRI.\n");
+ pI830->mmSize = 0;
+ pI830->directRenderingDisabled = TRUE;
+ }
+ } else
+#endif
+ pI830->disableTiling = TRUE; /* no DRI - so disableTiling */
+
+ if (!allocation_done) {
+ if (!i830_allocate_2d_memory(pScrn)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Couldn't allocate video memory\n");
+ return FALSE;
+ }
+ allocation_done = TRUE;
+ }
+
+ i830_describe_allocations(pScrn, 1, "");
+
+ if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Cannot support DRI with frame buffer width > 2048.\n");
+ pI830->disableTiling = TRUE;
+ pI830->directRenderingDisabled = TRUE;
+ }
+
+ pScrn->displayWidth = pScrn->displayWidth;
#ifdef HAS_MTRR_SUPPORT
{
@@ -2526,36 +2417,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pI830->starting = TRUE;
- /* Alloc our pointers for the primary head */
- if (I830IsPrimary(pScrn)) {
- if (!pI830->LpRing)
- pI830->LpRing = xalloc(sizeof(I830RingBuffer));
- if (!pI830->OverlayMem)
- pI830->OverlayMem = xalloc(sizeof(I830MemRange));
- if (!pI830->overlayOn)
- pI830->overlayOn = xalloc(sizeof(Bool));
- if (!pI830->used3D)
- pI830->used3D = xalloc(sizeof(int));
- if (!pI830->LpRing ||
- !pI830->OverlayMem || !pI830->overlayOn || !pI830->used3D) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Could not allocate primary data structures.\n");
- return FALSE;
- }
- *pI830->overlayOn = FALSE;
- if (pI830->entityPrivate)
- pI830->entityPrivate->XvInUse = -1;
- }
-
- /* Make our second head point to the first heads structures */
- if (!I830IsPrimary(pScrn)) {
- pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
- pI830->LpRing = pI8301->LpRing;
- pI830->OverlayMem = pI8301->OverlayMem;
- pI830->overlayOn = pI8301->overlayOn;
- pI830->used3D = pI8301->used3D;
- }
-
miClearVisualTypes();
if (!miSetVisualTypes(pScrn->depth,
miGetDefaultVisualMask(pScrn->depth),
@@ -2583,15 +2444,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pI830->XvEnabled = FALSE;
#endif
- if (I830IsPrimary(pScrn)) {
- I830ResetAllocations(pScrn, 0);
-
- if (!I830Allocate2DMemory(pScrn, ALLOC_INITIAL))
- return FALSE;
- }
-
if (!pI830->noAccel) {
- if (pI830->LpRing->mem.Size == 0) {
+ if (pI830->LpRing->mem->size == 0) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Disabling acceleration because the ring buffer "
"allocation failed.\n");
@@ -2606,7 +2460,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
"needs 2D acceleration.\n");
pI830->XvEnabled = FALSE;
}
- if (pI830->OverlayMem->Physical == 0) {
+ if (!IS_I9XX(pI830) && pI830->overlay_regs == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Disabling Xv because the overlay register buffer "
"allocation failed.\n");
@@ -2634,6 +2488,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DRI is disabled because it "
"needs HW cursor, 2D accel and AGPGART.\n");
pI830->directRenderingEnabled = FALSE;
+ i830_free_3d_memory(pScrn);
}
}
@@ -2642,39 +2497,17 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (pI830->directRenderingEnabled)
pI830->directRenderingEnabled = I830DRIScreenInit(pScreen);
- if (pI830->directRenderingEnabled) {
- pI830->directRenderingEnabled =
- I830Allocate3DMemory(pScrn,
- pI830->disableTiling ? ALLOC_NO_TILING : 0);
- if (!pI830->directRenderingEnabled)
- I830DRICloseScreen(pScreen);
+ if (!pI830->directRenderingEnabled) {
+ i830_free_3d_memory(pScrn);
}
#else
pI830->directRenderingEnabled = FALSE;
#endif
- /*
- * After the 3D allocations have been done, see if there's any free space
- * that can be added to the framebuffer allocation.
- */
- if (I830IsPrimary(pScrn)) {
- I830Allocate2DMemory(pScrn, 0);
-
- DPRINTF(PFX, "assert(if(!I830DoPoolAllocation(pScrn, pI830->StolenPool)))\n");
- if (!I830DoPoolAllocation(pScrn, &(pI830->StolenPool)))
- return FALSE;
-
- DPRINTF(PFX, "assert( if(!I830FixupOffsets(pScrn)) )\n");
- if (!I830FixupOffsets(pScrn))
- return FALSE;
- }
-
#ifdef XF86DRI
- if (pI830->directRenderingEnabled) {
- I830SetupMemoryTiling(pScrn);
+ if (pI830->directRenderingEnabled)
pI830->directRenderingEnabled = I830DRIDoMappings(pScreen);
- }
#endif
DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n");
@@ -2684,9 +2517,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pScrn->memPhysBase = (unsigned long)pI830->FbBase;
if (I830IsPrimary(pScrn)) {
- pScrn->fbOffset = pI830->FrontBuffer.Start;
+ pScrn->fbOffset = pI830->front_buffer->offset;
} else {
- pScrn->fbOffset = pI8301->FrontBuffer2.Start;
+ pScrn->fbOffset = pI8301->front_buffer_2->offset;
}
pI830->xoffset = (pScrn->fbOffset / pI830->cpp) % pScrn->displayWidth;
@@ -2700,8 +2533,30 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
DPRINTF(PFX, "assert( if(!I830EnterVT(scrnIndex, 0)) )\n");
- if (!I830EnterVT(scrnIndex, 0))
- return FALSE;
+ if (!pI830->useEXA) {
+ if (I830IsPrimary(pScrn)) {
+ if (!I830InitFBManager(pScreen, &(pI830->FbMemBox))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to init memory manager\n");
+ }
+
+ if (pI830->LinearAlloc &&
+ xf86InitFBManagerLinear(pScreen,
+ pI830->xaa_linear->offset / pI830->cpp,
+ pI830->xaa_linear->size / pI830->cpp))
+ {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Using %ld bytes of offscreen memory for linear "
+ "(offset=0x%lx)\n", pI830->xaa_linear->size,
+ pI830->xaa_linear->offset);
+ }
+ } else {
+ if (!I830InitFBManager(pScreen, &(pI8301->FbMemBox2))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to init memory manager\n");
+ }
+ }
+ }
if (pScrn->virtualX > pScrn->displayWidth)
pScrn->displayWidth = pScrn->virtualX;
@@ -2732,34 +2587,10 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
xf86SetBlackWhitePixels(pScreen);
- I830DGAInit(pScreen);
+ xf86DiDGAInit (pScreen, pI830->LinearAddr + pScrn->fbOffset);
DPRINTF(PFX,
"assert( if(!I830InitFBManager(pScreen, &(pI830->FbMemBox))) )\n");
- if (!pI830->useEXA) {
- if (I830IsPrimary(pScrn)) {
- if (!I830InitFBManager(pScreen, &(pI830->FbMemBox))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to init memory manager\n");
- }
-
- if (pI830->LinearAlloc &&
- xf86InitFBManagerLinear(pScreen,
- pI830->LinearMem.Offset / pI830->cpp,
- pI830->LinearMem.Size / pI830->cpp))
- {
- xf86DrvMsg(scrnIndex, X_INFO,
- "Using %ld bytes of offscreen memory for linear "
- "(offset=0x%lx)\n", pI830->LinearMem.Size,
- pI830->LinearMem.Offset);
- }
- } else {
- if (!I830InitFBManager(pScreen, &(pI8301->FbMemBox2))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to init memory manager\n");
- }
- }
- }
if (!pI830->noAccel) {
if (!I830AccelInit(pScreen)) {
@@ -2768,6 +2599,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
}
}
+ if (!I830EnterVT(scrnIndex, 0))
+ return FALSE;
+
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
xf86SetSilkenMouse(pScreen);
@@ -2882,27 +2716,24 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pI830->suspended = FALSE;
#ifdef XF86DRI_MM
- if (pI830->directRenderingEnabled && (pI830->mmModeFlags & I830_KERNEL_MM)) {
- unsigned long aperEnd = ROUND_DOWN_TO(pI830->FbMapSize, GTT_PAGE_SIZE)
- / GTT_PAGE_SIZE;
- unsigned long aperStart = ROUND_TO(pI830->FbMapSize - KB(pI830->mmSize), GTT_PAGE_SIZE)
- / GTT_PAGE_SIZE;
-
- if (aperEnd < aperStart || aperEnd - aperStart < I830_MM_MINPAGES) {
+ if (pI830->directRenderingEnabled && (pI830->mmModeFlags & I830_KERNEL_MM))
+ {
+ if (pI830->memory_manager == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Too little AGP aperture space for DRM memory manager.\n"
- "\tPlease increase AGP aperture size from BIOS configuration screen\n"
- "\tor decrease the amount of video RAM using option \"VideoRam\".\n"
+ "\tPlease increase AGP aperture size from BIOS configuration screen.\n"
"\tDisabling DRI.\n");
pI830->directRenderingOpen = FALSE;
I830DRICloseScreen(pScreen);
pI830->directRenderingEnabled = FALSE;
} else {
#ifndef XSERVER_LIBDRM_MM
- if (I830DrmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart,
+ if (I830DrmMMInit(pI830->drmSubFD, pI830->memory_manager->offset,
+ pI830->memory_manager->size,
DRM_BO_MEM_TT)) {
#else
- if (drmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart,
+ if (drmMMInit(pI830->drmSubFD, pI830->memory_manager->offset,
+ pI830->memory_manager->size,
DRM_BO_MEM_TT)) {
#endif
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -2911,12 +2742,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pI830->directRenderingOpen = FALSE;
I830DRICloseScreen(pScreen);
pI830->directRenderingEnabled = FALSE;
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Initialized DRM memory manager, %ld AGP pages\n"
- "\tat AGP offset 0x%lx\n",
- aperEnd - aperStart,
- aperStart);
}
}
}
@@ -2973,7 +2798,7 @@ I830LeaveVT(int scrnIndex, int flags)
if (!I830IsPrimary(pScrn)) {
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
- if (!pI8301->GttBound) {
+ if (!pI8301->gtt_acquired) {
return;
}
}
@@ -3007,7 +2832,7 @@ I830LeaveVT(int scrnIndex, int flags)
i830DumpRegs (pScrn);
if (I830IsPrimary(pScrn))
- I830UnbindAGPMemory(pScrn);
+ i830_unbind_all_memory(pScrn);
if (pI830->AccelInfoRec)
pI830->AccelInfoRec->NeedToSync = FALSE;
}
@@ -3043,7 +2868,7 @@ I830EnterVT(int scrnIndex, int flags)
#endif
if (I830IsPrimary(pScrn))
- if (!I830BindAGPMemory(pScrn))
+ if (!i830_bind_all_memory(pScrn))
return FALSE;
if (i830_check_error_state(pScrn)) {
@@ -3228,8 +3053,6 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen)
xfree(pI830->LpRing);
pI830->LpRing = NULL;
- xfree(pI830->OverlayMem);
- pI830->OverlayMem = NULL;
xfree(pI830->overlayOn);
pI830->overlayOn = NULL;
xfree(pI830->used3D);
@@ -3398,7 +3221,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
xf86ProbeOutputModes (pScrn, 0, 0);
xf86SetScrnInfoModes (pScrn);
- I830DGAReInit (pScrn->pScreen);
+ xf86DiDGAReInit (pScrn->pScreen);
xf86SwitchMode(pScrn->pScreen, pScrn->currentMode);
/* Clear the BIOS's hotkey press flags */
diff --git a/src/i830_edid_modes.c b/src/i830_edid_modes.c
deleted file mode 100644
index 1bab4cd8..00000000
--- a/src/i830_edid_modes.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright 2006 Luc Verhaegen.
- *
- * 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, sub license,
- * 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 NON-INFRINGEMENT. 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.
- */
-
-/**
- * @file This is a copy of edid_modes.c from the X Server, for compatibility
- * with old X Servers.
- */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86DDC.h"
-#include <X11/Xatom.h>
-#include "property.h"
-#include "propertyst.h"
-#include "xf86DDC.h"
-#include "i830.h"
-#include "i830_display.h"
-#include <string.h>
-#include <math.h>
-
-#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
-
-/*
- * Quirks to work around broken EDID data from various monitors.
- */
-
-typedef enum {
- DDC_QUIRK_NONE = 0,
- /* Force detailed sync polarity to -h +v */
- DDC_QUIRK_DT_SYNC_HM_VP = 1 << 0,
- /* First detailed mode is bogus, prefer largest mode at 60hz */
- DDC_QUIRK_PREFER_LARGE_60 = 1 << 1,
- /* 135MHz clock is too high, drop a bit */
- DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 2
-} ddc_quirk_t;
-
-static Bool quirk_dt_sync_hm_vp (int scrnIndex, xf86MonPtr DDC)
-{
- /* Belinea 1924S1W */
- if (memcmp (DDC->vendor.name, "MAX", 4) == 0 &&
- DDC->vendor.prod_id == 1932)
- return TRUE;
- /* Belinea 10 20 30W */
- if (memcmp (DDC->vendor.name, "MAX", 4) == 0 &&
- DDC->vendor.prod_id == 2007)
- return TRUE;
-
- return FALSE;
-}
-
-static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
-{
- /* Belinea 10 15 55 */
- if (memcmp (DDC->vendor.name, "MAX", 4) == 0 &&
- DDC->vendor.prod_id == 1516)
- return TRUE;
-
- return FALSE;
-}
-
-static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC)
-{
- /* Envision Peripherals, Inc. EN-7100e. See bug #9550. */
- if (memcmp (DDC->vendor.name, "EPI", 4) == 0 &&
- DDC->vendor.prod_id == 59264)
- return TRUE;
-
- return FALSE;
-}
-
-typedef struct {
- Bool (*detect) (int scrnIndex, xf86MonPtr DDC);
- ddc_quirk_t quirk;
- char *description;
-} ddc_quirk_map_t;
-
-static const ddc_quirk_map_t ddc_quirks[] = {
- {
- quirk_dt_sync_hm_vp, DDC_QUIRK_DT_SYNC_HM_VP,
- "Set detailed timing sync polarity to -h +v"
- },
- {
- quirk_prefer_large_60, DDC_QUIRK_PREFER_LARGE_60,
- "Detailed timing is not preferred, use largest mode at 60Hz"
- },
- {
- quirk_135_clock_too_high, DDC_QUIRK_135_CLOCK_TOO_HIGH,
- "Recommended 135MHz pixel clock is too high"
- },
- {
- NULL, DDC_QUIRK_NONE,
- "No known quirks"
- },
-};
-
-/*
- * TODO:
- * - for those with access to the VESA DMT standard; review please.
- */
-#define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DRIVER
-#define MODESUFFIX 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0
-
-static DisplayModeRec DDCEstablishedModes[17] = {
- { MODEPREFIX("800x600"), 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@60Hz */
- { MODEPREFIX("800x600"), 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@56Hz */
- { MODEPREFIX("640x480"), 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@75Hz */
- { MODEPREFIX("640x480"), 31500, 640, 664, 704, 832, 0, 480, 489, 491, 520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@72Hz */
- { MODEPREFIX("640x480"), 30240, 640, 704, 768, 864, 0, 480, 483, 486, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@67Hz */
- { MODEPREFIX("640x480"), 25200, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@60Hz */
- { MODEPREFIX("720x400"), 35500, 720, 738, 846, 900, 0, 400, 421, 423, 449, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 720x400@88Hz */
- { MODEPREFIX("720x400"), 28320, 720, 738, 846, 900, 0, 400, 412, 414, 449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400@70Hz */
- { MODEPREFIX("1280x1024"), 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@75Hz */
- { MODEPREFIX("1024x768"), 78800, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@75Hz */
- { MODEPREFIX("1024x768"), 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@70Hz */
- { MODEPREFIX("1024x768"), 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@60Hz */
- { MODEPREFIX("1024x768"), 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 776, 817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768@43Hz */
- { MODEPREFIX("832x624"), 57284, 832, 864, 928, 1152, 0, 624, 625, 628, 667, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 832x624@75Hz */
- { MODEPREFIX("800x600"), 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@75Hz */
- { MODEPREFIX("800x600"), 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@72Hz */
- { MODEPREFIX("1152x864"), 108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864@75Hz */
-};
-
-static DisplayModePtr
-DDCModesFromEstablished(int scrnIndex, struct established_timings *timing,
- ddc_quirk_t quirks)
-{
- DisplayModePtr Modes = NULL, Mode = NULL;
- CARD32 bits = (timing->t1) | (timing->t2 << 8) |
- ((timing->t_manu & 0x80) << 9);
- int i;
-
- for (i = 0; i < 17; i++) {
- if (bits & (0x01 << i)) {
- Mode = xf86DuplicateMode(&DDCEstablishedModes[i]);
- Modes = xf86ModesAdd(Modes, Mode);
- }
- }
-
- return Modes;
-}
-
-/*
- *
- */
-static DisplayModePtr
-DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing,
- ddc_quirk_t quirks)
-{
- DisplayModePtr Modes = NULL, Mode = NULL;
- int i;
-
- for (i = 0; i < STD_TIMINGS; i++) {
- if (timing[i].hsize && timing[i].vsize && timing[i].refresh) {
- Mode = xf86CVTMode(timing[i].hsize, timing[i].vsize,
- timing[i].refresh, FALSE, FALSE);
- Mode->type = M_T_DRIVER;
- Modes = xf86ModesAdd(Modes, Mode);
- }
- }
-
- return Modes;
-}
-
-/*
- *
- */
-static DisplayModePtr
-DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
- int preferred, ddc_quirk_t quirks)
-{
- DisplayModePtr Mode;
-
- /* We don't do stereo */
- if (timing->stereo) {
- xf86DrvMsg(scrnIndex, X_INFO,
- "%s: Ignoring: We don't handle stereo.\n", __func__);
- return NULL;
- }
-
- /* We only do seperate sync currently */
- if (timing->sync != 0x03) {
- xf86DrvMsg(scrnIndex, X_INFO,
- "%s: %dx%d Warning: We only handle seperate"
- " sync.\n", __func__, timing->h_active, timing->v_active);
- }
-
- Mode = xnfalloc(sizeof(DisplayModeRec));
- memset(Mode, 0, sizeof(DisplayModeRec));
-
- Mode->type = M_T_DRIVER;
- if (preferred)
- Mode->type |= M_T_PREFERRED;
-
- if( ( quirks & DDC_QUIRK_135_CLOCK_TOO_HIGH ) &&
- timing->clock == 135000000 )
- Mode->Clock = 108880;
- else
- Mode->Clock = timing->clock / 1000.0;
-
- Mode->HDisplay = timing->h_active;
- Mode->HSyncStart = timing->h_active + timing->h_sync_off;
- Mode->HSyncEnd = Mode->HSyncStart + timing->h_sync_width;
- Mode->HTotal = timing->h_active + timing->h_blanking;
-
- Mode->VDisplay = timing->v_active;
- Mode->VSyncStart = timing->v_active + timing->v_sync_off;
- Mode->VSyncEnd = Mode->VSyncStart + timing->v_sync_width;
- Mode->VTotal = timing->v_active + timing->v_blanking;
-
- xf86SetModeDefaultName(Mode);
-
- /* We ignore h/v_size and h/v_border for now. */
-
- if (timing->interlaced)
- Mode->Flags |= V_INTERLACE;
-
- if (quirks & DDC_QUIRK_DT_SYNC_HM_VP)
- Mode->Flags |= V_NHSYNC | V_PVSYNC;
- else
- {
- if (timing->misc & 0x02)
- Mode->Flags |= V_PHSYNC;
- else
- Mode->Flags |= V_NHSYNC;
-
- if (timing->misc & 0x01)
- Mode->Flags |= V_PVSYNC;
- else
- Mode->Flags |= V_NVSYNC;
- }
-
- return Mode;
-}
-
-DisplayModePtr
-xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
-{
- int preferred, i;
- DisplayModePtr Modes = NULL, Mode;
- ddc_quirk_t quirks;
-
- xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n",
- DDC->vendor.name, DDC->vendor.prod_id);
- quirks = DDC_QUIRK_NONE;
- for (i = 0; ddc_quirks[i].detect; i++)
- if (ddc_quirks[i].detect (scrnIndex, DDC))
- {
- xf86DrvMsg (scrnIndex, X_INFO, " EDID quirk: %s\n",
- ddc_quirks[i].description);
- quirks |= ddc_quirks[i].quirk;
- }
-
- preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
- if (quirks & DDC_QUIRK_PREFER_LARGE_60)
- preferred = 0;
-
- for (i = 0; i < DET_TIMINGS; i++) {
- struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
-
- switch (det_mon->type) {
- case DT:
- Mode = DDCModeFromDetailedTiming(scrnIndex,
- &det_mon->section.d_timings,
- preferred,
- quirks);
- preferred = 0;
- Modes = xf86ModesAdd(Modes, Mode);
- break;
- case DS_STD_TIMINGS:
- Mode = DDCModesFromStandardTiming(scrnIndex,
- det_mon->section.std_t,
- quirks);
- Modes = xf86ModesAdd(Modes, Mode);
- break;
- default:
- break;
- }
- }
-
- /* Add established timings */
- Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1, quirks);
- Modes = xf86ModesAdd(Modes, Mode);
-
- /* Add standard timings */
- Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2, quirks);
- Modes = xf86ModesAdd(Modes, Mode);
-
- if (quirks & DDC_QUIRK_PREFER_LARGE_60)
- {
- DisplayModePtr best = Modes;
- for (Mode = Modes; Mode; Mode = Mode->next)
- {
- if (Mode == best) continue;
- if (Mode->HDisplay * Mode->VDisplay > best->HDisplay * best->VDisplay)
- {
- best = Mode;
- continue;
- }
- if (Mode->HDisplay * Mode->VDisplay == best->HDisplay * best->VDisplay)
- {
- double mode_refresh = xf86ModeVRefresh (Mode);
- double best_refresh = xf86ModeVRefresh (best);
- double mode_dist = fabs(mode_refresh - 60.0);
- double best_dist = fabs(best_refresh - 60.0);
- if (mode_dist < best_dist)
- {
- best = Mode;
- continue;
- }
- }
- }
- if (best)
- best->type |= M_T_PREFERRED;
- }
- return Modes;
-}
-
-#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) */
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 97b4a98e..bef8faef 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -297,6 +297,93 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
}
}
+/**
+ * Uploads data from system memory to the framebuffer using a series of
+ * 8x8 pattern blits.
+ */
+static Bool
+i830_upload_to_screen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
+ int src_pitch)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+ const int uts_width_max = 16, uts_height_max = 16;
+ int cpp = pDst->drawable.bitsPerPixel / 8;
+ int sub_x, sub_y;
+ CARD32 br13;
+ CARD32 offset;
+
+ if (w > uts_width_max || h > uts_height_max)
+ I830FALLBACK("too large for upload to screen (%d,%d)", w, h);
+
+ offset = exaGetPixmapOffset(pDst);
+
+ br13 = exaGetPixmapPitch(pDst);
+ br13 |= ((I830PatternROP[GXcopy] & 0xff) << 16);
+ switch (pDst->drawable.bitsPerPixel) {
+ case 16:
+ br13 |= 1 << 24;
+ break;
+ case 32:
+ br13 |= 3 << 24;
+ break;
+ }
+
+ for (sub_y = 0; sub_y < uts_height_max && sub_y < h; sub_y += 8) {
+ int sub_height;
+
+ if (sub_y + 8 > h)
+ sub_height = h - sub_y;
+ else
+ sub_height = 8;
+
+ for (sub_x = 0; sub_x < uts_width_max && sub_x < w; sub_x += 8) {
+ int sub_width, line;
+ char *src_line = src + sub_y * src_pitch + sub_x * cpp;
+
+ if (sub_x + 8 > w)
+ sub_width = w - sub_x;
+ else
+ sub_width = 8;
+
+ BEGIN_LP_RING(6 + (cpp * 8 * 8 / 4));
+
+ /* XXX We may need a pattern offset here for {x,y} % 8 != 0*/
+ OUT_RING(XY_PAT_BLT_IMMEDIATE |
+ XY_SRC_COPY_BLT_WRITE_ALPHA |
+ XY_SRC_COPY_BLT_WRITE_RGB |
+ (3 + cpp * 8 * 8 / 4));
+ OUT_RING(br13);
+ OUT_RING(((y + sub_y) << 16) | (x + sub_x));
+ OUT_RING(((y + sub_y + sub_height) << 16) |
+ (x + sub_x + sub_width));
+ OUT_RING(offset);
+
+ /* Write out the lines with valid data, followed by any needed
+ * padding
+ */
+ for (line = 0; line < sub_height; line++) {
+ OUT_RING_COPY(sub_width * cpp, src_line);
+ src_line += src_pitch;
+ if (sub_width != 8)
+ OUT_RING_PAD((8 - sub_width) * cpp);
+ }
+ /* Write out any full padding lines to follow */
+ if (sub_height != 8)
+ OUT_RING_PAD(8 * cpp * (8 - sub_height));
+
+ OUT_RING(MI_NOOP);
+ ADVANCE_LP_RING();
+ }
+ }
+
+ exaMarkSync(pDst->drawable.pScreen);
+ /* exaWaitSync(pDst->drawable.pScreen); */
+
+ return TRUE;
+}
+
+
/*
* TODO:
* - Dual head?
@@ -318,8 +405,9 @@ I830EXAInit(ScreenPtr pScreen)
pI830->EXADriverPtr->exa_major = 2;
pI830->EXADriverPtr->exa_minor = 1;
pI830->EXADriverPtr->memoryBase = pI830->FbBase;
- pI830->EXADriverPtr->offScreenBase = pI830->Offscreen.Start;
- pI830->EXADriverPtr->memorySize = pI830->Offscreen.End;
+ pI830->EXADriverPtr->offScreenBase = pI830->exa_offscreen->offset;
+ pI830->EXADriverPtr->memorySize = pI830->exa_offscreen->offset +
+ pI830->exa_offscreen->size;
DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, memorySize 0x%x\n",
pI830->EXADriverPtr->memoryBase,
@@ -346,7 +434,8 @@ I830EXAInit(ScreenPtr pScreen)
* i965 limits 3D surface to 4kB-aligned offset if tiled.
* i965 limits 3D surfaces to w,h of ?,8192.
* i965 limits 3D surface to pitch of 1B - 128kB.
- * i965 limits 3D surface pitch alignment to 512B, only if tiled.
+ * i965 limits 3D surface pitch alignment to 1 or 2 times the element size.
+ * i965 limits 3D surface pitch alignment to 512B if tiled.
* i965 limits 3D destination drawing rect to w,h of 8192,8192.
*
* i915 limits 3D textures to 4B-aligned offset if un-tiled.
@@ -374,7 +463,7 @@ I830EXAInit(ScreenPtr pScreen)
*/
if (IS_I965G(pI830)) {
pI830->EXADriverPtr->pixmapOffsetAlign = 4 * 2;
- pI830->EXADriverPtr->pixmapPitchAlign = 1;
+ pI830->EXADriverPtr->pixmapPitchAlign = 16;
pI830->EXADriverPtr->maxX = 8192;
pI830->EXADriverPtr->maxY = 8192;
} else {
@@ -419,6 +508,10 @@ I830EXAInit(ScreenPtr pScreen)
pI830->EXADriverPtr->DoneComposite = i830_done_composite;
}
+ /* UploadToScreen/DownloadFromScreen */
+ if (0)
+ pI830->EXADriverPtr->UploadToScreen = i830_upload_to_screen;
+
if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"EXA initialization failed; trying older version\n");
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 59af13b9..642dd8a3 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -32,6 +32,7 @@
#include "xf86.h"
#include "i830.h"
#include "i830_bios.h"
+#include "i830_display.h"
#include "X11/Xatom.h"
/**
@@ -406,21 +407,99 @@ i830_lvds_init(ScrnInfoPtr pScrn)
I830Ptr pI830 = I830PTR(pScrn);
xf86OutputPtr output;
I830OutputPrivatePtr intel_output;
+ DisplayModePtr modes, scan, bios_mode;
+ output = xf86OutputCreate (pScrn, &i830_lvds_output_funcs, "LVDS");
+ if (!output)
+ return;
+ intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1);
+ if (!intel_output)
+ {
+ xf86OutputDestroy (output);
+ return;
+ }
+ intel_output->type = I830_OUTPUT_LVDS;
+ output->driver_private = intel_output;
+ output->subpixel_order = SubPixelHorizontalRGB;
+ output->interlaceAllowed = FALSE;
+ output->doubleScanAllowed = FALSE;
+
+ /* Set up the LVDS DDC channel. Most panels won't support it, but it can
+ * be useful if available.
+ */
+ I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOC, "LVDSDDC_C");
+
+ /* Attempt to get the fixed panel mode from DDC. Assume that the preferred
+ * mode is the right one.
+ */
+ modes = i830_ddc_get_modes(output);
+ for (scan = modes; scan != NULL; scan = scan->next) {
+ if (scan->type & M_T_PREFERRED)
+ break;
+ }
+ if (scan != NULL) {
+ /* Pull our chosen mode out and make it the fixed mode */
+ if (modes == scan)
+ modes = modes->next;
+ if (scan->prev != NULL)
+ scan->prev = scan->next;
+ if (scan->next != NULL)
+ scan->next = scan->prev;
+ pI830->panel_fixed_mode = scan;
+ }
+ /* Delete the mode list */
+ while (modes != NULL)
+ xf86DeleteMode(&modes, modes);
+
+ /* If we didn't get EDID, try checking if the panel is already turned on.
+ * If so, assume that whatever is currently programmed is the correct mode.
+ */
+ if (pI830->panel_fixed_mode == NULL) {
+ CARD32 lvds = INREG(LVDS);
+ int pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86CrtcPtr crtc = xf86_config->crtc[pipe];
+
+ if (lvds & LVDS_PORT_EN) {
+ pI830->panel_fixed_mode = i830_crtc_mode_get(pScrn, crtc);
+ if (pI830->panel_fixed_mode != NULL)
+ pI830->panel_fixed_mode->type |= M_T_PREFERRED;
+ }
+ }
/* Get the LVDS fixed mode out of the BIOS. We should support LVDS with
* the BIOS being unavailable or broken, but lack the configuration options
* for now.
*/
- if (!i830GetLVDSInfoFromBIOS(pScrn))
- return;
+ bios_mode = i830_bios_get_panel_mode(pScrn);
+ if (bios_mode != NULL) {
+ if (pI830->panel_fixed_mode != NULL) {
+ if (!xf86ModesEqual(pI830->panel_fixed_mode, bios_mode)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "BIOS panel mode data doesn't match probed data, "
+ "continuing with probed.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS mode:\n");
+ xf86PrintModeline(pScrn->scrnIndex, bios_mode);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "probed mode:\n");
+ xf86PrintModeline(pScrn->scrnIndex, pI830->panel_fixed_mode);
+ xfree(bios_mode->name);
+ xfree(bios_mode);
+ }
+ } else {
+ pI830->panel_fixed_mode = bios_mode;
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Couldn't detect panel mode. Disabling panel\n");
+ goto disable_exit;
+ }
/* Blacklist machines with BIOSes that list an LVDS panel without actually
* having one.
*/
if (pI830->PciInfo->chipType == PCI_CHIP_I945_GM) {
if (pI830->PciInfo->subsysVendor == 0xa0a0) /* aopen mini pc */
- return;
+ goto disable_exit;
if ((pI830->PciInfo->subsysVendor == 0x8086) &&
(pI830->PciInfo->subsysCard == 0x7270)) {
@@ -435,31 +514,18 @@ i830_lvds_init(ScrnInfoPtr pScrn)
if (pI830->panel_fixed_mode != NULL &&
pI830->panel_fixed_mode->HDisplay == 800 &&
- pI830->panel_fixed_mode->VDisplay == 600) {
+ pI830->panel_fixed_mode->VDisplay == 600)
+ {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Suspected Mac Mini, ignoring the LVDS\n");
- return;
+ goto disable_exit;
}
}
- }
-
- output = xf86OutputCreate (pScrn, &i830_lvds_output_funcs, "LVDS");
- if (!output)
- return;
- intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1);
- if (!intel_output)
- {
- xf86OutputDestroy (output);
- return;
}
- intel_output->type = I830_OUTPUT_LVDS;
- output->driver_private = intel_output;
- output->subpixel_order = SubPixelHorizontalRGB;
- output->interlaceAllowed = FALSE;
- output->doubleScanAllowed = FALSE;
- /* Set up the LVDS DDC channel. Most panels won't support it, but it can
- * be useful if available.
- */
- I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOC, "LVDSDDC_C");
+ return;
+
+disable_exit:
+ xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE);
+ xf86OutputDestroy(output);
}
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 6ceb05b5..5cddf173 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -50,6 +50,51 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* Alan Hourihane <alanh@tungstengraphics.com>
*/
+/**
+ * @file i830_memory.c
+ *
+ * This is the video memory allocator. Our memory allocation is different from
+ * other graphics chips, where you have a fixed amount of graphics memory
+ * available that you want to put to the best use. Instead, we have almost no
+ * memory pre-allocated, and we have to choose an appropriate amount of sytem
+ * memory to use.
+ *
+ * The allocations we might do:
+ *
+ * - Ring buffer
+ * - HW cursor 1
+ * - HW cursor 2
+ * - HW ARGB cursor 1
+ * - HW ARGB cursor 2
+ * - Overlay registers
+ * - XAA linear allocator (optional)
+ * - EXA 965 state buffer
+ * - XAA scratch (screen 1)
+ * - XAA scratch (screen 2, only in zaphod mode)
+ * - Front buffer (screen 1, more is better for XAA)
+ * - Front buffer (screen 2, only in zaphod mode, more is better for XAA)
+ * - Back/depth buffer (3D only)
+ * - Compatibility texture pool (optional, more is always better)
+ * - New texture pool (optional, more is always better. aperture allocation
+ * only)
+ * - EXA offscreen pool (more is always better)
+ *
+ * We also want to be able to resize the front/back/depth buffers, and then
+ * resize the EXA and texture memory pools appropriately.
+ *
+ * The user may request a specific amount of memory to be used
+ * (pI830->pEnt->videoRam != 0), in which case allocations have to fit within
+ * that much aperture. If not, the individual allocations will be
+ * automatically sized, and will be fit within the maximum aperture size.
+ * Only the actual memory used (not alignment padding) will get actual AGP
+ * memory allocated.
+ *
+ * Given that the allocations listed are generally a page or more than a page,
+ * our allocator will only return page-aligned offsets, simplifying the memory
+ * binding process. For smaller allocations, the acceleration architecture's
+ * linear allocator is preferred.
+ */
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -62,429 +107,608 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "i830.h"
#include "i810_reg.h"
-static int nextTile = 0;
-static unsigned int tileGeneration = -1;
+#define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1))
+enum tile_format {
+ TILING_NONE,
+ TILING_XMAJOR,
+ TILING_YMAJOR
+};
+
+static void i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset,
+ unsigned int pitch, unsigned int size,
+ enum tile_format tile_format);
+
+/**
+ * Returns the fence size for a tiled area of the given size.
+ */
static unsigned long
-GetBestTileAlignment(unsigned long size)
+i830_get_fence_size(ScrnInfoPtr pScrn, unsigned long size)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long i;
+ unsigned long start;
+
+ if (IS_I965G(pI830)) {
+ /* The 965 can have fences at any page boundary. */
+ return ALIGN(size, GTT_PAGE_SIZE);
+ } else {
+ /* Align the size to a power of two greater than the smallest fence
+ * size.
+ */
+ if (IS_I9XX(pI830))
+ start = MB(1);
+ else
+ start = KB(512);
+
+ for (i = start; i < size; i <<= 1)
+ ;
+
+ return i;
+ }
+}
+
+static Bool
+i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
{
- unsigned long i;
+ I830Ptr pI830 = I830PTR(pScrn);
- for (i = KB(512); i < size; i <<= 1)
- ;
+ if (mem == NULL || mem->key == -1 || mem->bound || !pI830->gtt_acquired)
+ return TRUE;
- if (i > MB(64))
- i = MB(64);
+ if (xf86BindGARTMemory(pScrn->scrnIndex, mem->key, mem->agp_offset)) {
+ mem->bound = TRUE;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
- return i;
+ return TRUE;
}
-/*
- * Allocate memory from the given pool. Grow the pool if needed and if
- * possible.
- */
-static unsigned long
-AllocFromPool(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool,
- long size, unsigned long alignment, int flags)
+static Bool
+i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
{
- I830Ptr pI830 = I830PTR(pScrn);
- long needed, start, end;
- Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
-
- if (!result || !pool || !size)
- return 0;
-
- /* Calculate how much space is needed. */
- if (alignment <= GTT_PAGE_SIZE)
- needed = size;
- else {
- if (flags & ALLOCATE_AT_BOTTOM) {
- start = ROUND_TO(pool->Free.Start, alignment);
- if (flags & ALIGN_BOTH_ENDS)
- end = ROUND_TO(start + size, alignment);
- else
- end = start + size;
- needed = end - pool->Free.Start;
- } else { /* allocate at top */
- if (flags & ALIGN_BOTH_ENDS)
- end = ROUND_DOWN_TO(pool->Free.End, alignment);
- else
- end = pool->Free.End;
-
- start = ROUND_DOWN_TO(end - size, alignment);
- needed = end - start;
- }
- }
- if (needed > pool->Free.Size) {
- long extra;
- /* See if the pool can be grown. */
- if (pI830->StolenOnly && !dryrun)
- return 0;
- extra = needed - pool->Free.Size;
- extra = ROUND_TO_PAGE(extra);
- if (extra > pI830->FreeMemory) {
- if (dryrun)
- pI830->FreeMemory = extra;
- else
- return 0;
- }
-
- if (!dryrun && ((long)extra > pI830->MemoryAperture.Size))
- return 0;
-
- pool->Free.Size += extra;
- pool->Free.End += extra;
- pool->Total.Size += extra;
- pool->Total.End += extra;
- pI830->FreeMemory -= extra;
- pI830->MemoryAperture.Start += extra;
- pI830->MemoryAperture.Size -= extra;
- }
- if (flags & ALLOCATE_AT_BOTTOM) {
- result->Start = ROUND_TO(pool->Free.Start, alignment);
- pool->Free.Start += needed;
- result->End = pool->Free.Start;
- } else {
- result->Start = ROUND_DOWN_TO(pool->Free.End - size, alignment);
- pool->Free.End -= needed;
- result->End = result->Start + needed;
- }
- pool->Free.Size = pool->Free.End - pool->Free.Start;
- result->Size = result->End - result->Start;
- result->Pool = pool;
- result->Alignment = alignment;
- return needed;
+ if (mem == NULL || mem->key == -1 || !mem->bound)
+ return TRUE;
+
+ if (xf86UnbindGARTMemory(pScrn->scrnIndex, mem->key)) {
+ mem->bound = FALSE;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
}
-static unsigned long
-AllocFromAGP(ScrnInfoPtr pScrn, I830MemRange *result, long size,
- unsigned long alignment, int flags)
+void
+i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem)
{
- I830Ptr pI830 = I830PTR(pScrn);
- unsigned long start, end;
- unsigned long newApStart, newApEnd;
- Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
-
- if (!result || !size)
- return 0;
-
- if ((flags & ALLOCATE_AT_BOTTOM) && pI830->StolenMemory.Size != 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "AllocFromAGP(): can't allocate from "
- "bottom when there is stolen memory\n");
- return 0;
- }
-
- if (size > pI830->FreeMemory) {
- if (dryrun)
- pI830->FreeMemory = size;
- else
- return 0;
- }
-
- /* Calculate offset */
- if (flags & ALLOCATE_AT_BOTTOM) {
- start = ROUND_TO(pI830->MemoryAperture.Start, alignment);
- if (flags & ALIGN_BOTH_ENDS)
- end = ROUND_TO(start + size, alignment);
- else
- end = start + size;
- newApStart = end;
- newApEnd = pI830->MemoryAperture.End;
- } else {
- if (flags & ALIGN_BOTH_ENDS)
- end = ROUND_DOWN_TO(pI830->MemoryAperture.End, alignment);
- else
- end = pI830->MemoryAperture.End;
- start = ROUND_DOWN_TO(end - size, alignment);
- newApStart = pI830->MemoryAperture.Start;
- newApEnd = start;
- }
-
- if (!dryrun) {
- if (newApStart > newApEnd)
- return 0;
-
- if (flags & NEED_PHYSICAL_ADDR)
- result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2,
- &(result->Physical));
- else
- result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
-
- if (result->Key == -1)
- return 0;
- }
-
- pI830->allocatedMemory += size;
- pI830->MemoryAperture.Start = newApStart;
- pI830->MemoryAperture.End = newApEnd;
- pI830->MemoryAperture.Size = newApEnd - newApStart;
- pI830->FreeMemory -= size;
- result->Start = start;
- result->End = start + size;
- result->Size = size;
- result->Offset = start;
- result->Alignment = alignment;
- result->Pool = NULL;
-
- return size;
+ if (mem == NULL)
+ return;
+
+ i830_unbind_memory(pScrn, mem);
+
+ /* Disconnect from the list of allocations */
+ if (mem->prev != NULL)
+ mem->prev->next = mem->next;
+ if (mem->next != NULL)
+ mem->next->prev = mem->prev;
+
+ /* Free any AGP memory. */
+ i830_unbind_memory(pScrn, mem);
+
+ if (mem->key != -1) {
+ xf86DeallocateGARTMemory(pScrn->scrnIndex, mem->key);
+ mem->key = -1;
+ }
+
+ xfree(mem->name);
+ xfree(mem);
}
+/* Resets the state of the aperture allocator, freeing all memory that had
+ * been allocated.
+ */
void
-I830FreeVidMem(ScrnInfoPtr pScrn, I830MemRange *range)
+i830_reset_allocations(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int i;
+
+ /* While there is any memory between the start and end markers, free it. */
+ while (pI830->memory_list->next->next != NULL)
+ i830_free_memory(pScrn, pI830->memory_list->next);
+
+ /* Null out the pointers for all the allocations we just freed. This is
+ * kind of gross, but at least it's just one place now.
+ */
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private;
+
+ intel_crtc->cursor_mem = NULL;
+ intel_crtc->cursor_mem_argb = NULL;
+ }
+
+ pI830->front_buffer = NULL;
+ pI830->front_buffer_2 = NULL;
+ pI830->xaa_scratch = NULL;
+ pI830->xaa_scratch_2 = NULL;
+ pI830->exa_offscreen = NULL;
+ pI830->exa_965_state = NULL;
+ pI830->overlay_regs = NULL;
+ pI830->xaa_linear = NULL;
+ pI830->logical_context = NULL;
+ pI830->back_buffer = NULL;
+ pI830->depth_buffer = NULL;
+ pI830->textures = NULL;
+ pI830->memory_manager = NULL;
+ pI830->LpRing->mem = NULL;
+
+ /* Reset the fence register allocation. */
+ pI830->next_fence = 0;
+ memset(pI830->fence, 0, sizeof(pI830->fence));
+}
+
+void
+i830_free_3d_memory(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ i830_free_memory(pScrn, pI830->back_buffer);
+ pI830->back_buffer = NULL;
+ i830_free_memory(pScrn, pI830->depth_buffer);
+ pI830->depth_buffer = NULL;
+ i830_free_memory(pScrn, pI830->textures);
+ pI830->textures = NULL;
+ i830_free_memory(pScrn, pI830->memory_manager);
+ pI830->memory_manager = NULL;
+}
+
+/**
+ * Initialize's the driver's video memory allocator to allocate in the
+ * given range.
+ */
+Bool
+i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset,
+ unsigned long size)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ i830_memory *start, *end;
+
+ start = xcalloc(1, sizeof(*start));
+ if (start == NULL)
+ return FALSE;
+ start->name = xstrdup("start marker");
+ if (start->name == NULL) {
+ xfree(start);
+ return FALSE;
+ }
+ end = xcalloc(1, sizeof(*end));
+ if (end == NULL) {
+ xfree(start->name);
+ xfree(start);
+ return FALSE;
+ }
+ end->name = xstrdup("end marker");
+ if (end->name == NULL) {
+ xfree(start->name);
+ xfree(start);
+ xfree(end);
+ return FALSE;
+ }
+
+ start->key = -1;
+ start->offset = offset;
+ start->end = start->offset;
+ start->size = 0;
+ start->next = end;
+ end->key = -1;
+ end->offset = offset + size;
+ end->end = end->offset;
+ end->size = 0;
+ end->prev = start;
+
+ pI830->memory_list = start;
+
+ return TRUE;
+}
+
+/* Allocate aperture space for the given size and alignment, and returns the
+ * memory allocation.
+ *
+ * Allocations are a minimum of a page, and will be at least page-aligned.
+ */
+static i830_memory *
+i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name,
+ long size, unsigned long alignment, int flags)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ i830_memory *mem, *scan;
+
+ mem = xcalloc(1, sizeof(*mem));
+ if (mem == NULL)
+ return NULL;
+
+ /* No memory allocated to back the region */
+ mem->key = -1;
+
+ mem->name = xstrdup(name);
+ if (mem->name == NULL) {
+ xfree(mem);
+ return NULL;
+ }
+ /* Only allocate page-sized increments. */
+ size = ALIGN(size, GTT_PAGE_SIZE);
+ mem->size = size;
+
+ if (alignment < GTT_PAGE_SIZE)
+ alignment = GTT_PAGE_SIZE;
+
+ for (scan = pI830->memory_list; scan->next != NULL; scan = scan->next) {
+ mem->offset = scan->end;
+ /* For allocations requiring physical addresses, we have to use AGP
+ * memory, so move the allocation up out of stolen memory.
+ */
+ if ((flags & NEED_PHYSICAL_ADDR) && mem->offset < pI830->stolen_size)
+ mem->offset = pI830->stolen_size;
+ mem->offset = ROUND_TO(mem->offset, alignment);
+
+ mem->end = mem->offset + size;
+ if (flags & ALIGN_BOTH_ENDS)
+ mem->end = ROUND_TO(mem->end, alignment);
+ if (mem->end <= scan->next->offset)
+ break;
+ }
+ if (scan->next == NULL) {
+ /* Reached the end of the list, and didn't find space */
+ xfree(mem->name);
+ xfree(mem);
+ return NULL;
+ }
+ /* Insert new allocation into the list */
+ mem->prev = scan;
+ mem->next = scan->next;
+ scan->next = mem;
+ mem->next->prev = scan;
+
+ return mem;
+}
+
+/**
+ * Allocates the AGP memory necessary for the part of a memory allocation not
+ * already covered by the stolen memory.
+ *
+ * The memory is automatically bound if we have the VT.
+ */
+static Bool
+i830_allocate_agp_memory(ScrnInfoPtr pScrn, i830_memory *mem, int flags)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long size;
+
+ if (mem->key != -1)
+ return TRUE;
+
+ if (mem->offset + mem->size <= pI830->stolen_size &&
+ !(flags & NEED_PHYSICAL_ADDR))
+ {
+ return TRUE;
+ }
+
+ if (mem->offset < pI830->stolen_size)
+ mem->agp_offset = pI830->stolen_size;
+ else
+ mem->agp_offset = mem->offset;
+
+ size = mem->size - (mem->agp_offset - mem->offset);
+
+ if (flags & NEED_PHYSICAL_ADDR)
+ mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2,
+ &mem->bus_addr);
+ else
+ mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
+ if (mem->key == -1 || ((flags & NEED_PHYSICAL_ADDR) && mem->bus_addr == 0))
+ {
+ return FALSE;
+ }
+
+ if (!i830_bind_memory(pScrn, mem)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/* Allocates video memory at the given size and alignment.
+ *
+ * The memory will be bound automatically when the driver is in control of the
+ * VT.
+ */
+static i830_memory *
+i830_allocate_memory(ScrnInfoPtr pScrn, const char *name,
+ unsigned long size, unsigned long alignment, int flags)
+{
+ i830_memory *mem;
+
+ mem = i830_allocate_aperture(pScrn, name, size, alignment, flags);
+ if (mem == NULL)
+ return NULL;
+
+ if (!i830_allocate_agp_memory(pScrn, mem, flags)) {
+ i830_free_memory(pScrn, mem);
+ return NULL;
+ }
+
+ return mem;
+}
+
+/* Allocate a tiled region with the given size and pitch.
+ *
+ * As is, we might miss out on tiling some allocations on older hardware with
+ * large framebuffer size and a small aperture size, where the first
+ * allocations use a large alignment even though we've got fences to spare, and
+ * the later allocations can't find enough aperture space left. We could do
+ * some search across all allocation options to fix this, probably, but that
+ * would be another rewrite.
+ */
+static i830_memory *
+i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name,
+ unsigned long size, unsigned long pitch,
+ unsigned long alignment, int flags,
+ enum tile_format tile_format)
{
- I830Ptr pI830 = I830PTR(pScrn);
-
- if (!range || range->Size == 0)
- return;
-
- if (range->Key != -1)
- xf86DeallocateGARTMemory(pScrn->scrnIndex, range->Key);
-
- if (range->Pool) {
- /*
- * This code essentially resets what I830DoPoolAllocation() did.
- * And if things are freed in the wrong order this can break wildly!
- * USE CAUTION when changing anything here...
- */
- I830MemPool *Pool = range->Pool;
- Pool->Total.End = pI830->StolenMemory.End;
-
- if (pI830->StolenOnly)
- Pool->Free.End += range->Size;
- else
- Pool->Free.End = Pool->Total.End;
-
- if (Pool->Free.End < Pool->Free.Start) {
- Pool->Free.End = Pool->Free.Start;
- }
-
- Pool->Free.Size = Pool->Free.End - Pool->Free.Start;
- Pool->Total.Size = Pool->Total.End - Pool->Total.Start;
-
- if (!pI830->StolenOnly) {
- pI830->FreeMemory -= Pool->Free.Size;
- pI830->MemoryAperture.Start -= (range->Size - Pool->Free.Size);
- pI830->MemoryAperture.Size += (range->Size - Pool->Free.Size);
- }
- } else {
- if (range->Alignment == GTT_PAGE_SIZE)
- pI830->MemoryAperture.End = range->End;
- else
- pI830->MemoryAperture.End = range->End - range->Size + range->Alignment;
- pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start;
- }
-
- if (!pI830->StolenOnly)
- pI830->FreeMemory += range->Size;
- pI830->allocatedMemory -= range->Size;
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long aper_size;
+ unsigned long aper_align;
+ i830_memory *mem;
+ int fence_divide, i;
+
+ if (tile_format == TILING_NONE)
+ return i830_allocate_memory(pScrn, name, size, alignment, flags);
+
+ /* Only allocate page-sized increments. */
+ size = ALIGN(size, GTT_PAGE_SIZE);
+
+ /* Check for maximum tiled region size */
+ if (IS_I9XX(pI830)) {
+ if (size > MB(128))
+ return NULL;
+ } else {
+ if (size > MB(64))
+ return NULL;
+ }
+
+ aper_size = i830_get_fence_size(pScrn, size);
+ if (IS_I965G(pI830)) {
+ aper_align = GTT_PAGE_SIZE;
+ } else {
+ /* The offset has to be aligned to at least the size of the fence
+ * region.
+ */
+ aper_align = aper_size;
+ }
+ if (aper_align < alignment)
+ aper_align = alignment;
+
+ fence_divide = 1;
+ mem = i830_allocate_aperture(pScrn, name, aper_size, aper_align, flags);
+ if (mem == NULL && !IS_I965G(pI830)) {
+ /* For the older hardware with stricter fencing limits, if we
+ * couldn't allocate with the large alignment, try relaxing the
+ * alignment requirements and using more fences to cover the area.
+ */
+ for (fence_divide = 2; fence_divide <= 4 && mem == NULL;
+ fence_divide *= 2)
+ {
+ /* Check that it's not too small for fencing. */
+ if (i830_get_fence_size(pScrn, aper_align / fence_divide) !=
+ aper_align / fence_divide)
+ {
+ break;
+ }
+
+ mem = i830_allocate_aperture(pScrn, name, aper_size,
+ aper_align / fence_divide, flags);
+ }
+ }
+
+ if (mem == NULL)
+ return NULL;
+
+ /* Make sure we've got enough free fence regs. It's pretty hard to run
+ * out, luckily, with 8 even on older hardware and us only tiling
+ * front/back/depth buffers.
+ */
+ if (pI830->next_fence + fence_divide >
+ (IS_I965G(pI830) ? FENCE_NEW_NR : FENCE_NR))
+ {
+ i830_free_memory(pScrn, mem);
+ return NULL;
+ }
+
+ /* Allocate any necessary AGP memory to back this allocation */
+ if (!i830_allocate_agp_memory(pScrn, mem, flags)) {
+ i830_free_memory(pScrn, mem);
+ return NULL;
+ }
+
+ /* Set up the fence registers. */
+ for (i = 0; i < fence_divide; i++) {
+ i830_set_fence(pScrn, pI830->next_fence++,
+ mem->offset + mem->size * i / fence_divide, pitch,
+ mem->size / fence_divide, tile_format);
+ }
+
+ mem->size = size;
+
+ return mem;
}
-unsigned long
-I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool,
- long size, unsigned long alignment, int flags)
+static void
+i830_describe_tiling(ScrnInfoPtr pScrn, int verbosity, const char *prefix,
+ i830_memory *mem, unsigned int tiling_mode)
{
- I830Ptr pI830 = I830PTR(pScrn);
- Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
-
- if (!result)
- return 0;
-
- /* Make sure these are initialised. */
- result->Size = 0;
- result->Key = -1;
-
- if (!size) {
- return 0;
- }
-
- switch (flags & FROM_MASK) {
- case FROM_POOL_ONLY:
- return AllocFromPool(pScrn, result, pool, size, alignment, flags);
- case FROM_NEW_ONLY:
- if (!dryrun && (pI830->StolenOnly || (pI830->FreeMemory <= 0)))
- return 0;
- return AllocFromAGP(pScrn, result, size, alignment, flags);
- case FROM_ANYWHERE:
- if ((!(flags & ALLOCATE_AT_BOTTOM) && (pI830->FreeMemory >= size)) ||
- (flags & NEED_PHYSICAL_ADDR))
- return AllocFromAGP(pScrn, result, size, alignment, flags);
- else
- return AllocFromPool(pScrn, result, pool, size, alignment, flags);
- default:
- /* Shouldn't happen. */
- return 0;
- }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%s%s is %stiled\n", prefix, mem->name,
+ (tiling_mode == FENCE_LINEAR) ? "not " : "");
+}
+
+void
+i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ i830_memory *mem;
+
+ if (pI830->memory_list == NULL) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sMemory allocator not initialized\n", prefix);
+ return;
+ }
+
+ if (pI830->memory_list->next->next == NULL) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sNo memory allocations\n", prefix);
+ return;
+ }
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sMemory allocation layout:\n", prefix);
+
+ for (mem = pI830->memory_list->next; mem->next != NULL; mem = mem->next) {
+
+ if (mem->offset >= pI830->stolen_size &&
+ mem->prev->offset < pI830->stolen_size)
+ {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%s0x%08lx: end of stolen memory\n",
+ prefix, pI830->stolen_size);
+ }
+
+ if (mem->bus_addr == 0) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%s0x%08lx-0x%08lx: %s (%ld kB)\n", prefix,
+ mem->offset, mem->end - 1, mem->name,
+ mem->size / 1024);
+ } else {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%s0x%08lx-0x%08lx: %s (%ld kB, 0x%08lx physical)\n",
+ prefix,
+ mem->offset, mem->end - 1, mem->name,
+ mem->size / 1024, mem->bus_addr);
+ }
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%s0x%08lx: end of aperture\n",
+ prefix, pI830->FbMapSize);
+
+ if (pI830->front_buffer != NULL) {
+ i830_describe_tiling(pScrn, verbosity, prefix, pI830->front_buffer,
+ pI830->front_tiled);
+ }
+ if (pI830->back_buffer != NULL) {
+ i830_describe_tiling(pScrn, verbosity, prefix, pI830->back_buffer,
+ pI830->back_tiled);
+ }
+ if (pI830->depth_buffer != NULL) {
+ i830_describe_tiling(pScrn, verbosity, prefix, pI830->depth_buffer,
+ pI830->depth_tiled);
+ }
}
static Bool
-AllocateRingBuffer(ScrnInfoPtr pScrn, int flags)
+i830_allocate_ringbuffer(ScrnInfoPtr pScrn)
{
- I830Ptr pI830 = I830PTR(pScrn);
- unsigned long size, alloced;
- Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
- int verbosity = dryrun ? 4 : 1;
- const char *s = dryrun ? "[dryrun] " : "";
-
- /* Clear ring buffer info */
- memset(pI830->LpRing, 0, sizeof(I830RingBuffer));
- pI830->LpRing->mem.Key = -1;
-
- if (pI830->noAccel)
- return TRUE;
-
- /* Ring buffer */
- size = PRIMARY_RINGBUFFER_SIZE;
- if (flags & FORCE_LOW)
- flags |= FROM_POOL_ONLY | ALLOCATE_AT_BOTTOM;
- else
- flags |= FROM_ANYWHERE | ALLOCATE_AT_TOP;
-
- alloced = I830AllocVidMem(pScrn, &(pI830->LpRing->mem),
- &(pI830->StolenPool), size,
- GTT_PAGE_SIZE, flags);
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate Ring Buffer space\n");
- }
- return FALSE;
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for the ring buffer at 0x%lx\n", s,
- alloced / 1024, pI830->LpRing->mem.Start);
- pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1;
- return TRUE;
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if (pI830->noAccel || pI830->LpRing->mem != NULL)
+ return TRUE;
+
+ pI830->LpRing->mem = i830_allocate_memory(pScrn, "ring buffer",
+ PRIMARY_RINGBUFFER_SIZE,
+ GTT_PAGE_SIZE, 0);
+ if (pI830->LpRing->mem == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate Ring Buffer space\n");
+ return FALSE;
+ }
+
+ pI830->LpRing->tail_mask = pI830->LpRing->mem->size - 1;
+ return TRUE;
}
#ifdef I830_XV
-/*
- * Note, the FORCE_LOW flag is currently not used or supported.
+/**
+ * Allocate space for overlay registers and XAA linear allocator (if
+ * requested)
*/
static Bool
-AllocateOverlay(ScrnInfoPtr pScrn, int flags)
+i830_allocate_overlay(ScrnInfoPtr pScrn)
{
- I830Ptr pI830 = I830PTR(pScrn);
- unsigned long size, alloced;
- Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
- int verbosity = dryrun ? 4 : 1;
- const char *s = dryrun ? "[dryrun] " : "";
-
- /* Clear overlay info */
- memset(pI830->OverlayMem, 0, sizeof(I830MemRange));
- pI830->OverlayMem->Key = -1;
-
- if (!pI830->XvEnabled)
- return TRUE;
-
- /*
- * The overlay register space needs a physical address in
- * system memory. We get this from the agpgart module using
- * a special memory type.
- */
-
- size = OVERLAY_SIZE;
- if (flags & FORCE_LOW)
- flags |= FROM_POOL_ONLY | ALLOCATE_AT_BOTTOM | NEED_PHYSICAL_ADDR;
- else
- flags |= FROM_ANYWHERE | ALLOCATE_AT_TOP | NEED_PHYSICAL_ADDR;
-
- alloced = I830AllocVidMem(pScrn, pI830->OverlayMem,
- &(pI830->StolenPool), size, GTT_PAGE_SIZE, flags);
-
- /*
- * XXX For testing only. Don't enable this unless you know how to set
- * physBase.
- */
- if (flags & FORCE_LOW) {
- ErrorF("AllocateOverlay() doesn't support setting FORCE_LOW\n");
- return FALSE;
- }
-
- if (!dryrun && (alloced < size)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate Overlay register space.\n");
- /* This failure isn't fatal. */
- } else {
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for Overlay registers at 0x%lx "
- "(0x%08lx).\n", s,
- alloced / 1024, pI830->OverlayMem->Start,
- pI830->OverlayMem->Physical);
- }
-
- /* Clear linearmem info */
- if (pI830->LinearAlloc) {
- memset(&(pI830->LinearMem), 0, sizeof(I830MemRange));
- pI830->LinearMem.Key = -1;
-
- size = KB(pI830->LinearAlloc);
- alloced = I830AllocVidMem(pScrn, &(pI830->LinearMem), &(pI830->StolenPool),
- size, GTT_PAGE_SIZE,
- FROM_ANYWHERE | ALLOCATE_AT_TOP);
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ /* Only allocate if overlay is going to be enabled. */
+ if (!pI830->XvEnabled || IS_I965G(pI830))
+ return TRUE;
+
+ if (!IS_I965G(pI830)) {
+ pI830->overlay_regs = i830_allocate_memory(pScrn, "overlay registers",
+ OVERLAY_SIZE, GTT_PAGE_SIZE,
+ NEED_PHYSICAL_ADDR);
+ if (pI830->overlay_regs == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to allocate Overlay register space.\n");
+ /* This failure isn't fatal. */
+ }
+ }
+
+ if (!pI830->useEXA && pI830->LinearAlloc) {
+ pI830->xaa_linear = i830_allocate_memory(pScrn, "XAA linear memory",
+ KB(pI830->LinearAlloc),
+ GTT_PAGE_SIZE, 0);
+ if (pI830->xaa_linear == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Failed to allocate linear buffer space\n");
- }
- } else
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for the linear buffer at 0x%lx\n", s,
- alloced / 1024, pI830->LinearMem.Start);
- }
-
- return TRUE;
+ }
+ }
+
+ return TRUE;
}
#endif
static Bool
IsTileable(ScrnInfoPtr pScrn, int pitch)
{
- I830Ptr pI830 = I830PTR(pScrn);
-
- if (IS_I965G(pI830)) {
- if (pitch / 512 * 512 == pitch && pitch <= KB(128))
- return TRUE;
- else
- return FALSE;
- }
-
- /*
- * Allow tiling for pitches that are a power of 2 multiple of 128 bytes,
- * up to 64 * 128 (= 8192) bytes.
- */
- switch (pitch) {
- case 128:
- case 256:
- if (IS_I945G(pI830) || IS_I945GM(pI830))
- return TRUE;
- else
- return FALSE;
- case 512:
- case KB(1):
- case KB(2):
- case KB(4):
- case KB(8):
- return TRUE;
- default:
- return FALSE;
- }
-}
+ I830Ptr pI830 = I830PTR(pScrn);
-static unsigned long
-GetFreeSpace(ScrnInfoPtr pScrn)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- unsigned long extra = 0;
-
- /* First check for free space in StolenPool. */
- if (pI830->StolenPool.Free.Size > 0)
- extra = pI830->StolenPool.Free.Size;
- /* Next check for unallocated space. */
- if (pI830->FreeMemory > 0)
- extra += pI830->FreeMemory;
+ if (IS_I965G(pI830)) {
+ if (pitch / 512 * 512 == pitch && pitch <= KB(128))
+ return TRUE;
+ else
+ return FALSE;
+ }
- return extra;
+ /*
+ * Allow tiling for pitches that are a power of 2 multiple of 128 bytes,
+ * up to 64 * 128 (= 8192) bytes.
+ */
+ switch (pitch) {
+ case 128:
+ case 256:
+ if (IS_I945G(pI830) || IS_I945GM(pI830))
+ return TRUE;
+ else
+ return FALSE;
+ case 512:
+ case KB(1):
+ case KB(2):
+ case KB(4):
+ case KB(8):
+ return TRUE;
+ default:
+ return FALSE;
+ }
}
/* This is the 2D rendering vertical coordinate limit. We can ignore
@@ -504,204 +728,162 @@ GetFreeSpace(ScrnInfoPtr pScrn)
* \param pI830 I830Ptr for the screen being allocated.
* \param FbMemBox
*/
-static Bool
-I830AllocateFramebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
- I830MemRange *FrontBuffer, I830MemPool *StolenPool,
- Bool secondary, const int flags)
+static i830_memory *
+i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
+ Bool secondary, int flags)
{
- Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
- unsigned long minspace, avail, lineSize;
- int cacheLines, maxCacheLines;
- int verbosity = dryrun ? 4 : 1;
- const char *s = dryrun ? "[dryrun] " : "";
- Bool tileable;
- int align, alignflags;
- long size, alloced, fb_height;
-
- /* Clear everything first. */
- memset(FbMemBox, 0, sizeof(*FbMemBox));
- memset(FrontBuffer, 0, sizeof(*FrontBuffer));
- FrontBuffer->Key = -1;
-
- /* We'll allocate the fb such that the root window will fit regardless of
- * rotation.
- */
- if (pScrn->virtualX > pScrn->virtualY)
- fb_height = pScrn->virtualX;
- else
- fb_height = pScrn->virtualY;
-
- FbMemBox->x1 = 0;
- FbMemBox->x2 = pScrn->displayWidth;
- FbMemBox->y1 = 0;
- FbMemBox->y2 = fb_height;
-
- /* Calculate how much framebuffer memory to allocate. For the
- * initial allocation, calculate a reasonable minimum. This is
- * enough for the virtual screen size, plus some pixmap cache
- * space if we're using XAA.
- */
-
- lineSize = pScrn->displayWidth * pI830->cpp;
- minspace = lineSize * pScrn->virtualY;
- avail = pScrn->videoRam * 1024;
-
- if (!pI830->useEXA) {
- maxCacheLines = (avail - minspace) / lineSize;
- /* This shouldn't happen. */
- if (maxCacheLines < 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Internal Error: "
- "maxCacheLines < 0 in I830Allocate2DMemory()\n");
- maxCacheLines = 0;
- }
- if (maxCacheLines > (MAX_2D_HEIGHT - pScrn->virtualY))
- maxCacheLines = MAX_2D_HEIGHT - pScrn->virtualY;
-
- if (pI830->CacheLines >= 0) {
- cacheLines = pI830->CacheLines;
- } else {
- int size;
-
- size = 3 * lineSize * pScrn->virtualY;
- size += 1920 * 1088 * 2 * 2;
- size = ROUND_TO_PAGE(size);
-
- cacheLines = (size + lineSize - 1) / lineSize;
- }
- if (cacheLines > maxCacheLines)
- cacheLines = maxCacheLines;
-
- FbMemBox->y2 += cacheLines;
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocating at least %d scanlines for pixmap cache\n",
- s, cacheLines);
- } else {
- /* For EXA, we have a separate allocation for the linear allocator which
- * also does the pixmap cache.
- */
- cacheLines = 0;
- }
-
- tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
- IsTileable(pScrn, pScrn->displayWidth * pI830->cpp);
- if (tileable) {
- if (IS_I9XX(pI830))
- align = MB(1);
- else
- align = KB(512);
- alignflags = ALIGN_BOTH_ENDS;
- } else {
- align = KB(64);
- alignflags = 0;
- }
-
- size = lineSize * (fb_height + cacheLines);
- size = ROUND_TO_PAGE(size);
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sInitial %sframebuffer allocation size: %ld kByte\n",
- s, secondary ? "secondary " : "",
- size / 1024);
- alloced = I830AllocVidMem(pScrn, FrontBuffer,
- StolenPool, size, align,
- flags | alignflags |
- FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
- "%sframebuffer. Is your VideoRAM set too low?\n",
- secondary ? "secondary " : "");
- }
- return FALSE;
- }
-
- return TRUE;
+ unsigned int pitch = pScrn->displayWidth * pI830->cpp;
+ unsigned long minspace, avail;
+ int cacheLines, maxCacheLines;
+ int align;
+ long size, fb_height;
+ char *name;
+ i830_memory *front_buffer = NULL;
+
+ /* Clear everything first. */
+ memset(FbMemBox, 0, sizeof(*FbMemBox));
+
+ /* We'll allocate the fb such that the root window will fit regardless of
+ * rotation.
+ */
+ if (pScrn->virtualX > pScrn->virtualY)
+ fb_height = pScrn->virtualX;
+ else
+ fb_height = pScrn->virtualY;
+
+ FbMemBox->x1 = 0;
+ FbMemBox->x2 = pScrn->displayWidth;
+ FbMemBox->y1 = 0;
+ FbMemBox->y2 = fb_height;
+
+ /* Calculate how much framebuffer memory to allocate. For the
+ * initial allocation, calculate a reasonable minimum. This is
+ * enough for the virtual screen size, plus some pixmap cache
+ * space if we're using XAA.
+ */
+ minspace = pitch * pScrn->virtualY;
+ avail = pScrn->videoRam * 1024;
+
+ if (!pI830->useEXA) {
+ maxCacheLines = (avail - minspace) / pitch;
+ /* This shouldn't happen. */
+ if (maxCacheLines < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Internal Error: "
+ "maxCacheLines < 0 in i830_allocate_2d_memory()\n");
+ maxCacheLines = 0;
+ }
+ if (maxCacheLines > (MAX_2D_HEIGHT - pScrn->virtualY))
+ maxCacheLines = MAX_2D_HEIGHT - pScrn->virtualY;
+
+ if (pI830->CacheLines >= 0) {
+ cacheLines = pI830->CacheLines;
+ } else {
+ int size;
+
+ size = 3 * pitch * pScrn->virtualY;
+ size += 1920 * 1088 * 2 * 2;
+ size = ROUND_TO_PAGE(size);
+
+ cacheLines = (size + pitch - 1) / pitch;
+ }
+ if (cacheLines > maxCacheLines)
+ cacheLines = maxCacheLines;
+
+ FbMemBox->y2 += cacheLines;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Allocating %d scanlines for pixmap cache\n",
+ cacheLines);
+ } else {
+ /* For EXA, we have a separate allocation for the linear allocator
+ * which also does the pixmap cache.
+ */
+ cacheLines = 0;
+ }
+
+ size = pitch * (fb_height + cacheLines);
+ size = ROUND_TO_PAGE(size);
+
+ name = secondary ? "secondary front buffer" : "front buffer";
+
+ /* Attempt to allocate it tiled first if we have page flipping on. */
+ if (!pI830->disableTiling && pI830->allowPageFlip &&
+ IsTileable(pScrn, pitch))
+ {
+ /* XXX: probably not the case on 965 */
+ if (IS_I9XX(pI830))
+ align = MB(1);
+ else
+ align = KB(512);
+ front_buffer = i830_allocate_memory_tiled(pScrn, name, size,
+ pitch, align,
+ 0, TILING_XMAJOR);
+ pI830->front_tiled = FENCE_XMAJOR;
+ }
+
+ /* If not, attempt it linear */
+ if (front_buffer == NULL) {
+ front_buffer = i830_allocate_memory(pScrn, name, size, KB(64), flags);
+ pI830->front_tiled = FENCE_LINEAR;
+ }
+
+ if (front_buffer == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
+ "%sframebuffer. Is your VideoRAM set too low?\n",
+ secondary ? "secondary " : "");
+ return NULL;
+ }
+
+ return front_buffer;
}
static Bool
-I830AllocateCursorBuffers(xf86CrtcPtr crtc, const int flags)
+i830_allocate_cursor_buffers(xf86CrtcPtr crtc)
{
- ScrnInfoPtr pScrn = crtc->scrn;
- I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
- I830Ptr pI830 = I830PTR(pScrn);
- Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
- int verbosity = dryrun ? 4 : 1;
- const char *s = dryrun ? "[dryrun] " : "";
- long size, alloced;
- int cursFlags = 0;
-
- /* Clear cursor info */
- memset(&intel_crtc->cursor_mem, 0, sizeof(I830MemRange));
- intel_crtc->cursor_mem.Key = -1;
- memset(&intel_crtc->cursor_mem_argb, 0, sizeof(I830MemRange));
- intel_crtc->cursor_mem_argb.Key = -1;
-
- if (pI830->SWCursor)
- return FALSE;
-
- /*
- * Mouse cursor -- The i810-i830 need a physical address in system
- * memory from which to upload the cursor. We get this from
- * the agpgart module using a special memory type.
- */
-
- size = HWCURSOR_SIZE;
- cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP;
- if (pI830->CursorNeedsPhysical)
- cursFlags |= NEED_PHYSICAL_ADDR;
-
- alloced = I830AllocVidMem(pScrn, &intel_crtc->cursor_mem,
- &pI830->StolenPool, size,
- GTT_PAGE_SIZE, flags | cursFlags);
- if (alloced < size ||
- (pI830->CursorNeedsPhysical && !intel_crtc->cursor_mem.Physical))
- {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate HW cursor space.\n");
- return FALSE;
- }
- } else {
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for HW cursor at 0x%lx", s,
- alloced / 1024, intel_crtc->cursor_mem.Start);
- if (pI830->CursorNeedsPhysical) {
- xf86ErrorFVerb(verbosity, " (0x%08lx)",
- intel_crtc->cursor_mem.Physical);
- }
- xf86ErrorFVerb(verbosity, "\n");
- }
-
- /* Allocate the ARGB cursor space. Its success is optional -- we won't set
- * SWCursor if it fails.
- */
- size = HWCURSOR_SIZE_ARGB;
- cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP;
- if (pI830->CursorNeedsPhysical)
- cursFlags |= NEED_PHYSICAL_ADDR;
-
- alloced = I830AllocVidMem(pScrn, &intel_crtc->cursor_mem_argb,
- &pI830->StolenPool, size,
- GTT_PAGE_SIZE, flags | cursFlags);
- if (alloced < size ||
- (pI830->CursorNeedsPhysical && !intel_crtc->cursor_mem_argb.Physical)) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate HW (ARGB) cursor space.\n");
- }
- } else {
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for HW (ARGB) cursor at 0x%lx", s,
- alloced / 1024, intel_crtc->cursor_mem_argb.Start);
- if (pI830->CursorNeedsPhysical) {
- xf86ErrorFVerb(verbosity, " (0x%08lx)",
- intel_crtc->cursor_mem_argb.Physical);
- }
- xf86ErrorFVerb(verbosity, "\n");
- }
-
- return FALSE;
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ I830Ptr pI830 = I830PTR(pScrn);
+ long size;
+ int flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0;
+
+ if (pI830->SWCursor)
+ return FALSE;
+
+ /* Mouse cursor -- The i810-i830 need a physical address in system
+ * memory from which to upload the cursor. We get this from
+ * the agpgart module using a special memory type.
+ */
+
+ size = HWCURSOR_SIZE;
+
+ if (intel_crtc->cursor_mem == NULL) {
+ intel_crtc->cursor_mem = i830_allocate_memory(pScrn, "HW cursor",
+ size, GTT_PAGE_SIZE,
+ flags);
+ if (intel_crtc->cursor_mem == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate HW cursor space.\n");
+ return FALSE;
+ }
+ }
+
+ if (intel_crtc->cursor_mem_argb == NULL) {
+ /* Allocate the ARGB cursor space. Its success is optional -- we won't
+ * set SWCursor if it fails.
+ */
+ intel_crtc->cursor_mem_argb = i830_allocate_memory(pScrn,
+ "HW ARGB cursor",
+ HWCURSOR_SIZE_ARGB,
+ GTT_PAGE_SIZE,
+ flags);
+ if (intel_crtc->cursor_mem_argb == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate HW (ARGB) cursor space.\n");
+ }
+ }
+
+ return TRUE;
}
/*
@@ -709,1245 +891,600 @@ I830AllocateCursorBuffers(xf86CrtcPtr crtc, const int flags)
* ring buffer, scratch memory, HW cursor.
*/
Bool
-I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
+i830_allocate_2d_memory(ScrnInfoPtr pScrn)
{
- I830Ptr pI830 = I830PTR(pScrn);
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- long size, alloced;
- Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
- int verbosity = dryrun ? 4 : 1;
- const char *s = dryrun ? "[dryrun] " : "";
- Bool tileable;
- int align, alignflags, i;
-
- DPRINTF(PFX, "I830Allocate2DMemory: inital is %s\n",
- BOOLTOSTRING(flags & ALLOC_INITIAL));
-
- if (!pI830->StolenOnly &&
- (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "AGP GART support is either not available or cannot "
- "be used.\n"
- "\tMake sure your kernel has agpgart support or has the\n"
- "\tagpgart module loaded.\n");
- }
- return FALSE;
- }
-
-
- /*
- * The I830 is slightly different from the I830/I815, it has no
- * dcache and it has stolen memory by default in its gtt. All
- * additional memory must go after it.
- */
-
- DPRINTF(PFX,
- "size == %luk (%lu bytes == pScrn->videoRam)\n"
- "pI830->StolenSize == %luk (%lu bytes)\n",
- pScrn->videoRam, pScrn->videoRam * 1024,
- pI830->StolenPool.Free.Size / 1024,
- pI830->StolenPool.Free.Size);
-
- if (flags & ALLOC_INITIAL) {
- if (pI830->NeedRingBufferLow)
- AllocateRingBuffer(pScrn, flags | FORCE_LOW);
-
- /* Unfortunately this doesn't run on the DRY_RUN pass because our
- * second head hasn't been created yet..... */
- if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) {
- I830EntPtr pI830Ent = pI830->entityPrivate;
- I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2);
-
- if (!I830AllocateFramebuffer(pI830Ent->pScrn_2, pI8302,
- &pI830->FbMemBox2,
- &pI830->FrontBuffer2, &pI830->StolenPool,
- TRUE, flags))
- {
- return FALSE;
- }
- }
- if (!I830AllocateFramebuffer(pScrn, pI830, &pI830->FbMemBox,
- &pI830->FrontBuffer, &pI830->StolenPool,
- FALSE, flags))
- {
- return FALSE;
- }
+ I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ unsigned int pitch = pScrn->displayWidth * pI830->cpp;
+ long size;
+ int i;
+
+ if (!pI830->StolenOnly &&
+ (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "AGP GART support is either not available or cannot "
+ "be used.\n"
+ "\tMake sure your kernel has agpgart support or has\n"
+ "\tthe agpgart module loaded.\n");
+ return FALSE;
+ }
-#ifdef I830_USE_EXA
- if (pI830->useEXA) {
- /* Default EXA to having 3 screens worth of offscreen memory space
- * (for pixmaps), plus a double-buffered, 1920x1088 video's worth.
- */
- size = 3 * pScrn->displayWidth * pI830->cpp * pScrn->virtualY;
- size += 1920 * 1088 * 2 * 2;
- size = ROUND_TO_PAGE(size);
-
- alloced = I830AllocVidMem(pScrn, &(pI830->Offscreen),
- &(pI830->StolenPool), size, 1,
- flags |
- FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
- "offscreen memory. Not enough VRAM?\n");
- }
- return FALSE;
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Successful allocation of "
- "EXA offscreen memory at 0x%lx, size %ld KB\n",
- pI830->Offscreen.Start, pI830->Offscreen.Size/1024);
- }
- }
- if (pI830->useEXA && IS_I965G(pI830)) {
- memset(&(pI830->EXAStateMem), 0, sizeof(I830MemRange));
- pI830->EXAStateMem.Key = -1;
- size = ROUND_TO_PAGE(EXA_LINEAR_EXTRA);
- align = GTT_PAGE_SIZE;
- alloced = I830AllocVidMem(pScrn, &(pI830->EXAStateMem),
- &(pI830->StolenPool), size, align,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "G965: Failed to allocate exa state buffer space.\n");
- }
- return FALSE;
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for the G965 exa state buffer at 0x%lx - 0x%lx.\n", s,
- alloced / 1024, pI830->EXAStateMem.Start, pI830->EXAStateMem.End);
- }
-#endif
- } else {
- long lineSize;
- long extra = 0;
- long maxFb = 0;
-
- /*
- * XXX Need to "free" up any 3D allocations if the DRI ended up
- * and make them available for 2D. The best way to do this would
- * be position all of those regions contiguously at the end of the
- * StolenPool.
- */
- extra = GetFreeSpace(pScrn);
-
- if (extra == 0)
- return TRUE;
-
- maxFb = pI830->FrontBuffer.Size + extra;
- lineSize = pScrn->displayWidth * pI830->cpp;
- maxFb = ROUND_DOWN_TO(maxFb, lineSize);
- if (maxFb > lineSize * MAX_2D_HEIGHT)
- maxFb = lineSize * MAX_2D_HEIGHT;
- if (0/*maxFb > pI830->FrontBuffer.Size*/) {
- unsigned long oldsize;
- /*
- * Sanity check -- the fb should be the last thing allocated at
- * the bottom of the stolen pool.
- */
- if (pI830->StolenPool.Free.Start != pI830->FrontBuffer.End) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Internal error in I830Allocate2DMemory():\n\t"
- "Framebuffer isn't the last allocation at the bottom"
- " of StolenPool\n\t(%lx != %lx).\n",
- pI830->FrontBuffer.End,
- pI830->StolenPool.Free.Start);
- return FALSE;
- }
- /*
- * XXX Maybe should have a "Free" function. This should be
- * the only place where a region is resized, and we know that
- * the fb is always at the bottom of the aperture/stolen pool,
- * and is the only region that is allocated bottom-up.
- * Allowing for more general realloction would require a smarter
- * allocation system.
- */
- oldsize = pI830->FrontBuffer.Size;
- pI830->StolenPool.Free.Size += pI830->FrontBuffer.Size;
- pI830->StolenPool.Free.Start -= pI830->FrontBuffer.Size;
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sUpdated framebuffer allocation size from %ld "
- "to %ld kByte\n", s, oldsize / 1024, maxFb / 1024);
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sUpdated pixmap cache from %ld scanlines to %ld "
- "scanlines\n", s,
- oldsize / lineSize - pScrn->virtualY,
- maxFb / lineSize - pScrn->virtualY);
- pI830->FbMemBox.y2 = maxFb / lineSize;
- tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
- IsTileable(pScrn, pScrn->displayWidth * pI830->cpp);
- if (tileable) {
- if (IS_I9XX(pI830))
- align = MB(1);
- else
- align = KB(512);
- alignflags = ALIGN_BOTH_ENDS;
- } else {
- align = KB(64);
- alignflags = 0;
- }
- alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer),
- &(pI830->StolenPool), maxFb, align,
- flags | alignflags |
- FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
- if (alloced < maxFb) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to re-allocate framebuffer\n");
- }
- return FALSE;
- }
- }
- return TRUE;
- }
-
-#if REMAP_RESERVED
- /*
- * Allocate a dummy page to pass when attempting to rebind the
- * pre-allocated region.
- */
- if (!dryrun) {
- memset(&(pI830->Dummy), 0, sizeof(pI830->Dummy));
- pI830->Dummy.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
- pI830->Dummy.Offset = 0;
- }
-#endif
+ /* Allocate the ring buffer first, so it ends up in stolen mem. */
+ i830_allocate_ringbuffer(pScrn);
+
+ /* Next, allocate other fixed-size allocations we have. */
+ if (!pI830->SWCursor) {
+ /* Allocate cursor memory */
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ if (!i830_allocate_cursor_buffers(xf86_config->crtc[i]) &&
+ !pI830->SWCursor)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling HW cursor because the cursor memory "
+ "allocation failed.\n");
+ pI830->SWCursor = TRUE;
+ break;
+ }
+ }
+ }
- if (!pI830->SWCursor && !dryrun) {
- for (i = 0; i < xf86_config->num_crtc; i++) {
- if (!I830AllocateCursorBuffers(xf86_config->crtc[i], flags) &&
- pI830->SWCursor)
- {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Disabling HW cursor because the cursor memory "
- "allocation failed.\n");
- pI830->SWCursor = TRUE;
- break;
- }
- }
- }
+ /* Space for the X Server's 3D context. 32k is fine for right now. */
+ pI830->logical_context = i830_allocate_memory(pScrn, "logical 3D context",
+ KB(32), GTT_PAGE_SIZE, 0);
+ if (pI830->logical_context == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to allocate logical context space.\n");
+ return FALSE;
+ }
#ifdef I830_XV
- AllocateOverlay(pScrn, flags);
+ /* Allocate overlay register space and optional XAA linear allocator
+ * space. The second head in zaphod mode will share the space.
+ */
+ if (I830IsPrimary(pScrn))
+ i830_allocate_overlay(pScrn);
#endif
- if (!pI830->NeedRingBufferLow)
- AllocateRingBuffer(pScrn, flags);
-
- /* Clear scratch info */
- memset(&(pI830->Scratch), 0, sizeof(I830MemRange));
- pI830->Scratch.Key = -1;
- memset(&(pI830->Scratch2), 0, sizeof(I830MemRange));
- pI830->Scratch2.Key = -1;
-
- if (!pI830->noAccel) {
- size = MAX_SCRATCH_BUFFER_SIZE;
- alloced = I830AllocVidMem(pScrn, &(pI830->Scratch), &(pI830->StolenPool),
- size, GTT_PAGE_SIZE,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
- if (alloced < size) {
- size = MIN_SCRATCH_BUFFER_SIZE;
- alloced = I830AllocVidMem(pScrn, &(pI830->Scratch),
- &(pI830->StolenPool), size,
- GTT_PAGE_SIZE,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
- }
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate scratch buffer space\n");
- }
- return FALSE;
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for the scratch buffer at 0x%lx\n", s,
- alloced / 1024, pI830->Scratch.Start);
-
- /* Let's allocate another scratch buffer for the second head */
- /* Again, this code won't execute on the dry run pass */
- if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) {
- size = MAX_SCRATCH_BUFFER_SIZE;
- alloced = I830AllocVidMem(pScrn, &(pI830->Scratch2),
- &(pI830->StolenPool),
- size, GTT_PAGE_SIZE,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
- if (alloced < size) {
- size = MIN_SCRATCH_BUFFER_SIZE;
- alloced = I830AllocVidMem(pScrn, &(pI830->Scratch2),
- &(pI830->StolenPool), size,
- GTT_PAGE_SIZE,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
- }
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate second scratch buffer space\n");
- }
- return FALSE;
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for the second scratch buffer at 0x%lx\n", s,
- alloced / 1024, pI830->Scratch2.Start);
- }
- }
-
- return TRUE;
-}
+ if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) {
+ I830EntPtr pI830Ent = pI830->entityPrivate;
+ I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2);
-void
-I830ResetAllocations(ScrnInfoPtr pScrn, const int flags)
-{
- I830Ptr pI830 = I830PTR(pScrn);
+ pI830->front_buffer_2 =
+ i830_allocate_framebuffer(pI830Ent->pScrn_2, pI8302,
+ &pI830->FbMemBox2, TRUE, 0);
+ if (pI830->front_buffer_2 == NULL)
+ return FALSE;
+ }
+ pI830->front_buffer =
+ i830_allocate_framebuffer(pScrn, pI830, &pI830->FbMemBox, FALSE, 0);
+ if (pI830->front_buffer == NULL)
+ return FALSE;
- pI830->MemoryAperture.Start = pI830->StolenMemory.End;
- pI830->MemoryAperture.End = pI830->FbMapSize;
- pI830->MemoryAperture.Size = pI830->FbMapSize - pI830->StolenMemory.Size;
-#ifdef XF86DRI
- if (!pI830->directRenderingDisabled) {
- pI830->MemoryAperture.End -= KB(pI830->mmSize);
- pI830->MemoryAperture.Size -= KB(pI830->mmSize);
- }
-#endif
- pI830->StolenPool.Fixed = pI830->StolenMemory;
- pI830->StolenPool.Total = pI830->StolenMemory;
- pI830->StolenPool.Free = pI830->StolenPool.Total;
- pI830->FreeMemory = pI830->TotalVideoRam - pI830->StolenPool.Total.Size;
- pI830->allocatedMemory = 0;
-}
+#ifdef I830_USE_EXA
+ if (pI830->useEXA) {
+ if (pI830->exa_offscreen == NULL) {
+ /* Default EXA to having 3 screens worth of offscreen memory space
+ * (for pixmaps), plus a double-buffered, 1920x1088 video's worth.
+ *
+ * XXX: It would be nice to auto-size it larger if the user
+ * specified a larger size, or to fit along with texture and FB
+ * memory if a low videoRam is specified.
+ */
+ size = 3 * pitch * pScrn->virtualY;
+ size += 1920 * 1088 * 2 * 2;
+ size = ROUND_TO_PAGE(size);
+
+ pI830->exa_offscreen = i830_allocate_memory(pScrn, "exa offscreen",
+ size, 1, 0);
+ if (pI830->exa_offscreen == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to allocate EXA offscreen memory.");
+ return FALSE;
+ }
+ }
+
+ if (IS_I965G(pI830) && pI830->exa_965_state == NULL) {
+ pI830->exa_965_state =
+ i830_allocate_memory(pScrn, "exa G965 state buffer",
+ EXA_LINEAR_EXTRA, GTT_PAGE_SIZE, 0);
+ if (pI830->exa_965_state == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to allocate exa state buffer for 965.\n");
+ return FALSE;
+ }
+ }
+ }
+#endif /* I830_USE_EXA */
+
+ if (!pI830->noAccel && !pI830->useEXA) {
+ pI830->xaa_scratch =
+ i830_allocate_memory(pScrn, "xaa scratch", MAX_SCRATCH_BUFFER_SIZE,
+ GTT_PAGE_SIZE, 0);
+ if (pI830->xaa_scratch == NULL) {
+ pI830->xaa_scratch =
+ i830_allocate_memory(pScrn, "xaa scratch",
+ MIN_SCRATCH_BUFFER_SIZE, GTT_PAGE_SIZE,
+ 0);
+ if (pI830->xaa_scratch == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to allocate scratch buffer space\n");
+ return FALSE;
+ }
+ }
+
+ /* Let's allocate another scratch buffer for the second head */
+ /* Again, this code won't execute on the dry run pass */
+ if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
+ {
+ pI830->xaa_scratch_2 =
+ i830_allocate_memory(pScrn, "xaa scratch 2",
+ MAX_SCRATCH_BUFFER_SIZE, GTT_PAGE_SIZE,
+ 0);
+ if (pI830->xaa_scratch_2 == NULL) {
+ pI830->xaa_scratch_2 =
+ i830_allocate_memory(pScrn, "xaa scratch 2",
+ MIN_SCRATCH_BUFFER_SIZE,
+ GTT_PAGE_SIZE, 0);
+ if (pI830->xaa_scratch_2 == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to allocate secondary scratch "
+ "buffer space\n");
+ return FALSE;
+ }
+ }
+ }
+ }
-long
-I830GetExcessMemoryAllocations(ScrnInfoPtr pScrn)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- long allocated;
-
- allocated = pI830->StolenPool.Total.Size + pI830->allocatedMemory;
- if (allocated > pI830->TotalVideoRam)
- return allocated - pI830->TotalVideoRam;
- else
- return 0;
+ return TRUE;
}
#ifdef XF86DRI
static unsigned int
myLog2(unsigned int n)
{
- unsigned int log2 = 1;
+ unsigned int log2 = 1;
- while (n > 1) {
- n >>= 1;
- log2++;
- }
- return log2;
+ while (n > 1) {
+ n >>= 1;
+ log2++;
+ }
+ return log2;
}
-Bool
-I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags)
+static Bool
+i830_allocate_backbuffer(ScrnInfoPtr pScrn)
{
- I830Ptr pI830 = I830PTR(pScrn);
- unsigned long size, alloced, align = 0;
- Bool tileable;
- Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
- int verbosity = dryrun ? 4 : 1;
- const char *s = dryrun ? "[dryrun] " : "";
- int lines;
- int height = (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) ? pScrn->virtualY : pScrn->virtualX;
-
- /* Back Buffer */
- memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer));
- pI830->BackBuffer.Key = -1;
- tileable = !(flags & ALLOC_NO_TILING) &&
- IsTileable(pScrn, pScrn->displayWidth * pI830->cpp);
- if (tileable) {
- /* Make the height a multiple of the tile height (16) */
- lines = (height + 15) / 16 * 16;
- } else {
- lines = height;
- }
-
- size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp);
- /*
- * Try to allocate on the best tile-friendly boundaries.
- */
- alloced = 0;
- if (tileable) {
- align = GetBestTileAlignment(size);
- for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
- alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer),
- &(pI830->StolenPool), size, align,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
- ALIGN_BOTH_ENDS);
- if (alloced >= size)
- break;
- }
- }
- if (alloced < size) {
- /* Give up on trying to tile */
- tileable = FALSE;
- size = ROUND_TO_PAGE(pScrn->displayWidth * height * pI830->cpp);
- align = GTT_PAGE_SIZE;
- alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer),
- &(pI830->StolenPool), size, align,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
- }
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate back buffer space.\n");
- }
- return FALSE;
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for the back buffer at 0x%lx.\n", s,
- alloced / 1024, pI830->BackBuffer.Start);
-
- return TRUE;
-}
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned int pitch = pScrn->displayWidth * pI830->cpp;
+ unsigned long size;
+ int height;
+
+ if (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180))
+ height = pScrn->virtualY;
+ else
+ height = pScrn->virtualX;
+
+ /* Try to allocate on the best tile-friendly boundaries. */
+ if (!pI830->disableTiling && IsTileable(pScrn, pitch))
+ {
+ size = ROUND_TO_PAGE(pitch * ALIGN(height, 16));
+ pI830->back_buffer =
+ i830_allocate_memory_tiled(pScrn, "back buffer",
+ size, pitch, GTT_PAGE_SIZE,
+ ALIGN_BOTH_ENDS,
+ TILING_XMAJOR);
+ pI830->back_tiled = FENCE_XMAJOR;
+ }
-Bool
-I830AllocateDepthBuffer(ScrnInfoPtr pScrn, const int flags)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- unsigned long size, alloced, align = 0;
- Bool tileable;
- Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
- int verbosity = dryrun ? 4 : 1;
- const char *s = dryrun ? "[dryrun] " : "";
- int lines;
- int height = (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) ? pScrn->virtualY : pScrn->virtualX;
-
- /* Depth Buffer -- same size as the back buffer */
- memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer));
- pI830->DepthBuffer.Key = -1;
- tileable = !(flags & ALLOC_NO_TILING) &&
- IsTileable(pScrn, pScrn->displayWidth * pI830->cpp);
- if (tileable) {
- /* Make the height a multiple of the tile height (16) */
- lines = (height + 15) / 16 * 16;
- } else {
- lines = height;
- }
-
- size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp);
- /*
- * Try to allocate on the best tile-friendly boundaries.
- */
- alloced = 0;
- if (tileable) {
- align = GetBestTileAlignment(size);
- for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) {
- alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer),
- &(pI830->StolenPool), size, align,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
- ALIGN_BOTH_ENDS);
- if (alloced >= size)
- break;
- }
- }
- if (alloced < size) {
- /* Give up on trying to tile */
- tileable = FALSE;
- size = ROUND_TO_PAGE(pScrn->displayWidth * height * pI830->cpp);
- align = GTT_PAGE_SIZE;
- alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer),
- &(pI830->StolenPool), size, align,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
- }
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate depth buffer space.\n");
- }
- return FALSE;
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for the depth buffer at 0x%lx.\n", s,
- alloced / 1024, pI830->DepthBuffer.Start);
-
- return TRUE;
-}
+ /* Otherwise, just allocate it linear */
+ if (pI830->back_buffer == NULL) {
+ size = ROUND_TO_PAGE(pitch * height);
+ pI830->back_buffer = i830_allocate_memory(pScrn, "back buffer",
+ size, GTT_PAGE_SIZE,
+ ALIGN_BOTH_ENDS);
+ pI830->back_tiled = FENCE_LINEAR;
+ }
-Bool
-I830AllocateTextureMemory(ScrnInfoPtr pScrn, const int flags)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- unsigned long size, alloced;
- int i;
- Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
- int verbosity = dryrun ? 4 : 1;
- const char *s = dryrun ? "[dryrun] " : "";
-
- /* Allocate the remaining space for textures. */
- memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem));
- pI830->TexMem.Key = -1;
-
- if (pI830->mmModeFlags & I830_KERNEL_TEX) {
-
- if (dryrun && pI830->pEnt->device->videoRam == 0) {
- /* If we're laying out a default-sized allocation, then don't be
- * too greedy and just ask for 32MB.
- */
- size = MB(32);
- } else {
- size = GetFreeSpace(pScrn);
- }
- if (dryrun && (size < MB(1)))
- size = MB(1);
- i = myLog2(size / I830_NR_TEX_REGIONS);
- if (i < I830_LOG_MIN_TEX_REGION_SIZE)
- i = I830_LOG_MIN_TEX_REGION_SIZE;
- pI830->TexGranularity = i;
- /* Truncate size */
- size >>= i;
- size <<= i;
- if (size < KB(512)) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Less than 512 kBytes for texture space (real %ld kBytes).\n",
- size / 1024);
- }
- return FALSE;
- }
- alloced = I830AllocVidMem(pScrn, &(pI830->TexMem),
- &(pI830->StolenPool), size, GTT_PAGE_SIZE,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate texture space.\n");
- }
- return FALSE;
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for textures at 0x%lx\n", s,
- alloced / 1024, pI830->TexMem.Start);
- }
-
- return TRUE;
-}
+ if (pI830->back_buffer == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to allocate back buffer space.\n");
+ return FALSE;
+ }
-Bool
-I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- unsigned long size, alloced;
- Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
- int verbosity = dryrun ? 4 : 1;
- const char *s = dryrun ? "[dryrun] " : "";
-
- DPRINTF(PFX, "I830Allocate3DMemory\n");
-
- /* Space for logical context. 32k is fine for right now. */
- memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem));
- pI830->ContextMem.Key = -1;
- size = KB(32);
- alloced = I830AllocVidMem(pScrn, &(pI830->ContextMem),
- &(pI830->StolenPool), size, GTT_PAGE_SIZE,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate logical context space.\n");
- }
- return FALSE;
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for the logical context at 0x%lx.\n", s,
- alloced / 1024, pI830->ContextMem.Start);
-
- if (!I830AllocateBackBuffer(pScrn, flags))
- return FALSE;
-
- if (!I830AllocateDepthBuffer(pScrn, flags))
- return FALSE;
-
- if (!I830AllocateTextureMemory(pScrn, flags))
- return FALSE;
-
- return TRUE;
+ return TRUE;
}
-#endif
-/* Allocate pool space that isn't pre-allocated */
-Bool
-I830DoPoolAllocation(ScrnInfoPtr pScrn, I830MemPool *pool)
+static Bool
+i830_allocate_depthbuffer(ScrnInfoPtr pScrn)
{
- I830Ptr pI830 = I830PTR(pScrn);
-
- DPRINTF(PFX, "I830DoPoolAllocation\n");
-
- if (!pool)
- return FALSE;
-
- /*
- * Sanity check: there shouldn't be an allocation required when
- * there is only stolen memory.
- */
- if (pI830->StolenOnly && (pool->Total.Size > pool->Fixed.Size)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "I830DoPoolAllocation(): pool size is greater than the "
- "preallocated size,\n\t"
- "and there is no allocatable memory.\n");
- return FALSE;
- }
-
- if (pool->Total.Size > pool->Fixed.Size) {
- pool->Allocated.Size = pool->Total.Size - pool->Fixed.Size;
- pool->Allocated.Key = xf86AllocateGARTMemory(pScrn->scrnIndex,
- pool->Allocated.Size, 0, NULL);
- if (pool->Allocated.Key == -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Pool allocation failed\n");
- return FALSE;
- }
- pool->Allocated.Start = pool->Fixed.End;
- pool->Allocated.End = pool->Total.Size;
- pool->Allocated.Offset = pool->Allocated.Start;
- } else
- pool->Allocated.Key = -1;
- return TRUE;
-}
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long size;
+ unsigned int pitch = pScrn->displayWidth * pI830->cpp;
+ int height;
+
+ /* XXX: this rotation stuff is bogus */
+ if (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180))
+ height = pScrn->virtualY;
+ else
+ height = pScrn->virtualX;
+
+ /* First try allocating it tiled */
+ if (!pI830->disableTiling && IsTileable(pScrn, pitch))
+ {
+ size = ROUND_TO_PAGE(pitch * ALIGN(height, 16));
+
+ pI830->depth_buffer =
+ i830_allocate_memory_tiled(pScrn, "depth buffer", size, pitch,
+ GTT_PAGE_SIZE, ALIGN_BOTH_ENDS,
+ TILING_YMAJOR);
+ pI830->depth_tiled = FENCE_YMAJOR;
+ }
-static unsigned long topOfMem = 0;
+ /* Otherwise, allocate it linear. */
+ if (pI830->depth_buffer == NULL) {
+ size = ROUND_TO_PAGE(pitch * height);
+ pI830->depth_buffer =
+ i830_allocate_memory(pScrn, "depth buffer", size, GTT_PAGE_SIZE,
+ 0);
+ pI830->depth_tiled = FENCE_LINEAR;
+ }
-/*
- * These modify the way memory is positioned within the aperture.
- *
- * By default, memory allocated from the bottom or specifically within
- * the pool at the bottom gets allocated from the "stolen pool", which is
- * actually the stolen memory plus any extra allocated to make it a larger
- * contiguous region. Memory allocated from the AGP is allocated top-down
- * from the end of the aperture space. Memory allocated "from top" defaults
- * to AGP if there is enough "free space". The total allocation (stolen +
- * extra) doesn't exceed the orignal pScrn->videoRam amount (this isn't true
- * when memory allocated from AGP gets moved into the pool by one of the
- * following options.
- *
- * XXX Write a better description.
- *
- */
-#define PACK_RANGES 0
-#define POOL_RANGES 0
+ if (pI830->depth_buffer == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to allocate depth buffer space.\n");
+ return FALSE;
+ }
-Bool
-I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem)
+ return TRUE;
+}
+
+static Bool
+i830_allocate_texture_memory(ScrnInfoPtr pScrn)
{
-#if POOL_RANGES
- I830Ptr pI830 = I830PTR(pScrn);
-#endif
+ I830Ptr pI830 = I830PTR(pScrn);
+ unsigned long size;
+ int i;
+
+ if (pI830->mmModeFlags & I830_KERNEL_MM) {
+ pI830->memory_manager =
+ i830_allocate_aperture(pScrn, "DRI memory manager",
+ pI830->mmSize * KB(1), GTT_PAGE_SIZE,
+ ALIGN_BOTH_ENDS);
+ /* XXX: try memory manager size backoff here? */
+ if (pI830->memory_manager == NULL)
+ return FALSE;
+ }
- if (!mem)
- return FALSE;
-
- if (mem->Pool && mem->Key == -1 && mem->Start < 0) {
- mem->Start = mem->Pool->Total.End + mem->Start;
- mem->End = mem->Start + mem->Size;
- }
-#if PACK_RANGES
- /*
- * Map AGP-allocated areas at the top of the stolen area, resulting in
- * a contiguous region in the aperture. Normally most AGP-allocated areas
- * will be at the top of the aperture, making alignment requirements
- * easier to achieve. This optin is primarily for debugging purposes,
- * and using this option can break any special alignment requirements.
- */
- if (!mem->Pool && mem->Start != 0 && mem->Key != -1 && mem->Physical == 0 &&
- mem->Offset != 0) {
- long diff;
- if (mem->Offset != mem->Start)
- ErrorF("mem %p, Offset != Start\n", mem);
- diff = mem->Offset - topOfMem;
- mem->Start -= diff;
- mem->End -= diff;
- mem->Offset -= diff;
- topOfMem += mem->Size;
- }
-#elif POOL_RANGES
- /*
- * Move AGP-allocated regions (that don't need a physical address) into
- * the pre-allocated pool when there's enough space to do so. Note: the
- * AGP-allocated areas aren't freed. This option is primarily for
- * debugging purposes, and using it can break any special alignment
- * requirements.
- */
- if (!mem->Pool && mem->Start >= pI830->StolenPool.Free.End &&
- mem->Key != -1 && mem->Physical == 0 && mem->Offset != 0 &&
- pI830->StolenPool.Free.Size >= mem->Size) {
- long diff;
- if (mem->Offset != mem->Start)
- ErrorF("mem %p, Offset != Start\n", mem);
- diff = mem->Offset - pI830->StolenPool.Free.Start;
- mem->Start -= diff;
- mem->End -= diff;
- mem->Offset -= diff;
- mem->Key = -1;
- pI830->StolenPool.Free.Start += mem->Size;
- pI830->StolenPool.Free.Size -= mem->Size;
- }
-#endif
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "%p: Memory at offset 0x%08lx, size %ld kBytes\n", (void *)mem,
- mem->Start, mem->Size / 1024);
- return TRUE;
+ if (pI830->mmModeFlags & I830_KERNEL_TEX) {
+ /* XXX: auto-sizing */
+ size = MB(32);
+ i = myLog2(size / I830_NR_TEX_REGIONS);
+ if (i < I830_LOG_MIN_TEX_REGION_SIZE)
+ i = I830_LOG_MIN_TEX_REGION_SIZE;
+ pI830->TexGranularity = i;
+ /* Truncate size */
+ size >>= i;
+ size <<= i;
+ if (size < KB(512)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Less than 512 kBytes for texture space (real %ld"
+ "kBytes).\n",
+ size / 1024);
+ return FALSE;
+ }
+ pI830->textures = i830_allocate_memory(pScrn, "textures", size,
+ GTT_PAGE_SIZE, 0);
+ if (pI830->textures == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to allocate texture space.\n");
+ return FALSE;
+ }
+ }
+
+ return TRUE;
}
Bool
-I830FixupOffsets(ScrnInfoPtr pScrn)
+i830_allocate_3d_memory(ScrnInfoPtr pScrn)
{
- I830Ptr pI830 = I830PTR(pScrn);
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int i;
+ DPRINTF(PFX, "i830_allocate_3d_memory\n");
- DPRINTF(PFX, "I830FixupOffsets\n");
+ if (!i830_allocate_backbuffer(pScrn))
+ return FALSE;
- topOfMem = pI830->StolenPool.Total.End;
- if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
- I830FixOffset(pScrn, &(pI830->FrontBuffer2));
- I830FixOffset(pScrn, &(pI830->FrontBuffer));
+ if (!i830_allocate_depthbuffer(pScrn))
+ return FALSE;
- for (i = 0; i < xf86_config->num_crtc; i++) {
- I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private;
+ if (!i830_allocate_texture_memory(pScrn))
+ return FALSE;
- I830FixOffset(pScrn, &intel_crtc->cursor_mem);
- I830FixOffset(pScrn, &intel_crtc->cursor_mem_argb);
- }
-
- I830FixOffset(pScrn, &(pI830->LpRing->mem));
- I830FixOffset(pScrn, &(pI830->Scratch));
- if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
- I830FixOffset(pScrn, &(pI830->Scratch2));
-#ifdef I830_XV
- if (pI830->XvEnabled) {
- I830FixOffset(pScrn, pI830->OverlayMem);
- if (pI830->LinearAlloc)
- I830FixOffset(pScrn, &(pI830->LinearMem));
- }
-#endif
-#ifdef XF86DRI
- if (pI830->directRenderingEnabled) {
- I830FixOffset(pScrn, &(pI830->ContextMem));
- I830FixOffset(pScrn, &(pI830->BackBuffer));
- I830FixOffset(pScrn, &(pI830->DepthBuffer));
- if (pI830->mmModeFlags & I830_KERNEL_TEX) {
- I830FixOffset(pScrn, &(pI830->TexMem));
- }
- }
-#endif
-#ifdef I830_USE_EXA
- if (pI830->useEXA) {
- I830FixOffset(pScrn, &(pI830->Offscreen));
- if (IS_I965G(pI830))
- I830FixOffset(pScrn, &(pI830->EXAStateMem));
- }
-#endif
- return TRUE;
+ return TRUE;
}
+#endif
#ifdef XF86DRI
-/* Tiled memory is good... really, really good...
+/**
+ * Sets up a fence area for the hardware.
*
- * Need to make it less likely that we miss out on this - probably
- * need to move the frontbuffer away from the 'guarenteed' alignment
- * of the first memory segment, or perhaps allocate a discontigous
- * framebuffer to get more alignment 'sweet spots'.
+ * The fences control automatic tiled address swizzling for CPU access of the
+ * framebuffer.
*/
static void
-SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch,
- unsigned int size)
+i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset,
+ unsigned int pitch, unsigned int size,
+ enum tile_format tile_format)
{
- I830Ptr pI830 = I830PTR(pScrn);
- I830RegPtr i830Reg = &pI830->ModeReg;
- CARD32 val;
- CARD32 fence_mask = 0;
- unsigned int fence_pitch;
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 val;
+ CARD32 fence_mask = 0;
+ unsigned int fence_pitch;
+
+ DPRINTF(PFX, "i830_set_fence(): %d, 0x%08x, %d, %d kByte\n",
+ nr, offset, pitch, size / 1024);
+
+ assert(tile_format != TILING_NONE);
+
+ if (IS_I965G(pI830)) {
+ if (nr < 0 || nr >= FENCE_NEW_NR) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "i830_set_fence(): fence %d out of range\n",nr);
+ return;
+ }
+
+ switch (tile_format) {
+ case TILING_XMAJOR:
+ pI830->fence[nr] = (((pitch / 128) - 1) << 2) | offset | 1;
+ pI830->fence[nr] |= I965_FENCE_X_MAJOR;
+ break;
+ case TILING_YMAJOR:
+ /* YMajor can be 128B aligned but the current code dictates
+ * otherwise. This isn't a problem apart from memory waste.
+ * FIXME */
+ pI830->fence[nr] = (((pitch / 128) - 1) << 2) | offset | 1;
+ pI830->fence[nr] |= I965_FENCE_Y_MAJOR;
+ break;
+ case TILING_NONE:
+ break;
+ }
- DPRINTF(PFX, "SetFence: %d, 0x%08x, %d, %d kByte\n",
- nr, start, pitch, size / 1024);
+ /* The end marker is the address of the last page in the allocation. */
+ pI830->fence[FENCE_NEW_NR + nr] = offset + size - 4096;
+ return;
+ }
- if (nr < 0 || nr > 7) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "SetFence: fence %d out of range\n",nr);
- return;
- }
+ if (nr < 0 || nr >= FENCE_NR) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "i830_set_fence(): fence %d out of range\n",nr);
+ return;
+ }
- i830Reg->Fence[nr] = 0;
+ pI830->fence[nr] = 0;
- if (IS_I9XX(pI830))
+ if (IS_I9XX(pI830))
fence_mask = ~I915G_FENCE_START_MASK;
- else
+ else
fence_mask = ~I830_FENCE_START_MASK;
- if (start & fence_mask) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "SetFence: %d: start (0x%08x) is not %s aligned\n",
- nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k");
- return;
- }
-
- if (start % size) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n",
- nr, start, size / 1024);
- return;
- }
-
- if (pitch & 127) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n",
- nr, pitch);
- return;
- }
-
- val = (start | FENCE_X_MAJOR | FENCE_VALID);
-
- if (IS_I9XX(pI830)) {
+ if (offset & fence_mask) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "i830_set_fence(): %d: offset (0x%08x) is not %s aligned\n",
+ nr, offset, (IS_I9XX(pI830)) ? "1MB" : "512k");
+ return;
+ }
+
+ if (offset % size) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "i830_set_fence(): %d: offset (0x%08x) is not size (%dk) "
+ "aligned\n",
+ nr, offset, size / 1024);
+ return;
+ }
+
+ if (pitch & 127) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "i830_set_fence(): %d: pitch (%d) not a multiple of 128 "
+ "bytes\n",
+ nr, pitch);
+ return;
+ }
+
+ val = offset | FENCE_VALID;
+
+ switch (tile_format) {
+ case TILING_XMAJOR:
+ val |= FENCE_X_MAJOR;
+ break;
+ case TILING_YMAJOR:
+ val |= FENCE_Y_MAJOR;
+ break;
+ case TILING_NONE:
+ break;
+ }
+
+ if (IS_I9XX(pI830)) {
switch (size) {
- case MB(1):
- val |= I915G_FENCE_SIZE_1M;
- break;
- case MB(2):
- val |= I915G_FENCE_SIZE_2M;
- break;
- case MB(4):
- val |= I915G_FENCE_SIZE_4M;
- break;
- case MB(8):
- val |= I915G_FENCE_SIZE_8M;
- break;
- case MB(16):
- val |= I915G_FENCE_SIZE_16M;
- break;
- case MB(32):
- val |= I915G_FENCE_SIZE_32M;
- break;
- case MB(64):
- val |= I915G_FENCE_SIZE_64M;
- break;
- default:
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024);
- return;
+ case MB(1):
+ val |= I915G_FENCE_SIZE_1M;
+ break;
+ case MB(2):
+ val |= I915G_FENCE_SIZE_2M;
+ break;
+ case MB(4):
+ val |= I915G_FENCE_SIZE_4M;
+ break;
+ case MB(8):
+ val |= I915G_FENCE_SIZE_8M;
+ break;
+ case MB(16):
+ val |= I915G_FENCE_SIZE_16M;
+ break;
+ case MB(32):
+ val |= I915G_FENCE_SIZE_32M;
+ break;
+ case MB(64):
+ val |= I915G_FENCE_SIZE_64M;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "i830_set_fence(): %d: illegal size (%d kByte)\n",
+ nr, size / 1024);
+ return;
}
} else {
switch (size) {
- case KB(512):
- val |= FENCE_SIZE_512K;
- break;
- case MB(1):
- val |= FENCE_SIZE_1M;
- break;
- case MB(2):
- val |= FENCE_SIZE_2M;
- break;
- case MB(4):
- val |= FENCE_SIZE_4M;
- break;
- case MB(8):
- val |= FENCE_SIZE_8M;
- break;
- case MB(16):
- val |= FENCE_SIZE_16M;
- break;
- case MB(32):
- val |= FENCE_SIZE_32M;
- break;
- case MB(64):
- val |= FENCE_SIZE_64M;
- break;
- default:
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024);
- return;
+ case KB(512):
+ val |= FENCE_SIZE_512K;
+ break;
+ case MB(1):
+ val |= FENCE_SIZE_1M;
+ break;
+ case MB(2):
+ val |= FENCE_SIZE_2M;
+ break;
+ case MB(4):
+ val |= FENCE_SIZE_4M;
+ break;
+ case MB(8):
+ val |= FENCE_SIZE_8M;
+ break;
+ case MB(16):
+ val |= FENCE_SIZE_16M;
+ break;
+ case MB(32):
+ val |= FENCE_SIZE_32M;
+ break;
+ case MB(64):
+ val |= FENCE_SIZE_64M;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "i830_set_fence(): %d: illegal size (%d kByte)\n",
+ nr, size / 1024);
+ return;
}
- }
+ }
- if (IS_I9XX(pI830))
+ if (IS_I9XX(pI830))
fence_pitch = pitch / 512;
- else
+ else
fence_pitch = pitch / 128;
- switch (fence_pitch) {
- case 1:
- val |= FENCE_PITCH_1;
- break;
- case 2:
- val |= FENCE_PITCH_2;
- break;
- case 4:
- val |= FENCE_PITCH_4;
- break;
- case 8:
- val |= FENCE_PITCH_8;
- break;
- case 16:
- val |= FENCE_PITCH_16;
- break;
- case 32:
- val |= FENCE_PITCH_32;
- break;
- case 64:
- val |= FENCE_PITCH_64;
- break;
- default:
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "SetFence: %d: illegal pitch (%d)\n", nr, pitch);
- return;
- }
-
- i830Reg->Fence[nr] = val;
-}
-
-static Bool
-MakeTiles(ScrnInfoPtr pScrn, I830MemRange *pMem, unsigned int fence)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- int pitch, ntiles, i;
-
-#if 0
- /* Hack to "improve" the alignment of the front buffer.
- */
- while (!(pMem->Start & ~pMem->Alignment) && pMem->Alignment < 0x00400000 )
- pMem->Alignment <<= 1;
-#endif
-
- if (tileGeneration != serverGeneration) {
- tileGeneration = serverGeneration;
- nextTile = 0;
- }
-
- pitch = pScrn->displayWidth * pI830->cpp;
-
- if (IS_I965G(pI830)) {
- I830RegPtr i830Reg = &pI830->ModeReg;
-
- switch (fence) {
- case FENCE_XMAJOR:
- i830Reg->Fence[nextTile] = (((pitch / 128) - 1) << 2) | pMem->Start | 1;
- break;
- case FENCE_YMAJOR:
- /* YMajor can be 128B aligned but the current code dictates
- * otherwise. This isn't a problem apart from memory waste.
- * FIXME */
- i830Reg->Fence[nextTile] = (((pitch / 128) - 1) << 2) | pMem->Start | 1;
- i830Reg->Fence[nextTile] |= (1<<1);
- break;
- default:
- case FENCE_LINEAR:
- break;
- }
-
- i830Reg->Fence[nextTile+FENCE_NEW_NR] = pMem->End;
- nextTile++;
- return TRUE;
- }
-
- /*
- * Simply try to break the region up into at most four pieces of size
- * equal to the alignment.
- */
- ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment;
- if (ntiles >= 4) {
- return FALSE;
- }
-
- for (i = 0; i < ntiles; i++, nextTile++) {
- SetFence(pScrn, nextTile, pMem->Start + i * pMem->Alignment,
- pitch, pMem->Alignment);
- }
- return TRUE;
-}
-
-void
-I830SetupMemoryTiling(ScrnInfoPtr pScrn)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- int i;
-
- /* Clear out */
- if (IS_I965G(pI830)) {
- for (i = 0; i < FENCE_NEW_NR*2; i++)
- pI830->ModeReg.Fence[i] = 0;
- } else {
- for (i = 0; i < 8; i++)
- pI830->ModeReg.Fence[i] = 0;
- }
-
- nextTile = 0;
- tileGeneration = -1;
-
- /* We currently only attempt to tile the back and depth buffers. */
- if (!pI830->directRenderingEnabled)
- return;
-
- if (!IsTileable(pScrn, pScrn->displayWidth * pI830->cpp)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "I830SetupMemoryTiling: Not tileable 0x%x\n",
- pScrn->displayWidth * pI830->cpp);
- pI830->allowPageFlip = FALSE;
- return;
- }
-
- pI830->front_tiled = FENCE_LINEAR;
- pI830->back_tiled = FENCE_LINEAR;
- pI830->depth_tiled = FENCE_LINEAR;
-
- if (pI830->allowPageFlip) {
- if (pI830->allowPageFlip && pI830->FrontBuffer.Alignment >= KB(512)) {
- if (MakeTiles(pScrn, &(pI830->FrontBuffer), FENCE_XMAJOR)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Activating tiled memory for the front buffer\n");
- pI830->front_tiled = FENCE_XMAJOR;
- } else {
- pI830->allowPageFlip = FALSE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "MakeTiles failed for the front buffer\n");
- }
- } else {
- pI830->allowPageFlip = FALSE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Alignment bad for the front buffer\n");
- }
- }
-
- /*
- * We tried to get the best alignment during the allocation. Check
- * the alignment values to tell. If well-aligned allocations were
- * successful, the address range reserved is a multiple of the align
- * value.
- */
- if (pI830->BackBuffer.Alignment >= KB(512)) {
- if (MakeTiles(pScrn, &(pI830->BackBuffer), FENCE_XMAJOR)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Activating tiled memory for the back buffer.\n");
- pI830->back_tiled = FENCE_XMAJOR;
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "MakeTiles failed for the back buffer.\n");
- pI830->allowPageFlip = FALSE;
- }
- }
-
- if (pI830->DepthBuffer.Alignment >= KB(512)) {
- if (MakeTiles(pScrn, &(pI830->DepthBuffer), FENCE_YMAJOR)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Activating tiled memory for the depth buffer.\n");
- pI830->depth_tiled = FENCE_YMAJOR;
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "MakeTiles failed for the depth buffer.\n");
- }
- }}
-#endif /* XF86DRI */
-
-static Bool
-BindMemRange(ScrnInfoPtr pScrn, I830MemRange *mem)
-{
- if (!mem)
- return FALSE;
-
- if (mem->Key == -1)
- return TRUE;
+ switch (fence_pitch) {
+ case 1:
+ val |= FENCE_PITCH_1;
+ break;
+ case 2:
+ val |= FENCE_PITCH_2;
+ break;
+ case 4:
+ val |= FENCE_PITCH_4;
+ break;
+ case 8:
+ val |= FENCE_PITCH_8;
+ break;
+ case 16:
+ val |= FENCE_PITCH_16;
+ break;
+ case 32:
+ val |= FENCE_PITCH_32;
+ break;
+ case 64:
+ val |= FENCE_PITCH_64;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "i830_set_fence(): %d: illegal pitch (%d)\n", nr, pitch);
+ return;
+ }
- return xf86BindGARTMemory(pScrn->scrnIndex, mem->Key, mem->Offset);
+ pI830->fence[nr] = val;
}
+#endif
+/**
+ * Called at EnterVT to grab the AGP GART and bind our allocations.
+ *
+ * In zaphod mode, this will walk the list trying to bind twice, since each
+ * pI830 points to the same allocation list, but the bind_memory will just
+ * no-op then.
+ */
Bool
-I830BindAGPMemory(ScrnInfoPtr pScrn)
+i830_bind_all_memory(ScrnInfoPtr pScrn)
{
- I830Ptr pI830 = I830PTR(pScrn);
-
- DPRINTF(PFX,
- "I830BindAGPMemory: StolenOnly is %s, pI830->GttBound is %s\n",
- BOOLTOSTRING(pI830->StolenOnly), BOOLTOSTRING(pI830->GttBound));
+ I830Ptr pI830 = I830PTR(pScrn);
- if (pI830->StolenOnly == TRUE)
- return TRUE;
+ if (pI830->StolenOnly == TRUE || pI830->memory_list == NULL)
+ return TRUE;
- if (xf86AgpGARTSupported() && !pI830->GttBound) {
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int i;
+ if (xf86AgpGARTSupported() && !pI830->gtt_acquired) {
+ i830_memory *mem;
- if (!xf86AcquireGART(pScrn->scrnIndex))
- return FALSE;
-
-#if REMAP_RESERVED
- /* Rebind the pre-allocated region. */
- BindMemRange(pScrn, &(pI830->Dummy));
-#endif
-
- if (!BindMemRange(pScrn, &(pI830->StolenPool.Allocated)))
- return FALSE;
- if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
- if (!BindMemRange(pScrn, &(pI830->FrontBuffer2)))
+ if (!xf86AcquireGART(pScrn->scrnIndex))
return FALSE;
- if (!BindMemRange(pScrn, &(pI830->FrontBuffer)))
- return FALSE;
- for (i = 0; i < xf86_config->num_crtc; i++) {
- I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private;
+ pI830->gtt_acquired = TRUE;
- if (!BindMemRange(pScrn, &intel_crtc->cursor_mem))
- return FALSE;
- if (!BindMemRange(pScrn, &intel_crtc->cursor_mem_argb))
- return FALSE;
- }
- if (!BindMemRange(pScrn, &(pI830->LpRing->mem)))
- return FALSE;
- if (!BindMemRange(pScrn, &(pI830->Scratch)))
- return FALSE;
- if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
- if (!BindMemRange(pScrn, &(pI830->Scratch2)))
- return FALSE;
-#ifdef I830_XV
- if (pI830->XvEnabled) {
- if (!BindMemRange(pScrn, pI830->OverlayMem))
- return FALSE;
- if (pI830->LinearAlloc)
- if (!BindMemRange(pScrn, &(pI830->LinearMem)))
- return FALSE;
- }
-#endif
-#ifdef XF86DRI
- if (pI830->directRenderingEnabled) {
- if (!BindMemRange(pScrn, &(pI830->ContextMem)))
- return FALSE;
- if (!BindMemRange(pScrn, &(pI830->BackBuffer)))
- return FALSE;
- if (!BindMemRange(pScrn, &(pI830->DepthBuffer)))
- return FALSE;
- if ((pI830->mmModeFlags & I830_KERNEL_TEX) &&
- !BindMemRange(pScrn, &(pI830->TexMem)))
- return FALSE;
- }
-#endif
-#ifdef I830_USE_EXA
- if (pI830->useEXA) {
- if (!BindMemRange(pScrn, &(pI830->Offscreen)))
- return FALSE;
- if (IS_I965G(pI830) && !BindMemRange(pScrn, &(pI830->EXAStateMem)))
- return FALSE;
- }
-#endif
- pI830->GttBound = 1;
- }
-
- return TRUE;
-}
-
-static Bool
-UnbindMemRange(ScrnInfoPtr pScrn, I830MemRange *mem)
-{
- if (!mem)
- return FALSE;
-
- if (mem->Key == -1)
- return TRUE;
+ for (mem = pI830->memory_list->next; mem->next != NULL;
+ mem = mem->next)
+ {
+ if (!i830_bind_memory(pScrn, mem)) {
+ /* This shouldn't happen */
+ FatalError("Couldn't bind memory for %s\n", mem->name);
+ }
+ }
+ }
- return xf86UnbindGARTMemory(pScrn->scrnIndex, mem->Key);
+ return TRUE;
}
-
+/** Called at LeaveVT, to unbind all of our AGP allocations. */
Bool
-I830UnbindAGPMemory(ScrnInfoPtr pScrn)
+i830_unbind_all_memory(ScrnInfoPtr pScrn)
{
- I830Ptr pI830 = I830PTR(pScrn);
+ I830Ptr pI830 = I830PTR(pScrn);
- DPRINTF(PFX,
- "I830UnbindAGPMemory: StolenOnly is %s, pI830->GttBound is %s\n",
- BOOLTOSTRING(pI830->StolenOnly), BOOLTOSTRING(pI830->GttBound));
+ if (pI830->StolenOnly == TRUE)
+ return TRUE;
- if (pI830->StolenOnly == TRUE)
- return TRUE;
+ if (xf86AgpGARTSupported() && pI830->gtt_acquired) {
+ i830_memory *mem;
- if (xf86AgpGARTSupported() && pI830->GttBound) {
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int i;
+ for (mem = pI830->memory_list->next; mem->next != NULL;
+ mem = mem->next)
+ {
+ i830_unbind_memory(pScrn, mem);
+ }
-#if REMAP_RESERVED
- /* "unbind" the pre-allocated region. */
- UnbindMemRange(pScrn, &(pI830->Dummy));
-#endif
-
- if (!UnbindMemRange(pScrn, &(pI830->StolenPool.Allocated)))
- return FALSE;
- if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
- if (!UnbindMemRange(pScrn, &(pI830->FrontBuffer2)))
- return FALSE;
- if (!UnbindMemRange(pScrn, &(pI830->FrontBuffer)))
- return FALSE;
+ pI830->gtt_acquired = FALSE;
- for (i = 0; i < xf86_config->num_crtc; i++) {
- I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private;
-
- if (!UnbindMemRange(pScrn, &intel_crtc->cursor_mem))
- return FALSE;
- if (!UnbindMemRange(pScrn, &intel_crtc->cursor_mem_argb))
- return FALSE;
- }
-
- if (!UnbindMemRange(pScrn, &(pI830->LpRing->mem)))
- return FALSE;
- if (!UnbindMemRange(pScrn, &(pI830->Scratch)))
- return FALSE;
- if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
- if (!UnbindMemRange(pScrn, &(pI830->Scratch2)))
- return FALSE;
-#ifdef I830_XV
- if (pI830->XvEnabled) {
- if (!UnbindMemRange(pScrn, pI830->OverlayMem))
- return FALSE;
- if (pI830->LinearAlloc)
- if (!UnbindMemRange(pScrn, &(pI830->LinearMem)))
- return FALSE;
- }
-#endif
-#ifdef XF86DRI
- if (pI830->directRenderingEnabled) {
- if (!UnbindMemRange(pScrn, &(pI830->ContextMem)))
- return FALSE;
- if (!UnbindMemRange(pScrn, &(pI830->BackBuffer)))
+ if (!xf86ReleaseGART(pScrn->scrnIndex))
return FALSE;
- if (!UnbindMemRange(pScrn, &(pI830->DepthBuffer)))
- return FALSE;
- if ((pI830->mmModeFlags & I830_KERNEL_TEX) &&
- !UnbindMemRange(pScrn, &(pI830->TexMem)))
- return FALSE;
- }
-#endif
-#ifdef I830_USE_EXA
- if (pI830->useEXA) {
- if (!UnbindMemRange(pScrn, &(pI830->Offscreen)))
- return FALSE;
- if (IS_I965G(pI830) && !UnbindMemRange(pScrn, &(pI830->EXAStateMem)))
- return FALSE;
- }
-#endif
- if (!xf86ReleaseGART(pScrn->scrnIndex))
- return FALSE;
-
- pI830->GttBound = 0;
- }
+ }
- return TRUE;
+ return TRUE;
}
+/**
+ * Returns the amount of system memory that could potentially be allocated
+ * from AGP, in kB.
+ */
long
I830CheckAvailableMemory(ScrnInfoPtr pScrn)
{
- AgpInfoPtr agpinf;
- int maxPages;
+ AgpInfoPtr agpinf;
+ int maxPages;
- if (!xf86AgpGARTSupported() ||
- !xf86AcquireGART(pScrn->scrnIndex) ||
- (agpinf = xf86GetAGPInfo(pScrn->scrnIndex)) == NULL ||
- !xf86ReleaseGART(pScrn->scrnIndex))
- return -1;
+ if (!xf86AgpGARTSupported() ||
+ !xf86AcquireGART(pScrn->scrnIndex) ||
+ (agpinf = xf86GetAGPInfo(pScrn->scrnIndex)) == NULL ||
+ !xf86ReleaseGART(pScrn->scrnIndex))
+ return -1;
- maxPages = agpinf->totalPages - agpinf->usedPages;
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "%s: %d kB available\n",
- "I830CheckAvailableMemory", maxPages * 4);
+ maxPages = agpinf->totalPages - agpinf->usedPages;
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "%s: %d kB available\n",
+ "I830CheckAvailableMemory", maxPages * 4);
- return maxPages * 4;
+ return maxPages * 4;
}
#ifdef I830_USE_XAA
@@ -1962,28 +1499,28 @@ i830_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length,
RemoveLinearCallbackProcPtr removeCB,
pointer privData)
{
- FBLinearPtr linear;
- int max_size;
+ FBLinearPtr linear;
+ int max_size;
- linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB,
- removeCB, privData);
- if (linear != NULL)
- return linear;
+ linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB,
+ removeCB, privData);
+ if (linear != NULL)
+ return linear;
- /* The above allocation didn't succeed, so purge unlocked stuff and try
- * again.
- */
- xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity,
- PRIORITY_EXTREME);
+ /* The above allocation didn't succeed, so purge unlocked stuff and try
+ * again.
+ */
+ xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity,
+ PRIORITY_EXTREME);
- if (max_size < length)
- return NULL;
+ if (max_size < length)
+ return NULL;
- xf86PurgeUnlockedOffscreenAreas(pScreen);
+ xf86PurgeUnlockedOffscreenAreas(pScreen);
- linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB,
- removeCB, privData);
+ linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB,
+ removeCB, privData);
- return linear;
+ return linear;
}
#endif
diff --git a/src/i830_modes.c b/src/i830_modes.c
index 405dcc61..06921a50 100644
--- a/src/i830_modes.c
+++ b/src/i830_modes.c
@@ -52,7 +52,7 @@
#include "X11/Xatom.h"
#include "i830.h"
#include "i830_display.h"
-#include "i830_xf86Modes.h"
+#include "xf86Modes.h"
#include <randrstr.h>
DisplayModePtr
diff --git a/src/i830_randr.c b/src/i830_randr.c
deleted file mode 100644
index 5eccf4bd..00000000
--- a/src/i830_randr.c
+++ /dev/null
@@ -1,950 +0,0 @@
-/* $XdotOrg: xc/programs/Xserver/hw/xfree86/common/xf86RandR.c,v 1.3 2004/07/30 21:53:09 eich Exp $ */
-/*
- * $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86RandR.c,v 1.7tsi Exp $
- *
- * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "xf86.h"
-#include "os.h"
-#include "mibank.h"
-#include "globals.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86DDC.h"
-#include "mipointer.h"
-#include "windowstr.h"
-#include <randrstr.h>
-#include <X11/extensions/render.h>
-
-#include "i830_xf86Crtc.h"
-#include "i830_randr.h"
-#include "i830_debug.h"
-#include "i830_display.h"
-#include "i830.h"
-
-typedef struct _xf86RandR12Info {
- int virtualX;
- int virtualY;
- int mmWidth;
- int mmHeight;
- int maxX;
- int maxY;
- Rotation rotation; /* current mode */
- Rotation supported_rotations; /* driver supported */
-} XF86RandRInfoRec, *XF86RandRInfoPtr;
-
-#ifdef RANDR_12_INTERFACE
-static Bool xf86RandR12Init12 (ScreenPtr pScreen);
-static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen);
-#endif
-
-static int xf86RandR12Index;
-static int xf86RandR12Generation;
-
-#define XF86RANDRINFO(p) \
- ((XF86RandRInfoPtr)(p)->devPrivates[xf86RandR12Index].ptr)
-
-static int
-xf86RandR12ModeRefresh (DisplayModePtr mode)
-{
- if (mode->VRefresh)
- return (int) (mode->VRefresh + 0.5);
- else
- return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
-}
-
-static Bool
-xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations)
-{
- RRScreenSizePtr pSize;
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- DisplayModePtr mode;
- int refresh0 = 60;
- int maxX = 0, maxY = 0;
-
- *rotations = randrp->supported_rotations;
-
- if (randrp->virtualX == -1 || randrp->virtualY == -1)
- {
- randrp->virtualX = scrp->virtualX;
- randrp->virtualY = scrp->virtualY;
- }
-
- /* Re-probe the outputs for new monitors or modes */
- xf86ProbeOutputModes (scrp, 0, 0);
- xf86SetScrnInfoModes (scrp);
- I830DGAReInit (pScreen);
-
- for (mode = scrp->modes; ; mode = mode->next)
- {
- int refresh = xf86RandR12ModeRefresh (mode);
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- if (maxX < mode->HDisplay)
- maxX = mode->HDisplay;
- if (maxY < mode->VDisplay)
- maxY = mode->VDisplay;
- }
- if (mode == scrp->modes)
- refresh0 = refresh;
- pSize = RRRegisterSize (pScreen,
- mode->HDisplay, mode->VDisplay,
- randrp->mmWidth, randrp->mmHeight);
- if (!pSize)
- return FALSE;
- RRRegisterRate (pScreen, pSize, refresh);
-
- if (xf86ModesEqual(mode, scrp->currentMode) &&
- mode->HDisplay == scrp->virtualX &&
- mode->VDisplay == scrp->virtualY)
- {
- RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
- }
- if (mode->next == scrp->modes)
- break;
- }
-
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- randrp->maxX = maxX;
- randrp->maxY = maxY;
- }
-
- if (scrp->currentMode->HDisplay != randrp->virtualX ||
- scrp->currentMode->VDisplay != randrp->virtualY)
- {
- pSize = RRRegisterSize (pScreen,
- randrp->virtualX, randrp->virtualY,
- randrp->mmWidth,
- randrp->mmHeight);
- if (!pSize)
- return FALSE;
- RRRegisterRate (pScreen, pSize, refresh0);
- if (scrp->virtualX == randrp->virtualX &&
- scrp->virtualY == randrp->virtualY)
- {
- RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize);
- }
- }
-
- return TRUE;
-}
-
-static Bool
-xf86RandR12SetMode (ScreenPtr pScreen,
- DisplayModePtr mode,
- Bool useVirtual,
- int mmWidth,
- int mmHeight)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- int oldWidth = pScreen->width;
- int oldHeight = pScreen->height;
- int oldmmWidth = pScreen->mmWidth;
- int oldmmHeight = pScreen->mmHeight;
- WindowPtr pRoot = WindowTable[pScreen->myNum];
- DisplayModePtr currentMode = NULL;
- Bool ret = TRUE;
- PixmapPtr pspix = NULL;
-
- if (pRoot)
- (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
- if (useVirtual)
- {
- scrp->virtualX = randrp->virtualX;
- scrp->virtualY = randrp->virtualY;
- }
- else
- {
- scrp->virtualX = mode->HDisplay;
- scrp->virtualY = mode->VDisplay;
- }
-
- if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
- {
- /* If the screen is rotated 90 or 270 degrees, swap the sizes. */
- pScreen->width = scrp->virtualY;
- pScreen->height = scrp->virtualX;
- pScreen->mmWidth = mmHeight;
- pScreen->mmHeight = mmWidth;
- }
- else
- {
- pScreen->width = scrp->virtualX;
- pScreen->height = scrp->virtualY;
- pScreen->mmWidth = mmWidth;
- pScreen->mmHeight = mmHeight;
- }
- if (scrp->currentMode == mode) {
- /* Save current mode */
- currentMode = scrp->currentMode;
- /* Reset, just so we ensure the drivers SwitchMode is called */
- scrp->currentMode = NULL;
- }
- /*
- * We know that if the driver failed to SwitchMode to the rotated
- * version, then it should revert back to it's prior mode.
- */
- if (!xf86SwitchMode (pScreen, mode))
- {
- ret = FALSE;
- scrp->virtualX = pScreen->width = oldWidth;
- scrp->virtualY = pScreen->height = oldHeight;
- pScreen->mmWidth = oldmmWidth;
- pScreen->mmHeight = oldmmHeight;
- scrp->currentMode = currentMode;
- }
- /*
- * Get the new Screen pixmap ptr as SwitchMode might have called
- * ModifyPixmapHeader and xf86EnableDisableFBAccess will put it back...
- * Unfortunately.
- */
- pspix = (*pScreen->GetScreenPixmap) (pScreen);
- if (pspix->devPrivate.ptr)
- scrp->pixmapPrivate = pspix->devPrivate;
-
- /*
- * Make sure the layout is correct
- */
- xf86ReconfigureLayout();
-
- /*
- * Make sure the whole screen is visible
- */
- xf86SetViewport (pScreen, pScreen->width, pScreen->height);
- xf86SetViewport (pScreen, 0, 0);
- if (pRoot)
- (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
- return ret;
-}
-
-Bool
-xf86RandR12SetConfig (ScreenPtr pScreen,
- Rotation rotation,
- int rate,
- RRScreenSizePtr pSize)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- DisplayModePtr mode;
- int px, py;
- Bool useVirtual = FALSE;
- int maxX = 0, maxY = 0;
- Rotation oldRotation = randrp->rotation;
-
- randrp->rotation = rotation;
-
- if (randrp->virtualX == -1 || randrp->virtualY == -1)
- {
- randrp->virtualX = scrp->virtualX;
- randrp->virtualY = scrp->virtualY;
- }
-
- miPointerPosition (&px, &py);
- for (mode = scrp->modes; ; mode = mode->next)
- {
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- if (maxX < mode->HDisplay)
- maxX = mode->HDisplay;
- if (maxY < mode->VDisplay)
- maxY = mode->VDisplay;
- }
- if (mode->HDisplay == pSize->width &&
- mode->VDisplay == pSize->height &&
- (rate == 0 || xf86RandR12ModeRefresh (mode) == rate))
- break;
- if (mode->next == scrp->modes)
- {
- if (pSize->width == randrp->virtualX &&
- pSize->height == randrp->virtualY)
- {
- mode = scrp->modes;
- useVirtual = TRUE;
- break;
- }
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- randrp->maxX = maxX;
- randrp->maxY = maxY;
- }
- return FALSE;
- }
- }
-
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- randrp->maxX = maxX;
- randrp->maxY = maxY;
- }
-
- if (!xf86RandR12SetMode (pScreen, mode, useVirtual, pSize->mmWidth,
- pSize->mmHeight)) {
- randrp->rotation = oldRotation;
- return FALSE;
- }
-
- /*
- * Move the cursor back where it belongs; SwitchMode repositions it
- */
- if (pScreen == miPointerCurrentScreen ())
- {
- px = (px >= pScreen->width ? (pScreen->width - 1) : px);
- py = (py >= pScreen->height ? (pScreen->height - 1) : py);
-
- xf86SetViewport(pScreen, px, py);
-
- (*pScreen->SetCursorPosition) (pScreen, px, py, FALSE);
- }
-
- return TRUE;
-}
-
-static Bool
-xf86RandR12ScreenSetSize (ScreenPtr pScreen,
- CARD16 width,
- CARD16 height,
- CARD32 mmWidth,
- CARD32 mmHeight)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
- WindowPtr pRoot = WindowTable[pScreen->myNum];
- Bool ret = TRUE;
-
- if (randrp->virtualX == -1 || randrp->virtualY == -1)
- {
- randrp->virtualX = pScrn->virtualX;
- randrp->virtualY = pScrn->virtualY;
- }
- if (pRoot)
- (*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
- pScrn->virtualX = width;
- pScrn->virtualY = height;
-
- pScreen->width = pScrn->virtualX;
- pScreen->height = pScrn->virtualY;
- pScreen->mmWidth = mmWidth;
- pScreen->mmHeight = mmHeight;
-
- xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1);
- xf86SetViewport (pScreen, 0, 0);
- if (pRoot)
- (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
-#if RANDR_12_INTERFACE
- if (WindowTable[pScreen->myNum])
- RRScreenSizeNotify (pScreen);
-#endif
- return ret;
-}
-
-Rotation
-xf86RandR12GetRotation(ScreenPtr pScreen)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-
- return randrp->rotation;
-}
-
-Bool
-xf86RandR12CreateScreenResources (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- int c;
- int width, height;
- int mmWidth, mmHeight;
-#ifdef PANORAMIX
- /* XXX disable RandR when using Xinerama */
- if (!noPanoramiXExtension)
- return TRUE;
-#endif
-
- /*
- * Compute size of screen
- */
- width = 0; height = 0;
- for (c = 0; c < config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = config->crtc[c];
- int crtc_width = crtc->x + crtc->mode.HDisplay;
- int crtc_height = crtc->y + crtc->mode.VDisplay;
-
- if (crtc->enabled && crtc_width > width)
- width = crtc_width;
- if (crtc->enabled && crtc_height > height)
- height = crtc_height;
- }
-
- if (width && height)
- {
- /*
- * Compute physical size of screen
- */
- if (monitorResolution)
- {
- mmWidth = width * 25.4 / monitorResolution;
- mmHeight = height * 25.4 / monitorResolution;
- }
- else
- {
- mmWidth = pScreen->mmWidth;
- mmHeight = pScreen->mmHeight;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Setting screen physical size to %d x %d\n",
- mmWidth, mmHeight);
- xf86RandR12ScreenSetSize (pScreen,
- width,
- height,
- mmWidth,
- mmHeight);
- }
-
- if (randrp->virtualX == -1 || randrp->virtualY == -1)
- {
- randrp->virtualX = pScrn->virtualX;
- randrp->virtualY = pScrn->virtualY;
- }
-#if RANDR_12_INTERFACE
- if (xf86RandR12CreateScreenResources12 (pScreen))
- return TRUE;
-#endif
- return TRUE;
-}
-
-
-Bool
-xf86RandR12Init (ScreenPtr pScreen)
-{
- rrScrPrivPtr rp;
- XF86RandRInfoPtr randrp;
-
-#ifdef PANORAMIX
- /* XXX disable RandR when using Xinerama */
- if (!noPanoramiXExtension)
- return TRUE;
-#endif
- if (xf86RandR12Generation != serverGeneration)
- {
- xf86RandR12Index = AllocateScreenPrivateIndex();
- xf86RandR12Generation = serverGeneration;
- }
-
- randrp = xalloc (sizeof (XF86RandRInfoRec));
- if (!randrp)
- return FALSE;
-
- if (!RRScreenInit(pScreen))
- {
- xfree (randrp);
- return FALSE;
- }
- rp = rrGetScrPriv(pScreen);
- rp->rrGetInfo = xf86RandR12GetInfo;
- rp->rrSetConfig = xf86RandR12SetConfig;
-
- randrp->virtualX = -1;
- randrp->virtualY = -1;
- randrp->mmWidth = pScreen->mmWidth;
- randrp->mmHeight = pScreen->mmHeight;
-
- randrp->rotation = RR_Rotate_0; /* initial rotated mode */
-
- randrp->supported_rotations = RR_Rotate_0;
-
- randrp->maxX = randrp->maxY = 0;
-
- pScreen->devPrivates[xf86RandR12Index].ptr = randrp;
-
-#if RANDR_12_INTERFACE
- if (!xf86RandR12Init12 (pScreen))
- return FALSE;
-#endif
- return TRUE;
-}
-
-void
-xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- int c;
-
- randrp->supported_rotations = rotations;
-
-#if RANDR_12_INTERFACE
- for (c = 0; c < config->num_crtc; c++) {
- xf86CrtcPtr crtc = config->crtc[c];
-
- RRCrtcSetRotations (crtc->randr_crtc, rotations);
- }
-#endif
-}
-
-void
-xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
-{
- ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
-
- if (xf86RandR12Generation != serverGeneration ||
- XF86RANDRINFO(pScreen)->virtualX == -1)
- {
- *x = pScrn->virtualX;
- *y = pScrn->virtualY;
- } else {
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-
- *x = randrp->virtualX;
- *y = randrp->virtualY;
- }
-}
-
-#if RANDR_12_INTERFACE
-static Bool
-xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
-{
- ScreenPtr pScreen = randr_crtc->pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- RRModePtr randr_mode = NULL;
- int x;
- int y;
- Rotation rotation;
- int numOutputs;
- RROutputPtr *randr_outputs;
- RROutputPtr randr_output;
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
- xf86OutputPtr output;
- int i, j;
- DisplayModePtr mode = &crtc->mode;
- Bool ret;
-
- randr_outputs = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr));
- if (!randr_outputs)
- return FALSE;
- x = crtc->x;
- y = crtc->y;
- rotation = crtc->rotation;
- numOutputs = 0;
- randr_mode = NULL;
- for (i = 0; i < config->num_output; i++)
- {
- output = config->output[i];
- if (output->crtc == crtc)
- {
- randr_output = output->randr_output;
- randr_outputs[numOutputs++] = randr_output;
- /*
- * We make copies of modes, so pointer equality
- * isn't sufficient
- */
- for (j = 0; j < randr_output->numModes; j++)
- {
- DisplayModePtr outMode = randr_output->modes[j]->devPrivate;
- if (xf86ModesEqual(mode, outMode))
- {
- randr_mode = randr_output->modes[j];
- break;
- }
- }
- }
- }
- ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
- rotation, numOutputs, randr_outputs);
- DEALLOCATE_LOCAL(randr_outputs);
- return ret;
-}
-
-static Bool
-xf86RandR12CrtcSet (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc,
- RRModePtr randr_mode,
- int x,
- int y,
- Rotation rotation,
- int num_randr_outputs,
- RROutputPtr *randr_outputs)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
- DisplayModePtr mode = randr_mode ? randr_mode->devPrivate : NULL;
- Bool changed = FALSE;
- int o, ro;
- xf86CrtcPtr *save_crtcs;
- Bool save_enabled = crtc->enabled;
-
- save_crtcs = ALLOCATE_LOCAL(config->num_crtc * sizeof (xf86CrtcPtr));
- if ((mode != NULL) != crtc->enabled)
- changed = TRUE;
- else if (mode && !xf86ModesEqual (&crtc->mode, mode))
- changed = TRUE;
-
- if (x != crtc->x || y != crtc->y)
- changed = TRUE;
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
- xf86CrtcPtr new_crtc;
-
- save_crtcs[o] = output->crtc;
-
- if (output->crtc == crtc)
- new_crtc = NULL;
- else
- new_crtc = output->crtc;
- for (ro = 0; ro < num_randr_outputs; ro++)
- if (output->randr_output == randr_outputs[ro])
- {
- new_crtc = crtc;
- break;
- }
- if (new_crtc != output->crtc)
- {
- changed = TRUE;
- output->crtc = new_crtc;
- }
- }
- /* XXX need device-independent mode setting code through an API */
- if (changed)
- {
- crtc->enabled = mode != NULL;
-
- if (mode)
- {
- if (!xf86CrtcSetMode (crtc, mode, rotation, x, y))
- {
- crtc->enabled = save_enabled;
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
- output->crtc = save_crtcs[o];
- }
- DEALLOCATE_LOCAL(save_crtcs);
- return FALSE;
- }
- /*
- * Save the last successful setting for EnterVT
- */
- crtc->desiredMode = *mode;
- crtc->desiredRotation = rotation;
- crtc->desiredX = x;
- crtc->desiredY = y;
- }
- xf86DisableUnusedFunctions (pScrn);
- }
- DEALLOCATE_LOCAL(save_crtcs);
- return xf86RandR12CrtcNotify (randr_crtc);
-}
-
-static Bool
-xf86RandR12CrtcSetGamma (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc)
-{
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
-
- if (crtc->funcs->gamma_set == NULL)
- return FALSE;
-
- crtc->funcs->gamma_set(crtc, randr_crtc->gammaRed, randr_crtc->gammaGreen,
- randr_crtc->gammaBlue, randr_crtc->gammaSize);
-
- return TRUE;
-}
-
-static Bool
-xf86RandR12OutputSetProperty (ScreenPtr pScreen,
- RROutputPtr randr_output,
- Atom property,
- RRPropertyValuePtr value)
-{
- xf86OutputPtr output = randr_output->devPrivate;
-
- /* If we don't have any property handler, then we don't care what the
- * user is setting properties to.
- */
- if (output->funcs->set_property == NULL)
- return TRUE;
-
- return output->funcs->set_property(output, property, value);
-}
-
-/**
- * Given a list of xf86 modes and a RandR Output object, construct
- * RandR modes and assign them to the output
- */
-static Bool
-xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
-{
- DisplayModePtr mode;
- RRModePtr *rrmodes = NULL;
- int nmode = 0;
- int npreferred = 0;
- Bool ret = TRUE;
- int pref;
-
- for (mode = modes; mode; mode = mode->next)
- nmode++;
-
- if (nmode) {
- rrmodes = xalloc (nmode * sizeof (RRModePtr));
-
- if (!rrmodes)
- return FALSE;
- nmode = 0;
-
- for (pref = 1; pref >= 0; pref--) {
- for (mode = modes; mode; mode = mode->next) {
- if ((pref != 0) == ((mode->type & M_T_PREFERRED) != 0)) {
- xRRModeInfo modeInfo;
- RRModePtr rrmode;
-
- modeInfo.nameLength = strlen (mode->name);
- modeInfo.width = mode->HDisplay;
- modeInfo.dotClock = mode->Clock * 1000;
- modeInfo.hSyncStart = mode->HSyncStart;
- modeInfo.hSyncEnd = mode->HSyncEnd;
- modeInfo.hTotal = mode->HTotal;
- modeInfo.hSkew = mode->HSkew;
-
- modeInfo.height = mode->VDisplay;
- modeInfo.vSyncStart = mode->VSyncStart;
- modeInfo.vSyncEnd = mode->VSyncEnd;
- modeInfo.vTotal = mode->VTotal;
- modeInfo.modeFlags = mode->Flags;
-
- rrmode = RRModeGet (&modeInfo, mode->name);
- if (rrmode) {
- rrmode->devPrivate = mode;
- rrmodes[nmode++] = rrmode;
- npreferred += pref;
- }
- }
- }
- }
- }
-
- ret = RROutputSetModes (randr_output, rrmodes, nmode, npreferred);
- xfree (rrmodes);
- return ret;
-}
-
-/*
- * Mirror the current mode configuration to RandR
- */
-static Bool
-xf86RandR12SetInfo12 (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- RROutputPtr *clones;
- RRCrtcPtr *crtcs;
- int ncrtc;
- int o, c, l;
- RRCrtcPtr randr_crtc;
- int nclone;
-
- clones = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr));
- crtcs = ALLOCATE_LOCAL (config->num_crtc * sizeof (RRCrtcPtr));
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
-
- ncrtc = 0;
- for (c = 0; c < config->num_crtc; c++)
- if (output->possible_crtcs & (1 << c))
- crtcs[ncrtc++] = config->crtc[c]->randr_crtc;
-
- if (output->crtc)
- randr_crtc = output->crtc->randr_crtc;
- else
- randr_crtc = NULL;
-
- if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc))
- {
- DEALLOCATE_LOCAL (crtcs);
- DEALLOCATE_LOCAL (clones);
- return FALSE;
- }
-
- RROutputSetCrtc (output->randr_output, randr_crtc);
- RROutputSetPhysicalSize(output->randr_output,
- output->mm_width,
- output->mm_height);
- xf86RROutputSetModes (output->randr_output, output->probed_modes);
-
- switch (output->status) {
- case XF86OutputStatusConnected:
- RROutputSetConnection (output->randr_output, RR_Connected);
- break;
- case XF86OutputStatusDisconnected:
- RROutputSetConnection (output->randr_output, RR_Disconnected);
- break;
- case XF86OutputStatusUnknown:
- RROutputSetConnection (output->randr_output, RR_UnknownConnection);
- break;
- }
-
- RROutputSetSubpixelOrder (output->randr_output, output->subpixel_order);
-
- /*
- * Valid clones
- */
- nclone = 0;
- for (l = 0; l < config->num_output; l++)
- {
- xf86OutputPtr clone = config->output[l];
-
- if (l != o && (output->possible_clones & (1 << l)))
- clones[nclone++] = clone->randr_output;
- }
- if (!RROutputSetClones (output->randr_output, clones, nclone))
- {
- DEALLOCATE_LOCAL (crtcs);
- DEALLOCATE_LOCAL (clones);
- return FALSE;
- }
- }
- DEALLOCATE_LOCAL (crtcs);
- DEALLOCATE_LOCAL (clones);
- return TRUE;
-}
-
-
-
-/*
- * Query the hardware for the current state, then mirror
- * that to RandR
- */
-static Bool
-xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
- xf86ProbeOutputModes (pScrn, 0, 0);
- xf86SetScrnInfoModes (pScrn);
- I830DGAReInit (pScreen);
- return xf86RandR12SetInfo12 (pScreen);
-}
-
-static Bool
-xf86RandR12CreateObjects12 (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- int c;
- int o;
-
- if (!RRInit ())
- return FALSE;
-
- /*
- * Configure crtcs
- */
- for (c = 0; c < config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = config->crtc[c];
-
- crtc->randr_crtc = RRCrtcCreate (crtc);
- RRCrtcAttachScreen (crtc->randr_crtc, pScreen);
- RRCrtcGammaSetSize (crtc->randr_crtc, 256);
- }
- /*
- * Configure outputs
- */
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
-
- output->randr_output = RROutputCreate (output->name,
- strlen (output->name),
- output);
- RROutputAttachScreen (output->randr_output, pScreen);
-
- if (output->funcs->create_resources != NULL)
- output->funcs->create_resources(output);
- }
- return TRUE;
-}
-
-static Bool
-xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
-{
- int c;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
-
- for (c = 0; c < config->num_crtc; c++)
- xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
-
-
- RRScreenSetSizeRange (pScreen, 320, 240,
- randrp->virtualX, randrp->virtualY);
- return TRUE;
-}
-
-static void
-xf86RandR12PointerMoved (int scrnIndex, int x, int y)
-{
-}
-
-static Bool
-xf86RandR12Init12 (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- rrScrPrivPtr rp = rrGetScrPriv(pScreen);
-
- rp->rrGetInfo = xf86RandR12GetInfo12;
- rp->rrScreenSetSize = xf86RandR12ScreenSetSize;
- rp->rrCrtcSet = xf86RandR12CrtcSet;
- rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
- rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
- rp->rrSetConfig = NULL;
- pScrn->PointerMoved = xf86RandR12PointerMoved;
- if (!xf86RandR12CreateObjects12 (pScreen))
- return FALSE;
-
- /*
- * Configure output modes
- */
- if (!xf86RandR12SetInfo12 (pScreen))
- return FALSE;
- return TRUE;
-}
-
-#endif
-
-Bool
-xf86RandR12PreInit (ScrnInfoPtr pScrn)
-{
- return TRUE;
-}
diff --git a/src/i830_randr.h b/src/i830_randr.h
deleted file mode 100644
index 8a4668b4..00000000
--- a/src/i830_randr.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright © 2006 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#ifndef _XF86_RANDR_H_
-#define _XF86_RANDR_H_
-#include <randrstr.h>
-#include <X11/extensions/render.h>
-
-Bool xf86RandR12CreateScreenResources (ScreenPtr pScreen);
-Bool xf86RandR12Init(ScreenPtr pScreen);
-void xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotation);
-Bool xf86RandR12SetConfig(ScreenPtr pScreen, Rotation rotation, int rate,
- RRScreenSizePtr pSize);
-Rotation xf86RandR12GetRotation(ScreenPtr pScreen);
-void xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y);
-Bool xf86RandR12PreInit (ScrnInfoPtr pScrn);
-
-#endif /* _XF86_RANDR_H_ */
diff --git a/src/i830_render.c b/src/i830_render.c
index 99338439..49d8fc11 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -557,17 +557,17 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
OUT_RING(PRIM3D_INLINE | PRIM3D_RECTLIST | (vertex_count-1));
- OUT_RING_F(dstX);
- OUT_RING_F(dstY);
- OUT_RING_F(src_x[0] / pI830->scale_units[0][0]);
- OUT_RING_F(src_y[0] / pI830->scale_units[0][1]);
+ OUT_RING_F(-0.125 + dstX + w);
+ OUT_RING_F(-0.125 + dstY + h);
+ OUT_RING_F(src_x[2] / pI830->scale_units[0][0]);
+ OUT_RING_F(src_y[2] / pI830->scale_units[0][1]);
if (has_mask) {
- OUT_RING_F(mask_x[0] / pI830->scale_units[1][0]);
- OUT_RING_F(mask_y[0] / pI830->scale_units[1][1]);
+ OUT_RING_F(mask_x[2] / pI830->scale_units[1][0]);
+ OUT_RING_F(mask_y[2] / pI830->scale_units[1][1]);
}
- OUT_RING_F(dstX);
- OUT_RING_F(dstY + h);
+ OUT_RING_F(-0.125 + dstX);
+ OUT_RING_F(-0.125 + dstY + h);
OUT_RING_F(src_x[1] / pI830->scale_units[0][0]);
OUT_RING_F(src_y[1] / pI830->scale_units[0][1]);
if (has_mask) {
@@ -575,13 +575,13 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
OUT_RING_F(mask_y[1] / pI830->scale_units[1][1]);
}
- OUT_RING_F(dstX + w);
- OUT_RING_F(dstY + h);
- OUT_RING_F(src_x[2] / pI830->scale_units[0][0]);
- OUT_RING_F(src_y[2] / pI830->scale_units[0][1]);
+ OUT_RING_F(-0.125 + dstX);
+ OUT_RING_F(-0.125 + dstY);
+ OUT_RING_F(src_x[0] / pI830->scale_units[0][0]);
+ OUT_RING_F(src_y[0] / pI830->scale_units[0][1]);
if (has_mask) {
- OUT_RING_F(mask_x[2] / pI830->scale_units[1][0]);
- OUT_RING_F(mask_y[2] / pI830->scale_units[1][1]);
+ OUT_RING_F(mask_x[0] / pI830->scale_units[1][0]);
+ OUT_RING_F(mask_y[0] / pI830->scale_units[1][1]);
}
ADVANCE_LP_RING();
}
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index ea62ad96..46a35f1c 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -1079,8 +1079,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
char *name_prefix;
char *name_suffix;
- output = xf86OutputCreate (pScrn, &i830_sdvo_output_funcs,
- "ADD2 PCIE card");
+ output = xf86OutputCreate (pScrn, &i830_sdvo_output_funcs,NULL);
if (!output)
return;
intel_output = xnfcalloc (sizeof (I830OutputPrivateRec) +
diff --git a/src/i830_video.c b/src/i830_video.c
index 22f5bee4..e580dab5 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -184,9 +184,9 @@ void exaMoveInPixmap (PixmapPtr pPixmap);
OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE); \
} \
if (IS_I965G(pI830)) \
- OUT_RING(pI830->OverlayMem->Start | OFC_UPDATE); \
+ OUT_RING(pI830->overlay_regs->offset | OFC_UPDATE); \
else \
- OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \
+ OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE); \
OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \
OUT_RING(MI_NOOP); \
ADVANCE_LP_RING(); \
@@ -202,9 +202,9 @@ void exaMoveInPixmap (PixmapPtr pPixmap);
OUT_RING(MI_NOOP); \
OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_OFF); \
if (IS_I965G(pI830)) \
- OUT_RING(pI830->OverlayMem->Start | OFC_UPDATE); \
+ OUT_RING(pI830->overlay_regs->offset | OFC_UPDATE); \
else \
- OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \
+ OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE); \
OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \
OUT_RING(MI_NOOP); \
ADVANCE_LP_RING(); \
@@ -472,7 +472,9 @@ I830InitVideo(ScreenPtr pScreen)
}
/* Set up overlay video if we can do it at this depth. */
- if (!IS_I965G(pI830) && pScrn->bitsPerPixel != 8) {
+ if (!IS_I965G(pI830) && pScrn->bitsPerPixel != 8 &&
+ pI830->overlay_regs != NULL)
+ {
overlayAdaptor = I830SetupImageVideoOverlay(pScreen);
if (overlayAdaptor != NULL) {
adaptors[num_adaptors++] = overlayAdaptor;
@@ -496,10 +498,10 @@ I830ResetVideo(ScrnInfoPtr pScrn)
I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
I830OverlayRegPtr overlay =
- (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
+ (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
OVERLAY_DEBUG("I830ResetVideo: base: %p, offset: 0x%lx, obase: %p\n",
- pI830->FbBase, pI830->OverlayMem->Start, overlay);
+ pI830->FbBase, pI830->overlay_regs->offset, overlay);
/*
* Default to maximum image size in YV12
*/
@@ -925,8 +927,7 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
{
I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
I830Ptr pI830 = I830PTR(pScrn);
- I830OverlayRegPtr overlay =
- (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
+ I830OverlayRegPtr overlay;
if (pPriv->textured) {
/* XXX: Currently the brightness/saturation attributes aren't hooked up.
@@ -936,6 +937,8 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
return Success;
}
+ overlay = (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
+
if (attribute == xvBrightness) {
if ((value < -128) || (value > 127))
return BadValue;
@@ -1553,7 +1556,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
I830OverlayRegPtr overlay =
- (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
+ (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
unsigned int swidth;
unsigned int mask, shift, offsety, offsetu;
int tmp;
@@ -2076,7 +2079,8 @@ I830AllocateMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear, int size,
/* Converts an offset from XAA's linear allocator to an offset from the
* start of fb.
*/
-#define XAA_OFFSET_TO_OFFSET(x) (pI830->FrontBuffer.Start + (x * pI830->cpp))
+#define XAA_OFFSET_TO_OFFSET(x) \
+ (pI830->front_buffer->offset + (x * pI830->cpp))
/* The XFree86 linear allocator operates in units of screen pixels,
* sadly.
@@ -2159,8 +2163,7 @@ I830PutImage(ScrnInfoPtr pScrn,
I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
- I830OverlayRegPtr overlay =
- (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
+ I830OverlayRegPtr overlay;
PixmapPtr pPixmap;
INT32 x1, x2, y1, y2;
int srcPitch, srcPitch2 = 0, dstPitch, destId;
@@ -2169,6 +2172,12 @@ I830PutImage(ScrnInfoPtr pScrn,
int pitchAlignMask;
int extraLinear;
+ if (pPriv->textured)
+ overlay = NULL;
+ else
+ overlay = (I830OverlayRegPtr) (pI830->FbBase +
+ pI830->overlay_regs->offset);
+
#if 0
ErrorF("I830PutImage: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d)\n"
"width %d, height %d\n", src_x, src_y, src_w, src_h, drw_x, drw_y,
@@ -2700,7 +2709,7 @@ I830DisplaySurface(XF86SurfacePtr surface,
I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pI830Priv = GET_PORT_PRIVATE(pScrn);
I830OverlayRegPtr overlay =
- (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
+ (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset);
INT32 x1, y1, x2, y2;
INT32 loops = 0;
BoxRec dstBox;
diff --git a/src/i830_xaa.c b/src/i830_xaa.c
index 5ef5d3c4..f0951387 100644
--- a/src/i830_xaa.c
+++ b/src/i830_xaa.c
@@ -162,20 +162,20 @@ I830XAAInit(ScreenPtr pScreen)
/* On the primary screen */
if (pI830->init == 0) {
- if (pI830->Scratch.Size != 0) {
+ if (pI830->xaa_scratch->size != 0) {
width = ((pScrn->displayWidth + 31) & ~31) / 8;
- nr_buffers = pI830->Scratch.Size / width;
- ptr = pI830->FbBase + pI830->Scratch.Start;
+ nr_buffers = pI830->xaa_scratch->size / width;
+ ptr = pI830->FbBase + pI830->xaa_scratch->offset;
}
} else {
/* On the secondary screen */
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
- if (pI8301->Scratch2.Size != 0) {
+ if (pI8301->xaa_scratch_2->size != 0) {
width = ((pScrn->displayWidth + 31) & ~31) / 8;
- nr_buffers = pI8301->Scratch2.Size / width;
+ nr_buffers = pI8301->xaa_scratch_2->size / width;
/* We have to use the primary screen's FbBase, as that's where
- * we allocated Scratch2, so we get the correct pointer */
- ptr = pI8301->FbBase + pI8301->Scratch2.Start;
+ * we allocated xaa_scratch_2, so we get the correct pointer */
+ ptr = pI8301->FbBase + pI8301->xaa_scratch_2->offset;
}
}
@@ -279,11 +279,15 @@ CheckTiling(ScrnInfoPtr pScrn)
if (IS_I965G(pI830)) {
if (pI830->bufferOffset == pScrn->fbOffset && pI830->front_tiled == FENCE_XMAJOR)
tiled = 1;
- if (pI830->bufferOffset == pI830->BackBuffer.Start && pI830->back_tiled == FENCE_XMAJOR)
+ if (pI830->bufferOffset == pI830->back_buffer->offset &&
+ pI830->back_tiled == FENCE_XMAJOR) {
tiled = 1;
+ }
/* not really supported as it's always YMajor tiled */
- if (pI830->bufferOffset == pI830->DepthBuffer.Start && pI830->depth_tiled == FENCE_XMAJOR)
+ if (pI830->bufferOffset == pI830->depth_buffer->offset &&
+ pI830->depth_tiled == FENCE_XMAJOR) {
tiled = 1;
+ }
}
return tiled;
@@ -600,7 +604,7 @@ I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
/* We have to use the primary screen's FbBase, as that's where
- * we allocated Scratch2, so we get the correct pointer */
+ * we allocated xaa_scratch_2, so we get the correct pointer */
pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
pI8301->FbBase);
}
@@ -700,7 +704,7 @@ I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
/* We have to use the primary screen's FbBase, as that's where
- * we allocated Scratch2, so we get the correct pointer */
+ * we allocated xaa_scratch_2, so we get the correct pointer */
pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
pI8301->FbBase);
}
diff --git a/src/i830_xf86Crtc.h b/src/i830_xf86Crtc.h
deleted file mode 100644
index 6de2c923..00000000
--- a/src/i830_xf86Crtc.h
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * Copyright © 2006 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-#ifndef _XF86CRTC_H_
-#define _XF86CRTC_H_
-
-#include <edid.h>
-#include "randrstr.h"
-#include "i830_xf86Rename.h"
-#include "i830_xf86Modes.h"
-#include "xf86Parser.h"
-#include "damage.h"
-
-/* Compat definitions for older X Servers. */
-#ifndef M_T_PREFERRED
-#define M_T_PREFERRED 0x08
-#endif
-#ifndef M_T_DRIVER
-#define M_T_DRIVER 0x40
-#endif
-
-typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr;
-typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr;
-
-typedef enum _xf86OutputStatus {
- XF86OutputStatusConnected,
- XF86OutputStatusDisconnected,
- XF86OutputStatusUnknown,
-} xf86OutputStatus;
-
-typedef struct _xf86CrtcFuncs {
- /**
- * Turns the crtc on/off, or sets intermediate power levels if available.
- *
- * Unsupported intermediate modes drop to the lower power setting. If the
- * mode is DPMSModeOff, the crtc must be disabled sufficiently for it to
- * be safe to call mode_set.
- */
- void
- (*dpms)(xf86CrtcPtr crtc,
- int mode);
-
- /**
- * Saves the crtc's state for restoration on VT switch.
- */
- void
- (*save)(xf86CrtcPtr crtc);
-
- /**
- * Restore's the crtc's state at VT switch.
- */
- void
- (*restore)(xf86CrtcPtr crtc);
-
- /**
- * Lock CRTC prior to mode setting, mostly for DRI.
- * Returns whether unlock is needed
- */
- Bool
- (*lock) (xf86CrtcPtr crtc);
-
- /**
- * Unlock CRTC after mode setting, mostly for DRI
- */
- void
- (*unlock) (xf86CrtcPtr crtc);
-
- /**
- * Callback to adjust the mode to be set in the CRTC.
- *
- * This allows a CRTC to adjust the clock or even the entire set of
- * timings, which is used for panels with fixed timings or for
- * buses with clock limitations.
- */
- Bool
- (*mode_fixup)(xf86CrtcPtr crtc,
- DisplayModePtr mode,
- DisplayModePtr adjusted_mode);
-
- /**
- * Callback for setting up a video mode after fixups have been made.
- */
- void
- (*mode_set)(xf86CrtcPtr crtc,
- DisplayModePtr mode,
- DisplayModePtr adjusted_mode,
- int x, int y);
-
- /* Set the color ramps for the CRTC to the given values. */
- void
- (*gamma_set)(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
- int size);
-
- /**
- * Create shadow pixmap for rotation support
- */
- PixmapPtr
- (*shadow_create) (xf86CrtcPtr crtc, int width, int height);
-
- /**
- * Destroy shadow pixmap
- */
- void
- (*shadow_destroy) (xf86CrtcPtr crtc, PixmapPtr pPixmap);
-
- /**
- * Clean up driver-specific bits of the crtc
- */
- void
- (*destroy) (xf86CrtcPtr crtc);
-} xf86CrtcFuncsRec, *xf86CrtcFuncsPtr;
-
-struct _xf86Crtc {
- /**
- * Associated ScrnInfo
- */
- ScrnInfoPtr scrn;
-
- /**
- * Active state of this CRTC
- *
- * Set when this CRTC is driving one or more outputs
- */
- Bool enabled;
-
- /** Track whether cursor is within CRTC range */
- Bool cursorInRange;
-
- /** Track state of cursor associated with this CRTC */
- Bool cursorShown;
-
- /**
- * Active mode
- *
- * This reflects the mode as set in the CRTC currently
- * It will be cleared when the VT is not active or
- * during server startup
- */
- DisplayModeRec mode;
- Rotation rotation;
- PixmapPtr rotatedPixmap;
- /**
- * Position on screen
- *
- * Locates this CRTC within the frame buffer
- */
- int x, y;
-
- /**
- * Desired mode
- *
- * This is set to the requested mode, independent of
- * whether the VT is active. In particular, it receives
- * the startup configured mode and saves the active mode
- * on VT switch.
- */
- DisplayModeRec desiredMode;
- Rotation desiredRotation;
- int desiredX, desiredY;
-
- /** crtc-specific functions */
- const xf86CrtcFuncsRec *funcs;
-
- /**
- * Driver private
- *
- * Holds driver-private information
- */
- void *driver_private;
-
-#ifdef RANDR_12_INTERFACE
- /**
- * RandR crtc
- *
- * When RandR 1.2 is available, this
- * points at the associated crtc object
- */
- RRCrtcPtr randr_crtc;
-#else
- void *randr_crtc;
-#endif
-};
-
-typedef struct _xf86OutputFuncs {
- /**
- * Called to allow the output a chance to create properties after the
- * RandR objects have been created.
- */
- void
- (*create_resources)(xf86OutputPtr output);
-
- /**
- * Turns the output on/off, or sets intermediate power levels if available.
- *
- * Unsupported intermediate modes drop to the lower power setting. If the
- * mode is DPMSModeOff, the output must be disabled, as the DPLL may be
- * disabled afterwards.
- */
- void
- (*dpms)(xf86OutputPtr output,
- int mode);
-
- /**
- * Saves the output's state for restoration on VT switch.
- */
- void
- (*save)(xf86OutputPtr output);
-
- /**
- * Restore's the output's state at VT switch.
- */
- void
- (*restore)(xf86OutputPtr output);
-
- /**
- * Callback for testing a video mode for a given output.
- *
- * This function should only check for cases where a mode can't be supported
- * on the output specifically, and not represent generic CRTC limitations.
- *
- * \return MODE_OK if the mode is valid, or another MODE_* otherwise.
- */
- int
- (*mode_valid)(xf86OutputPtr output,
- DisplayModePtr pMode);
-
- /**
- * Callback to adjust the mode to be set in the CRTC.
- *
- * This allows an output to adjust the clock or even the entire set of
- * timings, which is used for panels with fixed timings or for
- * buses with clock limitations.
- */
- Bool
- (*mode_fixup)(xf86OutputPtr output,
- DisplayModePtr mode,
- DisplayModePtr adjusted_mode);
-
- /**
- * Callback for setting up a video mode after fixups have been made.
- *
- * This is only called while the output is disabled. The dpms callback
- * must be all that's necessary for the output, to turn the output on
- * after this function is called.
- */
- void
- (*mode_set)(xf86OutputPtr output,
- DisplayModePtr mode,
- DisplayModePtr adjusted_mode);
-
- /**
- * Probe for a connected output, and return detect_status.
- */
- xf86OutputStatus
- (*detect)(xf86OutputPtr output);
-
- /**
- * Query the device for the modes it provides.
- *
- * This function may also update MonInfo, mm_width, and mm_height.
- *
- * \return singly-linked list of modes or NULL if no modes found.
- */
- DisplayModePtr
- (*get_modes)(xf86OutputPtr output);
-
-#ifdef RANDR_12_INTERFACE
- /**
- * Callback when an output's property has changed.
- */
- Bool
- (*set_property)(xf86OutputPtr output,
- Atom property,
- RRPropertyValuePtr value);
-#endif
- /**
- * Clean up driver-specific bits of the output
- */
- void
- (*destroy) (xf86OutputPtr output);
-} xf86OutputFuncsRec, *xf86OutputFuncsPtr;
-
-struct _xf86Output {
- /**
- * Associated ScrnInfo
- */
- ScrnInfoPtr scrn;
-
- /**
- * Currently connected crtc (if any)
- *
- * If this output is not in use, this field will be NULL.
- */
- xf86CrtcPtr crtc;
-
- /**
- * Possible CRTCs for this output as a mask of crtc indices
- */
- CARD32 possible_crtcs;
-
- /**
- * Possible outputs to share the same CRTC as a mask of output indices
- */
- CARD32 possible_clones;
-
- /**
- * Whether this output can support interlaced modes
- */
- Bool interlaceAllowed;
-
- /**
- * Whether this output can support double scan modes
- */
- Bool doubleScanAllowed;
-
- /**
- * List of available modes on this output.
- *
- * This should be the list from get_modes(), plus perhaps additional
- * compatible modes added later.
- */
- DisplayModePtr probed_modes;
-
- /**
- * Options parsed from the related monitor section
- */
- OptionInfoPtr options;
-
- /**
- * Configured monitor section
- */
- XF86ConfMonitorPtr conf_monitor;
-
- /**
- * Desired initial position
- */
- int initial_x, initial_y;
-
- /**
- * Current connection status
- *
- * This indicates whether a monitor is known to be connected
- * to this output or not, or whether there is no way to tell
- */
- xf86OutputStatus status;
-
- /** EDID monitor information */
- xf86MonPtr MonInfo;
-
- /** subpixel order */
- int subpixel_order;
-
- /** Physical size of the currently attached output device. */
- int mm_width, mm_height;
-
- /** Output name */
- char *name;
-
- /** output-specific functions */
- const xf86OutputFuncsRec *funcs;
-
- /** driver private information */
- void *driver_private;
-
-#ifdef RANDR_12_INTERFACE
- /**
- * RandR 1.2 output structure.
- *
- * When RandR 1.2 is available, this points at the associated
- * RandR output structure and is created when this output is created
- */
- RROutputPtr randr_output;
-#else
- void *randr_output;
-#endif
-};
-
-typedef struct _xf86CrtcConfig {
- int num_output;
- xf86OutputPtr *output;
- /**
- * compat_output is used whenever we deal
- * with legacy code that only understands a single
- * output. pScrn->modes will be loaded from this output,
- * adjust frame will whack this output, etc.
- */
- int compat_output;
-
- int num_crtc;
- xf86CrtcPtr *crtc;
-
- int minWidth, minHeight;
- int maxWidth, maxHeight;
-
- /* For crtc-based rotation */
- DamagePtr rotationDamage;
-
- /* DGA */
- unsigned int dga_flags;
-
-} xf86CrtcConfigRec, *xf86CrtcConfigPtr;
-
-extern int xf86CrtcConfigPrivateIndex;
-
-#define XF86_CRTC_CONFIG_PTR(p) ((xf86CrtcConfigPtr) ((p)->privates[xf86CrtcConfigPrivateIndex].ptr))
-
-/*
- * Initialize xf86CrtcConfig structure
- */
-
-void
-xf86CrtcConfigInit (ScrnInfoPtr scrn);
-
-void
-xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
- int minWidth, int minHeight,
- int maxWidth, int maxHeight);
-
-/*
- * Crtc functions
- */
-xf86CrtcPtr
-xf86CrtcCreate (ScrnInfoPtr scrn,
- const xf86CrtcFuncsRec *funcs);
-
-void
-xf86CrtcDestroy (xf86CrtcPtr crtc);
-
-
-/**
- * Allocate a crtc for the specified output
- *
- * Find a currently unused CRTC which is suitable for
- * the specified output
- */
-
-xf86CrtcPtr
-xf86AllocCrtc (xf86OutputPtr output);
-
-/**
- * Free a crtc
- *
- * Mark the crtc as unused by any outputs
- */
-
-void
-xf86FreeCrtc (xf86CrtcPtr crtc);
-
-/**
- * Sets the given video mode on the given crtc
- */
-Bool
-xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
- int x, int y);
-
-/*
- * Assign crtc rotation during mode set
- */
-Bool
-xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation);
-
-/**
- * Return whether any output is assigned to the crtc
- */
-Bool
-xf86CrtcInUse (xf86CrtcPtr crtc);
-
-/*
- * Output functions
- */
-xf86OutputPtr
-xf86OutputCreate (ScrnInfoPtr scrn,
- const xf86OutputFuncsRec *funcs,
- const char *name);
-
-Bool
-xf86OutputRename (xf86OutputPtr output, const char *name);
-
-void
-xf86OutputDestroy (xf86OutputPtr output);
-
-void
-xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY);
-
-void
-xf86SetScrnInfoModes (ScrnInfoPtr pScrn);
-
-Bool
-xf86InitialConfiguration (ScrnInfoPtr pScrn);
-
-void
-xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
-
-Bool
-xf86SaveScreen(ScreenPtr pScreen, int mode);
-
-void
-xf86DisableUnusedFunctions(ScrnInfoPtr pScrn);
-
-/**
- * Set the EDID information for the specified output
- */
-void
-xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon);
-
-/**
- * Return the list of modes supported by the EDID information
- * stored in 'output'
- */
-DisplayModePtr
-xf86OutputGetEDIDModes (xf86OutputPtr output);
-
-xf86MonPtr
-xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus);
-
-#endif /* _XF86CRTC_H_ */
diff --git a/src/i830_xf86Modes.c b/src/i830_xf86Modes.c
deleted file mode 100644
index f620d4d5..00000000
--- a/src/i830_xf86Modes.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/* -*- c-basic-offset: 4 -*- */
-/* $XdotOrg: xserver/xorg/hw/xfree86/common/xf86Mode.c,v 1.10 2006/03/07 16:00:57 libv Exp $ */
-/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Mode.c,v 1.69 2003/10/08 14:58:28 dawes Exp $ */
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * 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 COPYRIGHT HOLDER(S) OR AUTHOR(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.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "xf86.h"
-#include "i830.h"
-#include "i830_xf86Modes.h"
-#include "xf86Priv.h"
-
-extern XF86ConfigPtr xf86configptr;
-
-/**
- * @file this file contains symbols from xf86Mode.c and friends that are static
- * there but we still want to use. We need to come up with better API here.
- */
-
-#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
-/**
- * Calculates the horizontal sync rate of a mode.
- *
- * Exact copy of xf86Mode.c's.
- */
-double
-xf86ModeHSync(DisplayModePtr mode)
-{
- double hsync = 0.0;
-
- if (mode->HSync > 0.0)
- hsync = mode->HSync;
- else if (mode->HTotal > 0)
- hsync = (float)mode->Clock / (float)mode->HTotal;
-
- return hsync;
-}
-
-/**
- * Calculates the vertical refresh rate of a mode.
- *
- * Exact copy of xf86Mode.c's.
- */
-double
-xf86ModeVRefresh(DisplayModePtr mode)
-{
- double refresh = 0.0;
-
- if (mode->VRefresh > 0.0)
- refresh = mode->VRefresh;
- else if (mode->HTotal > 0 && mode->VTotal > 0) {
- refresh = mode->Clock * 1000.0 / mode->HTotal / mode->VTotal;
- if (mode->Flags & V_INTERLACE)
- refresh *= 2.0;
- if (mode->Flags & V_DBLSCAN)
- refresh /= 2.0;
- if (mode->VScan > 1)
- refresh /= (float)(mode->VScan);
- }
- return refresh;
-}
-
-/** Sets a default mode name of <width>x<height> on a mode. */
-void
-xf86SetModeDefaultName(DisplayModePtr mode)
-{
- if (mode->name != NULL)
- xfree(mode->name);
-
- mode->name = XNFprintf("%dx%d", mode->HDisplay, mode->VDisplay);
-}
-
-/*
- * xf86SetModeCrtc
- *
- * Initialises the Crtc parameters for a mode. The initialisation includes
- * adjustments for interlaced and double scan modes.
- *
- * Exact copy of xf86Mode.c's.
- */
-void
-xf86SetModeCrtc(DisplayModePtr p, int adjustFlags)
-{
- if ((p == NULL) || ((p->type & M_T_CRTC_C) == M_T_BUILTIN))
- return;
-
- p->CrtcHDisplay = p->HDisplay;
- p->CrtcHSyncStart = p->HSyncStart;
- p->CrtcHSyncEnd = p->HSyncEnd;
- p->CrtcHTotal = p->HTotal;
- p->CrtcHSkew = p->HSkew;
- p->CrtcVDisplay = p->VDisplay;
- p->CrtcVSyncStart = p->VSyncStart;
- p->CrtcVSyncEnd = p->VSyncEnd;
- p->CrtcVTotal = p->VTotal;
- if (p->Flags & V_INTERLACE) {
- if (adjustFlags & INTERLACE_HALVE_V) {
- p->CrtcVDisplay /= 2;
- p->CrtcVSyncStart /= 2;
- p->CrtcVSyncEnd /= 2;
- p->CrtcVTotal /= 2;
- }
- /* Force interlaced modes to have an odd VTotal */
- /* maybe we should only do this when INTERLACE_HALVE_V is set? */
- p->CrtcVTotal |= 1;
- }
-
- if (p->Flags & V_DBLSCAN) {
- p->CrtcVDisplay *= 2;
- p->CrtcVSyncStart *= 2;
- p->CrtcVSyncEnd *= 2;
- p->CrtcVTotal *= 2;
- }
- if (p->VScan > 1) {
- p->CrtcVDisplay *= p->VScan;
- p->CrtcVSyncStart *= p->VScan;
- p->CrtcVSyncEnd *= p->VScan;
- p->CrtcVTotal *= p->VScan;
- }
- p->CrtcVBlankStart = min(p->CrtcVSyncStart, p->CrtcVDisplay);
- p->CrtcVBlankEnd = max(p->CrtcVSyncEnd, p->CrtcVTotal);
- p->CrtcHBlankStart = min(p->CrtcHSyncStart, p->CrtcHDisplay);
- p->CrtcHBlankEnd = max(p->CrtcHSyncEnd, p->CrtcHTotal);
-
- p->CrtcHAdjusted = FALSE;
- p->CrtcVAdjusted = FALSE;
-}
-
-/**
- * Allocates and returns a copy of pMode, including pointers within pMode.
- */
-DisplayModePtr
-xf86DuplicateMode(DisplayModePtr pMode)
-{
- DisplayModePtr pNew;
-
- pNew = xnfalloc(sizeof(DisplayModeRec));
- *pNew = *pMode;
- pNew->next = NULL;
- pNew->prev = NULL;
- if (pNew->name == NULL) {
- xf86SetModeDefaultName(pMode);
- } else {
- pNew->name = xnfstrdup(pMode->name);
- }
-
- return pNew;
-}
-
-/**
- * Duplicates every mode in the given list and returns a pointer to the first
- * mode.
- *
- * \param modeList doubly-linked mode list
- */
-DisplayModePtr
-xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList)
-{
- DisplayModePtr first = NULL, last = NULL;
- DisplayModePtr mode;
-
- for (mode = modeList; mode != NULL; mode = mode->next) {
- DisplayModePtr new;
-
- new = xf86DuplicateMode(mode);
-
- /* Insert pNew into modeList */
- if (last) {
- last->next = new;
- new->prev = last;
- } else {
- first = new;
- new->prev = NULL;
- }
- new->next = NULL;
- last = new;
- }
-
- return first;
-}
-
-/**
- * Returns true if the given modes should program to the same timings.
- *
- * This doesn't use Crtc values, as it might be used on ModeRecs without the
- * Crtc values set. So, it's assumed that the other numbers are enough.
- *
- * This isn't in xf86Modes.c, but it might deserve to be there.
- */
-Bool
-xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2)
-{
- if (pMode1->Clock == pMode2->Clock &&
- pMode1->HDisplay == pMode2->HDisplay &&
- pMode1->HSyncStart == pMode2->HSyncStart &&
- pMode1->HSyncEnd == pMode2->HSyncEnd &&
- pMode1->HTotal == pMode2->HTotal &&
- pMode1->HSkew == pMode2->HSkew &&
- pMode1->VDisplay == pMode2->VDisplay &&
- pMode1->VSyncStart == pMode2->VSyncStart &&
- pMode1->VSyncEnd == pMode2->VSyncEnd &&
- pMode1->VTotal == pMode2->VTotal &&
- pMode1->VScan == pMode2->VScan &&
- pMode1->Flags == pMode2->Flags)
- {
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-/* exact copy of xf86Mode.c */
-static void
-add(char **p, char *new)
-{
- *p = xnfrealloc(*p, strlen(*p) + strlen(new) + 2);
- strcat(*p, " ");
- strcat(*p, new);
-}
-
-/**
- * Print out a modeline.
- *
- * Convenient VRefresh printing was added, though, compared to xf86Mode.c
- */
-void
-xf86PrintModeline(int scrnIndex,DisplayModePtr mode)
-{
- char tmp[256];
- char *flags = xnfcalloc(1, 1);
-
- if (mode->HSkew) {
- snprintf(tmp, 256, "hskew %i", mode->HSkew);
- add(&flags, tmp);
- }
- if (mode->VScan) {
- snprintf(tmp, 256, "vscan %i", mode->VScan);
- add(&flags, tmp);
- }
- if (mode->Flags & V_INTERLACE) add(&flags, "interlace");
- if (mode->Flags & V_CSYNC) add(&flags, "composite");
- if (mode->Flags & V_DBLSCAN) add(&flags, "doublescan");
- if (mode->Flags & V_BCAST) add(&flags, "bcast");
- if (mode->Flags & V_PHSYNC) add(&flags, "+hsync");
- if (mode->Flags & V_NHSYNC) add(&flags, "-hsync");
- if (mode->Flags & V_PVSYNC) add(&flags, "+vsync");
- if (mode->Flags & V_NVSYNC) add(&flags, "-vsync");
- if (mode->Flags & V_PCSYNC) add(&flags, "+csync");
- if (mode->Flags & V_NCSYNC) add(&flags, "-csync");
-#if 0
- if (mode->Flags & V_CLKDIV2) add(&flags, "vclk/2");
-#endif
- xf86DrvMsg(scrnIndex, X_INFO,
- "Modeline \"%s\"x%.01f %6.2f %i %i %i %i %i %i %i %i%s "
- "(%.01f kHz)\n",
- mode->name, mode->VRefresh, mode->Clock/1000., mode->HDisplay,
- mode->HSyncStart, mode->HSyncEnd, mode->HTotal,
- mode->VDisplay, mode->VSyncStart, mode->VSyncEnd,
- mode->VTotal, flags, xf86ModeHSync(mode));
- xfree(flags);
-}
-#endif /* XORG_VERSION_CURRENT <= 7.2.99.2 */
-
-/**
- * Marks as bad any modes with unsupported flags.
- *
- * \param modeList doubly-linked or circular list of modes.
- * \param flags flags supported by the driver.
- *
- * \bug only V_INTERLACE and V_DBLSCAN are supported. Is that enough?
- *
- * This is not in xf86Modes.c, but would be part of the proposed new API.
- */
-void
-xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- int flags)
-{
- DisplayModePtr mode;
-
- for (mode = modeList; mode != NULL; mode = mode->next) {
- if (mode->Flags & V_INTERLACE && !(flags & V_INTERLACE))
- mode->status = MODE_NO_INTERLACE;
- if (mode->Flags & V_DBLSCAN && !(flags & V_DBLSCAN))
- mode->status = MODE_NO_DBLESCAN;
- }
-}
-
-/**
- * Marks as bad any modes extending beyond the given max X, Y, or pitch.
- *
- * \param modeList doubly-linked or circular list of modes.
- *
- * This is not in xf86Modes.c, but would be part of the proposed new API.
- */
-void
-xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- int maxX, int maxY, int maxPitch)
-{
- DisplayModePtr mode;
-
- for (mode = modeList; mode != NULL; mode = mode->next) {
- if (maxPitch > 0 && mode->HDisplay > maxPitch)
- mode->status = MODE_BAD_WIDTH;
-
- if (maxX > 0 && mode->HDisplay > maxX)
- mode->status = MODE_VIRTUAL_X;
-
- if (maxY > 0 && mode->VDisplay > maxY)
- mode->status = MODE_VIRTUAL_Y;
-
- if (mode->next == modeList)
- break;
- }
-}
-
-/**
- * Marks as bad any modes that aren't supported by the given monitor's
- * hsync and vrefresh ranges.
- *
- * \param modeList doubly-linked or circular list of modes.
- *
- * This is not in xf86Modes.c, but would be part of the proposed new API.
- */
-void
-xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- MonPtr mon)
-{
- DisplayModePtr mode;
-
- for (mode = modeList; mode != NULL; mode = mode->next) {
- Bool bad;
- int i;
-
- bad = TRUE;
- for (i = 0; i < mon->nHsync; i++) {
- if (xf86ModeHSync(mode) >= mon->hsync[i].lo &&
- xf86ModeHSync(mode) <= mon->hsync[i].hi)
- {
- bad = FALSE;
- }
- }
- if (bad)
- mode->status = MODE_HSYNC;
-
- bad = TRUE;
- for (i = 0; i < mon->nVrefresh; i++) {
- if (xf86ModeVRefresh(mode) >= mon->vrefresh[i].lo &&
- xf86ModeVRefresh(mode) <= mon->vrefresh[i].hi)
- {
- bad = FALSE;
- }
- }
- if (bad)
- mode->status = MODE_VSYNC;
-
- if (mode->next == modeList)
- break;
- }
-}
-
-/**
- * Marks as bad any modes extending beyond outside of the given clock ranges.
- *
- * \param modeList doubly-linked or circular list of modes.
- * \param min pointer to minimums of clock ranges
- * \param max pointer to maximums of clock ranges
- * \param n_ranges number of ranges.
- *
- * This is not in xf86Modes.c, but would be part of the proposed new API.
- */
-void
-xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- int *min, int *max, int n_ranges)
-{
- DisplayModePtr mode;
- int i;
-
- for (mode = modeList; mode != NULL; mode = mode->next) {
- Bool good = FALSE;
- for (i = 0; i < n_ranges; i++) {
- if (mode->Clock >= min[i] && mode->Clock <= max[i]) {
- good = TRUE;
- break;
- }
- }
- if (!good)
- mode->status = MODE_CLOCK_RANGE;
- }
-}
-
-/**
- * If the user has specified a set of mode names to use, mark as bad any modes
- * not listed.
- *
- * The user mode names specified are prefixes to names of modes, so "1024x768"
- * will match modes named "1024x768", "1024x768x75", "1024x768-good", but
- * "1024x768x75" would only match "1024x768x75" from that list.
- *
- * MODE_BAD is used as the rejection flag, for lack of a better flag.
- *
- * \param modeList doubly-linked or circular list of modes.
- *
- * This is not in xf86Modes.c, but would be part of the proposed new API.
- */
-void
-xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList)
-{
- DisplayModePtr mode;
-
- if (pScrn->display->modes[0] == NULL)
- return;
-
- for (mode = modeList; mode != NULL; mode = mode->next) {
- int i;
- Bool good = FALSE;
-
- for (i = 0; pScrn->display->modes[i] != NULL; i++) {
- if (strncmp(pScrn->display->modes[i], mode->name,
- strlen(pScrn->display->modes[i])) == 0) {
- good = TRUE;
- break;
- }
- }
- if (!good)
- mode->status = MODE_BAD;
- }
-}
-
-
-/**
- * Frees any modes from the list with a status other than MODE_OK.
- *
- * \param modeList pointer to a doubly-linked or circular list of modes.
- * \param verbose determines whether the reason for mode invalidation is
- * printed.
- *
- * This is not in xf86Modes.c, but would be part of the proposed new API.
- */
-void
-xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
- Bool verbose)
-{
- DisplayModePtr mode;
-
- for (mode = *modeList; mode != NULL;) {
- DisplayModePtr next = mode->next, first = *modeList;
-
- if (mode->status != MODE_OK) {
- if (verbose) {
- char *type = "";
- if (mode->type & M_T_BUILTIN)
- type = "built-in ";
- else if (mode->type & M_T_DEFAULT)
- type = "default ";
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Not using %smode \"%s\" (%s)\n", type, mode->name,
- xf86ModeStatusToString(mode->status));
- }
- xf86DeleteMode(modeList, mode);
- }
-
- if (next == first)
- break;
- mode = next;
- }
-}
-
-/**
- * Adds the new mode into the mode list, and returns the new list
- *
- * \param modes doubly-linked mode list.
- */
-DisplayModePtr
-xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new)
-{
- if (modes == NULL)
- return new;
-
- if (new) {
- DisplayModePtr mode = modes;
-
- while (mode->next)
- mode = mode->next;
-
- mode->next = new;
- new->prev = mode;
- }
-
- return modes;
-}
-
-/**
- * Build a mode list from a list of config file modes
- */
-static DisplayModePtr
-xf86GetConfigModes (XF86ConfModeLinePtr conf_mode)
-{
- DisplayModePtr head = NULL, prev = NULL, mode;
-
- for (; conf_mode; conf_mode = (XF86ConfModeLinePtr) conf_mode->list.next)
- {
- mode = xcalloc(1, sizeof(DisplayModeRec));
- if (!mode)
- continue;
- mode->name = xstrdup(conf_mode->ml_identifier);
- if (!mode->name)
- {
- xfree (mode);
- continue;
- }
- mode->type = 0;
- mode->Clock = conf_mode->ml_clock;
- mode->HDisplay = conf_mode->ml_hdisplay;
- mode->HSyncStart = conf_mode->ml_hsyncstart;
- mode->HSyncEnd = conf_mode->ml_hsyncend;
- mode->HTotal = conf_mode->ml_htotal;
- mode->VDisplay = conf_mode->ml_vdisplay;
- mode->VSyncStart = conf_mode->ml_vsyncstart;
- mode->VSyncEnd = conf_mode->ml_vsyncend;
- mode->VTotal = conf_mode->ml_vtotal;
- mode->Flags = conf_mode->ml_flags;
- mode->HSkew = conf_mode->ml_hskew;
- mode->VScan = conf_mode->ml_vscan;
-
- mode->prev = prev;
- mode->next = NULL;
- if (prev)
- prev->next = mode;
- else
- head = mode;
- prev = mode;
- }
- return head;
-}
-
-/**
- * Build a mode list from a monitor configuration
- */
-DisplayModePtr
-xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor)
-{
- DisplayModePtr modes = NULL;
- XF86ConfModesLinkPtr modes_link;
-
- if (!conf_monitor)
- return NULL;
-
- /*
- * first we collect the mode lines from the UseModes directive
- */
- for (modes_link = conf_monitor->mon_modes_sect_lst;
- modes_link;
- modes_link = modes_link->list.next)
- {
- /* If this modes link hasn't been resolved, go look it up now */
- if (!modes_link->ml_modes)
- modes_link->ml_modes = xf86findModes (modes_link->ml_modes_str,
- xf86configptr->conf_modes_lst);
- if (modes_link->ml_modes)
- modes = xf86ModesAdd (modes,
- xf86GetConfigModes (modes_link->ml_modes->mon_modeline_lst));
- }
-
- return xf86ModesAdd (modes,
- xf86GetConfigModes (conf_monitor->mon_modeline_lst));
-}
-
-/**
- * Build a mode list containing all of the default modes
- */
-DisplayModePtr
-xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed)
-{
- DisplayModePtr head = NULL, prev = NULL, mode;
- int i;
-
- for (i = 0; xf86DefaultModes[i].name != NULL; i++)
- {
- DisplayModePtr defMode = &xf86DefaultModes[i];
-
- if (!interlaceAllowed && (defMode->Flags & V_INTERLACE))
- continue;
- if (!doubleScanAllowed && (defMode->Flags & V_DBLSCAN))
- continue;
-
- mode = xalloc(sizeof(DisplayModeRec));
- if (!mode)
- continue;
- memcpy(mode,&xf86DefaultModes[i],sizeof(DisplayModeRec));
- mode->name = xstrdup(xf86DefaultModes[i].name);
- if (!mode->name)
- {
- xfree (mode);
- continue;
- }
- mode->prev = prev;
- mode->next = NULL;
- if (prev)
- prev->next = mode;
- else
- head = mode;
- prev = mode;
- }
- return head;
-}
diff --git a/src/i830_xf86Modes.h b/src/i830_xf86Modes.h
deleted file mode 100644
index d032199d..00000000
--- a/src/i830_xf86Modes.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright © 2006 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Eric Anholt <eric@anholt.net>
- *
- */
-
-#ifndef _I830_XF86MODES_H_
-#define _I830_XF86MODES_H_
-#include "xorgVersion.h"
-#include "xf86Parser.h"
-#include "i830_xf86Rename.h"
-
-double xf86ModeHSync(DisplayModePtr mode);
-double xf86ModeVRefresh(DisplayModePtr mode);
-DisplayModePtr xf86DuplicateMode(DisplayModePtr pMode);
-DisplayModePtr xf86DuplicateModes(ScrnInfoPtr pScrn,
- DisplayModePtr modeList);
-void xf86SetModeDefaultName(DisplayModePtr mode);
-void xf86SetModeCrtc(DisplayModePtr p, int adjustFlags);
-Bool xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2);
-void xf86PrintModeline(int scrnIndex,DisplayModePtr mode);
-DisplayModePtr xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new);
-
-DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC);
-DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
- Bool Reduced, Bool Interlaced);
-
-void
-xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- int flags);
-
-void
-xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- int *min, int *max, int n_ranges);
-
-void
-xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- int maxX, int maxY, int maxPitch);
-
-void
-xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- MonPtr mon);
-
-void
-xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
- Bool verbose);
-
-void
-xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- int flags);
-
-void
-xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList);
-
-DisplayModePtr
-xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor);
-
-DisplayModePtr
-xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed);
-
-#endif /* _I830_XF86MODES_H_ */
diff --git a/src/i830_xf86Rename.h b/src/i830_xf86Rename.h
deleted file mode 100644
index cf8de622..00000000
--- a/src/i830_xf86Rename.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright © 2006 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#ifndef _XF86RENAME_H_
-#define _XF86RENAME_H_
-
-#include "local_xf86Rename.h"
-
-#define xf86CrtcConfigInit XF86NAME(xf86CrtcConfigInit)
-#define xf86CrtcConfigPrivateIndex XF86NAME(xf86CrtcConfigPrivateIndex)
-#define xf86CrtcCreate XF86NAME(xf86CrtcCreate)
-#define xf86CrtcDestroy XF86NAME(xf86CrtcDestroy)
-#define xf86CrtcInUse XF86NAME(xf86CrtcInUse)
-#define xf86CrtcRotate XF86NAME(xf86CrtcRotate)
-#define xf86CrtcSetMode XF86NAME(xf86CrtcSetMode)
-#define xf86CrtcSetSizeRange XF86NAME(xf86CrtcSetSizeRange)
-#define xf86CVTMode XF86NAME(xf86CVTMode)
-#define xf86DisableUnusedFunctions XF86NAME(xf86DisableUnusedFunctions)
-#define xf86DPMSSet XF86NAME(xf86DPMSSet)
-#define xf86DuplicateMode XF86NAME(xf86DuplicateMode)
-#define xf86DuplicateModes XF86NAME(xf86DuplicateModes)
-#define xf86GetDefaultModes XF86NAME(xf86GetDefaultModes)
-#define xf86GetMonitorModes XF86NAME(xf86GetMonitorModes)
-#define xf86InitialConfiguration XF86NAME(xf86InitialConfiguration)
-#define xf86ModeHSync XF86NAME(xf86ModeHSync)
-#define xf86ModesAdd XF86NAME(xf86ModesAdd)
-#define xf86ModesEqual XF86NAME(xf86ModesEqual)
-#define xf86ModeVRefresh XF86NAME(xf86ModeVRefresh)
-#define xf86OutputCreate XF86NAME(xf86OutputCreate)
-#define xf86OutputDestroy XF86NAME(xf86OutputDestroy)
-#define xf86OutputGetEDID XF86NAME(xf86OutputGetEDID)
-#define xf86OutputGetEDIDModes XF86NAME(xf86OutputGetEDIDModes)
-#define xf86OutputRename XF86NAME(xf86OutputRename)
-#define xf86OutputSetEDID XF86NAME(xf86OutputSetEDID)
-#define xf86PrintModeline XF86NAME(xf86PrintModeline)
-#define xf86ProbeOutputModes XF86NAME(xf86ProbeOutputModes)
-#define xf86PruneInvalidModes XF86NAME(xf86PruneInvalidModes)
-#define xf86SetModeCrtc XF86NAME(xf86SetModeCrtc)
-#define xf86SetModeDefaultName XF86NAME(xf86SetModeDefaultName)
-#define xf86SetScrnInfoModes XF86NAME(xf86SetScrnInfoModes)
-#define xf86ValidateModesClocks XF86NAME(xf86ValidateModesClocks)
-#define xf86ValidateModesFlags XF86NAME(xf86ValidateModesFlags)
-#define xf86ValidateModesSize XF86NAME(xf86ValidateModesSize)
-#define xf86ValidateModesSync XF86NAME(xf86ValidateModesSync)
-#define xf86ValidateModesUserConfig XF86NAME(xf86ValidateModesUserConfig)
-
-#endif /* _XF86RENAME_H_ */
diff --git a/src/i830_xf86Rotate.c b/src/i830_xf86Rotate.c
deleted file mode 100644
index bd4d5a60..00000000
--- a/src/i830_xf86Rotate.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * Copyright © 2006 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "xf86.h"
-#include "xf86DDC.h"
-#include "fb.h"
-#include "windowstr.h"
-#include "i830_xf86Crtc.h"
-#include "i830_xf86Modes.h"
-#include "i830_randr.h"
-#include "X11/extensions/render.h"
-#define DPMS_SERVER
-#include "X11/extensions/dpms.h"
-#include "X11/Xatom.h"
-
-static int
-mode_height (DisplayModePtr mode, Rotation rotation)
-{
- switch (rotation & 0xf) {
- case RR_Rotate_0:
- case RR_Rotate_180:
- return mode->VDisplay;
- case RR_Rotate_90:
- case RR_Rotate_270:
- return mode->HDisplay;
- default:
- return 0;
- }
-}
-
-static int
-mode_width (DisplayModePtr mode, Rotation rotation)
-{
- switch (rotation & 0xf) {
- case RR_Rotate_0:
- case RR_Rotate_180:
- return mode->HDisplay;
- case RR_Rotate_90:
- case RR_Rotate_270:
- return mode->VDisplay;
- default:
- return 0;
- }
-}
-
-/* borrowed from composite extension, move to Render and publish? */
-
-static VisualPtr
-compGetWindowVisual (WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- VisualID vid = wVisual (pWin);
- int i;
-
- for (i = 0; i < pScreen->numVisuals; i++)
- if (pScreen->visuals[i].vid == vid)
- return &pScreen->visuals[i];
- return 0;
-}
-
-static PictFormatPtr
-compWindowFormat (WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- return PictureMatchVisual (pScreen, pWin->drawable.depth,
- compGetWindowVisual (pWin));
-}
-
-static void
-xf86RotateBox (BoxPtr dst, BoxPtr src, Rotation rotation,
- int dest_width, int dest_height)
-{
- switch (rotation & 0xf) {
- default:
- case RR_Rotate_0:
- *dst = *src;
- break;
- case RR_Rotate_90:
- dst->x1 = src->y1;
- dst->y1 = dest_height - src->x2;
- dst->x2 = src->y2;
- dst->y2 = dest_height - src->x1;
- break;
- case RR_Rotate_180:
- dst->x1 = dest_width - src->x2;
- dst->y1 = dest_height - src->y2;
- dst->x2 = dest_width - src->x1;
- dst->y2 = dest_height - src->y1;
- break;
- case RR_Rotate_270:
- dst->x1 = dest_width - src->y2;
- dst->y1 = src->x1;
- dst->y2 = src->x2;
- dst->x2 = dest_width - src->y1;
- break;
- }
- if (rotation & RR_Reflect_X) {
- int x1 = dst->x1;
- dst->x1 = dest_width - dst->x2;
- dst->x2 = dest_width - x1;
- }
- if (rotation & RR_Reflect_Y) {
- int y1 = dst->y1;
- dst->y1 = dest_height - dst->y2;
- dst->y2 = dest_height - y1;
- }
-}
-
-static void
-xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
-{
- ScrnInfoPtr scrn = crtc->scrn;
- ScreenPtr screen = scrn->pScreen;
- WindowPtr root = WindowTable[screen->myNum];
- PixmapPtr dst_pixmap = crtc->rotatedPixmap;
- PictFormatPtr format = compWindowFormat (WindowTable[screen->myNum]);
- int error;
- PicturePtr src, dst;
- PictTransform transform;
- int n = REGION_NUM_RECTS(region);
- BoxPtr b = REGION_RECTS(region);
- XID include_inferiors = IncludeInferiors;
-
- src = CreatePicture (None,
- &root->drawable,
- format,
- CPSubwindowMode,
- &include_inferiors,
- serverClient,
- &error);
- if (!src) {
- ErrorF("couldn't create src pict\n");
- return;
- }
- dst = CreatePicture (None,
- &dst_pixmap->drawable,
- format,
- 0L,
- NULL,
- serverClient,
- &error);
- if (!dst) {
- ErrorF("couldn't create src pict\n");
- return;
- }
-
- memset (&transform, '\0', sizeof (transform));
- transform.matrix[2][2] = IntToxFixed(1);
- transform.matrix[0][2] = IntToxFixed(crtc->x);
- transform.matrix[1][2] = IntToxFixed(crtc->y);
- switch (crtc->rotation & 0xf) {
- default:
- case RR_Rotate_0:
- transform.matrix[0][0] = IntToxFixed(1);
- transform.matrix[1][1] = IntToxFixed(1);
- break;
- case RR_Rotate_90:
- transform.matrix[0][1] = IntToxFixed(-1);
- transform.matrix[1][0] = IntToxFixed(1);
- transform.matrix[0][2] += IntToxFixed(crtc->mode.VDisplay);
- break;
- case RR_Rotate_180:
- transform.matrix[0][0] = IntToxFixed(-1);
- transform.matrix[1][1] = IntToxFixed(-1);
- transform.matrix[0][2] += IntToxFixed(crtc->mode.HDisplay);
- transform.matrix[1][2] += IntToxFixed(crtc->mode.VDisplay);
- break;
- case RR_Rotate_270:
- transform.matrix[0][1] = IntToxFixed(1);
- transform.matrix[1][0] = IntToxFixed(-1);
- transform.matrix[1][2] += IntToxFixed(crtc->mode.VDisplay);
- break;
- }
-
- /* handle reflection */
- if (crtc->rotation & RR_Reflect_X)
- {
- /* XXX figure this out */
- }
- if (crtc->rotation & RR_Reflect_Y)
- {
- /* XXX figure this out too */
- }
-
- error = SetPictureTransform (src, &transform);
- if (error) {
- ErrorF("Couldn't set transform\n");
- return;
- }
-
- while (n--)
- {
- BoxRec dst_box;
-
- xf86RotateBox (&dst_box, b, crtc->rotation,
- crtc->mode.HDisplay, crtc->mode.VDisplay);
- CompositePicture (PictOpSrc,
- src, NULL, dst,
- dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1,
- dst_box.x2 - dst_box.x1,
- dst_box.y2 - dst_box.y1);
- b++;
- }
- FreePicture (src, None);
- FreePicture (dst, None);
-}
-
-static void
-xf86RotateRedisplay(ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- DamagePtr damage = xf86_config->rotationDamage;
- RegionPtr region;
-
- if (!damage)
- return;
- region = DamageRegion(damage);
- if (REGION_NOTEMPTY(pScreen, region))
- {
- int c;
-
- for (c = 0; c < xf86_config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = xf86_config->crtc[c];
-
- if (crtc->rotation != RR_Rotate_0)
- {
- BoxRec box;
- RegionRec crtc_damage;
-
- /* compute portion of damage that overlaps crtc */
- box.x1 = crtc->x;
- box.x2 = crtc->x + mode_width (&crtc->mode, crtc->rotation);
- box.y1 = crtc->y;
- box.y2 = crtc->y + mode_height (&crtc->mode, crtc->rotation);
- REGION_INIT(pScreen, &crtc_damage, &box, 1);
- REGION_INTERSECT (pScreen, &crtc_damage, &crtc_damage, region);
-
- /* update damaged region */
- if (REGION_NOTEMPTY(pScreen, &crtc_damage))
- xf86RotateCrtcRedisplay (crtc, &crtc_damage);
-
- REGION_UNINIT (pScreen, &crtc_damage);
- }
- }
- DamageEmpty(damage);
- }
-}
-
-static void
-xf86RotateBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead)
-{
- ScreenPtr pScreen = (ScreenPtr) data;
-
- xf86RotateRedisplay(pScreen);
-}
-
-static void
-xf86RotateWakeupHandler(pointer data, int i, pointer LastSelectMask)
-{
-}
-
-Bool
-xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- ScreenPtr pScreen = pScrn->pScreen;
-
- if (rotation == RR_Rotate_0)
- {
- /* Free memory from rotation */
- if (crtc->rotatedPixmap)
- {
- crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap);
- crtc->rotatedPixmap = NULL;
- }
-
- if (xf86_config->rotationDamage)
- {
- /* Free damage structure */
- DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
- xf86_config->rotationDamage);
- DamageDestroy (xf86_config->rotationDamage);
- xf86_config->rotationDamage = NULL;
- /* Free block/wakeup handler */
- RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler,
- xf86RotateWakeupHandler,
- (pointer) pScreen);
- }
- }
- else
- {
- /*
- * these are the size of the shadow pixmap, which
- * matches the mode, not the pre-rotated copy in the
- * frame buffer
- */
- int width = mode->HDisplay;
- int height = mode->VDisplay;
- PixmapPtr shadow = crtc->rotatedPixmap;
- int old_width = shadow ? shadow->drawable.width : 0;
- int old_height = shadow ? shadow->drawable.height : 0;
- BoxRec damage_box;
- RegionRec damage_region;
-
- /* Allocate memory for rotation */
- if (old_width != width || old_height != height)
- {
- if (shadow)
- {
- crtc->funcs->shadow_destroy (crtc, shadow);
- crtc->rotatedPixmap = NULL;
- }
- shadow = crtc->funcs->shadow_create (crtc, width, height);
- if (!shadow)
- goto bail1;
- crtc->rotatedPixmap = shadow;
- }
-
- if (!xf86_config->rotationDamage)
- {
- /* Create damage structure */
- xf86_config->rotationDamage = DamageCreate (NULL, NULL,
- DamageReportNone,
- TRUE, pScreen, pScreen);
- if (!xf86_config->rotationDamage)
- goto bail2;
-
- /* Hook damage to screen pixmap */
- DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
- xf86_config->rotationDamage);
-
- /* Assign block/wakeup handler */
- if (!RegisterBlockAndWakeupHandlers (xf86RotateBlockHandler,
- xf86RotateWakeupHandler,
- (pointer) pScreen))
- {
- goto bail3;
- }
- damage_box.x1 = 0;
- damage_box.y1 = 0;
- damage_box.x2 = mode_width (mode, rotation);
- damage_box.y2 = mode_height (mode, rotation);
- REGION_INIT (pScreen, &damage_region, &damage_box, 1);
- DamageDamageRegion (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
- &damage_region);
- REGION_UNINIT (pScreen, &damage_region);
- }
- if (0)
- {
-bail3:
- DamageDestroy (xf86_config->rotationDamage);
- xf86_config->rotationDamage = NULL;
-
-bail2:
- if (shadow)
- {
- crtc->funcs->shadow_destroy (crtc, shadow);
- crtc->rotatedPixmap = NULL;
- }
-bail1:
- if (old_width && old_height)
- crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
- old_width,
- old_height);
- return FALSE;
- }
- }
-
- /* All done */
- return TRUE;
-}
diff --git a/src/i830_xf86cvt.c b/src/i830_xf86cvt.c
deleted file mode 100644
index 1a2b7869..00000000
--- a/src/i830_xf86cvt.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright 2005-2006 Luc Verhaegen.
- *
- * 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 COPYRIGHT HOLDER(S) OR AUTHOR(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.
- */
-
-/**
- * @file This is a copy of xf86cvt.c from the X Server, for compatibility with
- * old servers (pre-1.2).
- */
-
-/*
- * The reason for having this function in a file of its own is
- * so that ../utils/cvt/cvt can link to it, and that xf86CVTMode
- * code is shared directly.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "xf86.h"
-
-#include "i830.h"
-#include "i830_display.h"
-#include <string.h>
-
-#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
-/*
- * Generate a CVT standard mode from HDisplay, VDisplay and VRefresh.
- *
- * These calculations are stolen from the CVT calculation spreadsheet written
- * by Graham Loveridge. He seems to be claiming no copyright and there seems to
- * be no license attached to this. He apparently just wants to see his name
- * mentioned.
- *
- * This file can be found at http://www.vesa.org/Public/CVT/CVTd6r1.xls
- *
- * Comments and structure corresponds to the comments and structure of the xls.
- * This should ease importing of future changes to the standard (not very
- * likely though).
- *
- * About margins; i'm sure that they are to be the bit between HDisplay and
- * HBlankStart, HBlankEnd and HTotal, VDisplay and VBlankStart, VBlankEnd and
- * VTotal, where the overscan colour is shown. FB seems to call _all_ blanking
- * outside sync "margin" for some reason. Since we prefer seeing proper
- * blanking instead of the overscan colour, and since the Crtc* values will
- * probably get altered after us, we will disable margins altogether. With
- * these calculations, Margins will plainly expand H/VDisplay, and we don't
- * want that. -- libv
- *
- */
-_X_EXPORT DisplayModePtr
-xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
- Bool Interlaced)
-{
- DisplayModeRec *Mode = xnfalloc(sizeof(DisplayModeRec));
-
- /* 1) top/bottom margin size (% of height) - default: 1.8 */
-#define CVT_MARGIN_PERCENTAGE 1.8
-
- /* 2) character cell horizontal granularity (pixels) - default 8 */
-#define CVT_H_GRANULARITY 8
-
- /* 4) Minimum vertical porch (lines) - default 3 */
-#define CVT_MIN_V_PORCH 3
-
- /* 4) Minimum number of vertical back porch lines - default 6 */
-#define CVT_MIN_V_BPORCH 6
-
- /* Pixel Clock step (kHz) */
-#define CVT_CLOCK_STEP 250
-
- Bool Margins = FALSE;
- float VFieldRate, HPeriod;
- int HDisplayRnd, HMargin;
- int VDisplayRnd, VMargin, VSync;
- float Interlace; /* Please rename this */
-
- memset(Mode, 0, sizeof(DisplayModeRec));
-
- /* CVT default is 60.0Hz */
- if (!VRefresh)
- VRefresh = 60.0;
-
- /* 1. Required field rate */
- if (Interlaced)
- VFieldRate = VRefresh * 2;
- else
- VFieldRate = VRefresh;
-
- /* 2. Horizontal pixels */
- HDisplayRnd = HDisplay - (HDisplay % CVT_H_GRANULARITY);
-
- /* 3. Determine left and right borders */
- if (Margins) {
- /* right margin is actually exactly the same as left */
- HMargin = (((float) HDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0);
- HMargin -= HMargin % CVT_H_GRANULARITY;
- } else
- HMargin = 0;
-
- /* 4. Find total active pixels */
- Mode->HDisplay = HDisplayRnd + 2*HMargin;
-
- /* 5. Find number of lines per field */
- if (Interlaced)
- VDisplayRnd = VDisplay / 2;
- else
- VDisplayRnd = VDisplay;
-
- /* 6. Find top and bottom margins */
- /* nope. */
- if (Margins)
- /* top and bottom margins are equal again. */
- VMargin = (((float) VDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0);
- else
- VMargin = 0;
-
- Mode->VDisplay = VDisplay + 2*VMargin;
-
- /* 7. Interlace */
- if (Interlaced)
- Interlace = 0.5;
- else
- Interlace = 0.0;
-
- /* Determine VSync Width from aspect ratio */
- if (!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay))
- VSync = 4;
- else if (!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay))
- VSync = 5;
- else if (!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay))
- VSync = 6;
- else if (!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay))
- VSync = 7;
- else if (!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay))
- VSync = 7;
- else /* Custom */
- VSync = 10;
-
- if (!Reduced) { /* simplified GTF calculation */
-
- /* 4) Minimum time of vertical sync + back porch interval (µs)
- * default 550.0 */
-#define CVT_MIN_VSYNC_BP 550.0
-
- /* 3) Nominal HSync width (% of line period) - default 8 */
-#define CVT_HSYNC_PERCENTAGE 8
-
- float HBlankPercentage;
- int VSyncAndBackPorch, VBackPorch;
- int HBlank;
-
- /* 8. Estimated Horizontal period */
- HPeriod = ((float) (1000000.0 / VFieldRate - CVT_MIN_VSYNC_BP)) /
- (VDisplayRnd + 2 * VMargin + CVT_MIN_V_PORCH + Interlace);
-
- /* 9. Find number of lines in sync + backporch */
- if (((int)(CVT_MIN_VSYNC_BP / HPeriod) + 1) < (VSync + CVT_MIN_V_PORCH))
- VSyncAndBackPorch = VSync + CVT_MIN_V_PORCH;
- else
- VSyncAndBackPorch = (int)(CVT_MIN_VSYNC_BP / HPeriod) + 1;
-
- /* 10. Find number of lines in back porch */
- VBackPorch = VSyncAndBackPorch - VSync;
-
- /* 11. Find total number of lines in vertical field */
- Mode->VTotal = VDisplayRnd + 2 * VMargin + VSyncAndBackPorch + Interlace
- + CVT_MIN_V_PORCH;
-
- /* 5) Definition of Horizontal blanking time limitation */
- /* Gradient (%/kHz) - default 600 */
-#define CVT_M_FACTOR 600
-
- /* Offset (%) - default 40 */
-#define CVT_C_FACTOR 40
-
- /* Blanking time scaling factor - default 128 */
-#define CVT_K_FACTOR 128
-
- /* Scaling factor weighting - default 20 */
-#define CVT_J_FACTOR 20
-
-#define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256
-#define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \
- CVT_J_FACTOR
-
- /* 12. Find ideal blanking duty cycle from formula */
- HBlankPercentage = CVT_C_PRIME - CVT_M_PRIME * HPeriod/1000.0;
-
- /* 13. Blanking time */
- if (HBlankPercentage < 20)
- HBlankPercentage = 20;
-
- HBlank = Mode->HDisplay * HBlankPercentage/(100.0 - HBlankPercentage);
- HBlank -= HBlank % (2*CVT_H_GRANULARITY);
-
- /* 14. Find total number of pixels in a line. */
- Mode->HTotal = Mode->HDisplay + HBlank;
-
- /* Fill in HSync values */
- Mode->HSyncEnd = Mode->HDisplay + HBlank / 2;
-
- Mode->HSyncStart = Mode->HSyncEnd -
- (Mode->HTotal * CVT_HSYNC_PERCENTAGE) / 100;
- Mode->HSyncStart += CVT_H_GRANULARITY -
- Mode->HSyncStart % CVT_H_GRANULARITY;
-
- /* Fill in VSync values */
- Mode->VSyncStart = Mode->VDisplay + CVT_MIN_V_PORCH;
- Mode->VSyncEnd = Mode->VSyncStart + VSync;
-
- } else { /* Reduced blanking */
- /* Minimum vertical blanking interval time (µs) - default 460 */
-#define CVT_RB_MIN_VBLANK 460.0
-
- /* Fixed number of clocks for horizontal sync */
-#define CVT_RB_H_SYNC 32.0
-
- /* Fixed number of clocks for horizontal blanking */
-#define CVT_RB_H_BLANK 160.0
-
- /* Fixed number of lines for vertical front porch - default 3 */
-#define CVT_RB_VFPORCH 3
-
- int VBILines;
-
- /* 8. Estimate Horizontal period. */
- HPeriod = ((float) (1000000.0 / VFieldRate - CVT_RB_MIN_VBLANK)) /
- (VDisplayRnd + 2*VMargin);
-
- /* 9. Find number of lines in vertical blanking */
- VBILines = ((float) CVT_RB_MIN_VBLANK) / HPeriod + 1;
-
- /* 10. Check if vertical blanking is sufficient */
- if (VBILines < (CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH))
- VBILines = CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH;
-
- /* 11. Find total number of lines in vertical field */
- Mode->VTotal = VDisplayRnd + 2 * VMargin + Interlace + VBILines;
-
- /* 12. Find total number of pixels in a line */
- Mode->HTotal = Mode->HDisplay + CVT_RB_H_BLANK;
-
- /* Fill in HSync values */
- Mode->HSyncEnd = Mode->HDisplay + CVT_RB_H_BLANK / 2;
- Mode->HSyncStart = Mode->HSyncEnd - CVT_RB_H_SYNC;
-
- /* Fill in VSync values */
- Mode->VSyncStart = Mode->VDisplay + CVT_RB_VFPORCH;
- Mode->VSyncEnd = Mode->VSyncStart + VSync;
- }
-
- /* 15/13. Find pixel clock frequency (kHz for xf86) */
- Mode->Clock = Mode->HTotal * 1000.0 / HPeriod;
- Mode->Clock -= Mode->Clock % CVT_CLOCK_STEP;
-
- /* 16/14. Find actual Horizontal Frequency (kHz) */
- Mode->HSync = ((float) Mode->Clock) / ((float) Mode->HTotal);
-
- /* 17/15. Find actual Field rate */
- Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) /
- ((float) (Mode->HTotal * Mode->VTotal));
-
- /* 18/16. Find actual vertical frame frequency */
- /* ignore - just set the mode flag for interlaced */
- if (Interlaced)
- Mode->VTotal *= 2;
-
- {
- char Name[256];
- Name[0] = 0;
-
- snprintf(Name, 256, "%dx%d", HDisplay, VDisplay);
-
- Mode->name = xnfalloc(strlen(Name) + 1);
- memcpy(Mode->name, Name, strlen(Name) + 1);
- }
-
- if (Reduced)
- Mode->Flags |= V_PHSYNC | V_NVSYNC;
- else
- Mode->Flags |= V_NHSYNC | V_PVSYNC;
-
- if (Interlaced)
- Mode->Flags |= V_INTERLACE;
-
- return Mode;
-}
-#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) */
diff --git a/src/i965_render.c b/src/i965_render.c
index 266b461f..78f1146c 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -133,7 +133,8 @@ static void i965_get_blend_cntl(int op, PicturePtr pMask, CARD32 dst_format,
* the source blend factor is 0, and the source blend value is the mask
* channels multiplied by the source picture's alpha.
*/
- if (pMask && pMask->componentAlpha && i965_blend_op[op].src_alpha) {
+ if (pMask && pMask->componentAlpha && PICT_FORMAT_RGB(pMask->format)
+ && i965_blend_op[op].src_alpha) {
if (*dblend == BRW_BLENDFACTOR_SRC_ALPHA) {
*dblend = BRW_BLENDFACTOR_SRC_COLOR;
} else if (*dblend == BRW_BLENDFACTOR_INV_SRC_ALPHA) {
@@ -223,7 +224,8 @@ i965_check_composite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
if (op >= sizeof(i965_blend_op) / sizeof(i965_blend_op[0]))
I830FALLBACK("Unsupported Composite op 0x%x\n", op);
- if (pMaskPicture != NULL && pMaskPicture->componentAlpha) {
+ if (pMaskPicture && pMaskPicture->componentAlpha &&
+ PICT_FORMAT_RGB(pMaskPicture->format)) {
/* Check if it's component alpha that relies on a source alpha and on
* the source value. We can only get one of those into the single
* source value that we get to blend with.
@@ -234,9 +236,7 @@ i965_check_composite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
I830FALLBACK("Component alpha not supported with source "
"alpha and source value blending.\n");
}
- /* XXX: fallback now for mask with componentAlpha */
- I830FALLBACK("mask componentAlpha not ready.\n");
- }
+ }
if (!i965_check_composite_texture(pSrcPicture, 0))
I830FALLBACK("Check Src picture texture\n");
@@ -337,17 +337,19 @@ static const CARD32 sf_kernel_static_mask[][4] = {
/* ps kernels */
#define PS_KERNEL_NUM_GRF 32
#define PS_MAX_THREADS 32
-/* 1: no mask */
+
static const CARD32 ps_kernel_static_nomask [][4] = {
#include "exa_wm_nomask_prog.h"
};
-/* 2: mask with componentAlpha, src * mask color, XXX: later */
static const CARD32 ps_kernel_static_maskca [][4] = {
-/*#include "i965_composite_wm_maskca.h" */
+#include "exa_wm_maskca_prog.h"
+};
+
+static const CARD32 ps_kernel_static_maskca_srcalpha [][4] = {
+#include "exa_wm_maskca_srcalpha_prog.h"
};
-/* 3: mask without componentAlpha, src * mask alpha */
static const CARD32 ps_kernel_static_masknoca [][4] = {
#include "exa_wm_masknoca_prog.h"
};
@@ -442,13 +444,20 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
else
next_offset = sf_kernel_offset + sizeof (sf_kernel_static);
- /* XXX: ps_kernel may be seperated, fix with offset */
ps_kernel_offset = ALIGN(next_offset, 64);
if (pMask) {
- if (pMaskPicture->componentAlpha)
- next_offset = ps_kernel_offset + sizeof(ps_kernel_static_maskca);
- else
- next_offset = ps_kernel_offset + sizeof(ps_kernel_static_masknoca);
+ if (pMaskPicture->componentAlpha &&
+ PICT_FORMAT_RGB(pMaskPicture->format)) {
+ if (i965_blend_op[op].src_alpha) {
+ next_offset = ps_kernel_offset +
+ sizeof(ps_kernel_static_maskca_srcalpha);
+ } else {
+ next_offset = ps_kernel_offset +
+ sizeof(ps_kernel_static_maskca);
+ }
+ } else
+ next_offset = ps_kernel_offset +
+ sizeof(ps_kernel_static_masknoca);
} else {
next_offset = ps_kernel_offset + sizeof (ps_kernel_static_nomask);
}
@@ -492,9 +501,9 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
next_offset = default_color_offset + sizeof(*default_color_state);
total_state_size = next_offset;
- assert(total_state_size < EXA_LINEAR_EXTRA);
+ assert(total_state_size < pI830->exa_965_state->size);
- state_base_offset = pI830->EXAStateMem.Start;
+ state_base_offset = pI830->exa_965_state->offset;
state_base_offset = ALIGN(state_base_offset, 64);
state_base = (char *)(pI830->FbBase + state_base_offset);
@@ -689,7 +698,7 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
default_color_state->color[0] = 0.0; /* R */
default_color_state->color[1] = 0.0; /* G */
default_color_state->color[2] = 0.0; /* B */
- default_color_state->color[3] = 1.0; /* A */
+ default_color_state->color[3] = 0.0; /* A */
src_sampler_state->ss0.default_color_mode = 0; /* GL mode */
@@ -746,7 +755,6 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
vs_state->vs6.vs_enable = 0;
vs_state->vs6.vert_cache_disable = 1;
- /* XXX: sf_kernel? keep it as now */
/* Set up the SF kernel to do coord interp: for each attribute,
* calculate dA/dx and dA/dy. Hand these interpolation coefficients
* back to SF which then hands pixels off to WM.
@@ -788,10 +796,15 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
/* Set up the PS kernel (dispatched by WM) */
if (pMask) {
- if (pMaskPicture->componentAlpha)
- memcpy(ps_kernel, ps_kernel_static_maskca,
- sizeof (ps_kernel_static_maskca));
- else
+ if (pMaskPicture->componentAlpha &&
+ PICT_FORMAT_RGB(pMaskPicture->format)) {
+ if (i965_blend_op[op].src_alpha)
+ memcpy(ps_kernel, ps_kernel_static_maskca_srcalpha,
+ sizeof (ps_kernel_static_maskca_srcalpha));
+ else
+ memcpy(ps_kernel, ps_kernel_static_maskca,
+ sizeof (ps_kernel_static_maskca));
+ } else
memcpy(ps_kernel, ps_kernel_static_masknoca,
sizeof (ps_kernel_static_masknoca));
} else {
@@ -812,7 +825,6 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
wm_state->thread2.scratch_space_base_pointer = (state_base_offset +
wm_scratch_offset)>>10;
wm_state->thread2.per_thread_scratch_space = 0;
- // XXX: urb allocation
wm_state->thread3.const_urb_entry_read_length = 0;
wm_state->thread3.const_urb_entry_read_offset = 0;
/* Each pair of attributes (src/mask coords) is one URB entry */
@@ -948,44 +960,41 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture,
VB0_VERTEXDATA |
((4 * 2 * nelem) << VB0_BUFFER_PITCH_SHIFT));
OUT_RING(state_base_offset + vb_offset);
- OUT_RING(2); // max index, prim has 4 coords
+ OUT_RING(3);
OUT_RING(0); // ignore for VERTEXDATA, but still there
/* Set up our vertex elements, sourced from the single vertex buffer.
*/
OUT_RING(BRW_3DSTATE_VERTEX_ELEMENTS | ((2 * nelem) - 1));
- /* offset 0: X,Y -> {X, Y, 1.0, 1.0} */
OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
VE0_VALID |
(BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
(0 << VE0_OFFSET_SHIFT));
OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
(BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
- (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
- (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
+ (BRW_VFCOMPONENT_NOSTORE << VE1_VFCOMPONENT_2_SHIFT) |
+ (BRW_VFCOMPONENT_NOSTORE << VE1_VFCOMPONENT_3_SHIFT) |
(0 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
- /* offset 8: S0, T0 -> {S0, T0, 1.0, 1.0} */
- OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
- VE0_VALID |
- (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
- (8 << VE0_OFFSET_SHIFT));
- OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
- (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
- (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
- (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
- (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
-
if (pMask) {
OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
VE0_VALID |
(BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
- (16 << VE0_OFFSET_SHIFT));
+ (8 << VE0_OFFSET_SHIFT));
OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
(BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
- (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
- (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
- (8 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
+ (BRW_VFCOMPONENT_NOSTORE << VE1_VFCOMPONENT_2_SHIFT) |
+ (BRW_VFCOMPONENT_NOSTORE << VE1_VFCOMPONENT_3_SHIFT) |
+ (2 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
}
+ OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
+ VE0_VALID |
+ (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
+ ((pMask?16:8) << VE0_OFFSET_SHIFT)); /* offset vb in bytes */
+ OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
+ (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
+ (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
+ (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
+ (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); /* VUE offset in dwords */
ADVANCE_LP_RING();
}
diff --git a/src/ivch/Makefile.am b/src/ivch/Makefile.am
index fac074db..40e26277 100644
--- a/src/ivch/Makefile.am
+++ b/src/ivch/Makefile.am
@@ -3,7 +3,7 @@
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
-AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@
+AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes
ivch_la_LTLIBRARIES = ivch.la
ivch_la_LDFLAGS = -module -avoid-version
diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c
index 085b542a..71f41f58 100644
--- a/src/ivch/ivch.c
+++ b/src/ivch/ivch.c
@@ -35,7 +35,7 @@
#include "compiler.h"
#include "miscstruct.h"
#include "xf86i2c.h"
-#include "../i830_xf86Crtc.h"
+#include "xf86Crtc.h"
#define DPMS_SERVER
#include <X11/extensions/dpms.h>
diff --git a/src/reg_dumper/.gitignore b/src/reg_dumper/.gitignore
new file mode 100644
index 00000000..1b38d5c6
--- /dev/null
+++ b/src/reg_dumper/.gitignore
@@ -0,0 +1 @@
+intel_reg_dumper
diff --git a/src/reg_dumper/Makefile.am b/src/reg_dumper/Makefile.am
new file mode 100644
index 00000000..aee26d0e
--- /dev/null
+++ b/src/reg_dumper/Makefile.am
@@ -0,0 +1,12 @@
+noinst_PROGRAMS = intel_reg_dumper
+
+intel_reg_dumper_SOURCES = \
+ main.c \
+ reg_dumper.h \
+ xprintf.c \
+ ../i830_debug.c
+
+intel_reg_dumper_LDADD = $(PCIACCESS_LIBS)
+
+intel_reg_dumper_CFLAGS = $(PCIACCESS_CFLAGS) $(WARN_CFLAGS) \
+ -I$(srcdir)/.. -DREG_DUMPER
diff --git a/src/reg_dumper/main.c b/src/reg_dumper/main.c
new file mode 100644
index 00000000..50c79236
--- /dev/null
+++ b/src/reg_dumper/main.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <pciaccess.h>
+#include <err.h>
+
+#include "reg_dumper.h"
+
+int main(int argc, char **argv)
+{
+ struct pci_device *dev;
+ I830Rec i830;
+ ScrnInfoRec scrn;
+ int err, mmio_bar;
+
+ err = pci_system_init();
+ if (err != 0) {
+ fprintf(stderr, "Couldn't initialize PCI system: %s\n", strerror(err));
+ exit(1);
+ }
+
+ /* Grab the graphics card */
+ dev = pci_device_find_by_slot(0, 0, 2, 0);
+ if (dev == NULL)
+ errx(1, "Couldn't find graphics card");
+
+ if (dev->vendor_id != 0x8086)
+ errx(1, "Graphics card is non-intel");
+
+ err = pci_device_probe(dev);
+ if (err != 0) {
+ fprintf(stderr, "Couldn't probe graphics card: %s\n", strerror(err));
+ exit(1);
+ }
+
+ i830.PciInfo = &i830.pci_info_rec;
+ i830.PciInfo->chipType = dev->device_id;
+
+ i830.pci_dev = dev;
+
+ mmio_bar = IS_I9XX((&i830)) ? 0 : 1;
+
+ err = pci_device_map_region(dev, mmio_bar, 1);
+ if (err != 0) {
+ fprintf(stderr, "Couldn't map MMIO region: %s\n", strerror(err));
+ exit(1);
+ }
+ i830.mmio = i830.pci_dev->regions[mmio_bar].memory;
+
+ scrn.scrnIndex = 0;
+ scrn.pI830 = &i830;
+
+ i830DumpRegs(&scrn);
+
+ return 0;
+}
+
+void xf86DrvMsg(int scrnIndex, int severity, const char *format, ...)
+{
+ va_list va;
+
+ switch (severity) {
+ case X_INFO:
+ printf("(II): ");
+ break;
+ case X_WARNING:
+ printf("(WW): ");
+ break;
+ case X_ERROR:
+ printf("(EE): ");
+ break;
+ }
+
+ va_start(va, format);
+ vprintf(format, va);
+ va_end(va);
+}
diff --git a/src/reg_dumper/reg_dumper.h b/src/reg_dumper/reg_dumper.h
new file mode 100644
index 00000000..a52d6622
--- /dev/null
+++ b/src/reg_dumper/reg_dumper.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "common.h"
+
+/** @file
+ * This file defines the typedefs and stub structures necessary for us to
+ * use i830_debug.c mostly unmodified.
+ */
+
+typedef uint32_t CARD32;
+typedef char Bool;
+
+#define FALSE 0
+#define TRUE 1
+
+#define X_INFO 0
+#define X_WARNING 1
+#define X_ERROR 2
+
+struct pci_info_rec {
+ uint16_t chipType;
+};
+
+typedef struct _i830 {
+ /* Fields in common with the real pI830 */
+ struct pci_info_rec *PciInfo;
+
+ /* Fields used for setting up reg_dumper */
+ struct pci_device *pci_dev;
+ struct pci_info_rec pci_info_rec;
+ volatile unsigned char *mmio;
+} I830Rec, *I830Ptr;
+
+typedef struct _scrn {
+ /* Fields in common with the real pScrn */
+ int scrnIndex;
+
+ /* Fields used for setting up reg_dumper */
+ I830Ptr pI830;
+} ScrnInfoRec, *ScrnInfoPtr;
+
+#define I830PTR(pScrn) (pScrn->pI830)
+
+#define INREG8(reg) (*(volatile uint8_t *)((pI830)->mmio + (reg)))
+#define INREG16(reg) (*(volatile uint16_t *)((pI830)->mmio + (reg)))
+#define INREG(reg) (*(volatile uint32_t *)((pI830)->mmio + (reg)))
+#define OUTREG8(reg, val) \
+ *(volatile uint8_t *)((pI830)->mmio + (reg)) = (val)
+#define OUTREG16(reg, val) \
+ *(volatile uint16_t *)((pI830)->mmio + (reg)) = (val)
+#define OUTREG(reg, val) \
+ *(volatile uint32_t *)((pI830)->mmio + (reg)) = (val)
+
+#define xalloc malloc
+#define xfree free
+#define ErrorF printf
+
+char *XNFprintf(const char *format, ...);
+void xf86DrvMsg(int scrnIndex, int severity, const char *format, ...);
+void i830DumpRegs(ScrnInfoPtr pScrn);
diff --git a/src/reg_dumper/xprintf.c b/src/reg_dumper/xprintf.c
new file mode 100644
index 00000000..125ae870
--- /dev/null
+++ b/src/reg_dumper/xprintf.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2004 Alexander Gottwald
+ *
+ * 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 ABOVE LISTED 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.
+ *
+ * Except as contained in this notice, the name(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the sale,
+ * use or other dealings in this Software without prior written authorization.
+ */
+
+#include <string.h>
+#include <stdarg.h>
+#include "reg_dumper.h"
+
+static char *
+XNFvprintf(const char *format, va_list va)
+{
+ char *ret;
+ int size;
+ va_list va2;
+
+ va_copy(va2, va);
+ size = vsnprintf(NULL, 0, format, va2);
+ va_end(va2);
+
+ ret = (char *)malloc(size + 1);
+ if (ret == NULL)
+ return NULL;
+
+ vsnprintf(ret, size + 1, format, va);
+ ret[size] = 0;
+ return ret;
+}
+
+char *
+XNFprintf(const char *format, ...)
+{
+ char *ret;
+ va_list va;
+ va_start(va, format);
+ ret = XNFvprintf(format, va);
+ va_end(va);
+ return ret;
+}
diff --git a/src/sil164/Makefile.am b/src/sil164/Makefile.am
index 927f5a77..4cf717c4 100644
--- a/src/sil164/Makefile.am
+++ b/src/sil164/Makefile.am
@@ -3,7 +3,7 @@
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
-AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/../
+AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes
sil164_la_LTLIBRARIES = sil164.la
sil164_la_LDFLAGS = -module -avoid-version
diff --git a/src/sil164/sil164.c b/src/sil164/sil164.c
index 453ed044..80b1b6a8 100644
--- a/src/sil164/sil164.c
+++ b/src/sil164/sil164.c
@@ -37,7 +37,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "compiler.h"
#include "miscstruct.h"
#include "xf86i2c.h"
-#include "i830_xf86Crtc.h"
+#include "xf86Crtc.h"
#define DPMS_SERVER
#include <X11/extensions/dpms.h>