Blob Blame History Raw
commit abbafe6db7c0d24efc61a05950d4214c00d3f043
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Thu Oct 4 11:33:09 2007 +0200

    radeon: Fix compile warnings.

commit 1110957ba703475847b8e72023c6edcbd1068aef
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Thu Oct 4 11:32:48 2007 +0200

    radeon: Fix for pci-rework.
    
    Surprisingly easy, thanks to George's pci-rework changes.

commit 7addf41885ec5658f531624a9c24ea5bd7d22d19
Merge: 3a958ba... 78c6bd3...
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Thu Oct 4 11:06:08 2007 +0200

    Merge remote branch 'origin/pci-rework'

commit 3a958ba136c3fae5a4ddd56373ac7cd47046f10e
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Oct 3 22:59:14 2007 -0400

    RADEON: remove some cruft

commit b6bda79f72df5e5bf9c6b71fa3298e765da506bd
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Oct 3 22:56:27 2007 -0400

    RADEON: more fixes for single crtc chips

commit 5f5c4e6ad61c45c24f1443b91b4bc5375efdebc0
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Oct 3 22:46:21 2007 -0400

    RADEON: remove RADEONSaveMode()
    
    It's only called by RADEONSave(), so just move its
    contents into RADEONSave().  this mirrors RADEONRestore().

commit bfede412b3a3cd11769a580b167c528734146096
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Oct 3 22:19:16 2007 -0400

    RADEON: minor fixes for external TMDS

commit 597dffce9bdc200003d0be880235258386a0bdd7
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Oct 3 21:43:08 2007 -0400

    RADEON: final fix for RMX/LVDS
    
    It seems that on quite a few laptops the LVDS H/V timing
    from the bios tables are way off or just doesn't work period.
    Either we are using it wrong or we need some additional checks
    when we parse it. Only the dot clock seems to really matter,
    so use cvt modes and update the dotclock.  This seems to work
    correctly in all cases.

commit cc0c2d8e61600652b1f9cb3dc49db2ef62b1e40d
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Wed Oct 3 00:59:37 2007 -0400

    RADEON: Finally sort out LVDS modes
    
    - The panel timing from the bios tables is for the crtc,
    not the native panel mode, so add cvt modes for the panel
    and fix up the crtc values in mode_fixup().
    - rename and reconfigure RADEONValidateFPModes() to what it
    really does: add screen modes.  I suppose for backwards
    compatibility we ought to add the screen modes to every
    reasonable output, but everyone should really use xrandr
    or an output monitor section to add custom modes.  Hopefully
    this will go away at some point.

commit 0ca184c3c35032df39ea7ce5d2d4aba1a97b6426
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Oct 2 19:38:18 2007 -0400

    RADEON: fix RADEONInitDispBandwidth() on single crtc cards
    
    Should fix bug 12490

commit a5fb2a5d54cdd562a97881cdea1a4af35b483aab
Author: Dave Airlie <airlied@linux.ie>
Date:   Mon Oct 1 08:48:27 2007 +1000

    radeon: fix powerpc build

commit 22519fde1e002f28d6036d448fcd18452d00f1bb
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sun Sep 30 13:11:20 2007 -0400

    RADEON: add support for ext tmds table and ext tmds chip init
    
    This probably won't work on all chips as the various gpio lines
    seem to need special magic to to actually talk to the i2c slave
    chips.

commit dcc376e2d2a13329dd03f1bc4b471329757a6f5f
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Sep 26 23:27:38 2007 -0400

    RADEON: remove cruft

commit 99ceaefa18c6e07b55106cca0ea8996fa73667be
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Sun Sep 30 12:02:54 2007 -0400

    RADEON: more work on LVDS mode validation and fixups
    
    Hopefully this will fix up the weird mode issues with LVDS and
    native and RMX modes, but I can't seem to get quite the right
    combo to fix everyone.

commit d808781d48adf01e80b5bb476bae2d2f599030f1
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Sep 28 14:50:42 2007 +1000

    rc410: disable DRI by default due to it not working

commit 4d9f944e40c6b9ac7e80428dff49c6e83fda1d8f
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Thu Sep 27 17:50:15 2007 +0200

    radeon: Fix build on little endian platforms.
    
    This was accidentally broken when moving away from using pixmap data pointers
    directly.

commit 5902e913010a2fb0c17efe01f9aade73f9646f16
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Thu Sep 27 12:53:34 2007 +0200

    radeon: EXA pitch fixes.
    
    The combined pitch/offset registers only support pitches up to 16320 bytes.
    
    With EXA >= 2.3, set the maxPitchBytes field accordingly. With older versions,
    limit maxX such that the pitch of 32bpp pixmaps doesn't exceed the limit.
    
    Also check the limit in RADEONGetOffsetPitch just in case.
    
    Fixes https://bugs.freedesktop.org/show_bug.cgi?id=12551 .

commit ca728973bce504e03bf6228d18287906c35eaa3f
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Thu Sep 27 11:14:21 2007 +0200

    radeon: Don't use pixmap data pointer directly with EXA.
    
    Fixes segfault with current xserver master without AccelDFS.

commit 21593d04d222b05dbba9abd31eaa3bfb91d999b6
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Mon Sep 24 23:01:20 2007 -0400

    RADEON: more clean up of mode code
    
    also print out LVDS mode info from bios for both
    legacy and atom bioses

commit 78c6bd305f2ea70629d1dda3c0c48c067451f5fb
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Mon Sep 10 19:00:16 2007 +0300

    [mach64] Revert to multiple mappings per BAR.
    
    libpciaccess added subrange mappings and mtrr handling.
    
    compile-tested only.

commit 6ff0645ecfe65727e8ef5d5e6215b4e03078e1a5
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Tue Aug 28 15:37:11 2007 +0300

    [mach64] Convert to pci-rework, keeping source-code compatibility.
    
    It still uses the old probe method though, this is due to the ati wrapper.

commit 7b38d9a1209f87255e5bb0aefe46a363ce4fb6ef
Merge: 2e3d43a... 673f799...
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Tue Aug 28 16:01:12 2007 +0300

    Merge branch 'master' into pci-rework
    
    Conflicts:
    
    	src/ati.c

commit 2e3d43af1e5077cc61dd8668551a6291368d9ed2
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Mon Mar 19 19:05:04 2007 +0200

    [mach64] Compute MMIO address once for each case (PIO, MMIO).
    
    For an MMIO-only driver, the extra MMIO address probing is not needed since we
    already compute the MMIO address during probe and do not make any BIOS calls.
    
    For a PIO driver, this extra probing could even result in a wrong MMIO address
    since the checking is done by reading through PIO, not MMIO. The MMIO address
    is later corrected but having the extra probe there is useless.

commit e7defc0e930f1b2d83623a769b2bfdb05c66a5fe
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Mon Mar 19 19:04:10 2007 +0200

    [mach64] Move setting of PIO and MMIO addresses up, after BIOS init.
    
    Partially revert "Minor refactoring of pATI->Block0Base computation."
    
    This parially reverts commit 2c8b33b761e4411451aea1eea3a89d629aeea40d.

commit 3dfdba195f1ff794ab00585ab80e7ea6ac92fcf4
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Sun Mar 18 16:40:07 2007 +0200

    [mach64] Make mapping code friendlier to pci-rework source-code compatibility.

commit 321db6d87c9110654ab386e5ec270116eca1e04f
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Sun Mar 18 16:15:20 2007 +0200

    [mach64] Add macros for pci-rework source-code compatibilty.

commit dfd07b6e99020d1db43d7ce0cae4423d8c6b1f05
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Sun Mar 18 16:38:26 2007 +0200

    [mach64] Drop checking that BAR base + size fits in 32 bit.
    
    I can't see how these tests could fail on 32-bit. OTOH they are potentially
    problematic with 64-bit PCI addresses.

commit e674338a98c50800637b8ebc01adf3aec2a3eb38
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Sun Mar 18 15:50:41 2007 +0200

    [mach64] Single mapping per BAR.
    
    - We reset write-combining of the FB when MMIO registers fall in the linear
      aperture.
    
    - We set MMIOInLinear in all three aperture mappings since the mapping code
      depends on it.
    
    - We map the linear aperture in its entirety for MMIOInLinear also.
      This simplifies mapping of HW cursor and the LE aperture on BE archs, as
      they always fall in the linear aperture.
    
    - I assumed that BAR[2] is page-aligned (we know it's 4K-aligned for sure).

commit e7969de8ec572d8801806f9525a9a081a58a03f1
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Sun Mar 18 15:35:25 2007 +0200

    [mach64] Drop poking the VGA MMIO aperture.
    
    We will not be able to handle this when we do mappings for PCI BARs only and
    it should be handled with a CPIO driver anyway.
diff --git a/configure.ac b/configure.ac
index 7204a31..c662168 100644
--- a/configure.ac
+++ b/configure.ac
@@ -204,10 +204,20 @@ AC_CHECK_DECL(xf86XVFillKeyHelperDrawable,
 	      [],
 	      [#include <xf86xv.h>])
 
+AC_CHECK_DECL(XSERVER_LIBPCIACCESS,
+	      [XSERVER_LIBPCIACCESS=yes],[XSERVER_LIBPCIACCESS=no],
+	      [#include "xorg-server.h"])
+
 CPPFLAGS="$SAVE_CPPFLAGS"
 
 AM_CONDITIONAL(USE_EXA, test "x$USE_EXA" = xyes)
 
+if test "x$XSERVER_LIBPCIACCESS" = xyes; then
+    PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.8.0])
+    XORG_CFLAGS="$XORG_CFLAGS $PCIACCESS_CFLAGS"
+fi
+AM_CONDITIONAL(XSERVER_LIBPCIACCESS, test "x$XSERVER_LIBPCIACCESS" = xyes)
+
 AC_SUBST([XORG_CFLAGS])
 AC_SUBST([DRI_CFLAGS])
 AC_SUBST([moduledir])
diff --git a/src/Makefile.am b/src/Makefile.am
index 709b98c..1eea432 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -66,13 +66,6 @@ atimisc_drv_la_SOURCES = \
 	atiload.c atimisc.c atimach64probe.c $(ATIMISC_CPIO_SOURCES) \
 	$(ATIMISC_DGA_SOURCES) $(ATIMISC_DRI_SRCS) $(ATIMISC_EXA_SOURCES)
 
-r128_drv_la_LTLIBRARIES = r128_drv.la
-r128_drv_la_LDFLAGS = -module -avoid-version
-r128_drv_ladir = @moduledir@/drivers
-r128_drv_la_SOURCES = \
-	r128_accel.c r128_cursor.c r128_dga.c r128_driver.c \
-	r128_video.c r128_misc.c r128_probe.c $(R128_DRI_SRCS)
-
 radeon_drv_la_LTLIBRARIES = radeon_drv.la
 radeon_drv_la_LDFLAGS = -module -avoid-version
 radeon_drv_ladir = @moduledir@/drivers
@@ -83,6 +76,16 @@ radeon_drv_la_SOURCES = \
 	radeon_crtc.c radeon_output.c radeon_modes.c radeon_tv.c \
 	$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
 
+if XSERVER_LIBPCIACCESS
+# r128 and theatre have not been ported yet
+else
+r128_drv_la_LTLIBRARIES = r128_drv.la
+r128_drv_la_LDFLAGS = -module -avoid-version
+r128_drv_ladir = @moduledir@/drivers
+r128_drv_la_SOURCES = \
+	r128_accel.c r128_cursor.c r128_dga.c r128_driver.c \
+	r128_video.c r128_misc.c r128_probe.c $(R128_DRI_SRCS)
+
 theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la
 theatre_detect_drv_la_LDFLAGS = -module -avoid-version
 theatre_detect_drv_ladir = @moduledir@/multimedia
@@ -103,6 +106,7 @@ theatre200_drv_la_CFLAGS = \
 	$(AM_CFLAGS) -DMICROC_DIR=\"$(theatre200_drv_ladir)\"
 theatre200_drv_la_SOURCES = \
 	theatre200.c theatre200_module.c
+endif
 
 EXTRA_DIST = \
 	atimach64render.c \
@@ -186,4 +190,5 @@ EXTRA_DIST = \
 	theatre_detect.h \
 	theatre.h \
 	theatre_reg.h \
-	atipciids.h
+	atipciids.h \
+	atipcirename.h
diff --git a/src/ati.c b/src/ati.c
index 423fd95..ada165f 100644
--- a/src/ati.c
+++ b/src/ati.c
@@ -57,6 +57,11 @@
 #include "config.h"
 #endif
 
+#ifdef XSERVER_LIBPCIACCESS
+#include <pciaccess.h>
+#endif
+#include "atipcirename.h"
+
 #include "ati.h"
 #include "atimodule.h"
 #include "ativersion.h"
@@ -65,6 +70,22 @@
 #include "radeon_probe.h"
 #include "r128_probe.h"
 
+#ifdef XSERVER_LIBPCIACCESS
+static const struct pci_id_match ati_device_match = {
+    PCI_VENDOR_ATI, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0
+};
+
+/* Stolen from xf86pciBus.c */
+/* PCI classes that get included in xf86PciVideoInfo */
+#define PCIINFOCLASSES(c) \
+    (  (((c) & 0x00ff0000) == (PCI_CLASS_PREHISTORIC << 16)) ||           \
+       (((c) & 0x00ff0000) == (PCI_CLASS_DISPLAY << 16)) ||               \
+      ((((c) & 0x00ffff00) == ((PCI_CLASS_MULTIMEDIA << 16) |             \
+                               (PCI_SUBCLASS_MULTIMEDIA_VIDEO << 8)))) || \
+      ((((c) & 0x00ffff00) == ((PCI_CLASS_PROCESSOR << 16) |              \
+                               (PCI_SUBCLASS_PROCESSOR_COPROC << 8)))) )
+#endif
+
 /*
  * ATIIdentify --
  *
@@ -99,11 +120,17 @@ ATIProbe
 )
 {
     pciVideoPtr pVideo;
+#ifndef XSERVER_LIBPCIACCESS
     pciVideoPtr *xf86PciVideoInfo;
+#else
+    struct pci_device_iterator *pVideoIter;
+#endif
     Bool        DoMach64 = FALSE;
     Bool        DoRage128 = FALSE, DoRadeon = FALSE;
     ATIChipType Chip;
 
+#ifndef XSERVER_LIBPCIACCESS
+
     xf86PciVideoInfo = xf86GetPciVideoInfo();
 
     if (xf86PciVideoInfo == NULL)
@@ -111,12 +138,37 @@ ATIProbe
 
     while ((pVideo = *xf86PciVideoInfo++) != NULL)
     {
-        if ((pVideo->vendor != PCI_VENDOR_ATI) ||
-            (pVideo->chipType == PCI_CHIP_MACH32))
+        if ((PCI_DEV_VENDOR_ID(pVideo) != PCI_VENDOR_ATI) ||
+            (PCI_DEV_DEVICE_ID(pVideo) == PCI_CHIP_MACH32))
+            continue;
+
+        /* Check for Rage128's, Radeon's and later adapters */
+        Chip = ATIChipID(PCI_DEV_DEVICE_ID(pVideo), PCI_DEV_REVISION(pVideo));
+        if (Chip <= ATI_CHIP_Mach64)
+            DoMach64 = TRUE;
+        else if (Chip <= ATI_CHIP_Rage128)
+            DoRage128 = TRUE;
+        else if (Chip <= ATI_CHIP_Radeon)
+            DoRadeon = TRUE;
+    }
+
+#else /* XSERVER_LIBPCIACCESS */
+
+    pVideoIter = pci_id_match_iterator_create(&ati_device_match);
+
+    while ((pVideo = pci_device_next(pVideoIter)) != NULL)
+    {
+        /* Check for non-video devices */
+        if (!PCIINFOCLASSES(pVideo->device_class))
+            continue;
+
+        /* Check for prehistoric PCI Mach32 */
+        if ((PCI_DEV_VENDOR_ID(pVideo) != PCI_VENDOR_ATI) ||
+            (PCI_DEV_DEVICE_ID(pVideo) == PCI_CHIP_MACH32))
             continue;
 
         /* Check for Rage128's, Radeon's and later adapters */
-        Chip = ATIChipID(pVideo->chipType, pVideo->chipRev);
+        Chip = ATIChipID(PCI_DEV_DEVICE_ID(pVideo), PCI_DEV_REVISION(pVideo));
         if (Chip <= ATI_CHIP_Mach64)
             DoMach64 = TRUE;
         else if (Chip <= ATI_CHIP_Rage128)
@@ -125,6 +177,10 @@ ATIProbe
             DoRadeon = TRUE;
     }
 
+    pci_iterator_destroy(pVideoIter);
+
+#endif /* XSERVER_LIBPCIACCESS */
+
     /* Call Radeon driver probe */
     if (DoRadeon)
     {
diff --git a/src/atidri.c b/src/atidri.c
index 07adda7..bc862a8 100644
--- a/src/atidri.c
+++ b/src/atidri.c
@@ -774,8 +774,8 @@ static Bool ATIDRISetAgpMode( ScreenPtr pScreen )
    xf86DrvMsg( pScreen->myNum, X_INFO,
 	       "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
 	       mode, vendor, device,
-	       pATI->PCIInfo->vendor,
-	       pATI->PCIInfo->chipType );
+	       PCI_DEV_VENDOR_ID(pATI->PCIInfo),
+	       PCI_DEV_DEVICE_ID(pATI->PCIInfo) );
 
    if ( drmAgpEnable( pATI->drmFD, mode ) < 0 ) {
       xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n" );
@@ -1134,18 +1134,15 @@ static Bool ATIDRIIrqInit( ScreenPtr pScreen )
 
    if ( pATI->irq <= 0 ) {
       pATI->irq = drmGetInterruptFromBusID(pATI->drmFD,
-					   ((pciConfigPtr)pATI->PCIInfo
-					    ->thisCard)->busnum,
-					   ((pciConfigPtr)pATI->PCIInfo
-					    ->thisCard)->devnum,
-					   ((pciConfigPtr)pATI->PCIInfo
-					    ->thisCard)->funcnum);
+					   PCI_CFG_BUS(pATI->PCIInfo),
+					   PCI_CFG_DEV(pATI->PCIInfo),
+					   PCI_CFG_FUNC(pATI->PCIInfo));
       if ( pATI->irq <= 0 ) {
 	 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
 		    "[drm] Couldn't find IRQ for bus id %d:%d:%d\n",
-		    ((pciConfigPtr)pATI->PCIInfo->thisCard)->busnum,
-		    ((pciConfigPtr)pATI->PCIInfo->thisCard)->devnum,
-		    ((pciConfigPtr)pATI->PCIInfo->thisCard)->funcnum);
+		    PCI_CFG_BUS(pATI->PCIInfo),
+		    PCI_CFG_DEV(pATI->PCIInfo),
+		    PCI_CFG_FUNC(pATI->PCIInfo));
 	 pATI->irq = 0;
       } else if ((drmCtlInstHandler(pATI->drmFD, pATI->irq)) != 0) {
  	 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
@@ -1243,9 +1240,9 @@ Bool ATIDRIScreenInit( ScreenPtr pScreen )
       pDRIInfo->busIdString = xalloc( 64 );
       sprintf( pDRIInfo->busIdString,
 	       "PCI:%d:%d:%d",
-	       pATI->PCIInfo->bus,
-	       pATI->PCIInfo->device,
-	       pATI->PCIInfo->func );
+	       PCI_DEV_BUS(pATI->PCIInfo),
+	       PCI_DEV_DEV(pATI->PCIInfo),
+	       PCI_DEV_FUNC(pATI->PCIInfo) );
    }
    pDRIInfo->ddxDriverMajorVersion = ATI_VERSION_MAJOR;
    pDRIInfo->ddxDriverMinorVersion = ATI_VERSION_MINOR;
