summaryrefslogtreecommitdiffstats
path: root/main/xf86-video-r128
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2015-03-17 09:17:24 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2015-03-17 11:01:25 +0000
commit94dcde212867ffcb3ee91b54fd3dedf51c184a7f (patch)
tree1dd929e26fff8d7c718bd90441b15fc103dc1b2f /main/xf86-video-r128
parentd50d348d94c23461442acf84c754e96476549b4a (diff)
downloadaports-94dcde212867ffcb3ee91b54fd3dedf51c184a7f.tar.bz2
aports-94dcde212867ffcb3ee91b54fd3dedf51c184a7f.tar.xz
main/xf86-video-r128: rebuild against xorg-server 1.17
Diffstat (limited to 'main/xf86-video-r128')
-rw-r--r--main/xf86-video-r128/APKBUILD21
-rw-r--r--main/xf86-video-r128/git-fixes.patch8804
2 files changed, 8820 insertions, 5 deletions
diff --git a/main/xf86-video-r128/APKBUILD b/main/xf86-video-r128/APKBUILD
index 233d2f209..495b36dc2 100644
--- a/main/xf86-video-r128/APKBUILD
+++ b/main/xf86-video-r128/APKBUILD
@@ -1,7 +1,7 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=xf86-video-r128
pkgver=6.9.2
-pkgrel=2
+pkgrel=3
pkgdesc="ATI Rage128 video driver"
url="http://xorg.freedesktop.org/"
arch="all"
@@ -11,15 +11,23 @@ depends=
makedepends="pkgconfig xorg-server-dev libxi-dev fontsproto randrproto
videoproto renderproto xineramaproto libdrm-dev xf86driproto glproto
mesa-dev expat-dev
+ util-macros autoconf automake libtool
"
-source="http://xorg.freedesktop.org/releases/individual/driver/$pkgname-$pkgver.tar.bz2"
+source="http://xorg.freedesktop.org/releases/individual/driver/$pkgname-$pkgver.tar.bz2
+ git-fixes.patch"
_builddir="$srcdir/$pkgname-$pkgver"
prepare() {
cd "$_builddir"
update_config_sub || return 1
+ for i in $source; do
+ case $i in
+ *.patch) msg $i; patch -p1 -i "$srcdir"/$i || return 1;;
+ esac
+ done
+ autoreconf -fi || return 1
}
build() {
@@ -40,6 +48,9 @@ package() {
rm "$pkgdir"/usr/lib/xorg/modules/*/*.la || return 1
install -Dm644 COPYING "$pkgdir"/usr/share/licenses/$pkgname/COPYING
}
-md5sums="2e906d856a1c477bde000254b142445c xf86-video-r128-6.9.2.tar.bz2"
-sha256sums="8b2d295f1842d07304a75da1cfb9bf139b320a6539970eaf8d5ecc010cd36ee0 xf86-video-r128-6.9.2.tar.bz2"
-sha512sums="7f8dc174ff8cff6d109a62610b255c3f3a99e6fbdc38373da3efb88a960a25fe3124dbdb6a9379de6b45edaedb3aae44a183a5604f80bbb488dbb98faebc2fb3 xf86-video-r128-6.9.2.tar.bz2"
+md5sums="2e906d856a1c477bde000254b142445c xf86-video-r128-6.9.2.tar.bz2
+4f1b508b64dd0435f1ab85c043bd531d git-fixes.patch"
+sha256sums="8b2d295f1842d07304a75da1cfb9bf139b320a6539970eaf8d5ecc010cd36ee0 xf86-video-r128-6.9.2.tar.bz2
+2139a1d3b12950f452b72f4d9b916143814789df5080cee03a1e0955421b1808 git-fixes.patch"
+sha512sums="7f8dc174ff8cff6d109a62610b255c3f3a99e6fbdc38373da3efb88a960a25fe3124dbdb6a9379de6b45edaedb3aae44a183a5604f80bbb488dbb98faebc2fb3 xf86-video-r128-6.9.2.tar.bz2
+00836925ffd54a7e51b4e9e4e29fddc6d5bf587ed456e758f44681a7f89b0d6a4b46b166ff22627407fc3d97d49ed4e2d313d4ec67990b9f249f8ee734ccd4e5 git-fixes.patch"
diff --git a/main/xf86-video-r128/git-fixes.patch b/main/xf86-video-r128/git-fixes.patch
new file mode 100644
index 000000000..c37227d9c
--- /dev/null
+++ b/main/xf86-video-r128/git-fixes.patch
@@ -0,0 +1,8804 @@
+From d5da29d2ff94c80c8edefd6ccf5fd05fc6018870 Mon Sep 17 00:00:00 2001
+From: Tormod Volden <debian.tormod@gmail.com>
+Date: Fri, 25 Oct 2013 20:31:05 +0200
+Subject: Do not use int10 or VBE on powerpc
+
+VBE was already skipped in the normal path, but not when setting
+the PROBE_DETECT flag.
+
+Should avoid bus error seen in
+http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=622606 and
+http://lists.x.org/archives/xorg/2012-February/053969.html
+
+Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ src/r128_driver.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index 72d9e3c..6acdf2d 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -1758,8 +1758,8 @@ static Bool R128PreInitCursor(ScrnInfoPtr pScrn)
+ static Bool R128PreInitInt10(ScrnInfoPtr pScrn, xf86Int10InfoPtr *ppInt10)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+-#if 1 && !defined(__alpha__)
+- /* int10 is broken on some Alphas */
++#if !defined(__powerpc__) && !defined(__alpha__)
++ /* int10 is broken on some Alphas and powerpc */
+ if (xf86LoadSubModule(pScrn, "int10")) {
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n");
+ *ppInt10 = xf86InitInt10(info->pEnt->index);
+@@ -1890,11 +1890,14 @@ static void
+ R128ProbeDDC(ScrnInfoPtr pScrn, int indx)
+ {
+ vbeInfoPtr pVbe;
++
++#if !defined(__powerpc__) && !defined(__alpha__) && !defined(__sparc__)
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ pVbe = VBEInit(NULL,indx);
+ ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
+ vbeFree(pVbe);
+ }
++#endif
+ }
+
+ /* R128PreInit is called once at server startup. */
+--
+2.2.2
+
+
+From d757fe10b9ce9493ef3cf854bc03088366aa7256 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Fri, 22 Nov 2013 22:55:59 -0800
+Subject: Drop dependence on xf86PciInfo.h
+
+It is about time we stop using this deprecated file and include pciids
+locally.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ src/r128_dri.c | 1 -
+ src/r128_driver.c | 1 -
+ src/r128_probe.c | 2 --
+ src/r128_probe.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 50 insertions(+), 4 deletions(-)
+
+diff --git a/src/r128_dri.c b/src/r128_dri.c
+index 67e8d1d..ff7bbc2 100644
+--- a/src/r128_dri.c
++++ b/src/r128_dri.c
+@@ -53,7 +53,6 @@
+
+ /* X and server generic header files */
+ #include "xf86.h"
+-#include "xf86PciInfo.h"
+ #include "windowstr.h"
+
+ #include "shadowfb.h"
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index 6acdf2d..04a4537 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -84,7 +84,6 @@
+ /* X and server generic header files */
+ #include "xf86.h"
+ #include "xf86_OSproc.h"
+-#include "xf86PciInfo.h"
+ #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
+ #include "xf86RAC.h"
+ #include "xf86Resources.h"
+diff --git a/src/r128_probe.c b/src/r128_probe.c
+index 7f1fbda..12e0c1c 100644
+--- a/src/r128_probe.c
++++ b/src/r128_probe.c
+@@ -43,8 +43,6 @@
+ #include "atipcirename.h"
+
+ #include "xf86.h"
+-#include "xf86PciInfo.h"
+-
+
+ #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
+ #include "xf86Resources.h"
+diff --git a/src/r128_probe.h b/src/r128_probe.h
+index 41fc0e4..7b55e71 100644
+--- a/src/r128_probe.h
++++ b/src/r128_probe.h
+@@ -38,6 +38,56 @@
+
+ #include "xf86str.h"
+
++/* Chip definitions */
++#define PCI_VENDOR_ATI 0x1002
++#define PCI_CHIP_RAGE128LE 0x4C45
++#define PCI_CHIP_RAGE128LF 0x4C46
++#define PCI_CHIP_RAGE128MF 0x4D46
++#define PCI_CHIP_RAGE128ML 0x4D4C
++#define PCI_CHIP_RAGE128PA 0x5041
++#define PCI_CHIP_RAGE128PB 0x5042
++#define PCI_CHIP_RAGE128PC 0x5043
++#define PCI_CHIP_RAGE128PD 0x5044
++#define PCI_CHIP_RAGE128PE 0x5045
++#define PCI_CHIP_RAGE128PF 0x5046
++#define PCI_CHIP_RAGE128PG 0x5047
++#define PCI_CHIP_RAGE128PH 0x5048
++#define PCI_CHIP_RAGE128PI 0x5049
++#define PCI_CHIP_RAGE128PJ 0x504A
++#define PCI_CHIP_RAGE128PK 0x504B
++#define PCI_CHIP_RAGE128PL 0x504C
++#define PCI_CHIP_RAGE128PM 0x504D
++#define PCI_CHIP_RAGE128PN 0x504E
++#define PCI_CHIP_RAGE128PO 0x504F
++#define PCI_CHIP_RAGE128PP 0x5050
++#define PCI_CHIP_RAGE128PQ 0x5051
++#define PCI_CHIP_RAGE128PR 0x5052
++#define PCI_CHIP_RAGE128PS 0x5053
++#define PCI_CHIP_RAGE128PT 0x5054
++#define PCI_CHIP_RAGE128PU 0x5055
++#define PCI_CHIP_RAGE128PV 0x5056
++#define PCI_CHIP_RAGE128PW 0x5057
++#define PCI_CHIP_RAGE128PX 0x5058
++#define PCI_CHIP_RAGE128RE 0x5245
++#define PCI_CHIP_RAGE128RF 0x5246
++#define PCI_CHIP_RAGE128RG 0x5247
++#define PCI_CHIP_RAGE128RK 0x524B
++#define PCI_CHIP_RAGE128RL 0x524C
++#define PCI_CHIP_RAGE128SE 0x5345
++#define PCI_CHIP_RAGE128SF 0x5346
++#define PCI_CHIP_RAGE128SG 0x5347
++#define PCI_CHIP_RAGE128SH 0x5348
++#define PCI_CHIP_RAGE128SK 0x534B
++#define PCI_CHIP_RAGE128SL 0x534C
++#define PCI_CHIP_RAGE128SM 0x534D
++#define PCI_CHIP_RAGE128SN 0x534E
++#define PCI_CHIP_RAGE128TF 0x5446
++#define PCI_CHIP_RAGE128TL 0x544C
++#define PCI_CHIP_RAGE128TR 0x5452
++#define PCI_CHIP_RAGE128TS 0x5453
++#define PCI_CHIP_RAGE128TT 0x5454
++#define PCI_CHIP_RAGE128TU 0x5455
++
+ extern DriverRec R128;
+
+ typedef struct
+--
+2.2.2
+
+
+From 35dc7faf9f87332f51ff0a6aa866a56eb017a950 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Thu, 21 Nov 2013 22:09:57 -0800
+Subject: Do not disable gouraud shading for a render op
+
+The EXA Composite hooks should not overwrite any register values
+expected by DRI. Initial testing of the EXA support revealed that
+R128_WINDOW_XY_OFFSET is one register where we have to be careful.
+However, it was mostly tested using glxgears which does not stress the
+driver very much. Going through the various 3D screensavers one by one
+reveals a bug where certain models turn green if compositing is enabled.
+
+It seems that if we slightly alter the values passed to R128_SETUP_CNTL
+and R128_PM4_VC_FPU_SETUP, the 3D driver will be happy and compositing
+will still work. The proper way would be to constantly save and restore
+register values but this showed poor performance when dragging 3D
+windows across the screen.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ src/r128_exa_render.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/r128_exa_render.c b/src/r128_exa_render.c
+index f00536e..cb9f929 100644
+--- a/src/r128_exa_render.c
++++ b/src/r128_exa_render.c
+@@ -350,7 +350,7 @@ do { \
+ R128_TEX_MAP_ALPHA_IN_TEXTURE | \
+ R128_TEX_CACHE_LINE_SIZE_4QW); \
+ OUT_RING_REG(R128_SETUP_CNTL, \
+- R128_COLOR_SOLID_COLOR | \
++ R128_COLOR_GOURAUD | \
+ R128_PRIM_TYPE_TRI | \
+ R128_TEXTURE_ST_MULT_W | \
+ R128_STARTING_VERTEX_1 | \
+@@ -358,9 +358,9 @@ do { \
+ R128_SUB_PIX_4BITS); \
+ OUT_RING_REG(R128_PM4_VC_FPU_SETUP, \
+ R128_FRONT_DIR_CCW | \
+- R128_BACKFACE_CULL | \
++ R128_BACKFACE_SOLID | \
+ R128_FRONTFACE_SOLID | \
+- R128_FPU_COLOR_SOLID | \
++ R128_FPU_COLOR_GOURAUD | \
+ R128_FPU_SUB_PIX_4BITS | \
+ R128_FPU_MODE_3D | \
+ R128_TRAP_BITS_DISABLE | \
+--
+2.2.2
+
+
+From 9eb693640136bc8bcbe706d642519b4eb23286d4 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Wed, 27 Nov 2013 18:14:43 -0800
+Subject: Only declare PCITAG if we need it
+
+If libpciaccess is available, we do not need to declare the deprecated
+PciTag member because it will not be used.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ src/r128.h | 2 ++
+ src/r128_driver.c | 7 ++++---
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/src/r128.h b/src/r128.h
+index 90071b4..ee0b1d4 100644
+--- a/src/r128.h
++++ b/src/r128.h
+@@ -301,7 +301,9 @@ struct r128_2d_state {
+ typedef struct {
+ EntityInfoPtr pEnt;
+ pciVideoPtr PciInfo;
++#ifndef XSERVER_LIBPCIACCESS
+ PCITAG PciTag;
++#endif
+ int Chipset;
+ Bool Primary;
+
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index 04a4537..0a0b82b 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -1957,9 +1957,6 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
+ }
+
+ info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
+- info->PciTag = pciTag(PCI_DEV_BUS(info->PciInfo),
+- PCI_DEV_DEV(info->PciInfo),
+- PCI_DEV_FUNC(info->PciInfo));
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "PCI bus %d card %d func %d\n",
+@@ -1968,6 +1965,10 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
+ PCI_DEV_FUNC(info->PciInfo));
+
+ #ifndef XSERVER_LIBPCIACCESS
++ info->PciTag = pciTag(PCI_DEV_BUS(info->PciInfo),
++ PCI_DEV_DEV(info->PciInfo),
++ PCI_DEV_FUNC(info->PciInfo));
++
+ if (xf86RegisterResources(info->pEnt->index, 0, ResNone)) goto fail;
+ if (xf86SetOperatingState(resVga, info->pEnt->index, ResUnusedOpr)) goto fail;
+
+--
+2.2.2
+
+
+From 5ef5812a7a272aa08543cfd9b633f33c35e34dbd Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Tue, 4 Mar 2014 01:43:00 -0800
+Subject: Remove overuse of COMPOSITE_SETUP()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+COMPOSITE_SETUP() involves expensive register writes so
+R128EnterServer() should call it once when there are 3D windows and 0
+times when there are no 3D windows.
+
+Instead the code was calling it once when there were no 3D windows and
+arbitrarily many times when there were 3D windows.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
+---
+ src/r128_dri.c | 6 +++++-
+ src/r128_exa_render.c | 7 +------
+ 2 files changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/src/r128_dri.c b/src/r128_dri.c
+index ff7bbc2..2c905a4 100644
+--- a/src/r128_dri.c
++++ b/src/r128_dri.c
+@@ -308,7 +308,11 @@ static void R128EnterServer(ScreenPtr pScreen)
+ #endif
+ #ifdef USE_EXA
+ if (info->ExaDriver) exaMarkSync(pScreen);
+- info->state_2d.composite_setup = FALSE;
++ /* EXA and DRI are fighting over control of the texture hardware.
++ * That means we need to setup compositing when the server wakes
++ * up if a 3D app is running.
++ */
++ if (info->have3DWindows) info->state_2d.composite_setup = FALSE;
+ #endif
+ }
+
+diff --git a/src/r128_exa_render.c b/src/r128_exa_render.c
+index cb9f929..f00daf7 100644
+--- a/src/r128_exa_render.c
++++ b/src/r128_exa_render.c
+@@ -458,12 +458,7 @@ R128CCEPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+
+ if (!info->state_2d.composite_setup) {
+ COMPOSITE_SETUP();
+- /* DRI and EXA are fighting over control of the texture hardware.
+- * That means we need to set up the compositing hardware every time
+- * while a 3D app is running and once after it closes.
+- */
+- if (!info->have3DWindows)
+- info->state_2d.composite_setup = TRUE;
++ info->state_2d.composite_setup = TRUE;
+ }
+
+ /* We cannot guarantee that this register will stay zero - DRI needs it too. */
+--
+2.2.2
+
+
+From 4efc87f41d770c753ddf7f54fe334b6dbd7daf79 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Mon, 28 Apr 2014 21:26:44 -0700
+Subject: Fix ScreenInit with noAccel
+
+Now that EXA is on by default, we must remember to turn it off again if
+acceleration is disabled.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+---
+ src/r128_driver.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index 0a0b82b..f425c3b 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -2314,6 +2314,7 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
+ miSetPixmapDepths ();
+
+ noAccel = xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE);
++ if (noAccel) info->useEXA = FALSE;
+
+ #ifdef R128DRI
+ /* Setup DRI after visuals have been
+--
+2.2.2
+
+
+From 3ed5035074540785f820906529fcce3148e0b387 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Wed, 2 Jul 2014 02:18:48 -0700
+Subject: Port to RandR
+
+This rearranges the r128 code to use the Crtc and Output interfaces
+which should make the driver easier to maintain in the long run. User
+visible changes include DDC detection working in more cases and the
+ability to have multiple monitors with DRI.
+
+Some choices have been made to conserve memory. Modes can be switched up
+to the highest resolution in xorg.conf. If this is 1024x768 for example,
+the front buffer will be 1024x768 instead of 1024x1024. This means 90
+and 270 degree rotations will not work. However, scalings, reflection
+and 180 degree rotations can be set with the xrandr client program.
+Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=75629
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ configure.ac | 2 +-
+ src/Makefile.am | 3 +-
+ src/r128.h | 48 +-
+ src/r128_crtc.c | 476 ++++++++++++++++++++
+ src/r128_cursor.c | 294 ++++++------
+ src/r128_driver.c | 1287 +++++++++++------------------------------------------
+ src/r128_output.c | 465 +++++++++++++++++++
+ src/r128_probe.c | 1 -
+ src/r128_probe.h | 79 ++++
+ src/r128_video.c | 17 +-
+ 10 files changed, 1479 insertions(+), 1193 deletions(-)
+ create mode 100644 src/r128_crtc.c
+ create mode 100644 src/r128_output.c
+
+diff --git a/configure.ac b/configure.ac
+index 56554ec..3cc3113 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -76,7 +76,7 @@ XORG_DRIVER_CHECK_EXT(XF86MISC, xf86miscproto)
+ XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
+
+ # Obtain compiler/linker options for the driver dependencies
+-PKG_CHECK_MODULES(XORG, [xorg-server >= 1.2 xproto fontsproto $REQUIRED_MODULES])
++PKG_CHECK_MODULES(XORG, [xorg-server >= 1.3 xproto fontsproto $REQUIRED_MODULES])
+ PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1],
+ HAVE_XEXTPROTO_71="yes"; AC_DEFINE(HAVE_XEXTPROTO_71, 1, [xextproto 7.1 available]),
+ HAVE_XEXTPROTO_71="no")
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 23e6c49..e4618ea 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -41,7 +41,8 @@ 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_EXA_SRCS) $(R128_DRI_SRCS)
++ r128_video.c r128_misc.c r128_crtc.c r128_output.c r128_probe.c \
++ $(R128_EXA_SRCS) $(R128_DRI_SRCS)
+
+ EXTRA_DIST = \
+ compat-api.h \
+diff --git a/src/r128.h b/src/r128.h
+index ee0b1d4..fe757f8 100644
+--- a/src/r128.h
++++ b/src/r128.h
+@@ -74,6 +74,7 @@
+ #endif
+
+ #include "fb.h"
++#include "xf86Crtc.h"
+
+ #include "compat-api.h"
+ #include "atipcirename.h"
+@@ -260,16 +261,6 @@ typedef struct {
+ DisplayModePtr mode;
+ } R128FBLayout;
+
+-typedef enum
+-{
+- MT_NONE,
+- MT_CRT,
+- MT_LCD,
+- MT_DFP,
+- MT_CTV,
+- MT_STV
+-} R128MonitorType;
+-
+ #ifdef USE_EXA
+ struct r128_2d_state {
+ Bool in_use;
+@@ -523,10 +514,10 @@ typedef struct {
+
+ Bool isDFP;
+ Bool isPro2;
+- I2CBusPtr pI2CBus;
+- CARD32 DDCReg;
++ Bool DDC;
+
+ Bool VGAAccess;
++ R128BIOSConnector BiosConnector[R128_MAX_BIOS_CONNECTOR];
+
+ /****** Added for dualhead support *******************/
+ BOOL HasCRTC2; /* M3/M4 */
+@@ -562,6 +553,39 @@ extern int R128MinBits(int val);
+
+ extern void R128InitVideo(ScreenPtr pScreen);
+
++extern void R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info);
++extern void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, DisplayModePtr mode, R128InfoPtr info);
++extern Bool R128InitCrtcBase(xf86CrtcPtr crtc, R128SavePtr save, int x, int y);
++extern Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save, DisplayModePtr mode, R128InfoPtr info);
++extern void R128InitPLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, double dot_clock);
++extern Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, R128InfoPtr info, DisplayModePtr mode);
++extern Bool R128InitCrtc2Base(xf86CrtcPtr crtc, R128SavePtr save, int x, int y);
++extern Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save, DisplayModePtr mode, R128InfoPtr info);
++extern void R128InitPLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, double dot_clock);
++extern Bool R128InitDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, R128InfoPtr info, DisplayModePtr mode);
++extern void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
++extern void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
++extern void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
++extern void R128RestorePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
++extern void R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
++extern void R128RestoreCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr restore);
++extern void R128RestorePLL2Registers(ScrnInfoPtr pScrn, R128SavePtr restore);
++extern void R128RestoreDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr restore);
++
++extern void r128_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg);
++extern void r128_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y);
++extern void r128_crtc_show_cursor(xf86CrtcPtr crtc);
++extern void r128_crtc_hide_cursor(xf86CrtcPtr crtc);
++extern void r128_crtc_load_cursor_image(xf86CrtcPtr crtc, unsigned char *src);
++
++extern Bool R128SetupConnectors(ScrnInfoPtr pScrn);
++extern Bool R128AllocateControllers(ScrnInfoPtr pScrn, int mask);
++extern void R128Blank(ScrnInfoPtr pScrn);
++extern void R128Unblank(ScrnInfoPtr pScrn);
++extern void R128DPMSSetOn(xf86OutputPtr output);
++extern void R128DPMSSetOff(xf86OutputPtr output);
++extern DisplayModePtr R128ProbeOutputModes(xf86OutputPtr output);
++
+ #ifdef R128DRI
+ extern Bool R128DRIScreenInit(ScreenPtr pScreen);
+ extern void R128DRICloseScreen(ScreenPtr pScreen);
+diff --git a/src/r128_crtc.c b/src/r128_crtc.c
+new file mode 100644
+index 0000000..35e1fee
+--- /dev/null
++++ b/src/r128_crtc.c
+@@ -0,0 +1,476 @@
++/*
++ * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
++ * VA Linux Systems Inc., Fremont, California.
++ *
++ * All Rights Reserved.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation on 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
++ * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
++ * THEIR SUPPLIERS 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.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include <string.h>
++#include <stdio.h>
++
++#include "xf86.h"
++#include "xf86Modes.h"
++
++#include "r128.h"
++#include "r128_probe.h"
++#include "r128_reg.h"
++
++static void r128_crtc_load_lut(xf86CrtcPtr crtc);
++
++static void r128_crtc_dpms(xf86CrtcPtr crtc, int mode)
++{
++ int mask;
++ ScrnInfoPtr pScrn = crtc->scrn;
++ R128InfoPtr info = R128PTR(pScrn);
++ unsigned char *R128MMIO = info->MMIO;
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
++
++ /* XXX: The HSYNC and VSYNC bits for CRTC2 don't exist on the r128? */
++ mask = r128_crtc->crtc_id ? R128_CRTC2_DISP_DIS : (R128_CRTC_DISPLAY_DIS | R128_CRTC_HSYNC_DIS | R128_CRTC_VSYNC_DIS);
++
++ switch (mode) {
++ case DPMSModeOn:
++ if (r128_crtc->crtc_id) {
++ OUTREGP(R128_CRTC2_GEN_CNTL, 0, ~mask);
++ } else {
++ OUTREGP(R128_CRTC_EXT_CNTL, 0, ~mask);
++ }
++ break;
++ case DPMSModeStandby:
++ if (r128_crtc->crtc_id) {
++ OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_DISP_DIS, ~mask);
++ } else {
++ OUTREGP(R128_CRTC_EXT_CNTL, (R128_CRTC_DISPLAY_DIS | R128_CRTC_HSYNC_DIS), ~mask);
++ }
++ break;
++ case DPMSModeSuspend:
++ if (r128_crtc->crtc_id) {
++ OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_DISP_DIS, ~mask);
++ } else {
++ OUTREGP(R128_CRTC_EXT_CNTL, (R128_CRTC_DISPLAY_DIS | R128_CRTC_VSYNC_DIS), ~mask);
++ }
++ break;
++ case DPMSModeOff:
++ if (r128_crtc->crtc_id) {
++ OUTREGP(R128_CRTC2_GEN_CNTL, mask, ~mask);
++ } else {
++ OUTREGP(R128_CRTC_EXT_CNTL, mask, ~mask);
++ }
++ break;
++ }
++
++ if (mode != DPMSModeOff)
++ r128_crtc_load_lut(crtc);
++}
++
++void r128_crtc_load_lut(xf86CrtcPtr crtc)
++{
++ ScrnInfoPtr pScrn = crtc->scrn;
++ R128InfoPtr info = R128PTR(pScrn);
++ unsigned char *R128MMIO = info->MMIO;
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
++ int i;
++
++ if (!crtc->enabled)
++ return;
++
++ PAL_SELECT(r128_crtc->crtc_id);
++
++ for (i = 0; i < 256; i++) {
++ OUTPAL(i, r128_crtc->lut_r[i], r128_crtc->lut_g[i], r128_crtc->lut_b[i]);
++ }
++}
++
++static Bool r128_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjusted_mode)
++{
++ return TRUE;
++}
++
++static void r128_crtc_mode_prepare(xf86CrtcPtr crtc)
++{
++ r128_crtc_dpms(crtc, DPMSModeOff);
++}
++
++static void r128_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjusted_mode, int x, int y)
++{
++ ScrnInfoPtr pScrn = crtc->scrn;
++ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
++ R128InfoPtr info = R128PTR(pScrn);
++ R128OutputType otype = OUTPUT_NONE;
++
++ double dot_clock = adjusted_mode->Clock / 1000.0;
++ int i;
++
++ if (r128_crtc->cursor_offset) r128_crtc_hide_cursor(crtc);
++ xf86PrintModeline(pScrn->scrnIndex, adjusted_mode);
++ R128InitCommonRegisters(&info->ModeReg, info);
++
++ for (i = 0; i < xf86_config->num_output; i++) {
++ xf86OutputPtr output = xf86_config->output[i];
++ R128OutputPrivatePtr r128_output = output->driver_private;
++
++ if (output->crtc == crtc)
++ otype = r128_output->type;
++ }
++
++ switch (r128_crtc->crtc_id) {
++ case 0:
++ R128InitCrtcRegisters(pScrn, &info->ModeReg, adjusted_mode, info);
++ R128InitCrtcBase(crtc, &info->ModeReg, x, y);
++ if (dot_clock) {
++ R128InitPLLRegisters(pScrn, &info->ModeReg, &info->pll, dot_clock);
++ R128InitDDARegisters(pScrn, &info->ModeReg, &info->pll, info, adjusted_mode);
++ } else {
++ info->ModeReg.ppll_ref_div = info->SavedReg.ppll_ref_div;
++ info->ModeReg.ppll_div_3 = info->SavedReg.ppll_div_3;
++ info->ModeReg.htotal_cntl = info->SavedReg.htotal_cntl;
++ info->ModeReg.dda_config = info->SavedReg.dda_config;
++ info->ModeReg.dda_on_off = info->SavedReg.dda_on_off;
++ }
++ break;
++ case 1:
++ R128InitCrtc2Registers(pScrn, &info->ModeReg, adjusted_mode, info);
++ R128InitCrtc2Base(crtc, &info->ModeReg, x, y);
++ if (dot_clock) {
++ R128InitPLL2Registers(pScrn, &info->ModeReg, &info->pll, dot_clock);
++ R128InitDDA2Registers(pScrn, &info->ModeReg, &info->pll, info, adjusted_mode);
++ }
++ break;
++ }
++
++ if (otype == OUTPUT_DVI || otype == OUTPUT_LVDS)
++ R128InitFPRegisters(&info->SavedReg, &info->ModeReg, adjusted_mode, info);
++ R128RestoreCommonRegisters(pScrn, &info->ModeReg);
++
++ switch (r128_crtc->crtc_id) {
++ case 0:
++ R128RestoreDDARegisters(pScrn, &info->ModeReg);
++ R128RestoreCrtcRegisters(pScrn, &info->ModeReg);
++ R128RestorePLLRegisters(pScrn, &info->ModeReg);
++ break;
++ case 1:
++ R128RestoreDDA2Registers(pScrn, &info->ModeReg);
++ R128RestoreCrtc2Registers(pScrn, &info->ModeReg);
++ R128RestorePLL2Registers(pScrn, &info->ModeReg);
++ break;
++ }
++
++ if (otype == OUTPUT_DVI || otype == OUTPUT_LVDS)
++ R128RestoreFPRegisters(pScrn, &info->ModeReg);
++
++ /* XXX: InitFPRegisters looks similar to radeon's InitRMXRegisters so
++ * maybe it should be called from mode_set in the output code.
++ */
++ if (r128_crtc->cursor_offset) r128_crtc_show_cursor(crtc);
++}
++
++static void r128_crtc_mode_commit(xf86CrtcPtr crtc)
++{
++ r128_crtc_dpms(crtc, DPMSModeOn);
++}
++
++static void r128_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, int size)
++{
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
++ int i;
++
++ for (i = 0; i < 256; i++) {
++ r128_crtc->lut_r[i] = red[i] >> 8;
++ r128_crtc->lut_g[i] = green[i] >> 8;
++ r128_crtc->lut_b[i] = blue[i] >> 8;
++ }
++
++ r128_crtc_load_lut(crtc);
++}
++
++static Bool r128_crtc_lock(xf86CrtcPtr crtc)
++{
++ ScrnInfoPtr pScrn = crtc->scrn;
++ ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
++ R128InfoPtr info = R128PTR(pScrn);
++
++#ifdef HAVE_XAA_H
++ if (info->accel) info->accel->Sync(pScrn);
++#endif
++#ifdef USE_EXA
++ if (info->ExaDriver) exaWaitSync(pScreen);
++#endif
++
++ return FALSE;
++}
++
++static void r128_crtc_unlock(xf86CrtcPtr crtc)
++{
++ ScrnInfoPtr pScrn = crtc->scrn;
++ ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
++ R128InfoPtr info = R128PTR(pScrn);
++
++#ifdef HAVE_XAA_H
++ if (info->accel) info->accel->Sync(pScrn);
++#endif
++#ifdef USE_EXA
++ if (info->ExaDriver) exaWaitSync(pScreen);
++#endif
++}
++
++#ifdef HAVE_XAA_H
++static FBLinearPtr r128_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length, int granularity,
++ MoveLinearCallbackProcPtr moveCB,
++ RemoveLinearCallbackProcPtr removeCB,
++ pointer privData)
++{
++ FBLinearPtr linear;
++ int max_size;
++
++ linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, removeCB, privData);
++ if (linear != NULL) return linear;
++
++ /* The above allocation did not succeed, so purge unlocked stuff and try again. */
++ xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity, PRIORITY_EXTREME);
++
++ if (max_size < length) return NULL;
++ xf86PurgeUnlockedOffscreenAreas(pScreen);
++
++ linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, removeCB, privData);
++ return linear;
++}
++#endif
++
++static void *r128_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
++{
++ ScrnInfoPtr pScrn = crtc->scrn;
++ ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
++ R128InfoPtr info = R128PTR(pScrn);
++
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
++ unsigned long rotate_offset = 0;
++ unsigned long rotate_pitch;
++ int cpp = pScrn->bitsPerPixel / 8;
++ int align = 4096;
++ int size;
++
++ rotate_pitch = pScrn->displayWidth * cpp;
++ size = rotate_pitch * height;
++
++#ifdef USE_EXA
++ if (info->ExaDriver) {
++ assert(r128_crtc->rotate_mem_exa == NULL);
++ r128_crtc->rotate_mem_exa = exaOffscreenAlloc(pScreen, size, align, TRUE, NULL, NULL);
++
++ if (r128_crtc->rotate_mem_exa == NULL) {
++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
++ "Couldn't allocate shadow memory for rotated CRTC\n");
++ return NULL;
++ }
++
++ rotate_offset = r128_crtc->rotate_mem_exa->offset;
++ }
++#endif
++#ifdef HAVE_XAA_H
++ if (info->accel) {
++ size = (size + cpp - 1) / cpp;
++ align = (align + cpp - 1) / cpp;
++
++ assert(r128_crtc->rotate_mem_xaa == NULL);
++ r128_crtc->rotate_mem_xaa = r128_xf86AllocateOffscreenLinear(pScreen, size, align, NULL, NULL, NULL);
++
++ if (r128_crtc->rotate_mem_exa == NULL) {
++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
++ "Couldn't allocate shadow memory for rotated CRTC\n");
++ return NULL;
++ }
++
++ rotate_offset = r128_crtc->rotate_mem_xaa->offset * cpp;
++ }
++#endif
++
++ /* If allocations failed or if there was no accel. */
++ if (rotate_offset == 0)
++ return NULL;
++
++ return info->FB + rotate_offset;
++}
++
++static PixmapPtr r128_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
++{
++ ScrnInfoPtr pScrn = crtc->scrn;
++ PixmapPtr rotate_pixmap;
++ unsigned long rotate_pitch;
++ int cpp = pScrn->bitsPerPixel / 8;
++
++ if (!data) data = r128_crtc_shadow_allocate(crtc, width, height);
++
++ rotate_pitch = pScrn->displayWidth * cpp;
++ rotate_pixmap = GetScratchPixmapHeader(xf86ScrnToScreen(pScrn),
++ width, height,
++ pScrn->depth,
++ pScrn->bitsPerPixel,
++ rotate_pitch,
++ data);
++
++ if (rotate_pixmap == NULL) {
++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
++ "Couldn't allocate shadow memory for rotated CRTC\n");
++ return NULL;
++ }
++
++ return rotate_pixmap;
++}
++
++static void r128_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
++{
++ ScrnInfoPtr pScrn = crtc->scrn;
++ ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
++ R128InfoPtr info = R128PTR(pScrn);
++
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
++
++ if (rotate_pixmap) FreeScratchPixmapHeader(rotate_pixmap);
++
++ if (data) {
++#ifdef USE_EXA
++ if (info->ExaDriver && r128_crtc->rotate_mem_exa != NULL) {
++ exaOffscreenFree(pScreen, r128_crtc->rotate_mem_exa);
++ r128_crtc->rotate_mem_exa = NULL;
++ }
++#endif
++#ifdef HAVE_XAA_H
++ if (info->accel) {
++ xf86FreeOffscreenLinear(r128_crtc->rotate_mem_xaa);
++ r128_crtc->rotate_mem_xaa = NULL;
++ }
++#endif
++ }
++}
++
++static const xf86CrtcFuncsRec r128_crtc_funcs = {
++ .dpms = r128_crtc_dpms,
++ .save = NULL,
++ .restore = NULL,
++ .mode_fixup = r128_crtc_mode_fixup,
++ .prepare = r128_crtc_mode_prepare,
++ .mode_set = r128_crtc_mode_set,
++ .commit = r128_crtc_mode_commit,
++ .gamma_set = r128_crtc_gamma_set,
++ .lock = r128_crtc_lock,
++ .unlock = r128_crtc_unlock,
++ .shadow_create = r128_crtc_shadow_create,
++ .shadow_allocate = r128_crtc_shadow_allocate,
++ .shadow_destroy = r128_crtc_shadow_destroy,
++ .set_cursor_colors = r128_crtc_set_cursor_colors,
++ .set_cursor_position = r128_crtc_set_cursor_position,
++ .show_cursor = r128_crtc_show_cursor,
++ .hide_cursor = r128_crtc_hide_cursor,
++ .load_cursor_image = r128_crtc_load_cursor_image,
++ .destroy = NULL,
++};
++
++Bool R128AllocateControllers(ScrnInfoPtr pScrn, int mask)
++{
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
++ R128InfoPtr info = R128PTR(pScrn);
++
++ if (mask & 1) {
++ if (pR128Ent->Controller[0])
++ return TRUE;
++
++ pR128Ent->pCrtc[0] = xf86CrtcCreate(pScrn, &r128_crtc_funcs);
++ if (!pR128Ent->pCrtc[0])
++ return FALSE;
++
++ pR128Ent->Controller[0] = xnfcalloc(sizeof(R128CrtcPrivateRec), 1);
++ if (!pR128Ent->Controller[0])
++ return FALSE;
++
++ pR128Ent->pCrtc[0]->driver_private = pR128Ent->Controller[0];
++ pR128Ent->Controller[0]->crtc_id = 0;
++ }
++
++ if (mask & 2) {
++ if (!info->HasCRTC2)
++ return TRUE;
++
++ pR128Ent->pCrtc[1] = xf86CrtcCreate(pScrn, &r128_crtc_funcs);
++ if (!pR128Ent->pCrtc[1])
++ return FALSE;
++
++ pR128Ent->Controller[1] = xnfcalloc(sizeof(R128CrtcPrivateRec), 1);
++ if (!pR128Ent->Controller[1]) {
++ free(pR128Ent->Controller[0]);
++ return FALSE;
++ }
++
++ pR128Ent->pCrtc[1]->driver_private = pR128Ent->Controller[1];
++ pR128Ent->Controller[1]->crtc_id = 1;
++ }
++
++ return TRUE;
++}
++
++void R128Blank(ScrnInfoPtr pScrn)
++{
++ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
++ xf86OutputPtr output;
++ xf86CrtcPtr crtc;
++ int o, c;
++
++ for (c = 0; c < xf86_config->num_crtc; c++) {
++ crtc = xf86_config->crtc[c];
++ for (o = 0; o < xf86_config->num_output; o++) {
++ output = xf86_config->output[o];
++ if (output->crtc != crtc)
++ continue;
++
++ output->funcs->dpms(output, DPMSModeOff);
++ }
++ crtc->funcs->dpms(crtc, DPMSModeOff);
++ }
++}
++
++void R128Unblank(ScrnInfoPtr pScrn)
++{
++ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
++ xf86OutputPtr output;
++ xf86CrtcPtr crtc;
++ int o, c;
++
++ for (c = 0; c < xf86_config->num_crtc; c++) {
++ crtc = xf86_config->crtc[c];
++ if (!crtc->enabled)
++ continue;
++ crtc->funcs->dpms(crtc, DPMSModeOn);
++ for (o = 0; o < xf86_config->num_output; o++) {
++ output = xf86_config->output[o];
++ if (output->crtc != crtc)
++ continue;
++
++ output->funcs->dpms(output, DPMSModeOn);
++ }
++ }
++}
+diff --git a/src/r128_cursor.c b/src/r128_cursor.c
+index b76913c..ad6752f 100644
+--- a/src/r128_cursor.c
++++ b/src/r128_cursor.c
+@@ -59,6 +59,9 @@
+ #include "exa.h"
+ #endif
+
++#define CURSOR_WIDTH 64
++#define CURSOR_HEIGHT 64
++
+ #if X_BYTE_ORDER == X_BIG_ENDIAN
+ #define P_SWAP32( a , b ) \
+ ((char *)a)[0] = ((char *)b)[3]; \
+@@ -73,84 +76,121 @@
+ ((char *)a)[3] = ((char *)b)[2]
+ #endif
+
++void r128_crtc_show_cursor(xf86CrtcPtr crtc)
++{
++ ScrnInfoPtr pScrn = crtc->scrn;
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
++ R128InfoPtr info = R128PTR(pScrn);
++ unsigned char *R128MMIO = info->MMIO;
++ int crtc_id = r128_crtc->crtc_id;
++
++ switch (crtc_id) {
++ case 0:
++ OUTREGP(R128_CRTC_GEN_CNTL, R128_CRTC_CUR_EN, ~R128_CRTC_CUR_EN);
++ break;
++ case 1:
++ OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_CUR_EN, ~R128_CRTC2_CUR_EN);
++ break;
++ default:
++ return;
++ }
++}
+
+-/* Set cursor foreground and background colors. */
+-static void R128SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
++void r128_crtc_hide_cursor(xf86CrtcPtr crtc)
+ {
+- R128InfoPtr info = R128PTR(pScrn);
++ ScrnInfoPtr pScrn = crtc->scrn;
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
++ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
++ int crtc_id = r128_crtc->crtc_id;
+
+- if(info->IsSecondary)
+- {
++ switch (crtc_id) {
++ case 0:
++ OUTREGP(R128_CRTC_GEN_CNTL, 0, ~R128_CRTC_CUR_EN);
++ break;
++ case 1:
++ OUTREGP(R128_CRTC2_GEN_CNTL, 0, ~R128_CRTC2_CUR_EN);
++ break;
++ default:
++ return;
++ }
++}
++
++void r128_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg)
++{
++ ScrnInfoPtr pScrn = crtc->scrn;
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
++ R128InfoPtr info = R128PTR(pScrn);
++ unsigned char *R128MMIO = info->MMIO;
++ int crtc_id = r128_crtc->crtc_id;
++
++ switch (crtc_id) {
++ case 0:
++ OUTREG(R128_CUR_CLR0, bg);
++ OUTREG(R128_CUR_CLR1, fg);
++ break;
++ case 1:
+ OUTREG(R128_CUR2_CLR0, bg);
+ OUTREG(R128_CUR2_CLR1, fg);
+- }
+- else
+- {
+- OUTREG(R128_CUR_CLR0, bg);
+- OUTREG(R128_CUR_CLR1, fg);
++ break;
++ default:
++ return;
+ }
+ }
+
+-/* Set cursor position to (x,y) with offset into cursor bitmap at
+- (xorigin,yorigin). */
+-static void R128SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
++void r128_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
+ {
+- R128InfoPtr info = R128PTR(pScrn);
+- unsigned char *R128MMIO = info->MMIO;
+- xf86CursorInfoPtr cursor = info->cursor;
+- int xorigin = 0;
+- int yorigin = 0;
+- int total_y = pScrn->frameY1 - pScrn->frameY0;
+-
+- if (x < 0) xorigin = -x;
+- if (y < 0) yorigin = -y;
+- if (y > total_y) y = total_y;
+- if (info->Flags & V_DBLSCAN) y *= 2;
+- if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1;
+- if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1;
+-
+- if(!info->IsSecondary)
+- {
+- OUTREG(R128_CUR_HORZ_VERT_OFF, R128_CUR_LOCK | (xorigin << 16) | yorigin);
+- OUTREG(R128_CUR_HORZ_VERT_POSN, (R128_CUR_LOCK
+- | ((xorigin ? 0 : x) << 16)
+- | (yorigin ? 0 : y)));
+- OUTREG(R128_CUR_OFFSET, info->cursor_start + yorigin * 16);
+- }
+- else
+- {
+- OUTREG(R128_CUR2_HORZ_VERT_OFF, (R128_CUR2_LOCK
+- | (xorigin << 16)
+- | yorigin));
+- OUTREG(R128_CUR2_HORZ_VERT_POSN, (R128_CUR2_LOCK
+- | ((xorigin ? 0 : x) << 16)
+- | (yorigin ? 0 : y)));
+- OUTREG(R128_CUR2_OFFSET,
+- info->cursor_start + pScrn->fbOffset + yorigin * 16);
++ ScrnInfoPtr pScrn = crtc->scrn;
++ R128InfoPtr info = R128PTR(pScrn);
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
++ unsigned char *R128MMIO = info->MMIO;
++ int crtc_id = r128_crtc->crtc_id;
++
++ int xorigin = 0, yorigin = 0;
++ DisplayModePtr mode = &crtc->mode;
++
++ if (x < 0) xorigin = -x + 1;
++ if (y < 0) yorigin = -y + 1;
++ if (xorigin >= CURSOR_WIDTH) xorigin = CURSOR_WIDTH - 1;
++ if (yorigin >= CURSOR_HEIGHT) yorigin = CURSOR_HEIGHT - 1;
++
++ if (mode->Flags & V_INTERLACE)
++ y /= 2;
++ else if (mode->Flags & V_DBLSCAN)
++ y *= 2;
++
++ if(crtc_id == 0) {
++ OUTREG(R128_CUR_HORZ_VERT_OFF, (R128_CUR_LOCK | (xorigin << 16) | yorigin));
++ OUTREG(R128_CUR_HORZ_VERT_POSN, (R128_CUR_LOCK | ((xorigin ? 0 : x) << 16) | (yorigin ? 0 : y)));
++ OUTREG(R128_CUR_OFFSET, r128_crtc->cursor_offset + pScrn->fbOffset + yorigin * 16);
++ } else if (crtc_id == 1) {
++ OUTREG(R128_CUR2_HORZ_VERT_OFF, (R128_CUR2_LOCK | (xorigin << 16) | yorigin));
++ OUTREG(R128_CUR2_HORZ_VERT_POSN, (R128_CUR2_LOCK | ((xorigin ? 0 : x) << 16) | (yorigin ? 0 : y)));
++ OUTREG(R128_CUR2_OFFSET, r128_crtc->cursor_offset + pScrn->fbOffset + yorigin * 16);
+ }
+ }
+
+-/* Copy cursor image from `image' to video memory. R128SetCursorPosition
+- will be called after this, so we can ignore xorigin and yorigin. */
+-static void R128LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image)
++void r128_crtc_load_cursor_image(xf86CrtcPtr crtc, unsigned char *src)
+ {
++ ScrnInfoPtr pScrn = crtc->scrn;
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
++ int crtc_id = r128_crtc->crtc_id;
++
++
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+- CARD32 *s = (pointer)image;
+- CARD32 *d = (pointer)((CARD8*)info->FB + info->cursor_start);
++ CARD32 *s = (pointer)src;
++ CARD32 *d = (pointer)(info->FB + r128_crtc->cursor_offset + pScrn->fbOffset);
++ CARD32 save1 = 0;
++ CARD32 save2 = 0;
+ int y;
+- CARD32 save;
+
+- if(!info->IsSecondary)
+- {
+- save = INREG(R128_CRTC_GEN_CNTL);
+- OUTREG(R128_CRTC_GEN_CNTL, save & (CARD32)~R128_CRTC_CUR_EN);
+- }
+- else
+- {
+- save = INREG(R128_CRTC2_GEN_CNTL);
+- OUTREG(R128_CRTC2_GEN_CNTL, save & (CARD32)~R128_CRTC2_CUR_EN);
++ if (crtc_id == 0) {
++ save1 = INREG(R128_CRTC_GEN_CNTL);
++ OUTREG(R128_CRTC_GEN_CNTL, save1 & (CARD32)~R128_CRTC_CUR_EN);
++ } else if (crtc_id == 1) {
++ save2 = INREG(R128_CRTC2_GEN_CNTL);
++ OUTREG(R128_CRTC2_GEN_CNTL, save2 & (CARD32)~R128_CRTC2_CUR_EN);
+ }
+
+ #if X_BYTE_ORDER == X_BIG_ENDIAN
+@@ -197,59 +237,10 @@ static void R128LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image)
+ }
+ #endif
+
+- /* Set the area after the cursor to be all transparent so that we
+- won't display corrupted cursors on the screen */
+- for (y = 0; y < 64; y++) {
+- *d++ = 0xffffffff; /* The AND bits */
+- *d++ = 0xffffffff;
+- *d++ = 0x00000000; /* The XOR bits */
+- *d++ = 0x00000000;
+- }
+-
+-
+- if(!info->IsSecondary)
+- OUTREG(R128_CRTC_GEN_CNTL, save);
++ if (crtc_id == 0)
++ OUTREG(R128_CRTC_GEN_CNTL, save1);
+ else
+- OUTREG(R128_CRTC2_GEN_CNTL, save);
+-
+-}
+-
+-/* Hide hardware cursor. */
+-static void R128HideCursor(ScrnInfoPtr pScrn)
+-{
+- R128InfoPtr info = R128PTR(pScrn);
+- unsigned char *R128MMIO = info->MMIO;
+-
+- if(info->IsSecondary)
+- OUTREGP(R128_CRTC2_GEN_CNTL, 0, ~R128_CRTC2_CUR_EN);
+- else
+- OUTREGP(R128_CRTC_GEN_CNTL, 0, ~R128_CRTC_CUR_EN);
+-}
+-
+-/* Show hardware cursor. */
+-static void R128ShowCursor(ScrnInfoPtr pScrn)
+-{
+- R128InfoPtr info = R128PTR(pScrn);
+- unsigned char *R128MMIO = info->MMIO;
+-
+- if(info->IsSecondary)
+- {
+- OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_CUR_EN,
+- ~R128_CRTC2_CUR_EN);
+- }
+- else
+- {
+- OUTREGP(R128_CRTC_GEN_CNTL, R128_CRTC_CUR_EN, ~R128_CRTC_CUR_EN);
+- }
+-}
+-
+-/* Determine if hardware cursor is in use. */
+-static Bool R128UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+-{
+- ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+- R128InfoPtr info = R128PTR(pScrn);
+-
+- return info->cursor_start ? TRUE : FALSE;
++ OUTREG(R128_CRTC2_GEN_CNTL, save2);
+ }
+
+ /* Initialize hardware cursor support. */
+@@ -257,77 +248,72 @@ Bool R128CursorInit(ScreenPtr pScreen)
+ {
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ R128InfoPtr info = R128PTR(pScrn);
+- xf86CursorInfoPtr cursor;
+ FBAreaPtr fbarea = NULL;
+ #ifdef USE_EXA
+ ExaOffscreenArea* osArea = NULL;
+ #else
+ void* osArea = NULL;
+ #endif
++ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
++ CARD32 cursor_offset = 0;
++ int cpp = info->CurrentLayout.pixel_bytes;
+ int width;
++ int width_bytes;
+ int height;
+ int size;
++ int size_bytes;
++ int c;
+
+- int cpp = info->CurrentLayout.pixel_bytes;
+-
+- if (!(cursor = info->cursor = xf86CreateCursorInfoRec())) return FALSE;
+-
+- cursor->MaxWidth = 64;
+- cursor->MaxHeight = 64;
+- cursor->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
+- | HARDWARE_CURSOR_SHOW_TRANSPARENT
+- | HARDWARE_CURSOR_UPDATE_UNHIDDEN
+-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+- | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
+-#endif
+- | HARDWARE_CURSOR_INVERT_MASK
+- | HARDWARE_CURSOR_AND_SOURCE_WITH_MASK
+- | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64
+- | HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK);
+-
+- cursor->SetCursorColors = R128SetCursorColors;
+- cursor->SetCursorPosition = R128SetCursorPosition;
+- cursor->LoadCursorImage = R128LoadCursorImage;
+- cursor->HideCursor = R128HideCursor;
+- cursor->ShowCursor = R128ShowCursor;
+- cursor->UseHWCursor = R128UseHWCursor;
+-
+- size = (cursor->MaxWidth/4) * cursor->MaxHeight;
++ size = CURSOR_WIDTH * CURSOR_HEIGHT / 4;
++ size_bytes = size * 2;
+ width = pScrn->displayWidth;
+- height = (size*2 + 1023) / pScrn->displayWidth;
++ width_bytes = width * (pScrn->bitsPerPixel / 8);
++ height = ((size_bytes * xf86_config->num_crtc) + width_bytes - 1) / width_bytes;
+
+ if(!info->useEXA) {
+ fbarea = xf86AllocateOffscreenArea(pScreen, width, height,
+ 16, NULL, NULL, NULL);
+
+- if (fbarea) {
+- info->cursor_start = R128_ALIGN((fbarea->box.x1
+- + width * fbarea->box.y1)
+- * cpp, 16);
+- info->cursor_end = info->cursor_start + size;
+- }
++ if (fbarea)
++ cursor_offset = R128_ALIGN((fbarea->box.x1 + width * fbarea->box.y1) * cpp, 16);
+ }
+ #ifdef USE_EXA
+ else {
+ osArea = exaOffscreenAlloc(pScreen, width * height, 16,
+ TRUE, NULL, NULL);
+
+- if (osArea) {
+- info->cursor_start = osArea->offset;
+- info->cursor_end = osArea->offset + osArea->size;
+- }
++ if (osArea)
++ cursor_offset = osArea->offset;
+ }
+ #endif
+
+ if ((!info->useEXA && !fbarea) || (info->useEXA && !osArea)) {
+- info->cursor_start = 0;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Hardware cursor disabled"
+ " due to insufficient offscreen memory\n");
++ return FALSE;
++ } else {
++ for (c = 0; c < xf86_config->num_crtc; c++) {
++ xf86CrtcPtr crtc = xf86_config->crtc[c];
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
++
++ r128_crtc->cursor_offset = cursor_offset + (c * size);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Will use %d kb for hardware cursor %d at offset 0x%08x\n",
++ (size_bytes * xf86_config->num_crtc) / 1024, c,
++ (unsigned int)r128_crtc->cursor_offset);
++ }
+ }
+
+- R128TRACE(("R128CursorInit (0x%08x-0x%08x)\n",
+- info->cursor_start, info->cursor_end));
+-
+- return xf86InitCursor(pScreen, cursor);
++ return xf86_cursors_init(pScreen, CURSOR_WIDTH, CURSOR_HEIGHT,
++ (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
++ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
++ HARDWARE_CURSOR_SHOW_TRANSPARENT |
++ HARDWARE_CURSOR_UPDATE_UNHIDDEN |
++#if X_BYTE_ORDER == X_LITTLE_ENDIAN
++ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
++#endif
++ HARDWARE_CURSOR_INVERT_MASK |
++ HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
++ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64));
+ }
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index f425c3b..9205328 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -84,6 +84,7 @@
+ /* X and server generic header files */
+ #include "xf86.h"
+ #include "xf86_OSproc.h"
++#include "xf86RandR12.h"
+ #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
+ #include "xf86RAC.h"
+ #include "xf86Resources.h"
+@@ -119,11 +120,6 @@ static Bool R128CloseScreen(CLOSE_SCREEN_ARGS_DECL);
+ static Bool R128SaveScreen(ScreenPtr pScreen, int mode);
+ static void R128Save(ScrnInfoPtr pScrn);
+ static void R128Restore(ScrnInfoPtr pScrn);
+-static Bool R128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+-static void R128DisplayPowerManagementSet(ScrnInfoPtr pScrn,
+- int PowerManagementMode, int flags);
+-static void R128DisplayPowerManagementSetLCD(ScrnInfoPtr pScrn,
+- int PowerManagementMode, int flags);
+
+ typedef enum {
+ OPTION_NOACCEL,
+@@ -258,6 +254,7 @@ static Bool R128MapMMIO(ScrnInfoPtr pScrn)
+ info->PciTag,
+ info->MMIOAddr,
+ R128_MMIOSIZE);
++ if (!info->MMIO) return FALSE;
+ #else
+ int err = pci_device_map_range(info->PciInfo,
+ info->MMIOAddr,
+@@ -274,7 +271,6 @@ static Bool R128MapMMIO(ScrnInfoPtr pScrn)
+ #endif
+ }
+
+- if (!info->MMIO) return FALSE;
+ return TRUE;
+ }
+
+@@ -402,78 +398,6 @@ void R128WaitForVerticalSync(ScrnInfoPtr pScrn)
+ }
+ }
+
+-/* Blank screen. */
+-static void R128Blank(ScrnInfoPtr pScrn)
+-{
+- R128InfoPtr info = R128PTR(pScrn);
+- unsigned char *R128MMIO = info->MMIO;
+-
+- if(!info->IsSecondary)
+- {
+- switch(info->DisplayType)
+- {
+- case MT_LCD:
+- OUTREGP(R128_LVDS_GEN_CNTL, R128_LVDS_DISPLAY_DIS,
+- ~R128_LVDS_DISPLAY_DIS);
+- break;
+- case MT_CRT:
+- OUTREGP(R128_CRTC_EXT_CNTL, R128_CRTC_DISPLAY_DIS, ~R128_CRTC_DISPLAY_DIS);
+- break;
+- case MT_DFP:
+- OUTREGP(R128_FP_GEN_CNTL, R128_FP_BLANK_DIS, ~R128_FP_BLANK_DIS);
+- break;
+- case MT_NONE:
+- default:
+- break;
+- }
+- }
+- else
+- {
+- OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_DISP_DIS, ~R128_CRTC2_DISP_DIS);
+- }
+-}
+-
+-/* Unblank screen. */
+-static void R128Unblank(ScrnInfoPtr pScrn)
+-{
+- R128InfoPtr info = R128PTR(pScrn);
+- unsigned char *R128MMIO = info->MMIO;
+-
+- if(!info->IsSecondary)
+- {
+- switch(info->DisplayType)
+- {
+- case MT_LCD:
+- OUTREGP(R128_LVDS_GEN_CNTL, 0,
+- ~R128_LVDS_DISPLAY_DIS);
+- break;
+- case MT_CRT:
+- OUTREGP(R128_CRTC_EXT_CNTL, 0, ~R128_CRTC_DISPLAY_DIS);
+- break;
+- case MT_DFP:
+- OUTREGP(R128_FP_GEN_CNTL, 0, ~R128_FP_BLANK_DIS);
+- break;
+- case MT_NONE:
+- default:
+- break;
+- }
+- }
+- else
+- {
+- switch(info->DisplayType)
+- {
+- case MT_LCD:
+- case MT_DFP:
+- case MT_CRT:
+- OUTREGP(R128_CRTC2_GEN_CNTL, 0, ~R128_CRTC2_DISP_DIS);
+- break;
+- case MT_NONE:
+- default:
+- break;
+- }
+- }
+-}
+-
+ /* Compute log base 2 of val. */
+ int R128MinBits(int val)
+ {
+@@ -1058,9 +982,9 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Option \"Display\" ignored "
+ "(framebuffer device determines display type)\n");
+- else if (info->IsPrimary || info->IsSecondary)
++ else if (!Display)
+ info->BIOSDisplay = R128_DUALHEAD;
+- else if (!Display || !xf86NameCmp(Display, "FP"))
++ else if (!xf86NameCmp(Display, "FP"))
+ info->BIOSDisplay = R128_BIOS_DISPLAY_FP;
+ else if (!xf86NameCmp(Display, "BIOS"))
+ info->BIOSDisplay = INREG8(R128_BIOS_5_SCRATCH);
+@@ -1079,9 +1003,6 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
+ info->BIOSDisplay = R128_BIOS_DISPLAY_CRT;
+ }
+
+- R128MMIO = NULL;
+- R128UnmapMMIO(pScrn);
+-
+ /* RAM */
+ switch (info->MemCntl & 0x3) {
+ case 0: /* SDR SGRAM 1:1 */
+@@ -1256,6 +1177,7 @@ static Bool R128PreInitDDC(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
+ #endif
+
+ if (!xf86LoadSubModule(pScrn, "ddc")) return FALSE;
++ if (!xf86LoadSubModule(pScrn, "i2c")) return FALSE;
+
+ #if defined(__powerpc__) || defined(__alpha__) || defined(__sparc__)
+ /* Int10 is broken on PPC and some Alphas */
+@@ -1281,468 +1203,6 @@ static Bool R128PreInitGamma(ScrnInfoPtr pScrn)
+ return TRUE;
+ }
+
+-static void
+-R128I2CGetBits(I2CBusPtr b, int *Clock, int *data)
+-{
+- ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
+- R128InfoPtr info = R128PTR(pScrn);
+- unsigned long val;
+- unsigned char *R128MMIO = info->MMIO;
+-
+- /* Get the result. */
+- val = INREG(info->DDCReg);
+- *Clock = (val & R128_GPIO_MONID_Y_3) != 0;
+- *data = (val & R128_GPIO_MONID_Y_0) != 0;
+-
+-}
+-
+-static void
+-R128I2CPutBits(I2CBusPtr b, int Clock, int data)
+-{
+- ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
+- R128InfoPtr info = R128PTR(pScrn);
+- unsigned long val;
+- unsigned char *R128MMIO = info->MMIO;
+-
+- val = INREG(info->DDCReg)
+- & ~(CARD32)(R128_GPIO_MONID_EN_0 | R128_GPIO_MONID_EN_3);
+- val |= (Clock ? 0:R128_GPIO_MONID_EN_3);
+- val |= (data ? 0:R128_GPIO_MONID_EN_0);
+- OUTREG(info->DDCReg, val);
+-}
+-
+-
+-static Bool
+-R128I2cInit(ScrnInfoPtr pScrn)
+-{
+- R128InfoPtr info = R128PTR(pScrn);
+- if ( !xf86LoadSubModule(pScrn, "i2c") ) {
+- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+- "Failed to load i2c module\n");
+- return FALSE;
+- }
+-
+- info->pI2CBus = xf86CreateI2CBusRec();
+- if(!info->pI2CBus) return FALSE;
+-
+- info->pI2CBus->BusName = "DDC";
+- info->pI2CBus->scrnIndex = pScrn->scrnIndex;
+- info->DDCReg = R128_GPIO_MONID;
+- info->pI2CBus->I2CPutBits = R128I2CPutBits;
+- info->pI2CBus->I2CGetBits = R128I2CGetBits;
+- info->pI2CBus->AcknTimeout = 5;
+-
+- if (!xf86I2CBusInit(info->pI2CBus)) {
+- return FALSE;
+- }
+- return TRUE;
+-}
+-
+-/* return TRUE is a DFP is indeed connected to a DVI port */
+-static Bool R128GetDFPInfo(ScrnInfoPtr pScrn)
+-{
+- R128InfoPtr info = R128PTR(pScrn);
+- int i;
+- xf86MonPtr MonInfo = NULL;
+- xf86MonPtr ddc;
+- unsigned char *R128MMIO = info->MMIO;
+-
+- if(!R128I2cInit(pScrn)){
+- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+- "I2C initialization failed!\n");
+- }
+-
+- OUTREG(info->DDCReg, (INREG(info->DDCReg)
+- | R128_GPIO_MONID_MASK_0 | R128_GPIO_MONID_MASK_3));
+-
+- OUTREG(info->DDCReg, INREG(info->DDCReg)
+- & ~(CARD32)(R128_GPIO_MONID_A_0 | R128_GPIO_MONID_A_3));
+-
+- MonInfo = xf86DoEDID_DDC2(XF86_SCRN_ARG(pScrn), info->pI2CBus);
+- if(!MonInfo) {
+- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+- "No DFP detected\n");
+- return FALSE;
+- }
+- xf86SetDDCproperties(pScrn, MonInfo);
+- ddc = pScrn->monitor->DDC;
+-
+- for(i=0; i<4; i++)
+- {
+- if((ddc->det_mon[i].type == 0) &&
+- (ddc->det_mon[i].section.d_timings.h_active > 0) &&
+- (ddc->det_mon[i].section.d_timings.v_active > 0))
+- {
+- info->PanelXRes =
+- ddc->det_mon[i].section.d_timings.h_active;
+- info->PanelYRes =
+- ddc->det_mon[i].section.d_timings.v_active;
+-
+- info->HOverPlus =
+- ddc->det_mon[i].section.d_timings.h_sync_off;
+- info->HSyncWidth =
+- ddc->det_mon[i].section.d_timings.h_sync_width;
+- info->HBlank =
+- ddc->det_mon[i].section.d_timings.h_blanking;
+- info->VOverPlus =
+- ddc->det_mon[i].section.d_timings.v_sync_off;
+- info->VSyncWidth =
+- ddc->det_mon[i].section.d_timings.v_sync_width;
+- info->VBlank =
+- ddc->det_mon[i].section.d_timings.v_blanking;
+- }
+- }
+- return TRUE;
+-}
+-
+-
+-static void R128SetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
+-{
+- int i;
+- xf86MonPtr ddc = pScrn->monitor->DDC;
+- if(flag) /*HSync*/
+- {
+- for(i=0; i<4; i++)
+- {
+- if(ddc->det_mon[i].type == DS_RANGES)
+- {
+- pScrn->monitor->nHsync = 1;
+- pScrn->monitor->hsync[0].lo =
+- ddc->det_mon[i].section.ranges.min_h;
+- pScrn->monitor->hsync[0].hi =
+- ddc->det_mon[i].section.ranges.max_h;
+- return;
+- }
+- }
+- /*if no sync ranges detected in detailed timing table,
+- let's try to derive them from supported VESA modes
+- Are we doing too much here!!!?
+- **/
+- i = 0;
+- if(ddc->timings1.t1 & 0x02) /*800x600@56*/
+- {
+- pScrn->monitor->hsync[i].lo =
+- pScrn->monitor->hsync[i].hi = 35.2;
+- i++;
+- }
+- if(ddc->timings1.t1 & 0x04) /*640x480@75*/
+- {
+- pScrn->monitor->hsync[i].lo =
+- pScrn->monitor->hsync[i].hi = 37.5;
+- i++;
+- }
+- if((ddc->timings1.t1 & 0x08) || (ddc->timings1.t1 & 0x01))
+- {
+- pScrn->monitor->hsync[i].lo =
+- pScrn->monitor->hsync[i].hi = 37.9;
+- i++;
+- }
+- if(ddc->timings1.t2 & 0x40)
+- {
+- pScrn->monitor->hsync[i].lo =
+- pScrn->monitor->hsync[i].hi = 46.9;
+- i++;
+- }
+- if((ddc->timings1.t2 & 0x80) || (ddc->timings1.t2 & 0x08))
+- {
+- pScrn->monitor->hsync[i].lo =
+- pScrn->monitor->hsync[i].hi = 48.1;
+- i++;
+- }
+- if(ddc->timings1.t2 & 0x04)
+- {
+- pScrn->monitor->hsync[i].lo =
+- pScrn->monitor->hsync[i].hi = 56.5;
+- i++;
+- }
+- if(ddc->timings1.t2 & 0x02)
+- {
+- pScrn->monitor->hsync[i].lo =
+- pScrn->monitor->hsync[i].hi = 60.0;
+- i++;
+- }
+- if(ddc->timings1.t2 & 0x01)
+- {
+- pScrn->monitor->hsync[i].lo =
+- pScrn->monitor->hsync[i].hi = 64.0;
+- i++;
+- }
+- pScrn->monitor->nHsync = i;
+- }
+- else /*Vrefresh*/
+- {
+- for(i=0; i<4; i++)
+- {
+- if(ddc->det_mon[i].type == DS_RANGES)
+- {
+- pScrn->monitor->nVrefresh = 1;
+- pScrn->monitor->vrefresh[0].lo =
+- ddc->det_mon[i].section.ranges.min_v;
+- pScrn->monitor->vrefresh[0].hi =
+- ddc->det_mon[i].section.ranges.max_v;
+- return;
+- }
+- }
+- i = 0;
+- if(ddc->timings1.t1 & 0x02) /*800x600@56*/
+- {
+- pScrn->monitor->vrefresh[i].lo =
+- pScrn->monitor->vrefresh[i].hi = 56;
+- i++;
+- }
+- if((ddc->timings1.t1 & 0x01) || (ddc->timings1.t2 & 0x08))
+- {
+- pScrn->monitor->vrefresh[i].lo =
+- pScrn->monitor->vrefresh[i].hi = 60;
+- i++;
+- }
+- if(ddc->timings1.t2 & 0x04)
+- {
+- pScrn->monitor->vrefresh[i].lo =
+- pScrn->monitor->vrefresh[i].hi = 70;
+- i++;
+- }
+- if((ddc->timings1.t1 & 0x08) || (ddc->timings1.t2 & 0x80))
+- {
+- pScrn->monitor->vrefresh[i].lo =
+- pScrn->monitor->vrefresh[i].hi = 72;
+- i++;
+- }
+- if((ddc->timings1.t1 & 0x04) || (ddc->timings1.t2 & 0x40)
+- || (ddc->timings1.t2 & 0x02) || (ddc->timings1.t2 & 0x01))
+- {
+- pScrn->monitor->vrefresh[i].lo =
+- pScrn->monitor->vrefresh[i].hi = 75;
+- i++;
+- }
+- pScrn->monitor->nVrefresh = i;
+- }
+-}
+-
+-/***********
+- free's xf86ValidateModes routine deosn't work well with DFPs
+- here is our own validation routine. All modes between
+- 640<=XRes<=MaxRes and 480<=YRes<=MaxYRes will be permitted.
+- NOTE: RageProII doesn't support rmx, can only work with the
+- standard modes the monitor can support (scale).
+-************/
+-
+-static int R128ValidateFPModes(ScrnInfoPtr pScrn)
+-{
+- int i, j, count=0, width, height;
+- R128InfoPtr info = R128PTR(pScrn);
+- DisplayModePtr last = NULL, new = NULL, first = NULL;
+- xf86MonPtr ddc;
+-
+- /* Free any allocated modes during configuration. We don't need them*/
+- while (pScrn->modes)
+- {
+- xf86DeleteMode(&pScrn->modes, pScrn->modes);
+- }
+- while (pScrn->modePool)
+- {
+- xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
+- }
+-
+- pScrn->virtualX = pScrn->display->virtualX;
+- pScrn->virtualY = pScrn->display->virtualY;
+-
+- /* If no mode specified in config, we use native resolution*/
+- if(!pScrn->display->modes[0])
+- {
+- pScrn->display->modes[0] = xnfalloc(16);
+- sprintf(pScrn->display->modes[0], "%dx%d",
+- info->PanelXRes, info->PanelYRes);
+- }
+-
+- for(i=0; pScrn->display->modes[i] != NULL; i++)
+- {
+- if (sscanf(pScrn->display->modes[i], "%dx%d", &width, &height) == 2)
+- {
+-
+- if(width < 640 || width > info->PanelXRes ||
+- height < 480 || height > info->PanelYRes)
+- {
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Mode %s is out of range.\n"
+- "Valid mode should be between 640x480-%dx%d\n",
+- pScrn->display->modes[i], info->PanelXRes, info->PanelYRes);
+- continue;
+- }
+-
+- new = xnfcalloc(1, sizeof(DisplayModeRec));
+- new->prev = last;
+- new->name = xnfalloc(strlen(pScrn->display->modes[i]) + 1);
+- strcpy(new->name, pScrn->display->modes[i]);
+- new->HDisplay = new->CrtcHDisplay = width;
+- new->VDisplay = new->CrtcVDisplay = height;
+-
+- ddc = pScrn->monitor->DDC;
+- for(j=0; j<DET_TIMINGS; j++)
+- {
+- /*We use native mode clock only*/
+- if(ddc->det_mon[j].type == 0){
+- new->Clock = ddc->det_mon[j].section.d_timings.clock / 1000;
+- break;
+- }
+- }
+-
+- if(new->prev) new->prev->next = new;
+- last = new;
+- if(!first) first = new;
+- pScrn->display->virtualX =
+- pScrn->virtualX = MAX(pScrn->virtualX, width);
+- pScrn->display->virtualY =
+- pScrn->virtualY = MAX(pScrn->virtualY, height);
+- count++;
+- }
+- else
+- {
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Mode name %s is invalid\n", pScrn->display->modes[i]);
+- continue;
+- }
+- }
+-
+- if(last)
+- {
+- last->next = first;
+- first->prev = last;
+- pScrn->modes = first;
+-
+- /*FIXME: May need to validate line pitch here*/
+- {
+- int dummy = 0;
+- switch(pScrn->depth / 8)
+- {
+- case 1:
+- dummy = 128 - pScrn->virtualX % 128;
+- break;
+- case 2:
+- dummy = 32 - pScrn->virtualX % 32;
+- break;
+- case 3:
+- case 4:
+- dummy = 16 - pScrn->virtualX % 16;
+- }
+- pScrn->displayWidth = pScrn->virtualX + dummy;
+- }
+-
+- }
+-
+- return count;
+-}
+-
+-
+-/* This is called by R128PreInit to validate modes and compute parameters
+- for all of the valid modes. */
+-static Bool R128PreInitModes(ScrnInfoPtr pScrn)
+-{
+- R128InfoPtr info = R128PTR(pScrn);
+- ClockRangePtr clockRanges;
+- int modesFound;
+-
+- if(info->isDFP) {
+- R128MapMem(pScrn);
+- info->BIOSDisplay = R128_BIOS_DISPLAY_FP;
+- /* validate if DFP really connected. */
+- if(!R128GetDFPInfo(pScrn)) {
+- info->isDFP = FALSE;
+- info->BIOSDisplay = R128_BIOS_DISPLAY_CRT;
+- } else if(!info->isPro2) {
+- /* RageProII doesn't support rmx, we can't use native-mode
+- stretching for other non-native modes. It will rely on
+- whatever VESA modes monitor can support. */
+- modesFound = R128ValidateFPModes(pScrn);
+- if(modesFound < 1) {
+- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+- "No valid mode found for this DFP/LCD\n");
+- R128UnmapMem(pScrn);
+- return FALSE;
+-
+- }
+- }
+- R128UnmapMem(pScrn);
+- }
+-
+- if(!info->isDFP || info->isPro2) {
+- /* Get mode information */
+- pScrn->progClock = TRUE;
+- clockRanges = xnfcalloc(sizeof(*clockRanges), 1);
+- clockRanges->next = NULL;
+- clockRanges->minClock = info->pll.min_pll_freq;
+- clockRanges->maxClock = info->pll.max_pll_freq * 10;
+- clockRanges->clockIndex = -1;
+- if (info->HasPanelRegs || info->isDFP) {
+- clockRanges->interlaceAllowed = FALSE;
+- clockRanges->doubleScanAllowed = FALSE;
+- } else {
+- clockRanges->interlaceAllowed = TRUE;
+- clockRanges->doubleScanAllowed = TRUE;
+- }
+-
+- if(pScrn->monitor->DDC) {
+- /*if we still don't know sync range yet, let's try EDID.
+- Note that, since we can have dual heads, the Xconfigurator
+- may not be able to probe both monitors correctly through
+- vbe probe function (R128ProbeDDC). Here we provide an
+- additional way to auto-detect sync ranges if they haven't
+- been added to XF86Config manually.
+- **/
+- if(pScrn->monitor->nHsync <= 0)
+- R128SetSyncRangeFromEdid(pScrn, 1);
+- if(pScrn->monitor->nVrefresh <= 0)
+- R128SetSyncRangeFromEdid(pScrn, 0);
+- }
+-
+- modesFound = xf86ValidateModes(pScrn,
+- pScrn->monitor->Modes,
+- pScrn->display->modes,
+- clockRanges,
+- NULL, /* linePitches */
+- 8 * 64, /* minPitch */
+- 8 * 1024, /* maxPitch */
+-/*
+- * ATI docs say pitchInc must be 8 * 64, but this doesn't permit a pitch of
+- * 800 bytes, which is known to work on the Rage128 LF on clamshell iBooks
+- */
+- 8 * 32, /* pitchInc */
+- 128, /* minHeight */
+- 2048, /* maxHeight */
+- pScrn->display->virtualX,
+- pScrn->display->virtualY,
+- info->FbMapSize,
+- LOOKUP_BEST_REFRESH);
+-
+- if (modesFound < 1 && info->FBDev) {
+- fbdevHWUseBuildinMode(pScrn);
+- pScrn->displayWidth = fbdevHWGetLineLength(pScrn)/(pScrn->bitsPerPixel/8);
+- modesFound = 1;
+- }
+-
+- if (modesFound == -1) return FALSE;
+- xf86PruneDriverModes(pScrn);
+- if (!modesFound || !pScrn->modes) {
+- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+- return FALSE;
+- }
+- xf86SetCrtcForModes(pScrn, 0);
+- }
+- /* Set DPI */
+- pScrn->currentMode = pScrn->modes;
+- xf86PrintModes(pScrn);
+-
+- xf86SetDpi(pScrn, 0, 0);
+-
+- /* Get ScreenInit function */
+- if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
+-
+- info->CurrentLayout.displayWidth = pScrn->displayWidth;
+- info->CurrentLayout.mode = pScrn->currentMode;
+-
+- return TRUE;
+-}
+-
+ /* This is called by R128PreInit to initialize the hardware cursor. */
+ static Bool R128PreInitCursor(ScrnInfoPtr pScrn)
+ {
+@@ -1885,6 +1345,43 @@ static Bool R128PreInitDRI(ScrnInfoPtr pScrn)
+ }
+ #endif
+
++static Bool R128PreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
++{
++ R128InfoPtr info = R128PTR(pScrn);
++ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
++ int i;
++ int mask;
++ int found = 0;
++
++ if (info->IsPrimary)
++ mask = 1;
++ else if (info->IsSecondary)
++ mask = 2;
++ else
++ mask = 3;
++
++ if (!R128GetBIOSParameters(pScrn, pInt10))
++ return FALSE;
++
++ if (!R128GetPLLParameters(pScrn))
++ return FALSE;
++
++ if (!R128AllocateControllers(pScrn, mask))
++ return FALSE;
++
++ if (!R128SetupConnectors(pScrn))
++ return FALSE;
++
++ for (i = 0; i < config->num_output; i++) {
++ xf86OutputPtr output = config->output[i];
++
++ output->status = (*output->funcs->detect) (output);
++ if (output->status == XF86OutputStatusConnected)
++ found++;
++ }
++ return !!found;
++}
++
+ static void
+ R128ProbeDDC(ScrnInfoPtr pScrn, int indx)
+ {
+@@ -1899,6 +1396,17 @@ R128ProbeDDC(ScrnInfoPtr pScrn, int indx)
+ #endif
+ }
+
++static Bool R128CRTCResize(ScrnInfoPtr pScrn, int width, int height)
++{
++ pScrn->virtualX = width;
++ pScrn->virtualY = height;
++ return TRUE;
++}
++
++static const xf86CrtcConfigFuncsRec R128CRTCResizeFuncs = {
++ R128CRTCResize
++};
++
+ /* R128PreInit is called once at server startup. */
+ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
+ {
+@@ -1976,6 +1484,9 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
+ #endif
+ pScrn->monitor = pScrn->confScreen->monitor;
+
++ /* Allocate an xf86CrtcConfig */
++ xf86CrtcConfigInit(pScrn, &R128CRTCResizeFuncs);
++
+ if (!R128PreInitVisual(pScrn)) goto fail;
+
+ /* We can't do this until we have a
+@@ -2016,8 +1527,6 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
+ "module load skipped\n");
+ #endif
+
+-
+-
+ if (!R128PreInitWeight(pScrn)) goto fail;
+
+ if(xf86GetOptValInteger(info->Options, OPTION_VIDEO_KEY, &(info->videoKey))) {
+@@ -2053,20 +1562,30 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
+ }
+
+ if (!info->FBDev)
+- if (!R128PreInitInt10(pScrn, &pInt10)) goto fail;
+-
+- if (!R128PreInitConfig(pScrn)) goto fail;
++ if (!R128PreInitInt10(pScrn, &pInt10)) goto fail;
+
+- if (!R128GetBIOSParameters(pScrn, pInt10)) goto fail;
++ if (!R128PreInitConfig(pScrn)) goto fail;
+
+- if (!R128GetPLLParameters(pScrn)) goto fail;
++ xf86CrtcSetSizeRange(pScrn, 320, 200, 4096, 4096);
+
+ /* Don't fail on this one */
+- R128PreInitDDC(pScrn, pInt10);
++ info->DDC = R128PreInitDDC(pScrn, pInt10);
+
+- if (!R128PreInitGamma(pScrn)) goto fail;
++ if (!R128PreInitControllers(pScrn, pInt10)) goto fail;
++
++ if (!xf86InitialConfiguration(pScrn, TRUE)) {
++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
++ goto fail;
++ }
++ pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
+
+- if (!R128PreInitModes(pScrn)) goto fail;
++ /* Set display resolution */
++ xf86SetDpi(pScrn, 0, 0);
++
++ /* Get ScreenInit function */
++ if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
++
++ if (!R128PreInitGamma(pScrn)) goto fail;
+
+ if (!R128PreInitCursor(pScrn)) goto fail;
+
+@@ -2074,6 +1593,18 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
+ if (!R128PreInitDRI(pScrn)) goto fail;
+ #endif
+
++ info->CurrentLayout.displayWidth = pScrn->displayWidth;
++
++ if (!xf86RandR12PreInit(pScrn)) {
++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
++ goto fail;
++ }
++
++ if (pScrn->modes == NULL) {
++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
++ goto fail;
++ }
++
+ /* Free the video bios (if applicable) */
+ if (info->VBIOS) {
+ free(info->VBIOS);
+@@ -2084,6 +1615,9 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
+ if (pInt10)
+ xf86FreeInt10(pInt10);
+
++ if (info->MMIO) R128UnmapMMIO(pScrn);
++ info->MMIO = NULL;
++
+ xf86DrvMsg(pScrn->scrnIndex, X_NOTICE,
+ "For information on using the multimedia capabilities\n\tof this"
+ " adapter, please see http://gatos.sf.net.\n");
+@@ -2116,56 +1650,66 @@ static void R128LoadPalette(ScrnInfoPtr pScrn, int numColors,
+ int *indices, LOCO *colors, VisualPtr pVisual)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+- unsigned char *R128MMIO = info->MMIO;
+- int i, j;
+- int idx;
+- unsigned char r, g, b;
+-
+- /* If the second monitor is connected, we also
+- need to deal with the secondary palette*/
+- if (info->IsSecondary) j = 1;
+- else j = 0;
+-
+- PAL_SELECT(j);
++ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
++ int i, j;
++ int c, index;
++ CARD16 lut_r[256], lut_g[256], lut_b[256];
++
++ for (c = 0; c < xf86_config->num_crtc; c++) {
++ xf86CrtcPtr crtc = xf86_config->crtc[c];
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
++
++ for (i = 0 ; i < 256; i++) {
++ lut_r[i] = r128_crtc->lut_r[i] << 8;
++ lut_g[i] = r128_crtc->lut_g[i] << 8;
++ lut_b[i] = r128_crtc->lut_b[i] << 8;
++ }
+
++ switch (info->CurrentLayout.depth) {
++ case 15:
++ for (i = 0; i < numColors; i++) {
++ index = indices[i];
++ for (j = 0; j < 8; j++) {
++ lut_r[index * 8 + j] = colors[index].red << 8;
++ lut_g[index * 8 + j] = colors[index].green << 8;
++ lut_b[index * 8 + j] = colors[index].blue << 8;
++ }
++ }
++ case 16:
++ for (i = 0; i < numColors; i++) {
++ index = indices[i];
++
++ /* XXX: The old version of R128LoadPalette did not do this and
++ * the old version of RADEONLoadPalette has a comment asking why.
++ */
++ if (i <= 31) {
++ for (j = 0; j < 8; j++) {
++ lut_r[index * 8 + j] = colors[index].red << 8;
++ lut_b[index * 8 + j] = colors[index].blue << 8;
++ }
++ }
+
+- /* Select palette 0 (main CRTC) if using FP-enabled chip */
+- /*if (info->HasPanelRegs || info->isDFP) PAL_SELECT(0);*/
++ for (j = 0; j < 4; j++) {
++ lut_g[index * 4 + j] = colors[index].green << 8;
++ }
++ }
++ default:
++ for (i = 0; i < numColors; i++) {
++ index = indices[i];
++ lut_r[index] = colors[index].red << 8;
++ lut_g[index] = colors[index].green << 8;
++ lut_b[index] = colors[index].blue << 8;
++ }
++ break;
++ }
+
+- if (info->CurrentLayout.depth == 15) {
+- /* 15bpp mode. This sends 32 values. */
+- for (i = 0; i < numColors; i++) {
+- idx = indices[i];
+- r = colors[idx].red;
+- g = colors[idx].green;
+- b = colors[idx].blue;
+- OUTPAL(idx * 8, r, g, b);
+- }
+- }
+- else if (info->CurrentLayout.depth == 16) {
+- /* 16bpp mode. This sends 64 values. */
+- /* There are twice as many green values as
+- there are values for red and blue. So,
+- we take each red and blue pair, and
+- combine it with each of the two green
+- values. */
+- for (i = 0; i < numColors; i++) {
+- idx = indices[i];
+- r = colors[idx / 2].red;
+- g = colors[idx].green;
+- b = colors[idx / 2].blue;
+- OUTPAL(idx * 4, r, g, b);
+- }
+- }
+- else {
+- /* 8bpp mode. This sends 256 values. */
+- for (i = 0; i < numColors; i++) {
+- idx = indices[i];
+- r = colors[idx].red;
+- b = colors[idx].blue;
+- g = colors[idx].green;
+- OUTPAL(idx, r, g, b);
+- }
++ /* Make the change through RandR */
++#ifdef RANDR_12_INTERFACE
++ if (crtc->randr_crtc)
++ RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
++ else
++#endif
++ crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
+ }
+ }
+
+@@ -2296,14 +1840,6 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
+ info->PaletteSavedOnVT = FALSE;
+
+ R128Save(pScrn);
+- if (info->FBDev) {
+- if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE;
+- } else {
+- if (!R128ModeInit(pScrn, pScrn->currentMode)) return FALSE;
+- }
+-
+- R128SaveScreen(pScreen, SCREEN_SAVER_ON);
+- pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
+
+ /* Visual setup */
+ miClearVisualTypes();
+@@ -2701,6 +2237,19 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
+ #endif
+ }
+
++ pScrn->vtSema = TRUE;
++ /* xf86CrtcRotate accesses pScrn->pScreen */
++ pScrn->pScreen = pScreen;
++
++ if (info->FBDev) {
++ if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE;
++ } else {
++ if (!xf86SetDesiredModes(pScrn)) return FALSE;
++ }
++
++ R128SaveScreen(pScreen, SCREEN_SAVER_ON);
++ //pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
++
+ /* DGA setup */
+ R128DGAInit(pScreen);
+
+@@ -2737,28 +2286,11 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using software cursor\n");
+ }
+
+- /* Colormap setup */
+- if (!miCreateDefColormap(pScreen)) return FALSE;
+- if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8,
+- (info->FBDev ? fbdevHWLoadPaletteWeak() :
+- R128LoadPalette), NULL,
+- CMAP_PALETTED_TRUECOLOR
+- | CMAP_RELOAD_ON_MODE_SWITCH
+-#if 0 /* This option messes up text mode! (eich@suse.de) */
+- | CMAP_LOAD_EVEN_IF_OFFSCREEN
+-#endif
+- )) return FALSE;
+-
+ /* DPMS setup - FIXME: also for mirror mode in non-fbdev case? - Michel */
+ if (info->FBDev)
+ xf86DPMSInit(pScreen, fbdevHWDPMSSetWeak(), 0);
+-
+- else {
+- if (info->DisplayType == MT_LCD)
+- xf86DPMSInit(pScreen, R128DisplayPowerManagementSetLCD, 0);
+- else
+- xf86DPMSInit(pScreen, R128DisplayPowerManagementSet, 0);
+- }
++ else
++ xf86DPMSInit(pScreen, xf86DPMSSet, 0);
+
+ if (!info->IsSecondary)
+ R128InitVideo(pScreen);
+@@ -2793,11 +2325,25 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
+ info->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = R128BlockHandler;
+
++ if (!xf86CrtcScreenInit(pScreen)) return FALSE;
++
++ /* Colormap setup */
++ if (!miCreateDefColormap(pScreen)) return FALSE;
++ if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8,
++ (info->FBDev ? fbdevHWLoadPaletteWeak() :
++ R128LoadPalette), NULL,
++ CMAP_PALETTED_TRUECOLOR
++ | CMAP_RELOAD_ON_MODE_SWITCH
++#if 0 /* This option messes up text mode! (eich@suse.de) */
++ | CMAP_LOAD_EVEN_IF_OFFSCREEN
++#endif
++ )) return FALSE;
++
+ return TRUE;
+ }
+
+ /* Write common registers (initialized to 0). */
+-static void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
++void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+@@ -2821,7 +2367,7 @@ static void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ }
+
+ /* Write CRTC registers. */
+-static void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
++void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+@@ -2844,7 +2390,7 @@ static void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ }
+
+ /* Write CRTC2 registers. */
+-static void R128RestoreCrtc2Registers(ScrnInfoPtr pScrn,
++void R128RestoreCrtc2Registers(ScrnInfoPtr pScrn,
+ R128SavePtr restore)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+@@ -2863,7 +2409,7 @@ static void R128RestoreCrtc2Registers(ScrnInfoPtr pScrn,
+ }
+
+ /* Write flat panel registers */
+-static void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
++void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+@@ -2936,7 +2482,7 @@ static void R128PLL2WriteUpdate(ScrnInfoPtr pScrn)
+ }
+
+ /* Write PLL registers. */
+-static void R128RestorePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
++void R128RestorePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+@@ -2999,7 +2545,7 @@ static void R128RestorePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ }
+
+ /* Write PLL2 registers. */
+-static void R128RestorePLL2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
++void R128RestorePLL2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+@@ -3068,7 +2614,7 @@ static void R128RestorePLL2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
+ }
+
+ /* Write DDA registers. */
+-static void R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
++void R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+@@ -3078,7 +2624,7 @@ static void R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ }
+
+ /* Write DDA registers. */
+-static void R128RestoreDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
++void R128RestoreDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+@@ -3087,126 +2633,6 @@ static void R128RestoreDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
+ OUTREG(R128_DDA2_ON_OFF, restore->dda2_on_off);
+ }
+
+-/* Write palette data. */
+-static void R128RestorePalette(ScrnInfoPtr pScrn, R128SavePtr restore)
+-{
+- R128InfoPtr info = R128PTR(pScrn);
+- unsigned char *R128MMIO = info->MMIO;
+- int i;
+-
+- if (!restore->palette_valid) return;
+-
+- PAL_SELECT(1);
+- OUTPAL_START(0);
+- for (i = 0; i < 256; i++) {
+- R128WaitForFifo(pScrn, 32); /* delay */
+- OUTPAL_NEXT_CARD32(restore->palette2[i]);
+- }
+-
+- PAL_SELECT(0);
+- OUTPAL_START(0);
+- for (i = 0; i < 256; i++) {
+- R128WaitForFifo(pScrn, 32); /* delay */
+- OUTPAL_NEXT_CARD32(restore->palette[i]);
+- }
+-
+-}
+-
+-/* Write out state to define a new video mode. */
+-static void R128RestoreMode(ScrnInfoPtr pScrn, R128SavePtr restore)
+-{
+- R128InfoPtr info = R128PTR(pScrn);
+- DevUnion* pPriv;
+- R128EntPtr pR128Ent;
+- static R128SaveRec restore0;
+-
+- R128TRACE(("R128RestoreMode(%p)\n", restore));
+- if(!info->HasCRTC2)
+- {
+- R128RestoreCommonRegisters(pScrn, restore);
+- R128RestoreDDARegisters(pScrn, restore);
+- R128RestoreCrtcRegisters(pScrn, restore);
+- if((info->DisplayType == MT_DFP) ||
+- (info->DisplayType == MT_LCD))
+- {
+- R128RestoreFPRegisters(pScrn, restore);
+- }
+- R128RestorePLLRegisters(pScrn, restore);
+- return;
+- }
+-
+- pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+- getR128EntityIndex());
+- pR128Ent = pPriv->ptr;
+-
+-
+- /*****
+- When changing mode with Dual-head card (VE/M6), care must
+- be taken for the special order in setting registers. CRTC2 has
+- to be set before changing CRTC_EXT register.
+- In the dual-head setup, X server calls this routine twice with
+- primary and secondary pScrn pointers respectively. The calls
+- can come with different order. Regardless the order of X server issuing
+- the calls, we have to ensure we set registers in the right order!!!
+- Otherwise we may get a blank screen.
+- *****/
+-
+- if(info->IsSecondary)
+- {
+- if (!pR128Ent->RestorePrimary && !info->SwitchingMode)
+- R128RestoreCommonRegisters(pScrn, restore);
+- R128RestoreDDA2Registers(pScrn, restore);
+- R128RestoreCrtc2Registers(pScrn, restore);
+- R128RestorePLL2Registers(pScrn, restore);
+-
+- if(info->SwitchingMode) return;
+-
+- pR128Ent->IsSecondaryRestored = TRUE;
+-
+- if(pR128Ent->RestorePrimary)
+- {
+- R128InfoPtr info0 = R128PTR(pR128Ent->pPrimaryScrn);
+- pR128Ent->RestorePrimary = FALSE;
+-
+- R128RestoreCrtcRegisters(pScrn, &restore0);
+- if((info0->DisplayType == MT_DFP) ||
+- (info0->DisplayType == MT_LCD))
+- {
+- R128RestoreFPRegisters(pScrn, &restore0);
+- }
+-
+- R128RestorePLLRegisters(pScrn, &restore0);
+- pR128Ent->IsSecondaryRestored = FALSE;
+-
+- }
+- }
+- else
+- {
+- if (!pR128Ent->IsSecondaryRestored)
+- R128RestoreCommonRegisters(pScrn, restore);
+- R128RestoreDDARegisters(pScrn, restore);
+- if(!pR128Ent->HasSecondary || pR128Ent->IsSecondaryRestored
+- || info->SwitchingMode)
+- {
+- pR128Ent->IsSecondaryRestored = FALSE;
+- R128RestoreCrtcRegisters(pScrn, restore);
+- if((info->DisplayType == MT_DFP) ||
+- (info->DisplayType == MT_LCD))
+- {
+- R128RestoreFPRegisters(pScrn, restore);
+- }
+- R128RestorePLLRegisters(pScrn, restore);
+- }
+- else
+- {
+- memcpy(&restore0, restore, sizeof(restore0));
+- pR128Ent->RestorePrimary = TRUE;
+- }
+- }
+-
+- R128RestorePalette(pScrn, restore);
+-}
+-
+ /* Read common registers. */
+ static void R128SaveCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr save)
+ {
+@@ -3450,9 +2876,19 @@ static void R128Restore(ScrnInfoPtr pScrn)
+ OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
+ OUTREG(R128_GEN_RESET_CNTL, restore->gen_reset_cntl);
+ OUTREG(R128_DP_DATATYPE, restore->dp_datatype);
++
++ R128RestoreCommonRegisters(pScrn, restore);
++ if (info->HasCRTC2) {
++ R128RestoreDDA2Registers(pScrn, restore);
++ R128RestoreCrtc2Registers(pScrn, restore);
++ R128RestorePLL2Registers(pScrn, restore);
++ }
++ R128RestoreDDARegisters(pScrn, restore);
++ R128RestoreCrtcRegisters(pScrn, restore);
++ R128RestorePLLRegisters(pScrn, restore);
++ R128RestoreFPRegisters(pScrn, restore);
+ }
+
+- R128RestoreMode(pScrn, restore);
+ #ifdef WITH_VGAHW
+ if (info->VGAAccess) {
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+@@ -3492,7 +2928,7 @@ static void R128Restore(ScrnInfoPtr pScrn)
+ }
+
+ /* Define common registers for requested video mode. */
+-static void R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info)
++void R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info)
+ {
+ save->ovr_clr = 0;
+ save->ovr_wid_left_right = 0;
+@@ -3518,8 +2954,64 @@ static void R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info)
+ save->bus_cntl |= R128_BUS_RD_DISCARD_EN | R128_BUS_RD_ABORT_EN;
+ }
+
++Bool R128InitCrtcBase(xf86CrtcPtr crtc, R128SavePtr save, int x, int y)
++{
++ ScrnInfoPtr pScrn = crtc->scrn;
++ R128InfoPtr info = R128PTR(pScrn);
++ int offset = y * info->CurrentLayout.displayWidth + x;
++ int Base = pScrn->fbOffset;
++
++ switch (info->CurrentLayout.pixel_code) {
++ case 15:
++ case 16: offset *= 2; break;
++ case 24: offset *= 3; break;
++ case 32: offset *= 4; break;
++ }
++ Base += offset;
++
++ if (crtc->rotatedData != NULL)
++ Base = pScrn->fbOffset + (char *)crtc->rotatedData - (char *)info->FB;
++
++ Base &= ~7; /* 3 lower bits are always 0 */
++ if (info->CurrentLayout.pixel_code == 24)
++ Base += 8 * (Base % 3); /* Must be multiple of 8 and 3 */
++
++ save->crtc_offset = Base;
++ save->crtc_offset_cntl = 0;
++
++ return TRUE;
++}
++
++Bool R128InitCrtc2Base(xf86CrtcPtr crtc, R128SavePtr save, int x, int y)
++{
++ ScrnInfoPtr pScrn = crtc->scrn;
++ R128InfoPtr info = R128PTR(pScrn);
++ int offset = y * info->CurrentLayout.displayWidth + x;
++ int Base = pScrn->fbOffset;
++
++ switch (info->CurrentLayout.pixel_code) {
++ case 15:
++ case 16: offset *= 2; break;
++ case 24: offset *= 3; break;
++ case 32: offset *= 4; break;
++ }
++ Base += offset;
++
++ if (crtc->rotatedData != NULL)
++ Base = pScrn->fbOffset + (char *)crtc->rotatedData - (char *)info->FB;
++
++ Base &= ~7; /* 3 lower bits are always 0 */
++ if (info->CurrentLayout.pixel_code == 24)
++ Base += 8 * (Base % 3); /* Must be multiple of 8 and 3 */
++
++ save->crtc2_offset = Base;
++ save->crtc2_offset_cntl = 0;
++
++ return TRUE;
++}
++
+ /* Define CRTC registers for requested video mode. */
+-static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
++Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+ DisplayModePtr mode, R128InfoPtr info)
+ {
+ int format;
+@@ -3633,8 +3125,6 @@ static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+ | ((mode->Flags & V_NVSYNC)
+ ? R128_CRTC_V_SYNC_POL
+ : 0));
+- save->crtc_offset = 0;
+- save->crtc_offset_cntl = 0;
+ save->crtc_pitch = info->CurrentLayout.displayWidth / 8;
+
+ R128TRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n",
+@@ -3654,7 +3144,7 @@ static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+ }
+
+ /* Define CRTC2 registers for requested video mode. */
+-static Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
++Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
+ DisplayModePtr mode, R128InfoPtr info)
+ {
+ int format;
+@@ -3727,10 +3217,6 @@ static Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
+ | ((mode->Flags & V_NVSYNC)
+ ? R128_CRTC2_V_SYNC_POL
+ : 0));
+-
+- save->crtc2_offset = 0;
+- save->crtc2_offset_cntl = 0;
+-
+ save->crtc2_pitch = info->CurrentLayout.displayWidth / 8;
+
+ R128TRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n",
+@@ -3740,7 +3226,7 @@ static Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
+ }
+
+ /* Define CRTC registers for requested video mode. */
+-static void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
++void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
+ DisplayModePtr mode, R128InfoPtr info)
+ {
+ int xres = mode->CrtcHDisplay;
+@@ -3853,7 +3339,7 @@ static void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
+ }
+
+ /* Define PLL registers for requested video mode. */
+-static void R128InitPLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
++void R128InitPLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+ R128PLLPtr pll, double dot_clock)
+ {
+ unsigned long freq = dot_clock * 100;
+@@ -3905,7 +3391,7 @@ static void R128InitPLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+ }
+
+ /* Define PLL2 registers for requested video mode. */
+-static void R128InitPLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
++void R128InitPLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
+ R128PLLPtr pll, double dot_clock)
+ {
+ unsigned long freq = dot_clock * 100;
+@@ -3957,7 +3443,7 @@ static void R128InitPLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
+ }
+
+ /* Define DDA registers for requested video mode. */
+-static Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save,
++Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+ R128PLLPtr pll, R128InfoPtr info,
+ DisplayModePtr mode)
+ {
+@@ -4026,7 +3512,7 @@ static Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+ }
+
+ /* Define DDA2 registers for requested video mode. */
+-static Bool R128InitDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
++Bool R128InitDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
+ R128PLLPtr pll, R128InfoPtr info,
+ DisplayModePtr mode)
+ {
+@@ -4106,122 +3592,6 @@ static void R128InitPalette(R128SavePtr save)
+ }
+ #endif
+
+-/* Define registers for a requested video mode. */
+-static Bool R128Init(ScrnInfoPtr pScrn, DisplayModePtr mode, R128SavePtr save)
+-{
+- R128InfoPtr info = R128PTR(pScrn);
+- double dot_clock = mode->Clock/1000.0;
+-
+-#if R128_DEBUG
+- ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)",
+- mode->name,
+- dot_clock,
+-
+- mode->HDisplay,
+- mode->HSyncStart,
+- mode->HSyncEnd,
+- mode->HTotal,
+-
+- mode->VDisplay,
+- mode->VSyncStart,
+- mode->VSyncEnd,
+- mode->VTotal,
+- pScrn->depth,
+- pScrn->bitsPerPixel);
+- if (mode->Flags & V_DBLSCAN) ErrorF(" D");
+- if (mode->Flags & V_CSYNC) ErrorF(" C");
+- if (mode->Flags & V_INTERLACE) ErrorF(" I");
+- if (mode->Flags & V_PHSYNC) ErrorF(" +H");
+- if (mode->Flags & V_NHSYNC) ErrorF(" -H");
+- if (mode->Flags & V_PVSYNC) ErrorF(" +V");
+- if (mode->Flags & V_NVSYNC) ErrorF(" -V");
+- ErrorF("\n");
+- ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)",
+- mode->name,
+- dot_clock,
+-
+- mode->CrtcHDisplay,
+- mode->CrtcHSyncStart,
+- mode->CrtcHSyncEnd,
+- mode->CrtcHTotal,
+-
+- mode->CrtcVDisplay,
+- mode->CrtcVSyncStart,
+- mode->CrtcVSyncEnd,
+- mode->CrtcVTotal,
+- pScrn->depth,
+- pScrn->bitsPerPixel);
+- if (mode->Flags & V_DBLSCAN) ErrorF(" D");
+- if (mode->Flags & V_CSYNC) ErrorF(" C");
+- if (mode->Flags & V_INTERLACE) ErrorF(" I");
+- if (mode->Flags & V_PHSYNC) ErrorF(" +H");
+- if (mode->Flags & V_NHSYNC) ErrorF(" -H");
+- if (mode->Flags & V_PVSYNC) ErrorF(" +V");
+- if (mode->Flags & V_NVSYNC) ErrorF(" -V");
+- ErrorF("\n");
+-#endif
+-
+- info->Flags = mode->Flags;
+-
+- if(info->IsSecondary)
+- {
+- if (!R128InitCrtc2Registers(pScrn, save,
+- pScrn->currentMode,info))
+- return FALSE;
+- R128InitPLL2Registers(pScrn, save, &info->pll, dot_clock);
+- if (!R128InitDDA2Registers(pScrn, save, &info->pll, info, mode))
+- return FALSE;
+- }
+- else
+- {
+- R128InitCommonRegisters(save, info);
+- if(!R128InitCrtcRegisters(pScrn, save, mode, info))
+- return FALSE;
+- if(dot_clock)
+- {
+- R128InitPLLRegisters(pScrn, save, &info->pll, dot_clock);
+- if (!R128InitDDARegisters(pScrn, save, &info->pll, info, mode))
+- return FALSE;
+- }
+- else
+- {
+- save->ppll_ref_div = info->SavedReg.ppll_ref_div;
+- save->ppll_div_3 = info->SavedReg.ppll_div_3;
+- save->htotal_cntl = info->SavedReg.htotal_cntl;
+- save->dda_config = info->SavedReg.dda_config;
+- save->dda_on_off = info->SavedReg.dda_on_off;
+- }
+- /* not used for now */
+- /*if (!info->PaletteSavedOnVT) RADEONInitPalette(save);*/
+- }
+-
+- if (((info->DisplayType == MT_DFP) ||
+- (info->DisplayType == MT_LCD)))
+- {
+- R128InitFPRegisters(&info->SavedReg, save, mode, info);
+- }
+-
+- R128TRACE(("R128Init returns %p\n", save));
+- return TRUE;
+-}
+-
+-/* Initialize a new mode. */
+-static Bool R128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+-{
+- R128InfoPtr info = R128PTR(pScrn);
+-
+- if (!R128Init(pScrn, mode, &info->ModeReg)) return FALSE;
+- /* FIXME? DRILock/DRIUnlock here? */
+- pScrn->vtSema = TRUE;
+- R128Blank(pScrn);
+- R128RestoreMode(pScrn, &info->ModeReg);
+- R128Unblank(pScrn);
+-
+- info->CurrentLayout.mode = mode;
+-
+- return TRUE;
+-}
+-
+ static Bool R128SaveScreen(ScreenPtr pScreen, int mode)
+ {
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+@@ -4252,7 +3622,7 @@ Bool R128SwitchMode(SWITCH_MODE_ARGS_DECL)
+ Bool ret;
+
+ info->SwitchingMode = TRUE;
+- ret = R128ModeInit(pScrn, mode);
++ ret = xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
+ info->SwitchingMode = FALSE;
+ return ret;
+ }
+@@ -4379,10 +3749,16 @@ Bool R128EnterVT(VT_FUNC_ARGS_DECL)
+ R128InfoPtr info = R128PTR(pScrn);
+
+ R128TRACE(("R128EnterVT\n"));
++
++ pScrn->vtSema = TRUE;
+ if (info->FBDev) {
+ if (!fbdevHWEnterVT(VT_FUNC_ARGS)) return FALSE;
+- } else
+- if (!R128ModeInit(pScrn, pScrn->currentMode)) return FALSE;
++ } else {
++ if (!xf86SetDesiredModes(pScrn)) return FALSE;
++ }
++
++ //if (!R128ModeInit(pScrn, pScrn->currentMode)) return FALSE;
++
+ if (info->accelOn)
+ R128EngineInit(pScrn);
+
+@@ -4399,7 +3775,7 @@ Bool R128EnterVT(VT_FUNC_ARGS_DECL)
+ #endif
+
+ info->PaletteSavedOnVT = FALSE;
+- pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
++ //pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
+
+ return TRUE;
+ }
+@@ -4504,130 +3880,3 @@ void R128FreeScreen(FREE_SCREEN_ARGS_DECL)
+ #endif
+ R128FreeRec(pScrn);
+ }
+-
+-/* Sets VESA Display Power Management Signaling (DPMS) Mode. */
+-static void R128DisplayPowerManagementSet(ScrnInfoPtr pScrn,
+- int PowerManagementMode, int flags)
+-{
+- R128InfoPtr info = R128PTR(pScrn);
+- unsigned char *R128MMIO = info->MMIO;
+- int mask = (R128_CRTC_DISPLAY_DIS
+- | R128_CRTC_HSYNC_DIS
+- | R128_CRTC_VSYNC_DIS);
+- int mask2 = R128_CRTC2_DISP_DIS;
+-
+- switch (PowerManagementMode) {
+- case DPMSModeOn:
+- /* Screen: On; HSync: On, VSync: On */
+- if (info->IsSecondary)
+- OUTREGP(R128_CRTC2_GEN_CNTL, 0, ~mask2);
+- else
+- OUTREGP(R128_CRTC_EXT_CNTL, 0, ~mask);
+- break;
+- case DPMSModeStandby:
+- /* Screen: Off; HSync: Off, VSync: On */
+- if (info->IsSecondary)
+- OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_DISP_DIS, ~mask2);
+- else
+- OUTREGP(R128_CRTC_EXT_CNTL,
+- R128_CRTC_DISPLAY_DIS | R128_CRTC_HSYNC_DIS, ~mask);
+- break;
+- case DPMSModeSuspend:
+- /* Screen: Off; HSync: On, VSync: Off */
+- if (info->IsSecondary)
+- OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_DISP_DIS, ~mask2);
+- else
+- OUTREGP(R128_CRTC_EXT_CNTL,
+- R128_CRTC_DISPLAY_DIS | R128_CRTC_VSYNC_DIS, ~mask);
+- break;
+- case DPMSModeOff:
+- /* Screen: Off; HSync: Off, VSync: Off */
+- if (info->IsSecondary)
+- OUTREGP(R128_CRTC2_GEN_CNTL, mask2, ~mask2);
+- else
+- OUTREGP(R128_CRTC_EXT_CNTL, mask, ~mask);
+- break;
+- }
+- if(info->isDFP) {
+- switch (PowerManagementMode) {
+- case DPMSModeOn:
+- OUTREG(R128_FP_GEN_CNTL, INREG(R128_FP_GEN_CNTL) | (R128_FP_FPON | R128_FP_TDMS_EN));
+- break;
+- case DPMSModeStandby:
+- case DPMSModeSuspend:
+- case DPMSModeOff:
+- OUTREG(R128_FP_GEN_CNTL, INREG(R128_FP_GEN_CNTL) & ~(R128_FP_FPON | R128_FP_TDMS_EN));
+- break;
+- }
+- }
+-}
+-
+-static int r128_set_backlight_enable(ScrnInfoPtr pScrn, int on);
+-
+-static void R128DisplayPowerManagementSetLCD(ScrnInfoPtr pScrn,
+- int PowerManagementMode, int flags)
+-{
+- R128InfoPtr info = R128PTR(pScrn);
+- unsigned char *R128MMIO = info->MMIO;
+- int mask = R128_LVDS_DISPLAY_DIS;
+-
+- switch (PowerManagementMode) {
+- case DPMSModeOn:
+- /* Screen: On; HSync: On, VSync: On */
+- OUTREGP(R128_LVDS_GEN_CNTL, 0, ~mask);
+- r128_set_backlight_enable(pScrn, 1);
+- break;
+- case DPMSModeStandby:
+- /* Fall through */
+- case DPMSModeSuspend:
+- /* Fall through */
+- break;
+- case DPMSModeOff:
+- /* Screen: Off; HSync: Off, VSync: Off */
+- OUTREGP(R128_LVDS_GEN_CNTL, mask, ~mask);
+- r128_set_backlight_enable(pScrn, 0);
+- break;
+- }
+-}
+-
+-static int r128_set_backlight_enable(ScrnInfoPtr pScrn, int on)
+-{
+- R128InfoPtr info = R128PTR(pScrn);
+- unsigned char *R128MMIO = info->MMIO;
+- unsigned int lvds_gen_cntl = INREG(R128_LVDS_GEN_CNTL);
+-
+- lvds_gen_cntl |= (/*R128_LVDS_BL_MOD_EN |*/ R128_LVDS_BLON);
+- if (on) {
+- lvds_gen_cntl |= R128_LVDS_DIGON;
+- if (!(lvds_gen_cntl & R128_LVDS_ON)) {
+- lvds_gen_cntl &= ~R128_LVDS_BLON;
+- OUTREG(R128_LVDS_GEN_CNTL, lvds_gen_cntl);
+- (void)INREG(R128_LVDS_GEN_CNTL);
+- usleep(10000);
+- lvds_gen_cntl |= R128_LVDS_BLON;
+- OUTREG(R128_LVDS_GEN_CNTL, lvds_gen_cntl);
+- }
+-#if 0
+- lvds_gen_cntl &= ~R128_LVDS_BL_MOD_LEVEL_MASK;
+- lvds_gen_cntl |= (0xFF /* backlight_conv[level] */ <<
+- R128_LVDS_BL_MOD_LEVEL_SHIFT);
+-#endif
+- lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_EN);
+- lvds_gen_cntl &= ~R128_LVDS_DISPLAY_DIS;
+- } else {
+-#if 0
+- lvds_gen_cntl &= ~R128_LVDS_BL_MOD_LEVEL_MASK;
+- lvds_gen_cntl |= (0xFF /* backlight_conv[0] */ <<
+- R128_LVDS_BL_MOD_LEVEL_SHIFT);
+-#endif
+- lvds_gen_cntl |= R128_LVDS_DISPLAY_DIS;
+- OUTREG(R128_LVDS_GEN_CNTL, lvds_gen_cntl);
+- usleep(10);
+- lvds_gen_cntl &= ~(R128_LVDS_ON | R128_LVDS_EN | R128_LVDS_BLON
+- | R128_LVDS_DIGON);
+- }
+-
+- OUTREG(R128_LVDS_GEN_CNTL, lvds_gen_cntl);
+-
+- return 0;
+-}
+diff --git a/src/r128_output.c b/src/r128_output.c
+new file mode 100644
+index 0000000..89a2958
+--- /dev/null
++++ b/src/r128_output.c
+@@ -0,0 +1,465 @@
++/*
++ * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
++ * VA Linux Systems Inc., Fremont, California.
++ *
++ * All Rights Reserved.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation on 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
++ * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
++ * THEIR SUPPLIERS 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.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include <string.h>
++#include <stdio.h>
++
++#include "xf86.h"
++#include "xf86Modes.h"
++
++#include "r128.h"
++#include "r128_probe.h"
++#include "r128_reg.h"
++
++static void R128ConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output);
++
++static void r128_dpms(xf86OutputPtr output, int mode)
++{
++ switch(mode) {
++ case DPMSModeOn:
++ R128DPMSSetOn(output);
++ break;
++ case DPMSModeStandby:
++ case DPMSModeSuspend:
++ case DPMSModeOff:
++ R128DPMSSetOff(output);
++ break;
++ }
++}
++
++static void r128_save(xf86OutputPtr output)
++{
++}
++
++static void r128_restore(xf86OutputPtr output)
++{
++}
++
++static int r128_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
++{
++ return MODE_OK;
++}
++
++static Bool r128_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
++{
++ return TRUE;
++}
++
++static void r128_mode_prepare(xf86OutputPtr output)
++{
++ r128_dpms(output, DPMSModeOff);
++}
++
++static void r128_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
++{
++}
++
++static void r128_mode_commit(xf86OutputPtr output)
++{
++ r128_dpms(output, DPMSModeOn);
++}
++
++static xf86OutputStatus r128_detect(xf86OutputPtr output)
++{
++ ScrnInfoPtr pScrn = output->scrn;
++ R128OutputPrivatePtr r128_output = output->driver_private;
++
++ r128_output->MonType = MT_UNKNOWN;
++ R128ConnectorFindMonitor(pScrn, output);
++
++ if (r128_output->MonType == MT_UNKNOWN) {
++ output->subpixel_order = SubPixelUnknown;
++ return XF86OutputStatusUnknown;
++ } else if (r128_output->MonType == MT_NONE) {
++ output->subpixel_order = SubPixelUnknown;
++ return XF86OutputStatusDisconnected;
++ } else {
++ switch(r128_output->MonType) {
++ case MT_LCD:
++ case MT_DFP:
++ output->subpixel_order = SubPixelHorizontalRGB;
++ break;
++ default:
++ output->subpixel_order = SubPixelNone;
++ break;
++ }
++
++ return XF86OutputStatusConnected;
++ }
++}
++
++static DisplayModePtr r128_get_modes(xf86OutputPtr output)
++{
++ DisplayModePtr modes;
++ modes = R128ProbeOutputModes(output);
++ return modes;
++}
++
++static void r128_destroy(xf86OutputPtr output)
++{
++ if (output->driver_private)
++ free(output->driver_private);
++}
++
++static const xf86OutputFuncsRec r128_output_funcs = {
++ .dpms = r128_dpms,
++ .save = r128_save,
++ .restore = r128_restore,
++ .mode_valid = r128_mode_valid,
++ .mode_fixup = r128_mode_fixup,
++ .prepare = r128_mode_prepare,
++ .mode_set = r128_mode_set,
++ .commit = r128_mode_commit,
++ .detect = r128_detect,
++ .get_modes = r128_get_modes,
++ .destroy = r128_destroy,
++};
++
++void R128DPMSSetOn(xf86OutputPtr output)
++{
++ ScrnInfoPtr pScrn = output->scrn;
++ R128InfoPtr info = R128PTR(pScrn);
++ unsigned char *R128MMIO = info->MMIO;
++ R128OutputPrivatePtr r128_output = output->driver_private;
++ R128MonitorType MonType = r128_output->MonType;
++
++ switch(MonType) {
++ case MT_LCD:
++ OUTREGP(R128_LVDS_GEN_CNTL, R128_LVDS_BLON, ~R128_LVDS_BLON);
++ usleep(info->PanelPwrDly * 1000);
++ OUTREGP(R128_LVDS_GEN_CNTL, R128_LVDS_ON, ~R128_LVDS_ON);
++ break;
++ case MT_DFP:
++ OUTREGP(R128_FP_GEN_CNTL, (R128_FP_FPON | R128_FP_TDMS_EN), ~(R128_FP_FPON | R128_FP_TDMS_EN));
++ break;
++ default:
++ break;
++ }
++}
++
++void R128DPMSSetOff(xf86OutputPtr output)
++{
++ ScrnInfoPtr pScrn = output->scrn;
++ R128InfoPtr info = R128PTR(pScrn);
++ unsigned char *R128MMIO = info->MMIO;
++ R128OutputPrivatePtr r128_output = output->driver_private;
++ R128MonitorType MonType = r128_output->MonType;
++
++ switch(MonType) {
++ case MT_LCD:
++ OUTREGP(R128_LVDS_GEN_CNTL, 0, ~(R128_LVDS_BLON | R128_LVDS_ON));
++ break;
++ case MT_DFP:
++ OUTREGP(R128_FP_GEN_CNTL, 0, ~(R128_FP_FPON | R128_FP_TDMS_EN));
++ break;
++ default:
++ break;
++ }
++}
++
++static R128MonitorType R128DisplayDDCConnected(xf86OutputPtr output)
++{
++ ScrnInfoPtr pScrn = output->scrn;
++ R128InfoPtr info = R128PTR(pScrn);
++ unsigned char *R128MMIO = info->MMIO;
++ R128OutputPrivatePtr r128_output = output->driver_private;
++
++ R128MonitorType MonType = MT_NONE;
++ xf86MonPtr *MonInfo = &output->MonInfo;
++ CARD32 mask1, mask2;
++
++ if (r128_output->type == OUTPUT_LVDS) {
++ return MT_LCD;
++ } else if (r128_output->type == OUTPUT_VGA) {
++ mask1 = R128_GPIO_MONID_MASK_1 | R128_GPIO_MONID_MASK_3;
++ mask2 = R128_GPIO_MONID_A_1 | R128_GPIO_MONID_A_3;
++ } else {
++ mask1 = R128_GPIO_MONID_MASK_0 | R128_GPIO_MONID_MASK_3;
++ mask2 = R128_GPIO_MONID_A_0 | R128_GPIO_MONID_A_3;
++ }
++
++ if (r128_output->pI2CBus) {
++ R128I2CBusPtr pR128I2CBus = &(r128_output->ddc_i2c);
++
++ /* XXX: Radeon does something here to appease old monitors. */
++ OUTREG(pR128I2CBus->ddc_reg, INREG(pR128I2CBus->ddc_reg) | mask1);
++ OUTREG(pR128I2CBus->ddc_reg, INREG(pR128I2CBus->ddc_reg) & ~mask2);
++ *MonInfo = xf86DoEDID_DDC2(XF86_SCRN_ARG(pScrn), r128_output->pI2CBus);
++ } else {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DDC2/I2C is not properly initialized\n");
++ return MT_NONE;
++ }
++
++ if (*MonInfo) {
++ if (r128_output->type == OUTPUT_VGA) {
++ MonType = MT_CRT;
++ } else {
++ if ((*MonInfo)->rawData[0x14] & 0x80)
++ MonType = MT_DFP;
++ else
++ MonType = MT_CRT;
++ }
++ }
++
++ return MonType;
++}
++
++static void R128ConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output)
++{
++ R128OutputPrivatePtr r128_output = output->driver_private;
++
++ /* XXX: We should figure out how the DAC and BIOS scratch registers work
++ * to handle the non-DDC case. */
++ if (r128_output->MonType == MT_UNKNOWN)
++ r128_output->MonType = R128DisplayDDCConnected(output);
++}
++
++DisplayModePtr R128ProbeOutputModes(xf86OutputPtr output)
++{
++ ScrnInfoPtr pScrn = output->scrn;
++ R128OutputPrivatePtr r128_output = output->driver_private;
++ DisplayModePtr modes = NULL;
++ DisplayModePtr mode;
++ xf86MonPtr edid_mon;
++
++ if (r128_output->pI2CBus) {
++ edid_mon = xf86OutputGetEDID(output, r128_output->pI2CBus);
++ xf86OutputSetEDID(output, edid_mon);
++ modes = xf86OutputGetEDIDModes(output);
++ }
++
++ /* Letting this function return NULL would be a bad idea. With old cards
++ * like r128, users often specify a small resolution in order to get DRI.
++ * If the X server has to guess modes, the list it comes up with includes
++ * high resolutions.
++ */
++ if (!modes)
++ modes = xf86GetDefaultModes();
++
++ for (mode = modes; mode != NULL; mode = mode->next) {
++ xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
++ if (mode->status == MODE_OK)
++ mode->status = R128ValidMode(XF86_SCRN_ARG(pScrn), mode, TRUE, MODECHECK_FINAL);
++ }
++
++ xf86ValidateModesUserConfig(pScrn, modes);
++ xf86PruneInvalidModes(pScrn, &modes, FALSE);
++
++ return modes;
++}
++
++static xf86OutputPtr R128OutputCreate(ScrnInfoPtr pScrn, const char *name, int i)
++{
++ char buf[32];
++ sprintf(buf, name, i);
++ return xf86OutputCreate(pScrn, &r128_output_funcs, buf);
++}
++
++static void R128I2CGetBits(I2CBusPtr b, int *Clock, int *data)
++{
++ ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
++ R128InfoPtr info = R128PTR(pScrn);
++ unsigned long val;
++ unsigned char *R128MMIO = info->MMIO;
++ R128I2CBusPtr pR128I2CBus = b->DriverPrivate.ptr;
++
++ /* Get the result. */
++ val = INREG(pR128I2CBus->ddc_reg);
++ *Clock = (val & pR128I2CBus->get_clk_mask) != 0;
++ *data = (val & pR128I2CBus->get_data_mask) != 0;
++}
++
++static void R128I2CPutBits(I2CBusPtr b, int Clock, int data)
++{
++ ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
++ R128InfoPtr info = R128PTR(pScrn);
++ unsigned long val;
++ unsigned char *R128MMIO = info->MMIO;
++ R128I2CBusPtr pR128I2CBus = b->DriverPrivate.ptr;
++
++ val = INREG(pR128I2CBus->ddc_reg)
++ & ~(CARD32)(pR128I2CBus->put_clk_mask | pR128I2CBus->put_data_mask);
++ val |= (Clock ? 0 : pR128I2CBus->put_clk_mask);
++ val |= (data ? 0 : pR128I2CBus->put_data_mask);
++ OUTREG(pR128I2CBus->ddc_reg, val);
++}
++
++static Bool R128I2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name)
++{
++ ScrnInfoPtr pScrn = output->scrn;
++ R128OutputPrivatePtr r128_output = output->driver_private;
++ R128I2CBusPtr pR128I2CBus = &(r128_output->ddc_i2c);
++ I2CBusPtr pI2CBus;
++
++ pI2CBus = xf86CreateI2CBusRec();
++ if(!pI2CBus) return FALSE;
++
++ pI2CBus->BusName = name;
++ pI2CBus->scrnIndex = pScrn->scrnIndex;
++ pI2CBus->I2CPutBits = R128I2CPutBits;
++ pI2CBus->I2CGetBits = R128I2CGetBits;
++ pI2CBus->AcknTimeout = 5;
++
++ pI2CBus->DriverPrivate.ptr = (pointer)pR128I2CBus;
++ if (!xf86I2CBusInit(pI2CBus)) return FALSE;
++
++ *bus_ptr = pI2CBus;
++ return TRUE;
++}
++
++void R128SetOutputType(ScrnInfoPtr pScrn, R128OutputPrivatePtr r128_output)
++{
++ R128OutputType output = OUTPUT_NONE;
++
++ switch (r128_output->ConnectorType) {
++ case CONNECTOR_VGA:
++ output = OUTPUT_VGA;
++ break;
++ case CONNECTOR_LVDS:
++ output = OUTPUT_LVDS;
++ break;
++ case CONNECTOR_DVI_D:
++ case CONNECTOR_DVI_I:
++ case CONNECTOR_DVI_A:
++ output = OUTPUT_DVI;
++ break;
++ default:
++ output = OUTPUT_NONE;
++ }
++
++ r128_output->type = output;
++}
++
++void R128SetupGenericConnectors(ScrnInfoPtr pScrn)
++{
++ R128InfoPtr info = R128PTR(pScrn);
++
++ if (!info->HasCRTC2 && !info->isDFP) {
++ info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
++ info->BiosConnector[0].valid = TRUE;
++ return;
++ } else if (!info->HasCRTC2) {
++ info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_D;
++ info->BiosConnector[0].valid = TRUE;
++ return;
++ }
++
++ info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
++ info->BiosConnector[0].valid = TRUE;
++
++ info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
++ info->BiosConnector[1].valid = TRUE;
++}
++
++Bool R128SetupConnectors(ScrnInfoPtr pScrn)
++{
++ R128InfoPtr info = R128PTR(pScrn);
++ xf86OutputPtr output;
++ int num_vga = 0;
++ int num_dvi = 0;
++ int i;
++
++ for (i = 0; i < R128_MAX_BIOS_CONNECTOR; i++) {
++ info->BiosConnector[i].valid = FALSE;
++ info->BiosConnector[i].ConnectorType = CONNECTOR_NONE;
++ }
++
++ /* XXX: Can we make R128GetConnectorInfoFromBIOS()? */
++ R128SetupGenericConnectors(pScrn);
++
++ for (i = 0; i < R128_MAX_BIOS_CONNECTOR; i++) {
++ if (info->BiosConnector[i].valid) {
++ if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
++ (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I) ||
++ (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A)) {
++ num_dvi++;
++ } else if (info->BiosConnector[i].ConnectorType == CONNECTOR_VGA) {
++ num_vga++;
++ }
++ }
++ }
++
++ for (i = 0; i < R128_MAX_BIOS_CONNECTOR; i++) {
++ if (info->BiosConnector[i].valid) {
++ R128I2CBusRec i2c;
++ R128OutputPrivatePtr r128_output;
++ R128ConnectorType conntype = info->BiosConnector[i].ConnectorType;
++
++ if (conntype == CONNECTOR_NONE)
++ continue;
++
++ r128_output = xnfcalloc(sizeof(R128OutputPrivateRec), 1);
++ if (!r128_output) return FALSE;
++
++ r128_output->MonType = MT_UNKNOWN;
++ r128_output->ConnectorType = conntype;
++ r128_output->num = i;
++
++ if (conntype == CONNECTOR_LVDS) {
++ output = R128OutputCreate(pScrn, "LVDS", 0);
++ } else if (conntype == CONNECTOR_VGA) {
++ output = R128OutputCreate(pScrn, "VGA-%d", --num_vga);
++ } else {
++ output = R128OutputCreate(pScrn, "DVI-%d", --num_dvi);
++ }
++
++ if (!output) return FALSE;
++ output->interlaceAllowed = TRUE;
++ output->doubleScanAllowed = TRUE;
++ output->driver_private = r128_output;
++ output->possible_clones = 0;
++ if (conntype == CONNECTOR_LVDS || !info->HasCRTC2)
++ output->possible_crtcs = 1;
++ else
++ output->possible_crtcs = 2;
++
++ if (conntype != CONNECTOR_LVDS && info->DDC) {
++ i2c.ddc_reg = R128_GPIO_MONID;
++ i2c.put_clk_mask = R128_GPIO_MONID_EN_3;
++ i2c.get_clk_mask = R128_GPIO_MONID_Y_3;
++ if (conntype == CONNECTOR_VGA) {
++ i2c.put_data_mask = R128_GPIO_MONID_EN_1;
++ i2c.get_data_mask = R128_GPIO_MONID_Y_1;
++ } else {
++ i2c.put_data_mask = R128_GPIO_MONID_EN_0;
++ i2c.get_data_mask = R128_GPIO_MONID_Y_0;
++ }
++ r128_output->ddc_i2c = i2c;
++ R128I2CInit(output, &r128_output->pI2CBus, output->name);
++ }
++
++ R128SetOutputType(pScrn, r128_output);
++ }
++ }
++
++ return TRUE;
++}
+diff --git a/src/r128_probe.c b/src/r128_probe.c
+index 12e0c1c..e623bc9 100644
+--- a/src/r128_probe.c
++++ b/src/r128_probe.c
+@@ -48,7 +48,6 @@
+ #include "xf86Resources.h"
+ #endif
+
+-#include "compat-api.h"
+ #include "r128_probe.h"
+
+ #ifndef XSERVER_LIBPCIACCESS
+diff --git a/src/r128_probe.h b/src/r128_probe.h
+index 7b55e71..f521a13 100644
+--- a/src/r128_probe.h
++++ b/src/r128_probe.h
+@@ -37,6 +37,15 @@
+ #define _R128_PROBE_H_ 1
+
+ #include "xf86str.h"
++#include "xf86DDC.h"
++#include "randrstr.h"
++#include "xf86Crtc.h"
++
++#include "compat-api.h"
++
++#ifdef USE_EXA
++#include "exa.h"
++#endif
+
+ /* Chip definitions */
+ #define PCI_VENDOR_ATI 0x1002
+@@ -90,6 +99,73 @@
+
+ extern DriverRec R128;
+
++typedef enum
++{
++ MT_UNKNOWN = -1,
++ MT_NONE = 0,
++ MT_CRT = 1,
++ MT_LCD = 2,
++ MT_DFP = 3,
++ MT_CTV = 4,
++ MT_STV = 5
++} R128MonitorType;
++
++typedef enum
++{
++ CONNECTOR_NONE,
++ CONNECTOR_VGA,
++ CONNECTOR_DVI_I,
++ CONNECTOR_DVI_D,
++ CONNECTOR_DVI_A,
++ CONNECTOR_LVDS
++} R128ConnectorType;
++
++typedef enum
++{
++ OUTPUT_NONE,
++ OUTPUT_VGA,
++ OUTPUT_DVI,
++ OUTPUT_LVDS
++} R128OutputType;
++
++typedef struct {
++ CARD32 ddc_reg;
++ CARD32 put_clk_mask;
++ CARD32 put_data_mask;
++ CARD32 get_clk_mask;
++ CARD32 get_data_mask;
++} R128I2CBusRec, *R128I2CBusPtr;
++
++typedef struct _R128CrtcPrivateRec {
++#ifdef HAVE_XAA_H
++ FBLinearPtr rotate_mem_xaa;
++#endif
++#ifdef USE_EXA
++ ExaOffscreenArea *rotate_mem_exa;
++#endif
++ int crtc_id;
++ CARD32 cursor_offset;
++ /* Lookup table values to be set when the CRTC is enabled */
++ CARD8 lut_r[256], lut_g[256], lut_b[256];
++} R128CrtcPrivateRec, *R128CrtcPrivatePtr;
++
++typedef struct {
++ R128ConnectorType ConnectorType;
++ Bool valid;
++} R128BIOSConnector;
++
++typedef struct _R128OutputPrivateRec {
++ int num;
++ R128OutputType type;
++ R128ConnectorType ConnectorType;
++ R128MonitorType MonType;
++ I2CBusPtr pI2CBus;
++ R128I2CBusRec ddc_i2c;
++} R128OutputPrivateRec, *R128OutputPrivatePtr;
++
++#define R128_MAX_CRTC 2
++#define R128_MAX_BIOS_CONNECTOR 2
++
+ typedef struct
+ {
+ Bool IsDRIEnabled;
+@@ -101,6 +177,9 @@ typedef struct
+ Bool IsSecondaryRestored;
+ Bool RestorePrimary;
+
++ xf86CrtcPtr pCrtc[R128_MAX_CRTC];
++ R128CrtcPrivatePtr Controller[R128_MAX_CRTC];
++
+ ScrnInfoPtr pSecondaryScrn;
+ ScrnInfoPtr pPrimaryScrn;
+ } R128EntRec, *R128EntPtr;
+diff --git a/src/r128_video.c b/src/r128_video.c
+index dccaa42..6439a24 100644
+--- a/src/r128_video.c
++++ b/src/r128_video.c
+@@ -226,7 +226,7 @@ R128SetupImageVideo(ScreenPtr pScreen)
+ return NULL;
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+- adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
++ adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/;
+ adapt->name = "ATI Rage128 Video Overlay";
+ adapt->nEncodings = 1;
+ adapt->pEncodings = &DummyEncoding;
+@@ -849,6 +849,13 @@ R128PutImage(
+ int top, left, npixels, nlines;
+ BoxRec dstBox;
+ CARD32 tmp;
++
++ /* Currently, the video is only visible on the first monitor.
++ * In the future we could try to make this smarter, or just implement
++ * textured video. */
++ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
++ xf86CrtcPtr crtc = xf86_config->crtc[0];
++
+ #if X_BYTE_ORDER == X_BIG_ENDIAN
+ unsigned char *R128MMIO = info->MMIO;
+ CARD32 config_cntl = INREG(R128_CONFIG_CNTL);
+@@ -893,10 +900,10 @@ R128PutImage(
+ clipBoxes, width, height))
+ return Success;
+
+- dstBox.x1 -= pScrn->frameX0;
+- dstBox.x2 -= pScrn->frameX0;
+- dstBox.y1 -= pScrn->frameY0;
+- dstBox.y2 -= pScrn->frameY0;
++ dstBox.x1 -= crtc->x;
++ dstBox.x2 -= crtc->x;
++ dstBox.y1 -= crtc->y;
++ dstBox.y2 -= crtc->y;
+
+ switch(id) {
+ case FOURCC_YV12:
+--
+2.2.2
+
+
+From 539320429ff1cf8918862da3f950c8740ba63ec4 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Fri, 4 Jul 2014 12:44:30 -0700
+Subject: Only enable CRTCs for DPMSModeOn
+
+This was suggested as a power saving tip.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ src/r128_crtc.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/src/r128_crtc.c b/src/r128_crtc.c
+index 35e1fee..8a6ec44 100644
+--- a/src/r128_crtc.c
++++ b/src/r128_crtc.c
+@@ -84,6 +84,20 @@ static void r128_crtc_dpms(xf86CrtcPtr crtc, int mode)
+ break;
+ }
+
++ if (mode != DPMSModeOn) {
++ if (r128_crtc->crtc_id) {
++ OUTREGP(R128_CRTC2_GEN_CNTL, 0, ~R128_CRTC2_EN);
++ } else {
++ OUTREGP(R128_CRTC_GEN_CNTL, 0, ~R128_CRTC_EN);
++ }
++ } else {
++ if (r128_crtc->crtc_id) {
++ OUTREGP(R128_CRTC2_GEN_CNTL, R128_CRTC2_EN, ~R128_CRTC2_EN);
++ } else {
++ OUTREGP(R128_CRTC_GEN_CNTL, R128_CRTC_EN, ~R128_CRTC_EN);
++ }
++ }
++
+ if (mode != DPMSModeOff)
+ r128_crtc_load_lut(crtc);
+ }
+--
+2.2.2
+
+
+From 4c6457e1893e16546c03ca85a2fa7378b6c927f3 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Mon, 7 Jul 2014 18:49:15 -0700
+Subject: Map and unmap the MMIO better
+
+Now that the MMIO stays mapped during several function calls, we need to
+remember to unmap it if any of them fail. This also fixes a PowerPC code
+path that was not updated to work with the longer lived MMIO.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+---
+ src/r128_driver.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index 9205328..e7833ed 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -641,15 +641,10 @@ static Bool R128GetPLLParameters(ScrnInfoPtr pScrn)
+ pll->min_pll_freq = 12500;
+ pll->max_pll_freq = 25000;
+
+- /* need to memory map the io to use INPLL since it
+- has not been done yet at this point in the startup */
+- R128MapMMIO(pScrn);
+ x_mpll_ref_fb_div = INPLL(pScrn, R128_X_MPLL_REF_FB_DIV);
+ xclk_cntl = INPLL(pScrn, R128_XCLK_CNTL) & 0x7;
+ pll->reference_div =
+ INPLL(pScrn,R128_PPLL_REF_DIV) & R128_PPLL_REF_DIV_MASK;
+- /* unmap it again */
+- R128UnmapMMIO(pScrn);
+
+ Nx = (x_mpll_ref_fb_div & 0x00FF00) >> 8;
+ M = (x_mpll_ref_fb_div & 0x0000FF);
+@@ -959,7 +954,7 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
+
+ /* Read registers used to determine options */
+ from = X_PROBED;
+- R128MapMMIO(pScrn);
++ if (!R128MapMMIO(pScrn)) return FALSE;
+ R128MMIO = info->MMIO;
+
+ if (info->FBDev)
+@@ -1641,6 +1636,10 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
+ if (info->VGAAccess)
+ vgaHWFreeHWRec(pScrn);
+ #endif
++
++ if (info->MMIO) R128UnmapMMIO(pScrn);
++ info->MMIO = NULL;
++
+ R128FreeRec(pScrn);
+ return FALSE;
+ }
+--
+2.2.2
+
+
+From de7fa61b06c887df7a89154bf0f07703a665263a Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Wed, 9 Jul 2014 11:37:12 -0700
+Subject: Split up output register functions
+
+The old code was writing registers more often than it needed to. TMDS
+writes were triggered by changing the mode for an LVDS panel and RMX
+writes were triggered by changing the mode for the second crtc. This
+splits TMDS, LVDS, DAC and RMX calls into their own functions.
+
+Also note that routing bits have been specified. R128_FP_SEL_CRTC2 and
+R128_LVDS_SEL_CRTC2 are always unset to make the panels use the first
+crtc. R128_DAC_CRT_SEL_CRTC2 is unset unless LVDS is already using the
+first crtc.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ src/r128.h | 8 +-
+ src/r128_crtc.c | 20 -----
+ src/r128_driver.c | 217 ++++++++++++++++++++++++++++++------------------------
+ src/r128_output.c | 30 +++++++-
+ src/r128_probe.h | 2 +
+ 5 files changed, 157 insertions(+), 120 deletions(-)
+
+diff --git a/src/r128.h b/src/r128.h
+index fe757f8..d01b5c1 100644
+--- a/src/r128.h
++++ b/src/r128.h
+@@ -554,7 +554,10 @@ extern int R128MinBits(int val);
+ extern void R128InitVideo(ScreenPtr pScreen);
+
+ extern void R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info);
+-extern void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, DisplayModePtr mode, R128InfoPtr info);
++extern void R128InitDACRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output);
++extern void R128InitRMXRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output, DisplayModePtr mode);
++extern void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output);
++extern void R128InitLVDSRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output);
+ extern Bool R128InitCrtcBase(xf86CrtcPtr crtc, R128SavePtr save, int x, int y);
+ extern Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save, DisplayModePtr mode, R128InfoPtr info);
+ extern void R128InitPLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, double dot_clock);
+@@ -564,7 +567,10 @@ extern Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save, D
+ extern void R128InitPLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, double dot_clock);
+ extern Bool R128InitDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, R128InfoPtr info, DisplayModePtr mode);
+ extern void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
++extern void R128RestoreDACRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
++extern void R128RestoreRMXRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
+ extern void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
++extern void R128RestoreLVDSRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
+ extern void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
+ extern void R128RestorePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
+ extern void R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
+diff --git a/src/r128_crtc.c b/src/r128_crtc.c
+index 8a6ec44..9c3d0a9 100644
+--- a/src/r128_crtc.c
++++ b/src/r128_crtc.c
+@@ -133,26 +133,14 @@ static void r128_crtc_mode_prepare(xf86CrtcPtr crtc)
+ static void r128_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjusted_mode, int x, int y)
+ {
+ ScrnInfoPtr pScrn = crtc->scrn;
+- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
+ R128InfoPtr info = R128PTR(pScrn);
+- R128OutputType otype = OUTPUT_NONE;
+-
+ double dot_clock = adjusted_mode->Clock / 1000.0;
+- int i;
+
+ if (r128_crtc->cursor_offset) r128_crtc_hide_cursor(crtc);
+ xf86PrintModeline(pScrn->scrnIndex, adjusted_mode);
+ R128InitCommonRegisters(&info->ModeReg, info);
+
+- for (i = 0; i < xf86_config->num_output; i++) {
+- xf86OutputPtr output = xf86_config->output[i];
+- R128OutputPrivatePtr r128_output = output->driver_private;
+-
+- if (output->crtc == crtc)
+- otype = r128_output->type;
+- }
+-
+ switch (r128_crtc->crtc_id) {
+ case 0:
+ R128InitCrtcRegisters(pScrn, &info->ModeReg, adjusted_mode, info);
+@@ -178,8 +166,6 @@ static void r128_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayMod
+ break;
+ }
+
+- if (otype == OUTPUT_DVI || otype == OUTPUT_LVDS)
+- R128InitFPRegisters(&info->SavedReg, &info->ModeReg, adjusted_mode, info);
+ R128RestoreCommonRegisters(pScrn, &info->ModeReg);
+
+ switch (r128_crtc->crtc_id) {
+@@ -195,12 +181,6 @@ static void r128_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayMod
+ break;
+ }
+
+- if (otype == OUTPUT_DVI || otype == OUTPUT_LVDS)
+- R128RestoreFPRegisters(pScrn, &info->ModeReg);
+-
+- /* XXX: InitFPRegisters looks similar to radeon's InitRMXRegisters so
+- * maybe it should be called from mode_set in the output code.
+- */
+ if (r128_crtc->cursor_offset) r128_crtc_show_cursor(crtc);
+ }
+
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index e7833ed..8e15b0c 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -2376,9 +2376,6 @@ void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ OUTREGP(R128_CRTC_EXT_CNTL, restore->crtc_ext_cntl,
+ R128_CRTC_VSYNC_DIS | R128_CRTC_HSYNC_DIS | R128_CRTC_DISPLAY_DIS);
+
+- OUTREGP(R128_DAC_CNTL, restore->dac_cntl,
+- R128_DAC_RANGE_CNTL | R128_DAC_BLANKING);
+-
+ OUTREG(R128_CRTC_H_TOTAL_DISP, restore->crtc_h_total_disp);
+ OUTREG(R128_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid);
+ OUTREG(R128_CRTC_V_TOTAL_DISP, restore->crtc_v_total_disp);
+@@ -2389,8 +2386,7 @@ void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ }
+
+ /* Write CRTC2 registers. */
+-void R128RestoreCrtc2Registers(ScrnInfoPtr pScrn,
+- R128SavePtr restore)
++void R128RestoreCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+@@ -2407,26 +2403,48 @@ void R128RestoreCrtc2Registers(ScrnInfoPtr pScrn,
+ OUTREG(R128_CRTC2_PITCH, restore->crtc2_pitch);
+ }
+
+-/* Write flat panel registers */
+-void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
++/* Write DAC registers */
++void R128RestoreDACRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
++{
++ R128InfoPtr info = R128PTR(pScrn);
++ unsigned char *R128MMIO = info->MMIO;
++
++ OUTREGP(R128_DAC_CNTL, restore->dac_cntl,
++ R128_DAC_RANGE_CNTL | R128_DAC_BLANKING);
++}
++
++/* Write RMX registers */
++void R128RestoreRMXRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+- CARD32 tmp;
+
+- if (info->BIOSDisplay != R128_DUALHEAD)
+- OUTREG(R128_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
+ OUTREG(R128_FP_HORZ_STRETCH, restore->fp_horz_stretch);
+ OUTREG(R128_FP_VERT_STRETCH, restore->fp_vert_stretch);
+ OUTREG(R128_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp);
+ OUTREG(R128_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp);
+ OUTREG(R128_FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid);
+ OUTREG(R128_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid);
+- OUTREG(R128_TMDS_CRC, restore->tmds_crc);
+- OUTREG(R128_FP_PANEL_CNTL, restore->fp_panel_cntl);
++}
++
++/* Write flat panel registers */
++void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
++{
++ R128InfoPtr info = R128PTR(pScrn);
++ unsigned char *R128MMIO = info->MMIO;
++
++ OUTREG(R128_TMDS_CRC, restore->tmds_crc);
++ OUTREG(R128_TMDS_TRANSMITTER_CNTL, restore->tmds_transmitter_cntl);
++ OUTREG(R128_FP_PANEL_CNTL, restore->fp_panel_cntl);
+ OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl & ~(CARD32)R128_FP_BLANK_DIS);
++}
+
+- if(info->isDFP) return;
++/* Write LVDS registers */
++void R128RestoreLVDSRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
++{
++ R128InfoPtr info = R128PTR(pScrn);
++ unsigned char *R128MMIO = info->MMIO;
++ CARD32 tmp;
+
+ tmp = INREG(R128_LVDS_GEN_CNTL);
+ if ((tmp & (R128_LVDS_ON | R128_LVDS_BLON)) ==
+@@ -2885,7 +2903,10 @@ static void R128Restore(ScrnInfoPtr pScrn)
+ R128RestoreDDARegisters(pScrn, restore);
+ R128RestoreCrtcRegisters(pScrn, restore);
+ R128RestorePLLRegisters(pScrn, restore);
++ R128RestoreDACRegisters(pScrn, restore);
++ R128RestoreRMXRegisters(pScrn, restore);
+ R128RestoreFPRegisters(pScrn, restore);
++ R128RestoreLVDSRegisters(pScrn, restore);
+ }
+
+ #ifdef WITH_VGAHW
+@@ -3058,21 +3079,14 @@ Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+ if((info->DisplayType == MT_DFP) ||
+ (info->DisplayType == MT_LCD))
+ {
+- save->crtc_ext_cntl = R128_VGA_ATI_LINEAR |
+- R128_XCRT_CNT_EN;
+ save->crtc_gen_cntl &= ~(R128_CRTC_DBL_SCAN_EN |
+ R128_CRTC_INTERLACE_EN);
+ }
+- else
+- save->crtc_ext_cntl = R128_VGA_ATI_LINEAR |
++
++ save->crtc_ext_cntl = R128_VGA_ATI_LINEAR |
+ R128_XCRT_CNT_EN |
+ R128_CRTC_CRT_ON;
+
+- save->dac_cntl = (R128_DAC_MASK_ALL
+- | R128_DAC_VGA_ADR_EN
+- | (info->dac6bits ? 0 : R128_DAC_8BIT_EN));
+-
+-
+ if(info->isDFP && !info->isPro2)
+ {
+ if(info->PanelXRes < mode->CrtcHDisplay)
+@@ -3224,36 +3238,50 @@ Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
+ return TRUE;
+ }
+
+-/* Define CRTC registers for requested video mode. */
+-void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
+- DisplayModePtr mode, R128InfoPtr info)
++/* Define DAC registers for the requested video mode. */
++void R128InitDACRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output)
++{
++ ScrnInfoPtr pScrn = output->scrn;
++ R128InfoPtr info = R128PTR(pScrn);
++ xf86CrtcPtr crtc = output->crtc;
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
++
++ save->dac_cntl = (R128_DAC_MASK_ALL | R128_DAC_VGA_ADR_EN |
++ (!r128_crtc->crtc_id ? 0 : R128_DAC_CRT_SEL_CRTC2) |
++ (info->dac6bits ? 0 : R128_DAC_8BIT_EN));
++}
++
++/* Define RMX registers for the requested video mode. */
++void R128InitRMXRegisters(R128SavePtr orig, R128SavePtr save,
++ xf86OutputPtr output, DisplayModePtr mode)
+ {
++ R128OutputPrivatePtr r128_output = output->driver_private;
++
+ int xres = mode->CrtcHDisplay;
+ int yres = mode->CrtcVDisplay;
+ float Hratio, Vratio;
+
+- if (info->BIOSDisplay == R128_BIOS_DISPLAY_CRT) {
+- save->crtc_ext_cntl |= R128_CRTC_CRT_ON;
+- save->crtc2_gen_cntl = 0;
+- save->fp_gen_cntl = orig->fp_gen_cntl;
+- save->fp_gen_cntl &= ~(R128_FP_FPON |
+- R128_FP_CRTC_USE_SHADOW_VEND |
+- R128_FP_CRTC_HORZ_DIV2_EN |
+- R128_FP_CRTC_HOR_CRT_DIV2_DIS |
+- R128_FP_USE_SHADOW_EN);
+- save->fp_gen_cntl |= (R128_FP_SEL_CRTC2 |
+- R128_FP_CRTC_DONT_SHADOW_VPAR);
+- save->fp_panel_cntl = orig->fp_panel_cntl & (CARD32)~R128_FP_DIGON;
+- save->lvds_gen_cntl = orig->lvds_gen_cntl &
+- (CARD32)~(R128_LVDS_ON | R128_LVDS_BLON);
++ save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
++ save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
++ save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid;
++ save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid;
++
++ if (r128_output->type != OUTPUT_DVI && r128_output->type != OUTPUT_LVDS)
+ return;
+- }
+
+- if (xres > info->PanelXRes) xres = info->PanelXRes;
+- if (yres > info->PanelYRes) yres = info->PanelYRes;
++ if (r128_output->PanelXRes == 0 || r128_output->PanelYRes == 0) {
++ xres = r128_output->PanelXRes;
++ yres = r128_output->PanelYRes;
++
++ Hratio = 1.0;
++ Vratio = 1.0;
++ } else {
++ if (xres > r128_output->PanelXRes) xres = r128_output->PanelXRes;
++ if (yres > r128_output->PanelYRes) yres = r128_output->PanelYRes;
+
+- Hratio = (float)xres/(float)info->PanelXRes;
+- Vratio = (float)yres/(float)info->PanelYRes;
++ Hratio = (float)xres/(float)r128_output->PanelXRes;
++ Vratio = (float)yres/(float)r128_output->PanelYRes;
++ }
+
+ save->fp_horz_stretch =
+ (((((int)(Hratio * R128_HORZ_STRETCH_RATIO_MAX + 0.5))
+@@ -3263,7 +3291,7 @@ void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
+ R128_HORZ_STRETCH_RESERVED)));
+ save->fp_horz_stretch &= ~R128_HORZ_AUTO_RATIO_FIX_EN;
+ save->fp_horz_stretch &= ~R128_AUTO_HORZ_RATIO;
+- if (xres == info->PanelXRes)
++ if (xres == r128_output->PanelXRes)
+ save->fp_horz_stretch &= ~(R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE);
+ else
+ save->fp_horz_stretch |= (R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE);
+@@ -3274,67 +3302,60 @@ void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
+ (orig->fp_vert_stretch & (R128_VERT_PANEL_SIZE |
+ R128_VERT_STRETCH_RESERVED)));
+ save->fp_vert_stretch &= ~R128_VERT_AUTO_RATIO_EN;
+- if (yres == info->PanelYRes)
++ if (yres == r128_output->PanelYRes)
+ save->fp_vert_stretch &= ~(R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND);
+ else
+ save->fp_vert_stretch |= (R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND);
++}
+
+- save->fp_gen_cntl = (orig->fp_gen_cntl &
+- (CARD32)~(R128_FP_SEL_CRTC2 |
+- R128_FP_CRTC_USE_SHADOW_VEND |
+- R128_FP_CRTC_HORZ_DIV2_EN |
+- R128_FP_CRTC_HOR_CRT_DIV2_DIS |
+- R128_FP_USE_SHADOW_EN));
+-
+- save->fp_panel_cntl = orig->fp_panel_cntl;
+- save->lvds_gen_cntl = orig->lvds_gen_cntl;
+- save->tmds_crc = orig->tmds_crc;
+-
+- /* Disable CRT output by disabling CRT output and setting the CRT
+- DAC to use CRTC2, which we set to 0's. In the future, we will
+- want to use the dual CRTC capabilities of the R128 to allow both
+- the flat panel and external CRT to either simultaneously display
+- the same image or display two different images. */
+-
+-
+- if(!info->isDFP){
+- if (info->BIOSDisplay == R128_BIOS_DISPLAY_FP_CRT) {
+- save->crtc_ext_cntl |= R128_CRTC_CRT_ON;
+- } else if (info->BIOSDisplay == R128_DUALHEAD) {
+- save->crtc_ext_cntl |= R128_CRTC_CRT_ON;
+- save->dac_cntl |= R128_DAC_CRT_SEL_CRTC2;
+- save->dac_cntl |= R128_DAC_PALETTE2_SNOOP_EN;
+- } else {
+- save->crtc_ext_cntl &= ~R128_CRTC_CRT_ON;
+- save->dac_cntl |= R128_DAC_CRT_SEL_CRTC2;
+- save->crtc2_gen_cntl = 0;
+- }
+- }
++/* Define flat panel registers for the requested video mode. */
++void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output)
++{
++ xf86CrtcPtr crtc = output->crtc;
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
+
+ /* WARNING: Be careful about turning on the flat panel */
+- if(info->isDFP){
+- save->fp_gen_cntl = orig->fp_gen_cntl;
+-
+- save->fp_gen_cntl &= ~(R128_FP_CRTC_USE_SHADOW_VEND |
+- R128_FP_CRTC_USE_SHADOW_ROWCUR |
+- R128_FP_CRTC_HORZ_DIV2_EN |
+- R128_FP_CRTC_HOR_CRT_DIV2_DIS |
+- R128_FP_CRT_SYNC_SEL |
+- R128_FP_USE_SHADOW_EN);
+-
+- save->fp_panel_cntl |= (R128_FP_DIGON | R128_FP_BLON);
+- save->fp_gen_cntl |= (R128_FP_FPON | R128_FP_TDMS_EN |
+- R128_FP_CRTC_DONT_SHADOW_VPAR | R128_FP_CRTC_DONT_SHADOW_HEND);
+- save->tmds_transmitter_cntl = (orig->tmds_transmitter_cntl
+- & ~(CARD32)R128_TMDS_PLLRST) | R128_TMDS_PLLEN;
+- }
++ save->fp_gen_cntl = orig->fp_gen_cntl;
++ save->fp_panel_cntl = orig->fp_panel_cntl;
++ save->tmds_transmitter_cntl = orig->tmds_transmitter_cntl;
++ save->tmds_crc = orig->tmds_crc;
++
++ if (r128_crtc->crtc_id)
++ save->fp_gen_cntl |= R128_FP_SEL_CRTC2;
+ else
+- save->lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_BLON);
++ save->fp_gen_cntl &= ~R128_FP_SEL_CRTC2;
+
+- save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
+- save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
+- save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid;
+- save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid;
++ save->fp_gen_cntl &= ~(R128_FP_CRTC_USE_SHADOW_VEND |
++ R128_FP_CRTC_USE_SHADOW_ROWCUR |
++ R128_FP_CRTC_HORZ_DIV2_EN |
++ R128_FP_CRTC_HOR_CRT_DIV2_DIS |
++ R128_FP_CRT_SYNC_SEL |
++ R128_FP_USE_SHADOW_EN);
++
++ save->fp_gen_cntl |= (R128_FP_FPON |
++ R128_FP_TDMS_EN |
++ R128_FP_CRTC_DONT_SHADOW_VPAR |
++ R128_FP_CRTC_DONT_SHADOW_HEND);
++
++ save->fp_panel_cntl |= (R128_FP_DIGON | R128_FP_BLON);
++ save->tmds_transmitter_cntl &= ~R128_TMDS_PLLRST;
++ save->tmds_transmitter_cntl |= R128_TMDS_PLLEN;
++}
++
++/* Define LVDS registers for the requested video mode. */
++void R128InitLVDSRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output)
++{
++ xf86CrtcPtr crtc = output->crtc;
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
++
++ save->lvds_gen_cntl = orig->lvds_gen_cntl;
++
++ if (r128_crtc->crtc_id)
++ save->lvds_gen_cntl |= R128_LVDS_SEL_CRTC2;
++ else
++ save->lvds_gen_cntl &= ~R128_LVDS_SEL_CRTC2;
++
++ save->lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_BLON);
+ }
+
+ /* Define PLL registers for requested video mode. */
+diff --git a/src/r128_output.c b/src/r128_output.c
+index 89a2958..4638067 100644
+--- a/src/r128_output.c
++++ b/src/r128_output.c
+@@ -81,6 +81,31 @@ static void r128_mode_prepare(xf86OutputPtr output)
+
+ static void r128_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
+ {
++ ScrnInfoPtr pScrn = output->scrn;
++ R128InfoPtr info = R128PTR(pScrn);
++ R128OutputPrivatePtr r128_output = output->driver_private;
++ xf86CrtcPtr crtc = output->crtc;
++ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
++
++ if (r128_crtc->crtc_id == 0)
++ R128InitRMXRegisters(&info->SavedReg, &info->ModeReg, output, adjusted_mode);
++
++ if (r128_output->type == OUTPUT_DVI)
++ R128InitFPRegisters(&info->SavedReg, &info->ModeReg, output);
++ else if (r128_output->type == OUTPUT_LVDS)
++ R128InitLVDSRegisters(&info->SavedReg, &info->ModeReg, output);
++ else if (r128_output->type == OUTPUT_VGA)
++ R128InitDACRegisters(&info->SavedReg, &info->ModeReg, output);
++
++ if (r128_crtc->crtc_id == 0)
++ R128RestoreRMXRegisters(pScrn, &info->ModeReg);
++
++ if (r128_output->type == OUTPUT_DVI)
++ R128RestoreFPRegisters(pScrn, &info->ModeReg);
++ else if (r128_output->type == OUTPUT_LVDS)
++ R128RestoreLVDSRegisters(pScrn, &info->ModeReg);
++ else if (r128_output->type == OUTPUT_VGA)
++ R128RestoreDACRegisters(pScrn, &info->ModeReg);
+ }
+
+ static void r128_mode_commit(xf86OutputPtr output)
+@@ -455,7 +480,10 @@ Bool R128SetupConnectors(ScrnInfoPtr pScrn)
+ }
+ r128_output->ddc_i2c = i2c;
+ R128I2CInit(output, &r128_output->pI2CBus, output->name);
+- }
++ } else if (conntype == CONNECTOR_LVDS) {
++ r128_output->PanelXRes = info->PanelXRes;
++ r128_output->PanelYRes = info->PanelYRes;
++ }
+
+ R128SetOutputType(pScrn, r128_output);
+ }
+diff --git a/src/r128_probe.h b/src/r128_probe.h
+index f521a13..95988ec 100644
+--- a/src/r128_probe.h
++++ b/src/r128_probe.h
+@@ -161,6 +161,8 @@ typedef struct _R128OutputPrivateRec {
+ R128MonitorType MonType;
+ I2CBusPtr pI2CBus;
+ R128I2CBusRec ddc_i2c;
++ int PanelXRes;
++ int PanelYRes;
+ } R128OutputPrivateRec, *R128OutputPrivatePtr;
+
+ #define R128_MAX_CRTC 2
+--
+2.2.2
+
+
+From 3bbce42414abea6c9977ff2b023ce3210d78f008 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Wed, 9 Jul 2014 11:40:35 -0700
+Subject: Move display enabling code to DPMS
+
+This ensures that DAC, TMDS and LVDS enable bits are properly saved and
+only set in the dpms hook.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ src/r128_driver.c | 10 ++--------
+ src/r128_output.c | 18 ++++++++++++++++--
+ 2 files changed, 18 insertions(+), 10 deletions(-)
+
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index 8e15b0c..4c03060 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -3083,9 +3083,7 @@ Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+ R128_CRTC_INTERLACE_EN);
+ }
+
+- save->crtc_ext_cntl = R128_VGA_ATI_LINEAR |
+- R128_XCRT_CNT_EN |
+- R128_CRTC_CRT_ON;
++ save->crtc_ext_cntl |= R128_VGA_ATI_LINEAR | R128_XCRT_CNT_EN;
+
+ if(info->isDFP && !info->isPro2)
+ {
+@@ -3332,9 +3330,7 @@ void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr outpu
+ R128_FP_CRT_SYNC_SEL |
+ R128_FP_USE_SHADOW_EN);
+
+- save->fp_gen_cntl |= (R128_FP_FPON |
+- R128_FP_TDMS_EN |
+- R128_FP_CRTC_DONT_SHADOW_VPAR |
++ save->fp_gen_cntl |= (R128_FP_CRTC_DONT_SHADOW_VPAR |
+ R128_FP_CRTC_DONT_SHADOW_HEND);
+
+ save->fp_panel_cntl |= (R128_FP_DIGON | R128_FP_BLON);
+@@ -3354,8 +3350,6 @@ void R128InitLVDSRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr out
+ save->lvds_gen_cntl |= R128_LVDS_SEL_CRTC2;
+ else
+ save->lvds_gen_cntl &= ~R128_LVDS_SEL_CRTC2;
+-
+- save->lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_BLON);
+ }
+
+ /* Define PLL registers for requested video mode. */
+diff --git a/src/r128_output.c b/src/r128_output.c
+index 4638067..79c80bf 100644
+--- a/src/r128_output.c
++++ b/src/r128_output.c
+@@ -176,15 +176,22 @@ void R128DPMSSetOn(xf86OutputPtr output)
+ unsigned char *R128MMIO = info->MMIO;
+ R128OutputPrivatePtr r128_output = output->driver_private;
+ R128MonitorType MonType = r128_output->MonType;
++ R128SavePtr save = &info->ModeReg;
+
+ switch(MonType) {
+ case MT_LCD:
+ OUTREGP(R128_LVDS_GEN_CNTL, R128_LVDS_BLON, ~R128_LVDS_BLON);
+ usleep(info->PanelPwrDly * 1000);
+ OUTREGP(R128_LVDS_GEN_CNTL, R128_LVDS_ON, ~R128_LVDS_ON);
++ save->lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_BLON);
+ break;
+ case MT_DFP:
+- OUTREGP(R128_FP_GEN_CNTL, (R128_FP_FPON | R128_FP_TDMS_EN), ~(R128_FP_FPON | R128_FP_TDMS_EN));
++ OUTREGP(R128_FP_GEN_CNTL, (R128_FP_FPON | R128_FP_TDMS_EN), ~(R128_FP_FPON | R128_FP_TDMS_EN));
++ save->fp_gen_cntl |= (R128_FP_FPON | R128_FP_TDMS_EN);
++ break;
++ case MT_CRT:
++ OUTREGP(R128_CRTC_EXT_CNTL, R128_CRTC_CRT_ON, ~R128_CRTC_CRT_ON);
++ save->crtc_ext_cntl |= R128_CRTC_CRT_ON;
+ break;
+ default:
+ break;
+@@ -198,13 +205,20 @@ void R128DPMSSetOff(xf86OutputPtr output)
+ unsigned char *R128MMIO = info->MMIO;
+ R128OutputPrivatePtr r128_output = output->driver_private;
+ R128MonitorType MonType = r128_output->MonType;
++ R128SavePtr save = &info->ModeReg;
+
+ switch(MonType) {
+ case MT_LCD:
+ OUTREGP(R128_LVDS_GEN_CNTL, 0, ~(R128_LVDS_BLON | R128_LVDS_ON));
++ save->lvds_gen_cntl &= ~(R128_LVDS_BLON | R128_LVDS_ON);
+ break;
+ case MT_DFP:
+- OUTREGP(R128_FP_GEN_CNTL, 0, ~(R128_FP_FPON | R128_FP_TDMS_EN));
++ OUTREGP(R128_FP_GEN_CNTL, 0, ~(R128_FP_FPON | R128_FP_TDMS_EN));
++ save->fp_gen_cntl &= ~(R128_FP_FPON | R128_FP_TDMS_EN);
++ break;
++ case MT_CRT:
++ OUTREGP(R128_CRTC_EXT_CNTL, 0, ~(R128_CRTC_CRT_ON));
++ save->crtc_ext_cntl &= ~(R128_CRTC_CRT_ON);
+ break;
+ default:
+ break;
+--
+2.2.2
+
+
+From e9ea36390ea0478c4b867df3bffdf2b122e0cb15 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Wed, 16 Jul 2014 00:57:18 -0700
+Subject: Change register name
+
+Surely this is a typo.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+---
+ src/r128_output.c | 8 ++++----
+ src/r128_reg.h | 2 +-
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/r128_output.c b/src/r128_output.c
+index 79c80bf..d7a1c55 100644
+--- a/src/r128_output.c
++++ b/src/r128_output.c
+@@ -186,8 +186,8 @@ void R128DPMSSetOn(xf86OutputPtr output)
+ save->lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_BLON);
+ break;
+ case MT_DFP:
+- OUTREGP(R128_FP_GEN_CNTL, (R128_FP_FPON | R128_FP_TDMS_EN), ~(R128_FP_FPON | R128_FP_TDMS_EN));
+- save->fp_gen_cntl |= (R128_FP_FPON | R128_FP_TDMS_EN);
++ OUTREGP(R128_FP_GEN_CNTL, (R128_FP_FPON | R128_FP_TMDS_EN), ~(R128_FP_FPON | R128_FP_TMDS_EN));
++ save->fp_gen_cntl |= (R128_FP_FPON | R128_FP_TMDS_EN);
+ break;
+ case MT_CRT:
+ OUTREGP(R128_CRTC_EXT_CNTL, R128_CRTC_CRT_ON, ~R128_CRTC_CRT_ON);
+@@ -213,8 +213,8 @@ void R128DPMSSetOff(xf86OutputPtr output)
+ save->lvds_gen_cntl &= ~(R128_LVDS_BLON | R128_LVDS_ON);
+ break;
+ case MT_DFP:
+- OUTREGP(R128_FP_GEN_CNTL, 0, ~(R128_FP_FPON | R128_FP_TDMS_EN));
+- save->fp_gen_cntl &= ~(R128_FP_FPON | R128_FP_TDMS_EN);
++ OUTREGP(R128_FP_GEN_CNTL, 0, ~(R128_FP_FPON | R128_FP_TMDS_EN));
++ save->fp_gen_cntl &= ~(R128_FP_FPON | R128_FP_TMDS_EN);
+ break;
+ case MT_CRT:
+ OUTREGP(R128_CRTC_EXT_CNTL, 0, ~(R128_CRTC_CRT_ON));
+diff --git a/src/r128_reg.h b/src/r128_reg.h
+index dac22e6..9ba0de5 100644
+--- a/src/r128_reg.h
++++ b/src/r128_reg.h
+@@ -599,7 +599,7 @@
+ #define R128_FP_GEN_CNTL 0x0284
+ # define R128_FP_FPON (1 << 0)
+ # define R128_FP_BLANK_DIS (1 << 1)
+-# define R128_FP_TDMS_EN (1 << 2)
++# define R128_FP_TMDS_EN (1 << 2)
+ # define R128_FP_DETECT_SENSE (1 << 8)
+ # define R128_FP_SEL_CRTC2 (1 << 13)
+ # define R128_FP_CRTC_DONT_SHADOW_VPAR (1 << 16)
+--
+2.2.2
+
+
+From c95ce4251921f09101911ca5c4ff3940c38cc6b5 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Wed, 16 Jul 2014 01:29:19 -0700
+Subject: Get entity without code duplication
+
+This fixes the parts of the code that were not using the helper function
+to find the entity.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+---
+ src/r128_accel.c | 8 ++------
+ src/r128_driver.c | 34 ++++++----------------------------
+ 2 files changed, 8 insertions(+), 34 deletions(-)
+
+diff --git a/src/r128_accel.c b/src/r128_accel.c
+index 7ffd15f..4d666c7 100644
+--- a/src/r128_accel.c
++++ b/src/r128_accel.c
+@@ -1853,12 +1853,8 @@ static void R128MMIOAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a)
+
+ if(xf86IsEntityShared(pScrn->entityList[0]))
+ {
+- DevUnion* pPriv;
+- R128EntPtr pR128Ent;
+- pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+- getR128EntityIndex());
+- pR128Ent = pPriv->ptr;
+-
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
++
+ /*if there are more than one devices sharing this entity, we
+ have to assign this call back, otherwise the XAA will be
+ disabled */
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index 4c03060..c62a1af 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -241,9 +241,7 @@ static Bool R128MapMMIO(ScrnInfoPtr pScrn)
+ /* If the primary screen has already mapped the MMIO region,
+ use its pointer instead of mapping it a second time. */
+ if (info->IsSecondary) {
+- DevUnion* pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+- getR128EntityIndex());
+- R128EntPtr pR128Ent = pPriv->ptr;
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+ R128InfoPtr info0 = R128PTR(pR128Ent->pPrimaryScrn);
+ info->MMIO=info0->MMIO;
+ if (info->MMIO) return TRUE;
+@@ -482,11 +480,7 @@ static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
+
+ if(info->DisplayType > MT_NONE)
+ {
+- DevUnion* pPriv;
+- R128EntPtr pR128Ent;
+- pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+- getR128EntityIndex());
+- pR128Ent = pPriv->ptr;
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+ pR128Ent->HasSecondary = TRUE;
+
+ }
+@@ -506,11 +500,7 @@ static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
+ If something on CRT port, treat it as primary*/
+ if(xf86IsEntityShared(pScrn->entityList[0]))
+ {
+- DevUnion* pPriv;
+- R128EntPtr pR128Ent;
+- pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+- getR128EntityIndex());
+- pR128Ent = pPriv->ptr;
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+ pR128Ent->BypassSecondary = TRUE;
+ }
+
+@@ -1427,24 +1417,16 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
+ {
+ if(xf86IsPrimInitDone(pScrn->entityList[0]))
+ {
+- DevUnion* pPriv;
+- R128EntPtr pR128Ent;
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+ info->IsSecondary = TRUE;
+- pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+- getR128EntityIndex());
+- pR128Ent = pPriv->ptr;
+ if(pR128Ent->BypassSecondary) return FALSE;
+ pR128Ent->pSecondaryScrn = pScrn;
+ }
+ else
+ {
+- DevUnion* pPriv;
+- R128EntPtr pR128Ent;
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+ info->IsPrimary = TRUE;
+ xf86SetPrimInitDone(pScrn->entityList[0]);
+- pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+- getR128EntityIndex());
+- pR128Ent = pPriv->ptr;
+ pR128Ent->pPrimaryScrn = pScrn;
+ pR128Ent->IsDRIEnabled = FALSE;
+ pR128Ent->BypassSecondary = FALSE;
+@@ -1894,11 +1876,7 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
+ R128DRIScreenInit(pScreen);
+ if(xf86IsEntityShared(pScrn->entityList[0]))
+ {
+- DevUnion* pPriv;
+- R128EntPtr pR128Ent;
+- pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+- getR128EntityIndex());
+- pR128Ent = pPriv->ptr;
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+ pR128Ent->IsDRIEnabled = info->directRenderingEnabled;
+ }
+ }
+--
+2.2.2
+
+
+From d05123eab19705d23310d06a299e61093abbe6cc Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Wed, 16 Jul 2014 17:23:37 -0700
+Subject: Cleanup entity struct
+
+This moves HasCRTC2 into the entity to make it more similar to radeon.
+It also removes IsDRIEnabled for being dead code.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+---
+ src/r128.h | 1 -
+ src/r128_crtc.c | 3 +--
+ src/r128_driver.c | 21 ++++++++-------------
+ src/r128_output.c | 12 +++++++-----
+ src/r128_probe.c | 1 -
+ src/r128_probe.h | 3 +--
+ 6 files changed, 17 insertions(+), 24 deletions(-)
+
+diff --git a/src/r128.h b/src/r128.h
+index d01b5c1..0308130 100644
+--- a/src/r128.h
++++ b/src/r128.h
+@@ -520,7 +520,6 @@ typedef struct {
+ R128BIOSConnector BiosConnector[R128_MAX_BIOS_CONNECTOR];
+
+ /****** Added for dualhead support *******************/
+- BOOL HasCRTC2; /* M3/M4 */
+ BOOL IsSecondary; /* second Screen */
+ BOOL IsPrimary; /* primary Screen */
+ BOOL UseCRT; /* force use CRT port as primary */
+diff --git a/src/r128_crtc.c b/src/r128_crtc.c
+index 9c3d0a9..e48e4d5 100644
+--- a/src/r128_crtc.c
++++ b/src/r128_crtc.c
+@@ -388,7 +388,6 @@ static const xf86CrtcFuncsRec r128_crtc_funcs = {
+ Bool R128AllocateControllers(ScrnInfoPtr pScrn, int mask)
+ {
+ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+- R128InfoPtr info = R128PTR(pScrn);
+
+ if (mask & 1) {
+ if (pR128Ent->Controller[0])
+@@ -407,7 +406,7 @@ Bool R128AllocateControllers(ScrnInfoPtr pScrn, int mask)
+ }
+
+ if (mask & 2) {
+- if (!info->HasCRTC2)
++ if (!pR128Ent->HasCRTC2)
+ return TRUE;
+
+ pR128Ent->pCrtc[1] = xf86CrtcCreate(pScrn, &r128_crtc_funcs);
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index c62a1af..3cd3773 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -469,8 +469,9 @@ static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Video BIOS not found!\n");
+ }
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+
+- if(info->HasCRTC2)
++ if(pR128Ent->HasCRTC2)
+ {
+ if(info->IsSecondary)
+ {
+@@ -480,7 +481,6 @@ static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
+
+ if(info->DisplayType > MT_NONE)
+ {
+- R128EntPtr pR128Ent = R128EntPriv(pScrn);
+ pR128Ent->HasSecondary = TRUE;
+
+ }
+@@ -771,6 +771,7 @@ static Bool R128PreInitWeight(ScrnInfoPtr pScrn)
+ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+ EntityInfoPtr pEnt = info->pEnt;
+ GDevPtr dev = pEnt->device;
+@@ -865,7 +866,7 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
+ } else {
+ info->isDFP = FALSE;
+ info->isPro2 = FALSE;
+- info->HasCRTC2 = FALSE;
++ pR128Ent->HasCRTC2 = FALSE;
+ switch (info->Chipset) {
+ /* R128 Pro and Pro2 can have DFP, we will deal with it.
+ No support for dual-head/xinerama yet.
+@@ -918,7 +919,7 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
+ case PCI_CHIP_RAGE128ML:
+ info->HasPanelRegs = TRUE;
+ /* which chips support dualhead? */
+- info->HasCRTC2 = TRUE;
++ pR128Ent->HasCRTC2 = TRUE;
+ break;
+ case PCI_CHIP_RAGE128RE:
+ case PCI_CHIP_RAGE128RF:
+@@ -1428,7 +1429,6 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
+ info->IsPrimary = TRUE;
+ xf86SetPrimInitDone(pScrn->entityList[0]);
+ pR128Ent->pPrimaryScrn = pScrn;
+- pR128Ent->IsDRIEnabled = FALSE;
+ pR128Ent->BypassSecondary = FALSE;
+ pR128Ent->HasSecondary = FALSE;
+ pR128Ent->RestorePrimary = FALSE;
+@@ -1872,13 +1872,7 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
+ "section in your XFConfig file.\n");
+ }
+ else
+- info->directRenderingEnabled =
+- R128DRIScreenInit(pScreen);
+- if(xf86IsEntityShared(pScrn->entityList[0]))
+- {
+- R128EntPtr pR128Ent = R128EntPriv(pScrn);
+- pR128Ent->IsDRIEnabled = info->directRenderingEnabled;
+- }
++ info->directRenderingEnabled = R128DRIScreenInit(pScreen);
+ }
+ }
+ }
+@@ -2854,6 +2848,7 @@ static void R128Save(ScrnInfoPtr pScrn)
+ static void R128Restore(ScrnInfoPtr pScrn)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+ R128SavePtr restore = &info->SavedReg;
+
+@@ -2873,7 +2868,7 @@ static void R128Restore(ScrnInfoPtr pScrn)
+ OUTREG(R128_DP_DATATYPE, restore->dp_datatype);
+
+ R128RestoreCommonRegisters(pScrn, restore);
+- if (info->HasCRTC2) {
++ if (pR128Ent->HasCRTC2) {
+ R128RestoreDDA2Registers(pScrn, restore);
+ R128RestoreCrtc2Registers(pScrn, restore);
+ R128RestorePLL2Registers(pScrn, restore);
+diff --git a/src/r128_output.c b/src/r128_output.c
+index d7a1c55..e5306d6 100644
+--- a/src/r128_output.c
++++ b/src/r128_output.c
+@@ -400,13 +400,14 @@ void R128SetOutputType(ScrnInfoPtr pScrn, R128OutputPrivatePtr r128_output)
+
+ void R128SetupGenericConnectors(ScrnInfoPtr pScrn)
+ {
+- R128InfoPtr info = R128PTR(pScrn);
++ R128InfoPtr info = R128PTR(pScrn);
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+
+- if (!info->HasCRTC2 && !info->isDFP) {
++ if (!pR128Ent->HasCRTC2 && !info->isDFP) {
+ info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
+ info->BiosConnector[0].valid = TRUE;
+ return;
+- } else if (!info->HasCRTC2) {
++ } else if (!pR128Ent->HasCRTC2) {
+ info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_D;
+ info->BiosConnector[0].valid = TRUE;
+ return;
+@@ -421,7 +422,8 @@ void R128SetupGenericConnectors(ScrnInfoPtr pScrn)
+
+ Bool R128SetupConnectors(ScrnInfoPtr pScrn)
+ {
+- R128InfoPtr info = R128PTR(pScrn);
++ R128InfoPtr info = R128PTR(pScrn);
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+ xf86OutputPtr output;
+ int num_vga = 0;
+ int num_dvi = 0;
+@@ -476,7 +478,7 @@ Bool R128SetupConnectors(ScrnInfoPtr pScrn)
+ output->doubleScanAllowed = TRUE;
+ output->driver_private = r128_output;
+ output->possible_clones = 0;
+- if (conntype == CONNECTOR_LVDS || !info->HasCRTC2)
++ if (conntype == CONNECTOR_LVDS || !pR128Ent->HasCRTC2)
+ output->possible_crtcs = 1;
+ else
+ output->possible_crtcs = 2;
+diff --git a/src/r128_probe.c b/src/r128_probe.c
+index e623bc9..348d15b 100644
+--- a/src/r128_probe.c
++++ b/src/r128_probe.c
+@@ -288,7 +288,6 @@ r128_get_scrninfo(int entity_num)
+ R128EntPtr pR128Ent;
+ pPriv->ptr = xnfcalloc(sizeof(R128EntRec), 1);
+ pR128Ent = pPriv->ptr;
+- pR128Ent->IsDRIEnabled = FALSE;
+ pR128Ent->BypassSecondary = FALSE;
+ pR128Ent->HasSecondary = FALSE;
+ pR128Ent->IsSecondaryRestored = FALSE;
+diff --git a/src/r128_probe.h b/src/r128_probe.h
+index 95988ec..426840a 100644
+--- a/src/r128_probe.h
++++ b/src/r128_probe.h
+@@ -170,9 +170,8 @@ typedef struct _R128OutputPrivateRec {
+
+ typedef struct
+ {
+- Bool IsDRIEnabled;
+-
+ Bool HasSecondary;
++ Bool HasCRTC2;
+ Bool BypassSecondary;
+ /*These two registers are used to make sure the CRTC2 is
+ retored before CRTC_EXT, otherwise it could lead to blank screen.*/
+--
+2.2.2
+
+
+From 866d0ad5295a7ca819b990f607d3e68582144b3b Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Wed, 16 Jul 2014 17:39:59 -0700
+Subject: Cleanup info struct
+
+This removes some dead code from info. It also fixes some indentation
+errors that were likely caused by sed.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+---
+ src/r128.h | 35 +++++++++++------------------------
+ src/r128_dri.c | 6 ------
+ src/r128_driver.c | 13 -------------
+ 3 files changed, 11 insertions(+), 43 deletions(-)
+
+diff --git a/src/r128.h b/src/r128.h
+index 0308130..b9fcc0a 100644
+--- a/src/r128.h
++++ b/src/r128.h
+@@ -296,7 +296,6 @@ typedef struct {
+ PCITAG PciTag;
+ #endif
+ int Chipset;
+- Bool Primary;
+
+ Bool FBDev;
+
+@@ -306,27 +305,20 @@ typedef struct {
+
+ void *MMIO; /* Map of MMIO region */
+ void *FB; /* Map of frame buffer */
++ CARD8 *VBIOS; /* Video BIOS for mode validation on FPs */
++ int FPBIOSstart; /* Start of the flat panel info */
+
+ CARD32 MemCntl;
+ CARD32 BusCntl;
+ unsigned long FbMapSize; /* Size of frame buffer, in bytes */
+- int Flags; /* Saved copy of mode flags */
+
+ CARD8 BIOSDisplay; /* Device the BIOS is set to display to */
+
+ Bool HasPanelRegs; /* Current chip can connect to a FP */
+- CARD8 *VBIOS; /* Video BIOS for mode validation on FPs */
+- int FPBIOSstart; /* Start of the flat panel info */
+
+ /* Computed values for FPs */
+ int PanelXRes;
+ int PanelYRes;
+- int HOverPlus;
+- int HSyncWidth;
+- int HBlank;
+- int VOverPlus;
+- int VSyncWidth;
+- int VBlank;
+ int PanelPwrDly;
+
+ R128PLLRec pll;
+@@ -343,7 +335,6 @@ typedef struct {
+ XAAInfoRecPtr accel;
+ #endif
+ Bool accelOn;
+-
+ Bool useEXA;
+ Bool RenderAccel;
+ #ifdef USE_EXA
+@@ -352,10 +343,6 @@ typedef struct {
+ struct r128_2d_state state_2d;
+ #endif
+
+- xf86CursorInfoPtr cursor;
+- unsigned long cursor_start;
+- unsigned long cursor_end;
+-
+ /*
+ * XAAForceTransBlit is used to change the behavior of the XAA
+ * SetupForScreenToScreenCopy function, to make it DGA-friendly.
+@@ -405,19 +392,19 @@ typedef struct {
+ Bool directRenderingEnabled;
+ DRIInfoPtr pDRIInfo;
+ int drmFD;
+- drm_context_t drmCtx;
++ drm_context_t drmCtx;
+ int numVisualConfigs;
+ __GLXvisualConfig *pVisualConfigs;
+ R128ConfigPrivPtr pVisualConfigsPriv;
+
+- drm_handle_t fbHandle;
++ drm_handle_t fbHandle;
+
+ drmSize registerSize;
+- drm_handle_t registerHandle;
++ drm_handle_t registerHandle;
+
+ Bool IsPCI; /* Current card is a PCI card */
+ drmSize pciSize;
+- drm_handle_t pciMemHandle;
++ drm_handle_t pciMemHandle;
+ drmAddress PCI; /* Map */
+
+ Bool allowPageFlip; /* Enable 3d page flipping */
+@@ -425,7 +412,7 @@ typedef struct {
+ int drmMinor;
+
+ drmSize agpSize;
+- drm_handle_t agpMemHandle; /* Handle from drmAgpAlloc */
++ drm_handle_t agpMemHandle; /* Handle from drmAgpAlloc */
+ unsigned long agpOffset;
+ drmAddress AGP; /* Map */
+ int agpMode;
+@@ -438,20 +425,20 @@ typedef struct {
+
+ /* CCE ring buffer data */
+ unsigned long ringStart; /* Offset into AGP space */
+- drm_handle_t ringHandle; /* Handle from drmAddMap */
++ drm_handle_t ringHandle; /* Handle from drmAddMap */
+ drmSize ringMapSize; /* Size of map */
+ int ringSize; /* Size of ring (in MB) */
+ drmAddress ring; /* Map */
+ int ringSizeLog2QW;
+
+ unsigned long ringReadOffset; /* Offset into AGP space */
+- drm_handle_t ringReadPtrHandle; /* Handle from drmAddMap */
++ drm_handle_t ringReadPtrHandle;/* Handle from drmAddMap */
+ drmSize ringReadMapSize; /* Size of map */
+ drmAddress ringReadPtr; /* Map */
+
+ /* CCE vertex/indirect buffer data */
+ unsigned long bufStart; /* Offset into AGP space */
+- drm_handle_t bufHandle; /* Handle from drmAddMap */
++ drm_handle_t bufHandle; /* Handle from drmAddMap */
+ drmSize bufMapSize; /* Size of map */
+ int bufSize; /* Size of buffers (in MB) */
+ drmAddress buf; /* Map */
+@@ -460,7 +447,7 @@ typedef struct {
+
+ /* CCE AGP Texture data */
+ unsigned long agpTexStart; /* Offset into AGP space */
+- drm_handle_t agpTexHandle; /* Handle from drmAddMap */
++ drm_handle_t agpTexHandle; /* Handle from drmAddMap */
+ drmSize agpTexMapSize; /* Size of map */
+ int agpTexSize; /* Size of AGP tex space (in MB) */
+ drmAddress agpTex; /* Map */
+diff --git a/src/r128_dri.c b/src/r128_dri.c
+index 2c905a4..f924331 100644
+--- a/src/r128_dri.c
++++ b/src/r128_dri.c
+@@ -1525,9 +1525,6 @@ static void R128DRITransitionTo3d(ScreenPtr pScreen)
+ R128EnablePageFlip(pScreen);
+
+ info->have3DWindows = 1;
+-
+- if (info->cursor_start)
+- xf86ForceHWCursor(pScreen, TRUE);
+ }
+
+ static void R128DRITransitionTo2d(ScreenPtr pScreen)
+@@ -1550,7 +1547,4 @@ static void R128DRITransitionTo2d(ScreenPtr pScreen)
+ }
+
+ info->have3DWindows = 0;
+-
+- if (info->cursor_start)
+- xf86ForceHWCursor(pScreen, FALSE);
+ }
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index 3cd3773..d17951d 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -2238,9 +2238,6 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
+ if (R128CursorInit(pScreen)) {
+ int width, height;
+
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "Using hardware cursor (scanline %ld)\n",
+- info->cursor_start / pScrn->displayWidth);
+ if (xf86QueryLargestOffscreenArea(pScreen, &width, &height,
+ 0, 0, 0)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+@@ -2253,7 +2250,6 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using software cursor\n");
+ }
+ } else {
+- info->cursor_start = 0;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using software cursor\n");
+ }
+
+@@ -3064,12 +3060,6 @@ Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+ mode->HDisplay = mode->CrtcHDisplay = info->PanelXRes;
+ if(info->PanelYRes < mode->CrtcVDisplay)
+ mode->VDisplay = mode->CrtcVDisplay = info->PanelYRes;
+- mode->CrtcHTotal = mode->CrtcHDisplay + info->HBlank;
+- mode->CrtcHSyncStart = mode->CrtcHDisplay + info->HOverPlus;
+- mode->CrtcHSyncEnd = mode->CrtcHSyncStart + info->HSyncWidth;
+- mode->CrtcVTotal = mode->CrtcVDisplay + info->VBlank;
+- mode->CrtcVSyncStart = mode->CrtcVDisplay + info->VOverPlus;
+- mode->CrtcVSyncEnd = mode->CrtcVSyncStart + info->VSyncWidth;
+ }
+
+ save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0xffff)
+@@ -3834,9 +3824,6 @@ static Bool R128CloseScreen(CLOSE_SCREEN_ARGS_DECL)
+ if (info->scratch_save) free(info->scratch_save);
+ info->scratch_save = NULL;
+
+- if (info->cursor) xf86DestroyCursorInfoRec(info->cursor);
+- info->cursor = NULL;
+-
+ if (info->DGAModes) free(info->DGAModes);
+ info->DGAModes = NULL;
+
+--
+2.2.2
+
+
+From b632e89b923179b16d0d38128209427f666b963c Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Wed, 16 Jul 2014 02:20:18 -0700
+Subject: Remove pointless output
+
+This removes a debug line to fix a compiler warning and make the
+crtc1 and crtc2 code more symmetric. The number of bits per pixel is
+easy to find out anyway.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+---
+ src/r128_driver.c | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index d17951d..6cd669a 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -3126,22 +3126,20 @@ Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
+ int hsync_wid;
+ int hsync_fudge;
+ int vsync_wid;
+- int bytpp;
+ int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 };
+
+ switch (info->CurrentLayout.pixel_code) {
+- case 4: format = 1; bytpp = 0; break;
+- case 8: format = 2; bytpp = 1; break;
+- case 15: format = 3; bytpp = 2; break; /* 555 */
+- case 16: format = 4; bytpp = 2; break; /* 565 */
+- case 24: format = 5; bytpp = 3; break; /* RGB */
+- case 32: format = 6; bytpp = 4; break; /* xRGB */
++ case 4: format = 1; break;
++ case 8: format = 2; break;
++ case 15: format = 3; break; /* 555 */
++ case 16: format = 4; break; /* 565 */
++ case 24: format = 5; break; /* RGB */
++ case 32: format = 6; break; /* xRGB */
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unsupported pixel depth (%d)\n", info->CurrentLayout.bitsPerPixel);
+ return FALSE;
+ }
+- R128TRACE(("Format = %d (%d bytes per pixel)\n", format, bytpp));
+
+ hsync_fudge = hsync_fudge_default[format-1];
+
+--
+2.2.2
+
+
+From 0d901460b375599c727928634d5f1067d2279844 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Wed, 16 Jul 2014 17:47:44 -0700
+Subject: Use standard integers
+
+To fix another warning, we need to be consistent about when we use
+CARD32 an when we use uint32_t. Xorg developers have decided on the
+latter as a convention.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+---
+ src/r128.h | 168 +++++++++++++++++++++++++-------------------------
+ src/r128_accel.c | 20 +++---
+ src/r128_crtc.c | 2 +-
+ src/r128_cursor.c | 14 ++---
+ src/r128_dga.c | 6 +-
+ src/r128_dri.c | 14 ++---
+ src/r128_driver.c | 14 ++---
+ src/r128_exa_render.c | 8 +--
+ src/r128_output.c | 4 +-
+ src/r128_probe.h | 14 ++---
+ src/r128_reg.h | 12 ++--
+ src/r128_video.c | 14 ++---
+ 12 files changed, 145 insertions(+), 145 deletions(-)
+
+diff --git a/src/r128.h b/src/r128.h
+index b9fcc0a..f361c2a 100644
+--- a/src/r128.h
++++ b/src/r128.h
+@@ -151,105 +151,105 @@ typedef struct { /* All values in XCLKS */
+
+ typedef struct {
+ /* Common registers */
+- CARD32 ovr_clr;
+- CARD32 ovr_wid_left_right;
+- CARD32 ovr_wid_top_bottom;
+- CARD32 ov0_scale_cntl;
+- CARD32 mpp_tb_config;
+- CARD32 mpp_gp_config;
+- CARD32 subpic_cntl;
+- CARD32 viph_control;
+- CARD32 i2c_cntl_1;
+- CARD32 gen_int_cntl;
+- CARD32 cap0_trig_cntl;
+- CARD32 cap1_trig_cntl;
+- CARD32 bus_cntl;
+- CARD32 config_cntl;
++ uint32_t ovr_clr;
++ uint32_t ovr_wid_left_right;
++ uint32_t ovr_wid_top_bottom;
++ uint32_t ov0_scale_cntl;
++ uint32_t mpp_tb_config;
++ uint32_t mpp_gp_config;
++ uint32_t subpic_cntl;
++ uint32_t viph_control;
++ uint32_t i2c_cntl_1;
++ uint32_t gen_int_cntl;
++ uint32_t cap0_trig_cntl;
++ uint32_t cap1_trig_cntl;
++ uint32_t bus_cntl;
++ uint32_t config_cntl;
+
+ /* Other registers to save for VT switches */
+- CARD32 dp_datatype;
+- CARD32 gen_reset_cntl;
+- CARD32 clock_cntl_index;
+- CARD32 amcgpio_en_reg;
+- CARD32 amcgpio_mask;
++ uint32_t dp_datatype;
++ uint32_t gen_reset_cntl;
++ uint32_t clock_cntl_index;
++ uint32_t amcgpio_en_reg;
++ uint32_t amcgpio_mask;
+
+ /* CRTC registers */
+- CARD32 crtc_gen_cntl;
+- CARD32 crtc_ext_cntl;
+- CARD32 dac_cntl;
+- CARD32 crtc_h_total_disp;
+- CARD32 crtc_h_sync_strt_wid;
+- CARD32 crtc_v_total_disp;
+- CARD32 crtc_v_sync_strt_wid;
+- CARD32 crtc_offset;
+- CARD32 crtc_offset_cntl;
+- CARD32 crtc_pitch;
++ uint32_t crtc_gen_cntl;
++ uint32_t crtc_ext_cntl;
++ uint32_t dac_cntl;
++ uint32_t crtc_h_total_disp;
++ uint32_t crtc_h_sync_strt_wid;
++ uint32_t crtc_v_total_disp;
++ uint32_t crtc_v_sync_strt_wid;
++ uint32_t crtc_offset;
++ uint32_t crtc_offset_cntl;
++ uint32_t crtc_pitch;
+
+ /* CRTC2 registers */
+- CARD32 crtc2_gen_cntl;
+- CARD32 crtc2_h_total_disp;
+- CARD32 crtc2_h_sync_strt_wid;
+- CARD32 crtc2_v_total_disp;
+- CARD32 crtc2_v_sync_strt_wid;
+- CARD32 crtc2_offset;
+- CARD32 crtc2_offset_cntl;
+- CARD32 crtc2_pitch;
++ uint32_t crtc2_gen_cntl;
++ uint32_t crtc2_h_total_disp;
++ uint32_t crtc2_h_sync_strt_wid;
++ uint32_t crtc2_v_total_disp;
++ uint32_t crtc2_v_sync_strt_wid;
++ uint32_t crtc2_offset;
++ uint32_t crtc2_offset_cntl;
++ uint32_t crtc2_pitch;
+
+ /* Flat panel registers */
+- CARD32 fp_crtc_h_total_disp;
+- CARD32 fp_crtc_v_total_disp;
+- CARD32 fp_gen_cntl;
+- CARD32 fp_h_sync_strt_wid;
+- CARD32 fp_horz_stretch;
+- CARD32 fp_panel_cntl;
+- CARD32 fp_v_sync_strt_wid;
+- CARD32 fp_vert_stretch;
+- CARD32 lvds_gen_cntl;
+- CARD32 tmds_crc;
+- CARD32 tmds_transmitter_cntl;
++ uint32_t fp_crtc_h_total_disp;
++ uint32_t fp_crtc_v_total_disp;
++ uint32_t fp_gen_cntl;
++ uint32_t fp_h_sync_strt_wid;
++ uint32_t fp_horz_stretch;
++ uint32_t fp_panel_cntl;
++ uint32_t fp_v_sync_strt_wid;
++ uint32_t fp_vert_stretch;
++ uint32_t lvds_gen_cntl;
++ uint32_t tmds_crc;
++ uint32_t tmds_transmitter_cntl;
+
+ /* Computed values for PLL */
+- CARD32 dot_clock_freq;
+- CARD32 pll_output_freq;
++ uint32_t dot_clock_freq;
++ uint32_t pll_output_freq;
+ int feedback_div;
+ int post_div;
+
+ /* PLL registers */
+- CARD32 ppll_ref_div;
+- CARD32 ppll_div_3;
+- CARD32 htotal_cntl;
++ uint32_t ppll_ref_div;
++ uint32_t ppll_div_3;
++ uint32_t htotal_cntl;
+
+ /* Computed values for PLL2 */
+- CARD32 dot_clock_freq_2;
+- CARD32 pll_output_freq_2;
++ uint32_t dot_clock_freq_2;
++ uint32_t pll_output_freq_2;
+ int feedback_div_2;
+ int post_div_2;
+
+ /* PLL2 registers */
+- CARD32 p2pll_ref_div;
+- CARD32 p2pll_div_0;
+- CARD32 htotal_cntl2;
++ uint32_t p2pll_ref_div;
++ uint32_t p2pll_div_0;
++ uint32_t htotal_cntl2;
+
+ /* DDA register */
+- CARD32 dda_config;
+- CARD32 dda_on_off;
++ uint32_t dda_config;
++ uint32_t dda_on_off;
+
+ /* DDA2 register */
+- CARD32 dda2_config;
+- CARD32 dda2_on_off;
++ uint32_t dda2_config;
++ uint32_t dda2_on_off;
+
+ /* Pallet */
+ Bool palette_valid;
+- CARD32 palette[256];
+- CARD32 palette2[256];
++ uint32_t palette[256];
++ uint32_t palette2[256];
+ } R128SaveRec, *R128SavePtr;
+
+ typedef struct {
+- CARD16 reference_freq;
+- CARD16 reference_div;
++ uint16_t reference_freq;
++ uint16_t reference_div;
+ unsigned min_pll_freq;
+ unsigned max_pll_freq;
+- CARD16 xclk;
++ uint16_t xclk;
+ } R128PLLRec, *R128PLLPtr;
+
+ typedef struct {
+@@ -305,14 +305,14 @@ typedef struct {
+
+ void *MMIO; /* Map of MMIO region */
+ void *FB; /* Map of frame buffer */
+- CARD8 *VBIOS; /* Video BIOS for mode validation on FPs */
++ uint8_t *VBIOS; /* Video BIOS for mode validation on FPs */
+ int FPBIOSstart; /* Start of the flat panel info */
+
+- CARD32 MemCntl;
+- CARD32 BusCntl;
++ uint32_t MemCntl;
++ uint32_t BusCntl;
+ unsigned long FbMapSize; /* Size of frame buffer, in bytes */
+
+- CARD8 BIOSDisplay; /* Device the BIOS is set to display to */
++ uint8_t BIOSDisplay; /* Device the BIOS is set to display to */
+
+ Bool HasPanelRegs; /* Current chip can connect to a FP */
+
+@@ -356,7 +356,7 @@ typedef struct {
+ /* Computed values for Rage 128 */
+ int pitch;
+ int datatype;
+- CARD32 dp_gui_master_cntl;
++ uint32_t dp_gui_master_cntl;
+
+ /* Saved values for ScreenToScreenCopy */
+ int xdir;
+@@ -477,18 +477,18 @@ typedef struct {
+ int log2TexGran;
+
+ /* Saved scissor values */
+- CARD32 sc_left;
+- CARD32 sc_right;
+- CARD32 sc_top;
+- CARD32 sc_bottom;
++ uint32_t sc_left;
++ uint32_t sc_right;
++ uint32_t sc_top;
++ uint32_t sc_bottom;
+
+- CARD32 re_top_left;
+- CARD32 re_width_height;
++ uint32_t re_top_left;
++ uint32_t re_width_height;
+
+- CARD32 aux_sc_cntl;
++ uint32_t aux_sc_cntl;
+
+ int irq;
+- CARD32 gen_int_cntl;
++ uint32_t gen_int_cntl;
+
+ Bool DMAForXv;
+ #endif
+@@ -643,7 +643,7 @@ extern void R128DoPrepareCopy(ScrnInfoPtr pScrn, uint32_t src_pitch_offset,
+
+ #define R128_VERBOSE 0
+
+-#define RING_LOCALS CARD32 *__head; int __count;
++#define RING_LOCALS uint32_t *__head; int __count;
+
+ #define R128CCE_REFRESH(pScrn, info) \
+ do { \
+@@ -684,12 +684,12 @@ do { \
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO, \
+ "ADVANCE_RING() used: %d+%d=%d/%d\n", \
+ info->indirectBuffer->used - info->indirectStart, \
+- __count * (int)sizeof(CARD32), \
++ __count * (int)sizeof(uint32_t), \
+ info->indirectBuffer->used - info->indirectStart + \
+- __count * (int)sizeof(CARD32), \
++ __count * (int)sizeof(uint32_t), \
+ info->indirectBuffer->total - info->indirectStart ); \
+ } \
+- info->indirectBuffer->used += __count * (int)sizeof(CARD32); \
++ info->indirectBuffer->used += __count * (int)sizeof(uint32_t); \
+ } while (0)
+
+ #define OUT_RING( x ) do { \
+diff --git a/src/r128_accel.c b/src/r128_accel.c
+index 4d666c7..99bfb20 100644
+--- a/src/r128_accel.c
++++ b/src/r128_accel.c
+@@ -145,9 +145,9 @@ void R128EngineReset(ScrnInfoPtr pScrn)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+- CARD32 clock_cntl_index;
+- CARD32 mclk_cntl;
+- CARD32 gen_reset_cntl;
++ uint32_t clock_cntl_index;
++ uint32_t mclk_cntl;
++ uint32_t gen_reset_cntl;
+
+ R128EngineFlush(pScrn);
+
+@@ -161,7 +161,7 @@ void R128EngineReset(ScrnInfoPtr pScrn)
+ OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI);
+ INREG(R128_GEN_RESET_CNTL);
+ OUTREG(R128_GEN_RESET_CNTL,
+- gen_reset_cntl & (CARD32)(~R128_SOFT_RESET_GUI));
++ gen_reset_cntl & (uint32_t)(~R128_SOFT_RESET_GUI));
+ INREG(R128_GEN_RESET_CNTL);
+
+ OUTPLL(R128_MCLK_CNTL, mclk_cntl);
+@@ -450,7 +450,7 @@ static void R128SetupForDashedLine(ScrnInfoPtr pScrn,
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+- CARD32 pat = *(CARD32 *)(pointer)pattern;
++ uint32_t pat = *(uint32_t *)(pointer)pattern;
+
+ #if X_BYTE_ORDER == X_LITTLE_ENDIAN
+ # define PAT_SHIFT(pat,n) pat << n
+@@ -847,10 +847,10 @@ static void R128SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+- CARD32 *p = (pointer)info->scratch_buffer[bufno];
++ uint32_t *p = (pointer)info->scratch_buffer[bufno];
+ int i;
+ int left = info->scanline_words;
+- volatile CARD32 *d;
++ volatile uint32_t *d;
+
+ if (info->scanline_direct) return;
+ --info->scanline_h;
+@@ -977,10 +977,10 @@ static void R128SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+- CARD32 *p = (pointer)info->scratch_buffer[bufno];
++ uint32_t *p = (pointer)info->scratch_buffer[bufno];
+ int i;
+ int left = info->scanline_words;
+- volatile CARD32 *d;
++ volatile uint32_t *d;
+
+ if (info->scanline_direct) return;
+ --info->scanline_h;
+@@ -1438,7 +1438,7 @@ static void R128CCESetupForDashedLine(ScrnInfoPtr pScrn,
+ int length, unsigned char *pattern)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+- CARD32 pat = *(CARD32 *)(pointer)pattern;
++ uint32_t pat = *(uint32_t *)(pointer)pattern;
+ RING_LOCALS;
+
+ R128CCE_REFRESH( pScrn, info );
+diff --git a/src/r128_crtc.c b/src/r128_crtc.c
+index e48e4d5..5f076cd 100644
+--- a/src/r128_crtc.c
++++ b/src/r128_crtc.c
+@@ -189,7 +189,7 @@ static void r128_crtc_mode_commit(xf86CrtcPtr crtc)
+ r128_crtc_dpms(crtc, DPMSModeOn);
+ }
+
+-static void r128_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, int size)
++static void r128_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green, uint16_t *blue, int size)
+ {
+ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
+ int i;
+diff --git a/src/r128_cursor.c b/src/r128_cursor.c
+index ad6752f..d42bea6 100644
+--- a/src/r128_cursor.c
++++ b/src/r128_cursor.c
+@@ -179,18 +179,18 @@ void r128_crtc_load_cursor_image(xf86CrtcPtr crtc, unsigned char *src)
+
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+- CARD32 *s = (pointer)src;
+- CARD32 *d = (pointer)(info->FB + r128_crtc->cursor_offset + pScrn->fbOffset);
+- CARD32 save1 = 0;
+- CARD32 save2 = 0;
++ uint32_t *s = (pointer)src;
++ uint32_t *d = (pointer)(info->FB + r128_crtc->cursor_offset + pScrn->fbOffset);
++ uint32_t save1 = 0;
++ uint32_t save2 = 0;
+ int y;
+
+ if (crtc_id == 0) {
+ save1 = INREG(R128_CRTC_GEN_CNTL);
+- OUTREG(R128_CRTC_GEN_CNTL, save1 & (CARD32)~R128_CRTC_CUR_EN);
++ OUTREG(R128_CRTC_GEN_CNTL, save1 & (uint32_t)~R128_CRTC_CUR_EN);
+ } else if (crtc_id == 1) {
+ save2 = INREG(R128_CRTC2_GEN_CNTL);
+- OUTREG(R128_CRTC2_GEN_CNTL, save2 & (CARD32)~R128_CRTC2_CUR_EN);
++ OUTREG(R128_CRTC2_GEN_CNTL, save2 & (uint32_t)~R128_CRTC2_CUR_EN);
+ }
+
+ #if X_BYTE_ORDER == X_BIG_ENDIAN
+@@ -255,7 +255,7 @@ Bool R128CursorInit(ScreenPtr pScreen)
+ void* osArea = NULL;
+ #endif
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+- CARD32 cursor_offset = 0;
++ uint32_t cursor_offset = 0;
+ int cpp = info->CurrentLayout.pixel_bytes;
+ int width;
+ int width_bytes;
+diff --git a/src/r128_dga.c b/src/r128_dga.c
+index d7fee02..bb4a1a6 100644
+--- a/src/r128_dga.c
++++ b/src/r128_dga.c
+@@ -332,7 +332,7 @@ R128_FillRect (
+ ){
+ R128InfoPtr info = R128PTR(pScrn);
+
+- (*info->accel->SetupForSolidFill)(pScrn, color, GXcopy, (CARD32)(~0));
++ (*info->accel->SetupForSolidFill)(pScrn, color, GXcopy, (uint32_t)(~0));
+ (*info->accel->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+
+ if (pScrn->bitsPerPixel == info->CurrentLayout.bitsPerPixel)
+@@ -351,7 +351,7 @@ R128_BlitRect(
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ (*info->accel->SetupForScreenToScreenCopy)(
+- pScrn, xdir, ydir, GXcopy, (CARD32)(~0), -1);
++ pScrn, xdir, ydir, GXcopy, (uint32_t)(~0), -1);
+ (*info->accel->SubsequentScreenToScreenCopy)(
+ pScrn, srcx, srcy, dstx, dsty, w, h);
+
+@@ -375,7 +375,7 @@ R128_BlitTransRect(
+ info->XAAForceTransBlit = TRUE;
+
+ (*info->accel->SetupForScreenToScreenCopy)(
+- pScrn, xdir, ydir, GXcopy, (CARD32)(~0), color);
++ pScrn, xdir, ydir, GXcopy, (uint32_t)(~0), color);
+
+ info->XAAForceTransBlit = FALSE;
+
+diff --git a/src/r128_dri.c b/src/r128_dri.c
+index f924331..467cd88 100644
+--- a/src/r128_dri.c
++++ b/src/r128_dri.c
+@@ -397,7 +397,7 @@ static void R128DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx)
+ pboxSave = pbox = REGION_RECTS(prgn);
+ nboxSave = nbox = REGION_NUM_RECTS(prgn);
+
+- (*info->accel->SetupForSolidFill)(pScrn, 0, GXcopy, (CARD32)(-1));
++ (*info->accel->SetupForSolidFill)(pScrn, 0, GXcopy, (uint32_t)(-1));
+ for (; nbox; nbox--, pbox++) {
+ (*info->accel->SubsequentSolidFillRect)(pScrn,
+ pbox->x1 + info->fbX,
+@@ -415,7 +415,7 @@ static void R128DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx)
+ nbox = nboxSave;
+
+ /* FIXME: this needs to consider depth tiling. */
+- (*info->accel->SetupForSolidFill)(pScrn, depth, GXcopy, (CARD32)(-1));
++ (*info->accel->SetupForSolidFill)(pScrn, depth, GXcopy, (uint32_t)(-1));
+ for (; nbox; nbox--, pbox++)
+ (*info->accel->SubsequentSolidFillRect)(pScrn,
+ pbox->x1 + info->depthX,
+@@ -647,7 +647,7 @@ static Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen)
+ static Bool R128DRIPciInit(R128InfoPtr info, ScreenPtr pScreen)
+ {
+ unsigned char *R128MMIO = info->MMIO;
+- CARD32 chunk;
++ uint32_t chunk;
+ int ret;
+ int flags;
+
+@@ -1413,12 +1413,12 @@ static void R128DRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+ if (!info->useEXA) {
+ (*info->accel->SetupForScreenToScreenCopy)(pScrn,
+ 1, 1, GXcopy,
+- (CARD32)(-1), -1);
++ (uint32_t)(-1), -1);
+ }
+ #endif
+ #ifdef USE_EXA
+ if (info->useEXA) {
+- CARD32 src_pitch_offset, dst_pitch_offset, datatype;
++ uint32_t src_pitch_offset, dst_pitch_offset, datatype;
+
+ R128GetPixmapOffsetPitch(pPix, &src_pitch_offset);
+ dst_pitch_offset = src_pitch_offset + (info->backOffset >> 5);
+@@ -1465,7 +1465,7 @@ static void R128EnablePageFlip(ScreenPtr pScreen)
+ if (!info->useEXA) {
+ (*info->accel->SetupForScreenToScreenCopy)(pScrn,
+ 1, 1, GXcopy,
+- (CARD32)(-1), -1);
++ (uint32_t)(-1), -1);
+
+ (*info->accel->SubsequentScreenToScreenCopy)(pScrn,
+ 0,
+@@ -1478,7 +1478,7 @@ static void R128EnablePageFlip(ScreenPtr pScreen)
+ #endif
+ #ifdef USE_EXA
+ if (info->useEXA) {
+- CARD32 src_pitch_offset, dst_pitch_offset, datatype;
++ uint32_t src_pitch_offset, dst_pitch_offset, datatype;
+
+ R128GetPixmapOffsetPitch(pPix, &src_pitch_offset);
+ dst_pitch_offset = src_pitch_offset + (info->backOffset >> 5);
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index 6cd669a..c541bfa 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -657,8 +657,8 @@ static Bool R128GetPLLParameters(ScrnInfoPtr pScrn)
+ pll->max_pll_freq = 25000;
+ pll->xclk = 10300;
+ } else {
+- CARD16 bios_header = R128_BIOS16(0x48);
+- CARD16 pll_info_block = R128_BIOS16(bios_header + 0x30);
++ uint16_t bios_header = R128_BIOS16(0x48);
++ uint16_t pll_info_block = R128_BIOS16(bios_header + 0x30);
+ R128TRACE(("Header at 0x%04x; PLL Information at 0x%04x\n",
+ bios_header, pll_info_block));
+
+@@ -1634,7 +1634,7 @@ static void R128LoadPalette(ScrnInfoPtr pScrn, int numColors,
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int i, j;
+ int c, index;
+- CARD16 lut_r[256], lut_g[256], lut_b[256];
++ uint16_t lut_r[256], lut_g[256], lut_b[256];
+
+ for (c = 0; c < xf86_config->num_crtc; c++) {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+@@ -2404,7 +2404,7 @@ void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ OUTREG(R128_TMDS_CRC, restore->tmds_crc);
+ OUTREG(R128_TMDS_TRANSMITTER_CNTL, restore->tmds_transmitter_cntl);
+ OUTREG(R128_FP_PANEL_CNTL, restore->fp_panel_cntl);
+- OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl & ~(CARD32)R128_FP_BLANK_DIS);
++ OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl & ~(uint32_t)R128_FP_BLANK_DIS);
+ }
+
+ /* Write LVDS registers */
+@@ -2412,7 +2412,7 @@ void R128RestoreLVDSRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+- CARD32 tmp;
++ uint32_t tmp;
+
+ tmp = INREG(R128_LVDS_GEN_CNTL);
+ if ((tmp & (R128_LVDS_ON | R128_LVDS_BLON)) ==
+@@ -2421,7 +2421,7 @@ void R128RestoreLVDSRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ } else {
+ if (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON)) {
+ OUTREG(R128_LVDS_GEN_CNTL,
+- restore->lvds_gen_cntl & (CARD32)~R128_LVDS_BLON);
++ restore->lvds_gen_cntl & (uint32_t)~R128_LVDS_BLON);
+ usleep(R128PTR(pScrn)->PanelPwrDly * 1000);
+ OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
+ } else {
+@@ -3643,7 +3643,7 @@ ModeStatus R128ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode,
+ if (R128_BIOS16(j+5)) j = R128_BIOS16(j+5);
+ else j += 9;
+
+- mode->Clock = (CARD32)R128_BIOS16(j) * 10;
++ mode->Clock = (uint32_t)R128_BIOS16(j) * 10;
+
+ mode->HDisplay = mode->CrtcHDisplay =
+ ((R128_BIOS16(j+10) & 0x01ff)+1)*8;
+diff --git a/src/r128_exa_render.c b/src/r128_exa_render.c
+index f00daf7..c0d3688 100644
+--- a/src/r128_exa_render.c
++++ b/src/r128_exa_render.c
+@@ -40,8 +40,8 @@
+ static struct {
+ Bool dst_alpha;
+ Bool src_alpha;
+- CARD32 sblend;
+- CARD32 dblend;
++ uint32_t sblend;
++ uint32_t dblend;
+ } R128BlendOp[] = {
+ /* Clear */
+ {0, 0, R128_ALPHA_BLEND_ZERO , R128_ALPHA_BLEND_ZERO},
+@@ -582,9 +582,9 @@ R128CCEPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+ return TRUE;
+ }
+
+-typedef union { float f; CARD32 i; } fi_type;
++typedef union { float f; uint32_t i; } fi_type;
+
+-static inline CARD32
++static inline uint32_t
+ R128FloatAsInt(float val)
+ {
+ fi_type fi;
+diff --git a/src/r128_output.c b/src/r128_output.c
+index e5306d6..7bb2e2a 100644
+--- a/src/r128_output.c
++++ b/src/r128_output.c
+@@ -234,7 +234,7 @@ static R128MonitorType R128DisplayDDCConnected(xf86OutputPtr output)
+
+ R128MonitorType MonType = MT_NONE;
+ xf86MonPtr *MonInfo = &output->MonInfo;
+- CARD32 mask1, mask2;
++ uint32_t mask1, mask2;
+
+ if (r128_output->type == OUTPUT_LVDS) {
+ return MT_LCD;
+@@ -346,7 +346,7 @@ static void R128I2CPutBits(I2CBusPtr b, int Clock, int data)
+ R128I2CBusPtr pR128I2CBus = b->DriverPrivate.ptr;
+
+ val = INREG(pR128I2CBus->ddc_reg)
+- & ~(CARD32)(pR128I2CBus->put_clk_mask | pR128I2CBus->put_data_mask);
++ & ~(uint32_t)(pR128I2CBus->put_clk_mask | pR128I2CBus->put_data_mask);
+ val |= (Clock ? 0 : pR128I2CBus->put_clk_mask);
+ val |= (data ? 0 : pR128I2CBus->put_data_mask);
+ OUTREG(pR128I2CBus->ddc_reg, val);
+diff --git a/src/r128_probe.h b/src/r128_probe.h
+index 426840a..40fe82b 100644
+--- a/src/r128_probe.h
++++ b/src/r128_probe.h
+@@ -129,11 +129,11 @@ typedef enum
+ } R128OutputType;
+
+ typedef struct {
+- CARD32 ddc_reg;
+- CARD32 put_clk_mask;
+- CARD32 put_data_mask;
+- CARD32 get_clk_mask;
+- CARD32 get_data_mask;
++ uint32_t ddc_reg;
++ uint32_t put_clk_mask;
++ uint32_t put_data_mask;
++ uint32_t get_clk_mask;
++ uint32_t get_data_mask;
+ } R128I2CBusRec, *R128I2CBusPtr;
+
+ typedef struct _R128CrtcPrivateRec {
+@@ -144,9 +144,9 @@ typedef struct _R128CrtcPrivateRec {
+ ExaOffscreenArea *rotate_mem_exa;
+ #endif
+ int crtc_id;
+- CARD32 cursor_offset;
++ uint32_t cursor_offset;
+ /* Lookup table values to be set when the CRTC is enabled */
+- CARD8 lut_r[256], lut_g[256], lut_b[256];
++ uint8_t lut_r[256], lut_g[256], lut_b[256];
+ } R128CrtcPrivateRec, *R128CrtcPrivatePtr;
+
+ typedef struct {
+diff --git a/src/r128_reg.h b/src/r128_reg.h
+index 9ba0de5..eee5fb1 100644
+--- a/src/r128_reg.h
++++ b/src/r128_reg.h
+@@ -57,12 +57,12 @@
+ #define OUTREG16(addr, val) MMIO_OUT16(R128MMIO, addr, val)
+ #define OUTREG(addr, val) MMIO_OUT32(R128MMIO, addr, val)
+
+-#define ADDRREG(addr) ((volatile CARD32 *)(pointer)(R128MMIO + (addr)))
++#define ADDRREG(addr) ((volatile uint32_t *)(pointer)(R128MMIO + (addr)))
+
+
+ #define OUTREGP(addr, val, mask) \
+ do { \
+- CARD32 tmp = INREG(addr); \
++ uint32_t tmp = INREG(addr); \
+ tmp &= (mask); \
+ tmp |= ((val) & ~(mask)); \
+ OUTREG(addr, tmp); \
+@@ -78,7 +78,7 @@
+
+ #define OUTPLLP(pScrn, addr, val, mask) \
+ do { \
+- CARD32 tmp = INPLL(pScrn, addr); \
++ uint32_t tmp = INPLL(pScrn, addr); \
+ tmp &= (mask); \
+ tmp |= ((val) & ~(mask)); \
+ OUTPLL(addr, tmp); \
+@@ -94,7 +94,7 @@
+ OUTREG(R128_PALETTE_DATA, ((r) << 16) | ((g) << 8) | (b)); \
+ } while (0)
+
+-#define OUTPAL_NEXT_CARD32(v) \
++#define OUTPAL_NEXT_uint32_t(v) \
+ do { \
+ OUTREG(R128_PALETTE_DATA, (v & 0x00ffffff)); \
+ } while (0)
+@@ -114,12 +114,12 @@
+
+ #define PAL_SELECT(idx) \
+ do { \
+- CARD32 tmp = INREG(R128_DAC_CNTL); \
++ uint32_t tmp = INREG(R128_DAC_CNTL); \
+ if (idx) { \
+ OUTREG(R128_DAC_CNTL, tmp | R128_DAC_PALETTE_ACC_CTL); \
+ } else { \
+ OUTREG(R128_DAC_CNTL, tmp & \
+- (CARD32)~R128_DAC_PALETTE_ACC_CTL); \
++ (uint32_t)~R128_DAC_PALETTE_ACC_CTL); \
+ } \
+ } while (0)
+
+diff --git a/src/r128_video.c b/src/r128_video.c
+index 6439a24..bcf36fc 100644
+--- a/src/r128_video.c
++++ b/src/r128_video.c
+@@ -59,8 +59,8 @@ typedef struct {
+ void* BufferHandle;
+ int videoOffset;
+ RegionRec clip;
+- CARD32 colorKey;
+- CARD32 videoStatus;
++ uint32_t colorKey;
++ uint32_t videoStatus;
+ Time offTime;
+ Time freeTime;
+ int ecp_div;
+@@ -405,7 +405,7 @@ R128DMA(
+ #define BUFSIZE (R128_BUFFER_SIZE - R128_HOSTDATA_BLIT_OFFSET)
+ #define MAXPASSES (MAXHEIGHT/(BUFSIZE/(MAXWIDTH*2))+1)
+
+- unsigned char *fb = (CARD8*)info->FB;
++ unsigned char *fb = (uint8_t*)info->FB;
+ unsigned char *buf;
+ int err=-1, i, idx, offset, hpass, passes, srcpassbytes, dstpassbytes;
+ int sizes[MAXPASSES], list[MAXPASSES];
+@@ -572,7 +572,7 @@ R128CopyData420(
+ }
+
+
+-static CARD32
++static uint32_t
+ R128AllocateMemory(
+ ScrnInfoPtr pScrn,
+ void **mem_struct,
+@@ -841,14 +841,14 @@ R128PutImage(
+ ){
+ R128InfoPtr info = R128PTR(pScrn);
+ R128PortPrivPtr pPriv = (R128PortPrivPtr)data;
+- unsigned char *fb = (CARD8*)info->FB;
++ unsigned char *fb = (uint8_t*)info->FB;
+ INT32 xa, xb, ya, yb;
+ int new_size, offset, s1offset, s2offset, s3offset;
+ int srcPitch, srcPitch2, dstPitch;
+ int d1line, d2line, d3line, d1offset, d2offset, d3offset;
+ int top, left, npixels, nlines;
+ BoxRec dstBox;
+- CARD32 tmp;
++ uint32_t tmp;
+
+ /* Currently, the video is only visible on the first monitor.
+ * In the future we could try to make this smarter, or just implement
+@@ -858,7 +858,7 @@ R128PutImage(
+
+ #if X_BYTE_ORDER == X_BIG_ENDIAN
+ unsigned char *R128MMIO = info->MMIO;
+- CARD32 config_cntl = INREG(R128_CONFIG_CNTL);
++ uint32_t config_cntl = INREG(R128_CONFIG_CNTL);
+
+ /* We need to disable byte swapping, or the data gets mangled */
+ OUTREG(R128_CONFIG_CNTL, config_cntl &
+--
+2.2.2
+
+
+From 48e9b2359e8ab07095e1cb024e61b223a67cbc1a Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Thu, 24 Jul 2014 00:00:24 -0700
+Subject: Unify allocators
+
+RandR and Xv were using almost the same code to grab offscreen memory
+from EXA and XAA.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ src/r128.h | 1 +
+ src/r128_crtc.c | 72 ++++----------------------------------
+ src/r128_probe.h | 7 +---
+ src/r128_video.c | 103 ++++++++++++++++++++++++++++---------------------------
+ 4 files changed, 62 insertions(+), 121 deletions(-)
+
+diff --git a/src/r128.h b/src/r128.h
+index f361c2a..6df1b51 100644
+--- a/src/r128.h
++++ b/src/r128.h
+@@ -570,6 +570,7 @@ extern void r128_crtc_show_cursor(xf86CrtcPtr crtc);
+ extern void r128_crtc_hide_cursor(xf86CrtcPtr crtc);
+ extern void r128_crtc_load_cursor_image(xf86CrtcPtr crtc, unsigned char *src);
+
++extern uint32_t R128AllocateMemory(ScrnInfoPtr pScrn, void **mem_struct, int size, int align, Bool need_accel);
+ extern Bool R128SetupConnectors(ScrnInfoPtr pScrn);
+ extern Bool R128AllocateControllers(ScrnInfoPtr pScrn, int mask);
+ extern void R128Blank(ScrnInfoPtr pScrn);
+diff --git a/src/r128_crtc.c b/src/r128_crtc.c
+index 5f076cd..92a6c30 100644
+--- a/src/r128_crtc.c
++++ b/src/r128_crtc.c
+@@ -233,33 +233,9 @@ static void r128_crtc_unlock(xf86CrtcPtr crtc)
+ #endif
+ }
+
+-#ifdef HAVE_XAA_H
+-static FBLinearPtr r128_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length, int granularity,
+- MoveLinearCallbackProcPtr moveCB,
+- RemoveLinearCallbackProcPtr removeCB,
+- pointer privData)
+-{
+- FBLinearPtr linear;
+- int max_size;
+-
+- linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, removeCB, privData);
+- if (linear != NULL) return linear;
+-
+- /* The above allocation did not succeed, so purge unlocked stuff and try again. */
+- xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity, PRIORITY_EXTREME);
+-
+- if (max_size < length) return NULL;
+- xf86PurgeUnlockedOffscreenAreas(pScreen);
+-
+- linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, removeCB, privData);
+- return linear;
+-}
+-#endif
+-
+ static void *r128_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
+ {
+ ScrnInfoPtr pScrn = crtc->scrn;
+- ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
+ R128InfoPtr info = R128PTR(pScrn);
+
+ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
+@@ -271,38 +247,7 @@ static void *r128_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
+
+ rotate_pitch = pScrn->displayWidth * cpp;
+ size = rotate_pitch * height;
+-
+-#ifdef USE_EXA
+- if (info->ExaDriver) {
+- assert(r128_crtc->rotate_mem_exa == NULL);
+- r128_crtc->rotate_mem_exa = exaOffscreenAlloc(pScreen, size, align, TRUE, NULL, NULL);
+-
+- if (r128_crtc->rotate_mem_exa == NULL) {
+- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+- "Couldn't allocate shadow memory for rotated CRTC\n");
+- return NULL;
+- }
+-
+- rotate_offset = r128_crtc->rotate_mem_exa->offset;
+- }
+-#endif
+-#ifdef HAVE_XAA_H
+- if (info->accel) {
+- size = (size + cpp - 1) / cpp;
+- align = (align + cpp - 1) / cpp;
+-
+- assert(r128_crtc->rotate_mem_xaa == NULL);
+- r128_crtc->rotate_mem_xaa = r128_xf86AllocateOffscreenLinear(pScreen, size, align, NULL, NULL, NULL);
+-
+- if (r128_crtc->rotate_mem_exa == NULL) {
+- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+- "Couldn't allocate shadow memory for rotated CRTC\n");
+- return NULL;
+- }
+-
+- rotate_offset = r128_crtc->rotate_mem_xaa->offset * cpp;
+- }
+-#endif
++ rotate_offset = R128AllocateMemory(pScrn, &(r128_crtc->rotate_mem), size, align, TRUE);
+
+ /* If allocations failed or if there was no accel. */
+ if (rotate_offset == 0)
+@@ -347,19 +292,16 @@ static void r128_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap,
+
+ if (rotate_pixmap) FreeScratchPixmapHeader(rotate_pixmap);
+
+- if (data) {
++ if (data && r128_crtc->rotate_mem != NULL) {
+ #ifdef USE_EXA
+- if (info->ExaDriver && r128_crtc->rotate_mem_exa != NULL) {
+- exaOffscreenFree(pScreen, r128_crtc->rotate_mem_exa);
+- r128_crtc->rotate_mem_exa = NULL;
+- }
++ if (info->ExaDriver)
++ exaOffscreenFree(pScreen, (ExaOffscreenArea *) r128_crtc->rotate_mem);
+ #endif
+ #ifdef HAVE_XAA_H
+- if (info->accel) {
+- xf86FreeOffscreenLinear(r128_crtc->rotate_mem_xaa);
+- r128_crtc->rotate_mem_xaa = NULL;
+- }
++ if (info->accel)
++ xf86FreeOffscreenLinear((FBLinearPtr) r128_crtc->rotate_mem);
+ #endif
++ r128_crtc->rotate_mem = NULL;
+ }
+ }
+
+diff --git a/src/r128_probe.h b/src/r128_probe.h
+index 40fe82b..433463b 100644
+--- a/src/r128_probe.h
++++ b/src/r128_probe.h
+@@ -137,12 +137,7 @@ typedef struct {
+ } R128I2CBusRec, *R128I2CBusPtr;
+
+ typedef struct _R128CrtcPrivateRec {
+-#ifdef HAVE_XAA_H
+- FBLinearPtr rotate_mem_xaa;
+-#endif
+-#ifdef USE_EXA
+- ExaOffscreenArea *rotate_mem_exa;
+-#endif
++ void *rotate_mem;
+ int crtc_id;
+ uint32_t cursor_offset;
+ /* Lookup table values to be set when the CRTC is enabled */
+diff --git a/src/r128_video.c b/src/r128_video.c
+index bcf36fc..b0059b5 100644
+--- a/src/r128_video.c
++++ b/src/r128_video.c
+@@ -572,76 +572,78 @@ R128CopyData420(
+ }
+
+
+-static uint32_t
++uint32_t
+ R128AllocateMemory(
+ ScrnInfoPtr pScrn,
+ void **mem_struct,
+- int size
++ int size,
++ int align,
++ Bool need_accel
+ ){
+ R128InfoPtr info = R128PTR(pScrn);
+ ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
+- int offset = 0;
++ Bool do_linear = !need_accel;
++ uint32_t offset = 0;
+
+- if(!info->useEXA) {
++#ifdef HAVE_XAA_H
++ if (!info->accel && need_accel)
++ do_linear = FALSE;
++ else
++ do_linear = TRUE;
++#endif
++#ifdef USE_EXA
++ if (info->ExaDriver) {
++ ExaOffscreenArea *area = *mem_struct;
++
++ if (area != NULL) {
++ if (area->size >= size) return area->offset;
++
++ exaOffscreenFree(pScreen, area);
++ }
++
++ area = exaOffscreenAlloc(pScreen, size, align, TRUE, NULL, NULL);
++ *mem_struct = area;
++
++ if (area == NULL) return 0;
++ offset = area->offset;
++ }
++#endif
++ if (!info->useEXA && do_linear) {
+ FBLinearPtr linear = *mem_struct;
+ int cpp = info->CurrentLayout.pixel_bytes;
+
+- /* XAA allocates in units of pixels at the screen bpp, so adjust size appropriately. */
+- size = (size + cpp - 1) / cpp;
++ /* XAA allocates in units of pixels at the screen bpp, so adjust size appropriately. */
++ size = (size + cpp - 1) / cpp;
++ align = (align + cpp - 1) / cpp;
+
+ if(linear) {
+- if(linear->size >= size)
+- return linear->offset * cpp;
++ if(linear->size >= size)
++ return linear->offset * cpp;
+
+- if(xf86ResizeOffscreenLinear(linear, size))
+- return linear->offset * cpp;
++ if(xf86ResizeOffscreenLinear(linear, size))
++ return linear->offset * cpp;
+
+- xf86FreeOffscreenLinear(linear);
++ xf86FreeOffscreenLinear(linear);
+ }
+
+-
+- linear = xf86AllocateOffscreenLinear(pScreen, size, 8,
+- NULL, NULL, NULL);
++ linear = xf86AllocateOffscreenLinear(pScreen, size, align, NULL, NULL, NULL);
+ *mem_struct = linear;
+
+ if(!linear) {
+- int max_size;
+-
+- xf86QueryLargestOffscreenLinear(pScreen, &max_size, 8,
+- PRIORITY_EXTREME);
++ int max_size;
+
+- if(max_size < size)
+- return 0;
++ xf86QueryLargestOffscreenLinear(pScreen, &max_size, align, PRIORITY_EXTREME);
++ if(max_size < size) return 0;
+
+- xf86PurgeUnlockedOffscreenAreas(pScreen);
+- linear = xf86AllocateOffscreenLinear(pScreen, size, 8,
+- NULL, NULL, NULL);
++ xf86PurgeUnlockedOffscreenAreas(pScreen);
++ linear = xf86AllocateOffscreenLinear(pScreen, size, align, NULL, NULL, NULL);
+
+- if(!linear) return 0;
++ *mem_struct = linear;
++ if(!linear) return 0;
+ }
+
+- offset = linear->offset * cpp;
++ offset = linear->offset * cpp;
+ }
+-#ifdef USE_EXA
+- else {
+- /* EXA support based on mga driver */
+- ExaOffscreenArea *area = *mem_struct;
+-
+- if(area) {
+- if(area->size >= size)
+- return area->offset;
+-
+- exaOffscreenFree(pScrn->pScreen, area);
+- }
+-
+- area = exaOffscreenAlloc(pScrn->pScreen, size, 64, TRUE, NULL, NULL);
+- *mem_struct = area;
+-
+- if(!area) return 0;
+-
+- offset = area->offset;
+- }
+-#endif
+
+ return offset;
+ }
+@@ -929,11 +931,12 @@ R128PutImage(
+ break;
+ }
+
+- if(!(pPriv->videoOffset = R128AllocateMemory(pScrn, &(pPriv->BufferHandle),
+- pPriv->doubleBuffer ? (new_size << 1) : new_size)))
+- {
+- return BadAlloc;
+- }
++ pPriv->videoOffset = R128AllocateMemory(pScrn, &(pPriv->BufferHandle),
++ pPriv->doubleBuffer ? (new_size << 1) : new_size,
++ 64, FALSE);
++
++ if (pPriv->videoOffset == 0)
++ return BadAlloc;
+
+ pPriv->currentBuffer ^= 1;
+
+--
+2.2.2
+
+
+From 6dc5e9ab12dc31ae5de24f1d5c10c4fe80e7fe07 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Thu, 24 Jul 2014 00:01:46 -0700
+Subject: Unify byte swappers
+
+The cursor loading function was using a lot of code to swap bytes for
+big endian systems. For awhile now, the solid picture support for EXA
+has had a more optimized function that does the same thing.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ src/r128_cursor.c | 67 +++++++------------------------------------------------
+ 1 file changed, 8 insertions(+), 59 deletions(-)
+
+diff --git a/src/r128_cursor.c b/src/r128_cursor.c
+index d42bea6..048e6c1 100644
+--- a/src/r128_cursor.c
++++ b/src/r128_cursor.c
+@@ -62,20 +62,6 @@
+ #define CURSOR_WIDTH 64
+ #define CURSOR_HEIGHT 64
+
+-#if X_BYTE_ORDER == X_BIG_ENDIAN
+-#define P_SWAP32( a , b ) \
+- ((char *)a)[0] = ((char *)b)[3]; \
+- ((char *)a)[1] = ((char *)b)[2]; \
+- ((char *)a)[2] = ((char *)b)[1]; \
+- ((char *)a)[3] = ((char *)b)[0]
+-
+-#define P_SWAP16( a , b ) \
+- ((char *)a)[0] = ((char *)b)[1]; \
+- ((char *)a)[1] = ((char *)b)[0]; \
+- ((char *)a)[2] = ((char *)b)[3]; \
+- ((char *)a)[3] = ((char *)b)[2]
+-#endif
+-
+ void r128_crtc_show_cursor(xf86CrtcPtr crtc)
+ {
+ ScrnInfoPtr pScrn = crtc->scrn;
+@@ -176,14 +162,10 @@ void r128_crtc_load_cursor_image(xf86CrtcPtr crtc, unsigned char *src)
+ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
+ int crtc_id = r128_crtc->crtc_id;
+
+-
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+- uint32_t *s = (pointer)src;
+- uint32_t *d = (pointer)(info->FB + r128_crtc->cursor_offset + pScrn->fbOffset);
+ uint32_t save1 = 0;
+ uint32_t save2 = 0;
+- int y;
+
+ if (crtc_id == 0) {
+ save1 = INREG(R128_CRTC_GEN_CNTL);
+@@ -194,48 +176,15 @@ void r128_crtc_load_cursor_image(xf86CrtcPtr crtc, unsigned char *src)
+ }
+
+ #if X_BYTE_ORDER == X_BIG_ENDIAN
+- switch(info->CurrentLayout.pixel_bytes) {
+- case 4:
+- case 3:
+- for (y = 0; y < 64; y++) {
+- P_SWAP32(d,s);
+- d++; s++;
+- P_SWAP32(d,s);
+- d++; s++;
+- P_SWAP32(d,s);
+- d++; s++;
+- P_SWAP32(d,s);
+- d++; s++;
+- }
+- break;
+- case 2:
+- for (y = 0; y < 64; y++) {
+- P_SWAP16(d,s);
+- d++; s++;
+- P_SWAP16(d,s);
+- d++; s++;
+- P_SWAP16(d,s);
+- d++; s++;
+- P_SWAP16(d,s);
+- d++; s++;
+- }
+- break;
+- default:
+- for (y = 0; y < 64; y++) {
+- *d++ = *s++;
+- *d++ = *s++;
+- *d++ = *s++;
+- *d++ = *s++;
+- }
+- }
+-#else
+- for (y = 0; y < 64; y++) {
+- *d++ = *s++;
+- *d++ = *s++;
+- *d++ = *s++;
+- *d++ = *s++;
+- }
++ if (info->CurrentLayout.pixel_bytes == 4 || info->CurrentLayout.pixel_bytes == 3)
++ R128CopySwap(info->FB + r128_crtc->cursor_offset + pScrn->fbOffset, src,
++ CURSOR_WIDTH * CURSOR_HEIGHT / 4, APER_0_BIG_ENDIAN_32BPP_SWAP);
++ else if (info->CurrentLayout.pixel_bytes == 2)
++ R128CopySwap(info->FB + r128_crtc->cursor_offset + pScrn->fbOffset, src,
++ CURSOR_WIDTH * CURSOR_HEIGHT / 4, APER_0_BIG_ENDIAN_16BPP_SWAP);
++ else
+ #endif
++ memcpy(info->FB + r128_crtc->cursor_offset + pScrn->fbOffset, src, CURSOR_WIDTH * CURSOR_HEIGHT / 4);
+
+ if (crtc_id == 0)
+ OUTREG(R128_CRTC_GEN_CNTL, save1);
+--
+2.2.2
+
+
+From 2072d9aa1a144e699f020a7f9e6a870e410bc9d7 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Wed, 6 Aug 2014 15:41:02 -0700
+Subject: Improve handling of monitor and output types
+
+Checking for OUTPUT_DVI is not the same as checking for MT_DFP. There
+might be r128 cards with a DVI-I connector. These have the capability of
+driving an MT_CRT so we now check the monitor type before programming
+DAC or TMDS registers.
+
+This patch also removes R128ConnectorType and R128BIOSConnector because
+they were not doing much. These data structures are more useful for the
+radeon driver where there is a much wider range of cards.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ src/r128.h | 1 -
+ src/r128_driver.c | 2 +-
+ src/r128_output.c | 160 ++++++++++++++++++++----------------------------------
+ src/r128_probe.h | 16 ------
+ 4 files changed, 60 insertions(+), 119 deletions(-)
+
+diff --git a/src/r128.h b/src/r128.h
+index 6df1b51..d8748b7 100644
+--- a/src/r128.h
++++ b/src/r128.h
+@@ -504,7 +504,6 @@ typedef struct {
+ Bool DDC;
+
+ Bool VGAAccess;
+- R128BIOSConnector BiosConnector[R128_MAX_BIOS_CONNECTOR];
+
+ /****** Added for dualhead support *******************/
+ BOOL IsSecondary; /* second Screen */
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index c541bfa..ce38b4e 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -3225,7 +3225,7 @@ void R128InitRMXRegisters(R128SavePtr orig, R128SavePtr save,
+ save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid;
+ save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid;
+
+- if (r128_output->type != OUTPUT_DVI && r128_output->type != OUTPUT_LVDS)
++ if (r128_output->MonType != MT_DFP && r128_output->MonType != MT_LCD)
+ return;
+
+ if (r128_output->PanelXRes == 0 || r128_output->PanelYRes == 0) {
+diff --git a/src/r128_output.c b/src/r128_output.c
+index 7bb2e2a..757ef9b 100644
+--- a/src/r128_output.c
++++ b/src/r128_output.c
+@@ -90,21 +90,21 @@ static void r128_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayMode
+ if (r128_crtc->crtc_id == 0)
+ R128InitRMXRegisters(&info->SavedReg, &info->ModeReg, output, adjusted_mode);
+
+- if (r128_output->type == OUTPUT_DVI)
++ if (r128_output->MonType == MT_DFP)
+ R128InitFPRegisters(&info->SavedReg, &info->ModeReg, output);
+- else if (r128_output->type == OUTPUT_LVDS)
++ else if (r128_output->MonType == MT_LCD)
+ R128InitLVDSRegisters(&info->SavedReg, &info->ModeReg, output);
+- else if (r128_output->type == OUTPUT_VGA)
++ else if (r128_output->MonType == MT_CRT)
+ R128InitDACRegisters(&info->SavedReg, &info->ModeReg, output);
+
+ if (r128_crtc->crtc_id == 0)
+ R128RestoreRMXRegisters(pScrn, &info->ModeReg);
+
+- if (r128_output->type == OUTPUT_DVI)
++ if (r128_output->MonType == MT_DFP)
+ R128RestoreFPRegisters(pScrn, &info->ModeReg);
+- else if (r128_output->type == OUTPUT_LVDS)
++ else if (r128_output->MonType == MT_LCD)
+ R128RestoreLVDSRegisters(pScrn, &info->ModeReg);
+- else if (r128_output->type == OUTPUT_VGA)
++ else if (r128_output->MonType == MT_CRT)
+ R128RestoreDACRegisters(pScrn, &info->ModeReg);
+ }
+
+@@ -375,133 +375,91 @@ static Bool R128I2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name)
+ return TRUE;
+ }
+
+-void R128SetOutputType(ScrnInfoPtr pScrn, R128OutputPrivatePtr r128_output)
+-{
+- R128OutputType output = OUTPUT_NONE;
+-
+- switch (r128_output->ConnectorType) {
+- case CONNECTOR_VGA:
+- output = OUTPUT_VGA;
+- break;
+- case CONNECTOR_LVDS:
+- output = OUTPUT_LVDS;
+- break;
+- case CONNECTOR_DVI_D:
+- case CONNECTOR_DVI_I:
+- case CONNECTOR_DVI_A:
+- output = OUTPUT_DVI;
+- break;
+- default:
+- output = OUTPUT_NONE;
+- }
+-
+- r128_output->type = output;
+-}
+-
+-void R128SetupGenericConnectors(ScrnInfoPtr pScrn)
++void R128SetupGenericConnectors(ScrnInfoPtr pScrn, R128OutputType *otypes)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+
+ if (!pR128Ent->HasCRTC2 && !info->isDFP) {
+- info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
+- info->BiosConnector[0].valid = TRUE;
++ otypes[0] = OUTPUT_VGA;
+ return;
+ } else if (!pR128Ent->HasCRTC2) {
+- info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_D;
+- info->BiosConnector[0].valid = TRUE;
++ otypes[0] = OUTPUT_DVI;
+ return;
+ }
+
+- info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
+- info->BiosConnector[0].valid = TRUE;
+-
+- info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
+- info->BiosConnector[1].valid = TRUE;
++ otypes[0] = OUTPUT_LVDS;
++ otypes[1] = OUTPUT_VGA;
+ }
+
+ Bool R128SetupConnectors(ScrnInfoPtr pScrn)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+- xf86OutputPtr output;
++
++ R128OutputType otypes[R128_MAX_BIOS_CONNECTOR];
++ xf86OutputPtr output;
+ int num_vga = 0;
+ int num_dvi = 0;
+ int i;
+
+- for (i = 0; i < R128_MAX_BIOS_CONNECTOR; i++) {
+- info->BiosConnector[i].valid = FALSE;
+- info->BiosConnector[i].ConnectorType = CONNECTOR_NONE;
+- }
+-
+ /* XXX: Can we make R128GetConnectorInfoFromBIOS()? */
+- R128SetupGenericConnectors(pScrn);
++ R128SetupGenericConnectors(pScrn, otypes);
+
+ for (i = 0; i < R128_MAX_BIOS_CONNECTOR; i++) {
+- if (info->BiosConnector[i].valid) {
+- if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
+- (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I) ||
+- (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A)) {
+- num_dvi++;
+- } else if (info->BiosConnector[i].ConnectorType == CONNECTOR_VGA) {
+- num_vga++;
+- }
+- }
++ if (otypes[i] == OUTPUT_VGA)
++ num_vga++;
++ else if (otypes[i] == OUTPUT_DVI)
++ num_dvi++;
+ }
+
+ for (i = 0; i < R128_MAX_BIOS_CONNECTOR; i++) {
+- if (info->BiosConnector[i].valid) {
+- R128I2CBusRec i2c;
+- R128OutputPrivatePtr r128_output;
+- R128ConnectorType conntype = info->BiosConnector[i].ConnectorType;
++ if (otypes[i] == OUTPUT_NONE) continue;
+
+- if (conntype == CONNECTOR_NONE)
+- continue;
++ R128I2CBusRec i2c;
++ R128OutputPrivatePtr r128_output;
+
+- r128_output = xnfcalloc(sizeof(R128OutputPrivateRec), 1);
+- if (!r128_output) return FALSE;
++ r128_output = xnfcalloc(sizeof(R128OutputPrivateRec), 1);
++ if (!r128_output) return FALSE;
+
+- r128_output->MonType = MT_UNKNOWN;
+- r128_output->ConnectorType = conntype;
+- r128_output->num = i;
++ r128_output->MonType = MT_UNKNOWN;
++ r128_output->type = otypes[i];
++ r128_output->num = i;
+
+- if (conntype == CONNECTOR_LVDS) {
+- output = R128OutputCreate(pScrn, "LVDS", 0);
+- } else if (conntype == CONNECTOR_VGA) {
+- output = R128OutputCreate(pScrn, "VGA-%d", --num_vga);
+- } else {
+- output = R128OutputCreate(pScrn, "DVI-%d", --num_dvi);
+- }
++ if (otypes[i] == OUTPUT_LVDS) {
++ output = R128OutputCreate(pScrn, "LVDS", 0);
++ } else if (otypes[i] == OUTPUT_VGA) {
++ output = R128OutputCreate(pScrn, "VGA-%d", --num_vga);
++ } else {
++ output = R128OutputCreate(pScrn, "DVI-%d", --num_dvi);
++ }
+
+- if (!output) return FALSE;
+- output->interlaceAllowed = TRUE;
+- output->doubleScanAllowed = TRUE;
+- output->driver_private = r128_output;
+- output->possible_clones = 0;
+- if (conntype == CONNECTOR_LVDS || !pR128Ent->HasCRTC2)
+- output->possible_crtcs = 1;
+- else
+- output->possible_crtcs = 2;
+-
+- if (conntype != CONNECTOR_LVDS && info->DDC) {
+- i2c.ddc_reg = R128_GPIO_MONID;
+- i2c.put_clk_mask = R128_GPIO_MONID_EN_3;
+- i2c.get_clk_mask = R128_GPIO_MONID_Y_3;
+- if (conntype == CONNECTOR_VGA) {
+- i2c.put_data_mask = R128_GPIO_MONID_EN_1;
+- i2c.get_data_mask = R128_GPIO_MONID_Y_1;
+- } else {
+- i2c.put_data_mask = R128_GPIO_MONID_EN_0;
+- i2c.get_data_mask = R128_GPIO_MONID_Y_0;
+- }
+- r128_output->ddc_i2c = i2c;
+- R128I2CInit(output, &r128_output->pI2CBus, output->name);
+- } else if (conntype == CONNECTOR_LVDS) {
+- r128_output->PanelXRes = info->PanelXRes;
+- r128_output->PanelYRes = info->PanelYRes;
++ if (!output) return FALSE;
++ output->interlaceAllowed = TRUE;
++ output->doubleScanAllowed = TRUE;
++ output->driver_private = r128_output;
++ output->possible_clones = 0;
++ if (otypes[i] == OUTPUT_LVDS || !pR128Ent->HasCRTC2)
++ output->possible_crtcs = 1;
++ else
++ output->possible_crtcs = 2;
++
++ if (otypes[i] != OUTPUT_LVDS && info->DDC) {
++ i2c.ddc_reg = R128_GPIO_MONID;
++ i2c.put_clk_mask = R128_GPIO_MONID_EN_3;
++ i2c.get_clk_mask = R128_GPIO_MONID_Y_3;
++ if (otypes[i] == OUTPUT_VGA) {
++ i2c.put_data_mask = R128_GPIO_MONID_EN_1;
++ i2c.get_data_mask = R128_GPIO_MONID_Y_1;
++ } else {
++ i2c.put_data_mask = R128_GPIO_MONID_EN_0;
++ i2c.get_data_mask = R128_GPIO_MONID_Y_0;
+ }
+-
+- R128SetOutputType(pScrn, r128_output);
++ r128_output->ddc_i2c = i2c;
++ R128I2CInit(output, &r128_output->pI2CBus, output->name);
++ } else if (otypes[i] == OUTPUT_LVDS) {
++ r128_output->PanelXRes = info->PanelXRes;
++ r128_output->PanelYRes = info->PanelYRes;
+ }
+ }
+
+diff --git a/src/r128_probe.h b/src/r128_probe.h
+index 433463b..fef210d 100644
+--- a/src/r128_probe.h
++++ b/src/r128_probe.h
+@@ -112,16 +112,6 @@ typedef enum
+
+ typedef enum
+ {
+- CONNECTOR_NONE,
+- CONNECTOR_VGA,
+- CONNECTOR_DVI_I,
+- CONNECTOR_DVI_D,
+- CONNECTOR_DVI_A,
+- CONNECTOR_LVDS
+-} R128ConnectorType;
+-
+-typedef enum
+-{
+ OUTPUT_NONE,
+ OUTPUT_VGA,
+ OUTPUT_DVI,
+@@ -144,15 +134,9 @@ typedef struct _R128CrtcPrivateRec {
+ uint8_t lut_r[256], lut_g[256], lut_b[256];
+ } R128CrtcPrivateRec, *R128CrtcPrivatePtr;
+
+-typedef struct {
+- R128ConnectorType ConnectorType;
+- Bool valid;
+-} R128BIOSConnector;
+-
+ typedef struct _R128OutputPrivateRec {
+ int num;
+ R128OutputType type;
+- R128ConnectorType ConnectorType;
+ R128MonitorType MonType;
+ I2CBusPtr pI2CBus;
+ R128I2CBusRec ddc_i2c;
+--
+2.2.2
+
+
+From 6140081f0e8f41cf85b8e86f7a9474c20be9a2e9 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Wed, 6 Aug 2014 15:51:33 -0700
+Subject: Remove custom dualhead code
+
+There are probably no reasons left to use Xinerama over xrandr. This
+removes the screen based dualhead code and the BIOS Display option in
+xorg.conf. Additionally, R128ValidMode() is wrapped so that it can be
+aware of multiple displays.
+
+Even though some Crtc functions refer to them, PanelXRes and PanelYRes
+should be properties of the Output. If this change to the code seems
+awkward, see http://marc.info/?t=107222330700001 for more information.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ man/r128.man | 18 --
+ src/r128.h | 42 ++--
+ src/r128_accel.c | 18 +-
+ src/r128_crtc.c | 62 +++--
+ src/r128_driver.c | 701 ++++++++++++++++++++----------------------------------
+ src/r128_output.c | 10 +-
+ src/r128_probe.c | 1 -
+ src/r128_probe.h | 4 +-
+ src/r128_video.c | 11 +-
+ 9 files changed, 326 insertions(+), 541 deletions(-)
+
+diff --git a/man/r128.man b/man/r128.man
+index d490f93..bd58e0d 100644
+--- a/man/r128.man
++++ b/man/r128.man
+@@ -88,24 +88,6 @@ are used. The default is
+ This overrides the default pixel value for the YUV video overlay key.
+ The default value is
+ .B undefined.
+-.TP
+-.BI "Option \*qDisplay\*q \*q" string \*q
+-Select display mode for devices which support flat panels. Supported modes are:
+-
+-.B \*qFP\*q
+-- use flat panel;
+-
+-.B \*qCRT\*q
+-- use cathode ray tube;
+-
+-.B \*qMirror\*q
+-- use both FP and CRT;
+-
+-.B \*qBIOS\*q
+-- use mode as configured in the BIOS.
+-
+-The default is
+-.B FP.
+
+ .PP
+ The following
+diff --git a/src/r128.h b/src/r128.h
+index d8748b7..3b1e631 100644
+--- a/src/r128.h
++++ b/src/r128.h
+@@ -136,6 +136,14 @@
+ #define R128_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
+ #define R128PTR(pScrn) ((R128InfoPtr)(pScrn)->driverPrivate)
+
++#define R128_BIOS8(v) ((info->VBIOS[(v)]))
++#define R128_BIOS16(v) ((info->VBIOS[(v)]) | \
++ (info->VBIOS[(v) + 1] << 8))
++#define R128_BIOS32(v) ((info->VBIOS[(v)]) | \
++ (info->VBIOS[(v) + 1] << 8) | \
++ (info->VBIOS[(v) + 2] << 16) | \
++ (info->VBIOS[(v) + 3] << 24))
++
+ typedef struct { /* All values in XCLKS */
+ int ML; /* Memory Read Latency */
+ int MB; /* Memory Burst Length */
+@@ -311,16 +319,8 @@ typedef struct {
+ uint32_t MemCntl;
+ uint32_t BusCntl;
+ unsigned long FbMapSize; /* Size of frame buffer, in bytes */
+-
+- uint8_t BIOSDisplay; /* Device the BIOS is set to display to */
+-
+ Bool HasPanelRegs; /* Current chip can connect to a FP */
+
+- /* Computed values for FPs */
+- int PanelXRes;
+- int PanelYRes;
+- int PanelPwrDly;
+-
+ R128PLLRec pll;
+ R128RAMPtr ram;
+
+@@ -501,17 +501,10 @@ typedef struct {
+
+ Bool isDFP;
+ Bool isPro2;
++ Bool SwitchingMode;
+ Bool DDC;
+
+ Bool VGAAccess;
+-
+- /****** Added for dualhead support *******************/
+- BOOL IsSecondary; /* second Screen */
+- BOOL IsPrimary; /* primary Screen */
+- BOOL UseCRT; /* force use CRT port as primary */
+- BOOL SwitchingMode;
+- R128MonitorType DisplayType; /* Monitor connected on*/
+-
+ } R128InfoRec, *R128InfoPtr;
+
+ #define R128WaitForFifo(pScrn, entries) \
+@@ -535,6 +528,7 @@ extern Bool R128CursorInit(ScreenPtr pScreen);
+ extern Bool R128DGAInit(ScreenPtr pScreen);
+
+ extern int R128MinBits(int val);
++extern xf86OutputPtr R128FirstOutput(xf86CrtcPtr crtc);
+
+ extern void R128InitVideo(ScreenPtr pScreen);
+
+@@ -544,13 +538,13 @@ extern void R128InitRMXRegisters(R128SavePtr orig, R128SavePtr save, xf86
+ extern void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output);
+ extern void R128InitLVDSRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output);
+ extern Bool R128InitCrtcBase(xf86CrtcPtr crtc, R128SavePtr save, int x, int y);
+-extern Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save, DisplayModePtr mode, R128InfoPtr info);
+-extern void R128InitPLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, double dot_clock);
+-extern Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, R128InfoPtr info, DisplayModePtr mode);
++extern Bool R128InitCrtcRegisters(xf86CrtcPtr crtc, R128SavePtr save, DisplayModePtr mode);
++extern void R128InitPLLRegisters(xf86CrtcPtr crtc, R128SavePtr save, R128PLLPtr pll, double dot_clock);
++extern Bool R128InitDDARegisters(xf86CrtcPtr crtc, R128SavePtr save, R128PLLPtr pll, DisplayModePtr mode);
+ extern Bool R128InitCrtc2Base(xf86CrtcPtr crtc, R128SavePtr save, int x, int y);
+-extern Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save, DisplayModePtr mode, R128InfoPtr info);
+-extern void R128InitPLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, double dot_clock);
+-extern Bool R128InitDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, R128InfoPtr info, DisplayModePtr mode);
++extern Bool R128InitCrtc2Registers(xf86CrtcPtr crtc, R128SavePtr save, DisplayModePtr mode);
++extern void R128InitPLL2Registers(xf86CrtcPtr crtc, R128SavePtr save, R128PLLPtr pll, double dot_clock);
++extern Bool R128InitDDA2Registers(xf86CrtcPtr crtc, R128SavePtr save, R128PLLPtr pll, DisplayModePtr mode);
+ extern void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
+ extern void R128RestoreDACRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
+ extern void R128RestoreRMXRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
+@@ -571,11 +565,13 @@ extern void r128_crtc_load_cursor_image(xf86CrtcPtr crtc, unsigned char *
+
+ extern uint32_t R128AllocateMemory(ScrnInfoPtr pScrn, void **mem_struct, int size, int align, Bool need_accel);
+ extern Bool R128SetupConnectors(ScrnInfoPtr pScrn);
+-extern Bool R128AllocateControllers(ScrnInfoPtr pScrn, int mask);
++extern Bool R128AllocateControllers(ScrnInfoPtr pScrn);
++extern void R128GetPanelInfoFromBIOS(xf86OutputPtr output);
+ extern void R128Blank(ScrnInfoPtr pScrn);
+ extern void R128Unblank(ScrnInfoPtr pScrn);
+ extern void R128DPMSSetOn(xf86OutputPtr output);
+ extern void R128DPMSSetOff(xf86OutputPtr output);
++extern ModeStatus R128DoValidMode(xf86OutputPtr output, DisplayModePtr mode, int flags);
+ extern DisplayModePtr R128ProbeOutputModes(xf86OutputPtr output);
+
+ #ifdef R128DRI
+diff --git a/src/r128_accel.c b/src/r128_accel.c
+index 99bfb20..fa58327 100644
+--- a/src/r128_accel.c
++++ b/src/r128_accel.c
+@@ -1746,7 +1746,7 @@ static void R128CCEAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a)
+ | HARDWARE_PATTERN_SCREEN_ORIGIN
+ | BIT_ORDER_IN_BYTE_LSBFIRST);
+
+- if(!info->IsSecondary && xf86IsEntityShared(pScrn->entityList[0]))
++ if (xf86IsEntityShared(info->pEnt->index))
+ a->RestoreAccelState = R128RestoreCCEAccelState;
+
+ }
+@@ -1851,15 +1851,13 @@ static void R128MMIOAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a)
+ | LEFT_EDGE_CLIPPING_NEGATIVE_X
+ | SCANLINE_PAD_DWORD;
+
+- if(xf86IsEntityShared(pScrn->entityList[0]))
+- {
+- R128EntPtr pR128Ent = R128EntPriv(pScrn);
+-
+- /*if there are more than one devices sharing this entity, we
+- have to assign this call back, otherwise the XAA will be
+- disabled */
+- if(pR128Ent->HasSecondary || pR128Ent->BypassSecondary)
+- a->RestoreAccelState = R128RestoreAccelState;
++ if (xf86IsEntityShared(info->pEnt-index)) {
++ /* If there are more than one devices sharing this entity, we
++ * have to assign this call back, otherwise the XAA will be
++ * disabled.
++ */
++ if (xf86GetNumEntityInstances(info->pEnt->index) > 1)
++ a->RestoreAccelState = R128RestoreAccelState;
+ }
+
+ }
+diff --git a/src/r128_crtc.c b/src/r128_crtc.c
+index 92a6c30..26d4414 100644
+--- a/src/r128_crtc.c
++++ b/src/r128_crtc.c
+@@ -143,11 +143,11 @@ static void r128_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayMod
+
+ switch (r128_crtc->crtc_id) {
+ case 0:
+- R128InitCrtcRegisters(pScrn, &info->ModeReg, adjusted_mode, info);
++ R128InitCrtcRegisters(crtc, &info->ModeReg, adjusted_mode);
+ R128InitCrtcBase(crtc, &info->ModeReg, x, y);
+ if (dot_clock) {
+- R128InitPLLRegisters(pScrn, &info->ModeReg, &info->pll, dot_clock);
+- R128InitDDARegisters(pScrn, &info->ModeReg, &info->pll, info, adjusted_mode);
++ R128InitPLLRegisters(crtc, &info->ModeReg, &info->pll, dot_clock);
++ R128InitDDARegisters(crtc, &info->ModeReg, &info->pll, adjusted_mode);
+ } else {
+ info->ModeReg.ppll_ref_div = info->SavedReg.ppll_ref_div;
+ info->ModeReg.ppll_div_3 = info->SavedReg.ppll_div_3;
+@@ -157,11 +157,11 @@ static void r128_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayMod
+ }
+ break;
+ case 1:
+- R128InitCrtc2Registers(pScrn, &info->ModeReg, adjusted_mode, info);
++ R128InitCrtc2Registers(crtc, &info->ModeReg, adjusted_mode);
+ R128InitCrtc2Base(crtc, &info->ModeReg, x, y);
+ if (dot_clock) {
+- R128InitPLL2Registers(pScrn, &info->ModeReg, &info->pll, dot_clock);
+- R128InitDDA2Registers(pScrn, &info->ModeReg, &info->pll, info, adjusted_mode);
++ R128InitPLL2Registers(crtc, &info->ModeReg, &info->pll, dot_clock);
++ R128InitDDA2Registers(crtc, &info->ModeReg, &info->pll, adjusted_mode);
+ }
+ break;
+ }
+@@ -327,44 +327,40 @@ static const xf86CrtcFuncsRec r128_crtc_funcs = {
+ .destroy = NULL,
+ };
+
+-Bool R128AllocateControllers(ScrnInfoPtr pScrn, int mask)
++Bool R128AllocateControllers(ScrnInfoPtr pScrn)
+ {
+ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+
+- if (mask & 1) {
+- if (pR128Ent->Controller[0])
+- return TRUE;
++ if (pR128Ent->Controller[0])
++ return TRUE;
+
+- pR128Ent->pCrtc[0] = xf86CrtcCreate(pScrn, &r128_crtc_funcs);
+- if (!pR128Ent->pCrtc[0])
+- return FALSE;
++ pR128Ent->pCrtc[0] = xf86CrtcCreate(pScrn, &r128_crtc_funcs);
++ if (!pR128Ent->pCrtc[0])
++ return FALSE;
+
+- pR128Ent->Controller[0] = xnfcalloc(sizeof(R128CrtcPrivateRec), 1);
+- if (!pR128Ent->Controller[0])
+- return FALSE;
++ pR128Ent->Controller[0] = xnfcalloc(sizeof(R128CrtcPrivateRec), 1);
++ if (!pR128Ent->Controller[0])
++ return FALSE;
+
+- pR128Ent->pCrtc[0]->driver_private = pR128Ent->Controller[0];
+- pR128Ent->Controller[0]->crtc_id = 0;
+- }
+-
+- if (mask & 2) {
+- if (!pR128Ent->HasCRTC2)
+- return TRUE;
++ pR128Ent->pCrtc[0]->driver_private = pR128Ent->Controller[0];
++ pR128Ent->Controller[0]->crtc_id = 0;
+
+- pR128Ent->pCrtc[1] = xf86CrtcCreate(pScrn, &r128_crtc_funcs);
+- if (!pR128Ent->pCrtc[1])
+- return FALSE;
++ if (!pR128Ent->HasCRTC2)
++ return TRUE;
+
+- pR128Ent->Controller[1] = xnfcalloc(sizeof(R128CrtcPrivateRec), 1);
+- if (!pR128Ent->Controller[1]) {
+- free(pR128Ent->Controller[0]);
+- return FALSE;
+- }
++ pR128Ent->pCrtc[1] = xf86CrtcCreate(pScrn, &r128_crtc_funcs);
++ if (!pR128Ent->pCrtc[1])
++ return FALSE;
+
+- pR128Ent->pCrtc[1]->driver_private = pR128Ent->Controller[1];
+- pR128Ent->Controller[1]->crtc_id = 1;
++ pR128Ent->Controller[1] = xnfcalloc(sizeof(R128CrtcPrivateRec), 1);
++ if (!pR128Ent->Controller[1]) {
++ free(pR128Ent->Controller[0]);
++ return FALSE;
+ }
+
++ pR128Ent->pCrtc[1]->driver_private = pR128Ent->Controller[1];
++ pR128Ent->Controller[1]->crtc_id = 1;
++
+ return TRUE;
+ }
+
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index ce38b4e..0a8d802 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -171,7 +171,6 @@ static const OptionInfoRec R128Options[] = {
+ { OPTION_BUFFER_SIZE, "BufferSize", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_PAGE_FLIP, "EnablePageFlip", OPTV_BOOLEAN, {0}, FALSE },
+ #endif
+- { OPTION_DISPLAY, "Display", OPTV_STRING, {0}, FALSE },
+ { OPTION_PANEL_WIDTH, "PanelWidth", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_PANEL_HEIGHT, "PanelHeight", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_PROG_FP_REGS, "ProgramFPRegs", OPTV_BOOLEAN, {0}, FALSE },
+@@ -238,14 +237,6 @@ static Bool R128MapMMIO(ScrnInfoPtr pScrn)
+ if (info->FBDev) {
+ info->MMIO = fbdevHWMapMMIO(pScrn);
+ } else {
+- /* If the primary screen has already mapped the MMIO region,
+- use its pointer instead of mapping it a second time. */
+- if (info->IsSecondary) {
+- R128EntPtr pR128Ent = R128EntPriv(pScrn);
+- R128InfoPtr info0 = R128PTR(pR128Ent->pPrimaryScrn);
+- info->MMIO=info0->MMIO;
+- if (info->MMIO) return TRUE;
+- }
+ #ifndef XSERVER_LIBPCIACCESS
+ info->MMIO = xf86MapPciMem(pScrn->scrnIndex,
+ VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
+@@ -412,20 +403,26 @@ static int R128Div(int n, int d)
+ return (n + (d / 2)) / d;
+ }
+
+-/* Read the Video BIOS block and the FP registers (if applicable). */
++/* Finds the first output using a given crtc. */
++xf86OutputPtr R128FirstOutput(xf86CrtcPtr crtc)
++{
++ ScrnInfoPtr pScrn = crtc->scrn;
++ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
++ xf86OutputPtr output = xf86_config->output[0];
++ int o;
++
++ for (o = 0; o < xf86_config->num_output; o++) {
++ output = xf86_config->output[o];
++ if (output->crtc == crtc) break;
++ }
++
++ return output;
++}
++
++/* Read the Video BIOS block. */
+ static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
+- int i;
+- int FPHeader = 0;
+-
+-#define R128_BIOS8(v) (info->VBIOS[v])
+-#define R128_BIOS16(v) (info->VBIOS[v] | \
+- (info->VBIOS[(v) + 1] << 8))
+-#define R128_BIOS32(v) (info->VBIOS[v] | \
+- (info->VBIOS[(v) + 1] << 8) | \
+- (info->VBIOS[(v) + 2] << 16) | \
+- (info->VBIOS[(v) + 3] << 24))
+
+ #ifdef XSERVER_LIBPCIACCESS
+ int size = info->PciInfo->rom_size > R128_VBIOS_SIZE ? info->PciInfo->rom_size : R128_VBIOS_SIZE;
+@@ -469,143 +466,103 @@ static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Video BIOS not found!\n");
+ }
+- R128EntPtr pR128Ent = R128EntPriv(pScrn);
+-
+- if(pR128Ent->HasCRTC2)
+- {
+- if(info->IsSecondary)
+- {
+- /* there may be a way to detect this, for now, just assume
+- second head is CRT */
+- info->DisplayType = MT_CRT;
+-
+- if(info->DisplayType > MT_NONE)
+- {
+- pR128Ent->HasSecondary = TRUE;
+-
+- }
+- else return FALSE;
+-
+- }
+- else
+- {
+- /* really need some sort of detection here */
+- if (info->HasPanelRegs) {
+- info->DisplayType = MT_LCD;
+- } else if (info->isDFP) {
+- info->DisplayType = MT_DFP;
+- } else
+- {
+- /*DVI port has no monitor connected, try CRT port.
+- If something on CRT port, treat it as primary*/
+- if(xf86IsEntityShared(pScrn->entityList[0]))
+- {
+- R128EntPtr pR128Ent = R128EntPriv(pScrn);
+- pR128Ent->BypassSecondary = TRUE;
+- }
+-
+- info->DisplayType = MT_CRT;
+-#if 0
+- {
+- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+- "No monitor detected!!!\n");
+- return FALSE;
+- }
+-#endif
+- }
+- }
+- }
+- else
+- {
+- /*Regular Radeon ASIC, only one CRTC, but it could be
+- used for DFP with a DVI output, like AIW board*/
+- if(info->isDFP) info->DisplayType = MT_DFP;
+- else info->DisplayType = MT_CRT;
+- }
+-
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s Display == Type %d\n",
+- (info->IsSecondary ? "Secondary" : "Primary"),
+- info->DisplayType);
+-
+-
+- if (info->VBIOS && info->DisplayType == MT_LCD) {
+- info->FPBIOSstart = 0;
+-
+- /* FIXME: There should be direct access to the start of the FP info
+- tables, but until we find out where that offset is stored, we
+- must search for the ATI signature string: "M3 ". */
+- for (i = 4; i < R128_VBIOS_SIZE-8; i++) {
+- if (R128_BIOS8(i) == 'M' &&
+- R128_BIOS8(i+1) == '3' &&
+- R128_BIOS8(i+2) == ' ' &&
+- R128_BIOS8(i+3) == ' ' &&
+- R128_BIOS8(i+4) == ' ' &&
+- R128_BIOS8(i+5) == ' ' &&
+- R128_BIOS8(i+6) == ' ' &&
+- R128_BIOS8(i+7) == ' ') {
+- FPHeader = i-2;
+- break;
+- }
+- }
+
+- if (!FPHeader) return TRUE;
++ return TRUE;
++}
+
+- /* Assume that only one panel is attached and supported */
+- for (i = FPHeader+20; i < FPHeader+84; i += 2) {
+- if (R128_BIOS16(i) != 0) {
+- info->FPBIOSstart = R128_BIOS16(i);
+- break;
+- }
+- }
+- if (!info->FPBIOSstart) return TRUE;
+-
+- if (!info->PanelXRes)
+- info->PanelXRes = R128_BIOS16(info->FPBIOSstart+25);
+- if (!info->PanelYRes)
+- info->PanelYRes = R128_BIOS16(info->FPBIOSstart+27);
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel size: %dx%d\n",
+- info->PanelXRes, info->PanelYRes);
+-
+- info->PanelPwrDly = R128_BIOS8(info->FPBIOSstart+56);
+-
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel ID: ");
+- for (i = 1; i <= 24; i++)
+- ErrorF("%c", R128_BIOS8(info->FPBIOSstart+i));
+- ErrorF("\n");
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Type: ");
+- i = R128_BIOS16(info->FPBIOSstart+29);
+- if (i & 1) ErrorF("Color, ");
+- else ErrorF("Monochrome, ");
+- if (i & 2) ErrorF("Dual(split), ");
+- else ErrorF("Single, ");
+- switch ((i >> 2) & 0x3f) {
+- case 0: ErrorF("STN"); break;
+- case 1: ErrorF("TFT"); break;
+- case 2: ErrorF("Active STN"); break;
+- case 3: ErrorF("EL"); break;
+- case 4: ErrorF("Plasma"); break;
+- default: ErrorF("UNKNOWN"); break;
+- }
+- ErrorF("\n");
+- if (R128_BIOS8(info->FPBIOSstart+61) & 1) {
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Interface: LVDS\n");
+- } else {
+- /* FIXME: Add Non-LVDS flat pael support */
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Non-LVDS panel interface detected! "
+- "This support is untested and may not "
+- "function properly\n");
+- }
++/* Read the FP parameters if an LVDS panel is expected. */
++void R128GetPanelInfoFromBIOS(xf86OutputPtr output)
++{
++ ScrnInfoPtr pScrn = output->scrn;
++ R128InfoPtr info = R128PTR(pScrn);
++ R128OutputPrivatePtr r128_output = output->driver_private;
++ int FPHeader = 0;
++ int i;
++
++ if (!info->VBIOS) return;
++ info->FPBIOSstart = 0;
++
++ /* FIXME: There should be direct access to the start of the FP info
++ * tables, but until we find out where that offset is stored, we
++ * must search for the ATI signature string: "M3 ".
++ */
++ for (i = 4; i < R128_VBIOS_SIZE - 8; i++) {
++ if (R128_BIOS8(i) == 'M' &&
++ R128_BIOS8(i + 1) == '3' &&
++ R128_BIOS8(i + 2) == ' ' &&
++ R128_BIOS8(i + 3) == ' ' &&
++ R128_BIOS8(i + 4) == ' ' &&
++ R128_BIOS8(i + 5) == ' ' &&
++ R128_BIOS8(i + 6) == ' ' &&
++ R128_BIOS8(i + 7) == ' ') {
++ FPHeader = i - 2;
++ break;
++ }
++ }
++
++ if (!FPHeader) return;
++
++ /* Assume that only one panel is attached and supported */
++ for (i = FPHeader+20; i < FPHeader+84; i += 2) {
++ if (R128_BIOS16(i) != 0) {
++ info->FPBIOSstart = R128_BIOS16(i);
++ break;
++ }
+ }
+
+- if (!info->PanelXRes || !info->PanelYRes) {
++ if (!info->FPBIOSstart) return;
++ xf86GetOptValInteger(info->Options, OPTION_PANEL_WIDTH, &(r128_output->PanelXRes));
++ xf86GetOptValInteger(info->Options, OPTION_PANEL_HEIGHT, &(r128_output->PanelYRes));
++
++ if (!r128_output->PanelXRes)
++ r128_output->PanelXRes = R128_BIOS16(info->FPBIOSstart + 25);
++ if (!r128_output->PanelYRes)
++ r128_output->PanelYRes = R128_BIOS16(info->FPBIOSstart + 27);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel size: %dx%d\n",
++ r128_output->PanelXRes, r128_output->PanelYRes);
++
++ r128_output->PanelPwrDly = R128_BIOS8(info->FPBIOSstart + 56);
++
++ if (!r128_output->PanelXRes || !r128_output->PanelYRes) {
+ info->HasPanelRegs = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Can't determine panel dimensions, and none specified.\n"
+ "\tDisabling programming of FP registers.\n");
+ }
+
+- return TRUE;
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel ID: ");
++ for (i = 1; i <= 24; i++)
++ ErrorF("%c", R128_BIOS8(info->FPBIOSstart + i));
++
++ ErrorF("\n");
++
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Type: ");
++ i = R128_BIOS16(info->FPBIOSstart + 29);
++ if (i & 1) ErrorF("Color, ");
++ else ErrorF("Monochrome, ");
++ if (i & 2) ErrorF("Dual(split), ");
++ else ErrorF("Single, ");
++
++ switch ((i >> 2) & 0x3f) {
++ case 0: ErrorF("STN"); break;
++ case 1: ErrorF("TFT"); break;
++ case 2: ErrorF("Active STN"); break;
++ case 3: ErrorF("EL"); break;
++ case 4: ErrorF("Plasma"); break;
++ default: ErrorF("UNKNOWN"); break;
++ }
++
++ ErrorF("\n");
++
++ if (R128_BIOS8(info->FPBIOSstart + 61) & 1) {
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Interface: LVDS\n");
++ } else {
++ /* FIXME: Add Non-LVDS flat pael support */
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Non-LVDS panel interface detected! "
++ "This support is untested and may not "
++ "function properly\n");
++ }
+ }
+
+ /* Read PLL parameters from BIOS block. Default to typical values if there
+@@ -956,39 +913,6 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
+ info->MemCntl = INREG(R128_MEM_CNTL);
+ info->BusCntl = INREG(R128_BUS_CNTL);
+
+- /* On non-flat panel systems, the default is to display to the CRT,
+- and on flat panel systems, the default is to display to the flat
+- panel unless the user explicity chooses otherwise using the "Display"
+- config file setting. BIOS_5_SCRATCH holds the display device on flat
+- panel systems only. */
+- if (info->HasPanelRegs) {
+- char *Display = xf86GetOptValString(info->Options, OPTION_DISPLAY);
+-
+- if (info->FBDev)
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "Option \"Display\" ignored "
+- "(framebuffer device determines display type)\n");
+- else if (!Display)
+- info->BIOSDisplay = R128_DUALHEAD;
+- else if (!xf86NameCmp(Display, "FP"))
+- info->BIOSDisplay = R128_BIOS_DISPLAY_FP;
+- else if (!xf86NameCmp(Display, "BIOS"))
+- info->BIOSDisplay = INREG8(R128_BIOS_5_SCRATCH);
+- else if (!xf86NameCmp(Display, "Mirror"))
+- info->BIOSDisplay = R128_BIOS_DISPLAY_FP_CRT;
+- else if (!xf86NameCmp(Display, "CRT"))
+- info->BIOSDisplay = R128_BIOS_DISPLAY_CRT;
+- else {
+- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+- "Unsupported type \"%s\" specified for Option \"Display\".\n"
+- "\tSupported types are: "
+- "\"BIOS\", \"Mirror\", \"CRT\" and \"FP\"\n", Display);
+- return FALSE;
+- }
+- } else {
+- info->BIOSDisplay = R128_BIOS_DISPLAY_CRT;
+- }
+-
+ /* RAM */
+ switch (info->MemCntl & 0x3) {
+ case 0: /* SDR SGRAM 1:1 */
+@@ -1027,62 +951,9 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "VideoRAM: %d kByte (%s)\n", pScrn->videoRam, info->ram->name);
+
+- if (info->IsPrimary) {
+- pScrn->videoRam /= 2;
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "Using %dk of videoram for primary head\n",
+- pScrn->videoRam);
+- }
+-
+- if (info->IsSecondary) {
+- pScrn->videoRam /= 2;
+- info->LinearAddr += pScrn->videoRam * 1024;
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "Using %dk of videoram for secondary head\n",
+- pScrn->videoRam);
+- }
+-
+ pScrn->videoRam &= ~1023;
+ info->FbMapSize = pScrn->videoRam * 1024;
+
+-
+- /* Flat panel (part 2) */
+- switch (info->BIOSDisplay) {
+- case R128_DUALHEAD:
+- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+- "Dual display\n");
+- break;
+- case R128_BIOS_DISPLAY_FP:
+- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+- "Using flat panel for display\n");
+- break;
+- case R128_BIOS_DISPLAY_CRT:
+- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+- "Using external CRT for display\n");
+- break;
+- case R128_BIOS_DISPLAY_FP_CRT:
+- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+- "Using both flat panel and external CRT "
+- "for display\n");
+- break;
+- }
+-
+- if (info->HasPanelRegs) {
+- /* Panel width/height overrides */
+- info->PanelXRes = 0;
+- info->PanelYRes = 0;
+- if (xf86GetOptValInteger(info->Options,
+- OPTION_PANEL_WIDTH, &(info->PanelXRes))) {
+- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+- "Flat panel width: %d\n", info->PanelXRes);
+- }
+- if (xf86GetOptValInteger(info->Options,
+- OPTION_PANEL_HEIGHT, &(info->PanelYRes))) {
+- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+- "Flat panel height: %d\n", info->PanelYRes);
+- }
+- }
+-
+ #ifdef R128DRI
+ /* DMA for Xv */
+ info->DMAForXv = xf86ReturnOptValBool(info->Options, OPTION_XV_DMA, FALSE);
+@@ -1333,18 +1204,9 @@ static Bool R128PreInitDRI(ScrnInfoPtr pScrn)
+
+ static Bool R128PreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
+ {
+- R128InfoPtr info = R128PTR(pScrn);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+- int i;
+- int mask;
+ int found = 0;
+-
+- if (info->IsPrimary)
+- mask = 1;
+- else if (info->IsSecondary)
+- mask = 2;
+- else
+- mask = 3;
++ int i;
+
+ if (!R128GetBIOSParameters(pScrn, pInt10))
+ return FALSE;
+@@ -1352,7 +1214,7 @@ static Bool R128PreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
+ if (!R128GetPLLParameters(pScrn))
+ return FALSE;
+
+- if (!R128AllocateControllers(pScrn, mask))
++ if (!R128AllocateControllers(pScrn))
+ return FALSE;
+
+ if (!R128SetupConnectors(pScrn))
+@@ -1405,43 +1267,19 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
+
+ if (!R128GetRec(pScrn)) return FALSE;
+
+- info = R128PTR(pScrn);
+-
+- info->IsSecondary = FALSE;
+- info->IsPrimary = FALSE;
++ info = R128PTR(pScrn);
+ info->SwitchingMode = FALSE;
++ info->MMIO = NULL;
+
+- info->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
++ info->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (info->pEnt->location.type != BUS_PCI) goto fail;
+
+- if(xf86IsEntityShared(pScrn->entityList[0]))
+- {
+- if(xf86IsPrimInitDone(pScrn->entityList[0]))
+- {
+- R128EntPtr pR128Ent = R128EntPriv(pScrn);
+- info->IsSecondary = TRUE;
+- if(pR128Ent->BypassSecondary) return FALSE;
+- pR128Ent->pSecondaryScrn = pScrn;
+- }
+- else
+- {
+- R128EntPtr pR128Ent = R128EntPriv(pScrn);
+- info->IsPrimary = TRUE;
+- xf86SetPrimInitDone(pScrn->entityList[0]);
+- pR128Ent->pPrimaryScrn = pScrn;
+- pR128Ent->BypassSecondary = FALSE;
+- pR128Ent->HasSecondary = FALSE;
+- pR128Ent->RestorePrimary = FALSE;
+- pR128Ent->IsSecondaryRestored = FALSE;
+- }
+- }
+-
+ if (flags & PROBE_DETECT) {
+ R128ProbeDDC(pScrn, info->pEnt->index);
+ return TRUE;
+ }
+
+- info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
++ info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "PCI bus %d card %d func %d\n",
+@@ -1450,16 +1288,16 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
+ PCI_DEV_FUNC(info->PciInfo));
+
+ #ifndef XSERVER_LIBPCIACCESS
+- info->PciTag = pciTag(PCI_DEV_BUS(info->PciInfo),
++ info->PciTag = pciTag(PCI_DEV_BUS(info->PciInfo),
+ PCI_DEV_DEV(info->PciInfo),
+ PCI_DEV_FUNC(info->PciInfo));
+
+ if (xf86RegisterResources(info->pEnt->index, 0, ResNone)) goto fail;
+ if (xf86SetOperatingState(resVga, info->pEnt->index, ResUnusedOpr)) goto fail;
+
+- pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR;
++ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR;
+ #endif
+- pScrn->monitor = pScrn->confScreen->monitor;
++ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /* Allocate an xf86CrtcConfig */
+ xf86CrtcConfigInit(pScrn, &R128CRTCResizeFuncs);
+@@ -1810,7 +1648,7 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
+
+ if (!R128MapMem(pScrn)) return FALSE;
+ pScrn->fbOffset = 0;
+- if(info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024;
++ //if(info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024;
+ #ifdef R128DRI
+ info->fbX = 0;
+ info->fbY = 0;
+@@ -1857,23 +1695,7 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
+ info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024);
+ info->directRenderingEnabled = FALSE;
+ } else {
+- if(info->IsSecondary)
+- info->directRenderingEnabled = FALSE;
+- else
+- {
+- /* Xinerama has sync problem with DRI, disable it for now */
+- if(xf86IsEntityShared(pScrn->entityList[0]))
+- {
+- info->directRenderingEnabled = FALSE;
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Direct Rendering Disabled -- "
+- "Dual-head configuration is not working with DRI "
+- "at present.\nPlease use only one Device/Screen "
+- "section in your XFConfig file.\n");
+- }
+- else
+- info->directRenderingEnabled = R128DRIScreenInit(pScreen);
+- }
++ info->directRenderingEnabled = R128DRIScreenInit(pScreen);
+ }
+ }
+ #endif
+@@ -2259,8 +2081,7 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
+ else
+ xf86DPMSInit(pScreen, xf86DPMSSet, 0);
+
+- if (!info->IsSecondary)
+- R128InitVideo(pScreen);
++ R128InitVideo(pScreen);
+
+ /* Provide SaveScreen */
+ pScreen->SaveScreen = R128SaveScreen;
+@@ -2411,9 +2232,13 @@ void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ void R128RestoreLVDSRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+ uint32_t tmp;
+
++ xf86OutputPtr output = R128FirstOutput(pR128Ent->pCrtc[0]);
++ R128OutputPrivatePtr r128_output = output->driver_private;
++
+ tmp = INREG(R128_LVDS_GEN_CNTL);
+ if ((tmp & (R128_LVDS_ON | R128_LVDS_BLON)) ==
+ (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON))) {
+@@ -2422,11 +2247,11 @@ void R128RestoreLVDSRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
+ if (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON)) {
+ OUTREG(R128_LVDS_GEN_CNTL,
+ restore->lvds_gen_cntl & (uint32_t)~R128_LVDS_BLON);
+- usleep(R128PTR(pScrn)->PanelPwrDly * 1000);
++ usleep(r128_output->PanelPwrDly * 1000);
+ OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
+ } else {
+ OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl | R128_LVDS_BLON);
+- usleep(R128PTR(pScrn)->PanelPwrDly * 1000);
++ usleep(r128_output->PanelPwrDly * 1000);
+ OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
+ }
+ }
+@@ -2664,8 +2489,6 @@ static void R128SaveFPRegisters(ScrnInfoPtr pScrn, R128SavePtr save)
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+
+- if (info->BIOSDisplay != R128_DUALHEAD)
+- save->crtc2_gen_cntl = INREG(R128_CRTC2_GEN_CNTL);
+ save->fp_crtc_h_total_disp = INREG(R128_FP_CRTC_H_TOTAL_DISP);
+ save->fp_crtc_v_total_disp = INREG(R128_FP_CRTC_V_TOTAL_DISP);
+ save->fp_gen_cntl = INREG(R128_FP_GEN_CNTL);
+@@ -2769,28 +2592,23 @@ static void R128SavePalette(ScrnInfoPtr pScrn, R128SavePtr save)
+ static void R128SaveMode(ScrnInfoPtr pScrn, R128SavePtr save)
+ {
+ R128InfoPtr info = R128PTR(pScrn);
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
+
+ R128TRACE(("R128SaveMode(%p)\n", save));
+
+- if(info->IsSecondary)
+- {
++ R128SaveCommonRegisters(pScrn, save);
++ R128SaveCrtcRegisters(pScrn, save);
++ R128SavePLLRegisters(pScrn, save);
++ R128SaveDDARegisters(pScrn, save);
++ if (pR128Ent->HasCRTC2) {
+ R128SaveCrtc2Registers(pScrn, save);
+ R128SavePLL2Registers(pScrn, save);
+ R128SaveDDA2Registers(pScrn, save);
+ }
+- else
+- {
+- R128SaveCommonRegisters(pScrn, save);
+- R128SaveCrtcRegisters(pScrn, save);
+- if((info->DisplayType == MT_DFP) ||
+- (info->DisplayType == MT_LCD))
+- {
+- R128SaveFPRegisters(pScrn, save);
+- }
+- R128SavePLLRegisters(pScrn, save);
+- R128SaveDDARegisters(pScrn, save);
+- R128SavePalette(pScrn, save);
++ if (info->HasPanelRegs) {
++ R128SaveFPRegisters(pScrn, save);
+ }
++ R128SavePalette(pScrn, save);
+
+ R128TRACE(("R128SaveMode returns %p\n", save));
+ }
+@@ -2808,36 +2626,33 @@ static void R128Save(ScrnInfoPtr pScrn)
+ return;
+ }
+
+- if (!info->IsSecondary) {
+ #ifdef WITH_VGAHW
+- if (info->VGAAccess) {
+- vgaHWPtr hwp = VGAHWPTR(pScrn);
++ if (info->VGAAccess) {
++ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+- vgaHWUnlock(hwp);
++ vgaHWUnlock(hwp);
+ # if defined(__powerpc__)
+- /* temporary hack to prevent crashing on PowerMacs when trying to
+- * read VGA fonts and colormap, will find a better solution
+- * in the future. TODO: Check if there's actually some VGA stuff
+- * setup in the card at all !!
+- */
+- vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */
++ /* temporary hack to prevent crashing on PowerMacs when trying to
++ * read VGA fonts and colormap, will find a better solution
++ * in the future. TODO: Check if there's actually some VGA stuff
++ * setup in the card at all !!
++ */
++ vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */
+ # else
+- /* Save mode * & fonts & cmap */
+- vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS);
++ /* Save mode * & fonts & cmap */
++ vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS);
+ # endif
+- vgaHWLock(hwp);
+- }
++ vgaHWLock(hwp);
++ }
+ #endif
+
+- save->dp_datatype = INREG(R128_DP_DATATYPE);
+- save->gen_reset_cntl = INREG(R128_GEN_RESET_CNTL);
+- save->clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX);
+- save->amcgpio_en_reg = INREG(R128_AMCGPIO_EN_REG);
+- save->amcgpio_mask = INREG(R128_AMCGPIO_MASK);
+- }
++ save->dp_datatype = INREG(R128_DP_DATATYPE);
++ save->gen_reset_cntl = INREG(R128_GEN_RESET_CNTL);
++ save->clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX);
++ save->amcgpio_en_reg = INREG(R128_AMCGPIO_EN_REG);
++ save->amcgpio_mask = INREG(R128_AMCGPIO_MASK);
+
+ R128SaveMode(pScrn, save);
+-
+ }
+
+ /* Restore the original (text) mode. */
+@@ -2856,59 +2671,39 @@ static void R128Restore(ScrnInfoPtr pScrn)
+
+ R128Blank(pScrn);
+
+- if (!info->IsSecondary) {
+- OUTREG(R128_AMCGPIO_MASK, restore->amcgpio_mask);
+- OUTREG(R128_AMCGPIO_EN_REG, restore->amcgpio_en_reg);
+- OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
+- OUTREG(R128_GEN_RESET_CNTL, restore->gen_reset_cntl);
+- OUTREG(R128_DP_DATATYPE, restore->dp_datatype);
+-
+- R128RestoreCommonRegisters(pScrn, restore);
+- if (pR128Ent->HasCRTC2) {
+- R128RestoreDDA2Registers(pScrn, restore);
+- R128RestoreCrtc2Registers(pScrn, restore);
+- R128RestorePLL2Registers(pScrn, restore);
+- }
+- R128RestoreDDARegisters(pScrn, restore);
+- R128RestoreCrtcRegisters(pScrn, restore);
+- R128RestorePLLRegisters(pScrn, restore);
+- R128RestoreDACRegisters(pScrn, restore);
+- R128RestoreRMXRegisters(pScrn, restore);
+- R128RestoreFPRegisters(pScrn, restore);
+- R128RestoreLVDSRegisters(pScrn, restore);
+- }
++ OUTREG(R128_AMCGPIO_MASK, restore->amcgpio_mask);
++ OUTREG(R128_AMCGPIO_EN_REG, restore->amcgpio_en_reg);
++ OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
++ OUTREG(R128_GEN_RESET_CNTL, restore->gen_reset_cntl);
++ OUTREG(R128_DP_DATATYPE, restore->dp_datatype);
++
++ R128RestoreCommonRegisters(pScrn, restore);
++ if (pR128Ent->HasCRTC2) {
++ R128RestoreDDA2Registers(pScrn, restore);
++ R128RestoreCrtc2Registers(pScrn, restore);
++ R128RestorePLL2Registers(pScrn, restore);
++ }
++ R128RestoreDDARegisters(pScrn, restore);
++ R128RestoreCrtcRegisters(pScrn, restore);
++ R128RestorePLLRegisters(pScrn, restore);
++ R128RestoreDACRegisters(pScrn, restore);
++ R128RestoreRMXRegisters(pScrn, restore);
++ R128RestoreFPRegisters(pScrn, restore);
++ R128RestoreLVDSRegisters(pScrn, restore);
+
+ #ifdef WITH_VGAHW
+ if (info->VGAAccess) {
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+- if (!info->IsSecondary) {
+- vgaHWUnlock(hwp);
++ vgaHWUnlock(hwp);
+ # if defined(__powerpc__)
+- /* Temporary hack to prevent crashing on PowerMacs when trying to
+- * write VGA fonts, will find a better solution in the future
+- */
+- vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE );
++ /* Temporary hack to prevent crashing on PowerMacs when trying to
++ * write VGA fonts, will find a better solution in the future
++ */
++ vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE );
+ # else
+- vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
++ vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
+ # endif
+- vgaHWLock(hwp);
+- } else {
+- R128EntPtr pR128Ent = R128EntPriv(pScrn);
+- ScrnInfoPtr pScrn0 = pR128Ent->pPrimaryScrn;
+- R128InfoPtr info0 = R128PTR(pScrn0);
+- vgaHWPtr hwp0;
+-
+- if (info0->VGAAccess) {
+- hwp0 = VGAHWPTR(pScrn0);
+- vgaHWUnlock(hwp0);
+-#if defined(__powerpc__)
+- vgaHWRestore(pScrn0, &hwp0->SavedReg, VGA_SR_MODE);
+-#else
+- vgaHWRestore(pScrn0, &hwp0->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
+-#endif
+- vgaHWLock(hwp0);
+- }
+- }
++ vgaHWLock(hwp);
+ }
+ #endif
+
+@@ -3000,9 +2795,13 @@ Bool R128InitCrtc2Base(xf86CrtcPtr crtc, R128SavePtr save, int x, int y)
+ }
+
+ /* Define CRTC registers for requested video mode. */
+-Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+- DisplayModePtr mode, R128InfoPtr info)
++Bool R128InitCrtcRegisters(xf86CrtcPtr crtc, R128SavePtr save, DisplayModePtr mode)
+ {
++ ScrnInfoPtr pScrn = crtc->scrn;
++ R128InfoPtr info = R128PTR(pScrn);
++ xf86OutputPtr output = R128FirstOutput(crtc);
++ R128OutputPrivatePtr r128_output = output->driver_private;
++
+ int format;
+ int hsync_start;
+ int hsync_wid;
+@@ -3026,8 +2825,7 @@ Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+ return FALSE;
+ }
+
+- if ((info->DisplayType == MT_DFP) ||
+- (info->DisplayType == MT_LCD))
++ if (r128_output->MonType == MT_LCD || r128_output->MonType == MT_DFP)
+ hsync_fudge = hsync_fudge_fp[format-1];
+ else
+ hsync_fudge = hsync_fudge_default[format-1];
+@@ -3045,21 +2843,16 @@ Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+ ? R128_CRTC_CSYNC_EN
+ : 0));
+
+- if((info->DisplayType == MT_DFP) ||
+- (info->DisplayType == MT_LCD))
+- {
+- save->crtc_gen_cntl &= ~(R128_CRTC_DBL_SCAN_EN |
+- R128_CRTC_INTERLACE_EN);
+- }
++ if (r128_output->MonType == MT_LCD || r128_output->MonType == MT_DFP)
++ save->crtc_gen_cntl &= ~(R128_CRTC_DBL_SCAN_EN | R128_CRTC_INTERLACE_EN);
+
+ save->crtc_ext_cntl |= R128_VGA_ATI_LINEAR | R128_XCRT_CNT_EN;
+
+- if(info->isDFP && !info->isPro2)
+- {
+- if(info->PanelXRes < mode->CrtcHDisplay)
+- mode->HDisplay = mode->CrtcHDisplay = info->PanelXRes;
+- if(info->PanelYRes < mode->CrtcVDisplay)
+- mode->VDisplay = mode->CrtcVDisplay = info->PanelYRes;
++ if (info->isDFP && !info->isPro2) {
++ if (r128_output->PanelXRes < mode->CrtcHDisplay)
++ mode->HDisplay = mode->CrtcHDisplay = r128_output->PanelXRes;
++ if (r128_output->PanelYRes < mode->CrtcVDisplay)
++ mode->VDisplay = mode->CrtcVDisplay = r128_output->PanelYRes;
+ }
+
+ save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0xffff)
+@@ -3118,9 +2911,11 @@ Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+ }
+
+ /* Define CRTC2 registers for requested video mode. */
+-Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
+- DisplayModePtr mode, R128InfoPtr info)
++Bool R128InitCrtc2Registers(xf86CrtcPtr crtc, R128SavePtr save, DisplayModePtr mode)
+ {
++ ScrnInfoPtr pScrn = crtc->scrn;
++ R128InfoPtr info = R128PTR(pScrn);
++
+ int format;
+ int hsync_start;
+ int hsync_wid;
+@@ -3314,9 +3109,10 @@ void R128InitLVDSRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr out
+ }
+
+ /* Define PLL registers for requested video mode. */
+-void R128InitPLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
++void R128InitPLLRegisters(xf86CrtcPtr crtc, R128SavePtr save,
+ R128PLLPtr pll, double dot_clock)
+ {
++ ScrnInfoPtr pScrn = crtc->scrn;
+ unsigned long freq = dot_clock * 100;
+ struct {
+ int divider;
+@@ -3366,9 +3162,10 @@ void R128InitPLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+ }
+
+ /* Define PLL2 registers for requested video mode. */
+-void R128InitPLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
++void R128InitPLL2Registers(xf86CrtcPtr crtc, R128SavePtr save,
+ R128PLLPtr pll, double dot_clock)
+ {
++ ScrnInfoPtr pScrn = crtc->scrn;
+ unsigned long freq = dot_clock * 100;
+ struct {
+ int divider;
+@@ -3418,10 +3215,14 @@ void R128InitPLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
+ }
+
+ /* Define DDA registers for requested video mode. */
+-Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+- R128PLLPtr pll, R128InfoPtr info,
+- DisplayModePtr mode)
++Bool R128InitDDARegisters(xf86CrtcPtr crtc, R128SavePtr save,
++ R128PLLPtr pll, DisplayModePtr mode)
+ {
++ ScrnInfoPtr pScrn = crtc->scrn;
++ R128InfoPtr info = R128PTR(pScrn);
++ xf86OutputPtr output = R128FirstOutput(crtc);
++ R128OutputPrivatePtr r128_output = output->driver_private;
++
+ int DisplayFifoWidth = 128;
+ int DisplayFifoDepth = 32;
+ int XclkFreq;
+@@ -3437,10 +3238,10 @@ Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+ VclkFreq = R128Div(pll->reference_freq * save->feedback_div,
+ pll->reference_div * save->post_div);
+
+- if(info->isDFP && !info->isPro2){
+- if(info->PanelXRes != mode->CrtcHDisplay)
+- VclkFreq = (VclkFreq * mode->CrtcHDisplay)/info->PanelXRes;
+- }
++ if (info->isDFP && !info->isPro2) {
++ if (r128_output->PanelXRes != mode->CrtcHDisplay)
++ VclkFreq = (VclkFreq * mode->CrtcHDisplay) / r128_output->PanelXRes;
++ }
+
+ XclksPerTransfer = R128Div(XclkFreq * DisplayFifoWidth,
+ VclkFreq * (info->CurrentLayout.pixel_bytes * 8));
+@@ -3487,10 +3288,14 @@ Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save,
+ }
+
+ /* Define DDA2 registers for requested video mode. */
+-Bool R128InitDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
+- R128PLLPtr pll, R128InfoPtr info,
+- DisplayModePtr mode)
++Bool R128InitDDA2Registers(xf86CrtcPtr crtc, R128SavePtr save,
++ R128PLLPtr pll, DisplayModePtr mode)
+ {
++ ScrnInfoPtr pScrn = crtc->scrn;
++ R128InfoPtr info = R128PTR(pScrn);
++ xf86OutputPtr output = R128FirstOutput(crtc);
++ R128OutputPrivatePtr r128_output = output->driver_private;
++
+ int DisplayFifoWidth = 128;
+ int DisplayFifoDepth = 32;
+ int XclkFreq;
+@@ -3506,10 +3311,10 @@ Bool R128InitDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
+ VclkFreq = R128Div(pll->reference_freq * save->feedback_div_2,
+ pll->reference_div * save->post_div_2);
+
+- if(info->isDFP && !info->isPro2){
+- if(info->PanelXRes != mode->CrtcHDisplay)
+- VclkFreq = (VclkFreq * mode->CrtcHDisplay)/info->PanelXRes;
+- }
++ if (info->isDFP && !info->isPro2) {
++ if (r128_output->PanelXRes != mode->CrtcHDisplay)
++ VclkFreq = (VclkFreq * mode->CrtcHDisplay) / r128_output->PanelXRes;
++ }
+
+ XclksPerTransfer = R128Div(XclkFreq * DisplayFifoWidth,
+ VclkFreq * (info->CurrentLayout.pixel_bytes * 8));
+@@ -3602,42 +3407,40 @@ Bool R128SwitchMode(SWITCH_MODE_ARGS_DECL)
+ return ret;
+ }
+
+-/* Used to disallow modes that are not supported by the hardware. */
+-ModeStatus R128ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode,
+- Bool verbose, int flags)
++ModeStatus R128DoValidMode(xf86OutputPtr output, DisplayModePtr mode, int flags)
+ {
+- SCRN_INFO_PTR(arg);
+- R128InfoPtr info = R128PTR(pScrn);
++ ScrnInfoPtr pScrn = output->scrn;
++ R128InfoPtr info = R128PTR(pScrn);
++ R128OutputPrivatePtr r128_output = output->driver_private;
+
+- if (info->BIOSDisplay == R128_BIOS_DISPLAY_CRT)
+- return MODE_OK;
++ if (r128_output->MonType == MT_CRT)
++ return MODE_OK;
+
+- if(info->isDFP) {
+- if(info->PanelXRes < mode->CrtcHDisplay ||
+- info->PanelYRes < mode->CrtcVDisplay)
++ if (info->isDFP) {
++ if (r128_output->PanelXRes < mode->CrtcHDisplay ||
++ r128_output->PanelYRes < mode->CrtcVDisplay)
+ return MODE_NOMODE;
+ else
+ return MODE_OK;
+ }
+
+- if (info->DisplayType == MT_LCD) {
++ if (r128_output->MonType == MT_LCD) {
+ if (mode->Flags & V_INTERLACE) return MODE_NO_INTERLACE;
+ if (mode->Flags & V_DBLSCAN) return MODE_NO_DBLESCAN;
+ }
+
+- if (info->DisplayType == MT_LCD &&
+- info->VBIOS) {
++ if (r128_output->MonType == MT_LCD && info->VBIOS) {
+ int i;
+- for (i = info->FPBIOSstart+64; R128_BIOS16(i) != 0; i += 2) {
++ for (i = info->FPBIOSstart + 64; R128_BIOS16(i) != 0; i += 2) {
+ int j = R128_BIOS16(i);
+
+ if (mode->CrtcHDisplay == R128_BIOS16(j) &&
+- mode->CrtcVDisplay == R128_BIOS16(j+2)) {
++ mode->CrtcVDisplay == R128_BIOS16(j + 2)) {
+ if ((flags & MODECHECK_FINAL) == MODECHECK_FINAL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Modifying mode according to VBIOS: %ix%i [pclk %.1f MHz] for FP to: ",
+- mode->CrtcHDisplay,mode->CrtcVDisplay,
+- (float)mode->Clock/1000);
++ mode->CrtcHDisplay, mode->CrtcVDisplay,
++ (float)mode->Clock / 1000);
+
+ /* Assume we are using expanded mode */
+ if (R128_BIOS16(j+5)) j = R128_BIOS16(j+5);
+@@ -3646,25 +3449,25 @@ ModeStatus R128ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode,
+ mode->Clock = (uint32_t)R128_BIOS16(j) * 10;
+
+ mode->HDisplay = mode->CrtcHDisplay =
+- ((R128_BIOS16(j+10) & 0x01ff)+1)*8;
++ ((R128_BIOS16(j + 10) & 0x01ff) + 1) * 8;
+ mode->HSyncStart = mode->CrtcHSyncStart =
+- ((R128_BIOS16(j+12) & 0x01ff)+1)*8;
++ ((R128_BIOS16(j + 12) & 0x01ff) + 1) * 8;
+ mode->HSyncEnd = mode->CrtcHSyncEnd =
+- mode->CrtcHSyncStart + (R128_BIOS8(j+14) & 0x1f);
++ mode->CrtcHSyncStart + (R128_BIOS8(j + 14) & 0x1f);
+ mode->HTotal = mode->CrtcHTotal =
+- ((R128_BIOS16(j+8) & 0x01ff)+1)*8;
++ ((R128_BIOS16(j + 8) & 0x01ff) + 1) * 8;
+
+ mode->VDisplay = mode->CrtcVDisplay =
+- (R128_BIOS16(j+17) & 0x07ff)+1;
++ (R128_BIOS16(j + 17) & 0x07ff) + 1;
+ mode->VSyncStart = mode->CrtcVSyncStart =
+- (R128_BIOS16(j+19) & 0x07ff)+1;
++ (R128_BIOS16(j + 19) & 0x07ff) + 1;
+ mode->VSyncEnd = mode->CrtcVSyncEnd =
+- mode->CrtcVSyncStart + ((R128_BIOS16(j+19) >> 11) & 0x1f);
++ mode->CrtcVSyncStart + ((R128_BIOS16(j + 19) >> 11) & 0x1f);
+ mode->VTotal = mode->CrtcVTotal =
+- (R128_BIOS16(j+15) & 0x07ff)+1;
++ (R128_BIOS16(j + 15) & 0x07ff) + 1;
+ xf86ErrorF("%ix%i [pclk %.1f MHz]\n",
+ mode->CrtcHDisplay,mode->CrtcVDisplay,
+- (float)mode->Clock/1000);
++ (float)mode->Clock/ 1000);
+ }
+ return MODE_OK;
+ }
+@@ -3680,6 +3483,17 @@ ModeStatus R128ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode,
+ return MODE_OK;
+ }
+
++/* Used to disallow modes that are not supported by the hardware. */
++ModeStatus R128ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode,
++ Bool verbose, int flags)
++{
++ SCRN_INFO_PTR(arg);
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
++ xf86OutputPtr output = R128FirstOutput(pR128Ent->pCrtc[0]);
++
++ return R128DoValidMode(output, mode, flags);
++}
++
+ /* Adjust viewport into virtual desktop such that (0,0) in viewport space
+ is (x,y) in virtual space. */
+ void R128AdjustFrame(ADJUST_FRAME_ARGS_DECL)
+@@ -3706,14 +3520,7 @@ void R128AdjustFrame(ADJUST_FRAME_ARGS_DECL)
+ if (info->CurrentLayout.pixel_code == 24)
+ Base += 8 * (Base % 3); /* Must be multiple of 8 and 3 */
+
+- if(info->IsSecondary)
+- {
+- Base += pScrn->fbOffset;
+- OUTREG(R128_CRTC2_OFFSET, Base);
+- }
+- else
+ OUTREG(R128_CRTC_OFFSET, Base);
+-
+ }
+
+ /* Called when VT switching back to the X server. Reinitialize the video
+diff --git a/src/r128_output.c b/src/r128_output.c
+index 757ef9b..8ef6d45 100644
+--- a/src/r128_output.c
++++ b/src/r128_output.c
+@@ -181,7 +181,7 @@ void R128DPMSSetOn(xf86OutputPtr output)
+ switch(MonType) {
+ case MT_LCD:
+ OUTREGP(R128_LVDS_GEN_CNTL, R128_LVDS_BLON, ~R128_LVDS_BLON);
+- usleep(info->PanelPwrDly * 1000);
++ usleep(r128_output->PanelPwrDly * 1000);
+ OUTREGP(R128_LVDS_GEN_CNTL, R128_LVDS_ON, ~R128_LVDS_ON);
+ save->lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_BLON);
+ break;
+@@ -307,7 +307,7 @@ DisplayModePtr R128ProbeOutputModes(xf86OutputPtr output)
+ for (mode = modes; mode != NULL; mode = mode->next) {
+ xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
+ if (mode->status == MODE_OK)
+- mode->status = R128ValidMode(XF86_SCRN_ARG(pScrn), mode, TRUE, MODECHECK_FINAL);
++ mode->status = R128DoValidMode(output, mode, MODECHECK_FINAL);
+ }
+
+ xf86ValidateModesUserConfig(pScrn, modes);
+@@ -457,10 +457,10 @@ Bool R128SetupConnectors(ScrnInfoPtr pScrn)
+ }
+ r128_output->ddc_i2c = i2c;
+ R128I2CInit(output, &r128_output->pI2CBus, output->name);
+- } else if (otypes[i] == OUTPUT_LVDS) {
+- r128_output->PanelXRes = info->PanelXRes;
+- r128_output->PanelYRes = info->PanelYRes;
+ }
++
++ if (otypes[i] != OUTPUT_VGA)
++ R128GetPanelInfoFromBIOS(output);
+ }
+
+ return TRUE;
+diff --git a/src/r128_probe.c b/src/r128_probe.c
+index 348d15b..9771d52 100644
+--- a/src/r128_probe.c
++++ b/src/r128_probe.c
+@@ -288,7 +288,6 @@ r128_get_scrninfo(int entity_num)
+ R128EntPtr pR128Ent;
+ pPriv->ptr = xnfcalloc(sizeof(R128EntRec), 1);
+ pR128Ent = pPriv->ptr;
+- pR128Ent->BypassSecondary = FALSE;
+ pR128Ent->HasSecondary = FALSE;
+ pR128Ent->IsSecondaryRestored = FALSE;
+ }
+diff --git a/src/r128_probe.h b/src/r128_probe.h
+index fef210d..0b54d21 100644
+--- a/src/r128_probe.h
++++ b/src/r128_probe.h
+@@ -142,6 +142,7 @@ typedef struct _R128OutputPrivateRec {
+ R128I2CBusRec ddc_i2c;
+ int PanelXRes;
+ int PanelYRes;
++ int PanelPwrDly;
+ } R128OutputPrivateRec, *R128OutputPrivatePtr;
+
+ #define R128_MAX_CRTC 2
+@@ -151,7 +152,6 @@ typedef struct
+ {
+ Bool HasSecondary;
+ Bool HasCRTC2;
+- Bool BypassSecondary;
+ /*These two registers are used to make sure the CRTC2 is
+ retored before CRTC_EXT, otherwise it could lead to blank screen.*/
+ Bool IsSecondaryRestored;
+@@ -160,7 +160,7 @@ typedef struct
+ xf86CrtcPtr pCrtc[R128_MAX_CRTC];
+ R128CrtcPrivatePtr Controller[R128_MAX_CRTC];
+
+- ScrnInfoPtr pSecondaryScrn;
++ ScrnInfoPtr pSecondaryScrn;
+ ScrnInfoPtr pPrimaryScrn;
+ } R128EntRec, *R128EntPtr;
+
+diff --git a/src/r128_video.c b/src/r128_video.c
+index b0059b5..dc1f25b 100644
+--- a/src/r128_video.c
++++ b/src/r128_video.c
+@@ -661,8 +661,12 @@ R128DisplayVideo422(
+ short drw_w, short drw_h
+ ){
+ R128InfoPtr info = R128PTR(pScrn);
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
++ xf86OutputPtr output = R128FirstOutput(pR128Ent->pCrtc[0]);
++ R128OutputPrivatePtr r128_output = output->driver_private;
+ unsigned char *R128MMIO = info->MMIO;
+ R128PortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;
++
+ int v_inc, h_inc, step_by, tmp, v_inc_shift;
+ int p1_h_accum_init, p23_h_accum_init;
+ int p1_v_accum_init;
+@@ -678,7 +682,7 @@ R128DisplayVideo422(
+
+ rmx_active = INREG(R128_FP_VERT_STRETCH) & R128_VERT_STRETCH_ENABLE;
+ if (rmx_active) {
+- v_inc = ((src_h * pScrn->currentMode->CrtcVDisplay / info->PanelYRes) << v_inc_shift) / drw_h;
++ v_inc = ((src_h * pScrn->currentMode->CrtcVDisplay / r128_output->PanelYRes) << v_inc_shift) / drw_h;
+ } else {
+ v_inc = (src_h << v_inc_shift) / drw_h;
+ }
+@@ -747,6 +751,9 @@ R128DisplayVideo420(
+ short drw_w, short drw_h
+ ){
+ R128InfoPtr info = R128PTR(pScrn);
++ R128EntPtr pR128Ent = R128EntPriv(pScrn);
++ xf86OutputPtr output = R128FirstOutput(pR128Ent->pCrtc[0]);
++ R128OutputPrivatePtr r128_output = output->driver_private;
+ unsigned char *R128MMIO = info->MMIO;
+ R128PortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;
+ int v_inc, h_inc, step_by, tmp, leftUV, v_inc_shift;
+@@ -762,7 +769,7 @@ R128DisplayVideo420(
+
+ rmx_active = INREG(R128_FP_VERT_STRETCH) & R128_VERT_STRETCH_ENABLE;
+ if (rmx_active) {
+- v_inc = ((src_h * pScrn->currentMode->CrtcVDisplay / info->PanelYRes) << v_inc_shift) / drw_h;
++ v_inc = ((src_h * pScrn->currentMode->CrtcVDisplay / r128_output->PanelYRes) << v_inc_shift) / drw_h;
+ } else {
+ v_inc = (src_h << v_inc_shift) / drw_h;
+ }
+--
+2.2.2
+
+
+From d49c3431e92a6120b054959ce6910e8decf61c67 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Fri, 25 Jul 2014 13:39:08 -0700
+Subject: Remove custom DGA code
+
+I have yet to see a use for the DGA code included in the driver.
+According to radeon commits, it should be safe to replace it with DiDGA.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ src/Makefile.am | 2 +-
+ src/r128.h | 13 --
+ src/r128_accel.c | 4 +-
+ src/r128_dga.c | 408 ------------------------------------------------------
+ src/r128_driver.c | 7 +-
+ 5 files changed, 6 insertions(+), 428 deletions(-)
+ delete mode 100644 src/r128_dga.c
+
+diff --git a/src/Makefile.am b/src/Makefile.am
+index e4618ea..05fbe6c 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -40,7 +40,7 @@ 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_accel.c r128_cursor.c r128_driver.c \
+ r128_video.c r128_misc.c r128_crtc.c r128_output.c r128_probe.c \
+ $(R128_EXA_SRCS) $(R128_DRI_SRCS)
+
+diff --git a/src/r128.h b/src/r128.h
+index 3b1e631..19124bf 100644
+--- a/src/r128.h
++++ b/src/r128.h
+@@ -343,12 +343,6 @@ typedef struct {
+ struct r128_2d_state state_2d;
+ #endif
+
+- /*
+- * XAAForceTransBlit is used to change the behavior of the XAA
+- * SetupForScreenToScreenCopy function, to make it DGA-friendly.
+- */
+- Bool XAAForceTransBlit;
+-
+ int fifo_slots; /* Free slots in the FIFO (64 max) */
+ int pix24bpp; /* Depth of pixmap for 24bpp framebuffer */
+ Bool dac6bits; /* Use 6 bit DAC? */
+@@ -381,12 +375,6 @@ typedef struct {
+ int scanline_direct;
+ int scanline_bpp; /* Only used for ImageWrite */
+
+- DGAModePtr DGAModes;
+- int numDGAModes;
+- Bool DGAactive;
+- int DGAViewportStatus;
+- DGAFunctionRec DGAFuncs;
+-
+ R128FBLayout CurrentLayout;
+ #ifdef R128DRI
+ Bool directRenderingEnabled;
+@@ -525,7 +513,6 @@ extern void R128WaitForVerticalSync(ScrnInfoPtr pScrn);
+ extern Bool R128AccelInit(ScreenPtr pScreen);
+ extern void R128EngineInit(ScrnInfoPtr pScrn);
+ extern Bool R128CursorInit(ScreenPtr pScreen);
+-extern Bool R128DGAInit(ScreenPtr pScreen);
+
+ extern int R128MinBits(int val);
+ extern xf86OutputPtr R128FirstOutput(xf86CrtcPtr crtc);
+diff --git a/src/r128_accel.c b/src/r128_accel.c
+index fa58327..c88e8f9 100644
+--- a/src/r128_accel.c
++++ b/src/r128_accel.c
+@@ -590,7 +590,7 @@ static void R128SetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ ? R128_DST_Y_TOP_TO_BOTTOM
+ : 0)));
+
+- if ((trans_color != -1) || (info->XAAForceTransBlit == TRUE)) {
++ if (trans_color != -1) {
+ /* Set up for transparency */
+ R128WaitForFifo(pScrn, 3);
+ OUTREG(R128_CLR_CMP_CLR_SRC, trans_color);
+@@ -1182,7 +1182,7 @@ static void R128CCESetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+
+ ADVANCE_RING();
+
+- if ((trans_color != -1) || (info->XAAForceTransBlit == TRUE)) {
++ if (trans_color != -1) {
+ BEGIN_RING( 6 );
+
+ OUT_RING_REG( R128_CLR_CMP_CLR_SRC, trans_color );
+diff --git a/src/r128_dga.c b/src/r128_dga.c
+deleted file mode 100644
+index bb4a1a6..0000000
+--- a/src/r128_dga.c
++++ /dev/null
+@@ -1,408 +0,0 @@
+-/*
+- * Authors:
+- * Ove Kåven <ovek@transgaming.com>,
+- * borrowing some code from the Chips and MGA drivers.
+- */
+-
+-#ifdef HAVE_CONFIG_H
+-#include "config.h"
+-#endif
+-
+-#include <string.h>
+-
+- /* Driver data structures */
+-#include "r128.h"
+-#include "r128_probe.h"
+-
+- /* X and server generic header files */
+-#include "xf86.h"
+-
+- /* DGA support */
+-#include "dgaproc.h"
+-
+-#ifdef R128DRI
+-#include "r128_common.h"
+-#endif
+-
+-static Bool R128_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
+- int *, int *, int *);
+-static Bool R128_SetMode(ScrnInfoPtr, DGAModePtr);
+-static int R128_GetViewport(ScrnInfoPtr);
+-static void R128_SetViewport(ScrnInfoPtr, int, int, int);
+-#ifdef HAVE_XAA_H
+-static void R128_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+-static void R128_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+-static void R128_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
+- unsigned long);
+-#endif
+-
+-static DGAModePtr R128SetupDGAMode(ScrnInfoPtr pScrn,
+- DGAModePtr modes,
+- int *num,
+- int bitsPerPixel,
+- int depth,
+- Bool pixmap,
+- int secondPitch,
+- unsigned long red,
+- unsigned long green,
+- unsigned long blue,
+- short visualClass)
+-{
+- R128InfoPtr info = R128PTR(pScrn);
+- DGAModePtr newmodes = NULL;
+- DGAModePtr currentMode;
+- DisplayModePtr pMode;
+- DisplayModePtr firstMode;
+- unsigned int size;
+- int pitch;
+- int Bpp = bitsPerPixel >> 3;
+-
+-SECOND_PASS:
+-
+- pMode = firstMode = pScrn->modes;
+-
+- while (1) {
+- pitch = pScrn->displayWidth;
+- size = pitch * Bpp * pMode->VDisplay;
+-
+- if ((!secondPitch || (pitch != secondPitch)) &&
+- (size <= info->FbMapSize)) {
+-
+- if (secondPitch)
+- pitch = secondPitch;
+-
+- if (!(newmodes = realloc(modes, (*num + 1) * sizeof(DGAModeRec))))
+- break;
+-
+- modes = newmodes;
+- currentMode = modes + *num;
+-
+- currentMode->mode = pMode;
+- currentMode->flags = DGA_CONCURRENT_ACCESS;
+-
+- if (pixmap)
+- currentMode->flags |= DGA_PIXMAP_AVAILABLE;
+-
+-#ifdef HAVE_XAA_H
+- if (info->accel) {
+- if (info->accel->SetupForSolidFill &&
+- info->accel->SubsequentSolidFillRect)
+- currentMode->flags |= DGA_FILL_RECT;
+- if (info->accel->SetupForScreenToScreenCopy &&
+- info->accel->SubsequentScreenToScreenCopy)
+- currentMode->flags |= DGA_BLIT_RECT | DGA_BLIT_RECT_TRANS;
+- if (currentMode->flags &
+- (DGA_PIXMAP_AVAILABLE | DGA_FILL_RECT |
+- DGA_BLIT_RECT | DGA_BLIT_RECT_TRANS))
+- currentMode->flags &= ~DGA_CONCURRENT_ACCESS;
+- }
+-#endif
+- if (pMode->Flags & V_DBLSCAN)
+- currentMode->flags |= DGA_DOUBLESCAN;
+- if (pMode->Flags & V_INTERLACE)
+- currentMode->flags |= DGA_INTERLACED;
+-
+- currentMode->byteOrder = pScrn->imageByteOrder;
+- currentMode->depth = depth;
+- currentMode->bitsPerPixel = bitsPerPixel;
+- currentMode->red_mask = red;
+- currentMode->green_mask = green;
+- currentMode->blue_mask = blue;
+- currentMode->visualClass = visualClass;
+- currentMode->viewportWidth = pMode->HDisplay;
+- currentMode->viewportHeight = pMode->VDisplay;
+- currentMode->xViewportStep = 8;
+- currentMode->yViewportStep = 1;
+- currentMode->viewportFlags = DGA_FLIP_RETRACE;
+- currentMode->offset = 0;
+- currentMode->address = (unsigned char*)info->LinearAddr;
+- currentMode->bytesPerScanline = pitch * Bpp;
+- currentMode->imageWidth = pitch;
+- currentMode->imageHeight = (info->FbMapSize
+- / currentMode->bytesPerScanline);
+- currentMode->pixmapWidth = currentMode->imageWidth;
+- currentMode->pixmapHeight = currentMode->imageHeight;
+- currentMode->maxViewportX = (currentMode->imageWidth
+- - currentMode->viewportWidth);
+- /* this might need to get clamped to some maximum */
+- currentMode->maxViewportY = (currentMode->imageHeight
+- - currentMode->viewportHeight);
+- (*num)++;
+- }
+-
+- pMode = pMode->next;
+- if (pMode == firstMode)
+- break;
+- }
+-
+- if (secondPitch) {
+- secondPitch = 0;
+- goto SECOND_PASS;
+- }
+-
+- return modes;
+-}
+-
+-Bool
+-R128DGAInit(ScreenPtr pScreen)
+-{
+- ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+- R128InfoPtr info = R128PTR(pScrn);
+- DGAModePtr modes = NULL;
+- int num = 0;
+-
+- /* 8 */
+- modes = R128SetupDGAMode (pScrn, modes, &num, 8, 8,
+- (pScrn->bitsPerPixel == 8),
+- (pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth,
+- 0, 0, 0, PseudoColor);
+-
+- /* 15 */
+- modes = R128SetupDGAMode (pScrn, modes, &num, 16, 15,
+- (pScrn->bitsPerPixel == 16),
+- (pScrn->depth != 15) ? 0 : pScrn->displayWidth,
+- 0x7c00, 0x03e0, 0x001f, TrueColor);
+-
+- modes = R128SetupDGAMode (pScrn, modes, &num, 16, 15,
+- (pScrn->bitsPerPixel == 16),
+- (pScrn->depth != 15) ? 0 : pScrn->displayWidth,
+- 0x7c00, 0x03e0, 0x001f, DirectColor);
+-
+- /* 16 */
+- modes = R128SetupDGAMode (pScrn, modes, &num, 16, 16,
+- (pScrn->bitsPerPixel == 16),
+- (pScrn->depth != 16) ? 0 : pScrn->displayWidth,
+- 0xf800, 0x07e0, 0x001f, TrueColor);
+-
+- modes = R128SetupDGAMode (pScrn, modes, &num, 16, 16,
+- (pScrn->bitsPerPixel == 16),
+- (pScrn->depth != 16) ? 0 : pScrn->displayWidth,
+- 0xf800, 0x07e0, 0x001f, DirectColor);
+-
+- /* 24 */
+- modes = R128SetupDGAMode (pScrn, modes, &num, 24, 24,
+- (pScrn->bitsPerPixel == 24),
+- (pScrn->bitsPerPixel != 24) ? 0 : pScrn->displayWidth,
+- 0xff0000, 0x00ff00, 0x0000ff, TrueColor);
+-
+- modes = R128SetupDGAMode (pScrn, modes, &num, 24, 24,
+- (pScrn->bitsPerPixel == 24),
+- (pScrn->bitsPerPixel != 24) ? 0 : pScrn->displayWidth,
+- 0xff0000, 0x00ff00, 0x0000ff, DirectColor);
+-
+- /* 32 */
+- modes = R128SetupDGAMode (pScrn, modes, &num, 32, 24,
+- (pScrn->bitsPerPixel == 32),
+- (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth,
+- 0xff0000, 0x00ff00, 0x0000ff, TrueColor);
+-
+- modes = R128SetupDGAMode (pScrn, modes, &num, 32, 24,
+- (pScrn->bitsPerPixel == 32),
+- (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth,
+- 0xff0000, 0x00ff00, 0x0000ff, DirectColor);
+-
+- info->numDGAModes = num;
+- info->DGAModes = modes;
+-
+- info->DGAFuncs.OpenFramebuffer = R128_OpenFramebuffer;
+- info->DGAFuncs.CloseFramebuffer = NULL;
+- info->DGAFuncs.SetMode = R128_SetMode;
+- info->DGAFuncs.SetViewport = R128_SetViewport;
+- info->DGAFuncs.GetViewport = R128_GetViewport;
+-
+- info->DGAFuncs.Sync = NULL;
+- info->DGAFuncs.FillRect = NULL;
+- info->DGAFuncs.BlitRect = NULL;
+- info->DGAFuncs.BlitTransRect = NULL;
+-
+-#ifdef HAVE_XAA_H
+- if (info->accel) {
+- info->DGAFuncs.Sync = info->accel->Sync;
+- if (info->accel->SetupForSolidFill &&
+- info->accel->SubsequentSolidFillRect)
+- info->DGAFuncs.FillRect = R128_FillRect;
+- if (info->accel->SetupForScreenToScreenCopy &&
+- info->accel->SubsequentScreenToScreenCopy) {
+- info->DGAFuncs.BlitRect = R128_BlitRect;
+- info->DGAFuncs.BlitTransRect = R128_BlitTransRect;
+- }
+- }
+-#endif
+-
+- return DGAInit(pScreen, &(info->DGAFuncs), modes, num);
+-}
+-
+-
+-static Bool
+-R128_SetMode(
+- ScrnInfoPtr pScrn,
+- DGAModePtr pMode
+-){
+- static R128FBLayout SavedLayouts[MAXSCREENS];
+- int indx = pScrn->pScreen->myNum;
+- R128InfoPtr info = R128PTR(pScrn);
+-
+- if(!pMode) { /* restore the original mode */
+- /* put the ScreenParameters back */
+- if(info->DGAactive)
+- memcpy(&info->CurrentLayout, &SavedLayouts[indx], sizeof(R128FBLayout));
+-
+- pScrn->currentMode = info->CurrentLayout.mode;
+-
+- pScrn->SwitchMode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode));
+-#ifdef R128DRI
+- if (info->directRenderingEnabled) {
+- R128CCE_STOP(pScrn, info);
+- }
+-#endif
+- if (info->accelOn)
+- R128EngineInit(pScrn);
+-#ifdef R128DRI
+- if (info->directRenderingEnabled) {
+- R128CCE_START(pScrn, info);
+- }
+-#endif
+- pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, 0, 0));
+- info->DGAactive = FALSE;
+- } else {
+- if(!info->DGAactive) { /* save the old parameters */
+- memcpy(&SavedLayouts[indx], &info->CurrentLayout, sizeof(R128FBLayout));
+- info->DGAactive = TRUE;
+- }
+-
+- info->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel;
+- info->CurrentLayout.depth = pMode->depth;
+- info->CurrentLayout.displayWidth = pMode->bytesPerScanline /
+- (pMode->bitsPerPixel >> 3);
+- info->CurrentLayout.pixel_bytes = pMode->bitsPerPixel / 8;
+- info->CurrentLayout.pixel_code = (pMode->bitsPerPixel != 16
+- ? pMode->bitsPerPixel
+- : pMode->depth);
+- /* R128ModeInit() will set the mode field */
+-
+- pScrn->SwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode));
+-
+-#ifdef R128DRI
+- if (info->directRenderingEnabled) {
+- R128CCE_STOP(pScrn, info);
+- }
+-#endif
+- if (info->accelOn)
+- R128EngineInit(pScrn);
+-#ifdef R128DRI
+- if (info->directRenderingEnabled) {
+- R128CCE_START(pScrn, info);
+- }
+-#endif
+- }
+-
+- return TRUE;
+-}
+-
+-
+-
+-static int
+-R128_GetViewport(
+- ScrnInfoPtr pScrn
+-){
+- R128InfoPtr info = R128PTR(pScrn);
+-
+- return info->DGAViewportStatus;
+-}
+-
+-
+-static void
+-R128_SetViewport(
+- ScrnInfoPtr pScrn,
+- int x, int y,
+- int flags
+-){
+- R128InfoPtr info = R128PTR(pScrn);
+-
+- pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y));
+- info->DGAViewportStatus = 0; /* FIXME */
+-}
+-
+-#ifdef HAVE_XAA_H
+-static void
+-R128_FillRect (
+- ScrnInfoPtr pScrn,
+- int x, int y, int w, int h,
+- unsigned long color
+-){
+- R128InfoPtr info = R128PTR(pScrn);
+-
+- (*info->accel->SetupForSolidFill)(pScrn, color, GXcopy, (uint32_t)(~0));
+- (*info->accel->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+-
+- if (pScrn->bitsPerPixel == info->CurrentLayout.bitsPerPixel)
+- SET_SYNC_FLAG(info->accel);
+-}
+-
+-static void
+-R128_BlitRect(
+- ScrnInfoPtr pScrn,
+- int srcx, int srcy,
+- int w, int h,
+- int dstx, int dsty
+-){
+- R128InfoPtr info = R128PTR(pScrn);
+- int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+- int ydir = (srcy < dsty) ? -1 : 1;
+-
+- (*info->accel->SetupForScreenToScreenCopy)(
+- pScrn, xdir, ydir, GXcopy, (uint32_t)(~0), -1);
+- (*info->accel->SubsequentScreenToScreenCopy)(
+- pScrn, srcx, srcy, dstx, dsty, w, h);
+-
+- if (pScrn->bitsPerPixel == info->CurrentLayout.bitsPerPixel)
+- SET_SYNC_FLAG(info->accel);
+-}
+-
+-
+-static void
+-R128_BlitTransRect(
+- ScrnInfoPtr pScrn,
+- int srcx, int srcy,
+- int w, int h,
+- int dstx, int dsty,
+- unsigned long color
+-){
+- R128InfoPtr info = R128PTR(pScrn);
+- int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+- int ydir = (srcy < dsty) ? -1 : 1;
+-
+- info->XAAForceTransBlit = TRUE;
+-
+- (*info->accel->SetupForScreenToScreenCopy)(
+- pScrn, xdir, ydir, GXcopy, (uint32_t)(~0), color);
+-
+- info->XAAForceTransBlit = FALSE;
+-
+- (*info->accel->SubsequentScreenToScreenCopy)(
+- pScrn, srcx, srcy, dstx, dsty, w, h);
+-
+- if (pScrn->bitsPerPixel == info->CurrentLayout.bitsPerPixel)
+- SET_SYNC_FLAG(info->accel);
+-}
+-#endif
+-
+-static Bool
+-R128_OpenFramebuffer(
+- ScrnInfoPtr pScrn,
+- char **name,
+- unsigned char **mem,
+- int *size,
+- int *offset,
+- int *flags
+-){
+- R128InfoPtr info = R128PTR(pScrn);
+-
+- *name = NULL; /* no special device */
+- *mem = (unsigned char*)info->LinearAddr;
+- *size = info->FbMapSize;
+- *offset = 0;
+- *flags = /* DGA_NEED_ROOT */ 0; /* don't need root, just /dev/mem access */
+-
+- return TRUE;
+-}
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index 0a8d802..2cbfc81 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -2044,7 +2044,9 @@ Bool R128ScreenInit(SCREEN_INIT_ARGS_DECL)
+ //pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
+
+ /* DGA setup */
+- R128DGAInit(pScreen);
++#ifdef XFreeXDGA
++ xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset);
++#endif
+
+ /* Backing store setup */
+ xf86SetBackingStore(pScreen);
+@@ -3629,9 +3631,6 @@ static Bool R128CloseScreen(CLOSE_SCREEN_ARGS_DECL)
+ if (info->scratch_save) free(info->scratch_save);
+ info->scratch_save = NULL;
+
+- if (info->DGAModes) free(info->DGAModes);
+- info->DGAModes = NULL;
+-
+ if (info->adaptor) {
+ free(info->adaptor->pPortPrivates[0].ptr);
+ xf86XVFreeVideoAdaptorRec(info->adaptor);
+--
+2.2.2
+
+
+From 0519b7b3aac61dfd57cbf3bb0da561ca9bd079cb Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Sat, 23 Aug 2014 01:13:18 -0400
+Subject: Improve panel code
+
+Since the driver uses PanelXRes and PanelYRes to calculate stretch
+ratios, it should try harder to set them. For LVDS, we need to move the
+xorg.conf check so that it executes before the BIOS check. For DVI, we
+should read them from the mode that the X server has identified as being
+the native one. Even then, PanelXRes and PanelYRes are not guaranteed to
+be positive, so the driver should verify this before dividing by them.
+
+Another problem with the old panel code was that PanelPwrDly had no sane
+default. It was also missing the check for Rage Pro 2 which lacks RMX.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+---
+ src/r128_driver.c | 27 +++++++--------------------
+ src/r128_output.c | 13 ++++++++++---
+ src/r128_video.c | 10 ++++++----
+ 3 files changed, 23 insertions(+), 27 deletions(-)
+
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index 2cbfc81..98b0644 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -479,6 +479,10 @@ void R128GetPanelInfoFromBIOS(xf86OutputPtr output)
+ int FPHeader = 0;
+ int i;
+
++ r128_output->PanelPwrDly = 200;
++ xf86GetOptValInteger(info->Options, OPTION_PANEL_WIDTH, &(r128_output->PanelXRes));
++ xf86GetOptValInteger(info->Options, OPTION_PANEL_HEIGHT, &(r128_output->PanelYRes));
++
+ if (!info->VBIOS) return;
+ info->FPBIOSstart = 0;
+
+@@ -511,8 +515,6 @@ void R128GetPanelInfoFromBIOS(xf86OutputPtr output)
+ }
+
+ if (!info->FPBIOSstart) return;
+- xf86GetOptValInteger(info->Options, OPTION_PANEL_WIDTH, &(r128_output->PanelXRes));
+- xf86GetOptValInteger(info->Options, OPTION_PANEL_HEIGHT, &(r128_output->PanelYRes));
+
+ if (!r128_output->PanelXRes)
+ r128_output->PanelXRes = R128_BIOS16(info->FPBIOSstart + 25);
+@@ -2850,13 +2852,6 @@ Bool R128InitCrtcRegisters(xf86CrtcPtr crtc, R128SavePtr save, DisplayModePtr mo
+
+ save->crtc_ext_cntl |= R128_VGA_ATI_LINEAR | R128_XCRT_CNT_EN;
+
+- if (info->isDFP && !info->isPro2) {
+- if (r128_output->PanelXRes < mode->CrtcHDisplay)
+- mode->HDisplay = mode->CrtcHDisplay = r128_output->PanelXRes;
+- if (r128_output->PanelYRes < mode->CrtcVDisplay)
+- mode->VDisplay = mode->CrtcVDisplay = r128_output->PanelYRes;
+- }
+-
+ save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0xffff)
+ | (((mode->CrtcHDisplay / 8) - 1) << 16));
+
+@@ -3240,7 +3235,7 @@ Bool R128InitDDARegisters(xf86CrtcPtr crtc, R128SavePtr save,
+ VclkFreq = R128Div(pll->reference_freq * save->feedback_div,
+ pll->reference_div * save->post_div);
+
+- if (info->isDFP && !info->isPro2) {
++ if (info->isDFP && !info->isPro2 && r128_output->PanelXRes > 0) {
+ if (r128_output->PanelXRes != mode->CrtcHDisplay)
+ VclkFreq = (VclkFreq * mode->CrtcHDisplay) / r128_output->PanelXRes;
+ }
+@@ -3313,7 +3308,7 @@ Bool R128InitDDA2Registers(xf86CrtcPtr crtc, R128SavePtr save,
+ VclkFreq = R128Div(pll->reference_freq * save->feedback_div_2,
+ pll->reference_div * save->post_div_2);
+
+- if (info->isDFP && !info->isPro2) {
++ if (info->isDFP && !info->isPro2 && r128_output->PanelXRes > 0) {
+ if (r128_output->PanelXRes != mode->CrtcHDisplay)
+ VclkFreq = (VclkFreq * mode->CrtcHDisplay) / r128_output->PanelXRes;
+ }
+@@ -3418,15 +3413,7 @@ ModeStatus R128DoValidMode(xf86OutputPtr output, DisplayModePtr mode, int flags)
+ if (r128_output->MonType == MT_CRT)
+ return MODE_OK;
+
+- if (info->isDFP) {
+- if (r128_output->PanelXRes < mode->CrtcHDisplay ||
+- r128_output->PanelYRes < mode->CrtcVDisplay)
+- return MODE_NOMODE;
+- else
+- return MODE_OK;
+- }
+-
+- if (r128_output->MonType == MT_LCD) {
++ if (r128_output->MonType == MT_DFP || r128_output->MonType == MT_LCD) {
+ if (mode->Flags & V_INTERLACE) return MODE_NO_INTERLACE;
+ if (mode->Flags & V_DBLSCAN) return MODE_NO_DBLESCAN;
+ }
+diff --git a/src/r128_output.c b/src/r128_output.c
+index 8ef6d45..6c35e78 100644
+--- a/src/r128_output.c
++++ b/src/r128_output.c
+@@ -87,7 +87,7 @@ static void r128_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayMode
+ xf86CrtcPtr crtc = output->crtc;
+ R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
+
+- if (r128_crtc->crtc_id == 0)
++ if (r128_crtc->crtc_id == 0 && !info->isPro2)
+ R128InitRMXRegisters(&info->SavedReg, &info->ModeReg, output, adjusted_mode);
+
+ if (r128_output->MonType == MT_DFP)
+@@ -97,7 +97,7 @@ static void r128_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayMode
+ else if (r128_output->MonType == MT_CRT)
+ R128InitDACRegisters(&info->SavedReg, &info->ModeReg, output);
+
+- if (r128_crtc->crtc_id == 0)
++ if (r128_crtc->crtc_id == 0 && !info->isPro2)
+ R128RestoreRMXRegisters(pScrn, &info->ModeReg);
+
+ if (r128_output->MonType == MT_DFP)
+@@ -305,6 +305,13 @@ DisplayModePtr R128ProbeOutputModes(xf86OutputPtr output)
+ modes = xf86GetDefaultModes();
+
+ for (mode = modes; mode != NULL; mode = mode->next) {
++ if (r128_output->type == OUTPUT_DVI) {
++ if (mode->type & (M_T_DRIVER | M_T_PREFERRED)) {
++ r128_output->PanelXRes = mode->HDisplay;
++ r128_output->PanelYRes = mode->VDisplay;
++ }
++ }
++
+ xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
+ if (mode->status == MODE_OK)
+ mode->status = R128DoValidMode(output, mode, MODECHECK_FINAL);
+@@ -459,7 +466,7 @@ Bool R128SetupConnectors(ScrnInfoPtr pScrn)
+ R128I2CInit(output, &r128_output->pI2CBus, output->name);
+ }
+
+- if (otypes[i] != OUTPUT_VGA)
++ if (otypes[i] == OUTPUT_LVDS)
+ R128GetPanelInfoFromBIOS(output);
+ }
+
+diff --git a/src/r128_video.c b/src/r128_video.c
+index dc1f25b..9da56ff 100644
+--- a/src/r128_video.c
++++ b/src/r128_video.c
+@@ -670,7 +670,7 @@ R128DisplayVideo422(
+ int v_inc, h_inc, step_by, tmp, v_inc_shift;
+ int p1_h_accum_init, p23_h_accum_init;
+ int p1_v_accum_init;
+- Bool rmx_active;
++ Bool rmx_active = FALSE;
+
+ R128ECP(pScrn, pPriv);
+
+@@ -680,7 +680,8 @@ R128DisplayVideo422(
+ if (pScrn->currentMode->Flags & V_DBLSCAN)
+ v_inc_shift--;
+
+- rmx_active = INREG(R128_FP_VERT_STRETCH) & R128_VERT_STRETCH_ENABLE;
++ if (r128_output->PanelYRes > 0)
++ rmx_active = INREG(R128_FP_VERT_STRETCH) & R128_VERT_STRETCH_ENABLE;
+ if (rmx_active) {
+ v_inc = ((src_h * pScrn->currentMode->CrtcVDisplay / r128_output->PanelYRes) << v_inc_shift) / drw_h;
+ } else {
+@@ -759,7 +760,7 @@ R128DisplayVideo420(
+ int v_inc, h_inc, step_by, tmp, leftUV, v_inc_shift;
+ int p1_h_accum_init, p23_h_accum_init;
+ int p1_v_accum_init, p23_v_accum_init;
+- Bool rmx_active;
++ Bool rmx_active = FALSE;
+
+ v_inc_shift = 20;
+ if (pScrn->currentMode->Flags & V_INTERLACE)
+@@ -767,7 +768,8 @@ R128DisplayVideo420(
+ if (pScrn->currentMode->Flags & V_DBLSCAN)
+ v_inc_shift--;
+
+- rmx_active = INREG(R128_FP_VERT_STRETCH) & R128_VERT_STRETCH_ENABLE;
++ if (r128_output->PanelYRes > 0)
++ rmx_active = INREG(R128_FP_VERT_STRETCH) & R128_VERT_STRETCH_ENABLE;
+ if (rmx_active) {
+ v_inc = ((src_h * pScrn->currentMode->CrtcVDisplay / r128_output->PanelYRes) << v_inc_shift) / drw_h;
+ } else {
+--
+2.2.2
+
+
+From 089c81ed6b6efc4610e0c5e5fcb36dfd58b83439 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Sat, 23 Aug 2014 01:19:25 -0400
+Subject: Fix whitespace near panel code
+
+This has been bugging me.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+---
+ src/r128_driver.c | 10 +++++-----
+ src/r128_video.c | 24 ++++++++++++------------
+ 2 files changed, 17 insertions(+), 17 deletions(-)
+
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index 98b0644..f00fa1d 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -507,7 +507,7 @@ void R128GetPanelInfoFromBIOS(xf86OutputPtr output)
+ if (!FPHeader) return;
+
+ /* Assume that only one panel is attached and supported */
+- for (i = FPHeader+20; i < FPHeader+84; i += 2) {
++ for (i = FPHeader + 20; i < FPHeader + 84; i += 2) {
+ if (R128_BIOS16(i) != 0) {
+ info->FPBIOSstart = R128_BIOS16(i);
+ break;
+@@ -3409,6 +3409,7 @@ ModeStatus R128DoValidMode(xf86OutputPtr output, DisplayModePtr mode, int flags)
+ ScrnInfoPtr pScrn = output->scrn;
+ R128InfoPtr info = R128PTR(pScrn);
+ R128OutputPrivatePtr r128_output = output->driver_private;
++ int i, j;
+
+ if (r128_output->MonType == MT_CRT)
+ return MODE_OK;
+@@ -3419,9 +3420,8 @@ ModeStatus R128DoValidMode(xf86OutputPtr output, DisplayModePtr mode, int flags)
+ }
+
+ if (r128_output->MonType == MT_LCD && info->VBIOS) {
+- int i;
+ for (i = info->FPBIOSstart + 64; R128_BIOS16(i) != 0; i += 2) {
+- int j = R128_BIOS16(i);
++ j = R128_BIOS16(i);
+
+ if (mode->CrtcHDisplay == R128_BIOS16(j) &&
+ mode->CrtcVDisplay == R128_BIOS16(j + 2)) {
+@@ -3432,8 +3432,8 @@ ModeStatus R128DoValidMode(xf86OutputPtr output, DisplayModePtr mode, int flags)
+ (float)mode->Clock / 1000);
+
+ /* Assume we are using expanded mode */
+- if (R128_BIOS16(j+5)) j = R128_BIOS16(j+5);
+- else j += 9;
++ if (R128_BIOS16(j + 5)) j = R128_BIOS16(j + 5);
++ else j += 9;
+
+ mode->Clock = (uint32_t)R128_BIOS16(j) * 10;
+
+diff --git a/src/r128_video.c b/src/r128_video.c
+index 9da56ff..cac4301 100644
+--- a/src/r128_video.c
++++ b/src/r128_video.c
+@@ -574,16 +574,16 @@ R128CopyData420(
+
+ uint32_t
+ R128AllocateMemory(
+- ScrnInfoPtr pScrn,
+- void **mem_struct,
+- int size,
+- int align,
+- Bool need_accel
++ ScrnInfoPtr pScrn,
++ void **mem_struct,
++ int size,
++ int align,
++ Bool need_accel
+ ){
+- R128InfoPtr info = R128PTR(pScrn);
+- ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
+- Bool do_linear = !need_accel;
+- uint32_t offset = 0;
++ R128InfoPtr info = R128PTR(pScrn);
++ ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
++ Bool do_linear = !need_accel;
++ uint32_t offset = 0;
+
+ #ifdef HAVE_XAA_H
+ if (!info->accel && need_accel)
+@@ -608,7 +608,7 @@ R128AllocateMemory(
+ offset = area->offset;
+ }
+ #endif
+- if (!info->useEXA && do_linear) {
++ if (!info->useEXA && do_linear) {
+ FBLinearPtr linear = *mem_struct;
+ int cpp = info->CurrentLayout.pixel_bytes;
+
+@@ -643,9 +643,9 @@ R128AllocateMemory(
+ }
+
+ offset = linear->offset * cpp;
+- }
++ }
+
+- return offset;
++ return offset;
+ }
+
+ static void
+--
+2.2.2
+
+
+From fcee44e469b22934a04bd3ee19ed101aaa176a54 Mon Sep 17 00:00:00 2001
+From: Connor Behan <connor.behan@gmail.com>
+Date: Sat, 23 Aug 2014 01:24:42 -0400
+Subject: Silence the non-debug warnings
+
+Some declarations of pScrn are only there for debugging purposes. This
+should make gcc quieter on most systems.
+
+Signed-off-by: Connor Behan <connor.behan@gmail.com>
+---
+ src/r128_driver.c | 4 ++++
+ src/r128_exa_render.c | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/src/r128_driver.c b/src/r128_driver.c
+index f00fa1d..e4e43a6 100644
+--- a/src/r128_driver.c
++++ b/src/r128_driver.c
+@@ -3109,7 +3109,9 @@ void R128InitLVDSRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr out
+ void R128InitPLLRegisters(xf86CrtcPtr crtc, R128SavePtr save,
+ R128PLLPtr pll, double dot_clock)
+ {
++#if R128_DEBUG
+ ScrnInfoPtr pScrn = crtc->scrn;
++#endif
+ unsigned long freq = dot_clock * 100;
+ struct {
+ int divider;
+@@ -3162,7 +3164,9 @@ void R128InitPLLRegisters(xf86CrtcPtr crtc, R128SavePtr save,
+ void R128InitPLL2Registers(xf86CrtcPtr crtc, R128SavePtr save,
+ R128PLLPtr pll, double dot_clock)
+ {
++#if R128_DEBUG
+ ScrnInfoPtr pScrn = crtc->scrn;
++#endif
+ unsigned long freq = dot_clock * 100;
+ struct {
+ int divider;
+diff --git a/src/r128_exa_render.c b/src/r128_exa_render.c
+index c0d3688..b9601ee 100644
+--- a/src/r128_exa_render.c
++++ b/src/r128_exa_render.c
+@@ -157,8 +157,10 @@ R128GetDatatypePict2(uint32_t format, uint32_t *type)
+ static Bool
+ R128CheckCompositeTexture(PicturePtr pPict, PicturePtr pDstPict, int op)
+ {
++#if R128_DEBUG
+ ScreenPtr pScreen = pDstPict->pDrawable->pScreen;
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
++#endif
+
+ unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
+ uint32_t tmp1;
+@@ -198,8 +200,10 @@ R128CheckCompositeTexture(PicturePtr pPict, PicturePtr pDstPict, int op)
+ static Bool
+ R128CCECheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture)
+ {
++#if R128_DEBUG
+ ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
++#endif
+
+ PixmapPtr pSrcPixmap, pDstPixmap;
+ uint32_t tmp1;
+--
+2.2.2
+