Blob Blame History Raw
commit c3532268875fd24e6519bea2fb1b814d612bbdb4
Author: Dave Airlie <airlied@linux.ie>
Date:   Wed May 7 02:37:18 2008 +1000

    radeon: fix zaphod EXA with texture video

commit ffc437f3606ab8ceba1ff152e4bb08988a58b54c
Author: Dave Airlie <airlied@linux.ie>
Date:   Wed May 7 02:30:28 2008 +1000

    avivo: fix zaphod cursor in theory

commit e36ef14e3a1087e1fe41baa26ade2937f396001f
Author: Dave Airlie <airlied@linux.ie>
Date:   Wed May 7 01:39:28 2008 +1000

    radeon: fix textured-xv on zaphod

commit 8fc19bee27c0f151d2ab3354f6ac0992b358436d
Author: Dave Airlie <airlied@linux.ie>
Date:   Wed May 7 01:38:24 2008 +1000

    radeon: zaphod: fix render accel for EXA

commit fc41b9042a5220a8419cc7b69ca3850cae6b903c
Author: Dave Airlie <airlied@linux.ie>
Date:   Wed May 7 01:32:23 2008 +1000

    radeon: fix EXA pixmap offset on zaphod

commit 4568cb820d567c6909a4be956d7e79b91232535e
Author: Dave Airlie <airlied@linux.ie>
Date:   Wed May 7 01:19:39 2008 +1000

    radeon: zaphod fixes for pciaccess not allowing multiple MMIO maps

commit ca81fa086b21633a7fd926833fb6d1d4fa080646
Author: Dave Airlie <airlied@linux.ie>
Date:   Wed May 7 01:12:01 2008 +1000

    radeon: zaphod fix for cursor on second head
    
    We don't need to add fbOffset here as the mmap we have of the framebuffer
    starts half way.

commit 24b60c8965f6a0b3f0c2bb1e7236b4d6642c5918
Author: Julien Cristau <jcristau@debian.org>
Date:   Fri May 2 15:30:45 2008 -0400

    Add a test for __GLIBC__ to CD_Common_Types.h.
    
    Atombios redefines the standard types but the definitions conflict
    with the ones from glibc (causes build failures on GNU/Hurd
    and GNU/kFreeBSD).

commit f051359ac09c6b9416e39b9ca7d9dc0880aa1557
Author: thegraze <thegraze@googlemail.com>
Date:   Fri May 2 14:02:16 2008 -0400

    ATOM: add support for DragonFlyBSD

commit 3d469cbc3225d890a895dac7cbc1ab7e08054b48
Author: Alex Deucher <alex@cube.(none)>
Date:   Wed Apr 30 18:33:04 2008 -0400

    RADEON: lock the cursors when updating
    
    this should fix occasional corruption seen when updating
    the cursor.

commit 445b71021843665ba32f37b2ce5c9d2857c07cc7
Author: Alex Deucher <alex@cube.(none)>
Date:   Tue Apr 29 21:01:41 2008 -0400

    RADEON: assorted fixes
    
    - free rotate pixmaps on VT switch
    - save crtc/output status so we only turn on
    crtcs/outputs if they are off
    - show/hide cursors when changing modes

commit 070cce5255a5c311f9d8b85ec54bd56655014933
Author: Stephan Wolf <stephan@letzte-bankreihe.de>
Date:   Mon Apr 28 11:26:37 2008 -0400

    R3xx+: further fix for IGP chips
    
    see bug 15538

commit 211e0041c7fc2df494b77428553943a2b526ee4e
Author: Alex Deucher <alex@cube.(none)>
Date:   Sun Apr 27 21:08:00 2008 -0400

    IGP: fix EXA composite corruption

commit 656b06bdde129ca4fc370f5a2cf7311c9179b0ff
Author: Alex Deucher <alex@botch2.com>
Date:   Sun Apr 27 20:20:49 2008 -0400

    RADEON: remove duplicate register define
    
    Also add more bit defs to wait_until register

commit 8a9820a3aa49bc667f90ac291a27e4d7b4ae38b3
Author: Alex Deucher <alex@botch2.com>
Date:   Sun Apr 27 19:02:22 2008 -0400

    RADEON: decrease crtc/output verbosity

commit c5d62fa0e8f52c3264ff9db3ff10cdf5a806bfc0
Author: Owen Taylor <otaylor@huygens.home.fishsoup.net>
Date:   Thu Apr 17 13:14:53 2008 +0200

    Emulate repeats by drawing in tiles
    
    When we can't turn on hardware repeats, because the texture
    is non-power-of-two, or has padding at the ends of lines,
    try to draw the image in multiple tiles rather than falling
    back to software. (We can only do this when there is no
    transform.)

commit eeb7b74bb6c813b0e3afa4b704f6ffb0d0aab92b
Author: Owen Taylor <otaylor@huygens.home.fishsoup.net>
Date:   Thu Apr 17 13:14:25 2008 +0200

    Turn on wrapping when repeating on R100 + R200
    
    Actually enable repeats for R100 and R200. This corresponds
    to a R300 change made in the patch in:
    http://bugs.freedesktop.org/show_bug.cgi?id=15333

commit e511f39dfef503006cf249b9f6934091eaade9b5
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Thu Apr 17 05:04:34 2008 -0400

    R300+: move more common code into init3d()
    
    - pre-load r3xx tex instructions
    - setup RS instructions in init3d()

commit 99435b7c18d931ea620044d0fdb4cc93dfcc6331
Author: Owen Taylor <otaylor@redhat.com>
Date:   Thu Apr 17 02:46:11 2008 -0400

    Radeon: Omit mask coordinates
    
    Adapted from Owen's patch on bug 15546
    This fixes the slowness with aatext on r300
    and may speed up other chips marginally.

commit 37614e1db9a595fbe8a21d7a045895e11d272db9
Author: Alex Deucher <alex@botch2.com>
Date:   Tue Apr 15 09:48:16 2008 -0400

    fix up some things from the last commit

commit 1286fe5ce1c77453d57817b9b26b1bdb32ca7bc8
Author: Alex Deucher <alex@botch2.(none)>
Date:   Mon Apr 14 20:02:14 2008 -0400

    R300+: properly setup vap_cntl
    
    this fixes tcl/pvs on RV515 among other things

commit f72a4b805db26f10f69330b88459cbeae661189b
Author: Alex Deucher <alex@botch2.com>
Date:   Mon Apr 14 14:10:40 2008 -0400

    EXA: Don't wait for 3D idle after each Composite()
    
    wait in CompositeDone() instead

commit 4cd4acf1092aeb696b086a382a033aee471d2de9
Author: Alex Deucher <alex@botch2.com>
Date:   Mon Apr 14 11:50:59 2008 -0400

    R300: move more common code to init3d()

commit 3c523c9a07402e17dff588fad842224c57e98223
Author: Alex Deucher <alex@botch2.com>
Date:   Mon Apr 14 11:21:42 2008 -0400

    R3xx+: 3D engine documentation and minor cleanups
    
    - document the R300 exa/textured video code
    - minor cleanups of textured video code to clarify meaning

commit ce025bbb2496d4de94b8d4ac450c64441b64ee04
Author: Alex Deucher <alex@botch2.com>
Date:   Sat Apr 12 21:22:03 2008 -0400

    R300+: consolidate some tcl/non-tcl paths
    
    - Move more code to init3d()
    - MMIO textured video seems more reliable now on newer chips

commit 11b54a319c7c9dd52e3fb13372697059dafe1cd3
Author: Alex Deucher <alex@botch2.com>
Date:   Sat Apr 12 16:50:22 2008 -0400

    R3xx+: fix XAA + textured video on non-TCL path

commit dd15a2f5906725116b8cd9954243099055e88e37
Author: Alex Deucher <alex@botch2.com>
Date:   Sat Apr 12 16:49:03 2008 -0400

    R3xx+: more fixes to 2D/3D engine init

commit f3e68d4b7afd2e23675bf6361c496814c9cb4b94
Author: Alex Deucher <alex@botch2.com>
Date:   Fri Apr 11 10:59:07 2008 -0400

    Fix exa glyph corruption on newer chips

commit b59686d6427cbf8b35e36b020cbbc6a0c5149b22
Author: Alex Deucher <alex@botch2.com>
Date:   Fri Apr 11 10:15:25 2008 -0400

    R300+: pre-load vertex programs in init3D()

commit acc5833a35ad6c29a57f659607afb27eebdc2ea5
Author: Alex Deucher <alex@botch2.com>
Date:   Thu Apr 10 17:52:52 2008 -0400

    R3xx+: consolidate more tcl code

commit 6f8f75bd19ef1919c0291141675be2d0e29b3251
Author: Alex Deucher <alex@botch2.com>
Date:   Thu Apr 10 17:08:50 2008 -0400

    R3xx+: consolidate some common 3D code

commit 4b9234e1c4f7c7f419cb4245d64f3f9756c98bb6
Author: Alex Deucher <alex@botch2.com>
Date:   Thu Apr 10 16:58:22 2008 -0400

    R3xx+: tcl wip

commit 865c463e3afb4759758f569132be8bf1386da5cc
Author: Alex Deucher <alex@botch2.com>
Date:   Thu Apr 10 16:51:04 2008 -0400

    R300+: textured video tcl cleanup

commit 79c8d4ca36a1c3e5fe759d4ccc379c36af8f1676
Author: Alex Deucher <alex@botch2.com>
Date:   Thu Apr 10 16:28:18 2008 -0400

    RADEON: cleanup

commit c4821a287d29a65f3bcb7d60dc72ec13c0384008
Author: Alex Deucher <alex@botch2.com>
Date:   Thu Apr 10 16:20:17 2008 -0400

    Revert "R3xx/R5xx: move more VAP, etc. state setup into common init3d() function"
    
    This reverts commit 305a3310963a5dd07b3495015b06aa8c7c4e6b02.
    
    Conflicts:
    
    	src/radeon_commonfuncs.c
    	src/radeon_exa_render.c
    	src/radeon_textured_videofuncs.c

commit 0032c80bf30bab189204e3e6929e18a19d753138
Author: Alex Deucher <alex@botch2.com>
Date:   Thu Apr 10 14:35:00 2008 -0400

    RADEON: store tcl status in driver rec

commit 9e2ffe66d106abe34a670d2edc9905ed62c485e8
Author: Alex Deucher <alex@botch2.com>
Date:   Thu Apr 10 14:24:04 2008 -0400

    R3xx+: use the right register for engine flush

commit e1a9f26c2d2cbca9ad159e723ec95b95be1ef349
Author: Alex Deucher <alex@botch2.com>
Date:   Thu Apr 10 14:12:15 2008 -0400

    R3xx+: minor textured video fixes
    
    - set shader output swizzling correctly
    - flush the right cache register on r3xx+

commit d79040906cd25bd494feb5901f465bbd050aa923
Author: Alex Deucher <alex@botch2.com>
Date:   Thu Apr 10 13:59:58 2008 -0400

    R3xx+: EXA/textured video fixes
    
    - get pipe config based on GB_PIPE_SELECT where applicable
    (adapted from a similar patch from Dave)
    - only flush the dst cache after submitting vertices, freeing
    the cache lines stalls the pipe
    - no need to wait for 3D idle after submitting vertices
    - fix PURGE_CACHE() and PURGE_ZCACHE() for r3xx+
    - fix depth 16 with EXA composite

commit 0a96173cc38e506728d4c3f2dd383ba56e856578
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Mon Apr 7 18:15:34 2008 +0200

    Increase default CP timeout.
    
    Helps avoid spurious timeouts causing problems, see
    http://bugs.freedesktop.org/show_bug.cgi?id=15203 .