diff --git a/src/atimach64probe.c b/src/atimach64probe.c
index c5330cc..2f716a1 100644
--- a/src/atimach64probe.c
+++ b/src/atimach64probe.c
@@ -146,8 +146,10 @@ Mach64Probe(DriverPtr pDriver, int flags)
     int     numUsed;
     Bool    ProbeSuccess = FALSE;
 
+#ifndef XSERVER_LIBPCIACCESS
     if (xf86GetPciVideoInfo() == NULL)
         return FALSE;
+#endif
 
     if ((numDevSections = xf86MatchDevice(ATI_DRIVER_NAME, &devSections)) <= 0)
         return FALSE;
diff --git a/src/atipcirename.h b/src/atipcirename.h
new file mode 100644
index 0000000..5aa6b80
--- /dev/null
+++ b/src/atipcirename.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2007 George Sapountzis
+ *
+ * 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.
+ */
+
+/**
+ * Macros for porting drivers from legacy xfree86 PCI code to the pciaccess
+ * library. The main purpose being to facilitate source code compatibility.
+ */
+
+#ifndef ATIPCIRENAME_H
+#define ATIPCIRENAME_H
+
+enum region_type {
+    REGION_MEM,
+    REGION_IO 
+};
+
+#ifndef XSERVER_LIBPCIACCESS
+
+/* pciVideoPtr */
+#define PCI_DEV_VENDOR_ID(_pcidev) ((_pcidev)->vendor)
+#define PCI_DEV_DEVICE_ID(_pcidev) ((_pcidev)->chipType)
+#define PCI_DEV_REVISION(_pcidev)  ((_pcidev)->chipRev)
+
+#define PCI_SUB_VENDOR_ID(_pcidev) ((_pcidev)->subsysVendor)
+#define PCI_SUB_DEVICE_ID(_pcidev) ((_pcidev)->subsysCard)
+
+#define PCI_DEV_TAG(_pcidev) pciTag((_pcidev)->bus,    \
+                                    (_pcidev)->device, \
+                                    (_pcidev)->func)
+#define PCI_DEV_BUS(_pcidev)       ((_pcidev)->bus)
+#define PCI_DEV_DEV(_pcidev)       ((_pcidev)->device)
+#define PCI_DEV_FUNC(_pcidev)      ((_pcidev)->func)
+
+/* pciConfigPtr */
+#define PCI_CFG_TAG(_pcidev)  (((pciConfigPtr)(_pcidev)->thisCard)->tag)
+#define PCI_CFG_BUS(_pcidev)  (((pciConfigPtr)(_pcidev)->thisCard)->busnum)
+#define PCI_CFG_DEV(_pcidev)  (((pciConfigPtr)(_pcidev)->thisCard)->devnum)
+#define PCI_CFG_FUNC(_pcidev) (((pciConfigPtr)(_pcidev)->thisCard)->funcnum)
+
+/* region addr: xfree86 uses different fields for memory regions and I/O ports */
+#define PCI_REGION_BASE(_pcidev, _b, _type)             \
+    (((_type) == REGION_MEM) ? (_pcidev)->memBase[(_b)] \
+                             : (_pcidev)->ioBase[(_b)])
+
+/* region size: xfree86 uses the log2 of the region size,
+ * but with zero meaning no region, not size of one XXX */
+#define PCI_REGION_SIZE(_pcidev, _b) \
+    (((_pcidev)->size[(_b)] > 0) ? (1 << (_pcidev)->size[(_b)]) : 0)
+
+/* read/write PCI configuration space */
+#define PCI_READ_BYTE(_pcidev, _value_ptr, _offset) \
+    *(_value_ptr) = pciReadByte(PCI_CFG_TAG(_pcidev), (_offset))
+
+#define PCI_READ_LONG(_pcidev, _value_ptr, _offset) \
+    *(_value_ptr) = pciReadLong(PCI_CFG_TAG(_pcidev), (_offset))
+
+#define PCI_WRITE_LONG(_pcidev, _value, _offset) \
+    pciWriteLong(PCI_CFG_TAG(_pcidev), (_offset), (_value))
+
+#else /* XSERVER_LIBPCIACCESS */
+
+typedef struct pci_device *pciVideoPtr;
+
+#define PCI_DEV_VENDOR_ID(_pcidev) ((_pcidev)->vendor_id)
+#define PCI_DEV_DEVICE_ID(_pcidev) ((_pcidev)->device_id)
+#define PCI_DEV_REVISION(_pcidev)  ((_pcidev)->revision)
+
+#define PCI_SUB_VENDOR_ID(_pcidev) ((_pcidev)->subvendor_id)
+#define PCI_SUB_DEVICE_ID(_pcidev) ((_pcidev)->subdevice_id)
+
+/* pci-rework functions take a 'pci_device' parameter instead of a tag */
+#define PCI_DEV_TAG(_pcidev)        (_pcidev)
+
+/* PCI_DEV macros, typically used in printf's, add domain ? XXX */
+#define PCI_DEV_BUS(_pcidev)       ((_pcidev)->bus)
+#define PCI_DEV_DEV(_pcidev)       ((_pcidev)->dev)
+#define PCI_DEV_FUNC(_pcidev)      ((_pcidev)->func)
+
+/* pci-rework functions take a 'pci_device' parameter instead of a tag */
+#define PCI_CFG_TAG(_pcidev)        (_pcidev)
+
+/* PCI_CFG macros, typically used in DRI init, contain the domain */
+#define PCI_CFG_BUS(_pcidev)      (((_pcidev)->domain << 8) | \
+                                    (_pcidev)->bus)
+#define PCI_CFG_DEV(_pcidev)       ((_pcidev)->dev)
+#define PCI_CFG_FUNC(_pcidev)      ((_pcidev)->func)
+
+#define PCI_REGION_BASE(_pcidev, _b, _type) ((_pcidev)->regions[(_b)].base_addr)
+#define PCI_REGION_SIZE(_pcidev, _b)        ((_pcidev)->regions[(_b)].size)
+
+#define PCI_READ_BYTE(_pcidev, _value_ptr, _offset) \
+    pci_device_cfg_read_u8((_pcidev), (_value_ptr), (_offset))
+
+#define PCI_READ_LONG(_pcidev, _value_ptr, _offset) \
+    pci_device_cfg_read_u32((_pcidev), (_value_ptr), (_offset))
+
+#define PCI_WRITE_LONG(_pcidev, _value, _offset) \
+    pci_device_cfg_write_u32((_pcidev), (_value), (_offset))
+
+#endif /* XSERVER_LIBPCIACCESS */
+
+#endif /* ATIPCIRENAME_H */
diff --git a/src/atipreinit.c b/src/atipreinit.c
index d960e88..8114f51 100644
--- a/src/atipreinit.c
+++ b/src/atipreinit.c
@@ -101,24 +101,6 @@ static const rgb   defaultWeight = {0, 0, 0};
 static const Gamma defaultGamma  = {0.0, 0.0, 0.0};
 
 /*
- * ATIMach64Map --
- *
- * This function attempts to mmap() a Mach64's MMIO aperture.
- */
-static void
-ATIMach64Map
-(
-    int    iScreen,
-    ATIPtr pATI
-)
-{
-    (void)ATIMapApertures(iScreen, pATI);
-    if (!pATI->pBlock[0] ||
-        (pATI->config_chip_id != inr(CONFIG_CHIP_ID)))
-        ATIUnmapApertures(iScreen, pATI);
-}
-
-/*
  * ATIPrintNoiseIfRequested --
  *
  * This function formats debugging information on the server's stderr when
@@ -175,7 +157,6 @@ ATIPreInit
     resPtr           pResources;
     pciVideoPtr      pVideo;
     DisplayModePtr   pMode;
-    unsigned long    Block0Base;
     CARD32           IOValue;
     int              i, j;
     int              Numerator, Denominator;
@@ -402,6 +383,24 @@ ATIPreInit
         return TRUE;
     }
 
+#ifndef AVOID_CPIO
+
+    /* I/O bases might no longer be valid after BIOS initialisation */
+    {
+        if (pATI->CPIODecoding == BLOCK_IO)
+            pATI->CPIOBase = PCI_REGION_BASE(pVideo, 1, REGION_IO);
+
+        pATI->MMIOInLinear = FALSE;
+
+        /* Set MMIO address from PCI configuration space, if available */
+        if ((pATI->Block0Base = PCI_REGION_BASE(pVideo, 2, REGION_MEM)))
+        {
+            pATI->Block0Base += 0x0400U;
+        }
+    }
+
+#endif /* AVOID_CPIO */
+
 #ifdef AVOID_CPIO
 
     pScreenInfo->racMemFlags =
