11b491330SLikun Gao /*
21b491330SLikun Gao  * Copyright 2022 Advanced Micro Devices, Inc.
31b491330SLikun Gao  *
41b491330SLikun Gao  * Permission is hereby granted, free of charge, to any person obtaining a
51b491330SLikun Gao  * copy of this software and associated documentation files (the "Software"),
61b491330SLikun Gao  * to deal in the Software without restriction, including without limitation
71b491330SLikun Gao  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
81b491330SLikun Gao  * and/or sell copies of the Software, and to permit persons to whom the
91b491330SLikun Gao  * Software is furnished to do so, subject to the following conditions:
101b491330SLikun Gao  *
111b491330SLikun Gao  * The above copyright notice and this permission notice shall be included in
121b491330SLikun Gao  * all copies or substantial portions of the Software.
131b491330SLikun Gao  *
141b491330SLikun Gao  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
151b491330SLikun Gao  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
161b491330SLikun Gao  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
171b491330SLikun Gao  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
181b491330SLikun Gao  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
191b491330SLikun Gao  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
201b491330SLikun Gao  * OTHER DEALINGS IN THE SOFTWARE.
211b491330SLikun Gao  *
221b491330SLikun Gao  */
231b491330SLikun Gao 
241b491330SLikun Gao #include "amdgpu.h"
251b491330SLikun Gao #include "amdgpu_lsdma.h"
26f932ffbbSLikun Gao 
27f932ffbbSLikun Gao #define AMDGPU_LSDMA_MAX_SIZE	0x2000000ULL
28f932ffbbSLikun Gao 
amdgpu_lsdma_wait_for(struct amdgpu_device * adev,uint32_t reg_index,uint32_t reg_val,uint32_t mask)29*d9b9aaaeSLikun Gao int amdgpu_lsdma_wait_for(struct amdgpu_device *adev,
30*d9b9aaaeSLikun Gao 			  uint32_t reg_index, uint32_t reg_val,
31*d9b9aaaeSLikun Gao 			  uint32_t mask)
32*d9b9aaaeSLikun Gao {
33*d9b9aaaeSLikun Gao 	uint32_t val;
34*d9b9aaaeSLikun Gao 	int i;
35*d9b9aaaeSLikun Gao 
36*d9b9aaaeSLikun Gao 	for (i = 0; i < adev->usec_timeout; i++) {
37*d9b9aaaeSLikun Gao 		val = RREG32(reg_index);
38*d9b9aaaeSLikun Gao 		if ((val & mask) == reg_val)
39*d9b9aaaeSLikun Gao 			return 0;
40*d9b9aaaeSLikun Gao 		udelay(1);
41*d9b9aaaeSLikun Gao 	}
42*d9b9aaaeSLikun Gao 
43*d9b9aaaeSLikun Gao 	return -ETIME;
44*d9b9aaaeSLikun Gao }
45*d9b9aaaeSLikun Gao 
amdgpu_lsdma_copy_mem(struct amdgpu_device * adev,uint64_t src_addr,uint64_t dst_addr,uint64_t mem_size)46f932ffbbSLikun Gao int amdgpu_lsdma_copy_mem(struct amdgpu_device *adev,
47f932ffbbSLikun Gao 			  uint64_t src_addr,
48f932ffbbSLikun Gao 			  uint64_t dst_addr,
49f932ffbbSLikun Gao 			  uint64_t mem_size)
50f932ffbbSLikun Gao {
51f932ffbbSLikun Gao 	int ret;
52f932ffbbSLikun Gao 
53f932ffbbSLikun Gao 	if (mem_size == 0)
54f932ffbbSLikun Gao 		return -EINVAL;
55f932ffbbSLikun Gao 
56f932ffbbSLikun Gao 	while (mem_size > 0) {
57f932ffbbSLikun Gao 		uint64_t current_copy_size = min(mem_size, AMDGPU_LSDMA_MAX_SIZE);
58f932ffbbSLikun Gao 
59f932ffbbSLikun Gao 		ret = adev->lsdma.funcs->copy_mem(adev, src_addr, dst_addr, current_copy_size);
60f932ffbbSLikun Gao 		if (ret)
61f932ffbbSLikun Gao 			return ret;
62f932ffbbSLikun Gao 		src_addr += current_copy_size;
63f932ffbbSLikun Gao 		dst_addr += current_copy_size;
64f932ffbbSLikun Gao 		mem_size -= current_copy_size;
65f932ffbbSLikun Gao 	}
66f932ffbbSLikun Gao 
67f932ffbbSLikun Gao 	return 0;
68f932ffbbSLikun Gao }
69*d9b9aaaeSLikun Gao 
amdgpu_lsdma_fill_mem(struct amdgpu_device * adev,uint64_t dst_addr,uint32_t data,uint64_t mem_size)70*d9b9aaaeSLikun Gao int amdgpu_lsdma_fill_mem(struct amdgpu_device *adev,
71*d9b9aaaeSLikun Gao 			  uint64_t dst_addr,
72*d9b9aaaeSLikun Gao 			  uint32_t data,
73*d9b9aaaeSLikun Gao 			  uint64_t mem_size)
74*d9b9aaaeSLikun Gao {
75*d9b9aaaeSLikun Gao 	int ret;
76*d9b9aaaeSLikun Gao 
77*d9b9aaaeSLikun Gao 	if (mem_size == 0)
78*d9b9aaaeSLikun Gao 		return -EINVAL;
79*d9b9aaaeSLikun Gao 
80*d9b9aaaeSLikun Gao 	while (mem_size > 0) {
81*d9b9aaaeSLikun Gao 		uint64_t current_fill_size = min(mem_size, AMDGPU_LSDMA_MAX_SIZE);
82*d9b9aaaeSLikun Gao 
83*d9b9aaaeSLikun Gao 		ret = adev->lsdma.funcs->fill_mem(adev, dst_addr, data, current_fill_size);
84*d9b9aaaeSLikun Gao 		if (ret)
85*d9b9aaaeSLikun Gao 			return ret;
86*d9b9aaaeSLikun Gao 		dst_addr += current_fill_size;
87*d9b9aaaeSLikun Gao 		mem_size -= current_fill_size;
88*d9b9aaaeSLikun Gao 	}
89*d9b9aaaeSLikun Gao 
90*d9b9aaaeSLikun Gao 	return 0;
91*d9b9aaaeSLikun Gao }
92