Blob Blame Raw
commit 792123c802991e2a0ef6f37361ceccf9373ce81f
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Mar 5 16:05:41 2009 +1000

    radeon: add support for relocatable CRTC inside VLINE
    
    We cannot let userspace decide which CRTC it wants because its userspace
    and might not own the crtc, so we need to provide a way to relocate it

commit 25471f05a590bf0aff31d29cd1ac0de4bf4409b9
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Mar 3 15:30:21 2009 +1000

    radeon: initial framebuffer resize support
    
    This relies on the kernel pinning everything which the latest
    rawhide kernel should do fine

commit 7d0a186543661e10167590b1743459754fdda75d
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Mar 3 09:20:30 2009 +1000

    radeon: do get sarea until we know we aren't DRI2

commit 92d98c27fb82debf303e90dd29fbb691bb112cc3
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Mar 3 09:12:30 2009 +1000

    radeon: no need to do any of this for DRI2

commit 633e5bf4a81449e8800d4deea1166fddb75a9fb2
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Feb 27 12:00:29 2009 +1000

    fixup issues post rebase

commit 36c1522b08722de1c2164481ce418bd1f08c5261
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Feb 26 10:47:42 2009 +1000

    radeon: don't init 3d engine in Xv path for drm mm

commit d21c95cd5ffa21568bd18d2b3f6efaf9c9b571f3
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Feb 17 19:14:27 2009 +1000

    radeon: fix vt switch for legacy paths

commit 181b0eed3c247f4ac3fceb8b75aeaae92e5926aa
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Feb 17 19:13:05 2009 +1000

    radeon: only init gart heap for non-kms

commit bf389fd99a9b9ef1895cc77b213db5817cca7b3d
Author: Dave Airlie <airlied@redhat.com>
Date:   Sun Jan 11 09:29:44 2009 +1000

    radeon: drop CS1

commit 06952498f6cc23e29a40a9f62af2edd7ecb090e2
Author: Jerome Glisse <glisse@freedesktop.org>
Date:   Wed Nov 12 14:36:52 2008 +0100

    radeon: enable dri2 only if memory manager is present
    (cherry picked from commit fd4bb9b7b639befd63e7acd37254011b9e46732d)

commit ed9d3d1f442ac68dd46d62a5e8f2236e851204b0
Author: Jerome Glisse <glisse@freedesktop.org>
Date:   Mon Nov 10 22:16:57 2008 +0100

    radeon: flush command stream in block handler and in dri2 copy callback
    (cherry picked from commit 13fa5ab73a707af52e71af400ea186073022f8b7)

commit b7b3ef60fc68a52627be2211700e6c8332889d48
Author: Jerome Glisse <glisse@freedesktop.org>
Date:   Fri Nov 14 12:44:29 2008 +0100

    radeon: bufmgr exa doesn't exist
    (cherry picked from commit 8a00de47a186db1707b82a5977da8cbf2e8e0c80)

commit 19ce13951371b8576f51da9b4e6d8a70b7edb0f6
Author: Jerome Glisse <glisse@freedesktop.org>
Date:   Thu Nov 6 00:25:18 2008 +0100

    radeon: initial dri2 support

commit 972cfd240fde82d9b6e2259c9e622e13b261a29d
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Dec 1 19:15:41 2008 +1000

    radeno: fixup unpinned buffers
    (cherry picked from commit d9759ca976cad48e6c8fd3c7d17ce38588522c34)

commit 37d665b6f3193929afae7608a92f7a05dc830a76
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Dec 22 16:16:16 2008 +1000

    radeon: fix for 1.6 server

commit 2e27c619191ff42698662b538863237df557c3a6
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Dec 19 12:37:01 2008 +1100

    radeon: only do mappings if direct rendering is enabled

commit 80308a43b19966cdc1e9b58249ced45080f7e6ba
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Dec 9 13:29:18 2008 +1000

    radeon: upstream fix for Init3D vs switch to/from 2d/3d

commit 0ccd8d665d2b11a4af35586d86c8cb7742ad14e0
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Dec 8 14:19:47 2008 +1000

    radeon: only update dri buffers if DRI enabled

commit 19f0842e41a81a8cd883048f9fae8736734ea3f4
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Dec 1 15:31:08 2008 +1100

    radeon: don't have 2D and 3D in one CS buffer

commit 5a09cdbd0dee2513dfde9da4e11cbc9ba85b28d6
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Nov 26 16:09:29 2008 +1100

    radeon: set touched flag on pinned buffers

commit b1153a6c85856db565791e8937b60214d32eff3b
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Nov 26 16:04:35 2008 +1100

    radeon: fix up some of the touched by gpu handling and force gtt handling
    
    this fixes DFS on the rs690

commit cd04e7dd7067b5ab067a5252884e85bef8d7f60b
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Nov 26 12:52:24 2008 +1100

    radeon: brutal attempt to fix RS4xx and RS6xx by flushing more often
    
    this might take more CPU but hopefully leads to stabler GPU

commit ea31830a208ff187d86a131236d3a681551c8de3
Author: Dave Airlie <airlied@redhat.com>
Date:   Sun Nov 23 17:56:02 2008 +1000

    radeon: wait for rendering before doing UTS

commit aa6f7f49f8a7576bdbd05e440126aa61e614a1a0
Author: Dave Airlie <airlied@redhat.com>
Date:   Sun Nov 23 17:54:27 2008 +1000

    radeon: stop this_op_read from going negative

commit d49164d6cfe4b75706fe5700b1d572bcb24ff3c1
Author: Dave Airlie <airlied@redhat.com>
Date:   Sun Nov 23 17:52:42 2008 +1000

    radeon: return flush for conflicting domains

commit fa9c42e37adc3755ae64e0362faa6b2c8daefe2c
Author: Dave Airlie <airlied@redhat.com>
Date:   Sun Nov 23 17:50:47 2008 +1000

    radeon: only reset state2d before emitting cache flush

commit 152939e563e77a90a1154669fa7b9af4c0392d63
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Nov 20 16:48:33 2008 +1000

    flush on UTS if any references

commit 41a16e4646f422e5cc76e44631ec17a5fd5d019f
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Nov 20 16:44:40 2008 +1000

    radeon: add gart vs vram writes

commit 64ced4a986b8c5c6534b4a27830e3a1e6119e269
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Nov 20 16:37:07 2008 +1000

    radeon: improve DFS performance for non-vram objects

commit 9f9545dd3b926b0edbef6dbe8f7b4c544e8f2631
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Nov 19 14:49:44 2008 +1000

    radeon: scrap state on LeaveVT not EnterVT

commit 9d80e58ee16d56d7b6c5d1dcbf6e8dafc4ce09ae
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Nov 19 11:08:34 2008 +1000

    radeon: even more typos

commit 1823d254a3a07ceea9cf7c6d70b0b22193fe4b27
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Nov 19 07:51:03 2008 +1000

    radeon: oops bad typo

commit 61285e439341b3ac357b46086b7535f8a3c6252c
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Nov 18 16:09:10 2008 +1000

    radeon: even if kernels fails, struggle onwards
    
    try and keep the session going even if visual glitches happen

commit e97d0ee5deb8dd8b681c491c5ef5505ae24db3a0
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Nov 18 15:46:46 2008 +1000

    radeon_bufmgr: much more complete size check functionality

commit 60806b5a76582478323be5649aeee510f0043328
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Nov 18 14:33:44 2008 +1000

    radeon: I fail at uint32_t division

commit 7402017c10bb3ef0d02dd81a940df1d97f14ec42
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Nov 18 12:06:02 2008 +1000

    radeon: workaround O(wtf) logic in post_submit bufmgr

commit 86265d8a8134e16211c8e179d2b5af11af77646e
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 17 19:19:43 2008 +1000

    radeon: set emit limit to 90% VRAM

commit dc74e4f790a30fed364b06e37978384bc5708149
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 17 16:16:51 2008 +1000

    radeon: use get/set master ioctls

commit 57af898aece299faf54bb36de26b5b9df7a23570
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Nov 14 15:56:16 2008 +1000

    radeon: make space accounting a lot smarter

commit 45ecaf81e28f47c3e49fbdaf94a205b827f7de8a
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Nov 14 15:55:12 2008 +1000

    radeon: retry on CS2 EAGAIN

commit d494dcfeff48b2ede9c0149b7b329cc764c16946
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Nov 14 15:20:59 2008 +1000

    radeon: add src/mask/dest to fallbacks

commit 3e94797cd315f138473a8e259c852ead40ab2826
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Nov 14 15:20:37 2008 +1000

    radeon_memory: align all allocations

commit 99f552fbb084b39df01495917c8799fd960238ff
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Nov 14 11:03:34 2008 +1000

    radeon: force gtt for mmap after fallbacks

commit 6b3c66d4ce4e8e63927dd3a0ce3b483241ec491b
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 10 14:18:17 2008 +1000

    radeon: add more buffer info + fix read objects too big fallback

commit e33b4410b0913ed9b614b54ccb884c00c2370615
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 10 11:47:02 2008 +1000

    radeon: remove old exa bufmgr not used anymore code

commit e8fad094a7d481cdfc712d55a31f8d8dbaf0b930
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 10 11:18:27 2008 +1000

    radeon: fix crtc dpms
    
    need to find a better way to switch displays off

commit 877935b871232545e84e32fc9d02fcff72552295
Author: Dave Airlie <airlied@redhat.com>
Date:   Sat Nov 8 14:48:29 2008 +1000

    radeon: add DPMS support for connectors

commit 6093bcb92e2b2439827300493f7179f8c1ce573f
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Nov 7 16:20:09 2008 +1000

    radeon: fix rotation of right-of heads

commit 5408002d2647353f9a8efe7f80371813810e1cc0
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 3 14:51:43 2008 +1000

    radeon: respect fb tex percent + trust kernel values

commit 939f818aa364c381ff50f7d46094986fc606ce58
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Oct 31 15:05:14 2008 +1000

    radeon: remove workaround hack since kernel is hopefully fixed

commit 492f3bb44de6676d68afbaca2f352ba4e22c0925
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Oct 31 15:04:31 2008 +1000

    radeon: workaround use after free

commit 10188b4331bbe466e4bce9ece9e512f4872a4331
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Oct 30 13:53:02 2008 +1000

    radeon: setup accel dfs for PCIE cards only if drm_mm

commit fda1c3d0db74e7dac72d73fce481baae365aeec5
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Oct 30 10:00:10 2008 +1000

    radeon: fixup name handling for bufmgr

commit 10cf6444c73542a28255072bea0a090197ef3493
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Oct 30 09:59:11 2008 +1000

    radeon: fix memory leak in CS2 code

commit d8589d2a8a5aa96e8799b0baa176804f60491f0c
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Oct 28 20:35:19 2008 +1000

    return on empty IBs, flush happen in the kernel

commit 6feee544fb530b78c255357268bb0e9aa34e5430
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Oct 28 10:16:09 2008 +1000

    radeon: remove some debugging

commit 98a17f1cc7326e35c17712ed318e79d7816eb817
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Oct 28 06:40:31 2008 +1000

    radeon: enable gem wait rendering.

commit 9f884ba97fe517b52148198df4ed0aceaabe4618
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Oct 27 16:51:00 2008 +1000

    radeon: add new CS submission scheme

commit bbbc0e7e21668684cb60649d0ebf0be36d94b5e4
Author: Dave Airlie <airlied@dhcp-1-203.bne.redhat.com>
Date:   Thu Oct 23 17:05:12 2008 +1000

    radeon: really rough effort at vram limit setting

commit 619eca79f15c36e1e50ca8d2e28a451327810216
Author: Dave Airlie <airlied@dhcp-1-203.bne.redhat.com>
Date:   Thu Oct 23 17:04:51 2008 +1000

    radeon: this shouldn't fail but it did once while debugging so patch up

commit 6bb16c3a3bcba75557fa45567d28d5dda5463875
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Oct 23 10:43:09 2008 +1000

    radeon: fixup some memory allocation issues
    
    hopefully since the alignment got fixed this doesn't break anything

commit 790e378c46b133e9a30d12e5b036ff9d1ec97181
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Oct 21 15:50:17 2008 +1000

    radeon: cleanup reserved space calcs

commit 5d0cdb6321c301ab94e9b9c49912562299efe9f3
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Oct 21 15:49:48 2008 +1000

    radeon: fixup Owen's optimisation - this fixes corruption
    
    I haven't a good explaination why mapping the buffer twice in a row
    seems to cause this failure. but I probably don't have time to track
    it down before release.

commit 79134741c9bd31d19d1ca887464a41625a4b9256
Author: Dave Airlie <airlied@redhat.com>
Date:   Sun Oct 19 18:27:53 2008 +1000

    radeon: fixup tex offset for no modeset

commit bc7abf58eb5f9497f70c337709631d4f991552e0
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Oct 15 17:01:34 2008 +1000

    radeon: add DFS support for CS

commit 977018370d2626aca452894b7d0cf7cc9b773d77
Author: airlied <airlied@unused-12-220.bne.redhat.com>
Date:   Wed Oct 15 23:55:13 2008 +1000

    radeon: add r100/r200 support for EXA render

commit 82c18e976f825c93aaec2208feb92877db13084b
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Oct 13 16:59:02 2008 +1000

    radeon: fix switch mode path so nexuiz starts

commit 7e2f98ba5bf205e395518a6a283095918620f099
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Oct 10 15:29:24 2008 +1000

    remove gem buf caching useless on radeon

commit 1dda85f41012139539b135af0c7280e703aa025c
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Oct 10 15:18:41 2008 +1000

    radeon: drmmode make names same as for non-kms drivers

commit a26a20f9a0ad340f3032c8420249c36b02de4fc4
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Oct 10 15:10:28 2008 +1000

    radeon: fix rotation under kms

commit 34a711886a77724f49cd3b8793922dc1b60d41ae
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Oct 10 14:44:39 2008 +1000

    radeon: remove testing fallback

commit 14e85e9202c0ea048877cd317db762e60a9586a3
Author: Kristian Høgsberg <krh@redhat.com>
Date:   Fri Oct 10 10:57:47 2008 +1100

    radeon: add copy fb contents patch

commit 08ee251f5ef124562eb496c966e5c5ab24de079c
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Oct 10 10:57:20 2008 +1100

    bufmgr: turn off debug

commit 19ecc7092fa7830ef19e3664c363d312a8112175
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Oct 10 10:38:38 2008 +1100

    radeon: fixup modesetting code after rebasing to master

commit 42ab306a892601460d69dd3a15ac459c902bfea3
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Oct 9 16:34:52 2008 +1100

    radeon: misc cleanups in exa

commit 4d7a61c0567d7d71c4df29d21e4e8731caa5af0c
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Oct 9 16:34:23 2008 +1100

    radeon: fix UTS for non-modesetting

commit d15a38541dfc34dd5156a727706eeef015346de2
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Oct 9 16:33:59 2008 +1100

    radeon: fix exa limits problem - shouldn't have been resetting scissor

commit c1ae7fbc398dd01c03621b7bf9b13df1c0da680e
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Oct 1 11:21:53 2008 +1000

    radeon: fixup for latest libdrm changes

commit 35b8f71d6181c2207ab523b78224c6c9b9a950b6
Author: Owen Taylor <otaylor@localhost.localdomain>
Date:   Fri Sep 26 16:17:49 2008 -0400

    Don't flush when mapping a newly created pixmap into system ram If we have a pixmap that has never been mapped into vram (and thus never written to by the GPU), there is no need to flush the graphics pipeline and wait for idle before starting to write to it.

commit c8750ddbe1c91fcfb1b2aefcb75f0d5f86fee8a1
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Sep 29 16:32:51 2008 +1000

    radeon: hopefully fix textured xv

commit 8a5a10bdd9e4f83047cc87353fa313f1299a601f
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Sep 26 11:38:36 2008 +1000

    radeon: fix the offset checks for command submission
    
    since we are relocating in the kernel we don't need these

commit 5636af08d3aa2294e25b574738d89859ad7e5d58
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Sep 26 10:46:20 2008 +1000

    radeon: fixup after mertge

commit 3785954990de17d4d1fd4972ea2f52a08df67c3f
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Sep 26 10:34:41 2008 +1000

    radeon: fix issues with emitting DST PIPE on cards that don't use it

commit 930633213ec71f48e30142185815df11ff945dba
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Sep 24 17:12:19 2008 +1000

    modesetting: fixup bits of drmmode_display.c

commit 442c52e9cc396a0c2c97f96e37fa97621d6ef81d
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Sep 24 15:42:01 2008 +1000

    r600: fixup for kms

commit e4e80616398db33614e38d58d47c8a5a8adaddce
Author: Dave Airlie <airlied@redhat.com>
Date:   Sun Sep 7 08:01:56 2008 +1000

    modeset: fix AddFB for current tree

commit f7cac11fc7f2b91d39f58dd0d03c7b7c8bf46450
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Aug 14 10:52:52 2008 +1000

    radeon: disable overlay for modesetting for now

commit 8ab5cc31e41a5d181f6c47b88c6f64764d44a346
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Aug 14 10:52:42 2008 +1000

    radeon: no need for this anymore

commit 35d4ee0ab5c3d6e3a76bde048a385b22da5996f0
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Sep 5 16:32:01 2008 +1000

    radeon: fix up for suspend/resume - uses new API

commit aaa954b49c92dafb4c24df67477d54f7b982c79b
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Aug 27 13:09:55 2008 +1000

    radeon: update to proper domain
    
    this should fix 3d again for now at least

commit da197aabd20d47dedabe18734da8c487f4875c8d
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Aug 26 18:29:23 2008 +1000

    ddx: move to using new gem interface
    
    add a GEM bufmgr backend along the lines of Intels one.
    
    The buffer reuse is disabled and I'll probably rip it out for radeon
    as we can't just re-use buffers that might have ended up in VRAM etc.
    
    Probably need some sort of in-kernel re-use.

commit 4e5fc75c73c388a0840720ce0fc27db3a19c86cf
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Aug 25 11:37:48 2008 +1000

    radeon: add an initial GEM bufmgr

commit 90a4d7d67767f2dfef516868d28b533b37e9bb93
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Aug 25 11:37:20 2008 +1000

    radeon: implement simple UTS

commit 6042177580839fdb7578200ba3ed39ec55312203
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Aug 22 15:34:58 2008 +1000

    radeon: add read/write domains properly

commit a7bb412bdca1bc915794ddae7276ebb59be6b4f7
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Aug 15 11:25:31 2008 +1000

    radeon: fix some rotate bugs

commit 05ec9ff3b85e3f526e2f803600ffb8db707aaf6c
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Aug 15 11:16:18 2008 +1000

    radeon: when create fake bos, they are already mapped

commit dfca01f53644333444c9364716e1024fc0ed3a3a
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Aug 15 11:15:58 2008 +1000

    exa: remove wrong assert

commit ad3cfb887815361be0ee61e1e8559781c8ebf026
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Aug 12 19:27:44 2008 +1000

    radeon: start to work on rotate pixmap support

commit dfeeb56293d4480e9b875334a7a8509f173e95cc
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Aug 12 18:28:23 2008 +1000

    radeon: port simple exa bufmgr
    
    exa pixmaps work now but they are slow

commit c612788007beaa5f09602c87f1b2f3bd517551be
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Aug 7 17:52:04 2008 +1000

    further pixmaps on EXA

commit 3ca79597ec6357571b01c143f75054624952c107
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Aug 7 11:22:46 2008 +1000

    initial exa on gem hackx
    
    Conflicts:
    
    	src/radeon_exa.c
    	src/radeon_memory.c

commit fb6f4e2dbf6a3c96493f1c85d0383954549b5ab6
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Aug 12 15:31:03 2008 +1000

    radeon: initial rotate pixmap
    
    This doesn't work, we really need EXA pixmaps for this stuff

commit 9de349249ff9f175e703b3d975e5f6a9fa332d40
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Aug 12 14:40:18 2008 +1000

    radeon: use buffer names

commit 18a3c5cc114b9af53c5d15301787dd67738e97b8
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Aug 12 14:38:56 2008 +1000

    ati: fix do adjust mode

commit 96f754c15ce3ac2c8477a1e46f7e013a67c68bb3
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Aug 12 09:38:48 2008 +1000

    FEDORA: update offsets in DRI private

commit 6636f4511635df967ad83c91ed5c5584b4fd70e0
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Aug 12 09:10:18 2008 +1000

    radeon: add vt bind flag

commit 97e41f34e01fa38f98d5a1b85a03e4fe61c341b2
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Aug 6 13:30:54 2008 +1000

    radeon: warning cleanups

commit 349c56d5229927317c4c533247bb13b22ef876f9
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Aug 6 13:18:52 2008 +1000

    radeon: remove debugging

commit 26705852d8be63f6d9f237b4023487089392c4ae
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Aug 6 13:17:31 2008 +1000

    radeon: add code to set memory map and not futz with mappings

commit c5a452276fc86beabc81d64d3da04afbe3e6b370
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Aug 6 13:16:56 2008 +1000

    drm: don't futz with framebuffer when no drm_mm

commit 558864d7647f69f610f6815368c7b8c23bf1808e
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Aug 5 16:47:21 2008 +1000

    radeon: undef OUT_RELOC

commit 1a67c636f39c62e7438958d07aa9e13893d529e4
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Aug 5 16:37:52 2008 +1000

    radeon: add stdint/lib to check for modesetting

commit cc426003d5ebf1ef6c3bf439ae00bcd0c8d08788
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Aug 5 16:07:31 2008 +1000

    fix whitespace

commit 9c1cb1d7a83a4fea9796acdceb792a7e0821554c
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Aug 5 16:07:07 2008 +1000

    radeon: fix build issue

commit fb90c1c7c2d9bb7c374080362a66947e0893751b
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Aug 4 16:27:55 2008 +1000

    radeon: free all pinned memory on server shutdown

commit bf5dbb81ba35ecbd1a215910404bd91dcc389e32
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Aug 4 16:11:30 2008 +1000

    radeon: get textured video working on the memory manager

commit 562c15131f0b47af3e60649e7bb0f63d0f8ce905
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Aug 4 16:11:18 2008 +1000

    radeon: convert bus addr to void pointer

commit dd5a36b4116f83ae1f406693b55ebacc90a96ba7
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Aug 4 15:11:13 2008 +1000

    radeon: avoid z cache flushes if not needed

commit 203cb77f84e2b6f449789adbc64609ec739522cf
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Jul 30 17:04:22 2008 +1000

    radeon: update DRI support, so mappings get added
    
    We only add fake frontbuffer mapping as DRI clients expect one.

commit d09e37bed190f3e4cf3c5fe415082b5af627ee73
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Jul 29 16:50:03 2008 +1000

    radeon: exa through the handle relocation function

commit 348cb50fb0ff61c42a55f1adaeb7e6521931a5b6
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Jul 29 14:58:22 2008 +1000

    radeon: keep track of 2D state
    
    This lets the kernel use the 2D blit engine in theory

commit 4ffb66c161f17b4a275a99e46dda6e9904ba0293
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Jul 28 17:48:59 2008 +1000

    new command submission attempt

commit 2db6760e425efedad537f33276553efa693b5f93
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Jul 28 17:48:08 2008 +1000

    radeon: fixup over fluishing problem

commit 34e98ac507605fee60f9811c25cd4eed531f3d8c
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Jul 28 17:44:51 2008 +1000

    hack for now: divide texture size by 2

commit 347cf1dfa7ce4f98e25af3d83b865208186cd41e
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Jul 25 17:07:20 2008 +1000

    radeon: fix dri message

commit 03e469920c0908e62c5fa76f892d6fc969026492
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Jul 25 15:11:58 2008 +1000

    radeon: fix pool which caused memory corruption

commit 4a214f115890170ffbd8c710067e165d4106cb5c
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Jul 25 14:59:07 2008 +1000

    radeon: get DRI to attempt to start up

commit f06e03e4b909b4a7a68365330b6b19937abe1506
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Jul 25 14:58:23 2008 +1000

    radeon: call the right sync function

commit b08f5b921676570a357cdbf2c9411b6b56fd564f
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Jul 25 14:57:21 2008 +1000

    radeon: unmap memory from objects

commit 869ce0cd2d28673eb30c92c8b79ada5870ff4c4f
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Jul 23 10:59:16 2008 +1000

    use CP for 3D engine with modeset

commit 7dedbf4a3abdba120cff59785e232d28ff324887
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Jul 23 10:59:04 2008 +1000

    radeon: fix DFS

commit 66581330987a8a6fa50df6be4edb41efdb998bd9
Author: Dave Airlie <airlied@redhat.com>
Date:   Wed Jul 23 10:48:45 2008 +1000

    radeon: get the fb location right

commit 3438a51e0d87a25dd1f747212ac9612149f49d3f
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Jul 22 18:08:25 2008 +1000

    radeon: make at least the EXA stipple work..

commit fce2c06070101243f8228574907f9f67826633d7
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Jul 22 18:07:15 2008 +1000

    radeon: disable debugging for now

commit 3d779c1a27ae4691a13ee8da83f6f06922afb83a
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Jul 21 18:40:14 2008 +1000

    radeon: initial indirect buffer use.
    
    Move EXA and front allocation into one big buffer to workaround
    EXA issues - need to move to driver pixmap hooks.
    
    Add new indirect GEM to take indirect buffers.
    
    doesn't work think the offsets are all wrong.

commit 181dec8fe5651fd7feb4efa1674fa0ef3685a7b4
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Jul 18 13:46:41 2008 +1000

    modesetting step 1: have X and a cursor

commit 8b5a5b041bc58c085d45aecedda4df11c94716f5
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Jul 17 09:59:19 2008 +1000

    radeon: add radeon_memory.c

commit 415ef83b9c2954fe7110e9dc6e2b2d6b4ce52bfb
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Jul 8 16:55:27 2008 +1000

    remove mappings of some buffers.
    
    use drm gart code if available

commit dff36e2075f948d9002b882aa6c9e3098a3481c9
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Jul 7 16:54:35 2008 +1000

    add initial support for a kernel memory manager
    
    This just pins all the current allocations via the kernel memory manager
    instead of trying to do them all in userspace.
    
    useful steps towards getting kernel modesetting

commit c12eccd5889541e9aa1a700f97c1de38920794c8
Author: Dave Airlie <airlied@redhat.com>
Date:   Fri Jul 4 10:39:34 2008 +1000

    port to using drm header files
diff --git a/configure.ac b/configure.ac
index b094a50..29a19e3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -114,8 +114,19 @@ if test "$DRI" = yes; then
 	if test "$have_damage_h" = yes; then
 		AC_DEFINE(DAMAGE,1,[Use Damage extension])
 	fi
+
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$XORG_CFLAGS $DRI_CFLAGS"
+        AC_CHECK_HEADER(xf86drmMode.h,[DRM_MODE=yes],[DRM_MODE=no],[#include <stdint.h>
+#include <stdlib.h>])
+        if test "x$DRM_MODE" = xyes; then
+                AC_DEFINE(XF86DRM_MODE,1,[DRM kernel modesetting])
+        fi
+	CFLAGS="$save_CFLAGS"
 fi
 
+AC_DEFINE(DRI2, 1,[Enable DRI2 code])
+
 save_CFLAGS="$CFLAGS"
 CFLAGS="$XORG_CFLAGS"
 AC_CHECK_HEADER(xf86Modes.h,[XMODES=yes],[XMODES=no],[#include "xorg-server.h"])
diff --git a/src/Makefile.am b/src/Makefile.am
index 7cc2a6f..8a55d1c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -90,12 +90,14 @@ radeon_drv_ladir = @moduledir@/drivers
 radeon_drv_la_SOURCES = \
 	radeon_accel.c radeon_cursor.c radeon_dga.c radeon_legacy_memory.c \
 	radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
-	radeon_vip.c radeon_misc.c radeon_probe.c \
+	radeon_vip.c radeon_misc.c radeon_probe.c radeon_memory.c \
 	legacy_crtc.c legacy_output.c \
 	radeon_textured_video.c \
 	radeon_crtc.c radeon_output.c radeon_modes.c radeon_tv.c \
 	$(RADEON_ATOMBIOS_SOURCES) radeon_atombios.c radeon_atomwrapper.c \
-	$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES) atombios_output.c atombios_crtc.c
+	$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES) atombios_output.c \
+	atombios_crtc.c  drmmode_display.c radeon_bufmgr_gem.c \
+	radeon_dri_bufmgr.c radeon_dri2.c
 
 if XMODES
 radeon_drv_la_SOURCES += \
@@ -144,6 +146,7 @@ EXTRA_DIST = \
 	radeon_exa_render.c \
 	radeon_exa_funcs.c \
 	radeon.h \
+	radeon_dri2.h \
 	radeon_macros.h \
 	radeon_probe.h \
 	radeon_reg.h \
@@ -164,4 +167,6 @@ EXTRA_DIST = \
 	radeon_pci_device_match_gen.h \
 	pcidb/ati_pciids.csv \
 	pcidb/parse_pci_ids.pl \
-	radeon_atombios.h
+	radeon_atombios.h \
+	drmmode_display.h \
+	radeon_dri_bufmgr.h
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
new file mode 100644
index 0000000..84f5f0a
--- /dev/null
+++ b/src/drmmode_display.c
@@ -0,0 +1,905 @@
+/*
+ * Copyright Š 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Dave Airlie <airlied@redhat.com>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef XF86DRM_MODE
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_drm.h"
+#include "sarea.h"
+
+/* DPMS */
+#define DPMS_SERVER
+#include <X11/extensions/dpms.h>
+
+static void
+drmmode_ConvertFromKMode(ScrnInfoPtr	scrn,
+		     struct drm_mode_modeinfo *kmode,
+		     DisplayModePtr	mode)
+{
+	memset(mode, 0, sizeof(DisplayModeRec));
+	mode->status = MODE_OK;
+	
+	mode->Clock = kmode->clock;
+	
+	mode->HDisplay = kmode->hdisplay;
+	mode->HSyncStart = kmode->hsync_start;
+	mode->HSyncEnd = kmode->hsync_end;
+	mode->HTotal = kmode->htotal;
+	mode->HSkew = kmode->hskew;
+    
+	mode->VDisplay = kmode->vdisplay;
+	mode->VSyncStart = kmode->vsync_start;
+	mode->VSyncEnd = kmode->vsync_end;
+	mode->VTotal = kmode->vtotal;
+	mode->VScan = kmode->vscan;
+
+	mode->Flags = kmode->flags; //& FLAG_BITS;
+	mode->name = strdup(kmode->name);
+
+	if (kmode->type & DRM_MODE_TYPE_DRIVER)
+		mode->type = M_T_DRIVER;
+	if (kmode->type & DRM_MODE_TYPE_PREFERRED)
+		mode->type |= M_T_PREFERRED;
+	xf86SetModeCrtc (mode, scrn->adjustFlags);
+}
+
+static void
+drmmode_ConvertToKMode(ScrnInfoPtr	scrn,
+		     struct drm_mode_modeinfo *kmode,
+		     DisplayModePtr	mode)
+{
+	memset(kmode, 0, sizeof(*kmode));
+
+	kmode->clock = mode->Clock;
+	kmode->hdisplay = mode->HDisplay;
+	kmode->hsync_start = mode->HSyncStart;
+	kmode->hsync_end = mode->HSyncEnd;
+	kmode->htotal = mode->HTotal;
+	kmode->hskew = mode->HSkew;
+    
+	kmode->vdisplay = mode->VDisplay;
+	kmode->vsync_start = mode->VSyncStart;
+	kmode->vsync_end = mode->VSyncEnd;
+	kmode->vtotal = mode->VTotal;
+	kmode->vscan = mode->VScan;
+
+	kmode->flags = mode->Flags; //& FLAG_BITS;
+	if (mode->name)
+		strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN);
+	kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
+
+}
+
+static void
+drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
+{
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+	/* bonghits in the randr 1.2 - uses dpms to disable crtc - bad buzz */
+	if (mode == DPMSModeOff) {
+//		drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+//			       0, 0, 0, NULL, 0, NULL);
+	}
+}
+
+static PixmapPtr
+create_pixmap_for_fb(drmmode_ptr drmmode, ScrnInfoPtr pScrn, drmModeFBPtr fb)
+{
+	ScreenPtr pScreen = pScrn->pScreen;
+	PixmapPtr pPixmap;
+	struct radeon_exa_pixmap_priv *driver_priv;
+	dri_bo *bo;
+
+	pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, fb->depth, 0);
+	driver_priv = exaGetPixmapDriverPrivate(pPixmap);
+	if (!driver_priv) {
+		(*pScreen->DestroyPixmap)(pPixmap);
+		return NULL;
+	}
+
+	miModifyPixmapHeader(pPixmap, fb->width, fb->height, fb->depth,
+                             pScrn->bitsPerPixel, fb->pitch, NULL);
+
+	bo = radeon_bo_gem_create_from_handle(drmmode->bufmgr,
+					      fb->handle,
+					      fb->pitch * fb->height);
+	driver_priv->bo = bo;
+	if (bo == NULL) {
+		(*pScreen->DestroyPixmap)(pPixmap);
+		return NULL;
+	}
+
+    	return pPixmap;
+}
+
+static void
+copy_fb_contents (drmmode_ptr drmmode,
+		  ScrnInfoPtr pScrn,
+		  unsigned int dest_id, int x, int y, unsigned int src_id)
+{
+	RADEONInfoPtr info = RADEONPTR(pScrn);
+	drmModeFBPtr dest_fb, src_fb;
+	dri_bo *dest_bo, *src_bo;
+	PixmapPtr src_pixmap, dest_pixmap;
+	ScreenPtr pScreen = pScrn->pScreen;
+
+	dest_fb = drmModeGetFB(drmmode->fd, dest_id);
+	src_fb = drmModeGetFB(drmmode->fd, src_id);
+	if (src_fb == NULL || dest_fb == NULL) {
+		ErrorF("failed to get old fb, id %d\n", src_id);
+		return;
+	}
+
+	dest_pixmap = create_pixmap_for_fb(drmmode, pScrn, dest_fb);
+	src_pixmap = create_pixmap_for_fb(drmmode, pScrn, src_fb);
+
+	info->accel_state->exa->PrepareCopy (src_pixmap, dest_pixmap,
+					     0, 0, GXcopy, 0xffffff);
+	info->accel_state->exa->Copy (dest_pixmap, 0, 0, x, y,
+			 	      src_fb->width, src_fb->height);
+	info->accel_state->exa->DoneCopy (dest_pixmap);
+	RADEONCPFlushIndirect(pScrn, 0);
+
+	(*pScreen->DestroyPixmap)(dest_pixmap);
+	(*pScreen->DestroyPixmap)(src_pixmap);
+
+	drmFree(dest_fb);
+	drmFree(src_fb);
+}
+
+static Bool
+drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
+		     Rotation rotation, int x, int y)
+{
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	int saved_x, saved_y;
+	Rotation saved_rotation;
+	DisplayModeRec saved_mode;
+	uint32_t *output_ids;
+	int output_count = 0;
+	Bool ret = TRUE;
+	int i;
+	int fb_id;
+	struct drm_mode_modeinfo kmode;
+
+	saved_mode = crtc->mode;
+	saved_x = crtc->x;
+	saved_y = crtc->y;
+	saved_rotation = crtc->rotation;
+
+	if (mode) {
+		crtc->mode = *mode;
+		crtc->x = x;
+		crtc->y = y;
+		crtc->rotation = rotation;
+	}
+
+	output_ids = xcalloc(sizeof(uint32_t), xf86_config->num_output);
+	if (!output_ids) {
+		ret = FALSE;
+		goto done;
+	}
+
+	if (mode) {
+		for (i = 0; i < xf86_config->num_output; i++) {
+			xf86OutputPtr output = xf86_config->output[i];
+			drmmode_output_private_ptr drmmode_output;
+
+			if (output->crtc != crtc)
+				continue;
+
+			drmmode_output = output->driver_private;
+			output_ids[output_count] = drmmode_output->mode_output->connector_id;
+			output_count++;
+		}
+
+		if (!xf86CrtcRotate(crtc)) {
+			goto done;
+		}
+
+		drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
+	
+		fb_id = drmmode->fb_id;
+		if (drmmode_crtc->rotate_fb_id) {
+			fb_id = drmmode_crtc->rotate_fb_id;
+			x = y = 0;
+		}
+		else if (fb_id != drmmode_crtc->mode_crtc->buffer_id)
+			copy_fb_contents (drmmode, crtc->scrn, fb_id, x, y,
+					  drmmode_crtc->mode_crtc->buffer_id);
+
+		drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+			       fb_id, x, y, output_ids, output_count, &kmode);
+
+		if (crtc->scrn->pScreen)
+			xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen);
+	}
+		
+
+
+
+done:
+	if (!ret) {
+		crtc->x = saved_x;
+		crtc->y = saved_y;
+		crtc->rotation = saved_rotation;
+		crtc->mode = saved_mode;
+	}
+	return ret;
+}
+
+static void
+drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
+{
+  
+}
+
+static void
+drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+	drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y);
+}
+
+static void
+drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	void *ptr;
+
+	/* cursor should be mapped already */
+	ptr = drmmode_crtc->cursor_map;
+
+	memcpy (ptr, image, 64 * 64 * 4);
+
+	return;
+}
+
+
+static void
+drmmode_hide_cursor (xf86CrtcPtr crtc)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	
+	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 64, 64);
+
+}
+
+static void
+drmmode_show_cursor (xf86CrtcPtr crtc)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+	drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, drmmode_crtc->cursor_handle, 64, 64);
+}
+
+static void *
+drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	int size;
+	unsigned long rotate_pitch;
+	dri_bo *rotate_bo;
+	int ret;
+	rotate_pitch = crtc->scrn->displayWidth * drmmode->cpp;
+	size = rotate_pitch * height;
+
+	rotate_bo = dri_bo_alloc(drmmode->bufmgr, "rotate", size, 0, 0);
+	if (rotate_bo == NULL)
+		return NULL;
+
+	dri_bo_pin(rotate_bo, RADEON_GEM_DOMAIN_VRAM);
+	dri_bo_map(rotate_bo, 1);
+
+	ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth,
+			   crtc->scrn->bitsPerPixel, rotate_pitch, dri_bo_get_handle(rotate_bo),
+			   &drmmode_crtc->rotate_fb_id);
+	if (ret) {
+		ErrorF("failed to add rotate fb\n");
+	}
+
+	drmmode_crtc->rotate_bo = rotate_bo;
+	return drmmode_crtc->rotate_bo->virtual;
+}
+
+static PixmapPtr
+drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
+{
+	ScrnInfoPtr pScrn = crtc->scrn;
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	unsigned long rotate_pitch;
+	PixmapPtr rotate_pixmap;
+	
+	if (!data)
+		data = drmmode_crtc_shadow_allocate (crtc, width, height);
+
+	rotate_pitch = pScrn->displayWidth * drmmode->cpp;
+	
+	rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen,
+					       width, height,
+					       pScrn->depth,
+					       pScrn->bitsPerPixel,
+					       rotate_pitch,
+					       data);
+	
+	if (rotate_pixmap == NULL) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "Couldn't allocate shadow pixmap for rotated CRTC\n");
+	}
+	return rotate_pixmap;
+
+}
+
+static void
+drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+	if (rotate_pixmap)
+	    FreeScratchPixmapHeader(rotate_pixmap);
+	
+	if (data) {
+		drmModeRmFB(drmmode->fd, drmmode_crtc->rotate_fb_id);
+		drmmode_crtc->rotate_fb_id = 0;
+		dri_bo_unreference(drmmode_crtc->rotate_bo);
+		drmmode_crtc->rotate_bo = NULL;
+	}
+
+}
+
+static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
+    .dpms = drmmode_crtc_dpms,
+    .set_mode_major = drmmode_set_mode_major,
+    .set_cursor_colors = drmmode_set_cursor_colors,
+    .set_cursor_position = drmmode_set_cursor_position,
+    .show_cursor = drmmode_show_cursor,
+    .hide_cursor = drmmode_hide_cursor,
+    .load_cursor_argb = drmmode_load_cursor_argb,
+
+    .shadow_create = drmmode_crtc_shadow_create,
+    .shadow_allocate = drmmode_crtc_shadow_allocate,
+    .shadow_destroy = drmmode_crtc_shadow_destroy,
+#if 0
+    .gamma_set = i830_crtc_gamma_set,
+#endif
+    .destroy = NULL, /* XXX */
+};
+
+
+static void
+drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
+{
+	xf86CrtcPtr crtc;
+	drmmode_crtc_private_ptr drmmode_crtc;
+
+	crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs);
+	if (crtc == NULL)
+		return;
+
+	drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
+	drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]);
+	drmmode_crtc->drmmode = drmmode;
+	crtc->driver_private = drmmode_crtc;
+
+	return;
+}
+
+static xf86OutputStatus
+drmmode_output_detect(xf86OutputPtr output)
+{
+	/* go to the hw and retrieve a new output struct */
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+	drmmode_ptr drmmode = drmmode_output->drmmode;
+	xf86OutputStatus status;
+	drmModeFreeConnector(drmmode_output->mode_output);
+	
+	drmmode_output->mode_output = drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
+	
+	switch (drmmode_output->mode_output->connection) {
+	case DRM_MODE_CONNECTED:
+		status = XF86OutputStatusConnected;
+		break;
+	case DRM_MODE_DISCONNECTED:
+		status = XF86OutputStatusDisconnected;
+		break;
+	default:
+	case DRM_MODE_UNKNOWNCONNECTION:
+		status = XF86OutputStatusUnknown;
+		break;
+	}
+	return status;
+}
+
+static Bool
+drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
+{
+	return MODE_OK;
+}
+
+static DisplayModePtr
+drmmode_output_get_modes(xf86OutputPtr output)
+{
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+	drmModeConnectorPtr koutput = drmmode_output->mode_output;
+	drmmode_ptr drmmode = drmmode_output->drmmode;
+	int i;
+	DisplayModePtr Modes = NULL, Mode;
+	drmModePropertyPtr props;
+
+	/* look for an EDID property */
+	for (i = 0; i < koutput->count_props; i++) {
+		props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
+		if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
+			if (!strcmp(props->name, "EDID")) {
+				if (drmmode_output->edid_blob)
+					drmModeFreePropertyBlob(drmmode_output->edid_blob);
+				drmmode_output->edid_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
+			}
+			drmModeFreeProperty(props);
+		}
+	}
+
+	if (drmmode_output->edid_blob)
+		xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, drmmode_output->edid_blob->data));
+	else
+		xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, NULL));
+
+	/* modes should already be available */
+	for (i = 0; i < koutput->count_modes; i++) {
+		Mode = xnfalloc(sizeof(DisplayModeRec));
+
+		drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode);
+		Modes = xf86ModesAdd(Modes, Mode);
+
+	}
+	return Modes;
+}
+
+static void
+drmmode_output_destroy(xf86OutputPtr output)
+{
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+
+	if (drmmode_output->edid_blob)
+		drmModeFreePropertyBlob(drmmode_output->edid_blob);
+	drmModeFreeConnector(drmmode_output->mode_output);
+	xfree(drmmode_output);
+	output->driver_private = NULL;
+}
+
+static void
+drmmode_output_dpms(xf86OutputPtr output, int mode)
+{
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+	drmModeConnectorPtr koutput = drmmode_output->mode_output;
+	drmmode_ptr drmmode = drmmode_output->drmmode;
+
+	drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id,
+				    drmmode_output->dpms_enum_id, mode);
+	return;
+}
+
+static const xf86OutputFuncsRec drmmode_output_funcs = {
+    .dpms = drmmode_output_dpms,
+#if 0
+
+    .save = drmmode_crt_save,
+    .restore = drmmode_crt_restore,
+    .mode_fixup = drmmode_crt_mode_fixup,
+    .prepare = drmmode_output_prepare,
+    .mode_set = drmmode_crt_mode_set,
+    .commit = drmmode_output_commit,
+#endif
+    .detect = drmmode_output_detect,
+    .mode_valid = drmmode_output_mode_valid,
+
+    .get_modes = drmmode_output_get_modes,
+    .destroy = drmmode_output_destroy
+};
+
+static int subpixel_conv_table[7] = { 0, SubPixelUnknown,
+				      SubPixelHorizontalRGB,
+				      SubPixelHorizontalBGR,
+				      SubPixelVerticalRGB,
+				      SubPixelVerticalBGR,
+				      SubPixelNone };
+
+const char *output_names[] = { "None",
+			       "VGA",
+			       "DVI",
+			       "DVI",
+			       "DVI",
+			       "Composite",
+			       "TV",
+			       "LVDS",
+			       "CTV",
+			       "DIN",
+			       "DP",
+			       "HDMI",
+			       "HDMI",
+};
+   
+
+static void
+drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
+{
+	xf86OutputPtr output;
+	drmModeConnectorPtr koutput;
+	drmModeEncoderPtr kencoder;
+	drmmode_output_private_ptr drmmode_output;
+	drmModePropertyPtr props;
+	char name[32];
+	int i;
+
+	koutput = drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]);
+	if (!koutput)
+		return;
+
+	kencoder = drmModeGetEncoder(drmmode->fd, koutput->encoders[0]);
+	if (!kencoder) {
+		drmModeFreeConnector(koutput);
+		return;
+	}
+
+	/* need to do smart conversion here for compat with non-kms ATI driver */
+	if (koutput->connector_type_id == 1) {
+	    switch(koutput->connector_type) {
+	    case DRM_MODE_CONNECTOR_VGA:
+	    case DRM_MODE_CONNECTOR_DVII:
+	    case DRM_MODE_CONNECTOR_DVID:
+	    case DRM_MODE_CONNECTOR_DVIA:
+	    case DRM_MODE_CONNECTOR_HDMIA:
+	    case DRM_MODE_CONNECTOR_HDMIB:
+		snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1);
+		break;
+	    default:
+		snprintf(name, 32, "%s", output_names[koutput->connector_type]);
+		break;
+	    }
+	} else {
+	    snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1);
+	}
+		
+	output = xf86OutputCreate (pScrn, &drmmode_output_funcs, name);
+	if (!output) {
+		drmModeFreeEncoder(kencoder);
+		drmModeFreeConnector(koutput);
+		return;
+	}
+
+	drmmode_output = xcalloc(sizeof(drmmode_output_private_rec), 1);
+	if (!drmmode_output) {
+		xf86OutputDestroy(output);
+		drmModeFreeConnector(koutput);
+		drmModeFreeEncoder(kencoder);
+		return;
+	}
+
+	drmmode_output->output_id = drmmode->mode_res->connectors[num];
+	drmmode_output->mode_output = koutput;
+	drmmode_output->mode_encoder = kencoder;
+	drmmode_output->drmmode = drmmode;
+	output->mm_width = koutput->mmWidth;
+	output->mm_height = koutput->mmHeight;
+
+	output->subpixel_order = subpixel_conv_table[koutput->subpixel];
+	output->driver_private = drmmode_output;
+
+	output->possible_crtcs = kencoder->possible_crtcs;
+	output->possible_clones = kencoder->possible_clones;
+
+	for (i = 0; i < koutput->count_props; i++) {
+		props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
+		if (props && (props->flags && DRM_MODE_PROP_ENUM)) {
+			if (!strcmp(props->name, "DPMS")) {
+				drmmode_output->dpms_enum_id = koutput->props[i];
+				drmModeFreeProperty(props);
+				break;
+			}
+			drmModeFreeProperty(props);
+		}
+	}
+
+	return;
+}
+
+static Bool
+drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
+{
+	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+	drmmode_crtc_private_ptr
+		    drmmode_crtc = xf86_config->crtc[0]->driver_private;
+	drmmode_ptr drmmode = drmmode_crtc->drmmode;
+	RADEONInfoPtr info = RADEONPTR(scrn);
+	struct radeon_memory *old_front = NULL;
+	BoxRec	    mem_box;
+	Bool	    tiled, ret;
+	ScreenPtr   screen = screenInfo.screens[scrn->scrnIndex];
+	uint32_t    old_fb_id;
+	int	    i, pitch, old_width, old_height, old_pitch;
+	int screen_size;
+	int cpp = info->CurrentLayout.pixel_bytes;
+	dri_bo *front_bo;
+
+	if (scrn->virtualX == width && scrn->virtualY == height)
+		return TRUE;
+
+	front_bo = radeon_get_pixmap_bo(screen->GetScreenPixmap(screen));
+	RADEONCPFlushIndirect(scrn, 0);
+
+	if (front_bo)
+		radeon_bufmgr_gem_wait_rendering(front_bo);
+	pitch = RADEON_ALIGN(width, 63);
+	height = RADEON_ALIGN(height, 16);
+
+	screen_size = pitch * height * cpp;
+
+	xf86DrvMsg(scrn->scrnIndex, X_INFO,
+		   "Allocate new frame buffer %dx%d stride %d\n",
+		   width, height, pitch);
+
+	old_width = scrn->virtualX;
+	old_height = scrn->virtualY;
+	old_pitch = scrn->displayWidth;
+	old_fb_id = drmmode->fb_id;
+	old_front = info->mm.front_buffer;
+
+	scrn->virtualX = width;
+	scrn->virtualY = height;
+	scrn->displayWidth = pitch;
+	info->mm.front_buffer = radeon_allocate_memory(scrn, RADEON_POOL_VRAM, screen_size, 0, 1, "Front Buffer", 0);
+	if (!info->mm.front_buffer)
+		goto fail;
+
+	ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
+			   scrn->bitsPerPixel, pitch * cpp,
+			   info->mm.front_buffer->kernel_bo_handle,
+			   &drmmode->fb_id);
+	if (ret)
+		goto fail;
+
+	radeon_set_pixmap_bo(screen->GetScreenPixmap(screen), info->mm.front_buffer);
+	screen->ModifyPixmapHeader(screen->GetScreenPixmap(screen),
+				   width, height, -1, -1, pitch * cpp, NULL);
+
+	xf86DrvMsg(scrn->scrnIndex, X_INFO, "New front buffer at 0x%lx\n",
+		   info->mm.front_buffer->offset);
+
+	for (i = 0; i < xf86_config->num_crtc; i++) {
+		xf86CrtcPtr crtc = xf86_config->crtc[i];
+
+		if (!crtc->enabled)
+			continue;
+
+		drmmode_set_mode_major(crtc, &crtc->mode,
+				       crtc->rotation, crtc->x, crtc->y);
+	}
+
+	if (old_fb_id)
+		drmModeRmFB(drmmode->fd, old_fb_id);
+	if (old_front)
+                radeon_free_memory(scrn, old_front);
+
+	return TRUE;
+
+ fail:
+	if (info->mm.front_buffer)
+		radeon_free_memory(scrn, info->mm.front_buffer);
+	info->mm.front_buffer = old_front;
+	scrn->virtualX = old_width;
+	scrn->virtualY = old_height;
+	scrn->displayWidth = old_pitch;
+	drmmode->fb_id = old_fb_id;
+
+	return FALSE;
+}
+
+static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
+	drmmode_xf86crtc_resize
+};
+
+
+Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId, char *driver_name, int cpp)
+{
+	xf86CrtcConfigPtr   xf86_config;
+	int i;
+	Bool ret;
+
+	/* Create a bus Id */
+	/* Low level DRM open */
+	ret = DRIOpenDRMMaster(pScrn, SAREA_MAX, busId, driver_name);
+	if (!ret) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "[dri] DRIGetVersion failed to open the DRM\n"
+			   "[dri] Disabling DRI.\n");
+		return FALSE;
+	}
+
+	drmmode->fd = DRIMasterFD(pScrn);
+
+	xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
+	xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+
+	drmmode->cpp = cpp;
+	drmmode->mode_res = drmModeGetResources(drmmode->fd);
+	if (!drmmode->mode_res)
+		return FALSE;
+
+	xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width, drmmode->mode_res->max_height);
+	for (i = 0; i < drmmode->mode_res->count_crtcs; i++)
+		drmmode_crtc_init(pScrn, drmmode, i);
+
+	for (i = 0; i < drmmode->mode_res->count_connectors; i++)
+		drmmode_output_init(pScrn, drmmode, i);
+
+	xf86InitialConfiguration(pScrn, TRUE);
+
+	return TRUE;
+}
+
+Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, dri_bufmgr *bufmgr)
+{
+	drmmode->bufmgr = bufmgr;
+	return TRUE;
+}
+
+void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height, int pitch, uint32_t handle)
+{
+	int ret;
+
+	ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
+			   scrn->bitsPerPixel, pitch, handle,
+			   &drmmode->fb_id);
+
+	if (ret) {
+		ErrorF("Failed to add fb\n");
+	}
+
+	drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
+	if (!drmmode->mode_fb)
+		return;
+
+
+	ErrorF("Add fb id %d %d %d\n", drmmode->fb_id, width, height);
+}
+
+void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, void *ptr, uint32_t handle)
+{
+  	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+	xf86CrtcPtr crtc = xf86_config->crtc[id];
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	
+
+	drmmode_crtc->cursor_handle = handle;
+	drmmode_crtc->cursor_map = ptr;
+}
+
+Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo)
+{
+	xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR (pScrn);
+	int i;
+
+	if (pPixData == NULL)
+		return FALSE;
+
+	for (i = 0; i < config->num_crtc; i++) {
+		xf86CrtcPtr crtc = config->crtc[i];
+		drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+		if (!drmmode_crtc->rotate_bo)
+			continue;
+
+		if (drmmode_crtc->rotate_bo->virtual == pPixData) {
+			*bo = drmmode_crtc->rotate_bo;
+			return TRUE;
+		}
+	}
+	return FALSE;
+
+}
+
+void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y, int flags)
+{
+	xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+	xf86OutputPtr  output = config->output[config->compat_output];
+	xf86CrtcPtr	crtc = output->crtc;
+
+	if (crtc && crtc->enabled) {
+		drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation,
+				       x, y);
+	}
+}
+
+Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
+{
+	xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
+	int			c, o;
+
+	for (c = 0; c < config->num_crtc; c++) {
+		xf86CrtcPtr	crtc = config->crtc[c];
+		drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+		xf86OutputPtr	output = NULL;
+		int		o;
+		
+		/* Skip disabled CRTCs */
+		if (!crtc->enabled) {
+			drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+				       0, 0, 0, NULL, 0, NULL);
+			continue;
+		}
+
+		if (config->output[config->compat_output]->crtc == crtc)
+			output = config->output[config->compat_output];
+		else
+		{
+			for (o = 0; o < config->num_output; o++)
+				if (config->output[o]->crtc == crtc)
+				{
+					output = config->output[o];
+					break;
+				}
+		}
+		/* paranoia */
+		if (!output)
+			continue;
+
+		/* Mark that we'll need to re-set the mode for sure */
+		memset(&crtc->mode, 0, sizeof(crtc->mode));
+		if (!crtc->desiredMode.CrtcHDisplay)
+		{
+			DisplayModePtr  mode = xf86OutputFindClosestMode (output, pScrn->currentMode);
+			
+			if (!mode)
+				return FALSE;
+			crtc->desiredMode = *mode;
+			crtc->desiredRotation = RR_Rotate_0;
+			crtc->desiredX = 0;
+			crtc->desiredY = 0;
+		}
+
+		if (!crtc->funcs->set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation,
+						 crtc->desiredX, crtc->desiredY))
+			return FALSE;
+	}
+	return TRUE;
+}
+#endif
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
new file mode 100644
index 0000000..5ea904b
--- /dev/null
+++ b/src/drmmode_display.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright Š 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *     Dave Airlie <airlied@redhat.com>
+ *
+ */
+#ifndef DRMMODE_DISPLAY_H
+#define DRMMODE_DISPLAY_H
+
+#ifdef XF86DRM_MODE
+
+#include "xf86drmMode.h"
+
+#include "radeon_probe.h"
+#include "radeon_bufmgr.h"
+
+typedef struct {
+  int fd;
+  int fb_id;
+  drmModeResPtr mode_res;
+  drmModeFBPtr mode_fb;
+  int cpp;
+  dri_bufmgr *bufmgr;
+} drmmode_rec, *drmmode_ptr;
+
+typedef struct {
+
+    drmmode_ptr drmmode;
+    drmModeCrtcPtr mode_crtc;
+    uint32_t cursor_handle;
+    void *cursor_map;
+    dri_bo *rotate_bo;
+    int rotate_fb_id;
+} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
+
+typedef struct {
+    drmmode_ptr drmmode;
+    int output_id;
+    drmModeConnectorPtr mode_output;
+    drmModeEncoderPtr mode_encoder;
+    drmModePropertyBlobPtr edid_blob;
+    int dpms_enum_id;
+} drmmode_output_private_rec, *drmmode_output_private_ptr;
+
+
+extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, char *busId, char *driver_name, int cpp);
+extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, dri_bufmgr *bufmgr);
+extern void drmmode_set_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int width, int height, int pitch, uint32_t handle);
+extern Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo);
+extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, void *ptr, uint32_t handle);
+void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y, int flags);
+extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
+#endif
+#endif
diff --git a/src/radeon.h b/src/radeon.h
index 355a949..21118d7 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -46,6 +46,8 @@
 #include "compiler.h"
 #include "xf86fbman.h"
 
+#include "drmmode_display.h"
+
 				/* PCI support */
 #include "xf86Pci.h"
 
@@ -75,6 +77,7 @@
 #include "dri.h"
 #include "GL/glxint.h"
 #include "xf86drm.h"
+#include "radeon_dri2.h"
 
 #ifdef DAMAGE
 #include "damage.h"
@@ -85,6 +88,7 @@
 #include "xf86Crtc.h"
 #include "X11/Xatom.h"
 
+#include "radeon_bufmgr.h"
 				/* Render support */
 #ifdef RENDER
 #include "picturestr.h"
@@ -412,6 +416,14 @@ typedef enum {
 
 typedef struct _atomBiosHandle *atomBiosHandlePtr;
 
+#define RADEON_POOL_GART 0
+#define RADEON_POOL_VRAM 1
+
+struct radeon_exa_pixmap_priv {
+    dri_bo *bo;
+    int flags;
+};
+    
 typedef struct {
     uint32_t pci_device_id;
     RADEONChipFamily chip_family;
@@ -422,7 +434,27 @@ typedef struct {
     int singledac;
 } RADEONCardInfo;
 
+#define RADEON_2D_EXA_COPY 1
+#define RADEON_2D_EXA_SOLID 2
+
+struct radeon_2d_state {
+    int op; //
+    uint32_t dst_pitch_offset;
+    uint32_t src_pitch_offset;
+    uint32_t dp_gui_master_cntl;
+    uint32_t dp_cntl;
+    uint32_t dp_write_mask;
+    uint32_t dp_brush_frgd_clr;
+    uint32_t dp_brush_bkgd_clr;
+    uint32_t dp_src_frgd_clr;
+    uint32_t dp_src_bkgd_clr;
+    uint32_t default_sc_bottom_right;
+    dri_bo *dst_bo;
+    dri_bo *src_bo;
+};
+    
 #ifdef XF86DRI
+
 struct radeon_cp {
     Bool              CPRuns;           /* CP is running */
     Bool              CPInUse;          /* CP has been used by X server */
@@ -436,6 +468,10 @@ struct radeon_cp {
     drmBufPtr         indirectBuffer;
     int               indirectStart;
 
+    drmBuf         ib_gem_fake;
+    void *ib_ptr;
+  
+    struct radeon_relocs_info relocs;
     /* Debugging info for BEGIN_RING/ADVANCE_RING pairs. */
     int               dma_begin_count;
     char              *dma_debug_func;
@@ -502,13 +538,13 @@ struct radeon_dri {
     drm_handle_t      ringHandle;       /* Handle from drmAddMap */
     drmSize           ringMapSize;      /* Size of map */
     int               ringSize;         /* Size of ring (in MB) */
-    drmAddress        ring;             /* Map */
+  //    drmAddress        ring;             /* Map */
     int               ringSizeLog2QW;
 
     unsigned long     ringReadOffset;   /* Offset into GART space */
     drm_handle_t      ringReadPtrHandle; /* Handle from drmAddMap */
     drmSize           ringReadMapSize;  /* Size of map */
-    drmAddress        ringReadPtr;      /* Map */
+  //    drmAddress        ringReadPtr;      /* Map */
 
     /* CP vertex/indirect buffer data */
     unsigned long     bufStart;         /* Offset into GART space */
@@ -527,7 +563,6 @@ struct radeon_dri {
     drmAddress        gartTex;           /* Map */
     int               log2GARTTexGran;
 
-    /* DRI screen private data */
     int               fbX;
     int               fbY;
     int               backX;
@@ -783,6 +818,7 @@ typedef struct {
     RADEONCardType    cardType;            /* Current card is a PCI card */
     struct radeon_cp  *cp;
     struct radeon_dri  *dri;
+    struct radeon_dri2 dri2;
 #ifdef USE_EXA
     Bool              accelDFS;
 #endif
@@ -884,6 +920,45 @@ typedef struct {
     int               virtualX;
     int               virtualY;
 
+    Bool new_cs; // new command submission routine
+    struct radeon_2d_state state_2d;
+    void (*reemit_current2d)(ScrnInfoPtr pScrn, int op); // emit the current 2D state into the IB 
+    Bool cs_used_depth;
+    Bool drm_mm; // the drm memory manager exists and is initialised 
+    struct {
+      uint64_t vram_start;
+      uint64_t vram_size;
+      uint64_t gart_start;
+      uint64_t gart_size;
+
+      struct radeon_memory *bo_list[2];
+      struct radeon_memory *front_buffer;
+      struct radeon_memory *back_buffer;
+      struct radeon_memory *depth_buffer;
+
+#if 0
+      struct radeon_memory *exa_buffer;
+#endif
+      struct radeon_memory *texture_buffer;
+
+      struct radeon_memory *dma_buffer;
+      struct radeon_memory *gart_texture_buffer;
+      struct radeon_memory *rotate_buffer;
+      struct radeon_memory *cursor[2];
+
+      /* indirect buffer for accel */
+      struct radeon_memory *gem_ib_memory;
+      
+    } mm;
+
+    drm_handle_t fb_map_handle;
+    Bool drm_mode_setting;
+#ifdef XF86DRM_MODE
+    drmmode_rec drmmode;
+#endif
+
+    int can_resize;
+    dri_bufmgr *bufmgr;
 } RADEONInfoRec, *RADEONInfoPtr;
 
 #define RADEONWaitForFifo(pScrn, entries)				\
@@ -1136,6 +1211,23 @@ extern void
 radeon_legacy_free_memory(ScrnInfoPtr pScrn,
 		          void *mem_struct);
 
+/* radeon_memory.c */
+extern uint32_t radeon_name_buffer(ScrnInfoPtr pScrn, struct radeon_memory *mem);
+extern Bool radeon_bind_all_memory(ScrnInfoPtr pScrn);
+extern Bool radeon_unbind_all_memory(ScrnInfoPtr pScrn);
+extern struct radeon_memory *radeon_allocate_memory(ScrnInfoPtr pScrn, int pool, int size, int alignment, Bool no_backing_store, char *name, 
+						    int need_bind);
+int radeon_map_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem);
+void radeon_unmap_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem);
+void radeon_free_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem);
+Bool radeon_bind_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem);
+Bool radeon_free_all_memory(ScrnInfoPtr pScrn);
+Bool radeon_setup_kernel_mem(ScreenPtr pScreen);
+Bool RADEONDRIDoMappings(ScreenPtr pScreen);
+Bool radeon_update_dri_buffers(ScreenPtr pScreen);
+
+dri_bo *radeon_get_pixmap_bo(PixmapPtr pPix);
+void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_memory *mem);
 #ifdef XF86DRI
 #  ifdef USE_XAA
 /* radeon_accelfuncs.c */
@@ -1154,7 +1246,9 @@ do {									\
 
 #define RADEONCP_RELEASE(pScrn, info)					\
 do {									\
-    if (info->cp->CPInUse) {						\
+    if (info->new_cs) {							\
+	RADEONCPReleaseIndirect(pScrn);					\
+    } else if (info->cp->CPInUse) {						\
 	RADEON_PURGE_CACHE();						\
 	RADEON_WAIT_UNTIL_IDLE();					\
 	RADEONCPReleaseIndirect(pScrn);					\
@@ -1189,7 +1283,7 @@ do {									\
 
 #define RADEONCP_REFRESH(pScrn, info)					\
 do {									\
-    if (!info->cp->CPInUse) {						\
+    if (!info->cp->CPInUse && !info->new_cs) {				\
 	if (info->cp->needCacheFlush) {					\
 	    RADEON_PURGE_CACHE();					\
 	    RADEON_PURGE_ZCACHE();					\
@@ -1216,6 +1310,13 @@ do {									\
 #define RING_LOCALS	uint32_t *__head = NULL; int __expected; int __count = 0
 
 #define BEGIN_RING(n) do {						\
+    if (!info->cp->indirectBuffer) {					\
+	info->cp->indirectBuffer = RADEONCPGetBuffer(pScrn);		\
+	info->cp->indirectStart = 0;					\
+    } else if (info->cp->indirectBuffer->used + (n) * (int)sizeof(uint32_t) >	\
+	       info->cp->indirectBuffer->total) {				\
+	RADEONCPFlushIndirect(pScrn, 1);				\
+    }									\
     if (RADEON_VERBOSE) {						\
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
 		   "BEGIN_RING(%d) in %s\n", (unsigned int)n, __FUNCTION__);\
@@ -1228,13 +1329,6 @@ do {									\
     }									\
     info->cp->dma_debug_func = __FILE__;				\
     info->cp->dma_debug_lineno = __LINE__;				\
-    if (!info->cp->indirectBuffer) {					\
-	info->cp->indirectBuffer = RADEONCPGetBuffer(pScrn);		\
-	info->cp->indirectStart = 0;					\
-    } else if (info->cp->indirectBuffer->used + (n) * (int)sizeof(uint32_t) >	\
-	       info->cp->indirectBuffer->total) {		        \
-	RADEONCPFlushIndirect(pScrn, 1);				\
-    }									\
     __expected = n;							\
     __head = (pointer)((char *)info->cp->indirectBuffer->address +	\
 		       info->cp->indirectBuffer->used);			\
@@ -1277,6 +1371,14 @@ do {									\
     OUT_RING(val);							\
 } while (0)
 
+/* TODO - VRAM is wrong in general but true for now - all EXA stuff
+ is in VRAM */
+#define OUT_RING_RELOC(x, read_domains, write_domains)			\
+  do {									\
+    radeon_bufmgr_emit_reloc(x, &info->cp->relocs, __head, &__count, read_domains, write_domains); \
+  } while(0)
+
+
 #define FLUSH_RING()							\
 do {									\
     if (RADEON_VERBOSE)							\
diff --git a/src/radeon_accel.c b/src/radeon_accel.c
index dffbc57..1531c81 100644
--- a/src/radeon_accel.c
+++ b/src/radeon_accel.c
@@ -92,6 +92,7 @@
 
 				/* X and server generic header files */
 #include "xf86.h"
+#include "radeon_bufmgr_gem.h"
 
 static void R600EngineReset(ScrnInfoPtr pScrn);
 
@@ -373,6 +374,9 @@ void RADEONEngineRestore(ScrnInfoPtr pScrn)
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
 
+    if (info->drm_mode_setting)
+      return;
+
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "EngineRestore (%d/%d)\n",
 		   info->CurrentLayout.pixel_code,
@@ -433,8 +437,8 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
 		   info->CurrentLayout.bitsPerPixel);
 
 #ifdef XF86DRI
-    if (info->directRenderingEnabled && (IS_R300_3D || IS_R500_3D)) {
-	drm_radeon_getparam_t np;
+    if ((info->directRenderingEnabled || info->drm_mode_setting) && (IS_R300_3D || IS_R500_3D)) {
+        drm_radeon_getparam_t np;
 	int num_pipes;
 
 	memset(&np, 0, sizeof(np));
@@ -453,59 +457,62 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
     }
 #endif
 
-    if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
-	(info->ChipFamily == CHIP_FAMILY_R420)  ||
-	(info->ChipFamily == CHIP_FAMILY_RS600) ||
-	(info->ChipFamily == CHIP_FAMILY_RS690) ||
-	(info->ChipFamily == CHIP_FAMILY_RS740) ||
-	(info->ChipFamily == CHIP_FAMILY_RS400) ||
-	(info->ChipFamily == CHIP_FAMILY_RS480) ||
-	IS_R500_3D) {
-	if (info->accel_state->num_gb_pipes == 0) {
-	    uint32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT);
-
-	    info->accel_state->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
-	    if (IS_R500_3D)
-		OUTPLL(pScrn, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
-	}
-    } else {
-	if (info->accel_state->num_gb_pipes == 0) {
-	    if ((info->ChipFamily == CHIP_FAMILY_R300) ||
-		(info->ChipFamily == CHIP_FAMILY_R350)) {
-		/* R3xx chips */
-		info->accel_state->num_gb_pipes = 2;
-	    } else {
-		/* RV3xx chips */
-		info->accel_state->num_gb_pipes = 1;
+    if (!info->drm_mode_setting) {
+	if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
+	    (info->ChipFamily == CHIP_FAMILY_R420)  ||
+	    (info->ChipFamily == CHIP_FAMILY_RS600) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS690) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS740) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS400) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS480) ||
+	    IS_R500_3D) {
+	    if (info->accel_state->num_gb_pipes == 0) {
+		uint32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT);
+
+		info->accel_state->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
+		if (IS_R500_3D)
+		    OUTPLL(pScrn, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
+	    }
+	} else {
+	    if (info->accel_state->num_gb_pipes == 0) {
+		if ((info->ChipFamily == CHIP_FAMILY_R300) ||
+		    (info->ChipFamily == CHIP_FAMILY_R350)) {
+		    /* R3xx chips */
+		    info->accel_state->num_gb_pipes = 2;
+		} else {
+		    /* RV3xx chips */
+		    info->accel_state->num_gb_pipes = 1;
+		}
 	    }
-	}
-    }
-
-    if (IS_R300_3D || IS_R500_3D)
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "num quad-pipes is %d\n", info->accel_state->num_gb_pipes);
-
-    if (IS_R300_3D || IS_R500_3D) {
-	uint32_t gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 | R300_SUBPIXEL_1_16);
-
-	switch(info->accel_state->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);
+	if (IS_R300_3D || IS_R500_3D)
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		       "num quad-pipes is %d\n", info->accel_state->num_gb_pipes);
+
+	if (IS_R300_3D || IS_R500_3D) {
+	    uint32_t gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 | R300_SUBPIXEL_1_16);
+	    
+	    switch(info->accel_state->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;
+	    }
 
-    RADEONEngineReset(pScrn);
+	    OUTREG(R300_GB_TILE_CONFIG, gb_tile_config);
+	    OUTREG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
+	    if (info->ChipFamily >= CHIP_FAMILY_R420)
+	    	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);
+    }
 
     switch (info->CurrentLayout.pixel_code) {
     case 8:  datatype = 2; break;
@@ -613,6 +620,119 @@ int RADEONCPStop(ScrnInfoPtr pScrn, RADEONInfoPtr info)
     }
 }
 
+#define RADEON_IB_RESERVE (16 * sizeof(uint32_t))
+drmBufPtr RADEONCSGetBuffer(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+
+    info->cp->relocs.size = getpagesize();
+    info->cp->relocs.num_reloc = 0;
+    info->cp->relocs.max_bo = info->cp->relocs.size / RADEON_RELOC_SIZE;
+    info->cp->relocs.buf = xcalloc(1, info->cp->relocs.size);
+    if (!info->cp->relocs.buf)
+        return NULL;
+
+    info->cp->relocs.bo_list = xcalloc(info->cp->relocs.max_bo, sizeof(dri_bo *));
+    if (!info->cp->relocs.bo_list) {
+	xfree(info->cp->relocs.buf);
+	return NULL;
+    }
+
+    info->cp->ib_gem_fake.address = xcalloc(1, RADEON_BUFFER_SIZE);
+    if (!info->cp->ib_gem_fake.address) {
+        xfree(info->cp->relocs.buf);
+        xfree(info->cp->relocs.bo_list);
+	return NULL;
+    }
+
+
+    info->cp->ib_gem_fake.used = 0;
+    info->cp->ib_gem_fake.total = RADEON_BUFFER_SIZE - RADEON_IB_RESERVE; // reserve 16 dwords
+    return &info->cp->ib_gem_fake;
+}
+
+void RADEONCSFlushIndirect(ScrnInfoPtr pScrn, int discard)
+{
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+    struct drm_radeon_cs args;
+    struct drm_radeon_cs_chunk chunk[2];
+    uint64_t chunk_array[2];
+    int retry = 0;
+    int ret;
+    RING_LOCALS;
+
+    if (info->cp->indirectBuffer->used == 0)
+	return;
+
+    /* always add the cache flushes to the end of the IB */
+    info->cp->indirectBuffer->total += RADEON_IB_RESERVE;
+    
+    /* end of IB purge caches */
+    if (info->cs_used_depth) {
+	RADEON_PURGE_ZCACHE();
+	info->cs_used_depth = 0;
+    }
+
+    chunk[0].chunk_data = (unsigned long)info->cp->ib_gem_fake.address;
+    chunk[0].length_dw = info->cp->indirectBuffer->used / sizeof(uint32_t);
+    chunk[0].chunk_id = RADEON_CHUNK_ID_IB;
+
+    chunk[1].chunk_data = (unsigned long)info->cp->relocs.buf;
+    chunk[1].length_dw = info->cp->relocs.num_reloc * RADEON_RELOC_SIZE;
+    chunk[1].chunk_id = RADEON_CHUNK_ID_RELOCS;
+
+    chunk_array[0] = (uint64_t)(unsigned long)&chunk[0];
+    chunk_array[1] = (uint64_t)(unsigned long)&chunk[1];
+
+    args.num_chunks = 2;
+    args.chunks = (uint64_t)(unsigned long)chunk_array;
+
+    do {
+	ret = drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_CS,
+				  &args, sizeof(args));
+	retry++;
+    } while (ret == -EAGAIN && retry < 1000);
+    if (ret) {
+        /* submit failed */
+        ErrorF("RADEON DRM CS failure - corruptions/glitches may occur %d\n", ret);
+    }
+
+
+    info->cp->indirectStart = 0;
+    info->cp->indirectBuffer->used = 0;
+    info->cp->indirectBuffer->total -= RADEON_IB_RESERVE;
+
+    if (info->bufmgr)
+      radeon_gem_bufmgr_post_submit(info->bufmgr, &info->cp->relocs, ret);
+    
+    info->cp->relocs.num_reloc = 0;
+    /* copy some state into the buffer now - we need to add 2D state to each
+       buffer as the kernel needs to use the blit engine to move stuff around */
+    if (info->reemit_current2d)
+      info->reemit_current2d(pScrn, 0);
+    if (info->dri2.enabled) {
+    info->accel_state->XInited3D = FALSE;
+    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
+    }
+}
+
+void RADEONCSReleaseIndirect(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+
+    if (!info->cp->indirectBuffer) return;
+    RADEONCSFlushIndirect(pScrn, 0);
+    xfree(info->cp->relocs.buf);
+    xfree(info->cp->relocs.bo_list);
+    info->cp->relocs.buf = 0;
+    info->cp->relocs.size = 0;
+    info->cp->relocs.num_reloc = 0;
+    xfree(info->cp->ib_gem_fake.address);
+    info->cp->ib_gem_fake.address = NULL;
+    info->cp->indirectBuffer = NULL;
+
+}
+
 /* Get an indirect buffer for the CP 2D acceleration commands  */
 drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn)
 {
@@ -623,6 +743,9 @@ drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn)
     int            size = 0;
     int            i = 0;
     int            ret;
+    
+    if (info->new_cs)
+	return RADEONCSGetBuffer(pScrn);
 
 #if 0
     /* FIXME: pScrn->pScreen has not been initialized when this is first
@@ -694,6 +817,11 @@ void RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard)
     if (!buffer) return;
     if (start == buffer->used && !discard) return;
 
+    if (info->new_cs) {
+	RADEONCSFlushIndirect(pScrn, discard);
+	return;
+    }
+
     if (RADEON_VERBOSE) {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Flushing buffer %d\n",
 		   buffer->idx);
@@ -749,10 +877,16 @@ void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn)
 	}
     }
 
+    if (info->new_cs) {
+      RADEONCSReleaseIndirect(pScrn);
+      return;
+    }
+
     info->cp->indirectBuffer = NULL;
     info->cp->indirectStart  = 0;
 
     if (!buffer) return;
+      
 
     if (RADEON_VERBOSE) {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Releasing buffer %d\n",
@@ -879,6 +1013,7 @@ RADEONHostDataBlit(
     ret = ( uint8_t* )&__head[__count];
 
     __count += dwords;
+
     ADVANCE_RING();
 
     *y += *hpass;
@@ -1013,7 +1148,7 @@ Bool RADEONAccelInit(ScreenPtr pScreen)
 #ifdef USE_EXA
     if (info->useEXA) {
 # ifdef XF86DRI
-	if (info->directRenderingEnabled) {
+	if (info->directRenderingEnabled || info->drm_mode_setting) {
 	    if (info->ChipFamily >= CHIP_FAMILY_R600) {
 		if (!R600DrawInit(pScreen))
 		    return FALSE;
@@ -1046,7 +1181,7 @@ Bool RADEONAccelInit(ScreenPtr pScreen)
 	}
 
 #ifdef XF86DRI
-	if (info->directRenderingEnabled)
+	if (info->directRenderingEnabled || info->drm_mode_setting)
 	    RADEONAccelInitCP(pScreen, a);
 	else
 #endif /* XF86DRI */
@@ -1068,11 +1203,13 @@ void RADEONInit3DEngine(ScrnInfoPtr pScrn)
     RADEONInfoPtr info = RADEONPTR (pScrn);
 
 #ifdef XF86DRI
-    if (info->directRenderingEnabled) {
-	drm_radeon_sarea_t *pSAREAPriv;
+    if (info->directRenderingEnabled || info->drm_mode_setting) {
+	if (info->directRenderingEnabled && !info->dri2.enabled) {
+	    drm_radeon_sarea_t *pSAREAPriv;
 
-	pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
-	pSAREAPriv->ctx_owner = DRIGetContext(pScrn->pScreen);
+	    pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
+	    pSAREAPriv->ctx_owner = DRIGetContext(pScrn->pScreen);
+	}
 	RADEONInit3DEngineCP(pScrn);
     } else
 #endif
@@ -1080,7 +1217,7 @@ void RADEONInit3DEngine(ScrnInfoPtr pScrn)
 
     info->accel_state->XInited3D = TRUE;
 }
-
+    
 #ifdef USE_XAA
 #ifdef XF86DRI
 Bool
diff --git a/src/radeon_bufmgr.h b/src/radeon_bufmgr.h
new file mode 100644
index 0000000..481c5cf
--- /dev/null
+++ b/src/radeon_bufmgr.h
@@ -0,0 +1,25 @@
+/**
+ * @file intel_bufmgr.h
+ *
+ * Public definitions of Intel-specific bufmgr functions.
+ */
+
+#ifndef RADEON_BUFMGR_H
+#define RADEON_BUFMGR_H
+
+#include "radeon_dri_bufmgr.h"
+
+struct radeon_bufmgr {
+  void (*emit_reloc)(dri_bo *buf, struct radeon_relocs_info *relocs, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain);
+};
+
+dri_bufmgr *radeon_bufmgr_gem_init(int fd);
+dri_bo *radeon_bo_gem_create_from_name(dri_bufmgr *bufmgr, const char *name,
+				       unsigned int handle);
+dri_bo *radeon_bo_gem_create_from_handle(dri_bufmgr *bufmgr,
+					 uint32_t handle, unsigned long size);
+
+void radeon_bufmgr_emit_reloc(dri_bo *buf, struct radeon_relocs_info *relocs, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain);
+
+void radeon_bufmgr_post_submit(dri_bufmgr *bufmgr);
+#endif
diff --git a/src/radeon_bufmgr_gem.c b/src/radeon_bufmgr_gem.c
new file mode 100644
index 0000000..a2fd61a
--- /dev/null
+++ b/src/radeon_bufmgr_gem.c
@@ -0,0 +1,668 @@
+/**************************************************************************
+ *
+ * Copyright Š 2007-2008 Red Hat Inc.
+ * Copyright Š 2007 Intel Corporation
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas HellstrĂśm <thomas-at-tungstengraphics-dot-com>
+ *          Keith Whitwell <keithw-at-tungstengraphics-dot-com>
+ *	    Eric Anholt <eric@anholt.net>
+ *	    Dave Airlie <airlied@linux.ie>
+ *	    Kristian Høgsberg <krh@redhat.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <xf86drm.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+
+#include "xf86.h"
+#include "errno.h"
+#include "string.h"
+
+#include "radeon_reg.h"
+#include "radeon_probe.h"
+#include "radeon.h"
+#include "radeon_bufmgr.h"
+#include "radeon_drm.h"
+
+#define DBG(...) do {					\
+   if (bufmgr_gem->bufmgr.debug)			\
+      fprintf(stderr, __VA_ARGS__);			\
+} while (0)
+
+typedef struct _dri_bo_gem {
+	dri_bo bo;
+	int refcount;
+	int reloc_count;
+	int map_count;
+	/* reloc list - add to list for relocs */
+	uint32_t gem_handle;
+	const char *name;
+	struct _dri_bo_gem *next;
+	int in_vram; /* have we migrated this bo to VRAM ever */
+	int force_gtt;
+	int pinned;
+	int touched;
+	uint32_t space_accounted;
+} dri_bo_gem;
+
+typedef struct _dri_bufmgr_gem {
+	dri_bufmgr bufmgr;
+	struct radeon_bufmgr radeon_bufmgr;
+	int fd;
+	uint32_t vram_limit, gart_limit;
+	uint32_t vram_write_used, gart_write_used;
+	uint32_t read_used;
+
+	struct _dri_bo_gem *bo_list;
+} dri_bufmgr_gem;
+
+static dri_bo *
+dri_gem_bo_alloc(dri_bufmgr *bufmgr, const char *name,
+		 unsigned long size, unsigned int alignment, uint64_t location_mask)
+
+{
+	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr;
+	struct drm_radeon_gem_create args;
+	int ret;
+	dri_bo_gem *gem_bo;
+
+	gem_bo = calloc(1, sizeof(*gem_bo));
+	if (!gem_bo)
+		return NULL;
+
+	gem_bo->bo.size = size;
+	args.size = size;
+	args.alignment = alignment;
+	args.initial_domain = RADEON_GEM_DOMAIN_CPU;
+	args.no_backing_store = 0;
+
+	ret = drmCommandWriteRead(bufmgr_gem->fd, DRM_RADEON_GEM_CREATE, &args, sizeof(args));
+	gem_bo->gem_handle = args.handle;
+	if (ret != 0) {
+		free(gem_bo);
+		return NULL;
+	}
+	gem_bo->bo.bufmgr = bufmgr;
+
+	gem_bo->refcount = 1;
+	gem_bo->reloc_count = 0;
+	gem_bo->map_count = 0;
+	gem_bo->in_vram = 0;
+	gem_bo->name = strdup(name);
+	gem_bo->touched = 0;
+
+	gem_bo->next = bufmgr_gem->bo_list;
+	bufmgr_gem->bo_list = gem_bo;
+
+	DBG("bo_create: buf %d (%s) %ldb\n",
+	    gem_bo->gem_handle, gem_bo->name, size);
+
+	return &gem_bo->bo;
+}
+
+static void
+dri_gem_bo_reference(dri_bo *bo)
+{
+	dri_bo_gem *gem_bo = (dri_bo_gem *)bo;
+	gem_bo->refcount++;
+}
+
+static void dri_gem_bo_free(dri_bo *bo)
+{
+	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
+	dri_bo_gem *gem_bo = (dri_bo_gem *)bo, *trav, *prev;
+	struct drm_gem_close args;
+
+	if (gem_bo->map_count)
+		munmap(gem_bo->bo.virtual, gem_bo->bo.size);
+
+	/* close object */
+	args.handle = gem_bo->gem_handle;
+	ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &args);
+
+	if (gem_bo == bufmgr_gem->bo_list)
+		bufmgr_gem->bo_list = gem_bo->next;
+	else {
+		prev = trav = bufmgr_gem->bo_list;
+		while (trav) {
+			if (trav == gem_bo) {
+				if (prev)
+					prev->next = trav->next;
+				break;
+			}
+			prev = trav;
+			trav = trav->next;
+		}
+	}
+	free(gem_bo->name);
+	free(gem_bo);
+}
+
+static void
+dri_gem_bo_unreference(dri_bo *bo)
+{
+	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
+	dri_bo_gem *gem_bo = (dri_bo_gem *)bo;
+
+	if (!bo)
+		return;
+	
+	if (--gem_bo->refcount == 0) {
+		DBG("bo_unreference final: %d (%s) 0 - free %d\n",
+		    gem_bo->gem_handle, gem_bo->name, gem_bo->in_vram);
+		dri_gem_bo_free(bo);
+		return;
+	}
+}
+
+static int
+dri_gem_bo_map(dri_bo *bo, int write_enable)
+{
+	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
+	dri_bo_gem *gem_bo = (dri_bo_gem *)bo;
+	struct drm_radeon_gem_mmap args;
+	int ret;
+
+	if (gem_bo->map_count++ != 0)
+		return 0;
+
+	args.handle = gem_bo->gem_handle;
+	args.offset = 0;
+	args.size = gem_bo->bo.size;
+
+	ret = drmCommandWriteRead(bufmgr_gem->fd, DRM_RADEON_GEM_MMAP, &args, sizeof(args));
+	if (!ret)
+		gem_bo->bo.virtual = (void *)(unsigned long)args.addr_ptr;
+
+	return ret;
+}
+
+static int
+dri_gem_bo_unmap(dri_bo *buf)
+{
+	dri_bo_gem *gem_bo = (dri_bo_gem *)buf;
+
+	if (--gem_bo->map_count > 0)
+		return 0;
+
+        munmap(gem_bo->bo.virtual, gem_bo->bo.size);
+	gem_bo->bo.virtual = 0;
+	return 0;
+}
+
+static void
+dri_bufmgr_gem_destroy(dri_bufmgr *bufmgr)
+{
+	free(bufmgr);
+}
+
+void radeon_bufmgr_gem_wait_rendering(dri_bo *buf)
+{
+	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)buf->bufmgr;
+	struct drm_radeon_gem_wait_rendering args;
+	struct drm_radeon_gem_set_domain sd_args;
+	dri_bo_gem *gem_bo = (dri_bo_gem *)buf;
+	int ret;
+
+	if (!gem_bo->touched)
+		return;
+
+	/* do a set domain */
+	if (gem_bo->force_gtt) {
+		sd_args.handle = gem_bo->gem_handle;
+		sd_args.read_domains = RADEON_GEM_DOMAIN_GTT;
+		sd_args.write_domain = 0;
+
+		ret = drmCommandWriteRead(bufmgr_gem->fd, DRM_RADEON_GEM_SET_DOMAIN,
+					  &sd_args, sizeof(sd_args));
+
+	} else {
+		args.handle = gem_bo->gem_handle;
+
+		do {
+		ret = drmCommandWriteRead(bufmgr_gem->fd, DRM_RADEON_GEM_WAIT_RENDERING,
+					  &args, sizeof(args));
+		} while (ret == -EAGAIN);
+	}
+	return;
+}
+
+dri_bo *
+radeon_bo_gem_create_from_handle(dri_bufmgr *bufmgr,
+				 uint32_t handle, unsigned long size)
+{
+    dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr;
+    dri_bo_gem *bo_gem;
+    char name[32];
+
+    sprintf(name, "handle:%8x", handle);
+    bo_gem = calloc(1, sizeof(*bo_gem));
+    if (!bo_gem)
+	return NULL;
+
+    bo_gem->bo.size = size;
+    bo_gem->bo.offset = 0;
+    bo_gem->bo.virtual = NULL;
+    bo_gem->bo.bufmgr = bufmgr;
+    bo_gem->name = strdup(name);
+    bo_gem->refcount = 1;
+    bo_gem->pinned = 1;
+    bo_gem->gem_handle = handle;
+    bo_gem->in_vram = 1;
+    /* if we get from kernel assume touched */
+    bo_gem->touched = 1;
+
+    bo_gem->next = bufmgr_gem->bo_list;
+    bufmgr_gem->bo_list = bo_gem;
+    return &bo_gem->bo;
+}
+
+/**
+ * Returns a dri_bo wrapping the given buffer object handle.
+ *
+ * This can be used when one application needs to pass a buffer object
+ * to another.
+ */
+dri_bo *
+radeon_bo_gem_create_from_name(dri_bufmgr *bufmgr, const char *name,
+			       unsigned int handle)
+{
+    dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr;
+    int ret;
+    struct drm_gem_open open_arg;
+
+    memset(&open_arg, 0, sizeof(open_arg));
+    open_arg.name = handle;
+    ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_OPEN, &open_arg);
+    if (ret != 0) {
+	fprintf(stderr, "Couldn't reference %s handle 0x%08x: %s\n",
+	       name, handle, strerror(-ret));
+	return NULL;
+    }
+
+    return radeon_bo_gem_create_from_handle(bufmgr,
+					    open_arg.handle, open_arg.size);
+}
+
+#define BUF_OUT_RING(x)	 do {			\
+		__head[__count++] = (x);				\
+	} while (0)
+
+void radeon_bufmgr_gem_emit_reloc(dri_bo *buf, struct radeon_relocs_info *reloc_info, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain)
+{
+	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)buf->bufmgr;
+	dri_bo_gem *gem_bo = (dri_bo_gem *)buf;
+	uint32_t *__head = head;
+	uint32_t __count = *count_p;
+	int i;
+	int index;
+	int have_reloc = -1;
+
+	for (i = 0; i < reloc_info->num_reloc; i++) {
+		if (reloc_info->buf[i * 4] == gem_bo->gem_handle) {
+			have_reloc = i;
+			break;
+		}
+	}
+
+	if (gem_bo->force_gtt && (read_domains & RADEON_GEM_DOMAIN_VRAM))
+		read_domains = RADEON_GEM_DOMAIN_GTT;
+
+	if (have_reloc != -1) {
+		uint32_t old_write, old_read;
+
+		index = have_reloc * 4;
+		old_read = reloc_info->buf[index + 1];
+		old_write = reloc_info->buf[index + 2];
+
+		/* error up for now - work out new domains - if we have a write */
+		if (write_domain && (old_read & write_domain)) {
+			reloc_info->buf[index + 1] = 0;
+			reloc_info->buf[index + 2] = write_domain;
+		} else if (read_domains & old_write) {
+			reloc_info->buf[index + 1] = 0;
+		} else {
+			/* rewrite the domains */
+			if (write_domain != old_write)
+				ErrorF("WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", gem_bo->gem_handle, write_domain, old_write);
+			if (read_domains != old_read)
+				ErrorF("READ DOMAIN RELOC FAILURE 0x%x %d %d\n", gem_bo->gem_handle, read_domains, old_read);
+		}
+		reloc_info->buf[index + 3]++;
+
+	} else {
+
+		if ((reloc_info->num_reloc + 1) * RADEON_RELOC_SIZE > reloc_info->size) {
+			/* resize the buffer */
+			reloc_info->size += getpagesize();
+			reloc_info->buf = xrealloc(reloc_info->buf, reloc_info->size);
+			if (!reloc_info->buf)
+				FatalError("failed to increase reloc buffer size\n");
+			reloc_info->max_bo = reloc_info->size / RADEON_RELOC_SIZE;
+			reloc_info->bo_list = xrealloc(reloc_info->bo_list, reloc_info->max_bo * (sizeof(dri_bo *)));
+		}
+
+		dri_bo_reference(buf);
+		gem_bo->touched = 1;
+
+		index = reloc_info->num_reloc * 4;
+		reloc_info->bo_list[index/4] = buf;
+		reloc_info->buf[index] = gem_bo->gem_handle;
+		reloc_info->buf[index + 1] = read_domains;
+		reloc_info->buf[index + 2] = write_domain;
+		reloc_info->buf[index + 3] = 1;
+		reloc_info->num_reloc++;
+	}
+
+	if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
+		if (gem_bo->in_vram == 0)
+			DBG("bo_into vram: buf %d (%s) %d %d\n",
+			    gem_bo->gem_handle, gem_bo->name, read_domains, write_domain);
+		
+		gem_bo->in_vram = 1;
+	}
+
+	BUF_OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_NOP, 0));
+	BUF_OUT_RING(index);
+	*count_p = __count;
+}
+
+static int radeon_gem_bufmgr_pin(dri_bo *bo, int domain)
+{
+	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
+	dri_bo_gem *gem_bo = (dri_bo_gem *)bo;
+	struct drm_radeon_gem_pin pin;
+	int ret;
+
+	if (domain == RADEON_GEM_DOMAIN_VRAM)
+		gem_bo->in_vram = 1;
+
+	pin.pin_domain = domain;
+	pin.handle = gem_bo->gem_handle;
+	pin.alignment = 0;
+
+	ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_RADEON_GEM_PIN, &pin);
+	if (ret != 0)
+		return -1;
+
+	/* pinned buffers are considered touched */
+	gem_bo->touched = 1;
+	gem_bo->pinned = 1;
+	return 0;
+}
+
+static void radeon_gem_bufmgr_unpin(dri_bo *bo)
+{
+
+	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
+	dri_bo_gem *gem_bo = (dri_bo_gem *)bo;
+	struct drm_radeon_gem_unpin unpin;
+
+	unpin.handle = gem_bo->gem_handle;
+	ioctl(bufmgr_gem->fd, DRM_IOCTL_RADEON_GEM_UNPIN, &unpin);
+	gem_bo->pinned = 0;
+}
+
+
+static uint32_t radeon_gem_bufmgr_get_handle(dri_bo *buf)
+{
+	dri_bo_gem *gem_bo = (dri_bo_gem *)buf;
+	
+	return gem_bo->gem_handle;
+}
+
+static int radeon_gem_bufmgr_check_aperture_space(struct radeon_space_check *bos, int num_bo)
+{
+	dri_bufmgr_gem *bufmgr_gem;
+ 	dri_bo_gem *gem_bo;
+	dri_bo *buf;
+	int this_op_read = 0, this_op_gart_write = 0, this_op_vram_write = 0;
+	uint32_t read_domains, write_domain;
+	int i;
+	/* check the totals for this operation */
+
+	if (num_bo == 0)
+		return 0;
+
+	bufmgr_gem = (dri_bufmgr_gem *)bos[0].buf->bufmgr;
+
+	/* prepare */
+	for (i = 0; i < num_bo; i++) {
+		buf = bos[i].buf;
+		gem_bo = (dri_bo_gem *)buf;
+
+		bos[i].new_accounted = 0;
+		read_domains = bos[i].read_domains;
+		write_domain = bos[i].write_domain;
+		
+		/* pinned bos don't count */
+		if (gem_bo->pinned)
+			continue;
+ 
+		/* already accounted this bo */
+		if (write_domain && (write_domain == gem_bo->space_accounted))
+			continue;
+
+		if (read_domains && ((read_domains << 16) == gem_bo->space_accounted))
+			continue;
+
+		if (gem_bo->space_accounted == 0) {
+			if (write_domain == RADEON_GEM_DOMAIN_VRAM)
+				this_op_vram_write += buf->size;
+			else if (write_domain == RADEON_GEM_DOMAIN_GTT)
+				this_op_gart_write += buf->size;
+			else
+				this_op_read += buf->size;
+			bos[i].new_accounted = (read_domains << 16) | write_domain;
+		} else {
+			uint16_t old_read, old_write;
+
+			old_read = gem_bo->space_accounted >> 16;
+			old_write = gem_bo->space_accounted & 0xffff;
+
+			if (write_domain && (old_read & write_domain)) {
+				bos[i].new_accounted = write_domain;
+				/* moving from read to a write domain */
+				if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
+					this_op_read -= buf->size;
+					this_op_vram_write += buf->size;
+				} else if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
+					this_op_read -= buf->size;
+					this_op_gart_write += buf->size;
+				}
+			} else if (read_domains & old_write) {
+				bos[i].new_accounted = gem_bo->space_accounted & 0xffff;
+			} else {
+				/* rewrite the domains */
+				if (write_domain != old_write)
+					ErrorF("WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", gem_bo->gem_handle, write_domain, old_write);
+				if (read_domains != old_read)
+					ErrorF("READ DOMAIN RELOC FAILURE 0x%x %d %d\n", gem_bo->gem_handle, read_domains, old_read);
+				return BUFMGR_SPACE_FLUSH;
+			}
+		}
+	}
+	
+	if (this_op_read < 0)
+		this_op_read = 0;
+
+	/* check sizes - operation first */
+	if ((this_op_read + this_op_gart_write > bufmgr_gem->gart_limit) ||
+	    (this_op_vram_write > bufmgr_gem->vram_limit)) {
+		return BUFMGR_SPACE_OP_TO_BIG;
+	}
+
+	if (((bufmgr_gem->vram_write_used + this_op_vram_write) > bufmgr_gem->vram_limit) ||
+	    ((bufmgr_gem->read_used + bufmgr_gem->gart_write_used + this_op_gart_write + this_op_read) > bufmgr_gem->gart_limit)) {
+		return BUFMGR_SPACE_FLUSH;
+	}
+
+	bufmgr_gem->gart_write_used += this_op_gart_write;
+	bufmgr_gem->vram_write_used += this_op_vram_write;
+	bufmgr_gem->read_used += this_op_read;
+	/* commit */
+	for (i = 0; i < num_bo; i++) {
+		buf = bos[i].buf;
+		gem_bo = (dri_bo_gem *)buf;
+		gem_bo->space_accounted = bos[i].new_accounted;
+	}
+
+	return BUFMGR_SPACE_OK;
+}
+
+/**
+ * Initializes the GEM buffer manager, which is just a thin wrapper
+ * around the GEM allocator.
+ *
+ * \param fd File descriptor of the opened DRM device.
+ * \param fence_type Driver-specific fence type used for fences with no flush.
+ * \param fence_type_flush Driver-specific fence type used for fences with a
+ *	  flush.
+ */
+dri_bufmgr *
+radeon_bufmgr_gem_init(int fd)
+{
+	dri_bufmgr_gem *bufmgr_gem;
+
+	bufmgr_gem = calloc(1, sizeof(*bufmgr_gem));
+	bufmgr_gem->fd = fd;
+
+	bufmgr_gem->bufmgr.bo_alloc = dri_gem_bo_alloc;
+	bufmgr_gem->bufmgr.bo_reference = dri_gem_bo_reference;
+	bufmgr_gem->bufmgr.bo_unreference = dri_gem_bo_unreference;
+	bufmgr_gem->bufmgr.bo_map = dri_gem_bo_map;
+	bufmgr_gem->bufmgr.bo_unmap = dri_gem_bo_unmap;
+	bufmgr_gem->bufmgr.destroy = dri_bufmgr_gem_destroy;
+	bufmgr_gem->bufmgr.pin = radeon_gem_bufmgr_pin;
+	bufmgr_gem->bufmgr.unpin = radeon_gem_bufmgr_unpin;
+	//bufmgr_gem->bufmgr.bo_wait_rendering = radeon_bufmgr_gem_wait_rendering;
+	bufmgr_gem->radeon_bufmgr.emit_reloc = radeon_bufmgr_gem_emit_reloc;
+	bufmgr_gem->bufmgr.get_handle = radeon_gem_bufmgr_get_handle;
+	bufmgr_gem->bufmgr.check_aperture_space = radeon_gem_bufmgr_check_aperture_space;
+	bufmgr_gem->bufmgr.debug = 0;
+	return &bufmgr_gem->bufmgr;
+}
+
+
+void radeon_gem_bufmgr_post_submit(dri_bufmgr *bufmgr, struct radeon_relocs_info *reloc_info, int error)
+{
+	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr;
+	struct _dri_bo_gem *trav, *prev;
+	int i;
+	
+	if (error) {
+		ErrorF("bufmgr: last submission : r:%d vs g:%d w:%d vs v:%d\n",
+		       bufmgr_gem->read_used, bufmgr_gem->gart_limit, 
+		       bufmgr_gem->vram_write_used, bufmgr_gem->vram_limit);
+	}
+
+	if (!bufmgr_gem->bo_list)
+		return;
+
+	for (i = 0; i < reloc_info->num_reloc; i++) {
+		trav = (dri_bo_gem *)reloc_info->bo_list[i];
+
+		trav->space_accounted = 0;
+		dri_bo_unreference(&trav->bo);
+	}
+
+	bufmgr_gem->read_used = 0;
+	bufmgr_gem->vram_write_used = 0;
+	bufmgr_gem->gart_write_used = 0;
+	
+}
+
+
+
+void radeon_bufmgr_emit_reloc(dri_bo *buf, struct radeon_relocs_info *relocs, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain)
+{
+	struct radeon_bufmgr *radeon_bufmgr;
+
+	radeon_bufmgr = (struct radeon_bufmgr *)(buf->bufmgr + 1);
+	radeon_bufmgr->emit_reloc(buf, relocs, head, count_p, read_domains, write_domain);
+}
+
+/* if the buffer is references by the current IB we need to flush the IB */
+int radeon_bufmgr_gem_has_references(dri_bo *buf)
+{
+	dri_bo_gem *gem_bo = (dri_bo_gem *)buf;
+
+	return gem_bo->touched;
+}
+
+void radeon_bufmgr_gem_set_limit(dri_bufmgr *bufmgr, uint32_t domain, uint32_t limit)
+{
+	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr;
+
+	if (domain == RADEON_GEM_DOMAIN_VRAM)
+	    bufmgr_gem->vram_limit = limit;
+	else
+	    bufmgr_gem->gart_limit = limit;
+
+}
+
+void radeon_bufmgr_gem_force_gtt(dri_bo *buf)
+{
+	dri_bo_gem *gem_bo = (dri_bo_gem *)buf;
+
+	if (!gem_bo->pinned && !gem_bo->force_gtt)
+	    gem_bo->force_gtt = 1;
+}
+
+int radeon_bufmgr_gem_in_vram(dri_bo *buf)
+{
+	dri_bo_gem *gem_bo = (dri_bo_gem *)buf;
+	return gem_bo->in_vram;
+}
+
+int radeon_bo_gem_name_buffer(dri_bo *bo, uint32_t *name)
+{
+	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
+	dri_bo_gem *gem_bo = (dri_bo_gem *)bo;
+    struct drm_gem_flink flink;
+    int r;
+
+    flink.handle = gem_bo->gem_handle;
+	fprintf(stderr,"naming attemp %d\n", flink.handle);
+    r = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_FLINK, &flink);
+    if (r) {
+        DBG("[drm] failed to name buffer %d\n", -errno);
+        return r;
+    }
+	fprintf(stderr,"naming %d with %d\n", flink.handle, flink.name);
+    *name = flink.name;
+    return 0;
+}
diff --git a/src/radeon_bufmgr_gem.h b/src/radeon_bufmgr_gem.h
new file mode 100644
index 0000000..6d3b6fe
--- /dev/null
+++ b/src/radeon_bufmgr_gem.h
@@ -0,0 +1,19 @@
+#ifndef RADEON_BUFMGR_GEM_H
+#define RADEON_BUFMGR_GEM_H
+
+#include "radeon_dri_bufmgr.h"
+
+
+extern void radeon_bufmgr_gem_wait_rendering(dri_bo *bo);
+extern dri_bo *radeon_bufmgr_gem_create_bo(dri_bufmgr *bufmgr, struct radeon_memory *mem);
+void radeon_bufmgr_gem_emit_reloc(dri_bo *bo, struct radeon_relocs_info *reloc_info, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain);
+void radeon_gem_bufmgr_post_submit(dri_bufmgr *bufmgr, struct radeon_relocs_info *reloc_info, int error);
+void radeon_bufmgr_pin(dri_bo *buf);
+void radeon_bufmgr_unpin(dri_bo *buf);
+uint32_t radeon_bufmgr_get_handle(dri_bo *buf);
+int radeon_bufmgr_gem_has_references(dri_bo *buf);
+int radeon_bufmgr_gem_force_gtt(dri_bo *buf);
+void radeon_bufmgr_gem_set_limit(dri_bufmgr *bufmgr, uint32_t domain, uint32_t limit);
+int radeon_bufmgr_gem_in_vram(dri_bo *buf);
+int radeon_bo_gem_name_buffer(dri_bo *bo, uint32_t *name);
+#endif
diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c
index eabd87d..8712a74 100644
--- a/src/radeon_commonfuncs.c
+++ b/src/radeon_commonfuncs.c
@@ -62,12 +62,15 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 	info->accel_state->texW[1] = info->accel_state->texH[1] = 1;
 
     if (IS_R300_3D || IS_R500_3D) {
+	int size;
 
-	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(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
-	FINISH_ACCEL();
+	if (!info->new_cs) {
+	    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(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);
 
@@ -79,10 +82,12 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 	case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
 	}
 
-	BEGIN_ACCEL(5);
+	size = (info->ChipFamily >= CHIP_FAMILY_R420) ? 5 : 4;
+	BEGIN_ACCEL(size);
 	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);
+	if (info->ChipFamily >= CHIP_FAMILY_R420)
+	    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();
@@ -626,6 +631,39 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 
 }
 
+#if defined(ACCEL_CP) && defined(XF86DRM_MODE)
+void drmmode_wait_for_vline(ScrnInfoPtr pScrn, PixmapPtr pPix,
+			    int crtc, int start, int stop)
+{
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+    xf86CrtcConfigPtr  xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    uint32_t offset;
+    drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[crtc]->driver_private;
+    ACCEL_PREAMBLE();
+
+    BEGIN_ACCEL(3);
+
+    if (IS_AVIVO_VARIANT) {
+	uint32_t reg = AVIVO_D1MODE_VLINE_START_END; /* this is just a marker */
+	OUT_ACCEL_REG(reg,
+		      ((start << AVIVO_D1MODE_VLINE_START_SHIFT) |
+		       (stop << AVIVO_D1MODE_VLINE_END_SHIFT) |
+		       AVIVO_D1MODE_VLINE_INV));
+    } else {
+	OUT_ACCEL_REG(RADEON_CRTC_GUI_TRIG_VLINE, /* another placeholder */
+		      ((start << RADEON_CRTC_GUI_TRIG_VLINE_START_SHIFT) |
+		      (stop << RADEON_CRTC_GUI_TRIG_VLINE_END_SHIFT) |
+		      RADEON_CRTC_GUI_TRIG_VLINE_INV));
+    }
+    OUT_ACCEL_REG(RADEON_WAIT_UNTIL, (RADEON_WAIT_CRTC_VLINE |
+				      RADEON_ENG_DISPLAY_SELECT_CRTC0));
+
+    OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_NOP, 0));
+    OUT_RING(drmmode_crtc->mode_crtc->crtc_id);
+    FINISH_ACCEL();
+}
+#endif
+
 /* inserts a wait for vline in the command stream */
 void FUNC_NAME(RADEONWaitForVLine)(ScrnInfoPtr pScrn, PixmapPtr pPix,
 	int crtc, int start, int stop)
@@ -644,16 +682,19 @@ void FUNC_NAME(RADEONWaitForVLine)(ScrnInfoPtr pScrn, PixmapPtr pPix,
     if (!xf86_config->crtc[crtc]->enabled)
 	return;
 
+    if (info->drm_mode_setting) {
+        if (pPix != pScrn->pScreen->GetScreenPixmap(pScrn->pScreen))
+	    return;
+    } else {
+        if (info->useEXA)
 #ifdef USE_EXA
-    if (info->useEXA)
-	offset = exaGetPixmapOffset(pPix);
-    else
+           offset = exaGetPixmapOffset(pPix);
+        else
 #endif
-	offset = pPix->devPrivate.ptr - info->FB;
-
-    /* if drawing to front buffer */
-    if (offset != 0)
-	return;
+	    offset = pPix->devPrivate.ptr - info->FB;
+        if (offset != 0)
+            return;
+    }
 
     start = max(start, 0);
     stop = min(stop, xf86_config->crtc[crtc]->mode.VDisplay);
@@ -661,6 +702,13 @@ void FUNC_NAME(RADEONWaitForVLine)(ScrnInfoPtr pScrn, PixmapPtr pPix,
     if (start > xf86_config->crtc[crtc]->mode.VDisplay)
 	return;
 
+#if defined(ACCEL_CP) && defined(XF86DRM_MODE)
+    if (info->drm_mode_setting) {
+	drmmode_wait_for_vline(pScrn, pPix, crtc, start, stop);
+	return;
+    }
+#endif
+
     BEGIN_ACCEL(2);
 
     if (IS_AVIVO_VARIANT) {
@@ -712,7 +760,7 @@ void FUNC_NAME(RADEONWaitForIdle)(ScrnInfoPtr pScrn)
 
 #ifdef ACCEL_CP
     /* Make sure the CP is idle first */
-    if (info->cp->CPStarted) {
+    if (info->cp->CPStarted || info->drm_mode_setting) {
 	int  ret;
 
 	FLUSH_RING();
diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index 0fcdcf0..49601cf 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -96,12 +96,19 @@ avivo_setup_cursor(xf86CrtcPtr crtc, Bool enable)
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     RADEONInfoPtr  info = RADEONPTR(crtc->scrn);
     unsigned char     *RADEONMMIO = info->MMIO;
-
+    uint32_t location;
+    
     OUTREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset, 0);
 
     if (enable) {
+
+	if (info->drm_mm)
+	    location = info->fbLocation + radeon_crtc->cursor->offset;
+	else
+	    location = info->fbLocation + radeon_crtc->cursor_offset + pScrn->fbOffset;
+
 	OUTREG(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
-	       info->fbLocation + radeon_crtc->cursor_offset + pScrn->fbOffset);
+	       location);
 	OUTREG(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset,
 	       ((CURSOR_WIDTH - 1) << 16) | (CURSOR_HEIGHT - 1));
 	OUTREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset,
@@ -203,6 +210,7 @@ radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
     int xorigin = 0, yorigin = 0;
     int stride = 256;
     DisplayModePtr mode = &crtc->mode;
+    uint32_t offset;
 
     if (x < 0)                        xorigin = -x+1;
     if (y < 0)                        yorigin = -y+1;
@@ -233,8 +241,12 @@ radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
 					       | (yorigin ? 0 : y)));
 	    RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
 			  radeon_crtc->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
+	    if (info->drm_mm)
+		offset = radeon_crtc->cursor->offset;
+	    else
+		offset = radeon_crtc->cursor_offset + pScrn->fbOffset;
 	    OUTREG(RADEON_CUR_OFFSET,
-		   radeon_crtc->cursor_offset + pScrn->fbOffset + yorigin * stride);
+		   offset + yorigin * stride);
 	} else if (crtc_id == 1) {
 	    OUTREG(RADEON_CUR2_HORZ_VERT_OFF,  (RADEON_CUR2_LOCK
 						| (xorigin << 16)
@@ -244,8 +256,12 @@ radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
 						| (yorigin ? 0 : y)));
 	    RADEONCTRACE(("cursor_offset2: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
 			  radeon_crtc->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
+	    if (info->drm_mm)
+		offset = radeon_crtc->cursor->offset;
+	    else
+		offset = radeon_crtc->cursor_offset + pScrn->fbOffset;
 	    OUTREG(RADEON_CUR2_OFFSET,
-		   radeon_crtc->cursor_offset + pScrn->fbOffset + yorigin * stride);
+		   offset + yorigin * stride);
 	}
     }
 }
@@ -299,10 +315,15 @@ radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     RADEONInfoPtr  info = RADEONPTR(pScrn);
     CURSOR_SWAPPING_DECL_MMIO
-    uint32_t *d = (uint32_t *)(pointer)(info->FB + radeon_crtc->cursor_offset);
+    uint32_t *d;
 
     RADEONCTRACE(("RADEONLoadCursorARGB\n"));
 
+    if (info->drm_mm) 
+      d = (uint32_t *)radeon_crtc->cursor->map;
+    else
+      d = (uint32_t *)(pointer)(info->FB + radeon_crtc->cursor_offset);
+
     info->cursor_argb = TRUE;
 
     CURSOR_SWAPPING_START();
@@ -333,7 +354,7 @@ Bool RADEONCursorInit(ScreenPtr pScreen)
     height      = ((size_bytes * xf86_config->num_crtc) + width_bytes - 1) / width_bytes;
     int align = IS_AVIVO_VARIANT ? 4096 : 256;
 
-    if (!info->useEXA) {
+    if (!info->useEXA && !info->drm_mm) {
 	for (c = 0; c < xf86_config->num_crtc; c++) {
 	    xf86CrtcPtr crtc = xf86_config->crtc[c];
 	    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index 2b7540c..6a24ae2 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -40,6 +40,8 @@
 
 #include <string.h>
 #include <stdio.h>
+#include <errno.h>
+#include <sys/ioctl.h>
 
 				/* Driver data structures */
 #include "radeon.h"
@@ -53,6 +55,8 @@
 
 #include "atipciids.h"
 
+#include "radeon_drm.h"
+
 				/* X and server generic header files */
 #include "xf86.h"
 #include "xf86PciInfo.h"
@@ -70,16 +74,31 @@ static size_t radeon_drm_page_size;
 extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
 				void **configprivs);
 
+#if defined(DAMAGE) && (DRIINFO_MAJOR_VERSION > 5 ||            \
+                        (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1))
+#define DRI_SUPPORTS_CLIP_NOTIFY 1
+#else
+#define DRI_SUPPORTS_CLIP_NOTIFY 0
+#endif
+
+#if (DRIINFO_MAJOR_VERSION > 5 || \
+     (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 4))
+#define DRI_DRIVER_FRAMEBUFFER_MAP 1
+#else
+#define DRI_DRIVER_FRAMEBUFFER_MAP 0
+#endif
+
 static void RADEONDRITransitionTo2d(ScreenPtr pScreen);
 static void RADEONDRITransitionTo3d(ScreenPtr pScreen);
 static void RADEONDRITransitionMultiToSingle3d(ScreenPtr pScreen);
 static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen);
 
+static Bool radeon_dri_gart_init(ScreenPtr pScreen);
+
 #ifdef DAMAGE
 static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, RegionPtr pReg);
 
-#if (DRIINFO_MAJOR_VERSION > 5 ||		\
-     (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1))
+#if DRI_SUPPORTS_CLIP_NOTIFY
 static void RADEONDRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num);
 #endif
 #endif
@@ -352,6 +371,133 @@ static void RADEONDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
 #endif
 }
 
+
+uint32_t radeon_name_buffer(ScrnInfoPtr pScrn, struct radeon_memory *mem)
+{
+    RADEONInfoPtr  info  = RADEONPTR(pScrn);
+    struct drm_gem_flink flink;
+    int ret;
+	
+    if (mem && mem->kernel_bo_handle) {
+	if (!mem->kernel_name) {
+	    flink.handle = mem->kernel_bo_handle;
+	    ret = ioctl(info->dri->drmFD, DRM_IOCTL_GEM_FLINK, &flink);
+	    if (ret != 0) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "[drm] failed to name buffer %d\n", -errno);
+		return -1;
+	    }
+	    mem->kernel_name = flink.name;
+	}
+	return mem->kernel_name;
+    }
+    return -1;
+}
+
+static void radeon_update_sarea(ScrnInfoPtr pScrn, drm_radeon_sarea_t * sarea)
+{
+    RADEONInfoPtr  info  = RADEONPTR(pScrn);
+    int cpp = info->CurrentLayout.pixel_bytes;
+    sarea->front_handle = -1;
+    sarea->back_handle = -1;
+    sarea->depth_handle = -1;
+   
+    if (info->drm_mm){
+	/* get handles and use them */
+	sarea->front_handle = radeon_name_buffer(pScrn, info->mm.front_buffer);
+
+	sarea->front_pitch         = info->dri->frontPitch * cpp;
+	sarea->back_pitch         = info->dri->backPitch * cpp;
+	sarea->depth_pitch         = info->dri->depthPitch * cpp;
+	ErrorF("front handle is %x\n", sarea->front_handle);
+	sarea->back_handle = radeon_name_buffer(pScrn, info->mm.back_buffer);
+	sarea->depth_handle = radeon_name_buffer(pScrn, info->mm.depth_buffer);
+
+    }
+}
+
+/* so we need to add a frontbuffer map no matter what */
+#define ROUND_TO(x, y)                 (((x) + (y) - 1) / (y) * (y))
+#define ROUND_TO_PAGE(x)               ROUND_TO((x), radeon_drm_page_size)
+
+static void
+radeon_update_screen_private(ScrnInfoPtr pScrn, drm_radeon_sarea_t * sarea)
+{
+    RADEONInfoPtr  info  = RADEONPTR(pScrn);
+    RADEONDRIPtr pRADEONDRI;
+
+    pRADEONDRI                    = (RADEONDRIPtr)info->dri->pDRIInfo->devPrivate;
+    info->dri->pDRIInfo->frameBufferPhysicalAddress = (char *) info->LinearAddr;
+    info->dri->pDRIInfo->frameBufferStride = pScrn->displayWidth * info->CurrentLayout.pixel_bytes;
+    info->dri->pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * info->CurrentLayout.pixel_bytes);
+#if DRI_DRIVER_FRAMEBUFFER_MAP
+    info->dri->pDRIInfo->hFrameBuffer = info->fb_map_handle;
+#endif
+    /* overload these */
+    pRADEONDRI->gartTexHandle = radeon_name_buffer(pScrn, info->mm.gart_texture_buffer);
+    pRADEONDRI->textureOffset = radeon_name_buffer(pScrn, info->mm.texture_buffer);
+    pRADEONDRI->frontOffset = radeon_name_buffer(pScrn, info->mm.front_buffer);
+    pRADEONDRI->backOffset = radeon_name_buffer(pScrn, info->mm.back_buffer);
+    pRADEONDRI->depthOffset = radeon_name_buffer(pScrn, info->mm.depth_buffer);
+}
+
+static Bool
+radeon_update_dri_mappings(ScrnInfoPtr pScrn, drm_radeon_sarea_t * sarea)
+{
+    RADEONInfoPtr  info  = RADEONPTR(pScrn);
+    uint32_t fb_addr, fb_size;
+    int ret;
+
+    if (!info->drm_mm)
+	return TRUE;
+
+
+    fb_addr = info->mm.front_buffer->offset + info->LinearAddr;
+    fb_size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * info->CurrentLayout.pixel_bytes);
+
+    if (info->fb_map_handle) {
+	drmRmMap(info->dri->drmFD, info->fb_map_handle);
+	info->fb_map_handle = 0;
+    }
+	
+    ret = drmAddMap(info->dri->drmFD, fb_addr, fb_size, DRM_FRAME_BUFFER, 0,
+		    &info->fb_map_handle);
+
+    ErrorF("adding fb map from %x for %x ret %d %x\n", fb_addr, fb_size, ret, info->fb_map_handle);
+
+    if (ret < 0)
+	return FALSE;
+
+    return TRUE;
+}
+
+Bool radeon_update_dri_buffers(ScreenPtr pScreen)
+{
+    ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];
+    RADEONInfoPtr  info  = RADEONPTR(pScrn);
+    Bool success;
+    drm_radeon_sarea_t *sarea;
+
+    if (info->ChipFamily >= CHIP_FAMILY_R600)
+	return TRUE;
+
+    if (!info->drm_mm)
+	return TRUE;
+
+    if (info->dri2.enabled)
+	return TRUE;
+
+    sarea = DRIGetSAREAPrivate(pScreen);
+    success = radeon_update_dri_mappings(pScrn, sarea);
+
+    if (!success)
+	return FALSE;
+
+    radeon_update_sarea(pScrn, sarea);
+    radeon_update_screen_private(pScrn, sarea);
+    return TRUE;
+}
+
 /* Called when the X server is woken up to allow the last client's
  * context to be saved and the X server's context to be loaded.  This is
  * not necessary for the Radeon since the client detects when it's
@@ -701,25 +847,35 @@ static void RADEONDRIInitGARTValues(RADEONInfoPtr info)
 
     info->dri->gartOffset = 0;
 
-				/* Initialize the CP ring buffer data */
-    info->dri->ringStart       = info->dri->gartOffset;
-    info->dri->ringMapSize     = info->dri->ringSize*1024*1024 + radeon_drm_page_size;
-    info->dri->ringSizeLog2QW  = RADEONMinBits(info->dri->ringSize*1024*1024/8)-1;
-
-    info->dri->ringReadOffset  = info->dri->ringStart + info->dri->ringMapSize;
-    info->dri->ringReadMapSize = radeon_drm_page_size;
-
-				/* Reserve space for vertex/indirect buffers */
-    info->dri->bufStart        = info->dri->ringReadOffset + info->dri->ringReadMapSize;
-    info->dri->bufMapSize      = info->dri->bufSize*1024*1024;
-
-				/* Reserve the rest for GART textures */
-    info->dri->gartTexStart     = info->dri->bufStart + info->dri->bufMapSize;
-    s = (info->dri->gartSize*1024*1024 - info->dri->gartTexStart);
-    l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);
-    if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
-    info->dri->gartTexMapSize   = (s >> l) << l;
-    info->dri->log2GARTTexGran  = l;
+    if (!info->drm_mm) {
+	/* Initialize the CP ring buffer data */
+	info->dri->ringStart       = info->dri->gartOffset;
+	info->dri->ringMapSize     = info->dri->ringSize*1024*1024 + radeon_drm_page_size;
+	info->dri->ringSizeLog2QW  = RADEONMinBits(info->dri->ringSize*1024*1024/8)-1;
+
+	info->dri->ringReadOffset  = info->dri->ringStart + info->dri->ringMapSize;
+	info->dri->ringReadMapSize = radeon_drm_page_size;
+
+	/* Reserve space for vertex/indirect buffers */
+	info->dri->bufStart        = info->dri->ringReadOffset + info->dri->ringReadMapSize;
+	info->dri->bufMapSize      = info->dri->bufSize*1024*1024;
+
+	/* Reserve the rest for GART textures */
+	info->dri->gartTexStart     = info->dri->bufStart + info->dri->bufMapSize;
+	s = (info->dri->gartSize*1024*1024 - info->dri->gartTexStart);
+	l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);
+	if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
+	info->dri->gartTexMapSize   = (s >> l) << l;
+	info->dri->log2GARTTexGran  = l;
+    } else {
+      s = (8*1024*1024);
+      l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);
+      l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);
+      if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
+      info->dri->gartTexMapSize   = (s >> l) << l;
+      info->dri->log2GARTTexGran  = l;
+    }
+
 }
 
 /* AGP Mode Quirk List - Certain hostbridge/gfx-card combos don't work with
@@ -990,6 +1146,8 @@ static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen)
 	       "[agp] ring handle = 0x%08x\n",
 	       (unsigned int)info->dri->ringHandle);
 
+
+#if 0
     if (drmMap(info->dri->drmFD, info->dri->ringHandle, info->dri->ringMapSize,
 	       &info->dri->ring) < 0) {
 	xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not map ring\n");
@@ -998,9 +1156,10 @@ static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen)
     xf86DrvMsg(pScreen->myNum, X_INFO,
 	       "[agp] Ring mapped at 0x%08lx\n",
 	       (unsigned long)info->dri->ring);
-
+#endif
     if (drmAddMap(info->dri->drmFD, info->dri->ringReadOffset, info->dri->ringReadMapSize,
 		  DRM_AGP, DRM_READ_ONLY, &info->dri->ringReadPtrHandle) < 0) {
+
 	xf86DrvMsg(pScreen->myNum, X_ERROR,
 		   "[agp] Could not add ring read ptr mapping\n");
 	return FALSE;
@@ -1009,6 +1168,8 @@ static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen)
  	       "[agp] ring read ptr handle = 0x%08x\n",
 	       (unsigned int)info->dri->ringReadPtrHandle);
 
+
+#if 0
     if (drmMap(info->dri->drmFD, info->dri->ringReadPtrHandle, info->dri->ringReadMapSize,
 	       &info->dri->ringReadPtr) < 0) {
 	xf86DrvMsg(pScreen->myNum, X_ERROR,
@@ -1018,6 +1179,7 @@ static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen)
     xf86DrvMsg(pScreen->myNum, X_INFO,
 	       "[agp] Ring read ptr mapped at 0x%08lx\n",
 	       (unsigned long)info->dri->ringReadPtr);
+#endif
 
     if (drmAddMap(info->dri->drmFD, info->dri->bufStart, info->dri->bufMapSize,
 		  DRM_AGP, 0, &info->dri->bufHandle) < 0) {
@@ -1095,6 +1257,7 @@ static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen)
 	       "[pci] ring handle = 0x%08x\n",
 	       (unsigned int)info->dri->ringHandle);
 
+#if 0
     if (drmMap(info->dri->drmFD, info->dri->ringHandle, info->dri->ringMapSize,
 	       &info->dri->ring) < 0) {
 	xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Could not map ring\n");
@@ -1106,6 +1269,7 @@ static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen)
     xf86DrvMsg(pScreen->myNum, X_INFO,
 	       "[pci] Ring contents 0x%08lx\n",
 	       *(unsigned long *)(pointer)info->dri->ring);
+#endif
 
     if (drmAddMap(info->dri->drmFD, info->dri->ringReadOffset, info->dri->ringReadMapSize,
 		  DRM_SCATTER_GATHER, flags, &info->dri->ringReadPtrHandle) < 0) {
@@ -1117,8 +1281,10 @@ static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen)
  	       "[pci] ring read ptr handle = 0x%08x\n",
 	       (unsigned int)info->dri->ringReadPtrHandle);
 
+#if 0
     if (drmMap(info->dri->drmFD, info->dri->ringReadPtrHandle, info->dri->ringReadMapSize,
 	       &info->dri->ringReadPtr) < 0) {
+
 	xf86DrvMsg(pScreen->myNum, X_ERROR,
 		   "[pci] Could not map ring read ptr\n");
 	return FALSE;
@@ -1129,6 +1295,7 @@ static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen)
     xf86DrvMsg(pScreen->myNum, X_INFO,
 	       "[pci] Ring read ptr contents 0x%08lx\n",
 	       *(unsigned long *)(pointer)info->dri->ringReadPtr);
+#endif
 
     if (drmAddMap(info->dri->drmFD, info->dri->bufStart, info->dri->bufMapSize,
 		  DRM_SCATTER_GATHER, 0, &info->dri->bufHandle) < 0) {
@@ -1181,6 +1348,9 @@ static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen)
  */
 static Bool RADEONDRIMapInit(RADEONInfoPtr info, ScreenPtr pScreen)
 {
+
+    if (info->drm_mm)
+    	return TRUE;
 				/* Map registers */
     info->dri->registerSize = info->MMIOSize;
     if (drmAddMap(info->dri->drmFD, info->MMIOAddr, info->dri->registerSize,
@@ -1221,20 +1391,23 @@ static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen)
     drmInfo.fb_bpp              = info->CurrentLayout.pixel_code;
     drmInfo.depth_bpp           = (info->dri->depthBits - 8) * 2;
 
-    drmInfo.front_offset        = info->dri->frontOffset;
-    drmInfo.front_pitch         = info->dri->frontPitch * cpp;
-    drmInfo.back_offset         = info->dri->backOffset;
-    drmInfo.back_pitch          = info->dri->backPitch * cpp;
-    drmInfo.depth_offset        = info->dri->depthOffset;
-    drmInfo.depth_pitch         = info->dri->depthPitch * drmInfo.depth_bpp / 8;
-
-    drmInfo.fb_offset           = info->dri->fbHandle;
-    drmInfo.mmio_offset         = info->dri->registerHandle;
-    drmInfo.ring_offset         = info->dri->ringHandle;
-    drmInfo.ring_rptr_offset    = info->dri->ringReadPtrHandle;
-    drmInfo.buffers_offset      = info->dri->bufHandle;
-    drmInfo.gart_textures_offset= info->dri->gartTexHandle;
-
+    if (!info->drm_mm) {
+	drmInfo.front_offset        = info->dri->frontOffset;
+	drmInfo.front_pitch         = info->dri->frontPitch * cpp;
+	drmInfo.back_offset         = info->dri->backOffset;
+	drmInfo.back_pitch          = info->dri->backPitch * cpp;
+	drmInfo.depth_offset        = info->dri->depthOffset;
+	drmInfo.depth_pitch         = info->dri->depthPitch * drmInfo.depth_bpp / 8;
+
+	drmInfo.fb_offset           = info->dri->fbHandle;
+	drmInfo.mmio_offset         = info->dri->registerHandle;
+	drmInfo.ring_offset         = info->dri->ringHandle;
+	drmInfo.ring_rptr_offset    = info->dri->ringReadPtrHandle;
+	drmInfo.buffers_offset      = info->dri->bufHandle;
+	drmInfo.gart_textures_offset= info->dri->gartTexHandle;
+    } else {
+    }
+	
     if (drmCommandWrite(info->dri->drmFD, DRM_RADEON_CP_INIT,
 			&drmInfo, sizeof(drm_radeon_init_t)) < 0)
 	return FALSE;
@@ -1243,8 +1416,9 @@ static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen)
      * registers back to their default values, so we need to restore
      * those engine register here.
      */
-    if (info->ChipFamily < CHIP_FAMILY_R600)
-	RADEONEngineRestore(pScrn);
+    if (!info->drm_mm)
+        if (info->ChipFamily < CHIP_FAMILY_R600)
+	    RADEONEngineRestore(pScrn);
 
     return TRUE;
 }
@@ -1442,12 +1616,11 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pScrn)
 
     /* Get DRM version & close DRM */
     info->dri->pKernelDRMVersion = drmGetVersion(fd);
-    drmClose(fd);
     if (info->dri->pKernelDRMVersion == NULL) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "[dri] RADEONDRIGetVersion failed to get the DRM version\n"
 		   "[dri] Disabling DRI.\n");
-	return FALSE;
+	goto fail;
     }
 
     /* Now check if we qualify */
@@ -1481,10 +1654,29 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pScrn)
 		   req_patch);
 	drmFreeVersion(info->dri->pKernelDRMVersion);
 	info->dri->pKernelDRMVersion = NULL;
-	return FALSE;
+	goto fail;
+    }
+
+    if (info->dri->pKernelDRMVersion->version_minor >= 30) {
+	    struct drm_radeon_gem_info mminfo;
+
+	    if (!drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo)))
+	    {
+		    info->drm_mm = TRUE;
+		    info->mm.vram_start = mminfo.vram_start;
+		    info->mm.vram_size = mminfo.vram_size;
+		    info->mm.gart_start = mminfo.vram_start;
+		    info->mm.gart_size = mminfo.gart_size;
+		    ErrorF("initing %llx %llx %llx %llx\n", mminfo.gart_start,
+			   mminfo.gart_size, mminfo.vram_start, mminfo.vram_size);
+	    }
     }
 
+    drmClose(fd);
     return TRUE;
+fail:
+    drmClose(fd);
+    return FALSE;
 }
 
 Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on)
@@ -1493,6 +1685,9 @@ Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on)
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     int value = 0;
 
+    if (info->drm_mode_setting)
+	return TRUE;
+
     if (!info->want_vblank_interrupts)
         on = FALSE;
 
@@ -1512,6 +1707,52 @@ Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on)
     return TRUE;
 }
 
+Bool RADEONDRIDoMappings(ScreenPtr pScreen)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    RADEONInfoPtr  info    = RADEONPTR(pScrn);
+    drm_radeon_sarea_t *  pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+				/* DRIScreenInit doesn't add all the
+				 * common mappings.  Add additional
+				 * mappings here.
+				 */
+
+    if (info->ChipFamily >= CHIP_FAMILY_R600)
+	return TRUE;
+
+    if (info->dri2.enabled)
+	return TRUE;
+
+    pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+    if (!RADEONDRIMapInit(info, pScreen)) {
+	RADEONDRICloseScreen(pScreen);
+	return FALSE;
+    }
+    
+    radeon_update_sarea(pScrn, pSAREAPriv);
+    
+				/* DRIScreenInit adds the frame buffer
+				   map, but we need it as well */
+    {
+	void *scratch_ptr;
+        int scratch_int;
+
+	DRIGetDeviceInfo(pScreen, &info->dri->fbHandle,
+                         &scratch_int, &scratch_int,
+                         &scratch_int, &scratch_int,
+                         &scratch_ptr);
+    }
+
+				/* FIXME: When are these mappings unmapped? */
+
+    if (!RADEONInitVisualConfigs(pScreen)) {
+	RADEONDRICloseScreen(pScreen);
+	return FALSE;
+    }
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Visual configs initialized\n");
+    return TRUE;
+
+}
 
 /* Initialize the screen-specific data structures for the DRI and the
  * Radeon.  This is the main entry point to the device-specific
@@ -1575,10 +1816,22 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
     pDRIInfo->ddxDriverMajorVersion      = info->allowColorTiling ? 5 : 4;
     pDRIInfo->ddxDriverMinorVersion      = 3;
     pDRIInfo->ddxDriverPatchVersion      = 0;
-    pDRIInfo->frameBufferPhysicalAddress = (void *)info->LinearAddr + info->dri->frontOffset;
-    pDRIInfo->frameBufferSize            = info->FbMapSize - info->FbSecureSize;
-    pDRIInfo->frameBufferStride          = (pScrn->displayWidth *
-					    info->CurrentLayout.pixel_bytes);
+
+#if DRI_DRIVER_FRAMEBUFFER_MAP
+    if (info->drm_mm) {
+	pDRIInfo->frameBufferPhysicalAddress = 0;
+	pDRIInfo->frameBufferSize = 0;
+	pDRIInfo->frameBufferStride = 0;
+	pDRIInfo->dontMapFrameBuffer = TRUE;
+    } else
+#endif
+    {
+	pDRIInfo->frameBufferPhysicalAddress = (void *)info->LinearAddr + info->dri->frontOffset;
+	pDRIInfo->frameBufferSize            = info->FbMapSize - info->FbSecureSize;
+	pDRIInfo->frameBufferStride          = (pScrn->displayWidth *
+						    info->CurrentLayout.pixel_bytes);
+    }
+
     pDRIInfo->ddxDrawableTableEntry      = RADEON_MAX_DRAWABLES;
     pDRIInfo->maxDrawableTableEntry      = (SAREA_MAX_DRAWABLES
 					    < RADEON_MAX_DRAWABLES
@@ -1631,9 +1884,7 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
     pDRIInfo->TransitionTo3d = RADEONDRITransitionTo3d;
     pDRIInfo->TransitionSingleToMulti3D = RADEONDRITransitionSingleToMulti3d;
     pDRIInfo->TransitionMultiToSingle3D = RADEONDRITransitionMultiToSingle3d;
-#if defined(DAMAGE) && (DRIINFO_MAJOR_VERSION > 5 ||	\
-			(DRIINFO_MAJOR_VERSION == 5 &&	\
-			 DRIINFO_MINOR_VERSION >= 1))
+#if DRI_SUPPORT_CLIP_NOTIFY
     pDRIInfo->ClipNotify     = RADEONDRIClipNotify;
 #endif
 
@@ -1665,57 +1916,60 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
 	pDRIInfo = NULL;
 	return FALSE;
     }
-				/* Initialize AGP */
-    if (info->cardType==CARD_AGP && !RADEONDRIAgpInit(info, pScreen)) {
-	xf86DrvMsg(pScreen->myNum, X_ERROR,
-		   "[agp] AGP failed to initialize. Disabling the DRI.\n" );
-	xf86DrvMsg(pScreen->myNum, X_INFO,
-		   "[agp] You may want to make sure the agpgart kernel "
-		   "module\nis loaded before the radeon kernel module.\n");
-	RADEONDRICloseScreen(pScreen);
-	return FALSE;
-    }
 
-				/* Initialize PCI */
-    if ((info->cardType!=CARD_AGP) && !RADEONDRIPciInit(info, pScreen)) {
-	xf86DrvMsg(pScreen->myNum, X_ERROR,
-		   "[pci] PCI failed to initialize. Disabling the DRI.\n" );
-	RADEONDRICloseScreen(pScreen);
-	return FALSE;
-    }
+    /* Now, nuke dri.c's dummy frontbuffer map setup if we did that. */
+    if (pDRIInfo->frameBufferSize != 0 && info->drm_mm) {
+	int tmp;
+	drm_handle_t fb_handle;
+	void *ptmp;
 
-				/* DRIScreenInit doesn't add all the
-				 * common mappings.  Add additional
-				 * mappings here.
-				 */
-    if (!RADEONDRIMapInit(info, pScreen)) {
-	RADEONDRICloseScreen(pScreen);
-	return FALSE;
-    }
-
-				/* DRIScreenInit adds the frame buffer
-				   map, but we need it as well */
-    {
-	void *scratch_ptr;
-        int scratch_int;
-
-	DRIGetDeviceInfo(pScreen, &info->dri->fbHandle,
-                         &scratch_int, &scratch_int,
-                         &scratch_int, &scratch_int,
-                         &scratch_ptr);
-    }
-
-				/* FIXME: When are these mappings unmapped? */
-
-    if (!RADEONInitVisualConfigs(pScreen)) {
-	RADEONDRICloseScreen(pScreen);
-	return FALSE;
+	/* With the compat method, it will continue to report
+	 * the wrong map out of GetDeviceInfo, which will break AIGLX.
+	 */
+	DRIGetDeviceInfo(pScreen, &fb_handle, &tmp, &tmp, &tmp, &tmp, &ptmp);
+	drmRmMap(info->dri->drmFD, fb_handle);
+
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "Removed DRI frontbuffer mapping in compatibility mode.\n");
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "DRIGetDeviceInfo will report incorrect frontbuffer "
+		   "handle.\n");
+    }
+   
+    if (info->drm_mm) {
+	int ret;
+	ret = radeon_dri_gart_init(pScreen);
+	if (!ret) {
+	    xf86DrvMsg(pScreen->myNum, X_ERROR,
+		       "[gart] GART failed to initialize. Disabling the DRI.\n" );
+	    RADEONDRICloseScreen(pScreen);
+	    return FALSE;
+	}
+    } else {
+	if (info->cardType==CARD_AGP && !RADEONDRIAgpInit(info, pScreen)) {
+	    /* Initialize AGP */
+	    xf86DrvMsg(pScreen->myNum, X_ERROR,
+		       "[agp] AGP failed to initialize. Disabling the DRI.\n" );
+	    xf86DrvMsg(pScreen->myNum, X_INFO,
+		       "[agp] You may want to make sure the agpgart kernel "
+		       "module\nis loaded before the radeon kernel module.\n");
+	    RADEONDRICloseScreen(pScreen);
+	    return FALSE;
+	}
+	
+				/* Initialize PCI */
+	if ((info->cardType!=CARD_AGP) && !RADEONDRIPciInit(info, pScreen)) {
+	    xf86DrvMsg(pScreen->myNum, X_ERROR,
+		       "[pci] PCI failed to initialize. Disabling the DRI.\n" );
+	    RADEONDRICloseScreen(pScreen);
+	    return FALSE;
+	}
     }
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Visual configs initialized\n");
 
     return TRUE;
 }
 
+
 static Bool RADEONDRIDoCloseScreen(int scrnIndex, ScreenPtr pScreen)
 {
     ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];
@@ -1757,17 +2011,21 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen)
 	return FALSE;
     }
 
-    /* Initialize the vertex buffers list */
-    if (!RADEONDRIBufInit(info, pScreen)) {
-	RADEONDRICloseScreen(pScreen);
-	return FALSE;
+    if (!info->drm_mm) {
+	/* Initialize the vertex buffers list */
+	if (!RADEONDRIBufInit(info, pScreen)) {
+	    RADEONDRICloseScreen(pScreen);
+	    return FALSE;
+	}
     }
 
-    /* Initialize IRQ */
-    RADEONDRIIrqInit(info, pScreen);
+    if (!info->drm_mode_setting) {
+	/* Initialize IRQ */
+	RADEONDRIIrqInit(info, pScreen);
+        /* Initialize kernel GART memory manager */
+        RADEONDRIGartHeapInit(info, pScreen);
+    }
 
-    /* Initialize kernel GART memory manager */
-    RADEONDRIGartHeapInit(info, pScreen);
 
     /* Initialize and start the CP if required */
     RADEONDRICPInit(pScrn);
@@ -1776,6 +2034,10 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen)
     pSAREAPriv = (drm_radeon_sarea_t*)DRIGetSAREAPrivate(pScreen);
     memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
 
+    if (info->drm_mm) {
+	/* init the handles into the sarea */
+	
+    }
     pRADEONDRI                    = (RADEONDRIPtr)info->dri->pDRIInfo->devPrivate;
 
     pRADEONDRI->deviceID          = info->Chipset;
@@ -1933,6 +2195,8 @@ void RADEONDRICloseScreen(ScreenPtr pScreen)
 	drmUnmap(info->dri->buf, info->dri->bufMapSize);
 	info->dri->buf = NULL;
     }
+
+#if 0
     if (info->dri->ringReadPtr) {
 	drmUnmap(info->dri->ringReadPtr, info->dri->ringReadMapSize);
 	info->dri->ringReadPtr = NULL;
@@ -1941,6 +2205,7 @@ void RADEONDRICloseScreen(ScreenPtr pScreen)
 	drmUnmap(info->dri->ring, info->dri->ringMapSize);
 	info->dri->ring = NULL;
     }
+#endif
     if (info->dri->agpMemHandle != DRM_AGP_NO_HANDLE) {
 	drmAgpUnbind(info->dri->drmFD, info->dri->agpMemHandle);
 	drmAgpFree(info->dri->drmFD, info->dri->agpMemHandle);
@@ -2346,3 +2611,11 @@ int RADEONDRISetParam(ScrnInfoPtr pScrn, unsigned int param, int64_t value)
 			  &radeonsetparam, sizeof(drm_radeon_setparam_t));
     return ret;
 }
+
+static Bool radeon_dri_gart_init(ScreenPtr pScreen)
+{
+    ScrnInfoPtr    pScrn   = xf86Screens[pScreen->myNum];
+    RADEONInfoPtr  info    = RADEONPTR(pScrn);
+
+    RADEONDRIInitGARTValues(info);
+}
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
new file mode 100644
index 0000000..eb15ff2
--- /dev/null
+++ b/src/radeon_dri2.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2008 Kristian Høgsberg 
+ * Copyright 2008 JĂŠrĂ´me Glisse
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "radeon.h"
+#include "radeon_dri2.h"
+#include "radeon_version.h"
+
+#ifdef DRI2
+
+struct dri2_buffer_priv {
+    PixmapPtr   pixmap;
+};
+
+
+static DRI2BufferPtr
+radeon_dri2_create_buffers(DrawablePtr drawable,
+                           unsigned int *attachments,
+                           int count)
+{
+    ScreenPtr pScreen = drawable->pScreen;
+    DRI2BufferPtr buffers;
+    struct dri2_buffer_priv *privates;
+    PixmapPtr pixmap, depth_pixmap;
+    struct radeon_exa_pixmap_priv *driver_priv;
+    int i, r;
+
+    buffers = xcalloc(count, sizeof *buffers);
+    if (buffers == NULL) {
+        return NULL;
+    }
+    privates = xcalloc(count, sizeof(struct dri2_buffer_priv));
+    if (privates == NULL) {
+        xfree(buffers);
+        return NULL;
+    }
+
+    depth_pixmap = NULL;
+    for (i = 0; i < count; i++) {
+        if (attachments[i] == DRI2BufferFrontLeft) {
+            if (drawable->type == DRAWABLE_PIXMAP) {
+                pixmap = (Pixmap*)drawable;
+            } else {
+                pixmap = (*pScreen->GetWindowPixmap)((WindowPtr)drawable);
+            }
+            pixmap->refcnt++;
+        } else if (attachments[i] == DRI2BufferStencil && depth_pixmap) {
+            pixmap = depth_pixmap;
+            pixmap->refcnt++;
+        } else {
+            pixmap = (*pScreen->CreatePixmap)(pScreen,
+                                              drawable->width,
+                                              drawable->height,
+                                              drawable->depth,
+                                              0);
+        }
+
+        if (attachments[i] == DRI2BufferDepth) {
+            depth_pixmap = pixmap;
+        }
+        driver_priv = exaGetPixmapDriverPrivate(pixmap);
+        r = radeon_bo_gem_name_buffer(driver_priv->bo, &buffers[i].name);
+        if (r) {
+            /* FIXME: cleanup */
+            fprintf(stderr, "flink error: %d %s\n", r, strerror(r));
+            xfree(buffers);
+            xfree(privates);
+            return NULL;
+        }
+        buffers[i].attachment = attachments[i];
+        buffers[i].pitch = pixmap->devKind;
+        buffers[i].cpp = pixmap->drawable.bitsPerPixel / 8;
+        buffers[i].driverPrivate = &privates[i];
+        buffers[i].flags = 0; /* not tiled */
+        privates[i].pixmap = pixmap;
+    }
+    return buffers;
+}
+
+static void
+radeon_dri2_destroy_buffers(DrawablePtr drawable,
+                            DRI2BufferPtr buffers,
+                            int count)
+{
+    ScreenPtr pScreen = drawable->pScreen;
+    struct dri2_buffer_priv *private;
+    int i;
+
+    for (i = 0; i < count; i++) {
+        private = buffers[i].driverPrivate;
+        (*pScreen->DestroyPixmap)(private->pixmap);
+    }
+    if (buffers) {
+        xfree(buffers[0].driverPrivate);
+        xfree(buffers);
+    }
+}
+
+static void
+radeon_dri2_copy_region(DrawablePtr drawable,
+                        RegionPtr region,
+                        DRI2BufferPtr dest_buffer,
+                        DRI2BufferPtr src_buffer)
+{
+    struct dri2_buffer_priv *private = src_buffer->driverPrivate;
+    ScreenPtr pScreen = drawable->pScreen;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    PixmapPtr pixmap = private->pixmap;
+    RegionPtr copy_clip;
+    GCPtr gc;
+
+    gc = GetScratchGC(drawable->depth, pScreen);
+    copy_clip = REGION_CREATE(pScreen, NULL, 0);
+    REGION_COPY(pScreen, copy_clip, region);
+    (*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0);
+    ValidateGC(drawable, gc);
+    (*gc->ops->CopyArea)(&pixmap->drawable, drawable, gc,
+                         0, 0, drawable->width, drawable->height, 0, 0);
+    FreeScratchGC(gc);
+    RADEONCPReleaseIndirect(pScrn);
+}
+
+Bool
+radeon_dri2_screen_init(ScreenPtr pScreen)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    DRI2InfoRec dri2_info;
+    int fd;
+    char *bus_id;
+    char *tmp_bus_id;
+    int cmp;
+    int i;
+
+    if (!info->useEXA) {
+        xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DRI2 requires EXA\n");
+        return FALSE;
+    }
+
+    /* The whole drmOpen thing is a fiasco and we need to find a way
+     * back to just using open(2).  For now, however, lets just make
+     * things worse with even more ad hoc directory walking code to
+     * discover the device file name. */
+    bus_id = DRICreatePCIBusID(info->PciInfo);
+    for (i = 0; i < DRM_MAX_MINOR; i++) {
+        sprintf(info->dri2.device_name, DRM_DEV_NAME, DRM_DIR_NAME, i);
+        fd = open(info->dri2.device_name, O_RDWR);
+        if (fd < 0)
+            continue;
+
+        tmp_bus_id = drmGetBusid(fd);
+        close(fd);
+        if (tmp_bus_id == NULL)
+            continue;
+
+        cmp = strcmp(tmp_bus_id, bus_id);
+        drmFree(tmp_bus_id);
+        if (cmp == 0)
+            break;
+    }
+    xfree(bus_id);
+
+    if (i == DRM_MAX_MINOR) {
+        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                   "DRI2: failed to open drm device\n");
+        return FALSE;
+    }
+
+    if ( (info->ChipFamily >= CHIP_FAMILY_R300) ) {
+        dri2_info.driverName = R300_DRIVER_NAME;
+    } else if ( info->ChipFamily >= CHIP_FAMILY_R200 ) {
+        dri2_info.driverName = R200_DRIVER_NAME;
+    } else {
+        dri2_info.driverName = RADEON_DRIVER_NAME;
+    }
+    dri2_info.fd = info->dri2.drm_fd;
+    dri2_info.deviceName = info->dri2.device_name;
+    dri2_info.version = 1;
+    dri2_info.CreateBuffers = radeon_dri2_create_buffers;
+    dri2_info.DestroyBuffers = radeon_dri2_destroy_buffers;
+    dri2_info.CopyRegion = radeon_dri2_copy_region;
+    info->dri2.enabled = DRI2ScreenInit(pScreen, &dri2_info);
+    return info->dri2.enabled;
+}
+
+void
+radeon_dri2_close_screen(ScreenPtr pScreen)
+{
+    DRI2CloseScreen(pScreen);
+}
+
+#endif
diff --git a/src/radeon_dri2.h b/src/radeon_dri2.h
new file mode 100644
index 0000000..9ad9cee
--- /dev/null
+++ b/src/radeon_dri2.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2008 Jerome Glisse
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifndef RADEON_DRI2_H
+#define RADEON_DRI2_H
+
+struct radeon_dri2 {
+    int         drm_fd;
+    Bool        enabled;
+    char        device_name[64];
+};
+
+#ifdef DRI2
+#include "dri2.h"
+Bool radeon_dri2_screen_init(ScreenPtr pScreen);
+void radeon_dri2_close_screen(ScreenPtr pScreen);
+#endif
+
+#endif
diff --git a/src/radeon_dri_bufmgr.c b/src/radeon_dri_bufmgr.c
new file mode 100644
index 0000000..f6154dc
--- /dev/null
+++ b/src/radeon_dri_bufmgr.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright Š 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "radeon_dri_bufmgr.h"
+
+/** @file dri_bufmgr.c
+ *
+ * Convenience functions for buffer management methods.
+ */
+
+dri_bo *
+dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size,
+	     unsigned int alignment, uint64_t location_mask)
+{
+   return bufmgr->bo_alloc(bufmgr, name, size, alignment, location_mask);
+}
+
+dri_bo *
+dri_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, unsigned long offset,
+		    unsigned long size, void *virtual,
+		    uint64_t location_mask)
+{
+   return bufmgr->bo_alloc_static(bufmgr, name, offset, size, virtual,
+				  location_mask);
+}
+
+void
+dri_bo_reference(dri_bo *bo)
+{
+   bo->bufmgr->bo_reference(bo);
+}
+
+void
+dri_bo_unreference(dri_bo *bo)
+{
+   if (bo == NULL)
+      return;
+
+   bo->bufmgr->bo_unreference(bo);
+}
+
+int
+dri_bo_map(dri_bo *buf, int write_enable)
+{
+   return buf->bufmgr->bo_map(buf, write_enable);
+}
+
+int
+dri_bo_unmap(dri_bo *buf)
+{
+   return buf->bufmgr->bo_unmap(buf);
+}
+
+void
+dri_fence_wait(dri_fence *fence)
+{
+   fence->bufmgr->fence_wait(fence);
+}
+
+void
+dri_fence_reference(dri_fence *fence)
+{
+   fence->bufmgr->fence_reference(fence);
+}
+
+void
+dri_fence_unreference(dri_fence *fence)
+{
+   if (fence == NULL)
+      return;
+
+   fence->bufmgr->fence_unreference(fence);
+}
+
+void
+dri_bo_subdata(dri_bo *bo, unsigned long offset,
+	       unsigned long size, const void *data)
+{
+   if (size == 0 || data == NULL)
+      return;
+
+   dri_bo_map(bo, 1);
+   memcpy((unsigned char *)bo->virtual + offset, data, size);
+   dri_bo_unmap(bo);
+}
+
+void
+dri_bo_get_subdata(dri_bo *bo, unsigned long offset,
+		   unsigned long size, void *data)
+{
+   if (size == 0 || data == NULL)
+      return;
+
+   dri_bo_map(bo, 0);
+   memcpy(data, (unsigned char *)bo->virtual + offset, size);
+   dri_bo_unmap(bo);
+}
+
+void
+dri_bufmgr_destroy(dri_bufmgr *bufmgr)
+{
+   bufmgr->destroy(bufmgr);
+}
+
+
+int dri_emit_reloc(dri_bo *reloc_buf, uint64_t flags, uint32_t delta,
+		    uint32_t offset, dri_bo *target_buf)
+{
+   return reloc_buf->bufmgr->emit_reloc(reloc_buf, flags, delta, offset, target_buf);
+}
+
+void *dri_process_relocs(dri_bo *batch_buf, uint32_t *count)
+{
+   return batch_buf->bufmgr->process_relocs(batch_buf, count);
+}
+
+void dri_post_submit(dri_bo *batch_buf, dri_fence **last_fence)
+{
+   batch_buf->bufmgr->post_submit(batch_buf, last_fence);
+}
+
+void
+dri_bufmgr_set_debug(dri_bufmgr *bufmgr, int enable_debug)
+{
+   bufmgr->debug = enable_debug;
+}
+
+int
+dri_bufmgr_check_aperture_space(struct radeon_space_check *bos, int num_bo)
+{
+  if (num_bo == 0)
+    return BUFMGR_SPACE_OK;
+
+  return bos[0].buf->bufmgr->check_aperture_space(bos, num_bo);
+}
+
+int dri_bo_pin(dri_bo *bo, int domain)
+{
+    return bo->bufmgr->pin(bo, domain);
+}
+
+void dri_bo_unpin(dri_bo *bo)
+{
+    bo->bufmgr->unpin(bo);
+}
+
+uint32_t dri_bo_get_handle(dri_bo *bo)
+{
+    return bo->bufmgr->get_handle(bo);
+}
diff --git a/src/radeon_dri_bufmgr.h b/src/radeon_dri_bufmgr.h
new file mode 100644
index 0000000..a19d7ec
--- /dev/null
+++ b/src/radeon_dri_bufmgr.h
@@ -0,0 +1,291 @@
+/**************************************************************************
+ * 
+ * Copyright Š 2007 Intel Corporation
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * 
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ *          Keith Whitwell <keithw-at-tungstengraphics-dot-com>
+ *	    Eric Anholt <eric@anholt.net>
+ */
+
+#ifndef _DRI_BUFMGR_H_
+#define _DRI_BUFMGR_H_
+#include <xf86drm.h>
+
+typedef struct _dri_bufmgr dri_bufmgr;
+typedef struct _dri_bo dri_bo;
+typedef struct _dri_fence dri_fence;
+
+#define BUFMGR_SPACE_OK 0
+#define BUFMGR_SPACE_OP_TO_BIG 1
+#define BUFMGR_SPACE_FLUSH 2
+struct radeon_space_check {
+	dri_bo *buf;
+	uint32_t read_domains;
+	uint32_t write_domain;
+	uint32_t new_accounted;
+};
+
+/* reloc format */
+/* gem handle, read_domains, write_domain, reloc_count */
+#define RADEON_RELOC_SIZE 4
+struct radeon_relocs_info {
+    uint32_t *buf;
+    dri_bo **bo_list;
+    int size;
+    int max_bo;
+    int num_reloc;
+};
+
+struct _dri_bo {
+   /** Size in bytes of the buffer object. */
+   unsigned long size;
+   /**
+    * Card virtual address (offset from the beginning of the aperture) for the
+    * object.  Only valid while validated.
+    */
+   unsigned long offset;
+   /**
+    * Virtual address for accessing the buffer data.  Only valid while mapped.
+    */
+   void *virtual;
+   /** Buffer manager context associated with this buffer object */
+   dri_bufmgr *bufmgr;
+};
+
+struct _dri_fence {
+   /**
+    * This is an ORed mask of DRM_BO_FLAG_READ, DRM_BO_FLAG_WRITE, and
+    * DRM_FLAG_EXE indicating the operations associated with this fence.
+    *
+    * It is constant for the life of the fence object.
+    */
+   unsigned int type;
+   /** Buffer manager context associated with this fence */
+   dri_bufmgr *bufmgr;
+};
+
+/**
+ * Context for a buffer manager instance.
+ *
+ * Contains public methods followed by private storage for the buffer manager.
+ */
+struct _dri_bufmgr {
+   /**
+    * Allocate a buffer object.
+    *
+    * Buffer objects are not necessarily initially mapped into CPU virtual
+    * address space or graphics device aperture.  They must be mapped using
+    * bo_map() to be used by the CPU, and validated for use using bo_validate()
+    * to be used from the graphics device.
+    */
+   dri_bo *(*bo_alloc)(dri_bufmgr *bufmgr_ctx, const char *name,
+		       unsigned long size, unsigned int alignment,
+		       uint64_t location_mask);
+
+   /**
+    * Allocates a buffer object for a static allocation.
+    *
+    * Static allocations are ones such as the front buffer that are offered by
+    * the X Server, which are never evicted and never moved.
+    */
+   dri_bo *(*bo_alloc_static)(dri_bufmgr *bufmgr_ctx, const char *name,
+			      unsigned long offset, unsigned long size,
+			      void *virtual, uint64_t location_mask);
+
+   /** Takes a reference on a buffer object */
+   void (*bo_reference)(dri_bo *bo);
+
+   /**
+    * Releases a reference on a buffer object, freeing the data if
+    * rerefences remain.
+    */
+   void (*bo_unreference)(dri_bo *bo);
+
+   /**
+    * Maps the buffer into userspace.
+    *
+    * This function will block waiting for any existing fence on the buffer to
+    * clear, first.  The resulting mapping is available at buf->virtual.
+\    */
+   int (*bo_map)(dri_bo *buf, int write_enable);
+
+   /** Reduces the refcount on the userspace mapping of the buffer object. */
+   int (*bo_unmap)(dri_bo *buf);
+
+   /** Takes a reference on a fence object */
+   void (*fence_reference)(dri_fence *fence);
+
+   /**
+    * Releases a reference on a fence object, freeing the data if
+    * rerefences remain.
+    */
+   void (*fence_unreference)(dri_fence *fence);
+
+   /**
+    * Blocks until the given fence is signaled.
+    */
+   void (*fence_wait)(dri_fence *fence);
+
+   /**
+    * Tears down the buffer manager instance.
+    */
+   void (*destroy)(dri_bufmgr *bufmgr);
+
+   /**
+    * Add relocation entry in reloc_buf, which will be updated with the
+    * target buffer's real offset on on command submission.
+    *
+    * Relocations remain in place for the lifetime of the buffer object.
+    *
+    * \param reloc_buf Buffer to write the relocation into.
+    * \param flags BO flags to be used in validating the target buffer.
+    *	     Applicable flags include:
+    *	     - DRM_BO_FLAG_READ: The buffer will be read in the process of
+    *	       command execution.
+    *	     - DRM_BO_FLAG_WRITE: The buffer will be written in the process of
+    *	       command execution.
+    *	     - DRM_BO_FLAG_MEM_TT: The buffer should be validated in TT memory.
+    *	     - DRM_BO_FLAG_MEM_VRAM: The buffer should be validated in video
+    *	       memory.
+    * \param delta Constant value to be added to the relocation target's offset.
+    * \param offset Byte offset within batch_buf of the relocated pointer.
+    * \param target Buffer whose offset should be written into the relocation
+    *	     entry.
+    */
+   int (*emit_reloc)(dri_bo *reloc_buf, uint64_t flags, uint32_t delta,
+		      uint32_t offset, dri_bo *target);
+
+   /**
+    * Processes the relocations, either in userland or by converting the list
+    * for use in batchbuffer submission.
+    *
+    * Kernel-based implementations will return a pointer to the arguments
+    * to be handed with batchbuffer submission to the kernel.  The userland
+    * implementation performs the buffer validation and emits relocations
+    * into them the appopriate order.
+    *
+    * \param batch_buf buffer at the root of the tree of relocations
+    * \param count returns the number of buffers validated.
+    * \return relocation record for use in command submission.
+    * */
+   void *(*process_relocs)(dri_bo *batch_buf, uint32_t *count);
+
+   void (*post_submit)(dri_bo *batch_buf, dri_fence **fence);
+
+   int (*check_aperture_space)(struct radeon_space_check *bos, int num_bo);
+
+   int (*pin)(dri_bo *bo, int domain);
+   void (*unpin)(dri_bo *bo);
+
+   uint32_t (*get_handle)(dri_bo *bo);
+   int debug; /**< Enables verbose debugging printouts */
+};
+
+dri_bo *dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size,
+		     unsigned int alignment, uint64_t location_mask);
+dri_bo *dri_bo_alloc_static(dri_bufmgr *bufmgr, const char *name,
+			    unsigned long offset, unsigned long size,
+			    void *virtual, uint64_t location_mask);
+void dri_bo_reference(dri_bo *bo);
+void dri_bo_unreference(dri_bo *bo);
+int dri_bo_map(dri_bo *buf, int write_enable);
+int dri_bo_unmap(dri_bo *buf);
+void dri_fence_wait(dri_fence *fence);
+void dri_fence_reference(dri_fence *fence);
+void dri_fence_unreference(dri_fence *fence);
+
+void dri_bo_subdata(dri_bo *bo, unsigned long offset,
+		    unsigned long size, const void *data);
+void dri_bo_get_subdata(dri_bo *bo, unsigned long offset,
+			unsigned long size, void *data);
+
+void dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr);
+dri_bufmgr *dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual,
+				 unsigned long size,
+				 unsigned int (*fence_emit)(void *private),
+				 int (*fence_wait)(void *private,
+						   unsigned int cookie),
+				 void *driver_priv);
+void dri_bufmgr_set_debug(dri_bufmgr *bufmgr, int enable_debug);
+void dri_bo_fake_disable_backing_store(dri_bo *bo,
+				       void (*invalidate_cb)(dri_bo *bo,
+							     void *ptr),
+				       void *ptr);
+void dri_bufmgr_destroy(dri_bufmgr *bufmgr);
+
+int dri_emit_reloc(dri_bo *reloc_buf, uint64_t flags, uint32_t delta,
+		   uint32_t offset, dri_bo *target_buf);
+void *dri_process_relocs(dri_bo *batch_buf, uint32_t *count);
+void dri_post_process_relocs(dri_bo *batch_buf);
+void dri_post_submit(dri_bo *batch_buf, dri_fence **last_fence);
+int dri_bufmgr_check_aperture_space(struct radeon_space_check *bos, int num_bo);
+
+int dri_bo_pin(dri_bo *bo, int domain);
+void dri_bo_unpin(dri_bo *bo);
+
+uint32_t dri_bo_get_handle(dri_bo *bo);
+
+#ifndef TTM_API
+/* reuse some TTM API */
+
+#define DRM_BO_MEM_LOCAL 0
+#define DRM_BO_MEM_TT 1
+#define DRM_BO_MEM_VRAM 2
+#define DRM_BO_MEM_PRIV0 3
+#define DRM_BO_MEM_PRIV1 4
+#define DRM_BO_MEM_PRIV2 5
+#define DRM_BO_MEM_PRIV3 6
+#define DRM_BO_MEM_PRIV4 7
+
+#define DRM_BO_FLAG_READ        (1ULL << 0)
+#define DRM_BO_FLAG_WRITE       (1ULL << 1)
+#define DRM_BO_FLAG_EXE         (1ULL << 2)
+#define DRM_BO_MASK_ACCESS	(DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE)
+#define DRM_BO_FLAG_NO_EVICT    (1ULL << 4)
+
+#define DRM_BO_FLAG_MAPPABLE    (1ULL << 5)
+#define DRM_BO_FLAG_SHAREABLE   (1ULL << 6)
+
+#define DRM_BO_FLAG_CACHED      (1ULL << 7)
+
+#define DRM_BO_FLAG_NO_MOVE     (1ULL << 8)
+#define DRM_BO_FLAG_CACHED_MAPPED    (1ULL << 19)
+#define DRM_BO_FLAG_FORCE_CACHING  (1ULL << 13)
+#define DRM_BO_FLAG_FORCE_MAPPABLE (1ULL << 14)
+#define DRM_BO_FLAG_TILE           (1ULL << 15)
+
+#define DRM_BO_FLAG_MEM_LOCAL  (1ULL << 24)
+#define DRM_BO_FLAG_MEM_TT     (1ULL << 25)
+#define DRM_BO_FLAG_MEM_VRAM   (1ULL << 26)
+
+#define DRM_BO_MASK_MEM         0x00000000FF000000ULL
+
+#define DRM_FENCE_TYPE_EXE                 0x00000001
+#endif
+
+#endif
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index e8d28f0..caea901 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -67,7 +67,7 @@
 
 #include <string.h>
 #include <stdio.h>
-
+#include <errno.h>
 				/* Driver data structures */
 #include "radeon.h"
 #include "radeon_reg.h"
@@ -225,7 +225,10 @@ radeonShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode,
     stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8;
     *size = stride;
 
-    return ((uint8_t *)info->FB + row * stride + offset);
+    if (info->drm_mm)
+        return ((uint8_t *)info->mm.front_buffer->map + row * stride + offset);
+    else
+        return ((uint8_t *)info->FB + row * stride + offset);
 }
 static Bool
 RADEONCreateScreenResources (ScreenPtr pScreen)
@@ -246,6 +249,13 @@ RADEONCreateScreenResources (ScreenPtr pScreen)
 		      radeonShadowWindow, 0, NULL))
 	   return FALSE;
    }
+
+   if (info->dri2.enabled) {
+       if (info->mm.front_buffer->kernel_bo_handle) {
+	   PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
+	   radeon_set_pixmap_bo(pPix, info->mm.front_buffer);
+       }
+   }
    return TRUE;
 }
 
@@ -1625,6 +1635,7 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn)
     }
 
     pScrn->videoRam  &= ~1023;
+
     info->FbMapSize  = pScrn->videoRam * 1024;
 
     /* if the card is PCI Express reserve the last 32k for the gart table */
@@ -1755,58 +1766,64 @@ static Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
     }
 
     from               = X_PROBED;
-    info->LinearAddr   = PCI_REGION_BASE(info->PciInfo, 0, REGION_MEM) & ~0x1ffffffULL;
+    info->LinearAddr   = PCI_REGION_BASE(info->PciInfo, 0, REGION_MEM) & ~0x1ffffffUL;
     pScrn->memPhysBase = info->LinearAddr;
-    if (dev->MemBase) {
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "Linear address override, using 0x%016lx instead of 0x%016llx\n",
-		   dev->MemBase,
-		   info->LinearAddr);
-	info->LinearAddr = dev->MemBase;
-	from             = X_CONFIG;
-    } else if (!info->LinearAddr) {
-	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		   "No valid linear framebuffer address\n");
-	return FALSE;
-    }
-    xf86DrvMsg(pScrn->scrnIndex, from,
-	       "Linear framebuffer at 0x%016llx\n", info->LinearAddr);
 
-#ifndef XSERVER_LIBPCIACCESS
-				/* BIOS */
-    from              = X_PROBED;
-    info->BIOSAddr    = info->PciInfo->biosBase & 0xfffe0000;
-    if (dev->BiosBase) {
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "BIOS address override, using 0x%08lx instead of 0x%08lx\n",
-		   (unsigned long)dev->BiosBase,
-		   (unsigned long)info->BIOSAddr);
-	info->BIOSAddr = dev->BiosBase;
-	from           = X_CONFIG;
-    }
-    if (info->BIOSAddr) {
+    if (!info->drm_mode_setting) {
+	from               = X_PROBED;
+	info->LinearAddr   = PCI_REGION_BASE(info->PciInfo, 0, REGION_MEM) & ~0x1ffffffUL;
+	pScrn->memPhysBase = info->LinearAddr;
+	if (dev->MemBase) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		       "Linear address override, using 0x%016lx instead of 0x%016llx\n",
+		       dev->MemBase,
+		       info->LinearAddr);
+	    info->LinearAddr = dev->MemBase;
+	    from             = X_CONFIG;
+	} else if (!info->LinearAddr) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "No valid linear framebuffer address\n");
+	    return FALSE;
+	}
 	xf86DrvMsg(pScrn->scrnIndex, from,
-		   "BIOS at 0x%08lx\n", (unsigned long)info->BIOSAddr);
-    }
+		   "Linear framebuffer at 0x%016llx\n", info->LinearAddr);
+
+#ifndef XSERVER_LIBPCIACCESS
+	/* BIOS */
+	from              = X_PROBED;
+	info->BIOSAddr    = info->PciInfo->biosBase & 0xfffe0000;
+	if (dev->BiosBase) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		       "BIOS address override, using 0x%08lx instead of 0x%08lx\n",
+		       dev->BiosBase,
+		       info->BIOSAddr);
+	    info->BIOSAddr = dev->BiosBase;
+	    from           = X_CONFIG;
+	}
+	if (info->BIOSAddr) {
+	    xf86DrvMsg(pScrn->scrnIndex, from,
+		       "BIOS at 0x%08lx\n", info->BIOSAddr);
+	}
 #endif
 
-				/* Read registers used to determine options */
-    /* Check chip errata */
-    info->ChipErrata = 0;
+	/* Read registers used to determine options */
+	/* Check chip errata */
+	info->ChipErrata = 0;
 
-    if (info->ChipFamily == CHIP_FAMILY_R300 &&
-	(INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK)
-	== RADEON_CFG_ATI_REV_A11)
+	if (info->ChipFamily == CHIP_FAMILY_R300 &&
+	    (INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK)
+	    == RADEON_CFG_ATI_REV_A11)
 	    info->ChipErrata |= CHIP_ERRATA_R300_CG;
-
-    if (info->ChipFamily == CHIP_FAMILY_RV200 ||
-	info->ChipFamily == CHIP_FAMILY_RS200)
+	
+	if (info->ChipFamily == CHIP_FAMILY_RV200 ||
+	    info->ChipFamily == CHIP_FAMILY_RS200)
 	    info->ChipErrata |= CHIP_ERRATA_PLL_DUMMYREADS;
-
-    if (info->ChipFamily == CHIP_FAMILY_RV100 ||
-	info->ChipFamily == CHIP_FAMILY_RS100 ||
-	info->ChipFamily == CHIP_FAMILY_RS200)
+	
+	if (info->ChipFamily == CHIP_FAMILY_RV100 ||
+	    info->ChipFamily == CHIP_FAMILY_RS100 ||
+	    info->ChipFamily == CHIP_FAMILY_RS200)
 	    info->ChipErrata |= CHIP_ERRATA_PLL_DELAY;
+    }
 
 #ifdef XF86DRI
 				/* AGP/PCI */
@@ -1998,6 +2015,9 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn)
     if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
 	int errmaj = 0, errmin = 0;
 
+#if defined(USE_EXA)
+	info->useEXA = TRUE;
+#endif
 	from = X_DEFAULT;
 #if defined(USE_EXA)
 #if defined(USE_XAA)
@@ -2008,6 +2028,7 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn)
 		info->useEXA = TRUE;
 	    } else if (xf86NameCmp(optstr, "XAA") == 0) {
 		from = X_CONFIG;
+		info->useEXA = FALSE;
 	    }
 	}
 #else /* USE_XAA */
@@ -2111,15 +2132,9 @@ static Bool RADEONPreInitInt10(ScrnInfoPtr pScrn, xf86Int10InfoPtr *ppInt10)
     return TRUE;
 }
 
-#ifdef XF86DRI
-static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn)
+static Bool radeon_alloc_dri(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info = RADEONPTR(pScrn);
-    MessageType    from;
-    char          *reason;
-
-    info->directRenderingEnabled = FALSE;
-    info->directRenderingInited = FALSE;
 
     if (!(info->dri = xcalloc(1, sizeof(struct radeon_dri)))) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Unable to allocate dri rec!\n");
@@ -2130,6 +2145,22 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn)
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Unable to allocate cp rec!\n");
 	return FALSE;
     }
+    return TRUE;
+}
+
+#ifdef XF86DRI
+static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+    MessageType    from;
+    char          *reason;
+
+    info->directRenderingEnabled = FALSE;
+    info->directRenderingInited = FALSE;
+
+    if (!radeon_alloc_dri(pScrn))
+	return FALSE;
+
     info->cp->CPInUse = FALSE;
     info->cp->CPStarted = FALSE;
     info->cp->CPusecTimeout = RADEON_DEFAULT_CP_TIMEOUT;
@@ -2692,6 +2723,37 @@ static const xf86CrtcConfigFuncsRec RADEONCRTCResizeFuncs = {
     RADEONCRTCResize
 };
 
+#ifdef XF86DRM_MODE
+static Bool radeon_kernel_mode_enabled(ScrnInfoPtr pScrn)
+{
+#if XSERVER_LIBPCIACCESS
+    struct pci_device *PciInfo;
+#else
+    pciVideoPtr PciInfo;
+#endif
+    EntityInfoPtr pEnt;
+    char *busIdString;
+    int ret;
+
+    pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+    PciInfo = xf86GetPciInfoForEntity(pEnt->index);
+
+    if (!xf86LoaderCheckSymbol("DRICreatePCIBusID"))
+	return FALSE;
+
+    busIdString = DRICreatePCIBusID(PciInfo);
+    ret = drmCheckModesettingSupported(busIdString);
+    xfree(busIdString);
+    if (ret)
+	return FALSE;
+
+    return TRUE;
+}
+#else
+#define radeon_kernel_mode_enabled(x) FALSE
+#endif
+
+
 Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
 {
     xf86CrtcConfigPtr   xf86_config;
@@ -2712,6 +2774,8 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
     info               = RADEONPTR(pScrn);
     info->MMIO         = NULL;
 
+    info->drm_mode_setting = radeon_kernel_mode_enabled(pScrn);
+
     info->IsSecondary  = FALSE;
     info->IsPrimary = FALSE;
 
@@ -2746,62 +2810,63 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
     }
 
     info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
-    info->PciTag  = pciTag(PCI_DEV_BUS(info->PciInfo),
-			   PCI_DEV_DEV(info->PciInfo),
-			   PCI_DEV_FUNC(info->PciInfo));
-    info->MMIOAddr = PCI_REGION_BASE(info->PciInfo, 2, REGION_MEM) & ~0xffULL;
-    info->MMIOSize = PCI_REGION_SIZE(info->PciInfo, 2);
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TOTO SAYS %016llx\n", 
-		(unsigned long long)PCI_REGION_BASE(info->PciInfo,
-		2, REGION_MEM));
-    if (info->pEnt->device->IOBase) {
-	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
-		   "MMIO address override, using 0x%08lx instead of 0x%016llx\n",
-		   info->pEnt->device->IOBase,
-		   info->MMIOAddr);
-	info->MMIOAddr = info->pEnt->device->IOBase;
-    } else if (!info->MMIOAddr) {
-	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid MMIO address\n");
-	goto fail1;
-    }
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "MMIO registers at 0x%016llx: size %ldKB\n", info->MMIOAddr, info->MMIOSize / 1024);
 
-    if(!RADEONMapMMIO(pScrn)) {
-	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		   "Memory map the MMIO region failed\n");
-	goto fail1;
-    }
+    if (!info->drm_mode_setting) {
 
+	info->PciTag  = pciTag(PCI_DEV_BUS(info->PciInfo),
+			       PCI_DEV_DEV(info->PciInfo),
+			       PCI_DEV_FUNC(info->PciInfo));
+        info->MMIOAddr = PCI_REGION_BASE(info->PciInfo, 2, REGION_MEM) & ~0xffULL;
+	info->MMIOSize = PCI_REGION_SIZE(info->PciInfo, 2);
+	if (info->pEnt->device->IOBase) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+		       "MMIO address override, using 0x%08lx instead of 0x%016llx\n",
+		       info->pEnt->device->IOBase,
+		       info->MMIOAddr);
+	    info->MMIOAddr = info->pEnt->device->IOBase;
+	} else if (!info->MMIOAddr) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid MMIO address\n");
+	    goto fail1;
+	}
+        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	           "MMIO registers at 0x%016llx: size %ldKB\n", info->MMIOAddr, info->MMIOSize / 1024);
+	
+	if(!RADEONMapMMIO(pScrn)) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "Memory map the MMIO region failed\n");
+	    goto fail1;
+	}
+	
 #if !defined(__alpha__)
-    if (
+	if (
 #ifndef XSERVER_LIBPCIACCESS
-	xf86GetPciDomain(info->PciTag) ||
+	    xf86GetPciDomain(info->PciTag) ||
 #endif
-	!xf86IsPrimaryPci(info->PciInfo))
-	RADEONPreInt10Save(pScrn, &int10_save);
+	    !xf86IsPrimaryPci(info->PciInfo))
+	    RADEONPreInt10Save(pScrn, &int10_save);
 #else
-    /* [Alpha] On the primary, the console already ran the BIOS and we're
-     *         going to run it again - so make sure to "fix up" the card
-     *         so that (1) we can read the BIOS ROM and (2) the BIOS will
-     *         get the memory config right.
-     */
-    RADEONPreInt10Save(pScrn, &int10_save);
+	/* [Alpha] On the primary, the console already ran the BIOS and we're
+	 *         going to run it again - so make sure to "fix up" the card
+	 *         so that (1) we can read the BIOS ROM and (2) the BIOS will
+	 *         get the memory config right.
+	 */
+	RADEONPreInt10Save(pScrn, &int10_save);
 #endif
-
-    if (flags & PROBE_DETECT) {
-	RADEONProbeDDC(pScrn, info->pEnt->index);
-	RADEONPostInt10Check(pScrn, int10_save);
-	if(info->MMIO) RADEONUnmapMMIO(pScrn);
-	return TRUE;
-    }
+	
+	if (flags & PROBE_DETECT) {
+	    RADEONProbeDDC(pScrn, info->pEnt->index);
+	    RADEONPostInt10Check(pScrn, int10_save);
+	    if(info->MMIO) RADEONUnmapMMIO(pScrn);
+	    return TRUE;
+	}
 
 
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "PCI bus %d card %d func %d\n",
-	       PCI_DEV_BUS(info->PciInfo),
-	       PCI_DEV_DEV(info->PciInfo),
-	       PCI_DEV_FUNC(info->PciInfo));
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		   "PCI bus %d card %d func %d\n",
+		   PCI_DEV_BUS(info->PciInfo),
+		   PCI_DEV_DEV(info->PciInfo),
+		   PCI_DEV_FUNC(info->PciInfo));
+    }
 
     if (xf86RegisterResources(info->pEnt->index, 0, ResExclusive))
 	goto fail;
@@ -2811,10 +2876,12 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
     pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR;
     pScrn->monitor     = pScrn->confScreen->monitor;
 
-   /* Allocate an xf86CrtcConfig */
-    xf86CrtcConfigInit (pScrn, &RADEONCRTCResizeFuncs);
-    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-
+    if (!info->drm_mode_setting) {
+	/* Allocate an xf86CrtcConfig */
+	xf86CrtcConfigInit (pScrn, &RADEONCRTCResizeFuncs);
+	xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	
+    }
 
     if (!RADEONPreInitVisual(pScrn))
 	goto fail;
@@ -2828,164 +2895,224 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
     memcpy(info->Options, RADEONOptions, sizeof(RADEONOptions));
     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options);
 
-    /* By default, don't do VGA IOs on ppc/sparc */
+    if (!info->drm_mode_setting) {
+	/* By default, don't do VGA IOs on ppc/sparc */
 #if defined(__powerpc__) || defined(__sparc__) || !defined(WITH_VGAHW)
-    info->VGAAccess = FALSE;
+	info->VGAAccess = FALSE;
 #else
-    info->VGAAccess = TRUE;
+	info->VGAAccess = TRUE;
 #endif
-
+	
 #ifdef WITH_VGAHW
-    xf86GetOptValBool(info->Options, OPTION_VGA_ACCESS, &info->VGAAccess);
-    if (info->VGAAccess) {
-       if (!xf86LoadSubModule(pScrn, "vgahw"))
-           info->VGAAccess = FALSE;
-        else {
-            if (!vgaHWGetHWRec(pScrn))
-               info->VGAAccess = FALSE;
-       }
-       if (!info->VGAAccess)
-           xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Loading VGA module failed,"
-                      " trying to run without it\n");
-    } else
-           xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VGAAccess option set to FALSE,"
-                      " VGA module load skipped\n");
-    if (info->VGAAccess)
-        vgaHWGetIOBase(VGAHWPTR(pScrn));
+	xf86GetOptValBool(info->Options, OPTION_VGA_ACCESS, &info->VGAAccess);
+	if (info->VGAAccess) {
+	    if (!xf86LoadSubModule(pScrn, "vgahw"))
+		info->VGAAccess = FALSE;
+	    else {
+		if (!vgaHWGetHWRec(pScrn))
+		    info->VGAAccess = FALSE;
+	    }
+	    if (!info->VGAAccess)
+		xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Loading VGA module failed,"
+			   " trying to run without it\n");
+	} else
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VGAAccess option set to FALSE,"
+		       " VGA module load skipped\n");
+	if (info->VGAAccess)
+	    vgaHWGetIOBase(VGAHWPTR(pScrn));
 #endif
-
-
+	
+    }
+	
     if (!RADEONPreInitWeight(pScrn))
 	goto fail;
 
-    info->DispPriority = 1;
-    if ((s = xf86GetOptValString(info->Options, OPTION_DISP_PRIORITY))) {
-	if (strcmp(s, "AUTO") == 0) {
-	    info->DispPriority = 1;
-	} else if (strcmp(s, "BIOS") == 0) {
-	    info->DispPriority = 0;
-	} else if (strcmp(s, "HIGH") == 0) {
-	    info->DispPriority = 2;
-	} else
-	    info->DispPriority = 1;
-    }
-
     if (!RADEONPreInitChipType(pScrn))
-	goto fail;
-
-    if (!RADEONPreInitInt10(pScrn, &pInt10))
-	goto fail;
-
-    RADEONPostInt10Check(pScrn, int10_save);
-
-    if (!RADEONPreInitBIOS(pScrn, pInt10))
-	goto fail;
+        goto fail;
+
+    if (!info->drm_mode_setting) {
+	info->DispPriority = 1;
+	if ((s = xf86GetOptValString(info->Options, OPTION_DISP_PRIORITY))) {
+	    if (strcmp(s, "AUTO") == 0) {
+		info->DispPriority = 1;
+	    } else if (strcmp(s, "BIOS") == 0) {
+		info->DispPriority = 0;
+	    } else if (strcmp(s, "HIGH") == 0) {
+		info->DispPriority = 2;
+	    } else
+		info->DispPriority = 1;
+	}
+	
+	
+	if (!RADEONPreInitInt10(pScrn, &pInt10))
+	    goto fail;
+	
+	RADEONPostInt10Check(pScrn, int10_save);
 
+	if (!RADEONPreInitBIOS(pScrn, pInt10))
+	    goto fail;
 #ifdef XF86DRI
-    /* PreInit DRI first of all since we need that for getting a proper
-     * memory map
-     */
-    info->directRenderingEnabled = RADEONPreInitDRI(pScrn);
+	/* PreInit DRI first of all since we need that for getting a proper
+	 * memory map
+	 */
+	info->directRenderingEnabled = RADEONPreInitDRI(pScrn);
 #endif
-    if (!info->directRenderingEnabled) {
-	if (info->ChipFamily >= CHIP_FAMILY_R600) {
-	    info->r600_shadow_fb = TRUE;
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	if (!info->directRenderingEnabled) {
+	    if (info->ChipFamily >= CHIP_FAMILY_R600) {
+		info->r600_shadow_fb = TRUE;
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 			   "using shadow framebuffer\n");
-	    if (!xf86LoadSubModule(pScrn, "shadow"))
-		info->r600_shadow_fb = FALSE;
-	}
-    }
-
-    if (!RADEONPreInitVRAM(pScrn))
-	goto fail;
-
-    RADEONPreInitColorTiling(pScrn);
-
-    /* we really need an FB manager... */
-    if (pScrn->display->virtualX) {
-	crtc_max_X = pScrn->display->virtualX;
-	crtc_max_Y = pScrn->display->virtualY;
-	if (info->allowColorTiling) {
-	    if (crtc_max_X > info->MaxSurfaceWidth ||
-		crtc_max_Y > info->MaxLines) {
-		info->allowColorTiling = FALSE;
-		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-			   "Requested desktop size exceeds surface limts for tiling, ColorTiling disabled\n");
+		if (!xf86LoadSubModule(pScrn, "shadow"))
+		    info->r600_shadow_fb = FALSE;
 	    }
 	}
-	if (crtc_max_X > 8192)
-	    crtc_max_X = 8192;
-	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;
+	
+	if (!RADEONPreInitVRAM(pScrn))
+	    goto fail;
+	
+	RADEONPreInitColorTiling(pScrn);
+	
+	/* we really need an FB manager... */
+	if (pScrn->display->virtualX) {
+	    crtc_max_X = pScrn->display->virtualX;
+	    crtc_max_Y = pScrn->display->virtualY;
+	    if (info->allowColorTiling) {
+		if (crtc_max_X > info->MaxSurfaceWidth ||
+		    crtc_max_Y > info->MaxLines) {
+		    info->allowColorTiling = FALSE;
+		    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+			       "Requested desktop size exceeds surface limts for tiling, ColorTiling disabled\n");
+		}
+	    }
+	    if (crtc_max_X > 8192)
+		crtc_max_X = 8192;
+	    if (crtc_max_Y > 8192)
+		crtc_max_Y = 8192;
 	} else {
-	    crtc_max_X = 2048;
-	    crtc_max_Y = 1200;
+	    /*
+	     * 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 {
+		crtc_max_X = 2048;
+		crtc_max_Y = 1200;
 	}
-    }
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Max desktop size set to %dx%d\n",
-	       crtc_max_X, crtc_max_Y);
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "For a larger or smaller max desktop size, add a Virtual line to your xorg.conf\n");
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "If you are having trouble with 3D, "
-	       "reduce the desktop size by adjusting the Virtual line to your xorg.conf\n");
-
+	}
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Max desktop size set to %dx%d\n",
+		   crtc_max_X, crtc_max_Y);
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		   "For a larger or smaller max desktop size, add a Virtual line to your xorg.conf\n");
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		   "If you are having trouble with 3D, "
+		   "reduce the desktop size by adjusting the Virtual line to your xorg.conf\n");
+	
     /*xf86CrtcSetSizeRange (pScrn, 320, 200, info->MaxSurfaceWidth, info->MaxLines);*/
-    xf86CrtcSetSizeRange (pScrn, 320, 200, crtc_max_X, crtc_max_Y);
+	xf86CrtcSetSizeRange (pScrn, 320, 200, crtc_max_X, crtc_max_Y);
+	
+	RADEONPreInitDDC(pScrn);
 
-    RADEONPreInitDDC(pScrn);
+	if (!RADEONPreInitControllers(pScrn))
+	    goto fail;
 
-    if (!RADEONPreInitControllers(pScrn))
-       goto fail;
 
+	ErrorF("before xf86InitialConfiguration\n");
+	
+	if (!xf86InitialConfiguration (pScrn, FALSE))
+	{
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
+		goto fail;
+	}
+	
+	/* fix up cloning on rn50 cards
+	 * since they only have one crtc sometimes the xserver doesn't assign
+	 * a crtc to one of the outputs even though both outputs have common modes
+	 * which results in only one monitor being enabled.  Assign a crtc here so
+	 * that both outputs light up.
+	 */
+	if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) {
+	    int i;
 
-    ErrorF("before xf86InitialConfiguration\n");
+	    for (i = 0; i < xf86_config->num_output; i++) {
+		xf86OutputPtr output = xf86_config->output[i];
 
-    if (!xf86InitialConfiguration (pScrn, FALSE))
-   {
-      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
-      goto fail;
-   }
+		/* XXX: double check crtc mode */
+		if ((output->probed_modes != NULL) && (output->crtc == NULL))
+		    output->crtc = xf86_config->crtc[0];
+	    }
+	}
+	ErrorF("after xf86InitialConfiguration\n");
 
-    /* fix up cloning on rn50 cards
-     * since they only have one crtc sometimes the xserver doesn't assign
-     * a crtc to one of the outputs even though both outputs have common modes
-     * which results in only one monitor being enabled.  Assign a crtc here so
-     * that both outputs light up.
-     */
-    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) {
-	int i;
+    } else {
+#ifdef XF86DRM_MODE
+	char *bus_id;
+   	 if (!radeon_alloc_dri(pScrn))
+		return FALSE;
+
+	bus_id = DRICreatePCIBusID(info->PciInfo);
+	if (drmmode_pre_init(pScrn, &info->drmmode, bus_id, "radeon", pScrn->bitsPerPixel / 8) == FALSE) {
+	    xfree(bus_id);
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n");
+	    goto fail;
+	}
+
+	info->dri->drmFD = info->drmmode.fd;
+    info->dri2.drm_fd = info->drmmode.fd;
+    info->dri2.enabled = FALSE;
+	xfree(bus_id);
+	 
+        {
+	    struct drm_radeon_gem_info mminfo;
+
+	    if (!drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo)))
+	    {
+		info->mm.vram_start = mminfo.vram_start;
+		info->mm.vram_size = mminfo.vram_visible;
+		info->mm.gart_start = mminfo.gart_start;
+		info->mm.gart_size = mminfo.gart_size;
+		ErrorF("initing %llx %llx %llx %llx %llx\n", mminfo.gart_start,
+		       mminfo.gart_size, mminfo.vram_start, mminfo.vram_size, mminfo.vram_visible);
+	    }
+	    {
+	        struct drm_radeon_getparam gp;
+		int value;
 
-	for (i = 0; i < xf86_config->num_output; i++) {
-	    xf86OutputPtr output = xf86_config->output[i];
+		memset(&gp, 0, sizeof(gp));
+		gp.param = RADEON_PARAM_FB_LOCATION;
+		gp.value = &value;
 
-	    /* XXX: double check crtc mode */
-	    if ((output->probed_modes != NULL) && (output->crtc == NULL))
-		output->crtc = xf86_config->crtc[0];
+		if (drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_GETPARAM, &gp,
+					sizeof(gp)) < 0) {
+		    goto fail;
+		}
+		if (info->ChipFamily >= CHIP_FAMILY_R600)
+	    		info->fbLocation = (value & 0xffff) << 24; 
+		else
+			info->fbLocation = (value & 0xffff) << 16;
+	    }
+        }
+	if (info->ChipFamily < CHIP_FAMILY_R600) {
+		info->useEXA = TRUE;
+		info->directRenderingEnabled = TRUE;
 	}
+	info->new_cs = TRUE;
+	info->drm_mm = TRUE;
+	//	info->directRenderingDisabled = FALSE;
+#endif
     }
 
-    ErrorF("after xf86InitialConfiguration\n");
-
     RADEONSetPitch(pScrn);
 
-   /* Set display resolution */
-   xf86SetDpi(pScrn, 0, 0);
+    /* Set display resolution */
+    xf86SetDpi(pScrn, 0, 0);
 
 	/* Get ScreenInit function */
     if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
@@ -3000,10 +3127,12 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
 	if (!RADEONPreInitXv(pScrn))                 goto fail;
     }
 
-    if (!xf86RandR12PreInit (pScrn))
-    {
-      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
-      goto fail;
+    if (!info->drm_mode_setting) {
+	if (!xf86RandR12PreInit (pScrn))
+	{
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
+		goto fail;
+	}
     }
 
     if (pScrn->modes == NULL) {
@@ -3156,6 +3285,9 @@ static void RADEONBlockHandler(int i, pointer blockData,
 
 #ifdef USE_EXA
     info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
+    if (info->new_cs) {
+        RADEONCPReleaseIndirect(pScrn);
+    }
 #endif
 }
 
@@ -3244,7 +3376,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
     int            subPixelOrder = SubPixelUnknown;
     char*          s;
 #endif
-
+    void *front_ptr;
 
     info->accelOn      = FALSE;
 #ifdef USE_XAA
@@ -3264,58 +3396,61 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
 		   "RADEONScreenInit %lx %ld\n",
 		   pScrn->memPhysBase, pScrn->fbOffset);
 #endif
-    if (!RADEONMapMem(pScrn)) return FALSE;
+
+    if (!info->drm_mode_setting) {
+	if (!RADEONMapMem(pScrn)) return FALSE;
 
 #ifdef XF86DRI
-    info->dri->fbX = 0;
-    info->dri->fbY = 0;
+	info->dri->fbX = 0;
+	info->dri->fbY = 0;
 #endif
+	
+	info->PaletteSavedOnVT = FALSE;
 
-    info->PaletteSavedOnVT = FALSE;
+	info->crtc_on = FALSE;
+	info->crtc2_on = FALSE;
 
-    info->crtc_on = FALSE;
-    info->crtc2_on = FALSE;
+        /* save the real front buffer size
+         * it changes with randr, rotation, etc.
+         */
+        info->virtualX = pScrn->virtualX;
+        info->virtualY = pScrn->virtualY;
 
-    /* save the real front buffer size
-     * it changes with randr, rotation, etc.
-     */
-    info->virtualX = pScrn->virtualX;
-    info->virtualY = pScrn->virtualY;
+	RADEONSave(pScrn);
 
-    RADEONSave(pScrn);
+	/* set initial bios scratch reg state */
+	RADEONInitBIOSRegisters(pScrn);
 
-    /* set initial bios scratch reg state */
-    RADEONInitBIOSRegisters(pScrn);
+	/* blank the outputs/crtcs */
+	RADEONBlank(pScrn);
 
-    /* blank the outputs/crtcs */
-    RADEONBlank(pScrn);
+	if (info->IsMobility && !IS_AVIVO_VARIANT) {
+	    if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
+		RADEONSetDynamicClock(pScrn, 1);
+	    } 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);
 
-    if (info->IsMobility && !IS_AVIVO_VARIANT) {
-	if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
-	    RADEONSetDynamicClock(pScrn, 1);
-	} else {
-	    RADEONSetDynamicClock(pScrn, 0);
+	if (info->allowColorTiling && (pScrn->virtualX > info->MaxSurfaceWidth)) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		       "Color tiling not supported with virtual x resolutions larger than %d, disabling\n",
+		       info->MaxSurfaceWidth);
+	    info->allowColorTiling = FALSE;
 	}
-    } 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 (info->allowColorTiling) {
+	    info->tilingEnabled = (pScrn->currentMode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
 	}
+	
     }
-
-    if (IS_R300_VARIANT || IS_RV100_VARIANT)
-	RADEONForceSomeClocks(pScrn);
-
-    if (info->allowColorTiling && (pScrn->virtualX > info->MaxSurfaceWidth)) {
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "Color tiling not supported with virtual x resolutions larger than %d, disabling\n",
-		    info->MaxSurfaceWidth);
-	info->allowColorTiling = FALSE;
-    }
-    if (info->allowColorTiling) {
-        info->tilingEnabled = (pScrn->currentMode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
-    }
-
     /* Visual setup */
     miClearVisualTypes();
     if (!miSetVisualTypes(pScrn->depth,
@@ -3349,19 +3484,21 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
     hasDRI = info->directRenderingEnabled;
 #endif /* XF86DRI */
 
-    /* Initialize the memory map, this basically calculates the values
-     * we'll use later on for MC_FB_LOCATION & MC_AGP_LOCATION
-     */
-    RADEONInitMemoryMap(pScrn);
+    if (!info->drm_mode_setting) {
+	/* Initialize the memory map, this basically calculates the values
+	 * we'll use later on for MC_FB_LOCATION & MC_AGP_LOCATION
+	 */
+	RADEONInitMemoryMap(pScrn);
 
-    /* empty the surfaces */
-    if (info->ChipFamily < CHIP_FAMILY_R600) {
-	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);
+	/* empty the surfaces */
+	if (info->ChipFamily < CHIP_FAMILY_R600) {
+	    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);
+	    }
 	}
     }
 
@@ -3398,7 +3535,10 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
 #ifdef XF86DRI
 	if (hasDRI) {
 	    info->accelDFS = xf86ReturnOptValBool(info->Options, OPTION_ACCEL_DFS,
-						  info->cardType != CARD_AGP);
+                                                  info->cardType != CARD_AGP);
+
+	    if (info->drm_mm)
+	      info->accelDFS = FALSE;
 
 	    /* Reserve approx. half of offscreen memory for local textures by
 	     * default, can be overridden with Option "FBTexPercent".
@@ -3424,7 +3564,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
 #endif
 
 #if defined(XF86DRI) && defined(USE_XAA)
-    if (!info->useEXA && hasDRI) {
+    if (!info->useEXA && hasDRI && !info->drm_mm) {
 	info->dri->textureSize = -1;
 	if (xf86GetOptValInteger(info->Options, OPTION_FBTEX_PERCENT,
 				 &(info->dri->textureSize))) {
@@ -3442,7 +3582,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
 #endif
 
 #ifdef USE_XAA
-    if (!info->useEXA && !hasDRI && !RADEONSetupMemXAA(scrnIndex, pScreen))
+    if (!info->useEXA && !hasDRI && !info->drm_mm && !RADEONSetupMemXAA(scrnIndex, pScreen))
 	return FALSE;
 #endif
 
@@ -3463,7 +3603,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
 			    info->CurrentLayout.pixel_bytes);
 	int  maxy        = info->FbMapSize / width_bytes;
 
-	if (maxy <= pScrn->virtualY * 3) {
+	if (maxy <= pScrn->virtualY * 3 && !info->drm_mm) {
 	    xf86DrvMsg(scrnIndex, X_ERROR,
 		       "Static buffer allocation failed.  Disabling DRI.\n");
 	    xf86DrvMsg(scrnIndex, X_ERROR,
@@ -3473,19 +3613,54 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
 			info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024);
 	    info->directRenderingEnabled = FALSE;
 	} else {
-	    info->directRenderingEnabled = RADEONDRIScreenInit(pScreen);
+        info->directRenderingEnabled = FALSE;
+#ifdef DRI2
+        if (info->drm_mm) {
+            info->directRenderingEnabled = radeon_dri2_screen_init(pScreen);
+        }
+#endif
+        if (!info->directRenderingEnabled) {
+    	    info->directRenderingEnabled = RADEONDRIScreenInit(pScreen);
+        }
 	}
     }
 
-    /* Tell DRI about new memory map */
-    if (info->directRenderingEnabled && info->dri->newMemoryMap) {
-        if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_NEW_MEMMAP, 1) < 0) {
+    front_ptr = info->FB;
+    if (info->drm_mm) {
+	if (info->directRenderingEnabled && info->dri->newMemoryMap) {
+	    if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_NEW_MEMMAP, 1) < 0) {
+		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+			   "[drm] failed to enable new memory map\n");
+		RADEONDRICloseScreen(pScreen);
+		info->directRenderingEnabled = FALSE;		
+	    }
+	}
+	info->bufmgr = radeon_bufmgr_gem_init(info->dri->drmFD);
+	drmmode_set_bufmgr(pScrn, &info->drmmode, info->bufmgr);
+	//radeon_bufmgr_gem_enable_reuse(info->bufmgr);
+	radeon_bufmgr_gem_set_limit(info->bufmgr, RADEON_GEM_DOMAIN_GTT, info->mm.gart_size - info->dri->gartTexMapSize);
+    
+	radeon_setup_kernel_mem(pScreen);
+	front_ptr = info->mm.front_buffer->map;
+	pScrn->fbOffset = info->mm.front_buffer->offset;
+	info->accel_state->dst_pitch_offset = (((pScrn->displayWidth * info->CurrentLayout.pixel_bytes / 64)
+						<< 22) | ((info->fbLocation + pScrn->fbOffset) >> 10));
+    } else {
+
+	/* Tell DRI about new memory map */
+	if (info->directRenderingEnabled && info->dri->newMemoryMap) {
+	    if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_NEW_MEMMAP, 1) < 0) {
 		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 			   "[drm] failed to enable new memory map\n");
 		RADEONDRICloseScreen(pScreen);
 		info->directRenderingEnabled = FALSE;
+	    }
 	}
     }
+
+    if (info->directRenderingEnabled == TRUE && !info->dri2.enabled)
+        RADEONDRIDoMappings(pScreen);
+
 #endif
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "Initializing fb layer\n");
@@ -3509,7 +3684,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
 
     if (info->r600_shadow_fb == FALSE) {
 	/* Init fb layer */
-	if (!fbScreenInit(pScreen, info->FB,
+	if (!fbScreenInit(pScreen, front_ptr,
 			  pScrn->virtualX, pScrn->virtualY,
 			  pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
 			  pScrn->bitsPerPixel))
@@ -3551,8 +3726,10 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
     /* restore the memory map here otherwise we may get a hang when
      * initializing the drm below
      */
-    RADEONInitMemMapRegisters(pScrn, info->ModeReg, info);
-    RADEONRestoreMemMapRegisters(pScrn, info->ModeReg);
+    if (!info->drm_mode_setting) {
+    	RADEONInitMemMapRegisters(pScrn, info->ModeReg, info);
+    	RADEONRestoreMemMapRegisters(pScrn, info->ModeReg);
+    }
 
     /* Backing store setup */
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
@@ -3562,7 +3739,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
 
     /* DRI finalisation */
 #ifdef XF86DRI
-    if (info->directRenderingEnabled && info->cardType==CARD_PCIE &&
+    if (!info->drm_mm && info->directRenderingEnabled && info->cardType==CARD_PCIE &&
         info->dri->pKernelDRMVersion->version_minor >= 19)
     {
       if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_PCIGART_LOCATION, info->dri->pciGartOffset) < 0)
@@ -3578,14 +3755,24 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
     if (info->directRenderingEnabled) {
         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		       "DRI Finishing init !\n");
+    if (!info->dri2.enabled) {
 	info->directRenderingEnabled = RADEONDRIFinishScreenInit(pScreen);
     }
+    }
     if (info->directRenderingEnabled) {
+
+	if (info->drm_mm)
+    if (!info->dri2.enabled) {
+	    radeon_update_dri_buffers(pScreen);
+    }
+    
 	/* DRI final init might have changed the memory map, we need to adjust
 	 * our local image to make sure we restore them properly on mode
 	 * changes or VT switches
 	 */
-	RADEONAdjustMemMapRegisters(pScrn, info->ModeReg);
+	if (!info->drm_mode_setting) {
+	    RADEONAdjustMemMapRegisters(pScrn, info->ModeReg);
+	}
 
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
 
@@ -3681,10 +3868,16 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
             return FALSE;
         }
     }
+    pScrn->pScreen = pScreen;
 
     /* set the modes with desired rotation, etc. */
-    if (!xf86SetDesiredModes (pScrn))
+    if (info->drm_mode_setting) {
+      if (!drmmode_set_desired_modes(pScrn, &info->drmmode))
+	return FALSE;
+    } else {
+      if (!xf86SetDesiredModes (pScrn))
 	return FALSE;
+    }
 
     /* Provide SaveScreen & wrap BlockHandler and CloseScreen */
     /* Wrap CloseScreen */
@@ -5261,7 +5454,7 @@ Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
 #ifdef XF86DRI
     Bool           CPStarted   = info->cp->CPStarted;
 
-    if (CPStarted) {
+    if (CPStarted && !info->drm_mode_setting) {
 	DRILock(pScrn->pScreen, 0);
 	RADEONCP_STOP(pScrn, info);
     }
@@ -5284,8 +5477,10 @@ Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
 #endif
     }
 
-    if (info->accelOn)
-        RADEON_SYNC(info, pScrn);
+    if (!info->drm_mode_setting) {
+    	if (info->accelOn)
+       	    RADEON_SYNC(info, pScrn);
+    }
 
     ret = xf86SetSingleMode (pScrn, mode, RR_Rotate_0);
 
@@ -5297,16 +5492,19 @@ Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
 	/* xf86SetRootClip would do, but can't access that here */
     }
 
-    if (info->accelOn) {
-        RADEON_SYNC(info, pScrn);
-	if (info->ChipFamily < CHIP_FAMILY_R600)
-	    RADEONEngineRestore(pScrn);
-    }
+    if (!info->drm_mode_setting)
+        if (info->accelOn) {
+           RADEON_SYNC(info, pScrn);
+	   if (info->ChipFamily < CHIP_FAMILY_R600)
+	       RADEONEngineRestore(pScrn);
+        }
 
 #ifdef XF86DRI
-    if (CPStarted) {
-	RADEONCP_START(pScrn, info);
-	DRIUnlock(pScrn->pScreen);
+    if (!info->drm_mode_setting) {
+    	if (CPStarted) {
+		RADEONCP_START(pScrn, info);
+		DRIUnlock(pScrn->pScreen);
+    	}
     }
 #endif
 
@@ -5504,6 +5702,11 @@ void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags)
     xf86OutputPtr  output = config->output[config->compat_output];
     xf86CrtcPtr	crtc = output->crtc;
 
+    if (info->drm_mode_setting) {
+	drmmode_adjust_frame(pScrn, &info->drmmode, x, y, flags);
+	return;
+    }
+
     /* not handled */
     if (IS_AVIVO_VARIANT)
 	return;
@@ -5543,76 +5746,103 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONEnterVT\n");
 
-    if (!radeon_card_posted(pScrn)) { /* Softboot V_BIOS */
-	if (info->IsAtomBios) {
-	    rhdAtomASICInit(info->atomBIOS);
-	} else {
-	    xf86Int10InfoPtr pInt;
+    if (!info->drm_mode_setting) {
+        if (!radeon_card_posted(pScrn)) { /* Softboot V_BIOS */
+	    if (info->IsAtomBios) {
+	        rhdAtomASICInit(info->atomBIOS);
+	    } else {
+	        xf86Int10InfoPtr pInt;
+
+	        pInt = xf86InitInt10 (info->pEnt->index);
+	        if (pInt) {
+		    pInt->num = 0xe6;
+		    xf86ExecX86int10 (pInt);
+		    xf86FreeInt10 (pInt);
+	        } else {
+		    RADEONGetBIOSInitTableOffsets(pScrn);
+		    RADEONPostCardFromBIOSTables(pScrn);
+	        }
+	    }
+        }
+	/* Makes sure the engine is idle before doing anything */
+	RADEONWaitForIdleMMIO(pScrn);
 
-	    pInt = xf86InitInt10 (info->pEnt->index);
-	    if (pInt) {
-		pInt->num = 0xe6;
-		xf86ExecX86int10 (pInt);
-		xf86FreeInt10 (pInt);
+	if (info->IsMobility && !IS_AVIVO_VARIANT) {
+	    if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
+		RADEONSetDynamicClock(pScrn, 1);
 	    } else {
-		RADEONGetBIOSInitTableOffsets(pScrn);
-		RADEONPostCardFromBIOSTables(pScrn);
+		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);
 	    }
 	}
-    }
-
-    /* Makes sure the engine is idle before doing anything */
-    RADEONWaitForIdleMMIO(pScrn);
+	
+	if (IS_R300_VARIANT || IS_RV100_VARIANT)
+	    RADEONForceSomeClocks(pScrn);
 
-    if (info->IsMobility && !IS_AVIVO_VARIANT) {
-	if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
-	    RADEONSetDynamicClock(pScrn, 1);
-	} 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);
+    } else {
+	int ret;
+	if (info->drm_mode_setting) {
+		ret = ioctl(info->dri->drmFD, DRM_IOCTL_SET_MASTER, NULL);
+		if (ret == -EINVAL)
+			ErrorF("Unable to retrieve master\n");
 	}
     }
 
-    if (IS_R300_VARIANT || IS_RV100_VARIANT)
-	RADEONForceSomeClocks(pScrn);
+    if (info->drm_mm) {
+	radeon_bind_all_memory(pScrn);
+	info->accel_state->XInited3D = FALSE;
+	info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
+    }
 
-    for (i = 0; i < config->num_crtc; i++)
-	radeon_crtc_modeset_ioctl(config->crtc[i], TRUE);
+    if (info->directRenderingEnabled)
+    	radeon_update_dri_buffers(pScrn->pScreen);
 
     pScrn->vtSema = TRUE;
 
-    if (!xf86SetDesiredModes(pScrn))
+    if (!info->drm_mode_setting)
+	for (i = 0; i < config->num_crtc; i++)
+	    radeon_crtc_modeset_ioctl(config->crtc[i], TRUE);
+
+    if (info->drm_mode_setting) {
+      if (!drmmode_set_desired_modes(pScrn, &info->drmmode))
 	return FALSE;
+    } else {
+      if (!xf86SetDesiredModes(pScrn))
+	return FALSE;
+    }
 
-    if (info->ChipFamily < CHIP_FAMILY_R600)
-        RADEONRestoreSurfaces(pScrn, info->ModeReg);
+    if (!info->drm_mode_setting) {
+	if (info->ChipFamily < CHIP_FAMILY_R600)
+	    RADEONRestoreSurfaces(pScrn, info->ModeReg);
 #ifdef XF86DRI
-    if (info->directRenderingEnabled) {
-    	if (info->cardType == CARD_PCIE &&
-	    info->dri->pKernelDRMVersion->version_minor >= 19 &&
-	    info->FbSecureSize) {
+	if (info->directRenderingEnabled) {
+	    if (info->cardType == CARD_PCIE &&
+		info->dri->pKernelDRMVersion->version_minor >= 19 &&
+		info->FbSecureSize) {
 #if X_BYTE_ORDER == X_BIG_ENDIAN
-	    unsigned char *RADEONMMIO = info->MMIO;
-	    unsigned int sctrl = INREG(RADEON_SURFACE_CNTL);
+	        unsigned char *RADEONMMIO = info->MMIO;
+	        unsigned int sctrl = INREG(RADEON_SURFACE_CNTL);
 
-	    /* we need to backup the PCIE GART TABLE from fb memory */
-	    OUTREG(RADEON_SURFACE_CNTL, 0);
+	        /* we need to backup the PCIE GART TABLE from fb memory */
+	        OUTREG(RADEON_SURFACE_CNTL, 0);
 #endif
-	    memcpy(info->FB + info->dri->pciGartOffset, info->dri->pciGartBackup, info->dri->pciGartSize);
+
+		/* we need to backup the PCIE GART TABLE from fb memory */
+		memcpy(info->FB + info->dri->pciGartOffset, info->dri->pciGartBackup, info->dri->pciGartSize);
 #if X_BYTE_ORDER == X_BIG_ENDIAN
-	    OUTREG(RADEON_SURFACE_CNTL, sctrl);
+	        OUTREG(RADEON_SURFACE_CNTL, sctrl);
 #endif
-    	}
-
-	/* get the DRI back into shape after resume */
-	RADEONDRISetVBlankInterrupt (pScrn, TRUE);
-	RADEONDRIResume(pScrn->pScreen);
-	RADEONAdjustMemMapRegisters(pScrn, info->ModeReg);
+	    }
 
+	    /* get the DRI back into shape after resume */
+	    RADEONDRISetVBlankInterrupt (pScrn, TRUE);
+	    RADEONDRIResume(pScrn->pScreen);
+	    RADEONAdjustMemMapRegisters(pScrn, info->ModeReg);
+	}
     }
 #endif
     /* this will get XVideo going again, but only if XVideo was initialised
@@ -5627,7 +5857,7 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
 	info->accel_state->XInited3D = FALSE;
 
 #ifdef XF86DRI
-    if (info->directRenderingEnabled) {
+    if (info->directRenderingEnabled && !info->drm_mode_setting) {
 	RADEONCP_START(pScrn, info);
 	DRIUnlock(pScrn->pScreen);
     }
@@ -5650,26 +5880,28 @@ void RADEONLeaveVT(int scrnIndex, int flags)
 		   "RADEONLeaveVT\n");
 #ifdef XF86DRI
     if (RADEONPTR(pScrn)->directRenderingInited) {
-
-	RADEONDRISetVBlankInterrupt (pScrn, FALSE);
-	DRILock(pScrn->pScreen, 0);
-	RADEONCP_STOP(pScrn, info);
-
-        if (info->cardType == CARD_PCIE &&
-	    info->dri->pKernelDRMVersion->version_minor >= 19 &&
-	    info->FbSecureSize) {
+	if (!info->drm_mode_setting) {
+	    RADEONDRISetVBlankInterrupt (pScrn, FALSE);
+	    DRILock(pScrn->pScreen, 0);
+	    RADEONCP_STOP(pScrn, info);
+
+	    if (info->cardType == CARD_PCIE &&
+		info->dri->pKernelDRMVersion->version_minor >= 19 &&
+		info->FbSecureSize) {
 #if X_BYTE_ORDER == X_BIG_ENDIAN
-	    unsigned char *RADEONMMIO = info->MMIO;
-	    unsigned int sctrl = INREG(RADEON_SURFACE_CNTL);
+                unsigned char *RADEONMMIO = info->MMIO;
+	        unsigned int sctrl = INREG(RADEON_SURFACE_CNTL);
 
-            /* we need to backup the PCIE GART TABLE from fb memory */
-	    OUTREG(RADEON_SURFACE_CNTL, 0);
+                /* we need to backup the PCIE GART TABLE from fb memory */
+	        OUTREG(RADEON_SURFACE_CNTL, 0);
 #endif
-            memcpy(info->dri->pciGartBackup, (info->FB + info->dri->pciGartOffset), info->dri->pciGartSize);
+		/* we need to backup the PCIE GART TABLE from fb memory */
+		memcpy(info->dri->pciGartBackup, (info->FB + info->dri->pciGartOffset), info->dri->pciGartSize);
 #if X_BYTE_ORDER == X_BIG_ENDIAN
-	    OUTREG(RADEON_SURFACE_CNTL, sctrl);
+	        OUTREG(RADEON_SURFACE_CNTL, sctrl);
 #endif
-        }
+	    }
+	}
 
 	/* Make sure 3D clients will re-upload textures to video RAM */
 	if (info->dri->textureSize) {
@@ -5685,6 +5917,11 @@ void RADEONLeaveVT(int scrnIndex, int flags)
 		i = list[i].next;
 	    } while (i != 0);
 	}
+
+	if (info->drm_mode_setting)
+		ioctl(info->dri->drmFD, DRM_IOCTL_DROP_MASTER, NULL);
+		
+	
     }
 #endif
 
@@ -5711,10 +5948,18 @@ void RADEONLeaveVT(int scrnIndex, int flags)
 
     xf86_hide_cursors (pScrn);
 
-    RADEONRestore(pScrn);
+    if (info->drm_mm) {
+	info->accel_state->XInited3D = FALSE;
+	info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
+	radeon_unbind_all_memory(pScrn);
+    }
 
-    for (i = 0; i < config->num_crtc; i++)
-	radeon_crtc_modeset_ioctl(config->crtc[i], FALSE);
+    if (!info->drm_mode_setting) {
+	RADEONRestore(pScrn);
+
+	for (i = 0; i < config->num_crtc; i++)
+	    radeon_crtc_modeset_ioctl(config->crtc[i], FALSE);
+    }
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "Ok, leaving now...\n");
@@ -5768,7 +6013,8 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen)
 #endif /* USE_XAA */
 
     if (pScrn->vtSema) {
-	RADEONRestore(pScrn);
+        if (!info->drm_mode_setting)
+	    RADEONRestore(pScrn);
     }
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
@@ -5803,6 +6049,12 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen)
     info->DGAModes = NULL;
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "Unmapping memory\n");
+
+    if (info->drm_mm) {
+	radeon_unbind_all_memory(pScrn);
+	radeon_free_all_memory(pScrn);
+    }
+
     RADEONUnmapMem(pScrn);
 
     pScrn->vtSema = FALSE;
diff --git a/src/radeon_drm.h b/src/radeon_drm.h
index 54bc234..06fbad3 100644
--- a/src/radeon_drm.h
+++ b/src/radeon_drm.h
@@ -303,7 +303,6 @@ typedef union {
 #define RADEON_INDEX_PRIM_OFFSET	20
 
 #define RADEON_SCRATCH_REG_OFFSET	32
-#define R600_SCRATCH_REG_OFFSET	        256
 
 #define RADEON_NR_SAREA_CLIPRECTS	12
 
@@ -454,6 +453,15 @@ typedef struct {
 	int pfCurrentPage;	/* which buffer is being displayed? */
 	int crtc2_base;		/* CRTC2 frame offset */
 	int tiling_enabled;	/* set by drm, read by 2d + 3d clients */
+
+	unsigned int last_fence;
+
+	uint32_t front_handle;
+	uint32_t back_handle;
+	uint32_t depth_handle;
+	uint32_t front_pitch;
+	uint32_t back_pitch;
+	uint32_t depth_pitch;
 } drm_radeon_sarea_t;
 
 /* WARNING: If you change any of these defines, make sure to change the
@@ -494,6 +502,18 @@ typedef struct {
 #define DRM_RADEON_SURF_ALLOC 0x1a
 #define DRM_RADEON_SURF_FREE  0x1b
 
+#define DRM_RADEON_GEM_INFO   0x1c
+#define DRM_RADEON_GEM_CREATE 0x1d
+#define DRM_RADEON_GEM_MMAP   0x1e
+#define DRM_RADEON_GEM_PIN    0x1f
+#define DRM_RADEON_GEM_UNPIN  0x20
+#define DRM_RADEON_GEM_PREAD  0x21
+#define DRM_RADEON_GEM_PWRITE 0x22
+#define DRM_RADEON_GEM_SET_DOMAIN 0x23
+#define DRM_RADEON_GEM_WAIT_RENDERING 0x24
+
+#define DRM_RADEON_CS       0x26
+
 #define DRM_IOCTL_RADEON_CP_INIT    DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
 #define DRM_IOCTL_RADEON_CP_START   DRM_IO(  DRM_COMMAND_BASE + DRM_RADEON_CP_START)
 #define DRM_IOCTL_RADEON_CP_STOP    DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_STOP, drm_radeon_cp_stop_t)
@@ -522,16 +542,28 @@ typedef struct {
 #define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t)
 #define DRM_IOCTL_RADEON_SURF_FREE  DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t)
 
+#define DRM_IOCTL_RADEON_GEM_INFO   DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INFO, struct drm_radeon_gem_info)
+#define DRM_IOCTL_RADEON_GEM_CREATE   DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_CREATE, struct drm_radeon_gem_create)
+#define DRM_IOCTL_RADEON_GEM_MMAP   DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_MMAP, struct drm_radeon_gem_mmap)
+#define DRM_IOCTL_RADEON_GEM_PIN   DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PIN, struct drm_radeon_gem_pin)
+#define DRM_IOCTL_RADEON_GEM_UNPIN   DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_UNPIN, struct drm_radeon_gem_unpin)
+#define DRM_IOCTL_RADEON_GEM_PREAD   DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread)
+#define DRM_IOCTL_RADEON_GEM_PWRITE   DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite)
+#define DRM_IOCTL_RADEON_GEM_SET_DOMAIN  DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain)
+#define DRM_IOCTL_RADEON_GEM_WAIT_RENDERING DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_RENDERING, struct drm_radeon_gem_wait_rendering) 
+#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs)
+
+
 typedef struct drm_radeon_init {
 	enum {
 		RADEON_INIT_CP = 0x01,
 		RADEON_CLEANUP_CP = 0x02,
 		RADEON_INIT_R200_CP = 0x03,
 		RADEON_INIT_R300_CP = 0x04,
-		RADEON_INIT_R600_CP = 0x05,
+		RADEON_INIT_R600_CP = 0x05
 	} func;
 	unsigned long sarea_priv_offset;
-	int is_pci; /* for overriding only */
+	int is_pci;
 	int cp_mode;
 	int gart_size;
 	int ring_size;
@@ -581,7 +613,7 @@ typedef struct drm_radeon_clear {
 	unsigned int clear_depth;
 	unsigned int color_mask;
 	unsigned int depth_mask;	/* misnamed field:  should be stencil */
-	drm_radeon_clear_rect_t  *depth_boxes;
+	drm_radeon_clear_rect_t *depth_boxes;
 } drm_radeon_clear_t;
 
 typedef struct drm_radeon_vertex {
@@ -607,9 +639,9 @@ typedef struct drm_radeon_vertex2 {
 	int idx;		/* Index of vertex buffer */
 	int discard;		/* Client finished with buffer? */
 	int nr_states;
-	drm_radeon_state_t  *state;
+	drm_radeon_state_t *state;
 	int nr_prims;
-	drm_radeon_prim_t  *prim;
+	drm_radeon_prim_t *prim;
 } drm_radeon_vertex2_t;
 
 /* v1.3 - obsoletes drm_radeon_vertex2
@@ -624,15 +656,15 @@ typedef struct drm_radeon_vertex2 {
  */
 typedef struct drm_radeon_cmd_buffer {
 	int bufsz;
-	char  *buf;
+	char *buf;
 	int nbox;
-	struct drm_clip_rect  *boxes;
+	struct drm_clip_rect *boxes;
 } drm_radeon_cmd_buffer_t;
 
 typedef struct drm_radeon_tex_image {
 	unsigned int x, y;	/* Blit coordinates */
 	unsigned int width, height;
-	const void  *data;
+	const void *data;
 } drm_radeon_tex_image_t;
 
 typedef struct drm_radeon_texture {
@@ -641,11 +673,11 @@ typedef struct drm_radeon_texture {
 	int format;
 	int width;		/* Texture image coordinates */
 	int height;
-	drm_radeon_tex_image_t  *image;
+	drm_radeon_tex_image_t *image;
 } drm_radeon_texture_t;
 
 typedef struct drm_radeon_stipple {
-	unsigned int  *mask;
+	unsigned int *mask;
 } drm_radeon_stipple_t;
 
 typedef struct drm_radeon_indirect {
@@ -655,9 +687,6 @@ typedef struct drm_radeon_indirect {
 	int discard;
 } drm_radeon_indirect_t;
 
-#define RADEON_INDIRECT_DISCARD (1 << 0)
-#define RADEON_INDIRECT_NOFLUSH (1 << 1)
-
 /* enum for card type parameters */
 #define RADEON_CARD_PCI 0
 #define RADEON_CARD_AGP 1
@@ -683,10 +712,11 @@ typedef struct drm_radeon_indirect {
 #define RADEON_PARAM_VBLANK_CRTC           13   /* VBLANK CRTC */
 #define RADEON_PARAM_FB_LOCATION           14   /* FB location */
 #define RADEON_PARAM_NUM_GB_PIPES          15   /* num GB pipes */
+#define RADEON_PARAM_KERNEL_MM             16
 
 typedef struct drm_radeon_getparam {
 	int param;
-	void  *value;
+	void *value;
 } drm_radeon_getparam_t;
 
 /* 1.6: Set up a memory manager for regions of shared memory:
@@ -698,7 +728,7 @@ typedef struct drm_radeon_mem_alloc {
 	int region;
 	int alignment;
 	int size;
-	int  *region_offset;	/* offset from start of fb or GART */
+	int *region_offset;	/* offset from start of fb or GART */
 } drm_radeon_mem_alloc_t;
 
 typedef struct drm_radeon_mem_free {
@@ -715,7 +745,7 @@ typedef struct drm_radeon_mem_init_heap {
 /* 1.6: Userspace can request & wait on irq's:
  */
 typedef struct drm_radeon_irq_emit {
-	int  *irq_seq;
+	int *irq_seq;
 } drm_radeon_irq_emit_t;
 
 typedef struct drm_radeon_irq_wait {
@@ -734,10 +764,10 @@ typedef struct drm_radeon_setparam {
 #define RADEON_SETPARAM_FB_LOCATION    1	/* determined framebuffer location */
 #define RADEON_SETPARAM_SWITCH_TILING  2	/* enable/disable color tiling */
 #define RADEON_SETPARAM_PCIGART_LOCATION 3	/* PCI Gart Location */
-
 #define RADEON_SETPARAM_NEW_MEMMAP 4		/* Use new memory map */
 #define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5    /* PCI GART Table Size */
 #define RADEON_SETPARAM_VBLANK_CRTC 6           /* VBLANK CRTC */
+#define RADEON_SETPARAM_MM_INIT 7               /* DDX wants memory manager but has no modesetting */
 /* 1.14: Clients can allocate/free a surface
  */
 typedef struct drm_radeon_surface_alloc {
@@ -753,4 +783,107 @@ typedef struct drm_radeon_surface_free {
 #define	DRM_RADEON_VBLANK_CRTC1		1
 #define	DRM_RADEON_VBLANK_CRTC2		2
 
+#define RADEON_GEM_DOMAIN_CPU 0x1   // Cached CPU domain
+#define RADEON_GEM_DOMAIN_GTT 0x2   // GTT or cache flushed
+#define RADEON_GEM_DOMAIN_VRAM 0x4  // VRAM domain
+
+/* return to userspace start/size of gtt and vram apertures */
+struct drm_radeon_gem_info {
+	uint64_t gart_start;
+	uint64_t gart_size;
+	uint64_t vram_start;
+	uint64_t vram_size;
+	uint64_t vram_visible;
+};
+
+struct drm_radeon_gem_create {
+	uint64_t size;
+	uint64_t alignment;
+	uint32_t handle;
+	uint32_t initial_domain; // to allow VRAM to be created
+	uint32_t no_backing_store; // for VRAM objects - select whether they need backing store
+	// pretty much front/back/depth don't need it - other things do
+};
+
+struct drm_radeon_gem_mmap {
+	uint32_t handle;
+	uint32_t pad;
+	uint64_t offset;
+	uint64_t size;
+	uint64_t addr_ptr;
+};
+
+struct drm_radeon_gem_set_domain {
+	uint32_t handle;
+	uint32_t read_domains;
+	uint32_t write_domain;
+};
+
+struct drm_radeon_gem_wait_rendering {
+	uint32_t handle;
+};
+
+struct drm_radeon_gem_pin {
+	uint32_t handle;
+	uint32_t pin_domain;
+	uint64_t alignment;
+	uint64_t offset;
+};
+
+struct drm_radeon_gem_unpin {
+	uint32_t handle;
+	uint32_t pad;
+};
+
+struct drm_radeon_gem_busy {
+	uint32_t handle;
+	uint32_t busy;
+};
+
+struct drm_radeon_gem_pread {
+	/** Handle for the object being read. */
+	uint32_t handle;
+	uint32_t pad;
+	/** Offset into the object to read from */
+	uint64_t offset;
+	/** Length of data to read */
+	uint64_t size;
+	/** Pointer to write the data into. */
+	uint64_t data_ptr;	/* void *, but pointers are not 32/64 compatible */
+};
+
+struct drm_radeon_gem_pwrite {
+	/** Handle for the object being written to. */
+	uint32_t handle;
+	uint32_t pad;
+	/** Offset into the object to write to */
+	uint64_t offset;
+	/** Length of data to write */
+	uint64_t size;
+	/** Pointer to read the data from. */
+	uint64_t data_ptr;	/* void *, but pointers are not 32/64 compatible */
+};
+
+
+/* New interface which obsolete all previous interface.
+ */
+
+
+#define RADEON_CHUNK_ID_RELOCS 0x01
+#define RADEON_CHUNK_ID_IB     0x02
+
+struct drm_radeon_cs_chunk {
+	uint32_t chunk_id;
+	uint32_t length_dw;
+	uint64_t chunk_data;
+};
+
+struct drm_radeon_cs {
+	uint32_t	num_chunks;
+	uint32_t        cs_id;
+	uint64_t	chunks; /* this points to uint64_t * which point to
+				   cs chunks */
+};
+
+
 #endif
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index ae68146..67299a4 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -44,7 +44,7 @@
 #include "radeon_version.h"
 
 #include "xf86.h"
-
+#include "radeon_bufmgr_gem.h"
 
 /***********************************************************************/
 #define RINFO_FROM_SCREEN(pScr) ScrnInfoPtr pScrn =  xf86Screens[pScr->myNum]; \
@@ -182,12 +182,23 @@ Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset)
 	RINFO_FROM_SCREEN(pPix->drawable.pScreen);
 	uint32_t pitch, offset;
 	int bpp;
+	struct radeon_exa_pixmap_priv *driver_priv;
 
 	bpp = pPix->drawable.bitsPerPixel;
 	if (bpp == 24)
 		bpp = 8;
 
-	offset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset;
+
+	/* validate the pixmap somewhere */
+	if (info->new_cs)
+	    offset = 0;
+	else { 
+	    if (driver_priv)
+		offset = driver_priv->bo->offset;
+	    else
+		offset = exaGetPixmapOffset(pPix);
+		offset += info->fbLocation + pScrn->fbOffset;
+	}
 	pitch = exaGetPixmapPitch(pPix);
 
 	return RADEONGetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch);
@@ -220,10 +231,27 @@ int RADEONBiggerCrtcArea(PixmapPtr pPix)
     return crtc_num;
 }
 
+Bool RADEONGetPixmapOffsetCS(PixmapPtr pPix, uint32_t *pitch_offset)
+{
+	RINFO_FROM_SCREEN(pPix->drawable.pScreen);
+	uint32_t pitch, offset;
+	int bpp;
+
+	bpp = pPix->drawable.bitsPerPixel;
+	if (bpp == 24)
+		bpp = 8;
+
+	offset = exaGetPixmapOffset(pPix);
+	pitch = exaGetPixmapPitch(pPix);
+	return RADEONGetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch);
+}
+
 #if X_BYTE_ORDER == X_BIG_ENDIAN
 
 static unsigned long swapper_surfaces[6];
 
+#endif
+
 static Bool RADEONPrepareAccess(PixmapPtr pPix, int index)
 {
     RINFO_FROM_SCREEN(pPix->drawable.pScreen);
@@ -231,7 +259,31 @@ static Bool RADEONPrepareAccess(PixmapPtr pPix, int index)
     uint32_t offset = exaGetPixmapOffset(pPix);
     int bpp, soff;
     uint32_t size, flags;
+    struct radeon_exa_pixmap_priv *driver_priv;
+   
+    driver_priv = exaGetPixmapDriverPrivate(pPix);
+    if (driver_priv) {
+
+	if (driver_priv->bo) {
+	    int ret;
+
+	    if (radeon_bufmgr_gem_has_references(driver_priv->bo))
+		RADEONCPFlushIndirect(pScrn, 0);
+
+	    radeon_bufmgr_gem_wait_rendering(driver_priv->bo);
 
+	    /* flush IB */
+	    ret = dri_bo_map(driver_priv->bo, 1);
+	    if (ret) {
+		FatalError("failed to map pixmap %d\n", ret);
+		return FALSE;
+	    }
+
+	    pPix->devPrivate.ptr = driver_priv->bo->virtual;
+	}
+    }
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
     /* Front buffer is always set with proper swappers */
     if (offset == 0)
         return TRUE;
@@ -287,6 +339,7 @@ static Bool RADEONPrepareAccess(PixmapPtr pPix, int index)
     OUTREG(RADEON_SURFACE0_LOWER_BOUND + soff, offset);
     OUTREG(RADEON_SURFACE0_UPPER_BOUND + soff, offset + size - 1);
     swapper_surfaces[index] = offset;
+#endif
     return TRUE;
 }
 
@@ -296,7 +349,17 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
     unsigned char *RADEONMMIO = info->MMIO;
     uint32_t offset = exaGetPixmapOffset(pPix);
     int soff;
+    struct radeon_exa_pixmap_priv *driver_priv;
 
+    driver_priv = exaGetPixmapDriverPrivate(pPix);
+
+    if (driver_priv) {
+	dri_bo_unmap(driver_priv->bo);
+    pPix->devPrivate.ptr = NULL;
+    }
+
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
     /* Front buffer is always set with proper swappers */
     if (offset == 0)
         return;
@@ -319,9 +382,135 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
     OUTREG(RADEON_SURFACE0_LOWER_BOUND + soff, 0);
     OUTREG(RADEON_SURFACE0_UPPER_BOUND + soff, 0);
     swapper_surfaces[index] = 0;
+#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */
 }
 
-#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */
+void *RADEONEXACreatePixmap(ScreenPtr pScreen, int size, int align)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    struct radeon_exa_pixmap_priv *new_priv;
+
+    new_priv = xcalloc(1, sizeof(struct radeon_exa_pixmap_priv));
+    if (!new_priv)
+	return NULL;
+
+    if (size == 0)
+	return new_priv;
+
+    new_priv->bo = dri_bo_alloc(info->bufmgr, "exa pixmap", size,
+				align, 0);
+    if (!new_priv->bo) {
+	xfree(new_priv);
+	ErrorF("Failed to alloc memory\n");
+	return NULL;
+    }
+    
+    return new_priv;
+
+}
+
+static void RADEONEXADestroyPixmap(ScreenPtr pScreen, void *driverPriv)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    struct radeon_exa_pixmap_priv *driver_priv = driverPriv;
+    int ret;
+
+    dri_bo_unreference(driver_priv->bo);
+    xfree(driverPriv);
+}
+
+static Bool RADEONEXAModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
+					int depth, int bitsPerPixel, int devKind,
+					pointer pPixData)
+{
+    ScreenPtr   pScreen = pPixmap->drawable.pScreen;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    struct radeon_exa_pixmap_priv *driver_priv;
+
+    driver_priv = exaGetPixmapDriverPrivate(pPixmap);
+    if (!driver_priv)
+	return FALSE;
+
+
+    if (info->drm_mode_setting && drmmode_is_rotate_pixmap(pScrn, pPixData, &driver_priv->bo)){
+	dri_bo_unmap(driver_priv->bo);
+	dri_bo_reference(driver_priv->bo);
+	miModifyPixmapHeader(pPixmap, width, height, depth,
+                             bitsPerPixel, devKind, NULL);
+
+    	return TRUE;
+    }
+
+#if 0
+    if (pPixData == info->mm.front_buffer->map) {
+	if (driver_priv->bo)
+	  dri_bo_unreference(driver_priv->bo);
+
+	driver_priv->bo = radeon_bo_gem_create_from_name(info->bufmgr, "front",
+							 radeon_name_buffer(pScrn, info->mm.front_buffer));
+
+	if (!driver_priv->bo)
+	  return FALSE;
+
+	miModifyPixmapHeader(pPixmap, width, height, depth,
+                             bitsPerPixel, devKind, NULL);
+	return TRUE;
+    }
+#endif
+    return FALSE;
+}
+
+dri_bo *radeon_get_pixmap_bo(PixmapPtr pPix)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    
+#ifdef XF86DRM_MODE
+    struct radeon_exa_pixmap_priv *driver_priv;
+    driver_priv = exaGetPixmapDriverPrivate(pPix);
+    if (driver_priv)
+	if (driver_priv->bo)
+ 	    return driver_priv->bo;
+#endif
+    return NULL;
+
+}
+
+void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_memory *mem)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    
+#ifdef XF86DRM_MODE
+    struct radeon_exa_pixmap_priv *driver_priv;
+
+    driver_priv = exaGetPixmapDriverPrivate(pPix);
+    if (driver_priv) {
+	if (driver_priv->bo)
+	    dri_bo_unreference(driver_priv->bo);
+
+	driver_priv->bo = radeon_bo_gem_create_from_name(info->bufmgr, "front",
+							 radeon_name_buffer(pScrn, mem));
+    }
+#endif
+}
+    
+
+static Bool RADEONEXAPixmapIsOffscreen(PixmapPtr pPix)
+{
+    struct radeon_exa_pixmap_priv *driver_priv;
+
+    driver_priv = exaGetPixmapDriverPrivate(pPix);
+
+    if (!driver_priv)
+       return FALSE;
+    if (driver_priv->bo)
+       return TRUE;
+    return FALSE;
+}
 
 #define ENTER_DRAW(x) TRACE
 #define LEAVE_DRAW(x) TRACE
@@ -332,6 +521,7 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
 #define BEGIN_ACCEL(n)		RADEONWaitForFifo(pScrn, (n))
 #define OUT_ACCEL_REG(reg, val)	OUTREG(reg, val)
 #define OUT_ACCEL_REG_F(reg, val) OUTREG(reg, F_TO_DW(val))
+#define OUT_RELOC(x, read, write)            do {} while(0)
 #define FINISH_ACCEL()
 
 #ifdef RENDER
@@ -345,6 +535,7 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
 #undef OUT_ACCEL_REG
 #undef OUT_ACCEL_REG_F
 #undef FINISH_ACCEL
+#undef OUT_RELOC
 
 #ifdef XF86DRI
 
@@ -355,6 +546,7 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
 #define BEGIN_ACCEL(n)		BEGIN_RING(2*(n))
 #define OUT_ACCEL_REG(reg, val)	OUT_RING_REG(reg, val)
 #define FINISH_ACCEL()		ADVANCE_RING()
+#define OUT_RELOC(x, read, write) OUT_RING_RELOC(x, read, write)
 
 #define OUT_RING_F(x) OUT_RING(F_TO_DW(x))
 
@@ -372,6 +564,8 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
 
 #endif /* XF86DRI */
 
+
+
 /*
  * Once screen->off_screen_base is set, this function
  * allocates the remaining memory appropriately
@@ -393,122 +587,126 @@ Bool RADEONSetupMemEXA (ScreenPtr pScreen)
     if (info->accel_state->exa == NULL)
 	return FALSE;
 
-    /* Need to adjust screen size for 16 line tiles, and then make it align to.
-     * the buffer alignment requirement.
-     */
-    if (info->allowColorTiling)
-	screen_size = RADEON_ALIGN(pScrn->virtualY, 16) * byteStride;
-    else
-	screen_size = pScrn->virtualY * byteStride;
-
-    info->accel_state->exa->memoryBase = info->FB;
-    info->accel_state->exa->memorySize = info->FbMapSize - info->FbSecureSize;
-    info->accel_state->exa->offScreenBase = screen_size;
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Allocating from a screen of %ld kb\n",
-	       info->accel_state->exa->memorySize / 1024);
-
-    /* Reserve static area for hardware cursor */
-    if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
-        int cursor_size = 64 * 4 * 64;
-        int align = IS_AVIVO_VARIANT ? 4096 : 256;
-        int c;
-
-        for (c = 0; c < xf86_config->num_crtc; c++) {
-            xf86CrtcPtr crtc = xf86_config->crtc[c];
-            RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-
-            radeon_crtc->cursor_offset =
-                RADEON_ALIGN(info->accel_state->exa->offScreenBase, align);
-            info->accel_state->exa->offScreenBase = radeon_crtc->cursor_offset + cursor_size;
-
-            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                       "Will use %d kb for hardware cursor %d at offset 0x%08x\n",
-                       (cursor_size * xf86_config->num_crtc) / 1024,
-                       c,
-                       (unsigned int)radeon_crtc->cursor_offset);
-        }
-    }
-
-#if defined(XF86DRI)
-    if (info->directRenderingEnabled) {
-	int depthCpp = (info->dri->depthBits - 8) / 4, l, next, depth_size;
-
-	info->dri->frontOffset = 0;
-	info->dri->frontPitch = pScrn->displayWidth;
-
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "Will use %d kb for front buffer at offset 0x%08x\n",
-	       screen_size / 1024, info->dri->frontOffset);
-	RADEONDRIAllocatePCIGARTTable(pScreen);
-	
-	if (info->cardType==CARD_PCIE)
-	  xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		     "Will use %d kb for PCI GART at offset 0x%08x\n",
-		     info->dri->pciGartSize / 1024,
-		     (int)info->dri->pciGartOffset);
-
-	/* Reserve a static area for the back buffer the same size as the
-	 * visible screen.  XXX: This would be better initialized in ati_dri.c
-	 * when GLX is set up, but the offscreen memory manager's allocations
-	 * don't last through VT switches, while the kernel's understanding of
-	 * offscreen locations does.
+    
+    if (info->drm_mm == FALSE) {
+	/* Need to adjust screen size for 16 line tiles, and then make it align to.
+	 * the buffer alignment requirement.
 	 */
-	info->dri->backPitch = pScrn->displayWidth;
-	next = RADEON_ALIGN(info->accel_state->exa->offScreenBase, RADEON_BUFFER_ALIGN);
-	if (!info->dri->noBackBuffer &&
-	    next + screen_size <= info->accel_state->exa->memorySize)
-	{
-	    info->dri->backOffset = next;
-	    info->accel_state->exa->offScreenBase = next + screen_size;
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		       "Will use %d kb for back buffer at offset 0x%08x\n",
-		       screen_size / 1024, info->dri->backOffset);
+	if (info->allowColorTiling)
+	    screen_size = RADEON_ALIGN(pScrn->virtualY, 16) * byteStride;
+	else
+	    screen_size = pScrn->virtualY * byteStride;
+
+	info->accel_state->exa->memoryBase = info->FB;
+	info->accel_state->exa->memorySize = info->FbMapSize - info->FbSecureSize;
+	info->accel_state->exa->offScreenBase = screen_size;
+
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Allocating from a screen of %ld kb\n",
+		   info->accel_state->exa->memorySize / 1024);
+
+	/* Reserve static area for hardware cursor */
+	if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
+	    int cursor_size = 64 * 4 * 64;
+	    int align = IS_AVIVO_VARIANT ? 4096 : 256;
+	    int c;
+
+	    for (c = 0; c < xf86_config->num_crtc; c++) {
+		xf86CrtcPtr crtc = xf86_config->crtc[c];
+		RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+
+		radeon_crtc->cursor_offset =
+		    RADEON_ALIGN(info->accel_state->exa->offScreenBase, align);
+		info->accel_state->exa->offScreenBase = radeon_crtc->cursor_offset + cursor_size;
+		
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			   "Will use %d kb for hardware cursor %d at offset 0x%08x\n",
+			   (cursor_size * xf86_config->num_crtc) / 1024,
+			   c,
+			   (unsigned int)radeon_crtc->cursor_offset);
+	    }
 	}
 
-	/* Reserve the static depth buffer, and adjust pitch and height to
-	 * handle tiling.
-	 */
-	info->dri->depthPitch = RADEON_ALIGN(pScrn->displayWidth, 32);
-	depth_size = RADEON_ALIGN(pScrn->virtualY, 16) * info->dri->depthPitch * depthCpp;
-	next = RADEON_ALIGN(info->accel_state->exa->offScreenBase, RADEON_BUFFER_ALIGN);
-	if (next + depth_size <= info->accel_state->exa->memorySize)
-	{
-	    info->dri->depthOffset = next;
-	    info->accel_state->exa->offScreenBase = next + depth_size;
+#if defined(XF86DRI)
+	if (info->directRenderingEnabled) {
+	    int depthCpp = (info->dri->depthBits - 8) / 4, l, next, depth_size;
+	    
+	    info->dri->frontOffset = 0;
+	    info->dri->frontPitch = pScrn->displayWidth;
+	    
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		       "Will use %d kb for depth buffer at offset 0x%08x\n",
-		       depth_size / 1024, info->dri->depthOffset);
-	}
+		       "Will use %d kb for front buffer at offset 0x%08x\n",
+		       screen_size / 1024, info->dri->frontOffset);
+	    RADEONDRIAllocatePCIGARTTable(pScreen);
+
+	    if (info->cardType==CARD_PCIE)
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			   "Will use %d kb for PCI GART at offset 0x%08x\n",
+			   info->dri->pciGartSize / 1024,
+			   (int)info->dri->pciGartOffset);
+
+	    /* Reserve a static area for the back buffer the same size as the
+	     * visible screen.  XXX: This would be better initialized in ati_dri.c
+	     * when GLX is set up, but the offscreen memory manager's allocations
+	     * don't last through VT switches, while the kernel's understanding of
+	     * offscreen locations does.
+	     */
+	    info->dri->backPitch = pScrn->displayWidth;
+	    next = RADEON_ALIGN(info->accel_state->exa->offScreenBase, RADEON_BUFFER_ALIGN);
+	    if (!info->dri->noBackBuffer &&
+		next + screen_size <= info->accel_state->exa->memorySize)
+	    {
+		info->dri->backOffset = next;
+		info->accel_state->exa->offScreenBase = next + screen_size;
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			   "Will use %d kb for back buffer at offset 0x%08x\n",
+			   screen_size / 1024, info->dri->backOffset);
+	    }
+
+	    /* Reserve the static depth buffer, and adjust pitch and height to
+	     * handle tiling.
+	     */
+	    info->dri->depthPitch = RADEON_ALIGN(pScrn->displayWidth, 32);
+	    depth_size = RADEON_ALIGN(pScrn->virtualY, 16) * info->dri->depthPitch * depthCpp;
+	    next = RADEON_ALIGN(info->accel_state->exa->offScreenBase, RADEON_BUFFER_ALIGN);
+	    if (next + depth_size <= info->accel_state->exa->memorySize)
+	    {
+		info->dri->depthOffset = next;
+		info->accel_state->exa->offScreenBase = next + depth_size;
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			   "Will use %d kb for depth buffer at offset 0x%08x\n",
+			   depth_size / 1024, info->dri->depthOffset);
+	    }
 	
-	info->dri->textureSize *= (info->accel_state->exa->memorySize -
-				   info->accel_state->exa->offScreenBase) / 100;
-
-	l = RADEONLog2(info->dri->textureSize / RADEON_NR_TEX_REGIONS);
-	if (l < RADEON_LOG_TEX_GRANULARITY)
-	    l = RADEON_LOG_TEX_GRANULARITY;
-	info->dri->textureSize = (info->dri->textureSize >> l) << l;
-	if (info->dri->textureSize >= 512 * 1024) {
-	    info->dri->textureOffset = info->accel_state->exa->offScreenBase;
-	    info->accel_state->exa->offScreenBase += info->dri->textureSize;
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		       "Will use %d kb for textures at offset 0x%08x\n",
-		       info->dri->textureSize / 1024, info->dri->textureOffset);
-	} else {
-	    /* Minimum texture size is for 2 256x256x32bpp textures */
-	    info->dri->textureSize = 0;
-	}
-    } else
+	    info->dri->textureSize *= (info->accel_state->exa->memorySize -
+				       info->accel_state->exa->offScreenBase) / 100;
+
+	    l = RADEONLog2(info->dri->textureSize / RADEON_NR_TEX_REGIONS);
+	    if (l < RADEON_LOG_TEX_GRANULARITY)
+		l = RADEON_LOG_TEX_GRANULARITY;
+	    info->dri->textureSize = (info->dri->textureSize >> l) << l;
+	    if (info->dri->textureSize >= 512 * 1024) {
+		info->dri->textureOffset = info->accel_state->exa->offScreenBase;
+		info->accel_state->exa->offScreenBase += info->dri->textureSize;
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			   "Will use %d kb for textures at offset 0x%08x\n",
+			   info->dri->textureSize / 1024, info->dri->textureOffset);
+	    } else {
+		/* Minimum texture size is for 2 256x256x32bpp textures */
+		info->dri->textureSize = 0;
+	    }
+	} else
 #endif /* XF86DRI */
-    	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		       "Will use %d kb for front buffer at offset 0x%08x\n",
 		       screen_size / 1024, 0);
-
+	
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	       "Will use %ld kb for X Server offscreen at offset 0x%08lx\n",
 	       (info->accel_state->exa->memorySize - info->accel_state->exa->offScreenBase) /
 	       1024, info->accel_state->exa->offScreenBase);
 
+    }
+
     return TRUE;
 }
 
@@ -523,14 +721,23 @@ RADEONTexOffsetStart(PixmapPtr pPix)
 {
     RINFO_FROM_SCREEN(pPix->drawable.pScreen);
     unsigned long long offset;
-    exaMoveInPixmap(pPix);
-    ExaOffscreenMarkUsed(pPix);
-
-    offset = exaGetPixmapOffset(pPix);
+    struct radeon_exa_pixmap_priv *driver_priv;
+
+    driver_priv = exaGetPixmapDriverPrivate(pPix);
+
+    if (driver_priv) {
+        //offset = dri_bo_get_handle(driver_priv->bo);
+        offset = driver_priv->bo->offset;
+    } else {
+    	exaMoveInPixmap(pPix);
+        offset = exaGetPixmapOffset(pPix);
+    	if (offset > info->FbMapSize)
+		return ~0ULL;
+    	else
+    		offset += info->fbLocation;
+        ExaOffscreenMarkUsed(pPix);
+    }
 
-    if (offset > info->FbMapSize)
-	return ~0ULL;
-    else
-	return info->fbLocation + offset;
+    return offset;
 }
 #endif
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index 59cb46f..7172cc2 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -74,21 +74,73 @@ FUNC_NAME(RADEONSync)(ScreenPtr pScreen, int marker)
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     RADEONInfoPtr info = RADEONPTR(pScrn);
 
+    if (info->new_cs)
+	    return;
+
     TRACE;
 
     if (info->accel_state->exaMarkerSynced != marker) {
-	FUNC_NAME(RADEONWaitForIdle)(pScrn);
+        FUNC_NAME(RADEONWaitForIdle)(pScrn);
 	info->accel_state->exaMarkerSynced = marker;
     }
 
     RADEONPTR(pScrn)->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
 }
 
+static void FUNC_NAME(Emit2DState)(ScrnInfoPtr pScrn, int op)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    uint32_t qwords;
+    int has_src;
+    ACCEL_PREAMBLE();
+
+    /* don't emit if no operation in progress */
+    if (info->state_2d.op == 0 && op == 0)
+	return;
+
+    has_src = info->state_2d.src_pitch_offset || (info->new_cs && info->state_2d.src_bo);
+
+    qwords = info->new_cs ? 10 : 9;
+    qwords += (has_src ? (info->new_cs ?  2 : 1) : 0);
+
+    BEGIN_ACCEL(qwords);
+    OUT_ACCEL_REG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, info->state_2d.default_sc_bottom_right);
+    OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->state_2d.dp_gui_master_cntl);
+    OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, info->state_2d.dp_brush_frgd_clr);
+    OUT_ACCEL_REG(RADEON_DP_BRUSH_BKGD_CLR, info->state_2d.dp_brush_bkgd_clr);
+    OUT_ACCEL_REG(RADEON_DP_SRC_FRGD_CLR,   info->state_2d.dp_src_frgd_clr);
+    OUT_ACCEL_REG(RADEON_DP_SRC_BKGD_CLR,   info->state_2d.dp_src_bkgd_clr);
+    OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, info->state_2d.dp_write_mask);
+    OUT_ACCEL_REG(RADEON_DP_CNTL, info->state_2d.dp_cntl);
+
+    OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset);
+    if (info->new_cs)
+	OUT_RELOC(info->state_2d.dst_bo, 0, RADEON_GEM_DOMAIN_VRAM);
+
+    if (has_src) {
+	    OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset);
+	    if (info->new_cs)
+		OUT_RELOC(info->state_2d.src_bo, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0);
+	    
+    }
+    FINISH_ACCEL();
+
+    if (op)
+	info->state_2d.op = op;
+    if (info->new_cs)
+	info->reemit_current2d = FUNC_NAME(Emit2DState);
+}
+
 static Bool
 FUNC_NAME(RADEONPrepareSolid)(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
 {
     RINFO_FROM_SCREEN(pPix->drawable.pScreen);
     uint32_t datatype, dst_pitch_offset;
+    struct radeon_exa_pixmap_priv *driver_priv;
+    int ret;
+    int retry_count = 0;
+    struct radeon_space_check bos[1];
+    int i;
     ACCEL_PREAMBLE();
 
     TRACE;
@@ -97,25 +149,58 @@ FUNC_NAME(RADEONPrepareSolid)(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
 	RADEON_FALLBACK(("24bpp unsupported\n"));
     if (!RADEONGetDatatypeBpp(pPix->drawable.bitsPerPixel, &datatype))
 	RADEON_FALLBACK(("RADEONGetDatatypeBpp failed\n"));
+
     if (!RADEONGetPixmapOffsetPitch(pPix, &dst_pitch_offset))
-	RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch failed\n"));
+        RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch failed\n"));
+
+ retry:
+    if (info->new_cs) {
+      
+	i = 0;
+	driver_priv = exaGetPixmapDriverPrivate(pPix);
+	bos[i].buf = driver_priv->bo;
+	bos[i].read_domains = 0;
+	bos[i].write_domain = RADEON_GEM_DOMAIN_VRAM;;
+	i++;
+
+	ret = dri_bufmgr_check_aperture_space(bos, i);
+	if (ret == BUFMGR_SPACE_OP_TO_BIG) {
+	    RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n"));
+	}
+	if (ret == BUFMGR_SPACE_FLUSH) {
+	    RADEONCPFlushIndirect(pScrn, 1);
+	    retry_count++;
+	    if (retry_count == 2)
+	        RADEON_FALLBACK(("Not enough Video RAM for src\n"));
+	    goto retry;
+	}
+    }
 
     RADEON_SWITCH_TO_2D();
 
-    BEGIN_ACCEL(5);
-    OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL,
-	    RADEON_GMC_DST_PITCH_OFFSET_CNTL |
-	    RADEON_GMC_BRUSH_SOLID_COLOR |
-	    (datatype << 8) |
-	    RADEON_GMC_SRC_DATATYPE_COLOR |
-	    RADEON_ROP[alu].pattern |
-	    RADEON_GMC_CLR_CMP_CNTL_DIS);
-    OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, fg);
-    OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, pm);
-    OUT_ACCEL_REG(RADEON_DP_CNTL,
-	(RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM));
-    OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset);
-    FINISH_ACCEL();
+    info->state_2d.default_sc_bottom_right = (RADEON_DEFAULT_SC_RIGHT_MAX |
+					       RADEON_DEFAULT_SC_BOTTOM_MAX);
+    info->state_2d.dp_brush_bkgd_clr = 0x00000000;
+    info->state_2d.dp_src_frgd_clr = 0xffffffff;
+    info->state_2d.dp_src_bkgd_clr = 0x00000000;
+    info->state_2d.dp_gui_master_cntl = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+					  RADEON_GMC_BRUSH_SOLID_COLOR |
+					  (datatype << 8) |
+					  RADEON_GMC_SRC_DATATYPE_COLOR |
+					  RADEON_ROP[alu].pattern |
+					  RADEON_GMC_CLR_CMP_CNTL_DIS);
+    info->state_2d.dp_brush_frgd_clr = fg;
+    info->state_2d.dp_cntl = (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM);
+    info->state_2d.dp_write_mask = pm;
+    info->state_2d.dst_pitch_offset = dst_pitch_offset;
+    info->state_2d.src_pitch_offset = 0;
+    info->state_2d.src_bo = NULL;
+
+    driver_priv = exaGetPixmapDriverPrivate(pPix);
+    if (driver_priv)
+      info->state_2d.dst_bo = driver_priv->bo;
+
+    FUNC_NAME(Emit2DState)(pScrn, RADEON_2D_EXA_SOLID);
 
     return TRUE;
 }
@@ -146,6 +231,7 @@ FUNC_NAME(RADEONDoneSolid)(PixmapPtr pPix)
 
     TRACE;
 
+    info->state_2d.op = 0;
     BEGIN_ACCEL(2);
     OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL);
     OUT_ACCEL_REG(RADEON_WAIT_UNTIL,
@@ -153,6 +239,7 @@ FUNC_NAME(RADEONDoneSolid)(PixmapPtr pPix)
     FINISH_ACCEL();
 }
 
+
 void
 FUNC_NAME(RADEONDoPrepareCopy)(ScrnInfoPtr pScrn, uint32_t src_pitch_offset,
 			       uint32_t dst_pitch_offset, uint32_t datatype, int rop,
@@ -163,23 +250,28 @@ FUNC_NAME(RADEONDoPrepareCopy)(ScrnInfoPtr pScrn, uint32_t src_pitch_offset,
 
     RADEON_SWITCH_TO_2D();
 
-    BEGIN_ACCEL(5);
-    OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL,
-	RADEON_GMC_DST_PITCH_OFFSET_CNTL |
-	RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
-	RADEON_GMC_BRUSH_NONE |
-	(datatype << 8) |
-	RADEON_GMC_SRC_DATATYPE_COLOR |
-	RADEON_ROP[rop].rop |
-	RADEON_DP_SRC_SOURCE_MEMORY |
-	RADEON_GMC_CLR_CMP_CNTL_DIS);
-    OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask);
-    OUT_ACCEL_REG(RADEON_DP_CNTL,
-	((info->accel_state->xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) |
-	 (info->accel_state->ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0)));
-    OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset);
-    OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, src_pitch_offset);
-    FINISH_ACCEL();
+    /* setup 2D state */
+    info->state_2d.dp_gui_master_cntl = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+					  RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
+					  RADEON_GMC_BRUSH_NONE |
+					  (datatype << 8) |
+					  RADEON_GMC_SRC_DATATYPE_COLOR |
+					  RADEON_ROP[rop].rop |
+					  RADEON_DP_SRC_SOURCE_MEMORY |
+					  RADEON_GMC_CLR_CMP_CNTL_DIS);
+    info->state_2d.dp_cntl = ((info->accel_state->xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) |
+			       (info->accel_state->ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0));
+    info->state_2d.dp_brush_frgd_clr = 0xffffffff;
+    info->state_2d.dp_brush_bkgd_clr = 0x00000000;
+    info->state_2d.dp_src_frgd_clr = 0xffffffff;
+    info->state_2d.dp_src_bkgd_clr = 0x00000000;
+    info->state_2d.dp_write_mask = planemask;
+    info->state_2d.dst_pitch_offset = dst_pitch_offset;
+    info->state_2d.src_pitch_offset = src_pitch_offset;
+    info->state_2d.default_sc_bottom_right =  (RADEON_DEFAULT_SC_RIGHT_MAX
+						| RADEON_DEFAULT_SC_BOTTOM_MAX);
+
+    FUNC_NAME(Emit2DState)(pScrn, RADEON_2D_EXA_COPY);
 }
 
 static Bool
@@ -190,9 +282,46 @@ FUNC_NAME(RADEONPrepareCopy)(PixmapPtr pSrc,   PixmapPtr pDst,
 {
     RINFO_FROM_SCREEN(pDst->drawable.pScreen);
     uint32_t datatype, src_pitch_offset, dst_pitch_offset;
-
+    struct radeon_exa_pixmap_priv *driver_priv;
+    int ret;
+    int retry_count = 0;
+    struct radeon_space_check bos[2];
+    int i;
     TRACE;
 
+retry:
+    if (info->new_cs) {
+      
+	i = 0;
+	driver_priv = exaGetPixmapDriverPrivate(pSrc);
+	info->state_2d.src_bo = driver_priv->bo;
+	bos[i].buf = driver_priv->bo;
+	bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
+	bos[i].write_domain = 0;
+	i++;
+
+
+	driver_priv = exaGetPixmapDriverPrivate(pDst);
+	info->state_2d.dst_bo = driver_priv->bo;
+	bos[i].buf = driver_priv->bo;
+	bos[i].read_domains = 0;
+	bos[i].write_domain = RADEON_GEM_DOMAIN_VRAM;;
+	i++;
+
+	ret = dri_bufmgr_check_aperture_space(bos, i);
+	if (ret == BUFMGR_SPACE_OP_TO_BIG) {
+	    RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n"));
+	}
+	if (ret == BUFMGR_SPACE_FLUSH) {
+	    RADEONCPFlushIndirect(pScrn, 1);
+	    retry_count++;
+	    if (retry_count == 2)
+	        RADEON_FALLBACK(("Not enough Video RAM for src\n"));
+	    goto retry;
+	}
+    }
+
+
     info->accel_state->xdir = xdir;
     info->accel_state->ydir = ydir;
 
@@ -200,10 +329,11 @@ FUNC_NAME(RADEONPrepareCopy)(PixmapPtr pSrc,   PixmapPtr pDst,
 	RADEON_FALLBACK(("24bpp unsupported"));
     if (!RADEONGetDatatypeBpp(pDst->drawable.bitsPerPixel, &datatype))
 	RADEON_FALLBACK(("RADEONGetDatatypeBpp failed\n"));
+
     if (!RADEONGetPixmapOffsetPitch(pSrc, &src_pitch_offset))
-	RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch source failed\n"));
+        RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch source failed\n"));
     if (!RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_offset))
-	RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch dest failed\n"));
+        RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch dest failed\n"));
 
     FUNC_NAME(RADEONDoPrepareCopy)(pScrn, src_pitch_offset, dst_pitch_offset,
 				   datatype, rop, planemask);
@@ -251,6 +381,7 @@ FUNC_NAME(RADEONDoneCopy)(PixmapPtr pDst)
 
     TRACE;
 
+    info->state_2d.op = 0;
     BEGIN_ACCEL(2);
     OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL);
     OUT_ACCEL_REG(RADEON_WAIT_UNTIL,
@@ -261,12 +392,15 @@ FUNC_NAME(RADEONDoneCopy)(PixmapPtr pDst)
 
 #ifdef ACCEL_CP
 
+#if 0
 static Bool
 RADEONUploadToScreenCP(PixmapPtr pDst, int x, int y, int w, int h,
 		       char *src, int src_pitch)
 {
     RINFO_FROM_SCREEN(pDst->drawable.pScreen);
     unsigned int   bpp	     = pDst->drawable.bitsPerPixel;
+    int ret;
+    struct radeon_exa_pixmap_priv *driver_priv;
     unsigned int   hpass;
     uint32_t	   buf_pitch, dst_pitch_off;
 
@@ -275,9 +409,45 @@ RADEONUploadToScreenCP(PixmapPtr pDst, int x, int y, int w, int h,
     if (bpp < 8)
 	return FALSE;
 
-    if (info->directRenderingEnabled &&
-	RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_off)) {
-	uint8_t *buf;
+    if (info->new_cs){
+
+	if (info->drm_mm) {
+	    uint32_t offset, bo_width, bo_height = h;
+
+	    driver_priv = exaGetPixmapDriverPrivate(pDst);
+	    if (!driver_priv)
+		return FALSE;
+
+
+	    if (radeon_bufmgr_gem_has_references(driver_priv->bo))
+		RADEONCPFlushIndirect(pScrn, 0);
+
+	    radeon_bufmgr_gem_wait_rendering(driver_priv->bo);
+
+	    /* use pwrites - maybe require some sort of fallback */
+	    bo_width = w * (bpp / 8);
+	    offset = (x * bpp / 8) + (y * dst_pitch);
+
+	    while (bo_height--) {
+		dri_bo_subdata(driver_priv->bo, offset, bo_width,
+				     src);
+		    
+		src += src_pitch;
+		offset += dst_pitch;
+	    }
+
+	    return TRUE;
+	}
+    }
+    if (!info->directRenderingEnabled && !info->drm_mode_setting)
+        goto fallback;
+
+    if (!RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_off))
+        goto fallback;
+
+    if (!info->new_cs)
+    {
+        uint8_t *buf;
 	int cpp = bpp / 8;
 	ACCEL_PREAMBLE();
 
@@ -300,17 +470,24 @@ RADEONUploadToScreenCP(PixmapPtr pDst, int x, int y, int w, int h,
 
     return FALSE;
 }
+#endif
 
 /* Emit blit with arbitrary source and destination offsets and pitches */
 static void
-RADEONBlitChunk(ScrnInfoPtr pScrn, uint32_t datatype, uint32_t src_pitch_offset,
+RADEONBlitChunk(ScrnInfoPtr pScrn, uint32_t datatype, dri_bo *src_bo, dri_bo *dst_bo,
+		uint32_t src_pitch_offset,
 		uint32_t dst_pitch_offset, int srcX, int srcY, int dstX, int dstY,
 		int w, int h)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
+    uint32_t qwords;
     ACCEL_PREAMBLE();
 
-    BEGIN_ACCEL(6);
+    qwords = 6;
+    if (src_bo && dst_bo)
+	qwords += 2;
+
+    BEGIN_ACCEL(qwords);
     OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL,
 		  RADEON_GMC_DST_PITCH_OFFSET_CNTL |
 		  RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
@@ -321,8 +498,14 @@ RADEONBlitChunk(ScrnInfoPtr pScrn, uint32_t datatype, uint32_t src_pitch_offset,
 		  RADEON_DP_SRC_SOURCE_MEMORY |
 		  RADEON_GMC_CLR_CMP_CNTL_DIS |
 		  RADEON_GMC_WR_MSK_DIS);
+    
     OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, src_pitch_offset);
+    if (src_bo)
+	OUT_RELOC(src_bo, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0);
     OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset);
+    if (dst_bo)
+	OUT_RELOC(dst_bo, 0, RADEON_GEM_DOMAIN_GTT);
+
     OUT_ACCEL_REG(RADEON_SRC_Y_X, (srcY << 16) | srcX);
     OUT_ACCEL_REG(RADEON_DST_Y_X, (dstY << 16) | dstX);
     OUT_ACCEL_REG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w);
@@ -334,6 +517,173 @@ RADEONBlitChunk(ScrnInfoPtr pScrn, uint32_t datatype, uint32_t src_pitch_offset,
     FINISH_ACCEL();
 }
 
+static Bool
+RADEON_DFS_CS2(PixmapPtr pSrc, int x, int y, int w, int h,
+		       char *dst, int dst_pitch)
+{
+    RINFO_FROM_SCREEN(pSrc->drawable.pScreen);
+    struct radeon_exa_pixmap_priv *driver_priv;
+    int		   src_pitch = exaGetPixmapPitch(pSrc);
+    int		   bpp	     = pSrc->drawable.bitsPerPixel;
+    uint32_t src_offset;
+    /* force into GTT? */
+
+    if (!info->accelDFS)
+	return FALSE;
+	
+    driver_priv = exaGetPixmapDriverPrivate(pSrc);
+
+    radeon_bufmgr_gem_force_gtt(driver_priv->bo);
+    radeon_bufmgr_gem_wait_rendering(driver_priv->bo);
+
+    dri_bo_map(driver_priv->bo, 0);
+
+    src_offset = (x * bpp / 8) + (y * src_pitch);
+    w *= bpp / 8;
+
+    while (h--) {
+	    memcpy(dst, driver_priv->bo->virtual + src_offset, w);
+	    src_offset += src_pitch;
+	    dst += dst_pitch;
+    }
+    dri_bo_unmap(driver_priv->bo);
+    return TRUE;
+}
+
+static Bool
+RADEON_DFS_CS(PixmapPtr pSrc, int x, int y, int w, int h,
+		       char *dst, int dst_pitch)
+{
+    RINFO_FROM_SCREEN(pSrc->drawable.pScreen);
+    struct radeon_exa_pixmap_priv *driver_priv;
+    dri_bo *scratch_bo[2];
+    int i, ret;
+    uint32_t scratch_size = RADEON_BUFFER_SIZE / 2;
+    int		   bpp	     = pSrc->drawable.bitsPerPixel;
+    uint32_t scratch_pitch = (w * bpp/8 + 63) & ~63, scratch_off = 0;
+    uint32_t datatype;
+    int		   src_pitch = exaGetPixmapPitch(pSrc);
+    dri_bo *cur_scratch;
+    uint32_t src_pitch_offset;
+    struct radeon_space_check bos[3];
+    int retry_count;
+    
+    if (!info->accelDFS)
+	return FALSE;
+
+    driver_priv = exaGetPixmapDriverPrivate(pSrc);
+
+    if (radeon_bufmgr_gem_has_references(driver_priv->bo))
+	RADEONCPFlushIndirect(pScrn, 0);
+
+    /* if we haven't put this buffer in VRAM then just force gtt and memcpy from it */
+    if (!radeon_bufmgr_gem_in_vram(driver_priv->bo)) {
+	return RADEON_DFS_CS2(pSrc, x, y, w, h, dst, dst_pitch);
+    }
+    RADEONGetDatatypeBpp(bpp, &datatype);
+    scratch_bo[0] = scratch_bo[1] = NULL;
+    for (i = 0; i < 2; i++) {
+	scratch_bo[i] = dri_bo_alloc(info->bufmgr, "DFS scratch", scratch_size, 0, 0);
+	if (!scratch_bo[i])
+	    goto fail;
+    }
+
+retry:
+    i = 0;
+    bos[i].buf = driver_priv->bo;
+    bos[i].read_domains = RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM;
+    bos[i].write_domain = 0;
+    i++;
+    bos[i].buf = scratch_bo[0];
+    bos[i].read_domains = 0;
+    bos[i].write_domain = RADEON_GEM_DOMAIN_GTT;
+    i++;
+    bos[i].buf = scratch_bo[1];
+    bos[i].read_domains = 0;
+    bos[i].write_domain = RADEON_GEM_DOMAIN_GTT;
+    i++;
+
+    ret = dri_bufmgr_check_aperture_space(bos, i);
+    if (ret == BUFMGR_SPACE_OP_TO_BIG)
+	goto fail;
+    if (ret == BUFMGR_SPACE_FLUSH) {
+	RADEONCPFlushIndirect(pScrn, 1);
+	retry_count++;
+	if (retry_count == 2)
+	    goto fail;
+	goto retry;
+    }
+    
+    /* we want to blit from the BO to the scratch and memcpy out of the scratch */
+    {
+	int wpass = wpass = w * bpp / 8;
+	int hpass = min(h, scratch_size / scratch_pitch);
+	uint32_t pitch_offset = scratch_pitch << 16;
+
+	RADEONGetPixmapOffsetPitch(pSrc, &src_pitch_offset);
+
+	ACCEL_PREAMBLE();
+	RADEON_SWITCH_TO_2D();
+
+	cur_scratch = scratch_bo[0];
+	RADEONBlitChunk(pScrn, datatype, driver_priv->bo, cur_scratch, src_pitch_offset,
+			  pitch_offset,
+			  x, y, 0, 0, w, hpass);
+
+	FLUSH_RING();
+
+	while (h) {
+	    int swap = RADEON_HOST_DATA_SWAP_NONE;
+	    int oldhpass = hpass, i = 0;
+	    dri_bo *old_scratch;
+	    uint8_t *src;
+
+	    old_scratch = cur_scratch;
+	    y += oldhpass;
+	    h -= oldhpass;
+	    hpass = min(h, scratch_size / scratch_pitch);
+	    if (hpass) {
+		if (cur_scratch == scratch_bo[0])
+		    cur_scratch = scratch_bo[1];
+		else
+		    cur_scratch = scratch_bo[0];
+
+		RADEONBlitChunk(pScrn, datatype, driver_priv->bo, cur_scratch, src_pitch_offset,
+				pitch_offset,
+				x, y, 0, 0, w, hpass);
+	    }
+
+	    ret = dri_bo_map(old_scratch, 0);
+	    
+	    if (hpass)
+		FLUSH_RING();
+
+	    src = old_scratch->virtual;
+
+	    if (wpass == scratch_pitch && wpass == dst_pitch) {
+		RADEONCopySwap((uint8_t*)dst, src, wpass * oldhpass, swap);
+		dst += dst_pitch * oldhpass;
+	    } else while (oldhpass--) {
+		RADEONCopySwap((uint8_t*)dst, src, wpass, swap);
+		src += scratch_pitch;
+		dst += dst_pitch;
+	    }
+	    dri_bo_unmap(old_scratch);
+	}
+
+	dri_bo_unreference(scratch_bo[0]);
+	dri_bo_unreference(scratch_bo[1]);
+	return TRUE;
+    }
+
+
+ fail:
+    if (scratch_bo[0])
+	dri_bo_unreference(scratch_bo[0]);
+    if (scratch_bo[1])
+	dri_bo_unreference(scratch_bo[1]);
+    return FALSE;
+}
 
 static Bool
 RADEONDownloadFromScreenCP(PixmapPtr pSrc, int x, int y, int w, int h,
@@ -347,12 +697,17 @@ RADEONDownloadFromScreenCP(PixmapPtr pSrc, int x, int y, int w, int h,
 
     TRACE;
 
+    if (info->new_cs) {
+	return RADEON_DFS_CS(pSrc, x, y, w, h, dst, dst_pitch);
+    }
+
     /*
      * Try to accelerate download. Use an indirect buffer as scratch space,
      * blitting the bits to one half while copying them out of the other one and
      * then swapping the halves.
      */
-    if (bpp != 24 && RADEONGetDatatypeBpp(bpp, &datatype) &&
+    if (!info->drm_mm && info->accelDFS && bpp != 24 &&
+	RADEONGetDatatypeBpp(bpp, &datatype) &&
 	RADEONGetPixmapOffsetPitch(pSrc, &src_pitch_offset) &&
 	(scratch = RADEONCPGetBuffer(pScrn)))
     {
@@ -367,7 +722,8 @@ RADEONDownloadFromScreenCP(PixmapPtr pSrc, int x, int y, int w, int h,
 	RADEON_SWITCH_TO_2D();
 
 	/* Kick the first blit as early as possible */
-	RADEONBlitChunk(pScrn, datatype, src_pitch_offset, scratch_pitch_offset,
+	RADEONBlitChunk(pScrn, datatype, NULL, NULL,
+			src_pitch_offset, scratch_pitch_offset,
 			x, y, 0, 0, w, hpass);
 	FLUSH_RING();
 
@@ -394,7 +750,8 @@ RADEONDownloadFromScreenCP(PixmapPtr pSrc, int x, int y, int w, int h,
 	    /* Prepare next blit if anything's left */
 	    if (hpass) {
 		scratch_off = scratch->total/2 - scratch_off;
-		RADEONBlitChunk(pScrn, datatype, src_pitch_offset, scratch_pitch_offset + (scratch_off >> 10),
+		RADEONBlitChunk(pScrn, datatype, NULL, NULL,
+				src_pitch_offset, scratch_pitch_offset + (scratch_off >> 10),
 				x, y, 0, 0, w, hpass);
 	    }
 
@@ -468,15 +825,13 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
     info->accel_state->exa->MarkSync = FUNC_NAME(RADEONMarkSync);
     info->accel_state->exa->WaitMarker = FUNC_NAME(RADEONSync);
 #ifdef ACCEL_CP
-    info->accel_state->exa->UploadToScreen = RADEONUploadToScreenCP;
+  //  info->accel_state->exa->UploadToScreen = RADEONUploadToScreenCP;
     if (info->accelDFS)
 	info->accel_state->exa->DownloadFromScreen = RADEONDownloadFromScreenCP;
 #endif
 
-#if X_BYTE_ORDER == X_BIG_ENDIAN
     info->accel_state->exa->PrepareAccess = RADEONPrepareAccess;
     info->accel_state->exa->FinishAccess = RADEONFinishAccess;
-#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */
 
     info->accel_state->exa->flags = EXA_OFFSCREEN_PIXMAPS;
 #ifdef EXA_SUPPORTS_PREPARE_AUX
@@ -485,6 +840,11 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
     info->accel_state->exa->pixmapOffsetAlign = RADEON_BUFFER_ALIGN + 1;
     info->accel_state->exa->pixmapPitchAlign = 64;
 
+    if (info->drm_mm) {
+      info->accel_state->exa->flags |= EXA_HANDLES_PIXMAPS;
+    } else {
+    }
+
 #ifdef RENDER
     if (info->RenderAccel) {
 	if (info->ChipFamily >= CHIP_FAMILY_R600)
@@ -493,7 +853,7 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
 	else if (IS_R300_3D || IS_R500_3D) {
 	    if ((info->ChipFamily < CHIP_FAMILY_RS400)
 #ifdef XF86DRI
-		|| (info->directRenderingEnabled)
+		|| (info->directRenderingEnabled || info->drm_mode_setting)
 #endif
 		) {
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration "
@@ -528,6 +888,16 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
     }
 #endif
 
+#if (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 4)
+    if (info->drm_mm) {
+        info->accel_state->exa->CreatePixmap = RADEONEXACreatePixmap;
+        info->accel_state->exa->DestroyPixmap = RADEONEXADestroyPixmap;
+        info->accel_state->exa->PixmapIsOffscreen = RADEONEXAPixmapIsOffscreen;
+        info->accel_state->exa->ModifyPixmapHeader = RADEONEXAModifyPixmapHeader;
+    }
+#endif
+
+
 #if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3)
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting EXA maxPitchBytes\n");
 
diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c
index 571204a..ca46505 100644
--- a/src/radeon_exa_render.c
+++ b/src/radeon_exa_render.c
@@ -54,6 +54,10 @@
 #define ONLY_ONCE
 #endif
 
+#define VTX_COUNT_MASK 6
+#define VTX_COUNT 4
+
+
 /* Only include the following (generic) bits once. */
 #ifdef ONLY_ONCE
 
@@ -365,12 +369,14 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
     Bool repeat = pPict->repeat && pPict->repeatType != RepeatPad &&
 	!(unit == 0 && (info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y));
     int i;
+    struct radeon_exa_pixmap_priv *driver_priv;
+    int qwords;
     ACCEL_PREAMBLE();
 
     txpitch = exaGetPixmapPitch(pPix);
-    txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset;
+    txoffset = exaGetPixmapOffset(pPix);
 
-    if ((txoffset & 0x1f) != 0)
+    if (!info->new_cs && ((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));
@@ -426,23 +432,43 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
 	}
     }
 
-    BEGIN_ACCEL(5);
+    qwords = info->new_cs ? 6 : 5;
+    BEGIN_ACCEL(qwords);
     if (unit == 0) {
 	OUT_ACCEL_REG(RADEON_PP_TXFILTER_0, txfilter);
 	OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat);
-	OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, txoffset);
 	OUT_ACCEL_REG(RADEON_PP_TEX_SIZE_0,
 	    (pPix->drawable.width - 1) |
 	    ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
 	OUT_ACCEL_REG(RADEON_PP_TEX_PITCH_0, txpitch - 32);
+
+	if (info->new_cs) {
+	    driver_priv = exaGetPixmapDriverPrivate(pPix); 
+	    OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, 0);
+	    OUT_RELOC(driver_priv->bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
+	} else {
+	    txoffset += info->fbLocation + pScrn->fbOffset;
+	    OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, txoffset);
+	}
+	/* emit a texture relocation */
     } else {
 	OUT_ACCEL_REG(RADEON_PP_TXFILTER_1, txfilter);
 	OUT_ACCEL_REG(RADEON_PP_TXFORMAT_1, txformat);
-	OUT_ACCEL_REG(RADEON_PP_TXOFFSET_1, txoffset);
+
 	OUT_ACCEL_REG(RADEON_PP_TEX_SIZE_1,
 	    (pPix->drawable.width - 1) |
 	    ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
 	OUT_ACCEL_REG(RADEON_PP_TEX_PITCH_1, txpitch - 32);
+	if (info->new_cs) {
+	    driver_priv = exaGetPixmapDriverPrivate(pPix); 
+	    OUT_ACCEL_REG(RADEON_PP_TXOFFSET_1, 0);
+	    OUT_RELOC(driver_priv->bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
+	} else {
+	    txoffset += info->fbLocation + pScrn->fbOffset;
+	    OUT_ACCEL_REG(RADEON_PP_TXOFFSET_1, txoffset);
+	}
+	    
+	/* emit a texture relocation */
     }
     FINISH_ACCEL();
 
@@ -551,10 +577,52 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op,
     uint32_t dst_format, dst_offset, dst_pitch, colorpitch;
     uint32_t pp_cntl, blendcntl, cblend, ablend;
     int pixel_shift;
+    struct radeon_exa_pixmap_priv *driver_priv;
+    int qwords;
+    int retry_count = 0;
+    struct radeon_space_check bos[3];
+    int i, ret;
     ACCEL_PREAMBLE();
 
     TRACE;
 
+ retry:
+    if (info->new_cs) {
+      
+	i = 0;
+	driver_priv = exaGetPixmapDriverPrivate(pSrc);
+	bos[i].buf = driver_priv->bo;
+	bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
+	bos[i].write_domain = 0;
+	i++;
+
+	if (pMask) {
+	    driver_priv = exaGetPixmapDriverPrivate(pMask);
+	    bos[i].buf = driver_priv->bo;
+	    bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
+	    bos[i].write_domain = 0;
+	    i++;
+	}
+
+	driver_priv = exaGetPixmapDriverPrivate(pDst);
+	bos[i].buf = driver_priv->bo;
+	bos[i].read_domains = 0;
+	bos[i].write_domain = RADEON_GEM_DOMAIN_VRAM;;
+	i++;
+
+	ret = dri_bufmgr_check_aperture_space(bos, i);
+	if (ret == BUFMGR_SPACE_OP_TO_BIG) {
+	    RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n"));
+	}
+	if (ret == BUFMGR_SPACE_FLUSH) {
+	    RADEONCPFlushIndirect(pScrn, 1);
+	    retry_count++;
+	    if (retry_count == 2)
+	        RADEON_FALLBACK(("Not enough Video RAM for src\n"));
+	    goto retry;
+	}
+    }
+
     if (!RADEONGetDestFormat(pDstPicture, &dst_format))
 	return FALSE;
 
@@ -568,19 +636,18 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op,
 
     pixel_shift = pDst->drawable.bitsPerPixel >> 4;
 
-    dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
+    dst_offset = exaGetPixmapOffset(pDst);
     dst_pitch = exaGetPixmapPitch(pDst);
     colorpitch = dst_pitch >> pixel_shift;
     if (RADEONPixmapIsColortiled(pDst))
 	colorpitch |= RADEON_COLOR_TILE_ENABLE;
 
-    dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
-    dst_pitch = exaGetPixmapPitch(pDst);
-    if ((dst_offset & 0x0f) != 0)
+    if (!info->new_cs && (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;
 
@@ -598,10 +665,18 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op,
 	info->accel_state->is_transform[1] = FALSE;
     }
 
-    BEGIN_ACCEL(8);
+    qwords = info->new_cs ? 9 : 8;
+    BEGIN_ACCEL(qwords);
     OUT_ACCEL_REG(RADEON_PP_CNTL, pp_cntl);
     OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format | RADEON_ALPHA_BLEND_ENABLE);
-    OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset);
+    if (info->new_cs) {
+      	driver_priv = exaGetPixmapDriverPrivate(pDst);
+        OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, 0);
+	OUT_RELOC(driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM);
+    } else {
+        dst_offset += info->fbLocation + pScrn->fbOffset;
+	OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset);
+    }
     OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch);
 
     /* IN operator: Multiply src by mask components or mask alpha.
@@ -701,13 +776,17 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
     Bool repeat = pPict->repeat && pPict->repeatType != RepeatPad &&
 	!(unit == 0 && (info->accel_state->need_src_tile_x || info->accel_state->need_src_tile_y));
     int i;
+    struct radeon_exa_pixmap_priv *driver_priv;
+    int qwords;
     ACCEL_PREAMBLE();
 
     txpitch = exaGetPixmapPitch(pPix);
-    txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset;
+    txoffset = exaGetPixmapOffset(pPix);
 
-    if ((txoffset & 0x1f) != 0)
-	RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset));
+    if (!info->new_cs) {
+	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));
 
@@ -764,7 +843,8 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
 	}
     }
 
-    BEGIN_ACCEL(6);
+    qwords = info->new_cs ? 7 : 6;
+    BEGIN_ACCEL(qwords);
     if (unit == 0) {
 	OUT_ACCEL_REG(R200_PP_TXFILTER_0, txfilter);
 	OUT_ACCEL_REG(R200_PP_TXFORMAT_0, txformat);
@@ -772,7 +852,15 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
 	OUT_ACCEL_REG(R200_PP_TXSIZE_0, (pPix->drawable.width - 1) |
 		      ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
 	OUT_ACCEL_REG(R200_PP_TXPITCH_0, txpitch - 32);
-	OUT_ACCEL_REG(R200_PP_TXOFFSET_0, txoffset);
+	if (info->new_cs) {
+	    driver_priv = exaGetPixmapDriverPrivate(pPix);
+
+	    OUT_ACCEL_REG(R200_PP_TXOFFSET_0, driver_priv ? 0 : txoffset);
+	    OUT_RELOC(driver_priv->bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
+	} else {
+	    txoffset += info->fbLocation + pScrn->fbOffset;
+	    OUT_ACCEL_REG(R200_PP_TXOFFSET_0, txoffset);
+	}
     } else {
 	OUT_ACCEL_REG(R200_PP_TXFILTER_1, txfilter);
 	OUT_ACCEL_REG(R200_PP_TXFORMAT_1, txformat);
@@ -780,7 +868,17 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
 	OUT_ACCEL_REG(R200_PP_TXSIZE_1, (pPix->drawable.width - 1) |
 		      ((pPix->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
 	OUT_ACCEL_REG(R200_PP_TXPITCH_1, txpitch - 32);
-	OUT_ACCEL_REG(R200_PP_TXOFFSET_1, txoffset);
+	if (info->new_cs) {
+	    uint32_t handle = 0;
+	    driver_priv = exaGetPixmapDriverPrivate(pPix);
+
+	    OUT_ACCEL_REG(R200_PP_TXOFFSET_1, driver_priv ? 0 : txoffset);
+	    OUT_RELOC(driver_priv->bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
+	} else {
+	    txoffset += info->fbLocation + pScrn->fbOffset;
+	    OUT_ACCEL_REG(R200_PP_TXOFFSET_1, txoffset);
+	}
+	/* emit a texture relocation */
     }
     FINISH_ACCEL();
 
@@ -873,10 +971,52 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture,
     uint32_t dst_format, dst_offset, dst_pitch;
     uint32_t pp_cntl, blendcntl, cblend, ablend, colorpitch;
     int pixel_shift;
+    struct radeon_exa_pixmap_priv *driver_priv;
+    int qwords;
+    int retry_count = 0;
+    struct radeon_space_check bos[3];
+    int i, ret;
     ACCEL_PREAMBLE();
 
     TRACE;
 
+ retry:
+    if (info->new_cs) {
+      
+	i = 0;
+	driver_priv = exaGetPixmapDriverPrivate(pSrc);
+	bos[i].buf = driver_priv->bo;
+	bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
+	bos[i].write_domain = 0;
+	i++;
+
+	if (pMask) {
+	    driver_priv = exaGetPixmapDriverPrivate(pMask);
+	    bos[i].buf = driver_priv->bo;
+	    bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
+	    bos[i].write_domain = 0;
+	    i++;
+	}
+
+	driver_priv = exaGetPixmapDriverPrivate(pDst);
+	bos[i].buf = driver_priv->bo;
+	bos[i].read_domains = 0;
+	bos[i].write_domain = RADEON_GEM_DOMAIN_VRAM;;
+	i++;
+
+	ret = dri_bufmgr_check_aperture_space(bos, i);
+	if (ret == BUFMGR_SPACE_OP_TO_BIG) {
+	    RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n"));
+	}
+	if (ret == BUFMGR_SPACE_FLUSH) {
+	    RADEONCPFlushIndirect(pScrn, 1);
+	    retry_count++;
+	    if (retry_count == 2)
+	        RADEON_FALLBACK(("Not enough Video RAM for src\n"));
+	    goto retry;
+	}
+    }
+
     if (!RADEONGetDestFormat(pDstPicture, &dst_format))
 	return FALSE;
 
@@ -890,13 +1030,13 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture,
 
     pixel_shift = pDst->drawable.bitsPerPixel >> 4;
 
-    dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
+    dst_offset = exaGetPixmapOffset(pDst);
     dst_pitch = exaGetPixmapPitch(pDst);
     colorpitch = dst_pitch >> pixel_shift;
     if (RADEONPixmapIsColortiled(pDst))
 	colorpitch |= RADEON_COLOR_TILE_ENABLE;
 
-    if ((dst_offset & 0x0f) != 0)
+    if (!info->new_cs && (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));
@@ -918,11 +1058,22 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture,
 	info->accel_state->is_transform[1] = FALSE;
     }
 
-    BEGIN_ACCEL(11);
+    qwords = info->new_cs ? 12 : 11;
+    BEGIN_ACCEL(qwords);
 
     OUT_ACCEL_REG(RADEON_PP_CNTL, pp_cntl);
     OUT_ACCEL_REG(RADEON_RB3D_CNTL, dst_format | RADEON_ALPHA_BLEND_ENABLE);
-    OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset);
+
+    if (info->new_cs) {
+	driver_priv = exaGetPixmapDriverPrivate(pDst);
+	assert(driver_priv);
+
+        OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, 0);
+	OUT_RELOC(driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM);
+    } else {
+        dst_offset += info->fbLocation + pScrn->fbOffset;
+	OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset);
+    }
 
     OUT_ACCEL_REG(R200_SE_VTX_FMT_0, R200_VTX_XY);
     if (pMask)
@@ -991,6 +1142,10 @@ static Bool R300CheckCompositeTexture(PicturePtr pPict,
 				      int unit,
 				      Bool is_r500)
 {
+    ScreenPtr pScreen = pDstPict->pDrawable->pScreen;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+
     int w = pPict->pDrawable->width;
     int h = pPict->pDrawable->height;
     int i;
@@ -1016,8 +1171,17 @@ static Bool R300CheckCompositeTexture(PicturePtr pPict,
 	RADEON_FALLBACK(("Unsupported picture format 0x%x\n",
 			 (int)pPict->format));
 
-    if (!RADEONCheckTexturePOT(pPict, unit == 0))
+    if (!RADEONCheckTexturePOT(pPict, unit == 0)) {
+	if (info->new_cs) {
+    		struct radeon_exa_pixmap_priv *driver_priv;
+		PixmapPtr pPix;
+
+    		pPix = RADEONGetDrawablePixmap(pPict->pDrawable);
+		driver_priv = exaGetPixmapDriverPrivate(pPix);
+		radeon_bufmgr_gem_force_gtt(driver_priv->bo);
+	}
 	return FALSE;
+    }
 
     if (pPict->filter != PictFilterNearest &&
 	pPict->filter != PictFilterBilinear)
@@ -1049,15 +1213,19 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
     int w = pPict->pDrawable->width;
     int h = pPict->pDrawable->height;
     int i, pixel_shift;
+    struct radeon_exa_pixmap_priv *driver_priv;
+    int qwords;
     ACCEL_PREAMBLE();
 
     TRACE;
 
     txpitch = exaGetPixmapPitch(pPix);
-    txoffset = exaGetPixmapOffset(pPix) + info->fbLocation + pScrn->fbOffset;
+    txoffset = exaGetPixmapOffset(pPix);
 
-    if ((txoffset & 0x1f) != 0)
-	RADEON_FALLBACK(("Bad texture offset 0x%x\n", (int)txoffset));
+    if (!info->new_cs) {
+    	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));
 
@@ -1139,13 +1307,26 @@ static Bool FUNC_NAME(R300TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
 	RADEON_FALLBACK(("Bad filter 0x%x\n", pPict->filter));
     }
 
-    BEGIN_ACCEL(pPict->repeat ? 6 : 7);
+    qwords = pPict->repeat ? 6 : 7;
+    qwords += info->new_cs ? 1 : 0;
+
+    BEGIN_ACCEL(qwords);
     OUT_ACCEL_REG(R300_TX_FILTER0_0 + (unit * 4), txfilter);
     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 (info->new_cs) {
+        uint32_t handle = 0;
+	driver_priv = exaGetPixmapDriverPrivate(pPix);
+
+        OUT_ACCEL_REG(R300_TX_OFFSET_0 + (unit * 4), driver_priv ? 0 : txoffset);
+	OUT_RELOC(driver_priv->bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
+    } else {
+        txoffset += info->fbLocation + pScrn->fbOffset;
+        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();
@@ -1244,6 +1425,7 @@ static Bool R300CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskP
     return TRUE;
 
 }
+
 #endif /* ONLY_ONCE */
 
 static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
@@ -1255,10 +1437,51 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
     uint32_t txenable, colorpitch;
     uint32_t blendcntl;
     int pixel_shift;
+    int qwords, ret;
+    int retry_count = 0;
+    struct radeon_exa_pixmap_priv *driver_priv;
+    struct radeon_space_check bos[3];
+    int i;
     ACCEL_PREAMBLE();
-
     TRACE;
 
+ retry:
+    if (info->new_cs) {
+      
+	i = 0;
+	driver_priv = exaGetPixmapDriverPrivate(pSrc);
+	bos[i].buf = driver_priv->bo;
+	bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
+	bos[i].write_domain = 0;
+	i++;
+
+	if (pMask) {
+	    driver_priv = exaGetPixmapDriverPrivate(pMask);
+	    bos[i].buf = driver_priv->bo;
+	    bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
+	    bos[i].write_domain = 0;
+	    i++;
+	}
+
+	driver_priv = exaGetPixmapDriverPrivate(pDst);
+	bos[i].buf = driver_priv->bo;
+	bos[i].read_domains = 0;
+	bos[i].write_domain = RADEON_GEM_DOMAIN_VRAM;;
+	i++;
+
+	ret = dri_bufmgr_check_aperture_space(bos, i);
+	if (ret == BUFMGR_SPACE_OP_TO_BIG) {
+	    RADEON_FALLBACK(("Not enough RAM to hw accel composite operation\n"));
+	}
+	if (ret == BUFMGR_SPACE_FLUSH) {
+	    RADEONCPFlushIndirect(pScrn, 1);
+	    retry_count++;
+	    if (retry_count == 2)
+	        RADEON_FALLBACK(("Not enough Video RAM - this really shouldn't happen\nm"));
+	    goto retry;
+	}
+    }
+
     if (!R300GetDestFormat(pDstPicture, &dst_format))
 	return FALSE;
 
@@ -1269,7 +1492,7 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
 
     pixel_shift = pDst->drawable.bitsPerPixel >> 4;
 
-    dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
+    dst_offset = exaGetPixmapOffset(pDst);
     dst_pitch = exaGetPixmapPitch(pDst);
     colorpitch = dst_pitch >> pixel_shift;
 
@@ -1278,7 +1501,7 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
 
     colorpitch |= dst_format;
 
-    if ((dst_offset & 0x0f) != 0)
+    if (!info->new_cs && ((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));
@@ -1287,6 +1510,9 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
 	return FALSE;
 
     RADEON_SWITCH_TO_3D();
+    BEGIN_ACCEL(1);
+    OUT_ACCEL_REG(R300_TX_INVALTAGS, 0x0);
+    FINISH_ACCEL();
 
     if (!FUNC_NAME(R300TextureSetup)(pSrcPicture, pSrc, 0))
 	return FALSE;
@@ -1939,9 +2165,18 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
 				     (8191 << R300_SCISSOR_Y_SHIFT)));
     FINISH_ACCEL();
 
-    BEGIN_ACCEL(3);
+    qwords = info->new_cs ? 4 : 3;
+    BEGIN_ACCEL(qwords);
+    if (info->new_cs) {
+        driver_priv = exaGetPixmapDriverPrivate(pDst);
+	assert(driver_priv);
 
-    OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
+        OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, 0);
+	OUT_RELOC(driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM);
+    } else {
+        dst_offset += info->fbLocation + pScrn->fbOffset;
+        OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
+    }
     OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch);
 
     blendcntl = RADEONGetBlendCntl(op, pMaskPicture, pDstPicture->format);
@@ -1959,7 +2194,6 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
     return TRUE;
 }
 
-
 #ifdef ACCEL_CP
 
 #define VTX_OUT_MASK(_dstX, _dstY, _srcX, _srcY, _maskX, _maskY)	\
@@ -2245,14 +2479,23 @@ static void FUNC_NAME(RadeonDoneComposite)(PixmapPtr pDst)
 
     if (IS_R300_3D || IS_R500_3D) {
 	BEGIN_ACCEL(3);
-	OUT_ACCEL_REG(R300_SC_CLIP_RULE, 0xAAAA);
 	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FLUSH_ALL);
+	OUT_ACCEL_REG(R300_SC_CLIP_RULE, 0xaaaa);
     } else
 	BEGIN_ACCEL(1);
     OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
     FINISH_ACCEL();
 
     LEAVE_DRAW(0);
+
+#if 0
+    /* workaround hang on RS4xx and RS6xx chips */
+    if(info->ChipFamily == CHIP_FAMILY_RS400 ||
+       info->ChipFamily == CHIP_FAMILY_RS480 ||
+       info->ChipFamily == CHIP_FAMILY_RS600 ||
+       info->ChipFamily == CHIP_FAMILY_RS690)
+	RADEONCPFlushIndirect(pScrn, 1);
+#endif
 }
 
 #undef ONLY_ONCE
diff --git a/src/radeon_legacy_memory.c b/src/radeon_legacy_memory.c
index 861fd97..c436faf 100644
--- a/src/radeon_legacy_memory.c
+++ b/src/radeon_legacy_memory.c
@@ -21,6 +21,19 @@ radeon_legacy_allocate_memory(ScrnInfoPtr pScrn,
     RADEONInfoPtr info = RADEONPTR(pScrn);
     uint32_t offset = 0;
 
+    if (info->new_cs) {
+	dri_bo *video_bo;
+
+	video_bo = dri_bo_alloc(info->bufmgr, "xv pixmap", size, 4096, 0);
+
+	*mem_struct = video_bo;
+
+	if (!video_bo)
+	    return 0;
+	
+	return (uint32_t)-1;
+
+    }
 #ifdef USE_EXA
     if (info->useEXA) {
 	ExaOffscreenArea *area = *mem_struct;
@@ -94,6 +107,12 @@ radeon_legacy_free_memory(ScrnInfoPtr pScrn,
 		   void *mem_struct)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
+
+    if (info->new_cs) {
+        dri_bo *bo = mem_struct;
+	dri_bo_unreference(bo);
+	return;
+    }
 #ifdef USE_EXA
     ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
 
diff --git a/src/radeon_memory.c b/src/radeon_memory.c
new file mode 100644
index 0000000..568f9ba
--- /dev/null
+++ b/src/radeon_memory.c
@@ -0,0 +1,396 @@
+
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include "radeon.h"
+#include "radeon_drm.h"
+#include "radeon_bufmgr_gem.h"
+
+Bool
+radeon_bind_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem)
+{
+	RADEONInfoPtr info = RADEONPTR(pScrn);	
+  
+	if (mem == NULL || mem->bound)
+		return TRUE;
+
+	if (!info->drm_mm)
+		return FALSE;
+
+	if (mem->kernel_bo_handle) {
+		struct drm_radeon_gem_pin pin;
+
+		int ret;
+
+    		if (mem->pool == RADEON_POOL_VRAM)
+		    pin.pin_domain = RADEON_GEM_DOMAIN_VRAM;
+    		else
+      		    pin.pin_domain = RADEON_GEM_DOMAIN_GTT;
+		pin.handle = mem->kernel_bo_handle;
+		pin.alignment = mem->alignment;
+
+		ret = ioctl(info->dri->drmFD, DRM_IOCTL_RADEON_GEM_PIN, &pin);
+		if (ret != 0) {
+			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+				   "Failed to pin %s: %s\n", mem->name, strerror(errno));
+			return FALSE;
+		}
+
+		mem->bound = TRUE;
+		mem->offset = pin.offset;
+		//		ErrorF("pin returned 0x%llx\n", pin.offset);
+		mem->end = mem->offset + mem->size;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static Bool
+radeon_unbind_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem)
+{
+	RADEONInfoPtr info = RADEONPTR(pScrn);
+	int ret;
+
+	if (mem == NULL || !mem->bound)
+		return TRUE;
+
+	if (!info->drm_mm)
+		return FALSE;
+
+	if (mem->kernel_bo_handle) {
+		struct drm_radeon_gem_unpin unpin;
+
+		unpin.handle = mem->kernel_bo_handle;
+		ret = ioctl(info->dri->drmFD, DRM_IOCTL_RADEON_GEM_UNPIN, &unpin);
+
+		if (ret == 0) {
+			mem->bound = FALSE;
+			mem->offset = -1;
+			mem->end = -1;
+			return TRUE;
+		} else {
+			return FALSE;
+		}
+	}
+	return FALSE;
+}
+
+void radeon_free_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem)
+{
+	RADEONInfoPtr info = RADEONPTR(pScrn);
+
+	if (mem == NULL)
+		return;
+
+	if (mem->map)
+	    radeon_unmap_memory(pScrn, mem);
+	    
+	radeon_unbind_memory(pScrn, mem);
+
+	if (mem->kernel_bo_handle) {
+		struct drm_gem_close close;
+
+		close.handle = mem->kernel_bo_handle;
+		ioctl(info->dri->drmFD, DRM_IOCTL_GEM_CLOSE, &close);
+	}
+
+	if (info->mm.bo_list[mem->pool] == mem) {
+	  info->mm.bo_list[mem->pool] = mem->next;
+	  if (mem->next)
+	    mem->next->prev = NULL;
+	} else {
+	  if (mem->prev)
+	    mem->prev->next = mem->next;
+	  if (mem->next)
+	    mem->next->prev = mem->prev;
+	}
+	xfree(mem->name);
+	xfree(mem);
+	return;
+}
+
+struct radeon_memory *radeon_allocate_memory(ScrnInfoPtr pScrn, int pool, int size, int alignment, Bool no_backing_store, char *name,
+					     int static_alloc)
+{
+    RADEONInfoPtr  info   = RADEONPTR(pScrn);	
+    struct drm_radeon_gem_create args;
+    struct radeon_memory *mem;
+    int ret;
+
+    mem = xcalloc(1, sizeof(*mem));
+    if (!mem)
+	return NULL;
+    
+    mem->name = xstrdup(name); 
+    if (!mem->name) {
+	xfree(mem);
+	return NULL;
+    }
+
+    mem->size = size;
+    mem->pool = pool;
+    mem->next = mem->prev = NULL;
+    mem->vt_bind = static_alloc;
+    args.size = size;
+    args.alignment = alignment;
+    if (pool == RADEON_POOL_VRAM)
+      args.initial_domain = RADEON_GEM_DOMAIN_VRAM;
+    else
+      args.initial_domain = RADEON_GEM_DOMAIN_GTT;
+    args.no_backing_store = no_backing_store;
+
+    ret = drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_GEM_CREATE, &args, sizeof(args));
+    if (ret) {
+	ErrorF("Failed to allocate %s\n", mem->name);
+	xfree(mem);
+	return NULL;
+    }
+
+    mem->kernel_bo_handle = args.handle;
+    //    xf86DrvMsg(pScrn->scrnIndex, X_INFO,	
+    //	       "%s allocated %d with handle %x\n", mem->name, mem->size, mem->kernel_bo_handle);
+
+    /* add to VRAM linked list for now */
+
+    mem->prev = NULL;
+    mem->next = info->mm.bo_list[pool];
+    if (info->mm.bo_list[pool] != NULL)
+	info->mm.bo_list[pool]->prev = mem;
+    info->mm.bo_list[pool] = mem;
+    return mem;
+}
+
+Bool radeon_bind_all_memory(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr  info   = RADEONPTR(pScrn);	
+    struct radeon_memory *mem;
+    int i;
+
+    for (i = 0; i < 2; i++) {
+	for (mem = info->mm.bo_list[i]; mem != NULL;
+	     mem = mem->next) {
+	    if (mem->vt_bind)
+		if (!radeon_bind_memory(pScrn, mem)) {
+		    FatalError("Couldn't bind %s\n", mem->name);
+		}
+	}
+    }
+    return TRUE;
+}
+	    
+Bool radeon_unbind_all_memory(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr  info   = RADEONPTR(pScrn);	
+    struct radeon_memory *mem;
+    int i;
+
+    for (i = 0; i < 2; i++) {
+	for (mem = info->mm.bo_list[i]; mem != NULL;
+	     mem = mem->next) {
+	    if (mem->vt_bind)
+		radeon_unbind_memory(pScrn, mem);
+	}
+    }
+    return TRUE;
+}
+
+Bool radeon_free_all_memory(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr  info   = RADEONPTR(pScrn);	
+    struct radeon_memory *mem, *tmp;
+    int i;
+
+    for (i = 0; i < 2; i++) {
+	
+	for (mem = info->mm.bo_list[i]; mem != NULL; ) {
+	    tmp = mem->next;
+	    radeon_free_memory(pScrn, mem);
+	    mem = tmp;
+	}
+    }
+    return TRUE;
+}
+
+int radeon_map_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem)
+{
+    struct drm_radeon_gem_mmap args;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    int ret;
+
+    assert(!mem->map);
+
+
+    args.handle = mem->kernel_bo_handle;
+    args.size = mem->size;
+    ret = drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_GEM_MMAP, &args, sizeof(args));
+
+    if (!ret)
+	mem->map = (void *)(unsigned long)args.addr_ptr;
+    //    ErrorF("Mapped %s size %ld at %x %p\n", mem->name, mem->size, mem->offset, mem->map);
+    return ret;
+}
+
+void radeon_unmap_memory(ScrnInfoPtr pScrn, struct radeon_memory *mem)
+{
+    assert(mem->map);
+    if (mem->map) {
+        munmap(mem->map, mem->size);
+        mem->map = NULL;
+    }
+}
+
+/* Okay radeon
+   2D allocations 
+   - Front buffer
+   - cursors
+   - EXA space
+
+   3D related:
+   - Backbuffer
+   - Depth buffer
+   - textures
+*/
+
+
+Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int cpp = info->CurrentLayout.pixel_bytes;
+    int screen_size;
+    int stride = pScrn->displayWidth * cpp;
+    int total_size_bytes = 0, remain_size_bytes;
+    int fb_size_bytes;
+    int pagesize = 4096;
+    
+    screen_size = RADEON_ALIGN(pScrn->virtualY, 16) * stride;
+
+    ErrorF("%d x %d x %d = %dK\n", pScrn->displayWidth, pScrn->virtualY, cpp, screen_size / 1024);
+
+    {
+	int cursor_size = 64 * 4 * 64;
+	int c;
+
+    	cursor_size = RADEON_ALIGN(cursor_size, pagesize);
+	for (c = 0; c < xf86_config->num_crtc; c++) {
+	    /* cursor objects */
+	    info->mm.cursor[c] = radeon_allocate_memory(pScrn, RADEON_POOL_VRAM, cursor_size, 0, 1, "Cursor", 0);
+	    if (!info->mm.cursor[c]) {
+		return FALSE;
+	    }
+
+	    if (radeon_map_memory(pScrn, info->mm.cursor[c])) {
+		ErrorF("Failed to map front buffer memory\n");
+	    }
+	    
+	    if (!info->drm_mode_setting) {
+		xf86CrtcPtr crtc = xf86_config->crtc[c];
+		RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+		radeon_crtc->cursor = info->mm.cursor[c];
+	    } else {
+		drmmode_set_cursor(pScrn, &info->drmmode, c, (void *)info->mm.cursor[c]->map, info->mm.cursor[c]->kernel_bo_handle);
+	    }
+	    total_size_bytes += cursor_size;
+	}
+    }
+
+    screen_size = RADEON_ALIGN(screen_size, pagesize);
+    /* keep area front front buffer - but don't allocate it yet */
+    total_size_bytes += screen_size;
+
+    if (info->directRenderingEnabled && !info->dri2.enabled) {
+	info->dri->backPitch = pScrn->displayWidth;
+	info->mm.back_buffer = radeon_allocate_memory(pScrn, RADEON_POOL_VRAM, screen_size, 0, 1, "Back Buffer", 0);
+	if (!info->mm.back_buffer) {
+	    return FALSE;
+	}
+	total_size_bytes += screen_size;
+	
+	info->dri->depthPitch = RADEON_ALIGN(pScrn->displayWidth, 32);
+	{
+	    int depthCpp = (info->dri->depthBits - 8) / 4;
+	    int depth_size = RADEON_ALIGN(pScrn->virtualY, 16) * info->dri->depthPitch * depthCpp;
+    	    depth_size = RADEON_ALIGN(depth_size, pagesize);
+	    info->mm.depth_buffer = radeon_allocate_memory(pScrn, RADEON_POOL_VRAM, depth_size, 0, 1, "Depth Buffer", 0);
+	    if (!info->mm.depth_buffer) {
+		return FALSE;
+	    }
+	    total_size_bytes += depth_size;
+	}
+    }
+
+    /* work out from the mm size what the exa / tex sizes need to be */
+    remain_size_bytes = info->mm.vram_size - total_size_bytes;
+
+    info->dri->textureSize = 0;
+#if 0
+    if (info->dri->textureSize > 0)
+    	info->dri->textureSize = (remain_size_bytes / 100) * info->dri->textureSize;
+    else
+    	info->dri->textureSize = remain_size_bytes / 2;
+
+    info->dri->textureSize = RADEON_ALIGN(info->dri->textureSize, pagesize);
+
+    remain_size_bytes -= info->dri->textureSize;
+#endif
+
+    ErrorF("texture size is %dK, exa is %dK\n", info->dri->textureSize / 1024, remain_size_bytes/1024);
+
+
+    fb_size_bytes = screen_size;
+
+    ErrorF("fb size is %dK %dK\n", fb_size_bytes / 1024, total_size_bytes / 1024);
+
+    info->mm.front_buffer = radeon_allocate_memory(pScrn, RADEON_POOL_VRAM, fb_size_bytes, 0, 1, "Front Buffer + EXA", 1);
+    if (!info->mm.front_buffer) {
+	return FALSE;
+    }
+
+    /* don't need to bind or map memory */
+    if (!info->dri2.enabled) {
+      if (radeon_map_memory(pScrn, info->mm.front_buffer)) {
+	ErrorF("Failed to map front buffer memory\n");
+      }
+      info->dri->frontPitch = pScrn->displayWidth;
+    }
+
+    if (info->directRenderingEnabled && info->dri->textureSize) {
+	info->mm.texture_buffer = radeon_allocate_memory(pScrn, RADEON_POOL_VRAM, info->dri->textureSize, 0, 1, "Texture Buffer", 1);
+	if (!info->mm.texture_buffer) {
+	    return FALSE;
+	}
+	radeon_bind_memory(pScrn, info->mm.texture_buffer);
+    }
+	
+    if (info->drm_mode_setting) {
+	drmmode_set_fb(pScrn, &info->drmmode, pScrn->virtualX, RADEON_ALIGN(pScrn->virtualY, 16), stride, info->mm.front_buffer->kernel_bo_handle);
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Front buffer size: %dK at 0x%08x\n", info->mm.front_buffer->size/1024, info->mm.front_buffer->offset);
+    if (info->directRenderingEnabled && !info->dri2.enabled) {
+   	 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Back buffer size:  %dK at 0x%08x\n", info->mm.back_buffer->size/1024, info->mm.back_buffer->offset);
+    	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Depth buffer size: %dK at 0x%08x\n", info->mm.depth_buffer->size/1024, info->mm.depth_buffer->offset);
+    }
+    if (info->mm.texture_buffer)
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Texture size:      %dK at 0x%08x\n", info->mm.texture_buffer->size/1024, info->mm.texture_buffer->offset);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Remaining VRAM size (used for pixmaps): %dK\n", remain_size_bytes/1024);
+
+    /* set the emit limit at 90% of VRAM */
+    remain_size_bytes = (remain_size_bytes / 10) * 9;
+
+    radeon_bufmgr_gem_set_limit(info->bufmgr, RADEON_GEM_DOMAIN_VRAM, remain_size_bytes);
+    return TRUE;
+}
+
+dri_bo *radeon_create_rotate_bo(ScrnInfoPtr pScrn, int size)
+{
+	RADEONInfoPtr info = RADEONPTR(pScrn);
+	dri_bo *bo;
+
+	bo = dri_bo_alloc(info->bufmgr, "rotate", size, 0, 0);
+
+	dri_bo_pin(bo, RADEON_GEM_DOMAIN_VRAM);
+	return bo;
+}
+
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index afc8e21..6138f36 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -146,6 +146,27 @@ typedef struct
     Bool hw_capable;
 } RADEONI2CBusRec, *RADEONI2CBusPtr;
 
+struct radeon_memory {
+    int pool; // memory is VRAM vs GART
+    unsigned long offset;
+    unsigned long end;
+
+    unsigned long size;
+    unsigned long allocated_size;
+    void *map;
+    int key;
+
+    Bool bound;
+    unsigned long agp_offset;
+    unsigned int pitch;
+    char *name;
+    struct radeon_memory *next, *prev;
+    uint32_t alignment;
+    uint32_t kernel_bo_handle;
+    uint32_t kernel_name;
+    Bool vt_bind;
+};
+
 typedef struct _RADEONCrtcPrivateRec {
     void *crtc_rotate_mem;
     void *cursor_mem;
@@ -159,6 +180,8 @@ typedef struct _RADEONCrtcPrivateRec {
     int can_tile;
     Bool enabled;
     Bool initialized;
+    struct radeon_memory *cursor;
+
 } RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr;
 
 typedef struct _radeon_encoder {
diff --git a/src/radeon_textured_video.c b/src/radeon_textured_video.c
index 2df299f..79b80de 100644
--- a/src/radeon_textured_video.c
+++ b/src/radeon_textured_video.c
@@ -40,6 +40,7 @@
 #include "radeon_macros.h"
 #include "radeon_probe.h"
 #include "radeon_video.h"
+#include "radeon_drm.h"
 
 #include <X11/extensions/Xv.h>
 #include "fourcc.h"
@@ -124,6 +125,7 @@ static __inline__ uint32_t F_TO_24(float val)
 #define BEGIN_ACCEL(n)		RADEONWaitForFifo(pScrn, (n))
 #define OUT_ACCEL_REG(reg, val)	OUTREG(reg, val)
 #define OUT_ACCEL_REG_F(reg, val) OUTREG(reg, F_TO_DW(val))
+#define OUT_RELOC(x, read, write) do {} while(0)
 #define FINISH_ACCEL()
 
 #include "radeon_textured_videofuncs.c"
@@ -133,6 +135,7 @@ static __inline__ uint32_t F_TO_24(float val)
 #undef BEGIN_ACCEL
 #undef OUT_ACCEL_REG
 #undef OUT_ACCEL_REG_F
+#undef OUT_RELOC
 #undef FINISH_ACCEL
 
 #ifdef XF86DRI
@@ -146,6 +149,7 @@ static __inline__ uint32_t F_TO_24(float val)
 #define OUT_ACCEL_REG_F(reg, val)	OUT_ACCEL_REG(reg, F_TO_DW(val))
 #define FINISH_ACCEL()		ADVANCE_RING()
 #define OUT_RING_F(x) OUT_RING(F_TO_DW(x))
+#define OUT_RELOC(x, read, write) OUT_RING_RELOC(x, read, write)
 
 #include "radeon_textured_videofuncs.c"
 
@@ -374,6 +378,9 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
 								size * 2, 64);
 	if (pPriv->video_offset == 0)
 	    return BadAlloc;
+
+	if (info->new_cs)
+	    pPriv->src_bo = pPriv->video_memory;
     }
 
     /* Bicubic filter setup */
@@ -397,6 +404,9 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
 	pPriv->bicubic_src_offset = pPriv->bicubic_offset + info->fbLocation + pScrn->fbOffset;
 	if (pPriv->bicubic_offset == 0)
 		pPriv->bicubic_enabled = FALSE;
+
+	if (info->new_cs)
+	    pPriv->bicubic_bo = pPriv->bicubic_memory;
     }
 
     if (pDraw->type == DRAWABLE_WINDOW)
@@ -426,11 +436,22 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
     left = (x1 >> 16) & ~1;
     npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left;
 
-    pPriv->src_offset = pPriv->video_offset + info->fbLocation + pScrn->fbOffset;
-    if (info->ChipFamily >= CHIP_FAMILY_R600)
-	pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset);
-    else
-	pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset + (top * dstPitch));
+    pPriv->src_offset = pPriv->video_offset;
+    if (info->new_cs) {
+	int ret;
+	ret = dri_bo_map(pPriv->src_bo, 1);
+	if (ret) 
+	    return BadAlloc;
+      
+	pPriv->src_addr = pPriv->src_bo->virtual;
+    } else if (info->drm_mm) {
+        pPriv->src_addr = (uint8_t *)(info->mm.front_buffer->map + pPriv->video_offset + (top * dstPitch));
+    } else {
+        if (info->ChipFamily >= CHIP_FAMILY_R600)
+            pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset);
+	else
+            pPriv->src_addr = (uint8_t *)(info->FB + pPriv->video_offset + (top * dstPitch));
+    }
     pPriv->src_pitch = dstPitch;
     pPriv->size = size;
     pPriv->pDraw = pDraw;
@@ -511,9 +532,24 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
 
     /* Upload bicubic filter tex */
     if (pPriv->bicubic_enabled) {
-	if (info->ChipFamily < CHIP_FAMILY_R600)
-	    RADEONCopyData(pScrn, (uint8_t *)bicubic_tex_512,
-			   (uint8_t *)(info->FB + pPriv->bicubic_offset), 1024, 1024, 1, 512, 2);
+       if (info->ChipFamily < CHIP_FAMILY_R600) {
+	   uint8_t *bicubic_addr;
+	   int ret;
+
+	   if (info->new_cs) {
+	       ret = dri_bo_map(pPriv->bicubic_bo, 1);
+	       if (ret)
+		   return BadAlloc;
+
+	       bicubic_addr = pPriv->bicubic_bo->virtual;
+	   } else
+	       bicubic_addr = (uint8_t *)(info->FB + pPriv->bicubic_offset);
+	
+	   RADEONCopyData(pScrn, (uint8_t *)bicubic_tex_512, bicubic_addr, 1024, 1024, 1, 512, 2);
+	   
+	   if (info->new_cs)
+	       dri_bo_unmap(pPriv->bicubic_bo);
+       }
     }
 
     /* update cliplist */
@@ -531,10 +567,12 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
     pPriv->w = width;
     pPriv->h = height;
 
+    if (info->new_cs)
+	dri_bo_unmap(pPriv->src_bo);
 #ifdef XF86DRI
     if (IS_R600_3D)
 	R600DisplayTexturedVideo(pScrn, pPriv);
-    else if (info->directRenderingEnabled)
+    if (info->directRenderingEnabled || info->drm_mode_setting)
 	RADEONDisplayTexturedVideoCP(pScrn, pPriv);
     else
 #endif
diff --git a/src/radeon_textured_videofuncs.c b/src/radeon_textured_videofuncs.c
index f55ae12..5d23ad9 100644
--- a/src/radeon_textured_videofuncs.c
+++ b/src/radeon_textured_videofuncs.c
@@ -92,6 +92,11 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
     PixmapPtr pPixmap = pPriv->pPixmap;
+    struct radeon_exa_pixmap_priv *driver_priv;
+    struct radeon_space_check bos[2];
+    int i, ret;
+    int retry_count = 0;
+    dri_bo *dst_bo;
     uint32_t txformat;
     uint32_t txfilter, txformat0, txformat1, txoffset, txpitch;
     uint32_t dst_offset, dst_pitch, dst_format;
@@ -100,19 +105,57 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
     int dstxoff, dstyoff, pixel_shift, vtx_count;
     BoxPtr pBox = REGION_RECTS(&pPriv->clip);
     int nBox = REGION_NUM_RECTS(&pPriv->clip);
+    int qwords;
     ACCEL_PREAMBLE();
 
+ retry:
+    if (info->new_cs) {
+      
+	i = 0;
+	bos[i].buf = pPriv->src_bo;
+	bos[i].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
+	bos[i].write_domain = 0;
+	i++;
+
+	driver_priv = exaGetPixmapDriverPrivate(pPixmap);
+	dst_bo = driver_priv->bo;
+	bos[i].buf = driver_priv->bo;
+	bos[i].read_domains = 0;
+	bos[i].write_domain = RADEON_GEM_DOMAIN_VRAM;;
+	i++;
+
+	ret = dri_bufmgr_check_aperture_space(bos, i);
+	if (ret == BUFMGR_SPACE_OP_TO_BIG) {
+	    ErrorF("Not enough RAM to hw accel composite operation\n");
+	    return;
+	}
+	if (ret == BUFMGR_SPACE_FLUSH) {
+	    RADEONCPFlushIndirect(pScrn, 1);
+	    retry_count++;
+	    if (retry_count == 2) {
+	        ErrorF("Not enough RAM to hw accel composite operation\n");
+	        return;
+	    }
+	    goto retry;
+	}
+    }
+
     pixel_shift = pPixmap->drawable.bitsPerPixel >> 4;
 
 #ifdef USE_EXA
     if (info->useEXA) {
-	dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset;
+	if (info->new_cs) {
+	    driver_priv = exaGetPixmapDriverPrivate(pPixmap);
+	    if (driver_priv)
+		dst_bo = driver_priv->bo;
+	} else {
+	    dst_offset = exaGetPixmapOffset(pPixmap);
+	}
 	dst_pitch = exaGetPixmapPitch(pPixmap);
     } else
 #endif
 	{
-	    dst_offset = (pPixmap->devPrivate.ptr - info->FB) +
-		info->fbLocation + pScrn->fbOffset;
+	    dst_offset = (pPixmap->devPrivate.ptr - info->FB);
 	    dst_pitch = pPixmap->devKind;
 	}
 
@@ -143,7 +186,7 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 			  RADEON_WAIT_DMA_GUI_IDLE);
 	    FINISH_ACCEL();
 
-	    if (!info->accel_state->XInited3D)
+	    if (!info->accel_state->XInited3D && !info->drm_mm)
 		RADEONInit3DEngine(pScrn);
 	}
 
@@ -213,13 +256,20 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 
 	txoffset = pPriv->src_offset;
 
-	BEGIN_ACCEL(6);
+	qwords = info->new_cs ? 7 : 6;
+	BEGIN_ACCEL(qwords);
 	OUT_ACCEL_REG(R300_TX_FILTER0_0, txfilter);
 	OUT_ACCEL_REG(R300_TX_FILTER1_0, 0);
 	OUT_ACCEL_REG(R300_TX_FORMAT0_0, txformat0);
 	OUT_ACCEL_REG(R300_TX_FORMAT1_0, txformat1);
 	OUT_ACCEL_REG(R300_TX_FORMAT2_0, txpitch);
-	OUT_ACCEL_REG(R300_TX_OFFSET_0, txoffset);
+	if (info->new_cs) {
+	    OUT_ACCEL_REG(R300_TX_OFFSET_0, 0);
+	    OUT_RELOC(pPriv->src_bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
+	} else {
+	    txoffset += info->fbLocation + pScrn->fbOffset;
+	    OUT_ACCEL_REG(R300_TX_OFFSET_0, txoffset);
+	}
 	FINISH_ACCEL();
 
 	txenable = R300_TEX_0_ENABLE;
@@ -240,13 +290,19 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 			    R300_TX_MAG_FILTER_NEAREST |
 			    (1 << R300_TX_ID_SHIFT));
 
-		BEGIN_ACCEL(6);
+		qwords = info->new_cs ? 7 : 6;
+		BEGIN_ACCEL(qwords);
 		OUT_ACCEL_REG(R300_TX_FILTER0_1, txfilter);
 		OUT_ACCEL_REG(R300_TX_FILTER1_1, 0);
 		OUT_ACCEL_REG(R300_TX_FORMAT0_1, txformat0);
 		OUT_ACCEL_REG(R300_TX_FORMAT1_1, txformat1);
 		OUT_ACCEL_REG(R300_TX_FORMAT2_1, txpitch);
-		OUT_ACCEL_REG(R300_TX_OFFSET_1, pPriv->bicubic_src_offset);
+		if (info->new_cs) {
+		    OUT_ACCEL_REG(R300_TX_OFFSET_1, 0);
+		    OUT_RELOC(pPriv->bicubic_bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
+		} else {
+		    OUT_ACCEL_REG(R300_TX_OFFSET_1, pPriv->bicubic_src_offset);
+		}
 		FINISH_ACCEL();
 
 		/* Enable tex 1 */
@@ -1332,11 +1388,18 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 	    }
 	}
 
-	BEGIN_ACCEL(6);
+	qwords = info->new_cs ? 7 : 6;
+	BEGIN_ACCEL(qwords);
 	OUT_ACCEL_REG(R300_TX_INVALTAGS, 0);
 	OUT_ACCEL_REG(R300_TX_ENABLE, txenable);
 
-	OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
+	if (info->new_cs) {
+	    OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, 0);
+	    OUT_RELOC(dst_bo, 0, RADEON_GEM_DOMAIN_VRAM);
+	} else {
+	    dst_offset += info->fbLocation + pScrn->fbOffset;
+	    OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
+	}
 	OUT_ACCEL_REG(R300_RB3D_COLORPITCH0, colorpitch);
 
 	blendcntl = RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO;
@@ -1381,6 +1444,8 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 		      RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE);
 	OUT_ACCEL_REG(RADEON_RB3D_CNTL,
 		      dst_format | RADEON_ALPHA_BLEND_ENABLE);
+
+	dst_offset += info->fbLocation + pScrn->fbOffset;
 	OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, dst_offset);
 
 	OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, colorpitch);
@@ -1418,7 +1483,8 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 			  ((pPriv->h - 1) << RADEON_TEX_VSIZE_SHIFT));
 	    OUT_ACCEL_REG(R200_PP_TXPITCH_0, pPriv->src_pitch - 32);
 
-	    OUT_ACCEL_REG(R200_PP_TXOFFSET_0, pPriv->src_offset);
+	    OUT_ACCEL_REG(R200_PP_TXOFFSET_0, pPriv->src_offset +
+			  info->fbLocation + pScrn->fbOffset);
 
 	    OUT_ACCEL_REG(R200_PP_TXCBLEND_0,
 			  R200_TXC_ARG_A_ZERO |
@@ -1451,8 +1517,10 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 			  RADEON_CLAMP_S_CLAMP_LAST |
 			  RADEON_CLAMP_T_CLAMP_LAST |
 			  RADEON_YUV_TO_RGB);
+
 	    OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat);
-	    OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, pPriv->src_offset);
+	    OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, pPriv->src_offset +
+			  info->fbLocation + pScrn->fbOffset);
 	    OUT_ACCEL_REG(RADEON_PP_TXCBLEND_0,
 			  RADEON_COLOR_ARG_A_ZERO |
 			  RADEON_COLOR_ARG_B_ZERO |
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 92d1a71..c953618 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -287,7 +287,7 @@ void RADEONInitVideo(ScreenPtr pScreen)
     memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
     adaptors = newAdaptors;
 
-    if (!IS_AVIVO_VARIANT) {
+    if (!IS_AVIVO_VARIANT && !info->drm_mode_setting) {
 	overlayAdaptor = RADEONSetupImageVideo(pScreen);
 	if (overlayAdaptor != NULL) {
 	    adaptors[num_adaptors++] = overlayAdaptor;
@@ -300,7 +300,7 @@ void RADEONInitVideo(ScreenPtr pScreen)
     if (info->ChipFamily != CHIP_FAMILY_RV250) {
 	if ((info->ChipFamily < CHIP_FAMILY_RS400)
 #ifdef XF86DRI
-	    || (info->directRenderingEnabled)
+	    || (info->directRenderingEnabled || info->drm_mode_setting)
 #endif
 	    ) {
 	    texturedAdaptor = RADEONSetupImageTexturedVideo(pScreen);
@@ -2203,7 +2203,7 @@ RADEONCopyData(
 
 #ifdef XF86DRI
 
-    if ( info->directRenderingEnabled && info->DMAForXv )
+    if ( info->directRenderingEnabled && info->DMAForXv && !info->new_cs )
     {
 	uint8_t *buf;
 	uint32_t bufPitch, dstPitchOff;
diff --git a/src/radeon_video.h b/src/radeon_video.h
index 7f1891e..7a5f740 100644
--- a/src/radeon_video.h
+++ b/src/radeon_video.h
@@ -116,6 +116,9 @@ typedef struct {
     int w, h;
     int drw_x, drw_y;
     int vsync;
+
+    dri_bo *src_bo;
+    dri_bo *bicubic_bo;
 } RADEONPortPrivRec, *RADEONPortPrivPtr;
 
 int