@@ -424,51 +423,17 @@ ATIPreInit
 
     /* Finish probing the adapter */
     {
-
-        if (pATI->CPIODecoding == BLOCK_IO)
-            pATI->CPIOBase = pVideo->ioBase[1];
-
-        /* Set MMIO address from PCI configuration space, if available */
-        if ((pATI->Block0Base = pVideo->memBase[2]))
-        {
-            if (pATI->Block0Base >= (CARD32)(-1 << pVideo->size[2]))
-                pATI->Block0Base = 0;
-            else
-                pATI->Block0Base += 0x0400U;
-        }
-
-            Block0Base = pATI->Block0Base; /* save */
-
-            do
-            {
-                /*
-                 * Find and mmap() MMIO area.  Allow only auxiliary aperture if
-                 * it exists.
-                 */
-                if (!pATI->Block0Base)
-                {
-                        /* Check tail end of linear (8MB or 4MB) aperture */
-                        if ((pATI->Block0Base = pVideo->memBase[0]))
-                        {
-                            pATI->Block0Base += 0x007FFC00U;
-                            ATIMach64Map(pScreenInfo->scrnIndex, pATI);
-                            if (pATI->pBlock[0])
-                                break;
-
-                            pATI->Block0Base -= 0x00400000U;
-                            ATIMach64Map(pScreenInfo->scrnIndex, pATI);
-                            if (pATI->pBlock[0])
-                                break;
-                        }
-
-                    /* Check VGA MMIO aperture */
-                    pATI->Block0Base = 0x000BFC00U;
-                }
-
-                ATIMach64Map(pScreenInfo->scrnIndex, pATI);
-            } while (0);
-
-            pATI->Block0Base = Block0Base; /* restore */
+        /*
+         * For MMIO register access, the MMIO address is computed when probing
+         * and there are no BIOS calls. This mapping should always succeed.
+         *
+         * For CPIO register access, the MMIO address is computed above in the
+         * presence of an auxiliary aperture. Otherwise, it is set to zero and
+         * gets computed when we read the linear aperture configuration. This
+         * mapping is either irrelevant or a no-op.
+         */
+        if (!ATIMapApertures(pScreenInfo->scrnIndex, pATI))
+            return FALSE;
 
 #ifdef AVOID_CPIO
 
@@ -481,15 +446,25 @@ ATIPreInit
 
 #endif /* AVOID_CPIO */
 
+            /*
+             * Verify register access by comparing against the CONFIG_CHIP_ID
+             * value saved by adapter detection.
+             */
+            if (pATI->config_chip_id != inr(CONFIG_CHIP_ID))
+            {
+                xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+                    "Adapter registers not mapped correctly.\n");
+                ATIUnmapApertures(pScreenInfo->scrnIndex, pATI);
+                return FALSE;
+            }
+
             pATIHW->crtc_gen_cntl = inr(CRTC_GEN_CNTL);
             if (!(pATIHW->crtc_gen_cntl & CRTC_EN) &&
                 (pATI->Chip >= ATI_CHIP_264CT))
             {
                 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
                     "Adapter has not been initialised.\n");
-                ATIPrintNoiseIfRequested(pATI, BIOS, BIOSSize);
-                ATIUnmapApertures(pScreenInfo->scrnIndex, pATI);
-                return FALSE;
+                goto bail_locked;
             }
 
 #ifdef AVOID_CPIO
@@ -499,9 +474,7 @@ ATIPreInit
                 xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
                     "Adapters found to be in VGA mode on server entry are not"
                     " supported by the MMIO-only version of this driver.\n");
-                ATIPrintNoiseIfRequested(pATI, BIOS, BIOSSize);
-                ATIUnmapApertures(pScreenInfo->scrnIndex, pATI);
-                return FALSE;
+                goto bail_locked;
             }
 
 #endif /* AVOID_CPIO */
@@ -1809,8 +1782,9 @@ ATIPreInit
 
             if (pATI->LinearBase && pATI->LinearSize)
             {
-                int AcceleratorVideoRAM = pATI->LinearSize >> 10;
-                int ServerVideoRAM = pATI->VideoRAM;
+                int AcceleratorVideoRAM = 0, ServerVideoRAM;
+
+#ifndef AVOID_CPIO
 
                 /*
                  * Unless specified in PCI configuration space, set MMIO
@@ -1823,6 +1797,10 @@ ATIPreInit
                     pATI->MMIOInLinear = TRUE;
                 }
 
+#endif /* AVOID_CPIO */
+
+                AcceleratorVideoRAM = pATI->LinearSize >> 10;
+
                 /*
                  * Account for MMIO area at the tail end of the linear
                  * aperture, if it is needed or if it cannot be disabled.
@@ -1830,6 +1808,8 @@ ATIPreInit
                 if (pATI->MMIOInLinear || (pATI->Chip < ATI_CHIP_264VTB))
                     AcceleratorVideoRAM -= 2;
 
+                ServerVideoRAM = pATI->VideoRAM;
+
                 if (pATI->Cursor > ATI_CURSOR_SOFTWARE)
                 {
                     /*
@@ -2475,6 +2455,8 @@ ATIPreInit
 
 bail:
     ATILock(pATI);
+
+bail_locked:
     ATIPrintNoiseIfRequested(pATI, BIOS, BIOSSize);
     ATIUnmapApertures(pScreenInfo->scrnIndex, pATI);
 
diff --git a/src/atiprint.c b/src/atiprint.c
index d435e21..60d9c21 100644
--- a/src/atiprint.c
+++ b/src/atiprint.c
@@ -355,8 +355,6 @@ ATIPrintRegisters
     ATIPtr pATI
 )
 {
-    pciVideoPtr  pVideo = pATI->PCIInfo;
-    pciConfigPtr pPCI = pVideo->thisCard;
     int          Index;
     CARD32       lcd_index, tv_out_index, lcd_gen_ctrl;
     CARD8        dac_read, dac_mask, dac_write;
@@ -642,10 +640,14 @@ ATIPrintRegisters
         xf86ErrorFVerb(4, "\n\n PCI configuration register values:");
         for (Index = 0;  Index < 256;  Index+= 4)
         {
+            pciVideoPtr pVideo = pATI->PCIInfo;
+            uint32_t    data;
+
+            PCI_READ_LONG(pVideo, &data, Index);
+
             if (!(Index & 15))
                 xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
-            xf86ErrorFVerb(4, " 0x%08lX",
-			   (unsigned long)pciReadLong(pPCI->tag, Index));
+            xf86ErrorFVerb(4, " 0x%08X", data);
         }
     }
 
diff --git a/src/atiprobe.c b/src/atiprobe.c
index 5f22032..78b3edd 100644
--- a/src/atiprobe.c
+++ b/src/atiprobe.c
@@ -214,29 +214,36 @@ ATIMach64Probe
     const ATIChipType Chip
 )
 {
-    CARD16 ChipType = pVideo->chipType;
+    CARD16 ChipType = PCI_DEV_DEVICE_ID(pVideo);
+
+        pATI->MMIOInLinear = FALSE;
 
         /*
          * Probe through auxiliary MMIO aperture if one exists.  Because such
          * apertures can be enabled/disabled only through PCI, this probes no
          * further.
          */
-        if ((pVideo->size[2] >= 12) &&
-            (pATI->Block0Base = pVideo->memBase[2]) &&
-            (pATI->Block0Base < (CARD32)(-1 << pVideo->size[2])))
+        if ((PCI_REGION_SIZE(pVideo, 2) >= (1 << 12)) &&
+            (pATI->Block0Base = PCI_REGION_BASE(pVideo, 2, REGION_MEM)))
         {
             pATI->Block0Base += 0x00000400U;
-            goto LastProbe;
+            if (ATIMach64Detect(pATI, ChipType, Chip))
+                return pATI;
+
+            return NULL;
         }
 
         /*
          * Probe through the primary MMIO aperture that exists at the tail end
          * of the linear aperture.  Test for both 8MB and 4MB linear apertures.
          */
-        if ((pVideo->size[0] >= 22) && (pATI->Block0Base = pVideo->memBase[0]))
+        if ((PCI_REGION_SIZE(pVideo, 0) >= (1 << 22)) &&
+            (pATI->Block0Base = PCI_REGION_BASE(pVideo, 0, REGION_MEM)))
         {
+            pATI->MMIOInLinear = TRUE;
+
             pATI->Block0Base += 0x007FFC00U;
-            if ((pVideo->size[0] >= 23) &&
+            if ((PCI_REGION_SIZE(pVideo, 0) >= (1 << 23)) &&
                 ATIMach64Detect(pATI, ChipType, Chip))
                 return pATI;
 
@@ -245,17 +252,6 @@ ATIMach64Probe
                 return pATI;
         }
 
-    /*
-     * A last, perhaps desparate, probe attempt.  Note that if this succeeds,
-     * there's a VGA in the system and it's likely the PIO version of the
-     * driver should be used instead (barring OS issues).
-     */
-    pATI->Block0Base = 0x000BFC00U;
-
-LastProbe:
-    if (ATIMach64Detect(pATI, ChipType, Chip))
-        return pATI;
-
     return NULL;
 }
 
@@ -276,11 +272,10 @@ ATIMach64Probe
 )
 {
     CARD32 IOValue;
-    CARD16 ChipType = pVideo->chipType;
+    CARD16 ChipType = PCI_DEV_DEVICE_ID(pVideo);
 
         if ((pATI->CPIODecoding == BLOCK_IO) &&
-            ((pVideo->size[1] < 8) ||
-             (pATI->CPIOBase >= (CARD32)(-1 << pVideo->size[1]))))
+            (PCI_REGION_SIZE(pVideo, 1) < (1 << 8)))
             return NULL;
 
     if (!ATIMach64Detect(pATI, ChipType, Chip))
@@ -380,21 +375,24 @@ ATIMach64ProbeIO
 #ifndef AVOID_CPIO
 
     /* Next, look for sparse I/O Mach64's */
-    if (!pVideo->size[1])
+    if (!PCI_REGION_SIZE(pVideo, 1))
     {
         static const IOADDRESS Mach64SparseIOBases[] = {
             0x02ECU,
             0x01CCU,
             0x01C8U
         };
+        uint32_t PciReg;
+        uint32_t j;
+
+#ifndef XSERVER_LIBPCIACCESS
         pciConfigPtr pPCI = pVideo->thisCard;
-        CARD32       PciReg;
-        CARD32       j;
 
         if (pPCI == NULL)
             goto SkipSparse;
+#endif
 
-        PciReg = pciReadLong(pPCI->tag, PCI_REG_USERCONFIG);
+        PCI_READ_LONG(pVideo, &PciReg, PCI_REG_USERCONFIG);
         j = PciReg & 0x03U;
 
         if (j == 0x03U)
@@ -402,7 +400,7 @@ ATIMach64ProbeIO
             xf86Msg(X_WARNING, ATI_NAME ": "
                 "PCI Mach64 in slot %d:%d:%d cannot be enabled\n"
                 "because it has neither a block, nor a sparse, I/O base.\n",
-                pVideo->bus, pVideo->device, pVideo->func);
+                PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo));
 
             goto SkipSparse;
         }
@@ -422,14 +420,17 @@ ATIMach64ProbeIO
             xf86Msg(X_WARNING, ATI_NAME ": "
                 "PCI Mach64 in slot %d:%d:%d will not be probed\n"
                 "set option \"probe_sparse\" to force sparse I/O probing.\n",
-                pVideo->bus, pVideo->device, pVideo->func);
+                PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo));
 
             goto SkipSparse;
         }
 
         /* Possibly fix block I/O indicator */
         if (PciReg & 0x00000004U)
-            pciWriteLong(pPCI->tag, PCI_REG_USERCONFIG, PciReg & ~0x00000004U);
+        {
+            PciReg &= ~0x00000004U;
+            PCI_WRITE_LONG(pVideo, PciReg, PCI_REG_USERCONFIG);
+        }
 
         pATI->CPIOBase = Mach64SparseIOBases[j];
         pATI->CPIODecoding = SPARSE_IO;
@@ -439,7 +440,7 @@ ATIMach64ProbeIO
         {
             xf86Msg(X_WARNING, ATI_NAME ": "
                 "PCI Mach64 in slot %d:%d:%d could not be detected!\n",
-                pVideo->bus, pVideo->device, pVideo->func);
+                PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo));
         }
         else
         {
@@ -447,7 +448,7 @@ ATIMach64ProbeIO
             xf86Msg(X_INFO, ATI_NAME ": "
                 "Shared PCI Mach64 in slot %d:%d:%d with sparse PIO base"
                 " 0x%04lX detected.\n",
-                pVideo->bus, pVideo->device, pVideo->func,
+                PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo),
                 Mach64SparseIOBases[j]);
 
             if (pATI->VGAAdapter)
@@ -459,7 +460,7 @@ SkipSparse:
 
 #else /* AVOID_CPIO */
 
-    if (!pVideo->size[1])
+    if (!PCI_REGION_SIZE(pVideo, 1))
     {
         /* The adapter's CPIO base is of little concern here */
         pATI->CPIOBase = 0;
@@ -472,23 +473,23 @@ SkipSparse:
             xf86Msg(X_INFO, ATI_NAME ": "
                 "Shared PCI Mach64 in slot %d:%d:%d with Block 0 base"
                 " 0x%08lX detected.\n",
-                pVideo->bus, pVideo->device, pVideo->func,
+                PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo),
                 pATI->Block0Base);
         }
         else
         {
             xf86Msg(X_WARNING, ATI_NAME ": "
                 "PCI Mach64 in slot %d:%d:%d could not be detected!\n",
-                pVideo->bus, pVideo->device, pVideo->func);
+                PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo));
         }
     }
 
 #endif /* AVOID_CPIO */
 
     /* Lastly, look for block I/O devices */