commit 255fbf465f5e7db2609a5a151bfa810249db52a0
Author: Owen W. Taylor <otaylor@fishsoup.net>
Date:   Thu Apr 3 02:25:41 2008 -0400

    Fix rendering of transformed sources for REPEAT_NONE with EXA on >= R300.
    
    Use the border color when possible, otherwise fall back to software.

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..ab8bd97 100644
--- a/configure.ac
+++ b/configure.ac
@@ -176,6 +176,14 @@ AC_CHECK_DECL(xf86_crtc_clip_video_helper,
 	       #include "xf86i2c.h"
 	       #include "xf86Crtc.h"])
 
+AC_CHECK_DECL(xf86RotateFreeShadow,
+	      [AC_DEFINE(HAVE_FREE_SHADOW, 1, [have new FreeShadow API])],
+	      [],
+	      [#include <xorg-server.h>
+               #include <windowstr.h>
+	       #include <xf86Crtc.h>])
+
+
 AC_CHECK_DECL(XSERVER_LIBPCIACCESS,
 	      [XSERVER_LIBPCIACCESS=yes],[XSERVER_LIBPCIACCESS=no],
 	      [#include "xorg-server.h"])
@@ -232,6 +240,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..c60b652 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 
     
@@ -47,7 +51,9 @@ Revision History:
 	//    typedef __int64             int64_t;
 		typedef unsigned __int32    uint32_t;
 		typedef __int32             int32_t;
-#elif defined (__linux__) || defined (__NetBSD__) || defined(__sun) || defined(__OpenBSD__) || defined (__FreeBSD__)
+#elif defined (__linux__) || defined (__NetBSD__) \
+    || defined(__sun) || defined(__OpenBSD__) \
+    || defined (__FreeBSD__) || defined(__DragonFly__) || defined(__GLIBC__)
 		typedef unsigned int uint32_t;
 		typedef int int32_t;
 	#else
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..bab56b2 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,25 +215,86 @@ 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);
+    /*ErrorF("table is %d %d\n", major, minor);*/
     switch(major) {
     case 1:
 	switch(minor) {
 	case 1:
-	case 2: {
-	    spc_param.sPCLKInput.usPixelClock = sclock;
-	    spc_param.sPCLKInput.usRefDiv = ref_div;
-	    spc_param.sPCLKInput.usFbDiv = fb_div;
-	    spc_param.sPCLKInput.ucPostDiv = post_div;
-	    spc_param.sPCLKInput.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
-	    spc_param.sPCLKInput.ucCRTC = radeon_crtc->crtc_id;
-	    spc_param.sPCLKInput.ucRefDivSrc = 1;
+	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..d8e88ca 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,40 +697,94 @@ 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("output dpms %d\n", mode);*/
 
-    ErrorF("AGD: output dpms %d\n", mode);
-
-   if (radeon_output->MonType == MT_LCD) {
-       if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
-	   atombios_device_dpms(output, ATOM_DEVICE_LCD1_SUPPORT, mode);
-   } else if (radeon_output->MonType == MT_DFP) {
-       ErrorF("AGD: tmds dpms\n");
-       if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
-	   atombios_device_dpms(output, ATOM_DEVICE_DFP1_SUPPORT, mode);
-       else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
-	   atombios_device_dpms(output, ATOM_DEVICE_DFP2_SUPPORT, mode);
-       else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
-	   atombios_device_dpms(output, ATOM_DEVICE_DFP3_SUPPORT, mode);
-   } else if (radeon_output->MonType == MT_CRT) {
-       ErrorF("AGD: dac dpms\n");
-       if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
-	   atombios_device_dpms(output, ATOM_DEVICE_CRT1_SUPPORT, mode);
-       else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
-	   atombios_device_dpms(output, ATOM_DEVICE_CRT2_SUPPORT, mode);
-   } else if (radeon_output->MonType == MT_CV) {
-       ErrorF("AGD: cv dpms\n");
-       if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
-	   atombios_device_dpms(output, ATOM_DEVICE_CV_SUPPORT, mode);
-   } else if (0 /*radeon_output->MonType == MT_STV ||
-		  radeon_output->MonType == MT_CTV*/) {
-       ErrorF("AGD: tv dpms\n");
-       if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
-	   atombios_device_dpms(output, ATOM_DEVICE_TV1_SUPPORT, mode);
-   }
+    if (radeon_output->MonType == MT_LCD) {
+	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("tmds dpms\n");*/
+	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)
+	    atombios_device_dpms(output, ATOM_DEVICE_CRT1_SUPPORT, mode);
+	else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
+	    atombios_device_dpms(output, ATOM_DEVICE_CRT2_SUPPORT, mode);
+    } else if (radeon_output->MonType == MT_CV) {
+	/*ErrorF("AGD: cv dpms\n");*/
+	if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
+	    atombios_device_dpms(output, ATOM_DEVICE_CV_SUPPORT, mode);
+    } else if (0 /*radeon_output->MonType == MT_STV ||
+		   radeon_output->MonType == MT_CTV*/) {
+	/*ErrorF("AGD: tv dpms\n");*/
+	if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
+	    atombios_device_dpms(output, ATOM_DEVICE_TV1_SUPPORT, mode);
+    }
 
 }
 
@@ -498,15 +797,13 @@ 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;
 
     atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
 
-    ErrorF("select crtc source table is %d %d\n", major, minor);
-
-    crtc_src_param.ucCRTC = radeon_crtc->crtc_id;
-    crtc_src_param.ucDevice = 0;
+    /*ErrorF("select crtc source table is %d %d\n", major, minor);*/
 
     switch(major) {
     case 1: {
@@ -514,6 +811,8 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
 	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;
@@ -679,7 +1049,7 @@ atombios_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output)
 	    bios_0_scratch = INREG(R600_BIOS_0_SCRATCH);
 	else
 	    bios_0_scratch = INREG(RADEON_BIOS_0_SCRATCH);
-	ErrorF("DAC connect %08X\n", (unsigned int)bios_0_scratch);
+	/*ErrorF("DAC connect %08X\n", (unsigned int)bios_0_scratch);*/
 
 	if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) {
 	    if (bios_0_scratch & ATOM_S0_CRT1_MASK)
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..a65a41e 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;
@@ -685,7 +701,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
     }
 
     if (bEnable) {
-	ErrorF("enable montype: %d\n", radeon_output->MonType);
+	/*ErrorF("enable montype: %d\n", radeon_output->MonType);*/
 	if (radeon_output->MonType == MT_CRT) {
 	    if (radeon_output->DACType == DAC_PRIMARY) {
 		info->output_crt1 |= (1 << o);
@@ -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);
@@ -744,7 +775,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    radeon_output->tv_on = TRUE;
 	}
     } else {
-	ErrorF("disable montype: %d\n", radeon_output->MonType);
+	/*ErrorF("disable montype: %d\n", radeon_output->MonType);*/
 	if (radeon_output->MonType == MT_CRT) {
 	    if (radeon_output->DACType == DAC_PRIMARY) {
 		info->output_crt1 &= ~(1 << o);
@@ -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..feff48f 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
  */
@@ -736,6 +760,9 @@ typedef struct {
 
     Bool              r600_shadow_fb;
     void *fb_shadow;
+
+    int num_gb_pipes;
+    Bool has_tcl;
 } RADEONInfoRec, *RADEONInfoPtr;
 
 #define RADEONWaitForFifo(pScrn, entries)				\
@@ -745,152 +772,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 +984,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 +1052,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)
@@ -1130,15 +1191,27 @@ do {									\
 #define RADEON_PURGE_CACHE()						\
 do {									\
     BEGIN_RING(2);							\
-    OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0));		\
-    OUT_RING(RADEON_RB3D_DC_FLUSH_ALL);					\
+    if (info->ChipFamily <= CHIP_FAMILY_RV280) {                        \
+        OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0));		\
+        OUT_RING(RADEON_RB3D_DC_FLUSH_ALL);				\
+    } else {                                                            \
+        OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));		\
+        OUT_RING(R300_RB3D_DC_FLUSH_ALL);				\
+    }                                                                   \
     ADVANCE_RING();							\
 } while (0)
 
 #define RADEON_PURGE_ZCACHE()						\
 do {									\
-    OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0));		\
-    OUT_RING(RADEON_RB3D_ZC_FLUSH_ALL);					\
+    BEGIN_RING(2);							\
+    if (info->ChipFamily <= CHIP_FAMILY_RV280) {                        \
+        OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0));		\
+        OUT_RING(RADEON_RB3D_ZC_FLUSH_ALL);				\
+    } else {                                                            \
+        OUT_RING(CP_PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0));		\
+        OUT_RING(R300_ZC_FLUSH_ALL);					\
+    }                                                                   \
+    ADVANCE_RING();							\
 } while (0)
 
 #endif /* XF86DRI */
diff --git a/src/radeon_accel.c b/src/radeon_accel.c
index 8b2f167..9e7ea7a 100644
--- a/src/radeon_accel.c
+++ b/src/radeon_accel.c
@@ -158,17 +158,32 @@ void RADEONEngineFlush(ScrnInfoPtr pScrn)
     unsigned char *RADEONMMIO = info->MMIO;
     int            i;
 
-    OUTREGP(RADEON_RB3D_DSTCACHE_CTLSTAT,
-	    RADEON_RB3D_DC_FLUSH_ALL,
-	    ~RADEON_RB3D_DC_FLUSH_ALL);
-    for (i = 0; i < RADEON_TIMEOUT; i++) {
-	if (!(INREG(RADEON_RB3D_DSTCACHE_CTLSTAT) & RADEON_RB3D_DC_BUSY))
-	    break;
-    }
-    if (i == RADEON_TIMEOUT) {
-	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		       "DC flush timeout: %x\n",
-		       (unsigned int)INREG(RADEON_RB3D_DSTCACHE_CTLSTAT));
+    if (info->ChipFamily <= CHIP_FAMILY_RV280) {
+	OUTREGP(RADEON_RB3D_DSTCACHE_CTLSTAT,
+		RADEON_RB3D_DC_FLUSH_ALL,
+		~RADEON_RB3D_DC_FLUSH_ALL);
+	for (i = 0; i < RADEON_TIMEOUT; i++) {
+	    if (!(INREG(RADEON_RB3D_DSTCACHE_CTLSTAT) & RADEON_RB3D_DC_BUSY))
+		break;
+	}
+	if (i == RADEON_TIMEOUT) {
+	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+			   "DC flush timeout: %x\n",
+			   (unsigned int)INREG(RADEON_RB3D_DSTCACHE_CTLSTAT));
+	}
+    } else {
+	OUTREGP(R300_RB2D_DSTCACHE_CTLSTAT,
+		R300_RB2D_DC_FLUSH_ALL,
+		~R300_RB2D_DC_FLUSH_ALL);
+	for (i = 0; i < RADEON_TIMEOUT; i++) {
+	    if (!(INREG(R300_RB2D_DSTCACHE_CTLSTAT) & R300_RB2D_DC_BUSY))
+		break;
+	}
+	if (i == RADEON_TIMEOUT) {
+	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+			   "DC flush timeout: %x\n",
+			   (unsigned int)INREG(R300_RB2D_DSTCACHE_CTLSTAT));
+	}
     }
 }
 
@@ -355,7 +370,52 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
 		   info->CurrentLayout.pixel_code,
 		   info->CurrentLayout.bitsPerPixel);
 
-    OUTREG(RADEON_RB3D_CNTL, 0);
+    if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
+	(info->ChipFamily == CHIP_FAMILY_R420)  ||
+	(info->ChipFamily == CHIP_FAMILY_RS690) ||
+	(info->ChipFamily == CHIP_FAMILY_RS740) ||
+	(info->ChipFamily == CHIP_FAMILY_RS400) ||
+	IS_R500_3D) {
+	uint32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT);
+	if (info->num_gb_pipes == 0) {
+	    info->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		       "%s: num pipes is %d\n", __FUNCTION__, info->num_gb_pipes);
+	}
+	if (IS_R500_3D)
+	    OUTPLL(pScrn, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
+    } else {
+	if (info->num_gb_pipes == 0) {
+	    if ((info->ChipFamily == CHIP_FAMILY_R300) ||
+		(info->ChipFamily == CHIP_FAMILY_R350)) {
+		/* R3xx chips */
+		info->num_gb_pipes = 2;
+	    } else {
+		/* RV3xx chips */
+		info->num_gb_pipes = 1;
+	    }
+	}
+    }
+
+    if (IS_R300_3D | IS_R500_3D) {
+	CARD32 gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 | R300_SUBPIXEL_1_16);
+
+	switch(info->num_gb_pipes) {
+	case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
+	case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
+	case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
+	default:
+	case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
+	}
+
+	OUTREG(R300_GB_TILE_CONFIG, gb_tile_config);
+	OUTREG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
+	OUTREG(R300_DST_PIPE_CONFIG, INREG(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG);
+	OUTREG(R300_RB2D_DSTCACHE_MODE, (INREG(R300_RB2D_DSTCACHE_MODE) |
+					 R300_DC_AUTOFLUSH_ENABLE |
+					 R300_DC_DC_DISABLE_IGNORE_PE));
+    } else
+	OUTREG(RADEON_RB3D_CNTL, 0);
 
     RADEONEngineReset(pScrn);
 
@@ -390,8 +450,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..b17b53c 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,
@@ -2673,7 +2071,7 @@ CailDelayMicroSeconds(VOID *CAIL, UINT32 delay)
 
     usleep(delay);
 
-    DEBUGP(xf86DrvMsg(((atomBiosHandlePtr)CAIL)->scrnIndex,X_INFO,"Delay %i usec\n",delay));
+    /*DEBUGP(xf86DrvMsg(((atomBiosHandlePtr)CAIL)->scrnIndex,X_INFO,"Delay %i usec\n",delay));*/
 }
 
 UINT32
@@ -2686,7 +2084,7 @@ CailReadATIRegister(VOID* CAIL, UINT32 idx)
     CAILFUNC(CAIL);
 
     ret  =  INREG(idx << 2);
-    DEBUGP(ErrorF("%s(%x) = %x\n",__func__,idx << 2,ret));
+    /*DEBUGP(ErrorF("%s(%x) = %x\n",__func__,idx << 2,ret));*/
     return ret;
 }
 
@@ -2699,7 +2097,7 @@ CailWriteATIRegister(VOID *CAIL, UINT32 idx, UINT32 data)
     CAILFUNC(CAIL);
 
     OUTREG(idx << 2,data);
-    DEBUGP(ErrorF("%s(%x,%x)\n",__func__,idx << 2,data));
+    /*DEBUGP(ErrorF("%s(%x,%x)\n",__func__,idx << 2,data));*/
 }
 
 UINT32
