2 * Copyright 2016 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
26 #include <linux/firmware.h>
28 #include "amdgpu_psp.h"
29 #include "amdgpu_ucode.h"
30 #include "soc15_common.h"
31 #include "psp_v10_0.h"
33 #include "vega10/soc15ip.h"
34 #include "raven1/MP/mp_10_0_offset.h"
35 #include "raven1/GC/gc_9_1_offset.h"
36 #include "raven1/SDMA0/sdma0_4_1_offset.h"
39 psp_v10_0_get_fw_type(struct amdgpu_firmware_info
*ucode
, enum psp_gfx_fw_type
*type
)
41 switch(ucode
->ucode_id
) {
42 case AMDGPU_UCODE_ID_SDMA0
:
43 *type
= GFX_FW_TYPE_SDMA0
;
45 case AMDGPU_UCODE_ID_SDMA1
:
46 *type
= GFX_FW_TYPE_SDMA1
;
48 case AMDGPU_UCODE_ID_CP_CE
:
49 *type
= GFX_FW_TYPE_CP_CE
;
51 case AMDGPU_UCODE_ID_CP_PFP
:
52 *type
= GFX_FW_TYPE_CP_PFP
;
54 case AMDGPU_UCODE_ID_CP_ME
:
55 *type
= GFX_FW_TYPE_CP_ME
;
57 case AMDGPU_UCODE_ID_CP_MEC1
:
58 *type
= GFX_FW_TYPE_CP_MEC
;
60 case AMDGPU_UCODE_ID_CP_MEC1_JT
:
61 *type
= GFX_FW_TYPE_CP_MEC_ME1
;
63 case AMDGPU_UCODE_ID_CP_MEC2
:
64 *type
= GFX_FW_TYPE_CP_MEC
;
66 case AMDGPU_UCODE_ID_CP_MEC2_JT
:
67 *type
= GFX_FW_TYPE_CP_MEC_ME2
;
69 case AMDGPU_UCODE_ID_RLC_G
:
70 *type
= GFX_FW_TYPE_RLC_G
;
72 case AMDGPU_UCODE_ID_SMC
:
73 *type
= GFX_FW_TYPE_SMU
;
75 case AMDGPU_UCODE_ID_UVD
:
76 *type
= GFX_FW_TYPE_UVD
;
78 case AMDGPU_UCODE_ID_VCE
:
79 *type
= GFX_FW_TYPE_VCE
;
81 case AMDGPU_UCODE_ID_MAXIMUM
:
89 int psp_v10_0_init_microcode(struct psp_context
*psp
)
91 struct amdgpu_device
*adev
= psp
->adev
;
92 const char *chip_name
;
95 const struct psp_firmware_header_v1_0
*hdr
;
99 switch (adev
->asic_type
) {
106 snprintf(fw_name
, sizeof(fw_name
), "amdgpu/%s_asd.bin", chip_name
);
107 err
= request_firmware(&adev
->psp
.asd_fw
, fw_name
, adev
->dev
);
111 err
= amdgpu_ucode_validate(adev
->psp
.asd_fw
);
115 hdr
= (const struct psp_firmware_header_v1_0
*)adev
->psp
.asd_fw
->data
;
116 adev
->psp
.asd_fw_version
= le32_to_cpu(hdr
->header
.ucode_version
);
117 adev
->psp
.asd_feature_version
= le32_to_cpu(hdr
->ucode_feature_version
);
118 adev
->psp
.asd_ucode_size
= le32_to_cpu(hdr
->header
.ucode_size_bytes
);
119 adev
->psp
.asd_start_addr
= (uint8_t *)hdr
+
120 le32_to_cpu(hdr
->header
.ucode_array_offset_bytes
);
126 "psp v10.0: Failed to load firmware \"%s\"\n",
128 release_firmware(adev
->psp
.asd_fw
);
129 adev
->psp
.asd_fw
= NULL
;
135 int psp_v10_0_prep_cmd_buf(struct amdgpu_firmware_info
*ucode
, struct psp_gfx_cmd_resp
*cmd
)
138 uint64_t fw_mem_mc_addr
= ucode
->mc_addr
;
139 struct common_firmware_header
*header
;
141 memset(cmd
, 0, sizeof(struct psp_gfx_cmd_resp
));
142 header
= (struct common_firmware_header
*)ucode
->fw
;
144 cmd
->cmd_id
= GFX_CMD_ID_LOAD_IP_FW
;
145 cmd
->cmd
.cmd_load_ip_fw
.fw_phy_addr_lo
= lower_32_bits(fw_mem_mc_addr
);
146 cmd
->cmd
.cmd_load_ip_fw
.fw_phy_addr_hi
= upper_32_bits(fw_mem_mc_addr
);
147 cmd
->cmd
.cmd_load_ip_fw
.fw_size
= le32_to_cpu(header
->ucode_size_bytes
);
149 ret
= psp_v10_0_get_fw_type(ucode
, &cmd
->cmd
.cmd_load_ip_fw
.fw_type
);
151 DRM_ERROR("Unknown firmware type\n");
156 int psp_v10_0_ring_init(struct psp_context
*psp
, enum psp_ring_type ring_type
)
159 struct psp_ring
*ring
;
160 struct amdgpu_device
*adev
= psp
->adev
;
162 ring
= &psp
->km_ring
;
164 ring
->ring_type
= ring_type
;
166 /* allocate 4k Page of Local Frame Buffer memory for ring */
167 ring
->ring_size
= 0x1000;
168 ret
= amdgpu_bo_create_kernel(adev
, ring
->ring_size
, PAGE_SIZE
,
169 AMDGPU_GEM_DOMAIN_VRAM
,
170 &adev
->firmware
.rbuf
,
171 &ring
->ring_mem_mc_addr
,
172 (void **)&ring
->ring_mem
);
181 int psp_v10_0_ring_create(struct psp_context
*psp
, enum psp_ring_type ring_type
)
184 unsigned int psp_ring_reg
= 0;
185 struct psp_ring
*ring
= &psp
->km_ring
;
186 struct amdgpu_device
*adev
= psp
->adev
;
188 /* Write low address of the ring to C2PMSG_69 */
189 psp_ring_reg
= lower_32_bits(ring
->ring_mem_mc_addr
);
190 WREG32_SOC15(MP0
, 0, mmMP0_SMN_C2PMSG_69
, psp_ring_reg
);
191 /* Write high address of the ring to C2PMSG_70 */
192 psp_ring_reg
= upper_32_bits(ring
->ring_mem_mc_addr
);
193 WREG32_SOC15(MP0
, 0, mmMP0_SMN_C2PMSG_70
, psp_ring_reg
);
194 /* Write size of ring to C2PMSG_71 */
195 psp_ring_reg
= ring
->ring_size
;
196 WREG32_SOC15(MP0
, 0, mmMP0_SMN_C2PMSG_71
, psp_ring_reg
);
197 /* Write the ring initialization command to C2PMSG_64 */
198 psp_ring_reg
= ring_type
;
199 psp_ring_reg
= psp_ring_reg
<< 16;
200 WREG32_SOC15(MP0
, 0, mmMP0_SMN_C2PMSG_64
, psp_ring_reg
);
202 /* There might be handshake issue with hardware which needs delay */
205 /* Wait for response flag (bit 31) in C2PMSG_64 */
206 ret
= psp_wait_for(psp
, SOC15_REG_OFFSET(MP0
, 0, mmMP0_SMN_C2PMSG_64
),
207 0x80000000, 0x8000FFFF, false);
212 int psp_v10_0_ring_destroy(struct psp_context
*psp
, enum psp_ring_type ring_type
)
215 struct psp_ring
*ring
;
216 unsigned int psp_ring_reg
= 0;
217 struct amdgpu_device
*adev
= psp
->adev
;
219 ring
= &psp
->km_ring
;
221 /* Write the ring destroy command to C2PMSG_64 */
222 psp_ring_reg
= 3 << 16;
223 WREG32_SOC15(MP0
, 0, mmMP0_SMN_C2PMSG_64
, psp_ring_reg
);
225 /* There might be handshake issue with hardware which needs delay */
228 /* Wait for response flag (bit 31) in C2PMSG_64 */
229 ret
= psp_wait_for(psp
, SOC15_REG_OFFSET(MP0
, 0, mmMP0_SMN_C2PMSG_64
),
230 0x80000000, 0x80000000, false);
232 amdgpu_bo_free_kernel(&adev
->firmware
.rbuf
,
233 &ring
->ring_mem_mc_addr
,
234 (void **)&ring
->ring_mem
);
239 int psp_v10_0_cmd_submit(struct psp_context
*psp
,
240 struct amdgpu_firmware_info
*ucode
,
241 uint64_t cmd_buf_mc_addr
, uint64_t fence_mc_addr
,
244 unsigned int psp_write_ptr_reg
= 0;
245 struct psp_gfx_rb_frame
* write_frame
= psp
->km_ring
.ring_mem
;
246 struct psp_ring
*ring
= &psp
->km_ring
;
247 struct amdgpu_device
*adev
= psp
->adev
;
249 /* KM (GPCOM) prepare write pointer */
250 psp_write_ptr_reg
= RREG32_SOC15(MP0
, 0, mmMP0_SMN_C2PMSG_67
);
252 /* Update KM RB frame pointer to new frame */
253 if ((psp_write_ptr_reg
% ring
->ring_size
) == 0)
254 write_frame
= ring
->ring_mem
;
256 write_frame
= ring
->ring_mem
+ (psp_write_ptr_reg
/ (sizeof(struct psp_gfx_rb_frame
) / 4));
258 /* Update KM RB frame */
259 write_frame
->cmd_buf_addr_hi
= upper_32_bits(cmd_buf_mc_addr
);
260 write_frame
->cmd_buf_addr_lo
= lower_32_bits(cmd_buf_mc_addr
);
261 write_frame
->fence_addr_hi
= upper_32_bits(fence_mc_addr
);
262 write_frame
->fence_addr_lo
= lower_32_bits(fence_mc_addr
);
263 write_frame
->fence_value
= index
;
265 /* Update the write Pointer in DWORDs */
266 psp_write_ptr_reg
+= sizeof(struct psp_gfx_rb_frame
) / 4;
267 psp_write_ptr_reg
= (psp_write_ptr_reg
>= ring
->ring_size
) ? 0 : psp_write_ptr_reg
;
268 WREG32_SOC15(MP0
, 0, mmMP0_SMN_C2PMSG_67
, psp_write_ptr_reg
);
274 psp_v10_0_sram_map(unsigned int *sram_offset
, unsigned int *sram_addr_reg_offset
,
275 unsigned int *sram_data_reg_offset
,
276 enum AMDGPU_UCODE_ID ucode_id
)
281 /* TODO: needs to confirm */
283 case AMDGPU_UCODE_ID_SMC
:
285 *sram_addr_reg_offset
= 0;
286 *sram_data_reg_offset
= 0;
290 case AMDGPU_UCODE_ID_CP_CE
:
292 *sram_addr_reg_offset
= SOC15_REG_OFFSET(GC
, 0, mmCP_CE_UCODE_ADDR
);
293 *sram_data_reg_offset
= SOC15_REG_OFFSET(GC
, 0, mmCP_CE_UCODE_DATA
);
296 case AMDGPU_UCODE_ID_CP_PFP
:
298 *sram_addr_reg_offset
= SOC15_REG_OFFSET(GC
, 0, mmCP_PFP_UCODE_ADDR
);
299 *sram_data_reg_offset
= SOC15_REG_OFFSET(GC
, 0, mmCP_PFP_UCODE_DATA
);
302 case AMDGPU_UCODE_ID_CP_ME
:
304 *sram_addr_reg_offset
= SOC15_REG_OFFSET(GC
, 0, mmCP_HYP_ME_UCODE_ADDR
);
305 *sram_data_reg_offset
= SOC15_REG_OFFSET(GC
, 0, mmCP_HYP_ME_UCODE_DATA
);
308 case AMDGPU_UCODE_ID_CP_MEC1
:
309 *sram_offset
= 0x10000;
310 *sram_addr_reg_offset
= SOC15_REG_OFFSET(GC
, 0, mmCP_MEC_ME1_UCODE_ADDR
);
311 *sram_data_reg_offset
= SOC15_REG_OFFSET(GC
, 0, mmCP_MEC_ME1_UCODE_DATA
);
314 case AMDGPU_UCODE_ID_CP_MEC2
:
315 *sram_offset
= 0x10000;
316 *sram_addr_reg_offset
= SOC15_REG_OFFSET(GC
, 0, mmCP_HYP_MEC2_UCODE_ADDR
);
317 *sram_data_reg_offset
= SOC15_REG_OFFSET(GC
, 0, mmCP_HYP_MEC2_UCODE_DATA
);
320 case AMDGPU_UCODE_ID_RLC_G
:
321 *sram_offset
= 0x2000;
322 *sram_addr_reg_offset
= SOC15_REG_OFFSET(GC
, 0, mmRLC_GPM_UCODE_ADDR
);
323 *sram_data_reg_offset
= SOC15_REG_OFFSET(GC
, 0, mmRLC_GPM_UCODE_DATA
);
326 case AMDGPU_UCODE_ID_SDMA0
:
328 *sram_addr_reg_offset
= SOC15_REG_OFFSET(SDMA0
, 0, mmSDMA0_UCODE_ADDR
);
329 *sram_data_reg_offset
= SOC15_REG_OFFSET(SDMA0
, 0, mmSDMA0_UCODE_DATA
);
332 /* TODO: needs to confirm */
334 case AMDGPU_UCODE_ID_SDMA1
:
336 *sram_addr_reg_offset
= ;
339 case AMDGPU_UCODE_ID_UVD
:
341 *sram_addr_reg_offset
= ;
344 case AMDGPU_UCODE_ID_VCE
:
346 *sram_addr_reg_offset
= ;
350 case AMDGPU_UCODE_ID_MAXIMUM
:
359 bool psp_v10_0_compare_sram_data(struct psp_context
*psp
,
360 struct amdgpu_firmware_info
*ucode
,
361 enum AMDGPU_UCODE_ID ucode_type
)
364 unsigned int fw_sram_reg_val
= 0;
365 unsigned int fw_sram_addr_reg_offset
= 0;
366 unsigned int fw_sram_data_reg_offset
= 0;
367 unsigned int ucode_size
;
368 uint32_t *ucode_mem
= NULL
;
369 struct amdgpu_device
*adev
= psp
->adev
;
371 err
= psp_v10_0_sram_map(&fw_sram_reg_val
, &fw_sram_addr_reg_offset
,
372 &fw_sram_data_reg_offset
, ucode_type
);
376 WREG32(fw_sram_addr_reg_offset
, fw_sram_reg_val
);
378 ucode_size
= ucode
->ucode_size
;
379 ucode_mem
= (uint32_t *)ucode
->kaddr
;
380 while (!ucode_size
) {
381 fw_sram_reg_val
= RREG32(fw_sram_data_reg_offset
);
383 if (*ucode_mem
!= fw_sram_reg_val
)