-    if (pVideo->size[1])
+    if (PCI_REGION_SIZE(pVideo, 1))
     {
-        pATI->CPIOBase = pVideo->ioBase[1];
+        pATI->CPIOBase = PCI_REGION_BASE(pVideo, 1, REGION_IO);
         pATI->CPIODecoding = BLOCK_IO;
         pATI->PCIInfo = pVideo;
 
@@ -497,7 +498,7 @@ SkipSparse:
             ProbeSuccess = TRUE;
             xf86Msg(X_INFO, ATI_NAME ": "
                 "Shared PCI/AGP Mach64 in slot %d:%d:%d detected.\n",
-                pVideo->bus, pVideo->device, pVideo->func);
+                PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo));
 
 #ifndef AVOID_CPIO
 
@@ -511,7 +512,7 @@ SkipSparse:
         {
             xf86Msg(X_WARNING, ATI_NAME ": "
                 "PCI/AGP Mach64 in slot %d:%d:%d could not be detected!\n",
-                pVideo->bus, pVideo->device, pVideo->func);
+                PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo));
         }
     }
 
diff --git a/src/atistruct.h b/src/atistruct.h
index 99be359..d574947 100644
--- a/src/atistruct.h
+++ b/src/atistruct.h
@@ -61,6 +61,8 @@
 #include "xf86Pci.h"
 #include "xf86Resources.h"
 
+#include "atipcirename.h"
+
 #define CacheSlotOf(____Register) ((____Register) / UnitOf(DWORD_SELECT))
 
 /*
diff --git a/src/atividmem.c b/src/atividmem.c
index b1a7a8d..8910c73 100644
--- a/src/atividmem.c
+++ b/src/atividmem.c
@@ -103,14 +103,26 @@ ATIUnmapLinear
     ATIPtr pATI
 )
 {
+    pciVideoPtr pVideo = pATI->PCIInfo;
+
     if (pATI->pMemory)
     {
+#ifndef XSERVER_LIBPCIACCESS
         xf86UnMapVidMem(iScreen, pATI->pMemory, pATI->LinearSize);
+#else
+        pci_device_unmap_range(pVideo, pATI->pMemory, pATI->LinearSize);
+#endif
 
 #if X_BYTE_ORDER != X_LITTLE_ENDIAN
 
         if (pATI->pMemoryLE)
+        {
+#ifndef XSERVER_LIBPCIACCESS
             xf86UnMapVidMem(iScreen, pATI->pMemoryLE, pATI->LinearSize);
+#else
+            pci_device_unmap_range(pVideo, pATI->pMemoryLE, pATI->LinearSize);
+#endif
+        }
 
 #endif /* X_BYTE_ORDER */
 
@@ -131,8 +143,16 @@ ATIUnmapMMIO
     ATIPtr pATI
 )
 {
+    pciVideoPtr pVideo = pATI->PCIInfo;
+
     if (pATI->pMMIO)
+    {
+#ifndef XSERVER_LIBPCIACCESS
         xf86UnMapVidMem(iScreen, pATI->pMMIO, getpagesize());
+#else
+        pci_device_unmap_range(pVideo, pATI->pMMIO, getpagesize());
+#endif
+    }
 
     pATI->pMMIO = pATI->pBlock[0] = pATI->pBlock[1] = NULL;
 }
@@ -149,8 +169,16 @@ ATIUnmapCursor
     ATIPtr pATI
 )
 {
+    pciVideoPtr pVideo = pATI->PCIInfo;
+
     if (pATI->pCursorPage)
+    {
+#ifndef XSERVER_LIBPCIACCESS
         xf86UnMapVidMem(iScreen, pATI->pCursorPage, getpagesize());
+#else
+        pci_device_unmap_range(pVideo, pATI->pCursorPage, getpagesize());
+#endif
+    }
 
     pATI->pCursorPage = pATI->pCursorImage = NULL;
 }
@@ -159,6 +187,11 @@ ATIUnmapCursor
  * ATIMapApertures --
  *
  * This function maps all apertures used by the driver.
+ *
+ * It is called three times:
+ * - to setup MMIO for an MMIO-only driver during Probe
+ * - to setup MMIO for an MMIO-only driver during PreInit
+ * - to setup MMIO (with Block0Base set) and FB (with LinearBase set)
  */
 Bool
 ATIMapApertures
@@ -168,7 +201,11 @@ ATIMapApertures
 )
 {
     pciVideoPtr   pVideo = pATI->PCIInfo;
-    PCITAG        Tag = ((pciConfigPtr)(pVideo->thisCard))->tag;
+#ifndef XSERVER_LIBPCIACCESS
+    PCITAG        Tag = PCI_CFG_TAG(pVideo);
+#else
+    pciVideoPtr   Tag = pVideo;
+#endif
     unsigned long PageSize = getpagesize();
 
     if (pATI->Mapped)
@@ -197,9 +234,30 @@ ATIMapApertures
     /* Map linear aperture */
     if (pATI->LinearBase)
     {
+
+#ifndef XSERVER_LIBPCIACCESS
+
             pATI->pMemory = xf86MapPciMem(iScreen, VIDMEM_FRAMEBUFFER,
                 Tag, pATI->LinearBase, pATI->LinearSize);
 
+#else /* XSERVER_LIBPCIACCESS */
+
+        int mode = PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE;
+
+        int err = pci_device_map_range(pVideo,
+                                       pATI->LinearBase,
+                                       pATI->LinearSize,
+                                       mode, &pATI->pMemory);
+
+        if (err)
+        {
+            xf86DrvMsg (iScreen, X_ERROR,
+                    "Unable to map linear aperture. %s (%d)\n",
+                    strerror (err), err);
+        }
+
+#endif /* XSERVER_LIBPCIACCESS */
+
         if (!pATI->pMemory)
         {
 
@@ -230,9 +288,31 @@ ATIMapApertures
          * caching of this area is _not_ wanted.
          */
         {
+
+#ifndef XSERVER_LIBPCIACCESS
+
             pATI->pMemoryLE = xf86MapPciMem(iScreen, VIDMEM_MMIO, Tag,
                 pATI->LinearBase - 0x00800000U, pATI->LinearSize);
 
+
+#else /* XSERVER_LIBPCIACCESS */
+
+        int mode = PCI_DEV_MAP_FLAG_WRITABLE;
+
+        int err = pci_device_map_range(pVideo,
+                                       pATI->LinearBase - 0x00800000U,
+                                       pATI->LinearSize,
+                                       mode, &pATI->pMemoryLE);
+
+        if (err)
+        {
+            xf86DrvMsg (iScreen, X_ERROR,
+                    "Unable to map extended linear aperture. %s (%d)\n",
+                    strerror (err), err);
+        }
+
+#endif /* XSERVER_LIBPCIACCESS */
+
             if (!pATI->pMemoryLE)
             {
                 ATIUnmapLinear(iScreen, pATI);
@@ -257,9 +337,29 @@ ATIMapApertures
     {
         unsigned long MMIOBase = pATI->Block0Base & ~(PageSize - 1);
 
+#ifndef XSERVER_LIBPCIACCESS
+
             pATI->pMMIO = xf86MapPciMem(iScreen, VIDMEM_MMIO,
                 Tag, MMIOBase, PageSize);
 
+#else /* XSERVER_LIBPCIACCESS */
+
+        int mode = PCI_DEV_MAP_FLAG_WRITABLE;
+
+        int err = pci_device_map_range(pVideo,
+                                       MMIOBase,
+                                       PageSize,
+                                       mode, &pATI->pMMIO);
+
+        if (err)
+        {
+            xf86DrvMsg (iScreen, X_ERROR,
+                    "Unable to map mmio aperture. %s (%d)\n",
+                    strerror (err), err);
+        }
+
+#endif /* XSERVER_LIBPCIACCESS */
+
         if (!pATI->pMMIO)
         {
 
@@ -308,9 +408,29 @@ ATIMapApertures
     {
         unsigned long CursorBase = pATI->CursorBase & ~(PageSize - 1);
 
+#ifndef XSERVER_LIBPCIACCESS
+
             pATI->pCursorPage = xf86MapPciMem(iScreen, VIDMEM_FRAMEBUFFER,
                 Tag, CursorBase, PageSize);
 
+#else /* XSERVER_LIBPCIACCESS */
+
+        int mode = PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE;
+
+        int err = pci_device_map_range(pVideo,
+                                       CursorBase,
+                                       PageSize,
+                                       mode, &pATI->pCursorPage);
+
+        if (err)
+        {
+            xf86DrvMsg (iScreen, X_ERROR,
+                    "Unable to map cursor aperture. %s (%d)\n",
+                    strerror (err), err);
+        }
+
+#endif /* XSERVER_LIBPCIACCESS */
+
         if (!pATI->pCursorPage)
         {
             ATIUnmapCursor(iScreen, pATI);
diff --git a/src/r128_probe.c b/src/r128_probe.c
index 81ff663..b2298df 100644
--- a/src/r128_probe.c
+++ b/src/r128_probe.c
@@ -144,7 +144,9 @@ R128Probe(DriverPtr drv, int flags)
     Bool          foundScreen = FALSE;
     int           i;
 
+#ifndef XSERVER_LIBPCIACCESS
     if (!xf86GetPciVideoInfo()) return FALSE;
+#endif
 
     /* Collect unclaimed device sections for both driver names */
     nATIGDev = xf86MatchDevice(ATI_NAME, &ATIGDevs);
diff --git a/src/radeon.h b/src/radeon.h
index cec06e9..ad94cc5 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -88,6 +88,8 @@
 #include "picturestr.h"
 #endif
 
+#include "atipcirename.h"
+
 #ifndef MAX
 #define MAX(a,b) ((a)>(b)?(a):(b))
 #endif
@@ -456,8 +458,8 @@ typedef struct {
     CARD32            mc_fb_location;
     CARD32            mc_agp_location;
 
-    unsigned char     *MMIO;            /* Map of MMIO region                */
-    unsigned char     *FB;              /* Map of frame buffer               */
+    void              *MMIO;            /* Map of MMIO region                */
+    void              *FB;              /* Map of frame buffer               */
     CARD8             *VBIOS;           /* Video BIOS pointer                */
 
     Bool              IsAtomBios;       /* New BIOS used in R420 etc.        */
@@ -940,7 +942,6 @@ extern Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn);
 extern int RADEONValidateMergeModes(ScrnInfoPtr pScrn);
 extern int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName,
 				  RADEONMonitorType DisplayType, int crtc2);
-extern int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePtr *modeList);
 extern void RADEONSetPitch (ScrnInfoPtr pScrn);
 extern void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode);
 
@@ -950,6 +951,15 @@ extern Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1,
 			DisplayModePtr crtc2, int crtc_mask,
 			RADEONSavePtr save, RADEONMonitorType montype);
 
+extern Bool
+RADEONDVOReadByte(I2CDevPtr dvo, int addr, CARD8 *ch);
+extern Bool
+RADEONDVOWriteByte(I2CDevPtr dvo, int addr, CARD8 ch);
+extern Bool
+RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output);
+extern Bool
+RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output);
+
 void
 radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y);
 void
diff --git a/src/radeon_accel.c b/src/radeon_accel.c
index b739988..6028aff 100644
--- a/src/radeon_accel.c
+++ b/src/radeon_accel.c
@@ -621,7 +621,7 @@ RADEONHostDataParams(ScrnInfoPtr pScrn, CARD8 *dst, CARD32 pitch, int cpp,
 		     CARD32 *dstPitchOff, int *x, int *y)
 {
     RADEONInfoPtr info = RADEONPTR( pScrn );
-    CARD32 dstOffs = dst - info->FB + info->fbLocation;
+    CARD32 dstOffs = dst - (CARD8*)info->FB + info->fbLocation;
 
     *dstPitchOff = pitch << 16 | (dstOffs & ~RADEON_BUFFER_ALIGN) >> 10;
     *y = ( dstOffs & RADEON_BUFFER_ALIGN ) / pitch;
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index cb96022..65c2bb0 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -41,20 +41,6 @@
 #include "radeon_probe.h"
 #include "vbe.h"
 
-int RADEONBIOSApplyConnectorQuirks(ScrnInfoPtr pScrn, int connector_found)
-{
-    RADEONInfoPtr  info   = RADEONPTR(pScrn);
-
-    /* quirk for compaq nx6125 - the bios lies about the VGA DDC */
-    if (info->PciInfo->subsysVendor == PCI_VENDOR_HP) {
-      if (info->PciInfo->subsysCard == 0x308b) {
-	if (info->BiosConnector[1].DDCType == DDC_CRT2)
-	  info->BiosConnector[1].DDCType = DDC_MONID;
-      }
-    }
-    return connector_found;
-}
-
 /* Read the Video BIOS block and the FP registers (if applicable). */
 Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
 {
@@ -62,7 +48,13 @@ Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
     int tmp;
     unsigned short dptr;
 
-    if (!(info->VBIOS = xalloc(RADEON_VBIOS_SIZE))) {
+    if (!(info->VBIOS = xalloc(
+#ifdef XSERVER_LIBPCIACCESS
+			       info->PciInfo->rom_size
+#else
+			       RADEON_VBIOS_SIZE
+#endif
+			       ))) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "Cannot allocate space for hold Video BIOS!\n");
 	return FALSE;
@@ -72,6 +64,12 @@ Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
 	    (void)memcpy(info->VBIOS, xf86int10Addr(pInt10, info->BIOSAddr),
 			 RADEON_VBIOS_SIZE);
 	} else {
+#ifdef XSERVER_LIBPCIACCESS
+	    if (pci_device_read_rom(info->PciInfo, info->VBIOS)) {
+		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+			   "Failed to read PCI ROM!\n");
+	    }
+#else
 	    xf86ReadPciBIOS(0, info->PciTag, 0, info->VBIOS, RADEON_VBIOS_SIZE);
 	    if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
 		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -83,6 +81,7 @@ Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
 		xf86ReadDomainMemory(info->PciTag, info->BIOSAddr,
 				     RADEON_VBIOS_SIZE, info->VBIOS);
 	    }
+#endif
 	}
     }
 
