Blob Blame History Raw
commit bc0407e53237d7968808110bc0243076377acf6e
Author: Alex Deucher <alex@cube.(none)>
Date:   Fri Apr 4 18:40:16 2008 -0400

    ATOMBIOS: Add support for DynamicClocks option
    
    This patch adds support for dynamic clock gating and static
    power management using the atom command tables.  In some cases
    the bios may already set this up during post, so YMMV.
    
    I was only able to test on desktop cards, so I haven't tested
    to see how much (if any) power this saves or how it affects the
    thermal footprint.

commit 5f5e21bb50555c56bd371576074c28c929307ff1
Author: Alex Deucher <alex@cube.(none)>
Date:   Fri Apr 4 14:29:45 2008 -0400

    RADEON: warning fixes

commit c8e9a973aaded24aad567a0e36d0c78a05d6b2fd
Author: Alex Deucher <alex@cube.(none)>
Date:   Fri Apr 4 14:26:19 2008 -0400

    RADEON: add some quirks

commit 091963a635b79884afe77c026eabb48972fbe175
Author: Alex Deucher <alex@botch2.com>
Date:   Thu Apr 3 22:35:16 2008 -0400

    Minor cleanup

commit 950e9860643c20acde0eca4e4ff26baacc1f2b69
Author: Alex Deucher <alex@botch2.com>
Date:   Thu Apr 3 22:11:48 2008 -0400

    Revert "RADEON: memmap rework 1"
    
    This reverts commit dd8ee1b444f4b973a1e0fadca5f943f2162b5e94.
    
    Conflicts:
    
    	src/radeon.h
    	src/radeon_driver.c
    
    This rework seems to have caused more trouble than it was worth.

commit 88a1fe4a94c5d11aff22734b21c89890e4428cd5
Author: Alex Deucher <alex@botch2.com>
Date:   Thu Apr 3 22:04:43 2008 -0400

    Revert "RADEON: remove driver rec copies of mc info, use save rec directly"
    
    This reverts commit be0858a84fbdf74c0b844f462933a221d48c707d.
    
    Conflicts:
    
    	src/radeon_driver.c

commit c40a7aa3989576a8144213e2f31b892d21df8686
Author: Owen W. Taylor <otaylor@fishsoup.net>
Date:   Thu Apr 3 14:43:55 2008 -0400

    R3xx/R5xx: Fix pitch and clamp mode for repeating textures
    
         - We can always use TXPITCH on a R300 even when repeating,
           (previous check for pitch matching width was also wrong)
         - Fix clamp mode for repeating textures to be WRAP

commit a8593482c1f2e0f2dbac06c2e5325ba8c83ed9ff
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Apr 2 09:58:05 2008 +1000

    atombios: fix the dual-head hopefully.
    
    tested on r600 with DVI and VGA

commit 61d883d116fab3e9b513432d65e705afc5bb39f1
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Apr 2 09:57:38 2008 +1000

    Revert "Revert "atombios: fixup the width/height to use the mode values not the scrn ones""
    
    This reverts commit fc9af578997b6f22ee8b17e83f37d98689291b0e.
    
    I see your revert and raise you one...

commit fc9af578997b6f22ee8b17e83f37d98689291b0e
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Tue Apr 1 09:25:45 2008 -0400

    Revert "atombios: fixup the width/height to use the mode values not the scrn ones"
    
    This reverts commit c2b1c8b706a6c7c1fd0af80091958473133d54e7.
    
    These registers hold surface size.  Using the mode values
    breaks dualhead.

commit 959509dd54de053f526b534e379a46934127231f
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Mar 31 14:29:44 2008 +1000

    radeon: use correct DDC interfaces so quirks get applied
    
    Radeon seemed to mess up applying certain quirks, hopefully this will fix it.

commit 18f5f1cd2f52afed89fc11ade0920f3dfea87306
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Mar 31 14:11:49 2008 +1000

    radeon: split quirks into separate function and new quirk for IBM RN50
    
    Add a connector table quirk for the IBM RN50.

commit c2b1c8b706a6c7c1fd0af80091958473133d54e7
Author: Dave Airlie <airlied@redhat.com>
Date:   Sun Mar 30 11:44:14 2008 +1000

    atombios: fixup the width/height to use the mode values not the scrn ones
    
    this fixes it properly, legacy appears to be okay.

commit c5edea3d8c9254d3a21e390b8309e39e4c9635db
Author: Dave Airlie <airlied@redhat.com>
Date:   Sun Mar 30 11:11:22 2008 +1000

    r500/r600: fix rotation to fill screen
    
    I'm not 100% sure this is the correct fix (maybe we shouldn't be using scrn
    virtualX/Y)... this will fix it for now until I get more time.

commit 9c62c820ba45ebc14d5f36f5d7885863800b6adb
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Fri Mar 28 12:37:29 2008 +0100

    Include config.h, so FGL_LINUX can actually be defined when it's tested...

commit a00d9260a85b94a522c442aee24bc5ea4dc31c5c
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Thu Mar 27 20:03:13 2008 -0400

    RADEON: fix lid issues on AVIVO chips for real this time :)

commit f0e89c09074b2c7e641f73692bb39b0bf68eb49c
Author: Alex Deucher <alex@botch2.com>
Date:   Thu Mar 27 19:15:18 2008 -0400

    Revert "RADEON: attempt to fix lid issues"
    
    This reverts commit 9b4473c1d830b88866dd22e8174a07195bd6fcf4.
    This doesn't help.

commit 1442d396b938049b83f009a78ddabe2bf85641b6
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Mar 27 14:02:51 2008 +1000

    radeon: size bios to max of bar vs 64k.
    
    reported by dwmw2: rhbz 438299

commit de2f609ff0004ef8b74727bfebc2c74fb91205ea
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Wed Mar 26 18:35:21 2008 -0400

    AVIVO: no need to call PreinitXv() on AVIVO chips as they have no overlay

commit 75884c257bc2bcfa5b498a77d4c403f09face036
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Wed Mar 26 18:16:47 2008 -0400

    XAA: update message about render so as to not confuse users

commit 9b4473c1d830b88866dd22e8174a07195bd6fcf4
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Wed Mar 26 18:01:29 2008 -0400

    RADEON: attempt to fix lid issues
    
    On some laptops the bios attempts to re-program the chip
    when a lid event comes in.  This should hopefully prevent
    the bios from doing that.

commit 8b144830fe9b4a0cee4745023de5e7d387070f60
Author: Alex Deucher <alex@samba.(none)>
Date:   Tue Mar 25 01:15:05 2008 -0400

    RV250: disable textured video due to HW bug
    
    The YUV->RGB conversion in the texture engine is broken
    on RV250 so the colors come out wrong.

commit 1789f11ab91633d3928f8b71988d51ff44bda9d1
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Mar 24 19:03:30 2008 -0400

    R3xx/R5xx: flush PVS state before enabling pvs-bypass

commit 305a3310963a5dd07b3495015b06aa8c7c4e6b02
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Mar 24 14:25:03 2008 -0400

    R3xx/R5xx: move more VAP, etc. state setup into common init3d() function
    
    Also some minor code cleanups

commit 399b1d405e602c62d6deebea6d7e1f38886cd8e2
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Mar 24 13:04:57 2008 -0400

    R3xx/R5xx: use non VAP/TCP for textured video
    
    Just extra state to emit.

commit cd77ec18f32a7b36acb655c927bbfd7044019f97
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Mar 24 18:42:21 2008 +1000

    r300: don't bother with VAP/TCL for render.
    
    We just send more data to the card to process per transaction, without getting
    any actual gains, as we already pre-compute the vertices without needing
    any clipping or transforms from the card.
    
    Perhaps some stuff could be done on-card, but so far the code is a lot
    faster if we avoid sending this extra info.
    
    pre: 150000 glyphs/sec
    post: 185000 glyphs/sec

commit 301c6739b88676a0c78fc72194e993f894b8dc28
Author: Alex Deucher <alex@botch2.com>
Date:   Sun Mar 23 11:14:02 2008 -0400

    RS4xx: Revert back to previous fifo settings for now
    
    Setup of these registers needs more investigation.

commit 9bea60b3eb378de5e1d44cc02a2763f4feae7882
Author: Alex Deucher <alex@botch2.com>
Date:   Sat Mar 22 11:46:15 2008 -0400

    RS4xx: more work on disp/disp2 fifo setup

commit 90f11c3986c28daa7b600b9662da145af325d264
Author: Alex Deucher <alex@botch2.com>
Date:   Sat Mar 22 11:29:51 2008 -0400

    RS4xx: missed this on the last commit.

commit 6d5066a451017a2683addc9e2496987626795dda
Author: Alex Deucher <alex@samba.(none)>
Date:   Fri Mar 21 16:21:54 2008 -0400

    RS4xx: attempt to set up disp/disp2 fifos correctly
    
    If you have an XPRESS chip, please test!!!

commit fb1cffac05ae20c8365b25a2042b0ae961880faf
Author: Alex Deucher <alex@samba.(none)>
Date:   Fri Mar 21 15:24:36 2008 -0400

    RS4xx: attempt to fix TMDS/DVO support
    
    XPRESS chips added a second set of FP control registers.
    I don't have the hw to test however.

commit 5e3b21284482df9974c9a58f248f0100def2bb0c
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Mar 19 19:15:05 2008 -0400

    Disable the setting of HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
    
    See bug 11796

commit 17cd42ed31814ba329a6a68edd0d75390a7da40e
Author: Matt Turner <mattst88@gmail.com>
Date:   Wed Mar 19 18:17:10 2008 -0400

    Enable BSR in Log2 functions
    
    This patch edits RADEONLog2 and ATILog2 to use the x86 BSR instruction instead
    of looping through bits. It should provide a somewhat of a speed increase in
    this function on x86 and AMD64 architectures.
    
    Note: the BSR instruction was added with the 80386 CPU and is therefore not
    compatible with earlier CPUs, though I highly doubt it's even possible to use a
    286 in conjunction with a Radeon.
    
    The inline assembly also works with Intel's compiler (icc).

commit c83827b4d2b6f03c54429e757a756eb99ff8be6b
Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>
Date:   Wed Mar 19 17:58:34 2008 -0400

    [PATCH] Compile warning fixes.
    
      Minor changes to avoid declarations mixed with code.
      Ansified functions with empty prototype to specify they don't
    receive arguments.
      Added some prototypes to radeon.h, and major reorder on radeon.h
    adding prototypes in alphabetical order and specifying to file that
    defines it.

commit bed9754ad21d6c0a7f61067b04ba31c430a7cecb
Merge: 55e446b... f71ac0e...
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Mar 19 16:06:41 2008 -0400

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

commit 55e446b5bc091e6c7b3c2e9ae20b45130555c246
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Mar 19 13:15:32 2008 -0400

    R3xx/R5xx: Make sure to clamp the output of the FS

commit b6aa4279cbe68cc8e4523795e9714fb798b62d98
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Mar 19 12:45:01 2008 -0400

    R5xx: bump textured video limits to 4096

commit 4a445a3e8c4c5ecd9d4ef8daa26906c3ceaa94a1
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Mar 19 12:31:51 2008 -0400

    RADEON: add new macros to distinguish between R3xx and R5xx 3D

commit 85d0c9e8d22ccc72bec87b3fd44da5d7609293e0
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Mar 19 12:07:33 2008 -0400

    RADEON: fixed textured video with XAA and tiling

commit f5951db7b3522e0fe6af7f46a170c9c9a60a9bff
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Mar 19 12:01:50 2008 -0400

    RV515: fix textured video and EXA Composite
    
    There seems to be an issue with the PVS setup on RV515, but
    bypassing it seems to work fine.

commit 13573879fe56368ad06234712b677c23fabc56c6
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Mar 19 15:06:47 2008 +1000

    r500: make it work from startup.
    
    I'm not sure why this worked or what is going wrong here, really the
    VAP internal architecture escapes me :)

commit d331dd64d644a18ec99a2136cd0943b5edca1f03
Author: Alex Deucher <alex@samba.(none)>
Date:   Tue Mar 18 19:44:26 2008 -0400

    R3xx/R5xx: remove extra return after last commit

commit bc34df7a9c35cdd38c49d5c22471f3f487a33d6e
Author: Alex Deucher <alex@samba.(none)>
Date:   Tue Mar 18 19:39:47 2008 -0400

    R3xx/R5xx: switch an ErrorF() to RADEONFALLBACK()

commit 6f03f8fe0ecf4181dcf125049cf63bece0451fb2
Author: Alex Deucher <alex@samba.(none)>
Date:   Tue Mar 18 19:36:05 2008 -0400

    R3xx: we only use 2 temps, not 3

commit 8bb71ab4a3eb4fb6ef7f709e87c8df387cb70ee3
Author: Tilman Sauerbeck <tilman@code-monkey.de>
Date:   Tue Mar 18 14:36:08 2008 -0400

    R3xx/R5xx: fix up a8-src-something_with_colors

commit c362591d9b496df30668543158e4de44de742dc3
Author: Alex Deucher <alex@samba.(none)>
Date:   Tue Mar 18 11:15:17 2008 -0400

    R3xx/R5xx: remove some cruft

commit 89fe6d2c7d7471e6088558130f6e49f46c31dd47
Author: Dave Airlie <airlied@linux.ie>
Date:   Tue Mar 18 09:43:43 2008 -0400

    R5xx: fix typ in r5xx render accel
    
    This gets render working on r5xx

commit 79b40ebcd8dedfc83e484c1024beeeaccc6124f3
Author: Alex Deucher <alex@samba.(none)>
Date:   Tue Mar 18 02:46:49 2008 -0400

    R5xx: first pass at render support (untested)

commit 71292c8f193230255d1d980c2e996bb01d04fab6
Author: Alex Deucher <alex@samba.(none)>
Date:   Tue Mar 18 00:45:37 2008 -0400

    R5xx: bump tex/dst limits to 4096

commit 30b52f8aa6a471455284f59b5b27252743892b13
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Mar 17 23:20:10 2008 -0400

    R3xx/R5xx: whitespace cleanup and cruft removal

commit 9c9f1b538ed710c3066775fba0a8e936b63087b1
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Mar 17 23:01:37 2008 -0400

    R3xx: get masks working and cleanup
    
    RS offset was wrong for mask texture

commit ef94febd74f8ee63081b61e42f093a5a2b8fbf1e
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Mar 17 22:27:19 2008 -0400

    R3xx: minor adjustments

commit f71ac0e40b9d950bcb3bba42a75d41f45b6ed1bf
Author: Alban Browaeys <prahal@yahoo.com>
Date:   Mon Mar 17 20:48:48 2008 -0400

    RADEON: Revert to old behavior when resetting the memmap on VT switch
    
    Not sure why this needs to be done twice.  Should fix bug 14980
    Probably needs more investigation.

commit bedbbf196dc97ee5142e7dfae16fb6f317fca5a7
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Mar 17 20:16:25 2008 -0400

    R3xx: some progress

commit af0e626c132de2dd9958fec657fcc85d4c0fe5e1
Author: Alex Deucher <alex@samba.(none)>
Date:   Mon Mar 17 18:07:12 2008 -0400

    R3xx: fix errant w

commit 29ea5bfc0eb3194e2454fc3ee863df54f0300880
Author: Alex Deucher <alex@cube.(none)>
Date:   Mon Mar 17 16:41:57 2008 -0400

    RADEON: fix typo in RADEONAdjustMemMapRegisters()

commit ab317e85c5ab1a249a510c34aeb3a908be1a66fc
Author: Alex Deucher <alex@cube.(none)>
Date:   Mon Mar 17 15:28:09 2008 -0400

    RADEON: make sure var is initialized properly in RADEONAdjustMemMapRegisters()

commit 208d307227e15f37a6af5194398ed23266ff743a
Author: Dave Airlie <airlied@linux.ie>
Date:   Sun Mar 16 19:39:23 2008 +1000

    radeon: the 0x5974 appears to be a mobility chip...
    
    After debugging with partymola on #radeon, adding this allowed his
    Dell Vostro 1000 to work properly

commit 9bc7c2ec4048e1677547c1d60c51ccb954f7589a
Author: Alex Deucher <alex@samba.(none)>
Date:   Fri Mar 14 20:12:22 2008 -0400

    R3xx: odds and ends...
    
    still not working.
    - swizzle US output for BGR formats
    - no need to write to temps in ALU ops,
    write to output only
    - flush the PVS before updating

commit 96bea7906c4706fcd57a9cd8f1ce3feab6ac676d
Author: Alex Deucher <alex@samba.(none)>
Date:   Fri Mar 14 15:59:36 2008 -0400

    R3xx: theoretical support for component alpha
    
    masks are still broken so...

commit cffe3dcc8991cd7c457a9c1a9f41055aa9ea3436
Author: Alex Deucher <alex@samba.(none)>
Date:   Fri Mar 14 14:37:43 2008 -0400

    R3xx: VS WIP

commit b73f52a50dfd6ff8d92f04d6b510c39582c6ac67
Author: Alex Deucher <alex@samba.(none)>
Date:   Fri Mar 14 14:20:49 2008 -0400

    R3xx/R5xx: enable VS for mask texture

commit 569a14ca9be1e18fe9921edc816ac3dc32d6cca7
Author: Alex Deucher <alex@samba.(none)>
Date:   Fri Mar 14 13:32:12 2008 -0400

    R3xx/R5xx: Fix magic numbers in vertex shaders

commit 4878997529601d62e257aa1c9112bd460561de73
Author: Alex Deucher <alex@samba.(none)>
Date:   Thu Mar 13 21:23:40 2008 -0400

    R3xx: make sure to set the FS code size correctly

commit 22f46b88ef05afb6a6b6d70007ac4980a446430e
Author: Alex Deucher <alex@samba.(none)>
Date:   Thu Mar 13 20:25:33 2008 -0400

    R3xx: attempt to setup the rasterizer properly for mask texture
    
    Not working yet

commit 081fc9e892fa3d2e07b7db65b2e2719646255463
Author: Alex Deucher <alex@samba.(none)>
Date:   Thu Mar 13 18:38:26 2008 -0400

    R3xx: more mask work

commit 2bf0236c03538ace3ce6d0e68f0829fc47d1385b
Author: Alex Deucher <alex@samba.(none)>
Date:   Thu Mar 13 18:32:00 2008 -0400

    R3xx: enable composite for non-mask cases

commit 74286ba41302107d2fc626fee2181f7c4bc18164
Author: Alex Deucher <alex@samba.(none)>
Date:   Thu Mar 13 18:25:32 2008 -0400

    R3xx: add basic mask support

commit a2bbe10d866567911b68f222b4758624bfe9bf84
Author: Alex Deucher <alex@samba.(none)>
Date:   Thu Mar 13 18:16:53 2008 -0400

    R300: setup source selects and output swizzling

commit b9974ecce7d1932595226004858b08a7a6b188dc
Author: Alex Deucher <alex@samba.(none)>
Date:   Thu Mar 13 17:35:38 2008 -0400

    R3xx: set the texture id and add some register info

commit 0ef700b7da5e554a0d0d166f3fde85ff45c9eb1f
Author: Alex Deucher <alex@samba.(none)>
Date:   Thu Mar 13 17:02:25 2008 -0400

    R3xx/R5xx: enable blending

commit b35c09a597c93a1d9f06ef0091c96822b0653f98
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Mar 13 18:42:29 2008 +1000

    xv: fixup XAA on r500 textured video
    
    the XAA area should never end up tiled. This may break with nooffscreen pixmaps

commit d4446461c3630caff166456c351ace34f57cc119
Author: Matt Turner <mattst88@gmail.com>
Date:   Tue Mar 11 21:20:53 2008 -0400

    Properly fix uninitialized variables warnings
    
    According to commit 9fd13e6773371c82b9799a5bda7c96ffa5cafe8c to
    xf86-video-intel by Kristian Høgsberg, there is a better way to fix the
    possibly initialized variables warnings. This patch will use Kristian's fix.

commit 20adfd7390d9b1f100e0c4a14f175377b8335c82
Author: Alex Deucher <alex@cube.(none)>
Date:   Tue Mar 11 20:09:35 2008 -0400

    RADEON: enable output attributes that require a modeset immediately
    
    This should fix bug 14915

commit 53ba7f5771b0b53fb0d3bc29d64bdd3813756d10
Author: Alex Deucher <alex@cube.(none)>
Date:   Tue Mar 11 19:12:40 2008 -0400

    RADEON: fix vblank interrupts after VT switch or suspend/resume

commit e946c097f0438afbea6f3dd37ee39d67d415708c
Author: Matt Turner <mattst88@gmail.com>
Date:   Tue Mar 11 19:07:58 2008 -0400

    [PATCH] Fix a few warnings

commit 8e160508520c0a24ca90aad182f296461ca0d9b6
Author: Alex Deucher <alex@cube.(none)>
Date:   Tue Mar 11 18:11:13 2008 -0400

    DCE3: add support for PCIEPHY (untested)

commit fbded88a2925f9f049936dad0736721e7b84a6ee
Author: Alex Deucher <alex@cube.(none)>
Date:   Tue Mar 11 14:10:31 2008 -0400

    ATOM: remove some cruft

commit 3263f6e4a410281d620c288a92bb4521f7b6fc06
Author: Alex Deucher <alex@cube.(none)>
Date:   Tue Mar 11 14:05:48 2008 -0400

    DCE3: enable DPMS on DIG ports

commit eb90e235b58c94f3d4d75394725ab2fe246a42ff
Author: Alex Deucher <alex@cube.(none)>
Date:   Tue Mar 11 13:53:54 2008 -0400

    DCE3: adjust PLL for DCE3 chips
    
    this fixes stability issues on digital outputs and certain modes.

commit 552615ccc5360baafb8bb41698c1ca27816fd4b2
Author: Alex Deucher <alex@cube.(none)>
Date:   Tue Mar 11 13:38:29 2008 -0400

    ATOMBIOS: enable load detection by default on both DACs
    
    Load detection is reliable with atom, so enable it by default
    on both DACA and DACB, rather than just DACA.

commit 78b10487cf222c96f8944ba25e2ea970506b3535
Author: Alex Deucher <alex@cube.(none)>
Date:   Tue Mar 11 13:16:00 2008 -0400

    DCE3: add output attribute to enable/disable coherent mode
    
    Enabled by default.  The TMDS transmitter can be programmed
    slightly differently depending on the chips in the panel.  If you
    have problems with tmds on a particular panel, try disabling it.

commit d20be31c46fbec623af4c3628a7c603ceacf500f
Author: Alex Deucher <alex@botch2.(none)>
Date:   Mon Mar 10 21:05:43 2008 -0400

    RV550: MC setup is like RV515 not RV530

commit 38606b08b68842fbcc81c233009c1117269f3be9
Author: Matthieu Herrb <matthieu@bluenote.herrb.net>
Date:   Sat Mar 8 23:22:59 2008 +0100

    Makefile.am: nuke RCS Id

commit 9d710ee1a44cf2f3a948fbdbe17ef09521cbe744
Author: Alex Deucher <alex@cube.(none)>
Date:   Fri Mar 7 15:09:14 2008 -0500

    AVIVO: clean up some unused variables

commit c28c30c9f3d7bfebfd56a5c982c96f0090982054
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Fri Mar 7 14:10:49 2008 -0500

    RADEON: Fix crash in last commit

commit c3a3635865e380c784a226c8ead069d4716d6b75
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Mar 6 20:17:45 2008 -0500

    RADEON: fix tiling/interlaced interaction with randr 1.2

commit df1b94dc4eb1f35b636dbf2ec0ab1c2da9937c0d
Author: Alex Deucher <alex@botch2.(none)>
Date:   Thu Mar 6 19:22:08 2008 -0500

    DCE3: Ignore outputs with DIN connectors for now

commit cb2dc19387c7b6494c47c76d683cf38a48700768
Author: Alex Deucher <alex@cube.(none)>
Date:   Thu Mar 6 18:33:12 2008 -0500

    AVIVO: fix typo from a previous commit
    
    Leave tv dpms hook disabled or you may get bad interactions
    with the shared DAC

commit 77355de48057e5e7e0d5b3f3cf5a7a92220a53b1
Author: Alex Deucher <alex@cube.(none)>
Date:   Thu Mar 6 17:46:00 2008 -0500

    AVIVO: don't add outputs for invalid connectors

commit 600dbe080997a01ceaf6be86723189d518bc1281
Merge: 594743a... 5b7875d...
Author: Alex Deucher <alex@cube.(none)>
Date:   Thu Mar 6 17:31:37 2008 -0500

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

commit 594743a99811a8b0f391412892414fcd158eeb56
Author: Alex Deucher <alex@cube.(none)>
Date:   Thu Mar 6 17:30:21 2008 -0500

    AVIVO: fix up memsize detection for IGP chips

commit 5b7875d0cbfbdbcd1515c4e942d30de298b49dff
Author: Doug Chapman <doug.chapman@hp.com>
Date:   Thu Mar 6 14:31:06 2008 -0500

    Bug #14826: Fix a bogus check around xf86SetOperatingState.

commit 651fe23f4c650ed91843dec48db24e18e8b91219
Merge: 3de2dc8... 766f464...
Author: Adam Jackson <ajax@redhat.com>
Date:   Thu Mar 6 14:28:27 2008 -0500

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

commit 41171c25cd235bafad26bcbabced16ead4b8c54b
Author: Alex Deucher <alex@cube.(none)>
Date:   Thu Mar 6 14:05:18 2008 -0500

    DCE3.0: add support for crtc memreq table

commit 766f464dfdfccadef23e4232f2bce5db22195513
Author: Alex Deucher <alex@cube.(none)>
Date:   Thu Mar 6 13:35:43 2008 -0500

    RADEON: take 2 on proper pragma pack support for bsds
    
    See bug 14594.  Based on suggestion by Henry Zhao

commit a842ce9ca6494e724a7828cead9b61c9ef02b6aa
Author: Alex Deucher <alex@cube.(none)>
Date:   Thu Mar 6 12:32:18 2008 -0500

    DCE3.0: Minor fixups

commit 8a1ba374033591c725a78923aa30829e4de2a5ae
Author: Alex Deucher <alex@cube.(none)>
Date:   Thu Mar 6 09:53:51 2008 -0500

    RADEON: option to override TVDAC adj values from bios with driver defaults
    
    If you have a washed out image on the tv dac, try this option.
    Option "DefaultTVDACAdj" "TRUE"

commit 0ed48f8f651a28e189f9fee8c6b593da0178d21c
Author: Alex Deucher <alex@cube.(none)>
Date:   Wed Mar 5 18:41:01 2008 -0500

    AVIVO: Initial support for DCE 3.0 using atombios
    
    DACs are working well, DIG support (DVI, HDMI, LVDS, etc.)
    still has some issues.

commit 2901e99f1942842856cd39c1dcc8b22f3cf7d9e3
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Mar 5 10:40:06 2008 -0500

    RADEON: fix fetching of dac2 adj values from newer bios tables

commit 74eb981287d76836327830bd51272f605a07e0cc
Author: Alex Deucher <alex@botch2.(none)>
Date:   Mon Mar 3 12:02:44 2008 -0500

    ATOMBIOS: fix atombios parser support on *bsd
    
    bsd requires a different pragma pack than Linux.
    See bug 14594.

commit f7769ea86e265f347eb58c517ccb5ef8b35eec27
Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>
Date:   Sun Mar 2 14:49:21 2008 -0500

    [PATCH] Ensure symbols used by other modules are visible.
    
    The xf86-video-ati drivers are one of the cases where LoaderSymbol is
    widely used in some obscure ways. This patch fixes the problem, and
    allows compiling with -fvisibility=hidden.

commit a4398ac3ad77216f2c8aa628425bef5f2912a0a9
Author: Alex Deucher <alex@cube.(none)>
Date:   Sat Mar 1 18:52:26 2008 -0500

    RS6xx: change isIGP checks to CHIP_FAMILY_RS690
    
    these paths are only relevant on RS6xx chips

commit 67d4d04836c05293b844bc505f303cfb04c0f8a4
Author: Alex Deucher <alex@cube.(none)>
Date:   Sat Mar 1 18:33:18 2008 -0500

    RADEON: use xf86SetDesiredModes() in screeninit and enterVT
    
    this should restore the proper output state on VT switches

commit be0858a84fbdf74c0b844f462933a221d48c707d
Author: Maciej Cencora <m.cencora@gmail.com>
Date:   Sat Mar 1 18:11:58 2008 -0500

    RADEON: remove driver rec copies of mc info, use save rec directly
    
    info->mc_* were used and the immediately copied into info->ModeReg
    ones.  Just use the ModeReg copies directly.

commit dd8ee1b444f4b973a1e0fadca5f943f2162b5e94
Author: Alex Deucher <alex@cube.(none)>
Date:   Sat Mar 1 16:23:51 2008 -0500

    RADEON: memmap rework 1
    
    Don't restore memmap regs on every mode switch.
    Just do memmap save/restore/setup on server start and VT switch.

commit 1f6a23000001f3d1c21b5c04f94714a8caa7aa8b
Author: Alex Deucher <alex@cube.(none)>
Date:   Sat Mar 1 15:53:42 2008 -0500

    RADEON: only restore legacy dac regs on legacy radeons

commit dee6cef8e62d0651c00319e03eea92940fd24aa4
Author: Alex Deucher <alex@botch2.(none)>
Date:   Sat Mar 1 14:39:32 2008 -0500

    RS4xx: enable exa render accel and textured video
    
    RS6xx paths seem to work fine on RS4xx

commit 129f737efe4e8d1a368e7db4b063bdcd9339cb09
Author: Alex Deucher <alex@cube.(none)>
Date:   Sat Mar 1 14:32:30 2008 -0500

    AVIVO: save/restore regs by block
    
    Save/Restore the entire block for each output.
    This should fix VT switch problems.

commit b069aadaa63a95d7a71b5cfbab83577b49501094
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Feb 29 22:36:02 2008 -0500

    AVIVO: LVDS panels need dithering enabled
    
    Fixes bug 14760

commit fe87bdee815372b4b4d7d4c705e34681625b90f2
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Feb 29 13:10:13 2008 -0500

    AVIVO: disable pageflipping on avivo chips until we have proper drm support

commit fb3678c7f511d539a51cd090cb8b5041d7d2ba26
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Feb 29 13:01:21 2008 -0500

    R5xx: fix register count when sending fragment program for textured video

commit a66d37d1a896ec934989592457c2beff8e6f1639
Author: Alex Deucher <alex@botch2.(none)>
Date:   Fri Feb 29 04:07:05 2008 -0500

    fix off-by-one in last commit

commit e56062960be0c8d3947861dd5e0691fce6516b99
Author: Alex Deucher <alex@cube.(none)>
Date:   Thu Feb 28 19:16:39 2008 -0500

    AVIVO: save/restore scaler regs

commit ae1c39a9b3e666404d0931679c9078c2e125a8bc
Author: Alex Deucher <alex@cube.(none)>
Date:   Thu Feb 28 18:53:55 2008 -0500

    RS6xx: rework output parsing
    
    Turns out it's not as complex as I originially thought.
    IGP chips just have non-standard GPIO entires for DDC.

commit d8d6c9fe4ae7e1ab67dd041a251e901d97c29ed6
Author: Alex Deucher <alex@botch2.(none)>
Date:   Thu Feb 28 17:01:14 2008 -0500

    RS6xx: fix typos in previous commit
    
    Noted by Maciej Cencora on IRC

commit 46547ae8bdbc5c10f1fd028b95ec4c5c31a5b318
Author: Alex Deucher <alex@cube.(none)>
Date:   Thu Feb 28 14:29:30 2008 -0500

    AVIVO: disable dithering on DFPs
    
    This should fix the color banding some people have noticed.
    Also save/restore DDIA regs on RS6xx

commit 72a53d6f20ac29b3baddb7d8af04f19b76d2e04f
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Thu Feb 28 17:38:04 2008 +0100

    Handle EXA coordinate limits more cleverly.
    
    Generally set the 2D engine limits, and only enforce the 3D engine limits in the
    CheckComposite hook. This should still prevent useless migration of pixmaps the
    3D engine can't handle but allows for basic acceleration of bigger ones.
    
    Fixes http://bugs.freedesktop.org/show_bug.cgi?id=14708 .

commit 5249f450a2487475a95531603cc8668db2c21c33
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Thu Feb 28 12:23:58 2008 +0100

    Fix 16 bit packed YUV XVideo playback on big endian systems with DRI disabled.
    
    http://bugs.freedesktop.org/show_bug.cgi?id=14668

commit e40d75fd8b2aece9dae8076fac822a4a83025fb2
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Feb 27 22:53:10 2008 -0500

    R500: fragment program clean up and magic number conversion

commit 140dadba36b2191f0e18e41dd987785abd5f55d2
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Feb 27 22:21:12 2008 -0500

    R300: fix up magic numbers in fragment program

commit e521476bb5e2dfabc93747e43eb911a8a101357e
Author: Alex Deucher <alex@botch2.(none)>
Date:   Wed Feb 27 21:26:55 2008 -0500

    R300/R400: bump up the clip limits for textured video
    
    This allows up to 2560x2560 (hw limit)

commit 10db46f11d7e1c055c9ad6034c65ad163dad17dc
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Feb 27 15:28:50 2008 -0500

    AVIVO: make sure we select the right LUT for each crtc

commit ea944f38dcfd871b27345698afea1cb986ecb049
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Feb 27 14:37:52 2008 -0500

    R300+: update RADEONCP_REFRESH() to reflect new location of scissor regs

commit b865faf95666e2172c3eec143f77fe9c524e4983
Author: Alex Deucher <alex@samba.(none)>
Date:   Wed Feb 27 14:05:44 2008 -0500

    R100/R200: move r100/r200 specific 3D setup into appropriate blocks
    
    R3xx+ doesn't have these regs.

commit 3de2dc88cf26ff5932f11cecdf975777b8aa2a4a
Author: Adam Jackson <ajax@redhat.com>
Date:   Wed Jan 16 14:55:05 2008 -0500

    Bump CRTC size limits on AVIVO chips so 30" displays work without tweaking.
    
    Note that the CRTC size limits we're using right now are _not_ the
    hardware limits, they're just heuristics until we can resize the front
    buffer properly.
diff --git a/configure.ac b/configure.ac
index 2412d4f..b644348 100644
--- a/configure.ac
+++ b/configure.ac
@@ -232,6 +232,11 @@ if test "x$XSERVER_LIBPCIACCESS" = xyes; then
 fi
 AM_CONDITIONAL(XSERVER_LIBPCIACCESS, test "x$XSERVER_LIBPCIACCESS" = xyes)
 
+case $host_os in
+  *linux*)
+  AC_DEFINE(FGL_LINUX, 1, [Use linux pragma pack]) ;;
+esac
+
 AC_SUBST([XORG_CFLAGS])
 AC_SUBST([DRI_CFLAGS])
 AC_SUBST([moduledir])
diff --git a/man/Makefile.am b/man/Makefile.am
index 2d11006..93ff52c 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -1,4 +1,3 @@
-# $Id$
 #
 # Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 # 
diff --git a/man/radeon.man b/man/radeon.man
index 86be965..ac6ea40 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -422,6 +422,14 @@ internal TMDS controller.
 The default is
 .B off.
 .TP
+.BI "Option \*qDefaultTVDACAdj\*q \*q" boolean \*q
+Use the default driver provided TVDAC Adj values rather than the ones
+provided by the bios. This option has no effect on Mac cards.  Enable 
+this option if you are having problems with a washed out display on 
+the secondary DAC.
+The default is
+.B off.
+.TP
 .BI "Option \*qDRI\*q \*q" boolean \*q
 Enable DRI support.  This option allows you to enable to disable the DRI.  
 The default is
diff --git a/src/AtomBios/includes/CD_Common_Types.h b/src/AtomBios/includes/CD_Common_Types.h
index 44a0b35..bc18c42 100644
--- a/src/AtomBios/includes/CD_Common_Types.h
+++ b/src/AtomBios/includes/CD_Common_Types.h
@@ -37,6 +37,10 @@ Revision History:
 #ifndef _COMMON_TYPES_H_
 	#define _COMMON_TYPES_H_
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
     #ifndef LINUX
 	#if _MSC_EXTENSIONS 
     
diff --git a/src/Makefile.am b/src/Makefile.am
index 70c05e5..5333495 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -66,7 +66,8 @@ if USE_EXA
 RADEON_EXA_SOURCES = radeon_exa.c
 endif
 
-AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ @XMODES_CFLAGS@ -DDISABLE_EASF -DENABLE_ALL_SERVICE_FUNCTIONS -DATOM_BIOS -DATOM_BIOS_PARSER -DFGL_LINUX -DDRIVER_PARSER
+AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ @XMODES_CFLAGS@ -DDISABLE_EASF -DENABLE_ALL_SERVICE_FUNCTIONS -DATOM_BIOS -DATOM_BIOS_PARSER -DDRIVER_PARSER
+
 INCLUDES = -I$(srcdir)/AtomBios/includes
 
 ati_drv_la_LTLIBRARIES = ati_drv.la
diff --git a/src/ati.c b/src/ati.c
index b3f07ca..85da389 100644
--- a/src/ati.c
+++ b/src/ati.c
@@ -102,7 +102,7 @@ ati_device_get_from_busid(int bus, int dev, int func)
 }
 
 static struct pci_device*
-ati_device_get_primary()
+ati_device_get_primary(void)
 {
     struct pci_device *device = NULL;
     struct pci_device_iterator *device_iter;
diff --git a/src/ati.h b/src/ati.h
index 828aae1..fa2e45e 100644
--- a/src/ati.h
+++ b/src/ati.h
@@ -31,4 +31,6 @@
 
 #include "xf86_OSproc.h"
 
+extern void ati_gdev_subdriver(pointer options);
+
 #endif /* ___ATI_H___ */
diff --git a/src/ati_pciids_gen.h b/src/ati_pciids_gen.h
index 330d1a9..b5e000c 100644
--- a/src/ati_pciids_gen.h
+++ b/src/ati_pciids_gen.h
@@ -281,9 +281,9 @@
 #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_RV515_7200 0x7200
+#define PCI_CHIP_RV515_7210 0x7210
+#define PCI_CHIP_RV515_7211 0x7211
 #define PCI_CHIP_R580_7240 0x7240
 #define PCI_CHIP_R580_7243 0x7243
 #define PCI_CHIP_R580_7244 0x7244
@@ -356,3 +356,22 @@
 #define PCI_CHIP_RV630_958C 0x958C
 #define PCI_CHIP_RV630_958D 0x958D
 #define PCI_CHIP_RV630_958E 0x958E
+#define PCI_CHIP_RV620_95C0 0x95C0
+#define PCI_CHIP_RV620_95C5 0x95C5
+#define PCI_CHIP_RV620_95C7 0x95C7
+#define PCI_CHIP_RV620_95C2 0x95C2
+#define PCI_CHIP_RV620_95C4 0x95C4
+#define PCI_CHIP_RV620_95CD 0x95CD
+#define PCI_CHIP_RV620_95CE 0x95CE
+#define PCI_CHIP_RV620_95CF 0x95CF
+#define PCI_CHIP_RV635_9590 0x9590
+#define PCI_CHIP_RV635_9596 0x9596
+#define PCI_CHIP_RV635_9597 0x9597
+#define PCI_CHIP_RV635_9598 0x9598
+#define PCI_CHIP_RV635_9599 0x9599
+#define PCI_CHIP_RV635_9591 0x9591
+#define PCI_CHIP_RV635_9593 0x9593
+#define PCI_CHIP_RS780_9610 0x9610
+#define PCI_CHIP_RS780_9611 0x9611
+#define PCI_CHIP_RS780_9612 0x9612
+#define PCI_CHIP_RS780_9613 0x9613
diff --git a/src/atimodule.c b/src/atimodule.c
index c249333..f0eb147 100644
--- a/src/atimodule.c
+++ b/src/atimodule.c
@@ -27,8 +27,6 @@
 #include "ati.h"
 #include "ativersion.h"
 
-extern void ati_gdev_subdriver(pointer options);
-
 /* Module loader interface */
 
 static XF86ModuleVersionInfo ATIVersionRec =
diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c
index bc2df18..51981a7 100644
--- a/src/atombios_crtc.c
+++ b/src/atombios_crtc.c
@@ -1,10 +1,5 @@
  /*
  * 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
@@ -28,6 +23,7 @@
  *
  * Authors:
  *    Dave Airlie <airlied@redhat.com>
+ *    Alex Deucher <alexander.deucher@amd.com>
  *
  */
 /*
@@ -52,7 +48,7 @@
 #include "sarea.h"
 #endif
 
-AtomBiosResult
+static AtomBiosResult
 atombios_enable_crtc(atomBiosHandlePtr atomBIOS, int crtc, int state)
 {
     ENABLE_CRTC_PS_ALLOCATION crtc_data;
@@ -75,7 +71,30 @@ atombios_enable_crtc(atomBiosHandlePtr atomBIOS, int crtc, int state)
     return ATOM_NOT_IMPLEMENTED;
 }
 
-AtomBiosResult
+static AtomBiosResult
+atombios_enable_crtc_memreq(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, EnableCRTCMemReq);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &crtc_data;
+
+    if (RHDAtomBiosFunc(atomBIOS->scrnIndex, atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("%s CRTC memreq %d success\n", state? "Enable":"Disable", crtc);
+	return ATOM_SUCCESS ;
+    }
+
+    ErrorF("Enable CRTC memreq failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+}
+
+static AtomBiosResult
 atombios_blank_crtc(atomBiosHandlePtr atomBIOS, int crtc, int state)
 {
     BLANK_CRTC_PS_ALLOCATION crtc_data;
@@ -99,19 +118,6 @@ atombios_blank_crtc(atomBiosHandlePtr atomBIOS, int crtc, int state)
     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)
 {
@@ -121,12 +127,16 @@ atombios_crtc_dpms(xf86CrtcPtr crtc, int mode)
     case DPMSModeOn:
     case DPMSModeStandby:
     case DPMSModeSuspend:
+	if (IS_DCE3_VARIANT)
+	    atombios_enable_crtc_memreq(info->atomBIOS, radeon_crtc->crtc_id, 1);
 	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);
+	if (IS_DCE3_VARIANT)
+	    atombios_enable_crtc_memreq(info->atomBIOS, radeon_crtc->crtc_id, 0);
 	break;
     }
 }
@@ -155,12 +165,20 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
 {
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     RADEONInfoPtr  info = RADEONPTR(crtc->scrn);
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(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;
+    int major, minor, i;
     SET_PIXEL_CLOCK_PS_ALLOCATION spc_param;
+    PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr;
+    PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr;
+    int pll_flags = 0;
+
+    xf86OutputPtr output;
+    RADEONOutputPrivatePtr radeon_output = NULL;
+
     void *ptr;
     AtomBiosArgRec data;
     unsigned char *space;
@@ -168,7 +186,11 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
 
     if (IS_AVIVO_VARIANT) {
 	CARD32 temp;
-	RADEONComputePLL(&info->pll, mode->Clock, &temp, &fb_div, &ref_div, &post_div, 0);
+
+	if (IS_DCE3_VARIANT)
+	    pll_flags |= RADEON_PLL_DCE3;
+
+	RADEONComputePLL(&info->pll, mode->Clock, &temp, &fb_div, &ref_div, &post_div, pll_flags);
 	sclock = temp;
 
 	/* disable spread spectrum clocking for now -- thanks Hedy Lamarr */
@@ -193,6 +215,20 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
 	       "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);
 
+    /* Can't really do cloning easily on DCE3 cards */
+    for (i = 0; i < xf86_config->num_output; i++) {
+	output = xf86_config->output[i];
+	if (output->crtc == crtc) {
+	    radeon_output = output->driver_private;
+	    break;
+	}
+    }
+
+    if (radeon_output == NULL) {
+	xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "No output assigned to crtc!\n");
+	return;
+    }
+
     atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
 
     ErrorF("table is %d %d\n", major, minor);
@@ -200,18 +236,65 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
     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;
+	case 2:
+	    spc2_ptr = (PIXEL_CLOCK_PARAMETERS_V2*)&spc_param.sPCLKInput;
+	    spc2_ptr->usPixelClock = sclock;
+	    spc2_ptr->usRefDiv = ref_div;
+	    spc2_ptr->usFbDiv = fb_div;
+	    spc2_ptr->ucPostDiv = post_div;
+	    spc2_ptr->ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
+	    spc2_ptr->ucCRTC = radeon_crtc->crtc_id;
+	    spc2_ptr->ucRefDivSrc = 1;
+	    ptr = &spc_param;
+	    break;
+	case 3:
+	    spc3_ptr = (PIXEL_CLOCK_PARAMETERS_V3*)&spc_param.sPCLKInput;
+	    spc3_ptr->usPixelClock = sclock;
+	    spc3_ptr->usRefDiv = ref_div;
+	    spc3_ptr->usFbDiv = fb_div;
+	    spc3_ptr->ucPostDiv = post_div;
+	    spc3_ptr->ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
+	    spc3_ptr->ucMiscInfo = (radeon_crtc->crtc_id << 2);
+
+	    if (radeon_output->MonType == MT_CRT) {
+		if (radeon_output->DACType == DAC_PRIMARY)
+		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
+		else if (radeon_output->DACType == DAC_TVDAC)
+		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
+		spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_CRT;
+	    } else if (radeon_output->MonType == MT_DFP) {
+		if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
+		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_UNIPHY;
+		else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
+		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1;
+		else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
+		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA;
+		if (OUTPUT_IS_DVI)
+		    spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_DVI;
+		else if (radeon_output->type == OUTPUT_HDMI)
+		    spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_HDMI;
+		else if (radeon_output->type == OUTPUT_DP)
+		    spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_DP;
+	    } else if (radeon_output->MonType == MT_LCD) {
+		if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
+		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA;
+		spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_LVDS;
+	    } else if (OUTPUT_IS_TV) {
+		if (radeon_output->DACType == DAC_PRIMARY)
+		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
+		else if (radeon_output->DACType == DAC_TVDAC)
+		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
+		spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_TV;
+	    } else if (radeon_output->MonType == MT_CV) {
+		if (radeon_output->DACType == DAC_PRIMARY)
+		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
+		else if (radeon_output->DACType == DAC_TVDAC)
+		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
+		spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_CV;
+	    }
 
 	    ptr = &spc_param;
 	    break;
-	}
 	default:
 	    ErrorF("Unknown table version\n");
 	    exit(-1);
@@ -247,26 +330,16 @@ atombios_crtc_mode_set(xf86CrtcPtr crtc,
     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;
+    Bool tilingChanged = FALSE;
 
     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
+        radeon_crtc->can_tile = (adjusted_mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
+	tilingChanged = RADEONSetTiling(pScrn);
     }
 
     for (i = 0; i < xf86_config->num_output; i++) {
@@ -334,27 +407,25 @@ atombios_crtc_mode_set(xf86CrtcPtr crtc,
     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;
+	CARD32 fb_format;
+
 	switch (crtc->scrn->bitsPerPixel) {
 	case 15:
-	    radeon_crtc->fb_format = AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555;
+	    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;
+	    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;
+	    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;
+	    fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
 	}
 
 	if (radeon_crtc->crtc_id == 0)
@@ -376,17 +447,14 @@ atombios_crtc_mode_set(xf86CrtcPtr crtc,
 
 	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_CONTROL + radeon_crtc->crtc_offset, 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_X_START + radeon_crtc->crtc_offset, x);
+	OUTREG(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, y);
+	OUTREG(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, x + mode->HDisplay);
+	OUTREG(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, y + mode->VDisplay);
 	OUTREG(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset,
 	       crtc->scrn->displayWidth);
 	OUTREG(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
@@ -398,7 +466,7 @@ atombios_crtc_mode_set(xf86CrtcPtr crtc,
 	OUTREG(AVIVO_D1SCL_UPDATE + radeon_crtc->crtc_offset, AVIVO_D1SCL_UPDATE_LOCK);
 
 	OUTREG(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
-	       crtc->scrn->virtualY);
+	       		mode->VDisplay);
 	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);
@@ -411,7 +479,7 @@ atombios_crtc_mode_set(xf86CrtcPtr crtc,
 
     atombios_set_crtc_timing(info->atomBIOS, &crtc_timing);
 
-    if (info->tilingEnabled != tilingOld) {
+    if (tilingChanged) {
 	/* 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)
diff --git a/src/atombios_output.c b/src/atombios_output.c
index 07d212f..a00d87f 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -235,7 +235,7 @@ atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode)
 }
 
 static int
-atombios_ddia_setup(xf86OutputPtr output, DisplayModePtr mode)
+atombios_output_ddia_setup(xf86OutputPtr output, DisplayModePtr mode)
 {
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
     DVO_ENCODER_CONTROL_PS_ALLOCATION disp_data;
@@ -346,6 +346,224 @@ atombios_output_lvds_setup(xf86OutputPtr output, DisplayModePtr mode)
 }
 
 static int
+atombios_output_dig1_setup(xf86OutputPtr output, DisplayModePtr mode)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    DIG_ENCODER_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.ucAction = 1;
+    disp_data.usPixelClock = mode->Clock / 10;
+    disp_data.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1;
+    if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) {
+	if (radeon_output->coherent_mode) {
+	    disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
+	    xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG1: Coherent Mode enabled\n");
+	} else
+	    xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG1: Coherent Mode disabled\n");
+    }
+
+    if (mode->Clock > 165000) {
+	disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B;
+	disp_data.ucLaneNum = 8;
+    } else {
+	disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
+	disp_data.ucLaneNum = 4;
+    }
+
+    if (OUTPUT_IS_DVI)
+	disp_data.ucEncoderMode = ATOM_ENCODER_MODE_DVI;
+    else if (radeon_output->type == OUTPUT_HDMI)
+	disp_data.ucEncoderMode = ATOM_ENCODER_MODE_HDMI;
+    else if (radeon_output->type == OUTPUT_DP)
+	disp_data.ucEncoderMode = ATOM_ENCODER_MODE_DP;
+    else if (radeon_output->type == OUTPUT_LVDS)
+	disp_data.ucEncoderMode = ATOM_ENCODER_MODE_LVDS;
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Output DIG1 setup success\n");
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Output DIG1 setup failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+
+}
+
+static int
+atombios_output_dig1_transmitter_setup(xf86OutputPtr output, DisplayModePtr mode)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    DIG_TRANSMITTER_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.ucAction = ATOM_TRANSMITTER_ACTION_ENABLE;
+    disp_data.usPixelClock = mode->Clock / 10;
+    disp_data.ucConfig = ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER | ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
+
+    if (info->IsIGP && (radeon_output->TMDSType == TMDS_UNIPHY)) {
+	if (mode->Clock > 165000) {
+	    disp_data.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
+				   ATOM_TRANSMITTER_CONFIG_LINKA_B);
+	    /* guess */
+	    if (radeon_output->igp_lane_info & 0x3)
+		disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
+	    else if (radeon_output->igp_lane_info & 0xc)
+		disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
+	} else {
+	    disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
+	    if (radeon_output->igp_lane_info & 0x1)
+		disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+	    else if (radeon_output->igp_lane_info & 0x2)
+		disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
+	    else if (radeon_output->igp_lane_info & 0x4)
+		disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
+	    else if (radeon_output->igp_lane_info & 0x8)
+		disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
+	}
+    } else {
+	if (mode->Clock > 165000)
+	    disp_data.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
+				   ATOM_TRANSMITTER_CONFIG_LINKA_B |
+				   ATOM_TRANSMITTER_CONFIG_LANE_0_7);
+	else
+	    disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+    }
+
+    radeon_output->transmitter_config = disp_data.ucConfig;
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Output DIG1 transmitter setup success\n");
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Output DIG1 transmitter setup failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+
+}
+
+static int
+atombios_output_dig2_setup(xf86OutputPtr output, DisplayModePtr mode)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    DIG_ENCODER_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.ucAction = 1;
+    disp_data.usPixelClock = mode->Clock / 10;
+    disp_data.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2;
+    if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) {
+	if (radeon_output->coherent_mode) {
+	    disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
+	    xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG2: Coherent Mode enabled\n");
+	} else
+	    xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG2: Coherent Mode disabled\n");
+    }
+
+    if (mode->Clock > 165000) {
+	disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B;
+	disp_data.ucLaneNum = 8;
+    } else {
+	disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
+	disp_data.ucLaneNum = 4;
+    }
+
+    if (OUTPUT_IS_DVI)
+	disp_data.ucEncoderMode = ATOM_ENCODER_MODE_DVI;
+    else if (radeon_output->type == OUTPUT_HDMI)
+	disp_data.ucEncoderMode = ATOM_ENCODER_MODE_HDMI;
+    else if (radeon_output->type == OUTPUT_DP)
+	disp_data.ucEncoderMode = ATOM_ENCODER_MODE_DP;
+    else if (radeon_output->type == OUTPUT_LVDS)
+	disp_data.ucEncoderMode = ATOM_ENCODER_MODE_LVDS;
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Output DIG2 setup success\n");
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Output DIG2 setup failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+
+}
+
+static int
+atombios_output_dig2_transmitter_setup(xf86OutputPtr output, DisplayModePtr mode)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    DIG_TRANSMITTER_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.ucAction = ATOM_TRANSMITTER_ACTION_ENABLE;
+    disp_data.usPixelClock = mode->Clock / 10;
+    disp_data.ucConfig = ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER | ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
+
+    if (info->IsIGP && (radeon_output->TMDSType == TMDS_UNIPHY)) {
+	if (mode->Clock > 165000) {
+	    disp_data.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
+				   ATOM_TRANSMITTER_CONFIG_LINKA_B);
+	    /* guess */
+	    if (radeon_output->igp_lane_info & 0x3)
+		disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
+	    else if (radeon_output->igp_lane_info & 0xc)
+		disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
+	} else {
+	    disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
+	    if (radeon_output->igp_lane_info & 0x1)
+		disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+	    else if (radeon_output->igp_lane_info & 0x2)
+		disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
+	    else if (radeon_output->igp_lane_info & 0x4)
+		disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
+	    else if (radeon_output->igp_lane_info & 0x8)
+		disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
+	}
+    } else {
+	if (mode->Clock > 165000)
+	    disp_data.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
+				   ATOM_TRANSMITTER_CONFIG_LINKA_B |
+				   ATOM_TRANSMITTER_CONFIG_LANE_0_7);
+	else
+	    disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+    }
+
+    radeon_output->transmitter_config = disp_data.ucConfig;
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Output DIG2 transmitter setup success\n");
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Output DIG2 transmitter setup failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+
+}
+
+static int
 atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode)
 {
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
@@ -382,6 +600,33 @@ atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode)
 
 }
 
+static void
+dfp_disable_dither(xf86OutputPtr output, int device)
+{
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    switch (device) {
+    case ATOM_DEVICE_DFP1_SUPPORT:
+	OUTREG(AVIVO_TMDSA_BIT_DEPTH_CONTROL, 0); /* TMDSA */
+	break;
+    case ATOM_DEVICE_DFP2_SUPPORT:
+	if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS740))
+	    OUTREG(AVIVO_DDIA_BIT_DEPTH_CONTROL, 0); /* DDIA */
+	else
+	    OUTREG(AVIVO_DVOA_BIT_DEPTH_CONTROL, 0); /* DVO */
+	break;
+    /*case ATOM_DEVICE_LCD1_SUPPORT:*/ /* LVDS panels need dither enabled */
+    case ATOM_DEVICE_DFP3_SUPPORT:
+	OUTREG(AVIVO_LVTMA_BIT_DEPTH_CONTROL, 0); /* LVTMA */
+	break;
+    default:
+	break;
+    }
+
+}
+
 static AtomBiosResult
 atombios_display_device_control(atomBiosHandlePtr atomBIOS, int device, Bool state)
 {
@@ -452,24 +697,78 @@ atombios_device_dpms(xf86OutputPtr output, int device, int mode)
     }
 }
 
+static int
+atombios_output_dig_dpms(xf86OutputPtr output, int mode, int block)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    DIG_TRANSMITTER_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    switch (mode) {
+    case DPMSModeOn:
+	disp_data.ucAction = ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT;
+	break;
+    case DPMSModeStandby:
+    case DPMSModeSuspend:
+    case DPMSModeOff:
+	disp_data.ucAction = ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT;
+	break;
+    }
+
+    disp_data.ucConfig = radeon_output->transmitter_config;
+
+    if (block == 1)
+	data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
+    else
+	data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Output DIG%d dpms success\n", block);
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Output DIG%d dpms failed\n", block);
+    return ATOM_NOT_IMPLEMENTED;
+
+}
+
 void
 atombios_output_dpms(xf86OutputPtr output, int mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
 
     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);
+       if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) {
+	   if (IS_DCE3_VARIANT)
+	       atombios_output_dig_dpms(output, mode, 2);
+	   else
+	       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);
+       if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) {
+	   if (IS_DCE3_VARIANT)
+	       atombios_output_dig_dpms(output, mode, 1);
+	   else
+	       atombios_device_dpms(output, ATOM_DEVICE_DFP1_SUPPORT, mode);
+       } else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) {
+	   if (IS_DCE3_VARIANT)
+	       return; // fixme
+	   else
+	       atombios_device_dpms(output, ATOM_DEVICE_DFP2_SUPPORT, mode);
+       } else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) {
+	   if (IS_DCE3_VARIANT)
+	       atombios_output_dig_dpms(output, mode, 2);
+	   else
+	       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)
@@ -498,6 +797,7 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
     AtomBiosArgRec data;
     unsigned char *space;
     SELECT_CRTC_SOURCE_PS_ALLOCATION crtc_src_param;
+    SELECT_CRTC_SOURCE_PARAMETERS_V2 crtc_src_param2;
     int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
     int major, minor;
 
@@ -505,15 +805,14 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
 
     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:
+	    crtc_src_param.ucCRTC = radeon_crtc->crtc_id;
+	    crtc_src_param.ucDevice = 0;
 	    if (radeon_output->MonType == MT_CRT) {
 		if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
 		    crtc_src_param.ucDevice = ATOM_DEVICE_CRT1_INDEX;
@@ -536,6 +835,46 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
 		if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
 		    crtc_src_param.ucDevice = ATOM_DEVICE_CV_INDEX;
 	    }
+	    data.exec.pspace = &crtc_src_param;
+	    ErrorF("device sourced: 0x%x\n", crtc_src_param.ucDevice);
+	    break;
+	case 2:
+	    crtc_src_param2.ucCRTC = radeon_crtc->crtc_id;
+	    if (radeon_output->MonType == MT_CRT) {
+		if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
+		    crtc_src_param2.ucEncoderID = ATOM_DEVICE_CRT1_INDEX;
+		else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
+		    crtc_src_param2.ucEncoderID = ATOM_DEVICE_CRT2_INDEX;
+		crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;
+	    } else if (radeon_output->MonType == MT_DFP) {
+		if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
+		    crtc_src_param2.ucEncoderID = ATOM_DEVICE_DFP1_INDEX;
+		else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
+		    crtc_src_param2.ucEncoderID = ATOM_DEVICE_DFP2_INDEX;
+		else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
+		    crtc_src_param2.ucEncoderID = ATOM_DEVICE_DFP3_INDEX;
+		if (OUTPUT_IS_DVI)
+		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DVI;
+		else if (radeon_output->type == OUTPUT_HDMI)
+		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_HDMI;
+		else if (radeon_output->type == OUTPUT_DP)
+		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DP;
+	    } else if (radeon_output->MonType == MT_LCD) {
+		if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
+		    crtc_src_param2.ucEncoderID = ATOM_DEVICE_LCD1_INDEX;
+		crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;
+	    } else if (OUTPUT_IS_TV) {
+		if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
+		    crtc_src_param2.ucEncoderID = ATOM_DEVICE_TV1_INDEX;
+		crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_TV;
+	    } else if (radeon_output->MonType == MT_CV) {
+		if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
+		    crtc_src_param2.ucEncoderID = ATOM_DEVICE_CV_INDEX;
+		crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CV;
+	    }
+
+	    data.exec.pspace = &crtc_src_param2;
+	    ErrorF("device sourced: 0x%x\n", crtc_src_param2.ucEncoderID);
 	    break;
 	}
 	break;
@@ -544,11 +883,8 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
 	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);
@@ -579,19 +915,47 @@ atombios_output_mode_set(xf86OutputPtr output,
 	       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) {
-	   if (info->IsIGP)
-	       atombios_ddia_setup(output, adjusted_mode);
-	   else
-	       atombios_external_tmds_setup(output, adjusted_mode);
-       } else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
-	   atombios_output_tmds2_setup(output, adjusted_mode);
+	if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) {
+	    if (IS_DCE3_VARIANT) {
+		atombios_output_dig1_setup(output, adjusted_mode);
+		atombios_output_dig1_transmitter_setup(output, adjusted_mode);
+	    } else {
+		atombios_output_tmds1_setup(output, adjusted_mode);
+		dfp_disable_dither(output, ATOM_DEVICE_DFP1_SUPPORT);
+	    }
+	} else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) {
+	    if (IS_DCE3_VARIANT) {
+		// fix me
+	    } else {
+		if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+		    (info->ChipFamily == CHIP_FAMILY_RS740))
+		    atombios_output_ddia_setup(output, adjusted_mode);
+		else
+		    atombios_external_tmds_setup(output, adjusted_mode);
+		dfp_disable_dither(output, ATOM_DEVICE_DFP2_SUPPORT);
+	    }
+	} else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) {
+	    if (IS_DCE3_VARIANT) {
+		atombios_output_dig2_setup(output, adjusted_mode);
+		atombios_output_dig2_transmitter_setup(output, adjusted_mode);
+	    } else {
+		atombios_output_tmds2_setup(output, adjusted_mode);
+		dfp_disable_dither(output, ATOM_DEVICE_DFP3_SUPPORT);
+	    }
+	}
     } 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->devices & ATOM_DEVICE_LCD1_SUPPORT) {
+	    if (IS_DCE3_VARIANT) {
+		atombios_output_dig2_setup(output, adjusted_mode);
+		atombios_output_dig2_transmitter_setup(output, adjusted_mode);
+	    } else {
+		atombios_output_lvds_setup(output, adjusted_mode);
+		dfp_disable_dither(output, ATOM_DEVICE_LCD1_SUPPORT);
+	    }
+	}
+    } else if ((radeon_output->MonType == MT_CTV) ||
+	       (radeon_output->MonType == MT_STV) ||
+	       (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)
@@ -605,10 +969,13 @@ static AtomBiosResult
 atom_bios_dac_load_detect(atomBiosHandlePtr atomBIOS, xf86OutputPtr output)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
     DAC_LOAD_DETECTION_PS_ALLOCATION dac_data;
     AtomBiosArgRec data;
     unsigned char *space;
 
+    dac_data.sDacload.ucMisc = 0;
+
     if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) {
 	dac_data.sDacload.usDeviceID = ATOM_DEVICE_CRT1_SUPPORT;
 	if (radeon_output->DACType == DAC_PRIMARY)
@@ -627,18 +994,21 @@ atom_bios_dac_load_detect(atomBiosHandlePtr atomBIOS, xf86OutputPtr output)
 	    dac_data.sDacload.ucDacType = ATOM_DAC_A;
 	else if (radeon_output->DACType == DAC_TVDAC)
 	    dac_data.sDacload.ucDacType = ATOM_DAC_B;
+	if (IS_DCE3_VARIANT)
+	    dac_data.sDacload.ucMisc = 1;
     } 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;
+	if (IS_DCE3_VARIANT)
+	    dac_data.sDacload.ucMisc = 1;
     } 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;
diff --git a/src/legacy_crtc.c b/src/legacy_crtc.c
index 06ad60c..5ef86ce 100644
--- a/src/legacy_crtc.c
+++ b/src/legacy_crtc.c
@@ -78,6 +78,13 @@ RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
     OUTREG(RADEON_BUS_CNTL,           restore->bus_cntl);
     OUTREG(RADEON_SURFACE_CNTL,       restore->surface_cntl);
 
+    if (info->ChipFamily == CHIP_FAMILY_RS400) {
+	OUTREG(RS400_DISP2_REQ_CNTL1, restore->disp2_req_cntl1);
+	OUTREG(RS400_DISP2_REQ_CNTL2, restore->disp2_req_cntl2);
+	OUTREG(RS400_DMIF_MEM_CNTL1,  restore->dmif_mem_cntl1);
+	OUTREG(RS400_DISP1_REQ_CNTL1, restore->disp1_req_cntl1);
+    }
+
     /* 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.
@@ -178,12 +185,6 @@ RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
     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);
 
 }
@@ -489,6 +490,13 @@ RADEONSaveCommonRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
     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);
+
+    if (info->ChipFamily == CHIP_FAMILY_RS400) {
+	save->disp2_req_cntl1 = INREG(RS400_DISP2_REQ_CNTL1);
+	save->disp2_req_cntl2 = INREG(RS400_DISP2_REQ_CNTL2);
+	save->dmif_mem_cntl1  = INREG(RS400_DMIF_MEM_CNTL1);
+	save->disp1_req_cntl1 = INREG(RS400_DISP1_REQ_CNTL1);
+    }
 }
 
 /* Read CRTC registers */
@@ -550,13 +558,6 @@ RADEONSaveCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save)
     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 */
@@ -677,6 +678,14 @@ RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info)
     save->cap0_trig_cntl     = 0;
     save->cap1_trig_cntl     = 0;
     save->bus_cntl           = info->BusCntl;
+
+    if (info->ChipFamily == CHIP_FAMILY_RS400) {
+	save->disp2_req_cntl1 = info->SavedReg->disp2_req_cntl1;
+	save->disp2_req_cntl2 = info->SavedReg->disp2_req_cntl2;
+	save->dmif_mem_cntl1  = info->SavedReg->dmif_mem_cntl1;
+	save->disp1_req_cntl1 = info->SavedReg->disp1_req_cntl1;
+    }
+
     /*
      * If bursts are enabled, turn on discards
      * Radeon doesn't have write bursts
@@ -1125,13 +1134,6 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save,
     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;
 }
 
@@ -1554,6 +1556,24 @@ RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2
     OUTREG(RADEON_GRPH_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
 				     (critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
 
+#if 0
+    if (info->ChipFamily == CHIP_FAMILY_RS400) {
+	/* attempt to program RS400 disp regs correctly ??? */
+	temp = info->SavedReg->disp1_req_cntl1;
+	temp &= ~(RS400_DISP1_START_REQ_LEVEL_MASK |
+		  RS400_DISP1_STOP_REQ_LEVEL_MASK);
+	OUTREG(RS400_DISP1_REQ_CNTL1, (temp |
+				       (critical_point << RS400_DISP1_START_REQ_LEVEL_SHIFT) |
+				       (critical_point << RS400_DISP1_STOP_REQ_LEVEL_SHIFT)));
+	temp = info->SavedReg->dmif_mem_cntl1;
+	temp &= ~(RS400_DISP1_CRITICAL_POINT_START_MASK |
+		  RS400_DISP1_CRITICAL_POINT_STOP_MASK);
+	OUTREG(RS400_DMIF_MEM_CNTL1, (temp |
+				      (critical_point << RS400_DISP1_CRITICAL_POINT_START_SHIFT) |
+				      (critical_point << RS400_DISP1_CRITICAL_POINT_STOP_SHIFT)));
+    }
+#endif
+
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "GRPH_BUFFER_CNTL from %x to %x\n",
 		   (unsigned int)info->SavedReg->grph_buffer_cntl,
@@ -1604,6 +1624,28 @@ RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2
 	OUTREG(RADEON_GRPH2_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
 					  (critical_point2 << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
 
+	if (info->ChipFamily == CHIP_FAMILY_RS400) {
+#if 0
+	    /* attempt to program RS400 disp2 regs correctly ??? */
+	    temp = info->SavedReg->disp2_req_cntl1;
+	    temp &= ~(RS400_DISP2_START_REQ_LEVEL_MASK |
+		      RS400_DISP2_STOP_REQ_LEVEL_MASK);
+	    OUTREG(RS400_DISP2_REQ_CNTL1, (temp |
+					   (critical_point2 << RS400_DISP1_START_REQ_LEVEL_SHIFT) |
+					   (critical_point2 << RS400_DISP1_STOP_REQ_LEVEL_SHIFT)));
+	    temp = info->SavedReg->disp2_req_cntl2;
+	    temp &= ~(RS400_DISP2_CRITICAL_POINT_START_MASK |
+		      RS400_DISP2_CRITICAL_POINT_STOP_MASK);
+	    OUTREG(RS400_DISP2_REQ_CNTL2, (temp |
+					   (critical_point2 << RS400_DISP2_CRITICAL_POINT_START_SHIFT) |
+					   (critical_point2 << RS400_DISP2_CRITICAL_POINT_STOP_SHIFT)));
+#endif
+	    OUTREG(RS400_DISP2_REQ_CNTL1, 0x105DC1CC);
+	    OUTREG(RS400_DISP2_REQ_CNTL2, 0x2749D000);
+	    OUTREG(RS400_DMIF_MEM_CNTL1,  0x29CA71DC);
+	    OUTREG(RS400_DISP1_REQ_CNTL1, 0x28FBC3AC);
+	}
+
 	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		       "GRPH2_BUFFER_CNTL from %x to %x\n",
 		       (unsigned int)info->SavedReg->grph2_buffer_cntl,
@@ -1658,26 +1700,15 @@ legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
     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;
-
+    Bool tilingChanged = 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
+	radeon_crtc->can_tile = (adjusted_mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
+	tilingChanged = RADEONSetTiling(pScrn);
     }
 
     for (i = 0; i < xf86_config->num_output; i++) {
@@ -1775,7 +1806,7 @@ legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
     if (info->DispPriority)
         RADEONInitDispBandwidth(pScrn);
 
-    if (info->tilingEnabled != tilingOld) {
+    if (tilingChanged) {
 	/* 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)
diff --git a/src/legacy_output.c b/src/legacy_output.c
index 0de13df..0d6e4f1 100644
--- a/src/legacy_output.c
+++ b/src/legacy_output.c
@@ -103,6 +103,12 @@ RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
     OUTREG(RADEON_TMDS_TRANSMITTER_CNTL,restore->tmds_transmitter_cntl);
     OUTREG(RADEON_FP_GEN_CNTL,          restore->fp_gen_cntl);
 
+    if (info->ChipFamily == CHIP_FAMILY_RS400) {
+	OUTREG(RS400_FP_2ND_GEN_CNTL, restore->fp_2nd_gen_cntl);
+	/*OUTREG(RS400_TMDS2_CNTL, restore->tmds2_cntl);*/
+	OUTREG(RS400_TMDS2_TRANSMITTER_CNTL, restore->tmds2_transmitter_cntl);
+    }
+
     /* old AIW Radeon has some BIOS initialization problem
      * with display buffer underflow, only occurs to DFP
      */
@@ -121,6 +127,8 @@ RADEONRestoreFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 
     OUTREG(RADEON_FP2_GEN_CNTL,         restore->fp2_gen_cntl);
 
+    if (info->ChipFamily == CHIP_FAMILY_RS400)
+	OUTREG(RS400_FP2_2_GEN_CNTL, restore->fp2_2_gen_cntl);
 }
 
 /* Write RMX registers */
@@ -203,6 +211,14 @@ RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
 	/* bit 22 of TMDS_PLL_CNTL is read-back inverted */
 	save->tmds_pll_cntl ^= (1 << 22);
     }
+
+    if (info->ChipFamily == CHIP_FAMILY_RS400) {
+	save->fp_2nd_gen_cntl         = INREG(RS400_FP_2ND_GEN_CNTL);
+	save->fp2_2_gen_cntl          = INREG(RS400_FP2_2_GEN_CNTL);
+	save->tmds2_cntl              = INREG(RS400_TMDS2_CNTL);
+	save->tmds2_transmitter_cntl  = INREG(RS400_TMDS2_TRANSMITTER_CNTL);
+    }
+
 }
 
 Bool
@@ -675,9 +691,9 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
     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);
 
+    radeon_output = output->driver_private;
     for (o = 0; o < xf86_config->num_output; o++) {
 	if (output == xf86_config->output[o]) {
 	    break;
@@ -716,6 +732,13 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 		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);
+		if (info->ChipFamily == CHIP_FAMILY_RS400) {
+		    tmp = INREG(RS400_FP_2ND_GEN_CNTL);
+		    tmp |= (RS400_FP_2ND_ON | RS400_TMDS_2ND_EN);
+		    OUTREG(RS400_FP_2ND_GEN_CNTL, tmp);
+		    save->fp_2nd_gen_cntl |= (RS400_FP_2ND_ON |
+					      RS400_TMDS_2ND_EN);
+		}
 	    } else if (radeon_output->TMDSType == TMDS_EXT) {
 		info->output_dfp2 |= (1 << o);
 		tmp = INREG(RADEON_FP2_GEN_CNTL);
@@ -724,6 +747,14 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 		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;
+		if (info->ChipFamily == CHIP_FAMILY_RS400) {
+		    tmp = INREG(RS400_FP2_2_GEN_CNTL);
+		    tmp &= ~RS400_FP2_2_BLANK_EN;
+		    tmp |= (RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN);
+		    OUTREG(RS400_FP2_2_GEN_CNTL, tmp);
+		    save->fp2_2_gen_cntl |= (RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN);
+		    save->fp2_2_gen_cntl &= ~RS400_FP2_2_BLANK_EN;
+		}
 	    }
 	} else if (radeon_output->MonType == MT_LCD) {
 	    info->output_lcd1 |= (1 << o);
@@ -780,6 +811,13 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 		    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);
+		    if (info->ChipFamily == CHIP_FAMILY_RS400) {
+			tmp = INREG(RS400_FP_2ND_GEN_CNTL);
+			tmp &= ~(RS400_FP_2ND_ON | RS400_TMDS_2ND_EN);
+			OUTREG(RS400_FP_2ND_GEN_CNTL, tmp);
+			save->fp_2nd_gen_cntl &= ~(RS400_FP_2ND_ON |
+						   RS400_TMDS_2ND_EN);
+		    }
 		}
 	    } else if (radeon_output->TMDSType == TMDS_EXT) {
 		info->output_dfp2 &= ~(1 << o);
@@ -790,6 +828,14 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 		    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;
+		    if (info->ChipFamily == CHIP_FAMILY_RS400) {
+			tmp = INREG(RS400_FP2_2_GEN_CNTL);
+			tmp |= RS400_FP2_2_BLANK_EN;
+			tmp &= ~(RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN);
+			OUTREG(RS400_FP2_2_GEN_CNTL, tmp);
+			save->fp2_2_gen_cntl &= ~(RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN);
+			save->fp2_2_gen_cntl |= RS400_FP2_2_BLANK_EN;
+		    }
 		}
 	    }
 	} else if (radeon_output->MonType == MT_LCD) {
@@ -918,6 +964,29 @@ RADEONInitFPRegisters(xf86OutputPtr output, RADEONSavePtr save,
 	    save->fp_gen_cntl |= RADEON_FP_SEL_CRTC2;
     }
 
+    if (info->ChipFamily == CHIP_FAMILY_RS400) {
+	save->tmds2_transmitter_cntl = info->SavedReg->tmds2_transmitter_cntl &
+	    ~(RS400_TMDS2_PLLRST);
+	save->tmds2_transmitter_cntl &= ~(RS400_TMDS2_PLLEN);
+
+	save->fp_2nd_gen_cntl = info->SavedReg->fp_2nd_gen_cntl;
+
+	if (pScrn->rgbBits == 8)
+	    save->fp_2nd_gen_cntl |= RS400_PANEL_FORMAT_2ND;  /* 24 bit format */
+	else
+	    save->fp_2nd_gen_cntl &= ~RS400_PANEL_FORMAT_2ND;/* 18 bit format */
+
+	save->fp_2nd_gen_cntl &= ~RS400_FP_2ND_SOURCE_SEL_MASK;
+
+	if (IsPrimary) {
+	    if (radeon_output->Flags & RADEON_USE_RMX)
+		save->fp_2nd_gen_cntl |= RS400_FP_2ND_SOURCE_SEL_RMX;
+	    else
+		save->fp_2nd_gen_cntl |= RS400_FP_2ND_SOURCE_SEL_CRTC1;
+	} else
+	    save->fp_2nd_gen_cntl |= RS400_FP_2ND_SOURCE_SEL_CRTC2;
+    }
+
 }
 
 static void
@@ -954,6 +1023,8 @@ RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save,
 	    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 |= R200_FP2_SOURCE_SEL_CRTC1;
 	} else {
 	    save->fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_CRTC2;
 	}
@@ -966,6 +1037,27 @@ RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save,
 	}
     }
 
+    if (info->ChipFamily == CHIP_FAMILY_RS400) {
+	if (pScrn->rgbBits == 8)
+	    save->fp2_2_gen_cntl = info->SavedReg->fp2_2_gen_cntl |
+		RS400_FP2_2_PANEL_FORMAT; /* 24 bit format, */
+	else
+	    save->fp2_2_gen_cntl = info->SavedReg->fp2_2_gen_cntl &
+		~RS400_FP2_2_PANEL_FORMAT;/* 18 bit format, */
+
+	save->fp2_2_gen_cntl &= ~(RS400_FP2_2_ON |
+				  RS400_FP2_2_DVO2_EN |
+				  RS400_FP2_2_SOURCE_SEL_MASK);
+
+	if (IsPrimary) {
+	    if (radeon_output->Flags & RADEON_USE_RMX)
+		save->fp2_2_gen_cntl |= RS400_FP2_2_SOURCE_SEL_RMX;
+	    else
+		save->fp2_2_gen_cntl |= RS400_FP2_2_SOURCE_SEL_CRTC1;
+	} else
+	    save->fp2_2_gen_cntl |= RS400_FP2_2_SOURCE_SEL_CRTC2;
+    }
+
 }
 
 static void
diff --git a/src/pcidb/ati_pciids.csv b/src/pcidb/ati_pciids.csv
index 5a2191a..fc340e7 100644
--- a/src/pcidb/ati_pciids.csv
+++ b/src/pcidb/ati_pciids.csv
@@ -187,7 +187,7 @@
 "0x5964","RV280_5964","RV280",,,,,,"ATI Radeon 9200SE 5964 (AGP)"
 "0x5965","RV280_5965","RV280",,,,,,"ATI FireMV 2200 (PCI)"
 "0x5969","RN50_5969","RV100",,,1,,,"ATI ES1000 5969 (PCI)"
-"0x5974","RS482_5974","RS400",,1,,,1,"ATI Radeon XPRESS 200 5974 (PCIE)"
+"0x5974","RS482_5974","RS400",1,1,,,1,"ATI Radeon XPRESS 200 5974 (PCIE)"
 "0x5975","RS485_5975","RS400",1,1,,,1,"ATI Radeon XPRESS 200M 5975 (PCIE)"
 "0x5A41","RS400_5A41","RS400",,1,,,1,"ATI Radeon XPRESS 200 5A41 (PCIE)"
 "0x5A42","RS400_5A42","RS400",1,1,,,1,"ATI Radeon XPRESS 200M 5A42 (PCIE)"
@@ -282,9 +282,9 @@
 "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"
+"0x7200","RV515_7200","RV515",,,,,,"ATI Radeon X2300HD"
+"0x7210","RV515_7210","RV515",1,,,,,"ATI Mobility Radeon HD 2300"
+"0x7211","RV515_7211","RV515",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"
@@ -331,13 +331,13 @@
 "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"
+"0x94C4","RV610_94C4","RV610",,,,,,"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"
+"0x94CB","RV610_94CB","RV610",1,,,,,"ATI RADEON E2400"
 "0x94CC","RV610_94CC","RV610",,,,,,"ATI RV610"
 "0x9500","RV670_9500","RV670",,,,,,"ATI RV670"
 "0x9501","RV670_9501","RV670",,,,,,"ATI Radeon HD3870"
@@ -348,12 +348,31 @@
 "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"
+"0x9586","RV630_9586","RV630",,,,,,"ATI Radeon HD 2600 XT AGP"
+"0x9587","RV630_9587","RV630",,,,,,"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"
+"0x958B","RV630_958B","RV630",1,,,,,"ATI Gemini 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"
+"0x958E","RV630_958E","RV630",,,,,,"ATI Radeon HD 2600 LE"
+"0x95C0","RV620_95C0","RV620",,,,,,"ATI Radeon HD 3470"
+"0x95C5","RV620_95C5","RV620",,,,,,"ATI Radeon HD 3450"
+"0x95C7","RV620_95C7","RV620",,,,,,"ATI Radeon HD 3430"
+"0x95C2","RV620_95C2","RV620",1,,,,,"ATI Mobility Radeon HD 3430"
+"0x95C4","RV620_95C4","RV620",1,,,,,"ATI Mobility Radeon HD 3400 Series"
+"0x95CD","RV620_95CD","RV620",,,,,,"ATI FireMV 2450"
+"0x95CE","RV620_95CE","RV620",,,,,,"ATI FireMV 2260"
+"0x95CF","RV620_95CF","RV620",,,,,,"ATI FireMV 2260"
+"0x9590","RV635_9590","RV635",,,,,,"ATI ATI Radeon HD 3600 Series"
+"0x9596","RV635_9596","RV635",,,,,,"ATI ATI Radeon HD 3650 AGP"
+"0x9597","RV635_9597","RV635",,,,,,"ATI ATI Radeon HD 3600 PRO"
+"0x9598","RV635_9598","RV635",,,,,,"ATI ATI Radeon HD 3600 XT"
+"0x9599","RV635_9599","RV635",,,,,,"ATI ATI Radeon HD 3600 PRO"
+"0x9591","RV635_9591","RV635",1,,,,,"ATI Mobility Radeon HD 3650"
+"0x9593","RV635_9593","RV635",1,,,,,"ATI Mobility Radeon HD 3670"
+"0x9610","RS780_9610","RS780",,1,,,1,"ATI Radeon HD 3200 Graphics"
+"0x9611","RS780_9611","RS780",,1,,,1,"ATI Radeon 3100 Graphics"
+"0x9612","RS780_9612","RS780",,1,,,1,"ATI Radeon HD 3200 Graphics"
+"0x9613","RS780_9613","RS780",,1,,,1,"ATI Radeon 3100 Graphics"
diff --git a/src/radeon.h b/src/radeon.h
index aba3c0f..ef62883 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -167,7 +167,8 @@ typedef enum {
     OPTION_TVDAC_LOAD_DETECT,
     OPTION_FORCE_TVOUT,
     OPTION_TVSTD,
-    OPTION_IGNORE_LID_STATUS
+    OPTION_IGNORE_LID_STATUS,
+    OPTION_DEFAULT_TVDAC_ADJ
 } RADEONOpts;
 
 
@@ -213,6 +214,7 @@ typedef struct {
 #define RADEON_PLL_NO_ODD_POST_DIV (1 << 1)
 #define RADEON_PLL_USE_REF_DIV     (1 << 2)
 #define RADEON_PLL_LEGACY          (1 << 3)
+#define RADEON_PLL_DCE3            (1 << 4)
 
 typedef struct {
     CARD16            reference_freq;
@@ -268,12 +270,15 @@ typedef enum {
     CHIP_FAMILY_RV560,   /* rv560 */
     CHIP_FAMILY_RV570,   /* rv570 */
     CHIP_FAMILY_RS690,
-    CHIP_FAMILY_R600,    /* r60 */
+    CHIP_FAMILY_RS740,
+    CHIP_FAMILY_R600,    /* r600 */
     CHIP_FAMILY_R630,
     CHIP_FAMILY_RV610,
     CHIP_FAMILY_RV630,
     CHIP_FAMILY_RV670,
-    CHIP_FAMILY_RS740,
+    CHIP_FAMILY_RV620,
+    CHIP_FAMILY_RV635,
+    CHIP_FAMILY_RS780,
     CHIP_FAMILY_LAST
 } RADEONChipFamily;
 
@@ -296,6 +301,25 @@ typedef enum {
 
 #define IS_AVIVO_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV515))
 
+#define IS_DCE3_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV620))
+
+#define IS_R500_3D ((info->ChipFamily == CHIP_FAMILY_RV515)  ||  \
+	(info->ChipFamily == CHIP_FAMILY_R520)   ||  \
+	(info->ChipFamily == CHIP_FAMILY_RV530)  ||  \
+	(info->ChipFamily == CHIP_FAMILY_R580)   ||  \
+	(info->ChipFamily == CHIP_FAMILY_RV560)  ||  \
+	(info->ChipFamily == CHIP_FAMILY_RV570))
+
+#define IS_R300_3D ((info->ChipFamily == CHIP_FAMILY_R300)  ||  \
+	(info->ChipFamily == CHIP_FAMILY_RV350) ||  \
+	(info->ChipFamily == CHIP_FAMILY_R350)  ||  \
+	(info->ChipFamily == CHIP_FAMILY_RV380) ||  \
+	(info->ChipFamily == CHIP_FAMILY_R420)  ||  \
+	(info->ChipFamily == CHIP_FAMILY_RV410) ||  \
+	(info->ChipFamily == CHIP_FAMILY_RS690) ||  \
+	(info->ChipFamily == CHIP_FAMILY_RS740) ||  \
+	(info->ChipFamily == CHIP_FAMILY_RS400))
+
 /*
  * Errata workarounds
  */
@@ -745,152 +769,208 @@ do {									\
     info->fifo_slots -= entries;					\
 } while (0)
 
-extern RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn);
-extern void        RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries);
-extern void        RADEONWaitForIdleMMIO(ScrnInfoPtr pScrn);
+/* legacy_crtc.c */
+extern void legacy_crtc_dpms(xf86CrtcPtr crtc, int mode);
+extern void legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
+				 DisplayModePtr adjusted_mode, int x, int y);
+extern void RADEONInitDispBandwidth(ScrnInfoPtr pScrn);
+extern void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
+					 RADEONSavePtr restore);
+extern void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
+				       RADEONSavePtr restore);
+extern void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
+					RADEONSavePtr restore);
+extern void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
+				      RADEONSavePtr restore);
+extern void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
+				       RADEONSavePtr restore);
+extern void RADEONSaveCommonRegisters(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);
+
+/* legacy_output.c */
+extern RADEONMonitorType legacy_dac_detect(ScrnInfoPtr pScrn,
+					   xf86OutputPtr output);
+extern void legacy_output_dpms(xf86OutputPtr output, int mode);
+extern void legacy_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
+				   DisplayModePtr adjusted_mode);
+extern I2CDevPtr RADEONDVODeviceInit(I2CBusPtr b, I2CSlaveAddr addr);
+extern Bool RADEONDVOReadByte(I2CDevPtr dvo, int addr, CARD8 *ch);
+extern Bool RADEONDVOWriteByte(I2CDevPtr dvo, int addr, CARD8 ch);
+extern void RADEONRestoreDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore);
+extern void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore);
+extern void RADEONRestoreFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr restore);
+extern void RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore);
+extern void RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore);
+extern void RADEONSaveDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
+extern void RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
+
+/* radeon_accel.c */
+extern Bool RADEONAccelInit(ScreenPtr pScreen);
+extern void RADEONEngineFlush(ScrnInfoPtr pScrn);
+extern void RADEONEngineInit(ScrnInfoPtr pScrn);
+extern void RADEONEngineReset(ScrnInfoPtr pScrn);
+extern void RADEONEngineRestore(ScrnInfoPtr pScrn);
+extern CARD8 *RADEONHostDataBlit(ScrnInfoPtr pScrn, unsigned int cpp,
+				 unsigned int w, CARD32 dstPitchOff,
+				 CARD32 *bufPitch, int x, int *y,
+				 unsigned int *h, unsigned int *hpass);
+extern void RADEONHostDataBlitCopyPass(ScrnInfoPtr pScrn,
+				       unsigned int bpp,
+				       CARD8 *dst, CARD8 *src,
+				       unsigned int hpass,
+				       unsigned int dstPitch,
+				       unsigned int srcPitch);
+extern void  RADEONCopySwap(CARD8 *dst, CARD8 *src, unsigned int size, int swap);
+extern void RADEONHostDataParams(ScrnInfoPtr pScrn, CARD8 *dst,
+				 CARD32 pitch, int cpp,
+				 CARD32 *dstPitchOffset, int *x, int *y);
+extern void RADEONInit3DEngine(ScrnInfoPtr pScrn);
+extern void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries);
 #ifdef XF86DRI
-extern int RADEONDRISetParam(ScrnInfoPtr pScrn, unsigned int param, int64_t value);
-extern void        RADEONWaitForIdleCP(ScrnInfoPtr pScrn);
+extern drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn);
+extern void RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard);
+extern void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn);
+extern int RADEONCPStop(ScrnInfoPtr pScrn,  RADEONInfoPtr info);
+#  ifdef USE_XAA
+extern Bool RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen);
+#  endif
 #endif
 
-extern void        RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y,
-				       Bool clone);
-
-extern void        RADEONEngineReset(ScrnInfoPtr pScrn);
-extern void        RADEONEngineFlush(ScrnInfoPtr pScrn);
-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);
+#ifdef USE_XAA
+/* radeon_accelfuncs.c */
+extern void RADEONAccelInitMMIO(ScreenPtr pScreen, XAAInfoRecPtr a);
+extern Bool RADEONSetupMemXAA(int scrnIndex, ScreenPtr pScreen);
+#endif
 
-extern void        RADEONWaitForVerticalSync(ScrnInfoPtr pScrn);
-extern void        RADEONWaitForVerticalSync2(ScrnInfoPtr pScrn);
+/* radeon_bios.c */
+extern Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10);
+extern Bool RADEONGetClockInfoFromBIOS(ScrnInfoPtr pScrn);
+extern Bool RADEONGetConnectorInfoFromBIOS(ScrnInfoPtr pScrn);
+extern Bool RADEONGetDAC2InfoFromBIOS(xf86OutputPtr output);
+extern Bool RADEONGetExtTMDSInfoFromBIOS(xf86OutputPtr output);
+extern Bool RADEONGetHardCodedEDIDFromBIOS(xf86OutputPtr output);
+extern Bool RADEONGetBIOSInitTableOffsets(ScrnInfoPtr pScrn);
+extern Bool RADEONGetLVDSInfoFromBIOS(xf86OutputPtr output);
+extern Bool RADEONGetTMDSInfoFromBIOS(xf86OutputPtr output);
+extern Bool RADEONGetTVInfoFromBIOS(xf86OutputPtr output);
+extern Bool RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output);
+extern Bool RADEONPostCardFromBIOSTables(ScrnInfoPtr pScrn);
+
+/* radeon_commonfuncs.c */
+#ifdef XF86DRI
+extern void RADEONWaitForIdleCP(ScrnInfoPtr pScrn);
+#endif
+extern void RADEONWaitForIdleMMIO(ScrnInfoPtr pScrn);
 
-extern void        RADEONChangeSurfaces(ScrnInfoPtr pScrn);
+/* radeon_crtc.c */
+extern void radeon_crtc_load_lut(xf86CrtcPtr crtc);
+extern Bool RADEONAllocateControllers(ScrnInfoPtr pScrn, int mask);
+extern void RADEONBlank(ScrnInfoPtr pScrn);
+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);
+extern DisplayModePtr RADEONCrtcFindClosestMode(xf86CrtcPtr crtc,
+						DisplayModePtr pMode);
+extern void RADEONUnblank(ScrnInfoPtr pScrn);
+extern Bool RADEONSetTiling(ScrnInfoPtr pScrn);
+
+/* radeon_cursor.c */
+extern Bool RADEONCursorInit(ScreenPtr pScreen);
+extern void radeon_crtc_hide_cursor(xf86CrtcPtr crtc);
+extern void radeon_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image);
+extern void radeon_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg);
+extern void radeon_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y);
+extern void radeon_crtc_show_cursor(xf86CrtcPtr crtc);
+
+/* radeon_dga.c */
+extern Bool RADEONDGAInit(ScreenPtr pScreen);
 
-extern Bool        RADEONAccelInit(ScreenPtr pScreen);
-#ifdef USE_EXA
-extern Bool        RADEONSetupMemEXA (ScreenPtr pScreen);
-extern Bool        RADEONDrawInitMMIO(ScreenPtr pScreen);
 #ifdef XF86DRI
-extern unsigned long long RADEONTexOffsetStart(PixmapPtr pPix);
-extern Bool        RADEONGetDatatypeBpp(int bpp, CARD32 *type);
-extern Bool        RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
-					      CARD32 *pitch_offset);
-extern Bool        RADEONDrawInitCP(ScreenPtr pScreen);
-extern void        RADEONDoPrepareCopyCP(ScrnInfoPtr pScrn,
-					 CARD32 src_pitch_offset,
-					 CARD32 dst_pitch_offset,
-					 CARD32 datatype, int rop,
-					 Pixel planemask);
-extern void        RADEONCopyCP(PixmapPtr pDst, int srcX, int srcY, int dstX,
-				int dstY, int w, int h);
-#endif
-#endif
-#ifdef USE_XAA
-extern void        RADEONAccelInitMMIO(ScreenPtr pScreen, XAAInfoRecPtr a);
+/* radeon_dri.c */
+extern void RADEONDRIAllocatePCIGARTTable(ScreenPtr pScreen);
+extern void RADEONDRICloseScreen(ScreenPtr pScreen);
+extern Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen);
+extern int RADEONDRIGetPciAperTableSize(ScrnInfoPtr pScrn);
+extern Bool RADEONDRIGetVersion(ScrnInfoPtr pScrn);
+extern void RADEONDRIResume(ScreenPtr pScreen);
+extern Bool RADEONDRIScreenInit(ScreenPtr pScreen);
+extern int RADEONDRISetParam(ScrnInfoPtr pScrn,
+			     unsigned int param, int64_t value);
+extern Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on);
+extern void RADEONDRIStop(ScreenPtr pScreen);
 #endif
-extern void        RADEONEngineInit(ScrnInfoPtr pScrn);
-extern Bool        RADEONCursorInit(ScreenPtr pScreen);
-extern Bool        RADEONDGAInit(ScreenPtr pScreen);
-
-extern void        RADEONInit3DEngine(ScrnInfoPtr pScrn);
-
-extern int         RADEONMinBits(int val);
-
-extern void        RADEONInitVideo(ScreenPtr pScreen);
-extern void        RADEONResetVideo(ScrnInfoPtr pScrn);
-extern void        R300CGWorkaround(ScrnInfoPtr pScrn);
-
-extern void        RADEONPllErrataAfterIndex(RADEONInfoPtr info);
-extern void        RADEONPllErrataAfterData(RADEONInfoPtr info);
-
-extern Bool        RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10);
-extern Bool        RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn);
-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,
-						RADEONSavePtr restore);
-extern void        RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
-						RADEONSavePtr restore);
-extern void        RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
-					      RADEONSavePtr restore);
-extern void        RADEONRestoreDACRegisters(ScrnInfoPtr pScrn,
-					     RADEONSavePtr restore);
-extern void        RADEONRestoreFPRegisters(ScrnInfoPtr pScrn,
-					    RADEONSavePtr restore);
-extern void        RADEONRestoreFP2Registers(ScrnInfoPtr pScrn,
-					     RADEONSavePtr restore);
-extern void        RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn,
-					      RADEONSavePtr restore);
-extern void        RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn,
-					     RADEONSavePtr restore);
-extern void        RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
-					     RADEONSavePtr restore);
-extern void        RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
-					       RADEONSavePtr restore);
-extern void        RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
-					      RADEONSavePtr restore);
-
-extern void        RADEONInitMemMapRegisters(ScrnInfoPtr pScrn,
-					     RADEONSavePtr save,
-					     RADEONInfoPtr info);
-extern void        RADEONInitDispBandwidth(ScrnInfoPtr pScrn);
-extern Bool        RADEONI2cInit(ScrnInfoPtr pScrn);
-extern Bool        RADEONSetupConnectors(ScrnInfoPtr pScrn);
-extern void        RADEONPrintPortMap(ScrnInfoPtr pScrn);
-extern void        RADEONDisableDisplays(ScrnInfoPtr pScrn);
-extern void        RADEONGetPanelInfo(ScrnInfoPtr pScrn);
-extern void        RADEONUnblank(ScrnInfoPtr pScrn);
-extern void        RADEONUnblank(ScrnInfoPtr pScrn);
-extern void        RADEONBlank(ScrnInfoPtr pScrn);
 
-extern Bool RADEONAllocateControllers(ScrnInfoPtr pScrn, int mask);
-extern Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn);
+/* radeon_driver.c */
+extern void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, Bool clone);
+extern void RADEONChangeSurfaces(ScrnInfoPtr pScrn);
+extern RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn);
+extern int RADEONMinBits(int val);
+extern unsigned RADEONINMC(ScrnInfoPtr pScrn, int addr);
+extern unsigned RADEONINPLL(ScrnInfoPtr pScrn, int addr);
+extern void RADEONOUTMC(ScrnInfoPtr pScrn, int addr, CARD32 data);
+extern void RADEONOUTPLL(ScrnInfoPtr pScrn, int addr, CARD32 data);
+extern void RADEONPllErrataAfterData(RADEONInfoPtr info);
+extern void RADEONPllErrataAfterIndex(RADEONInfoPtr info);
+extern void RADEONWaitForVerticalSync(ScrnInfoPtr pScrn);
+extern void RADEONWaitForVerticalSync2(ScrnInfoPtr pScrn);
+extern void RADEONInitMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
+				      RADEONInfoPtr info);
+extern void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
+					 RADEONSavePtr restore);
 
-extern void RADEONSetPitch (ScrnInfoPtr pScrn);
-extern void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode);
+#ifdef USE_EXA
+/* radeon_exa.c */
+extern Bool RADEONSetupMemEXA(ScreenPtr pScreen);
+
+/* radeon_exa_funcs.c */
+extern void RADEONCopyCP(PixmapPtr pDst, int srcX, int srcY, int dstX,
+			 int dstY, int w, int h);
+extern void RADEONCopyMMIO(PixmapPtr pDst, int srcX, int srcY, int dstX,
+			   int dstY, int w, int h);
+extern Bool RADEONDrawInitCP(ScreenPtr pScreen);
+extern Bool RADEONDrawInitMMIO(ScreenPtr pScreen);
+extern void RADEONDoPrepareCopyCP(ScrnInfoPtr pScrn,
+				  CARD32 src_pitch_offset,
+				  CARD32 dst_pitch_offset,
+				  CARD32 datatype, int rop,
+				  Pixel planemask);
+extern void RADEONDoPrepareCopyMMIO(ScrnInfoPtr pScrn,
+				    CARD32 src_pitch_offset,
+				    CARD32 dst_pitch_offset,
+				    CARD32 datatype, int rop,
+				    Pixel planemask);
+#endif
 
-extern DisplayModePtr
-RADEONProbeOutputModes(xf86OutputPtr output);
-
-extern Bool
-RADEONDVOReadByte(I2CDevPtr dvo, int addr, CARD8 *ch);
-extern Bool
-RADEONDVOWriteByte(I2CDevPtr dvo, int addr, CARD8 ch);
-extern Bool
-RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output);
-extern Bool
-RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output);
-
-extern RADEONI2CBusRec
-legacy_setup_i2c_bus(int ddc_line);
-extern RADEONI2CBusRec
-atom_setup_i2c_bus(int ddc_line);
-
-extern void
-radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y);
-extern void
-radeon_crtc_show_cursor (xf86CrtcPtr crtc);
-extern void
-radeon_crtc_hide_cursor (xf86CrtcPtr crtc);
-extern void
-radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y);
-extern void
-radeon_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg);
-extern void
-radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image);
-extern void
-radeon_crtc_load_lut(xf86CrtcPtr crtc);
+#if defined(XF86DRI) && defined(USE_EXA)
+/* radeon_exa.c */
+extern Bool RADEONGetDatatypeBpp(int bpp, CARD32 *type);
+extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
+				       CARD32 *pitch_offset);
+extern unsigned long long RADEONTexOffsetStart(PixmapPtr pPix);
+#endif
 
+/* radeon_modes.c */
+extern void RADEONSetPitch(ScrnInfoPtr pScrn);
+extern DisplayModePtr RADEONProbeOutputModes(xf86OutputPtr output);
+
+/* radeon_output.c */
+extern RADEONI2CBusRec atom_setup_i2c_bus(int ddc_line);
+extern RADEONI2CBusRec legacy_setup_i2c_bus(int ddc_line);
+extern void RADEONConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output);
+extern void RADEONGetPanelInfo(ScrnInfoPtr pScrn);
+extern void RADEONInitConnector(xf86OutputPtr output);
+extern void RADEONPrintPortMap(ScrnInfoPtr pScrn);
+extern void RADEONSetOutputType(ScrnInfoPtr pScrn,
+				RADEONOutputPrivatePtr radeon_output);
+extern Bool RADEONSetupConnectors(ScrnInfoPtr pScrn);
+
+/* radeon_tv.c */
+extern void RADEONSaveTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
 extern void RADEONAdjustCrtcRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
 					   DisplayModePtr mode, xf86OutputPtr output);
 extern void RADEONAdjustPLLRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
@@ -901,47 +981,18 @@ extern void RADEONAdjustPLL2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save
 					  DisplayModePtr mode, xf86OutputPtr output);
 extern void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
                                   DisplayModePtr mode, BOOL IsPrimary);
-
 extern void RADEONRestoreTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore);
+extern void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode);
 
-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);
+/* radeon_video.c */
+extern void RADEONInitVideo(ScreenPtr pScreen);
+extern void RADEONResetVideo(ScrnInfoPtr pScrn);
 
 #ifdef XF86DRI
-#ifdef USE_XAA
-extern void        RADEONAccelInitCP(ScreenPtr pScreen, XAAInfoRecPtr a);
-#endif
-extern Bool        RADEONDRIGetVersion(ScrnInfoPtr pScrn);
-extern Bool        RADEONDRIScreenInit(ScreenPtr pScreen);
-extern void        RADEONDRICloseScreen(ScreenPtr pScreen);
-extern void        RADEONDRIResume(ScreenPtr pScreen);
-extern Bool        RADEONDRIFinishScreenInit(ScreenPtr pScreen);
-extern void        RADEONDRIAllocatePCIGARTTable(ScreenPtr pScreen);
-extern int         RADEONDRIGetPciAperTableSize(ScrnInfoPtr pScrn);
-extern void        RADEONDRIStop(ScreenPtr pScreen);
-
-extern drmBufPtr   RADEONCPGetBuffer(ScrnInfoPtr pScrn);
-extern void        RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard);
-extern void        RADEONCPReleaseIndirect(ScrnInfoPtr pScrn);
-extern int         RADEONCPStop(ScrnInfoPtr pScrn,  RADEONInfoPtr info);
-extern Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on);
-
-extern void        RADEONHostDataParams(ScrnInfoPtr pScrn, CARD8 *dst,
-					CARD32 pitch, int cpp,
-					CARD32 *dstPitchOffset, int *x, int *y);
-extern CARD8*      RADEONHostDataBlit(ScrnInfoPtr pScrn, unsigned int cpp,
-				      unsigned int w, CARD32 dstPitchOff,
-				      CARD32 *bufPitch, int x, int *y,
-				      unsigned int *h, unsigned int *hpass);
-extern void        RADEONHostDataBlitCopyPass(ScrnInfoPtr pScrn,
-					      unsigned int bpp,
-					      CARD8 *dst, CARD8 *src,
-					      unsigned int hpass,
-					      unsigned int dstPitch,
-					      unsigned int srcPitch);
-extern void        RADEONCopySwap(CARD8 *dst, CARD8 *src, unsigned int size,
-				  int swap);
+#  ifdef USE_XAA
+/* radeon_accelfuncs.c */
+extern void RADEONAccelInitCP(ScreenPtr pScreen, XAAInfoRecPtr a);
+#  endif
 
 #define RADEONCP_START(pScrn, info)					\
 do {									\
@@ -998,11 +1049,18 @@ do {									\
 	    info->needCacheFlush = FALSE;				\
 	}								\
 	RADEON_WAIT_UNTIL_IDLE();					\
-	BEGIN_RING(6);							\
-	OUT_RING_REG(RADEON_RE_TOP_LEFT,     info->re_top_left);	\
-	OUT_RING_REG(RADEON_RE_WIDTH_HEIGHT, info->re_width_height);	\
-	OUT_RING_REG(RADEON_AUX_SC_CNTL,     info->aux_sc_cntl);	\
-	ADVANCE_RING();							\
+        if (info->ChipFamily <= CHIP_FAMILY_RV280) {                    \
+	    BEGIN_RING(6);						\
+	    OUT_RING_REG(RADEON_RE_TOP_LEFT,     info->re_top_left);	\
+	    OUT_RING_REG(RADEON_RE_WIDTH_HEIGHT, info->re_width_height); \
+	    OUT_RING_REG(RADEON_AUX_SC_CNTL,     info->aux_sc_cntl);	\
+	    ADVANCE_RING();						\
+        } else {                                                        \
+            BEGIN_RING(4);                                              \
+            OUT_RING_REG(R300_SC_SCISSOR0, info->re_top_left);          \
+	    OUT_RING_REG(R300_SC_SCISSOR1, info->re_width_height);      \
+            ADVANCE_RING();                                             \
+	}                                                               \
 	info->CPInUse = TRUE;						\
     }									\
 } while (0)
diff --git a/src/radeon_accel.c b/src/radeon_accel.c
index 8b2f167..015d176 100644
--- a/src/radeon_accel.c
+++ b/src/radeon_accel.c
@@ -390,8 +390,12 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
     info->sc_bottom       = RADEON_DEFAULT_SC_BOTTOM_MAX;
 
     info->re_top_left     = 0x00000000;
-    info->re_width_height = ((0x7ff << RADEON_RE_WIDTH_SHIFT) |
-			     (0x7ff << RADEON_RE_HEIGHT_SHIFT));
+    if (info->ChipFamily <= CHIP_FAMILY_RV280)
+	info->re_width_height = ((0x7ff << RADEON_RE_WIDTH_SHIFT) |
+				 (0x7ff << RADEON_RE_HEIGHT_SHIFT));
+    else
+	info->re_width_height = ((8191 << R300_SCISSOR_X_SHIFT) |
+				 (8191 << R300_SCISSOR_Y_SHIFT));
 
     info->aux_sc_cntl     = 0x00000000;
 #endif
diff --git a/src/radeon_accelfuncs.c b/src/radeon_accelfuncs.c
index e3b37c1..bda15ff 100644
--- a/src/radeon_accelfuncs.c
+++ b/src/radeon_accelfuncs.c
@@ -1302,15 +1302,16 @@ FUNC_NAME(RADEONAccelInit)(ScreenPtr pScreen, XAAInfoRecPtr a)
 	a->CPUToScreenTextureDstFormats = RADEONDstFormats;
 
 	if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration "
-		       "unsupported on Radeon 9500/9700 and newer.\n");
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "XAA Render acceleration "
+		       "unsupported on Radeon 9500/9700 and newer. "
+		       "Please use EXA instead.\n");
 	} else if ((info->ChipFamily == CHIP_FAMILY_RV250) || 
 		   (info->ChipFamily == CHIP_FAMILY_RV280) || 
 		   (info->ChipFamily == CHIP_FAMILY_RS300) || 
 		   (info->ChipFamily == CHIP_FAMILY_R200)) {
 	    a->SetupForCPUToScreenAlphaTexture2 =
 		FUNC_NAME(R200SetupForCPUToScreenAlphaTexture);
-	    a->SubsequentCPUToScreenAlphaTexture = 
+	    a->SubsequentCPUToScreenAlphaTexture =
 		FUNC_NAME(R200SubsequentCPUToScreenTexture);
 
 	    a->SetupForCPUToScreenTexture2 =
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index 88c220b..224aae3 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -35,6 +35,8 @@
 #include "radeon_probe.h"
 #include "radeon_macros.h"
 
+#include "ati_pciids_gen.h"
+
 #include "xorg-server.h"
 
 /* only for testing now */
@@ -517,25 +519,52 @@ rhdAtomASICInit(atomBiosHandlePtr handle)
     return FALSE;
 }
 
-Bool
-rhdAtomSetScaler(atomBiosHandlePtr handle, unsigned char scalerID, int setting)
+int
+atombios_dyn_clk_setup(ScrnInfoPtr pScrn, int enable)
 {
-    ENABLE_SCALER_PARAMETERS scaler;
+    RADEONInfoPtr info       = RADEONPTR(pScrn);
+    DYNAMIC_CLOCK_GATING_PS_ALLOCATION dynclk_data;
     AtomBiosArgRec data;
+    unsigned char *space;
 
-    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;
+    dynclk_data.ucEnable = enable;
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, DynamicClockGating);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &dynclk_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Dynamic clock gating %s success\n", enable? "enable" : "disable");
+	return ATOM_SUCCESS;
     }
-    xf86DrvMsg(handle->scrnIndex, X_INFO, "EableScaler Failed\n");
-    return FALSE;
+
+    ErrorF("Dynamic clock gating %s failure\n", enable? "enable" : "disable");
+    return ATOM_NOT_IMPLEMENTED;
+
+}
+
+int
+atombios_static_pwrmgt_setup(ScrnInfoPtr pScrn, int enable)
+{
+    RADEONInfoPtr info       = RADEONPTR(pScrn);
+    ENABLE_ASIC_STATIC_PWR_MGT_PS_ALLOCATION pwrmgt_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    pwrmgt_data.ucEnable = enable;
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, EnableASIC_StaticPwrMgt);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &pwrmgt_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Static power management %s success\n", enable? "enable" : "disable");
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Static power management %s failure\n", enable? "enable" : "disable");
+    return ATOM_NOT_IMPLEMENTED;
+
 }
 
 # endif
@@ -1399,7 +1428,7 @@ const int object_connector_convert[] =
       CONNECTOR_NONE,
       CONNECTOR_NONE,
       CONNECTOR_NONE,
-      CONNECTOR_NONE,
+      CONNECTOR_DISPLAY_PORT,
     };
 
 static void
@@ -1499,6 +1528,7 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
     unsigned short size;
     atomDataTablesPtr atomDataPtr;
     ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
+    ATOM_INTEGRATED_SYSTEM_INFO_V2 *igp_obj = NULL;
     int i, j, ddc_line = 0;
 
     atomDataPtr = info->atomBIOS->atomDataPtr;
@@ -1507,7 +1537,7 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 
     if (crev < 2)
 	return FALSE;
-    
+
     con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *)
 	((char *)&atomDataPtr->Object_Header->sHeader +
 	 atomDataPtr->Object_Header->usConnectorObjectTableOffset);
@@ -1527,10 +1557,34 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 	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;
+
+	if ((info->ChipFamily == CHIP_FAMILY_RS780) &&
+	    (obj_id == CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) {
+	    CARD32 slot_config, ct;
+
+	    igp_obj = info->atomBIOS->atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo_v2;
+
+	    if (!igp_obj)
+		info->BiosConnector[i].ConnectorType = object_connector_convert[obj_id];
+	    else {
+		if (num == 1)
+		    slot_config = igp_obj->ulDDISlot1Config;
+		else
+		    slot_config = igp_obj->ulDDISlot2Config;
+
+		ct = (slot_config  >> 16) & 0xff;
+		info->BiosConnector[i].ConnectorType = object_connector_convert[ct];
+		info->BiosConnector[i].igp_lane_info = slot_config & 0xffff;
+	    }
+	} else
+	    info->BiosConnector[i].ConnectorType = object_connector_convert[obj_id];
+
+	if (info->BiosConnector[i].ConnectorType == CONNECTOR_NONE)
+	    info->BiosConnector[i].valid = FALSE;
+	else
+	    info->BiosConnector[i].valid = TRUE;
 	info->BiosConnector[i].devices = 0;
 
 	for (j = 0; j < SrcDstTable->ucNumberOfSrc; j++) {
@@ -1538,7 +1592,7 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 
 	    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);
@@ -1548,6 +1602,13 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 		info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP1_INDEX);
 		info->BiosConnector[i].TMDSType = TMDS_INT;
 		break;
+	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+		if (num == 1)
+		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP1_INDEX);
+		else
+		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP2_INDEX);
+		info->BiosConnector[i].TMDSType = TMDS_UNIPHY;
+		break;
 	    case ENCODER_OBJECT_ID_INTERNAL_TMDS2:
 	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
 		info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP2_INDEX);
@@ -1560,7 +1621,13 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 		break;
 	    case ENCODER_OBJECT_ID_INTERNAL_DAC1:
 	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-		info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_CRT1_INDEX);
+		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);
+		    info->BiosConnector[i].valid = FALSE;
+		else
+		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_CRT1_INDEX);
 		info->BiosConnector[i].DACType = DAC_PRIMARY;
 		break;
 	    case ENCODER_OBJECT_ID_INTERNAL_DAC2:
@@ -1568,7 +1635,8 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 		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);
+		    //info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_TV1_INDEX);
+		    info->BiosConnector[i].valid = FALSE;
 		else
 		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_CRT2_INDEX);
 		info->BiosConnector[i].DACType = DAC_TVDAC;
@@ -1588,7 +1656,7 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 	    ErrorF("record type %d\n", Record->ucRecordType);
 	    switch (Record->ucRecordType) {
 		case ATOM_I2C_RECORD_TYPE:
-		    rhdAtomParseI2CRecord(info->atomBIOS, 
+		    rhdAtomParseI2CRecord(info->atomBIOS,
 					  (ATOM_I2C_RECORD *)Record,
 					  &ddc_line);
 		    info->BiosConnector[i].ddc_i2c = atom_setup_i2c_bus(ddc_line);
@@ -1708,6 +1776,22 @@ RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_
     return TRUE;
 }
 
+static void RADEONApplyATOMQuirks(ScrnInfoPtr pScrn, int index)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+
+    /* Asus M2A-VM HDMI board lists the DVI port as HDMI */
+    if ((info->Chipset == PCI_CHIP_RS690_791E) &&
+	(PCI_SUB_VENDOR_ID(info->PciInfo) == 0x1043) &&
+	(PCI_SUB_DEVICE_ID(info->PciInfo) == 0x826d)) {
+	if ((info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_A) &&
+	    (info->BiosConnector[index].TMDSType == TMDS_LVTMA)) {
+	    info->BiosConnector[index].ConnectorType = CONNECTOR_DVI_D;
+	}
+    }
+
+}
+
 Bool
 RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 {
@@ -1745,12 +1829,7 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 
 	info->BiosConnector[i].valid = TRUE;
 	info->BiosConnector[i].output_id = ci.sucI2cId.sbfAccess.bfI2C_LineMux;
-	if (info->IsIGP && (i == ATOM_DEVICE_DFP2_INDEX))
-	    info->BiosConnector[i].devices = (1 << ATOM_DEVICE_DFP3_INDEX);
-	else if (info->IsIGP && (i == ATOM_DEVICE_DFP3_INDEX))
-	    info->BiosConnector[i].devices = (1 << ATOM_DEVICE_DFP2_INDEX);
-	else
-	    info->BiosConnector[i].devices = (1 << i);
+	info->BiosConnector[i].devices = (1 << i);
 	info->BiosConnector[i].ConnectorType = ci.sucConnectorInfo.sbfAccess.bfConnectorType;
 	info->BiosConnector[i].DACType = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC;
 
@@ -1759,14 +1838,15 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 	    (i == ATOM_DEVICE_TV2_INDEX) ||
 	    (i == ATOM_DEVICE_CV_INDEX))
 	    info->BiosConnector[i].ddc_i2c.valid = FALSE;
-	else if ((i == ATOM_DEVICE_DFP3_INDEX) && info->IsIGP) {
-	    /* DDIA port uses non-standard gpio entry */
-	    if (info->BiosConnector[ATOM_DEVICE_DFP2_INDEX].valid)
+	else if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+		 (info->ChipFamily == CHIP_FAMILY_RS740)) {
+	    /* IGP DFP ports use non-standard gpio entries */
+	    if ((i == ATOM_DEVICE_DFP2_INDEX) || (i == ATOM_DEVICE_DFP3_INDEX))
 		info->BiosConnector[i].ddc_i2c =
-		    RADEONLookupGPIOLineForDDC(pScrn, ci.sucI2cId.sbfAccess.bfI2C_LineMux + 2);
+		    RADEONLookupGPIOLineForDDC(pScrn, ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1);
 	    else
 		info->BiosConnector[i].ddc_i2c =
-		    RADEONLookupGPIOLineForDDC(pScrn, ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1);
+		    RADEONLookupGPIOLineForDDC(pScrn, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
 	} else
 	    info->BiosConnector[i].ddc_i2c =
 		RADEONLookupGPIOLineForDDC(pScrn, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
@@ -1774,16 +1854,14 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 	if (i == ATOM_DEVICE_DFP1_INDEX)
 	    info->BiosConnector[i].TMDSType = TMDS_INT;
 	else if (i == ATOM_DEVICE_DFP2_INDEX) {
-	    if (info->IsIGP)
-		info->BiosConnector[i].TMDSType = TMDS_LVTMA;
-	    else
-		info->BiosConnector[i].TMDSType = TMDS_EXT;
-	} else if (i == ATOM_DEVICE_DFP3_INDEX) {
-	    if (info->IsIGP)
+	    if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+		(info->ChipFamily == CHIP_FAMILY_RS740))
 		info->BiosConnector[i].TMDSType = TMDS_DDIA;
 	    else
-		info->BiosConnector[i].TMDSType = TMDS_LVTMA;
-	} else
+		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
@@ -1816,6 +1894,9 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 	} else {
 	    info->BiosConnector[i].hpd_mask = 0;
 	}
+
+	RADEONApplyATOMQuirks(pScrn, i);
+
     }
 
     /* CRTs/DFPs may share a port */
@@ -1859,689 +1940,6 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
     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,
diff --git a/src/radeon_atombios.h b/src/radeon_atombios.h
index 9cb279e..955f2e4 100644
--- a/src/radeon_atombios.h
+++ b/src/radeon_atombios.h
@@ -116,6 +116,12 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn);
 extern Bool
 RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn);
 
+extern int
+atombios_dyn_clk_setup(ScrnInfoPtr pScrn, int enable);
+
+extern int
+atombios_static_pwrmgt_setup(ScrnInfoPtr pScrn, int enable);
+
 extern Bool
 RADEONGetATOMTVInfo(xf86OutputPtr output);
 
diff --git a/src/radeon_atomwrapper.c b/src/radeon_atomwrapper.c
index 259366c..3e7ae01 100644
--- a/src/radeon_atomwrapper.c
+++ b/src/radeon_atomwrapper.c
@@ -27,7 +27,7 @@
 # include "config.h"
 #endif
 
-//#include "radeon_atomwrapper.h"
+#include "radeon_atomwrapper.h"
 
 #define INT32 INT32
 #include "CD_Common_Types.h"
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 8e6bd8d..6be3528 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -75,7 +75,8 @@ Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
 
 #ifdef XSERVER_LIBPCIACCESS
     //info->VBIOS = xalloc(info->PciInfo->rom_size);
-    info->VBIOS = xalloc(RADEON_VBIOS_SIZE);
+    int size = info->PciInfo->rom_size > RADEON_VBIOS_SIZE ? info->PciInfo->rom_size : RADEON_VBIOS_SIZE;
+    info->VBIOS = xalloc(size);
 #else
     info->VBIOS = xalloc(RADEON_VBIOS_SIZE);
 #endif
@@ -216,6 +217,54 @@ static Bool RADEONGetATOMConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
     return FALSE;
 }
 
+static void RADEONApplyLegacyQuirks(ScrnInfoPtr pScrn, int index)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+
+    /* most XPRESS chips seem to specify DDC_CRT2 for their 
+     * VGA DDC port, however DDC never seems to work on that
+     * port.  Some have reported success on DDC_MONID, so 
+     * lets see what happens with that.
+     */
+    if (info->ChipFamily == CHIP_FAMILY_RS400 &&
+	info->BiosConnector[index].ConnectorType == CONNECTOR_VGA &&
+	info->BiosConnector[index].ddc_i2c.mask_clk_reg == RADEON_GPIO_CRT2_DDC) {
+	info->BiosConnector[index].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[index].ConnectorType == CONNECTOR_LVDS)) {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "Proprietary connector found, assuming DVI-D\n");
+	info->BiosConnector[index].DACType = DAC_NONE;
+	info->BiosConnector[index].TMDSType = TMDS_EXT;
+	info->BiosConnector[index].ConnectorType = CONNECTOR_DVI_D;
+    }
+
+    /* Certain IBM chipset RN50s have a BIOS reporting two VGAs,
+       one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */
+    if (info->Chipset == PCI_CHIP_RN50_515E &&
+	PCI_SUB_VENDOR_ID(info->PciInfo) == 0x1014) {
+	if (info->BiosConnector[index].ConnectorType == CONNECTOR_VGA &&
+	    info->BiosConnector[index].ddc_i2c.mask_clk_reg == RADEON_GPIO_CRT2_DDC) {
+	    info->BiosConnector[index].valid = FALSE;
+	}
+    }
+
+    /* Some RV100 cards with 2 VGA ports show up with DVI+VGA */
+    if (info->Chipset == PCI_CHIP_RV100_QY &&
+	PCI_SUB_VENDOR_ID(info->PciInfo) == 0x1002 &&
+	PCI_SUB_DEVICE_ID(info->PciInfo) == 0x013a) {
+	if (info->BiosConnector[index].ConnectorType == CONNECTOR_DVI_I) {
+	    info->BiosConnector[index].ConnectorType = CONNECTOR_VGA;
+	}
+    }
+
+}
+
 static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info = RADEONPTR (pScrn);
@@ -297,28 +346,8 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    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
-	     * port.  Some have reported success on DDC_MONID, so 
-	     * lets see what happens with that.
-	     */
-	    if (info->ChipFamily == CHIP_FAMILY_RS400 &&
-		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);
-	    }
+	    RADEONApplyLegacyQuirks(pScrn, i);
 
-	    /* 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_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;
-	    }
 	}
     } else {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Connector Info Table found!\n");
@@ -620,6 +649,9 @@ Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output)
 
     if (!info->VBIOS) return FALSE;
 
+    if (xf86ReturnOptValBool(info->Options, OPTION_DEFAULT_TVDAC_ADJ, FALSE))
+	return FALSE;
+
     if (info->IsAtomBios) {
 	/* not implemented yet */
 	return FALSE;
@@ -628,7 +660,21 @@ Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output)
 	offset = RADEON_BIOS16(info->ROMHeaderStart + 0x32);
         if (offset) {
 	    rev = RADEON_BIOS8(offset + 0x3);
-	    if (rev > 1) {
+	    if (rev > 4) {
+		bg = RADEON_BIOS8(offset + 0xc) & 0xf;
+		dac = RADEON_BIOS8(offset + 0xd) & 0xf;
+		radeon_output->ps2_tvdac_adj = (bg << 16) | (dac << 20);
+
+		bg = RADEON_BIOS8(offset + 0xe) & 0xf;
+		dac = RADEON_BIOS8(offset + 0xf) & 0xf;
+		radeon_output->pal_tvdac_adj = (bg << 16) | (dac << 20);
+
+		bg = RADEON_BIOS8(offset + 0x10) & 0xf;
+		dac = RADEON_BIOS8(offset + 0x11) & 0xf;
+		radeon_output->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
+
+		return TRUE;
+	    } else 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);
@@ -656,6 +702,14 @@ Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output)
 		radeon_output->ntsc_tvdac_adj = radeon_output->ps2_tvdac_adj;
 
 		return TRUE;
+	    } else {
+		bg = RADEON_BIOS8(offset + 0x4) & 0xf;
+		dac = RADEON_BIOS8(offset + 0x5) & 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;
 	    }
 	}
     }
diff --git a/src/radeon_chipinfo_gen.h b/src/radeon_chipinfo_gen.h
index 420f5d8..de1d109 100644
--- a/src/radeon_chipinfo_gen.h
+++ b/src/radeon_chipinfo_gen.h
@@ -106,7 +106,7 @@ RADEONCardInfo RADEONCards[] = {
  { 0x5964, CHIP_FAMILY_RV280, 0, 0, 0, 0, 0 },
  { 0x5965, CHIP_FAMILY_RV280, 0, 0, 0, 0, 0 },
  { 0x5969, CHIP_FAMILY_RV100, 0, 0, 1, 0, 0 },
- { 0x5974, CHIP_FAMILY_RS400, 0, 1, 0, 0, 1 },
+ { 0x5974, CHIP_FAMILY_RS400, 1, 1, 0, 0, 1 },
  { 0x5975, CHIP_FAMILY_RS400, 1, 1, 0, 0, 1 },
  { 0x5A41, CHIP_FAMILY_RS400, 0, 1, 0, 0, 1 },
  { 0x5A42, CHIP_FAMILY_RS400, 1, 1, 0, 0, 1 },
@@ -201,9 +201,9 @@ RADEONCardInfo RADEONCards[] = {
  { 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 },
+ { 0x7200, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 },
+ { 0x7210, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 },
+ { 0x7211, CHIP_FAMILY_RV515, 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 },
@@ -276,4 +276,23 @@ RADEONCardInfo RADEONCards[] = {
  { 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 },
+ { 0x95C0, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
+ { 0x95C5, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
+ { 0x95C7, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
+ { 0x95C2, CHIP_FAMILY_RV620, 1, 0, 0, 0, 0 },
+ { 0x95C4, CHIP_FAMILY_RV620, 1, 0, 0, 0, 0 },
+ { 0x95CD, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
+ { 0x95CE, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
+ { 0x95CF, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
+ { 0x9590, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 },
+ { 0x9596, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 },
+ { 0x9597, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 },
+ { 0x9598, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 },
+ { 0x9599, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 },
+ { 0x9591, CHIP_FAMILY_RV635, 1, 0, 0, 0, 0 },
+ { 0x9593, CHIP_FAMILY_RV635, 1, 0, 0, 0, 0 },
+ { 0x9610, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 },
+ { 0x9611, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 },
+ { 0x9612, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 },
+ { 0x9613, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 },
 };
diff --git a/src/radeon_chipset_gen.h b/src/radeon_chipset_gen.h
index e6890be..b668823 100644
--- a/src/radeon_chipset_gen.h
+++ b/src/radeon_chipset_gen.h
@@ -201,9 +201,9 @@ static SymTabRec RADEONChipsets[] = {
   { 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_RV515_7200, "ATI Radeon X2300HD" },
+  { PCI_CHIP_RV515_7210, "ATI Mobility Radeon HD 2300" },
+  { PCI_CHIP_RV515_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" },
@@ -250,13 +250,13 @@ static SymTabRec RADEONChipsets[] = {
   { 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_94C4, "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_94CB, "ATI RADEON E2400" },
   { PCI_CHIP_RV610_94CC, "ATI RV610" },
   { PCI_CHIP_RV670_9500, "ATI RV670" },
   { PCI_CHIP_RV670_9501, "ATI Radeon HD3870" },
@@ -267,14 +267,33 @@ static SymTabRec RADEONChipsets[] = {
   { 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_9586, "ATI Radeon HD 2600 XT AGP" },
+  { PCI_CHIP_RV630_9587, "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_958B, "ATI Gemini 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" },
+  { PCI_CHIP_RV630_958E, "ATI Radeon HD 2600 LE" },
+  { PCI_CHIP_RV620_95C0, "ATI Radeon HD 3470" },
+  { PCI_CHIP_RV620_95C5, "ATI Radeon HD 3450" },
+  { PCI_CHIP_RV620_95C7, "ATI Radeon HD 3430" },
+  { PCI_CHIP_RV620_95C2, "ATI Mobility Radeon HD 3430" },
+  { PCI_CHIP_RV620_95C4, "ATI Mobility Radeon HD 3400 Series" },
+  { PCI_CHIP_RV620_95CD, "ATI FireMV 2450" },
+  { PCI_CHIP_RV620_95CE, "ATI FireMV 2260" },
+  { PCI_CHIP_RV620_95CF, "ATI FireMV 2260" },
+  { PCI_CHIP_RV635_9590, "ATI ATI Radeon HD 3600 Series" },
+  { PCI_CHIP_RV635_9596, "ATI ATI Radeon HD 3650 AGP" },
+  { PCI_CHIP_RV635_9597, "ATI ATI Radeon HD 3600 PRO" },
+  { PCI_CHIP_RV635_9598, "ATI ATI Radeon HD 3600 XT" },
+  { PCI_CHIP_RV635_9599, "ATI ATI Radeon HD 3600 PRO" },
+  { PCI_CHIP_RV635_9591, "ATI Mobility Radeon HD 3650" },
+  { PCI_CHIP_RV635_9593, "ATI Mobility Radeon HD 3670" },
+  { PCI_CHIP_RS780_9610, "ATI Radeon HD 3200 Graphics" },
+  { PCI_CHIP_RS780_9611, "ATI Radeon 3100 Graphics" },
+  { PCI_CHIP_RS780_9612, "ATI Radeon HD 3200 Graphics" },
+  { PCI_CHIP_RS780_9613, "ATI Radeon 3100 Graphics" },
   { -1,                 NULL }
 };
diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c
index 0250aef..5c9eae1 100644
--- a/src/radeon_commonfuncs.c
+++ b/src/radeon_commonfuncs.c
@@ -60,7 +60,7 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 
     info->texW[0] = info->texH[0] = info->texW[1] = info->texH[1] = 1;
 
-    if (IS_R300_VARIANT || IS_AVIVO_VARIANT || info->ChipFamily == CHIP_FAMILY_RS690) {
+    if (IS_R300_3D || IS_R500_3D) {
 
 	BEGIN_ACCEL(3);
 	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
@@ -84,7 +84,8 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 	    /* R3xx chips */
 	    gb_tile_config |= R300_PIPE_COUNT_R300;
 	} else if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
-		   (info->ChipFamily == CHIP_FAMILY_RS690)) {
+		   (info->ChipFamily == CHIP_FAMILY_RS690) ||
+		   (info->ChipFamily == CHIP_FAMILY_RS740)) {
 	    /* RV4xx, RS6xx chips */
 	    gb_tile_config |= R300_PIPE_COUNT_R420_3P;
 	} else {
@@ -148,7 +149,20 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 	OUT_ACCEL_REG(R300_SU_DEPTH_OFFSET, 0);
 	FINISH_ACCEL();
 
+	/* setup the VAP */
 	BEGIN_ACCEL(5);
+	/* disable TCL/PVS */
+	OUT_ACCEL_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
+	OUT_ACCEL_REG(R300_VAP_CNTL_STATUS, R300_PVS_BYPASS);
+	OUT_ACCEL_REG(R300_VAP_CNTL, ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
+				      (5 << R300_PVS_NUM_CNTLRS_SHIFT) |
+				      (4 << R300_PVS_NUM_FPUS_SHIFT) |
+				      (5 << R300_VF_MAX_VTX_NUM_SHIFT)));
+	OUT_ACCEL_REG(R300_VAP_VTE_CNTL, R300_VTX_XY_FMT | R300_VTX_Z_FMT);
+	OUT_ACCEL_REG(R300_VAP_PSC_SGN_NORM_CNTL, 0);
+	FINISH_ACCEL();
+
+	BEGIN_ACCEL(4);
 	OUT_ACCEL_REG(R300_US_W_FMT, 0);
 	OUT_ACCEL_REG(R300_US_OUT_FMT_1, (R300_OUT_FMT_UNUSED |
 					  R300_OUT_FMT_C0_SEL_BLUE |
@@ -165,11 +179,6 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 					  R300_OUT_FMT_C1_SEL_GREEN |
 					  R300_OUT_FMT_C2_SEL_RED |
 					  R300_OUT_FMT_C3_SEL_ALPHA));
-	OUT_ACCEL_REG(R300_US_OUT_FMT_0, (R300_OUT_FMT_C4_10 |
-					  R300_OUT_FMT_C0_SEL_BLUE |
-					  R300_OUT_FMT_C1_SEL_GREEN |
-					  R300_OUT_FMT_C2_SEL_RED |
-					  R300_OUT_FMT_C3_SEL_ALPHA));
 	FINISH_ACCEL();
 
 
@@ -179,7 +188,8 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 	OUT_ACCEL_REG(R300_FG_ALPHA_FUNC, 0);
 	FINISH_ACCEL();
 
-	BEGIN_ACCEL(12);
+	BEGIN_ACCEL(13);
+	OUT_ACCEL_REG(R300_RB3D_ABLENDCNTL, 0);
 	OUT_ACCEL_REG(R300_RB3D_ZSTENCILCNTL, 0);
 	OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
 	OUT_ACCEL_REG(R300_RB3D_BW_CNTL, 0);
@@ -205,12 +215,12 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 	OUT_ACCEL_REG(R300_SC_SCISSOR1, ((8191 << R300_SCISSOR_X_SHIFT) |
 					 (8191 << R300_SCISSOR_Y_SHIFT)));
 
-	if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RS690)) {
+	if (IS_R300_3D) {
 	    /* clip has offset 1440 */
 	    OUT_ACCEL_REG(R300_SC_CLIP_0_A, ((1088 << R300_CLIP_X_SHIFT) |
 					     (1088 << R300_CLIP_Y_SHIFT)));
-	    OUT_ACCEL_REG(R300_SC_CLIP_0_B, (((1080 + 2048) << R300_CLIP_X_SHIFT) |
-					     ((1080 + 2048) << R300_CLIP_Y_SHIFT)));
+	    OUT_ACCEL_REG(R300_SC_CLIP_0_B, (((1080 + 2920) << R300_CLIP_X_SHIFT) |
+					     ((1080 + 2920) << R300_CLIP_Y_SHIFT)));
 	} else {
 	    OUT_ACCEL_REG(R300_SC_CLIP_0_A, ((0 << R300_CLIP_X_SHIFT) |
 					     (0 << R300_CLIP_Y_SHIFT)));
@@ -239,6 +249,19 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 	OUT_ACCEL_REG(R200_SE_VAP_CNTL, R200_VAP_FORCE_W_TO_ONE |
 	    R200_VAP_VF_MAX_VTX_NUM);
 	FINISH_ACCEL();
+
+	BEGIN_ACCEL(5);
+	OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0);
+	OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, 0x07ff07ff);
+	OUT_ACCEL_REG(RADEON_AUX_SC_CNTL, 0);
+	OUT_ACCEL_REG(RADEON_RB3D_PLANEMASK, 0xffffffff);
+	OUT_ACCEL_REG(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD |
+				       RADEON_BFACE_SOLID |
+				       RADEON_FFACE_SOLID |
+				       RADEON_VTX_PIX_CENTER_OGL |
+				       RADEON_ROUND_MODE_ROUND |
+				       RADEON_ROUND_PREC_4TH_PIX));
+	FINISH_ACCEL();
     } else {
 	BEGIN_ACCEL(2);
 	if ((info->ChipFamily == CHIP_FAMILY_RADEON) ||
@@ -252,20 +275,21 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 	    RADEON_VTX_ST1_NONPARAMETRIC |
 	    RADEON_TEX1_W_ROUTING_USE_W0);
 	FINISH_ACCEL();
+
+	BEGIN_ACCEL(5);
+	OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0);
+	OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, 0x07ff07ff);
+	OUT_ACCEL_REG(RADEON_AUX_SC_CNTL, 0);
+	OUT_ACCEL_REG(RADEON_RB3D_PLANEMASK, 0xffffffff);
+	OUT_ACCEL_REG(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD |
+				       RADEON_BFACE_SOLID |
+				       RADEON_FFACE_SOLID |
+				       RADEON_VTX_PIX_CENTER_OGL |
+				       RADEON_ROUND_MODE_ROUND |
+				       RADEON_ROUND_PREC_4TH_PIX));
+	FINISH_ACCEL();
     }
 
-    BEGIN_ACCEL(5);
-    OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0);
-    OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, 0x07ff07ff);
-    OUT_ACCEL_REG(RADEON_AUX_SC_CNTL, 0);
-    OUT_ACCEL_REG(RADEON_RB3D_PLANEMASK, 0xffffffff);
-    OUT_ACCEL_REG(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD |
-				   RADEON_BFACE_SOLID |
-				   RADEON_FFACE_SOLID |
-				   RADEON_VTX_PIX_CENTER_OGL |
-				   RADEON_ROUND_MODE_ROUND |
-				   RADEON_ROUND_PREC_4TH_PIX));
-    FINISH_ACCEL();
 }
 
 
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 3524b75..e2d31eb 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -57,12 +57,7 @@ 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)
@@ -190,8 +185,10 @@ RADEONComputePLL(RADEONPLLPtr pll,
 		best_vco_diff = vco_diff;
 	    }
 	}
-	if (best_freq == freq)
-	    break;
+	if (!(flags & RADEON_PLL_DCE3)) {
+	    if (best_freq == freq)
+		break;
+	}
     }
 
     ErrorF("best_freq: %u\n", (unsigned int)best_freq);
@@ -275,6 +272,10 @@ radeon_crtc_load_lut(xf86CrtcPtr crtc)
 	OUTPAL(i, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]);
     }
 
+    if (IS_AVIVO_VARIANT) {
+	OUTREG(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id);
+    }
+
 }
 
 
@@ -533,11 +534,12 @@ static const xf86CrtcFuncsRec radeon_crtc_funcs = {
 Bool RADEONAllocateControllers(ScrnInfoPtr pScrn, int mask)
 {
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
 
     if (mask & 1) {
 	if (pRADEONEnt->Controller[0])
 	    return TRUE;
-	
+
 	pRADEONEnt->pCrtc[0] = xf86CrtcCreate(pScrn, &radeon_crtc_funcs);
 	if (!pRADEONEnt->pCrtc[0])
 	    return FALSE;
@@ -549,16 +551,20 @@ Bool RADEONAllocateControllers(ScrnInfoPtr pScrn, int mask)
 	pRADEONEnt->pCrtc[0]->driver_private = pRADEONEnt->Controller[0];
 	pRADEONEnt->Controller[0]->crtc_id = 0;
 	pRADEONEnt->Controller[0]->crtc_offset = 0;
+	if (info->allowColorTiling)
+	    pRADEONEnt->Controller[0]->can_tile = 1;
+	else
+	    pRADEONEnt->Controller[0]->can_tile = 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])
 	    {
@@ -569,6 +575,10 @@ Bool RADEONAllocateControllers(ScrnInfoPtr pScrn, int mask)
 	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;
+	if (info->allowColorTiling)
+	    pRADEONEnt->Controller[1]->can_tile = 1;
+	else
+	    pRADEONEnt->Controller[1]->can_tile = 0;
     }
 
     return TRUE;
@@ -719,3 +729,41 @@ RADEONUnblank(ScrnInfoPtr pScrn)
     }
 }
 
+Bool
+RADEONSetTiling(ScrnInfoPtr pScrn)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    RADEONCrtcPrivatePtr radeon_crtc;
+    xf86CrtcPtr crtc;
+    int c;
+    int can_tile = 1;
+    Bool changed = FALSE;
+
+    for (c = 0; c < xf86_config->num_crtc; c++) {
+	crtc = xf86_config->crtc[c];
+	radeon_crtc = crtc->driver_private;
+
+	if (crtc->enabled) {
+	    if (!radeon_crtc->can_tile)
+		can_tile = 0;
+	}
+    }
+
+    if (info->tilingEnabled != can_tile)
+	changed = TRUE;
+
+#ifdef XF86DRI
+    if (info->directRenderingEnabled && (info->tilingEnabled != can_tile)) {
+	RADEONSAREAPrivPtr pSAREAPriv;
+	if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_SWITCH_TILING, (can_tile ? 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
+
+    return changed;
+}
diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index 0f7e668..de64dee 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -346,14 +346,6 @@ Bool RADEONCursorInit(ScreenPtr pScreen)
 
     return xf86_cursors_init (pScreen, CURSOR_WIDTH, CURSOR_HEIGHT,
 			      (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
-#if X_BYTE_ORDER == X_BIG_ENDIAN
-				 /* this is a lie --
-				  * HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
-				  * actually inverts the bit order, so
-				  * this switches to LSBFIRST
-				  */
-			       HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
-#endif
 			       HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
 			       HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
 			       HARDWARE_CURSOR_ARGB));
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 5cf8d51..d5595ea 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -126,35 +126,6 @@ static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
 static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
 #endif
 
-extern DisplayModePtr
-RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode);
-
-extern void
-RADEONSaveCommonRegisters(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 },
     { OPTION_SW_CURSOR,      "SWcursor",         OPTV_BOOLEAN, {0}, FALSE },
@@ -219,18 +190,17 @@ static const OptionInfoRec RADEONOptions[] = {
     { OPTION_FORCE_TVOUT,    "ForceTVOut",         OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_TVSTD,          "TVStandard",         OPTV_STRING,  {0}, FALSE },
     { OPTION_IGNORE_LID_STATUS, "IgnoreLidStatus", OPTV_BOOLEAN, {0}, FALSE },
+    { OPTION_DEFAULT_TVDAC_ADJ, "DefaultTVDACAdj", OPTV_BOOLEAN, {0}, FALSE },
     { -1,                    NULL,               OPTV_NONE,    {0}, FALSE }
 };
 
 const OptionInfoRec *RADEONOptionsWeak(void) { return RADEONOptions; }
 
+extern _X_EXPORT int gRADEONEntityIndex;
+
 static int getRADEONEntityIndex(void)
 {
-    int *radeon_entity_index = LoaderSymbol("gRADEONEntityIndex");
-    if (!radeon_entity_index)
-        return -1;
-    else
-        return *radeon_entity_index;
+    return gRADEONEntityIndex;
 }
 
 struct RADEONInt10Save {
@@ -439,6 +409,9 @@ static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn)
 /* Memory map the frame buffer.  Used by RADEONMapMem, below. */
 static Bool RADEONMapFB(ScrnInfoPtr pScrn)
 {
+#ifdef XSERVER_LIBPCIACCESS
+    int err;
+#endif
     RADEONInfoPtr  info = RADEONPTR(pScrn);
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
@@ -456,7 +429,7 @@ static Bool RADEONMapFB(ScrnInfoPtr pScrn)
 
 #else
 
-    int err = pci_device_map_range(info->PciInfo,
+    err = pci_device_map_range(info->PciInfo,
 				   info->LinearAddr,
 				   info->FbMapSize,
 				   PCI_DEV_MAP_FLAG_WRITABLE |
@@ -585,10 +558,10 @@ unsigned RADEONINMC(ScrnInfoPtr pScrn, int addr)
     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);
+    if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	(info->ChipFamily == CHIP_FAMILY_RS740)) {
+	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);
@@ -614,12 +587,12 @@ 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);
+    if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	(info->ChipFamily == CHIP_FAMILY_RS740)) {
+	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);
@@ -636,7 +609,7 @@ void RADEONOUTMC(ScrnInfoPtr pScrn, int addr, CARD32 data)
     }
 }
 
-Bool avivo_get_mc_idle(ScrnInfoPtr pScrn)
+static Bool avivo_get_mc_idle(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
 
@@ -648,7 +621,8 @@ Bool avivo_get_mc_idle(ScrnInfoPtr pScrn)
 	    return TRUE;
 	else
 	    return FALSE;
-    } else if (info->ChipFamily == CHIP_FAMILY_RS690) {
+    } else if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	       (info->ChipFamily == CHIP_FAMILY_RS740)) {
 	if (INMC(pScrn, RS690_MC_STATUS) & RS690_MC_STATUS_IDLE)
 	    return TRUE;
 	else
@@ -663,7 +637,7 @@ Bool avivo_get_mc_idle(ScrnInfoPtr pScrn)
 
 #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)
+static 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;
@@ -681,12 +655,13 @@ void radeon_write_mc_fb_agp_location(ScrnInfoPtr pScrn, int mask, CARD32 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) {
+    } else if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	       (info->ChipFamily == CHIP_FAMILY_RS740)) {
 	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) { 
+    } else if (info->ChipFamily >= CHIP_FAMILY_R520) {
 	if (mask & LOC_FB)
 	    OUTMC(pScrn, R520_MC_FB_LOCATION, fb_loc);
 	if (mask & LOC_AGP)
@@ -700,7 +675,7 @@ void radeon_write_mc_fb_agp_location(ScrnInfoPtr pScrn, int mask, CARD32 fb_loc,
     }
 }
 
-void radeon_read_mc_fb_agp_location(ScrnInfoPtr pScrn, int mask, CARD32 *fb_loc, CARD32 *agp_loc, CARD32 *agp_loc_hi)
+static 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;
@@ -719,7 +694,8 @@ void radeon_read_mc_fb_agp_location(ScrnInfoPtr pScrn, int mask, CARD32 *fb_loc,
 	    *agp_loc = INMC(pScrn, RV515_MC_AGP_LOCATION);
 	    *agp_loc_hi = 0;
 	}
-    } else if (info->ChipFamily == CHIP_FAMILY_RS690) {
+    } else if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	       (info->ChipFamily == CHIP_FAMILY_RS740)) {
 	if (mask & LOC_FB)
 	    *fb_loc = INMC(pScrn, RS690_MC_FB_LOCATION);
 	if (mask & LOC_AGP) {
@@ -1259,7 +1235,8 @@ static void RADEONInitMemoryMap(ScrnInfoPtr pScrn)
     }
 #endif
 
-    if (info->ChipFamily != CHIP_FAMILY_RS690) {
+    if ((info->ChipFamily != CHIP_FAMILY_RS690) &&
+	(info->ChipFamily != CHIP_FAMILY_RS740)) {
 	if (info->IsIGP)
 	    info->mc_fb_location = INREG(RADEON_NB_TOM);
 	else
@@ -1458,23 +1435,20 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn)
     MessageType    from = X_PROBED;
     CARD32         accessible, bar_size;
 
-    if (info->ChipFamily == CHIP_FAMILY_RS690) {
-	pScrn->videoRam = INREG(RADEON_CONFIG_MEMSIZE);
-    } else if (info->IsIGP) {
-        CARD32 tom = INREG(RADEON_NB_TOM);
+    if ((!IS_AVIVO_VARIANT) && info->IsIGP) {
+	CARD32 tom = INREG(RADEON_NB_TOM);
 
 	pScrn->videoRam = (((tom >> 16) -
 			    (tom & 0xffff) + 1) << 6);
 
 	OUTREG(RADEON_CONFIG_MEMSIZE, pScrn->videoRam * 1024);
     } else {
-	
 	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;
@@ -2163,7 +2137,14 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn)
     } else {
 	from = xf86GetOptValBool(info->Options, OPTION_PAGE_FLIP,
 				 &info->allowPageFlip) ? X_CONFIG : X_DEFAULT;
-	reason = "";
+
+	if (IS_AVIVO_VARIANT) {
+	    info->allowPageFlip = 0;
+	    reason = " on r5xx and newer chips.\n";
+	} else {
+	    reason = "";
+	}
+
     }
 #else
     from = X_DEFAULT;
@@ -2221,7 +2202,7 @@ static void RADEONPreInitColorTiling(ScrnInfoPtr pScrn)
 		   info->pKernelDRMVersion->version_minor,
 		   info->pKernelDRMVersion->version_patchlevel);
 	   info->allowColorTiling = FALSE;
-	   return;	   
+	   return;
     }
 #endif /* XF86DRI */
 
@@ -2366,7 +2347,7 @@ static Bool RADEONPreInitXv(ScrnInfoPtr pScrn)
        }
 
     bios_header=info->VBIOS[0x48];
-    bios_header+=(((int)info->VBIOS[0x49]+0)<<8);           
+    bios_header+=(((int)info->VBIOS[0x49]+0)<<8);
         
     mm_table=info->VBIOS[bios_header+0x38];
     if(mm_table==0)
@@ -2636,8 +2617,7 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
     if (xf86RegisterResources(info->pEnt->index, 0, ResExclusive))
 	goto fail;
 
-    if (xf86SetOperatingState(resVga, info->pEnt->index, ResUnusedOpr))
-	goto fail;
+    xf86SetOperatingState(resVga, info->pEnt->index, ResUnusedOpr);
 
     pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR;
     pScrn->monitor     = pScrn->confScreen->monitor;
@@ -2689,7 +2669,7 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
     if (!RADEONPreInitWeight(pScrn))
 	goto fail;
 
-    info->DispPriority = 1; 
+    info->DispPriority = 1;
     if ((s = xf86GetOptValString(info->Options, OPTION_DISP_PRIORITY))) {
 	if (strcmp(s, "AUTO") == 0) {
 	    info->DispPriority = 1;
@@ -2698,7 +2678,7 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
 	} else if (strcmp(s, "HIGH") == 0) {
 	    info->DispPriority = 2;
 	} else
-	    info->DispPriority = 1; 
+	    info->DispPriority = 1;
     }
 
     if (!RADEONPreInitInt10(pScrn, &pInt10))
@@ -2739,17 +2719,22 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
 	if (crtc_max_Y > 8192)
 	    crtc_max_Y = 8192;
     } else {
+	/*
+	 * note that these aren't really the CRTC limits, they're just
+	 * heuristics until we have a better memory manager.
+	 */
 	if (pScrn->videoRam <= 16384) {
 	    crtc_max_X = 1600;
 	    crtc_max_Y = 1200;
+	} else if (IS_R300_VARIANT) {
+	    crtc_max_X = 2560;
+	    crtc_max_Y = 1200;
+	} else if (IS_AVIVO_VARIANT) {
+	    crtc_max_X = 2560;
+	    crtc_max_Y = 1600;
 	} else {
-	    if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
-		crtc_max_X = 2560;
-		crtc_max_Y = 1200;
-	    } else {
-		crtc_max_X = 2048;
-		crtc_max_Y = 1200;
-	    }
+	    crtc_max_X = 2048;
+	    crtc_max_Y = 1200;
 	}
     }
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Max desktop size set to %dx%d\n",
@@ -2793,14 +2778,16 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
 
     if (!RADEONPreInitAccel(pScrn))              goto fail;
 
-    if (!RADEONPreInitXv(pScrn))                 goto fail;
+    if (!IS_AVIVO_VARIANT) {
+	if (!RADEONPreInitXv(pScrn))                 goto fail;
+    }
 
     if (!xf86RandR12PreInit (pScrn))
     {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
       goto fail;
-    }	
-    
+    }
+
     if (pScrn->modes == NULL) {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
       goto fail;
@@ -3001,7 +2988,8 @@ RADEONInitBIOSRegisters(ScrnInfoPtr pScrn)
 	/* let the bios control the backlight */
 	save->bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE;
 	/* tell the bios not to handle mode switching */
-	save->bios_6_scratch |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH;
+	save->bios_6_scratch |= (ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH |
+				 ATOM_S6_ACC_MODE);
 
 	if (info->ChipFamily >= CHIP_FAMILY_R600) {
 	    OUTREG(R600_BIOS_2_SCRATCH, save->bios_2_scratch);
@@ -3014,7 +3002,8 @@ RADEONInitBIOSRegisters(ScrnInfoPtr pScrn)
 	/* let the bios control the backlight */
 	save->bios_0_scratch &= ~RADEON_DRIVER_BRIGHTNESS_EN;
 	/* tell the bios not to handle mode switching */
-	save->bios_6_scratch |= RADEON_DISPLAY_SWITCHING_DIS;
+	save->bios_6_scratch |= (RADEON_DISPLAY_SWITCHING_DIS |
+				 RADEON_ACC_MODE_CHANGE);
 	/* tell the bios a driver is loaded */
 	save->bios_7_scratch |= RADEON_DRV_LOADED;
 
@@ -3032,9 +3021,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
 {
     ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     int            hasDRI = 0;
-    int i;
 #ifdef RENDER
     int            subPixelOrder = SubPixelUnknown;
     char*          s;
@@ -3080,11 +3067,16 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
     RADEONBlank(pScrn);
 
     if (info->IsMobility && !IS_AVIVO_VARIANT) {
-        if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
+	if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
 	    RADEONSetDynamicClock(pScrn, 1);
-        } else {
+	} else {
 	    RADEONSetDynamicClock(pScrn, 0);
-        }
+	}
+    } else if (IS_AVIVO_VARIANT) {
+	if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
+	    atombios_static_pwrmgt_setup(pScrn, 1);
+	    atombios_dyn_clk_setup(pScrn, 1);
+	}
     }
 
     if (IS_R300_VARIANT || IS_RV100_VARIANT)
@@ -3139,12 +3131,14 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
     RADEONInitMemoryMap(pScrn);
 
     /* empty the surfaces */
-    unsigned char *RADEONMMIO = info->MMIO;
-    unsigned int j;
-    for (j = 0; j < 8; j++) {
-	OUTREG(RADEON_SURFACE0_INFO + 16 * j, 0);
-	OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * j, 0);
-	OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * j, 0);
+    {
+	unsigned char *RADEONMMIO = info->MMIO;
+	unsigned int j;
+	for (j = 0; j < 8; j++) {
+	    OUTREG(RADEON_SURFACE0_INFO + 16 * j, 0);
+	    OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * j, 0);
+	    OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * j, 0);
+	}
     }
 
 #ifdef XF86DRI
@@ -3340,28 +3334,8 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
     /* xf86CrtcRotate() accesses pScrn->pScreen */
     pScrn->pScreen = pScreen;
 
-#if 1
-    for (i = 0; i < xf86_config->num_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) {
-	    crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode);
-	    crtc->desiredRotation = RR_Rotate_0;
-	    crtc->desiredX = 0;
-	    crtc->desiredY = 0;
-	}
-
-	if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation, crtc->desiredX, crtc->desiredY))
-	    return FALSE;
-
-    }
-#else
-    /* seems to do the wrong thing on some cards??? */
     if (!xf86SetDesiredModes (pScrn))
 	return FALSE;
-#endif
 
     RADEONSaveScreen(pScreen, SCREEN_SAVER_ON);
 
@@ -3760,15 +3734,15 @@ static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
 {
     RADEONInfoPtr  info   = RADEONPTR(pScrn);
     CARD32 fb, agp, agp_hi;
-    int changed;
+    int changed = 0;
 
     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)
+
+    if (fb != save->mc_fb_location || agp != save->mc_agp_location ||
+	agp_hi != save->mc_agp_location_hi)
 	changed = 1;
 
     if (changed) {
@@ -4039,12 +4013,13 @@ static void RADEONSavePalette(ScrnInfoPtr pScrn, RADEONSavePtr save)
 }
 #endif
 
-void
+static void
 avivo_save(ScrnInfoPtr pScrn, RADEONSavePtr save)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     struct avivo_state *state = &save->avivo;
+    int i, j;
 
     //    state->vga_memory_base = INREG(AVIVO_VGA_MEMORY_BASE);
     //    state->vga_fb_start = INREG(AVIVO_VGA_FB_START);
@@ -4110,8 +4085,6 @@ avivo_save(ScrnInfoPtr pScrn, RADEONSavePtr save)
 
     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);
 
@@ -4151,57 +4124,207 @@ avivo_save(ScrnInfoPtr pScrn, RADEONSavePtr save)
 
     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);
+    if (IS_DCE3_VARIANT) {
+	/* save DVOA regs */
+	state->dvoa[0] = INREG(0x7080);
+	state->dvoa[1] = INREG(0x7084);
+	state->dvoa[2] = INREG(0x708c);
+	state->dvoa[3] = INREG(0x7090);
+	state->dvoa[4] = INREG(0x7094);
+	state->dvoa[5] = INREG(0x70ac);
+	state->dvoa[6] = INREG(0x70b0);
+
+	j = 0;
+	/* save DAC regs */
+	for (i = 0x7000; i <= 0x7040; i += 4) {
+	    state->daca[j] = INREG(i);
+	    state->dacb[j] = INREG(i + 0x100);
+	    j++;
+	}
+	for (i = 0x7058; i <= 0x7060; i += 4) {
+	    state->daca[j] = INREG(i);
+	    state->dacb[j] = INREG(i + 0x100);
+	    j++;
+	}
+	for (i = 0x7068; i <= 0x706c; i += 4) {
+	    state->daca[j] = INREG(i);
+	    state->dacb[j] = INREG(i + 0x100);
+	    j++;
+	}
+	for (i = 0x7ef0; i <= 0x7ef8; i += 4) {
+	    state->daca[j] = INREG(i);
+	    state->dacb[j] = INREG(i + 0x100);
+	    j++;
+	}
+	state->daca[j] = INREG(0x7050);
+	state->dacb[j] = INREG(0x7050 + 0x100);
+
+	j = 0;
+	/* save FMT regs */
+	for (i = 0x6700; i <= 0x6744; i += 4) {
+	    state->fmt1[j] = INREG(i);
+	    state->fmt2[j] = INREG(i + 0x800);
+	    j++;
+	}
+
+	j = 0;
+	/* save DIG regs */
+	for (i = 0x75a0; i <= 0x75e0; i += 4) {
+	    state->dig1[j] = INREG(i);
+	    state->dig2[j] = INREG(i + 0x400);
+	    j++;
+	}
+	for (i = 0x75e8; i <= 0x75ec; i += 4) {
+	    state->dig1[j] = INREG(i);
+	    state->dig2[j] = INREG(i + 0x400);
+	    j++;
+	}
+
+	j = 0;
+	/* save HDMI regs */
+	for (i = 0x7400; i <= 0x741c; i += 4) {
+	    state->hdmi1[j] = INREG(i);
+	    state->hdmi2[j] = INREG(i + 0x400);
+	    j++;
+	}
+	for (i = 0x7430; i <= 0x74ec; i += 4) {
+	    state->hdmi1[j] = INREG(i);
+	    state->hdmi2[j] = INREG(i + 0x400);
+	    j++;
+	}
+	state->hdmi1[j] = INREG(0x7428);
+	state->hdmi2[j] = INREG(0x7828);
+
+	j = 0;
+	/* save AUX regs */
+	for (i = 0x7780; i <= 0x77b4; i += 4) {
+	    state->aux_cntl1[j] = INREG(i);
+	    state->aux_cntl2[j] = INREG(i + 0x040);
+	    state->aux_cntl3[j] = INREG(i + 0x400);
+	    state->aux_cntl4[j] = INREG(i + 0x440);
+	    j++;
+	}
+
+	j = 0;
+	/* save UNIPHY regs */
+	for (i = 0x7ec0; i <= 0x7edc; i += 4) {
+	    state->uniphy1[j] = INREG(i);
+	    state->uniphy2[j] = INREG(i + 0x100);
+	    j++;
+	}
+	j = 0;
+	/* save PHY,LINK regs */
+	for (i = 0x7f20; i <= 0x7f34; i += 4) {
+	    state->phy[j] = INREG(i);
+	    j++;
+	}
+	for (i = 0x7f9c; i <= 0x7fa4; i += 4) {
+	    state->phy[j] = INREG(i);
+	    j++;
+	}
+	state->phy[j] = INREG(0x7f40);
+
+	j = 0;
+	/* save LVTMA regs */
+	for (i = 0x7f00; i <= 0x7f1c; i += 4) {
+	    state->lvtma[j] = INREG(i);
+	    j++;
+	}
+	for (i = 0x7f80; i <= 0x7f98; i += 4) {
+	    state->lvtma[j] = INREG(i);
+	    j++;
+	}
     } 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);
+	j = 0;
+	/* save DVOA regs */
+	for (i = 0x7980; i <= 0x79bc; i += 4) {
+	    state->dvoa[j] = INREG(i);
+	    j++;
+	}
+
+	j = 0;
+	/* save DAC regs */
+	for (i = 0x7800; i <= 0x782c; i += 4) {
+	    state->daca[j] = INREG(i);
+	    state->dacb[j] = INREG(i + 0x200);
+	    j++;
+	}
+	for (i = 0x7834; i <= 0x7840; i += 4) {
+	    state->daca[j] = INREG(i);
+	    state->dacb[j] = INREG(i + 0x200);
+	    j++;
+	}
+	for (i = 0x7850; i <= 0x7868; i += 4) {
+	    state->daca[j] = INREG(i);
+	    state->dacb[j] = INREG(i + 0x200);
+	    j++;
+	}
+
+	j = 0;
+	/* save TMDSA regs */
+	for (i = 0x7880; i <= 0x78e0; i += 4) {
+	    state->tmdsa[j] = INREG(i);
+	    j++;
+	}
+	for (i = 0x7904; i <= 0x7918; i += 4) {
+	    state->tmdsa[j] = INREG(i);
+	    j++;
+	}
+
+	j = 0;
+	/* save LVTMA regs */
+	for (i = 0x7a80; i <= 0x7b18; i += 4) {
+	    state->lvtma[j] = INREG(i);
+	    j++;
+	}
+
+	if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS740)) {
+	    j = 0;
+	    /* save DDIA regs */
+	    for (i = 0x7200; i <= 0x7290; i += 4) {
+		state->ddia[j] = INREG(i);
+		j++;
+	    }
+	}
     }
 
+    /* scalers */
+    j = 0;
+    for (i = 0x6578; i <= 0x65e4; i += 4) {
+	state->d1scl[j] = INREG(i);
+	state->d2scl[j] = INREG(i + 0x800);
+	j++;
+    }
+    for (i = 0x6600; i <= 0x662c; i += 4) {
+	state->d1scl[j] = INREG(i);
+	state->d2scl[j] = INREG(i + 0x800);
+	j++;
+    }
+    j = 0;
+    for (i = 0x66e8; i <= 0x66fc; i += 4) {
+	state->dxscl[j] = INREG(i);
+	j++;
+    }
+    state->dxscl[6] = INREG(0x6e30);
+    state->dxscl[7] = INREG(0x6e34);
+
     if (state->crtc1.control & AVIVO_CRTC_EN)
 	info->crtc_on = TRUE;
-    
+
     if (state->crtc2.control & AVIVO_CRTC_EN)
 	info->crtc2_on = TRUE;
 
 }
 
-void
+static void
 avivo_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     struct avivo_state *state = &restore->avivo;
+    int i, j;
 
     //    OUTMC(pScrn, AVIVO_MC_MEMORY_MAP, state->mc_memory_map);
     //    OUTREG(AVIVO_VGA_MEMORY_BASE, state->vga_memory_base);
@@ -4266,8 +4389,6 @@ avivo_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 
     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);
 
@@ -4306,49 +4427,199 @@ avivo_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 
     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);
+
+    if (IS_DCE3_VARIANT) {
+	/* DVOA regs */
+	OUTREG(0x7080, state->dvoa[0]);
+	OUTREG(0x7084, state->dvoa[1]);
+	OUTREG(0x708c, state->dvoa[2]);
+	OUTREG(0x7090, state->dvoa[3]);
+	OUTREG(0x7094, state->dvoa[4]);
+	OUTREG(0x70ac, state->dvoa[5]);
+	OUTREG(0x70b0, state->dvoa[6]);
+
+	j = 0;
+	/* DAC regs */
+	for (i = 0x7000; i <= 0x7040; i += 4) {
+	    OUTREG(i, state->daca[j]);
+	    OUTREG((i + 0x100), state->dacb[j]);
+	    j++;
+	}
+	for (i = 0x7058; i <= 0x7060; i += 4) {
+	    OUTREG(i, state->daca[j]);
+	    OUTREG((i + 0x100), state->dacb[j]);
+	    j++;
+	}
+	for (i = 0x7068; i <= 0x706c; i += 4) {
+	    OUTREG(i, state->daca[j]);
+	    OUTREG((i + 0x100), state->dacb[j]);
+	    j++;
+	}
+	for (i = 0x7ef0; i <= 0x7ef8; i += 4) {
+	    OUTREG(i, state->daca[j]);
+	    OUTREG((i + 0x100), state->dacb[j]);
+	    j++;
+	}
+	OUTREG(0x7050, state->daca[j]);
+	OUTREG((0x7050 + 0x100), state->dacb[j]);
+
+	j = 0;
+	/* FMT regs */
+	for (i = 0x6700; i <= 0x6744; i += 4) {
+	    OUTREG(i, state->fmt1[j]);
+	    OUTREG((i + 0x800), state->fmt2[j]);
+	    j++;
+	}
+
+	j = 0;
+	/* DIG regs */
+	for (i = 0x75a0; i <= 0x75e0; i += 4) {
+	    OUTREG(i, state->dig1[j]);
+	    OUTREG((i + 0x400), state->dig2[j]);
+	    j++;
+	}
+	for (i = 0x75e8; i <= 0x75ec; i += 4) {
+	    OUTREG(i, state->dig1[j]);
+	    OUTREG((i + 0x400), state->dig2[j]);
+	    j++;
+	}
+
+	j = 0;
+	/* HDMI regs */
+	for (i = 0x7400; i <= 0x741c; i += 4) {
+	    OUTREG(i, state->hdmi1[j]);
+	    OUTREG((i + 0x400), state->hdmi2[j]);
+	    j++;
+	}
+	for (i = 0x7430; i <= 0x74ec; i += 4) {
+	    OUTREG(i, state->hdmi1[j]);
+	    OUTREG((i + 0x400), state->hdmi2[j]);
+	    j++;
+	}
+	OUTREG(0x7428, state->hdmi1[j]);
+	OUTREG((0x7428 + 0x400), state->hdmi2[j]);
+
+	j = 0;
+	/* save AUX regs */
+	for (i = 0x7780; i <= 0x77b4; i += 4) {
+	    OUTREG(i, state->aux_cntl1[j]);
+	    OUTREG((i + 0x040), state->aux_cntl2[j]);
+	    OUTREG((i + 0x400), state->aux_cntl3[j]);
+	    OUTREG((i + 0x440), state->aux_cntl4[j]);
+	    j++;
+	}
+
+	j = 0;
+	/* save UNIPHY regs */
+	for (i = 0x7ec0; i <= 0x7edc; i += 4) {
+	    OUTREG(i, state->uniphy1[j]);
+	    OUTREG((i + 0x100), state->uniphy2[j]);
+	    j++;
+	}
+	j = 0;
+	/* save PHY,LINK regs */
+	for (i = 0x7f20; i <= 0x7f34; i += 4) {
+	    OUTREG(i, state->phy[j]);
+	    j++;
+	}
+	for (i = 0x7f9c; i <= 0x7fa4; i += 4) {
+	    OUTREG(i, state->phy[j]);
+	    j++;
+	}
+	state->phy[j] = INREG(0x7f40);
+
+	j = 0;
+	/* save LVTMA regs */
+	for (i = 0x7f00; i <= 0x7f1c; i += 4) {
+	    OUTREG(i, state->lvtma[j]);
+	    j++;
+	}
+	for (i = 0x7f80; i <= 0x7f98; i += 4) {
+	    OUTREG(i, state->lvtma[j]);
+	    j++;
+	}
     } 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);
+	j = 0;
+	/* DVOA regs */
+	for (i = 0x7980; i <= 0x79bc; i += 4) {
+	    OUTREG(i, state->dvoa[j]);
+	    j++;
+	}
+
+	j = 0;
+	/* DAC regs */
+	for (i = 0x7800; i <= 0x782c; i += 4) {
+	    OUTREG(i, state->daca[j]);
+	    OUTREG((i + 0x200), state->dacb[j]);
+	    j++;
+	}
+	for (i = 0x7834; i <= 0x7840; i += 4) {
+	    OUTREG(i, state->daca[j]);
+	    OUTREG((i + 0x200), state->dacb[j]);
+	    j++;
+	}
+	for (i = 0x7850; i <= 0x7868; i += 4) {
+	    OUTREG(i, state->daca[j]);
+	    OUTREG((i + 0x200), state->dacb[j]);
+	    j++;
+	}
+
+	j = 0;
+	/* TMDSA regs */
+	for (i = 0x7880; i <= 0x78e0; i += 4) {
+	    OUTREG(i, state->tmdsa[j]);
+	    j++;
+	}
+	for (i = 0x7904; i <= 0x7918; i += 4) {
+	    OUTREG(i, state->tmdsa[j]);
+	    j++;
+	}
+
+	j = 0;
+	/* LVTMA regs */
+	for (i = 0x7a80; i <= 0x7b18; i += 4) {
+	    OUTREG(i, state->lvtma[j]);
+	    j++;
+	}
+
+	/* DDIA regs */
+	if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS740)) {
+	    j = 0;
+	    for (i = 0x7200; i <= 0x7290; i += 4) {
+		OUTREG(i, state->ddia[j]);
+		j++;
+	    }
+	}
     }
 
+    /* scalers */
+    j = 0;
+    for (i = 0x6578; i <= 0x65e4; i += 4) {
+	OUTREG(i, state->d1scl[j]);
+	OUTREG((i + 0x800), state->d2scl[j]);
+	j++;
+    }
+    for (i = 0x6600; i <= 0x662c; i += 4) {
+	OUTREG(i, state->d1scl[j]);
+	OUTREG((i + 0x800), state->d2scl[j]);
+	j++;
+    }
+    j = 0;
+    for (i = 0x66e8; i <= 0x66fc; i += 4) {
+	OUTREG(i, state->dxscl[j]);
+	j++;
+    }
+    OUTREG(0x6e30, state->dxscl[6]);
+    OUTREG(0x6e34, state->dxscl[7]);
+
     OUTREG(AVIVO_D1VGA_CONTROL, state->vga1_cntl);
     OUTREG(AVIVO_D2VGA_CONTROL, state->vga2_cntl);
 }
 
-void avivo_restore_vga_regs(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{    
+static void avivo_restore_vga_regs(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
     RADEONInfoPtr info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     struct avivo_state *state = &restore->avivo;
@@ -4471,7 +4742,7 @@ static void RADEONSave(ScrnInfoPtr pScrn)
 }
 
 /* Restore the original (text) mode */
-void RADEONRestore(ScrnInfoPtr pScrn)
+static void RADEONRestore(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
@@ -4567,7 +4838,9 @@ void RADEONRestore(ScrnInfoPtr pScrn)
      */
     if (IS_AVIVO_VARIANT)
 	avivo_restore_vga_regs(pScrn, restore);
-    RADEONRestoreDACRegisters(pScrn, restore);
+
+    if (!IS_AVIVO_VARIANT)
+	RADEONRestoreDACRegisters(pScrn, restore);
 
 #if 0
     RADEONWaitForVerticalSync(pScrn);
@@ -4885,8 +5158,6 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
     ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int i;
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONEnterVT\n");
@@ -4907,41 +5178,34 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
     RADEONWaitForIdleMMIO(pScrn);
 
     if (info->IsMobility && !IS_AVIVO_VARIANT) {
-        if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
+	if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
 	    RADEONSetDynamicClock(pScrn, 1);
-        } else {
+	} else {
 	    RADEONSetDynamicClock(pScrn, 0);
-        }
+	}
+    } else if (IS_AVIVO_VARIANT) {
+	if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
+	    atombios_static_pwrmgt_setup(pScrn, 1);
+	    atombios_dyn_clk_setup(pScrn, 1);
+	}
     }
 
     if (IS_R300_VARIANT || IS_RV100_VARIANT)
 	RADEONForceSomeClocks(pScrn);
 
     pScrn->vtSema = TRUE;
-    for (i = 0; i < xf86_config->num_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) {
-	    crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode);
-	    crtc->desiredRotation = RR_Rotate_0;
-	    crtc->desiredX = 0;
-	    crtc->desiredY = 0;
-	}
-
-	if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation,
-			      crtc->desiredX, crtc->desiredY))
-	    return FALSE;
 
-    }
+    if (!xf86SetDesiredModes(pScrn))
+	return FALSE;
 
     RADEONRestoreSurfaces(pScrn, info->ModeReg);
 #ifdef XF86DRI
     if (info->directRenderingEnabled) {
-    	if (info->cardType == CARD_PCIE && info->pKernelDRMVersion->version_minor >= 19 && info->FbSecureSize)
-    	{
-      		/* we need to backup the PCIE GART TABLE from fb memory */
-	  memcpy(info->FB + info->pciGartOffset, info->pciGartBackup, info->pciGartSize);
+    	if (info->cardType == CARD_PCIE &&
+	    info->pKernelDRMVersion->version_minor >= 19 &&
+	    info->FbSecureSize) {
+	    /* we need to backup the PCIE GART TABLE from fb memory */
+	    memcpy(info->FB + info->pciGartOffset, info->pciGartBackup, info->pciGartSize);
     	}
 
 	/* get the DRI back into shape after resume */
@@ -4966,8 +5230,6 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
     }
 #endif
 
-    //    pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
     return TRUE;
 }
 
@@ -4988,8 +5250,9 @@ void RADEONLeaveVT(int scrnIndex, int flags)
 	DRILock(pScrn->pScreen, 0);
 	RADEONCP_STOP(pScrn, info);
 
-        if (info->cardType == CARD_PCIE && info->pKernelDRMVersion->version_minor >= 19 && info->FbSecureSize)
-        {
+        if (info->cardType == CARD_PCIE &&
+	    info->pKernelDRMVersion->version_minor >= 19 &&
+	    info->FbSecureSize) {
             /* we need to backup the PCIE GART TABLE from fb memory */
             memcpy(info->pciGartBackup, (info->FB + info->pciGartOffset), info->pciGartSize);
         }
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index 4da4841..a6ededa 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -99,10 +99,17 @@ static __inline__ int
 RADEONLog2(int val)
 {
 	int bits;
-
+#if (defined __i386__ || defined __x86_64__) && (defined __GNUC__)
+	__asm volatile("bsrl	%1, %0"
+		: "=r" (bits)
+		: "c" (val)
+	);
+	return bits;
+#else
 	for (bits = 0; val != 0; val >>= 1, ++bits)
 		;
 	return bits - 1;
+#endif
 }
 
 static __inline__ CARD32 F_TO_DW(float val)
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index 10221c0..d5ee5a6 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -533,13 +533,12 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
 
 #ifdef RENDER
     if (info->RenderAccel) {
-	if ((info->ChipFamily >= CHIP_FAMILY_R600) ||
-	    (info->ChipFamily == CHIP_FAMILY_RS400))
+	if (info->ChipFamily >= CHIP_FAMILY_R600)
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration "
-			       "unsupported on XPRESS, R500 and newer cards.\n");
-	else if (IS_R300_VARIANT || (IS_AVIVO_VARIANT && info->ChipFamily <= CHIP_FAMILY_RS690)) {
+			       "unsupported on R600 and newer cards.\n");
+	else if (IS_R300_3D || IS_R500_3D) {
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration "
-			       "enabled for R300 type cards.\n");
+			       "enabled for R300/R400/R500 type cards.\n");
 		info->exa->CheckComposite = R300CheckComposite;
 		info->exa->PrepareComposite =
 		    FUNC_NAME(R300PrepareComposite);
@@ -572,11 +571,11 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting EXA maxPitchBytes\n");
 
     info->exa->maxPitchBytes = 16320;
-    info->exa->maxX = info->exa->Composite ? 2048 : 8192;
+    info->exa->maxX = 8192;
 #else
-    info->exa->maxX = info->exa->Composite ? 2048 : 16320 / 4;
+    info->exa->maxX = 16320 / 4;
 #endif
-    info->exa->maxY = info->exa->Composite ? 2048 : 8192;
+    info->exa->maxY = 8192;
 
     RADEONEngineInit(pScrn);
 
diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c
index 9bbccb5..4e5ab81 100644
--- a/src/radeon_exa_render.c
+++ b/src/radeon_exa_render.c
@@ -177,9 +177,8 @@ static Bool R300GetDestFormat(PicturePtr pDstPicture, CARD32 *dst_format)
 	*dst_format = R300_COLORFORMAT_I8;
 	break;
     default:
-	ErrorF("Unsupported dest format 0x%x\n",
-	       (int)pDstPicture->format);
-	return FALSE;
+	RADEON_FALLBACK(("Unsupported dest format 0x%x\n",
+	       (int)pDstPicture->format));
     }
     return TRUE;
 }
@@ -338,41 +337,76 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
 }
 
 #ifdef ONLY_ONCE
+
+static PixmapPtr
+RADEONGetDrawablePixmap(DrawablePtr pDrawable)
+{
+    if (pDrawable->type == DRAWABLE_WINDOW)
+	return pDrawable->pScreen->GetWindowPixmap((WindowPtr)pDrawable);
+    else
+	return (PixmapPtr)pDrawable;
+}
+
 static Bool R100CheckComposite(int op, PicturePtr pSrcPicture,
 			       PicturePtr pMaskPicture, PicturePtr pDstPicture)
 {
+    PixmapPtr pSrcPixmap, pDstPixmap;
     CARD32 tmp1;
 
     /* Check for unsupported compositing operations. */
     if (op >= sizeof(RadeonBlendOp) / sizeof(RadeonBlendOp[0]))
 	RADEON_FALLBACK(("Unsupported Composite op 0x%x\n", op));
 
-    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 (!pSrcPicture->pDrawable)
+	return FALSE;
+
+    pSrcPixmap = RADEONGetDrawablePixmap(pSrcPicture->pDrawable);
+
+    if (pSrcPixmap->drawable.width >= 2048 ||
+	pSrcPixmap->drawable.height >= 2048) {
+	RADEON_FALLBACK(("Source w/h too large (%d,%d).\n",
+			 pSrcPixmap->drawable.width,
+			 pSrcPixmap->drawable.height));
     }
 
-    if (pDstPicture->pDrawable->width >= (1 << 11) ||
-	pDstPicture->pDrawable->height >= (1 << 11))
-    {
+    pDstPixmap = RADEONGetDrawablePixmap(pDstPicture->pDrawable);
+
+    if (pDstPixmap->drawable.width >= 2048 ||
+	pDstPixmap->drawable.height >= 2048) {
 	RADEON_FALLBACK(("Dest w/h too large (%d,%d).\n",
-			pDstPicture->pDrawable->width,
-			pDstPicture->pDrawable->height));
+			 pDstPixmap->drawable.width,
+			 pDstPixmap->drawable.height));
+    }
+
+    if (pMaskPicture) {
+	PixmapPtr pMaskPixmap = RADEONGetDrawablePixmap(pMaskPicture->pDrawable);
+
+	if (pMaskPixmap->drawable.width >= 2048 ||
+	    pMaskPixmap->drawable.height >= 2048) {
+	    RADEON_FALLBACK(("Mask w/h too large (%d,%d).\n",
+			     pMaskPixmap->drawable.width,
+			     pMaskPixmap->drawable.height));
+	}
+
+	if (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 (!R100CheckCompositeTexture(pMaskPicture, 1))
+	    return FALSE;
     }
 
     if (!R100CheckCompositeTexture(pSrcPicture, 0))
 	return FALSE;
-    if (pMaskPicture != NULL && !R100CheckCompositeTexture(pMaskPicture, 1))
-	return FALSE;
 
     if (!RADEONGetDestFormat(pDstPicture, &tmp1))
 	return FALSE;
@@ -400,7 +434,9 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op,
     if (!info->XInited3D)
 	RADEONInit3DEngine(pScrn);
 
-    RADEONGetDestFormat(pDstPicture, &dst_format);
+    if (!RADEONGetDestFormat(pDstPicture, &dst_format))
+	return FALSE;
+
     pixel_shift = pDst->drawable.bitsPerPixel >> 4;
 
     dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation;
@@ -532,7 +568,7 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
 	RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset));
     if ((txpitch & 0x1f) != 0)
 	RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch));
-    
+
     for (i = 0; i < sizeof(R200TexFormats) / sizeof(R200TexFormats[0]); i++)
     {
 	if (R200TexFormats[i].fmt == pPict->format)
@@ -604,32 +640,61 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
 static Bool R200CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
 			       PicturePtr pDstPicture)
 {
+    PixmapPtr pSrcPixmap, pDstPixmap;
     CARD32 tmp1;
 
     TRACE;
 
-    /* Check for unsupported compositing operations. */
-    if (op >= sizeof(RadeonBlendOp) / sizeof(RadeonBlendOp[0]))
-	RADEON_FALLBACK(("Unsupported Composite op 0x%x\n", op));
+    if (!pSrcPicture->pDrawable)
+	return FALSE;
+
+    pSrcPixmap = RADEONGetDrawablePixmap(pSrcPicture->pDrawable);
+
+    if (pSrcPixmap->drawable.width >= 2048 ||
+	pSrcPixmap->drawable.height >= 2048) {
+	RADEON_FALLBACK(("Source w/h too large (%d,%d).\n",
+			 pSrcPixmap->drawable.width,
+			 pSrcPixmap->drawable.height));
+    }
+
+    pDstPixmap = RADEONGetDrawablePixmap(pDstPicture->pDrawable);
+
+    if (pDstPixmap->drawable.width >= 2048 ||
+	pDstPixmap->drawable.height >= 2048) {
+	RADEON_FALLBACK(("Dest w/h too large (%d,%d).\n",
+			 pDstPixmap->drawable.width,
+			 pDstPixmap->drawable.height));
+    }
+
+    if (pMaskPicture) {
+	PixmapPtr pMaskPixmap = RADEONGetDrawablePixmap(pMaskPicture->pDrawable);
+
+	if (pMaskPixmap->drawable.width >= 2048 ||
+	    pMaskPixmap->drawable.height >= 2048) {
+	    RADEON_FALLBACK(("Mask w/h too large (%d,%d).\n",
+			     pMaskPixmap->drawable.width,
+			     pMaskPixmap->drawable.height));
+	}
 
-    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 (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 (!R200CheckCompositeTexture(pMaskPicture, 1))
+	    return FALSE;
     }
 
     if (!R200CheckCompositeTexture(pSrcPicture, 0))
 	return FALSE;
-    if (pMaskPicture != NULL && !R200CheckCompositeTexture(pMaskPicture, 1))
-	return FALSE;
 
     if (!RADEONGetDestFormat(pDstPicture, &tmp1))
 	return FALSE;
@@ -653,7 +718,9 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture,
     if (!info->XInited3D)
 	RADEONInit3DEngine(pScrn);
 
-    RADEONGetDestFormat(pDstPicture, &dst_format);
+    if (!RADEONGetDestFormat(pDstPicture, &dst_format))
+	return FALSE;
+
     pixel_shift = pDst->drawable.bitsPerPixel >> 4;
 
     dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation;
@@ -744,13 +811,22 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture,
 
 #ifdef ONLY_ONCE
 
-static Bool R300CheckCompositeTexture(PicturePtr pPict, int unit)
+static Bool R300CheckCompositeTexture(PicturePtr pPict, int unit, Bool is_r500)
 {
     int w = pPict->pDrawable->width;
     int h = pPict->pDrawable->height;
     int i;
+    int max_tex_w, max_tex_h;
 
-    if ((w > 0x7ff) || (h > 0x7ff))
+    if (is_r500) {
+	max_tex_w = 4096;
+	max_tex_h = 4096;
+    } else {
+	max_tex_w = 2048;
+	max_tex_h = 2048;
+    }
+
+    if ((w > max_tex_w) || (h > max_tex_h))
 	RADEON_FALLBACK(("Picture w/h too large (%dx%d)\n", w, h));
 
     for (i = 0; i < sizeof(R300TexFormats) / sizeof(R300TexFormats[0]); i++)
@@ -794,6 +870,7 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
     if ((txpitch & 0x1f) != 0)
 	RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch));
 
+    /* TXPITCH = pixels (texels) per line - 1 */
     pixel_shift = pPix->drawable.bitsPerPixel >> 4;
     txpitch >>= pixel_shift;
     txpitch -= 1;
@@ -809,24 +886,32 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
 
     txformat1 = R300TexFormats[i].card_fmt;
 
-    txformat0 = (((w - 1) << R300_TXWIDTH_SHIFT) |
-		 ((h - 1) << R300_TXHEIGHT_SHIFT));
+    txformat0 = ((((w - 1) & 0x7ff) << R300_TXWIDTH_SHIFT) |
+		 (((h - 1) & 0x7ff) << 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;
+    if (IS_R500_3D && ((w - 1) & 0x800))
+	txpitch |= R500_TXWIDTH_11;
 
+    if (IS_R500_3D && ((h - 1) & 0x800))
+	txpitch |= R500_TXHEIGHT_11;
+
+    /* Use TXPITCH instead of TXWIDTH for address computations: we could
+     * omit this if there is no padding, but there is no apparent advantage
+     * in doing so.
+     */
+    txformat0 |= R300_TXPITCH_EN;
 
     info->texW[unit] = w;
     info->texH[unit] = h;
 
-    txfilter = (R300_TX_CLAMP_S(R300_TX_CLAMP_CLAMP_LAST) |
-		R300_TX_CLAMP_T(R300_TX_CLAMP_CLAMP_LAST));
+    if (pPict->repeat)
+      txfilter = (R300_TX_CLAMP_S(R300_TX_CLAMP_WRAP) |
+		  R300_TX_CLAMP_T(R300_TX_CLAMP_WRAP));
+    else
+      txfilter = (R300_TX_CLAMP_S(R300_TX_CLAMP_CLAMP_LAST) |
+		  R300_TX_CLAMP_T(R300_TX_CLAMP_CLAMP_LAST));
+
+    txfilter |= (unit << R300_TX_ID_SHIFT);
 
     switch (pPict->filter) {
     case PictFilterNearest:
@@ -841,7 +926,7 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
 
     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_FILTER1_0 + (unit * 4), 0);
     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);
@@ -867,8 +952,8 @@ static Bool R300CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP
     ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
     PixmapPtr pSrcPixmap, pDstPixmap;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int i;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    int max_tex_w, max_tex_h, max_dst_w, max_dst_h;
 
     TRACE;
 
@@ -876,51 +961,64 @@ static Bool R300CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP
     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"));
+    pSrcPixmap = RADEONGetDrawablePixmap(pSrcPicture->pDrawable);
 
-    if (pSrcPicture->pDrawable->type != DRAWABLE_WINDOW ||
-	pDstPicture->pDrawable->type != DRAWABLE_PIXMAP) {
-	RADEON_FALLBACK(("bad drawable\n"));
+    if (IS_R500_3D) {
+	max_tex_w = 4096;
+	max_tex_h = 4096;
+	max_dst_w = 4096;
+	max_dst_h = 4096;
+    } else {
+	max_tex_w = 2048;
+	max_tex_h = 2048;
+	max_dst_w = 2560;
+	max_dst_h = 2560;
     }
 
-    pSrcPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) pSrcPicture->pDrawable);
-    pDstPixmap = (PixmapPtr)pDstPicture->pDrawable;
+    if (pSrcPixmap->drawable.width >= max_tex_w ||
+	pSrcPixmap->drawable.height >= max_tex_h) {
+	RADEON_FALLBACK(("Source w/h too large (%d,%d).\n",
+			 pSrcPixmap->drawable.width,
+			 pSrcPixmap->drawable.height));
+    }
 
-    /* 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];
+    pDstPixmap = RADEONGetDrawablePixmap(pDstPicture->pDrawable);
 
-	if (crtc->rotatedPixmap == pDstPixmap)
-	    break;
+    if (pDstPixmap->drawable.width >= max_dst_w ||
+	pDstPixmap->drawable.height >= max_dst_h) {
+	RADEON_FALLBACK(("Dest w/h too large (%d,%d).\n",
+			 pDstPixmap->drawable.width,
+			 pDstPixmap->drawable.height));
     }
-    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) {
+	PixmapPtr pMaskPixmap = RADEONGetDrawablePixmap(pMaskPicture->pDrawable);
 
+	if (pMaskPixmap->drawable.width >= max_tex_w ||
+	    pMaskPixmap->drawable.height >= max_tex_h) {
+	    RADEON_FALLBACK(("Mask w/h too large (%d,%d).\n",
+			     pMaskPixmap->drawable.width,
+			     pMaskPixmap->drawable.height));
+	}
 
-    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 (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(pMaskPicture, 1, IS_R500_3D))
+	    return FALSE;
     }
 
-    if (!R300CheckCompositeTexture(pSrcPicture, 0))
-	return FALSE;
-    if (pMaskPicture != NULL && !R300CheckCompositeTexture(pMaskPicture, 1))
+    if (!R300CheckCompositeTexture(pSrcPicture, 0, IS_R500_3D))
 	return FALSE;
 
     if (!R300GetDestFormat(pDstPicture, &tmp1))
@@ -940,7 +1038,6 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
     CARD32 txenable, colorpitch;
     CARD32 blendcntl;
     int pixel_shift;
-    int has_tcl = (info->ChipFamily != CHIP_FAMILY_RS690 && info->ChipFamily != CHIP_FAMILY_RS400);
     ACCEL_PREAMBLE();
 
     TRACE;
@@ -948,7 +1045,9 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
     if (!info->XInited3D)
 	RADEONInit3DEngine(pScrn);
 
-    R300GetDestFormat(pDstPicture, &dst_format);
+    if (!R300GetDestFormat(pDstPicture, &dst_format))
+	return FALSE;
+
     pixel_shift = pDst->drawable.bitsPerPixel >> 4;
 
     dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation;
@@ -979,279 +1078,643 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
 
     RADEON_SWITCH_TO_3D();
 
-    /* setup the VAP */
-
-    if (has_tcl) {
-	BEGIN_ACCEL(28);
-	OUT_ACCEL_REG(R300_VAP_CNTL_STATUS, 0);
-	OUT_ACCEL_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
-	OUT_ACCEL_REG(R300_VAP_CNTL, ((6 << R300_PVS_NUM_SLOTS_SHIFT) |
-				      (5 << R300_PVS_NUM_CNTLRS_SHIFT) |
-				      (4 << R300_PVS_NUM_FPUS_SHIFT) |
-				      (12 << R300_VF_MAX_VTX_NUM_SHIFT)));
-    } else {
-	BEGIN_ACCEL(10);
-	OUT_ACCEL_REG(R300_VAP_CNTL_STATUS, R300_PVS_BYPASS);
-	OUT_ACCEL_REG(R300_VAP_CNTL, ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
-				      (5 << R300_PVS_NUM_CNTLRS_SHIFT) |
-				      (4 << R300_PVS_NUM_FPUS_SHIFT) |
-				      (5 << R300_VF_MAX_VTX_NUM_SHIFT)));
-    }
-
-    OUT_ACCEL_REG(R300_VAP_VTE_CNTL, R300_VTX_XY_FMT | R300_VTX_Z_FMT);
-    OUT_ACCEL_REG(R300_VAP_PSC_SGN_NORM_CNTL, 0);
-
-    if (has_tcl) {
-	OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_0,
-		      ((R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) |
-		       (0 << R300_SKIP_DWORDS_0_SHIFT) |
-		       (0 << R300_DST_VEC_LOC_0_SHIFT) |
-		       R300_SIGNED_0 |
-		       (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_1_SHIFT) |
-		       (0 << R300_SKIP_DWORDS_1_SHIFT) |
-		       (10 << R300_DST_VEC_LOC_1_SHIFT) |
-		       R300_SIGNED_1));
-	OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_1,
-		      ((R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_2_SHIFT) |
-		       (0 << R300_SKIP_DWORDS_2_SHIFT) |
-		       (11 << R300_DST_VEC_LOC_2_SHIFT) |
-		       R300_LAST_VEC_2 |
-		       R300_SIGNED_2));
-	OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0,
-		      ((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_0_SHIFT) |
-		       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_0_SHIFT) |
-		       (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_0_SHIFT) |
-		       (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_0_SHIFT) |
-		       ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
-			<< R300_WRITE_ENA_0_SHIFT) |
-		       (R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_1_SHIFT) |
-		       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_1_SHIFT) |
-		       (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_1_SHIFT) |
-		       (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_1_SHIFT) |
-		       ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
-			<< R300_WRITE_ENA_1_SHIFT)));
-	OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_EXT_1,
-		      ((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_2_SHIFT) |
-		       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_2_SHIFT) |
-		       (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_2_SHIFT) |
-		       (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_2_SHIFT) |
-		       ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
-			<< R300_WRITE_ENA_2_SHIFT)));
-    } else {
-	OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_0,
-		      ((R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) |
-		       (0 << R300_SKIP_DWORDS_0_SHIFT) |
-		       (0 << R300_DST_VEC_LOC_0_SHIFT) |
-		       R300_SIGNED_0 |
-		       (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_1_SHIFT) |
-		       (0 << R300_SKIP_DWORDS_1_SHIFT) |
-		       (6 << R300_DST_VEC_LOC_1_SHIFT) |
-		       R300_SIGNED_1));
-	OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_1,
-		      ((R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_2_SHIFT) |
-		       (0 << R300_SKIP_DWORDS_2_SHIFT) |
-		       (7 << R300_DST_VEC_LOC_2_SHIFT) |
-		       R300_LAST_VEC_2 |
-		       R300_SIGNED_2));
-	OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0,
-		      ((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_0_SHIFT) |
-		       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_0_SHIFT) |
-		       (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_0_SHIFT) |
-		       (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_0_SHIFT) |
-		       ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y)
-			<< R300_WRITE_ENA_0_SHIFT) |
-		       (R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_1_SHIFT) |
-		       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_1_SHIFT) |
-		       (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_1_SHIFT) |
-		       (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_1_SHIFT) |
-		       ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y)
-			<< R300_WRITE_ENA_1_SHIFT)));
-	OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_EXT_1,
-		      ((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_2_SHIFT) |
-		       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_2_SHIFT) |
-		       (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_2_SHIFT) |
-		       (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_2_SHIFT) |
-		       ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y)
-			<< R300_WRITE_ENA_2_SHIFT)));
-    }
+    BEGIN_ACCEL(8);
+    OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_0,
+		  ((R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) |
+		   (0 << R300_SKIP_DWORDS_0_SHIFT) |
+		   (0 << R300_DST_VEC_LOC_0_SHIFT) |
+		   R300_SIGNED_0 |
+		   (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_1_SHIFT) |
+		   (0 << R300_SKIP_DWORDS_1_SHIFT) |
+		   (6 << R300_DST_VEC_LOC_1_SHIFT) |
+		   R300_SIGNED_1));
+    OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_1,
+		  ((R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_2_SHIFT) |
+		   (0 << R300_SKIP_DWORDS_2_SHIFT) |
+		   (7 << R300_DST_VEC_LOC_2_SHIFT) |
+		   R300_LAST_VEC_2 |
+		   R300_SIGNED_2));
+    OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0,
+		  ((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_0_SHIFT) |
+		   (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_0_SHIFT) |
+		   (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_0_SHIFT) |
+		   (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_0_SHIFT) |
+		   ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
+		    << R300_WRITE_ENA_0_SHIFT) |
+		   (R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_1_SHIFT) |
+		   (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_1_SHIFT) |
+		   (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_1_SHIFT) |
+		   (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_1_SHIFT) |
+		   ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
+		    << R300_WRITE_ENA_1_SHIFT)));
+    OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_EXT_1,
+		  ((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_2_SHIFT) |
+		   (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_2_SHIFT) |
+		   (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_2_SHIFT) |
+		   (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_2_SHIFT) |
+		   ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
+		    << R300_WRITE_ENA_2_SHIFT)));
 
-    /* setup the vertex shader */
-    if (has_tcl) {
-	OUT_ACCEL_REG(R300_VAP_PVS_CODE_CNTL_0,
-		      ((0 << R300_PVS_FIRST_INST_SHIFT) |
-		       (1 << R300_PVS_XYZW_VALID_INST_SHIFT) |
-		       (1 << R300_PVS_LAST_INST_SHIFT)));
-	OUT_ACCEL_REG(R300_VAP_PVS_CODE_CNTL_1,
-		      (1 << R300_PVS_LAST_VTX_SRC_INST_SHIFT));
-	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, 0);
-
-	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, R300_CLIP_DISABLE);
-    }
     OUT_ACCEL_REG(R300_VAP_OUT_VTX_FMT_0, R300_VTX_POS_PRESENT);
     OUT_ACCEL_REG(R300_VAP_OUT_VTX_FMT_1,
 		  ((2 << R300_TEX_0_COMP_CNT_SHIFT) |
 		   (2 << R300_TEX_1_COMP_CNT_SHIFT)));
 
+    OUT_ACCEL_REG(R300_TX_INVALTAGS, 0);
+    OUT_ACCEL_REG(R300_TX_ENABLE, txenable);
     FINISH_ACCEL();
 
     /* setup pixel shader */
-    if (IS_R300_VARIANT || info->ChipFamily == CHIP_FAMILY_RS690) {
-      BEGIN_ACCEL(16);
-      OUT_ACCEL_REG(R300_RS_COUNT,
-		    ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |
-		     R300_RS_COUNT_HIRES_EN));
-      OUT_ACCEL_REG(R300_RS_IP_0,
-		    (R300_RS_TEX_PTR(0) |
-		     R300_RS_COL_PTR(0) |
-		     R300_RS_COL_FMT(R300_RS_COL_FMT_RGBA) |
-		     R300_RS_SEL_S(R300_RS_SEL_C0) |
-		     R300_RS_SEL_T(R300_RS_SEL_C1) |
-		     R300_RS_SEL_R(R300_RS_SEL_K0) |
-		     R300_RS_SEL_Q(R300_RS_SEL_K1)));
-      OUT_ACCEL_REG(R300_RS_INST_COUNT, R300_TX_OFFSET_RS(6));
-      OUT_ACCEL_REG(R300_RS_INST_0, R300_RS_INST_TEX_CN_WRITE);
-      OUT_ACCEL_REG(R300_US_CONFIG, (0 << R300_NLEVEL_SHIFT) | R300_FIRST_TEX);
-      OUT_ACCEL_REG(R300_US_PIXSIZE, 0);
-      OUT_ACCEL_REG(R300_US_CODE_OFFSET,
-		    (R300_ALU_CODE_OFFSET(0) |
-		     R300_ALU_CODE_SIZE(1) |
-		     R300_TEX_CODE_OFFSET(0) |
-		     R300_TEX_CODE_SIZE(1)));
-      OUT_ACCEL_REG(R300_US_CODE_ADDR_0, 0);
-      OUT_ACCEL_REG(R300_US_CODE_ADDR_1, 0);
-      OUT_ACCEL_REG(R300_US_CODE_ADDR_2, 0);
-      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();
-    } else {
-      BEGIN_ACCEL(23);
-      OUT_ACCEL_REG(R300_RS_COUNT,
-		    ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |
-		     R300_RS_COUNT_HIRES_EN));
-      OUT_ACCEL_REG(R500_RS_IP_0, (0 << R500_RS_IP_TEX_PTR_S_SHIFT) | (1 << R500_RS_IP_TEX_PTR_T_SHIFT) |
-		    (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) | (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT));
-
-      OUT_ACCEL_REG(R300_RS_INST_COUNT, 0);
-      OUT_ACCEL_REG(R500_RS_INST_0, R500_RS_INST_TEX_CN_WRITE);
-      OUT_ACCEL_REG(R300_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
-      OUT_ACCEL_REG(R300_US_PIXSIZE, 0);
-      OUT_ACCEL_REG(R500_US_FC_CTRL, 0);
-      OUT_ACCEL_REG(R500_US_CODE_ADDR, R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(1));
-      OUT_ACCEL_REG(R500_US_CODE_RANGE, R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(1));
-      OUT_ACCEL_REG(R500_US_CODE_OFFSET, 0);
-      OUT_ACCEL_REG(R500_GA_US_VECTOR_INDEX, 0);
-      // 7807
-      OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, R500_INST_TYPE_TEX | R500_INST_TEX_SEM_WAIT | 
-		    R500_INST_RGB_WMASK_R | R500_INST_RGB_WMASK_G | R500_INST_RGB_WMASK_B | R500_INST_ALPHA_WMASK);
-      
-      OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, R500_TEX_ID(0) | R500_TEX_INST_LD | R500_TEX_SEM_ACQUIRE |
-		    R500_TEX_IGNORE_UNCOVERED);
-
-      OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, R500_TEX_SRC_ADDR(0) | R500_TEX_SRC_S_SWIZ_R | R500_TEX_SRC_T_SWIZ_G |
-		    R500_TEX_DST_ADDR(0) | R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G | R500_TEX_DST_B_SWIZ_B |
-		    R500_TEX_DST_A_SWIZ_A);
-      OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, 0x00000000); // TEX_ADDR_DXDY
-      OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, 0x00000000); // mbz
-      OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, 0x00000000); // mbz
-
-      // 0x78105
-      OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, R500_INST_TYPE_OUT | R500_INST_TEX_SEM_WAIT | R500_INST_LAST |
-		    R500_INST_RGB_OMASK_R | R500_INST_RGB_OMASK_G | R500_INST_RGB_OMASK_B | R500_INST_ALPHA_OMASK);
-
-      OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
-		    R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST | R500_RGB_SRCP_OP_1_MINUS_2RGB0); //0x10040000
-      OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
-		    R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST | R500_ALPHA_SRCP_OP_1_MINUS_2A0); //0x10040000
-
-      OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA,
-		    R500_ALU_RGB_SEL_A_SRC0 |
-		    R500_ALU_RGB_R_SWIZ_A_R | R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B |
-		    R500_ALU_RGB_SEL_B_SRC0 |
-		    R500_ALU_RGB_R_SWIZ_B_1 | R500_ALU_RGB_B_SWIZ_B_1 | R500_ALU_RGB_G_SWIZ_B_1);//0x00db0220
-
-      OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, R500_ALPHA_OP_MAD | 
-		    R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_1);//0x00c0c000)
-
-      OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, R500_ALU_RGBA_OP_MAD |
-		    R500_ALU_RGBA_R_SWIZ_0 | R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 |
-		    R500_ALU_RGBA_A_SWIZ_0);//0x20490000
-      FINISH_ACCEL();
-    }
+    if (IS_R300_3D) {
+	CARD32 output_fmt;
+	int src_color, src_alpha;
+	int mask_color, mask_alpha;
 
-    BEGIN_ACCEL(6);
-    OUT_ACCEL_REG(R300_TX_INVALTAGS, 0x0);
-    OUT_ACCEL_REG(R300_TX_ENABLE, txenable);
+	if (PICT_FORMAT_RGB(pSrcPicture->format) == 0)
+	    src_color = R300_ALU_RGB_0_0;
+	else
+	    src_color = R300_ALU_RGB_SRC0_RGB;
 
-    OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
-    OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch);
+	if (PICT_FORMAT_A(pSrcPicture->format) == 0)
+	    src_alpha = R300_ALU_ALPHA_1_0;
+	else
+	    src_alpha = R300_ALU_ALPHA_SRC0_A;
+
+	if (pMask && pMaskPicture->componentAlpha) {
+	    if (RadeonBlendOp[op].src_alpha) {
+		if (PICT_FORMAT_A(pSrcPicture->format) == 0) {
+		    src_color = R300_ALU_RGB_1_0;
+		    src_alpha = R300_ALU_ALPHA_1_0;
+		} else {
+		    src_color = R300_ALU_RGB_SRC0_AAA;
+		    src_alpha = R300_ALU_ALPHA_SRC0_A;
+		}
+
+		mask_color = R300_ALU_RGB_SRC1_RGB;
+
+		if (PICT_FORMAT_A(pMaskPicture->format) == 0)
+		    mask_alpha = R300_ALU_ALPHA_1_0;
+		else
+		    mask_alpha = R300_ALU_ALPHA_SRC1_A;
+
+	    } else {
+		src_color = R300_ALU_RGB_SRC0_RGB;
+
+		if (PICT_FORMAT_A(pSrcPicture->format) == 0)
+		    src_alpha = R300_ALU_ALPHA_1_0;
+		else
+		    src_alpha = R300_ALU_ALPHA_SRC0_A;
+
+		mask_color = R300_ALU_RGB_SRC1_RGB;
+
+		if (PICT_FORMAT_A(pMaskPicture->format) == 0)
+		    mask_alpha = R300_ALU_ALPHA_1_0;
+		else
+		    mask_alpha = R300_ALU_ALPHA_SRC1_A;
+
+	    }
+	} else if (pMask) {
+	    if (PICT_FORMAT_A(pMaskPicture->format) == 0)
+		mask_color = R300_ALU_RGB_1_0;
+	    else
+		mask_color = R300_ALU_RGB_SRC1_AAA;
+
+	    if (PICT_FORMAT_A(pMaskPicture->format) == 0)
+		mask_alpha = R300_ALU_ALPHA_1_0;
+	    else
+		mask_alpha = R300_ALU_ALPHA_SRC1_A;
+	} else {
+	    mask_color = R300_ALU_RGB_1_0;
+	    mask_alpha = R300_ALU_ALPHA_1_0;
+	}
 
-    blendcntl = RADEONGetBlendCntl(op, pMaskPicture, pDstPicture->format);
-    OUT_ACCEL_REG(R300_RB3D_BLENDCNTL, blendcntl);
-    OUT_ACCEL_REG(R300_RB3D_ABLENDCNTL, 0);
+	/* shader output swizzling */
+	switch (pDstPicture->format) {
+	case PICT_a8r8g8b8:
+	case PICT_x8r8g8b8:
+	default:
+	    output_fmt = (R300_OUT_FMT_C4_8 |
+			  R300_OUT_FMT_C0_SEL_BLUE |
+			  R300_OUT_FMT_C1_SEL_GREEN |
+			  R300_OUT_FMT_C2_SEL_RED |
+			  R300_OUT_FMT_C3_SEL_ALPHA);
+	    break;
+	case PICT_a8b8g8r8:
+	case PICT_x8b8g8r8:
+	    output_fmt = (R300_OUT_FMT_C4_8 |
+			  R300_OUT_FMT_C0_SEL_RED |
+			  R300_OUT_FMT_C1_SEL_GREEN |
+			  R300_OUT_FMT_C2_SEL_BLUE |
+			  R300_OUT_FMT_C3_SEL_ALPHA);
+	    break;
+	case PICT_a1r5g5b5:
+	case PICT_x1r5g5b5:
+	    /* fix me */
+	case PICT_r5g6b5:
+	    output_fmt = (R300_OUT_FMT_C_5_6_5 |
+			  R300_OUT_FMT_C0_SEL_BLUE |
+			  R300_OUT_FMT_C1_SEL_GREEN |
+			  R300_OUT_FMT_C2_SEL_RED |
+			  R300_OUT_FMT_C3_SEL_ALPHA);
+	    break;
+	case PICT_a8:
+	    output_fmt = (R300_OUT_FMT_C4_8 |
+			  R300_OUT_FMT_C0_SEL_ALPHA);
+	    break;
+	}
 
-#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;
+	/* setup the rasterizer */
+	if (pMask) {
+	    BEGIN_ACCEL(20);
+	    /* 4 components: 2 for tex0, 2 for tex1 */
+	    OUT_ACCEL_REG(R300_RS_COUNT,
+			  ((4 << R300_RS_COUNT_IT_COUNT_SHIFT) |
+			   R300_RS_COUNT_HIRES_EN));
+	    /* rasterizer source table */
+	    OUT_ACCEL_REG(R300_RS_IP_0,
+			  (R300_RS_TEX_PTR(0) |
+			   R300_RS_SEL_S(R300_RS_SEL_C0) |
+			   R300_RS_SEL_T(R300_RS_SEL_C1) |
+			   R300_RS_SEL_R(R300_RS_SEL_K0) |
+			   R300_RS_SEL_Q(R300_RS_SEL_K1)));
+	    OUT_ACCEL_REG(R300_RS_IP_1,
+			  (R300_RS_TEX_PTR(2) |
+			   R300_RS_SEL_S(R300_RS_SEL_C0) |
+			   R300_RS_SEL_T(R300_RS_SEL_C1) |
+			   R300_RS_SEL_R(R300_RS_SEL_K0) |
+			   R300_RS_SEL_Q(R300_RS_SEL_K1)));
+
+	    OUT_ACCEL_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(1) | R300_TX_OFFSET_RS(6));
+	    /* src tex */
+	    OUT_ACCEL_REG(R300_RS_INST_0, (R300_INST_TEX_ID(0) |
+					   R300_RS_INST_TEX_CN_WRITE |
+					   R300_INST_TEX_ADDR(0)));
+	    /* mask tex */
+	    OUT_ACCEL_REG(R300_RS_INST_1, (R300_INST_TEX_ID(1) |
+					   R300_RS_INST_TEX_CN_WRITE |
+					   R300_INST_TEX_ADDR(1)));
+
+	    OUT_ACCEL_REG(R300_US_CONFIG, (0 << R300_NLEVEL_SHIFT) | R300_FIRST_TEX);
+	    OUT_ACCEL_REG(R300_US_PIXSIZE, 1); /* max num of temps used */
+	    OUT_ACCEL_REG(R300_US_CODE_OFFSET, (R300_ALU_CODE_OFFSET(0) |
+						R300_ALU_CODE_SIZE(0) |
+						R300_TEX_CODE_OFFSET(0) |
+						R300_TEX_CODE_SIZE(1)));
+
+	} else {
+	    BEGIN_ACCEL(17);
+	    /* 2 components: 2 for tex0 */
+	    OUT_ACCEL_REG(R300_RS_COUNT,
+			  ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |
+			   R300_RS_COUNT_HIRES_EN));
+	    OUT_ACCEL_REG(R300_RS_IP_0,
+			  (R300_RS_TEX_PTR(0) |
+			   R300_RS_SEL_S(R300_RS_SEL_C0) |
+			   R300_RS_SEL_T(R300_RS_SEL_C1) |
+			   R300_RS_SEL_R(R300_RS_SEL_K0) |
+			   R300_RS_SEL_Q(R300_RS_SEL_K1)));
+	    OUT_ACCEL_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6));
+	    /* src tex */
+	    OUT_ACCEL_REG(R300_RS_INST_0, (R300_INST_TEX_ID(0) |
+					   R300_RS_INST_TEX_CN_WRITE |
+					   R300_INST_TEX_ADDR(0)));
+
+	    OUT_ACCEL_REG(R300_US_CONFIG, (0 << R300_NLEVEL_SHIFT) | R300_FIRST_TEX);
+	    OUT_ACCEL_REG(R300_US_PIXSIZE, 1); /* max num of temps used */
+	    OUT_ACCEL_REG(R300_US_CODE_OFFSET, (R300_ALU_CODE_OFFSET(0) |
+						R300_ALU_CODE_SIZE(0) |
+						R300_TEX_CODE_OFFSET(0) |
+						R300_TEX_CODE_SIZE(0)));
 
-    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;
+	}
+
+	OUT_ACCEL_REG(R300_US_CODE_ADDR_0,
+		      (R300_ALU_START(0) |
+		       R300_ALU_SIZE(0) |
+		       R300_TEX_START(0) |
+		       R300_TEX_SIZE(0)));
+	OUT_ACCEL_REG(R300_US_CODE_ADDR_1,
+		      (R300_ALU_START(0) |
+		       R300_ALU_SIZE(0) |
+		       R300_TEX_START(0) |
+		       R300_TEX_SIZE(0)));
+	OUT_ACCEL_REG(R300_US_CODE_ADDR_2,
+		      (R300_ALU_START(0) |
+		       R300_ALU_SIZE(0) |
+		       R300_TEX_START(0) |
+		       R300_TEX_SIZE(0)));
+
+	if (pMask) {
+	    OUT_ACCEL_REG(R300_US_CODE_ADDR_3,
+			  (R300_ALU_START(0) |
+			   R300_ALU_SIZE(0) |
+			   R300_TEX_START(0) |
+			   R300_TEX_SIZE(1) |
+			   R300_RGBA_OUT));
+	} else {
+	    OUT_ACCEL_REG(R300_US_CODE_ADDR_3,
+			  (R300_ALU_START(0) |
+			   R300_ALU_SIZE(0) |
+			   R300_TEX_START(0) |
+			   R300_TEX_SIZE(0) |
+			   R300_RGBA_OUT));
+	}
+
+	OUT_ACCEL_REG(R300_US_OUT_FMT_0, output_fmt);
+
+	OUT_ACCEL_REG(R300_US_TEX_INST_0,
+		      (R300_TEX_SRC_ADDR(0) |
+		       R300_TEX_DST_ADDR(0) |
+		       R300_TEX_ID(0) |
+		       R300_TEX_INST(R300_TEX_INST_LD)));
+
+	if (pMask) {
+	    OUT_ACCEL_REG(R300_US_TEX_INST_1,
+			  (R300_TEX_SRC_ADDR(1) |
+			   R300_TEX_DST_ADDR(1) |
+			   R300_TEX_ID(1) |
+			   R300_TEX_INST(R300_TEX_INST_LD)));
+	}
+
+	OUT_ACCEL_REG(R300_US_ALU_RGB_ADDR_0,
+		      (R300_ALU_RGB_ADDR0(0) |
+		       R300_ALU_RGB_ADDR1(1) |
+		       R300_ALU_RGB_ADDR2(0) |
+		       R300_ALU_RGB_ADDRD(0) |
+		       R300_ALU_RGB_OMASK((R300_ALU_RGB_MASK_R |
+					   R300_ALU_RGB_MASK_G |
+					   R300_ALU_RGB_MASK_B)) |
+		       R300_ALU_RGB_TARGET_A));
+	OUT_ACCEL_REG(R300_US_ALU_RGB_INST_0,
+		      (R300_ALU_RGB_SEL_A(src_color) |
+		       R300_ALU_RGB_MOD_A(R300_ALU_RGB_MOD_NOP) |
+		       R300_ALU_RGB_SEL_B(mask_color) |
+		       R300_ALU_RGB_MOD_B(R300_ALU_RGB_MOD_NOP) |
+		       R300_ALU_RGB_SEL_C(R300_ALU_RGB_0_0) |
+		       R300_ALU_RGB_MOD_C(R300_ALU_RGB_MOD_NOP) |
+		       R300_ALU_RGB_OP(R300_ALU_RGB_OP_MAD) |
+		       R300_ALU_RGB_OMOD(R300_ALU_RGB_OMOD_NONE) |
+		       R300_ALU_RGB_CLAMP));
+	OUT_ACCEL_REG(R300_US_ALU_ALPHA_ADDR_0,
+		      (R300_ALU_ALPHA_ADDR0(0) |
+		       R300_ALU_ALPHA_ADDR1(1) |
+		       R300_ALU_ALPHA_ADDR2(0) |
+		       R300_ALU_ALPHA_ADDRD(0) |
+		       R300_ALU_ALPHA_OMASK(R300_ALU_ALPHA_MASK_A) |
+		       R300_ALU_ALPHA_TARGET_A |
+		       R300_ALU_ALPHA_OMASK_W(R300_ALU_ALPHA_MASK_NONE)));
+	OUT_ACCEL_REG(R300_US_ALU_ALPHA_INST_0,
+		      (R300_ALU_ALPHA_SEL_A(src_alpha) |
+		       R300_ALU_ALPHA_MOD_A(R300_ALU_ALPHA_MOD_NOP) |
+		       R300_ALU_ALPHA_SEL_B(mask_alpha) |
+		       R300_ALU_ALPHA_MOD_B(R300_ALU_ALPHA_MOD_NOP) |
+		       R300_ALU_ALPHA_SEL_C(R300_ALU_ALPHA_0_0) |
+		       R300_ALU_ALPHA_MOD_C(R300_ALU_ALPHA_MOD_NOP) |
+		       R300_ALU_ALPHA_OP(R300_ALU_ALPHA_OP_MAD) |
+		       R300_ALU_ALPHA_OMOD(R300_ALU_ALPHA_OMOD_NONE) |
+		       R300_ALU_ALPHA_CLAMP));
+	FINISH_ACCEL();
     } else {
-	cblend |= R200_TXC_ARG_B_ZERO | R200_TXC_COMP_ARG_B;
-	ablend |= R200_TXA_ARG_B_ZERO | R200_TXA_COMP_ARG_B;
+	CARD32 output_fmt;
+	CARD32 src_color, src_alpha;
+	CARD32 mask_color, mask_alpha;
+
+	if (PICT_FORMAT_RGB(pSrcPicture->format) == 0)
+	    src_color = (R500_ALU_RGB_R_SWIZ_A_0 |
+			 R500_ALU_RGB_G_SWIZ_A_0 |
+			 R500_ALU_RGB_B_SWIZ_A_0);
+	else
+	    src_color = (R500_ALU_RGB_R_SWIZ_A_R |
+			 R500_ALU_RGB_G_SWIZ_A_G |
+			 R500_ALU_RGB_B_SWIZ_A_B);
+
+	if (PICT_FORMAT_A(pSrcPicture->format) == 0)
+	    src_alpha = R500_ALPHA_SWIZ_A_1;
+	else
+	    src_alpha = R500_ALPHA_SWIZ_A_A;
+
+	if (pMask && pMaskPicture->componentAlpha) {
+	    if (RadeonBlendOp[op].src_alpha) {
+		if (PICT_FORMAT_A(pSrcPicture->format) == 0) {
+		    src_color = (R500_ALU_RGB_R_SWIZ_A_1 |
+				 R500_ALU_RGB_G_SWIZ_A_1 |
+				 R500_ALU_RGB_B_SWIZ_A_1);
+		    src_alpha = R500_ALPHA_SWIZ_A_1;
+		} else {
+		    src_color = (R500_ALU_RGB_R_SWIZ_A_A |
+				 R500_ALU_RGB_G_SWIZ_A_A |
+				 R500_ALU_RGB_B_SWIZ_A_A);
+		    src_alpha = R500_ALPHA_SWIZ_A_A;
+		}
+
+		mask_color = (R500_ALU_RGB_R_SWIZ_B_R |
+			      R500_ALU_RGB_G_SWIZ_B_G |
+			      R500_ALU_RGB_B_SWIZ_B_B);
+
+		if (PICT_FORMAT_A(pMaskPicture->format) == 0)
+		    mask_alpha = R500_ALPHA_SWIZ_B_1;
+		else
+		    mask_alpha = R500_ALPHA_SWIZ_B_A;
+
+	    } else {
+		src_color = (R500_ALU_RGB_R_SWIZ_A_R |
+			     R500_ALU_RGB_G_SWIZ_A_G |
+			     R500_ALU_RGB_B_SWIZ_A_B);
+
+		if (PICT_FORMAT_A(pSrcPicture->format) == 0)
+		    src_alpha = R500_ALPHA_SWIZ_A_1;
+		else
+		    src_alpha = R500_ALPHA_SWIZ_A_A;
+
+		mask_color = (R500_ALU_RGB_R_SWIZ_B_R |
+			      R500_ALU_RGB_G_SWIZ_B_G |
+			      R500_ALU_RGB_B_SWIZ_B_B);
+
+		if (PICT_FORMAT_A(pMaskPicture->format) == 0)
+		    mask_alpha = R500_ALPHA_SWIZ_B_1;
+		else
+		    mask_alpha = R500_ALPHA_SWIZ_B_A;
+
+	    }
+	} else if (pMask) {
+	    if (PICT_FORMAT_A(pMaskPicture->format) == 0)
+		mask_color = (R500_ALU_RGB_R_SWIZ_B_1 |
+			      R500_ALU_RGB_G_SWIZ_B_1 |
+			      R500_ALU_RGB_B_SWIZ_B_1);
+	    else
+		mask_color = (R500_ALU_RGB_R_SWIZ_B_A |
+			      R500_ALU_RGB_G_SWIZ_B_A |
+			      R500_ALU_RGB_B_SWIZ_B_A);
+
+	    if (PICT_FORMAT_A(pMaskPicture->format) == 0)
+		mask_alpha = R500_ALPHA_SWIZ_B_1;
+	    else
+		mask_alpha = R500_ALPHA_SWIZ_B_A;
+	} else {
+	    mask_color = (R500_ALU_RGB_R_SWIZ_B_1 |
+			  R500_ALU_RGB_G_SWIZ_B_1 |
+			  R500_ALU_RGB_B_SWIZ_B_1);
+	    mask_alpha = R500_ALPHA_SWIZ_B_1;
+	}
+
+	/* shader output swizzling */
+	switch (pDstPicture->format) {
+	case PICT_a8r8g8b8:
+	case PICT_x8r8g8b8:
+	default:
+	    output_fmt = (R300_OUT_FMT_C4_8 |
+			  R300_OUT_FMT_C0_SEL_BLUE |
+			  R300_OUT_FMT_C1_SEL_GREEN |
+			  R300_OUT_FMT_C2_SEL_RED |
+			  R300_OUT_FMT_C3_SEL_ALPHA);
+	    break;
+	case PICT_a8b8g8r8:
+	case PICT_x8b8g8r8:
+	    output_fmt = (R300_OUT_FMT_C4_8 |
+			  R300_OUT_FMT_C0_SEL_RED |
+			  R300_OUT_FMT_C1_SEL_GREEN |
+			  R300_OUT_FMT_C2_SEL_BLUE |
+			  R300_OUT_FMT_C3_SEL_ALPHA);
+	    break;
+	case PICT_a1r5g5b5:
+	case PICT_x1r5g5b5:
+	    /* fix me */
+	case PICT_r5g6b5:
+	    output_fmt = (R300_OUT_FMT_C_5_6_5 |
+			  R300_OUT_FMT_C0_SEL_BLUE |
+			  R300_OUT_FMT_C1_SEL_GREEN |
+			  R300_OUT_FMT_C2_SEL_RED |
+			  R300_OUT_FMT_C3_SEL_ALPHA);
+	    break;
+	case PICT_a8:
+	    output_fmt = (R300_OUT_FMT_C4_8 |
+			  R300_OUT_FMT_C0_SEL_ALPHA);
+	    break;
+	}
+
+	if (pMask) {
+	    BEGIN_ACCEL(13);
+	    OUT_ACCEL_REG(R300_RS_COUNT,
+			  ((4 << R300_RS_COUNT_IT_COUNT_SHIFT) |
+			   R300_RS_COUNT_HIRES_EN));
+	    OUT_ACCEL_REG(R500_RS_IP_0, ((0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
+					 (1 << R500_RS_IP_TEX_PTR_T_SHIFT) |
+					 (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
+					 (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)));
+
+	    OUT_ACCEL_REG(R500_RS_IP_1, ((2 << R500_RS_IP_TEX_PTR_S_SHIFT) |
+					 (3 << R500_RS_IP_TEX_PTR_T_SHIFT) |
+					 (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
+					 (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)));
+
+	    OUT_ACCEL_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(1) | R300_TX_OFFSET_RS(6));
+
+	    /* src tex */
+	    OUT_ACCEL_REG(R500_RS_INST_0, ((0 << R500_RS_INST_TEX_ID_SHIFT) |
+					   R500_RS_INST_TEX_CN_WRITE |
+					   (0 << R500_RS_INST_TEX_ADDR_SHIFT)));
+	    /* mask tex */
+	    OUT_ACCEL_REG(R500_RS_INST_1, ((1 << R500_RS_INST_TEX_ID_SHIFT) |
+					   R500_RS_INST_TEX_CN_WRITE |
+					   (1 << R500_RS_INST_TEX_ADDR_SHIFT)));
+
+	    OUT_ACCEL_REG(R300_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
+	    OUT_ACCEL_REG(R300_US_PIXSIZE, 1);
+	    OUT_ACCEL_REG(R500_US_FC_CTRL, 0);
+	    OUT_ACCEL_REG(R500_US_CODE_ADDR, (R500_US_CODE_START_ADDR(0) |
+					      R500_US_CODE_END_ADDR(2)));
+	    OUT_ACCEL_REG(R500_US_CODE_RANGE, (R500_US_CODE_RANGE_ADDR(0) |
+					       R500_US_CODE_RANGE_SIZE(2)));
+	    OUT_ACCEL_REG(R500_US_CODE_OFFSET, 0);
+	} else {
+	    BEGIN_ACCEL(11);
+	    OUT_ACCEL_REG(R300_RS_COUNT,
+			  ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |
+			   R300_RS_COUNT_HIRES_EN));
+
+	    OUT_ACCEL_REG(R500_RS_IP_0, ((0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
+					 (1 << R500_RS_IP_TEX_PTR_T_SHIFT) |
+					 (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
+					 (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)));
+
+	    OUT_ACCEL_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6));
+
+	    /* src tex */
+	    OUT_ACCEL_REG(R500_RS_INST_0, ((0 << R500_RS_INST_TEX_ID_SHIFT) |
+					   R500_RS_INST_TEX_CN_WRITE |
+					   (0 << R500_RS_INST_TEX_ADDR_SHIFT)));
+
+	    OUT_ACCEL_REG(R300_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
+	    OUT_ACCEL_REG(R300_US_PIXSIZE, 1);
+	    OUT_ACCEL_REG(R500_US_FC_CTRL, 0);
+	    OUT_ACCEL_REG(R500_US_CODE_ADDR, (R500_US_CODE_START_ADDR(0) |
+					      R500_US_CODE_END_ADDR(1)));
+	    OUT_ACCEL_REG(R500_US_CODE_RANGE, (R500_US_CODE_RANGE_ADDR(0) |
+					       R500_US_CODE_RANGE_SIZE(1)));
+	    OUT_ACCEL_REG(R500_US_CODE_OFFSET, 0);
+	}
+
+	OUT_ACCEL_REG(R300_US_OUT_FMT_0, output_fmt);
+	FINISH_ACCEL();
+
+	if (pMask) {
+	    BEGIN_ACCEL(19);
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_INDEX, 0);
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_INST_TYPE_TEX |
+						   R500_INST_RGB_WMASK_R |
+						   R500_INST_RGB_WMASK_G |
+						   R500_INST_RGB_WMASK_B |
+						   R500_INST_ALPHA_WMASK |
+						   R500_INST_RGB_CLAMP |
+						   R500_INST_ALPHA_CLAMP));
+
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_TEX_ID(0) |
+						   R500_TEX_INST_LD |
+						   R500_TEX_IGNORE_UNCOVERED));
+
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_TEX_SRC_ADDR(0) |
+						   R500_TEX_SRC_S_SWIZ_R |
+						   R500_TEX_SRC_T_SWIZ_G |
+						   R500_TEX_DST_ADDR(0) |
+						   R500_TEX_DST_R_SWIZ_R |
+						   R500_TEX_DST_G_SWIZ_G |
+						   R500_TEX_DST_B_SWIZ_B |
+						   R500_TEX_DST_A_SWIZ_A));
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_DX_ADDR(0) |
+						   R500_DX_S_SWIZ_R |
+						   R500_DX_T_SWIZ_R |
+						   R500_DX_R_SWIZ_R |
+						   R500_DX_Q_SWIZ_R |
+						   R500_DY_ADDR(0) |
+						   R500_DY_S_SWIZ_R |
+						   R500_DY_T_SWIZ_R |
+						   R500_DY_R_SWIZ_R |
+						   R500_DY_Q_SWIZ_R));
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, 0x00000000);
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, 0x00000000);
+
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_INST_TYPE_TEX |
+						   R500_INST_TEX_SEM_WAIT |
+						   R500_INST_RGB_WMASK_R |
+						   R500_INST_RGB_WMASK_G |
+						   R500_INST_RGB_WMASK_B |
+						   R500_INST_ALPHA_WMASK |
+						   R500_INST_RGB_CLAMP |
+						   R500_INST_ALPHA_CLAMP));
+
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_TEX_ID(1) |
+						   R500_TEX_INST_LD |
+						   R500_TEX_SEM_ACQUIRE |
+						   R500_TEX_IGNORE_UNCOVERED));
+
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_TEX_SRC_ADDR(1) |
+						   R500_TEX_SRC_S_SWIZ_R |
+						   R500_TEX_SRC_T_SWIZ_G |
+						   R500_TEX_DST_ADDR(1) |
+						   R500_TEX_DST_R_SWIZ_R |
+						   R500_TEX_DST_G_SWIZ_G |
+						   R500_TEX_DST_B_SWIZ_B |
+						   R500_TEX_DST_A_SWIZ_A));
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_DX_ADDR(1) |
+						   R500_DX_S_SWIZ_R |
+						   R500_DX_T_SWIZ_R |
+						   R500_DX_R_SWIZ_R |
+						   R500_DX_Q_SWIZ_R |
+						   R500_DY_ADDR(1) |
+						   R500_DY_S_SWIZ_R |
+						   R500_DY_T_SWIZ_R |
+						   R500_DY_R_SWIZ_R |
+						   R500_DY_Q_SWIZ_R));
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, 0x00000000);
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, 0x00000000);
+	} else {
+	    BEGIN_ACCEL(13);
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_INDEX, 0);
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_INST_TYPE_TEX |
+						   R500_INST_TEX_SEM_WAIT |
+						   R500_INST_RGB_WMASK_R |
+						   R500_INST_RGB_WMASK_G |
+						   R500_INST_RGB_WMASK_B |
+						   R500_INST_ALPHA_WMASK |
+						   R500_INST_RGB_CLAMP |
+						   R500_INST_ALPHA_CLAMP));
+
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_TEX_ID(0) |
+						   R500_TEX_INST_LD |
+						   R500_TEX_SEM_ACQUIRE |
+						   R500_TEX_IGNORE_UNCOVERED));
+
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_TEX_SRC_ADDR(0) |
+						   R500_TEX_SRC_S_SWIZ_R |
+						   R500_TEX_SRC_T_SWIZ_G |
+						   R500_TEX_DST_ADDR(0) |
+						   R500_TEX_DST_R_SWIZ_R |
+						   R500_TEX_DST_G_SWIZ_G |
+						   R500_TEX_DST_B_SWIZ_B |
+						   R500_TEX_DST_A_SWIZ_A));
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_DX_ADDR(0) |
+						   R500_DX_S_SWIZ_R |
+						   R500_DX_T_SWIZ_R |
+						   R500_DX_R_SWIZ_R |
+						   R500_DX_Q_SWIZ_R |
+						   R500_DY_ADDR(0) |
+						   R500_DY_S_SWIZ_R |
+						   R500_DY_T_SWIZ_R |
+						   R500_DY_R_SWIZ_R |
+						   R500_DY_Q_SWIZ_R));
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, 0x00000000);
+	    OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, 0x00000000);
+	}
+
+	OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_INST_TYPE_OUT |
+					       R500_INST_TEX_SEM_WAIT |
+					       R500_INST_LAST |
+					       R500_INST_RGB_OMASK_R |
+					       R500_INST_RGB_OMASK_G |
+					       R500_INST_RGB_OMASK_B |
+					       R500_INST_ALPHA_OMASK |
+					       R500_INST_RGB_CLAMP |
+					       R500_INST_ALPHA_CLAMP));
+
+	OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_RGB_ADDR0(0) |
+					       R500_RGB_ADDR1(1) |
+					       R500_RGB_ADDR2(0)));
+
+	OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALPHA_ADDR0(0) |
+					       R500_ALPHA_ADDR1(1) |
+					       R500_ALPHA_ADDR2(0)));
+
+	OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALU_RGB_SEL_A_SRC0 |
+					       src_color |
+					       R500_ALU_RGB_SEL_B_SRC1 |
+					       mask_color |
+					       R500_ALU_RGB_TARGET(0)));
+
+	OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALPHA_OP_MAD |
+					       R500_ALPHA_ADDRD(0) |
+					       R500_ALPHA_SEL_A_SRC0 |
+					       src_alpha |
+					       R500_ALPHA_SEL_B_SRC1 |
+					       mask_alpha |
+					       R500_ALPHA_TARGET(0)));
+
+	OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALU_RGBA_OP_MAD |
+					       R500_ALU_RGBA_ADDRD(0) |
+					       R500_ALU_RGBA_R_SWIZ_0 |
+					       R500_ALU_RGBA_G_SWIZ_0 |
+					       R500_ALU_RGBA_B_SWIZ_0 |
+					       R500_ALU_RGBA_A_SWIZ_0));
+	FINISH_ACCEL();
     }
 
-    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);
+    BEGIN_ACCEL(3);
+
+    OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
+    OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch);
 
-    /* Op operator. */
     blendcntl = RADEONGetBlendCntl(op, pMaskPicture, pDstPicture->format);
-    OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, blendcntl);
-#endif
+    OUT_ACCEL_REG(R300_RB3D_BLENDCNTL, blendcntl | R300_ALPHA_BLEND_ENABLE | R300_READ_ENABLE);
 
     FINISH_ACCEL();
 
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 62cc5d4..28539d4 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -178,15 +178,9 @@ 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);
 static void
 radeon_bios_output_dpms(xf86OutputPtr output, int mode);
 static void
@@ -239,6 +233,8 @@ avivo_display_ddc_connected(ScrnInfoPtr pScrn, xf86OutputPtr output)
 	    MonType = MT_DFP;
 	else if (radeon_output->type == OUTPUT_HDMI)
 	    MonType = MT_DFP;
+	else if (radeon_output->type == OUTPUT_DP)
+	    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
@@ -301,7 +297,7 @@ RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output)
 		   INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
 	    usleep(15000);
 
-	    MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, radeon_output->pI2CBus);
+	    MonInfo = xf86OutputGetEDID(output, radeon_output->pI2CBus);
 
 	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
 	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
@@ -324,7 +320,7 @@ RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output)
 	    if (MonInfo)  break;
 	}
     } else if (radeon_output->pI2CBus && info->ddc2 && ((DDCReg == RADEON_LCD_GPIO_MASK) || (DDCReg == RADEON_MDGPIO_EN_REG))) {
-         MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, radeon_output->pI2CBus);
+	MonInfo = xf86OutputGetEDID(output, radeon_output->pI2CBus);
     } else {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DDC2/I2C is not properly initialized\n");
 	MonType = MT_NONE;
@@ -673,15 +669,15 @@ radeon_bios_output_lock(xf86OutputPtr output, Bool lock)
 
     if (info->IsAtomBios) {
 	if (lock) {
-	    save->bios_6_scratch |= (ATOM_S6_CRITICAL_STATE | ATOM_S6_ACC_MODE);
+	    save->bios_6_scratch |= ATOM_S6_CRITICAL_STATE;
 	} else {
-	    save->bios_6_scratch &= ~(ATOM_S6_CRITICAL_STATE | ATOM_S6_ACC_MODE);
+	    save->bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE;
 	}
     } else {
 	if (lock) {
-	    save->bios_6_scratch |= (RADEON_DRIVER_CRITICAL | RADEON_ACC_MODE_CHANGE);
+	    save->bios_6_scratch |= RADEON_DRIVER_CRITICAL;
 	} else {
-	    save->bios_6_scratch &= ~(RADEON_DRIVER_CRITICAL | RADEON_ACC_MODE_CHANGE);
+	    save->bios_6_scratch &= ~RADEON_DRIVER_CRITICAL;
 	}
     }
     if (info->ChipFamily >= CHIP_FAMILY_R600)
@@ -1168,6 +1164,7 @@ static Atom tmds_pll_atom;
 static Atom rmx_atom;
 static Atom monitor_type_atom;
 static Atom load_detection_atom;
+static Atom coherent_mode_atom;
 static Atom tv_hsize_atom;
 static Atom tv_hpos_atom;
 static Atom tv_vpos_atom;
@@ -1235,6 +1232,30 @@ radeon_create_resources(xf86OutputPtr output)
 	}
     }
 
+    if (IS_DCE3_VARIANT &&
+	(OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI))) {
+	coherent_mode_atom = MAKE_ATOM("coherent_mode");
+
+	range[0] = 0; /* off */
+	range[1] = 1; /* on */
+	err = RRConfigureOutputProperty(output->randr_output, coherent_mode_atom,
+					FALSE, TRUE, FALSE, 2, range);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRConfigureOutputProperty error, %d\n", err);
+	}
+
+	data = 1; /* use coherent mode by default */
+
+	err = RRChangeOutputProperty(output->randr_output, coherent_mode_atom,
+				     XA_INTEGER, 32, PropModeReplace, 1, &data,
+				     FALSE, TRUE);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRChangeOutputProperty error, %d\n", err);
+	}
+    }
+
     if (OUTPUT_IS_DVI && radeon_output->TMDSType == TMDS_INT) {
 	tmds_pll_atom = MAKE_ATOM("tmds_pll");
 
@@ -1413,6 +1434,26 @@ radeon_create_resources(xf86OutputPtr output)
 }
 
 static Bool
+radeon_set_mode_for_property(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+
+    if (output->crtc) {
+	xf86CrtcPtr crtc = output->crtc;
+
+	if (crtc->enabled) {
+	    if (!xf86CrtcSetMode(crtc, &crtc->desiredMode, crtc->desiredRotation,
+				 crtc->desiredX, crtc->desiredY)) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "Failed to set mode after propery change!\n");
+		return FALSE;
+	    }
+	}
+    }
+    return TRUE;
+}
+
+static Bool
 radeon_set_property(xf86OutputPtr output, Atom property,
 		       RRPropertyValuePtr value)
 {
@@ -1451,22 +1492,47 @@ radeon_set_property(xf86OutputPtr output, Atom property,
 
 	radeon_output->load_detection = val;
 
+    } else if (property == coherent_mode_atom) {
+	Bool coherent_mode = radeon_output->coherent_mode;
+
+	if (value->type != XA_INTEGER ||
+	    value->format != 32 ||
+	    value->size != 1) {
+	    return FALSE;
+	}
+
+	val = *(INT32 *)value->data;
+	if (val < 0 || val > 1)
+	    return FALSE;
+
+	radeon_output->coherent_mode = val;
+	if (!radeon_set_mode_for_property(output)) {
+	    radeon_output->coherent_mode = coherent_mode;
+	    (void)radeon_set_mode_for_property(output);
+	    return FALSE;
+	}
+
     } else if (property == rmx_atom) {
 	const char *s;
+	RADEONRMXType rmx = radeon_output->rmx_type;
+
 	if (value->type != XA_STRING || value->format != 8)
 	    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("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"))) {
 	    radeon_output->rmx_type = RMX_OFF;
-	    return TRUE;
+	} else
+	    return FALSE;
+
+	if (!radeon_set_mode_for_property(output)) {
+	    radeon_output->rmx_type = rmx;
+	    (void)radeon_set_mode_for_property(output);
+	    return FALSE;
 	}
-	return FALSE;
     } else if (property == tmds_pll_atom) {
 	const char *s;
 	if (value->type != XA_STRING || value->format != 8)
@@ -1475,12 +1541,12 @@ radeon_set_property(xf86OutputPtr output, Atom property,
 	if (value->size == strlen("bios") && !strncmp("bios", s, strlen("bios"))) {
 	    if (!RADEONGetTMDSInfoFromBIOS(output))
 		RADEONGetTMDSInfoFromTable(output);
-	    return TRUE;
 	} else if (value->size == strlen("driver") && !strncmp("driver", s, strlen("driver"))) {
 	    RADEONGetTMDSInfoFromTable(output);
-	    return TRUE;
-	}
-	return FALSE;
+	} else
+	    return FALSE;
+
+	return radeon_set_mode_for_property(output);
     } else if (property == monitor_type_atom) {
 	const char *s;
 	if (value->type != XA_STRING || value->format != 8)
@@ -1495,8 +1561,8 @@ radeon_set_property(xf86OutputPtr output, Atom property,
 	} else if (value->size == strlen("digital") && !strncmp("digital", s, strlen("digital"))) {
 	    radeon_output->DVIType = DVI_DIGITAL;
 	    return TRUE;
-	}
-	return FALSE;
+	} else
+	    return FALSE;
     } else if (property == tv_hsize_atom) {
 	if (value->type != XA_INTEGER ||
 	    value->format != 32 ||
@@ -1511,7 +1577,7 @@ radeon_set_property(xf86OutputPtr output, Atom property,
 	radeon_output->hSize = val;
 	if (radeon_output->tv_on && !IS_AVIVO_VARIANT)
 	    RADEONUpdateHVPosition(output, &output->crtc->mode);
-	return TRUE;
+
     } else if (property == tv_hpos_atom) {
 	if (value->type != XA_INTEGER ||
 	    value->format != 32 ||
@@ -1526,7 +1592,7 @@ radeon_set_property(xf86OutputPtr output, Atom property,
 	radeon_output->hPos = val;
 	if (radeon_output->tv_on && !IS_AVIVO_VARIANT)
 	    RADEONUpdateHVPosition(output, &output->crtc->mode);
-	return TRUE;
+
     } else if (property == tv_vpos_atom) {
 	if (value->type != XA_INTEGER ||
 	    value->format != 32 ||
@@ -1541,38 +1607,38 @@ radeon_set_property(xf86OutputPtr output, Atom property,
 	radeon_output->vPos = val;
 	if (radeon_output->tv_on && !IS_AVIVO_VARIANT)
 	    RADEONUpdateHVPosition(output, &output->crtc->mode);
-	return TRUE;
+
     } else if (property == tv_std_atom) {
 	const char *s;
+	TVStd std = radeon_output->tvStd;
+
 	if (value->type != XA_STRING || value->format != 8)
 	    return FALSE;
 	s = (char*)value->data;
 	if (value->size == strlen("ntsc") && !strncmp("ntsc", s, strlen("ntsc"))) {
 	    radeon_output->tvStd = TV_STD_NTSC;
-	    return TRUE;
 	} else if (value->size == strlen("pal") && !strncmp("pal", s, strlen("pal"))) {
 	    radeon_output->tvStd = TV_STD_PAL;
-	    return TRUE;
 	} else if (value->size == strlen("pal-m") && !strncmp("pal-m", s, strlen("pal-m"))) {
 	    radeon_output->tvStd = TV_STD_PAL_M;
-	    return TRUE;
 	} else if (value->size == strlen("pal-60") && !strncmp("pal-60", s, strlen("pal-60"))) {
 	    radeon_output->tvStd = TV_STD_PAL_60;
-	    return TRUE;
 	} else if (value->size == strlen("ntsc-j") && !strncmp("ntsc-j", s, strlen("ntsc-j"))) {
 	    radeon_output->tvStd = TV_STD_NTSC_J;
-	    return TRUE;
 	} 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;
+	} else
+	    return FALSE;
+
+	if (!radeon_set_mode_for_property(output)) {
+	    radeon_output->tvStd = std;
+	    (void)radeon_set_mode_for_property(output);
+	    return FALSE;
 	}
-	return FALSE;
     }
 
     return TRUE;
@@ -1622,6 +1688,8 @@ void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output
     case CONNECTOR_HDMI_TYPE_A:
     case CONNECTOR_HDMI_TYPE_B:
 	output = OUTPUT_HDMI; break;
+    case CONNECTOR_DISPLAY_PORT:
+	output = OUTPUT_DP; break;
     case CONNECTOR_DIGITAL:
     case CONNECTOR_NONE:
     case CONNECTOR_UNSUPPORTED:
@@ -2139,16 +2207,17 @@ void RADEONInitConnector(xf86OutputPtr output)
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
-    if (radeon_output->DACType == DAC_PRIMARY)
+    if (info->IsAtomBios &&
+	((radeon_output->DACType == DAC_PRIMARY) ||
+	 (radeon_output->DACType == DAC_TVDAC)))
+	radeon_output->load_detection = 1;
+    else 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 */
+	radeon_output->load_detection = 0;
 
     if (radeon_output->type == OUTPUT_LVDS) {
 	radeon_output->rmx_type = RMX_FULL;
@@ -2189,6 +2258,9 @@ void RADEONInitConnector(xf86OutputPtr output)
 	RADEONGetTVDacAdjInfo(output);
     }
 
+    if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI))
+	radeon_output->coherent_mode = TRUE;
+
     if (radeon_output->ddc_i2c.valid)
 	RADEONI2CInit(output, &radeon_output->pI2CBus, output->name, FALSE);
 
@@ -2729,11 +2801,12 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 
     for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	if (info->BiosConnector[i].valid) {
+	    RADEONOutputPrivatePtr radeon_output;
 
 	    if (info->BiosConnector[i].ConnectorType == CONNECTOR_NONE)
 		continue;
 
-	    RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
+	    radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
 	    if (!radeon_output) {
 		return FALSE;
 	    }
@@ -2742,6 +2815,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	    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;
+	    radeon_output->igp_lane_info = info->BiosConnector[i].igp_lane_info;
 
 	    if (radeon_output->ConnectorType == CONNECTOR_DVI_D)
 		radeon_output->DACType = DAC_NONE;
diff --git a/src/radeon_pci_chipset_gen.h b/src/radeon_pci_chipset_gen.h
index ab6b62a..7bfae55 100644
--- a/src/radeon_pci_chipset_gen.h
+++ b/src/radeon_pci_chipset_gen.h
@@ -201,9 +201,9 @@ PciChipsets RADEONPciChipsets[] = {
  { 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_RV515_7200, PCI_CHIP_RV515_7200, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7210, PCI_CHIP_RV515_7210, RES_SHARED_VGA },
+ { PCI_CHIP_RV515_7211, PCI_CHIP_RV515_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 },
@@ -276,5 +276,24 @@ PciChipsets RADEONPciChipsets[] = {
  { 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 },
+ { PCI_CHIP_RV620_95C0, PCI_CHIP_RV620_95C0, RES_SHARED_VGA },
+ { PCI_CHIP_RV620_95C5, PCI_CHIP_RV620_95C5, RES_SHARED_VGA },
+ { PCI_CHIP_RV620_95C7, PCI_CHIP_RV620_95C7, RES_SHARED_VGA },
+ { PCI_CHIP_RV620_95C2, PCI_CHIP_RV620_95C2, RES_SHARED_VGA },
+ { PCI_CHIP_RV620_95C4, PCI_CHIP_RV620_95C4, RES_SHARED_VGA },
+ { PCI_CHIP_RV620_95CD, PCI_CHIP_RV620_95CD, RES_SHARED_VGA },
+ { PCI_CHIP_RV620_95CE, PCI_CHIP_RV620_95CE, RES_SHARED_VGA },
+ { PCI_CHIP_RV620_95CF, PCI_CHIP_RV620_95CF, RES_SHARED_VGA },
+ { PCI_CHIP_RV635_9590, PCI_CHIP_RV635_9590, RES_SHARED_VGA },
+ { PCI_CHIP_RV635_9596, PCI_CHIP_RV635_9596, RES_SHARED_VGA },
+ { PCI_CHIP_RV635_9597, PCI_CHIP_RV635_9597, RES_SHARED_VGA },
+ { PCI_CHIP_RV635_9598, PCI_CHIP_RV635_9598, RES_SHARED_VGA },
+ { PCI_CHIP_RV635_9599, PCI_CHIP_RV635_9599, RES_SHARED_VGA },
+ { PCI_CHIP_RV635_9591, PCI_CHIP_RV635_9591, RES_SHARED_VGA },
+ { PCI_CHIP_RV635_9593, PCI_CHIP_RV635_9593, RES_SHARED_VGA },
+ { PCI_CHIP_RS780_9610, PCI_CHIP_RS780_9610, RES_SHARED_VGA },
+ { PCI_CHIP_RS780_9611, PCI_CHIP_RS780_9611, RES_SHARED_VGA },
+ { PCI_CHIP_RS780_9612, PCI_CHIP_RS780_9612, RES_SHARED_VGA },
+ { PCI_CHIP_RS780_9613, PCI_CHIP_RS780_9613, RES_SHARED_VGA },
  { -1,                 -1,                 RES_UNDEFINED }
 };
diff --git a/src/radeon_pci_device_match_gen.h b/src/radeon_pci_device_match_gen.h
index 04393da..2a04f8d 100644
--- a/src/radeon_pci_device_match_gen.h
+++ b/src/radeon_pci_device_match_gen.h
@@ -201,9 +201,9 @@ static const struct pci_id_match radeon_device_match[] = {
  ATI_DEVICE_MATCH( PCI_CHIP_RV530_71D6, 0 ),
  ATI_DEVICE_MATCH( PCI_CHIP_RV530_71DA, 0 ),
  ATI_DEVICE_MATCH( PCI_CHIP_RV530_71DE, 0 ),
- ATI_DEVICE_MATCH( PCI_CHIP_RV530_7200, 0 ),
- ATI_DEVICE_MATCH( PCI_CHIP_RV530_7210, 0 ),
- ATI_DEVICE_MATCH( PCI_CHIP_RV530_7211, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV515_7200, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV515_7210, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV515_7211, 0 ),
  ATI_DEVICE_MATCH( PCI_CHIP_R580_7240, 0 ),
  ATI_DEVICE_MATCH( PCI_CHIP_R580_7243, 0 ),
  ATI_DEVICE_MATCH( PCI_CHIP_R580_7244, 0 ),
@@ -276,5 +276,24 @@ static const struct pci_id_match radeon_device_match[] = {
  ATI_DEVICE_MATCH( PCI_CHIP_RV630_958C, 0 ),
  ATI_DEVICE_MATCH( PCI_CHIP_RV630_958D, 0 ),
  ATI_DEVICE_MATCH( PCI_CHIP_RV630_958E, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV620_95C0, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV620_95C5, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV620_95C7, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV620_95C2, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV620_95C4, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV620_95CD, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV620_95CE, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV620_95CF, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV635_9590, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV635_9596, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV635_9597, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV635_9598, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV635_9599, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV635_9591, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV635_9593, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RS780_9610, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RS780_9611, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RS780_9612, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RS780_9613, 0 ),
  { 0, 0, 0 }
 };
diff --git a/src/radeon_probe.c b/src/radeon_probe.c
index 4ec7485..5d2eb43 100644
--- a/src/radeon_probe.c
+++ b/src/radeon_probe.c
@@ -60,7 +60,7 @@
 static Bool RADEONProbe(DriverPtr drv, int flags);
 #endif
 
-int gRADEONEntityIndex = -1;
+_X_EXPORT int gRADEONEntityIndex = -1;
 
 /* Return the options for supported chipset 'n'; NULL otherwise */
 static const OptionInfoRec *
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 9c1bdc5..0096ce0 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -104,7 +104,8 @@ typedef enum
     TMDS_INT     = 1,
     TMDS_EXT     = 2,
     TMDS_LVTMA   = 3,
-    TMDS_DDIA    = 4
+    TMDS_DDIA    = 4,
+    TMDS_UNIPHY  = 5
 } RADEONTmdsType;
 
 typedef enum
@@ -191,12 +192,7 @@ typedef struct _RADEONCrtcPrivateRec {
     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;
+    int can_tile;
 } RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr;
 
 typedef struct {
@@ -208,6 +204,7 @@ typedef struct {
     int devices;
     int hpd_mask;
     RADEONI2CBusRec ddc_i2c;
+    int igp_lane_info;
 } RADEONBIOSConnector;
 
 typedef struct _RADEONOutputPrivateRec {
@@ -256,6 +253,10 @@ typedef struct _RADEONOutputPrivateRec {
     int               SupportedTVStds;
     Bool              tv_on;
     int               load_detection;
+    /* dig block */
+    int transmitter_config;
+    Bool coherent_mode;
+    int igp_lane_info;
 
     char              *name;
     int               output_id;
@@ -310,24 +311,6 @@ struct avivo_grph_state {
 
     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
@@ -343,9 +326,6 @@ struct avivo_state
     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;
 
@@ -355,11 +335,41 @@ struct avivo_state
     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;
+    /* DDIA block on RS6xx chips */
+    CARD32 ddia[37];
+
+    /* scalers */
+    CARD32 d1scl[40];
+    CARD32 d2scl[40];
+    CARD32 dxscl[6+2];
+
+    /* dac regs */
+    CARD32 daca[26];
+    CARD32 dacb[26];
+
+    /* tmdsa */
+    CARD32 tmdsa[31];
+
+    /* lvtma */
+    CARD32 lvtma[39];
+
+    /* dvoa */
+    CARD32 dvoa[16];
+
+    /* DCE3 chips */
+    CARD32 fmt1[18];
+    CARD32 fmt2[18];
+    CARD32 dig1[19];
+    CARD32 dig2[19];
+    CARD32 hdmi1[57];
+    CARD32 hdmi2[57];
+    CARD32 aux_cntl1[14];
+    CARD32 aux_cntl2[14];
+    CARD32 aux_cntl3[14];
+    CARD32 aux_cntl4[14];
+    CARD32 phy[10];
+    CARD32 uniphy1[8];
+    CARD32 uniphy2[8];
 
 };
 
@@ -495,10 +505,16 @@ typedef struct {
     CARD32            palette[256];
     CARD32            palette2[256];
 
-    CARD32            rs480_unk_e30;
-    CARD32            rs480_unk_e34;
-    CARD32            rs480_unk_e38;
-    CARD32            rs480_unk_e3c;
+    CARD32            disp2_req_cntl1;
+    CARD32            disp2_req_cntl2;
+    CARD32            dmif_mem_cntl1;
+    CARD32            disp1_req_cntl1;
+
+    CARD32            fp_2nd_gen_cntl;
+    CARD32            fp2_2_gen_cntl;
+    CARD32            tmds2_cntl;
+    CARD32            tmds2_transmitter_cntl;
+
 
     /* TV out registers */
     CARD32 	      tv_master_cntl;
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 046c52b..dcfdbac 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -887,6 +887,33 @@
 #       define RADEON_VERT_STRETCH_BLEND       (1     << 26)
 #       define RADEON_VERT_AUTO_RATIO_EN       (1     << 27)
 #       define RADEON_VERT_STRETCH_RESERVED    0xf1000000
+#define RS400_FP_2ND_GEN_CNTL               0x0384
+#       define RS400_FP_2ND_ON              (1 << 0)
+#       define RS400_FP_2ND_BLANK_EN        (1 << 1)
+#       define RS400_TMDS_2ND_EN            (1 << 2)
+#       define RS400_PANEL_FORMAT_2ND       (1 << 3)
+#       define RS400_FP_2ND_EN_TMDS         (1 << 7)
+#       define RS400_FP_2ND_DETECT_SENSE    (1 << 8)
+#       define RS400_FP_2ND_SOURCE_SEL_MASK        (3 << 10)
+#       define RS400_FP_2ND_SOURCE_SEL_CRTC1       (0 << 10)
+#       define RS400_FP_2ND_SOURCE_SEL_CRTC2       (1 << 10)
+#       define RS400_FP_2ND_SOURCE_SEL_RMX         (2 << 10)
+#       define RS400_FP_2ND_DETECT_EN       (1 << 12)
+#       define RS400_HPD_2ND_SEL            (1 << 13)
+#define RS400_FP2_2_GEN_CNTL                0x0388
+#       define RS400_FP2_2_BLANK_EN         (1 << 1)
+#       define RS400_FP2_2_ON               (1 << 2)
+#       define RS400_FP2_2_PANEL_FORMAT     (1 << 3)
+#       define RS400_FP2_2_DETECT_SENSE     (1 << 8)
+#       define RS400_FP2_2_SOURCE_SEL_MASK        (3 << 10)
+#       define RS400_FP2_2_SOURCE_SEL_CRTC1       (0 << 10)
+#       define RS400_FP2_2_SOURCE_SEL_CRTC2       (1 << 10)
+#       define RS400_FP2_2_SOURCE_SEL_RMX         (2 << 10)
+#       define RS400_FP2_2_DVO2_EN          (1 << 25)
+#define RS400_TMDS2_CNTL                    0x0394
+#define RS400_TMDS2_TRANSMITTER_CNTL        0x03a4
+#       define RS400_TMDS2_PLLEN            (1 << 0)
+#       define RS400_TMDS2_PLLRST           (1 << 1)
 
 #define RADEON_GEN_INT_CNTL                 0x0040
 #define RADEON_GEN_INT_STATUS               0x0044
@@ -3328,10 +3355,32 @@
 #       define RADEON_TVPLL_TEST_DIS             (1 << 31)
 #       define RADEON_TVCLK_SRC_SEL_TVPLL        (1 << 30)
 
-#define RADEON_RS480_UNK_e30			0xe30
-#define RADEON_RS480_UNK_e34			0xe34
-#define RADEON_RS480_UNK_e38			0xe38
-#define RADEON_RS480_UNK_e3c			0xe3c
+#define RS400_DISP2_REQ_CNTL1			0xe30
+#       define RS400_DISP2_START_REQ_LEVEL_SHIFT   0
+#       define RS400_DISP2_START_REQ_LEVEL_MASK    0x3ff
+#       define RS400_DISP2_STOP_REQ_LEVEL_SHIFT    12
+#       define RS400_DISP2_STOP_REQ_LEVEL_MASK     0x3ff
+#       define RS400_DISP2_ALLOW_FID_LEVEL_SHIFT   22
+#       define RS400_DISP2_ALLOW_FID_LEVEL_MASK    0x3ff
+#define RS400_DISP2_REQ_CNTL2			0xe34
+#       define RS400_DISP2_CRITICAL_POINT_START_SHIFT    12
+#       define RS400_DISP2_CRITICAL_POINT_START_MASK     0x3ff
+#       define RS400_DISP2_CRITICAL_POINT_STOP_SHIFT     22
+#       define RS400_DISP2_CRITICAL_POINT_STOP_MASK      0x3ff
+#define RS400_DMIF_MEM_CNTL1			0xe38
+#       define RS400_DISP2_START_ADR_SHIFT      0
+#       define RS400_DISP2_START_ADR_MASK       0x3ff
+#       define RS400_DISP1_CRITICAL_POINT_START_SHIFT    12
+#       define RS400_DISP1_CRITICAL_POINT_START_MASK     0x3ff
+#       define RS400_DISP1_CRITICAL_POINT_STOP_SHIFT     22
+#       define RS400_DISP1_CRITICAL_POINT_STOP_MASK      0x3ff
+#define RS400_DISP1_REQ_CNTL1			0xe3c
+#       define RS400_DISP1_START_REQ_LEVEL_SHIFT   0
+#       define RS400_DISP1_START_REQ_LEVEL_MASK    0x3ff
+#       define RS400_DISP1_STOP_REQ_LEVEL_SHIFT    12
+#       define RS400_DISP1_STOP_REQ_LEVEL_MASK     0x3ff
+#       define RS400_DISP1_ALLOW_FID_LEVEL_SHIFT   22
+#       define RS400_DISP1_ALLOW_FID_LEVEL_MASK    0x3ff
 
 #define RS690_MC_INDEX				0x78
 #	define RS690_MC_INDEX_MASK		0x1ff
@@ -3555,6 +3604,8 @@
 #define AVIVO_D2SCL_SCALER_ENABLE               0x6d90
 #define AVIVO_D2SCL_SCALER_TAP_CONTROL	 	0x6d94
 
+#define AVIVO_DDIA_BIT_DEPTH_CONTROL				0x7214
+
 #define AVIVO_DACA_ENABLE					0x7800
 #	define AVIVO_DAC_ENABLE				(1 << 0)
 #define AVIVO_DACA_SOURCE_SELECT				0x7804
@@ -3745,6 +3796,8 @@
 #	define AVIVO_LVDS_BACKLIGHT_LEVEL_MASK		0x0000ff00
 #	define AVIVO_LVDS_BACKLIGHT_LEVEL_SHIFT		8
 
+#define AVIVO_DVOA_BIT_DEPTH_CONTROL			0x7988
+
 #define AVIVO_GPIO_0                        0x7e30
 #define AVIVO_GPIO_1                        0x7e40
 #define AVIVO_GPIO_2                        0x7e50
@@ -3986,6 +4039,123 @@
 #       define R300_PVS_LAST_VTX_SRC_INST_SHIFT         0
 #define R300_VAP_PVS_VECTOR_INDX_REG		        0x2200
 #define R300_VAP_PVS_VECTOR_DATA_REG		        0x2204
+/* PVS instructions */
+/* Opcode and dst instruction */
+#define R300_PVS_DST_OPCODE(x)                          (x << 0)
+/* Vector ops */
+#       define R300_VECTOR_NO_OP                        0
+#       define R300_VE_DOT_PRODUCT                      1
+#       define R300_VE_MULTIPLY                         2
+#       define R300_VE_ADD                              3
+#       define R300_VE_MULTIPLY_ADD                     4
+#       define R300_VE_DISTANCE_VECTOR                  5
+#       define R300_VE_FRACTION                         6
+#       define R300_VE_MAXIMUM                          7
+#       define R300_VE_MINIMUM                          8
+#       define R300_VE_SET_GREATER_THAN_EQUAL           9
+#       define R300_VE_SET_LESS_THAN                    10
+#       define R300_VE_MULTIPLYX2_ADD                   11
+#       define R300_VE_MULTIPLY_CLAMP                   12
+#       define R300_VE_FLT2FIX_DX                       13
+#       define R300_VE_FLT2FIX_DX_RND                   14
+/* R500 additions */
+#       define R500_VE_PRED_SET_EQ_PUSH                 15
+#       define R500_VE_PRED_SET_GT_PUSH                 16
+#       define R500_VE_PRED_SET_GTE_PUSH                17
+#       define R500_VE_PRED_SET_NEQ_PUSH                18
+#       define R500_VE_COND_WRITE_EQ                    19
+#       define R500_VE_COND_WRITE_GT                    20
+#       define R500_VE_COND_WRITE_GTE                   21
+#       define R500_VE_COND_WRITE_NEQ                   22
+#       define R500_VE_COND_MUX_EQ                      23
+#       define R500_VE_COND_MUX_GT                      24
+#       define R500_VE_COND_MUX_GTE                     25
+#       define R500_VE_SET_GREATER_THAN                 26
+#       define R500_VE_SET_EQUAL                        27
+#       define R500_VE_SET_NOT_EQUAL                    28
+/* Math ops */
+#       define R300_MATH_NO_OP                          0
+#       define R300_ME_EXP_BASE2_DX                     1
+#       define R300_ME_LOG_BASE2_DX                     2
+#       define R300_ME_EXP_BASEE_FF                     3
+#       define R300_ME_LIGHT_COEFF_DX                   4
+#       define R300_ME_POWER_FUNC_FF                    5
+#       define R300_ME_RECIP_DX                         6
+#       define R300_ME_RECIP_FF                         7
+#       define R300_ME_RECIP_SQRT_DX                    8
+#       define R300_ME_RECIP_SQRT_FF                    9
+#       define R300_ME_MULTIPLY                         10
+#       define R300_ME_EXP_BASE2_FULL_DX                11
+#       define R300_ME_LOG_BASE2_FULL_DX                12
+#       define R300_ME_POWER_FUNC_FF_CLAMP_B            13
+#       define R300_ME_POWER_FUNC_FF_CLAMP_B1           14
+#       define R300_ME_POWER_FUNC_FF_CLAMP_01           15
+#       define R300_ME_SIN                              16
+#       define R300_ME_COS                              17
+/* R500 additions */
+#       define R500_ME_LOG_BASE2_IEEE                   18
+#       define R500_ME_RECIP_IEEE                       19
+#       define R500_ME_RECIP_SQRT_IEEE                  20
+#       define R500_ME_PRED_SET_EQ                      21
+#       define R500_ME_PRED_SET_GT                      22
+#       define R500_ME_PRED_SET_GTE                     23
+#       define R500_ME_PRED_SET_NEQ                     24
+#       define R500_ME_PRED_SET_CLR                     25
+#       define R500_ME_PRED_SET_INV                     26
+#       define R500_ME_PRED_SET_POP                     27
+#       define R500_ME_PRED_SET_RESTORE                 28
+/* macro */
+#       define R300_PVS_MACRO_OP_2CLK_MADD              0
+#       define R300_PVS_MACRO_OP_2CLK_M2X_ADD           1
+#define R300_PVS_DST_MATH_INST                          (1 << 6)
+#define R300_PVS_DST_MACRO_INST                         (1 << 7)
+#define R300_PVS_DST_REG_TYPE(x)                        (x << 8)
+#       define R300_PVS_DST_REG_TEMPORARY               0
+#       define R300_PVS_DST_REG_A0                      1
+#       define R300_PVS_DST_REG_OUT                     2
+#       define R500_PVS_DST_REG_OUT_REPL_X              3
+#       define R300_PVS_DST_REG_ALT_TEMPORARY           4
+#       define R300_PVS_DST_REG_INPUT                   5
+#define R300_PVS_DST_ADDR_MODE_1                        (1 << 12)
+#define R300_PVS_DST_OFFSET(x)                          (x << 13)
+#define R300_PVS_DST_WE_X                               (1 << 20)
+#define R300_PVS_DST_WE_Y                               (1 << 21)
+#define R300_PVS_DST_WE_Z                               (1 << 22)
+#define R300_PVS_DST_WE_W                               (1 << 23)
+#define R300_PVS_DST_VE_SAT                             (1 << 24)
+#define R300_PVS_DST_ME_SAT                             (1 << 25)
+#define R300_PVS_DST_PRED_ENABLE                        (1 << 26)
+#define R300_PVS_DST_PRED_SENSE                         (1 << 27)
+#define R300_PVS_DST_DUAL_MATH_OP                       (1 << 28)
+#define R300_PVS_DST_ADDR_SEL(x)                        (x << 29)
+#define R300_PVS_DST_ADDR_MODE_0                        (1 << 31)
+/* src operand instruction */
+#define R300_PVS_SRC_REG_TYPE(x)                        (x << 0)
+#       define R300_PVS_SRC_REG_TEMPORARY               0
+#       define R300_PVS_SRC_REG_INPUT                   1
+#       define R300_PVS_SRC_REG_CONSTANT                2
+#       define R300_PVS_SRC_REG_ALT_TEMPORARY           3
+#define R300_SPARE_0                                    (1 << 2)
+#define R300_PVS_SRC_ABS_XYZW                           (1 << 3)
+#define R300_PVS_SRC_ADDR_MODE_0                        (1 << 4)
+#define R300_PVS_SRC_OFFSET(x)                          (x << 5)
+#define R300_PVS_SRC_SWIZZLE_X(x)                       (x << 13)
+#define R300_PVS_SRC_SWIZZLE_Y(x)                       (x << 16)
+#define R300_PVS_SRC_SWIZZLE_Z(x)                       (x << 19)
+#define R300_PVS_SRC_SWIZZLE_W(x)                       (x << 22)
+#       define R300_PVS_SRC_SELECT_X                    0
+#       define R300_PVS_SRC_SELECT_Y                    1
+#       define R300_PVS_SRC_SELECT_Z                    2
+#       define R300_PVS_SRC_SELECT_W                    3
+#       define R300_PVS_SRC_SELECT_FORCE_0              4
+#       define R300_PVS_SRC_SELECT_FORCE_1              5
+#define R300_PVS_SRC_NEG_X                              (1 << 25)
+#define R300_PVS_SRC_NEG_Y                              (1 << 26)
+#define R300_PVS_SRC_NEG_Z                              (1 << 27)
+#define R300_PVS_SRC_NEG_W                              (1 << 28)
+#define R300_PVS_SRC_ADDR_SEL(x)                        (x << 29)
+#define R300_PVS_SRC_ADDR_MODE_1                        (1 << 31)
+
 #define R300_VAP_PVS_FLOW_CNTL_OPC		        0x22DC
 #define R300_VAP_OUT_VTX_FMT_0			        0x2090
 #       define R300_VTX_POS_PRESENT                     (1 << 0)
@@ -4019,6 +4189,7 @@
 #       define R300_CLIP_DISABLE                        (1 << 16)
 #       define R300_UCP_CULL_ONLY_ENA                   (1 << 17)
 #       define R300_BOUNDARY_EDGE_FLAG_ENA              (1 << 18)
+#define R300_VAP_PVS_STATE_FLUSH_REG			0x2284
 
 #define R300_SU_TEX_WRAP				0x42a0
 #define R300_SU_POLY_OFFSET_ENABLE		        0x42b4
@@ -4036,6 +4207,7 @@
 #	define R300_RS_COUNT_HIRES_EN			(1 << 18)
 
 #define R300_RS_IP_0				        0x4310
+#define R300_RS_IP_1				        0x4314
 #	define R300_RS_TEX_PTR(x)		        (x << 0)
 #	define R300_RS_COL_PTR(x)		        (x << 6)
 #	define R300_RS_COL_FMT(x)		        (x << 9)
@@ -4063,7 +4235,10 @@
 #	define R300_RS_W_EN			        (1 << 4)
 #	define R300_TX_OFFSET_RS(x)		        (x << 5)
 #define R300_RS_INST_0				        0x4330
+#define R300_RS_INST_1				        0x4334
+#	define R300_INST_TEX_ID(x)		        (x << 0)
 #       define R300_RS_INST_TEX_CN_WRITE		(1 << 3)
+#	define R300_INST_TEX_ADDR(x)		        (x << 6)
 
 #define R300_TX_INVALTAGS				0x4100
 #define R300_TX_FILTER0_0				0x4400
@@ -4082,6 +4257,7 @@
 #       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_ID_SHIFT                         28
 #define R300_TX_FILTER1_0				0x4440
 #define R300_TX_FORMAT0_0				0x4480
 #       define R300_TXWIDTH_SHIFT                       0
@@ -4164,11 +4340,14 @@
 #       define R300_TX_FORMAT_SWAP_YUV                 (1 << 24)
 
 #define R300_TX_FORMAT2_0				0x4500
+#       define R500_TXWIDTH_11                          (1 << 15)
+#       define R500_TXHEIGHT_11                         (1 << 16)
+
 #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_MACRO_TILE                          (1 << 2)
 
 #define R300_TX_ENABLE				        0x4104
 #       define R300_TEX_0_ENABLE                        (1 << 0)
@@ -4189,7 +4368,7 @@
 #       define R300_OUT_FMT_C2_16_MPEG                  (7 << 0)
 #       define R300_OUT_FMT_C2_4                        (8 << 0)
 #       define R300_OUT_FMT_C_3_3_2                     (9 << 0)
-#       define R300_OUT_FMT_C_6_5_6                     (10 << 0)
+#       define R300_OUT_FMT_C_5_6_5                     (10 << 0)
 #       define R300_OUT_FMT_C_11_11_10                  (11 << 0)
 #       define R300_OUT_FMT_C_10_11_11                  (12 << 0)
 #       define R300_OUT_FMT_C_2_10_10_10                (13 << 0)
@@ -4227,14 +4406,197 @@
 #       define R300_TEX_CODE_OFFSET(x)                  (x << 13)
 #       define R300_TEX_CODE_SIZE(x)                    (x << 18)
 #define R300_US_CODE_ADDR_0				0x4610
+#       define R300_ALU_START(x)                        (x << 0)
+#       define R300_ALU_SIZE(x)                         (x << 6)
+#       define R300_TEX_START(x)                        (x << 12)
+#       define R300_TEX_SIZE(x)                         (x << 17)
+#       define R300_RGBA_OUT                            (1 << 22)
+#       define R300_W_OUT                               (1 << 23)
 #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_TEX_INST_1				0x4624
+#define R300_US_TEX_INST_2				0x4628
+#       define R300_TEX_SRC_ADDR(x)                     (x << 0)
+#       define R300_TEX_DST_ADDR(x)                     (x << 6)
+#       define R300_TEX_ID(x)                           (x << 11)
+#       define R300_TEX_INST(x)                         (x << 15)
+#       define R300_TEX_INST_NOP                        0
+#       define R300_TEX_INST_LD                         1
+#       define R300_TEX_INST_TEXKILL                    2
+#       define R300_TEX_INST_PROJ                       3
+#       define R300_TEX_INST_LODBIAS                    4
 #define R300_US_ALU_RGB_ADDR_0			        0x46c0
+#define R300_US_ALU_RGB_ADDR_1			        0x46c4
+#define R300_US_ALU_RGB_ADDR_2			        0x46c8
+/* for ADDR0-2, values 0-31 specify a location in the pixel stack,
+   values 32-63 specify a constant */
+#       define R300_ALU_RGB_ADDR0(x)                    (x << 0)
+#       define R300_ALU_RGB_ADDR1(x)                    (x << 6)
+#       define R300_ALU_RGB_ADDR2(x)                    (x << 12)
+/* ADDRD - where on the pixle stack the result of this instruction
+   will be written */
+#       define R300_ALU_RGB_ADDRD(x)                    (x << 18)
+#       define R300_ALU_RGB_WMASK(x)                    (x << 23)
+#       define R300_ALU_RGB_OMASK(x)                    (x << 26)
+#       define R300_ALU_RGB_MASK_NONE                   0
+#       define R300_ALU_RGB_MASK_R                      1
+#       define R300_ALU_RGB_MASK_G                      2
+#       define R300_ALU_RGB_MASK_B                      4
+#       define R300_ALU_RGB_TARGET_A                    (0 << 29)
+#       define R300_ALU_RGB_TARGET_B                    (1 << 29)
+#       define R300_ALU_RGB_TARGET_C                    (2 << 29)
+#       define R300_ALU_RGB_TARGET_D                    (3 << 29)
 #define R300_US_ALU_RGB_INST_0			        0x48c0
+#define R300_US_ALU_RGB_INST_1			        0x48c4
+#define R300_US_ALU_RGB_INST_2			        0x48c8
+#       define R300_ALU_RGB_SEL_A(x)                    (x << 0)
+#       define R300_ALU_RGB_SRC0_RGB                    0
+#       define R300_ALU_RGB_SRC0_RRR                    1
+#       define R300_ALU_RGB_SRC0_GGG                    2
+#       define R300_ALU_RGB_SRC0_BBB                    3
+#       define R300_ALU_RGB_SRC1_RGB                    4
+#       define R300_ALU_RGB_SRC1_RRR                    5
+#       define R300_ALU_RGB_SRC1_GGG                    6
+#       define R300_ALU_RGB_SRC1_BBB                    7
+#       define R300_ALU_RGB_SRC2_RGB                    8
+#       define R300_ALU_RGB_SRC2_RRR                    9
+#       define R300_ALU_RGB_SRC2_GGG                    10
+#       define R300_ALU_RGB_SRC2_BBB                    11
+#       define R300_ALU_RGB_SRC0_AAA                    12
+#       define R300_ALU_RGB_SRC1_AAA                    13
+#       define R300_ALU_RGB_SRC2_AAA                    14
+#       define R300_ALU_RGB_SRCP_RGB                    15
+#       define R300_ALU_RGB_SRCP_RRR                    16
+#       define R300_ALU_RGB_SRCP_GGG                    17
+#       define R300_ALU_RGB_SRCP_BBB                    18
+#       define R300_ALU_RGB_SRCP_AAA                    19
+#       define R300_ALU_RGB_0_0                         20
+#       define R300_ALU_RGB_1_0                         21
+#       define R300_ALU_RGB_0_5                         22
+#       define R300_ALU_RGB_SRC0_GBR                    23
+#       define R300_ALU_RGB_SRC1_GBR                    24
+#       define R300_ALU_RGB_SRC2_GBR                    25
+#       define R300_ALU_RGB_SRC0_BRG                    26
+#       define R300_ALU_RGB_SRC1_BRG                    27
+#       define R300_ALU_RGB_SRC2_BRG                    28
+#       define R300_ALU_RGB_SRC0_ABG                    29
+#       define R300_ALU_RGB_SRC1_ABG                    30
+#       define R300_ALU_RGB_SRC2_ABG                    31
+#       define R300_ALU_RGB_MOD_A(x)                    (x << 5)
+#       define R300_ALU_RGB_MOD_NOP                     0
+#       define R300_ALU_RGB_MOD_NEG                     1
+#       define R300_ALU_RGB_MOD_ABS                     2
+#       define R300_ALU_RGB_MOD_NAB                     3
+#       define R300_ALU_RGB_SEL_B(x)                    (x << 7)
+#       define R300_ALU_RGB_MOD_B(x)                    (x << 12)
+#       define R300_ALU_RGB_SEL_C(x)                    (x << 14)
+#       define R300_ALU_RGB_MOD_C(x)                    (x << 19)
+#       define R300_ALU_RGB_SRCP_OP(x)                  (x << 21)
+#       define R300_ALU_RGB_SRCP_OP_1_MINUS_2RGB0	0
+#       define R300_ALU_RGB_SRCP_OP_RGB1_MINUS_RGB0	1
+#       define R300_ALU_RGB_SRCP_OP_RGB1_PLUS_RGB0	2
+#       define R300_ALU_RGB_SRCP_OP_1_MINUS_RGB0	3
+#       define R300_ALU_RGB_OP(x)                       (x << 23)
+#       define R300_ALU_RGB_OP_MAD                      0
+#       define R300_ALU_RGB_OP_DP3                      1
+#       define R300_ALU_RGB_OP_DP4                      2
+#       define R300_ALU_RGB_OP_D2A                      3
+#       define R300_ALU_RGB_OP_MIN                      4
+#       define R300_ALU_RGB_OP_MAX                      5
+#       define R300_ALU_RGB_OP_CND                      7
+#       define R300_ALU_RGB_OP_CMP                      8
+#       define R300_ALU_RGB_OP_FRC                      9
+#       define R300_ALU_RGB_OP_SOP                      10
+#       define R300_ALU_RGB_OMOD(x)                     (x << 27)
+#       define R300_ALU_RGB_OMOD_NONE                   0
+#       define R300_ALU_RGB_OMOD_MUL_2                  1
+#       define R300_ALU_RGB_OMOD_MUL_4                  2
+#       define R300_ALU_RGB_OMOD_MUL_8                  3
+#       define R300_ALU_RGB_OMOD_DIV_2                  4
+#       define R300_ALU_RGB_OMOD_DIV_4                  5
+#       define R300_ALU_RGB_OMOD_DIV_8                  6
+#       define R300_ALU_RGB_CLAMP                       (1 << 30)
+#       define R300_ALU_RGB_INSERT_NOP                  (1 << 31)
 #define R300_US_ALU_ALPHA_ADDR_0		        0x47c0
+#define R300_US_ALU_ALPHA_ADDR_1		        0x47c4
+#define R300_US_ALU_ALPHA_ADDR_2		        0x47c8
+/* for ADDR0-2, values 0-31 specify a location in the pixel stack,
+   values 32-63 specify a constant */
+#       define R300_ALU_ALPHA_ADDR0(x)                  (x << 0)
+#       define R300_ALU_ALPHA_ADDR1(x)                  (x << 6)
+#       define R300_ALU_ALPHA_ADDR2(x)                  (x << 12)
+/* ADDRD - where on the pixle stack the result of this instruction
+   will be written */
+#       define R300_ALU_ALPHA_ADDRD(x)                  (x << 18)
+#       define R300_ALU_ALPHA_WMASK(x)                  (x << 23)
+#       define R300_ALU_ALPHA_OMASK(x)                  (x << 24)
+#       define R300_ALU_ALPHA_OMASK_W(x)                (x << 27)
+#       define R300_ALU_ALPHA_MASK_NONE                 0
+#       define R300_ALU_ALPHA_MASK_A                    1
+#       define R300_ALU_ALPHA_TARGET_A                  (0 << 25)
+#       define R300_ALU_ALPHA_TARGET_B                  (1 << 25)
+#       define R300_ALU_ALPHA_TARGET_C                  (2 << 25)
+#       define R300_ALU_ALPHA_TARGET_D                  (3 << 25)
 #define R300_US_ALU_ALPHA_INST_0		        0x49c0
+#define R300_US_ALU_ALPHA_INST_1		        0x49c4
+#define R300_US_ALU_ALPHA_INST_2		        0x49c8
+#       define R300_ALU_ALPHA_SEL_A(x)                  (x << 0)
+#       define R300_ALU_ALPHA_SRC0_R                    0
+#       define R300_ALU_ALPHA_SRC0_G                    1
+#       define R300_ALU_ALPHA_SRC0_B                    2
+#       define R300_ALU_ALPHA_SRC1_R                    3
+#       define R300_ALU_ALPHA_SRC1_G                    4
+#       define R300_ALU_ALPHA_SRC1_B                    5
+#       define R300_ALU_ALPHA_SRC2_R                    6
+#       define R300_ALU_ALPHA_SRC2_G                    7
+#       define R300_ALU_ALPHA_SRC2_B                    8
+#       define R300_ALU_ALPHA_SRC0_A                    9
+#       define R300_ALU_ALPHA_SRC1_A                    10
+#       define R300_ALU_ALPHA_SRC2_A                    11
+#       define R300_ALU_ALPHA_SRCP_R                    12
+#       define R300_ALU_ALPHA_SRCP_G                    13
+#       define R300_ALU_ALPHA_SRCP_B                    14
+#       define R300_ALU_ALPHA_SRCP_A                    15
+#       define R300_ALU_ALPHA_0_0                       16
+#       define R300_ALU_ALPHA_1_0                       17
+#       define R300_ALU_ALPHA_0_5                       18
+#       define R300_ALU_ALPHA_MOD_A(x)                  (x << 5)
+#       define R300_ALU_ALPHA_MOD_NOP                   0
+#       define R300_ALU_ALPHA_MOD_NEG                   1
+#       define R300_ALU_ALPHA_MOD_ABS                   2
+#       define R300_ALU_ALPHA_MOD_NAB                   3
+#       define R300_ALU_ALPHA_SEL_B(x)                  (x << 7)
+#       define R300_ALU_ALPHA_MOD_B(x)                  (x << 12)
+#       define R300_ALU_ALPHA_SEL_C(x)                  (x << 14)
+#       define R300_ALU_ALPHA_MOD_C(x)                  (x << 19)
+#       define R300_ALU_ALPHA_SRCP_OP(x)                (x << 21)
+#       define R300_ALU_ALPHA_SRCP_OP_1_MINUS_2RGB0	0
+#       define R300_ALU_ALPHA_SRCP_OP_RGB1_MINUS_RGB0	1
+#       define R300_ALU_ALPHA_SRCP_OP_RGB1_PLUS_RGB0	2
+#       define R300_ALU_ALPHA_SRCP_OP_1_MINUS_RGB0	3
+#       define R300_ALU_ALPHA_OP(x)                     (x << 23)
+#       define R300_ALU_ALPHA_OP_MAD                    0
+#       define R300_ALU_ALPHA_OP_DP                     1
+#       define R300_ALU_ALPHA_OP_MIN                    2
+#       define R300_ALU_ALPHA_OP_MAX                    3
+#       define R300_ALU_ALPHA_OP_CND                    5
+#       define R300_ALU_ALPHA_OP_CMP                    6
+#       define R300_ALU_ALPHA_OP_FRC                    7
+#       define R300_ALU_ALPHA_OP_EX2                    8
+#       define R300_ALU_ALPHA_OP_LN2                    9
+#       define R300_ALU_ALPHA_OP_RCP                    10
+#       define R300_ALU_ALPHA_OP_RSQ                    11
+#       define R300_ALU_ALPHA_OMOD(x)                   (x << 27)
+#       define R300_ALU_ALPHA_OMOD_NONE                 0
+#       define R300_ALU_ALPHA_OMOD_MUL_2                1
+#       define R300_ALU_ALPHA_OMOD_MUL_4                2
+#       define R300_ALU_ALPHA_OMOD_MUL_8                3
+#       define R300_ALU_ALPHA_OMOD_DIV_2                4
+#       define R300_ALU_ALPHA_OMOD_DIV_4                5
+#       define R300_ALU_ALPHA_OMOD_DIV_8                6
+#       define R300_ALU_ALPHA_CLAMP                     (1 << 30)
 
 #define R300_FG_DEPTH_SRC				0x4bd8
 #define R300_FG_FOG_BLEND				0x4bc0
@@ -4256,6 +4618,9 @@
 #define R300_RB3D_ZTOP				        0x4f14
 #define R300_RB3D_ROPCNTL				0x4e18
 #define R300_RB3D_BLENDCNTL				0x4e04
+#       define R300_ALPHA_BLEND_ENABLE                  (1 << 0)
+#       define R300_SEPARATE_ALPHA_ENABLE               (1 << 1)
+#       define R300_READ_ENABLE                         (1 << 2)
 #define R300_RB3D_ABLENDCNTL			        0x4e08
 #define R300_RB3D_DSTCACHE_CTLSTAT		        0x4e4c
 #define R300_RB3D_COLOROFFSET0			        0x4e28
@@ -4387,7 +4752,7 @@
 #   define R500_ALPHA_SRCP_OP_1_MINUS_2A0		(0 << 30)
 #   define R500_ALPHA_SRCP_OP_A1_MINUS_A0		(1 << 30)
 #   define R500_ALPHA_SRCP_OP_A1_PLUS_A0		(2 << 30)
-#   define R500_ALPHA_SRCP_OP_1_PLUS_A0			(3 << 30)
+#   define R500_ALPHA_SRCP_OP_1_MINUS_A0		(3 << 30)
 #define R500_US_ALU_RGBA_INST_0				0xb000
 #   define R500_ALU_RGBA_OP_MAD				(0 << 0)
 #   define R500_ALU_RGBA_OP_DP3				(1 << 0)
@@ -4540,7 +4905,7 @@
 #   define R500_RGB_SRCP_OP_1_MINUS_2RGB0		(0 << 30)
 #   define R500_RGB_SRCP_OP_RGB1_MINUS_RGB0		(1 << 30)
 #   define R500_RGB_SRCP_OP_RGB1_PLUS_RGB0		(2 << 30)
-#   define R500_RGB_SRCP_OP_1_PLUS_RGB0			(3 << 30)
+#   define R500_RGB_SRCP_OP_1_MINUS_RGB0		(3 << 30)
 #define R500_US_CMN_INST_0				0xb800
 #   define R500_INST_TYPE_ALU				(0 << 0)
 #   define R500_INST_TYPE_OUT				(1 << 0)
@@ -4779,17 +5144,18 @@
 #define R500_GA_US_VECTOR_DATA 0x4254
 
 #define R500_RS_INST_0					0x4320
-#define R500_RS_INST_TEX_ID_SHIFT			0
-#define R500_RS_INST_TEX_CN_WRITE			(1 << 4)
-#define R500_RS_INST_TEX_ADDR_SHIFT			5
-#define R500_RS_INST_COL_ID_SHIFT			12
-#define R500_RS_INST_COL_CN_NO_WRITE			(0 << 16)
-#define R500_RS_INST_COL_CN_WRITE			(1 << 16)
-#define R500_RS_INST_COL_CN_WRITE_FBUFFER		(2 << 16)
-#define R500_RS_INST_COL_CN_WRITE_BACKFACE		(3 << 16)
-#define R500_RS_INST_COL_COL_ADDR_SHIFT			18
-#define R500_RS_INST_TEX_ADJ				(1 << 25)
-#define R500_RS_INST_W_CN				(1 << 26)
+#define R500_RS_INST_1					0x4324
+#   define R500_RS_INST_TEX_ID_SHIFT			0
+#   define R500_RS_INST_TEX_CN_WRITE			(1 << 4)
+#   define R500_RS_INST_TEX_ADDR_SHIFT			5
+#   define R500_RS_INST_COL_ID_SHIFT			12
+#   define R500_RS_INST_COL_CN_NO_WRITE			(0 << 16)
+#   define R500_RS_INST_COL_CN_WRITE			(1 << 16)
+#   define R500_RS_INST_COL_CN_WRITE_FBUFFER		(2 << 16)
+#   define R500_RS_INST_COL_CN_WRITE_BACKFACE		(3 << 16)
+#   define R500_RS_INST_COL_COL_ADDR_SHIFT		18
+#   define R500_RS_INST_TEX_ADJ				(1 << 25)
+#   define R500_RS_INST_W_CN				(1 << 26)
 
 #define R500_US_FC_CTRL					0x4624
 #define R500_US_CODE_ADDR				0x4630
@@ -4797,16 +5163,17 @@
 #define R500_US_CODE_OFFSET 				0x4638
 
 #define R500_RS_IP_0					0x4074
-#define R500_RS_IP_PTR_K0				62
-#define R500_RS_IP_PTR_K1 				63
-#define R500_RS_IP_TEX_PTR_S_SHIFT 			0
-#define R500_RS_IP_TEX_PTR_T_SHIFT 			6
-#define R500_RS_IP_TEX_PTR_R_SHIFT 			12
-#define R500_RS_IP_TEX_PTR_Q_SHIFT 			18
-#define R500_RS_IP_COL_PTR_SHIFT 			24
-#define R500_RS_IP_COL_FMT_SHIFT 			27
-#define R500_RS_IP_COL_FMT_RGBA				(0<<27)
-#define R500_RS_IP_OFFSET_EN 				(1 << 31)
+#define R500_RS_IP_1					0x4078
+#   define R500_RS_IP_PTR_K0				62
+#   define R500_RS_IP_PTR_K1 				63
+#   define R500_RS_IP_TEX_PTR_S_SHIFT 			0
+#   define R500_RS_IP_TEX_PTR_T_SHIFT 			6
+#   define R500_RS_IP_TEX_PTR_R_SHIFT 			12
+#   define R500_RS_IP_TEX_PTR_Q_SHIFT 			18
+#   define R500_RS_IP_COL_PTR_SHIFT 			24
+#   define R500_RS_IP_COL_FMT_SHIFT 			27
+#   define R500_RS_IP_COL_FMT_RGBA			(0 << 27)
+#   define R500_RS_IP_OFFSET_EN 			(1 << 31)
 
 
 #endif
diff --git a/src/radeon_render.c b/src/radeon_render.c
index a80d136..950753c 100644
--- a/src/radeon_render.c
+++ b/src/radeon_render.c
@@ -250,10 +250,17 @@ static __inline__ int
 ATILog2(int val)
 {
 	int bits;
-
+#if (defined __i386__ || defined __x86_64__) && (defined __GNUC__)
+	__asm volatile("bsrl	%1, %0"
+		: "=r" (bits)
+		: "c" (val)
+	);
+	return bits;
+#else
 	for (bits = 0; val != 0; val >>= 1, ++bits)
 		;
 	return bits - 1;
+#endif
 }
 
 static void
diff --git a/src/radeon_textured_video.c b/src/radeon_textured_video.c
index 329a834..0a6598d 100644
--- a/src/radeon_textured_video.c
+++ b/src/radeon_textured_video.c
@@ -46,6 +46,9 @@
 #define IMAGE_MAX_WIDTH		2048
 #define IMAGE_MAX_HEIGHT	2048
 
+#define IMAGE_MAX_WIDTH_R500	4096
+#define IMAGE_MAX_HEIGHT_R500	4096
+
 static Bool
 RADEONTilingEnabled(ScrnInfoPtr pScrn, PixmapPtr pPix)
 {
@@ -60,7 +63,7 @@ RADEONTilingEnabled(ScrnInfoPtr pScrn, PixmapPtr pPix)
     } else
 #endif
 	{
-	    if (info->tilingEnabled)
+	    if (info->tilingEnabled && ((pPix->devPrivate.ptr - info->FB) == 0))
 		return TRUE;
 	    else
 		return FALSE;
@@ -300,6 +303,16 @@ static XF86VideoEncodingRec DummyEncoding[1] =
     }
 };
 
+static XF86VideoEncodingRec DummyEncodingR500[1] =
+{
+    {
+	0,
+	"XV_IMAGE",
+	IMAGE_MAX_WIDTH_R500, IMAGE_MAX_HEIGHT_R500,
+	{1, 1}
+    }
+};
+
 #define NUM_FORMATS 3
 
 static XF86VideoFormatRec Formats[NUM_FORMATS] =
@@ -326,6 +339,8 @@ static XF86ImageRec Images[NUM_IMAGES] =
 XF86VideoAdaptorPtr
 RADEONSetupImageTexturedVideo(ScreenPtr pScreen)
 {
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    RADEONInfoPtr    info = RADEONPTR(pScrn);
     RADEONPortPrivPtr pPortPriv;
     XF86VideoAdaptorPtr adapt;
     int i;
@@ -340,7 +355,10 @@ RADEONSetupImageTexturedVideo(ScreenPtr pScreen)
     adapt->flags = 0;
     adapt->name = "Radeon Textured Video";
     adapt->nEncodings = 1;
-    adapt->pEncodings = DummyEncoding;
+    if (IS_R500_3D)
+	adapt->pEncodings = DummyEncodingR500;
+    else
+	adapt->pEncodings = DummyEncoding;
     adapt->nFormats = NUM_FORMATS;
     adapt->pFormats = Formats;
     adapt->nPorts = num_texture_ports;
diff --git a/src/radeon_textured_videofuncs.c b/src/radeon_textured_videofuncs.c
index e0f3bba..45dc0c9 100644
--- a/src/radeon_textured_videofuncs.c
+++ b/src/radeon_textured_videofuncs.c
@@ -80,10 +80,9 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
     CARD32 txenable, colorpitch;
     CARD32 blendcntl;
     int dstxoff, dstyoff, pixel_shift;
-    VIDEO_PREAMBLE();
-
     BoxPtr pBox = REGION_RECTS(&pPriv->clip);
     int nBox = REGION_NUM_RECTS(&pPriv->clip);
+    VIDEO_PREAMBLE();
 
     pixel_shift = pPixmap->drawable.bitsPerPixel >> 4;
 
@@ -107,15 +106,6 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
     dstyoff = 0;
 #endif
 
-#if 0
-    ErrorF("dst_offset: 0x%x\n", dst_offset);
-    ErrorF("dst_pitch: 0x%x\n", dst_pitch);
-    ErrorF("dstxoff: 0x%x\n", dstxoff);
-    ErrorF("dstyoff: 0x%x\n", dstyoff);
-    ErrorF("src_offset: 0x%x\n", pPriv->src_offset);
-    ErrorF("src_pitch: 0x%x\n", pPriv->src_pitch);
-#endif
-
     if (!info->XInited3D)
 	RADEONInit3DEngine(pScrn);
 
@@ -127,8 +117,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 		RADEON_WAIT_HOST_IDLECLEAN | RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
     FINISH_VIDEO();
 
-    if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
-	int has_tcl = (info->ChipFamily != CHIP_FAMILY_RS690 && info->ChipFamily != CHIP_FAMILY_RS400);
+    if (IS_R300_3D || IS_R500_3D) {
 
 	switch (pPixmap->drawable.bitsPerPixel) {
 	case 16:
@@ -157,8 +146,8 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 
 	txformat1 |= R300_TX_FORMAT_YUV_TO_RGB_CLAMP;
 
-	txformat0 = (((pPriv->w - 1) << R300_TXWIDTH_SHIFT) |
-		     ((pPriv->h - 1) << R300_TXHEIGHT_SHIFT));
+	txformat0 = ((((pPriv->w - 1) & 0x7ff) << R300_TXWIDTH_SHIFT) |
+		     (((pPriv->h - 1) & 0x7ff) << R300_TXHEIGHT_SHIFT));
 
 	txformat0 |= R300_TXPITCH_EN;
 
@@ -173,6 +162,12 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 	txpitch = pPriv->src_pitch / 2;
 	txpitch -= 1;
 
+	if (IS_R500_3D && ((pPriv->w - 1) & 0x800))
+	    txpitch |= R500_TXWIDTH_11;
+
+	if (IS_R500_3D && ((pPriv->h - 1) & 0x800))
+	    txpitch |= R500_TXHEIGHT_11;
+
 	txoffset = pPriv->src_offset;
 
 	BEGIN_VIDEO(6);
@@ -186,110 +181,40 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 
 	txenable = R300_TEX_0_ENABLE;
 
-	/* setup the VAP */
-	if (has_tcl) {
-	    BEGIN_VIDEO(26);
-	    OUT_VIDEO_REG(R300_VAP_CNTL_STATUS, 0);
-	    OUT_VIDEO_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
-	    OUT_VIDEO_REG(R300_VAP_CNTL, ((6 << R300_PVS_NUM_SLOTS_SHIFT) |
-					  (5 << R300_PVS_NUM_CNTLRS_SHIFT) |
-					  (4 << R300_PVS_NUM_FPUS_SHIFT) |
-					  (12 << R300_VF_MAX_VTX_NUM_SHIFT)));
-	} else {
-	    BEGIN_VIDEO(8);
-	    OUT_VIDEO_REG(R300_VAP_CNTL_STATUS, R300_PVS_BYPASS);
-	    OUT_VIDEO_REG(R300_VAP_CNTL, ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
-					  (5 << R300_PVS_NUM_CNTLRS_SHIFT) |
-					  (4 << R300_PVS_NUM_FPUS_SHIFT) |
-					  (5 << R300_VF_MAX_VTX_NUM_SHIFT)));
-	}
-
-	OUT_VIDEO_REG(R300_VAP_VTE_CNTL, R300_VTX_XY_FMT | R300_VTX_Z_FMT);
-	OUT_VIDEO_REG(R300_VAP_PSC_SGN_NORM_CNTL, 0);
-
-	if (has_tcl) {
-	    OUT_VIDEO_REG(R300_VAP_PROG_STREAM_CNTL_0,
-			  ((R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) |
-			   (0 << R300_SKIP_DWORDS_0_SHIFT) |
-			   (0 << R300_DST_VEC_LOC_0_SHIFT) |
-			   R300_SIGNED_0 |
-			   (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_1_SHIFT) |
-			   (0 << R300_SKIP_DWORDS_1_SHIFT) |
-			   (10 << R300_DST_VEC_LOC_1_SHIFT) |
-			   R300_LAST_VEC_1 |
-			   R300_SIGNED_1));
-	    OUT_VIDEO_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0,
-			  ((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_0_SHIFT) |
-			   (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_0_SHIFT) |
-			   (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_0_SHIFT) |
-			   (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_0_SHIFT) |
-			   ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
-			    << R300_WRITE_ENA_0_SHIFT) |
-			   (R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_1_SHIFT) |
-			   (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_1_SHIFT) |
-			   (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_1_SHIFT) |
-			   (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_1_SHIFT) |
-			   ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
-			    << R300_WRITE_ENA_1_SHIFT)));
-	} else {
-	    OUT_VIDEO_REG(R300_VAP_PROG_STREAM_CNTL_0,
-			  ((R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) |
-			   (0 << R300_SKIP_DWORDS_0_SHIFT) |
-			   (0 << R300_DST_VEC_LOC_0_SHIFT) |
-			   R300_SIGNED_0 |
-			   (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_1_SHIFT) |
-			   (0 << R300_SKIP_DWORDS_1_SHIFT) |
-			   (6 << R300_DST_VEC_LOC_1_SHIFT) |
-			   R300_LAST_VEC_1 |
-			   R300_SIGNED_1));
-	    OUT_VIDEO_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0,
-			  ((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_0_SHIFT) |
-			   (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_0_SHIFT) |
-			   (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_0_SHIFT) |
-			   (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_0_SHIFT) |
-			   ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y)
-			    << R300_WRITE_ENA_0_SHIFT) |
-			   (R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_1_SHIFT) |
-			   (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_1_SHIFT) |
-			   (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_1_SHIFT) |
-			   (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_1_SHIFT) |
-			   ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y)
-			    << R300_WRITE_ENA_1_SHIFT)));
-	}
-
-	/* setup vertex shader */
-	if (has_tcl) {
-	    OUT_VIDEO_REG(R300_VAP_PVS_CODE_CNTL_0,
-			  ((0 << R300_PVS_FIRST_INST_SHIFT) |
-			   (1 << R300_PVS_XYZW_VALID_INST_SHIFT) |
-			   (1 << R300_PVS_LAST_INST_SHIFT)));
-	    OUT_VIDEO_REG(R300_VAP_PVS_CODE_CNTL_1,
-			  (1 << R300_PVS_LAST_VTX_SRC_INST_SHIFT));
-	    OUT_VIDEO_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0);
-	    OUT_VIDEO_REG(R300_VAP_PVS_VECTOR_DATA_REG,0x00f00203);
-	    OUT_VIDEO_REG(R300_VAP_PVS_VECTOR_DATA_REG,0x00d10001);
-	    OUT_VIDEO_REG(R300_VAP_PVS_VECTOR_DATA_REG,0x01248001);
-	    OUT_VIDEO_REG(R300_VAP_PVS_VECTOR_DATA_REG,0x01248001);
-	    OUT_VIDEO_REG(R300_VAP_PVS_VECTOR_DATA_REG,0x00f02203);
-	    OUT_VIDEO_REG(R300_VAP_PVS_VECTOR_DATA_REG,0x00d10141);
-	    OUT_VIDEO_REG(R300_VAP_PVS_VECTOR_DATA_REG,0x01248141);
-	    OUT_VIDEO_REG(R300_VAP_PVS_VECTOR_DATA_REG,0x01248141);
-	    OUT_VIDEO_REG(R300_VAP_PVS_FLOW_CNTL_OPC, 0);
-
-
-	    OUT_VIDEO_REG(R300_VAP_GB_VERT_CLIP_ADJ, 0x3f800000);
-	    OUT_VIDEO_REG(R300_VAP_GB_VERT_DISC_ADJ, 0x3f800000);
-	    OUT_VIDEO_REG(R300_VAP_GB_HORZ_CLIP_ADJ, 0x3f800000);
-	    OUT_VIDEO_REG(R300_VAP_GB_HORZ_DISC_ADJ, 0x3f800000);
-	    OUT_VIDEO_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
-	}
+	BEGIN_VIDEO(6);
+	OUT_VIDEO_REG(R300_VAP_PROG_STREAM_CNTL_0,
+		      ((R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) |
+		       (0 << R300_SKIP_DWORDS_0_SHIFT) |
+		       (0 << R300_DST_VEC_LOC_0_SHIFT) |
+		       R300_SIGNED_0 |
+		       (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_1_SHIFT) |
+		       (0 << R300_SKIP_DWORDS_1_SHIFT) |
+		       (6 << R300_DST_VEC_LOC_1_SHIFT) |
+		       R300_LAST_VEC_1 |
+		       R300_SIGNED_1));
+	OUT_VIDEO_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0,
+		      ((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_0_SHIFT) |
+		       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_0_SHIFT) |
+		       (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_0_SHIFT) |
+		       (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_0_SHIFT) |
+		       ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y)
+			<< R300_WRITE_ENA_0_SHIFT) |
+		       (R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_1_SHIFT) |
+		       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_1_SHIFT) |
+		       (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_1_SHIFT) |
+		       (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_1_SHIFT) |
+		       ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y)
+			<< R300_WRITE_ENA_1_SHIFT)));
 
 	OUT_VIDEO_REG(R300_VAP_OUT_VTX_FMT_0, R300_VTX_POS_PRESENT);
 	OUT_VIDEO_REG(R300_VAP_OUT_VTX_FMT_1, (2 << R300_TEX_0_COMP_CNT_SHIFT));
+
+	OUT_VIDEO_REG(R300_TX_INVALTAGS, 0);
+	OUT_VIDEO_REG(R300_TX_ENABLE, txenable);
 	FINISH_VIDEO();
 
 	/* setup pixel shader */
-	if (IS_R300_VARIANT || info->ChipFamily == CHIP_FAMILY_RS690) {
+	if (IS_R300_3D) {
 	    BEGIN_VIDEO(16);
 	    OUT_VIDEO_REG(R300_RS_COUNT,
 			  ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |
@@ -302,7 +227,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 			   R300_RS_SEL_T(R300_RS_SEL_C1) |
 			   R300_RS_SEL_R(R300_RS_SEL_K0) |
 			   R300_RS_SEL_Q(R300_RS_SEL_K1)));
-	    OUT_VIDEO_REG(R300_RS_INST_COUNT, R300_TX_OFFSET_RS(6));
+	    OUT_VIDEO_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6));
 	    OUT_VIDEO_REG(R300_RS_INST_0, R300_RS_INST_TEX_CN_WRITE);
 	    OUT_VIDEO_REG(R300_US_CONFIG, (0 << R300_NLEVEL_SHIFT) | R300_FIRST_TEX);
 	    OUT_VIDEO_REG(R300_US_PIXSIZE, 0);
@@ -311,61 +236,186 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 			   R300_ALU_CODE_SIZE(1) |
 			   R300_TEX_CODE_OFFSET(0) |
 			   R300_TEX_CODE_SIZE(1)));
-	    OUT_VIDEO_REG(R300_US_CODE_ADDR_0, 0);
-	    OUT_VIDEO_REG(R300_US_CODE_ADDR_1, 0);
-	    OUT_VIDEO_REG(R300_US_CODE_ADDR_2, 0);
-	    OUT_VIDEO_REG(R300_US_CODE_ADDR_3, 0x400000);
-	    OUT_VIDEO_REG(R300_US_TEX_INST_0, 0x8000);
-	    OUT_VIDEO_REG(R300_US_ALU_RGB_ADDR_0, 0x1f800000);
-	    OUT_VIDEO_REG(R300_US_ALU_RGB_INST_0, 0x50a80);
-	    OUT_VIDEO_REG(R300_US_ALU_ALPHA_ADDR_0, 0x1800000);
-	    OUT_VIDEO_REG(R300_US_ALU_ALPHA_INST_0, 0x00040889);
+	    OUT_VIDEO_REG(R300_US_CODE_ADDR_0,
+			  (R300_ALU_START(0) |
+			   R300_ALU_SIZE(0) |
+			   R300_TEX_START(0) |
+			   R300_TEX_SIZE(0)));
+	    OUT_VIDEO_REG(R300_US_CODE_ADDR_1,
+			  (R300_ALU_START(0) |
+			   R300_ALU_SIZE(0) |
+			   R300_TEX_START(0) |
+			   R300_TEX_SIZE(0)));
+	    OUT_VIDEO_REG(R300_US_CODE_ADDR_2,
+			  (R300_ALU_START(0) |
+			   R300_ALU_SIZE(0) |
+			   R300_TEX_START(0) |
+			   R300_TEX_SIZE(0)));
+	    OUT_VIDEO_REG(R300_US_CODE_ADDR_3,
+			  (R300_ALU_START(0) |
+			   R300_ALU_SIZE(0) |
+			   R300_TEX_START(0) |
+			   R300_TEX_SIZE(0) |
+			   R300_RGBA_OUT));
+	    OUT_VIDEO_REG(R300_US_TEX_INST_0,
+			  (R300_TEX_SRC_ADDR(0) |
+			   R300_TEX_DST_ADDR(0) |
+			   R300_TEX_ID(0) |
+			   R300_TEX_INST(R300_TEX_INST_LD)));
+	    OUT_VIDEO_REG(R300_US_ALU_RGB_ADDR_0,
+			  (R300_ALU_RGB_ADDR0(0) |
+			   R300_ALU_RGB_ADDR1(0) |
+			   R300_ALU_RGB_ADDR2(0) |
+			   R300_ALU_RGB_ADDRD(0) |
+			   R300_ALU_RGB_WMASK((R300_ALU_RGB_MASK_R |
+					       R300_ALU_RGB_MASK_G |
+					       R300_ALU_RGB_MASK_B)) |
+			   R300_ALU_RGB_OMASK((R300_ALU_RGB_MASK_R |
+					       R300_ALU_RGB_MASK_G |
+					       R300_ALU_RGB_MASK_B)) |
+			   R300_ALU_RGB_TARGET_A));
+	    OUT_VIDEO_REG(R300_US_ALU_RGB_INST_0,
+			  (R300_ALU_RGB_SEL_A(R300_ALU_RGB_SRC0_RGB) |
+			   R300_ALU_RGB_MOD_A(R300_ALU_RGB_MOD_NOP) |
+			   R300_ALU_RGB_SEL_B(R300_ALU_RGB_1_0) |
+			   R300_ALU_RGB_MOD_B(R300_ALU_RGB_MOD_NOP) |
+			   R300_ALU_RGB_SEL_C(R300_ALU_RGB_0_0) |
+			   R300_ALU_RGB_MOD_C(R300_ALU_RGB_MOD_NOP) |
+			   R300_ALU_RGB_OP(R300_ALU_RGB_OP_MAD) |
+			   R300_ALU_RGB_OMOD(R300_ALU_RGB_OMOD_NONE) |
+			   R300_ALU_RGB_CLAMP));
+	    OUT_VIDEO_REG(R300_US_ALU_ALPHA_ADDR_0,
+			  (R300_ALU_ALPHA_ADDR0(0) |
+			   R300_ALU_ALPHA_ADDR1(0) |
+			   R300_ALU_ALPHA_ADDR2(0) |
+			   R300_ALU_ALPHA_ADDRD(0) |
+			   R300_ALU_ALPHA_WMASK(R300_ALU_ALPHA_MASK_A) |
+			   R300_ALU_ALPHA_OMASK(R300_ALU_ALPHA_MASK_A) |
+			   R300_ALU_ALPHA_TARGET_A |
+			   R300_ALU_ALPHA_OMASK_W(R300_ALU_ALPHA_MASK_NONE)));
+	    OUT_VIDEO_REG(R300_US_ALU_ALPHA_INST_0,
+			  (R300_ALU_ALPHA_SEL_A(R300_ALU_ALPHA_SRC0_A) |
+			   R300_ALU_ALPHA_MOD_A(R300_ALU_ALPHA_MOD_NOP) |
+			   R300_ALU_ALPHA_SEL_B(R300_ALU_ALPHA_1_0) |
+			   R300_ALU_ALPHA_MOD_B(R300_ALU_ALPHA_MOD_NOP) |
+			   R300_ALU_ALPHA_SEL_C(R300_ALU_ALPHA_0_0) |
+			   R300_ALU_ALPHA_MOD_C(R300_ALU_ALPHA_MOD_NOP) |
+			   R300_ALU_ALPHA_OP(R300_ALU_ALPHA_OP_MAD) |
+			   R300_ALU_ALPHA_OMOD(R300_ALU_ALPHA_OMOD_NONE) |
+			   R300_ALU_ALPHA_CLAMP));
 	    FINISH_VIDEO();
 	} else {
-	    BEGIN_VIDEO(22);
+	    BEGIN_VIDEO(23);
 	    OUT_VIDEO_REG(R300_RS_COUNT,
 			  ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |
 			   R300_RS_COUNT_HIRES_EN));
-	    OUT_VIDEO_REG(R500_RS_IP_0, (0 << R500_RS_IP_TEX_PTR_S_SHIFT) | (1 << R500_RS_IP_TEX_PTR_T_SHIFT) |
-			  (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) | (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT));
+	    OUT_VIDEO_REG(R500_RS_IP_0, ((0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
+					 (1 << R500_RS_IP_TEX_PTR_T_SHIFT) |
+					 (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
+					 (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)));
+
+	    OUT_VIDEO_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6));
 
-	    OUT_VIDEO_REG(R300_RS_INST_COUNT, 0);
-	    OUT_VIDEO_REG(R500_RS_INST_0, R500_RS_INST_TEX_CN_WRITE);
+	    OUT_VIDEO_REG(R500_RS_INST_0, ((0 << R500_RS_INST_TEX_ID_SHIFT) |
+					   R500_RS_INST_TEX_CN_WRITE |
+					   (0 << R500_RS_INST_TEX_ADDR_SHIFT)));
 	    OUT_VIDEO_REG(R300_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
 	    OUT_VIDEO_REG(R300_US_PIXSIZE, 0);
 	    OUT_VIDEO_REG(R500_US_FC_CTRL, 0);
-	    OUT_VIDEO_REG(R500_US_CODE_ADDR, R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(1));
-	    OUT_VIDEO_REG(R500_US_CODE_RANGE, R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(1));
+	    OUT_VIDEO_REG(R500_US_CODE_ADDR, (R500_US_CODE_START_ADDR(0) |
+					      R500_US_CODE_END_ADDR(1)));
+	    OUT_VIDEO_REG(R500_US_CODE_RANGE, (R500_US_CODE_RANGE_ADDR(0) |
+					       R500_US_CODE_RANGE_SIZE(1)));
 	    OUT_VIDEO_REG(R500_US_CODE_OFFSET, 0);
 	    OUT_VIDEO_REG(R500_GA_US_VECTOR_INDEX, 0);
-	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, 0x00007807);
-	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, 0x06400000);
-	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, 0xe4000400);
-	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, 0x00000000);
+
+	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_INST_TYPE_TEX |
+						   R500_INST_TEX_SEM_WAIT |
+						   R500_INST_RGB_WMASK_R |
+						   R500_INST_RGB_WMASK_G |
+						   R500_INST_RGB_WMASK_B |
+						   R500_INST_ALPHA_WMASK |
+						   R500_INST_RGB_CLAMP |
+						   R500_INST_ALPHA_CLAMP));
+
+	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_TEX_ID(0) |
+						   R500_TEX_INST_LD |
+						   R500_TEX_SEM_ACQUIRE |
+						   R500_TEX_IGNORE_UNCOVERED));
+
+	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_TEX_SRC_ADDR(0) |
+						   R500_TEX_SRC_S_SWIZ_R |
+						   R500_TEX_SRC_T_SWIZ_G |
+						   R500_TEX_DST_ADDR(0) |
+						   R500_TEX_DST_R_SWIZ_R |
+						   R500_TEX_DST_G_SWIZ_G |
+						   R500_TEX_DST_B_SWIZ_B |
+						   R500_TEX_DST_A_SWIZ_A));
+	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_DX_ADDR(0) |
+						   R500_DX_S_SWIZ_R |
+						   R500_DX_T_SWIZ_R |
+						   R500_DX_R_SWIZ_R |
+						   R500_DX_Q_SWIZ_R |
+						   R500_DY_ADDR(0) |
+						   R500_DY_S_SWIZ_R |
+						   R500_DY_T_SWIZ_R |
+						   R500_DY_R_SWIZ_R |
+						   R500_DY_Q_SWIZ_R));
 	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, 0x00000000);
 	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, 0x00000000);
-	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, 0x00078105);
-	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, 0x10040000);
-	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, 0x10040000);
-	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, 0x00db0220);
-	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, 0x00c0c000);
-	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, 0x20490000);
+
+	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_INST_TYPE_OUT |
+						   R500_INST_TEX_SEM_WAIT |
+						   R500_INST_LAST |
+						   R500_INST_RGB_OMASK_R |
+						   R500_INST_RGB_OMASK_G |
+						   R500_INST_RGB_OMASK_B |
+						   R500_INST_ALPHA_OMASK |
+						   R500_INST_RGB_CLAMP |
+						   R500_INST_ALPHA_CLAMP));
+
+	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_RGB_ADDR0(0) |
+						   R500_RGB_ADDR1(0) |
+						   R500_RGB_ADDR1_CONST |
+						   R500_RGB_ADDR2(0) |
+						   R500_RGB_ADDR2_CONST |
+						   R500_RGB_SRCP_OP_1_MINUS_2RGB0));
+	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_ALPHA_ADDR0(0) |
+						   R500_ALPHA_ADDR1(0) |
+						   R500_ALPHA_ADDR1_CONST |
+						   R500_ALPHA_ADDR2(0) |
+						   R500_ALPHA_ADDR2_CONST |
+						   R500_ALPHA_SRCP_OP_1_MINUS_2A0));
+
+	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_ALU_RGB_SEL_A_SRC0 |
+						   R500_ALU_RGB_R_SWIZ_A_R |
+						   R500_ALU_RGB_G_SWIZ_A_G |
+						   R500_ALU_RGB_B_SWIZ_A_B |
+						   R500_ALU_RGB_SEL_B_SRC0 |
+						   R500_ALU_RGB_R_SWIZ_B_1 |
+						   R500_ALU_RGB_B_SWIZ_B_1 |
+						   R500_ALU_RGB_G_SWIZ_B_1));
+
+	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_ALPHA_OP_MAD |
+						   R500_ALPHA_SWIZ_A_A |
+						   R500_ALPHA_SWIZ_B_1));
+
+	    OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_ALU_RGBA_OP_MAD |
+						   R500_ALU_RGBA_R_SWIZ_0 |
+						   R500_ALU_RGBA_G_SWIZ_0 |
+						   R500_ALU_RGBA_B_SWIZ_0 |
+						   R500_ALU_RGBA_A_SWIZ_0));
 	    FINISH_VIDEO();
 	}
 
-	BEGIN_VIDEO(6);
-	OUT_VIDEO_REG(R300_TX_INVALTAGS, 0);
-	OUT_VIDEO_REG(R300_TX_ENABLE, txenable);
+	BEGIN_VIDEO(4);
 
 	OUT_VIDEO_REG(R300_RB3D_COLOROFFSET0, dst_offset);
 	OUT_VIDEO_REG(R300_RB3D_COLORPITCH0, colorpitch);
 
 	blendcntl = RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO;
-	OUT_VIDEO_REG(R300_RB3D_BLENDCNTL, blendcntl);
-	OUT_VIDEO_REG(R300_RB3D_ABLENDCNTL, 0);
-	FINISH_VIDEO();
+	OUT_VIDEO_REG(R300_RB3D_BLENDCNTL, blendcntl | R300_ALPHA_BLEND_ENABLE | R300_READ_ENABLE);
 
-	BEGIN_VIDEO(1);
 	OUT_VIDEO_REG(R300_VAP_VTX_SIZE, VTX_DWORD_COUNT);
 	FINISH_VIDEO();
 
@@ -538,7 +588,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 		     RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
 		     (4 << RADEON_CP_VC_CNTL_NUM_SHIFT));
 	} else {
-	    if (IS_R300_VARIANT || IS_AVIVO_VARIANT)
+	    if (IS_R300_3D || IS_R500_3D)
 		BEGIN_RING(4 * VTX_DWORD_COUNT + 6);
 	    else
 		BEGIN_RING(4 * VTX_DWORD_COUNT + 2);
@@ -549,7 +599,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 		     (4 << RADEON_CP_VC_CNTL_NUM_SHIFT));
 	}
 #else /* ACCEL_CP */
-	if (IS_R300_VARIANT || IS_AVIVO_VARIANT)
+	if (IS_R300_3D || IS_R500_3D)
 	    BEGIN_VIDEO(3 + VTX_DWORD_COUNT * 4);
 	else
 	    BEGIN_VIDEO(1 + VTX_DWORD_COUNT * 4);
@@ -575,7 +625,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 	VTX_OUT((float)(dstX + dstw),                                (float)dstY,
 		xFixedToFloat(srcTopRight.x) / info->texW[0],     xFixedToFloat(srcTopRight.y) / info->texH[0]);
 
-	if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
+	if (IS_R300_3D || IS_R500_3D) {
 	    OUT_VIDEO_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
 	    OUT_VIDEO_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
 	}
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 7502e1e..216cd65 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -285,14 +285,15 @@ void RADEONInitVideo(ScreenPtr pScreen)
 	RADEONInitOffscreenImages(pScreen);
     }
 
-    if (info->ChipFamily != CHIP_FAMILY_RS400) {
+    if (info->ChipFamily != CHIP_FAMILY_RV250) {
 	texturedAdaptor = RADEONSetupImageTexturedVideo(pScreen);
 	if (texturedAdaptor != NULL) {
 	    adaptors[num_adaptors++] = texturedAdaptor;
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up textured video\n");
 	} else
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up textured video\n");
-    }
+    } else
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Textured video disabled on RV250 due to HW bug\n");
 
     if(num_adaptors)
 	xf86XVScreenInit(pScreen, adaptors, num_adaptors);
@@ -2159,6 +2160,13 @@ RADEONCopyData(
   unsigned int bpp
 ){
     RADEONInfoPtr info = RADEONPTR(pScrn);
+
+    /* Get the byte-swapping right for big endian systems */
+    if ( bpp == 2 ) {
+	w *= 2;
+	bpp = 1;
+    }
+
 #ifdef XF86DRI
 
     if ( info->directRenderingEnabled && info->DMAForXv )
@@ -2168,13 +2176,6 @@ RADEONCopyData(
 	int x, y;
 	unsigned int hpass;
 
-	/* Get the byte-swapping right for big endian systems */
-	if ( bpp == 2 )
-	{
-	    w *= 2;
-	    bpp = 1;
-	}
-
 	RADEONHostDataParams( pScrn, dst, dstPitch, bpp, &dstPitchOff, &x, &y );
 
 	while ( (buf = RADEONHostDataBlit( pScrn, bpp, w, dstPitchOff, &bufPitch,
diff --git a/src/theatre.c b/src/theatre.c
index a5aadfb..a4d3c10 100644
--- a/src/theatre.c
+++ b/src/theatre.c
@@ -28,6 +28,8 @@ static Bool theatre_write(TheatrePtr t,CARD32 reg, CARD32 data)
 #define RT_regw(reg,data)	theatre_write(t,(reg),(data))
 #define VIP_TYPE      "ATI VIP BUS"
 
+static void CalculateCrCbGain (TheatrePtr t, double *CrGain, double *CbGain, CARD16 wStandard);
+static void RT_SetCombFilter (TheatrePtr t, CARD16 wStandard, CARD16 wConnector);
 
 #if 0
 TheatrePtr DetectTheatre(GENERIC_BUS_Ptr b)
@@ -793,7 +795,7 @@ static void RT_SetVINClock(TheatrePtr t, CARD16 wStandard)
  *    Inputs: int hue - the hue value to be set.                            *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetTint (TheatrePtr t, int hue)
+_X_EXPORT void RT_SetTint (TheatrePtr t, int hue)
 {
     CARD32 nhue = 0;
 
@@ -846,7 +848,7 @@ void RT_SetTint (TheatrePtr t, int hue)
  *    Inputs: int Saturation - the saturation value to be set.              *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetSaturation (TheatrePtr t, int Saturation)
+_X_EXPORT void RT_SetSaturation (TheatrePtr t, int Saturation)
 {
     CARD16   wSaturation_V, wSaturation_U;
     double dbSaturation = 0, dbCrGain = 0, dbCbGain = 0;
@@ -893,7 +895,7 @@ void RT_SetSaturation (TheatrePtr t, int Saturation)
  *    Inputs: int Brightness - the brightness value to be set.              *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetBrightness (TheatrePtr t, int Brightness)
+_X_EXPORT void RT_SetBrightness (TheatrePtr t, int Brightness)
 {
     double dbSynctipRef0=0, dbContrast=1;
 
@@ -967,7 +969,7 @@ void RT_SetBrightness (TheatrePtr t, int Brightness)
  *    Inputs: CARD16 wSharpness - the sharpness value to be set.              *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetSharpness (TheatrePtr t, CARD16 wSharpness)
+_X_EXPORT void RT_SetSharpness (TheatrePtr t, CARD16 wSharpness)
 {
     switch (wSharpness)
     {
@@ -993,7 +995,7 @@ void RT_SetSharpness (TheatrePtr t, CARD16 wSharpness)
  *    Inputs: int Contrast - the contrast value to be set.                  *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetContrast (TheatrePtr t, int Contrast)
+_X_EXPORT void RT_SetContrast (TheatrePtr t, int Contrast)
 {
     double dbSynctipRef0=0, dbContrast=0;
     double dbYgain=0;
@@ -1052,7 +1054,7 @@ void RT_SetContrast (TheatrePtr t, int Contrast)
  *    Inputs: CARD8 bInterlace                                               *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetInterlace (TheatrePtr t, CARD8 bInterlace)
+_X_EXPORT void RT_SetInterlace (TheatrePtr t, CARD8 bInterlace)
 {
 
     switch(bInterlace)
@@ -1142,7 +1144,7 @@ static void GetStandardConstants (double *LPeriod, double *FPeriod,
  *    Inputs: CARD16 wStandard - input standard (NTSC, PAL, SECAM)            *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetStandard (TheatrePtr t, CARD16 wStandard)
+_X_EXPORT void RT_SetStandard (TheatrePtr t, CARD16 wStandard)
 {
     double dbFsamp=0, dbLPeriod=0, dbFPeriod=0;
     CARD16   wFrameTotal = 0;
@@ -1427,7 +1429,7 @@ void RT_SetStandard (TheatrePtr t, CARD16 wStandard)
  *            CARD16 wConnector - COMPOSITE, SVIDEO                           *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetCombFilter (TheatrePtr t, CARD16 wStandard, CARD16 wConnector)
+static void RT_SetCombFilter (TheatrePtr t, CARD16 wStandard, CARD16 wConnector)
 {
     CARD32 dwComb_Cntl0=0;
     CARD32 dwComb_Cntl1=0;
@@ -1567,7 +1569,7 @@ void RT_SetCombFilter (TheatrePtr t, CARD16 wStandard, CARD16 wConnector)
  *            CARD8 fVBI_Cap_On - enable VBI capture                         *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetOutputVideoSize (TheatrePtr t, CARD16 wHorzSize, CARD16 wVertSize, CARD8 fCC_On, CARD8 fVBICap_On)
+_X_EXPORT void RT_SetOutputVideoSize (TheatrePtr t, CARD16 wHorzSize, CARD16 wVertSize, CARD8 fCC_On, CARD8 fVBICap_On)
 {
     CARD32  dwHwinStart=0;
     CARD32  dwHScaleRatio=0;
@@ -1723,7 +1725,7 @@ void RT_SetOutputVideoSize (TheatrePtr t, CARD16 wHorzSize, CARD16 wVertSize, CA
  *            CARD16 wStandard - input standard (NTSC, PAL, SECAM)            *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void CalculateCrCbGain (TheatrePtr t, double *CrGain, double *CbGain, CARD16 wStandard)
+static void CalculateCrCbGain (TheatrePtr t, double *CrGain, double *CbGain, CARD16 wStandard)
 {
     #define UVFLTGAIN   1.5
     #define FRMAX       280000.0
@@ -1864,7 +1866,7 @@ void RT_SetConnector (TheatrePtr t, CARD16 wConnector, int tunerFlag)
 } /* RT_SetConnector ()...*/
 
 
-void InitTheatre(TheatrePtr t)
+_X_EXPORT void InitTheatre(TheatrePtr t)
 {
     CARD32 data;
 
@@ -1929,7 +1931,7 @@ void InitTheatre(TheatrePtr t)
 }
 
 
-void ShutdownTheatre(TheatrePtr t)
+_X_EXPORT void ShutdownTheatre(TheatrePtr t)
 {
     WriteRT_fld (fld_VIN_ASYNC_RST, RT_ASYNC_DISABLE);
     WriteRT_fld (fld_VINRST       , RT_VINRST_RESET);
@@ -1938,7 +1940,7 @@ void ShutdownTheatre(TheatrePtr t)
     t->mode=MODE_UNINITIALIZED;
 }
 
-void DumpRageTheatreRegs(TheatrePtr t)
+_X_EXPORT void DumpRageTheatreRegs(TheatrePtr t)
 {
     int i;
     CARD32 data;
@@ -2159,7 +2161,7 @@ void DumpRageTheatreRegsByName(TheatrePtr t)
 
 }
 
-void ResetTheatreRegsForNoTVout(TheatrePtr t)
+_X_EXPORT void ResetTheatreRegsForNoTVout(TheatrePtr t)
 {
      RT_regw(VIP_CLKOUT_CNTL, 0x0); 
      RT_regw(VIP_HCOUNT, 0x0); 
@@ -2173,7 +2175,7 @@ void ResetTheatreRegsForNoTVout(TheatrePtr t)
 }
 
 
-void ResetTheatreRegsForTVout(TheatrePtr t)
+_X_EXPORT void ResetTheatreRegsForTVout(TheatrePtr t)
 {
 /*    RT_regw(VIP_HW_DEBUG, 0x200);   */
 /*     RT_regw(VIP_INT_CNTL, 0x0); 
diff --git a/src/theatre.h b/src/theatre.h
index 958b443..36d6e05 100644
--- a/src/theatre.h
+++ b/src/theatre.h
@@ -35,45 +35,37 @@ typedef struct {
 	 
 	 } TheatreRec, * TheatrePtr;
 
-/* DO NOT FORGET to setup constants before calling InitTheatre */
-void InitTheatre(TheatrePtr t);
-
-void RT_SetTint (TheatrePtr t, int hue);
-void RT_SetSaturation (TheatrePtr t, int Saturation);
-void RT_SetBrightness (TheatrePtr t, int Brightness);
-void RT_SetSharpness (TheatrePtr t, CARD16 wSharpness);
-void RT_SetContrast (TheatrePtr t, int Contrast);
-void RT_SetInterlace (TheatrePtr t, CARD8 bInterlace);
-void RT_SetStandard (TheatrePtr t, CARD16 wStandard);
-void RT_SetCombFilter (TheatrePtr t, CARD16 wStandard, CARD16 wConnector);
-void RT_SetOutputVideoSize (TheatrePtr t, CARD16 wHorzSize, CARD16 wVertSize, CARD8 fCC_On, CARD8 fVBICap_On);
-void CalculateCrCbGain (TheatrePtr t, double *CrGain, double *CbGain, CARD16 wStandard);
-void RT_SetConnector (TheatrePtr t, CARD16 wConnector, int tunerFlag);
-
-void RageTheatreDebugGain(TheatrePtr t, Bool on, CARD32 gain);
-void ShutdownTheatre(TheatrePtr t);
-void DumpRageTheatreRegs(TheatrePtr t);
-void ResetTheatreRegsForTVout(TheatrePtr t);
-void ResetTheatreRegsForNoTVout(TheatrePtr t);
-
 
-#define xf86_InitTheatre           ((void (*)(TheatrePtr t))LoaderSymbol("InitTheatre"))
-
-#define xf86_RT_SetTint            ((void (*)(TheatrePtr, int))LoaderSymbol("RT_SetTint"))
-#define xf86_RT_SetSaturation      ((void (*)(TheatrePtr, int))LoaderSymbol("RT_SetSaturation"))
-#define xf86_RT_SetBrightness      ((void (*)(TheatrePtr, int))LoaderSymbol("RT_SetBrightness"))
-#define xf86_RT_SetSharpness       ((void (*)(TheatrePtr, CARD16))LoaderSymbol("RT_SetSharpness"))
-#define xf86_RT_SetContrast        ((void (*)(TheatrePtr, int))LoaderSymbol("RT_SetContrast"))
-#define xf86_RT_SetInterlace       ((void (*)(TheatrePtr, CARD8))LoaderSymbol("RT_SetInterlace"))
-#define xf86_RT_SetStandard        ((void (*)(TheatrePtr, CARD16))LoaderSymbol("RT_SetStandard"))
-#define xf86_RT_SetOutputVideoSize ((void (*)(TheatrePtr, CARD16, CARD16, CARD8, CARD8))LoaderSymbol("RT_SetOutputVideoSize"))
-#define xf86_RT_SetConnector       ((void (*)(TheatrePtr, CARD16, int))LoaderSymbol("RT_SetConnector"))
-
-#define xf86_RageTheatreDebugGain       ((void (*)(TheatrePtr, Bool, CARD32))LoaderSymbol("RageTheatreDebugGain"))
-#define xf86_ShutdownTheatre       ((void (*)(TheatrePtr))LoaderSymbol("ShutdownTheatre"))
-#define xf86_DumpRageTheatreRegs       ((void (*)(TheatrePtr))LoaderSymbol("DumpRageTheatreRegs"))
-#define xf86_ResetTheatreRegsForTVout       ((void (*)(TheatrePtr))LoaderSymbol("ResetTheatreRegsForTVout"))
-#define xf86_ResetTheatreRegsForNoTVout       ((void (*)(TheatrePtr))LoaderSymbol("ResetTheatreRegsForNoTVout"))
-#define xf86_RT_GetSignalStatus       ((void (*)(TheatrePtr))LoaderSymbol("xf86_RT_GetSignalStatus"))
+/* DO NOT FORGET to setup constants before calling InitTheatre */
+#define xf86_InitTheatre		InitTheatre
+_X_EXPORT void InitTheatre(TheatrePtr t);
+#define xf86_RT_SetTint			RT_SetTint
+_X_EXPORT void RT_SetTint (TheatrePtr t, int hue);
+#define xf86_RT_SetSaturation		RT_SetSaturation
+_X_EXPORT void RT_SetSaturation (TheatrePtr t, int Saturation);
+#define xf86_RT_SetBrightness		RT_SetBrightness
+_X_EXPORT void RT_SetBrightness (TheatrePtr t, int Brightness);
+#define xf86_RT_SetSharpness		RT_SetSharpness
+_X_EXPORT void RT_SetSharpness (TheatrePtr t, CARD16 wSharpness);
+#define xf86_RT_SetContrast		RT_SetContrast
+_X_EXPORT void RT_SetContrast (TheatrePtr t, int Contrast);
+#define xf86_RT_SetInterlace		RT_SetInterlace
+_X_EXPORT void RT_SetInterlace (TheatrePtr t, CARD8 bInterlace);
+#define xf86_RT_SetStandard		RT_SetStandard
+_X_EXPORT void RT_SetStandard (TheatrePtr t, CARD16 wStandard);
+#define xf86_RT_SetOutputVideoSize	RT_SetOutputVideoSize
+_X_EXPORT void RT_SetOutputVideoSize (TheatrePtr t, CARD16 wHorzSize, CARD16 wVertSize, CARD8 fCC_On, CARD8 fVBICap_On);
+#define xf86_RT_SetConnector		RT_SetConnector
+_X_EXPORT void RT_SetConnector (TheatrePtr t, CARD16 wConnector, int tunerFlag);
+#define xf86_ResetTheatreRegsForNoTVout	ResetTheatreRegsForNoTVout
+_X_EXPORT void ResetTheatreRegsForNoTVout(TheatrePtr t);
+#define xf86_ResetTheatreRegsForTVout	ResetTheatreRegsForTVout
+_X_EXPORT void ResetTheatreRegsForTVout(TheatrePtr t);
+#define xf86_DumpRageTheatreRegs	DumpRageTheatreRegs
+_X_EXPORT void DumpRageTheatreRegs(TheatrePtr t);
+#define xf86_DumpRageTheatreRegsByName	DumpRageTheatreRegsByName
+_X_EXPORT void DumpRageTheatreRegsByName(TheatrePtr t);
+#define xf86_ShutdownTheatre		ShutdownTheatre
+_X_EXPORT void ShutdownTheatre(TheatrePtr t);
 
 #endif
diff --git a/src/theatre200.c b/src/theatre200.c
index 672f01e..0341c6e 100644
--- a/src/theatre200.c
+++ b/src/theatre200.c
@@ -1492,7 +1492,7 @@ static CARD32 ReadRT_fld1 (TheatrePtr t,CARD32 dwReg)
  *    Inputs: int hue - the hue value to be set.                            *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetTint (TheatrePtr t, int hue)
+_X_EXPORT void RT_SetTint (TheatrePtr t, int hue)
 {
     /* Validate Hue level */
     if (hue < -1000)
@@ -1517,7 +1517,7 @@ void RT_SetTint (TheatrePtr t, int hue)
  *    Inputs: int Saturation - the saturation value to be set.              *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetSaturation (TheatrePtr t, int Saturation)
+_X_EXPORT void RT_SetSaturation (TheatrePtr t, int Saturation)
 {
     /* VALIDATE SATURATION LEVEL */
     if (Saturation < -1000L)
@@ -1543,7 +1543,7 @@ void RT_SetSaturation (TheatrePtr t, int Saturation)
  *    Inputs: int Brightness - the brightness value to be set.              *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetBrightness (TheatrePtr t, int Brightness)
+_X_EXPORT void RT_SetBrightness (TheatrePtr t, int Brightness)
 {
     /* VALIDATE BRIGHTNESS LEVEL */
     if (Brightness < -1000)
@@ -1572,7 +1572,7 @@ void RT_SetBrightness (TheatrePtr t, int Brightness)
  *    Inputs: CARD16 wSharpness - the sharpness value to be set.              *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetSharpness (TheatrePtr t, CARD16 wSharpness)
+_X_EXPORT void RT_SetSharpness (TheatrePtr t, CARD16 wSharpness)
 {
 	switch (wSharpness)
 	{
@@ -1598,7 +1598,7 @@ void RT_SetSharpness (TheatrePtr t, CARD16 wSharpness)
  *    Inputs: int Contrast - the contrast value to be set.                  *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetContrast (TheatrePtr t, int Contrast)
+_X_EXPORT void RT_SetContrast (TheatrePtr t, int Contrast)
 {
 	/* VALIDATE CONTRAST LEVEL */
 	if (Contrast < -1000)
@@ -1626,7 +1626,7 @@ void RT_SetContrast (TheatrePtr t, int Contrast)
  *    Inputs: CARD8 bInterlace                                               *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetInterlace (TheatrePtr t, CARD8 bInterlace)
+_X_EXPORT void RT_SetInterlace (TheatrePtr t, CARD8 bInterlace)
 {
 	switch(bInterlace)
 	{
@@ -1653,7 +1653,7 @@ void RT_SetInterlace (TheatrePtr t, CARD8 bInterlace)
  *    Inputs: CARD16 wStandard - input standard (NTSC, PAL, SECAM)            *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetStandard (TheatrePtr t, CARD16 wStandard)
+_X_EXPORT void RT_SetStandard (TheatrePtr t, CARD16 wStandard)
 {
 	xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"Rage Theatre setting standard 0x%04x\n",
 		wStandard);
@@ -1772,7 +1772,7 @@ void RT_SetStandard (TheatrePtr t, CARD16 wStandard)
  *            CARD8 fVBI_Cap_On - enable VBI capture                         *
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetOutputVideoSize (TheatrePtr t, CARD16 wHorzSize, CARD16 wVertSize, CARD8 fCC_On, CARD8 fVBICap_On)
+_X_EXPORT void RT_SetOutputVideoSize (TheatrePtr t, CARD16 wHorzSize, CARD16 wVertSize, CARD8 fCC_On, CARD8 fVBICap_On)
 {
 	/* VBI is ignored now */
 
@@ -1792,7 +1792,7 @@ void RT_SetOutputVideoSize (TheatrePtr t, CARD16 wHorzSize, CARD16 wVertSize, CA
  *            int tunerFlag
  *   Outputs: NONE                                                          *
  ****************************************************************************/
-void RT_SetConnector (TheatrePtr t, CARD16 wConnector, int tunerFlag)
+_X_EXPORT void RT_SetConnector (TheatrePtr t, CARD16 wConnector, int tunerFlag)
 {
 	CARD32 data;
 
@@ -1871,7 +1871,7 @@ void RT_SetConnector (TheatrePtr t, CARD16 wConnector, int tunerFlag)
 } /* RT_SetConnector ()...*/
 
 
-void InitTheatre(TheatrePtr t)
+_X_EXPORT void InitTheatre(TheatrePtr t)
 {
 	CARD32 data;
 	CARD32 M, N, P;
@@ -1992,7 +1992,7 @@ err_exit:
 }
 
 
-void ShutdownTheatre(TheatrePtr t)
+_X_EXPORT void ShutdownTheatre(TheatrePtr t)
 {
 #if 0
     WriteRT_fld (fld_VIN_ASYNC_RST, RT_ASYNC_DISABLE);
@@ -2003,7 +2003,7 @@ void ShutdownTheatre(TheatrePtr t)
     t->mode=MODE_UNINITIALIZED;
 }
 
-void DumpRageTheatreRegs(TheatrePtr t)
+_X_EXPORT void DumpRageTheatreRegs(TheatrePtr t)
 {
     int i;
     CARD32 data;
@@ -2224,7 +2224,7 @@ void DumpRageTheatreRegsByName(TheatrePtr t)
 
 }
 
-void ResetTheatreRegsForNoTVout(TheatrePtr t)
+_X_EXPORT void ResetTheatreRegsForNoTVout(TheatrePtr t)
 {
      RT_regw(VIP_CLKOUT_CNTL, 0x0); 
      RT_regw(VIP_HCOUNT, 0x0); 
@@ -2238,7 +2238,7 @@ void ResetTheatreRegsForNoTVout(TheatrePtr t)
 }
 
 
-void ResetTheatreRegsForTVout(TheatrePtr t)
+_X_EXPORT void ResetTheatreRegsForTVout(TheatrePtr t)
 {
 /*    RT_regw(VIP_HW_DEBUG, 0x200);   */
 /*     RT_regw(VIP_INT_CNTL, 0x0); 
diff --git a/src/theatre_detect.c b/src/theatre_detect.c
index 8770911..79dcfe4 100644
--- a/src/theatre_detect.c
+++ b/src/theatre_detect.c
@@ -43,6 +43,7 @@
 #include "generic_bus.h"
 #include "theatre.h"
 #include "theatre_reg.h"
+#include "theatre_detect.h"
 
 static Bool theatre_read(TheatrePtr t,CARD32 reg, CARD32 *data)
 {
@@ -64,7 +65,7 @@ static Bool theatre_write(TheatrePtr t,CARD32 reg, CARD32 data)
 #define VIP_TYPE      "ATI VIP BUS"
 
 
-TheatrePtr DetectTheatre(GENERIC_BUS_Ptr b)
+_X_EXPORT TheatrePtr DetectTheatre(GENERIC_BUS_Ptr b)
 {
    TheatrePtr t;  
    int i;
diff --git a/src/theatre_detect.h b/src/theatre_detect.h
index 5fed160..53d8d11 100644
--- a/src/theatre_detect.h
+++ b/src/theatre_detect.h
@@ -38,9 +38,9 @@
  */
 
 
-TheatrePtr DetectTheatre(GENERIC_BUS_Ptr b);
+#define xf86_DetectTheatre	DetectTheatre
+_X_EXPORT TheatrePtr DetectTheatre(GENERIC_BUS_Ptr b);
 
 
-#define xf86_DetectTheatre         ((TheatrePtr (*)(GENERIC_BUS_Ptr))LoaderSymbol("DetectTheatre"))
 
 #endif