@@ -2714,10 +2112,10 @@ CailReadFBData(VOID* CAIL, UINT32 idx)
     if (((atomBiosHandlePtr)CAIL)->fbBase) {
 	CARD8 *FBBase = (CARD8*)info->FB;
 	ret =  *((CARD32*)(FBBase + (((atomBiosHandlePtr)CAIL)->fbBase) + idx));
-	DEBUGP(ErrorF("%s(%x) = %x\n",__func__,idx,ret));
+	/*DEBUGP(ErrorF("%s(%x) = %x\n",__func__,idx,ret));*/
     } else if (((atomBiosHandlePtr)CAIL)->scratchBase) {
 	ret = *(CARD32*)((CARD8*)(((atomBiosHandlePtr)CAIL)->scratchBase) + idx);
-	DEBUGP(ErrorF("%s(%x) = %x\n",__func__,idx,ret));
+	/*DEBUGP(ErrorF("%s(%x) = %x\n",__func__,idx,ret));*/
     } else {
 	xf86DrvMsg(((atomBiosHandlePtr)CAIL)->scrnIndex,X_ERROR,
 		   "%s: no fbbase set\n",__func__);
@@ -2731,7 +2129,7 @@ CailWriteFBData(VOID *CAIL, UINT32 idx, UINT32 data)
 {
     CAILFUNC(CAIL);
 
-    DEBUGP(ErrorF("%s(%x,%x)\n",__func__,idx,data));
+    /*DEBUGP(ErrorF("%s(%x,%x)\n",__func__,idx,data));*/
     if (((atomBiosHandlePtr)CAIL)->fbBase) {
 	CARD8 *FBBase = (CARD8*)
 	    RADEONPTR(xf86Screens[((atomBiosHandlePtr)CAIL)->scrnIndex])->FB;
@@ -2752,7 +2150,7 @@ CailReadMC(VOID *CAIL, ULONG Address)
     CAILFUNC(CAIL);
 
     ret = INMC(pScrn, Address);
-    DEBUGP(ErrorF("%s(%x) = %x\n",__func__,Address,ret));
+    /*DEBUGP(ErrorF("%s(%x) = %x\n",__func__,Address,ret));*/
     return ret;
 }
 
@@ -2762,7 +2160,7 @@ CailWriteMC(VOID *CAIL, ULONG Address, ULONG data)
     ScrnInfoPtr pScrn = xf86Screens[((atomBiosHandlePtr)CAIL)->scrnIndex];
 
     CAILFUNC(CAIL);
-    DEBUGP(ErrorF("%s(%x,%x)\n",__func__,Address,data));
+    /*DEBUGP(ErrorF("%s(%x,%x)\n",__func__,Address,data));*/
     OUTMC(pScrn, Address, data);
 }
 
@@ -2808,7 +2206,7 @@ CailReadPCIConfigData(VOID*CAIL, VOID* ret, UINT32 idx,UINT16 size)
 	return;
 	    break;
     }
-    DEBUGP(ErrorF("%s(%x) = %x\n",__func__,idx,*(unsigned int*)ret));
+    /*DEBUGP(ErrorF("%s(%x) = %x\n",__func__,idx,*(unsigned int*)ret));*/
 
 }
 
@@ -2818,7 +2216,7 @@ CailWritePCIConfigData(VOID*CAIL,VOID*src,UINT32 idx,UINT16 size)
     PCITAG tag = ((atomBiosHandlePtr)CAIL)->PciTag;
 
     CAILFUNC(CAIL);
-    DEBUGP(ErrorF("%s(%x,%x)\n",__func__,idx,(*(unsigned int*)src)));
+    /*DEBUGP(ErrorF("%s(%x,%x)\n",__func__,idx,(*(unsigned int*)src)));*/
     switch (size) {
 	case 8:
 	    pciWriteByte(tag,idx << 2,*(CARD8*)src);
@@ -2846,7 +2244,7 @@ CailReadPLL(VOID *CAIL, ULONG Address)
     CAILFUNC(CAIL);
 
     ret = RADEONINPLL(pScrn, Address);
-    DEBUGP(ErrorF("%s(%x) = %x\n",__func__,Address,ret));
+    /*DEBUGP(ErrorF("%s(%x) = %x\n",__func__,Address,ret));*/
     return ret;
 }
 
@@ -2856,7 +2254,7 @@ CailWritePLL(VOID *CAIL, ULONG Address,ULONG Data)
     ScrnInfoPtr pScrn = xf86Screens[((atomBiosHandlePtr)CAIL)->scrnIndex];
     CAILFUNC(CAIL);
 
-    DEBUGP(ErrorF("%s(%x,%x)\n",__func__,Address,Data));
+    /*DEBUGP(ErrorF("%s(%x,%x)\n",__func__,Address,Data));*/
     RADEONOUTPLL(pScrn, Address, Data);
 }
 
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..9a450f9 100644
--- a/src/radeon_commonfuncs.c
+++ b/src/radeon_commonfuncs.c
@@ -55,53 +55,49 @@
 static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    CARD32 gb_tile_config;
+    CARD32 gb_tile_config, su_reg_dest, vap_cntl;
     ACCEL_PREAMBLE();
 
     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);
 	OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
-	OUT_ACCEL_REG(R300_WAIT_UNTIL, R300_WAIT_2D_IDLECLEAN | R300_WAIT_3D_IDLECLEAN);
+	OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
 	FINISH_ACCEL();
 
 	gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 | R300_SUBPIXEL_1_16);
 
-	if ((info->Chipset == PCI_CHIP_RV410_5E4C) ||
-	    (info->Chipset == PCI_CHIP_RV410_5E4F)) {
-	    /* RV410 SE chips */
-	    gb_tile_config |= R300_PIPE_COUNT_RV350;
-	} else if ((info->ChipFamily == CHIP_FAMILY_RV350) ||
-		   (info->ChipFamily == CHIP_FAMILY_RV380) ||
-		   (info->ChipFamily == CHIP_FAMILY_RS400)) {
-	    /* RV3xx, RS4xx chips */
-	    gb_tile_config |= R300_PIPE_COUNT_RV350;
-	} else if ((info->ChipFamily == CHIP_FAMILY_R300) ||
-		   (info->ChipFamily == CHIP_FAMILY_R350)) {
-	    /* R3xx chips */
-	    gb_tile_config |= R300_PIPE_COUNT_R300;
-	} else if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
-		   (info->ChipFamily == CHIP_FAMILY_RS690)) {
-	    /* RV4xx, RS6xx chips */
-	    gb_tile_config |= R300_PIPE_COUNT_R420_3P;
-	} else {
-	    /* R4xx, R5xx chips */
-	    gb_tile_config |= R300_PIPE_COUNT_R420;
+	switch(info->num_gb_pipes) {
+	case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
+	case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
+	case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
+	default:
+	case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
 	}
 
-	BEGIN_ACCEL(3);
+	BEGIN_ACCEL(5);
 	OUT_ACCEL_REG(R300_GB_TILE_CONFIG, gb_tile_config);
+	OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
+	OUT_ACCEL_REG(R300_DST_PIPE_CONFIG, R300_PIPE_AUTO_CONFIG);
 	OUT_ACCEL_REG(R300_GB_SELECT, 0);
 	OUT_ACCEL_REG(R300_GB_ENABLE, 0);
 	FINISH_ACCEL();
 
+	if (IS_R500_3D) {
+	    su_reg_dest = ((1 << info->num_gb_pipes) - 1);
+	    BEGIN_ACCEL(2);
+	    OUT_ACCEL_REG(R500_SU_REG_DEST, su_reg_dest);
+	    OUT_ACCEL_REG(R500_VAP_INDEX_OFFSET, 0);
+	    FINISH_ACCEL();
+	}
+
 	BEGIN_ACCEL(3);
 	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
 	OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
-	OUT_ACCEL_REG(R300_WAIT_UNTIL, R300_WAIT_2D_IDLECLEAN | R300_WAIT_3D_IDLECLEAN);
+	OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
 	FINISH_ACCEL();
 
 	BEGIN_ACCEL(5);
@@ -125,7 +121,8 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 				       (8 << R300_MSBD1_SHIFT)));
 	FINISH_ACCEL();
 
-	BEGIN_ACCEL(4);
+	BEGIN_ACCEL(5);
+	OUT_ACCEL_REG(R300_GA_ENHANCE, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL);
 	OUT_ACCEL_REG(R300_GA_POLY_MODE, R300_FRONT_PTYPE_TRIANGE | R300_BACK_PTYPE_TRIANGE);
 	OUT_ACCEL_REG(R300_GA_ROUND_MODE, (R300_GEOMETRY_ROUND_NEAREST |
 					   R300_COLOR_ROUND_NEAREST));
@@ -148,7 +145,399 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 	OUT_ACCEL_REG(R300_SU_DEPTH_OFFSET, 0);
 	FINISH_ACCEL();
 
