]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/gpu/drm/radeon/radeon_state.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6-omap-h63xx.git] / drivers / gpu / drm / radeon / radeon_state.c
index 5d7153fcc7b0063625a8232e66b6f89b09a042c3..fa728ec6ed34c18bb66a8c78505467d9918ef7b0 100644 (file)
@@ -742,13 +742,14 @@ static struct {
  */
 
 static void radeon_clear_box(drm_radeon_private_t * dev_priv,
+                            struct drm_radeon_master_private *master_priv,
                             int x, int y, int w, int h, int r, int g, int b)
 {
        u32 color;
        RING_LOCALS;
 
-       x += dev_priv->sarea_priv->boxes[0].x1;
-       y += dev_priv->sarea_priv->boxes[0].y1;
+       x += master_priv->sarea_priv->boxes[0].x1;
+       y += master_priv->sarea_priv->boxes[0].y1;
 
        switch (dev_priv->color_fmt) {
        case RADEON_COLOR_FORMAT_RGB565:
@@ -776,7 +777,7 @@ static void radeon_clear_box(drm_radeon_private_t * dev_priv,
                 RADEON_GMC_SRC_DATATYPE_COLOR |
                 RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS);
 
-       if (dev_priv->sarea_priv->pfCurrentPage == 1) {
+       if (master_priv->sarea_priv->pfCurrentPage == 1) {
                OUT_RING(dev_priv->front_pitch_offset);
        } else {
                OUT_RING(dev_priv->back_pitch_offset);
@@ -790,7 +791,7 @@ static void radeon_clear_box(drm_radeon_private_t * dev_priv,
        ADVANCE_RING();
 }
 
-static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
+static void radeon_cp_performance_boxes(drm_radeon_private_t *dev_priv, struct drm_radeon_master_private *master_priv)
 {
        /* Collapse various things into a wait flag -- trying to
         * guess if userspase slept -- better just to have them tell us.
@@ -807,12 +808,12 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
        /* Purple box for page flipping
         */
        if (dev_priv->stats.boxes & RADEON_BOX_FLIP)
-               radeon_clear_box(dev_priv, 4, 4, 8, 8, 255, 0, 255);
+               radeon_clear_box(dev_priv, master_priv, 4, 4, 8, 8, 255, 0, 255);
 
        /* Red box if we have to wait for idle at any point
         */
        if (dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE)
-               radeon_clear_box(dev_priv, 16, 4, 8, 8, 255, 0, 0);
+               radeon_clear_box(dev_priv, master_priv, 16, 4, 8, 8, 255, 0, 0);
 
        /* Blue box: lost context?
         */
@@ -820,12 +821,12 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
        /* Yellow box for texture swaps
         */
        if (dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD)
-               radeon_clear_box(dev_priv, 40, 4, 8, 8, 255, 255, 0);
+               radeon_clear_box(dev_priv, master_priv, 40, 4, 8, 8, 255, 255, 0);
 
        /* Green box if hardware never idles (as far as we can tell)
         */
        if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE))
-               radeon_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0);
+               radeon_clear_box(dev_priv, master_priv, 64, 4, 8, 8, 0, 255, 0);
 
        /* Draw bars indicating number of buffers allocated
         * (not a great measure, easily confused)
@@ -834,7 +835,7 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
                if (dev_priv->stats.requested_bufs > 100)
                        dev_priv->stats.requested_bufs = 100;
 
-               radeon_clear_box(dev_priv, 4, 16,
+               radeon_clear_box(dev_priv, master_priv, 4, 16,
                                 dev_priv->stats.requested_bufs, 4,
                                 196, 128, 128);
        }
@@ -848,11 +849,13 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
  */
 
 static void radeon_cp_dispatch_clear(struct drm_device * dev,
+                                    struct drm_master *master,
                                     drm_radeon_clear_t * clear,
                                     drm_radeon_clear_rect_t * depth_boxes)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
-       drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       struct drm_radeon_master_private *master_priv = master->driver_priv;
+       drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
        drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear;
        int nbox = sarea_priv->nbox;
        struct drm_clip_rect *pbox = sarea_priv->boxes;
@@ -864,7 +867,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
 
        dev_priv->stats.clears++;
 
-       if (dev_priv->sarea_priv->pfCurrentPage == 1) {
+       if (sarea_priv->pfCurrentPage == 1) {
                unsigned int tmp = flags;
 
                flags &= ~(RADEON_FRONT | RADEON_BACK);
@@ -890,7 +893,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
 
                /* Make sure we restore the 3D state next time.
                 */
-               dev_priv->sarea_priv->ctx_owner = 0;
+               sarea_priv->ctx_owner = 0;
 
                for (i = 0; i < nbox; i++) {
                        int x = pbox[i].x1;
@@ -967,7 +970,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
                /* Make sure we restore the 3D state next time.
                 * we haven't touched any "normal" state - still need this?
                 */
-               dev_priv->sarea_priv->ctx_owner = 0;
+               sarea_priv->ctx_owner = 0;
 
                if ((dev_priv->flags & RADEON_HAS_HIERZ)
                    && (flags & RADEON_USE_HIERZ)) {
@@ -1214,7 +1217,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
 
                /* Make sure we restore the 3D state next time.
                 */
-               dev_priv->sarea_priv->ctx_owner = 0;
+               sarea_priv->ctx_owner = 0;
 
                for (i = 0; i < nbox; i++) {
 
@@ -1285,7 +1288,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
 
                /* Make sure we restore the 3D state next time.
                 */
-               dev_priv->sarea_priv->ctx_owner = 0;
+               sarea_priv->ctx_owner = 0;
 
                for (i = 0; i < nbox; i++) {
 
@@ -1328,20 +1331,21 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
         * wait on this value before performing the clear ioctl.  We
         * need this because the card's so damned fast...
         */
-       dev_priv->sarea_priv->last_clear++;
+       sarea_priv->last_clear++;
 
        BEGIN_RING(4);
 
-       RADEON_CLEAR_AGE(dev_priv->sarea_priv->last_clear);
+       RADEON_CLEAR_AGE(sarea_priv->last_clear);
        RADEON_WAIT_UNTIL_IDLE();
 
        ADVANCE_RING();
 }
 
-static void radeon_cp_dispatch_swap(struct drm_device * dev)
+static void radeon_cp_dispatch_swap(struct drm_device *dev, struct drm_master *master)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
-       drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       struct drm_radeon_master_private *master_priv = master->driver_priv;
+       drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
        int nbox = sarea_priv->nbox;
        struct drm_clip_rect *pbox = sarea_priv->boxes;
        int i;
@@ -1351,7 +1355,7 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev)
        /* Do some trivial performance monitoring...
         */
        if (dev_priv->do_boxes)
-               radeon_cp_performance_boxes(dev_priv);
+               radeon_cp_performance_boxes(dev_priv, master_priv);
 
        /* Wait for the 3D stream to idle before dispatching the bitblt.
         * This will prevent data corruption between the two streams.
@@ -1385,7 +1389,7 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev)
                /* Make this work even if front & back are flipped:
                 */
                OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1));
-               if (dev_priv->sarea_priv->pfCurrentPage == 0) {
+               if (sarea_priv->pfCurrentPage == 0) {
                        OUT_RING(dev_priv->back_pitch_offset);
                        OUT_RING(dev_priv->front_pitch_offset);
                } else {
@@ -1405,31 +1409,32 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev)
         * throttle the framerate by waiting for this value before
         * performing the swapbuffer ioctl.
         */
-       dev_priv->sarea_priv->last_frame++;
+       sarea_priv->last_frame++;
 
        BEGIN_RING(4);
 
-       RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame);
+       RADEON_FRAME_AGE(sarea_priv->last_frame);
        RADEON_WAIT_UNTIL_2D_IDLE();
 
        ADVANCE_RING();
 }
 
-static void radeon_cp_dispatch_flip(struct drm_device * dev)
+void radeon_cp_dispatch_flip(struct drm_device *dev, struct drm_master *master)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
-       struct drm_sarea *sarea = (struct drm_sarea *) dev_priv->sarea->handle;
-       int offset = (dev_priv->sarea_priv->pfCurrentPage == 1)
+       struct drm_radeon_master_private *master_priv = master->driver_priv;
+       struct drm_sarea *sarea = (struct drm_sarea *)master_priv->sarea->handle;
+       int offset = (master_priv->sarea_priv->pfCurrentPage == 1)
            ? dev_priv->front_offset : dev_priv->back_offset;
        RING_LOCALS;
        DRM_DEBUG("pfCurrentPage=%d\n",
-                 dev_priv->sarea_priv->pfCurrentPage);
+                 master_priv->sarea_priv->pfCurrentPage);
 
        /* Do some trivial performance monitoring...
         */
        if (dev_priv->do_boxes) {
                dev_priv->stats.boxes |= RADEON_BOX_FLIP;
-               radeon_cp_performance_boxes(dev_priv);
+               radeon_cp_performance_boxes(dev_priv, master_priv);
        }
 
        /* Update the frame offsets for both CRTCs
@@ -1441,7 +1446,7 @@ static void radeon_cp_dispatch_flip(struct drm_device * dev)
                     ((sarea->frame.y * dev_priv->front_pitch +
                       sarea->frame.x * (dev_priv->color_fmt - 2)) & ~7)
                     + offset);
-       OUT_RING_REG(RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base
+       OUT_RING_REG(RADEON_CRTC2_OFFSET, master_priv->sarea_priv->crtc2_base
                     + offset);
 
        ADVANCE_RING();
@@ -1450,13 +1455,13 @@ static void radeon_cp_dispatch_flip(struct drm_device * dev)
         * throttle the framerate by waiting for this value before
         * performing the swapbuffer ioctl.
         */
-       dev_priv->sarea_priv->last_frame++;
-       dev_priv->sarea_priv->pfCurrentPage =
-               1 - dev_priv->sarea_priv->pfCurrentPage;
+       master_priv->sarea_priv->last_frame++;
+       master_priv->sarea_priv->pfCurrentPage =
+               1 - master_priv->sarea_priv->pfCurrentPage;
 
        BEGIN_RING(2);
 
-       RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame);
+       RADEON_FRAME_AGE(master_priv->sarea_priv->last_frame);
 
        ADVANCE_RING();
 }
@@ -1494,11 +1499,13 @@ typedef struct {
 } drm_radeon_tcl_prim_t;
 
 static void radeon_cp_dispatch_vertex(struct drm_device * dev,
+                                     struct drm_file *file_priv,
                                      struct drm_buf * buf,
                                      drm_radeon_tcl_prim_t * prim)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
-       drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
+       drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
        int offset = dev_priv->gart_buffers_offset + buf->offset + prim->start;
        int numverts = (int)prim->numverts;
        int nbox = sarea_priv->nbox;
@@ -1539,18 +1546,25 @@ static void radeon_cp_dispatch_vertex(struct drm_device * dev,
        } while (i < nbox);
 }
 
