radeon: make new CS2 command submission interface port older interface to this
authorDave Airlie <airlied@redhat.com>
Sun, 2 Nov 2008 23:39:53 +0000 (09:39 +1000)
committerDave Airlie <airlied@redhat.com>
Sun, 2 Nov 2008 23:39:53 +0000 (09:39 +1000)
linux-core/radeon_gem.c
shared-core/radeon_cs.c
shared-core/radeon_drm.h
shared-core/radeon_drv.h
shared-core/radeon_state.c

index 4b15fac..7899490 100644 (file)
@@ -1148,11 +1148,11 @@ int radeon_gem_object_unpin(struct drm_gem_object *obj)
 
 #define RADEON_NUM_IB (RADEON_IB_MEMORY / RADEON_IB_SIZE)
 
-int radeon_gem_ib_get(struct drm_device *dev, void **ib, uint32_t dwords, uint32_t *card_offset)
+int radeon_gem_ib_get(struct drm_radeon_cs_parser *parser, uint32_t *card_offset)
 {
        int i, index = -1;
        int ret;
-       drm_radeon_private_t *dev_priv = dev->dev_private;
+       drm_radeon_private_t *dev_priv = parser->dev->dev_private;
 
        for (i = 0; i < RADEON_NUM_IB; i++) {
                if (!(dev_priv->ib_alloc_bitmap & (1 << i))){
@@ -1178,12 +1178,12 @@ int radeon_gem_ib_get(struct drm_device *dev, void **ib, uint32_t dwords, uint32
        }
 
        if (index == -1) {
-               DRM_ERROR("Major case fail to allocate IB from freelist %x\n", dev_priv->ib_alloc_bitmap);
+               DRM_ERROR("Major case fail to allocate IB from freelist %llx\n", dev_priv->ib_alloc_bitmap);
                return -EINVAL;
        }
                
 
-       if (dwords > RADEON_IB_SIZE / sizeof(uint32_t))
+       if (parser->chunks[parser->ib_index].length_dw > RADEON_IB_SIZE / sizeof(uint32_t))
                return -EINVAL;
 
        ret = drm_bo_do_validate(dev_priv->ib_objs[index]->bo, 0,
@@ -1195,25 +1195,24 @@ int radeon_gem_ib_get(struct drm_device *dev, void **ib, uint32_t dwords, uint32
        }
                
        *card_offset = dev_priv->gart_vm_start + dev_priv->ib_objs[index]->bo->offset;
-       *ib = dev_priv->ib_objs[index]->kmap.virtual;
+       parser->ib = dev_priv->ib_objs[index]->kmap.virtual;
        dev_priv->ib_alloc_bitmap |= (1 << i);
        return 0;
 }
 
-static void radeon_gem_ib_free(struct drm_device *dev, void *ib, uint32_t dwords)
+static void radeon_gem_ib_free(struct drm_radeon_cs_parser *parser)
 {
+       struct drm_device *dev = parser->dev;
        drm_radeon_private_t *dev_priv = dev->dev_private;
        struct drm_fence_object *fence;
        int ret;
        int i;
 
        for (i = 0; i < RADEON_NUM_IB; i++) {
-
-               if (dev_priv->ib_objs[i]->kmap.virtual == ib) {
+               if (dev_priv->ib_objs[i]->kmap.virtual == parser->ib) {
                        /* emit a fence object */
                        ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence);
                        if (ret) {
-                               
                                drm_putback_buffer_objects(dev);
                        }
                        /* dereference the fence object */
@@ -1243,19 +1242,19 @@ static int radeon_gem_ib_destroy(struct drm_device *dev)
        return 0;
 }
 
-static int radeon_gem_relocate(struct drm_device *dev, struct drm_file *file_priv,
-                               uint32_t *reloc, uint32_t *offset)
+static int radeon_gem_relocate(struct drm_radeon_cs_parser *parser,
+                              uint32_t *reloc, uint32_t *offset)
 {
+       struct drm_device *dev = parser->dev;
        drm_radeon_private_t *dev_priv = dev->dev_private;
        /* relocate the handle */
        uint32_t read_domains = reloc[2];
        uint32_t write_domain = reloc[3];
        struct drm_gem_object *obj;
        int flags = 0;
-       int ret;
        struct drm_radeon_gem_object *obj_priv;
 
-       obj = drm_gem_object_lookup(dev, file_priv, reloc[1]);
+       obj = drm_gem_object_lookup(dev, parser->file_priv, reloc[1]);
        if (!obj)
                return -EINVAL;
 
index b598289..452f04b 100644 (file)
 #include "radeon_drv.h"
 #include "r300_reg.h"
 
+int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
+{
+       struct drm_radeon_cs_parser parser;
+       struct drm_radeon_private *dev_priv = dev->dev_private;
+       struct drm_radeon_cs2 *cs = data;
+       uint32_t cs_id;
+       struct drm_radeon_cs_chunk __user **chunk_ptr = NULL;
+       uint64_t *chunk_array;
+       uint64_t *chunk_array_ptr;
+       uint32_t card_offset;
+       long size;
+       int r, i;
+       RING_LOCALS;
+
+       /* set command stream id to 0 which is fake id */
+       cs_id = 0;
+       DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t));
+
+       if (dev_priv == NULL) {
+               DRM_ERROR("called with no initialization\n");
+               return -EINVAL;
+       }
+       if (!cs->num_chunks) {
+               return 0;
+       }
+
+
+       chunk_array = drm_calloc(cs->num_chunks, sizeof(uint64_t), DRM_MEM_DRIVER);
+       if (!chunk_array) {
+               return -ENOMEM;
+       }
+
+       chunk_array_ptr = (uint64_t *)(unsigned long)(cs->chunks);
+
+       if (DRM_COPY_FROM_USER(chunk_array, chunk_array_ptr, sizeof(uint64_t)*cs->num_chunks)) {
+               r = -EFAULT;
+               goto out;
+       }
+
+       parser.reloc_index = -1;
+       parser.ib_index = -1;
+       parser.num_chunks = cs->num_chunks;
+       /* copy out the chunk headers */
+       parser.chunks = drm_calloc(parser.num_chunks, sizeof(struct drm_radeon_kernel_chunk), DRM_MEM_DRIVER);
+       if (!parser.chunks) {
+               return -ENOMEM;
+       }
+
+       for (i = 0; i < parser.num_chunks; i++) {
+               struct drm_radeon_cs_chunk user_chunk;
+
+               chunk_ptr = (void __user *)(unsigned long)chunk_array[i];
+
+               if (DRM_COPY_FROM_USER(&user_chunk, chunk_ptr, sizeof(struct drm_radeon_cs_chunk))){
+                       r = -EFAULT;
+                       goto out;
+               }
+               parser.chunks[i].chunk_id = user_chunk.chunk_id;
+
+               if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS)
+                       parser.reloc_index = i;
+
+               if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_IB)
+                       parser.ib_index = i;
+
+               if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_OLD) {
+                       parser.ib_index = i;
+                       parser.reloc_index = -1;
+               }
+
+               parser.chunks[i].length_dw = user_chunk.length_dw;
+               parser.chunks[i].chunk_data = (uint32_t *)(unsigned long)user_chunk.chunk_data;
+
+               parser.chunks[i].kdata = NULL;
+
+               switch(parser.chunks[i].chunk_id) {
+               case RADEON_CHUNK_ID_RELOCS:
+               case RADEON_CHUNK_ID_IB:
+               case RADEON_CHUNK_ID_OLD: {
+                       /* copy from user the relocs chunk */
+                       int size = parser.chunks[i].length_dw * sizeof(uint32_t);
+                       parser.chunks[i].kdata = drm_alloc(size, DRM_MEM_DRIVER);
+                       if (!parser.chunks[i].kdata) { 
+                               r = -ENOMEM;
+                               goto out;
+                       }
+                       
+                       if (DRM_COPY_FROM_USER(parser.chunks[i].kdata, parser.chunks[i].chunk_data, size)) {
+                               r = -EFAULT;
+                               goto out;
+                       }
+               }
+                       break;
+               default:
+                       break;
+               }
+               DRM_DEBUG("chunk %d %d %d %p\n", i, parser.chunks[i].chunk_id, parser.chunks[i].length_dw,
+                         parser.chunks[i].chunk_data);
+       }
+
+
+       if (parser.chunks[parser.ib_index].length_dw > (16 * 1024)) {
+               DRM_ERROR("cs->dwords too big: %d\n", parser.chunks[parser.ib_index].length_dw);
+               r = -EINVAL;
+               goto out;
+       }
+
+       /* get ib */
+       r = dev_priv->cs.ib_get(&parser, &card_offset);
+       if (r) {
+               DRM_ERROR("ib_get failed\n");
+               goto out;
+       }
+
+       /* now parse command stream */
+       r = dev_priv->cs.parse(&parser);
+       if (r) {
+               goto out;
+       }
+
+       BEGIN_RING(4);
+       OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
+       OUT_RING(card_offset);
+       OUT_RING(parser.chunks[parser.ib_index].length_dw);
+       OUT_RING(CP_PACKET2());
+       ADVANCE_RING();
+
+       /* emit cs id sequence */
+       dev_priv->cs.id_emit(dev, &cs_id);
+       COMMIT_RING();
+
+       DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t));
+out:
+       dev_priv->cs.ib_free(&parser);
+
+       for (i = 0; i < parser.num_chunks; i++) {
+               if (parser.chunks[i].kdata)
+                       drm_free(parser.chunks[i].kdata, parser.chunks[i].length_dw * sizeof(uint32_t), DRM_MEM_DRIVER);
+       }
+
+       drm_free(parser.chunks, sizeof(struct drm_radeon_kernel_chunk)*parser.num_chunks, DRM_MEM_DRIVER);
+       drm_free(chunk_array, sizeof(uint64_t)*parser.num_chunks, DRM_MEM_DRIVER);
+
+       return r;
+}
+
 int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
 {
+       struct drm_radeon_cs_parser parser;
        struct drm_radeon_private *dev_priv = dev->dev_private;
        struct drm_radeon_cs *cs = data;
        uint32_t *packets = NULL;
        uint32_t cs_id;
        uint32_t card_offset;
-       void *ib = NULL;
        long size;
        int r;
+       struct drm_radeon_kernel_chunk chunk_fake[1];
        RING_LOCALS;
 
        /* set command stream id to 0 which is fake id */
@@ -69,14 +216,26 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
                r = -EFAULT;
                goto out;
        }