-	BEGIN_ACCEL(5);
+	/* setup the VAP */
+	if (info->has_tcl)
+	    vap_cntl = ((5 << R300_PVS_NUM_SLOTS_SHIFT) |
+			(5 << R300_PVS_NUM_CNTLRS_SHIFT) |
+			(9 << R300_VF_MAX_VTX_NUM_SHIFT));
+	else
+	    vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
+			(5 << R300_PVS_NUM_CNTLRS_SHIFT) |
+			(5 << R300_VF_MAX_VTX_NUM_SHIFT));
+
+	if (info->ChipFamily == CHIP_FAMILY_RV515)
+	    vap_cntl |= (2 << R300_PVS_NUM_FPUS_SHIFT);
+	else if ((info->ChipFamily == CHIP_FAMILY_RV530) ||
+		 (info->ChipFamily == CHIP_FAMILY_RV560))
+	    vap_cntl |= (5 << R300_PVS_NUM_FPUS_SHIFT);
+	else if (info->ChipFamily == CHIP_FAMILY_R420)
+	    vap_cntl |= (6 << R300_PVS_NUM_FPUS_SHIFT);
+	else if ((info->ChipFamily == CHIP_FAMILY_R520) ||
+		 (info->ChipFamily == CHIP_FAMILY_R580) ||
+		 (info->ChipFamily == CHIP_FAMILY_RV570))
+	    vap_cntl |= (8 << R300_PVS_NUM_FPUS_SHIFT);
+	else
+	    vap_cntl |= (4 << R300_PVS_NUM_FPUS_SHIFT);
+
+	if (info->has_tcl)
+	    BEGIN_ACCEL(15);
+	else
+	    BEGIN_ACCEL(9);
+	OUT_ACCEL_REG(R300_VAP_VTX_STATE_CNTL, 0);
+	OUT_ACCEL_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
+
+	if (info->has_tcl)
+	    OUT_ACCEL_REG(R300_VAP_CNTL_STATUS, 0);
+	else
+	    OUT_ACCEL_REG(R300_VAP_CNTL_STATUS, R300_PVS_BYPASS);
+	OUT_ACCEL_REG(R300_VAP_CNTL, vap_cntl);
+	OUT_ACCEL_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
+	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);
+
+	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)));
+
+	if (info->has_tcl) {
+	    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);
+	}
+	FINISH_ACCEL();
+
+	/* pre-load the vertex shaders */
+	if (info->has_tcl) {
+	    /* exa mask shader program */
+	    BEGIN_ACCEL(13);
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0);
+	    /* PVS inst 0 */
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
+			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
+			   R300_PVS_DST_OFFSET(0) |
+			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
+			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(0) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(0) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(0) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
+
+	    /* PVS inst 1 */
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
+			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
+			   R300_PVS_DST_OFFSET(1) |
+			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
+			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(6) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(6) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(6) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
+
+	    /* PVS inst 2 */
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
+			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
+			   R300_PVS_DST_OFFSET(2) |
+			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
+			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(7) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(7) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(7) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
+	    FINISH_ACCEL();
+
+	    BEGIN_ACCEL(9);
+	    /* exa no mask instruction */
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_INDX_REG, 3);
+	    /* PVS inst 0 */
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
+			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
+			   R300_PVS_DST_OFFSET(0) |
+			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
+			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(0) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(0) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(0) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
+
+	    /* PVS inst 1 */
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
+			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
+			   R300_PVS_DST_OFFSET(1) |
+			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
+			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(6) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(6) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(6) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
+	    FINISH_ACCEL();
+
+	    /* Xv shader program */
+	    BEGIN_ACCEL(9);
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_INDX_REG, 5);
+
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
+			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
+			   R300_PVS_DST_OFFSET(0) |
+			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
+			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(0) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(0) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(0) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
+
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
+			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
+			   R300_PVS_DST_OFFSET(1) |
+			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
+			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(6) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(6) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
+	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
+			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+			   R300_PVS_SRC_OFFSET(6) |
+			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
+			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
+	    FINISH_ACCEL();
+	}
+
+	/* pre-load the RS instructions */
+	BEGIN_ACCEL(4);
+	if (IS_R300_3D) {
+	    /* rasterizer source table
+	     * R300_RS_TEX_PTR is the offset into the input RS stream
+	     * 0,1 are tex0
+	     * 2,3 are tex1
+	     */
+	    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)));
+	    /* src tex */
+	    /* R300_INST_TEX_ID - select the RS source table entry
+	     * R300_INST_TEX_ADDR - the FS temp register for the texture data
+	     */
+	    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)));
+
+	} else {
+	    /* rasterizer source table
+	     * R300_RS_TEX_PTR is the offset into the input RS stream
+	     * 0,1 are tex0
+	     * 2,3 are tex1
+	     */
+	    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)));
+	    /* src tex */
+	    /* R500_RS_INST_TEX_ID_SHIFT - select the RS source table entry
+	     * R500_RS_INST_TEX_ADDR_SHIFT - the FS temp register for the texture data
+	     */
+	    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)));
+	}
+	FINISH_ACCEL();
+
+	/* pre-load FS tex instructions */
+	if (IS_R300_3D) {
+	    BEGIN_ACCEL(2);
+	    /* tex inst for src texture */
+	    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)));
+
+	    /* tex inst for mask texture */
+	    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)));
+	    FINISH_ACCEL();
+	}
+
+	if (IS_R300_3D) {
+	    BEGIN_ACCEL(9);
+	    OUT_ACCEL_REG(R300_US_CONFIG, (0 << R300_NLEVEL_SHIFT) | R300_FIRST_TEX);
+	    OUT_ACCEL_REG(R300_US_PIXSIZE, 1); /* highest temp used */
+	    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)));
+	} else {
+	    BEGIN_ACCEL(7);
+	    OUT_ACCEL_REG(R300_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
+	    OUT_ACCEL_REG(R300_US_PIXSIZE, 1); /* highest temp used */
+	    OUT_ACCEL_REG(R500_US_FC_CTRL, 0);
+	}
 	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 +554,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 +563,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 +590,13 @@ 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_VARIANT || (info->ChipFamily == CHIP_FAMILY_RS690) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS740)) {
 	    /* 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 +625,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 +651,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..6a9a76d 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)
@@ -72,6 +67,9 @@ radeon_crtc_dpms(xf86CrtcPtr crtc, int mode)
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     xf86CrtcPtr crtc0 = pRADEONEnt->pCrtc[0];
 
+    if ((mode == DPMSModeOn) && radeon_crtc->enabled)
+	return;
+
     if (IS_AVIVO_VARIANT) {
 	atombios_crtc_dpms(crtc, mode);
     } else {
@@ -91,6 +89,11 @@ radeon_crtc_dpms(xf86CrtcPtr crtc, int mode)
 		legacy_crtc_dpms(crtc0, mode);
 	}
     }
+
+    if (mode == DPMSModeOn)
+	radeon_crtc->enabled = TRUE;
+    else
+	radeon_crtc->enabled = FALSE;
 }
 
 static Bool
@@ -103,6 +106,10 @@ radeon_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
 static void
 radeon_crtc_mode_prepare(xf86CrtcPtr crtc)
 {
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+
+    if (radeon_crtc->enabled)
+	crtc->funcs->hide_cursor(crtc);
     radeon_crtc_dpms(crtc, DPMSModeOff);
 }
 
@@ -190,8 +197,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);
@@ -238,6 +247,10 @@ radeon_crtc_mode_commit(xf86CrtcPtr crtc)
     }
 
     radeon_crtc_dpms(crtc, DPMSModeOn);
+
+    if (crtc->scrn->pScreen != NULL)
+	xf86_reload_cursors(crtc->scrn->pScreen);
+
 }
 
 void
@@ -275,6 +288,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 +550,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 +567,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 +591,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 +745,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..42f9a85 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -92,6 +92,7 @@
 static void
 avivo_setup_cursor(xf86CrtcPtr crtc, Bool enable)
 {
+    ScrnInfoPtr pScrn = crtc->scrn;
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     RADEONInfoPtr  info = RADEONPTR(crtc->scrn);
     unsigned char     *RADEONMMIO = info->MMIO;
@@ -100,7 +101,7 @@ avivo_setup_cursor(xf86CrtcPtr crtc, Bool enable)
 
     if (enable) {
 	OUTREG(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
-	       info->fbLocation + radeon_crtc->cursor_offset);
+	       info->fbLocation + radeon_crtc->cursor_offset + pScrn->fbOffset);
 	OUTREG(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset,
 	       ((CURSOR_WIDTH - 1) << 16) | (CURSOR_HEIGHT - 1));
 	OUTREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset,
@@ -108,6 +109,24 @@ avivo_setup_cursor(xf86CrtcPtr crtc, Bool enable)
     }
 }
 
+static void
+avivo_lock_cursor(xf86CrtcPtr crtc, Bool lock)
+{
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    RADEONInfoPtr  info = RADEONPTR(crtc->scrn);
+    unsigned char     *RADEONMMIO = info->MMIO;
+    CARD32 tmp;
+
+    tmp = INREG(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset);
+
+    if (lock)
+	tmp |= AVIVO_D1CURSOR_UPDATE_LOCK;
+    else
+	tmp &= ~AVIVO_D1CURSOR_UPDATE_LOCK;
+
+    OUTREG(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset, tmp);
+}
+
 void
 radeon_crtc_show_cursor (xf86CrtcPtr crtc)
 {
@@ -118,10 +137,12 @@ radeon_crtc_show_cursor (xf86CrtcPtr crtc)
     unsigned char     *RADEONMMIO = info->MMIO;
 
     if (IS_AVIVO_VARIANT) {
+	avivo_lock_cursor(crtc, TRUE);
 	OUTREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset,
 	       INREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset)
 	       | AVIVO_D1CURSOR_EN);
 	avivo_setup_cursor(crtc, TRUE);
+	avivo_lock_cursor(crtc, FALSE);
     } else {
         switch (crtc_id) {
         case 0:
@@ -149,10 +170,12 @@ radeon_crtc_hide_cursor (xf86CrtcPtr crtc)
     unsigned char     *RADEONMMIO = info->MMIO;
 
     if (IS_AVIVO_VARIANT) {
+	avivo_lock_cursor(crtc, TRUE);
 	OUTREG(AVIVO_D1CUR_CONTROL+ radeon_crtc->crtc_offset,
 	       INREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset)
 	       & ~(AVIVO_D1CURSOR_EN));
 	avivo_setup_cursor(crtc, FALSE);
+	avivo_lock_cursor(crtc, FALSE);
     } else {
 	switch(crtc_id) {
     	case 0:
@@ -195,9 +218,11 @@ radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
 	/* avivo cursor spans the full fb width */
 	x += crtc->x;
 	y += crtc->y;
+	avivo_lock_cursor(crtc, TRUE);
 	OUTREG(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset, ((xorigin ? 0 : x) << 16)
 	       | (yorigin ? 0 : y));
 	OUTREG(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin);
+	avivo_lock_cursor(crtc, FALSE);
     } else {
 	if (crtc_id == 0) {
 	    OUTREG(RADEON_CUR_HORZ_VERT_OFF,  (RADEON_CUR_LOCK
@@ -274,7 +299,7 @@ radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     CURSOR_SWAPPING_DECL_MMIO
-    CARD32        *d          = (CARD32 *)(pointer)(info->FB + radeon_crtc->cursor_offset + pScrn->fbOffset);
+    CARD32        *d          = (CARD32 *)(pointer)(info->FB + radeon_crtc->cursor_offset);
 
     RADEONCTRACE(("RADEONLoadCursorARGB\n"));
 
@@ -346,14 +371,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_dri.h b/src/radeon_dri.h
index 3b54626..67892a6 100644
--- a/src/radeon_dri.h
+++ b/src/radeon_dri.h
@@ -46,7 +46,7 @@
 #define RADEON_DEFAULT_BUFFER_SIZE    2 /* MB (must be page aligned) */
 #define RADEON_DEFAULT_GART_TEX_SIZE  1 /* MB (must be page aligned) */
 
-#define RADEON_DEFAULT_CP_TIMEOUT     10000  /* usecs */
+#define RADEON_DEFAULT_CP_TIMEOUT     100000  /* usecs */
 
 #define RADEON_DEFAULT_PCI_APER_SIZE 32 /* in MB */
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 5cf8d51..2701f57 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 {
@@ -387,6 +357,12 @@ static void RADEONFreeRec(ScrnInfoPtr pScrn)
 static Bool RADEONMapMMIO(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+
+    if (pRADEONEnt->MMIO) {
+        info->MMIO = pRADEONEnt->MMIO;
+        return TRUE;
+    }
 
 #ifndef XSERVER_LIBPCIACCESS
 
@@ -397,7 +373,6 @@ static Bool RADEONMapMMIO(ScrnInfoPtr pScrn)
 			       info->MMIOSize);
 
     if (!info->MMIO) return FALSE;
-
 #else
 
     void** result = (void**)&info->MMIO;
@@ -416,6 +391,7 @@ static Bool RADEONMapMMIO(ScrnInfoPtr pScrn)
 
 #endif
 
+    pRADEONEnt->MMIO = info->MMIO;
     return TRUE;
 }
 
@@ -425,6 +401,13 @@ static Bool RADEONMapMMIO(ScrnInfoPtr pScrn)
 static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+
+    if (info->IsPrimary || info->IsSecondary) {
+      /* never unmap on zaphod */
+      info->MMIO = NULL;
+      return TRUE;
+    }
 
 #ifndef XSERVER_LIBPCIACCESS
     xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, info->MMIOSize);
@@ -432,6 +415,7 @@ static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn)
     pci_device_unmap_range(info->PciInfo, info->MMIO, info->MMIOSize);
 #endif
 
+    pRADEONEnt->MMIO = NULL;
     info->MMIO = NULL;
     return TRUE;
 }
@@ -439,6 +423,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 +443,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 +572,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 +601,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 +623,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 +635,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 +651,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 +669,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 +689,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 +708,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 +1249,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 +1449,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;
@@ -1811,6 +1799,19 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
         if (!xf86LoadSubModule(pScrn, "shadow"))
             return FALSE;
     }
+
+
+    if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
+	(info->ChipFamily == CHIP_FAMILY_RS200) ||
+	(info->ChipFamily == CHIP_FAMILY_RS300) ||
+	(info->ChipFamily == CHIP_FAMILY_RS400) ||
+	(info->ChipFamily == CHIP_FAMILY_RS690) ||
+	(info->ChipFamily == CHIP_FAMILY_RS740))
+	info->has_tcl = FALSE;
+    else {
+	info->has_tcl = TRUE;
+    }
+
     return TRUE;
 }
 
@@ -2163,7 +2164,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 +2229,7 @@ static void RADEONPreInitColorTiling(ScrnInfoPtr pScrn)
 		   info->pKernelDRMVersion->version_minor,
 		   info->pKernelDRMVersion->version_patchlevel);
 	   info->allowColorTiling = FALSE;
-	   return;	   
+	   return;
     }
 #endif /* XF86DRI */
 
@@ -2366,7 +2374,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 +2644,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 +2696,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 +2705,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 +2746,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 +2805,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 +3015,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 +3029,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 +3048,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 +3094,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 +3158,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 +3361,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 +3761,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 +4040,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 +4112,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 +4151,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 +4416,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 +4454,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 +4769,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 +4865,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 +5185,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 +5205,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 +5257,6 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
     }
 #endif
 
-    //    pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
     return TRUE;
 }
 
@@ -4978,6 +5267,10 @@ void RADEONLeaveVT(int scrnIndex, int flags)
 {
     ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
+#ifndef HAVE_FREE_SHADOW
+    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int o;
+#endif
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONLeaveVT\n");
@@ -4988,8 +5281,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);
         }
@@ -5009,6 +5303,23 @@ void RADEONLeaveVT(int scrnIndex, int flags)
     }
 #endif
 
+#ifndef HAVE_FREE_SHADOW
+    for (o = 0; o < config->num_crtc; o++) {
+	xf86CrtcPtr crtc = config->crtc[o];
+
+	if (crtc->rotatedPixmap || crtc->rotatedData) {
+	    crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
+					crtc->rotatedData);
+	    crtc->rotatedPixmap = NULL;
+	    crtc->rotatedData = NULL;
+	}
+    }
+#else
+    xf86RotateFreeShadow(pScrn);
+#endif
+
+    xf86_hide_cursors (pScrn);
+
     RADEONRestore(pScrn);
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index 4da4841..fa6ac0d 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)
@@ -182,7 +189,7 @@ Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, CARD32 *pitch_offset)
 	if (bpp == 24)
 		bpp = 8;
 
-	offset = exaGetPixmapOffset(pPix) + info->fbLocation;
+	offset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset;
 	pitch = exaGetPixmapPitch(pPix);
 
 	return RADEONGetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch);
@@ -395,7 +402,7 @@ Bool RADEONSetupMemEXA (ScreenPtr pScreen)
     else
 	screen_size = pScrn->virtualY * byteStride;
 
-    info->exa->memoryBase = info->FB + pScrn->fbOffset;
+    info->exa->memoryBase = info->FB;
     info->exa->memorySize = info->FbMapSize - info->FbSecureSize;
     info->exa->offScreenBase = screen_size;
 
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index 10221c0..272ffa9 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -533,18 +533,17 @@ 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);
 		info->exa->Composite = FUNC_NAME(RadeonComposite);
-		info->exa->DoneComposite = RadeonDoneComposite;
+		info->exa->DoneComposite = FUNC_NAME(RadeonDoneComposite);
 	} else if ((info->ChipFamily == CHIP_FAMILY_RV250) || 
 		   (info->ChipFamily == CHIP_FAMILY_RV280) || 
 		   (info->ChipFamily == CHIP_FAMILY_RS300) || 
@@ -555,7 +554,7 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
 		info->exa->PrepareComposite =
 		    FUNC_NAME(R200PrepareComposite);
 		info->exa->Composite = FUNC_NAME(RadeonComposite);
-		info->exa->DoneComposite = RadeonDoneComposite;
+		info->exa->DoneComposite = FUNC_NAME(RadeonDoneComposite);
 	} else {
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration "
 			       "enabled for R100 type cards.\n");
@@ -563,7 +562,7 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
 		info->exa->PrepareComposite =
 		    FUNC_NAME(R100PrepareComposite);
 		info->exa->Composite = FUNC_NAME(RadeonComposite);
-		info->exa->DoneComposite = RadeonDoneComposite;
+		info->exa->DoneComposite = FUNC_NAME(RadeonDoneComposite);
 	}
     }
 #endif