-static void radeon_cp_discard_buffer(struct drm_device * dev, struct drm_buf * buf)
+static void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
+       struct drm_radeon_master_private *master_priv = master->driver_priv;
        drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
        RING_LOCALS;
 
-       buf_priv->age = ++dev_priv->sarea_priv->last_dispatch;
+       buf_priv->age = ++master_priv->sarea_priv->last_dispatch;
 
        /* Emit the vertex buffer age */
-       BEGIN_RING(2);
-       RADEON_DISPATCH_AGE(buf_priv->age);
-       ADVANCE_RING();
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
+               BEGIN_RING(3);
+               R600_DISPATCH_AGE(buf_priv->age);
+               ADVANCE_RING();
+       } else {
+               BEGIN_RING(2);
+               RADEON_DISPATCH_AGE(buf_priv->age);
+               ADVANCE_RING();
+       }
 
        buf->pending = 1;
        buf->used = 0;
@@ -1590,12 +1604,14 @@ static void radeon_cp_dispatch_indirect(struct drm_device * dev,
        }
 }
 
-static void radeon_cp_dispatch_indices(struct drm_device * dev,
+static void radeon_cp_dispatch_indices(struct drm_device *dev,
+                                      struct drm_master *master,
                                       struct drm_buf * elt_buf,
                                       drm_radeon_tcl_prim_t * prim)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
-       drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       struct drm_radeon_master_private *master_priv = master->driver_priv;
+       drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
        int offset = dev_priv->gart_buffers_offset + prim->offset;
        u32 *data;
        int dwords;
@@ -1870,7 +1886,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
                ADVANCE_RING();
                COMMIT_RING();
 
-               radeon_cp_discard_buffer(dev, buf);
+               radeon_cp_discard_buffer(dev, file_priv->master, buf);
 
                /* Update the input parameters for next time */
                image->y += height;
@@ -1970,7 +1986,7 @@ static int alloc_surface(drm_radeon_surface_alloc_t *new,
 
        /* find a virtual surface */
        for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++)
-               if (dev_priv->virt_surfaces[i].file_priv == 0)
+               if (dev_priv->virt_surfaces[i].file_priv == NULL)
                        break;
        if (i == 2 * RADEON_MAX_SURFACES) {
                return -1;
@@ -2110,7 +2126,8 @@ static int radeon_surface_free(struct drm_device *dev, void *data, struct drm_fi
 static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
-       drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
+       drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
        drm_radeon_clear_t *clear = data;
        drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
        DRM_DEBUG("\n");
@@ -2126,7 +2143,7 @@ static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *
                               sarea_priv->nbox * sizeof(depth_boxes[0])))
                return -EFAULT;
 
-       radeon_cp_dispatch_clear(dev, clear, depth_boxes);
+       radeon_cp_dispatch_clear(dev, file_priv->master, clear, depth_boxes);
 
        COMMIT_RING();
        return 0;
@@ -2134,9 +2151,10 @@ static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *
 
 /* Not sure why this isn't set all the time:
  */
-static int radeon_do_init_pageflip(struct drm_device * dev)
+static int radeon_do_init_pageflip(struct drm_device *dev, struct drm_master *master)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
+       struct drm_radeon_master_private *master_priv = master->driver_priv;
        RING_LOCALS;
 
        DRM_DEBUG("\n");
@@ -2153,8 +2171,8 @@ static int radeon_do_init_pageflip(struct drm_device * dev)
 
        dev_priv->page_flipping = 1;
 
-       if (dev_priv->sarea_priv->pfCurrentPage != 1)
-               dev_priv->sarea_priv->pfCurrentPage = 0;
+       if (master_priv->sarea_priv->pfCurrentPage != 1)
+               master_priv->sarea_priv->pfCurrentPage = 0;
 
        return 0;
 }
