1 /* 2 * Copyright 2016 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 * Author: Huang Rui 23 * 24 */ 25 26 #include <linux/firmware.h> 27 #include "drmP.h" 28 #include "amdgpu.h" 29 #include "amdgpu_psp.h" 30 #include "amdgpu_ucode.h" 31 #include "soc15_common.h" 32 #include "psp_v10_0.h" 33 34 #include "vega10/soc15ip.h" 35 #include "raven1/MP/mp_10_0_offset.h" 36 #include "raven1/GC/gc_9_1_offset.h" 37 #include "raven1/SDMA0/sdma0_4_1_offset.h" 38 39 static int 40 psp_v10_0_get_fw_type(struct amdgpu_firmware_info *ucode, enum psp_gfx_fw_type *type) 41 { 42 switch(ucode->ucode_id) { 43 case AMDGPU_UCODE_ID_SDMA0: 44 *type = GFX_FW_TYPE_SDMA0; 45 break; 46 case AMDGPU_UCODE_ID_SDMA1: 47 *type = GFX_FW_TYPE_SDMA1; 48 break; 49 case AMDGPU_UCODE_ID_CP_CE: 50 *type = GFX_FW_TYPE_CP_CE; 51 break; 52 case AMDGPU_UCODE_ID_CP_PFP: 53 *type = GFX_FW_TYPE_CP_PFP; 54 break; 55 case AMDGPU_UCODE_ID_CP_ME: 56 *type = GFX_FW_TYPE_CP_ME; 57 break; 58 case AMDGPU_UCODE_ID_CP_MEC1: 59 *type = GFX_FW_TYPE_CP_MEC; 60 break; 61 case AMDGPU_UCODE_ID_CP_MEC1_JT: 62 *type = GFX_FW_TYPE_CP_MEC_ME1; 63 break; 64 case AMDGPU_UCODE_ID_CP_MEC2: 65 *type = GFX_FW_TYPE_CP_MEC; 66 break; 67 case AMDGPU_UCODE_ID_CP_MEC2_JT: 68 *type = GFX_FW_TYPE_CP_MEC_ME2; 69 break; 70 case AMDGPU_UCODE_ID_RLC_G: 71 *type = GFX_FW_TYPE_RLC_G; 72 break; 73 case AMDGPU_UCODE_ID_SMC: 74 *type = GFX_FW_TYPE_SMU; 75 break; 76 case AMDGPU_UCODE_ID_UVD: 77 *type = GFX_FW_TYPE_UVD; 78 break; 79 case AMDGPU_UCODE_ID_VCE: 80 *type = GFX_FW_TYPE_VCE; 81 break; 82 case AMDGPU_UCODE_ID_MAXIMUM: 83 default: 84 return -EINVAL; 85 } 86 87 return 0; 88 } 89 90 int psp_v10_0_prep_cmd_buf(struct amdgpu_firmware_info *ucode, struct psp_gfx_cmd_resp *cmd) 91 { 92 int ret; 93 uint64_t fw_mem_mc_addr = ucode->mc_addr; 94 struct common_firmware_header *header; 95 96 memset(cmd, 0, sizeof(struct psp_gfx_cmd_resp)); 97 header = (struct common_firmware_header *)ucode->fw; 98 99 cmd->cmd_id = GFX_CMD_ID_LOAD_IP_FW; 100 cmd->cmd.cmd_load_ip_fw.fw_phy_addr_lo = (uint32_t)fw_mem_mc_addr; 101 cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = (uint32_t)((uint64_t)fw_mem_mc_addr >> 32); 102 cmd->cmd.cmd_load_ip_fw.fw_size = le32_to_cpu(header->ucode_size_bytes); 103 104 ret = psp_v10_0_get_fw_type(ucode, &cmd->cmd.cmd_load_ip_fw.fw_type); 105 if (ret) 106 DRM_ERROR("Unknown firmware type\n"); 107 108 return ret; 109 } 110 111 int psp_v10_0_ring_init(struct psp_context *psp, enum psp_ring_type ring_type) 112 { 113 int ret = 0; 114 unsigned int psp_ring_reg = 0; 115 struct psp_ring *ring; 116 struct amdgpu_device *adev = psp->adev; 117 118 ring = &psp->km_ring; 119 120 ring->ring_type = ring_type; 121 122 /* allocate 4k Page of Local Frame Buffer memory for ring */ 123 ring->ring_size = 0x1000; 124 ret = amdgpu_bo_create_kernel(adev, ring->ring_size, PAGE_SIZE, 125 AMDGPU_GEM_DOMAIN_VRAM, 126 &adev->firmware.rbuf, 127 &ring->ring_mem_mc_addr, 128 (void **)&ring->ring_mem); 129 if (ret) { 130 ring->ring_size = 0; 131 return ret; 132 } 133 134 /* Write low address of the ring to C2PMSG_69 */ 135 psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr); 136 WREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_69), psp_ring_reg); 137 /* Write high address of the ring to C2PMSG_70 */ 138 psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr); 139 WREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_70), psp_ring_reg); 140 /* Write size of ring to C2PMSG_71 */ 141 psp_ring_reg = ring->ring_size; 142 WREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_71), psp_ring_reg); 143 /* Write the ring initialization command to C2PMSG_64 */ 144 psp_ring_reg = ring_type; 145 psp_ring_reg = psp_ring_reg << 16; 146 WREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64), psp_ring_reg); 147 /* Wait for response flag (bit 31) in C2PMSG_64 */ 148 psp_ring_reg = 0; 149 while ((psp_ring_reg & 0x80000000) == 0) { 150 psp_ring_reg = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64)); 151 } 152 153 return 0; 154 } 155 156 int psp_v10_0_cmd_submit(struct psp_context *psp, 157 struct amdgpu_firmware_info *ucode, 158 uint64_t cmd_buf_mc_addr, uint64_t fence_mc_addr, 159 int index) 160 { 161 unsigned int psp_write_ptr_reg = 0; 162 struct psp_gfx_rb_frame * write_frame = psp->km_ring.ring_mem; 163 struct psp_ring *ring = &psp->km_ring; 164 struct amdgpu_device *adev = psp->adev; 165 166 /* KM (GPCOM) prepare write pointer */ 167 psp_write_ptr_reg = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_67)); 168 169 /* Update KM RB frame pointer to new frame */ 170 if ((psp_write_ptr_reg % ring->ring_size) == 0) 171 write_frame = ring->ring_mem; 172 else 173 write_frame = ring->ring_mem + (psp_write_ptr_reg / (sizeof(struct psp_gfx_rb_frame) / 4)); 174 175 /* Update KM RB frame */ 176 write_frame->cmd_buf_addr_hi = (unsigned int)(cmd_buf_mc_addr >> 32); 177 write_frame->cmd_buf_addr_lo = (unsigned int)(cmd_buf_mc_addr); 178 write_frame->fence_addr_hi = (unsigned int)(fence_mc_addr >> 32); 179 write_frame->fence_addr_lo = (unsigned int)(fence_mc_addr); 180 write_frame->fence_value = index; 181 182 /* Update the write Pointer in DWORDs */ 183 psp_write_ptr_reg += sizeof(struct psp_gfx_rb_frame) / 4; 184 psp_write_ptr_reg = (psp_write_ptr_reg >= ring->ring_size) ? 0 : psp_write_ptr_reg; 185 WREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_67), psp_write_ptr_reg); 186 187 return 0; 188 } 189 190 static int 191 psp_v10_0_sram_map(unsigned int *sram_offset, unsigned int *sram_addr_reg_offset, 192 unsigned int *sram_data_reg_offset, 193 enum AMDGPU_UCODE_ID ucode_id) 194 { 195 int ret = 0; 196 197 switch(ucode_id) { 198 /* TODO: needs to confirm */ 199 #if 0 200 case AMDGPU_UCODE_ID_SMC: 201 *sram_offset = 0; 202 *sram_addr_reg_offset = 0; 203 *sram_data_reg_offset = 0; 204 break; 205 #endif 206 207 case AMDGPU_UCODE_ID_CP_CE: 208 *sram_offset = 0x0; 209 *sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_CE_UCODE_ADDR); 210 *sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_CE_UCODE_DATA); 211 break; 212 213 case AMDGPU_UCODE_ID_CP_PFP: 214 *sram_offset = 0x0; 215 *sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_PFP_UCODE_ADDR); 216 *sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_PFP_UCODE_DATA); 217 break; 218 219 case AMDGPU_UCODE_ID_CP_ME: 220 *sram_offset = 0x0; 221 *sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_ME_UCODE_ADDR); 222 *sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_ME_UCODE_DATA); 223 break; 224 225 case AMDGPU_UCODE_ID_CP_MEC1: 226 *sram_offset = 0x10000; 227 *sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_MEC_ME1_UCODE_ADDR); 228 *sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_MEC_ME1_UCODE_DATA); 229 break; 230 231 case AMDGPU_UCODE_ID_CP_MEC2: 232 *sram_offset = 0x10000; 233 *sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_MEC2_UCODE_ADDR); 234 *sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_MEC2_UCODE_DATA); 235 break; 236 237 case AMDGPU_UCODE_ID_RLC_G: 238 *sram_offset = 0x2000; 239 *sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_UCODE_ADDR); 240 *sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_UCODE_DATA); 241 break; 242 243 case AMDGPU_UCODE_ID_SDMA0: 244 *sram_offset = 0x0; 245 *sram_addr_reg_offset = SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_UCODE_ADDR); 246 *sram_data_reg_offset = SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_UCODE_DATA); 247 break; 248 249 /* TODO: needs to confirm */ 250 #if 0 251 case AMDGPU_UCODE_ID_SDMA1: 252 *sram_offset = ; 253 *sram_addr_reg_offset = ; 254 break; 255 256 case AMDGPU_UCODE_ID_UVD: 257 *sram_offset = ; 258 *sram_addr_reg_offset = ; 259 break; 260 261 case AMDGPU_UCODE_ID_VCE: 262 *sram_offset = ; 263 *sram_addr_reg_offset = ; 264 break; 265 #endif 266 267 case AMDGPU_UCODE_ID_MAXIMUM: 268 default: 269 ret = -EINVAL; 270 break; 271 } 272 273 return ret; 274 } 275 276 bool psp_v10_0_compare_sram_data(struct psp_context *psp, 277 struct amdgpu_firmware_info *ucode, 278 enum AMDGPU_UCODE_ID ucode_type) 279 { 280 int err = 0; 281 unsigned int fw_sram_reg_val = 0; 282 unsigned int fw_sram_addr_reg_offset = 0; 283 unsigned int fw_sram_data_reg_offset = 0; 284 unsigned int ucode_size; 285 uint32_t *ucode_mem = NULL; 286 struct amdgpu_device *adev = psp->adev; 287 288 err = psp_v10_0_sram_map(&fw_sram_reg_val, &fw_sram_addr_reg_offset, 289 &fw_sram_data_reg_offset, ucode_type); 290 if (err) 291 return false; 292 293 WREG32(fw_sram_addr_reg_offset, fw_sram_reg_val); 294 295 ucode_size = ucode->ucode_size; 296 ucode_mem = (uint32_t *)ucode->kaddr; 297 while (!ucode_size) { 298 fw_sram_reg_val = RREG32(fw_sram_data_reg_offset); 299 300 if (*ucode_mem != fw_sram_reg_val) 301 return false; 302 303 ucode_mem++; 304 /* 4 bytes */ 305 ucode_size -= 4; 306 } 307 308 return true; 309 } 310