@@ -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..54b0272 100644
--- a/src/radeon_exa_render.c
+++ b/src/radeon_exa_render.c
@@ -26,6 +26,7 @@
  *    Eric Anholt <anholt@FreeBSD.org>
  *    Zack Rusin <zrusin@trolltech.com>
  *    Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ *    Alex Deucher <alexander.deucher@amd.com>
  *
  */
 
@@ -57,6 +58,13 @@
 #ifdef ONLY_ONCE
 static Bool is_transform[2];
 static PictTransform *transform[2];
+static Bool has_mask;
+/* Whether we are tiling horizontally and vertically */
+static Bool need_src_tile_x;
+static Bool need_src_tile_y;
+/* Size of tiles ... set to 65536x65536 if not tiling in that direction */
+static Bool src_tile_width;
+static Bool src_tile_height;
 
 struct blendinfo {
     Bool dst_alpha;
@@ -177,9 +185,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;
 }
@@ -221,6 +228,95 @@ union intfloat {
     CARD32 i;
 };
 
+/* Check if we need a software-fallback because of a repeating
+ *   non-power-of-two texture.
+ *
+ * canTile: whether we can emulate a repeat by drawing in tiles:
+ *   possible for the source, but not for the mask. (Actually
+ *   we could do tiling for the mask too, but dealing with the
+ *   combination of a tiled mask and a tiled source would be
+ *   a lot of complexity, so we handle only the most common
+ *   case of a repeating mask.)
+ */
+static Bool RADEONCheckTexturePOT(PicturePtr pPict, Bool canTile)
+{
+    int w = pPict->pDrawable->width;
+    int h = pPict->pDrawable->height;
+
+    if (pPict->repeat && ((w & (w - 1)) != 0 || (h & (h - 1)) != 0) &&
+	!(!pPict->transform && canTile))
+	RADEON_FALLBACK(("NPOT repeating %s unsupported (%dx%d), transform=%d\n",
+			 canTile ? "source" : "mask", w, h, pPict->transform != 0));
+
+    return TRUE;
+}
+
+/* Determine if the pitch of the pixmap meets the criteria for being
+ * used as a repeating texture: no padding or only a single line texture.
+ */
+static Bool RADEONPitchMatches(PixmapPtr pPix)
+{
+    int w = pPix->drawable.width;
+    int h = pPix->drawable.height;
+    CARD32 txpitch = exaGetPixmapPitch(pPix);
+
+    if (h > 1 && ((w * pPix->drawable.bitsPerPixel / 8 + 31) & ~31) != txpitch)
+	return FALSE;
+
+    return TRUE;
+}
+
+/* We can't turn on repeats normally for a non-power-of-two dimension,
+ * but if the source isn't transformed, we can get the same effect
+ * by drawing the image in multiple tiles. (A common case that it's
+ * important to get right is drawing a strip of a NPOTxPOT texture
+ * repeating in the POT direction. With tiling, this ends up as a
+ * a single tile on R300 and newer, which is perfect.)
+ *
+ * canTile1d: On R300 and newer, we can repeat a texture that is NPOT in
+ *   one direction and POT in the other in the POT direction; on
+ *   older chips we can only repeat at all if the texture is POT in
+ *   both directions.
+ *
+ * needMatchingPitch: On R100/R200, we can only repeat horizontally if
+ *   there is no padding in the texture. Textures with small POT widths
+ *   (1,2,4,8) thus can't be tiled.
+ */
+static Bool RADEONSetupSourceTile(PicturePtr pPict,
+				  PixmapPtr pPix,
+				  Bool canTile1d,
+				  Bool needMatchingPitch)
+{
+    need_src_tile_x = need_src_tile_y = FALSE;
+    src_tile_width = src_tile_height = 65536; /* "infinite" */
+	    
+    if (pPict->repeat) {
+	Bool badPitch = needMatchingPitch && !RADEONPitchMatches(pPix);
+	
+	int w = pPict->pDrawable->width;
+	int h = pPict->pDrawable->height;
+	
+	if (pPict->transform) {
+	    if (badPitch)
+		RADEON_FALLBACK(("Width %d and pitch %u not compatible for repeat\n",
+				 w, (unsigned)exaGetPixmapPitch(pPix)));
+	} else {
+	    need_src_tile_x = (w & (w - 1)) != 0 || badPitch;
+	    need_src_tile_y = (h & (h - 1)) != 0;
+	    
+	    if (!canTile1d)
+		need_src_tile_x = need_src_tile_y = need_src_tile_x || need_src_tile_y;
+	}
+
+	if (need_src_tile_x)
+	  src_tile_width = w;
+	if (need_src_tile_y)
+	  src_tile_height = h;
+    }
+
+    return TRUE;
+}
+
 /* R100-specific code */
 
 static Bool R100CheckCompositeTexture(PicturePtr pPict, int unit)
@@ -240,8 +336,8 @@ static Bool R100CheckCompositeTexture(PicturePtr pPict, int unit)
 	RADEON_FALLBACK(("Unsupported picture format 0x%x\n",
 			(int)pPict->format));
 
-    if (pPict->repeat && ((w & (w - 1)) != 0 || (h & (h - 1)) != 0))
-	RADEON_FALLBACK(("NPOT repeat unsupported (%dx%d)\n", w, h));
+    if (!RADEONCheckTexturePOT(pPict, unit == 0))
+	return FALSE;
 
     if (pPict->filter != PictFilterNearest &&
 	pPict->filter != PictFilterBilinear)
@@ -261,11 +357,12 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
     CARD32 txfilter, txformat, txoffset, txpitch;
     int w = pPict->pDrawable->width;
     int h = pPict->pDrawable->height;
+    Bool repeat = pPict->repeat && !(unit == 0 && (need_src_tile_x || need_src_tile_y));
     int i;
     ACCEL_PREAMBLE();
 
     txpitch = exaGetPixmapPitch(pPix);
-    txoffset = exaGetPixmapOffset(pPix) + info->fbLocation;
+    txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset;
 
     if ((txoffset & 0x1f) != 0)
 	RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset));
@@ -281,9 +378,8 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
     if (RADEONPixmapIsColortiled(pPix))
 	txoffset |= RADEON_TXO_MACRO_TILE;
 
-    if (pPict->repeat) {
-	if ((h != 1) &&
-	    (((w * pPix->drawable.bitsPerPixel / 8 + 31) & ~31) != txpitch))
+    if (repeat) {
+	if (!RADEONPitchMatches(pPix))
 	    RADEON_FALLBACK(("Width %d and pitch %u not compatible for repeat\n",
 			     w, (unsigned)txpitch));
 
@@ -307,6 +403,9 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
 	RADEON_FALLBACK(("Bad filter 0x%x\n", pPict->filter));
     }
 
+    if (repeat)
+      txfilter |= RADEON_CLAMP_S_WRAP | RADEON_CLAMP_T_WRAP;
+
     BEGIN_ACCEL(5);
     if (unit == 0) {
 	OUT_ACCEL_REG(RADEON_PP_TXFILTER_0, txfilter);
@@ -338,41 +437,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,22 +534,32 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op,
     if (!info->XInited3D)
 	RADEONInit3DEngine(pScrn);
 
-    RADEONGetDestFormat(pDstPicture, &dst_format);
+    if (!RADEONGetDestFormat(pDstPicture, &dst_format))
+	return FALSE;
+
+    if (pMask)
+	has_mask = TRUE;
+    else
+	has_mask = FALSE;
+
     pixel_shift = pDst->drawable.bitsPerPixel >> 4;
 
-    dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation;
+    dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
     dst_pitch = exaGetPixmapPitch(pDst);
     colorpitch = dst_pitch >> pixel_shift;
     if (RADEONPixmapIsColortiled(pDst))
 	colorpitch |= RADEON_COLOR_TILE_ENABLE;
 
-    dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation;
+    dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
     dst_pitch = exaGetPixmapPitch(pDst);
     if ((dst_offset & 0x0f) != 0)
 	RADEON_FALLBACK(("Bad destination offset 0x%x\n", (int)dst_offset));
     if (((dst_pitch >> pixel_shift) & 0x7) != 0)
 	RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch));
 
+    if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE))
+	return FALSE;
+
     if (!FUNC_NAME(R100TextureSetup)(pSrcPicture, pSrc, 0))
 	return FALSE;
     pp_cntl = RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE;
@@ -471,9 +615,13 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op,
 
     OUT_ACCEL_REG(RADEON_PP_TXCBLEND_0, cblend);
     OUT_ACCEL_REG(RADEON_PP_TXABLEND_0, ablend);
-    OUT_ACCEL_REG(RADEON_SE_VTX_FMT, RADEON_SE_VTX_FMT_XY |
-				     RADEON_SE_VTX_FMT_ST0 |
-				     RADEON_SE_VTX_FMT_ST1);
+    if (pMask)
+	OUT_ACCEL_REG(RADEON_SE_VTX_FMT, (RADEON_SE_VTX_FMT_XY |
+					  RADEON_SE_VTX_FMT_ST0 |
+					  RADEON_SE_VTX_FMT_ST1));
+    else
+	OUT_ACCEL_REG(RADEON_SE_VTX_FMT, (RADEON_SE_VTX_FMT_XY |
+					  RADEON_SE_VTX_FMT_ST0));
     /* Op operator. */
     blendcntl = RADEONGetBlendCntl(op, pMaskPicture, pDstPicture->format);
 
@@ -503,8 +651,8 @@ static Bool R200CheckCompositeTexture(PicturePtr pPict, int unit)
 	RADEON_FALLBACK(("Unsupported picture format 0x%x\n",
 			 (int)pPict->format));
 
-    if (pPict->repeat && ((w & (w - 1)) != 0 || (h & (h - 1)) != 0))
-	RADEON_FALLBACK(("NPOT repeat unsupported (%dx%d)\n", w, h));
+    if (!RADEONCheckTexturePOT(pPict, unit == 0))
+	return FALSE;
 
     if (pPict->filter != PictFilterNearest &&
 	pPict->filter != PictFilterBilinear)
@@ -522,17 +670,18 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
     CARD32 txfilter, txformat, txoffset, txpitch;
     int w = pPict->pDrawable->width;
     int h = pPict->pDrawable->height;
+    Bool repeat = pPict->repeat && !(unit == 0 && (need_src_tile_x || need_src_tile_y));
     int i;
     ACCEL_PREAMBLE();
 
     txpitch = exaGetPixmapPitch(pPix);
-    txoffset = exaGetPixmapOffset(pPix) + info->fbLocation;
+    txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset;
 
     if ((txoffset & 0x1f) != 0)
 	RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset));
     if ((txpitch & 0x1f) != 0)
 	RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch));
-    
+
     for (i = 0; i < sizeof(R200TexFormats) / sizeof(R200TexFormats[0]); i++)
     {
 	if (R200TexFormats[i].fmt == pPict->format)
@@ -542,9 +691,8 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
     if (RADEONPixmapIsColortiled(pPix))
 	txoffset |= R200_TXO_MACRO_TILE;
 
-    if (pPict->repeat) {
-	if ((h != 1) &&
-	    (((w * pPix->drawable.bitsPerPixel / 8 + 31) & ~31) != txpitch))
+    if (repeat) {
+	if (!RADEONPitchMatches(pPix))
 	    RADEON_FALLBACK(("Width %d and pitch %u not compatible for repeat\n",
 			     w, (unsigned)txpitch));
 
@@ -570,6 +718,9 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
 	RADEON_FALLBACK(("Bad filter 0x%x\n", pPict->filter));
     }
 
+    if (repeat)
+      txfilter |= R200_CLAMP_S_WRAP | R200_CLAMP_T_WRAP;
+
     BEGIN_ACCEL(6);
     if (unit == 0) {
 	OUT_ACCEL_REG(R200_PP_TXFILTER_0, txfilter);
@@ -604,32 +755,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;
 
-    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"));
+    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->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,10 +833,17 @@ 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;
+
+    if (pMask)
+	has_mask = TRUE;
+    else
+	has_mask = FALSE;
+
     pixel_shift = pDst->drawable.bitsPerPixel >> 4;
 
-    dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation;
+    dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
     dst_pitch = exaGetPixmapPitch(pDst);
     colorpitch = dst_pitch >> pixel_shift;
     if (RADEONPixmapIsColortiled(pDst))
@@ -667,6 +854,9 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture,
     if (((dst_pitch >> pixel_shift) & 0x7) != 0)
 	RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch));
 
+    if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE))
+	return FALSE;
+
     if (!FUNC_NAME(R200TextureSetup)(pSrcPicture, pSrc, 0))
 	return FALSE;
     pp_cntl = RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE;
@@ -688,9 +878,13 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture,
     OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset);
 
     OUT_ACCEL_REG(R200_SE_VTX_FMT_0, R200_VTX_XY);
-    OUT_ACCEL_REG(R200_SE_VTX_FMT_1,
-		 (2 << R200_VTX_TEX0_COMP_CNT_SHIFT) |
-		 (2 << R200_VTX_TEX1_COMP_CNT_SHIFT));
+    if (pMask)
+	OUT_ACCEL_REG(R200_SE_VTX_FMT_1,
+		      (2 << R200_VTX_TEX0_COMP_CNT_SHIFT) |
+		      (2 << R200_VTX_TEX1_COMP_CNT_SHIFT));
+    else
+	OUT_ACCEL_REG(R200_SE_VTX_FMT_1,
+		      (2 << R200_VTX_TEX0_COMP_CNT_SHIFT));
 
     OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch);
 