@@ -2172,9 +2190,9 @@ static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *f
        RING_SPACE_TEST_WITH_RETURN(dev_priv);
 
        if (!dev_priv->page_flipping)
-               radeon_do_init_pageflip(dev);
+               radeon_do_init_pageflip(dev, file_priv->master);
 
-       radeon_cp_dispatch_flip(dev);
+       radeon_cp_dispatch_flip(dev, file_priv->master);
 
        COMMIT_RING();
        return 0;
@@ -2183,7 +2201,9 @@ static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *f
 static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
-       drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
+       drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
+
        DRM_DEBUG("\n");
 
        LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -2193,8 +2213,8 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f
        if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
                sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
 
-       radeon_cp_dispatch_swap(dev);
-       dev_priv->sarea_priv->ctx_owner = 0;
+       radeon_cp_dispatch_swap(dev, file_priv->master);
+       sarea_priv->ctx_owner = 0;
 
        COMMIT_RING();
        return 0;
@@ -2203,7 +2223,8 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f
 static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
-       drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
+       drm_radeon_sarea_t *sarea_priv;
        struct drm_device_dma *dma = dev->dma;
        struct drm_buf *buf;
        drm_radeon_vertex_t *vertex = data;
@@ -2211,6 +2232,8 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file
 
        LOCK_TEST_WITH_RETURN(dev, file_priv);
 
