drm/radeon: rework ring syncing code
[deliverable/linux.git] / drivers / gpu / drm / radeon / radeon_cs.c
index c7d64a7390339e7b6fe29e27de06265843a865ff..dd3e234294e443ea1f959af0f0f5053d3c0560e0 100644 (file)
@@ -115,38 +115,23 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority
        return 0;
 }
 
-static int radeon_cs_sync_rings(struct radeon_cs_parser *p)
+static void radeon_cs_sync_rings(struct radeon_cs_parser *p)
 {
-       bool sync_to_ring[RADEON_NUM_RINGS] = { };
-       bool need_sync = false;
-       int i, r;
+       int i;
 
        for (i = 0; i < p->nrelocs; i++) {
-               struct radeon_fence *fence;
+               struct radeon_fence *a, *b;
 
                if (!p->relocs[i].robj || !p->relocs[i].robj->tbo.sync_obj)
                        continue;
 
-               fence = p->relocs[i].robj->tbo.sync_obj;
-               if (fence->ring != p->ring && !radeon_fence_signaled(fence)) {
-                       sync_to_ring[fence->ring] = true;
-                       need_sync = true;
-               }
-       }
-
-       if (!need_sync) {
-               return 0;
-       }
-
-       r = radeon_semaphore_create(p->rdev, &p->ib.semaphore);
-       if (r) {
-               return r;
+               a = p->relocs[i].robj->tbo.sync_obj;
+               b = p->ib.sync_to[a->ring];
+               p->ib.sync_to[a->ring] = radeon_fence_later(a, b);
        }
-
-       return radeon_semaphore_sync_rings(p->rdev, p->ib.semaphore,
-                                          sync_to_ring, p->ring);
 }
 
+/* XXX: note that this is called from the legacy UMS CS ioctl as well */
 int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
 {
        struct drm_radeon_cs *cs = data;
@@ -245,22 +230,24 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
                }
        }
 
-       if ((p->cs_flags & RADEON_CS_USE_VM) &&
-           !p->rdev->vm_manager.enabled) {
-               DRM_ERROR("VM not active on asic!\n");
-               return -EINVAL;
-       }
-
-       /* we only support VM on SI+ */
-       if ((p->rdev->family >= CHIP_TAHITI) &&
-           ((p->cs_flags & RADEON_CS_USE_VM) == 0)) {
-               DRM_ERROR("VM required on SI+!\n");
-               return -EINVAL;
-       }
+       /* these are KMS only */
+       if (p->rdev) {
+               if ((p->cs_flags & RADEON_CS_USE_VM) &&
+                   !p->rdev->vm_manager.enabled) {
+                       DRM_ERROR("VM not active on asic!\n");
+                       return -EINVAL;
+               }
 
-       if (radeon_cs_get_ring(p, ring, priority))
-               return -EINVAL;
+               /* we only support VM on SI+ */
+               if ((p->rdev->family >= CHIP_TAHITI) &&
+                   ((p->cs_flags & RADEON_CS_USE_VM) == 0)) {
+                       DRM_ERROR("VM required on SI+!\n");
+                       return -EINVAL;
+               }
 
+               if (radeon_cs_get_ring(p, ring, priority))
+                       return -EINVAL;
+       }
 
        /* deal with non-vm */
        if ((p->chunk_ib_idx != -1) &&
@@ -365,10 +352,7 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev,
                DRM_ERROR("Invalid command stream !\n");
                return r;
        }
-       r = radeon_cs_sync_rings(parser);
-       if (r) {
-               DRM_ERROR("Failed to synchronize rings !\n");
-       }
+       radeon_cs_sync_rings(parser);
        parser->ib.vm_id = 0;
        r = radeon_ib_schedule(rdev, &parser->ib);
        if (r) {
@@ -465,10 +449,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
        if (r) {
                goto out;
        }
-       r = radeon_cs_sync_rings(parser);
-       if (r) {
-               DRM_ERROR("Failed to synchronize rings !\n");
-       }
+       radeon_cs_sync_rings(parser);
 
        if ((rdev->family >= CHIP_TAHITI) &&
            (parser->chunk_const_ib_idx != -1)) {
@@ -580,7 +561,7 @@ int radeon_cs_finish_pages(struct radeon_cs_parser *p)
        return 0;
 }
 
-int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx)
+static int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx)
 {
        int new_page;
        struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx];
@@ -623,3 +604,28 @@ int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx)
 
        return new_page;
 }
+
+u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx)
+{
+       struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx];
+       u32 pg_idx, pg_offset;
+       u32 idx_value = 0;
+       int new_page;
+
+       pg_idx = (idx * 4) / PAGE_SIZE;
+       pg_offset = (idx * 4) % PAGE_SIZE;
+
+       if (ibc->kpage_idx[0] == pg_idx)
+               return ibc->kpage[0][pg_offset/4];
+       if (ibc->kpage_idx[1] == pg_idx)
+               return ibc->kpage[1][pg_offset/4];
+
+       new_page = radeon_cs_update_pages(p, pg_idx);
+       if (new_page < 0) {
+               p->parser_error = new_page;
+               return 0;
+       }
+
+       idx_value = ibc->kpage[new_page][pg_offset/4];
+       return idx_value;
+}
This page took 0.026899 seconds and 5 git commands to generate.