@@ -332,218 +331,6 @@ Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	return RADEONGetLegacyConnectorInfoFromBIOS(pScrn);
 }
 
-#if 0
-Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr info = RADEONPTR (pScrn);
-    int i = 0, j, tmp, tmp0=0, tmp1=0;
-    RADEONBIOSConnector tempConnector;
-
-    if(!info->VBIOS) return FALSE;
-
-    if (info->IsAtomBios) {
-	if((tmp = RADEON_BIOS16 (info->MasterDataStart + 22))) {
-	    int crtc = 0, id[2];
-	    tmp1 = RADEON_BIOS16 (tmp + 4);
-	    for (i=0; i<8; i++) {
-		if(tmp1 & (1<<i)) {
-		    CARD16 portinfo = RADEON_BIOS16(tmp+6+i*2);
-		    if (crtc < 2) {
-			if ((i==2) || (i==6)) continue; /* ignore TV here */
-
-			if (crtc == 1) {
-			    /* sharing same port with id[0] */
-			    if (((portinfo>>8) & 0xf) == id[0]) {
-				if (i == 3) 
-				    info->BiosConnector[0].TMDSType = TMDS_INT;
-				else if (i == 7)
-				    info->BiosConnector[0].TMDSType = TMDS_EXT;
-
-				if (info->BiosConnector[0].DACType == DAC_UNKNOWN)
-				    info->BiosConnector[0].DACType = (portinfo & 0xf) - 1;
-				continue;
-			    }
-			}
-
-			id[crtc] = (portinfo>>8) & 0xf; 
-			info->BiosConnector[crtc].DACType = (portinfo & 0xf) - 1;
-			info->BiosConnector[crtc].ConnectorType = (portinfo>>4) & 0xf;
-			if (i == 3) 
-			    info->BiosConnector[crtc].TMDSType = TMDS_INT;
-			else if (i == 7)
-			    info->BiosConnector[crtc].TMDSType = TMDS_EXT;
-			
-			if((tmp0 = RADEON_BIOS16 (info->MasterDataStart + 24)) && id[crtc]) {
-			    switch (RADEON_BIOS16 (tmp0 + 4 + 27 * id[crtc]) * 4) 
-			    {
-			    case RADEON_GPIO_MONID:
-				info->BiosConnector[crtc].DDCType = DDC_MONID;
-				break;
-			    case RADEON_GPIO_DVI_DDC:
-				info->BiosConnector[crtc].DDCType = DDC_DVI;
-				break;
-			    case RADEON_GPIO_VGA_DDC:
-				info->BiosConnector[crtc].DDCType = DDC_VGA;
-				break;
-			    case RADEON_GPIO_CRT2_DDC:
-				info->BiosConnector[crtc].DDCType = DDC_CRT2;
-				break;
-			    case RADEON_LCD_GPIO_MASK:
-				info->BiosConnector[crtc].DDCType = DDC_LCD;
-				break;
-			    default:
-				info->BiosConnector[crtc].DDCType = DDC_NONE_DETECTED;
-				break;
-			    }
-
-			} else {
-			    info->BiosConnector[crtc].DDCType = DDC_NONE_DETECTED;
-			}
-			crtc++;
-		    } else {
-			/* we have already had two CRTCs assigned. the rest may share the same
-			 * port with the existing connector, fill in them accordingly.
-			 */
-			for (j=0; j<2; j++) {
-			    if (((portinfo>>8) & 0xf) == id[j]) {
-				if (i == 3) 
-				    info->BiosConnector[j].TMDSType = TMDS_INT;
-				else if (i == 7)
-				    info->BiosConnector[j].TMDSType = TMDS_EXT;
-
-				if (info->BiosConnector[j].DACType == DAC_UNKNOWN)
-				    info->BiosConnector[j].DACType = (portinfo & 0xf) - 1;
-			    }
-			}
-		    }
-		}
-	    }
-
-	    /* R4xx seem to get the connector table backwards */
-	    tempConnector = info->BiosConnector[0];
-	    info->BiosConnector[0] = info->BiosConnector[1];
-	    info->BiosConnector[1] = tempConnector;
-
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
-	    for (i=0; i<2; i++) {
-		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
-			   i, info->BiosConnector[i].DDCType, info->BiosConnector[i].DACType,
-			   info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType);
-	    }	    
-	} else {
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Device Info Table found!\n");
-	    return FALSE;
-	}
-    } else {
-	/* Some laptops only have one connector (VGA) listed in the connector table, 
-	 * we need to add LVDS in as a non-DDC display. 
-	 * Note, we can't assume the listed VGA will be filled in PortInfo[0],
-	 * when walking through connector table. connector_found has following meaning: 
-	 * 0 -- nothing found, 
-	 * 1 -- only PortInfo[0] filled, 
-	 * 2 -- only PortInfo[1] filled,
-	 * 3 -- both are filled.
-	 */
-	int connector_found = 0;
-
-	if ((tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x50))) {
-	    for (i = 1; i < 4; i++) {
-
-		if (!RADEON_BIOS16(tmp + i*2))
-			break; /* end of table */
-		
-		tmp0 = RADEON_BIOS16(tmp + i*2);
-		if (((tmp0 >> 12) & 0x0f) == 0) continue;     /* no connector */
-		if (connector_found > 0) {
-		    if (info->BiosConnector[tmp1].DDCType == ((tmp0 >> 8) & 0x0f))
-			continue;                             /* same connector */
-		}
-
-		/* internal DDC_DVI port will get assigned to PortInfo[0], or if there is no DDC_DVI (like in some IGPs). */
-		tmp1 = ((((tmp0 >> 8) & 0xf) == DDC_DVI) || (tmp1 == 1)) ? 0 : 1; /* determine port info index */
-		
-		info->BiosConnector[tmp1].DDCType        = (tmp0 >> 8) & 0x0f;
-		if (info->BiosConnector[tmp1].DDCType > DDC_CRT2)
-		    info->BiosConnector[tmp1].DDCType = DDC_NONE_DETECTED;
-		info->BiosConnector[tmp1].DACType        = (tmp0 & 0x01) ? DAC_TVDAC : DAC_PRIMARY;
-		info->BiosConnector[tmp1].ConnectorType  = (tmp0 >> 12) & 0x0f;
-		if (info->BiosConnector[tmp1].ConnectorType > CONNECTOR_UNSUPPORTED)
-		    info->BiosConnector[tmp1].ConnectorType = CONNECTOR_UNSUPPORTED;
-		info->BiosConnector[tmp1].TMDSType       = ((tmp0 >> 4) & 0x01) ? TMDS_EXT : TMDS_INT;
-
-		/* some sanity checks */
-		if (((info->BiosConnector[tmp1].ConnectorType != CONNECTOR_DVI_D) &&
-		     (info->BiosConnector[tmp1].ConnectorType != CONNECTOR_DVI_I)) &&
-		    info->BiosConnector[tmp1].TMDSType == TMDS_INT)
-		    info->BiosConnector[tmp1].TMDSType = TMDS_UNKNOWN;
-		
-		connector_found += (tmp1 + 1);
-	    }
-	} else {
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Connector Info Table found!\n");
-	    return FALSE;
-	}
-
-	if (info->IsMobility) {
-	    if ((tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42))) {
-	        if ((tmp0 = RADEON_BIOS16(tmp + 0x15))) {
-		    if ((tmp1 = RADEON_BIOS8(tmp0+2) & 0x07)) {	    
-			info->BiosConnector[0].DDCType	= tmp1;      
-			if (info->BiosConnector[0].DDCType > DDC_LCD) {
-			    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-				       "Unknown DDCType %d found\n",
-				       info->BiosConnector[0].DDCType);
-			    info->BiosConnector[0].DDCType = DDC_NONE_DETECTED;
-			}
-			xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "LCD DDC Info Table found!\n");
-		    }
-		}
-	    } 
-	} else if (connector_found == 2) {
-	    memcpy (&info->BiosConnector[0], &info->BiosConnector[1], 
-		    sizeof (info->BiosConnector[0]));	
-	    info->BiosConnector[1].DACType = DAC_UNKNOWN;
-	    info->BiosConnector[1].TMDSType = TMDS_UNKNOWN;
-	    info->BiosConnector[1].DDCType = DDC_NONE_DETECTED;
-	    info->BiosConnector[1].ConnectorType = CONNECTOR_NONE;
-	    connector_found = 1;
-	}
-
-	connector_found = RADEONBIOSApplyConnectorQuirks(pScrn, connector_found);
-	
-	if (connector_found == 0) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No connector found in Connector Info Table.\n");
-	} else {
-	    xf86DrvMsg(0, X_INFO, "Bios Connector0: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
-		       info->BiosConnector[0].DDCType, info->BiosConnector[0].DACType,
-		       info->BiosConnector[0].TMDSType, info->BiosConnector[0].ConnectorType);
-	}
-	if (connector_found == 3) {
-	    xf86DrvMsg(0, X_INFO, "Bios Connector1: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
-		       info->BiosConnector[1].DDCType, info->BiosConnector[1].DACType,
-		       info->BiosConnector[1].TMDSType, info->BiosConnector[1].ConnectorType);
-	}
-
-#if 0
-/* External TMDS Table, not used now */
-        if ((tmp0 = RADEON_BIOS16(info->ROMHeaderStart + 0x58))) {
-
-            //info->BiosConnector[1].DDCType = (RADEON_BIOS8(tmp0 + 7) & 0x07);
-            //info->BiosConnector[1].ConnectorType  = CONNECTOR_DVI_I;
-            //info->BiosConnector[1].TMDSType = TMDS_EXT;
-            xf86DrvMsg(pScrn->scrnIndex, X_INFO, "External TMDS found.\n");
-
-        } else {
-            xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NO External TMDS Info found\n");
-
-        }
-#endif
-
-    }
-    return TRUE;
-}
-#endif
-
 Bool RADEONGetTVInfoFromBIOS (xf86OutputPtr output) {
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
@@ -715,14 +502,6 @@ Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output)
 		radeon_output->PanelPwrDly = 2000;
 
 	    radeon_output->Flags = 0;
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 
-		       "LVDS Info:\n"
-		       "XRes: %d, YRes: %d, DotClock: %d\n"
-		       "HBlank: %d, HOverPlus: %d, HSyncWidth: %d\n"
-		       "VBlank: %d, VOverPlus: %d, VSyncWidth: %d\n",
-		       radeon_output->PanelXRes, radeon_output->PanelYRes, radeon_output->DotClock,
-		       radeon_output->HBlank, radeon_output->HOverPlus, radeon_output->HSyncWidth,
-		       radeon_output->VBlank, radeon_output->VOverPlus, radeon_output->VSyncWidth);
 	} else {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		       "No LVDS Info Table found in BIOS!\n");
@@ -793,6 +572,16 @@ Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output)
 	    }
 	}
     }
+
+    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+	       "LVDS Info:\n"
+	       "XRes: %d, YRes: %d, DotClock: %d\n"
+	       "HBlank: %d, HOverPlus: %d, HSyncWidth: %d\n"
+	       "VBlank: %d, VOverPlus: %d, VSyncWidth: %d\n",
+	       radeon_output->PanelXRes, radeon_output->PanelYRes, radeon_output->DotClock,
+	       radeon_output->HBlank, radeon_output->HOverPlus, radeon_output->HSyncWidth,
+	       radeon_output->VBlank, radeon_output->VOverPlus, radeon_output->VSyncWidth);
+
     return TRUE;
 }
 
@@ -896,6 +685,140 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output)
     return FALSE;
 }
 
+Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    int offset, table_start, max_freq, gpio_reg, flags;
+
+    if (!info->VBIOS) return FALSE;
+
+    if (info->IsAtomBios) {
+	return FALSE;
+    } else {
+	offset = RADEON_BIOS16(info->ROMHeaderStart + 0x58);
+	if (offset) {
+	     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			"External TMDS Table revision: %d\n",
+			RADEON_BIOS8(offset));
+	    table_start = offset+4;
+	    max_freq = RADEON_BIOS16(table_start);
+	    radeon_output->dvo_i2c_slave_addr = RADEON_BIOS8(table_start+2);
+	    gpio_reg = RADEON_BIOS8(table_start+3);
+	    if (gpio_reg == 1)
+		radeon_output->dvo_i2c_reg = RADEON_GPIO_MONID;
+	    else if (gpio_reg == 2)
+		radeon_output->dvo_i2c_reg = RADEON_GPIO_DVI_DDC;
+	    else if (gpio_reg == 3)
+		radeon_output->dvo_i2c_reg = RADEON_GPIO_VGA_DDC;
+	    else if (gpio_reg == 4)
+		radeon_output->dvo_i2c_reg = RADEON_GPIO_CRT2_DDC;
+	    else if (gpio_reg == 5)
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "unsupported MM gpio_reg\n");
+		/*radeon_output->i2c_reg = RADEON_GPIO_MM;*/
+	    else {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "Unknown gpio reg: %d\n", gpio_reg);
+		return FALSE;
+	    }
+	    flags = RADEON_BIOS8(table_start+5);
+	    radeon_output->dvo_duallink = flags & 0x01;
+	    if (radeon_output->dvo_duallink) {
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			   "Duallink TMDS detected\n");
+	    }
+	    return TRUE;
+	}
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+	       "No External TMDS Table found\n");
+
+    return FALSE;
+}
+
+Bool RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    int offset, index, id;
+    CARD32 val, reg, andmask, ormask;
+
+    if (!info->VBIOS) return FALSE;
+
+    if (info->IsAtomBios) {
+	return FALSE;
+    } else {
+	offset = RADEON_BIOS16(info->ROMHeaderStart + 0x58);
+	if (offset) {
+	    index = offset+10;
+	    id = RADEON_BIOS16(index);
+	    while (id != 0xffff) {
+		index += 2;
+		switch(id >> 13) {
+		case 0:
+		    reg = id & 0x1fff;
+		    val = RADEON_BIOS32(index);
+		    index += 4;
+		    ErrorF("WRITE INDEXED: 0x%x 0x%x\n",
+			   (unsigned)reg, (unsigned)val);
+		    /*OUTREG(reg, val);*/
+		    break;
+		case 2:
+		    reg = id & 0x1fff;
+		    andmask = RADEON_BIOS32(index);
+		    index += 4;
+		    ormask = RADEON_BIOS32(index);
+		    index += 4;
+		    val = INREG(reg);
+		    val = (val & andmask) | ormask;
+		    ErrorF("MASK DIRECT: 0x%x 0x%x 0x%x\n",
+			   (unsigned)reg, (unsigned)andmask, (unsigned)ormask);
+		    /*OUTREG(reg, val);*/
+		    break;
+		case 4:
+		    val = RADEON_BIOS16(index);
+		    index += 2;
+		    ErrorF("delay: %u\n", (unsigned)val);
+		    usleep(val);
+		    break;
+		case 5:
+		    reg = id & 0x1fff;
+		    andmask = RADEON_BIOS32(index);
+		    index += 4;
+		    ormask = RADEON_BIOS32(index);
+		    index += 4;
+		    ErrorF("MASK PLL: 0x%x 0x%x 0x%x\n",
+			   (unsigned)reg, (unsigned)andmask, (unsigned)ormask);
+		    /*val = INPLL(pScrn, reg);
+		    val = (val & andmask) | ormask;
+		    OUTPLL(pScrn, reg, val);*/
+		    break;
+		case 6:
+		    reg = id & 0x1fff;
+		    val = RADEON_BIOS8(index);
+		    index += 1;
+		    ErrorF("i2c write: 0x%x, 0x%x\n", (unsigned)reg,
+			   (unsigned)val);
+		    RADEONDVOWriteByte(radeon_output->DVOChip, reg, val);
+		    break;
+		default:
+		    ErrorF("unknown id %d\n", id>>13);
+		    return FALSE;
+		};
+		id = RADEON_BIOS16(index);
+	    }
+	    return TRUE;
+	}
+    }
+
+    return FALSE;
+}
+
 /* support for init from bios tables
  *
  * Based heavily on the netbsd radeonfb driver
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 7f599e6..5c4fbfa 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -791,6 +791,11 @@ void RADEONInitDispBandwidth(ScrnInfoPtr pScrn)
 	mode1 = &xf86_config->crtc[1]->mode;
       } else
 	return;
+    } else {
+	if (xf86_config->crtc[0]->enabled)
+	    mode1 = &xf86_config->crtc[0]->mode;
+	else
+	    return;
     }
 
     RADEONInitDispBandwidth2(pScrn, info, pixel_bytes2, mode1, mode2);
diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index 24018e8..2c533b1 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -795,8 +795,8 @@ static Bool RADEONSetAgpMode(RADEONInfoPtr info, ScreenPtr pScreen)
     xf86DrvMsg(pScreen->myNum, X_INFO,
 	       "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
 	       mode, vendor, device,
-	       info->PciInfo->vendor,
-	       info->PciInfo->chipType);
+	       PCI_DEV_VENDOR_ID(info->PciInfo),
+	       PCI_DEV_DEVICE_ID(info->PciInfo));
 
     if (drmAgpEnable(info->drmFD, mode) < 0) {
 	xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n");
@@ -1183,9 +1183,9 @@ static void RADEONDRIIrqInit(RADEONInfoPtr info, ScreenPtr pScreen)
     if (!info->irq) {
 	info->irq = drmGetInterruptFromBusID(
 	    info->drmFD,
-	    ((pciConfigPtr)info->PciInfo->thisCard)->busnum,
-	    ((pciConfigPtr)info->PciInfo->thisCard)->devnum,
-	    ((pciConfigPtr)info->PciInfo->thisCard)->funcnum);
+	    PCI_CFG_BUS(info->PciInfo),
+	    PCI_CFG_DEV(info->PciInfo),
+	    PCI_CFG_FUNC(info->PciInfo));
 
 	if ((drmCtlInstHandler(info->drmFD, info->irq)) != 0) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -1291,9 +1291,9 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pScrn)
 	busId = xalloc(64);
 	sprintf(busId,
 		"PCI:%d:%d:%d",
-		info->PciInfo->bus,
-		info->PciInfo->device,
-		info->PciInfo->func);
+		PCI_DEV_BUS(info->PciInfo),
+		PCI_DEV_DEV(info->PciInfo),
+		PCI_DEV_FUNC(info->PciInfo));
     }
 
     /* Low level DRM open */
@@ -1431,9 +1431,9 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
 	pDRIInfo->busIdString            = xalloc(64);
 	sprintf(pDRIInfo->busIdString,
 		"PCI:%d:%d:%d",
-		info->PciInfo->bus,
-		info->PciInfo->device,
-		info->PciInfo->func);
+		PCI_DEV_BUS(info->PciInfo),
+		PCI_DEV_DEV(info->PciInfo),
+		PCI_DEV_FUNC(info->PciInfo));
     }
     pDRIInfo->ddxDriverMajorVersion      = info->allowColorTiling ?
     				RADEON_VERSION_MAJOR_TILED : RADEON_VERSION_MAJOR;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index e7cccf6..6f8a753 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -525,6 +525,8 @@ static Bool RADEONMapMMIO(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info = RADEONPTR(pScrn);
 
+#ifndef XSERVER_LIBPCIACCESS
+
     info->MMIO = xf86MapPciMem(pScrn->scrnIndex,
 			       VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
 			       info->PciTag,
@@ -532,6 +534,25 @@ static Bool RADEONMapMMIO(ScrnInfoPtr pScrn)
 			       info->MMIOSize);
 
     if (!info->MMIO) return FALSE;
+
+#else
+
+    void** result = (void**)&info->MMIO;
+    int err = pci_device_map_range(info->PciInfo,
+				   info->MMIOAddr,
+				   info->MMIOSize,
+				   PCI_DEV_MAP_FLAG_WRITABLE,
+				   result);
+
+    if (err) {
+	xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+                    "Unable to map MMIO aperture. %s (%d)\n",
+                    strerror (err), err);
+	return FALSE;
+    }
+
+#endif
+
     return TRUE;
 }
 
@@ -542,7 +563,11 @@ static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info = RADEONPTR(pScrn);
 
+#ifndef XSERVER_LIBPCIACCESS
     xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, info->MMIOSize);
+#else
+    pci_device_unmap_range(info->PciInfo, info->MMIO, info->MMIOSize);
+#endif
 
     info->MMIO = NULL;
     return TRUE;
@@ -555,6 +580,9 @@ static Bool RADEONMapFB(ScrnInfoPtr pScrn)
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "Map: 0x%08lx, 0x%08lx\n", info->LinearAddr, info->FbMapSize);
+
+#ifndef XSERVER_LIBPCIACCESS
+
     info->FB = xf86MapPciMem(pScrn->scrnIndex,
 			     VIDMEM_FRAMEBUFFER,
 			     info->PciTag,
@@ -562,6 +590,25 @@ static Bool RADEONMapFB(ScrnInfoPtr pScrn)
 			     info->FbMapSize);
 
     if (!info->FB) return FALSE;
+
+#else
+
+    int err = pci_device_map_range(info->PciInfo,
+				   info->LinearAddr,
+				   info->FbMapSize,
+				   PCI_DEV_MAP_FLAG_WRITABLE |
+				   PCI_DEV_MAP_FLAG_WRITE_COMBINE,
+				   &info->FB);
+
+    if (err) {
+	xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+                    "Unable to map FB aperture. %s (%d)\n",
+                    strerror (err), err);
+	return FALSE;
+    }
+
+#endif
+
     return TRUE;
 }
 
@@ -570,7 +617,12 @@ static Bool RADEONUnmapFB(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info = RADEONPTR(pScrn);
 
+#ifndef XSERVER_LIBPCIACCESS
     xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize);
+#else
+    pci_device_unmap_range(info->PciInfo, info->FB, info->FbMapSize);
+#endif
+
     info->FB = NULL;
     return TRUE;
 }
@@ -1271,6 +1323,7 @@ static CARD32 RADEONGetAccessibleVRAM(ScrnInfoPtr pScrn)
     RADEONInfoPtr  info   = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32	   aper_size = INREG(RADEON_CONFIG_APER_SIZE) / 1024;
+    unsigned char  byte;
 
 #ifdef XF86DRI
     /* If we use the DRI, we need to check if it's a version that has the
@@ -1311,7 +1364,8 @@ static CARD32 RADEONGetAccessibleVRAM(ScrnInfoPtr pScrn)
      * check if it's a multifunction card by reading the PCI config
      * header type... Limit those to one aperture size
      */
-    if (pciReadByte(info->PciTag, 0xe) & 0x80) {
+    PCI_READ_BYTE(info->PciInfo, &byte, 0xe);
+    if (byte & 0x80) {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		   "Generation 1 PCI interface in multifunction mode"
 		   ", accessible memory limited to one aperture\n");
@@ -1359,7 +1413,7 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn)
     accessible = RADEONGetAccessibleVRAM(pScrn);
 
     /* Crop it to the size of the PCI BAR */
-    bar_size = (1ul << info->PciInfo->size[0]) / 1024;
+    bar_size = PCI_REGION_SIZE(info->PciInfo, 0) / 1024;
     if (bar_size == 0)
 	bar_size = 0x20000;
     if (accessible > bar_size)
@@ -1419,6 +1473,7 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
     MessageType    from = X_PROBED;
 #ifdef XF86DRI
     const char *s;
+    uint32_t cmd_stat;
 #endif
 
     /* Chipset */
@@ -1430,7 +1485,7 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
 	info->Chipset  = dev->chipID;
 	from           = X_CONFIG;
     } else {
-	info->Chipset = info->PciInfo->chipType;
+	info->Chipset = PCI_DEV_DEVICE_ID(info->PciInfo);
     }
 
     pScrn->chipset = (char *)xf86TokenToString(RADEONChipsets, info->Chipset);
@@ -1470,17 +1525,17 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
 	info->ChipFamily = CHIP_FAMILY_RV100;
 
 	/* DELL triple-head configuration. */