+
+       chunk_fake[0].chunk_id = RADEON_CHUNK_ID_OLD;
+       chunk_fake[0].length_dw = cs->dwords;
+       chunk_fake[0].kdata = packets;
+
+       parser.dev = dev;
+       parser.file_priv = fpriv;
+       parser.num_chunks = 1;
+       parser.chunks = chunk_fake;
+       parser.ib_index = 0;
+       parser.reloc_index = -1;
+
        /* get ib */
-       r = dev_priv->cs.ib_get(dev, &ib, cs->dwords, &card_offset);
+       r = dev_priv->cs.ib_get(&parser, &card_offset);
        if (r) {
                goto out;
        }
 
        /* now parse command stream */
-       r = dev_priv->cs.parse(dev, fpriv, ib, packets, cs->dwords);
+       r = dev_priv->cs.parse(&parser);
        if (r) {
                goto out;
        }
@@ -94,13 +253,13 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
 
        DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t));
 out:
-       dev_priv->cs.ib_free(dev, ib, cs->dwords);
+       dev_priv->cs.ib_free(&parser);
        drm_free(packets, size, DRM_MEM_DRIVER);
        return r;
 }
 
 /* for non-mm */
-static int radeon_nomm_relocate(struct drm_device *dev, struct drm_file *file_priv, uint32_t *reloc, uint32_t *offset)
+static int radeon_nomm_relocate(struct drm_radeon_cs_parser *parser, uint32_t *reloc, uint32_t *offset)
 {
        *offset = reloc[1];
        return 0;
@@ -108,17 +267,24 @@ static int radeon_nomm_relocate(struct drm_device *dev, struct drm_file *file_pr
 #define RELOC_SIZE 2
 #define RADEON_2D_OFFSET_MASK 0x3fffff
 
-static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct drm_file *file_priv,
-                                                uint32_t *packets, uint32_t offset_dw)
+static __inline__ int radeon_cs_relocate_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw)
 {
+       struct drm_device *dev = parser->dev;
        drm_radeon_private_t *dev_priv = dev->dev_private;
-       uint32_t hdr = packets[offset_dw];
-       uint32_t reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2;
-       uint32_t val = packets[offset_dw + 1];
-       uint32_t packet3_hdr = packets[offset_dw+2];
+       uint32_t hdr, reg, val, packet3_hdr;
        uint32_t tmp, offset;
+       struct drm_radeon_kernel_chunk *ib_chunk;
        int ret;
 
+       ib_chunk = &parser->chunks[parser->ib_index];
+//     if (parser->reloc_index == -1)
+//             is_old = 1;
+
+       hdr = ib_chunk->kdata[offset_dw];
+       reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2;
+       val = ib_chunk->kdata[offset_dw + 1];
+       packet3_hdr = ib_chunk->kdata[offset_dw + 2];
+
        /* this is too strict we may want to expand the length in the future and have
         old kernels ignore it. */ 
        if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) {
@@ -130,7 +296,7 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct
        case RADEON_DST_PITCH_OFFSET:
        case RADEON_SRC_PITCH_OFFSET:
                /* pass in the start of the reloc */
-               ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + 2, &offset);
+               ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + 2, &offset);
                if (ret)
                        return ret;
                tmp = (val & RADEON_2D_OFFSET_MASK) << 10;