@@ -744,13 +938,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++)
@@ -762,13 +965,24 @@ static Bool R300CheckCompositeTexture(PicturePtr pPict, int unit)
 	RADEON_FALLBACK(("Unsupported picture format 0x%x\n",
 			 (int)pPict->format));
 
-    if (pPict->repeat && ((w & (w - 1)) != 0 || (h & (h - 1)) != 0))
-	RADEON_FALLBACK(("NPOT repeat unsupported (%dx%d)\n", w, h));
+    if (!RADEONCheckTexturePOT(pPict, unit == 0))
+	return FALSE;
 
     if (pPict->filter != PictFilterNearest &&
 	pPict->filter != PictFilterBilinear)
 	RADEON_FALLBACK(("Unsupported filter 0x%x\n", pPict->filter));
 
+    /* for REPEAT_NONE, Render semantics are that sampling outside the source
+     * picture results in alpha=0 pixels. We can implement this with a border color
+     * *if* our source texture has an alpha channel, otherwise we need to fall
+     * back. If we're not transformed then we hope that upper layers have clipped
+     * rendering to the bounds of the source drawable, in which case it doesn't
+     * matter. I have not, however, verified that the X server always does such
+     * clipping.
+     */
+    if (pPict->transform != 0 && !pPict->repeat && PICT_FORMAT_A(pPict->format) == 0)
+	RADEON_FALLBACK(("REPEAT_NONE unsupported for transformed xRGB source\n"));
+
     return TRUE;
 }
 
@@ -787,13 +1001,14 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
     TRACE;
 
     txpitch = exaGetPixmapPitch(pPix);
-    txoffset = exaGetPixmapOffset(pPix) + info->fbLocation;
+    txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset;
 
     if ((txoffset & 0x1f) != 0)
 	RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset));
     if ((txpitch & 0x1f) != 0)
 	RADEON_FALLBACK(("Bad texture pitch 0x%x\n", (int)txpitch));
 
+    /* TXPITCH = pixels (texels) per line - 1 */
     pixel_shift = pPix->drawable.bitsPerPixel >> 4;
     txpitch >>= pixel_shift;
     txpitch -= 1;
@@ -809,24 +1024,35 @@ 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 && !(unit == 0 && need_src_tile_x))
+      txfilter = R300_TX_CLAMP_S(R300_TX_CLAMP_WRAP);
+    else
+      txfilter = R300_TX_CLAMP_S(R300_TX_CLAMP_CLAMP_GL);
+
+    if (pPict->repeat && !(unit == 0 && need_src_tile_y))
+      txfilter |= R300_TX_CLAMP_T(R300_TX_CLAMP_WRAP);
+    else
+      txfilter |= R300_TX_CLAMP_T(R300_TX_CLAMP_CLAMP_GL);
+		   
+    txfilter |= (unit << R300_TX_ID_SHIFT);
 
     switch (pPict->filter) {
     case PictFilterNearest:
@@ -839,13 +1065,15 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
 	RADEON_FALLBACK(("Bad filter 0x%x\n", pPict->filter));
     }
 
-    BEGIN_ACCEL(6);
+    BEGIN_ACCEL(pPict->repeat ? 6 : 7);
     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);
     OUT_ACCEL_REG(R300_TX_OFFSET_0 + (unit * 4), txoffset);
+    if (!pPict->repeat)
+	OUT_ACCEL_REG(R300_TX_BORDER_COLOR_0 + (unit * 4), 0);
     FINISH_ACCEL();
 
     if (pPict->transform != 0) {
@@ -867,8 +1095,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 +1104,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 +1181,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,10 +1188,17 @@ 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;
+
+    if (pMask)
+	has_mask = TRUE;
+    else
+	has_mask = FALSE;
+
     pixel_shift = pDst->drawable.bitsPerPixel >> 4;
 
-    dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation;
+    dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
     dst_pitch = exaGetPixmapPitch(pDst);
     colorpitch = dst_pitch >> pixel_shift;
 
@@ -965,6 +1212,9 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
     if (((dst_pitch >> pixel_shift) & 0x7) != 0)
 	RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch));
 
+    if (!RADEONSetupSourceTile(pSrcPicture, pSrc, TRUE, FALSE))
+	return FALSE;
+
     if (!FUNC_NAME(R300TextureSetup)(pSrcPicture, pSrc, 0))
 	return FALSE;
     txenable = R300_TEX_0_ENABLE;
@@ -980,28 +1230,32 @@ 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)));
+    if (info->has_tcl) {
+	if (pMask)
+	    BEGIN_ACCEL(8);
+	else
+	    BEGIN_ACCEL(7);
     } 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)));
+	if (pMask)
+	    BEGIN_ACCEL(6);
+	else
+	    BEGIN_ACCEL(5);
     }
 
-    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) {
+    /* These registers define the number, type, and location of data submitted
+     * to the PVS unit of GA input (when PVS is disabled)
+     * DST_VEC_LOC is the slot in the PVS input vector memory when PVS/TCL is
+     * enabled.  This memory provides the imputs to the vertex shader program
+     * and ordering is not important.  When PVS/TCL is disabled, this field maps
+     * directly to the GA input memory and the order is signifigant.  In
+     * PVS_BYPASS mode the order is as follows:
+     * Position
+     * Point Size
+     * Color 0-3
+     * Textures 0-7
+     * Fog
+     */
+    if (pMask) {
 	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) |
@@ -1009,35 +1263,15 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
 		       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) |
+		       (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) |
-		       (11 << R300_DST_VEC_LOC_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_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 {
+    } 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) |
@@ -1046,223 +1280,569 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
 		       (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_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)));
-    }
 
-    /* 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);
+    /* load the vertex shader
+     * We pre-load vertex programs in RADEONInit3DEngine():
+     * - exa no mask
+     * - exa mask
+     * - Xv
+     * Here we select the offset of the vertex program we want to use
+     */
+    if (info->has_tcl) {
+	if (pMask) {
+	    OUT_ACCEL_REG(R300_VAP_PVS_CODE_CNTL_0,
+			  ((0 << R300_PVS_FIRST_INST_SHIFT) |
+			   (2 << R300_PVS_XYZW_VALID_INST_SHIFT) |
+			   (2 << R300_PVS_LAST_INST_SHIFT)));
+	    OUT_ACCEL_REG(R300_VAP_PVS_CODE_CNTL_1,
+			  (2 << R300_PVS_LAST_VTX_SRC_INST_SHIFT));
+	} else {
+	    OUT_ACCEL_REG(R300_VAP_PVS_CODE_CNTL_0,
+			  ((3 << R300_PVS_FIRST_INST_SHIFT) |
+			   (4 << R300_PVS_XYZW_VALID_INST_SHIFT) |
+			   (4 << R300_PVS_LAST_INST_SHIFT)));
+	    OUT_ACCEL_REG(R300_VAP_PVS_CODE_CNTL_1,
+			  (4 << R300_PVS_LAST_VTX_SRC_INST_SHIFT));
+	}
     }
+
+    /* Position and one or two sets of 2 texture coordinates */
     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)));
+    if (pMask)
+	OUT_ACCEL_REG(R300_VAP_OUT_VTX_FMT_1,
+		      ((2 << R300_TEX_0_COMP_CNT_SHIFT) |
+		       (2 << R300_TEX_1_COMP_CNT_SHIFT)));
+    else
+	OUT_ACCEL_REG(R300_VAP_OUT_VTX_FMT_1,
+		      (2 << R300_TEX_0_COMP_CNT_SHIFT));
 
+    OUT_ACCEL_REG(R300_TX_INVALTAGS, 0x0);
+    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_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, load FS */
+	BEGIN_ACCEL(9);
+	if (pMask) {
+	    /* 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));
+
+	    /* R300_INST_COUNT_RS - highest RS instruction used */
+	    OUT_ACCEL_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(1) | R300_TX_OFFSET_RS(6));
+
+	    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)));
+
+	    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 {
+	    /* 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_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6));
+
+	    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)));
+
+	    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));
+	}
 
-    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;
+	/* shader output swizzling */
+	OUT_ACCEL_REG(R300_US_OUT_FMT_0, output_fmt);
+
+	/* tex inst for src texture is pre-loaded in RADEONInit3DEngine() */
+	/* tex inst for mask texture is pre-loaded in RADEONInit3DEngine() */
+
+	/* RGB inst
+	 * temp addresses for texture inputs
+	 * ALU_RGB_ADDR0 is src tex (temp 0)
+	 * ALU_RGB_ADDR1 is mask tex (temp 1)
+	 * R300_ALU_RGB_OMASK - output components to write
+	 * R300_ALU_RGB_TARGET_A - render target
+	 */
+	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));
+	/* RGB inst
+	 * ALU operation
+	 */
+	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));
+	/* Alpha inst
+	 * temp addresses for texture inputs
+	 * ALU_ALPHA_ADDR0 is src tex (0)
+	 * ALU_ALPHA_ADDR1 is mask tex (1)
+	 * R300_ALU_ALPHA_OMASK - output components to write
+	 * R300_ALU_ALPHA_TARGET_A - render target
+	 */
+	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)));
+	/* Alpha inst
+	 * ALU operation
+	 */
+	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_a8:
+	    output_fmt = (R300_OUT_FMT_C4_8 |
+			  R300_OUT_FMT_C0_SEL_ALPHA);
+	    break;
+	}
+
+	BEGIN_ACCEL(6);
+	if (pMask) {
+	    /* 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));
+
+	    /* 2 RS instructions: 1 for tex0 (src), 1 for tex1 (mask) */
+	    OUT_ACCEL_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(1) | R300_TX_OFFSET_RS(6));
+
+	    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 {
+	    OUT_ACCEL_REG(R300_RS_COUNT,
+			  ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |
+			   R300_RS_COUNT_HIRES_EN));
+
+	    OUT_ACCEL_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6));
+
+	    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);
+	    /* tex inst for src texture */
+	    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);
+
+	    /* tex inst for mask texture */
+	    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);
+	    /* tex inst for src texture */
+	    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);
+	}
+
+	/* ALU inst */
+	/* *_OMASK* - output component write mask */
+	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));
+	/* ALU inst
+	 * temp addresses for texture inputs
+	 * RGB_ADDR0 is src tex (temp 0)
+	 * RGB_ADDR1 is mask tex (temp 1)
+	 */
+	OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_RGB_ADDR0(0) |
+					       R500_RGB_ADDR1(1) |
+					       R500_RGB_ADDR2(0)));
+	/* ALU inst
+	 * temp addresses for texture inputs
+	 * ALPHA_ADDR0 is src tex (temp 0)
+	 * ALPHA_ADDR1 is mask tex (temp 1)
+	 */
+	OUT_ACCEL_REG(R500_GA_US_VECTOR_DATA, (R500_ALPHA_ADDR0(0) |
+					       R500_ALPHA_ADDR1(1) |
+					       R500_ALPHA_ADDR2(0)));
+
+	/* R500_ALU_RGB_TARGET - RGB render target */
+	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)));
+
+	/* R500_ALPHA_RGB_TARGET - alpha render target */
+	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();
 
     return TRUE;
 }
 
-#define VTX_COUNT 6
+#define VTX_COUNT_MASK 6
+#define VTX_COUNT 4
 
 #ifdef ACCEL_CP
 
-#define VTX_OUT(_dstX, _dstY, _srcX, _srcY, _maskX, _maskY)	\
+#define VTX_OUT_MASK(_dstX, _dstY, _srcX, _srcY, _maskX, _maskY)	\
 do {								\
     OUT_RING_F(_dstX);						\
     OUT_RING_F(_dstY);						\
@@ -1272,9 +1852,17 @@ do {								\
     OUT_RING_F(_maskY);						\
 } while (0)
 
+#define VTX_OUT(_dstX, _dstY, _srcX, _srcY)	\
+do {								\
+    OUT_RING_F(_dstX);						\
+    OUT_RING_F(_dstY);						\
+    OUT_RING_F(_srcX);						\
+    OUT_RING_F(_srcY);						\
+} while (0)
+
 #else /* ACCEL_CP */
 
-#define VTX_OUT(_dstX, _dstY, _srcX, _srcY, _maskX, _maskY)	\
+#define VTX_OUT_MASK(_dstX, _dstY, _srcX, _srcY, _maskX, _maskY)	\
 do {								\
     OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _dstX);		\
     OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _dstY);		\
@@ -1284,6 +1872,14 @@ do {								\
     OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _maskY);		\
 } while (0)
 
+#define VTX_OUT(_dstX, _dstY, _srcX, _srcY)	\
+do {								\
+    OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _dstX);		\
+    OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _dstY);		\
+    OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _srcX);		\
+    OUT_ACCEL_REG_F(RADEON_SE_PORT_DATA0, _srcY);		\
+} while (0)
+
 #endif /* !ACCEL_CP */
 
 #ifdef ONLY_ONCE
@@ -1299,11 +1895,11 @@ static inline void transformPoint(PictTransform *transform, xPointFixed *point)
 }
 #endif
 
-static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
-				     int srcX, int srcY,
-				     int maskX, int maskY,
-				     int dstX, int dstY,
-				     int w, int h)
+static void FUNC_NAME(RadeonCompositeTile)(PixmapPtr pDst,
+					   int srcX, int srcY,
+					   int maskX, int maskY,
+					   int dstX, int dstY,
+					   int w, int h)
 {
     RINFO_FROM_SCREEN(pDst->drawable.pScreen);
     int vtx_count;
@@ -1347,9 +1943,12 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
 	transformPoint(transform[1], &maskBottomRight);
     }
 