-	if ((info->PciInfo->subsysVendor == PCI_VENDOR_DELL) &&
-	    ((info->PciInfo->subsysCard  == 0x016c) ||
-	    (info->PciInfo->subsysCard   == 0x016d) ||
-	    (info->PciInfo->subsysCard   == 0x016e) ||
-	    (info->PciInfo->subsysCard   == 0x016f) ||
-	    (info->PciInfo->subsysCard   == 0x0170) ||
-	    (info->PciInfo->subsysCard   == 0x017d) ||
-	    (info->PciInfo->subsysCard   == 0x017e) ||
-	    (info->PciInfo->subsysCard   == 0x0183) ||
-	    (info->PciInfo->subsysCard   == 0x018a) ||
-	    (info->PciInfo->subsysCard   == 0x019a))) {
+	if ((PCI_SUB_VENDOR_ID(info->PciInfo) == PCI_VENDOR_DELL) &&
+	    ((PCI_SUB_DEVICE_ID(info->PciInfo) == 0x016c) ||
+	     (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x016d) ||
+	     (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x016e) ||
+	     (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x016f) ||
+	     (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x0170) ||
+	     (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x017d) ||
+	     (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x017e) ||
+	     (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x0183) ||
+	     (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x018a) ||
+	     (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x019a))) {
 	    info->IsDellServer = TRUE;
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DELL server detected, force to special setup\n");
 	}
@@ -1702,7 +1757,7 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
 
 
     from               = X_PROBED;
-    info->LinearAddr   = info->PciInfo->memBase[0] & 0xfe000000;
+    info->LinearAddr   = PCI_REGION_BASE(info->PciInfo, 0, REGION_MEM) & 0xfe000000;
     pScrn->memPhysBase = info->LinearAddr;
     if (dev->MemBase) {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -1719,6 +1774,7 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
     xf86DrvMsg(pScrn->scrnIndex, from,
 	       "Linear framebuffer at 0x%08lx\n", info->LinearAddr);
 
+#ifndef XSERVER_LIBPCIACCESS
 				/* BIOS */
     from              = X_PROBED;
     info->BIOSAddr    = info->PciInfo->biosBase & 0xfffe0000;
@@ -1734,6 +1790,7 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
 	xf86DrvMsg(pScrn->scrnIndex, from,
 		   "BIOS at 0x%08lx\n", info->BIOSAddr);
     }
+#endif
 
 				/* Read registers used to determine options */
     /* Check chip errata */
@@ -1796,15 +1853,15 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
 
     info->cardType = CARD_PCI;
 
-    if (pciReadLong(info->PciTag, PCI_CMD_STAT_REG) & RADEON_CAP_LIST) {
-	CARD32 cap_ptr, cap_id;
-	
-	cap_ptr = pciReadLong(info->PciTag,
-			      RADEON_CAPABILITIES_PTR_PCI_CONFIG)
-	    & RADEON_CAP_PTR_MASK;
+    PCI_READ_LONG(info->PciInfo, &cmd_stat, PCI_CMD_STAT_REG);
+    if (cmd_stat & RADEON_CAP_LIST) {
+	uint32_t cap_ptr, cap_id;
+
+	PCI_READ_LONG(info->PciInfo, &cap_ptr, RADEON_CAPABILITIES_PTR_PCI_CONFIG);
+	cap_ptr &= RADEON_CAP_PTR_MASK;
 
 	while(cap_ptr != RADEON_CAP_ID_NULL) {
-	    cap_id = pciReadLong(info->PciTag, cap_ptr);
+	    PCI_READ_LONG(info->PciInfo, &cap_id, cap_ptr);
 	    if ((cap_id & 0xff)== RADEON_CAP_ID_AGP) {
 		info->cardType = CARD_AGP;
 		break;
@@ -1938,8 +1995,8 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn)
 
 #ifdef USE_EXA
 	if (info->useEXA) {
-	    info->exaReq.majorversion = 2;
-	    info->exaReq.minorversion = 0;
+	    info->exaReq.majorversion = EXA_VERSION_MAJOR;
+	    info->exaReq.minorversion = EXA_VERSION_MINOR;
 
 	    if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL,
 			       &info->exaReq, &errmaj, &errmin)) {
@@ -1991,7 +2048,7 @@ static Bool RADEONPreInitInt10(ScrnInfoPtr pScrn, xf86Int10InfoPtr *ppInt10)
 	/* The VGA BIOS on the RV100/QY cannot be read when the digital output
 	 * is enabled.  Clear and restore FP2_ON around int10 to avoid this.
 	 */
-	if (info->PciInfo->chipType == PCI_CHIP_RV100_QY) {
+	if (PCI_DEV_DEVICE_ID(info->PciInfo) == PCI_CHIP_RV100_QY) {
 	    fp2_gen_ctl_save = INREG(RADEON_FP2_GEN_CNTL);
 	    if (fp2_gen_ctl_save & RADEON_FP2_ON) {
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "disabling digital out\n");
@@ -2026,15 +2083,17 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn)
     info->pKernelDRMVersion = NULL;
 
     if (info->Chipset == PCI_CHIP_RN50_515E ||
-	info->Chipset == PCI_CHIP_RN50_5969) {
+	info->Chipset == PCI_CHIP_RN50_5969 ||
+	info->Chipset == PCI_CHIP_RC410_5A61 ||
+	info->Chipset == PCI_CHIP_RC410_5A62) {
     	if (xf86ReturnOptValBool(info->Options, OPTION_DRI, FALSE)) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		"Direct rendering for RN50 forced on -- "
+		"Direct rendering for RN50/RC410 forced on -- "
 		"This is NOT officially supported at the hardware level "
 		"and may cause instability or lockups\n");
     	} else {
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		"Direct rendering not officially supported on RN50\n");
+		"Direct rendering not officially supported on RN50/RC410\n");
 	    return FALSE;
 	}
     }
@@ -2525,11 +2584,11 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
     if (info->pEnt->location.type != BUS_PCI) goto fail;
 
     info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
-    info->PciTag  = pciTag(info->PciInfo->bus,
-			   info->PciInfo->device,
-			   info->PciInfo->func);
-    info->MMIOAddr   = info->PciInfo->memBase[2] & 0xffffff00;
-    info->MMIOSize  = (1 << info->PciInfo->size[2]);
+    info->PciTag  = pciTag(PCI_DEV_BUS(info->PciInfo),
+			   PCI_DEV_DEV(info->PciInfo),
+			   PCI_DEV_FUNC(info->PciInfo));
+    info->MMIOAddr = PCI_REGION_BASE(info->PciInfo, 2, REGION_MEM) & 0xffffff00;
+    info->MMIOSize = PCI_REGION_SIZE(info->PciInfo, 2);
     if (info->pEnt->device->IOBase) {
 	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
 		   "MMIO address override, using 0x%08lx instead of 0x%08lx\n",
@@ -2550,7 +2609,10 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
     }
 
 #if !defined(__alpha__)
-    if (xf86GetPciDomain(info->PciTag) ||
+    if (
+#ifndef XSERVER_LIBPCIACCESS
+	xf86GetPciDomain(info->PciTag) ||
+#endif
 	!xf86IsPrimaryPci(info->PciInfo))
 	RADEONPreInt10Save(pScrn, &int10_save);
 #else
@@ -2572,9 +2634,9 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	       "PCI bus %d card %d func %d\n",
-	       info->PciInfo->bus,
-	       info->PciInfo->device,
-	       info->PciInfo->func);
+	       PCI_DEV_BUS(info->PciInfo),
+	       PCI_DEV_DEV(info->PciInfo),
+	       PCI_DEV_FUNC(info->PciInfo));
 
     if (xf86RegisterResources(info->pEnt->index, 0, ResExclusive))
 	goto fail;
@@ -2753,10 +2815,10 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
    }
 
     /* Free the video bios (if applicable) */
-    if (info->VBIOS) {
-	xfree(info->VBIOS);
-	info->VBIOS = NULL;
-    }
+    //if (info->VBIOS) {
+    //xfree(info->VBIOS);
+    //info->VBIOS = NULL;
+    //}
 
 				/* Free int10 info */
     if (pInt10)
@@ -5237,34 +5299,11 @@ static void RADEONSavePalette(ScrnInfoPtr pScrn, RADEONSavePtr save)
 }
 #endif
 
-/* Save state that defines current video mode */
-static void RADEONSaveMode(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "RADEONSaveMode(%p)\n", save);
-
-    RADEONSaveMemMapRegisters(pScrn, save);
-    RADEONSaveCommonRegisters(pScrn, save);
-    RADEONSavePLLRegisters(pScrn, save);
-    RADEONSaveCrtcRegisters(pScrn, save);
-    RADEONSaveFPRegisters(pScrn, save);
-    RADEONSaveDACRegisters(pScrn, save);
-    RADEONSaveCrtc2Registers(pScrn, save);
-    RADEONSavePLL2Registers(pScrn, save);
-    if (info->InternalTVOut)
-	RADEONSaveTVRegisters(pScrn, save);
-    /*RADEONSavePalette(pScrn, save);*/
-
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "RADEONSaveMode returns %p\n", save);
-}
-
 /* Save everything needed to restore the original VC state */
 static void RADEONSave(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     RADEONSavePtr  save       = &info->SavedReg;
 
@@ -5295,7 +5334,19 @@ static void RADEONSave(ScrnInfoPtr pScrn)
     save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
     RADEONPllErrataAfterIndex(info);
 
-    RADEONSaveMode(pScrn, save);
+    RADEONSaveMemMapRegisters(pScrn, save);
+    RADEONSaveCommonRegisters(pScrn, save);
+    RADEONSavePLLRegisters(pScrn, save);
+    RADEONSaveCrtcRegisters(pScrn, save);
+    RADEONSaveFPRegisters(pScrn, save);
+    RADEONSaveDACRegisters(pScrn, save);
+    if (pRADEONEnt->HasCRTC2) {
+	RADEONSaveCrtc2Registers(pScrn, save);
+	RADEONSavePLL2Registers(pScrn, save);
+    }
+    if (info->InternalTVOut)
+	RADEONSaveTVRegisters(pScrn, save);
+
     RADEONSaveSurfaces(pScrn, save);
 }
 
@@ -5326,15 +5377,6 @@ void RADEONRestore(ScrnInfoPtr pScrn)
     OUTREG(RADEON_GRPH_BUFFER_CNTL, restore->grph_buffer_cntl);
     OUTREG(RADEON_GRPH2_BUFFER_CNTL, restore->grph2_buffer_cntl);
 
-#if 0
-    /* M6 card has trouble restoring text mode for its CRT.
-     * This is fixed elsewhere and will be removed in the future.
-     */
-    if ((xf86IsEntityShared(info->pEnt->index) || info->MergedFB)
-	&& info->IsM6)
-	OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
-#endif
-
     RADEONRestoreMemMapRegisters(pScrn, restore);
     RADEONRestoreCommonRegisters(pScrn, restore);
 
@@ -5381,9 +5423,11 @@ void RADEONRestore(ScrnInfoPtr pScrn)
 #endif
 
     /* need to make sure we don't enable a crtc by accident or we may get a hang */
-    if (info->crtc2_on) {
-	crtc = xf86_config->crtc[1];
-	crtc->funcs->dpms(crtc, DPMSModeOn);
+    if (pRADEONEnt->HasCRTC2) {
+	if (info->crtc2_on) {
+	    crtc = xf86_config->crtc[1];
+	    crtc->funcs->dpms(crtc, DPMSModeOn);
+	}
     }
     if (info->crtc_on) {
 	crtc = xf86_config->crtc[0];
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index d074f08..8a12e1b 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -157,7 +157,7 @@ static Bool RADEONGetOffsetPitch(PixmapPtr pPix, int bpp, CARD32 *pitch_offset,
 {
 	RINFO_FROM_SCREEN(pPix->drawable.pScreen);
 
-	if (pitch % info->exa->pixmapPitchAlign != 0)
+	if (pitch > 16320 || pitch % info->exa->pixmapPitchAlign != 0)
 		RADEON_FALLBACK(("Bad pitch 0x%08x\n", pitch));
 
 	if (offset % info->exa->pixmapOffsetAlign != 0)
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index c356de7..2b7f0e8 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -241,10 +241,8 @@ static Bool
 FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h,
 				char *src, int src_pitch)
 {
-#if X_BYTE_ORDER == X_BIG_ENDIAN || defined(ACCEL_CP)
     RINFO_FROM_SCREEN(pDst->drawable.pScreen);
-#endif
-    CARD8	   *dst	     = pDst->devPrivate.ptr;
+    CARD8	   *dst	     = info->FB + exaGetPixmapOffset(pDst);
     unsigned int   dst_pitch = exaGetPixmapPitch(pDst);
     unsigned int   bpp	     = pDst->drawable.bitsPerPixel;
 #ifdef ACCEL_CP
@@ -353,16 +351,14 @@ static Bool
 FUNC_NAME(RADEONDownloadFromScreen)(PixmapPtr pSrc, int x, int y, int w, int h,
 				    char *dst, int dst_pitch)
 {
-#if defined(ACCEL_CP) || X_BYTE_ORDER == X_BIG_ENDIAN
     RINFO_FROM_SCREEN(pSrc->drawable.pScreen);
-#endif
 #if X_BYTE_ORDER == X_BIG_ENDIAN
     unsigned char *RADEONMMIO = info->MMIO;
     unsigned int swapper = info->ModeReg.surface_cntl &
 	    ~(RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP |
 	      RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP);
 #endif
-    CARD8	  *src	     = pSrc->devPrivate.ptr;
+    CARD8	  *src	     = info->FB + exaGetPixmapOffset(pSrc);
     int		   src_pitch = exaGetPixmapPitch(pSrc);
     int		   bpp	     = pSrc->drawable.bitsPerPixel;
 #ifdef ACCEL_CP
@@ -511,8 +507,8 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
 	return FALSE;
     }
 
-    info->exa->exa_major = 2;
-    info->exa->exa_minor = 0;
+    info->exa->exa_major = EXA_VERSION_MAJOR;
+    info->exa->exa_minor = EXA_VERSION_MINOR;
 
     info->exa->PrepareSolid = FUNC_NAME(RADEONPrepareSolid);
     info->exa->Solid = FUNC_NAME(RADEONSolid);
@@ -564,7 +560,14 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
     }
 #endif
 
+#if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3)
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting EXA maxPitchBytes\n");
+
+    info->exa->maxPitchBytes = 16320;
     info->exa->maxX = info->exa->Composite ? 2048 : 8192;
+#else
+    info->exa->maxX = info->exa->Composite ? 2048 : 16320 / 4;
+#endif
     info->exa->maxY = info->exa->Composite ? 2048 : 8192;
 
     RADEONEngineInit(pScrn);
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index af56cdf..ea2c229 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -97,30 +97,15 @@ static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output)
     ScrnInfoPtr pScrn = output->scrn;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     DisplayModePtr  new   = NULL;
-    char            stmp[32];
 
     if (radeon_output->PanelXRes != 0 &&
 	radeon_output->PanelYRes != 0 &&
 	radeon_output->DotClock != 0) {
 
 	/* Add native panel size */
-	new             = xnfcalloc(1, sizeof (DisplayModeRec));
-	sprintf(stmp, "%dx%d", radeon_output->PanelXRes, radeon_output->PanelYRes);
-	new->name       = xnfalloc(strlen(stmp) + 1);
-	strcpy(new->name, stmp);
-	new->HDisplay   = radeon_output->PanelXRes;
-	new->VDisplay   = radeon_output->PanelYRes;
-
-	new->HTotal     = new->HDisplay + radeon_output->HBlank;
-	new->HSyncStart = new->HDisplay + radeon_output->HOverPlus;
-	new->HSyncEnd   = new->HSyncStart + radeon_output->HSyncWidth;
-	new->VTotal     = new->VDisplay + radeon_output->VBlank;
-	new->VSyncStart = new->VDisplay + radeon_output->VOverPlus;
-	new->VSyncEnd   = new->VSyncStart + radeon_output->VSyncWidth;
-
-	new->Clock      = radeon_output->DotClock;
-	new->Flags      = 0;
-	new->type       = M_T_USERDEF | M_T_PREFERRED;
+	new = xf86CVTMode(radeon_output->PanelXRes, radeon_output->PanelYRes, 60.0, TRUE, FALSE);
+
+	new->type       = M_T_DRIVER | M_T_PREFERRED;
 
 	new->next       = NULL;
 	new->prev       = NULL;
@@ -132,20 +117,84 @@ static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output)
     return new;
 }
 
+/* this function is basically a hack to add the screen modes */
+static void RADEONAddScreenModes(xf86OutputPtr output, DisplayModePtr *modeList)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    DisplayModePtr  last       = NULL;
+    DisplayModePtr  new        = NULL;
+    DisplayModePtr  first      = NULL;
+    int             count      = 0;
+    int             i, width, height;
+    char **ppModeName = pScrn->display->modes;
+
+    first = last = *modeList;
+
+    /* We have a flat panel connected to the primary display, and we
+     * don't have any DDC info.
+     */
+    for (i = 0; ppModeName[i] != NULL; i++) {
+
+	if (sscanf(ppModeName[i], "%dx%d", &width, &height) != 2) continue;
+
+	if (radeon_output->type == OUTPUT_LVDS) {
+	    /* already added the native mode */
+	    if (width == radeon_output->PanelXRes && height == radeon_output->PanelYRes)
+		continue;
+
+	    /* Note: We allow all non-standard modes as long as they do not
+	     * exceed the native resolution of the panel.  Since these modes
+	     * need the internal RMX unit in the video chips (and there is
+	     * only one per card), this will only apply to the primary head.
+	     */
+	    if (width < 320 || width > radeon_output->PanelXRes ||
+		height < 200 || height > radeon_output->PanelYRes) {
+		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+			   "Mode %s is out of range.\n", ppModeName[i]);
+		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+			   "Valid FP modes must be between 320x200-%dx%d\n",
+			   radeon_output->PanelXRes, radeon_output->PanelYRes);
+		continue;
+	    }
+	}
+
+	new = xf86CVTMode(width, height, 60.0, TRUE, FALSE);
+
+	new->type      |= M_T_USERDEF;
+
+	new->next       = NULL;
+	new->prev       = last;
+
+	if (last) last->next = new;
+	last = new;
+	if (!first) first = new;
+
+	count++;
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		   "Adding Screen mode: %s\n", new->name);
+    }
+
+
+    /* Close the doubly-linked mode list, if we found any usable modes */
+    if (last) {
+	last->next   = NULL; //first;
+	first->prev  = NULL; //last;
+	*modeList = first;
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "Total number of valid Screen mode(s) added: %d\n", count);
+
+}
+
 DisplayModePtr
 RADEONProbeOutputModes(xf86OutputPtr output)
 {
-    ScrnInfoPtr	    pScrn = output->scrn;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     xf86MonPtr		    edid_mon;
     DisplayModePtr	    modes = NULL;
 
-#if 0
-    /* force reprobe */
-    radeon_output->MonType = MT_UNKNOWN;
-
-    RADEONConnectorFindMonitor(pScrn, output);
-#endif
     ErrorF("in RADEONProbeOutputModes\n");
 
     if (output->status == XF86OutputStatusConnected) {
@@ -167,18 +216,16 @@ RADEONProbeOutputModes(xf86OutputPtr output)
 		xf86OutputSetEDID (output, edid_mon);
 
 		modes = xf86OutputGetEDIDModes (output);
-		return modes;
-	    } else
-		/* add native panel mode */
+	    }
+	    if (modes == NULL) {
 		modes = RADEONFPNativeMode(output);
+		/* add the screen modes */
+		RADEONAddScreenModes(output, &modes);
+	    }
+	    return modes;
 	}
     }
 