@@ -148,7 +314,7 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct
        case R200_PP_TXOFFSET_1:
        case RADEON_PP_TXOFFSET_0:
        case RADEON_PP_TXOFFSET_1:
-               ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + 2, &offset);
+               ret = dev_priv->cs.relocate(parser. ib_chunk->kdata + offset_dw + 2, &offset);
                if (ret)
                        return ret;
 
@@ -159,25 +325,32 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct
                break;
        }
 
-       packets[offset_dw + 1] = val;
+       ib_chunk->kdata[offset_dw + 1] = val;
        return 0;
 }
 
-static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *file_priv,
-                                     uint32_t *packets, uint32_t offset_dw)
+static int radeon_cs_relocate_packet3(struct drm_radeon_cs_parser *parser,
+                                     uint32_t offset_dw)
 {
-       drm_radeon_private_t *dev_priv = dev->dev_private;
-       uint32_t hdr = packets[offset_dw];
-       int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16;
-       uint32_t reg = hdr & 0xff00;
+       drm_radeon_private_t *dev_priv = parser->dev->dev_private;
+       uint32_t hdr, num_dw, reg;
        uint32_t offset, val, tmp;
        int ret;
+       struct drm_radeon_kernel_chunk *ib_chunk;
+
+       ib_chunk = &parser->chunks[parser->ib_index];
+//     if (parser->reloc_index == -1)
+//             is_old = 1;
+
+       hdr = ib_chunk->kdata[offset_dw];
+       num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16;
+       reg = hdr & 0xff00;
 
        switch(reg) {
        case RADEON_CNTL_HOSTDATA_BLT:
        {
-               val = packets[offset_dw + 2];
-               ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + num_dw + 2, &offset);
+               val = ib_chunk->kdata[offset_dw + 2];
+               ret = dev_priv->cs.relocate(parser, ib_chunk->kdata + offset_dw + num_dw + 2, &offset);
                if (ret)
                        return ret;
 
@@ -187,7 +360,7 @@ static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *f
                offset >>= 10;
                val |= offset;
 
-               packets[offset_dw + 2] = val;
+               ib_chunk->kdata[offset_dw + 2] = val;
        }
        default:
                return -EINVAL;
@@ -195,17 +368,18 @@ static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *f
        return 0;
 }
 