-    vtx_count = VTX_COUNT;
+    if (has_mask)
+	vtx_count = VTX_COUNT_MASK;
+    else
+	vtx_count = VTX_COUNT;
 
-    if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
+    if (IS_R300_3D || IS_R500_3D) {
 	BEGIN_ACCEL(1);
 	OUT_ACCEL_REG(R300_VAP_VTX_SIZE, vtx_count);
 	FINISH_ACCEL();
@@ -1360,17 +1959,21 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
 	BEGIN_RING(4 * vtx_count + 3);
 	OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_3D_DRAW_IMMD,
 			    4 * vtx_count + 1));
-	OUT_RING(RADEON_CP_VC_FRMT_XY |
-		 RADEON_CP_VC_FRMT_ST0 |
-		 RADEON_CP_VC_FRMT_ST1);
+	if (has_mask)
+	    OUT_RING(RADEON_CP_VC_FRMT_XY |
+		     RADEON_CP_VC_FRMT_ST0 |
+		     RADEON_CP_VC_FRMT_ST1);
+	else
+	    OUT_RING(RADEON_CP_VC_FRMT_XY |
+		     RADEON_CP_VC_FRMT_ST0);
 	OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN |
 		 RADEON_CP_VC_CNTL_PRIM_WALK_RING |
 		 RADEON_CP_VC_CNTL_MAOS_ENABLE |
 		 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
 		 (4 << RADEON_CP_VC_CNTL_NUM_SHIFT));
     } else {
-	if (IS_R300_VARIANT || IS_AVIVO_VARIANT)
-	    BEGIN_RING(4 * vtx_count + 6);
+	if (IS_R300_3D | IS_R500_3D)
+	    BEGIN_RING(4 * vtx_count + 4);
 	else
 	    BEGIN_RING(4 * vtx_count + 2);
 
@@ -1382,8 +1985,8 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
     }
 
 #else /* ACCEL_CP */
-    if (IS_R300_VARIANT || IS_AVIVO_VARIANT)
-	BEGIN_ACCEL(3 + vtx_count * 4);
+    if (IS_R300_3D | IS_R500_3D)
+	BEGIN_ACCEL(2 + vtx_count * 4);
     else
 	BEGIN_ACCEL(1 + vtx_count * 4);
 
@@ -1399,24 +2002,34 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
     }
 #endif
 
-    VTX_OUT((float)dstX,                                      (float)dstY,
-	    xFixedToFloat(srcTopLeft.x) / info->texW[0],      xFixedToFloat(srcTopLeft.y) / info->texH[0],
-	    xFixedToFloat(maskTopLeft.x) / info->texW[1],     xFixedToFloat(maskTopLeft.y) / info->texH[1]);
-    VTX_OUT((float)dstX,                                      (float)(dstY + h),
-	    xFixedToFloat(srcBottomLeft.x) / info->texW[0],   xFixedToFloat(srcBottomLeft.y) / info->texH[0],
-	    xFixedToFloat(maskBottomLeft.x) / info->texW[1],  xFixedToFloat(maskBottomLeft.y) / info->texH[1]);
-    VTX_OUT((float)(dstX + w),                                (float)(dstY + h),
-	    xFixedToFloat(srcBottomRight.x) / info->texW[0],  xFixedToFloat(srcBottomRight.y) / info->texH[0],
-	    xFixedToFloat(maskBottomRight.x) / info->texW[1], xFixedToFloat(maskBottomRight.y) / info->texH[1]);
-    VTX_OUT((float)(dstX + w),                                (float)dstY,
-	    xFixedToFloat(srcTopRight.x) / info->texW[0],     xFixedToFloat(srcTopRight.y) / info->texH[0],
-	    xFixedToFloat(maskTopRight.x) / info->texW[1],    xFixedToFloat(maskTopRight.y) / info->texH[1]);
-
-    if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
-	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
-	OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
+    if (has_mask) {
+	VTX_OUT_MASK((float)dstX,                                      (float)dstY,
+		xFixedToFloat(srcTopLeft.x) / info->texW[0],      xFixedToFloat(srcTopLeft.y) / info->texH[0],
+		xFixedToFloat(maskTopLeft.x) / info->texW[1],     xFixedToFloat(maskTopLeft.y) / info->texH[1]);
+	VTX_OUT_MASK((float)dstX,                                      (float)(dstY + h),
+		xFixedToFloat(srcBottomLeft.x) / info->texW[0],   xFixedToFloat(srcBottomLeft.y) / info->texH[0],
+		xFixedToFloat(maskBottomLeft.x) / info->texW[1],  xFixedToFloat(maskBottomLeft.y) / info->texH[1]);
+	VTX_OUT_MASK((float)(dstX + w),                                (float)(dstY + h),
+		xFixedToFloat(srcBottomRight.x) / info->texW[0],  xFixedToFloat(srcBottomRight.y) / info->texH[0],
+		xFixedToFloat(maskBottomRight.x) / info->texW[1], xFixedToFloat(maskBottomRight.y) / info->texH[1]);
+	VTX_OUT_MASK((float)(dstX + w),                                (float)dstY,
+		xFixedToFloat(srcTopRight.x) / info->texW[0],     xFixedToFloat(srcTopRight.y) / info->texH[0],
+		xFixedToFloat(maskTopRight.x) / info->texW[1],    xFixedToFloat(maskTopRight.y) / info->texH[1]);
+    } else {
+	VTX_OUT((float)dstX,                                      (float)dstY,
+		xFixedToFloat(srcTopLeft.x) / info->texW[0],      xFixedToFloat(srcTopLeft.y) / info->texH[0]);
+	VTX_OUT((float)dstX,                                      (float)(dstY + h),
+		xFixedToFloat(srcBottomLeft.x) / info->texW[0],   xFixedToFloat(srcBottomLeft.y) / info->texH[0]);
+	VTX_OUT((float)(dstX + w),                                (float)(dstY + h),
+		xFixedToFloat(srcBottomRight.x) / info->texW[0],  xFixedToFloat(srcBottomRight.y) / info->texH[0]);
+	VTX_OUT((float)(dstX + w),                                (float)dstY,
+		xFixedToFloat(srcTopRight.x) / info->texW[0],     xFixedToFloat(srcTopRight.y) / info->texH[0]);
     }
 
+    if (IS_R300_3D | IS_R500_3D)
+	/* flushing is pipelined, free/finish is not */
+	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D);
+
 #ifdef ACCEL_CP
     ADVANCE_RING();
 #else
@@ -1426,14 +2039,88 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
     LEAVE_DRAW(0);
 }
 #undef VTX_OUT
+#undef VTX_OUT_MASK
 
-#ifdef ONLY_ONCE
-static void RadeonDoneComposite(PixmapPtr pDst)
+static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst,
+				       int srcX, int srcY,
+				       int maskX, int maskY,
+				       int dstX, int dstY,
+				       int width, int height)
+{
+    int tileSrcY, tileMaskY, tileDstY;
+    int remainingHeight;
+    
+    if (!need_src_tile_x && !need_src_tile_y) {
+	FUNC_NAME(RadeonCompositeTile)(pDst,
+				       srcX, srcY,
+				       maskX, maskY,
+				       dstX, dstY,
+				       width, height);
+	return;
+    }
+
+    /* Tiling logic borrowed from exaFillRegionTiled */
+
+    modulus(srcY, src_tile_height, tileSrcY);
+    tileMaskY = maskY;
+    tileDstY = dstY;
+
+    remainingHeight = height;
+    while (remainingHeight > 0) {
+	int remainingWidth = width;
+	int tileSrcX, tileMaskX, tileDstX;
+	int h = src_tile_height - tileSrcY;
+	
+	if (h > remainingHeight)
+	    h = remainingHeight;
+	remainingHeight -= h;
+
+	modulus(srcX, src_tile_width, tileSrcX);
+	tileMaskX = maskX;
+	tileDstX = dstX;
+	
+	while (remainingWidth > 0) {
+	    int w = src_tile_width - tileSrcX;
+	    if (w > remainingWidth)
+		w = remainingWidth;
+	    remainingWidth -= w;
+	    
+	    FUNC_NAME(RadeonCompositeTile)(pDst,
+					   tileSrcX, tileSrcY,
+					   tileMaskX, tileMaskY,
+					   tileDstX, tileDstY,
+					   w, h);
+	    
+	    tileSrcX = 0;
+	    tileMaskX += w;
+	    tileDstX += w;
+	}
+	tileSrcY = 0;
+	tileMaskY += h;
+	tileDstY += h;
+    }
+}
+
+static void FUNC_NAME(RadeonDoneComposite)(PixmapPtr pDst)
 {
+    RINFO_FROM_SCREEN(pDst->drawable.pScreen);
+    ACCEL_PREAMBLE();
+
     ENTER_DRAW(0);
+
+    if (IS_R500_3D || ((info->ChipFamily == CHIP_FAMILY_RS400) ||
+		       (info->ChipFamily == CHIP_FAMILY_RS690) ||
+		       (info->ChipFamily == CHIP_FAMILY_RS740))) {
+	/* r500 shows corruption on small things like glyphs without a 3D idle 
+	 * IGP shows more substantial corruption
+	 */
+	BEGIN_ACCEL(1);
+	OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
+	FINISH_ACCEL();
+    }
+
     LEAVE_DRAW(0);
 }