-    if (modes) {
-	xf86ValidateModesUserConfig(pScrn, modes);
-	xf86PruneInvalidModes(pScrn, &modes, FALSE);
-    }
-
     return modes;
 }
 
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 6ece28a..a6da78e 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -154,6 +154,88 @@ static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color);
 static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn);
 static void RADEONGetTMDSInfoFromTable(xf86OutputPtr output);
 
+Bool
+RADEONDVOReadByte(I2CDevPtr dvo, int addr, CARD8 *ch)
+{
+    if (!xf86I2CReadByte(dvo, addr, ch)) {
+	xf86DrvMsg(dvo->pI2CBus->scrnIndex, X_ERROR,
+		   "Unable to read from %s Slave %d.\n",
+		   dvo->pI2CBus->BusName, dvo->SlaveAddr);
+	return FALSE;
+    }
+    return TRUE;
+}
+
+Bool
+RADEONDVOWriteByte(I2CDevPtr dvo, int addr, CARD8 ch)
+{
+    if (!xf86I2CWriteByte(dvo, addr, ch)) {
+	xf86DrvMsg(dvo->pI2CBus->scrnIndex, X_ERROR,
+		   "Unable to write to %s Slave %d.\n",
+		   dvo->pI2CBus->BusName, dvo->SlaveAddr);
+	return FALSE;
+    }
+    return TRUE;
+}
+
+static I2CDevPtr
+RADEONDVODeviceInit(I2CBusPtr b, I2CSlaveAddr addr)
+{
+    I2CDevPtr dvo;
+
+    dvo = xcalloc(1, sizeof(I2CDevRec));
+    if (dvo == NULL)
+	return NULL;
+
+    dvo->DevName = "RADEON DVO Controller";
+    dvo->SlaveAddr = addr;
+    dvo->pI2CBus = b;
+    dvo->StartTimeout = b->StartTimeout;
+    dvo->BitTimeout = b->BitTimeout;
+    dvo->AcknTimeout = b->AcknTimeout;
+    dvo->ByteTimeout = b->ByteTimeout;
+
+    if (xf86I2CDevInit(dvo)) {
+	return dvo;
+    }
+
+    xfree(dvo);
+    return NULL;
+}
+
+void
+RADEONRestoreDVOChip(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    if (!radeon_output->DVOChip)
+	return;
+
+    OUTREG(radeon_output->dvo_i2c_reg, INREG(radeon_output->dvo_i2c_reg) &
+	   (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1));
+
+    if (!RADEONInitExtTMDSInfoFromBIOS(output)) {
+	/* do mac stuff here */
+#if defined(__powerpc__)
+	if (radeon_output->DVOChip) {
+	    switch(info->MacModel) {
+	    case RADEON_MAC_POWERBOOK_DL:
+		RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x30);
+		RADEONDVOWriteByte(radeon_output->DVOChip, 0x09, 0x00);
+		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0a, 0x90);
+		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0c, 0x89);
+		RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x3b);
+		break;
+	    default:
+		break;
+	    }
+	}
+#endif
+    }
+}
+
 void RADEONPrintPortMap(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
@@ -658,7 +740,7 @@ radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
 	    pMode->VDisplay > radeon_output->PanelYRes)
 	    return MODE_PANEL;
     }
-    
+
     return MODE_OK;
 }
 
@@ -668,31 +750,27 @@ radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
+    radeon_output->Flags &= ~RADEON_USE_RMX;
+
+    /* decide if we are using RMX */
     if ((radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP)
 	&& radeon_output->rmx_type != RMX_OFF) {
 	xf86CrtcPtr crtc = output->crtc;
 	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
 
-	if ((mode->HDisplay < radeon_output->PanelXRes ||
-	     mode->VDisplay < radeon_output->PanelYRes) &&
-	    radeon_crtc->crtc_id == 0)
-	    adjusted_mode->Flags |= RADEON_USE_RMX;
-
-	if (adjusted_mode->Flags & RADEON_USE_RMX) {
-	    radeon_output->Flags |= RADEON_USE_RMX;
-	    if (radeon_output->MonType == MT_DFP) {
-		adjusted_mode->CrtcHTotal     = mode->CrtcHDisplay + radeon_output->HBlank;
-		adjusted_mode->CrtcHSyncStart = mode->CrtcHDisplay + radeon_output->HOverPlus;
-		adjusted_mode->CrtcHSyncEnd   = mode->CrtcHSyncStart + radeon_output->HSyncWidth;
-		adjusted_mode->CrtcVTotal     = mode->CrtcVDisplay + radeon_output->VBlank;
-		adjusted_mode->CrtcVSyncStart = mode->CrtcVDisplay + radeon_output->VOverPlus;
-		adjusted_mode->CrtcVSyncEnd   = mode->CrtcVSyncStart + radeon_output->VSyncWidth;
-		adjusted_mode->Clock          = radeon_output->DotClock;
-		adjusted_mode->Flags          = radeon_output->Flags;
-	    }
-	} else
-	    radeon_output->Flags &= ~RADEON_USE_RMX;
+	if (radeon_crtc->crtc_id == 0) {
+	    if (mode->HDisplay < radeon_output->PanelXRes ||
+		mode->VDisplay < radeon_output->PanelYRes)
+		radeon_output->Flags |= RADEON_USE_RMX;
+	}
+    }
 
+    /* update clock for LVDS always and DFP if RMX is active */
+    if ((radeon_output->MonType == MT_LCD) ||
+	((radeon_output->MonType == MT_DFP) &&
+	 (radeon_output->Flags & RADEON_USE_RMX))) {
+	adjusted_mode->Clock          = radeon_output->DotClock;
+	adjusted_mode->Flags          = radeon_output->Flags;
     }
 
     return TRUE;
@@ -787,6 +865,16 @@ static void RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save,
 			    RADEON_FP2_DVO_EN |
 			    RADEON_FP2_DVO_RATE_SEL_SDR);
 
+
+    /* XXX: these may be oem specific */
+    if (IS_R300_VARIANT) {
+	save->fp2_gen_cntl |= RADEON_FP2_PAD_FLOP_EN | R300_FP2_DVO_CLOCK_MODE_SINGLE;
+#if 0
+	if (mode->Clock > 165000)
+	    save->fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;
+#endif
+    }
+
     if (IsPrimary) {
         if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
             save->fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK;
@@ -1053,6 +1141,7 @@ radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 	    RADEONRestoreFPRegisters(pScrn, &info->ModeReg);
 	} else {
 	    ErrorF("restore FP2\n");
+	    RADEONRestoreDVOChip(pScrn, output);
 	    RADEONRestoreFP2Registers(pScrn, &info->ModeReg);
 	}
 	break;
@@ -2480,8 +2569,27 @@ void RADEONInitConnector(xf86OutputPtr output)
     }
 
     if (radeon_output->type == OUTPUT_DVI) {
+	I2CBusPtr pDVOBus;
 	radeon_output->rmx_type = RMX_OFF;
-	RADEONGetTMDSInfo(output);
+	if (radeon_output->TMDSType == TMDS_EXT) {
+#if defined(__powerpc__)
+	    radeon_output->dvo_i2c_reg = RADEON_GPIO_MONID;
+	    radeon_output->dvo_i2c_slave_addr = 0x70;
+#else
+	    if (!RADEONGetExtTMDSInfoFromBIOS(output)) {
+		radeon_output->dvo_i2c_reg = RADEON_GPIO_CRT2_DDC;
+		radeon_output->dvo_i2c_slave_addr = 0x70;
+	    }
+#endif
+	    if (RADEONI2CInit(pScrn, &pDVOBus, radeon_output->dvo_i2c_reg, "DVO")) {
+		radeon_output->DVOChip =
+		    RADEONDVODeviceInit(pDVOBus,
+					radeon_output->dvo_i2c_slave_addr);
+		if (!radeon_output->DVOChip)
+		    xfree(pDVOBus);
+	    }
+	} else
+	    RADEONGetTMDSInfo(output);
     }
 
     if (radeon_output->type == OUTPUT_STV ||
diff --git a/src/radeon_probe.c b/src/radeon_probe.c
index 207e537..5c7d16f 100644
--- a/src/radeon_probe.c
+++ b/src/radeon_probe.c
@@ -237,7 +237,9 @@ RADEONProbe(DriverPtr drv, int flags)
     Bool     foundScreen = FALSE;
     int      i;
 
+#ifndef XSERVER_LIBPCIACCESS
     if (!xf86GetPciVideoInfo()) return FALSE;
+#endif
 
     /* Collect unclaimed device sections for both driver names */
     nATIGDev    = xf86MatchDevice(ATI_NAME, &ATIGDevs);
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index ec895e4..dbd50d7 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -205,6 +205,11 @@ typedef struct _RADEONOutputPrivateRec {
     int               DotClock;
     RADEONTMDSPll     tmds_pll[4];
     RADEONRMXType     rmx_type;
+    /* dvo */
+    I2CDevPtr         DVOChip;
+    int               dvo_i2c_reg;
+    int               dvo_i2c_slave_addr;
+    Bool              dvo_duallink;
     /* TV out */
     TVStd             default_tvStd;
     TVStd             tvStd;
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 96adb22..2653339 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -780,7 +780,7 @@
 #       define RADEON_FP2_PANEL_FORMAT         (1 <<  3)
 #       define RADEON_FP2_DETECT_SENSE         (1 <<  8)
 #       define R200_FP2_SOURCE_SEL_MASK        (3 << 10)
-#       define R200_FP2_SOURCE_SEL_CRTC1       (0 <<  10)
+#       define R200_FP2_SOURCE_SEL_CRTC1       (0 << 10)
 #       define R200_FP2_SOURCE_SEL_CRTC2       (1 << 10)
 #       define R200_FP2_SOURCE_SEL_RMX         (2 << 10)
 #       define R200_FP2_SOURCE_SEL_TRANS_UNIT  (3 << 10)
@@ -796,6 +796,8 @@
 #       define RADEON_FP2_DVO_EN               (1 << 25)
 #       define RADEON_FP2_DVO_RATE_SEL_SDR     (1 << 26)
 #       define R200_FP2_DVO_RATE_SEL_SDR       (1 << 27)
+#       define R300_FP2_DVO_CLOCK_MODE_SINGLE  (1 << 28)
+#       define R300_FP2_DVO_DUAL_CHANNEL_EN    (1 << 29)
 #define RADEON_FP_H_SYNC_STRT_WID           0x02c4
 #define RADEON_FP_H2_SYNC_STRT_WID          0x03c4
 #define RADEON_FP_HORZ_STRETCH              0x028c
diff --git a/src/radeon_video.c b/src/radeon_video.c
index dca9695..26857a5 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -1213,9 +1213,11 @@ RADEONResetVideo(ScrnInfoPtr pScrn)
 
     xvAdjustment      = MAKE_ATOM("XV_DEBUG_ADJUSTMENT");
 
-    sprintf(tmp, "RXXX:%d.%d.%d", info->PciInfo->vendor, info->PciInfo->chipType, info->PciInfo->chipRev);
+    sprintf(tmp, "RXXX:%d.%d.%d", PCI_DEV_VENDOR_ID(info->PciInfo),
+	    PCI_DEV_DEVICE_ID(info->PciInfo), PCI_DEV_REVISION(info->PciInfo));
     pPriv->device_id = MAKE_ATOM(tmp);
-    sprintf(tmp, "PCI:%02d:%02d.%d", info->PciInfo->bus, info->PciInfo->device, info->PciInfo->func);
+    sprintf(tmp, "PCI:%02d:%02d.%d", PCI_DEV_BUS(info->PciInfo),
+	    PCI_DEV_DEV(info->PciInfo), PCI_DEV_FUNC(info->PciInfo));
     pPriv->location_id = MAKE_ATOM(tmp);
     sprintf(tmp, "INSTANCE:%d", pScrn->scrnIndex);
     pPriv->instance_id = MAKE_ATOM(tmp);