Blob Blame History Raw
commit f65e8dfac23adfa199026765fe3a1ea08cf4da67
Author: Alex Deucher <alex@cube.(none)>
Date:   Sun Feb 3 00:09:59 2008 -0500

    RADEON: rework i2c handling
    
    Split out clk, data, and lock regs and masks.  some cards use different
    regs and masks for each.  For cards with ATOMBIOS, use the i2c bios
    table to grab the i2c data.

commit a38a903debc0a50dbc73f59dc2741bbea76d2bd9
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Fri Feb 1 02:59:07 2008 -0500

    RADEON: don't restore LVDS_PLL_CNTL for now
    
    seems to cause problems with resume for some users.
    this needs further investigation.
    see bug 12596

commit 5d7bea2b62c86868baf1960665a40249a43bafc5
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Fri Feb 1 02:53:22 2008 -0500

    RADEON: remove redundant RADEONDisableDisplays()
    
    use RADEONBlank() instead

commit 73b437ce232c94c0067a0d2f70538b6e1e8c07a7
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Fri Feb 1 02:47:06 2008 -0500

    RADEON: remove unused "aspect" scaler option

commit f1fb9e4daa29bc379f653f847254db1496b625fd
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Fri Feb 1 02:39:18 2008 -0500

    RADEON: Implement "center" mode for RMX on legacy radeons

commit bcd590103e04bfdb4f12413beacebf344f07e88e
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Jan 29 12:12:54 2008 -0500

    RADEON: update man page to reflect AGP 1x default revert

commit 09348a83d06ba9d3129499c4daedd44a68771530
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Jan 29 12:09:24 2008 -0500

    Seems the default is more reliable... we can't win.
    
    Revert "radeon: Default to 1x again with non-v3 AGP cards."
    
    This reverts commit b653e5a628bfa4dfb168e96f93f41eb910f409fb.

commit 0c26806245381b925b73ff9f3b747e3dcf0ebd6f
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Jan 29 10:26:48 2008 -0500

    RADEON: Add new RV380 pci id
    
    bug 14289

commit ce77ed78a877023da72dbe51609aef9a07e250b1
Author: Maciej Cencora <m.cencora@gmail.com>
Date:   Mon Jan 28 19:02:56 2008 -0500

    RS690: Implement MC idle check

commit b7de4ff52cfbdd85ee65000613632e21b92af24e
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Sat Jan 26 19:28:05 2008 +0200

    mach64: add hint for sparc and minor cosmetic.

commit 09d713aa0ed6367b4457420b3c2832fe8eca9b00
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Jan 23 18:05:41 2008 -0500

    Revert "RADEON: adjust PAL mode hstart"
    
    This reverts commit 719a9a376e34d99032af75e3f7b002670ccb816b.
    
    This breaks TV out on some cards.

commit 719a9a376e34d99032af75e3f7b002670ccb816b
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sun Jan 20 18:40:53 2008 -0500

    RADEON: adjust PAL mode hstart
    
    Most people seem to get a more aligned picture with this setting

commit b2db8657fb888cff6d64c6dcb182caac389776ce
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sun Jan 20 18:33:22 2008 -0500

    RADEON: re-work i2c for DDC
    
    Unify the radeon/avivo paths and grab the data/clk masks from bios
    if available

commit a43003b24022a833e604f41b2873c0350b34181c
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sat Jan 19 18:49:53 2008 -0500

    RADEON: get dac2 adj values from the bios tables

commit d4596c52ac9994be26e9ec2d7d57b3892c34abdb
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sat Jan 19 17:17:26 2008 -0500

    RADEON: grab pll_in_min/pll_in_max from bios tables if available

commit 9a0947c812d0d38d1bca6a91140ac210831a6cb4
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sat Jan 19 13:57:50 2008 -0500

    ATOM: Use LVDS edid from bios if available

commit 7238258c12def8ef273e5362f716d165f720c5a5
Author: Kusanagi Kouichi <slash@ma.neweb.ne.jp>
Date:   Sat Jan 19 15:04:21 2008 +0100

    radeon: Partial fix for XVideo RGB image distortions.

commit 32be3cf9d6c34e60ff8c3d6cfe9f73f1869c50e4
Author: Brice Goglin <Brice.Goglin@ens-lyon.org>
Date:   Fri Jan 18 14:42:14 2008 -0500

    RADEON: print the name of the output when printing the EDID

commit 4ba9430ee97dbce8f77db8de6ce9b753a75e453d
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Fri Jan 18 18:18:18 2008 +0200

    mach64: workaround for corruption at upper-left
    
    commit possible workaround, it's reported multiple times ...

commit 12c00111b68c9cf4872a424258c6f8b7247aac47
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Fri Jan 18 18:17:40 2008 +0200

    use stand-alone drivers for each chip family.
    
    Do not load the ati wrapper when the user specifies the sub-driver name in
    the Driver line of xorg.conf.  Also, for -configure cause the wrapper to fail
    and let each sub-driver speak for themselves.

commit 24c7d134cd450f9e2cca85e4a2fc3253d250be04
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Jan 18 09:50:38 2008 -0500

    RADEON: make sure EXA Composite is actually disabled on XPRESS chips.

commit eaf425436008092abe81208321a2b3b6698a5d79
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Jan 18 20:11:57 2008 +1000

    fixup register 6594 save/restore

commit 2a89a31481d71a56a9930073cf99d3ae7b4290e1
Author: Alex Deucher <alex@samba.(none)>
Date:   Thu Jan 17 15:08:17 2008 -0500

    RADEON: use radeon_output->Flags for tracking RMX rather than mode->Flags

commit 495e3119250ffb48489debbaabe560d23753cc43
Author: Alex Deucher <alex@samba.(none)>
Date:   Thu Jan 17 14:56:19 2008 -0500

    AVIVO: Add support for RMX
    
    Both centered and expansion modes are supported.  Select
    using output attributes.

commit 6bd510a211f25d52e74791e4a429cd2218ced541
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Jan 16 18:09:49 2008 -0500

    RADEON: add a message about render accel on newer cards

commit 85bf3439fe2579aec48f5cd8d65a9d51b1ae8535
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Jan 16 17:52:06 2008 -0500

    R300: only init3d on r3xx

commit dbb2ca471dfbff245b30c5055871dee0dc0e3d15
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Jan 16 17:10:02 2008 -0500

    R300: only enable render accel on non-IGP r3xx/r4xx chips for now

commit 3c72b100bcfacee600644669b586e86cfd32754e
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Jan 16 16:55:42 2008 -0500

    R300: First pass at render accel
    
    This first pass is pretty limited.  All it currently supports
    is transforms for rotation.  No blending yet.
    
    Based on inital implementation from Wolke Liu with
    additional lock-up fixes by Dave Airlie.

commit 2ba3562d2af911fdd90881049599e239d27260bc
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Sat Jan 12 17:11:59 2008 +0200

    ati wrapper: xf86PciInfo.h is enough

commit c2caeb11a97dad5379d70881c5c0fd834a8c3d54
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Sat Jan 12 16:18:34 2008 +0200

    ati wrapper: add DriverRec's and use them

commit 19e1b180fec6f83a474e125465bc60111c0f43e0
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Sat Jan 12 16:18:07 2008 +0200

    mach64: load for both "ati" and "mach64" as driver names
    
    similar to r128/radeon

commit 92f54400d5450b29b3a76d5ecc927cf0d73e156e
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Sat Jan 12 16:17:47 2008 +0200

    mach64: add version (need not match with ati)
    
    similar to r128/radeon

commit 311ec7b6c54a50a4b8a5a445f7283da2b0b2e0f5
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Sat Jan 12 16:17:21 2008 +0200

    atimisc: rename to mach64

commit 5244e235262290eab8a3546f449295c12ed8f6c7
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Jan 14 16:11:09 2008 -0500

    ATOMBIOS: disable the scaler by default on avivo cards
    
    Fixes bug 14001

commit 729da30c80d6545b75c8faea44754634f477cc09
Merge: 000741e... 625a885...
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Jan 14 10:05:01 2008 -0500

    Merge branch 'master' of ssh://agd5f@git.freedesktop.org/git/xorg/driver/xf86-video-ati

commit 625a885a964488da2a35065eb597a17ee57b22a9
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Wed Jan 9 17:39:56 2008 +0200

    ati wrapper: use pci ids

commit 48865200ca9f1daf87e52620b9f8175f88dd886f
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Wed Jan 9 19:01:04 2008 +0200

    radeon: remove stray include

commit a5a6b873353611cb7e46e5e375f039957c7051a7
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Wed Jan 9 13:03:32 2008 +0200

    radeon: remove stray _X_EXPORT

commit 80c9974b6cdc0147d777df6990b3f3aacd87969d
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Tue Jan 8 18:15:47 2008 +0200

    r128: pci-rework conversion
    
    compile-tested only

commit cd4b39403d74f314e1c2cfa4cf0e4fe542891dc3
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Sat Mar 10 23:12:15 2007 +0200

    Drop symbol lists from r128, radeon, theatre.
    
    compile-tested only

commit 63b4b8213fabc5a57f897b60b6eaa9f78d86e6ff
Author: George Sapountzis <gsap7@yahoo.gr>
Date:   Wed Mar 21 20:24:22 2007 +0200

    [mach64] Drop symbol lists.
    
    egrep LOADER\|SymLists\|Symbols src/*.[hc]
    
    not needed after server commit bca9364f3f4a2376edbcf57a34f704ce28be21ba, i.e.
    xserver 1.2
    
    compile-tested only

commit 000741e250e54122b0adc91694eb4bfa320a70fb
Author: Alex Deucher <alex@samba.(none)>
Date:   Thu Jan 10 14:49:48 2008 -0500

    RADEON: clean up output handling

commit 10e7636c02478b8ffe183bb0c46229ca0d6584e1
Author: Kristian Høgsberg <krh@bitplanet.net>
Date:   Wed Jan 9 12:47:39 2008 -0500

    RADEON: fix crtc routing on r4xx cards when using atom to init DVO chip

commit 3af671f5963810dbfd63abc9889b1d46b68f404c
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Jan 9 11:30:25 2008 -0500

    RADEON: restore FP2 regs before external encoders
    
    This may fix krh's dvi problem

commit 2a54c6bb09ade2ec8f998dfc1624017029d47fa3
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Jan 8 18:43:54 2008 -0500

    RADEON: Make default output actually work...

commit fa3e2055225c27e25465fc46786da1b7574fd3cc
Author: Alex Deucher <alex@botch2.(none)>
Date:   Mon Jan 7 01:13:09 2008 -0500

    RADEON: add default outputs if no connected devices
    
    If no connected devices found at server startup, default
    to something so the server comes up.  LVDS on mobility chips,
    DAC or TMDS on others.

commit d972cc9237eb90b49b11f8d2bdc5b61f628911dc
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sat Jan 5 17:19:06 2008 -0500

    RADEON: Fix TVStandard option

commit 45656b9d5a426053da2a094de39c2690c0c6f799
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sat Jan 5 12:00:55 2008 -0500

    R128: Like powerpc, don't use VGA by default on sparc

commit b8e8db4675d07e45782de0d7c67ee0fd85eaedb3
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Fri Jan 4 20:16:19 2008 -0500

    RADEON: fix tvdac load detection at server start up

commit 3ba7f393d0669df36848715799de8affc10a5534
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Fri Jan 4 20:00:48 2008 -0500

    RADEON: further fixup for pScrn->pScreen issue
    
    the previous fix seems to cause the driver to hang on
    some cards.

commit a0de9c0844f9e066e0f02e8cd8045bdd278e6494
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Fri Jan 4 19:48:30 2008 -0500

    RADEON: improve ntsc image centering

commit 03d2f25801c8a8ec15030f06008df112d07c1a2d
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Fri Jan 4 18:19:54 2008 -0500

    RADEON: fix compile

commit 308848783ed9ae27aed7c7de6ee813d375ef495e
Author: Dave Airlie <airlied@linux.ie>
Date:   Sat Jan 5 09:11:55 2008 +1000

    i2c: a line mux of 0 is valid

commit 94d5a432f72801f821d1c4ce952baba17552659d
Author: Dave Airlie <airlied@linux.ie>
Date:   Fri Jan 4 17:16:54 2008 +1000

    atombios: i2c lines are all done with sw so we can accept any of them.
    
    hch reported this working on his laptop with 0x7e60 as EDID for LVDS

commit 2e4473b63d65801ae8ac5a8391de232b2201d958
Author: Alex Deucher <alex@samba.(none)>
Date:   Thu Jan 3 15:47:50 2008 -0500

    RADEON: fix crash when setting rotation in the config file
    
    xf86CrtcRotate() accesses pScrn->pScreen which is not set
    during ScreenInit().  This should also be fixed in the server.
    See bug 12129

commit c652208861bffca94f06b7f67688ce220e050bfb
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Thu Jan 3 17:54:58 2008 +0100

    radeon: Adapt manpage to reality wrt AGP options.

commit ab451e4b7a5423d61b57cf0646599267d8504af4
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Thu Jan 3 17:52:39 2008 +0100

    radeon: Miscellaneous warning fixes.

commit 394c52273328e90518568b694ee79dc1a8dab651
Author: Dave Airlie <airlied@linux.ie>
Date:   Thu Jan 3 18:56:16 2008 +1000

    r500: tvout avoid doing dpms here it makes my tv mode go all crappy
    
    need to investigate further

commit 1c647279f021d01e110980727b7c7dd7efae1642
Author: Dave Airlie <airlied@linux.ie>
Date:   Thu Jan 3 11:55:28 2008 +1000

    r600: change devices list depending on connector

commit f36db6e10d32a68b32d20ae4ad02cfc0bfd1c9c3
Author: Dave Airlie <airlied@linux.ie>
Date:   Thu Jan 3 11:27:47 2008 +1000

    r600: fixup crash on unknown output type
    
    not sure this is 100% the correct approach

commit 1accfdd590828e95e0d68a576c8ee05a06a86e43
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Jan 2 19:48:28 2008 -0500

    RADEON: various avivo tv-out related clean-ups

commit ce34090c758ac91171cb6adb9b8a36e4adbf99cf
Merge: 2180f04... 30cab1d...
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Jan 2 16:41:36 2008 -0500

    Merge branch 'master' of git+ssh://agd5f@git.freedesktop.org/git/xorg/driver/xf86-video-ati

commit 2180f04b6fb94a638f6274cb4455d5688b324dbc
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Jan 2 16:41:06 2008 -0500

    RADEON: preliminary support for ATOM RMX
    
    not functional yet.

commit dab4dc285154d40303aadaa849b85f8e251e578e
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Jan 2 16:27:19 2008 -0500

    RADEON: add support for ATOM component video table
    
    Component output is still not working.

commit 30cab1dbebb7bdb925f2fe9f91b84183312bbbfd
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Jan 2 15:41:01 2008 -0500

    RADEON: Make sure all old IGP chips have HasSingleDac set
    
    fix the csv file and re-gen the headers.

commit e8e585651215b011e3ad07c59d0eab9107ccd8c6
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Jan 2 10:14:46 2008 +1000

    PLL/r600: tweak pll to pick first one found instead of keeping going

commit 14aa4060ad27ecb3d40b2b17ee4cf7cc55a121dd
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Jan 2 09:49:44 2008 +1000

    r600: fix tv-out output naming

commit f65374f5e15bfd391a1838a686cd87d3bab8043d
Author: Maciej Cencora <m.cencora@gmail.com>
Date:   Mon Dec 31 09:44:34 2007 +1000

    atombios: initial rs690 patches

commit a674f683e6699c30664d9cd468a64de991c3fd7e
Author: Dave Airlie <airlied@linux.ie>
Date:   Sun Dec 30 17:43:17 2007 +1000

    atombios: enable TV-out detection code - tv out works for me with this

commit aa7c28cbd943bb525698515d444cb5097880e364
Author: Dave Airlie <airlied@linux.ie>
Date:   Sun Dec 30 17:40:37 2007 +1000

    atombios: enable support for using tv timings
    
    enable support for the atombios tv timings selection by programming the crtc
    with the tv timings if a tv is detected on the output

commit 0bc3fd595a73e12a424571697d164a09a6a4c072
Author: Dave Airlie <airlied@linux.ie>
Date:   Sun Dec 30 16:39:58 2007 +1000

    atombios: add support for reading tv standard from atombios
    
    fix typo in atombios header file

commit bfa22d676a6f333503104041f62222f4de9bb7d8
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Wed Dec 26 12:29:47 2007 -0500

    RADEON: fix typo that broke tv load detection

commit 0c99554c6fab1192f5e8595469c21b5f33e1eb4f
Author: David Miller <davem@davemloft.net>
Date:   Wed Dec 26 02:19:12 2007 -0500

    [RADEON]: Add missing break in SCLK calculation.

commit 6e0d5cc1c62fbfc1962fa0d6333f0c0a8c6327bd
Author: David Miller <davem@davemloft.net>
Date:   Wed Dec 26 02:17:34 2007 -0500

    [RADEON]: Like powerpc, don't use VGA by default on sparc.

commit 2b1fae668ddabbc72e5fc31365302ea722174df1
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Wed Dec 26 02:04:06 2007 -0500

    RADEON: fix PAL tv-out
    
    Many thanks to Andrew Randrianasulu for providing me with
    pll reg dumps

commit d736eb5732da573162c70712dc4e8b0114986702
Author: Alex Deucher <alex@botch2.(none)>
Date:   Mon Dec 24 12:34:15 2007 -0500

    RADEON: default "IgnoreLidStatus" to TRUE
    
    Seems there are lots of busted ACPI lid status and people
    starting X with the lid closed.

commit 653da558148cc601bc1f80253e92ef98c75ef37a
Author: Alex Deucher <alex@botch2.(none)>
Date:   Mon Dec 24 01:11:56 2007 -0500

    RADEON: restore crtc regs before VGA regs.
    
    It seems some radeons don't restore text console properly if
    the crtc regs are restored after the VGA regs.
    Thanks to Sverre Froyen for helping me track this down

commit ad3325f672a241449ca239c8ee3a24b6d7703d76
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sun Dec 23 17:18:42 2007 -0500

    RADEON: Add "IgnoreLidStatus" option
    
    Generally, users that start X with the laptop lid closed
    want to use one or more external monitors rather than the
    internal panel and do not want the internal panel to be on
    by default.  Others, it seems, want to always have the
    internal panel on, regardless of the lid.  I can't win.
    Enable this option to force the latter.

commit 20eedf348a527e1e0a5450bc22d7564895034a66
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sun Dec 23 11:27:55 2007 -0500

    RADEON: fix pll input setup on mac cards
    
    the function was exiting before the complete setup was finished.

commit 4f2e833e8ebaba3ad85ec5314fff8fa05395b679
Author: Arkadiusz Miskiewicz <arekm@maven.pl>
Date:   Fri Dec 21 18:56:34 2007 -0500

    configure.ac fixes

commit 2b6e8e2b8f74e94560de89693ecbc7260536591e
Author: Arkadiusz Miskiewicz <arekm@maven.pl>
Date:   Fri Dec 21 18:10:17 2007 -0500

    RADEON: various cleanups

commit 4c6f60e3b19ac55ab1255c79df03b1df5950864e
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Dec 21 17:33:04 2007 -0500

    RADEON: clean up prototypes

commit 8c761afdcb9baf1649b93449692fb9ab67bc2c80
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Dec 21 16:24:49 2007 -0500

    RADEON: more re-org
    
    move save/restore routines into legacy_crtc/output

commit 910773d3a6c717f9d4762ea7b9ee6c3ae061781e
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Dec 21 15:53:15 2007 -0500

    RADEON: more re-org.  move XAA Mem init to radeon_accel.c

commit 0631a23bd103f9b74e525da2c41304eab60c6f17
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Dec 21 15:40:18 2007 -0500

    RADEON: fix rn50 reversion from last merge

commit 5b917797a13c6caa80028d1842a284598e874288
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Dec 21 15:30:20 2007 -0500

    RADEON: remove no longer used radeon_display.c

commit bf14aa5f88fc3b4e69d71db5b23248b8bb2018d0
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Dec 21 15:29:47 2007 -0500

    RADEON: re-org legacy crtc/output code into separate files

commit be7f8fd338f5af8b632f16a83db41e15d00af469
Author: Dave Airlie <airlied@linux.ie>
Date:   Fri Dec 21 10:03:49 2007 +1000

    fix mode bandwidth configure check

commit 3f9b597dedc45379b0bc0b631f3f924c403bca48
Author: Dave Airlie <airlied@linux.ie>
Date:   Fri Dec 21 09:55:42 2007 +1000

    fixup clip test include handling

commit 9a5b501332c0a1f10af20845af48c9ddd2ce26a0
Author: Dave Airlie <airlied@linux.ie>
Date:   Fri Dec 21 09:45:55 2007 +1000

    set ddc line correctly post-merge

commit 3c31b96afa20913ad947e68fe0c3a662e5eafbdd
Merge: eb99c3c... f5e8c18...
Author: Dave Airlie <airlied@linux.ie>
Date:   Fri Dec 21 09:36:22 2007 +1000

    Merge remote branch 'origin/atombios-support'
    
    Conflicts:
    
    	src/radeon_display.c
    	src/radeon_driver.c

commit f5e8c185001e62e744310667c2d1bd3fe6542a62
Author: Dave Airlie <airlied@clockmaker.usersys.redhat.com>
Date:   Wed Dec 19 10:38:58 2007 +1000

    more endian related fixage

commit 98b247066d00db66abe91f518cd93b5c4da4cfb4
Author: Dave Airlie <airlied@clockmaker.usersys.redhat.com>
Date:   Wed Dec 19 10:25:41 2007 +1000

    fix big endian build since zaphod fixups

commit bd7206fa120495037e3fea0c920d0031d7715bf6
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Dec 18 03:03:11 2007 -0500

    RADEON: fix another merge error
    
    this broken legacy radeons

commit 65a3ac7530e11bb7d818a988fd0cf1dde7688fa4
Author: Alex Deucher <alex@samba.(none)>
Date:   Tue Dec 18 00:15:38 2007 -0500

    RADEON: more PLL tweaks

commit d93a0e10b8bc6e3797a3cf6c1e28ca413a7c38e4
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Dec 17 20:32:45 2007 -0500

    RADEON: post div tweaks for legacy radeon

commit 03b8b49f6f502c45552b018fd8c44d366b2d576f
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Dec 17 20:20:04 2007 -0500

    RADEON: fix typo from merge

commit 19b9d3708852b7efe2b05249c8359dadb924dd94
Merge: cf685f3... 29706ca...
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Dec 17 20:07:32 2007 -0500

    Merge branch 'atombios-support' of git+ssh://agd5f@git.freedesktop.org/git/xorg/driver/xf86-video-ati into atombios-support

commit cf685f37ec874f0aacd09e7c4eb0402c6daec1b0
Merge: 2a134af... 44d07c4...
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Dec 17 20:07:07 2007 -0500

    Merge branch 'master' of git+ssh://agd5f@git.freedesktop.org/git/xorg/driver/xf86-video-ati into atombios-support
    
    merge master and fix conflicts

commit 29706ca585ebd9b7b3521521a17016322e9ecccb
Author: Dave Airlie <airlied@linux.ie>
Date:   Tue Dec 18 10:55:38 2007 +1000

    fixup shadow setup on !r600

commit 2a134af01bc85de758ad83a85b23d1bba4a1a0f5
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Dec 17 15:00:36 2007 +1000

    r600: add shadow support to r600 driver to at least make 2d useable

commit 614414611a9f246cbc74f579a79987fff97cf571
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Dec 17 11:10:14 2007 +1000

    radeon: cleanup pitch calculation and make r600 work again

commit 79a375dbc7f323e2f551490a35f44ec36bed877c
Author: George Wu <geo@flood.OCF.Berkeley.EDU>
Date:   Mon Dec 17 10:55:36 2007 +1000

    r600: might as well fix VT for R600

commit bc213ee723a45f2c396b4ed211a50f7642349973
Author: Alex Deucher <alex@samba.(none)>
Date:   Sun Dec 16 14:54:00 2007 -0500

    RADEON: fix sclock printout

commit a9817b2cf436a536dbc43ad77abc3bdcc53d346d
Author: Alex Deucher <alex@samba.(none)>
Date:   Sat Dec 15 20:51:53 2007 -0500

    RADEON: clean up units in PLL calculation

commit b3eed3d87f76779b5a62a3115f99a31484dc38e0
Author: Alex Deucher <alex@samba.(none)>
Date:   Fri Dec 14 00:20:10 2007 -0500

    RADEON: fix typo in previous cursor fix

commit 814c6c48aebba2e45ce257289b922cd7e92caf2a
Author: Alex Deucher <alex@samba.(none)>
Date:   Thu Dec 13 18:45:09 2007 -0500

    RADEON: rework PLL calculation
    
    - Take into account the limits from the bios tables
    - Unify the PLL calculation between legacy and avivo chips

commit f5ac34983411e4c4f41ab1817dce582830f398fd
Merge: f2b2e08... 6ccf5b3...
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Dec 12 22:37:44 2007 -0500

    Merge branch 'master' of git+ssh://agd5f@git.freedesktop.org/git/xorg/driver/xf86-video-ati into atombios-support
    
    merge and fix conflicts

commit f2b2e0804183b52d9d3f56ad85b3552ece76c544
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Dec 12 22:18:37 2007 -0500

    RADEON: fix rotation on avivo chips
    
    There are still some issues, but this is better than before.

commit 372bf41818fdafc6a9d2914aee3a8e359f668f02
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Dec 11 14:04:58 2007 -0500

    RADEON: handle HMDI properly (untested) and fix some merge leftovers

commit 3c22ad977c25d5ca2811821fcac6bb8ecd79994a
Merge: c9a0cee... f3d2ec3...
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Dec 11 13:11:15 2007 -0500

    Merge branch 'master' of ssh://agd5f@git.freedesktop.org/git/xorg/driver/xf86-video-ati into atombios-support
    
    fix conflicts

commit c9a0cee97ca69e8fe1e1937c7670fa903214cded
Author: Dave Airlie <airlied@linux.ie>
Date:   Tue Dec 11 06:03:46 2007 +1000

    more zaphod fixes - some other work maybe needed

commit 731830297f2fc4a416882aacfb0d9b5f8ed32520
Author: Dave Airlie <airlied@linux.ie>
Date:   Mon Dec 10 15:50:38 2007 +1000

    fixup some warnings

commit 2818e2b02ca90c9dfa50905b5311b2ae83ac3b0c
Author: Dave Airlie <airlied@linux.ie>
Date:   Mon Dec 10 15:43:52 2007 +1000

    add more to configure.ac for using out-of-tree mode src

commit cc3c36100986f9d8060bc2d433373d4806f8e730
Author: Dave Airlie <airlied@linux.ie>
Date:   Mon Dec 10 15:25:56 2007 +1000

    add support for building against legacy servers similiar to Intel codepaths

commit 9c278cb7fa7f18d13bde053fd75221cfba9da377
Merge: 6451ea2... cc167b9...
Author: Dave Airlie <airlied@linux.ie>
Date:   Mon Dec 10 15:18:03 2007 +1000

    Merge branch 'zaphod-lolz' of git://git.freedesktop.org/git/xorg/driver/xf86-video-ati into atombios-support
    
    Conflicts:
    
    	src/radeon.h
    	src/radeon_crtc.c
    	src/radeon_driver.c
    	src/radeon_output.c

commit 6451ea2dcc4fac762442f699935864f4a8d445f7
Merge: 0d89556... 5896ca4...
Author: Dave Airlie <airlied@linux.ie>
Date:   Mon Dec 10 15:08:42 2007 +1000

    Merge branch 'master' into atombios-support

commit cc167b9bb7f1c3b8579e51e7bc2fca2f8eba6bd1
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Dec 7 15:41:36 2007 +1000

    disable tiling for zaphod heads

commit 2ce8d192533a8c795714c5a9fb308ec74db40287
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Dec 7 15:35:21 2007 +1000

    don't add fboffset to info->FB it already is mapped at the offset

commit 0dcd926d3092100854b3e362d6659d4950508aeb
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Dec 7 14:45:04 2007 +1000

    radeon: bring back zaphod all is forgiven.
    
    You've whined, you've cried, you've nagged, and you're guilt trippin has
    made me do it... It actually wasn't as hard as I thought it would be.
    
    Still not perfect, couple of things to fix yet

commit bb5ede557bf32a42eef158ff0fbcfe1c6ede098a
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Dec 7 14:30:32 2007 +1000

    radeon: move savedreg/modereg into entity instead of info

commit 0d89556bfa41a3acbd6afe85b062e3a21f2ca057
Author: Dave Airlie <airlied@ppcg5.localdomain>
Date:   Thu Dec 6 19:23:06 2007 +1100

    powerpc: build fixes from last merge

commit dbe3d2608ecc9896db9c23b3a347b50748c51e13
Merge: 48e31cd... 21ed435...
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Dec 6 14:22:03 2007 +1000

    Merge branch 'master' into atombios-support
    
    Conflicts:
    
    	src/radeon_output.c

commit 48e31cdaa0caa21573879af5b9267773fe89176a
Author: George Wu <geo@ocf.berkeley.edu>
Date:   Sun Dec 2 15:25:09 2007 +1000

    RADEON/R600: small code cleanup

commit 1e029fef5fe264f2ced445b80bf6070abcb84b82
Author: Alex Deucher <alex@samba.(none)>
Date:   Sat Dec 1 00:58:51 2007 -0500

    RADEON: move GPIO lookup to a separate function

commit dcbef1ba9dfcf35c28e058832a55adf00afb472e
Author: Alex Deucher <alex@samba.(none)>
Date:   Sat Dec 1 00:35:25 2007 -0500

    RADEON: fix typo in previous commit
    
    check gpio table revision before connector table revision

commit fdce0598a2228c48c84deae1d7bebb2d7b3e979b
Author: Alex Deucher <alex@samba.(none)>
Date:   Sat Dec 1 00:15:34 2007 -0500

    RADEON: convert atombios connector table parsing to use ATOM structs
    
    convert and add hpd info

commit e3d7de9cc956aec5f940ad6db09e826b3a69523a
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Nov 30 20:14:42 2007 -0500

    RADEON: remove unused cruft from last atom import

commit d5d83411e8a884154d671aad440524507cce313e
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Nov 30 20:11:42 2007 -0500

    RADEON: save/restore avivo crtc cursor control
    
    this should prevent the cursor from showing up on in text
    mode or vesafb etc. after running the driver.

commit af0196f7bf0d1d5d211391149c18935d64ed2b06
Merge: d9858a2... 0175b79...
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Nov 30 16:40:28 2007 -0500

    Merge branch 'master' of ssh://agd5f@git.freedesktop.org/git/xorg/driver/xf86-video-ati into atombios-support
    
    merge master and fix conflicts

commit d9858a2b3744b99003cfb9f31b743a2d31b322e9
Author: Dave Airlie <airlied@linux.ie>
Date:   Sat Dec 1 06:49:59 2007 +1000

    radeon: add in pll spread spectrum workaround

commit e1945f1f25a34310bd58ce128c8ff27ecc985618
Merge: b368b0f... df7777b...
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Nov 30 14:30:55 2007 -0500

    Merge branch 'atombios-support' of ssh://agd5f@git.freedesktop.org/git/xorg/driver/xf86-video-ati into atombios-support

commit b368b0f22cd1d7ef9b4c65d82929c76f3b82d573
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Nov 30 14:29:27 2007 -0500

    RADEON: disable atom pll set for r4xx cards
    
    the clocks do not get set correctly in all cases.  this needs
    further investigation.

commit 5af15739571c09260750bcfd3620e16fd7fec862
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Nov 30 14:24:30 2007 -0500

    RADEON: small cleanup of pll code

commit df7777bff40c1feabcc12d2148ad6ac5213efbb3
Author: George Wu <geo@ocf.berkeley.edu>
Date:   Fri Nov 30 17:49:33 2007 +1000

    Add LVTMA PWRSEQ registers to fix VT switching for LVDS

commit 017c939cf0a2b12fbdc1681cc70c28b23ae3b397
Author: Alex Deucher <alex@samba.(none)>
Date:   Thu Nov 29 02:52:14 2007 -0500

    RADEON: implement CLUT adjust support

commit 9963b0fe01feb6dd0cb555b874a48f6fa3b255cb
Author: Alex Deucher <alex@samba.(none)>
Date:   Thu Nov 29 00:46:23 2007 -0500

    RADEON: fix cursor offset on avivo chips

commit 6c56e3d7655b17e93e8823aefe34b05291104695
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Nov 27 15:27:36 2007 -0500

    RADEON: switch r4xx to atombios load detection
    
    works great

commit 7561242e5b79bc2798ca3aace2b79e1a36949488
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Nov 27 14:50:36 2007 -0500

    RADEON: re-org load detection for legacy chips

commit febdcc2dccd42acbcd68ae630b7811cae5c58e8a
Author: Dave Airlie <airlied@linux.ie>
Date:   Wed Nov 28 05:10:57 2007 +1000

    legacy: fix fb/agp read/writes

commit bb8545146959b748994be055d5b3de66ec66c8b2
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Nov 26 17:34:51 2007 -0500

    RADEON: first pass at TV/Component video
    
    Untested and not likely to work just yet.

commit e2bde646b864dca9056d9ecfe23a0d905647ea9a
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Nov 26 14:35:57 2007 -0500

    RADEON: move crtc output source selection into atombios_output.c
    
    The function fits better as an output function and should now
    work with clones as well.

commit 16c9be4107678a2a58d3418b7f1cc94d695ca8d6
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Nov 26 14:20:54 2007 -0500

    RADEON: add default connector table for avivo chips

commit 4e792db655dc92d2864db36b4d8f6714908de8e8
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Nov 23 15:44:44 2007 +1000

    r500: set default minimum pll freq

commit a13b4c69c105c096dd05e6de2c5c154c9a8bcc71
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Nov 23 15:25:06 2007 +1000

    r5xx: cleanup pll code..
    
    Clean the PLL code to use the radeon pll structs.

commit 5d792b5673bbf4784eb0ec059221e9b57232a122
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Nov 23 15:03:13 2007 +1000

    radeon: fix up memory mapping issues for vt switch

commit 558a2ef266c1ca517c7fb464b0ccfef83238c913
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Nov 23 14:39:32 2007 +1000

    fix silly spaces

commit 1bda4424a7031de437acfca9c41d4b3668e36051
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Nov 23 14:39:19 2007 +1000

    r600: add hi agp address for mc

commit 133234c31a294f24a3968a576aad2bb8b89d0f6a
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Nov 23 14:15:18 2007 +1000

    atombios: use values from object header

commit dbf6eae7e7a4bd1bc60fefdc7ab6276ed3f097c4
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Nov 23 11:55:05 2007 +1000

    atombios: add initial object header parsing for r600 cards

commit 6b103915c11fc79d2efc43c44fc2a00c3bc64ede
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Nov 23 09:24:20 2007 +1000

    r500: make vt switch work again for me

commit d24208276aad7669feeed527dced60c76d39eae6
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Nov 23 08:50:25 2007 +1000

    avivo: fix typo in register saving

commit 0cc7e94849c1525750fabd04cf58f2dee88372e0
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Nov 21 17:06:17 2007 -0500

    RADEON: reorder crtc/pll setup

commit d56bde98efceaa8344e62f8e98db90c4bb642331
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Nov 21 17:03:39 2007 -0500

    RADEON: fix crtc to output routing
    
    Thanks to AMD for the information

commit a12390c832abe423def60e39cd5a9118e5910339
Merge: d531792... e74dca1...
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Nov 21 02:24:48 2007 -0500

    Merge branch 'atombios-support' of git://git.freedesktop.org/git/xorg/driver/xf86-video-ati into atombios-support

commit d5317922f29a57b6c4127826a2fc126c5fd7c117
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Nov 21 02:23:37 2007 -0500

    RADEON: attempt to fix crtc to output routing
    
    The output routing seems to be based on the output ids from the bios
    connector tables and the connected status in the bios scratch regs.
    I don't fully understand this yet, but this seems to work
    for the most part, however changing modes can sometimes
    lead to a blanked head.  This can be remedied by forcing
    a dpms off cycle.

commit 81ce299bffd75540925b4c8234adf11226147165
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Nov 21 01:35:44 2007 -0500

    RADEON: provide clearer debugging info

commit e74dca19416b13f97db9d1fc06299b988057d6a4
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Nov 21 16:24:25 2007 +1000

    re-enable mobility chips

commit 9c5b813dd6b3492cbc9833bc59792a5cec457e51
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Nov 21 01:22:42 2007 -0500

    RADEON: major re-org and clean up of atom output control
    
    - use radeon_output->devices to determine output
    - clean up and simplify dpms and mode set

commit 7634cb6b96f938bc6615eb2c49ae75aaefd04cce
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Nov 21 00:10:14 2007 -0500

    RADEON: make naming consistent and remove some cruft

commit 908748343fc9a6cdc38af0fc028c63a82766da3f
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Nov 21 00:05:42 2007 -0500

    RADEON: store devices ids from bios for each driver output

commit 3975da2ea8cb628f7f66c3f26c5dfa181cd1c532
Merge: e283aa3... 295ce27...
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Nov 20 23:52:29 2007 -0500

    Merge branch 'atombios-support' of git://git.freedesktop.org/git/xorg/driver/xf86-video-ati into atombios-support

commit e283aa332adf0134243a4fa3d14263719cd8a3fd
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Nov 20 23:35:46 2007 -0500

    RADEON: add LVDS atom support

commit e4bc3e1e7bb45571367d41b5328ff2590810b0f9
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Nov 20 18:09:29 2007 -0500

    RADEON: enable/disable the right TMDS controller

commit 3e47683ffaa44a89cda9bcddf530643befb27efa
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Nov 20 18:01:15 2007 -0500

    RADEON: fixup for bios tables with wrong connector types

commit 7412952eb1d1e9857cdab8417f7305f676900827
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Nov 20 18:00:12 2007 -0500

    RADEON: switch to using ATOM defines for bios device table

commit 295ce277bb0a44b9539b3dba575e7aff279dc2d0
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Nov 21 08:56:40 2007 +1000

    add missing files for make dist
    
    noted by ndim on #radeonhd

commit 20083b0695987b25e442ecbdec24f3cb6f1ac2ae
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Nov 21 08:53:44 2007 +1000

    LVDS on r500/r600 needs some work disable mobile chips for now

commit e4b8a4479ddea9b083b3a763dc0b9302e7b9a82a
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Nov 21 08:06:12 2007 +1000

    r600: add memory controller regs from AMD

commit aa88da974b97ea1e9bbb47b3494543575c09d912
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Nov 21 08:01:35 2007 +1000

    rs690 is !> r600

commit a5b34c2f1f7d5346c4489cb30e07291d1217026c
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Nov 20 16:37:29 2007 +1000

    r600: use standard memory controller setup paths

commit 4a523da5221d53f2efa49da2326500e9b0b9f14d
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Nov 20 15:31:11 2007 +1000

    r600: get r600 to work non-accelerated.
    
    DDC still not working yet

commit 80023441ba46882bc810ff3790c7148059f155f5
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Nov 20 14:10:23 2007 +1000

    r600: block r600 startup due to lack of memory controller info

commit f6fbbacc17bf9b1073d3e993b225987fd9173182
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Nov 20 13:41:55 2007 +1000

    atombios: add warnings for r500 and r600

commit 45a8b083c123b820c008f04ab857a64a8facec14
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Nov 20 13:37:00 2007 +1000

    atombios: add all r5xx and r6xx pci ids

commit 5d023e2c3c2ab44ea57ffadc9607025d602c376c
Merge: 0d1e0c7... c887260...
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Nov 20 13:02:43 2007 +1000

    Merge branch 'master' into atombios-support
    
    Conflicts:
    
    	src/radeon_chipset.h
    	src/radeon_driver.c
    	src/radeon_probe.c

commit 0d1e0c7805b3d8e56ccb49465e6b144afb7bdc51
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Nov 20 09:08:04 2007 +1000

    r5xx: add 71c5 for macbook pro

commit d5909b30595c103bb5f42cd1704330f944bba49c
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Nov 20 08:15:58 2007 +1000

    r5xx: cleanups after last merge

commit fe2f7a09050fb7a345a1f52239f8f3c4f1053891
Merge: 744c8cb... 49055d8...
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Nov 20 08:04:32 2007 +1000

    Merge branch 'master' into agd-atom-merge
    
    Conflicts:
    
    	src/radeon_cursor.c
    	src/radeon_output.c

commit 744c8cb6c293fcaa687566f52901644e699baace
Merge: e258fbe... e530af7...
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Nov 20 07:56:33 2007 +1000

    Merge branch 'agd-atom' of ssh://people.freedesktop.org/~agd5f/xf86-video-ati-atom into agd-atom

commit e258fbe411d255a1044b61d7ff738aee3fb5b7f4
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 19 16:35:05 2007 +1000

    makes 2-headed cursor work

commit e530af79adf51b3e95a0eca676c915a34dcbf4a7
Merge: 69e197f... 52aba8d...
Author: Alex Deucher <alex@botch2.(none)>
Date:   Mon Nov 19 00:59:30 2007 -0500

    Merge branch 'agd-atom' of /home/alex/git/airlied/xf86-video-ati2 into agd-atom

commit 69e197f2c8002aacf2587754c8d3bd63c88f85b1
Merge: 5e8940f... 862dcab...
Author: Alex Deucher <alex@botch2.(none)>
Date:   Mon Nov 19 00:57:34 2007 -0500

    Merge branch 'agd-atom' of /home/alex/git/airlied/xf86-video-ati2 into agd-atom

commit fca47ad083449f4cf9063dd970cdcebea6a7f110
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 19 15:53:40 2007 +1000

    add z3ro's pciids

commit 5e8940fa6e33d09091aa4bcf04b0f9e79596e1b8
Author: Alex Deucher <alex@botch2.(none)>
Date:   Mon Nov 19 00:52:38 2007 -0500

    fix logic in connector table check for TVs and switch counter to symbolic names

commit c19123fd9483758eb6b286c3dffcb6d79d5b1ee5
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 19 15:46:58 2007 +1000

    add firegl card on ajaxs machine

commit f02f340e466a415b4e01648ca1e323f4ce125885
Author: Alex Deucher <alex@botch2.(none)>
Date:   Mon Nov 19 00:39:19 2007 -0500

    Don't assign a gpio for TV

commit 52aba8d73189ba959f19c0437499d5e7a8829827
Merge: 862dcab... 5e8940f...
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 19 15:30:46 2007 +1000

    Merge branch 'agd-atom' of ssh://people.freedesktop.org/~agd5f/xf86-video-ati-atom into agd-atom

commit 862dcabfe0c10751d815e5cdd7436c10c2c2db10
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 19 15:30:08 2007 +1000

    r520: nail i2c enable/disable issue

commit f3dd7f413b670eeb6b8639f6677d72050ad5fe04
Author: Alex Deucher <alex@botch2.(none)>
Date:   Mon Nov 19 00:19:39 2007 -0500

    Don't detect TV out for now

commit 94de0e22d7229ca71e18e1e849d8545d9ca7bafe
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 19 14:47:33 2007 +1000

    i2c: fix bus enable stuff

commit 3f1fc7eef13ea02fa5119e9b51d499841b801f2d
Author: Alex Deucher <alex@botch2.(none)>
Date:   Mon Nov 19 00:02:14 2007 -0500

    CRTs/DFPs may share a DVI port, but TV and CV don't

commit 8f84c5ad4c4af14612ea68fe6f24d0d527f00acc
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sun Nov 18 23:43:06 2007 -0500

    fix typo in loop

commit 384cd8f52c89d089c6559e2eedbae45641fcd14e
Merge: f3f0e4e... 234b607...
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 19 14:02:55 2007 +1000

    Merge branch 'agd-atom' of ../xf86-video-ati into agd-atom

commit f3f0e4ec92c935c89ddb2f4241fe4335a521b439
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sun Nov 18 23:14:01 2007 -0500

    RADEON: unify connectortype handling

commit 234b6073054ac7630e82781683e666b94b2f12de
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 19 14:02:09 2007 +1000

    restore avivo memory map registers at correct places

commit 459a30ba511fe2fa8051380a9741fcfd9bb401ef
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 19 13:44:38 2007 +1000

    fix type for r520 agp code

commit 760af92412ef0d5cc44e52e7cec11fd80c4aaaeb
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sun Nov 18 22:34:59 2007 -0500

    RADEON: unify DDC line handling

commit e73bf6290da20dd61798ace775999ce1cb550934
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 19 13:32:16 2007 +1000

    add x1900xt support

commit 2e37937bacd624d616b91c41006c113791ebe98d
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sun Nov 18 20:18:50 2007 -0500

    RADEON: step one in output rework
    
    re-organize the output type

commit 679e7a2e0d1b213524b8109193483bc9840fb116
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sun Nov 18 17:56:51 2007 -0500

    Few fixes from the last commit.
    
    Update parser works fine on r4xx.

commit 1cd7cc3e6758ab1012f3ced6e958a1517f45557f
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sun Nov 18 17:44:36 2007 -0500

    WIP: new atom code comples.
    
    I commented out the object parsing for the time being as
    using it will require some thought as to new output
    related data structures.

commit b155fa872ee4ca5d801e942aee6e619cef104f35
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sat Nov 17 00:34:56 2007 -0500

    WIP: more new ATOM integration work

commit 67db114d97abed7a607467e5d67c7b4ffa2c347e
Merge: 7d06a87... ea15346...
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Nov 16 14:29:53 2007 -0500

    Merge branch 'agd-atom' of /home/alex/git/airlied/xf86-video-ati2 into agd-atom

commit ea1534659de87d3d75eb20d808d039cff22cb537
Author: Dave Airlie <airlied@linux.ie>
Date:   Fri Nov 16 18:46:02 2007 +1000

    avivo: fixup some i2c stuff

commit 7d06a8791839ce6b22e2449646832b79cebf1b21
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Nov 16 02:43:00 2007 -0500

    WIP: sync up with the latest ATOM bios code in rhd
    
    doesn't compile ATM

commit 3614d80ceb9a7b3615b0baab3cf2dd34ed4ab464
Author: Dave Airlie <airlied@linux.ie>
Date:   Fri Nov 16 17:22:39 2007 +1000

    add missing hpd register

commit 9a2715fda97ac0ebcb45650a416e0652aab575b8
Author: Dave Airlie <airlied@linux.ie>
Date:   Fri Nov 16 17:22:25 2007 +1000

    make i2c unlock/lock registers for gpios

commit 20dc549fff9a4137c93ebed449d05e0c437b6bc1
Author: Dave Airlie <airlied@linux.ie>
Date:   Fri Nov 16 17:01:33 2007 +1000

    avivo i2c: consolidate the avivo i2c code

commit 3e62730f79a13883a65a568bc821bc56055a4ab7
Author: Dave Airlie <airlied@linux.ie>
Date:   Fri Nov 16 15:19:00 2007 +1000

    atombios: fixup warnings in atombios files

commit cca7af3c4910983f7f090792986fcbfa0dc97cfb
Author: Dave Airlie <airlied@linux.ie>
Date:   Fri Nov 16 15:04:01 2007 +1000

    remove avivo_reg.h

commit d39eb2077c6b2fc094ccd952772528eb9428c587
Author: Dave Airlie <airlied@linux.ie>
Date:   Fri Nov 16 15:00:50 2007 +1000

    radeon: rename a large section of avivo regs to documented names

commit b7774c28dde72a205a40be78003df72eabfb9b1f
Author: Dave Airlie <airlied@linux.ie>
Date:   Fri Nov 16 14:48:36 2007 +1000

    Add copyright headers

commit 3cfcd2164b400bd0d1cb4ede8eeb01abba9d75c8
Merge: efac14e... 718bfd3...
Author: Alex Deucher <alex@botch2.(none)>
Date:   Thu Nov 15 23:25:39 2007 -0500

    Merge branch 'agd-atom' of /home/alex/git/airlied/xf86-video-ati2 into agd-atom

commit efac14e669a0c6184f8848191eb49ffb21934ee1
Author: Dave Airlie <airlied@linux.ie>
Date:   Thu Nov 15 23:17:25 2007 -0500

    r5xx: fix typo for crtc offset

commit e6db621c37ff615be286462f000d67a662c5c331
Author: Alex Deucher <alex@botch2.(none)>
Date:   Thu Nov 15 23:15:56 2007 -0500

    fix INMC() and OUTMC() on !AVIVO chips
    
    WR_EN is bit 8 so don't use OUTREG8.

commit 52ba3fdd1ce05983fabedff234cfaf4c60fba38d
Author: Alex Deucher <alex@botch2.(none)>
Date:   Thu Nov 15 23:12:30 2007 -0500

    atombios_dac_detect() takes care of primary vs tv dac itself

commit 718bfd3b61879172eee819fdab7080d5d4c0a756
Author: Dave Airlie <airlied@linux.ie>
Date:   Fri Nov 16 10:37:04 2007 +1000

    r5xx: fix typo for crtc offset

commit 7aeb35e5ad1aed6e78a3d8565fbfbfe66232ab45
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sun Nov 11 19:29:30 2007 -0500

    fix from last commit

commit 2ea95900547165e86ad3f8a41ce3331a05bad60e
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sun Nov 11 18:43:03 2007 -0500

    Add full parsing support for atom bios connector table

commit 7ce730828c293f0810dfdc554df48dfd76e35c49
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sun Nov 11 12:37:01 2007 -0500

    rework crtc output source setup

commit d61b6c78aa7810a2f9b9e2d9d95aab4295de80ce
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sun Nov 11 11:58:17 2007 -0500

    make sure i2c bus exists before using it

commit 342e3e207efda42ba679731c30dfb9d5e9d5643f
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Nov 9 17:11:43 2007 -0500

    combine outputs based on id

commit 8078c299d5941460243944d55051547c1a4d3791
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Nov 9 16:35:08 2007 -0500

    use atom to program plls on r4xx

commit 5febe2c96642f61d006abe6e8081e69d5b95adc0
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Nov 9 16:24:56 2007 -0500

    turn off vga control when using ext modes

commit 83f170c32c08c74a9e3466ffa0e0a0606c74427b
Author: Alex Deucher <alex@botch2.(none)>
Date:   Thu Nov 8 19:33:13 2007 -0500

    add pci ids for X1550PRO

commit 5cdcaba0f6e9de2d15cfcc109ab97d9fd423e3bf
Author: Alex Deucher <alex@botch2.(none)>
Date:   Thu Nov 8 19:28:03 2007 -0500

    make sure to assign gpio

commit 2dcb852778301b9284a2b4906dcf64f95ed638b7
Author: Alex Deucher <alex@botch2.(none)>
Date:   Thu Nov 8 18:39:23 2007 -0500

    pull in another of Dave's fixes

commit 96273016a0bbdfa4d3a4e6275a3b09eeeadaa534
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Nov 7 01:22:30 2007 -0500

    fix and move crtc source set up atombios_output.c
    
    it's really more output related.

commit 5c495c81cc3bcd4a38d06954243ed3bdc85bdc07
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Nov 7 01:04:11 2007 -0500

    add support for initing external tmds via ATOM

commit 5c13d9355280e6de44ebbf8de7ea89a6b91c7388
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Nov 7 00:17:28 2007 -0500

    add avivo output stuff

commit 68e7f5c67e2e9d2162b469ce31f452f3f89756b5
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Nov 6 23:43:29 2007 -0500

    more avivo updates

commit 303562dfb57e13c027b2aa9289d54e547c829ff1
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Nov 6 23:06:46 2007 -0500

    add additional connector types

commit 0d3e0735f710cb7b9505e4330997aa332f73c102
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Nov 6 22:59:25 2007 -0500

    First round of avivo support

commit 0abfe3150ce3eed4db93ccc2975bd4622dfa54a7
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Nov 6 18:47:00 2007 -0500

    Add atombios files

commit 20f01950e42babc308b4470df6a3c6628c932003
Author: Alex Deucher <alex@botch2.(none)>
Date:   Tue Nov 6 18:04:43 2007 -0500

    for r4xx ATOM cards, just use ATOM for PLL
    
    while crtc timing and pll seem to work fine, output setup
    and routing don't seem to work too reliably with atom.
    AMD claims ATOM was still pretty new with r4xx so
    it's probably better to stick with direct programming for
    some things.

commit 78a3eabff382e8ebe33df2039076fb083bcc361b
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sun Nov 4 14:11:26 2007 -0500

    WIP: get ATOM crtc stuff working on r4xx

commit 5e9ebd8e496b72b051053d637c63b2956b7861d3
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sat Nov 3 20:46:17 2007 -0400

    Initial support for r4xx
    
    - add r3xx/r4xx MC access macros and functions

commit c106075ccb81ca2ee4894743e676fd37653c8dce
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sat Nov 3 18:29:20 2007 -0400

    More of Dave's ATOM init code.

commit e18f5d61806b445ad77d93e258fbce9422b52bb6
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sat Nov 3 18:20:55 2007 -0400

    Initial integration of Atom code and some of Dave's code.
    
    ATOM builds, but it's not hooked up yet.
diff --git a/configure.ac b/configure.ac
index 48302d2..cc2b01a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -40,7 +40,7 @@ AC_PROG_LIBTOOL
 AC_PROG_CC
 
 if test "x$GCC" = "xyes"; then
-	CFLAGS="$CFLAGS -Wall"
+	CPPFLAGS="$CPPFLAGS -Wall"
 fi
 
 AH_TOP([#include "xorg-server.h"])
@@ -62,6 +62,11 @@ AC_ARG_ENABLE(exa,
               [EXA="$enableval"],
               [EXA=yes])
 
+AC_ARG_WITH(xserver-source,AC_HELP_STRING([--with-xserver-source=XSERVER_SOURCE],
+                                          [Path to X server source tree]),
+                           [ XSERVER_SOURCE="$withval" ],
+                           [ XSERVER_SOURCE="" ])
+
 # Checks for extensions
 XORG_DRIVER_CHECK_EXT(XINERAMA, xineramaproto)
 XORG_DRIVER_CHECK_EXT(RANDR, randrproto)
@@ -71,7 +76,7 @@ XORG_DRIVER_CHECK_EXT(XF86MISC, xf86miscproto)
 XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
 
 # Checks for pkg-config packages
-PKG_CHECK_MODULES(XORG, [xorg-server >= 1.3 xproto fontsproto $REQUIRED_MODULES])
+PKG_CHECK_MODULES(XORG, [xorg-server >= 1.2 xproto fontsproto $REQUIRED_MODULES])
 sdkdir=$(pkg-config --variable=sdkdir xorg-server)
 
 # Checks for libraries.
@@ -112,6 +117,11 @@ if test "$DRI" = yes; then
 	fi
 fi
 
+save_CFLAGS="$CFLAGS"
+CFLAGS="$XORG_CFLAGS"
+AC_CHECK_HEADER(xf86Modes.h,[XMODES=yes],[XMODES=no],[#include "xorg-server.h"])
+CFLAGS="$save_CFLAGS"
+
 # Note that this is sort of inverted from drivers/ati/Imakefile in
 # the monolith.  We test for foo, not for !foo (i.e. ATMISC_CPIO, not
 # ATIMISC_AVOID_CPIO), but the defines are negative.  So beware.  Oh yeah,
@@ -207,17 +217,63 @@ AC_CHECK_DECL(xf86XVFillKeyHelperDrawable,
 AC_CHECK_DECL(xf86ModeBandwidth,
 	      [AC_DEFINE(HAVE_XF86MODEBANDWIDTH, 1, [Have xf86ModeBandwidth prototype])],
 	      [],
-	      [#include "xf86Modes.h"])
+	      [#include "xorg-server.h"
+	       #include "xf86Modes.h"])
 
 AC_CHECK_DECL(xf86_crtc_clip_video_helper,
 	      [AC_DEFINE(HAVE_XF86CRTCCLIPVIDEOHELPER, 1, [Have xf86_crtc_clip_video_helper prototype])],
 	      [],
-	      [#include "xf86Crtc.h"])
+	      [#include <X11/Xmd.h>
+	       #include "xorg-server.h"
+	       #include "xf86i2c.h"
+	       #include "xf86Crtc.h"])
 
 AC_CHECK_DECL(XSERVER_LIBPCIACCESS,
 	      [XSERVER_LIBPCIACCESS=yes],[XSERVER_LIBPCIACCESS=no],
 	      [#include "xorg-server.h"])
 
+AM_CONDITIONAL(XMODES, test "x$XMODES" = xno)
+
+if test "x$XSERVER_SOURCE" = x; then
+        if test -d ../../xserver; then
+                XSERVER_SOURCE="`cd ../../xserver && pwd`"
+        fi
+fi
+
+if test -d "$XSERVER_SOURCE"; then
+        case "$XSERVER_SOURCE" in
+        /*)
+                ;;
+        *)
+                XSERVER_SOURCE="`cd $XSERVER_SOURCE && pwd`"
+        esac
+        if test -f src/modes/xf86Modes.h; then
+                :
+        else
+                ln -sf $XSERVER_SOURCE/hw/xfree86/modes src/modes
+        fi
+
+        if test -f src/parser/xf86Parser.h; then
+                :
+        else
+                ln -sf $XSERVER_SOURCE/hw/xfree86/parser src/parser
+        fi
+fi
+if test "x$XMODES" = xyes; then
+        AC_MSG_NOTICE([X server has new mode code])
+        AC_DEFINE(XMODES, 1,[X server has built-in mode code])
+        XMODES_CFLAGS=
+else
+        if test -f src/modes/xf86Modes.h -a -f src/parser/xf86Parser.h; then
+                AC_MSG_NOTICE([X server is missing new mode code, using local copy])
+        else
+                AC_MSG_ERROR([Must have X server >= 1.3 source tree for mode setting code. Please specify --with-xserver-source])
+        fi
+        XMODES_CFLAGS='-DXF86_MODES_RENAME -I$(top_srcdir)/src -I$(top_srcdir)/src/modes -I$(top_srcdir)/src/parser'
+fi
+
+AC_SUBST([XMODES_CFLAGS])
+
 CPPFLAGS="$SAVE_CPPFLAGS"
 
 AM_CONDITIONAL(USE_EXA, test "x$USE_EXA" = xyes)
diff --git a/man/ati.man b/man/ati.man
index c6c7d01..d8d84eb 100644
--- a/man/ati.man
+++ b/man/ati.man
@@ -17,7 +17,7 @@ ati \- ATI video driver
 is an __xservername__ wrapper driver for ATI video cards.  It autodetects
 whether your hardware has a Radeon, Rage 128, or Mach64 or earlier class of
 chipset, and loads the radeon(__drivermansuffix__),
-r128(__drivermansuffix__), or atimisc driver as
+r128(__drivermansuffix__), or mach64 driver as
 appropriate.
 .SH SUPPORTED HARDWARE
 The
diff --git a/man/r128.man b/man/r128.man
index 32bbaae..709c2fe 100644
--- a/man/r128.man
+++ b/man/r128.man
@@ -136,7 +136,7 @@ shouldn't be if the console is using radeonfb or some other graphic
 mode driver. Some platforms like PowerPC have issues with those, and they aren't
 necessary unless you have a real text mode in console. The default is
 .B off
-on PowerPC and
+on PowerPC and SPARC and
 .B on
 on other architectures.
 
diff --git a/man/radeon.man b/man/radeon.man
index 3c4df23..b4ade32 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -154,13 +154,13 @@ The default value is either 1536 (for most chips) or 1920.
 Set AGP data transfer rate.
 (used only when DRI is enabled)
 .br
-1      \-\- 1x (before AGPv3 only)
+1      \-\- 1x (before AGP v3 only)
 .br
-2      \-\- 2x (before AGPv3 only)
+2      \-\- 2x (before AGP v3 only)
 .br
 4      \-\- 4x
 .br
-8      \-\- 8x (AGPv3 only)
+8      \-\- 8x (AGP v3 only)
 .br
 others \-\- invalid
 .br
@@ -172,8 +172,8 @@ Enable AGP fast writes.  Enabling this is frequently the cause of
 instability. Used only when the DRI is enabled. If you enable
 this option you will get *NO* support from developers.
 .br
-The default is to
-.B leave it unchanged.
+The default is
+.B off.
 .TP
 .BI "Option \*qBusType\*q \*q" string \*q
 Used to replace previous ForcePCIMode option.
@@ -362,7 +362,7 @@ shouldn't be if the console is using radeonfb or some other graphic
 mode driver. Some platforms like PowerPC have issues with those, and they aren't
 necessary unless you have a real text mode in console. The default is
 .B off
-on PowerPC and
+on PowerPC and SPARC and
 .B on
 on other architectures.
 .TP
@@ -467,6 +467,12 @@ Enable this option to force TV Out to always be detected as attached.
 The default is
 .B off 
 .TP
+.BI "Option \*qIgnoreLidStatus\*q \*q" boolean \*q
+Enable this option to ignore lid status on laptops and always detect
+LVDS as attached.
+The default is
+.B on. 
+.TP
 
 .SH SEE ALSO
 __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
diff --git a/src/AtomBios/CD_Operations.c b/src/AtomBios/CD_Operations.c
new file mode 100644
index 0000000..1e48f81
--- /dev/null
+++ b/src/AtomBios/CD_Operations.c
@@ -0,0 +1,954 @@
+/*
+ * Copyright 2006-2007 Advanced Micro Devices, Inc.  
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+
+Module Name:
+
+    CD_Operations.c
+
+Abstract:
+
+		Functions Implementing Command Operations and other common functions
+
+Revision History:
+
+	NEG:27.09.2002	Initiated.
+--*/
+#define __SW_4
+
+#include "Decoder.h"
+#include	"atombios.h"
+
+
+
+VOID PutDataRegister(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+VOID PutDataPS(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+VOID PutDataWS(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+VOID PutDataFB(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+VOID PutDataPLL(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+VOID PutDataMC(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+UINT32 GetParametersDirect32(PARSER_TEMP_DATA STACK_BASED *	pParserTempData);
+UINT32 GetParametersDirect16(PARSER_TEMP_DATA STACK_BASED *	pParserTempData);
+UINT32 GetParametersDirect8(PARSER_TEMP_DATA STACK_BASED *	pParserTempData);
+
+UINT32 GetParametersRegister(PARSER_TEMP_DATA STACK_BASED *	pParserTempData);
+UINT32 GetParametersPS(PARSER_TEMP_DATA STACK_BASED *	pParserTempData);
+UINT32 GetParametersWS(PARSER_TEMP_DATA STACK_BASED *	pParserTempData);
+UINT32 GetParametersFB(PARSER_TEMP_DATA STACK_BASED *	pParserTempData);
+UINT32 GetParametersPLL(PARSER_TEMP_DATA STACK_BASED *	pParserTempData);
+UINT32 GetParametersMC(PARSER_TEMP_DATA STACK_BASED *	pParserTempData);
+
+VOID SkipParameters16(PARSER_TEMP_DATA STACK_BASED *	pParserTempData);
+VOID SkipParameters8(PARSER_TEMP_DATA STACK_BASED *	pParserTempData);
+
+UINT32 GetParametersIndirect(PARSER_TEMP_DATA STACK_BASED *	pParserTempData);
+UINT32 GetParametersDirect(PARSER_TEMP_DATA STACK_BASED *	pParserTempData);
+
+UINT16* GetDataMasterTablePointer(DEVICE_DATA STACK_BASED*  pDeviceData);
+UINT8 GetTrueIndexInMasterTable(PARSER_TEMP_DATA STACK_BASED * pParserTempData, UINT8 IndexInMasterTable);
+
+
+WRITE_IO_FUNCTION WritePCIFunctions[8] =   {
+    WritePCIReg32,
+    WritePCIReg16, WritePCIReg16, WritePCIReg16,
+    WritePCIReg8,WritePCIReg8,WritePCIReg8,WritePCIReg8
+};
+WRITE_IO_FUNCTION WriteIOFunctions[8] =    {
+    WriteSysIOReg32,
+    WriteSysIOReg16,WriteSysIOReg16,WriteSysIOReg16,
+    WriteSysIOReg8,WriteSysIOReg8,WriteSysIOReg8,WriteSysIOReg8
+};
+READ_IO_FUNCTION ReadPCIFunctions[8] =      {
+    (READ_IO_FUNCTION)ReadPCIReg32,
+    (READ_IO_FUNCTION)ReadPCIReg16,
+    (READ_IO_FUNCTION)ReadPCIReg16,
+    (READ_IO_FUNCTION)ReadPCIReg16,
+    (READ_IO_FUNCTION)ReadPCIReg8,
+    (READ_IO_FUNCTION)ReadPCIReg8,
+    (READ_IO_FUNCTION)ReadPCIReg8,
+    (READ_IO_FUNCTION)ReadPCIReg8
+};
+READ_IO_FUNCTION ReadIOFunctions[8] =       {
+    (READ_IO_FUNCTION)ReadSysIOReg32,
+    (READ_IO_FUNCTION)ReadSysIOReg16,
+    (READ_IO_FUNCTION)ReadSysIOReg16,
+    (READ_IO_FUNCTION)ReadSysIOReg16,
+    (READ_IO_FUNCTION)ReadSysIOReg8,
+    (READ_IO_FUNCTION)ReadSysIOReg8,
+    (READ_IO_FUNCTION)ReadSysIOReg8,
+    (READ_IO_FUNCTION)ReadSysIOReg8
+};
+READ_IO_FUNCTION GetParametersDirectArray[8]={
+    GetParametersDirect32,
+    GetParametersDirect16,GetParametersDirect16,GetParametersDirect16,
+    GetParametersDirect8,GetParametersDirect8,GetParametersDirect8,
+    GetParametersDirect8
+};
+
+COMMANDS_DECODER PutDataFunctions[6]   =     {
+    PutDataRegister,
+    PutDataPS,
+    PutDataWS,
+    PutDataFB,
+    PutDataPLL,
+    PutDataMC
+};
+CD_GET_PARAMETERS GetDestination[6]   =     {
+    GetParametersRegister,
+    GetParametersPS,
+    GetParametersWS,
+    GetParametersFB,
+    GetParametersPLL,
+    GetParametersMC
+};
+
+COMMANDS_DECODER SkipDestination[6]   =     {
+    SkipParameters16,
+    SkipParameters8,
+    SkipParameters8,
+    SkipParameters8,
+    SkipParameters8,
+    SkipParameters8
+};
+
+CD_GET_PARAMETERS GetSource[8]   =          {
+    GetParametersRegister,
+    GetParametersPS,
+    GetParametersWS,
+    GetParametersFB,
+    GetParametersIndirect,
+    GetParametersDirect,
+    GetParametersPLL,
+    GetParametersMC
+};
+
+UINT32 AlignmentMask[8] =                   {0xFFFFFFFF,0xFFFF,0xFFFF,0xFFFF,0xFF,0xFF,0xFF,0xFF};
+UINT8  SourceAlignmentShift[8] =            {0,0,8,16,0,8,16,24};
+UINT8  DestinationAlignmentShift[4] =       {0,8,16,24};
+
+#define INDIRECTIO_ID         1
+#define INDIRECTIO_END_OF_ID  9
+
+VOID IndirectIOCommand(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+VOID IndirectIOCommand_MOVE(PARSER_TEMP_DATA STACK_BASED * pParserTempData, UINT32 temp);
+VOID IndirectIOCommand_MOVE_INDEX(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+VOID IndirectIOCommand_MOVE_ATTR(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+VOID IndirectIOCommand_MOVE_DATA(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+VOID IndirectIOCommand_SET(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+VOID IndirectIOCommand_CLEAR(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+
+INDIRECT_IO_PARSER_COMMANDS  IndirectIOParserCommands[10]={
+    {IndirectIOCommand,1},
+    {IndirectIOCommand,2},
+    {ReadIndReg32,3},
+    {WriteIndReg32,3},
+    {IndirectIOCommand_CLEAR,3},
+    {IndirectIOCommand_SET,3},
+    {IndirectIOCommand_MOVE_INDEX,4},
+    {IndirectIOCommand_MOVE_ATTR,4},
+    {IndirectIOCommand_MOVE_DATA,4},
+    {IndirectIOCommand,3}
+};
+
+
+VOID IndirectIOCommand(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+}
+
+
+VOID IndirectIOCommand_MOVE_INDEX(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->IndirectData &= ~((0xFFFFFFFF >> (32-pParserTempData->IndirectIOTablePointer[1])) << pParserTempData->IndirectIOTablePointer[3]);
+    pParserTempData->IndirectData |=(((pParserTempData->Index >> pParserTempData->IndirectIOTablePointer[2]) &
+				      (0xFFFFFFFF >> (32-pParserTempData->IndirectIOTablePointer[1]))) << pParserTempData->IndirectIOTablePointer[3]);
+}
+
+VOID IndirectIOCommand_MOVE_ATTR(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->IndirectData &= ~((0xFFFFFFFF >> (32-pParserTempData->IndirectIOTablePointer[1])) << pParserTempData->IndirectIOTablePointer[3]);
+    pParserTempData->IndirectData |=(((pParserTempData->AttributesData >> pParserTempData->IndirectIOTablePointer[2])
+				      & (0xFFFFFFFF >> (32-pParserTempData->IndirectIOTablePointer[1]))) << pParserTempData->IndirectIOTablePointer[3]);
+}
+
+VOID IndirectIOCommand_MOVE_DATA(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->IndirectData &= ~((0xFFFFFFFF >> (32-pParserTempData->IndirectIOTablePointer[1])) << pParserTempData->IndirectIOTablePointer[3]);
+    pParserTempData->IndirectData |=(((pParserTempData->DestData32 >> pParserTempData->IndirectIOTablePointer[2])
+				      & (0xFFFFFFFF >> (32-pParserTempData->IndirectIOTablePointer[1]))) << pParserTempData->IndirectIOTablePointer[3]);
+}
+
+
+VOID IndirectIOCommand_SET(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->IndirectData |= ((0xFFFFFFFF >> (32-pParserTempData->IndirectIOTablePointer[1])) << pParserTempData->IndirectIOTablePointer[2]);
+}
+
+VOID IndirectIOCommand_CLEAR(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->IndirectData &= ~((0xFFFFFFFF >> (32-pParserTempData->IndirectIOTablePointer[1])) << pParserTempData->IndirectIOTablePointer[2]);
+}
+
+
+UINT32 IndirectInputOutput(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    // if ((pParserTempData->IndirectData & 0x7f)==INDIRECT_IO_MM) pParserTempData->IndirectData|=pParserTempData->CurrentPortID;
+//  pParserTempData->IndirectIOTablePointer=pParserTempData->IndirectIOTable;
+    while (*pParserTempData->IndirectIOTablePointer)
+    {
+	if ((pParserTempData->IndirectIOTablePointer[0] == INDIRECTIO_ID) &&
+            (pParserTempData->IndirectIOTablePointer[1] == pParserTempData->IndirectData))
+	{
+	    pParserTempData->IndirectIOTablePointer+=IndirectIOParserCommands[*pParserTempData->IndirectIOTablePointer].csize;
+	    while (*pParserTempData->IndirectIOTablePointer != INDIRECTIO_END_OF_ID)
+	    {
+		IndirectIOParserCommands[*pParserTempData->IndirectIOTablePointer].func(pParserTempData);
+		pParserTempData->IndirectIOTablePointer+=IndirectIOParserCommands[*pParserTempData->IndirectIOTablePointer].csize;
+	    }
+	    pParserTempData->IndirectIOTablePointer-=*(UINT16*)(pParserTempData->IndirectIOTablePointer+1);
+	    pParserTempData->IndirectIOTablePointer++;
+	    return pParserTempData->IndirectData;
+	} else pParserTempData->IndirectIOTablePointer+=IndirectIOParserCommands[*pParserTempData->IndirectIOTablePointer].csize;
+    }
+    return 0;
+}
+
+
+
+VOID PutDataRegister(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->Index=(UINT32)pParserTempData->pCmd->Parameters.WordXX.PA_Destination;
+    pParserTempData->Index+=pParserTempData->CurrentRegBlock;
+    switch(pParserTempData->Multipurpose.CurrentPort){
+	case ATI_RegsPort:
+	    if (pParserTempData->CurrentPortID == INDIRECT_IO_MM)
+	    {
+		if (pParserTempData->Index==0) pParserTempData->DestData32 <<= 2;
+		WriteReg32( pParserTempData);
+	    } else
+	    {
+		pParserTempData->IndirectData=pParserTempData->CurrentPortID+INDIRECT_IO_WRITE;
+		IndirectInputOutput(pParserTempData);
+	    }
+	    break;
+	case PCI_Port:
+	    WritePCIFunctions[pParserTempData->pCmd->Header.Attribute.SourceAlignment](pParserTempData);
+	    break;
+	case SystemIO_Port:
+	    WriteIOFunctions[pParserTempData->pCmd->Header.Attribute.SourceAlignment](pParserTempData);
+	    break;
+    }
+}
+
+VOID PutDataPS(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    *(pParserTempData->pDeviceData->pParameterSpace+pParserTempData->pCmd->Parameters.ByteXX.PA_Destination)=
+	pParserTempData->DestData32;
+}
+
+VOID PutDataWS(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    if (pParserTempData->pCmd->Parameters.ByteXX.PA_Destination < WS_QUOTIENT_C)
+	*(pParserTempData->pWorkingTableData->pWorkSpace+pParserTempData->pCmd->Parameters.ByteXX.PA_Destination) = pParserTempData->DestData32;
+    else
+	switch (pParserTempData->pCmd->Parameters.ByteXX.PA_Destination)
+	{
+	    case WS_REMINDER_C:
+		pParserTempData->MultiplicationOrDivision.Division.Reminder32=pParserTempData->DestData32;
+		break;
+	    case WS_QUOTIENT_C:
+		pParserTempData->MultiplicationOrDivision.Division.Quotient32=pParserTempData->DestData32;
+		break;
+	    case WS_DATAPTR_C:
+#ifndef		UEFI_BUILD
+		pParserTempData->CurrentDataBlock=(UINT16)pParserTempData->DestData32;
+#else
+		pParserTempData->CurrentDataBlock=(UINTN)pParserTempData->DestData32;
+#endif
+		break;
+	    case WS_SHIFT_C:
+		pParserTempData->Shift2MaskConverter=(UINT8)pParserTempData->DestData32;
+		break;
+	    case WS_FB_WINDOW_C:
+		pParserTempData->CurrentFB_Window=pParserTempData->DestData32;
+		break;
+	    case WS_ATTRIBUTES_C:
+		pParserTempData->AttributesData=(UINT16)pParserTempData->DestData32;
+		break;
+	}
+
+}
+
+VOID PutDataFB(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->Index=(UINT32)pParserTempData->pCmd->Parameters.ByteXX.PA_Destination;
+    //Make an Index from address first, then add to the Index
+    pParserTempData->Index+=(pParserTempData->CurrentFB_Window>>2);
+    WriteFrameBuffer32(pParserTempData);
+}
+
+VOID PutDataPLL(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->Index=(UINT32)pParserTempData->pCmd->Parameters.ByteXX.PA_Destination;
+    WritePLL32( pParserTempData );
+}
+
+VOID PutDataMC(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->Index=(UINT32)pParserTempData->pCmd->Parameters.ByteXX.PA_Destination;
+    WriteMC32( pParserTempData );
+}
+
+
+VOID SkipParameters8(PARSER_TEMP_DATA STACK_BASED *	pParserTempData)
+{
+    pParserTempData->pWorkingTableData->IP+=sizeof(UINT8);
+}
+
+VOID SkipParameters16(PARSER_TEMP_DATA STACK_BASED *	pParserTempData)
+{
+    pParserTempData->pWorkingTableData->IP+=sizeof(UINT16);
+}
+
+
+UINT32 GetParametersRegister(PARSER_TEMP_DATA STACK_BASED *	pParserTempData)
+{
+    pParserTempData->Index=*(UINT16*)pParserTempData->pWorkingTableData->IP;
+    pParserTempData->pWorkingTableData->IP+=sizeof(UINT16);
+    pParserTempData->Index+=pParserTempData->CurrentRegBlock;
+    switch(pParserTempData->Multipurpose.CurrentPort)
+    {
+	case PCI_Port:
+	    return ReadPCIFunctions[pParserTempData->pCmd->Header.Attribute.SourceAlignment](pParserTempData);
+	case SystemIO_Port:
+	    return ReadIOFunctions[pParserTempData->pCmd->Header.Attribute.SourceAlignment](pParserTempData);
+	case ATI_RegsPort:
+	default:
+	    if (pParserTempData->CurrentPortID == INDIRECT_IO_MM) return ReadReg32( pParserTempData );
+	    else
+	    {
+		pParserTempData->IndirectData=pParserTempData->CurrentPortID+INDIRECT_IO_READ;
+		return IndirectInputOutput(pParserTempData);
+	    }
+    }
+}
+
+UINT32 GetParametersPS(PARSER_TEMP_DATA STACK_BASED *	pParserTempData)
+{
+    pParserTempData->Index=*pParserTempData->pWorkingTableData->IP;
+    pParserTempData->pWorkingTableData->IP+=sizeof(UINT8);
+    return *(pParserTempData->pDeviceData->pParameterSpace+pParserTempData->Index);
+}
+
+UINT32 GetParametersWS(PARSER_TEMP_DATA STACK_BASED *	pParserTempData)
+{
+    pParserTempData->Index=*pParserTempData->pWorkingTableData->IP;
+    pParserTempData->pWorkingTableData->IP+=sizeof(UINT8);
+    if (pParserTempData->Index < WS_QUOTIENT_C)
+	return *(pParserTempData->pWorkingTableData->pWorkSpace+pParserTempData->Index);
+    else
+	switch (pParserTempData->Index)
+	{
+	    case WS_REMINDER_C:
+		return pParserTempData->MultiplicationOrDivision.Division.Reminder32;
+	    case WS_QUOTIENT_C:
+		return pParserTempData->MultiplicationOrDivision.Division.Quotient32;
+	    case WS_DATAPTR_C:
+		return (UINT32)pParserTempData->CurrentDataBlock;
+	    case WS_OR_MASK_C:
+		return ((UINT32)1) << pParserTempData->Shift2MaskConverter;
+	    case WS_AND_MASK_C:
+		return ~(((UINT32)1) << pParserTempData->Shift2MaskConverter);
+	    case WS_FB_WINDOW_C:
+		return pParserTempData->CurrentFB_Window;
+	    case WS_ATTRIBUTES_C:
+		return pParserTempData->AttributesData;
+	}
+    return 0;
+
+}
+
+UINT32 GetParametersFB(PARSER_TEMP_DATA STACK_BASED *	pParserTempData)
+{
+    pParserTempData->Index=*pParserTempData->pWorkingTableData->IP;
+    pParserTempData->pWorkingTableData->IP+=sizeof(UINT8);
+    pParserTempData->Index+=(pParserTempData->CurrentFB_Window>>2);
+    return ReadFrameBuffer32(pParserTempData);
+}
+
+UINT32 GetParametersPLL(PARSER_TEMP_DATA STACK_BASED *	pParserTempData)
+{
+    pParserTempData->Index=*pParserTempData->pWorkingTableData->IP;
+    pParserTempData->pWorkingTableData->IP+=sizeof(UINT8);
+    return ReadPLL32( pParserTempData );
+}
+
+UINT32 GetParametersMC(PARSER_TEMP_DATA STACK_BASED *	pParserTempData)
+{
+    pParserTempData->Index=*pParserTempData->pWorkingTableData->IP;
+    pParserTempData->pWorkingTableData->IP+=sizeof(UINT8);
+    return ReadMC32( pParserTempData );
+}
+
+
+UINT32 GetParametersIndirect(PARSER_TEMP_DATA STACK_BASED *	pParserTempData)
+{
+    pParserTempData->Index=*(UINT16*)pParserTempData->pWorkingTableData->IP;
+    pParserTempData->pWorkingTableData->IP+=sizeof(UINT16);
+    return *(UINT32*)(RELATIVE_TO_BIOS_IMAGE(pParserTempData->Index)+pParserTempData->CurrentDataBlock);
+}
+
+UINT32 GetParametersDirect8(PARSER_TEMP_DATA STACK_BASED *	pParserTempData)
+{
+    pParserTempData->CD_Mask.SrcAlignment=alignmentByte0;
+    pParserTempData->Index=*(UINT8*)pParserTempData->pWorkingTableData->IP;
+    pParserTempData->pWorkingTableData->IP+=sizeof(UINT8);
+    return pParserTempData->Index;
+}
+
+UINT32 GetParametersDirect16(PARSER_TEMP_DATA STACK_BASED *	pParserTempData)
+{
+    pParserTempData->CD_Mask.SrcAlignment=alignmentLowerWord;
+    pParserTempData->Index=*(UINT16*)pParserTempData->pWorkingTableData->IP;
+    pParserTempData->pWorkingTableData->IP+=sizeof(UINT16);
+    return pParserTempData->Index;
+}
+
+UINT32 GetParametersDirect32(PARSER_TEMP_DATA STACK_BASED *	pParserTempData)
+{
+    pParserTempData->CD_Mask.SrcAlignment=alignmentDword;
+    pParserTempData->Index=*(UINT32*)pParserTempData->pWorkingTableData->IP;
+    pParserTempData->pWorkingTableData->IP+=sizeof(UINT32);
+    return pParserTempData->Index;
+}
+
+
+UINT32 GetParametersDirect(PARSER_TEMP_DATA STACK_BASED *	pParserTempData)
+{
+    return GetParametersDirectArray[pParserTempData->pCmd->Header.Attribute.SourceAlignment](pParserTempData);
+}
+
+
+VOID CommonSourceDataTransformation(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->SourceData32 >>= SourceAlignmentShift[pParserTempData->CD_Mask.SrcAlignment];
+    pParserTempData->SourceData32 &=  AlignmentMask[pParserTempData->CD_Mask.SrcAlignment];
+    pParserTempData->SourceData32 <<= DestinationAlignmentShift[pParserTempData->CD_Mask.DestAlignment];
+}
+
+VOID CommonOperationDataTransformation(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->SourceData32 >>= SourceAlignmentShift[pParserTempData->CD_Mask.SrcAlignment];
+    pParserTempData->SourceData32 &= AlignmentMask[pParserTempData->CD_Mask.SrcAlignment];
+    pParserTempData->DestData32   >>= DestinationAlignmentShift[pParserTempData->CD_Mask.DestAlignment];
+    pParserTempData->DestData32   &= AlignmentMask[pParserTempData->CD_Mask.SrcAlignment];
+}
+
+VOID ProcessMove(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    if (pParserTempData->CD_Mask.SrcAlignment!=alignmentDword)
+    {
+	pParserTempData->DestData32=GetDestination[pParserTempData->ParametersType.Destination](pParserTempData);
+    } else
+    {
+	SkipDestination[pParserTempData->ParametersType.Destination](pParserTempData);
+    }
+    pParserTempData->SourceData32=GetSource[pParserTempData->ParametersType.Source](pParserTempData);
+
+    if (pParserTempData->CD_Mask.SrcAlignment!=alignmentDword)
+    {
+	pParserTempData->DestData32 &= ~(AlignmentMask[pParserTempData->CD_Mask.SrcAlignment] << DestinationAlignmentShift[pParserTempData->CD_Mask.DestAlignment]);
+	CommonSourceDataTransformation(pParserTempData);
+	pParserTempData->DestData32 |= pParserTempData->SourceData32;
+    } else
+    {
+	pParserTempData->DestData32=pParserTempData->SourceData32;
+    }
+    PutDataFunctions[pParserTempData->ParametersType.Destination](pParserTempData);
+}
+
+VOID ProcessMask(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+
+    pParserTempData->DestData32=GetDestination[pParserTempData->ParametersType.Destination](pParserTempData);
+    pParserTempData->SourceData32=GetParametersDirect(pParserTempData);
+    pParserTempData->Index=GetParametersDirect(pParserTempData);
+    pParserTempData->SourceData32 <<= DestinationAlignmentShift[pParserTempData->CD_Mask.DestAlignment];
+    pParserTempData->SourceData32 |= ~(AlignmentMask[pParserTempData->CD_Mask.SrcAlignment] << DestinationAlignmentShift[pParserTempData->CD_Mask.DestAlignment]);
+    pParserTempData->DestData32   &= pParserTempData->SourceData32;
+    pParserTempData->Index        &= AlignmentMask[pParserTempData->CD_Mask.SrcAlignment];
+    pParserTempData->Index        <<= DestinationAlignmentShift[pParserTempData->CD_Mask.DestAlignment];
+    pParserTempData->DestData32   |= pParserTempData->Index;
+    PutDataFunctions[pParserTempData->ParametersType.Destination](pParserTempData);
+}
+
+VOID ProcessAnd(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->DestData32=GetDestination[pParserTempData->ParametersType.Destination](pParserTempData);
+    pParserTempData->SourceData32=GetSource[pParserTempData->ParametersType.Source](pParserTempData);
+    pParserTempData->SourceData32 >>= SourceAlignmentShift[pParserTempData->CD_Mask.SrcAlignment];
+    pParserTempData->SourceData32 <<= DestinationAlignmentShift[pParserTempData->CD_Mask.DestAlignment];
+    pParserTempData->SourceData32 |= ~(AlignmentMask[pParserTempData->CD_Mask.SrcAlignment] << DestinationAlignmentShift[pParserTempData->CD_Mask.DestAlignment]);
+    pParserTempData->DestData32   &= pParserTempData->SourceData32;
+    PutDataFunctions[pParserTempData->ParametersType.Destination](pParserTempData);
+}
+
+VOID ProcessOr(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->DestData32=GetDestination[pParserTempData->ParametersType.Destination](pParserTempData);
+    pParserTempData->SourceData32=GetSource[pParserTempData->ParametersType.Source](pParserTempData);
+    CommonSourceDataTransformation(pParserTempData);
+    pParserTempData->DestData32 |= pParserTempData->SourceData32;
+    PutDataFunctions[pParserTempData->ParametersType.Destination](pParserTempData);
+}
+
+VOID ProcessXor(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->DestData32=GetDestination[pParserTempData->ParametersType.Destination](pParserTempData);
+    pParserTempData->SourceData32=GetSource[pParserTempData->ParametersType.Source](pParserTempData);
+    CommonSourceDataTransformation(pParserTempData);
+    pParserTempData->DestData32 ^= pParserTempData->SourceData32;
+    PutDataFunctions[pParserTempData->ParametersType.Destination](pParserTempData);
+}
+
+VOID ProcessShl(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->DestData32=GetDestination[pParserTempData->ParametersType.Destination](pParserTempData);
+    pParserTempData->SourceData32=GetSource[pParserTempData->ParametersType.Source](pParserTempData);
+    CommonSourceDataTransformation(pParserTempData);
+    pParserTempData->DestData32 <<= pParserTempData->SourceData32;
+    PutDataFunctions[pParserTempData->ParametersType.Destination](pParserTempData);
+}
+
+VOID ProcessShr(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->DestData32=GetDestination[pParserTempData->ParametersType.Destination](pParserTempData);
+    pParserTempData->SourceData32=GetSource[pParserTempData->ParametersType.Source](pParserTempData);
+    CommonSourceDataTransformation(pParserTempData);
+    pParserTempData->DestData32 >>= pParserTempData->SourceData32;
+    PutDataFunctions[pParserTempData->ParametersType.Destination](pParserTempData);
+}
+
+
+VOID ProcessADD(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->DestData32=GetDestination[pParserTempData->ParametersType.Destination](pParserTempData);
+    pParserTempData->SourceData32=GetSource[pParserTempData->ParametersType.Source](pParserTempData);
+    CommonSourceDataTransformation(pParserTempData);
+    pParserTempData->DestData32 += pParserTempData->SourceData32;
+    PutDataFunctions[pParserTempData->ParametersType.Destination](pParserTempData);
+}
+
+VOID ProcessSUB(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->DestData32=GetDestination[pParserTempData->ParametersType.Destination](pParserTempData);
+    pParserTempData->SourceData32=GetSource[pParserTempData->ParametersType.Source](pParserTempData);
+    CommonSourceDataTransformation(pParserTempData);
+    pParserTempData->DestData32 -= pParserTempData->SourceData32;
+    PutDataFunctions[pParserTempData->ParametersType.Destination](pParserTempData);
+}
+
+VOID ProcessMUL(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->DestData32=GetDestination[pParserTempData->ParametersType.Destination](pParserTempData);
+    pParserTempData->SourceData32=GetSource[pParserTempData->ParametersType.Source](pParserTempData);
+    CommonOperationDataTransformation(pParserTempData);
+    pParserTempData->MultiplicationOrDivision.Multiplication.Low32Bit=pParserTempData->DestData32 * pParserTempData->SourceData32;
+}
+
+VOID ProcessDIV(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->DestData32=GetDestination[pParserTempData->ParametersType.Destination](pParserTempData);
+    pParserTempData->SourceData32=GetSource[pParserTempData->ParametersType.Source](pParserTempData);
+
+    CommonOperationDataTransformation(pParserTempData);
+    pParserTempData->MultiplicationOrDivision.Division.Quotient32=
+	pParserTempData->DestData32 / pParserTempData->SourceData32;
+    pParserTempData->MultiplicationOrDivision.Division.Reminder32=
+	pParserTempData->DestData32 % pParserTempData->SourceData32;
+}
+
+
+VOID ProcessCompare(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->DestData32=GetDestination[pParserTempData->ParametersType.Destination](pParserTempData);
+    pParserTempData->SourceData32=GetSource[pParserTempData->ParametersType.Source](pParserTempData);
+
+    CommonOperationDataTransformation(pParserTempData);
+
+    // Here we just set flags based on evaluation
+    if (pParserTempData->DestData32==pParserTempData->SourceData32)
+	pParserTempData->CompareFlags = Equal;
+    else
+	pParserTempData->CompareFlags =
+	    (UINT8)((pParserTempData->DestData32<pParserTempData->SourceData32) ? Below : Above);
+
+}
+
+VOID ProcessClear(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->DestData32=GetDestination[pParserTempData->ParametersType.Destination](pParserTempData);
+    pParserTempData->DestData32 &= ~(AlignmentMask[pParserTempData->CD_Mask.SrcAlignment] << SourceAlignmentShift[pParserTempData->CD_Mask.SrcAlignment]);
+    PutDataFunctions[pParserTempData->ParametersType.Destination](pParserTempData);
+
+}
+
+VOID ProcessShift(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    UINT32 mask = AlignmentMask[pParserTempData->CD_Mask.SrcAlignment] << SourceAlignmentShift[pParserTempData->CD_Mask.SrcAlignment];
+    pParserTempData->DestData32=GetDestination[pParserTempData->ParametersType.Destination](pParserTempData);
+    pParserTempData->SourceData32=GetParametersDirect8(pParserTempData);
+
+    // save original value of the destination
+    pParserTempData->Index = pParserTempData->DestData32 & ~mask;
+    pParserTempData->DestData32 &= mask;
+
+    if (pParserTempData->pCmd->Header.Opcode < SHIFT_RIGHT_REG_OPCODE)
+	pParserTempData->DestData32 <<= pParserTempData->SourceData32; else
+	    pParserTempData->DestData32 >>= pParserTempData->SourceData32;
+
+    // Clear any bits shifted out of masked area...
+    pParserTempData->DestData32 &= mask;
+    // ... and restore the area outside of masked with original values
+    pParserTempData->DestData32 |= pParserTempData->Index;
+
+    // write data back
+    PutDataFunctions[pParserTempData->ParametersType.Destination](pParserTempData);
+}
+
+VOID ProcessTest(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->DestData32=GetDestination[pParserTempData->ParametersType.Destination](pParserTempData);
+    pParserTempData->SourceData32=GetSource[pParserTempData->ParametersType.Source](pParserTempData);
+    CommonOperationDataTransformation(pParserTempData);
+    pParserTempData->CompareFlags =
+	(UINT8)((pParserTempData->DestData32 & pParserTempData->SourceData32) ? NotEqual : Equal);
+
+}
+
+VOID ProcessSetFB_Base(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->SourceData32=GetSource[pParserTempData->ParametersType.Source](pParserTempData);
+    pParserTempData->SourceData32 >>= SourceAlignmentShift[pParserTempData->CD_Mask.SrcAlignment];
+    pParserTempData->SourceData32 &= AlignmentMask[pParserTempData->CD_Mask.SrcAlignment];
+    pParserTempData->CurrentFB_Window=pParserTempData->SourceData32;
+}
+
+VOID ProcessSwitch(PARSER_TEMP_DATA STACK_BASED * pParserTempData){
+    pParserTempData->SourceData32=GetSource[pParserTempData->ParametersType.Source](pParserTempData);
+    pParserTempData->SourceData32 >>= SourceAlignmentShift[pParserTempData->CD_Mask.SrcAlignment];
+    pParserTempData->SourceData32 &= AlignmentMask[pParserTempData->CD_Mask.SrcAlignment];
+    while ( *(UINT16*)pParserTempData->pWorkingTableData->IP != (((UINT16)NOP_OPCODE << 8)+NOP_OPCODE))
+    {
+	if (*pParserTempData->pWorkingTableData->IP == 'c')
+	{
+	    pParserTempData->pWorkingTableData->IP++;
+	    pParserTempData->DestData32=GetParametersDirect(pParserTempData);
+	    pParserTempData->Index=GetParametersDirect16(pParserTempData);
+	    if (pParserTempData->SourceData32 == pParserTempData->DestData32)
+	    {
+		pParserTempData->pWorkingTableData->IP= RELATIVE_TO_TABLE(pParserTempData->Index);
+		return;
+	    }
+	}
+    }
+    pParserTempData->pWorkingTableData->IP+=sizeof(UINT16);
+}
+
+
+VOID	cmdSetDataBlock(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    UINT8 value;
+    UINT16* pMasterDataTable;
+    value=((COMMAND_TYPE_1*)pParserTempData->pWorkingTableData->IP)->Parameters.ByteXX.PA_Destination;
+    if (value == 0) pParserTempData->CurrentDataBlock=0; else
+    {
+	if (value == DB_CURRENT_COMMAND_TABLE)
+        {
+	    pParserTempData->CurrentDataBlock= (UINT16)(pParserTempData->pWorkingTableData->pTableHead-pParserTempData->pDeviceData->pBIOS_Image);
+        } else
+	{
+	    pMasterDataTable = GetDataMasterTablePointer(pParserTempData->pDeviceData);
+	    pParserTempData->CurrentDataBlock= (TABLE_UNIT_TYPE)((PTABLE_UNIT_TYPE)pMasterDataTable)[value];
+	}
+    }
+    pParserTempData->pWorkingTableData->IP+=sizeof(COMMAND_TYPE_OPCODE_VALUE_BYTE);
+}
+
+VOID	cmdSet_ATI_Port(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->Multipurpose.CurrentPort=ATI_RegsPort;
+    pParserTempData->CurrentPortID = (UINT8)((COMMAND_TYPE_1*)pParserTempData->pWorkingTableData->IP)->Parameters.WordXX.PA_Destination;
+    pParserTempData->pWorkingTableData->IP+=sizeof(COMMAND_TYPE_OPCODE_OFFSET16);
+}
+
+VOID	cmdSet_Reg_Block(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->CurrentRegBlock = ((COMMAND_TYPE_1*)pParserTempData->pWorkingTableData->IP)->Parameters.WordXX.PA_Destination;
+    pParserTempData->pWorkingTableData->IP+=sizeof(COMMAND_TYPE_OPCODE_OFFSET16);
+}
+
+
+//Atavism!!! Review!!!
+VOID	cmdSet_X_Port(PARSER_TEMP_DATA STACK_BASED * pParserTempData){
+    pParserTempData->Multipurpose.CurrentPort=pParserTempData->ParametersType.Destination;
+    pParserTempData->pWorkingTableData->IP+=sizeof(COMMAND_TYPE_OPCODE_ONLY);
+
+}
+
+VOID	cmdDelay_Millisec(PARSER_TEMP_DATA STACK_BASED * pParserTempData){
+    pParserTempData->SourceData32 =
+	((COMMAND_TYPE_1*)pParserTempData->pWorkingTableData->IP)->Parameters.ByteXX.PA_Destination;
+    DelayMilliseconds(pParserTempData);
+    pParserTempData->pWorkingTableData->IP+=sizeof(COMMAND_TYPE_OPCODE_VALUE_BYTE);
+}
+VOID	cmdDelay_Microsec(PARSER_TEMP_DATA STACK_BASED * pParserTempData){
+    pParserTempData->SourceData32 =
+	((COMMAND_TYPE_1*)pParserTempData->pWorkingTableData->IP)->Parameters.ByteXX.PA_Destination;
+    DelayMicroseconds(pParserTempData);
+    pParserTempData->pWorkingTableData->IP+=sizeof(COMMAND_TYPE_OPCODE_VALUE_BYTE);
+}
+
+VOID ProcessPostChar(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->SourceData32 =
+	((COMMAND_TYPE_1*)pParserTempData->pWorkingTableData->IP)->Parameters.ByteXX.PA_Destination;
+    PostCharOutput(pParserTempData);
+    pParserTempData->pWorkingTableData->IP+=sizeof(COMMAND_TYPE_OPCODE_VALUE_BYTE);
+}
+
+VOID ProcessDebug(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->SourceData32 =
+	((COMMAND_TYPE_1*)pParserTempData->pWorkingTableData->IP)->Parameters.ByteXX.PA_Destination;
+    CallerDebugFunc(pParserTempData);
+    pParserTempData->pWorkingTableData->IP+=sizeof(COMMAND_TYPE_OPCODE_VALUE_BYTE);
+}
+
+
+VOID ProcessDS(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->pWorkingTableData->IP+=((COMMAND_TYPE_1*)pParserTempData->pWorkingTableData->IP)->Parameters.WordXX.PA_Destination+sizeof(COMMAND_TYPE_OPCODE_OFFSET16);
+}
+
+
+VOID	cmdCall_Table(PARSER_TEMP_DATA STACK_BASED * pParserTempData){
+    UINT16*	MasterTableOffset;
+    pParserTempData->pWorkingTableData->IP+=sizeof(COMMAND_TYPE_OPCODE_VALUE_BYTE);
+    MasterTableOffset = GetCommandMasterTablePointer(pParserTempData->pDeviceData);
+    if(((PTABLE_UNIT_TYPE)MasterTableOffset)[((COMMAND_TYPE_OPCODE_VALUE_BYTE*)pParserTempData->pCmd)->Value]!=0 )  // if the offset is not ZERO
+    {
+	pParserTempData->CommandSpecific.IndexInMasterTable=GetTrueIndexInMasterTable(pParserTempData,((COMMAND_TYPE_OPCODE_VALUE_BYTE*)pParserTempData->pCmd)->Value);
+	pParserTempData->Multipurpose.PS_SizeInDwordsUsedByCallingTable =
+	    (((ATOM_COMMON_ROM_COMMAND_TABLE_HEADER *)pParserTempData->pWorkingTableData->pTableHead)->TableAttribute.PS_SizeInBytes>>2);
+	pParserTempData->pDeviceData->pParameterSpace+=
+	    pParserTempData->Multipurpose.PS_SizeInDwordsUsedByCallingTable;
+	pParserTempData->Status=CD_CALL_TABLE;
+	pParserTempData->pCmd=(GENERIC_ATTRIBUTE_COMMAND*)MasterTableOffset;
+    }
+}
+
+
+VOID	cmdNOP_(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+}
+
+
+static VOID NotImplemented(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    pParserTempData->Status = CD_NOT_IMPLEMENTED;
+}
+
+
+VOID ProcessJump(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    if ((pParserTempData->ParametersType.Destination == NoCondition) ||
+	(pParserTempData->ParametersType.Destination == pParserTempData->CompareFlags ))
+    {
+
+	pParserTempData->pWorkingTableData->IP= RELATIVE_TO_TABLE(((COMMAND_TYPE_OPCODE_OFFSET16*)pParserTempData->pWorkingTableData->IP)->CD_Offset16);
+    } else
+    {
+	pParserTempData->pWorkingTableData->IP+=sizeof(COMMAND_TYPE_OPCODE_OFFSET16);
+    }
+}
+
+VOID ProcessJumpE(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    if ((pParserTempData->CompareFlags == Equal) ||
+	(pParserTempData->CompareFlags == pParserTempData->ParametersType.Destination))
+    {
+
+	pParserTempData->pWorkingTableData->IP= RELATIVE_TO_TABLE(((COMMAND_TYPE_OPCODE_OFFSET16*)pParserTempData->pWorkingTableData->IP)->CD_Offset16);
+    } else
+    {
+	pParserTempData->pWorkingTableData->IP+=sizeof(COMMAND_TYPE_OPCODE_OFFSET16);
+    }
+}
+
+VOID ProcessJumpNE(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+    if (pParserTempData->CompareFlags != Equal)
+    {
+
+	pParserTempData->pWorkingTableData->IP= RELATIVE_TO_TABLE(((COMMAND_TYPE_OPCODE_OFFSET16*)pParserTempData->pWorkingTableData->IP)->CD_Offset16);
+    } else
+    {
+	pParserTempData->pWorkingTableData->IP+=sizeof(COMMAND_TYPE_OPCODE_OFFSET16);
+    }
+}
+
+
+
+COMMANDS_PROPERTIES CallTable[] =
+{
+    { NULL, 0,0},
+    { ProcessMove,      destRegister,     sizeof(COMMAND_HEADER)},
+    { ProcessMove,      destParamSpace,   sizeof(COMMAND_HEADER)},
+    { ProcessMove,      destWorkSpace,    sizeof(COMMAND_HEADER)},
+    { ProcessMove,      destFrameBuffer,  sizeof(COMMAND_HEADER)},
+    { ProcessMove,      destPLL,          sizeof(COMMAND_HEADER)},
+    { ProcessMove,      destMC,           sizeof(COMMAND_HEADER)},
+    { ProcessAnd,       destRegister,     sizeof(COMMAND_HEADER)},
+    { ProcessAnd,       destParamSpace,   sizeof(COMMAND_HEADER)},
+    { ProcessAnd,       destWorkSpace,    sizeof(COMMAND_HEADER)},
+    { ProcessAnd,       destFrameBuffer,  sizeof(COMMAND_HEADER)},
+    { ProcessAnd,       destPLL,          sizeof(COMMAND_HEADER)},
+    { ProcessAnd,       destMC,           sizeof(COMMAND_HEADER)},
+    { ProcessOr,        destRegister,     sizeof(COMMAND_HEADER)},
+    { ProcessOr,        destParamSpace,   sizeof(COMMAND_HEADER)},
+    { ProcessOr,        destWorkSpace,    sizeof(COMMAND_HEADER)},
+    { ProcessOr,        destFrameBuffer,  sizeof(COMMAND_HEADER)},
+    { ProcessOr,        destPLL,          sizeof(COMMAND_HEADER)},
+    { ProcessOr,        destMC,           sizeof(COMMAND_HEADER)},
+    { ProcessShift,     destRegister,     sizeof(COMMAND_HEADER)},
+    { ProcessShift,     destParamSpace,   sizeof(COMMAND_HEADER)},
+    { ProcessShift,     destWorkSpace,    sizeof(COMMAND_HEADER)},
+    { ProcessShift,     destFrameBuffer,  sizeof(COMMAND_HEADER)},
+    { ProcessShift,     destPLL,          sizeof(COMMAND_HEADER)},
+    { ProcessShift,     destMC,           sizeof(COMMAND_HEADER)},
+    { ProcessShift,     destRegister,     sizeof(COMMAND_HEADER)},
+    { ProcessShift,     destParamSpace,   sizeof(COMMAND_HEADER)},
+    { ProcessShift,     destWorkSpace,    sizeof(COMMAND_HEADER)},
+    { ProcessShift,     destFrameBuffer,  sizeof(COMMAND_HEADER)},
+    { ProcessShift,     destPLL,          sizeof(COMMAND_HEADER)},
+    { ProcessShift,     destMC,           sizeof(COMMAND_HEADER)},
+    { ProcessMUL,       destRegister,     sizeof(COMMAND_HEADER)},
+    { ProcessMUL,       destParamSpace,   sizeof(COMMAND_HEADER)},
+    { ProcessMUL,       destWorkSpace,    sizeof(COMMAND_HEADER)},
+    { ProcessMUL,       destFrameBuffer,  sizeof(COMMAND_HEADER)},
+    { ProcessMUL,       destPLL,          sizeof(COMMAND_HEADER)},
+    { ProcessMUL,       destMC,           sizeof(COMMAND_HEADER)},
+    { ProcessDIV,       destRegister,     sizeof(COMMAND_HEADER)},
+    { ProcessDIV,       destParamSpace,   sizeof(COMMAND_HEADER)},
+    { ProcessDIV,       destWorkSpace,    sizeof(COMMAND_HEADER)},
+    { ProcessDIV,       destFrameBuffer,  sizeof(COMMAND_HEADER)},
+    { ProcessDIV,       destPLL,          sizeof(COMMAND_HEADER)},
+    { ProcessDIV,       destMC,           sizeof(COMMAND_HEADER)},
+    { ProcessADD,       destRegister,     sizeof(COMMAND_HEADER)},
+    { ProcessADD,       destParamSpace,   sizeof(COMMAND_HEADER)},
+    { ProcessADD,       destWorkSpace,    sizeof(COMMAND_HEADER)},
+    { ProcessADD,       destFrameBuffer,  sizeof(COMMAND_HEADER)},
+    { ProcessADD,       destPLL,          sizeof(COMMAND_HEADER)},
+    { ProcessADD,       destMC,           sizeof(COMMAND_HEADER)},
+    { ProcessSUB,       destRegister,     sizeof(COMMAND_HEADER)},
+    { ProcessSUB,       destParamSpace,   sizeof(COMMAND_HEADER)},
+    { ProcessSUB,       destWorkSpace,    sizeof(COMMAND_HEADER)},
+    { ProcessSUB,       destFrameBuffer,  sizeof(COMMAND_HEADER)},
+    { ProcessSUB,       destPLL,          sizeof(COMMAND_HEADER)},
+    { ProcessSUB,       destMC,           sizeof(COMMAND_HEADER)},
+    { cmdSet_ATI_Port,  ATI_RegsPort,     0},
+    { cmdSet_X_Port,    PCI_Port,         0},
+    { cmdSet_X_Port,    SystemIO_Port,    0},
+    { cmdSet_Reg_Block,	0,                0},
+    { ProcessSetFB_Base,0,                sizeof(COMMAND_HEADER)},
+    { ProcessCompare,   destRegister,     sizeof(COMMAND_HEADER)},
+    { ProcessCompare,   destParamSpace,   sizeof(COMMAND_HEADER)},
+    { ProcessCompare,   destWorkSpace,    sizeof(COMMAND_HEADER)},
+    { ProcessCompare,   destFrameBuffer,  sizeof(COMMAND_HEADER)},
+    { ProcessCompare,   destPLL,          sizeof(COMMAND_HEADER)},
+    { ProcessCompare,   destMC,           sizeof(COMMAND_HEADER)},
+    { ProcessSwitch,    0,              	sizeof(COMMAND_HEADER)},
+    { ProcessJump,			NoCondition,      0},
+    { ProcessJump,	    Equal,            0},
+    { ProcessJump,      Below,	          0},
+    { ProcessJump,      Above,	          0},
+    { ProcessJumpE,     Below,            0},
+    { ProcessJumpE,     Above,            0},
+    { ProcessJumpNE,		0,                0},
+    { ProcessTest,      destRegister,     sizeof(COMMAND_HEADER)},
+    { ProcessTest,      destParamSpace,   sizeof(COMMAND_HEADER)},
+    { ProcessTest,      destWorkSpace,    sizeof(COMMAND_HEADER)},
+    { ProcessTest,      destFrameBuffer,  sizeof(COMMAND_HEADER)},
+    { ProcessTest,      destPLL,          sizeof(COMMAND_HEADER)},
+    { ProcessTest,      destMC,           sizeof(COMMAND_HEADER)},
+    { cmdDelay_Millisec,0,                0},
+    { cmdDelay_Microsec,0,                0},
+    { cmdCall_Table,		0,                0},
+    /*cmdRepeat*/	    { NotImplemented,   0,                0},
+    { ProcessClear,     destRegister,     sizeof(COMMAND_HEADER)},
+    { ProcessClear,     destParamSpace,   sizeof(COMMAND_HEADER)},
+    { ProcessClear,     destWorkSpace,    sizeof(COMMAND_HEADER)},
+    { ProcessClear,     destFrameBuffer,  sizeof(COMMAND_HEADER)},
+    { ProcessClear,     destPLL,          sizeof(COMMAND_HEADER)},
+    { ProcessClear,     destMC,           sizeof(COMMAND_HEADER)},
+    { cmdNOP_,		      0,                sizeof(COMMAND_TYPE_OPCODE_ONLY)},
+    /*cmdEOT*/        { cmdNOP_,		      0,                sizeof(COMMAND_TYPE_OPCODE_ONLY)},
+    { ProcessMask,      destRegister,     sizeof(COMMAND_HEADER)},
+    { ProcessMask,      destParamSpace,   sizeof(COMMAND_HEADER)},
+    { ProcessMask,      destWorkSpace,    sizeof(COMMAND_HEADER)},
+    { ProcessMask,      destFrameBuffer,  sizeof(COMMAND_HEADER)},
+    { ProcessMask,      destPLL,          sizeof(COMMAND_HEADER)},
+    { ProcessMask,      destMC,           sizeof(COMMAND_HEADER)},
+    /*cmdPost_Card*/	{ ProcessPostChar,  0,                0},
+    /*cmdBeep*/		    { NotImplemented,   0,                0},
+    /*cmdSave_Reg*/	  { NotImplemented,   0,                0},
+    /*cmdRestore_Reg*/{ NotImplemented,   0,                0},
+    { cmdSetDataBlock,  0,                0},
+    { ProcessXor,        destRegister,     sizeof(COMMAND_HEADER)},
+    { ProcessXor,        destParamSpace,   sizeof(COMMAND_HEADER)},
+    { ProcessXor,        destWorkSpace,    sizeof(COMMAND_HEADER)},
+    { ProcessXor,        destFrameBuffer,  sizeof(COMMAND_HEADER)},
+    { ProcessXor,        destPLL,          sizeof(COMMAND_HEADER)},
+    { ProcessXor,        destMC,           sizeof(COMMAND_HEADER)},
+
+    { ProcessShl,        destRegister,     sizeof(COMMAND_HEADER)},
+    { ProcessShl,        destParamSpace,   sizeof(COMMAND_HEADER)},
+    { ProcessShl,        destWorkSpace,    sizeof(COMMAND_HEADER)},
+    { ProcessShl,        destFrameBuffer,  sizeof(COMMAND_HEADER)},
+    { ProcessShl,        destPLL,          sizeof(COMMAND_HEADER)},
+    { ProcessShl,        destMC,           sizeof(COMMAND_HEADER)},
+
+    { ProcessShr,        destRegister,     sizeof(COMMAND_HEADER)},
+    { ProcessShr,        destParamSpace,   sizeof(COMMAND_HEADER)},
+    { ProcessShr,        destWorkSpace,    sizeof(COMMAND_HEADER)},
+    { ProcessShr,        destFrameBuffer,  sizeof(COMMAND_HEADER)},
+    { ProcessShr,        destPLL,          sizeof(COMMAND_HEADER)},
+    { ProcessShr,        destMC,           sizeof(COMMAND_HEADER)},
+    /*cmdDebug*/		{ ProcessDebug,  0,                0},
+    { ProcessDS,  0,                0},
+
+};
+
+// EOF
diff --git a/src/AtomBios/Decoder.c b/src/AtomBios/Decoder.c
new file mode 100644
index 0000000..cdaa9ef
--- /dev/null
+++ b/src/AtomBios/Decoder.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2006-2007 Advanced Micro Devices, Inc.  
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+
+Module Name:
+
+    Decoder.c
+    
+Abstract:
+
+		Commands Decoder
+
+Revision History:
+
+	NEG:24.09.2002	Initiated.
+--*/
+//#include "AtomBios.h"
+#include "Decoder.h"
+#include "atombios.h"
+#include "CD_binding.h"
+#include "CD_Common_Types.h"
+
+#ifndef DISABLE_EASF
+	#include "easf.h"
+#endif
+
+
+
+#define INDIRECT_IO_TABLE (((UINT16)(ULONG_PTR)&((ATOM_MASTER_LIST_OF_DATA_TABLES*)0)->IndirectIOAccess)/sizeof(TABLE_UNIT_TYPE) )
+extern COMMANDS_PROPERTIES CallTable[];
+
+
+UINT8 ProcessCommandProperties(PARSER_TEMP_DATA STACK_BASED *	pParserTempData)
+{
+  UINT8 opcode=((COMMAND_HEADER*)pParserTempData->pWorkingTableData->IP)->Opcode;
+  pParserTempData->pWorkingTableData->IP+=CallTable[opcode].headersize;
+  pParserTempData->ParametersType.Destination=CallTable[opcode].destination;
+  pParserTempData->ParametersType.Source = pParserTempData->pCmd->Header.Attribute.Source;
+  pParserTempData->CD_Mask.SrcAlignment=pParserTempData->pCmd->Header.Attribute.SourceAlignment;
+  pParserTempData->CD_Mask.DestAlignment=pParserTempData->pCmd->Header.Attribute.DestinationAlignment;
+  return opcode;
+}
+
+UINT16* GetCommandMasterTablePointer(DEVICE_DATA STACK_BASED*  pDeviceData)
+{
+	UINT16		*MasterTableOffset;
+#ifndef DISABLE_EASF
+	if (pDeviceData->format == TABLE_FORMAT_EASF)
+	{
+    /*
+    make MasterTableOffset point to EASF_ASIC_SETUP_TABLE structure, including usSize.
+    */
+		MasterTableOffset = (UINT16 *) (pDeviceData->pBIOS_Image+((EASF_ASIC_DESCRIPTOR*)pDeviceData->pBIOS_Image)->usAsicSetupTable_Offset);
+	} else
+#endif
+	{
+#ifndef		UEFI_BUILD
+		MasterTableOffset = (UINT16 *)(*(UINT16 *)(pDeviceData->pBIOS_Image+OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER) + pDeviceData->pBIOS_Image);
+		MasterTableOffset = (UINT16 *)((ULONG)((ATOM_ROM_HEADER *)MasterTableOffset)->usMasterCommandTableOffset + pDeviceData->pBIOS_Image );
+		MasterTableOffset =(UINT16 *) &(((ATOM_MASTER_COMMAND_TABLE *)MasterTableOffset)->ListOfCommandTables);
+#else
+	MasterTableOffset = (UINT16 *)(&(GetCommandMasterTable( )->ListOfCommandTables));
+#endif
+	}
+	return MasterTableOffset;
+}
+
+UINT16* GetDataMasterTablePointer(DEVICE_DATA STACK_BASED*  pDeviceData)
+{
+	UINT16		*MasterTableOffset;
+	
+#ifndef		UEFI_BUILD
+	MasterTableOffset = (UINT16 *)(*(UINT16 *)(pDeviceData->pBIOS_Image+OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER) + pDeviceData->pBIOS_Image);
+	MasterTableOffset = (UINT16 *)((ULONG)((ATOM_ROM_HEADER *)MasterTableOffset)->usMasterDataTableOffset + pDeviceData->pBIOS_Image );
+	MasterTableOffset =(UINT16 *) &(((ATOM_MASTER_DATA_TABLE *)MasterTableOffset)->ListOfDataTables);
+#else
+	MasterTableOffset = (UINT16 *)(&(GetDataMasterTable( )->ListOfDataTables));
+#endif
+	return MasterTableOffset;
+}
+
+
+UINT8 GetTrueIndexInMasterTable(PARSER_TEMP_DATA STACK_BASED * pParserTempData, UINT8 IndexInMasterTable)
+{
+#ifndef DISABLE_EASF
+	UINT16 i;
+	if ( pParserTempData->pDeviceData->format == TABLE_FORMAT_EASF)
+	{
+/*
+		Consider EASF_ASIC_SETUP_TABLE structure pointed by pParserTempData->pCmd as UINT16[]
+		((UINT16*)pParserTempData->pCmd)[0] = EASF_ASIC_SETUP_TABLE.usSize;
+		((UINT16*)pParserTempData->pCmd)[1+n*4] = usFunctionID;
+		usFunctionID has to be shifted left by 2 before compare it to the value provided by caller.
+*/
+		for (i=1; (i < ((UINT16*)pParserTempData->pCmd)[0] >> 1);i+=4)
+	  		if ((UINT8)(((UINT16*)pParserTempData->pCmd)[i] << 2)==(IndexInMasterTable & EASF_TABLE_INDEX_MASK)) return (i+1+(IndexInMasterTable & EASF_TABLE_ATTR_MASK));
+		return 1;
+	} else
+#endif
+	{
+		return IndexInMasterTable;
+	}
+}
+
+CD_STATUS ParseTable(DEVICE_DATA STACK_BASED* pDeviceData, UINT8 IndexInMasterTable)
+{
+	PARSER_TEMP_DATA	ParserTempData;
+  WORKING_TABLE_DATA STACK_BASED* prevWorkingTableData;
+
+  ParserTempData.pDeviceData=(DEVICE_DATA*)pDeviceData;
+#ifndef DISABLE_EASF
+  if (pDeviceData->format == TABLE_FORMAT_EASF)
+  {
+      ParserTempData.IndirectIOTablePointer = 0;
+  } else
+#endif
+  {
+    ParserTempData.pCmd=(GENERIC_ATTRIBUTE_COMMAND*)GetDataMasterTablePointer(pDeviceData);
+    ParserTempData.IndirectIOTablePointer=(UINT8*)((ULONG)(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[INDIRECT_IO_TABLE]) + pDeviceData->pBIOS_Image);
+    ParserTempData.IndirectIOTablePointer+=sizeof(ATOM_COMMON_TABLE_HEADER);
+  }
+
+	ParserTempData.pCmd=(GENERIC_ATTRIBUTE_COMMAND*)GetCommandMasterTablePointer(pDeviceData);
+    IndexInMasterTable=GetTrueIndexInMasterTable((PARSER_TEMP_DATA STACK_BASED *)&ParserTempData,IndexInMasterTable);
+	if(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]!=0 )  // if the offset is not ZERO
+	{
+		ParserTempData.CommandSpecific.IndexInMasterTable=IndexInMasterTable;
+		ParserTempData.Multipurpose.CurrentPort=ATI_RegsPort;
+		ParserTempData.CurrentPortID=INDIRECT_IO_MM;
+		ParserTempData.CurrentRegBlock=0;
+		ParserTempData.CurrentFB_Window=0;
+    prevWorkingTableData=NULL;
+		ParserTempData.Status=CD_CALL_TABLE;
+
+		do{
+
+			if (ParserTempData.Status==CD_CALL_TABLE)
+      {
+				IndexInMasterTable=ParserTempData.CommandSpecific.IndexInMasterTable;
+				if(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]!=0)  // if the offset is not ZERO
+					{
+#ifndef		UEFI_BUILD
+  					ParserTempData.pWorkingTableData =(WORKING_TABLE_DATA STACK_BASED*) AllocateWorkSpace(pDeviceData,
+								((ATOM_COMMON_ROM_COMMAND_TABLE_HEADER*)(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]+pDeviceData->pBIOS_Image))->TableAttribute.WS_SizeInBytes+sizeof(WORKING_TABLE_DATA));
+#else
+  					ParserTempData.pWorkingTableData =(WORKING_TABLE_DATA STACK_BASED*) AllocateWorkSpace(pDeviceData,
+								((ATOM_COMMON_ROM_COMMAND_TABLE_HEADER*)(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]))->TableAttribute.WS_SizeInBytes+sizeof(WORKING_TABLE_DATA));
+#endif
+            if (ParserTempData.pWorkingTableData!=NULL)
+            {
+						  ParserTempData.pWorkingTableData->pWorkSpace=(WORKSPACE_POINTER STACK_BASED*)((UINT8*)ParserTempData.pWorkingTableData+sizeof(WORKING_TABLE_DATA));
+#ifndef		UEFI_BUILD
+						  ParserTempData.pWorkingTableData->pTableHead  = (UINT8 *)(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]+pDeviceData->pBIOS_Image);
+#else
+						  ParserTempData.pWorkingTableData->pTableHead  = (UINT8 *)(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]);
+#endif
+	 					  ParserTempData.pWorkingTableData->IP=((UINT8*)ParserTempData.pWorkingTableData->pTableHead)+sizeof(ATOM_COMMON_ROM_COMMAND_TABLE_HEADER);
+              ParserTempData.pWorkingTableData->prevWorkingTableData=prevWorkingTableData;
+              prevWorkingTableData=ParserTempData.pWorkingTableData;
+              ParserTempData.Status = CD_SUCCESS;
+            } else ParserTempData.Status = CD_UNEXPECTED_BEHAVIOR;
+					} else ParserTempData.Status = CD_EXEC_TABLE_NOT_FOUND;
+			}
+			if (!CD_ERROR(ParserTempData.Status))
+			{
+        ParserTempData.Status = CD_SUCCESS;
+				while (!CD_ERROR_OR_COMPLETED(ParserTempData.Status))  
+        {
+
+					if (IS_COMMAND_VALID(((COMMAND_HEADER*)ParserTempData.pWorkingTableData->IP)->Opcode))
+          {
+						ParserTempData.pCmd = (GENERIC_ATTRIBUTE_COMMAND*)ParserTempData.pWorkingTableData->IP;
+
+						if (IS_END_OF_TABLE(((COMMAND_HEADER*)ParserTempData.pWorkingTableData->IP)->Opcode))
+						{
+							ParserTempData.Status=CD_COMPLETED;
+              prevWorkingTableData=ParserTempData.pWorkingTableData->prevWorkingTableData;
+
+							FreeWorkSpace(pDeviceData, ParserTempData.pWorkingTableData);
+              ParserTempData.pWorkingTableData=prevWorkingTableData;
+              if (prevWorkingTableData!=NULL)
+              {
+							  ParserTempData.pDeviceData->pParameterSpace-=
+								  		(((ATOM_COMMON_ROM_COMMAND_TABLE_HEADER*)ParserTempData.pWorkingTableData->
+									  		pTableHead)->TableAttribute.PS_SizeInBytes>>2);
+              } 
+						// if there is a parent table where to return, then restore PS_pointer to the original state
+						}
+						else
+						{
+              IndexInMasterTable=ProcessCommandProperties((PARSER_TEMP_DATA STACK_BASED *)&ParserTempData);
+							(*CallTable[IndexInMasterTable].function)((PARSER_TEMP_DATA STACK_BASED *)&ParserTempData);
+#if (PARSER_TYPE!=DRIVER_TYPE_PARSER)
+              BIOS_STACK_MODIFIER();
+#endif
+						}
+					}
+					else
+					{
+						ParserTempData.Status=CD_INVALID_OPCODE;
+						break;
+					}
+
+				}	// while
+			}	// if
+			else
+				break;
+		} while (prevWorkingTableData!=NULL);
+    if (ParserTempData.Status == CD_COMPLETED) return CD_SUCCESS;
+		return ParserTempData.Status;
+	} else return CD_SUCCESS;
+}
+
+// EOF
+
diff --git a/src/AtomBios/hwserv_drv.c b/src/AtomBios/hwserv_drv.c
new file mode 100644
index 0000000..a5f5a5b
--- /dev/null
+++ b/src/AtomBios/hwserv_drv.c
@@ -0,0 +1,348 @@
+/*
+ * Copyright 2006-2007 Advanced Micro Devices, Inc.  
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+
+Module Name:
+
+    hwserv_drv.c
+    
+Abstract:
+
+		Functions defined in the Command Decoder Specification document
+
+Revision History:
+
+	NEG:27.09.2002	Initiated.
+--*/
+#include "CD_binding.h"
+#include "CD_hw_services.h"
+
+//trace settings
+#if DEBUG_OUTPUT_DEVICE & 1
+	#define TRACE_USING_STDERR          //define it to use stderr as trace output,
+#endif
+#if DEBUG_OUTPUT_DEVICE & 2
+	#define TRACE_USING_RS232
+#endif
+#if DEBUG_OUTPUT_DEVICE & 4
+	#define TRACE_USING_LPT
+#endif
+
+
+#if DEBUG_PARSER == 4
+	#define IO_TRACE					//IO access trace switch, undefine it to turn off
+	#define PCI_TRACE					//PCI access trace switch, undefine it to turn off
+	#define MEM_TRACE					//MEM access trace switch, undefine it to turn off
+#endif
+
+UINT32 CailReadATIRegister(VOID*,UINT32);
+VOID   CailWriteATIRegister(VOID*,UINT32,UINT32);
+VOID*  CailAllocateMemory(VOID*,UINT16);
+VOID   CailReleaseMemory(VOID *,VOID *);
+VOID   CailDelayMicroSeconds(VOID *,UINT32 );
+VOID   CailReadPCIConfigData(VOID*,VOID*,UINT32,UINT16);
+VOID   CailWritePCIConfigData(VOID*,VOID*,UINT32,UINT16);
+UINT32 CailReadFBData(VOID*,UINT32);
+VOID   CailWriteFBData(VOID*,UINT32,UINT32);
+ULONG  CailReadPLL(VOID *Context ,ULONG Address);
+VOID   CailWritePLL(VOID *Context,ULONG Address,ULONG Data);
+ULONG  CailReadMC(VOID *Context ,ULONG Address);
+VOID   CailWriteMC(VOID *Context ,ULONG Address,ULONG Data);
+
+
+#if DEBUG_PARSER>0
+VOID   CailVideoDebugPrint(VOID*,ULONG_PTR, UINT16);
+#endif
+// Delay function
+#if ( defined ENABLE_PARSER_DELAY || defined ENABLE_ALL_SERVICE_FUNCTIONS )
+
+VOID	DelayMilliseconds(PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+	    CailDelayMicroSeconds(pWorkingTableData->pDeviceData->CAIL,pWorkingTableData->SourceData32*1000);
+}
+
+VOID	DelayMicroseconds(PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+	    CailDelayMicroSeconds(pWorkingTableData->pDeviceData->CAIL,pWorkingTableData->SourceData32);
+}
+#endif
+
+VOID	PostCharOutput(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+}
+
+VOID	CallerDebugFunc(PARSER_TEMP_DATA STACK_BASED * pParserTempData)
+{
+}
+
+
+// PCI READ Access
+
+#if ( defined ENABLE_PARSER_PCIREAD8 || defined ENABLE_ALL_SERVICE_FUNCTIONS )
+UINT8   ReadPCIReg8(PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+    UINT8 rvl;
+    CailReadPCIConfigData(pWorkingTableData->pDeviceData->CAIL,&rvl,pWorkingTableData->Index,sizeof(UINT8));
+	return rvl;
+}
+#endif
+
+
+#if ( defined ENABLE_PARSER_PCIREAD16 || defined ENABLE_ALL_SERVICE_FUNCTIONS )
+UINT16	ReadPCIReg16(PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+
+    UINT16 rvl;
+    CailReadPCIConfigData(pWorkingTableData->pDeviceData->CAIL,&rvl,pWorkingTableData->Index,sizeof(UINT16));
+    return rvl;
+
+}
+#endif
+
+
+
+#if ( defined ENABLE_PARSER_PCIREAD32 || defined ENABLE_ALL_SERVICE_FUNCTIONS )
+UINT32  ReadPCIReg32   (PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+
+    UINT32 rvl;
+    CailReadPCIConfigData(pWorkingTableData->pDeviceData->CAIL,&rvl,pWorkingTableData->Index,sizeof(UINT32));
+    return rvl;
+}
+#endif
+
+
+// PCI WRITE Access
+
+#if ( defined ENABLE_PARSER_PCIWRITE8 || defined ENABLE_ALL_SERVICE_FUNCTIONS )
+VOID	WritePCIReg8	(PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+
+    CailWritePCIConfigData(pWorkingTableData->pDeviceData->CAIL,&(pWorkingTableData->DestData32),pWorkingTableData->Index,sizeof(UINT8));
+
+}
+
+#endif
+
+
+#if ( defined ENABLE_PARSER_PCIWRITE16 || defined ENABLE_ALL_SERVICE_FUNCTIONS )
+VOID    WritePCIReg16  (PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+
+        CailWritePCIConfigData(pWorkingTableData->pDeviceData->CAIL,&(pWorkingTableData->DestData32),pWorkingTableData->Index,sizeof(UINT16));
+}
+
+#endif
+
+
+#if ( defined ENABLE_PARSER_PCIWRITE32 || defined ENABLE_ALL_SERVICE_FUNCTIONS )
+VOID    WritePCIReg32  (PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+    CailWritePCIConfigData(pWorkingTableData->pDeviceData->CAIL,&(pWorkingTableData->DestData32),pWorkingTableData->Index,sizeof(UINT32));
+}
+#endif
+
+
+
+
+// System IO Access
+#if ( defined ENABLE_PARSER_SYS_IOREAD8 || defined ENABLE_ALL_SERVICE_FUNCTIONS )
+UINT8   ReadSysIOReg8    (PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+    UINT8 rvl;
+    rvl=0;
+    //rvl= (UINT8) ReadGenericPciCfg(dev,reg,sizeof(UINT8));
+	return rvl;
+}
+#endif
+
+
+#if ( defined ENABLE_PARSER_SYS_IOREAD16 || defined ENABLE_ALL_SERVICE_FUNCTIONS )
+UINT16	ReadSysIOReg16(PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+
+    UINT16 rvl;
+    rvl=0;
+    //rvl= (UINT16) ReadGenericPciCfg(dev,reg,sizeof(UINT16));
+    return rvl;
+
+}
+#endif
+
+
+
+#if ( defined ENABLE_PARSER_SYS_IOREAD32 || defined ENABLE_ALL_SERVICE_FUNCTIONS )
+UINT32  ReadSysIOReg32   (PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+
+    UINT32 rvl;
+    rvl=0;
+    //rvl= (UINT32) ReadGenericPciCfg(dev,reg,sizeof(UINT32));
+    return rvl;
+}
+#endif
+
+
+// PCI WRITE Access
+
+#if ( defined ENABLE_PARSER_SYS_IOWRITE8 || defined ENABLE_ALL_SERVICE_FUNCTIONS )
+VOID	WriteSysIOReg8	(PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+
+    //WriteGenericPciCfg(dev,reg,sizeof(UINT8),(UINT32)value);
+}
+
+#endif
+
+
+#if ( defined ENABLE_PARSER_SYS_IOWRITE16 || defined ENABLE_ALL_SERVICE_FUNCTIONS )
+VOID    WriteSysIOReg16  (PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+
+    //WriteGenericPciCfg(dev,reg,sizeof(UINT16),(UINT32)value);
+}
+
+#endif
+
+
+#if ( defined ENABLE_PARSER_SYS_IOWRITE32 || defined ENABLE_ALL_SERVICE_FUNCTIONS )
+VOID    WriteSysIOReg32  (PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+    //WriteGenericPciCfg(dev,reg,sizeof(UINT32),(UINT32)value);
+}
+#endif
+
+// ATI Registers Memory Mapped Access
+
+#if ( defined ENABLE_PARSER_REGISTERS_MEMORY_ACCESS || defined ENABLE_ALL_SERVICE_FUNCTIONS)
+
+UINT32	ReadReg32 (PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+    return CailReadATIRegister(pWorkingTableData->pDeviceData->CAIL,pWorkingTableData->Index);
+}
+
+VOID	WriteReg32(PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+    CailWriteATIRegister(pWorkingTableData->pDeviceData->CAIL,(UINT16)pWorkingTableData->Index,pWorkingTableData->DestData32 );
+}
+
+
+VOID	ReadIndReg32 (PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+    pWorkingTableData->IndirectData = CailReadATIRegister(pWorkingTableData->pDeviceData->CAIL,*(UINT16*)(pWorkingTableData->IndirectIOTablePointer+1));
+}
+
+VOID	WriteIndReg32(PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+    CailWriteATIRegister(pWorkingTableData->pDeviceData->CAIL,*(UINT16*)(pWorkingTableData->IndirectIOTablePointer+1),pWorkingTableData->IndirectData );
+}
+
+#endif
+
+// ATI Registers IO Mapped Access
+
+#if ( defined ENABLE_PARSER_REGISTERS_IO_ACCESS || defined ENABLE_ALL_SERVICE_FUNCTIONS )
+UINT32	ReadRegIO (PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+    //return CailReadATIRegister(pWorkingTableData->pDeviceData->CAIL,pWorkingTableData->Index);
+    return 0;
+}
+VOID	WriteRegIO(PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+      //  return CailWriteATIRegister(pWorkingTableData->pDeviceData->CAIL,pWorkingTableData->Index,pWorkingTableData->DestData32 );
+}
+#endif
+
+// access to Frame buffer, dummy function, need more information to implement it  
+UINT32	ReadFrameBuffer32 (PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+    
+    return CailReadFBData(pWorkingTableData->pDeviceData->CAIL, (pWorkingTableData->Index <<2 ));
+
+}
+
+VOID	WriteFrameBuffer32(PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+    CailWriteFBData(pWorkingTableData->pDeviceData->CAIL,(pWorkingTableData->Index <<2), pWorkingTableData->DestData32);
+
+}
+
+
+VOID *AllocateMemory(DEVICE_DATA *pDeviceData , UINT16 MemSize)
+{
+    if(MemSize)
+        return(CailAllocateMemory(pDeviceData->CAIL,MemSize));
+    else
+        return NULL;
+}
+
+
+VOID ReleaseMemory(DEVICE_DATA *pDeviceData , WORKING_TABLE_DATA* pWorkingTableData)
+{
+    if( pWorkingTableData)
+        CailReleaseMemory(pDeviceData->CAIL, pWorkingTableData);
+}
+
+
+UINT32	ReadMC32(PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+    UINT32 ReadData;
+    ReadData=(UINT32)CailReadMC(pWorkingTableData->pDeviceData->CAIL,pWorkingTableData->Index);
+    return ReadData;
+}
+
+VOID	WriteMC32(PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+    CailWriteMC(pWorkingTableData->pDeviceData->CAIL,pWorkingTableData->Index,pWorkingTableData->DestData32);    
+}
+
+UINT32	ReadPLL32(PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+    UINT32 ReadData;
+    ReadData=(UINT32)CailReadPLL(pWorkingTableData->pDeviceData->CAIL,pWorkingTableData->Index);
+    return ReadData;
+
+}
+
+VOID	WritePLL32(PARSER_TEMP_DATA STACK_BASED * pWorkingTableData)
+{
+    CailWritePLL(pWorkingTableData->pDeviceData->CAIL,pWorkingTableData->Index,pWorkingTableData->DestData32);    
+
+}
+
+
+
+#if DEBUG_PARSER>0
+VOID CD_print_string	(DEVICE_DATA *pDeviceData, UINT8 *str)
+{
+    CailVideoDebugPrint( pDeviceData->CAIL, (ULONG_PTR) str, PARSER_STRINGS);
+}
+
+VOID CD_print_value	(DEVICE_DATA *pDeviceData, ULONG_PTR value, UINT16 value_type )
+{
+    CailVideoDebugPrint( pDeviceData->CAIL, (ULONG_PTR)value, value_type);
+}
+
+#endif
+
+// EOF
diff --git a/src/AtomBios/includes/CD_Common_Types.h b/src/AtomBios/includes/CD_Common_Types.h
new file mode 100644
index 0000000..44a0b35
--- /dev/null
+++ b/src/AtomBios/includes/CD_Common_Types.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2006-2007 Advanced Micro Devices, Inc.  
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*++
+
+Module Name:
+
+    CD_Common_Types.h
+    
+Abstract:
+
+		Defines common data types to use across platforms/SW components
+
+Revision History:
+
+	NEG:17.09.2002	Initiated.
+--*/
+#ifndef _COMMON_TYPES_H_
+	#define _COMMON_TYPES_H_
+
+    #ifndef LINUX
+	#if _MSC_EXTENSIONS 
+    
+    //
+    // use Microsoft* C complier dependent interger width types 
+    //
+	//    typedef unsigned __int64    uint64_t;
+	//    typedef __int64             int64_t;
+		typedef unsigned __int32    uint32_t;
+		typedef __int32             int32_t;
+#elif defined (__linux__) || defined (__NetBSD__) || defined(__sun) || defined(__OpenBSD__) || defined (__FreeBSD__)
+		typedef unsigned int uint32_t;
+		typedef int int32_t;
+	#else
+		typedef unsigned long	    uint32_t;
+		typedef signed long         int32_t;
+	#endif
+		typedef unsigned char       uint8_t;
+#if (defined(__sun) && defined(_CHAR_IS_SIGNED))
+		typedef char                int8_t;
+#else
+		typedef signed char         int8_t;
+#endif
+		typedef unsigned short      uint16_t;
+		typedef signed short        int16_t;
+	#endif
+#ifndef	UEFI_BUILD
+		typedef signed int			intn_t;
+		typedef unsigned int		uintn_t;
+#else
+#ifndef EFIX64
+		typedef signed int			intn_t;
+		typedef unsigned int		uintn_t;
+#endif
+#endif
+#ifndef FGL_LINUX
+#pragma warning ( disable : 4142 )
+#endif
+
+
+#ifndef VOID
+typedef void		VOID;
+#endif
+#ifndef	UEFI_BUILD
+	typedef intn_t		INTN;
+	typedef uintn_t		UINTN;
+#else
+#ifndef EFIX64
+	typedef intn_t		INTN;
+	typedef uintn_t		UINTN;
+#endif
+#endif
+#ifndef BOOLEAN
+typedef uint8_t		BOOLEAN;
+#endif
+#ifndef INT8
+typedef int8_t		INT8;
+#endif
+#ifndef UINT8
+typedef uint8_t		UINT8;
+#endif
+#ifndef INT16
+typedef int16_t		INT16;
+#endif
+#ifndef UINT16
+typedef uint16_t	UINT16;
+#endif
+#ifndef INT32
+typedef int32_t		INT32;
+#endif
+#ifndef UINT32
+typedef uint32_t	UINT32;
+#endif
+//typedef int64_t   INT64;
+//typedef uint64_t  UINT64;
+typedef uint8_t		CHAR8;
+typedef uint16_t	CHAR16;
+#ifndef USHORT
+typedef UINT16		USHORT;
+#endif
+#ifndef UCHAR
+typedef UINT8		UCHAR;
+#endif
+#ifndef ULONG
+typedef	UINT32		ULONG;
+#endif
+
+#ifndef _WIN64
+#ifndef ULONG_PTR
+typedef unsigned long ULONG_PTR;
+#endif // ULONG_PTR
+#endif // _WIN64
+
+//#define	FAR	__far
+#ifndef TRUE
+  #define TRUE  ((BOOLEAN) 1 == 1)
+#endif
+
+#ifndef FALSE
+  #define FALSE ((BOOLEAN) 0 == 1)
+#endif
+
+#ifndef NULL
+  #define NULL  ((VOID *) 0)
+#endif
+
+//typedef	UINTN		CD_STATUS;
+
+
+#ifndef FGL_LINUX
+#pragma warning ( default : 4142 )
+#endif
+#endif // _COMMON_TYPES_H_
+
+// EOF
diff --git a/src/AtomBios/includes/CD_Definitions.h b/src/AtomBios/includes/CD_Definitions.h
new file mode 100644
index 0000000..98fd495
--- /dev/null
+++ b/src/AtomBios/includes/CD_Definitions.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2006-2007 Advanced Micro Devices, Inc.  
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*++
+
+Module Name:
+
+CD_Definitions.h
+
+Abstract:
+
+Defines Script Language commands
+
+Revision History:
+
+NEG:27.08.2002	Initiated.
+--*/
+
+#include "CD_Structs.h"
+#ifndef _CD_DEFINITIONS_H
+#define _CD_DEFINITIONS_H_
+#ifdef DRIVER_PARSER
+VOID *AllocateMemory(VOID *, UINT16);
+VOID ReleaseMemory(DEVICE_DATA * , WORKING_TABLE_DATA* );
+#endif
+CD_STATUS ParseTable(DEVICE_DATA* pDeviceData, UINT8 IndexInMasterTable);
+//CD_STATUS CD_MainLoop(PARSER_TEMP_DATA_POINTER pParserTempData);
+CD_STATUS Main_Loop(DEVICE_DATA* pDeviceData,UINT16 *MasterTableOffset,UINT8 IndexInMasterTable);
+UINT16* GetCommandMasterTablePointer(DEVICE_DATA*  pDeviceData);
+#endif //CD_DEFINITIONS
diff --git a/src/AtomBios/includes/CD_Opcodes.h b/src/AtomBios/includes/CD_Opcodes.h
new file mode 100644
index 0000000..2f3bec5
--- /dev/null
+++ b/src/AtomBios/includes/CD_Opcodes.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2006-2007 Advanced Micro Devices, Inc.  
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*++
+
+Module Name:
+
+CD_OPCODEs.h
+
+Abstract:
+
+Defines Command Decoder OPCODEs
+
+Revision History:
+
+NEG:24.09.2002	Initiated.
+--*/
+#ifndef _CD_OPCODES_H_
+#define _CD_OPCODES_H_
+
+typedef enum _OPCODE {
+    Reserved_00= 0,				//	0	= 0x00
+    // MOVE_ group
+    MOVE_REG_OPCODE,			//	1	= 0x01
+    FirstValidCommand=MOVE_REG_OPCODE,
+    MOVE_PS_OPCODE,				//	2	= 0x02
+    MOVE_WS_OPCODE,				//	3	= 0x03
+    MOVE_FB_OPCODE,				//	4	= 0x04
+    MOVE_PLL_OPCODE,			//	5	= 0x05
+    MOVE_MC_OPCODE,				//	6	= 0x06
+    // Logic group
+    AND_REG_OPCODE,				//	7	= 0x07
+    AND_PS_OPCODE,				//	8	= 0x08
+    AND_WS_OPCODE,				//	9	= 0x09
+    AND_FB_OPCODE,				//	10	= 0x0A
+    AND_PLL_OPCODE,				//	11	= 0x0B
+    AND_MC_OPCODE,				//	12	= 0x0C
+    OR_REG_OPCODE,				//	13	= 0x0D
+    OR_PS_OPCODE,				//	14	= 0x0E
+    OR_WS_OPCODE,				//	15	= 0x0F
+    OR_FB_OPCODE,				//	16	= 0x10
+    OR_PLL_OPCODE,				//	17	= 0x11
+    OR_MC_OPCODE,				//	18	= 0x12
+    SHIFT_LEFT_REG_OPCODE,		//	19	= 0x13
+    SHIFT_LEFT_PS_OPCODE,		//	20	= 0x14
+    SHIFT_LEFT_WS_OPCODE,		//	21	= 0x15
+    SHIFT_LEFT_FB_OPCODE,		//	22	= 0x16
+    SHIFT_LEFT_PLL_OPCODE,		//	23	= 0x17
+    SHIFT_LEFT_MC_OPCODE,		//	24	= 0x18
+    SHIFT_RIGHT_REG_OPCODE,		//	25	= 0x19
+    SHIFT_RIGHT_PS_OPCODE,		//	26	= 0x1A
+    SHIFT_RIGHT_WS_OPCODE,		//	27	= 0x1B
+    SHIFT_RIGHT_FB_OPCODE,		//	28	= 0x1C
+    SHIFT_RIGHT_PLL_OPCODE,		//	29	= 0x1D
+    SHIFT_RIGHT_MC_OPCODE,		//	30	= 0x1E
+    // Arithmetic group
+    MUL_REG_OPCODE,				//	31	= 0x1F
+    MUL_PS_OPCODE,				//	32	= 0x20
+    MUL_WS_OPCODE,				//	33	= 0x21
+    MUL_FB_OPCODE,				//	34	= 0x22
+    MUL_PLL_OPCODE,				//	35	= 0x23
+    MUL_MC_OPCODE,				//	36	= 0x24
+    DIV_REG_OPCODE,				//	37	= 0x25
+    DIV_PS_OPCODE,				//	38	= 0x26
+    DIV_WS_OPCODE,				//	39	= 0x27
+    DIV_FB_OPCODE,				//	40	= 0x28
+    DIV_PLL_OPCODE,				//	41	= 0x29
+    DIV_MC_OPCODE,				//	42	= 0x2A
+    ADD_REG_OPCODE,				//	43	= 0x2B
+    ADD_PS_OPCODE,				//	44	= 0x2C
+    ADD_WS_OPCODE,				//	45	= 0x2D
+    ADD_FB_OPCODE,				//	46	= 0x2E
+    ADD_PLL_OPCODE,				//	47	= 0x2F
+    ADD_MC_OPCODE,				//	48	= 0x30
+    SUB_REG_OPCODE,				//	49	= 0x31
+    SUB_PS_OPCODE,				//	50	= 0x32
+    SUB_WS_OPCODE,				//	51	= 0x33
+    SUB_FB_OPCODE,				//	52	= 0x34
+    SUB_PLL_OPCODE,				//	53	= 0x35
+    SUB_MC_OPCODE,				//	54	= 0x36
+    // Control grouop
+    SET_ATI_PORT_OPCODE,		//	55	= 0x37
+    SET_PCI_PORT_OPCODE,		//	56	= 0x38
+    SET_SYS_IO_PORT_OPCODE,		//	57	= 0x39
+    SET_REG_BLOCK_OPCODE,		//	58	= 0x3A
+    SET_FB_BASE_OPCODE,			//	59	= 0x3B
+    COMPARE_REG_OPCODE,			//	60	= 0x3C
+    COMPARE_PS_OPCODE,			//	61	= 0x3D
+    COMPARE_WS_OPCODE,			//	62	= 0x3E
+    COMPARE_FB_OPCODE,			//	63	= 0x3F
+    COMPARE_PLL_OPCODE,			//	64	= 0x40
+    COMPARE_MC_OPCODE,			//	65	= 0x41
+    SWITCH_OPCODE,				//	66	= 0x42
+    JUMP__OPCODE,				//	67	= 0x43
+    JUMP_EQUAL_OPCODE,			//	68	= 0x44
+    JUMP_BELOW_OPCODE,			//	69	= 0x45
+    JUMP_ABOVE_OPCODE,			//	70	= 0x46
+    JUMP_BELOW_OR_EQUAL_OPCODE,	//	71	= 0x47
+    JUMP_ABOVE_OR_EQUAL_OPCODE,	//	72	= 0x48
+    JUMP_NOT_EQUAL_OPCODE,		//	73	= 0x49
+    TEST_REG_OPCODE,			//	74	= 0x4A
+    TEST_PS_OPCODE,				//	75	= 0x4B
+    TEST_WS_OPCODE,				//	76	= 0x4C
+    TEST_FB_OPCODE,				//	77	= 0x4D
+    TEST_PLL_OPCODE,			//	78	= 0x4E
+    TEST_MC_OPCODE,				//	79	= 0x4F
+    DELAY_MILLISEC_OPCODE,		//	80	= 0x50
+    DELAY_MICROSEC_OPCODE,		//	81	= 0x51
+    CALL_TABLE_OPCODE,			//	82	= 0x52
+    REPEAT_OPCODE,				//	83	= 0x53
+    //	Miscellaneous	group
+    CLEAR_REG_OPCODE,			//	84	= 0x54
+    CLEAR_PS_OPCODE,			//	85	= 0x55
+    CLEAR_WS_OPCODE,			//	86	= 0x56
+    CLEAR_FB_OPCODE,			//	87	= 0x57
+    CLEAR_PLL_OPCODE,			//	88	= 0x58
+    CLEAR_MC_OPCODE,			//	89	= 0x59
+    NOP_OPCODE,					//	90	= 0x5A
+    EOT_OPCODE,					//	91	= 0x5B
+    MASK_REG_OPCODE,			//	92	= 0x5C
+    MASK_PS_OPCODE,				//	93	= 0x5D
+    MASK_WS_OPCODE,				//	94	= 0x5E
+    MASK_FB_OPCODE,				//	95	= 0x5F
+    MASK_PLL_OPCODE,			//	96	= 0x60
+    MASK_MC_OPCODE,				//	97	= 0x61
+    // BIOS dedicated group
+    POST_CARD_OPCODE,			//	98	= 0x62
+    BEEP_OPCODE,				//	99	= 0x63
+    SAVE_REG_OPCODE,			//	100 = 0x64
+    RESTORE_REG_OPCODE,			//	101	= 0x65
+    SET_DATA_BLOCK_OPCODE,			//	102     = 0x66
+
+    XOR_REG_OPCODE,				//	103	= 0x67
+    XOR_PS_OPCODE,				//	104	= 0x68
+    XOR_WS_OPCODE,				//	105	= 0x69
+    XOR_FB_OPCODE,				//	106	= 0x6a
+    XOR_PLL_OPCODE,				//	107	= 0x6b
+    XOR_MC_OPCODE,				//	108	= 0x6c
+
+    SHL_REG_OPCODE,				//	109	= 0x6d
+    SHL_PS_OPCODE,				//	110	= 0x6e
+    SHL_WS_OPCODE,				//	111	= 0x6f
+    SHL_FB_OPCODE,				//	112	= 0x70
+    SHL_PLL_OPCODE,				//	113	= 0x71
+    SHL_MC_OPCODE,				//	114	= 0x72
+
+    SHR_REG_OPCODE,				//	115	= 0x73
+    SHR_PS_OPCODE,				//	116	= 0x74
+    SHR_WS_OPCODE,				//	117	= 0x75
+    SHR_FB_OPCODE,				//	118	= 0x76
+    SHR_PLL_OPCODE,				//	119	= 0x77
+    SHR_MC_OPCODE,				//	120	= 0x78
+
+    DEBUG_OPCODE,                           //	121	= 0x79
+    CTB_DS_OPCODE,                          //	122	= 0x7A
+
+    LastValidCommand = CTB_DS_OPCODE,
+    //	Extension specificaTOR
+    Extension	= 0x80,			//	128 = 0x80	// Next byte is an OPCODE as well
+    Reserved_FF = 255			//	255 = 0xFF
+}OPCODE;
+#endif		// _CD_OPCODES_H_
diff --git a/src/AtomBios/includes/CD_Structs.h b/src/AtomBios/includes/CD_Structs.h
new file mode 100644
index 0000000..c43f81d
--- /dev/null
+++ b/src/AtomBios/includes/CD_Structs.h
@@ -0,0 +1,464 @@
+/*
+ * Copyright 2006-2007 Advanced Micro Devices, Inc.  
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*++
+
+Module Name:
+
+CD_Struct.h
+
+Abstract:
+
+Defines Script Language commands
+
+Revision History:
+
+NEG:26.08.2002	Initiated.
+--*/
+
+#include "CD_binding.h"
+#ifndef _CD_STRUCTS_H_
+#define _CD_STRUCTS_H_
+
+#ifdef		UEFI_BUILD
+typedef	UINT16**	PTABLE_UNIT_TYPE;
+typedef	UINTN		TABLE_UNIT_TYPE;
+#else
+typedef	UINT16*		PTABLE_UNIT_TYPE;
+typedef	UINT16		TABLE_UNIT_TYPE;
+#endif
+
+#include <regsdef.h> //This important file is dynamically generated based on the ASIC!!!!
+
+#define PARSER_MAJOR_REVISION 5
+#define PARSER_MINOR_REVISION 0
+
+//#include "atombios.h"
+#if (PARSER_TYPE==DRIVER_TYPE_PARSER)
+#ifdef FGL_LINUX
+#pragma pack(push,1)
+#else
+#pragma pack(push)
+#pragma pack(1)
+#endif
+#endif
+
+#include "CD_Common_Types.h"
+#include "CD_Opcodes.h"
+typedef UINT16				WORK_SPACE_SIZE;
+typedef enum _CD_STATUS{
+    CD_SUCCESS,
+    CD_CALL_TABLE,
+    CD_COMPLETED=0x10,
+    CD_GENERAL_ERROR=0x80,
+    CD_INVALID_OPCODE,
+    CD_NOT_IMPLEMENTED,
+    CD_EXEC_TABLE_NOT_FOUND,
+    CD_EXEC_PARAMETER_ERROR,
+    CD_EXEC_PARSER_ERROR,
+    CD_INVALID_DESTINATION_TYPE,
+    CD_UNEXPECTED_BEHAVIOR,
+    CD_INVALID_SWITCH_OPERAND_SIZE
+}CD_STATUS;
+
+#define PARSER_STRINGS                  0
+#define PARSER_DEC                      1
+#define PARSER_HEX                      2
+
+#define DB_CURRENT_COMMAND_TABLE	0xFF
+
+#define TABLE_FORMAT_BIOS		0
+#define TABLE_FORMAT_EASF		1
+
+#define EASF_TABLE_INDEX_MASK		0xfc
+#define EASF_TABLE_ATTR_MASK		0x03
+
+#define CD_ERROR(a)    (((INTN) (a)) > CD_COMPLETED)
+#define CD_ERROR_OR_COMPLETED(a)    (((INTN) (a)) > CD_SUCCESS)
+
+
+#if (BIOS_PARSER==1)
+#ifdef _H2INC
+#define STACK_BASED
+#else
+extern __segment farstack;
+#define STACK_BASED __based(farstack)
+#endif
+#else
+#define STACK_BASED
+#endif
+
+typedef enum _COMPARE_FLAGS{
+    Below,
+    Equal,
+    Above,
+    NotEqual,
+    Overflow,
+    NoCondition
+}COMPARE_FLAGS;
+
+typedef UINT16 IO_BASE_ADDR;
+
+typedef struct _BUS_DEV_FUNC_PCI_ADDR{
+    UINT8   Register;
+    UINT8   Function;
+    UINT8   Device;
+    UINT8   Bus;
+} BUS_DEV_FUNC_PCI_ADDR;
+
+typedef struct _BUS_DEV_FUNC{
+    UINT8   Function : 3;
+    UINT8   Device   : 5;
+    UINT8   Bus;
+} BUS_DEV_FUNC;
+
+#ifndef	UEFI_BUILD
+typedef struct _PCI_CONFIG_ACCESS_CF8{
+    UINT32  Reg     : 8;
+    UINT32  Func    : 3;
+    UINT32  Dev     : 5;
+    UINT32  Bus     : 8;
+    UINT32  Reserved: 7;
+    UINT32  Enable  : 1;
+} PCI_CONFIG_ACCESS_CF8;
+#endif
+
+typedef enum _MEM_RESOURCE {
+    Stack_Resource,
+    FrameBuffer_Resource,
+    BIOS_Image_Resource
+}MEM_RESOURCE;
+
+typedef enum _PORTS{
+    ATI_RegsPort,
+    PCI_Port,
+    SystemIO_Port
+}PORTS;
+
+typedef enum _OPERAND_TYPE {
+    typeRegister,
+    typeParamSpace,
+    typeWorkSpace,
+    typeFrameBuffer,
+    typeIndirect,
+    typeDirect,
+    typePLL,
+    typeMC
+}OPERAND_TYPE;
+
+typedef enum _DESTINATION_OPERAND_TYPE {
+    destRegister,
+    destParamSpace,
+    destWorkSpace,
+    destFrameBuffer,
+    destPLL,
+    destMC
+}DESTINATION_OPERAND_TYPE;
+
+typedef enum _SOURCE_OPERAND_TYPE {
+    sourceRegister,
+    sourceParamSpace,
+    sourceWorkSpace,
+    sourceFrameBuffer,
+    sourceIndirect,
+    sourceDirect,
+    sourcePLL,
+    sourceMC
+}SOURCE_OPERAND_TYPE;
+
+typedef enum _ALIGNMENT_TYPE {
+    alignmentDword,
+    alignmentLowerWord,
+    alignmentMiddleWord,
+    alignmentUpperWord,
+    alignmentByte0,
+    alignmentByte1,
+    alignmentByte2,
+    alignmentByte3
+}ALIGNMENT_TYPE;
+
+
+#define INDIRECT_IO_READ    0
+#define INDIRECT_IO_WRITE   0x80
+#define INDIRECT_IO_MM      0
+#define INDIRECT_IO_PLL     1
+#define INDIRECT_IO_MC      2
+
+typedef struct _PARAMETERS_TYPE{
+    UINT8	Destination;
+    UINT8	Source;
+}PARAMETERS_TYPE;
+/* The following structures don't used to allocate any type of objects(variables).
+   they are serve the only purpose: Get proper access to data(commands), found in the tables*/
+typedef struct _PA_BYTE_BYTE{
+    UINT8		PA_Destination;
+    UINT8		PA_Source;
+    UINT8		PA_Padding[8];
+}PA_BYTE_BYTE;
+typedef struct _PA_BYTE_WORD{
+    UINT8		PA_Destination;
+    UINT16		PA_Source;
+    UINT8		PA_Padding[7];
+}PA_BYTE_WORD;
+typedef struct _PA_BYTE_DWORD{
+    UINT8		PA_Destination;
+    UINT32		PA_Source;
+    UINT8		PA_Padding[5];
+}PA_BYTE_DWORD;
+typedef struct _PA_WORD_BYTE{
+    UINT16		PA_Destination;
+    UINT8		PA_Source;
+    UINT8		PA_Padding[7];
+}PA_WORD_BYTE;
+typedef struct _PA_WORD_WORD{
+    UINT16		PA_Destination;
+    UINT16		PA_Source;
+    UINT8		PA_Padding[6];
+}PA_WORD_WORD;
+typedef struct _PA_WORD_DWORD{
+    UINT16		PA_Destination;
+    UINT32		PA_Source;
+    UINT8		PA_Padding[4];
+}PA_WORD_DWORD;
+typedef struct _PA_WORD_XX{
+    UINT16		PA_Destination;
+    UINT8		PA_Padding[8];
+}PA_WORD_XX;
+typedef struct _PA_BYTE_XX{
+    UINT8		PA_Destination;
+    UINT8		PA_Padding[9];
+}PA_BYTE_XX;
+/*The following 6 definitions used for Mask operation*/
+typedef struct _PA_BYTE_BYTE_BYTE{
+    UINT8		PA_Destination;
+    UINT8		PA_AndMaskByte;
+    UINT8		PA_OrMaskByte;
+    UINT8		PA_Padding[7];
+}PA_BYTE_BYTE_BYTE;
+typedef struct _PA_BYTE_WORD_WORD{
+    UINT8		PA_Destination;
+    UINT16		PA_AndMaskWord;
+    UINT16		PA_OrMaskWord;
+    UINT8		PA_Padding[5];
+}PA_BYTE_WORD_WORD;
+typedef struct _PA_BYTE_DWORD_DWORD{
+    UINT8		PA_Destination;
+    UINT32		PA_AndMaskDword;
+    UINT32		PA_OrMaskDword;
+    UINT8		PA_Padding;
+}PA_BYTE_DWORD_DWORD;
+typedef struct _PA_WORD_BYTE_BYTE{
+    UINT16		PA_Destination;
+    UINT8		PA_AndMaskByte;
+    UINT8		PA_OrMaskByte;
+    UINT8		PA_Padding[6];
+}PA_WORD_BYTE_BYTE;
+typedef struct _PA_WORD_WORD_WORD{
+    UINT16		PA_Destination;
+    UINT16		PA_AndMaskWord;
+    UINT16		PA_OrMaskWord;
+    UINT8		PA_Padding[4];
+}PA_WORD_WORD_WORD;
+typedef struct _PA_WORD_DWORD_DWORD{
+    UINT16		PA_Destination;
+    UINT32		PA_AndMaskDword;
+    UINT32		PA_OrMaskDword;
+}PA_WORD_DWORD_DWORD;
+
+
+typedef union _PARAMETER_ACCESS {
+    PA_BYTE_XX			ByteXX;
+    PA_BYTE_BYTE		ByteByte;
+    PA_BYTE_WORD		ByteWord;
+    PA_BYTE_DWORD		ByteDword;
+    PA_WORD_BYTE		WordByte;
+    PA_WORD_WORD		WordWord;
+    PA_WORD_DWORD		WordDword;
+    PA_WORD_XX			WordXX;
+/*The following 6 definitions used for Mask operation*/
+    PA_BYTE_BYTE_BYTE	ByteByteAndByteOr;
+    PA_BYTE_WORD_WORD	ByteWordAndWordOr;
+    PA_BYTE_DWORD_DWORD	ByteDwordAndDwordOr;
+    PA_WORD_BYTE_BYTE	WordByteAndByteOr;
+    PA_WORD_WORD_WORD	WordWordAndWordOr;
+    PA_WORD_DWORD_DWORD	WordDwordAndDwordOr;
+}PARAMETER_ACCESS;
+
+typedef	struct _COMMAND_ATTRIBUTE {
+    UINT8		Source:3;
+    UINT8		SourceAlignment:3;
+    UINT8		DestinationAlignment:2;
+}COMMAND_ATTRIBUTE;
+
+typedef struct _SOURCE_DESTINATION_ALIGNMENT{
+    UINT8					DestAlignment;
+    UINT8					SrcAlignment;
+}SOURCE_DESTINATION_ALIGNMENT;
+typedef struct _MULTIPLICATION_RESULT{
+    UINT32									Low32Bit;
+    UINT32									High32Bit;
+}MULTIPLICATION_RESULT;
+typedef struct _DIVISION_RESULT{
+    UINT32									Quotient32;
+    UINT32									Reminder32;
+}DIVISION_RESULT;
+typedef union _DIVISION_MULTIPLICATION_RESULT{
+    MULTIPLICATION_RESULT		Multiplication;
+    DIVISION_RESULT					Division;
+}DIVISION_MULTIPLICATION_RESULT;
+typedef struct _COMMAND_HEADER {
+    UINT8					Opcode;
+    COMMAND_ATTRIBUTE		Attribute;
+}COMMAND_HEADER;
+
+typedef struct _GENERIC_ATTRIBUTE_COMMAND{
+    COMMAND_HEADER			Header;
+    PARAMETER_ACCESS		Parameters;
+} GENERIC_ATTRIBUTE_COMMAND;
+
+typedef struct	_COMMAND_TYPE_1{
+    UINT8					Opcode;
+    PARAMETER_ACCESS		Parameters;
+} COMMAND_TYPE_1;
+
+typedef struct	_COMMAND_TYPE_OPCODE_OFFSET16{
+    UINT8					Opcode;
+    UINT16					CD_Offset16;
+} COMMAND_TYPE_OPCODE_OFFSET16;
+
+typedef struct	_COMMAND_TYPE_OPCODE_OFFSET32{
+    UINT8					Opcode;
+    UINT32					CD_Offset32;
+} COMMAND_TYPE_OPCODE_OFFSET32;
+
+typedef struct	_COMMAND_TYPE_OPCODE_VALUE_BYTE{
+    UINT8					Opcode;
+    UINT8					Value;
+} COMMAND_TYPE_OPCODE_VALUE_BYTE;
+
+typedef union  _COMMAND_SPECIFIC_UNION{
+    UINT8	ContinueSwitch;
+    UINT8	ControlOperandSourcePosition;
+    UINT8	IndexInMasterTable;
+} COMMAND_SPECIFIC_UNION;
+
+
+typedef struct _CD_GENERIC_BYTE{
+    UINT16					CommandType:3;
+    UINT16					CurrentParameterSize:3;
+    UINT16					CommandAccessType:3;
+    UINT16					CurrentPort:2;
+    UINT16					PS_SizeInDwordsUsedByCallingTable:5;
+}CD_GENERIC_BYTE;
+
+typedef UINT8	COMMAND_TYPE_OPCODE_ONLY;
+
+typedef UINT8  COMMAND_HEADER_POINTER;
+
+
+#if (PARSER_TYPE==BIOS_TYPE_PARSER)
+
+typedef struct _DEVICE_DATA	{
+    UINT32	STACK_BASED		*pParameterSpace;
+    UINT8									*pBIOS_Image;
+    UINT8							format;
+#if (IO_INTERFACE==PARSER_INTERFACE)
+    IO_BASE_ADDR					IOBase;
+#endif
+}  DEVICE_DATA;
+
+#else
+
+typedef struct _DEVICE_DATA	{
+    UINT32							*pParameterSpace;
+    VOID								*CAIL;
+    UINT8 							*pBIOS_Image;
+    UINT32							format;
+} DEVICE_DATA;
+
+#endif
+
+struct _PARSER_TEMP_DATA;
+typedef UINT32 WORKSPACE_POINTER;
+
+struct	_WORKING_TABLE_DATA{
+    UINT8																		* pTableHead;
+    COMMAND_HEADER_POINTER									* IP;			// Commands pointer
+    WORKSPACE_POINTER	STACK_BASED						* pWorkSpace;
+    struct _WORKING_TABLE_DATA STACK_BASED  * prevWorkingTableData;
+};
+
+
+
+typedef struct	_PARSER_TEMP_DATA{
+    DEVICE_DATA	STACK_BASED							*pDeviceData;
+    struct _WORKING_TABLE_DATA STACK_BASED		*pWorkingTableData;
+    UINT32															SourceData32;
+    UINT32															DestData32;
+    DIVISION_MULTIPLICATION_RESULT			MultiplicationOrDivision;
+    UINT32															Index;
+    UINT32					                    CurrentFB_Window;
+    UINT32					                    IndirectData;
+    UINT16															CurrentRegBlock;
+    TABLE_UNIT_TYPE													CurrentDataBlock;
+    UINT16                              AttributesData;
+//  UINT8                               *IndirectIOTable;
+    UINT8                               *IndirectIOTablePointer;
+    GENERIC_ATTRIBUTE_COMMAND						*pCmd;			//CurrentCommand;
+    SOURCE_DESTINATION_ALIGNMENT  			CD_Mask;
+    PARAMETERS_TYPE											ParametersType;
+    CD_GENERIC_BYTE											Multipurpose;
+    UINT8																CompareFlags;
+    COMMAND_SPECIFIC_UNION							CommandSpecific;
+    CD_STATUS														Status;
+    UINT8                               Shift2MaskConverter;
+    UINT8															  CurrentPortID;
+} PARSER_TEMP_DATA;
+
+
+typedef struct _WORKING_TABLE_DATA  WORKING_TABLE_DATA;
+
+
+
+typedef VOID (*COMMANDS_DECODER)(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+typedef VOID (*WRITE_IO_FUNCTION)(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+typedef UINT32 (*READ_IO_FUNCTION)(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+typedef UINT32 (*CD_GET_PARAMETERS)(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+typedef struct _COMMANDS_PROPERTIES
+{
+    COMMANDS_DECODER  function;
+    UINT8             destination;
+    UINT8             headersize;
+} COMMANDS_PROPERTIES;
+
+typedef struct _INDIRECT_IO_PARSER_COMMANDS
+{
+    COMMANDS_DECODER  func;
+    UINT8             csize;
+} INDIRECT_IO_PARSER_COMMANDS;
+
+#if (PARSER_TYPE==DRIVER_TYPE_PARSER)
+#pragma pack(pop)
+#endif
+
+#endif
diff --git a/src/AtomBios/includes/CD_binding.h b/src/AtomBios/includes/CD_binding.h
new file mode 100644
index 0000000..7b021d3
--- /dev/null
+++ b/src/AtomBios/includes/CD_binding.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2006-2007 Advanced Micro Devices, Inc.  
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef NT_BUILD
+#ifdef LH_BUILD
+#include <ntddk.h>
+#else
+#include <miniport.h>
+#endif // LH_BUILD
+#endif // NT_BUILD
+
+
+#if ((defined DBG) || (defined DEBUG))
+#define DEBUG_PARSER				1   // enable parser debug output
+#endif
+
+#define USE_SWITCH_COMMAND			1
+#define	DRIVER_TYPE_PARSER		0x48
+
+#define PARSER_TYPE DRIVER_TYPE_PARSER
+
+#define AllocateWorkSpace(x,y)      AllocateMemory(pDeviceData,y)
+#define FreeWorkSpace(x,y)          ReleaseMemory(x,y)
+
+#define RELATIVE_TO_BIOS_IMAGE( x ) ((ULONG_PTR)x + (ULONG_PTR)((DEVICE_DATA*)pParserTempData->pDeviceData->pBIOS_Image))
+#define RELATIVE_TO_TABLE( x )      (x + (UCHAR *)(pParserTempData->pWorkingTableData->pTableHead))
+
diff --git a/src/AtomBios/includes/CD_hw_services.h b/src/AtomBios/includes/CD_hw_services.h
new file mode 100644
index 0000000..529fde5
--- /dev/null
+++ b/src/AtomBios/includes/CD_hw_services.h
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2006-2007 Advanced Micro Devices, Inc.  
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _HW_SERVICES_INTERFACE_
+#define _HW_SERVICES_INTERFACE_
+
+#include	"CD_Common_Types.h"
+#include	"CD_Structs.h"
+
+
+// CD - from Command Decoder
+typedef	UINT16	CD_REG_INDEX;
+typedef	UINT8	CD_PCI_OFFSET;
+typedef	UINT16	CD_FB_OFFSET;
+typedef	UINT16	CD_SYS_IO_PORT;
+typedef	UINT8	CD_MEM_TYPE;
+typedef	UINT8	CD_MEM_SIZE;
+
+typedef VOID *	CD_VIRT_ADDR;
+typedef UINT32	CD_PHYS_ADDR;
+typedef UINT32	CD_IO_ADDR;
+
+/***********************ATI Registers access routines**************************/
+
+	VOID	ReadIndReg32(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	VOID	WriteIndReg32(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	UINT32	ReadReg32(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	VOID	WriteReg32(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	UINT32	ReadPLL32(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	VOID	WritePLL32(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	UINT32	ReadMC32(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	VOID	WriteMC32(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+/************************PCI Registers access routines*************************/
+
+	UINT8	ReadPCIReg8(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	UINT16	ReadPCIReg16(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	UINT32	ReadPCIReg32(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	VOID	WritePCIReg8(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	VOID	WritePCIReg16(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	VOID	WritePCIReg32(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+/***************************Frame buffer access routines************************/
+
+	UINT32  ReadFrameBuffer32(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	VOID	WriteFrameBuffer32(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+/******************System IO Registers access routines********************/
+
+	UINT8	ReadSysIOReg8(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	UINT16	ReadSysIOReg16(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	UINT32	ReadSysIOReg32(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	VOID	WriteSysIOReg8(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	VOID	WriteSysIOReg16(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	VOID	WriteSysIOReg32(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+/****************************Delay routines****************************************/
+
+	VOID	DelayMicroseconds(PARSER_TEMP_DATA STACK_BASED * pParserTempData); // take WORKING_TABLE_DATA->SourceData32 as a delay value
+
+	VOID	DelayMilliseconds(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	VOID	PostCharOutput(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+	VOID	CallerDebugFunc(PARSER_TEMP_DATA STACK_BASED * pParserTempData);
+
+
+//************************Tracing/Debugging routines and macroses******************/
+#define KEYPRESSED	-1
+
+#if (DEBUG_PARSER != 0)
+
+#ifdef DRIVER_PARSER
+
+VOID CD_print_string	(DEVICE_DATA STACK_BASED *pDeviceData, UINT8 *str);
+VOID CD_print_value	    (DEVICE_DATA STACK_BASED *pDeviceData, ULONG_PTR value, UINT16 value_type );
+
+// Level 1 : can use WorkingTableData or pDeviceData
+#define CD_TRACE_DL1(string)			CD_print_string(pDeviceData, string);
+#define CD_TRACETAB_DL1(string)			CD_TRACE_DL1("\n");CD_TRACE_DL1(string)
+#define CD_TRACEDEC_DL1(value)			CD_print_value( pDeviceData, (ULONG_PTR)value, PARSER_DEC);
+#define CD_TRACEHEX_DL1(value)			CD_print_value( pDeviceData, (ULONG_PTR)value, PARSER_HEX);
+
+// Level 2:can use pWorkingTableData
+#define CD_TRACE_DL2(string)			CD_print_string( pWorkingTableData->pParserTempData->pDeviceData, string);
+#define CD_TRACETAB_DL2(string)			CD_TRACE_DL2("\n");CD_TRACE_DL2(string)
+#define CD_TRACEDEC_DL2(value)			CD_print_value( pWorkingTableData->pParserTempData->pDeviceData, (ULONG_PTR)value, PARSER_DEC);
+#define CD_TRACEHEX_DL2(value)			CD_print_value( pWorkingTableData->pParserTempData->pDeviceData, (ULONG_PTR)value, PARSER_HEX);
+
+// Level 3:can use pWorkingTableData
+#define CD_TRACE_DL3(string)			CD_print_string( pWorkingTableData->pParserTempData->pDeviceData, string);
+#define CD_TRACETAB_DL3(string)			CD_TRACE_DL3("\n");CD_TRACE_DL3(string)
+#define CD_TRACEDEC_DL3(value)			CD_print_value( pWorkingTableData->pParserTempData->pDeviceData, value, PARSER_DEC);
+#define CD_TRACEHEX_DL3(value)			CD_print_value( pWorkingTableData->pParserTempData->pDeviceData, value, PARSER_HEX);
+
+#define CD_TRACE(string)
+#define CD_WAIT(what)
+#define CD_BREAKPOINT()
+
+#else
+
+
+VOID CD_assert	(UINT8 *file, INTN lineno);		//output file/line to debug console
+VOID CD_postcode(UINT8 value);					//output post code to debug console
+VOID CD_print	(UINT8 *str);					//output text to debug console
+VOID CD_print_dec(UINTN value);					//output value in decimal format to debug console
+VOID CD_print_hex(UINT32 value, UINT8 len);		//output value in hexadecimal format to debug console
+VOID CD_print_buf(UINT8 *p, UINTN len);			//output dump of memory to debug console
+VOID CD_wait(INT32 what);						//wait for KEYPRESSED=-1 or Delay value	expires
+VOID CD_breakpoint();							//insert int3 opcode or 0xF1 (for American Arium)
+
+#define CD_ASSERT(condition)			if(!(condition)) CD_assert(__FILE__, __LINE__)
+#define CD_POSTCODE(value)				CD_postcode(value)
+#define CD_TRACE(string)				CD_print(string)
+#define CD_TRACETAB(string)				CD_print(string)
+#define CD_TRACEDEC(value)				CD_print_dec( (UINTN)(value))
+#define CD_TRACEHEX(value)				CD_print_hex( (UINT32)(value), sizeof(value) )
+#define CD_TRACEBUF(pointer, len)		CD_print_buf( (UINT8 *)(pointer), (UINTN) len)
+#define CD_WAIT(what)					CD_wait((INT32)what)
+#define CD_BREAKPOINT()					CD_breakpoint()
+
+#if (DEBUG_PARSER == 4)
+#define CD_ASSERT_DL4(condition)		if(!(condition)) CD_assert(__FILE__, __LINE__)
+#define CD_POSTCODE_DL4(value)			CD_postcode(value)
+#define CD_TRACE_DL4(string)			CD_print(string)
+#define CD_TRACETAB_DL4(string)			CD_print("\n\t\t");CD_print(string)
+#define CD_TRACEDEC_DL4(value)			CD_print_dec( (UINTN)(value))
+#define CD_TRACEHEX_DL4(value)			CD_print_hex( (UINT32)(value), sizeof(value) )
+#define CD_TRACEBUF_DL4(pointer, len)	CD_print_buf( (UINT8 *)(pointer), (UINTN) len)
+#define CD_WAIT_DL4(what)				CD_wait((INT32)what)
+#define CD_BREAKPOINT_DL4()				CD_breakpoint()
+#else
+#define CD_ASSERT_DL4(condition)
+#define CD_POSTCODE_DL4(value)
+#define CD_TRACE_DL4(string)
+#define CD_TRACETAB_DL4(string)
+#define CD_TRACEDEC_DL4(value)
+#define CD_TRACEHEX_DL4(value)
+#define CD_TRACEBUF_DL4(pointer, len)
+#define CD_WAIT_DL4(what)
+#define CD_BREAKPOINT_DL4()
+#endif
+
+#if (DEBUG_PARSER >= 3)
+#define CD_ASSERT_DL3(condition)		if(!(condition)) CD_assert(__FILE__, __LINE__)
+#define CD_POSTCODE_DL3(value)			CD_postcode(value)
+#define CD_TRACE_DL3(string)			CD_print(string)
+#define CD_TRACETAB_DL3(string)			CD_print("\n\t\t");CD_print(string)
+#define CD_TRACEDEC_DL3(value)			CD_print_dec( (UINTN)(value))
+#define CD_TRACEHEX_DL3(value)			CD_print_hex( (UINT32)(value), sizeof(value) )
+#define CD_TRACEBUF_DL3(pointer, len)	CD_print_buf( (UINT8 *)(pointer), (UINTN) len)
+#define CD_WAIT_DL3(what)				CD_wait((INT32)what)
+#define CD_BREAKPOINT_DL3()				CD_breakpoint()
+#else
+#define CD_ASSERT_DL3(condition)
+#define CD_POSTCODE_DL3(value)
+#define CD_TRACE_DL3(string)
+#define CD_TRACETAB_DL3(string)
+#define CD_TRACEDEC_DL3(value)
+#define CD_TRACEHEX_DL3(value)
+#define CD_TRACEBUF_DL3(pointer, len)
+#define CD_WAIT_DL3(what)
+#define CD_BREAKPOINT_DL3()
+#endif
+
+
+#if (DEBUG_PARSER >= 2)
+#define CD_ASSERT_DL2(condition)		if(!(condition)) CD_assert(__FILE__, __LINE__)
+#define CD_POSTCODE_DL2(value)			CD_postcode(value)
+#define CD_TRACE_DL2(string)			CD_print(string)
+#define CD_TRACETAB_DL2(string)			CD_print("\n\t");CD_print(string)
+#define CD_TRACEDEC_DL2(value)			CD_print_dec( (UINTN)(value))
+#define CD_TRACEHEX_DL2(value)			CD_print_hex( (UINT32)(value), sizeof(value) )
+#define CD_TRACEBUF_DL2(pointer, len)	CD_print_buf( (UINT8 *)(pointer), (UINTN) len)
+#define CD_WAIT_DL2(what)				CD_wait((INT32)what)
+#define CD_BREAKPOINT_DL2()				CD_breakpoint()
+#else
+#define CD_ASSERT_DL2(condition)
+#define CD_POSTCODE_DL2(value)
+#define CD_TRACE_DL2(string)
+#define CD_TRACETAB_DL2(string)
+#define CD_TRACEDEC_DL2(value)
+#define CD_TRACEHEX_DL2(value)
+#define CD_TRACEBUF_DL2(pointer, len)
+#define CD_WAIT_DL2(what)
+#define CD_BREAKPOINT_DL2()
+#endif
+
+
+#if (DEBUG_PARSER >= 1)
+#define CD_ASSERT_DL1(condition)		if(!(condition)) CD_assert(__FILE__, __LINE__)
+#define CD_POSTCODE_DL1(value)			CD_postcode(value)
+#define CD_TRACE_DL1(string)			CD_print(string)
+#define CD_TRACETAB_DL1(string)			CD_print("\n");CD_print(string)
+#define CD_TRACEDEC_DL1(value)			CD_print_dec( (UINTN)(value))
+#define CD_TRACEHEX_DL1(value)			CD_print_hex( (UINT32)(value), sizeof(value) )
+#define CD_TRACEBUF_DL1(pointer, len)	CD_print_buf( (UINT8 *)(pointer), (UINTN) len)
+#define CD_WAIT_DL1(what)				CD_wait((INT32)what)
+#define CD_BREAKPOINT_DL1()				CD_breakpoint()
+#else
+#define CD_ASSERT_DL1(condition)
+#define CD_POSTCODE_DL1(value)
+#define CD_TRACE_DL1(string)
+#define CD_TRACETAB_DL1(string)
+#define CD_TRACEDEC_DL1(value)
+#define CD_TRACEHEX_DL1(value)
+#define CD_TRACEBUF_DL1(pointer, len)
+#define CD_WAIT_DL1(what)
+#define CD_BREAKPOINT_DL1()
+#endif
+
+#endif  //#ifdef DRIVER_PARSER
+
+
+#else
+
+#define CD_ASSERT(condition)
+#define CD_POSTCODE(value)
+#define CD_TRACE(string)
+#define CD_TRACEDEC(value)
+#define CD_TRACEHEX(value)
+#define CD_TRACEBUF(pointer, len)
+#define CD_WAIT(what)
+#define CD_BREAKPOINT()
+
+#define CD_ASSERT_DL4(condition)
+#define CD_POSTCODE_DL4(value)
+#define CD_TRACE_DL4(string)
+#define CD_TRACETAB_DL4(string)
+#define CD_TRACEDEC_DL4(value)
+#define CD_TRACEHEX_DL4(value)
+#define CD_TRACEBUF_DL4(pointer, len)
+#define CD_WAIT_DL4(what)
+#define CD_BREAKPOINT_DL4()
+
+#define CD_ASSERT_DL3(condition)
+#define CD_POSTCODE_DL3(value)
+#define CD_TRACE_DL3(string)
+#define CD_TRACETAB_DL3(string)
+#define CD_TRACEDEC_DL3(value)
+#define CD_TRACEHEX_DL3(value)
+#define CD_TRACEBUF_DL3(pointer, len)
+#define CD_WAIT_DL3(what)
+#define CD_BREAKPOINT_DL3()
+
+#define CD_ASSERT_DL2(condition)
+#define CD_POSTCODE_DL2(value)
+#define CD_TRACE_DL2(string)
+#define CD_TRACETAB_DL2(string)
+#define CD_TRACEDEC_DL2(value)
+#define CD_TRACEHEX_DL2(value)
+#define CD_TRACEBUF_DL2(pointer, len)
+#define CD_WAIT_DL2(what)
+#define CD_BREAKPOINT_DL2()
+
+#define CD_ASSERT_DL1(condition)
+#define CD_POSTCODE_DL1(value)
+#define CD_TRACE_DL1(string)
+#define CD_TRACETAB_DL1(string)
+#define CD_TRACEDEC_DL1(value)
+#define CD_TRACEHEX_DL1(value)
+#define CD_TRACEBUF_DL1(pointer, len)
+#define CD_WAIT_DL1(what)
+#define CD_BREAKPOINT_DL1()
+
+
+#endif  //#if (DEBUG_PARSER > 0)
+
+
+#ifdef CHECKSTACK
+VOID CD_fillstack(UINT16 size);
+UINT16 CD_checkstack(UINT16 size);
+#define CD_CHECKSTACK(stacksize)	CD_checkstack(stacksize)
+#define CD_FILLSTACK(stacksize)		CD_fillstack(stacksize)
+#else
+#define CD_CHECKSTACK(stacksize)	0
+#define CD_FILLSTACK(stacksize)
+#endif
+
+
+#endif
diff --git a/src/AtomBios/includes/Decoder.h b/src/AtomBios/includes/Decoder.h
new file mode 100644
index 0000000..24c25fc
--- /dev/null
+++ b/src/AtomBios/includes/Decoder.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2006-2007 Advanced Micro Devices, Inc.  
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*++
+
+Module Name:
+
+Decoder.h
+
+Abstract:
+
+Includes all helper headers
+
+Revision History:
+
+NEG:27.08.2002	Initiated.
+--*/
+#ifndef _DECODER_H_
+#define _DECODER_H_
+#define WS_QUOTIENT_C														64
+#define WS_REMINDER_C														(WS_QUOTIENT_C+1)
+#define WS_DATAPTR_C														(WS_REMINDER_C+1)
+#define WS_SHIFT_C													    (WS_DATAPTR_C+1)
+#define WS_OR_MASK_C													  (WS_SHIFT_C+1)
+#define WS_AND_MASK_C													  (WS_OR_MASK_C+1)
+#define WS_FB_WINDOW_C                          (WS_AND_MASK_C+1)
+#define WS_ATTRIBUTES_C                         (WS_FB_WINDOW_C+1)
+#define PARSER_VERSION_MAJOR                   0x00000000
+#define PARSER_VERSION_MINOR                   0x0000000E
+#define PARSER_VERSION                         (PARSER_VERSION_MAJOR | PARSER_VERSION_MINOR)
+#include "CD_binding.h"
+#include "CD_Common_Types.h"
+#include "CD_hw_services.h"
+#include "CD_Structs.h"
+#include "CD_Definitions.h"
+#include "CD_Opcodes.h"
+
+#define	SOURCE_ONLY_CMD_TYPE		0//0xFE
+#define SOURCE_DESTINATION_CMD_TYPE	1//0xFD
+#define	DESTINATION_ONLY_CMD_TYPE	2//0xFC
+
+#define	ACCESS_TYPE_BYTE			0//0xF9
+#define	ACCESS_TYPE_WORD			1//0xF8
+#define	ACCESS_TYPE_DWORD			2//0xF7
+#define	SWITCH_TYPE_ACCESS			3//0xF6
+
+#define CD_CONTINUE					0//0xFB
+#define CD_STOP						1//0xFA
+
+
+#define IS_END_OF_TABLE(cmd) ((cmd) == EOT_OPCODE)
+#define IS_COMMAND_VALID(cmd) (((cmd)<=LastValidCommand)&&((cmd)>=FirstValidCommand))
+#define IS_IT_SHIFT_COMMAND(Opcode) ((Opcode<=SHIFT_RIGHT_MC_OPCODE)&&(Opcode>=SHIFT_LEFT_REG_OPCODE))
+#define IS_IT_XXXX_COMMAND(Group, Opcode) ((Opcode<=Group##_MC_OPCODE)&&(Opcode>=Group##_REG_OPCODE))
+#define	CheckCaseAndAdjustIP_Macro(size) \
+	if (pParserTempData->SourceData32==(UINT32)((CASE_OFFSET*)pParserTempData->pWorkingTableData->IP)->XX_Access.size##.Access.Value){\
+		pParserTempData->CommandSpecific.ContinueSwitch = CD_STOP;\
+		pParserTempData->pWorkingTableData->IP =(COMMAND_HEADER_POINTER *) RELATIVE_TO_TABLE(((CASE_OFFSET*)pParserTempData->pWorkingTableData->IP)->XX_Access.size##.Access.JumpOffset);\
+	}else{\
+		pParserTempData->pWorkingTableData->IP+=(sizeof (CASE_##size##ACCESS)\
+		+sizeof(((CASE_OFFSET*)pParserTempData->pWorkingTableData->IP)->CaseSignature));\
+	}
+
+#endif
+/*	pWorkingTableData->pCmd->Header.Attribute.SourceAlignment=alignmentLowerWord;\*/
+
+// EOF
diff --git a/src/AtomBios/includes/ObjectID.h b/src/AtomBios/includes/ObjectID.h
new file mode 100644
index 0000000..a630c69
--- /dev/null
+++ b/src/AtomBios/includes/ObjectID.h
@@ -0,0 +1,448 @@
+/*
+* Copyright 2006-2007 Advanced Micro Devices, Inc.  
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*/
+/* based on stg/asic_reg/drivers/inc/asic_reg/ObjectID.h ver 23 */
+
+#ifndef _OBJECTID_H
+#define _OBJECTID_H
+
+#if defined(_X86_)
+#pragma pack(1)
+#endif
+
+/****************************************************/
+/* Graphics Object Type Definition                  */
+/****************************************************/
+#define GRAPH_OBJECT_TYPE_NONE                    0x0
+#define GRAPH_OBJECT_TYPE_GPU                     0x1
+#define GRAPH_OBJECT_TYPE_ENCODER                 0x2
+#define GRAPH_OBJECT_TYPE_CONNECTOR               0x3
+#define GRAPH_OBJECT_TYPE_ROUTER                  0x4
+/* deleted */
+
+/****************************************************/
+/* Encoder Object ID Definition                     */
+/****************************************************/
+#define ENCODER_OBJECT_ID_NONE                    0x00 
+
+/* Radeon Class Display Hardware */
+#define ENCODER_OBJECT_ID_INTERNAL_LVDS           0x01
+#define ENCODER_OBJECT_ID_INTERNAL_TMDS1          0x02
+#define ENCODER_OBJECT_ID_INTERNAL_TMDS2          0x03
+#define ENCODER_OBJECT_ID_INTERNAL_DAC1           0x04
+#define ENCODER_OBJECT_ID_INTERNAL_DAC2           0x05     /* TV/CV DAC */
+#define ENCODER_OBJECT_ID_INTERNAL_SDVOA          0x06
+#define ENCODER_OBJECT_ID_INTERNAL_SDVOB          0x07
+
+/* External Third Party Encoders */
+#define ENCODER_OBJECT_ID_SI170B                  0x08
+#define ENCODER_OBJECT_ID_CH7303                  0x09
+#define ENCODER_OBJECT_ID_CH7301                  0x0A
+#define ENCODER_OBJECT_ID_INTERNAL_DVO1           0x0B    /* This belongs to Radeon Class Display Hardware */
+#define ENCODER_OBJECT_ID_EXTERNAL_SDVOA          0x0C
+#define ENCODER_OBJECT_ID_EXTERNAL_SDVOB          0x0D
+#define ENCODER_OBJECT_ID_TITFP513                0x0E
+#define ENCODER_OBJECT_ID_INTERNAL_LVTM1          0x0F    /* not used for Radeon */
+#define ENCODER_OBJECT_ID_VT1623                  0x10
+#define ENCODER_OBJECT_ID_HDMI_SI1930             0x11
+#define ENCODER_OBJECT_ID_HDMI_INTERNAL           0x12
+/* Kaleidoscope (KLDSCP) Class Display Hardware (internal) */
+#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1   0x13
+#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1    0x14
+#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1    0x15
+#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2    0x16  /* Shared with CV/TV and CRT */
+#define ENCODER_OBJECT_ID_SI178                   0X17  /* External TMDS (dual link, no HDCP.) */
+#define ENCODER_OBJECT_ID_MVPU_FPGA               0x18  /* MVPU FPGA chip */
+#define ENCODER_OBJECT_ID_INTERNAL_DDI            0x19
+#define ENCODER_OBJECT_ID_VT1625                  0x1A
+#define ENCODER_OBJECT_ID_HDMI_SI1932             0x1B
+#define ENCODER_OBJECT_ID_DP_AN9801               0x1C
+#define ENCODER_OBJECT_ID_DP_DP501                0x1D
+
+/****************************************************/
+/* Connector Object ID Definition                   */
+/****************************************************/
+#define CONNECTOR_OBJECT_ID_NONE                  0x00 
+#define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I     0x01
+#define CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I       0x02
+#define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D     0x03
+#define CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D       0x04
+#define CONNECTOR_OBJECT_ID_VGA                   0x05
+#define CONNECTOR_OBJECT_ID_COMPOSITE             0x06
+#define CONNECTOR_OBJECT_ID_SVIDEO                0x07
+#define CONNECTOR_OBJECT_ID_YPbPr                 0x08
+#define CONNECTOR_OBJECT_ID_D_CONNECTOR           0x09
+#define CONNECTOR_OBJECT_ID_9PIN_DIN              0x0A  /* Supports both CV & TV */
+#define CONNECTOR_OBJECT_ID_SCART                 0x0B
+#define CONNECTOR_OBJECT_ID_HDMI_TYPE_A           0x0C
+#define CONNECTOR_OBJECT_ID_HDMI_TYPE_B           0x0D
+#define CONNECTOR_OBJECT_ID_LVDS                  0x0E
+#define CONNECTOR_OBJECT_ID_7PIN_DIN              0x0F
+#define CONNECTOR_OBJECT_ID_PCIE_CONNECTOR        0x10
+#define CONNECTOR_OBJECT_ID_CROSSFIRE             0x11
+#define CONNECTOR_OBJECT_ID_HARDCODE_DVI          0x12
+#define CONNECTOR_OBJECT_ID_DISPLAYPORT           0x13
+
+/* deleted */
+
+/****************************************************/
+/* Router Object ID Definition                      */
+/****************************************************/
+#define ROUTER_OBJECT_ID_NONE											0x00
+#define ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL				0x01
+
+/****************************************************/
+// Graphics Object ENUM ID Definition               */
+/****************************************************/
+#define GRAPH_OBJECT_ENUM_ID1                     0x01
+#define GRAPH_OBJECT_ENUM_ID2                     0x02
+#define GRAPH_OBJECT_ENUM_ID3                     0x03
+#define GRAPH_OBJECT_ENUM_ID4                     0x04
+
+/****************************************************/
+/* Graphics Object ID Bit definition                */
+/****************************************************/
+#define OBJECT_ID_MASK                            0x00FF
+#define ENUM_ID_MASK                              0x0700
+#define RESERVED1_ID_MASK                         0x0800
+#define OBJECT_TYPE_MASK                          0x7000
+#define RESERVED2_ID_MASK                         0x8000
+                                                  
+#define OBJECT_ID_SHIFT                           0x00
+#define ENUM_ID_SHIFT                             0x08
+#define OBJECT_TYPE_SHIFT                         0x0C
+
+
+/****************************************************/
+/* Graphics Object family definition                */
+/****************************************************/
+#define CONSTRUCTOBJECTFAMILYID(GRAPHICS_OBJECT_TYPE, GRAPHICS_OBJECT_ID) (GRAPHICS_OBJECT_TYPE << OBJECT_TYPE_SHIFT | \
+                                                                           GRAPHICS_OBJECT_ID   << OBJECT_ID_SHIFT)
+/****************************************************/
+/* GPU Object ID definition - Shared with BIOS      */
+/****************************************************/
+#define GPU_ENUM_ID1                            ( GRAPH_OBJECT_TYPE_GPU << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT)
+
+/****************************************************/
+/* Encoder Object ID definition - Shared with BIOS  */
+/****************************************************/
+/*
+#define ENCODER_INTERNAL_LVDS_ENUM_ID1        0x2101      
+#define ENCODER_INTERNAL_TMDS1_ENUM_ID1       0x2102
+#define ENCODER_INTERNAL_TMDS2_ENUM_ID1       0x2103
+#define ENCODER_INTERNAL_DAC1_ENUM_ID1        0x2104
+#define ENCODER_INTERNAL_DAC2_ENUM_ID1        0x2105
+#define ENCODER_INTERNAL_SDVOA_ENUM_ID1       0x2106
+#define ENCODER_INTERNAL_SDVOB_ENUM_ID1       0x2107
+#define ENCODER_SIL170B_ENUM_ID1              0x2108  
+#define ENCODER_CH7303_ENUM_ID1               0x2109
+#define ENCODER_CH7301_ENUM_ID1               0x210A
+#define ENCODER_INTERNAL_DVO1_ENUM_ID1        0x210B
+#define ENCODER_EXTERNAL_SDVOA_ENUM_ID1       0x210C
+#define ENCODER_EXTERNAL_SDVOB_ENUM_ID1       0x210D
+#define ENCODER_TITFP513_ENUM_ID1             0x210E
+#define ENCODER_INTERNAL_LVTM1_ENUM_ID1       0x210F
+#define ENCODER_VT1623_ENUM_ID1               0x2110
+#define ENCODER_HDMI_SI1930_ENUM_ID1          0x2111
+#define ENCODER_HDMI_INTERNAL_ENUM_ID1        0x2112
+#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1   0x2113
+#define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1    0x2114
+#define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1    0x2115
+#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1    0x2116  
+#define ENCODER_SI178_ENUM_ID1                   0x2117 
+#define ENCODER_MVPU_FPGA_ENUM_ID1               0x2118
+#define ENCODER_INTERNAL_DDI_ENUM_ID1            0x2119
+#define ENCODER_VT1625_ENUM_ID1               0x211A
+*/
+#define ENCODER_INTERNAL_LVDS_ENUM_ID1     ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_LVDS << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_TMDS1_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_TMDS1 << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_TMDS2_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_TMDS2 << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_DAC1_ENUM_ID1     ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_DAC1 << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_DAC2_ENUM_ID1     ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_DAC2 << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_SDVOA_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_SDVOA_ENUM_ID2    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_SDVOB_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_SDVOB << OBJECT_ID_SHIFT)
+
+#define ENCODER_SIL170B_ENUM_ID1           ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_SI170B << OBJECT_ID_SHIFT)
+
+#define ENCODER_CH7303_ENUM_ID1            ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_CH7303 << OBJECT_ID_SHIFT)
+
+#define ENCODER_CH7301_ENUM_ID1            ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_CH7301 << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_DVO1_ENUM_ID1     ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_DVO1 << OBJECT_ID_SHIFT)
+
+#define ENCODER_EXTERNAL_SDVOA_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT)
+
+#define ENCODER_EXTERNAL_SDVOA_ENUM_ID2    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT)
+
+
+#define ENCODER_EXTERNAL_SDVOB_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_EXTERNAL_SDVOB << OBJECT_ID_SHIFT)
+
+
+#define ENCODER_TITFP513_ENUM_ID1          ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_TITFP513 << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_LVTM1_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_LVTM1 << OBJECT_ID_SHIFT)
+
+#define ENCODER_VT1623_ENUM_ID1            ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_VT1623 << OBJECT_ID_SHIFT)
+
+#define ENCODER_HDMI_SI1930_ENUM_ID1       ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_HDMI_SI1930 << OBJECT_ID_SHIFT)
+
+#define ENCODER_HDMI_INTERNAL_ENUM_ID1     ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_HDMI_INTERNAL << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1   ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                   GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                   ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT)
+
+
+#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID2   ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                   GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                   ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT)
+
+
+#define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                   GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                   ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                   GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                   ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                   GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                   ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 << OBJECT_ID_SHIFT)  // Shared with CV/TV and CRT
+
+#define ENCODER_SI178_ENUM_ID1                    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                   GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                   ENCODER_OBJECT_ID_SI178 << OBJECT_ID_SHIFT)  
+
+#define ENCODER_MVPU_FPGA_ENUM_ID1                ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                   GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                   ENCODER_OBJECT_ID_MVPU_FPGA << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_DDI_ENUM_ID1     (  GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_INTERNAL_DDI << OBJECT_ID_SHIFT) 
+
+#define ENCODER_VT1625_ENUM_ID1            ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_VT1625 << OBJECT_ID_SHIFT)
+
+#define ENCODER_HDMI_SI1932_ENUM_ID1       ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_HDMI_SI1932 << OBJECT_ID_SHIFT)
+
+#define ENCODER_DP_DP501_ENUM_ID1            ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_DP_DP501 << OBJECT_ID_SHIFT)
+
+#define ENCODER_DP_AN9801_ENUM_ID1            ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                             GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                             ENCODER_OBJECT_ID_DP_AN9801 << OBJECT_ID_SHIFT)
+/****************************************************/
+/* Connector Object ID definition - Shared with BIOS */
+/****************************************************/
+/*
+#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1        0x3101
+#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1          0x3102
+#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1        0x3103
+#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1          0x3104
+#define CONNECTOR_VGA_ENUM_ID1                      0x3105
+#define CONNECTOR_COMPOSITE_ENUM_ID1                0x3106
+#define CONNECTOR_SVIDEO_ENUM_ID1                   0x3107
+#define CONNECTOR_YPbPr_ENUM_ID1                    0x3108
+#define CONNECTOR_D_CONNECTORE_ENUM_ID1             0x3109
+#define CONNECTOR_9PIN_DIN_ENUM_ID1                 0x310A
+#define CONNECTOR_SCART_ENUM_ID1                    0x310B
+#define CONNECTOR_HDMI_TYPE_A_ENUM_ID1              0x310C
+#define CONNECTOR_HDMI_TYPE_B_ENUM_ID1              0x310D
+#define CONNECTOR_LVDS_ENUM_ID1                     0x310E
+#define CONNECTOR_7PIN_DIN_ENUM_ID1                 0x310F
+#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1           0x3110
+*/
+#define CONNECTOR_LVDS_ENUM_ID1                ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1   ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID2   ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1     ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID2     ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1   ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1     ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_VGA_ENUM_ID1                 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_COMPOSITE_ENUM_ID1           ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_COMPOSITE << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_SVIDEO_ENUM_ID1              ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_YPbPr_ENUM_ID1               ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_D_CONNECTOR_ENUM_ID1         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_9PIN_DIN_ENUM_ID1            ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_SCART_ENUM_ID1               ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_HDMI_TYPE_A_ENUM_ID1         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_HDMI_TYPE_B_ENUM_ID1         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_7PIN_DIN_ENUM_ID1            ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1      ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_CROSSFIRE_ENUM_ID1           ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_CROSSFIRE_ENUM_ID2           ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT)
+
+
+#define CONNECTOR_HARDCODE_DVI_ENUM_ID1        ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_HARDCODE_DVI_ENUM_ID2        ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_DISPLAYPORT_ENUM_ID1         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
+/****************************************************/
+/* Router Object ID definition - Shared with BIOS   */
+/****************************************************/
+#define ROUTER_I2C_EXTENDER_CNTL_ENUM_ID1      ( GRAPH_OBJECT_TYPE_ROUTER << OBJECT_TYPE_SHIFT |\
+                                                GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL << OBJECT_ID_SHIFT)
+
+/* deleted */
+
+/****************************************************/
+/* Object Cap definition - Shared with BIOS         */
+/****************************************************/
+#define GRAPHICS_OBJECT_CAP_I2C                 0x00000001L
+#define GRAPHICS_OBJECT_CAP_TABLE_ID            0x00000002L
+
+
+#define GRAPHICS_OBJECT_I2CCOMMAND_TABLE_ID                   0x01
+#define GRAPHICS_OBJECT_HOTPLUGDETECTIONINTERUPT_TABLE_ID     0x02
+#define GRAPHICS_OBJECT_ENCODER_OUTPUT_PROTECTION_TABLE_ID    0x03
+
+#if defined(_X86_)
+#pragma pack()
+#endif
+
+#endif  /*GRAPHICTYPE */
+
+
+
+
diff --git a/src/AtomBios/includes/atombios.h b/src/AtomBios/includes/atombios.h
new file mode 100644
index 0000000..863de2e
--- /dev/null
+++ b/src/AtomBios/includes/atombios.h
@@ -0,0 +1,4306 @@
+/*
+ * Copyright 2006-2007 Advanced Micro Devices, Inc.  
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/****************************************************************************/	
+/*Portion I: Definitions  shared between VBIOS and Driver                   */
+/****************************************************************************/
+
+
+#ifndef _ATOMBIOS_H
+#define _ATOMBIOS_H
+
+#define ATOM_VERSION_MAJOR                   0x00020000
+#define ATOM_VERSION_MINOR                   0x00000002
+
+#define ATOM_HEADER_VERSION (ATOM_VERSION_MAJOR | ATOM_VERSION_MINOR)
+
+
+#ifdef _H2INC
+  #ifndef ULONG 
+    typedef unsigned long ULONG;
+  #endif
+
+  #ifndef UCHAR
+    typedef unsigned char UCHAR;
+  #endif
+
+  #ifndef USHORT 
+    typedef unsigned short USHORT;
+  #endif
+#endif
+      
+#define ATOM_DAC_A            0 
+#define ATOM_DAC_B            1
+#define ATOM_EXT_DAC          2
+
+#define ATOM_CRTC1            0
+#define ATOM_CRTC2            1
+
+#define ATOM_DIGA             0
+#define ATOM_DIGB             1
+
+#define ATOM_PPLL1            0
+#define ATOM_PPLL2            1
+
+#define ATOM_SCALER1          0
+#define ATOM_SCALER2          1
+
+#define ATOM_SCALER_DISABLE   0   
+#define ATOM_SCALER_CENTER    1   
+#define ATOM_SCALER_EXPANSION 2   
+#define ATOM_SCALER_MULTI_EX  3   
+
+#define ATOM_DISABLE          0
+#define ATOM_ENABLE           1
+#define ATOM_LCD_BLOFF                          (ATOM_DISABLE+2)
+#define ATOM_LCD_BLON                           (ATOM_ENABLE+2)
+#define ATOM_LCD_BL_BRIGHTNESS_CONTROL          (ATOM_ENABLE+3)
+#define ATOM_LCD_SELFTEST_START									(ATOM_DISABLE+5)
+#define ATOM_LCD_SELFTEST_STOP									(ATOM_ENABLE+5)
+#define ATOM_ENCODER_INIT			                  (ATOM_DISABLE+7)
+
+#define ATOM_BLANKING         1
+#define ATOM_BLANKING_OFF     0
+
+#define ATOM_CURSOR1          0
+#define ATOM_CURSOR2          1
+
+#define ATOM_ICON1            0
+#define ATOM_ICON2            1
+
+#define ATOM_CRT1             0
+#define ATOM_CRT2             1
+
+#define ATOM_TV_NTSC          1
+#define ATOM_TV_NTSCJ         2
+#define ATOM_TV_PAL           3
+#define ATOM_TV_PALM          4
+#define ATOM_TV_PALCN         5
+#define ATOM_TV_PALN          6
+#define ATOM_TV_PAL60         7
+#define ATOM_TV_SECAM         8
+#define ATOM_TV_CV            16
+
+#define ATOM_DAC1_PS2         1
+#define ATOM_DAC1_CV          2
+#define ATOM_DAC1_NTSC        3
+#define ATOM_DAC1_PAL         4
+
+#define ATOM_DAC2_PS2         ATOM_DAC1_PS2
+#define ATOM_DAC2_CV          ATOM_DAC1_CV
+#define ATOM_DAC2_NTSC        ATOM_DAC1_NTSC
+#define ATOM_DAC2_PAL         ATOM_DAC1_PAL
+ 
+#define ATOM_PM_ON            0
+#define ATOM_PM_STANDBY       1
+#define ATOM_PM_SUSPEND       2
+#define ATOM_PM_OFF           3
+
+/* Bit0:{=0:single, =1:dual},
+   Bit1 {=0:666RGB, =1:888RGB},
+   Bit2:3:{Grey level}
+   Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888}*/
+
+#define ATOM_PANEL_MISC_DUAL               0x00000001
+#define ATOM_PANEL_MISC_888RGB             0x00000002
+#define ATOM_PANEL_MISC_GREY_LEVEL         0x0000000C
+#define ATOM_PANEL_MISC_FPDI               0x00000010
+#define ATOM_PANEL_MISC_GREY_LEVEL_SHIFT   2
+#define ATOM_PANEL_MISC_SPATIAL            0x00000020
+#define ATOM_PANEL_MISC_TEMPORAL           0x00000040
+#define ATOM_PANEL_MISC_API_ENABLED        0x00000080
+
+
+#define MEMTYPE_DDR1              "DDR1"
+#define MEMTYPE_DDR2              "DDR2"
+#define MEMTYPE_DDR3              "DDR3"
+#define MEMTYPE_DDR4              "DDR4"
+
+#define ASIC_BUS_TYPE_PCI         "PCI"
+#define ASIC_BUS_TYPE_AGP         "AGP"
+#define ASIC_BUS_TYPE_PCIE        "PCI_EXPRESS"
+
+/* Maximum size of that FireGL flag string */
+
+#define ATOM_FIREGL_FLAG_STRING     "FGL"             //Flag used to enable FireGL Support
+#define ATOM_MAX_SIZE_OF_FIREGL_FLAG_STRING  3        //sizeof( ATOM_FIREGL_FLAG_STRING )
+
+#define ATOM_FAKE_DESKTOP_STRING    "DSK"             //Flag used to enable mobile ASIC on Desktop
+#define ATOM_MAX_SIZE_OF_FAKE_DESKTOP_STRING  ATOM_MAX_SIZE_OF_FIREGL_FLAG_STRING 
+
+#define ATOM_M54T_FLAG_STRING       "M54T"            //Flag used to enable M54T Support
+#define ATOM_MAX_SIZE_OF_M54T_FLAG_STRING    4        //sizeof( ATOM_M54T_FLAG_STRING )
+
+#define HW_ASSISTED_I2C_STATUS_FAILURE          2
+#define HW_ASSISTED_I2C_STATUS_SUCCESS          1
+
+#pragma pack(1)                                       /* BIOS data must use byte aligment */
+
+/*  Define offset to location of ROM header. */
+
+#define OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER		0x00000048L
+#define OFFSET_TO_ATOM_ROM_IMAGE_SIZE				    0x00000002L
+
+#define OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE    0x94
+#define MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE   20    /* including the terminator 0x0! */
+#define	OFFSET_TO_GET_ATOMBIOS_STRINGS_NUMBER		0x002f
+#define	OFFSET_TO_GET_ATOMBIOS_STRINGS_START		0x006e
+
+/* Common header for all ROM Data tables.
+  Every table pointed  _ATOM_MASTER_DATA_TABLE has this common header. 
+  And the pointer actually points to this header. */
+
+typedef struct _ATOM_COMMON_TABLE_HEADER
+{
+  USHORT usStructureSize;
+  UCHAR  ucTableFormatRevision;   /*Change it when the Parser is not backward compatible */
+  UCHAR  ucTableContentRevision;  /*Change it only when the table needs to change but the firmware */
+                                  /*Image can't be updated, while Driver needs to carry the new table! */
+}ATOM_COMMON_TABLE_HEADER;
+
+typedef struct _ATOM_ROM_HEADER
+{
+  ATOM_COMMON_TABLE_HEADER		sHeader;
+  UCHAR	 uaFirmWareSignature[4];    /*Signature to distinguish between Atombios and non-atombios, 
+                                      atombios should init it as "ATOM", don't change the position */
+  USHORT usBiosRuntimeSegmentAddress;
+  USHORT usProtectedModeInfoOffset;
+  USHORT usConfigFilenameOffset;
+  USHORT usCRC_BlockOffset;
+  USHORT usBIOS_BootupMessageOffset;
+  USHORT usInt10Offset;
+  USHORT usPciBusDevInitCode;
+  USHORT usIoBaseAddress;
+  USHORT usSubsystemVendorID;
+  USHORT usSubsystemID;
+  USHORT usPCI_InfoOffset; 
+  USHORT usMasterCommandTableOffset; /*Offset for SW to get all command table offsets, Don't change the position */
+  USHORT usMasterDataTableOffset;   /*Offset for SW to get all data table offsets, Don't change the position */
+  UCHAR  ucExtendedFunctionCode;
+  UCHAR  ucReserved;
+}ATOM_ROM_HEADER;
+
+/*==============================Command Table Portion==================================== */
+
+#ifdef	UEFI_BUILD
+	#define	UTEMP	USHORT
+	#define	USHORT	void*
+#endif
+
+typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{
+  USHORT ASIC_Init;                              //Function Table, used by various SW components,latest version 1.1
+  USHORT GetDisplaySurfaceSize;                  //Atomic Table,  Used by Bios when enabling HW ICON
+  USHORT ASIC_RegistersInit;                     //Atomic Table,  indirectly used by various SW components,called from ASIC_Init
+  USHORT VRAM_BlockVenderDetection;
+  USHORT SetClocksRatio;
+  USHORT MemoryControllerInit;                   //Atomic Table,  indirectly used by various SW components,called from ASIC_Init
+  USHORT EnableCRTCMemReq;                       //Function Table,directly used by various SW components,latest version 2.1
+  USHORT MemoryParamAdjust; 										 //Atomic Table,  indirectly used by various SW components,called from SetMemoryClock if needed
+  USHORT DVOEncoderControl;                      //Function Table,directly used by various SW components,latest version 1.2
+  USHORT GPIOPinControl;												 //Atomic Table,  only used by Bios
+  USHORT SetEngineClock;                         //Function Table,directly used by various SW components,latest version 1.1
+  USHORT SetMemoryClock;                         //Function Table,directly used by various SW components,latest version 1.1
+  USHORT SetPixelClock;                          //Function Table,directly used by various SW components,latest version 1.2  
+  USHORT DynamicClockGating;                     //Atomic Table,  indirectly used by various SW components,called from ASIC_Init
+  USHORT ResetMemoryDLL;                         //Atomic Table,  indirectly used by various SW components,called from SetMemoryClock
+  USHORT ResetMemoryDevice;                      //Atomic Table,  indirectly used by various SW components,called from SetMemoryClock
+  USHORT MemoryPLLInit;
+  USHORT AdjustDisplayPll;												//only used by Bios
+  USHORT AdjustMemoryController;                 //Atomic Table,  indirectly used by various SW components,called from SetMemoryClock                
+  USHORT EnableASIC_StaticPwrMgt;                //Atomic Table,  only used by Bios
+  USHORT ASIC_StaticPwrMgtStatusChange;          //Obsolete ,     only used by Bios   
+  USHORT DAC_LoadDetection;                      //Atomic Table,  directly used by various SW components,latest version 1.2  
+  USHORT LVTMAEncoderControl;                    //Atomic Table,directly used by various SW components,latest version 1.3
+  USHORT LCD1OutputControl;                      //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT DAC1EncoderControl;                     //Atomic Table,  directly used by various SW components,latest version 1.1  
+  USHORT DAC2EncoderControl;                     //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT DVOOutputControl;                       //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT CV1OutputControl;                       //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT GetConditionalGoldenSetting;            //only used by Bios
+  USHORT TVEncoderControl;                       //Function Table,directly used by various SW components,latest version 1.1
+  USHORT TMDSAEncoderControl;                    //Atomic Table,  directly used by various SW components,latest version 1.3
+  USHORT LVDSEncoderControl;                     //Atomic Table,  directly used by various SW components,latest version 1.3
+  USHORT TV1OutputControl;                       //Atomic Table,  directly used by various SW components,latest version 1.1
+  USHORT EnableScaler;                           //Atomic Table,  used only by Bios
+  USHORT BlankCRTC;                              //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT EnableCRTC;                             //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT GetPixelClock;                          //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT EnableVGA_Render;                       //Function Table,directly used by various SW components,latest version 1.1
+  USHORT EnableVGA_Access;                       //Obsolete ,     only used by Bios
+  USHORT SetCRTC_Timing;                         //Atomic Table,  directly used by various SW components,latest version 1.1
+  USHORT SetCRTC_OverScan;                       //Atomic Table,  used by various SW components,latest version 1.1 
+  USHORT SetCRTC_Replication;                    //Atomic Table,  used only by Bios
+  USHORT SelectCRTC_Source;                      //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT EnableGraphSurfaces;                    //Atomic Table,  used only by Bios
+  USHORT UpdateCRTC_DoubleBufferRegisters;
+  USHORT LUT_AutoFill;                           //Atomic Table,  only used by Bios
+  USHORT EnableHW_IconCursor;                    //Atomic Table,  only used by Bios
+  USHORT GetMemoryClock;                         //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT GetEngineClock;                         //Atomic Table,  directly used by various SW components,latest version 1.1 
+  USHORT SetCRTC_UsingDTDTiming;                 //Atomic Table,  directly used by various SW components,latest version 1.1
+  USHORT ExternalEncoderControl;                 //Atomic Table,  directly used by various SW components,latest version 2.1
+  USHORT LVTMAOutputControl;                     //Atomic Table,  directly used by various SW components,latest version 1.1
+  USHORT VRAM_BlockDetectionByStrap;
+  USHORT MemoryCleanUp;                          //Atomic Table,  only used by Bios    
+  USHORT ReadEDIDFromHWAssistedI2C;              //Function Table,only used by Bios
+  USHORT WriteOneByteToHWAssistedI2C;            //Function Table,indirectly used by various SW components 
+  USHORT ReadHWAssistedI2CStatus;                //Atomic Table,  indirectly used by various SW components
+  USHORT SpeedFanControl;                        //Function Table,indirectly used by various SW components,called from ASIC_Init
+  USHORT PowerConnectorDetection;                //Atomic Table,  directly used by various SW components,latest version 1.1
+  USHORT MC_Synchronization;                     //Atomic Table,  indirectly used by various SW components,called from SetMemoryClock
+  USHORT ComputeMemoryEnginePLL;                 //Atomic Table,  indirectly used by various SW components,called from SetMemory/EngineClock
+  USHORT MemoryRefreshConversion;                //Atomic Table,  indirectly used by various SW components,called from SetMemory or SetEngineClock
+  USHORT VRAM_GetCurrentInfoBlock;
+  USHORT DynamicMemorySettings;                  //Atomic Table,  indirectly used by various SW components,called from SetMemoryClock
+  USHORT MemoryTraining;
+  USHORT EnableSpreadSpectrumOnPPLL;             //Atomic Table,  directly used by various SW components,latest version 1.2
+  USHORT TMDSAOutputControl;                     //Atomic Table,  directly used by various SW components,latest version 1.1
+  USHORT SetVoltage;                             //Function Table,directly and/or indirectly used by various SW components,latest version 1.1
+  USHORT DAC1OutputControl;                      //Atomic Table,  directly used by various SW components,latest version 1.1
+  USHORT DAC2OutputControl;                      //Atomic Table,  directly used by various SW components,latest version 1.1
+  USHORT SetupHWAssistedI2CStatus;               //Function Table,only used by Bios, obsolete soon.Switch to use "ReadEDIDFromHWAssistedI2C"
+  USHORT ClockSource;                            //Atomic Table,  indirectly used by various SW components,called from ASIC_Init
+  USHORT MemoryDeviceInit;                       //Atomic Table,  indirectly used by various SW components,called from SetMemoryClock
+  USHORT EnableYUV;                              //Atomic Table,  indirectly used by various SW components,called from EnableVGARender
+  USHORT DIG1EncoderControl;                     //Atomic Table,directly used by various SW components,latest version 1.1
+  USHORT DIG2EncoderControl;                     //Atomic Table,directly used by various SW components,latest version 1.1
+  USHORT DIG1TransmitterControl;                 //Atomic Table,directly used by various SW components,latest version 1.1
+  USHORT DIG2TransmitterControl;	               //Atomic Table,directly used by various SW components,latest version 1.1 
+  USHORT ProcessAuxChannelTransaction;					 //Function Table,only used by Bios
+  USHORT DPEncoderService;											 //Function Table,only used by Bios
+}ATOM_MASTER_LIST_OF_COMMAND_TABLES;   
+
+#define UNIPHYTransmitterControl						     DIG1TransmitterControl
+#define LVTMATransmitterControl							     DIG2TransmitterControl
+#define SetCRTC_DPM_State                                    GetConditionalGoldenSetting
+
+typedef struct _ATOM_MASTER_COMMAND_TABLE
+{
+  ATOM_COMMON_TABLE_HEADER           sHeader;
+  ATOM_MASTER_LIST_OF_COMMAND_TABLES ListOfCommandTables;
+}ATOM_MASTER_COMMAND_TABLE;
+
+typedef struct _ATOM_TABLE_ATTRIBUTE
+{
+  USHORT  WS_SizeInBytes:8;           //[7:0]=Size of workspace in Bytes (in multiple of a dword), 
+  USHORT  PS_SizeInBytes:7;           //[14:8]=Size of parameter space in Bytes (multiple of a dword), 
+  USHORT  UpdatedByUtility:1;         //[15]=Table updated by utility flag
+}ATOM_TABLE_ATTRIBUTE;
+
+// Common header for all command tables.
+//Every table pointed by _ATOM_MASTER_COMMAND_TABLE has this common header. 
+//And the pointer actually points to this header.
+
+typedef struct _ATOM_COMMON_ROM_COMMAND_TABLE_HEADER
+{
+  ATOM_COMMON_TABLE_HEADER CommonHeader;
+  ATOM_TABLE_ATTRIBUTE     TableAttribute;	
+}ATOM_COMMON_ROM_COMMAND_TABLE_HEADER;
+
+
+typedef struct _ASIC_INIT_PARAMETERS
+{
+  ULONG ulDefaultEngineClock;         //In 10Khz unit
+  ULONG ulDefaultMemoryClock;         //In 10Khz unit
+}ASIC_INIT_PARAMETERS;
+
+#define COMPUTE_MEMORY_PLL_PARAM        1
+#define COMPUTE_ENGINE_PLL_PARAM        2
+
+typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS
+{
+  ULONG   ulClock;        //When returen, it's the re-calculated clock based on given Fb_div Post_Div and ref_div
+  UCHAR   ucAction;       //0:reserved //1:Memory //2:Engine  
+  UCHAR   ucReserved;     //may expand to return larger Fbdiv later
+  UCHAR   ucFbDiv;        //return value
+  UCHAR   ucPostDiv;      //return value
+}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS;
+
+typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2
+{
+  ULONG   ulClock;        //When return, [23:0] return real clock 
+  UCHAR   ucAction;       //0:reserved;COMPUTE_MEMORY_PLL_PARAM:Memory;COMPUTE_ENGINE_PLL_PARAM:Engine. it return ref_div to be written to register
+  USHORT  usFbDiv;		    //return Feedback value to be written to register
+  UCHAR   ucPostDiv;      //return post div to be written to register
+}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2;
+#define COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION   COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS
+
+
+#define SET_CLOCK_FREQ_MASK                     0x00FFFFFF  //Clock change tables only take bit [23:0] as the requested clock value
+#define USE_NON_BUS_CLOCK_MASK                  0x01000000  //Applicable to both memory and engine clock change, when set, it uses another clock as the temporary clock (engine uses memory and vice versa)
+#define USE_MEMORY_SELF_REFRESH_MASK            0x02000000	//Only applicable to memory clock change, when set, using memory self refresh during clock transition
+#define SKIP_INTERNAL_MEMORY_PARAMETER_CHANGE   0x04000000  //Only applicable to memory clock change, when set, the table will skip predefined internal memory parameter change
+#define FIRST_TIME_CHANGE_CLOCK									0x08000000	//Applicable to both memory and engine clock change,when set, it means this is 1st time to change clock after ASIC bootup
+#define SKIP_SW_PROGRAM_PLL											0x10000000	//Applicable to both memory and engine clock change, when set, it means the table will not program SPLL/MPLL
+#define USE_SS_ENABLED_PIXEL_CLOCK  USE_NON_BUS_CLOCK_MASK
+
+#define b3USE_NON_BUS_CLOCK_MASK                  0x01       //Applicable to both memory and engine clock change, when set, it uses another clock as the temporary clock (engine uses memory and vice versa)
+#define b3USE_MEMORY_SELF_REFRESH                 0x02	     //Only applicable to memory clock change, when set, using memory self refresh during clock transition
+#define b3SKIP_INTERNAL_MEMORY_PARAMETER_CHANGE   0x04       //Only applicable to memory clock change, when set, the table will skip predefined internal memory parameter change
+#define b3FIRST_TIME_CHANGE_CLOCK									0x08       //Applicable to both memory and engine clock change,when set, it means this is 1st time to change clock after ASIC bootup
+#define b3SKIP_SW_PROGRAM_PLL											0x10			 //Applicable to both memory and engine clock change, when set, it means the table will not program SPLL/MPLL
+
+typedef struct _SET_ENGINE_CLOCK_PARAMETERS
+{
+  ULONG ulTargetEngineClock;          //In 10Khz unit
+}SET_ENGINE_CLOCK_PARAMETERS;
+
+typedef struct _SET_ENGINE_CLOCK_PS_ALLOCATION
+{
+  ULONG ulTargetEngineClock;          //In 10Khz unit
+  COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved;
+}SET_ENGINE_CLOCK_PS_ALLOCATION;
+
+
+typedef struct _SET_MEMORY_CLOCK_PARAMETERS
+{
+  ULONG ulTargetMemoryClock;          //In 10Khz unit
+}SET_MEMORY_CLOCK_PARAMETERS;
+
+typedef struct _SET_MEMORY_CLOCK_PS_ALLOCATION
+{
+  ULONG ulTargetMemoryClock;          //In 10Khz unit
+  COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved;
+}SET_MEMORY_CLOCK_PS_ALLOCATION;
+
+typedef struct _ASIC_INIT_PS_ALLOCATION
+{
+  ASIC_INIT_PARAMETERS sASICInitClocks;
+  SET_ENGINE_CLOCK_PS_ALLOCATION sReserved; //Caller doesn't need to init this structure
+}ASIC_INIT_PS_ALLOCATION;
+
+
+typedef struct _DYNAMIC_CLOCK_GATING_PARAMETERS 
+{
+  UCHAR ucEnable;                     // ATOM_ENABLE or ATOM_DISABLE
+  UCHAR ucPadding[3];
+}DYNAMIC_CLOCK_GATING_PARAMETERS;
+#define  DYNAMIC_CLOCK_GATING_PS_ALLOCATION  DYNAMIC_CLOCK_GATING_PARAMETERS
+
+
+typedef struct _ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS
+{
+  UCHAR ucEnable;                     // ATOM_ENABLE or ATOM_DISABLE
+  UCHAR ucPadding[3];
+}ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS;
+#define ENABLE_ASIC_STATIC_PWR_MGT_PS_ALLOCATION  ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS
+
+
+typedef struct _DAC_LOAD_DETECTION_PARAMETERS
+{
+  USHORT usDeviceID;                  //{ATOM_DEVICE_CRTx_SUPPORT,ATOM_DEVICE_TVx_SUPPORT,ATOM_DEVICE_CVx_SUPPORT}
+  UCHAR  ucDacType;                   //{ATOM_DAC_A,ATOM_DAC_B, ATOM_EXT_DAC}
+  UCHAR  ucMisc;											//Valid only when table revision =1.3 and above
+}DAC_LOAD_DETECTION_PARAMETERS;
+
+// DAC_LOAD_DETECTION_PARAMETERS.ucMisc
+#define DAC_LOAD_MISC_YPrPb						0x01
+
+
+typedef struct _DAC_LOAD_DETECTION_PS_ALLOCATION
+{
+  DAC_LOAD_DETECTION_PARAMETERS            sDacload;
+  ULONG                                    Reserved[2];// Don't set this one, allocation for EXT DAC
+}DAC_LOAD_DETECTION_PS_ALLOCATION;
+
+
+typedef struct _DAC_ENCODER_CONTROL_PARAMETERS 
+{
+  USHORT usPixelClock;                // in 10KHz; for bios convenient
+  UCHAR  ucDacStandard;               // See definition of ATOM_DACx_xxx
+                                      // 1: PS2
+  UCHAR  ucAction;                    // 0: turn off encoder
+                                      // 1: setup and turn on encoder
+}DAC_ENCODER_CONTROL_PARAMETERS;
+
+#define DAC_ENCODER_CONTROL_PS_ALLOCATION  DAC_ENCODER_CONTROL_PARAMETERS
+
+typedef struct _TV_ENCODER_CONTROL_PARAMETERS
+{
+  USHORT usPixelClock;                // in 10KHz; for bios convenient
+  UCHAR  ucTvStandard;                // See definition "ATOM_TV_NTSC ..."
+  UCHAR  ucAction;                    // 0: turn off encoder
+                                      // 1: setup and turn on encoder
+}TV_ENCODER_CONTROL_PARAMETERS;
+
+typedef struct _DIG_ENCODER_CONTROL_PARAMETERS
+{
+  USHORT usPixelClock;		// in 10KHz; for bios convenient
+  UCHAR  ucConfig;		  
+													// [2] Link Select:
+  												// =0: PHY linkA if bfLane<3
+													// =1: PHY linkB if bfLanes<3
+		  										// =0: PHY linkA+B if bfLanes=3
+													// [3] Transmitter Sel
+													// =0: UNIPHY or PCIEPHY
+													// =1: LVTMA 					
+	UCHAR ucAction;				  // =0: turn off encoder					
+	                        // =1: turn on encoder			
+	union{
+  UCHAR ucEncoderMode;
+													// =0: DP   encoder      
+                          // =1: LVDS encoder          
+                          // =2: DVI  encoder  
+                          // =3: HDMI encoder
+                          // =4: SDVO encoder
+	UCHAR ucEncoderType;
+	};
+	UCHAR ucLaneNum;				// how many lanes to enable
+  UCHAR ucReserved[2];
+}DIG_ENCODER_CONTROL_PARAMETERS;
+#define DIG_ENCODER_CONTROL_PS_ALLOCATION			  DIG_ENCODER_CONTROL_PARAMETERS
+#define EXTERNAL_ENCODER_CONTROL_PARAMETER			DIG_ENCODER_CONTROL_PARAMETERS
+#define EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION	DIG_ENCODER_CONTROL_PS_ALLOCATION
+
+//ucConfig
+#define ATOM_ENCODER_CONFIG_LINK_SEL_MASK				  0x04
+#define ATOM_ENCODER_CONFIG_LINKA								  0x00
+#define ATOM_ENCODER_CONFIG_LINKB								  0x04
+#define ATOM_ENCODER_CONFIG_LINKA_B							  ATOM_TRANSMITTER_CONFIG_LINKA
+#define ATOM_ENCODER_CONFIG_TRANSMITTER_SEL_MASK	0x08
+#define ATOM_ENCODER_CONFIG_UNIPHY							  0x00
+#define ATOM_ENCODER_CONFIG_LVTMA								  0x08
+#define ATOM_ENCODER_CONFIG_TRANSMITTER1				  0x00
+#define ATOM_ENCODER_CONFIG_TRANSMITTER2				  0x08
+#define ATOM_ENCODER_CONFIG_DIGB								  0x80			// VBIOS Internal use, outside SW should set this bit=0
+// ucAction
+// ATOM_ENABLE:  Enable Encoder
+// ATOM_DISABLE: Disable Encoder
+
+//ucEncoderMode
+#define ATOM_ENCODER_MODE_DP											0
+#define ATOM_ENCODER_MODE_LVDS										1
+#define ATOM_ENCODER_MODE_DVI											2
+#define ATOM_ENCODER_MODE_HDMI										3
+#define ATOM_ENCODER_MODE_SDVO										4
+#define ATOM_ENCODER_MODE_TV											13
+#define ATOM_ENCODER_MODE_CV											14
+#define ATOM_ENCODER_MODE_CRT											15
+
+typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS
+{
+	union
+	{
+  USHORT usPixelClock;		// in 10KHz; for bios convenient
+	USHORT usInitInfo;			// when init uniphy,lower 8bit is used for connector type defined in objectid.h
+	};
+  UCHAR ucConfig;
+													// [0]=0: 4 lane Link,      
+													//    =1: 8 lane Link ( Dual Links TMDS ) 
+                          // [1]=0: InCoherent mode   
+													//    =1: Coherent Mode										
+													// [2] Link Select:
+  												// =0: PHY linkA   if bfLane<3
+													// =1: PHY linkB   if bfLanes<3
+		  										// =0: PHY linkA+B if bfLanes=3		
+                          // [5:4]PCIE lane Sel
+                          // =0: lane 0~3 or 0~7
+                          // =1: lane 4~7
+                          // =2: lane 8~11 or 8~15
+                          // =3: lane 12~15 
+	UCHAR ucAction;				  // =0: turn off encoder					
+	                        // =1: turn on encoder			
+  UCHAR ucReserved[4];
+}DIG_TRANSMITTER_CONTROL_PARAMETERS;
+
+#define DIG_TRANSMITTER_CONTROL_PS_ALLOCATION		DIG_TRANSMITTER_CONTROL_PARAMETERS					
+
+//ucInitInfo
+#define ATOM_TRAMITTER_INITINFO_CONNECTOR_MASK	0x00ff			
+
+//ucConfig 
+#define ATOM_TRANSMITTER_CONFIG_8LANE_LINK			0x01
+#define ATOM_TRANSMITTER_CONFIG_COHERENT				0x02
+#define ATOM_TRANSMITTER_CONFIG_LINK_SEL_MASK		0x04
+#define ATOM_TRANSMITTER_CONFIG_LINKA						0x00
+#define ATOM_TRANSMITTER_CONFIG_LINKB						0x04
+#define ATOM_TRANSMITTER_CONFIG_LINKA_B					ATOM_TRANSMITTER_CONFIG_LINKA
+#define ATOM_TRANSMITTER_CONFIG_CLKSRC_MASK			0x30
+#define ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL			0x00
+#define ATOM_TRANSMITTER_CONFIG_CLKSRC_PCIE			0x20
+#define ATOM_TRANSMITTER_CONFIG_CLKSRC_XTALIN		0x30
+#define ATOM_TRANSMITTER_CONFIG_LANE_SEL_MASK		0xc0
+#define ATOM_TRANSMITTER_CONFIG_LANE_0_3				0x00
+#define ATOM_TRANSMITTER_CONFIG_LANE_0_7				0x00
+#define ATOM_TRANSMITTER_CONFIG_LANE_4_7				0x40
+#define ATOM_TRANSMITTER_CONFIG_LANE_8_11				0x80
+#define ATOM_TRANSMITTER_CONFIG_LANE_8_15				0x80
+#define ATOM_TRANSMITTER_CONFIG_LANE_12_15			0xc0
+
+//ucAction
+#define ATOM_TRANSMITTER_ACTION_DISABLE					       0
+#define ATOM_TRANSMITTER_ACTION_ENABLE					       1
+#define ATOM_TRANSMITTER_ACTION_LCD_BLOFF				       2
+#define ATOM_TRANSMITTER_ACTION_LCD_BLON				       3
+#define ATOM_TRANSMITTER_ACTION_BL_BRIGHTNESS_CONTROL  4
+#define ATOM_TRANSMITTER_ACTION_LCD_SELFTEST_START		 5
+#define ATOM_TRANSMITTER_ACTION_LCD_SELFTEST_STOP			 6
+#define ATOM_TRANSMITTER_ACTION_INIT						       7
+#define ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT		       8
+#define ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT	       9
+#define ATOM_TRANSMITTER_ACTION_SETUP						       10
+
+
+/****************************Device Output Control Command Table Definitions**********************/
+typedef struct _DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS
+{
+  UCHAR  ucAction;                    // Possible input:ATOM_ENABLE||ATOMDISABLE
+                                      // When the display is LCD, in addition to above:
+                                      // ATOM_LCD_BLOFF|| ATOM_LCD_BLON ||ATOM_LCD_BL_BRIGHTNESS_CONTROL||ATOM_LCD_SELFTEST_START||
+                                      // ATOM_LCD_SELFTEST_STOP
+                                      
+  UCHAR  aucPadding[3];               // padding to DWORD aligned
+}DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS;
+
+#define DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS
+
+
+#define CRT1_OUTPUT_CONTROL_PARAMETERS     DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS 
+#define CRT1_OUTPUT_CONTROL_PS_ALLOCATION  DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION
+
+#define CRT2_OUTPUT_CONTROL_PARAMETERS     DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS 
+#define CRT2_OUTPUT_CONTROL_PS_ALLOCATION  DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION
+
+#define CV1_OUTPUT_CONTROL_PARAMETERS      DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS
+#define CV1_OUTPUT_CONTROL_PS_ALLOCATION   DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION
+
+#define TV1_OUTPUT_CONTROL_PARAMETERS      DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS
+#define TV1_OUTPUT_CONTROL_PS_ALLOCATION   DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION
+
+#define DFP1_OUTPUT_CONTROL_PARAMETERS     DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS
+#define DFP1_OUTPUT_CONTROL_PS_ALLOCATION  DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION
+
+#define DFP2_OUTPUT_CONTROL_PARAMETERS     DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS
+#define DFP2_OUTPUT_CONTROL_PS_ALLOCATION  DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION
+
+#define LCD1_OUTPUT_CONTROL_PARAMETERS     DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS
+#define LCD1_OUTPUT_CONTROL_PS_ALLOCATION  DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION
+
+#define DVO_OUTPUT_CONTROL_PARAMETERS      DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS
+#define DVO_OUTPUT_CONTROL_PS_ALLOCATION   DIG_TRANSMITTER_CONTROL_PS_ALLOCATION
+#define DVO_OUTPUT_CONTROL_PARAMETERS_V3	 DIG_TRANSMITTER_CONTROL_PARAMETERS
+
+/**************************************************************************/
+typedef struct _BLANK_CRTC_PARAMETERS
+{
+  UCHAR  ucCRTC;                    	// ATOM_CRTC1 or ATOM_CRTC2
+  UCHAR  ucBlanking;                  // ATOM_BLANKING or ATOM_BLANKINGOFF
+  USHORT usBlackColorRCr;
+  USHORT usBlackColorGY;
+  USHORT usBlackColorBCb;
+}BLANK_CRTC_PARAMETERS;
+#define BLANK_CRTC_PS_ALLOCATION    BLANK_CRTC_PARAMETERS
+
+
+typedef struct _ENABLE_CRTC_PARAMETERS
+{
+  UCHAR ucCRTC;                    	  // ATOM_CRTC1 or ATOM_CRTC2
+  UCHAR ucEnable;                     // ATOM_ENABLE or ATOM_DISABLE 
+  UCHAR ucPadding[2];
+}ENABLE_CRTC_PARAMETERS;
+#define ENABLE_CRTC_PS_ALLOCATION   ENABLE_CRTC_PARAMETERS
+
+
+typedef struct _SET_CRTC_OVERSCAN_PARAMETERS
+{
+  USHORT usOverscanRight;             // right
+  USHORT usOverscanLeft;              // left
+  USHORT usOverscanBottom;            // bottom
+  USHORT usOverscanTop;               // top
+  UCHAR  ucCRTC;                      // ATOM_CRTC1 or ATOM_CRTC2
+  UCHAR  ucPadding[3];
+}SET_CRTC_OVERSCAN_PARAMETERS;
+#define SET_CRTC_OVERSCAN_PS_ALLOCATION  SET_CRTC_OVERSCAN_PARAMETERS
+
+
+typedef struct _SET_CRTC_REPLICATION_PARAMETERS
+{
+  UCHAR ucH_Replication;              // horizontal replication
+  UCHAR ucV_Replication;              // vertical replication
+  UCHAR usCRTC;                       // ATOM_CRTC1 or ATOM_CRTC2
+  UCHAR ucPadding;
+}SET_CRTC_REPLICATION_PARAMETERS;
+#define SET_CRTC_REPLICATION_PS_ALLOCATION  SET_CRTC_REPLICATION_PARAMETERS
+
+
+typedef struct _SELECT_CRTC_SOURCE_PARAMETERS
+{
+  UCHAR ucCRTC;                    	  // ATOM_CRTC1 or ATOM_CRTC2
+  UCHAR ucDevice;                     // ATOM_DEVICE_CRT1|ATOM_DEVICE_CRT2|....
+  UCHAR ucPadding[2];
+}SELECT_CRTC_SOURCE_PARAMETERS;
+#define SELECT_CRTC_SOURCE_PS_ALLOCATION  SELECT_CRTC_SOURCE_PARAMETERS
+
+typedef struct _SELECT_CRTC_SOURCE_PARAMETERS_V2
+{
+  UCHAR ucCRTC;                    	  // ATOM_CRTC1 or ATOM_CRTC2
+  UCHAR ucEncoderID;                  // DAC1/DAC2/TVOUT/DIG1/DIG2/DVO
+  UCHAR ucEncodeMode;									// Encoding mode, only valid when using DIG1/DIG2/DVO
+  UCHAR ucPadding;
+}SELECT_CRTC_SOURCE_PARAMETERS_V2;
+
+//ucEncoderID
+//#define ASIC_INT_DAC1_ENCODER_ID    						0x00 
+//#define ASIC_INT_TV_ENCODER_ID									0x02
+//#define ASIC_INT_DIG1_ENCODER_ID								0x03
+//#define ASIC_INT_DAC2_ENCODER_ID								0x04
+//#define ASIC_EXT_TV_ENCODER_ID									0x06
+//#define ASIC_INT_DVO_ENCODER_ID									0x07
+//#define ASIC_INT_DIG2_ENCODER_ID								0x09
+//#define ASIC_EXT_DIG_ENCODER_ID									0x05
+
+//ucEncodeMode
+//#define ATOM_ENCODER_MODE_DP										0
+//#define ATOM_ENCODER_MODE_LVDS									1
+//#define ATOM_ENCODER_MODE_DVI										2
+//#define ATOM_ENCODER_MODE_HDMI									3
+//#define ATOM_ENCODER_MODE_SDVO									4
+//#define ATOM_ENCODER_MODE_TV										13
+//#define ATOM_ENCODER_MODE_CV										14
+//#define ATOM_ENCODER_MODE_CRT										15
+
+//Major revision=1., Minor revision=1
+typedef struct _PIXEL_CLOCK_PARAMETERS
+{
+  USHORT usPixelClock;                // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div)
+                                      // 0 means disable PPLL
+  USHORT usRefDiv;                    // Reference divider
+  USHORT usFbDiv;                     // feedback divider
+  UCHAR  ucPostDiv;                   // post divider	
+  UCHAR  ucFracFbDiv;                 // fractional feedback divider
+  UCHAR  ucPpll;                      // ATOM_PPLL1 or ATOM_PPL2
+  UCHAR  ucRefDivSrc;                 // ATOM_PJITTER or ATO_NONPJITTER
+  UCHAR  ucCRTC;                      // Which CRTC uses this Ppll
+  UCHAR  ucPadding;
+}PIXEL_CLOCK_PARAMETERS;
+
+
+//Major revision=1., Minor revision=2, add ucMiscIfno
+//ucMiscInfo:
+#define MISC_FORCE_REPROG_PIXEL_CLOCK 0x1
+#define MISC_DEVICE_INDEX_MASK        0xF0
+#define MISC_DEVICE_INDEX_SHIFT       4
+
+typedef struct _PIXEL_CLOCK_PARAMETERS_V2
+{
+  USHORT usPixelClock;                // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div)
+                                      // 0 means disable PPLL
+  USHORT usRefDiv;                    // Reference divider
+  USHORT usFbDiv;                     // feedback divider
+  UCHAR  ucPostDiv;                   // post divider	
+  UCHAR  ucFracFbDiv;                 // fractional feedback divider
+  UCHAR  ucPpll;                      // ATOM_PPLL1 or ATOM_PPL2
+  UCHAR  ucRefDivSrc;                 // ATOM_PJITTER or ATO_NONPJITTER
+  UCHAR  ucCRTC;                      // Which CRTC uses this Ppll
+  UCHAR  ucMiscInfo;                  // Different bits for different purpose, bit [7:4] as device index, bit[0]=Force prog
+}PIXEL_CLOCK_PARAMETERS_V2;
+
+//Major revision=1., Minor revision=3, structure/definition change
+//ucEncoderMode:
+//ATOM_ENCODER_MODE_DP
+//ATOM_ENOCDER_MODE_LVDS
+//ATOM_ENOCDER_MODE_DVI
+//ATOM_ENOCDER_MODE_HDMI
+//ATOM_ENOCDER_MODE_SDVO
+//ATOM_ENCODER_MODE_TV										13
+//ATOM_ENCODER_MODE_CV										14
+//ATOM_ENCODER_MODE_CRT										15
+
+//ucMiscInfo: also changed, see below
+#define PIXEL_CLOCK_MISC_FORCE_PROG_PPLL						0x01
+#define PIXEL_CLOCK_MISC_VGA_MODE										0x02
+#define PIXEL_CLOCK_MISC_CRTC_SEL_MASK							0x04
+#define PIXEL_CLOCK_MISC_CRTC_SEL_CRTC1							0x00
+#define PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2							0x04
+
+typedef struct _PIXEL_CLOCK_PARAMETERS_V3
+{
+  USHORT usPixelClock;                // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div)
+                                      // 0 means disable PPLL. For VGA PPLL,make sure this value is not 0.
+  USHORT usRefDiv;                    // Reference divider
+  USHORT usFbDiv;                     // feedback divider
+  UCHAR  ucPostDiv;                   // post divider	
+  UCHAR  ucFracFbDiv;                 // fractional feedback divider
+  UCHAR  ucPpll;                      // ATOM_PPLL1 or ATOM_PPL2
+  UCHAR  ucTransmitterId;             // graphic encoder id defined in objectId.h
+  UCHAR  ucEncoderMode;               // encoder type defined as ATOM_ENCODER_MODE_DP/DVI/HDMI/
+  UCHAR  ucMiscInfo;                  // bit[0]=Force program, bit[1]= set pclk for VGA, b[2]= CRTC sel
+}PIXEL_CLOCK_PARAMETERS_V3;
+
+#define PIXEL_CLOCK_PARAMETERS_LAST			PIXEL_CLOCK_PARAMETERS_V2
+#define GET_PIXEL_CLOCK_PS_ALLOCATION		PIXEL_CLOCK_PARAMETERS_LAST
+
+typedef struct _ADJUST_DISPLAY_PLL_PARAMETERS
+{
+	USHORT usPixelClock;
+	UCHAR ucTransmitterID;
+	UCHAR ucEncodeMode;
+	union
+	{
+		UCHAR ucDVOConfig;									//if DVO, need passing link rate and output 12bitlow or 24bit
+		UCHAR ucConfig;											//if none DVO, not defined yet
+	};
+	UCHAR ucReserved[3];
+}ADJUST_DISPLAY_PLL_PARAMETERS;
+
+#define ADJUST_DISPLAY_PLL_PS_ALLOCATION			ADJUST_DISPLAY_PLL_PARAMETERS
+
+typedef struct _ENABLE_YUV_PARAMETERS
+{
+  UCHAR ucEnable;                     // ATOM_ENABLE:Enable YUV or ATOM_DISABLE:Disable YUV (RGB)
+  UCHAR ucCRTC;                       // Which CRTC needs this YUV or RGB format
+  UCHAR ucPadding[2];
+}ENABLE_YUV_PARAMETERS;
+#define ENABLE_YUV_PS_ALLOCATION ENABLE_YUV_PARAMETERS
+
+typedef struct _GET_MEMORY_CLOCK_PARAMETERS
+{
+  ULONG ulReturnMemoryClock;          // current memory speed in 10KHz unit
+} GET_MEMORY_CLOCK_PARAMETERS;
+#define GET_MEMORY_CLOCK_PS_ALLOCATION  GET_MEMORY_CLOCK_PARAMETERS
+
+
+typedef struct _GET_ENGINE_CLOCK_PARAMETERS
+{
+  ULONG ulReturnEngineClock;          // current engine speed in 10KHz unit
+} GET_ENGINE_CLOCK_PARAMETERS;
+#define GET_ENGINE_CLOCK_PS_ALLOCATION  GET_ENGINE_CLOCK_PARAMETERS
+
+
+//Maxium 8 bytes,the data read in will be placed in the parameter space.
+//Read operaion successeful when the paramter space is non-zero, otherwise read operation failed
+typedef struct _READ_EDID_FROM_HW_I2C_DATA_PARAMETERS
+{
+  USHORT    usPrescale;         //Ratio between Engine clock and I2C clock
+  USHORT    usVRAMAddress;      //Adress in Frame Buffer where to pace raw EDID
+  USHORT    usStatus;           //When use output: lower byte EDID checksum, high byte hardware status
+                                //WHen use input:  lower byte as 'byte to read':currently limited to 128byte or 1byte
+  UCHAR     ucSlaveAddr;        //Read from which slave
+  UCHAR     ucLineNumber;       //Read from which HW assisted line
+}READ_EDID_FROM_HW_I2C_DATA_PARAMETERS;
+#define READ_EDID_FROM_HW_I2C_DATA_PS_ALLOCATION  READ_EDID_FROM_HW_I2C_DATA_PARAMETERS
+
+
+#define  ATOM_WRITE_I2C_FORMAT_PSOFFSET_PSDATABYTE                  0
+#define  ATOM_WRITE_I2C_FORMAT_PSOFFSET_PSTWODATABYTES              1
+#define  ATOM_WRITE_I2C_FORMAT_PSCOUNTER_PSOFFSET_IDDATABLOCK       2
+#define  ATOM_WRITE_I2C_FORMAT_PSCOUNTER_IDOFFSET_PLUS_IDDATABLOCK  3
+#define  ATOM_WRITE_I2C_FORMAT_IDCOUNTER_IDOFFSET_IDDATABLOCK       4
+
+typedef struct _WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS
+{
+  USHORT    usPrescale;         //Ratio between Engine clock and I2C clock
+  USHORT    usByteOffset;       //Write to which byte
+                                //Upper portion of usByteOffset is Format of data 
+                                //1bytePS+offsetPS
+                                //2bytesPS+offsetPS
+                                //blockID+offsetPS
+                                //blockID+offsetID
+                                //blockID+counterID+offsetID
+  UCHAR     ucData;             //PS data1
+  UCHAR     ucStatus;           //Status byte 1=success, 2=failure, Also is used as PS data2
+  UCHAR     ucSlaveAddr;        //Write to which slave
+  UCHAR     ucLineNumber;       //Write from which HW assisted line
+}WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS;
+
+#define WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION  WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS
+
+typedef struct _SET_UP_HW_I2C_DATA_PARAMETERS
+{
+  USHORT    usPrescale;         //Ratio between Engine clock and I2C clock
+  UCHAR     ucSlaveAddr;        //Write to which slave
+  UCHAR     ucLineNumber;       //Write from which HW assisted line
+}SET_UP_HW_I2C_DATA_PARAMETERS;
+
+
+/**************************************************************************/
+#define SPEED_FAN_CONTROL_PS_ALLOCATION   WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS
+
+typedef struct	_POWER_CONNECTOR_DETECTION_PARAMETERS
+{
+  UCHAR   ucPowerConnectorStatus;      //Used for return value 0: detected, 1:not detected
+	UCHAR   ucPwrBehaviorId;							
+	USHORT	usPwrBudget;								 //how much power currently boot to in unit of watt
+}POWER_CONNECTOR_DETECTION_PARAMETERS;
+
+typedef struct POWER_CONNECTOR_DETECTION_PS_ALLOCATION
+{                               
+  UCHAR   ucPowerConnectorStatus;      //Used for return value 0: detected, 1:not detected
+	UCHAR   ucReserved;
+	USHORT	usPwrBudget;								 //how much power currently boot to in unit of watt
+  WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION    sReserved;
+}POWER_CONNECTOR_DETECTION_PS_ALLOCATION;
+
+/****************************LVDS SS Command Table Definitions**********************/
+typedef struct	_ENABLE_LVDS_SS_PARAMETERS
+{
+  USHORT  usSpreadSpectrumPercentage;       
+  UCHAR   ucSpreadSpectrumType;           //Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD
+  UCHAR   ucSpreadSpectrumStepSize_Delay; //bits3:2 SS_STEP_SIZE; bit 6:4 SS_DELAY
+  UCHAR   ucEnable;                       //ATOM_ENABLE or ATOM_DISABLE
+  UCHAR   ucPadding[3];
+}ENABLE_LVDS_SS_PARAMETERS;
+
+//ucTableFormatRevision=1,ucTableContentRevision=2
+typedef struct	_ENABLE_LVDS_SS_PARAMETERS_V2
+{
+  USHORT  usSpreadSpectrumPercentage;       
+  UCHAR   ucSpreadSpectrumType;           //Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD
+  UCHAR   ucSpreadSpectrumStep;           //
+  UCHAR   ucEnable;                       //ATOM_ENABLE or ATOM_DISABLE
+  UCHAR   ucSpreadSpectrumDelay;
+  UCHAR   ucSpreadSpectrumRange;
+  UCHAR   ucPadding;
+}ENABLE_LVDS_SS_PARAMETERS_V2;
+
+//This new structure is based on ENABLE_LVDS_SS_PARAMETERS but expands to SS on PPLL, so other devices can use SS.
+typedef struct	_ENABLE_SPREAD_SPECTRUM_ON_PPLL
+{
+  USHORT  usSpreadSpectrumPercentage;
+  UCHAR   ucSpreadSpectrumType;           // Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD
+  UCHAR   ucSpreadSpectrumStep;           //
+  UCHAR   ucEnable;                       // ATOM_ENABLE or ATOM_DISABLE
+  UCHAR   ucSpreadSpectrumDelay;
+  UCHAR   ucSpreadSpectrumRange;
+  UCHAR   ucPpll;												  // ATOM_PPLL1/ATOM_PPLL2
+}ENABLE_SPREAD_SPECTRUM_ON_PPLL;
+
+#define ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION  ENABLE_SPREAD_SPECTRUM_ON_PPLL
+
+/**************************************************************************/
+
+typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION
+{
+  PIXEL_CLOCK_PARAMETERS sPCLKInput;
+  ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;//Caller doesn't need to init this portion 
+}SET_PIXEL_CLOCK_PS_ALLOCATION;
+
+#define ENABLE_VGA_RENDER_PS_ALLOCATION   SET_PIXEL_CLOCK_PS_ALLOCATION
+
+typedef struct	_MEMORY_TRAINING_PARAMETERS
+{
+  ULONG ulTargetMemoryClock;          //In 10Khz unit
+}MEMORY_TRAINING_PARAMETERS;
+#define MEMORY_TRAINING_PS_ALLOCATION MEMORY_TRAINING_PARAMETERS
+
+
+
+/****************************LVDS and other encoder command table definitions **********************/
+typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS
+{
+  USHORT usPixelClock;  // in 10KHz; for bios convenient
+  UCHAR  ucMisc;        // bit0=0: Enable single link
+                        //     =1: Enable dual link
+                        // Bit1=0: 666RGB
+                        //     =1: 888RGB
+  UCHAR  ucAction;      // 0: turn off encoder
+                        // 1: setup and turn on encoder
+}LVDS_ENCODER_CONTROL_PARAMETERS;
+
+#define LVDS_ENCODER_CONTROL_PS_ALLOCATION  LVDS_ENCODER_CONTROL_PARAMETERS
+   
+#define TMDS1_ENCODER_CONTROL_PARAMETERS    LVDS_ENCODER_CONTROL_PARAMETERS
+#define TMDS1_ENCODER_CONTROL_PS_ALLOCATION TMDS1_ENCODER_CONTROL_PARAMETERS
+
+#define TMDS2_ENCODER_CONTROL_PARAMETERS    TMDS1_ENCODER_CONTROL_PARAMETERS
+#define TMDS2_ENCODER_CONTROL_PS_ALLOCATION TMDS2_ENCODER_CONTROL_PARAMETERS
+
+typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS
+{                               
+  UCHAR    ucEnable;            // Enable or Disable External TMDS encoder
+  UCHAR    ucMisc;              // Bit0=0:Enable Single link;=1:Enable Dual link;Bit1 {=0:666RGB, =1:888RGB}
+  UCHAR    ucPadding[2];
+}ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS;
+
+typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION
+{                               
+  ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS    sXTmdsEncoder;
+  WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION   sReserved;     //Caller doesn't need to init this portion
+}ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION;
+
+
+//ucTableFormatRevision=1,ucTableContentRevision=2
+typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS_V2
+{
+  USHORT usPixelClock;  // in 10KHz; for bios convenient
+  UCHAR  ucMisc;        // see PANEL_ENCODER_MISC_xx defintions below
+  UCHAR  ucAction;      // 0: turn off encoder
+                        // 1: setup and turn on encoder
+  UCHAR  ucTruncate;    // bit0=0: Disable truncate
+                        //     =1: Enable truncate
+                        // bit4=0: 666RGB
+                        //     =1: 888RGB
+  UCHAR  ucSpatial;     // bit0=0: Disable spatial dithering
+                        //     =1: Enable spatial dithering
+                        // bit4=0: 666RGB
+                        //     =1: 888RGB
+  UCHAR  ucTemporal;    // bit0=0: Disable temporal dithering
+                        //     =1: Enable temporal dithering
+                        // bit4=0: 666RGB
+                        //     =1: 888RGB
+                        // bit5=0: Gray level 2
+                        //     =1: Gray level 4
+  UCHAR  ucFRC;         // bit4=0: 25FRC_SEL pattern E
+                        //     =1: 25FRC_SEL pattern F
+                        // bit6:5=0: 50FRC_SEL pattern A
+                        //       =1: 50FRC_SEL pattern B
+                        //       =2: 50FRC_SEL pattern C
+                        //       =3: 50FRC_SEL pattern D
+                        // bit7=0: 75FRC_SEL pattern E
+                        //     =1: 75FRC_SEL pattern F
+}LVDS_ENCODER_CONTROL_PARAMETERS_V2;
+
+#define LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2  LVDS_ENCODER_CONTROL_PARAMETERS_V2
+   
+#define TMDS1_ENCODER_CONTROL_PARAMETERS_V2    LVDS_ENCODER_CONTROL_PARAMETERS_V2
+#define TMDS1_ENCODER_CONTROL_PS_ALLOCATION_V2 TMDS1_ENCODER_CONTROL_PARAMETERS_V2
+  
+#define TMDS2_ENCODER_CONTROL_PARAMETERS_V2    TMDS1_ENCODER_CONTROL_PARAMETERS_V2
+#define TMDS2_ENCODER_CONTROL_PS_ALLOCATION_V2 TMDS2_ENCODER_CONTROL_PARAMETERS_V2
+#define ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS_V2  LVDS_ENCODER_CONTROL_PARAMETERS_V2
+
+typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION_V2
+{                               
+  ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS_V2    sXTmdsEncoder;
+  WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION      sReserved;     //Caller doesn't need to init this portion
+}ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION_V2;
+
+
+//ucTableFormatRevision=1,ucTableContentRevision=3
+
+//ucDVOConfig:
+#define DVO_ENCODER_CONFIG_RATE_SEL							0x01
+#define DVO_ENCODER_CONFIG_DDR_SPEED						0x00
+#define DVO_ENCODER_CONFIG_SDR_SPEED						0x01
+#define DVO_ENCODER_CONFIG_OUTPUT_SEL						0x0c
+#define DVO_ENCODER_CONFIG_LOW12BIT							0x00
+#define DVO_ENCODER_CONFIG_UPPER12BIT						0x04
+#define DVO_ENCODER_CONFIG_24BIT								0x08
+
+typedef struct _DVO_ENCODER_CONTROL_PARAMETERS_V3
+{
+  USHORT usPixelClock; 
+  UCHAR  ucDVOConfig;
+  UCHAR  ucAction;														//ATOM_ENABLE/ATOM_DISABLE/ATOM_HPD_INIT
+  UCHAR  ucReseved[4];
+}DVO_ENCODER_CONTROL_PARAMETERS_V3;
+#define DVO_ENCODER_CONTROL_PS_ALLOCATION_V3	DVO_ENCODER_CONTROL_PARAMETERS_V3
+
+//ucTableFormatRevision=1
+//ucTableContentRevision=3 structure is not changed but usMisc add bit 1 as another input for 
+// bit1=0: non-coherent mode
+//     =1: coherent mode
+
+#define LVDS_ENCODER_CONTROL_PARAMETERS_V3     LVDS_ENCODER_CONTROL_PARAMETERS_V2
+#define LVDS_ENCODER_CONTROL_PS_ALLOCATION_V3  LVDS_ENCODER_CONTROL_PARAMETERS_V3
+
+#define TMDS1_ENCODER_CONTROL_PARAMETERS_V3    LVDS_ENCODER_CONTROL_PARAMETERS_V3
+#define TMDS1_ENCODER_CONTROL_PS_ALLOCATION_V3 TMDS1_ENCODER_CONTROL_PARAMETERS_V3
+
+#define TMDS2_ENCODER_CONTROL_PARAMETERS_V3    LVDS_ENCODER_CONTROL_PARAMETERS_V3
+#define TMDS2_ENCODER_CONTROL_PS_ALLOCATION_V3 TMDS2_ENCODER_CONTROL_PARAMETERS_V3
+
+//==========================================================================================
+//Only change is here next time when changing encoder parameter definitions again!
+#define LVDS_ENCODER_CONTROL_PARAMETERS_LAST     LVDS_ENCODER_CONTROL_PARAMETERS_V3
+#define LVDS_ENCODER_CONTROL_PS_ALLOCATION_LAST  LVDS_ENCODER_CONTROL_PARAMETERS_LAST
+
+#define TMDS1_ENCODER_CONTROL_PARAMETERS_LAST    LVDS_ENCODER_CONTROL_PARAMETERS_V3
+#define TMDS1_ENCODER_CONTROL_PS_ALLOCATION_LAST TMDS1_ENCODER_CONTROL_PARAMETERS_LAST
+
+#define TMDS2_ENCODER_CONTROL_PARAMETERS_LAST    LVDS_ENCODER_CONTROL_PARAMETERS_V3
+#define TMDS2_ENCODER_CONTROL_PS_ALLOCATION_LAST TMDS2_ENCODER_CONTROL_PARAMETERS_LAST
+
+#define DVO_ENCODER_CONTROL_PARAMETERS_LAST      DVO_ENCODER_CONTROL_PARAMETERS
+#define DVO_ENCODER_CONTROL_PS_ALLOCATION_LAST   DVO_ENCODER_CONTROL_PS_ALLOCATION
+
+//==========================================================================================
+#define PANEL_ENCODER_MISC_DUAL                0x01
+#define PANEL_ENCODER_MISC_COHERENT            0x02
+#define	PANEL_ENCODER_MISC_TMDS_LINKB					 0x04
+#define	PANEL_ENCODER_MISC_HDMI_TYPE					 0x08
+
+#define PANEL_ENCODER_ACTION_DISABLE           ATOM_DISABLE
+#define PANEL_ENCODER_ACTION_ENABLE            ATOM_ENABLE
+#define PANEL_ENCODER_ACTION_COHERENTSEQ       (ATOM_ENABLE+1)
+
+#define PANEL_ENCODER_TRUNCATE_EN              0x01
+#define PANEL_ENCODER_TRUNCATE_DEPTH           0x10
+#define PANEL_ENCODER_SPATIAL_DITHER_EN        0x01
+#define PANEL_ENCODER_SPATIAL_DITHER_DEPTH     0x10
+#define PANEL_ENCODER_TEMPORAL_DITHER_EN       0x01
+#define PANEL_ENCODER_TEMPORAL_DITHER_DEPTH    0x10
+#define PANEL_ENCODER_TEMPORAL_LEVEL_4         0x20
+#define PANEL_ENCODER_25FRC_MASK               0x10
+#define PANEL_ENCODER_25FRC_E                  0x00
+#define PANEL_ENCODER_25FRC_F                  0x10
+#define PANEL_ENCODER_50FRC_MASK               0x60
+#define PANEL_ENCODER_50FRC_A                  0x00
+#define PANEL_ENCODER_50FRC_B                  0x20
+#define PANEL_ENCODER_50FRC_C                  0x40
+#define PANEL_ENCODER_50FRC_D                  0x60
+#define PANEL_ENCODER_75FRC_MASK               0x80
+#define PANEL_ENCODER_75FRC_E                  0x00
+#define PANEL_ENCODER_75FRC_F                  0x80
+
+/**************************************************************************/
+
+#define SET_VOLTAGE_TYPE_ASIC_VDDC             1
+#define SET_VOLTAGE_TYPE_ASIC_MVDDC            2
+#define SET_VOLTAGE_TYPE_ASIC_MVDDQ            3
+#define SET_VOLTAGE_TYPE_ASIC_VDDCI            4
+
+#define SET_ASIC_VOLTAGE_MODE_ALL_SOURCE       0x1
+#define SET_ASIC_VOLTAGE_MODE_SOURCE_A         0x2
+#define SET_ASIC_VOLTAGE_MODE_SOURCE_B         0x4
+
+#define	SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE			 0x0
+#define	SET_ASIC_VOLTAGE_MODE_GET_GPIOVAL			 0x1	
+#define	SET_ASIC_VOLTAGE_MODE_GET_GPIOMASK		 0x2
+
+typedef struct	_SET_VOLTAGE_PARAMETERS
+{
+  UCHAR    ucVoltageType;               // To tell which voltage to set up, VDDC/MVDDC/MVDDQ
+  UCHAR    ucVoltageMode;               // To set all, to set source A or source B or ...
+  UCHAR    ucVoltageIndex;              // An index to tell which voltage level
+  UCHAR    ucReserved;          
+}SET_VOLTAGE_PARAMETERS;
+
+
+typedef struct	_SET_VOLTAGE_PARAMETERS_V2
+{
+  UCHAR    ucVoltageType;               // To tell which voltage to set up, VDDC/MVDDC/MVDDQ
+  UCHAR    ucVoltageMode;               // Not used, maybe use for state machine for differen power mode
+  USHORT   usVoltageLevel;              // real voltage level
+}SET_VOLTAGE_PARAMETERS_V2;
+
+
+typedef struct _SET_VOLTAGE_PS_ALLOCATION
+{
+  SET_VOLTAGE_PARAMETERS sASICSetVoltage;
+  WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved;
+}SET_VOLTAGE_PS_ALLOCATION;
+
+typedef struct _TV_ENCODER_CONTROL_PS_ALLOCATION
+{
+  TV_ENCODER_CONTROL_PARAMETERS sTVEncoder;          
+  WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION    sReserved; // Don't set this one
+}TV_ENCODER_CONTROL_PS_ALLOCATION;
+
+//==============================Data Table Portion====================================
+
+#ifdef	UEFI_BUILD
+	#define	UTEMP	USHORT
+	#define	USHORT	void*
+#endif
+
+typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES
+{
+  USHORT        UtilityPipeLine;	        // Offest for the utility to get parser info,Don't change this position!
+  USHORT        MultimediaCapabilityInfo; // Only used by MM Lib,latest version 1.1, not configuable from Bios, need to include the table to build Bios 
+  USHORT        MultimediaConfigInfo;     // Only used by MM Lib,latest version 2.1, not configuable from Bios, need to include the table to build Bios
+  USHORT        StandardVESA_Timing;      // Only used by Bios
+  USHORT        FirmwareInfo;             // Shared by various SW components,latest version 1.4
+  USHORT        DAC_Info;                 // Will be obsolete from R600
+  USHORT        LVDS_Info;                // Shared by various SW components,latest version 1.1 
+  USHORT        TMDS_Info;                // Will be obsolete from R600
+  USHORT        AnalogTV_Info;            // Shared by various SW components,latest version 1.1 
+  USHORT        SupportedDevicesInfo;     // Will be obsolete from R600
+  USHORT        GPIO_I2C_Info;            // Shared by various SW components,latest version 1.2 will be used from R600           
+  USHORT        VRAM_UsageByFirmware;     // Shared by various SW components,latest version 1.3 will be used from R600
+  USHORT        GPIO_Pin_LUT;             // Shared by various SW components,latest version 1.1
+  USHORT        VESA_ToInternalModeLUT;   // Only used by Bios
+  USHORT        ComponentVideoInfo;       // Shared by various SW components,latest version 2.1 will be used from R600
+  USHORT        PowerPlayInfo;            // Shared by various SW components,latest version 2.1,new design from R600
+  USHORT        CompassionateData;        // Will be obsolete from R600
+  USHORT        SaveRestoreInfo;          // Only used by Bios
+  USHORT        PPLL_SS_Info;             // Shared by various SW components,latest version 1.2, used to call SS_Info, change to new name because of int ASIC SS info
+  USHORT        OemInfo;                  // Defined and used by external SW, should be obsolete soon
+  USHORT        XTMDS_Info;               // Will be obsolete from R600
+  USHORT        MclkSS_Info;              // Shared by various SW components,latest version 1.1, only enabled when ext SS chip is used
+  USHORT        Object_Header;            // Shared by various SW components,latest version 1.1
+  USHORT        IndirectIOAccess;         // Only used by Bios,this table position can't change at all!!
+  USHORT        MC_InitParameter;         // Only used by command table
+  USHORT        ASIC_VDDC_Info;						// Will be obsolete from R600
+  USHORT        ASIC_InternalSS_Info;			// New tabel name from R600, used to be called "ASIC_MVDDC_Info"
+  USHORT        TV_VideoMode;							// Only used by command table
+  USHORT        VRAM_Info;								// Only used by command table, latest version 1.3
+  USHORT        MemoryTrainingInfo;				// Used for VBIOS and Diag utility for memory training purpose since R600. the new table rev start from 2.1
+  USHORT        IntegratedSystemInfo;			// Shared by various SW components
+  USHORT        ASIC_ProfilingInfo;				// New table name from R600, used to be called "ASIC_VDDCI_Info" for pre-R600
+  USHORT        VoltageObjectInfo;				// Shared by various SW components, latest version 1.1
+	USHORT				PowerSourceInfo;					// Shared by various SW components, latest versoin 1.1
+}ATOM_MASTER_LIST_OF_DATA_TABLES;
+
+#ifdef	UEFI_BUILD
+	#define	USHORT	UTEMP
+#endif
+
+
+typedef struct _ATOM_MASTER_DATA_TABLE
+{ 
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  ATOM_MASTER_LIST_OF_DATA_TABLES   ListOfDataTables;
+}ATOM_MASTER_DATA_TABLE;
+
+
+typedef struct _ATOM_MULTIMEDIA_CAPABILITY_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  ULONG                    ulSignature;      // HW info table signature string "$ATI"
+  UCHAR                    ucI2C_Type;       // I2C type (normal GP_IO, ImpactTV GP_IO, Dedicated I2C pin, etc)
+  UCHAR                    ucTV_OutInfo;     // Type of TV out supported (3:0) and video out crystal frequency (6:4) and TV data port (7)
+  UCHAR                    ucVideoPortInfo;  // Provides the video port capabilities
+  UCHAR                    ucHostPortInfo;   // Provides host port configuration information
+}ATOM_MULTIMEDIA_CAPABILITY_INFO;
+
+
+typedef struct _ATOM_MULTIMEDIA_CONFIG_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;
+  ULONG                    ulSignature;      // MM info table signature sting "$MMT"
+  UCHAR                    ucTunerInfo;      // Type of tuner installed on the adapter (4:0) and video input for tuner (7:5)
+  UCHAR                    ucAudioChipInfo;  // List the audio chip type (3:0) product type (4) and OEM revision (7:5)
+  UCHAR                    ucProductID;      // Defines as OEM ID or ATI board ID dependent on product type setting
+  UCHAR                    ucMiscInfo1;      // Tuner voltage (1:0) HW teletext support (3:2) FM audio decoder (5:4) reserved (6) audio scrambling (7)
+  UCHAR                    ucMiscInfo2;      // I2S input config (0) I2S output config (1) I2S Audio Chip (4:2) SPDIF Output Config (5) reserved (7:6)
+  UCHAR                    ucMiscInfo3;      // Video Decoder Type (3:0) Video In Standard/Crystal (7:4)
+  UCHAR                    ucMiscInfo4;      // Video Decoder Host Config (2:0) reserved (7:3)
+  UCHAR                    ucVideoInput0Info;// Video Input 0 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6)
+  UCHAR                    ucVideoInput1Info;// Video Input 1 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6)
+  UCHAR                    ucVideoInput2Info;// Video Input 2 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6)
+  UCHAR                    ucVideoInput3Info;// Video Input 3 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6)
+  UCHAR                    ucVideoInput4Info;// Video Input 4 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6)
+}ATOM_MULTIMEDIA_CONFIG_INFO;
+
+/****************************Firmware Info Table Definitions**********************/
+
+// usBIOSCapability Defintion:
+// Bit 0 = 0: Bios image is not Posted, =1:Bios image is Posted; 
+// Bit 1 = 0: Dual CRTC is not supported, =1: Dual CRTC is supported; 
+// Bit 2 = 0: Extended Desktop is not supported, =1: Extended Desktop is supported; 
+// Others: Reserved
+#define ATOM_BIOS_INFO_ATOM_FIRMWARE_POSTED         0x0001
+#define ATOM_BIOS_INFO_DUAL_CRTC_SUPPORT            0x0002
+#define ATOM_BIOS_INFO_EXTENDED_DESKTOP_SUPPORT     0x0004
+#define ATOM_BIOS_INFO_MEMORY_CLOCK_SS_SUPPORT      0x0008
+#define ATOM_BIOS_INFO_ENGINE_CLOCK_SS_SUPPORT      0x0010
+#define ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU         0x0020
+#define ATOM_BIOS_INFO_WMI_SUPPORT                  0x0040
+#define ATOM_BIOS_INFO_PPMODE_ASSIGNGED_BY_SYSTEM   0x0080
+#define ATOM_BIOS_INFO_HYPERMEMORY_SUPPORT          0x0100
+#define ATOM_BIOS_INFO_HYPERMEMORY_SIZE_MASK        0x1E00
+#define ATOM_BIOS_INFO_VPOST_WITHOUT_FIRST_MODE_SET 0x2000
+#define ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE  0x4000
+
+
+#ifndef _H2INC
+
+//Please don't add or expand this bitfield structure below, this one will retire soon.!
+typedef struct _ATOM_FIRMWARE_CAPABILITY
+{
+  USHORT FirmwarePosted:1;
+  USHORT DualCRTC_Support:1;
+  USHORT ExtendedDesktopSupport:1;
+  USHORT MemoryClockSS_Support:1;
+  USHORT EngineClockSS_Support:1;
+  USHORT GPUControlsBL:1;
+  USHORT WMI_SUPPORT:1;
+  USHORT PPMode_Assigned:1;
+  USHORT HyperMemory_Support:1;
+  USHORT HyperMemory_Size:4;
+  USHORT Reserved:3;
+}ATOM_FIRMWARE_CAPABILITY;
+
+typedef union _ATOM_FIRMWARE_CAPABILITY_ACCESS
+{
+  ATOM_FIRMWARE_CAPABILITY sbfAccess;
+  USHORT                   susAccess;
+}ATOM_FIRMWARE_CAPABILITY_ACCESS;
+
+#else
+
+typedef union _ATOM_FIRMWARE_CAPABILITY_ACCESS
+{
+  USHORT                   susAccess;
+}ATOM_FIRMWARE_CAPABILITY_ACCESS;
+
+#endif
+
+typedef struct _ATOM_FIRMWARE_INFO
+{
+  ATOM_COMMON_TABLE_HEADER        sHeader; 
+  ULONG                           ulFirmwareRevision;
+  ULONG                           ulDefaultEngineClock;       //In 10Khz unit
+  ULONG                           ulDefaultMemoryClock;       //In 10Khz unit
+  ULONG                           ulDriverTargetEngineClock;  //In 10Khz unit
+  ULONG                           ulDriverTargetMemoryClock;  //In 10Khz unit
+  ULONG                           ulMaxEngineClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxMemoryClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxPixelClockPLL_Output;  //In 10Khz unit
+  ULONG                           ulASICMaxEngineClock;       //In 10Khz unit
+  ULONG                           ulASICMaxMemoryClock;       //In 10Khz unit
+  UCHAR                           ucASICMaxTemperature;
+  UCHAR                           ucPadding[3];               //Don't use them
+  ULONG                           aulReservedForBIOS[3];      //Don't use them
+  USHORT                          usMinEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinEngineClockPLL_Output; //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Output; //In 10Khz unit
+  USHORT                          usMaxPixelClock;            //In 10Khz unit, Max.  Pclk
+  USHORT                          usMinPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMaxPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMinPixelClockPLL_Output;  //In 10Khz unit, the definitions above can't change!!!
+  ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability;
+  USHORT                          usReferenceClock;           //In 10Khz unit	
+  USHORT                          usPM_RTS_Location;          //RTS PM4 starting location in ROM in 1Kb unit 
+  UCHAR                           ucPM_RTS_StreamSize;        //RTS PM4 packets in Kb unit
+  UCHAR                           ucDesign_ID;                //Indicate what is the board design
+  UCHAR                           ucMemoryModule_ID;          //Indicate what is the board design
+}ATOM_FIRMWARE_INFO;
+
+typedef struct _ATOM_FIRMWARE_INFO_V1_2
+{
+  ATOM_COMMON_TABLE_HEADER        sHeader; 
+  ULONG                           ulFirmwareRevision;
+  ULONG                           ulDefaultEngineClock;       //In 10Khz unit
+  ULONG                           ulDefaultMemoryClock;       //In 10Khz unit
+  ULONG                           ulDriverTargetEngineClock;  //In 10Khz unit
+  ULONG                           ulDriverTargetMemoryClock;  //In 10Khz unit
+  ULONG                           ulMaxEngineClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxMemoryClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxPixelClockPLL_Output;  //In 10Khz unit
+  ULONG                           ulASICMaxEngineClock;       //In 10Khz unit
+  ULONG                           ulASICMaxMemoryClock;       //In 10Khz unit
+  UCHAR                           ucASICMaxTemperature;
+  UCHAR                           ucMinAllowedBL_Level;
+  UCHAR                           ucPadding[2];               //Don't use them
+  ULONG                           aulReservedForBIOS[2];      //Don't use them
+  ULONG                           ulMinPixelClockPLL_Output;  //In 10Khz unit
+  USHORT                          usMinEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinEngineClockPLL_Output; //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Output; //In 10Khz unit
+  USHORT                          usMaxPixelClock;            //In 10Khz unit, Max.  Pclk
+  USHORT                          usMinPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMaxPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMinPixelClockPLL_Output;  //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output
+  ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability;
+  USHORT                          usReferenceClock;           //In 10Khz unit	
+  USHORT                          usPM_RTS_Location;          //RTS PM4 starting location in ROM in 1Kb unit 
+  UCHAR                           ucPM_RTS_StreamSize;        //RTS PM4 packets in Kb unit
+  UCHAR                           ucDesign_ID;                //Indicate what is the board design
+  UCHAR                           ucMemoryModule_ID;          //Indicate what is the board design
+}ATOM_FIRMWARE_INFO_V1_2;
+
+typedef struct _ATOM_FIRMWARE_INFO_V1_3
+{
+  ATOM_COMMON_TABLE_HEADER        sHeader; 
+  ULONG                           ulFirmwareRevision;
+  ULONG                           ulDefaultEngineClock;       //In 10Khz unit
+  ULONG                           ulDefaultMemoryClock;       //In 10Khz unit
+  ULONG                           ulDriverTargetEngineClock;  //In 10Khz unit
+  ULONG                           ulDriverTargetMemoryClock;  //In 10Khz unit
+  ULONG                           ulMaxEngineClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxMemoryClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxPixelClockPLL_Output;  //In 10Khz unit
+  ULONG                           ulASICMaxEngineClock;       //In 10Khz unit
+  ULONG                           ulASICMaxMemoryClock;       //In 10Khz unit
+  UCHAR                           ucASICMaxTemperature;
+  UCHAR                           ucMinAllowedBL_Level;
+  UCHAR                           ucPadding[2];               //Don't use them
+  ULONG                           aulReservedForBIOS;         //Don't use them
+  ULONG                           ul3DAccelerationEngineClock;//In 10Khz unit
+  ULONG                           ulMinPixelClockPLL_Output;  //In 10Khz unit
+  USHORT                          usMinEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinEngineClockPLL_Output; //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Output; //In 10Khz unit
+  USHORT                          usMaxPixelClock;            //In 10Khz unit, Max.  Pclk
+  USHORT                          usMinPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMaxPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMinPixelClockPLL_Output;  //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output
+  ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability;
+  USHORT                          usReferenceClock;           //In 10Khz unit	
+  USHORT                          usPM_RTS_Location;          //RTS PM4 starting location in ROM in 1Kb unit 
+  UCHAR                           ucPM_RTS_StreamSize;        //RTS PM4 packets in Kb unit
+  UCHAR                           ucDesign_ID;                //Indicate what is the board design
+  UCHAR                           ucMemoryModule_ID;          //Indicate what is the board design
+}ATOM_FIRMWARE_INFO_V1_3;
+
+typedef struct _ATOM_FIRMWARE_INFO_V1_4
+{
+  ATOM_COMMON_TABLE_HEADER        sHeader; 
+  ULONG                           ulFirmwareRevision;
+  ULONG                           ulDefaultEngineClock;       //In 10Khz unit
+  ULONG                           ulDefaultMemoryClock;       //In 10Khz unit
+  ULONG                           ulDriverTargetEngineClock;  //In 10Khz unit
+  ULONG                           ulDriverTargetMemoryClock;  //In 10Khz unit
+  ULONG                           ulMaxEngineClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxMemoryClockPLL_Output; //In 10Khz unit
+  ULONG                           ulMaxPixelClockPLL_Output;  //In 10Khz unit
+  ULONG                           ulASICMaxEngineClock;       //In 10Khz unit
+  ULONG                           ulASICMaxMemoryClock;       //In 10Khz unit
+  UCHAR                           ucASICMaxTemperature;
+  UCHAR                           ucMinAllowedBL_Level;
+  USHORT                          usBootUpVDDCVoltage;        //In MV unit
+  USHORT                          usLcdMinPixelClockPLL_Output; // In MHz unit
+  USHORT                          usLcdMaxPixelClockPLL_Output; // In MHz unit
+  ULONG                           ul3DAccelerationEngineClock;//In 10Khz unit
+  ULONG                           ulMinPixelClockPLL_Output;  //In 10Khz unit
+  USHORT                          usMinEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxEngineClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinEngineClockPLL_Output; //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMaxMemoryClockPLL_Input;  //In 10Khz unit
+  USHORT                          usMinMemoryClockPLL_Output; //In 10Khz unit
+  USHORT                          usMaxPixelClock;            //In 10Khz unit, Max.  Pclk
+  USHORT                          usMinPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMaxPixelClockPLL_Input;   //In 10Khz unit
+  USHORT                          usMinPixelClockPLL_Output;  //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output
+  ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability;
+  USHORT                          usReferenceClock;           //In 10Khz unit	
+  USHORT                          usPM_RTS_Location;          //RTS PM4 starting location in ROM in 1Kb unit 
+  UCHAR                           ucPM_RTS_StreamSize;        //RTS PM4 packets in Kb unit
+  UCHAR                           ucDesign_ID;                //Indicate what is the board design
+  UCHAR                           ucMemoryModule_ID;          //Indicate what is the board design
+}ATOM_FIRMWARE_INFO_V1_4;
+
+#define ATOM_FIRMWARE_INFO_LAST  ATOM_FIRMWARE_INFO_V1_4
+
+#define IGP_CAP_FLAG_DYNAMIC_CLOCK_EN      0x2
+#define IGP_CAP_FLAG_AC_CARD               0x4
+#define IGP_CAP_FLAG_SDVO_CARD             0x8
+#define IGP_CAP_FLAG_POSTDIV_BY_2_MODE     0x10
+
+typedef struct _ATOM_INTEGRATED_SYSTEM_INFO
+{
+  ATOM_COMMON_TABLE_HEADER        sHeader; 
+  ULONG	                          ulBootUpEngineClock;		    //in 10kHz unit
+  ULONG	                          ulBootUpMemoryClock;		    //in 10kHz unit
+  ULONG	                          ulMaxSystemMemoryClock;	    //in 10kHz unit
+  ULONG	                          ulMinSystemMemoryClock;	    //in 10kHz unit
+  UCHAR                           ucNumberOfCyclesInPeriodHi;
+  UCHAR                           ucLCDTimingSel;             //=0:not valid.!=0 sel this timing descriptor from LCD EDID.
+  USHORT                          usReserved1;
+  USHORT                          usInterNBVoltageLow;        //An intermidiate PMW value to set the voltage 
+  USHORT                          usInterNBVoltageHigh;       //Another intermidiate PMW value to set the voltage 
+  ULONG	                          ulReserved[2];
+
+  USHORT	                        usFSBClock;			            //In MHz unit
+  USHORT                          usCapabilityFlag;		        //Bit0=1 indicates the fake HDMI support,Bit1=0/1 for Dynamic clocking dis/enable
+																                              //Bit[3:2]== 0:No PCIE card, 1:AC card, 2:SDVO card
+                                                              //Bit[4]==1: P/2 mode, ==0: P/1 mode
+  USHORT	                        usPCIENBCfgReg7;				    //bit[7:0]=MUX_Sel, bit[9:8]=MUX_SEL_LEVEL2, bit[10]=Lane_Reversal
+  USHORT	                        usK8MemoryClock;            //in MHz unit
+  USHORT	                        usK8SyncStartDelay;         //in 0.01 us unit
+  USHORT	                        usK8DataReturnTime;         //in 0.01 us unit
+  UCHAR                           ucMaxNBVoltage;
+  UCHAR                           ucMinNBVoltage;
+  UCHAR                           ucMemoryType;					      //[7:4]=1:DDR1;=2:DDR2;=3:DDR3.[3:0] is reserved
+  UCHAR                           ucNumberOfCyclesInPeriod;		//CG.FVTHROT_PWM_CTRL_REG0.NumberOfCyclesInPeriod 
+  UCHAR                           ucStartingPWM_HighTime;     //CG.FVTHROT_PWM_CTRL_REG0.StartingPWM_HighTime
+  UCHAR                           ucHTLinkWidth;              //16 bit vs. 8 bit
+  UCHAR                           ucMaxNBVoltageHigh;    
+  UCHAR                           ucMinNBVoltageHigh;
+}ATOM_INTEGRATED_SYSTEM_INFO;
+
+/* Explanation on entries in ATOM_INTEGRATED_SYSTEM_INFO
+ulBootUpMemoryClock:    For Intel IGP,it's the UMA system memory clock 
+                        For AMD IGP,it's 0 if no SidePort memory installed or it's the boot-up SidePort memory clock
+ulMaxSystemMemoryClock: For Intel IGP,it's the Max freq from memory SPD if memory runs in ASYNC mode or otherwise (SYNC mode) it's 0
+                        For AMD IGP,for now this can be 0
+ulMinSystemMemoryClock: For Intel IGP,it's 133MHz if memory runs in ASYNC mode or otherwise (SYNC mode) it's 0 
+                        For AMD IGP,for now this can be 0
+
+usFSBClock:             For Intel IGP,it's FSB Freq 
+                        For AMD IGP,it's HT Link Speed
+
+usK8MemoryClock:        For AMD IGP only. For RevF CPU, set it to 200
+usK8SyncStartDelay:     For AMD IGP only. Memory access latency in K8, required for watermark calculation
+usK8DataReturnTime:     For AMD IGP only. Memory access latency in K8, required for watermark calculation
+
+VC:Voltage Control
+ucMaxNBVoltage:         Voltage regulator dependent PWM value. Low 8 bits of the value for the max voltage.Set this one to 0xFF if VC without PWM. Set this to 0x0 if no VC at all.
+ucMinNBVoltage:         Voltage regulator dependent PWM value. Low 8 bits of the value for the min voltage.Set this one to 0x00 if VC without PWM or no VC at all.
+
+ucNumberOfCyclesInPeriod:   Indicate how many cycles when PWM duty is 100%. low 8 bits of the value. 
+ucNumberOfCyclesInPeriodHi: Indicate how many cycles when PWM duty is 100%. high 8 bits of the value.If the PWM has an inverter,set bit [7]==1,otherwise set it 0 
+
+ucMaxNBVoltageHigh:     Voltage regulator dependent PWM value. High 8 bits of  the value for the max voltage.Set this one to 0xFF if VC without PWM. Set this to 0x0 if no VC at all.
+ucMinNBVoltageHigh:     Voltage regulator dependent PWM value. High 8 bits of the value for the min voltage.Set this one to 0x00 if VC without PWM or no VC at all.
+
+
+usInterNBVoltageLow:    Voltage regulator dependent PWM value. The value makes the the voltage >=Min NB voltage but <=InterNBVoltageHigh. Set this to 0x0000 if VC without PWM or no VC at all.
+usInterNBVoltageHigh:   Voltage regulator dependent PWM value. The value makes the the voltage >=InterNBVoltageLow but <=Max NB voltage.Set this to 0x0000 if VC without PWM or no VC at all.
+*/
+
+
+/*
+The following IGP table is introduced from RS780, which is supposed to be put by SBIOS in FB before IGP VBIOS starts VPOST;
+Then VBIOS will copy the whole structure to its image so all GPU SW components can access this data structure to get whatever they need. 
+The enough reservation should allow us to never change table revisions. Whenever needed, a GPU SW component can use reserved portion for new data entries.
+
+SW components can access the IGP system infor structure in the same way as before
+*/
+
+
+typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V2
+{
+  ATOM_COMMON_TABLE_HEADER   sHeader;
+  ULONG	                     ulBootUpEngineClock;       //in 10kHz unit
+  ULONG			                 ulReserved1[2];            //must be 0x0 for the reserved
+  ULONG	                     ulBootUpUMAClock;          //in 10kHz unit
+  ULONG	                     ulBootUpSidePortClock;     //in 10kHz unit
+  ULONG			                 ulReserved2[8];            //must be 0x0 for the reserved
+  ULONG                      ulBootUpReqDisplayVector;
+  ULONG                      ulOtherDisplayMisc;
+  ULONG                      ulDDISlot1Config;
+  ULONG                      ulDDISlot2Config;
+  UCHAR                      ucMemoryType;              //[7:4]=1:DDR1;=2:DDR2;=3:DDR3.[3:0] is reserved
+  UCHAR                      ucReserved;                //must be 0x0 for the reserved
+  UCHAR                      ucDockingPinBit;
+  UCHAR                      ucDockingPinPolarity;
+  ULONG                      ulDockingPinCFGInfo;
+  ULONG                      ulCPUCapInfo;              
+  ULONG                      ulReserved3[107];          //must be 0x0
+}ATOM_INTEGRATED_SYSTEM_INFO_V2;   
+
+/*
+ulBootUpEngineClock:   Boot-up Engine Clock in 10Khz;
+ulBootUpUMAClock:      Boot-up UMA Clock in 10Khz; it must be 0x0 when UMA is not present
+ulBootUpSidePortClock: Boot-up SidePort Clock in 10Khz; it must be 0x0 when SidePort Memory is not present
+
+
+ulBootUpReqDisplayVector: This dword is a bit vector indicates what display devices are requested during boot-up. Refer to ATOM_DEVICE_xxx_SUPPORT for the bit vector definitions.
+
+ulOtherDisplayMisc: [15:8]- Bootup LCD Expansion selection; 0-center, 1-full panel size expansion;
+			              [7:0] - BootupTV standard selection; This is a bit vector to indicate what TV standards are supported by the system. Refer to ucTVSuppportedStd definition;
+
+ulDDISlot1Config: Describes the PCIE lane configuration on this DDI PCIE slot (ADD2 card) or connector (Mobile design).
+      [3:0]  - Bit vector to indicate PCIE lane config of the DDI slot/connector on chassis (bit 0=1 lane 3:0; bit 1=1 lane 7:4; bit 2=1 lane 11:8; bit 3=1 lane 15:12)
+			[7:4]  - Bit vector to indicate PCIE lane config of the same DDI slot/connector on docking station (bit 0=1 lane 3:0; bit 1=1 lane 7:4; bit 2=1 lane 11:8; bit 3=1 lane 15:12)			
+			[15:8] - Lane configuration attribute; 
+			[31:16]- Reserved
+
+ulDDISlot2Config: Same as Slot1
+
+ulDockingPinCFGInfo: [15:0]-Bus/Device/Function # to CFG to read this Docking Pin; [31:16]-reg offset in CFG to read this pin 
+ucDockingPinBit:     which bit in this register to read the pin status;
+ucDockingPinPolarity:Polarity of the pin when docked;
+
+ulCPUCapInfo: TBD
+
+*/
+
+#define ATOM_CRT_INT_ENCODER1_INDEX                       0x00000000
+#define ATOM_LCD_INT_ENCODER1_INDEX                       0x00000001
+#define ATOM_TV_INT_ENCODER1_INDEX                        0x00000002
+#define ATOM_DFP_INT_ENCODER1_INDEX                       0x00000003
+#define ATOM_CRT_INT_ENCODER2_INDEX                       0x00000004
+#define ATOM_LCD_EXT_ENCODER1_INDEX                       0x00000005
+#define ATOM_TV_EXT_ENCODER1_INDEX                        0x00000006
+#define ATOM_DFP_EXT_ENCODER1_INDEX                       0x00000007
+#define ATOM_CV_INT_ENCODER1_INDEX                        0x00000008
+#define ATOM_DFP_INT_ENCODER2_INDEX                       0x00000009
+#define ATOM_CRT_EXT_ENCODER1_INDEX                       0x0000000A
+#define ATOM_CV_EXT_ENCODER1_INDEX                        0x0000000B
+#define ATOM_DFP_INT_ENCODER3_INDEX                       0x0000000C
+#define ATOM_DFP_INT_ENCODER4_INDEX                       0x0000000D
+
+// define ASIC internal encoder id ( bit vector )
+#define ASIC_INT_DAC1_ENCODER_ID    											0x00 
+#define ASIC_INT_TV_ENCODER_ID														0x02
+#define ASIC_INT_DIG1_ENCODER_ID													0x03
+#define ASIC_INT_DAC2_ENCODER_ID													0x04
+#define ASIC_EXT_TV_ENCODER_ID														0x06
+#define ASIC_INT_DVO_ENCODER_ID														0x07
+#define ASIC_INT_DIG2_ENCODER_ID													0x09
+#define ASIC_EXT_DIG_ENCODER_ID														0x05
+
+//define Encoder attribute
+#define ATOM_ANALOG_ENCODER																0
+#define ATOM_DIGITAL_ENCODER															1		
+
+#define ATOM_DEVICE_CRT1_INDEX                            0x00000000
+#define ATOM_DEVICE_LCD1_INDEX                            0x00000001
+#define ATOM_DEVICE_TV1_INDEX                             0x00000002
+#define ATOM_DEVICE_DFP1_INDEX                            0x00000003
+#define ATOM_DEVICE_CRT2_INDEX                            0x00000004
+#define ATOM_DEVICE_LCD2_INDEX                            0x00000005
+#define ATOM_DEVICE_TV2_INDEX                             0x00000006
+#define ATOM_DEVICE_DFP2_INDEX                            0x00000007
+#define ATOM_DEVICE_CV_INDEX                              0x00000008
+#define ATOM_DEVICE_DFP3_INDEX				  0x00000009
+#define ATOM_DEVICE_RESERVEDA_INDEX                       0x0000000A
+#define ATOM_DEVICE_RESERVEDB_INDEX                       0x0000000B
+#define ATOM_DEVICE_RESERVEDC_INDEX                       0x0000000C
+#define ATOM_DEVICE_RESERVEDD_INDEX                       0x0000000D
+#define ATOM_DEVICE_RESERVEDE_INDEX                       0x0000000E
+#define ATOM_DEVICE_RESERVEDF_INDEX                       0x0000000F
+#define ATOM_MAX_SUPPORTED_DEVICE_INFO                    (ATOM_DEVICE_CV_INDEX+2)
+#define ATOM_MAX_SUPPORTED_DEVICE_INFO_2                  ATOM_MAX_SUPPORTED_DEVICE_INFO
+#define ATOM_MAX_SUPPORTED_DEVICE                         (ATOM_DEVICE_RESERVEDF_INDEX+1)
+
+#define ATOM_DEVICE_CRT1_SUPPORT                          (0x1L << ATOM_DEVICE_CRT1_INDEX )
+#define ATOM_DEVICE_LCD1_SUPPORT                          (0x1L << ATOM_DEVICE_LCD1_INDEX )
+#define ATOM_DEVICE_TV1_SUPPORT                           (0x1L << ATOM_DEVICE_TV1_INDEX  )
+#define ATOM_DEVICE_DFP1_SUPPORT                          (0x1L << ATOM_DEVICE_DFP1_INDEX)
+#define ATOM_DEVICE_CRT2_SUPPORT                          (0x1L << ATOM_DEVICE_CRT2_INDEX )
+#define ATOM_DEVICE_LCD2_SUPPORT                          (0x1L << ATOM_DEVICE_LCD2_INDEX )
+#define ATOM_DEVICE_TV2_SUPPORT                           (0x1L << ATOM_DEVICE_TV2_INDEX  )
+#define ATOM_DEVICE_DFP2_SUPPORT                          (0x1L << ATOM_DEVICE_DFP2_INDEX)
+#define ATOM_DEVICE_CV_SUPPORT                            (0x1L << ATOM_DEVICE_CV_INDEX   )
+#define ATOM_DEVICE_DFP3_SUPPORT													(0x1L << ATOM_DEVICE_DFP3_INDEX )
+
+#define ATOM_DEVICE_CRT_SUPPORT                           ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_CRT2_SUPPORT
+#define ATOM_DEVICE_DFP_SUPPORT                           ATOM_DEVICE_DFP1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT |  ATOM_DEVICE_DFP3_SUPPORT
+#define ATOM_DEVICE_TV_SUPPORT                            ATOM_DEVICE_TV1_SUPPORT  | ATOM_DEVICE_TV2_SUPPORT
+#define ATOM_DEVICE_LCD_SUPPORT                           ATOM_DEVICE_LCD1_SUPPORT | ATOM_DEVICE_LCD2_SUPPORT
+
+#define ATOM_DEVICE_CONNECTOR_TYPE_MASK                   0x000000F0
+#define ATOM_DEVICE_CONNECTOR_TYPE_SHIFT                  0x00000004
+#define ATOM_DEVICE_CONNECTOR_VGA                         0x00000001
+#define ATOM_DEVICE_CONNECTOR_DVI_I                       0x00000002
+#define ATOM_DEVICE_CONNECTOR_DVI_D                       0x00000003
+#define ATOM_DEVICE_CONNECTOR_DVI_A                       0x00000004
+#define ATOM_DEVICE_CONNECTOR_SVIDEO                      0x00000005
+#define ATOM_DEVICE_CONNECTOR_COMPOSITE                   0x00000006
+#define ATOM_DEVICE_CONNECTOR_LVDS                        0x00000007
+#define ATOM_DEVICE_CONNECTOR_DIGI_LINK                   0x00000008
+#define ATOM_DEVICE_CONNECTOR_SCART                       0x00000009
+#define ATOM_DEVICE_CONNECTOR_HDMI_TYPE_A                 0x0000000A
+#define ATOM_DEVICE_CONNECTOR_HDMI_TYPE_B                 0x0000000B
+#define ATOM_DEVICE_CONNECTOR_CASE_1                      0x0000000E
+#define ATOM_DEVICE_CONNECTOR_DISPLAYPORT                 0x0000000F
+
+
+#define ATOM_DEVICE_DAC_INFO_MASK                         0x0000000F
+#define ATOM_DEVICE_DAC_INFO_SHIFT                        0x00000000
+#define ATOM_DEVICE_DAC_INFO_NODAC                        0x00000000
+#define ATOM_DEVICE_DAC_INFO_DACA                         0x00000001
+#define ATOM_DEVICE_DAC_INFO_DACB                         0x00000002
+#define ATOM_DEVICE_DAC_INFO_EXDAC                        0x00000003
+
+#define ATOM_DEVICE_I2C_ID_NOI2C                          0x00000000
+
+#define ATOM_DEVICE_I2C_LINEMUX_MASK                      0x0000000F
+#define ATOM_DEVICE_I2C_LINEMUX_SHIFT                     0x00000000
+
+#define ATOM_DEVICE_I2C_ID_MASK                           0x00000070
+#define ATOM_DEVICE_I2C_ID_SHIFT                          0x00000004
+#define ATOM_DEVICE_I2C_ID_IS_FOR_NON_MM_USE              0x00000001
+#define ATOM_DEVICE_I2C_ID_IS_FOR_MM_USE                  0x00000002
+#define ATOM_DEVICE_I2C_ID_IS_FOR_SDVO_USE                0x00000003    //For IGP RS600
+#define ATOM_DEVICE_I2C_ID_IS_FOR_DAC_SCL                 0x00000004    //For IGP RS690
+
+#define ATOM_DEVICE_I2C_HARDWARE_CAP_MASK                 0x00000080
+#define ATOM_DEVICE_I2C_HARDWARE_CAP_SHIFT                0x00000007
+#define	ATOM_DEVICE_USES_SOFTWARE_ASSISTED_I2C            0x00000000
+#define	ATOM_DEVICE_USES_HARDWARE_ASSISTED_I2C            0x00000001
+
+//  usDeviceSupport:
+//  Bits0	= 0 - no CRT1 support= 1- CRT1 is supported
+//  Bit 1	= 0 - no LCD1 support= 1- LCD1 is supported
+//  Bit 2	= 0 - no TV1  support= 1- TV1  is supported
+//  Bit 3	= 0 - no DFP1 support= 1- DFP1 is supported
+//  Bit 4	= 0 - no CRT2 support= 1- CRT2 is supported
+//  Bit 5	= 0 - no LCD2 support= 1- LCD2 is supported
+//  Bit 6	= 0 - no TV2  support= 1- TV2  is supported
+//  Bit 7	= 0 - no DFP2 support= 1- DFP2 is supported
+//  Bit 8	= 0 - no CV   support= 1- CV   is supported
+//  Bit 9	= 0 - no DFP3 support= 1- DFP3 is supported
+//  Byte1 (Supported Device Info)
+//  Bit 0	= = 0 - no CV support= 1- CV is supported
+//   
+//  
+
+//		ucI2C_ConfigID
+//    [7:0] - I2C LINE Associate ID
+//          = 0   - no I2C
+//    [7]		-	HW_Cap        =	1,  [6:0]=HW assisted I2C ID(HW line selection)
+//                          =	0,  [6:0]=SW assisted I2C ID
+//    [6-4]	- HW_ENGINE_ID  =	1,  HW engine for NON multimedia use
+//                          =	2,	HW engine for Multimedia use
+//                          =	3-7	Reserved for future I2C engines
+//		[3-0] - I2C_LINE_MUX  = A Mux number when it's HW assisted I2C or GPIO ID when it's SW I2C
+
+
+typedef struct _ATOM_I2C_ID_CONFIG
+{
+  UCHAR   bfI2C_LineMux:4;
+  UCHAR   bfHW_EngineID:3;
+  UCHAR   bfHW_Capable:1;
+}ATOM_I2C_ID_CONFIG;
+
+typedef union _ATOM_I2C_ID_CONFIG_ACCESS
+{
+  ATOM_I2C_ID_CONFIG sbfAccess;
+  UCHAR              ucAccess;
+}ATOM_I2C_ID_CONFIG_ACCESS;
+   
+
+typedef struct _ATOM_GPIO_I2C_ASSIGMENT
+{
+  USHORT                    usClkMaskRegisterIndex;
+  USHORT                    usClkEnRegisterIndex;
+  USHORT                    usClkY_RegisterIndex;
+  USHORT                    usClkA_RegisterIndex;
+  USHORT                    usDataMaskRegisterIndex;
+  USHORT                    usDataEnRegisterIndex;
+  USHORT                    usDataY_RegisterIndex;
+  USHORT                    usDataA_RegisterIndex;
+  ATOM_I2C_ID_CONFIG_ACCESS sucI2cId;
+  UCHAR                     ucClkMaskShift;
+  UCHAR                     ucClkEnShift;
+  UCHAR                     ucClkY_Shift;
+  UCHAR                     ucClkA_Shift;
+  UCHAR                     ucDataMaskShift;
+  UCHAR                     ucDataEnShift;
+  UCHAR                     ucDataY_Shift;
+  UCHAR                     ucDataA_Shift;
+  UCHAR                     ucReserved1;
+  UCHAR                     ucReserved2;
+}ATOM_GPIO_I2C_ASSIGMENT;
+
+typedef struct _ATOM_GPIO_I2C_INFO
+{ 
+  ATOM_COMMON_TABLE_HEADER	sHeader;
+  ATOM_GPIO_I2C_ASSIGMENT   asGPIO_Info[ATOM_MAX_SUPPORTED_DEVICE];
+}ATOM_GPIO_I2C_INFO;
+
+
+#ifndef _H2INC
+  
+//Please don't add or expand this bitfield structure below, this one will retire soon.!
+typedef struct _ATOM_MODE_MISC_INFO
+{ 
+  USHORT HorizontalCutOff:1;
+  USHORT HSyncPolarity:1;      //0=Active High, 1=Active Low
+  USHORT VSyncPolarity:1;      //0=Active High, 1=Active Low
+  USHORT VerticalCutOff:1;
+  USHORT H_ReplicationBy2:1;
+  USHORT V_ReplicationBy2:1;
+  USHORT CompositeSync:1;
+  USHORT Interlace:1;
+  USHORT DoubleClock:1;
+  USHORT RGB888:1;
+  USHORT Reserved:6;           
+}ATOM_MODE_MISC_INFO;
+  
+typedef union _ATOM_MODE_MISC_INFO_ACCESS
+{ 
+  ATOM_MODE_MISC_INFO sbfAccess;
+  USHORT              usAccess;
+}ATOM_MODE_MISC_INFO_ACCESS;
+  
+#else
+  
+typedef union _ATOM_MODE_MISC_INFO_ACCESS
+{ 
+  USHORT              usAccess;
+}ATOM_MODE_MISC_INFO_ACCESS;
+   
+#endif
+
+// usModeMiscInfo-
+#define ATOM_H_CUTOFF           0x01
+#define ATOM_HSYNC_POLARITY     0x02             //0=Active High, 1=Active Low
+#define ATOM_VSYNC_POLARITY     0x04             //0=Active High, 1=Active Low
+#define ATOM_V_CUTOFF           0x08
+#define ATOM_H_REPLICATIONBY2   0x10
+#define ATOM_V_REPLICATIONBY2   0x20
+#define ATOM_COMPOSITESYNC      0x40
+#define ATOM_INTERLACE          0x80
+#define ATOM_DOUBLE_CLOCK_MODE  0x100
+#define ATOM_RGB888_MODE        0x200
+
+//usRefreshRate-
+#define ATOM_REFRESH_43         43
+#define ATOM_REFRESH_47         47
+#define ATOM_REFRESH_56         56	
+#define ATOM_REFRESH_60         60
+#define ATOM_REFRESH_65         65
+#define ATOM_REFRESH_70         70
+#define ATOM_REFRESH_72         72
+#define ATOM_REFRESH_75         75
+#define ATOM_REFRESH_85         85
+
+// ATOM_MODE_TIMING data are exactly the same as VESA timing data.
+// Translation from EDID to ATOM_MODE_TIMING, use the following formula.
+//
+//	VESA_HTOTAL			=	VESA_ACTIVE + 2* VESA_BORDER + VESA_BLANK
+//						=	EDID_HA + EDID_HBL
+//	VESA_HDISP			=	VESA_ACTIVE	=	EDID_HA
+//	VESA_HSYNC_START	=	VESA_ACTIVE + VESA_BORDER + VESA_FRONT_PORCH
+//						=	EDID_HA + EDID_HSO
+//	VESA_HSYNC_WIDTH	=	VESA_HSYNC_TIME	=	EDID_HSPW
+//	VESA_BORDER			=	EDID_BORDER
+
+
+typedef struct _SET_CRTC_USING_DTD_TIMING_PARAMETERS
+{
+  USHORT  usH_Size;
+  USHORT  usH_Blanking_Time;
+  USHORT  usV_Size;
+  USHORT  usV_Blanking_Time;			
+  USHORT  usH_SyncOffset;
+  USHORT  usH_SyncWidth;
+  USHORT  usV_SyncOffset;
+  USHORT  usV_SyncWidth;
+  ATOM_MODE_MISC_INFO_ACCESS  susModeMiscInfo;  
+  UCHAR   ucH_Border;         // From DFP EDID
+  UCHAR   ucV_Border;
+  UCHAR   ucCRTC;             // ATOM_CRTC1 or ATOM_CRTC2  
+  UCHAR   ucPadding[3];
+}SET_CRTC_USING_DTD_TIMING_PARAMETERS;
+
+typedef struct _SET_CRTC_TIMING_PARAMETERS
+{
+  USHORT                      usH_Total;        // horizontal total
+  USHORT                      usH_Disp;         // horizontal display
+  USHORT                      usH_SyncStart;    // horozontal Sync start
+  USHORT                      usH_SyncWidth;    // horizontal Sync width
+  USHORT                      usV_Total;        // vertical total
+  USHORT                      usV_Disp;         // vertical display
+  USHORT                      usV_SyncStart;    // vertical Sync start
+  USHORT                      usV_SyncWidth;    // vertical Sync width
+  ATOM_MODE_MISC_INFO_ACCESS  susModeMiscInfo;
+  UCHAR                       ucCRTC;           // ATOM_CRTC1 or ATOM_CRTC2
+  UCHAR                       ucOverscanRight;  // right
+  UCHAR                       ucOverscanLeft;   // left
+  UCHAR                       ucOverscanBottom; // bottom
+  UCHAR                       ucOverscanTop;    // top
+  UCHAR                       ucReserved;
+}SET_CRTC_TIMING_PARAMETERS;
+#define SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION SET_CRTC_TIMING_PARAMETERS
+
+
+typedef struct _ATOM_MODE_TIMING
+{
+  USHORT  usCRTC_H_Total;
+  USHORT  usCRTC_H_Disp;
+  USHORT  usCRTC_H_SyncStart;
+  USHORT  usCRTC_H_SyncWidth;
+  USHORT  usCRTC_V_Total;
+  USHORT  usCRTC_V_Disp;
+  USHORT  usCRTC_V_SyncStart;
+  USHORT  usCRTC_V_SyncWidth;
+  USHORT  usPixelClock;					                 //in 10Khz unit
+  ATOM_MODE_MISC_INFO_ACCESS  susModeMiscInfo;
+  USHORT  usCRTC_OverscanRight;
+  USHORT  usCRTC_OverscanLeft;
+  USHORT  usCRTC_OverscanBottom;
+  USHORT  usCRTC_OverscanTop;
+  USHORT  usReserve;
+  UCHAR   ucInternalModeNumber;
+  UCHAR   ucRefreshRate;
+}ATOM_MODE_TIMING;
+
+ 
+typedef struct _ATOM_DTD_FORMAT
+{
+  USHORT  usPixClk;
+  USHORT  usHActive;
+  USHORT  usHBlanking_Time;
+  USHORT  usVActive;
+  USHORT  usVBlanking_Time;			
+  USHORT  usHSyncOffset;
+  USHORT  usHSyncWidth;
+  USHORT  usVSyncOffset;
+  USHORT  usVSyncWidth;
+  USHORT  usImageHSize;
+  USHORT  usImageVSize;
+  UCHAR   ucHBorder;
+  UCHAR   ucVBorder;
+  ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo;
+  UCHAR   ucReserved1;
+  UCHAR   ucReserved2;
+}ATOM_DTD_FORMAT;
+
+#define SUPPORTED_LCD_REFRESHRATE_30Hz          0x0004
+#define SUPPORTED_LCD_REFRESHRATE_40Hz          0x0008
+#define SUPPORTED_LCD_REFRESHRATE_50Hz          0x0010
+#define SUPPORTED_LCD_REFRESHRATE_60Hz          0x0020
+
+/****************************LVDS Info Table Definitions **********************/
+//ucTableFormatRevision=1
+//ucTableContentRevision=1
+typedef struct _ATOM_LVDS_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  ATOM_DTD_FORMAT     sLCDTiming;
+  USHORT              usModePatchTableOffset;
+  USHORT              usSupportedRefreshRate;     //Refer to panel info table in ATOMBIOS extension Spec.
+  USHORT              usOffDelayInMs;
+  UCHAR               ucPowerSequenceDigOntoDEin10Ms;
+  UCHAR               ucPowerSequenceDEtoBLOnin10Ms;
+  UCHAR               ucLVDS_Misc;               // Bit0:{=0:single, =1:dual},Bit1 {=0:666RGB, =1:888RGB},Bit2:3:{Grey level}
+                                                 // Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888}
+                                                 // Bit5:{=0:Spatial Dithering disabled;1 Spatial Dithering enabled}
+                                                 // Bit6:{=0:Temporal Dithering disabled;1 Temporal Dithering enabled}
+  UCHAR               ucPanelDefaultRefreshRate;
+  UCHAR               ucPanelIdentification;
+  UCHAR               ucSS_Id;
+}ATOM_LVDS_INFO;
+
+//ucTableFormatRevision=1
+//ucTableContentRevision=2
+typedef struct _ATOM_LVDS_INFO_V12
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  ATOM_DTD_FORMAT     sLCDTiming;
+  USHORT              usExtInfoTableOffset;
+  USHORT              usSupportedRefreshRate;     //Refer to panel info table in ATOMBIOS extension Spec.
+  USHORT              usOffDelayInMs;
+  UCHAR               ucPowerSequenceDigOntoDEin10Ms;
+  UCHAR               ucPowerSequenceDEtoBLOnin10Ms;
+  UCHAR               ucLVDS_Misc;               // Bit0:{=0:single, =1:dual},Bit1 {=0:666RGB, =1:888RGB},Bit2:3:{Grey level}
+                                                 // Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888}
+                                                 // Bit5:{=0:Spatial Dithering disabled;1 Spatial Dithering enabled}
+                                                 // Bit6:{=0:Temporal Dithering disabled;1 Temporal Dithering enabled}
+  UCHAR               ucPanelDefaultRefreshRate;
+  UCHAR               ucPanelIdentification;
+  UCHAR               ucSS_Id;
+  USHORT              usLCDVenderID;
+  USHORT              usLCDProductID;
+  UCHAR               ucLCDPanel_SpecialHandlingCap; 
+	UCHAR								ucPanelInfoSize;					//  start from ATOM_DTD_FORMAT to end of panel info, include ExtInfoTable
+  UCHAR               ucReserved[2];
+}ATOM_LVDS_INFO_V12;
+
+#define ATOM_LVDS_INFO_LAST  ATOM_LVDS_INFO_V12
+
+typedef struct  _ATOM_PATCH_RECORD_MODE
+{
+  UCHAR     ucRecordType;
+  USHORT    usHDisp;
+  USHORT    usVDisp;
+}ATOM_PATCH_RECORD_MODE;
+
+typedef struct  _ATOM_LCD_RTS_RECORD
+{
+  UCHAR     ucRecordType;
+  UCHAR     ucRTSValue;
+}ATOM_LCD_RTS_RECORD;
+
+//!! If the record below exits, it shoud always be the first record for easy use in command table!!! 
+typedef struct  _ATOM_LCD_MODE_CONTROL_CAP
+{
+  UCHAR     ucRecordType;
+  USHORT    usLCDCap;
+}ATOM_LCD_MODE_CONTROL_CAP;
+
+#define LCD_MODE_CAP_BL_OFF                   1
+#define LCD_MODE_CAP_CRTC_OFF                 2
+#define LCD_MODE_CAP_PANEL_OFF                4
+
+typedef struct _ATOM_FAKE_EDID_PATCH_RECORD
+{
+  UCHAR ucRecordType;
+  UCHAR ucFakeEDIDLength;
+  UCHAR ucFakeEDIDString[1];    // This actually has ucFakeEdidLength elements.
+} ATOM_FAKE_EDID_PATCH_RECORD;
+
+typedef struct  _ATOM_PANEL_RESOLUTION_PATCH_RECORD
+{
+   UCHAR    ucRecordType;
+   USHORT		usHSize;
+   USHORT		usVSize;
+}ATOM_PANEL_RESOLUTION_PATCH_RECORD;
+
+#define LCD_MODE_PATCH_RECORD_MODE_TYPE       1
+#define LCD_RTS_RECORD_TYPE                   2
+#define LCD_CAP_RECORD_TYPE                   3
+#define LCD_FAKE_EDID_PATCH_RECORD_TYPE       4
+#define LCD_PANEL_RESOLUTION_RECORD_TYPE      5
+#define ATOM_RECORD_END_TYPE                  0xFF
+
+/****************************Spread Spectrum Info Table Definitions **********************/
+
+//ucTableFormatRevision=1
+//ucTableContentRevision=2
+typedef struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT
+{
+  USHORT              usSpreadSpectrumPercentage; 
+  UCHAR               ucSpreadSpectrumType;	    //Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD
+  UCHAR               ucSS_Step;
+  UCHAR               ucSS_Delay;
+  UCHAR               ucSS_Id;
+  UCHAR               ucRecommandedRef_Div;
+  UCHAR               ucSS_Range;               //it was reserved for V11
+}ATOM_SPREAD_SPECTRUM_ASSIGNMENT;
+
+#define ATOM_MAX_SS_ENTRY                      16
+#define ATOM_DP_SS_ID1												 0x0f1			// SS modulation freq=30k
+#define ATOM_DP_SS_ID2												 0x0f2			// SS modulation freq=33k
+
+
+#define ATOM_SS_DOWN_SPREAD_MODE_MASK          0x00000000
+#define ATOM_SS_DOWN_SPREAD_MODE               0x00000000
+#define ATOM_SS_CENTRE_SPREAD_MODE_MASK        0x00000001
+#define ATOM_SS_CENTRE_SPREAD_MODE             0x00000001
+#define ATOM_INTERNAL_SS_MASK                  0x00000000
+#define ATOM_EXTERNAL_SS_MASK                  0x00000002
+#define EXEC_SS_STEP_SIZE_SHIFT                2
+#define EXEC_SS_DELAY_SHIFT                    4    
+#define ACTIVEDATA_TO_BLON_DELAY_SHIFT         4
+
+typedef struct _ATOM_SPREAD_SPECTRUM_INFO
+{ 
+  ATOM_COMMON_TABLE_HEADER	sHeader;
+  ATOM_SPREAD_SPECTRUM_ASSIGNMENT   asSS_Info[ATOM_MAX_SS_ENTRY];
+}ATOM_SPREAD_SPECTRUM_INFO;
+
+
+
+
+//ucTVBootUpDefaultStd definiton:
+
+//ATOM_TV_NTSC                1
+//ATOM_TV_NTSCJ               2
+//ATOM_TV_PAL                 3
+//ATOM_TV_PALM                4
+//ATOM_TV_PALCN               5
+//ATOM_TV_PALN                6
+//ATOM_TV_PAL60               7
+//ATOM_TV_SECAM               8
+
+
+//ucTVSuppportedStd definition:
+#define NTSC_SUPPORT          0x1
+#define NTSCJ_SUPPORT         0x2
+
+#define PAL_SUPPORT           0x4
+#define PALM_SUPPORT          0x8
+#define PALCN_SUPPORT         0x10
+#define PALN_SUPPORT          0x20
+#define PAL60_SUPPORT         0x40
+#define SECAM_SUPPORT         0x80
+
+#define MAX_SUPPORTED_TV_TIMING    2
+
+typedef struct _ATOM_ANALOG_TV_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  UCHAR                    ucTV_SupportedStandard;
+  UCHAR                    ucTV_BootUpDefaultStandard; 
+  UCHAR                    ucExt_TV_ASIC_ID;
+  UCHAR                    ucExt_TV_ASIC_SlaveAddr;
+  ATOM_MODE_TIMING         aModeTimings[MAX_SUPPORTED_TV_TIMING];
+}ATOM_ANALOG_TV_INFO;
+
+
+/**************************************************************************/
+// VRAM usage and their defintions
+
+// One chunk of VRAM used by Bios are for HWICON surfaces,EDID data.
+// Current Mode timing and Dail Timing and/or STD timing data EACH device. They can be broken down as below.
+// All the addresses below are the offsets from the frame buffer start.They all MUST be Dword aligned!
+// To driver: The physical address of this memory portion=mmFB_START(4K aligned)+ATOMBIOS_VRAM_USAGE_START_ADDR+ATOM_x_ADDR
+// To Bios:  ATOMBIOS_VRAM_USAGE_START_ADDR+ATOM_x_ADDR->MM_INDEX 
+
+#ifndef VESA_MEMORY_IN_64K_BLOCK
+#define VESA_MEMORY_IN_64K_BLOCK        0x100       //256*64K=16Mb (Max. VESA memory is 16Mb!)
+#endif
+
+#define ATOM_EDID_RAW_DATASIZE          256         //In Bytes
+#define ATOM_HWICON_SURFACE_SIZE        4096        //In Bytes
+#define ATOM_HWICON_INFOTABLE_SIZE      32
+#define MAX_DTD_MODE_IN_VRAM            6
+#define ATOM_DTD_MODE_SUPPORT_TBL_SIZE  (MAX_DTD_MODE_IN_VRAM*28)    //28= (SIZEOF ATOM_DTD_FORMAT) 
+#define ATOM_STD_MODE_SUPPORT_TBL_SIZE  32*8                         //32 is a predefined number,8= (SIZEOF ATOM_STD_FORMAT)
+#define DFP_ENCODER_TYPE_OFFSET					0x80
+#define DP_ENCODER_LANE_NUMBER					0x84
+#define DP_ENCODER_LINK_RATE   					0x88
+
+#define ATOM_HWICON1_SURFACE_ADDR       0
+#define ATOM_HWICON2_SURFACE_ADDR       (ATOM_HWICON1_SURFACE_ADDR + ATOM_HWICON_SURFACE_SIZE)
+#define ATOM_HWICON_INFOTABLE_ADDR      (ATOM_HWICON2_SURFACE_ADDR + ATOM_HWICON_SURFACE_SIZE)
+#define ATOM_CRT1_EDID_ADDR             (ATOM_HWICON_INFOTABLE_ADDR + ATOM_HWICON_INFOTABLE_SIZE)
+#define ATOM_CRT1_DTD_MODE_TBL_ADDR     (ATOM_CRT1_EDID_ADDR + ATOM_EDID_RAW_DATASIZE)
+#define ATOM_CRT1_STD_MODE_TBL_ADDR	    (ATOM_CRT1_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
+
+#define ATOM_LCD1_EDID_ADDR             (ATOM_CRT1_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE)
+#define ATOM_LCD1_DTD_MODE_TBL_ADDR     (ATOM_LCD1_EDID_ADDR + ATOM_EDID_RAW_DATASIZE)
+#define ATOM_LCD1_STD_MODE_TBL_ADDR   	(ATOM_LCD1_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
+
+#define ATOM_TV1_DTD_MODE_TBL_ADDR      (ATOM_LCD1_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE)
+
+#define ATOM_DFP1_EDID_ADDR             (ATOM_TV1_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
+#define ATOM_DFP1_DTD_MODE_TBL_ADDR     (ATOM_DFP1_EDID_ADDR + ATOM_EDID_RAW_DATASIZE)
+#define ATOM_DFP1_STD_MODE_TBL_ADDR	    (ATOM_DFP1_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
+
+#define ATOM_CRT2_EDID_ADDR             (ATOM_DFP1_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE)
+#define ATOM_CRT2_DTD_MODE_TBL_ADDR     (ATOM_CRT2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE)
+#define ATOM_CRT2_STD_MODE_TBL_ADDR	    (ATOM_CRT2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
+
+#define ATOM_LCD2_EDID_ADDR             (ATOM_CRT2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE)
+#define ATOM_LCD2_DTD_MODE_TBL_ADDR     (ATOM_LCD2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE)
+#define ATOM_LCD2_STD_MODE_TBL_ADDR   	(ATOM_LCD2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
+
+#define ATOM_TV2_EDID_ADDR              (ATOM_LCD2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE)
+#define ATOM_TV2_DTD_MODE_TBL_ADDR      (ATOM_TV2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE)
+#define ATOM_TV2_STD_MODE_TBL_ADDR  	  (ATOM_TV2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
+
+#define ATOM_DFP2_EDID_ADDR             (ATOM_TV2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE)
+#define ATOM_DFP2_DTD_MODE_TBL_ADDR     (ATOM_DFP2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE)
+#define ATOM_DFP2_STD_MODE_TBL_ADDR     (ATOM_DFP2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
+
+#define ATOM_CV_EDID_ADDR               (ATOM_DFP2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE)
+#define ATOM_CV_DTD_MODE_TBL_ADDR       (ATOM_CV_EDID_ADDR + ATOM_EDID_RAW_DATASIZE)
+#define ATOM_CV_STD_MODE_TBL_ADDR       (ATOM_CV_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
+
+#define ATOM_DFP3_EDID_ADDR             (ATOM_CV_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE)
+#define ATOM_DFP3_DTD_MODE_TBL_ADDR     (ATOM_DFP3_EDID_ADDR + ATOM_EDID_RAW_DATASIZE)
+#define ATOM_DFP3_STD_MODE_TBL_ADDR     (ATOM_DFP3_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE)
+
+#define ATOM_DP_TRAINING_TBL_ADDR				(ATOM_DFP3_STD_MODE_TBL_ADDR+ATOM_STD_MODE_SUPPORT_TBL_SIZE)       
+
+#define ATOM_STACK_STORAGE_START        (ATOM_DP_TRAINING_TBL_ADDR+256)       
+#define ATOM_STACK_STORAGE_END          ATOM_STACK_STORAGE_START+512        
+
+//The size below is in Kb!
+#define ATOM_VRAM_RESERVE_SIZE         ((((ATOM_STACK_STORAGE_END - ATOM_HWICON1_SURFACE_ADDR)>>10)+4)&0xFFFC)
+   
+#define	ATOM_VRAM_OPERATION_FLAGS_MASK         0xC0000000L
+#define ATOM_VRAM_OPERATION_FLAGS_SHIFT        30
+#define	ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION   0x1
+#define	ATOM_VRAM_BLOCK_NEEDS_RESERVATION      0x0
+
+#define ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO			1
+
+typedef struct _ATOM_FIRMWARE_VRAM_RESERVE_INFO
+{
+  ULONG   ulStartAddrUsedByFirmware;
+  USHORT  usFirmwareUseInKb;
+  USHORT  usReserved;
+}ATOM_FIRMWARE_VRAM_RESERVE_INFO;
+
+typedef struct _ATOM_VRAM_USAGE_BY_FIRMWARE
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  ATOM_FIRMWARE_VRAM_RESERVE_INFO	asFirmwareVramReserveInfo[ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO];
+}ATOM_VRAM_USAGE_BY_FIRMWARE;
+
+/**************************************************************************/
+//GPIO Pin lut table definition
+typedef struct _ATOM_GPIO_PIN_ASSIGNMENT
+{
+  USHORT                   usGpioPin_AIndex;
+  UCHAR                    ucGpioPinBitShift;
+  UCHAR                    ucGPIO_ID;
+}ATOM_GPIO_PIN_ASSIGNMENT;
+
+typedef struct _ATOM_GPIO_PIN_LUT
+{
+  ATOM_COMMON_TABLE_HEADER  sHeader;
+  ATOM_GPIO_PIN_ASSIGNMENT	asGPIO_Pin[1];
+}ATOM_GPIO_PIN_LUT;
+
+/**************************************************************************/
+
+
+#define GPIO_PIN_ACTIVE_HIGH          0x1
+
+#define MAX_SUPPORTED_CV_STANDARDS    5
+
+// definitions for ATOM_D_INFO.ucSettings
+#define ATOM_GPIO_SETTINGS_BITSHIFT_MASK  0x1F    // [4:0]
+#define ATOM_GPIO_SETTINGS_RESERVED_MASK  0x60    // [6:5] = must be zeroed out
+#define ATOM_GPIO_SETTINGS_ACTIVE_MASK    0x80    // [7]
+
+typedef struct _ATOM_GPIO_INFO
+{
+  USHORT  usAOffset;
+  UCHAR   ucSettings;
+  UCHAR   ucReserved;
+}ATOM_GPIO_INFO;
+
+// definitions for ATOM_COMPONENT_VIDEO_INFO.ucMiscInfo (bit vector)
+#define ATOM_CV_RESTRICT_FORMAT_SELECTION           0x2
+
+// definitions for ATOM_COMPONENT_VIDEO_INFO.uc480i/uc480p/uc720p/uc1080i
+#define ATOM_GPIO_DEFAULT_MODE_EN                   0x80 //[7];
+#define ATOM_GPIO_SETTING_PERMODE_MASK              0x7F //[6:0]
+
+// definitions for ATOM_COMPONENT_VIDEO_INFO.ucLetterBoxMode
+//Line 3 out put 5V.
+#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_A       0x01     //represent gpio 3 state for 16:9
+#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_B       0x02     //represent gpio 4 state for 16:9
+#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_SHIFT   0x0   
+
+//Line 3 out put 2.2V              
+#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_A 0x04     //represent gpio 3 state for 4:3 Letter box
+#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_B 0x08     //represent gpio 4 state for 4:3 Letter box
+#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_SHIFT 0x2     
+
+//Line 3 out put 0V
+#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_A        0x10     //represent gpio 3 state for 4:3
+#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_B        0x20     //represent gpio 4 state for 4:3
+#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_SHIFT    0x4 
+
+#define ATOM_CV_LINE3_ASPECTRATIO_MASK              0x3F     // bit [5:0]
+
+#define ATOM_CV_LINE3_ASPECTRATIO_EXIST             0x80     //bit 7
+
+//GPIO bit index in gpio setting per mode value, also represend the block no. in gpio blocks.
+#define ATOM_GPIO_INDEX_LINE3_ASPECRATIO_GPIO_A   3   //bit 3 in uc480i/uc480p/uc720p/uc1080i, which represend the default gpio bit setting for the mode.
+#define ATOM_GPIO_INDEX_LINE3_ASPECRATIO_GPIO_B   4   //bit 4 in uc480i/uc480p/uc720p/uc1080i, which represend the default gpio bit setting for the mode.
+
+
+typedef struct _ATOM_COMPONENT_VIDEO_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;
+  USHORT             usMask_PinRegisterIndex;
+  USHORT             usEN_PinRegisterIndex;
+  USHORT             usY_PinRegisterIndex;
+  USHORT             usA_PinRegisterIndex;
+  UCHAR              ucBitShift;
+  UCHAR              ucPinActiveState;  //ucPinActiveState: Bit0=1 active high, =0 active low
+  ATOM_DTD_FORMAT    sReserved;         // must be zeroed out
+  UCHAR              ucMiscInfo;
+  UCHAR              uc480i;
+  UCHAR              uc480p;
+  UCHAR              uc720p;
+  UCHAR              uc1080i;
+  UCHAR              ucLetterBoxMode;
+  UCHAR              ucReserved[3];
+  UCHAR              ucNumOfWbGpioBlocks; //For Component video D-Connector support. If zere, NTSC type connector
+  ATOM_GPIO_INFO     aWbGpioStateBlock[MAX_SUPPORTED_CV_STANDARDS];
+  ATOM_DTD_FORMAT    aModeTimings[MAX_SUPPORTED_CV_STANDARDS];
+}ATOM_COMPONENT_VIDEO_INFO;
+
+//ucTableFormatRevision=2
+//ucTableContentRevision=1
+typedef struct _ATOM_COMPONENT_VIDEO_INFO_V21
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;
+  UCHAR              ucMiscInfo;
+  UCHAR              uc480i;
+  UCHAR              uc480p;
+  UCHAR              uc720p;
+  UCHAR              uc1080i;
+  UCHAR              ucReserved;
+  UCHAR              ucLetterBoxMode;
+  UCHAR              ucNumOfWbGpioBlocks; //For Component video D-Connector support. If zere, NTSC type connector
+  ATOM_GPIO_INFO     aWbGpioStateBlock[MAX_SUPPORTED_CV_STANDARDS];
+  ATOM_DTD_FORMAT    aModeTimings[MAX_SUPPORTED_CV_STANDARDS];
+}ATOM_COMPONENT_VIDEO_INFO_V21;
+
+#define ATOM_COMPONENT_VIDEO_INFO_LAST  ATOM_COMPONENT_VIDEO_INFO_V21
+
+/**************************************************************************/
+//Object table starts here
+typedef struct _ATOM_OBJECT_HEADER
+{ 
+  ATOM_COMMON_TABLE_HEADER	sHeader;
+  USHORT                    usDeviceSupport;
+  USHORT                    usConnectorObjectTableOffset;
+  USHORT                    usRouterObjectTableOffset;
+  USHORT                    usEncoderObjectTableOffset;
+  USHORT                    usProtectionObjectTableOffset; //only available when Protection block is independent.
+  USHORT                    usDisplayPathTableOffset;
+}ATOM_OBJECT_HEADER;
+
+
+typedef struct  _ATOM_DISPLAY_OBJECT_PATH
+{
+  USHORT    usDeviceTag;                                   //supported device 
+  USHORT    usSize;                                        //the size of ATOM_DISPLAY_OBJECT_PATH
+  USHORT    usConnObjectId;                                //Connector Object ID 
+  USHORT    usGPUObjectId;                                 //GPU ID 
+  USHORT    usGraphicObjIds[1];                             //1st Encoder Obj source from GPU to last Graphic Obj destinate to connector.
+}ATOM_DISPLAY_OBJECT_PATH;
+
+typedef struct _ATOM_DISPLAY_OBJECT_PATH_TABLE
+{
+  UCHAR                           ucNumOfDispPath;
+  UCHAR                           ucVersion;
+  UCHAR                           ucPadding[2];
+  ATOM_DISPLAY_OBJECT_PATH        asDispPath[1];
+}ATOM_DISPLAY_OBJECT_PATH_TABLE;
+
+
+typedef struct _ATOM_OBJECT                                //each object has this structure    
+{
+  USHORT              usObjectID;
+  USHORT              usSrcDstTableOffset;
+  USHORT              usRecordOffset;                     //this pointing to a bunch of records defined below
+  USHORT              usReserved;
+}ATOM_OBJECT;
+
+typedef struct _ATOM_OBJECT_TABLE                         //Above 4 object table offset pointing to a bunch of objects all have this structure     
+{
+  UCHAR               ucNumberOfObjects;
+  UCHAR               ucPadding[3];
+  ATOM_OBJECT         asObjects[1];
+}ATOM_OBJECT_TABLE;
+
+typedef struct _ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT         //usSrcDstTableOffset pointing to this structure
+{
+  UCHAR               ucNumberOfSrc;
+  USHORT              usSrcObjectID[1];
+  UCHAR               ucNumberOfDst;
+  USHORT              usDstObjectID[1];
+}ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT;
+
+
+//Related definitions, all records are differnt but they have a commond header
+typedef struct _ATOM_COMMON_RECORD_HEADER
+{
+  UCHAR               ucRecordType;                      //An emun to indicate the record type
+  UCHAR               ucRecordSize;                      //The size of the whole record in byte
+}ATOM_COMMON_RECORD_HEADER;
+
+
+#define ATOM_I2C_RECORD_TYPE                           1         
+#define ATOM_HPD_INT_RECORD_TYPE                       2
+#define ATOM_OUTPUT_PROTECTION_RECORD_TYPE             3
+#define ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE          4
+#define	ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD_TYPE	     5 //Obsolete, switch to use GPIO_CNTL_RECORD_TYPE
+#define ATOM_ENCODER_FPGA_CONTROL_RECORD_TYPE          6 //Obsolete, switch to use GPIO_CNTL_RECORD_TYPE
+#define ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD_TYPE      7
+#define ATOM_JTAG_RECORD_TYPE                          8 //Obsolete, switch to use GPIO_CNTL_RECORD_TYPE
+#define ATOM_OBJECT_GPIO_CNTL_RECORD_TYPE              9
+#define ATOM_ENCODER_DVO_CF_RECORD_TYPE               10
+#define ATOM_CONNECTOR_CF_RECORD_TYPE                 11
+#define	ATOM_CONNECTOR_HARDCODE_DTD_RECORD_TYPE	      12
+#define ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD_TYPE  13
+#define ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE				14
+#define ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE					15
+
+//Must be updated when new record type is added,equal to that record definition!
+#define ATOM_MAX_OBJECT_RECORD_NUMBER             ATOM_CONNECTOR_CF_RECORD_TYPE     
+
+typedef struct  _ATOM_I2C_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  ATOM_I2C_ID_CONFIG          sucI2cId; 
+  UCHAR                       ucI2CAddr;              //The slave address, it's 0 when the record is attached to connector for DDC
+}ATOM_I2C_RECORD;
+
+typedef struct  _ATOM_HPD_INT_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR                       ucHPDIntGPIOID;         //Corresponding block in GPIO_PIN_INFO table gives the pin info           
+  UCHAR                       ucPluggged_PinState;
+}ATOM_HPD_INT_RECORD;
+
+
+typedef struct  _ATOM_OUTPUT_PROTECTION_RECORD 
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR                       ucProtectionFlag;
+  UCHAR                       ucReserved;
+}ATOM_OUTPUT_PROTECTION_RECORD;
+
+typedef struct  _ATOM_CONNECTOR_DEVICE_TAG
+{
+  ULONG                       ulACPIDeviceEnum;       //Reserved for now
+  USHORT                      usDeviceID;             //This Id is same as "ATOM_DEVICE_XXX_SUPPORT"
+  USHORT                      usPadding;
+}ATOM_CONNECTOR_DEVICE_TAG;
+
+typedef struct  _ATOM_CONNECTOR_DEVICE_TAG_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR                       ucNumberOfDevice;
+  UCHAR                       ucReserved;
+  ATOM_CONNECTOR_DEVICE_TAG   asDeviceTag[1];         //This Id is same as "ATOM_DEVICE_XXX_SUPPORT", 1 is only for allocation
+}ATOM_CONNECTOR_DEVICE_TAG_RECORD;
+
+
+typedef struct  _ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR						            ucConfigGPIOID;
+  UCHAR						            ucConfigGPIOState;	    //Set to 1 when it's active high to enable external flow in
+  UCHAR                       ucFlowinGPIPID;
+  UCHAR                       ucExtInGPIPID;
+}ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD;
+
+typedef struct  _ATOM_ENCODER_FPGA_CONTROL_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR                       ucCTL1GPIO_ID;
+  UCHAR                       ucCTL1GPIOState;        //Set to 1 when it's active high
+  UCHAR                       ucCTL2GPIO_ID;
+  UCHAR                       ucCTL2GPIOState;        //Set to 1 when it's active high
+  UCHAR                       ucCTL3GPIO_ID;
+  UCHAR                       ucCTL3GPIOState;        //Set to 1 when it's active high
+  UCHAR                       ucCTLFPGA_IN_ID;
+  UCHAR                       ucPadding[3];
+}ATOM_ENCODER_FPGA_CONTROL_RECORD;
+
+typedef struct  _ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR                       ucGPIOID;               //Corresponding block in GPIO_PIN_INFO table gives the pin info 
+  UCHAR                       ucTVActiveState;        //Indicating when the pin==0 or 1 when TV is connected
+}ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD;
+
+typedef struct  _ATOM_JTAG_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR                       ucTMSGPIO_ID;
+  UCHAR                       ucTMSGPIOState;         //Set to 1 when it's active high
+  UCHAR                       ucTCKGPIO_ID;
+  UCHAR                       ucTCKGPIOState;         //Set to 1 when it's active high
+  UCHAR                       ucTDOGPIO_ID;
+  UCHAR                       ucTDOGPIOState;         //Set to 1 when it's active high
+  UCHAR                       ucTDIGPIO_ID;
+  UCHAR                       ucTDIGPIOState;         //Set to 1 when it's active high
+  UCHAR                       ucPadding[2];
+}ATOM_JTAG_RECORD;
+
+
+//The following generic object gpio pin control record type will replace JTAG_RECORD/FPGA_CONTROL_RECORD/DVI_EXT_INPUT_RECORD above gradually
+typedef struct _ATOM_GPIO_PIN_CONTROL_PAIR
+{
+  UCHAR                       ucGPIOID;               // GPIO_ID, find the corresponding ID in GPIO_LUT table
+  UCHAR                       ucGPIO_PinState;        // Pin state showing how to set-up the pin
+}ATOM_GPIO_PIN_CONTROL_PAIR;
+
+typedef struct  _ATOM_OBJECT_GPIO_CNTL_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  UCHAR                       ucFlags;                // Future expnadibility
+  UCHAR                       ucNumberOfPins;         // Number of GPIO pins used to control the object
+  ATOM_GPIO_PIN_CONTROL_PAIR  asGpio[1];              // the real gpio pin pair determined by number of pins ucNumberOfPins
+}ATOM_OBJECT_GPIO_CNTL_RECORD;
+
+//Definitions for GPIO pin state 
+#define GPIO_PIN_TYPE_INPUT             0x00
+#define GPIO_PIN_TYPE_OUTPUT            0x10
+#define GPIO_PIN_TYPE_HW_CONTROL        0x20
+
+//For GPIO_PIN_TYPE_OUTPUT the following is defined 
+#define GPIO_PIN_OUTPUT_STATE_MASK      0x01
+#define GPIO_PIN_OUTPUT_STATE_SHIFT     0
+#define GPIO_PIN_STATE_ACTIVE_LOW       0x0
+#define GPIO_PIN_STATE_ACTIVE_HIGH      0x1
+
+typedef struct  _ATOM_ENCODER_DVO_CF_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  ULONG                       ulStrengthControl;      // DVOA strength control for CF
+  UCHAR                       ucPadding[2];
+}ATOM_ENCODER_DVO_CF_RECORD;
+
+// value for ATOM_CONNECTOR_CF_RECORD.ucConnectedDvoBundle
+#define ATOM_CONNECTOR_CF_RECORD_CONNECTED_UPPER12BITBUNDLEA   1
+#define ATOM_CONNECTOR_CF_RECORD_CONNECTED_LOWER12BITBUNDLEB   2
+
+typedef struct  _ATOM_CONNECTOR_CF_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+  USHORT                      usMaxPixClk;
+  UCHAR                       ucFlowCntlGpioId;
+  UCHAR                       ucSwapCntlGpioId;
+  UCHAR                       ucConnectedDvoBundle;
+  UCHAR                       ucPadding;
+}ATOM_CONNECTOR_CF_RECORD;
+
+typedef struct  _ATOM_CONNECTOR_HARDCODE_DTD_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;
+	ATOM_DTD_FORMAT							asTiming;
+}ATOM_CONNECTOR_HARDCODE_DTD_RECORD;
+
+typedef struct _ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD
+{
+  ATOM_COMMON_RECORD_HEADER   sheader;                //ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD_TYPE
+  UCHAR                       ucSubConnectorType;     //CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D|X_ID_DUAL_LINK_DVI_D|HDMI_TYPE_A
+  UCHAR                       ucReserved;
+}ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD;
+
+
+typedef struct _ATOM_ROUTER_DDC_PATH_SELECT_RECORD
+{
+	ATOM_COMMON_RECORD_HEADER   sheader;                
+	UCHAR												ucMuxType;							//decide the number of ucMuxState, =0, no pin state, =1: single state with complement, >1: multiple state
+	UCHAR												ucMuxControlPin;
+	UCHAR												ucMuxState[2];					//for alligment purpose
+}ATOM_ROUTER_DDC_PATH_SELECT_RECORD;
+
+typedef struct _ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD
+{
+	ATOM_COMMON_RECORD_HEADER   sheader;                
+	UCHAR												ucMuxType;
+	UCHAR												ucMuxControlPin;
+	UCHAR												ucMuxState[2];					//for alligment purpose
+}ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD;
+
+// define ucMuxType
+#define ATOM_ROUTER_MUX_PIN_STATE_MASK								0x0f
+#define ATOM_ROUTER_MUX_PIN_SINGLE_STATE_COMPLEMENT		0x01
+
+/**************************************************************************/
+//ASIC voltage data table starts here
+
+typedef struct  _ATOM_VOLTAGE_INFO_HEADER
+{
+   USHORT   usVDDCBaseLevel;                //In number of 50mv unit
+   USHORT   usReserved;                     //For possible extension table offset
+   UCHAR    ucNumOfVoltageEntries;
+   UCHAR    ucBytesPerVoltageEntry;
+   UCHAR    ucVoltageStep;                  //Indicating in how many mv increament is one step, 0.5mv unit
+   UCHAR    ucDefaultVoltageEntry;
+   UCHAR    ucVoltageControlI2cLine;
+   UCHAR    ucVoltageControlAddress;
+   UCHAR    ucVoltageControlOffset;
+}ATOM_VOLTAGE_INFO_HEADER;
+
+typedef struct  _ATOM_VOLTAGE_INFO
+{
+   ATOM_COMMON_TABLE_HEADER	sHeader; 
+   ATOM_VOLTAGE_INFO_HEADER viHeader;
+   UCHAR    ucVoltageEntries[64];            //64 is for allocation, the actual number of entry is present at ucNumOfVoltageEntries*ucBytesPerVoltageEntry
+}ATOM_VOLTAGE_INFO;
+
+
+typedef struct  _ATOM_VOLTAGE_FORMULA
+{
+   USHORT   usVoltageBaseLevel;             // In number of 1mv unit
+   USHORT   usVoltageStep;                  // Indicating in how many mv increament is one step, 1mv unit
+	 UCHAR		ucNumOfVoltageEntries;					// Number of Voltage Entry, which indicate max Voltage
+	 UCHAR		ucFlag;													// bit0=0 :step is 1mv =1 0.5mv
+	 UCHAR		ucBaseVID;											// if there is no lookup table, VID= BaseVID + ( Vol - BaseLevle ) /VoltageStep
+	 UCHAR		ucReserved;
+	 UCHAR		ucVIDAdjustEntries[32];					// 32 is for allocation, the actual number of entry is present at ucNumOfVoltageEntries
+}ATOM_VOLTAGE_FORMULA;
+
+typedef struct _ATOM_VOLTAGE_CONTROL
+{
+	UCHAR		 ucVoltageControlId;							//Indicate it is controlled by I2C or GPIO or HW state machine		
+  UCHAR    ucVoltageControlI2cLine;
+  UCHAR    ucVoltageControlAddress;
+  UCHAR    ucVoltageControlOffset;	 	
+  USHORT   usGpioPin_AIndex;								//GPIO_PAD register index
+  UCHAR    ucGpioPinBitShift[9];						//at most 8 pin support 255 VIDs, termintate with 0xff
+	UCHAR		 ucReserved;
+}ATOM_VOLTAGE_CONTROL;
+
+// Define ucVoltageControlId
+#define	VOLTAGE_CONTROLLED_BY_HW							0x00
+#define	VOLTAGE_CONTROLLED_BY_I2C_MASK				0x7F
+#define	VOLTAGE_CONTROLLED_BY_GPIO						0x80
+#define	VOLTAGE_CONTROL_ID_LM64								0x01									//I2C control, used for R5xx Core Voltage
+#define	VOLTAGE_CONTROL_ID_DAC								0x02									//I2C control, used for R5xx/R6xx MVDDC,MVDDQ or VDDCI
+#define	VOLTAGE_CONTROL_ID_VT116xM						0x03									//I2C control, used for R6xx Core Voltage
+#define VOLTAGE_CONTROL_ID_DS4402							0x04									
+
+typedef struct  _ATOM_VOLTAGE_OBJECT
+{
+ 	 UCHAR		ucVoltageType;									//Indicate Voltage Source: VDDC, MVDDC, MVDDQ or MVDDCI	 
+	 UCHAR		ucSize;													//Size of Object	
+	 ATOM_VOLTAGE_CONTROL			asControl;			//describ how to control 	 
+ 	 ATOM_VOLTAGE_FORMULA			asFormula;			//Indicate How to convert real Voltage to VID 
+}ATOM_VOLTAGE_OBJECT;
+
+typedef struct  _ATOM_VOLTAGE_OBJECT_INFO
+{
+   ATOM_COMMON_TABLE_HEADER	sHeader; 
+	 ATOM_VOLTAGE_OBJECT			asVoltageObj[3];	//Info for Voltage control	  	 
+}ATOM_VOLTAGE_OBJECT_INFO;
+
+typedef struct  _ATOM_LEAKID_VOLTAGE
+{
+	UCHAR		ucLeakageId;
+	UCHAR		ucReserved;
+	USHORT	usVoltage;
+}ATOM_LEAKID_VOLTAGE;
+
+typedef struct  _ATOM_ASIC_PROFILE_VOLTAGE
+{
+	UCHAR		ucProfileId;
+	UCHAR		ucReserved;
+	USHORT	usSize;
+	USHORT	usEfuseSpareStartAddr;
+	USHORT	usFuseIndex[8];												//from LSB to MSB, Max 8bit,end of 0xffff if less than 8 efuse id, 
+	ATOM_LEAKID_VOLTAGE					asLeakVol[2];			//Leakid and relatd voltage
+}ATOM_ASIC_PROFILE_VOLTAGE;
+
+//ucProfileId
+#define	ATOM_ASIC_PROFILE_ID_EFUSE_VOLTAGE			1		
+#define	ATOM_ASIC_PROFILE_ID_EFUSE_PERFORMANCE_VOLTAGE			1
+#define	ATOM_ASIC_PROFILE_ID_EFUSE_THERMAL_VOLTAGE					2
+
+typedef struct  _ATOM_ASIC_PROFILING_INFO
+{
+  ATOM_COMMON_TABLE_HEADER			asHeader; 
+	ATOM_ASIC_PROFILE_VOLTAGE			asVoltage;
+}ATOM_ASIC_PROFILING_INFO;
+
+typedef struct _ATOM_POWER_SOURCE_OBJECT
+{
+	UCHAR	ucPwrSrcId;													// Power source
+	UCHAR	ucPwrSensorType;										// GPIO, I2C or none
+	UCHAR	ucPwrSensId;											  // if GPIO detect, it is GPIO id,  if I2C detect, it is I2C id
+	UCHAR	ucPwrSensSlaveAddr;									// Slave address if I2C detect
+	UCHAR ucPwrSensRegIndex;									// I2C register Index if I2C detect
+	UCHAR ucPwrSensRegBitMask;								// detect which bit is used if I2C detect
+	UCHAR	ucPwrSensActiveState;								// high active or low active
+	UCHAR	ucReserve[3];												// reserve		
+	USHORT usSensPwr;													// in unit of watt
+}ATOM_POWER_SOURCE_OBJECT;
+
+typedef struct _ATOM_POWER_SOURCE_INFO
+{
+		ATOM_COMMON_TABLE_HEADER		asHeader;
+		UCHAR												asPwrbehave[16];
+		ATOM_POWER_SOURCE_OBJECT		asPwrObj[1];
+}ATOM_POWER_SOURCE_INFO;
+
+
+//Define ucPwrSrcId
+#define POWERSOURCE_PCIE_ID1						0x00
+#define POWERSOURCE_6PIN_CONNECTOR_ID1	0x01
+#define POWERSOURCE_8PIN_CONNECTOR_ID1	0x02
+#define POWERSOURCE_6PIN_CONNECTOR_ID2	0x04
+#define POWERSOURCE_8PIN_CONNECTOR_ID2	0x08
+
+//define ucPwrSensorId
+#define POWER_SENSOR_ALWAYS							0x00
+#define POWER_SENSOR_GPIO								0x01
+#define POWER_SENSOR_I2C								0x02
+
+/**************************************************************************/
+// This portion is only used when ext thermal chip or engine/memory clock SS chip is populated on a design
+//Memory SS Info Table
+//Define Memory Clock SS chip ID
+#define ICS91719  1
+#define ICS91720  2
+
+//Define one structure to inform SW a "block of data" writing to external SS chip via I2C protocol
+typedef struct _ATOM_I2C_DATA_RECORD
+{
+  UCHAR         ucNunberOfBytes;                                              //Indicates how many bytes SW needs to write to the external ASIC for one block, besides to "Start" and "Stop"
+  UCHAR         ucI2CData[1];                                                 //I2C data in bytes, should be less than 16 bytes usually
+}ATOM_I2C_DATA_RECORD;
+
+
+//Define one structure to inform SW how many blocks of data writing to external SS chip via I2C protocol, in addition to other information
+typedef struct _ATOM_I2C_DEVICE_SETUP_INFO
+{
+  ATOM_I2C_ID_CONFIG_ACCESS       sucI2cId;               //I2C line and HW/SW assisted cap.
+  UCHAR		                        ucSSChipID;             //SS chip being used
+  UCHAR		                        ucSSChipSlaveAddr;      //Slave Address to set up this SS chip
+  UCHAR                           ucNumOfI2CDataRecords;  //number of data block
+  ATOM_I2C_DATA_RECORD            asI2CData[1];  
+}ATOM_I2C_DEVICE_SETUP_INFO;
+
+//==========================================================================================
+typedef struct  _ATOM_ASIC_MVDD_INFO
+{
+  ATOM_COMMON_TABLE_HEADER	      sHeader; 
+  ATOM_I2C_DEVICE_SETUP_INFO      asI2CSetup[1];
+}ATOM_ASIC_MVDD_INFO;
+
+//==========================================================================================
+#define ATOM_MCLK_SS_INFO         ATOM_ASIC_MVDD_INFO
+
+//==========================================================================================
+/**************************************************************************/
+
+typedef struct _ATOM_ASIC_SS_ASSIGNMENT
+{
+	ULONG								ulTargetClockRange;						//Clock Out frequence (VCO ), in unit of 10Khz
+  USHORT              usSpreadSpectrumPercentage;		//in unit of 0.01%
+	USHORT							usSpreadRateInKhz;						//in unit of kHz, modulation freq
+  UCHAR               ucClockIndication;					  //Indicate which clock source needs SS
+	UCHAR								ucSpreadSpectrumMode;					//Bit1=0 Down Spread,=1 Center Spread.
+	UCHAR								ucReserved[2];
+}ATOM_ASIC_SS_ASSIGNMENT;
+
+//Define ucSpreadSpectrumType
+#define ASIC_INTERNAL_MEMORY_SS			1
+#define ASIC_INTERNAL_ENGINE_SS			2
+#define ASIC_INTERNAL_UVD_SS				3
+
+typedef struct _ATOM_ASIC_INTERNAL_SS_INFO{
+  ATOM_COMMON_TABLE_HEADER	      sHeader; 
+  ATOM_ASIC_SS_ASSIGNMENT		      asSpreadSpectrum[4];
+}ATOM_ASIC_INTERNAL_SS_INFO;
+
+//==============================Scratch Pad Definition Portion===============================
+#define ATOM_DEVICE_CONNECT_INFO_DEF  0
+#define ATOM_ROM_LOCATION_DEF         1
+#define ATOM_TV_STANDARD_DEF          2
+#define ATOM_ACTIVE_INFO_DEF          3
+#define ATOM_LCD_INFO_DEF             4
+#define ATOM_DOS_REQ_INFO_DEF         5
+#define ATOM_ACC_CHANGE_INFO_DEF      6
+#define ATOM_DOS_MODE_INFO_DEF        7
+#define ATOM_I2C_CHANNEL_STATUS_DEF   8
+#define ATOM_I2C_CHANNEL_STATUS1_DEF  9
+
+
+// BIOS_0_SCRATCH Definition 
+#define ATOM_S0_CRT1_MONO               0x00000001L
+#define ATOM_S0_CRT1_COLOR              0x00000002L
+#define ATOM_S0_CRT1_MASK               (ATOM_S0_CRT1_MONO+ATOM_S0_CRT1_COLOR)
+
+#define ATOM_S0_TV1_COMPOSITE_A         0x00000004L
+#define ATOM_S0_TV1_SVIDEO_A            0x00000008L
+#define ATOM_S0_TV1_MASK_A              (ATOM_S0_TV1_COMPOSITE_A+ATOM_S0_TV1_SVIDEO_A)
+
+#define ATOM_S0_CV_A                    0x00000010L
+#define ATOM_S0_CV_DIN_A                0x00000020L
+#define ATOM_S0_CV_MASK_A               (ATOM_S0_CV_A+ATOM_S0_CV_DIN_A)
+
+
+#define ATOM_S0_CRT2_MONO               0x00000100L
+#define ATOM_S0_CRT2_COLOR              0x00000200L
+#define ATOM_S0_CRT2_MASK               (ATOM_S0_CRT2_MONO+ATOM_S0_CRT2_COLOR)
+
+#define ATOM_S0_TV1_COMPOSITE           0x00000400L
+#define ATOM_S0_TV1_SVIDEO              0x00000800L
+#define ATOM_S0_TV1_SCART               0x00004000L
+#define ATOM_S0_TV1_MASK                (ATOM_S0_TV1_COMPOSITE+ATOM_S0_TV1_SVIDEO+ATOM_S0_TV1_SCART)
+
+#define ATOM_S0_CV                      0x00001000L
+#define ATOM_S0_CV_DIN                  0x00002000L
+#define ATOM_S0_CV_MASK                 (ATOM_S0_CV+ATOM_S0_CV_DIN)
+
+
+#define ATOM_S0_DFP1                    0x00010000L
+#define ATOM_S0_DFP2                    0x00020000L
+#define ATOM_S0_LCD1                    0x00040000L
+#define ATOM_S0_LCD2                    0x00080000L
+#define ATOM_S0_TV2                     0x00100000L
+#define ATOM_S0_DFP3										0x00200000L
+
+#define ATOM_S0_FAD_REGISTER_BUG        0x02000000L // If set, indicates we are running a PCIE asic with 
+                                                    // the FAD/HDP reg access bug.  Bit is read by DAL
+
+#define ATOM_S0_THERMAL_STATE_MASK      0x1C000000L
+#define ATOM_S0_THERMAL_STATE_SHIFT     26
+
+#define ATOM_S0_SYSTEM_POWER_STATE_MASK 0xE0000000L
+#define ATOM_S0_SYSTEM_POWER_STATE_SHIFT 29 
+
+#define ATOM_S0_SYSTEM_POWER_STATE_VALUE_AC     1
+#define ATOM_S0_SYSTEM_POWER_STATE_VALUE_DC     2
+#define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LITEAC 3
+
+//Byte aligned defintion for BIOS usage
+#define ATOM_S0_CRT1_MONOb0             0x01
+#define ATOM_S0_CRT1_COLORb0            0x02
+#define ATOM_S0_CRT1_MASKb0             (ATOM_S0_CRT1_MONOb0+ATOM_S0_CRT1_COLORb0)
+
+#define ATOM_S0_TV1_COMPOSITEb0         0x04
+#define ATOM_S0_TV1_SVIDEOb0            0x08
+#define ATOM_S0_TV1_MASKb0              (ATOM_S0_TV1_COMPOSITEb0+ATOM_S0_TV1_SVIDEOb0)
+
+#define ATOM_S0_CVb0                    0x10
+#define ATOM_S0_CV_DINb0                0x20
+#define ATOM_S0_CV_MASKb0               (ATOM_S0_CVb0+ATOM_S0_CV_DINb0)
+
+#define ATOM_S0_CRT2_MONOb1             0x01
+#define ATOM_S0_CRT2_COLORb1            0x02
+#define ATOM_S0_CRT2_MASKb1             (ATOM_S0_CRT2_MONOb1+ATOM_S0_CRT2_COLORb1)
+
+#define ATOM_S0_TV1_COMPOSITEb1         0x04
+#define ATOM_S0_TV1_SVIDEOb1            0x08
+#define ATOM_S0_TV1_SCARTb1             0x40
+#define ATOM_S0_TV1_MASKb1              (ATOM_S0_TV1_COMPOSITEb1+ATOM_S0_TV1_SVIDEOb1+ATOM_S0_TV1_SCARTb1)
+
+#define ATOM_S0_CVb1                    0x10
+#define ATOM_S0_CV_DINb1                0x20
+#define ATOM_S0_CV_MASKb1               (ATOM_S0_CVb1+ATOM_S0_CV_DINb1)
+
+#define ATOM_S0_DFP1b2                  0x01
+#define ATOM_S0_DFP2b2                  0x02
+#define ATOM_S0_LCD1b2                  0x04
+#define ATOM_S0_LCD2b2                  0x08
+#define ATOM_S0_TV2b2                   0x10
+#define ATOM_S0_DFP3b2									0x20
+
+#define ATOM_S0_THERMAL_STATE_MASKb3    0x1C
+#define ATOM_S0_THERMAL_STATE_SHIFTb3   2
+
+#define ATOM_S0_SYSTEM_POWER_STATE_MASKb3 0xE0
+#define ATOM_S0_LCD1_SHIFT              18
+
+// BIOS_1_SCRATCH Definition
+#define ATOM_S1_ROM_LOCATION_MASK       0x0000FFFFL
+#define ATOM_S1_PCI_BUS_DEV_MASK        0xFFFF0000L
+
+     
+//	BIOS_2_SCRATCH Definition
+#define ATOM_S2_TV1_STANDARD_MASK       0x0000000FL
+#define ATOM_S2_CURRENT_BL_LEVEL_MASK   0x0000FF00L
+#define ATOM_S2_CURRENT_BL_LEVEL_SHIFT  8
+
+#define ATOM_S2_CRT1_DPMS_STATE         0x00010000L
+#define ATOM_S2_LCD1_DPMS_STATE	        0x00020000L
+#define ATOM_S2_TV1_DPMS_STATE          0x00040000L
+#define ATOM_S2_DFP1_DPMS_STATE         0x00080000L
+#define ATOM_S2_CRT2_DPMS_STATE         0x00100000L
+#define ATOM_S2_LCD2_DPMS_STATE         0x00200000L
+#define ATOM_S2_TV2_DPMS_STATE          0x00400000L
+#define ATOM_S2_DFP2_DPMS_STATE         0x00800000L
+#define ATOM_S2_CV_DPMS_STATE           0x01000000L
+#define ATOM_S2_DFP3_DPMS_STATE					0x02000000L
+
+#define ATOM_S2_DEVICE_DPMS_STATE       (ATOM_S2_CRT1_DPMS_STATE+ATOM_S2_LCD1_DPMS_STATE+ATOM_S2_TV1_DPMS_STATE+\
+                                        ATOM_S2_DFP1I_DPMS_STATE+ATOM_S2_CRT2_DPMS_STATE+ATOM_S2_LCD2_DPMS_STATE+\
+                                        ATOM_S2_TV2_DPMS_STATE+ATOM_S2_DFP1X_DPMS_STATE+ATOM_S2_CV_DPMS_STATE+\
+                                        ATOM_S2_DFP3_DPMS_STATE)
+
+
+#define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASK       0x0C000000L
+#define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASK_SHIFT 26
+#define ATOM_S2_FORCEDLOWPWRMODE_STATE_CHANGE     0x10000000L
+
+#define ATOM_S2_VRI_BRIGHT_ENABLE       0x20000000L
+
+#define ATOM_S2_DISPLAY_ROTATION_0_DEGREE     0x0
+#define ATOM_S2_DISPLAY_ROTATION_90_DEGREE    0x1
+#define ATOM_S2_DISPLAY_ROTATION_180_DEGREE   0x2
+#define ATOM_S2_DISPLAY_ROTATION_270_DEGREE   0x3
+#define ATOM_S2_DISPLAY_ROTATION_DEGREE_SHIFT 30
+#define ATOM_S2_DISPLAY_ROTATION_ANGLE_MASK   0xC0000000L
+
+
+//Byte aligned defintion for BIOS usage
+#define ATOM_S2_TV1_STANDARD_MASKb0     0x0F
+#define ATOM_S2_CURRENT_BL_LEVEL_MASKb1 0xFF
+#define ATOM_S2_CRT1_DPMS_STATEb2       0x01
+#define ATOM_S2_LCD1_DPMS_STATEb2       0x02
+#define ATOM_S2_TV1_DPMS_STATEb2        0x04
+#define ATOM_S2_DFP1_DPMS_STATEb2       0x08
+#define ATOM_S2_CRT2_DPMS_STATEb2       0x10
+#define ATOM_S2_LCD2_DPMS_STATEb2       0x20
+#define ATOM_S2_TV2_DPMS_STATEb2        0x40
+#define ATOM_S2_DFP2_DPMS_STATEb2       0x80
+#define ATOM_S2_CV_DPMS_STATEb3         0x01
+#define ATOM_S2_DFP3_DPMS_STATEb3				0x02
+
+#define ATOM_S2_DEVICE_DPMS_MASKw1      0x3FF
+#define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASKb3     0x0C
+#define ATOM_S2_FORCEDLOWPWRMODE_STATE_CHANGEb3   0x10
+#define ATOM_S2_VRI_BRIGHT_ENABLEb3     0x20
+#define ATOM_S2_ROTATION_STATE_MASKb3   0xC0
+
+
+// BIOS_3_SCRATCH Definition
+#define ATOM_S3_CRT1_ACTIVE             0x00000001L
+#define ATOM_S3_LCD1_ACTIVE             0x00000002L
+#define ATOM_S3_TV1_ACTIVE              0x00000004L
+#define ATOM_S3_DFP1_ACTIVE             0x00000008L
+#define ATOM_S3_CRT2_ACTIVE             0x00000010L
+#define ATOM_S3_LCD2_ACTIVE             0x00000020L
+#define ATOM_S3_TV2_ACTIVE              0x00000040L
+#define ATOM_S3_DFP2_ACTIVE             0x00000080L
+#define ATOM_S3_CV_ACTIVE               0x00000100L
+#define ATOM_S3_DFP3_ACTIVE							0x00000200L
+
+#define ATOM_S3_DEVICE_ACTIVE_MASK      0x000003FFL
+
+#define ATOM_S3_CRT1_CRTC_ACTIVE        0x00010000L
+#define ATOM_S3_LCD1_CRTC_ACTIVE        0x00020000L
+#define ATOM_S3_TV1_CRTC_ACTIVE         0x00040000L
+#define ATOM_S3_DFP1_CRTC_ACTIVE        0x00080000L
+#define ATOM_S3_CRT2_CRTC_ACTIVE        0x00100000L
+#define ATOM_S3_LCD2_CRTC_ACTIVE        0x00200000L
+#define ATOM_S3_TV2_CRTC_ACTIVE         0x00400000L
+#define ATOM_S3_DFP2_CRTC_ACTIVE        0x00800000L
+#define ATOM_S3_CV_CRTC_ACTIVE          0x01000000L
+#define ATOM_S3_DFP3_CRTC_ACTIVE				0x02000000L
+
+#define ATOM_S3_DEVICE_CRTC_ACTIVE_MASK 0x03FF0000L
+#define ATOM_S3_ASIC_GUI_ENGINE_HUNG    0x20000000L
+#define ATOM_S3_ALLOW_FAST_PWR_SWITCH   0x40000000L
+#define ATOM_S3_RQST_GPU_USE_MIN_PWR    0x80000000L
+
+//Byte aligned defintion for BIOS usage
+#define ATOM_S3_CRT1_ACTIVEb0           0x01
+#define ATOM_S3_LCD1_ACTIVEb0           0x02
+#define ATOM_S3_TV1_ACTIVEb0            0x04
+#define ATOM_S3_DFP1_ACTIVEb0           0x08
+#define ATOM_S3_CRT2_ACTIVEb0           0x10
+#define ATOM_S3_LCD2_ACTIVEb0           0x20
+#define ATOM_S3_TV2_ACTIVEb0            0x40
+#define ATOM_S3_DFP2_ACTIVEb0           0x80
+#define ATOM_S3_CV_ACTIVEb1             0x01
+#define ATOM_S3_DFP3_ACTIVEb1						0x02
+
+#define ATOM_S3_ACTIVE_CRTC1w0          0x3FF
+
+#define ATOM_S3_CRT1_CRTC_ACTIVEb2      0x01
+#define ATOM_S3_LCD1_CRTC_ACTIVEb2      0x02
+#define ATOM_S3_TV1_CRTC_ACTIVEb2       0x04
+#define ATOM_S3_DFP1_CRTC_ACTIVEb2      0x08
+#define ATOM_S3_CRT2_CRTC_ACTIVEb2      0x10
+#define ATOM_S3_LCD2_CRTC_ACTIVEb2      0x20
+#define ATOM_S3_TV2_CRTC_ACTIVEb2       0x40
+#define ATOM_S3_DFP2_CRTC_ACTIVEb2      0x80
+#define ATOM_S3_CV_CRTC_ACTIVEb3        0x01
+#define ATOM_S3_DFP3_CRTC_ACTIVEb3			0x02
+
+#define ATOM_S3_ACTIVE_CRTC2w1          0x3FF
+
+#define ATOM_S3_ASIC_GUI_ENGINE_HUNGb3	0x20
+#define ATOM_S3_ALLOW_FAST_PWR_SWITCHb3 0x40
+#define ATOM_S3_RQST_GPU_USE_MIN_PWRb3  0x80
+
+// BIOS_4_SCRATCH Definition
+#define ATOM_S4_LCD1_PANEL_ID_MASK      0x000000FFL
+#define ATOM_S4_LCD1_REFRESH_MASK       0x0000FF00L
+#define ATOM_S4_LCD1_REFRESH_SHIFT      8
+
+
+//Byte aligned defintion for BIOS usage
+#define ATOM_S4_LCD1_PANEL_ID_MASKb0	  0x0FF
+#define ATOM_S4_LCD1_REFRESH_MASKb1		  ATOM_S4_LCD1_PANEL_ID_MASKb0
+#define ATOM_S4_VRAM_INFO_MASKb2        ATOM_S4_LCD1_PANEL_ID_MASKb0
+
+
+// BIOS_5_SCRATCH Definition, BIOS_5_SCRATCH is used by Firmware only !!!!
+#define ATOM_S5_DOS_REQ_CRT1b0          0x01
+#define ATOM_S5_DOS_REQ_LCD1b0          0x02
+#define ATOM_S5_DOS_REQ_TV1b0           0x04
+#define ATOM_S5_DOS_REQ_DFP1b0          0x08
+#define ATOM_S5_DOS_REQ_CRT2b0          0x10
+#define ATOM_S5_DOS_REQ_LCD2b0          0x20
+#define ATOM_S5_DOS_REQ_TV2b0           0x40
+#define ATOM_S5_DOS_REQ_DFP2b0          0x80
+#define ATOM_S5_DOS_REQ_CVb1            0x01
+#define ATOM_S5_DOS_REQ_DFP3b1					0x02
+
+#define ATOM_S5_DOS_REQ_DEVICEw0        0x03FF
+
+#define ATOM_S5_DOS_REQ_CRT1            0x0001
+#define ATOM_S5_DOS_REQ_LCD1            0x0002
+#define ATOM_S5_DOS_REQ_TV1             0x0004
+#define ATOM_S5_DOS_REQ_DFP1            0x0008
+#define ATOM_S5_DOS_REQ_CRT2            0x0010
+#define ATOM_S5_DOS_REQ_LCD2            0x0020
+#define ATOM_S5_DOS_REQ_TV2             0x0040
+#define ATOM_S5_DOS_REQ_DFP2            0x0080
+#define ATOM_S5_DOS_REQ_CV              0x0100
+#define ATOM_S5_DOS_REQ_DFP3						0x0200
+
+#define ATOM_S5_DOS_FORCE_CRT1b2        ATOM_S5_DOS_REQ_CRT1b0
+#define ATOM_S5_DOS_FORCE_TV1b2         ATOM_S5_DOS_REQ_TV1b0
+#define ATOM_S5_DOS_FORCE_CRT2b2        ATOM_S5_DOS_REQ_CRT2b0
+#define ATOM_S5_DOS_FORCE_CVb3          ATOM_S5_DOS_REQ_CVb1
+#define ATOM_S5_DOS_FORCE_DEVICEw1      (ATOM_S5_DOS_FORCE_CRT1b2+ATOM_S5_DOS_FORCE_TV1b2+ATOM_S5_DOS_FORCE_CRT2b2+\
+                                        (ATOM_S5_DOS_FORCE_CVb3<<8))
+
+// BIOS_6_SCRATCH Definition
+#define ATOM_S6_DEVICE_CHANGE           0x00000001L
+#define ATOM_S6_SCALER_CHANGE           0x00000002L
+#define ATOM_S6_LID_CHANGE              0x00000004L
+#define ATOM_S6_DOCKING_CHANGE          0x00000008L
+#define ATOM_S6_ACC_MODE                0x00000010L
+#define ATOM_S6_EXT_DESKTOP_MODE        0x00000020L
+#define ATOM_S6_LID_STATE               0x00000040L
+#define ATOM_S6_DOCK_STATE              0x00000080L
+#define ATOM_S6_CRITICAL_STATE          0x00000100L
+#define ATOM_S6_HW_I2C_BUSY_STATE       0x00000200L
+#define ATOM_S6_THERMAL_STATE_CHANGE    0x00000400L
+#define ATOM_S6_INTERRUPT_SET_BY_BIOS   0x00000800L
+#define ATOM_S6_REQ_LCD_EXPANSION_FULL         0x00001000L //Normal expansion Request bit for LCD
+#define ATOM_S6_REQ_LCD_EXPANSION_ASPEC_RATIO  0x00002000L //Aspect ratio expansion Request bit for LCD
+
+#define ATOM_S6_DISPLAY_STATE_CHANGE    0x00004000L        //This bit is recycled when ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE is set,previously it's SCL2_H_expansion
+#define ATOM_S6_I2C_STATE_CHANGE        0x00008000L        //This bit is recycled,when ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE is set,previously it's SCL2_V_expansion
+
+
+#define ATOM_S6_ACC_REQ_CRT1            0x00010000L
+#define ATOM_S6_ACC_REQ_LCD1            0x00020000L
+#define ATOM_S6_ACC_REQ_TV1             0x00040000L
+#define ATOM_S6_ACC_REQ_DFP1            0x00080000L
+#define ATOM_S6_ACC_REQ_CRT2            0x00100000L
+#define ATOM_S6_ACC_REQ_LCD2            0x00200000L
+#define ATOM_S6_ACC_REQ_TV2             0x00400000L
+#define ATOM_S6_ACC_REQ_DFP2            0x00800000L
+#define ATOM_S6_ACC_REQ_CV              0x01000000L
+#define ATOM_S6_ACC_REQ_DFP3						0x02000000L
+
+#define ATOM_S6_ACC_REQ_MASK                0x03FF0000L
+#define ATOM_S6_SYSTEM_POWER_MODE_CHANGE    0x10000000L
+#define ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH    0x20000000L
+#define ATOM_S6_VRI_BRIGHTNESS_CHANGE       0x40000000L
+#define ATOM_S6_CONFIG_DISPLAY_CHANGE_MASK  0x80000000L
+
+//Byte aligned defintion for BIOS usage
+#define ATOM_S6_DEVICE_CHANGEb0         0x01
+#define ATOM_S6_SCALER_CHANGEb0         0x02
+#define ATOM_S6_LID_CHANGEb0            0x04
+#define ATOM_S6_DOCKING_CHANGEb0        0x08
+#define ATOM_S6_ACC_MODEb0              0x10
+#define ATOM_S6_EXT_DESKTOP_MODEb0      0x20
+#define ATOM_S6_LID_STATEb0             0x40
+#define ATOM_S6_DOCK_STATEb0            0x80
+#define ATOM_S6_CRITICAL_STATEb1        0x01
+#define ATOM_S6_HW_I2C_BUSY_STATEb1     0x02  
+#define ATOM_S6_THERMAL_STATE_CHANGEb1  0x04
+#define ATOM_S6_INTERRUPT_SET_BY_BIOSb1 0x08
+#define ATOM_S6_REQ_LCD_EXPANSION_FULLb1        0x10    
+#define ATOM_S6_REQ_LCD_EXPANSION_ASPEC_RATIOb1 0x20 
+
+#define ATOM_S6_ACC_REQ_CRT1b2          0x01
+#define ATOM_S6_ACC_REQ_LCD1b2          0x02
+#define ATOM_S6_ACC_REQ_TV1b2           0x04
+#define ATOM_S6_ACC_REQ_DFP1b2          0x08
+#define ATOM_S6_ACC_REQ_CRT2b2          0x10
+#define ATOM_S6_ACC_REQ_LCD2b2          0x20
+#define ATOM_S6_ACC_REQ_TV2b2           0x40
+#define ATOM_S6_ACC_REQ_DFP2b2          0x80
+#define ATOM_S6_ACC_REQ_CVb3            0x01
+#define ATOM_S6_ACC_REQ_DFP3b3					0x02
+
+#define ATOM_S6_ACC_REQ_DEVICEw1        ATOM_S5_DOS_REQ_DEVICEw0
+#define ATOM_S6_SYSTEM_POWER_MODE_CHANGEb3 0x10
+#define ATOM_S6_ACC_BLOCK_DISPLAY_SWITCHb3 0x20
+#define ATOM_S6_VRI_BRIGHTNESS_CHANGEb3    0x40
+#define ATOM_S6_CONFIG_DISPLAY_CHANGEb3    0x80
+
+#define ATOM_S6_DEVICE_CHANGE_SHIFT             0
+#define ATOM_S6_SCALER_CHANGE_SHIFT             1
+#define ATOM_S6_LID_CHANGE_SHIFT                2
+#define ATOM_S6_DOCKING_CHANGE_SHIFT            3
+#define ATOM_S6_ACC_MODE_SHIFT                  4
+#define ATOM_S6_EXT_DESKTOP_MODE_SHIFT          5
+#define ATOM_S6_LID_STATE_SHIFT                 6
+#define ATOM_S6_DOCK_STATE_SHIFT                7
+#define ATOM_S6_CRITICAL_STATE_SHIFT            8
+#define ATOM_S6_HW_I2C_BUSY_STATE_SHIFT         9
+#define ATOM_S6_THERMAL_STATE_CHANGE_SHIFT      10
+#define ATOM_S6_INTERRUPT_SET_BY_BIOS_SHIFT     11
+#define ATOM_S6_REQ_SCALER_SHIFT                12
+#define ATOM_S6_REQ_SCALER_ARATIO_SHIFT         13
+#define ATOM_S6_DISPLAY_STATE_CHANGE_SHIFT      14
+#define ATOM_S6_I2C_STATE_CHANGE_SHIFT          15
+#define ATOM_S6_SYSTEM_POWER_MODE_CHANGE_SHIFT  28
+#define ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH_SHIFT  29
+#define ATOM_S6_VRI_BRIGHTNESS_CHANGE_SHIFT     30
+#define ATOM_S6_CONFIG_DISPLAY_CHANGE_SHIFT     31
+
+// BIOS_7_SCRATCH Definition, BIOS_7_SCRATCH is used by Firmware only !!!!
+#define ATOM_S7_DOS_MODE_TYPEb0             0x03
+#define ATOM_S7_DOS_MODE_VGAb0              0x00
+#define ATOM_S7_DOS_MODE_VESAb0             0x01
+#define ATOM_S7_DOS_MODE_EXTb0              0x02
+#define ATOM_S7_DOS_MODE_PIXEL_DEPTHb0      0x0C
+#define ATOM_S7_DOS_MODE_PIXEL_FORMATb0     0xF0
+#define ATOM_S7_DOS_8BIT_DAC_ENb1           0x01
+#define ATOM_S7_DOS_MODE_NUMBERw1           0x0FFFF
+
+#define ATOM_S7_DOS_8BIT_DAC_EN_SHIFT       8
+
+// BIOS_8_SCRATCH Definition
+#define ATOM_S8_I2C_CHANNEL_BUSY_MASK       0x00000FFFF
+#define ATOM_S8_I2C_HW_ENGINE_BUSY_MASK     0x0FFFF0000   
+
+#define ATOM_S8_I2C_CHANNEL_BUSY_SHIFT      0
+#define ATOM_S8_I2C_ENGINE_BUSY_SHIFT       16
+
+// BIOS_9_SCRATCH Definition
+#ifndef ATOM_S9_I2C_CHANNEL_COMPLETED_MASK 
+#define ATOM_S9_I2C_CHANNEL_COMPLETED_MASK  0x0000FFFF
+#endif
+#ifndef ATOM_S9_I2C_CHANNEL_ABORTED_MASK  
+#define ATOM_S9_I2C_CHANNEL_ABORTED_MASK    0xFFFF0000
+#endif
+#ifndef ATOM_S9_I2C_CHANNEL_COMPLETED_SHIFT 
+#define ATOM_S9_I2C_CHANNEL_COMPLETED_SHIFT 0
+#endif
+#ifndef ATOM_S9_I2C_CHANNEL_ABORTED_SHIFT   
+#define ATOM_S9_I2C_CHANNEL_ABORTED_SHIFT   16
+#endif
+
+ 
+#define ATOM_FLAG_SET                         0x20
+#define ATOM_FLAG_CLEAR                       0
+#define CLEAR_ATOM_S6_ACC_MODE                ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_ACC_MODE_SHIFT | ATOM_FLAG_CLEAR)
+#define SET_ATOM_S6_DEVICE_CHANGE             ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DEVICE_CHANGE_SHIFT | ATOM_FLAG_SET)
+#define SET_ATOM_S6_VRI_BRIGHTNESS_CHANGE     ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_VRI_BRIGHTNESS_CHANGE_SHIFT | ATOM_FLAG_SET)
+#define SET_ATOM_S6_SCALER_CHANGE             ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_SCALER_CHANGE_SHIFT | ATOM_FLAG_SET)
+#define SET_ATOM_S6_LID_CHANGE                ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_LID_CHANGE_SHIFT | ATOM_FLAG_SET)
+
+#define SET_ATOM_S6_LID_STATE                 ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_LID_STATE_SHIFT | ATOM_FLAG_SET)
+#define CLEAR_ATOM_S6_LID_STATE               ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_LID_STATE_SHIFT | ATOM_FLAG_CLEAR)
+
+#define SET_ATOM_S6_DOCK_CHANGE			          ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DOCKING_CHANGE_SHIFT | ATOM_FLAG_SET)
+#define SET_ATOM_S6_DOCK_STATE                ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DOCK_STATE_SHIFT | ATOM_FLAG_SET)
+#define CLEAR_ATOM_S6_DOCK_STATE              ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DOCK_STATE_SHIFT | ATOM_FLAG_CLEAR)
+
+#define SET_ATOM_S6_THERMAL_STATE_CHANGE      ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_THERMAL_STATE_CHANGE_SHIFT | ATOM_FLAG_SET)
+#define SET_ATOM_S6_SYSTEM_POWER_MODE_CHANGE  ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_SYSTEM_POWER_MODE_CHANGE_SHIFT | ATOM_FLAG_SET)
+#define SET_ATOM_S6_INTERRUPT_SET_BY_BIOS     ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_INTERRUPT_SET_BY_BIOS_SHIFT | ATOM_FLAG_SET)
+
+#define SET_ATOM_S6_CRITICAL_STATE            ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_CRITICAL_STATE_SHIFT | ATOM_FLAG_SET)
+#define CLEAR_ATOM_S6_CRITICAL_STATE          ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_CRITICAL_STATE_SHIFT | ATOM_FLAG_CLEAR)
+
+#define SET_ATOM_S6_REQ_SCALER                ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_SHIFT | ATOM_FLAG_SET)  
+#define CLEAR_ATOM_S6_REQ_SCALER              ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_SHIFT | ATOM_FLAG_CLEAR )
+
+#define SET_ATOM_S6_REQ_SCALER_ARATIO         ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_ARATIO_SHIFT | ATOM_FLAG_SET )
+#define CLEAR_ATOM_S6_REQ_SCALER_ARATIO       ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_ARATIO_SHIFT | ATOM_FLAG_CLEAR )
+
+#define SET_ATOM_S6_I2C_STATE_CHANGE          ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_I2C_STATE_CHANGE_SHIFT | ATOM_FLAG_SET )
+
+#define SET_ATOM_S6_DISPLAY_STATE_CHANGE      ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DISPLAY_STATE_CHANGE_SHIFT | ATOM_FLAG_SET )
+
+#define SET_ATOM_S6_DEVICE_RECONFIG           ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_CONFIG_DISPLAY_CHANGE_SHIFT | ATOM_FLAG_SET)
+#define CLEAR_ATOM_S0_LCD1                    ((ATOM_DEVICE_CONNECT_INFO_DEF << 8 )|  ATOM_S0_LCD1_SHIFT | ATOM_FLAG_CLEAR )
+#define SET_ATOM_S7_DOS_8BIT_DAC_EN           ((ATOM_DOS_MODE_INFO_DEF << 8 )|ATOM_S7_DOS_8BIT_DAC_EN_SHIFT | ATOM_FLAG_SET )
+#define CLEAR_ATOM_S7_DOS_8BIT_DAC_EN         ((ATOM_DOS_MODE_INFO_DEF << 8 )|ATOM_S7_DOS_8BIT_DAC_EN_SHIFT | ATOM_FLAG_CLEAR )
+
+/****************************************************************************/	
+//Portion II: Definitinos only used in Driver
+/****************************************************************************/
+
+// Macros used by driver
+
+#define	GetIndexIntoMasterTable(MasterOrData, FieldName) (((char*)(&((ATOM_MASTER_LIST_OF_##MasterOrData##_TABLES*)0)->FieldName)-(char*)0)/sizeof(USHORT))
+
+#define GET_COMMAND_TABLE_COMMANDSET_REVISION(TABLE_HEADER_OFFSET) ((((ATOM_COMMON_TABLE_HEADER*)TABLE_HEADER_OFFSET)->ucTableFormatRevision)&0x3F)
+#define GET_COMMAND_TABLE_PARAMETER_REVISION(TABLE_HEADER_OFFSET)  ((((ATOM_COMMON_TABLE_HEADER*)TABLE_HEADER_OFFSET)->ucTableContentRevision)&0x3F)
+
+#define GET_DATA_TABLE_MAJOR_REVISION GET_COMMAND_TABLE_COMMANDSET_REVISION
+#define GET_DATA_TABLE_MINOR_REVISION GET_COMMAND_TABLE_PARAMETER_REVISION
+
+/****************************************************************************/	
+//Portion III: Definitinos only used in VBIOS
+/****************************************************************************/
+#define ATOM_DAC_SRC					0x80
+#define ATOM_SRC_DAC1					0
+#define ATOM_SRC_DAC2					0x80
+
+
+#ifdef	UEFI_BUILD
+	#define	USHORT	UTEMP
+#endif
+
+typedef struct _MEMORY_PLLINIT_PARAMETERS
+{
+  ULONG ulTargetMemoryClock; //In 10Khz unit
+  UCHAR   ucAction;					 //not define yet
+  UCHAR   ucFbDiv_Hi;				 //Fbdiv Hi byte
+  UCHAR   ucFbDiv;					 //FB value
+  UCHAR   ucPostDiv;				 //Post div
+}MEMORY_PLLINIT_PARAMETERS;
+
+#define MEMORY_PLLINIT_PS_ALLOCATION  MEMORY_PLLINIT_PARAMETERS
+
+
+#define	GPIO_PIN_WRITE													0x01			
+#define	GPIO_PIN_READ														0x00
+
+typedef struct  _GPIO_PIN_CONTROL_PARAMETERS
+{
+  UCHAR ucGPIO_ID;           //return value, read from GPIO pins
+  UCHAR ucGPIOBitShift;	     //define which bit in uGPIOBitVal need to be update 
+	UCHAR ucGPIOBitVal;		     //Set/Reset corresponding bit defined in ucGPIOBitMask
+  UCHAR ucAction;				     //=GPIO_PIN_WRITE: Read; =GPIO_PIN_READ: Write
+}GPIO_PIN_CONTROL_PARAMETERS;
+
+typedef struct _ENABLE_SCALER_PARAMETERS
+{
+  UCHAR ucScaler;            // ATOM_SCALER1, ATOM_SCALER2
+  UCHAR ucEnable;            // ATOM_SCALER_DISABLE or ATOM_SCALER_CENTER or ATOM_SCALER_EXPANSION
+  UCHAR ucPadding[2];
+}ENABLE_SCALER_PARAMETERS; 
+#define ENABLE_SCALER_PS_ALLOCATION ENABLE_SCALER_PARAMETERS 
+
+//ucEnable:
+#define SCALER_BYPASS_AUTO_CENTER_NO_REPLICATION    0
+#define SCALER_BYPASS_AUTO_CENTER_AUTO_REPLICATION  1
+#define SCALER_ENABLE_2TAP_ALPHA_MODE               2
+#define SCALER_ENABLE_MULTITAP_MODE                 3
+
+typedef struct _ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS
+{
+  ULONG  usHWIconHorzVertPosn;        // Hardware Icon Vertical position
+  UCHAR  ucHWIconVertOffset;          // Hardware Icon Vertical offset
+  UCHAR  ucHWIconHorzOffset;          // Hardware Icon Horizontal offset
+  UCHAR  ucSelection;                 // ATOM_CURSOR1 or ATOM_ICON1 or ATOM_CURSOR2 or ATOM_ICON2
+  UCHAR  ucEnable;                    // ATOM_ENABLE or ATOM_DISABLE
+}ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS;
+
+typedef struct _ENABLE_HARDWARE_ICON_CURSOR_PS_ALLOCATION
+{
+  ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS  sEnableIcon;
+  ENABLE_CRTC_PARAMETERS                  sReserved;  
+}ENABLE_HARDWARE_ICON_CURSOR_PS_ALLOCATION;
+
+typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS
+{
+  USHORT usHight;                     // Image Hight
+  USHORT usWidth;                     // Image Width
+  UCHAR  ucSurface;                   // Surface 1 or 2	
+  UCHAR  ucPadding[3];
+}ENABLE_GRAPH_SURFACE_PARAMETERS;
+
+typedef struct _ENABLE_GRAPH_SURFACE_PS_ALLOCATION
+{
+  ENABLE_GRAPH_SURFACE_PARAMETERS sSetSurface;          
+  ENABLE_YUV_PS_ALLOCATION        sReserved; // Don't set this one
+}ENABLE_GRAPH_SURFACE_PS_ALLOCATION;
+
+typedef struct _MEMORY_CLEAN_UP_PARAMETERS
+{
+  USHORT  usMemoryStart;                //in 8Kb boundry, offset from memory base address
+  USHORT  usMemorySize;                 //8Kb blocks aligned
+}MEMORY_CLEAN_UP_PARAMETERS;
+#define MEMORY_CLEAN_UP_PS_ALLOCATION MEMORY_CLEAN_UP_PARAMETERS
+
+typedef struct  _GET_DISPLAY_SURFACE_SIZE_PARAMETERS
+{
+  USHORT  usX_Size;                     //When use as input parameter, usX_Size indicates which CRTC                 
+  USHORT  usY_Size;
+}GET_DISPLAY_SURFACE_SIZE_PARAMETERS; 
+
+typedef struct _INDIRECT_IO_ACCESS
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  UCHAR                    IOAccessSequence[256];
+} INDIRECT_IO_ACCESS;
+
+#define INDIRECT_READ              0x00
+#define INDIRECT_WRITE             0x80
+
+#define INDIRECT_IO_MM             0
+#define INDIRECT_IO_PLL            1
+#define INDIRECT_IO_MC             2
+#define INDIRECT_IO_PCIE           3
+#define INDIRECT_IO_PCIEP          4
+
+#define INDIRECT_IO_PLL_READ       INDIRECT_IO_PLL   | INDIRECT_READ
+#define INDIRECT_IO_PLL_WRITE      INDIRECT_IO_PLL   | INDIRECT_WRITE
+#define INDIRECT_IO_MC_READ        INDIRECT_IO_MC    | INDIRECT_READ
+#define INDIRECT_IO_MC_WRITE       INDIRECT_IO_MC    | INDIRECT_WRITE
+#define INDIRECT_IO_PCIE_READ      INDIRECT_IO_PCIE  | INDIRECT_READ
+#define INDIRECT_IO_PCIE_WRITE     INDIRECT_IO_PCIE  | INDIRECT_WRITE
+#define INDIRECT_IO_PCIEP_READ     INDIRECT_IO_PCIEP | INDIRECT_READ
+#define INDIRECT_IO_PCIEP_WRITE    INDIRECT_IO_PCIEP | INDIRECT_WRITE
+
+typedef struct _ATOM_OEM_INFO
+{ 
+  ATOM_COMMON_TABLE_HEADER	sHeader;
+  ATOM_I2C_ID_CONFIG_ACCESS sucI2cId;
+}ATOM_OEM_INFO;
+
+typedef struct _ATOM_TV_MODE
+{
+   UCHAR	ucVMode_Num;			  //Video mode number
+   UCHAR	ucTV_Mode_Num;			//Internal TV mode number
+}ATOM_TV_MODE;
+
+typedef struct _ATOM_BIOS_INT_TVSTD_MODE
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+   USHORT	usTV_Mode_LUT_Offset;	// Pointer to standard to internal number conversion table
+   USHORT	usTV_FIFO_Offset;		  // Pointer to FIFO entry table
+   USHORT	usNTSC_Tbl_Offset;		// Pointer to SDTV_Mode_NTSC table
+   USHORT	usPAL_Tbl_Offset;		  // Pointer to SDTV_Mode_PAL table 
+   USHORT	usCV_Tbl_Offset;		  // Pointer to SDTV_Mode_PAL table 
+}ATOM_BIOS_INT_TVSTD_MODE;
+
+
+typedef struct _ATOM_TV_MODE_SCALER_PTR
+{
+   USHORT	ucFilter0_Offset;		//Pointer to filter format 0 coefficients
+   USHORT	usFilter1_Offset;		//Pointer to filter format 0 coefficients
+   UCHAR	ucTV_Mode_Num;
+}ATOM_TV_MODE_SCALER_PTR;
+
+typedef struct _ATOM_STANDARD_VESA_TIMING
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  ATOM_MODE_TIMING				 aModeTimings[16];      // 16 is not the real array number, just for initial allocation
+}ATOM_STANDARD_VESA_TIMING;
+
+
+typedef struct _ATOM_STD_FORMAT
+{ 
+  USHORT    usSTD_HDisp;
+  USHORT    usSTD_VDisp;
+  USHORT    usSTD_RefreshRate;
+  USHORT    usReserved;
+}ATOM_STD_FORMAT;
+
+typedef struct _ATOM_VESA_TO_EXTENDED_MODE
+{
+  USHORT  usVESA_ModeNumber;
+  USHORT  usExtendedModeNumber;
+}ATOM_VESA_TO_EXTENDED_MODE;
+
+typedef struct _ATOM_VESA_TO_INTENAL_MODE_LUT
+{ 
+  ATOM_COMMON_TABLE_HEADER   sHeader;  
+  ATOM_VESA_TO_EXTENDED_MODE asVESA_ToExtendedModeInfo[76];
+}ATOM_VESA_TO_INTENAL_MODE_LUT;
+
+/*************** ATOM Memory Related Data Structure ***********************/
+typedef struct _ATOM_MEMORY_VENDOR_BLOCK{
+	UCHAR												ucMemoryType;
+	UCHAR												ucMemoryVendor;
+	UCHAR												ucAdjMCId;
+	UCHAR												ucDynClkId;
+	ULONG												ulDllResetClkRange;
+}ATOM_MEMORY_VENDOR_BLOCK;
+
+
+typedef struct _ATOM_MEMORY_SETTING_ID_CONFIG{
+	ULONG												ulMemClockRange:24;
+	ULONG												ucMemBlkId:8;
+}ATOM_MEMORY_SETTING_ID_CONFIG;
+
+typedef union _ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS
+{
+  ATOM_MEMORY_SETTING_ID_CONFIG slAccess;
+  ULONG                         ulAccess;
+}ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS;
+
+
+typedef struct _ATOM_MEMORY_SETTING_DATA_BLOCK{
+	ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS			ulMemoryID;
+	ULONG															        aulMemData[1];
+}ATOM_MEMORY_SETTING_DATA_BLOCK;
+
+
+typedef struct _ATOM_INIT_REG_INDEX_FORMAT{
+	 USHORT											usRegIndex;                                     // MC register index
+	 UCHAR											ucPreRegDataLength;                             // offset in ATOM_INIT_REG_DATA_BLOCK.saRegDataBuf
+}ATOM_INIT_REG_INDEX_FORMAT;
+
+
+typedef struct _ATOM_INIT_REG_BLOCK{
+	USHORT													usRegIndexTblSize;													//size of asRegIndexBuf
+	USHORT													usRegDataBlkSize;														//size of ATOM_MEMORY_SETTING_DATA_BLOCK
+	ATOM_INIT_REG_INDEX_FORMAT			asRegIndexBuf[1];
+	ATOM_MEMORY_SETTING_DATA_BLOCK	asRegDataBuf[1];
+}ATOM_INIT_REG_BLOCK;
+
+#define END_OF_REG_INDEX_BLOCK  0x0ffff
+#define END_OF_REG_DATA_BLOCK   0x00000000
+#define ATOM_INIT_REG_MASK_FLAG 0x80
+#define	CLOCK_RANGE_HIGHEST			0x00ffffff
+
+#define VALUE_DWORD             SIZEOF ULONG
+#define VALUE_SAME_AS_ABOVE     0
+#define VALUE_MASK_DWORD        0x84
+
+typedef struct _ATOM_MC_INIT_PARAM_TABLE
+{ 
+  ATOM_COMMON_TABLE_HEADER		sHeader;
+  USHORT											usAdjustARB_SEQDataOffset;
+  USHORT											usMCInitMemTypeTblOffset;
+  USHORT											usMCInitCommonTblOffset;
+  USHORT											usMCInitPowerDownTblOffset;
+	ULONG												ulARB_SEQDataBuf[32];
+	ATOM_INIT_REG_BLOCK					asMCInitMemType;
+	ATOM_INIT_REG_BLOCK					asMCInitCommon;
+}ATOM_MC_INIT_PARAM_TABLE;
+
+
+#define _4Mx16              0x2
+#define _4Mx32              0x3
+#define _8Mx16              0x12
+#define _8Mx32              0x13
+#define _16Mx16             0x22
+#define _16Mx32             0x23
+#define _32Mx16             0x32
+
+#define SAMSUNG             0x1
+#define INFINEON            0x2
+#define ELPIDA              0x3
+#define ETRON               0x4
+#define NANYA               0x5
+#define HYNIX               0x6
+#define MOSEL               0x7
+#define WINBOND             0x8
+#define ESMT                0x9
+#define MICRO               0xF
+
+#define ATOM_MAX_NUMBER_OF_VRAM_MODULE	16
+
+#define ATOM_VRAM_MODULE_MEMORY_VENDOR_ID_MASK	0xF
+typedef struct _ATOM_VRAM_MODULE_V1
+{
+  ULONG                      ulReserved;
+  USHORT                     usEMRSValue;  
+  USHORT                     usMRSValue;
+  USHORT                     usReserved;
+  UCHAR                      ucExtMemoryID;     // An external indicator (by hardcode, callback or pin) to tell what is the current memory module
+  UCHAR                      ucMemoryType;      // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] reserved;
+  UCHAR                      ucMemoryVenderID;  // Predefined,never change across designs or memory type/vender 
+  UCHAR                      ucMemoryDeviceCfg; // [7:4]=0x0:4M;=0x1:8M;=0x2:16M;0x3:32M....[3:0]=0x0:x4;=0x1:x8;=0x2:x16;=0x3:x32...
+  UCHAR                      ucRow;             // Number of Row,in power of 2;
+  UCHAR                      ucColumn;          // Number of Column,in power of 2;
+  UCHAR                      ucBank;            // Nunber of Bank;
+  UCHAR                      ucRank;            // Number of Rank, in power of 2
+  UCHAR                      ucChannelNum;      // Number of channel;
+  UCHAR                      ucChannelConfig;   // [3:0]=Indication of what channel combination;[4:7]=Channel bit width, in number of 2
+  UCHAR                      ucDefaultMVDDQ_ID; // Default MVDDQ setting for this memory block, ID linking to MVDDQ info table to find real set-up data;
+  UCHAR                      ucDefaultMVDDC_ID; // Default MVDDC setting for this memory block, ID linking to MVDDC info table to find real set-up data;
+  UCHAR                      ucReserved[2];
+}ATOM_VRAM_MODULE_V1;
+
+
+typedef struct _ATOM_VRAM_MODULE_V2
+{
+  ULONG                      ulReserved;
+  ULONG                      ulFlags;     			// To enable/disable functionalities based on memory type
+  ULONG                      ulEngineClock;     // Override of default engine clock for particular memory type
+  ULONG                      ulMemoryClock;     // Override of default memory clock for particular memory type
+  USHORT                     usEMRS2Value;      // EMRS2 Value is used for GDDR2 and GDDR4 memory type
+  USHORT                     usEMRS3Value;      // EMRS3 Value is used for GDDR2 and GDDR4 memory type
+  USHORT                     usEMRSValue;  
+  USHORT                     usMRSValue;
+  USHORT                     usReserved;
+  UCHAR                      ucExtMemoryID;     // An external indicator (by hardcode, callback or pin) to tell what is the current memory module
+  UCHAR                      ucMemoryType;      // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] - must not be used for now;
+  UCHAR                      ucMemoryVenderID;  // Predefined,never change across designs or memory type/vender. If not predefined, vendor detection table gets executed
+  UCHAR                      ucMemoryDeviceCfg; // [7:4]=0x0:4M;=0x1:8M;=0x2:16M;0x3:32M....[3:0]=0x0:x4;=0x1:x8;=0x2:x16;=0x3:x32...
+  UCHAR                      ucRow;             // Number of Row,in power of 2;
+  UCHAR                      ucColumn;          // Number of Column,in power of 2;
+  UCHAR                      ucBank;            // Nunber of Bank;
+  UCHAR                      ucRank;            // Number of Rank, in power of 2
+  UCHAR                      ucChannelNum;      // Number of channel;
+  UCHAR                      ucChannelConfig;   // [3:0]=Indication of what channel combination;[4:7]=Channel bit width, in number of 2
+  UCHAR                      ucDefaultMVDDQ_ID; // Default MVDDQ setting for this memory block, ID linking to MVDDQ info table to find real set-up data;
+  UCHAR                      ucDefaultMVDDC_ID; // Default MVDDC setting for this memory block, ID linking to MVDDC info table to find real set-up data;
+  UCHAR                      ucRefreshRateFactor;
+  UCHAR                      ucReserved[3];
+}ATOM_VRAM_MODULE_V2;
+
+
+typedef	struct _ATOM_MEMORY_TIMING_FORMAT
+{
+	ULONG											 ulClkRange;				// memory clock in 10kHz unit, when target memory clock is below this clock, use this memory timing 	
+	USHORT										 usMRS;							// mode register						
+	USHORT										 usEMRS;						// extended mode register
+	UCHAR											 ucCL;							// CAS latency
+	UCHAR											 ucWL;							// WRITE Latency				
+	UCHAR											 uctRAS;						// tRAS
+	UCHAR											 uctRC;							// tRC	
+	UCHAR											 uctRFC;						// tRFC
+	UCHAR											 uctRCDR;						// tRCDR	
+	UCHAR											 uctRCDW;						// tRCDW
+	UCHAR											 uctRP;							// tRP
+	UCHAR											 uctRRD;						// tRRD	
+	UCHAR											 uctWR;							// tWR
+	UCHAR											 uctWTR;						// tWTR
+	UCHAR											 uctPDIX;						// tPDIX
+	UCHAR											 uctFAW;						// tFAW
+	UCHAR											 uctAOND;						// tAOND
+	UCHAR											 ucflag;						// flag to control memory timing calculation. bit0= control EMRS2 Infineon 
+	UCHAR											 ucReserved;				// 
+}ATOM_MEMORY_TIMING_FORMAT;
+
+#define	MEM_TIMING_FLAG_APP_MODE								0x01									// =0 mid clock range  =1 high clock range
+
+typedef	struct _ATOM_MEMORY_FORMAT
+{
+	ULONG											 ulDllDisClock;			// memory DLL will be disable when target memory clock is below this clock
+  USHORT                     usEMRS2Value;      // EMRS2 Value is used for GDDR2 and GDDR4 memory type
+  USHORT                     usEMRS3Value;      // EMRS3 Value is used for GDDR2 and GDDR4 memory type
+  UCHAR                      ucMemoryType;      // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] - must not be used for now;
+  UCHAR                      ucMemoryVenderID;  // Predefined,never change across designs or memory type/vender. If not predefined, vendor detection table gets executed
+  UCHAR                      ucRow;             // Number of Row,in power of 2;
+  UCHAR                      ucColumn;          // Number of Column,in power of 2;
+  UCHAR                      ucBank;            // Nunber of Bank;
+  UCHAR                      ucRank;            // Number of Rank, in power of 2
+	UCHAR											 ucBurstSize;				// burst size, 0= burst size=4  1= burst size=8
+  UCHAR                      ucDllDisBit;				// position of DLL Enable/Disable bit in EMRS ( Extended Mode Register )
+  UCHAR                      ucRefreshRateFactor;	// memory refresh rate in unit of ms	
+	UCHAR											 ucDensity;					// _8Mx32, _16Mx32, _16Mx16, _32Mx16
+	UCHAR											 ucPreamble;				//[7:4] Write Preamble, [3:0] Read Preamble
+  UCHAR											 ucMemAttrib;				// Memory Device Addribute, like RDBI/WDBI etc
+	ATOM_MEMORY_TIMING_FORMAT	 asMemTiming[5];		//Memory Timing block sort from lower clock to higher clock
+}ATOM_MEMORY_FORMAT;
+
+
+typedef struct _ATOM_VRAM_MODULE_V3
+{
+	ULONG											 ulChannelMapCfg;		// board dependent paramenter:Channel combination
+	USHORT										 usSize;						// size of ATOM_VRAM_MODULE_V3
+  USHORT                     usDefaultMVDDQ;		// board dependent parameter:Default Memory Core Voltage
+  USHORT                     usDefaultMVDDC;		// board dependent parameter:Default Memory IO Voltage
+	UCHAR                      ucExtMemoryID;     // An external indicator (by hardcode, callback or pin) to tell what is the current memory module
+  UCHAR                      ucChannelNum;      // board dependent parameter:Number of channel;
+	UCHAR											 ucChannelSize;			// board dependent parameter:32bit or 64bit	
+	UCHAR											 ucVREFI;						// board dependnt parameter: EXT or INT +160mv to -140mv
+	UCHAR											 ucNPL_RT;					// board dependent parameter:NPL round trip delay, used for calculate memory timing parameters
+	UCHAR											 ucFlag;						// To enable/disable functionalities based on memory type
+	ATOM_MEMORY_FORMAT				 asMemory;					// describ all of video memory parameters from memory spec
+}ATOM_VRAM_MODULE_V3;
+
+//ATOM_VRAM_MODULE_V3.ucFlag
+#define	Mx_FLAG_RDBI_ENABLE											0x01
+#define	Mx_FLAG_WDBI_ENABLE											0x02
+#define	Mx_FLAG_DQ_QS_AUTO_CALI									0x04
+#define Mx_FLAG_STROBE_SINGLE_END								0x08
+#define Mx_FLAG_DIS_MEM_TRAINING								0x10
+
+//ATOM_VRAM_MODULE_V3.ucNPL_RT
+#define NPL_RT_MASK															0x0f
+#define BATTERY_ODT_MASK												0xc0
+
+#define ATOM_VRAM_MODULE		 ATOM_VRAM_MODULE_V3
+
+typedef struct _ATOM_VRAM_INFO_V2
+{
+  ATOM_COMMON_TABLE_HEADER   sHeader;
+  UCHAR                      ucNumOfVRAMModule;
+  ATOM_VRAM_MODULE           aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE];      // just for allocation, real number of blocks is in ucNumOfVRAMModule;
+}ATOM_VRAM_INFO_V2;
+
+typedef struct _ATOM_VRAM_INFO_V3
+{
+  ATOM_COMMON_TABLE_HEADER   sHeader;
+	USHORT										 usMemAdjustTblOffset;													 // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting
+	USHORT										 usMemClkPatchTblOffset;												 //	offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting
+	USHORT										 usRerseved;
+	UCHAR           	         aVID_PinsShift[9];															 // 8 bit strap maximum+terminator
+  UCHAR                      ucNumOfVRAMModule;
+  ATOM_VRAM_MODULE		       aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE];      // just for allocation, real number of blocks is in ucNumOfVRAMModule;
+	ATOM_INIT_REG_BLOCK				 asMemPatch;																		 // for allocation
+																																						 //	ATOM_INIT_REG_BLOCK				 aMemAdjust;
+}ATOM_VRAM_INFO_V3;
+
+#define	ATOM_VRAM_INFO_LAST	     ATOM_VRAM_INFO_V3
+
+typedef struct _ATOM_VRAM_GPIO_DETECTION_INFO
+{
+  ATOM_COMMON_TABLE_HEADER   sHeader;
+  UCHAR           	         aVID_PinsShift[9];   //8 bit strap maximum+terminator
+}ATOM_VRAM_GPIO_DETECTION_INFO;
+
+
+typedef struct _ATOM_MEMORY_TRAINING_INFO
+{
+	ATOM_COMMON_TABLE_HEADER   sHeader;
+	UCHAR											 ucTrainingLoop;
+	UCHAR											 ucReserved[3];
+	ATOM_INIT_REG_BLOCK				 asMemTrainingSetting;
+}ATOM_MEMORY_TRAINING_INFO;
+
+
+typedef struct SW_I2C_CNTL_DATA_PARAMETERS
+{
+  UCHAR    ucControl;
+  UCHAR    ucData; 
+  UCHAR    ucSatus; 
+  UCHAR    ucTemp; 
+} SW_I2C_CNTL_DATA_PARAMETERS;
+
+#define SW_I2C_CNTL_DATA_PS_ALLOCATION  SW_I2C_CNTL_DATA_PARAMETERS
+
+typedef struct _SW_I2C_IO_DATA_PARAMETERS
+{                               
+  USHORT   GPIO_Info;
+  UCHAR    ucAct; 
+  UCHAR    ucData; 
+ } SW_I2C_IO_DATA_PARAMETERS;
+
+#define SW_I2C_IO_DATA_PS_ALLOCATION  SW_I2C_IO_DATA_PARAMETERS
+
+/****************************SW I2C CNTL DEFINITIONS**********************/
+#define SW_I2C_IO_RESET       0
+#define SW_I2C_IO_GET         1
+#define SW_I2C_IO_DRIVE       2
+#define SW_I2C_IO_SET         3
+#define SW_I2C_IO_START       4
+
+#define SW_I2C_IO_CLOCK       0
+#define SW_I2C_IO_DATA        0x80
+
+#define SW_I2C_IO_ZERO        0
+#define SW_I2C_IO_ONE         0x100
+
+#define SW_I2C_CNTL_READ      0
+#define SW_I2C_CNTL_WRITE     1
+#define SW_I2C_CNTL_START     2
+#define SW_I2C_CNTL_STOP      3
+#define SW_I2C_CNTL_OPEN      4
+#define SW_I2C_CNTL_CLOSE     5
+#define SW_I2C_CNTL_WRITE1BIT 6
+
+//==============================VESA definition Portion===============================
+#define VESA_OEM_PRODUCT_REV			            '01.00'
+#define VESA_MODE_ATTRIBUTE_MODE_SUPPORT	     0xBB	//refer to VBE spec p.32, no TTY support
+#define VESA_MODE_WIN_ATTRIBUTE						     7
+#define VESA_WIN_SIZE											     64
+
+typedef struct _PTR_32_BIT_STRUCTURE
+{
+	USHORT	Offset16;			
+	USHORT	Segment16;				
+} PTR_32_BIT_STRUCTURE;
+
+typedef union _PTR_32_BIT_UNION
+{
+	PTR_32_BIT_STRUCTURE	SegmentOffset;
+	ULONG					        Ptr32_Bit;
+} PTR_32_BIT_UNION;
+
+typedef struct _VBE_1_2_INFO_BLOCK_UPDATABLE
+{
+	UCHAR				      VbeSignature[4];
+	USHORT				    VbeVersion;
+	PTR_32_BIT_UNION	OemStringPtr;
+	UCHAR				      Capabilities[4];
+	PTR_32_BIT_UNION	VideoModePtr;
+	USHORT				    TotalMemory;
+} VBE_1_2_INFO_BLOCK_UPDATABLE;
+
+
+typedef struct _VBE_2_0_INFO_BLOCK_UPDATABLE
+{
+	VBE_1_2_INFO_BLOCK_UPDATABLE	CommonBlock;
+	USHORT							    OemSoftRev;
+	PTR_32_BIT_UNION				OemVendorNamePtr;
+	PTR_32_BIT_UNION				OemProductNamePtr;
+	PTR_32_BIT_UNION				OemProductRevPtr;
+} VBE_2_0_INFO_BLOCK_UPDATABLE;
+
+typedef union _VBE_VERSION_UNION
+{
+	VBE_2_0_INFO_BLOCK_UPDATABLE	VBE_2_0_InfoBlock;
+	VBE_1_2_INFO_BLOCK_UPDATABLE	VBE_1_2_InfoBlock;
+} VBE_VERSION_UNION;
+
+typedef struct _VBE_INFO_BLOCK
+{
+	VBE_VERSION_UNION			UpdatableVBE_Info;
+	UCHAR						      Reserved[222];
+	UCHAR						      OemData[256];
+} VBE_INFO_BLOCK;
+
+typedef struct _VBE_FP_INFO
+{
+  USHORT	HSize;
+	USHORT	VSize;
+	USHORT	FPType;
+	UCHAR		RedBPP;
+	UCHAR		GreenBPP;
+	UCHAR		BlueBPP;
+	UCHAR		ReservedBPP;
+	ULONG		RsvdOffScrnMemSize;
+	ULONG		RsvdOffScrnMEmPtr;
+	UCHAR		Reserved[14];
+} VBE_FP_INFO;
+
+typedef struct _VESA_MODE_INFO_BLOCK
+{
+// Mandatory information for all VBE revisions
+  USHORT    ModeAttributes;  //			dw	?	; mode attributes
+	UCHAR     WinAAttributes;  //			db	?	; window A attributes
+	UCHAR     WinBAttributes;  //			db	?	; window B attributes
+	USHORT    WinGranularity;  //			dw	?	; window granularity
+	USHORT    WinSize;         //			dw	?	; window size
+	USHORT    WinASegment;     //			dw	?	; window A start segment
+	USHORT    WinBSegment;     //			dw	?	; window B start segment
+	ULONG     WinFuncPtr;      //			dd	?	; real mode pointer to window function
+	USHORT    BytesPerScanLine;//			dw	?	; bytes per scan line
+
+//; Mandatory information for VBE 1.2 and above
+  USHORT    XResolution;      //			dw	?	; horizontal resolution in pixels or characters
+	USHORT    YResolution;      //			dw	?	; vertical resolution in pixels or characters
+	UCHAR     XCharSize;        //			db	?	; character cell width in pixels
+	UCHAR     YCharSize;        //			db	?	; character cell height in pixels
+	UCHAR     NumberOfPlanes;   //			db	?	; number of memory planes
+	UCHAR     BitsPerPixel;     //			db	?	; bits per pixel
+	UCHAR     NumberOfBanks;    //			db	?	; number of banks
+	UCHAR     MemoryModel;      //			db	?	; memory model type
+	UCHAR     BankSize;         //			db	?	; bank size in KB
+	UCHAR     NumberOfImagePages;//		  db	?	; number of images
+	UCHAR     ReservedForPageFunction;//db	1	; reserved for page function
+
+//; Direct Color fields(required for direct/6 and YUV/7 memory models)
+	UCHAR			RedMaskSize;        //		db	?	; size of direct color red mask in bits
+	UCHAR			RedFieldPosition;   //		db	?	; bit position of lsb of red mask
+	UCHAR			GreenMaskSize;      //		db	?	; size of direct color green mask in bits
+	UCHAR			GreenFieldPosition; //		db	?	; bit position of lsb of green mask
+	UCHAR			BlueMaskSize;       //		db	?	; size of direct color blue mask in bits
+	UCHAR			BlueFieldPosition;  //		db	?	; bit position of lsb of blue mask
+	UCHAR			RsvdMaskSize;       //		db	?	; size of direct color reserved mask in bits
+	UCHAR			RsvdFieldPosition;  //		db	?	; bit position of lsb of reserved mask
+	UCHAR			DirectColorModeInfo;//		db	?	; direct color mode attributes
+
+//; Mandatory information for VBE 2.0 and above
+	ULONG			PhysBasePtr;        //		dd	?	; physical address for flat memory frame buffer
+	ULONG			Reserved_1;         //		dd	0	; reserved - always set to 0
+	USHORT		Reserved_2;         //	  dw	0	; reserved - always set to 0
+
+//; Mandatory information for VBE 3.0 and above
+	USHORT		LinBytesPerScanLine;  //	dw	?	; bytes per scan line for linear modes
+	UCHAR			BnkNumberOfImagePages;//	db	?	; number of images for banked modes
+	UCHAR			LinNumberOfImagPages; //	db	?	; number of images for linear modes
+	UCHAR			LinRedMaskSize;       //	db	?	; size of direct color red mask(linear modes)
+	UCHAR			LinRedFieldPosition;  //	db	?	; bit position of lsb of red mask(linear modes)
+	UCHAR			LinGreenMaskSize;     //	db	?	; size of direct color green mask(linear modes)
+	UCHAR			LinGreenFieldPosition;//	db	?	; bit position of lsb of green mask(linear modes)
+	UCHAR			LinBlueMaskSize;      //	db	?	; size of direct color blue mask(linear modes)
+	UCHAR			LinBlueFieldPosition; //	db	?	; bit position of lsb of blue mask(linear modes)
+	UCHAR			LinRsvdMaskSize;      //	db	?	; size of direct color reserved mask(linear modes)
+	UCHAR			LinRsvdFieldPosition; //	db	?	; bit position of lsb of reserved mask(linear modes)
+	ULONG			MaxPixelClock;        //	dd	?	; maximum pixel clock(in Hz) for graphics mode
+	UCHAR			Reserved;             //	db	190 dup (0)
+} VESA_MODE_INFO_BLOCK;
+
+// BIOS function CALLS
+#define ATOM_BIOS_EXTENDED_FUNCTION_CODE        0xA0	        // ATI Extended Function code
+#define ATOM_BIOS_FUNCTION_COP_MODE             0x00
+#define ATOM_BIOS_FUNCTION_SHORT_QUERY1         0x04
+#define ATOM_BIOS_FUNCTION_SHORT_QUERY2         0x05
+#define ATOM_BIOS_FUNCTION_SHORT_QUERY3         0x06
+#define ATOM_BIOS_FUNCTION_GET_DDC              0x0B   
+#define ATOM_BIOS_FUNCTION_ASIC_DSTATE          0x0E
+#define ATOM_BIOS_FUNCTION_DEBUG_PLAY           0x0F
+#define ATOM_BIOS_FUNCTION_STV_STD              0x16
+#define ATOM_BIOS_FUNCTION_DEVICE_DET           0x17
+#define ATOM_BIOS_FUNCTION_DEVICE_SWITCH        0x18
+
+#define ATOM_BIOS_FUNCTION_PANEL_CONTROL        0x82
+#define ATOM_BIOS_FUNCTION_OLD_DEVICE_DET       0x83
+#define ATOM_BIOS_FUNCTION_OLD_DEVICE_SWITCH    0x84
+#define ATOM_BIOS_FUNCTION_HW_ICON              0x8A 
+#define ATOM_BIOS_FUNCTION_SET_CMOS             0x8B
+#define SUB_FUNCTION_UPDATE_DISPLAY_INFO        0x8000          // Sub function 80
+#define SUB_FUNCTION_UPDATE_EXPANSION_INFO      0x8100          // Sub function 80
+
+#define ATOM_BIOS_FUNCTION_DISPLAY_INFO         0x8D
+#define ATOM_BIOS_FUNCTION_DEVICE_ON_OFF        0x8E
+#define ATOM_BIOS_FUNCTION_VIDEO_STATE          0x8F 
+#define ATOM_SUB_FUNCTION_GET_CRITICAL_STATE    0x0300          // Sub function 03  
+#define ATOM_SUB_FUNCTION_GET_LIDSTATE          0x0700          // Sub function 7
+#define ATOM_SUB_FUNCTION_THERMAL_STATE_NOTICE  0x1400          // Notify caller the current thermal state
+#define ATOM_SUB_FUNCTION_CRITICAL_STATE_NOTICE 0x8300          // Notify caller the current critical state
+#define ATOM_SUB_FUNCTION_SET_LIDSTATE          0x8500          // Sub function 85
+#define ATOM_SUB_FUNCTION_GET_REQ_DISPLAY_FROM_SBIOS_MODE 0x8900// Sub function 89
+#define ATOM_SUB_FUNCTION_INFORM_ADC_SUPPORT    0x9400          // Notify caller that ADC is supported
+     
+
+#define ATOM_BIOS_FUNCTION_VESA_DPMS            0x4F10          // Set DPMS 
+#define ATOM_SUB_FUNCTION_SET_DPMS              0x0001          // BL: Sub function 01 
+#define ATOM_SUB_FUNCTION_GET_DPMS              0x0002          // BL: Sub function 02 
+#define ATOM_PARAMETER_VESA_DPMS_ON             0x0000          // BH Parameter for DPMS ON.  
+#define ATOM_PARAMETER_VESA_DPMS_STANDBY        0x0100          // BH Parameter for DPMS STANDBY  
+#define ATOM_PARAMETER_VESA_DPMS_SUSPEND        0x0200          // BH Parameter for DPMS SUSPEND
+#define ATOM_PARAMETER_VESA_DPMS_OFF            0x0400          // BH Parameter for DPMS OFF
+#define ATOM_PARAMETER_VESA_DPMS_REDUCE_ON      0x0800          // BH Parameter for DPMS REDUCE ON (NOT SUPPORTED)
+
+#define ATOM_BIOS_RETURN_CODE_MASK              0x0000FF00L
+#define ATOM_BIOS_REG_HIGH_MASK                 0x0000FF00L
+#define ATOM_BIOS_REG_LOW_MASK                  0x000000FFL
+
+// structure used for VBIOS only
+
+//DispOutInfoTable
+typedef struct _ASIC_TRANSMITTER_INFO
+{
+	USHORT usTransmitterObjId;
+	USHORT usSupportDevice;
+  UCHAR  ucTransmitterCmdTblId;
+	UCHAR  ucConfig;
+	UCHAR  ucEncoderID;					 //available 1st encoder ( default )
+	UCHAR  ucOptionEncoderID;    //available 2nd encoder ( optional )
+	UCHAR  uc2ndEncoderID;
+	UCHAR  ucReserved;
+}ASIC_TRANSMITTER_INFO;
+
+typedef struct _ASIC_ENCODER_INFO
+{
+	UCHAR ucEncoderID;
+	UCHAR ucEncoderConfig;
+  USHORT usEncoderCmdTblId;
+}ASIC_ENCODER_INFO;
+
+typedef struct _ATOM_DISP_OUT_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+	USHORT ptrTransmitterInfo;
+	USHORT ptrEncoderInfo;
+	ASIC_TRANSMITTER_INFO  asTransmitterInfo[1];
+	ASIC_ENCODER_INFO      asEncoderInfo[1];
+}ATOM_DISP_OUT_INFO;
+
+// DispDevicePriorityInfo
+typedef struct _ATOM_DISPLAY_DEVICE_PRIORITY_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+	USHORT asDevicePriority[16];
+}ATOM_DISPLAY_DEVICE_PRIORITY_INFO;
+
+//ProcessAuxChannelTransactionTable
+typedef struct _PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS
+{
+	USHORT	lpAuxRequest;
+	USHORT  lpDataOut;
+	UCHAR		ucChannelID;
+	union
+	{
+  UCHAR   ucReplyStatus;
+	UCHAR   ucDelay;
+	};
+  UCHAR   ucDataOutLen;
+	UCHAR   ucReserved;
+}PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS;
+
+#define PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION			PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS
+
+//GetSinkType
+
+typedef struct _DP_ENCODER_SERVICE_PARAMETERS
+{
+	USHORT ucLinkClock;
+	union 
+	{
+	UCHAR ucConfig;				// for DP training command
+	UCHAR ucI2cId;				// use for GET_SINK_TYPE command
+	};
+	UCHAR ucAction;
+	UCHAR ucStatus;
+	UCHAR ucLaneNum;
+	UCHAR ucReserved[2];
+}DP_ENCODER_SERVICE_PARAMETERS;
+
+// ucAction
+#define ATOM_DP_ACTION_GET_SINK_TYPE							0x01
+#define ATOM_DP_ACTION_TRAINING_START							0x02
+#define ATOM_DP_ACTION_TRAINING_COMPLETE					0x03
+#define ATOM_DP_ACTION_TRAINING_PATTERN_SEL				0x04
+#define ATOM_DP_ACTION_SET_VSWING_PREEMP					0x05
+#define ATOM_DP_ACTION_GET_VSWING_PREEMP					0x06
+
+// ucConfig
+#define ATOM_DP_CONFIG_ENCODER_SEL_MASK						0x03
+#define ATOM_DP_CONFIG_DIG1_ENCODER								0x00
+#define ATOM_DP_CONFIG_DIG2_ENCODER								0x01
+#define ATOM_DP_CONFIG_EXTERNAL_ENCODER						0x02
+#define ATOM_DP_CONFIG_LINK_SEL_MASK							0x04
+#define ATOM_DP_CONFIG_LINK_A											0x00
+#define ATOM_DP_CONFIG_LINK_B											0x04
+
+#define DP_ENCODER_SERVICE_PS_ALLOCATION				WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS
+
+// DP_TRAINING_TABLE
+#define DPCD_SET_LINKRATE_LANENUM_PATTERN1_TBL_ADDR				ATOM_DP_TRAINING_TBL_ADDR		
+#define DPCD_SET_SS_CNTL_TBL_ADDR													(ATOM_DP_TRAINING_TBL_ADDR + 8 )
+#define DPCD_SET_LANE_VSWING_PREEMP_TBL_ADDR							(ATOM_DP_TRAINING_TBL_ADDR + 16 )
+#define DPCD_SET_TRAINING_PATTERN0_TBL_ADDR								(ATOM_DP_TRAINING_TBL_ADDR + 24 )
+#define DPCD_SET_TRAINING_PATTERN2_TBL_ADDR								(ATOM_DP_TRAINING_TBL_ADDR + 32)
+#define DPCD_GET_LINKRATE_LANENUM_SS_TBL_ADDR							(ATOM_DP_TRAINING_TBL_ADDR + 40)
+#define	DPCD_GET_LANE_STATUS_ADJUST_TBL_ADDR							(ATOM_DP_TRAINING_TBL_ADDR + 48)
+#define DP_I2C_AUX_DDC_WRITE_START_TBL_ADDR								(ATOM_DP_TRAINING_TBL_ADDR + 60)
+#define DP_I2C_AUX_DDC_WRITE_TBL_ADDR											(ATOM_DP_TRAINING_TBL_ADDR + 64)
+#define DP_I2C_AUX_DDC_READ_START_TBL_ADDR								(ATOM_DP_TRAINING_TBL_ADDR + 72)
+#define DP_I2C_AUX_DDC_READ_TBL_ADDR											(ATOM_DP_TRAINING_TBL_ADDR + 76)
+#define DP_I2C_AUX_DDC_READ_END_TBL_ADDR									(ATOM_DP_TRAINING_TBL_ADDR + 80)
+
+
+/****************************************************************************/	
+//Portion VI: Definitinos being oboselete
+/****************************************************************************/
+
+//==========================================================================================
+//Remove the definitions below when driver is ready!
+typedef struct _ATOM_DAC_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  USHORT                   usMaxFrequency;      // in 10kHz unit
+  USHORT                   usReserved;
+}ATOM_DAC_INFO;
+
+
+typedef struct  _COMPASSIONATE_DATA           
+{
+  ATOM_COMMON_TABLE_HEADER sHeader; 
+
+  //==============================  DAC1 portion
+  UCHAR   ucDAC1_BG_Adjustment;
+  UCHAR   ucDAC1_DAC_Adjustment;
+  USHORT  usDAC1_FORCE_Data;
+  //==============================  DAC2 portion
+  UCHAR   ucDAC2_CRT2_BG_Adjustment;
+  UCHAR   ucDAC2_CRT2_DAC_Adjustment;
+  USHORT  usDAC2_CRT2_FORCE_Data;
+  USHORT  usDAC2_CRT2_MUX_RegisterIndex;
+  UCHAR   ucDAC2_CRT2_MUX_RegisterInfo;     //Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low
+  UCHAR   ucDAC2_NTSC_BG_Adjustment;
+  UCHAR   ucDAC2_NTSC_DAC_Adjustment;
+  USHORT  usDAC2_TV1_FORCE_Data;
+  USHORT  usDAC2_TV1_MUX_RegisterIndex;
+  UCHAR   ucDAC2_TV1_MUX_RegisterInfo;      //Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low
+  UCHAR   ucDAC2_CV_BG_Adjustment;
+  UCHAR   ucDAC2_CV_DAC_Adjustment;
+  USHORT  usDAC2_CV_FORCE_Data;
+  USHORT  usDAC2_CV_MUX_RegisterIndex;
+  UCHAR   ucDAC2_CV_MUX_RegisterInfo;       //Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low
+  UCHAR   ucDAC2_PAL_BG_Adjustment;
+  UCHAR   ucDAC2_PAL_DAC_Adjustment;
+  USHORT  usDAC2_TV2_FORCE_Data;
+}COMPASSIONATE_DATA;
+
+/****************************Supported Device Info Table Definitions**********************/
+//  ucConnectInfo:
+//    [7:4] - connector type
+//      = 1   - VGA connector   
+//      = 2   - DVI-I
+//      = 3   - DVI-D
+//      = 4   - DVI-A
+//      = 5   - SVIDEO
+//      = 6   - COMPOSITE
+//      = 7   - LVDS
+//      = 8   - DIGITAL LINK
+//      = 9   - SCART
+//      = 0xA - HDMI_type A
+//      = 0xB - HDMI_type B
+//      = 0xE - Special case1 (DVI+DIN)
+//      Others=TBD
+//    [3:0] - DAC Associated
+//      = 0   - no DAC
+//      = 1   - DACA
+//      = 2   - DACB
+//      = 3   - External DAC
+//      Others=TBD
+//    
+
+typedef struct _ATOM_CONNECTOR_INFO
+{
+  UCHAR   bfAssociatedDAC:4;
+  UCHAR   bfConnectorType:4;
+}ATOM_CONNECTOR_INFO;
+
+typedef union _ATOM_CONNECTOR_INFO_ACCESS
+{
+  ATOM_CONNECTOR_INFO sbfAccess;
+  UCHAR               ucAccess;
+}ATOM_CONNECTOR_INFO_ACCESS;
+
+typedef struct _ATOM_CONNECTOR_INFO_I2C
+{
+  ATOM_CONNECTOR_INFO_ACCESS sucConnectorInfo;
+  ATOM_I2C_ID_CONFIG_ACCESS  sucI2cId;
+}ATOM_CONNECTOR_INFO_I2C;
+
+
+typedef struct _ATOM_SUPPORTED_DEVICES_INFO
+{ 
+  ATOM_COMMON_TABLE_HEADER	sHeader;
+  USHORT                    usDeviceSupport;
+  ATOM_CONNECTOR_INFO_I2C   asConnInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO];
+}ATOM_SUPPORTED_DEVICES_INFO;
+
+#define NO_INT_SRC_MAPPED       0xFF
+
+typedef struct _ATOM_CONNECTOR_INC_SRC_BITMAP
+{
+  UCHAR   ucIntSrcBitmap;
+}ATOM_CONNECTOR_INC_SRC_BITMAP;
+
+typedef struct _ATOM_SUPPORTED_DEVICES_INFO_2
+{ 
+  ATOM_COMMON_TABLE_HEADER      sHeader;
+  USHORT                        usDeviceSupport;
+  ATOM_CONNECTOR_INFO_I2C       asConnInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_2];
+  ATOM_CONNECTOR_INC_SRC_BITMAP asIntSrcInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_2];
+}ATOM_SUPPORTED_DEVICES_INFO_2;
+
+typedef struct _ATOM_SUPPORTED_DEVICES_INFO_2d1
+{ 
+  ATOM_COMMON_TABLE_HEADER      sHeader;
+  USHORT                        usDeviceSupport;
+  ATOM_CONNECTOR_INFO_I2C       asConnInfo[ATOM_MAX_SUPPORTED_DEVICE];
+  ATOM_CONNECTOR_INC_SRC_BITMAP asIntSrcInfo[ATOM_MAX_SUPPORTED_DEVICE];
+}ATOM_SUPPORTED_DEVICES_INFO_2d1;
+
+#define ATOM_SUPPORTED_DEVICES_INFO_LAST ATOM_SUPPORTED_DEVICES_INFO_2d1
+
+
+
+typedef struct _ATOM_MISC_CONTROL_INFO
+{
+   USHORT usFrequency;
+   UCHAR  ucPLL_ChargePump;				                // PLL charge-pump gain control
+   UCHAR  ucPLL_DutyCycle;				                // PLL duty cycle control
+   UCHAR  ucPLL_VCO_Gain;				                  // PLL VCO gain control
+   UCHAR  ucPLL_VoltageSwing;			                // PLL driver voltage swing control
+}ATOM_MISC_CONTROL_INFO;  
+
+
+#define ATOM_MAX_MISC_INFO       4
+
+typedef struct _ATOM_TMDS_INFO
+{
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  USHORT							usMaxFrequency;             // in 10Khz
+  ATOM_MISC_CONTROL_INFO				asMiscInfo[ATOM_MAX_MISC_INFO];
+}ATOM_TMDS_INFO;
+
+
+typedef struct _ATOM_ENCODER_ANALOG_ATTRIBUTE
+{
+  UCHAR ucTVStandard;     //Same as TV standards defined above, 
+  UCHAR ucPadding[1];
+}ATOM_ENCODER_ANALOG_ATTRIBUTE;
+
+typedef struct _ATOM_ENCODER_DIGITAL_ATTRIBUTE
+{
+  UCHAR ucAttribute;      //Same as other digital encoder attributes defined above
+  UCHAR ucPadding[1];		
+}ATOM_ENCODER_DIGITAL_ATTRIBUTE;
+
+typedef union _ATOM_ENCODER_ATTRIBUTE
+{
+  ATOM_ENCODER_ANALOG_ATTRIBUTE sAlgAttrib;
+  ATOM_ENCODER_DIGITAL_ATTRIBUTE sDigAttrib;
+}ATOM_ENCODER_ATTRIBUTE;
+
+
+typedef struct _DVO_ENCODER_CONTROL_PARAMETERS
+{
+  USHORT usPixelClock; 
+  USHORT usEncoderID; 
+  UCHAR  ucDeviceType;												//Use ATOM_DEVICE_xxx1_Index to indicate device type only.	
+  UCHAR  ucAction;														//ATOM_ENABLE/ATOM_DISABLE/ATOM_HPD_INIT
+  ATOM_ENCODER_ATTRIBUTE usDevAttr;     		
+}DVO_ENCODER_CONTROL_PARAMETERS;
+
+typedef struct _DVO_ENCODER_CONTROL_PS_ALLOCATION
+{                               
+  DVO_ENCODER_CONTROL_PARAMETERS    sDVOEncoder;
+  WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION      sReserved;     //Caller doesn't need to init this portion
+}DVO_ENCODER_CONTROL_PS_ALLOCATION;
+
+
+#define ATOM_XTMDS_ASIC_SI164_ID        1
+#define ATOM_XTMDS_ASIC_SI178_ID        2
+#define ATOM_XTMDS_ASIC_TFP513_ID       3
+#define ATOM_XTMDS_SUPPORTED_SINGLELINK 0x00000001
+#define ATOM_XTMDS_SUPPORTED_DUALLINK   0x00000002
+#define ATOM_XTMDS_MVPU_FPGA            0x00000004
+
+                           
+typedef struct _ATOM_XTMDS_INFO
+{
+  ATOM_COMMON_TABLE_HEADER   sHeader;  
+  USHORT                     usSingleLinkMaxFrequency; 
+  ATOM_I2C_ID_CONFIG_ACCESS  sucI2cId;           //Point the ID on which I2C is used to control external chip
+  UCHAR                      ucXtransimitterID;          
+  UCHAR                      ucSupportedLink;    // Bit field, bit0=1, single link supported;bit1=1,dual link supported
+  UCHAR                      ucSequnceAlterID;   // Even with the same external TMDS asic, it's possible that the program seqence alters 
+                                                 // due to design. This ID is used to alert driver that the sequence is not "standard"!              
+  UCHAR                      ucMasterAddress;    // Address to control Master xTMDS Chip
+  UCHAR                      ucSlaveAddress;     // Address to control Slave xTMDS Chip
+}ATOM_XTMDS_INFO;
+
+typedef struct _DFP_DPMS_STATUS_CHANGE_PARAMETERS
+{  
+  UCHAR ucEnable;                     // ATOM_ENABLE=On or ATOM_DISABLE=Off
+  UCHAR ucDevice;                     // ATOM_DEVICE_DFP1_INDEX....
+  UCHAR ucPadding[2];             
+}DFP_DPMS_STATUS_CHANGE_PARAMETERS;
+
+/****************************Legacy Power Play Table Definitions **********************/
+
+//Definitions for ulPowerPlayMiscInfo
+#define ATOM_PM_MISCINFO_SPLIT_CLOCK                     0x00000000L
+#define ATOM_PM_MISCINFO_USING_MCLK_SRC                  0x00000001L
+#define ATOM_PM_MISCINFO_USING_SCLK_SRC                  0x00000002L
+
+#define ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT            0x00000004L
+#define ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH        0x00000008L
+
+#define ATOM_PM_MISCINFO_LOAD_PERFORMANCE_EN             0x00000010L
+
+#define ATOM_PM_MISCINFO_ENGINE_CLOCK_CONTRL_EN          0x00000020L
+#define ATOM_PM_MISCINFO_MEMORY_CLOCK_CONTRL_EN          0x00000040L
+#define ATOM_PM_MISCINFO_PROGRAM_VOLTAGE                 0x00000080L  //When this bit set, ucVoltageDropIndex is not an index for GPIO pin, but a voltage ID that SW needs program  
+ 
+#define ATOM_PM_MISCINFO_ASIC_REDUCED_SPEED_SCLK_EN      0x00000100L
+#define ATOM_PM_MISCINFO_ASIC_DYNAMIC_VOLTAGE_EN         0x00000200L
+#define ATOM_PM_MISCINFO_ASIC_SLEEP_MODE_EN              0x00000400L
+#define ATOM_PM_MISCINFO_LOAD_BALANCE_EN                 0x00000800L
+#define ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE     0x00001000L
+#define ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE 0x00002000L
+#define ATOM_PM_MISCINFO_LOW_LCD_REFRESH_RATE            0x00004000L
+
+#define ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE             0x00008000L
+#define ATOM_PM_MISCINFO_OVER_CLOCK_MODE                 0x00010000L 
+#define ATOM_PM_MISCINFO_OVER_DRIVE_MODE                 0x00020000L
+#define ATOM_PM_MISCINFO_POWER_SAVING_MODE               0x00040000L
+#define ATOM_PM_MISCINFO_THERMAL_DIODE_MODE              0x00080000L
+
+#define ATOM_PM_MISCINFO_FRAME_MODULATION_MASK           0x00300000L  //0-FM Disable, 1-2 level FM, 2-4 level FM, 3-Reserved
+#define ATOM_PM_MISCINFO_FRAME_MODULATION_SHIFT          20 
+
+#define ATOM_PM_MISCINFO_DYN_CLK_3D_IDLE                 0x00400000L
+#define ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_2      0x00800000L
+#define ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_4      0x01000000L
+#define ATOM_PM_MISCINFO_DYNAMIC_HDP_BLOCK_EN            0x02000000L  //When set, Dynamic 
+#define ATOM_PM_MISCINFO_DYNAMIC_MC_HOST_BLOCK_EN        0x04000000L  //When set, Dynamic
+#define ATOM_PM_MISCINFO_3D_ACCELERATION_EN              0x08000000L  //When set, This mode is for acceleated 3D mode
+
+#define ATOM_PM_MISCINFO_POWERPLAY_SETTINGS_GROUP_MASK   0x70000000L  //1-Optimal Battery Life Group, 2-High Battery, 3-Balanced, 4-High Performance, 5- Optimal Performance (Default state with Default clocks) 
+#define ATOM_PM_MISCINFO_POWERPLAY_SETTINGS_GROUP_SHIFT  28
+#define ATOM_PM_MISCINFO_ENABLE_BACK_BIAS                0x80000000L
+
+#define ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE            0x00000001L
+#define ATOM_PM_MISCINFO2_MULTI_DISPLAY_SUPPORT          0x00000002L
+#define ATOM_PM_MISCINFO2_DYNAMIC_BACK_BIAS_EN           0x00000004L
+#define ATOM_PM_MISCINFO2_FS3D_OVERDRIVE_INFO            0x00000008L
+#define ATOM_PM_MISCINFO2_FORCEDLOWPWR_MODE              0x00000010L
+#define ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN       0x00000020L
+#define ATOM_PM_MISCINFO2_VIDEO_PLAYBACK_CAPABLE         0x00000040L  //If this bit is set in multi-pp mode, then driver will pack up one with the minior power consumption. 
+                                                                      //If it's not set in any pp mode, driver will use its default logic to pick a pp mode in video playback
+#define ATOM_PM_MISCINFO2_NOT_VALID_ON_DC                0x00000080L
+#define ATOM_PM_MISCINFO2_STUTTER_MODE_EN                0x00000100L
+#define ATOM_PM_MISCINFO2_UVD_SUPPORT_MODE               0x00000200L 
+
+//ucTableFormatRevision=1
+//ucTableContentRevision=1
+typedef struct  _ATOM_POWERMODE_INFO
+{
+  ULONG     ulMiscInfo;                 //The power level should be arranged in ascending order
+  ULONG     ulReserved1;                // must set to 0
+  ULONG     ulReserved2;                // must set to 0
+  USHORT    usEngineClock;
+  USHORT    usMemoryClock;
+  UCHAR     ucVoltageDropIndex;         // index to GPIO table
+  UCHAR     ucSelectedPanel_RefreshRate;// panel refresh rate
+  UCHAR     ucMinTemperature;
+  UCHAR     ucMaxTemperature;
+  UCHAR     ucNumPciELanes;             // number of PCIE lanes
+}ATOM_POWERMODE_INFO;
+
+//ucTableFormatRevision=2
+//ucTableContentRevision=1
+typedef struct  _ATOM_POWERMODE_INFO_V2
+{
+  ULONG     ulMiscInfo;                 //The power level should be arranged in ascending order
+  ULONG     ulMiscInfo2;                
+  ULONG     ulEngineClock;                
+  ULONG     ulMemoryClock;
+  UCHAR     ucVoltageDropIndex;         // index to GPIO table
+  UCHAR     ucSelectedPanel_RefreshRate;// panel refresh rate
+  UCHAR     ucMinTemperature;
+  UCHAR     ucMaxTemperature;
+  UCHAR     ucNumPciELanes;             // number of PCIE lanes
+}ATOM_POWERMODE_INFO_V2;
+
+//ucTableFormatRevision=2
+//ucTableContentRevision=2
+typedef struct  _ATOM_POWERMODE_INFO_V3
+{
+  ULONG     ulMiscInfo;                 //The power level should be arranged in ascending order
+  ULONG     ulMiscInfo2;                
+  ULONG     ulEngineClock;                
+  ULONG     ulMemoryClock;
+  UCHAR     ucVoltageDropIndex;         // index to Core (VDDC) votage table
+  UCHAR     ucSelectedPanel_RefreshRate;// panel refresh rate
+  UCHAR     ucMinTemperature;
+  UCHAR     ucMaxTemperature;
+  UCHAR     ucNumPciELanes;             // number of PCIE lanes
+  UCHAR     ucVDDCI_VoltageDropIndex;   // index to VDDCI votage table
+}ATOM_POWERMODE_INFO_V3;
+
+
+#define ATOM_MAX_NUMBEROF_POWER_BLOCK  8
+
+#define ATOM_PP_OVERDRIVE_INTBITMAP_AUXWIN            0x01
+#define ATOM_PP_OVERDRIVE_INTBITMAP_OVERDRIVE         0x02
+
+#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_LM63      0x01
+#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_ADM1032   0x02
+#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_ADM1030   0x03
+#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_MUA6649   0x04
+#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_LM64      0x05
+#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_F75375    0x06
+#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_ASC7512   0x07	// Andigilog
+
+
+typedef struct  _ATOM_POWERPLAY_INFO
+{
+  ATOM_COMMON_TABLE_HEADER	sHeader; 
+  UCHAR    ucOverdriveThermalController;
+  UCHAR    ucOverdriveI2cLine;
+  UCHAR    ucOverdriveIntBitmap;
+  UCHAR    ucOverdriveControllerAddress;
+  UCHAR    ucSizeOfPowerModeEntry;
+  UCHAR    ucNumOfPowerModeEntries;
+  ATOM_POWERMODE_INFO asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK];
+}ATOM_POWERPLAY_INFO;
+
+typedef struct  _ATOM_POWERPLAY_INFO_V2
+{
+  ATOM_COMMON_TABLE_HEADER	sHeader; 
+  UCHAR    ucOverdriveThermalController;
+  UCHAR    ucOverdriveI2cLine;
+  UCHAR    ucOverdriveIntBitmap;
+  UCHAR    ucOverdriveControllerAddress;
+  UCHAR    ucSizeOfPowerModeEntry;
+  UCHAR    ucNumOfPowerModeEntries;
+  ATOM_POWERMODE_INFO_V2 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK];
+}ATOM_POWERPLAY_INFO_V2;
+  
+typedef struct  _ATOM_POWERPLAY_INFO_V3
+{
+  ATOM_COMMON_TABLE_HEADER	sHeader; 
+  UCHAR    ucOverdriveThermalController;
+  UCHAR    ucOverdriveI2cLine;
+  UCHAR    ucOverdriveIntBitmap;
+  UCHAR    ucOverdriveControllerAddress;
+  UCHAR    ucSizeOfPowerModeEntry;
+  UCHAR    ucNumOfPowerModeEntries;
+  ATOM_POWERMODE_INFO_V3 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK];
+}ATOM_POWERPLAY_INFO_V3;
+
+
+
+/**************************************************************************/
+
+
+// Following definitions are for compatiblity issue in different SW components. 
+#define ATOM_MASTER_DATA_TABLE_REVISION   0x01
+#define Object_Info												Object_Header			
+#define	AdjustARB_SEQ											MC_InitParameter
+#define	VRAM_GPIO_DetectionInfo						VoltageObjectInfo
+#define	ASIC_VDDCI_Info                   ASIC_ProfilingInfo														
+#define ASIC_MVDDQ_Info										MemoryTrainingInfo
+#define SS_Info                           PPLL_SS_Info                      
+#define ASIC_MVDDC_Info                   ASIC_InternalSS_Info
+#define DispDevicePriorityInfo						SaveRestoreInfo
+#define DispOutInfo												TV_VideoMode
+
+
+#define ATOM_ENCODER_OBJECT_TABLE         ATOM_OBJECT_TABLE
+#define ATOM_CONNECTOR_OBJECT_TABLE       ATOM_OBJECT_TABLE
+
+#define ATOM_S3_SCALER2_ACTIVE_H          0x00004000L
+#define ATOM_S3_SCALER2_ACTIVE_V          0x00008000L
+#define ATOM_S6_REQ_SCALER2_H             0x00004000L
+#define ATOM_S6_REQ_SCALER2_V             0x00008000L
+ 
+#define ATOM_S3_SCALER1_ACTIVE_H          0x00001000L
+#define ATOM_S3_SCALER1_ACTIVE_V          0x00002000L
+ 
+#define ATOM_S6_REQ_SCALER1_H             ATOM_S6_REQ_LCD_EXPANSION_FULL
+#define ATOM_S6_REQ_SCALER1_V             ATOM_S6_REQ_LCD_EXPANSION_ASPEC_RATIO
+
+//New device naming, remove them when both DAL/VBIOS is ready
+#define DFP2I_OUTPUT_CONTROL_PARAMETERS    CRT1_OUTPUT_CONTROL_PARAMETERS
+#define DFP2I_OUTPUT_CONTROL_PS_ALLOCATION DFP2I_OUTPUT_CONTROL_PARAMETERS
+
+#define DFP1X_OUTPUT_CONTROL_PARAMETERS    CRT1_OUTPUT_CONTROL_PARAMETERS
+#define DFP1X_OUTPUT_CONTROL_PS_ALLOCATION DFP1X_OUTPUT_CONTROL_PARAMETERS
+
+#define DFP1I_OUTPUT_CONTROL_PARAMETERS    DFP1_OUTPUT_CONTROL_PARAMETERS
+#define DFP1I_OUTPUT_CONTROL_PS_ALLOCATION DFP1_OUTPUT_CONTROL_PS_ALLOCATION
+
+#define ATOM_DEVICE_DFP1I_SUPPORT          ATOM_DEVICE_DFP1_SUPPORT
+#define ATOM_DEVICE_DFP1X_SUPPORT          ATOM_DEVICE_DFP2_SUPPORT
+
+#define ATOM_DEVICE_DFP1I_INDEX            ATOM_DEVICE_DFP1_INDEX
+#define ATOM_DEVICE_DFP1X_INDEX            ATOM_DEVICE_DFP2_INDEX
+ 
+#define ATOM_DEVICE_DFP2I_INDEX            0x00000009
+#define ATOM_DEVICE_DFP2I_SUPPORT          (0x1L << ATOM_DEVICE_DFP2I_INDEX)
+
+#define ATOM_S0_DFP1I                      ATOM_S0_DFP1
+#define ATOM_S0_DFP1X                      ATOM_S0_DFP2
+
+#define ATOM_S0_DFP2I                      0x00200000L
+#define ATOM_S0_DFP2Ib2                    0x20
+
+#define ATOM_S2_DFP1I_DPMS_STATE           ATOM_S2_DFP1_DPMS_STATE
+#define ATOM_S2_DFP1X_DPMS_STATE           ATOM_S2_DFP2_DPMS_STATE
+
+#define ATOM_S2_DFP2I_DPMS_STATE           0x02000000L
+#define ATOM_S2_DFP2I_DPMS_STATEb3         0x02
+
+#define ATOM_S3_DFP2I_ACTIVEb1             0x02
+
+#define ATOM_S3_DFP1I_ACTIVE               ATOM_S3_DFP1_ACTIVE 
+#define ATOM_S3_DFP1X_ACTIVE               ATOM_S3_DFP2_ACTIVE
+
+#define ATOM_S3_DFP2I_ACTIVE               0x00000200L
+
+#define ATOM_S3_DFP1I_CRTC_ACTIVE          ATOM_S3_DFP1_CRTC_ACTIVE
+#define ATOM_S3_DFP1X_CRTC_ACTIVE          ATOM_S3_DFP2_CRTC_ACTIVE
+#define ATOM_S3_DFP2I_CRTC_ACTIVE          0x02000000L
+
+#define ATOM_S3_DFP2I_CRTC_ACTIVEb3        0x02
+#define ATOM_S5_DOS_REQ_DFP2Ib1            0x02
+
+#define ATOM_S5_DOS_REQ_DFP2I              0x0200
+#define ATOM_S6_ACC_REQ_DFP1I              ATOM_S6_ACC_REQ_DFP1
+#define ATOM_S6_ACC_REQ_DFP1X              ATOM_S6_ACC_REQ_DFP2
+
+#define ATOM_S6_ACC_REQ_DFP2Ib3            0x02
+#define ATOM_S6_ACC_REQ_DFP2I              0x02000000L
+
+#define TMDS1XEncoderControl               DVOEncoderControl           
+#define DFP1XOutputControl                 DVOOutputControl
+
+#define ExternalDFPOutputControl           DFP1XOutputControl
+#define EnableExternalTMDS_Encoder         TMDS1XEncoderControl
+
+#define DFP1IOutputControl                 TMDSAOutputControl
+#define DFP2IOutputControl                 LVTMAOutputControl      
+
+#define DAC1_ENCODER_CONTROL_PARAMETERS    DAC_ENCODER_CONTROL_PARAMETERS
+#define DAC1_ENCODER_CONTROL_PS_ALLOCATION DAC_ENCODER_CONTROL_PS_ALLOCATION
+
+#define DAC2_ENCODER_CONTROL_PARAMETERS    DAC_ENCODER_CONTROL_PARAMETERS
+#define DAC2_ENCODER_CONTROL_PS_ALLOCATION DAC_ENCODER_CONTROL_PS_ALLOCATION
+
+#define ucDac1Standard  ucDacStandard
+#define ucDac2Standard  ucDacStandard  
+
+#define TMDS1EncoderControl TMDSAEncoderControl
+#define TMDS2EncoderControl LVTMAEncoderControl
+
+#define DFP1OutputControl   TMDSAOutputControl
+#define DFP2OutputControl   LVTMAOutputControl
+#define CRT1OutputControl   DAC1OutputControl
+#define CRT2OutputControl   DAC2OutputControl
+
+//These two lines will be removed for sure in a few days, will follow up with Michael V.
+#define EnableLVDS_SS   EnableSpreadSpectrumOnPPLL
+#define ENABLE_LVDS_SS_PARAMETERS_V3  ENABLE_SPREAD_SPECTRUM_ON_PPLL  
+
+/*********************************************************************************/
+
+//==========================================================================================
+
+#pragma pack() // BIOS data must use byte aligment
+
+#endif /* _ATOMBIOS_H */
diff --git a/src/AtomBios/includes/regsdef.h b/src/AtomBios/includes/regsdef.h
new file mode 100644
index 0000000..e557ac0
--- /dev/null
+++ b/src/AtomBios/includes/regsdef.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2006-2007 Advanced Micro Devices, Inc.  
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+//This is a dummy file used by driver-parser during compilation. 
+//Without this file, compatibility will be broken among ASICs and  BIOs vs. driver
+//James H. Apr. 22/03
diff --git a/src/Makefile.am b/src/Makefile.am
index 5152577..661dcd8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -32,6 +32,38 @@ R128_DRI_SRCS = r128_dri.c
 RADEON_DRI_SRCS = radeon_dri.c
 endif
 
+RADEON_ATOMBIOS_SOURCES = \
+	AtomBios/CD_Operations.c \
+	AtomBios/Decoder.c \
+	AtomBios/hwserv_drv.c \
+	AtomBios/includes/atombios.h \
+        AtomBios/includes/CD_binding.h \
+        AtomBios/includes/CD_Common_Types.h \
+        AtomBios/includes/CD_Definitions.h \
+        AtomBios/includes/CD_hw_services.h \
+        AtomBios/includes/CD_Opcodes.h \
+        AtomBios/includes/CD_Structs.h \
+        AtomBios/includes/Decoder.h \
+        AtomBios/includes/ObjectID.h \
+        AtomBios/includes/regsdef.h
+
+XMODE_SRCS=\
+        local_xf86Rename.h \
+	parser/xf86Parser.h \
+        parser/xf86Optrec.h \
+        modes/xf86Modes.h \
+        modes/xf86Modes.c \
+        modes/xf86cvt.c \
+        modes/xf86Crtc.h \
+        modes/xf86Crtc.c \
+        modes/xf86Cursors.c \
+        modes/xf86EdidModes.c \
+        modes/xf86RandR12.c \
+        modes/xf86RandR12.h \
+        modes/xf86Rename.h \
+        modes/xf86Rotate.c \
+        modes/xf86DiDGA.c
+
 if ATIMISC_CPIO
 ATIMISC_CPIO_SOURCES = ativga.c ativgaio.c atibank.c atiwonder.c atiwonderio.c
 endif
@@ -45,7 +77,8 @@ ATIMISC_EXA_SOURCES = atimach64exa.c
 RADEON_EXA_SOURCES = radeon_exa.c
 endif
 
-AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@
+AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ @XMODES_CFLAGS@ -DDISABLE_EASF -DENABLE_ALL_SERVICE_FUNCTIONS -DATOM_BIOS -DATOM_BIOS_PARSER -DFGL_LINUX -DDRIVER_PARSER
+INCLUDES = -I$(srcdir)/AtomBios/includes
 
 ati_drv_la_LTLIBRARIES = ati_drv.la
 ati_drv_la_LDFLAGS = -module -avoid-version
@@ -53,10 +86,10 @@ ati_drv_ladir = @moduledir@/drivers
 ati_drv_la_SOURCES = \
 	ati.c atimodule.c
 
-atimisc_drv_la_LTLIBRARIES = atimisc_drv.la
-atimisc_drv_la_LDFLAGS = -module -avoid-version
-atimisc_drv_ladir = @moduledir@/drivers
-atimisc_drv_la_SOURCES = \
+mach64_drv_la_LTLIBRARIES = mach64_drv.la
+mach64_drv_la_LDFLAGS = -module -avoid-version
+mach64_drv_ladir = @moduledir@/drivers
+mach64_drv_la_SOURCES = \
 	atibus.c atichip.c atiprobe.c atividmem.c \
 	atiadjust.c atiaudio.c aticlock.c aticonfig.c aticonsole.c \
 	atidac.c atidecoder.c atidsp.c atii2c.c \
@@ -66,16 +99,12 @@ atimisc_drv_la_SOURCES = \
 	atiload.c atimisc.c atimach64probe.c $(ATIMISC_CPIO_SOURCES) \
 	$(ATIMISC_DGA_SOURCES) $(ATIMISC_DRI_SRCS) $(ATIMISC_EXA_SOURCES)
 
-if XSERVER_LIBPCIACCESS
-# r128 has not been ported yet
-else
 r128_drv_la_LTLIBRARIES = r128_drv.la
 r128_drv_la_LDFLAGS = -module -avoid-version
 r128_drv_ladir = @moduledir@/drivers
 r128_drv_la_SOURCES = \
 	r128_accel.c r128_cursor.c r128_dga.c r128_driver.c \
 	r128_video.c r128_misc.c r128_probe.c $(R128_DRI_SRCS)
-endif
 
 radeon_drv_la_LTLIBRARIES = radeon_drv.la
 radeon_drv_la_LDFLAGS = -module -avoid-version
@@ -83,9 +112,16 @@ radeon_drv_ladir = @moduledir@/drivers
 radeon_drv_la_SOURCES = \
 	radeon_accel.c radeon_cursor.c radeon_dga.c \
 	radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
-	radeon_vip.c radeon_misc.c radeon_probe.c radeon_display.c \
+	radeon_vip.c radeon_misc.c radeon_probe.c \
+	legacy_crtc.c legacy_output.c \
 	radeon_crtc.c radeon_output.c radeon_modes.c radeon_tv.c \
-	$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
+	$(RADEON_ATOMBIOS_SOURCES) radeon_atombios.c radeon_atomwrapper.c \
+	$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES) atombios_output.c atombios_crtc.c
+
+if XMODES
+radeon_drv_la_SOURCES += \
+	$(XMODE_SRCS)
+endif
 
 theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la
 theatre_detect_drv_la_LDFLAGS = -module -avoid-version
@@ -109,6 +145,7 @@ theatre200_drv_la_SOURCES = \
 	theatre200.c theatre200_module.c
 
 EXTRA_DIST = \
+	$(XMODE_SRCS) \
 	atimach64render.c \
 	radeon_render.c \
 	radeon_accelfuncs.c \
@@ -138,7 +175,6 @@ EXTRA_DIST = \
 	atimach64io.h \
 	atimach64probe.h \
 	atimode.h \
-	atimodule.h \
 	atioption.h \
 	atipreinit.h \
 	atiprint.h \
@@ -185,6 +221,7 @@ EXTRA_DIST = \
 	radeon_version.h \
 	radeon_video.h \
 	radeon_tv.h \
+        radeon_atomwrapper.h \
 	theatre200.h \
 	theatre_detect.h \
 	theatre.h \
@@ -196,4 +233,5 @@ EXTRA_DIST = \
 	radeon_chipset_gen.h \
 	radeon_pci_chipset_gen.h \
 	pcidb/ati_pciids.csv \
-	pcidb/parse_pci_ids.pl
+	pcidb/parse_pci_ids.pl \
+	radeon_atombios.h
diff --git a/src/ati.c b/src/ati.c
index ada165f..89e62dc 100644
--- a/src/ati.c
+++ b/src/ati.c
@@ -63,12 +63,48 @@
 #include "atipcirename.h"
 
 #include "ati.h"
-#include "atimodule.h"
 #include "ativersion.h"
-#include "atimach64probe.h"
 
-#include "radeon_probe.h"
-#include "r128_probe.h"
+/* names duplicated from version headers */
+#define MACH64_NAME         "MACH64"
+#define MACH64_DRIVER_NAME  "mach64"
+#define R128_NAME           "R128"
+#define R128_DRIVER_NAME    "r128"
+#define RADEON_NAME         "RADEON"
+#define RADEON_DRIVER_NAME  "radeon"
+
+enum
+{
+    ATI_CHIP_FAMILY_NONE = 0,
+    ATI_CHIP_FAMILY_Mach64,
+    ATI_CHIP_FAMILY_Rage128,
+    ATI_CHIP_FAMILY_Radeon
+};
+
+/*
+ * Record which sub-drivers have already been loaded, and thus have called
+ * xf86AddDriver(). For those sub-drivers, cause the ati wrapper later to fail
+ * when probing.
+ *
+ * The check is only called once when the ati wrapper is loaded and depends on
+ * the X server loading all drivers before doing any probes.
+ */
+static Bool mach64_drv_added = FALSE;
+static Bool r128_drv_added = FALSE;
+static Bool radeon_drv_added = FALSE;
+
+void
+ati_check_subdriver_added()
+{
+    if (LoaderSymbol(MACH64_NAME))
+        mach64_drv_added = TRUE;
+    if (LoaderSymbol(R128_NAME))
+        r128_drv_added = TRUE;
+    if (LoaderSymbol(RADEON_NAME))
+        radeon_drv_added = TRUE;
+}
+
+static int ATIChipID(const CARD16);
 
 #ifdef XSERVER_LIBPCIACCESS
 static const struct pci_id_match ati_device_match = {
@@ -127,7 +163,11 @@ ATIProbe
 #endif
     Bool        DoMach64 = FALSE;
     Bool        DoRage128 = FALSE, DoRadeon = FALSE;
-    ATIChipType Chip;
+    int         Chip;
+
+    /* Let the sub-drivers probe & configure for themselves */
+    if (xf86ServerIsOnlyDetecting())
+        return FALSE;
 
 #ifndef XSERVER_LIBPCIACCESS
 
@@ -143,12 +183,12 @@ ATIProbe
             continue;
 
         /* Check for Rage128's, Radeon's and later adapters */
-        Chip = ATIChipID(PCI_DEV_DEVICE_ID(pVideo), PCI_DEV_REVISION(pVideo));
-        if (Chip <= ATI_CHIP_Mach64)
+        Chip = ATIChipID(PCI_DEV_DEVICE_ID(pVideo));
+        if (Chip == ATI_CHIP_FAMILY_Mach64)
             DoMach64 = TRUE;
-        else if (Chip <= ATI_CHIP_Rage128)
+        else if (Chip == ATI_CHIP_FAMILY_Rage128)
             DoRage128 = TRUE;
-        else if (Chip <= ATI_CHIP_Radeon)
+        else if (Chip == ATI_CHIP_FAMILY_Radeon)
             DoRadeon = TRUE;
     }
 
@@ -168,12 +208,12 @@ ATIProbe
             continue;
 
         /* Check for Rage128's, Radeon's and later adapters */
-        Chip = ATIChipID(PCI_DEV_DEVICE_ID(pVideo), PCI_DEV_REVISION(pVideo));
-        if (Chip <= ATI_CHIP_Mach64)
+        Chip = ATIChipID(PCI_DEV_DEVICE_ID(pVideo));
+        if (Chip == ATI_CHIP_FAMILY_Mach64)
             DoMach64 = TRUE;
-        else if (Chip <= ATI_CHIP_Rage128)
+        else if (Chip == ATI_CHIP_FAMILY_Rage128)
             DoRage128 = TRUE;
-        else if (Chip <= ATI_CHIP_Radeon)
+        else if (Chip == ATI_CHIP_FAMILY_Radeon)
             DoRadeon = TRUE;
     }
 
@@ -184,67 +224,82 @@ ATIProbe
     /* Call Radeon driver probe */
     if (DoRadeon)
     {
-        pointer radeon = xf86LoadDrvSubModule(pDriver, "radeon");
+        DriverRec *radeon;
+
+        /* If the sub-driver was added, let it probe for itself */
+        if (radeon_drv_added)
+            return FALSE;
+
+        if (!LoaderSymbol(RADEON_NAME))
+            xf86LoadDrvSubModule(pDriver, RADEON_DRIVER_NAME);
+
+        radeon = (DriverRec*)LoaderSymbol(RADEON_NAME);
 
         if (!radeon)
         {
             xf86Msg(X_ERROR,
-                ATI_NAME ":  Failed to load \"radeon\" module.\n");
+                ATI_NAME ":  Failed to find \"radeon\" driver symbol.\n");
             return FALSE;
         }
 
-        xf86LoaderReqSymLists(RADEONSymbols, NULL);
+        radeon->Identify(flags);
 
-        RADEONIdentify(flags);
-
-        if (RADEONProbe(pDriver, flags))
+        if (radeon->Probe(pDriver, flags))
             return TRUE;
-
-        xf86UnloadSubModule(radeon);
     }
 
     /* Call Rage 128 driver probe */
     if (DoRage128)
     {
-        pointer r128 = xf86LoadDrvSubModule(pDriver, "r128");
+        DriverRec *r128;
+
+        /* If the sub-driver was added, let it probe for itself */
+        if (r128_drv_added)
+            return FALSE;
+
+        if (!LoaderSymbol(R128_NAME))
+            xf86LoadDrvSubModule(pDriver, R128_DRIVER_NAME);
+
+        r128 = (DriverRec*)LoaderSymbol(R128_NAME);
 
         if (!r128)
         {
             xf86Msg(X_ERROR,
-                ATI_NAME ":  Failed to load \"r128\" module.\n");
+                ATI_NAME ":  Failed to find \"r128\" driver symbol.\n");
             return FALSE;
         }
 
-        xf86LoaderReqSymLists(R128Symbols, NULL);
+        r128->Identify(flags);
 
-        R128Identify(flags);
-
-        if (R128Probe(pDriver, flags))
+        if (r128->Probe(pDriver, flags))
             return TRUE;
-
-        xf86UnloadSubModule(r128);
     }
 
     /* Call Mach64 driver probe */
     if (DoMach64)
     {
-        pointer atimisc = xf86LoadDrvSubModule(pDriver, "atimisc");
+        DriverRec *mach64;
 
-        if (!atimisc)
+        /* If the sub-driver was added, let it probe for itself */
+        if (mach64_drv_added)
+            return FALSE;
+
+        if (!LoaderSymbol(MACH64_NAME))
+            xf86LoadDrvSubModule(pDriver, MACH64_DRIVER_NAME);
+
+        mach64 = (DriverRec*)LoaderSymbol(MACH64_NAME);
+
+        if (!mach64)
         {
             xf86Msg(X_ERROR,
-                ATI_NAME ":  Failed to load \"atimisc\" module.\n");
+                ATI_NAME ":  Failed to find \"mach64\" driver symbol.\n");
             return FALSE;
         }
 
-        xf86LoaderReqSymLists(ATISymbols, NULL);
+        mach64->Identify(flags);
 
-        Mach64Identify(flags);
-
-        if (Mach64Probe(pDriver, flags))
+        if (mach64->Probe(pDriver, flags))
             return TRUE;
-
-        xf86UnloadSubModule(atimisc);
     }
 
     return FALSE;
@@ -263,17 +318,52 @@ ATIAvailableOptions
 )
 {
     CARD16      ChipType = ChipId & 0xffff;
-    ATIChipType Chip;
+    int         Chip;
 
     /* Probe should have loaded the appropriate subdriver by this point */
 
-    Chip = ATIChipID(ChipType, 0x0); /* chip revision is don't care */
-    if (Chip <= ATI_CHIP_Mach64)
-        return Mach64AvailableOptions(ChipId, BusId);
-    else if (Chip <= ATI_CHIP_Rage128)
-        return R128AvailableOptions(ChipId, BusId);
-    else if (Chip <= ATI_CHIP_Radeon)
-        return RADEONAvailableOptions(ChipId, BusId);
+    Chip = ATIChipID(ChipType);
+    if (Chip == ATI_CHIP_FAMILY_Mach64)
+    {
+        DriverRec *mach64 = (DriverRec*)LoaderSymbol(MACH64_NAME);
+
+        if (!mach64)
+        {
+            xf86Msg(X_ERROR,
+                ATI_NAME ":  Failed to find \"mach64\" driver symbol.\n");
+            return NULL;
+        }
+
+        return mach64->AvailableOptions(ChipId, BusId);
+    }
+
+    if (Chip == ATI_CHIP_FAMILY_Rage128)
+    {
+        DriverRec *r128 = (DriverRec*)LoaderSymbol(R128_NAME);
+
+        if (!r128)
+        {
+            xf86Msg(X_ERROR,
+                ATI_NAME ":  Failed to find \"r128\" driver symbol.\n");
+            return NULL;
+        }
+
+        return r128->AvailableOptions(ChipId, BusId);
+    }
+
+    if (Chip == ATI_CHIP_FAMILY_Radeon)
+    {
+        DriverRec *radeon = (DriverRec*)LoaderSymbol(RADEON_NAME);
+
+        if (!radeon)
+        {
+            xf86Msg(X_ERROR,
+                ATI_NAME ":  Failed to find \"radeon\" driver symbol.\n");
+            return NULL;
+        }
+
+        return radeon->AvailableOptions(ChipId, BusId);
+    }
 
     return NULL;
 }
@@ -291,467 +381,105 @@ _X_EXPORT DriverRec ATI =
 };
 
 /*
- * Chip-related definitions.
- */
-const char *ATIChipNames[] =
-{
-    "Unknown",
-    "ATI 88800GX-C",
-    "ATI 88800GX-D",
-    "ATI 88800GX-E",
-    "ATI 88800GX-F",
-    "ATI 88800GX",
-    "ATI 88800CX",
-    "ATI 264CT",
-    "ATI 264ET",
-    "ATI 264VT",
-    "ATI 3D Rage",
-    "ATI 264VT-B",
-    "ATI 3D Rage II",
-    "ATI 264VT3",
-    "ATI 3D Rage II+DVD",
-    "ATI 3D Rage LT",
-    "ATI 264VT4",
-    "ATI 3D Rage IIc",
-    "ATI 3D Rage Pro",
-    "ATI 3D Rage LT Pro",
-    "ATI 3D Rage XL or XC",
-    "ATI 3D Rage Mobility",
-    "ATI unknown Mach64",
-    "ATI Rage 128 GL",
-    "ATI Rage 128 VR",
-    "ATI Rage 128 Pro GL",
-    "ATI Rage 128 Pro VR",
-    "ATI Rage 128 Pro ULTRA",
-    "ATI Rage 128 Mobility M3",
-    "ATI Rage 128 Mobility M4",
-    "ATI unknown Rage 128"
-    "ATI Radeon 7200",
-    "ATI Radeon 7000 (VE)",
-    "ATI Radeon Mobility M6",
-    "ATI Radeon IGP320",
-    "ATI Radeon IGP330/340/350",
-    "ATI Radeon 7000 IGP",
-    "ATI Radeon 7500",
-    "ATI Radeon Mobility M7",
-    "ATI Radeon 8500/9100",
-    "ATI Radeon 9000",
-    "ATI Radeon Mobility M9",
-    "ATI Radeon 9100 IGP",
-    "ATI Radeon 9200 IGP",
-    "ATI Radeon 9200",
-    "ATI Radeon Mobility M9+",
-    "ATI Radeon 9700/9500",
-    "ATI Radeon 9600/9550",
-    "ATI Radeon 9800",
-    "ATI Radeon 9800XT",
-    "ATI Radeon X300/X550/M22",
-    "ATI Radeon X600/X550/M24",
-    "ATI Radeon X800/M18 AGP",
-    "ATI Radeon X800/M28 PCIE",
-    "ATI Radeon X800XL PCIE",
-    "ATI Radeon X850 PCIE",
-    "ATI Radeon X850 AGP",
-    "ATI Radeon X700",
-    "ATI Xpress 200"
-    "ATI unknown Radeon",
-    "ATI Rage HDTV"
-};
-
-#include "atichip.h"
-
-/*
  * ATIChipID --
  *
- * This returns the ATI_CHIP_* value (generally) associated with a particular
- * ChipID/ChipRev combination.
+ * This returns the ATI_CHIP_FAMILY_* value associated with a particular ChipID.
  */
-ATIChipType
-ATIChipID
-(
-    const CARD16 ChipID,
-    const CARD8  ChipRev
-)
+static int
+ATIChipID(const CARD16 ChipID)
 {
     switch (ChipID)
     {
-        case OldChipID('G', 'X'):  case NewChipID('G', 'X'):
-            switch (ChipRev)
-            {
-                case 0x00U:
-                    return ATI_CHIP_88800GXC;
-
-                case 0x01U:
-                    return ATI_CHIP_88800GXD;
-
-                case 0x02U:
-                    return ATI_CHIP_88800GXE;
-
-                case 0x03U:
-                    return ATI_CHIP_88800GXF;
-
-                default:
-                    return ATI_CHIP_88800GX;
-            }
-
-        case OldChipID('C', 'X'):  case NewChipID('C', 'X'):
-            return ATI_CHIP_88800CX;
-
-        case OldChipID('C', 'T'):  case NewChipID('C', 'T'):
-            return ATI_CHIP_264CT;
-
-        case OldChipID('E', 'T'):  case NewChipID('E', 'T'):
-            return ATI_CHIP_264ET;
-
-        case OldChipID('V', 'T'):  case NewChipID('V', 'T'):
-            /* For simplicity, ignore ChipID discrepancy that can occur here */
-            if (!(ChipRev & GetBits(CFG_CHIP_VERSION, CFG_CHIP_REV)))
-                return ATI_CHIP_264VT;
-            return ATI_CHIP_264VTB;
-
-        case OldChipID('G', 'T'):  case NewChipID('G', 'T'):
-            if (!(ChipRev & GetBits(CFG_CHIP_VERSION, CFG_CHIP_REV)))
-                return ATI_CHIP_264GT;
-            return ATI_CHIP_264GTB;
-
-        case OldChipID('V', 'U'):  case NewChipID('V', 'U'):
-            return ATI_CHIP_264VT3;
-
-        case OldChipID('G', 'U'):  case NewChipID('G', 'U'):
-            return ATI_CHIP_264GTDVD;
-
-        case OldChipID('L', 'G'):  case NewChipID('L', 'G'):
-            return ATI_CHIP_264LT;
-
-        case OldChipID('V', 'V'):  case NewChipID('V', 'V'):
-            return ATI_CHIP_264VT4;
-
-        case OldChipID('G', 'V'):  case NewChipID('G', 'V'):
-        case OldChipID('G', 'W'):  case NewChipID('G', 'W'):
-        case OldChipID('G', 'Y'):  case NewChipID('G', 'Y'):
-        case OldChipID('G', 'Z'):  case NewChipID('G', 'Z'):
-            return ATI_CHIP_264GT2C;
-
-        case OldChipID('G', 'B'):  case NewChipID('G', 'B'):
-        case OldChipID('G', 'D'):  case NewChipID('G', 'D'):
-        case OldChipID('G', 'I'):  case NewChipID('G', 'I'):
-        case OldChipID('G', 'P'):  case NewChipID('G', 'P'):
-        case OldChipID('G', 'Q'):  case NewChipID('G', 'Q'):
-            return ATI_CHIP_264GTPRO;
-
-        case OldChipID('L', 'B'):  case NewChipID('L', 'B'):
-        case OldChipID('L', 'D'):  case NewChipID('L', 'D'):
-        case OldChipID('L', 'I'):  case NewChipID('L', 'I'):
-        case OldChipID('L', 'P'):  case NewChipID('L', 'P'):
-        case OldChipID('L', 'Q'):  case NewChipID('L', 'Q'):
-            return ATI_CHIP_264LTPRO;
-
-        case OldChipID('G', 'L'):  case NewChipID('G', 'L'):
-        case OldChipID('G', 'M'):  case NewChipID('G', 'M'):
-        case OldChipID('G', 'N'):  case NewChipID('G', 'N'):
-        case OldChipID('G', 'O'):  case NewChipID('G', 'O'):
-        case OldChipID('G', 'R'):  case NewChipID('G', 'R'):
-        case OldChipID('G', 'S'):  case NewChipID('G', 'S'):
-            return ATI_CHIP_264XL;
-
-        case OldChipID('L', 'M'):  case NewChipID('L', 'M'):
-        case OldChipID('L', 'N'):  case NewChipID('L', 'N'):
-        case OldChipID('L', 'R'):  case NewChipID('L', 'R'):
-        case OldChipID('L', 'S'):  case NewChipID('L', 'S'):
-            return ATI_CHIP_MOBILITY;
-
-        case NewChipID('R', 'E'):
-        case NewChipID('R', 'F'):
-        case NewChipID('R', 'G'):
-        case NewChipID('S', 'K'):
-        case NewChipID('S', 'L'):
-        case NewChipID('S', 'M'):
-        /* "SN" is listed as ATI_CHIP_RAGE128_4X in ATI docs */
-        case NewChipID('S', 'N'):
-            return ATI_CHIP_RAGE128GL;
-
-        case NewChipID('R', 'K'):
-        case NewChipID('R', 'L'):
-        /*
-         * ATI documentation lists SE/SF/SG under both ATI_CHIP_RAGE128VR
-         * and ATI_CHIP_RAGE128_4X, and lists SH/SK/SL under Rage 128 4X only.
-         * I'm stuffing them here for now until this can be clarified as ATI
-         * documentation doesn't mention their details. <mharris@redhat.com>
-         */
-        case NewChipID('S', 'E'):
-        case NewChipID('S', 'F'):
-        case NewChipID('S', 'G'):
-        case NewChipID('S', 'H'):
-            return ATI_CHIP_RAGE128VR;
-
-     /* case NewChipID('S', 'H'): */
-     /* case NewChipID('S', 'K'): */
-     /* case NewChipID('S', 'L'): */
-     /* case NewChipID('S', 'N'): */
-     /*     return ATI_CHIP_RAGE128_4X; */
-
-        case NewChipID('P', 'A'):
-        case NewChipID('P', 'B'):
-        case NewChipID('P', 'C'):
-        case NewChipID('P', 'D'):
-        case NewChipID('P', 'E'):
-        case NewChipID('P', 'F'):
-            return ATI_CHIP_RAGE128PROGL;
-
-        case NewChipID('P', 'G'):
-        case NewChipID('P', 'H'):
-        case NewChipID('P', 'I'):
-        case NewChipID('P', 'J'):
-        case NewChipID('P', 'K'):
-        case NewChipID('P', 'L'):
-        case NewChipID('P', 'M'):
-        case NewChipID('P', 'N'):
-        case NewChipID('P', 'O'):
-        case NewChipID('P', 'P'):
-        case NewChipID('P', 'Q'):
-        case NewChipID('P', 'R'):
-        case NewChipID('P', 'S'):
-        case NewChipID('P', 'T'):
-        case NewChipID('P', 'U'):
-        case NewChipID('P', 'V'):
-        case NewChipID('P', 'W'):
-        case NewChipID('P', 'X'):
-            return ATI_CHIP_RAGE128PROVR;
-
-        case NewChipID('T', 'F'):
-        case NewChipID('T', 'L'):
-        case NewChipID('T', 'R'):
-        case NewChipID('T', 'S'):
-        case NewChipID('T', 'T'):
-        case NewChipID('T', 'U'):
-            return ATI_CHIP_RAGE128PROULTRA;
-
-        case NewChipID('L', 'E'):
-        case NewChipID('L', 'F'):
-        /*
-         * "LK" and "LL" are not in any ATI documentation I can find
-         * - mharris
-         */
-        case NewChipID('L', 'K'):
-        case NewChipID('L', 'L'):
-            return ATI_CHIP_RAGE128MOBILITY3;
-
-        case NewChipID('M', 'F'):
-        case NewChipID('M', 'L'):
-            return ATI_CHIP_RAGE128MOBILITY4;
-
-        case NewChipID('Q', 'D'):
-        case NewChipID('Q', 'E'):
-        case NewChipID('Q', 'F'):
-        case NewChipID('Q', 'G'):
-            return ATI_CHIP_RADEON;
-
-        case NewChipID('Q', 'Y'):
-        case NewChipID('Q', 'Z'):
-        case NewChipID('Q', '^'):
-            return ATI_CHIP_RADEONVE;
-
-        case NewChipID('L', 'Y'):
-        case NewChipID('L', 'Z'):
-            return ATI_CHIP_RADEONMOBILITY6;
-
-        case NewChipID('A', '6'):
-        case NewChipID('C', '6'):
-             return ATI_CHIP_RS100;
-
-        case NewChipID('A', '7'):
-        case NewChipID('C', '7'):
-             return ATI_CHIP_RS200;
-
-        case NewChipID('D', '7'):
-        case NewChipID('B', '7'):
-             return ATI_CHIP_RS250;
-
-        case NewChipID('L', 'W'):
-        case NewChipID('L', 'X'):
-            return ATI_CHIP_RADEONMOBILITY7;
-
-        case NewChipID('Q', 'H'):
-        case NewChipID('Q', 'I'):
-        case NewChipID('Q', 'J'):
-        case NewChipID('Q', 'K'):
-        case NewChipID('Q', 'L'):
-        case NewChipID('Q', 'M'):
-        case NewChipID('Q', 'N'):
-        case NewChipID('Q', 'O'):
-        case NewChipID('Q', 'h'):
-        case NewChipID('Q', 'i'):
-        case NewChipID('Q', 'j'):
-        case NewChipID('Q', 'k'):
-        case NewChipID('Q', 'l'):
-        case NewChipID('B', 'B'):
-            return ATI_CHIP_R200;
-
-        case NewChipID('Q', 'W'):
-        case NewChipID('Q', 'X'):
-            return ATI_CHIP_RV200;
-
-        case NewChipID('I', 'f'):
-        case NewChipID('I', 'g'):
-            return ATI_CHIP_RV250;
-
-        case NewChipID('L', 'd'):
-        case NewChipID('L', 'f'):
-        case NewChipID('L', 'g'):
-            return ATI_CHIP_RADEONMOBILITY9;
-
-        case NewChipID('X', '4'):
-        case NewChipID('X', '5'):
-             return ATI_CHIP_RS300;
-
-        case NewChipID('x', '4'):
-        case NewChipID('x', '5'):
-             return ATI_CHIP_RS350;
-
-        case NewChipID('Y', '\''):
-        case NewChipID('Y', 'a'):
-        case NewChipID('Y', 'b'):
-        case NewChipID('Y', 'd'):
-        case NewChipID('Y', 'e'):
-            return ATI_CHIP_RV280;
-
-        case NewChipID('\\', 'a'):
-        case NewChipID('\\', 'c'):
-            return ATI_CHIP_RADEONMOBILITY9PLUS;
-
-        case NewChipID('A', 'D'):
-        case NewChipID('A', 'E'):
-        case NewChipID('A', 'F'):
-        case NewChipID('A', 'G'):
-        case NewChipID('N', 'D'):
-        case NewChipID('N', 'E'):
-        case NewChipID('N', 'F'):
-        case NewChipID('N', 'G'):
-            return ATI_CHIP_R300;
-
-        case NewChipID('A', 'H'):
-        case NewChipID('A', 'I'):
-        case NewChipID('A', 'J'):
-        case NewChipID('A', 'K'):
-        case NewChipID('N', 'H'):
-        case NewChipID('N', 'I'):
-        case NewChipID('N', 'K'):
-            return ATI_CHIP_R350;
-
-        case NewChipID('A', 'P'):
-        case NewChipID('A', 'Q'):
-        case NewChipID('A', 'R'):
-        case NewChipID('A', 'S'):
-        case NewChipID('A', 'T'):
-        case NewChipID('A', 'U'):
-        case NewChipID('A', 'V'):
-        case NewChipID('N', 'P'):
-        case NewChipID('N', 'Q'):
-        case NewChipID('N', 'R'):
-        case NewChipID('N', 'S'):
-        case NewChipID('N', 'T'):
-        case NewChipID('N', 'V'):
-            return ATI_CHIP_RV350;
-
-        case NewChipID('N', 'J'):
-            return ATI_CHIP_R360;
-
-        case NewChipID('[', '\''):
-        case NewChipID('[', 'b'):
-        case NewChipID('[', 'c'):
-        case NewChipID('[', 'd'):
-        case NewChipID('[', 'e'):
-        case NewChipID('T', '\''):
-        case NewChipID('T', 'b'):
-        case NewChipID('T', 'd'):
-	    return ATI_CHIP_RV370;
-
-        case NewChipID('>', 'P'):
-        case NewChipID('>', 'T'):
-        case NewChipID('1', 'P'):
-        case NewChipID('1', 'R'):
-        case NewChipID('1', 'T'):
-	    return ATI_CHIP_RV380;
-
-        case NewChipID('J', 'H'):
-        case NewChipID('J', 'I'):
-        case NewChipID('J', 'J'):
-        case NewChipID('J', 'K'):
-        case NewChipID('J', 'L'):
-        case NewChipID('J', 'M'):
-        case NewChipID('J', 'N'):
-        case NewChipID('J', 'O'):
-        case NewChipID('J', 'P'):
-        case NewChipID('J', 'T'):
-	    return ATI_CHIP_R420;
-
-        case NewChipID('U', 'H'):
-        case NewChipID('U', 'I'):
-        case NewChipID('U', 'J'):
-        case NewChipID('U', 'K'):
-        case NewChipID('U', 'P'):
-        case NewChipID('U', 'Q'):
-        case NewChipID('U', 'R'):
-        case NewChipID('U', 'T'):
-        case NewChipID(']', 'W'):
-        /* those are m28, not 100% certain they are r423 could
-	   be r480 but not r430 as their pci id names indicate... */
-        case NewChipID(']', 'H'):
-        case NewChipID(']', 'I'):
-        case NewChipID(']', 'J'):
-	    return ATI_CHIP_R423;
-
-        case NewChipID('U', 'L'):
-        case NewChipID('U', 'M'):
-        case NewChipID('U', 'N'):
-        case NewChipID('U', 'O'):
-	    return ATI_CHIP_R430;
-
-        case NewChipID(']', 'L'):
-        case NewChipID(']', 'M'):
-        case NewChipID(']', 'N'):
-        case NewChipID(']', 'O'):
-        case NewChipID(']', 'P'):
-        case NewChipID(']', 'R'):
-	    return ATI_CHIP_R480;
-
-        case NewChipID('K', 'I'):
-        case NewChipID('K', 'J'):
-        case NewChipID('K', 'K'):
-        case NewChipID('K', 'L'):
-	    return ATI_CHIP_R481;
-
-        case NewChipID('^', 'H'):
-        case NewChipID('^', 'J'):
-        case NewChipID('^', 'K'):
-        case NewChipID('^', 'L'):
-        case NewChipID('^', 'M'):
-        case NewChipID('^', 'O'):
-        case NewChipID('V', 'J'):
-        case NewChipID('V', 'K'):
-        case NewChipID('V', 'O'):
-        case NewChipID('V', 'R'):
-        case NewChipID('V', 'S'):
-	    return ATI_CHIP_RV410;
-
-        case NewChipID('Z', 'A'):
-        case NewChipID('Z', 'B'):
-        case NewChipID('Z', 'a'):
-        case NewChipID('Z', 'b'):
-        case NewChipID('Y', 'T'):
-        case NewChipID('Y', 'U'):
-        case NewChipID('Y', 't'):
-        case NewChipID('Y', 'u'):
-	    return ATI_CHIP_RS400;
-
-        case NewChipID('H', 'D'):
-            return ATI_CHIP_HDTV;
+        case PCI_CHIP_MACH64GX:
+        case PCI_CHIP_MACH64CX:
+        case PCI_CHIP_MACH64CT:
+        case PCI_CHIP_MACH64ET:
+        case PCI_CHIP_MACH64VT:
+        case PCI_CHIP_MACH64GT:
+        case PCI_CHIP_MACH64VU:
+        case PCI_CHIP_MACH64GU:
+        case PCI_CHIP_MACH64LG:
+        case PCI_CHIP_MACH64VV:
+        case PCI_CHIP_MACH64GV:
+        case PCI_CHIP_MACH64GW:
+        case PCI_CHIP_MACH64GY:
+        case PCI_CHIP_MACH64GZ:
+        case PCI_CHIP_MACH64GB:
+        case PCI_CHIP_MACH64GD:
+        case PCI_CHIP_MACH64GI:
+        case PCI_CHIP_MACH64GP:
+        case PCI_CHIP_MACH64GQ:
+        case PCI_CHIP_MACH64LB:
+        case PCI_CHIP_MACH64LD:
+        case PCI_CHIP_MACH64LI:
+        case PCI_CHIP_MACH64LP:
+        case PCI_CHIP_MACH64LQ:
+        case PCI_CHIP_MACH64GL:
+        case PCI_CHIP_MACH64GM:
+        case PCI_CHIP_MACH64GN:
+        case PCI_CHIP_MACH64GO:
+        case PCI_CHIP_MACH64GR:
+        case PCI_CHIP_MACH64GS:
+        case PCI_CHIP_MACH64LM:
+        case PCI_CHIP_MACH64LN:
+        case PCI_CHIP_MACH64LR:
+        case PCI_CHIP_MACH64LS:
+            return ATI_CHIP_FAMILY_Mach64;
+
+        case PCI_CHIP_RAGE128RE:
+        case PCI_CHIP_RAGE128RF:
+        case PCI_CHIP_RAGE128RG:
+        case PCI_CHIP_RAGE128SK:
+        case PCI_CHIP_RAGE128SL:
+        case PCI_CHIP_RAGE128SM:
+        case PCI_CHIP_RAGE128SN:
+        case PCI_CHIP_RAGE128RK:
+        case PCI_CHIP_RAGE128RL:
+        case PCI_CHIP_RAGE128SE:
+        case PCI_CHIP_RAGE128SF:
+        case PCI_CHIP_RAGE128SG:
+        case PCI_CHIP_RAGE128SH:
+        case PCI_CHIP_RAGE128PA:
+        case PCI_CHIP_RAGE128PB:
+        case PCI_CHIP_RAGE128PC:
+        case PCI_CHIP_RAGE128PD:
+        case PCI_CHIP_RAGE128PE:
+        case PCI_CHIP_RAGE128PF:
+        case PCI_CHIP_RAGE128PG:
+        case PCI_CHIP_RAGE128PH:
+        case PCI_CHIP_RAGE128PI:
+        case PCI_CHIP_RAGE128PJ:
+        case PCI_CHIP_RAGE128PK:
+        case PCI_CHIP_RAGE128PL:
+        case PCI_CHIP_RAGE128PM:
+        case PCI_CHIP_RAGE128PN:
+        case PCI_CHIP_RAGE128PO:
+        case PCI_CHIP_RAGE128PP:
+        case PCI_CHIP_RAGE128PQ:
+        case PCI_CHIP_RAGE128PR:
+        case PCI_CHIP_RAGE128PS:
+        case PCI_CHIP_RAGE128PT:
+        case PCI_CHIP_RAGE128PU:
+        case PCI_CHIP_RAGE128PV:
+        case PCI_CHIP_RAGE128PW:
+        case PCI_CHIP_RAGE128PX:
+        case PCI_CHIP_RAGE128TF:
+        case PCI_CHIP_RAGE128TL:
+        case PCI_CHIP_RAGE128TR:
+        case PCI_CHIP_RAGE128TS:
+        case PCI_CHIP_RAGE128TT:
+        case PCI_CHIP_RAGE128TU:
+        case PCI_CHIP_RAGE128LE:
+        case PCI_CHIP_RAGE128LF:
+#if 0
+        case PCI_CHIP_RAGE128LK:
+        case PCI_CHIP_RAGE128LL:
+#endif
+        case PCI_CHIP_RAGE128MF:
+        case PCI_CHIP_RAGE128ML:
+            return ATI_CHIP_FAMILY_Rage128;
 
         default:
-            /*
-             * Treat anything else as an unknown Radeon.  Please keep the above
-             * up-to-date however, as it serves as a central chip list.
-             */
-            return ATI_CHIP_Radeon;
+            return ATI_CHIP_FAMILY_Radeon;
     }
 }
diff --git a/src/ati.h b/src/ati.h
index 48ab1cd..e86e50c 100644
--- a/src/ati.h
+++ b/src/ati.h
@@ -25,84 +25,14 @@
 
 #include <unistd.h>
 #include "xf86Pci.h"
-#include "atipciids.h"
+#include "xf86PciInfo.h"
 
 #include "xf86.h"
 
 #include "xf86_OSproc.h"
 
-extern DriverRec ATI;
-
-/*
- * Chip-related definitions.
- */
-typedef enum
-{
-    ATI_CHIP_NONE = 0,
-    ATI_CHIP_88800GXC,          /* Mach64 */
-    ATI_CHIP_88800GXD,          /* Mach64 */
-    ATI_CHIP_88800GXE,          /* Mach64 */
-    ATI_CHIP_88800GXF,          /* Mach64 */
-    ATI_CHIP_88800GX,           /* Mach64 */
-    ATI_CHIP_88800CX,           /* Mach64 */
-    ATI_CHIP_264CT,             /* Mach64 */
-    ATI_CHIP_264ET,             /* Mach64 */
-    ATI_CHIP_264VT,             /* Mach64 */
-    ATI_CHIP_264GT,             /* Mach64 */
-    ATI_CHIP_264VTB,            /* Mach64 */
-    ATI_CHIP_264GTB,            /* Mach64 */
-    ATI_CHIP_264VT3,            /* Mach64 */
-    ATI_CHIP_264GTDVD,          /* Mach64 */
-    ATI_CHIP_264LT,             /* Mach64 */
-    ATI_CHIP_264VT4,            /* Mach64 */
-    ATI_CHIP_264GT2C,           /* Mach64 */
-    ATI_CHIP_264GTPRO,          /* Mach64 */
-    ATI_CHIP_264LTPRO,          /* Mach64 */
-    ATI_CHIP_264XL,             /* Mach64 */
-    ATI_CHIP_MOBILITY,          /* Mach64 */
-    ATI_CHIP_Mach64,            /* Last among Mach64's */
-    ATI_CHIP_RAGE128GL,         /* Rage128 */
-    ATI_CHIP_RAGE128VR,         /* Rage128 */
-    ATI_CHIP_RAGE128PROGL,      /* Rage128 */
-    ATI_CHIP_RAGE128PROVR,      /* Rage128 */
-    ATI_CHIP_RAGE128PROULTRA,   /* Rage128 */
-    ATI_CHIP_RAGE128MOBILITY3,  /* Rage128 */
-    ATI_CHIP_RAGE128MOBILITY4,  /* Rage128 */
-    ATI_CHIP_Rage128,           /* Last among Rage128's */
-    ATI_CHIP_RADEON,            /* Radeon */
-    ATI_CHIP_RADEONVE,          /* Radeon VE */
-    ATI_CHIP_RADEONMOBILITY6,   /* Radeon M6 */
-    ATI_CHIP_RS100,             /* IGP320 */
-    ATI_CHIP_RS200,             /* IGP340 */
-    ATI_CHIP_RS250,             /* Radoen 7000 IGP */
-    ATI_CHIP_RV200,             /* RV200 */
-    ATI_CHIP_RADEONMOBILITY7,   /* Radeon M7 */
-    ATI_CHIP_R200,              /* R200 */
-    ATI_CHIP_RV250,             /* RV250 */
-    ATI_CHIP_RADEONMOBILITY9,   /* Radeon M9 */
-    ATI_CHIP_RS300,             /* Radoen 9100 IGP */
-    ATI_CHIP_RS350,             /* Radoen 9200 IGP */
-    ATI_CHIP_RV280,             /* RV250 */
-    ATI_CHIP_RADEONMOBILITY9PLUS,   /* Radeon M9+ */
-    ATI_CHIP_R300,              /* R300 */
-    ATI_CHIP_RV350,             /* RV350/M10/M11 */
-    ATI_CHIP_R350,              /* R350 */
-    ATI_CHIP_R360,              /* R360 */
-    ATI_CHIP_RV370,             /* RV370/M22 */
-    ATI_CHIP_RV380,             /* RV380/M24 */
-    ATI_CHIP_R420,              /* R420/M18 */
-    ATI_CHIP_R423,              /* R423/M28? */
-    ATI_CHIP_R430,              /* R430 */
-    ATI_CHIP_R480,              /* R480/M28? */
-    ATI_CHIP_R481,              /* R481 */
-    ATI_CHIP_RV410,             /* RV410, M26 */
-    ATI_CHIP_RS400,             /* RS400, RS410, RS480, RS482, ... */
-    ATI_CHIP_Radeon,            /* Last among Radeon's */
-    ATI_CHIP_HDTV               /* HDTV */
-} ATIChipType;
-
-extern const char *ATIChipNames[];
+extern void ati_check_subdriver_added();
 
-extern ATIChipType ATIChipID(const CARD16, const CARD8);
+extern DriverRec ATI;
 
 #endif /* ___ATI_H___ */
diff --git a/src/ati_pciids_gen.h b/src/ati_pciids_gen.h
index ad54f64..26d2f09 100644
--- a/src/ati_pciids_gen.h
+++ b/src/ati_pciids_gen.h
@@ -195,6 +195,7 @@
 #define PCI_CHIP_RV370_5B60 0x5B60
 #define PCI_CHIP_RV370_5B62 0x5B62
 #define PCI_CHIP_RV370_5B63 0x5B63
+#define PCI_CHIP_RV370_5657 0x5657
 #define PCI_CHIP_RV370_5B64 0x5B64
 #define PCI_CHIP_RV370_5B65 0x5B65
 #define PCI_CHIP_RV280_5C61 0x5C61
@@ -215,5 +216,137 @@
 #define PCI_CHIP_RV410_5E4C 0x5E4C
 #define PCI_CHIP_RV410_5E4D 0x5E4D
 #define PCI_CHIP_RV410_5E4F 0x5E4F
+#define PCI_CHIP_R520_7100 0x7100
+#define PCI_CHIP_R520_7101 0x7101
+#define PCI_CHIP_R520_7102 0x7102
+#define PCI_CHIP_R520_7103 0x7103
+#define PCI_CHIP_R520_7104 0x7104
+#define PCI_CHIP_R520_7105 0x7105
+#define PCI_CHIP_R520_7106 0x7106
+#define PCI_CHIP_R520_7108 0x7108
+#define PCI_CHIP_R520_7109 0x7109
+#define PCI_CHIP_R520_710A 0x710A
+#define PCI_CHIP_R520_710B 0x710B
+#define PCI_CHIP_R520_710C 0x710C
+#define PCI_CHIP_R520_710E 0x710E
+#define PCI_CHIP_R520_710F 0x710F
+#define PCI_CHIP_RV515_7140 0x7140
+#define PCI_CHIP_RV515_7141 0x7141
+#define PCI_CHIP_RV515_7142 0x7142
+#define PCI_CHIP_RV515_7143 0x7143
+#define PCI_CHIP_RV515_7144 0x7144
+#define PCI_CHIP_RV515_7145 0x7145
+#define PCI_CHIP_RV515_7146 0x7146
+#define PCI_CHIP_RV515_7147 0x7147
+#define PCI_CHIP_RV515_7149 0x7149
+#define PCI_CHIP_RV515_714A 0x714A
+#define PCI_CHIP_RV515_714B 0x714B
+#define PCI_CHIP_RV515_714C 0x714C
+#define PCI_CHIP_RV515_714D 0x714D
+#define PCI_CHIP_RV515_714E 0x714E
+#define PCI_CHIP_RV515_714F 0x714F
+#define PCI_CHIP_RV515_7151 0x7151
+#define PCI_CHIP_RV515_7152 0x7152
+#define PCI_CHIP_RV515_7153 0x7153
+#define PCI_CHIP_RV515_715E 0x715E
+#define PCI_CHIP_RV515_715F 0x715F
+#define PCI_CHIP_RV515_7180 0x7180
+#define PCI_CHIP_RV515_7181 0x7181
+#define PCI_CHIP_RV515_7183 0x7183
+#define PCI_CHIP_RV515_7186 0x7186
+#define PCI_CHIP_RV515_7187 0x7187
+#define PCI_CHIP_RV515_7188 0x7188
+#define PCI_CHIP_RV515_718A 0x718A
+#define PCI_CHIP_RV515_718B 0x718B
+#define PCI_CHIP_RV515_718C 0x718C
+#define PCI_CHIP_RV515_718D 0x718D
+#define PCI_CHIP_RV515_718F 0x718F
+#define PCI_CHIP_RV515_7193 0x7193
+#define PCI_CHIP_RV515_7196 0x7196
+#define PCI_CHIP_RV515_719B 0x719B
+#define PCI_CHIP_RV515_719F 0x719F
+#define PCI_CHIP_RV530_71C0 0x71C0
+#define PCI_CHIP_RV530_71C1 0x71C1
+#define PCI_CHIP_RV530_71C2 0x71C2
+#define PCI_CHIP_RV530_71C3 0x71C3
+#define PCI_CHIP_RV530_71C4 0x71C4
+#define PCI_CHIP_RV530_71C5 0x71C5
+#define PCI_CHIP_RV530_71C6 0x71C6
+#define PCI_CHIP_RV530_71C7 0x71C7
+#define PCI_CHIP_RV530_71CD 0x71CD
+#define PCI_CHIP_RV530_71CE 0x71CE
+#define PCI_CHIP_RV530_71D2 0x71D2
+#define PCI_CHIP_RV530_71D4 0x71D4
+#define PCI_CHIP_RV530_71D5 0x71D5
+#define PCI_CHIP_RV530_71D6 0x71D6
+#define PCI_CHIP_RV530_71DA 0x71DA
+#define PCI_CHIP_RV530_71DE 0x71DE
+#define PCI_CHIP_RV530_7200 0x7200
+#define PCI_CHIP_RV530_7210 0x7210
+#define PCI_CHIP_RV530_7211 0x7211
+#define PCI_CHIP_R580_7240 0x7240
+#define PCI_CHIP_R580_7243 0x7243
+#define PCI_CHIP_R580_7244 0x7244
+#define PCI_CHIP_R580_7245 0x7245
+#define PCI_CHIP_R580_7246 0x7246
+#define PCI_CHIP_R580_7247 0x7247
+#define PCI_CHIP_R580_7248 0x7248
+#define PCI_CHIP_R580_7249 0x7249
+#define PCI_CHIP_R580_724A 0x724A
+#define PCI_CHIP_R580_724B 0x724B
+#define PCI_CHIP_R580_724C 0x724C
+#define PCI_CHIP_R580_724D 0x724D
+#define PCI_CHIP_R580_724E 0x724E
+#define PCI_CHIP_R580_724F 0x724F
+#define PCI_CHIP_RV570_7280 0x7280
+#define PCI_CHIP_RV560_7281 0x7281
+#define PCI_CHIP_RV560_7283 0x7283
+#define PCI_CHIP_R580_7284 0x7284
+#define PCI_CHIP_RV560_7287 0x7287
+#define PCI_CHIP_RV570_7288 0x7288
+#define PCI_CHIP_RV570_7289 0x7289
+#define PCI_CHIP_RV570_728B 0x728B
+#define PCI_CHIP_RV570_728C 0x728C
+#define PCI_CHIP_RV560_7290 0x7290
+#define PCI_CHIP_RV560_7291 0x7291
+#define PCI_CHIP_RV560_7293 0x7293
+#define PCI_CHIP_RV560_7297 0x7297
 #define PCI_CHIP_RS350_7834 0x7834
 #define PCI_CHIP_RS350_7835 0x7835
+#define PCI_CHIP_RS690_791E 0x791E
+#define PCI_CHIP_RS690_791F 0x791F
+#define PCI_CHIP_RS740_796C 0x796C
+#define PCI_CHIP_RS740_796D 0x796D
+#define PCI_CHIP_RS740_796E 0x796E
+#define PCI_CHIP_RS740_796F 0x796F
+#define PCI_CHIP_R600_9400 0x9400
+#define PCI_CHIP_R600_9401 0x9401
+#define PCI_CHIP_R600_9402 0x9402
+#define PCI_CHIP_R600_9403 0x9403
+#define PCI_CHIP_R600_9405 0x9405
+#define PCI_CHIP_R600_940A 0x940A
+#define PCI_CHIP_R600_940B 0x940B
+#define PCI_CHIP_R600_940F 0x940F
+#define PCI_CHIP_RV610_94C0 0x94C0
+#define PCI_CHIP_RV610_94C1 0x94C1
+#define PCI_CHIP_RV610_94C3 0x94C3
+#define PCI_CHIP_RV610_94C4 0x94C4
+#define PCI_CHIP_RV610_94C5 0x94C5
+#define PCI_CHIP_RV610_94C6 0x94C6
+#define PCI_CHIP_RV610_94C7 0x94C7
+#define PCI_CHIP_RV610_94C8 0x94C8
+#define PCI_CHIP_RV610_94C9 0x94C9
+#define PCI_CHIP_RV610_94CB 0x94CB
+#define PCI_CHIP_RV610_94CC 0x94CC
+#define PCI_CHIP_RV630_9580 0x9580
+#define PCI_CHIP_RV630_9581 0x9581
+#define PCI_CHIP_RV630_9583 0x9583
+#define PCI_CHIP_RV630_9586 0x9586
+#define PCI_CHIP_RV630_9587 0x9587
+#define PCI_CHIP_RV630_9588 0x9588
+#define PCI_CHIP_RV630_9589 0x9589
+#define PCI_CHIP_RV630_958A 0x958A
+#define PCI_CHIP_RV630_958B 0x958B
+#define PCI_CHIP_RV630_958C 0x958C
+#define PCI_CHIP_RV630_958D 0x958D
+#define PCI_CHIP_RV630_958E 0x958E
diff --git a/src/atibus.c b/src/atibus.c
index 32f02b6..69a3089 100644
--- a/src/atibus.c
+++ b/src/atibus.c
@@ -31,7 +31,6 @@
 #include "atichip.h"
 #include "atimach64io.h"
 #include "atistruct.h"
-#include "ativersion.h"
 
 /*
  * Definitions related to an adapter's system bus interface.
diff --git a/src/atichip.c b/src/atichip.c
index 5f8a221..aac00e6 100644
--- a/src/atichip.c
+++ b/src/atichip.c
@@ -28,7 +28,7 @@
 #include "atibus.h"
 #include "atichip.h"
 #include "atimach64io.h"
-#include "ativersion.h"
+#include "atimach64version.h"
 
 const char *ATIFoundryNames[] =
     { "SGS", "NEC", "KCS", "UMC", "TSMC", "5", "6", "UMC" };
@@ -114,7 +114,7 @@ ATIMach64ChipID
                     pATI->Chip = ATI_CHIP_264GT;
                 else
                     xf86Msg(X_WARNING,
-                            ATI_NAME ":  Mach64 chip type probe discrepancy"
+                            MACH64_NAME ":  Mach64 chip type probe discrepancy"
                             " detected:  PCI=0x%04X;  CHIP_ID=0x%04X.\n",
                             ExpectedChipType, pATI->ChipType);
             }
diff --git a/src/atichip.h b/src/atichip.h
index 44cd188..e59d6eb 100644
--- a/src/atichip.h
+++ b/src/atichip.h
@@ -29,6 +29,36 @@
 #include <X11/Xmd.h>
 
 /*
+ * Chip-related definitions.
+ */
+typedef enum
+{
+    ATI_CHIP_NONE = 0,
+    ATI_CHIP_88800GXC,          /* Mach64 */
+    ATI_CHIP_88800GXD,          /* Mach64 */
+    ATI_CHIP_88800GXE,          /* Mach64 */
+    ATI_CHIP_88800GXF,          /* Mach64 */
+    ATI_CHIP_88800GX,           /* Mach64 */
+    ATI_CHIP_88800CX,           /* Mach64 */
+    ATI_CHIP_264CT,             /* Mach64 */
+    ATI_CHIP_264ET,             /* Mach64 */
+    ATI_CHIP_264VT,             /* Mach64 */
+    ATI_CHIP_264GT,             /* Mach64 */
+    ATI_CHIP_264VTB,            /* Mach64 */
+    ATI_CHIP_264GTB,            /* Mach64 */
+    ATI_CHIP_264VT3,            /* Mach64 */
+    ATI_CHIP_264GTDVD,          /* Mach64 */
+    ATI_CHIP_264LT,             /* Mach64 */
+    ATI_CHIP_264VT4,            /* Mach64 */
+    ATI_CHIP_264GT2C,           /* Mach64 */
+    ATI_CHIP_264GTPRO,          /* Mach64 */
+    ATI_CHIP_264LTPRO,          /* Mach64 */
+    ATI_CHIP_264XL,             /* Mach64 */
+    ATI_CHIP_MOBILITY,          /* Mach64 */
+    ATI_CHIP_Mach64,            /* Last among Mach64's */
+} ATIChipType;
+
+/*
  * Foundry codes for 264xT's.
  */
 typedef enum
diff --git a/src/aticlock.c b/src/aticlock.c
index 2aa65c4..8dd79d4 100644
--- a/src/aticlock.c
+++ b/src/aticlock.c
@@ -139,6 +139,16 @@ ATIClockPreInit
                     (double)pATI->ReferenceNumerator /
                         ((double)pATI->ReferenceDenominator * 1000.0));
 
+#if defined(__sparc__)
+            if (pATI->ReferenceNumerator != 315000 &&
+                pATI->ReferenceDenominator != 11)
+            {
+                xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+                    "If modes do not work on Ultra 5/10 or Blade 100/150,\n"
+                    "set option \"reference_clock\" to \"28.636 MHz\"\n");
+            }
+#endif
+
             if (pATI->ProgrammableClock == ATI_CLOCK_CH8398)
             {   /* First two are fixed */
                 pScreenInfo->numClocks = 2;
diff --git a/src/aticonsole.c b/src/aticonsole.c
index bd5ec9c..8efe897 100644
--- a/src/aticonsole.c
+++ b/src/aticonsole.c
@@ -51,11 +51,6 @@
 #include "atioption.h"
 #include "vbe.h"
 
-static const char *vbeSymbols[] = {
-    "VBEGetVBEMode",
-    NULL
-};
-
 #endif /* TV_OUT */
 
 /*
@@ -131,8 +126,6 @@ ATIProbeAndSetActiveDisplays
     int disp_request;
     ATITVStandard tv_std, tv_std_request;
 
-    xf86LoaderRefSymLists(vbeSymbols, NULL);
-
     if (xf86GetVerbosity() > 3) {
 	xf86ErrorFVerb(4, "\n Before TV-Out queries\n\n");
 	ATIPrintRegisters(pATI);
@@ -539,8 +532,6 @@ ATIEnterGraphics
 #ifdef TV_OUT
     if (pATI->OptionTvOut) {
 
-	xf86LoaderRefSymLists(vbeSymbols, NULL);
-
 	if (pATI->pVBE) {
 	    if (VBEGetVBEMode(pATI->pVBE, &pATI->vbemode)) {
 		xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Saving VESA mode: 0x%x\n", 
@@ -658,6 +649,12 @@ ATISwitchMode
 
 #endif /* XF86DRI_DEVEL */
 
+        /* XXX Workaround for X server not hiding the cursor for Xcursor (but
+         * only for core cursor), leaving a 64x64 garbage upper-left.
+         */
+        if (pATI->pCursorInfo)
+            (*pATI->pCursorInfo->HideCursor)(pScreenInfo);
+
         ATIModeSet(pScreenInfo, pATI, &pATI->NewHW);
 
 #ifdef XF86DRI_DEVEL
diff --git a/src/atidri.c b/src/atidri.c
index 0da1bc5..15d0014 100644
--- a/src/atidri.c
+++ b/src/atidri.c
@@ -41,9 +41,9 @@
 #include "atidri.h"
 #include "atiregs.h"
 #include "atistruct.h"
-#include "ativersion.h"
 
 #include "atimach64io.h"
+#include "atimach64version.h"
 #include "mach64_dri.h"
 #include "mach64_common.h"
 #include "mach64_sarea.h"
@@ -1244,9 +1244,9 @@ Bool ATIDRIScreenInit( ScreenPtr pScreen )
 	       PCI_DEV_DEV(pATI->PCIInfo),
 	       PCI_DEV_FUNC(pATI->PCIInfo) );
    }
-   pDRIInfo->ddxDriverMajorVersion = ATI_VERSION_MAJOR;
-   pDRIInfo->ddxDriverMinorVersion = ATI_VERSION_MINOR;
-   pDRIInfo->ddxDriverPatchVersion = ATI_VERSION_PATCH;
+   pDRIInfo->ddxDriverMajorVersion = MACH64_VERSION_MAJOR;
+   pDRIInfo->ddxDriverMinorVersion = MACH64_VERSION_MINOR;
+   pDRIInfo->ddxDriverPatchVersion = MACH64_VERSION_PATCH;
    pDRIInfo->frameBufferPhysicalAddress = (void *)pATI->LinearBase;
    pDRIInfo->frameBufferSize = pATI->LinearSize;
    pDRIInfo->frameBufferStride = (pScreenInfo->displayWidth *
diff --git a/src/atii2c.c b/src/atii2c.c
index 73febf7..a13d647 100644
--- a/src/atii2c.c
+++ b/src/atii2c.c
@@ -25,7 +25,6 @@
 #endif
 
 #include "atii2c.h"
-#include "atiload.h"
 #include "atimach64i2c.h"
 #include "atistruct.h"
 
@@ -365,7 +364,7 @@ ATII2CPreInit
     ATIPtr      pATI
 )
 {
-            if (!ATILoadModule(pScreenInfo, "i2c", ATIi2cSymbols))
+            if (!xf86LoadSubModule(pScreenInfo, "i2c"))
                 return;
 
             ATIMach64I2CPreInit(pScreenInfo, pATI);
diff --git a/src/atiload.c b/src/atiload.c
index 0001ced..621b0b0 100644
--- a/src/atiload.c
+++ b/src/atiload.c
@@ -18,179 +18,18 @@
  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
- *
- * DRI support by:
- *    Leif Delgass <ldelgass@retinalburn.net>
  */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#ifdef XFree86LOADER
-
 #include "ati.h"
 #include "aticursor.h"
 #include "atiload.h"
 #include "atistruct.h"
 
 /*
- * All symbol lists belong here.  They are externalised so that they can be
- * referenced elsewhere.  Note the naming convention for these things...
- */
-
-const char *ATIint10Symbols[] =
-{
-    "xf86FreeInt10",
-    "xf86InitInt10",
-    "xf86int10Addr",
-    NULL
-};
-
-const char *ATIddcSymbols[] =
-{
-    "xf86PrintEDID",
-    "xf86SetDDCproperties",
-    NULL
-};
-
-const char *ATIvbeSymbols[] =
-{
-    "VBEInit",
-    "vbeDoEDID",
-    "vbeFree",
-    NULL
-};
-
-#ifdef XF86DRI_DEVEL
-
-const char *ATIdrmSymbols[] = {
-    "drmAddBufs",
-    "drmAddMap",
-    "drmAgpAcquire",
-    "drmAgpAlloc",
-    "drmAgpBase",
-    "drmAgpBind",
-    "drmAgpDeviceId",
-    "drmAgpEnable",
-    "drmAgpFree",
-    "drmAgpGetMode",
-    "drmAgpRelease",
-    "drmAgpUnbind",
-    "drmAgpVendorId",
-    "drmAvailable",
-    "drmCommandNone",
-    "drmCommandRead",
-    "drmCommandWrite",
-    "drmCommandWriteRead",
-    "drmCtlInstHandler",
-    "drmCtlUninstHandler",
-    "drmFreeVersion",
-    "drmGetInterruptFromBusID",
-    "drmGetLibVersion",
-    "drmGetVersion",
-    "drmMap",
-    "drmMapBufs",
-    "drmDMA",
-    "drmUnmap",
-    "drmUnmapBufs",
-    NULL
-};
-
-const char *ATIdriSymbols[] = {
-    "DRICloseScreen",
-    "DRICreateInfoRec",
-    "DRIDestroyInfoRec",
-    "DRIFinishScreenInit",
-    "DRIGetSAREAPrivate",
-    "DRILock",
-    "DRIQueryVersion",
-    "DRIScreenInit",
-    "DRIUnlock",
-    "GlxSetVisualConfigs",
-    "DRICreatePCIBusID",
-    NULL
-};
-
-#endif /* XF86DRI_DEVEL */
-
-const char *ATIfbSymbols[] =
-{
-    "fbPictureInit",
-    "fbScreenInit",
-    NULL
-};
-
-const char *ATIshadowfbSymbols[] =
-{
-    "ShadowFBInit",
-    NULL
-};
-
-#ifdef USE_EXA
-const char *ATIexaSymbols[] =
-{
-    "exaDriverAlloc",
-    "exaDriverInit",
-    "exaDriverFini",
-    "exaOffscreenAlloc",
-    "exaOffscreenFree",
-    NULL
-};
-#endif
-
-#ifdef USE_XAA
-const char *ATIxaaSymbols[] =
-{
-    "XAACreateInfoRec",
-    "XAADestroyInfoRec",
-    "XAAInit",
-    NULL
-};
-#endif
-
-const char *ATIramdacSymbols[] =
-{
-    "xf86CreateCursorInfoRec",
-    "xf86DestroyCursorInfoRec",
-    "xf86InitCursor",
-    NULL
-};
-
-const char *ATIi2cSymbols[] =
-{
-    "xf86CreateI2CBusRec",
-    "xf86DestroyI2CBusRec",
-    "xf86I2CBusInit",
-    "xf86I2CDevInit",
-    "xf86I2CFindDev",
-    "xf86I2CGetScreenBuses",
-    NULL
-};
-
-/*
- * ATILoadModule --
- *
- * Load a specific module and register with the loader those of its entry
- * points that are referenced by this driver.
- */
-pointer
-ATILoadModule
-(
-    ScrnInfoPtr  pScreenInfo,
-    const char  *Module,
-    const char **SymbolList
-)
-{
-    pointer pModule = xf86LoadSubModule(pScreenInfo, Module);
-
-    if (pModule)
-        xf86LoaderReqSymLists(SymbolList, NULL);
-
-    return pModule;
-}
-
-/*
  * ATILoadModules --
  *
  * This function loads other modules required for a screen.
@@ -206,7 +45,7 @@ ATILoadModules
 
     /* Load shadow frame buffer code if needed */
     if (pATI->OptionShadowFB &&
-        !ATILoadModule(pScreenInfo, "shadowfb", ATIshadowfbSymbols))
+        !xf86LoadSubModule(pScreenInfo, "shadowfb"))
         return NULL;
 
     /* Load depth-specific entry points */
@@ -216,7 +55,7 @@ ATILoadModules
         case 16:
         case 24:
         case 32:
-            fbPtr = ATILoadModule(pScreenInfo, "fb", ATIfbSymbols);
+            fbPtr = xf86LoadSubModule(pScreenInfo, "fb");
             break;
 
         default:
@@ -227,14 +66,13 @@ ATILoadModules
 
     /* Load ramdac module if needed */
     if ((pATI->Cursor > ATI_CURSOR_SOFTWARE) &&
-        !ATILoadModule(pScreenInfo, "ramdac", ATIramdacSymbols))
+        !xf86LoadSubModule(pScreenInfo, "ramdac"))
         return NULL;
 
 #ifdef USE_EXA
     /* Load EXA if needed */
     if (pATI->useEXA && pATI->OptionAccel)
     {
-        /* Cannot use ATILoadModule(), because of version checking */
         XF86ModReqInfo req;
         int errmaj, errmin;
 
@@ -247,17 +85,14 @@ ATILoadModules
             LoaderErrorMsg(NULL, "exa", errmaj, errmin);
             return NULL;
         }
-        xf86LoaderReqSymLists(ATIexaSymbols, NULL);
     }
 #endif
 #ifdef USE_XAA
     /* Load XAA if needed */
     if (!pATI->useEXA && pATI->OptionAccel &&
-        !ATILoadModule(pScreenInfo, "xaa", ATIxaaSymbols))
+        !xf86LoadSubModule(pScreenInfo, "xaa"))
         return NULL;
 #endif
 
     return fbPtr;
 }
-
-#endif /* XFree86LOADER */
diff --git a/src/atiload.h b/src/atiload.h
index ebccd75..168224c 100644
--- a/src/atiload.h
+++ b/src/atiload.h
@@ -18,52 +18,15 @@
  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
- *
- * DRI support by:
- *    Leif Delgass <ldelgass@retinalburn.net>
  */
 
 #ifndef ___ATILOAD_H___
 #define ___ATILOAD_H___ 1
 
-#ifdef XFree86LOADER
-
 #include "atipriv.h"
 
 #include "xf86str.h"
 
-extern const char *ATIint10Symbols[], *ATIddcSymbols[], *ATIvbeSymbols[],
-
-#ifdef XF86DRI_DEVEL
- 
-                  *ATIdrmSymbols[], *ATIdriSymbols[],
- 
-#endif /* XF86DRI_DEVEL */
-
-                  *ATIfbSymbols[], *ATIshadowfbSymbols[],
-
-#ifdef USE_EXA
- 
-                  *ATIexaSymbols[],
-
-#endif /* USE_EXA */
-
-#ifdef USE_XAA
- 
-                  *ATIxaaSymbols[],
-
-#endif /* USE_XAA */
-
-                  *ATIramdacSymbols[], *ATIi2cSymbols[];
-
-extern pointer ATILoadModule(ScrnInfoPtr, const char *, const char **);
 extern pointer ATILoadModules(ScrnInfoPtr, ATIPtr);
 
-#else /* XFree86LOADER */
-
-#define ATILoadModule(pScreenInfo, Module, SymboList) ((pointer)1)
-#define ATILoadModules(pScreenInfo, pATI)             ((pointer)1)
-
-#endif /* XFree86LOADER */
-
 #endif /* ___ATILOAD_H___ */
diff --git a/src/atimach64probe.c b/src/atimach64probe.c
index 2f716a1..ffab153 100644
--- a/src/atimach64probe.c
+++ b/src/atimach64probe.c
@@ -28,6 +28,7 @@
 #include "atichip.h"
 #include "atimach64io.h"
 #include "atimach64probe.h"
+#include "atimach64version.h"
 #include "atioption.h"
 #include "ativersion.h"
 
@@ -106,11 +107,11 @@ Mach64PciChipsets[] = {
     {-1, -1, RES_UNDEFINED}
 };
 
-_X_EXPORT const OptionInfoRec *
+static const OptionInfoRec *
 Mach64AvailableOptions(int chipid, int busid)
 {
     /*
-     * Return options defined in the atimisc submodule which will have been
+     * Return options defined in the mach64 submodule which will have been
      * loaded by this point.
      */
     return ATIOptionsWeak();
@@ -121,13 +122,13 @@ Mach64AvailableOptions(int chipid, int busid)
  *
  * Print the driver's list of chipset names.
  */
-_X_EXPORT void
+static void
 Mach64Identify
 (
     int flags
 )
 {
-    xf86Msg(X_INFO, "%s: %s\n", ATI_NAME,
+    xf86Msg(X_INFO, "%s: %s\n", MACH64_NAME,
             "Driver for ATI Mach64 chipsets");
 }
 
@@ -137,12 +138,12 @@ Mach64Identify
  * This function is called once, at the start of the first server generation to
  * do a minimal probe for supported hardware.
  */
-_X_EXPORT Bool
+static Bool
 Mach64Probe(DriverPtr pDriver, int flags)
 {
-    GDevPtr *devSections;
+    GDevPtr *devSections, *ATIGDevs, *Mach64GDevs;
     int     *usedChips;
-    int     numDevSections;
+    int     numDevSections, nATIGDev, nMach64GDev;
     int     numUsed;
     Bool    ProbeSuccess = FALSE;
 
@@ -151,10 +152,32 @@ Mach64Probe(DriverPtr pDriver, int flags)
         return FALSE;
 #endif
 
-    if ((numDevSections = xf86MatchDevice(ATI_DRIVER_NAME, &devSections)) <= 0)
+    /* Collect unclaimed device sections for both driver names */
+    nATIGDev = xf86MatchDevice(ATI_DRIVER_NAME, &ATIGDevs);
+    nMach64GDev = xf86MatchDevice(MACH64_DRIVER_NAME, &Mach64GDevs);
+
+    if ((numDevSections = nATIGDev + nMach64GDev) <= 0)
         return FALSE;
 
-    numUsed = xf86MatchPciInstances(ATI_DRIVER_NAME, PCI_VENDOR_ATI,
+    if (ATIGDevs == NULL) {
+        devSections = Mach64GDevs;
+        numDevSections = nMach64GDev;
+    } else if (Mach64GDevs == NULL) {
+        devSections = ATIGDevs;
+        numDevSections = nATIGDev;
+    } else {
+        /* Combine into one list */
+        devSections = xnfalloc((numDevSections + 1) * sizeof(GDevPtr));
+        (void)memcpy(devSections,
+                     ATIGDevs, nATIGDev * sizeof(GDevPtr));
+        (void)memcpy(devSections + nATIGDev,
+                     Mach64GDevs, nMach64GDev * sizeof(GDevPtr));
+        devSections[numDevSections] = NULL;
+        xfree(ATIGDevs);
+        xfree(Mach64GDevs);
+    }
+
+    numUsed = xf86MatchPciInstances(MACH64_NAME, PCI_VENDOR_ATI,
                                     Mach64Chipsets, Mach64PciChipsets,
                                     devSections, numDevSections,
                                     pDriver, &usedChips);
@@ -177,9 +200,9 @@ Mach64Probe(DriverPtr pDriver, int flags)
             if (!pScrn)
                 continue;
 
-            pScrn->driverVersion = ATI_VERSION_CURRENT;
-            pScrn->driverName    = ATI_DRIVER_NAME;
-            pScrn->name          = ATI_NAME;
+            pScrn->driverVersion = MACH64_VERSION_CURRENT;
+            pScrn->driverName    = MACH64_DRIVER_NAME;
+            pScrn->name          = MACH64_NAME;
             pScrn->Probe         = Mach64Probe;
             pScrn->PreInit       = ATIPreInit;
             pScrn->ScreenInit    = ATIScreenInit;
@@ -198,3 +221,14 @@ Mach64Probe(DriverPtr pDriver, int flags)
 
     return ProbeSuccess;
 }
+
+_X_EXPORT DriverRec MACH64 =
+{
+    MACH64_VERSION_CURRENT,
+    MACH64_DRIVER_NAME,
+    Mach64Identify,
+    Mach64Probe,
+    Mach64AvailableOptions,
+    NULL,
+    0
+};
diff --git a/src/atimach64probe.h b/src/atimach64probe.h
index 65ced98..7b0b4b6 100644
--- a/src/atimach64probe.h
+++ b/src/atimach64probe.h
@@ -25,10 +25,8 @@
 
 #include "xf86str.h"
 
-extern SymTabRec             Mach64Chipsets[];
+extern DriverRec MACH64;
 
-extern const OptionInfoRec * Mach64AvailableOptions(int, int);
-extern void                  Mach64Identify(int);
-extern Bool                  Mach64Probe(DriverPtr, int);
+extern SymTabRec Mach64Chipsets[];
 
 #endif /* ___ATIMACH64PROBE_H___ */
diff --git a/src/atimach64version.h b/src/atimach64version.h
new file mode 100644
index 0000000..c1848bd
--- /dev/null
+++ b/src/atimach64version.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MACH64_VERSION_H_
+#define _MACH64_VERSION_H_ 1
+
+#undef  MACH64_NAME
+#undef  MACH64_DRIVER_NAME
+#undef  MACH64_VERSION_MAJOR
+#undef  MACH64_VERSION_MINOR
+#undef  MACH64_VERSION_PATCH
+#undef  MACH64_VERSION_CURRENT
+#undef  MACH64_VERSION_EVALUATE
+#undef  MACH64_VERSION_STRINGIFY
+#undef  MACH64_VERSION_NAME
+
+#define MACH64_NAME          "MACH64"
+#define MACH64_DRIVER_NAME   "mach64"
+
+#define MACH64_VERSION_MAJOR 6
+#define MACH64_VERSION_MINOR 7
+#define MACH64_VERSION_PATCH 0
+
+#ifndef MACH64_VERSION_EXTRA
+#define MACH64_VERSION_EXTRA ""
+#endif
+
+#define MACH64_VERSION_CURRENT \
+    ((MACH64_VERSION_MAJOR << 20) | \
+     (MACH64_VERSION_MINOR << 10) | \
+     (MACH64_VERSION_PATCH))
+
+#define MACH64_VERSION_EVALUATE(__x) #__x
+#define MACH64_VERSION_STRINGIFY(_x) MACH64_VERSION_EVALUATE(_x)
+#define MACH64_VERSION_NAME                                             \
+    MACH64_VERSION_STRINGIFY(MACH64_VERSION_MAJOR) "."                  \
+    MACH64_VERSION_STRINGIFY(MACH64_VERSION_MINOR) "."                  \
+    MACH64_VERSION_STRINGIFY(MACH64_VERSION_MINOR) MACH64_VERSION_EXTRA
+
+#endif /* _MACH64_VERSION_H_ */
diff --git a/src/atimach64xv.c b/src/atimach64xv.c
index 67becec..ef17861 100644
--- a/src/atimach64xv.c
+++ b/src/atimach64xv.c
@@ -1385,7 +1385,7 @@ ATIMach64XVInitialiseAdaptor
     else if (pATI->Chip < ATI_CHIP_264GTPRO ||
              pATI->Chip > ATI_CHIP_264LTPRO)
     {
-        /* Do nothing */
+        enc->width = 720; /* default */
     }
     else
     {
@@ -1441,7 +1441,8 @@ ATIMach64XVInitialiseAdaptor
     else if (pATI->Chip < ATI_CHIP_264GTPRO ||
              pATI->Chip > ATI_CHIP_264LTPRO)
     {
-        /* Do nothing */
+        surf0->max_width = 720; /* default */
+        surf1->max_width = 720;
     }
     else
     {
diff --git a/src/atimisc.c b/src/atimisc.c
index e6012ec..cf2347a 100644
--- a/src/atimisc.c
+++ b/src/atimisc.c
@@ -18,31 +18,28 @@
  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
- *
- * DRI support by:
- *    Leif Delgass <ldelgass@retinalburn.net>
  */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#ifdef XFree86LOADER
-
 #include "ati.h"
-#include "atiload.h"
 #include "ativersion.h"
 
+#include "atimach64probe.h"
+#include "atimach64version.h"
+
 /* Module loader interface for subsidiary driver module */
 
 static XF86ModuleVersionInfo ATIVersionRec =
 {
-    "atimisc",
+    "mach64",
     MODULEVENDORSTRING,
     MODINFOSTRING1,
     MODINFOSTRING2,
     XORG_VERSION_CURRENT,
-    ATI_VERSION_MAJOR, ATI_VERSION_MINOR, ATI_VERSION_PATCH,
+    MACH64_VERSION_MAJOR, MACH64_VERSION_MINOR, MACH64_VERSION_PATCH,
     ABI_CLASS_VIDEODRV,
     ABI_VIDEODRV_VERSION,
     MOD_CLASS_VIDEODRV,
@@ -67,74 +64,8 @@ ATISetup
 
     if (!Inited)
     {
-        /* Ensure main driver module is loaded, but not as a submodule */
-        if (!xf86ServerIsOnlyDetecting())
-        {
-            if (!LoaderSymbol(ATI_NAME))
-                xf86LoadOneModule(ATI_DRIVER_NAME, Options);
-
-            /* ati & atimisc module versions must match */
-            do
-            {
-                XF86ModuleData *pModuleData = LoaderSymbol("atiModuleData");
-
-                if (pModuleData)
-                {
-                    XF86ModuleVersionInfo *pModuleInfo = pModuleData->vers;
-
-                    if ((pModuleInfo->majorversion == ATI_VERSION_MAJOR) &&
-                        (pModuleInfo->minorversion == ATI_VERSION_MINOR) &&
-                        (pModuleInfo->patchlevel == ATI_VERSION_PATCH))
-                        break;
-                }
-
-                xf86Msg(X_ERROR,
-                        "\"ati\" and \"atimisc\" module versions must"
-                        " match.\n");
-
-                if (ErrorMajor)
-                    *ErrorMajor = (int)LDR_MISMATCH;
-                if (ErrorMinor)
-                    *ErrorMinor = (int)LDR_MISMATCH;
-
-                return NULL;
-            } while (0);
-        }
-
-        /*
-         * Tell loader about symbols from other modules that this module might
-         * refer to.
-         */
-        xf86LoaderRefSymLists(
-            ATIint10Symbols,
-            ATIddcSymbols,
-            ATIvbeSymbols,
-
-#ifdef XF86DRI_DEVEL
-
-            ATIdrmSymbols,
-            ATIdriSymbols,
-
-#endif /* XF86DRI_DEVEL */
-
-            ATIfbSymbols,
-            ATIshadowfbSymbols,
-
-#ifdef USE_EXA
-
-            ATIexaSymbols,
-
-#endif /* USE_EXA */
-
-#ifdef USE_XAA
-
-            ATIxaaSymbols,
-
-#endif /* USE_XAA */
-
-            ATIramdacSymbols,
-            ATIi2cSymbols,
-            NULL);
+        if (xf86ServerIsOnlyDetecting() || !LoaderSymbol(ATI_NAME))
+            xf86AddDriver(&MACH64, Module, 0);
 
         Inited = TRUE;
     }
@@ -142,12 +73,10 @@ ATISetup
     return (pointer)TRUE;
 }
 
-/* The following record must be called atimiscModuleData */
-_X_EXPORT XF86ModuleData atimiscModuleData =
+/* The following record must be called mach64ModuleData */
+_X_EXPORT XF86ModuleData mach64ModuleData =
 {
     &ATIVersionRec,
     ATISetup,
     NULL
 };
-
-#endif /* XFree86LOADER */
diff --git a/src/atimode.c b/src/atimode.c
index 68c1342..d1b3198 100644
--- a/src/atimode.c
+++ b/src/atimode.c
@@ -43,12 +43,6 @@
 
 #include "vbe.h"
 
-static const char *vbeSymbols[] = {
-    "VBESetVBEMode",
-    "vbeFree",
-    NULL
-};
-
 #endif /* TV_OUT */
 
 #ifndef AVOID_CPIO
@@ -733,9 +727,6 @@ ATISetVBEMode
     ATIHWPtr    pATIHW
 )
 {
-
-    xf86LoaderRefSymLists(vbeSymbols, NULL);
-
     if (pATIHW->crtc == ATI_CRTC_MACH64) {
 	int vbemode, modekey;
 
diff --git a/src/atimodule.c b/src/atimodule.c
index 6aa9a2e..802c35a 100644
--- a/src/atimodule.c
+++ b/src/atimodule.c
@@ -24,38 +24,11 @@
 #include "config.h"
 #endif
 
-#ifdef XFree86LOADER
-
 #include "ati.h"
-#include "atimodule.h"
 #include "ativersion.h"
 
 /* Module loader interface */
 
-const char *ATISymbols[] =
-{
-    "Mach64Identify",
-    "Mach64Probe",
-    "Mach64AvailableOptions",
-    NULL
-};
-
-const char *R128Symbols[] =
-{
-    "R128Identify",
-    "R128Probe",
-    "R128AvailableOptions",
-    NULL
-};
-
-const char *RADEONSymbols[] =
-{
-    "RADEONIdentify",
-    "RADEONProbe",
-    "RADEONAvailableOptions",
-    NULL
-};
-
 static XF86ModuleVersionInfo ATIVersionRec =
 {
     ATI_DRIVER_NAME,
@@ -91,11 +64,7 @@ ATISetup
         Inited = TRUE;
         xf86AddDriver(&ATI, Module, 0);
 
-        xf86LoaderRefSymLists(
-            ATISymbols,
-            R128Symbols,
-            RADEONSymbols,
-            NULL);
+        ati_check_subdriver_added();
     }
 
     return (pointer)1;
@@ -108,5 +77,3 @@ _X_EXPORT XF86ModuleData atiModuleData =
     ATISetup,
     NULL
 };
-
-#endif /* XFree86LOADER */
diff --git a/src/atimodule.h b/src/atimodule.h
deleted file mode 100644
index d33b01d..0000000
--- a/src/atimodule.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 1997 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of Marc Aurele La France not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  Marc Aurele La France makes no representations
- * about the suitability of this software for any purpose.  It is provided
- * "as-is" without express or implied warranty.
- *
- * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO
- * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#if defined(XFree86LOADER) && !defined(___ATIMODULE_H___)
-#define ___ATIMODULE_H___ 1
-
-extern const char *ATISymbols[];
-extern const char *R128Symbols[];
-extern const char *RADEONSymbols[];
-
-#endif /* ___ATIMODULE_H___ */
diff --git a/src/atipciids.h b/src/atipciids.h
index f24f8fb..2953964 100644
--- a/src/atipciids.h
+++ b/src/atipciids.h
@@ -40,6 +40,13 @@
 
 #include "ati_pciids_gen.h"
 
+#define PCI_CHIP_R520_7104		0x7104
+#define PCI_CHIP_RV515_7142             0x7142
+#define PCI_CHIP_RV515_7183             0x7183
+#define PCI_CHIP_RV530_71C5             0x71C5
+#define PCI_CHIP_R580_7249		0x7249
+#define PCI_CHIP_RV570_7280             0x7280
+
 /* Misc */
 #define PCI_CHIP_AMD761			0x700E
 
diff --git a/src/atipreinit.c b/src/atipreinit.c
index 8114f51..2420b9f 100644
--- a/src/atipreinit.c
+++ b/src/atipreinit.c
@@ -301,7 +301,7 @@ ATIPreInit
      * If there is an ix86-style BIOS, ensure its initialisation entry point
      * has been executed, and retrieve DDC and VBE information from it.
      */
-    if (!(pInt10Module = ATILoadModule(pScreenInfo, "int10", ATIint10Symbols)))
+    if (!(pInt10Module = xf86LoadSubModule(pScreenInfo, "int10")))
     {
         xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
             "Unable to load int10 module.\n");
@@ -313,13 +313,13 @@ ATIPreInit
     }
     else
     {
-        if (!(pDDCModule = ATILoadModule(pScreenInfo, "ddc", ATIddcSymbols)))
+        if (!(pDDCModule = xf86LoadSubModule(pScreenInfo, "ddc")))
         {
             xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
                 "Unable to load ddc module.\n");
         }
         else
-        if (!(pVBEModule = ATILoadModule(pScreenInfo, "vbe", ATIvbeSymbols)))
+        if (!(pVBEModule = xf86LoadSubModule(pScreenInfo, "vbe")))
         {
             xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
                 "Unable to load vbe module.\n");
diff --git a/src/atiprobe.c b/src/atiprobe.c
index 38ce90d..ddfed31 100644
--- a/src/atiprobe.c
+++ b/src/atiprobe.c
@@ -32,8 +32,8 @@
 #include "atibus.h"
 #include "atichip.h"
 #include "atimach64io.h"
+#include "atimach64version.h"
 #include "atiprobe.h"
-#include "ativersion.h"
 #include "atividmem.h"
 #include "atiwonderio.h"
 
@@ -58,7 +58,7 @@ ATIVGAWonderProbe
             if (!pATI->OptionProbeSparse)
             {
                 xf86Msg(X_WARNING,
-                    ATI_NAME ":  Expected VGA Wonder capability at I/O port"
+                    MACH64_NAME ":  Expected VGA Wonder capability at I/O port"
                     " 0x%04lX will not be probed\n"
                     "set option \"probe_sparse\" to force probing.\n",
                     pATI->CPIO_VGAWonder);
@@ -96,13 +96,13 @@ ATIVGAWonderProbe
                 (IOValue6 == 0))
             {
                 xf86MsgVerb(X_INFO, 3,
-                    ATI_NAME ":  VGA Wonder at I/O port 0x%04lX detected.\n",
+                    MACH64_NAME ":  VGA Wonder at I/O port 0x%04lX detected.\n",
                     pATI->CPIO_VGAWonder);
             }
             else
             {
                 xf86Msg(X_WARNING,
-                    ATI_NAME ":  Expected VGA Wonder capability at I/O port"
+                    MACH64_NAME ":  Expected VGA Wonder capability at I/O port"
                     " 0x%04lX was not detected.\n", pATI->CPIO_VGAWonder);
                 pATI->CPIO_VGAWonder = 0;
             }
@@ -398,7 +398,7 @@ ATIMach64ProbeIO
 
         if (j == 0x03U)
         {
-            xf86Msg(X_WARNING, ATI_NAME ": "
+            xf86Msg(X_WARNING, MACH64_NAME ": "
                 "PCI Mach64 in slot %d:%d:%d cannot be enabled\n"
                 "because it has neither a block, nor a sparse, I/O base.\n",
                 PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo));
@@ -406,6 +406,13 @@ ATIMach64ProbeIO
             goto SkipSparse;
         }
 
+        /* Possibly fix block I/O indicator */
+        if (PciReg & 0x00000004U)
+        {
+            PciReg &= ~0x00000004U;
+            PCI_WRITE_LONG(pVideo, PciReg, PCI_REG_USERCONFIG);
+        }
+
         /* FIXME:
          * Should not probe at sparse I/O bases which have been registered to
          * other PCI devices. The old ATIProbe() would scan the PCI space and
@@ -418,7 +425,7 @@ ATIMach64ProbeIO
          */
         if (!pATI->OptionProbeSparse)
         {
-            xf86Msg(X_WARNING, ATI_NAME ": "
+            xf86Msg(X_WARNING, MACH64_NAME ": "
                 "PCI Mach64 in slot %d:%d:%d will not be probed\n"
                 "set option \"probe_sparse\" to force sparse I/O probing.\n",
                 PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo));
@@ -426,27 +433,20 @@ ATIMach64ProbeIO
             goto SkipSparse;
         }
 
-        /* Possibly fix block I/O indicator */
-        if (PciReg & 0x00000004U)
-        {
-            PciReg &= ~0x00000004U;
-            PCI_WRITE_LONG(pVideo, PciReg, PCI_REG_USERCONFIG);
-        }
-
         pATI->CPIOBase = Mach64SparseIOBases[j];
         pATI->CPIODecoding = SPARSE_IO;
         pATI->PCIInfo = pVideo;
 
         if (!ATIMach64Probe(pATI, pVideo, pATI->Chip))
         {
-            xf86Msg(X_WARNING, ATI_NAME ": "
+            xf86Msg(X_WARNING, MACH64_NAME ": "
                 "PCI Mach64 in slot %d:%d:%d could not be detected!\n",
                 PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo));
         }
         else
         {
             ProbeSuccess = TRUE;
-            xf86Msg(X_INFO, ATI_NAME ": "
+            xf86Msg(X_INFO, MACH64_NAME ": "
                 "Shared PCI Mach64 in slot %d:%d:%d with sparse PIO base"
                 " 0x%04lX detected.\n",
                 PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo),
@@ -471,7 +471,7 @@ SkipSparse:
         if (ATIMach64Probe(pATI, pVideo, pATI->Chip))
         {
             ProbeSuccess = TRUE;
-            xf86Msg(X_INFO, ATI_NAME ": "
+            xf86Msg(X_INFO, MACH64_NAME ": "
                 "Shared PCI Mach64 in slot %d:%d:%d with Block 0 base"
                 " 0x%08lX detected.\n",
                 PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo),
@@ -479,7 +479,7 @@ SkipSparse:
         }
         else
         {
-            xf86Msg(X_WARNING, ATI_NAME ": "
+            xf86Msg(X_WARNING, MACH64_NAME ": "
                 "PCI Mach64 in slot %d:%d:%d could not be detected!\n",
                 PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo));
         }
@@ -497,7 +497,7 @@ SkipSparse:
         if (ATIMach64Probe(pATI, pVideo, pATI->Chip))
         {
             ProbeSuccess = TRUE;
-            xf86Msg(X_INFO, ATI_NAME ": "
+            xf86Msg(X_INFO, MACH64_NAME ": "
                 "Shared PCI/AGP Mach64 in slot %d:%d:%d detected.\n",
                 PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo));
 
@@ -511,7 +511,7 @@ SkipSparse:
         }
         else
         {
-            xf86Msg(X_WARNING, ATI_NAME ": "
+            xf86Msg(X_WARNING, MACH64_NAME ": "
                 "PCI/AGP Mach64 in slot %d:%d:%d could not be detected!\n",
                 PCI_DEV_BUS(pVideo), PCI_DEV_DEV(pVideo), PCI_DEV_FUNC(pVideo));
         }
diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c
new file mode 100644
index 0000000..bc2df18
--- /dev/null
+++ b/src/atombios_crtc.c
@@ -0,0 +1,426 @@
+ /*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * PLL code is:
+ * Copyright 2007  Luc Verhaegen <lverhaegen@novell.com>
+ * Copyright 2007  Matthias Hopf <mhopf@novell.com>
+ * Copyright 2007  Egbert Eich   <eich@novell.com>
+ * Copyright 2007  Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Dave Airlie <airlied@redhat.com>
+ *
+ */
+/*
+ * avivo crtc handling functions.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+/* DPMS */
+#define DPMS_SERVER
+#include <X11/extensions/dpms.h>
+
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_macros.h"
+#include "radeon_atombios.h"
+
+#ifdef XF86DRI
+#define _XF86DRI_SERVER_
+#include "radeon_dri.h"
+#include "radeon_sarea.h"
+#include "sarea.h"
+#endif
+
+AtomBiosResult
+atombios_enable_crtc(atomBiosHandlePtr atomBIOS, int crtc, int state)
+{
+    ENABLE_CRTC_PS_ALLOCATION crtc_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    crtc_data.ucCRTC = crtc;
+    crtc_data.ucEnable = state;
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, EnableCRTC);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &crtc_data;
+
+    if (RHDAtomBiosFunc(atomBIOS->scrnIndex, atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("%s CRTC %d success\n", state? "Enable":"Disable", crtc);
+	return ATOM_SUCCESS ;
+    }
+
+    ErrorF("Enable CRTC failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+}
+
+AtomBiosResult
+atombios_blank_crtc(atomBiosHandlePtr atomBIOS, int crtc, int state)
+{
+    BLANK_CRTC_PS_ALLOCATION crtc_data;
+    unsigned char *space;
+    AtomBiosArgRec data;
+
+    memset(&crtc_data, 0, sizeof(crtc_data));
+    crtc_data.ucCRTC = crtc;
+    crtc_data.ucBlanking = state;
+
+    data.exec.index = offsetof(ATOM_MASTER_LIST_OF_COMMAND_TABLES, BlankCRTC) / sizeof(unsigned short);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &crtc_data;
+
+    if (RHDAtomBiosFunc(atomBIOS->scrnIndex, atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("%s CRTC %d success\n", state? "Blank":"Unblank", crtc);
+	return ATOM_SUCCESS ;
+    }
+
+    ErrorF("Blank CRTC failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+}
+
+#if 0
+static void
+atombios_crtc_enable(xf86CrtcPtr crtc, int enable)
+{
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    RADEONInfoPtr  info = RADEONPTR(crtc->scrn);
+
+    atombios_enable_crtc(info->atomBIOS, radeon_crtc->crtc_id, enable);
+
+    //TODOavivo_wait_idle(avivo);
+}
+#endif
+
+void
+atombios_crtc_dpms(xf86CrtcPtr crtc, int mode)
+{
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    RADEONInfoPtr  info = RADEONPTR(crtc->scrn);
+    switch (mode) {
+    case DPMSModeOn:
+    case DPMSModeStandby:
+    case DPMSModeSuspend:
+	atombios_enable_crtc(info->atomBIOS, radeon_crtc->crtc_id, 1);
+	atombios_blank_crtc(info->atomBIOS, radeon_crtc->crtc_id, 0);
+	break;
+    case DPMSModeOff:
+	atombios_blank_crtc(info->atomBIOS, radeon_crtc->crtc_id, 1);
+	atombios_enable_crtc(info->atomBIOS, radeon_crtc->crtc_id, 0);
+	break;
+    }
+}
+
+static AtomBiosResult
+atombios_set_crtc_timing(atomBiosHandlePtr atomBIOS, SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_param)
+{
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = crtc_param;
+
+    if (RHDAtomBiosFunc(atomBIOS->scrnIndex, atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Set CRTC Timing success\n");
+	return ATOM_SUCCESS ;
+    }
+
+    ErrorF("Set CRTC Timing failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+}
+
+void
+atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
+{
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    RADEONInfoPtr  info = RADEONPTR(crtc->scrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
+    CARD32 sclock = mode->Clock;
+    CARD32 ref_div = 0, fb_div = 0, post_div = 0;
+    int major, minor;
+    SET_PIXEL_CLOCK_PS_ALLOCATION spc_param;
+    void *ptr;
+    AtomBiosArgRec data;
+    unsigned char *space;
+    RADEONSavePtr save = info->ModeReg;
+
+    if (IS_AVIVO_VARIANT) {
+	CARD32 temp;
+	RADEONComputePLL(&info->pll, mode->Clock, &temp, &fb_div, &ref_div, &post_div, 0);
+	sclock = temp;
+
+	/* disable spread spectrum clocking for now -- thanks Hedy Lamarr */
+	if (radeon_crtc->crtc_id == 0) {
+	    temp = INREG(AVIVO_P1PLL_INT_SS_CNTL);
+	    OUTREG(AVIVO_P1PLL_INT_SS_CNTL, temp & ~1);
+	} else {
+	    temp = INREG(AVIVO_P2PLL_INT_SS_CNTL);
+	    OUTREG(AVIVO_P2PLL_INT_SS_CNTL, temp & ~1);
+	}
+    } else {
+	sclock = save->dot_clock_freq;
+	fb_div = save->feedback_div;
+	post_div = save->post_div;
+	ref_div = save->ppll_ref_div;
+    }
+
+    xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO,
+	       "crtc(%d) Clock: mode %d, PLL %lu\n",
+	       radeon_crtc->crtc_id, mode->Clock, (long unsigned int)sclock * 10);
+    xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO,
+	       "crtc(%d) PLL  : refdiv %u, fbdiv 0x%X(%u), pdiv %u\n",
+	       radeon_crtc->crtc_id, (unsigned int)ref_div, (unsigned int)fb_div, (unsigned int)fb_div, (unsigned int)post_div);
+
+    atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
+
+    ErrorF("table is %d %d\n", major, minor);
+    switch(major) {
+    case 1:
+	switch(minor) {
+	case 1:
+	case 2: {
+	    spc_param.sPCLKInput.usPixelClock = sclock;
+	    spc_param.sPCLKInput.usRefDiv = ref_div;
+	    spc_param.sPCLKInput.usFbDiv = fb_div;
+	    spc_param.sPCLKInput.ucPostDiv = post_div;
+	    spc_param.sPCLKInput.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
+	    spc_param.sPCLKInput.ucCRTC = radeon_crtc->crtc_id;
+	    spc_param.sPCLKInput.ucRefDivSrc = 1;
+
+	    ptr = &spc_param;
+	    break;
+	}
+	default:
+	    ErrorF("Unknown table version\n");
+	    exit(-1);
+	}
+	break;
+    default:
+	ErrorF("Unknown table version\n");
+	exit(-1);
+    }
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = ptr;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Set CRTC PLL success\n");
+	return;
+    }
+
+    ErrorF("Set CRTC PLL failed\n");
+    return;
+}
+
+void
+atombios_crtc_mode_set(xf86CrtcPtr crtc,
+		       DisplayModePtr mode,
+		       DisplayModePtr adjusted_mode,
+		       int x, int y)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    unsigned long fb_location = crtc->scrn->fbOffset + info->fbLocation;
+    Bool           tilingOld   = info->tilingEnabled;
+    int need_tv_timings = 0;
+    int i, ret;
+    SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing;
+
+    memset(&crtc_timing, 0, sizeof(crtc_timing));
+
+    if (info->allowColorTiling) {
+	info->tilingEnabled = (adjusted_mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
+#ifdef XF86DRI
+	if (info->directRenderingEnabled && (info->tilingEnabled != tilingOld)) {
+	    RADEONSAREAPrivPtr pSAREAPriv;
+	    if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_SWITCH_TILING, (info->tilingEnabled ? 1 : 0)) < 0)
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "[drm] failed changing tiling status\n");
+	    /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
+	    pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
+	    info->tilingEnabled = pSAREAPriv->tiling_enabled ? TRUE : FALSE;
+	}
+#endif
+    }
+
+    for (i = 0; i < xf86_config->num_output; i++) {
+	xf86OutputPtr output = xf86_config->output[i];
+	RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+	if (output->crtc == crtc) {
+	    if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
+		if (radeon_output->tvStd == TV_STD_NTSC ||
+		    radeon_output->tvStd == TV_STD_NTSC_J ||
+		    radeon_output->tvStd == TV_STD_PAL_M)
+		    need_tv_timings = 1;
+		else
+		    need_tv_timings = 2;
+
+	    }
+	}
+    }
+
+    crtc_timing.ucCRTC = radeon_crtc->crtc_id;
+    if (need_tv_timings) {
+	ret = RADEONATOMGetTVTimings(pScrn, need_tv_timings - 1, &crtc_timing, &adjusted_mode->Clock);
+	if (ret == FALSE) {
+	    need_tv_timings = 0;
+	} else {
+	    adjusted_mode->CrtcHDisplay = crtc_timing.usH_Disp;
+	    adjusted_mode->CrtcHTotal = crtc_timing.usH_Total;
+	    adjusted_mode->CrtcVDisplay = crtc_timing.usV_Disp;
+	    adjusted_mode->CrtcVTotal = crtc_timing.usV_Total;
+	}
+    }
+
+    if (!need_tv_timings) {
+	crtc_timing.usH_Total = adjusted_mode->CrtcHTotal;
+	crtc_timing.usH_Disp = adjusted_mode->CrtcHDisplay;
+	crtc_timing.usH_SyncStart = adjusted_mode->CrtcHSyncStart;
+	crtc_timing.usH_SyncWidth = adjusted_mode->CrtcHSyncEnd - adjusted_mode->CrtcHSyncStart;
+
+	crtc_timing.usV_Total = adjusted_mode->CrtcVTotal;
+	crtc_timing.usV_Disp = adjusted_mode->CrtcVDisplay;
+	crtc_timing.usV_SyncStart = adjusted_mode->CrtcVSyncStart;
+	crtc_timing.usV_SyncWidth = adjusted_mode->CrtcVSyncEnd - adjusted_mode->CrtcVSyncStart;
+
+	if (adjusted_mode->Flags & V_NVSYNC)
+	    crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY;
+
+	if (adjusted_mode->Flags & V_NHSYNC)
+	    crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY;
+
+	if (adjusted_mode->Flags & V_CSYNC)
+	    crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC;
+
+	if (adjusted_mode->Flags & V_INTERLACE)
+	    crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE;
+
+	if (adjusted_mode->Flags & V_DBLSCAN)
+	    crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE;
+
+    }
+
+    ErrorF("Mode %dx%d - %d %d %d\n", adjusted_mode->CrtcHDisplay, adjusted_mode->CrtcVDisplay,
+	   adjusted_mode->CrtcHTotal, adjusted_mode->CrtcVTotal, adjusted_mode->Flags);
+
+    RADEONInitMemMapRegisters(pScrn, info->ModeReg, info);
+    RADEONRestoreMemMapRegisters(pScrn, info->ModeReg);
+
+    if (IS_AVIVO_VARIANT) {
+	radeon_crtc->fb_width = mode->CrtcHDisplay;
+	radeon_crtc->fb_height = pScrn->virtualY;
+	radeon_crtc->fb_pitch = mode->CrtcHDisplay;
+	radeon_crtc->fb_length = radeon_crtc->fb_pitch * radeon_crtc->fb_height * 4;
+	switch (crtc->scrn->bitsPerPixel) {
+	case 15:
+	    radeon_crtc->fb_format = AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555;
+	    break;
+	case 16:
+	    radeon_crtc->fb_format = AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | AVIVO_D1GRPH_CONTROL_16BPP_RGB565;
+	    break;
+	case 24:
+	case 32:
+	    radeon_crtc->fb_format = AVIVO_D1GRPH_CONTROL_DEPTH_32BPP | AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888;
+	    break;
+	default:
+	    FatalError("Unsupported screen depth: %d\n", xf86GetDepth());
+	}
+
+	if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
+	    radeon_crtc->fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
+	}
+
+	if (radeon_crtc->crtc_id == 0)
+	    OUTREG(AVIVO_D1VGA_CONTROL, 0);
+	else
+	    OUTREG(AVIVO_D2VGA_CONTROL, 0);
+
+	/* setup fb format and location
+	 */
+	if (crtc->rotatedData != NULL) {
+	    /* x/y offset is already included */
+	    x = 0;
+	    y = 0;
+	    fb_location = fb_location + (char *)crtc->rotatedData - (char *)info->FB;
+	}
+
+	/* lock the grph regs */
+	OUTREG(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, AVIVO_D1GRPH_UPDATE_LOCK);
+
+	OUTREG(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, fb_location);
+	OUTREG(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, fb_location);
+	OUTREG(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset,
+	       radeon_crtc->fb_format);
+
+	OUTREG(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
+	OUTREG(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
+	OUTREG(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0);
+	OUTREG(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0);
+	OUTREG(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset,
+	       crtc->scrn->virtualX);
+	OUTREG(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset,
+	       crtc->scrn->virtualY);
+	OUTREG(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset,
+	       crtc->scrn->displayWidth);
+	OUTREG(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
+
+	/* unlock the grph regs */
+	OUTREG(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, 0);
+
+	/* lock the mode regs */
+	OUTREG(AVIVO_D1SCL_UPDATE + radeon_crtc->crtc_offset, AVIVO_D1SCL_UPDATE_LOCK);
+
+	OUTREG(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
+	       crtc->scrn->virtualY);
+	OUTREG(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, (x << 16) | y);
+	OUTREG(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
+	       (mode->HDisplay << 16) | mode->VDisplay);
+	/* unlock the mode regs */
+	OUTREG(AVIVO_D1SCL_UPDATE + radeon_crtc->crtc_offset, 0);
+
+    }
+
+    atombios_crtc_set_pll(crtc, adjusted_mode);
+
+    atombios_set_crtc_timing(info->atomBIOS, &crtc_timing);
+
+    if (info->tilingEnabled != tilingOld) {
+	/* need to redraw front buffer, I guess this can be considered a hack ? */
+	/* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
+	if (pScrn->pScreen)
+	    xf86EnableDisableFBAccess(pScrn->scrnIndex, FALSE);
+	RADEONChangeSurfaces(pScrn);
+	if (pScrn->pScreen)
+	    xf86EnableDisableFBAccess(pScrn->scrnIndex, TRUE);
+	/* xf86SetRootClip would do, but can't access that here */
+    }
+
+}
+
diff --git a/src/atombios_output.c b/src/atombios_output.c
new file mode 100644
index 0000000..6eb8776
--- /dev/null
+++ b/src/atombios_output.c
@@ -0,0 +1,693 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ * Copyright 2007  Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Dave Airlie <airlied@redhat.com>
+ *    Alex Deucher <alexdeucher@gmail.com>
+ *
+ */
+
+/*
+ * avivo output handling functions.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+/* DPMS */
+#define DPMS_SERVER
+#include <X11/extensions/dpms.h>
+#include <unistd.h>
+
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_macros.h"
+#include "radeon_atombios.h"
+
+static int
+atombios_output_dac1_setup(xf86OutputPtr output, DisplayModePtr mode)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    DAC_ENCODER_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.ucAction = 1;
+
+    if (radeon_output->MonType == MT_CRT)
+	disp_data.ucDacStandard = ATOM_DAC1_PS2;
+    else if (radeon_output->MonType == MT_CV)
+	disp_data.ucDacStandard = ATOM_DAC1_CV;
+    else if (OUTPUT_IS_TV) {
+	switch (radeon_output->tvStd) {
+	case TV_STD_NTSC:
+	case TV_STD_NTSC_J:
+	case TV_STD_PAL_60:
+	    disp_data.ucDacStandard = ATOM_DAC1_NTSC;
+	    break;
+	case TV_STD_PAL:
+	case TV_STD_PAL_M:
+	case TV_STD_SCART_PAL:
+	case TV_STD_SECAM:
+	case TV_STD_PAL_CN:
+	    disp_data.ucDacStandard = ATOM_DAC1_PAL;
+	    break;
+	default:
+	    disp_data.ucDacStandard = ATOM_DAC1_NTSC;
+	    break;
+	}
+    }
+
+    disp_data.usPixelClock = mode->Clock / 10;
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Output DAC1 setup success\n");
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Output DAC1 setup failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+
+}
+
+static int
+atombios_output_dac2_setup(xf86OutputPtr output, DisplayModePtr mode)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    DAC_ENCODER_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.ucAction = 1;
+
+    if (radeon_output->MonType == MT_CRT)
+	disp_data.ucDacStandard = ATOM_DAC2_PS2;
+    else if (radeon_output->MonType == MT_CV)
+	disp_data.ucDacStandard = ATOM_DAC2_CV;
+    else if (OUTPUT_IS_TV) {
+	switch (radeon_output->tvStd) {
+	case TV_STD_NTSC:
+	case TV_STD_NTSC_J:
+	case TV_STD_PAL_60:
+	    disp_data.ucDacStandard = ATOM_DAC2_NTSC;
+	    break;
+	case TV_STD_PAL:
+	case TV_STD_PAL_M:
+	case TV_STD_SCART_PAL:
+	case TV_STD_SECAM:
+	case TV_STD_PAL_CN:
+	    disp_data.ucDacStandard = ATOM_DAC2_PAL;
+	    break;
+	default:
+	    disp_data.ucDacStandard = ATOM_DAC2_NTSC;
+	    break;
+	}
+    }
+
+    disp_data.usPixelClock = mode->Clock / 10;
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Output DAC2 setup success\n");
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Output DAC2 setup failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+
+}
+
+static int
+atombios_output_tv1_setup(xf86OutputPtr output, DisplayModePtr mode)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    TV_ENCODER_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.sTVEncoder.ucAction = 1;
+
+    if (radeon_output->MonType == MT_CV)
+	disp_data.sTVEncoder.ucTvStandard = ATOM_TV_CV;
+    else {
+	switch (radeon_output->tvStd) {
+	case TV_STD_NTSC:
+	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
+	    break;
+	case TV_STD_PAL:
+	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PAL;
+	    break;
+	case TV_STD_PAL_M:
+	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PALM;
+	    break;
+	case TV_STD_PAL_60:
+	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PAL60;
+	    break;
+	case TV_STD_NTSC_J:
+	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_NTSCJ;
+	    break;
+	case TV_STD_SCART_PAL:
+	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PAL; /* ??? */
+	    break;
+	case TV_STD_SECAM:
+	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_SECAM;
+	    break;
+	case TV_STD_PAL_CN:
+	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PALCN;
+	    break;
+	default:
+	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
+	    break;
+	}
+    }
+
+    disp_data.sTVEncoder.usPixelClock = mode->Clock / 10;
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Output TV1 setup success\n");
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Output TV1 setup failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+
+}
+
+int
+atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode)
+{
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.sXTmdsEncoder.ucEnable = 1;
+
+    if (mode->Clock > 165000)
+	disp_data.sXTmdsEncoder.ucMisc = 1;
+    else
+	disp_data.sXTmdsEncoder.ucMisc = 0;
+
+    if (!info->dac6bits)
+	disp_data.sXTmdsEncoder.ucMisc |= (1 << 1);
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("External TMDS setup success\n");
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("External TMDS setup failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+}
+
+static int
+atombios_output_tmds1_setup(xf86OutputPtr output, DisplayModePtr mode)
+{
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    TMDS1_ENCODER_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.ucAction = 1;
+    if (mode->Clock > 165000)
+	disp_data.ucMisc = 1;
+    else
+	disp_data.ucMisc = 0;
+    disp_data.usPixelClock = mode->Clock / 10;
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Output TMDS1 setup success\n");
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Output TMDS1 setup failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+
+}
+
+static int
+atombios_output_tmds2_setup(xf86OutputPtr output, DisplayModePtr mode)
+{
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    TMDS2_ENCODER_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.ucAction = 1;
+    if (mode->Clock > 165000)
+	disp_data.ucMisc = 1;
+    else
+	disp_data.ucMisc = 0;
+    disp_data.usPixelClock = mode->Clock / 10;
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Output TMDS2 setup success\n");
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Output TMDS2 setup failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+}
+
+static int
+atombios_output_lvds_setup(xf86OutputPtr output, DisplayModePtr mode)
+{
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    LVDS_ENCODER_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.ucAction = 1;
+    if (mode->Clock > 165000)
+	disp_data.ucMisc = 1;
+    else
+	disp_data.ucMisc = 0;
+    disp_data.usPixelClock = mode->Clock / 10;
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Output LVDS setup success\n");
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Output LVDS setup failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+}
+
+static int
+atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode)
+{
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
+    ENABLE_SCALER_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.ucScaler = radeon_crtc->crtc_id;
+
+    if (radeon_output->Flags & RADEON_USE_RMX) {
+	ErrorF("Using RMX\n");
+	if (radeon_output->rmx_type == RMX_FULL)
+	    disp_data.ucEnable = ATOM_SCALER_EXPANSION;
+	else if (radeon_output->rmx_type == RMX_CENTER)
+	    disp_data.ucEnable = ATOM_SCALER_CENTER;
+    } else {
+	ErrorF("Not using RMX\n");
+	disp_data.ucEnable = ATOM_SCALER_DISABLE;
+    }
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("scaler %d setup success\n", radeon_crtc->crtc_id);
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("scaler %d setup failed\n", radeon_crtc->crtc_id);
+    return ATOM_NOT_IMPLEMENTED;
+
+}
+
+static AtomBiosResult
+atombios_display_device_control(atomBiosHandlePtr atomBIOS, int device, Bool state)
+{
+    DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.ucAction = state;
+    data.exec.index = device;
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(atomBIOS->scrnIndex, atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Output %d %s success\n", device, state? "enable":"disable");
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Output %d %s failed\n", device, state? "enable":"disable");
+    return ATOM_NOT_IMPLEMENTED;
+}
+
+static void
+atombios_device_dpms(xf86OutputPtr output, int device, int mode)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    int index = 0;
+
+    switch (device) {
+    case ATOM_DEVICE_CRT1_SUPPORT:
+    case ATOM_DEVICE_CRT2_SUPPORT:
+	if (radeon_output->DACType == DAC_PRIMARY)
+	    index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
+	else if (radeon_output->DACType == DAC_TVDAC)
+	    index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
+	break;
+    case ATOM_DEVICE_DFP1_SUPPORT:
+	index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);
+	break;
+    case ATOM_DEVICE_DFP2_SUPPORT:
+	index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
+	break;
+    case ATOM_DEVICE_DFP3_SUPPORT:
+	index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);
+	break;
+    case ATOM_DEVICE_LCD1_SUPPORT:
+	index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
+	break;
+    case ATOM_DEVICE_TV1_SUPPORT:
+	index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
+	break;
+    case ATOM_DEVICE_CV_SUPPORT:
+	index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
+	break;
+    default:
+	return;
+    }
+
+    switch (mode) {
+    case DPMSModeOn:
+	atombios_display_device_control(info->atomBIOS, index, ATOM_ENABLE);
+	break;
+    case DPMSModeStandby:
+    case DPMSModeSuspend:
+    case DPMSModeOff:
+	atombios_display_device_control(info->atomBIOS, index, ATOM_DISABLE);
+	break;
+    }
+}
+
+void
+atombios_output_dpms(xf86OutputPtr output, int mode)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    int tmp, count;
+
+#if 1
+    /* try to grab card lock or at least somethings that looks like a lock
+     * if it fails more than 5 times with 1000ms wait btw each try than we
+     * assume we can process.
+     */
+    count = 0;
+    tmp = INREG(RADEON_BIOS_6_SCRATCH);
+    while((tmp & 0x100) && (count < 5)) {
+        tmp = INREG(RADEON_BIOS_6_SCRATCH);
+        count++;
+        usleep(1000);
+    }
+    if (count >= 5) {
+        xf86DrvMsg(output->scrn->scrnIndex, X_INFO,
+                   "%s (WARNING) failed to grab card lock process anyway.\n",
+                   __func__);
+    }
+    OUTREG(RADEON_BIOS_6_SCRATCH, tmp | 0x100);
+#endif
+
+    ErrorF("AGD: output dpms %d\n", mode);
+
+   if (radeon_output->MonType == MT_LCD) {
+       if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
+	   atombios_device_dpms(output, ATOM_DEVICE_LCD1_SUPPORT, mode);
+   } else if (radeon_output->MonType == MT_DFP) {
+       ErrorF("AGD: tmds dpms\n");
+       if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
+	   atombios_device_dpms(output, ATOM_DEVICE_DFP1_SUPPORT, mode);
+       else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
+	   atombios_device_dpms(output, ATOM_DEVICE_DFP2_SUPPORT, mode);
+       else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
+	   atombios_device_dpms(output, ATOM_DEVICE_DFP3_SUPPORT, mode);
+   } else if (radeon_output->MonType == MT_CRT) {
+       ErrorF("AGD: dac dpms\n");
+       if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
+	   atombios_device_dpms(output, ATOM_DEVICE_CRT1_SUPPORT, mode);
+       else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
+	   atombios_device_dpms(output, ATOM_DEVICE_CRT2_SUPPORT, mode);
+   } else if (radeon_output->MonType == MT_CV) {
+       ErrorF("AGD: cv dpms\n");
+       if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
+	   atombios_device_dpms(output, ATOM_DEVICE_CV_SUPPORT, mode);
+   } else if (0 /*OUTPUT_IS_TV*/) {
+       ErrorF("AGD: tv dpms\n");
+       if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
+	   atombios_device_dpms(output, ATOM_DEVICE_TV1_SUPPORT, mode);
+   }
+#if 1
+    /* release card lock */
+    tmp = INREG(RADEON_BIOS_6_SCRATCH);
+    OUTREG(RADEON_BIOS_6_SCRATCH, tmp & (~0x100));
+#endif
+}
+
+static void
+atombios_set_output_crtc_source(xf86OutputPtr output)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    AtomBiosArgRec data;
+    unsigned char *space;
+    SELECT_CRTC_SOURCE_PS_ALLOCATION crtc_src_param;
+    int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
+    int major, minor;
+
+    atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
+
+    ErrorF("select crtc source table is %d %d\n", major, minor);
+
+    crtc_src_param.ucCRTC = radeon_crtc->crtc_id;
+    crtc_src_param.ucDevice = 0;
+
+    switch(major) {
+    case 1: {
+	switch(minor) {
+	case 0:
+	case 1:
+	default:
+	    if (radeon_output->MonType == MT_CRT) {
+		if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
+		    crtc_src_param.ucDevice = ATOM_DEVICE_CRT1_INDEX;
+		else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
+		    crtc_src_param.ucDevice = ATOM_DEVICE_CRT2_INDEX;
+	    } else if (radeon_output->MonType == MT_DFP) {
+		if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
+		    crtc_src_param.ucDevice = ATOM_DEVICE_DFP1_INDEX;
+		else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
+		    crtc_src_param.ucDevice = ATOM_DEVICE_DFP2_INDEX;
+		else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
+		    crtc_src_param.ucDevice = ATOM_DEVICE_DFP3_INDEX;
+	    } else if (radeon_output->MonType == MT_LCD) {
+		if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
+		    crtc_src_param.ucDevice = ATOM_DEVICE_LCD1_INDEX;
+	    } else if (OUTPUT_IS_TV) {
+		if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
+		    crtc_src_param.ucDevice = ATOM_DEVICE_TV1_INDEX;
+	    } else if (radeon_output->MonType == MT_CV) {
+		if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
+		    crtc_src_param.ucDevice = ATOM_DEVICE_CV_INDEX;
+	    }
+	    break;
+	}
+	break;
+    }
+    default:
+	break;
+    }
+
+    ErrorF("device sourced: 0x%x\n", crtc_src_param.ucDevice);
+
+    data.exec.index = index;
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &crtc_src_param;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Set CRTC %d Source success\n", radeon_crtc->crtc_id);
+	return;
+    }
+
+    ErrorF("Set CRTC Source failed\n");
+    return;
+}
+
+void
+atombios_output_mode_set(xf86OutputPtr output,
+			 DisplayModePtr mode,
+			 DisplayModePtr adjusted_mode)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    atombios_output_scaler_setup(output, mode);
+    atombios_set_output_crtc_source(output);
+
+    if (radeon_output->MonType == MT_CRT) {
+       if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT ||
+	   radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) {
+	   if (radeon_output->DACType == DAC_PRIMARY)
+	       atombios_output_dac1_setup(output, adjusted_mode);
+	   else if (radeon_output->DACType == DAC_TVDAC)
+	       atombios_output_dac2_setup(output, adjusted_mode);
+       }
+    } else if (radeon_output->MonType == MT_DFP) {
+       if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
+	   atombios_output_tmds1_setup(output, adjusted_mode);
+       else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
+	   atombios_external_tmds_setup(output, adjusted_mode);
+       else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
+	   atombios_output_tmds2_setup(output, adjusted_mode);
+    } else if (radeon_output->MonType == MT_LCD) {
+	if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
+	    atombios_output_lvds_setup(output, adjusted_mode);
+    } else if (OUTPUT_IS_TV || (radeon_output->MonType == MT_CV)) {
+	if (radeon_output->DACType == DAC_PRIMARY)
+	    atombios_output_dac1_setup(output, adjusted_mode);
+	else if (radeon_output->DACType == DAC_TVDAC)
+	    atombios_output_dac2_setup(output, adjusted_mode);
+	atombios_output_tv1_setup(output, adjusted_mode);
+    }
+
+}
+
+static AtomBiosResult
+atom_bios_dac_load_detect(atomBiosHandlePtr atomBIOS, xf86OutputPtr output)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    DAC_LOAD_DETECTION_PS_ALLOCATION dac_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) {
+	dac_data.sDacload.usDeviceID = ATOM_DEVICE_CRT1_SUPPORT;
+	if (radeon_output->DACType == DAC_PRIMARY)
+	    dac_data.sDacload.ucDacType = ATOM_DAC_A;
+	else if (radeon_output->DACType == DAC_TVDAC)
+	    dac_data.sDacload.ucDacType = ATOM_DAC_B;
+    } else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) {
+	dac_data.sDacload.usDeviceID = ATOM_DEVICE_CRT2_SUPPORT;
+	if (radeon_output->DACType == DAC_PRIMARY)
+	    dac_data.sDacload.ucDacType = ATOM_DAC_A;
+	else if (radeon_output->DACType == DAC_TVDAC)
+	    dac_data.sDacload.ucDacType = ATOM_DAC_B;
+    } else if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) {
+	dac_data.sDacload.usDeviceID = ATOM_DEVICE_CV_SUPPORT;
+	if (radeon_output->DACType == DAC_PRIMARY)
+	    dac_data.sDacload.ucDacType = ATOM_DAC_A;
+	else if (radeon_output->DACType == DAC_TVDAC)
+	    dac_data.sDacload.ucDacType = ATOM_DAC_B;
+    } else if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) {
+	dac_data.sDacload.usDeviceID = ATOM_DEVICE_TV1_SUPPORT;
+	if (radeon_output->DACType == DAC_PRIMARY)
+	    dac_data.sDacload.ucDacType = ATOM_DAC_A;
+	else if (radeon_output->DACType == DAC_TVDAC)
+	    dac_data.sDacload.ucDacType = ATOM_DAC_B;
+    } else {
+	ErrorF("invalid output device for dac detection\n");
+	return ATOM_NOT_IMPLEMENTED;
+    }
+
+    dac_data.sDacload.ucMisc = 0;
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &dac_data;
+
+    if (RHDAtomBiosFunc(atomBIOS->scrnIndex, atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+
+	ErrorF("Dac detection success\n");
+	return ATOM_SUCCESS ;
+    }
+
+    ErrorF("DAC detection failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+}
+
+RADEONMonitorType
+atombios_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+    RADEONInfoPtr info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONMonitorType MonType = MT_NONE;
+    AtomBiosResult ret;
+    uint32_t bios_0_scratch;
+
+    if (OUTPUT_IS_TV) {
+	if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_TVOUT, FALSE)) {
+	    if (radeon_output->type == OUTPUT_STV)
+		return MT_STV;
+	    else
+		return MT_CTV;
+	}
+    }
+
+    ret = atom_bios_dac_load_detect(info->atomBIOS, output);
+    if (ret == ATOM_SUCCESS) {
+	bios_0_scratch = INREG(RADEON_BIOS_0_SCRATCH);
+	ErrorF("DAC connect %08X\n", (unsigned int)bios_0_scratch);
+
+	if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) {
+	    if (bios_0_scratch & ATOM_S0_CRT1_MASK)
+		MonType = MT_CRT;
+	} else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) {
+	    if (bios_0_scratch & ATOM_S0_CRT2_MASK)
+		MonType = MT_CRT;
+	} else if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) {
+	    if (bios_0_scratch & (ATOM_S0_CV_MASK | ATOM_S0_CV_MASK_A))
+		MonType = MT_CV;
+	} else if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) {
+	    if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))
+		MonType = MT_CTV;
+	    else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))
+		MonType = MT_STV;
+	}
+    }
+
+    return MonType;
+}
+
diff --git a/src/legacy_crtc.c b/src/legacy_crtc.c
new file mode 100644
index 0000000..53f0374
--- /dev/null
+++ b/src/legacy_crtc.c
@@ -0,0 +1,1821 @@
+/*
+ * 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>
+
+/* X and server generic header files */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "vgaHW.h"
+#include "xf86Modes.h"
+
+/* Driver data structures */
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_macros.h"
+#include "radeon_probe.h"
+#include "radeon_version.h"
+
+#ifdef XF86DRI
+#define _XF86DRI_SERVER_
+#include "radeon_dri.h"
+#include "radeon_sarea.h"
+#include "sarea.h"
+#endif
+
+/* Write common registers */
+void
+RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
+			     RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    if (info->IsSecondary)
+      return;
+
+    OUTREG(RADEON_OVR_CLR,            restore->ovr_clr);
+    OUTREG(RADEON_OVR_WID_LEFT_RIGHT, restore->ovr_wid_left_right);
+    OUTREG(RADEON_OVR_WID_TOP_BOTTOM, restore->ovr_wid_top_bottom);
+    OUTREG(RADEON_OV0_SCALE_CNTL,     restore->ov0_scale_cntl);
+    OUTREG(RADEON_SUBPIC_CNTL,        restore->subpic_cntl);
+    OUTREG(RADEON_VIPH_CONTROL,       restore->viph_control);
+    OUTREG(RADEON_I2C_CNTL_1,         restore->i2c_cntl_1);
+    OUTREG(RADEON_GEN_INT_CNTL,       restore->gen_int_cntl);
+    OUTREG(RADEON_CAP0_TRIG_CNTL,     restore->cap0_trig_cntl);
+    OUTREG(RADEON_CAP1_TRIG_CNTL,     restore->cap1_trig_cntl);
+    OUTREG(RADEON_BUS_CNTL,           restore->bus_cntl);
+    OUTREG(RADEON_SURFACE_CNTL,       restore->surface_cntl);
+
+    /* Workaround for the VT switching problem in dual-head mode.  This
+     * problem only occurs on RV style chips, typically when a FP and
+     * CRT are connected.
+     */
+    if (pRADEONEnt->HasCRTC2 &&
+	info->ChipFamily != CHIP_FAMILY_R200 &&
+	!IS_R300_VARIANT) {
+	CARD32        tmp;
+
+	tmp = INREG(RADEON_DAC_CNTL2);
+	OUTREG(RADEON_DAC_CNTL2, tmp & ~RADEON_DAC2_DAC_CLK_SEL);
+	usleep(100000);
+    }
+}
+
+
+/* Write CRTC registers */
+void
+RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
+			   RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Programming CRTC1, offset: 0x%08x\n",
+		   (unsigned)restore->crtc_offset);
+
+    /* We prevent the CRTC from hitting the memory controller until
+     * fully programmed
+     */
+    OUTREG(RADEON_CRTC_GEN_CNTL, restore->crtc_gen_cntl |
+	   RADEON_CRTC_DISP_REQ_EN_B);
+
+    OUTREGP(RADEON_CRTC_EXT_CNTL,
+	    restore->crtc_ext_cntl,
+	    RADEON_CRTC_VSYNC_DIS |
+	    RADEON_CRTC_HSYNC_DIS |
+	    RADEON_CRTC_DISPLAY_DIS);
+
+    OUTREG(RADEON_CRTC_H_TOTAL_DISP,    restore->crtc_h_total_disp);
+    OUTREG(RADEON_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid);
+    OUTREG(RADEON_CRTC_V_TOTAL_DISP,    restore->crtc_v_total_disp);
+    OUTREG(RADEON_CRTC_V_SYNC_STRT_WID, restore->crtc_v_sync_strt_wid);
+
+    if (IS_R300_VARIANT)
+	OUTREG(R300_CRTC_TILE_X0_Y0, restore->crtc_tile_x0_y0);
+    OUTREG(RADEON_CRTC_OFFSET_CNTL,     restore->crtc_offset_cntl);
+    OUTREG(RADEON_CRTC_OFFSET,          restore->crtc_offset);
+
+    OUTREG(RADEON_CRTC_PITCH,           restore->crtc_pitch);
+    OUTREG(RADEON_DISP_MERGE_CNTL,      restore->disp_merge_cntl);
+
+    if (info->IsDellServer) {
+	OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
+	OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
+	OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
+	OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
+    }
+
+    OUTREG(RADEON_CRTC_GEN_CNTL, restore->crtc_gen_cntl);
+}
+
+/* Write CRTC2 registers */
+void
+RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
+			    RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    /*    CARD32	   crtc2_gen_cntl;*/
+
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Programming CRTC2, offset: 0x%08x\n",
+		   (unsigned)restore->crtc2_offset);
+
+    /* We prevent the CRTC from hitting the memory controller until
+     * fully programmed
+     */
+    OUTREG(RADEON_CRTC2_GEN_CNTL,
+	   restore->crtc2_gen_cntl | RADEON_CRTC2_VSYNC_DIS |
+	   RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_DIS |
+	   RADEON_CRTC2_DISP_REQ_EN_B);
+
+    OUTREG(RADEON_CRTC2_H_TOTAL_DISP,    restore->crtc2_h_total_disp);
+    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, restore->crtc2_h_sync_strt_wid);
+    OUTREG(RADEON_CRTC2_V_TOTAL_DISP,    restore->crtc2_v_total_disp);
+    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, restore->crtc2_v_sync_strt_wid);
+
+    OUTREG(RADEON_FP_H2_SYNC_STRT_WID,   restore->fp_h2_sync_strt_wid);
+    OUTREG(RADEON_FP_V2_SYNC_STRT_WID,   restore->fp_v2_sync_strt_wid);
+
+    if (IS_R300_VARIANT)
+	OUTREG(R300_CRTC2_TILE_X0_Y0, restore->crtc2_tile_x0_y0);
+    OUTREG(RADEON_CRTC2_OFFSET_CNTL,     restore->crtc2_offset_cntl);
+    OUTREG(RADEON_CRTC2_OFFSET,          restore->crtc2_offset);
+
+    OUTREG(RADEON_CRTC2_PITCH,           restore->crtc2_pitch);
+    OUTREG(RADEON_DISP2_MERGE_CNTL,      restore->disp2_merge_cntl);
+
+    if (info->ChipFamily == CHIP_FAMILY_RS400) {
+	OUTREG(RADEON_RS480_UNK_e30, restore->rs480_unk_e30);
+	OUTREG(RADEON_RS480_UNK_e34, restore->rs480_unk_e34);
+	OUTREG(RADEON_RS480_UNK_e38, restore->rs480_unk_e38);
+	OUTREG(RADEON_RS480_UNK_e3c, restore->rs480_unk_e3c);
+    }
+    OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
+
+}
+
+static void
+RADEONPLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn)
+{
+    int i = 0;
+
+    /* FIXME: Certain revisions of R300 can't recover here.  Not sure of
+       the cause yet, but this workaround will mask the problem for now.
+       Other chips usually will pass at the very first test, so the
+       workaround shouldn't have any effect on them. */
+    for (i = 0;
+	 (i < 10000 &&
+	  INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R);
+	 i++);
+}
+
+static void
+RADEONPLLWriteUpdate(ScrnInfoPtr pScrn)
+{
+    while (INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R);
+
+    OUTPLLP(pScrn, RADEON_PPLL_REF_DIV,
+	    RADEON_PPLL_ATOMIC_UPDATE_W,
+	    ~(RADEON_PPLL_ATOMIC_UPDATE_W));
+}
+
+static void
+RADEONPLL2WaitForReadUpdateComplete(ScrnInfoPtr pScrn)
+{
+    int i = 0;
+
+    /* FIXME: Certain revisions of R300 can't recover here.  Not sure of
+       the cause yet, but this workaround will mask the problem for now.
+       Other chips usually will pass at the very first test, so the
+       workaround shouldn't have any effect on them. */
+    for (i = 0;
+	 (i < 10000 &&
+	  INPLL(pScrn, RADEON_P2PLL_REF_DIV) & RADEON_P2PLL_ATOMIC_UPDATE_R);
+	 i++);
+}
+
+static void
+RADEONPLL2WriteUpdate(ScrnInfoPtr pScrn)
+{
+    while (INPLL(pScrn, RADEON_P2PLL_REF_DIV) & RADEON_P2PLL_ATOMIC_UPDATE_R);
+
+    OUTPLLP(pScrn, RADEON_P2PLL_REF_DIV,
+	    RADEON_P2PLL_ATOMIC_UPDATE_W,
+	    ~(RADEON_P2PLL_ATOMIC_UPDATE_W));
+}
+
+static CARD8
+RADEONComputePLLGain(CARD16 reference_freq, CARD16 ref_div,
+		     CARD16 fb_div)
+{
+    unsigned vcoFreq;
+
+    if (!ref_div)
+	return 1;
+
+    vcoFreq = ((unsigned)reference_freq * fb_div) / ref_div;
+
+    /*
+     * This is horribly crude: the VCO frequency range is divided into
+     * 3 parts, each part having a fixed PLL gain value.
+     */
+    if (vcoFreq >= 30000)
+	/*
+	 * [300..max] MHz : 7
+	 */
+	return 7;
+    else if (vcoFreq >= 18000)
+	/*
+	 * [180..300) MHz : 4
+	 */
+        return 4;
+    else
+	/*
+	 * [0..180) MHz : 1
+	 */
+        return 1;
+}
+
+/* Write PLL registers */
+void
+RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
+			  RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD8 pllGain;
+
+#if defined(__powerpc__)
+    /* apparently restoring the pll causes a hang??? */
+    if (info->MacModel == RADEON_MAC_IBOOK)
+	return;
+#endif
+
+    pllGain = RADEONComputePLLGain(info->pll.reference_freq,
+				   restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
+				   restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK);
+
+    if (info->IsMobility) {
+        /* A temporal workaround for the occational blanking on certain laptop panels.
+           This appears to related to the PLL divider registers (fail to lock?).
+	   It occurs even when all dividers are the same with their old settings.
+           In this case we really don't need to fiddle with PLL registers.
+           By doing this we can avoid the blanking problem with some panels.
+        */
+        if ((restore->ppll_ref_div == (INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_REF_DIV_MASK)) &&
+	    (restore->ppll_div_3 == (INPLL(pScrn, RADEON_PPLL_DIV_3) & 
+				     (RADEON_PPLL_POST3_DIV_MASK | RADEON_PPLL_FB3_DIV_MASK)))) {
+	    OUTREGP(RADEON_CLOCK_CNTL_INDEX,
+		    RADEON_PLL_DIV_SEL,
+		    ~(RADEON_PLL_DIV_SEL));
+	    RADEONPllErrataAfterIndex(info);
+	    return;
+	}
+    }
+
+    OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
+	    RADEON_VCLK_SRC_SEL_CPUCLK,
+	    ~(RADEON_VCLK_SRC_SEL_MASK));
+
+    OUTPLLP(pScrn,
+	    RADEON_PPLL_CNTL,
+	    RADEON_PPLL_RESET
+	    | RADEON_PPLL_ATOMIC_UPDATE_EN
+	    | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
+	    | ((CARD32)pllGain << RADEON_PPLL_PVG_SHIFT),
+	    ~(RADEON_PPLL_RESET
+	      | RADEON_PPLL_ATOMIC_UPDATE_EN
+	      | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
+	      | RADEON_PPLL_PVG_MASK));
+
+    OUTREGP(RADEON_CLOCK_CNTL_INDEX,
+	    RADEON_PLL_DIV_SEL,
+	    ~(RADEON_PLL_DIV_SEL));
+    RADEONPllErrataAfterIndex(info);
+
+    if (IS_R300_VARIANT ||
+	(info->ChipFamily == CHIP_FAMILY_RS300) ||
+	(info->ChipFamily == CHIP_FAMILY_RS400)) {
+	if (restore->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
+	    /* When restoring console mode, use saved PPLL_REF_DIV
+	     * setting.
+	     */
+	    OUTPLLP(pScrn, RADEON_PPLL_REF_DIV,
+		    restore->ppll_ref_div,
+		    0);
+	} else {
+	    /* R300 uses ref_div_acc field as real ref divider */
+	    OUTPLLP(pScrn, RADEON_PPLL_REF_DIV,
+		    (restore->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),
+		    ~R300_PPLL_REF_DIV_ACC_MASK);
+	}
+    } else {
+	OUTPLLP(pScrn, RADEON_PPLL_REF_DIV,
+		restore->ppll_ref_div,
+		~RADEON_PPLL_REF_DIV_MASK);
+    }
+
+    OUTPLLP(pScrn, RADEON_PPLL_DIV_3,
+	    restore->ppll_div_3,
+	    ~RADEON_PPLL_FB3_DIV_MASK);
+
+    OUTPLLP(pScrn, RADEON_PPLL_DIV_3,
+	    restore->ppll_div_3,
+	    ~RADEON_PPLL_POST3_DIV_MASK);
+
+    RADEONPLLWriteUpdate(pScrn);
+    RADEONPLLWaitForReadUpdateComplete(pScrn);
+
+    OUTPLL(pScrn, RADEON_HTOTAL_CNTL, restore->htotal_cntl);
+
+    OUTPLLP(pScrn, RADEON_PPLL_CNTL,
+	    0,
+	    ~(RADEON_PPLL_RESET
+	      | RADEON_PPLL_SLEEP
+	      | RADEON_PPLL_ATOMIC_UPDATE_EN
+	      | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN));
+
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
+		   restore->ppll_ref_div,
+		   restore->ppll_div_3,
+		   (unsigned)restore->htotal_cntl,
+		   INPLL(pScrn, RADEON_PPLL_CNTL));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Wrote: rd=%d, fd=%d, pd=%d\n",
+		   restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
+		   restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK,
+		   (restore->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16);
+
+    usleep(50000); /* Let the clock to lock */
+
+    OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
+	    RADEON_VCLK_SRC_SEL_PPLLCLK,
+	    ~(RADEON_VCLK_SRC_SEL_MASK));
+
+    /*OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, restore->vclk_ecp_cntl);*/
+
+    ErrorF("finished PLL1\n");
+
+}
+
+/* Write PLL2 registers */
+void
+RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
+			   RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    CARD8 pllGain;
+
+    pllGain = RADEONComputePLLGain(info->pll.reference_freq,
+                                   restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
+                                   restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK);
+
+
+    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
+	    RADEON_PIX2CLK_SRC_SEL_CPUCLK,
+	    ~(RADEON_PIX2CLK_SRC_SEL_MASK));
+
+    OUTPLLP(pScrn,
+	    RADEON_P2PLL_CNTL,
+	    RADEON_P2PLL_RESET
+	    | RADEON_P2PLL_ATOMIC_UPDATE_EN
+	    | ((CARD32)pllGain << RADEON_P2PLL_PVG_SHIFT),
+	    ~(RADEON_P2PLL_RESET
+	      | RADEON_P2PLL_ATOMIC_UPDATE_EN
+	      | RADEON_P2PLL_PVG_MASK));
+
+
+    OUTPLLP(pScrn, RADEON_P2PLL_REF_DIV,
+	    restore->p2pll_ref_div,
+	    ~RADEON_P2PLL_REF_DIV_MASK);
+
+    OUTPLLP(pScrn, RADEON_P2PLL_DIV_0,
+	    restore->p2pll_div_0,
+	    ~RADEON_P2PLL_FB0_DIV_MASK);
+
+    OUTPLLP(pScrn, RADEON_P2PLL_DIV_0,
+	    restore->p2pll_div_0,
+	    ~RADEON_P2PLL_POST0_DIV_MASK);
+
+    RADEONPLL2WriteUpdate(pScrn);
+    RADEONPLL2WaitForReadUpdateComplete(pScrn);
+
+    OUTPLL(pScrn, RADEON_HTOTAL2_CNTL, restore->htotal_cntl2);
+
+    OUTPLLP(pScrn, RADEON_P2PLL_CNTL,
+	    0,
+	    ~(RADEON_P2PLL_RESET
+	      | RADEON_P2PLL_SLEEP
+	      | RADEON_P2PLL_ATOMIC_UPDATE_EN));
+
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Wrote2: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
+		   (unsigned)restore->p2pll_ref_div,
+		   (unsigned)restore->p2pll_div_0,
+		   (unsigned)restore->htotal_cntl2,
+		   INPLL(pScrn, RADEON_P2PLL_CNTL));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Wrote2: rd=%u, fd=%u, pd=%u\n",
+		   (unsigned)restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
+		   (unsigned)restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK,
+		   (unsigned)((restore->p2pll_div_0 &
+			       RADEON_P2PLL_POST0_DIV_MASK) >>16));
+
+    usleep(5000); /* Let the clock to lock */
+
+    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
+	    RADEON_PIX2CLK_SRC_SEL_P2PLLCLK,
+	    ~(RADEON_PIX2CLK_SRC_SEL_MASK));
+
+    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, restore->pixclks_cntl);
+
+    ErrorF("finished PLL2\n");
+
+}
+
+/* Read common registers */
+void
+RADEONSaveCommonRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    save->ovr_clr            = INREG(RADEON_OVR_CLR);
+    save->ovr_wid_left_right = INREG(RADEON_OVR_WID_LEFT_RIGHT);
+    save->ovr_wid_top_bottom = INREG(RADEON_OVR_WID_TOP_BOTTOM);
+    save->ov0_scale_cntl     = INREG(RADEON_OV0_SCALE_CNTL);
+    save->subpic_cntl        = INREG(RADEON_SUBPIC_CNTL);
+    save->viph_control       = INREG(RADEON_VIPH_CONTROL);
+    save->i2c_cntl_1         = INREG(RADEON_I2C_CNTL_1);
+    save->gen_int_cntl       = INREG(RADEON_GEN_INT_CNTL);
+    save->cap0_trig_cntl     = INREG(RADEON_CAP0_TRIG_CNTL);
+    save->cap1_trig_cntl     = INREG(RADEON_CAP1_TRIG_CNTL);
+    save->bus_cntl           = INREG(RADEON_BUS_CNTL);
+    save->surface_cntl	     = INREG(RADEON_SURFACE_CNTL);
+    save->grph_buffer_cntl   = INREG(RADEON_GRPH_BUFFER_CNTL);
+    save->grph2_buffer_cntl  = INREG(RADEON_GRPH2_BUFFER_CNTL);
+}
+
+void
+RADEONSaveBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    save->bios_4_scratch       = INREG(RADEON_BIOS_4_SCRATCH);
+    save->bios_5_scratch       = INREG(RADEON_BIOS_5_SCRATCH);
+    save->bios_6_scratch       = INREG(RADEON_BIOS_6_SCRATCH);
+}
+
+/* Read CRTC registers */
+void
+RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    save->crtc_gen_cntl        = INREG(RADEON_CRTC_GEN_CNTL);
+    save->crtc_ext_cntl        = INREG(RADEON_CRTC_EXT_CNTL);
+    save->crtc_h_total_disp    = INREG(RADEON_CRTC_H_TOTAL_DISP);
+    save->crtc_h_sync_strt_wid = INREG(RADEON_CRTC_H_SYNC_STRT_WID);
+    save->crtc_v_total_disp    = INREG(RADEON_CRTC_V_TOTAL_DISP);
+    save->crtc_v_sync_strt_wid = INREG(RADEON_CRTC_V_SYNC_STRT_WID);
+
+    save->crtc_offset          = INREG(RADEON_CRTC_OFFSET);
+    save->crtc_offset_cntl     = INREG(RADEON_CRTC_OFFSET_CNTL);
+    save->crtc_pitch           = INREG(RADEON_CRTC_PITCH);
+    save->disp_merge_cntl      = INREG(RADEON_DISP_MERGE_CNTL);
+
+    if (IS_R300_VARIANT)
+	save->crtc_tile_x0_y0 =  INREG(R300_CRTC_TILE_X0_Y0);
+
+    if (info->IsDellServer) {
+	save->tv_dac_cntl      = INREG(RADEON_TV_DAC_CNTL);
+	save->dac2_cntl        = INREG(RADEON_DAC_CNTL2);
+	save->disp_hw_debug    = INREG (RADEON_DISP_HW_DEBUG);
+	save->crtc2_gen_cntl   = INREG(RADEON_CRTC2_GEN_CNTL);
+    }
+
+    /* track if the crtc is enabled for text restore */
+    if (save->crtc_ext_cntl & RADEON_CRTC_DISPLAY_DIS)
+	info->crtc_on = FALSE;
+    else
+	info->crtc_on = TRUE;
+
+}
+
+/* Read CRTC2 registers */
+void
+RADEONSaveCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    save->crtc2_gen_cntl        = INREG(RADEON_CRTC2_GEN_CNTL);
+    save->crtc2_h_total_disp    = INREG(RADEON_CRTC2_H_TOTAL_DISP);
+    save->crtc2_h_sync_strt_wid = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
+    save->crtc2_v_total_disp    = INREG(RADEON_CRTC2_V_TOTAL_DISP);
+    save->crtc2_v_sync_strt_wid = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
+    save->crtc2_offset          = INREG(RADEON_CRTC2_OFFSET);
+    save->crtc2_offset_cntl     = INREG(RADEON_CRTC2_OFFSET_CNTL);
+    save->crtc2_pitch           = INREG(RADEON_CRTC2_PITCH);
+
+    if (IS_R300_VARIANT)
+	save->crtc2_tile_x0_y0 =  INREG(R300_CRTC2_TILE_X0_Y0);
+
+    save->fp_h2_sync_strt_wid   = INREG (RADEON_FP_H2_SYNC_STRT_WID);
+    save->fp_v2_sync_strt_wid   = INREG (RADEON_FP_V2_SYNC_STRT_WID);
+
+    if (info->ChipFamily == CHIP_FAMILY_RS400) {
+	save->rs480_unk_e30 = INREG(RADEON_RS480_UNK_e30);
+	save->rs480_unk_e34 = INREG(RADEON_RS480_UNK_e34);
+	save->rs480_unk_e38 = INREG(RADEON_RS480_UNK_e38);
+	save->rs480_unk_e3c = INREG(RADEON_RS480_UNK_e3c);
+    }
+    
+    save->disp2_merge_cntl      = INREG(RADEON_DISP2_MERGE_CNTL);
+
+    /* track if the crtc is enabled for text restore */
+    if (save->crtc2_gen_cntl & RADEON_CRTC2_DISP_DIS)
+	info->crtc2_on = FALSE;
+    else
+	info->crtc2_on = TRUE;
+
+}
+
+/* Read PLL registers */
+void
+RADEONSavePLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+    save->ppll_ref_div = INPLL(pScrn, RADEON_PPLL_REF_DIV);
+    save->ppll_div_3   = INPLL(pScrn, RADEON_PPLL_DIV_3);
+    save->htotal_cntl  = INPLL(pScrn, RADEON_HTOTAL_CNTL);
+    save->vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Read: 0x%08x 0x%08x 0x%08x\n",
+		   save->ppll_ref_div,
+		   save->ppll_div_3,
+		   (unsigned)save->htotal_cntl);
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Read: rd=%d, fd=%d, pd=%d\n",
+		   save->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
+		   save->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK,
+		   (save->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16);
+}
+
+/* Read PLL registers */
+void
+RADEONSavePLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+    save->p2pll_ref_div = INPLL(pScrn, RADEON_P2PLL_REF_DIV);
+    save->p2pll_div_0   = INPLL(pScrn, RADEON_P2PLL_DIV_0);
+    save->htotal_cntl2  = INPLL(pScrn, RADEON_HTOTAL2_CNTL);
+    save->pixclks_cntl  = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Read: 0x%08x 0x%08x 0x%08x\n",
+		   (unsigned)save->p2pll_ref_div,
+		   (unsigned)save->p2pll_div_0,
+		   (unsigned)save->htotal_cntl2);
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Read: rd=%u, fd=%u, pd=%u\n",
+		   (unsigned)(save->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK),
+		   (unsigned)(save->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK),
+		   (unsigned)((save->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK)
+			      >> 16));
+}
+
+void
+legacy_crtc_dpms(xf86CrtcPtr crtc, int mode)
+{
+    int mask;
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    mask = radeon_crtc->crtc_id ? (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_REQ_EN_B) : (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS);
+
+
+    switch(mode) {
+    case DPMSModeOn:
+	if (radeon_crtc->crtc_id) {
+	    OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask);
+	} else {
+	    OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
+	    OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask);
+	}
+	break;
+    case DPMSModeStandby:
+	if (radeon_crtc->crtc_id) {
+	    OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), ~mask);
+	} else {
+	    OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
+	    OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS), ~mask);
+	}
+	break;
+    case DPMSModeSuspend:
+	if (radeon_crtc->crtc_id) {
+	    OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), ~mask);
+	} else {
+	    OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
+	    OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS), ~mask);
+	}
+	break;
+    case DPMSModeOff:
+	if (radeon_crtc->crtc_id) {
+	    OUTREGP(RADEON_CRTC2_GEN_CNTL, mask, ~mask);
+	} else {
+	    OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~RADEON_CRTC_DISP_REQ_EN_B);
+	    OUTREGP(RADEON_CRTC_EXT_CNTL, mask, ~mask);
+	}
+	break;
+    }
+  
+    if (mode != DPMSModeOff)
+	radeon_crtc_load_lut(crtc);
+}
+
+
+/* Define common registers for requested video mode */
+static void
+RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info)
+{
+    save->ovr_clr            = 0;
+    save->ovr_wid_left_right = 0;
+    save->ovr_wid_top_bottom = 0;
+    save->ov0_scale_cntl     = 0;
+    save->subpic_cntl        = 0;
+    save->viph_control       = 0;
+    save->i2c_cntl_1         = 0;
+    save->rbbm_soft_reset    = 0;
+    save->cap0_trig_cntl     = 0;
+    save->cap1_trig_cntl     = 0;
+    save->bus_cntl           = info->BusCntl;
+    /*
+     * If bursts are enabled, turn on discards
+     * Radeon doesn't have write bursts
+     */
+    if (save->bus_cntl & (RADEON_BUS_READ_BURST))
+	save->bus_cntl |= RADEON_BUS_RD_DISCARD_EN;
+}
+
+static void
+RADEONInitSurfaceCntl(xf86CrtcPtr crtc, RADEONSavePtr save)
+{
+    save->surface_cntl = 0;
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+    /* We must set both apertures as they can be both used to map the entire
+     * video memory. -BenH.
+     */
+    switch (crtc->scrn->bitsPerPixel) {
+    case 16:
+	save->surface_cntl |= RADEON_NONSURF_AP0_SWP_16BPP;
+	save->surface_cntl |= RADEON_NONSURF_AP1_SWP_16BPP;
+	break;
+
+    case 32:
+	save->surface_cntl |= RADEON_NONSURF_AP0_SWP_32BPP;
+	save->surface_cntl |= RADEON_NONSURF_AP1_SWP_32BPP;
+	break;
+    }
+#endif
+
+}
+
+
+static Bool
+RADEONInitCrtcBase(xf86CrtcPtr crtc, RADEONSavePtr save,
+		   int x, int y)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    int    Base;
+#ifdef XF86DRI
+    RADEONSAREAPrivPtr pSAREAPriv;
+    XF86DRISAREAPtr pSAREA;
+#endif
+
+    save->crtc_offset      = pScrn->fbOffset;
+#ifdef XF86DRI
+    if (info->allowPageFlip)
+	save->crtc_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
+    else
+#endif
+	save->crtc_offset_cntl = 0;
+
+    if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
+       if (IS_R300_VARIANT)
+          save->crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
+				     R300_CRTC_MICRO_TILE_BUFFER_DIS |
+				     R300_CRTC_MACRO_TILE_EN);
+       else
+          save->crtc_offset_cntl |= RADEON_CRTC_TILE_EN;
+    }
+    else {
+       if (IS_R300_VARIANT)
+          save->crtc_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
+				      R300_CRTC_MICRO_TILE_BUFFER_DIS |
+				      R300_CRTC_MACRO_TILE_EN);
+       else
+          save->crtc_offset_cntl &= ~RADEON_CRTC_TILE_EN;
+    }
+
+    Base = pScrn->fbOffset;
+
+    if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
+        if (IS_R300_VARIANT) {
+	/* On r300/r400 when tiling is enabled crtc_offset is set to the address of
+	 * the surface.  the x/y offsets are handled by the X_Y tile reg for each crtc
+	 * Makes tiling MUCH easier.
+	 */
+             save->crtc_tile_x0_y0 = x | (y << 16);
+             Base &= ~0x7ff;
+         } else {
+	     /* note we cannot really simply use the info->ModeReg.crtc_offset_cntl value, since the
+		drm might have set FLIP_CNTL since we wrote that. Unfortunately FLIP_CNTL causes
+		flickering when scrolling vertically in a virtual screen, possibly because crtc will
+		pick up the new offset value at the end of each scanline, but the new offset_cntl value
+		only after a vsync. We'd probably need to wait (in drm) for vsync and only then update
+		OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */
+	     /*save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL) & ~0xf;*/
+#if 0
+	     /* try to get rid of flickering when scrolling at least for 2d */
+#ifdef XF86DRI
+	     if (!info->have3DWindows)
+#endif
+		 save->crtc_offset_cntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
+#endif
+	     
+             int byteshift = info->CurrentLayout.bitsPerPixel >> 4;
+             /* crtc uses 256(bytes)x8 "half-tile" start addresses? */
+             int tile_addr = (((y >> 3) * info->CurrentLayout.displayWidth + x) >> (8 - byteshift)) << 11;
+             Base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
+             save->crtc_offset_cntl = save->crtc_offset_cntl | (y % 16);
+         }
+    }
+    else {
+       int offset = y * info->CurrentLayout.displayWidth + x;
+       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 */
+
+
+#ifdef XF86DRI
+    if (info->directRenderingInited) {
+	/* note cannot use pScrn->pScreen since this is unitialized when called from
+	   RADEONScreenInit, and we need to call from there to get mergedfb + pageflip working */
+        /*** NOTE: r3/4xx will need sarea and drm pageflip updates to handle the xytile regs for
+	 *** pageflipping!
+	 ***/
+	pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
+	/* can't get at sarea in a semi-sane way? */
+	pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
+
+	pSAREA->frame.x = (Base  / info->CurrentLayout.pixel_bytes)
+	    % info->CurrentLayout.displayWidth;
+	pSAREA->frame.y = (Base / info->CurrentLayout.pixel_bytes)
+	    / info->CurrentLayout.displayWidth;
+	pSAREA->frame.width = pScrn->frameX1 - x + 1;
+	pSAREA->frame.height = pScrn->frameY1 - y + 1;
+
+	if (pSAREAPriv->pfCurrentPage == 1) {
+	    Base += info->backOffset - info->frontOffset;
+	}
+    }
+#endif
+    save->crtc_offset = Base;
+
+    return TRUE;
+
+}
+
+/* Define CRTC registers for requested video mode */
+static Bool
+RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save,
+			DisplayModePtr mode)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    int    format;
+    int    hsync_start;
+    int    hsync_wid;
+    int    vsync_wid;
+
+    switch (info->CurrentLayout.pixel_code) {
+    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;
+    }
+
+    /*save->bios_4_scratch = info->SavedReg->bios_4_scratch;*/
+    save->crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN
+			   | RADEON_CRTC_EN
+			   | (format << 8)
+			   | ((mode->Flags & V_DBLSCAN)
+			      ? RADEON_CRTC_DBL_SCAN_EN
+			      : 0)
+			   | ((mode->Flags & V_CSYNC)
+			      ? RADEON_CRTC_CSYNC_EN
+			      : 0)
+			   | ((mode->Flags & V_INTERLACE)
+			      ? RADEON_CRTC_INTERLACE_EN
+			      : 0));
+
+    save->crtc_ext_cntl |= (RADEON_XCRT_CNT_EN|
+			    RADEON_CRTC_VSYNC_DIS |
+			    RADEON_CRTC_HSYNC_DIS |
+			    RADEON_CRTC_DISPLAY_DIS);
+
+    save->disp_merge_cntl = info->SavedReg->disp_merge_cntl;
+    save->disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
+
+    save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
+			       | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff)
+				  << 16));
+
+    hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
+    if (!hsync_wid)       hsync_wid = 1;
+    hsync_start = mode->CrtcHSyncStart - 8;
+
+    save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff)
+				  | ((hsync_wid & 0x3f) << 16)
+				  | ((mode->Flags & V_NHSYNC)
+				     ? RADEON_CRTC_H_SYNC_POL
+				     : 0));
+
+				/* This works for double scan mode. */
+    save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
+			       | ((mode->CrtcVDisplay - 1) << 16));
+
+    vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+    if (!vsync_wid)       vsync_wid = 1;
+
+    save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
+				  | ((vsync_wid & 0x1f) << 16)
+				  | ((mode->Flags & V_NVSYNC)
+				     ? RADEON_CRTC_V_SYNC_POL
+				     : 0));
+
+    save->crtc_pitch  = (((pScrn->displayWidth * pScrn->bitsPerPixel) +
+			  ((pScrn->bitsPerPixel * 8) -1)) /
+			 (pScrn->bitsPerPixel * 8));
+    save->crtc_pitch |= save->crtc_pitch << 16;
+
+    if (info->IsDellServer) {
+	save->dac2_cntl = info->SavedReg->dac2_cntl;
+	save->tv_dac_cntl = info->SavedReg->tv_dac_cntl;
+	save->crtc2_gen_cntl = info->SavedReg->crtc2_gen_cntl;
+	save->disp_hw_debug = info->SavedReg->disp_hw_debug;
+
+	save->dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL;
+	save->dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
+
+	/* For CRT on DAC2, don't turn it on if BIOS didn't
+	   enable it, even it's detected.
+	*/
+	save->disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
+	save->tv_dac_cntl &= ~((1<<2) | (3<<8) | (7<<24) | (0xff<<16));
+	save->tv_dac_cntl |= (0x03 | (2<<8) | (0x58<<16));
+    }
+
+    return TRUE;
+}
+
+
+static Bool
+RADEONInitCrtc2Base(xf86CrtcPtr crtc, RADEONSavePtr save,
+		    int x, int y)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    int    Base;
+#ifdef XF86DRI
+    RADEONSAREAPrivPtr pSAREAPriv;
+    XF86DRISAREAPtr pSAREA;
+#endif
+
+    /* It seems all fancy options apart from pflip can be safely disabled
+     */
+    save->crtc2_offset      = pScrn->fbOffset;
+#ifdef XF86DRI
+    if (info->allowPageFlip)
+	save->crtc2_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
+    else
+#endif
+	save->crtc2_offset_cntl = 0;
+
+    if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
+       if (IS_R300_VARIANT)
+          save->crtc2_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
+				      R300_CRTC_MICRO_TILE_BUFFER_DIS |
+				      R300_CRTC_MACRO_TILE_EN);
+       else
+          save->crtc2_offset_cntl |= RADEON_CRTC_TILE_EN;
+    }
+    else {
+       if (IS_R300_VARIANT)
+          save->crtc2_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
+				      R300_CRTC_MICRO_TILE_BUFFER_DIS |
+				      R300_CRTC_MACRO_TILE_EN);
+       else
+          save->crtc2_offset_cntl &= ~RADEON_CRTC_TILE_EN;
+    }
+
+    Base = pScrn->fbOffset;
+
+    if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
+        if (IS_R300_VARIANT) {
+	/* On r300/r400 when tiling is enabled crtc_offset is set to the address of
+	 * the surface.  the x/y offsets are handled by the X_Y tile reg for each crtc
+	 * Makes tiling MUCH easier.
+	 */
+             save->crtc2_tile_x0_y0 = x | (y << 16);
+             Base &= ~0x7ff;
+         } else {
+	     /* note we cannot really simply use the info->ModeReg.crtc_offset_cntl value, since the
+		drm might have set FLIP_CNTL since we wrote that. Unfortunately FLIP_CNTL causes
+		flickering when scrolling vertically in a virtual screen, possibly because crtc will
+		pick up the new offset value at the end of each scanline, but the new offset_cntl value
+		only after a vsync. We'd probably need to wait (in drm) for vsync and only then update
+		OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */
+	     /*save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL) & ~0xf;*/
+#if 0
+	     /* try to get rid of flickering when scrolling at least for 2d */
+#ifdef XF86DRI
+	     if (!info->have3DWindows)
+#endif
+		 save->crtc2_offset_cntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
+#endif
+
+             int byteshift = info->CurrentLayout.bitsPerPixel >> 4;
+             /* crtc uses 256(bytes)x8 "half-tile" start addresses? */
+             int tile_addr = (((y >> 3) * info->CurrentLayout.displayWidth + x) >> (8 - byteshift)) << 11;
+             Base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
+             save->crtc2_offset_cntl = save->crtc_offset_cntl | (y % 16);
+         }
+    }
+    else {
+       int offset = y * info->CurrentLayout.displayWidth + x;
+       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 */
+
+#ifdef XF86DRI
+    if (info->directRenderingInited) {
+	/* note cannot use pScrn->pScreen since this is unitialized when called from
+	   RADEONScreenInit, and we need to call from there to get mergedfb + pageflip working */
+        /*** NOTE: r3/4xx will need sarea and drm pageflip updates to handle the xytile regs for
+	 *** pageflipping!
+	 ***/
+	pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
+	/* can't get at sarea in a semi-sane way? */
+	pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
+
+	pSAREAPriv->crtc2_base = Base;
+
+	if (pSAREAPriv->pfCurrentPage == 1) {
+	    Base += info->backOffset - info->frontOffset;
+	}
+    }
+#endif
+    save->crtc2_offset = Base;
+
+    return TRUE;
+}
+
+
+/* Define CRTC2 registers for requested video mode */
+static Bool
+RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save,
+			 DisplayModePtr mode)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    int    format;
+    int    hsync_start;
+    int    hsync_wid;
+    int    vsync_wid;
+
+    switch (info->CurrentLayout.pixel_code) {
+    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;
+    }
+
+    save->crtc2_h_total_disp =
+	((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
+	 | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff) << 16));
+
+    hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
+    if (!hsync_wid)       hsync_wid = 1;
+    hsync_start = mode->CrtcHSyncStart - 8;
+
+    save->crtc2_h_sync_strt_wid = ((hsync_start & 0x1fff)
+				   | ((hsync_wid & 0x3f) << 16)
+				   | ((mode->Flags & V_NHSYNC)
+				      ? RADEON_CRTC_H_SYNC_POL
+				      : 0));
+
+				/* This works for double scan mode. */
+    save->crtc2_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
+				| ((mode->CrtcVDisplay - 1) << 16));
+
+    vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+    if (!vsync_wid)       vsync_wid = 1;
+
+    save->crtc2_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
+				   | ((vsync_wid & 0x1f) << 16)
+				   | ((mode->Flags & V_NVSYNC)
+				      ? RADEON_CRTC2_V_SYNC_POL
+				      : 0));
+
+    save->crtc2_pitch  = ((pScrn->displayWidth * pScrn->bitsPerPixel) +
+			  ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8);
+    save->crtc2_pitch |= save->crtc2_pitch << 16;
+
+    /* check to see if TV DAC is enabled for another crtc and keep it enabled */
+    if (save->crtc2_gen_cntl & RADEON_CRTC2_CRT2_ON)
+	save->crtc2_gen_cntl = RADEON_CRTC2_CRT2_ON;
+    else
+	save->crtc2_gen_cntl = 0;
+
+    save->crtc2_gen_cntl |= (RADEON_CRTC2_EN
+			     | (format << 8)
+			     | RADEON_CRTC2_VSYNC_DIS
+			     | RADEON_CRTC2_HSYNC_DIS
+			     | RADEON_CRTC2_DISP_DIS
+			     | ((mode->Flags & V_DBLSCAN)
+				? RADEON_CRTC2_DBL_SCAN_EN
+				: 0)
+			     | ((mode->Flags & V_CSYNC)
+				? RADEON_CRTC2_CSYNC_EN
+				: 0)
+			     | ((mode->Flags & V_INTERLACE)
+				? RADEON_CRTC2_INTERLACE_EN
+				: 0));
+
+    save->disp2_merge_cntl = info->SavedReg->disp2_merge_cntl;
+    save->disp2_merge_cntl &= ~(RADEON_DISP2_RGB_OFFSET_EN);
+
+    save->fp_h2_sync_strt_wid = save->crtc2_h_sync_strt_wid;
+    save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;
+
+    if (info->ChipFamily == CHIP_FAMILY_RS400) {
+	save->rs480_unk_e30 = 0x105DC1CC; /* because I'm worth it */
+	save->rs480_unk_e34 = 0x2749D000; /* AMD really should */
+	save->rs480_unk_e38 = 0x29ca71dc; /* release docs */
+	save->rs480_unk_e3c = 0x28FBC3AC; /* this is so a trade secret */
+    }
+
+    return TRUE;
+}
+
+
+/* Define PLL registers for requested video mode */
+static void
+RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
+		       RADEONPLLPtr pll, DisplayModePtr mode,
+		       int flags)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    CARD32 feedback_div = 0;
+    CARD32 reference_div = 0;
+    CARD32 post_divider = 0;
+    CARD32 freq = 0;
+
+    struct {
+	int divider;
+	int bitvalue;
+    } *post_div, post_divs[]   = {
+				/* From RAGE 128 VR/RAGE 128 GL Register
+				 * Reference Manual (Technical Reference
+				 * Manual P/N RRG-G04100-C Rev. 0.04), page
+				 * 3-17 (PLL_DIV_[3:0]).
+				 */
+	{  1, 0 },              /* VCLK_SRC                 */
+	{  2, 1 },              /* VCLK_SRC/2               */
+	{  4, 2 },              /* VCLK_SRC/4               */
+	{  8, 3 },              /* VCLK_SRC/8               */
+	{  3, 4 },              /* VCLK_SRC/3               */
+	{ 16, 5 },              /* VCLK_SRC/16              */
+	{  6, 6 },              /* VCLK_SRC/6               */
+	{ 12, 7 },              /* VCLK_SRC/12              */
+	{  0, 0 }
+    };
+
+
+    if ((flags & RADEON_PLL_USE_BIOS_DIVS) && info->UseBiosDividers) {
+       save->ppll_ref_div = info->RefDivider;
+       save->ppll_div_3   = info->FeedbackDivider | (info->PostDivider << 16);
+       save->htotal_cntl  = 0;
+       return;
+    }
+
+    RADEONComputePLL(pll, mode->Clock, &freq, &feedback_div, &reference_div, &post_divider, flags);
+
+    for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
+	if (post_div->divider == post_divider)
+	    break;
+    }
+
+    if (!post_div->divider) {
+	save->pll_output_freq = freq;
+	post_div = &post_divs[0];
+    }
+
+    save->dot_clock_freq = freq;
+    save->feedback_div   = feedback_div;
+    save->reference_div  = reference_div;
+    save->post_div       = post_divider;
+
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "dc=%u, of=%u, fd=%d, rd=%d, pd=%d\n",
+		   (unsigned)save->dot_clock_freq,
+		   (unsigned)save->pll_output_freq,
+		   save->feedback_div,
+		   save->reference_div,
+		   save->post_div);
+
+    save->ppll_ref_div   = save->reference_div;
+
+#if defined(__powerpc__)
+    /* apparently programming this otherwise causes a hang??? */
+    if (info->MacModel == RADEON_MAC_IBOOK)
+	save->ppll_div_3 = 0x000600ad;
+    else
+#endif
+    save->ppll_div_3     = (save->feedback_div | (post_div->bitvalue << 16));
+
+    save->htotal_cntl    = mode->HTotal & 0x7;
+
+    save->vclk_ecp_cntl = (info->SavedReg->vclk_ecp_cntl &
+	    ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
+}
+
+/* Define PLL2 registers for requested video mode */
+static void
+RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
+			RADEONPLLPtr pll, DisplayModePtr mode,
+			int flags)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    CARD32 feedback_div = 0;
+    CARD32 reference_div = 0;
+    CARD32 post_divider = 0;
+    CARD32 freq = 0;
+
+    struct {
+	int divider;
+	int bitvalue;
+    } *post_div, post_divs[]   = {
+				/* From RAGE 128 VR/RAGE 128 GL Register
+				 * Reference Manual (Technical Reference
+				 * Manual P/N RRG-G04100-C Rev. 0.04), page
+				 * 3-17 (PLL_DIV_[3:0]).
+				 */
+	{  1, 0 },              /* VCLK_SRC                 */
+	{  2, 1 },              /* VCLK_SRC/2               */
+	{  4, 2 },              /* VCLK_SRC/4               */
+	{  8, 3 },              /* VCLK_SRC/8               */
+	{  3, 4 },              /* VCLK_SRC/3               */
+	{  6, 6 },              /* VCLK_SRC/6               */
+	{ 12, 7 },              /* VCLK_SRC/12              */
+	{  0, 0 }
+    };
+
+    if ((flags & RADEON_PLL_USE_BIOS_DIVS) && info->UseBiosDividers) {
+       save->p2pll_ref_div = info->RefDivider;
+       save->p2pll_div_0   = info->FeedbackDivider | (info->PostDivider << 16);
+       save->htotal_cntl2  = 0;
+       return;
+    }
+
+    RADEONComputePLL(pll, mode->Clock, &freq, &feedback_div, &reference_div, &post_divider, flags);
+
+    for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
+	if (post_div->divider == post_divider)
+	    break;
+    }
+
+    if (!post_div->divider) {
+	save->pll_output_freq_2 = freq;
+	post_div = &post_divs[0];
+    }
+
+    save->dot_clock_freq_2 = freq;
+    save->feedback_div_2   = feedback_div;
+    save->reference_div_2  = reference_div;
+    save->post_div_2       = post_divider;
+
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "dc=%u, of=%u, fd=%d, rd=%d, pd=%d\n",
+		   (unsigned)save->dot_clock_freq_2,
+		   (unsigned)save->pll_output_freq_2,
+		   save->feedback_div_2,
+		   save->reference_div_2,
+		   save->post_div_2);
+
+    save->p2pll_ref_div    = save->reference_div_2;
+
+    save->p2pll_div_0      = (save->feedback_div_2 |
+			      (post_div->bitvalue << 16));
+
+    save->htotal_cntl2     = mode->HTotal & 0x7;
+
+    save->pixclks_cntl     = ((info->SavedReg->pixclks_cntl &
+			       ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
+			      RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
+}
+
+static void
+RADEONInitBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+    RADEONInfoPtr  info      = RADEONPTR(pScrn);
+
+    /* tell the bios not to muck with the hardware on events */
+    save->bios_4_scratch = 0x4; /* 0x4 needed for backlight */
+    save->bios_5_scratch = (info->SavedReg->bios_5_scratch & 0xff) | 0xff00; /* bits 0-3 keep backlight level */
+    save->bios_6_scratch = info->SavedReg->bios_6_scratch | 0x40000000;
+
+}
+
+static void
+radeon_update_tv_routing(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    /* pixclks_cntl controls tv clock routing */
+    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, restore->pixclks_cntl);
+}
+
+/* Calculate display buffer watermark to prevent buffer underflow */
+static void
+RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2, DisplayModePtr mode1, DisplayModePtr mode2)
+{
+    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    CARD32 temp, data, mem_trcd, mem_trp, mem_tras, mem_trbs=0;
+    float mem_tcas;
+    int k1, c;
+    CARD32 MemTrcdExtMemCntl[4]     = {1, 2, 3, 4};
+    CARD32 MemTrpExtMemCntl[4]      = {1, 2, 3, 4};
+    CARD32 MemTrasExtMemCntl[8]     = {1, 2, 3, 4, 5, 6, 7, 8};
+
+    CARD32 MemTrcdMemTimingCntl[8]     = {1, 2, 3, 4, 5, 6, 7, 8};
+    CARD32 MemTrpMemTimingCntl[8]      = {1, 2, 3, 4, 5, 6, 7, 8};
+    CARD32 MemTrasMemTimingCntl[16]    = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
+
+    float MemTcas[8]  = {0, 1, 2, 3, 0, 1.5, 2.5, 0};
+    float MemTcas2[8] = {0, 1, 2, 3, 4, 5, 6, 7};
+    float MemTrbs[8]  = {1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5};
+
+    float mem_bw, peak_disp_bw;
+    float min_mem_eff = 0.8;
+    float sclk_eff, sclk_delay;
+    float mc_latency_mclk, mc_latency_sclk, cur_latency_mclk, cur_latency_sclk;
+    float disp_latency, disp_latency_overhead, disp_drain_rate, disp_drain_rate2;
+    float pix_clk, pix_clk2; /* in MHz */
+    int cur_size = 16;       /* in octawords */
+    int critical_point, critical_point2;
+    int stop_req, max_stop_req;
+    float read_return_rate, time_disp1_drop_priority;
+
+    /*
+     * Set display0/1 priority up on r3/4xx in the memory controller for
+     * high res modes if the user specifies HIGH for displaypriority
+     * option.
+     */
+    if ((info->DispPriority == 2) && IS_R300_VARIANT) {
+	CARD32 mc_init_misc_lat_timer = INREG(R300_MC_INIT_MISC_LAT_TIMER);
+	if (pRADEONEnt->pCrtc[1]->enabled) {
+	    mc_init_misc_lat_timer |= 0x1100; /* display 0 and 1 */
+	} else {
+	    mc_init_misc_lat_timer |= 0x0100; /* display 0 only */
+	}
+	OUTREG(R300_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer);
+    }
+
+
+    /* R420 and RV410 family not supported yet */
+    if (info->ChipFamily == CHIP_FAMILY_R420 || info->ChipFamily == CHIP_FAMILY_RV410) return; 
+
+    /*
+     * Determine if there is enough bandwidth for current display mode
+     */
+    mem_bw = info->mclk * (info->RamWidth / 8) * (info->IsDDR ? 2 : 1);
+
+    pix_clk = mode1->Clock/1000.0;
+    if (mode2)
+	pix_clk2 = mode2->Clock/1000.0;
+    else
+	pix_clk2 = 0;
+
+    peak_disp_bw = (pix_clk * info->CurrentLayout.pixel_bytes);
+    if (pixel_bytes2)
+      peak_disp_bw += (pix_clk2 * pixel_bytes2);
+
+    if (peak_disp_bw >= mem_bw * min_mem_eff) {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "You may not have enough display bandwidth for current mode\n"
+		   "If you have flickering problem, try to lower resolution, refresh rate, or color depth\n");
+    }
+
+    /*  CRTC1
+        Set GRPH_BUFFER_CNTL register using h/w defined optimal values.
+	GRPH_STOP_REQ <= MIN[ 0x7C, (CRTC_H_DISP + 1) * (bit depth) / 0x10 ]
+    */
+    stop_req = mode1->HDisplay * info->CurrentLayout.pixel_bytes / 16;
+
+    /* setup Max GRPH_STOP_REQ default value */
+    if (IS_RV100_VARIANT)
+	max_stop_req = 0x5c;
+    else
+	max_stop_req  = 0x7c;
+    if (stop_req > max_stop_req)
+	stop_req = max_stop_req;
+
+    /*  Get values from the EXT_MEM_CNTL register...converting its contents. */
+    temp = INREG(RADEON_MEM_TIMING_CNTL);
+    if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */
+	mem_trcd      = MemTrcdExtMemCntl[(temp & 0x0c) >> 2];
+	mem_trp       = MemTrpExtMemCntl[ (temp & 0x03) >> 0];
+	mem_tras      = MemTrasExtMemCntl[(temp & 0x70) >> 4];
+    } else { /* RV200 and later */
+	mem_trcd      = MemTrcdMemTimingCntl[(temp & 0x07) >> 0];
+	mem_trp       = MemTrpMemTimingCntl[ (temp & 0x700) >> 8];
+	mem_tras      = MemTrasMemTimingCntl[(temp & 0xf000) >> 12];
+    }
+
+    /* Get values from the MEM_SDRAM_MODE_REG register...converting its */
+    temp = INREG(RADEON_MEM_SDRAM_MODE_REG);
+    data = (temp & (7<<20)) >> 20;
+    if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */
+	mem_tcas = MemTcas [data];
+    } else {
+	mem_tcas = MemTcas2 [data];
+    }
+
+    if (IS_R300_VARIANT) {
+
+	/* on the R300, Tcas is included in Trbs.
+	*/
+	temp = INREG(RADEON_MEM_CNTL);
+	data = (R300_MEM_NUM_CHANNELS_MASK & temp);
+	if (data == 1) {
+	    if (R300_MEM_USE_CD_CH_ONLY & temp) {
+		temp  = INREG(R300_MC_IND_INDEX);
+		temp &= ~R300_MC_IND_ADDR_MASK;
+		temp |= R300_MC_READ_CNTL_CD_mcind;
+		OUTREG(R300_MC_IND_INDEX, temp);
+		temp  = INREG(R300_MC_IND_DATA);
+		data = (R300_MEM_RBS_POSITION_C_MASK & temp);
+	    } else {
+		temp = INREG(R300_MC_READ_CNTL_AB);
+		data = (R300_MEM_RBS_POSITION_A_MASK & temp);
+	    }
+	} else {
+	    temp = INREG(R300_MC_READ_CNTL_AB);
+	    data = (R300_MEM_RBS_POSITION_A_MASK & temp);
+	}
+
+	mem_trbs = MemTrbs[data];
+	mem_tcas += mem_trbs;
+    }
+
+    if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */
+	/* DDR64 SCLK_EFF = SCLK for analysis */
+	sclk_eff = info->sclk;
+    } else {
+#ifdef XF86DRI
+	if (info->directRenderingEnabled)
+	    sclk_eff = info->sclk - (info->agpMode * 50.0 / 3.0);
+	else
+#endif
+	    sclk_eff = info->sclk;
+    }
+
+    /* Find the memory controller latency for the display client.
+    */
+    if (IS_R300_VARIANT) {
+	/*not enough for R350 ???*/
+	/*
+	if (!mode2) sclk_delay = 150;
+	else {
+	    if (info->RamWidth == 256) sclk_delay = 87;
+	    else sclk_delay = 97;
+	}
+	*/
+	sclk_delay = 250;
+    } else {
+	if ((info->ChipFamily == CHIP_FAMILY_RV100) ||
+	    info->IsIGP) {
+	    if (info->IsDDR) sclk_delay = 41;
+	    else sclk_delay = 33;
+	} else {
+	    if (info->RamWidth == 128) sclk_delay = 57;
+	    else sclk_delay = 41;
+	}
+    }
+
+    mc_latency_sclk = sclk_delay / sclk_eff;
+
+    if (info->IsDDR) {
+	if (info->RamWidth == 32) {
+	    k1 = 40;
+	    c  = 3;
+	} else {
+	    k1 = 20;
+	    c  = 1;
+	}
+    } else {
+	k1 = 40;
+	c  = 3;
+    }
+    mc_latency_mclk = ((2.0*mem_trcd + mem_tcas*c + 4.0*mem_tras + 4.0*mem_trp + k1) /
+		       info->mclk) + (4.0 / sclk_eff);
+
+    /*
+      HW cursor time assuming worst case of full size colour cursor.
+    */
+    cur_latency_mclk = (mem_trp + MAX(mem_tras, (mem_trcd + 2*(cur_size - (info->IsDDR+1))))) / info->mclk;
+    cur_latency_sclk = cur_size / sclk_eff;
+
+    /*
+      Find the total latency for the display data.
+    */
+    disp_latency_overhead = 8.0 / info->sclk;
+    mc_latency_mclk = mc_latency_mclk + disp_latency_overhead + cur_latency_mclk;
+    mc_latency_sclk = mc_latency_sclk + disp_latency_overhead + cur_latency_sclk;
+    disp_latency = MAX(mc_latency_mclk, mc_latency_sclk);
+
+    /*
+      Find the drain rate of the display buffer.
+    */
+    disp_drain_rate = pix_clk / (16.0/info->CurrentLayout.pixel_bytes);
+    if (pixel_bytes2)
+	disp_drain_rate2 = pix_clk2 / (16.0/pixel_bytes2);
+    else
+	disp_drain_rate2 = 0;
+
+    /*
+      Find the critical point of the display buffer.
+    */
+    critical_point= (CARD32)(disp_drain_rate * disp_latency + 0.5);
+
+    /* ???? */
+    /*
+    temp = (info->SavedReg.grph_buffer_cntl & RADEON_GRPH_CRITICAL_POINT_MASK) >> RADEON_GRPH_CRITICAL_POINT_SHIFT;
+    if (critical_point < temp) critical_point = temp;
+    */
+    if (info->DispPriority == 2) {
+	critical_point = 0;
+    }
+
+    /*
+      The critical point should never be above max_stop_req-4.  Setting
+      GRPH_CRITICAL_CNTL = 0 will thus force high priority all the time.
+    */
+    if (max_stop_req - critical_point < 4) critical_point = 0;
+
+    if (critical_point == 0 && mode2 && info->ChipFamily == CHIP_FAMILY_R300) {
+	/* some R300 cards have problem with this set to 0, when CRTC2 is enabled.*/
+	critical_point = 0x10;
+    }
+
+    temp = info->SavedReg->grph_buffer_cntl;
+    temp &= ~(RADEON_GRPH_STOP_REQ_MASK);
+    temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT);
+    temp &= ~(RADEON_GRPH_START_REQ_MASK);
+    if ((info->ChipFamily == CHIP_FAMILY_R350) &&
+	(stop_req > 0x15)) {
+	stop_req -= 0x10;
+    }
+    temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT);
+
+    temp |= RADEON_GRPH_BUFFER_SIZE;
+    temp &= ~(RADEON_GRPH_CRITICAL_CNTL   |
+	      RADEON_GRPH_CRITICAL_AT_SOF |
+	      RADEON_GRPH_STOP_CNTL);
+    /*
+      Write the result into the register.
+    */
+    OUTREG(RADEON_GRPH_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
+				     (critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
+
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "GRPH_BUFFER_CNTL from %x to %x\n",
+		   (unsigned int)info->SavedReg->grph_buffer_cntl,
+		   (unsigned int)INREG(RADEON_GRPH_BUFFER_CNTL));
+
+    if (mode2) {
+	stop_req = mode2->HDisplay * pixel_bytes2 / 16;
+
+	if (stop_req > max_stop_req) stop_req = max_stop_req;
+
+	temp = info->SavedReg->grph2_buffer_cntl;
+	temp &= ~(RADEON_GRPH_STOP_REQ_MASK);
+	temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT);
+	temp &= ~(RADEON_GRPH_START_REQ_MASK);
+	if ((info->ChipFamily == CHIP_FAMILY_R350) &&
+	    (stop_req > 0x15)) {
+	    stop_req -= 0x10;
+	}
+	temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT);
+	temp |= RADEON_GRPH_BUFFER_SIZE;
+	temp &= ~(RADEON_GRPH_CRITICAL_CNTL   |
+		  RADEON_GRPH_CRITICAL_AT_SOF |
+		  RADEON_GRPH_STOP_CNTL);
+
+	if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS200))
+	    critical_point2 = 0;
+	else {
+	    read_return_rate = MIN(info->sclk, info->mclk*(info->RamWidth*(info->IsDDR+1)/128));
+	    time_disp1_drop_priority = critical_point / (read_return_rate - disp_drain_rate);
+
+	    critical_point2 = (CARD32)((disp_latency + time_disp1_drop_priority + 
+					disp_latency) * disp_drain_rate2 + 0.5);
+
+	    if (info->DispPriority == 2) {
+		critical_point2 = 0;
+	    }
+
+	    if (max_stop_req - critical_point2 < 4) critical_point2 = 0;
+
+	}
+
+	if (critical_point2 == 0 && info->ChipFamily == CHIP_FAMILY_R300) {
+	    /* some R300 cards have problem with this set to 0 */
+	    critical_point2 = 0x10;
+	}
+
+	OUTREG(RADEON_GRPH2_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
+					  (critical_point2 << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
+
+	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "GRPH2_BUFFER_CNTL from %x to %x\n",
+		       (unsigned int)info->SavedReg->grph2_buffer_cntl,
+		       (unsigned int)INREG(RADEON_GRPH2_BUFFER_CNTL));
+    }
+}
+
+void
+RADEONInitDispBandwidth(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    DisplayModePtr mode1, mode2;
+    int pixel_bytes2 = 0;
+
+    if (info->IsPrimary || info->IsSecondary)
+	mode1 = &xf86_config->crtc[0]->mode;
+    else
+	mode1 = info->CurrentLayout.mode;
+    mode2 = NULL;
+    pixel_bytes2 = info->CurrentLayout.pixel_bytes;
+
+    if (xf86_config->num_crtc == 2) {
+      pixel_bytes2 = 0;
+      mode2 = NULL;
+
+      if (xf86_config->crtc[1]->enabled && xf86_config->crtc[0]->enabled) {
+	pixel_bytes2 = info->CurrentLayout.pixel_bytes;
+	mode1 = &xf86_config->crtc[0]->mode;
+	mode2 = &xf86_config->crtc[1]->mode;
+      } else if (xf86_config->crtc[0]->enabled) {
+	mode1 = &xf86_config->crtc[0]->mode;
+      } else if (xf86_config->crtc[1]->enabled) {
+	mode1 = &xf86_config->crtc[1]->mode;
+      } else
+	return;
+    } else {
+	if (xf86_config->crtc[0]->enabled)
+	    mode1 = &xf86_config->crtc[0]->mode;
+	else
+	    return;
+    }
+
+    RADEONInitDispBandwidth2(pScrn, info, pixel_bytes2, mode1, mode2);
+}
+
+void
+legacy_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);
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    Bool           tilingOld   = info->tilingEnabled;
+    int i = 0;
+    double dot_clock = 0;
+    int pll_flags = RADEON_PLL_LEGACY;
+    Bool update_tv_routing = FALSE;
+
+
+    if (info->allowColorTiling) {
+	info->tilingEnabled = (adjusted_mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
+#ifdef XF86DRI
+	if (info->directRenderingEnabled && (info->tilingEnabled != tilingOld)) {
+	    RADEONSAREAPrivPtr pSAREAPriv;
+	    if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_SWITCH_TILING, (info->tilingEnabled ? 1 : 0)) < 0)
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "[drm] failed changing tiling status\n");
+	    /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
+	    pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
+	    info->tilingEnabled = pSAREAPriv->tiling_enabled ? TRUE : FALSE;
+	}
+#endif
+    }
+
+    for (i = 0; i < xf86_config->num_output; i++) {
+	xf86OutputPtr output = xf86_config->output[i];
+	RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+	if (output->crtc == crtc) {
+	    if (radeon_output->MonType != MT_CRT)
+		pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
+	    if (radeon_output->MonType == MT_LCD)
+		pll_flags |= (RADEON_PLL_USE_BIOS_DIVS | RADEON_PLL_USE_REF_DIV);
+	}
+    }
+
+    if (info->IsMobility)
+	RADEONInitBIOSRegisters(pScrn, info->ModeReg);
+
+    ErrorF("init memmap\n");
+    RADEONInitMemMapRegisters(pScrn, info->ModeReg, info);
+    ErrorF("init common\n");
+    RADEONInitCommonRegisters(info->ModeReg, info);
+
+    RADEONInitSurfaceCntl(crtc, info->ModeReg);
+
+    switch (radeon_crtc->crtc_id) {
+    case 0:
+	ErrorF("init crtc1\n");
+	RADEONInitCrtcRegisters(crtc, info->ModeReg, adjusted_mode);
+	RADEONInitCrtcBase(crtc, info->ModeReg, x, y);
+	dot_clock = adjusted_mode->Clock / 1000.0;
+	if (dot_clock) {
+	    ErrorF("init pll1\n");
+	    RADEONInitPLLRegisters(pScrn, info->ModeReg, &info->pll, adjusted_mode, pll_flags);
+	} 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;
+	}
+	break;
+    case 1:
+	ErrorF("init crtc2\n");
+	RADEONInitCrtc2Registers(crtc, info->ModeReg, adjusted_mode);
+	RADEONInitCrtc2Base(crtc, info->ModeReg, x, y);
+	dot_clock = adjusted_mode->Clock / 1000.0;
+	if (dot_clock) {
+	    ErrorF("init pll2\n");
+	    RADEONInitPLL2Registers(pScrn, info->ModeReg, &info->pll, adjusted_mode, pll_flags);
+	}
+	break;
+    }
+
+    for (i = 0; i < xf86_config->num_output; i++) {
+	xf86OutputPtr output = xf86_config->output[i];
+	RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+	if (output->crtc == crtc) {
+	    if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
+		switch (radeon_crtc->crtc_id) {
+		case 0:
+		    RADEONAdjustCrtcRegistersForTV(pScrn, info->ModeReg, adjusted_mode, output);
+		    RADEONAdjustPLLRegistersForTV(pScrn, info->ModeReg, adjusted_mode, output);
+		    update_tv_routing = TRUE;
+		    break;
+		case 1:
+		    RADEONAdjustCrtc2RegistersForTV(pScrn, info->ModeReg, adjusted_mode, output);
+		    RADEONAdjustPLL2RegistersForTV(pScrn, info->ModeReg, adjusted_mode, output);
+		    break;
+		}
+	    }
+	}
+    }
+
+    if (info->IsMobility)
+	RADEONRestoreBIOSRegisters(pScrn, info->ModeReg);
+
+    ErrorF("restore memmap\n");
+    RADEONRestoreMemMapRegisters(pScrn, info->ModeReg);
+    ErrorF("restore common\n");
+    RADEONRestoreCommonRegisters(pScrn, info->ModeReg);
+
+    switch (radeon_crtc->crtc_id) {
+    case 0:
+	ErrorF("restore crtc1\n");
+	RADEONRestoreCrtcRegisters(pScrn, info->ModeReg);
+	ErrorF("restore pll1\n");
+	RADEONRestorePLLRegisters(pScrn, info->ModeReg);
+	break;
+    case 1:
+	ErrorF("restore crtc2\n");
+	RADEONRestoreCrtc2Registers(pScrn, info->ModeReg);
+	ErrorF("restore pll2\n");
+	RADEONRestorePLL2Registers(pScrn, info->ModeReg);
+	break;
+    }
+
+    /* pixclks_cntl handles tv-out clock routing */
+    if (update_tv_routing)
+	radeon_update_tv_routing(pScrn, info->ModeReg);
+
+    if (info->DispPriority)
+        RADEONInitDispBandwidth(pScrn);
+
+    if (info->tilingEnabled != tilingOld) {
+	/* need to redraw front buffer, I guess this can be considered a hack ? */
+	/* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
+	if (pScrn->pScreen)
+	    xf86EnableDisableFBAccess(pScrn->scrnIndex, FALSE);
+	RADEONChangeSurfaces(pScrn);
+	if (pScrn->pScreen)
+	    xf86EnableDisableFBAccess(pScrn->scrnIndex, TRUE);
+	/* xf86SetRootClip would do, but can't access that here */
+    }
+
+    /* reset ecp_div for Xv */
+    info->ecp_div = -1;
+
+}
+
diff --git a/src/legacy_output.c b/src/legacy_output.c
new file mode 100644
index 0000000..7ade772
--- /dev/null
+++ b/src/legacy_output.c
@@ -0,0 +1,1787 @@
+/*
+ * 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>
+
+/* X and server generic header files */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "vgaHW.h"
+#include "xf86Modes.h"
+
+/* Driver data structures */
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_macros.h"
+#include "radeon_probe.h"
+#include "radeon_version.h"
+#include "radeon_tv.h"
+#include "radeon_atombios.h"
+
+static RADEONMonitorType radeon_detect_tv(ScrnInfoPtr pScrn);
+static RADEONMonitorType radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color);
+static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color);
+static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn);
+
+void
+RADEONRestoreDACRegisters(ScrnInfoPtr pScrn,
+			  RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    if (IS_R300_VARIANT)
+	OUTREGP(RADEON_GPIOPAD_A, restore->gpiopad_a, ~1);
+
+    OUTREGP(RADEON_DAC_CNTL,
+	    restore->dac_cntl,
+	    RADEON_DAC_RANGE_CNTL |
+	    RADEON_DAC_BLANKING);
+
+    OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
+
+    if ((info->ChipFamily != CHIP_FAMILY_RADEON) &&
+    	(info->ChipFamily != CHIP_FAMILY_R200)) 
+    OUTREG (RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
+
+    OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl);
+
+    if ((info->ChipFamily == CHIP_FAMILY_R200) ||
+	IS_R300_VARIANT) {
+	OUTREG(RADEON_DISP_TV_OUT_CNTL, restore->disp_tv_out_cntl);
+    } else {
+	OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
+    }
+
+    OUTREG(RADEON_DAC_MACRO_CNTL, restore->dac_macro_cntl);
+
+    /* R200 DAC connected via DVO */
+    if (info->ChipFamily == CHIP_FAMILY_R200)
+	OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl);
+}
+
+
+/* Write TMDS registers */
+void
+RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    OUTREG(RADEON_TMDS_PLL_CNTL,        restore->tmds_pll_cntl);
+    OUTREG(RADEON_TMDS_TRANSMITTER_CNTL,restore->tmds_transmitter_cntl);
+    OUTREG(RADEON_FP_GEN_CNTL,          restore->fp_gen_cntl);
+
+    /* old AIW Radeon has some BIOS initialization problem
+     * with display buffer underflow, only occurs to DFP
+     */
+    if (!pRADEONEnt->HasCRTC2)
+	OUTREG(RADEON_GRPH_BUFFER_CNTL,
+	       INREG(RADEON_GRPH_BUFFER_CNTL) & ~0x7f0000);
+
+}
+
+/* Write FP2 registers */
+void
+RADEONRestoreFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    OUTREG(RADEON_FP2_GEN_CNTL,         restore->fp2_gen_cntl);
+
+}
+
+/* Write RMX registers */
+void
+RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    OUTREG(RADEON_FP_HORZ_STRETCH,      restore->fp_horz_stretch);
+    OUTREG(RADEON_FP_VERT_STRETCH,      restore->fp_vert_stretch);
+    OUTREG(RADEON_CRTC_MORE_CNTL,       restore->crtc_more_cntl);
+    OUTREG(RADEON_FP_HORZ_VERT_ACTIVE,  restore->fp_horz_vert_active);
+    OUTREG(RADEON_FP_H_SYNC_STRT_WID,   restore->fp_h_sync_strt_wid);
+    OUTREG(RADEON_FP_V_SYNC_STRT_WID,   restore->fp_v_sync_strt_wid);
+    OUTREG(RADEON_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp);
+    OUTREG(RADEON_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp);
+
+}
+
+/* Write LVDS registers */
+void
+RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    if (info->IsMobility) {
+	OUTREG(RADEON_LVDS_GEN_CNTL,  restore->lvds_gen_cntl);
+	/*OUTREG(RADEON_LVDS_PLL_CNTL,  restore->lvds_pll_cntl);*/
+
+	if (info->ChipFamily == CHIP_FAMILY_RV410) {
+	    OUTREG(RADEON_CLOCK_CNTL_INDEX, 0);
+	}
+    }
+
+}
+
+void
+RADEONRestoreBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 bios_5_scratch = INREG(RADEON_BIOS_5_SCRATCH);
+    CARD32 bios_6_scratch = INREG(RADEON_BIOS_6_SCRATCH);
+
+    OUTREG(RADEON_BIOS_4_SCRATCH, restore->bios_4_scratch);
+    bios_5_scratch &= 0xF;
+    bios_5_scratch |= (restore->bios_5_scratch & ~0xF);
+    OUTREG(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
+    if (restore->bios_6_scratch & 0x40000000)
+	bios_6_scratch |= 0x40000000;
+    else
+	bios_6_scratch &= ~0x40000000;
+    OUTREG(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
+
+}
+
+void
+RADEONSaveDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    save->dac_cntl              = INREG(RADEON_DAC_CNTL);
+    save->dac2_cntl             = INREG(RADEON_DAC_CNTL2);
+    save->tv_dac_cntl           = INREG(RADEON_TV_DAC_CNTL);
+    save->disp_output_cntl      = INREG(RADEON_DISP_OUTPUT_CNTL);
+    save->disp_tv_out_cntl      = INREG(RADEON_DISP_TV_OUT_CNTL);
+    save->disp_hw_debug         = INREG(RADEON_DISP_HW_DEBUG);
+    save->dac_macro_cntl        = INREG(RADEON_DAC_MACRO_CNTL);
+    save->gpiopad_a             = INREG(RADEON_GPIOPAD_A);
+
+}
+
+/* Read flat panel registers */
+void
+RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    save->fp_gen_cntl          = INREG(RADEON_FP_GEN_CNTL);
+    save->fp2_gen_cntl          = INREG (RADEON_FP2_GEN_CNTL);
+    save->fp_horz_stretch      = INREG(RADEON_FP_HORZ_STRETCH);
+    save->fp_vert_stretch      = INREG(RADEON_FP_VERT_STRETCH);
+    save->fp_horz_vert_active  = INREG(RADEON_FP_HORZ_VERT_ACTIVE);
+    save->crtc_more_cntl       = INREG(RADEON_CRTC_MORE_CNTL);
+    save->lvds_gen_cntl        = INREG(RADEON_LVDS_GEN_CNTL);
+    save->lvds_pll_cntl        = INREG(RADEON_LVDS_PLL_CNTL);
+    save->tmds_pll_cntl        = INREG(RADEON_TMDS_PLL_CNTL);
+    save->tmds_transmitter_cntl= INREG(RADEON_TMDS_TRANSMITTER_CNTL);
+
+    save->fp_h_sync_strt_wid   = INREG(RADEON_FP_H_SYNC_STRT_WID);
+    save->fp_v_sync_strt_wid   = INREG(RADEON_FP_V_SYNC_STRT_WID);
+    save->fp_crtc_h_total_disp = INREG(RADEON_FP_CRTC_H_TOTAL_DISP);
+    save->fp_crtc_v_total_disp = INREG(RADEON_FP_CRTC_V_TOTAL_DISP);
+
+    if (info->ChipFamily == CHIP_FAMILY_RV280) {
+	/* bit 22 of TMDS_PLL_CNTL is read-back inverted */
+	save->tmds_pll_cntl ^= (1 << 22);
+    }
+}
+
+Bool
+RADEONDVOReadByte(I2CDevPtr dvo, int addr, CARD8 *ch)
+{
+    if (!xf86I2CReadByte(dvo, addr, ch)) {
+	xf86DrvMsg(dvo->pI2CBus->scrnIndex, X_ERROR,
+		   "Unable to read from %s Slave %d.\n",
+		   dvo->pI2CBus->BusName, dvo->SlaveAddr);
+	return FALSE;
+    }
+    return TRUE;
+}
+
+Bool
+RADEONDVOWriteByte(I2CDevPtr dvo, int addr, CARD8 ch)
+{
+    if (!xf86I2CWriteByte(dvo, addr, ch)) {
+	xf86DrvMsg(dvo->pI2CBus->scrnIndex, X_ERROR,
+		   "Unable to write to %s Slave %d.\n",
+		   dvo->pI2CBus->BusName, dvo->SlaveAddr);
+	return FALSE;
+    }
+    return TRUE;
+}
+
+I2CDevPtr
+RADEONDVODeviceInit(I2CBusPtr b, I2CSlaveAddr addr)
+{
+    I2CDevPtr dvo;
+
+    dvo = xcalloc(1, sizeof(I2CDevRec));
+    if (dvo == NULL)
+	return NULL;
+
+    dvo->DevName = "RADEON DVO Controller";
+    dvo->SlaveAddr = addr;
+    dvo->pI2CBus = b;
+    dvo->StartTimeout = b->StartTimeout;
+    dvo->BitTimeout = b->BitTimeout;
+    dvo->AcknTimeout = b->AcknTimeout;
+    dvo->ByteTimeout = b->ByteTimeout;
+
+    if (xf86I2CDevInit(dvo)) {
+	return dvo;
+    }
+
+    xfree(dvo);
+    return NULL;
+}
+
+static void
+RADEONRestoreDVOChip(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    if (!radeon_output->DVOChip)
+	return;
+
+    OUTREG(radeon_output->dvo_i2c.mask_clk_reg,
+	   INREG(radeon_output->dvo_i2c.mask_clk_reg) &
+	   (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1));
+
+    if (!RADEONInitExtTMDSInfoFromBIOS(output)) {
+	if (radeon_output->DVOChip) {
+	    switch(info->ext_tmds_chip) {
+	    case RADEON_SIL_164:
+		RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x30);
+		RADEONDVOWriteByte(radeon_output->DVOChip, 0x09, 0x00);
+		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0a, 0x90);
+		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0c, 0x89);
+		RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x3b);
+		break;
+#if 0
+		/* needs work see bug 10418 */
+	    case RADEON_SIL_1178:
+		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0f, 0x44);
+		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0f, 0x4c);
+		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0e, 0x01);
+		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0a, 0x80);
+                RADEONDVOWriteByte(radeon_output->DVOChip, 0x09, 0x30);
+                RADEONDVOWriteByte(radeon_output->DVOChip, 0x0c, 0xc9);
+                RADEONDVOWriteByte(radeon_output->DVOChip, 0x0d, 0x70);
+                RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x32);
+                RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x33);
+		break;
+#endif
+	    default:
+		break;
+	    }
+	}
+    }
+}
+
+#if 0
+static RADEONMonitorType
+RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
+{
+    RADEONInfoPtr info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    int		  bConnected = 0;
+
+    /* the monitor either wasn't connected or it is a non-DDC CRT.
+     * try to probe it
+     */
+    if(IsCrtDac) {
+	unsigned long ulOrigVCLK_ECP_CNTL;
+	unsigned long ulOrigDAC_CNTL;
+	unsigned long ulOrigDAC_MACRO_CNTL;
+	unsigned long ulOrigDAC_EXT_CNTL;
+	unsigned long ulOrigCRTC_EXT_CNTL;
+	unsigned long ulData;
+	unsigned long ulMask;
+
+	ulOrigVCLK_ECP_CNTL = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+
+	ulData              = ulOrigVCLK_ECP_CNTL;
+	ulData             &= ~(RADEON_PIXCLK_ALWAYS_ONb
+				| RADEON_PIXCLK_DAC_ALWAYS_ONb);
+	ulMask              = ~(RADEON_PIXCLK_ALWAYS_ONb
+				|RADEON_PIXCLK_DAC_ALWAYS_ONb);
+	OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
+
+	ulOrigCRTC_EXT_CNTL = INREG(RADEON_CRTC_EXT_CNTL);
+	ulData              = ulOrigCRTC_EXT_CNTL;
+	ulData             |= RADEON_CRTC_CRT_ON;
+	OUTREG(RADEON_CRTC_EXT_CNTL, ulData);
+
+	ulOrigDAC_EXT_CNTL = INREG(RADEON_DAC_EXT_CNTL);
+	ulData             = ulOrigDAC_EXT_CNTL;
+	ulData            &= ~RADEON_DAC_FORCE_DATA_MASK;
+	ulData            |=  (RADEON_DAC_FORCE_BLANK_OFF_EN
+			       |RADEON_DAC_FORCE_DATA_EN
+			       |RADEON_DAC_FORCE_DATA_SEL_MASK);
+	if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
+	    (info->ChipFamily == CHIP_FAMILY_RV280))
+	    ulData |= (0x01b6 << RADEON_DAC_FORCE_DATA_SHIFT);
+	else
+	    ulData |= (0x01ac << RADEON_DAC_FORCE_DATA_SHIFT);
+
+	OUTREG(RADEON_DAC_EXT_CNTL, ulData);
+
+	/* turn on power so testing can go through */
+	ulOrigDAC_CNTL = INREG(RADEON_DAC_CNTL);
+	ulOrigDAC_CNTL &= ~RADEON_DAC_PDWN;
+	OUTREG(RADEON_DAC_CNTL, ulOrigDAC_CNTL);
+
+	ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
+	ulOrigDAC_MACRO_CNTL &= ~(RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
+				  RADEON_DAC_PDWN_B);
+	OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
+
+	/* Enable comparators and set DAC range to PS2 (VGA) output level */
+	ulData = ulOrigDAC_CNTL;
+	ulData |= RADEON_DAC_CMP_EN;
+	ulData &= ~RADEON_DAC_RANGE_CNTL_MASK;
+	ulData |= 0x2;
+	OUTREG(RADEON_DAC_CNTL, ulData);
+
+	/* Settle down */
+	usleep(10000);
+
+	/* Read comparators */
+	ulData     = INREG(RADEON_DAC_CNTL);
+	bConnected =  (RADEON_DAC_CMP_OUTPUT & ulData)?1:0;
+
+	/* Restore things */
+	ulData    = ulOrigVCLK_ECP_CNTL;
+	ulMask    = 0xFFFFFFFFL;
+	OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
+
+	OUTREG(RADEON_DAC_CNTL,      ulOrigDAC_CNTL     );
+	OUTREG(RADEON_DAC_EXT_CNTL,  ulOrigDAC_EXT_CNTL );
+	OUTREG(RADEON_CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
+
+	if (!bConnected) {
+	    /* Power DAC down if CRT is not connected */
+            ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
+            ulOrigDAC_MACRO_CNTL |= (RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
+	    	RADEON_DAC_PDWN_B);
+            OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
+
+	    ulData = INREG(RADEON_DAC_CNTL);
+	    ulData |= RADEON_DAC_PDWN;
+	    OUTREG(RADEON_DAC_CNTL, ulData);
+    	}
+    } else { /* TV DAC */
+
+        /* This doesn't seem to work reliably (maybe worse on some OEM cards),
+           for now we always return false. If one wants to connected a
+           non-DDC monitor on the DVI port when CRT port is also connected,
+           he will need to explicitly tell the driver in the config file
+           with Option MonitorLayout.
+        */
+        bConnected = FALSE;
+
+#if 0
+	if (info->ChipFamily == CHIP_FAMILY_R200) {
+	    unsigned long ulOrigGPIO_MONID;
+	    unsigned long ulOrigFP2_GEN_CNTL;
+	    unsigned long ulOrigDISP_OUTPUT_CNTL;
+	    unsigned long ulOrigCRTC2_GEN_CNTL;
+	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_A;
+	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_B;
+	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_C;
+	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_D;
+	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_E;
+	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_F;
+	    unsigned long ulOrigCRTC2_H_TOTAL_DISP;
+	    unsigned long ulOrigCRTC2_V_TOTAL_DISP;
+	    unsigned long ulOrigCRTC2_H_SYNC_STRT_WID;
+	    unsigned long ulOrigCRTC2_V_SYNC_STRT_WID;
+	    unsigned long ulData, i;
+
+	    ulOrigGPIO_MONID = INREG(RADEON_GPIO_MONID);
+	    ulOrigFP2_GEN_CNTL = INREG(RADEON_FP2_GEN_CNTL);
+	    ulOrigDISP_OUTPUT_CNTL = INREG(RADEON_DISP_OUTPUT_CNTL);
+	    ulOrigCRTC2_GEN_CNTL = INREG(RADEON_CRTC2_GEN_CNTL);
+	    ulOrigDISP_LIN_TRANS_GRPH_A = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
+	    ulOrigDISP_LIN_TRANS_GRPH_B = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
+	    ulOrigDISP_LIN_TRANS_GRPH_C = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
+	    ulOrigDISP_LIN_TRANS_GRPH_D = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
+	    ulOrigDISP_LIN_TRANS_GRPH_E = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
+	    ulOrigDISP_LIN_TRANS_GRPH_F = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
+
+	    ulOrigCRTC2_H_TOTAL_DISP = INREG(RADEON_CRTC2_H_TOTAL_DISP);
+	    ulOrigCRTC2_V_TOTAL_DISP = INREG(RADEON_CRTC2_V_TOTAL_DISP);
+	    ulOrigCRTC2_H_SYNC_STRT_WID = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
+	    ulOrigCRTC2_V_SYNC_STRT_WID = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
+
+	    ulData     = INREG(RADEON_GPIO_MONID);
+	    ulData    &= ~RADEON_GPIO_A_0;
+	    OUTREG(RADEON_GPIO_MONID, ulData);
+
+	    OUTREG(RADEON_FP2_GEN_CNTL, 0x0a000c0c);
+
+	    OUTREG(RADEON_DISP_OUTPUT_CNTL, 0x00000012);
+
+	    OUTREG(RADEON_CRTC2_GEN_CNTL, 0x06000000);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
+	    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
+	    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
+	    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
+	    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
+
+	    for (i = 0; i < 200; i++) {
+		ulData     = INREG(RADEON_GPIO_MONID);
+		bConnected = (ulData & RADEON_GPIO_Y_0)?1:0;
+		if (!bConnected) break;
+
+		usleep(1000);
+	    }
+
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, ulOrigDISP_LIN_TRANS_GRPH_A);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, ulOrigDISP_LIN_TRANS_GRPH_B);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, ulOrigDISP_LIN_TRANS_GRPH_C);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, ulOrigDISP_LIN_TRANS_GRPH_D);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, ulOrigDISP_LIN_TRANS_GRPH_E);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, ulOrigDISP_LIN_TRANS_GRPH_F);
+	    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, ulOrigCRTC2_H_TOTAL_DISP);
+	    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, ulOrigCRTC2_V_TOTAL_DISP);
+	    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, ulOrigCRTC2_H_SYNC_STRT_WID);
+	    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, ulOrigCRTC2_V_SYNC_STRT_WID);
+	    OUTREG(RADEON_CRTC2_GEN_CNTL, ulOrigCRTC2_GEN_CNTL);
+	    OUTREG(RADEON_DISP_OUTPUT_CNTL, ulOrigDISP_OUTPUT_CNTL);
+	    OUTREG(RADEON_FP2_GEN_CNTL, ulOrigFP2_GEN_CNTL);
+	    OUTREG(RADEON_GPIO_MONID, ulOrigGPIO_MONID);
+        } else {
+	    unsigned long ulOrigPIXCLKSDATA;
+	    unsigned long ulOrigTV_MASTER_CNTL;
+	    unsigned long ulOrigTV_DAC_CNTL;
+	    unsigned long ulOrigTV_PRE_DAC_MUX_CNTL;
+	    unsigned long ulOrigDAC_CNTL2;
+	    unsigned long ulData;
+	    unsigned long ulMask;
+
+	    ulOrigPIXCLKSDATA = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+
+	    ulData            = ulOrigPIXCLKSDATA;
+	    ulData           &= ~(RADEON_PIX2CLK_ALWAYS_ONb
+				  | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
+	    ulMask            = ~(RADEON_PIX2CLK_ALWAYS_ONb
+			  | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
+	    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
+
+	    ulOrigTV_MASTER_CNTL = INREG(RADEON_TV_MASTER_CNTL);
+	    ulData               = ulOrigTV_MASTER_CNTL;
+	    ulData              &= ~RADEON_TVCLK_ALWAYS_ONb;
+	    OUTREG(RADEON_TV_MASTER_CNTL, ulData);
+
+	    ulOrigDAC_CNTL2 = INREG(RADEON_DAC_CNTL2);
+	    ulData          = ulOrigDAC_CNTL2;
+	    ulData          &= ~RADEON_DAC2_DAC2_CLK_SEL;
+	    OUTREG(RADEON_DAC_CNTL2, ulData);
+
+	    ulOrigTV_DAC_CNTL = INREG(RADEON_TV_DAC_CNTL);
+
+	    ulData  = 0x00880213;
+	    OUTREG(RADEON_TV_DAC_CNTL, ulData);
+
+	    ulOrigTV_PRE_DAC_MUX_CNTL = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
+
+	    ulData  =  (RADEON_Y_RED_EN
+			| RADEON_C_GRN_EN
+			| RADEON_CMP_BLU_EN
+			| RADEON_RED_MX_FORCE_DAC_DATA
+			| RADEON_GRN_MX_FORCE_DAC_DATA
+			| RADEON_BLU_MX_FORCE_DAC_DATA);
+            if (IS_R300_VARIANT)
+		ulData |= 0x180 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
+	    else
+		ulData |= 0x1f5 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
+	    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulData);
+
+	    usleep(10000);
+
+	    ulData     = INREG(RADEON_TV_DAC_CNTL);
+	    bConnected = (ulData & RADEON_TV_DAC_CMPOUT)?1:0;
+
+	    ulData    = ulOrigPIXCLKSDATA;
+	    ulMask    = 0xFFFFFFFFL;
+	    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
+
+	    OUTREG(RADEON_TV_MASTER_CNTL, ulOrigTV_MASTER_CNTL);
+	    OUTREG(RADEON_DAC_CNTL2, ulOrigDAC_CNTL2);
+	    OUTREG(RADEON_TV_DAC_CNTL, ulOrigTV_DAC_CNTL);
+	    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulOrigTV_PRE_DAC_MUX_CNTL);
+	}
+#endif
+	return MT_UNKNOWN;
+    }
+
+    return(bConnected ? MT_CRT : MT_NONE);
+}
+#endif
+
+RADEONMonitorType
+legacy_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+    RADEONInfoPtr info      = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONMonitorType found = MT_NONE;
+
+    if (OUTPUT_IS_TV) {
+	if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_TVOUT, FALSE)) {
+	    if (radeon_output->type == OUTPUT_STV)
+		found = MT_STV;
+	    else
+		found = MT_CTV;
+	} else {
+	    if (info->InternalTVOut) {
+		if (radeon_output->load_detection)
+		    found = radeon_detect_tv(pScrn);
+		else
+		    found = MT_NONE;
+	    }
+	}
+    } else {
+	if (radeon_output->DACType == DAC_PRIMARY) {
+	    if (radeon_output->load_detection)
+		found = radeon_detect_primary_dac(pScrn, TRUE);
+	} else if (radeon_output->DACType == DAC_TVDAC) {
+	    if (radeon_output->load_detection) {
+		if (info->ChipFamily == CHIP_FAMILY_R200)
+		    found = radeon_detect_ext_dac(pScrn);
+		else
+		    found = radeon_detect_tv_dac(pScrn, TRUE);
+	    } else
+		found = MT_NONE;
+	}
+    }
+
+    return found;
+}
+
+/*
+ * Powering done DAC, needed for DPMS problem with ViewSonic P817 (or its variant).
+ *
+ */
+static void
+RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    if (IsPrimaryDAC) {
+	CARD32 dac_cntl;
+	CARD32 dac_macro_cntl = 0;
+	dac_cntl = INREG(RADEON_DAC_CNTL);
+	dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
+	if (IsOn) {
+	    dac_cntl &= ~RADEON_DAC_PDWN;
+	    dac_macro_cntl &= ~(RADEON_DAC_PDWN_R |
+				RADEON_DAC_PDWN_G |
+				RADEON_DAC_PDWN_B);
+	} else {
+	    dac_cntl |= RADEON_DAC_PDWN;
+	    dac_macro_cntl |= (RADEON_DAC_PDWN_R |
+			       RADEON_DAC_PDWN_G |
+			       RADEON_DAC_PDWN_B);
+	}
+	OUTREG(RADEON_DAC_CNTL, dac_cntl);
+	OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
+    } else {
+	CARD32 tv_dac_cntl;
+	CARD32 fp2_gen_cntl;
+
+	switch(info->ChipFamily)
+	{
+	case CHIP_FAMILY_R420:
+	case CHIP_FAMILY_RV410:
+	    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+	    if (IsOn) {
+		tv_dac_cntl &= ~(R420_TV_DAC_RDACPD |
+				 R420_TV_DAC_GDACPD |
+				 R420_TV_DAC_BDACPD |
+				 RADEON_TV_DAC_BGSLEEP);
+	    } else {
+		tv_dac_cntl |= (R420_TV_DAC_RDACPD |
+				R420_TV_DAC_GDACPD |
+				R420_TV_DAC_BDACPD |
+				RADEON_TV_DAC_BGSLEEP);
+	    }
+	    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+	    break;
+	case CHIP_FAMILY_R200:
+	    fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL);
+	    if (IsOn) {
+		fp2_gen_cntl |= RADEON_FP2_DVO_EN;
+	    } else {
+		fp2_gen_cntl &= ~RADEON_FP2_DVO_EN;
+	    }
+	    OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
+	    break;
+
+	default:
+	    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+	    if (IsOn) {
+		tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD |
+				 RADEON_TV_DAC_GDACPD |
+				 RADEON_TV_DAC_BDACPD |
+				 RADEON_TV_DAC_BGSLEEP);
+	    } else {
+		tv_dac_cntl |= (RADEON_TV_DAC_RDACPD |
+				RADEON_TV_DAC_GDACPD |
+				RADEON_TV_DAC_BDACPD |
+				RADEON_TV_DAC_BGSLEEP);
+	    }
+	    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+	    break;
+	}
+    }
+}
+
+/* This is to be used enable/disable displays dynamically */
+static void
+RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    RADEONSavePtr save = info->ModeReg;
+    unsigned char * RADEONMMIO = info->MMIO;
+    unsigned long tmp;
+    RADEONOutputPrivatePtr radeon_output;
+    int tv_dac_change = 0, o;
+    radeon_output = output->driver_private;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+
+    for (o = 0; o < xf86_config->num_output; o++) {
+	if (output == xf86_config->output[o]) {
+	    break;
+	}
+    }
+
+    if (bEnable) {
+	ErrorF("enable montype: %d\n", radeon_output->MonType);
+	if (radeon_output->MonType == MT_CRT) {
+	    if (radeon_output->DACType == DAC_PRIMARY) {
+		info->output_crt1 |= (1 << o);
+		tmp = INREG(RADEON_CRTC_EXT_CNTL);
+		tmp |= RADEON_CRTC_CRT_ON;
+		OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
+		save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON;
+		RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+	    } else if (radeon_output->DACType == DAC_TVDAC) {
+		info->output_crt2 |= (1 << o);
+		if (info->ChipFamily == CHIP_FAMILY_R200) {
+		    tmp = INREG(RADEON_FP2_GEN_CNTL);
+		    tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+		    OUTREG(RADEON_FP2_GEN_CNTL, tmp);
+		    save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+		} else {
+		    tmp = INREG(RADEON_CRTC2_GEN_CNTL);
+		    tmp |= RADEON_CRTC2_CRT2_ON;
+		    OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
+		    save->crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
+		}
+		tv_dac_change = 1;
+	    }
+	} else if (radeon_output->MonType == MT_DFP) {
+	    if (radeon_output->TMDSType == TMDS_INT) {
+		info->output_dfp1 |= (1 << o);
+		tmp = INREG(RADEON_FP_GEN_CNTL);
+		tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+		OUTREG(RADEON_FP_GEN_CNTL, tmp);
+		save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+	    } else if (radeon_output->TMDSType == TMDS_EXT) {
+		info->output_dfp2 |= (1 << o);
+		tmp = INREG(RADEON_FP2_GEN_CNTL);
+		tmp &= ~RADEON_FP2_BLANK_EN;
+		tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+		OUTREG(RADEON_FP2_GEN_CNTL, tmp);
+		save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+		save->fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN;
+	    }
+	} else if (radeon_output->MonType == MT_LCD) {
+	    info->output_lcd1 |= (1 << o);
+	    tmp = INREG(RADEON_LVDS_GEN_CNTL);
+	    tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
+	    tmp &= ~(RADEON_LVDS_DISPLAY_DIS);
+	    usleep (radeon_output->PanelPwrDly * 1000);
+	    OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
+	    save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
+	    save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
+	} else if (radeon_output->MonType == MT_STV ||
+		   radeon_output->MonType == MT_CTV) {
+	    info->output_tv1 |= (1 << o);
+	    tmp = INREG(RADEON_TV_MASTER_CNTL);
+	    tmp |= RADEON_TV_ON;
+	    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
+	    tv_dac_change = 2;
+	    radeon_output->tv_on = TRUE;
+	}
+    } else {
+	ErrorF("disable montype: %d\n", radeon_output->MonType);
+	if (radeon_output->MonType == MT_CRT) {
+	    if (radeon_output->DACType == DAC_PRIMARY) {
+		info->output_crt1 &= ~(1 << o);
+		if (!info->output_crt1) {
+		    tmp = INREG(RADEON_CRTC_EXT_CNTL);
+		    tmp &= ~RADEON_CRTC_CRT_ON;
+		    OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
+		    save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
+		    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+		}
+	    } else if (radeon_output->DACType == DAC_TVDAC) {
+		info->output_crt2 &= ~(1 << o);
+		tv_dac_change = 1;
+		if (!info->output_crt2) {
+		    if (info->ChipFamily == CHIP_FAMILY_R200) {
+			tmp = INREG(RADEON_FP2_GEN_CNTL);
+			tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+			OUTREG(RADEON_FP2_GEN_CNTL, tmp);
+			save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+		    } else {
+			tmp = INREG(RADEON_CRTC2_GEN_CNTL);
+			tmp &= ~RADEON_CRTC2_CRT2_ON;
+			OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
+			save->crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
+		    }
+		}
+	    }
+	} else if (radeon_output->MonType == MT_DFP) {
+	    if (radeon_output->TMDSType == TMDS_INT) {
+		info->output_dfp1 &= ~(1 << o);
+		if (!info->output_dfp1) {
+		    tmp = INREG(RADEON_FP_GEN_CNTL);
+		    tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+		    OUTREG(RADEON_FP_GEN_CNTL, tmp);
+		    save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+		}
+	    } else if (radeon_output->TMDSType == TMDS_EXT) {
+		info->output_dfp2 &= ~(1 << o);
+		if (!info->output_dfp2) {
+		    tmp = INREG(RADEON_FP2_GEN_CNTL);
+		    tmp |= RADEON_FP2_BLANK_EN;
+		    tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+		    OUTREG(RADEON_FP2_GEN_CNTL, tmp);
+		    save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+		    save->fp2_gen_cntl |= RADEON_FP2_BLANK_EN;
+		}
+	    }
+	} else if (radeon_output->MonType == MT_LCD) {
+	    info->output_lcd1 &= ~(1 << o);
+	    if (!info->output_lcd1) {
+		unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+		if (info->IsMobility || info->IsIGP) {
+		    /* Asic bug, when turning off LVDS_ON, we have to make sure
+		       RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
+		    */
+		    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
+		}
+		tmp = INREG(RADEON_LVDS_GEN_CNTL);
+		tmp |= RADEON_LVDS_DISPLAY_DIS;
+		tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
+		OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
+		save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
+		save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
+		if (info->IsMobility || info->IsIGP) {
+		    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
+		}
+	    }
+	} else if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
+	    info->output_tv1 &= ~(1 << o);
+	    tv_dac_change = 2;
+	    if (!info->output_tv1) {
+		tmp = INREG(RADEON_TV_MASTER_CNTL);
+		tmp &= ~RADEON_TV_ON;
+		OUTREG(RADEON_TV_MASTER_CNTL, tmp);
+		radeon_output->tv_on = FALSE;
+	    }
+	}
+    }
+
+    if (tv_dac_change) {
+	if (bEnable)
+	    info->tv_dac_enable_mask |= tv_dac_change;
+	else
+	    info->tv_dac_enable_mask &= ~tv_dac_change;
+
+	if (bEnable && info->tv_dac_enable_mask)
+	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+	else if (!bEnable && info->tv_dac_enable_mask == 0)
+	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+
+    }
+}
+
+void
+legacy_output_dpms(xf86OutputPtr output, int mode)
+{
+    switch(mode) {
+    case DPMSModeOn:
+	RADEONEnableDisplay(output, TRUE);
+	break;
+    case DPMSModeOff:
+    case DPMSModeSuspend:
+    case DPMSModeStandby:
+	RADEONEnableDisplay(output, FALSE);
+	break;
+    }
+}
+
+static void
+RADEONInitFPRegisters(xf86OutputPtr output, RADEONSavePtr save,
+		      DisplayModePtr mode, BOOL IsPrimary)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONEntPtr  pRADEONEnt = RADEONEntPriv(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    int i;
+    CARD32 tmp = info->SavedReg->tmds_pll_cntl & 0xfffff;
+
+    for (i=0; i<4; i++) {
+	if (radeon_output->tmds_pll[i].freq == 0) break;
+	if ((CARD32)(mode->Clock/10) < radeon_output->tmds_pll[i].freq) {
+	    tmp = radeon_output->tmds_pll[i].value ;
+	    break;
+	}
+    }
+
+    if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RV280)) {
+	if (tmp & 0xfff00000)
+	    save->tmds_pll_cntl = tmp;
+	else {
+	    save->tmds_pll_cntl = info->SavedReg->tmds_pll_cntl & 0xfff00000;
+	    save->tmds_pll_cntl |= tmp;
+	}
+    } else save->tmds_pll_cntl = tmp;
+
+    save->tmds_transmitter_cntl = info->SavedReg->tmds_transmitter_cntl &
+					~(RADEON_TMDS_TRANSMITTER_PLLRST);
+
+    if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_R200) || !pRADEONEnt->HasCRTC2)
+	save->tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN);
+    else /* weird, RV chips got this bit reversed? */
+	save->tmds_transmitter_cntl |= (RADEON_TMDS_TRANSMITTER_PLLEN);
+
+    save->fp_gen_cntl = info->SavedReg->fp_gen_cntl |
+			 (RADEON_FP_CRTC_DONT_SHADOW_VPAR |
+			  RADEON_FP_CRTC_DONT_SHADOW_HEND );
+
+    save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+
+    if (pScrn->rgbBits == 8)
+	save->fp_gen_cntl |= RADEON_FP_PANEL_FORMAT;  /* 24 bit format */
+    else
+	save->fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */
+
+
+    if (IsPrimary) {
+	if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) {
+	    save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
+	    if (radeon_output->Flags & RADEON_USE_RMX)
+		save->fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX;
+	    else
+		save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1;
+	} else
+	    save->fp_gen_cntl |= RADEON_FP_SEL_CRTC1;
+    } else {
+	if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) {
+	    save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
+	    save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2;
+	} else
+	    save->fp_gen_cntl |= RADEON_FP_SEL_CRTC2;
+    }
+
+}
+
+static void
+RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save,
+		       DisplayModePtr mode, BOOL IsPrimary)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    if (pScrn->rgbBits == 8)
+	save->fp2_gen_cntl = info->SavedReg->fp2_gen_cntl |
+				RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */
+    else
+	save->fp2_gen_cntl = info->SavedReg->fp2_gen_cntl &
+				~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */
+
+    save->fp2_gen_cntl &= ~(RADEON_FP2_ON |
+			    RADEON_FP2_DVO_EN |
+			    RADEON_FP2_DVO_RATE_SEL_SDR);
+
+
+    /* XXX: these may be oem specific */
+    if (IS_R300_VARIANT) {
+	save->fp2_gen_cntl |= RADEON_FP2_PAD_FLOP_EN | R300_FP2_DVO_CLOCK_MODE_SINGLE;
+#if 0
+	if (mode->Clock > 165000)
+	    save->fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;
+#endif
+    }
+
+    if (IsPrimary) {
+	if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+	    save->fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK;
+	    if (radeon_output->Flags & RADEON_USE_RMX)
+		save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX;
+	} else {
+	    save->fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_CRTC2;
+	}
+    } else {
+	if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+	    save->fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK;
+	    save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
+	} else {
+	    save->fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2;
+	}
+    }
+
+}
+
+static void
+RADEONInitLVDSRegisters(xf86OutputPtr output, RADEONSavePtr save,
+			DisplayModePtr mode, BOOL IsPrimary)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    save->lvds_pll_cntl = (info->SavedReg->lvds_pll_cntl |
+			   RADEON_LVDS_PLL_EN);
+
+    save->lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET;
+
+    save->lvds_gen_cntl = info->SavedReg->lvds_gen_cntl;
+    save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
+    save->lvds_gen_cntl &= ~(RADEON_LVDS_ON |
+			     RADEON_LVDS_BLON |
+			     RADEON_LVDS_EN |
+			     RADEON_LVDS_RST_FM);
+
+    if (IS_R300_VARIANT)
+	save->lvds_pll_cntl &= ~(R300_LVDS_SRC_SEL_MASK);
+
+    if (IsPrimary) {
+	if (IS_R300_VARIANT) {
+	    if (radeon_output->Flags & RADEON_USE_RMX)
+		save->lvds_pll_cntl |= R300_LVDS_SRC_SEL_RMX;
+	} else
+	    save->lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2;
+    } else {
+	if (IS_R300_VARIANT) {
+	    save->lvds_pll_cntl |= R300_LVDS_SRC_SEL_CRTC2;
+	} else
+	    save->lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2;
+    }
+
+}
+
+static void
+RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save,
+		       DisplayModePtr mode)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    int    xres = mode->HDisplay;
+    int    yres = mode->VDisplay;
+    float  Hratio, Vratio;
+    int    hsync_wid;
+    int    vsync_wid;
+
+    save->fp_vert_stretch = info->SavedReg->fp_vert_stretch &
+	                    RADEON_VERT_STRETCH_RESERVED;
+    save->fp_horz_stretch = info->SavedReg->fp_horz_stretch &
+	                    (RADEON_HORZ_FP_LOOP_STRETCH |
+	                     RADEON_HORZ_AUTO_RATIO_INC);
+
+    save->crtc_more_cntl = 0;
+    if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
+	(info->ChipFamily == CHIP_FAMILY_RS200)) {
+	/* This is to workaround the asic bug for RMX, some versions
+           of BIOS dosen't have this register initialized correctly.
+	*/
+	save->crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN;
+    }
+
+    if (radeon_output->MonType != MT_LCD && radeon_output->MonType != MT_DFP)
+	return;
+
+    if ((radeon_output->rmx_type == RMX_CENTER) &&
+	(radeon_output->Flags & RADEON_USE_RMX)) {
+	save->crtc_more_cntl |= (RADEON_CRTC_AUTO_HORZ_CENTER_EN |
+				 RADEON_CRTC_AUTO_VERT_CENTER_EN);
+    }
+
+    if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) {
+	Hratio = 1.0;
+	Vratio = 1.0;
+    } else {
+	if (xres > radeon_output->PanelXRes) xres = radeon_output->PanelXRes;
+	if (yres > radeon_output->PanelYRes) yres = radeon_output->PanelYRes;
+
+	Hratio = (float)xres/(float)radeon_output->PanelXRes;
+	Vratio = (float)yres/(float)radeon_output->PanelYRes;
+    }
+
+    if ((Hratio == 1.0) || (!(radeon_output->Flags & RADEON_USE_RMX)) ||
+	(radeon_output->rmx_type == RMX_CENTER)) {
+	save->fp_horz_stretch |= ((xres/8-1)<<16);
+    } else {
+	save->fp_horz_stretch |= ((((unsigned long)
+				    (Hratio * RADEON_HORZ_STRETCH_RATIO_MAX)) &
+				   RADEON_HORZ_STRETCH_RATIO_MASK) |
+				  RADEON_HORZ_STRETCH_BLEND |
+				  RADEON_HORZ_STRETCH_ENABLE |
+				  ((radeon_output->PanelXRes/8-1)<<16));
+    }
+
+    if ((Vratio == 1.0) || (!(radeon_output->Flags & RADEON_USE_RMX)) ||
+	(radeon_output->rmx_type == RMX_CENTER)) {
+	save->fp_vert_stretch |= ((yres-1)<<12);
+    } else {
+	save->fp_vert_stretch |= ((((unsigned long)(Vratio * RADEON_VERT_STRETCH_RATIO_MAX)) &
+				   RADEON_VERT_STRETCH_RATIO_MASK) |
+				  RADEON_VERT_STRETCH_ENABLE |
+				  RADEON_VERT_STRETCH_BLEND |
+				  ((radeon_output->PanelYRes-1)<<12));
+    }
+
+
+
+    if ((radeon_output->rmx_type == RMX_CENTER) &&
+	(radeon_output->Flags & RADEON_USE_RMX)) {
+	int    blank_width;
+
+	blank_width = (mode->CrtcHBlankEnd - mode->CrtcHBlankStart) / 8;
+	if (blank_width > 110) blank_width = 110;
+
+	save->fp_crtc_h_total_disp = (((blank_width) & 0x3ff)
+				      | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff)
+					 << 16));
+
+	hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
+	if (!hsync_wid)       hsync_wid = 1;
+
+	save->fp_h_sync_strt_wid = ((((mode->CrtcHSyncStart - mode->CrtcHBlankStart) / 8) & 0x1fff)
+				    | ((hsync_wid & 0x3f) << 16)
+				    | ((mode->Flags & V_NHSYNC)
+				       ? RADEON_CRTC_H_SYNC_POL
+				       : 0));
+
+	save->fp_crtc_v_total_disp = (((mode->CrtcVBlankEnd - mode->CrtcVBlankStart) & 0xffff)
+				      | ((mode->CrtcVDisplay - 1) << 16));
+
+	vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+	if (!vsync_wid)       vsync_wid = 1;
+
+	save->fp_v_sync_strt_wid = ((((mode->CrtcVSyncStart - mode->CrtcVBlankStart) & 0xfff)
+				    | ((vsync_wid & 0x1f) << 16)
+				    | ((mode->Flags & V_NVSYNC)
+				       ? RADEON_CRTC_V_SYNC_POL
+				       : 0)));
+
+	save->fp_horz_vert_active = (((radeon_output->PanelYRes) & 0xfff) |
+				     (((radeon_output->PanelXRes / 8) & 0x1ff) << 16));
+
+    } else {
+	int    hsync_start;
+
+	save->fp_crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
+				      | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff)
+					 << 16));
+
+	hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
+	if (!hsync_wid)       hsync_wid = 1;
+	hsync_start = mode->CrtcHSyncStart - 8;
+
+	save->fp_h_sync_strt_wid = ((hsync_start & 0x1fff)
+				    | ((hsync_wid & 0x3f) << 16)
+				    | ((mode->Flags & V_NHSYNC)
+				       ? RADEON_CRTC_H_SYNC_POL
+				       : 0));
+
+	save->fp_crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
+				      | ((mode->CrtcVDisplay - 1) << 16));
+
+	vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+	if (!vsync_wid)       vsync_wid = 1;
+
+	save->fp_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
+				    | ((vsync_wid & 0x1f) << 16)
+				    | ((mode->Flags & V_NVSYNC)
+				       ? RADEON_CRTC_V_SYNC_POL
+				       : 0));
+
+	save->fp_horz_vert_active = 0;
+    }
+}
+
+static void
+RADEONInitDACRegisters(xf86OutputPtr output, RADEONSavePtr save,
+		       DisplayModePtr mode, BOOL IsPrimary)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+
+    if (IsPrimary) {
+	if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+            save->disp_output_cntl = info->SavedReg->disp_output_cntl &
+					~RADEON_DISP_DAC_SOURCE_MASK;
+        } else {
+            save->dac2_cntl = info->SavedReg->dac2_cntl & ~(RADEON_DAC2_DAC_CLK_SEL);
+        }
+    } else {
+        if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+            save->disp_output_cntl = info->SavedReg->disp_output_cntl &
+					~RADEON_DISP_DAC_SOURCE_MASK;
+            save->disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2;
+        } else {
+            save->dac2_cntl = info->SavedReg->dac2_cntl | RADEON_DAC2_DAC_CLK_SEL;
+        }
+    }
+    save->dac_cntl = (RADEON_DAC_MASK_ALL
+		      | RADEON_DAC_VGA_ADR_EN
+		      | (info->dac6bits ? 0 : RADEON_DAC_8BIT_EN));
+
+    save->dac_macro_cntl = info->SavedReg->dac_macro_cntl;
+}
+
+static void
+RADEONInitTvDacCntl(xf86OutputPtr output, RADEONSavePtr save)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    if (info->ChipFamily == CHIP_FAMILY_R420 ||
+	info->ChipFamily == CHIP_FAMILY_RV410) {
+	save->tv_dac_cntl = info->SavedReg->tv_dac_cntl &
+			     ~(RADEON_TV_DAC_STD_MASK |
+			       RADEON_TV_DAC_BGADJ_MASK |
+			       R420_TV_DAC_DACADJ_MASK |
+			       R420_TV_DAC_RDACPD |
+			       R420_TV_DAC_GDACPD |
+			       R420_TV_DAC_GDACPD |
+			       R420_TV_DAC_TVENABLE);
+    } else {
+	save->tv_dac_cntl = info->SavedReg->tv_dac_cntl &
+			     ~(RADEON_TV_DAC_STD_MASK |
+			       RADEON_TV_DAC_BGADJ_MASK |
+			       RADEON_TV_DAC_DACADJ_MASK |
+			       RADEON_TV_DAC_RDACPD |
+			       RADEON_TV_DAC_GDACPD |
+			       RADEON_TV_DAC_GDACPD);
+    }
+
+    save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
+			  RADEON_TV_DAC_NHOLD |
+			  RADEON_TV_DAC_STD_PS2 |
+			  radeon_output->ps2_tvdac_adj);
+
+}
+
+static void
+RADEONInitDAC2Registers(xf86OutputPtr output, RADEONSavePtr save,
+			DisplayModePtr mode, BOOL IsPrimary)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+
+    /*0x0028023;*/
+    RADEONInitTvDacCntl(output, save);
+
+    if (IS_R300_VARIANT)
+	save->gpiopad_a = info->SavedReg->gpiopad_a | 1;
+
+    save->dac2_cntl = info->SavedReg->dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
+
+    if (IsPrimary) {
+        if (IS_R300_VARIANT) {
+            save->disp_output_cntl = info->SavedReg->disp_output_cntl &
+					~RADEON_DISP_TVDAC_SOURCE_MASK;
+            save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC;
+        } else if (info->ChipFamily == CHIP_FAMILY_R200) {
+	    save->fp2_gen_cntl = info->SavedReg->fp2_gen_cntl &
+				  ~(R200_FP2_SOURCE_SEL_MASK |
+				    RADEON_FP2_DVO_RATE_SEL_SDR);
+	} else {
+            save->disp_hw_debug = info->SavedReg->disp_hw_debug | RADEON_CRT2_DISP1_SEL;
+        }
+    } else {
+        if (IS_R300_VARIANT) {
+            save->disp_output_cntl = info->SavedReg->disp_output_cntl &
+					~RADEON_DISP_TVDAC_SOURCE_MASK;
+            save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
+	} else if (info->ChipFamily == CHIP_FAMILY_R200) {
+	    save->fp2_gen_cntl = info->SavedReg->fp2_gen_cntl &
+				  ~(R200_FP2_SOURCE_SEL_MASK |
+				    RADEON_FP2_DVO_RATE_SEL_SDR);
+            save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
+        } else {
+            save->disp_hw_debug = info->SavedReg->disp_hw_debug &
+					~RADEON_CRT2_DISP1_SEL;
+        }
+    }
+}
+
+static void
+RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
+			  DisplayModePtr mode, xf86OutputPtr output,
+			  int crtc_num)
+{
+    Bool IsPrimary = crtc_num == 0 ? TRUE : FALSE;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    if (crtc_num == 0)
+	RADEONInitRMXRegisters(output, save, mode);
+
+    if (radeon_output->MonType == MT_CRT) {
+	if (radeon_output->DACType == DAC_PRIMARY) {
+	    RADEONInitDACRegisters(output, save, mode, IsPrimary);
+	} else {
+	    RADEONInitDAC2Registers(output, save, mode, IsPrimary);
+	}
+    } else if (radeon_output->MonType == MT_LCD) {
+	RADEONInitLVDSRegisters(output, save, mode, IsPrimary);
+    } else if (radeon_output->MonType == MT_DFP) {
+	if (radeon_output->TMDSType == TMDS_INT) {
+	    RADEONInitFPRegisters(output, save, mode, IsPrimary);
+	} else {
+	    RADEONInitFP2Registers(output, save, mode, IsPrimary);
+	}
+    } else if (radeon_output->MonType == MT_STV ||
+	       radeon_output->MonType == MT_CTV) {
+	RADEONInitTVRegisters(output, save, mode, IsPrimary);
+    }
+}
+
+void
+legacy_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
+		  DisplayModePtr adjusted_mode)
+{
+    ScrnInfoPtr	    pScrn = output->scrn;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    xf86CrtcPtr	crtc = output->crtc;
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+
+    RADEONInitOutputRegisters(pScrn, info->ModeReg, adjusted_mode, output, radeon_crtc->crtc_id);
+
+    if (radeon_crtc->crtc_id == 0)
+	RADEONRestoreRMXRegisters(pScrn, info->ModeReg);
+
+    switch(radeon_output->MonType) {
+    case MT_LCD:
+	ErrorF("restore LVDS\n");
+	RADEONRestoreLVDSRegisters(pScrn, info->ModeReg);
+	break;
+    case MT_DFP:
+	if (radeon_output->TMDSType == TMDS_INT) {
+	    ErrorF("restore FP\n");
+	    RADEONRestoreFPRegisters(pScrn, info->ModeReg);
+	} else {
+	    ErrorF("restore FP2\n");
+	    if (info->IsAtomBios) {
+		unsigned char *RADEONMMIO = info->MMIO;
+		CARD32 fp2_gen_cntl;
+
+		atombios_external_tmds_setup(output, mode);
+		/* r4xx atom has hard coded crtc mappings in the atom code
+		 * Fix it up here.
+		 */
+		fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL) & ~R200_FP2_SOURCE_SEL_MASK;
+		if (radeon_crtc->crtc_id == 1)
+		    fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
+		else {
+		    if (radeon_output->Flags & RADEON_USE_RMX)
+			fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX;
+		    else
+			fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC1;
+		}
+		OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
+	    } else {
+		RADEONRestoreDVOChip(pScrn, output);
+		RADEONRestoreFP2Registers(pScrn, info->ModeReg);
+	    }
+	}
+	break;
+    case MT_STV:
+    case MT_CTV:
+	ErrorF("restore tv\n");
+	RADEONRestoreDACRegisters(pScrn, info->ModeReg);
+	RADEONRestoreTVRegisters(pScrn, info->ModeReg);
+	break;
+    default:
+	ErrorF("restore dac\n");
+	RADEONRestoreDACRegisters(pScrn, info->ModeReg);
+    }
+
+}
+
+/* the following functions are based on the load detection code
+ * in the beos radeon driver by Thomas Kurschel and the existing
+ * load detection code in this driver.
+ */
+static RADEONMonitorType
+radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 vclk_ecp_cntl, crtc_ext_cntl;
+    CARD32 dac_ext_cntl, dac_cntl, dac_macro_cntl, tmp;
+    RADEONMonitorType found = MT_NONE;
+
+    /* save the regs we need */
+    vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+    crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
+    dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
+    dac_cntl = INREG(RADEON_DAC_CNTL);
+    dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
+
+    tmp = vclk_ecp_cntl &
+	~(RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb);
+    OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
+
+    tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON;
+    OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
+
+    tmp = RADEON_DAC_FORCE_BLANK_OFF_EN |
+	RADEON_DAC_FORCE_DATA_EN;
+
+    if (color)
+	tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB;
+    else
+	tmp |= RADEON_DAC_FORCE_DATA_SEL_G;
+
+    if (IS_R300_VARIANT)
+	tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
+    else
+	tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
+
+    OUTREG(RADEON_DAC_EXT_CNTL, tmp);
+
+    tmp = dac_cntl & ~(RADEON_DAC_RANGE_CNTL_MASK | RADEON_DAC_PDWN);
+    tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;
+    OUTREG(RADEON_DAC_CNTL, tmp);
+
+    tmp &= ~(RADEON_DAC_PDWN_R |
+	     RADEON_DAC_PDWN_G |
+	     RADEON_DAC_PDWN_B);
+
+    OUTREG(RADEON_DAC_MACRO_CNTL, tmp);
+
+    usleep(2000);
+
+    if (INREG(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) {
+	found = MT_CRT;
+	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+		    "Found %s CRT connected to primary DAC\n",
+		    color ? "color" : "bw");
+    }
+
+    /* restore the regs we used */
+    OUTREG(RADEON_DAC_CNTL, dac_cntl);
+    OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
+    OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
+    OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
+    OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, vclk_ecp_cntl);
+
+    return found;
+}
+
+static RADEONMonitorType
+radeon_detect_ext_dac(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl;
+    CARD32 disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c;
+    CARD32 disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f;
+    CARD32 tmp, crtc2_h_total_disp, crtc2_v_total_disp;
+    CARD32 crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid;
+    RADEONMonitorType found = MT_NONE;
+    int connected = 0;
+    int i = 0;
+
+    /* save the regs we need */
+    gpio_monid = INREG(RADEON_GPIO_MONID);
+    fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL);
+    disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
+    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+    disp_lin_trans_grph_a = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
+    disp_lin_trans_grph_b = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
+    disp_lin_trans_grph_c = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
+    disp_lin_trans_grph_d = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
+    disp_lin_trans_grph_e = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
+    disp_lin_trans_grph_f = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
+    crtc2_h_total_disp = INREG(RADEON_CRTC2_H_TOTAL_DISP);
+    crtc2_v_total_disp = INREG(RADEON_CRTC2_V_TOTAL_DISP);
+    crtc2_h_sync_strt_wid = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
+    crtc2_v_sync_strt_wid = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
+
+    tmp = INREG(RADEON_GPIO_MONID);
+    tmp &= ~RADEON_GPIO_A_0;
+    OUTREG(RADEON_GPIO_MONID, tmp);
+
+    OUTREG(RADEON_FP2_GEN_CNTL,
+	   RADEON_FP2_ON |
+	   RADEON_FP2_PANEL_FORMAT |
+	   R200_FP2_SOURCE_SEL_TRANS_UNIT |
+	   RADEON_FP2_DVO_EN |
+	   R200_FP2_DVO_RATE_SEL_SDR);
+
+    OUTREG(RADEON_DISP_OUTPUT_CNTL,
+	   RADEON_DISP_DAC_SOURCE_RMX |
+	   RADEON_DISP_TRANS_MATRIX_GRAPHICS);
+
+    OUTREG(RADEON_CRTC2_GEN_CNTL,
+	   RADEON_CRTC2_EN |
+	   RADEON_CRTC2_DISP_REQ_EN_B);
+
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
+
+    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
+    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
+    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
+    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
+
+    for (i = 0; i < 200; i++) {
+	tmp = INREG(RADEON_GPIO_MONID);
+	if (tmp & RADEON_GPIO_Y_0)
+	    connected = 1;
+	else
+	    connected = 0;
+
+	if (!connected)
+	    break;
+
+	usleep(1000);
+    }
+
+    if (connected)
+	found = MT_CRT;
+
+    /* restore the regs we used */
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f);
+    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp);
+    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp);
+    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid);
+    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid);
+    OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+    OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+    OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
+    OUTREG(RADEON_GPIO_MONID, gpio_monid);
+
+    return found;
+}
+
+static RADEONMonitorType
+radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
+    CARD32 disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp;
+    RADEONMonitorType found = MT_NONE;
+
+    /* save the regs we need */
+    pixclks_cntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+    gpiopad_a = IS_R300_VARIANT ? INREG(RADEON_GPIOPAD_A) : 0;
+    disp_output_cntl = IS_R300_VARIANT ? INREG(RADEON_DISP_OUTPUT_CNTL) : 0;
+    disp_hw_debug = !IS_R300_VARIANT ? INREG(RADEON_DISP_HW_DEBUG) : 0;
+    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+    dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
+    dac_cntl2 = INREG(RADEON_DAC_CNTL2);
+
+    tmp = pixclks_cntl & ~(RADEON_PIX2CLK_ALWAYS_ONb
+			   | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
+    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
+
+    if (IS_R300_VARIANT) {
+	OUTREGP(RADEON_GPIOPAD_A, 1, ~1 );
+    }
+
+    tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
+    tmp |= RADEON_CRTC2_CRT2_ON |
+	(2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
+
+    OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
+
+    if (IS_R300_VARIANT) {
+	tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
+	tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
+	OUTREG(RADEON_DISP_OUTPUT_CNTL, tmp);
+    } else {
+	tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL;
+	OUTREG(RADEON_DISP_HW_DEBUG, tmp);
+    }
+
+    tmp = RADEON_TV_DAC_NBLANK |
+	RADEON_TV_DAC_NHOLD |
+	RADEON_TV_MONITOR_DETECT_EN |
+	RADEON_TV_DAC_STD_PS2;
+
+    OUTREG(RADEON_TV_DAC_CNTL, tmp);
+
+    tmp = RADEON_DAC2_FORCE_BLANK_OFF_EN |
+	RADEON_DAC2_FORCE_DATA_EN;
+
+    if (color)
+	tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB;
+    else
+	tmp |= RADEON_DAC_FORCE_DATA_SEL_G;
+
+    if (IS_R300_VARIANT)
+	tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
+    else
+	tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
+
+    OUTREG(RADEON_DAC_EXT_CNTL, tmp);
+
+    tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN;
+    OUTREG(RADEON_DAC_CNTL2, tmp);
+
+    usleep(10000);
+
+    if (IS_R300_VARIANT) {
+	if (INREG(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) {
+	    found = MT_CRT;
+	    xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+			"Found %s CRT connected to TV DAC\n",
+			color ? "color" : "bw");
+	}
+    } else {
+	if (INREG(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUTPUT) {
+	    found = MT_CRT;
+	    xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+			"Found %s CRT connected to TV DAC\n",
+			color ? "color" : "bw");
+	}
+    }
+
+    /* restore regs we used */
+    OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
+    OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
+    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+    OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+
+    if (IS_R300_VARIANT) {
+	OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+	OUTREGP(RADEON_GPIOPAD_A, gpiopad_a, ~1 );
+    } else {
+	OUTREG(RADEON_DISP_HW_DEBUG, disp_hw_debug);
+    }
+    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, pixclks_cntl);
+
+    return found;
+}
+
+static RADEONMonitorType
+r300_detect_tv(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 tmp, dac_cntl2, crtc2_gen_cntl, dac_ext_cntl, tv_dac_cntl;
+    CARD32 gpiopad_a, disp_output_cntl;
+    RADEONMonitorType found = MT_NONE;
+
+    /* save the regs we need */
+    gpiopad_a = INREG(RADEON_GPIOPAD_A);
+    dac_cntl2 = INREG(RADEON_DAC_CNTL2);
+    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+    dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
+    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+    disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
+
+    OUTREGP(RADEON_GPIOPAD_A, 0, ~1 );
+
+    OUTREG(RADEON_DAC_CNTL2, RADEON_DAC2_DAC2_CLK_SEL );
+
+    OUTREG(RADEON_CRTC2_GEN_CNTL,
+	   RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT );
+
+    tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
+    tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
+    OUTREG(RADEON_DISP_OUTPUT_CNTL, tmp);
+
+    OUTREG(RADEON_DAC_EXT_CNTL,
+	   RADEON_DAC2_FORCE_BLANK_OFF_EN |
+	   RADEON_DAC2_FORCE_DATA_EN |
+	   RADEON_DAC_FORCE_DATA_SEL_RGB |
+	   (0xec << RADEON_DAC_FORCE_DATA_SHIFT ));
+
+    OUTREG(RADEON_TV_DAC_CNTL,
+	   RADEON_TV_DAC_STD_NTSC |
+	   (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
+	   (6 << RADEON_TV_DAC_DACADJ_SHIFT ));
+
+    INREG(RADEON_TV_DAC_CNTL);
+
+    usleep(4000);
+
+    OUTREG(RADEON_TV_DAC_CNTL,
+	   RADEON_TV_DAC_NBLANK |
+	   RADEON_TV_DAC_NHOLD |
+	   RADEON_TV_MONITOR_DETECT_EN |
+	   RADEON_TV_DAC_STD_NTSC |
+	   (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
+	   (6 << RADEON_TV_DAC_DACADJ_SHIFT ));
+
+    INREG(RADEON_TV_DAC_CNTL);
+
+    usleep(6000);
+
+    tmp = INREG(RADEON_TV_DAC_CNTL);
+    if ( (tmp & RADEON_TV_DAC_GDACDET) != 0 ) {
+	found = MT_STV;
+	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+		    "S-Video TV connection detected\n");
+    } else if ( (tmp & RADEON_TV_DAC_BDACDET) != 0 ) {
+	found = MT_CTV;
+	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+		    "Composite TV connection detected\n" );
+    }
+
+    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl );
+    OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
+    OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+    OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+    OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
+    OUTREGP(RADEON_GPIOPAD_A, gpiopad_a, ~1);
+
+    return found;
+}
+
+static RADEONMonitorType
+radeon_detect_tv(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 tmp, dac_cntl2, tv_master_cntl;
+    CARD32 tv_dac_cntl, tv_pre_dac_mux_cntl, config_cntl;
+    RADEONMonitorType found = MT_NONE;
+
+    if (IS_R300_VARIANT)
+	return r300_detect_tv(pScrn);
+
+    /* save the regs we need */
+    dac_cntl2 = INREG(RADEON_DAC_CNTL2);
+    tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL);
+    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+    config_cntl = INREG(RADEON_CONFIG_CNTL);
+    tv_pre_dac_mux_cntl = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
+
+    tmp = dac_cntl2 & ~RADEON_DAC2_DAC2_CLK_SEL;
+    OUTREG(RADEON_DAC_CNTL2, tmp);
+
+    tmp = tv_master_cntl | RADEON_TV_ON;
+    tmp &= ~(RADEON_TV_ASYNC_RST |
+	     RADEON_RESTART_PHASE_FIX |
+	     RADEON_CRT_FIFO_CE_EN |
+	     RADEON_TV_FIFO_CE_EN |
+	     RADEON_RE_SYNC_NOW_SEL_MASK);
+    tmp |= RADEON_TV_FIFO_ASYNC_RST | RADEON_CRT_ASYNC_RST;
+
+    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
+
+    tmp = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD |
+	RADEON_TV_MONITOR_DETECT_EN | RADEON_TV_DAC_STD_NTSC |
+	(8 << RADEON_TV_DAC_BGADJ_SHIFT);
+
+    if (config_cntl & RADEON_CFG_ATI_REV_ID_MASK)
+	tmp |= (4 << RADEON_TV_DAC_DACADJ_SHIFT);
+    else
+	tmp |= (8 << RADEON_TV_DAC_DACADJ_SHIFT);
+
+    OUTREG(RADEON_TV_DAC_CNTL, tmp);
+
+    tmp = RADEON_C_GRN_EN | RADEON_CMP_BLU_EN |
+	RADEON_RED_MX_FORCE_DAC_DATA |
+	RADEON_GRN_MX_FORCE_DAC_DATA |
+	RADEON_BLU_MX_FORCE_DAC_DATA |
+	(0x109 << RADEON_TV_FORCE_DAC_DATA_SHIFT);
+
+    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, tmp);
+
+    usleep(3000);
+
+    tmp = INREG(RADEON_TV_DAC_CNTL);
+    if (tmp & RADEON_TV_DAC_GDACDET) {
+	found = MT_STV;
+	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+		    "S-Video TV connection detected\n");
+    } else if (tmp & RADEON_TV_DAC_BDACDET) {
+	found = MT_CTV;
+	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+		    "Composite TV connection detected\n" );
+    }
+
+    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl);
+    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+    OUTREG(RADEON_TV_MASTER_CNTL, tv_master_cntl);
+    OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
+
+    return found;
+}
diff --git a/src/pcidb/ati_pciids.csv b/src/pcidb/ati_pciids.csv
index f201cc4..f235a5c 100644
--- a/src/pcidb/ati_pciids.csv
+++ b/src/pcidb/ati_pciids.csv
@@ -4,8 +4,8 @@
 "0x3154","RV380_3154","RV380",1,,,,,"ATI FireGL M24 GL 3154 (PCIE)"
 "0x3E50","RV380_3E50","RV380",,,,,,"ATI Radeon X600 (RV380) 3E50 (PCIE)"
 "0x3E54","RV380_3E54","RV380",,,,,,"ATI FireGL V3200 (RV380) 3E54 (PCIE)"
-"0x4136","RS100_4136","RS100",,1,,,,"ATI Radeon IGP320 (A3) 4136"
-"0x4137","RS200_4137","RS200",,1,,,,"ATI Radeon IGP330/340/350 (A4) 4137"
+"0x4136","RS100_4136","RS100",,1,,,1,"ATI Radeon IGP320 (A3) 4136"
+"0x4137","RS200_4137","RS200",,1,,,1,"ATI Radeon IGP330/340/350 (A4) 4137"
 "0x4144","R300_AD","R300",,,,,,"ATI Radeon 9500 AD (AGP)"
 "0x4145","R300_AE","R300",,,,,,"ATI Radeon 9500 AE (AGP)"
 "0x4146","R300_AF","R300",,,,,,"ATI Radeon 9600TX AF (AGP)"
@@ -22,14 +22,14 @@
 "0x4155","RV350_4155","RV350",,,,,,"ATI Radeon 9650"
 "0x4156","RV350_AV","RV350",,,,,,"ATI FireGL RV360 AV (AGP)"
 "0x4158","MACH32","MACH32",,,,,,
-"0x4237","RS250_4237","RS200",,1,,,,"ATI Radeon 7000 IGP (A4+) 4237"
+"0x4237","RS250_4237","RS200",,1,,,1,"ATI Radeon 7000 IGP (A4+) 4237"
 "0x4242","R200_BB","R200",,,,1,,"ATI Radeon 8500 AIW BB (AGP)"
 "0x4243","R200_BC","R200",,,,1,,"ATI Radeon 8500 AIW BC (AGP)"
-"0x4336","RS100_4336","RS100",1,1,,,,"ATI Radeon IGP320M (U1) 4336"
-"0x4337","RS200_4337","RS200",1,1,,,,"ATI Radeon IGP330M/340M/350M (U2) 4337"
+"0x4336","RS100_4336","RS100",1,1,,,1,"ATI Radeon IGP320M (U1) 4336"
+"0x4337","RS200_4337","RS200",1,1,,,1,"ATI Radeon IGP330M/340M/350M (U2) 4337"
 "0x4354","MACH64CT","MACH64",,,,,,
 "0x4358","MACH64CX","MACH64",,,,,,
-"0x4437","RS250_4437","RS200",1,1,,,,"ATI Radeon Mobility 7000 IGP 4437"
+"0x4437","RS250_4437","RS200",1,1,,,1,"ATI Radeon Mobility 7000 IGP 4437"
 "0x4554","MACH64ET","MACH64",,,,,,
 "0x4742","MACH64GB","MACH64",,,,,,
 "0x4744","MACH64GD","MACH64",,,,,,
@@ -196,6 +196,7 @@
 "0x5B60","RV370_5B60","RV380",,,,,,"ATI Radeon X300 (RV370) 5B60 (PCIE)"
 "0x5B62","RV370_5B62","RV380",,,,,,"ATI Radeon X600 (RV370) 5B62 (PCIE)"
 "0x5B63","RV370_5B63","RV380",,,,,,"ATI Radeon X550 (RV370) 5B63 (PCIE)"
+"0x5657","RV370_5657","RV380",,,,,,"ATI Radeon X550XTX (RV370) 5657 (PCIE)"
 "0x5B64","RV370_5B64","RV380",,,,,,"ATI FireGL V3100 (RV370) 5B64 (PCIE)"
 "0x5B65","RV370_5B65","RV380",,,,,,"ATI FireMV 2200 PCIE (RV370) 5B65 (PCIE)"
 "0x5C61","RV280_5C61","RV280",1,,,,,"ATI Radeon Mobility 9200 (M9+) 5C61 (AGP)"
@@ -216,5 +217,137 @@
 "0x5E4C","RV410_5E4C","RV410",,,,,,"ATI Radeon X700 SE (RV410) (PCIE)"
 "0x5E4D","RV410_5E4D","RV410",,,,,,"ATI Radeon X700 (RV410) (PCIE)"
 "0x5E4F","RV410_5E4F","RV410",,,,,,"ATI Radeon X700 SE (RV410) (PCIE)"
-"0x7834","RS350_7834","RS300",,1,,,,"ATI Radeon 9100 PRO IGP 7834"
-"0x7835","RS350_7835","RS300",1,1,,,,"ATI Radeon Mobility 9200 IGP 7835"
+"0x7100","R520_7100","R520",,,,,,"ATI Radeon X1800"
+"0x7101","R520_7101","R520",1,,,,,"ATI Mobility Radeon X1800 XT"
+"0x7102","R520_7102","R520",1,,,,,"ATI Mobility Radeon X1800"
+"0x7103","R520_7103","R520",1,,,,,"ATI Mobility FireGL V7200"
+"0x7104","R520_7104","R520",,,,,,"ATI FireGL V7200"
+"0x7105","R520_7105","R520",,,,,,"ATI FireGL V5300"
+"0x7106","R520_7106","R520",1,,,,,"ATI Mobility FireGL V7100"
+"0x7108","R520_7108","R520",,,,,,"ATI Radeon X1800"
+"0x7109","R520_7109","R520",,,,,,"ATI Radeon X1800"
+"0x710A","R520_710A","R520",,,,,,"ATI Radeon X1800"
+"0x710B","R520_710B","R520",,,,,,"ATI Radeon X1800"
+"0x710C","R520_710C","R520",,,,,,"ATI Radeon X1800"
+"0x710E","R520_710E","R520",,,,,,"ATI FireGL V7300"
+"0x710F","R520_710F","R520",,,,,,"ATI FireGL V7350"
+"0x7140","RV515_7140","RV515",,,,,,"ATI Radeon X1600"
+"0x7141","RV515_7141","RV515",,,,,,"ATI RV505"
+"0x7142","RV515_7142","RV515",,,,,,"ATI Radeon X1300/X1550"
+"0x7143","RV515_7143","RV515",,,,,,"ATI Radeon X1550"
+"0x7144","RV515_7144","RV515",1,,,,,"ATI M54-GL"
+"0x7145","RV515_7145","RV515",1,,,,,"ATI Mobility Radeon X1400"
+"0x7146","RV515_7146","RV515",,,,,,"ATI Radeon X1300/X1550"
+"0x7147","RV515_7147","RV515",,,,,,"ATI Radeon X1550 64-bit"
+"0x7149","RV515_7149","RV515",1,,,,,"ATI Mobility Radeon X1300"
+"0x714A","RV515_714A","RV515",1,,,,,"ATI Mobility Radeon X1300"
+"0x714B","RV515_714B","RV515",1,,,,,"ATI Mobility Radeon X1300"
+"0x714C","RV515_714C","RV515",1,,,,,"ATI Mobility Radeon X1300"
+"0x714D","RV515_714D","RV515",,,,,,"ATI Radeon X1300"
+"0x714E","RV515_714E","RV515",,,,,,"ATI Radeon X1300"
+"0x714F","RV515_714F","RV515",,,,,,"ATI RV505"
+"0x7151","RV515_7151","RV515",,,,,,"ATI RV505"
+"0x7152","RV515_7152","RV515",,,,,,"ATI FireGL V3300"
+"0x7153","RV515_7153","RV515",,,,,,"ATI FireGL V3350"
+"0x715E","RV515_715E","RV515",,,,,,"ATI Radeon X1300"
+"0x715F","RV515_715F","RV515",,,,,,"ATI Radeon X1550 64-bit"
+"0x7180","RV515_7180","RV515",,,,,,"ATI Radeon X1300/X1550"
+"0x7181","RV515_7181","RV515",,,,,,"ATI Radeon X1600"
+"0x7183","RV515_7183","RV515",,,,,,"ATI Radeon X1300/X1550"
+"0x7186","RV515_7186","RV515",1,,,,,"ATI Mobility Radeon X1450"
+"0x7187","RV515_7187","RV515",,,,,,"ATI Radeon X1300/X1550"
+"0x7188","RV515_7188","RV515",1,,,,,"ATI Mobility Radeon X2300"
+"0x718A","RV515_718A","RV515",1,,,,,"ATI Mobility Radeon X2300"
+"0x718B","RV515_718B","RV515",1,,,,,"ATI Mobility Radeon X1350"
+"0x718C","RV515_718C","RV515",1,,,,,"ATI Mobility Radeon X1350"
+"0x718D","RV515_718D","RV515",1,,,,,"ATI Mobility Radeon X1450"
+"0x718F","RV515_718F","RV515",,,,,,"ATI Radeon X1300"
+"0x7193","RV515_7193","RV515",,,,,,"ATI Radeon X1550"
+"0x7196","RV515_7196","RV515",1,,,,,"ATI Mobility Radeon X1350"
+"0x719B","RV515_719B","RV515",,,,,,"ATI FireMV 2250"
+"0x719F","RV515_719F","RV515",,,,,,"ATI Radeon X1550 64-bit"
+"0x71C0","RV530_71C0","RV530",,,,,,"ATI Radeon X1600"
+"0x71C1","RV530_71C1","RV530",,,,,,"ATI Radeon X1650"
+"0x71C2","RV530_71C2","RV530",,,,,,"ATI Radeon X1600"
+"0x71C3","RV530_71C3","RV530",,,,,,"ATI Radeon X1600"
+"0x71C4","RV530_71C4","RV530",1,,,,,"ATI Mobility FireGL V5200"
+"0x71C5","RV530_71C5","RV530",1,,,,,"ATI Mobility Radeon X1600"
+"0x71C6","RV530_71C6","RV530",,,,,,"ATI Radeon X1650"
+"0x71C7","RV530_71C7","RV530",,,,,,"ATI Radeon X1650"
+"0x71CD","RV530_71CD","RV530",,,,,,"ATI Radeon X1600"
+"0x71CE","RV530_71CE","RV530",,,,,,"ATI Radeon X1300 XT/X1600 Pro"
+"0x71D2","RV530_71D2","RV530",,,,,,"ATI FireGL V3400"
+"0x71D4","RV530_71D4","RV530",1,,,,,"ATI Mobility FireGL V5250"
+"0x71D5","RV530_71D5","RV530",1,,,,,"ATI Mobility Radeon X1700"
+"0x71D6","RV530_71D6","RV530",1,,,,,"ATI Mobility Radeon X1700 XT"
+"0x71DA","RV530_71DA","RV530",,,,,,"ATI FireGL V5200"
+"0x71DE","RV530_71DE","RV530",1,,,,,"ATI Mobility Radeon X1700"
+"0x7200","RV530_7200","RV530",,,,,,"ATI  Radeon X2300HD"
+"0x7210","RV530_7210","RV530",1,,,,,"ATI Mobility Radeon HD 2300"
+"0x7211","RV530_7211","RV530",1,,,,,"ATI Mobility Radeon HD 2300"
+"0x7240","R580_7240","R580",,,,,,"ATI Radeon X1950"
+"0x7243","R580_7243","R580",,,,,,"ATI Radeon X1900"
+"0x7244","R580_7244","R580",,,,,,"ATI Radeon X1950"
+"0x7245","R580_7245","R580",,,,,,"ATI Radeon X1900"
+"0x7246","R580_7246","R580",,,,,,"ATI Radeon X1900"
+"0x7247","R580_7247","R580",,,,,,"ATI Radeon X1900"
+"0x7248","R580_7248","R580",,,,,,"ATI Radeon X1900"
+"0x7249","R580_7249","R580",,,,,,"ATI Radeon X1900"
+"0x724A","R580_724A","R580",,,,,,"ATI Radeon X1900"
+"0x724B","R580_724B","R580",,,,,,"ATI Radeon X1900"
+"0x724C","R580_724C","R580",,,,,,"ATI Radeon X1900"
+"0x724D","R580_724D","R580",,,,,,"ATI Radeon X1900"
+"0x724E","R580_724E","R580",,,,,,"ATI AMD Stream Processor"
+"0x724F","R580_724F","R580",,,,,,"ATI Radeon X1900"
+"0x7280","RV570_7280","RV570",,,,,,"ATI Radeon X1950"
+"0x7281","RV560_7281","RV560",,,,,,"ATI RV560"
+"0x7283","RV560_7283","RV560",,,,,,"ATI RV560"
+"0x7284","R580_7284","R580",1,,,,,"ATI Mobility Radeon X1900"
+"0x7287","RV560_7287","RV560",,,,,,"ATI RV560"
+"0x7288","RV570_7288","RV570",,,,,,"ATI Radeon X1950 GT"
+"0x7289","RV570_7289","RV570",,,,,,"ATI RV570"
+"0x728B","RV570_728B","RV570",,,,,,"ATI RV570"
+"0x728C","RV570_728C","RV570",,,,,,"ATI ATI FireGL V7400"
+"0x7290","RV560_7290","RV560",,,,,,"ATI RV560"
+"0x7291","RV560_7291","RV560",,,,,,"ATI Radeon X1650"
+"0x7293","RV560_7293","RV560",,,,,,"ATI Radeon X1650"
+"0x7297","RV560_7297","RV560",,,,,,"ATI RV560"
+"0x7834","RS350_7834","RS300",,1,,,1,"ATI Radeon 9100 PRO IGP 7834"
+"0x7835","RS350_7835","RS300",1,1,,,1,"ATI Radeon Mobility 9200 IGP 7835"
+"0x791E","RS690_791E","RS690",,1,,,1,"ATI Radeon X1200"
+"0x791F","RS690_791F","RS690",,1,,,1,"ATI Radeon X1200"
+"0x796C","RS740_796C","RS740",,1,,,1,"ATI RS740"
+"0x796D","RS740_796D","RS740",,1,,,1,"ATI RS740M"
+"0x796E","RS740_796E","RS740",,1,,,1,"ATI RS740"
+"0x796F","RS740_796F","RS740",,1,,,1,"ATI RS740M"
+"0x9400","R600_9400","R600",,,,,,"ATI Radeon HD 2900 XT"
+"0x9401","R600_9401","R600",,,,,,"ATI Radeon HD 2900 XT"
+"0x9402","R600_9402","R600",,,,,,"ATI Radeon HD 2900 XT"
+"0x9403","R600_9403","R600",,,,,,"ATI Radeon HD 2900 Pro"
+"0x9405","R600_9405","R600",,,,,,"ATI Radeon HD 2900 GT"
+"0x940A","R600_940A","R600",,,,,,"ATI FireGL V8650"
+"0x940B","R600_940B","R600",,,,,,"ATI FireGL V8600"
+"0x940F","R600_940F","R600",,,,,,"ATI FireGL V7600"
+"0x94C0","RV610_94C0","RV610",,,,,,"ATI RV610"
+"0x94C1","RV610_94C1","RV610",,,,,,"ATI Radeon HD 2400 XT"
+"0x94C3","RV610_94C3","RV610",,,,,,"ATI Radeon HD 2400 Pro"
+"0x94C4","RV610_94C4","RV610",,,,,,"ATI ATI Radeon HD 2400 PRO AGP"
+"0x94C5","RV610_94C5","RV610",,,,,,"ATI FireGL V4000"
+"0x94C6","RV610_94C6","RV610",,,,,,"ATI RV610"
+"0x94C7","RV610_94C7","RV610",,,,,,"ATI ATI Radeon HD 2350"
+"0x94C8","RV610_94C8","RV610",1,,,,,"ATI Mobility Radeon HD 2400 XT"
+"0x94C9","RV610_94C9","RV610",1,,,,,"ATI Mobility Radeon HD 2400"
+"0x94CB","RV610_94CB","RV610",1,,,,,"ATI ATI RADEON E2400"
+"0x94CC","RV610_94CC","RV610",,,,,,"ATI RV610"
+"0x9580","RV630_9580","RV630",,,,,,"ATI RV630"
+"0x9581","RV630_9581","RV630",1,,,,,"ATI Mobility Radeon HD 2600"
+"0x9583","RV630_9583","RV630",1,,,,,"ATI Mobility Radeon HD 2600 XT"
+"0x9586","RV630_9586","RV630",,,,,,"ATI ATI Radeon HD 2600 XT AGP"
+"0x9587","RV630_9587","RV630",,,,,,"ATI ATI Radeon HD 2600 Pro AGP"
+"0x9588","RV630_9588","RV630",,,,,,"ATI Radeon HD 2600 XT"
+"0x9589","RV630_9589","RV630",,,,,,"ATI Radeon HD 2600 Pro"
+"0x958A","RV630_958A","RV630",,,,,,"ATI Gemini RV630"
+"0x958B","RV630_958B","RV630",1,,,,,"ATI Gemini ATI Mobility Radeon HD 2600 XT"
+"0x958C","RV630_958C","RV630",,,,,,"ATI FireGL V5600"
+"0x958D","RV630_958D","RV630",,,,,,"ATI FireGL V3600"
+"0x958E","RV630_958E","RV630",,,,,,"ATI ATI Radeon HD 2600 LE"
diff --git a/src/r128.h b/src/r128.h
index dd1a670..1205245 100644
--- a/src/r128.h
+++ b/src/r128.h
@@ -63,6 +63,8 @@
 #include "GL/glxint.h"
 #endif
 
+#include "atipcirename.h"
+
 #define R128_DEBUG          0   /* Turn off debugging output               */
 #define R128_IDLE_RETRY    32   /* Fall out of idle loops after this count */
 #define R128_TIMEOUT  2000000   /* Fall out of wait loops after this count */
@@ -234,8 +236,8 @@ typedef struct {
     unsigned long     MMIOAddr;     /* MMIO region physical address          */
     unsigned long     BIOSAddr;     /* BIOS physical address                 */
 
-    unsigned char     *MMIO;        /* Map of MMIO region                    */
-    unsigned char     *FB;          /* Map of frame buffer                   */
+    void              *MMIO;        /* Map of MMIO region                    */
+    void              *FB;          /* Map of frame buffer                   */
 
     CARD32            MemCntl;
     CARD32            BusCntl;
diff --git a/src/r128_cursor.c b/src/r128_cursor.c
index 908ddb9..8321284 100644
--- a/src/r128_cursor.c
+++ b/src/r128_cursor.c
@@ -133,7 +133,7 @@ static void R128LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image)
     R128InfoPtr   info      = R128PTR(pScrn);
     unsigned char *R128MMIO = info->MMIO;
     CARD32        *s        = (pointer)image;
-    CARD32        *d        = (pointer)(info->FB + info->cursor_start);
+    CARD32        *d        = (pointer)((CARD8*)info->FB + info->cursor_start);
     int           y;
     CARD32        save;
 
diff --git a/src/r128_dri.c b/src/r128_dri.c
index edb77ba..da201e3 100644
--- a/src/r128_dri.c
+++ b/src/r128_dri.c
@@ -470,8 +470,8 @@ static Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen)
     xf86DrvMsg(pScreen->myNum, X_INFO,
 	       "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
 	       mode, vendor, device,
-	       info->PciInfo->vendor,
-	       info->PciInfo->chipType);
+	       PCI_DEV_VENDOR_ID(info->PciInfo),
+	       PCI_DEV_DEVICE_ID(info->PciInfo));
 
     if (drmAgpEnable(info->drmFD, mode) < 0) {
 	xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n");
@@ -910,9 +910,9 @@ static void R128DRIIrqInit(R128InfoPtr info, ScreenPtr pScreen)
    if (!info->irq) {
       info->irq = drmGetInterruptFromBusID(
 	 info->drmFD,
-	 ((pciConfigPtr)info->PciInfo->thisCard)->busnum,
-	 ((pciConfigPtr)info->PciInfo->thisCard)->devnum,
-	 ((pciConfigPtr)info->PciInfo->thisCard)->funcnum);
+	 PCI_CFG_BUS(info->PciInfo),
+	 PCI_CFG_DEV(info->PciInfo),
+	 PCI_CFG_FUNC(info->PciInfo));
 
       if((drmCtlInstHandler(info->drmFD, info->irq)) != 0) {
 	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -1029,9 +1029,9 @@ Bool R128DRIScreenInit(ScreenPtr pScreen)
 	pDRIInfo->busIdString            = xalloc(64);
 	sprintf(pDRIInfo->busIdString,
 		"PCI:%d:%d:%d",
-		info->PciInfo->bus,
-		info->PciInfo->device,
-		info->PciInfo->func);
+		PCI_DEV_BUS(info->PciInfo),
+		PCI_DEV_DEV(info->PciInfo),
+		PCI_DEV_FUNC(info->PciInfo));
     }
     pDRIInfo->ddxDriverMajorVersion      = R128_VERSION_MAJOR;
     pDRIInfo->ddxDriverMinorVersion      = R128_VERSION_MINOR;
diff --git a/src/r128_driver.c b/src/r128_driver.c
index 6e26a6e..45917cd 100644
--- a/src/r128_driver.c
+++ b/src/r128_driver.c
@@ -194,186 +194,6 @@ R128RAMRec R128RAM[] = {        /* Memory Specifications
     { 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SGRAM" },
 };
 
-#ifdef WITH_VGAHW
-static const char *vgahwSymbols[] = {
-    "vgaHWFreeHWRec",
-    "vgaHWGetHWRec",
-    "vgaHWGetIndex",
-    "vgaHWLock",
-    "vgaHWRestore",
-    "vgaHWSave",
-    "vgaHWUnlock",
-    NULL
-};
-#endif
-
-static const char *fbdevHWSymbols[] = {
-    "fbdevHWInit",
-    "fbdevHWUseBuildinMode",
-    "fbdevHWGetLineLength",
-    "fbdevHWGetVidmem",
-
-    "fbdevHWDPMSSet",
-    "fbdevHWDPMSSetWeak",
-
-    /* colormap */
-    "fbdevHWLoadPalette",
-    "fbdevHWLoadPaletteWeak",
-
-    /* ScrnInfo hooks */
-    "fbdevHWAdjustFrame",
-    "fbdevHWAdjustFrameWeak",
-    "fbdevHWEnterVT",
-    "fbdevHWLeaveVT",
-    "fbdevHWModeInit",
-    "fbdevHWRestore",
-    "fbdevHWSave",
-    "fbdevHWSwitchMode",
-    "fbdevHWSwitchModeWeak",
-    "fbdevHWValidModeWeak",
-
-    "fbdevHWMapMMIO",
-    "fbdevHWMapVidmem",
-    "fbdevHWUnmapMMIO",
-    "fbdevHWUnmapVidmem",
-
-    NULL
-};
-
-static const char *ddcSymbols[] = {
-    "xf86PrintEDID",
-    "xf86DoEDID_DDC1",
-    "xf86DoEDID_DDC2",
-    NULL
-};
-
-static const char *i2cSymbols[] = {
-    "xf86CreateI2CBusRec",
-    "xf86I2CBusInit",
-    NULL
-};
-
-static const char *fbSymbols[] = {
-    "fbPictureInit",
-    "fbScreenInit",
-    NULL
-};
-
-static const char *xaaSymbols[] = {
-    "XAACreateInfoRec",
-    "XAADestroyInfoRec",
-    "XAAInit",
-    NULL
-};
-
-static const char *ramdacSymbols[] = {
-    "xf86CreateCursorInfoRec",
-    "xf86DestroyCursorInfoRec",
-    "xf86InitCursor",
-    NULL
-};
-
-#ifdef XF86DRI
-static const char *drmSymbols[] = {
-    "drmAddBufs",
-    "drmAddMap",
-    "drmAgpAcquire",
-    "drmAgpAlloc",
-    "drmAgpBase",
-    "drmAgpBind",
-    "drmAgpDeviceId",
-    "drmAgpEnable",
-    "drmAgpFree",
-    "drmAgpGetMode",
-    "drmAgpRelease",
-    "drmAgpUnbind",
-    "drmAgpVendorId",
-    "drmAvailable",
-    "drmCommandNone",
-    "drmCommandRead",
-    "drmCommandWrite",
-    "drmCommandWriteRead",
-    "drmCtlInstHandler",
-    "drmCtlUninstHandler",
-    "drmFreeBufs",
-    "drmFreeVersion",
-    "drmGetInterruptFromBusID",
-    "drmGetLibVersion",
-    "drmGetVersion",
-    "drmMap",
-    "drmMapBufs",
-    "drmDMA",
-    "drmScatterGatherAlloc",
-    "drmScatterGatherFree",
-    "drmUnmap",
-    "drmUnmapBufs",
-    NULL
-};
-
-static const char *driSymbols[] = {
-    "DRICloseScreen",
-    "DRICreateInfoRec",
-    "DRIDestroyInfoRec",
-    "DRIFinishScreenInit",
-    "DRIGetDeviceInfo",
-    "DRIGetSAREAPrivate",
-    "DRILock",
-    "DRIQueryVersion",
-    "DRIScreenInit",
-    "DRIUnlock",
-    "GlxSetVisualConfigs",
-    "DRICreatePCIBusID",
-    NULL
-};
-
-static const char *driShadowFBSymbols[] = {
-    "ShadowFBInit",
-    NULL
-};
-#endif
-
-static const char *vbeSymbols[] = {
-    "VBEInit",
-    "vbeDoEDID",
-    "vbeFree",
-    NULL
-};
-
-static const char *int10Symbols[] = {
-    "xf86InitInt10",
-    "xf86FreeInt10",
-    "xf86int10Addr",
-    NULL
-};
-
-void R128LoaderRefSymLists(void)
-{
-    /*
-     * Tell the loader about symbols from other modules that this module might
-     * refer to.
-     */
-    xf86LoaderRefSymLists(
-#ifdef WITH_VGAHW
-		      vgahwSymbols,
-#endif
-		      fbSymbols,
-		      xaaSymbols,
-		      ramdacSymbols,
-#ifdef XF86DRI
-		      drmSymbols,
-		      driSymbols,
-		      driShadowFBSymbols,
-#endif
-		      fbdevHWSymbols,
-		      int10Symbols,
-		      vbeSymbols,
-		      /* ddcsymbols, */
-		      i2cSymbols,
-		      /* shadowSymbols, */
-		      NULL);
-}
-
-#ifdef XFree86LOADER
 int getR128EntityIndex(void)
 {
     int *r128_entity_index = LoaderSymbol("gR128EntityIndex");
@@ -382,13 +202,6 @@ int getR128EntityIndex(void)
     else
         return *r128_entity_index;
 }
-#else
-extern int gR128EntityIndex;
-int getR128EntityIndex(void)
-{
-    return gR128EntityIndex;
-}
-#endif
 
 R128EntPtr R128EntPriv(ScrnInfoPtr pScrn)
 {
@@ -425,11 +238,26 @@ static Bool R128MapMMIO(ScrnInfoPtr pScrn)
     if (info->FBDev) {
 	info->MMIO = fbdevHWMapMMIO(pScrn);
     } else {
+#ifndef XSERVER_LIBPCIACCESS
 	info->MMIO = xf86MapPciMem(pScrn->scrnIndex,
 				   VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
 				   info->PciTag,
 				   info->MMIOAddr,
 				   R128_MMIOSIZE);
+#else
+	int err = pci_device_map_range(info->PciInfo,
+				       info->MMIOAddr,
+				       R128_MMIOSIZE,
+				       PCI_DEV_MAP_FLAG_WRITABLE,
+				       &info->MMIO);
+
+	if (err) {
+	    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+                        "Unable to map MMIO aperture. %s (%d)\n",
+                        strerror (err), err);
+	    return FALSE;
+	}
+#endif
     }
 
     if (!info->MMIO) return FALSE;
@@ -445,7 +273,11 @@ static Bool R128UnmapMMIO(ScrnInfoPtr pScrn)
     if (info->FBDev)
 	fbdevHWUnmapMMIO(pScrn);
     else {
+#ifndef XSERVER_LIBPCIACCESS
 	xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, R128_MMIOSIZE);
+#else
+	pci_device_unmap_range(info->PciInfo, info->MMIO, R128_MMIOSIZE);
+#endif
     }
     info->MMIO = NULL;
     return TRUE;
@@ -459,11 +291,27 @@ static Bool R128MapFB(ScrnInfoPtr pScrn)
     if (info->FBDev) {
 	info->FB = fbdevHWMapVidmem(pScrn);
     } else {
+#ifndef XSERVER_LIBPCIACCESS
 	info->FB = xf86MapPciMem(pScrn->scrnIndex,
 				 VIDMEM_FRAMEBUFFER,
 				 info->PciTag,
 				 info->LinearAddr,
 				 info->FbMapSize);
+#else
+	int err = pci_device_map_range(info->PciInfo,
+				       info->LinearAddr,
+				       info->FbMapSize,
+				       PCI_DEV_MAP_FLAG_WRITABLE |
+				       PCI_DEV_MAP_FLAG_WRITE_COMBINE,
+				       &info->FB);
+
+	if (err) {
+	    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+                        "Unable to map FB aperture. %s (%d)\n",
+                        strerror (err), err);
+	    return FALSE;
+	}
+#endif
     }
 
     if (!info->FB) return FALSE;
@@ -478,7 +326,11 @@ static Bool R128UnmapFB(ScrnInfoPtr pScrn)
     if (info->FBDev)
 	fbdevHWUnmapVidmem(pScrn);
     else
+#ifndef XSERVER_LIBPCIACCESS
 	xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize);
+#else
+	pci_device_unmap_range(info->PciInfo, info->FB, info->FbMapSize);
+#endif
     info->FB = NULL;
     return TRUE;
 }
@@ -639,7 +491,13 @@ static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
 			(info->VBIOS[(v) + 2] << 16) | \
 			(info->VBIOS[(v) + 3] << 24))
 
-    if (!(info->VBIOS = xalloc(R128_VBIOS_SIZE))) {
+#ifdef XSERVER_LIBPCIACCESS
+    info->VBIOS = xalloc(info->PciInfo->rom_size);
+#else
+    info->VBIOS = xalloc(R128_VBIOS_SIZE);
+#endif
+
+    if (!info->VBIOS) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "Cannot allocate space for hold Video BIOS!\n");
 	return FALSE;
@@ -650,6 +508,12 @@ static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
 	(void)memcpy(info->VBIOS, xf86int10Addr(pInt10, info->BIOSAddr),
 		     R128_VBIOS_SIZE);
     } else {
+#ifdef XSERVER_LIBPCIACCESS
+	if (pci_device_read_rom(info->PciInfo, info->VBIOS)) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		       "Failed to read PCI ROM!\n");
+	}
+#else
 	xf86ReadPciBIOS(0, info->PciTag, 0, info->VBIOS, R128_VBIOS_SIZE);
 	if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -659,6 +523,7 @@ static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
 	    info->BIOSAddr = 0x000c0000;
 	    xf86ReadDomainMemory(info->PciTag, info->BIOSAddr, R128_VBIOS_SIZE, info->VBIOS);
 	}
+#endif
     }
     if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
 	info->BIOSAddr = 0x00000000;
@@ -997,7 +862,7 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
 	info->Chipset  = dev->chipID;
 	from           = X_CONFIG;
     } else {
-	info->Chipset = info->PciInfo->chipType;
+	info->Chipset = PCI_DEV_DEVICE_ID(info->PciInfo);
     }
     pScrn->chipset = (char *)xf86TokenToString(R128Chipsets, info->Chipset);
 
@@ -1021,7 +886,7 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
 				/* Framebuffer */
 
     from             = X_PROBED;
-    info->LinearAddr = info->PciInfo->memBase[0] & 0xfc000000;
+    info->LinearAddr = PCI_REGION_BASE(info->PciInfo, 0, REGION_MEM) & 0xfc000000;
     pScrn->memPhysBase = info->LinearAddr;
     if (dev->MemBase) {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -1040,7 +905,7 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
 
 				/* MMIO registers */
     from             = X_PROBED;
-    info->MMIOAddr   = info->PciInfo->memBase[2] & 0xffffff00;
+    info->MMIOAddr   = PCI_REGION_BASE(info->PciInfo, 2, REGION_MEM) & 0xffffff00;
     if (dev->IOBase) {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		   "MMIO address override, using 0x%08lx instead of 0x%08lx\n",
@@ -1055,6 +920,7 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
     xf86DrvMsg(pScrn->scrnIndex, from,
 	       "MMIO registers at 0x%08lx\n", info->MMIOAddr);
 
+#ifndef XSERVER_LIBPCIACCESS
 				/* BIOS */
     from              = X_PROBED;
     info->BIOSAddr    = info->PciInfo->biosBase & 0xfffe0000;
@@ -1070,6 +936,7 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
 	xf86DrvMsg(pScrn->scrnIndex, from,
 		   "BIOS at 0x%08lx\n", info->BIOSAddr);
     }
+#endif
 
 				/* Flat panel (part 1) */
     if (xf86GetOptValBool(info->Options, OPTION_PROG_FP_REGS,
@@ -1376,20 +1243,18 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
 
 static Bool R128PreInitDDC(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
 {
-#if !defined(__powerpc__) && !defined(__alpha__)
+#if !defined(__powerpc__) && !defined(__alpha__) && !defined(__sparc__)
     R128InfoPtr   info = R128PTR(pScrn);
     vbeInfoPtr pVbe;
 #endif
 
     if (!xf86LoadSubModule(pScrn, "ddc")) return FALSE;
-    xf86LoaderReqSymLists(ddcSymbols, NULL);
 
-#if defined(__powerpc__) || defined(__alpha__)
+#if defined(__powerpc__) || defined(__alpha__) || defined(__sparc__)
     /* Int10 is broken on PPC and some Alphas */
     return TRUE;
 #else
     if (xf86LoadSubModule(pScrn, "vbe")) {
-	xf86LoaderReqSymLists(vbeSymbols,NULL);
 	pVbe = VBEInit(pInt10,info->pEnt->index);
 	if (!pVbe) return FALSE;
         xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(pVbe,NULL)));
@@ -1444,9 +1309,7 @@ static Bool
 R128I2cInit(ScrnInfoPtr pScrn)
 {
     R128InfoPtr info = R128PTR(pScrn);
-    if ( xf86LoadSubModule(pScrn, "i2c") )
-        xf86LoaderReqSymLists(i2cSymbols,NULL);
-	else{
+    if ( !xf86LoadSubModule(pScrn, "i2c") ) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
             "Failed to load i2c module\n");
 		return FALSE;
@@ -1866,7 +1729,6 @@ static Bool R128PreInitModes(ScrnInfoPtr pScrn)
 
 				/* Get ScreenInit function */
     if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
-    xf86LoaderReqSymLists(fbSymbols, NULL);
 
     info->CurrentLayout.displayWidth = pScrn->displayWidth;
     info->CurrentLayout.mode = pScrn->currentMode;
@@ -1881,7 +1743,6 @@ static Bool R128PreInitCursor(ScrnInfoPtr pScrn)
 
     if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
 	if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE;
-	xf86LoaderReqSymLists(ramdacSymbols, NULL);
     }
     return TRUE;
 }
@@ -1893,7 +1754,6 @@ static Bool R128PreInitAccel(ScrnInfoPtr pScrn)
 
     if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
 	if (!xf86LoadSubModule(pScrn, "xaa")) return FALSE;
-	xf86LoaderReqSymLists(xaaSymbols, NULL);
     }
     return TRUE;
 }
@@ -1904,7 +1764,6 @@ static Bool R128PreInitInt10(ScrnInfoPtr pScrn, xf86Int10InfoPtr *ppInt10)
 #if 1 && !defined(__alpha__)
     /* int10 is broken on some Alphas */
     if (xf86LoadSubModule(pScrn, "int10")) {
-	xf86LoaderReqSymLists(int10Symbols, NULL);
 	xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n");
 	*ppInt10 = xf86InitInt10(info->pEnt->index);
     }
@@ -2018,8 +1877,6 @@ static Bool R128PreInitDRI(ScrnInfoPtr pScrn)
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "Couldn't load shadowfb module:\n");
     } else {
-	xf86LoaderReqSymLists(driShadowFBSymbols, NULL);
-
 	info->allowPageFlip = xf86ReturnOptValBool(info->Options,
 						   OPTION_PAGE_FLIP,
 						   FALSE);
@@ -2101,15 +1958,15 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
     }
 
     info->PciInfo      = xf86GetPciInfoForEntity(info->pEnt->index);
-    info->PciTag       = pciTag(info->PciInfo->bus,
-				info->PciInfo->device,
-				info->PciInfo->func);
+    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",
-	       info->PciInfo->bus,
-	       info->PciInfo->device,
-	       info->PciInfo->func);
+	       PCI_DEV_BUS(info->PciInfo),
+	       PCI_DEV_DEV(info->PciInfo),
+	       PCI_DEV_FUNC(info->PciInfo));
 
     if (xf86RegisterResources(info->pEnt->index, 0, ResNone)) goto fail;
     if (xf86SetOperatingState(resVga, info->pEnt->index, ResUnusedOpr)) goto fail;
@@ -2127,7 +1984,7 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options);
 
     /* By default, don't do VGA IOs on ppc */
-#if defined(__powerpc__) || !defined(WITH_VGAHW)
+#if defined(__powerpc__) || defined(__sparc__) || !defined(WITH_VGAHW)
     info->VGAAccess = FALSE;
 #else
     info->VGAAccess = TRUE;
@@ -2139,7 +1996,6 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
        if (!xf86LoadSubModule(pScrn, "vgahw"))
            info->VGAAccess = FALSE;
         else {
-           xf86LoaderReqSymLists(vgahwSymbols, NULL);
             if (!vgaHWGetHWRec(pScrn))
                info->VGAAccess = FALSE;
        }
@@ -2186,7 +2042,6 @@ Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
     if (info->FBDev) {
 	/* check for linux framebuffer device */
 	if (!xf86LoadSubModule(pScrn, "fbdevhw")) return FALSE;
-	xf86LoaderReqSymLists(fbdevHWSymbols, NULL);
 	if (!fbdevHWInit(pScrn, info->PciInfo, NULL)) return FALSE;
 	pScrn->SwitchMode    = fbdevHWSwitchModeWeak();
 	pScrn->AdjustFrame   = fbdevHWAdjustFrameWeak();
diff --git a/src/r128_misc.c b/src/r128_misc.c
index 5ace7d7..f8bccfe 100644
--- a/src/r128_misc.c
+++ b/src/r128_misc.c
@@ -24,8 +24,6 @@
 #include "config.h"
 #endif
 
-#ifdef XFree86LOADER
-
 #include "ativersion.h"
 
 #include "r128_probe.h"
@@ -67,11 +65,8 @@ R128Setup
 
     if (!Inited)
     {
-        /* Ensure main driver module is loaded, but not as a submodule */
-        if (!xf86ServerIsOnlyDetecting() && !LoaderSymbol(ATI_NAME))
-            xf86LoadOneModule(ATI_DRIVER_NAME, Options);
-
-        R128LoaderRefSymLists();
+        if (xf86ServerIsOnlyDetecting() || !LoaderSymbol(ATI_NAME))
+            xf86AddDriver(&R128, Module, 0);
 
         Inited = TRUE;
     }
@@ -86,5 +81,3 @@ _X_EXPORT XF86ModuleData r128ModuleData =
     R128Setup,
     NULL
 };
-
-#endif /* XFree86LOADER */
diff --git a/src/r128_probe.c b/src/r128_probe.c
index 0be21e8..5dd5cc9 100644
--- a/src/r128_probe.c
+++ b/src/r128_probe.c
@@ -106,7 +106,7 @@ PciChipsets R128PciChipsets[] = {
 int gR128EntityIndex = -1;
 
 /* Return the options for supported chipset 'n'; NULL otherwise */
-_X_EXPORT const OptionInfoRec *
+static const OptionInfoRec *
 R128AvailableOptions(int chipid, int busid)
 {
     int i;
@@ -125,7 +125,7 @@ R128AvailableOptions(int chipid, int busid)
 }
 
 /* Return the string name for supported chipset 'n'; NULL otherwise. */
-_X_EXPORT void
+static void
 R128Identify(int flags)
 {
     xf86PrintChipsets(R128_NAME,
@@ -134,7 +134,7 @@ R128Identify(int flags)
 }
 
 /* Return TRUE if chipset is present; FALSE otherwise. */
-_X_EXPORT Bool
+static Bool
 R128Probe(DriverPtr drv, int flags)
 {
     int           numUsed;
@@ -253,3 +253,14 @@ R128Probe(DriverPtr drv, int flags)
 
     return foundScreen;
 }
+
+_X_EXPORT DriverRec R128 =
+{
+    R128_VERSION_CURRENT,
+    R128_DRIVER_NAME,
+    R128Identify,
+    R128Probe,
+    R128AvailableOptions,
+    NULL,
+    0
+};
diff --git a/src/r128_probe.h b/src/r128_probe.h
index 180e52a..719340a 100644
--- a/src/r128_probe.h
+++ b/src/r128_probe.h
@@ -38,6 +38,8 @@
 
 #include "xf86str.h"
 
+extern DriverRec R128;
+
 typedef struct
 {
     Bool IsDRIEnabled;
@@ -54,14 +56,9 @@ typedef struct
 } R128EntRec, *R128EntPtr;
 
 /* r128_probe.c */
-extern const OptionInfoRec * R128AvailableOptions(int, int);
-extern void                  R128Identify(int);
-extern Bool                  R128Probe(DriverPtr, int);
-
 extern PciChipsets           R128PciChipsets[];
 
 /* r128_driver.c */
-extern void                  R128LoaderRefSymLists(void);
 extern Bool                  R128PreInit(ScrnInfoPtr, int);
 extern Bool                  R128ScreenInit(int, ScreenPtr, int, char **);
 extern Bool                  R128SwitchMode(int, DisplayModePtr, int);
diff --git a/src/r128_video.c b/src/r128_video.c
index 0f715aa..8e83323 100644
--- a/src/r128_video.c
+++ b/src/r128_video.c
@@ -397,6 +397,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 *buf;
     int err=-1, i, idx, offset, hpass, passes, srcpassbytes, dstpassbytes;
     int sizes[MAXPASSES], list[MAXPASSES];
@@ -439,7 +440,7 @@ R128DMA(
     dstpassbytes = hpass*dstPitch;
     dstPitch /= 8;
 
-    for (i=0, offset=dst-info->FB; i<passes; i++, offset+=dstpassbytes) {
+    for (i=0, offset=dst-fb; i<passes; i++, offset+=dstpassbytes) {
         if (i == (passes-1) && (h % hpass) != 0) {
 	    hpass = h % hpass;
 	    srcpassbytes = w*hpass;
@@ -775,6 +776,7 @@ R128PutImage(
 ){
    R128InfoPtr info = R128PTR(pScrn);
    R128PortPrivPtr pPriv = (R128PortPrivPtr)data;
+   unsigned char *fb = (CARD8*)info->FB;
    INT32 xa, xb, ya, yb;
    int new_size, offset, s1offset, s2offset, s3offset;
    int srcPitch, srcPitch2, dstPitch;
@@ -899,7 +901,7 @@ R128PutImage(
 
 	nlines = ((((yb + 0xffff) >> 16) + 1) & ~1) - top;
 	R128CopyData420(info, buf + s1offset, buf + s2offset, buf + s3offset,
-			info->FB+d1offset, info->FB+d2offset, info->FB+d3offset,
+			fb + d1offset, fb + d2offset, fb + d3offset,
 			srcPitch, srcPitch2, dstPitch, nlines, npixels);
 	break;
     case FOURCC_UYVY:
@@ -914,7 +916,7 @@ R128PutImage(
 	d3offset = 0;
 	s1offset += (top * srcPitch) + left;
 	nlines = ((yb + 0xffff) >> 16) - top;
-	R128CopyData422(info, buf + s1offset, info->FB + d1offset,
+	R128CopyData422(info, buf + s1offset, fb + d1offset,
 			srcPitch, dstPitch, nlines, npixels);
 	break;
     }
diff --git a/src/radeon.h b/src/radeon.h
index 801d616..ec952b5 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -166,7 +166,8 @@ typedef enum {
     OPTION_DEFAULT_TMDS_PLL,
     OPTION_TVDAC_LOAD_DETECT,
     OPTION_FORCE_TVOUT,
-    OPTION_TVSTD
+    OPTION_TVSTD,
+    OPTION_IGNORE_LID_STATUS
 } RADEONOpts;
 
 
@@ -206,189 +207,26 @@ typedef struct {
     CARD16 rr4_offset;
 } RADEONBIOSInitTable;
 
-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            bios_4_scratch;
-    CARD32            bios_5_scratch;
-    CARD32            bios_6_scratch;
-    CARD32            surface_cntl;
-    CARD32            surfaces[8][3];
-    CARD32            mc_agp_location;
-    CARD32            mc_fb_location;
-    CARD32            display_base_addr;
-    CARD32            display2_base_addr;
-    CARD32            ov0_base_addr;
-
-				/* Other registers to save for VT switches */
-    CARD32            dp_datatype;
-    CARD32            rbbm_soft_reset;
-    CARD32            clock_cntl_index;
-    CARD32            amcgpio_en_reg;
-    CARD32            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;
-    CARD32            disp_merge_cntl;
-    CARD32            grph_buffer_cntl;
-    CARD32            crtc_more_cntl;
-    CARD32            crtc_tile_x0_y0;
-
-				/* CRTC2 registers */
-    CARD32            crtc2_gen_cntl;
-    CARD32            dac_macro_cntl;
-    CARD32            dac2_cntl;
-    CARD32            disp_output_cntl;
-    CARD32            disp_tv_out_cntl;
-    CARD32            disp_hw_debug;
-    CARD32            disp2_merge_cntl;
-    CARD32            grph2_buffer_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;
-    CARD32            crtc2_tile_x0_y0;
-
-				/* Flat panel registers */
-    CARD32            fp_crtc_h_total_disp;
-    CARD32            fp_crtc_v_total_disp;
-    CARD32            fp_gen_cntl;
-    CARD32            fp2_gen_cntl;
-    CARD32            fp_h_sync_strt_wid;
-    CARD32            fp_h2_sync_strt_wid;
-    CARD32            fp_horz_stretch;
-    CARD32            fp_panel_cntl;
-    CARD32            fp_v_sync_strt_wid;
-    CARD32            fp_v2_sync_strt_wid;
-    CARD32            fp_vert_stretch;
-    CARD32            lvds_gen_cntl;
-    CARD32            lvds_pll_cntl;
-    CARD32            tmds_pll_cntl;
-    CARD32            tmds_transmitter_cntl;
-
-				/* Computed values for PLL */
-    CARD32            dot_clock_freq;
-    CARD32            pll_output_freq;
-    int               feedback_div;
-    int               reference_div;
-    int               post_div;
-
-				/* PLL registers */
-    unsigned          ppll_ref_div;
-    unsigned          ppll_div_3;
-    CARD32            htotal_cntl;
-    CARD32            vclk_ecp_cntl;
-
-				/* Computed values for PLL2 */
-    CARD32            dot_clock_freq_2;
-    CARD32            pll_output_freq_2;
-    int               feedback_div_2;
-    int               reference_div_2;
-    int               post_div_2;
-
-				/* PLL2 registers */
-    CARD32            p2pll_ref_div;
-    CARD32            p2pll_div_0;
-    CARD32            htotal_cntl2;
-    CARD32            pixclks_cntl;
-
-				/* Pallet */
-    Bool              palette_valid;
-    CARD32            palette[256];
-    CARD32            palette2[256];
-
-    CARD32            rs480_unk_e30;
-    CARD32            rs480_unk_e34;
-    CARD32            rs480_unk_e38;
-    CARD32            rs480_unk_e3c;
-
-    /* TV out registers */
-    CARD32 	      tv_master_cntl;
-    CARD32 	      tv_htotal;
-    CARD32 	      tv_hsize;
-    CARD32 	      tv_hdisp;
-    CARD32 	      tv_hstart;
-    CARD32 	      tv_vtotal;
-    CARD32 	      tv_vdisp;
-    CARD32 	      tv_timing_cntl;
-    CARD32 	      tv_vscaler_cntl1;
-    CARD32 	      tv_vscaler_cntl2;
-    CARD32 	      tv_sync_size;
-    CARD32 	      tv_vrestart;
-    CARD32 	      tv_hrestart;
-    CARD32 	      tv_frestart;
-    CARD32 	      tv_ftotal;
-    CARD32 	      tv_clock_sel_cntl;
-    CARD32 	      tv_clkout_cntl;
-    CARD32 	      tv_data_delay_a;
-    CARD32 	      tv_data_delay_b;
-    CARD32 	      tv_dac_cntl;
-    CARD32 	      tv_pll_cntl;
-    CARD32 	      tv_pll_cntl1;
-    CARD32	      tv_pll_fine_cntl;
-    CARD32 	      tv_modulator_cntl1;
-    CARD32 	      tv_modulator_cntl2;
-    CARD32 	      tv_frame_lock_cntl;
-    CARD32 	      tv_pre_dac_mux_cntl;
-    CARD32 	      tv_rgb_cntl;
-    CARD32 	      tv_y_saw_tooth_cntl;
-    CARD32 	      tv_y_rise_cntl;
-    CARD32 	      tv_y_fall_cntl;
-    CARD32 	      tv_uv_adr;
-    CARD32	      tv_upsamp_and_gain_cntl;
-    CARD32	      tv_gain_limit_settings;
-    CARD32	      tv_linear_gain_settings;
-    CARD32	      tv_crc_cntl;
-    CARD32            tv_sync_cntl;
-    CARD32	      gpiopad_a;
-    CARD32            pll_test_cntl;
-
-    CARD16	      h_code_timing[MAX_H_CODE_TIMING_LEN];
-    CARD16	      v_code_timing[MAX_V_CODE_TIMING_LEN];
-
-} RADEONSaveRec, *RADEONSavePtr;
-
 #define RADEON_PLL_USE_BIOS_DIVS   (1 << 0)
 #define RADEON_PLL_NO_ODD_POST_DIV (1 << 1)
 #define RADEON_PLL_USE_REF_DIV     (1 << 2)
+#define RADEON_PLL_LEGACY          (1 << 3)
 
 typedef struct {
     CARD16            reference_freq;
     CARD16            reference_div;
-    CARD32            min_pll_freq;
-    CARD32            max_pll_freq;
+    CARD32            pll_in_min;
+    CARD32            pll_in_max;
+    CARD32            pll_out_min;
+    CARD32            pll_out_max;
     CARD16            xclk;
 
     CARD32            min_ref_div;
     CARD32            max_ref_div;
+    CARD32            min_post_div;
+    CARD32            max_post_div;
     CARD32            min_feedback_div;
     CARD32            max_feedback_div;
-    CARD32            pll_in_min;
-    CARD32            pll_in_max;
     CARD32            best_vco;
 } RADEONPLLRec, *RADEONPLLPtr;
 
@@ -421,6 +259,18 @@ typedef enum {
     CHIP_FAMILY_R420,     /* R420/R423/M18 */
     CHIP_FAMILY_RV410,    /* RV410, M26 */
     CHIP_FAMILY_RS400,    /* xpress 200, 200m (RS400/410/480) */
+    CHIP_FAMILY_RV515,    /* rv515 */
+    CHIP_FAMILY_R520,    /* r520 */
+    CHIP_FAMILY_RV530,    /* rv530 */
+    CHIP_FAMILY_R580,    /* r580 */
+    CHIP_FAMILY_RV560,   /* rv560 */
+    CHIP_FAMILY_RV570,   /* rv570 */
+    CHIP_FAMILY_RS690,
+    CHIP_FAMILY_R600,    /* r60 */
+    CHIP_FAMILY_R630,
+    CHIP_FAMILY_RV610,
+    CHIP_FAMILY_RV630,
+    CHIP_FAMILY_RS740,
     CHIP_FAMILY_LAST
 } RADEONChipFamily;
 
@@ -441,6 +291,8 @@ typedef enum {
         (info->ChipFamily == CHIP_FAMILY_RV410) ||  \
         (info->ChipFamily == CHIP_FAMILY_RS400))
 
+#define IS_AVIVO_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV515))
+
 /*
  * Errata workarounds
  */
@@ -475,6 +327,8 @@ typedef enum {
 	CARD_PCIE
 } RADEONCardType;
 
+typedef struct _atomBiosHandle *atomBiosHandlePtr;
+
 typedef struct {
     CARD32 pci_device_id;
     RADEONChipFamily chip_family;
@@ -500,6 +354,7 @@ typedef struct {
     CARD32            gartLocation;
     CARD32            mc_fb_location;
     CARD32            mc_agp_location;
+    CARD32            mc_agp_location_hi;
 
     void              *MMIO;            /* Map of MMIO region                */
     void              *FB;              /* Map of frame buffer               */
@@ -542,8 +397,8 @@ typedef struct {
     Bool	      IsDDR;
     int               DispPriority;
 
-    RADEONSaveRec     SavedReg;         /* Original (text) mode              */
-    RADEONSaveRec     ModeReg;          /* Current mode                      */
+    RADEONSavePtr     SavedReg;         /* Original (text) mode              */
+    RADEONSavePtr     ModeReg;          /* Current mode                      */
     Bool              (*CloseScreen)(int, ScreenPtr);
 
     void              (*BlockHandler)(int, pointer, pointer, pointer);
@@ -815,14 +670,12 @@ typedef struct {
     OptionInfoPtr     Options;
 
     Bool              useEXA;
-#ifdef XFree86LOADER
 #ifdef USE_EXA
     XF86ModReqInfo    exaReq;
 #endif
 #ifdef USE_XAA
     XF86ModReqInfo    xaaReq;
 #endif
-#endif
 
     /* X itself has the 3D context */
     Bool              XInited3D;
@@ -856,6 +709,10 @@ typedef struct {
 #endif
     RADEONExtTMDSChip ext_tmds_chip;
 
+    atomBiosHandlePtr atomBIOS;
+    unsigned long FbFreeStart, FbFreeSize;
+    unsigned char*      BIOSCopy;
+
     /* output enable masks for outputs shared across connectors */
     int output_crt1;
     int output_crt2;
@@ -867,6 +724,15 @@ typedef struct {
     Rotation rotation;
     void (*PointerMoved)(int, int, int);
     CreateScreenResourcesProcPtr CreateScreenResources;
+
+    /* if no devices are connected at server startup */
+    Bool              first_load_no_devices;
+
+    Bool              IsSecondary;
+    Bool              IsPrimary;
+
+    Bool              r600_shadow_fb;
+    void *fb_shadow;
 } RADEONInfoRec, *RADEONInfoPtr;
 
 #define RADEONWaitForFifo(pScrn, entries)				\
@@ -894,6 +760,9 @@ extern void        RADEONEngineRestore(ScrnInfoPtr pScrn);
 extern unsigned    RADEONINPLL(ScrnInfoPtr pScrn, int addr);
 extern void        RADEONOUTPLL(ScrnInfoPtr pScrn, int addr, CARD32 data);
 
+extern unsigned    RADEONINMC(ScrnInfoPtr pScrn, int addr);
+extern void        RADEONOUTMC(ScrnInfoPtr pScrn, int addr, CARD32 data);
+
 extern void        RADEONWaitForVerticalSync(ScrnInfoPtr pScrn);
 extern void        RADEONWaitForVerticalSync2(ScrnInfoPtr pScrn);
 
@@ -942,6 +811,7 @@ extern Bool        RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn);
 extern Bool        RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output);
 extern Bool        RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output);
 extern Bool        RADEONGetTVInfoFromBIOS (xf86OutputPtr output);
+extern Bool        RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output);
 extern Bool        RADEONGetHardCodedEDIDFromBIOS (xf86OutputPtr output);
 
 extern void        RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
@@ -974,32 +844,22 @@ extern void        RADEONInitMemMapRegisters(ScrnInfoPtr pScrn,
 					     RADEONInfoPtr info);
 extern void        RADEONInitDispBandwidth(ScrnInfoPtr pScrn);
 extern Bool        RADEONI2cInit(ScrnInfoPtr pScrn);
-extern void        RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag);
 extern Bool        RADEONSetupConnectors(ScrnInfoPtr pScrn);
 extern void        RADEONPrintPortMap(ScrnInfoPtr pScrn);
-extern void        RADEONEnableDisplay(xf86OutputPtr pPort, BOOL bEnable);
 extern void        RADEONDisableDisplays(ScrnInfoPtr pScrn);
 extern void        RADEONGetPanelInfo(ScrnInfoPtr pScrn);
-extern void        RADEONGetTVDacAdjInfo(xf86OutputPtr output);
 extern void        RADEONUnblank(ScrnInfoPtr pScrn);
 extern void        RADEONUnblank(ScrnInfoPtr pScrn);
 extern void        RADEONBlank(ScrnInfoPtr pScrn);
-extern void        RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn,
-						   int PowerManagementMode,
-						   int flags);
-extern Bool RADEONAllocateControllers(ScrnInfoPtr pScrn);
+
+extern Bool RADEONAllocateControllers(ScrnInfoPtr pScrn, int mask);
 extern Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn);
-extern int RADEONValidateMergeModes(ScrnInfoPtr pScrn);
-extern int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName,
-				  RADEONMonitorType DisplayType, int crtc2);
+
 extern void RADEONSetPitch (ScrnInfoPtr pScrn);
 extern void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode);
 
-DisplayModePtr
+extern DisplayModePtr
 RADEONProbeOutputModes(xf86OutputPtr output);
-extern Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1,
-			DisplayModePtr crtc2, int crtc_mask,
-			RADEONSavePtr save, RADEONMonitorType montype);
 
 extern Bool
 RADEONDVOReadByte(I2CDevPtr dvo, int addr, CARD8 *ch);
@@ -1010,20 +870,23 @@ RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output);
 extern Bool
 RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output);
 
-void
+extern RADEONI2CBusRec
+legacy_setup_i2c_bus(int ddc_line);
+
+extern void
 radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y);
-void
+extern void
 radeon_crtc_show_cursor (xf86CrtcPtr crtc);
-void
+extern void
 radeon_crtc_hide_cursor (xf86CrtcPtr crtc);
-void
+extern void
 radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y);
-void
+extern void
 radeon_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg);
-void
+extern void
 radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image);
-void
-RADEONEnableOutputs(ScrnInfoPtr pScrn, int crtc_num);
+extern void
+radeon_crtc_load_lut(xf86CrtcPtr crtc);
 
 extern void RADEONAdjustCrtcRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
 					   DisplayModePtr mode, xf86OutputPtr output);
@@ -1037,8 +900,10 @@ extern void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
                                   DisplayModePtr mode, BOOL IsPrimary);
 
 extern void RADEONRestoreTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore);
-extern void RADEONRestoreTVRestarts(ScrnInfoPtr pScrn, RADEONSavePtr restore);
-extern void RADEONRestoreTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr restore);
+
+extern void RADEONComputePLL(RADEONPLLPtr pll, unsigned long freq, CARD32 *chosen_dot_clock_freq,
+		CARD32 *chosen_feedback_div, CARD32 *chosen_reference_div,
+		CARD32 *chosen_post_div, int flags);
 
 #ifdef XF86DRI
 #ifdef USE_XAA
diff --git a/src/radeon_accel.c b/src/radeon_accel.c
index ed7d1e9..8b2f167 100644
--- a/src/radeon_accel.c
+++ b/src/radeon_accel.c
@@ -250,7 +250,7 @@ void RADEONEngineReset(ScrnInfoPtr pScrn)
     host_path_cntl = INREG(RADEON_HOST_PATH_CNTL);
     rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET);
 
-    if (IS_R300_VARIANT) {
+    if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
 	CARD32 tmp;
 
 	OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
@@ -284,7 +284,7 @@ void RADEONEngineReset(ScrnInfoPtr pScrn)
     INREG(RADEON_HOST_PATH_CNTL);
     OUTREG(RADEON_HOST_PATH_CNTL, host_path_cntl);
 
-    if (!IS_R300_VARIANT)
+    if (!IS_R300_VARIANT && !IS_AVIVO_VARIANT)
 	OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
 
     OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
@@ -322,7 +322,7 @@ void RADEONEngineRestore(ScrnInfoPtr pScrn)
 #endif
 
     /* Restore SURFACE_CNTL */
-    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);
+    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl);
 
     RADEONWaitForFifo(pScrn, 1);
     OUTREG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX
@@ -853,6 +853,9 @@ Bool RADEONAccelInit(ScreenPtr pScreen)
     ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
 
+    if (info->ChipFamily >= CHIP_FAMILY_R600)
+	return FALSE;
+
 #ifdef USE_EXA
     if (info->useEXA) {
 # ifdef XF86DRI
@@ -912,3 +915,340 @@ void RADEONInit3DEngine(ScrnInfoPtr pScrn)
     info->XInited3D = TRUE;
 }
 
+#ifdef USE_XAA
+#ifdef XF86DRI
+Bool
+RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen)
+{
+    ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];
+    RADEONInfoPtr  info  = RADEONPTR(pScrn);
+    int            cpp = info->CurrentLayout.pixel_bytes;
+    int            depthCpp = (info->depthBits - 8) / 4;
+    int            width_bytes = pScrn->displayWidth * cpp;
+    int            bufferSize;
+    int            depthSize;
+    int            l;
+    int            scanlines;
+    int            texsizerequest;
+    BoxRec         MemBox;
+    FBAreaPtr      fbarea;
+
+    info->frontOffset = 0;
+    info->frontPitch = pScrn->displayWidth;
+    info->backPitch = pScrn->displayWidth;
+
+    /* make sure we use 16 line alignment for tiling (8 might be enough).
+     * Might need that for non-XF86DRI too?
+     */
+    if (info->allowColorTiling) {
+	bufferSize = (((pScrn->virtualY + 15) & ~15) * width_bytes
+		      + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN;
+    } else {
+        bufferSize = (pScrn->virtualY * width_bytes
+		      + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN;
+    }
+
+    /* Due to tiling, the Z buffer pitch must be a multiple of 32 pixels,
+     * which is always the case if color tiling is used due to color pitch
+     * but not necessarily otherwise, and its height a multiple of 16 lines.
+     */
+    info->depthPitch = (pScrn->displayWidth + 31) & ~31;
+    depthSize = ((((pScrn->virtualY + 15) & ~15) * info->depthPitch
+		  * depthCpp + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN);
+
+    switch (info->CPMode) {
+    case RADEON_DEFAULT_CP_PIO_MODE:
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in PIO mode\n");
+	break;
+    case RADEON_DEFAULT_CP_BM_MODE:
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in BM mode\n");
+	break;
+    default:
+        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in UNKNOWN mode\n");
+	break;
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "Using %d MB GART aperture\n", info->gartSize);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "Using %d MB for the ring buffer\n", info->ringSize);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "Using %d MB for vertex/indirect buffers\n", info->bufSize);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "Using %d MB for GART textures\n", info->gartTexSize);
+
+    /* Try for front, back, depth, and three framebuffers worth of
+     * pixmap cache.  Should be enough for a fullscreen background
+     * image plus some leftovers.
+     * If the FBTexPercent option was used, try to achieve that percentage instead,
+     * but still have at least one pixmap buffer (get problems with xvideo/render
+     * otherwise probably), and never reserve more than 3 offscreen buffers as it's
+     * probably useless for XAA.
+     */
+    if (info->textureSize >= 0) {
+	texsizerequest = ((int)info->FbMapSize - 2 * bufferSize - depthSize
+			 - 2 * width_bytes - 16384 - info->FbSecureSize)
+	/* first divide, then multiply or we'll get an overflow (been there...) */
+			 / 100 * info->textureSize;
+    }
+    else {
+	texsizerequest = (int)info->FbMapSize / 2;
+    }
+    info->textureSize = info->FbMapSize - info->FbSecureSize - 5 * bufferSize - depthSize;
+
+    /* If that gives us less than the requested memory, let's
+     * be greedy and grab some more.  Sorry, I care more about 3D
+     * performance than playing nicely, and you'll get around a full
+     * framebuffer's worth of pixmap cache anyway.
+     */
+    if (info->textureSize < texsizerequest) {
+        info->textureSize = info->FbMapSize - 4 * bufferSize - depthSize;
+    }
+    if (info->textureSize < texsizerequest) {
+        info->textureSize = info->FbMapSize - 3 * bufferSize - depthSize;
+    }
+
+    /* If there's still no space for textures, try without pixmap cache, but
+     * never use the reserved space, the space hw cursor and PCIGART table might
+     * use.
+     */
+    if (info->textureSize < 0) {
+	info->textureSize = info->FbMapSize - 2 * bufferSize - depthSize
+	                    - 2 * width_bytes - 16384 - info->FbSecureSize;
+    }
+
+    /* Check to see if there is more room available after the 8192nd
+     * scanline for textures
+     */
+    /* FIXME: what's this good for? condition is pretty much impossible to meet */
+    if ((int)info->FbMapSize - 8192*width_bytes - bufferSize - depthSize
+	> info->textureSize) {
+	info->textureSize =
+		info->FbMapSize - 8192*width_bytes - bufferSize - depthSize;
+    }
+
+    /* If backbuffer is disabled, don't allocate memory for it */
+    if (info->noBackBuffer) {
+	info->textureSize += bufferSize;
+    }
+
+    /* RADEON_BUFFER_ALIGN is not sufficient for backbuffer!
+       At least for pageflip + color tiling, need to make sure it's 16 scanlines aligned,
+       otherwise the copy-from-front-to-back will fail (width_bytes * 16 will also guarantee
+       it's still 4kb aligned for tiled case). Need to round up offset (might get into cursor
+       area otherwise).
+       This might cause some space at the end of the video memory to be unused, since it
+       can't be used (?) due to that log_tex_granularity thing???
+       Could use different copyscreentoscreen function for the pageflip copies
+       (which would use different src and dst offsets) to avoid this. */   
+    if (info->allowColorTiling && !info->noBackBuffer) {
+	info->textureSize = info->FbMapSize - ((info->FbMapSize - info->textureSize +
+			  width_bytes * 16 - 1) / (width_bytes * 16)) * (width_bytes * 16);
+    }
+    if (info->textureSize > 0) {
+	l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS);
+	if (l < RADEON_LOG_TEX_GRANULARITY)
+	    l = RADEON_LOG_TEX_GRANULARITY;
+	/* Round the texture size up to the nearest whole number of
+	 * texture regions.  Again, be greedy about this, don't
+	 * round down.
+	 */
+	info->log2TexGran = l;
+	info->textureSize = (info->textureSize >> l) << l;
+    } else {
+	info->textureSize = 0;
+    }
+
+    /* Set a minimum usable local texture heap size.  This will fit
+     * two 256x256x32bpp textures.
+     */
+    if (info->textureSize < 512 * 1024) {
+	info->textureOffset = 0;
+	info->textureSize = 0;
+    }
+
+    if (info->allowColorTiling && !info->noBackBuffer) {
+	info->textureOffset = ((info->FbMapSize - info->textureSize) /
+			       (width_bytes * 16)) * (width_bytes * 16);
+    }
+    else {
+	/* Reserve space for textures */
+	info->textureOffset = ((info->FbMapSize - info->textureSize +
+				RADEON_BUFFER_ALIGN) &
+			       ~(CARD32)RADEON_BUFFER_ALIGN);
+    }
+
+    /* Reserve space for the shared depth
+     * buffer.
+     */
+    info->depthOffset = ((info->textureOffset - depthSize +
+			  RADEON_BUFFER_ALIGN) &
+			 ~(CARD32)RADEON_BUFFER_ALIGN);
+
+    /* Reserve space for the shared back buffer */
+    if (info->noBackBuffer) {
+       info->backOffset = info->depthOffset;
+    } else {
+       info->backOffset = ((info->depthOffset - bufferSize +
+			    RADEON_BUFFER_ALIGN) &
+			   ~(CARD32)RADEON_BUFFER_ALIGN);
+    }
+
+    info->backY = info->backOffset / width_bytes;
+    info->backX = (info->backOffset - (info->backY * width_bytes)) / cpp;
+
+    scanlines = (info->FbMapSize-info->FbSecureSize) / width_bytes;
+    if (scanlines > 8191)
+	scanlines = 8191;
+
+    MemBox.x1 = 0;
+    MemBox.y1 = 0;
+    MemBox.x2 = pScrn->displayWidth;
+    MemBox.y2 = scanlines;
+
+    if (!xf86InitFBManager(pScreen, &MemBox)) {
+        xf86DrvMsg(scrnIndex, X_ERROR,
+		   "Memory manager initialization to "
+		   "(%d,%d) (%d,%d) failed\n",
+		   MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
+	return FALSE;
+    } else {
+	int  width, height;
+
+	xf86DrvMsg(scrnIndex, X_INFO,
+		   "Memory manager initialized to (%d,%d) (%d,%d)\n",
+		   MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
+	/* why oh why can't we just request modes which are guaranteed to be 16 lines
+	   aligned... sigh */
+	if ((fbarea = xf86AllocateOffscreenArea(pScreen,
+						pScrn->displayWidth,
+						info->allowColorTiling ? 
+						((pScrn->virtualY + 15) & ~15)
+						- pScrn->virtualY + 2 : 2,
+						0, NULL, NULL,
+						NULL))) {
+	    xf86DrvMsg(scrnIndex, X_INFO,
+		       "Reserved area from (%d,%d) to (%d,%d)\n",
+		       fbarea->box.x1, fbarea->box.y1,
+		       fbarea->box.x2, fbarea->box.y2);
+	} else {
+	    xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n");
+	}
+
+	RADEONDRIAllocatePCIGARTTable(pScreen);
+
+	if (xf86QueryLargestOffscreenArea(pScreen, &width,
+					  &height, 0, 0, 0)) {
+	    xf86DrvMsg(scrnIndex, X_INFO,
+		       "Largest offscreen area available: %d x %d\n",
+		       width, height);
+
+	    /* Lines in offscreen area needed for depth buffer and
+	     * textures
+	     */
+	    info->depthTexLines = (scanlines
+				   - info->depthOffset / width_bytes);
+	    info->backLines	    = (scanlines
+				       - info->backOffset / width_bytes
+				       - info->depthTexLines);
+	    info->backArea	    = NULL;
+	} else {
+	    xf86DrvMsg(scrnIndex, X_ERROR,
+		       "Unable to determine largest offscreen area "
+		       "available\n");
+	    return FALSE;
+	}
+    }
+
+    xf86DrvMsg(scrnIndex, X_INFO,
+	       "Will use front buffer at offset 0x%x\n",
+	       info->frontOffset);
+
+    xf86DrvMsg(scrnIndex, X_INFO,
+	       "Will use back buffer at offset 0x%x\n",
+	       info->backOffset);
+    xf86DrvMsg(scrnIndex, X_INFO,
+	       "Will use depth buffer at offset 0x%x\n",
+	       info->depthOffset);
+    if (info->cardType==CARD_PCIE)
+    	xf86DrvMsg(scrnIndex, X_INFO,
+	           "Will use %d kb for PCI GART table at offset 0x%x\n",
+		   info->pciGartSize/1024, (unsigned)info->pciGartOffset);
+    xf86DrvMsg(scrnIndex, X_INFO,
+	       "Will use %d kb for textures at offset 0x%x\n",
+	       info->textureSize/1024, info->textureOffset);
+
+    info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) |
+			      ((info->frontOffset + info->fbLocation) >> 10));
+
+    info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) |
+			     ((info->backOffset + info->fbLocation) >> 10));
+
+    info->depthPitchOffset = (((info->depthPitch * depthCpp / 64) << 22) |
+			      ((info->depthOffset + info->fbLocation) >> 10));
+    return TRUE;
+}
+#endif /* XF86DRI */
+
+Bool
+RADEONSetupMemXAA(int scrnIndex, ScreenPtr pScreen)
+{
+    ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];
+    RADEONInfoPtr  info  = RADEONPTR(pScrn);
+    BoxRec         MemBox;
+    int            y2;
+
+    int width_bytes = pScrn->displayWidth * info->CurrentLayout.pixel_bytes;
+
+    MemBox.x1 = 0;
+    MemBox.y1 = 0;
+    MemBox.x2 = pScrn->displayWidth;
+    y2 = info->FbMapSize / width_bytes;
+    if (y2 >= 32768)
+	y2 = 32767; /* because MemBox.y2 is signed short */
+    MemBox.y2 = y2;
+    
+    /* The acceleration engine uses 14 bit
+     * signed coordinates, so we can't have any
+     * drawable caches beyond this region.
+     */
+    if (MemBox.y2 > 8191)
+	MemBox.y2 = 8191;
+
+    if (!xf86InitFBManager(pScreen, &MemBox)) {
+	xf86DrvMsg(scrnIndex, X_ERROR,
+		   "Memory manager initialization to "
+		   "(%d,%d) (%d,%d) failed\n",
+		   MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
+	return FALSE;
+    } else {
+	int       width, height;
+	FBAreaPtr fbarea;
+
+	xf86DrvMsg(scrnIndex, X_INFO,
+		   "Memory manager initialized to (%d,%d) (%d,%d)\n",
+		   MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
+	if ((fbarea = xf86AllocateOffscreenArea(pScreen,
+						pScrn->displayWidth,
+						info->allowColorTiling ? 
+						((pScrn->virtualY + 15) & ~15)
+						- pScrn->virtualY + 2 : 2,
+						0, NULL, NULL,
+						NULL))) {
+	    xf86DrvMsg(scrnIndex, X_INFO,
+		       "Reserved area from (%d,%d) to (%d,%d)\n",
+		       fbarea->box.x1, fbarea->box.y1,
+		       fbarea->box.x2, fbarea->box.y2);
+	} else {
+	    xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n");
+	}
+	if (xf86QueryLargestOffscreenArea(pScreen, &width, &height,
+					      0, 0, 0)) {
+	    xf86DrvMsg(scrnIndex, X_INFO,
+		       "Largest offscreen area available: %d x %d\n",
+		       width, height);
+	}
+	return TRUE;
+    }    
+}
+#endif /* USE_XAA */
diff --git a/src/radeon_accelfuncs.c b/src/radeon_accelfuncs.c
index 212131f..e3b37c1 100644
--- a/src/radeon_accelfuncs.c
+++ b/src/radeon_accelfuncs.c
@@ -1182,9 +1182,7 @@ FUNC_NAME(RADEONAccelInit)(ScreenPtr pScreen, XAAInfoRecPtr a)
     a->SubsequentSolidHorVertLine
 	= FUNC_NAME(RADEONSubsequentSolidHorVertLine);
 
-#ifdef XFree86LOADER
     if (info->xaaReq.minorversion >= 1) {
-#endif
 
     /* RADEON only supports 14 bits for lines and clipping and only
      * draws lines that are completely on-screen correctly.  This will
@@ -1231,12 +1229,10 @@ FUNC_NAME(RADEONAccelInit)(ScreenPtr pScreen, XAAInfoRecPtr a)
 	a->DashedLineLimits.y2 = pScrn->virtualY-1;
     }
 
-#ifdef XFree86LOADER
     } else {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		   "libxaa too old, can't accelerate TwoPoint lines\n");
     }
-#endif
 
     /* Clipping, note that without this, all line accelerations will
      * not be called
@@ -1296,11 +1292,7 @@ FUNC_NAME(RADEONAccelInit)(ScreenPtr pScreen, XAAInfoRecPtr a)
 #endif
 
 #ifdef RENDER
-    if (info->RenderAccel
-#ifdef XFree86LOADER
-	&& info->xaaReq.minorversion >= 2
-#endif
-	) {
+    if (info->RenderAccel && info->xaaReq.minorversion >= 2) {
 
 	a->CPUToScreenAlphaTextureFlags = XAA_RENDER_POWER_OF_2_TILE_ONLY;
 	a->CPUToScreenAlphaTextureFormats = RADEONTextureFormats;
@@ -1309,7 +1301,7 @@ FUNC_NAME(RADEONAccelInit)(ScreenPtr pScreen, XAAInfoRecPtr a)
 	a->CPUToScreenTextureFormats = RADEONTextureFormats;
 	a->CPUToScreenTextureDstFormats = RADEONDstFormats;
 
-	if (IS_R300_VARIANT) {
+	if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration "
 		       "unsupported on Radeon 9500/9700 and newer.\n");
 	} else if ((info->ChipFamily == CHIP_FAMILY_RV250) || 
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
new file mode 100644
index 0000000..e8f9e91
--- /dev/null
+++ b/src/radeon_atombios.c
@@ -0,0 +1,2833 @@
+/*
+ * Copyright 2007  Egbert Eich   <eich@novell.com>
+ * Copyright 2007  Luc Verhaegen <lverhaegen@novell.com>
+ * Copyright 2007  Matthias Hopf <mhopf@novell.com>
+ * Copyright 2007  Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include "radeon.h"
+#include "radeon_atombios.h"
+#include "radeon_atomwrapper.h"
+#include "radeon_probe.h"
+#include "radeon_macros.h"
+
+#include "xorg-server.h"
+
+/* only for testing now */
+#include "xf86DDC.h"
+
+typedef AtomBiosResult (*AtomBiosRequestFunc)(atomBiosHandlePtr handle,
+					  AtomBiosRequestID unused, AtomBiosArgPtr data);
+typedef struct rhdConnectorInfo *rhdConnectorInfoPtr;
+
+static AtomBiosResult rhdAtomInit(atomBiosHandlePtr unused1,
+				      AtomBiosRequestID unused2, AtomBiosArgPtr data);
+static AtomBiosResult rhdAtomTearDown(atomBiosHandlePtr handle,
+					  AtomBiosRequestID unused1, AtomBiosArgPtr unused2);
+static AtomBiosResult rhdAtomVramInfoQuery(atomBiosHandlePtr handle,
+					       AtomBiosRequestID func, AtomBiosArgPtr data);
+static AtomBiosResult rhdAtomTmdsInfoQuery(atomBiosHandlePtr handle,
+					       AtomBiosRequestID func, AtomBiosArgPtr data);
+static AtomBiosResult rhdAtomAllocateFbScratch(atomBiosHandlePtr handle,
+						   AtomBiosRequestID func, AtomBiosArgPtr data);
+static AtomBiosResult rhdAtomLvdsGetTimings(atomBiosHandlePtr handle,
+					AtomBiosRequestID unused, AtomBiosArgPtr data);
+static AtomBiosResult rhdAtomCVGetTimings(atomBiosHandlePtr handle,
+					  AtomBiosRequestID unused, AtomBiosArgPtr data);
+static AtomBiosResult rhdAtomLvdsInfoQuery(atomBiosHandlePtr handle,
+					       AtomBiosRequestID func,  AtomBiosArgPtr data);
+static AtomBiosResult rhdAtomGPIOI2CInfoQuery(atomBiosHandlePtr handle,
+						  AtomBiosRequestID func, AtomBiosArgPtr data);
+static AtomBiosResult rhdAtomFirmwareInfoQuery(atomBiosHandlePtr handle,
+						   AtomBiosRequestID func, AtomBiosArgPtr data);
+/*static AtomBiosResult rhdAtomConnectorInfo(atomBiosHandlePtr handle,
+  AtomBiosRequestID unused, AtomBiosArgPtr data);*/
+# ifdef ATOM_BIOS_PARSER
+static AtomBiosResult rhdAtomExec(atomBiosHandlePtr handle,
+				   AtomBiosRequestID unused, AtomBiosArgPtr data);
+# endif
+static AtomBiosResult
+rhdAtomCompassionateDataQuery(atomBiosHandlePtr handle,
+			      AtomBiosRequestID func, AtomBiosArgPtr data);
+
+
+enum msgDataFormat {
+    MSG_FORMAT_NONE,
+    MSG_FORMAT_HEX,
+    MSG_FORMAT_DEC
+};
+
+struct atomBIOSRequests {
+    AtomBiosRequestID id;
+    AtomBiosRequestFunc request;
+    char *message;
+    enum msgDataFormat message_format;
+} AtomBiosRequestList [] = {
+    {ATOMBIOS_INIT,			rhdAtomInit,
+     "AtomBIOS Init",				MSG_FORMAT_NONE},
+    {ATOMBIOS_TEARDOWN,			rhdAtomTearDown,
+     "AtomBIOS Teardown",			MSG_FORMAT_NONE},
+# ifdef ATOM_BIOS_PARSER
+    {ATOMBIOS_EXEC,			rhdAtomExec,
+     "AtomBIOS Exec",				MSG_FORMAT_NONE},
+#endif
+    {ATOMBIOS_ALLOCATE_FB_SCRATCH,	rhdAtomAllocateFbScratch,
+     "AtomBIOS Set FB Space",			MSG_FORMAT_NONE},
+    /*{ATOMBIOS_GET_CONNECTORS,		rhdAtomConnectorInfo,
+      "AtomBIOS Get Connectors",			MSG_FORMAT_NONE},*/
+    {ATOMBIOS_GET_PANEL_MODE,		rhdAtomLvdsGetTimings,
+     "AtomBIOS Get Panel Mode",			MSG_FORMAT_NONE},
+    {ATOMBIOS_GET_PANEL_EDID,		rhdAtomLvdsGetTimings,
+     "AtomBIOS Get Panel EDID",			MSG_FORMAT_NONE},
+    {GET_DEFAULT_ENGINE_CLOCK,		rhdAtomFirmwareInfoQuery,
+     "Default Engine Clock",			MSG_FORMAT_DEC},
+    {GET_DEFAULT_MEMORY_CLOCK,		rhdAtomFirmwareInfoQuery,
+     "Default Memory Clock",			MSG_FORMAT_DEC},
+    {GET_MAX_PIXEL_CLOCK_PLL_OUTPUT,	rhdAtomFirmwareInfoQuery,
+     "Maximum Pixel ClockPLL Frequency Output", MSG_FORMAT_DEC},
+    {GET_MIN_PIXEL_CLOCK_PLL_OUTPUT,	rhdAtomFirmwareInfoQuery,
+     "Minimum Pixel ClockPLL Frequency Output", MSG_FORMAT_DEC},
+    {GET_MAX_PIXEL_CLOCK_PLL_INPUT,	rhdAtomFirmwareInfoQuery,
+     "Maximum Pixel ClockPLL Frequency Input", MSG_FORMAT_DEC},
+    {GET_MIN_PIXEL_CLOCK_PLL_INPUT,	rhdAtomFirmwareInfoQuery,
+     "Minimum Pixel ClockPLL Frequency Input", MSG_FORMAT_DEC},
+    {GET_MAX_PIXEL_CLK,			rhdAtomFirmwareInfoQuery,
+     "Maximum Pixel Clock",			MSG_FORMAT_DEC},
+    {GET_REF_CLOCK,			rhdAtomFirmwareInfoQuery,
+     "Reference Clock",				MSG_FORMAT_DEC},
+    {GET_FW_FB_START,			rhdAtomVramInfoQuery,
+      "Start of VRAM area used by Firmware",	MSG_FORMAT_HEX},
+    {GET_FW_FB_SIZE,			rhdAtomVramInfoQuery,
+      "Framebuffer space used by Firmware (kb)", MSG_FORMAT_DEC},
+    {ATOM_TMDS_FREQUENCY,		rhdAtomTmdsInfoQuery,
+     "TMDS Frequency",				MSG_FORMAT_DEC},
+    {ATOM_TMDS_PLL_CHARGE_PUMP,		rhdAtomTmdsInfoQuery,
+     "TMDS PLL ChargePump",			MSG_FORMAT_DEC},
+    {ATOM_TMDS_PLL_DUTY_CYCLE,		rhdAtomTmdsInfoQuery,
+     "TMDS PLL DutyCycle",			MSG_FORMAT_DEC},
+    {ATOM_TMDS_PLL_VCO_GAIN,		rhdAtomTmdsInfoQuery,
+     "TMDS PLL VCO Gain",			MSG_FORMAT_DEC},
+    {ATOM_TMDS_PLL_VOLTAGE_SWING,	rhdAtomTmdsInfoQuery,
+     "TMDS PLL VoltageSwing",			MSG_FORMAT_DEC},
+    {ATOM_LVDS_SUPPORTED_REFRESH_RATE,	rhdAtomLvdsInfoQuery,
+     "LVDS Supported Refresh Rate",		MSG_FORMAT_DEC},
+    {ATOM_LVDS_OFF_DELAY,		rhdAtomLvdsInfoQuery,
+     "LVDS Off Delay",				MSG_FORMAT_DEC},
+    {ATOM_LVDS_SEQ_DIG_ONTO_DE,		rhdAtomLvdsInfoQuery,
+     "LVDS SEQ Dig onto DE",			MSG_FORMAT_DEC},
+    {ATOM_LVDS_SEQ_DE_TO_BL,		rhdAtomLvdsInfoQuery,
+     "LVDS SEQ DE to BL",			MSG_FORMAT_DEC},
+    {ATOM_LVDS_DITHER,			rhdAtomLvdsInfoQuery,
+     "LVDS Ditherc",				MSG_FORMAT_HEX},
+    {ATOM_LVDS_DUALLINK,		rhdAtomLvdsInfoQuery,
+     "LVDS Duallink",				MSG_FORMAT_HEX},
+    {ATOM_LVDS_GREYLVL,			rhdAtomLvdsInfoQuery,
+     "LVDS Grey Level",				MSG_FORMAT_HEX},
+    {ATOM_LVDS_FPDI,			rhdAtomLvdsInfoQuery,
+     "LVDS FPDI",				MSG_FORMAT_HEX},
+    {ATOM_LVDS_24BIT,			rhdAtomLvdsInfoQuery,
+     "LVDS 24Bit",				MSG_FORMAT_HEX},
+    {ATOM_GPIO_I2C_CLK_MASK,		rhdAtomGPIOI2CInfoQuery,
+     "GPIO_I2C_Clk_Mask",			MSG_FORMAT_HEX},
+    {ATOM_DAC1_BG_ADJ,		rhdAtomCompassionateDataQuery,
+     "DAC1 BG Adjustment",			MSG_FORMAT_HEX},
+    {ATOM_DAC1_DAC_ADJ,		rhdAtomCompassionateDataQuery,
+     "DAC1 DAC Adjustment",			MSG_FORMAT_HEX},
+    {ATOM_DAC1_FORCE,		rhdAtomCompassionateDataQuery,
+     "DAC1 Force Data",				MSG_FORMAT_HEX},
+    {ATOM_DAC2_CRTC2_BG_ADJ,	rhdAtomCompassionateDataQuery,
+     "DAC2_CRTC2 BG Adjustment",		MSG_FORMAT_HEX},
+    {ATOM_DAC2_CRTC2_DAC_ADJ,	rhdAtomCompassionateDataQuery,
+     "DAC2_CRTC2 DAC Adjustment",		MSG_FORMAT_HEX},
+    {ATOM_DAC2_CRTC2_FORCE,	rhdAtomCompassionateDataQuery,
+     "DAC2_CRTC2 Force",			MSG_FORMAT_HEX},
+    {ATOM_DAC2_CRTC2_MUX_REG_IND,rhdAtomCompassionateDataQuery,
+     "DAC2_CRTC2 Mux Register Index",		MSG_FORMAT_HEX},
+    {ATOM_DAC2_CRTC2_MUX_REG_INFO,rhdAtomCompassionateDataQuery,
+     "DAC2_CRTC2 Mux Register Info",		MSG_FORMAT_HEX},
+    {ATOMBIOS_GET_CV_MODES,		rhdAtomCVGetTimings,
+     "AtomBIOS Get CV Mode",			MSG_FORMAT_NONE},
+    {FUNC_END,					NULL,
+     NULL,					MSG_FORMAT_NONE}
+};
+
+enum {
+    legacyBIOSLocation = 0xC0000,
+    legacyBIOSMax = 0x10000
+};
+
+#define DEBUGP(x) {x;}
+#define LOG_DEBUG 7
+
+#  ifdef ATOM_BIOS_PARSER
+
+#   define LOG_CAIL LOG_DEBUG + 1
+
+#if 0
+
+static void
+RHDDebug(int scrnIndex, const char *format, ...)
+{
+    va_list ap;
+
+    va_start(ap, format);
+    xf86VDrvMsgVerb(scrnIndex, X_INFO, LOG_DEBUG, format, ap);
+    va_end(ap);
+}
+
+static void
+RHDDebugCont(const char *format, ...)
+{
+    va_list ap;
+
+    va_start(ap, format);
+    xf86VDrvMsgVerb(-1, X_NONE, LOG_DEBUG, format, ap);
+    va_end(ap);
+}
+
+#endif
+
+static void
+CailDebug(int scrnIndex, const char *format, ...)
+{
+    va_list ap;
+
+    va_start(ap, format);
+    xf86VDrvMsgVerb(scrnIndex, X_INFO, LOG_CAIL, format, ap);
+    va_end(ap);
+}
+#   define CAILFUNC(ptr) \
+  CailDebug(((atomBiosHandlePtr)(ptr))->scrnIndex, "CAIL: %s\n", __func__)
+
+#  endif
+
+static int
+rhdAtomAnalyzeCommonHdr(ATOM_COMMON_TABLE_HEADER *hdr)
+{
+    if (hdr->usStructureSize == 0xaa55)
+        return FALSE;
+
+    return TRUE;
+}
+
+static int
+rhdAtomAnalyzeRomHdr(unsigned char *rombase,
+		     ATOM_ROM_HEADER *hdr,
+		     unsigned int *data_offset, 
+		     unsigned int *command_offset)
+{
+    if (!rhdAtomAnalyzeCommonHdr(&hdr->sHeader)) {
+        return FALSE;
+    }
+    xf86DrvMsg(-1,X_NONE,"\tSubsystemVendorID: 0x%4.4x SubsystemID: 0x%4.4x\n",
+               hdr->usSubsystemVendorID,hdr->usSubsystemID);
+    xf86DrvMsg(-1,X_NONE,"\tIOBaseAddress: 0x%4.4x\n",hdr->usIoBaseAddress);
+    xf86DrvMsgVerb(-1,X_NONE,3,"\tFilename: %s\n",rombase + hdr->usConfigFilenameOffset);
+    xf86DrvMsgVerb(-1,X_NONE,3,"\tBIOS Bootup Message: %s\n",
+		   rombase + hdr->usBIOS_BootupMessageOffset);
+
+    *data_offset = hdr->usMasterDataTableOffset;
+    *command_offset = hdr->usMasterCommandTableOffset;
+
+    return TRUE;
+}
+
+static int
+rhdAtomAnalyzeRomDataTable(unsigned char *base, int offset,
+                    void *ptr,unsigned short *size)
+{
+    ATOM_COMMON_TABLE_HEADER *table = (ATOM_COMMON_TABLE_HEADER *)
+        (base + offset);
+
+   if (!*size || !rhdAtomAnalyzeCommonHdr(table)) {
+       if (*size) *size -= 2;
+       *(void **)ptr = NULL;
+       return FALSE;
+   }
+   *size -= 2;
+   *(void **)ptr = (void *)(table);
+   return TRUE;
+}
+
+Bool
+rhdAtomGetTableRevisionAndSize(ATOM_COMMON_TABLE_HEADER *hdr,
+			       CARD8 *contentRev,
+			       CARD8 *formatRev,
+			       unsigned short *size)
+{
+    if (!hdr)
+        return FALSE;
+
+    if (contentRev) *contentRev = hdr->ucTableContentRevision;
+    if (formatRev) *formatRev = hdr->ucTableFormatRevision;
+    if (size) *size = (short)hdr->usStructureSize
+                   - sizeof(ATOM_COMMON_TABLE_HEADER);
+    return TRUE;
+}
+
+static Bool
+rhdAtomAnalyzeMasterDataTable(unsigned char *base,
+			      ATOM_MASTER_DATA_TABLE *table,
+			      atomDataTablesPtr data)
+{
+    ATOM_MASTER_LIST_OF_DATA_TABLES *data_table =
+        &table->ListOfDataTables;
+    unsigned short size;
+
+    if (!rhdAtomAnalyzeCommonHdr(&table->sHeader))
+        return FALSE;
+    if (!rhdAtomGetTableRevisionAndSize(&table->sHeader,NULL,NULL,
+					&size))
+        return FALSE;
+# define SET_DATA_TABLE(x) {\
+   rhdAtomAnalyzeRomDataTable(base,data_table->x,(void *)(&(data->x)),&size); \
+    }
+
+# define SET_DATA_TABLE_VERS(x) {\
+   rhdAtomAnalyzeRomDataTable(base,data_table->x,&(data->x.base),&size); \
+    }
+
+    SET_DATA_TABLE(UtilityPipeLine);
+    SET_DATA_TABLE(MultimediaCapabilityInfo);
+    SET_DATA_TABLE(MultimediaConfigInfo);
+    SET_DATA_TABLE(StandardVESA_Timing);
+    SET_DATA_TABLE_VERS(FirmwareInfo);
+    SET_DATA_TABLE(DAC_Info);
+    SET_DATA_TABLE_VERS(LVDS_Info);
+    SET_DATA_TABLE(TMDS_Info);
+    SET_DATA_TABLE(AnalogTV_Info);
+    SET_DATA_TABLE_VERS(SupportedDevicesInfo);
+    SET_DATA_TABLE(GPIO_I2C_Info);
+    SET_DATA_TABLE(VRAM_UsageByFirmware);
+    SET_DATA_TABLE(GPIO_Pin_LUT);
+    SET_DATA_TABLE(VESA_ToInternalModeLUT);
+    SET_DATA_TABLE_VERS(ComponentVideoInfo);
+    SET_DATA_TABLE(PowerPlayInfo);
+    SET_DATA_TABLE(CompassionateData);
+    SET_DATA_TABLE(SaveRestoreInfo);
+    SET_DATA_TABLE(PPLL_SS_Info);
+    SET_DATA_TABLE(OemInfo);
+    SET_DATA_TABLE(XTMDS_Info);
+    SET_DATA_TABLE(MclkSS_Info);
+    SET_DATA_TABLE(Object_Header);
+    SET_DATA_TABLE(IndirectIOAccess);
+    SET_DATA_TABLE(MC_InitParameter);
+    SET_DATA_TABLE(ASIC_VDDC_Info);
+    SET_DATA_TABLE(ASIC_InternalSS_Info);
+    SET_DATA_TABLE(TV_VideoMode);
+    SET_DATA_TABLE_VERS(VRAM_Info);
+    SET_DATA_TABLE(MemoryTrainingInfo);
+    SET_DATA_TABLE_VERS(IntegratedSystemInfo);
+    SET_DATA_TABLE(ASIC_ProfilingInfo);
+    SET_DATA_TABLE(VoltageObjectInfo);
+    SET_DATA_TABLE(PowerSourceInfo);
+# undef SET_DATA_TABLE
+
+    return TRUE;
+}
+
+static Bool
+rhdAtomGetDataTable(int scrnIndex,
+		    unsigned char *base,
+		    atomDataTables *atomDataPtr,
+		    unsigned int *cmd_offset,
+		    unsigned int BIOSImageSize)
+{
+    unsigned int data_offset;
+    unsigned int atom_romhdr_off =  *(unsigned short*)
+        (base + OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER);
+    ATOM_ROM_HEADER *atom_rom_hdr =
+        (ATOM_ROM_HEADER *)(base + atom_romhdr_off);
+
+    //RHDFUNCI(scrnIndex);
+
+    if (atom_romhdr_off + sizeof(ATOM_ROM_HEADER) > BIOSImageSize) {
+	xf86DrvMsg(scrnIndex,X_ERROR,
+		   "%s: AtomROM header extends beyond BIOS image\n",__func__);
+	return FALSE;
+    }
+
+    if (memcmp("ATOM",&atom_rom_hdr->uaFirmWareSignature,4)) {
+        xf86DrvMsg(scrnIndex,X_ERROR,"%s: No AtomBios signature found\n",
+		   __func__);
+        return FALSE;
+    }
+    xf86DrvMsg(scrnIndex, X_INFO, "ATOM BIOS Rom: \n");
+    if (!rhdAtomAnalyzeRomHdr(base, atom_rom_hdr, &data_offset, cmd_offset)) {
+        xf86DrvMsg(scrnIndex, X_ERROR, "RomHeader invalid\n");
+        return FALSE;
+    }
+
+    if (data_offset + sizeof (ATOM_MASTER_DATA_TABLE) > BIOSImageSize) {
+	xf86DrvMsg(scrnIndex,X_ERROR,"%s: Atom data table outside of BIOS\n",
+		   __func__);
+    }
+
+    if (*cmd_offset + sizeof (ATOM_MASTER_COMMAND_TABLE) > BIOSImageSize) {
+	xf86DrvMsg(scrnIndex,X_ERROR,"%s: Atom command table outside of BIOS\n",
+		   __func__);
+    }
+
+    if (!rhdAtomAnalyzeMasterDataTable(base, (ATOM_MASTER_DATA_TABLE *)
+				       (base + data_offset),
+				       atomDataPtr)) {
+        xf86DrvMsg(scrnIndex, X_ERROR, "%s: ROM Master Table invalid\n",
+		   __func__);
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static Bool
+rhdAtomGetFbBaseAndSize(atomBiosHandlePtr handle, unsigned int *base,
+			unsigned int *size)
+{
+    AtomBiosArgRec data;
+    if (RHDAtomBiosFunc(handle->scrnIndex, handle, GET_FW_FB_SIZE, &data)
+	== ATOM_SUCCESS) {
+	if (data.val == 0) {
+	    xf86DrvMsg(handle->scrnIndex, X_WARNING, "%s: AtomBIOS specified VRAM "
+		       "scratch space size invalid\n", __func__);
+	    return FALSE;
+	}
+	if (size)
+	    *size = (int)data.val;
+    } else
+	return FALSE;
+    if (RHDAtomBiosFunc(handle->scrnIndex, handle, GET_FW_FB_START, &data)
+	== ATOM_SUCCESS) {
+	if (data.val == 0)
+	    return FALSE;
+	if (base)
+	    *base = (int)data.val;
+    }
+    return TRUE;
+}
+
+/*
+ * Uses videoRam form ScrnInfoRec.
+ */
+static AtomBiosResult
+rhdAtomAllocateFbScratch(atomBiosHandlePtr handle,
+			 AtomBiosRequestID func, AtomBiosArgPtr data)
+{
+    unsigned int fb_base = 0;
+    unsigned int fb_size = 0;
+    unsigned int start = data->fb.start;
+    unsigned int size = data->fb.size;
+    handle->scratchBase = NULL;
+    handle->fbBase = 0;
+
+    if (rhdAtomGetFbBaseAndSize(handle, &fb_base, &fb_size)) {
+	xf86DrvMsg(handle->scrnIndex, X_INFO, "AtomBIOS requests %ikB"
+		   " of VRAM scratch space\n",fb_size);
+	fb_size *= 1024; /* convert to bytes */
+	xf86DrvMsg(handle->scrnIndex, X_INFO, "AtomBIOS VRAM scratch base: 0x%x\n",
+		   fb_base);
+    } else {
+	    fb_size = 20 * 1024;
+	    xf86DrvMsg(handle->scrnIndex, X_INFO, " default to: %i\n",fb_size);
+    }
+    if (fb_base && fb_size && size) {
+	/* 4k align */
+	fb_size = (fb_size & ~(CARD32)0xfff) + ((fb_size & 0xfff) ? 1 : 0);
+	if ((fb_base + fb_size) > (start + size)) {
+	    xf86DrvMsg(handle->scrnIndex, X_WARNING,
+		       "%s: FW FB scratch area %i (size: %i)"
+		       " extends beyond available framebuffer size %i\n",
+		       __func__, fb_base, fb_size, size);
+	} else if ((fb_base + fb_size) < (start + size)) {
+	    xf86DrvMsg(handle->scrnIndex, X_WARNING,
+		       "%s: FW FB scratch area not located "
+		       "at the end of VRAM. Scratch End: "
+		       "0x%x VRAM End: 0x%x\n", __func__,
+		       (unsigned int)(fb_base + fb_size),
+		       size);
+	} else if (fb_base < start) {
+	    xf86DrvMsg(handle->scrnIndex, X_WARNING,
+		       "%s: FW FB scratch area extends below "
+		       "the base of the free VRAM: 0x%x Base: 0x%x\n",
+		       __func__, (unsigned int)(fb_base), start);
+	} else {
+	    size -= fb_size;
+	    handle->fbBase = fb_base;
+	    return ATOM_SUCCESS;
+	}
+    }
+
+    if (!handle->fbBase) {
+	xf86DrvMsg(handle->scrnIndex, X_INFO,
+		   "Cannot get VRAM scratch space. "
+		   "Allocating in main memory instead\n");
+	handle->scratchBase = xcalloc(fb_size,1);
+	return ATOM_SUCCESS;
+    }
+    return ATOM_FAILED;
+}
+
+# ifdef ATOM_BIOS_PARSER
+static Bool
+rhdAtomASICInit(atomBiosHandlePtr handle)
+{
+    ASIC_INIT_PS_ALLOCATION asicInit;
+    AtomBiosArgRec data;
+
+    RHDAtomBiosFunc(handle->scrnIndex, handle,
+		    GET_DEFAULT_ENGINE_CLOCK,
+		    &data);
+    asicInit.sASICInitClocks.ulDefaultEngineClock = data.val / 10;/*in 10 Khz*/
+    RHDAtomBiosFunc(handle->scrnIndex, handle,
+		    GET_DEFAULT_MEMORY_CLOCK,
+		    &data);
+    asicInit.sASICInitClocks.ulDefaultMemoryClock = data.val / 10;/*in 10 Khz*/
+    data.exec.dataSpace = NULL;
+    data.exec.index = 0x0;
+    data.exec.pspace = &asicInit;
+    xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling ASIC Init\n");
+    if (RHDAtomBiosFunc(handle->scrnIndex, handle,
+			ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	xf86DrvMsg(handle->scrnIndex, X_INFO, "ASIC_INIT Successful\n");
+	return TRUE;
+    }
+    xf86DrvMsg(handle->scrnIndex, X_INFO, "ASIC_INIT Failed\n");
+    return FALSE;
+}
+
+Bool
+rhdAtomSetScaler(atomBiosHandlePtr handle, unsigned char scalerID, int setting)
+{
+    ENABLE_SCALER_PARAMETERS scaler;
+    AtomBiosArgRec data;
+
+    scaler.ucScaler = scalerID;
+    scaler.ucEnable = setting;
+    data.exec.dataSpace = NULL;
+    data.exec.index = 0x21;
+    data.exec.pspace = &scaler;
+    xf86DrvMsg(handle->scrnIndex, X_INFO, "Calling EnableScaler\n");
+    if (RHDAtomBiosFunc(handle->scrnIndex, handle,
+			ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	xf86DrvMsg(handle->scrnIndex, X_INFO, "EnableScaler Successful\n");
+	return TRUE;
+    }
+    xf86DrvMsg(handle->scrnIndex, X_INFO, "EableScaler Failed\n");
+    return FALSE;
+}
+
+# endif
+
+static AtomBiosResult
+rhdAtomInit(atomBiosHandlePtr unused1, AtomBiosRequestID unused2,
+		    AtomBiosArgPtr data)
+{
+    int scrnIndex = data->val;
+    RADEONInfoPtr  info   = RADEONPTR(xf86Screens[scrnIndex]);
+    unsigned char *ptr;
+    atomDataTablesPtr atomDataPtr;
+    unsigned int cmd_offset;
+    atomBiosHandlePtr handle = NULL;
+    unsigned int BIOSImageSize = 0;
+    data->atomhandle = NULL;
+
+    //RHDFUNCI(scrnIndex);
+
+    /*if (info->BIOSCopy) {
+	xf86DrvMsg(scrnIndex,X_INFO,"Getting BIOS copy from INT10\n");
+	ptr = info->BIOSCopy;
+	info->BIOSCopy = NULL;
+
+	BIOSImageSize = ptr[2] * 512;
+	if (BIOSImageSize > legacyBIOSMax) {
+	    xf86DrvMsg(scrnIndex,X_ERROR,"Invalid BIOS length field\n");
+	    return ATOM_FAILED;
+	}
+    } else*/ {
+	/*if (!xf86IsEntityPrimary(info->entityIndex)) {
+	    if (!(BIOSImageSize = RHDReadPCIBios(info, &ptr)))
+		return ATOM_FAILED;
+	} else*/ {
+	     int read_len;
+	    unsigned char tmp[32];
+	    xf86DrvMsg(scrnIndex,X_INFO,"Getting BIOS copy from legacy VBIOS location\n");
+	    if (xf86ReadBIOS(legacyBIOSLocation, 0, tmp, 32) < 0) {
+		xf86DrvMsg(scrnIndex,X_ERROR,
+			   "Cannot obtain POSTed BIOS header\n");
+		return ATOM_FAILED;
+	    }
+	    BIOSImageSize = tmp[2] * 512;
+	    if (BIOSImageSize > legacyBIOSMax) {
+		xf86DrvMsg(scrnIndex,X_ERROR,"Invalid BIOS length field\n");
+		return ATOM_FAILED;
+	    }
+	    if (!(ptr = xcalloc(1,BIOSImageSize))) {
+		xf86DrvMsg(scrnIndex,X_ERROR,
+			   "Cannot allocate %i bytes of memory "
+			   "for BIOS image\n",BIOSImageSize);
+		return ATOM_FAILED;
+	    }
+	    if ((read_len = xf86ReadBIOS(legacyBIOSLocation, 0, ptr, BIOSImageSize)
+		 < 0)) {
+		xf86DrvMsg(scrnIndex,X_ERROR,"Cannot read POSTed BIOS\n");
+		goto error;
+	    }
+	}
+    }
+
+    if (!(atomDataPtr = xcalloc(1, sizeof(atomDataTables)))) {
+	xf86DrvMsg(scrnIndex,X_ERROR,"Cannot allocate memory for "
+		   "ATOM BIOS data tabes\n");
+	goto error;
+    }
+    if (!rhdAtomGetDataTable(scrnIndex, ptr, atomDataPtr, &cmd_offset, BIOSImageSize))
+	goto error1;
+    if (!(handle = xcalloc(1, sizeof(atomBiosHandleRec)))) {
+	xf86DrvMsg(scrnIndex,X_ERROR,"Cannot allocate memory\n");
+	goto error1;
+    }
+    handle->BIOSBase = ptr;
+    handle->atomDataPtr = atomDataPtr;
+    handle->cmd_offset = cmd_offset;
+    handle->scrnIndex = scrnIndex;
+#if XSERVER_LIBPCIACCESS
+    handle->device = info->PciInfo;
+#else
+    handle->PciTag = info->PciTag;
+#endif
+    handle->BIOSImageSize = BIOSImageSize;
+
+# if ATOM_BIOS_PARSER
+    /* Try to find out if BIOS has been posted (either by system or int10 */
+    if (!rhdAtomGetFbBaseAndSize(handle, NULL, NULL)) {
+	/* run AsicInit */
+	if (!rhdAtomASICInit(handle))
+	    xf86DrvMsg(scrnIndex, X_WARNING,
+		       "%s: AsicInit failed. Won't be able to obtain in VRAM "
+		       "FB scratch space\n",__func__);
+    }
+# endif
+
+    data->atomhandle = handle;
+    return ATOM_SUCCESS;
+
+ error1:
+    xfree(atomDataPtr);
+ error:
+    xfree(ptr);
+    return ATOM_FAILED;
+}
+
+static AtomBiosResult
+rhdAtomTearDown(atomBiosHandlePtr handle,
+		AtomBiosRequestID unused1, AtomBiosArgPtr unused2)
+{
+    //RHDFUNC(handle);
+
+    xfree(handle->BIOSBase);
+    xfree(handle->atomDataPtr);
+    if (handle->scratchBase) xfree(handle->scratchBase);
+    xfree(handle);
+    return ATOM_SUCCESS;
+}
+
+static AtomBiosResult
+rhdAtomVramInfoQuery(atomBiosHandlePtr handle, AtomBiosRequestID func,
+		     AtomBiosArgPtr data)
+{
+    atomDataTablesPtr atomDataPtr;
+    CARD32 *val = &data->val;
+    //RHDFUNC(handle);
+
+    atomDataPtr = handle->atomDataPtr;
+
+    switch (func) {
+	case GET_FW_FB_START:
+	    *val = atomDataPtr->VRAM_UsageByFirmware
+		->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware;
+	    break;
+	case GET_FW_FB_SIZE:
+	    *val = atomDataPtr->VRAM_UsageByFirmware
+		->asFirmwareVramReserveInfo[0].usFirmwareUseInKb;
+	    break;
+	default:
+	    return ATOM_NOT_IMPLEMENTED;
+    }
+    return ATOM_SUCCESS;
+}
+
+static AtomBiosResult
+rhdAtomTmdsInfoQuery(atomBiosHandlePtr handle,
+		     AtomBiosRequestID func, AtomBiosArgPtr data)
+{
+    atomDataTablesPtr atomDataPtr;
+    CARD32 *val = &data->val;
+    int idx = *val;
+
+    atomDataPtr = handle->atomDataPtr;
+    if (!rhdAtomGetTableRevisionAndSize(
+	    (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->TMDS_Info),
+	    NULL,NULL,NULL)) {
+	return ATOM_FAILED;
+    }
+
+    //RHDFUNC(handle);
+
+    switch (func) {
+	case ATOM_TMDS_FREQUENCY:
+	    *val = atomDataPtr->TMDS_Info->asMiscInfo[idx].usFrequency;
+	    break;
+	case ATOM_TMDS_PLL_CHARGE_PUMP:
+	    *val = atomDataPtr->TMDS_Info->asMiscInfo[idx].ucPLL_ChargePump;
+	    break;
+	case ATOM_TMDS_PLL_DUTY_CYCLE:
+	    *val = atomDataPtr->TMDS_Info->asMiscInfo[idx].ucPLL_DutyCycle;
+	    break;
+	case ATOM_TMDS_PLL_VCO_GAIN:
+	    *val = atomDataPtr->TMDS_Info->asMiscInfo[idx].ucPLL_VCO_Gain;
+	    break;
+	case ATOM_TMDS_PLL_VOLTAGE_SWING:
+	    *val = atomDataPtr->TMDS_Info->asMiscInfo[idx].ucPLL_VoltageSwing;
+	    break;
+	default:
+	    return ATOM_NOT_IMPLEMENTED;
+    }
+    return ATOM_SUCCESS;
+}
+
+static DisplayModePtr
+rhdAtomDTDTimings(atomBiosHandlePtr handle, ATOM_DTD_FORMAT *dtd)
+{
+    DisplayModePtr mode;
+#define NAME_LEN 16
+    char name[NAME_LEN];
+
+    //RHDFUNC(handle);
+
+    if (!dtd->usHActive || !dtd->usVActive)
+	return NULL;
+
+    if (!(mode = (DisplayModePtr)xcalloc(1,sizeof(DisplayModeRec))))
+	return NULL;
+
+    mode->CrtcHDisplay = mode->HDisplay = dtd->usHActive;
+    mode->CrtcVDisplay = mode->VDisplay = dtd->usVActive;
+    mode->CrtcHBlankStart = dtd->usHActive + dtd->ucHBorder;
+    mode->CrtcHBlankEnd = mode->CrtcHBlankStart + dtd->usHBlanking_Time;
+    mode->CrtcHTotal = mode->HTotal = mode->CrtcHBlankEnd + dtd->ucHBorder;
+    mode->CrtcVBlankStart = dtd->usVActive + dtd->ucVBorder;
+    mode->CrtcVBlankEnd = mode->CrtcVBlankStart + dtd->usVBlanking_Time;
+    mode->CrtcVTotal = mode->VTotal = mode->CrtcVBlankEnd + dtd->ucVBorder;
+    mode->CrtcHSyncStart = mode->HSyncStart = dtd->usHActive + dtd->usHSyncOffset;
+    mode->CrtcHSyncEnd = mode->HSyncEnd = mode->HSyncStart + dtd->usHSyncWidth;
+    mode->CrtcVSyncStart = mode->VSyncStart = dtd->usVActive + dtd->usVSyncOffset;
+    mode->CrtcVSyncEnd = mode->VSyncEnd = mode->VSyncStart + dtd->usVSyncWidth;
+
+    mode->SynthClock = mode->Clock = dtd->usPixClk * 10;
+
+    mode->HSync = ((float) mode->Clock) / ((float)mode->HTotal);
+    mode->VRefresh = (1000.0 * ((float) mode->Clock))
+	/ ((float)(((float)mode->HTotal) * ((float)mode->VTotal)));
+
+    if (dtd->susModeMiscInfo.sbfAccess.CompositeSync)
+	mode->Flags |= V_CSYNC;
+    if (dtd->susModeMiscInfo.sbfAccess.Interlace)
+	mode->Flags |= V_INTERLACE;
+    if (dtd->susModeMiscInfo.sbfAccess.DoubleClock)
+	mode->Flags |= V_DBLSCAN;
+    if (dtd->susModeMiscInfo.sbfAccess.VSyncPolarity)
+	mode->Flags |= V_NVSYNC;
+    if (dtd->susModeMiscInfo.sbfAccess.HSyncPolarity)
+	mode->Flags |= V_NHSYNC;
+
+    snprintf(name, NAME_LEN, "%dx%d",
+	     mode->HDisplay, mode->VDisplay);
+    mode->name = xstrdup(name);
+
+    ErrorF("DTD Modeline: %s  "
+	   "%2.d  %i (%i) %i %i (%i) %i  %i (%i) %i %i (%i) %i flags: 0x%x\n",
+	   mode->name, mode->Clock,
+	   mode->HDisplay, mode->CrtcHBlankStart, mode->HSyncStart, mode->CrtcHSyncEnd,
+	   mode->CrtcHBlankEnd, mode->HTotal,
+	   mode->VDisplay, mode->CrtcVBlankStart, mode->VSyncStart, mode->VSyncEnd,
+	   mode->CrtcVBlankEnd, mode->VTotal, mode->Flags);
+
+    return mode;
+}
+
+static unsigned char*
+rhdAtomLvdsDDC(atomBiosHandlePtr handle, CARD32 offset, unsigned char *record)
+{
+    unsigned char *EDIDBlock;
+
+    //RHDFUNC(handle);
+
+    while (*record != ATOM_RECORD_END_TYPE) {
+
+	switch (*record) {
+	    case LCD_MODE_PATCH_RECORD_MODE_TYPE:
+		offset += sizeof(ATOM_PATCH_RECORD_MODE);
+		if (offset > handle->BIOSImageSize) break;
+		record += sizeof(ATOM_PATCH_RECORD_MODE);
+		break;
+
+	    case LCD_RTS_RECORD_TYPE:
+		offset += sizeof(ATOM_LCD_RTS_RECORD);
+		if (offset > handle->BIOSImageSize) break;
+		record += sizeof(ATOM_LCD_RTS_RECORD);
+		break;
+
+	    case LCD_CAP_RECORD_TYPE:
+		offset += sizeof(ATOM_LCD_MODE_CONTROL_CAP);
+		if (offset > handle->BIOSImageSize) break;
+		record += sizeof(ATOM_LCD_MODE_CONTROL_CAP);
+		break;
+
+	    case LCD_FAKE_EDID_PATCH_RECORD_TYPE:
+		offset += sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
+		/* check if the structure still fully lives in the BIOS image */
+		if (offset > handle->BIOSImageSize) break;
+		offset += ((ATOM_FAKE_EDID_PATCH_RECORD*)record)->ucFakeEDIDLength
+		    - sizeof(UCHAR);
+		if (offset > handle->BIOSImageSize) break;
+		/* dup string as we free it later */
+		if (!(EDIDBlock = (unsigned char *)xalloc(
+			  ((ATOM_FAKE_EDID_PATCH_RECORD*)record)->ucFakeEDIDLength)))
+		    return NULL;
+		memcpy(EDIDBlock,&((ATOM_FAKE_EDID_PATCH_RECORD*)record)->ucFakeEDIDString,
+		       ((ATOM_FAKE_EDID_PATCH_RECORD*)record)->ucFakeEDIDLength);
+
+		/* for testing */
+		{
+		    xf86MonPtr mon = xf86InterpretEDID(handle->scrnIndex,EDIDBlock);
+		    xf86PrintEDID(mon);
+		    xfree(mon);
+		}
+		return EDIDBlock;
+
+	    case LCD_PANEL_RESOLUTION_RECORD_TYPE:
+		offset += sizeof(ATOM_PANEL_RESOLUTION_PATCH_RECORD);
+		if (offset > handle->BIOSImageSize) break;
+		record += sizeof(ATOM_PANEL_RESOLUTION_PATCH_RECORD);
+		break;
+
+	    default:
+		xf86DrvMsg(handle->scrnIndex, X_ERROR,
+			   "%s: unknown record type: %x\n",__func__,*record);
+		return NULL;
+	}
+    }
+
+    return NULL;
+}
+
+static AtomBiosResult
+rhdAtomCVGetTimings(atomBiosHandlePtr handle, AtomBiosRequestID func,
+		    AtomBiosArgPtr data)
+{
+    atomDataTablesPtr atomDataPtr;
+    CARD8 crev, frev;
+    DisplayModePtr  last       = NULL;
+    DisplayModePtr  new        = NULL;
+    DisplayModePtr  first      = NULL;
+    int i;
+
+    data->modes = NULL;
+
+    atomDataPtr = handle->atomDataPtr;
+
+    if (!rhdAtomGetTableRevisionAndSize(
+	    (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->ComponentVideoInfo.base),
+	    &frev,&crev,NULL)) {
+	return ATOM_FAILED;
+    }
+
+    switch (frev) {
+
+	case 1:
+	    switch (func) {
+		case ATOMBIOS_GET_CV_MODES:
+		    for (i = 0; i < MAX_SUPPORTED_CV_STANDARDS; i++) {
+			new = rhdAtomDTDTimings(handle,
+						&atomDataPtr->ComponentVideoInfo
+						.ComponentVideoInfo->aModeTimings[i]);
+
+			if (!new)
+			    continue;
+
+			new->type      |= M_T_DRIVER;
+			new->next       = NULL;
+			new->prev       = last;
+
+			if (last) last->next = new;
+			last = new;
+			if (!first) first = new;
+		    }
+		    if (last) {
+			last->next   = NULL; //first;
+			first->prev  = NULL; //last;
+			data->modes = first;
+		    }
+		    if (data->modes)
+			return ATOM_SUCCESS;
+		default:
+		    return ATOM_FAILED;
+	    }
+	case 2:
+	    switch (func) {
+		case ATOMBIOS_GET_CV_MODES:
+		    for (i = 0; i < MAX_SUPPORTED_CV_STANDARDS; i++) {
+			new = rhdAtomDTDTimings(handle,
+						&atomDataPtr->ComponentVideoInfo
+						.ComponentVideoInfo_v21->aModeTimings[i]);
+
+			if (!new)
+			    continue;
+
+			new->type      |= M_T_DRIVER;
+			new->next       = NULL;
+			new->prev       = last;
+
+			if (last) last->next = new;
+			last = new;
+			if (!first) first = new;
+
+		    }
+		    if (last) {
+			last->next   = NULL; //first;
+			first->prev  = NULL; //last;
+			data->modes = first;
+		    }
+		    if (data->modes)
+			return ATOM_SUCCESS;
+		    return ATOM_FAILED;
+
+		default:
+		    return ATOM_FAILED;
+	    }
+	default:
+	    return ATOM_NOT_IMPLEMENTED;
+    }
+/*NOTREACHED*/
+}
+
+static AtomBiosResult
+rhdAtomLvdsGetTimings(atomBiosHandlePtr handle, AtomBiosRequestID func,
+		    AtomBiosArgPtr data)
+{
+    atomDataTablesPtr atomDataPtr;
+    CARD8 crev, frev;
+    unsigned long offset;
+
+    //RHDFUNC(handle);
+
+    atomDataPtr = handle->atomDataPtr;
+
+    if (!rhdAtomGetTableRevisionAndSize(
+	    (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->LVDS_Info.base),
+	    &frev,&crev,NULL)) {
+	return ATOM_FAILED;
+    }
+
+    switch (crev) {
+
+	case 1:
+	    switch (func) {
+		case ATOMBIOS_GET_PANEL_MODE:
+		    data->modes = rhdAtomDTDTimings(handle,
+						   &atomDataPtr->LVDS_Info
+						   .LVDS_Info->sLCDTiming);
+		    if (data->modes)
+			return ATOM_SUCCESS;
+		default:
+		    return ATOM_FAILED;
+	    }
+	case 2:
+	    switch (func) {
+		case ATOMBIOS_GET_PANEL_MODE:
+		    data->modes = rhdAtomDTDTimings(handle,
+						   &atomDataPtr->LVDS_Info
+						   .LVDS_Info_v12->sLCDTiming);
+		    if (data->modes)
+			return ATOM_SUCCESS;
+		    return ATOM_FAILED;
+
+		case ATOMBIOS_GET_PANEL_EDID:
+		    offset = (unsigned long)&atomDataPtr->LVDS_Info.base
+			- (unsigned long)handle->BIOSBase
+			+ atomDataPtr->LVDS_Info
+			.LVDS_Info_v12->usExtInfoTableOffset;
+
+		    data->EDIDBlock
+			= rhdAtomLvdsDDC(handle, offset,
+					 (unsigned char *)
+					 &atomDataPtr->LVDS_Info.base
+					 + atomDataPtr->LVDS_Info
+					 .LVDS_Info_v12->usExtInfoTableOffset);
+		    if (data->EDIDBlock)
+			return ATOM_SUCCESS;
+		default:
+		    return ATOM_FAILED;
+	    }
+	default:
+	    return ATOM_NOT_IMPLEMENTED;
+    }
+/*NOTREACHED*/
+}
+
+static AtomBiosResult
+rhdAtomLvdsInfoQuery(atomBiosHandlePtr handle,
+		     AtomBiosRequestID func,  AtomBiosArgPtr data)
+{
+    atomDataTablesPtr atomDataPtr;
+    CARD8 crev, frev;
+    CARD32 *val = &data->val;
+
+    //RHDFUNC(handle);
+
+    atomDataPtr = handle->atomDataPtr;
+
+    if (!rhdAtomGetTableRevisionAndSize(
+	    (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->LVDS_Info.base),
+	    &frev,&crev,NULL)) {
+	return ATOM_FAILED;
+    }
+
+    switch (crev) {
+	case 1:
+	    switch (func) {
+		case ATOM_LVDS_SUPPORTED_REFRESH_RATE:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info->usSupportedRefreshRate;
+		    break;
+		case ATOM_LVDS_OFF_DELAY:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info->usOffDelayInMs;
+		    break;
+		case ATOM_LVDS_SEQ_DIG_ONTO_DE:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info->ucPowerSequenceDigOntoDEin10Ms * 10;
+		    break;
+		case ATOM_LVDS_SEQ_DE_TO_BL:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info->ucPowerSequenceDEtoBLOnin10Ms * 10;
+		    break;
+		case     ATOM_LVDS_DITHER:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info->ucLVDS_Misc & 0x40;
+		    break;
+		case     ATOM_LVDS_DUALLINK:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info->ucLVDS_Misc & 0x01;
+		    break;
+		case     ATOM_LVDS_24BIT:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info->ucLVDS_Misc & 0x02;
+		    break;
+		case     ATOM_LVDS_GREYLVL:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info->ucLVDS_Misc & 0x0C;
+		    break;
+		case     ATOM_LVDS_FPDI:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info->ucLVDS_Misc * 0x10;
+		    break;
+		default:
+		    return ATOM_NOT_IMPLEMENTED;
+	    }
+	    break;
+	case 2:
+	    switch (func) {
+		case ATOM_LVDS_SUPPORTED_REFRESH_RATE:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info_v12->usSupportedRefreshRate;
+		    break;
+		case ATOM_LVDS_OFF_DELAY:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info_v12->usOffDelayInMs;
+		    break;
+		case ATOM_LVDS_SEQ_DIG_ONTO_DE:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info_v12->ucPowerSequenceDigOntoDEin10Ms * 10;
+		    break;
+		case ATOM_LVDS_SEQ_DE_TO_BL:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info_v12->ucPowerSequenceDEtoBLOnin10Ms * 10;
+		    break;
+		case     ATOM_LVDS_DITHER:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info_v12->ucLVDS_Misc & 0x40;
+		    break;
+		case     ATOM_LVDS_DUALLINK:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info_v12->ucLVDS_Misc & 0x01;
+		    break;
+		case     ATOM_LVDS_24BIT:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info_v12->ucLVDS_Misc & 0x02;
+		    break;
+		case     ATOM_LVDS_GREYLVL:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info_v12->ucLVDS_Misc & 0x0C;
+		    break;
+		case     ATOM_LVDS_FPDI:
+		    *val = atomDataPtr->LVDS_Info
+			.LVDS_Info_v12->ucLVDS_Misc * 0x10;
+		    break;
+		default:
+		    return ATOM_NOT_IMPLEMENTED;
+	    }
+	    break;
+	default:
+	    return ATOM_NOT_IMPLEMENTED;
+    }
+
+    return ATOM_SUCCESS;
+}
+
+static AtomBiosResult
+rhdAtomCompassionateDataQuery(atomBiosHandlePtr handle,
+			AtomBiosRequestID func, AtomBiosArgPtr data)
+{
+    atomDataTablesPtr atomDataPtr;
+    CARD8 crev, frev;
+    CARD32 *val = &data->val;
+
+    //RHDFUNC(handle);
+
+    atomDataPtr = handle->atomDataPtr;
+
+    if (!rhdAtomGetTableRevisionAndSize(
+	    (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->CompassionateData),
+	    &frev,&crev,NULL)) {
+	return ATOM_FAILED;
+    }
+
+    switch (func) {
+	case ATOM_DAC1_BG_ADJ:
+	    *val = atomDataPtr->CompassionateData->
+		ucDAC1_BG_Adjustment;
+	    break;
+	case ATOM_DAC1_DAC_ADJ:
+	    *val = atomDataPtr->CompassionateData->
+		ucDAC1_DAC_Adjustment;
+	    break;
+	case ATOM_DAC1_FORCE:
+	    *val = atomDataPtr->CompassionateData->
+		usDAC1_FORCE_Data;
+	    break;
+	case ATOM_DAC2_CRTC2_BG_ADJ:
+	    *val = atomDataPtr->CompassionateData->
+		ucDAC2_CRT2_BG_Adjustment;
+	    break;
+	case ATOM_DAC2_CRTC2_DAC_ADJ:
+	    *val = atomDataPtr->CompassionateData->
+		ucDAC2_CRT2_DAC_Adjustment;
+	    break;
+	case ATOM_DAC2_CRTC2_FORCE:
+	    *val = atomDataPtr->CompassionateData->
+		usDAC2_CRT2_FORCE_Data;
+	    break;
+	case ATOM_DAC2_CRTC2_MUX_REG_IND:
+	    *val = atomDataPtr->CompassionateData->
+		usDAC2_CRT2_MUX_RegisterIndex;
+	    break;
+	case ATOM_DAC2_CRTC2_MUX_REG_INFO:
+	    *val = atomDataPtr->CompassionateData->
+		ucDAC2_CRT2_MUX_RegisterInfo;
+	    break;
+	default:
+	    return ATOM_NOT_IMPLEMENTED;
+    }
+    return ATOM_SUCCESS;
+}
+
+static AtomBiosResult
+rhdAtomGPIOI2CInfoQuery(atomBiosHandlePtr handle,
+			AtomBiosRequestID func, AtomBiosArgPtr data)
+{
+    atomDataTablesPtr atomDataPtr;
+    CARD8 crev, frev;
+    CARD32 *val = &data->val;
+    unsigned short size;
+
+    //RHDFUNC(handle);
+
+    atomDataPtr = handle->atomDataPtr;
+
+    if (!rhdAtomGetTableRevisionAndSize(
+	    (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->GPIO_I2C_Info),
+	    &frev,&crev,&size)) {
+	return ATOM_FAILED;
+    }
+
+    switch (func) {
+	case ATOM_GPIO_I2C_CLK_MASK:
+	    if ((sizeof(ATOM_COMMON_TABLE_HEADER)
+		 + (*val * sizeof(ATOM_GPIO_I2C_ASSIGMENT))) > size) {
+		xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: GPIO_I2C Device "
+			   "num %lu exeeds table size %u\n",__func__,
+			   (unsigned long)val,
+			   size);
+		return ATOM_FAILED;
+	    }
+
+	    *val = atomDataPtr->GPIO_I2C_Info->asGPIO_Info[*val]
+		.usClkMaskRegisterIndex;
+	    break;
+
+	default:
+	    return ATOM_NOT_IMPLEMENTED;
+    }
+    return ATOM_SUCCESS;
+}
+
+static AtomBiosResult
+rhdAtomFirmwareInfoQuery(atomBiosHandlePtr handle,
+			 AtomBiosRequestID func, AtomBiosArgPtr data)
+{
+    atomDataTablesPtr atomDataPtr;
+    CARD8 crev, frev;
+    CARD32 *val = &data->val;
+
+    //RHDFUNC(handle);
+
+    atomDataPtr = handle->atomDataPtr;
+
+    if (!rhdAtomGetTableRevisionAndSize(
+	    (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->FirmwareInfo.base),
+	    &crev,&frev,NULL)) {
+	return ATOM_FAILED;
+    }
+
+    switch (crev) {
+	case 1:
+	    switch (func) {
+		case GET_DEFAULT_ENGINE_CLOCK:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo->ulDefaultEngineClock * 10;
+		    break;
+		case GET_DEFAULT_MEMORY_CLOCK:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo->ulDefaultMemoryClock * 10;
+		    break;
+		case GET_MAX_PIXEL_CLOCK_PLL_OUTPUT:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo->ulMaxPixelClockPLL_Output * 10;
+		    break;
+		case GET_MIN_PIXEL_CLOCK_PLL_OUTPUT:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo->usMinPixelClockPLL_Output * 10;
+		case GET_MAX_PIXEL_CLOCK_PLL_INPUT:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo->usMaxPixelClockPLL_Input * 10;
+		    break;
+		case GET_MIN_PIXEL_CLOCK_PLL_INPUT:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo->usMinPixelClockPLL_Input * 10;
+		    break;
+		case GET_MAX_PIXEL_CLK:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo->usMaxPixelClock * 10;
+		    break;
+		case GET_REF_CLOCK:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo->usReferenceClock * 10;
+		    break;
+		default:
+		    return ATOM_NOT_IMPLEMENTED;
+	    }
+	case 2:
+	    switch (func) {
+		case GET_DEFAULT_ENGINE_CLOCK:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_2->ulDefaultEngineClock * 10;
+		    break;
+		case GET_DEFAULT_MEMORY_CLOCK:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_2->ulDefaultMemoryClock * 10;
+		    break;
+		case GET_MAX_PIXEL_CLOCK_PLL_OUTPUT:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_2->ulMaxPixelClockPLL_Output * 10;
+		    break;
+		case GET_MIN_PIXEL_CLOCK_PLL_OUTPUT:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_2->usMinPixelClockPLL_Output * 10;
+		    break;
+		case GET_MAX_PIXEL_CLOCK_PLL_INPUT:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_2->usMaxPixelClockPLL_Input * 10;
+		    break;
+		case GET_MIN_PIXEL_CLOCK_PLL_INPUT:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_2->usMinPixelClockPLL_Input * 10;
+		    break;
+		case GET_MAX_PIXEL_CLK:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_2->usMaxPixelClock * 10;
+		    break;
+		case GET_REF_CLOCK:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_2->usReferenceClock * 10;
+		    break;
+		default:
+		    return ATOM_NOT_IMPLEMENTED;
+	    }
+	    break;
+	case 3:
+	    switch (func) {
+		case GET_DEFAULT_ENGINE_CLOCK:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_3->ulDefaultEngineClock * 10;
+		    break;
+		case GET_DEFAULT_MEMORY_CLOCK:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_3->ulDefaultMemoryClock * 10;
+		    break;
+		case GET_MAX_PIXEL_CLOCK_PLL_OUTPUT:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_3->ulMaxPixelClockPLL_Output * 10;
+		    break;
+		case GET_MIN_PIXEL_CLOCK_PLL_OUTPUT:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_3->usMinPixelClockPLL_Output * 10;
+		    break;
+		case GET_MAX_PIXEL_CLOCK_PLL_INPUT:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_3->usMaxPixelClockPLL_Input * 10;
+		    break;
+		case GET_MIN_PIXEL_CLOCK_PLL_INPUT:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_3->usMinPixelClockPLL_Input * 10;
+		    break;
+		case GET_MAX_PIXEL_CLK:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_3->usMaxPixelClock * 10;
+		    break;
+		case GET_REF_CLOCK:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_3->usReferenceClock * 10;
+		    break;
+		default:
+		    return ATOM_NOT_IMPLEMENTED;
+	    }
+	    break;
+	case 4:
+	    switch (func) {
+		case GET_DEFAULT_ENGINE_CLOCK:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_4->ulDefaultEngineClock * 10;
+		    break;
+		case GET_DEFAULT_MEMORY_CLOCK:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_4->ulDefaultMemoryClock * 10;
+		    break;
+		case GET_MAX_PIXEL_CLOCK_PLL_INPUT:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_4->usMaxPixelClockPLL_Input * 10;
+		    break;
+		case GET_MIN_PIXEL_CLOCK_PLL_INPUT:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_4->usMinPixelClockPLL_Input * 10;
+		    break;
+		case GET_MAX_PIXEL_CLOCK_PLL_OUTPUT:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_4->ulMaxPixelClockPLL_Output * 10;
+		    break;
+		case GET_MIN_PIXEL_CLOCK_PLL_OUTPUT:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_4->usMinPixelClockPLL_Output * 10;
+		    break;
+		case GET_MAX_PIXEL_CLK:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_4->usMaxPixelClock * 10;
+		    break;
+		case GET_REF_CLOCK:
+		    *val = atomDataPtr->FirmwareInfo
+			.FirmwareInfo_V_1_4->usReferenceClock * 10;
+		    break;
+		default:
+		    return ATOM_NOT_IMPLEMENTED;
+	    }
+	    break;
+	default:
+	    return ATOM_NOT_IMPLEMENTED;
+    }
+    return ATOM_SUCCESS;
+}
+
+const int object_connector_convert[] =
+    { CONNECTOR_NONE,
+      CONNECTOR_DVI_I,
+      CONNECTOR_DVI_I,
+      CONNECTOR_DVI_D,
+      CONNECTOR_DVI_D,
+      CONNECTOR_VGA,
+      CONNECTOR_CTV,
+      CONNECTOR_STV,
+      CONNECTOR_NONE,
+      CONNECTOR_DIN,
+      CONNECTOR_SCART,
+      CONNECTOR_HDMI_TYPE_A,
+      CONNECTOR_HDMI_TYPE_B,
+      CONNECTOR_HDMI_TYPE_B,
+      CONNECTOR_LVDS,
+      CONNECTOR_DIN,
+      CONNECTOR_NONE,
+      CONNECTOR_NONE,
+      CONNECTOR_NONE,
+      CONNECTOR_NONE,
+    };
+
+static void
+rhdAtomParseI2CRecord(atomBiosHandlePtr handle,
+			ATOM_I2C_RECORD *Record, int *line)
+{
+    ErrorF(" %s:  I2C Record: %s[%x] EngineID: %x I2CAddr: %x\n",
+	     __func__,
+	     Record->sucI2cId.bfHW_Capable ? "HW_Line" : "GPIO_ID",
+	     Record->sucI2cId.bfI2C_LineMux,
+	     Record->sucI2cId.bfHW_EngineID,
+	     Record->ucI2CAddr);
+
+    if (!*(unsigned char *)&(Record->sucI2cId))
+	*line = 0;
+    else {
+
+	if (Record->ucI2CAddr != 0)
+	    return;
+	*line = Record->sucI2cId.bfI2C_LineMux;
+	return;
+    }
+}
+
+static RADEONI2CBusRec
+RADEONLookupGPIOLineForDDC(ScrnInfoPtr pScrn, CARD8 id)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+    atomDataTablesPtr atomDataPtr;
+    ATOM_GPIO_I2C_ASSIGMENT gpio;
+    RADEONI2CBusRec i2c;
+    CARD8 crev, frev;
+
+    i2c.valid = FALSE;
+
+    atomDataPtr = info->atomBIOS->atomDataPtr;
+
+    if (!rhdAtomGetTableRevisionAndSize(
+	    &(atomDataPtr->GPIO_I2C_Info->sHeader),
+	    &crev,&frev,NULL)) {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No GPIO Info Table found!\n");
+	return i2c;
+    }
+
+    gpio = atomDataPtr->GPIO_I2C_Info->asGPIO_Info[id];
+    i2c.mask_clk_reg = gpio.usClkMaskRegisterIndex * 4;
+    i2c.mask_data_reg = gpio.usDataMaskRegisterIndex * 4;
+    i2c.put_clk_reg = gpio.usClkEnRegisterIndex * 4;
+    i2c.put_data_reg = gpio.usDataEnRegisterIndex * 4;
+    i2c.get_clk_reg = gpio.usClkY_RegisterIndex * 4;
+    i2c.get_data_reg = gpio.usDataY_RegisterIndex * 4;
+    i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift);
+    i2c.mask_data_mask = (1 << gpio.ucDataMaskShift);
+    i2c.put_clk_mask = (1 << gpio.ucClkEnShift);
+    i2c.put_data_mask = (1 << gpio.ucDataEnShift);
+    i2c.get_clk_mask = (1 << gpio.ucClkY_Shift);
+    i2c.get_data_mask = (1 <<  gpio.ucDataY_Shift);
+    i2c.valid = TRUE;
+
+    return i2c;
+}
+
+Bool
+RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+    CARD8 crev, frev;
+    unsigned short size;
+    atomDataTablesPtr atomDataPtr;
+    ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
+    int i, j, line = 0;
+
+    atomDataPtr = info->atomBIOS->atomDataPtr;
+    if (!rhdAtomGetTableRevisionAndSize((ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->Object_Header), &crev, &frev, &size))
+	return FALSE;
+
+    if (crev < 2)
+	return FALSE;
+    
+    con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *)
+	((char *)&atomDataPtr->Object_Header->sHeader +
+	 atomDataPtr->Object_Header->usConnectorObjectTableOffset);
+
+    for (i = 0; i < con_obj->ucNumberOfObjects; i++) {
+	ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *SrcDstTable;
+	ATOM_COMMON_RECORD_HEADER *Record;
+	CARD8 obj_id, num, obj_type;
+	int record_base;
+
+	obj_id = (con_obj->asObjects[i].usObjectID & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+	num = (con_obj->asObjects[i].usObjectID & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
+	obj_type = (con_obj->asObjects[i].usObjectID & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
+	if (obj_type != GRAPH_OBJECT_TYPE_CONNECTOR)
+	    continue;
+
+	SrcDstTable = (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *)
+	    ((char *)&atomDataPtr->Object_Header->sHeader
+	     + con_obj->asObjects[i].usSrcDstTableOffset);
+	
+	ErrorF("object id %04x %02x\n", obj_id, SrcDstTable->ucNumberOfSrc);
+	info->BiosConnector[i].ConnectorType = object_connector_convert[obj_id];
+	info->BiosConnector[i].valid = TRUE;
+	info->BiosConnector[i].devices = 0;
+
+	for (j = 0; j < SrcDstTable->ucNumberOfSrc; j++) {
+	    CARD8 sobj_id;
+
+	    sobj_id = (SrcDstTable->usSrcObjectID[j] & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+	    ErrorF("src object id %04x %d\n", SrcDstTable->usSrcObjectID[j], sobj_id);
+	    
+	    switch(sobj_id) {
+	    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+		info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX);
+		break;
+	    case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+		info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP1_INDEX);
+		info->BiosConnector[i].TMDSType = TMDS_INT;
+		break;
+	    case ENCODER_OBJECT_ID_INTERNAL_TMDS2:
+		info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP2_INDEX);
+		info->BiosConnector[i].TMDSType = TMDS_EXT;
+		break;
+	    case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+		info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP3_INDEX);
+		info->BiosConnector[i].TMDSType = TMDS_LVTMA;
+		break;
+	    case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+		info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_CRT1_INDEX);
+		info->BiosConnector[i].DACType = DAC_PRIMARY;
+		break;
+	    case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+		if (info->BiosConnector[i].ConnectorType == CONNECTOR_DIN ||
+		    info->BiosConnector[i].ConnectorType == CONNECTOR_STV ||
+		    info->BiosConnector[i].ConnectorType == CONNECTOR_CTV)
+		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_TV1_INDEX);
+		else
+		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_CRT2_INDEX);
+		info->BiosConnector[i].DACType = DAC_TVDAC;
+		break;
+	    }
+	}
+
+	Record = (ATOM_COMMON_RECORD_HEADER *)
+	    ((char *)&atomDataPtr->Object_Header->sHeader
+	     + con_obj->asObjects[i].usRecordOffset);
+
+	record_base = con_obj->asObjects[i].usRecordOffset;
+
+	while (Record->ucRecordType > 0
+	       && Record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER ) {
+
+	    ErrorF("record type %d\n", Record->ucRecordType);
+	    switch (Record->ucRecordType) {
+		case ATOM_I2C_RECORD_TYPE:
+		    rhdAtomParseI2CRecord(info->atomBIOS, 
+					  (ATOM_I2C_RECORD *)Record,
+					  &line);
+		    info->BiosConnector[i].ddc_i2c = RADEONLookupGPIOLineForDDC(pScrn, line);
+		    break;
+		case ATOM_HPD_INT_RECORD_TYPE:
+		    break;
+		case ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE:
+		    break;
+	    }
+
+	    Record = (ATOM_COMMON_RECORD_HEADER*)
+		((char *)Record + Record->ucRecordSize);
+	}
+    }
+    return TRUE;
+}
+
+Bool
+RADEONGetATOMTVInfo(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    ATOM_ANALOG_TV_INFO *tv_info;
+
+    tv_info = info->atomBIOS->atomDataPtr->AnalogTV_Info;
+
+    if (!tv_info)
+	return FALSE;
+
+    switch(tv_info->ucTV_BootUpDefaultStandard) {
+    case NTSC_SUPPORT:
+	radeon_output->default_tvStd = TV_STD_NTSC;
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC\n");
+	break;
+    case NTSCJ_SUPPORT:
+	radeon_output->default_tvStd = TV_STD_NTSC_J;
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC-J\n");
+	break;
+    case PAL_SUPPORT:
+	radeon_output->default_tvStd = TV_STD_PAL;
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL\n");
+	break;
+    case PALM_SUPPORT:
+	radeon_output->default_tvStd = TV_STD_PAL_M;
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-M\n");
+	break;
+    case PAL60_SUPPORT:
+	radeon_output->default_tvStd = TV_STD_PAL_60;
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-60\n");
+	break;
+    }
+
+    radeon_output->tvStd = radeon_output->default_tvStd;
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standards supported by chip: ");
+    radeon_output->SupportedTVStds = radeon_output->default_tvStd;
+    if (tv_info->ucTV_SupportedStandard & NTSC_SUPPORT) {
+	ErrorF("NTSC ");
+	radeon_output->SupportedTVStds |= TV_STD_NTSC;
+    }
+    if (tv_info->ucTV_SupportedStandard & NTSCJ_SUPPORT) {
+	ErrorF("NTSC-J ");
+	radeon_output->SupportedTVStds |= TV_STD_NTSC_J;
+    }
+    if (tv_info->ucTV_SupportedStandard & PAL_SUPPORT) {
+	ErrorF("PAL ");
+	radeon_output->SupportedTVStds |= TV_STD_PAL;
+    }
+    if (tv_info->ucTV_SupportedStandard & PALM_SUPPORT) {
+	ErrorF("PAL-M ");
+	radeon_output->SupportedTVStds |= TV_STD_PAL_M;
+    }
+    if (tv_info->ucTV_SupportedStandard & PAL60_SUPPORT) {
+	ErrorF("PAL-60 ");
+	radeon_output->SupportedTVStds |= TV_STD_PAL_60;
+    }
+    ErrorF("\n");
+
+    if (tv_info->ucExt_TV_ASIC_ID) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unknown external TV ASIC\n");
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+Bool
+RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, int32_t *pixel_clock)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    ATOM_ANALOG_TV_INFO *tv_info;
+
+    tv_info = info->atomBIOS->atomDataPtr->AnalogTV_Info;
+
+    if (index > MAX_SUPPORTED_TV_TIMING)
+	return FALSE;
+
+    crtc_timing->usH_Total = tv_info->aModeTimings[index].usCRTC_H_Total;
+    crtc_timing->usH_Disp = tv_info->aModeTimings[index].usCRTC_H_Disp;
+    crtc_timing->usH_SyncStart = tv_info->aModeTimings[index].usCRTC_H_SyncStart;
+    crtc_timing->usH_SyncWidth = tv_info->aModeTimings[index].usCRTC_H_SyncWidth;
+
+    crtc_timing->usV_Total = tv_info->aModeTimings[index].usCRTC_V_Total;
+    crtc_timing->usV_Disp = tv_info->aModeTimings[index].usCRTC_V_Disp;
+    crtc_timing->usV_SyncStart = tv_info->aModeTimings[index].usCRTC_V_SyncStart;
+    crtc_timing->usV_SyncWidth = tv_info->aModeTimings[index].usCRTC_V_SyncWidth;
+
+    crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo;
+
+    crtc_timing->ucOverscanRight = tv_info->aModeTimings[index].usCRTC_OverscanRight;
+    crtc_timing->ucOverscanLeft = tv_info->aModeTimings[index].usCRTC_OverscanLeft;
+    crtc_timing->ucOverscanBottom = tv_info->aModeTimings[index].usCRTC_OverscanBottom;
+    crtc_timing->ucOverscanTop = tv_info->aModeTimings[index].usCRTC_OverscanTop;
+    *pixel_clock = tv_info->aModeTimings[index].usPixelClock * 10;
+
+    return TRUE;
+}
+
+Bool
+RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+    atomDataTablesPtr atomDataPtr;
+    CARD8 crev, frev;
+    int i, j;
+
+    atomDataPtr = info->atomBIOS->atomDataPtr;
+
+    if (!rhdAtomGetTableRevisionAndSize(
+	    &(atomDataPtr->SupportedDevicesInfo.SupportedDevicesInfo->sHeader),
+	    &crev,&frev,NULL)) {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Device Info Table found!\n");
+	return FALSE;
+    }
+
+    for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+	ATOM_CONNECTOR_INFO_I2C ci
+	    = atomDataPtr->SupportedDevicesInfo.SupportedDevicesInfo->asConnInfo[i];
+
+	if (!(atomDataPtr->SupportedDevicesInfo
+	      .SupportedDevicesInfo->usDeviceSupport & (1 << i))) {
+	    info->BiosConnector[i].valid = FALSE;
+	    continue;
+	}
+
+#if 1
+	if (i == ATOM_DEVICE_CV_INDEX) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Skipping Component Video\n");
+	    info->BiosConnector[i].valid = FALSE;
+	    continue;
+	}
+#endif
+
+	info->BiosConnector[i].valid = TRUE;
+	info->BiosConnector[i].output_id = ci.sucI2cId.sbfAccess.bfI2C_LineMux;
+	info->BiosConnector[i].devices = (1 << i);
+	info->BiosConnector[i].ConnectorType = ci.sucConnectorInfo.sbfAccess.bfConnectorType;
+	info->BiosConnector[i].DACType = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC;
+
+	/* don't assign a gpio for tv */
+	if ((i == ATOM_DEVICE_TV1_INDEX) ||
+	    (i == ATOM_DEVICE_TV2_INDEX) ||
+	    (i == ATOM_DEVICE_CV_INDEX))
+	    info->BiosConnector[i].ddc_i2c.valid = FALSE;
+	else
+	    info->BiosConnector[i].ddc_i2c =
+		RADEONLookupGPIOLineForDDC(pScrn, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
+
+	if (i == ATOM_DEVICE_DFP1_INDEX)
+	    info->BiosConnector[i].TMDSType = TMDS_INT;
+	else if (i == ATOM_DEVICE_DFP2_INDEX)
+	    info->BiosConnector[i].TMDSType = TMDS_EXT;
+	else if (i == ATOM_DEVICE_DFP3_INDEX)
+	    info->BiosConnector[i].TMDSType = TMDS_LVTMA;
+	else
+	    info->BiosConnector[i].TMDSType = TMDS_NONE;
+
+	/* Always set the connector type to VGA for CRT1/CRT2. if they are
+	 * shared with a DVI port, we'll pick up the DVI connector below when we
+	 * merge the outputs
+	 */
+	if ((i == ATOM_DEVICE_CRT1_INDEX || i == ATOM_DEVICE_CRT2_INDEX) &&
+	    (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I ||
+	     info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D ||
+	     info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A)) {
+	    info->BiosConnector[i].ConnectorType = CONNECTOR_VGA;
+	}
+
+	if (crev > 1) {
+	    ATOM_CONNECTOR_INC_SRC_BITMAP isb
+		= atomDataPtr->SupportedDevicesInfo
+		.SupportedDevicesInfo_HD->asIntSrcInfo[i];
+
+	    switch (isb.ucIntSrcBitmap) {
+		case 0x4:
+		    info->BiosConnector[i].hpd_mask = 0x00000001;
+		    break;
+		case 0xa:
+		    info->BiosConnector[i].hpd_mask = 0x00000100;
+		    break;
+		default:
+		    info->BiosConnector[i].hpd_mask = 0;
+		    break;
+	    }
+	} else {
+	    info->BiosConnector[i].hpd_mask = 0;
+	}
+    }
+
+    /* CRTs/DFPs may share a port */
+    for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+	if (info->BiosConnector[i].valid) {
+	    for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) {
+		if (info->BiosConnector[j].valid && (i != j) ) {
+		    if (info->BiosConnector[i].output_id == info->BiosConnector[j].output_id) {
+			if (((i == ATOM_DEVICE_DFP1_INDEX) ||
+			     (i == ATOM_DEVICE_DFP2_INDEX) ||
+			     (i == ATOM_DEVICE_DFP3_INDEX)) &&
+			    ((j == ATOM_DEVICE_CRT1_INDEX) || (j == ATOM_DEVICE_CRT2_INDEX))) {
+			    info->BiosConnector[i].DACType = info->BiosConnector[j].DACType;
+			    info->BiosConnector[i].devices |= info->BiosConnector[j].devices;
+			    info->BiosConnector[j].valid = FALSE;
+			} else if (((j == ATOM_DEVICE_DFP1_INDEX) ||
+			     (j == ATOM_DEVICE_DFP2_INDEX) ||
+			     (j == ATOM_DEVICE_DFP3_INDEX)) &&
+			    ((i == ATOM_DEVICE_CRT1_INDEX) || (i == ATOM_DEVICE_CRT2_INDEX))) {
+			    info->BiosConnector[j].DACType = info->BiosConnector[i].DACType;
+			    info->BiosConnector[j].devices |= info->BiosConnector[i].devices;
+			    info->BiosConnector[i].valid = FALSE;
+			}
+			/* other possible combos?  */
+		    }
+		}
+	    }
+	}
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
+    for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+	if (info->BiosConnector[i].valid) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-0x%x, DACType-%d, TMDSType-%d, ConnectorType-%d, hpd_mask-0x%x\n",
+		       i, (unsigned int)info->BiosConnector[i].ddc_i2c.mask_clk_reg, info->BiosConnector[i].DACType,
+		       info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType,
+		       info->BiosConnector[i].hpd_mask);
+	}
+    }
+
+    return TRUE;
+}
+
+#if 0
+#define RHD_CONNECTORS_MAX 4
+#define MAX_OUTPUTS_PER_CONNECTOR 2
+
+#define Limit(n,max,name) ((n >= max) ? ( \
+     xf86DrvMsg(handle->scrnIndex,X_ERROR,"%s: %s %i exceeds maximum %i\n", \
+		__func__,name,n,max), TRUE) : FALSE)
+
+static const struct _rhd_connector_objs
+{
+    char *name;
+    RADEONConnectorTypeATOM con;
+} rhd_connector_objs[] = {
+    { "NONE", CONNECTOR_NONE_ATOM },
+    { "SINGLE_LINK_DVI_I", CONNECTOR_DVI_I_ATOM },
+    { "DUAL_LINK_DVI_I", CONNECTOR_DVI_I_ATOM },
+    { "SINGLE_LINK_DVI_D", CONNECTOR_DVI_D_ATOM },
+    { "DUAL_LINK_DVI_D", CONNECTOR_DVI_D_ATOM },
+    { "VGA", CONNECTOR_VGA_ATOM },
+    { "COMPOSITE", CONNECTOR_CTV_ATOM },
+    { "SVIDEO", CONNECTOR_STV_ATOM },
+    { "D_CONNECTOR", CONNECTOR_NONE_ATOM },
+    { "9PIN_DIN", CONNECTOR_NONE_ATOM },
+    { "SCART", CONNECTOR_SCART_ATOM },
+    { "HDMI_TYPE_A", CONNECTOR_HDMI_TYPE_A_ATOM },
+    { "HDMI_TYPE_B", CONNECTOR_HDMI_TYPE_B_ATOM },
+    { "HDMI_TYPE_B", CONNECTOR_HDMI_TYPE_B_ATOM },
+    { "LVDS", CONNECTOR_LVDS_ATOM },
+    { "7PIN_DIN", CONNECTOR_STV_ATOM },
+    { "PCIE_CONNECTOR", CONNECTOR_NONE_ATOM },
+    { "CROSSFIRE", CONNECTOR_NONE_ATOM },
+    { "HARDCODE_DVI", CONNECTOR_NONE_ATOM },
+    { "DISPLAYPORT", CONNECTOR_DISPLAY_PORT_ATOM }
+};
+static const int n_rhd_connector_objs = sizeof (rhd_connector_objs) / sizeof(struct _rhd_connector_objs);
+
+static const struct _rhd_encoders
+{
+    char *name;
+    RADEONOutputTypeATOM ot;
+} rhd_encoders[] = {
+    { "NONE", OUTPUT_NONE_ATOM },
+    { "INTERNAL_LVDS", OUTPUT_LVDS_ATOM },
+    { "INTERNAL_TMDS1", OUTPUT_TMDSA_ATOM },
+    { "INTERNAL_TMDS2", OUTPUT_TMDSB_ATOM },
+    { "INTERNAL_DAC1", OUTPUT_DACA_ATOM },
+    { "INTERNAL_DAC2", OUTPUT_DACB_ATOM },
+    { "INTERNAL_SDVOA", OUTPUT_NONE_ATOM },
+    { "INTERNAL_SDVOB", OUTPUT_NONE_ATOM },
+    { "SI170B", OUTPUT_NONE_ATOM },
+    { "CH7303", OUTPUT_NONE_ATOM },
+    { "CH7301", OUTPUT_NONE_ATOM },
+    { "INTERNAL_DVO1", OUTPUT_NONE_ATOM },
+    { "EXTERNAL_SDVOA", OUTPUT_NONE_ATOM },
+    { "EXTERNAL_SDVOB", OUTPUT_NONE_ATOM },
+    { "TITFP513", OUTPUT_NONE_ATOM },
+    { "INTERNAL_LVTM1", OUTPUT_LVTMA_ATOM },
+    { "VT1623", OUTPUT_NONE_ATOM },
+    { "HDMI_SI1930", OUTPUT_NONE_ATOM },
+    { "HDMI_INTERNAL", OUTPUT_NONE_ATOM },
+    { "INTERNAL_KLDSCP_TMDS1", OUTPUT_TMDSA_ATOM },
+    { "INTERNAL_KLSCP_DVO1", OUTPUT_NONE_ATOM },
+    { "INTERNAL_KLDSCP_DAC1", OUTPUT_DACA_ATOM },
+    { "INTERNAL_KLDSCP_DAC2", OUTPUT_DACB_ATOM },
+    { "SI178", OUTPUT_NONE_ATOM },
+    { "MVPU_FPGA", OUTPUT_NONE_ATOM },
+    { "INTERNAL_DDI", OUTPUT_NONE_ATOM },
+    { "VT1625", OUTPUT_NONE_ATOM },
+    { "HDMI_SI1932", OUTPUT_NONE_ATOM },
+    { "AN9801", OUTPUT_NONE_ATOM },
+    { "DP501",  OUTPUT_NONE_ATOM },
+};
+static const int n_rhd_encoders = sizeof (rhd_encoders) / sizeof(struct _rhd_encoders);
+
+static const struct _rhd_connectors
+{
+    char *name;
+    RADEONConnectorTypeATOM con;
+    Bool dual;
+} rhd_connectors[] = {
+    {"NONE", CONNECTOR_NONE_ATOM, FALSE },
+    {"VGA", CONNECTOR_VGA_ATOM, FALSE },
+    {"DVI-I", CONNECTOR_DVI_I_ATOM, TRUE },
+    {"DVI-D", CONNECTOR_DVI_D_ATOM, FALSE },
+    {"DVI-A", CONNECTOR_DVI_A_ATOM, FALSE },
+    {"SVIDEO", CONNECTOR_STV_ATOM, FALSE },
+    {"COMPOSITE", CONNECTOR_CTV_ATOM, FALSE },
+    {"PANEL", CONNECTOR_LVDS_ATOM, FALSE },
+    {"DIGITAL_LINK", CONNECTOR_DIGITAL_ATOM, FALSE },
+    {"SCART", CONNECTOR_SCART_ATOM, FALSE },
+    {"HDMI Type A", CONNECTOR_HDMI_TYPE_A_ATOM, FALSE },
+    {"HDMI Type B", CONNECTOR_HDMI_TYPE_B_ATOM, FALSE },
+    {"UNKNOWN", CONNECTOR_NONE_ATOM, FALSE },
+    {"UNKNOWN", CONNECTOR_NONE_ATOM, FALSE },
+    {"DVI+DIN", CONNECTOR_NONE_ATOM, FALSE }
+};
+static const int n_rhd_connectors = sizeof(rhd_connectors) / sizeof(struct _rhd_connectors);
+
+static const struct _rhd_devices
+{
+    char *name;
+    RADEONOutputTypeATOM ot;
+} rhd_devices[] = {
+    {" CRT1", OUTPUT_NONE_ATOM },
+    {" LCD1", OUTPUT_LVTMA_ATOM },
+    {" TV1", OUTPUT_NONE_ATOM },
+    {" DFP1", OUTPUT_TMDSA_ATOM },
+    {" CRT2", OUTPUT_NONE_ATOM },
+    {" LCD2", OUTPUT_LVTMA_ATOM },
+    {" TV2", OUTPUT_NONE_ATOM },
+    {" DFP2", OUTPUT_LVTMA_ATOM },
+    {" CV", OUTPUT_NONE_ATOM },
+    {" DFP3", OUTPUT_LVTMA_ATOM }
+};
+static const int n_rhd_devices = sizeof(rhd_devices) / sizeof(struct _rhd_devices);
+
+static const rhdDDC hwddc[] = { RHD_DDC_0, RHD_DDC_1, RHD_DDC_2, RHD_DDC_3 };
+static const int n_hwddc = sizeof(hwddc) / sizeof(rhdDDC);
+
+static const rhdOutputType acc_dac[] = { OUTPUT_NONE_ATOM,
+					 OUTPUT_DACA_ATOM,
+					 OUTPUT_DACB_ATOM,
+					 OUTPUT_DAC_EXTERNAL_ATOM };
+static const int n_acc_dac = sizeof(acc_dac) / sizeof (rhdOutputType);
+
+/*
+ *
+ */
+static Bool
+rhdAtomInterpretObjectID(atomBiosHandlePtr handle,
+			 CARD16 id, CARD8 *obj_type, CARD8 *obj_id,
+			 CARD8 *num, char **name)
+{
+    *obj_id = (id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+    *num = (id & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
+    *obj_type = (id & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
+
+    *name = NULL;
+
+    switch (*obj_type) {
+	case GRAPH_OBJECT_TYPE_CONNECTOR:
+	    if (!Limit(*obj_id, n_rhd_connector_objs, "obj_id"))
+		*name = rhd_connector_objs[*obj_id].name;
+	    break;
+	case GRAPH_OBJECT_TYPE_ENCODER:
+	    if (!Limit(*obj_id, n_rhd_encoders, "obj_id"))
+		*name = rhd_encoders[*obj_id].name;
+	    break;
+	default:
+	    break;
+    }
+    return TRUE;
+}
+
+/*
+ *
+ */
+static void
+rhdAtomDDCFromI2CRecord(atomBiosHandlePtr handle,
+			ATOM_I2C_RECORD *Record, rhdDDC *DDC)
+{
+    RHDDebug(handle->scrnIndex,
+	     "   %s:  I2C Record: %s[%x] EngineID: %x I2CAddr: %x\n",
+	     __func__,
+	     Record->sucI2cId.bfHW_Capable ? "HW_Line" : "GPIO_ID",
+	     Record->sucI2cId.bfI2C_LineMux,
+	     Record->sucI2cId.bfHW_EngineID,
+	     Record->ucI2CAddr);
+
+    if (!*(unsigned char *)&(Record->sucI2cId))
+	*DDC = RHD_DDC_NONE;
+    else {
+
+	if (Record->ucI2CAddr != 0)
+	    return;
+
+	if (Record->sucI2cId.bfHW_Capable) {
+
+	    *DDC = (rhdDDC)Record->sucI2cId.bfI2C_LineMux;
+	    if (*DDC >= RHD_DDC_MAX)
+		*DDC = RHD_DDC_NONE;
+
+	} else {
+	    *DDC = RHD_DDC_GPIO;
+	    /* add GPIO pin parsing */
+	}
+    }
+}
+
+/*
+ *
+ */
+static void
+rhdAtomParseGPIOLutForHPD(atomBiosHandlePtr handle,
+			  CARD8 pinID, rhdHPD *HPD)
+{
+    atomDataTablesPtr atomDataPtr;
+    ATOM_GPIO_PIN_LUT *gpio_pin_lut;
+    unsigned short size;
+    int i = 0;
+
+    //RHDFUNC(handle);
+
+    atomDataPtr = handle->atomDataPtr;
+
+    *HPD = RHD_HPD_NONE;
+
+    if (!rhdAtomGetTableRevisionAndSize(
+	    &atomDataPtr->GPIO_Pin_LUT->sHeader, NULL, NULL, &size)) {
+	xf86DrvMsg(handle->scrnIndex, X_ERROR,
+		   "%s: No valid GPIO pin LUT in AtomBIOS\n",__func__);
+	return;
+    }
+    gpio_pin_lut = atomDataPtr->GPIO_Pin_LUT;
+
+    while (1) {
+	if (gpio_pin_lut->asGPIO_Pin[i].ucGPIO_ID  == pinID) {
+
+	    if ((sizeof(ATOM_COMMON_TABLE_HEADER)
+		  + (i * sizeof(ATOM_GPIO_PIN_ASSIGNMENT))) > size)
+		return;
+
+	    RHDDebug(handle->scrnIndex,
+		     "   %s: GPIO PinID: %i Index: %x Shift: %i\n",
+		     __func__,
+		     pinID,
+		     gpio_pin_lut->asGPIO_Pin[i].usGpioPin_AIndex,
+		     gpio_pin_lut->asGPIO_Pin[i].ucGpioPinBitShift);
+
+	    /* grr... map backwards: register indices -> line numbers */
+	    if (gpio_pin_lut->asGPIO_Pin[i].usGpioPin_AIndex
+		== (DC_GPIO_HPD_A >> 2)) {
+		switch (gpio_pin_lut->asGPIO_Pin[i].ucGpioPinBitShift) {
+		    case 0:
+			*HPD = RHD_HPD_0;
+			return;
+		    case 8:
+			*HPD = RHD_HPD_1;
+			return;
+		    case 16:
+			*HPD = RHD_HPD_2;
+			return;
+		}
+	    }
+	}
+	i++;
+    }
+}
+
+/*
+ *
+ */
+static void
+rhdAtomHPDFromRecord(atomBiosHandlePtr handle,
+		     ATOM_HPD_INT_RECORD *Record, rhdHPD *HPD)
+{
+    RHDDebug(handle->scrnIndex,
+	     "   %s:  HPD Record: GPIO ID: %x Plugged_PinState: %x\n",
+	     __func__,
+	     Record->ucHPDIntGPIOID,
+	     Record->ucPluggged_PinState);
+    rhdAtomParseGPIOLutForHPD(handle, Record->ucHPDIntGPIOID, HPD);
+}
+
+/*
+ *
+ */
+static char *
+rhdAtomDeviceTagsFromRecord(atomBiosHandlePtr handle,
+			    ATOM_CONNECTOR_DEVICE_TAG_RECORD *Record)
+{
+    int i, j, k;
+    char *devices;
+
+    //RHDFUNC(handle);
+
+    RHDDebug(handle->scrnIndex,"   NumberOfDevice: %i\n",
+	     Record->ucNumberOfDevice);
+
+    if (!Record->ucNumberOfDevice) return NULL;
+
+    devices = (char *)xcalloc(Record->ucNumberOfDevice * 4 + 1,1);
+
+    for (i = 0; i < Record->ucNumberOfDevice; i++) {
+	k = 0;
+	j = Record->asDeviceTag[i].usDeviceID;
+
+	while (!(j & 0x1)) { j >>= 1; k++; };
+
+	if (!Limit(k,n_rhd_devices,"usDeviceID"))
+	    strcat(devices, rhd_devices[k].name);
+    }
+
+    RHDDebug(handle->scrnIndex,"   Devices:%s\n",devices);
+
+    return devices;
+}
+
+/*
+ *
+ */
+static AtomBiosResult
+rhdAtomConnectorInfoFromObjectHeader(atomBiosHandlePtr handle,
+				     rhdConnectorInfoPtr *ptr)
+{
+    atomDataTablesPtr atomDataPtr;
+    CARD8 crev, frev;
+    ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
+    rhdConnectorInfoPtr cp;
+    unsigned long object_header_end;
+    int ncon = 0;
+    int i,j;
+    unsigned short object_header_size;
+
+    //RHDFUNC(handle);
+
+    atomDataPtr = handle->atomDataPtr;
+
+    if (!rhdAtomGetTableRevisionAndSize(
+	    &atomDataPtr->Object_Header->sHeader,
+	    &crev,&frev,&object_header_size)) {
+	return ATOM_NOT_IMPLEMENTED;
+    }
+
+    if (crev < 2) /* don't bother with anything below rev 2 */
+	return ATOM_NOT_IMPLEMENTED;
+
+    if (!(cp = (rhdConnectorInfoPtr)xcalloc(sizeof(struct rhdConnectorInfo),
+					 RHD_CONNECTORS_MAX)))
+	return ATOM_FAILED;
+
+    object_header_end =
+	atomDataPtr->Object_Header->usConnectorObjectTableOffset
+	+ object_header_size;
+
+    RHDDebug(handle->scrnIndex,"ObjectTable - size: %u, BIOS - size: %u "
+	     "TableOffset: %u object_header_end: %u\n",
+	     object_header_size, handle->BIOSImageSize,
+	     atomDataPtr->Object_Header->usConnectorObjectTableOffset,
+	     object_header_end);
+
+    if ((object_header_size > handle->BIOSImageSize)
+	|| (atomDataPtr->Object_Header->usConnectorObjectTableOffset
+	    > handle->BIOSImageSize)
+	|| object_header_end > handle->BIOSImageSize) {
+	xf86DrvMsg(handle->scrnIndex, X_ERROR,
+		   "%s: Object table information is bogus\n",__func__);
+	return ATOM_FAILED;
+    }
+
+    if (((unsigned long)&atomDataPtr->Object_Header->sHeader
+	 + object_header_end) >  ((unsigned long)handle->BIOSBase
+		     + handle->BIOSImageSize)) {
+	xf86DrvMsg(handle->scrnIndex, X_ERROR,
+		   "%s: Object table extends beyond BIOS Image\n",__func__);
+	return ATOM_FAILED;
+    }
+
+    con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *)
+	((char *)&atomDataPtr->Object_Header->sHeader +
+	 atomDataPtr->Object_Header->usConnectorObjectTableOffset);
+
+    for (i = 0; i < con_obj->ucNumberOfObjects; i++) {
+	ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *SrcDstTable;
+	ATOM_COMMON_RECORD_HEADER *Record;
+	int record_base;
+	CARD8 obj_type, obj_id, num;
+	char *name;
+	int nout = 0;
+
+	rhdAtomInterpretObjectID(handle, con_obj->asObjects[i].usObjectID,
+			     &obj_type, &obj_id, &num, &name);
+
+	RHDDebug(handle->scrnIndex, "Object: ID: %x name: %s type: %x id: %x\n",
+		 con_obj->asObjects[i].usObjectID, name ? name : "",
+		 obj_type, obj_id);
+
+
+	if (obj_type != GRAPH_OBJECT_TYPE_CONNECTOR)
+	    continue;
+
+	SrcDstTable = (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *)
+	    ((char *)&atomDataPtr->Object_Header->sHeader
+	     + con_obj->asObjects[i].usSrcDstTableOffset);
+
+	if (con_obj->asObjects[i].usSrcDstTableOffset
+	    + (SrcDstTable->ucNumberOfSrc
+	       * sizeof(ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT))
+	    > handle->BIOSImageSize) {
+	    xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: SrcDstTable[%i] extends "
+		       "beyond Object_Header table\n",__func__,i);
+	    continue;
+	}
+
+	cp[ncon].Type = rhd_connector_objs[obj_id].con;
+	cp[ncon].Name = RhdAppendString(cp[ncon].Name,name);
+
+	for (j = 0; j < SrcDstTable->ucNumberOfSrc; j++) {
+	    CARD8 stype, sobj_id, snum;
+	    char *sname;
+
+	    rhdAtomInterpretObjectID(handle, SrcDstTable->usSrcObjectID[j],
+				     &stype, &sobj_id, &snum, &sname);
+
+	    RHDDebug(handle->scrnIndex, " * SrcObject: ID: %x name: %s\n",
+		     SrcDstTable->usSrcObjectID[j], sname);
+
+	    cp[ncon].Output[nout] = rhd_encoders[sobj_id].ot;
+	    if (++nout >= MAX_OUTPUTS_PER_CONNECTOR)
+		break;
+	}
+
+	Record = (ATOM_COMMON_RECORD_HEADER *)
+	    ((char *)&atomDataPtr->Object_Header->sHeader
+	     + con_obj->asObjects[i].usRecordOffset);
+
+	record_base = con_obj->asObjects[i].usRecordOffset;
+
+	while (Record->ucRecordType > 0
+	       && Record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER ) {
+	    char *taglist;
+
+	    if ((record_base += Record->ucRecordSize)
+		> object_header_size) {
+		xf86DrvMsg(handle->scrnIndex, X_ERROR,
+			   "%s: Object Records extend beyond Object Table\n",
+			   __func__);
+		break;
+	    }
+
+	    RHDDebug(handle->scrnIndex, " - Record Type: %x\n",
+		     Record->ucRecordType);
+
+	    switch (Record->ucRecordType) {
+
+		case ATOM_I2C_RECORD_TYPE:
+		    rhdAtomDDCFromI2CRecord(handle,
+					    (ATOM_I2C_RECORD *)Record,
+					    &cp[ncon].DDC);
+		    break;
+
+		case ATOM_HPD_INT_RECORD_TYPE:
+		    rhdAtomHPDFromRecord(handle,
+					 (ATOM_HPD_INT_RECORD *)Record,
+					 &cp[ncon].HPD);
+		    break;
+
+		case ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE:
+		    taglist = rhdAtomDeviceTagsFromRecord(handle,
+							  (ATOM_CONNECTOR_DEVICE_TAG_RECORD *)Record);
+		    if (taglist) {
+			cp[ncon].Name = RhdAppendString(cp[ncon].Name,taglist);
+			xfree(taglist);
+		    }
+		    break;
+
+		default:
+		    break;
+	    }
+
+	    Record = (ATOM_COMMON_RECORD_HEADER*)
+		((char *)Record + Record->ucRecordSize);
+
+	}
+
+	if ((++ncon) == RHD_CONNECTORS_MAX)
+	    break;
+    }
+    *ptr = cp;
+
+    RhdPrintConnectorInfo(handle->scrnIndex, cp);
+
+    return ATOM_SUCCESS;
+}
+
+/*
+ *
+ */
+static AtomBiosResult
+rhdAtomConnectorInfoFromSupportedDevices(atomBiosHandlePtr handle,
+					 rhdConnectorInfoPtr *ptr)
+{
+    atomDataTablesPtr atomDataPtr;
+    CARD8 crev, frev;
+    rhdConnectorInfoPtr cp;
+    struct {
+	rhdOutputType ot;
+	rhdConnectorType con;
+	rhdDDC ddc;
+	rhdHPD hpd;
+	Bool dual;
+	char *name;
+	char *outputName;
+    } devices[ATOM_MAX_SUPPORTED_DEVICE];
+    int ncon = 0;
+    int n;
+
+    //RHDFUNC(handle);
+
+    atomDataPtr = handle->atomDataPtr;
+
+    if (!rhdAtomGetTableRevisionAndSize(
+	    &(atomDataPtr->SupportedDevicesInfo.SupportedDevicesInfo->sHeader),
+	    &crev,&frev,NULL)) {
+	return ATOM_NOT_IMPLEMENTED;
+    }
+
+    if (!(cp = (rhdConnectorInfoPtr)xcalloc(RHD_CONNECTORS_MAX,
+					 sizeof(struct rhdConnectorInfo))))
+	return ATOM_FAILED;
+
+    for (n = 0; n < ATOM_MAX_SUPPORTED_DEVICE; n++) {
+	ATOM_CONNECTOR_INFO_I2C ci
+	    = atomDataPtr->SupportedDevicesInfo.SupportedDevicesInfo->asConnInfo[n];
+
+	devices[n].ot = OUTPUT_NONE_ATOM;
+
+	if (!(atomDataPtr->SupportedDevicesInfo
+	      .SupportedDevicesInfo->usDeviceSupport & (1 << n)))
+	    continue;
+
+	if (Limit(ci.sucConnectorInfo.sbfAccess.bfConnectorType,
+		  n_rhd_connectors, "bfConnectorType"))
+	    continue;
+
+	devices[n].con
+	    = rhd_connectors[ci.sucConnectorInfo.sbfAccess.bfConnectorType].con;
+	if (devices[n].con == RHD_CONNECTOR_NONE)
+	    continue;
+
+	devices[n].dual
+	    = rhd_connectors[ci.sucConnectorInfo.sbfAccess.bfConnectorType].dual;
+	devices[n].name
+	    = rhd_connectors[ci.sucConnectorInfo.sbfAccess.bfConnectorType].name;
+
+	RHDDebug(handle->scrnIndex,"AtomBIOS Connector[%i]: %s Device:%s ",n,
+		 rhd_connectors[ci.sucConnectorInfo
+				.sbfAccess.bfConnectorType].name,
+		 rhd_devices[n].name);
+
+	devices[n].outputName = rhd_devices[n].name;
+
+	if (!Limit(ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC,
+		   n_acc_dac, "bfAssociatedDAC")) {
+	    if ((devices[n].ot
+		 = acc_dac[ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC])
+		== OUTPUT_NONE_ATOM) {
+		devices[n].ot = rhd_devices[n].ot;
+	    }
+	} else
+	    devices[n].ot = OUTPUT_NONE_ATOM;
+
+	RHDDebugCont("Output: %x ",devices[n].ot);
+
+	if (ci.sucI2cId.sbfAccess.bfHW_Capable) {
+
+	    RHDDebugCont("HW DDC %i ",
+			 ci.sucI2cId.sbfAccess.bfI2C_LineMux);
+
+	    if (Limit(ci.sucI2cId.sbfAccess.bfI2C_LineMux,
+		      n_hwddc, "bfI2C_LineMux"))
+		devices[n].ddc = RHD_DDC_NONE;
+	    else
+		devices[n].ddc = hwddc[ci.sucI2cId.sbfAccess.bfI2C_LineMux];
+
+	} else if (ci.sucI2cId.sbfAccess.bfI2C_LineMux) {
+
+	    RHDDebugCont("GPIO DDC ");
+	    devices[n].ddc = RHD_DDC_GPIO;
+
+	    /* add support for GPIO line */
+	} else {
+
+	    RHDDebugCont("NO DDC ");
+	    devices[n].ddc = RHD_DDC_NONE;
+
+	}
+
+	if (crev > 1) {
+	    ATOM_CONNECTOR_INC_SRC_BITMAP isb
+		= atomDataPtr->SupportedDevicesInfo
+		.SupportedDevicesInfo_HD->asIntSrcInfo[n];
+
+	    switch (isb.ucIntSrcBitmap) {
+		case 0x4:
+		    RHDDebugCont("HPD 0\n");
+		    devices[n].hpd = RHD_HPD_0;
+		    break;
+		case 0xa:
+		    RHDDebugCont("HPD 1\n");
+		    devices[n].hpd = RHD_HPD_1;
+		    break;
+		default:
+		    RHDDebugCont("NO HPD\n");
+		    devices[n].hpd = RHD_HPD_NONE;
+		    break;
+	    }
+	} else {
+	    RHDDebugCont("NO HPD\n");
+	    devices[n].hpd = RHD_HPD_NONE;
+	}
+    }
+    /* sort devices for connectors */
+    for (n = 0; n < ATOM_MAX_SUPPORTED_DEVICE; n++) {
+	int i;
+
+	if (devices[n].ot == OUTPUT_NONE_ATOM)
+	    continue;
+	if (devices[n].con == CONNECTOR_NONE_ATOM)
+	    continue;
+
+	cp[ncon].DDC = devices[n].ddc;
+	cp[ncon].HPD = devices[n].hpd;
+	cp[ncon].Output[0] = devices[n].ot;
+	cp[ncon].Output[1] = OUTPUT_NONE_ATOM;
+	cp[ncon].Type = devices[n].con;
+	cp[ncon].Name = xf86strdup(devices[n].name);
+	cp[ncon].Name = RhdAppendString(cp[ncon].Name, devices[n].outputName);
+
+	if (devices[n].dual) {
+	    if (devices[n].ddc == RHD_DDC_NONE)
+		xf86DrvMsg(handle->scrnIndex, X_ERROR,
+			   "No DDC channel for device %s found."
+			   " Cannot find matching device.\n",devices[n].name);
+	    else {
+		for (i = n + 1; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+
+		    if (!devices[i].dual)
+			continue;
+
+		    if (devices[n].ddc != devices[i].ddc)
+			continue;
+
+		    if (((devices[n].ot == OUTPUT_DACA_ATOM
+			  || devices[n].ot == OUTPUT_DACB_ATOM)
+			 && (devices[i].ot == OUTPUT_LVTMA_ATOM
+			     || devices[i].ot == OUTPUT_TMDSA_ATOM))
+			|| ((devices[i].ot == OUTPUT_DACA_ATOM
+			     || devices[i].ot == OUTPUT_DACB_ATOM)
+			    && (devices[n].ot == OUTPUT_LVTMA_ATOM
+				|| devices[n].ot == OUTPUT_TMDSA_ATOM))) {
+
+			cp[ncon].Output[1] = devices[i].ot;
+
+			if (cp[ncon].HPD == RHD_HPD_NONE)
+			    cp[ncon].HPD = devices[i].hpd;
+
+			cp[ncon].Name = RhdAppendString(cp[ncon].Name,
+							devices[i].outputName);
+			devices[i].ot = OUTPUT_NONE_ATOM; /* zero the device */
+		    }
+		}
+	    }
+	}
+
+	if ((++ncon) == RHD_CONNECTORS_MAX)
+	    break;
+    }
+    *ptr = cp;
+
+    RhdPrintConnectorInfo(handle->scrnIndex, cp);
+
+    return ATOM_SUCCESS;
+}
+
+/*
+ *
+ */
+static AtomBiosResult
+rhdAtomConnectorInfo(atomBiosHandlePtr handle,
+		     AtomBiosRequestID unused, AtomBiosArgPtr data)
+{
+    data->connectorInfo = NULL;
+
+    if (rhdAtomConnectorInfoFromObjectHeader(handle,&data->connectorInfo)
+	== ATOM_SUCCESS)
+	return ATOM_SUCCESS;
+    else
+	return rhdAtomConnectorInfoFromSupportedDevices(handle,
+							&data->connectorInfo);
+}
+#endif
+
+# ifdef ATOM_BIOS_PARSER
+static AtomBiosResult
+rhdAtomExec (atomBiosHandlePtr handle,
+	     AtomBiosRequestID unused, AtomBiosArgPtr data)
+{
+    RADEONInfoPtr info = RADEONPTR (xf86Screens[handle->scrnIndex]);
+    Bool ret = FALSE;
+    char *msg;
+    int idx = data->exec.index;
+    void *pspace = data->exec.pspace;
+    pointer *dataSpace = data->exec.dataSpace;
+
+    //RHDFUNCI(handle->scrnIndex);
+
+    if (dataSpace) {
+	if (!handle->fbBase && !handle->scratchBase)
+	    return ATOM_FAILED;
+	if (handle->fbBase) {
+	    if (!info->FB) {
+		xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: "
+			   "Cannot exec AtomBIOS: framebuffer not mapped\n",
+			   __func__);
+		return ATOM_FAILED;
+	    }
+	    *dataSpace = (CARD8*)info->FB + handle->fbBase;
+	} else
+	    *dataSpace = (CARD8*)handle->scratchBase;
+    }
+    ret = ParseTableWrapper(pspace, idx, handle,
+			    handle->BIOSBase,
+			    &msg);
+    if (!ret)
+	xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s\n",msg);
+    else
+	xf86DrvMsgVerb(handle->scrnIndex, X_INFO, 5, "%s\n",msg);
+
+    return (ret) ? ATOM_SUCCESS : ATOM_FAILED;
+}
+# endif
+
+AtomBiosResult
+RHDAtomBiosFunc(int scrnIndex, atomBiosHandlePtr handle,
+		AtomBiosRequestID id, AtomBiosArgPtr data)
+{
+    AtomBiosResult ret = ATOM_FAILED;
+    int i;
+    char *msg = NULL;
+    enum msgDataFormat msg_f = MSG_FORMAT_NONE;
+    AtomBiosRequestFunc req_func = NULL;
+
+    //RHDFUNCI(scrnIndex);
+
+    for (i = 0; AtomBiosRequestList[i].id != FUNC_END; i++) {
+	if (id ==  AtomBiosRequestList[i].id) {
+	    req_func = AtomBiosRequestList[i].request;
+	    msg = AtomBiosRequestList[i].message;
+	    msg_f = AtomBiosRequestList[i].message_format;
+	    break;
+	}
+    }
+
+    if (req_func == NULL) {
+	xf86DrvMsg(scrnIndex, X_ERROR, "Unknown AtomBIOS request: %i\n",id);
+	return ATOM_NOT_IMPLEMENTED;
+    }
+    /* Hack for now */
+    if (id == ATOMBIOS_INIT)
+	data->val = scrnIndex;
+
+    if (id == ATOMBIOS_INIT || handle)
+	ret = req_func(handle, id, data);
+
+    if (ret == ATOM_SUCCESS) {
+
+	switch (msg_f) {
+	    case MSG_FORMAT_DEC:
+		xf86DrvMsg(scrnIndex,X_INFO,"%s: %li\n", msg,
+			   (unsigned long) data->val);
+		break;
+	    case MSG_FORMAT_HEX:
+		xf86DrvMsg(scrnIndex,X_INFO,"%s: 0x%lx\n",msg ,
+			   (unsigned long) data->val);
+		break;
+	    case MSG_FORMAT_NONE:
+		xf86DrvMsgVerb(scrnIndex, 7, X_INFO,
+			       "Call to %s succeeded\n", msg);
+		break;
+	}
+
+    } else {
+
+	char *result = (ret == ATOM_FAILED) ? "failed"
+	    : "not implemented";
+	switch (msg_f) {
+	    case MSG_FORMAT_DEC:
+	    case MSG_FORMAT_HEX:
+		xf86DrvMsgVerb(scrnIndex, 1, X_WARNING,
+			       "Call to %s %s\n", msg, result);
+		break;
+	    case MSG_FORMAT_NONE:
+		xf86DrvMsg(scrnIndex,X_INFO,"Query for %s: %s\n", msg, result);
+		    break;
+	}
+    }
+    return ret;
+}
+
+# ifdef ATOM_BIOS_PARSER
+VOID*
+CailAllocateMemory(VOID *CAIL,UINT16 size)
+{
+    CAILFUNC(CAIL);
+
+    return malloc(size);
+}
+
+VOID
+CailReleaseMemory(VOID *CAIL, VOID *addr)
+{
+    CAILFUNC(CAIL);
+
+    free(addr);
+}
+
+VOID
+CailDelayMicroSeconds(VOID *CAIL, UINT32 delay)
+{
+    CAILFUNC(CAIL);
+
+    usleep(delay);
+
+    DEBUGP(xf86DrvMsg(((atomBiosHandlePtr)CAIL)->scrnIndex,X_INFO,"Delay %i usec\n",delay));
+}
+
+UINT32
+CailReadATIRegister(VOID* CAIL, UINT32 idx)
+{
+    ScrnInfoPtr pScrn = xf86Screens[((atomBiosHandlePtr)CAIL)->scrnIndex];
+    RADEONInfoPtr  info   = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    UINT32 ret;
+    CAILFUNC(CAIL);
+
+    ret  =  INREG(idx << 2);
+    DEBUGP(ErrorF("%s(%x) = %x\n",__func__,idx << 2,ret));
+    return ret;
+}
+
+VOID
+CailWriteATIRegister(VOID *CAIL, UINT32 idx, UINT32 data)
+{
+    ScrnInfoPtr pScrn = xf86Screens[((atomBiosHandlePtr)CAIL)->scrnIndex];
+    RADEONInfoPtr  info   = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CAILFUNC(CAIL);
+
+    OUTREG(idx << 2,data);
+    DEBUGP(ErrorF("%s(%x,%x)\n",__func__,idx << 2,data));
+}
+
+UINT32
+CailReadFBData(VOID* CAIL, UINT32 idx)
+{
+    ScrnInfoPtr pScrn = xf86Screens[((atomBiosHandlePtr)CAIL)->scrnIndex];
+    RADEONInfoPtr  info   = RADEONPTR(pScrn);
+    UINT32 ret;
+
+    CAILFUNC(CAIL);
+
+    if (((atomBiosHandlePtr)CAIL)->fbBase) {
+	CARD8 *FBBase = (CARD8*)info->FB;
+	ret =  *((CARD32*)(FBBase + (((atomBiosHandlePtr)CAIL)->fbBase) + idx));
+	DEBUGP(ErrorF("%s(%x) = %x\n",__func__,idx,ret));
+    } else if (((atomBiosHandlePtr)CAIL)->scratchBase) {
+	ret = *(CARD32*)((CARD8*)(((atomBiosHandlePtr)CAIL)->scratchBase) + idx);
+	DEBUGP(ErrorF("%s(%x) = %x\n",__func__,idx,ret));
+    } else {
+	xf86DrvMsg(((atomBiosHandlePtr)CAIL)->scrnIndex,X_ERROR,
+		   "%s: no fbbase set\n",__func__);
+	return 0;
+    }
+    return ret;
+}
+
+VOID
+CailWriteFBData(VOID *CAIL, UINT32 idx, UINT32 data)
+{
+    CAILFUNC(CAIL);
+
+    DEBUGP(ErrorF("%s(%x,%x)\n",__func__,idx,data));
+    if (((atomBiosHandlePtr)CAIL)->fbBase) {
+	CARD8 *FBBase = (CARD8*)
+	    RADEONPTR(xf86Screens[((atomBiosHandlePtr)CAIL)->scrnIndex])->FB;
+	*((CARD32*)(FBBase + (((atomBiosHandlePtr)CAIL)->fbBase) + idx)) = data;
+    } else if (((atomBiosHandlePtr)CAIL)->scratchBase) {
+	*(CARD32*)((CARD8*)(((atomBiosHandlePtr)CAIL)->scratchBase) + idx) = data;
+    } else
+	xf86DrvMsg(((atomBiosHandlePtr)CAIL)->scrnIndex,X_ERROR,
+		   "%s: no fbbase set\n",__func__);
+}
+
+ULONG
+CailReadMC(VOID *CAIL, ULONG Address)
+{
+    ScrnInfoPtr pScrn = xf86Screens[((atomBiosHandlePtr)CAIL)->scrnIndex];
+    ULONG ret;
+
+    CAILFUNC(CAIL);
+
+    ret = INMC(pScrn, Address);
+    DEBUGP(ErrorF("%s(%x) = %x\n",__func__,Address,ret));
+    return ret;
+}
+
+VOID
+CailWriteMC(VOID *CAIL, ULONG Address, ULONG data)
+{
+    ScrnInfoPtr pScrn = xf86Screens[((atomBiosHandlePtr)CAIL)->scrnIndex];
+
+    CAILFUNC(CAIL);
+    DEBUGP(ErrorF("%s(%x,%x)\n",__func__,Address,data));
+    OUTMC(pScrn, Address, data);
+}
+
+#ifdef XSERVER_LIBPCIACCESS
+
+VOID
+CailReadPCIConfigData(VOID*CAIL, VOID* ret, UINT32 idx,UINT16 size)
+{
+    pci_device_cfg_read(RADEONPTR(xf86Screens[((atomBiosHandlePtr)CAIL)->scrnIndex])->PciInfo,
+				ret,idx << 2 , size >> 3, NULL);
+}
+
+VOID
+CailWritePCIConfigData(VOID*CAIL,VOID*src,UINT32 idx,UINT16 size)
+{
+    pci_device_cfg_write(RADEONPTR(xf86Screens[((atomBiosHandlePtr)CAIL)->scrnIndex])->PciInfo,
+			 src, idx << 2, size >> 3, NULL);
+}
+
+#else
+
+VOID
+CailReadPCIConfigData(VOID*CAIL, VOID* ret, UINT32 idx,UINT16 size)
+{
+    PCITAG tag = ((atomBiosHandlePtr)CAIL)->PciTag;
+
+    CAILFUNC(CAIL);
+
+    switch (size) {
+	case 8:
+	    *(CARD8*)ret = pciReadByte(tag,idx << 2);
+	    break;
+	case 16:
+	    *(CARD16*)ret = pciReadWord(tag,idx << 2);
+	    break;
+	case 32:
+	    *(CARD32*)ret = pciReadLong(tag,idx << 2);
+	    break;
+	default:
+	xf86DrvMsg(((atomBiosHandlePtr)CAIL)->scrnIndex,
+		   X_ERROR,"%s: Unsupported size: %i\n",
+		   __func__,(int)size);
+	return;
+	    break;
+    }
+    DEBUGP(ErrorF("%s(%x) = %x\n",__func__,idx,*(unsigned int*)ret));
+
+}
+
+VOID
+CailWritePCIConfigData(VOID*CAIL,VOID*src,UINT32 idx,UINT16 size)
+{
+    PCITAG tag = ((atomBiosHandlePtr)CAIL)->PciTag;
+
+    CAILFUNC(CAIL);
+    DEBUGP(ErrorF("%s(%x,%x)\n",__func__,idx,(*(unsigned int*)src)));
+    switch (size) {
+	case 8:
+	    pciWriteByte(tag,idx << 2,*(CARD8*)src);
+	    break;
+	case 16:
+	    pciWriteWord(tag,idx << 2,*(CARD16*)src);
+	    break;
+	case 32:
+	    pciWriteLong(tag,idx << 2,*(CARD32*)src);
+	    break;
+	default:
+	    xf86DrvMsg(((atomBiosHandlePtr)CAIL)->scrnIndex,X_ERROR,
+		       "%s: Unsupported size: %i\n",__func__,(int)size);
+	    break;
+    }
+}
+#endif
+
+ULONG
+CailReadPLL(VOID *CAIL, ULONG Address)
+{
+    ScrnInfoPtr pScrn = xf86Screens[((atomBiosHandlePtr)CAIL)->scrnIndex];
+    ULONG ret;
+
+    CAILFUNC(CAIL);
+
+    ret = RADEONINPLL(pScrn, Address);
+    DEBUGP(ErrorF("%s(%x) = %x\n",__func__,Address,ret));
+    return ret;
+}
+
+VOID
+CailWritePLL(VOID *CAIL, ULONG Address,ULONG Data)
+{
+    ScrnInfoPtr pScrn = xf86Screens[((atomBiosHandlePtr)CAIL)->scrnIndex];
+    CAILFUNC(CAIL);
+
+    DEBUGP(ErrorF("%s(%x,%x)\n",__func__,Address,Data));
+    RADEONOUTPLL(pScrn, Address, Data);
+}
+
+void
+atombios_get_command_table_version(atomBiosHandlePtr atomBIOS, int index, int *major, int *minor)
+{
+    ATOM_MASTER_COMMAND_TABLE *cmd_table = (void *)(atomBIOS->BIOSBase + atomBIOS->cmd_offset);
+    ATOM_MASTER_LIST_OF_COMMAND_TABLES *table_start;
+    ATOM_COMMON_ROM_COMMAND_TABLE_HEADER *table_hdr;
+
+    //unsigned short *ptr;
+    unsigned short offset;
+
+    table_start = &cmd_table->ListOfCommandTables;
+
+    offset  = *(((unsigned short *)table_start) + index);
+
+    table_hdr = (ATOM_COMMON_ROM_COMMAND_TABLE_HEADER *)(atomBIOS->BIOSBase + offset);
+
+    *major = table_hdr->CommonHeader.ucTableFormatRevision;
+    *minor = table_hdr->CommonHeader.ucTableContentRevision;
+}
+
+
+#endif /* ATOM_BIOS */
diff --git a/src/radeon_atombios.h b/src/radeon_atombios.h
new file mode 100644
index 0000000..9cb279e
--- /dev/null
+++ b/src/radeon_atombios.h
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2007  Egbert Eich   <eich@novell.com>
+ * Copyright 2007  Luc Verhaegen <lverhaegen@novell.com>
+ * Copyright 2007  Matthias Hopf <mhopf@novell.com>
+ * Copyright 2007  Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef RHD_ATOMBIOS_H_
+# define RHD_ATOMBIOS_H_
+
+//#include "radeon.h"
+
+# ifdef ATOM_BIOS
+
+typedef enum _AtomBiosRequestID {
+    ATOMBIOS_INIT,
+    ATOMBIOS_TEARDOWN,
+# ifdef ATOM_BIOS_PARSER
+    ATOMBIOS_EXEC,
+#endif
+    ATOMBIOS_ALLOCATE_FB_SCRATCH,
+    ATOMBIOS_GET_CONNECTORS,
+    ATOMBIOS_GET_PANEL_MODE,
+    ATOMBIOS_GET_PANEL_EDID,
+    GET_DEFAULT_ENGINE_CLOCK,
+    GET_DEFAULT_MEMORY_CLOCK,
+    GET_MAX_PIXEL_CLOCK_PLL_OUTPUT,
+    GET_MIN_PIXEL_CLOCK_PLL_OUTPUT,
+    GET_MAX_PIXEL_CLOCK_PLL_INPUT,
+    GET_MIN_PIXEL_CLOCK_PLL_INPUT,
+    GET_MAX_PIXEL_CLK,
+    GET_REF_CLOCK,
+    GET_FW_FB_START,
+    GET_FW_FB_SIZE,
+    ATOM_TMDS_FREQUENCY,
+    ATOM_TMDS_PLL_CHARGE_PUMP,
+    ATOM_TMDS_PLL_DUTY_CYCLE,
+    ATOM_TMDS_PLL_VCO_GAIN,
+    ATOM_TMDS_PLL_VOLTAGE_SWING,
+    ATOM_LVDS_SUPPORTED_REFRESH_RATE,
+    ATOM_LVDS_OFF_DELAY,
+    ATOM_LVDS_SEQ_DIG_ONTO_DE,
+    ATOM_LVDS_SEQ_DE_TO_BL,
+    ATOM_LVDS_DITHER,
+    ATOM_LVDS_DUALLINK,
+    ATOM_LVDS_24BIT,
+    ATOM_LVDS_GREYLVL,
+    ATOM_LVDS_FPDI,
+    ATOM_GPIO_QUERIES,
+    ATOM_GPIO_I2C_CLK_MASK,
+    ATOM_DAC1_BG_ADJ,
+    ATOM_DAC1_DAC_ADJ,
+    ATOM_DAC1_FORCE,
+    ATOM_DAC2_CRTC2_BG_ADJ,
+    ATOM_DAC2_CRTC2_DAC_ADJ,
+    ATOM_DAC2_CRTC2_FORCE,
+    ATOM_DAC2_CRTC2_MUX_REG_IND,
+    ATOM_DAC2_CRTC2_MUX_REG_INFO,
+    ATOMBIOS_GET_CV_MODES,
+    FUNC_END
+} AtomBiosRequestID;
+
+typedef enum _AtomBiosResult {
+    ATOM_SUCCESS,
+    ATOM_FAILED,
+    ATOM_NOT_IMPLEMENTED
+} AtomBiosResult;
+
+typedef struct AtomExec {
+    int index;
+    pointer pspace;
+    pointer *dataSpace;
+} AtomExecRec, *AtomExecPtr;
+
+typedef struct AtomFb {
+    unsigned int start;
+    unsigned int size;
+} AtomFbRec, *AtomFbPtr;
+
+typedef union AtomBiosArg
+{
+    CARD32 val;
+    struct rhdConnectorInfo	*connectorInfo;
+    unsigned char*		EDIDBlock;
+    atomBiosHandlePtr		atomhandle;
+    DisplayModePtr		modes;
+    AtomExecRec			exec;
+    AtomFbRec			fb;
+} AtomBiosArgRec, *AtomBiosArgPtr;
+
+extern AtomBiosResult
+RHDAtomBiosFunc(int scrnIndex, atomBiosHandlePtr handle,
+		AtomBiosRequestID id, AtomBiosArgPtr data);
+
+extern Bool
+RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn);
+extern Bool
+RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn);
+
+extern Bool
+RADEONGetATOMTVInfo(xf86OutputPtr output);
+
+extern int
+atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode);
+
+extern void
+atombios_get_command_table_version(atomBiosHandlePtr atomBIOS, int index, int *major, int *minor);
+
+# include "xf86int10.h"
+# ifdef ATOM_BIOS_PARSER
+#  define INT8 INT8
+#  define INT16 INT16
+#  define INT32 INT32
+#  include "CD_Common_Types.h"
+# else
+#  ifndef ULONG
+typedef unsigned int ULONG;
+#   define ULONG ULONG
+#  endif
+#  ifndef UCHAR
+typedef unsigned char UCHAR;
+#   define UCHAR UCHAR
+#  endif
+#  ifndef USHORT
+typedef unsigned short USHORT;
+#   define USHORT USHORT
+#  endif
+# endif
+
+# include "atombios.h"
+# include "ObjectID.h"
+
+
+/*
+ * This works around a bug in atombios.h where
+ * ATOM_MAX_SUPPORTED_DEVICE_INFO is specified incorrectly.
+ */
+
+#define ATOM_MAX_SUPPORTED_DEVICE_INFO_HD (ATOM_DEVICE_RESERVEDF_INDEX+1)
+typedef struct _ATOM_SUPPORTED_DEVICES_INFO_HD
+{
+    ATOM_COMMON_TABLE_HEADER      sHeader;
+    USHORT                        usDeviceSupport;
+    ATOM_CONNECTOR_INFO_I2C       asConnInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_HD];
+    ATOM_CONNECTOR_INC_SRC_BITMAP asIntSrcInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_HD];
+} ATOM_SUPPORTED_DEVICES_INFO_HD;
+
+typedef struct _atomDataTables
+{
+    unsigned char                       *UtilityPipeLine;
+    ATOM_MULTIMEDIA_CAPABILITY_INFO     *MultimediaCapabilityInfo;
+    ATOM_MULTIMEDIA_CONFIG_INFO         *MultimediaConfigInfo;
+    ATOM_STANDARD_VESA_TIMING           *StandardVESA_Timing;
+    union {
+        void                            *base;
+        ATOM_FIRMWARE_INFO              *FirmwareInfo;
+        ATOM_FIRMWARE_INFO_V1_2         *FirmwareInfo_V_1_2;
+        ATOM_FIRMWARE_INFO_V1_3         *FirmwareInfo_V_1_3;
+        ATOM_FIRMWARE_INFO_V1_4         *FirmwareInfo_V_1_4;
+    } FirmwareInfo;
+    ATOM_DAC_INFO                       *DAC_Info;
+    union {
+        void                            *base;
+        ATOM_LVDS_INFO                  *LVDS_Info;
+        ATOM_LVDS_INFO_V12              *LVDS_Info_v12;
+    } LVDS_Info;
+    ATOM_TMDS_INFO                      *TMDS_Info;
+    ATOM_ANALOG_TV_INFO                 *AnalogTV_Info;
+    union {
+        void                            *base;
+        ATOM_SUPPORTED_DEVICES_INFO     *SupportedDevicesInfo;
+        ATOM_SUPPORTED_DEVICES_INFO_2   *SupportedDevicesInfo_2;
+        ATOM_SUPPORTED_DEVICES_INFO_2d1 *SupportedDevicesInfo_2d1;
+        ATOM_SUPPORTED_DEVICES_INFO_HD  *SupportedDevicesInfo_HD;
+    } SupportedDevicesInfo;
+    ATOM_GPIO_I2C_INFO                  *GPIO_I2C_Info;
+    ATOM_VRAM_USAGE_BY_FIRMWARE         *VRAM_UsageByFirmware;
+    ATOM_GPIO_PIN_LUT                   *GPIO_Pin_LUT;
+    ATOM_VESA_TO_INTENAL_MODE_LUT       *VESA_ToInternalModeLUT;
+    union {
+        void                            *base;
+        ATOM_COMPONENT_VIDEO_INFO       *ComponentVideoInfo;
+        ATOM_COMPONENT_VIDEO_INFO_V21   *ComponentVideoInfo_v21;
+    } ComponentVideoInfo;
+/**/unsigned char                       *PowerPlayInfo;
+    COMPASSIONATE_DATA                  *CompassionateData;
+    ATOM_DISPLAY_DEVICE_PRIORITY_INFO   *SaveRestoreInfo;
+/**/unsigned char                       *PPLL_SS_Info;
+    ATOM_OEM_INFO                       *OemInfo;
+    ATOM_XTMDS_INFO                     *XTMDS_Info;
+    ATOM_ASIC_MVDD_INFO                 *MclkSS_Info;
+    ATOM_OBJECT_HEADER                  *Object_Header;
+    INDIRECT_IO_ACCESS                  *IndirectIOAccess;
+    ATOM_MC_INIT_PARAM_TABLE            *MC_InitParameter;
+/**/unsigned char                       *ASIC_VDDC_Info;
+    ATOM_ASIC_INTERNAL_SS_INFO          *ASIC_InternalSS_Info;
+/**/unsigned char                       *TV_VideoMode;
+    union {
+        void                            *base;
+        ATOM_VRAM_INFO_V2               *VRAM_Info_v2;
+        ATOM_VRAM_INFO_V3               *VRAM_Info_v3;
+    } VRAM_Info;
+    ATOM_MEMORY_TRAINING_INFO           *MemoryTrainingInfo;
+    union {
+        void                            *base;
+        ATOM_INTEGRATED_SYSTEM_INFO     *IntegratedSystemInfo;
+        ATOM_INTEGRATED_SYSTEM_INFO_V2  *IntegratedSystemInfo_v2;
+    } IntegratedSystemInfo;
+    ATOM_ASIC_PROFILING_INFO            *ASIC_ProfilingInfo;
+    ATOM_VOLTAGE_OBJECT_INFO            *VoltageObjectInfo;
+    ATOM_POWER_SOURCE_INFO              *PowerSourceInfo;
+} atomDataTables, *atomDataTablesPtr;
+
+typedef struct _atomBiosHandle {
+    int scrnIndex;
+    unsigned char *BIOSBase;
+    atomDataTablesPtr atomDataPtr;
+    unsigned int cmd_offset;
+    pointer *scratchBase;
+    CARD32 fbBase;
+#if XSERVER_LIBPCIACCESS
+    struct pci_device *device;
+#else
+    PCITAG PciTag;
+#endif
+    unsigned int BIOSImageSize;
+} atomBiosHandleRec;
+
+# endif
+
+extern Bool
+RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, int32_t *pixel_clock);
+
+#endif /*  RHD_ATOMBIOS_H_ */
diff --git a/src/radeon_atomwrapper.c b/src/radeon_atomwrapper.c
new file mode 100644
index 0000000..259366c
--- /dev/null
+++ b/src/radeon_atomwrapper.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2007  Luc Verhaegen <lverhaegen@novell.com>
+ * Copyright 2007  Matthias Hopf <mhopf@novell.com>
+ * Copyright 2007  Egbert Eich   <eich@novell.com>
+ * Copyright 2007  Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+//#include "radeon_atomwrapper.h"
+
+#define INT32 INT32
+#include "CD_Common_Types.h"
+#include "CD_Definitions.h"
+
+
+int
+ParseTableWrapper(void *pspace, int index, void *handle, void *BIOSBase,
+		  char **msg_return)
+{
+    DEVICE_DATA deviceData;
+    int ret = 0;
+
+    /* FILL OUT PARAMETER SPACE */
+    deviceData.pParameterSpace = (UINT32*) pspace;
+    deviceData.CAIL = handle;
+    deviceData.pBIOS_Image = BIOSBase;
+    deviceData.format = TABLE_FORMAT_BIOS;
+
+    switch (ParseTable(&deviceData, index)) { /* IndexInMasterTable */
+	case CD_SUCCESS:
+	    ret = 1;
+	    *msg_return = "ParseTable said: CD_SUCCESS";
+	    break;
+	case CD_CALL_TABLE:
+	    ret = 1;
+	    *msg_return = "ParseTable said: CD_CALL_TABLE";
+	    break;
+	case CD_COMPLETED:
+	    ret = 1;
+	    *msg_return = "ParseTable said: CD_COMPLETED";
+	    break;
+	case CD_GENERAL_ERROR:
+	    ret = 0;
+	    *msg_return = " ParseTable said: CD_GENERAL_ERROR";
+	    break;
+	case CD_INVALID_OPCODE:
+	    ret = 0;
+	    *msg_return = " ParseTable said: CD_INVALID_OPCODE";
+	    break;
+	case CD_NOT_IMPLEMENTED:
+	    ret = 0;
+	    *msg_return = " ParseTable said: CD_NOT_IMPLEMENTED";
+	    break;
+	case CD_EXEC_TABLE_NOT_FOUND:
+	    ret = 0;
+	    *msg_return = " ParseTable said: CD_EXEC_TABLE_NOT_FOUND";
+	    break;
+	case CD_EXEC_PARAMETER_ERROR:
+	    ret = 0;
+	    *msg_return = " ParseTable said: CD_EXEC_PARAMETER_ERROR";
+	    break;
+	case CD_EXEC_PARSER_ERROR:
+	    ret = 0;
+	    *msg_return = " ParseTable said: CD_EXEC_PARSER_ERROR";
+	    break;
+	case CD_INVALID_DESTINATION_TYPE:
+	    ret = 0;
+	    *msg_return = " ParseTable said: CD_INVALID_DESTINATION_TYPE";
+	    break;
+	case CD_UNEXPECTED_BEHAVIOR:
+	    ret = 0;
+	    *msg_return = " ParseTable said: CD_UNEXPECTED_BEHAVIOR";
+	    break;
+	case CD_INVALID_SWITCH_OPERAND_SIZE:
+	    ret = 0;
+	    *msg_return = " ParseTable said: CD_INVALID_SWITCH_OPERAND_SIZE\n";
+	    break;
+    }
+    return ret;
+}
diff --git a/src/radeon_atomwrapper.h b/src/radeon_atomwrapper.h
new file mode 100644
index 0000000..1e7cc77
--- /dev/null
+++ b/src/radeon_atomwrapper.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2007  Luc Verhaegen <lverhaegen@novell.com>
+ * Copyright 2007  Matthias Hopf <mhopf@novell.com>
+ * Copyright 2007  Egbert Eich   <eich@novell.com>
+ * Copyright 2007  Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef RHD_ATOMWRAPPER_H_
+# define RHD_ATOMWRAPPER_H_
+
+extern int ParseTableWrapper(void *pspace, int index, void *CAIL,
+			      void *BIOSBase, char **msg_return);
+
+#endif /* RHD_ATOMWRAPPER_H_ */
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 7d4d12a..8e6bd8d 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -39,8 +39,33 @@
 #include "radeon_reg.h"
 #include "radeon_macros.h"
 #include "radeon_probe.h"
+#include "radeon_atombios.h"
 #include "vbe.h"
 
+typedef enum
+{
+    DDC_NONE_DETECTED,
+    DDC_MONID,
+    DDC_DVI,
+    DDC_VGA,
+    DDC_CRT2,
+    DDC_LCD,
+    DDC_GPIO,
+} RADEONLegacyDDCType;
+
+typedef enum
+{
+    CONNECTOR_NONE_LEGACY,
+    CONNECTOR_PROPRIETARY_LEGACY,
+    CONNECTOR_CRT_LEGACY,
+    CONNECTOR_DVI_I_LEGACY,
+    CONNECTOR_DVI_D_LEGACY,
+    CONNECTOR_CTV_LEGACY,
+    CONNECTOR_STV_LEGACY,
+    CONNECTOR_UNSUPPORTED_LEGACY
+} RADEONLegacyConnectorType;
+
+
 /* Read the Video BIOS block and the FP registers (if applicable). */
 Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
 {
@@ -49,7 +74,8 @@ Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
     unsigned short dptr;
 
 #ifdef XSERVER_LIBPCIACCESS
-    info->VBIOS = xalloc(info->PciInfo->rom_size);
+    //info->VBIOS = xalloc(info->PciInfo->rom_size);
+    info->VBIOS = xalloc(RADEON_VBIOS_SIZE);
 #else
     info->VBIOS = xalloc(RADEON_VBIOS_SIZE);
 #endif
@@ -130,103 +156,72 @@ Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
     else
 	info->IsAtomBios = FALSE;
 
-    if (info->IsAtomBios) 
-	info->MasterDataStart = RADEON_BIOS16 (info->ROMHeaderStart + 32);
-
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s BIOS detected\n",
 	       info->IsAtomBios ? "ATOM":"Legacy");
 
+    if (info->IsAtomBios) {
+#if 1
+        AtomBiosArgRec atomBiosArg;
+
+        if (RHDAtomBiosFunc(pScrn->scrnIndex, NULL, ATOMBIOS_INIT, &atomBiosArg)
+            == ATOM_SUCCESS) {
+            info->atomBIOS = atomBiosArg.atomhandle;
+        }
+
+        atomBiosArg.fb.start = info->FbFreeStart;
+        atomBiosArg.fb.size = info->FbFreeSize;
+        if (RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS, ATOMBIOS_ALLOCATE_FB_SCRATCH,
+			    &atomBiosArg) == ATOM_SUCCESS) {
+
+	    info->FbFreeStart = atomBiosArg.fb.start;
+	    info->FbFreeSize = atomBiosArg.fb.size;
+        }
+
+        RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS, GET_DEFAULT_ENGINE_CLOCK,
+                        &atomBiosArg);
+        RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS, GET_DEFAULT_MEMORY_CLOCK,
+                        &atomBiosArg);
+        RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
+                        GET_MAX_PIXEL_CLOCK_PLL_OUTPUT, &atomBiosArg);
+        RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
+                        GET_MIN_PIXEL_CLOCK_PLL_OUTPUT, &atomBiosArg);
+        RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
+                        GET_MAX_PIXEL_CLOCK_PLL_INPUT, &atomBiosArg);
+        RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
+			GET_MIN_PIXEL_CLOCK_PLL_INPUT, &atomBiosArg);
+        RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
+			GET_MAX_PIXEL_CLK, &atomBiosArg);
+        RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
+                        GET_REF_CLOCK, &atomBiosArg);
+
+#endif
+	info->MasterDataStart = RADEON_BIOS16 (info->ROMHeaderStart + 32);
+    }
+
     return TRUE;
 }
 
 static Bool RADEONGetATOMConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info = RADEONPTR (pScrn);
-    int offset, i, tmp, tmp0, crtc, portinfo, gpio;
 
     if (!info->VBIOS) return FALSE;
+    
+    if (RADEONGetATOMConnectorInfoFromBIOSObject(pScrn))
+	return TRUE;
 
-    offset = RADEON_BIOS16(info->MasterDataStart + 22);
+    if (RADEONGetATOMConnectorInfoFromBIOSConnectorTable(pScrn))
+	return TRUE;
 
-    if (offset) {
-	tmp = RADEON_BIOS16(offset + 4);
-	for (i = 0; i < 8; i++) {
-	    if (tmp & (1 << i)) {
-		info->BiosConnector[i].valid = TRUE;
-		portinfo = RADEON_BIOS16(offset + 6 + i * 2);
-		info->BiosConnector[i].DACType = (portinfo & 0xf) - 1;
-		info->BiosConnector[i].ConnectorType = (portinfo >> 4) & 0xf;
-		crtc = (portinfo >> 8) & 0xf;
-		tmp0 = RADEON_BIOS16(info->MasterDataStart + 24);
-		gpio = RADEON_BIOS16(tmp0 + 4 + 27 * crtc) * 4;
-		switch(gpio) {
-		case RADEON_GPIO_MONID:
-		    info->BiosConnector[i].DDCType = DDC_MONID;
-		    break;
-		case RADEON_GPIO_DVI_DDC:
-		    info->BiosConnector[i].DDCType = DDC_DVI;
-		    break;
-		case RADEON_GPIO_VGA_DDC:
-		    info->BiosConnector[i].DDCType = DDC_VGA;
-		    break;
-		case RADEON_GPIO_CRT2_DDC:
-		    info->BiosConnector[i].DDCType = DDC_CRT2;
-		    break;
-		case RADEON_LCD_GPIO_MASK:
-		    info->BiosConnector[i].DDCType = DDC_LCD;
-		    break;
-		case RADEON_MDGPIO_EN_REG:
-		    info->BiosConnector[i].DDCType = DDC_GPIO;
-		    break;
-		default:
-		    info->BiosConnector[i].DDCType = DDC_NONE_DETECTED;
-		    break;
-		}
-
-		if (i == 3)
-		    info->BiosConnector[i].TMDSType = TMDS_INT;
-		else if (i == 7)
-		    info->BiosConnector[i].TMDSType = TMDS_EXT;
-		else
-		    info->BiosConnector[i].TMDSType = TMDS_UNKNOWN;
-
-	    } else {
-		info->BiosConnector[i].valid = FALSE;
-	    }
-	}   
-    } else {
-	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Device Info Table found!\n");
-	return FALSE;
-    }
-
-    /* DVI-I ports have 2 entries: one for analog, one for digital.  combine them */
-    if (info->BiosConnector[0].valid && info->BiosConnector[7].valid) {
-	info->BiosConnector[7].DACType = info->BiosConnector[0].DACType;
-	info->BiosConnector[0].valid = FALSE;
-    }
-
-    if (info->BiosConnector[4].valid && info->BiosConnector[3].valid) {
-	info->BiosConnector[3].DACType = info->BiosConnector[4].DACType;
-	info->BiosConnector[4].valid = FALSE;
-    }
-
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
-    for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
-	if (info->BiosConnector[i].valid) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
-		       i, info->BiosConnector[i].DDCType, info->BiosConnector[i].DACType,
-		       info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType);
-	}
-    }
-
-    return TRUE;
+    return FALSE;
 }
 
 static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info = RADEONPTR (pScrn);
     int offset, i, entry, tmp, tmp0, tmp1;
+    RADEONLegacyDDCType DDCType;
+    RADEONLegacyConnectorType ConnectorType;
 
     if (!info->VBIOS) return FALSE;
 
@@ -241,9 +236,66 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    info->BiosConnector[i].valid = TRUE;
 	    tmp = RADEON_BIOS16(entry);
 	    info->BiosConnector[i].ConnectorType = (tmp >> 12) & 0xf;
-	    info->BiosConnector[i].DDCType = (tmp >> 8) & 0xf;
-	    info->BiosConnector[i].DACType = tmp & 0x1;
-	    info->BiosConnector[i].TMDSType = (tmp >> 4) & 0x1;
+	    ConnectorType = (tmp >> 12) & 0xf;
+	    switch (ConnectorType) {
+	    case CONNECTOR_PROPRIETARY_LEGACY:
+		info->BiosConnector[i].ConnectorType = CONNECTOR_LVDS;
+		break;
+	    case CONNECTOR_CRT_LEGACY:
+		info->BiosConnector[i].ConnectorType = CONNECTOR_VGA;
+		break;
+	    case CONNECTOR_DVI_I_LEGACY:
+		info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_I;
+		break;
+	    case CONNECTOR_DVI_D_LEGACY:
+		info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_D;
+		break;
+	    case CONNECTOR_CTV_LEGACY:
+		info->BiosConnector[i].ConnectorType = CONNECTOR_CTV;
+		break;
+	    case CONNECTOR_STV_LEGACY:
+		info->BiosConnector[i].ConnectorType = CONNECTOR_STV;
+		break;
+	    default:
+		xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown Connector Type: %d\n", ConnectorType);
+		info->BiosConnector[i].valid = FALSE;
+		break;
+	    }
+
+	    info->BiosConnector[i].ddc_i2c.valid = FALSE;
+
+	    DDCType = (tmp >> 8) & 0xf;
+	    switch (DDCType) {
+	    case DDC_MONID:
+		info->BiosConnector[i].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
+		break;
+	    case DDC_DVI:
+		info->BiosConnector[i].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+		break;
+	    case DDC_VGA:
+		info->BiosConnector[i].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		break;
+	    case DDC_CRT2:
+		info->BiosConnector[i].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+		break;
+	    default:
+		xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown DDC Type: %d\n", DDCType);
+		break;
+	    }
+
+	    if (tmp & 0x1)
+		info->BiosConnector[i].DACType = DAC_TVDAC;
+	    else
+		info->BiosConnector[i].DACType = DAC_PRIMARY;
+
+	    /* For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC*/
+	    if (info->IsIGP)
+		info->BiosConnector[i].DACType = DAC_TVDAC;
+
+	    if ((tmp >> 4) & 0x1)
+		info->BiosConnector[i].TMDSType = TMDS_EXT;
+	    else
+		info->BiosConnector[i].TMDSType = TMDS_INT;
 
 	    /* most XPRESS chips seem to specify DDC_CRT2 for their 
 	     * VGA DDC port, however DDC never seems to work on that
@@ -251,29 +303,22 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	     * lets see what happens with that.
 	     */
 	    if (info->ChipFamily == CHIP_FAMILY_RS400 &&
-		info->BiosConnector[i].ConnectorType == CONNECTOR_CRT &&
-		info->BiosConnector[i].DDCType == DDC_CRT2) {
-		info->BiosConnector[i].DDCType = DDC_MONID;
+		info->BiosConnector[i].ConnectorType == CONNECTOR_VGA &&
+		info->BiosConnector[i].ddc_i2c.mask_clk_reg == RADEON_GPIO_CRT2_DDC) {
+		info->BiosConnector[i].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
 	    }
 
 	    /* XPRESS desktop chips seem to have a proprietary connector listed for
 	     * DVI-D, try and do the right thing here.
 	    */
 	    if ((!info->IsMobility) &&
-		(info->BiosConnector[i].ConnectorType == CONNECTOR_PROPRIETARY)) {
+		(info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS)) {
 		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 			   "Proprietary connector found, assuming DVI-D\n");
 		info->BiosConnector[i].DACType = DAC_NONE;
 		info->BiosConnector[i].TMDSType = TMDS_EXT;
 		info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_D;
 	    }
-
-	    if (info->BiosConnector[i].ConnectorType >= CONNECTOR_UNSUPPORTED) {
-		xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown connector type: %d!\n",
-			   info->BiosConnector[i].ConnectorType);
-		info->BiosConnector[i].valid = FALSE;
-	    }
-
 	}
     } else {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Connector Info Table found!\n");
@@ -289,7 +334,7 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
 	    info->BiosConnector[0].DACType = DAC_PRIMARY;
 	    info->BiosConnector[0].TMDSType = TMDS_INT;
-	    info->BiosConnector[0].DDCType = DDC_DVI;
+	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	} else
 	    return FALSE;
     }
@@ -299,28 +344,62 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	offset = RADEON_BIOS16(info->ROMHeaderStart + 0x40);
 	if (offset) {
 	    info->BiosConnector[4].valid = TRUE;
-	    info->BiosConnector[4].ConnectorType = CONNECTOR_PROPRIETARY;
+	    info->BiosConnector[4].ConnectorType = CONNECTOR_LVDS;
 	    info->BiosConnector[4].DACType = DAC_NONE;
 	    info->BiosConnector[4].TMDSType = TMDS_NONE;
+	    info->BiosConnector[4].ddc_i2c.valid = FALSE;
 
 	    tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42);
 	    if (tmp) {
 		tmp0 = RADEON_BIOS16(tmp + 0x15);
 		if (tmp0) {
 		    tmp1 = RADEON_BIOS8(tmp0+2) & 0x07;
-		    if (tmp1) {	    
-			info->BiosConnector[4].DDCType	= tmp1;      
-			if (info->BiosConnector[4].DDCType > DDC_GPIO) {
-			    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-				       "Unknown DDCType %d found\n",
-				       info->BiosConnector[4].DDCType);
-			    info->BiosConnector[4].DDCType = DDC_NONE_DETECTED;
+		    if (tmp1) {
+			DDCType	= tmp1;
+			switch (DDCType) {
+			case DDC_MONID:
+			    info->BiosConnector[4].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
+			    break;
+			case DDC_DVI:
+			    info->BiosConnector[4].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+			    break;
+			case DDC_VGA:
+			    info->BiosConnector[4].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+			    break;
+			case DDC_CRT2:
+			    info->BiosConnector[4].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+			    break;
+			case DDC_LCD:
+			    info->BiosConnector[4].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
+			    info->BiosConnector[4].ddc_i2c.mask_clk_mask =
+				RADEON_BIOS32(tmp0 + 0x03) | RADEON_BIOS32(tmp0 + 0x07);
+			    info->BiosConnector[4].ddc_i2c.mask_data_mask =
+				RADEON_BIOS32(tmp0 + 0x03) | RADEON_BIOS32(tmp0 + 0x07);
+			    info->BiosConnector[4].ddc_i2c.put_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
+			    info->BiosConnector[4].ddc_i2c.put_data_mask = RADEON_BIOS32(tmp0 + 0x07);
+			    info->BiosConnector[4].ddc_i2c.get_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
+			    info->BiosConnector[4].ddc_i2c.get_data_mask = RADEON_BIOS32(tmp0 + 0x07);
+			    break;
+			case DDC_GPIO:
+			    info->BiosConnector[4].ddc_i2c = legacy_setup_i2c_bus(RADEON_MDGPIO_EN_REG);
+			    info->BiosConnector[4].ddc_i2c.mask_clk_mask =
+				RADEON_BIOS32(tmp0 + 0x03) | RADEON_BIOS32(tmp0 + 0x07);
+			    info->BiosConnector[4].ddc_i2c.mask_data_mask =
+				RADEON_BIOS32(tmp0 + 0x03) | RADEON_BIOS32(tmp0 + 0x07);
+			    info->BiosConnector[4].ddc_i2c.put_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
+			    info->BiosConnector[4].ddc_i2c.put_data_mask = RADEON_BIOS32(tmp0 + 0x07);
+			    info->BiosConnector[4].ddc_i2c.get_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
+			    info->BiosConnector[4].ddc_i2c.get_data_mask = RADEON_BIOS32(tmp0 + 0x07);
+			    break;
+			default:
+			    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown DDC Type: %d\n", DDCType);
+			    break;
 			}
 			xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "LCD DDC Info Table found!\n");
 		    }
 		}
 	    } else {
-		info->BiosConnector[4].DDCType = DDC_NONE_DETECTED;
+		info->BiosConnector[4].ddc_i2c.valid = FALSE;
 	    }
 	}
     }
@@ -335,7 +414,7 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		info->BiosConnector[5].ConnectorType = CONNECTOR_STV;
 		info->BiosConnector[5].DACType = DAC_TVDAC;
 		info->BiosConnector[5].TMDSType = TMDS_NONE;
-		info->BiosConnector[5].DDCType = DDC_NONE_DETECTED;
+		info->BiosConnector[5].ddc_i2c.valid = FALSE;
 	    }
 	}
     }
@@ -343,8 +422,8 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
     for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	if (info->BiosConnector[i].valid) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
-		       i, info->BiosConnector[i].DDCType, info->BiosConnector[i].DACType,
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-0x%x, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
+		       i, (unsigned int)info->BiosConnector[i].ddc_i2c.mask_clk_reg, info->BiosConnector[i].DACType,
 		       info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType);
 	}
     }
@@ -373,8 +452,7 @@ Bool RADEONGetTVInfoFromBIOS (xf86OutputPtr output) {
     if (!info->VBIOS) return FALSE;
 
     if (info->IsAtomBios) {
-	/* no idea where TV table is on ATOM bios */
-	return FALSE;
+        return RADEONGetATOMTVInfo(output);
     } else {
 	offset = RADEON_BIOS16(info->ROMHeaderStart + 0x32);
 	if (offset) {
@@ -476,20 +554,44 @@ Bool RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn)
 					or use a new algorithm to calculate
 					from min_input and max_input
 				     */
-	    pll->min_pll_freq = RADEON_BIOS16 (pll_info_block + 78);
-	    pll->max_pll_freq = RADEON_BIOS32 (pll_info_block + 32);
+	    pll->pll_out_min = RADEON_BIOS16 (pll_info_block + 78);
+	    pll->pll_out_max = RADEON_BIOS32 (pll_info_block + 32);
+
+	    if (pll->pll_out_min == 0) {
+		if (IS_AVIVO_VARIANT)
+		    pll->pll_out_min = 64800;
+		else
+		    pll->pll_out_min = 20000;
+	    }
+
+	    pll->pll_in_min = RADEON_BIOS16 (pll_info_block + 74);
+	    pll->pll_in_max = RADEON_BIOS16 (pll_info_block + 76);
+
 	    pll->xclk = RADEON_BIOS16 (pll_info_block + 72);
 
 	    info->sclk = RADEON_BIOS32(pll_info_block + 8) / 100.0;
 	    info->mclk = RADEON_BIOS32(pll_info_block + 12) / 100.0;
 	} else {
+	    int rev;
+
 	    pll_info_block = RADEON_BIOS16 (info->ROMHeaderStart + 0x30);
 
+	    rev = RADEON_BIOS8(pll_info_block);
+
 	    pll->reference_freq = RADEON_BIOS16 (pll_info_block + 0x0e);
 	    pll->reference_div = RADEON_BIOS16 (pll_info_block + 0x10);
-	    pll->min_pll_freq = RADEON_BIOS32 (pll_info_block + 0x12);
-	    pll->max_pll_freq = RADEON_BIOS32 (pll_info_block + 0x16);
-	    pll->xclk = RADEON_BIOS16 (pll_info_block + 0x08);
+	    pll->pll_out_min = RADEON_BIOS32 (pll_info_block + 0x12);
+	    pll->pll_out_max = RADEON_BIOS32 (pll_info_block + 0x16);
+
+	    if (rev > 9) {
+		pll->pll_in_min = RADEON_BIOS32(pll_info_block + 0x36);
+		pll->pll_in_max = RADEON_BIOS32(pll_info_block + 0x3a);
+	    } else {
+		pll->pll_in_min = 40;
+		pll->pll_in_max = 500;
+	    }
+
+	    pll->xclk = RADEON_BIOS16(pll_info_block + 0x08);
 
 	    info->sclk = RADEON_BIOS16(pll_info_block + 8) / 100.0;
 	    info->mclk = RADEON_BIOS16(pll_info_block + 10) / 100.0;
@@ -499,15 +601,68 @@ Bool RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn)
 	if (info->mclk == 0) info->mclk = 200;
     }
 
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ref_freq: %d, min_pll: %u, "
-	       "max_pll: %u, xclk: %d, sclk: %f, mclk: %f\n",
-	       pll->reference_freq, (unsigned)pll->min_pll_freq,
-	       (unsigned)pll->max_pll_freq, pll->xclk, info->sclk,
-	       info->mclk);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ref_freq: %d, min_out_pll: %u, "
+	       "max_out_pll: %u, min_in_pll: %u, max_in_pll: %u, xclk: %d, "
+	       "sclk: %f, mclk: %f\n",
+	       pll->reference_freq, (unsigned)pll->pll_out_min,
+	       (unsigned)pll->pll_out_max, (unsigned)pll->pll_in_min,
+	       (unsigned)pll->pll_in_max, pll->xclk, info->sclk, info->mclk);
 
     return TRUE;
 }
 
+Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    int offset, rev, bg, dac;
+
+    if (!info->VBIOS) return FALSE;
+
+    if (info->IsAtomBios) {
+	/* not implemented yet */
+	return FALSE;
+    } else {
+	/* first check TV table */
+	offset = RADEON_BIOS16(info->ROMHeaderStart + 0x32);
+        if (offset) {
+	    rev = RADEON_BIOS8(offset + 0x3);
+	    if (rev > 1) {
+		bg = RADEON_BIOS8(offset + 0xc) & 0xf;
+		dac = (RADEON_BIOS8(offset + 0xc) >> 4) & 0xf;
+		radeon_output->ps2_tvdac_adj = (bg << 16) | (dac << 20);
+
+		bg = RADEON_BIOS8(offset + 0xd) & 0xf;
+		dac = (RADEON_BIOS8(offset + 0xd) >> 4) & 0xf;
+		radeon_output->pal_tvdac_adj = (bg << 16) | (dac << 20);
+
+		bg = RADEON_BIOS8(offset + 0xe) & 0xf;
+		dac = (RADEON_BIOS8(offset + 0xe) >> 4) & 0xf;
+		radeon_output->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
+
+		return TRUE;
+	    }
+	}
+	/* then check CRT table */
+	offset = RADEON_BIOS16(info->ROMHeaderStart + 0x60);
+        if (offset) {
+	    rev = RADEON_BIOS8(offset) & 0x3;
+	    if (rev < 2) {
+		bg = RADEON_BIOS8(offset + 0x3) & 0xf;
+		dac = (RADEON_BIOS8(offset + 0x3) >> 4) & 0xf;
+		radeon_output->ps2_tvdac_adj = (bg << 16) | (dac << 20);
+		radeon_output->pal_tvdac_adj = radeon_output->ps2_tvdac_adj;
+		radeon_output->ntsc_tvdac_adj = radeon_output->ps2_tvdac_adj;
+
+		return TRUE;
+	    }
+	}
+    }
+
+    return FALSE;
+}
+
 Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output)
 {
     ScrnInfoPtr pScrn = output->scrn;
@@ -738,19 +893,19 @@ Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output)
 	    table_start = offset+4;
 	    max_freq = RADEON_BIOS16(table_start);
 	    radeon_output->dvo_i2c_slave_addr = RADEON_BIOS8(table_start+2);
+	    radeon_output->dvo_i2c.valid = FALSE;
 	    gpio_reg = RADEON_BIOS8(table_start+3);
 	    if (gpio_reg == 1)
-		radeon_output->dvo_i2c_reg = RADEON_GPIO_MONID;
+		radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
 	    else if (gpio_reg == 2)
-		radeon_output->dvo_i2c_reg = RADEON_GPIO_DVI_DDC;
+		radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	    else if (gpio_reg == 3)
-		radeon_output->dvo_i2c_reg = RADEON_GPIO_VGA_DDC;
+		radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	    else if (gpio_reg == 4)
-		radeon_output->dvo_i2c_reg = RADEON_GPIO_CRT2_DDC;
+		radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
 	    else if (gpio_reg == 5)
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 			   "unsupported MM gpio_reg\n");
-		/*radeon_output->i2c_reg = RADEON_GPIO_MM;*/
 	    else {
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 			   "Unknown gpio reg: %d\n", gpio_reg);
diff --git a/src/radeon_chipinfo_gen.h b/src/radeon_chipinfo_gen.h
index a12b225..775df06 100644
--- a/src/radeon_chipinfo_gen.h
+++ b/src/radeon_chipinfo_gen.h
@@ -5,8 +5,8 @@ RADEONCardInfo RADEONCards[] = {
  { 0x3154, CHIP_FAMILY_RV380, 1, 0, 0, 0, 0 },
  { 0x3E50, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 },
  { 0x3E54, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 },
- { 0x4136, CHIP_FAMILY_RS100, 0, 1, 0, 0, 0 },
- { 0x4137, CHIP_FAMILY_RS200, 0, 1, 0, 0, 0 },
+ { 0x4136, CHIP_FAMILY_RS100, 0, 1, 0, 0, 1 },
+ { 0x4137, CHIP_FAMILY_RS200, 0, 1, 0, 0, 1 },
  { 0x4144, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 },
  { 0x4145, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 },
  { 0x4146, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 },
@@ -22,12 +22,12 @@ RADEONCardInfo RADEONCards[] = {
  { 0x4154, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 },
  { 0x4155, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 },
  { 0x4156, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 },
- { 0x4237, CHIP_FAMILY_RS200, 0, 1, 0, 0, 0 },
+ { 0x4237, CHIP_FAMILY_RS200, 0, 1, 0, 0, 1 },
  { 0x4242, CHIP_FAMILY_R200, 0, 0, 0, 1, 0 },
  { 0x4243, CHIP_FAMILY_R200, 0, 0, 0, 1, 0 },
- { 0x4336, CHIP_FAMILY_RS100, 1, 1, 0, 0, 0 },
- { 0x4337, CHIP_FAMILY_RS200, 1, 1, 0, 0, 0 },
- { 0x4437, CHIP_FAMILY_RS200, 1, 1, 0, 0, 0 },
+ { 0x4336, CHIP_FAMILY_RS100, 1, 1, 0, 0, 1 },
+ { 0x4337, CHIP_FAMILY_RS200, 1, 1, 0, 0, 1 },
+ { 0x4437, CHIP_FAMILY_RS200, 1, 1, 0, 0, 1 },
  { 0x4966, CHIP_FAMILY_RV250, 0, 0, 0, 0, 0 },
  { 0x4967, CHIP_FAMILY_RV250, 0, 0, 0, 0, 0 },
  { 0x4A48, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 },
@@ -115,6 +115,7 @@ RADEONCardInfo RADEONCards[] = {
  { 0x5B60, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 },
  { 0x5B62, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 },
  { 0x5B63, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 },
+ { 0x5657, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 },
  { 0x5B64, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 },
  { 0x5B65, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 },
  { 0x5C61, CHIP_FAMILY_RV280, 1, 0, 0, 0, 0 },
@@ -135,6 +136,138 @@ RADEONCardInfo RADEONCards[] = {
  { 0x5E4C, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 },
  { 0x5E4D, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 },
  { 0x5E4F, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 },
- { 0x7834, CHIP_FAMILY_RS300, 0, 1, 0, 0, 0 },
- { 0x7835, CHIP_FAMILY_RS300, 1, 1, 0, 0, 0 },
+ { 0x7100, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
+ { 0x7101, CHIP_FAMILY_R520, 1, 0, 0, 0, 0 },
+ { 0x7102, CHIP_FAMILY_R520, 1, 0, 0, 0, 0 },
+ { 0x7103, CHIP_FAMILY_R520, 1, 0, 0, 0, 0 },
+ { 0x7104, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
+ { 0x7105, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
+ { 0x7106, CHIP_FAMILY_R520, 1, 0, 0, 0, 0 },
+ { 0x7108, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
+ { 0x7109, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
+ { 0x710A, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
+ { 0x710B, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
+ { 0x710C, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
+ { 0x710E, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
+ { 0x710F, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 },
+ { 0x7140, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7141, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7142, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7143, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7144, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
+ { 0x7145, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
+ { 0x7146, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7147, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7149, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
+ { 0x714A, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
+ { 0x714B, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
+ { 0x714C, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
+ { 0x714D, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x714E, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x714F, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7151, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7152, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7153, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x715E, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x715F, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7180, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7181, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7183, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7186, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
+ { 0x7187, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7188, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
+ { 0x718A, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
+ { 0x718B, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
+ { 0x718C, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
+ { 0x718D, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
+ { 0x718F, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7193, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7196, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
+ { 0x719B, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x719F, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x71C0, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
+ { 0x71C1, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
+ { 0x71C2, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
+ { 0x71C3, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
+ { 0x71C4, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 },
+ { 0x71C5, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 },
+ { 0x71C6, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
+ { 0x71C7, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
+ { 0x71CD, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
+ { 0x71CE, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
+ { 0x71D2, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
+ { 0x71D4, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 },
+ { 0x71D5, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 },
+ { 0x71D6, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 },
+ { 0x71DA, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
+ { 0x71DE, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 },
+ { 0x7200, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 },
+ { 0x7210, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 },
+ { 0x7211, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 },
+ { 0x7240, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
+ { 0x7243, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
+ { 0x7244, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
+ { 0x7245, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
+ { 0x7246, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
+ { 0x7247, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
+ { 0x7248, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
+ { 0x7249, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
+ { 0x724A, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
+ { 0x724B, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
+ { 0x724C, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
+ { 0x724D, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
+ { 0x724E, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
+ { 0x724F, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 },
+ { 0x7280, CHIP_FAMILY_RV570, 0, 0, 0, 0, 0 },
+ { 0x7281, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 },
+ { 0x7283, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 },
+ { 0x7284, CHIP_FAMILY_R580, 1, 0, 0, 0, 0 },
+ { 0x7287, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 },
+ { 0x7288, CHIP_FAMILY_RV570, 0, 0, 0, 0, 0 },
+ { 0x7289, CHIP_FAMILY_RV570, 0, 0, 0, 0, 0 },
+ { 0x728B, CHIP_FAMILY_RV570, 0, 0, 0, 0, 0 },
+ { 0x728C, CHIP_FAMILY_RV570, 0, 0, 0, 0, 0 },
+ { 0x7290, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 },
+ { 0x7291, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 },
+ { 0x7293, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 },
+ { 0x7297, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 },
+ { 0x7834, CHIP_FAMILY_RS300, 0, 1, 0, 0, 1 },
+ { 0x7835, CHIP_FAMILY_RS300, 1, 1, 0, 0, 1 },
+ { 0x791E, CHIP_FAMILY_RS690, 0, 1, 0, 0, 1 },
+ { 0x791F, CHIP_FAMILY_RS690, 0, 1, 0, 0, 1 },
+ { 0x796C, CHIP_FAMILY_RS740, 0, 1, 0, 0, 1 },
+ { 0x796D, CHIP_FAMILY_RS740, 0, 1, 0, 0, 1 },
+ { 0x796E, CHIP_FAMILY_RS740, 0, 1, 0, 0, 1 },
+ { 0x796F, CHIP_FAMILY_RS740, 0, 1, 0, 0, 1 },
+ { 0x9400, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 },
+ { 0x9401, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 },
+ { 0x9402, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 },
+ { 0x9403, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 },
+ { 0x9405, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 },
+ { 0x940A, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 },
+ { 0x940B, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 },
+ { 0x940F, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 },
+ { 0x94C0, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 },
+ { 0x94C1, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 },
+ { 0x94C3, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 },
+ { 0x94C4, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 },
+ { 0x94C5, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 },
+ { 0x94C6, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 },
+ { 0x94C7, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 },
+ { 0x94C8, CHIP_FAMILY_RV610, 1, 0, 0, 0, 0 },
+ { 0x94C9, CHIP_FAMILY_RV610, 1, 0, 0, 0, 0 },
+ { 0x94CB, CHIP_FAMILY_RV610, 1, 0, 0, 0, 0 },
+ { 0x94CC, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 },
+ { 0x9580, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
+ { 0x9581, CHIP_FAMILY_RV630, 1, 0, 0, 0, 0 },
+ { 0x9583, CHIP_FAMILY_RV630, 1, 0, 0, 0, 0 },
+ { 0x9586, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
+ { 0x9587, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
+ { 0x9588, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
+ { 0x9589, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
+ { 0x958A, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
+ { 0x958B, CHIP_FAMILY_RV630, 1, 0, 0, 0, 0 },
+ { 0x958C, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
+ { 0x958D, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
+ { 0x958E, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
 };
diff --git a/src/radeon_chipset_gen.h b/src/radeon_chipset_gen.h
index 0a7a9c1..0c3fc96 100644
--- a/src/radeon_chipset_gen.h
+++ b/src/radeon_chipset_gen.h
@@ -115,6 +115,7 @@ static SymTabRec RADEONChipsets[] = {
   { PCI_CHIP_RV370_5B60, "ATI Radeon X300 (RV370) 5B60 (PCIE)" },
   { PCI_CHIP_RV370_5B62, "ATI Radeon X600 (RV370) 5B62 (PCIE)" },
   { PCI_CHIP_RV370_5B63, "ATI Radeon X550 (RV370) 5B63 (PCIE)" },
+  { PCI_CHIP_RV370_5657, "ATI Radeon X550XTX (RV370) 5657 (PCIE)" },
   { PCI_CHIP_RV370_5B64, "ATI FireGL V3100 (RV370) 5B64 (PCIE)" },
   { PCI_CHIP_RV370_5B65, "ATI FireMV 2200 PCIE (RV370) 5B65 (PCIE)" },
   { PCI_CHIP_RV280_5C61, "ATI Radeon Mobility 9200 (M9+) 5C61 (AGP)" },
@@ -135,7 +136,139 @@ static SymTabRec RADEONChipsets[] = {
   { PCI_CHIP_RV410_5E4C, "ATI Radeon X700 SE (RV410) (PCIE)" },
   { PCI_CHIP_RV410_5E4D, "ATI Radeon X700 (RV410) (PCIE)" },
   { PCI_CHIP_RV410_5E4F, "ATI Radeon X700 SE (RV410) (PCIE)" },
+  { PCI_CHIP_R520_7100, "ATI Radeon X1800" },
+  { PCI_CHIP_R520_7101, "ATI Mobility Radeon X1800 XT" },
+  { PCI_CHIP_R520_7102, "ATI Mobility Radeon X1800" },
+  { PCI_CHIP_R520_7103, "ATI Mobility FireGL V7200" },
+  { PCI_CHIP_R520_7104, "ATI FireGL V7200" },
+  { PCI_CHIP_R520_7105, "ATI FireGL V5300" },
+  { PCI_CHIP_R520_7106, "ATI Mobility FireGL V7100" },
+  { PCI_CHIP_R520_7108, "ATI Radeon X1800" },
+  { PCI_CHIP_R520_7109, "ATI Radeon X1800" },
+  { PCI_CHIP_R520_710A, "ATI Radeon X1800" },
+  { PCI_CHIP_R520_710B, "ATI Radeon X1800" },
+  { PCI_CHIP_R520_710C, "ATI Radeon X1800" },
+  { PCI_CHIP_R520_710E, "ATI FireGL V7300" },
+  { PCI_CHIP_R520_710F, "ATI FireGL V7350" },
+  { PCI_CHIP_RV515_7140, "ATI Radeon X1600" },
+  { PCI_CHIP_RV515_7141, "ATI RV505" },
+  { PCI_CHIP_RV515_7142, "ATI Radeon X1300/X1550" },
+  { PCI_CHIP_RV515_7143, "ATI Radeon X1550" },
+  { PCI_CHIP_RV515_7144, "ATI M54-GL" },
+  { PCI_CHIP_RV515_7145, "ATI Mobility Radeon X1400" },
+  { PCI_CHIP_RV515_7146, "ATI Radeon X1300/X1550" },
+  { PCI_CHIP_RV515_7147, "ATI Radeon X1550 64-bit" },
+  { PCI_CHIP_RV515_7149, "ATI Mobility Radeon X1300" },
+  { PCI_CHIP_RV515_714A, "ATI Mobility Radeon X1300" },
+  { PCI_CHIP_RV515_714B, "ATI Mobility Radeon X1300" },
+  { PCI_CHIP_RV515_714C, "ATI Mobility Radeon X1300" },
+  { PCI_CHIP_RV515_714D, "ATI Radeon X1300" },
+  { PCI_CHIP_RV515_714E, "ATI Radeon X1300" },
+  { PCI_CHIP_RV515_714F, "ATI RV505" },
+  { PCI_CHIP_RV515_7151, "ATI RV505" },
+  { PCI_CHIP_RV515_7152, "ATI FireGL V3300" },
+  { PCI_CHIP_RV515_7153, "ATI FireGL V3350" },
+  { PCI_CHIP_RV515_715E, "ATI Radeon X1300" },
+  { PCI_CHIP_RV515_715F, "ATI Radeon X1550 64-bit" },
+  { PCI_CHIP_RV515_7180, "ATI Radeon X1300/X1550" },
+  { PCI_CHIP_RV515_7181, "ATI Radeon X1600" },
+  { PCI_CHIP_RV515_7183, "ATI Radeon X1300/X1550" },
+  { PCI_CHIP_RV515_7186, "ATI Mobility Radeon X1450" },
+  { PCI_CHIP_RV515_7187, "ATI Radeon X1300/X1550" },
+  { PCI_CHIP_RV515_7188, "ATI Mobility Radeon X2300" },
+  { PCI_CHIP_RV515_718A, "ATI Mobility Radeon X2300" },
+  { PCI_CHIP_RV515_718B, "ATI Mobility Radeon X1350" },
+  { PCI_CHIP_RV515_718C, "ATI Mobility Radeon X1350" },
+  { PCI_CHIP_RV515_718D, "ATI Mobility Radeon X1450" },
+  { PCI_CHIP_RV515_718F, "ATI Radeon X1300" },
+  { PCI_CHIP_RV515_7193, "ATI Radeon X1550" },
+  { PCI_CHIP_RV515_7196, "ATI Mobility Radeon X1350" },
+  { PCI_CHIP_RV515_719B, "ATI FireMV 2250" },
+  { PCI_CHIP_RV515_719F, "ATI Radeon X1550 64-bit" },
+  { PCI_CHIP_RV530_71C0, "ATI Radeon X1600" },
+  { PCI_CHIP_RV530_71C1, "ATI Radeon X1650" },
+  { PCI_CHIP_RV530_71C2, "ATI Radeon X1600" },
+  { PCI_CHIP_RV530_71C3, "ATI Radeon X1600" },
+  { PCI_CHIP_RV530_71C4, "ATI Mobility FireGL V5200" },
+  { PCI_CHIP_RV530_71C5, "ATI Mobility Radeon X1600" },
+  { PCI_CHIP_RV530_71C6, "ATI Radeon X1650" },
+  { PCI_CHIP_RV530_71C7, "ATI Radeon X1650" },
+  { PCI_CHIP_RV530_71CD, "ATI Radeon X1600" },
+  { PCI_CHIP_RV530_71CE, "ATI Radeon X1300 XT/X1600 Pro" },
+  { PCI_CHIP_RV530_71D2, "ATI FireGL V3400" },
+  { PCI_CHIP_RV530_71D4, "ATI Mobility FireGL V5250" },
+  { PCI_CHIP_RV530_71D5, "ATI Mobility Radeon X1700" },
+  { PCI_CHIP_RV530_71D6, "ATI Mobility Radeon X1700 XT" },
+  { PCI_CHIP_RV530_71DA, "ATI FireGL V5200" },
+  { PCI_CHIP_RV530_71DE, "ATI Mobility Radeon X1700" },
+  { PCI_CHIP_RV530_7200, "ATI  Radeon X2300HD" },
+  { PCI_CHIP_RV530_7210, "ATI Mobility Radeon HD 2300" },
+  { PCI_CHIP_RV530_7211, "ATI Mobility Radeon HD 2300" },
+  { PCI_CHIP_R580_7240, "ATI Radeon X1950" },
+  { PCI_CHIP_R580_7243, "ATI Radeon X1900" },
+  { PCI_CHIP_R580_7244, "ATI Radeon X1950" },
+  { PCI_CHIP_R580_7245, "ATI Radeon X1900" },
+  { PCI_CHIP_R580_7246, "ATI Radeon X1900" },
+  { PCI_CHIP_R580_7247, "ATI Radeon X1900" },
+  { PCI_CHIP_R580_7248, "ATI Radeon X1900" },
+  { PCI_CHIP_R580_7249, "ATI Radeon X1900" },
+  { PCI_CHIP_R580_724A, "ATI Radeon X1900" },
+  { PCI_CHIP_R580_724B, "ATI Radeon X1900" },
+  { PCI_CHIP_R580_724C, "ATI Radeon X1900" },
+  { PCI_CHIP_R580_724D, "ATI Radeon X1900" },
+  { PCI_CHIP_R580_724E, "ATI AMD Stream Processor" },
+  { PCI_CHIP_R580_724F, "ATI Radeon X1900" },
+  { PCI_CHIP_RV570_7280, "ATI Radeon X1950" },
+  { PCI_CHIP_RV560_7281, "ATI RV560" },
+  { PCI_CHIP_RV560_7283, "ATI RV560" },
+  { PCI_CHIP_R580_7284, "ATI Mobility Radeon X1900" },
+  { PCI_CHIP_RV560_7287, "ATI RV560" },
+  { PCI_CHIP_RV570_7288, "ATI Radeon X1950 GT" },
+  { PCI_CHIP_RV570_7289, "ATI RV570" },
+  { PCI_CHIP_RV570_728B, "ATI RV570" },
+  { PCI_CHIP_RV570_728C, "ATI ATI FireGL V7400" },
+  { PCI_CHIP_RV560_7290, "ATI RV560" },
+  { PCI_CHIP_RV560_7291, "ATI Radeon X1650" },
+  { PCI_CHIP_RV560_7293, "ATI Radeon X1650" },
+  { PCI_CHIP_RV560_7297, "ATI RV560" },
   { PCI_CHIP_RS350_7834, "ATI Radeon 9100 PRO IGP 7834" },
   { PCI_CHIP_RS350_7835, "ATI Radeon Mobility 9200 IGP 7835" },
+  { PCI_CHIP_RS690_791E, "ATI Radeon X1200" },
+  { PCI_CHIP_RS690_791F, "ATI Radeon X1200" },
+  { PCI_CHIP_RS740_796C, "ATI RS740" },
+  { PCI_CHIP_RS740_796D, "ATI RS740M" },
+  { PCI_CHIP_RS740_796E, "ATI RS740" },
+  { PCI_CHIP_RS740_796F, "ATI RS740M" },
+  { PCI_CHIP_R600_9400, "ATI Radeon HD 2900 XT" },
+  { PCI_CHIP_R600_9401, "ATI Radeon HD 2900 XT" },
+  { PCI_CHIP_R600_9402, "ATI Radeon HD 2900 XT" },
+  { PCI_CHIP_R600_9403, "ATI Radeon HD 2900 Pro" },
+  { PCI_CHIP_R600_9405, "ATI Radeon HD 2900 GT" },
+  { PCI_CHIP_R600_940A, "ATI FireGL V8650" },
+  { PCI_CHIP_R600_940B, "ATI FireGL V8600" },
+  { PCI_CHIP_R600_940F, "ATI FireGL V7600" },
+  { PCI_CHIP_RV610_94C0, "ATI RV610" },
+  { PCI_CHIP_RV610_94C1, "ATI Radeon HD 2400 XT" },
+  { PCI_CHIP_RV610_94C3, "ATI Radeon HD 2400 Pro" },
+  { PCI_CHIP_RV610_94C4, "ATI ATI Radeon HD 2400 PRO AGP" },
+  { PCI_CHIP_RV610_94C5, "ATI FireGL V4000" },
+  { PCI_CHIP_RV610_94C6, "ATI RV610" },
+  { PCI_CHIP_RV610_94C7, "ATI ATI Radeon HD 2350" },
+  { PCI_CHIP_RV610_94C8, "ATI Mobility Radeon HD 2400 XT" },
+  { PCI_CHIP_RV610_94C9, "ATI Mobility Radeon HD 2400" },
+  { PCI_CHIP_RV610_94CB, "ATI ATI RADEON E2400" },
+  { PCI_CHIP_RV610_94CC, "ATI RV610" },
+  { PCI_CHIP_RV630_9580, "ATI RV630" },
+  { PCI_CHIP_RV630_9581, "ATI Mobility Radeon HD 2600" },
+  { PCI_CHIP_RV630_9583, "ATI Mobility Radeon HD 2600 XT" },
+  { PCI_CHIP_RV630_9586, "ATI ATI Radeon HD 2600 XT AGP" },
+  { PCI_CHIP_RV630_9587, "ATI ATI Radeon HD 2600 Pro AGP" },
+  { PCI_CHIP_RV630_9588, "ATI Radeon HD 2600 XT" },
+  { PCI_CHIP_RV630_9589, "ATI Radeon HD 2600 Pro" },
+  { PCI_CHIP_RV630_958A, "ATI Gemini RV630" },
+  { PCI_CHIP_RV630_958B, "ATI Gemini ATI Mobility Radeon HD 2600 XT" },
+  { PCI_CHIP_RV630_958C, "ATI FireGL V5600" },
+  { PCI_CHIP_RV630_958D, "ATI FireGL V3600" },
+  { PCI_CHIP_RV630_958E, "ATI ATI Radeon HD 2600 LE" },
   { -1,                 NULL }
 };
diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c
index a1802f8..53bbce9 100644
--- a/src/radeon_commonfuncs.c
+++ b/src/radeon_commonfuncs.c
@@ -57,8 +57,140 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 
     info->texW[0] = info->texH[0] = info->texW[1] = info->texH[1] = 1;
 
-    if (info->ChipFamily >= CHIP_FAMILY_R300) {
-	/* Unimplemented */
+    if (IS_R300_VARIANT) {
+	BEGIN_ACCEL(3);
+	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA);
+	OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, 0x3);
+	OUT_ACCEL_REG(R300_WAIT_UNTIL, 0x30000);
+	FINISH_ACCEL();
+
+	BEGIN_ACCEL(3);
+	OUT_ACCEL_REG(R300_GB_TILE_CONFIG, 0x10011);
+	OUT_ACCEL_REG(R300_GB_SELECT,0x0);
+	OUT_ACCEL_REG(R300_GB_ENABLE, 0x0);
+	FINISH_ACCEL();
+
+	BEGIN_ACCEL(3);
+	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA);
+	OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, 0x3);
+	OUT_ACCEL_REG(R300_WAIT_UNTIL, 0x30000);
+	FINISH_ACCEL();
+
+	BEGIN_ACCEL(5);
+	OUT_ACCEL_REG(R300_GB_AA_CONFIG, 0x0);
+	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA);
+	OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, 0x3);
+	OUT_ACCEL_REG(R300_GB_MSPOS0, 0x78888888);
+	OUT_ACCEL_REG(R300_GB_MSPOS1, 0x08888888);
+	FINISH_ACCEL();
+
+	BEGIN_ACCEL(4);
+	OUT_ACCEL_REG(R300_GA_POLY_MODE, 0x120);
+	OUT_ACCEL_REG(R300_GA_ROUND_MODE, 0x5);
+	OUT_ACCEL_REG(R300_GA_COLOR_CONTROL, 0xAAAA);
+	OUT_ACCEL_REG(R300_GA_OFFSET, 0x0);
+	FINISH_ACCEL();
+
+	BEGIN_ACCEL(26);
+	OUT_ACCEL_REG(R300_VAP_CNTL_STATUS, 0x0);
+	OUT_ACCEL_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0);
+	OUT_ACCEL_REG(R300_VAP_CNTL, 0x300456);
+	OUT_ACCEL_REG(R300_VAP_VTE_CNTL, 0x300);
+	OUT_ACCEL_REG(R300_VAP_PSC_SGN_NORM_CNTL, 0x0);
+	OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_0, 0x6a014001);
+	OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0, 0xf688f688);
+	OUT_ACCEL_REG(R300_VAP_PVS_CODE_CNTL_0, 0x100400);
+	OUT_ACCEL_REG(R300_VAP_PVS_CODE_CNTL_1, 0x1);
+	OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0);
+	OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,0x00f00203);
+	OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,0x00d10001);
+	OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,0x01248001);
+	OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,0x01248001);
+	OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,0x00f02203);
+	OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,0x00d10141);
+	OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,0x01248141);
+	OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,0x01248141);
+
+	OUT_ACCEL_REG(R300_VAP_PVS_FLOW_CNTL_OPC, 0x0);
+	OUT_ACCEL_REG(R300_VAP_OUT_VTX_FMT_0, 0x1);
+	OUT_ACCEL_REG(R300_VAP_OUT_VTX_FMT_1, 0x2);
+
+	OUT_ACCEL_REG(R300_VAP_GB_VERT_CLIP_ADJ, 0x3f800000);
+	OUT_ACCEL_REG(R300_VAP_GB_VERT_DISC_ADJ, 0x3f800000);
+	OUT_ACCEL_REG(R300_VAP_GB_HORZ_CLIP_ADJ, 0x3f800000);
+	OUT_ACCEL_REG(R300_VAP_GB_HORZ_DISC_ADJ, 0x3f800000);
+	OUT_ACCEL_REG(R300_VAP_CLIP_CNTL, 0x10000);
+	FINISH_ACCEL();
+
+	BEGIN_ACCEL(7);
+	OUT_ACCEL_REG(R300_SU_TEX_WRAP, 0x0);
+	OUT_ACCEL_REG(R300_SU_POLY_OFFSET_ENABLE, 0x0);
+	OUT_ACCEL_REG(R300_SU_CULL_MODE, 0x4);
+	OUT_ACCEL_REG(R300_SU_DEPTH_SCALE, 0x4b7fffff);
+	OUT_ACCEL_REG(R300_SU_DEPTH_OFFSET, 0x0);
+	OUT_ACCEL_REG(R300_RS_COUNT, 0x40002);
+	OUT_ACCEL_REG(R300_RS_IP_0, 0x1610000);
+	FINISH_ACCEL();
+
+	BEGIN_ACCEL(5);
+	OUT_ACCEL_REG(R300_US_W_FMT, 0x0);
+	OUT_ACCEL_REG(R300_US_OUT_FMT_1, 0x1B0F);
+	OUT_ACCEL_REG(R300_US_OUT_FMT_2, 0x1B0F);
+	OUT_ACCEL_REG(R300_US_OUT_FMT_3, 0x1B0F);
+	OUT_ACCEL_REG(R300_US_OUT_FMT_0, 0x1B01);
+	FINISH_ACCEL();
+
+	BEGIN_ACCEL(2);
+	OUT_ACCEL_REG(R300_RS_INST_COUNT, 0xC0);
+	OUT_ACCEL_REG(R300_RS_INST_0, 0x8);
+	FINISH_ACCEL();
+
+	BEGIN_ACCEL(12);
+	OUT_ACCEL_REG(R300_US_CONFIG, 0x8);
+	OUT_ACCEL_REG(R300_US_PIXSIZE, 0x0);
+	OUT_ACCEL_REG(R300_US_CODE_OFFSET, 0x40040);
+	OUT_ACCEL_REG(R300_US_CODE_ADDR_0, 0x0);
+	OUT_ACCEL_REG(R300_US_CODE_ADDR_1, 0x0);
+	OUT_ACCEL_REG(R300_US_CODE_ADDR_2, 0x0);
+	OUT_ACCEL_REG(R300_US_CODE_ADDR_3, 0x400000);
+	OUT_ACCEL_REG(R300_US_TEX_INST_0, 0x8000);
+	OUT_ACCEL_REG(R300_US_ALU_RGB_ADDR_0, 0x1f800000);
+	OUT_ACCEL_REG(R300_US_ALU_RGB_INST_0, 0x50a80);
+	OUT_ACCEL_REG(R300_US_ALU_ALPHA_ADDR_0, 0x1800000);
+	OUT_ACCEL_REG(R300_US_ALU_ALPHA_INST_0, 0x00040889);
+	FINISH_ACCEL();
+
+	BEGIN_ACCEL(3);
+	OUT_ACCEL_REG(R300_FG_DEPTH_SRC, 0x0);
+	OUT_ACCEL_REG(R300_FG_FOG_BLEND, 0x0);
+	OUT_ACCEL_REG(R300_FG_ALPHA_FUNC, 0x0);
+	FINISH_ACCEL();
+
+	BEGIN_ACCEL(12);
+	OUT_ACCEL_REG(R300_RB3D_ZSTENCILCNTL, 0x0);
+	OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, 0x3);
+	OUT_ACCEL_REG(R300_RB3D_BW_CNTL, 0x0);
+	OUT_ACCEL_REG(R300_RB3D_ZCNTL, 0x0);
+	OUT_ACCEL_REG(R300_RB3D_ZTOP, 0x0);
+	OUT_ACCEL_REG(R300_RB3D_ROPCNTL, 0x0);
+
+	OUT_ACCEL_REG(R300_RB3D_AARESOLVE_CTL, 0x0);
+	OUT_ACCEL_REG(R300_RB3D_COLOR_CHANNEL_MASK, 0xf);
+	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA);
+	OUT_ACCEL_REG(R300_RB3D_CCTL, 0x0);
+	OUT_ACCEL_REG(R300_RB3D_DITHER_CTL, 0x0);
+	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA);
+	FINISH_ACCEL();
+
+	BEGIN_ACCEL(7);
+	OUT_ACCEL_REG(R300_SC_EDGERULE, 0xA5294A5);
+	OUT_ACCEL_REG(R300_SC_SCISSOR0, 0x0);
+	OUT_ACCEL_REG(R300_SC_SCISSOR1, 0x3ffffff);
+	OUT_ACCEL_REG(R300_SC_CLIP_0_A, 0x880440);
+	OUT_ACCEL_REG(R300_SC_CLIP_0_B, 0xff0ff0);
+	OUT_ACCEL_REG(R300_SC_CLIP_RULE, 0xAAAA);
+	OUT_ACCEL_REG(R300_SC_SCREENDOOR, 0xffffff);
+	FINISH_ACCEL();
     } else if ((info->ChipFamily == CHIP_FAMILY_RV250) || 
 	       (info->ChipFamily == CHIP_FAMILY_RV280) || 
 	       (info->ChipFamily == CHIP_FAMILY_RS300) || 
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 07857dd..e1e4550 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -53,57 +53,27 @@
 #include "sarea.h"
 #endif
 
-void radeon_crtc_load_lut(xf86CrtcPtr crtc);
+extern void atombios_crtc_mode_set(xf86CrtcPtr crtc,
+				   DisplayModePtr mode,
+				   DisplayModePtr adjusted_mode,
+				   int x, int y);
+extern void legacy_crtc_mode_set(xf86CrtcPtr crtc,
+				 DisplayModePtr mode,
+				 DisplayModePtr adjusted_mode,
+				 int x, int y);
+extern void atombios_crtc_dpms(xf86CrtcPtr crtc, int mode);
+extern void legacy_crtc_dpms(xf86CrtcPtr crtc, int mode);
 
 static void
 radeon_crtc_dpms(xf86CrtcPtr crtc, int mode)
 {
-    int mask;
-    ScrnInfoPtr pScrn = crtc->scrn;
-    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    
-    mask = radeon_crtc->crtc_id ? (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_REQ_EN_B) : (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS);
-
+    RADEONInfoPtr info = RADEONPTR(crtc->scrn);
 
-    switch(mode) {
-    case DPMSModeOn:
-	if (radeon_crtc->crtc_id) {
-	    OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask);
-	} else {
-	    OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
-	    OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask);
-	}
-	break;
-    case DPMSModeStandby:
-	if (radeon_crtc->crtc_id) {
-	    OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), ~mask);
-	} else {
-	    OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
-	    OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS), ~mask);
-	}
-	break;
-    case DPMSModeSuspend:
-	if (radeon_crtc->crtc_id) {
-	    OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), ~mask);
-	} else {
-	    OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
-	    OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS), ~mask);
-	}
-	break;
-    case DPMSModeOff:
-	if (radeon_crtc->crtc_id) {
-	    OUTREGP(RADEON_CRTC2_GEN_CNTL, mask, ~mask);
-	} else {
-	    OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~RADEON_CRTC_DISP_REQ_EN_B);
-	    OUTREGP(RADEON_CRTC_EXT_CNTL, mask, ~mask);
-	}
-	break;
+    if (IS_AVIVO_VARIANT) {
+	atombios_crtc_dpms(crtc, mode);
+    } else {
+	legacy_crtc_dpms(crtc, mode);
     }
-  
-    if (mode != DPMSModeOff)
-	radeon_crtc_load_lut(crtc);
 }
 
 static Bool
@@ -119,497 +89,12 @@ radeon_crtc_mode_prepare(xf86CrtcPtr crtc)
     radeon_crtc_dpms(crtc, DPMSModeOff);
 }
 
-/* Define common registers for requested video mode */
-static void
-RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info)
-{
-    save->ovr_clr            = 0;
-    save->ovr_wid_left_right = 0;
-    save->ovr_wid_top_bottom = 0;
-    save->ov0_scale_cntl     = 0;
-    save->subpic_cntl        = 0;
-    save->viph_control       = 0;
-    save->i2c_cntl_1         = 0;
-    save->rbbm_soft_reset    = 0;
-    save->cap0_trig_cntl     = 0;
-    save->cap1_trig_cntl     = 0;
-    save->bus_cntl           = info->BusCntl;
-    /*
-     * If bursts are enabled, turn on discards
-     * Radeon doesn't have write bursts
-     */
-    if (save->bus_cntl & (RADEON_BUS_READ_BURST))
-	save->bus_cntl |= RADEON_BUS_RD_DISCARD_EN;
-}
-
-static void
-RADEONInitSurfaceCntl(xf86CrtcPtr crtc, RADEONSavePtr save)
-{
-    save->surface_cntl = 0;
-
-#if X_BYTE_ORDER == X_BIG_ENDIAN
-    /* We must set both apertures as they can be both used to map the entire
-     * video memory. -BenH.
-     */
-    switch (crtc->scrn->bitsPerPixel) {
-    case 16:
-	save->surface_cntl |= RADEON_NONSURF_AP0_SWP_16BPP;
-	save->surface_cntl |= RADEON_NONSURF_AP1_SWP_16BPP;
-	break;
-
-    case 32:
-	save->surface_cntl |= RADEON_NONSURF_AP0_SWP_32BPP;
-	save->surface_cntl |= RADEON_NONSURF_AP1_SWP_32BPP;
-	break;
-    }
-#endif
-
-}
-
-static Bool
-RADEONInitCrtcBase(xf86CrtcPtr crtc, RADEONSavePtr save,
-		   int x, int y)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    int    Base;
-#ifdef XF86DRI
-    RADEONSAREAPrivPtr pSAREAPriv;
-    XF86DRISAREAPtr pSAREA;
-#endif
-
-    save->crtc_offset      = pScrn->fbOffset;
-#ifdef XF86DRI
-    if (info->allowPageFlip)
-	save->crtc_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
-    else
-#endif
-	save->crtc_offset_cntl = 0;
-
-    if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
-       if (IS_R300_VARIANT)
-          save->crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
-				     R300_CRTC_MICRO_TILE_BUFFER_DIS |
-				     R300_CRTC_MACRO_TILE_EN);
-       else
-          save->crtc_offset_cntl |= RADEON_CRTC_TILE_EN;
-    }
-    else {
-       if (IS_R300_VARIANT)
-          save->crtc_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
-				      R300_CRTC_MICRO_TILE_BUFFER_DIS |
-				      R300_CRTC_MACRO_TILE_EN);
-       else
-          save->crtc_offset_cntl &= ~RADEON_CRTC_TILE_EN;
-    }
-
-    Base = pScrn->fbOffset;
-
-    if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
-        if (IS_R300_VARIANT) {
-	/* On r300/r400 when tiling is enabled crtc_offset is set to the address of
-	 * the surface.  the x/y offsets are handled by the X_Y tile reg for each crtc
-	 * Makes tiling MUCH easier.
-	 */
-             save->crtc_tile_x0_y0 = x | (y << 16);
-             Base &= ~0x7ff;
-         } else {
-	     /* note we cannot really simply use the info->ModeReg.crtc_offset_cntl value, since the
-		drm might have set FLIP_CNTL since we wrote that. Unfortunately FLIP_CNTL causes
-		flickering when scrolling vertically in a virtual screen, possibly because crtc will
-		pick up the new offset value at the end of each scanline, but the new offset_cntl value
-		only after a vsync. We'd probably need to wait (in drm) for vsync and only then update
-		OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */
-	     /*save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL) & ~0xf;*/
-#if 0
-	     /* try to get rid of flickering when scrolling at least for 2d */
-#ifdef XF86DRI
-	     if (!info->have3DWindows)
-#endif
-		 save->crtc_offset_cntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
-#endif
-	     
-             int byteshift = info->CurrentLayout.bitsPerPixel >> 4;
-             /* crtc uses 256(bytes)x8 "half-tile" start addresses? */
-             int tile_addr = (((y >> 3) * info->CurrentLayout.displayWidth + x) >> (8 - byteshift)) << 11;
-             Base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
-             save->crtc_offset_cntl = save->crtc_offset_cntl | (y % 16);
-         }
-    }
-    else {
-       int offset = y * info->CurrentLayout.displayWidth + x;
-       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 */
-
-
-#ifdef XF86DRI
-    if (info->directRenderingInited) {
-	/* note cannot use pScrn->pScreen since this is unitialized when called from
-	   RADEONScreenInit, and we need to call from there to get mergedfb + pageflip working */
-        /*** NOTE: r3/4xx will need sarea and drm pageflip updates to handle the xytile regs for
-	 *** pageflipping!
-	 ***/
-	pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
-	/* can't get at sarea in a semi-sane way? */
-	pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
-
-	pSAREA->frame.x = (Base  / info->CurrentLayout.pixel_bytes)
-	    % info->CurrentLayout.displayWidth;
-	pSAREA->frame.y = (Base / info->CurrentLayout.pixel_bytes)
-	    / info->CurrentLayout.displayWidth;
-	pSAREA->frame.width = pScrn->frameX1 - x + 1;
-	pSAREA->frame.height = pScrn->frameY1 - y + 1;
-
-	if (pSAREAPriv->pfCurrentPage == 1) {
-	    Base += info->backOffset - info->frontOffset;
-	}
-    }
-#endif
-    save->crtc_offset = Base;
-
-    return TRUE;
-
-}
-
-/* Define CRTC registers for requested video mode */
-static Bool
-RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save,
-			DisplayModePtr mode)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    int    format;
-    int    hsync_start;
-    int    hsync_wid;
-    int    vsync_wid;
-
-    switch (info->CurrentLayout.pixel_code) {
-    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;
-    }
-
-    /*save->bios_4_scratch = info->SavedReg.bios_4_scratch;*/
-    save->crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN
-			   | RADEON_CRTC_EN
-			   | (format << 8)
-			   | ((mode->Flags & V_DBLSCAN)
-			      ? RADEON_CRTC_DBL_SCAN_EN
-			      : 0)
-			   | ((mode->Flags & V_CSYNC)
-			      ? RADEON_CRTC_CSYNC_EN
-			      : 0)
-			   | ((mode->Flags & V_INTERLACE)
-			      ? RADEON_CRTC_INTERLACE_EN
-			      : 0));
-
-    save->crtc_ext_cntl |= (RADEON_XCRT_CNT_EN|
-			    RADEON_CRTC_VSYNC_DIS |
-			    RADEON_CRTC_HSYNC_DIS |
-			    RADEON_CRTC_DISPLAY_DIS);
-
-    save->disp_merge_cntl = info->SavedReg.disp_merge_cntl;
-    save->disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
-
-    save->crtc_more_cntl = 0;
-    if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
-        (info->ChipFamily == CHIP_FAMILY_RS200)) {
-        /* This is to workaround the asic bug for RMX, some versions
-           of BIOS dosen't have this register initialized correctly.
-	*/
-        save->crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN;
-    }
-
-    save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
-			       | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff)
-				  << 16));
-
-    hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
-    if (!hsync_wid)       hsync_wid = 1;
-    hsync_start = mode->CrtcHSyncStart - 8;
-
-    save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff)
-				  | ((hsync_wid & 0x3f) << 16)
-				  | ((mode->Flags & V_NHSYNC)
-				     ? RADEON_CRTC_H_SYNC_POL
-				     : 0));
-
-				/* This works for double scan mode. */
-    save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
-			       | ((mode->CrtcVDisplay - 1) << 16));
-
-    vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
-    if (!vsync_wid)       vsync_wid = 1;
-
-    save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
-				  | ((vsync_wid & 0x1f) << 16)
-				  | ((mode->Flags & V_NVSYNC)
-				     ? RADEON_CRTC_V_SYNC_POL
-				     : 0));
-
-    save->crtc_pitch  = (((pScrn->displayWidth * pScrn->bitsPerPixel) +
-			  ((pScrn->bitsPerPixel * 8) -1)) /
-			 (pScrn->bitsPerPixel * 8));
-    save->crtc_pitch |= save->crtc_pitch << 16;
-    
-    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_crtc_h_total_disp = save->crtc_h_total_disp;
-    save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
-
-    if (info->IsDellServer) {
-	save->dac2_cntl = info->SavedReg.dac2_cntl;
-	save->tv_dac_cntl = info->SavedReg.tv_dac_cntl;
-	save->crtc2_gen_cntl = info->SavedReg.crtc2_gen_cntl;
-	save->disp_hw_debug = info->SavedReg.disp_hw_debug;
-
-	save->dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL;
-	save->dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
-
-	/* For CRT on DAC2, don't turn it on if BIOS didn't
-	   enable it, even it's detected.
-	*/
-	save->disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
-	save->tv_dac_cntl &= ~((1<<2) | (3<<8) | (7<<24) | (0xff<<16));
-	save->tv_dac_cntl |= (0x03 | (2<<8) | (0x58<<16));
-    }
-
-    return TRUE;
-}
-
-static Bool
-RADEONInitCrtc2Base(xf86CrtcPtr crtc, RADEONSavePtr save,
-		    int x, int y)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    int    Base;
-#ifdef XF86DRI
-    RADEONSAREAPrivPtr pSAREAPriv;
-    XF86DRISAREAPtr pSAREA;
-#endif
-
-    /* It seems all fancy options apart from pflip can be safely disabled
-     */
-    save->crtc2_offset      = pScrn->fbOffset;
-#ifdef XF86DRI
-    if (info->allowPageFlip)
-	save->crtc2_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
-    else
-#endif
-	save->crtc2_offset_cntl = 0;
-
-    if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
-       if (IS_R300_VARIANT)
-          save->crtc2_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
-				      R300_CRTC_MICRO_TILE_BUFFER_DIS |
-				      R300_CRTC_MACRO_TILE_EN);
-       else
-          save->crtc2_offset_cntl |= RADEON_CRTC_TILE_EN;
-    }
-    else {
-       if (IS_R300_VARIANT)
-          save->crtc2_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
-				      R300_CRTC_MICRO_TILE_BUFFER_DIS |
-				      R300_CRTC_MACRO_TILE_EN);
-       else
-          save->crtc2_offset_cntl &= ~RADEON_CRTC_TILE_EN;
-    }
-
-    Base = pScrn->fbOffset;
-
-    if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
-        if (IS_R300_VARIANT) {
-	/* On r300/r400 when tiling is enabled crtc_offset is set to the address of
-	 * the surface.  the x/y offsets are handled by the X_Y tile reg for each crtc
-	 * Makes tiling MUCH easier.
-	 */
-             save->crtc2_tile_x0_y0 = x | (y << 16);
-             Base &= ~0x7ff;
-         } else {
-	     /* note we cannot really simply use the info->ModeReg.crtc_offset_cntl value, since the
-		drm might have set FLIP_CNTL since we wrote that. Unfortunately FLIP_CNTL causes
-		flickering when scrolling vertically in a virtual screen, possibly because crtc will
-		pick up the new offset value at the end of each scanline, but the new offset_cntl value
-		only after a vsync. We'd probably need to wait (in drm) for vsync and only then update
-		OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */
-	     /*save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL) & ~0xf;*/
-#if 0
-	     /* try to get rid of flickering when scrolling at least for 2d */
-#ifdef XF86DRI
-	     if (!info->have3DWindows)
-#endif
-		 save->crtc2_offset_cntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
-#endif
-
-             int byteshift = info->CurrentLayout.bitsPerPixel >> 4;
-             /* crtc uses 256(bytes)x8 "half-tile" start addresses? */
-             int tile_addr = (((y >> 3) * info->CurrentLayout.displayWidth + x) >> (8 - byteshift)) << 11;
-             Base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
-             save->crtc2_offset_cntl = save->crtc_offset_cntl | (y % 16);
-         }
-    }
-    else {
-       int offset = y * info->CurrentLayout.displayWidth + x;
-       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 */
-
-#ifdef XF86DRI
-    if (info->directRenderingInited) {
-	/* note cannot use pScrn->pScreen since this is unitialized when called from
-	   RADEONScreenInit, and we need to call from there to get mergedfb + pageflip working */
-        /*** NOTE: r3/4xx will need sarea and drm pageflip updates to handle the xytile regs for
-	 *** pageflipping!
-	 ***/
-	pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
-	/* can't get at sarea in a semi-sane way? */
-	pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
-
-	pSAREAPriv->crtc2_base = Base;
-
-	if (pSAREAPriv->pfCurrentPage == 1) {
-	    Base += info->backOffset - info->frontOffset;
-	}
-    }
-#endif
-    save->crtc2_offset = Base;
-
-    return TRUE;
-}
-
-/* Define CRTC2 registers for requested video mode */
-static Bool
-RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save,
-			 DisplayModePtr mode)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    int    format;
-    int    hsync_start;
-    int    hsync_wid;
-    int    vsync_wid;
-
-    switch (info->CurrentLayout.pixel_code) {
-    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;
-    }
-
-    save->crtc2_h_total_disp =
-	((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
-	 | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff) << 16));
-
-    hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
-    if (!hsync_wid)       hsync_wid = 1;
-    hsync_start = mode->CrtcHSyncStart - 8;
-
-    save->crtc2_h_sync_strt_wid = ((hsync_start & 0x1fff)
-				   | ((hsync_wid & 0x3f) << 16)
-				   | ((mode->Flags & V_NHSYNC)
-				      ? RADEON_CRTC_H_SYNC_POL
-				      : 0));
-
-				/* This works for double scan mode. */
-    save->crtc2_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
-				| ((mode->CrtcVDisplay - 1) << 16));
-
-    vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
-    if (!vsync_wid)       vsync_wid = 1;
-
-    save->crtc2_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
-				   | ((vsync_wid & 0x1f) << 16)
-				   | ((mode->Flags & V_NVSYNC)
-				      ? RADEON_CRTC2_V_SYNC_POL
-				      : 0));
-
-    save->crtc2_pitch  = ((pScrn->displayWidth * pScrn->bitsPerPixel) +
-			  ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8);
-    save->crtc2_pitch |= save->crtc2_pitch << 16;
-
-    /* check to see if TV DAC is enabled for another crtc and keep it enabled */
-    if (save->crtc2_gen_cntl & RADEON_CRTC2_CRT2_ON)
-	save->crtc2_gen_cntl = RADEON_CRTC2_CRT2_ON;
-    else
-	save->crtc2_gen_cntl = 0;
-
-    save->crtc2_gen_cntl |= (RADEON_CRTC2_EN
-			     | (format << 8)
-			     | RADEON_CRTC2_VSYNC_DIS
-			     | RADEON_CRTC2_HSYNC_DIS
-			     | RADEON_CRTC2_DISP_DIS
-			     | ((mode->Flags & V_DBLSCAN)
-				? RADEON_CRTC2_DBL_SCAN_EN
-				: 0)
-			     | ((mode->Flags & V_CSYNC)
-				? RADEON_CRTC2_CSYNC_EN
-				: 0)
-			     | ((mode->Flags & V_INTERLACE)
-				? RADEON_CRTC2_INTERLACE_EN
-				: 0));
-
-    save->disp2_merge_cntl = info->SavedReg.disp2_merge_cntl;
-    save->disp2_merge_cntl &= ~(RADEON_DISP2_RGB_OFFSET_EN);
-
-    save->fp_h2_sync_strt_wid = save->crtc2_h_sync_strt_wid;
-    save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;
-
-    if (info->ChipFamily == CHIP_FAMILY_RS400) {
-	save->rs480_unk_e30 = 0x105DC1CC; /* because I'm worth it */
-	save->rs480_unk_e34 = 0x2749D000; /* AMD really should */
-	save->rs480_unk_e38 = 0x29ca71dc; /* release docs */
-	save->rs480_unk_e3c = 0x28FBC3AC; /* this is so a trade secret */
-    }
-
-    return TRUE;
-}
-
-
-static int RADEONDiv(int n, int d)
+static CARD32 RADEONDiv(CARD64 n, CARD32 d)
 {
     return (n + (d / 2)) / d;
 }
 
-static void
+void
 RADEONComputePLL(RADEONPLLPtr pll,
 		 unsigned long freq,
 		 CARD32 *chosen_dot_clock_freq,
@@ -618,10 +103,6 @@ RADEONComputePLL(RADEONPLLPtr pll,
 		 CARD32 *chosen_post_div,
 		 int flags)
 {
-    int post_divs[] = {1, 2, 4, 8, 3, 6, 12, 0};
-
-    int i;
-
     CARD32 min_ref_div = pll->min_ref_div;
     CARD32 max_ref_div = pll->max_ref_div;
     CARD32 best_vco = pll->best_vco;
@@ -631,23 +112,33 @@ RADEONComputePLL(RADEONPLLPtr pll,
     CARD32 best_freq = 1;
     CARD32 best_error = 0xffffffff;
     CARD32 best_vco_diff = 1;
+    CARD32 post_div;
 
-    freq = freq / 10;
+    freq = freq * 1000;
 
     ErrorF("freq: %lu\n", freq);
 
     if (flags & RADEON_PLL_USE_REF_DIV)
 	min_ref_div = max_ref_div = pll->reference_div;
 
-    for (i = 0; post_divs[i]; i++) {
-	int post_div = post_divs[i];
+    for (post_div = pll->min_post_div; post_div <= pll->max_post_div; ++post_div) {
 	CARD32 ref_div;
-	CARD32 vco = freq * post_div;
+	CARD32 vco = (freq / 10000) * post_div;
 
 	if ((flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1))
 	    continue;
 
-	if (vco < pll->min_pll_freq || vco > pll->max_pll_freq)
+	/* legacy radeons only have a few post_divs */
+	if (flags & RADEON_PLL_LEGACY) {
+	    if ((post_div == 5) ||
+		(post_div == 7) ||
+		(post_div == 9) ||
+		(post_div == 10) ||
+		(post_div == 11))
+		continue;
+	}
+
+	if (vco < pll->pll_out_min || vco > pll->pll_out_max)
 	    continue;
 
 	for (ref_div = min_ref_div; ref_div <= max_ref_div; ++ref_div) {
@@ -657,21 +148,22 @@ RADEONComputePLL(RADEONPLLPtr pll,
 	    if (pll_in < pll->pll_in_min || pll_in > pll->pll_in_max)
 		continue;
 
-	    feedback_div = RADEONDiv(freq * ref_div * post_div,
-				     pll->reference_freq);
+	    feedback_div = RADEONDiv((CARD64)freq * ref_div * post_div,
+				     pll->reference_freq * 10000);
 
 	    if (feedback_div < pll->min_feedback_div || feedback_div > pll->max_feedback_div)
 		continue;
 
-	    current_freq = RADEONDiv(pll->reference_freq * feedback_div, 
+	    current_freq = RADEONDiv((CARD64)pll->reference_freq * 10000 * feedback_div,
 				     ref_div * post_div);
 
 	    error = abs(current_freq - freq);
 	    vco_diff = abs(vco - best_vco);
 
 	    if ((best_vco == 0 && error < best_error) ||
+		(ref_div == pll->reference_div) ||
 		(best_vco != 0 &&
-		 (error < best_error - 1000 ||
+		 (error < best_error - 100 ||
 		  (abs(error - best_error) < 100 && vco_diff < best_vco_diff )))) {
 		best_post_div = post_div;
 		best_ref_div = ref_div;
@@ -681,341 +173,34 @@ RADEONComputePLL(RADEONPLLPtr pll,
 		best_vco_diff = vco_diff;
 	    }
 	}
+	if (best_freq == freq)
+	    break;
     }
 
-    ErrorF("best_freq: %u\n", (unsigned)best_freq);
-    ErrorF("best_feedback_div: %u\n", (unsigned)best_feedback_div);
-    ErrorF("best_ref_div: %u\n", (unsigned)best_ref_div);
-    ErrorF("best_post_div: %u\n", (unsigned)best_post_div);
+    ErrorF("best_freq: %u\n", (unsigned int)best_freq);
+    ErrorF("best_feedback_div: %u\n", (unsigned int)best_feedback_div);
+    ErrorF("best_ref_div: %u\n", (unsigned int)best_ref_div);
+    ErrorF("best_post_div: %u\n", (unsigned int)best_post_div);
 
-    *chosen_dot_clock_freq = best_freq;
+    *chosen_dot_clock_freq = best_freq / 10000;
     *chosen_feedback_div = best_feedback_div;
     *chosen_reference_div = best_ref_div;
     *chosen_post_div = best_post_div;
 
 }
 
-/* Define PLL registers for requested video mode */
-static void
-RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
-		       RADEONPLLPtr pll, DisplayModePtr mode,
-		       int flags)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    CARD32 feedback_div = 0;
-    CARD32 reference_div = 0;
-    CARD32 post_divider = 0;
-    CARD32 freq = 0;
-
-    struct {
-	int divider;
-	int bitvalue;
-    } *post_div, post_divs[]   = {
-				/* From RAGE 128 VR/RAGE 128 GL Register
-				 * Reference Manual (Technical Reference
-				 * Manual P/N RRG-G04100-C Rev. 0.04), page
-				 * 3-17 (PLL_DIV_[3:0]).
-				 */
-	{  1, 0 },              /* VCLK_SRC                 */
-	{  2, 1 },              /* VCLK_SRC/2               */
-	{  4, 2 },              /* VCLK_SRC/4               */
-	{  8, 3 },              /* VCLK_SRC/8               */
-	{  3, 4 },              /* VCLK_SRC/3               */
-	{ 16, 5 },              /* VCLK_SRC/16              */
-	{  6, 6 },              /* VCLK_SRC/6               */
-	{ 12, 7 },              /* VCLK_SRC/12              */
-	{  0, 0 }
-    };
-
-
-    if ((flags & RADEON_PLL_USE_BIOS_DIVS) && info->UseBiosDividers) {
-       save->ppll_ref_div = info->RefDivider;
-       save->ppll_div_3   = info->FeedbackDivider | (info->PostDivider << 16);
-       save->htotal_cntl  = 0;
-       return;
-    }
-
-    RADEONComputePLL(pll, mode->Clock, &freq, &feedback_div, &reference_div, &post_divider, flags);
-
-    for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
-	if (post_div->divider == post_divider)
-	    break;
-    }
-
-    if (!post_div->divider) {
-	save->pll_output_freq = freq;
-	post_div = &post_divs[0];
-    }
-
-    save->dot_clock_freq = freq;
-    save->feedback_div   = feedback_div;
-    save->reference_div  = reference_div;
-    save->post_div       = post_divider;
-
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "dc=%u, of=%u, fd=%d, rd=%d, pd=%d\n",
-		   (unsigned)save->dot_clock_freq,
-		   (unsigned)save->pll_output_freq,
-		   save->feedback_div,
-		   save->reference_div,
-		   save->post_div);
-
-    save->ppll_ref_div   = save->reference_div;
-
-#if defined(__powerpc__)
-    /* apparently programming this otherwise causes a hang??? */
-    if (info->MacModel == RADEON_MAC_IBOOK)
-	save->ppll_div_3 = 0x000600ad;
-    else
-#endif
-    save->ppll_div_3     = (save->feedback_div | (post_div->bitvalue << 16));
-
-    save->htotal_cntl    = mode->HTotal & 0x7;
-
-    save->vclk_ecp_cntl  = (info->SavedReg.vclk_ecp_cntl &
-			    ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
-
-}
-
-/* Define PLL2 registers for requested video mode */
-static void
-RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
-			RADEONPLLPtr pll, DisplayModePtr mode,
-			int flags)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    CARD32 feedback_div = 0;
-    CARD32 reference_div = 0;
-    CARD32 post_divider = 0;
-    CARD32 freq = 0;
-
-    struct {
-	int divider;
-	int bitvalue;
-    } *post_div, post_divs[]   = {
-				/* From RAGE 128 VR/RAGE 128 GL Register
-				 * Reference Manual (Technical Reference
-				 * Manual P/N RRG-G04100-C Rev. 0.04), page
-				 * 3-17 (PLL_DIV_[3:0]).
-				 */
-	{  1, 0 },              /* VCLK_SRC                 */
-	{  2, 1 },              /* VCLK_SRC/2               */
-	{  4, 2 },              /* VCLK_SRC/4               */
-	{  8, 3 },              /* VCLK_SRC/8               */
-	{  3, 4 },              /* VCLK_SRC/3               */
-	{  6, 6 },              /* VCLK_SRC/6               */
-	{ 12, 7 },              /* VCLK_SRC/12              */
-	{  0, 0 }
-    };
-
-    if ((flags & RADEON_PLL_USE_BIOS_DIVS) && info->UseBiosDividers) {
-       save->p2pll_ref_div = info->RefDivider;
-       save->p2pll_div_0   = info->FeedbackDivider | (info->PostDivider << 16);
-       save->htotal_cntl2  = 0;
-       return;
-    }
-
-    RADEONComputePLL(pll, mode->Clock, &freq, &feedback_div, &reference_div, &post_divider, flags);
-
-    for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
-	if (post_div->divider == post_divider)
-	    break;
-    }
-
-    if (!post_div->divider) {
-	save->pll_output_freq_2 = freq;
-	post_div = &post_divs[0];
-    }
-
-    save->dot_clock_freq_2 = freq;
-    save->feedback_div_2   = feedback_div;
-    save->reference_div_2  = reference_div;
-    save->post_div_2       = post_divider;
-
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "dc=%u, of=%u, fd=%d, rd=%d, pd=%d\n",
-		   (unsigned)save->dot_clock_freq_2,
-		   (unsigned)save->pll_output_freq_2,
-		   save->feedback_div_2,
-		   save->reference_div_2,
-		   save->post_div_2);
-
-    save->p2pll_ref_div    = save->reference_div_2;
-
-    save->p2pll_div_0      = (save->feedback_div_2 |
-			      (post_div->bitvalue << 16));
-
-    save->htotal_cntl2     = mode->HTotal & 0x7;
-
-    save->pixclks_cntl     = ((info->SavedReg.pixclks_cntl &
-			       ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
-			      RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
-
-}
-
-static void
-RADEONInitBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
-    RADEONInfoPtr  info      = RADEONPTR(pScrn);
-
-    /* tell the bios not to muck with the hardware on events */
-    save->bios_4_scratch = 0x4; /* 0x4 needed for backlight */
-    save->bios_5_scratch = (info->SavedReg.bios_5_scratch & 0xff) | 0xff00; /* bits 0-3 keep backlight level */
-    save->bios_6_scratch = info->SavedReg.bios_6_scratch | 0x40000000;
-
-}
-
-static void
-radeon_update_tv_routing(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
-    /* pixclks_cntl controls tv clock routing */
-    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, restore->pixclks_cntl);
-}
-
 static void
 radeon_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);
-    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     RADEONInfoPtr info = RADEONPTR(pScrn);
-    Bool           tilingOld   = info->tilingEnabled;
-    int i = 0;
-    double dot_clock = 0;
-    int pll_flags = 0;
-    Bool update_tv_routing = FALSE;
-
-
-    if (info->allowColorTiling) {
-	info->tilingEnabled = (adjusted_mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
-#ifdef XF86DRI
-	if (info->directRenderingEnabled && (info->tilingEnabled != tilingOld)) {
-	    RADEONSAREAPrivPtr pSAREAPriv;
-	    if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_SWITCH_TILING, (info->tilingEnabled ? 1 : 0)) < 0)
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "[drm] failed changing tiling status\n");
-	    /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
-	    pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
-	    info->tilingEnabled = pSAREAPriv->tiling_enabled ? TRUE : FALSE;
-	}
-#endif
-    }
-
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-	RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
-	if (output->crtc == crtc) {
-	    if (radeon_output->MonType != MT_CRT)
-		pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
-	    if (radeon_output->MonType == MT_LCD)
-		pll_flags |= (RADEON_PLL_USE_BIOS_DIVS | RADEON_PLL_USE_REF_DIV);
-	}
-    }
 
-    if (info->IsMobility)
-	RADEONInitBIOSRegisters(pScrn, &info->ModeReg);
-
-    ErrorF("init memmap\n");
-    RADEONInitMemMapRegisters(pScrn, &info->ModeReg, info);
-    ErrorF("init common\n");
-    RADEONInitCommonRegisters(&info->ModeReg, info);
-
-    RADEONInitSurfaceCntl(crtc, &info->ModeReg);
-
-    switch (radeon_crtc->crtc_id) {
-    case 0:
-	ErrorF("init crtc1\n");
-	RADEONInitCrtcRegisters(crtc, &info->ModeReg, adjusted_mode);
-	RADEONInitCrtcBase(crtc, &info->ModeReg, x, y);
-	dot_clock = adjusted_mode->Clock / 1000.0;
-	if (dot_clock) {
-	    ErrorF("init pll1\n");
-	    RADEONInitPLLRegisters(pScrn, &info->ModeReg, &info->pll, adjusted_mode, pll_flags);
-	} 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;
-	}
-	break;
-    case 1:
-	ErrorF("init crtc2\n");
-	RADEONInitCrtc2Registers(crtc, &info->ModeReg, adjusted_mode);
-	RADEONInitCrtc2Base(crtc, &info->ModeReg, x, y);
-	dot_clock = adjusted_mode->Clock / 1000.0;
-	if (dot_clock) {
-	    ErrorF("init pll2\n");
-	    RADEONInitPLL2Registers(pScrn, &info->ModeReg, &info->pll, adjusted_mode, pll_flags);
-	}
-	break;
-    }
-
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-	RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
-	if (output->crtc == crtc) {
-	    if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
-		switch (radeon_crtc->crtc_id) {
-		case 0:
-		    RADEONAdjustCrtcRegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
-		    RADEONAdjustPLLRegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
-		    update_tv_routing = TRUE;
-		    break;
-		case 1:
-		    RADEONAdjustCrtc2RegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
-		    RADEONAdjustPLL2RegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
-		    break;
-		}
-	    }
-	}
-    }
-
-    if (info->IsMobility)
-	RADEONRestoreBIOSRegisters(pScrn, &info->ModeReg);
-
-    ErrorF("restore memmap\n");
-    RADEONRestoreMemMapRegisters(pScrn, &info->ModeReg);
-    ErrorF("restore common\n");
-    RADEONRestoreCommonRegisters(pScrn, &info->ModeReg);
-
-    switch (radeon_crtc->crtc_id) {
-    case 0:
-	ErrorF("restore crtc1\n");
-	RADEONRestoreCrtcRegisters(pScrn, &info->ModeReg);
-	ErrorF("restore pll1\n");
-	RADEONRestorePLLRegisters(pScrn, &info->ModeReg);
-	break;
-    case 1:
-	ErrorF("restore crtc2\n");
-	RADEONRestoreCrtc2Registers(pScrn, &info->ModeReg);
-	ErrorF("restore pll2\n");
-	RADEONRestorePLL2Registers(pScrn, &info->ModeReg);
-	break;
-    }
-
-    /* pixclks_cntl handles tv-out clock routing */
-    if (update_tv_routing)
-	radeon_update_tv_routing(pScrn, &info->ModeReg);
-
-    if (info->DispPriority)
-        RADEONInitDispBandwidth(pScrn);
-
-    if (info->tilingEnabled != tilingOld) {
-	/* need to redraw front buffer, I guess this can be considered a hack ? */
-	/* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
-	if (pScrn->pScreen)
-	    xf86EnableDisableFBAccess(pScrn->scrnIndex, FALSE);
-	RADEONChangeSurfaces(pScrn);
-	if (pScrn->pScreen)
-	    xf86EnableDisableFBAccess(pScrn->scrnIndex, TRUE);
-	/* xf86SetRootClip would do, but can't access that here */
+    if (IS_AVIVO_VARIANT) {
+	atombios_crtc_mode_set(crtc, mode, adjusted_mode, x, y);
+    } else {
+	legacy_crtc_mode_set(crtc, mode, adjusted_mode, x, y);
     }
-
-    /* reset ecp_div for Xv */
-    info->ecp_div = -1;
-
 }
 
 static void
@@ -1024,7 +209,8 @@ radeon_crtc_mode_commit(xf86CrtcPtr crtc)
     radeon_crtc_dpms(crtc, DPMSModeOn);
 }
 
-void radeon_crtc_load_lut(xf86CrtcPtr crtc)
+void
+radeon_crtc_load_lut(xf86CrtcPtr crtc)
 {
     ScrnInfoPtr pScrn = crtc->scrn;
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
@@ -1035,8 +221,25 @@ void radeon_crtc_load_lut(xf86CrtcPtr crtc)
     if (!crtc->enabled)
 	return;
 
+    if (IS_AVIVO_VARIANT) {
+	OUTREG(AVIVO_DC_LUTA_CONTROL + radeon_crtc->crtc_offset, 0);
+
+	OUTREG(AVIVO_DC_LUTA_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
+	OUTREG(AVIVO_DC_LUTA_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0);
+	OUTREG(AVIVO_DC_LUTA_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0);
+
+	OUTREG(AVIVO_DC_LUTA_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0x0000ffff);
+	OUTREG(AVIVO_DC_LUTA_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0x0000ffff);
+	OUTREG(AVIVO_DC_LUTA_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0x0000ffff);
+    }
+
     PAL_SELECT(radeon_crtc->crtc_id);
 
+    if (IS_AVIVO_VARIANT) {
+	OUTREG(AVIVO_DC_LUT_RW_MODE, 0);
+	OUTREG(AVIVO_DC_LUT_WRITE_EN_MASK, 0x0000003f);
+    }
+
     for (i = 0; i < 256; i++) {
 	OUTPAL(i, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]);
     }
@@ -1153,12 +356,13 @@ radeon_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length,
  * Allocates memory for a locked-in-framebuffer shadow of the given
  * width and height for this CRTC's rotated shadow framebuffer.
  */
- 
+
 static void *
 radeon_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
 {
     ScrnInfoPtr pScrn = crtc->scrn;
-    ScreenPtr pScreen = pScrn->pScreen;
+    /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
+    ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
     RADEONInfoPtr  info = RADEONPTR(pScrn);
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     unsigned long rotate_pitch;
@@ -1229,7 +433,7 @@ radeon_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
 
     if (!data)
 	data = radeon_crtc_shadow_allocate(crtc, width, height);
-    
+
     rotate_pitch = pScrn->displayWidth * cpp;
 
     rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen,
@@ -1295,40 +499,47 @@ static const xf86CrtcFuncsRec radeon_crtc_funcs = {
     .destroy = NULL, /* XXX */
 };
 
-Bool RADEONAllocateControllers(ScrnInfoPtr pScrn)
+Bool RADEONAllocateControllers(ScrnInfoPtr pScrn, int mask)
 {
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
 
-    if (pRADEONEnt->Controller[0])
-      return TRUE;
-
-    pRADEONEnt->pCrtc[0] = xf86CrtcCreate(pScrn, &radeon_crtc_funcs);
-    if (!pRADEONEnt->pCrtc[0])
-      return FALSE;
-
-    pRADEONEnt->Controller[0] = xnfcalloc(sizeof(RADEONCrtcPrivateRec), 1);
-    if (!pRADEONEnt->Controller[0])
-        return FALSE;
-
-    pRADEONEnt->pCrtc[0]->driver_private = pRADEONEnt->Controller[0];
-    pRADEONEnt->Controller[0]->crtc_id = 0;
-
-    if (!pRADEONEnt->HasCRTC2)
-	return TRUE;
-
-    pRADEONEnt->pCrtc[1] = xf86CrtcCreate(pScrn, &radeon_crtc_funcs);
-    if (!pRADEONEnt->pCrtc[1])
-      return FALSE;
+    if (mask & 1) {
+	if (pRADEONEnt->Controller[0])
+	    return TRUE;
+	
+	pRADEONEnt->pCrtc[0] = xf86CrtcCreate(pScrn, &radeon_crtc_funcs);
+	if (!pRADEONEnt->pCrtc[0])
+	    return FALSE;
+
+	pRADEONEnt->Controller[0] = xnfcalloc(sizeof(RADEONCrtcPrivateRec), 1);
+	if (!pRADEONEnt->Controller[0])
+	    return FALSE;
+
+	pRADEONEnt->pCrtc[0]->driver_private = pRADEONEnt->Controller[0];
+	pRADEONEnt->Controller[0]->crtc_id = 0;
+	pRADEONEnt->Controller[0]->crtc_offset = 0;
+    }
+
+    if (mask & 2) {
+	if (!pRADEONEnt->HasCRTC2)
+	    return TRUE;
+	
+	pRADEONEnt->pCrtc[1] = xf86CrtcCreate(pScrn, &radeon_crtc_funcs);
+	if (!pRADEONEnt->pCrtc[1])
+	    return FALSE;
+	
+	pRADEONEnt->Controller[1] = xnfcalloc(sizeof(RADEONCrtcPrivateRec), 1);
+	if (!pRADEONEnt->Controller[1])
+	    {
+		xfree(pRADEONEnt->Controller[0]);
+		return FALSE;
+	    }
 
-    pRADEONEnt->Controller[1] = xnfcalloc(sizeof(RADEONCrtcPrivateRec), 1);
-    if (!pRADEONEnt->Controller[1])
-    {
-	xfree(pRADEONEnt->Controller[0]);
-	return FALSE;
+	pRADEONEnt->pCrtc[1]->driver_private = pRADEONEnt->Controller[1];
+	pRADEONEnt->Controller[1]->crtc_id = 1;
+	pRADEONEnt->Controller[1]->crtc_offset = AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
     }
 
-    pRADEONEnt->pCrtc[1]->driver_private = pRADEONEnt->Controller[1];
-    pRADEONEnt->Controller[1]->crtc_id = 1;
     return TRUE;
 }
 
@@ -1433,3 +644,47 @@ RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode)
     return pMode;
 }
 
+void
+RADEONBlank(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
+RADEONUnblank(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/radeon_cursor.c b/src/radeon_cursor.c
index ba1159c..0f7e668 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -74,12 +74,12 @@
 #define CURSOR_SWAPPING_START() \
   do { \
     OUTREG(RADEON_SURFACE_CNTL, \
-	   (info->ModeReg.surface_cntl | \
+	   (info->ModeReg->surface_cntl | \
 	     RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP) & \
 	   ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP)); \
   } while (0)
 #define CURSOR_SWAPPING_END()	(OUTREG(RADEON_SURFACE_CNTL, \
-					info->ModeReg.surface_cntl))
+					info->ModeReg->surface_cntl))
 
 #else
 
@@ -89,6 +89,25 @@
 
 #endif
 
+static void
+avivo_setup_cursor(xf86CrtcPtr crtc, Bool enable)
+{
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    RADEONInfoPtr  info = RADEONPTR(crtc->scrn);
+    unsigned char     *RADEONMMIO = info->MMIO;
+
+    OUTREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset, 0);
+
+    if (enable) {
+	OUTREG(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
+	       info->fbLocation + radeon_crtc->cursor_offset);
+	OUTREG(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset,
+	       ((CURSOR_WIDTH - 1) << 16) | (CURSOR_HEIGHT - 1));
+	OUTREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset,
+	       AVIVO_D1CURSOR_EN | (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
+    }
+}
+
 void
 radeon_crtc_show_cursor (xf86CrtcPtr crtc)
 {
@@ -98,19 +117,26 @@ radeon_crtc_show_cursor (xf86CrtcPtr crtc)
     RADEONInfoPtr      info       = RADEONPTR(pScrn);
     unsigned char     *RADEONMMIO = info->MMIO;
 
-    switch (crtc_id) {
-    case 0:
-	OUTREG(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL);
-	break;
-    case 1:
-	OUTREG(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL);
-	break;
-    default:
-	return;
+    if (IS_AVIVO_VARIANT) {
+	OUTREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset,
+	       INREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset)
+	       | AVIVO_D1CURSOR_EN);
+	avivo_setup_cursor(crtc, TRUE);
+    } else {
+        switch (crtc_id) {
+        case 0:
+            OUTREG(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL);
+	    break;
+        case 1:
+            OUTREG(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL);
+	    break;
+        default:
+            return;
+        }
+
+        OUTREGP(RADEON_MM_DATA, RADEON_CRTC_CUR_EN | 2 << 20, 
+                ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK));
     }
-
-    OUTREGP(RADEON_MM_DATA, RADEON_CRTC_CUR_EN | 2 << 20, 
-	    ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK));
 }
 
 void
@@ -122,18 +148,25 @@ radeon_crtc_hide_cursor (xf86CrtcPtr crtc)
     RADEONInfoPtr      info       = RADEONPTR(pScrn);
     unsigned char     *RADEONMMIO = info->MMIO;
 
-    switch (crtc_id) {
-    case 0:
-	OUTREG(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL);
-	break;
-    case 1:
-	OUTREG(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL);
-	break;
-    default:
-	return;
-    }
-
-    OUTREGP(RADEON_MM_DATA, 0, ~RADEON_CRTC_CUR_EN);
+    if (IS_AVIVO_VARIANT) {
+	OUTREG(AVIVO_D1CUR_CONTROL+ radeon_crtc->crtc_offset,
+	       INREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset)
+	       & ~(AVIVO_D1CURSOR_EN));
+	avivo_setup_cursor(crtc, FALSE);
+    } else {
+	switch(crtc_id) {
+    	case 0:
+            OUTREG(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL);
+            break;
+    	case 1:
+	    OUTREG(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL);
+	    break;
+        default:
+	    return;
+        }
+
+        OUTREGP(RADEON_MM_DATA, 0, ~RADEON_CRTC_CUR_EN);
+   }
 }
 
 void
@@ -158,30 +191,38 @@ radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
     else if (mode->Flags & V_DBLSCAN)
 	y *= 2;
 
-    if (crtc_id == 0) {
-	OUTREG(RADEON_CUR_HORZ_VERT_OFF,  (RADEON_CUR_LOCK
-					   | (xorigin << 16)
-					   | yorigin));
-	OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK
-					   | ((xorigin ? 0 : x) << 16)
-					   | (yorigin ? 0 : y)));
-	RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
-			radeon_crtc->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
-	OUTREG(RADEON_CUR_OFFSET,
-		radeon_crtc->cursor_offset + pScrn->fbOffset + yorigin * stride);
-    } else if (crtc_id == 1) {
-	OUTREG(RADEON_CUR2_HORZ_VERT_OFF,  (RADEON_CUR2_LOCK
-					    | (xorigin << 16)
-					    | yorigin));
-	OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK
-					   | ((xorigin ? 0 : x) << 16)
-					   | (yorigin ? 0 : y)));
-	RADEONCTRACE(("cursor_offset2: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
-			radeon_crtc->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
-	OUTREG(RADEON_CUR2_OFFSET,
-		radeon_crtc->cursor_offset + pScrn->fbOffset + yorigin * stride);
+    if (IS_AVIVO_VARIANT) {
+	/* avivo cursor spans the full fb width */
+	x += crtc->x;
+	y += crtc->y;
+	OUTREG(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset, ((xorigin ? 0 : x) << 16)
+	       | (yorigin ? 0 : y));
+	OUTREG(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin);
+    } else {
+	if (crtc_id == 0) {
+	    OUTREG(RADEON_CUR_HORZ_VERT_OFF,  (RADEON_CUR_LOCK
+					       | (xorigin << 16)
+					       | yorigin));
+	    OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK
+					       | ((xorigin ? 0 : x) << 16)
+					       | (yorigin ? 0 : y)));
+	    RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
+			  radeon_crtc->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
+	    OUTREG(RADEON_CUR_OFFSET,
+		   radeon_crtc->cursor_offset + pScrn->fbOffset + yorigin * stride);
+	} else if (crtc_id == 1) {
+	    OUTREG(RADEON_CUR2_HORZ_VERT_OFF,  (RADEON_CUR2_LOCK
+						| (xorigin << 16)
+						| yorigin));
+	    OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK
+						| ((xorigin ? 0 : x) << 16)
+						| (yorigin ? 0 : y)));
+	    RADEONCTRACE(("cursor_offset2: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
+			  radeon_crtc->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
+	    OUTREG(RADEON_CUR2_OFFSET,
+		   radeon_crtc->cursor_offset + pScrn->fbOffset + yorigin * stride);
+	}
     }
-
 }
 
 void
@@ -269,10 +310,11 @@ Bool RADEONCursorInit(ScreenPtr pScreen)
 
 #ifdef USE_XAA
     if (!info->useEXA) {
+	int align = IS_AVIVO_VARIANT ? 4096 : 256;
 	FBAreaPtr          fbarea;
 
 	fbarea = xf86AllocateOffscreenArea(pScreen, width, height,
-					   256, NULL, NULL, NULL);
+					   align, NULL, NULL, NULL);
 
 	if (!fbarea) {
 	    cursor_offset    = 0;
@@ -284,7 +326,7 @@ Bool RADEONCursorInit(ScreenPtr pScreen)
 	    cursor_offset  = RADEON_ALIGN((fbarea->box.x1 +
 					   fbarea->box.y1 * width) *
 					  info->CurrentLayout.pixel_bytes,
-					  256);
+					  align);
 
 	    for (c = 0; c < xf86_config->num_crtc; c++) {
 		xf86CrtcPtr crtc = xf86_config->crtc[c];
diff --git a/src/radeon_display.c b/src/radeon_display.c
deleted file mode 100644
index ea31a82..0000000
--- a/src/radeon_display.c
+++ /dev/null
@@ -1,875 +0,0 @@
-/*
- * 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>
-
-/* X and server generic header files */
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "vgaHW.h"
-#include "xf86Modes.h"
-
-/* Driver data structures */
-#include "radeon.h"
-#include "radeon_reg.h"
-#include "radeon_macros.h"
-#include "radeon_probe.h"
-#include "radeon_version.h"
-
-extern int getRADEONEntityIndex(void);
-
-static const CARD32 default_tvdac_adj [CHIP_FAMILY_LAST] =
-{
-    0x00000000,   /* unknown */
-    0x00000000,   /* legacy */
-    0x00000000,   /* r100 */
-    0x00280000,   /* rv100 */
-    0x00000000,   /* rs100 */
-    0x00880000,   /* rv200 */
-    0x00000000,   /* rs200 */
-    0x00000000,   /* r200 */
-    0x00770000,   /* rv250 */
-    0x00290000,   /* rs300 */
-    0x00560000,   /* rv280 */
-    0x00780000,   /* r300 */
-    0x00770000,   /* r350 */
-    0x00780000,   /* rv350 */
-    0x00780000,   /* rv380 */
-    0x01080000,   /* r420 */
-    0x01080000,   /* rv410 */ /* FIXME: just values from r420 used... */
-    0x00780000,   /* rs400 */ /* FIXME: just values from rv380 used... */
-};
-
-void RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
-{
-    MonPtr      mon = pScrn->monitor;
-    xf86MonPtr  ddc = mon->DDC;
-    int         i;
-
-    if (flag) { /* HSync */
-	for (i = 0; i < 4; i++) {
-	    if (ddc->det_mon[i].type == DS_RANGES) {
-		mon->nHsync = 1;
-		mon->hsync[0].lo = ddc->det_mon[i].section.ranges.min_h;
-		mon->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 */
-	    mon->hsync[i].lo = mon->hsync[i].hi = 35.2;
-	    i++;
-	}
-	if (ddc->timings1.t1 & 0x04) { /* 640x480@75 */
-	    mon->hsync[i].lo = mon->hsync[i].hi = 37.5;
-	    i++;
-	}
-	if ((ddc->timings1.t1 & 0x08) || (ddc->timings1.t1 & 0x01)) {
-	    mon->hsync[i].lo = mon->hsync[i].hi = 37.9;
-	    i++;
-	}
-	if (ddc->timings1.t2 & 0x40) {
-	    mon->hsync[i].lo = mon->hsync[i].hi = 46.9;
-	    i++;
-	}
-	if ((ddc->timings1.t2 & 0x80) || (ddc->timings1.t2 & 0x08)) {
-	    mon->hsync[i].lo = mon->hsync[i].hi = 48.1;
-	    i++;
-	}
-	if (ddc->timings1.t2 & 0x04) {
-	    mon->hsync[i].lo = mon->hsync[i].hi = 56.5;
-	    i++;
-	}
-	if (ddc->timings1.t2 & 0x02) {
-	    mon->hsync[i].lo = mon->hsync[i].hi = 60.0;
-	    i++;
-	}
-	if (ddc->timings1.t2 & 0x01) {
-	    mon->hsync[i].lo = mon->hsync[i].hi = 64.0;
-	    i++;
-	}
-	mon->nHsync = i;
-    } else {  /* Vrefresh */
-	for (i = 0; i < 4; i++) {
-	    if (ddc->det_mon[i].type == DS_RANGES) {
-		mon->nVrefresh = 1;
-		mon->vrefresh[0].lo = ddc->det_mon[i].section.ranges.min_v;
-		mon->vrefresh[0].hi = ddc->det_mon[i].section.ranges.max_v;
-		return;
-	    }
-	}
-
-	i = 0;
-	if (ddc->timings1.t1 & 0x02) { /* 800x600@56 */
-	    mon->vrefresh[i].lo = mon->vrefresh[i].hi = 56;
-	    i++;
-	}
-	if ((ddc->timings1.t1 & 0x01) || (ddc->timings1.t2 & 0x08)) {
-	    mon->vrefresh[i].lo = mon->vrefresh[i].hi = 60;
-	    i++;
-	}
-	if (ddc->timings1.t2 & 0x04) {
-	    mon->vrefresh[i].lo = mon->vrefresh[i].hi = 70;
-	    i++;
-	}
-	if ((ddc->timings1.t1 & 0x08) || (ddc->timings1.t2 & 0x80)) {
-	    mon->vrefresh[i].lo = mon->vrefresh[i].hi = 72;
-	    i++;
-	}
-	if ((ddc->timings1.t1 & 0x04) || (ddc->timings1.t2 & 0x40) ||
-	    (ddc->timings1.t2 & 0x02) || (ddc->timings1.t2 & 0x01)) {
-	    mon->vrefresh[i].lo = mon->vrefresh[i].hi = 75;
-	    i++;
-	}
-	mon->nVrefresh = i;
-    }
-}
-
-void RADEONGetTVDacAdjInfo(xf86OutputPtr output)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
-    /* Todo: get this setting from BIOS */
-    radeon_output->tv_dac_adj = default_tvdac_adj[info->ChipFamily];
-    if (info->IsMobility) { /* some mobility chips may different */
-	if (info->ChipFamily == CHIP_FAMILY_RV250)
-	    radeon_output->tv_dac_adj = 0x00880000;
-    }
-}
-
-/*
- * Powering done DAC, needed for DPMS problem with ViewSonic P817 (or its variant).
- *
- */
-static void RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    if (IsPrimaryDAC) {
-	CARD32 dac_cntl;
-	CARD32 dac_macro_cntl = 0;
-	dac_cntl = INREG(RADEON_DAC_CNTL);
-	dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
-	if (IsOn) {
-	    dac_cntl &= ~RADEON_DAC_PDWN;
-	    dac_macro_cntl &= ~(RADEON_DAC_PDWN_R |
-				RADEON_DAC_PDWN_G |
-				RADEON_DAC_PDWN_B);
-	} else {
-	    dac_cntl |= RADEON_DAC_PDWN;
-	    dac_macro_cntl |= (RADEON_DAC_PDWN_R |
-			       RADEON_DAC_PDWN_G |
-			       RADEON_DAC_PDWN_B);
-	}
-	OUTREG(RADEON_DAC_CNTL, dac_cntl);
-	OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
-    } else {
-	CARD32 tv_dac_cntl;
-	CARD32 fp2_gen_cntl;
-
-	switch(info->ChipFamily)
-	{
-	case CHIP_FAMILY_R420:
-	case CHIP_FAMILY_RV410:
-	    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
-	    if (IsOn) {
-		tv_dac_cntl &= ~(R420_TV_DAC_RDACPD |
-				 R420_TV_DAC_GDACPD |
-				 R420_TV_DAC_BDACPD |
-				 RADEON_TV_DAC_BGSLEEP);
-	    } else {
-		tv_dac_cntl |= (R420_TV_DAC_RDACPD |
-				R420_TV_DAC_GDACPD |
-				R420_TV_DAC_BDACPD |
-				RADEON_TV_DAC_BGSLEEP);
-	    }
-	    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
-	    break;
-	case CHIP_FAMILY_R200:
-	    fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL);
-	    if (IsOn) {
-		fp2_gen_cntl |= RADEON_FP2_DVO_EN;
-	    } else {
-		fp2_gen_cntl &= ~RADEON_FP2_DVO_EN;
-	    }
-	    OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
-	    break;
-
-	default:
-	    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
-	    if (IsOn) {
-		tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD |
-				 RADEON_TV_DAC_GDACPD |
-				 RADEON_TV_DAC_BDACPD |
-				 RADEON_TV_DAC_BGSLEEP);
-	    } else {
-		tv_dac_cntl |= (RADEON_TV_DAC_RDACPD |
-				RADEON_TV_DAC_GDACPD |
-				RADEON_TV_DAC_BDACPD |
-				RADEON_TV_DAC_BGSLEEP);
-	    }
-	    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
-	    break;
-	}
-    }
-}
-
-/* disable all ouputs before enabling the ones we want */
-void RADEONDisableDisplays(ScrnInfoPtr pScrn) {
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    unsigned char * RADEONMMIO = info->MMIO;
-    unsigned long tmp, tmpPixclksCntl;
-
-
-    /* primary DAC */
-    tmp = INREG(RADEON_CRTC_EXT_CNTL);
-    tmp &= ~RADEON_CRTC_CRT_ON;
-    OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
-    RADEONDacPowerSet(pScrn, FALSE, TRUE);
-
-    /* Secondary DAC */
-    if (info->ChipFamily == CHIP_FAMILY_R200) {
-	tmp = INREG(RADEON_FP2_GEN_CNTL);
-	tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
-	OUTREG(RADEON_FP2_GEN_CNTL, tmp);
-    } else {
-	tmp = INREG(RADEON_CRTC2_GEN_CNTL);
-	tmp &= ~RADEON_CRTC2_CRT2_ON;
-	OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
-    }
-    RADEONDacPowerSet(pScrn, FALSE, FALSE);
-
-    /* turn off tv-out */
-    if (info->InternalTVOut) {
-	tmp = INREG(RADEON_TV_MASTER_CNTL);
-	tmp &= ~RADEON_TV_ON;
-	OUTREG(RADEON_TV_MASTER_CNTL, tmp);
-    }
-
-    /* FP 1 */
-    tmp = INREG(RADEON_FP_GEN_CNTL);
-    tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
-    OUTREG(RADEON_FP_GEN_CNTL, tmp);
-
-    /* FP 2 */
-    tmp = INREG(RADEON_FP2_GEN_CNTL);
-    tmp |= RADEON_FP2_BLANK_EN;
-    tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
-    OUTREG(RADEON_FP2_GEN_CNTL, tmp);
-
-    /* LVDS */
-    if (info->IsMobility) {
-	tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
-	if (info->IsMobility || info->IsIGP) {
-	    /* Asic bug, when turning off LVDS_ON, we have to make sure
-	       RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
-	    */
-	    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
-	}
-	tmp = INREG(RADEON_LVDS_GEN_CNTL);
-	tmp |= RADEON_LVDS_DISPLAY_DIS;
-	tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
-	OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
-	if (info->IsMobility || info->IsIGP) {
-	    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
-	}
-    }
-
-}
-
-/* This is to be used enable/disable displays dynamically */
-void RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    RADEONSavePtr save = &info->ModeReg;
-    unsigned char * RADEONMMIO = info->MMIO;
-    unsigned long tmp;
-    RADEONOutputPrivatePtr radeon_output;
-    int tv_dac_change = 0, o;
-    radeon_output = output->driver_private;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-
-    for (o = 0; o < xf86_config->num_output; o++) {
-	if (output == xf86_config->output[o]) {
-	    break;
-	}
-    }
-
-    if (bEnable) {
-	ErrorF("enable montype: %d\n", radeon_output->MonType);
-	if (radeon_output->MonType == MT_CRT) {
-	    if (radeon_output->DACType == DAC_PRIMARY) {
-		info->output_crt1 |= (1 << o);
-		tmp = INREG(RADEON_CRTC_EXT_CNTL);
-		tmp |= RADEON_CRTC_CRT_ON;
-		OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
-		save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON;
-		RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
-	    } else if (radeon_output->DACType == DAC_TVDAC) {
-		info->output_crt2 |= (1 << o);
-		if (info->ChipFamily == CHIP_FAMILY_R200) {
-		    tmp = INREG(RADEON_FP2_GEN_CNTL);
-		    tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
-		    OUTREG(RADEON_FP2_GEN_CNTL, tmp);
-		    save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
-		} else {
-		    tmp = INREG(RADEON_CRTC2_GEN_CNTL);
-		    tmp |= RADEON_CRTC2_CRT2_ON;
-		    OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
-		    save->crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
-		}
-		tv_dac_change = 1;
-	    }
-	} else if (radeon_output->MonType == MT_DFP) {
-	    if (radeon_output->TMDSType == TMDS_INT) {
-		info->output_dfp1 |= (1 << o);
-		tmp = INREG(RADEON_FP_GEN_CNTL);
-		tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
-		OUTREG(RADEON_FP_GEN_CNTL, tmp);
-		save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
-	    } else if (radeon_output->TMDSType == TMDS_EXT) {
-		info->output_dfp2 |= (1 << o);
-		tmp = INREG(RADEON_FP2_GEN_CNTL);
-		tmp &= ~RADEON_FP2_BLANK_EN;
-		tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
-		OUTREG(RADEON_FP2_GEN_CNTL, tmp);
-		save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
-		save->fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN;
-	    }
-	} else if (radeon_output->MonType == MT_LCD) {
-	    info->output_lcd1 |= (1 << o);
-	    tmp = INREG(RADEON_LVDS_GEN_CNTL);
-	    tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
-	    tmp &= ~(RADEON_LVDS_DISPLAY_DIS);
-	    usleep (radeon_output->PanelPwrDly * 1000);
-	    OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
-	    save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
-	    save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
-	} else if (radeon_output->MonType == MT_STV ||
-		   radeon_output->MonType == MT_CTV) {
-	    info->output_tv1 |= (1 << o);
-	    tmp = INREG(RADEON_TV_MASTER_CNTL);
-	    tmp |= RADEON_TV_ON;
-	    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
-	    tv_dac_change = 2;
-	    radeon_output->tv_on = TRUE;
-	}
-    } else {
-	ErrorF("disable montype: %d\n", radeon_output->MonType);
-	if (radeon_output->MonType == MT_CRT) {
-	    if (radeon_output->DACType == DAC_PRIMARY) {
-		info->output_crt1 &= ~(1 << o);
-		if (!info->output_crt1) {
-		    tmp = INREG(RADEON_CRTC_EXT_CNTL);
-		    tmp &= ~RADEON_CRTC_CRT_ON;
-		    OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
-		    save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
-		    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
-		}
-	    } else if (radeon_output->DACType == DAC_TVDAC) {
-		info->output_crt2 &= ~(1 << o);
-		tv_dac_change = 1;
-		if (!info->output_crt2) {
-		    if (info->ChipFamily == CHIP_FAMILY_R200) {
-			tmp = INREG(RADEON_FP2_GEN_CNTL);
-			tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
-			OUTREG(RADEON_FP2_GEN_CNTL, tmp);
-			save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
-		    } else {
-			tmp = INREG(RADEON_CRTC2_GEN_CNTL);
-			tmp &= ~RADEON_CRTC2_CRT2_ON;
-			OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
-			save->crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
-		    }
-		}
-	    }
-	} else if (radeon_output->MonType == MT_DFP) {
-	    if (radeon_output->TMDSType == TMDS_INT) {
-		info->output_dfp1 &= ~(1 << o);
-		if (!info->output_dfp1) {
-		    tmp = INREG(RADEON_FP_GEN_CNTL);
-		    tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
-		    OUTREG(RADEON_FP_GEN_CNTL, tmp);
-		    save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
-		}
-	    } else if (radeon_output->TMDSType == TMDS_EXT) {
-		info->output_dfp2 &= ~(1 << o);
-		if (!info->output_dfp2) {
-		    tmp = INREG(RADEON_FP2_GEN_CNTL);
-		    tmp |= RADEON_FP2_BLANK_EN;
-		    tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
-		    OUTREG(RADEON_FP2_GEN_CNTL, tmp);
-		    save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
-		    save->fp2_gen_cntl |= RADEON_FP2_BLANK_EN;
-		}
-	    }
-	} else if (radeon_output->MonType == MT_LCD) {
-	    info->output_lcd1 &= ~(1 << o);
-	    if (!info->output_lcd1) {
-		unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
-		if (info->IsMobility || info->IsIGP) {
-		    /* Asic bug, when turning off LVDS_ON, we have to make sure
-		       RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
-		    */
-		    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
-		}
-		tmp = INREG(RADEON_LVDS_GEN_CNTL);
-		tmp |= RADEON_LVDS_DISPLAY_DIS;
-		tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
-		OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
-		save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
-		save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
-		if (info->IsMobility || info->IsIGP) {
-		    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
-		}
-	    }
-	} else if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
-	    info->output_tv1 &= ~(1 << o);
-	    tv_dac_change = 2;
-	    if (!info->output_tv1) {
-		tmp = INREG(RADEON_TV_MASTER_CNTL);
-		tmp &= ~RADEON_TV_ON;
-		OUTREG(RADEON_TV_MASTER_CNTL, tmp);
-		radeon_output->tv_on = FALSE;
-	    }
-	}
-    }
-
-    if (tv_dac_change) {
-	if (bEnable)
-	    info->tv_dac_enable_mask |= tv_dac_change;
-	else
-	    info->tv_dac_enable_mask &= ~tv_dac_change;
-
-	if (bEnable && info->tv_dac_enable_mask)
-	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
-	else if (!bEnable && info->tv_dac_enable_mask == 0)
-	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
-
-    }
-}
-
-/* Calculate display buffer watermark to prevent buffer underflow */
-void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2, DisplayModePtr mode1, DisplayModePtr mode2)
-{
-    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    CARD32 temp, data, mem_trcd, mem_trp, mem_tras, mem_trbs=0;
-    float mem_tcas;
-    int k1, c;
-    CARD32 MemTrcdExtMemCntl[4]     = {1, 2, 3, 4};
-    CARD32 MemTrpExtMemCntl[4]      = {1, 2, 3, 4};
-    CARD32 MemTrasExtMemCntl[8]     = {1, 2, 3, 4, 5, 6, 7, 8};
-
-    CARD32 MemTrcdMemTimingCntl[8]     = {1, 2, 3, 4, 5, 6, 7, 8};
-    CARD32 MemTrpMemTimingCntl[8]      = {1, 2, 3, 4, 5, 6, 7, 8};
-    CARD32 MemTrasMemTimingCntl[16]    = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
-
-    float MemTcas[8]  = {0, 1, 2, 3, 0, 1.5, 2.5, 0};
-    float MemTcas2[8] = {0, 1, 2, 3, 4, 5, 6, 7};
-    float MemTrbs[8]  = {1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5};
-
-    float mem_bw, peak_disp_bw;
-    float min_mem_eff = 0.8;
-    float sclk_eff, sclk_delay;
-    float mc_latency_mclk, mc_latency_sclk, cur_latency_mclk, cur_latency_sclk;
-    float disp_latency, disp_latency_overhead, disp_drain_rate, disp_drain_rate2;
-    float pix_clk, pix_clk2; /* in MHz */
-    int cur_size = 16;       /* in octawords */
-    int critical_point, critical_point2;
-    int stop_req, max_stop_req;
-    float read_return_rate, time_disp1_drop_priority;
-
-    /*
-     * Set display0/1 priority up on r3/4xx in the memory controller for
-     * high res modes if the user specifies HIGH for displaypriority
-     * option.
-     */
-    if ((info->DispPriority == 2) && IS_R300_VARIANT) {
-	CARD32 mc_init_misc_lat_timer = INREG(R300_MC_INIT_MISC_LAT_TIMER);
-	if (pRADEONEnt->pCrtc[1]->enabled) {
-	    mc_init_misc_lat_timer |= 0x1100; /* display 0 and 1 */
-	} else {
-	    mc_init_misc_lat_timer |= 0x0100; /* display 0 only */
-	}
-	OUTREG(R300_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer);
-    }
-
-
-    /* R420 and RV410 family not supported yet */
-    if (info->ChipFamily == CHIP_FAMILY_R420 || info->ChipFamily == CHIP_FAMILY_RV410) return; 
-
-    /*
-     * Determine if there is enough bandwidth for current display mode
-     */
-    mem_bw = info->mclk * (info->RamWidth / 8) * (info->IsDDR ? 2 : 1);
-
-    pix_clk = mode1->Clock/1000.0;
-    if (mode2)
-	pix_clk2 = mode2->Clock/1000.0;
-    else
-	pix_clk2 = 0;
-
-    peak_disp_bw = (pix_clk * info->CurrentLayout.pixel_bytes);
-    if (pixel_bytes2)
-      peak_disp_bw += (pix_clk2 * pixel_bytes2);
-
-    if (peak_disp_bw >= mem_bw * min_mem_eff) {
-	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		   "You may not have enough display bandwidth for current mode\n"
-		   "If you have flickering problem, try to lower resolution, refresh rate, or color depth\n");
-    }
-
-    /*  CRTC1
-        Set GRPH_BUFFER_CNTL register using h/w defined optimal values.
-	GRPH_STOP_REQ <= MIN[ 0x7C, (CRTC_H_DISP + 1) * (bit depth) / 0x10 ]
-    */
-    stop_req = mode1->HDisplay * info->CurrentLayout.pixel_bytes / 16;
-
-    /* setup Max GRPH_STOP_REQ default value */
-    if (IS_RV100_VARIANT)
-	max_stop_req = 0x5c;
-    else
-	max_stop_req  = 0x7c;
-    if (stop_req > max_stop_req)
-	stop_req = max_stop_req;
-
-    /*  Get values from the EXT_MEM_CNTL register...converting its contents. */
-    temp = INREG(RADEON_MEM_TIMING_CNTL);
-    if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */
-	mem_trcd      = MemTrcdExtMemCntl[(temp & 0x0c) >> 2];
-	mem_trp       = MemTrpExtMemCntl[ (temp & 0x03) >> 0];
-	mem_tras      = MemTrasExtMemCntl[(temp & 0x70) >> 4];
-    } else { /* RV200 and later */
-	mem_trcd      = MemTrcdMemTimingCntl[(temp & 0x07) >> 0];
-	mem_trp       = MemTrpMemTimingCntl[ (temp & 0x700) >> 8];
-	mem_tras      = MemTrasMemTimingCntl[(temp & 0xf000) >> 12];
-    }
-
-    /* Get values from the MEM_SDRAM_MODE_REG register...converting its */
-    temp = INREG(RADEON_MEM_SDRAM_MODE_REG);
-    data = (temp & (7<<20)) >> 20;
-    if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */
-	mem_tcas = MemTcas [data];
-    } else {
-	mem_tcas = MemTcas2 [data];
-    }
-
-    if (IS_R300_VARIANT) {
-
-	/* on the R300, Tcas is included in Trbs.
-	*/
-	temp = INREG(RADEON_MEM_CNTL);
-	data = (R300_MEM_NUM_CHANNELS_MASK & temp);
-	if (data == 1) {
-	    if (R300_MEM_USE_CD_CH_ONLY & temp) {
-		temp  = INREG(R300_MC_IND_INDEX);
-		temp &= ~R300_MC_IND_ADDR_MASK;
-		temp |= R300_MC_READ_CNTL_CD_mcind;
-		OUTREG(R300_MC_IND_INDEX, temp);
-		temp  = INREG(R300_MC_IND_DATA);
-		data = (R300_MEM_RBS_POSITION_C_MASK & temp);
-	    } else {
-		temp = INREG(R300_MC_READ_CNTL_AB);
-		data = (R300_MEM_RBS_POSITION_A_MASK & temp);
-	    }
-	} else {
-	    temp = INREG(R300_MC_READ_CNTL_AB);
-	    data = (R300_MEM_RBS_POSITION_A_MASK & temp);
-	}
-
-	mem_trbs = MemTrbs[data];
-	mem_tcas += mem_trbs;
-    }
-
-    if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */
-	/* DDR64 SCLK_EFF = SCLK for analysis */
-	sclk_eff = info->sclk;
-    } else {
-#ifdef XF86DRI
-	if (info->directRenderingEnabled)
-	    sclk_eff = info->sclk - (info->agpMode * 50.0 / 3.0);
-	else
-#endif
-	    sclk_eff = info->sclk;
-    }
-
-    /* Find the memory controller latency for the display client.
-    */
-    if (IS_R300_VARIANT) {
-	/*not enough for R350 ???*/
-	/*
-	if (!mode2) sclk_delay = 150;
-	else {
-	    if (info->RamWidth == 256) sclk_delay = 87;
-	    else sclk_delay = 97;
-	}
-	*/
-	sclk_delay = 250;
-    } else {
-	if ((info->ChipFamily == CHIP_FAMILY_RV100) ||
-	    info->IsIGP) {
-	    if (info->IsDDR) sclk_delay = 41;
-	    else sclk_delay = 33;
-	} else {
-	    if (info->RamWidth == 128) sclk_delay = 57;
-	    else sclk_delay = 41;
-	}
-    }
-
-    mc_latency_sclk = sclk_delay / sclk_eff;
-
-    if (info->IsDDR) {
-	if (info->RamWidth == 32) {
-	    k1 = 40;
-	    c  = 3;
-	} else {
-	    k1 = 20;
-	    c  = 1;
-	}
-    } else {
-	k1 = 40;
-	c  = 3;
-    }
-    mc_latency_mclk = ((2.0*mem_trcd + mem_tcas*c + 4.0*mem_tras + 4.0*mem_trp + k1) /
-		       info->mclk) + (4.0 / sclk_eff);
-
-    /*
-      HW cursor time assuming worst case of full size colour cursor.
-    */
-    cur_latency_mclk = (mem_trp + MAX(mem_tras, (mem_trcd + 2*(cur_size - (info->IsDDR+1))))) / info->mclk;
-    cur_latency_sclk = cur_size / sclk_eff;
-
-    /*
-      Find the total latency for the display data.
-    */
-    disp_latency_overhead = 8.0 / info->sclk;
-    mc_latency_mclk = mc_latency_mclk + disp_latency_overhead + cur_latency_mclk;
-    mc_latency_sclk = mc_latency_sclk + disp_latency_overhead + cur_latency_sclk;
-    disp_latency = MAX(mc_latency_mclk, mc_latency_sclk);
-
-    /*
-      Find the drain rate of the display buffer.
-    */
-    disp_drain_rate = pix_clk / (16.0/info->CurrentLayout.pixel_bytes);
-    if (pixel_bytes2)
-	disp_drain_rate2 = pix_clk2 / (16.0/pixel_bytes2);
-    else
-	disp_drain_rate2 = 0;
-
-    /*
-      Find the critical point of the display buffer.
-    */
-    critical_point= (CARD32)(disp_drain_rate * disp_latency + 0.5);
-
-    /* ???? */
-    /*
-    temp = (info->SavedReg.grph_buffer_cntl & RADEON_GRPH_CRITICAL_POINT_MASK) >> RADEON_GRPH_CRITICAL_POINT_SHIFT;
-    if (critical_point < temp) critical_point = temp;
-    */
-    if (info->DispPriority == 2) {
-	critical_point = 0;
-    }
-
-    /*
-      The critical point should never be above max_stop_req-4.  Setting
-      GRPH_CRITICAL_CNTL = 0 will thus force high priority all the time.
-    */
-    if (max_stop_req - critical_point < 4) critical_point = 0;
-
-    if (critical_point == 0 && mode2 && info->ChipFamily == CHIP_FAMILY_R300) {
-	/* some R300 cards have problem with this set to 0, when CRTC2 is enabled.*/
-	critical_point = 0x10;
-    }
-
-    temp = info->SavedReg.grph_buffer_cntl;
-    temp &= ~(RADEON_GRPH_STOP_REQ_MASK);
-    temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT);
-    temp &= ~(RADEON_GRPH_START_REQ_MASK);
-    if ((info->ChipFamily == CHIP_FAMILY_R350) &&
-	(stop_req > 0x15)) {
-	stop_req -= 0x10;
-    }
-    temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT);
-
-    temp |= RADEON_GRPH_BUFFER_SIZE;
-    temp &= ~(RADEON_GRPH_CRITICAL_CNTL   |
-	      RADEON_GRPH_CRITICAL_AT_SOF |
-	      RADEON_GRPH_STOP_CNTL);
-    /*
-      Write the result into the register.
-    */
-    OUTREG(RADEON_GRPH_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
-				     (critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
-
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "GRPH_BUFFER_CNTL from %x to %x\n",
-		   (unsigned int)info->SavedReg.grph_buffer_cntl,
-		   (unsigned int)INREG(RADEON_GRPH_BUFFER_CNTL));
-
-    if (mode2) {
-	stop_req = mode2->HDisplay * pixel_bytes2 / 16;
-
-	if (stop_req > max_stop_req) stop_req = max_stop_req;
-
-	temp = info->SavedReg.grph2_buffer_cntl;
-	temp &= ~(RADEON_GRPH_STOP_REQ_MASK);
-	temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT);
-	temp &= ~(RADEON_GRPH_START_REQ_MASK);
-	if ((info->ChipFamily == CHIP_FAMILY_R350) &&
-	    (stop_req > 0x15)) {
-	    stop_req -= 0x10;
-	}
-	temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT);
-	temp |= RADEON_GRPH_BUFFER_SIZE;
-	temp &= ~(RADEON_GRPH_CRITICAL_CNTL   |
-		  RADEON_GRPH_CRITICAL_AT_SOF |
-		  RADEON_GRPH_STOP_CNTL);
-
-	if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
-	    (info->ChipFamily == CHIP_FAMILY_RS200))
-	    critical_point2 = 0;
-	else {
-	    read_return_rate = MIN(info->sclk, info->mclk*(info->RamWidth*(info->IsDDR+1)/128));
-	    time_disp1_drop_priority = critical_point / (read_return_rate - disp_drain_rate);
-
-	    critical_point2 = (CARD32)((disp_latency + time_disp1_drop_priority + 
-					disp_latency) * disp_drain_rate2 + 0.5);
-
-	    if (info->DispPriority == 2) {
-		critical_point2 = 0;
-	    }
-
-	    if (max_stop_req - critical_point2 < 4) critical_point2 = 0;
-
-	}
-
-	if (critical_point2 == 0 && info->ChipFamily == CHIP_FAMILY_R300) {
-	    /* some R300 cards have problem with this set to 0 */
-	    critical_point2 = 0x10;
-	}
-
-	OUTREG(RADEON_GRPH2_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
-					  (critical_point2 << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
-
-	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		       "GRPH2_BUFFER_CNTL from %x to %x\n",
-		       (unsigned int)info->SavedReg.grph2_buffer_cntl,
-		       (unsigned int)INREG(RADEON_GRPH2_BUFFER_CNTL));
-    }
-}
-
-void RADEONInitDispBandwidth(ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    DisplayModePtr mode1, mode2;
-    int pixel_bytes2 = 0;
-
-    mode1 = info->CurrentLayout.mode;
-    mode2 = NULL;
-    pixel_bytes2 = info->CurrentLayout.pixel_bytes;
-
-    if (xf86_config->num_crtc == 2) {
-      pixel_bytes2 = 0;
-      mode2 = NULL;
-
-      if (xf86_config->crtc[1]->enabled && xf86_config->crtc[0]->enabled) {
-	pixel_bytes2 = info->CurrentLayout.pixel_bytes;
-	mode1 = &xf86_config->crtc[0]->mode;
-	mode2 = &xf86_config->crtc[1]->mode;
-      } else if (xf86_config->crtc[0]->enabled) {
-	mode1 = &xf86_config->crtc[0]->mode;
-      } else if (xf86_config->crtc[1]->enabled) {
-	mode1 = &xf86_config->crtc[1]->mode;
-      } else
-	return;
-    } else {
-	if (xf86_config->crtc[0]->enabled)
-	    mode1 = &xf86_config->crtc[0]->mode;
-	else
-	    return;
-    }
-
-    RADEONInitDispBandwidth2(pScrn, info, pixel_bytes2, mode1, mode2);
-}
-
-void RADEONBlank(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 RADEONUnblank(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/radeon_dri.c b/src/radeon_dri.c
index 3190451..ac8d03c 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -726,9 +726,18 @@ static Bool RADEONSetAgpMode(RADEONInfoPtr info, ScreenPtr pScreen)
        pcie-agp rialto bridge chip - use the one from bridge which must match */
     CARD32 agp_status = (INREG(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode;
     Bool is_v3 = (agp_status & RADEON_AGPv3_MODE);
-    unsigned int defaultMode = is_v3 ?
-	((agp_status & RADEON_AGPv3_8X_MODE) ? 8 : 4) : 1;
-    MessageType from = X_DEFAULT;
+    unsigned int defaultMode;
+    MessageType from;
+
+    if (is_v3) {
+	defaultMode = (agp_status & RADEON_AGPv3_8X_MODE) ? 8 : 4;
+    } else {
+	if (agp_status & RADEON_AGP_4X_MODE) defaultMode = 4;
+	else if (agp_status & RADEON_AGP_2X_MODE) defaultMode = 2;
+	else defaultMode = 1;
+    }
+
+    from = X_DEFAULT;
 
     if (xf86GetOptValInteger(info->Options, OPTION_AGP_MODE, &info->agpMode)) {
 	if ((info->agpMode < (is_v3 ? 4 : 1)) ||
@@ -1188,7 +1197,7 @@ static void RADEONDRIIrqInit(RADEONInfoPtr info, ScreenPtr pScreen)
 	    info->irq = 0;
 	} else {
 	    unsigned char *RADEONMMIO = info->MMIO;
-	    info->ModeReg.gen_int_cntl = INREG( RADEON_GEN_INT_CNTL );
+	    info->ModeReg->gen_int_cntl = INREG( RADEON_GEN_INT_CNTL );
 	}
     }
 
@@ -1768,7 +1777,7 @@ void RADEONDRICloseScreen(ScreenPtr pScreen)
 	RADEONDRISetVBlankInterrupt (pScrn, FALSE);
 	drmCtlUninstHandler(info->drmFD);
 	info->irq = 0;
-	info->ModeReg.gen_int_cntl = 0;
+	info->ModeReg->gen_int_cntl = 0;
     }
 
     /* De-allocate vertex buffers */
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 9f9fd90..cf32d40 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -97,6 +97,7 @@
 #include "xf86cmap.h"
 #include "vbe.h"
 
+#include "shadow.h"
 				/* vgaHW definitions */
 #ifdef WITH_VGAHW
 #include "vgaHW.h"
@@ -124,11 +125,36 @@ static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
 static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
 #endif
 
-DisplayModePtr
+extern DisplayModePtr
 RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode);
 
-static void RADEONWaitPLLLock(ScrnInfoPtr pScrn, unsigned nTests,
-                              unsigned nWaitLoops, unsigned cntThreshold);
+extern void
+RADEONSaveCommonRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
+extern void
+RADEONSaveBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
+extern void
+RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
+extern void
+RADEONSaveCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save);
+extern void
+RADEONSavePLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
+extern void
+RADEONSavePLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save);
+extern void
+RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
+extern void
+RADEONSaveDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
+extern void
+RADEONSaveTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
+
+#ifdef USE_XAA
+#ifdef XF86DRI
+extern Bool
+RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen);
+#endif /* XF86DRI */
+extern Bool
+RADEONSetupMemXAA(int scrnIndex, ScreenPtr pScreen);
+#endif /* USE_XAA */
 
 static const OptionInfoRec RADEONOptions[] = {
     { OPTION_NOACCEL,        "NoAccel",          OPTV_BOOLEAN, {0}, FALSE },
@@ -193,193 +219,12 @@ static const OptionInfoRec RADEONOptions[] = {
     { OPTION_TVDAC_LOAD_DETECT, "TVDACLoadDetect", OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_FORCE_TVOUT,    "ForceTVOut",         OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_TVSTD,          "TVStandard",         OPTV_STRING,  {0}, FALSE },
+    { OPTION_IGNORE_LID_STATUS, "IgnoreLidStatus", OPTV_BOOLEAN, {0}, FALSE },
     { -1,                    NULL,               OPTV_NONE,    {0}, FALSE }
 };
 
 const OptionInfoRec *RADEONOptionsWeak(void) { return RADEONOptions; }
 
-#ifdef WITH_VGAHW
-static const char *vgahwSymbols[] = {
-    "vgaHWFreeHWRec",
-    "vgaHWGetHWRec",
-    "vgaHWGetIndex",
-    "vgaHWLock",
-    "vgaHWRestore",
-    "vgaHWSave",
-    "vgaHWUnlock",
-    "vgaHWGetIOBase",
-    NULL
-};
-#endif
-
-static const char *ddcSymbols[] = {
-    "xf86PrintEDID",
-    "xf86DoEDID_DDC1",
-    "xf86DoEDID_DDC2",
-    NULL
-};
-
-static const char *fbSymbols[] = {
-    "fbScreenInit",
-    "fbPictureInit",
-    NULL
-};
-
-
-#ifdef USE_EXA
-static const char *exaSymbols[] = {
-    "exaDriverAlloc",
-    "exaDriverInit",
-    "exaDriverFini",
-    "exaOffscreenAlloc",
-    "exaOffscreenFree",
-    "exaGetPixmapOffset",
-    "exaGetPixmapPitch",
-    "exaGetPixmapSize",
-    "exaMarkSync",
-    "exaWaitSync",
-    NULL
-};
-#endif /* USE_EXA */
-
-#ifdef USE_XAA
-static const char *xaaSymbols[] = {
-    "XAACreateInfoRec",
-    "XAADestroyInfoRec",
-    "XAAInit",
-    NULL
-};
-#endif /* USE_XAA */
-
-#if 0
-static const char *xf8_32bppSymbols[] = {
-    "xf86Overlay8Plus32Init",
-    NULL
-};
-#endif
-
-static const char *ramdacSymbols[] = {
-    "xf86CreateCursorInfoRec",
-    "xf86DestroyCursorInfoRec",
-    "xf86ForceHWCursor",
-    "xf86InitCursor",
-    NULL
-};
-
-#ifdef XF86DRI
-static const char *drmSymbols[] = {
-    "drmGetInterruptFromBusID",
-    "drmCtlInstHandler",
-    "drmCtlUninstHandler",
-    "drmAddBufs",
-    "drmAddMap",
-    "drmAgpAcquire",
-    "drmAgpAlloc",
-    "drmAgpBase",
-    "drmAgpBind",
-    "drmAgpDeviceId",
-    "drmAgpEnable",
-    "drmAgpFree",
-    "drmAgpGetMode",
-    "drmAgpRelease",
-    "drmAgpUnbind",
-    "drmAgpVendorId",
-    "drmCommandNone",
-    "drmCommandRead",
-    "drmCommandWrite",
-    "drmCommandWriteRead",
-    "drmDMA",
-    "drmFreeVersion",
-    "drmGetLibVersion",
-    "drmGetVersion",
-    "drmMap",
-    "drmMapBufs",
-    "drmRadeonCleanupCP",
-    "drmRadeonClear",
-    "drmRadeonFlushIndirectBuffer",
-    "drmRadeonInitCP",
-    "drmRadeonResetCP",
-    "drmRadeonStartCP",
-    "drmRadeonStopCP",
-    "drmRadeonWaitForIdleCP",
-    "drmScatterGatherAlloc",
-    "drmScatterGatherFree",
-    "drmUnmap",
-    "drmUnmapBufs",
-    NULL
-};
-
-static const char *driSymbols[] = {
-    "DRICloseScreen",
-    "DRICreateInfoRec",
-    "DRIDestroyInfoRec",
-    "DRIFinishScreenInit",
-    "DRIGetContext",
-    "DRIGetDeviceInfo",
-    "DRIGetSAREAPrivate",
-    "DRILock",
-    "DRIQueryVersion",
-    "DRIScreenInit",
-    "DRIUnlock",
-    "GlxSetVisualConfigs",
-    "DRICreatePCIBusID",
-    NULL
-};
-#endif
-
-static const char *vbeSymbols[] = {
-    "VBEInit",
-    "vbeDoEDID",
-    NULL
-};
-
-static const char *int10Symbols[] = {
-    "xf86InitInt10",
-    "xf86FreeInt10",
-    "xf86int10Addr",
-    "xf86ExecX86int10",
-    NULL
-};
-
-static const char *i2cSymbols[] = {
-    "xf86CreateI2CBusRec",
-    "xf86I2CBusInit",
-    NULL
-};
-
-void RADEONLoaderRefSymLists(void)
-{
-    /*
-     * Tell the loader about symbols from other modules that this module might
-     * refer to.
-     */
-    xf86LoaderRefSymLists(
-#ifdef WITH_VGAHW
-			  vgahwSymbols,
-#endif
-			  fbSymbols,
-#ifdef USE_EXA
-			  exaSymbols,
-#endif
-#ifdef USE_XAA
-			  xaaSymbols,
-#endif
-#if 0
-			  xf8_32bppSymbols,
-#endif
-			  ramdacSymbols,
-#ifdef XF86DRI
-			  drmSymbols,
-			  driSymbols,
-#endif
-			  vbeSymbols,
-			  int10Symbols,
-			  i2cSymbols,
-			  ddcSymbols,
-			  NULL);
-}
-
-#ifdef XFree86LOADER
 static int getRADEONEntityIndex(void)
 {
     int *radeon_entity_index = LoaderSymbol("gRADEONEntityIndex");
@@ -388,13 +233,6 @@ static int getRADEONEntityIndex(void)
     else
         return *radeon_entity_index;
 }
-#else
-extern int gRADEONEntityIndex;
-static int getRADEONEntityIndex(void)
-{
-    return gRADEONEntityIndex;
-}
-#endif
 
 struct RADEONInt10Save {
 	CARD32 MEM_CNTL;
@@ -405,23 +243,41 @@ struct RADEONInt10Save {
 static Bool RADEONMapMMIO(ScrnInfoPtr pScrn);
 static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn);
 
-#if 0
+static void *
+radeonShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode,
+		   CARD32 *size, void *closure)
+{
+    ScrnInfoPtr pScrn = xf86Screens[screen->myNum];
+    RADEONInfoPtr  info   = RADEONPTR(pScrn);
+    int stride;
+
+    stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8;
+    *size = stride;
+
+    return ((CARD8 *)info->FB + pScrn->fbOffset +
+            row * stride + offset);
+}
 static Bool
 RADEONCreateScreenResources (ScreenPtr pScreen)
 {
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    RADEONInfoPtr  info   = RADEONPTR(pScrn);
+   PixmapPtr pixmap;
 
    pScreen->CreateScreenResources = info->CreateScreenResources;
    if (!(*pScreen->CreateScreenResources)(pScreen))
       return FALSE;
+   pScreen->CreateScreenResources = RADEONCreateScreenResources;
 
-   if (!xf86RandR12CreateScreenResources(pScreen))
-      return FALSE;
+   if (info->r600_shadow_fb) {
+       pixmap = pScreen->GetScreenPixmap(pScreen);
 
-  return TRUE;
+       if (!shadowAdd(pScreen, pixmap, shadowUpdatePackedWeak(),
+		      radeonShadowWindow, 0, NULL))
+	   return FALSE;
+   }
+   return TRUE;
 }
-#endif
 
 RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn)
 {
@@ -440,18 +296,20 @@ RADEONPreInt10Save(ScrnInfoPtr pScrn, void **pPtr)
     CARD32 CardTmp;
     static struct RADEONInt10Save SaveStruct = { 0, 0, 0 };
 
-    /* Save the values and zap MEM_CNTL */
-    SaveStruct.MEM_CNTL = INREG(RADEON_MEM_CNTL);
-    SaveStruct.MEMSIZE = INREG(RADEON_CONFIG_MEMSIZE);
-    SaveStruct.MPP_TB_CONFIG = INREG(RADEON_MPP_TB_CONFIG);
+    if (!IS_AVIVO_VARIANT) {
+	/* Save the values and zap MEM_CNTL */
+	SaveStruct.MEM_CNTL = INREG(RADEON_MEM_CNTL);
+	SaveStruct.MEMSIZE = INREG(RADEON_CONFIG_MEMSIZE);
+	SaveStruct.MPP_TB_CONFIG = INREG(RADEON_MPP_TB_CONFIG);
 
-    /*
-     * Zap MEM_CNTL and set MPP_TB_CONFIG<31:24> to 4
-     */
-    OUTREG(RADEON_MEM_CNTL, 0);
-    CardTmp = SaveStruct.MPP_TB_CONFIG & 0x00ffffffu;
-    CardTmp |= 0x04 << 24;
-    OUTREG(RADEON_MPP_TB_CONFIG, CardTmp);
+	/*
+	 * Zap MEM_CNTL and set MPP_TB_CONFIG<31:24> to 4
+	 */
+	OUTREG(RADEON_MEM_CNTL, 0);
+	CardTmp = SaveStruct.MPP_TB_CONFIG & 0x00ffffffu;
+	CardTmp |= 0x04 << 24;
+	OUTREG(RADEON_MPP_TB_CONFIG, CardTmp);
+    }
 
     *pPtr = (void *)&SaveStruct;
 }
@@ -468,6 +326,9 @@ RADEONPostInt10Check(ScrnInfoPtr pScrn, void *ptr)
     if (!pSave || !pSave->MEM_CNTL)
 	return;
 
+    if (IS_AVIVO_VARIANT)
+	return;
+
     /*
      * If either MEM_CNTL is currently zero or inconistent (configured for
      * two channels with the two channels configured differently), restore
@@ -718,6 +579,168 @@ void RADEONOUTPLL(ScrnInfoPtr pScrn, int addr, CARD32 data)
     RADEONPllErrataAfterData(info);
 }
 
+/* Read MC register */
+unsigned RADEONINMC(ScrnInfoPtr pScrn, int addr)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32         data;
+
+    if (info->ChipFamily == CHIP_FAMILY_RS690)
+    {
+        OUTREG(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK));
+        data = INREG(RS690_MC_DATA);
+    } else if (IS_AVIVO_VARIANT) {
+	OUTREG(AVIVO_MC_INDEX, (addr & 0xff) | 0x7f0000);
+	(void)INREG(AVIVO_MC_INDEX);
+	data = INREG(AVIVO_MC_DATA);
+
+	OUTREG(AVIVO_MC_INDEX, 0);
+	(void)INREG(AVIVO_MC_INDEX);
+    } else {
+	OUTREG(R300_MC_IND_INDEX, addr & 0x3f);
+	(void)INREG(R300_MC_IND_INDEX);
+	data = INREG(R300_MC_IND_DATA);
+	
+	OUTREG(R300_MC_IND_INDEX, 0);
+	(void)INREG(R300_MC_IND_INDEX);
+    }
+
+    return data;
+}
+
+/* Write MC information */
+void RADEONOUTMC(ScrnInfoPtr pScrn, int addr, CARD32 data)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    if (info->ChipFamily == CHIP_FAMILY_RS690)
+    {
+        OUTREG(RS690_MC_INDEX, ((addr & RS690_MC_INDEX_MASK) |
+                        RS690_MC_INDEX_WR_EN));
+        OUTREG(RS690_MC_DATA, data);
+        OUTREG(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK);
+    } else if (IS_AVIVO_VARIANT) {
+	OUTREG(AVIVO_MC_INDEX, (addr & 0xff) | 0xff0000);
+	(void)INREG(AVIVO_MC_INDEX);
+	OUTREG(AVIVO_MC_DATA, data);
+	OUTREG(AVIVO_MC_INDEX, 0);
+	(void)INREG(AVIVO_MC_INDEX);
+    } else {
+	OUTREG(R300_MC_IND_INDEX, (((addr) & 0x3f) |
+				   R300_MC_IND_WR_EN));
+	(void)INREG(R300_MC_IND_INDEX);
+	OUTREG(R300_MC_IND_DATA, data);
+	OUTREG(R300_MC_IND_INDEX, 0);
+	(void)INREG(R300_MC_IND_INDEX);
+    }
+}
+
+Bool avivo_get_mc_idle(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+
+    if (info->ChipFamily >= CHIP_FAMILY_R600) {
+	/* no idea where this is on r600 yet */
+	return TRUE;
+    } else if (info->ChipFamily == CHIP_FAMILY_RV515) {
+	if (INMC(pScrn, RV515_MC_STATUS) & RV515_MC_STATUS_IDLE)
+	    return TRUE;
+	else
+	    return FALSE;
+    } else if (info->ChipFamily == CHIP_FAMILY_RS690) {
+	if (INMC(pScrn, RS690_MC_STATUS) & RS690_MC_STATUS_IDLE)
+	    return TRUE;
+	else
+	    return FALSE;
+    } else {
+	if (INMC(pScrn, R520_MC_STATUS) & R520_MC_STATUS_IDLE)
+	    return TRUE;
+	else
+	    return FALSE;
+    }
+}
+
+#define LOC_FB 0x1
+#define LOC_AGP 0x2
+void radeon_write_mc_fb_agp_location(ScrnInfoPtr pScrn, int mask, CARD32 fb_loc, CARD32 agp_loc, CARD32 agp_loc_hi)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    if (info->ChipFamily >= CHIP_FAMILY_R600) {
+	if (mask & LOC_FB)
+	    OUTREG(R600_MC_VM_FB_LOCATION, fb_loc);
+	if (mask & LOC_AGP) {
+	    OUTREG(R600_MC_VM_AGP_BOT, agp_loc);
+	    OUTREG(R600_MC_VM_AGP_TOP, agp_loc_hi);
+	}
+    } else if (info->ChipFamily == CHIP_FAMILY_RV515) {
+	if (mask & LOC_FB)
+	    OUTMC(pScrn, RV515_MC_FB_LOCATION, fb_loc);
+	if (mask & LOC_AGP)
+	    OUTMC(pScrn, RV515_MC_AGP_LOCATION, agp_loc);
+	(void)INMC(pScrn, RV515_MC_AGP_LOCATION);
+    } else if (info->ChipFamily == CHIP_FAMILY_RS690) {
+	if (mask & LOC_FB)
+	    OUTMC(pScrn, RS690_MC_FB_LOCATION, fb_loc);
+	if (mask & LOC_AGP)
+	    OUTMC(pScrn, RS690_MC_AGP_LOCATION, agp_loc);
+    } else if (info->ChipFamily >= CHIP_FAMILY_R520) { 
+	if (mask & LOC_FB)
+	    OUTMC(pScrn, R520_MC_FB_LOCATION, fb_loc);
+	if (mask & LOC_AGP)
+	    OUTMC(pScrn, R520_MC_AGP_LOCATION, agp_loc);
+	(void)INMC(pScrn, R520_MC_FB_LOCATION);
+    } else {
+	if (mask & LOC_FB)
+	    OUTREG(RADEON_MC_FB_LOCATION, fb_loc);
+	if (mask & LOC_AGP)
+	    OUTREG(RADEON_MC_AGP_LOCATION, agp_loc);
+    }
+}
+
+void radeon_read_mc_fb_agp_location(ScrnInfoPtr pScrn, int mask, CARD32 *fb_loc, CARD32 *agp_loc, CARD32 *agp_loc_hi)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    if (info->ChipFamily >= CHIP_FAMILY_R600) {
+	if (mask & LOC_FB)
+	    *fb_loc = INREG(R600_MC_VM_FB_LOCATION);
+	if (mask & LOC_AGP) {
+	    *agp_loc = INREG(R600_MC_VM_AGP_BOT);
+	    *agp_loc_hi = INREG(R600_MC_VM_AGP_TOP);
+	}
+    } else if (info->ChipFamily == CHIP_FAMILY_RV515) {
+	if (mask & LOC_FB)
+	    *fb_loc = INMC(pScrn, RV515_MC_FB_LOCATION);
+	if (mask & LOC_AGP) {
+	    *agp_loc = INMC(pScrn, RV515_MC_AGP_LOCATION);
+	    *agp_loc_hi = 0;
+	}
+    } else if (info->ChipFamily == CHIP_FAMILY_RS690) {
+	if (mask & LOC_FB)
+	    *fb_loc = INMC(pScrn, RS690_MC_FB_LOCATION);
+	if (mask & LOC_AGP) {
+	    *agp_loc = INMC(pScrn, RS690_MC_AGP_LOCATION);
+	    *agp_loc_hi = 0;
+	}
+    } else if (info->ChipFamily >= CHIP_FAMILY_R520) {
+	if (mask & LOC_FB)
+	    *fb_loc = INMC(pScrn, R520_MC_FB_LOCATION);
+	if (mask & LOC_AGP) {
+	    *agp_loc = INMC(pScrn, R520_MC_AGP_LOCATION);
+	    *agp_loc_hi = 0;
+	}
+    } else {
+	if (mask & LOC_FB)
+	    *fb_loc = INREG(RADEON_MC_FB_LOCATION);
+	if (mask & LOC_AGP)
+	    *agp_loc = INREG(RADEON_MC_AGP_LOCATION);
+    }
+}
 
 #if 0
 /* Read PAL information (only used for debugging) */
@@ -979,7 +1002,7 @@ static Bool RADEONProbePLLParameters(ScrnInfoPtr pScrn)
     case 2: info->sclk = spll / 2.0; break;
     case 3: info->sclk = spll / 4.0; break;
     case 4: info->sclk = spll / 8.0; break;
-    case 7: info->sclk = mpll;
+    case 7: info->sclk = mpll; break;
     default:
            info->sclk = 200.00;
            xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unsupported SCLK source"
@@ -1000,7 +1023,6 @@ static Bool RADEONProbePLLParameters(ScrnInfoPtr pScrn)
 static void RADEONGetClockInfo(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info = RADEONPTR (pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     RADEONPLLPtr pll = &info->pll;
     double min_dotclock;
 
@@ -1022,49 +1044,56 @@ static void RADEONGetClockInfo(ScrnInfoPtr pScrn)
 
 	    if (pll->reference_div < 2) pll->reference_div = 12;
 	}
-	
     } else {
 	xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
 		    "Video BIOS not detected, using default clock settings!\n");
 
        /* Default min/max PLL values */
        if (info->ChipFamily == CHIP_FAMILY_R420 || info->ChipFamily == CHIP_FAMILY_RV410) {
-           pll->min_pll_freq = 20000;
-           pll->max_pll_freq = 50000;
+	   pll->pll_in_min = 100;
+	   pll->pll_in_max = 1350;
+	   pll->pll_out_min = 20000;
+	   pll->pll_out_max = 50000;
        } else {
-           pll->min_pll_freq = 12500;
-           pll->max_pll_freq = 35000;
+	   pll->pll_in_min = 40;
+	   pll->pll_in_max = 500;
+	   pll->pll_out_min = 12500;
+	   pll->pll_out_max = 35000;
        }
 
-       if (RADEONProbePLLParameters(pScrn))
-            return;
+       if (!RADEONProbePLLParameters(pScrn)) {
+	   if (info->IsIGP)
+	       pll->reference_freq = 1432;
+	   else
+	       pll->reference_freq = 2700;
 
-	if (info->IsIGP)
-	    pll->reference_freq = 1432;
-	else
-	    pll->reference_freq = 2700;
-
-	pll->reference_div = 12;
-	pll->xclk = 10300;
+	   pll->reference_div = 12;
+	   pll->xclk = 10300;
 
-        info->sclk = 200.00;
-        info->mclk = 200.00;
+	   info->sclk = 200.00;
+	   info->mclk = 200.00;
+       }
     }
 
     /* card limits for computing PLLs */
+    if (IS_AVIVO_VARIANT) {
+	pll->min_post_div = 2;
+	pll->max_post_div = 0x7f;
+    } else {
+	pll->min_post_div = 1;
+	pll->max_post_div = 12; //16 on crtc0
+    }
     pll->min_ref_div = 2;
     pll->max_ref_div = 0x3ff;
     pll->min_feedback_div = 4;
     pll->max_feedback_div = 0x7ff;
-    pll->pll_in_min = 40;
-    pll->pll_in_max = 500;
     pll->best_vco = 0;
 
     xf86DrvMsg (pScrn->scrnIndex, X_INFO,
 		"PLL parameters: rf=%u rd=%u min=%u max=%u; xclk=%u\n",
 		pll->reference_freq,
 		pll->reference_div,
-		(unsigned)pll->min_pll_freq, (unsigned)pll->max_pll_freq,
+		(unsigned)pll->pll_out_min, (unsigned)pll->pll_out_max,
 		pll->xclk);
 
     /* (Some?) Radeon BIOSes seem too lie about their minimum dot
@@ -1073,7 +1102,7 @@ static void RADEONGetClockInfo(ScrnInfoPtr pScrn)
      */
     if (xf86GetOptValFreq(info->Options, OPTION_MIN_DOTCLOCK,
 			  OPTUNITS_MHZ, &min_dotclock)) {
-	if (min_dotclock < 12 || min_dotclock*100 >= pll->max_pll_freq) {
+	if (min_dotclock < 12 || min_dotclock*100 >= pll->pll_out_max) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		       "Illegal minimum dotclock specified %.2f MHz "
 		       "(option ignored)\n",
@@ -1082,8 +1111,8 @@ static void RADEONGetClockInfo(ScrnInfoPtr pScrn)
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		       "Forced minimum dotclock to %.2f MHz "
 		       "(instead of detected %.2f MHz)\n",
-		       min_dotclock, ((double)pll->min_pll_freq/1000));
-	    pll->min_pll_freq = min_dotclock * 1000;
+		       min_dotclock, ((double)pll->pll_out_min/1000));
+	    pll->pll_out_min = min_dotclock * 1000;
 	}
     }
 }
@@ -1184,9 +1213,14 @@ void RADEONInitMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
 {
     save->mc_fb_location = info->mc_fb_location;
     save->mc_agp_location = info->mc_agp_location;
-    save->display_base_addr = info->fbLocation;
-    save->display2_base_addr = info->fbLocation;
-    save->ov0_base_addr = info->fbLocation;
+
+    if (IS_AVIVO_VARIANT) {
+	save->mc_agp_location_hi = info->mc_agp_location_hi;
+    } else {
+	save->display_base_addr = info->fbLocation;
+	save->display2_base_addr = info->fbLocation;
+	save->ov0_base_addr = info->fbLocation;
+    }
 }
 
 static void RADEONInitMemoryMap(ScrnInfoPtr pScrn)
@@ -1196,17 +1230,22 @@ static void RADEONInitMemoryMap(ScrnInfoPtr pScrn)
     CARD32 mem_size;
     CARD32 aper_size;
 
-    /* Default to existing values */
-    info->mc_fb_location = INREG(RADEON_MC_FB_LOCATION);
-    info->mc_agp_location = INREG(RADEON_MC_AGP_LOCATION);
+    radeon_read_mc_fb_agp_location(pScrn, LOC_FB | LOC_AGP, &info->mc_fb_location,
+				   &info->mc_agp_location, &info->mc_agp_location_hi);
 
     /* We shouldn't use info->videoRam here which might have been clipped
      * but the real video RAM instead
      */
-    mem_size = INREG(RADEON_CONFIG_MEMSIZE);
-    aper_size = INREG(RADEON_CONFIG_APER_SIZE);
+    if (info->ChipFamily >= CHIP_FAMILY_R600) {
+	mem_size = INREG(R600_CONFIG_MEMSIZE);
+	aper_size = INREG(R600_CONFIG_APER_SIZE);
+    } else {
+	mem_size = INREG(RADEON_CONFIG_MEMSIZE);
+	aper_size = INREG(RADEON_CONFIG_APER_SIZE);
+    }
+
     if (mem_size == 0)
-	    mem_size = 0x800000;
+	mem_size = 0x800000;
 
     /* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM - 
        Novell bug 204882 + along with lots of ubuntu ones */
@@ -1221,7 +1260,7 @@ static void RADEONInitMemoryMap(ScrnInfoPtr pScrn)
     }
 #endif
 
-    {
+    if (info->ChipFamily != CHIP_FAMILY_RS690) {
 	if (info->IsIGP)
 	    info->mc_fb_location = INREG(RADEON_NB_TOM);
 	else
@@ -1233,7 +1272,13 @@ static void RADEONInitMemoryMap(ScrnInfoPtr pScrn)
 	else
 #endif
 	{
-	    CARD32 aper0_base = INREG(RADEON_CONFIG_APER_0_BASE);
+	    CARD32 aper0_base;
+
+	    if (info->ChipFamily >= CHIP_FAMILY_R600) {
+		aper0_base = INREG(R600_CONFIG_F0_BASE);
+	    } else {
+		aper0_base = INREG(RADEON_CONFIG_APER_0_BASE);
+	    }
 
 	    /* Recent chips have an "issue" with the memory controller, the
 	     * location must be aligned to the size. We just align it down,
@@ -1250,17 +1295,30 @@ static void RADEONInitMemoryMap(ScrnInfoPtr pScrn)
 		info->ChipFamily == CHIP_FAMILY_RV410)
 		    aper0_base &= ~(mem_size - 1);
 
-	    info->mc_fb_location = (aper0_base >> 16) |
+	    if (info->ChipFamily >= CHIP_FAMILY_R600) {
+		info->mc_fb_location = (aper0_base >> 24) |
+		    (((aper0_base + mem_size - 1) & 0xff000000U) >> 8);
+		ErrorF("mc fb loc is %08x\n", (unsigned int)info->mc_fb_location);
+	    } else {
+		info->mc_fb_location = (aper0_base >> 16) |
 		    ((aper0_base + mem_size - 1) & 0xffff0000U);
+	    }
 	}
     }
-    info->fbLocation = (info->mc_fb_location & 0xffff) << 16;
-   
+    if (info->ChipFamily >= CHIP_FAMILY_R600) {
+	info->fbLocation = (info->mc_fb_location & 0xffff) << 24;
+    } else {
+   	info->fbLocation = (info->mc_fb_location & 0xffff) << 16;
+    }
     /* Just disable the damn AGP apertures for now, it may be
      * re-enabled later by the DRM
      */
-    info->mc_agp_location = 0xffffffc0;
 
+    if (IS_AVIVO_VARIANT) {
+        OUTREG(AVIVO_HDP_FB_LOCATION, info->mc_fb_location);
+    	info->mc_agp_location = 0x003f0000;
+    } else
+    	info->mc_agp_location = 0xffffffc0;
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	       "RADEONInitMemoryMap() : \n");
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -1322,9 +1380,14 @@ static CARD32 RADEONGetAccessibleVRAM(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info   = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    CARD32	   aper_size = INREG(RADEON_CONFIG_APER_SIZE) / 1024;
+    CARD32	   aper_size;
     unsigned char  byte;
 
+    if (info->ChipFamily >= CHIP_FAMILY_R600)
+	aper_size = INREG(R600_CONFIG_APER_SIZE) / 1024;
+    else
+	aper_size = INREG(RADEON_CONFIG_APER_SIZE) / 1024;
+
 #ifdef XF86DRI
     /* If we use the DRI, we need to check if it's a version that has the
      * bug of always cropping MC_FB_LOCATION to one aperture, in which case
@@ -1352,7 +1415,8 @@ static CARD32 RADEONGetAccessibleVRAM(ScrnInfoPtr pScrn)
 	info->ChipFamily == CHIP_FAMILY_RV350 ||
 	info->ChipFamily == CHIP_FAMILY_RV380 ||
 	info->ChipFamily == CHIP_FAMILY_R420 ||
-	info->ChipFamily == CHIP_FAMILY_RV410) {
+	info->ChipFamily == CHIP_FAMILY_RV410 ||
+        IS_AVIVO_VARIANT) {
 	    OUTREGP (RADEON_HOST_PATH_CNTL, RADEON_HDP_APER_CNTL,
 		     ~RADEON_HDP_APER_CNTL);
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -1391,7 +1455,9 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn)
     MessageType    from = X_PROBED;
     CARD32         accessible, bar_size;
 
-    if ((info->IsIGP)) {
+    if (info->ChipFamily == CHIP_FAMILY_RS690) {
+	pScrn->videoRam = INREG(RADEON_CONFIG_MEMSIZE);
+    } else if (info->IsIGP) {
         CARD32 tom = INREG(RADEON_NB_TOM);
 
 	pScrn->videoRam = (((tom >> 16) -
@@ -1399,13 +1465,18 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn)
 
 	OUTREG(RADEON_CONFIG_MEMSIZE, pScrn->videoRam * 1024);
     } else {
-	/* Read VRAM size from card */
-        pScrn->videoRam      = INREG(RADEON_CONFIG_MEMSIZE) / 1024;
-
-	/* Some production boards of m6 will return 0 if it's 8 MB */
-	if (pScrn->videoRam == 0) {
-	    pScrn->videoRam = 8192;
-	    OUTREG(RADEON_CONFIG_MEMSIZE, 0x800000);
+	
+	if (info->ChipFamily >= CHIP_FAMILY_R600)
+	    pScrn->videoRam = INREG(R600_CONFIG_MEMSIZE) / 1024;
+	else {
+	    /* Read VRAM size from card */
+	    pScrn->videoRam      = INREG(RADEON_CONFIG_MEMSIZE) / 1024;
+	    
+	    /* Some production boards of m6 will return 0 if it's 8 MB */
+	    if (pScrn->videoRam == 0) {
+		pScrn->videoRam = 8192;
+		OUTREG(RADEON_CONFIG_MEMSIZE, 0x800000);
+	    }
 	}
     }
 
@@ -1425,7 +1496,8 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn)
     if (pScrn->videoRam > accessible)
 	pScrn->videoRam = accessible;
 
-    info->MemCntl            = INREG(RADEON_SDRAM_MODE_REG);
+    if (!IS_AVIVO_VARIANT)
+	info->MemCntl            = INREG(RADEON_SDRAM_MODE_REG);
     info->BusCntl            = INREG(RADEON_BUS_CNTL);
 
     RADEONGetVRamType(pScrn);
@@ -1442,6 +1514,21 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn)
     xf86DrvMsg(pScrn->scrnIndex, from,
 	       "Mapped VideoRAM: %d kByte (%d bit %s SDRAM)\n", pScrn->videoRam, info->RamWidth, info->IsDDR?"DDR":"SDR");
 
+    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;
 
@@ -1550,6 +1637,15 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
 	break;
     }
 
+    if (info->ChipFamily >= CHIP_FAMILY_R600) {
+        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                   "R600 support is mostly incomplete and very experimental\n");
+    }
+
+    if ((info->ChipFamily >= CHIP_FAMILY_RV515) && (info->ChipFamily < CHIP_FAMILY_R600)) {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                   "R500 support is under development. Please report any issues to xorg-driver-ati@lists.x.org\n");
+    }
 
     from               = X_PROBED;
     info->LinearAddr   = PCI_REGION_BASE(info->PciInfo, 0, REGION_MEM) & ~0x1ffffffUL;
@@ -1705,6 +1801,13 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
 					     info->Chipset != PCI_CHIP_RN50_5969);
 #endif
 
+    if (info->ChipFamily >= CHIP_FAMILY_R600) {
+        info->r600_shadow_fb = TRUE;
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                   "using shadow framebuffer\n");
+        if (!xf86LoadSubModule(pScrn, "shadow"))
+            return FALSE;
+    }
     return TRUE;
 }
 
@@ -1719,16 +1822,13 @@ static void RADEONPreInitDDC(ScrnInfoPtr pScrn)
     if (!xf86LoadSubModule(pScrn, "ddc")) {
 	info->ddc2 = FALSE;
     } else {
-	xf86LoaderReqSymLists(ddcSymbols, NULL);
 	info->ddc2 = TRUE;
     }
 
     /* DDC can use I2C bus */
     /* Load I2C if we have the code to use it */
     if (info->ddc2) {
-	if (xf86LoadSubModule(pScrn, "i2c")) {
-	    xf86LoaderReqSymLists(i2cSymbols,NULL);
-	}
+	xf86LoadSubModule(pScrn, "i2c");
     }
 }
 
@@ -1748,7 +1848,6 @@ static Bool RADEONPreInitCursor(ScrnInfoPtr pScrn)
 
     if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
 	if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE;
-	xf86LoaderReqSymLists(ramdacSymbols, NULL);
     }
     return TRUE;
 }
@@ -1756,7 +1855,6 @@ static Bool RADEONPreInitCursor(ScrnInfoPtr pScrn)
 /* This is called by RADEONPreInit to initialize hardware acceleration */
 static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn)
 {
-#ifdef XFree86LOADER
     RADEONInfoPtr  info = RADEONPTR(pScrn);
     MessageType from;
 #if defined(USE_EXA) && defined(USE_XAA)
@@ -1765,6 +1863,12 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn)
 
     info->useEXA = FALSE;
 
+    if (info->ChipFamily >= CHIP_FAMILY_R600) {
+	xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
+	    "No acceleration support available on R600 yet.\n");
+	return TRUE;
+    }
+
     if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
 	int errmaj = 0, errmin = 0;
 
@@ -1798,7 +1902,6 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn)
 		LoaderErrorMsg(NULL, "exa", errmaj, errmin);
 		return FALSE;
 	    }
-	    xf86LoaderReqSymLists(exaSymbols, NULL);
 	}
 #endif /* USE_EXA */
 #ifdef USE_XAA
@@ -1821,25 +1924,21 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn)
 		    }
 		}
 	    }
-	    xf86LoaderReqSymLists(xaaSymbols, NULL);
 	}
 #endif /* USE_XAA */
     }
-#endif /* XFree86Loader */
 
     return TRUE;
 }
 
 static Bool RADEONPreInitInt10(ScrnInfoPtr pScrn, xf86Int10InfoPtr *ppInt10)
 {
-#if !defined(__powerpc__)
+#if !defined(__powerpc__) && !defined(__sparc__)
     RADEONInfoPtr  info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32 fp2_gen_ctl_save   = 0;
 
     if (xf86LoadSubModule(pScrn, "int10")) {
-	xf86LoaderReqSymLists(int10Symbols, NULL);
-
 	/* The VGA BIOS on the RV100/QY cannot be read when the digital output
 	 * is enabled.  Clear and restore FP2_ON around int10 to avoid this.
 	 */
@@ -1877,19 +1976,32 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn)
     info->pLibDRMVersion = NULL;
     info->pKernelDRMVersion = NULL;
 
+   if (xf86IsEntityShared(info->pEnt->index)) {
+        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                   "Direct Rendering Disabled -- "
+                   "Dual-head configuration is not working with "
+                   "DRI at present.\n"
+                   "Please use the radeon MergedFB option if you "
+                   "want Dual-head with DRI.\n");
+        return FALSE;
+    }
+    if (info->IsSecondary)
+        return FALSE;
+
     if (info->Chipset == PCI_CHIP_RN50_515E ||
 	info->Chipset == PCI_CHIP_RN50_5969 ||
 	info->Chipset == PCI_CHIP_RC410_5A61 ||
 	info->Chipset == PCI_CHIP_RC410_5A62 ||
-	info->Chipset == PCI_CHIP_RS485_5975) {
+	info->Chipset == PCI_CHIP_RS485_5975 ||
+	info->ChipFamily >= CHIP_FAMILY_R600) {
     	if (xf86ReturnOptValBool(info->Options, OPTION_DRI, FALSE)) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		"Direct rendering for RN50/RC410/RS485 forced on -- "
+		"Direct rendering for RN50/RC410/RS485/R600 forced on -- "
 		"This is NOT officially supported at the hardware level "
 		"and may cause instability or lockups\n");
     	} else {
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		"Direct rendering not officially supported on RN50/RC410\n");
+		"Direct rendering not officially supported on RN50/RC410/R600\n");
 	    return FALSE;
 	}
     }
@@ -2075,7 +2187,7 @@ static void RADEONPreInitColorTiling(ScrnInfoPtr pScrn)
 
     info->allowColorTiling = xf86ReturnOptValBool(info->Options,
 				        OPTION_COLOR_TILING, TRUE);
-    if (IS_R300_VARIANT) {
+    if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
 	/* this may be 4096 on r4xx -- need to double check */
 	info->MaxSurfaceWidth = 3968; /* one would have thought 4096...*/
 	info->MaxLines = 4096;
@@ -2087,6 +2199,13 @@ static void RADEONPreInitColorTiling(ScrnInfoPtr pScrn)
     if (!info->allowColorTiling)
 	return;
 
+    if (info->ChipFamily >= CHIP_FAMILY_R600)
+	info->allowColorTiling = FALSE;
+
+    /* for zaphod disable tiling for now */
+    if (info->IsPrimary || info->IsSecondary)
+	info->allowColorTiling = FALSE;
+
 #ifdef XF86DRI
     if (info->directRenderingEnabled &&
 	info->pKernelDRMVersion->version_minor < 14) {
@@ -2307,12 +2426,39 @@ static void RADEONPreInitBIOS(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
 #endif
 }
 
+static void RADEONFixZaphodOutputs(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
+
+    if (info->IsPrimary) {
+	xf86OutputDestroy(config->output[0]);
+	while(config->num_output > 1) {
+	    xf86OutputDestroy(config->output[1]);
+	}
+    } else {
+	while(config->num_output > 1) {
+	    xf86OutputDestroy(config->output[1]);
+	}
+    }
+}
+
 static Bool RADEONPreInitControllers(ScrnInfoPtr pScrn)
 {
     xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
+    RADEONInfoPtr info = RADEONPTR(pScrn);
     int i;
+    int mask;
+    int found = 0;
 
-    if (!RADEONAllocateControllers(pScrn))
+    if (!info->IsPrimary && !info->IsSecondary)
+	mask = 3;
+    else if (info->IsPrimary)
+	mask = 1;
+    else
+	mask = 2;
+	
+    if (!RADEONAllocateControllers(pScrn, mask))
 	return FALSE;
 
     RADEONGetClockInfo(pScrn);
@@ -2320,16 +2466,34 @@ static Bool RADEONPreInitControllers(ScrnInfoPtr pScrn)
     if (!RADEONSetupConnectors(pScrn)) {
 	return FALSE;
     }
+
+    if (info->IsPrimary || info->IsSecondary) {
+	/* fixup outputs for zaphod */
+	RADEONFixZaphodOutputs(pScrn);
+    }
       
     RADEONPrintPortMap(pScrn);
 
-    for (i = 0; i < config->num_output; i++) 
-    {
-      xf86OutputPtr	      output = config->output[i];
+    info->first_load_no_devices = FALSE;
+    for (i = 0; i < config->num_output; i++) {
+	xf86OutputPtr	      output = config->output[i];
       
-      output->status = (*output->funcs->detect) (output);
-      ErrorF("finished output detect: %d\n", i);
+	output->status = (*output->funcs->detect) (output);
+	ErrorF("finished output detect: %d\n", i);
+	if (info->IsPrimary || info->IsSecondary) {
+	    if (output->status != XF86OutputStatusConnected)
+		return FALSE;
+	}
+	if (output->status != XF86OutputStatusDisconnected)
+	    found++;
     }
+
+    if (!found) {
+	/* nothing connected, light up some defaults so the server comes up */
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No connected devices found!\n");
+	info->first_load_no_devices = TRUE;
+    }
+
     ErrorF("finished all detect\n");
     return TRUE;
 }
@@ -2358,7 +2522,7 @@ static const xf86CrtcConfigFuncsRec RADEONCRTCResizeFuncs = {
     RADEONCRTCResize
 };
 
-_X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
+Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
 {
     xf86CrtcConfigPtr   xf86_config;
     RADEONInfoPtr     info;
@@ -2366,6 +2530,8 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
     void *int10_save = NULL;
     const char *s;
     int crtc_max_X, crtc_max_Y;
+    RADEONEntPtr pRADEONEnt;
+    DevUnion* pPriv;
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONPreInit\n");
@@ -2376,9 +2542,39 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
     info               = RADEONPTR(pScrn);
     info->MMIO         = NULL;
 
+    info->IsSecondary  = FALSE;
+    info->IsPrimary = FALSE;
+
     info->pEnt         = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
     if (info->pEnt->location.type != BUS_PCI) goto fail;
 
+    pPriv = xf86GetEntityPrivate(pScrn->entityList[0], 
+				 getRADEONEntityIndex());
+    pRADEONEnt = pPriv->ptr;
+
+    if(xf86IsEntityShared(pScrn->entityList[0]))
+    {
+        if(xf86IsPrimInitDone(pScrn->entityList[0]))
+        {
+            info->IsSecondary = TRUE;
+            pRADEONEnt->pSecondaryScrn = pScrn;
+	    info->SavedReg = &pRADEONEnt->SavedReg;
+	    info->ModeReg = &pRADEONEnt->ModeReg;
+        }
+        else
+        {
+	    info->IsPrimary = TRUE;
+            xf86SetPrimInitDone(pScrn->entityList[0]);
+            pRADEONEnt->pPrimaryScrn = pScrn;
+            pRADEONEnt->HasSecondary = FALSE;
+	    info->SavedReg = &pRADEONEnt->SavedReg;
+	    info->ModeReg = &pRADEONEnt->ModeReg;
+        }
+    } else {
+	info->SavedReg = &pRADEONEnt->SavedReg;
+	info->ModeReg = &pRADEONEnt->ModeReg;
+    }
+
     info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
     info->PciTag  = pciTag(PCI_DEV_BUS(info->PciInfo),
 			   PCI_DEV_DEV(info->PciInfo),
@@ -2460,8 +2656,8 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
     memcpy(info->Options, RADEONOptions, sizeof(RADEONOptions));
     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options);
 
-    /* By default, don't do VGA IOs on ppc */
-#if defined(__powerpc__) || !defined(WITH_VGAHW)
+    /* By default, don't do VGA IOs on ppc/sparc */
+#if defined(__powerpc__) || defined(__sparc__) || !defined(WITH_VGAHW)
     info->VGAAccess = FALSE;
 #else
     info->VGAAccess = TRUE;
@@ -2473,7 +2669,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
        if (!xf86LoadSubModule(pScrn, "vgahw"))
            info->VGAAccess = FALSE;
         else {
-           xf86LoaderReqSymLists(vgahwSymbols, NULL);
             if (!vgaHWGetHWRec(pScrn))
                info->VGAAccess = FALSE;
        }
@@ -2545,7 +2740,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
 	    crtc_max_X = 1600;
 	    crtc_max_Y = 1200;
 	} else {
-	    if (IS_R300_VARIANT) {
+	    if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
 		crtc_max_X = 2560;
 		crtc_max_Y = 1200;
 	    } else {
@@ -2589,8 +2784,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
 	/* Get ScreenInit function */
     if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
 
-    xf86LoaderReqSymLists(fbSymbols, NULL);
-
     if (!RADEONPreInitGamma(pScrn))              goto fail;
 
     if (!RADEONPreInitCursor(pScrn))             goto fail;
@@ -2610,11 +2803,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
       goto fail;
    }
 
-    /* Free the video bios (if applicable) */
-    //if (info->VBIOS) {
-    //xfree(info->VBIOS);
-    //info->VBIOS = NULL;
-    //}
 
 				/* Free int10 info */
     if (pInt10)
@@ -2726,10 +2914,11 @@ static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors,
 
 	      /* Make the change through RandR */
 #ifdef RANDR_12_INTERFACE
-      RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
-#else
-      crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
+	  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);
       }
     }
 
@@ -2762,343 +2951,6 @@ static void RADEONBlockHandler(int i, pointer blockData,
 #endif
 }
 
-
-#ifdef USE_XAA
-#ifdef XF86DRI
-Bool RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen)
-{
-    ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];
-    RADEONInfoPtr  info  = RADEONPTR(pScrn);
-    int            cpp = info->CurrentLayout.pixel_bytes;
-    int            depthCpp = (info->depthBits - 8) / 4;
-    int            width_bytes = pScrn->displayWidth * cpp;
-    int            bufferSize;
-    int            depthSize;
-    int            l;
-    int            scanlines;
-    int            texsizerequest;
-    BoxRec         MemBox;
-    FBAreaPtr      fbarea;
-
-    info->frontOffset = 0;
-    info->frontPitch = pScrn->displayWidth;
-    info->backPitch = pScrn->displayWidth;
-
-    /* make sure we use 16 line alignment for tiling (8 might be enough).
-     * Might need that for non-XF86DRI too?
-     */
-    if (info->allowColorTiling) {
-	bufferSize = (((pScrn->virtualY + 15) & ~15) * width_bytes
-		      + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN;
-    } else {
-        bufferSize = (pScrn->virtualY * width_bytes
-		      + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN;
-    }
-
-    /* Due to tiling, the Z buffer pitch must be a multiple of 32 pixels,
-     * which is always the case if color tiling is used due to color pitch
-     * but not necessarily otherwise, and its height a multiple of 16 lines.
-     */
-    info->depthPitch = (pScrn->displayWidth + 31) & ~31;
-    depthSize = ((((pScrn->virtualY + 15) & ~15) * info->depthPitch
-		  * depthCpp + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN);
-
-    switch (info->CPMode) {
-    case RADEON_DEFAULT_CP_PIO_MODE:
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in PIO mode\n");
-	break;
-    case RADEON_DEFAULT_CP_BM_MODE:
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in BM mode\n");
-	break;
-    default:
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in UNKNOWN mode\n");
-	break;
-    }
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "Using %d MB GART aperture\n", info->gartSize);
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "Using %d MB for the ring buffer\n", info->ringSize);
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "Using %d MB for vertex/indirect buffers\n", info->bufSize);
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "Using %d MB for GART textures\n", info->gartTexSize);
-
-    /* Try for front, back, depth, and three framebuffers worth of
-     * pixmap cache.  Should be enough for a fullscreen background
-     * image plus some leftovers.
-     * If the FBTexPercent option was used, try to achieve that percentage instead,
-     * but still have at least one pixmap buffer (get problems with xvideo/render
-     * otherwise probably), and never reserve more than 3 offscreen buffers as it's
-     * probably useless for XAA.
-     */
-    if (info->textureSize >= 0) {
-	texsizerequest = ((int)info->FbMapSize - 2 * bufferSize - depthSize
-			 - 2 * width_bytes - 16384 - info->FbSecureSize)
-	/* first divide, then multiply or we'll get an overflow (been there...) */
-			 / 100 * info->textureSize;
-    }
-    else {
-	texsizerequest = (int)info->FbMapSize / 2;
-    }
-    info->textureSize = info->FbMapSize - info->FbSecureSize - 5 * bufferSize - depthSize;
-
-    /* If that gives us less than the requested memory, let's
-     * be greedy and grab some more.  Sorry, I care more about 3D
-     * performance than playing nicely, and you'll get around a full
-     * framebuffer's worth of pixmap cache anyway.
-     */
-    if (info->textureSize < texsizerequest) {
-        info->textureSize = info->FbMapSize - 4 * bufferSize - depthSize;
-    }
-    if (info->textureSize < texsizerequest) {
-        info->textureSize = info->FbMapSize - 3 * bufferSize - depthSize;
-    }
-
-    /* If there's still no space for textures, try without pixmap cache, but
-     * never use the reserved space, the space hw cursor and PCIGART table might
-     * use.
-     */
-    if (info->textureSize < 0) {
-	info->textureSize = info->FbMapSize - 2 * bufferSize - depthSize
-	                    - 2 * width_bytes - 16384 - info->FbSecureSize;
-    }
-
-    /* Check to see if there is more room available after the 8192nd
-     * scanline for textures
-     */
-    /* FIXME: what's this good for? condition is pretty much impossible to meet */
-    if ((int)info->FbMapSize - 8192*width_bytes - bufferSize - depthSize
-	> info->textureSize) {
-	info->textureSize =
-		info->FbMapSize - 8192*width_bytes - bufferSize - depthSize;
-    }
-
-    /* If backbuffer is disabled, don't allocate memory for it */
-    if (info->noBackBuffer) {
-	info->textureSize += bufferSize;
-    }
-
-    /* RADEON_BUFFER_ALIGN is not sufficient for backbuffer!
-       At least for pageflip + color tiling, need to make sure it's 16 scanlines aligned,
-       otherwise the copy-from-front-to-back will fail (width_bytes * 16 will also guarantee
-       it's still 4kb aligned for tiled case). Need to round up offset (might get into cursor
-       area otherwise).
-       This might cause some space at the end of the video memory to be unused, since it
-       can't be used (?) due to that log_tex_granularity thing???
-       Could use different copyscreentoscreen function for the pageflip copies
-       (which would use different src and dst offsets) to avoid this. */   
-    if (info->allowColorTiling && !info->noBackBuffer) {
-	info->textureSize = info->FbMapSize - ((info->FbMapSize - info->textureSize +
-			  width_bytes * 16 - 1) / (width_bytes * 16)) * (width_bytes * 16);
-    }
-    if (info->textureSize > 0) {
-	l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS);
-	if (l < RADEON_LOG_TEX_GRANULARITY)
-	    l = RADEON_LOG_TEX_GRANULARITY;
-	/* Round the texture size up to the nearest whole number of
-	 * texture regions.  Again, be greedy about this, don't
-	 * round down.
-	 */
-	info->log2TexGran = l;
-	info->textureSize = (info->textureSize >> l) << l;
-    } else {
-	info->textureSize = 0;
-    }
-
-    /* Set a minimum usable local texture heap size.  This will fit
-     * two 256x256x32bpp textures.
-     */
-    if (info->textureSize < 512 * 1024) {
-	info->textureOffset = 0;
-	info->textureSize = 0;
-    }
-
-    if (info->allowColorTiling && !info->noBackBuffer) {
-	info->textureOffset = ((info->FbMapSize - info->textureSize) /
-			       (width_bytes * 16)) * (width_bytes * 16);
-    }
-    else {
-	/* Reserve space for textures */
-	info->textureOffset = ((info->FbMapSize - info->textureSize +
-				RADEON_BUFFER_ALIGN) &
-			       ~(CARD32)RADEON_BUFFER_ALIGN);
-    }
-
-    /* Reserve space for the shared depth
-     * buffer.
-     */
-    info->depthOffset = ((info->textureOffset - depthSize +
-			  RADEON_BUFFER_ALIGN) &
-			 ~(CARD32)RADEON_BUFFER_ALIGN);
-
-    /* Reserve space for the shared back buffer */
-    if (info->noBackBuffer) {
-       info->backOffset = info->depthOffset;
-    } else {
-       info->backOffset = ((info->depthOffset - bufferSize +
-			    RADEON_BUFFER_ALIGN) &
-			   ~(CARD32)RADEON_BUFFER_ALIGN);
-    }
-
-    info->backY = info->backOffset / width_bytes;
-    info->backX = (info->backOffset - (info->backY * width_bytes)) / cpp;
-
-    scanlines = (info->FbMapSize-info->FbSecureSize) / width_bytes;
-    if (scanlines > 8191)
-	scanlines = 8191;
-
-    MemBox.x1 = 0;
-    MemBox.y1 = 0;
-    MemBox.x2 = pScrn->displayWidth;
-    MemBox.y2 = scanlines;
-
-    if (!xf86InitFBManager(pScreen, &MemBox)) {
-        xf86DrvMsg(scrnIndex, X_ERROR,
-		   "Memory manager initialization to "
-		   "(%d,%d) (%d,%d) failed\n",
-		   MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
-	return FALSE;
-    } else {
-	int  width, height;
-
-	xf86DrvMsg(scrnIndex, X_INFO,
-		   "Memory manager initialized to (%d,%d) (%d,%d)\n",
-		   MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
-	/* why oh why can't we just request modes which are guaranteed to be 16 lines
-	   aligned... sigh */
-	if ((fbarea = xf86AllocateOffscreenArea(pScreen,
-						pScrn->displayWidth,
-						info->allowColorTiling ? 
-						((pScrn->virtualY + 15) & ~15)
-						- pScrn->virtualY + 2 : 2,
-						0, NULL, NULL,
-						NULL))) {
-	    xf86DrvMsg(scrnIndex, X_INFO,
-		       "Reserved area from (%d,%d) to (%d,%d)\n",
-		       fbarea->box.x1, fbarea->box.y1,
-		       fbarea->box.x2, fbarea->box.y2);
-	} else {
-	    xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n");
-	}
-
-	RADEONDRIAllocatePCIGARTTable(pScreen);
-
-	if (xf86QueryLargestOffscreenArea(pScreen, &width,
-					  &height, 0, 0, 0)) {
-	    xf86DrvMsg(scrnIndex, X_INFO,
-		       "Largest offscreen area available: %d x %d\n",
-		       width, height);
-
-	    /* Lines in offscreen area needed for depth buffer and
-	     * textures
-	     */
-	    info->depthTexLines = (scanlines
-				   - info->depthOffset / width_bytes);
-	    info->backLines	    = (scanlines
-				       - info->backOffset / width_bytes
-				       - info->depthTexLines);
-	    info->backArea	    = NULL;
-	} else {
-	    xf86DrvMsg(scrnIndex, X_ERROR,
-		       "Unable to determine largest offscreen area "
-		       "available\n");
-	    return FALSE;
-	}
-    }
-
-    xf86DrvMsg(scrnIndex, X_INFO,
-	       "Will use front buffer at offset 0x%x\n",
-	       info->frontOffset);
-
-    xf86DrvMsg(scrnIndex, X_INFO,
-	       "Will use back buffer at offset 0x%x\n",
-	       info->backOffset);
-    xf86DrvMsg(scrnIndex, X_INFO,
-	       "Will use depth buffer at offset 0x%x\n",
-	       info->depthOffset);
-    if (info->cardType==CARD_PCIE)
-    	xf86DrvMsg(scrnIndex, X_INFO,
-	           "Will use %d kb for PCI GART table at offset 0x%x\n",
-		   info->pciGartSize/1024, (unsigned)info->pciGartOffset);
-    xf86DrvMsg(scrnIndex, X_INFO,
-	       "Will use %d kb for textures at offset 0x%x\n",
-	       info->textureSize/1024, info->textureOffset);
-
-    info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) |
-			      ((info->frontOffset + info->fbLocation) >> 10));
-
-    info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) |
-			     ((info->backOffset + info->fbLocation) >> 10));
-
-    info->depthPitchOffset = (((info->depthPitch * depthCpp / 64) << 22) |
-			      ((info->depthOffset + info->fbLocation) >> 10));
-    return TRUE;
-}
-#endif /* XF86DRI */
-
-Bool RADEONSetupMemXAA(int scrnIndex, ScreenPtr pScreen)
-{
-    ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];
-    RADEONInfoPtr  info  = RADEONPTR(pScrn);
-    BoxRec         MemBox;
-    int            y2;
-
-    int width_bytes = pScrn->displayWidth * info->CurrentLayout.pixel_bytes;
-
-    MemBox.x1 = 0;
-    MemBox.y1 = 0;
-    MemBox.x2 = pScrn->displayWidth;
-    y2 = info->FbMapSize / width_bytes;
-    if (y2 >= 32768)
-	y2 = 32767; /* because MemBox.y2 is signed short */
-    MemBox.y2 = y2;
-    
-    /* The acceleration engine uses 14 bit
-     * signed coordinates, so we can't have any
-     * drawable caches beyond this region.
-     */
-    if (MemBox.y2 > 8191)
-	MemBox.y2 = 8191;
-
-    if (!xf86InitFBManager(pScreen, &MemBox)) {
-	xf86DrvMsg(scrnIndex, X_ERROR,
-		   "Memory manager initialization to "
-		   "(%d,%d) (%d,%d) failed\n",
-		   MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
-	return FALSE;
-    } else {
-	int       width, height;
-	FBAreaPtr fbarea;
-
-	xf86DrvMsg(scrnIndex, X_INFO,
-		   "Memory manager initialized to (%d,%d) (%d,%d)\n",
-		   MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
-	if ((fbarea = xf86AllocateOffscreenArea(pScreen,
-						pScrn->displayWidth,
-						info->allowColorTiling ? 
-						((pScrn->virtualY + 15) & ~15)
-						- pScrn->virtualY + 2 : 2,
-						0, NULL, NULL,
-						NULL))) {
-	    xf86DrvMsg(scrnIndex, X_INFO,
-		       "Reserved area from (%d,%d) to (%d,%d)\n",
-		       fbarea->box.x1, fbarea->box.y1,
-		       fbarea->box.x2, fbarea->box.y2);
-	} else {
-	    xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n");
-	}
-	if (xf86QueryLargestOffscreenArea(pScreen, &width, &height,
-					      0, 0, 0)) {
-	    xf86DrvMsg(scrnIndex, X_INFO,
-		       "Largest offscreen area available: %d x %d\n",
-		       width, height);
-	}
-	return TRUE;
-    }    
-}
-#endif /* USE_XAA */
-
 static void
 RADEONPointerMoved(int index, int x, int y)
 {
@@ -3140,15 +2992,6 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
     char*          s;
 #endif
 
-#ifdef XF86DRI
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "RADEONScreenInit %lx %ld %d\n",
-		   pScrn->memPhysBase, pScrn->fbOffset, info->frontOffset);
-#else
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "RADEONScreenInit %lx %ld\n",
-		   pScrn->memPhysBase, pScrn->fbOffset);
-#endif
 
     info->accelOn      = FALSE;
 #ifdef USE_XAA
@@ -3158,6 +3001,16 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
     pScrn->fbOffset    = info->frontOffset;
 #endif
 
+    if (info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024;
+#ifdef XF86DRI
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
+		   "RADEONScreenInit %lx %ld %d\n",
+		   pScrn->memPhysBase, pScrn->fbOffset, info->frontOffset);
+#else
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONScreenInit %lx %ld\n",
+		   pScrn->memPhysBase, pScrn->fbOffset);
+#endif
     if (!RADEONMapMem(pScrn)) return FALSE;
 
 #ifdef XF86DRI
@@ -3172,9 +3025,10 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
 
     RADEONSave(pScrn);
 
-    RADEONDisableDisplays(pScrn);
+    /* blank the outputs/crtcs */
+    RADEONBlank(pScrn);
 
-    if (info->IsMobility) {
+    if (info->IsMobility && !IS_AVIVO_VARIANT) {
         if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
 	    RADEONSetDynamicClock(pScrn, 1);
         } else {
@@ -3373,13 +3227,32 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
 #endif
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "Initializing fb layer\n");
+    
+    if (info->r600_shadow_fb) {
+	info->fb_shadow = xcalloc(1,
+				  pScrn->displayWidth * pScrn->virtualY *
+				  ((pScrn->bitsPerPixel + 7) >> 3));
+	if (info->fb_shadow == NULL) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                       "Failed to allocate shadow framebuffer\n");
+	    info->r600_shadow_fb = FALSE;
+	} else {
+	    if (!fbScreenInit(pScreen, info->fb_shadow,
+			      pScrn->virtualX, pScrn->virtualY,
+			      pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
+			      pScrn->bitsPerPixel))
+		return FALSE;
+	}
+    }
 
-    /* Init fb layer */
-    if (!fbScreenInit(pScreen, info->FB + pScrn->fbOffset,
-		      pScrn->virtualX, pScrn->virtualY,
-		      pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
-		      pScrn->bitsPerPixel))
-	return FALSE;
+    if (info->r600_shadow_fb == FALSE) {
+	/* Init fb layer */
+	if (!fbScreenInit(pScreen, info->FB,
+			  pScrn->virtualX, pScrn->virtualY,
+			  pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
+			  pScrn->bitsPerPixel))
+	    return FALSE;
+    }
 
     xf86SetBlackWhitePixels(pScreen);
 
@@ -3413,9 +3286,13 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
 
     pScrn->vtSema = TRUE;
 
+    /* xf86CrtcRotate() accesses pScrn->pScreen */
+    pScrn->pScreen = pScreen;
+
+#if 1
     for (i = 0; i < xf86_config->num_crtc; i++) {
-	xf86CrtcPtr	crtc = xf86_config->crtc[i];
-	    
+	xf86CrtcPtr crtc = xf86_config->crtc[i];
+
 	/* Mark that we'll need to re-set the mode for sure */
 	memset(&crtc->mode, 0, sizeof(crtc->mode));
 	if (!crtc->desiredMode.CrtcHDisplay) {
@@ -3429,11 +3306,14 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
 	    return FALSE;
 
     }
+#else
+    /* seems to do the wrong thing on some cards??? */
+    if (!xf86SetDesiredModes (pScrn))
+	return FALSE;
+#endif
 
     RADEONSaveScreen(pScreen, SCREEN_SAVER_ON);
 
-    //    pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
     /* Backing store setup */
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "Initializing backing store\n");
@@ -3465,7 +3345,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
 	 * our local image to make sure we restore them properly on mode
 	 * changes or VT switches
 	 */
-	RADEONAdjustMemMapRegisters(pScrn, &info->ModeReg);
+	RADEONAdjustMemMapRegisters(pScrn, info->ModeReg);
 
 	if ((info->DispPriority == 1) && (info->cardType==CARD_AGP)) {
 	    /* we need to re-calculate bandwidth because of AGPMode difference. */ 
@@ -3491,6 +3371,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
 
     RADEONChangeSurfaces(pScrn);
 
+
     /* Enable aceleration */
     if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
 	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
@@ -3553,9 +3434,17 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
     RADEONDGAInit(pScreen);
 
     /* Init Xv */
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Initializing Xv\n");
-    RADEONInitVideo(pScreen);
+    if (!IS_AVIVO_VARIANT) {
+	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "Initializing Xv\n");
+	RADEONInitVideo(pScreen);
+    }
+
+    if (info->r600_shadow_fb == TRUE) {
+        if (!shadowSetup(pScreen)) {
+            return FALSE;
+        }
+    }
 
     /* Provide SaveScreen & wrap BlockHandler and CloseScreen */
     /* Wrap CloseScreen */
@@ -3564,6 +3453,8 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
     pScreen->SaveScreen  = RADEONSaveScreen;
     info->BlockHandler = pScreen->BlockHandler;
     pScreen->BlockHandler = RADEONBlockHandler;
+    info->CreateScreenResources = pScreen->CreateScreenResources;
+    pScreen->CreateScreenResources = RADEONCreateScreenResources;
 
    if (!xf86CrtcScreenInit (pScreen))
        return FALSE;
@@ -3602,184 +3493,252 @@ void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     int timeout;
+    CARD32 mc_fb_loc, mc_agp_loc, mc_agp_loc_hi;
+
+    radeon_read_mc_fb_agp_location(pScrn, LOC_FB | LOC_AGP, &mc_fb_loc,
+				   &mc_agp_loc, &mc_agp_loc_hi);
 
+    if (info->IsSecondary)
+      return;
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	       "RADEONRestoreMemMapRegisters() : \n");
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "  MC_FB_LOCATION   : 0x%08x\n",
-	       (unsigned)restore->mc_fb_location);
+	       "  MC_FB_LOCATION   : 0x%08x 0x%08x\n",
+	       (unsigned)restore->mc_fb_location, (unsigned int)mc_fb_loc);
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	       "  MC_AGP_LOCATION  : 0x%08x\n",
 	       (unsigned)restore->mc_agp_location);
 
-    /* Write memory mapping registers only if their value change
-     * since we must ensure no access is done while they are
-     * reprogrammed
-     */
-    if (INREG(RADEON_MC_FB_LOCATION) != restore->mc_fb_location ||
-	INREG(RADEON_MC_AGP_LOCATION) != restore->mc_agp_location) {
-	CARD32 crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl=0, ov0_scale_cntl;
-	CARD32 old_mc_status, status_idle;
+    if (IS_AVIVO_VARIANT) {
 
-	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		       "  Map Changed ! Applying ...\n");
+	if (mc_fb_loc != restore->mc_fb_location ||
+	    mc_agp_loc != restore->mc_agp_location) {
+	    CARD32 tmp;
 
-	/* Make sure engine is idle. We assume the CCE is stopped
-	 * at this point
-	 */
-	RADEONWaitForIdleMMIO(pScrn);
+	    RADEONWaitForIdleMMIO(pScrn);
 
-	if (info->IsIGP)
-		goto igp_no_mcfb;
+	    OUTREG(AVIVO_D1VGA_CONTROL, INREG(AVIVO_D1VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
+	    OUTREG(AVIVO_D2VGA_CONTROL, INREG(AVIVO_D2VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
 
-	/* Capture MC_STATUS in case things go wrong ... */
-	old_mc_status = INREG(RADEON_MC_STATUS);
-
-	/* Stop display & memory access */
-	ov0_scale_cntl = INREG(RADEON_OV0_SCALE_CNTL);
-	OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl & ~RADEON_SCALER_ENABLE);
-	crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
-	OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl | RADEON_CRTC_DISPLAY_DIS);
-	crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL);
-	RADEONWaitForVerticalSync(pScrn);
-	OUTREG(RADEON_CRTC_GEN_CNTL,
-	       (crtc_gen_cntl
-		& ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_ICON_EN))
-	       | RADEON_CRTC_DISP_REQ_EN_B | RADEON_CRTC_EXT_DISP_EN);
-
- 	if (pRADEONEnt->HasCRTC2) {
-	    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
-	    RADEONWaitForVerticalSync2(pScrn);
-	    OUTREG(RADEON_CRTC2_GEN_CNTL,
-		   (crtc2_gen_cntl
-		    & ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_ICON_EN))
-		   | RADEON_CRTC2_DISP_REQ_EN_B);
-	}
+	    /* Stop display & memory access */
+	    tmp = INREG(AVIVO_D1CRTC_CONTROL);
+	    OUTREG(AVIVO_D1CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN);
 
- 	/* Make sure the chip settles down (paranoid !) */ 
- 	usleep(100000);
+	    tmp = INREG(AVIVO_D2CRTC_CONTROL);
+	    OUTREG(AVIVO_D2CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN);
 
-	/* Wait for MC idle */
-	if (IS_R300_VARIANT)
-	    status_idle = R300_MC_IDLE;
-	else
-	    status_idle = RADEON_MC_IDLE;
+	    tmp = INREG(AVIVO_D2CRTC_CONTROL);
 
-	timeout = 0;
-	while (!(INREG(RADEON_MC_STATUS) & status_idle)) {
-	    if (++timeout > 1000000) {
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		    "Timeout trying to update memory controller settings !\n");
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "MC_STATUS = 0x%08x (on entry = 0x%08x)\n",
-			   INREG(RADEON_MC_STATUS), (unsigned int)old_mc_status);
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		    "You will probably crash now ... \n");
-		/* Nothing we can do except maybe try to kill the server,
-		 * let's wait 2 seconds to leave the above message a chance
-		 * to maybe hit the disk and continue trying to setup despite
-		 * the MC being non-idle
-		 */
-		usleep(2000000);
+	    usleep(10000);
+	    timeout = 0;
+	    while (!(avivo_get_mc_idle(pScrn))) {
+		if (++timeout > 1000000) {
+		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			       "Timeout trying to update memory controller settings !\n");
+		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			       "You will probably crash now ... \n");
+		    /* Nothing we can do except maybe try to kill the server,
+		     * let's wait 2 seconds to leave the above message a chance
+		     * to maybe hit the disk and continue trying to setup despite
+		     * the MC being non-idle
+		     */
+		    usleep(2000000);
+		}
+		usleep(10);
 	    }
-	    usleep(10);
+
+	    radeon_write_mc_fb_agp_location(pScrn, LOC_FB | LOC_AGP,
+					    restore->mc_fb_location,
+					    restore->mc_agp_location,
+					    restore->mc_agp_location_hi);
+
+	    if (info->ChipFamily < CHIP_FAMILY_R600) {
+		OUTREG(AVIVO_HDP_FB_LOCATION, restore->mc_fb_location);
+	    }
+	    
+	    /* Reset the engine and HDP */
+	    RADEONEngineReset(pScrn);
 	}
+    } else {
 
-	/* Update maps, first clearing out AGP to make sure we don't get
-	 * a temporary overlap
+	/* Write memory mapping registers only if their value change
+	 * since we must ensure no access is done while they are
+	 * reprogrammed
 	 */
- 	OUTREG(RADEON_MC_AGP_LOCATION, 0xfffffffc);
-	OUTREG(RADEON_MC_FB_LOCATION, restore->mc_fb_location);
-    igp_no_mcfb:
- 	OUTREG(RADEON_MC_AGP_LOCATION, restore->mc_agp_location);
-	/* Make sure map fully reached the chip */
-	(void)INREG(RADEON_MC_FB_LOCATION);
+	if (mc_fb_loc != restore->mc_fb_location ||
+	    mc_agp_loc != restore->mc_agp_location) {
+	    CARD32 crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl=0, ov0_scale_cntl;
+	    CARD32 old_mc_status, status_idle;
 
-	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		       "  Map applied, resetting engine ...\n");
+	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+			   "  Map Changed ! Applying ...\n");
 
-	/* Reset the engine and HDP */
-	RADEONEngineReset(pScrn);
+	    /* Make sure engine is idle. We assume the CCE is stopped
+	     * at this point
+	     */
+	    RADEONWaitForIdleMMIO(pScrn);
 
-	/* Make sure we have sane offsets before re-enabling the CRTCs, disable
-	 * stereo, clear offsets, and wait for offsets to catch up with hw
-	 */
+	    if (info->IsIGP)
+		goto igp_no_mcfb;
 
-	OUTREG(RADEON_CRTC_OFFSET_CNTL, RADEON_CRTC_OFFSET_FLIP_CNTL);
-	OUTREG(RADEON_CRTC_OFFSET, 0);
-	OUTREG(RADEON_CUR_OFFSET, 0);
-	timeout = 0;
-	while(INREG(RADEON_CRTC_OFFSET) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET) {
-	    if (timeout++ > 1000000) {
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "Timeout waiting for CRTC offset to update !\n");
-		break;
+	    /* Capture MC_STATUS in case things go wrong ... */
+	    old_mc_status = INREG(RADEON_MC_STATUS);
+
+	    /* Stop display & memory access */
+	    ov0_scale_cntl = INREG(RADEON_OV0_SCALE_CNTL);
+	    OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl & ~RADEON_SCALER_ENABLE);
+	    crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
+	    OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl | RADEON_CRTC_DISPLAY_DIS);
+	    crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL);
+	    RADEONWaitForVerticalSync(pScrn);
+	    OUTREG(RADEON_CRTC_GEN_CNTL,
+		   (crtc_gen_cntl
+		    & ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_ICON_EN))
+		   | RADEON_CRTC_DISP_REQ_EN_B | RADEON_CRTC_EXT_DISP_EN);
+
+	    if (pRADEONEnt->HasCRTC2) {
+		crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+		RADEONWaitForVerticalSync2(pScrn);
+		OUTREG(RADEON_CRTC2_GEN_CNTL,
+		       (crtc2_gen_cntl
+			& ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_ICON_EN))
+		       | RADEON_CRTC2_DISP_REQ_EN_B);
 	    }
-	    usleep(1000);
-	}
-	if (pRADEONEnt->HasCRTC2) {
-	    OUTREG(RADEON_CRTC2_OFFSET_CNTL, RADEON_CRTC2_OFFSET_FLIP_CNTL);
-	    OUTREG(RADEON_CRTC2_OFFSET, 0);
-	    OUTREG(RADEON_CUR2_OFFSET, 0);
+
+	    /* Make sure the chip settles down (paranoid !) */ 
+	    usleep(100000);
+
+	    /* Wait for MC idle */
+	    if (IS_R300_VARIANT)
+		status_idle = R300_MC_IDLE;
+	    else
+		status_idle = RADEON_MC_IDLE;
+
+	    timeout = 0;
+	    while (!(INREG(RADEON_MC_STATUS) & status_idle)) {
+		if (++timeout > 1000000) {
+		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			       "Timeout trying to update memory controller settings !\n");
+		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			       "MC_STATUS = 0x%08x (on entry = 0x%08x)\n",
+			       (unsigned int)INREG(RADEON_MC_STATUS), (unsigned int)old_mc_status);
+		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			       "You will probably crash now ... \n");
+		    /* Nothing we can do except maybe try to kill the server,
+		     * let's wait 2 seconds to leave the above message a chance
+		     * to maybe hit the disk and continue trying to setup despite
+		     * the MC being non-idle
+		     */
+		    usleep(2000000);
+		}
+		usleep(10);
+	    }
+
+	    /* Update maps, first clearing out AGP to make sure we don't get
+	     * a temporary overlap
+	     */
+	    OUTREG(RADEON_MC_AGP_LOCATION, 0xfffffffc);
+	    OUTREG(RADEON_MC_FB_LOCATION, restore->mc_fb_location);
+	    radeon_write_mc_fb_agp_location(pScrn, LOC_FB | LOC_AGP, restore->mc_fb_location,
+					    0xfffffffc, 0);
+	igp_no_mcfb:
+	    radeon_write_mc_fb_agp_location(pScrn, LOC_AGP, 0,
+					    restore->mc_agp_location, 0);
+	    /* Make sure map fully reached the chip */
+	    (void)INREG(RADEON_MC_FB_LOCATION);
+
+	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+			   "  Map applied, resetting engine ...\n");
+
+	    /* Reset the engine and HDP */
+	    RADEONEngineReset(pScrn);
+
+	    /* Make sure we have sane offsets before re-enabling the CRTCs, disable
+	     * stereo, clear offsets, and wait for offsets to catch up with hw
+	     */
+
+	    OUTREG(RADEON_CRTC_OFFSET_CNTL, RADEON_CRTC_OFFSET_FLIP_CNTL);
+	    OUTREG(RADEON_CRTC_OFFSET, 0);
+	    OUTREG(RADEON_CUR_OFFSET, 0);
 	    timeout = 0;
-	    while(INREG(RADEON_CRTC2_OFFSET) & RADEON_CRTC2_OFFSET__GUI_TRIG_OFFSET) {
+	    while(INREG(RADEON_CRTC_OFFSET) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET) {
 		if (timeout++ > 1000000) {
 		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			       "Timeout waiting for CRTC2 offset to update !\n");
+			       "Timeout waiting for CRTC offset to update !\n");
 		    break;
 		}
 		usleep(1000);
 	    }
+	    if (pRADEONEnt->HasCRTC2) {
+		OUTREG(RADEON_CRTC2_OFFSET_CNTL, RADEON_CRTC2_OFFSET_FLIP_CNTL);
+		OUTREG(RADEON_CRTC2_OFFSET, 0);
+		OUTREG(RADEON_CUR2_OFFSET, 0);
+		timeout = 0;
+		while(INREG(RADEON_CRTC2_OFFSET) & RADEON_CRTC2_OFFSET__GUI_TRIG_OFFSET) {
+		    if (timeout++ > 1000000) {
+			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+				   "Timeout waiting for CRTC2 offset to update !\n");
+			break;
+		    }
+		    usleep(1000);
+		}
+	    }
 	}
-    }
 
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Updating display base addresses...\n");
+	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "Updating display base addresses...\n");
 
-    OUTREG(RADEON_DISPLAY_BASE_ADDR, restore->display_base_addr);
-    if (pRADEONEnt->HasCRTC2)
-        OUTREG(RADEON_DISPLAY2_BASE_ADDR, restore->display2_base_addr);
-    OUTREG(RADEON_OV0_BASE_ADDR, restore->ov0_base_addr);
-    (void)INREG(RADEON_OV0_BASE_ADDR);
+	OUTREG(RADEON_DISPLAY_BASE_ADDR, restore->display_base_addr);
+	if (pRADEONEnt->HasCRTC2)
+	    OUTREG(RADEON_DISPLAY2_BASE_ADDR, restore->display2_base_addr);
+	OUTREG(RADEON_OV0_BASE_ADDR, restore->ov0_base_addr);
+	(void)INREG(RADEON_OV0_BASE_ADDR);
 
-    /* More paranoia delays, wait 100ms */
-    usleep(100000);
+	/* More paranoia delays, wait 100ms */
+	usleep(100000);
 
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Memory map updated.\n");
- }
+	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "Memory map updated.\n");
+    }
+}
 
 #ifdef XF86DRI
 static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
 {
     RADEONInfoPtr  info   = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    CARD32 fb, agp;
+    CARD32 fb, agp, agp_hi;
+    int changed;
 
-    fb = INREG(RADEON_MC_FB_LOCATION);
-    agp = INREG(RADEON_MC_AGP_LOCATION);
-
-    if (fb != info->mc_fb_location || agp != info->mc_agp_location) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		       "DRI init changed memory map, adjusting ...\n");
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		       "  MC_FB_LOCATION  was: 0x%08x is: 0x%08x\n",
-		       (unsigned)info->mc_fb_location, (unsigned)fb);
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		       "  MC_AGP_LOCATION was: 0x%08x is: 0x%08x\n",
-		       (unsigned)info->mc_agp_location, (unsigned)agp);
-	    info->mc_fb_location = fb;
-	    info->mc_agp_location = agp;
-	    info->fbLocation = (save->mc_fb_location & 0xffff) << 16;
-	    info->dst_pitch_offset =
-		    (((pScrn->displayWidth * info->CurrentLayout.pixel_bytes / 64)
-		      << 22) | ((info->fbLocation + pScrn->fbOffset) >> 10));
+    if (info->IsSecondary)
+      return;
 
+    radeon_read_mc_fb_agp_location(pScrn, LOC_FB | LOC_AGP, &fb, &agp, &agp_hi);
+    
+    if (fb != info->mc_fb_location || agp != info->mc_agp_location ||
+	agp_hi || info->mc_agp_location_hi)
+	changed = 1;
 
-	    RADEONInitMemMapRegisters(pScrn, save, info);
+    if (changed) {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "DRI init changed memory map, adjusting ...\n");
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "  MC_FB_LOCATION  was: 0x%08lx is: 0x%08lx\n",
+		   (long unsigned int)info->mc_fb_location, (long unsigned int)fb);
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "  MC_AGP_LOCATION was: 0x%08lx is: 0x%08lx\n",
+		   (long unsigned int)info->mc_agp_location, (long unsigned int)agp);
+	info->mc_fb_location = fb;
+	info->mc_agp_location = agp;
+	if (info->ChipFamily >= CHIP_FAMILY_R600)
+	    info->fbLocation = (info->mc_fb_location & 0xffff) << 24;
+	else
+	    info->fbLocation = (info->mc_fb_location & 0xffff) << 16;
 
-	    /* Adjust the various offsets */
-	    RADEONRestoreMemMapRegisters(pScrn, save);
+	info->dst_pitch_offset =
+	    (((pScrn->displayWidth * info->CurrentLayout.pixel_bytes / 64)
+	      << 22) | ((info->fbLocation + pScrn->fbOffset) >> 10));
+	RADEONInitMemMapRegisters(pScrn, save, info);
+	RADEONRestoreMemMapRegisters(pScrn, save);
     }
 
 #ifdef USE_EXA
@@ -3806,817 +3765,6 @@ static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
 }
 #endif
 
-/* Write common registers */
-void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
-					 RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    OUTREG(RADEON_OVR_CLR,            restore->ovr_clr);
-    OUTREG(RADEON_OVR_WID_LEFT_RIGHT, restore->ovr_wid_left_right);
-    OUTREG(RADEON_OVR_WID_TOP_BOTTOM, restore->ovr_wid_top_bottom);
-    OUTREG(RADEON_OV0_SCALE_CNTL,     restore->ov0_scale_cntl);
-    OUTREG(RADEON_SUBPIC_CNTL,        restore->subpic_cntl);
-    OUTREG(RADEON_VIPH_CONTROL,       restore->viph_control);
-    OUTREG(RADEON_I2C_CNTL_1,         restore->i2c_cntl_1);
-    OUTREG(RADEON_GEN_INT_CNTL,       restore->gen_int_cntl);
-    OUTREG(RADEON_CAP0_TRIG_CNTL,     restore->cap0_trig_cntl);
-    OUTREG(RADEON_CAP1_TRIG_CNTL,     restore->cap1_trig_cntl);
-    OUTREG(RADEON_BUS_CNTL,           restore->bus_cntl);
-    OUTREG(RADEON_SURFACE_CNTL,       restore->surface_cntl);
-
-    /* Workaround for the VT switching problem in dual-head mode.  This
-     * problem only occurs on RV style chips, typically when a FP and
-     * CRT are connected.
-     */
-    if (pRADEONEnt->HasCRTC2 &&
-	info->ChipFamily != CHIP_FAMILY_R200 &&
-	!IS_R300_VARIANT) {
-	CARD32        tmp;
-
-	tmp = INREG(RADEON_DAC_CNTL2);
-	OUTREG(RADEON_DAC_CNTL2, tmp & ~RADEON_DAC2_DAC_CLK_SEL);
-	usleep(100000);
-    }
-}
-
-void RADEONRestoreDACRegisters(ScrnInfoPtr pScrn,
-				       RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    if (IS_R300_VARIANT)
-	OUTREGP(RADEON_GPIOPAD_A, restore->gpiopad_a, ~1);
-
-    OUTREGP(RADEON_DAC_CNTL,
-	    restore->dac_cntl,
-	    RADEON_DAC_RANGE_CNTL |
-	    RADEON_DAC_BLANKING);
-
-    OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
-
-    if ((info->ChipFamily != CHIP_FAMILY_RADEON) &&
-    	(info->ChipFamily != CHIP_FAMILY_R200)) 
-    OUTREG (RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
-
-    OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl);
-
-    if ((info->ChipFamily == CHIP_FAMILY_R200) ||
-	IS_R300_VARIANT) {
-	OUTREG(RADEON_DISP_TV_OUT_CNTL, restore->disp_tv_out_cntl);
-    } else {
-	OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
-    }
-
-    OUTREG(RADEON_DAC_MACRO_CNTL, restore->dac_macro_cntl);
-
-    /* R200 DAC connected via DVO */
-    if (info->ChipFamily == CHIP_FAMILY_R200)
-	OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl);
-}
-
-/* Write CRTC registers */
-void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
-				       RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Programming CRTC1, offset: 0x%08x\n",
-		   (unsigned)restore->crtc_offset);
-
-    /* We prevent the CRTC from hitting the memory controller until
-     * fully programmed
-     */
-    OUTREG(RADEON_CRTC_GEN_CNTL, restore->crtc_gen_cntl |
-	   RADEON_CRTC_DISP_REQ_EN_B);
-
-    OUTREGP(RADEON_CRTC_EXT_CNTL,
-	    restore->crtc_ext_cntl,
-	    RADEON_CRTC_VSYNC_DIS |
-	    RADEON_CRTC_HSYNC_DIS |
-	    RADEON_CRTC_DISPLAY_DIS);
-
-    OUTREG(RADEON_CRTC_H_TOTAL_DISP,    restore->crtc_h_total_disp);
-    OUTREG(RADEON_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid);
-    OUTREG(RADEON_CRTC_V_TOTAL_DISP,    restore->crtc_v_total_disp);
-    OUTREG(RADEON_CRTC_V_SYNC_STRT_WID, restore->crtc_v_sync_strt_wid);
-
-    OUTREG(RADEON_FP_H_SYNC_STRT_WID,   restore->fp_h_sync_strt_wid);
-    OUTREG(RADEON_FP_V_SYNC_STRT_WID,   restore->fp_v_sync_strt_wid);
-    OUTREG(RADEON_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp);
-    OUTREG(RADEON_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp);
-
-    if (IS_R300_VARIANT)
-	OUTREG(R300_CRTC_TILE_X0_Y0, restore->crtc_tile_x0_y0);
-    OUTREG(RADEON_CRTC_OFFSET_CNTL,     restore->crtc_offset_cntl);
-    OUTREG(RADEON_CRTC_OFFSET,          restore->crtc_offset);
-
-    OUTREG(RADEON_CRTC_PITCH,           restore->crtc_pitch);
-    OUTREG(RADEON_DISP_MERGE_CNTL,      restore->disp_merge_cntl);
-    OUTREG(RADEON_CRTC_MORE_CNTL,       restore->crtc_more_cntl);
-
-    if (info->IsDellServer) {
-	OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
-	OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
-	OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
-	OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
-    }
-
-    OUTREG(RADEON_CRTC_GEN_CNTL, restore->crtc_gen_cntl);
-}
-
-/* Write CRTC2 registers */
-void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
-					RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    /*    CARD32	   crtc2_gen_cntl;*/
-
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Programming CRTC2, offset: 0x%08x\n",
-		   (unsigned)restore->crtc2_offset);
-
-    /* We prevent the CRTC from hitting the memory controller until
-     * fully programmed
-     */
-    OUTREG(RADEON_CRTC2_GEN_CNTL,
-	   restore->crtc2_gen_cntl | RADEON_CRTC2_VSYNC_DIS |
-	   RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_DIS |
-	   RADEON_CRTC2_DISP_REQ_EN_B);
-
-    OUTREG(RADEON_CRTC2_H_TOTAL_DISP,    restore->crtc2_h_total_disp);
-    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, restore->crtc2_h_sync_strt_wid);
-    OUTREG(RADEON_CRTC2_V_TOTAL_DISP,    restore->crtc2_v_total_disp);
-    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, restore->crtc2_v_sync_strt_wid);
-
-    OUTREG(RADEON_FP_H2_SYNC_STRT_WID,   restore->fp_h2_sync_strt_wid);
-    OUTREG(RADEON_FP_V2_SYNC_STRT_WID,   restore->fp_v2_sync_strt_wid);
-
-    if (IS_R300_VARIANT)
-	OUTREG(R300_CRTC2_TILE_X0_Y0, restore->crtc2_tile_x0_y0);
-    OUTREG(RADEON_CRTC2_OFFSET_CNTL,     restore->crtc2_offset_cntl);
-    OUTREG(RADEON_CRTC2_OFFSET,          restore->crtc2_offset);
-
-    OUTREG(RADEON_CRTC2_PITCH,           restore->crtc2_pitch);
-    OUTREG(RADEON_DISP2_MERGE_CNTL,      restore->disp2_merge_cntl);
-
-    if (info->ChipFamily == CHIP_FAMILY_RS400) {
-	OUTREG(RADEON_RS480_UNK_e30, restore->rs480_unk_e30);
-	OUTREG(RADEON_RS480_UNK_e34, restore->rs480_unk_e34);
-	OUTREG(RADEON_RS480_UNK_e38, restore->rs480_unk_e38);
-	OUTREG(RADEON_RS480_UNK_e3c, restore->rs480_unk_e3c);
-    }
-    OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
-
-}
-
-/* Write TMDS registers */
-void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    OUTREG(RADEON_TMDS_PLL_CNTL,        restore->tmds_pll_cntl);
-    OUTREG(RADEON_TMDS_TRANSMITTER_CNTL,restore->tmds_transmitter_cntl);
-    OUTREG(RADEON_FP_GEN_CNTL,          restore->fp_gen_cntl);
-
-    /* old AIW Radeon has some BIOS initialization problem
-     * with display buffer underflow, only occurs to DFP
-     */
-    if (!pRADEONEnt->HasCRTC2)
-	OUTREG(RADEON_GRPH_BUFFER_CNTL,
-	       INREG(RADEON_GRPH_BUFFER_CNTL) & ~0x7f0000);
-
-}
-
-/* Write FP2 registers */
-void RADEONRestoreFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    OUTREG(RADEON_FP2_GEN_CNTL,         restore->fp2_gen_cntl);
-
-}
-
-/* Write RMX registers */
-void RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    OUTREG(RADEON_FP_HORZ_STRETCH,      restore->fp_horz_stretch);
-    OUTREG(RADEON_FP_VERT_STRETCH,      restore->fp_vert_stretch);
-
-}
-
-/* Write LVDS registers */
-void RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    if (info->IsMobility) {
-	OUTREG(RADEON_LVDS_GEN_CNTL,  restore->lvds_gen_cntl);
-	OUTREG(RADEON_LVDS_PLL_CNTL,  restore->lvds_pll_cntl);
-
-	if (info->ChipFamily == CHIP_FAMILY_RV410) {
-	    OUTREG(RADEON_CLOCK_CNTL_INDEX, 0);
-	}
-    }
-
-}
-
-void RADEONRestoreBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    CARD32 bios_5_scratch = INREG(RADEON_BIOS_5_SCRATCH);
-    CARD32 bios_6_scratch = INREG(RADEON_BIOS_6_SCRATCH);
-
-    OUTREG(RADEON_BIOS_4_SCRATCH, restore->bios_4_scratch);
-    bios_5_scratch &= 0xF;
-    bios_5_scratch |= (restore->bios_5_scratch & ~0xF);
-    OUTREG(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
-    if (restore->bios_6_scratch & 0x40000000)
-	bios_6_scratch |= 0x40000000;
-    else
-	bios_6_scratch &= ~0x40000000;
-    OUTREG(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
-
-}
-
-/* Write to TV FIFO RAM */
-static void RADEONWriteTVFIFO(ScrnInfoPtr pScrn, CARD16 addr,
-			      CARD32 value)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    CARD32 tmp;
-    int i = 0;
-
-    OUTREG(RADEON_TV_HOST_WRITE_DATA, value);
-
-    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr);
-    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT);
-
-    do {
-	tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
-	if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0)
-	    break;
-	i++;
-    }
-    while (i < 10000);
-    /*while ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0);*/
-
-    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
-}
-
-/* Read from TV FIFO RAM */
-static CARD32 RADEONReadTVFIFO(ScrnInfoPtr pScrn, CARD16 addr)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    CARD32 tmp;
-    int i = 0;
-  
-    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr);
-    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD);
-
-    do {
-	tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
-	if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0)
-	    break;
-	i++;
-    }
-    while (i < 10000);
-    /*while ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0);*/
-
-    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
-
-    return INREG(RADEON_TV_HOST_READ_DATA);
-}
-
-/* Get FIFO addresses of horizontal & vertical code timing tables from
- * settings of uv_adr register. 
- */
-static CARD16 RADEONGetHTimingTablesAddr(CARD32 tv_uv_adr)
-{
-    CARD16 hTable;
-
-    switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) {
-    case 0:
-	hTable = RADEON_TV_MAX_FIFO_ADDR_INTERNAL;
-	break;
-    case 1:
-	hTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2;
-	break;
-    case 2:
-	hTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2;
-	break;
-    default:
-	/* Of course, this should never happen */
-	hTable = 0;
-	break;
-    }
-    return hTable;
-}
-
-static CARD16 RADEONGetVTimingTablesAddr(CARD32 tv_uv_adr)
-{
-    CARD16 vTable;
-
-    switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) {
-    case 0:
-	vTable = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1;
-	break;
-    case 1:
-	vTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1;
-	break;
-    case 2:
-	vTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1;
-	break;
-    default:
-	/* Of course, this should never happen */
-	vTable = 0;
-	break;
-    }
-    return vTable;
-}
-
-/* Restore horizontal/vertical timing code tables */
-void RADEONRestoreTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    CARD16 hTable;
-    CARD16 vTable;
-    CARD32 tmp;
-    unsigned i;
-
-    OUTREG(RADEON_TV_UV_ADR, restore->tv_uv_adr);
-    hTable = RADEONGetHTimingTablesAddr(restore->tv_uv_adr);
-    vTable = RADEONGetVTimingTablesAddr(restore->tv_uv_adr);
-
-    for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, hTable--) {
-	tmp = ((CARD32)restore->h_code_timing[ i ] << 14) | ((CARD32)restore->h_code_timing[ i + 1 ]);
-	RADEONWriteTVFIFO(pScrn, hTable, tmp);
-	if (restore->h_code_timing[ i ] == 0 || restore->h_code_timing[ i + 1 ] == 0)
-	    break;
-    }
-
-    for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, vTable++) {
-	tmp = ((CARD32)restore->v_code_timing[ i + 1 ] << 14) | ((CARD32)restore->v_code_timing[ i ]);
-	RADEONWriteTVFIFO(pScrn, vTable, tmp);
-	if (restore->v_code_timing[ i ] == 0 || restore->v_code_timing[ i + 1 ] == 0)
-	    break;
-    }
-}
-
-/* restore TV PLLs */
-static void RADEONRestoreTVPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
-
-    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL);
-    OUTPLL(pScrn, RADEON_TV_PLL_CNTL, restore->tv_pll_cntl);
-    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET);
-
-    RADEONWaitPLLLock(pScrn, 200, 800, 135);
-  
-    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET);
-
-    RADEONWaitPLLLock(pScrn, 300, 160, 27);
-    RADEONWaitPLLLock(pScrn, 200, 800, 135);
-  
-    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~0xf);
-    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL);
-  
-    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK);
-    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP);
-}
-
-/* Restore TV horizontal/vertical settings */
-static void RADEONRestoreTVHVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    OUTREG(RADEON_TV_RGB_CNTL, restore->tv_rgb_cntl);
-
-    OUTREG(RADEON_TV_HTOTAL, restore->tv_htotal);
-    OUTREG(RADEON_TV_HDISP, restore->tv_hdisp);
-    OUTREG(RADEON_TV_HSTART, restore->tv_hstart);
-
-    OUTREG(RADEON_TV_VTOTAL, restore->tv_vtotal);
-    OUTREG(RADEON_TV_VDISP, restore->tv_vdisp);
-
-    OUTREG(RADEON_TV_FTOTAL, restore->tv_ftotal);
-
-    OUTREG(RADEON_TV_VSCALER_CNTL1, restore->tv_vscaler_cntl1);
-    OUTREG(RADEON_TV_VSCALER_CNTL2, restore->tv_vscaler_cntl2);
-
-    OUTREG(RADEON_TV_Y_FALL_CNTL, restore->tv_y_fall_cntl);
-    OUTREG(RADEON_TV_Y_RISE_CNTL, restore->tv_y_rise_cntl);
-    OUTREG(RADEON_TV_Y_SAW_TOOTH_CNTL, restore->tv_y_saw_tooth_cntl);
-}
-
-/* restore TV RESTART registers */
-void RADEONRestoreTVRestarts(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    OUTREG(RADEON_TV_FRESTART, restore->tv_frestart);
-    OUTREG(RADEON_TV_HRESTART, restore->tv_hrestart);
-    OUTREG(RADEON_TV_VRESTART, restore->tv_vrestart);
-}
-
-/* restore tv standard & output muxes */
-static void RADEONRestoreTVOutputStd(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    OUTREG(RADEON_TV_SYNC_CNTL, restore->tv_sync_cntl);
-  
-    OUTREG(RADEON_TV_TIMING_CNTL, restore->tv_timing_cntl);
-
-    OUTREG(RADEON_TV_MODULATOR_CNTL1, restore->tv_modulator_cntl1);
-    OUTREG(RADEON_TV_MODULATOR_CNTL2, restore->tv_modulator_cntl2);
- 
-    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, restore->tv_pre_dac_mux_cntl);
-
-    OUTREG(RADEON_TV_CRC_CNTL, restore->tv_crc_cntl);
-}
-
-/* Restore TV out regs */
-void RADEONRestoreTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    ErrorF("Entering Restore TV\n");
-
-    OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
-				   | RADEON_TV_ASYNC_RST
-				   | RADEON_CRT_ASYNC_RST
-				   | RADEON_TV_FIFO_ASYNC_RST));
-
-    /* Temporarily turn the TV DAC off */
-    OUTREG(RADEON_TV_DAC_CNTL, ((restore->tv_dac_cntl & ~RADEON_TV_DAC_NBLANK)
-				| RADEON_TV_DAC_BGSLEEP
-				| RADEON_TV_DAC_RDACPD
-				| RADEON_TV_DAC_GDACPD
-				| RADEON_TV_DAC_BDACPD));
-
-    ErrorF("Restore TV PLL\n");
-    RADEONRestoreTVPLLRegisters(pScrn, restore);
-
-    ErrorF("Restore TVHV\n");
-    RADEONRestoreTVHVRegisters(pScrn, restore);
-
-    OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
-				   | RADEON_TV_ASYNC_RST
-				   | RADEON_CRT_ASYNC_RST));
-
-    ErrorF("Restore TV Restarts\n");
-    RADEONRestoreTVRestarts(pScrn, restore);
-  
-    ErrorF("Restore Timing Tables\n");
-    RADEONRestoreTVTimingTables(pScrn, restore);
-  
-
-    OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
-				   | RADEON_TV_ASYNC_RST));
-
-    ErrorF("Restore TV standard\n");
-    RADEONRestoreTVOutputStd(pScrn, restore);
-
-    OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl);
-
-    OUTREG(RADEON_TV_GAIN_LIMIT_SETTINGS, restore->tv_gain_limit_settings);
-    OUTREG(RADEON_TV_LINEAR_GAIN_SETTINGS, restore->tv_linear_gain_settings);
-
-    OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
-
-    ErrorF("Leaving Restore TV\n");
-}
-
-static void RADEONPLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn)
-{
-    int i = 0;
-
-    /* FIXME: Certain revisions of R300 can't recover here.  Not sure of
-       the cause yet, but this workaround will mask the problem for now.
-       Other chips usually will pass at the very first test, so the
-       workaround shouldn't have any effect on them. */
-    for (i = 0;
-	 (i < 10000 &&
-	  INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R);
-	 i++);
-}
-
-static void RADEONPLLWriteUpdate(ScrnInfoPtr pScrn)
-{
-    while (INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R);
-
-    OUTPLLP(pScrn, RADEON_PPLL_REF_DIV,
-	    RADEON_PPLL_ATOMIC_UPDATE_W,
-	    ~(RADEON_PPLL_ATOMIC_UPDATE_W));
-}
-
-static void RADEONPLL2WaitForReadUpdateComplete(ScrnInfoPtr pScrn)
-{
-    int i = 0;
-
-    /* FIXME: Certain revisions of R300 can't recover here.  Not sure of
-       the cause yet, but this workaround will mask the problem for now.
-       Other chips usually will pass at the very first test, so the
-       workaround shouldn't have any effect on them. */
-    for (i = 0;
-	 (i < 10000 &&
-	  INPLL(pScrn, RADEON_P2PLL_REF_DIV) & RADEON_P2PLL_ATOMIC_UPDATE_R);
-	 i++);
-}
-
-static void RADEONPLL2WriteUpdate(ScrnInfoPtr pScrn)
-{
-    while (INPLL(pScrn, RADEON_P2PLL_REF_DIV) & RADEON_P2PLL_ATOMIC_UPDATE_R);
-
-    OUTPLLP(pScrn, RADEON_P2PLL_REF_DIV,
-	    RADEON_P2PLL_ATOMIC_UPDATE_W,
-	    ~(RADEON_P2PLL_ATOMIC_UPDATE_W));
-}
-
-static CARD8 RADEONComputePLLGain(CARD16 reference_freq, CARD16 ref_div,
-				  CARD16 fb_div)
-{
-    unsigned vcoFreq;
-
-    if (!ref_div)
-	return 1;
-
-    vcoFreq = ((unsigned)reference_freq * fb_div) / ref_div;
-
-    /*
-     * This is horribly crude: the VCO frequency range is divided into
-     * 3 parts, each part having a fixed PLL gain value.
-     */
-    if (vcoFreq >= 30000)
-	/*
-	 * [300..max] MHz : 7
-	 */
-	return 7;
-    else if (vcoFreq >= 18000)
-	/*
-	 * [180..300) MHz : 4
-	 */
-        return 4;
-    else
-	/*
-	 * [0..180) MHz : 1
-	 */
-        return 1;
-}
-
-/* Wait for PLLs to lock */
-static void RADEONWaitPLLLock(ScrnInfoPtr pScrn, unsigned nTests,
-			      unsigned nWaitLoops, unsigned cntThreshold)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    CARD32 savePLLTest;
-    unsigned i;
-    unsigned j;
-
-    OUTREG(RADEON_TEST_DEBUG_MUX, (INREG(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100);
-
-    savePLLTest = INPLL(pScrn, RADEON_PLL_TEST_CNTL);
-
-    OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest & ~RADEON_PLL_MASK_READ_B);
-
-    /* XXX: these should probably be OUTPLL to avoid various PLL errata */
-
-    OUTREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL);
-
-    for (i = 0; i < nTests; i++) {
-	OUTREG8(RADEON_CLOCK_CNTL_DATA + 3, 0);
-      
-	for (j = 0; j < nWaitLoops; j++)
-	    if (INREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cntThreshold)
-		break;
-    }
-
-    OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest);
-
-    OUTREG(RADEON_TEST_DEBUG_MUX, INREG(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff);
-}
-
-/* Write PLL registers */
-void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
-			       RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    CARD8 pllGain;
-
-#if defined(__powerpc__)
-    /* apparently restoring the pll causes a hang??? */
-    if (info->MacModel == RADEON_MAC_IBOOK)
-	return;
-#endif
-
-    pllGain = RADEONComputePLLGain(info->pll.reference_freq,
-				   restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
-				   restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK);
-
-    if (info->IsMobility) {
-        /* A temporal workaround for the occational blanking on certain laptop panels.
-           This appears to related to the PLL divider registers (fail to lock?).
-	   It occurs even when all dividers are the same with their old settings.
-           In this case we really don't need to fiddle with PLL registers.
-           By doing this we can avoid the blanking problem with some panels.
-        */
-        if ((restore->ppll_ref_div == (INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_REF_DIV_MASK)) &&
-	    (restore->ppll_div_3 == (INPLL(pScrn, RADEON_PPLL_DIV_3) & 
-				     (RADEON_PPLL_POST3_DIV_MASK | RADEON_PPLL_FB3_DIV_MASK)))) {
-	    OUTREGP(RADEON_CLOCK_CNTL_INDEX,
-		    RADEON_PLL_DIV_SEL,
-		    ~(RADEON_PLL_DIV_SEL));
-	    RADEONPllErrataAfterIndex(info);
-	    return;
-	}
-    }
-
-    OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
-	    RADEON_VCLK_SRC_SEL_CPUCLK,
-	    ~(RADEON_VCLK_SRC_SEL_MASK));
-
-    OUTPLLP(pScrn,
-	    RADEON_PPLL_CNTL,
-	    RADEON_PPLL_RESET
-	    | RADEON_PPLL_ATOMIC_UPDATE_EN
-	    | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
-	    | ((CARD32)pllGain << RADEON_PPLL_PVG_SHIFT),
-	    ~(RADEON_PPLL_RESET
-	      | RADEON_PPLL_ATOMIC_UPDATE_EN
-	      | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
-	      | RADEON_PPLL_PVG_MASK));
-
-    OUTREGP(RADEON_CLOCK_CNTL_INDEX,
-	    RADEON_PLL_DIV_SEL,
-	    ~(RADEON_PLL_DIV_SEL));
-    RADEONPllErrataAfterIndex(info);
-
-    if (IS_R300_VARIANT ||
-	(info->ChipFamily == CHIP_FAMILY_RS300) ||
-	(info->ChipFamily == CHIP_FAMILY_RS400)) {
-	if (restore->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
-	    /* When restoring console mode, use saved PPLL_REF_DIV
-	     * setting.
-	     */
-	    OUTPLLP(pScrn, RADEON_PPLL_REF_DIV,
-		    restore->ppll_ref_div,
-		    0);
-	} else {
-	    /* R300 uses ref_div_acc field as real ref divider */
-	    OUTPLLP(pScrn, RADEON_PPLL_REF_DIV,
-		    (restore->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),
-		    ~R300_PPLL_REF_DIV_ACC_MASK);
-	}
-    } else {
-	OUTPLLP(pScrn, RADEON_PPLL_REF_DIV,
-		restore->ppll_ref_div,
-		~RADEON_PPLL_REF_DIV_MASK);
-    }
-
-    OUTPLLP(pScrn, RADEON_PPLL_DIV_3,
-	    restore->ppll_div_3,
-	    ~RADEON_PPLL_FB3_DIV_MASK);
-
-    OUTPLLP(pScrn, RADEON_PPLL_DIV_3,
-	    restore->ppll_div_3,
-	    ~RADEON_PPLL_POST3_DIV_MASK);
-
-    RADEONPLLWriteUpdate(pScrn);
-    RADEONPLLWaitForReadUpdateComplete(pScrn);
-
-    OUTPLL(pScrn, RADEON_HTOTAL_CNTL, restore->htotal_cntl);
-
-    OUTPLLP(pScrn, RADEON_PPLL_CNTL,
-	    0,
-	    ~(RADEON_PPLL_RESET
-	      | RADEON_PPLL_SLEEP
-	      | RADEON_PPLL_ATOMIC_UPDATE_EN
-	      | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN));
-
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
-		   restore->ppll_ref_div,
-		   restore->ppll_div_3,
-		   (unsigned)restore->htotal_cntl,
-		   INPLL(pScrn, RADEON_PPLL_CNTL));
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Wrote: rd=%d, fd=%d, pd=%d\n",
-		   restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
-		   restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK,
-		   (restore->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16);
-
-    usleep(50000); /* Let the clock to lock */
-
-    OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
-	    RADEON_VCLK_SRC_SEL_PPLLCLK,
-	    ~(RADEON_VCLK_SRC_SEL_MASK));
-
-    /*OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, restore->vclk_ecp_cntl);*/
-
-    ErrorF("finished PLL1\n");
-
-}
-
-
-/* Write PLL2 registers */
-void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
-				RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    CARD8 pllGain;
-
-    pllGain = RADEONComputePLLGain(info->pll.reference_freq,
-                                   restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
-                                   restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK);
-
-
-    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
-	    RADEON_PIX2CLK_SRC_SEL_CPUCLK,
-	    ~(RADEON_PIX2CLK_SRC_SEL_MASK));
-
-    OUTPLLP(pScrn,
-	    RADEON_P2PLL_CNTL,
-	    RADEON_P2PLL_RESET
-	    | RADEON_P2PLL_ATOMIC_UPDATE_EN
-	    | ((CARD32)pllGain << RADEON_P2PLL_PVG_SHIFT),
-	    ~(RADEON_P2PLL_RESET
-	      | RADEON_P2PLL_ATOMIC_UPDATE_EN
-	      | RADEON_P2PLL_PVG_MASK));
-
-
-    OUTPLLP(pScrn, RADEON_P2PLL_REF_DIV,
-	    restore->p2pll_ref_div,
-	    ~RADEON_P2PLL_REF_DIV_MASK);
-
-    OUTPLLP(pScrn, RADEON_P2PLL_DIV_0,
-	    restore->p2pll_div_0,
-	    ~RADEON_P2PLL_FB0_DIV_MASK);
-
-    OUTPLLP(pScrn, RADEON_P2PLL_DIV_0,
-	    restore->p2pll_div_0,
-	    ~RADEON_P2PLL_POST0_DIV_MASK);
-
-    RADEONPLL2WriteUpdate(pScrn);
-    RADEONPLL2WaitForReadUpdateComplete(pScrn);
-
-    OUTPLL(pScrn, RADEON_HTOTAL2_CNTL, restore->htotal_cntl2);
-
-    OUTPLLP(pScrn, RADEON_P2PLL_CNTL,
-	    0,
-	    ~(RADEON_P2PLL_RESET
-	      | RADEON_P2PLL_SLEEP
-	      | RADEON_P2PLL_ATOMIC_UPDATE_EN));
-
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Wrote2: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
-		   (unsigned)restore->p2pll_ref_div,
-		   (unsigned)restore->p2pll_div_0,
-		   (unsigned)restore->htotal_cntl2,
-		   INPLL(pScrn, RADEON_P2PLL_CNTL));
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Wrote2: rd=%u, fd=%u, pd=%u\n",
-		   (unsigned)restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
-		   (unsigned)restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK,
-		   (unsigned)((restore->p2pll_div_0 &
-			       RADEON_P2PLL_POST0_DIV_MASK) >>16));
-
-    usleep(5000); /* Let the clock to lock */
-
-    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
-	    RADEON_PIX2CLK_SRC_SEL_P2PLLCLK,
-	    ~(RADEON_PIX2CLK_SRC_SEL_MASK));
-
-    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, restore->pixclks_cntl);
-
-    ErrorF("finished PLL2\n");
-
-}
-
-
 /* restore original surface info (for fb console). */
 static void RADEONRestoreSurfaces(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
@@ -4680,7 +3828,7 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn)
 #endif
     if (info->ChipFamily < CHIP_FAMILY_R200) {
 	color_pattern = RADEON_SURF_TILE_COLOR_MACRO;
-    } else if (IS_R300_VARIANT) {
+    } else if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
        color_pattern = R300_SURF_TILE_COLOR_MACRO;
     } else {
 	color_pattern = R200_SURF_TILE_COLOR_MACRO;
@@ -4719,7 +3867,7 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn)
 	drmsurfalloc.flags = swap_pattern;
 
 	if (info->tilingEnabled) {
-	    if (IS_R300_VARIANT)
+	    if (IS_R300_VARIANT || IS_AVIVO_VARIANT)
 		drmsurfalloc.flags |= (width_bytes / 8) | color_pattern;
 	    else
 		drmsurfalloc.flags |= (width_bytes / 16) | color_pattern;
@@ -4744,7 +3892,7 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn)
 		depth_pattern = RADEON_SURF_TILE_DEPTH_16BPP;
 	    else
 		depth_pattern = RADEON_SURF_TILE_DEPTH_32BPP;
-	} else if (IS_R300_VARIANT) {
+	} else if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
 	    if (depthCpp == 2)
 		depth_pattern = R300_SURF_TILE_COLOR_MACRO;
 	    else
@@ -4764,7 +3912,7 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn)
 	    drmRadeonSurfaceAlloc drmsurfalloc;
 	    drmsurfalloc.size = depthBufferSize;
 	    drmsurfalloc.address = info->depthOffset;
-            if (IS_R300_VARIANT)
+            if (IS_R300_VARIANT || IS_AVIVO_VARIANT)
                 drmsurfalloc.flags = swap_pattern | (depth_width_bytes / 8) | depth_pattern;
             else
                 drmsurfalloc.flags = swap_pattern | (depth_width_bytes / 16) | depth_pattern;
@@ -4782,7 +3930,7 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn)
 	unsigned char *RADEONMMIO = info->MMIO;
 	/* we don't need anything like WaitForFifo, no? */
 	if (info->tilingEnabled) {
-	    if (IS_R300_VARIANT)
+	    if (IS_R300_VARIANT || IS_AVIVO_VARIANT)
 		surf_info |= (width_bytes / 8) | color_pattern;
 	    else
 		surf_info |= (width_bytes / 16) | color_pattern;
@@ -4796,7 +3944,7 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn)
     }
 
     /* Update surface images */
-    RADEONSaveSurfaces(pScrn, &info->ModeReg);
+    RADEONSaveSurfaces(pScrn, info->ModeReg);
 }
 
 /* Read memory map */
@@ -4805,318 +3953,356 @@ static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
 
-    save->mc_fb_location     = INREG(RADEON_MC_FB_LOCATION);
-    save->mc_agp_location    = INREG(RADEON_MC_AGP_LOCATION);
-    save->display_base_addr  = INREG(RADEON_DISPLAY_BASE_ADDR);
-    save->display2_base_addr = INREG(RADEON_DISPLAY2_BASE_ADDR);
-    save->ov0_base_addr      = INREG(RADEON_OV0_BASE_ADDR);
-}
-
-/* Read common registers */
-static void RADEONSaveCommonRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    save->ovr_clr            = INREG(RADEON_OVR_CLR);
-    save->ovr_wid_left_right = INREG(RADEON_OVR_WID_LEFT_RIGHT);
-    save->ovr_wid_top_bottom = INREG(RADEON_OVR_WID_TOP_BOTTOM);
-    save->ov0_scale_cntl     = INREG(RADEON_OV0_SCALE_CNTL);
-    save->subpic_cntl        = INREG(RADEON_SUBPIC_CNTL);
-    save->viph_control       = INREG(RADEON_VIPH_CONTROL);
-    save->i2c_cntl_1         = INREG(RADEON_I2C_CNTL_1);
-    save->gen_int_cntl       = INREG(RADEON_GEN_INT_CNTL);
-    save->cap0_trig_cntl     = INREG(RADEON_CAP0_TRIG_CNTL);
-    save->cap1_trig_cntl     = INREG(RADEON_CAP1_TRIG_CNTL);
-    save->bus_cntl           = INREG(RADEON_BUS_CNTL);
-    save->surface_cntl	     = INREG(RADEON_SURFACE_CNTL);
-    save->grph_buffer_cntl   = INREG(RADEON_GRPH_BUFFER_CNTL);
-    save->grph2_buffer_cntl  = INREG(RADEON_GRPH2_BUFFER_CNTL);
-}
-
-/* Read CRTC registers */
-static void RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    save->crtc_gen_cntl        = INREG(RADEON_CRTC_GEN_CNTL);
-    save->crtc_ext_cntl        = INREG(RADEON_CRTC_EXT_CNTL);
-    save->crtc_h_total_disp    = INREG(RADEON_CRTC_H_TOTAL_DISP);
-    save->crtc_h_sync_strt_wid = INREG(RADEON_CRTC_H_SYNC_STRT_WID);
-    save->crtc_v_total_disp    = INREG(RADEON_CRTC_V_TOTAL_DISP);
-    save->crtc_v_sync_strt_wid = INREG(RADEON_CRTC_V_SYNC_STRT_WID);
-
-    save->fp_h_sync_strt_wid   = INREG(RADEON_FP_H_SYNC_STRT_WID);
-    save->fp_v_sync_strt_wid   = INREG(RADEON_FP_V_SYNC_STRT_WID);
-    save->fp_crtc_h_total_disp = INREG(RADEON_FP_CRTC_H_TOTAL_DISP);
-    save->fp_crtc_v_total_disp = INREG(RADEON_FP_CRTC_V_TOTAL_DISP);
-
-    save->crtc_offset          = INREG(RADEON_CRTC_OFFSET);
-    save->crtc_offset_cntl     = INREG(RADEON_CRTC_OFFSET_CNTL);
-    save->crtc_pitch           = INREG(RADEON_CRTC_PITCH);
-    save->disp_merge_cntl      = INREG(RADEON_DISP_MERGE_CNTL);
-    save->crtc_more_cntl       = INREG(RADEON_CRTC_MORE_CNTL);
-
-    if (IS_R300_VARIANT)
-	save->crtc_tile_x0_y0 =  INREG(R300_CRTC_TILE_X0_Y0);
-
-    if (info->IsDellServer) {
-	save->tv_dac_cntl      = INREG(RADEON_TV_DAC_CNTL);
-	save->dac2_cntl        = INREG(RADEON_DAC_CNTL2);
-	save->disp_hw_debug    = INREG (RADEON_DISP_HW_DEBUG);
-	save->crtc2_gen_cntl   = INREG(RADEON_CRTC2_GEN_CNTL);
-    }
-
-    /* track if the crtc is enabled for text restore */
-    if (save->crtc_ext_cntl & RADEON_CRTC_DISPLAY_DIS)
-	info->crtc_on = FALSE;
-    else
-	info->crtc_on = TRUE;
+    radeon_read_mc_fb_agp_location(pScrn, LOC_FB | LOC_AGP, &save->mc_fb_location,
+				   &save->mc_agp_location, &save->mc_agp_location_hi);
 
+    if (!IS_AVIVO_VARIANT) {
+        save->display_base_addr  = INREG(RADEON_DISPLAY_BASE_ADDR);
+        save->display2_base_addr = INREG(RADEON_DISPLAY2_BASE_ADDR);
+        save->ov0_base_addr      = INREG(RADEON_OV0_BASE_ADDR);
+    }
 }
 
-/* Read DAC registers */
-static void RADEONSaveDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    save->dac_cntl              = INREG(RADEON_DAC_CNTL);
-    save->dac2_cntl             = INREG(RADEON_DAC_CNTL2);
-    save->tv_dac_cntl           = INREG(RADEON_TV_DAC_CNTL);
-    save->disp_output_cntl      = INREG(RADEON_DISP_OUTPUT_CNTL);
-    save->disp_tv_out_cntl      = INREG(RADEON_DISP_TV_OUT_CNTL);
-    save->disp_hw_debug         = INREG(RADEON_DISP_HW_DEBUG);
-    save->dac_macro_cntl        = INREG(RADEON_DAC_MACRO_CNTL);
-    save->gpiopad_a             = INREG(RADEON_GPIOPAD_A);
 
-}
-
-static void RADEONSaveBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+#if 0
+/* Read palette data */
+static void RADEONSavePalette(ScrnInfoPtr pScrn, RADEONSavePtr save)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
+    int            i;
 
-    save->bios_4_scratch       = INREG(RADEON_BIOS_4_SCRATCH);
-    save->bios_5_scratch       = INREG(RADEON_BIOS_5_SCRATCH);
-    save->bios_6_scratch       = INREG(RADEON_BIOS_6_SCRATCH);
+#ifdef ENABLE_FLAT_PANEL
+    /* Select palette 0 (main CRTC) if using FP-enabled chip */
+ /* if (info->Port1 == MT_DFP) PAL_SELECT(1); */
+#endif
+    PAL_SELECT(1);
+    INPAL_START(0);
+    for (i = 0; i < 256; i++) save->palette2[i] = INPAL_NEXT();
+    PAL_SELECT(0);
+    INPAL_START(0);
+    for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT();
+    save->palette_valid = TRUE;
 }
+#endif
 
-/* Read flat panel registers */
-static void RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+void
+avivo_save(ScrnInfoPtr pScrn, RADEONSavePtr save)
 {
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONInfoPtr info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-
-    save->fp_gen_cntl          = INREG(RADEON_FP_GEN_CNTL);
-    save->fp2_gen_cntl          = INREG (RADEON_FP2_GEN_CNTL);
-    save->fp_horz_stretch      = INREG(RADEON_FP_HORZ_STRETCH);
-    save->fp_vert_stretch      = INREG(RADEON_FP_VERT_STRETCH);
-    save->lvds_gen_cntl        = INREG(RADEON_LVDS_GEN_CNTL);
-    save->lvds_pll_cntl        = INREG(RADEON_LVDS_PLL_CNTL);
-    save->tmds_pll_cntl        = INREG(RADEON_TMDS_PLL_CNTL);
-    save->tmds_transmitter_cntl= INREG(RADEON_TMDS_TRANSMITTER_CNTL);
-
-    if (info->ChipFamily == CHIP_FAMILY_RV280) {
-	/* bit 22 of TMDS_PLL_CNTL is read-back inverted */
-	save->tmds_pll_cntl ^= (1 << 22);
+    struct avivo_state *state = &save->avivo;
+
+    //    state->vga_memory_base = INREG(AVIVO_VGA_MEMORY_BASE);
+    //    state->vga_fb_start = INREG(AVIVO_VGA_FB_START);
+    state->vga1_cntl = INREG(AVIVO_D1VGA_CONTROL);
+    state->vga2_cntl = INREG(AVIVO_D2VGA_CONTROL);
+
+    state->crtc_master_en = INREG(AVIVO_DC_CRTC_MASTER_EN);
+    state->crtc_tv_control = INREG(AVIVO_DC_CRTC_TV_CONTROL);
+
+    state->pll1.ref_div_src = INREG(AVIVO_EXT1_PPLL_REF_DIV_SRC);
+    state->pll1.ref_div = INREG(AVIVO_EXT1_PPLL_REF_DIV);
+    state->pll1.fb_div = INREG(AVIVO_EXT1_PPLL_FB_DIV);
+    state->pll1.post_div_src = INREG(AVIVO_EXT1_PPLL_POST_DIV_SRC);
+    state->pll1.post_div = INREG(AVIVO_EXT1_PPLL_POST_DIV);
+    state->pll1.ext_ppll_cntl = INREG(AVIVO_EXT1_PPLL_CNTL);
+    state->pll1.pll_cntl = INREG(AVIVO_P1PLL_CNTL);
+    state->pll1.int_ss_cntl = INREG(AVIVO_P1PLL_INT_SS_CNTL);
+
+    state->pll2.ref_div_src = INREG(AVIVO_EXT1_PPLL_REF_DIV_SRC);
+    state->pll2.ref_div = INREG(AVIVO_EXT2_PPLL_REF_DIV);
+    state->pll2.fb_div = INREG(AVIVO_EXT2_PPLL_FB_DIV);
+    state->pll2.post_div_src = INREG(AVIVO_EXT2_PPLL_POST_DIV_SRC);
+    state->pll2.post_div = INREG(AVIVO_EXT2_PPLL_POST_DIV);
+    state->pll2.ext_ppll_cntl = INREG(AVIVO_EXT2_PPLL_CNTL);
+    state->pll2.pll_cntl = INREG(AVIVO_P2PLL_CNTL);
+    state->pll2.int_ss_cntl = INREG(AVIVO_P2PLL_INT_SS_CNTL);
+
+    state->crtc1.pll_source = INREG(AVIVO_PCLK_CRTC1_CNTL);
+
+    state->crtc1.h_total = INREG(AVIVO_D1CRTC_H_TOTAL);
+    state->crtc1.h_blank_start_end = INREG(AVIVO_D1CRTC_H_BLANK_START_END);
+    state->crtc1.h_sync_a = INREG(AVIVO_D1CRTC_H_SYNC_A);
+    state->crtc1.h_sync_a_cntl = INREG(AVIVO_D1CRTC_H_SYNC_A_CNTL);
+    state->crtc1.h_sync_b = INREG(AVIVO_D1CRTC_H_SYNC_B);
+    state->crtc1.h_sync_b_cntl = INREG(AVIVO_D1CRTC_H_SYNC_B_CNTL);
+
+    state->crtc1.v_total = INREG(AVIVO_D1CRTC_V_TOTAL);
+    state->crtc1.v_blank_start_end = INREG(AVIVO_D1CRTC_V_BLANK_START_END);
+    state->crtc1.v_sync_a = INREG(AVIVO_D1CRTC_V_SYNC_A);
+    state->crtc1.v_sync_a_cntl = INREG(AVIVO_D1CRTC_V_SYNC_A_CNTL);
+    state->crtc1.v_sync_b = INREG(AVIVO_D1CRTC_V_SYNC_B);
+    state->crtc1.v_sync_b_cntl = INREG(AVIVO_D1CRTC_V_SYNC_B_CNTL);
+
+    state->crtc1.control = INREG(AVIVO_D1CRTC_CONTROL);
+    state->crtc1.blank_control = INREG(AVIVO_D1CRTC_BLANK_CONTROL);
+    state->crtc1.interlace_control = INREG(AVIVO_D1CRTC_INTERLACE_CONTROL);
+    state->crtc1.stereo_control = INREG(AVIVO_D1CRTC_STEREO_CONTROL);
+
+    state->crtc1.cursor_control = INREG(AVIVO_D1CUR_CONTROL);
+
+    state->grph1.enable = INREG(AVIVO_D1GRPH_ENABLE);
+    state->grph1.control = INREG(AVIVO_D1GRPH_CONTROL);
+    state->grph1.control = INREG(AVIVO_D1GRPH_CONTROL);
+    state->grph1.prim_surf_addr = INREG(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS);
+    state->grph1.sec_surf_addr = INREG(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS);
+    state->grph1.pitch = INREG(AVIVO_D1GRPH_PITCH);
+    state->grph1.x_offset = INREG(AVIVO_D1GRPH_SURFACE_OFFSET_X);
+    state->grph1.y_offset = INREG(AVIVO_D1GRPH_SURFACE_OFFSET_Y);
+    state->grph1.x_start = INREG(AVIVO_D1GRPH_X_START);
+    state->grph1.y_start = INREG(AVIVO_D1GRPH_Y_START);
+    state->grph1.x_end = INREG(AVIVO_D1GRPH_X_END);
+    state->grph1.y_end = INREG(AVIVO_D1GRPH_Y_END);
+
+    state->grph1.viewport_start = INREG(AVIVO_D1MODE_VIEWPORT_START);
+    state->grph1.viewport_size = INREG(AVIVO_D1MODE_VIEWPORT_SIZE);
+    state->grph1.scl_enable = INREG(AVIVO_D1SCL_SCALER_ENABLE);
+    state->grph1.scl_tap_control = INREG(AVIVO_D1SCL_SCALER_TAP_CONTROL);
+
+    state->crtc2.pll_source = INREG(AVIVO_PCLK_CRTC2_CNTL);
+
+    state->crtc2.h_total = INREG(AVIVO_D2CRTC_H_TOTAL);
+    state->crtc2.h_blank_start_end = INREG(AVIVO_D2CRTC_H_BLANK_START_END);
+    state->crtc2.h_sync_a = INREG(AVIVO_D2CRTC_H_SYNC_A);
+    state->crtc2.h_sync_a_cntl = INREG(AVIVO_D2CRTC_H_SYNC_A_CNTL);
+    state->crtc2.h_sync_b = INREG(AVIVO_D2CRTC_H_SYNC_B);
+    state->crtc2.h_sync_b_cntl = INREG(AVIVO_D2CRTC_H_SYNC_B_CNTL);
+
+    state->crtc2.v_total = INREG(AVIVO_D2CRTC_V_TOTAL);
+    state->crtc2.v_blank_start_end = INREG(AVIVO_D2CRTC_V_BLANK_START_END);
+    state->crtc2.v_sync_a = INREG(AVIVO_D2CRTC_V_SYNC_A);
+    state->crtc2.v_sync_a_cntl = INREG(AVIVO_D2CRTC_V_SYNC_A_CNTL);
+    state->crtc2.v_sync_b = INREG(AVIVO_D2CRTC_V_SYNC_B);
+    state->crtc2.v_sync_b_cntl = INREG(AVIVO_D2CRTC_V_SYNC_B_CNTL);
+
+    state->crtc2.control = INREG(AVIVO_D2CRTC_CONTROL);
+    state->crtc2.blank_control = INREG(AVIVO_D2CRTC_BLANK_CONTROL);
+    state->crtc2.interlace_control = INREG(AVIVO_D2CRTC_INTERLACE_CONTROL);
+    state->crtc2.stereo_control = INREG(AVIVO_D2CRTC_STEREO_CONTROL);
+
+    state->crtc2.cursor_control = INREG(AVIVO_D2CUR_CONTROL);
+
+    state->grph2.enable = INREG(AVIVO_D2GRPH_ENABLE);
+    state->grph2.control = INREG(AVIVO_D2GRPH_CONTROL);
+    state->grph2.control = INREG(AVIVO_D2GRPH_CONTROL);
+    state->grph2.prim_surf_addr = INREG(AVIVO_D2GRPH_PRIMARY_SURFACE_ADDRESS);
+    state->grph2.sec_surf_addr = INREG(AVIVO_D2GRPH_SECONDARY_SURFACE_ADDRESS);
+    state->grph2.pitch = INREG(AVIVO_D2GRPH_PITCH);
+    state->grph2.x_offset = INREG(AVIVO_D2GRPH_SURFACE_OFFSET_X);
+    state->grph2.y_offset = INREG(AVIVO_D2GRPH_SURFACE_OFFSET_Y);
+    state->grph2.x_start = INREG(AVIVO_D2GRPH_X_START);
+    state->grph2.y_start = INREG(AVIVO_D2GRPH_Y_START);
+    state->grph2.x_end = INREG(AVIVO_D2GRPH_X_END);
+    state->grph2.y_end = INREG(AVIVO_D2GRPH_Y_END);
+
+    state->grph2.viewport_start = INREG(AVIVO_D2MODE_VIEWPORT_START);
+    state->grph2.viewport_size = INREG(AVIVO_D2MODE_VIEWPORT_SIZE);
+    state->grph2.scl_enable = INREG(AVIVO_D2SCL_SCALER_ENABLE);
+    state->grph2.scl_tap_control = INREG(AVIVO_D2SCL_SCALER_TAP_CONTROL);
+
+    state->daca.enable = INREG(AVIVO_DACA_ENABLE);
+    state->daca.source_select = INREG(AVIVO_DACA_SOURCE_SELECT);
+    state->daca.force_output_cntl = INREG(AVIVO_DACA_FORCE_OUTPUT_CNTL);
+    state->daca.powerdown = INREG(AVIVO_DACA_POWERDOWN);
+
+    state->dacb.enable = INREG(AVIVO_DACB_ENABLE);
+    state->dacb.source_select = INREG(AVIVO_DACB_SOURCE_SELECT);
+    state->dacb.force_output_cntl = INREG(AVIVO_DACB_FORCE_OUTPUT_CNTL);
+    state->dacb.powerdown = INREG(AVIVO_DACB_POWERDOWN);
+
+    state->tmds1.cntl = INREG(AVIVO_TMDSA_CNTL);
+    state->tmds1.source_select = INREG(AVIVO_TMDSA_SOURCE_SELECT);
+    state->tmds1.bit_depth_cntl = INREG(AVIVO_TMDSA_BIT_DEPTH_CONTROL);
+    state->tmds1.data_sync = INREG(AVIVO_TMDSA_DATA_SYNCHRONIZATION);
+    state->tmds1.transmitter_enable = INREG(AVIVO_TMDSA_TRANSMITTER_ENABLE);
+    state->tmds1.transmitter_cntl = INREG(AVIVO_TMDSA_TRANSMITTER_CONTROL);
+
+    state->tmds2.cntl = INREG(AVIVO_LVTMA_CNTL);
+    state->tmds2.source_select = INREG(AVIVO_LVTMA_SOURCE_SELECT);
+    state->tmds2.bit_depth_cntl = INREG(AVIVO_LVTMA_BIT_DEPTH_CONTROL);
+    state->tmds2.data_sync = INREG(AVIVO_LVTMA_DATA_SYNCHRONIZATION);
+
+    if (info->ChipFamily >= CHIP_FAMILY_R600) {
+        state->tmds2.transmitter_enable = INREG(R600_LVTMA_TRANSMITTER_ENABLE);
+        state->tmds2.transmitter_cntl = INREG(R600_LVTMA_TRANSMITTER_CONTROL);
+        state->lvtma_pwrseq_cntl = INREG(R600_LVTMA_PWRSEQ_CNTL);
+        state->lvtma_pwrseq_state = INREG(R600_LVTMA_PWRSEQ_STATE);
+    } else {
+        state->tmds2.transmitter_enable = INREG(R500_LVTMA_TRANSMITTER_ENABLE);
+        state->tmds2.transmitter_cntl = INREG(R500_LVTMA_TRANSMITTER_CONTROL);
+        state->lvtma_pwrseq_cntl = INREG(R500_LVTMA_PWRSEQ_CNTL);
+        state->lvtma_pwrseq_state = INREG(R500_LVTMA_PWRSEQ_STATE);
     }
-}
-
-/* Read CRTC2 registers */
-static void RADEONSaveCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    save->crtc2_gen_cntl        = INREG(RADEON_CRTC2_GEN_CNTL);
-    save->crtc2_h_total_disp    = INREG(RADEON_CRTC2_H_TOTAL_DISP);
-    save->crtc2_h_sync_strt_wid = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
-    save->crtc2_v_total_disp    = INREG(RADEON_CRTC2_V_TOTAL_DISP);
-    save->crtc2_v_sync_strt_wid = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
-    save->crtc2_offset          = INREG(RADEON_CRTC2_OFFSET);
-    save->crtc2_offset_cntl     = INREG(RADEON_CRTC2_OFFSET_CNTL);
-    save->crtc2_pitch           = INREG(RADEON_CRTC2_PITCH);
-
-    if (IS_R300_VARIANT)
-	save->crtc2_tile_x0_y0 =  INREG(R300_CRTC2_TILE_X0_Y0);
-
-    save->fp_h2_sync_strt_wid   = INREG (RADEON_FP_H2_SYNC_STRT_WID);
-    save->fp_v2_sync_strt_wid   = INREG (RADEON_FP_V2_SYNC_STRT_WID);
 
-    if (info->ChipFamily == CHIP_FAMILY_RS400) {
-	save->rs480_unk_e30 = INREG(RADEON_RS480_UNK_e30);
-	save->rs480_unk_e34 = INREG(RADEON_RS480_UNK_e34);
-	save->rs480_unk_e38 = INREG(RADEON_RS480_UNK_e38);
-	save->rs480_unk_e3c = INREG(RADEON_RS480_UNK_e3c);
-    }
+    if (state->crtc1.control & AVIVO_CRTC_EN)
+	info->crtc_on = TRUE;
     
-    save->disp2_merge_cntl      = INREG(RADEON_DISP2_MERGE_CNTL);
-
-    /* track if the crtc is enabled for text restore */
-    if (save->crtc2_gen_cntl & RADEON_CRTC2_DISP_DIS)
-	info->crtc2_on = FALSE;
-    else
+    if (state->crtc2.control & AVIVO_CRTC_EN)
 	info->crtc2_on = TRUE;
 
 }
 
-/* Save horizontal/vertical timing code tables */
-static void RADEONSaveTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr save)
+void
+avivo_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONInfoPtr info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    CARD16 hTable;
-    CARD16 vTable;
-    CARD32 tmp;
-    unsigned i;
-
-    save->tv_uv_adr = INREG(RADEON_TV_UV_ADR);
-    hTable = RADEONGetHTimingTablesAddr(save->tv_uv_adr);
-    vTable = RADEONGetVTimingTablesAddr(save->tv_uv_adr);
-
-    /*
-     * Reset FIFO arbiter in order to be able to access FIFO RAM
-     */
-
-    OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
-				   | RADEON_CRT_ASYNC_RST
-				   | RADEON_RESTART_PHASE_FIX
-				   | RADEON_CRT_FIFO_CE_EN
-				   | RADEON_TV_FIFO_CE_EN
-				   | RADEON_TV_ON));
-
-    /*OUTREG(RADEON_TV_MASTER_CNTL, save->tv_master_cntl | RADEON_TV_ON);*/
-
-    ErrorF("saveTimingTables: reading timing tables\n");
-
-    for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2) {
-	tmp = RADEONReadTVFIFO(pScrn, hTable--);
-	save->h_code_timing[ i     ] = (CARD16)((tmp >> 14) & 0x3fff);
-	save->h_code_timing[ i + 1 ] = (CARD16)(tmp & 0x3fff);
-
-	if (save->h_code_timing[ i ] == 0 || save->h_code_timing[ i + 1 ] == 0)
-	    break;
-    }
-
-    for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2) {
-	tmp = RADEONReadTVFIFO(pScrn, vTable++);
-	save->v_code_timing[ i     ] = (CARD16)(tmp & 0x3fff);
-	save->v_code_timing[ i + 1 ] = (CARD16)((tmp >> 14) & 0x3fff);
-
-	if (save->v_code_timing[ i ] == 0 || save->v_code_timing[ i + 1 ] == 0)
-	    break;
+    struct avivo_state *state = &restore->avivo;
+
+    //    OUTMC(pScrn, AVIVO_MC_MEMORY_MAP, state->mc_memory_map);
+    //    OUTREG(AVIVO_VGA_MEMORY_BASE, state->vga_memory_base);
+    //    OUTREG(AVIVO_VGA_FB_START, state->vga_fb_start);
+
+
+    OUTREG(AVIVO_DC_CRTC_MASTER_EN, state->crtc_master_en);
+    OUTREG(AVIVO_DC_CRTC_TV_CONTROL, state->crtc_tv_control);
+
+    OUTREG(AVIVO_EXT1_PPLL_REF_DIV_SRC, state->pll1.ref_div_src);
+    OUTREG(AVIVO_EXT1_PPLL_REF_DIV, state->pll1.ref_div);
+    OUTREG(AVIVO_EXT1_PPLL_FB_DIV, state->pll1.fb_div);
+    OUTREG(AVIVO_EXT1_PPLL_POST_DIV_SRC, state->pll1.post_div_src);
+    OUTREG(AVIVO_EXT1_PPLL_POST_DIV, state->pll1.post_div);
+    OUTREG(AVIVO_EXT1_PPLL_CNTL, state->pll1.ext_ppll_cntl);
+    OUTREG(AVIVO_P1PLL_CNTL, state->pll1.pll_cntl);
+    OUTREG(AVIVO_P1PLL_INT_SS_CNTL, state->pll1.int_ss_cntl);
+
+    OUTREG(AVIVO_EXT2_PPLL_REF_DIV_SRC, state->pll2.ref_div_src);
+    OUTREG(AVIVO_EXT2_PPLL_REF_DIV, state->pll2.ref_div);
+    OUTREG(AVIVO_EXT2_PPLL_FB_DIV, state->pll2.fb_div);
+    OUTREG(AVIVO_EXT2_PPLL_POST_DIV_SRC, state->pll2.post_div_src);
+    OUTREG(AVIVO_EXT2_PPLL_POST_DIV, state->pll2.post_div);
+    OUTREG(AVIVO_EXT2_PPLL_CNTL, state->pll2.ext_ppll_cntl);
+    OUTREG(AVIVO_P2PLL_CNTL, state->pll2.pll_cntl);
+    OUTREG(AVIVO_P2PLL_INT_SS_CNTL, state->pll2.int_ss_cntl);
+
+    OUTREG(AVIVO_PCLK_CRTC1_CNTL, state->crtc1.pll_source);
+
+    OUTREG(AVIVO_D1CRTC_H_TOTAL, state->crtc1.h_total);
+    OUTREG(AVIVO_D1CRTC_H_BLANK_START_END, state->crtc1.h_blank_start_end);
+    OUTREG(AVIVO_D1CRTC_H_SYNC_A, state->crtc1.h_sync_a);
+    OUTREG(AVIVO_D1CRTC_H_SYNC_A_CNTL, state->crtc1.h_sync_a_cntl);
+    OUTREG(AVIVO_D1CRTC_H_SYNC_B, state->crtc1.h_sync_b);
+    OUTREG(AVIVO_D1CRTC_H_SYNC_B_CNTL, state->crtc1.h_sync_b_cntl);
+
+    OUTREG(AVIVO_D1CRTC_V_TOTAL, state->crtc1.v_total);
+    OUTREG(AVIVO_D1CRTC_V_BLANK_START_END, state->crtc1.v_blank_start_end);
+    OUTREG(AVIVO_D1CRTC_V_SYNC_A, state->crtc1.v_sync_a);
+    OUTREG(AVIVO_D1CRTC_V_SYNC_A_CNTL, state->crtc1.v_sync_a_cntl);
+    OUTREG(AVIVO_D1CRTC_V_SYNC_B, state->crtc1.v_sync_b);
+    OUTREG(AVIVO_D1CRTC_V_SYNC_B_CNTL, state->crtc1.v_sync_b_cntl);
+
+    OUTREG(AVIVO_D1CRTC_CONTROL, state->crtc1.control);
+    OUTREG(AVIVO_D1CRTC_BLANK_CONTROL, state->crtc1.blank_control);
+    OUTREG(AVIVO_D1CRTC_INTERLACE_CONTROL, state->crtc1.interlace_control);
+    OUTREG(AVIVO_D1CRTC_STEREO_CONTROL, state->crtc1.stereo_control);
+
+    OUTREG(AVIVO_D1CUR_CONTROL, state->crtc1.cursor_control);
+
+    OUTREG(AVIVO_D1GRPH_ENABLE, state->grph1.enable);
+    OUTREG(AVIVO_D1GRPH_CONTROL, state->grph1.control);
+    OUTREG(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS, state->grph1.prim_surf_addr);
+    OUTREG(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS, state->grph1.sec_surf_addr);
+    OUTREG(AVIVO_D1GRPH_PITCH, state->grph1.pitch);
+    OUTREG(AVIVO_D1GRPH_SURFACE_OFFSET_X, state->grph1.x_offset);
+    OUTREG(AVIVO_D1GRPH_SURFACE_OFFSET_Y, state->grph1.y_offset);
+    OUTREG(AVIVO_D1GRPH_X_START, state->grph1.x_start);
+    OUTREG(AVIVO_D1GRPH_Y_START, state->grph1.y_start);
+    OUTREG(AVIVO_D1GRPH_X_END, state->grph1.x_end);
+    OUTREG(AVIVO_D1GRPH_Y_END, state->grph1.y_end);
+
+    OUTREG(AVIVO_D1MODE_VIEWPORT_START, state->grph1.viewport_start);
+    OUTREG(AVIVO_D1MODE_VIEWPORT_SIZE, state->grph1.viewport_size);
+    OUTREG(AVIVO_D1SCL_SCALER_ENABLE, state->grph1.scl_enable);
+    OUTREG(AVIVO_D1SCL_SCALER_TAP_CONTROL, state->grph1.scl_tap_control);
+
+    OUTREG(AVIVO_PCLK_CRTC2_CNTL, state->crtc2.pll_source);
+
+    OUTREG(AVIVO_D2CRTC_H_TOTAL, state->crtc2.h_total);
+    OUTREG(AVIVO_D2CRTC_H_BLANK_START_END, state->crtc2.h_blank_start_end);
+    OUTREG(AVIVO_D2CRTC_H_SYNC_A, state->crtc2.h_sync_a);
+    OUTREG(AVIVO_D2CRTC_H_SYNC_A_CNTL, state->crtc2.h_sync_a_cntl);
+    OUTREG(AVIVO_D2CRTC_H_SYNC_B, state->crtc2.h_sync_b);
+    OUTREG(AVIVO_D2CRTC_H_SYNC_B_CNTL, state->crtc2.h_sync_b_cntl);
+
+    OUTREG(AVIVO_D2CRTC_V_TOTAL, state->crtc2.v_total);
+    OUTREG(AVIVO_D2CRTC_V_BLANK_START_END, state->crtc2.v_blank_start_end);
+    OUTREG(AVIVO_D2CRTC_V_SYNC_A, state->crtc2.v_sync_a);
+    OUTREG(AVIVO_D2CRTC_V_SYNC_A_CNTL, state->crtc2.v_sync_a_cntl);
+    OUTREG(AVIVO_D2CRTC_V_SYNC_B, state->crtc2.v_sync_b);
+    OUTREG(AVIVO_D2CRTC_V_SYNC_B_CNTL, state->crtc2.v_sync_b_cntl);
+
+    OUTREG(AVIVO_D2CRTC_CONTROL, state->crtc2.control);
+    OUTREG(AVIVO_D2CRTC_BLANK_CONTROL, state->crtc2.blank_control);
+    OUTREG(AVIVO_D2CRTC_INTERLACE_CONTROL, state->crtc2.interlace_control);
+    OUTREG(AVIVO_D2CRTC_STEREO_CONTROL, state->crtc2.stereo_control);
+
+    OUTREG(AVIVO_D2CUR_CONTROL, state->crtc2.cursor_control);
+
+    OUTREG(AVIVO_D2GRPH_ENABLE, state->grph2.enable);
+    OUTREG(AVIVO_D2GRPH_CONTROL, state->grph2.control);
+    OUTREG(AVIVO_D2GRPH_PRIMARY_SURFACE_ADDRESS, state->grph2.prim_surf_addr);
+    OUTREG(AVIVO_D2GRPH_SECONDARY_SURFACE_ADDRESS, state->grph2.sec_surf_addr);
+    OUTREG(AVIVO_D2GRPH_PITCH, state->grph2.pitch);
+    OUTREG(AVIVO_D2GRPH_SURFACE_OFFSET_X, state->grph2.x_offset);
+    OUTREG(AVIVO_D2GRPH_SURFACE_OFFSET_Y, state->grph2.y_offset);
+    OUTREG(AVIVO_D2GRPH_X_START, state->grph2.x_start);
+    OUTREG(AVIVO_D2GRPH_Y_START, state->grph2.y_start);
+    OUTREG(AVIVO_D2GRPH_X_END, state->grph2.x_end);
+    OUTREG(AVIVO_D2GRPH_Y_END, state->grph2.y_end);
+
+    OUTREG(AVIVO_D2MODE_VIEWPORT_START, state->grph2.viewport_start);
+    OUTREG(AVIVO_D2MODE_VIEWPORT_SIZE, state->grph2.viewport_size);
+    OUTREG(AVIVO_D2SCL_SCALER_ENABLE, state->grph2.scl_enable);
+    OUTREG(AVIVO_D2SCL_SCALER_TAP_CONTROL, state->grph2.scl_tap_control);
+
+    OUTREG(AVIVO_DACA_ENABLE, state->daca.enable);
+    OUTREG(AVIVO_DACA_SOURCE_SELECT, state->daca.source_select);
+    OUTREG(AVIVO_DACA_FORCE_OUTPUT_CNTL, state->daca.force_output_cntl);
+    OUTREG(AVIVO_DACA_POWERDOWN, state->daca.powerdown);
+
+    OUTREG(AVIVO_TMDSA_CNTL, state->tmds1.cntl);
+    OUTREG(AVIVO_TMDSA_BIT_DEPTH_CONTROL, state->tmds1.bit_depth_cntl);
+    OUTREG(AVIVO_TMDSA_DATA_SYNCHRONIZATION, state->tmds1.data_sync);
+    OUTREG(AVIVO_TMDSA_TRANSMITTER_ENABLE, state->tmds1.transmitter_enable);
+    OUTREG(AVIVO_TMDSA_TRANSMITTER_CONTROL, state->tmds1.transmitter_cntl);
+    OUTREG(AVIVO_TMDSA_SOURCE_SELECT, state->tmds1.source_select);
+
+    OUTREG(AVIVO_DACB_ENABLE, state->dacb.enable);
+    OUTREG(AVIVO_DACB_SOURCE_SELECT, state->dacb.source_select);
+    OUTREG(AVIVO_DACB_FORCE_OUTPUT_CNTL, state->dacb.force_output_cntl);
+    OUTREG(AVIVO_DACB_POWERDOWN, state->dacb.powerdown);
+
+    OUTREG(AVIVO_LVTMA_CNTL, state->tmds2.cntl);
+    OUTREG(AVIVO_LVTMA_BIT_DEPTH_CONTROL, state->tmds2.bit_depth_cntl);
+    OUTREG(AVIVO_LVTMA_DATA_SYNCHRONIZATION, state->tmds2.data_sync);
+    OUTREG(AVIVO_LVTMA_SOURCE_SELECT, state->tmds2.source_select);
+
+    if (info->ChipFamily >= CHIP_FAMILY_R600) {
+        OUTREG(R600_LVTMA_TRANSMITTER_ENABLE, state->tmds2.transmitter_enable);
+        OUTREG(R600_LVTMA_TRANSMITTER_CONTROL, state->tmds2.transmitter_cntl);
+        OUTREG(R600_LVTMA_PWRSEQ_CNTL, state->lvtma_pwrseq_cntl);
+        OUTREG(R600_LVTMA_PWRSEQ_STATE, state->lvtma_pwrseq_state);
+    } else {
+        OUTREG(R500_LVTMA_TRANSMITTER_ENABLE, state->tmds2.transmitter_enable);
+        OUTREG(R500_LVTMA_TRANSMITTER_CONTROL, state->tmds2.transmitter_cntl);
+        OUTREG(R500_LVTMA_PWRSEQ_CNTL, state->lvtma_pwrseq_cntl);
+        OUTREG(R500_LVTMA_PWRSEQ_STATE, state->lvtma_pwrseq_state);
     }
-}
-
-/* read TV regs */
-static void RADEONSaveTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    ErrorF("Entering TV Save\n");
-
-    save->tv_crc_cntl = INREG(RADEON_TV_CRC_CNTL);
-    save->tv_frestart = INREG(RADEON_TV_FRESTART);
-    save->tv_hrestart = INREG(RADEON_TV_HRESTART);
-    save->tv_vrestart = INREG(RADEON_TV_VRESTART);
-    save->tv_gain_limit_settings = INREG(RADEON_TV_GAIN_LIMIT_SETTINGS);
-    save->tv_hdisp = INREG(RADEON_TV_HDISP);
-    save->tv_hstart = INREG(RADEON_TV_HSTART);
-    save->tv_htotal = INREG(RADEON_TV_HTOTAL);
-    save->tv_linear_gain_settings = INREG(RADEON_TV_LINEAR_GAIN_SETTINGS);
-    save->tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL);
-    save->tv_rgb_cntl = INREG(RADEON_TV_RGB_CNTL);
-    save->tv_modulator_cntl1 = INREG(RADEON_TV_MODULATOR_CNTL1);
-    save->tv_modulator_cntl2 = INREG(RADEON_TV_MODULATOR_CNTL2);
-    save->tv_pre_dac_mux_cntl = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
-    save->tv_sync_cntl = INREG(RADEON_TV_SYNC_CNTL);
-    save->tv_timing_cntl = INREG(RADEON_TV_TIMING_CNTL);
-    save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
-    save->tv_upsamp_and_gain_cntl = INREG(RADEON_TV_UPSAMP_AND_GAIN_CNTL);
-    save->tv_vdisp = INREG(RADEON_TV_VDISP);
-    save->tv_ftotal = INREG(RADEON_TV_FTOTAL);
-    save->tv_vscaler_cntl1 = INREG(RADEON_TV_VSCALER_CNTL1);
-    save->tv_vscaler_cntl2 = INREG(RADEON_TV_VSCALER_CNTL2);
-    save->tv_vtotal = INREG(RADEON_TV_VTOTAL);
-    save->tv_y_fall_cntl = INREG(RADEON_TV_Y_FALL_CNTL);
-    save->tv_y_rise_cntl = INREG(RADEON_TV_Y_RISE_CNTL);
-    save->tv_y_saw_tooth_cntl = INREG(RADEON_TV_Y_SAW_TOOTH_CNTL);
-
-    save->tv_pll_cntl = INPLL(pScrn, RADEON_TV_PLL_CNTL);
-    save->tv_pll_cntl1 = INPLL(pScrn, RADEON_TV_PLL_CNTL1);
-
-    ErrorF("Save TV timing tables\n");
-
-    RADEONSaveTVTimingTables(pScrn, save);
-
-    ErrorF("TV Save done\n");
-}
-
-/* Read PLL registers */
-static void RADEONSavePLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
-    save->ppll_ref_div = INPLL(pScrn, RADEON_PPLL_REF_DIV);
-    save->ppll_div_3   = INPLL(pScrn, RADEON_PPLL_DIV_3);
-    save->htotal_cntl  = INPLL(pScrn, RADEON_HTOTAL_CNTL);
-    save->vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
-
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Read: 0x%08x 0x%08x 0x%08x\n",
-		   save->ppll_ref_div,
-		   save->ppll_div_3,
-		   (unsigned)save->htotal_cntl);
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Read: rd=%d, fd=%d, pd=%d\n",
-		   save->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
-		   save->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK,
-		   (save->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16);
-}
-
-/* Read PLL registers */
-static void RADEONSavePLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
-    save->p2pll_ref_div = INPLL(pScrn, RADEON_P2PLL_REF_DIV);
-    save->p2pll_div_0   = INPLL(pScrn, RADEON_P2PLL_DIV_0);
-    save->htotal_cntl2  = INPLL(pScrn, RADEON_HTOTAL2_CNTL);
-    save->pixclks_cntl  = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
 
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Read: 0x%08x 0x%08x 0x%08x\n",
-		   (unsigned)save->p2pll_ref_div,
-		   (unsigned)save->p2pll_div_0,
-		   (unsigned)save->htotal_cntl2);
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Read: rd=%u, fd=%u, pd=%u\n",
-		   (unsigned)(save->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK),
-		   (unsigned)(save->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK),
-		   (unsigned)((save->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK)
-			      >> 16));
+    OUTREG(AVIVO_D1VGA_CONTROL, state->vga1_cntl);
+    OUTREG(AVIVO_D2VGA_CONTROL, state->vga2_cntl);
 }
 
-#if 0
-/* Read palette data */
-static void RADEONSavePalette(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+void avivo_restore_vga_regs(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{    
+    RADEONInfoPtr info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    int            i;
+    struct avivo_state *state = &restore->avivo;
 
-#ifdef ENABLE_FLAT_PANEL
-    /* Select palette 0 (main CRTC) if using FP-enabled chip */
- /* if (info->Port1 == MT_DFP) PAL_SELECT(1); */
-#endif
-    PAL_SELECT(1);
-    INPAL_START(0);
-    for (i = 0; i < 256; i++) save->palette2[i] = INPAL_NEXT();
-    PAL_SELECT(0);
-    INPAL_START(0);
-    for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT();
-    save->palette_valid = TRUE;
+    OUTREG(AVIVO_D1VGA_CONTROL, state->vga1_cntl);
+    OUTREG(AVIVO_D2VGA_CONTROL, state->vga2_cntl);
 }
-#endif
 
 /* Save everything needed to restore the original VC state */
 static void RADEONSave(ScrnInfoPtr pScrn)
@@ -5124,7 +4310,7 @@ static void RADEONSave(ScrnInfoPtr pScrn)
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    RADEONSavePtr  save       = &info->SavedReg;
+    RADEONSavePtr  save       = info->SavedReg;
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONSave\n");
@@ -5148,26 +4334,33 @@ static void RADEONSave(ScrnInfoPtr pScrn)
 	vgaHWLock(hwp);
     }
 #endif
-    save->dp_datatype      = INREG(RADEON_DP_DATATYPE);
-    save->rbbm_soft_reset  = INREG(RADEON_RBBM_SOFT_RESET);
-    save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
-    RADEONPllErrataAfterIndex(info);
 
-    RADEONSaveMemMapRegisters(pScrn, save);
-    RADEONSaveCommonRegisters(pScrn, save);
-    RADEONSavePLLRegisters(pScrn, save);
-    RADEONSaveCrtcRegisters(pScrn, save);
-    RADEONSaveFPRegisters(pScrn, save);
-    RADEONSaveBIOSRegisters(pScrn, save);
-    RADEONSaveDACRegisters(pScrn, save);
-    if (pRADEONEnt->HasCRTC2) {
-	RADEONSaveCrtc2Registers(pScrn, save);
-	RADEONSavePLL2Registers(pScrn, save);
-    }
-    if (info->InternalTVOut)
-	RADEONSaveTVRegisters(pScrn, save);
-
-    RADEONSaveSurfaces(pScrn, save);
+    if (IS_AVIVO_VARIANT) {
+	RADEONSaveMemMapRegisters(pScrn, save);
+	avivo_save(pScrn, save);
+    } else {
+	save->dp_datatype      = INREG(RADEON_DP_DATATYPE);
+	save->rbbm_soft_reset  = INREG(RADEON_RBBM_SOFT_RESET);
+	save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
+	RADEONPllErrataAfterIndex(info);
+
+	RADEONSaveMemMapRegisters(pScrn, save);
+	RADEONSaveCommonRegisters(pScrn, save);
+	RADEONSavePLLRegisters(pScrn, save);
+	RADEONSaveCrtcRegisters(pScrn, save);
+	RADEONSaveFPRegisters(pScrn, save);
+	RADEONSaveBIOSRegisters(pScrn, save);
+	RADEONSaveDACRegisters(pScrn, save);
+	if (pRADEONEnt->HasCRTC2) {
+	    RADEONSaveCrtc2Registers(pScrn, save);
+	    RADEONSavePLL2Registers(pScrn, save);
+	}
+	if (info->InternalTVOut)
+	    RADEONSaveTVRegisters(pScrn, save);
+    }
+
+	RADEONSaveSurfaces(pScrn, save);
+
 }
 
 /* Restore the original (text) mode */
@@ -5176,7 +4369,7 @@ void RADEONRestore(ScrnInfoPtr pScrn)
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    RADEONSavePtr  restore    = &info->SavedReg;
+    RADEONSavePtr  restore    = info->SavedReg;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     xf86CrtcPtr crtc;
 
@@ -5190,33 +4383,40 @@ void RADEONRestore(ScrnInfoPtr pScrn)
 
     RADEONBlank(pScrn);
 
-    OUTREG(RADEON_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
-    RADEONPllErrataAfterIndex(info);
-    OUTREG(RADEON_RBBM_SOFT_RESET,  restore->rbbm_soft_reset);
-    OUTREG(RADEON_DP_DATATYPE,      restore->dp_datatype);
-    OUTREG(RADEON_GRPH_BUFFER_CNTL, restore->grph_buffer_cntl);
-    OUTREG(RADEON_GRPH2_BUFFER_CNTL, restore->grph2_buffer_cntl);
+    if (IS_AVIVO_VARIANT) {
+	RADEONRestoreMemMapRegisters(pScrn, restore);
+	avivo_restore(pScrn, restore);
+    } else {
+	OUTREG(RADEON_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
+	RADEONPllErrataAfterIndex(info);
+	OUTREG(RADEON_RBBM_SOFT_RESET,  restore->rbbm_soft_reset);
+	OUTREG(RADEON_DP_DATATYPE,      restore->dp_datatype);
+	OUTREG(RADEON_GRPH_BUFFER_CNTL, restore->grph_buffer_cntl);
+	OUTREG(RADEON_GRPH2_BUFFER_CNTL, restore->grph2_buffer_cntl);
 
-    RADEONRestoreMemMapRegisters(pScrn, restore);
-    RADEONRestoreCommonRegisters(pScrn, restore);
+    if (!info->IsSecondary) {
+	RADEONRestoreMemMapRegisters(pScrn, restore);
+	RADEONRestoreCommonRegisters(pScrn, restore);
 
-    if (pRADEONEnt->HasCRTC2) {
-	RADEONRestoreCrtc2Registers(pScrn, restore);
-	RADEONRestorePLL2Registers(pScrn, restore);
-    }
+	if (pRADEONEnt->HasCRTC2) {
+	    RADEONRestoreCrtc2Registers(pScrn, restore);
+	    RADEONRestorePLL2Registers(pScrn, restore);
+	}
 
-    RADEONRestoreBIOSRegisters(pScrn, restore);
-    RADEONRestoreCrtcRegisters(pScrn, restore);
-    RADEONRestorePLLRegisters(pScrn, restore);
-    RADEONRestoreRMXRegisters(pScrn, restore);
-    RADEONRestoreFPRegisters(pScrn, restore);
-    RADEONRestoreFP2Registers(pScrn, restore);
-    RADEONRestoreLVDSRegisters(pScrn, restore);
+	RADEONRestoreBIOSRegisters(pScrn, restore);
+	RADEONRestoreCrtcRegisters(pScrn, restore);
+	RADEONRestorePLLRegisters(pScrn, restore);
+	RADEONRestoreRMXRegisters(pScrn, restore);
+	RADEONRestoreFPRegisters(pScrn, restore);
+	RADEONRestoreFP2Registers(pScrn, restore);
+	RADEONRestoreLVDSRegisters(pScrn, restore);
 
-    if (info->InternalTVOut)
-	RADEONRestoreTVRegisters(pScrn, restore);
+	if (info->InternalTVOut)
+	    RADEONRestoreTVRegisters(pScrn, restore);
+    }
 
-    RADEONRestoreSurfaces(pScrn, restore);
+	RADEONRestoreSurfaces(pScrn, restore);
+    }
 
 #if 1
     /* Temp fix to "solve" VT switch problems.  When switching VTs on
@@ -5227,6 +4427,18 @@ void RADEONRestore(ScrnInfoPtr pScrn)
     usleep(100000);
 #endif
 
+    /* need to make sure we don't enable a crtc by accident or we may get a hang */
+    if (pRADEONEnt->HasCRTC2 && !info->IsSecondary) {
+	if (info->crtc2_on && xf86_config->num_crtc > 1) {
+	    crtc = xf86_config->crtc[1];
+	    crtc->funcs->dpms(crtc, DPMSModeOn);
+	}
+    }
+    if (info->crtc_on) {
+	crtc = xf86_config->crtc[0];
+	crtc->funcs->dpms(crtc, DPMSModeOn);
+    }
+
 #ifdef WITH_VGAHW
     if (info->VGAAccess) {
        vgaHWPtr hwp = VGAHWPTR(pScrn);
@@ -5243,20 +4455,11 @@ void RADEONRestore(ScrnInfoPtr pScrn)
     }
 #endif
 
-    /* need to make sure we don't enable a crtc by accident or we may get a hang */
-    if (pRADEONEnt->HasCRTC2) {
-	if (info->crtc2_on) {
-	    crtc = xf86_config->crtc[1];
-	    crtc->funcs->dpms(crtc, DPMSModeOn);
-	}
-    }
-    if (info->crtc_on) {
-	crtc = xf86_config->crtc[0];
-	crtc->funcs->dpms(crtc, DPMSModeOn);
-    }
     /* to restore console mode, DAC registers should be set after every other registers are set,
      * otherwise,we may get blank screen 
      */
+    if (IS_AVIVO_VARIANT)
+	avivo_restore_vga_regs(pScrn, restore);
     RADEONRestoreDACRegisters(pScrn, restore);
 
 #if 0
@@ -5470,7 +4673,7 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, Bool crtc2)
     crtcoffsetcntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
 #endif
     if (info->tilingEnabled) {
-        if (IS_R300_VARIANT) {
+        if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
 	/* On r300/r400 when tiling is enabled crtc_offset is set to the address of
 	 * the surface.  the x/y offsets are handled by the X_Y tile reg for each crtc
 	 * Makes tiling MUCH easier.
@@ -5527,7 +4730,7 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, Bool crtc2)
     }
 #endif
 
-    if (IS_R300_VARIANT) {
+    if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
 	OUTREG(xytilereg, crtcxytile);
     } else {
 	OUTREG(regcntl, crtcoffsetcntl);
@@ -5614,7 +4817,7 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
 
     }
 
-    RADEONRestoreSurfaces(pScrn, &info->ModeReg);
+    RADEONRestoreSurfaces(pScrn, info->ModeReg);
 #ifdef XF86DRI
     if (info->directRenderingEnabled) {
     	if (info->cardType == CARD_PCIE && info->pKernelDRMVersion->version_minor >= 19 && info->FbSecureSize)
@@ -5626,7 +4829,7 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
 	/* get the DRI back into shape after resume */
 	RADEONDRISetVBlankInterrupt (pScrn, TRUE);
 	RADEONDRIResume(pScrn->pScreen);
-	RADEONAdjustMemMapRegisters(pScrn, &info->ModeReg);
+	RADEONAdjustMemMapRegisters(pScrn, info->ModeReg);
 
     }
 #endif
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index 4da4841..3b0c734 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -105,6 +105,23 @@ RADEONLog2(int val)
 	return bits - 1;
 }
 
+static __inline__ int
+RADEONPow2(int num)
+{
+    int pot = 2;
+
+    if (num <= 2)
+	return num;
+
+    while (pot < num) {
+	pot *= 2;
+    }
+
+    return pot;
+}
+
+
+
 static __inline__ CARD32 F_TO_DW(float val)
 {
     union {
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index 2b7f0e8..20b96a5 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -55,7 +55,6 @@
 #include <string.h>
 
 #include "radeon.h"
-#include "atidri.h"
 
 #include "exa.h"
 
@@ -251,7 +250,7 @@ FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h,
 #endif
 #if X_BYTE_ORDER == X_BIG_ENDIAN 
     unsigned char *RADEONMMIO = info->MMIO;
-    unsigned int swapper = info->ModeReg.surface_cntl &
+    unsigned int swapper = info->ModeReg->surface_cntl &
 	    ~(RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP |
 	      RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP);
 #endif
@@ -311,7 +310,7 @@ FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h,
 
 #if X_BYTE_ORDER == X_BIG_ENDIAN
     /* restore byte swapping */
-    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);
+    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl);
 #endif
 
     return TRUE;
@@ -354,7 +353,7 @@ FUNC_NAME(RADEONDownloadFromScreen)(PixmapPtr pSrc, int x, int y, int w, int h,
     RINFO_FROM_SCREEN(pSrc->drawable.pScreen);
 #if X_BYTE_ORDER == X_BIG_ENDIAN
     unsigned char *RADEONMMIO = info->MMIO;
-    unsigned int swapper = info->ModeReg.surface_cntl &
+    unsigned int swapper = info->ModeReg->surface_cntl &
 	    ~(RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP |
 	      RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP);
 #endif
@@ -492,7 +491,7 @@ FUNC_NAME(RADEONDownloadFromScreen)(PixmapPtr pSrc, int x, int y, int w, int h,
 
 #if X_BYTE_ORDER == X_BIG_ENDIAN
     /* restore byte swapping */
-    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);
+    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl);
 #endif
 
     return TRUE;
@@ -534,9 +533,18 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
 
 #ifdef RENDER
     if (info->RenderAccel) {
-	if (info->ChipFamily >= CHIP_FAMILY_R300) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration "
-			       "unsupported on R300 type cards and newer.\n");
+	if ((info->ChipFamily >= CHIP_FAMILY_RV515) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS400))
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration "
+			       "unsupported on XPRESS, R500 and newer cards.\n");
+	else if (IS_R300_VARIANT) {
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration "
+			       "enabled for R300 type cards.\n");
+		info->exa->CheckComposite = R300CheckComposite;
+		info->exa->PrepareComposite =
+		    FUNC_NAME(R300PrepareComposite);
+		info->exa->Composite = FUNC_NAME(RadeonComposite);
+		info->exa->DoneComposite = RadeonDoneComposite;
 	} else if ((info->ChipFamily == CHIP_FAMILY_RV250) || 
 		   (info->ChipFamily == CHIP_FAMILY_RV280) || 
 		   (info->ChipFamily == CHIP_FAMILY_RS300) || 
diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c
index eae69c4..c642aff 100644
--- a/src/radeon_exa_render.c
+++ b/src/radeon_exa_render.c
@@ -121,6 +121,17 @@ static struct formatinfo R200TexFormats[] = {
     {PICT_a8,		R200_TXFORMAT_I8 | R200_TXFORMAT_ALPHA_IN_MAP},
 };
 
+static struct formatinfo R300TexFormats[] = {
+    {PICT_a8r8g8b8,	R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)},
+    {PICT_x8r8g8b8,	R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)},
+    {PICT_a8b8g8r8,	R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)},
+    {PICT_x8b8g8r8,	R300_EASY_TX_FORMAT(Z, Y, X, ONE, W8Z8Y8X8)},
+    {PICT_r5g6b5,	R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)},
+    {PICT_a1r5g5b5,	R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)},
+    {PICT_x1r5g5b5,	R300_EASY_TX_FORMAT(X, Y, Z, ONE, W1Z5Y5X5)},
+    {PICT_a8,		R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8)},
+};
+
 /* Common Radeon setup code */
 
 static Bool RADEONGetDestFormat(PicturePtr pDstPicture, CARD32 *dst_format)
@@ -148,6 +159,31 @@ static Bool RADEONGetDestFormat(PicturePtr pDstPicture, CARD32 *dst_format)
     return TRUE;
 }
 
+static Bool R300GetDestFormat(PicturePtr pDstPicture, CARD32 *dst_format)
+{
+    switch (pDstPicture->format) {
+    case PICT_a8r8g8b8:
+    case PICT_x8r8g8b8:
+	*dst_format = R300_COLORFORMAT_ARGB8888;
+	break;
+    case PICT_r5g6b5:
+	*dst_format = R300_COLORFORMAT_RGB565;
+	break;
+    case PICT_a1r5g5b5:
+    case PICT_x1r5g5b5:
+	*dst_format = R300_COLORFORMAT_ARGB1555;
+	break;
+    case PICT_a8:
+	*dst_format = R300_COLORFORMAT_I8;
+	break;
+    default:
+	ErrorF("Unsupported dest format 0x%x\n",
+	       (int)pDstPicture->format);
+	return FALSE;
+    }
+    return TRUE;
+}
+
 static CARD32 RADEONGetBlendCntl(int op, PicturePtr pMask, CARD32 dst_format)
 {
     CARD32 sblend, dblend;
@@ -706,9 +742,304 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture,
     return TRUE;
 }
 
-#ifdef ACCEL_CP
+#ifdef ONLY_ONCE
+
+static Bool R300CheckCompositeTexture(PicturePtr pPict, int unit)
+{
+    int w = pPict->pDrawable->width;
+    int h = pPict->pDrawable->height;
+    int i;
+
+    if ((w > 0x7ff) || (h > 0x7ff))
+	RADEON_FALLBACK(("Picture w/h too large (%dx%d)\n", w, h));
+
+    for (i = 0; i < sizeof(R300TexFormats) / sizeof(R300TexFormats[0]); i++)
+    {
+	if (R300TexFormats[i].fmt == pPict->format)
+	    break;
+    }
+    if (i == sizeof(R300TexFormats) / sizeof(R300TexFormats[0]))
+	RADEON_FALLBACK(("Unsupported picture format 0x%x\n",
+			 (int)pPict->format));
+
+    if (pPict->repeat && ((w & (w - 1)) != 0 || (h & (h - 1)) != 0))
+	RADEON_FALLBACK(("NPOT repeat unsupported (%dx%d)\n", w, h));
+
+    if (pPict->filter != PictFilterNearest &&
+	pPict->filter != PictFilterBilinear)
+	RADEON_FALLBACK(("Unsupported filter 0x%x\n", pPict->filter));
+
+    return TRUE;
+}
+
+#endif /* ONLY_ONCE */
+
+static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
+					int unit)
+{
+    RINFO_FROM_SCREEN(pPix->drawable.pScreen);
+    CARD32 txfilter, txformat0, txformat1, txoffset, txpitch;
+    int w = pPict->pDrawable->width;
+    int h = pPict->pDrawable->height;
+    int i, pixel_shift;
+    ACCEL_PREAMBLE();
+
+    TRACE;
+
+    txpitch = exaGetPixmapPitch(pPix);
+    txoffset = exaGetPixmapOffset(pPix) + info->fbLocation;
+
+    if ((txoffset & 0x1f) != 0)
+	RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset));
+    if ((txpitch & 0x1f) != 0)
+	RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch));
+
+    pixel_shift = pPix->drawable.bitsPerPixel >> 4;
+    txpitch >>= pixel_shift;
+    txpitch -= 1;
+
+    if (RADEONPixmapIsColortiled(pPix))
+	txoffset |= R300_MACRO_TILE;
+
+    for (i = 0; i < sizeof(R300TexFormats) / sizeof(R300TexFormats[0]); i++)
+    {
+	if (R300TexFormats[i].fmt == pPict->format)
+	    break;
+    }
+
+    txformat1 = R300TexFormats[i].card_fmt;
+
+    txformat0 = (((RADEONPow2(w) - 1) << R300_TXWIDTH_SHIFT) |
+		 ((RADEONPow2(h) - 1) << R300_TXHEIGHT_SHIFT));
+
+    if (pPict->repeat) {
+	ErrorF("repeat\n");
+	if ((h != 1) &&
+	    (((w * pPix->drawable.bitsPerPixel / 8 + 31) & ~31) != txpitch))
+	    RADEON_FALLBACK(("Width %d and pitch %u not compatible for repeat\n",
+			     w, (unsigned)txpitch));
+    } else
+	txformat0 |= R300_TXPITCH_EN;
+
+
+    info->texW[unit] = RADEONPow2(w);
+    info->texH[unit] = RADEONPow2(h);
+
+    switch (pPict->filter) {
+    case PictFilterNearest:
+	txfilter = (R300_TX_MAG_FILTER_NEAREST | R300_TX_MIN_FILTER_NEAREST);
+	break;
+    case PictFilterBilinear:
+	txfilter = (R300_TX_MAG_FILTER_LINEAR | R300_TX_MIN_FILTER_LINEAR);
+	break;
+    default:
+	RADEON_FALLBACK(("Bad filter 0x%x\n", pPict->filter));
+    }
+
+    BEGIN_ACCEL(6);
+    OUT_ACCEL_REG(R300_TX_FILTER0_0 + (unit * 4), txfilter);
+    OUT_ACCEL_REG(R300_TX_FILTER1_0 + (unit * 4), 0x0);
+    OUT_ACCEL_REG(R300_TX_FORMAT0_0 + (unit * 4), txformat0);
+    OUT_ACCEL_REG(R300_TX_FORMAT1_0 + (unit * 4), txformat1);
+    OUT_ACCEL_REG(R300_TX_FORMAT2_0 + (unit * 4), txpitch);
+    OUT_ACCEL_REG(R300_TX_OFFSET_0 + (unit * 4), txoffset);
+    FINISH_ACCEL();
+
+    if (pPict->transform != 0) {
+	is_transform[unit] = TRUE;
+	transform[unit] = pPict->transform;
+    } else {
+	is_transform[unit] = FALSE;
+    }
+
+    return TRUE;
+}
+
+#ifdef ONLY_ONCE
+
+static Bool R300CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+			       PicturePtr pDstPicture)
+{
+    CARD32 tmp1;
+    ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+    PixmapPtr pSrcPixmap, pDstPixmap;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int i;
+
+    TRACE;
+
+    /* Check for unsupported compositing operations. */
+    if (op >= sizeof(RadeonBlendOp) / sizeof(RadeonBlendOp[0]))
+	RADEON_FALLBACK(("Unsupported Composite op 0x%x\n", op));
+
+#if 1
+    /* Throw out cases that aren't going to be our rotation first */
+    if (pMaskPicture != NULL || op != PictOpSrc || pSrcPicture->pDrawable == NULL)
+	RADEON_FALLBACK(("Junk driver\n"));
+
+    if (pSrcPicture->pDrawable->type != DRAWABLE_WINDOW ||
+	pDstPicture->pDrawable->type != DRAWABLE_PIXMAP) {
+	RADEON_FALLBACK(("bad drawable\n"));
+    }
+
+    pSrcPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) pSrcPicture->pDrawable);
+    pDstPixmap = (PixmapPtr)pDstPicture->pDrawable;
+
+    /* Check if the dest is one of our shadow pixmaps */
+    for (i = 0; i < xf86_config->num_crtc; i++) {
+	xf86CrtcPtr crtc = xf86_config->crtc[i];
+
+	if (crtc->rotatedPixmap == pDstPixmap)
+	    break;
+    }
+    if (i == xf86_config->num_crtc)
+	RADEON_FALLBACK(("no rotated pixmap\n"));
+
+    if (pSrcPixmap != pScreen->GetScreenPixmap(pScreen))
+	RADEON_FALLBACK(("src not screen\n"));
+#endif
+
+
+    if (pMaskPicture != NULL && pMaskPicture->componentAlpha) {
+	/* Check if it's component alpha that relies on a source alpha and on
+	 * the source value.  We can only get one of those into the single
+	 * source value that we get to blend with.
+	 */
+	if (RadeonBlendOp[op].src_alpha &&
+	    (RadeonBlendOp[op].blend_cntl & RADEON_SRC_BLEND_MASK) !=
+	     RADEON_SRC_BLEND_GL_ZERO)
+	{
+	    RADEON_FALLBACK(("Component alpha not supported with source "
+			    "alpha and source value blending.\n"));
+	}
+    }
+
+    if (!R300CheckCompositeTexture(pSrcPicture, 0))
+	return FALSE;
+    if (pMaskPicture != NULL && !R300CheckCompositeTexture(pMaskPicture, 1))
+	return FALSE;
+
+    if (!R300GetDestFormat(pDstPicture, &tmp1))
+	return FALSE;
+
+    return TRUE;
+
+}
+#endif /* ONLY_ONCE */
+
+static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
+				PicturePtr pMaskPicture, PicturePtr pDstPicture,
+				PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
+{
+    RINFO_FROM_SCREEN(pDst->drawable.pScreen);
+    CARD32 dst_format, dst_offset, dst_pitch;
+    CARD32 txenable, colorpitch;
+    /*CARD32 blendcntl, cblend, ablend;*/
+    int pixel_shift;
+    ACCEL_PREAMBLE();
+
+    TRACE;
+
+    if (!info->XInited3D)
+	RADEONInit3DEngine(pScrn);
+
+    R300GetDestFormat(pDstPicture, &dst_format);
+    pixel_shift = pDst->drawable.bitsPerPixel >> 4;
+
+    dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation;
+    dst_pitch = exaGetPixmapPitch(pDst);
+    colorpitch = dst_pitch >> pixel_shift;
+
+    if (RADEONPixmapIsColortiled(pDst))
+	colorpitch |= R300_COLORTILE;
+
+    colorpitch |= dst_format;
+
+    if ((dst_offset & 0x0f) != 0)
+	RADEON_FALLBACK(("Bad destination offset 0x%x\n", (int)dst_offset));
+    if (((dst_pitch >> pixel_shift) & 0x7) != 0)
+	RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch));
+
+    if (!FUNC_NAME(R300TextureSetup)(pSrcPicture, pSrc, 0))
+	return FALSE;
+    txenable = R300_TEX_0_ENABLE;
+
+    if (pMask != NULL) {
+	if (!FUNC_NAME(R300TextureSetup)(pMaskPicture, pMask, 1))
+	    return FALSE;
+	txenable |= R300_TEX_1_ENABLE;
+    } else {
+	is_transform[1] = FALSE;
+    }
 
-#define VTX_DWORD_COUNT 6
+    RADEON_SWITCH_TO_3D();
+
+    BEGIN_ACCEL(6);
+    OUT_ACCEL_REG(R300_TX_INVALTAGS, 0x0);
+    OUT_ACCEL_REG(R300_TX_ENABLE, txenable);
+
+    OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
+    OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch);
+
+    OUT_ACCEL_REG(R300_RB3D_BLENDCNTL, 0x0);
+    OUT_ACCEL_REG(R300_RB3D_ABLENDCNTL, 0x0);
+
+#if 0
+    /* IN operator: Multiply src by mask components or mask alpha.
+     * BLEND_CTL_ADD is A * B + C.
+     * If a picture is a8, we have to explicitly zero its color values.
+     * If the destination is a8, we have to route the alpha to red, I think.
+     * If we're doing component alpha where the source for blending is going to
+     * be the source alpha (and there's no source value used), we have to zero
+     * the source's color values.
+     */
+    cblend = R200_TXC_OP_MADD | R200_TXC_ARG_C_ZERO;
+    ablend = R200_TXA_OP_MADD | R200_TXA_ARG_C_ZERO;
+
+    if (pDstPicture->format == PICT_a8 ||
+	(pMask && pMaskPicture->componentAlpha && RadeonBlendOp[op].src_alpha))
+    {
+	cblend |= R200_TXC_ARG_A_R0_ALPHA;
+    } else if (pSrcPicture->format == PICT_a8)
+	cblend |= R200_TXC_ARG_A_ZERO;
+    else
+	cblend |= R200_TXC_ARG_A_R0_COLOR;
+    ablend |= R200_TXA_ARG_A_R0_ALPHA;
+
+    if (pMask) {
+	if (pMaskPicture->componentAlpha &&
+	    pDstPicture->format != PICT_a8)
+	    cblend |= R200_TXC_ARG_B_R1_COLOR;
+	else
+	    cblend |= R200_TXC_ARG_B_R1_ALPHA;
+	ablend |= R200_TXA_ARG_B_R1_ALPHA;
+    } else {
+	cblend |= R200_TXC_ARG_B_ZERO | R200_TXC_COMP_ARG_B;
+	ablend |= R200_TXA_ARG_B_ZERO | R200_TXA_COMP_ARG_B;
+    }
+
+    OUT_ACCEL_REG(R200_PP_TXCBLEND_0, cblend);
+    OUT_ACCEL_REG(R200_PP_TXCBLEND2_0,
+	R200_TXC_CLAMP_0_1 | R200_TXC_OUTPUT_REG_R0);
+    OUT_ACCEL_REG(R200_PP_TXABLEND_0, ablend);
+    OUT_ACCEL_REG(R200_PP_TXABLEND2_0,
+	R200_TXA_CLAMP_0_1 | R200_TXA_OUTPUT_REG_R0);
+
+    /* Op operator. */
+    blendcntl = RADEONGetBlendCntl(op, pMaskPicture, pDstPicture->format);
+    OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, blendcntl);
+#endif
+
+    FINISH_ACCEL();
+
+    return TRUE;
+}
+
+#define VTX_COUNT 6
+#define R300_VTX_COUNT 4
+
+#ifdef ACCEL_CP
 
 #define VTX_OUT(_dstX, _dstY, _srcX, _srcY, _maskX, _maskY)	\
 do {								\
@@ -720,9 +1051,15 @@ do {								\
     OUT_RING_F(_maskY);						\
 } while (0)
 
-#else /* ACCEL_CP */
+#define VTX_OUT4(_dstX, _dstY, _srcX, _srcY)	                \
+do {								\
+    OUT_RING_F(_dstX);						\
+    OUT_RING_F(_dstY);						\
+    OUT_RING_F(_srcX);						\
+    OUT_RING_F(_srcY);						\
+} while (0)
 
-#define VTX_REG_COUNT 6
+#else /* ACCEL_CP */
 
 #define VTX_OUT(_dstX, _dstY, _srcX, _srcY, _maskX, _maskY)	\
 do {								\
@@ -734,6 +1071,14 @@ do {								\
     OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _maskY);		\
 } while (0)
 
+#define VTX_OUT4(_dstX, _dstY, _srcX, _srcY)	                \
+do {								\
+    OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _dstX);		\
+    OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _dstY);		\
+    OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _srcX);		\
+    OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _srcY);		\
+} while (0)
+
 #endif /* !ACCEL_CP */
 
 #ifdef ONLY_ONCE
@@ -759,6 +1104,7 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
 {
     RINFO_FROM_SCREEN(pDst->drawable.pScreen);
     int srcXend, srcYend, maskXend, maskYend;
+    int vtx_count;
     xPointFixed srcTopLeft, srcTopRight, srcBottomLeft, srcBottomRight;
     xPointFixed maskTopLeft, maskTopRight, maskBottomLeft, maskBottomRight;
     ACCEL_PREAMBLE();
@@ -766,7 +1112,7 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
     ENTER_DRAW(0);
 
     /*ErrorF("RadeonComposite (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n",
-	   srcX, srcY, maskX, maskY,dstX, dstY, w, h);*/
+          srcX, srcY, maskX, maskY,dstX, dstY, w, h);*/
 
     srcXend = srcX + w;
     srcYend = srcY + h;
@@ -804,11 +1150,19 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
 	transformPoint(transform[1], &maskBottomRight);
     }
 
+    vtx_count = (info->ChipFamily >= CHIP_FAMILY_R300) ? R300_VTX_COUNT : VTX_COUNT;
+
+    if (IS_R300_VARIANT) {
+	BEGIN_ACCEL(1);
+	OUT_ACCEL_REG(R300_VAP_VTX_SIZE, vtx_count);
+	FINISH_ACCEL();
+    }
+
 #ifdef ACCEL_CP
     if (info->ChipFamily < CHIP_FAMILY_R200) {
-	BEGIN_RING(4 * VTX_DWORD_COUNT + 3);
+	BEGIN_RING(4 * vtx_count + 3);
 	OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_3D_DRAW_IMMD,
-			    4 * VTX_DWORD_COUNT + 1));
+			    4 * vtx_count + 1));
 	OUT_RING(RADEON_CP_VC_FRMT_XY |
 		 RADEON_CP_VC_FRMT_ST0 |
 		 RADEON_CP_VC_FRMT_ST1);
@@ -818,16 +1172,24 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
 		 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
 		 (4 << RADEON_CP_VC_CNTL_NUM_SHIFT));
     } else {
-	BEGIN_RING(4 * VTX_DWORD_COUNT + 2);
+	if (IS_R300_VARIANT)
+	    BEGIN_RING(4 * vtx_count + 6);
+	else
+	    BEGIN_RING(4 * vtx_count + 2);
+
 	OUT_RING(CP_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2,
-			    4 * VTX_DWORD_COUNT));
+			    4 * vtx_count));
 	OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN |
 		 RADEON_CP_VC_CNTL_PRIM_WALK_RING |
 		 (4 << RADEON_CP_VC_CNTL_NUM_SHIFT));
     }
 
 #else /* ACCEL_CP */
-    BEGIN_ACCEL(1 + VTX_REG_COUNT * 4);
+    if (IS_R300_VARIANT)
+	BEGIN_ACCEL(3 + vtx_count * 4);
+    else
+	BEGIN_ACCEL(1 + vtx_count * 4);
+
     if (info->ChipFamily < CHIP_FAMILY_R200) {
 	OUT_ACCEL_REG(RADEON_SE_VF_CNTL, (RADEON_VF_PRIM_TYPE_TRIANGLE_FAN |
 					  RADEON_VF_PRIM_WALK_DATA |
@@ -846,6 +1208,22 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
 	VTX_OUT(dstX,     dstY + h,   srcX,     srcYend,  maskX,    maskYend);
 	VTX_OUT(dstX + w, dstY + h,   srcXend,  srcYend,  maskXend, maskYend);
 	VTX_OUT(dstX + w, dstY,	      srcXend,  srcY,     maskXend, maskY);
+    } else if (IS_R300_VARIANT) {
+	VTX_OUT4((float)dstX, (float)dstY,
+		 xFixedToFloat(srcTopLeft.x) / info->texW[0],
+		 xFixedToFloat(srcTopLeft.y) / info->texH[0]);
+
+	VTX_OUT4((float)dstX, (float)(dstY + h),
+		 xFixedToFloat(srcBottomLeft.x) / info->texW[0],
+		 xFixedToFloat(srcBottomLeft.y) / info->texH[0]);
+
+	VTX_OUT4((float)(dstX + w), (float)(dstY + h),
+		 xFixedToFloat(srcBottomRight.x) / info->texW[0],
+		 xFixedToFloat(srcBottomRight.y) / info->texH[0]);
+
+	VTX_OUT4((float)(dstX + w), (float)dstY,
+		 xFixedToFloat(srcTopRight.x) / info->texW[0],
+		 xFixedToFloat(srcTopRight.y) / info->texH[0]);
     } else {
 	VTX_OUT((float)dstX,                                      (float)dstY,
 	        xFixedToFloat(srcTopLeft.x) / info->texW[0],      xFixedToFloat(srcTopLeft.y) / info->texH[0],
@@ -861,6 +1239,11 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
 	        xFixedToFloat(maskTopRight.x) / info->texW[1],    xFixedToFloat(maskTopRight.y) / info->texH[1]);
     }
 
+    if (IS_R300_VARIANT) {
+	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA);
+	OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
+    }
+
 #ifdef ACCEL_CP
     ADVANCE_RING();
 #else
@@ -870,6 +1253,7 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
     LEAVE_DRAW(0);
 }
 #undef VTX_OUT
+#undef VTX_OUT4
 
 #ifdef ONLY_ONCE
 static void RadeonDoneComposite(PixmapPtr pDst)
diff --git a/src/radeon_macros.h b/src/radeon_macros.h
index efc9e82..7f532a8 100644
--- a/src/radeon_macros.h
+++ b/src/radeon_macros.h
@@ -92,12 +92,20 @@ do {									\
 
 #define OUTPAL_START(idx)						\
 do {									\
-    OUTREG8(RADEON_PALETTE_INDEX, (idx));				\
+    if (IS_AVIVO_VARIANT) {                                             \
+        OUTREG8(AVIVO_DC_LUT_RW_INDEX, (idx));				\
+    } else {                                                            \
+        OUTREG8(RADEON_PALETTE_INDEX, (idx));				\
+    }								        \
 } while (0)
 
 #define OUTPAL_NEXT(r, g, b)						\
 do {									\
-    OUTREG(RADEON_PALETTE_DATA, ((r) << 16) | ((g) << 8) | (b));	\
+    if (IS_AVIVO_VARIANT) {                                             \
+        OUTREG(AVIVO_DC_LUT_30_COLOR, ((r) << 22) | ((g) << 12) | ((b) << 2));	\
+    } else {                                                               \
+        OUTREG(RADEON_PALETTE_DATA, ((r) << 16) | ((g) << 8) | (b));	\
+    }								        \
 } while (0)
 
 #define OUTPAL_NEXT_CARD32(v)						\
@@ -113,20 +121,43 @@ do {									\
 
 #define INPAL_START(idx)						\
 do {									\
-    OUTREG(RADEON_PALETTE_INDEX, (idx) << 16);				\
+    if (IS_AVIVO_VARIANT) {                                             \
+        OUTREG8(AVIVO_DC_LUT_RW_INDEX, (idx));				\
+    } else {                                                            \
+        OUTREG(RADEON_PALETTE_INDEX, (idx) << 16);			\
+    }								        \
 } while (0)
 
-#define INPAL_NEXT() INREG(RADEON_PALETTE_DATA)
+#define INPAL_NEXT()                                                    \
+do {									\
+    if (IS_AVIVO_VARIANT) {                                             \
+        INREG(AVIVO_DC_LUT_30_COLOR);                                   \
+    } else {                                                            \
+        INREG(RADEON_PALETTE_DATA);                                     \
+    }								        \
+} while (0)
 
 #define PAL_SELECT(idx)							\
 do {									\
-    if (!idx) {								\
-	OUTREG(RADEON_DAC_CNTL2, INREG(RADEON_DAC_CNTL2) &		\
-	       (CARD32)~RADEON_DAC2_PALETTE_ACC_CTL);			\
-    } else {								\
-	OUTREG(RADEON_DAC_CNTL2, INREG(RADEON_DAC_CNTL2) |		\
-	       RADEON_DAC2_PALETTE_ACC_CTL);				\
-    }									\
+    if (IS_AVIVO_VARIANT) {                                             \
+        if (!idx) {							\
+	    OUTREG(AVIVO_DC_LUT_RW_SELECT, 0);                          \
+        } else {						        \
+	    OUTREG(AVIVO_DC_LUT_RW_SELECT, 1);                          \
+        }								\
+    } else {                                                            \
+        if (!idx) {							\
+	    OUTREG(RADEON_DAC_CNTL2, INREG(RADEON_DAC_CNTL2) &		\
+	           (CARD32)~RADEON_DAC2_PALETTE_ACC_CTL);		\
+        } else {							\
+	    OUTREG(RADEON_DAC_CNTL2, INREG(RADEON_DAC_CNTL2) |		\
+	           RADEON_DAC2_PALETTE_ACC_CTL);			\
+        }								\
+    }								        \
 } while (0)
 
+#define INMC(pScrn, addr) RADEONINMC(pScrn, addr)
+
+#define OUTMC(pScrn, addr, val) RADEONOUTMC(pScrn, addr, val)
+
 #endif
diff --git a/src/radeon_misc.c b/src/radeon_misc.c
index 17b987c..fc608dd 100644
--- a/src/radeon_misc.c
+++ b/src/radeon_misc.c
@@ -24,8 +24,6 @@
 #include "config.h"
 #endif
 
-#ifdef XFree86LOADER
-
 #include "ativersion.h"
 
 #include "radeon_probe.h"
@@ -66,11 +64,8 @@ RADEONSetup
     static Bool Inited = FALSE;
 
     if (!Inited) {
-        /* Ensure main driver module is loaded, but not as a submodule */
-        if (!xf86ServerIsOnlyDetecting() && !LoaderSymbol(ATI_NAME))
-            xf86LoadOneModule(ATI_DRIVER_NAME, Options);
-
-        RADEONLoaderRefSymLists();
+        if (xf86ServerIsOnlyDetecting() || !LoaderSymbol(ATI_NAME))
+            xf86AddDriver(&RADEON, Module, 0);
 
         Inited = TRUE;
     }
@@ -85,5 +80,3 @@ _X_EXPORT XF86ModuleData radeonModuleData =
     RADEONSetup,
     NULL
 };
-
-#endif /* XFree86LOADER */
diff --git a/src/radeon_mm_i2c.c b/src/radeon_mm_i2c.c
index cdb9437..0524fa9 100644
--- a/src/radeon_mm_i2c.c
+++ b/src/radeon_mm_i2c.c
@@ -410,14 +410,6 @@ void RADEONInitI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
         pPriv->i2c = NULL;
         return;
     } 
-    xf86LoaderReqSymbols("xf86CreateI2CBusRec", 
-                          "xf86I2CBusInit",
-                          "xf86DestroyI2CBus",
-                          "xf86CreateI2CDevRec",
-                          "xf86DestroyI2CDevRec",
-                          "xf86I2CDevInit",
-                          "xf86I2CWriteRead",
-                          NULL);
     pPriv->i2c=CreateI2CBusRec();
     pPriv->i2c->scrnIndex=pScrn->scrnIndex;
     pPriv->i2c->BusName="Radeon multimedia bus";
@@ -483,7 +475,6 @@ void RADEONInitI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
     }
     else
     {
-    xf86LoaderReqSymbols(FI1236SymbolsList, NULL);
     if(pPriv->fi1236 == NULL)
     {
         pPriv->fi1236 = xf86_Detect_FI1236(pPriv->i2c, FI1236_ADDR_1);
@@ -512,7 +503,6 @@ void RADEONInitI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
     }
     else    
     {
-    xf86LoaderReqSymbols(TDA9885SymbolsList, NULL);
     if(pPriv->tda9885 == NULL)
     {
         pPriv->tda9885 = xf86_Detect_tda9885(pPriv->i2c, TDA9885_ADDR_1);
@@ -537,7 +527,6 @@ void RADEONInitI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
 		}
 		else
 		{
-			xf86LoaderReqSymbols(TDA9885SymbolsList, NULL);
 			if(pPriv->tda9885 == NULL)
 			{
 				pPriv->tda9885 = xf86_Detect_tda9885(pPriv->i2c, TDA9885_ADDR_1);
@@ -560,7 +549,6 @@ void RADEONInitI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
 	}
 	else    
 	{
-		xf86LoaderReqSymbols(UDA1380SymbolsList, NULL);
 		if(pPriv->uda1380 == NULL)
 		{
 			pPriv->uda1380 = xf86_Detect_uda1380(pPriv->i2c, UDA1380_ADDR_1);
@@ -582,7 +570,6 @@ void RADEONInitI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
     } 
     else 
     {
-    xf86LoaderReqSymbols(MSP3430SymbolsList, NULL);
     if(pPriv->msp3430 == NULL)
     {
        pPriv->msp3430 = xf86_DetectMSP3430(pPriv->i2c, MSP3430_ADDR_1);
@@ -616,7 +603,6 @@ void RADEONInitI2C(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
     } 
     else 
     {
-    xf86LoaderReqSymbols(SAA7114SymbolsList, NULL);
     if(pPriv->saa7114 == NULL)
     {
        pPriv->saa7114 = xf86_DetectSAA7114(pPriv->i2c, SAA7114_ADDR_1);
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 3c4badd..2c72395 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -47,8 +47,8 @@
 #include "radeon.h"
 #include "radeon_reg.h"
 #include "radeon_macros.h"
-
 #include "radeon_version.h"
+#include "radeon_atombios.h"
 
 #include "xf86Modes.h"
 				/* DDC support */
@@ -59,26 +59,29 @@ void RADEONSetPitch (ScrnInfoPtr pScrn)
 {
     int  dummy = pScrn->virtualX;
     RADEONInfoPtr info = RADEONPTR(pScrn);
+    int pitch_mask = 0;
+    int align_large;
+
+    align_large = info->allowColorTiling || IS_AVIVO_VARIANT;
 
     /* FIXME: May need to validate line pitch here */
     switch (pScrn->depth / 8) {
-    case 1: if (info->allowColorTiling) dummy = (pScrn->virtualX + 255) & ~255;
-	else dummy = (pScrn->virtualX + 127) & ~127;
+    case 1: pitch_mask = align_large ? 255 : 127;
 	break;
-    case 2: if (info->allowColorTiling) dummy = (pScrn->virtualX + 127) & ~127;
-	else dummy = (pScrn->virtualX + 31) & ~31;
+    case 2: pitch_mask = align_large ? 127 : 31;
 	break;
     case 3:
-    case 4: if (info->allowColorTiling) dummy = (pScrn->virtualX + 63) & ~63;
-	else dummy = (pScrn->virtualX + 15) & ~15;
+    case 4: pitch_mask = align_large ? 63 : 15;
 	break;
     }
+    dummy = (pScrn->virtualX + pitch_mask) & ~pitch_mask;
     pScrn->displayWidth = dummy;
     info->CurrentLayout.displayWidth = pScrn->displayWidth;
 
 }
 
-static DisplayModePtr RADEONTVModes(xf86OutputPtr output)
+static DisplayModePtr
+RADEONTVModes(xf86OutputPtr output)
 {
     DisplayModePtr new  = NULL;
 
@@ -89,6 +92,55 @@ static DisplayModePtr RADEONTVModes(xf86OutputPtr output)
     return new;
 }
 
+static DisplayModePtr
+RADEONATOMTVModes(xf86OutputPtr output)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    DisplayModePtr  last       = NULL;
+    DisplayModePtr  new        = NULL;
+    DisplayModePtr  first      = NULL;
+    int max_v, i;
+    /* Add some common sizes */
+    int widths[5] = {640, 720, 800, 848, 1024};
+
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+	radeon_output->tvStd == TV_STD_NTSC_J ||
+	radeon_output->tvStd == TV_STD_PAL_M)
+	max_v = 480;
+    else
+	max_v = 600;
+
+    for (i = 0; i < 5; i++) {
+	new = xf86CVTMode(widths[i], max_v, 60.0, FALSE, FALSE);
+
+	new->type       = M_T_DRIVER;
+
+	if (radeon_output->tvStd == TV_STD_NTSC ||
+	    radeon_output->tvStd == TV_STD_NTSC_J ||
+	    radeon_output->tvStd == TV_STD_PAL_M) {
+	    if (widths[i] == 640)
+		new->type |= M_T_PREFERRED;
+	} else {
+	    if (widths[i] == 800)
+		new->type |= M_T_PREFERRED;
+	}
+
+	new->next       = NULL;
+	new->prev       = last;
+
+	if (last) last->next = new;
+	last = new;
+	if (!first) first = new;
+    }
+
+    if (last) {
+	last->next   = NULL; //first;
+	first->prev  = NULL; //last;
+    }
+
+    return first;
+}
+
 /* This is used only when no mode is specified for FP and no ddc is
  * available.  We force it to native mode, if possible.
  */
@@ -209,21 +261,46 @@ DisplayModePtr
 RADEONProbeOutputModes(xf86OutputPtr output)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
     DisplayModePtr	    modes = NULL;
+    AtomBiosArgRec atomBiosArg;
+    AtomBiosResult atomBiosResult;
 
     ErrorF("in RADEONProbeOutputModes\n");
 
     if (output->status == XF86OutputStatusConnected) {
-	if (radeon_output->type == OUTPUT_STV || radeon_output->type == OUTPUT_CTV) {
-	    modes = RADEONTVModes(output);
+	if (OUTPUT_IS_TV) {
+	    if (IS_AVIVO_VARIANT)
+		modes = RADEONATOMTVModes(output);
+	    else
+		modes = RADEONTVModes(output);
+	} else if (radeon_output->type == OUTPUT_CV) {
+	    atomBiosResult = RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
+					     ATOMBIOS_GET_CV_MODES, &atomBiosArg);
+	    if (atomBiosResult == ATOM_SUCCESS) {
+		modes = atomBiosArg.modes;
+	    }
 	} else {
 	    if (output->MonInfo)
 		modes = xf86OutputGetEDIDModes (output);
 	    if (modes == NULL) {
-		if (radeon_output->type == OUTPUT_LVDS)
-		    modes = RADEONFPNativeMode(output);
-		/* add the screen modes */
-		RADEONAddScreenModes(output, &modes);
+		if ((radeon_output->type == OUTPUT_LVDS) && info->IsAtomBios) {
+		    atomBiosResult = RHDAtomBiosFunc(pScrn->scrnIndex,
+						     info->atomBIOS,
+						     ATOMBIOS_GET_PANEL_EDID, &atomBiosArg);
+		    if (atomBiosResult == ATOM_SUCCESS) {
+			output->MonInfo = xf86InterpretEDID(pScrn->scrnIndex,
+							    atomBiosArg.EDIDBlock);
+			modes = xf86OutputGetEDIDModes(output);
+		    }
+		}
+		if (modes == NULL) {
+		    if (radeon_output->type == OUTPUT_LVDS)
+			modes = RADEONFPNativeMode(output);
+		    /* add the screen modes */
+		    RADEONAddScreenModes(output, &modes);
+		}
 	    }
 	}
     }
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 64c0438..5ef864e 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -46,19 +46,22 @@
 #include "radeon_probe.h"
 #include "radeon_version.h"
 #include "radeon_tv.h"
+#include "radeon_atombios.h"
 
-
-const char *MonTypeName[7] = {
+const char *MonTypeName[10] = {
   "AUTO",
   "NONE",
   "CRT",
   "LVDS",
   "TMDS",
   "CTV",
-  "STV"
+  "STV",
+  "CV",
+  "HDMI",
+  "DP"
 };
 
-const RADEONMonitorType MonTypeID[7] = {
+const RADEONMonitorType MonTypeID[10] = {
   MT_UNKNOWN, /* this is just a dummy value for AUTO DETECTION */
   MT_NONE,    /* NONE -> NONE */
   MT_CRT,     /* CRT -> CRT */
@@ -66,44 +69,26 @@ const RADEONMonitorType MonTypeID[7] = {
   MT_DFP,     /* DFPs are driven via TMDS */
   MT_CTV,     /* CTV -> CTV */
   MT_STV,     /* STV -> STV */
+  MT_CV,
+  MT_HDMI,
+  MT_DP
 };
 
 const char *TMDSTypeName[4] = {
-  "Unknown",
+  "None",
   "Internal",
   "External",
-  "None"
-};
-
-const char *DDCTypeName[7] = {
-  "None",
-  "MONID",
-  "DVI_DDC",
-  "VGA_DDC",
-  "CRT2_DDC",
-  "LCD_DDC",
-  "GPIO_DDC"
+  "LVTMA",
 };
 
 const char *DACTypeName[4] = {
-  "Unknown",
+  "None",
   "Primary",
   "TVDAC/ExtDAC",
-  "None"
+  "ExtDac"
 };
 
-const char *ConnectorTypeName[8] = {
-  "None",
-  "Proprietary/LVDS",
-  "VGA",
-  "DVI-I",
-  "DVI-D",
-  "CTV",
-  "STV",
-  "Unsupported"
-};
-
-const char *ConnectorTypeNameATOM[10] = {
+const char *ConnectorTypeName[17] = {
   "None",
   "VGA",
   "DVI-I",
@@ -113,16 +98,28 @@ const char *ConnectorTypeNameATOM[10] = {
   "CTV",
   "LVDS",
   "Digital",
+  "SCART",
+  "HDMI-A",
+  "HDMI-B",
+  "Unsupported",
+  "Unsupported",
+  "DIN",
+  "DisplayPort",
   "Unsupported"
 };
 
-const char *OutputType[10] = {
+const char *OutputType[11] = {
     "None",
     "VGA",
     "DVI",
+    "DVI",
+    "DVI",
     "LVDS",
     "S-video",
     "Composite",
+    "Component",
+    "HDMI",
+    "DisplayPort",
 };
 
 static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
@@ -147,110 +144,52 @@ static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
     {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RS400*/ /* FIXME: just values from rv380 used... */
 };
 
-static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output);
-static void RADEONUpdatePanelSize(xf86OutputPtr output);
-static RADEONMonitorType radeon_detect_tv(ScrnInfoPtr pScrn);
-static RADEONMonitorType radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color);
-static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color);
-static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn);
-static void RADEONGetTMDSInfoFromTable(xf86OutputPtr output);
-
-Bool
-RADEONDVOReadByte(I2CDevPtr dvo, int addr, CARD8 *ch)
-{
-    if (!xf86I2CReadByte(dvo, addr, ch)) {
-	xf86DrvMsg(dvo->pI2CBus->scrnIndex, X_ERROR,
-		   "Unable to read from %s Slave %d.\n",
-		   dvo->pI2CBus->BusName, dvo->SlaveAddr);
-	return FALSE;
-    }
-    return TRUE;
-}
-
-Bool
-RADEONDVOWriteByte(I2CDevPtr dvo, int addr, CARD8 ch)
+static const CARD32 default_tvdac_adj [CHIP_FAMILY_LAST] =
 {
-    if (!xf86I2CWriteByte(dvo, addr, ch)) {
-	xf86DrvMsg(dvo->pI2CBus->scrnIndex, X_ERROR,
-		   "Unable to write to %s Slave %d.\n",
-		   dvo->pI2CBus->BusName, dvo->SlaveAddr);
-	return FALSE;
-    }
-    return TRUE;
-}
-
-static I2CDevPtr
-RADEONDVODeviceInit(I2CBusPtr b, I2CSlaveAddr addr)
-{
-    I2CDevPtr dvo;
-
-    dvo = xcalloc(1, sizeof(I2CDevRec));
-    if (dvo == NULL)
-	return NULL;
-
-    dvo->DevName = "RADEON DVO Controller";
-    dvo->SlaveAddr = addr;
-    dvo->pI2CBus = b;
-    dvo->StartTimeout = b->StartTimeout;
-    dvo->BitTimeout = b->BitTimeout;
-    dvo->AcknTimeout = b->AcknTimeout;
-    dvo->ByteTimeout = b->ByteTimeout;
-
-    if (xf86I2CDevInit(dvo)) {
-	return dvo;
-    }
-
-    xfree(dvo);
-    return NULL;
-}
+    0x00000000,   /* unknown */
+    0x00000000,   /* legacy */
+    0x00000000,   /* r100 */
+    0x00280000,   /* rv100 */
+    0x00000000,   /* rs100 */
+    0x00880000,   /* rv200 */
+    0x00000000,   /* rs200 */
+    0x00000000,   /* r200 */
+    0x00770000,   /* rv250 */
+    0x00290000,   /* rs300 */
+    0x00560000,   /* rv280 */
+    0x00780000,   /* r300 */
+    0x00770000,   /* r350 */
+    0x00780000,   /* rv350 */
+    0x00780000,   /* rv380 */
+    0x01080000,   /* r420 */
+    0x01080000,   /* rv410 */ /* FIXME: just values from r420 used... */
+    0x00780000,   /* rs400 */ /* FIXME: just values from rv380 used... */
+};
 
-void
-RADEONRestoreDVOChip(ScrnInfoPtr pScrn, xf86OutputPtr output)
-{
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
-    if (!radeon_output->DVOChip)
-	return;
+static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output);
+static void RADEONUpdatePanelSize(xf86OutputPtr output);
+static void RADEONGetTMDSInfoFromTable(xf86OutputPtr output);
+#define AVIVO_I2C_DISABLE 0
+#define AVIVO_I2C_ENABLE 1
+static Bool AVIVOI2CDoLock(xf86OutputPtr output, int lock_state);
+
+extern void atombios_output_mode_set(xf86OutputPtr output,
+				     DisplayModePtr mode,
+				     DisplayModePtr adjusted_mode);
+extern void legacy_output_mode_set(xf86OutputPtr output,
+				   DisplayModePtr mode,
+				   DisplayModePtr adjusted_mode);
+extern void atombios_output_dpms(xf86OutputPtr output, int mode);
+extern void legacy_output_dpms(xf86OutputPtr output, int mode);
+extern RADEONMonitorType atombios_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output);
+extern RADEONMonitorType legacy_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output);
+extern int atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode);
+extern I2CDevPtr RADEONDVODeviceInit(I2CBusPtr b, I2CSlaveAddr addr);
 
-    OUTREG(radeon_output->dvo_i2c_reg, INREG(radeon_output->dvo_i2c_reg) &
-	   (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1));
-
-    if (!RADEONInitExtTMDSInfoFromBIOS(output)) {
-	if (radeon_output->DVOChip) {
-	    switch(info->ext_tmds_chip) {
-	    case RADEON_SIL_164:
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x30);
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x09, 0x00);
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0a, 0x90);
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0c, 0x89);
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x3b);
-		break;
-#if 0
-		/* needs work see bug 10418 */
-	    case RADEON_SIL_1178:
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0f, 0x44);
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0f, 0x4c);
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0e, 0x01);
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0a, 0x80);
-                RADEONDVOWriteByte(radeon_output->DVOChip, 0x09, 0x30);
-                RADEONDVOWriteByte(radeon_output->DVOChip, 0x0c, 0xc9);
-                RADEONDVOWriteByte(radeon_output->DVOChip, 0x0d, 0x70);
-                RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x32);
-                RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x33);
-		break;
-#endif
-	    default:
-		break;
-	    }
-	}
-    }
-}
 
 void RADEONPrintPortMap(ScrnInfoPtr pScrn)
 {
-    RADEONInfoPtr info       = RADEONPTR(pScrn);
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     RADEONOutputPrivatePtr radeon_output;
     xf86OutputPtr output;
@@ -260,33 +199,67 @@ void RADEONPrintPortMap(ScrnInfoPtr pScrn)
 	output = xf86_config->output[o];
 	radeon_output = output->driver_private;
 
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-		   "Port%d:\n Monitor   -- %s\n Connector -- %s\n DAC Type  -- %s\n TMDS Type -- %s\n DDC Type  -- %s\n", 
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		   "Port%d:\n Monitor   -- %s\n Connector -- %s\n DAC Type  -- %s\n TMDS Type -- %s\n DDC Type  -- 0x%x\n", 
 		   o,
 		   MonTypeName[radeon_output->MonType+1],
-		   info->IsAtomBios ? 
-		   ConnectorTypeNameATOM[radeon_output->ConnectorType]:
 		   ConnectorTypeName[radeon_output->ConnectorType],
-		   DACTypeName[radeon_output->DACType+1],
-		   TMDSTypeName[radeon_output->TMDSType+1],
-		   DDCTypeName[radeon_output->DDCType]);
+		   DACTypeName[radeon_output->DACType],
+		   TMDSTypeName[radeon_output->TMDSType],
+		   (unsigned int)radeon_output->ddc_i2c.mask_clk_reg);
     }
 
 }
 
 static RADEONMonitorType
+avivo_display_ddc_connected(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    RADEONMonitorType MonType = MT_NONE;
+    xf86MonPtr MonInfo = NULL;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    if (radeon_output->pI2CBus) {
+	AVIVOI2CDoLock(output, AVIVO_I2C_ENABLE);
+	MonInfo = xf86OutputGetEDID(output, radeon_output->pI2CBus);
+	AVIVOI2CDoLock(output, AVIVO_I2C_DISABLE);
+    }
+    if (MonInfo) {
+	if (!xf86ReturnOptValBool(info->Options, OPTION_IGNORE_EDID, FALSE))
+	    xf86OutputSetEDID(output, MonInfo);
+	if (radeon_output->type == OUTPUT_LVDS)
+	    MonType = MT_LCD;
+	else if (radeon_output->type == OUTPUT_DVI_D)
+	    MonType = MT_DFP;
+	else if (radeon_output->type == OUTPUT_HDMI)
+	    MonType = MT_DFP;
+	else if (radeon_output->type == OUTPUT_DVI_I && (MonInfo->rawData[0x14] & 0x80)) /* if it's digital and DVI */
+	    MonType = MT_DFP;
+	else
+	    MonType = MT_CRT;
+    } else MonType = MT_NONE;
+    
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "Output: %s, Detected Monitor Type: %d\n", output->name, MonType);
+
+    return MonType;
+}
+
+static RADEONMonitorType
 RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    unsigned long DDCReg;
+    CARD32 DDCReg;
     RADEONMonitorType MonType = MT_NONE;
     xf86MonPtr MonInfo = NULL;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    RADEONDDCType DDCType = radeon_output->DDCType;
     int i, j;
 
-    DDCReg = radeon_output->DDCReg;
+    if (!radeon_output->ddc_i2c.valid)
+	return MT_NONE;
+
+    DDCReg = radeon_output->ddc_i2c.mask_clk_reg;
 
     /* Read and output monitor info using DDC2 over I2C bus */
     if (radeon_output->pI2CBus && info->ddc2 && (DDCReg != RADEON_LCD_GPIO_MASK) && (DDCReg != RADEON_MDGPIO_EN_REG)) {
@@ -357,272 +330,24 @@ RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output)
     if (MonInfo) {
 	if (!xf86ReturnOptValBool(info->Options, OPTION_IGNORE_EDID, FALSE))
 	    xf86OutputSetEDID(output, MonInfo);
-	if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_LVDS_ATOM) ||
-	    (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_PROPRIETARY)) {
+	if (radeon_output->type == OUTPUT_LVDS)
 	    MonType = MT_LCD;
-	} else if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM) ||
-		 (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D)) {
+	else if (radeon_output->type == OUTPUT_DVI_D)
 	    MonType = MT_DFP;
-	} else if (radeon_output->type == OUTPUT_DVI &&
-		   (MonInfo->rawData[0x14] & 0x80)) { /* if it's digital and DVI */
+	else if (radeon_output->type == OUTPUT_HDMI)
 	    MonType = MT_DFP;
-	} else {
+	else if (radeon_output->type == OUTPUT_DVI_I && (MonInfo->rawData[0x14] & 0x80)) /* if it's digital and DVI */
+	    MonType = MT_DFP;
+	else
 	    MonType = MT_CRT;
-	}
     } else MonType = MT_NONE;
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "DDC Type: %d, Detected Monitor Type: %d\n", DDCType, MonType);
+	       "Output: %s, Detected Monitor Type: %d\n", output->name, MonType);
 
     return MonType;
 }
 
-#if 0
-static RADEONMonitorType
-RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
-{
-    RADEONInfoPtr info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    int		  bConnected = 0;
-
-    /* the monitor either wasn't connected or it is a non-DDC CRT.
-     * try to probe it
-     */
-    if(IsCrtDac) {
-	unsigned long ulOrigVCLK_ECP_CNTL;
-	unsigned long ulOrigDAC_CNTL;
-	unsigned long ulOrigDAC_MACRO_CNTL;
-	unsigned long ulOrigDAC_EXT_CNTL;
-	unsigned long ulOrigCRTC_EXT_CNTL;
-	unsigned long ulData;
-	unsigned long ulMask;
-
-	ulOrigVCLK_ECP_CNTL = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
-
-	ulData              = ulOrigVCLK_ECP_CNTL;
-	ulData             &= ~(RADEON_PIXCLK_ALWAYS_ONb
-				| RADEON_PIXCLK_DAC_ALWAYS_ONb);
-	ulMask              = ~(RADEON_PIXCLK_ALWAYS_ONb
-				|RADEON_PIXCLK_DAC_ALWAYS_ONb);
-	OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
-
-	ulOrigCRTC_EXT_CNTL = INREG(RADEON_CRTC_EXT_CNTL);
-	ulData              = ulOrigCRTC_EXT_CNTL;
-	ulData             |= RADEON_CRTC_CRT_ON;
-	OUTREG(RADEON_CRTC_EXT_CNTL, ulData);
-
-	ulOrigDAC_EXT_CNTL = INREG(RADEON_DAC_EXT_CNTL);
-	ulData             = ulOrigDAC_EXT_CNTL;
-	ulData            &= ~RADEON_DAC_FORCE_DATA_MASK;
-	ulData            |=  (RADEON_DAC_FORCE_BLANK_OFF_EN
-			       |RADEON_DAC_FORCE_DATA_EN
-			       |RADEON_DAC_FORCE_DATA_SEL_MASK);
-	if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
-	    (info->ChipFamily == CHIP_FAMILY_RV280))
-	    ulData |= (0x01b6 << RADEON_DAC_FORCE_DATA_SHIFT);
-	else
-	    ulData |= (0x01ac << RADEON_DAC_FORCE_DATA_SHIFT);
-
-	OUTREG(RADEON_DAC_EXT_CNTL, ulData);
-
-	/* turn on power so testing can go through */
-	ulOrigDAC_CNTL = INREG(RADEON_DAC_CNTL);
-	ulOrigDAC_CNTL &= ~RADEON_DAC_PDWN;
-	OUTREG(RADEON_DAC_CNTL, ulOrigDAC_CNTL);
-
-	ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
-	ulOrigDAC_MACRO_CNTL &= ~(RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
-				  RADEON_DAC_PDWN_B);
-	OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
-
-	/* Enable comparators and set DAC range to PS2 (VGA) output level */
-	ulData = ulOrigDAC_CNTL;
-	ulData |= RADEON_DAC_CMP_EN;
-	ulData &= ~RADEON_DAC_RANGE_CNTL_MASK;
-	ulData |= 0x2;
-	OUTREG(RADEON_DAC_CNTL, ulData);
-
-	/* Settle down */
-	usleep(10000);
-
-	/* Read comparators */
-	ulData     = INREG(RADEON_DAC_CNTL);
-	bConnected =  (RADEON_DAC_CMP_OUTPUT & ulData)?1:0;
-
-	/* Restore things */
-	ulData    = ulOrigVCLK_ECP_CNTL;
-	ulMask    = 0xFFFFFFFFL;
-	OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
-
-	OUTREG(RADEON_DAC_CNTL,      ulOrigDAC_CNTL     );
-	OUTREG(RADEON_DAC_EXT_CNTL,  ulOrigDAC_EXT_CNTL );
-	OUTREG(RADEON_CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
-
-	if (!bConnected) {
-	    /* Power DAC down if CRT is not connected */
-            ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
-            ulOrigDAC_MACRO_CNTL |= (RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
-	    	RADEON_DAC_PDWN_B);
-            OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
-
-	    ulData = INREG(RADEON_DAC_CNTL);
-	    ulData |= RADEON_DAC_PDWN;
-	    OUTREG(RADEON_DAC_CNTL, ulData);
-    	}
-    } else { /* TV DAC */
-
-        /* This doesn't seem to work reliably (maybe worse on some OEM cards),
-           for now we always return false. If one wants to connected a
-           non-DDC monitor on the DVI port when CRT port is also connected,
-           he will need to explicitly tell the driver in the config file
-           with Option MonitorLayout.
-        */
-        bConnected = FALSE;
-
-#if 0
-	if (info->ChipFamily == CHIP_FAMILY_R200) {
-	    unsigned long ulOrigGPIO_MONID;
-	    unsigned long ulOrigFP2_GEN_CNTL;
-	    unsigned long ulOrigDISP_OUTPUT_CNTL;
-	    unsigned long ulOrigCRTC2_GEN_CNTL;
-	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_A;
-	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_B;
-	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_C;
-	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_D;
-	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_E;
-	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_F;
-	    unsigned long ulOrigCRTC2_H_TOTAL_DISP;
-	    unsigned long ulOrigCRTC2_V_TOTAL_DISP;
-	    unsigned long ulOrigCRTC2_H_SYNC_STRT_WID;
-	    unsigned long ulOrigCRTC2_V_SYNC_STRT_WID;
-	    unsigned long ulData, i;
-
-	    ulOrigGPIO_MONID = INREG(RADEON_GPIO_MONID);
-	    ulOrigFP2_GEN_CNTL = INREG(RADEON_FP2_GEN_CNTL);
-	    ulOrigDISP_OUTPUT_CNTL = INREG(RADEON_DISP_OUTPUT_CNTL);
-	    ulOrigCRTC2_GEN_CNTL = INREG(RADEON_CRTC2_GEN_CNTL);
-	    ulOrigDISP_LIN_TRANS_GRPH_A = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
-	    ulOrigDISP_LIN_TRANS_GRPH_B = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
-	    ulOrigDISP_LIN_TRANS_GRPH_C = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
-	    ulOrigDISP_LIN_TRANS_GRPH_D = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
-	    ulOrigDISP_LIN_TRANS_GRPH_E = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
-	    ulOrigDISP_LIN_TRANS_GRPH_F = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
-
-	    ulOrigCRTC2_H_TOTAL_DISP = INREG(RADEON_CRTC2_H_TOTAL_DISP);
-	    ulOrigCRTC2_V_TOTAL_DISP = INREG(RADEON_CRTC2_V_TOTAL_DISP);
-	    ulOrigCRTC2_H_SYNC_STRT_WID = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
-	    ulOrigCRTC2_V_SYNC_STRT_WID = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
-
-	    ulData     = INREG(RADEON_GPIO_MONID);
-	    ulData    &= ~RADEON_GPIO_A_0;
-	    OUTREG(RADEON_GPIO_MONID, ulData);
-
-	    OUTREG(RADEON_FP2_GEN_CNTL, 0x0a000c0c);
-
-	    OUTREG(RADEON_DISP_OUTPUT_CNTL, 0x00000012);
-
-	    OUTREG(RADEON_CRTC2_GEN_CNTL, 0x06000000);
-	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
-	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
-	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
-	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
-	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
-	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
-	    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
-	    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
-	    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
-	    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
-
-	    for (i = 0; i < 200; i++) {
-		ulData     = INREG(RADEON_GPIO_MONID);
-		bConnected = (ulData & RADEON_GPIO_Y_0)?1:0;
-		if (!bConnected) break;
-
-		usleep(1000);
-	    }
-
-	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, ulOrigDISP_LIN_TRANS_GRPH_A);
-	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, ulOrigDISP_LIN_TRANS_GRPH_B);
-	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, ulOrigDISP_LIN_TRANS_GRPH_C);
-	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, ulOrigDISP_LIN_TRANS_GRPH_D);
-	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, ulOrigDISP_LIN_TRANS_GRPH_E);
-	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, ulOrigDISP_LIN_TRANS_GRPH_F);
-	    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, ulOrigCRTC2_H_TOTAL_DISP);
-	    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, ulOrigCRTC2_V_TOTAL_DISP);
-	    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, ulOrigCRTC2_H_SYNC_STRT_WID);
-	    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, ulOrigCRTC2_V_SYNC_STRT_WID);
-	    OUTREG(RADEON_CRTC2_GEN_CNTL, ulOrigCRTC2_GEN_CNTL);
-	    OUTREG(RADEON_DISP_OUTPUT_CNTL, ulOrigDISP_OUTPUT_CNTL);
-	    OUTREG(RADEON_FP2_GEN_CNTL, ulOrigFP2_GEN_CNTL);
-	    OUTREG(RADEON_GPIO_MONID, ulOrigGPIO_MONID);
-        } else {
-	    unsigned long ulOrigPIXCLKSDATA;
-	    unsigned long ulOrigTV_MASTER_CNTL;
-	    unsigned long ulOrigTV_DAC_CNTL;
-	    unsigned long ulOrigTV_PRE_DAC_MUX_CNTL;
-	    unsigned long ulOrigDAC_CNTL2;
-	    unsigned long ulData;
-	    unsigned long ulMask;
-
-	    ulOrigPIXCLKSDATA = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
-
-	    ulData            = ulOrigPIXCLKSDATA;
-	    ulData           &= ~(RADEON_PIX2CLK_ALWAYS_ONb
-				  | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
-	    ulMask            = ~(RADEON_PIX2CLK_ALWAYS_ONb
-			  | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
-	    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
-
-	    ulOrigTV_MASTER_CNTL = INREG(RADEON_TV_MASTER_CNTL);
-	    ulData               = ulOrigTV_MASTER_CNTL;
-	    ulData              &= ~RADEON_TVCLK_ALWAYS_ONb;
-	    OUTREG(RADEON_TV_MASTER_CNTL, ulData);
-
-	    ulOrigDAC_CNTL2 = INREG(RADEON_DAC_CNTL2);
-	    ulData          = ulOrigDAC_CNTL2;
-	    ulData          &= ~RADEON_DAC2_DAC2_CLK_SEL;
-	    OUTREG(RADEON_DAC_CNTL2, ulData);
-
-	    ulOrigTV_DAC_CNTL = INREG(RADEON_TV_DAC_CNTL);
-
-	    ulData  = 0x00880213;
-	    OUTREG(RADEON_TV_DAC_CNTL, ulData);
-
-	    ulOrigTV_PRE_DAC_MUX_CNTL = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
-
-	    ulData  =  (RADEON_Y_RED_EN
-			| RADEON_C_GRN_EN
-			| RADEON_CMP_BLU_EN
-			| RADEON_RED_MX_FORCE_DAC_DATA
-			| RADEON_GRN_MX_FORCE_DAC_DATA
-			| RADEON_BLU_MX_FORCE_DAC_DATA);
-            if (IS_R300_VARIANT)
-		ulData |= 0x180 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
-	    else
-		ulData |= 0x1f5 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
-	    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulData);
-
-	    usleep(10000);
-
-	    ulData     = INREG(RADEON_TV_DAC_CNTL);
-	    bConnected = (ulData & RADEON_TV_DAC_CMPOUT)?1:0;
-
-	    ulData    = ulOrigPIXCLKSDATA;
-	    ulMask    = 0xFFFFFFFFL;
-	    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
-
-	    OUTREG(RADEON_TV_MASTER_CNTL, ulOrigTV_MASTER_CNTL);
-	    OUTREG(RADEON_DAC_CNTL2, ulOrigDAC_CNTL2);
-	    OUTREG(RADEON_TV_DAC_CNTL, ulOrigTV_DAC_CNTL);
-	    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulOrigTV_PRE_DAC_MUX_CNTL);
-	}
-#endif
-	return MT_UNKNOWN;
-    }
-
-    return(bConnected ? MT_CRT : MT_NONE);
-}
-#endif
 
 /* Primary Head (DVI or Laptop Int. panel)*/
 /* A ddc capable display connected on DVI port */
@@ -633,38 +358,24 @@ void RADEONConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output)
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
     if (radeon_output->MonType == MT_UNKNOWN) {
-	if (radeon_output->type == OUTPUT_STV || radeon_output->type == OUTPUT_CTV) {
-	    if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_TVOUT, FALSE)) {
-		if (radeon_output->type == OUTPUT_STV)
-		    radeon_output->MonType = MT_STV;
+	if (IS_AVIVO_VARIANT) {
+	    radeon_output->MonType = avivo_display_ddc_connected(pScrn, output);
+	    if (!radeon_output->MonType) {
+		if (radeon_output->type == OUTPUT_LVDS)
+		    radeon_output->MonType = MT_LCD;
 		else
-		    radeon_output->MonType = MT_CTV;
-	    } else {
-		if (info->InternalTVOut) {
-		    if (radeon_output->load_detection)
-			radeon_output->MonType = radeon_detect_tv(pScrn);
-		    else
-			radeon_output->MonType = MT_NONE;
-		}
+		    radeon_output->MonType = atombios_dac_detect(pScrn, output);
 	    }
 	} else {
 	    radeon_output->MonType = RADEONDisplayDDCConnected(pScrn, output);
 	    if (!radeon_output->MonType) {
-		if (radeon_output->type == OUTPUT_LVDS || radeon_output->type == OUTPUT_DVI)
+		if (radeon_output->type == OUTPUT_LVDS || OUTPUT_IS_DVI)
 		    radeon_output->MonType = RADEONPortCheckNonDDC(pScrn, output);
 		if (!radeon_output->MonType) {
-		    if (radeon_output->DACType == DAC_PRIMARY) {
-			if (radeon_output->load_detection)
-			    radeon_output->MonType = radeon_detect_primary_dac(pScrn, TRUE);
-		    } else if (radeon_output->DACType == DAC_TVDAC) {
-			if (radeon_output->load_detection) {
-			    if (info->ChipFamily == CHIP_FAMILY_R200)
-				radeon_output->MonType = radeon_detect_ext_dac(pScrn);
-			    else
-				radeon_output->MonType = radeon_detect_tv_dac(pScrn, TRUE);
-			} else
-			    radeon_output->MonType = MT_NONE;
-		    }
+		    if (info->IsAtomBios)
+			radeon_output->MonType = atombios_dac_detect(pScrn, output);
+		    else
+			radeon_output->MonType = legacy_dac_detect(pScrn, output);
 		}
 	    }
 	}
@@ -675,11 +386,8 @@ void RADEONConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output)
 	RADEONUpdatePanelSize(output);
 
     if (output->MonInfo) {
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on connector: %s ----------------------\n",
-		   info->IsAtomBios ?
-		   ConnectorTypeNameATOM[radeon_output->ConnectorType]:
-		   ConnectorTypeName[radeon_output->ConnectorType]
-		   );
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on output: %s ----------------------\n",
+		   output->name);
 	xf86PrintEDID( output->MonInfo );
     }
 }
@@ -732,14 +440,18 @@ RADEONDetectLidStatus(ScrnInfoPtr pScrn)
 
 static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output)
 {
+    RADEONInfoPtr info = RADEONPTR(output->scrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONMonitorType MonType = MT_NONE;
 
     if (radeon_output->type == OUTPUT_LVDS) {
+	if (xf86ReturnOptValBool(info->Options, OPTION_IGNORE_LID_STATUS, TRUE))
+	    MonType = MT_LCD;
+	else
 #if defined(__powerpc__)
-	MonType = MT_LCD;
+	    MonType = MT_LCD;
 #else
-	MonType = RADEONDetectLidStatus(pScrn);
+	    MonType = RADEONDetectLidStatus(pScrn);
 #endif
     } /*else if (radeon_output->type == OUTPUT_DVI) {
 	if (radeon_output->TMDSType == TMDS_INT) {
@@ -752,7 +464,7 @@ static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr
 	}*/
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "Detected Monitor Type: %d\n", MonType);
+	       "Detected non-DDC Monitor Type: %d\n", MonType);
 
     return MonType;
 
@@ -761,15 +473,12 @@ static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr
 static void
 radeon_dpms(xf86OutputPtr output, int mode)
 {
-    switch(mode) {
-    case DPMSModeOn:
-	RADEONEnableDisplay(output, TRUE);
-	break;
-    case DPMSModeOff:
-    case DPMSModeSuspend:
-    case DPMSModeStandby:
-	RADEONEnableDisplay(output, FALSE);
-	break;
+    RADEONInfoPtr info = RADEONPTR(output->scrn);
+
+    if (IS_AVIVO_VARIANT) {
+	atombios_output_dpms(output, mode);
+    } else {
+	legacy_output_dpms(output, mode);
     }
 }
 
@@ -803,13 +512,32 @@ radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
 	    return MODE_BANDWIDTH;
     }
 
-    if (radeon_output->type == OUTPUT_STV ||
-	radeon_output->type == OUTPUT_CTV) {
+    if (OUTPUT_IS_TV) {
 	/* FIXME: Update when more modes are added */
-	if (pMode->HDisplay == 800 && pMode->VDisplay == 600)
-	    return MODE_OK;
-	else
-	    return MODE_CLOCK_RANGE;
+	if (IS_AVIVO_VARIANT) {
+	    int max_v;
+
+	    /* tv-scaler can scale horizontal width
+	     * but frame ends must match tv_pll
+	     * for now cap v size
+	     */
+	    if (radeon_output->tvStd == TV_STD_NTSC ||
+		radeon_output->tvStd == TV_STD_NTSC_J ||
+		radeon_output->tvStd == TV_STD_PAL_M)
+		max_v = 480;
+	    else
+		max_v = 600;
+
+	    if (pMode->VDisplay == max_v)
+		return MODE_OK;
+	    else
+		return MODE_CLOCK_RANGE;
+	} else {
+	    if (pMode->HDisplay == 800 && pMode->VDisplay == 600)
+		return MODE_OK;
+	    else
+		return MODE_CLOCK_RANGE;
+	}
     }
 
     if (radeon_output->type == OUTPUT_LVDS) {
@@ -830,6 +558,7 @@ static Bool
 radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 		    DisplayModePtr adjusted_mode)
 {
+    RADEONInfoPtr info = RADEONPTR(output->scrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
     radeon_output->Flags &= ~RADEON_USE_RMX;
@@ -840,35 +569,56 @@ radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 	xf86CrtcPtr crtc = output->crtc;
 	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
 
-	if (radeon_crtc->crtc_id == 0) {
+	if (IS_AVIVO_VARIANT || radeon_crtc->crtc_id == 0) {
 	    if (mode->HDisplay < radeon_output->PanelXRes ||
-		mode->VDisplay < radeon_output->PanelYRes)
+		mode->VDisplay < radeon_output->PanelYRes) {
 		radeon_output->Flags |= RADEON_USE_RMX;
+		if (IS_AVIVO_VARIANT) {
+		    /* set to the panel's native mode */
+		    adjusted_mode->HDisplay = radeon_output->PanelXRes;
+		    adjusted_mode->HDisplay = radeon_output->PanelYRes;
+		    adjusted_mode->HTotal = radeon_output->PanelXRes + radeon_output->HBlank;
+		    adjusted_mode->HSyncStart = radeon_output->PanelXRes + radeon_output->HOverPlus;
+		    adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + radeon_output->HSyncWidth;
+		    adjusted_mode->VTotal = radeon_output->PanelYRes + radeon_output->VBlank;
+		    adjusted_mode->VSyncStart = radeon_output->PanelYRes + radeon_output->VOverPlus;
+		    adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + radeon_output->VSyncWidth;
+		    /* update crtc values */
+		    xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
+		    /* adjust crtc values */
+		    adjusted_mode->CrtcHDisplay = radeon_output->PanelXRes;
+		    adjusted_mode->CrtcVDisplay = radeon_output->PanelYRes;
+		    adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + radeon_output->HBlank;
+		    adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + radeon_output->HOverPlus;
+		    adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + radeon_output->HSyncWidth;
+		    adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + radeon_output->VBlank;
+		    adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + radeon_output->VOverPlus;
+		    adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + radeon_output->VSyncWidth;
+		} else {
+		    /* set to the panel's native mode */
+		    adjusted_mode->HTotal = radeon_output->PanelXRes + radeon_output->HBlank;
+		    adjusted_mode->HSyncStart = radeon_output->PanelXRes + radeon_output->HOverPlus;
+		    adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + radeon_output->HSyncWidth;
+		    adjusted_mode->VTotal = radeon_output->PanelYRes + radeon_output->VBlank;
+		    adjusted_mode->VSyncStart = radeon_output->PanelYRes + radeon_output->VOverPlus;
+		    adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + radeon_output->VSyncWidth;
+		    adjusted_mode->Clock = radeon_output->DotClock;
+		    /* update crtc values */
+		    xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
+		    /* adjust crtc values */
+		    adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + radeon_output->HBlank;
+		    adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + radeon_output->HOverPlus;
+		    adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + radeon_output->HSyncWidth;
+		    adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + radeon_output->VBlank;
+		    adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + radeon_output->VOverPlus;
+		    adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + radeon_output->VSyncWidth;
+		}
+		adjusted_mode->Clock = radeon_output->DotClock;
+		adjusted_mode->Flags = radeon_output->Flags;
+	    }
 	}
     }
 
-    /* update timing for LVDS and DFP if RMX is active */
-    if (radeon_output->Flags & RADEON_USE_RMX) {
-	/* set to the panel's native mode */
-	adjusted_mode->HTotal = radeon_output->PanelXRes + radeon_output->HBlank;
-	adjusted_mode->HSyncStart = radeon_output->PanelXRes + radeon_output->HOverPlus;
-	adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + radeon_output->HSyncWidth;
-	adjusted_mode->VTotal = radeon_output->PanelYRes + radeon_output->VBlank;
-	adjusted_mode->VSyncStart = radeon_output->PanelYRes + radeon_output->VOverPlus;
-	adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + radeon_output->VSyncWidth;
-	/* update crtc values */
-	xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
-	/* adjust crtc values */
-	adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + radeon_output->HBlank;
-	adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + radeon_output->HOverPlus;
-	adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + radeon_output->HSyncWidth;
-	adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + radeon_output->VBlank;
-	adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + radeon_output->VOverPlus;
-	adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + radeon_output->VSyncWidth;
-	adjusted_mode->Clock = radeon_output->DotClock;
-	adjusted_mode->Flags = radeon_output->Flags;
-    }
-
     return TRUE;
 }
 
@@ -877,809 +627,23 @@ radeon_mode_prepare(xf86OutputPtr output)
 {
 }
 
-static void RADEONInitFPRegisters(xf86OutputPtr output, RADEONSavePtr save,
-				  DisplayModePtr mode, BOOL IsPrimary)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONEntPtr  pRADEONEnt = RADEONEntPriv(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    int i;
-    CARD32 tmp = info->SavedReg.tmds_pll_cntl & 0xfffff;
-
-    for (i=0; i<4; i++) {
-	if (radeon_output->tmds_pll[i].freq == 0) break;
-	if ((CARD32)(mode->Clock/10) < radeon_output->tmds_pll[i].freq) {
-	    tmp = radeon_output->tmds_pll[i].value ;
-	    break;
-	}
-    }
-
-    if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RV280)) {
-	if (tmp & 0xfff00000)
-	    save->tmds_pll_cntl = tmp;
-	else {
-	    save->tmds_pll_cntl = info->SavedReg.tmds_pll_cntl & 0xfff00000;
-	    save->tmds_pll_cntl |= tmp;
-	}
-    } else save->tmds_pll_cntl = tmp;
-
-    save->tmds_transmitter_cntl = info->SavedReg.tmds_transmitter_cntl &
-					~(RADEON_TMDS_TRANSMITTER_PLLRST);
-
-    if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_R200) || !pRADEONEnt->HasCRTC2)
-	save->tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN);
-    else /* weird, RV chips got this bit reversed? */
-        save->tmds_transmitter_cntl |= (RADEON_TMDS_TRANSMITTER_PLLEN);
-
-    save->fp_gen_cntl = info->SavedReg.fp_gen_cntl |
-			 (RADEON_FP_CRTC_DONT_SHADOW_VPAR |
-			  RADEON_FP_CRTC_DONT_SHADOW_HEND );
-
-    save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
-
-    if (pScrn->rgbBits == 8)
-        save->fp_gen_cntl |= RADEON_FP_PANEL_FORMAT;  /* 24 bit format */
-    else
-        save->fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */
-
-
-    if (IsPrimary) {
-	if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) {
-	    save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
-	    if (mode->Flags & RADEON_USE_RMX) 
-		save->fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX;
-	    else
-		save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1;
-	} else 
-	    save->fp_gen_cntl |= RADEON_FP_SEL_CRTC1;
-    } else {
-	if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) {
-	    save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
-	    save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2;
-	} else 
-	    save->fp_gen_cntl |= RADEON_FP_SEL_CRTC2;
-    }
-
-}
-
-static void RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save,
-				   DisplayModePtr mode, BOOL IsPrimary)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-
-
-    if (pScrn->rgbBits == 8) 
-	save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl |
-				RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */
-    else
-	save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl &
-				~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */
-
-    save->fp2_gen_cntl &= ~(RADEON_FP2_ON |
-			    RADEON_FP2_DVO_EN |
-			    RADEON_FP2_DVO_RATE_SEL_SDR);
-
-
-    /* XXX: these may be oem specific */
-    if (IS_R300_VARIANT) {
-	save->fp2_gen_cntl |= RADEON_FP2_PAD_FLOP_EN | R300_FP2_DVO_CLOCK_MODE_SINGLE;
-#if 0
-	if (mode->Clock > 165000)
-	    save->fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;
-#endif
-    }
-
-    if (IsPrimary) {
-        if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
-            save->fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK;
-	    if (mode->Flags & RADEON_USE_RMX)
-		save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX;
-        } else {
-            save->fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_CRTC2;
-	}
-    } else {
-        if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
-            save->fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK;
-            save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
-        } else {
-            save->fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2;
-        }
-    }
-
-}
-
-static void RADEONInitLVDSRegisters(xf86OutputPtr output, RADEONSavePtr save,
-				    DisplayModePtr mode, BOOL IsPrimary)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-
-    save->lvds_pll_cntl = (info->SavedReg.lvds_pll_cntl |
-			   RADEON_LVDS_PLL_EN);
-
-    save->lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET;
-
-    save->lvds_gen_cntl = info->SavedReg.lvds_gen_cntl;
-    save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
-    save->lvds_gen_cntl &= ~(RADEON_LVDS_ON |
-			     RADEON_LVDS_BLON |
-			     RADEON_LVDS_EN |
-			     RADEON_LVDS_RST_FM);
-
-    if (IS_R300_VARIANT)
-	save->lvds_pll_cntl &= ~(R300_LVDS_SRC_SEL_MASK);
-
-    if (IsPrimary) {
-	if (IS_R300_VARIANT) {
-	    if (mode->Flags & RADEON_USE_RMX)
-		save->lvds_pll_cntl |= R300_LVDS_SRC_SEL_RMX;
-	} else
-	    save->lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2;
-    } else {
-	if (IS_R300_VARIANT) {
-	    save->lvds_pll_cntl |= R300_LVDS_SRC_SEL_CRTC2;
-	} else
-	    save->lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2;
-    }
-
-}
-
-static void RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save,
-				   DisplayModePtr mode)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    int    xres = mode->HDisplay;
-    int    yres = mode->VDisplay;
-    float  Hratio, Vratio;
-
-    save->fp_vert_stretch = info->SavedReg.fp_vert_stretch &
-	                    RADEON_VERT_STRETCH_RESERVED;
-    save->fp_horz_stretch = info->SavedReg.fp_horz_stretch &
-	                    (RADEON_HORZ_FP_LOOP_STRETCH |
-	                     RADEON_HORZ_AUTO_RATIO_INC);
-
-    if (radeon_output->MonType != MT_LCD && radeon_output->MonType != MT_DFP)
-	return;
-
-    if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) {
-	Hratio = 1.0;
-	Vratio = 1.0;
-    } else {
-	if (xres > radeon_output->PanelXRes) xres = radeon_output->PanelXRes;
-	if (yres > radeon_output->PanelYRes) yres = radeon_output->PanelYRes;
-	    
-	Hratio = (float)xres/(float)radeon_output->PanelXRes;
-	Vratio = (float)yres/(float)radeon_output->PanelYRes;
-    }
-
-    if (Hratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) {
-	save->fp_horz_stretch |= ((xres/8-1)<<16);
-    } else {
-	save->fp_horz_stretch |= ((((unsigned long)
-				    (Hratio * RADEON_HORZ_STRETCH_RATIO_MAX)) &
-				   RADEON_HORZ_STRETCH_RATIO_MASK) |
-				  RADEON_HORZ_STRETCH_BLEND |
-				  RADEON_HORZ_STRETCH_ENABLE |
-				  ((radeon_output->PanelXRes/8-1)<<16));
-    }
-
-    if (Vratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) {
-	save->fp_vert_stretch |= ((yres-1)<<12);
-    } else {
-	save->fp_vert_stretch |= ((((unsigned long)(Vratio * RADEON_VERT_STRETCH_RATIO_MAX)) &
-				   RADEON_VERT_STRETCH_RATIO_MASK) |
-				  RADEON_VERT_STRETCH_ENABLE |
-				  RADEON_VERT_STRETCH_BLEND |
-				  ((radeon_output->PanelYRes-1)<<12));
-    }
-
-}
-
-static void RADEONInitDACRegisters(xf86OutputPtr output, RADEONSavePtr save,
-				  DisplayModePtr mode, BOOL IsPrimary)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-
-    if (IsPrimary) {
-	if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
-            save->disp_output_cntl = info->SavedReg.disp_output_cntl &
-					~RADEON_DISP_DAC_SOURCE_MASK;
-        } else {
-            save->dac2_cntl = info->SavedReg.dac2_cntl & ~(RADEON_DAC2_DAC_CLK_SEL);
-        }
-    } else {
-        if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
-            save->disp_output_cntl = info->SavedReg.disp_output_cntl &
-					~RADEON_DISP_DAC_SOURCE_MASK;
-            save->disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2;
-        } else {
-            save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC_CLK_SEL;
-        }
-    }
-    save->dac_cntl = (RADEON_DAC_MASK_ALL
-		      | RADEON_DAC_VGA_ADR_EN
-		      | (info->dac6bits ? 0 : RADEON_DAC_8BIT_EN));
-
-    save->dac_macro_cntl = info->SavedReg.dac_macro_cntl;
-}
-
-static void
-RADEONInitTvDacCntl(xf86OutputPtr output, RADEONSavePtr save)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
-    if (info->ChipFamily == CHIP_FAMILY_R420 ||
-	info->ChipFamily == CHIP_FAMILY_RV410) {
-	save->tv_dac_cntl = info->SavedReg.tv_dac_cntl &
-			     ~(RADEON_TV_DAC_STD_MASK |
-			       RADEON_TV_DAC_BGADJ_MASK |
-			       R420_TV_DAC_DACADJ_MASK |
-			       R420_TV_DAC_RDACPD |
-			       R420_TV_DAC_GDACPD |
-			       R420_TV_DAC_GDACPD |
-			       R420_TV_DAC_TVENABLE);
-    } else {
-	save->tv_dac_cntl = info->SavedReg.tv_dac_cntl &
-			     ~(RADEON_TV_DAC_STD_MASK |
-			       RADEON_TV_DAC_BGADJ_MASK |
-			       RADEON_TV_DAC_DACADJ_MASK |
-			       RADEON_TV_DAC_RDACPD |
-			       RADEON_TV_DAC_GDACPD |
-			       RADEON_TV_DAC_GDACPD);
-    }
-
-    save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
-			  RADEON_TV_DAC_NHOLD |
-			  RADEON_TV_DAC_STD_PS2 |
-			  radeon_output->tv_dac_adj);
-
-}
-
-static void RADEONInitDAC2Registers(xf86OutputPtr output, RADEONSavePtr save,
-				  DisplayModePtr mode, BOOL IsPrimary)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-
-    /*0x0028023;*/
-    RADEONInitTvDacCntl(output, save);
-
-    if (IS_R300_VARIANT)
-	save->gpiopad_a = info->SavedReg.gpiopad_a | 1;
-
-    save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
-
-    if (IsPrimary) {
-        if (IS_R300_VARIANT) {
-            save->disp_output_cntl = info->SavedReg.disp_output_cntl &
-					~RADEON_DISP_TVDAC_SOURCE_MASK;
-            save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC;
-        } else if (info->ChipFamily == CHIP_FAMILY_R200) {
-	    save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl &
-				  ~(R200_FP2_SOURCE_SEL_MASK |
-				    RADEON_FP2_DVO_RATE_SEL_SDR);
-	} else {
-            save->disp_hw_debug = info->SavedReg.disp_hw_debug | RADEON_CRT2_DISP1_SEL;
-        }
-    } else {
-        if (IS_R300_VARIANT) {
-            save->disp_output_cntl = info->SavedReg.disp_output_cntl &
-					~RADEON_DISP_TVDAC_SOURCE_MASK;
-            save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
-	} else if (info->ChipFamily == CHIP_FAMILY_R200) {
-	    save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl &
-				  ~(R200_FP2_SOURCE_SEL_MASK |
-				    RADEON_FP2_DVO_RATE_SEL_SDR);
-            save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
-        } else {
-            save->disp_hw_debug = info->SavedReg.disp_hw_debug &
-					~RADEON_CRT2_DISP1_SEL;
-        }
-    }
-}
-
-static void
-RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
-			  DisplayModePtr mode, xf86OutputPtr output,
-			  int crtc_num)
-{
-    Bool IsPrimary = crtc_num == 0 ? TRUE : FALSE;
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
-    if (crtc_num == 0)
-	RADEONInitRMXRegisters(output, save, mode);
-
-    if (radeon_output->MonType == MT_CRT) {
-	if (radeon_output->DACType == DAC_PRIMARY) {
-	    RADEONInitDACRegisters(output, save, mode, IsPrimary);
-	} else {
-	    RADEONInitDAC2Registers(output, save, mode, IsPrimary);
-	}
-    } else if (radeon_output->MonType == MT_LCD) {
-	RADEONInitLVDSRegisters(output, save, mode, IsPrimary);
-    } else if (radeon_output->MonType == MT_DFP) {
-	if (radeon_output->TMDSType == TMDS_INT) {
-	    RADEONInitFPRegisters(output, save, mode, IsPrimary);
-	} else {
-	    RADEONInitFP2Registers(output, save, mode, IsPrimary);
-	}
-    } else if (radeon_output->MonType == MT_STV ||
-	       radeon_output->MonType == MT_CTV) {
-	RADEONInitTVRegisters(output, save, mode, IsPrimary);
-    }
-}
-
 static void
 radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode,
-		  DisplayModePtr adjusted_mode)
+		DisplayModePtr adjusted_mode)
 {
-    ScrnInfoPtr	    pScrn = output->scrn;
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    xf86CrtcPtr	crtc = output->crtc;
-    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-
-    RADEONInitOutputRegisters(pScrn, &info->ModeReg, adjusted_mode, output, radeon_crtc->crtc_id);
-
-    if (radeon_crtc->crtc_id == 0)
-	RADEONRestoreRMXRegisters(pScrn, &info->ModeReg);
+    RADEONInfoPtr info = RADEONPTR(output->scrn);
 
-    switch(radeon_output->MonType) {
-    case MT_LCD:
-	ErrorF("restore LVDS\n");
-	RADEONRestoreLVDSRegisters(pScrn, &info->ModeReg);
-	break;
-    case MT_DFP:
-	if (radeon_output->TMDSType == TMDS_INT) {
-	    ErrorF("restore FP\n");
-	    RADEONRestoreFPRegisters(pScrn, &info->ModeReg);
-	} else {
-	    ErrorF("restore FP2\n");
-	    RADEONRestoreDVOChip(pScrn, output);
-	    RADEONRestoreFP2Registers(pScrn, &info->ModeReg);
-	}
-	break;
-    case MT_STV:
-    case MT_CTV:
-	ErrorF("restore tv\n");
-	RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
-	RADEONRestoreTVRegisters(pScrn, &info->ModeReg);
-	break;
-    default:
-	ErrorF("restore dac\n");
-	RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
-    }
+    if (IS_AVIVO_VARIANT)
+	atombios_output_mode_set(output, mode, adjusted_mode);
+    else
+	legacy_output_mode_set(output, mode, adjusted_mode);
 
 }
 
 static void
 radeon_mode_commit(xf86OutputPtr output)
 {
-    RADEONEnableDisplay(output, TRUE);
-}
-
-/* the following functions are based on the load detection code
- * in the beos radeon driver by Thomas Kurschel and the existing
- * load detection code in this driver.
- */
-static RADEONMonitorType
-radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color)
-{
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    CARD32 vclk_ecp_cntl, crtc_ext_cntl;
-    CARD32 dac_ext_cntl, dac_cntl, dac_macro_cntl, tmp;
-    RADEONMonitorType found = MT_NONE;
-
-    /* save the regs we need */
-    vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
-    crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
-    dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
-    dac_cntl = INREG(RADEON_DAC_CNTL);
-    dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
-
-    tmp = vclk_ecp_cntl &
-	~(RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb);
-    OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
-
-    tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON;
-    OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
-
-    tmp = RADEON_DAC_FORCE_BLANK_OFF_EN |
-	RADEON_DAC_FORCE_DATA_EN;
-
-    if (color)
-	tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB;
-    else
-	tmp |= RADEON_DAC_FORCE_DATA_SEL_G;
-
-    if (IS_R300_VARIANT)
-	tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
-    else
-	tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
-
-    OUTREG(RADEON_DAC_EXT_CNTL, tmp);
-
-    tmp = dac_cntl & ~(RADEON_DAC_RANGE_CNTL_MASK | RADEON_DAC_PDWN);
-    tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;
-    OUTREG(RADEON_DAC_CNTL, tmp);
-
-    tmp &= ~(RADEON_DAC_PDWN_R |
-	     RADEON_DAC_PDWN_G |
-	     RADEON_DAC_PDWN_B);
-
-    OUTREG(RADEON_DAC_MACRO_CNTL, tmp);
-
-    usleep(2000);
-
-    if (INREG(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) {
-	found = MT_CRT;
-	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
-		    "Found %s CRT connected to primary DAC\n",
-		    color ? "color" : "bw");
-    }
-
-    /* restore the regs we used */
-    OUTREG(RADEON_DAC_CNTL, dac_cntl);
-    OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
-    OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
-    OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
-    OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, vclk_ecp_cntl);
-
-    return found;
-}
-
-static RADEONMonitorType
-radeon_detect_ext_dac(ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    CARD32 gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl;
-    CARD32 disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c;
-    CARD32 disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f;
-    CARD32 tmp, crtc2_h_total_disp, crtc2_v_total_disp;
-    CARD32 crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid;
-    RADEONMonitorType found = MT_NONE;
-    int connected = 0;
-    int i = 0;
-
-    /* save the regs we need */
-    gpio_monid = INREG(RADEON_GPIO_MONID);
-    fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL);
-    disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
-    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
-    disp_lin_trans_grph_a = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
-    disp_lin_trans_grph_b = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
-    disp_lin_trans_grph_c = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
-    disp_lin_trans_grph_d = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
-    disp_lin_trans_grph_e = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
-    disp_lin_trans_grph_f = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
-    crtc2_h_total_disp = INREG(RADEON_CRTC2_H_TOTAL_DISP);
-    crtc2_v_total_disp = INREG(RADEON_CRTC2_V_TOTAL_DISP);
-    crtc2_h_sync_strt_wid = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
-    crtc2_v_sync_strt_wid = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
-
-    tmp = INREG(RADEON_GPIO_MONID);
-    tmp &= ~RADEON_GPIO_A_0;
-    OUTREG(RADEON_GPIO_MONID, tmp);
-
-    OUTREG(RADEON_FP2_GEN_CNTL,
-	   RADEON_FP2_ON |
-	   RADEON_FP2_PANEL_FORMAT |
-	   R200_FP2_SOURCE_SEL_TRANS_UNIT |
-	   RADEON_FP2_DVO_EN |
-	   R200_FP2_DVO_RATE_SEL_SDR);
-
-    OUTREG(RADEON_DISP_OUTPUT_CNTL,
-	   RADEON_DISP_DAC_SOURCE_RMX |
-	   RADEON_DISP_TRANS_MATRIX_GRAPHICS);
-
-    OUTREG(RADEON_CRTC2_GEN_CNTL,
-	   RADEON_CRTC2_EN |
-	   RADEON_CRTC2_DISP_REQ_EN_B);
-
-    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
-    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
-    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
-    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
-    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
-    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
-
-    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
-    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
-    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
-    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
-
-    for (i = 0; i < 200; i++) {
-	tmp = INREG(RADEON_GPIO_MONID);
-	if (tmp & RADEON_GPIO_Y_0)
-	    connected = 1;
-	else
-	    connected = 0;
-
-	if (!connected)
-	    break;
-
-	usleep(1000);
-    }
-
-    if (connected)
-	found = MT_CRT;
-
-    /* restore the regs we used */
-    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a);
-    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b);
-    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c);
-    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d);
-    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e);
-    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f);
-    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp);
-    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp);
-    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid);
-    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid);
-    OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
-    OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
-    OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
-    OUTREG(RADEON_GPIO_MONID, gpio_monid);
-
-    return found;
-}
-
-static RADEONMonitorType
-radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color)
-{
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    CARD32 crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
-    CARD32 disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp;
-    RADEONMonitorType found = MT_NONE;
-
-    /* save the regs we need */
-    pixclks_cntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
-    gpiopad_a = IS_R300_VARIANT ? INREG(RADEON_GPIOPAD_A) : 0;
-    disp_output_cntl = IS_R300_VARIANT ? INREG(RADEON_DISP_OUTPUT_CNTL) : 0;
-    disp_hw_debug = !IS_R300_VARIANT ? INREG(RADEON_DISP_HW_DEBUG) : 0;
-    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
-    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
-    dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
-    dac_cntl2 = INREG(RADEON_DAC_CNTL2);
-
-    tmp = pixclks_cntl & ~(RADEON_PIX2CLK_ALWAYS_ONb
-			   | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
-    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
-
-    if (IS_R300_VARIANT) {
-	OUTREGP(RADEON_GPIOPAD_A, 1, ~1 );
-    }
-
-    tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
-    tmp |= RADEON_CRTC2_CRT2_ON |
-	(2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
-
-    OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
-
-    if (IS_R300_VARIANT) {
-	tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
-	tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
-	OUTREG(RADEON_DISP_OUTPUT_CNTL, tmp);
-    } else {
-	tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL;
-	OUTREG(RADEON_DISP_HW_DEBUG, tmp);
-    }
-
-    tmp = RADEON_TV_DAC_NBLANK |
-	RADEON_TV_DAC_NHOLD |
-	RADEON_TV_MONITOR_DETECT_EN |
-	RADEON_TV_DAC_STD_PS2;
-
-    OUTREG(RADEON_TV_DAC_CNTL, tmp);
-
-    tmp = RADEON_DAC2_FORCE_BLANK_OFF_EN |
-	RADEON_DAC2_FORCE_DATA_EN;
-
-    if (color)
-	tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB;
-    else
-	tmp |= RADEON_DAC_FORCE_DATA_SEL_G;
-
-    if (IS_R300_VARIANT)
-	tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
-    else
-	tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
-
-    OUTREG(RADEON_DAC_EXT_CNTL, tmp);
-
-    tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN;
-    OUTREG(RADEON_DAC_CNTL2, tmp);
-
-    usleep(10000);
-
-    if (IS_R300_VARIANT) {
-	if (INREG(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) {
-	    found = MT_CRT;
-	    xf86DrvMsg (pScrn->scrnIndex, X_INFO,
-			"Found %s CRT connected to TV DAC\n",
-			color ? "color" : "bw");
-	}
-    } else {
-	if (INREG(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUTPUT) {
-	    found = MT_CRT;
-	    xf86DrvMsg (pScrn->scrnIndex, X_INFO,
-			"Found %s CRT connected to TV DAC\n",
-			color ? "color" : "bw");
-	}
-    }
-
-    /* restore regs we used */
-    OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
-    OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
-    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
-    OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
-
-    if (IS_R300_VARIANT) {
-	OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
-	OUTREGP(RADEON_GPIOPAD_A, gpiopad_a, ~1 );
-    } else {
-	OUTREG(RADEON_DISP_HW_DEBUG, disp_hw_debug);
-    }
-    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, pixclks_cntl);
-
-    return found;
-}
-
-static RADEONMonitorType
-r300_detect_tv(ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    CARD32 tmp, dac_cntl2, crtc2_gen_cntl, dac_ext_cntl, tv_dac_cntl;
-    CARD32 gpiopad_a, disp_output_cntl;
-    RADEONMonitorType found = MT_NONE;
-
-    /* save the regs we need */
-    gpiopad_a = INREG(RADEON_GPIOPAD_A);
-    dac_cntl2 = INREG(RADEON_DAC_CNTL2);
-    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
-    dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
-    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
-    disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
-
-    OUTREGP(RADEON_GPIOPAD_A, 0, ~1 );
-
-    OUTREG(RADEON_DAC_CNTL2, RADEON_DAC2_DAC2_CLK_SEL );
-
-    OUTREG(RADEON_CRTC2_GEN_CNTL,
-	   RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT );
-
-    tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
-    tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
-    OUTREG(RADEON_DISP_OUTPUT_CNTL, tmp);
-
-    OUTREG(RADEON_DAC_EXT_CNTL,
-	   RADEON_DAC2_FORCE_BLANK_OFF_EN |
-	   RADEON_DAC2_FORCE_DATA_EN |
-	   RADEON_DAC_FORCE_DATA_SEL_RGB |
-	   (0xec << RADEON_DAC_FORCE_DATA_SHIFT ));
-
-    OUTREG(RADEON_TV_DAC_CNTL,
-	   RADEON_TV_DAC_STD_NTSC |
-	   (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
-	   (6 << RADEON_TV_DAC_DACADJ_SHIFT ));
-
-    INREG(RADEON_TV_DAC_CNTL);
-
-    usleep(4000);
-
-    OUTREG(RADEON_TV_DAC_CNTL,
-	   RADEON_TV_DAC_NBLANK |
-	   RADEON_TV_DAC_NHOLD |
-	   RADEON_TV_MONITOR_DETECT_EN |
-	   RADEON_TV_DAC_STD_NTSC |
-	   (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
-	   (6 << RADEON_TV_DAC_DACADJ_SHIFT ));
-
-    INREG(RADEON_TV_DAC_CNTL);
-
-    usleep(6000);
-
-    tmp = INREG(RADEON_TV_DAC_CNTL);
-    if ( (tmp & RADEON_TV_DAC_GDACDET) != 0 ) {
-	found = MT_STV;
-	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
-		    "S-Video TV connection detected\n");
-    } else if ( (tmp & RADEON_TV_DAC_BDACDET) != 0 ) {
-	found = MT_CTV;
-	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
-		    "Composite TV connection detected\n" );
-    }
-
-    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl );
-    OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
-    OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
-    OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
-    OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
-    OUTREGP(RADEON_GPIOPAD_A, gpiopad_a, ~1);
-
-    return found;
-}
-
-static RADEONMonitorType
-radeon_detect_tv(ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    CARD32 tmp, dac_cntl2, tv_master_cntl;
-    CARD32 tv_dac_cntl, tv_pre_dac_mux_cntl, config_cntl;
-    RADEONMonitorType found = MT_NONE;
-
-    if (IS_R300_VARIANT)
-	return r300_detect_tv(pScrn);
-
-    /* save the regs we need */
-    dac_cntl2 = INREG(RADEON_DAC_CNTL2);
-    tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL);
-    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
-    config_cntl = INREG(RADEON_CONFIG_CNTL);
-    tv_pre_dac_mux_cntl = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
-
-    tmp = dac_cntl2 & ~RADEON_DAC2_DAC2_CLK_SEL;
-    OUTREG(RADEON_DAC_CNTL2, tmp);
-
-    tmp = tv_master_cntl | RADEON_TV_ON;
-    tmp &= ~(RADEON_TV_ASYNC_RST |
-	     RADEON_RESTART_PHASE_FIX |
-	     RADEON_CRT_FIFO_CE_EN |
-	     RADEON_TV_FIFO_CE_EN |
-	     RADEON_RE_SYNC_NOW_SEL_MASK);
-    tmp |= RADEON_TV_FIFO_ASYNC_RST | RADEON_CRT_ASYNC_RST;
-
-    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
-
-    tmp = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD |
-	RADEON_TV_MONITOR_DETECT_EN | RADEON_TV_DAC_STD_NTSC |
-	(8 << RADEON_TV_DAC_BGADJ_SHIFT);
-
-    if (config_cntl & RADEON_CFG_ATI_REV_ID_MASK)
-	tmp |= (4 << RADEON_TV_DAC_DACADJ_SHIFT);
-    else
-	tmp |= (8 << RADEON_TV_DAC_DACADJ_SHIFT);
-
-    OUTREG(RADEON_TV_DAC_CNTL, tmp);
-
-    tmp = RADEON_C_GRN_EN | RADEON_CMP_BLU_EN |
-	RADEON_RED_MX_FORCE_DAC_DATA |
-	RADEON_GRN_MX_FORCE_DAC_DATA |
-	RADEON_BLU_MX_FORCE_DAC_DATA |
-	(0x109 << RADEON_TV_FORCE_DAC_DATA_SHIFT);
-
-    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, tmp);
-
-    usleep(3000);
-
-    tmp = INREG(RADEON_TV_DAC_CNTL);
-    if (tmp & RADEON_TV_DAC_GDACDET) {
-	found = MT_STV;
-	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
-		    "S-Video TV connection detected\n");
-    } else if (tmp & RADEON_TV_DAC_BDACDET) {
-	found = MT_CTV;
-	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
-		    "Composite TV connection detected\n" );
-    }
-
-    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl);
-    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
-    OUTREG(RADEON_TV_MASTER_CNTL, tv_master_cntl);
-    OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
-
-    return found;
+    radeon_dpms(output, DPMSModeOn);
 }
 
 static xf86OutputStatus
@@ -1693,16 +657,26 @@ radeon_detect(xf86OutputPtr output)
     radeon_output->MonType = MT_UNKNOWN;
     RADEONConnectorFindMonitor(pScrn, output);
 
-    /* force montype based on output property */
-    if (radeon_output->type == OUTPUT_DVI) {
-	if (radeon_output->MonType == MT_NONE)
-	    connected = FALSE;
-	if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I_ATOM) ||
-	    (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I)) {
-	    if (radeon_output->DVIType == DVI_ANALOG)
+    /* nothing connected, light up some defaults so the server comes up */
+    if (radeon_output->MonType == MT_NONE &&
+	info->first_load_no_devices) {
+	if (info->IsMobility) {
+	    if (radeon_output->type == OUTPUT_LVDS) {
+		radeon_output->MonType = MT_LCD;
+		info->first_load_no_devices = FALSE;
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using LVDS default\n");
+	    }
+	} else {
+	    if (radeon_output->type == OUTPUT_VGA ||
+		radeon_output->type == OUTPUT_DVI_I) {
 		radeon_output->MonType = MT_CRT;
-	    else if (radeon_output->DVIType == DVI_DIGITAL)
+		info->first_load_no_devices = FALSE;
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using VGA default\n");
+	    } else if (radeon_output->type == OUTPUT_DVI_D) {
 		radeon_output->MonType = MT_DFP;
+		info->first_load_no_devices = FALSE;
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using DVI default\n");
+	    }
 	}
     }
 
@@ -1717,9 +691,20 @@ radeon_detect(xf86OutputPtr output)
             radeon_output->MonType = MT_STV;
 	else if (radeon_output->type == OUTPUT_CTV)
             radeon_output->MonType = MT_CTV;
-	else if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM) ||
-		 (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D))
+	else if (radeon_output->type == OUTPUT_CV)
+            radeon_output->MonType = MT_CV;
+	else if (radeon_output->type == OUTPUT_DVI_D)
+	    radeon_output->MonType = MT_DFP;
+	else if (radeon_output->type == OUTPUT_HDMI)
 	    radeon_output->MonType = MT_DFP;
+	else if (radeon_output->type == OUTPUT_DVI_A)
+	    radeon_output->MonType = MT_CRT;
+	else if (radeon_output->type == OUTPUT_DVI_I) {
+	    if (radeon_output->DVIType == DVI_ANALOG)
+		radeon_output->MonType = MT_CRT;
+	    else if (radeon_output->DVIType == DVI_DIGITAL)
+		radeon_output->MonType = MT_DFP;
+	}
     }
 
     if (radeon_output->MonType == MT_UNKNOWN) {
@@ -1737,21 +722,23 @@ radeon_detect(xf86OutputPtr output)
 	  break;
       }
 
+#if 0
       if (!connected) {
 	  /* default to unknown for flaky chips/connectors
 	   * so we can get something on the screen
 	   */
-	  if ((radeon_output->type == OUTPUT_VGA || radeon_output->type == OUTPUT_DVI) &&
+	  if ((radeon_output->type == OUTPUT_VGA || radeon_output->type == OUTPUT_DVI_I) &&
 	      (radeon_output->DACType == DAC_TVDAC) &&
 	      (info->ChipFamily == CHIP_FAMILY_RS400)) {
 	      radeon_output->MonType = MT_CRT;
 	      return XF86OutputStatusUnknown;
 	  } else if  ((info->ChipFamily == CHIP_FAMILY_RS400) &&
-		      radeon_output->type == OUTPUT_DVI) {
+		      radeon_output->type == OUTPUT_DVI_D) {
 	      radeon_output->MonType = MT_DFP; /* MT_LCD ??? */
 	      return XF86OutputStatusUnknown;
 	  }
       }
+#endif
 
       if (connected)
 	  return XF86OutputStatusConnected;
@@ -1772,7 +759,7 @@ radeon_get_modes(xf86OutputPtr output)
 static void
 radeon_destroy (xf86OutputPtr output)
 {
-    if(output->driver_private)
+    if (output->driver_private)
         xfree(output->driver_private);
 }
 
@@ -1817,7 +804,6 @@ radeon_create_resources(xf86OutputPtr output)
     INT32 range[2];
     int data, err;
     const char *s;
-    char *optstr;
 
     /* backlight control */
     if (radeon_output->type == OUTPUT_LVDS) {
@@ -1832,7 +818,7 @@ radeon_create_resources(xf86OutputPtr output)
 		       "RRConfigureOutputProperty error, %d\n", err);
 	}
 	/* Set the current value of the backlight property */
-	//data = (info->SavedReg.lvds_gen_cntl & RADEON_LVDS_BL_MOD_LEVEL_MASK) >> RADEON_LVDS_BL_MOD_LEVEL_SHIFT;
+	//data = (info->SavedReg->lvds_gen_cntl & RADEON_LVDS_BL_MOD_LEVEL_MASK) >> RADEON_LVDS_BL_MOD_LEVEL_SHIFT;
 	data = RADEON_MAX_BACKLIGHT_LEVEL;
 	err = RRChangeOutputProperty(output->randr_output, backlight_atom,
 				     XA_INTEGER, 32, PropModeReplace, 1, &data,
@@ -1856,12 +842,7 @@ radeon_create_resources(xf86OutputPtr output)
 		       "RRConfigureOutputProperty error, %d\n", err);
 	}
 
-	if (radeon_output->DACType == DAC_PRIMARY)
-	    data = 1; /* primary dac, only drives vga */
-	/*else if (radeon_output->DACType == DAC_TVDAC &&
-		 info->tvdac_use_count < 2)
-		 data = 1;*/ /* only one output with tvdac */
-	else if (xf86ReturnOptValBool(info->Options, OPTION_TVDAC_LOAD_DETECT, FALSE))
+	if (radeon_output->load_detection)
 	    data = 1; /* user forces on tv dac load detection */
 	else
 	    data = 0; /* shared tvdac between vga/dvi/tv */
@@ -1875,8 +856,7 @@ radeon_create_resources(xf86OutputPtr output)
 	}
     }
 
-    if (radeon_output->type == OUTPUT_DVI &&
-	radeon_output->TMDSType == TMDS_INT) {
+    if (OUTPUT_IS_DVI && radeon_output->TMDSType == TMDS_INT) {
 	tmds_pll_atom = MAKE_ATOM("tmds_pll");
 
 	err = RRConfigureOutputProperty(output->randr_output, tmds_pll_atom,
@@ -1907,8 +887,7 @@ radeon_create_resources(xf86OutputPtr output)
 
     /* RMX control - fullscreen, centered, keep ratio, off */
     /* actually more of a crtc property as only crtc1 has rmx */
-    if (radeon_output->type == OUTPUT_LVDS ||
-	radeon_output->type == OUTPUT_DVI) {
+    if (radeon_output->type == OUTPUT_LVDS || OUTPUT_IS_DVI) {
 	rmx_atom = MAKE_ATOM("scaler");
 
 	err = RRConfigureOutputProperty(output->randr_output, rmx_atom,
@@ -1932,97 +911,86 @@ radeon_create_resources(xf86OutputPtr output)
     }
 
     /* force auto/analog/digital for DVI-I ports */
-    if (radeon_output->type == OUTPUT_DVI) {
-	if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I_ATOM) ||
-	    (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I)) {
-	    monitor_type_atom = MAKE_ATOM("dvi_monitor_type");
+    if (radeon_output->type == OUTPUT_DVI_I) {
+	monitor_type_atom = MAKE_ATOM("dvi_monitor_type");
 
-	    err = RRConfigureOutputProperty(output->randr_output, monitor_type_atom,
-					    FALSE, FALSE, FALSE, 0, NULL);
-	    if (err != 0) {
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "RRConfigureOutputProperty error, %d\n", err);
-	    }
-	    /* Set the current value of the backlight property */
-	    s = "auto";
-	    err = RRChangeOutputProperty(output->randr_output, monitor_type_atom,
-					 XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
-					 FALSE, FALSE);
-	    if (err != 0) {
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "RRChangeOutputProperty error, %d\n", err);
-	    }
-	}
-    }
-
-    if (radeon_output->type == OUTPUT_STV ||
-	radeon_output->type == OUTPUT_CTV) {
-	tv_hsize_atom = MAKE_ATOM("tv_horizontal_size");
-
-	range[0] = -MAX_H_SIZE;
-	range[1] = MAX_H_SIZE;
-	err = RRConfigureOutputProperty(output->randr_output, tv_hsize_atom,
-					FALSE, TRUE, FALSE, 2, range);
+	err = RRConfigureOutputProperty(output->randr_output, monitor_type_atom,
+					FALSE, FALSE, FALSE, 0, NULL);
 	if (err != 0) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		       "RRConfigureOutputProperty error, %d\n", err);
 	}
-	data = 0;
-	err = RRChangeOutputProperty(output->randr_output, tv_hsize_atom,
-				     XA_INTEGER, 32, PropModeReplace, 1, &data,
-				     FALSE, TRUE);
+	/* Set the current value of the backlight property */
+	s = "auto";
+	err = RRChangeOutputProperty(output->randr_output, monitor_type_atom,
+				     XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
+				     FALSE, FALSE);
 	if (err != 0) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		       "RRChangeOutputProperty error, %d\n", err);
 	}
     }
 
-    if (radeon_output->type == OUTPUT_STV ||
-	radeon_output->type == OUTPUT_CTV) {
-	tv_hpos_atom = MAKE_ATOM("tv_horizontal_position");
+    if (OUTPUT_IS_TV) {
+	if (!IS_AVIVO_VARIANT) {
+	    tv_hsize_atom = MAKE_ATOM("tv_horizontal_size");
 
-	range[0] = -MAX_H_POSITION;
-	range[1] = MAX_H_POSITION;
-	err = RRConfigureOutputProperty(output->randr_output, tv_hpos_atom,
-					FALSE, TRUE, FALSE, 2, range);
-	if (err != 0) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "RRConfigureOutputProperty error, %d\n", err);
-	}
-	data = 0;
-	err = RRChangeOutputProperty(output->randr_output, tv_hpos_atom,
-				     XA_INTEGER, 32, PropModeReplace, 1, &data,
-				     FALSE, TRUE);
-	if (err != 0) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "RRChangeOutputProperty error, %d\n", err);
-	}
-    }
+	    range[0] = -MAX_H_SIZE;
+	    range[1] = MAX_H_SIZE;
+	    err = RRConfigureOutputProperty(output->randr_output, tv_hsize_atom,
+					    FALSE, TRUE, FALSE, 2, range);
+	    if (err != 0) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "RRConfigureOutputProperty error, %d\n", err);
+	    }
+	    data = 0;
+	    err = RRChangeOutputProperty(output->randr_output, tv_hsize_atom,
+					 XA_INTEGER, 32, PropModeReplace, 1, &data,
+					 FALSE, TRUE);
+	    if (err != 0) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "RRChangeOutputProperty error, %d\n", err);
+	    }
 
-    if (radeon_output->type == OUTPUT_STV ||
-	radeon_output->type == OUTPUT_CTV) {
-	tv_vpos_atom = MAKE_ATOM("tv_vertical_position");
+	    tv_hpos_atom = MAKE_ATOM("tv_horizontal_position");
 
-	range[0] = -MAX_V_POSITION;
-	range[1] = MAX_V_POSITION;
-	err = RRConfigureOutputProperty(output->randr_output, tv_vpos_atom,
-					FALSE, TRUE, FALSE, 2, range);
-	if (err != 0) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "RRConfigureOutputProperty error, %d\n", err);
-	}
-	data = 0;
-	err = RRChangeOutputProperty(output->randr_output, tv_vpos_atom,
-				     XA_INTEGER, 32, PropModeReplace, 1, &data,
-				     FALSE, TRUE);
-	if (err != 0) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "RRChangeOutputProperty error, %d\n", err);
+	    range[0] = -MAX_H_POSITION;
+	    range[1] = MAX_H_POSITION;
+	    err = RRConfigureOutputProperty(output->randr_output, tv_hpos_atom,
+					    FALSE, TRUE, FALSE, 2, range);
+	    if (err != 0) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "RRConfigureOutputProperty error, %d\n", err);
+	    }
+	    data = 0;
+	    err = RRChangeOutputProperty(output->randr_output, tv_hpos_atom,
+					 XA_INTEGER, 32, PropModeReplace, 1, &data,
+					 FALSE, TRUE);
+	    if (err != 0) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "RRChangeOutputProperty error, %d\n", err);
+	    }
+
+	    tv_vpos_atom = MAKE_ATOM("tv_vertical_position");
+
+	    range[0] = -MAX_V_POSITION;
+	    range[1] = MAX_V_POSITION;
+	    err = RRConfigureOutputProperty(output->randr_output, tv_vpos_atom,
+					    FALSE, TRUE, FALSE, 2, range);
+	    if (err != 0) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "RRConfigureOutputProperty error, %d\n", err);
+	    }
+	    data = 0;
+	    err = RRChangeOutputProperty(output->randr_output, tv_vpos_atom,
+					 XA_INTEGER, 32, PropModeReplace, 1, &data,
+					 FALSE, TRUE);
+	    if (err != 0) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "RRChangeOutputProperty error, %d\n", err);
+	    }
 	}
-    }
 
-    if (radeon_output->type == OUTPUT_STV ||
-	radeon_output->type == OUTPUT_CTV) {
 	tv_std_atom = MAKE_ATOM("tv_standard");
 
 	err = RRConfigureOutputProperty(output->randr_output, tv_std_atom,
@@ -2031,8 +999,9 @@ radeon_create_resources(xf86OutputPtr output)
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		       "RRConfigureOutputProperty error, %d\n", err);
 	}
+
 	/* Set the current value of the property */
-	switch (radeon_output->default_tvStd) {
+	switch (radeon_output->tvStd) {
 	case TV_STD_PAL:
 	    s = "pal";
 	    break;
@@ -2054,25 +1023,6 @@ radeon_create_resources(xf86OutputPtr output)
 	    break;
 	}
 
-	optstr = (char *)xf86GetOptValString(info->Options, OPTION_TVSTD);
-	if (optstr) {
-	    if (!strncmp("ntsc", optstr, strlen("ntsc")))
-		radeon_output->tvStd = TV_STD_NTSC;
-	    else if (!strncmp("pal", optstr, strlen("pal")))
-		radeon_output->tvStd = TV_STD_PAL;
-	    else if (!strncmp("pal-m", optstr, strlen("pal-m")))
-		radeon_output->tvStd = TV_STD_PAL_M;
-	    else if (!strncmp("pal-60", optstr, strlen("pal-60")))
-		radeon_output->tvStd = TV_STD_PAL_60;
-	    else if (!strncmp("ntsc-j", optstr, strlen("ntsc-j")))
-		radeon_output->tvStd = TV_STD_NTSC_J;
-	    else if (!strncmp("scart-pal", optstr, strlen("scart-pal")))
-		radeon_output->tvStd = TV_STD_SCART_PAL;
-	    else {
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid TV Standard: %s\n", optstr);
-	    }
-	}
-
 	err = RRChangeOutputProperty(output->randr_output, tv_std_atom,
 				     XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
 				     FALSE, FALSE);
@@ -2087,6 +1037,7 @@ static Bool
 radeon_set_property(xf86OutputPtr output, Atom property,
 		       RRPropertyValuePtr value)
 {
+    RADEONInfoPtr info = RADEONPTR(output->scrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     INT32 val;
 
@@ -2124,21 +1075,18 @@ radeon_set_property(xf86OutputPtr output, Atom property,
     } else if (property == rmx_atom) {
 	const char *s;
 	if (value->type != XA_STRING || value->format != 8)
- 	    return FALSE;
+	    return FALSE;
 	s = (char*)value->data;
 	if (value->size == strlen("full") && !strncmp("full", s, strlen("full"))) {
 	    radeon_output->rmx_type = RMX_FULL;
 	    return TRUE;
-	} else if (value->size == strlen("aspect") && !strncmp("aspect", s, strlen("aspect"))) {
-	    radeon_output->rmx_type = RMX_ASPECT;
-	    return TRUE;
 	} else if (value->size == strlen("center") && !strncmp("center", s, strlen("center"))) {
 	    radeon_output->rmx_type = RMX_CENTER;
 	    return TRUE;
- 	} else if (value->size == strlen("off") && !strncmp("off", s, strlen("off"))) {
+	} else if (value->size == strlen("off") && !strncmp("off", s, strlen("off"))) {
 	    radeon_output->rmx_type = RMX_OFF;
 	    return TRUE;
- 	}
+	}
 	return FALSE;
     } else if (property == tmds_pll_atom) {
 	const char *s;
@@ -2182,7 +1130,7 @@ radeon_set_property(xf86OutputPtr output, Atom property,
 	    return FALSE;
 
 	radeon_output->hSize = val;
-	if (radeon_output->tv_on)
+	if (radeon_output->tv_on && !IS_AVIVO_VARIANT)
 	    RADEONUpdateHVPosition(output, &output->crtc->mode);
 	return TRUE;
     } else if (property == tv_hpos_atom) {
@@ -2197,7 +1145,7 @@ radeon_set_property(xf86OutputPtr output, Atom property,
 	    return FALSE;
 
 	radeon_output->hPos = val;
-	if (radeon_output->tv_on)
+	if (radeon_output->tv_on && !IS_AVIVO_VARIANT)
 	    RADEONUpdateHVPosition(output, &output->crtc->mode);
 	return TRUE;
     } else if (property == tv_vpos_atom) {
@@ -2212,7 +1160,7 @@ radeon_set_property(xf86OutputPtr output, Atom property,
 	    return FALSE;
 
 	radeon_output->vPos = val;
-	if (radeon_output->tv_on)
+	if (radeon_output->tv_on && !IS_AVIVO_VARIANT)
 	    RADEONUpdateHVPosition(output, &output->crtc->mode);
 	return TRUE;
     } else if (property == tv_std_atom) {
@@ -2238,6 +1186,12 @@ radeon_set_property(xf86OutputPtr output, Atom property,
 	} else if (value->size == strlen("scart-pal") && !strncmp("scart-pal", s, strlen("scart-pal"))) {
 	    radeon_output->tvStd = TV_STD_SCART_PAL;
 	    return TRUE;
+	} else if (value->size == strlen("pal-cn") && !strncmp("pal-cn", s, strlen("pal-cn"))) {
+	    radeon_output->tvStd = TV_STD_PAL_CN;
+	    return TRUE;
+	} else if (value->size == strlen("secam") && !strncmp("secam", s, strlen("secam"))) {
+	    radeon_output->tvStd = TV_STD_SECAM;
+	    return TRUE;
 	}
 	return FALSE;
     }
@@ -2263,74 +1217,98 @@ static const xf86OutputFuncsRec radeon_output_funcs = {
 
 void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output)
 {
-    RADEONInfoPtr info = RADEONPTR (pScrn);
-    RADEONOutputType output;
-
-    if (info->IsAtomBios) {
-	switch(radeon_output->ConnectorType) {
-	case CONNECTOR_VGA_ATOM:
-	    output = OUTPUT_VGA; break;
-	case CONNECTOR_DVI_I_ATOM:
-	case CONNECTOR_DVI_D_ATOM:
-	case CONNECTOR_DVI_A_ATOM:
-	    output = OUTPUT_DVI; break;
-	case CONNECTOR_STV_ATOM:
-	    output = OUTPUT_STV; break;
-	case CONNECTOR_CTV_ATOM:
-	    output = OUTPUT_CTV; break;
-	case CONNECTOR_LVDS_ATOM:
-	case CONNECTOR_DIGITAL_ATOM:
-	    output = OUTPUT_LVDS; break;
-	case CONNECTOR_NONE_ATOM:
-	case CONNECTOR_UNSUPPORTED_ATOM:
-	default:
-	    output = OUTPUT_NONE; break;
-	}
-    }
-    else {
-	switch(radeon_output->ConnectorType) {
-	case CONNECTOR_PROPRIETARY:
-	    output = OUTPUT_LVDS; break;
-	case CONNECTOR_CRT:
-	    output = OUTPUT_VGA; break;
-	case CONNECTOR_DVI_I:
-	case CONNECTOR_DVI_D:
-	    output = OUTPUT_DVI; break;
-	case CONNECTOR_CTV:
-	    output = OUTPUT_CTV; break;
-	case CONNECTOR_STV:
-	    output = OUTPUT_STV; break;
-	case CONNECTOR_NONE:
-	case CONNECTOR_UNSUPPORTED:
-	default:
-	    output = OUTPUT_NONE; break;
-	}
+    RADEONOutputType output = OUTPUT_NONE;
+
+    switch(radeon_output->ConnectorType) {
+    case CONNECTOR_VGA:
+	output = OUTPUT_VGA; break;
+    case CONNECTOR_DVI_I:
+	output = OUTPUT_DVI_I; break;
+    case CONNECTOR_DVI_D:
+	output = OUTPUT_DVI_D; break;
+    case CONNECTOR_DVI_A:
+	output = OUTPUT_DVI_A; break;
+    case CONNECTOR_DIN:
+	if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
+	    output = OUTPUT_CV;
+	else if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
+	    output = OUTPUT_STV;
+	break;
+    case CONNECTOR_STV:
+	output = OUTPUT_STV; break;
+    case CONNECTOR_CTV:
+	output = OUTPUT_CTV; break;
+    case CONNECTOR_LVDS:
+	output = OUTPUT_LVDS; break;
+    case CONNECTOR_HDMI_TYPE_A:
+    case CONNECTOR_HDMI_TYPE_B:
+	output = OUTPUT_HDMI; break;
+    case CONNECTOR_DIGITAL:
+    case CONNECTOR_NONE:
+    case CONNECTOR_UNSUPPORTED:
+    default:
+	output = OUTPUT_NONE; break;
     }
     radeon_output->type = output;
 }
 
+#if 0
+static
+Bool AVIVOI2CReset(ScrnInfoPtr pScrn)
+{
+  RADEONInfoPtr info = RADEONPTR(pScrn);
+  unsigned char *RADEONMMIO = info->MMIO;
+
+  OUTREG(AVIVO_I2C_STOP, 1);
+  INREG(AVIVO_I2C_STOP);
+  OUTREG(AVIVO_I2C_STOP, 0x0);
+  return TRUE;
+}
+#endif
+
+static
+Bool AVIVOI2CDoLock(xf86OutputPtr output, int lock_state)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONI2CBusPtr pRADEONI2CBus = radeon_output->pI2CBus->DriverPrivate.ptr;
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 temp;
+
+    temp = INREG(pRADEONI2CBus->mask_clk_reg);
+    if (lock_state == AVIVO_I2C_ENABLE)
+	temp |= (pRADEONI2CBus->put_clk_mask);
+    else
+	temp &= ~(pRADEONI2CBus->put_clk_mask);
+    OUTREG(pRADEONI2CBus->mask_clk_reg, temp);
+    temp = INREG(pRADEONI2CBus->mask_clk_reg);
+
+    temp = INREG(pRADEONI2CBus->mask_data_reg);
+    if (lock_state == AVIVO_I2C_ENABLE)
+	temp |= (pRADEONI2CBus->put_data_mask);
+    else
+	temp &= ~(pRADEONI2CBus->put_data_mask);
+    OUTREG(pRADEONI2CBus->mask_data_reg, temp);
+    temp = INREG(pRADEONI2CBus->mask_data_reg);
+
+    return TRUE;
+}
+
 static void RADEONI2CGetBits(I2CBusPtr b, int *Clock, int *data)
 {
     ScrnInfoPtr    pScrn      = xf86Screens[b->scrnIndex];
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned long  val;
     unsigned char *RADEONMMIO = info->MMIO;
+    RADEONI2CBusPtr pRADEONI2CBus = b->DriverPrivate.ptr;
 
     /* Get the result */
+    val = INREG(pRADEONI2CBus->get_clk_reg);
+    *Clock = (val & pRADEONI2CBus->get_clk_mask) != 0;
+    val = INREG(pRADEONI2CBus->get_data_reg);
+    *data  = (val & pRADEONI2CBus->get_data_mask) != 0;
 
-    if (b->DriverPrivate.uval == RADEON_LCD_GPIO_MASK) { 
-        val = INREG(b->DriverPrivate.uval+4);
-        *Clock = (val & (1<<13)) != 0;
-        *data  = (val & (1<<12)) != 0;
-    } else if (b->DriverPrivate.uval == RADEON_MDGPIO_EN_REG) {
-        val = INREG(b->DriverPrivate.uval+4);
-        *Clock = (val & (1<<19)) != 0;
-        *data  = (val & (1<<18)) != 0;
-    } else {
-        val = INREG(b->DriverPrivate.uval);
-        *Clock = (val & RADEON_GPIO_Y_1) != 0;
-        *data  = (val & RADEON_GPIO_Y_0) != 0;
-    }
 }
 
 static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
@@ -2339,31 +1317,29 @@ static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned long  val;
     unsigned char *RADEONMMIO = info->MMIO;
+    RADEONI2CBusPtr pRADEONI2CBus = b->DriverPrivate.ptr;
 
-    if (b->DriverPrivate.uval == RADEON_LCD_GPIO_MASK) {
-        val = INREG(b->DriverPrivate.uval) & (CARD32)~((1<<12) | (1<<13));
-        val |= (Clock ? 0:(1<<13));
-        val |= (data ? 0:(1<<12));
-        OUTREG(b->DriverPrivate.uval, val);
-    } else if (b->DriverPrivate.uval == RADEON_MDGPIO_EN_REG) {
-        val = INREG(b->DriverPrivate.uval) & (CARD32)~((1<<18) | (1<<19));
-        val |= (Clock ? 0:(1<<19));
-        val |= (data ? 0:(1<<18));
-        OUTREG(b->DriverPrivate.uval, val);
-    } else {
-        val = INREG(b->DriverPrivate.uval) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1);
-        val |= (Clock ? 0:RADEON_GPIO_EN_1);
-        val |= (data ? 0:RADEON_GPIO_EN_0);
-        OUTREG(b->DriverPrivate.uval, val);
-   }
+    val = INREG(pRADEONI2CBus->put_clk_reg) & (CARD32)~(pRADEONI2CBus->put_clk_mask);
+    val |= (Clock ? 0:pRADEONI2CBus->put_clk_mask);
+    OUTREG(pRADEONI2CBus->put_clk_reg, val);
+    /* read back to improve reliability on some cards. */
+    val = INREG(pRADEONI2CBus->put_clk_reg);
+
+    val = INREG(pRADEONI2CBus->put_data_reg) & (CARD32)~(pRADEONI2CBus->put_data_mask);
+    val |= (data ? 0:pRADEONI2CBus->put_data_mask);
+    OUTREG(pRADEONI2CBus->put_data_reg, val);
     /* read back to improve reliability on some cards. */
-    val = INREG(b->DriverPrivate.uval);
+    val = INREG(pRADEONI2CBus->put_data_reg);
+
 }
 
 static Bool
-RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name)
+RADEONI2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name, Bool dvo)
 {
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     I2CBusPtr pI2CBus;
+    RADEONI2CBusPtr pRADEONI2CBus;
 
     pI2CBus = xf86CreateI2CBusRec();
     if (!pI2CBus) return FALSE;
@@ -2373,14 +1349,44 @@ RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name)
     pI2CBus->I2CPutBits = RADEONI2CPutBits;
     pI2CBus->I2CGetBits = RADEONI2CGetBits;
     pI2CBus->AcknTimeout = 5;
-    pI2CBus->DriverPrivate.uval = i2c_reg;
 
-    if (!xf86I2CBusInit(pI2CBus)) return FALSE;
+    if (dvo) {
+	pRADEONI2CBus = &(radeon_output->dvo_i2c);
+    } else {
+	pRADEONI2CBus = &(radeon_output->ddc_i2c);
+    }
+
+    pI2CBus->DriverPrivate.ptr = (pointer)pRADEONI2CBus;
+
+    if (!xf86I2CBusInit(pI2CBus))
+	return FALSE;
 
     *bus_ptr = pI2CBus;
     return TRUE;
 }
 
+RADEONI2CBusRec
+legacy_setup_i2c_bus(int ddc_line)
+{
+    RADEONI2CBusRec i2c;
+
+    i2c.mask_clk_mask = RADEON_GPIO_EN_1 | RADEON_GPIO_Y_1;
+    i2c.mask_data_mask =  RADEON_GPIO_EN_0 | RADEON_GPIO_Y_0;
+    i2c.put_clk_mask = RADEON_GPIO_EN_1;
+    i2c.put_data_mask = RADEON_GPIO_EN_0;
+    i2c.get_clk_mask = RADEON_GPIO_Y_1;
+    i2c.get_data_mask = RADEON_GPIO_Y_0;
+    i2c.mask_clk_reg = ddc_line;
+    i2c.mask_data_reg = ddc_line;
+    i2c.put_clk_reg = ddc_line;
+    i2c.put_data_reg = ddc_line;
+    i2c.get_clk_reg = ddc_line;
+    i2c.get_data_reg = ddc_line;
+    i2c.valid = TRUE;
+
+    return i2c;
+}
+
 static void
 RADEONGetPanelInfoFromReg (xf86OutputPtr output)
 {
@@ -2643,71 +1649,99 @@ RADEONGetTMDSInfo(xf86OutputPtr output)
 static void
 RADEONGetTVInfo(xf86OutputPtr output)
 {
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    char *optstr;
 
     radeon_output->hPos = 0;
     radeon_output->vPos = 0;
     radeon_output->hSize = 0;
 
-    if (RADEONGetTVInfoFromBIOS(output)) return;
+    if (!RADEONGetTVInfoFromBIOS(output)) {
+	/* set some reasonable defaults */
+	radeon_output->default_tvStd = TV_STD_NTSC;
+	radeon_output->tvStd = TV_STD_NTSC;
+	radeon_output->TVRefClk = 27.000000000;
+	radeon_output->SupportedTVStds = TV_STD_NTSC | TV_STD_PAL;
+    }
+
+    optstr = (char *)xf86GetOptValString(info->Options, OPTION_TVSTD);
+    if (optstr) {
+	if (!strncmp("ntsc", optstr, strlen("ntsc")))
+	    radeon_output->tvStd = TV_STD_NTSC;
+	else if (!strncmp("pal", optstr, strlen("pal")))
+	    radeon_output->tvStd = TV_STD_PAL;
+	else if (!strncmp("pal-m", optstr, strlen("pal-m")))
+	    radeon_output->tvStd = TV_STD_PAL_M;
+	else if (!strncmp("pal-60", optstr, strlen("pal-60")))
+	    radeon_output->tvStd = TV_STD_PAL_60;
+	else if (!strncmp("ntsc-j", optstr, strlen("ntsc-j")))
+	    radeon_output->tvStd = TV_STD_NTSC_J;
+	else if (!strncmp("scart-pal", optstr, strlen("scart-pal")))
+	    radeon_output->tvStd = TV_STD_SCART_PAL;
+	else {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid TV Standard: %s\n", optstr);
+	}
+    }
+
+}
 
-    /* set some reasonable defaults */
-    radeon_output->default_tvStd = TV_STD_NTSC;
-    radeon_output->tvStd = TV_STD_NTSC;
-    radeon_output->TVRefClk = 27.000000000;
-    radeon_output->SupportedTVStds = TV_STD_NTSC | TV_STD_PAL;
+static void
+RADEONGetTVDacAdjInfo(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    if (!RADEONGetDAC2InfoFromBIOS(output)) {
+	radeon_output->ps2_tvdac_adj = default_tvdac_adj[info->ChipFamily];
+	if (info->IsMobility) { /* some mobility chips may different */
+	    if (info->ChipFamily == CHIP_FAMILY_RV250)
+		radeon_output->ps2_tvdac_adj = 0x00880000;
+	}
+	radeon_output->pal_tvdac_adj = radeon_output->ps2_tvdac_adj;
+	radeon_output->ntsc_tvdac_adj = radeon_output->ps2_tvdac_adj;
+    }
 
 }
 
 void RADEONInitConnector(xf86OutputPtr output)
 {
     ScrnInfoPtr	    pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    int DDCReg = 0;
-    char* name = (char*) DDCTypeName[radeon_output->DDCType];
-
-    switch(radeon_output->DDCType) {
-    case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break;
-    case DDC_DVI  : DDCReg = RADEON_GPIO_DVI_DDC; break;
-    case DDC_VGA  : DDCReg = RADEON_GPIO_VGA_DDC; break;
-    case DDC_CRT2 : DDCReg = RADEON_GPIO_CRT2_DDC; break;
-    case DDC_LCD  : DDCReg = RADEON_LCD_GPIO_MASK; break;
-    case DDC_GPIO : DDCReg = RADEON_MDGPIO_EN_REG; break;
-    default: break;
-    }
 
     if (radeon_output->DACType == DAC_PRIMARY)
 	radeon_output->load_detection = 1; /* primary dac, only drives vga */
     /*else if (radeon_output->DACType == DAC_TVDAC &&
 	     info->tvdac_use_count < 2)
 	     radeon_output->load_detection = 1;*/ /* only one output with tvdac */
+    else if ((radeon_output->DACType == DAC_TVDAC) &&
+	     (xf86ReturnOptValBool(info->Options, OPTION_TVDAC_LOAD_DETECT, FALSE)))
+	radeon_output->load_detection = 1; /* shared tvdac between vga/dvi/tv */
     else
 	radeon_output->load_detection = 0; /* shared tvdac between vga/dvi/tv */
 
-    if (DDCReg) {
-	radeon_output->DDCReg = DDCReg;
-	RADEONI2CInit(pScrn, &radeon_output->pI2CBus, DDCReg, name);
-    }
-
     if (radeon_output->type == OUTPUT_LVDS) {
 	radeon_output->rmx_type = RMX_FULL;
 	RADEONGetLVDSInfo(output);
     }
 
-    if (radeon_output->type == OUTPUT_DVI) {
+    if (OUTPUT_IS_DVI) {
 	I2CBusPtr pDVOBus;
 	radeon_output->rmx_type = RMX_OFF;
-	if (radeon_output->TMDSType == TMDS_EXT) {
+	if ((!info->IsAtomBios) && radeon_output->TMDSType == TMDS_EXT) {
 #if defined(__powerpc__)
-	    radeon_output->dvo_i2c_reg = RADEON_GPIO_MONID;
+	    radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
 	    radeon_output->dvo_i2c_slave_addr = 0x70;
 #else
 	    if (!RADEONGetExtTMDSInfoFromBIOS(output)) {
-		radeon_output->dvo_i2c_reg = RADEON_GPIO_CRT2_DDC;
+		radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
 		radeon_output->dvo_i2c_slave_addr = 0x70;
 	    }
 #endif
-	    if (RADEONI2CInit(pScrn, &pDVOBus, radeon_output->dvo_i2c_reg, "DVO")) {
+	    if (RADEONI2CInit(output, &pDVOBus, "DVO", TRUE)) {
 		radeon_output->DVOChip =
 		    RADEONDVODeviceInit(pDVOBus,
 					radeon_output->dvo_i2c_slave_addr);
@@ -2718,8 +1752,7 @@ void RADEONInitConnector(xf86OutputPtr output)
 	    RADEONGetTMDSInfo(output);
     }
 
-    if (radeon_output->type == OUTPUT_STV ||
-	radeon_output->type == OUTPUT_CTV) {
+    if (OUTPUT_IS_TV) {
 	RADEONGetTVInfo(output);
 	RADEONGetTVDacAdjInfo(output);
     }
@@ -2729,6 +1762,9 @@ void RADEONInitConnector(xf86OutputPtr output)
 	RADEONGetTVDacAdjInfo(output);
     }
 
+    if (radeon_output->ddc_i2c.valid)
+	RADEONI2CInit(output, &radeon_output->pI2CBus, output->name, FALSE);
+
 }
 
 #if defined(__powerpc__)
@@ -2739,32 +1775,32 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 
     switch (info->MacModel) {
     case RADEON_MAC_IBOOK:
-	info->BiosConnector[0].DDCType = DDC_DVI;
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	info->BiosConnector[0].DACType = DAC_NONE;
 	info->BiosConnector[0].TMDSType = TMDS_NONE;
-	info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
+	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	info->BiosConnector[0].valid = TRUE;
 
-	info->BiosConnector[1].DDCType = DDC_VGA;
+	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	info->BiosConnector[1].DACType = DAC_TVDAC;
 	info->BiosConnector[1].TMDSType = TMDS_NONE;
-	info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
+	info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[1].valid = TRUE;
 
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
-	info->BiosConnector[2].DDCType = DDC_NONE_DETECTED;
+	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	return TRUE;
     case RADEON_MAC_POWERBOOK_EXTERNAL:
-	info->BiosConnector[0].DDCType = DDC_DVI;
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	info->BiosConnector[0].DACType = DAC_NONE;
 	info->BiosConnector[0].TMDSType = TMDS_NONE;
-	info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
+	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	info->BiosConnector[0].valid = TRUE;
 
-	info->BiosConnector[1].DDCType = DDC_VGA;
+	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	info->BiosConnector[1].DACType = DAC_PRIMARY;
 	info->BiosConnector[1].TMDSType = TMDS_EXT;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
@@ -2773,17 +1809,18 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
-	info->BiosConnector[2].DDCType = DDC_NONE_DETECTED;
+	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	return TRUE;
+
     case RADEON_MAC_POWERBOOK_INTERNAL:
-	info->BiosConnector[0].DDCType = DDC_DVI;
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	info->BiosConnector[0].DACType = DAC_NONE;
 	info->BiosConnector[0].TMDSType = TMDS_NONE;
-	info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
+	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	info->BiosConnector[0].valid = TRUE;
 
-	info->BiosConnector[1].DDCType = DDC_VGA;
+	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	info->BiosConnector[1].DACType = DAC_PRIMARY;
 	info->BiosConnector[1].TMDSType = TMDS_INT;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
@@ -2792,17 +1829,17 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
-	info->BiosConnector[2].DDCType = DDC_NONE_DETECTED;
+	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	return TRUE;
     case RADEON_MAC_POWERBOOK_VGA:
-	info->BiosConnector[0].DDCType = DDC_DVI;
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	info->BiosConnector[0].DACType = DAC_NONE;
 	info->BiosConnector[0].TMDSType = TMDS_NONE;
-	info->BiosConnector[0].ConnectorType = CONNECTOR_CRT;
+	info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[0].valid = TRUE;
 
-	info->BiosConnector[1].DDCType = DDC_VGA;
+	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	info->BiosConnector[1].DACType = DAC_PRIMARY;
 	info->BiosConnector[1].TMDSType = TMDS_INT;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
@@ -2811,11 +1848,11 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
-	info->BiosConnector[2].DDCType = DDC_NONE_DETECTED;
+	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	return TRUE;
     case RADEON_MAC_MINI_EXTERNAL:
-	info->BiosConnector[0].DDCType = DDC_CRT2;
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
 	info->BiosConnector[0].DACType = DAC_TVDAC;
 	info->BiosConnector[0].TMDSType = TMDS_EXT;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
@@ -2824,11 +1861,11 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[1].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[1].DACType = DAC_TVDAC;
 	info->BiosConnector[1].TMDSType = TMDS_NONE;
-	info->BiosConnector[1].DDCType = DDC_NONE_DETECTED;
+	info->BiosConnector[1].ddc_i2c.valid = FALSE;
 	info->BiosConnector[1].valid = TRUE;
 	return TRUE;
     case RADEON_MAC_MINI_INTERNAL:
-	info->BiosConnector[0].DDCType = DDC_CRT2;
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
 	info->BiosConnector[0].DACType = DAC_TVDAC;
 	info->BiosConnector[0].TMDSType = TMDS_INT;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
@@ -2837,26 +1874,26 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[1].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[1].DACType = DAC_TVDAC;
 	info->BiosConnector[1].TMDSType = TMDS_NONE;
-	info->BiosConnector[1].DDCType = DDC_NONE_DETECTED;
+	info->BiosConnector[1].ddc_i2c.valid = FALSE;
 	info->BiosConnector[1].valid = TRUE;
 	return TRUE;
     case RADEON_MAC_IMAC_G5_ISIGHT:
-	info->BiosConnector[0].DDCType = DDC_MONID;
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
 	info->BiosConnector[0].DACType = DAC_NONE;
 	info->BiosConnector[0].TMDSType = TMDS_INT;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_D;
 	info->BiosConnector[0].valid = TRUE;
 
-	info->BiosConnector[1].DDCType = DDC_DVI;
+	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	info->BiosConnector[1].DACType = DAC_TVDAC;
 	info->BiosConnector[1].TMDSType = TMDS_NONE;
-	info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
+	info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[1].valid = TRUE;
 
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
-	info->BiosConnector[2].DDCType = DDC_NONE_DETECTED;
+	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	return TRUE;
     default:
@@ -2873,108 +1910,146 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
 
     if (!pRADEONEnt->HasCRTC2) {
-	info->BiosConnector[0].DDCType = DDC_VGA;
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	info->BiosConnector[0].DACType = DAC_PRIMARY;
 	info->BiosConnector[0].TMDSType = TMDS_NONE;
-	info->BiosConnector[0].ConnectorType = CONNECTOR_CRT;
+	info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[0].valid = TRUE;
 	return;
     }
 
-    if (info->IsMobility) {
-	/* Below is the most common setting, but may not be true */
-	if (info->IsIGP) {
-	    info->BiosConnector[0].DDCType = DDC_LCD;
-	    info->BiosConnector[0].DACType = DAC_UNKNOWN;
-	    info->BiosConnector[0].TMDSType = TMDS_UNKNOWN;
-	    info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
+    if (IS_AVIVO_VARIANT) {
+	if (info->IsMobility) {
+	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(0x7e60);
+	    info->BiosConnector[0].DACType = DAC_NONE;
+	    info->BiosConnector[0].TMDSType = TMDS_NONE;
+	    info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
+	    info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
 	    info->BiosConnector[0].valid = TRUE;
 
-	    /* IGP only has TVDAC */
-	    if (info->ChipFamily == CHIP_FAMILY_RS400)
-		info->BiosConnector[1].DDCType = DDC_CRT2;
-	    else
-		info->BiosConnector[1].DDCType = DDC_VGA;
-	    info->BiosConnector[1].DACType = DAC_TVDAC;
-	    info->BiosConnector[1].TMDSType = TMDS_UNKNOWN;
-	    info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
-	    info->BiosConnector[1].valid = TRUE;
-	} else {
-#if defined(__powerpc__)
-	    info->BiosConnector[0].DDCType = DDC_DVI;
-#else
-	    info->BiosConnector[0].DDCType = DDC_LCD;
-#endif
-	    info->BiosConnector[0].DACType = DAC_UNKNOWN;
-	    info->BiosConnector[0].TMDSType = TMDS_UNKNOWN;
-	    info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
-	    info->BiosConnector[0].valid = TRUE;
-
-	    info->BiosConnector[1].DDCType = DDC_VGA;
+	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(0x7e40);
 	    info->BiosConnector[1].DACType = DAC_PRIMARY;
-	    info->BiosConnector[1].TMDSType = TMDS_UNKNOWN;
-	    info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
-	    info->BiosConnector[1].valid = TRUE;
-	}
-    } else {
-	/* Below is the most common setting, but may not be true */
-	if (info->IsIGP) {
-	    if (info->ChipFamily == CHIP_FAMILY_RS400)
-		info->BiosConnector[0].DDCType = DDC_CRT2;
-	    else
-		info->BiosConnector[0].DDCType = DDC_VGA;
-	    info->BiosConnector[0].DACType = DAC_TVDAC;
-	    info->BiosConnector[0].TMDSType = TMDS_UNKNOWN;
-	    info->BiosConnector[0].ConnectorType = CONNECTOR_CRT;
-	    info->BiosConnector[0].valid = TRUE;
-
-	    /* not sure what a good default DDCType for DVI on 
-	     * IGP desktop chips is
-	     */
-	    info->BiosConnector[1].DDCType = DDC_MONID; /* DDC_DVI? */
-	    info->BiosConnector[1].DACType = DAC_UNKNOWN;
-	    info->BiosConnector[1].TMDSType = TMDS_EXT;
-	    info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_D;
+	    info->BiosConnector[1].TMDSType = TMDS_NONE;
+	    info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
+	    info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT;
 	    info->BiosConnector[1].valid = TRUE;
 	} else {
-	    info->BiosConnector[0].DDCType = DDC_DVI;
+	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(0x7e50);
 	    info->BiosConnector[0].DACType = DAC_TVDAC;
 	    info->BiosConnector[0].TMDSType = TMDS_INT;
 	    info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
+	    info->BiosConnector[0].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT;
 	    info->BiosConnector[0].valid = TRUE;
 
-#if defined(__powerpc__)
-	    info->BiosConnector[1].DDCType = DDC_VGA;
-	    info->BiosConnector[1].DACType = DAC_PRIMARY;
-	    info->BiosConnector[1].TMDSType = TMDS_EXT;
-	    info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
-	    info->BiosConnector[1].valid = TRUE;
-#else
-	    info->BiosConnector[1].DDCType = DDC_VGA;
+	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(0x7e40);
 	    info->BiosConnector[1].DACType = DAC_PRIMARY;
 	    info->BiosConnector[1].TMDSType = TMDS_NONE;
-	    info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
+	    info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
+	    info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT;
 	    info->BiosConnector[1].valid = TRUE;
-#endif
 	}
-    }
 
-    if (info->InternalTVOut) {
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
-	info->BiosConnector[2].DDCType = DDC_NONE_DETECTED;
+	info->BiosConnector[2].ddc_i2c.valid = FALSE;
+	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
 	info->BiosConnector[2].valid = TRUE;
-    }
+    } else {
+	if (info->IsMobility) {
+	    /* Below is the most common setting, but may not be true */
+	    if (info->IsIGP) {
+		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
+		info->BiosConnector[0].DACType = DAC_NONE;
+		info->BiosConnector[0].TMDSType = TMDS_NONE;
+		info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
+		info->BiosConnector[0].valid = TRUE;
+
+		/* IGP only has TVDAC */
+		if (info->ChipFamily == CHIP_FAMILY_RS400)
+		    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+		else
+		    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		info->BiosConnector[1].DACType = DAC_TVDAC;
+		info->BiosConnector[1].TMDSType = TMDS_NONE;
+		info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
+		info->BiosConnector[1].valid = TRUE;
+	    } else {
+#if defined(__powerpc__)
+		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+#else
+		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
+#endif
+		info->BiosConnector[0].DACType = DAC_NONE;
+		info->BiosConnector[0].TMDSType = TMDS_NONE;
+		info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
+		info->BiosConnector[0].valid = TRUE;
+
+		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		info->BiosConnector[1].DACType = DAC_PRIMARY;
+		info->BiosConnector[1].TMDSType = TMDS_NONE;
+		info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
+		info->BiosConnector[1].valid = TRUE;
+	    }
+	} else {
+	    /* Below is the most common setting, but may not be true */
+	    if (info->IsIGP) {
+		if (info->ChipFamily == CHIP_FAMILY_RS400)
+		    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+		else
+		    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		info->BiosConnector[0].DACType = DAC_TVDAC;
+		info->BiosConnector[0].TMDSType = TMDS_NONE;
+		info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
+		info->BiosConnector[0].valid = TRUE;
+
+		/* not sure what a good default DDCType for DVI on
+		 * IGP desktop chips is
+		 */
+		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); /* DDC_DVI? */
+		info->BiosConnector[1].DACType = DAC_NONE;
+		info->BiosConnector[1].TMDSType = TMDS_EXT;
+		info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_D;
+		info->BiosConnector[1].valid = TRUE;
+	    } else {
+		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+		info->BiosConnector[0].DACType = DAC_TVDAC;
+		info->BiosConnector[0].TMDSType = TMDS_INT;
+		info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
+		info->BiosConnector[0].valid = TRUE;
 
-    /* Some cards have the DDC lines swapped and we have no way to
-     * detect it yet (Mac cards)
-     */
-    if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) {
-	info->BiosConnector[0].DDCType = DDC_VGA;
-	info->BiosConnector[1].DDCType = DDC_DVI;
-    }
+#if defined(__powerpc__)
+		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		info->BiosConnector[1].DACType = DAC_PRIMARY;
+		info->BiosConnector[1].TMDSType = TMDS_EXT;
+		info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
+		info->BiosConnector[1].valid = TRUE;
+#else
+		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		info->BiosConnector[1].DACType = DAC_PRIMARY;
+		info->BiosConnector[1].TMDSType = TMDS_EXT;
+		info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
+		info->BiosConnector[1].valid = TRUE;
+#endif
+	    }
+	}
 
+	if (info->InternalTVOut) {
+	    info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
+	    info->BiosConnector[2].DACType = DAC_TVDAC;
+	    info->BiosConnector[2].TMDSType = TMDS_NONE;
+	    info->BiosConnector[2].ddc_i2c.valid = FALSE;
+	    info->BiosConnector[2].valid = TRUE;
+	}
+
+	/* Some cards have the DDC lines swapped and we have no way to
+	 * detect it yet (Mac cards)
+	 */
+	if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) {
+	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+	}
+    }
 }
 
 #if defined(__powerpc__)
@@ -3104,6 +2179,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
     int i = 0;
     int num_vga = 0;
     int num_dvi = 0;
+    int num_hdmi = 0;
 
     /* We first get the information about all connectors from BIOS.
      * This is how the card is phyiscally wired up.
@@ -3111,9 +2187,9 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
      */
     for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	info->BiosConnector[i].valid = FALSE;
-	info->BiosConnector[i].DDCType = DDC_NONE_DETECTED;
-	info->BiosConnector[i].DACType = DAC_UNKNOWN;
-	info->BiosConnector[i].TMDSType = TMDS_UNKNOWN;
+	info->BiosConnector[i].ddc_i2c.valid = FALSE;
+	info->BiosConnector[i].DACType = DAC_NONE;
+	info->BiosConnector[i].TMDSType = TMDS_NONE;
 	info->BiosConnector[i].ConnectorType = CONNECTOR_NONE;
     }
 
@@ -3162,15 +2238,9 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	    RADEONSetupGenericConnectors(pScrn);
     }
 
-    if (info->HasSingleDAC) {
-        /* For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC*/
-	for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
-	    if (info->BiosConnector[i].ConnectorType == CONNECTOR_CRT)
-		info->BiosConnector[i].DACType = DAC_TVDAC;
-	}
-    } else if (!pRADEONEnt->HasCRTC2) {
+    if (!pRADEONEnt->HasCRTC2) {
 	for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
-	    if (info->BiosConnector[i].ConnectorType == CONNECTOR_CRT)
+	    if (info->BiosConnector[i].ConnectorType == CONNECTOR_VGA)
 		info->BiosConnector[i].DACType = DAC_PRIMARY;
 	}
     }
@@ -3179,23 +2249,28 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
     optstr = (char *)xf86GetOptValString(info->Options, OPTION_CONNECTORTABLE);
 
     if (optstr) {
+	unsigned int ddc_line[2];
+
 	for (i = 2; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	    info->BiosConnector[i].valid = FALSE;
 	}
 	info->BiosConnector[0].valid = TRUE;
 	info->BiosConnector[1].valid = TRUE;
-	if (sscanf(optstr, "%u,%d,%d,%u,%u,%d,%d,%u",
-		   &info->BiosConnector[0].DDCType,
+	if (sscanf(optstr, "%u,%u,%u,%u,%u,%u,%u,%u",
+		   &ddc_line[0],
 		   &info->BiosConnector[0].DACType,
 		   &info->BiosConnector[0].TMDSType,
 		   &info->BiosConnector[0].ConnectorType,
-		   &info->BiosConnector[1].DDCType,
+		   &ddc_line[1],
 		   &info->BiosConnector[1].DACType,
 		   &info->BiosConnector[1].TMDSType,
 		   &info->BiosConnector[1].ConnectorType) != 8) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid ConnectorTable option: %s\n", optstr);
 	    return FALSE;
 	}
+
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(ddc_line[0]);
+	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(ddc_line[1]);
     }
 
     info->tvdac_use_count = 0;
@@ -3204,21 +2279,15 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	    if (info->BiosConnector[i].DACType == DAC_TVDAC)
 		info->tvdac_use_count++;
 
-	    if (info->IsAtomBios) {
-		if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D_ATOM) ||
-		    (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
-		    (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A_ATOM)) {
-		    num_dvi++;
-		} else if (info->BiosConnector[i].ConnectorType == CONNECTOR_VGA_ATOM) {
-		    num_vga++;
-		}
-	    } else {
-		if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
-		    (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I)) {
-		    num_dvi++;
-		} else if (info->BiosConnector[i].ConnectorType == CONNECTOR_CRT) {
-		    num_vga++;
-		}
+	    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++;
+	    } else if ((info->BiosConnector[i].ConnectorType == CONNECTOR_HDMI_TYPE_A) ||
+		       (info->BiosConnector[i].ConnectorType == CONNECTOR_HDMI_TYPE_B)) {
+		num_hdmi++;
 	    }
 	}
     }
@@ -3243,67 +2312,47 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	    }
 	    radeon_output->MonType = MT_UNKNOWN;
 	    radeon_output->ConnectorType = info->BiosConnector[i].ConnectorType;
-	    radeon_output->DDCType = info->BiosConnector[i].DDCType;
-	    if (info->IsAtomBios) {
-		if (radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM)
-		    radeon_output->DACType = DAC_NONE;
-		else
-		    radeon_output->DACType = info->BiosConnector[i].DACType;
+	    radeon_output->devices = info->BiosConnector[i].devices;
+	    radeon_output->output_id = info->BiosConnector[i].output_id;
+	    radeon_output->ddc_i2c = info->BiosConnector[i].ddc_i2c;
 
-		if (radeon_output->ConnectorType == CONNECTOR_VGA_ATOM)
-		    radeon_output->TMDSType = TMDS_NONE;
-		else
-		    radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
-	    } else {
-		if (radeon_output->ConnectorType == CONNECTOR_DVI_D)
-		    radeon_output->DACType = DAC_NONE;
-		else
-		    radeon_output->DACType = info->BiosConnector[i].DACType;
+	    if (radeon_output->ConnectorType == CONNECTOR_DVI_D)
+		radeon_output->DACType = DAC_NONE;
+	    else
+		radeon_output->DACType = info->BiosConnector[i].DACType;
+
+	    if (radeon_output->ConnectorType == CONNECTOR_VGA)
+		radeon_output->TMDSType = TMDS_NONE;
+	    else
+		radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
 
-		if (radeon_output->ConnectorType == CONNECTOR_CRT)
-		    radeon_output->TMDSType = TMDS_NONE;
-		else
-		    radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
-	    }
 	    RADEONSetOutputType(pScrn, radeon_output);
-	    if (info->IsAtomBios) {
-		if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D_ATOM) ||
-		    (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
-		    (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A_ATOM)) {
-		    if (num_dvi > 1) {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
-			num_dvi--;
-		    } else {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
-		    }
-		} else if (info->BiosConnector[i].ConnectorType == CONNECTOR_VGA_ATOM) {
-		    if (num_vga > 1) {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
-			num_vga--;
-		    } else {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
-		    }
-		} else
-		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
-	    } else {
-		if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
-		     (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I)) {
-		    if (num_dvi > 1) {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
-			num_dvi--;
-		    } else {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
-		    }
-		} else if (info->BiosConnector[i].ConnectorType == CONNECTOR_CRT) {
-		    if (num_vga > 1) {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
-			num_vga--;
-		    } else {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
-		    }
-		} else
-		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
-	    }
+	    if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
+		(info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I) ||
+		(info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A)) {
+		if (num_dvi > 1) {
+		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
+		    num_dvi--;
+		} else {
+		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
+		}
+	    } else if (info->BiosConnector[i].ConnectorType == CONNECTOR_VGA) {
+		if (num_vga > 1) {
+		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
+		    num_vga--;
+		} else {
+		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
+		}
+	    } else if ((info->BiosConnector[i].ConnectorType == CONNECTOR_HDMI_TYPE_A) ||
+		(info->BiosConnector[i].ConnectorType == CONNECTOR_HDMI_TYPE_B)) {
+		if (num_hdmi > 1) {
+		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, "HDMI-1");
+		    num_hdmi--;
+		} else {
+		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, "HDMI-0");
+		}
+	    } else
+		output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
 
 	    if (!output) {
 		return FALSE;
diff --git a/src/radeon_pci_chipset_gen.h b/src/radeon_pci_chipset_gen.h
index 7a36242..9d73b96 100644
--- a/src/radeon_pci_chipset_gen.h
+++ b/src/radeon_pci_chipset_gen.h
@@ -115,6 +115,7 @@ PciChipsets RADEONPciChipsets[] = {
  { PCI_CHIP_RV370_5B60, PCI_CHIP_RV370_5B60, RES_SHARED_VGA },
  { PCI_CHIP_RV370_5B62, PCI_CHIP_RV370_5B62, RES_SHARED_VGA },
  { PCI_CHIP_RV370_5B63, PCI_CHIP_RV370_5B63, RES_SHARED_VGA },
+ { PCI_CHIP_RV370_5657, PCI_CHIP_RV370_5657, RES_SHARED_VGA },
  { PCI_CHIP_RV370_5B64, PCI_CHIP_RV370_5B64, RES_SHARED_VGA },
  { PCI_CHIP_RV370_5B65, PCI_CHIP_RV370_5B65, RES_SHARED_VGA },
  { PCI_CHIP_RV280_5C61, PCI_CHIP_RV280_5C61, RES_SHARED_VGA },
@@ -135,7 +136,139 @@ PciChipsets RADEONPciChipsets[] = {
  { PCI_CHIP_RV410_5E4C, PCI_CHIP_RV410_5E4C, RES_SHARED_VGA },
  { PCI_CHIP_RV410_5E4D, PCI_CHIP_RV410_5E4D, RES_SHARED_VGA },
  { PCI_CHIP_RV410_5E4F, PCI_CHIP_RV410_5E4F, RES_SHARED_VGA },
+ { PCI_CHIP_R520_7100, PCI_CHIP_R520_7100, RES_SHARED_VGA },
+ { PCI_CHIP_R520_7101, PCI_CHIP_R520_7101, RES_SHARED_VGA },
+ { PCI_CHIP_R520_7102, PCI_CHIP_R520_7102, RES_SHARED_VGA },
+ { PCI_CHIP_R520_7103, PCI_CHIP_R520_7103, RES_SHARED_VGA },
+ { PCI_CHIP_R520_7104, PCI_CHIP_R520_7104, RES_SHARED_VGA },
+ { PCI_CHIP_R520_7105, PCI_CHIP_R520_7105, RES_SHARED_VGA },
+ { PCI_CHIP_R520_7106, PCI_CHIP_R520_7106, RES_SHARED_VGA },
+ { PCI_CHIP_R520_7108, PCI_CHIP_R520_7108, RES_SHARED_VGA },
+ { PCI_CHIP_R520_7109, PCI_CHIP_R520_7109, RES_SHARED_VGA },
+ { PCI_CHIP_R520_710A, PCI_CHIP_R520_710A, RES_SHARED_VGA },
+ { PCI_CHIP_R520_710B, PCI_CHIP_R520_710B, RES_SHARED_VGA },
+ { PCI_CHIP_R520_710C, PCI_CHIP_R520_710C, RES_SHARED_VGA },
+ { PCI_CHIP_R520_710E, PCI_CHIP_R520_710E, RES_SHARED_VGA },
+ { PCI_CHIP_R520_710F, PCI_CHIP_R520_710F, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7140, PCI_CHIP_RV515_7140, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7141, PCI_CHIP_RV515_7141, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7142, PCI_CHIP_RV515_7142, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7143, PCI_CHIP_RV515_7143, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7144, PCI_CHIP_RV515_7144, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7145, PCI_CHIP_RV515_7145, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7146, PCI_CHIP_RV515_7146, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7147, PCI_CHIP_RV515_7147, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7149, PCI_CHIP_RV515_7149, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_714A, PCI_CHIP_RV515_714A, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_714B, PCI_CHIP_RV515_714B, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_714C, PCI_CHIP_RV515_714C, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_714D, PCI_CHIP_RV515_714D, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_714E, PCI_CHIP_RV515_714E, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_714F, PCI_CHIP_RV515_714F, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7151, PCI_CHIP_RV515_7151, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7152, PCI_CHIP_RV515_7152, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7153, PCI_CHIP_RV515_7153, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_715E, PCI_CHIP_RV515_715E, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_715F, PCI_CHIP_RV515_715F, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7180, PCI_CHIP_RV515_7180, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7181, PCI_CHIP_RV515_7181, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7183, PCI_CHIP_RV515_7183, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7186, PCI_CHIP_RV515_7186, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7187, PCI_CHIP_RV515_7187, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7188, PCI_CHIP_RV515_7188, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_718A, PCI_CHIP_RV515_718A, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_718B, PCI_CHIP_RV515_718B, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_718C, PCI_CHIP_RV515_718C, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_718D, PCI_CHIP_RV515_718D, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_718F, PCI_CHIP_RV515_718F, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7193, PCI_CHIP_RV515_7193, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7196, PCI_CHIP_RV515_7196, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_719B, PCI_CHIP_RV515_719B, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_719F, PCI_CHIP_RV515_719F, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_71C0, PCI_CHIP_RV530_71C0, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_71C1, PCI_CHIP_RV530_71C1, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_71C2, PCI_CHIP_RV530_71C2, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_71C3, PCI_CHIP_RV530_71C3, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_71C4, PCI_CHIP_RV530_71C4, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_71C5, PCI_CHIP_RV530_71C5, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_71C6, PCI_CHIP_RV530_71C6, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_71C7, PCI_CHIP_RV530_71C7, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_71CD, PCI_CHIP_RV530_71CD, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_71CE, PCI_CHIP_RV530_71CE, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_71D2, PCI_CHIP_RV530_71D2, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_71D4, PCI_CHIP_RV530_71D4, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_71D5, PCI_CHIP_RV530_71D5, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_71D6, PCI_CHIP_RV530_71D6, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_71DA, PCI_CHIP_RV530_71DA, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_71DE, PCI_CHIP_RV530_71DE, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_7200, PCI_CHIP_RV530_7200, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_7210, PCI_CHIP_RV530_7210, RES_SHARED_VGA },
+ { PCI_CHIP_RV530_7211, PCI_CHIP_RV530_7211, RES_SHARED_VGA },
+ { PCI_CHIP_R580_7240, PCI_CHIP_R580_7240, RES_SHARED_VGA },
+ { PCI_CHIP_R580_7243, PCI_CHIP_R580_7243, RES_SHARED_VGA },
+ { PCI_CHIP_R580_7244, PCI_CHIP_R580_7244, RES_SHARED_VGA },
+ { PCI_CHIP_R580_7245, PCI_CHIP_R580_7245, RES_SHARED_VGA },
+ { PCI_CHIP_R580_7246, PCI_CHIP_R580_7246, RES_SHARED_VGA },
+ { PCI_CHIP_R580_7247, PCI_CHIP_R580_7247, RES_SHARED_VGA },
+ { PCI_CHIP_R580_7248, PCI_CHIP_R580_7248, RES_SHARED_VGA },
+ { PCI_CHIP_R580_7249, PCI_CHIP_R580_7249, RES_SHARED_VGA },
+ { PCI_CHIP_R580_724A, PCI_CHIP_R580_724A, RES_SHARED_VGA },
+ { PCI_CHIP_R580_724B, PCI_CHIP_R580_724B, RES_SHARED_VGA },
+ { PCI_CHIP_R580_724C, PCI_CHIP_R580_724C, RES_SHARED_VGA },
+ { PCI_CHIP_R580_724D, PCI_CHIP_R580_724D, RES_SHARED_VGA },
+ { PCI_CHIP_R580_724E, PCI_CHIP_R580_724E, RES_SHARED_VGA },
+ { PCI_CHIP_R580_724F, PCI_CHIP_R580_724F, RES_SHARED_VGA },
+ { PCI_CHIP_RV570_7280, PCI_CHIP_RV570_7280, RES_SHARED_VGA },
+ { PCI_CHIP_RV560_7281, PCI_CHIP_RV560_7281, RES_SHARED_VGA },
+ { PCI_CHIP_RV560_7283, PCI_CHIP_RV560_7283, RES_SHARED_VGA },
+ { PCI_CHIP_R580_7284, PCI_CHIP_R580_7284, RES_SHARED_VGA },
+ { PCI_CHIP_RV560_7287, PCI_CHIP_RV560_7287, RES_SHARED_VGA },
+ { PCI_CHIP_RV570_7288, PCI_CHIP_RV570_7288, RES_SHARED_VGA },
+ { PCI_CHIP_RV570_7289, PCI_CHIP_RV570_7289, RES_SHARED_VGA },
+ { PCI_CHIP_RV570_728B, PCI_CHIP_RV570_728B, RES_SHARED_VGA },
+ { PCI_CHIP_RV570_728C, PCI_CHIP_RV570_728C, RES_SHARED_VGA },
+ { PCI_CHIP_RV560_7290, PCI_CHIP_RV560_7290, RES_SHARED_VGA },
+ { PCI_CHIP_RV560_7291, PCI_CHIP_RV560_7291, RES_SHARED_VGA },
+ { PCI_CHIP_RV560_7293, PCI_CHIP_RV560_7293, RES_SHARED_VGA },
+ { PCI_CHIP_RV560_7297, PCI_CHIP_RV560_7297, RES_SHARED_VGA },
  { PCI_CHIP_RS350_7834, PCI_CHIP_RS350_7834, RES_SHARED_VGA },
  { PCI_CHIP_RS350_7835, PCI_CHIP_RS350_7835, RES_SHARED_VGA },
+ { PCI_CHIP_RS690_791E, PCI_CHIP_RS690_791E, RES_SHARED_VGA },
+ { PCI_CHIP_RS690_791F, PCI_CHIP_RS690_791F, RES_SHARED_VGA },
+ { PCI_CHIP_RS740_796C, PCI_CHIP_RS740_796C, RES_SHARED_VGA },
+ { PCI_CHIP_RS740_796D, PCI_CHIP_RS740_796D, RES_SHARED_VGA },
+ { PCI_CHIP_RS740_796E, PCI_CHIP_RS740_796E, RES_SHARED_VGA },
+ { PCI_CHIP_RS740_796F, PCI_CHIP_RS740_796F, RES_SHARED_VGA },
+ { PCI_CHIP_R600_9400, PCI_CHIP_R600_9400, RES_SHARED_VGA },
+ { PCI_CHIP_R600_9401, PCI_CHIP_R600_9401, RES_SHARED_VGA },
+ { PCI_CHIP_R600_9402, PCI_CHIP_R600_9402, RES_SHARED_VGA },
+ { PCI_CHIP_R600_9403, PCI_CHIP_R600_9403, RES_SHARED_VGA },
+ { PCI_CHIP_R600_9405, PCI_CHIP_R600_9405, RES_SHARED_VGA },
+ { PCI_CHIP_R600_940A, PCI_CHIP_R600_940A, RES_SHARED_VGA },
+ { PCI_CHIP_R600_940B, PCI_CHIP_R600_940B, RES_SHARED_VGA },
+ { PCI_CHIP_R600_940F, PCI_CHIP_R600_940F, RES_SHARED_VGA },
+ { PCI_CHIP_RV610_94C0, PCI_CHIP_RV610_94C0, RES_SHARED_VGA },
+ { PCI_CHIP_RV610_94C1, PCI_CHIP_RV610_94C1, RES_SHARED_VGA },
+ { PCI_CHIP_RV610_94C3, PCI_CHIP_RV610_94C3, RES_SHARED_VGA },
+ { PCI_CHIP_RV610_94C4, PCI_CHIP_RV610_94C4, RES_SHARED_VGA },
+ { PCI_CHIP_RV610_94C5, PCI_CHIP_RV610_94C5, RES_SHARED_VGA },
+ { PCI_CHIP_RV610_94C6, PCI_CHIP_RV610_94C6, RES_SHARED_VGA },
+ { PCI_CHIP_RV610_94C7, PCI_CHIP_RV610_94C7, RES_SHARED_VGA },
+ { PCI_CHIP_RV610_94C8, PCI_CHIP_RV610_94C8, RES_SHARED_VGA },
+ { PCI_CHIP_RV610_94C9, PCI_CHIP_RV610_94C9, RES_SHARED_VGA },
+ { PCI_CHIP_RV610_94CB, PCI_CHIP_RV610_94CB, RES_SHARED_VGA },
+ { PCI_CHIP_RV610_94CC, PCI_CHIP_RV610_94CC, RES_SHARED_VGA },
+ { PCI_CHIP_RV630_9580, PCI_CHIP_RV630_9580, RES_SHARED_VGA },
+ { PCI_CHIP_RV630_9581, PCI_CHIP_RV630_9581, RES_SHARED_VGA },
+ { PCI_CHIP_RV630_9583, PCI_CHIP_RV630_9583, RES_SHARED_VGA },
+ { PCI_CHIP_RV630_9586, PCI_CHIP_RV630_9586, RES_SHARED_VGA },
+ { PCI_CHIP_RV630_9587, PCI_CHIP_RV630_9587, RES_SHARED_VGA },
+ { PCI_CHIP_RV630_9588, PCI_CHIP_RV630_9588, RES_SHARED_VGA },
+ { PCI_CHIP_RV630_9589, PCI_CHIP_RV630_9589, RES_SHARED_VGA },
+ { PCI_CHIP_RV630_958A, PCI_CHIP_RV630_958A, RES_SHARED_VGA },
+ { PCI_CHIP_RV630_958B, PCI_CHIP_RV630_958B, RES_SHARED_VGA },
+ { PCI_CHIP_RV630_958C, PCI_CHIP_RV630_958C, RES_SHARED_VGA },
+ { PCI_CHIP_RV630_958D, PCI_CHIP_RV630_958D, RES_SHARED_VGA },
+ { PCI_CHIP_RV630_958E, PCI_CHIP_RV630_958E, RES_SHARED_VGA },
  { -1,                 -1,                 RES_UNDEFINED }
 };
diff --git a/src/radeon_probe.c b/src/radeon_probe.c
index baea47c..0cf54b6 100644
--- a/src/radeon_probe.c
+++ b/src/radeon_probe.c
@@ -58,7 +58,7 @@
 int gRADEONEntityIndex = -1;
 
 /* Return the options for supported chipset 'n'; NULL otherwise */
-_X_EXPORT const OptionInfoRec *
+static const OptionInfoRec *
 RADEONAvailableOptions(int chipid, int busid)
 {
     int  i;
@@ -77,7 +77,7 @@ RADEONAvailableOptions(int chipid, int busid)
 }
 
 /* Return the string name for supported chipset 'n'; NULL otherwise. */
-_X_EXPORT void
+static void
 RADEONIdentify(int flags)
 {
     xf86PrintChipsets(RADEON_NAME,
@@ -86,7 +86,7 @@ RADEONIdentify(int flags)
 }
 
 /* Return TRUE if chipset is present; FALSE otherwise. */
-_X_EXPORT Bool
+static Bool
 RADEONProbe(DriverPtr drv, int flags)
 {
     int      numUsed;
@@ -175,7 +175,7 @@ RADEONProbe(DriverPtr drv, int flags)
 		DevUnion   *pPriv;
 		RADEONEntPtr pRADEONEnt;
 
-		/*xf86SetEntitySharable(usedChips[i]);*/
+		xf86SetEntitySharable(usedChips[i]);
 
 		if (gRADEONEntityIndex == -1)
 		    gRADEONEntityIndex = xf86AllocateEntityPrivateIndex();
@@ -207,3 +207,14 @@ RADEONProbe(DriverPtr drv, int flags)
 
     return foundScreen;
 }
+
+_X_EXPORT DriverRec RADEON =
+{
+    RADEON_VERSION_CURRENT,
+    RADEON_DRIVER_NAME,
+    RADEONIdentify,
+    RADEONProbe,
+    RADEONAvailableOptions,
+    NULL,
+    0
+};
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 7f8ce45..df87dab 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -36,6 +36,7 @@
 #ifndef _RADEON_PROBE_H_
 #define _RADEON_PROBE_H_ 1
 
+#include <stdint.h>
 #include "xf86str.h"
 #include "xf86DDC.h"
 #include "randrstr.h"
@@ -52,16 +53,7 @@
 #include "xaa.h"
 #endif
 
-typedef enum
-{
-    DDC_NONE_DETECTED,
-    DDC_MONID,
-    DDC_DVI,
-    DDC_VGA,
-    DDC_CRT2,
-    DDC_LCD,
-    DDC_GPIO,
-} RADEONDDCType;
+extern DriverRec RADEON;
 
 typedef enum
 {
@@ -71,49 +63,47 @@ typedef enum
     MT_LCD     = 2,
     MT_DFP     = 3,
     MT_CTV     = 4,
-    MT_STV     = 5
+    MT_STV     = 5,
+    MT_CV      = 6,
+    MT_HDMI    = 7, // this should really just be MT_DFP
+    MT_DP      = 8
 } RADEONMonitorType;
 
 typedef enum
 {
     CONNECTOR_NONE,
-    CONNECTOR_PROPRIETARY,
-    CONNECTOR_CRT,
+    CONNECTOR_VGA,
     CONNECTOR_DVI_I,
     CONNECTOR_DVI_D,
-    CONNECTOR_CTV,
+    CONNECTOR_DVI_A,
     CONNECTOR_STV,
+    CONNECTOR_CTV,
+    CONNECTOR_LVDS,
+    CONNECTOR_DIGITAL,
+    CONNECTOR_SCART,
+    CONNECTOR_HDMI_TYPE_A,
+    CONNECTOR_HDMI_TYPE_B,
+    CONNECTOR_0XC,
+    CONNECTOR_0XD,
+    CONNECTOR_DIN,
+    CONNECTOR_DISPLAY_PORT,
     CONNECTOR_UNSUPPORTED
 } RADEONConnectorType;
 
 typedef enum
 {
-    CONNECTOR_NONE_ATOM,
-    CONNECTOR_VGA_ATOM,
-    CONNECTOR_DVI_I_ATOM,
-    CONNECTOR_DVI_D_ATOM,
-    CONNECTOR_DVI_A_ATOM,
-    CONNECTOR_STV_ATOM,
-    CONNECTOR_CTV_ATOM,
-    CONNECTOR_LVDS_ATOM,
-    CONNECTOR_DIGITAL_ATOM,
-    CONNECTOR_UNSUPPORTED_ATOM
-} RADEONConnectorTypeATOM;
-
-typedef enum
-{
-    DAC_UNKNOWN = -1,
-    DAC_PRIMARY = 0,
-    DAC_TVDAC   = 1,
-    DAC_NONE    = 2
+    DAC_NONE    = 0,
+    DAC_PRIMARY = 1,
+    DAC_TVDAC   = 2,
+    DAC_EXT     = 3
 } RADEONDacType;
 
 typedef enum
 {
-    TMDS_UNKNOWN = -1,
-    TMDS_INT     = 0,
-    TMDS_EXT     = 1,
-    TMDS_NONE    = 2
+    TMDS_NONE    = 0,
+    TMDS_INT     = 1,
+    TMDS_EXT     = 2,
+    TMDS_LVTMA   = 3
 } RADEONTmdsType;
 
 typedef enum
@@ -127,8 +117,7 @@ typedef enum
 {
     RMX_OFF,
     RMX_FULL,
-    RMX_CENTER,
-    RMX_ASPECT
+    RMX_CENTER
 } RADEONRMXType;
 
 typedef struct {
@@ -140,12 +129,23 @@ typedef enum
 {
     OUTPUT_NONE,
     OUTPUT_VGA,
-    OUTPUT_DVI,
+    OUTPUT_DVI_I,
+    OUTPUT_DVI_D,
+    OUTPUT_DVI_A,
     OUTPUT_LVDS,
     OUTPUT_STV,
     OUTPUT_CTV,
+    OUTPUT_CV,
+    OUTPUT_HDMI,
+    OUTPUT_DP
 } RADEONOutputType;
 
+#define OUTPUT_IS_DVI ((radeon_output->type == OUTPUT_DVI_D || \
+                        radeon_output->type == OUTPUT_DVI_I || \
+                        radeon_output->type == OUTPUT_DVI_A))
+#define OUTPUT_IS_TV ((radeon_output->type == OUTPUT_STV || \
+                       radeon_output->type == OUTPUT_CTV))
+
 /* standards */
 typedef enum
 {
@@ -155,8 +155,27 @@ typedef enum
     TV_STD_PAL_60    = 8,
     TV_STD_NTSC_J    = 16,
     TV_STD_SCART_PAL = 32,
+    TV_STD_SECAM     = 64,
+    TV_STD_PAL_CN    = 128,
 } TVStd;
 
+typedef struct
+{
+    Bool   valid;
+    CARD32 mask_clk_reg;
+    CARD32 mask_data_reg;
+    CARD32 put_clk_reg;
+    CARD32 put_data_reg;
+    CARD32 get_clk_reg;
+    CARD32 get_data_reg;
+    CARD32 mask_clk_mask;
+    CARD32 mask_data_mask;
+    CARD32 put_clk_mask;
+    CARD32 put_data_mask;
+    CARD32 get_clk_mask;
+    CARD32 get_data_mask;
+} RADEONI2CBusRec, *RADEONI2CBusPtr;
+
 typedef struct _RADEONCrtcPrivateRec {
 #ifdef USE_XAA
     FBLinearPtr rotate_mem_xaa;
@@ -169,21 +188,32 @@ typedef struct _RADEONCrtcPrivateRec {
     CARD32 cursor_offset;
     /* Lookup table values to be set when the CRTC is enabled */
     CARD8 lut_r[256], lut_g[256], lut_b[256];
+
+    uint32_t crtc_offset;
+    int               h_total, h_blank, h_sync_wid, h_sync_pol;
+    int               v_total, v_blank, v_sync_wid, v_sync_pol;
+    int               fb_format, fb_length;
+    int               fb_pitch, fb_width, fb_height;
+    INT16             cursor_x;
+    INT16             cursor_y;
 } RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr;
 
 typedef struct {
-    RADEONDDCType DDCType;
     RADEONDacType DACType;
     RADEONTmdsType TMDSType;
     RADEONConnectorType ConnectorType;
     Bool valid;
+    int output_id;
+    int devices;
+    int hpd_mask;
+    RADEONI2CBusRec ddc_i2c;
 } RADEONBIOSConnector;
 
 typedef struct _RADEONOutputPrivateRec {
     int num;
     RADEONOutputType type;
     void *dev_priv;
-    RADEONDDCType DDCType;
+    CARD32 ddc_line;
     RADEONDacType DACType;
     RADEONDviType DVIType;
     RADEONTmdsType TMDSType;
@@ -192,7 +222,10 @@ typedef struct _RADEONOutputPrivateRec {
     int crtc_num;
     int DDCReg;
     I2CBusPtr         pI2CBus;
-    CARD32            tv_dac_adj;
+    RADEONI2CBusRec   ddc_i2c;
+    CARD32            ps2_tvdac_adj;
+    CARD32            pal_tvdac_adj;
+    CARD32            ntsc_tvdac_adj;
     /* panel stuff */
     int               PanelXRes;
     int               PanelYRes;
@@ -209,7 +242,7 @@ typedef struct _RADEONOutputPrivateRec {
     RADEONRMXType     rmx_type;
     /* dvo */
     I2CDevPtr         DVOChip;
-    int               dvo_i2c_reg;
+    RADEONI2CBusRec   dvo_i2c;
     int               dvo_i2c_slave_addr;
     Bool              dvo_duallink;
     /* TV out */
@@ -222,10 +255,291 @@ typedef struct _RADEONOutputPrivateRec {
     int               SupportedTVStds;
     Bool              tv_on;
     int               load_detection;
+
+    char              *name;
+    int               output_id;
+    int               devices;
 } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
 
+struct avivo_pll_state {
+    CARD32 ref_div_src;
+    CARD32 ref_div;
+    CARD32 fb_div;
+    CARD32 post_div_src;
+    CARD32 post_div;
+    CARD32 ext_ppll_cntl;
+    CARD32 pll_cntl;
+    CARD32 int_ss_cntl;
+};
+
+
+struct avivo_crtc_state {
+    CARD32 pll_source;
+    CARD32 h_total;
+    CARD32 h_blank_start_end;
+    CARD32 h_sync_a;
+    CARD32 h_sync_a_cntl;
+    CARD32 h_sync_b;
+    CARD32 h_sync_b_cntl;
+    CARD32 v_total;
+    CARD32 v_blank_start_end;
+    CARD32 v_sync_a;
+    CARD32 v_sync_a_cntl;
+    CARD32 v_sync_b;
+    CARD32 v_sync_b_cntl;
+    CARD32 control;
+    CARD32 blank_control;
+    CARD32 interlace_control;
+    CARD32 stereo_control;
+    CARD32 cursor_control;
+};
+
+struct avivo_grph_state {
+    CARD32 enable;
+    CARD32 control;
+    CARD32 prim_surf_addr;
+    CARD32 sec_surf_addr;
+    CARD32 pitch;
+    CARD32 x_offset;
+    CARD32 y_offset;
+    CARD32 x_start;
+    CARD32 y_start;
+    CARD32 x_end;
+    CARD32 y_end;
+
+    CARD32 viewport_start;
+    CARD32 viewport_size;
+    CARD32 scl_enable;
+    CARD32 scl_tap_control;
+};
+
+struct avivo_dac_state {
+    CARD32 enable;
+    CARD32 source_select;
+    CARD32 force_output_cntl;
+    CARD32 powerdown;
+};
+
+struct avivo_dig_state {
+    CARD32 cntl;
+    CARD32 bit_depth_cntl;
+    CARD32 data_sync;
+    CARD32 transmitter_enable;
+    CARD32 transmitter_cntl;
+    CARD32 source_select;
+};
+
+struct avivo_state
+{
+    CARD32 hdp_fb_location;
+    CARD32 mc_memory_map;
+    CARD32 vga_memory_base;
+    CARD32 vga_fb_start;
+
+    CARD32 vga1_cntl;
+    CARD32 vga2_cntl;
+
+    CARD32 crtc_master_en;
+    CARD32 crtc_tv_control;
+
+    CARD32 lvtma_pwrseq_cntl;
+    CARD32 lvtma_pwrseq_state;
+
+    struct avivo_pll_state pll1;
+    struct avivo_pll_state pll2;
+
+    struct avivo_crtc_state crtc1;
+    struct avivo_crtc_state crtc2;
+
+    struct avivo_grph_state grph1;
+    struct avivo_grph_state grph2;
+
+    struct avivo_dac_state daca;
+    struct avivo_dac_state dacb;
+
+    struct avivo_dig_state tmds1;
+    struct avivo_dig_state tmds2;
+
+};
+
+/*
+ * Maximum length of horizontal/vertical code timing tables for state storage
+ */
+#define MAX_H_CODE_TIMING_LEN 32
+#define MAX_V_CODE_TIMING_LEN 32
+
+typedef struct {
+    struct avivo_state avivo;
+
+				/* 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            bios_4_scratch;
+    CARD32            bios_5_scratch;
+    CARD32            bios_6_scratch;
+    CARD32            surface_cntl;
+    CARD32            surfaces[8][3];
+    CARD32            mc_agp_location;
+    CARD32            mc_agp_location_hi;
+    CARD32            mc_fb_location;
+    CARD32            display_base_addr;
+    CARD32            display2_base_addr;
+    CARD32            ov0_base_addr;
+
+				/* Other registers to save for VT switches */
+    CARD32            dp_datatype;
+    CARD32            rbbm_soft_reset;
+    CARD32            clock_cntl_index;
+    CARD32            amcgpio_en_reg;
+    CARD32            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;
+    CARD32            disp_merge_cntl;
+    CARD32            grph_buffer_cntl;
+    CARD32            crtc_more_cntl;
+    CARD32            crtc_tile_x0_y0;
+
+				/* CRTC2 registers */
+    CARD32            crtc2_gen_cntl;
+    CARD32            dac_macro_cntl;
+    CARD32            dac2_cntl;
+    CARD32            disp_output_cntl;
+    CARD32            disp_tv_out_cntl;
+    CARD32            disp_hw_debug;
+    CARD32            disp2_merge_cntl;
+    CARD32            grph2_buffer_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;
+    CARD32            crtc2_tile_x0_y0;
+
+				/* Flat panel registers */
+    CARD32            fp_crtc_h_total_disp;
+    CARD32            fp_crtc_v_total_disp;
+    CARD32            fp_gen_cntl;
+    CARD32            fp2_gen_cntl;
+    CARD32            fp_h_sync_strt_wid;
+    CARD32            fp_h2_sync_strt_wid;
+    CARD32            fp_horz_stretch;
+    CARD32            fp_horz_vert_active;
+    CARD32            fp_panel_cntl;
+    CARD32            fp_v_sync_strt_wid;
+    CARD32            fp_v2_sync_strt_wid;
+    CARD32            fp_vert_stretch;
+    CARD32            lvds_gen_cntl;
+    CARD32            lvds_pll_cntl;
+    CARD32            tmds_pll_cntl;
+    CARD32            tmds_transmitter_cntl;
+
+				/* Computed values for PLL */
+    CARD32            dot_clock_freq;
+    CARD32            pll_output_freq;
+    int               feedback_div;
+    int               reference_div;
+    int               post_div;
+
+				/* PLL registers */
+    unsigned          ppll_ref_div;
+    unsigned          ppll_div_3;
+    CARD32            htotal_cntl;
+    CARD32            vclk_ecp_cntl;
+
+				/* Computed values for PLL2 */
+    CARD32            dot_clock_freq_2;
+    CARD32            pll_output_freq_2;
+    int               feedback_div_2;
+    int               reference_div_2;
+    int               post_div_2;
+
+				/* PLL2 registers */
+    CARD32            p2pll_ref_div;
+    CARD32            p2pll_div_0;
+    CARD32            htotal_cntl2;
+    CARD32            pixclks_cntl;
+
+				/* Pallet */
+    Bool              palette_valid;
+    CARD32            palette[256];
+    CARD32            palette2[256];
+
+    CARD32            rs480_unk_e30;
+    CARD32            rs480_unk_e34;
+    CARD32            rs480_unk_e38;
+    CARD32            rs480_unk_e3c;
+
+    /* TV out registers */
+    CARD32 	      tv_master_cntl;
+    CARD32 	      tv_htotal;
+    CARD32 	      tv_hsize;
+    CARD32 	      tv_hdisp;
+    CARD32 	      tv_hstart;
+    CARD32 	      tv_vtotal;
+    CARD32 	      tv_vdisp;
+    CARD32 	      tv_timing_cntl;
+    CARD32 	      tv_vscaler_cntl1;
+    CARD32 	      tv_vscaler_cntl2;
+    CARD32 	      tv_sync_size;
+    CARD32 	      tv_vrestart;
+    CARD32 	      tv_hrestart;
+    CARD32 	      tv_frestart;
+    CARD32 	      tv_ftotal;
+    CARD32 	      tv_clock_sel_cntl;
+    CARD32 	      tv_clkout_cntl;
+    CARD32 	      tv_data_delay_a;
+    CARD32 	      tv_data_delay_b;
+    CARD32 	      tv_dac_cntl;
+    CARD32 	      tv_pll_cntl;
+    CARD32 	      tv_pll_cntl1;
+    CARD32	      tv_pll_fine_cntl;
+    CARD32 	      tv_modulator_cntl1;
+    CARD32 	      tv_modulator_cntl2;
+    CARD32 	      tv_frame_lock_cntl;
+    CARD32 	      tv_pre_dac_mux_cntl;
+    CARD32 	      tv_rgb_cntl;
+    CARD32 	      tv_y_saw_tooth_cntl;
+    CARD32 	      tv_y_rise_cntl;
+    CARD32 	      tv_y_fall_cntl;
+    CARD32 	      tv_uv_adr;
+    CARD32	      tv_upsamp_and_gain_cntl;
+    CARD32	      tv_gain_limit_settings;
+    CARD32	      tv_linear_gain_settings;
+    CARD32	      tv_crc_cntl;
+    CARD32            tv_sync_cntl;
+    CARD32	      gpiopad_a;
+    CARD32            pll_test_cntl;
+
+    CARD16	      h_code_timing[MAX_H_CODE_TIMING_LEN];
+    CARD16	      v_code_timing[MAX_V_CODE_TIMING_LEN];
+
+} RADEONSaveRec, *RADEONSavePtr;
+
 #define RADEON_MAX_CRTC 2
-#define RADEON_MAX_BIOS_CONNECTOR 8
+#define RADEON_MAX_BIOS_CONNECTOR 16
 
 typedef struct
 {
@@ -243,17 +557,18 @@ typedef struct
     xf86CrtcPtr pCrtc[RADEON_MAX_CRTC];
     RADEONCrtcPrivatePtr Controller[RADEON_MAX_CRTC];
 
+    ScrnInfoPtr pSecondaryScrn;    
+    ScrnInfoPtr pPrimaryScrn;
+
+    RADEONSaveRec     ModeReg;          /* Current mode                      */
+    RADEONSaveRec     SavedReg;         /* Original (text) mode              */
+
 } RADEONEntRec, *RADEONEntPtr;
 
 /* radeon_probe.c */
-extern const OptionInfoRec *RADEONAvailableOptions(int, int);
-extern void                 RADEONIdentify(int);
-extern Bool                 RADEONProbe(DriverPtr, int);
-
 extern PciChipsets          RADEONPciChipsets[];
 
 /* radeon_driver.c */
-extern void                 RADEONLoaderRefSymLists(void);
 extern Bool                 RADEONPreInit(ScrnInfoPtr, int);
 extern Bool                 RADEONScreenInit(int, ScreenPtr, int, char **);
 extern Bool                 RADEONSwitchMode(int, DisplayModePtr, int);
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 6e4e383..eec8784 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -337,6 +337,8 @@
 #       define RADEON_CRTC2_HSYNC_DIS       (1 << 28)
 #       define RADEON_CRTC2_VSYNC_DIS       (1 << 29)
 #define RADEON_CRTC_MORE_CNTL               0x27c
+#       define RADEON_CRTC_AUTO_HORZ_CENTER_EN (1<<2)
+#       define RADEON_CRTC_AUTO_VERT_CENTER_EN (1<<3)
 #       define RADEON_CRTC_H_CUTOFF_ACTIVE_EN (1<<4)
 #       define RADEON_CRTC_V_CUTOFF_ACTIVE_EN (1<<5)
 #define RADEON_CRTC_GUI_TRIG_VLINE          0x0218
@@ -812,6 +814,7 @@
 #       define RADEON_HORZ_AUTO_RATIO         (1      << 27)
 #       define RADEON_HORZ_FP_LOOP_STRETCH    (0x7    << 28)
 #       define RADEON_HORZ_AUTO_RATIO_INC     (1      << 31)
+#define RADEON_FP_HORZ_VERT_ACTIVE          0x0278
 #define RADEON_FP_V_SYNC_STRT_WID           0x02c8
 #define RADEON_FP_VERT_STRETCH              0x0290
 #define RADEON_FP_V2_SYNC_STRT_WID          0x03c8
@@ -997,6 +1000,7 @@
 #define RADEON_MPP_GP_CONFIG                0x01c8 /* ? */
 #define R300_MC_IND_INDEX                   0x01f8
 #       define R300_MC_IND_ADDR_MASK        0x3f
+#       define R300_MC_IND_WR_EN            (1 << 8)
 #define R300_MC_IND_DATA                    0x01fc
 #define R300_MC_READ_CNTL_AB                0x017c
 #       define R300_MEM_RBS_POSITION_A_MASK 0x03
@@ -3243,9 +3247,9 @@
 #define RADEON_TV_PLL_FINE_CNTL			     0x0020	/* PLL */
 #define RADEON_TV_PLL_CNTL                           0x0021	/* PLL */
 #       define RADEON_TV_M0LO_MASK               0xff
-#       define RADEON_TV_M0HI_MASK               0x3
+#       define RADEON_TV_M0HI_MASK               0x7
 #       define RADEON_TV_M0HI_SHIFT              18
-#       define RADEON_TV_N0LO_MASK               0xff
+#       define RADEON_TV_N0LO_MASK               0x1ff
 #       define RADEON_TV_N0LO_SHIFT              8
 #       define RADEON_TV_N0HI_MASK               0x3
 #       define RADEON_TV_N0HI_SHIFT              21
@@ -3271,4 +3275,680 @@
 #define RADEON_RS480_UNK_e38			0xe38
 #define RADEON_RS480_UNK_e3c			0xe3c
 
+#define RS690_MC_INDEX				0x78
+#	define RS690_MC_INDEX_MASK		0x1ff
+#	define RS690_MC_INDEX_WR_EN		(1 << 9)
+#	define RS690_MC_INDEX_WR_ACK		0x7f
+#define RS690_MC_DATA				0x7c
+
+#define RS690_MC_FB_LOCATION			0x100
+#define RS690_MC_AGP_LOCATION			0x101
+#define RS690_MC_AGP_BASE			0x102
+#define RS690_MC_STATUS                         0x90
+#define RS690_MC_STATUS_IDLE                     (1 << 0)
+
+#define AVIVO_MC_INDEX						0x0070
+#define R520_MC_STATUS 0x00
+#define R520_MC_STATUS_IDLE (1<<1)
+#define RV515_MC_STATUS 0x08
+#define RV515_MC_STATUS_IDLE (1<<4)
+#define AVIVO_MC_DATA						0x0074
+
+#define RV515_MC_FB_LOCATION 0x1
+#define RV515_MC_AGP_LOCATION 0x2
+#define R520_MC_FB_LOCATION 0x4
+#define R520_MC_AGP_LOCATION 0x5
+
+#define AVIVO_HDP_FB_LOCATION 0x134
+
+#define AVIVO_D1VGA_CONTROL					0x0330
+#       define AVIVO_DVGA_CONTROL_MODE_ENABLE (1<<0)
+#       define AVIVO_DVGA_CONTROL_TIMING_SELECT (1<<8)
+#       define AVIVO_DVGA_CONTROL_SYNC_POLARITY_SELECT (1<<9)
+#       define AVIVO_DVGA_CONTROL_OVERSCAN_TIMING_SELECT (1<<10)
+#       define AVIVO_DVGA_CONTROL_OVERSCAN_COLOR_EN (1<<16)
+#       define AVIVO_DVGA_CONTROL_ROTATE (1<<24)
+#define AVIVO_D2VGA_CONTROL					0x0338
+
+#define AVIVO_EXT1_PPLL_REF_DIV_SRC                             0x400
+#define AVIVO_EXT1_PPLL_REF_DIV                                 0x404
+#define AVIVO_EXT1_PPLL_UPDATE_LOCK                             0x408
+#define AVIVO_EXT1_PPLL_UPDATE_CNTL                             0x40c
+
+#define AVIVO_EXT2_PPLL_REF_DIV_SRC                             0x410
+#define AVIVO_EXT2_PPLL_REF_DIV                                 0x414
+#define AVIVO_EXT2_PPLL_UPDATE_LOCK                             0x418
+#define AVIVO_EXT2_PPLL_UPDATE_CNTL                             0x41c
+
+#define AVIVO_EXT1_PPLL_FB_DIV                                   0x430
+#define AVIVO_EXT2_PPLL_FB_DIV                                   0x434
+
+#define AVIVO_EXT1_PPLL_POST_DIV_SRC                                 0x438
+#define AVIVO_EXT1_PPLL_POST_DIV                                     0x43c
+
+#define AVIVO_EXT2_PPLL_POST_DIV_SRC                                 0x440
+#define AVIVO_EXT2_PPLL_POST_DIV                                     0x444
+
+#define AVIVO_EXT1_PPLL_CNTL                                    0x448
+#define AVIVO_EXT2_PPLL_CNTL                                    0x44c
+
+#define AVIVO_P1PLL_CNTL                                        0x450
+#define AVIVO_P2PLL_CNTL                                        0x454
+#define AVIVO_P1PLL_INT_SS_CNTL                                 0x458
+#define AVIVO_P2PLL_INT_SS_CNTL                                 0x45c
+#define AVIVO_P1PLL_TMDSA_CNTL                                  0x460
+#define AVIVO_P2PLL_LVTMA_CNTL                                  0x464
+
+#define AVIVO_PCLK_CRTC1_CNTL                                   0x480
+#define AVIVO_PCLK_CRTC2_CNTL                                   0x484
+
+#define AVIVO_D1CRTC_H_TOTAL					0x6000
+#define AVIVO_D1CRTC_H_BLANK_START_END                          0x6004
+#define AVIVO_D1CRTC_H_SYNC_A                                   0x6008
+#define AVIVO_D1CRTC_H_SYNC_A_CNTL                              0x600c
+#define AVIVO_D1CRTC_H_SYNC_B                                   0x6010
+#define AVIVO_D1CRTC_H_SYNC_B_CNTL                              0x6014
+
+#define AVIVO_D1CRTC_V_TOTAL					0x6020
+#define AVIVO_D1CRTC_V_BLANK_START_END                          0x6024
+#define AVIVO_D1CRTC_V_SYNC_A                                   0x6028
+#define AVIVO_D1CRTC_V_SYNC_A_CNTL                              0x602c
+#define AVIVO_D1CRTC_V_SYNC_B                                   0x6030
+#define AVIVO_D1CRTC_V_SYNC_B_CNTL                              0x6034
+
+#define AVIVO_D1CRTC_CONTROL                                    0x6080
+#       define AVIVO_CRTC_EN                            (1<<0)
+#define AVIVO_D1CRTC_BLANK_CONTROL                              0x6084
+#define AVIVO_D1CRTC_INTERLACE_CONTROL                          0x6088
+#define AVIVO_D1CRTC_INTERLACE_STATUS                           0x608c
+#define AVIVO_D1CRTC_STEREO_CONTROL                             0x60c4
+
+/* master controls */
+#define AVIVO_DC_CRTC_MASTER_EN                                 0x60f8
+#define AVIVO_DC_CRTC_TV_CONTROL                                0x60fc
+
+#define AVIVO_D1GRPH_ENABLE                                     0x6100
+#define AVIVO_D1GRPH_CONTROL                                    0x6104
+#       define AVIVO_D1GRPH_CONTROL_DEPTH_8BPP          (0<<0)
+#       define AVIVO_D1GRPH_CONTROL_DEPTH_16BPP         (1<<0)
+#       define AVIVO_D1GRPH_CONTROL_DEPTH_32BPP         (2<<0)
+#       define AVIVO_D1GRPH_CONTROL_DEPTH_64BPP         (3<<0)
+
+#       define AVIVO_D1GRPH_CONTROL_8BPP_INDEXED        (0<<8)
+
+#       define AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555      (0<<8)
+#       define AVIVO_D1GRPH_CONTROL_16BPP_RGB565        (1<<8)
+#       define AVIVO_D1GRPH_CONTROL_16BPP_ARGB4444      (2<<8)
+#       define AVIVO_D1GRPH_CONTROL_16BPP_AI88          (3<<8)
+#       define AVIVO_D1GRPH_CONTROL_16BPP_MONO16        (4<<8)
+
+#       define AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888      (0<<8)
+#       define AVIVO_D1GRPH_CONTROL_32BPP_ARGB2101010   (1<<8)
+#       define AVIVO_D1GRPH_CONTROL_32BPP_DIGITAL       (2<<8)
+#       define AVIVO_D1GRPH_CONTROL_32BPP_8B_ARGB2101010 (3<<8)
+
+
+#       define AVIVO_D1GRPH_CONTROL_64BPP_ARGB16161616  (0<<8)
+
+#       define AVIVO_D1GRPH_SWAP_RB                     (1<<16)
+#       define AVIVO_D1GRPH_TILED                       (1<<20)
+#       define AVIVO_D1GRPH_MACRO_ADDRESS_MODE          (1<<21)
+
+#define AVIVO_D1GRPH_LUT_SEL                                    0x6108
+#define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS                    0x6110
+#define AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS                  0x6118
+#define AVIVO_D1GRPH_PITCH                                      0x6120
+#define AVIVO_D1GRPH_SURFACE_OFFSET_X                           0x6124
+#define AVIVO_D1GRPH_SURFACE_OFFSET_Y                           0x6128
+#define AVIVO_D1GRPH_X_START                                    0x612c
+#define AVIVO_D1GRPH_Y_START                                    0x6130
+#define AVIVO_D1GRPH_X_END                                      0x6134
+#define AVIVO_D1GRPH_Y_END                                      0x6138
+#define AVIVO_D1GRPH_UPDATE                                     0x6144
+#       define AVIVO_D1GRPH_UPDATE_LOCK                 (1<<16)
+#define AVIVO_D1GRPH_FLIP_CONTROL                               0x6148
+
+#define AVIVO_D1CUR_CONTROL                     0x6400
+#       define AVIVO_D1CURSOR_EN           (1<<0)
+#       define AVIVO_D1CURSOR_MODE_SHIFT  8
+#       define AVIVO_D1CURSOR_MODE_MASK   (0x3<<8)
+#       define AVIVO_D1CURSOR_MODE_24BPP  (0x2)
+#define AVIVO_D1CUR_SURFACE_ADDRESS             0x6408
+#define AVIVO_D1CUR_SIZE                        0x6410
+#define AVIVO_D1CUR_POSITION                    0x6414
+#define AVIVO_D1CUR_HOT_SPOT                    0x6418
+
+#define AVIVO_DC_LUT_RW_SELECT                  0x6480
+#define AVIVO_DC_LUT_RW_MODE                    0x6484
+#define AVIVO_DC_LUT_RW_INDEX                   0x6488
+#define AVIVO_DC_LUT_SEQ_COLOR                  0x648c
+#define AVIVO_DC_LUT_PWL_DATA                   0x6490
+#define AVIVO_DC_LUT_30_COLOR                   0x6494
+#define AVIVO_DC_LUT_READ_PIPE_SELECT           0x6498
+#define AVIVO_DC_LUT_WRITE_EN_MASK              0x649c
+#define AVIVO_DC_LUT_AUTOFILL                   0x64a0
+
+#define AVIVO_DC_LUTA_CONTROL                   0x64c0
+#define AVIVO_DC_LUTA_BLACK_OFFSET_BLUE         0x64c4
+#define AVIVO_DC_LUTA_BLACK_OFFSET_GREEN        0x64c8
+#define AVIVO_DC_LUTA_BLACK_OFFSET_RED          0x64cc
+#define AVIVO_DC_LUTA_WHITE_OFFSET_BLUE         0x64d0
+#define AVIVO_DC_LUTA_WHITE_OFFSET_GREEN        0x64d4
+#define AVIVO_DC_LUTA_WHITE_OFFSET_RED          0x64d8
+
+
+#define AVIVO_D1MODE_DESKTOP_HEIGHT             0x652C
+#define AVIVO_D1MODE_VIEWPORT_START             0x6580
+#define AVIVO_D1MODE_VIEWPORT_SIZE              0x6584
+#define AVIVO_D1MODE_EXT_OVERSCAN_LEFT_RIGHT    0x6588
+#define AVIVO_D1MODE_EXT_OVERSCAN_TOP_BOTTOM    0x658c
+
+#define AVIVO_D1SCL_SCALER_ENABLE               0x6590
+#define AVIVO_D1SCL_SCALER_TAP_CONTROL	 	0x6594
+#define AVIVO_D1SCL_UPDATE                      0x65cc
+#       define AVIVO_D1SCL_UPDATE_LOCK         (1<<16)
+
+/* second crtc */
+#define AVIVO_D2CRTC_H_TOTAL					0x6800
+#define AVIVO_D2CRTC_H_BLANK_START_END                          0x6804
+#define AVIVO_D2CRTC_H_SYNC_A                                   0x6808
+#define AVIVO_D2CRTC_H_SYNC_A_CNTL                              0x680c
+#define AVIVO_D2CRTC_H_SYNC_B                                   0x6810
+#define AVIVO_D2CRTC_H_SYNC_B_CNTL                              0x6814
+
+#define AVIVO_D2CRTC_V_TOTAL					0x6820
+#define AVIVO_D2CRTC_V_BLANK_START_END                          0x6824
+#define AVIVO_D2CRTC_V_SYNC_A                                   0x6828
+#define AVIVO_D2CRTC_V_SYNC_A_CNTL                              0x682c
+#define AVIVO_D2CRTC_V_SYNC_B                                   0x6830
+#define AVIVO_D2CRTC_V_SYNC_B_CNTL                              0x6834
+
+#define AVIVO_D2CRTC_CONTROL                                    0x6880
+#define AVIVO_D2CRTC_BLANK_CONTROL                              0x6884
+#define AVIVO_D2CRTC_INTERLACE_CONTROL                          0x6888
+#define AVIVO_D2CRTC_INTERLACE_STATUS                           0x688c
+#define AVIVO_D2CRTC_STEREO_CONTROL                             0x68c4
+
+#define AVIVO_D2GRPH_ENABLE                                     0x6900
+#define AVIVO_D2GRPH_CONTROL                                    0x6904
+#define AVIVO_D2GRPH_LUT_SEL                                    0x6908
+#define AVIVO_D2GRPH_PRIMARY_SURFACE_ADDRESS                    0x6910
+#define AVIVO_D2GRPH_SECONDARY_SURFACE_ADDRESS                  0x6918
+#define AVIVO_D2GRPH_PITCH                                      0x6920
+#define AVIVO_D2GRPH_SURFACE_OFFSET_X                           0x6924
+#define AVIVO_D2GRPH_SURFACE_OFFSET_Y                           0x6928
+#define AVIVO_D2GRPH_X_START                                    0x692c
+#define AVIVO_D2GRPH_Y_START                                    0x6930
+#define AVIVO_D2GRPH_X_END                                      0x6934
+#define AVIVO_D2GRPH_Y_END                                      0x6938
+#define AVIVO_D2GRPH_UPDATE                                     0x6944
+#define AVIVO_D2GRPH_FLIP_CONTROL                               0x6948
+
+#define AVIVO_D2CUR_CONTROL                     0x6c00
+#define AVIVO_D2CUR_SURFACE_ADDRESS             0x6c08
+#define AVIVO_D2CUR_SIZE                        0x6c10
+#define AVIVO_D2CUR_POSITION                    0x6c14
+
+#define AVIVO_D2MODE_VIEWPORT_START             0x6d80
+#define AVIVO_D2MODE_VIEWPORT_SIZE              0x6d84
+#define AVIVO_D2MODE_EXT_OVERSCAN_LEFT_RIGHT    0x6d88
+#define AVIVO_D2MODE_EXT_OVERSCAN_TOP_BOTTOM    0x6d8c
+
+#define AVIVO_D2SCL_SCALER_ENABLE               0x6d90
+#define AVIVO_D2SCL_SCALER_TAP_CONTROL	 	0x6d94
+
+#define AVIVO_DACA_ENABLE					0x7800
+#	define AVIVO_DAC_ENABLE				(1 << 0)
+#define AVIVO_DACA_SOURCE_SELECT				0x7804
+#       define AVIVO_DAC_SOURCE_CRTC1                   (0 << 0)
+#       define AVIVO_DAC_SOURCE_CRTC2                   (1 << 0)
+#       define AVIVO_DAC_SOURCE_TV                      (2 << 0)
+
+#define AVIVO_DACA_FORCE_OUTPUT_CNTL				0x783c
+# define AVIVO_DACA_FORCE_OUTPUT_CNTL_FORCE_DATA_EN             (1 << 0)
+# define AVIVO_DACA_FORCE_OUTPUT_CNTL_DATA_SEL_SHIFT            (8)
+# define AVIVO_DACA_FORCE_OUTPUT_CNTL_DATA_SEL_BLUE             (1 << 0)
+# define AVIVO_DACA_FORCE_OUTPUT_CNTL_DATA_SEL_GREEN            (1 << 1)
+# define AVIVO_DACA_FORCE_OUTPUT_CNTL_DATA_SEL_RED              (1 << 2)
+# define AVIVO_DACA_FORCE_OUTPUT_CNTL_DATA_ON_BLANKB_ONLY       (1 << 24)
+#define AVIVO_DACA_POWERDOWN					0x7850
+# define AVIVO_DACA_POWERDOWN_POWERDOWN                         (1 << 0)
+# define AVIVO_DACA_POWERDOWN_BLUE                              (1 << 8)
+# define AVIVO_DACA_POWERDOWN_GREEN                             (1 << 16)
+# define AVIVO_DACA_POWERDOWN_RED                               (1 << 24)
+
+#define AVIVO_DACB_ENABLE					0x7a00
+#define AVIVO_DACB_SOURCE_SELECT				0x7a04
+#define AVIVO_DACB_FORCE_OUTPUT_CNTL				0x7a3c
+# define AVIVO_DACB_FORCE_OUTPUT_CNTL_FORCE_DATA_EN             (1 << 0)
+# define AVIVO_DACB_FORCE_OUTPUT_CNTL_DATA_SEL_SHIFT            (8)
+# define AVIVO_DACB_FORCE_OUTPUT_CNTL_DATA_SEL_BLUE             (1 << 0)
+# define AVIVO_DACB_FORCE_OUTPUT_CNTL_DATA_SEL_GREEN            (1 << 1)
+# define AVIVO_DACB_FORCE_OUTPUT_CNTL_DATA_SEL_RED              (1 << 2)
+# define AVIVO_DACB_FORCE_OUTPUT_CNTL_DATA_ON_BLANKB_ONLY       (1 << 24)
+#define AVIVO_DACB_POWERDOWN					0x7a50
+# define AVIVO_DACB_POWERDOWN_POWERDOWN                         (1 << 0)
+# define AVIVO_DACB_POWERDOWN_BLUE                              (1 << 8)
+# define AVIVO_DACB_POWERDOWN_GREEN                             (1 << 16)
+# define AVIVO_DACB_POWERDOWN_RED 
+
+#define AVIVO_TMDSA_CNTL                    0x7880
+#   define AVIVO_TMDSA_CNTL_ENABLE               (1 << 0)
+#   define AVIVO_TMDSA_CNTL_HPD_MASK             (1 << 4)
+#   define AVIVO_TMDSA_CNTL_HPD_SELECT           (1 << 8)
+#   define AVIVO_TMDSA_CNTL_SYNC_PHASE           (1 << 12)
+#   define AVIVO_TMDSA_CNTL_PIXEL_ENCODING       (1 << 16)
+#   define AVIVO_TMDSA_CNTL_DUAL_LINK_ENABLE     (1 << 24)
+#   define AVIVO_TMDSA_CNTL_SWAP                 (1 << 28)
+#define AVIVO_TMDSA_SOURCE_SELECT				0x7884
+/* 78a8 appears to be some kind of (reasonably tolerant) clock?
+ * 78d0 definitely hits the transmitter, definitely clock. */
+/* MYSTERY1 This appears to control dithering? */
+#define AVIVO_TMDSA_BIT_DEPTH_CONTROL		0x7894
+#   define AVIVO_TMDS_BIT_DEPTH_CONTROL_TRUNCATE_EN           (1 << 0)
+#   define AVIVO_TMDS_BIT_DEPTH_CONTROL_TRUNCATE_DEPTH        (1 << 4)
+#   define AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN     (1 << 8)
+#   define AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_DEPTH  (1 << 12)
+#   define AVIVO_TMDS_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_EN    (1 << 16)
+#   define AVIVO_TMDS_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_DEPTH (1 << 20)
+#   define AVIVO_TMDS_BIT_DEPTH_CONTROL_TEMPORAL_LEVEL        (1 << 24)
+#   define AVIVO_TMDS_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_RESET (1 << 26)
+#define AVIVO_TMDSA_DCBALANCER_CONTROL                  0x78d0
+#   define AVIVO_TMDSA_DCBALANCER_CONTROL_EN                  (1 << 0)
+#   define AVIVO_TMDSA_DCBALANCER_CONTROL_TEST_EN             (1 << 8)
+#   define AVIVO_TMDSA_DCBALANCER_CONTROL_TEST_IN_SHIFT       (16)
+#   define AVIVO_TMDSA_DCBALANCER_CONTROL_FORCE               (1 << 24)
+#define AVIVO_TMDSA_DATA_SYNCHRONIZATION                0x78d8
+#   define AVIVO_TMDSA_DATA_SYNCHRONIZATION_DSYNSEL           (1 << 0)
+#   define AVIVO_TMDSA_DATA_SYNCHRONIZATION_PFREQCHG          (1 << 8)
+#define AVIVO_TMDSA_CLOCK_ENABLE            0x7900
+#define AVIVO_TMDSA_TRANSMITTER_ENABLE              0x7904
+#   define AVIVO_TMDSA_TRANSMITTER_ENABLE_TX0_ENABLE          (1 << 0)
+#   define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKC0EN             (1 << 1)
+#   define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD00EN            (1 << 2)
+#   define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD01EN            (1 << 3)
+#   define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD02EN            (1 << 4)
+#   define AVIVO_TMDSA_TRANSMITTER_ENABLE_TX1_ENABLE          (1 << 8)
+#   define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD10EN            (1 << 10)
+#   define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD11EN            (1 << 11)
+#   define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD12EN            (1 << 12)
+#   define AVIVO_TMDSA_TRANSMITTER_ENABLE_TX_ENABLE_HPD_MASK  (1 << 16)
+#   define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKCEN_HPD_MASK     (1 << 17)
+#   define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKDEN_HPD_MASK     (1 << 18)
+
+#define AVIVO_TMDSA_TRANSMITTER_CONTROL				0x7910
+#	define AVIVO_TMDSA_TRANSMITTER_CONTROL_PLL_ENABLE	(1 << 0)
+#	define AVIVO_TMDSA_TRANSMITTER_CONTROL_PLL_RESET  	(1 << 1)
+#	define AVIVO_TMDSA_TRANSMITTER_CONTROL_PLL_HPD_MASK_SHIFT	(2)
+#	define AVIVO_TMDSA_TRANSMITTER_CONTROL_IDSCKSEL	        (1 << 4)
+#       define AVIVO_TMDSA_TRANSMITTER_CONTROL_BGSLEEP          (1 << 5)
+#	define AVIVO_TMDSA_TRANSMITTER_CONTROL_PLL_PWRUP_SEQ_EN	(1 << 6)
+#	define AVIVO_TMDSA_TRANSMITTER_CONTROL_TMCLK	        (1 << 8)
+#	define AVIVO_TMDSA_TRANSMITTER_CONTROL_TMCLK_FROM_PADS	(1 << 13)
+#	define AVIVO_TMDSA_TRANSMITTER_CONTROL_TDCLK	        (1 << 14)
+#	define AVIVO_TMDSA_TRANSMITTER_CONTROL_TDCLK_FROM_PADS	(1 << 15)
+#       define AVIVO_TMDSA_TRANSMITTER_CONTROL_CLK_PATTERN_SHIFT (16)
+#	define AVIVO_TMDSA_TRANSMITTER_CONTROL_BYPASS_PLL	(1 << 28)
+#       define AVIVO_TMDSA_TRANSMITTER_CONTROL_USE_CLK_DATA     (1 << 29)
+#	define AVIVO_TMDSA_TRANSMITTER_CONTROL_INPUT_TEST_CLK_SEL	(1 << 31)
+
+#define AVIVO_LVTMA_CNTL					0x7a80
+#   define AVIVO_LVTMA_CNTL_ENABLE               (1 << 0)
+#   define AVIVO_LVTMA_CNTL_HPD_MASK             (1 << 4)
+#   define AVIVO_LVTMA_CNTL_HPD_SELECT           (1 << 8)
+#   define AVIVO_LVTMA_CNTL_SYNC_PHASE           (1 << 12)
+#   define AVIVO_LVTMA_CNTL_PIXEL_ENCODING       (1 << 16)
+#   define AVIVO_LVTMA_CNTL_DUAL_LINK_ENABLE     (1 << 24)
+#   define AVIVO_LVTMA_CNTL_SWAP                 (1 << 28)
+#define AVIVO_LVTMA_SOURCE_SELECT                               0x7a84
+#define AVIVO_LVTMA_COLOR_FORMAT                                0x7a88
+#define AVIVO_LVTMA_BIT_DEPTH_CONTROL                           0x7a94
+#   define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_EN           (1 << 0)
+#   define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_DEPTH        (1 << 4)
+#   define AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN     (1 << 8)
+#   define AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_DEPTH  (1 << 12)
+#   define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_EN    (1 << 16)
+#   define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_DEPTH (1 << 20)
+#   define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TEMPORAL_LEVEL        (1 << 24)
+#   define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_RESET (1 << 26)
+
+
+
+#define AVIVO_LVTMA_DCBALANCER_CONTROL                  0x7ad0
+#   define AVIVO_LVTMA_DCBALANCER_CONTROL_EN                  (1 << 0)
+#   define AVIVO_LVTMA_DCBALANCER_CONTROL_TEST_EN             (1 << 8)
+#   define AVIVO_LVTMA_DCBALANCER_CONTROL_TEST_IN_SHIFT       (16)
+#   define AVIVO_LVTMA_DCBALANCER_CONTROL_FORCE               (1 << 24)
+
+#define AVIVO_LVTMA_DATA_SYNCHRONIZATION                0x78d8
+#   define AVIVO_LVTMA_DATA_SYNCHRONIZATION_DSYNSEL           (1 << 0)
+#   define AVIVO_LVTMA_DATA_SYNCHRONIZATION_PFREQCHG          (1 << 8)
+#define R500_LVTMA_CLOCK_ENABLE			0x7b00
+#define R600_LVTMA_CLOCK_ENABLE			0x7b04
+
+#define R500_LVTMA_TRANSMITTER_ENABLE              0x7b04
+#define R600_LVTMA_TRANSMITTER_ENABLE              0x7b08
+#   define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKC0EN             (1 << 1)
+#   define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD00EN            (1 << 2)
+#   define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD01EN            (1 << 3)
+#   define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD02EN            (1 << 4)
+#   define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD03EN            (1 << 5)
+#   define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKC1EN             (1 << 9)
+#   define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD10EN            (1 << 10)
+#   define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD11EN            (1 << 11)
+#   define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD12EN            (1 << 12)
+#   define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKCEN_HPD_MASK     (1 << 17)
+#   define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKDEN_HPD_MASK     (1 << 18)
+
+#define R500_LVTMA_TRANSMITTER_CONTROL			        0x7b10
+#define R600_LVTMA_TRANSMITTER_CONTROL			        0x7b14
+#	define AVIVO_LVTMA_TRANSMITTER_CONTROL_PLL_ENABLE	  (1 << 0)
+#	define AVIVO_LVTMA_TRANSMITTER_CONTROL_PLL_RESET  	  (1 << 1)
+#	define AVIVO_LVTMA_TRANSMITTER_CONTROL_PLL_HPD_MASK_SHIFT (2)
+#	define AVIVO_LVTMA_TRANSMITTER_CONTROL_IDSCKSEL	          (1 << 4)
+#       define AVIVO_LVTMA_TRANSMITTER_CONTROL_BGSLEEP            (1 << 5)
+#	define AVIVO_LVTMA_TRANSMITTER_CONTROL_PLL_PWRUP_SEQ_EN	  (1 << 6)
+#	define AVIVO_LVTMA_TRANSMITTER_CONTROL_TMCLK	          (1 << 8)
+#	define AVIVO_LVTMA_TRANSMITTER_CONTROL_TMCLK_FROM_PADS	  (1 << 13)
+#	define AVIVO_LVTMA_TRANSMITTER_CONTROL_TDCLK	          (1 << 14)
+#	define AVIVO_LVTMA_TRANSMITTER_CONTROL_TDCLK_FROM_PADS	  (1 << 15)
+#       define AVIVO_LVTMA_TRANSMITTER_CONTROL_CLK_PATTERN_SHIFT  (16)
+#	define AVIVO_LVTMA_TRANSMITTER_CONTROL_BYPASS_PLL	  (1 << 28)
+#       define AVIVO_LVTMA_TRANSMITTER_CONTROL_USE_CLK_DATA       (1 << 29)
+#	define AVIVO_LVTMA_TRANSMITTER_CONTROL_INPUT_TEST_CLK_SEL (1 << 31)
+
+#define R500_LVTMA_PWRSEQ_CNTL						0x7af0
+#define R600_LVTMA_PWRSEQ_CNTL						0x7af4
+#	define AVIVO_LVTMA_PWRSEQ_EN					    (1 << 0)
+#	define AVIVO_LVTMA_PWRSEQ_PLL_ENABLE_MASK			    (1 << 2)
+#	define AVIVO_LVTMA_PWRSEQ_PLL_RESET_MASK			    (1 << 3)
+#	define AVIVO_LVTMA_PWRSEQ_TARGET_STATE				    (1 << 4)
+#	define AVIVO_LVTMA_SYNCEN					    (1 << 8)
+#	define AVIVO_LVTMA_SYNCEN_OVRD					    (1 << 9)
+#	define AVIVO_LVTMA_SYNCEN_POL					    (1 << 10)
+#	define AVIVO_LVTMA_DIGON					    (1 << 16)
+#	define AVIVO_LVTMA_DIGON_OVRD					    (1 << 17)
+#	define AVIVO_LVTMA_DIGON_POL					    (1 << 18)
+#	define AVIVO_LVTMA_BLON						    (1 << 24)
+#	define AVIVO_LVTMA_BLON_OVRD					    (1 << 25)
+#	define AVIVO_LVTMA_BLON_POL					    (1 << 26)
+
+#define R500_LVTMA_PWRSEQ_STATE                        0x7af4
+#define R600_LVTMA_PWRSEQ_STATE                        0x7af8
+#       define AVIVO_LVTMA_PWRSEQ_STATE_TARGET_STATE_R          (1 << 0)
+#       define AVIVO_LVTMA_PWRSEQ_STATE_DIGON                   (1 << 1)
+#       define AVIVO_LVTMA_PWRSEQ_STATE_SYNCEN                  (1 << 2)
+#       define AVIVO_LVTMA_PWRSEQ_STATE_BLON                    (1 << 3)
+#       define AVIVO_LVTMA_PWRSEQ_STATE_DONE                    (1 << 4)
+#       define AVIVO_LVTMA_PWRSEQ_STATE_STATUS_SHIFT            (8)
+
+#define AVIVO_LVDS_BACKLIGHT_CNTL			0x7af8
+#	define AVIVO_LVDS_BACKLIGHT_CNTL_EN			(1 << 0)
+#	define AVIVO_LVDS_BACKLIGHT_LEVEL_MASK		0x0000ff00
+#	define AVIVO_LVDS_BACKLIGHT_LEVEL_SHIFT		8
+
+#define AVIVO_GPIO_0                        0x7e30
+#define AVIVO_GPIO_1                        0x7e40
+#define AVIVO_GPIO_2                        0x7e50
+#define AVIVO_GPIO_3                        0x7e60
+
+#define AVIVO_DC_GPIO_HPD_Y                 0x7e9c
+
+#define AVIVO_I2C_STATUS					0x7d30
+#	define AVIVO_I2C_STATUS_DONE				(1 << 0)
+#	define AVIVO_I2C_STATUS_NACK				(1 << 1)
+#	define AVIVO_I2C_STATUS_HALT				(1 << 2)
+#	define AVIVO_I2C_STATUS_GO				(1 << 3)
+#	define AVIVO_I2C_STATUS_MASK				0x7
+/* If radeon_mm_i2c is to be believed, this is HALT, NACK, and maybe
+ * DONE? */
+#	define AVIVO_I2C_STATUS_CMD_RESET			0x7
+#	define AVIVO_I2C_STATUS_CMD_WAIT			(1 << 3)
+#define AVIVO_I2C_STOP						0x7d34
+#define AVIVO_I2C_START_CNTL				0x7d38
+#	define AVIVO_I2C_START						(1 << 8)
+#	define AVIVO_I2C_CONNECTOR0					(0 << 16)
+#	define AVIVO_I2C_CONNECTOR1					(1 << 16)
+#define R520_I2C_START (1<<0)
+#define R520_I2C_STOP (1<<1)
+#define R520_I2C_RX (1<<2)
+#define R520_I2C_EN (1<<8)
+#define R520_I2C_DDC1 (0<<16)
+#define R520_I2C_DDC2 (1<<16)
+#define R520_I2C_DDC3 (2<<16)
+#define R520_I2C_DDC_MASK (3<<16)
+#define AVIVO_I2C_CONTROL2					0x7d3c
+#	define AVIVO_I2C_7D3C_SIZE_SHIFT			8
+#	define AVIVO_I2C_7D3C_SIZE_MASK				(0xf << 8)
+#define AVIVO_I2C_CONTROL3						0x7d40
+/* Reading is done 4 bytes at a time: read the bottom 8 bits from
+ * 7d44, four times in a row.
+ * Writing is a little more complex.  First write DATA with
+ * 0xnnnnnnzz, then 0xnnnnnnyy, where nnnnnn is some non-deterministic
+ * magic number, zz is, I think, the slave address, and yy is the byte
+ * you want to write. */
+#define AVIVO_I2C_DATA						0x7d44
+#define R520_I2C_ADDR_COUNT_MASK (0x7)
+#define R520_I2C_DATA_COUNT_SHIFT (8)
+#define R520_I2C_DATA_COUNT_MASK (0xF00)
+#define AVIVO_I2C_CNTL						0x7d50
+#	define AVIVO_I2C_EN							(1 << 0)
+#	define AVIVO_I2C_RESET						(1 << 8)
+
+#define R600_MC_VM_FB_LOCATION                                     0x2180
+#define R600_MC_VM_AGP_TOP                                         0x2184
+#define R600_MC_VM_AGP_BOT                                         0x2188
+#define R600_MC_VM_AGP_BASE                                        0x218c
+#define R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR                        0x2190
+#define R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR                       0x2194
+#define R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR                    0x2198
+
+#define R600_BUS_CNTL                                           0x5420
+#define R600_CONFIG_CNTL                                        0x5424
+#define R600_CONFIG_MEMSIZE                                     0x5428
+#define R600_CONFIG_F0_BASE                                     0x542C
+#define R600_CONFIG_APER_SIZE                                   0x5430
+
+#define R300_GB_TILE_CONFIG				0x4018
+#define R300_GB_SELECT				        0x401c
+#define R300_GB_ENABLE				        0x4008
+#define R300_GB_AA_CONFIG				0x4020
+#define R300_GB_MSPOS0				        0x4010
+#define R300_GB_MSPOS1				        0x4014
+
+#define R300_GA_POLY_MODE				0x4288
+#define R300_GA_ROUND_MODE				0x428c
+#define R300_GA_COLOR_CONTROL			        0x4278
+#define R300_GA_OFFSET				        0x4290
+
+#define R300_VAP_CNTL_STATUS				0x2140
+#define R300_VAP_PVS_STATE_FLUSH_REG		        0x2284
+#define R300_VAP_CNTL				        0x2080
+#define R300_VAP_VTE_CNTL				0x20B0
+#define R300_VAP_PSC_SGN_NORM_CNTL		        0x21DC
+#define R300_VAP_PROG_STREAM_CNTL_0		        0x2150
+#define R300_VAP_PROG_STREAM_CNTL_EXT_0	                0x21e0
+#define R300_VAP_PVS_CODE_CNTL_0			0x22D0
+#define R300_VAP_PVS_CODE_CNTL_1			0x22D8
+#define R300_VAP_PVS_VECTOR_INDX_REG		        0x2200
+#define R300_VAP_PVS_VECTOR_DATA_REG		        0x2204
+#define R300_VAP_PVS_FLOW_CNTL_OPC		        0x22DC
+#define R300_VAP_OUT_VTX_FMT_0			        0x2090
+#define R300_VAP_OUT_VTX_FMT_1			        0x2094
+#define R300_VAP_VTX_SIZE				0x20b4
+#define R300_VAP_GB_VERT_CLIP_ADJ		        0x2220
+#define R300_VAP_GB_VERT_DISC_ADJ		        0x2224
+#define R300_VAP_GB_HORZ_CLIP_ADJ		        0x2228
+#define R300_VAP_GB_HORZ_DISC_ADJ		        0x222c
+#define R300_VAP_CLIP_CNTL				0x221c
+
+#define R300_SU_TEX_WRAP				0x42a0
+#define R300_SU_POLY_OFFSET_ENABLE		        0x42b4
+#define R300_SU_CULL_MODE				0x42b8
+#define R300_SU_DEPTH_SCALE				0x42c0
+#define R300_SU_DEPTH_OFFSET			        0x42c4
+
+#define R300_RS_COUNT				        0x4300
+#define R300_RS_IP_0				        0x4310
+#define R300_RS_INST_COUNT				0x4304
+#define R300_RS_INST_0				        0x4330
+
+#define R300_TX_INVALTAGS				0x4100
+#define R300_TX_FILTER0_0				0x4400
+#       define R300_TX_MAG_FILTER_NEAREST               (1 << 9)
+#       define R300_TX_MIN_FILTER_NEAREST               (1 << 11)
+#       define R300_TX_MAG_FILTER_LINEAR                (2 << 9)
+#       define R300_TX_MIN_FILTER_LINEAR                (2 << 11)
+#define R300_TX_FILTER1_0				0x4440
+#define R300_TX_FORMAT0_0				0x4480
+#       define R300_TXWIDTH_SHIFT                       0
+#       define R300_TXHEIGHT_SHIFT                      11
+#       define R300_NUM_LEVELS_SHIFT                    26
+#       define R300_NUM_LEVELS_MASK                     0x
+#       define R300_TXPROJECTED                         (1 << 30)
+#       define R300_TXPITCH_EN                          (1 << 31)
+#define R300_TX_FORMAT1_0				0x44c0
+#	define R300_TX_FORMAT_X8		    0x0
+#	define R300_TX_FORMAT_X16		    0x1
+#	define R300_TX_FORMAT_Y4X4		    0x2
+#	define R300_TX_FORMAT_Y8X8		    0x3
+#	define R300_TX_FORMAT_Y16X16		    0x4
+#	define R300_TX_FORMAT_Z3Y3X2		    0x5
+#	define R300_TX_FORMAT_Z5Y6X5		    0x6
+#	define R300_TX_FORMAT_Z6Y5X5		    0x7
+#	define R300_TX_FORMAT_Z11Y11X10		    0x8
+#	define R300_TX_FORMAT_Z10Y11X11		    0x9
+#	define R300_TX_FORMAT_W4Z4Y4X4		    0xA
+#	define R300_TX_FORMAT_W1Z5Y5X5		    0xB
+#	define R300_TX_FORMAT_W8Z8Y8X8		    0xC
+#	define R300_TX_FORMAT_W2Z10Y10X10	    0xD
+#	define R300_TX_FORMAT_W16Z16Y16X16	    0xE
+#	define R300_TX_FORMAT_DXT1	    	    0xF
+#	define R300_TX_FORMAT_DXT3	    	    0x10
+#	define R300_TX_FORMAT_DXT5	    	    0x11
+#	define R300_TX_FORMAT_D3DMFT_CxV8U8	    0x12     /* no swizzle */
+#	define R300_TX_FORMAT_A8R8G8B8	    	    0x13     /* no swizzle */
+#	define R300_TX_FORMAT_B8G8_B8G8	    	    0x14     /* no swizzle */
+#	define R300_TX_FORMAT_G8R8_G8B8	    	    0x15     /* no swizzle */
+#	define R300_TX_FORMAT_X24_Y8	    	    0x1e
+#	define R300_TX_FORMAT_X32	    	    0x1e
+	/* Floating point formats */
+	/* Note - hardware supports both 16 and 32 bit floating point */
+#	define R300_TX_FORMAT_FL_I16	    	    0x18
+#	define R300_TX_FORMAT_FL_I16A16	    	    0x19
+#	define R300_TX_FORMAT_FL_R16G16B16A16	    0x1A
+#	define R300_TX_FORMAT_FL_I32	    	    0x1B
+#	define R300_TX_FORMAT_FL_I32A32	    	    0x1C
+#	define R300_TX_FORMAT_FL_R32G32B32A32	    0x1D
+	/* alpha modes, convenience mostly */
+	/* if you have alpha, pick constant appropriate to the
+	   number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */
+# 	define R300_TX_FORMAT_ALPHA_1CH		    0x000
+# 	define R300_TX_FORMAT_ALPHA_2CH		    0x200
+# 	define R300_TX_FORMAT_ALPHA_4CH		    0x600
+# 	define R300_TX_FORMAT_ALPHA_NONE	    0xA00
+	/* Swizzling */
+	/* constants */
+#	define R300_TX_FORMAT_X		0
+#	define R300_TX_FORMAT_Y		1
+#	define R300_TX_FORMAT_Z		2
+#	define R300_TX_FORMAT_W		3
+#	define R300_TX_FORMAT_ZERO	4
+#	define R300_TX_FORMAT_ONE	5
+	/* 2.0*Z, everything above 1.0 is set to 0.0 */
+#	define R300_TX_FORMAT_CUT_Z	6
+	/* 2.0*W, everything above 1.0 is set to 0.0 */
+#	define R300_TX_FORMAT_CUT_W	7
+
+#	define R300_TX_FORMAT_B_SHIFT	18
+#	define R300_TX_FORMAT_G_SHIFT	15
+#	define R300_TX_FORMAT_R_SHIFT	12
+#	define R300_TX_FORMAT_A_SHIFT	9
+
+	/* Convenience macro to take care of layout and swizzling */
+#	define R300_EASY_TX_FORMAT(B, G, R, A, FMT)	(		\
+		((R300_TX_FORMAT_##B)<<R300_TX_FORMAT_B_SHIFT)		\
+		| ((R300_TX_FORMAT_##G)<<R300_TX_FORMAT_G_SHIFT)	\
+		| ((R300_TX_FORMAT_##R)<<R300_TX_FORMAT_R_SHIFT)	\
+		| ((R300_TX_FORMAT_##A)<<R300_TX_FORMAT_A_SHIFT)	\
+		| (R300_TX_FORMAT_##FMT)				\
+		)
+
+#define R300_TX_FORMAT2_0				0x4500
+#define R300_TX_OFFSET_0				0x4540
+#       define R300_ENDIAN_SWAP_16_BIT                  (1 << 0)
+#       define R300_ENDIAN_SWAP_32_BIT                  (2 << 0)
+#       define R300_ENDIAN_SWAP_HALF_DWORD              (3 << 0)
+#       define R300_MACRO_TILE                          (1 << 2);
+
+#define R300_TX_ENABLE				        0x4104
+#       define R300_TEX_0_ENABLE                        (1 << 0)
+#       define R300_TEX_1_ENABLE                        (1 << 1)
+
+#define R300_US_W_FMT				        0x46b4
+#define R300_US_OUT_FMT_1				0x46a8
+#define R300_US_OUT_FMT_2				0x46ac
+#define R300_US_OUT_FMT_3				0x46b0
+#define R300_US_OUT_FMT_0				0x46a4
+#define R300_US_CONFIG				        0x4600
+#define R300_US_PIXSIZE				        0x4604
+#define R300_US_CODE_OFFSET				0x4608
+#define R300_US_CODE_ADDR_0				0x4610
+#define R300_US_CODE_ADDR_1				0x4614
+#define R300_US_CODE_ADDR_2				0x4618
+#define R300_US_CODE_ADDR_3				0x461c
+#define R300_US_TEX_INST_0				0x4620
+#define R300_US_ALU_RGB_ADDR_0			        0x46c0
+#define R300_US_ALU_RGB_INST_0			        0x48c0
+#define R300_US_ALU_ALPHA_ADDR_0		        0x47c0
+#define R300_US_ALU_ALPHA_INST_0		        0x49c0
+
+#define R300_FG_DEPTH_SRC				0x4bd8
+#define R300_FG_FOG_BLEND				0x4bc0
+#define R300_FG_ALPHA_FUNC				0x4bd4
+
+#define R300_RB3D_DSTCACHE_CTLSTAT		        0x4e4c
+#define R300_RB3D_ZCACHE_CTLSTAT			0x4f18
+#define R300_WAIT_UNTIL				        0x1720
+#define R300_RB3D_ZSTENCILCNTL			        0x4f04
+#define R300_RB3D_ZCACHE_CTLSTAT		        0x4f18
+#define R300_RB3D_BW_CNTL				0x4f1c
+#define R300_RB3D_ZCNTL				        0x4f00
+#define R300_RB3D_ZTOP				        0x4f14
+#define R300_RB3D_ROPCNTL				0x4e18
+#define R300_RB3D_BLENDCNTL				0x4e04
+#define R300_RB3D_ABLENDCNTL			        0x4e08
+#define R300_RB3D_DSTCACHE_CTLSTAT		        0x4e4c
+#define R300_RB3D_COLOROFFSET0			        0x4e28
+#define R300_RB3D_COLORPITCH0			        0x4e38
+#       define R300_COLORTILE                           (1 << 16)
+#       define R300_COLORENDIAN_WORD                    (1 << 19)
+#       define R300_COLORENDIAN_DWORD                   (2 << 19)
+#       define R300_COLORENDIAN_HALF_DWORD              (3 << 19)
+#       define R300_COLORFORMAT_ARGB1555                (3 << 21)
+#       define R300_COLORFORMAT_RGB565                  (4 << 21)
+#       define R300_COLORFORMAT_ARGB8888                (6 << 21)
+#       define R300_COLORFORMAT_ARGB32323232            (7 << 21)
+#       define R300_COLORFORMAT_I8                      (9 << 21)
+#       define R300_COLORFORMAT_ARGB16161616            (10 << 21)
+#       define R300_COLORFORMAT_VYUY                    (11 << 21)
+#       define R300_COLORFORMAT_YVYU                    (12 << 21)
+#       define R300_COLORFORMAT_UV88                    (13 << 21)
+#       define R300_COLORFORMAT_ARGB4444                (15 << 21)
+
+#define R300_RB3D_AARESOLVE_CTL			        0x4e88
+#define R300_RB3D_COLOR_CHANNEL_MASK	                0x4e0c
+#define R300_RB3D_COLOR_CLEAR_VALUE                     0x4e14
+#define R300_RB3D_DSTCACHE_CTLSTAT		        0x4e4c
+#define R300_RB3D_CCTL				        0x4e00
+#define R300_RB3D_DITHER_CTL			        0x4e50
+
+#define R300_SC_EDGERULE				0x43a8
+#define R300_SC_SCISSOR0				0x43e0
+#define R300_SC_SCISSOR1				0x43e4
+#define R300_SC_CLIP_0_A				0x43b0
+#define R300_SC_CLIP_0_B				0x43b4
+#define R300_SC_CLIP_RULE				0x43d0
+#define R300_SC_SCREENDOOR				0x43e8
+
 #endif
diff --git a/src/radeon_render.c b/src/radeon_render.c
index 490dec1..a80d136 100644
--- a/src/radeon_render.c
+++ b/src/radeon_render.c
@@ -317,7 +317,7 @@ static Bool RADEONSetupRenderByteswap(ScrnInfoPtr pScrn, int tex_bytepp)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    CARD32 swapper = info->ModeReg.surface_cntl;
+    CARD32 swapper = info->ModeReg->surface_cntl;
 
     swapper &= ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP |
 		 RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP);
@@ -345,7 +345,7 @@ static void RADEONRestoreByteswap(RADEONInfoPtr info)
 {
     unsigned char *RADEONMMIO = info->MMIO;
 
-    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);
+    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl);
 }
 #endif	/* X_BYTE_ORDER == X_BIG_ENDIAN */
 
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 2a8873c..d5d1e9e 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -180,6 +180,401 @@ static long SLOPE_value[5] = { 1, 2, 2, 4, 8 };
 static long SLOPE_limit[5] = { 6, 5, 4, 3, 2 };
 
 
+static void
+RADEONWaitPLLLock(ScrnInfoPtr pScrn, unsigned nTests,
+		  unsigned nWaitLoops, unsigned cntThreshold)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 savePLLTest;
+    unsigned i;
+    unsigned j;
+
+    OUTREG(RADEON_TEST_DEBUG_MUX, (INREG(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100);
+
+    savePLLTest = INPLL(pScrn, RADEON_PLL_TEST_CNTL);
+
+    OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest & ~RADEON_PLL_MASK_READ_B);
+
+    /* XXX: these should probably be OUTPLL to avoid various PLL errata */
+
+    OUTREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL);
+
+    for (i = 0; i < nTests; i++) {
+	OUTREG8(RADEON_CLOCK_CNTL_DATA + 3, 0);
+      
+	for (j = 0; j < nWaitLoops; j++)
+	    if (INREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cntThreshold)
+		break;
+    }
+
+    OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest);
+
+    OUTREG(RADEON_TEST_DEBUG_MUX, INREG(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff);
+}
+
+/* Write to TV FIFO RAM */
+static void
+RADEONWriteTVFIFO(ScrnInfoPtr pScrn, CARD16 addr,
+		  CARD32 value)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 tmp;
+    int i = 0;
+
+    OUTREG(RADEON_TV_HOST_WRITE_DATA, value);
+
+    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr);
+    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT);
+
+    do {
+	tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
+	if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0)
+	    break;
+	i++;
+    }
+    while (i < 10000);
+    /*while ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0);*/
+
+    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
+}
+
+/* Read from TV FIFO RAM */
+static CARD32
+RADEONReadTVFIFO(ScrnInfoPtr pScrn, CARD16 addr)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 tmp;
+    int i = 0;
+  
+    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr);
+    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD);
+
+    do {
+	tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
+	if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0)
+	    break;
+	i++;
+    }
+    while (i < 10000);
+    /*while ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0);*/
+
+    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
+
+    return INREG(RADEON_TV_HOST_READ_DATA);
+}
+
+/* Get FIFO addresses of horizontal & vertical code timing tables from
+ * settings of uv_adr register. 
+ */
+static CARD16
+RADEONGetHTimingTablesAddr(CARD32 tv_uv_adr)
+{
+    CARD16 hTable;
+
+    switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) {
+    case 0:
+	hTable = RADEON_TV_MAX_FIFO_ADDR_INTERNAL;
+	break;
+    case 1:
+	hTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2;
+	break;
+    case 2:
+	hTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2;
+	break;
+    default:
+	/* Of course, this should never happen */
+	hTable = 0;
+	break;
+    }
+    return hTable;
+}
+
+static CARD16
+RADEONGetVTimingTablesAddr(CARD32 tv_uv_adr)
+{
+    CARD16 vTable;
+
+    switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) {
+    case 0:
+	vTable = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1;
+	break;
+    case 1:
+	vTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1;
+	break;
+    case 2:
+	vTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1;
+	break;
+    default:
+	/* Of course, this should never happen */
+	vTable = 0;
+	break;
+    }
+    return vTable;
+}
+
+/* Restore horizontal/vertical timing code tables */
+static void
+RADEONRestoreTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD16 hTable;
+    CARD16 vTable;
+    CARD32 tmp;
+    unsigned i;
+
+    OUTREG(RADEON_TV_UV_ADR, restore->tv_uv_adr);
+    hTable = RADEONGetHTimingTablesAddr(restore->tv_uv_adr);
+    vTable = RADEONGetVTimingTablesAddr(restore->tv_uv_adr);
+
+    for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, hTable--) {
+	tmp = ((CARD32)restore->h_code_timing[ i ] << 14) | ((CARD32)restore->h_code_timing[ i + 1 ]);
+	RADEONWriteTVFIFO(pScrn, hTable, tmp);
+	if (restore->h_code_timing[ i ] == 0 || restore->h_code_timing[ i + 1 ] == 0)
+	    break;
+    }
+
+    for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, vTable++) {
+	tmp = ((CARD32)restore->v_code_timing[ i + 1 ] << 14) | ((CARD32)restore->v_code_timing[ i ]);
+	RADEONWriteTVFIFO(pScrn, vTable, tmp);
+	if (restore->v_code_timing[ i ] == 0 || restore->v_code_timing[ i + 1 ] == 0)
+	    break;
+    }
+}
+
+/* restore TV PLLs */
+static void
+RADEONRestoreTVPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+
+    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL);
+    OUTPLL(pScrn, RADEON_TV_PLL_CNTL, restore->tv_pll_cntl);
+    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET);
+
+    RADEONWaitPLLLock(pScrn, 200, 800, 135);
+  
+    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET);
+
+    RADEONWaitPLLLock(pScrn, 300, 160, 27);
+    RADEONWaitPLLLock(pScrn, 200, 800, 135);
+  
+    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~0xf);
+    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL);
+  
+    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK);
+    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP);
+}
+
+/* Restore TV horizontal/vertical settings */
+static void
+RADEONRestoreTVHVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    OUTREG(RADEON_TV_RGB_CNTL, restore->tv_rgb_cntl);
+
+    OUTREG(RADEON_TV_HTOTAL, restore->tv_htotal);
+    OUTREG(RADEON_TV_HDISP, restore->tv_hdisp);
+    OUTREG(RADEON_TV_HSTART, restore->tv_hstart);
+
+    OUTREG(RADEON_TV_VTOTAL, restore->tv_vtotal);
+    OUTREG(RADEON_TV_VDISP, restore->tv_vdisp);
+
+    OUTREG(RADEON_TV_FTOTAL, restore->tv_ftotal);
+
+    OUTREG(RADEON_TV_VSCALER_CNTL1, restore->tv_vscaler_cntl1);
+    OUTREG(RADEON_TV_VSCALER_CNTL2, restore->tv_vscaler_cntl2);
+
+    OUTREG(RADEON_TV_Y_FALL_CNTL, restore->tv_y_fall_cntl);
+    OUTREG(RADEON_TV_Y_RISE_CNTL, restore->tv_y_rise_cntl);
+    OUTREG(RADEON_TV_Y_SAW_TOOTH_CNTL, restore->tv_y_saw_tooth_cntl);
+}
+
+/* restore TV RESTART registers */
+static void
+RADEONRestoreTVRestarts(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    OUTREG(RADEON_TV_FRESTART, restore->tv_frestart);
+    OUTREG(RADEON_TV_HRESTART, restore->tv_hrestart);
+    OUTREG(RADEON_TV_VRESTART, restore->tv_vrestart);
+}
+
+/* restore tv standard & output muxes */
+static void
+RADEONRestoreTVOutputStd(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    OUTREG(RADEON_TV_SYNC_CNTL, restore->tv_sync_cntl);
+  
+    OUTREG(RADEON_TV_TIMING_CNTL, restore->tv_timing_cntl);
+
+    OUTREG(RADEON_TV_MODULATOR_CNTL1, restore->tv_modulator_cntl1);
+    OUTREG(RADEON_TV_MODULATOR_CNTL2, restore->tv_modulator_cntl2);
+ 
+    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, restore->tv_pre_dac_mux_cntl);
+
+    OUTREG(RADEON_TV_CRC_CNTL, restore->tv_crc_cntl);
+}
+
+/* Restore TV out regs */
+void
+RADEONRestoreTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    ErrorF("Entering Restore TV\n");
+
+    OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
+				   | RADEON_TV_ASYNC_RST
+				   | RADEON_CRT_ASYNC_RST
+				   | RADEON_TV_FIFO_ASYNC_RST));
+
+    /* Temporarily turn the TV DAC off */
+    OUTREG(RADEON_TV_DAC_CNTL, ((restore->tv_dac_cntl & ~RADEON_TV_DAC_NBLANK)
+				| RADEON_TV_DAC_BGSLEEP
+				| RADEON_TV_DAC_RDACPD
+				| RADEON_TV_DAC_GDACPD
+				| RADEON_TV_DAC_BDACPD));
+
+    ErrorF("Restore TV PLL\n");
+    RADEONRestoreTVPLLRegisters(pScrn, restore);
+
+    ErrorF("Restore TVHV\n");
+    RADEONRestoreTVHVRegisters(pScrn, restore);
+
+    OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
+				   | RADEON_TV_ASYNC_RST
+				   | RADEON_CRT_ASYNC_RST));
+
+    ErrorF("Restore TV Restarts\n");
+    RADEONRestoreTVRestarts(pScrn, restore);
+  
+    ErrorF("Restore Timing Tables\n");
+    RADEONRestoreTVTimingTables(pScrn, restore);
+  
+
+    OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
+				   | RADEON_TV_ASYNC_RST));
+
+    ErrorF("Restore TV standard\n");
+    RADEONRestoreTVOutputStd(pScrn, restore);
+
+    OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl);
+
+    OUTREG(RADEON_TV_GAIN_LIMIT_SETTINGS, restore->tv_gain_limit_settings);
+    OUTREG(RADEON_TV_LINEAR_GAIN_SETTINGS, restore->tv_linear_gain_settings);
+
+    OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
+
+    ErrorF("Leaving Restore TV\n");
+}
+
+/* Save horizontal/vertical timing code tables */
+static void
+RADEONSaveTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD16 hTable;
+    CARD16 vTable;
+    CARD32 tmp;
+    unsigned i;
+
+    save->tv_uv_adr = INREG(RADEON_TV_UV_ADR);
+    hTable = RADEONGetHTimingTablesAddr(save->tv_uv_adr);
+    vTable = RADEONGetVTimingTablesAddr(save->tv_uv_adr);
+
+    /*
+     * Reset FIFO arbiter in order to be able to access FIFO RAM
+     */
+
+    OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
+				   | RADEON_CRT_ASYNC_RST
+				   | RADEON_RESTART_PHASE_FIX
+				   | RADEON_CRT_FIFO_CE_EN
+				   | RADEON_TV_FIFO_CE_EN
+				   | RADEON_TV_ON));
+
+    /*OUTREG(RADEON_TV_MASTER_CNTL, save->tv_master_cntl | RADEON_TV_ON);*/
+
+    ErrorF("saveTimingTables: reading timing tables\n");
+
+    for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2) {
+	tmp = RADEONReadTVFIFO(pScrn, hTable--);
+	save->h_code_timing[ i     ] = (CARD16)((tmp >> 14) & 0x3fff);
+	save->h_code_timing[ i + 1 ] = (CARD16)(tmp & 0x3fff);
+
+	if (save->h_code_timing[ i ] == 0 || save->h_code_timing[ i + 1 ] == 0)
+	    break;
+    }
+
+    for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2) {
+	tmp = RADEONReadTVFIFO(pScrn, vTable++);
+	save->v_code_timing[ i     ] = (CARD16)(tmp & 0x3fff);
+	save->v_code_timing[ i + 1 ] = (CARD16)((tmp >> 14) & 0x3fff);
+
+	if (save->v_code_timing[ i ] == 0 || save->v_code_timing[ i + 1 ] == 0)
+	    break;
+    }
+}
+
+/* read TV regs */
+void
+RADEONSaveTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    ErrorF("Entering TV Save\n");
+
+    save->tv_crc_cntl = INREG(RADEON_TV_CRC_CNTL);
+    save->tv_frestart = INREG(RADEON_TV_FRESTART);
+    save->tv_hrestart = INREG(RADEON_TV_HRESTART);
+    save->tv_vrestart = INREG(RADEON_TV_VRESTART);
+    save->tv_gain_limit_settings = INREG(RADEON_TV_GAIN_LIMIT_SETTINGS);
+    save->tv_hdisp = INREG(RADEON_TV_HDISP);
+    save->tv_hstart = INREG(RADEON_TV_HSTART);
+    save->tv_htotal = INREG(RADEON_TV_HTOTAL);
+    save->tv_linear_gain_settings = INREG(RADEON_TV_LINEAR_GAIN_SETTINGS);
+    save->tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL);
+    save->tv_rgb_cntl = INREG(RADEON_TV_RGB_CNTL);
+    save->tv_modulator_cntl1 = INREG(RADEON_TV_MODULATOR_CNTL1);
+    save->tv_modulator_cntl2 = INREG(RADEON_TV_MODULATOR_CNTL2);
+    save->tv_pre_dac_mux_cntl = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
+    save->tv_sync_cntl = INREG(RADEON_TV_SYNC_CNTL);
+    save->tv_timing_cntl = INREG(RADEON_TV_TIMING_CNTL);
+    save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+    save->tv_upsamp_and_gain_cntl = INREG(RADEON_TV_UPSAMP_AND_GAIN_CNTL);
+    save->tv_vdisp = INREG(RADEON_TV_VDISP);
+    save->tv_ftotal = INREG(RADEON_TV_FTOTAL);
+    save->tv_vscaler_cntl1 = INREG(RADEON_TV_VSCALER_CNTL1);
+    save->tv_vscaler_cntl2 = INREG(RADEON_TV_VSCALER_CNTL2);
+    save->tv_vtotal = INREG(RADEON_TV_VTOTAL);
+    save->tv_y_fall_cntl = INREG(RADEON_TV_Y_FALL_CNTL);
+    save->tv_y_rise_cntl = INREG(RADEON_TV_Y_RISE_CNTL);
+    save->tv_y_saw_tooth_cntl = INREG(RADEON_TV_Y_SAW_TOOTH_CNTL);
+
+    save->tv_pll_cntl = INPLL(pScrn, RADEON_TV_PLL_CNTL);
+    save->tv_pll_cntl1 = INPLL(pScrn, RADEON_TV_PLL_CNTL1);
+
+    ErrorF("Save TV timing tables\n");
+
+    RADEONSaveTVTimingTables(pScrn, save);
+
+    ErrorF("TV Save done\n");
+}
+
+
 /* Compute F,V,H restarts from default restart position and hPos & vPos
  * Return TRUE when code timing table was changed
  */
@@ -224,6 +619,8 @@ static Bool RADEONInitTVRestarts(xf86OutputPtr output, RADEONSavePtr save,
     if (radeon_output->tvStd == TV_STD_NTSC ||
 	radeon_output->tvStd == TV_STD_NTSC_J ||
 	radeon_output->tvStd == TV_STD_PAL_M) {
+	/* improve image centering */
+	hOffset -= 50;
 	p1 = hor_timing_NTSC[ H_TABLE_POS1 ];
 	p2 = hor_timing_NTSC[ H_TABLE_POS2 ];
     } else {
@@ -444,9 +841,15 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
     tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000;
     save->tv_timing_cntl = tmp;
 
-    save->tv_dac_cntl = (RADEON_TV_DAC_NBLANK |
-			 RADEON_TV_DAC_NHOLD |
-			 radeon_output->tv_dac_adj /*(8 << 16) | (6 << 20)*/);
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+        radeon_output->tvStd == TV_STD_NTSC_J ||
+        radeon_output->tvStd == TV_STD_PAL_M ||
+        radeon_output->tvStd == TV_STD_PAL_60)
+	save->tv_dac_cntl = radeon_output->ntsc_tvdac_adj;
+    else
+	save->tv_dac_cntl = radeon_output->pal_tvdac_adj;
+
+    save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
 
     if (radeon_output->tvStd == TV_STD_NTSC ||
 	radeon_output->tvStd == TV_STD_NTSC_J)
@@ -474,13 +877,13 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
 	save->tv_pll_cntl = (NTSC_TV_PLL_M & RADEON_TV_M0LO_MASK) |
 	    (((NTSC_TV_PLL_M >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) |
 	    ((NTSC_TV_PLL_N & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) |
-	    (((NTSC_TV_PLL_N >> 8) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) |
+	    (((NTSC_TV_PLL_N >> 9) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) |
 	    ((NTSC_TV_PLL_P & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT);
     else
 	save->tv_pll_cntl = (PAL_TV_PLL_M & RADEON_TV_M0LO_MASK) |
 	    (((PAL_TV_PLL_M >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) |
 	    ((PAL_TV_PLL_N & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) |
-	    (((PAL_TV_PLL_N >> 8) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) |
+	    (((PAL_TV_PLL_N >> 9) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) |
 	    ((PAL_TV_PLL_P & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT);
 
     save->tv_pll_cntl1 =  (((4 & RADEON_TVPCP_MASK)<< RADEON_TVPCP_SHIFT) |
@@ -540,7 +943,7 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
     save->dac_cntl &= ~RADEON_DAC_TVO_EN;
 
     if (IS_R300_VARIANT)
-        save->gpiopad_a = info->SavedReg.gpiopad_a & ~1;
+        save->gpiopad_a = info->SavedReg->gpiopad_a & ~1;
 
     if (IsPrimary) {
 	save->disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
@@ -571,7 +974,7 @@ void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode)
     RADEONInfoPtr  info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     Bool reloadTable;
-    RADEONSavePtr restore = &info->ModeReg;
+    RADEONSavePtr restore = info->ModeReg;
 
     reloadTable = RADEONInitTVRestarts(output, restore, mode);
 
diff --git a/src/radeon_tv.h b/src/radeon_tv.h
index 5c8c8c9..c4b7838 100644
--- a/src/radeon_tv.h
+++ b/src/radeon_tv.h
@@ -3,11 +3,6 @@
  * Federico Ulivi <fulivi@lycos.com>
  */
 
-/*
- * Maximum length of horizontal/vertical code timing tables for state storage
- */
-#define MAX_H_CODE_TIMING_LEN 32
-#define MAX_V_CODE_TIMING_LEN 32
 
 /*
  * Limits of h/v positions (hPos & vPos)
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 2b5764f..92b4a61 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -1456,7 +1456,7 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
      * 0 for PIXCLK < 175Mhz, and 1 (divide by 2)
      * for higher clocks, sure makes life nicer
      */
-    dot_clock = info->ModeReg.dot_clock_freq;
+    dot_clock = info->ModeReg->dot_clock_freq;
 
     if (dot_clock < 17500)
         info->ecp_div = 0;
@@ -1505,8 +1505,6 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
 		xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre detect module\n");
 		goto skip_theatre;
     }
-	xf86LoaderReqSymbols(TheatreDetectSymbolsList, NULL);
-
 	RADEONSetupTheatre(pScrn, pPriv);
 
 	/*
@@ -1546,7 +1544,6 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
 				goto skip_theatre;
 			}
 		}
-		xf86LoaderReqSymbols(TheatreSymbolsList, NULL);
 	}
     
 	if(pPriv->theatre!=NULL)
@@ -2182,7 +2179,7 @@ RADEONCopyData(
     {
 #if X_BYTE_ORDER == X_BIG_ENDIAN
 	unsigned char *RADEONMMIO = info->MMIO;
-	unsigned int swapper = info->ModeReg.surface_cntl &
+	unsigned int swapper = info->ModeReg->surface_cntl &
 		~(RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP |
 		  RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP);
 
@@ -2208,7 +2205,7 @@ RADEONCopyData(
 
 #if X_BYTE_ORDER == X_BIG_ENDIAN
 	/* restore byte swapping */
-	OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);
+	OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl);
 #endif
     }
 }
@@ -2264,7 +2261,7 @@ RADEONCopyRGB24Data(
     {
 #if X_BYTE_ORDER == X_BIG_ENDIAN
 	unsigned char *RADEONMMIO = info->MMIO;
-	OUTREG(RADEON_SURFACE_CNTL, (info->ModeReg.surface_cntl
+	OUTREG(RADEON_SURFACE_CNTL, (info->ModeReg->surface_cntl
 				   | RADEON_NONSURF_AP0_SWP_32BPP)
 				  & ~RADEON_NONSURF_AP0_SWP_16BPP);
 #endif
@@ -2280,7 +2277,7 @@ RADEONCopyRGB24Data(
 
 #if X_BYTE_ORDER == X_BIG_ENDIAN
 	/* restore byte swapping */
-	OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);
+	OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl);
 #endif
     }
 }
@@ -2359,7 +2356,7 @@ RADEONCopyMungedData(
 
 #if X_BYTE_ORDER == X_BIG_ENDIAN
 	unsigned char *RADEONMMIO = info->MMIO;
-	OUTREG(RADEON_SURFACE_CNTL, (info->ModeReg.surface_cntl
+	OUTREG(RADEON_SURFACE_CNTL, (info->ModeReg->surface_cntl
 				   | RADEON_NONSURF_AP0_SWP_32BPP)
 				  & ~RADEON_NONSURF_AP0_SWP_16BPP);
 #endif
@@ -2397,7 +2394,7 @@ RADEONCopyMungedData(
 	}
 #if X_BYTE_ORDER == X_BIG_ENDIAN
 	/* restore byte swapping */
-	OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);
+	OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl);
 #endif
     }
 }
@@ -2578,9 +2575,9 @@ RADEONDisplayVideo(
 
     /* Figure out which head we are on for dot clock */
     if (radeon_crtc->crtc_id == 1)
-        dot_clock = info->ModeReg.dot_clock_freq_2;
+        dot_clock = info->ModeReg->dot_clock_freq_2;
     else
-        dot_clock = info->ModeReg.dot_clock_freq;
+        dot_clock = info->ModeReg->dot_clock_freq;
 
     if (dot_clock < 17500)
         ecp_div = 0;
@@ -2736,7 +2733,8 @@ RADEONDisplayVideo(
     }
     else {
 	left = (left >> 16) & 7;
-	leftuv = left >> 1;
+	if (!is_rgb)
+	    leftuv = left >> 1;
     }
 
     RADEONWaitForFifo(pScrn, 2);
@@ -2745,7 +2743,7 @@ RADEONDisplayVideo(
     while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_LOCK_READBACK));
 
     RADEONWaitForFifo(pScrn, 10);
-    OUTREG(RADEON_OV0_H_INC, h_inc | ((h_inc_uv >> 1) << 16));
+    OUTREG(RADEON_OV0_H_INC, h_inc | ((is_rgb? h_inc_uv: (h_inc_uv >> 1)) << 16));
     OUTREG(RADEON_OV0_STEP_BY, step_by_y | (step_by_uv << 8) |
 	predownscale << 4 | predownscale << 12);
 
@@ -2810,7 +2808,8 @@ RADEONDisplayVideo(
     OUTREG(RADEON_OV0_VID_BUF_PITCH0_VALUE, pitch);
     OUTREG(RADEON_OV0_VID_BUF_PITCH1_VALUE, is_planar ? pitch >> 1 : pitch);
     OUTREG(RADEON_OV0_P1_X_START_END, (src_w + left - 1) | (left << 16));
-    src_w >>= 1;
+    if (!is_rgb)
+	src_w >>= 1;
     OUTREG(RADEON_OV0_P2_X_START_END, (src_w + leftuv - 1) | (leftuv << 16));
     OUTREG(RADEON_OV0_P3_X_START_END, (src_w + leftuv - 1) | (leftuv << 16));
     OUTREG(RADEON_OV0_VID_BUF0_BASE_ADRS, offset1);
diff --git a/src/theatre.h b/src/theatre.h
index 3c1fd4b..958b443 100644
--- a/src/theatre.h
+++ b/src/theatre.h
@@ -57,25 +57,6 @@ void ResetTheatreRegsForTVout(TheatrePtr t);
 void ResetTheatreRegsForNoTVout(TheatrePtr t);
 
 
-#define TheatreSymbolsList  \
-		"InitTheatre" \
-		"RT_SetTint", \
-		"RT_SetSaturation", \
-		"RT_SetBrightness", \
-		"RT_SetSharpness", \
-		"RT_SetContrast", \
-		"RT_SetInterlace", \
-		"RT_SetStandard", \
-		"RT_SetCombFilter", \
-		"RT_SetOutputVideoSize", \
-		"RT_SetConnector", \
-		"ResetTheatreRegsForNoTVout", \
-		"ResetTheatreRegsForTVout", \
-		"DumpRageTheatreRegs", \
-		"ShutdownTheatre"
-
-#ifdef XFree86LOADER
-
 #define xf86_InitTheatre           ((void (*)(TheatrePtr t))LoaderSymbol("InitTheatre"))
 
 #define xf86_RT_SetTint            ((void (*)(TheatrePtr, int))LoaderSymbol("RT_SetTint"))
@@ -94,24 +75,5 @@ void ResetTheatreRegsForNoTVout(TheatrePtr t);
 #define xf86_ResetTheatreRegsForTVout       ((void (*)(TheatrePtr))LoaderSymbol("ResetTheatreRegsForTVout"))
 #define xf86_ResetTheatreRegsForNoTVout       ((void (*)(TheatrePtr))LoaderSymbol("ResetTheatreRegsForNoTVout"))
 #define xf86_RT_GetSignalStatus       ((void (*)(TheatrePtr))LoaderSymbol("xf86_RT_GetSignalStatus"))
-#else
-
-#define xf86_InitTheatre               InitTheatre
-
-#define xf86_RT_SetTint                RT_SetTint
-#define xf86_RT_SetSaturation          RT_SetSaturation
-#define xf86_RT_SetBrightness          RT_SetBrightness
-#define xf86_RT_SetSharpness           RT_SetSharpness
-#define xf86_RT_SetContrast            RT_SetContrast
-#define xf86_RT_SetInterlace           RT_SetInterlace
-#define xf86_RT_SetStandard            RT_SetStandard
-#define xf86_RT_SetOutputVideoSize     RT_SetOutputVideoSize
-#define xf86_RT_SetConnector           RT_SetConnector
-
-#define xf86_RageTheatreDebugGain      RageTheatreDebugGain
-#define xf86_ShutdownTheatre           ShutdownTheatre
-#define xf86_DumpRageTheatreRegs       DumpRageTheatreRegs 
-#define xf86_ResetTheatreRegsForNoTVout ResetTheatreRegsForNoTVout
-#endif		
 
 #endif
diff --git a/src/theatre_detect.h b/src/theatre_detect.h
index b414308..5fed160 100644
--- a/src/theatre_detect.h
+++ b/src/theatre_detect.h
@@ -41,17 +41,6 @@
 TheatrePtr DetectTheatre(GENERIC_BUS_Ptr b);
 
 
-#define TheatreDetectSymbolsList  \
-		"DetectTheatre"
-
-#ifdef XFree86LOADER
-
 #define xf86_DetectTheatre         ((TheatrePtr (*)(GENERIC_BUS_Ptr))LoaderSymbol("DetectTheatre"))
 
-#else
-
-#define xf86_DetectTheatre             DetectTheatre
-
-#endif		
-
 #endif