+       sarea_priv = master_priv->sarea_priv;
+
        DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
                  DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard);
 
@@ -2263,13 +2286,13 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file
                prim.finish = vertex->count;    /* unused */
                prim.prim = vertex->prim;
                prim.numverts = vertex->count;
-               prim.vc_format = dev_priv->sarea_priv->vc_format;
+               prim.vc_format = sarea_priv->vc_format;
 
-               radeon_cp_dispatch_vertex(dev, buf, &prim);
+               radeon_cp_dispatch_vertex(dev, file_priv, buf, &prim);
        }
 
        if (vertex->discard) {
-               radeon_cp_discard_buffer(dev, buf);
+               radeon_cp_discard_buffer(dev, file_priv->master, buf);
        }
 
        COMMIT_RING();
@@ -2279,7 +2302,8 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file
 static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
-       drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
+       drm_radeon_sarea_t *sarea_priv;
        struct drm_device_dma *dma = dev->dma;
        struct drm_buf *buf;
        drm_radeon_indices_t *elts = data;
@@ -2288,6 +2312,8 @@ static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file
 
        LOCK_TEST_WITH_RETURN(dev, file_priv);
 
+       sarea_priv = master_priv->sarea_priv;
+
        DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n",
                  DRM_CURRENTPID, elts->idx, elts->start, elts->end,
                  elts->discard);
