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