drm/radeon/kms: Fix r600 blit cleanup path
[safe/jmp/linux-2.6] / drivers / gpu / drm / radeon / r600_blit_kms.c
index 4f0d181..2bedce4 100644 (file)
@@ -368,7 +368,7 @@ set_default_state(struct radeon_device *rdev)
        if ((rdev->family == CHIP_RV610) ||
            (rdev->family == CHIP_RV620) ||
            (rdev->family == CHIP_RS780) ||
-           (rdev->family == CHIP_RS780) ||
+           (rdev->family == CHIP_RS880) ||
            (rdev->family == CHIP_RV710))
                sq_config = 0;
        else
@@ -473,31 +473,25 @@ int r600_blit_init(struct radeon_device *rdev)
        obj_size += r6xx_ps_size * 4;
        obj_size = ALIGN(obj_size, 256);
 
-       r = radeon_object_create(rdev, NULL, obj_size,
-                                true, RADEON_GEM_DOMAIN_VRAM,
-                                false, &rdev->r600_blit.shader_obj);
+       r = radeon_bo_create(rdev, NULL, obj_size, true, RADEON_GEM_DOMAIN_VRAM,
+                               &rdev->r600_blit.shader_obj);
        if (r) {
                DRM_ERROR("r600 failed to allocate shader\n");
                return r;
        }
 
-       r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
-                            &rdev->r600_blit.shader_gpu_addr);
-       if (r) {
-               DRM_ERROR("failed to pin blit object %d\n", r);
-               return r;
-       }
-
-       DRM_DEBUG("r6xx blit allocated bo @ 0x%16llx %08x vs %08x ps %08x\n",
-                 rdev->r600_blit.shader_gpu_addr, obj_size,
+       DRM_DEBUG("r6xx blit allocated bo %08x vs %08x ps %08x\n",
+                 obj_size,
                  rdev->r600_blit.vs_offset, rdev->r600_blit.ps_offset);
 
-       r = radeon_object_kmap(rdev->r600_blit.shader_obj, &ptr);
+       r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+       if (unlikely(r != 0))
+               return r;
+       r = radeon_bo_kmap(rdev->r600_blit.shader_obj, &ptr);
        if (r) {
                DRM_ERROR("failed to map blit object %d\n", r);
                return r;
        }
-
        if (rdev->family >= CHIP_RV770)
                memcpy_toio(ptr + rdev->r600_blit.state_offset,
                            r7xx_default_state, rdev->r600_blit.state_len * 4);
@@ -507,19 +501,28 @@ int r600_blit_init(struct radeon_device *rdev)
        if (num_packet2s)
                memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
                            packet2s, num_packet2s * 4);
-
-
        memcpy(ptr + rdev->r600_blit.vs_offset, r6xx_vs, r6xx_vs_size * 4);
        memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4);
-
-       radeon_object_kunmap(rdev->r600_blit.shader_obj);
+       radeon_bo_kunmap(rdev->r600_blit.shader_obj);
+       radeon_bo_unreserve(rdev->r600_blit.shader_obj);
        return 0;
 }
 
 void r600_blit_fini(struct radeon_device *rdev)
 {
-       radeon_object_unpin(rdev->r600_blit.shader_obj);
-       radeon_object_unref(&rdev->r600_blit.shader_obj);
+       int r;
+
+       if (rdev->r600_blit.shader_obj == NULL)
+               return;
+       /* If we can't reserve the bo, unref should be enough to destroy
+        * it when it becomes idle.
+        */
+       r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+       if (!r) {
+               radeon_bo_unpin(rdev->r600_blit.shader_obj);
+               radeon_bo_unreserve(rdev->r600_blit.shader_obj);
+       }
+       radeon_bo_unref(&rdev->r600_blit.shader_obj);
 }
 
 int r600_vb_ib_get(struct radeon_device *rdev)
@@ -548,10 +551,13 @@ void r600_vb_ib_put(struct radeon_device *rdev)
 int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
 {
        int r;
-       int ring_size;
+       int ring_size, line_size;
        int max_size;
        /* loops of emits 64 + fence emit possible */
-       int dwords_per_loop = 76;
+       int dwords_per_loop = 76, num_loops;
+
+       r = r600_vb_ib_get(rdev);
+       WARN_ON(r);
 
        /* set_render_target emits 2 extra dwords on rv6xx */
        if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770)
@@ -559,19 +565,23 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
 
        /* 8 bpp vs 32 bpp for xfer unit */
        if (size_bytes & 3)
-               max_size = 8192*8192;
+               line_size = 8192;
        else
-               max_size = 8192*8192*4;
+               line_size = 8192*4;
 
-       r = r600_vb_ib_get(rdev);
-       WARN_ON(r);
+       max_size = 8192 * line_size;
 
-       ring_size = ((size_bytes + max_size) / max_size) * dwords_per_loop;
+       /* major loops cover the max size transfer */
+       num_loops = ((size_bytes + max_size) / max_size);
+       /* minor loops cover the extra non aligned bits */
+       num_loops += ((size_bytes % line_size) ? 1 : 0);
+       /* calculate number of loops correctly */
+       ring_size = num_loops * dwords_per_loop;
        /* set default  + shaders */
        ring_size += 40; /* shaders + def state */
-       ring_size += 3; /* fence emit for VB IB */
+       ring_size += 7; /* fence emit for VB IB */
        ring_size += 5; /* done copy */
-       ring_size += 3; /* fence emit for done copy */
+       ring_size += 7; /* fence emit for done copy */
        r = radeon_ring_lock(rdev, ring_size);
        WARN_ON(r);
 
@@ -774,7 +784,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
 
                        /* dst 23 */
                        set_render_target(rdev, COLOR_8_8_8_8,
-                                         dst_x + cur_size, h,
+                                         (dst_x + cur_size) / 4, h,
                                          dst_gpu_addr);
 
                        /* scissors 12  */