@@ -2353,11 +2379,11 @@ static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file
        prim.prim = elts->prim;
        prim.offset = 0;        /* offset from start of dma buffers */
        prim.numverts = RADEON_MAX_VB_VERTS;    /* duh */
-       prim.vc_format = dev_priv->sarea_priv->vc_format;
+       prim.vc_format = sarea_priv->vc_format;
 
-       radeon_cp_dispatch_indices(dev, buf, &prim);
+       radeon_cp_dispatch_indices(dev, file_priv->master, buf, &prim);
        if (elts->discard) {
-               radeon_cp_discard_buffer(dev, buf);
+               radeon_cp_discard_buffer(dev, file_priv->master, buf);
        }
 
        COMMIT_RING();
@@ -2453,24 +2479,25 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil
 
        buf->used = indirect->end;
 
-       /* Wait for the 3D stream to idle before the indirect buffer
-        * containing 2D acceleration commands is processed.
-        */
-       BEGIN_RING(2);
-
-       RADEON_WAIT_UNTIL_3D_IDLE();
-
-       ADVANCE_RING();
-
        /* Dispatch the indirect buffer full of commands from the
         * X server.  This is insecure and is thus only available to
         * privileged clients.
         */
-       radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
-       if (indirect->discard) {
-               radeon_cp_discard_buffer(dev, buf);
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+               r600_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
+       else {
+               /* Wait for the 3D stream to idle before the indirect buffer
+                * containing 2D acceleration commands is processed.
+                */
+               BEGIN_RING(2);
+               RADEON_WAIT_UNTIL_3D_IDLE();
+               ADVANCE_RING();
+               radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
        }
 
+       if (indirect->discard)
+               radeon_cp_discard_buffer(dev, file_priv->master, buf);
+
        COMMIT_RING();
        return 0;
 }
@@ -2478,7 +2505,8 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil
 static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
-       drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
+       drm_radeon_sarea_t *sarea_priv;
        struct drm_device_dma *dma = dev->dma;
        struct drm_buf *buf;
        drm_radeon_vertex2_t *vertex = data;
@@ -2487,6 +2515,8 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file
 
        LOCK_TEST_WITH_RETURN(dev, file_priv);
 
+       sarea_priv = master_priv->sarea_priv;
+
        DRM_DEBUG("pid=%d index=%d discard=%d\n",
                  DRM_CURRENTPID, vertex->idx, vertex->discard);
 
@@ -2547,12 +2577,12 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file
                        tclprim.offset = prim.numverts * 64;
                        tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */
 