-#endif /* ONLY_ONCE */
 
 #undef ONLY_ONCE
 #undef FUNC_NAME
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 62cc5d4..907d824 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;
@@ -485,6 +481,10 @@ static void
 radeon_dpms(xf86OutputPtr output, int mode)
 {
     RADEONInfoPtr info = RADEONPTR(output->scrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    if ((mode == DPMSModeOn) && radeon_output->enabled)
+	return;
 
     if (IS_AVIVO_VARIANT) {
 	atombios_output_dpms(output, mode);
@@ -493,6 +493,11 @@ radeon_dpms(xf86OutputPtr output, int mode)
     }
     radeon_bios_output_dpms(output, mode);
 
+    if (mode == DPMSModeOn)
+	radeon_output->enabled = TRUE;
+    else
+	radeon_output->enabled = FALSE;
+
 }
 
 static void
@@ -673,15 +678,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 +1173,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 +1241,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 +1443,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 +1501,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 +1550,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 +1570,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 +1586,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 +1601,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 +1616,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 +1697,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 +2216,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 +2267,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 +2810,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 +2824,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..f03e997 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,8 @@ 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;
+    Bool enabled;
 } RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr;
 
 typedef struct {
@@ -208,6 +205,7 @@ typedef struct {
     int devices;
     int hpd_mask;
     RADEONI2CBusRec ddc_i2c;
+    int igp_lane_info;
 } RADEONBIOSConnector;
 
 typedef struct _RADEONOutputPrivateRec {
@@ -256,10 +254,15 @@ 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;
     int               devices;
+    Bool enabled;
 } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
 
 struct avivo_pll_state {
@@ -273,7 +276,6 @@ struct avivo_pll_state {
     CARD32 int_ss_cntl;
 };
 
-
 struct avivo_crtc_state {
     CARD32 pll_source;
     CARD32 h_total;
@@ -310,24 +312,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 +327,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 +336,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 +506,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;
@@ -571,6 +588,7 @@ typedef struct
     RADEONSaveRec     ModeReg;          /* Current mode                      */
     RADEONSaveRec     SavedReg;         /* Original (text) mode              */
 
+    void              *MMIO;            /* Map of MMIO region                */
 } RADEONEntRec, *RADEONEntPtr;
 
 /* radeon_probe.c */
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 046c52b..815bcaa 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
@@ -1634,9 +1661,25 @@
 
 #define RADEON_WAIT_UNTIL                   0x1720
 #       define RADEON_WAIT_CRTC_PFLIP       (1 << 0)
+#       define RADEON_WAIT_RE_CRTC_VLINE    (1 << 1)
+#       define RADEON_WAIT_FE_CRTC_VLINE    (1 << 2)
+#       define RADEON_WAIT_CRTC_VLINE       (1 << 3)
+#       define RADEON_WAIT_DMA_VID_IDLE     (1 << 8)
+#       define RADEON_WAIT_DMA_GUI_IDLE     (1 << 9)
+#       define RADEON_WAIT_CMDFIFO          (1 << 10) /* wait for CMDFIFO_ENTRIES */
+#       define RADEON_WAIT_OV0_FLIP         (1 << 11)
+#       define RADEON_WAIT_AGP_FLUSH        (1 << 13)
+#       define RADEON_WAIT_2D_IDLE          (1 << 14)
+#       define RADEON_WAIT_3D_IDLE          (1 << 15)
 #       define RADEON_WAIT_2D_IDLECLEAN     (1 << 16)
 #       define RADEON_WAIT_3D_IDLECLEAN     (1 << 17)
 #       define RADEON_WAIT_HOST_IDLECLEAN   (1 << 18)
+#       define RADEON_CMDFIFO_ENTRIES_SHIFT 10
+#       define RADEON_CMDFIFO_ENTRIES_MASK  0x7f
+#       define RADEON_WAIT_VAP_IDLE         (1 << 28)
+#       define RADEON_WAIT_BOTH_CRTC_PFLIP  (1 << 30)
+#       define RADEON_ENG_DISPLAY_SELECT_CRTC0    (0 << 31)
+#       define RADEON_ENG_DISPLAY_SELECT_CRTC1    (1 << 31)
 
 #define RADEON_X_MPLL_REF_FB_DIV            0x000a /* PLL */
 #define RADEON_XCLK_CNTL                    0x000d /* PLL */
@@ -3328,10 +3371,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
@@ -3475,6 +3540,8 @@
 #define AVIVO_D1CUR_SIZE                        0x6410
 #define AVIVO_D1CUR_POSITION                    0x6414
 #define AVIVO_D1CUR_HOT_SPOT                    0x6418
+#define AVIVO_D1CUR_UPDATE                      0x6424
+#       define AVIVO_D1CURSOR_UPDATE_LOCK (1 << 16)
 
 #define AVIVO_DC_LUT_RW_SELECT                  0x6480
 #define AVIVO_DC_LUT_RW_MODE                    0x6484
@@ -3555,6 +3622,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 +3814,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
@@ -3832,6 +3903,7 @@
 #define R300_GB_SELECT				        0x401c
 #define R300_GB_ENABLE				        0x4008
 #define R300_GB_AA_CONFIG				0x4020
+#define R400_GB_PIPE_SELECT                             0x402c
 #define R300_GB_MSPOS0				        0x4010
 #       define R300_MS_X0_SHIFT                         0
 #       define R300_MS_Y0_SHIFT                         4
@@ -3850,6 +3922,10 @@
 #       define R300_MS_Y5_SHIFT                         20
 #       define R300_MSBD1_SHIFT                         24
 
+#define R300_GA_ENHANCE				        0x4274
+#       define R300_GA_DEADLOCK_CNTL                    (1 << 0)
+#       define R300_GA_FASTSYNC_CNTL                    (1 << 1)
+
 #define R300_GA_POLY_MODE				0x4288
 #       define R300_FRONT_PTYPE_POINT                   (0 << 4)
 #       define R300_FRONT_PTYPE_LINE                    (1 << 4)
@@ -3889,6 +3965,8 @@
 #       define R300_ALPHA3_SHADING_GOURAUD              (2 << 14)
 #define R300_GA_OFFSET				        0x4290
 
+#define R500_SU_REG_DEST                                0x42c8
+
 #define R300_VAP_CNTL_STATUS				0x2140
 #       define R300_PVS_BYPASS                          (1 << 8)
 #define R300_VAP_PVS_STATE_FLUSH_REG		        0x2284
@@ -3899,6 +3977,7 @@
 #       define R300_VF_MAX_VTX_NUM_SHIFT                18
 #       define R300_GL_CLIP_SPACE_DEF                   (0 << 22)
 #       define R300_DX_CLIP_SPACE_DEF                   (1 << 22)
+#       define R500_TCL_STATE_OPTIMIZATION              (1 << 23)
 #define R300_VAP_VTE_CNTL				0x20B0
 #       define R300_VPORT_X_SCALE_ENA                   (1 << 0)
 #       define R300_VPORT_X_OFFSET_ENA                  (1 << 1)
@@ -3909,6 +3988,7 @@
 #       define R300_VTX_XY_FMT                          (1 << 8)
 #       define R300_VTX_Z_FMT                           (1 << 9)
 #       define R300_VTX_W0_FMT                          (1 << 10)
+#define R300_VAP_VTX_STATE_CNTL		                0x2180
 #define R300_VAP_PSC_SGN_NORM_CNTL		        0x21DC
 #define R300_VAP_PROG_STREAM_CNTL_0		        0x2150
 #       define R300_DATA_TYPE_0_SHIFT                   0
@@ -3986,6 +4066,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 +4216,9 @@
 #       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 R500_VAP_INDEX_OFFSET			        0x208c
 
 #define R300_SU_TEX_WRAP				0x42a0
 #define R300_SU_POLY_OFFSET_ENABLE		        0x42b4
@@ -4036,6 +4236,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 +4264,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 +4286,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 +4369,16 @@
 #       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_BORDER_COLOR_0			        0x45c0
 
 #define R300_TX_ENABLE				        0x4104
 #       define R300_TEX_0_ENABLE                        (1 << 0)
@@ -4189,7 +4399,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,28 +4437,221 @@
 #       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
 #define R300_FG_ALPHA_FUNC				0x4bd4
 
+#define R300_DST_PIPE_CONFIG		                0x170c
+#       define R300_PIPE_AUTO_CONFIG                    (1 << 31)
+#define R300_RB2D_DSTCACHE_MODE		                0x3428
+#       define R300_DC_AUTOFLUSH_ENABLE                 (1 << 8)
+#       define R300_DC_DC_DISABLE_IGNORE_PE             (1 << 17)
+#define R300_RB2D_DSTCACHE_CTLSTAT		        0x342c
+#       define R300_DC_FLUSH_2D                         (1 << 0)
+#       define R300_DC_FREE_2D                          (1 << 2)
+#       define R300_RB2D_DC_FLUSH_ALL                   (R300_DC_FLUSH_2D | R300_DC_FREE_2D)
+#       define R300_RB2D_DC_BUSY                        (1 << 31)
 #define R300_RB3D_DSTCACHE_CTLSTAT		        0x4e4c
 #       define R300_DC_FLUSH_3D                         (2 << 0)
 #       define R300_DC_FREE_3D                          (2 << 2)
+#       define R300_RB3D_DC_FLUSH_ALL                   (R300_DC_FLUSH_3D | R300_DC_FREE_3D)
+#       define R300_DC_FINISH_3D                        (1 << 4)
 #define R300_RB3D_ZCACHE_CTLSTAT			0x4f18
 #       define R300_ZC_FLUSH                            (1 << 0)
 #       define R300_ZC_FREE                             (1 << 1)
-#define R300_WAIT_UNTIL				        0x1720
-#       define R300_WAIT_2D_IDLECLEAN                   (1 << 16)
-#       define R300_WAIT_3D_IDLECLEAN                   (1 << 17)
+#       define R300_ZC_FLUSH_ALL                        0x3
 #define R300_RB3D_ZSTENCILCNTL			        0x4f04
 #define R300_RB3D_ZCACHE_CTLSTAT		        0x4f18
 #define R300_RB3D_BW_CNTL				0x4f1c
@@ -4256,6 +4659,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 +4793,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 +4946,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 +5185,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 +5204,18 @@
 #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)
+
+#define R500_DYN_SCLK_PWMEM_PIPE                        0x000d /* PLL */
 
 #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..5d153e7 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;
@@ -223,7 +226,7 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
     left = (x1 >> 16) & ~1;
     npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left;
 
-    pPriv->src_offset = pPriv->video_offset + info->fbLocation;
+    pPriv->src_offset = pPriv->video_offset + info->fbLocation + pScrn->fbOffset;
     pPriv->src_addr = (CARD8 *)(info->FB + pPriv->video_offset + (top * dstPitch));
     pPriv->src_pitch = dstPitch;
     pPriv->size = size;
@@ -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..b0286a6 100644
--- a/src/radeon_textured_videofuncs.c
+++ b/src/radeon_textured_videofuncs.c
@@ -80,16 +80,15 @@ 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;
 
 #ifdef USE_EXA
     if (info->useEXA) {
-	dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation;
+	dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset;
 	dst_pitch = exaGetPixmapPitch(pPixmap);
     } else
 #endif
@@ -107,28 +106,22 @@ 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);
 
     /* we can probably improve this */
     BEGIN_VIDEO(2);
-    OUT_VIDEO_REG(RADEON_RB3D_DSTCACHE_CTLSTAT, RADEON_RB3D_DC_FLUSH);
+    if (IS_R300_3D || IS_R500_3D)
+	OUT_VIDEO_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D);
+    else
+	OUT_VIDEO_REG(RADEON_RB3D_DSTCACHE_CTLSTAT, RADEON_RB3D_DC_FLUSH);
     /* We must wait for 3d to idle, in case source was just written as a dest. */
     OUT_VIDEO_REG(RADEON_WAIT_UNTIL,
 		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) {
+	CARD32 output_fmt;
 
 	switch (pPixmap->drawable.bitsPerPixel) {
 	case 16:
@@ -144,6 +137,12 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 	    return;
 	}
 
+	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);
+
 	colorpitch = dst_pitch >> pixel_shift;
 	colorpitch |= dst_format;
 
@@ -157,8 +156,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 +172,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);
@@ -187,173 +192,220 @@ 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) {
+	if (info->has_tcl)
+	    BEGIN_VIDEO(6);
+	else
+	    BEGIN_VIDEO(4);
+
+	/* These registers define the number, type, and location of data submitted
+	 * to the PVS unit of GA input (when PVS is disabled)
+	 * DST_VEC_LOC is the slot in the PVS input vector memory when PVS/TCL is
+	 * enabled.  This memory provides the imputs to the vertex shader program
+	 * and ordering is not important.  When PVS/TCL is disabled, this field maps
+	 * directly to the GA input memory and the order is signifigant.  In
+	 * PVS_BYPASS mode the order is as follows:
+	 * Position
+	 * Point Size
+	 * Color 0-3
+	 * Textures 0-7
+	 * Fog
+	 */
+	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));
+
+	/* load the vertex shader
+	 * We pre-load vertex programs in RADEONInit3DEngine():
+	 * - exa no mask
+	 * - exa mask
+	 * - Xv
+	 * Here we select the offset of the vertex program we want to use
+	 */
+	if (info->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)));
+			  ((5 << R300_PVS_FIRST_INST_SHIFT) |
+			   (6 << R300_PVS_XYZW_VALID_INST_SHIFT) |
+			   (6 << 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);
+			  (6 << R300_PVS_LAST_VTX_SRC_INST_SHIFT));
 	}
 
+	/* Position and one set of 2 texture coordinates */
 	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_US_OUT_FMT_0, output_fmt);
 	FINISH_VIDEO();
 
 	/* setup pixel shader */
-	if (IS_R300_VARIANT || info->ChipFamily == CHIP_FAMILY_RS690) {
-	    BEGIN_VIDEO(16);
+	if (IS_R300_3D) {
+	    BEGIN_VIDEO(8);
+	    /* 2 components: 2 for tex0 */
 	    OUT_VIDEO_REG(R300_RS_COUNT,
 			  ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |
 			   R300_RS_COUNT_HIRES_EN));
-	    OUT_VIDEO_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_VIDEO_REG(R300_RS_INST_COUNT, 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);
+	    /* R300_INST_COUNT_RS - highest RS instruction used */
+	    OUT_VIDEO_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6));
+
 	    OUT_VIDEO_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_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_3,
+			  (R300_ALU_START(0) |
+			   R300_ALU_SIZE(0) |
+			   R300_TEX_START(0) |
+			   R300_TEX_SIZE(0) |
+			   R300_RGBA_OUT));
+
+	    /* tex inst is preloaded in RADEONInit3DEngine() */
+
+	    /* ALU inst */
+	    /* RGB */
+	    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_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));
+	    /* Alpha */
+	    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_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(18);
+	    /* 2 components: 2 for tex0 */
 	    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(R300_RS_INST_COUNT, 0);
-	    OUT_VIDEO_REG(R500_RS_INST_0, R500_RS_INST_TEX_CN_WRITE);
-	    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));
+
+	    /* R300_INST_COUNT_RS - highest RS instruction used */
+	    OUT_VIDEO_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6));
+
+	    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);
+
+	    /* tex inst */
+	    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);
+
+	    /* ALU inst */
+	    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));
+	    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));
+
+	    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);
+	BEGIN_VIDEO(5);
 	OUT_VIDEO_REG(R300_TX_INVALTAGS, 0);
 	OUT_VIDEO_REG(R300_TX_ENABLE, txenable);
 
@@ -361,8 +413,8 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 	OUT_VIDEO_REG(R300_RB3D_COLORPITCH0, colorpitch);
 
 	blendcntl = RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO;
+	/* no need to enable blending */
 	OUT_VIDEO_REG(R300_RB3D_BLENDCNTL, blendcntl);
-	OUT_VIDEO_REG(R300_RB3D_ABLENDCNTL, 0);
 	FINISH_VIDEO();
 
 	BEGIN_VIDEO(1);
@@ -538,8 +590,8 @@ 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)
-		BEGIN_RING(4 * VTX_DWORD_COUNT + 6);
+	    if (IS_R300_3D || IS_R500_3D)
+		BEGIN_RING(4 * VTX_DWORD_COUNT + 4);
 	    else
 		BEGIN_RING(4 * VTX_DWORD_COUNT + 2);
 	    OUT_RING(CP_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2,
@@ -549,8 +601,8 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 		     (4 << RADEON_CP_VC_CNTL_NUM_SHIFT));
 	}
 #else /* ACCEL_CP */
-	if (IS_R300_VARIANT || IS_AVIVO_VARIANT)
-	    BEGIN_VIDEO(3 + VTX_DWORD_COUNT * 4);
+	if (IS_R300_3D || IS_R500_3D)
+	    BEGIN_VIDEO(2 + VTX_DWORD_COUNT * 4);
 	else
 	    BEGIN_VIDEO(1 + VTX_DWORD_COUNT * 4);
 
@@ -575,10 +627,9 @@ 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) {
-	    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);
-	}
+	if (IS_R300_3D || IS_R500_3D)
+	    /* flushing is pipelined, free/finish is not */
+	    OUT_VIDEO_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D);
 
 #ifdef ACCEL_CP
 	ADVANCE_RING();
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