1 /* 2 * Copyright 2023 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 */ 23 24 #include <linux/delay.h> 25 #include "amdgpu.h" 26 #include "lsdma_v7_0.h" 27 #include "amdgpu_lsdma.h" 28 29 #include "lsdma/lsdma_7_0_0_offset.h" 30 #include "lsdma/lsdma_7_0_0_sh_mask.h" 31 32 static int lsdma_v7_0_wait_pio_status(struct amdgpu_device *adev) 33 { 34 return amdgpu_lsdma_wait_for(adev, SOC15_REG_OFFSET(LSDMA, 0, regLSDMA_PIO_STATUS), 35 LSDMA_PIO_STATUS__PIO_IDLE_MASK | LSDMA_PIO_STATUS__PIO_FIFO_EMPTY_MASK, 36 LSDMA_PIO_STATUS__PIO_IDLE_MASK | LSDMA_PIO_STATUS__PIO_FIFO_EMPTY_MASK); 37 } 38 39 static int lsdma_v7_0_copy_mem(struct amdgpu_device *adev, 40 uint64_t src_addr, 41 uint64_t dst_addr, 42 uint64_t size) 43 { 44 int ret; 45 uint32_t tmp; 46 47 WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_SRC_ADDR_LO, lower_32_bits(src_addr)); 48 WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_SRC_ADDR_HI, upper_32_bits(src_addr)); 49 50 WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_DST_ADDR_LO, lower_32_bits(dst_addr)); 51 WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_DST_ADDR_HI, upper_32_bits(dst_addr)); 52 53 WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_CONTROL, 0x0); 54 55 tmp = RREG32_SOC15(LSDMA, 0, regLSDMA_PIO_COMMAND); 56 tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, BYTE_COUNT, size); 57 tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, SRC_LOCATION, 0); 58 tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, DST_LOCATION, 0); 59 tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, SRC_ADDR_INC, 0); 60 tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, DST_ADDR_INC, 0); 61 tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, OVERLAP_DISABLE, 0); 62 tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, CONSTANT_FILL, 0); 63 WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_COMMAND, tmp); 64 65 ret = lsdma_v7_0_wait_pio_status(adev); 66 if (ret) 67 dev_err(adev->dev, "LSDMA PIO failed to copy memory!\n"); 68 69 return ret; 70 } 71 72 static int lsdma_v7_0_fill_mem(struct amdgpu_device *adev, 73 uint64_t dst_addr, 74 uint32_t data, 75 uint64_t size) 76 { 77 int ret; 78 uint32_t tmp; 79 80 WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_CONSTFILL_DATA, data); 81 82 WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_DST_ADDR_LO, lower_32_bits(dst_addr)); 83 WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_DST_ADDR_HI, upper_32_bits(dst_addr)); 84 85 WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_CONTROL, 0x0); 86 87 tmp = RREG32_SOC15(LSDMA, 0, regLSDMA_PIO_COMMAND); 88 tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, BYTE_COUNT, size); 89 tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, SRC_LOCATION, 0); 90 tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, DST_LOCATION, 0); 91 tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, SRC_ADDR_INC, 0); 92 tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, DST_ADDR_INC, 0); 93 tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, OVERLAP_DISABLE, 0); 94 tmp = REG_SET_FIELD(tmp, LSDMA_PIO_COMMAND, CONSTANT_FILL, 1); 95 WREG32_SOC15(LSDMA, 0, regLSDMA_PIO_COMMAND, tmp); 96 97 ret = lsdma_v7_0_wait_pio_status(adev); 98 if (ret) 99 dev_err(adev->dev, "LSDMA PIO failed to fill memory!\n"); 100 101 return ret; 102 } 103 104 static void lsdma_v7_0_update_memory_power_gating(struct amdgpu_device *adev, 105 bool enable) 106 { 107 uint32_t tmp; 108 109 tmp = RREG32_SOC15(LSDMA, 0, regLSDMA_MEM_POWER_CTRL); 110 tmp = REG_SET_FIELD(tmp, LSDMA_MEM_POWER_CTRL, MEM_POWER_CTRL_EN, 0); 111 WREG32_SOC15(LSDMA, 0, regLSDMA_MEM_POWER_CTRL, tmp); 112 113 tmp = REG_SET_FIELD(tmp, LSDMA_MEM_POWER_CTRL, MEM_POWER_CTRL_EN, enable); 114 WREG32_SOC15(LSDMA, 0, regLSDMA_MEM_POWER_CTRL, tmp); 115 } 116 117 const struct amdgpu_lsdma_funcs lsdma_v7_0_funcs = { 118 .copy_mem = lsdma_v7_0_copy_mem, 119 .fill_mem = lsdma_v7_0_fill_mem, 120 .update_memory_power_gating = lsdma_v7_0_update_memory_power_gating 121 }; 122