-int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv,
-                     uint32_t *packets, uint32_t offset_dw)
+int radeon_cs_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw)
 {
-       drm_radeon_private_t *dev_priv = dev->dev_private;
-       uint32_t hdr = packets[offset_dw];
-       int num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2;
+       drm_radeon_private_t *dev_priv = parser->dev->dev_private;
+       uint32_t hdr, num_dw, reg;
        int need_reloc = 0;
-       int reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2;
        int count_dw = 1;
        int ret;
 
+       hdr = parser->chunks[parser->ib_index].kdata[offset_dw];
+       num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2;
+       reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2;
+
        while (count_dw < num_dw) {
                /* need to have something like the r300 validation here - 
                   list of allowed registers */
@@ -226,7 +400,7 @@ int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv,
                                        return -EINVAL;
                                }
 
-                               ret = radeon_cs_relocate_packet0(dev, file_priv, packets, offset_dw);
+                               ret = radeon_cs_relocate_packet0(parser, offset_dw);
                                if (ret)
                                        return ret;
                                DRM_DEBUG("need to relocate %x %d\n", reg, flags);
@@ -245,24 +419,27 @@ int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv,
        return 0;
 }
 
-int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv,
-                   void *ib, uint32_t *packets, uint32_t dwords)
+int radeon_cs_parse(struct drm_radeon_cs_parser *parser)
 {
-       drm_radeon_private_t *dev_priv = dev->dev_private;
+       struct drm_device *dev = parser->dev;
+       drm_radeon_private_t *dev_priv = parser->dev->dev_private;
        volatile int rb;
-       int size_dw = dwords;
+       struct drm_radeon_kernel_chunk *ib_chunk;
        /* scan the packet for various things */
-       int count_dw = 0;
+       int count_dw = 0, size_dw;
        int ret = 0;
 
+       ib_chunk = &parser->chunks[parser->ib_index];
+       size_dw = ib_chunk->length_dw;
+
        while (count_dw < size_dw && ret == 0) {
-               int hdr = packets[count_dw];
+               int hdr = ib_chunk->kdata[count_dw];
                int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16;
                int reg;
 
                switch (hdr & RADEON_CP_PACKET_MASK) {
                case RADEON_CP_PACKET0:
-                       ret = radeon_cs_packet0(dev, file_priv, packets, count_dw);
+                       ret = radeon_cs_packet0(parser, count_dw);
                        break;
                case RADEON_CP_PACKET1:
                case RADEON_CP_PACKET2:
@@ -275,7 +452,7 @@ int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv,
                        
                        switch(reg) {
                        case RADEON_CNTL_HOSTDATA_BLT:
-                               radeon_cs_relocate_packet3(dev, file_priv, packets, count_dw);
+                               radeon_cs_relocate_packet3(parser, count_dw);
                                break;
 
                        case RADEON_CNTL_BITBLT_MULTI:
@@ -306,10 +483,10 @@ int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv,
             
 
        /* copy the packet into the IB */
-       memcpy(ib, packets, dwords * sizeof(uint32_t));
+       memcpy(parser->ib, ib_chunk->kdata, ib_chunk->length_dw * sizeof(uint32_t));
 
        /* read back last byte to flush WC buffers */
-       rb = readl((ib + (dwords-1) * sizeof(uint32_t)));
+       rb = readl((parser->ib + (ib_chunk->length_dw-1) * sizeof(uint32_t)));
 
        return 0;
 }
index c924c68..bc2eb45 100644 (file)
@@ -514,6 +514,7 @@ typedef struct {
 #define DRM_RADEON_GEM_INDIRECT 0x24 // temporary for X server
 
 #define DRM_RADEON_CS           0x25
+#define DRM_RADEON_CS2       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)
@@ -554,6 +555,7 @@ typedef struct {
 #define DRM_IOCTL_RADEON_GEM_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INDIRECT, struct drm_radeon_gem_indirect)
 
 #define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs)
+#define DRM_IOCTL_RADEON_CS2 DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS2, struct drm_radeon_cs2)
 
 
 typedef struct drm_radeon_init {
@@ -874,11 +876,26 @@ struct drm_radeon_gem_indirect {
 
 
 struct drm_radeon_cs {
-//     uint32_t __user     *packets;
        uint32_t            dwords;
        uint32_t            cs_id;
        uint64_t            packets;
+};
+
+#define RADEON_CHUNK_ID_RELOCS 0x01
+#define RADEON_CHUNK_ID_IB     0x02
+#define RADEON_CHUNK_ID_OLD 0xff
+
+struct drm_radeon_cs_chunk {
+       uint32_t chunk_id;
+       uint32_t length_dw;
+       uint64_t chunk_data;
+};
 
+struct drm_radeon_cs2 {
+       uint32_t        num_chunks;
+       uint32_t        cs_id;
+       uint64_t        chunks; /* this points to uint64_t * which point to
+                                  cs chunks */
 };
 
 
index 17c0c29..b741953 100644 (file)
@@ -294,6 +294,23 @@ struct drm_radeon_master_private {
 #define RADEON_FLUSH_EMITED    (1 < 0)
 #define RADEON_PURGE_EMITED    (1 < 1)
 
+struct drm_radeon_kernel_chunk {
+       uint32_t chunk_id;
+       uint32_t length_dw;
+       uint32_t __user *chunk_data;
+       uint32_t *kdata;
+};
+
+struct drm_radeon_cs_parser {
+       struct drm_device *dev;
+       struct drm_file *file_priv;
+       uint32_t num_chunks;
+       struct drm_radeon_kernel_chunk *chunks;
+       int ib_index;
+       int reloc_index;
+       void *ib;
+};
+
 /* command submission struct */
 struct drm_radeon_cs_priv {
        uint32_t id_wcnt;
@@ -301,21 +318,22 @@ struct drm_radeon_cs_priv {
        uint32_t id_last_wcnt;
        uint32_t id_last_scnt;
 
-       int (*parse)(struct drm_device *dev, struct drm_file *file_priv,
-                    void *ib, uint32_t *packets, uint32_t dwords);
+       int (*parse)(struct drm_radeon_cs_parser *parser);
        void (*id_emit)(struct drm_device *dev, uint32_t *id);
        uint32_t (*id_last_get)(struct drm_device *dev);
        /* this ib handling callback are for hidding memory manager drm
         * from memory manager less drm, free have to emit ib discard
         * sequence into the ring */
-       int (*ib_get)(struct drm_device *dev, void **ib, uint32_t dwords, uint32_t *card_offset);
+       int (*ib_get)(struct drm_radeon_cs_parser *parser, uint32_t *card_offset);
        uint32_t (*ib_get_ptr)(struct drm_device *dev, void *ib);
-       void (*ib_free)(struct drm_device *dev, void *ib, uint32_t dwords);
+       void (*ib_free)(struct drm_radeon_cs_parser *parser);
        /* do a relocation either MM or non-MM */
-       int (*relocate)(struct drm_device *dev, struct drm_file *file_priv,
-                        uint32_t *reloc, uint32_t *offset);
+       int (*relocate)(struct drm_radeon_cs_parser *parser,
+                       uint32_t *reloc, uint32_t *offset);
 };
 
+
+
 struct radeon_pm_regs {
        uint32_t crtc_ext_cntl;
        uint32_t bios_scratch[8];
@@ -1689,6 +1707,7 @@ extern int radeon_master_create(struct drm_device *dev, struct drm_master *maste
 extern void radeon_master_destroy(struct drm_device *dev, struct drm_master *master);
 extern void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master *master);
 extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv);
+extern int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv);
 extern int radeon_cs_init(struct drm_device *dev);
 void radeon_gem_update_offsets(struct drm_device *dev, struct drm_master *master);
 void radeon_init_memory_map(struct drm_device *dev);
index 7262b2a..f0cd6f8 100644 (file)
@@ -3290,6 +3290,7 @@ struct drm_ioctl_desc radeon_ioctls[] = {
        DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH),
        DRM_IOCTL_DEF(DRM_RADEON_GEM_INDIRECT, radeon_gem_indirect_ioctl, DRM_AUTH),
        DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_RADEON_CS2, radeon_cs2_ioctl, DRM_AUTH),
 };
 
 int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);