-                       radeon_cp_dispatch_indices(dev, buf, &tclprim);
+                       radeon_cp_dispatch_indices(dev, file_priv->master, buf, &tclprim);
                } else {
                        tclprim.numverts = prim.numverts;
                        tclprim.offset = 0;     /* not used */
 
-                       radeon_cp_dispatch_vertex(dev, buf, &tclprim);
+                       radeon_cp_dispatch_vertex(dev, file_priv, buf, &tclprim);
                }
 
                if (sarea_priv->nbox == 1)
@@ -2560,7 +2590,7 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file
        }
 
        if (vertex->discard) {
-               radeon_cp_discard_buffer(dev, buf);
+               radeon_cp_discard_buffer(dev, file_priv->master, buf);
        }
 
        COMMIT_RING();
@@ -2909,7 +2939,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file
                                goto err;
                        }
 
-                       radeon_cp_discard_buffer(dev, buf);
+                       radeon_cp_discard_buffer(dev, file_priv->master, buf);
                        break;
 
                case RADEON_CMD_PACKET3:
@@ -2987,14 +3017,14 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
                break;
        case RADEON_PARAM_LAST_FRAME:
                dev_priv->stats.last_frame_reads++;
-               value = GET_SCRATCH(0);
+               value = GET_SCRATCH(dev_priv, 0);
                break;
        case RADEON_PARAM_LAST_DISPATCH:
-               value = GET_SCRATCH(1);
+               value = GET_SCRATCH(dev_priv, 1);
                break;
        case RADEON_PARAM_LAST_CLEAR:
                dev_priv->stats.last_clear_reads++;
-               value = GET_SCRATCH(2);
+               value = GET_SCRATCH(dev_priv, 2);
                break;
        case RADEON_PARAM_IRQ_NR:
                value = drm_dev_to_irq(dev);
@@ -3020,7 +3050,7 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
                 */
        case RADEON_PARAM_SAREA_HANDLE:
                /* The lock is the first dword in the sarea. */
-               value = (long)dev->lock.hw_lock;
+               /* no users of this parameter */
                break;
 #endif
        case RADEON_PARAM_GART_TEX_HANDLE:
@@ -3029,7 +3059,10 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
        case RADEON_PARAM_SCRATCH_OFFSET:
                if (!dev_priv->writeback_works)
                        return -EINVAL;
-               value = RADEON_SCRATCH_REG_OFFSET;
+               if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+                       value = R600_SCRATCH_REG_OFFSET;
+               else
+                       value = RADEON_SCRATCH_REG_OFFSET;
                break;
        case RADEON_PARAM_CARD_TYPE:
                if (dev_priv->flags & RADEON_IS_PCIE)
@@ -3064,6 +3097,7 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
 static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
+       struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
        drm_radeon_setparam_t *sp = data;
        struct drm_radeon_driver_file_fields *radeon_priv;
 
@@ -3078,12 +3112,14 @@ static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_fil
                        DRM_DEBUG("color tiling disabled\n");
                        dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO;
                        dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO;
-                       dev_priv->sarea_priv->tiling_enabled = 0;
+                       if (master_priv->sarea_priv)
+                               master_priv->sarea_priv->tiling_enabled = 0;
                } else if (sp->value == 1) {
                        DRM_DEBUG("color tiling enabled\n");
                        dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO;
                        dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO;
-                       dev_priv->sarea_priv->tiling_enabled = 1;
+                       if (master_priv->sarea_priv)
+                               master_priv->sarea_priv->tiling_enabled = 1;
                }
                break;
        case RADEON_SETPARAM_PCIGART_LOCATION:
@@ -3129,14 +3165,7 @@ void radeon_driver_preclose(struct drm_device *dev, struct drm_file *file_priv)
 
 void radeon_driver_lastclose(struct drm_device *dev)
 {
-       if (dev->dev_private) {
-               drm_radeon_private_t *dev_priv = dev->dev_private;
-
-               if (dev_priv->sarea_priv &&
-                   dev_priv->sarea_priv->pfCurrentPage != 0)
-                       radeon_cp_dispatch_flip(dev);
-       }
-
+       radeon_surfaces_release(PCIGART_FILE_PRIV, dev->dev_private);
        radeon_do_release(dev);
 }