rv770_dma.c revision aa4c8b36e5fcf70ba5ec7d175da19dac4a33c51a
1d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten/*
2d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * Copyright 2013 Advanced Micro Devices, Inc.
3d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *
4d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * Permission is hereby granted, free of charge, to any person obtaining a
5d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * copy of this software and associated documentation files (the "Software"),
6d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * to deal in the Software without restriction, including without limitation
7d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * and/or sell copies of the Software, and to permit persons to whom the
9d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * Software is furnished to do so, subject to the following conditions:
10d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *
11d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * The above copyright notice and this permission notice shall be included in
12d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * all copies or substantial portions of the Software.
13d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *
14d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * OTHER DEALINGS IN THE SOFTWARE.
21d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *
22d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * Authors: Alex Deucher
23d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten */
24d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten#include <drm/drmP.h>
25d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten#include "radeon.h"
26d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten#include "radeon_asic.h"
27d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten#include "rv770d.h"
28d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
29d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten/**
30d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * rv770_copy_dma - copy pages using the DMA engine
31d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *
323d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten * @rdev: radeon_device pointer
333d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten * @src_offset: src GPU address
343d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten * @dst_offset: dst GPU address
35d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * @num_gpu_pages: number of GPU pages to xfer
36d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * @fence: radeon fence object
37d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *
387180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten * Copy GPU paging using the DMA engine (r7xx).
397180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten * Used by the radeon ttm implementation to move pages if
407180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten * registered as the asic copy callback.
417180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten */
427180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweetenint rv770_copy_dma(struct radeon_device *rdev,
437180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten		  uint64_t src_offset, uint64_t dst_offset,
447180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten		  unsigned num_gpu_pages,
457180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten		  struct radeon_fence **fence)
467180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten{
477180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten	struct radeon_semaphore *sem = NULL;
487180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten	int ring_index = rdev->asic->copy.dma_ring_index;
497180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten	struct radeon_ring *ring = &rdev->ring[ring_index];
507180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten	u32 size_in_dw, cur_size_in_dw;
517180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten	int i, num_loops;
527180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten	int r = 0;
537180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten
547180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten	r = radeon_semaphore_create(rdev, &sem);
557180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten	if (r) {
56d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		DRM_ERROR("radeon: moving bo (%d).\n", r);
57d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		return r;
58d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	}
5923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten
6023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4;
6123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFF);
6223fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	r = radeon_ring_lock(rdev, ring, num_loops * 5 + 8);
63d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	if (r) {
64d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		DRM_ERROR("radeon: moving bo (%d).\n", r);
65d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		radeon_semaphore_free(rdev, &sem, NULL);
66d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		return r;
67d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	}
68d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
69d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	radeon_semaphore_sync_to(sem, *fence);
70d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	radeon_semaphore_sync_rings(rdev, sem, ring->idx);
717180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten
72d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	for (i = 0; i < num_loops; i++) {
73d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		cur_size_in_dw = size_in_dw;
74d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		if (cur_size_in_dw > 0xFFFF)
75d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten			cur_size_in_dw = 0xFFFF;
767180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten		size_in_dw -= cur_size_in_dw;
77d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_COPY, 0, 0, cur_size_in_dw));
78d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		radeon_ring_write(ring, dst_offset & 0xfffffffc);
79d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		radeon_ring_write(ring, src_offset & 0xfffffffc);
80d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff);
81d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		radeon_ring_write(ring, upper_32_bits(src_offset) & 0xff);
82d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		src_offset += cur_size_in_dw * 4;
83d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		dst_offset += cur_size_in_dw * 4;
8423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	}
8523fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten
8623fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	r = radeon_fence_emit(rdev, fence, ring->idx);
8723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	if (r) {
8823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten		radeon_ring_unlock_undo(rdev, ring);
8923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten		radeon_semaphore_free(rdev, &sem, NULL);
9023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten		return r;
9123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	}
9223fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten
9323fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	radeon_ring_unlock_commit(rdev, ring);
9423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	radeon_semaphore_free(rdev, &sem, *fence);
95d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
96d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	return r;
97d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten}
98d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten