1 | /* |
2 | * Copyright 2020 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 | #include <drm/drm_drv.h> |
24 | #include <linux/vmalloc.h> |
25 | #include "amdgpu.h" |
26 | #include "amdgpu_psp.h" |
27 | #include "amdgpu_ucode.h" |
28 | #include "soc15_common.h" |
29 | #include "psp_v13_0.h" |
30 | #include "amdgpu_ras.h" |
31 | |
32 | #include "mp/mp_13_0_2_offset.h" |
33 | #include "mp/mp_13_0_2_sh_mask.h" |
34 | |
35 | MODULE_FIRMWARE("amdgpu/aldebaran_sos.bin" ); |
36 | MODULE_FIRMWARE("amdgpu/aldebaran_ta.bin" ); |
37 | MODULE_FIRMWARE("amdgpu/aldebaran_cap.bin" ); |
38 | MODULE_FIRMWARE("amdgpu/yellow_carp_toc.bin" ); |
39 | MODULE_FIRMWARE("amdgpu/yellow_carp_ta.bin" ); |
40 | MODULE_FIRMWARE("amdgpu/psp_13_0_5_toc.bin" ); |
41 | MODULE_FIRMWARE("amdgpu/psp_13_0_5_ta.bin" ); |
42 | MODULE_FIRMWARE("amdgpu/psp_13_0_8_toc.bin" ); |
43 | MODULE_FIRMWARE("amdgpu/psp_13_0_8_ta.bin" ); |
44 | MODULE_FIRMWARE("amdgpu/psp_13_0_0_sos.bin" ); |
45 | MODULE_FIRMWARE("amdgpu/psp_13_0_0_ta.bin" ); |
46 | MODULE_FIRMWARE("amdgpu/psp_13_0_7_sos.bin" ); |
47 | MODULE_FIRMWARE("amdgpu/psp_13_0_7_ta.bin" ); |
48 | MODULE_FIRMWARE("amdgpu/psp_13_0_10_sos.bin" ); |
49 | MODULE_FIRMWARE("amdgpu/psp_13_0_10_ta.bin" ); |
50 | MODULE_FIRMWARE("amdgpu/psp_13_0_11_toc.bin" ); |
51 | MODULE_FIRMWARE("amdgpu/psp_13_0_11_ta.bin" ); |
52 | MODULE_FIRMWARE("amdgpu/psp_13_0_6_sos.bin" ); |
53 | MODULE_FIRMWARE("amdgpu/psp_13_0_6_ta.bin" ); |
54 | MODULE_FIRMWARE("amdgpu/psp_14_0_0_toc.bin" ); |
55 | MODULE_FIRMWARE("amdgpu/psp_14_0_0_ta.bin" ); |
56 | MODULE_FIRMWARE("amdgpu/psp_14_0_1_toc.bin" ); |
57 | MODULE_FIRMWARE("amdgpu/psp_14_0_1_ta.bin" ); |
58 | |
59 | /* For large FW files the time to complete can be very long */ |
60 | #define USBC_PD_POLLING_LIMIT_S 240 |
61 | |
62 | /* Read USB-PD from LFB */ |
63 | #define GFX_CMD_USB_PD_USE_LFB 0x480 |
64 | |
65 | /* Retry times for vmbx ready wait */ |
66 | #define PSP_VMBX_POLLING_LIMIT 3000 |
67 | |
68 | /* VBIOS gfl defines */ |
69 | #define MBOX_READY_MASK 0x80000000 |
70 | #define MBOX_STATUS_MASK 0x0000FFFF |
71 | #define MBOX_COMMAND_MASK 0x00FF0000 |
72 | #define MBOX_READY_FLAG 0x80000000 |
73 | #define C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_LO 0x2 |
74 | #define C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_HI 0x3 |
75 | #define C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE 0x4 |
76 | |
77 | /* memory training timeout define */ |
78 | #define MEM_TRAIN_SEND_MSG_TIMEOUT_US 3000000 |
79 | |
80 | static int psp_v13_0_init_microcode(struct psp_context *psp) |
81 | { |
82 | struct amdgpu_device *adev = psp->adev; |
83 | char ucode_prefix[30]; |
84 | int err = 0; |
85 | |
86 | amdgpu_ucode_ip_version_decode(adev, block_type: MP0_HWIP, ucode_prefix, len: sizeof(ucode_prefix)); |
87 | |
88 | switch (amdgpu_ip_version(adev, ip: MP0_HWIP, inst: 0)) { |
89 | case IP_VERSION(13, 0, 2): |
90 | err = psp_init_sos_microcode(psp, chip_name: ucode_prefix); |
91 | if (err) |
92 | return err; |
93 | /* It's not necessary to load ras ta on Guest side */ |
94 | if (!amdgpu_sriov_vf(adev)) { |
95 | err = psp_init_ta_microcode(psp, chip_name: ucode_prefix); |
96 | if (err) |
97 | return err; |
98 | } |
99 | break; |
100 | case IP_VERSION(13, 0, 1): |
101 | case IP_VERSION(13, 0, 3): |
102 | case IP_VERSION(13, 0, 5): |
103 | case IP_VERSION(13, 0, 8): |
104 | case IP_VERSION(13, 0, 11): |
105 | case IP_VERSION(14, 0, 0): |
106 | case IP_VERSION(14, 0, 1): |
107 | err = psp_init_toc_microcode(psp, chip_name: ucode_prefix); |
108 | if (err) |
109 | return err; |
110 | err = psp_init_ta_microcode(psp, chip_name: ucode_prefix); |
111 | if (err) |
112 | return err; |
113 | break; |
114 | case IP_VERSION(13, 0, 0): |
115 | case IP_VERSION(13, 0, 6): |
116 | case IP_VERSION(13, 0, 7): |
117 | case IP_VERSION(13, 0, 10): |
118 | err = psp_init_sos_microcode(psp, chip_name: ucode_prefix); |
119 | if (err) |
120 | return err; |
121 | /* It's not necessary to load ras ta on Guest side */ |
122 | err = psp_init_ta_microcode(psp, chip_name: ucode_prefix); |
123 | if (err) |
124 | return err; |
125 | break; |
126 | default: |
127 | BUG(); |
128 | } |
129 | |
130 | return 0; |
131 | } |
132 | |
133 | static bool psp_v13_0_is_sos_alive(struct psp_context *psp) |
134 | { |
135 | struct amdgpu_device *adev = psp->adev; |
136 | uint32_t sol_reg; |
137 | |
138 | sol_reg = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_81); |
139 | |
140 | return sol_reg != 0x0; |
141 | } |
142 | |
143 | static int psp_v13_0_wait_for_vmbx_ready(struct psp_context *psp) |
144 | { |
145 | struct amdgpu_device *adev = psp->adev; |
146 | int retry_loop, ret; |
147 | |
148 | for (retry_loop = 0; retry_loop < PSP_VMBX_POLLING_LIMIT; retry_loop++) { |
149 | /* Wait for bootloader to signify that is |
150 | ready having bit 31 of C2PMSG_33 set to 1 */ |
151 | ret = psp_wait_for( |
152 | psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_33), |
153 | field_val: 0x80000000, mask: 0xffffffff, check_changed: false); |
154 | |
155 | if (ret == 0) |
156 | break; |
157 | } |
158 | |
159 | if (ret) |
160 | dev_warn(adev->dev, "Bootloader wait timed out" ); |
161 | |
162 | return ret; |
163 | } |
164 | |
165 | static int psp_v13_0_wait_for_bootloader(struct psp_context *psp) |
166 | { |
167 | struct amdgpu_device *adev = psp->adev; |
168 | int retry_loop, retry_cnt, ret; |
169 | |
170 | retry_cnt = |
171 | (amdgpu_ip_version(adev, ip: MP0_HWIP, inst: 0) == IP_VERSION(13, 0, 6)) ? |
172 | PSP_VMBX_POLLING_LIMIT : |
173 | 10; |
174 | /* Wait for bootloader to signify that it is ready having bit 31 of |
175 | * C2PMSG_35 set to 1. All other bits are expected to be cleared. |
176 | * If there is an error in processing command, bits[7:0] will be set. |
177 | * This is applicable for PSP v13.0.6 and newer. |
178 | */ |
179 | for (retry_loop = 0; retry_loop < retry_cnt; retry_loop++) { |
180 | ret = psp_wait_for( |
181 | psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_35), |
182 | field_val: 0x80000000, mask: 0xffffffff, check_changed: false); |
183 | |
184 | if (ret == 0) |
185 | return 0; |
186 | } |
187 | |
188 | return ret; |
189 | } |
190 | |
191 | static int psp_v13_0_wait_for_bootloader_steady_state(struct psp_context *psp) |
192 | { |
193 | struct amdgpu_device *adev = psp->adev; |
194 | int ret; |
195 | |
196 | if (amdgpu_ip_version(adev, ip: MP0_HWIP, inst: 0) == IP_VERSION(13, 0, 6)) { |
197 | ret = psp_v13_0_wait_for_vmbx_ready(psp); |
198 | if (ret) |
199 | amdgpu_ras_query_boot_status(adev, num_instances: 4); |
200 | |
201 | ret = psp_v13_0_wait_for_bootloader(psp); |
202 | if (ret) |
203 | amdgpu_ras_query_boot_status(adev, num_instances: 4); |
204 | |
205 | return ret; |
206 | } |
207 | |
208 | return 0; |
209 | } |
210 | |
211 | static int psp_v13_0_bootloader_load_component(struct psp_context *psp, |
212 | struct psp_bin_desc *bin_desc, |
213 | enum psp_bootloader_cmd bl_cmd) |
214 | { |
215 | int ret; |
216 | uint32_t psp_gfxdrv_command_reg = 0; |
217 | struct amdgpu_device *adev = psp->adev; |
218 | |
219 | /* Check tOS sign of life register to confirm sys driver and sOS |
220 | * are already been loaded. |
221 | */ |
222 | if (psp_v13_0_is_sos_alive(psp)) |
223 | return 0; |
224 | |
225 | ret = psp_v13_0_wait_for_bootloader(psp); |
226 | if (ret) |
227 | return ret; |
228 | |
229 | memset(psp->fw_pri_buf, 0, PSP_1_MEG); |
230 | |
231 | /* Copy PSP KDB binary to memory */ |
232 | memcpy(psp->fw_pri_buf, bin_desc->start_addr, bin_desc->size_bytes); |
233 | |
234 | /* Provide the PSP KDB to bootloader */ |
235 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_36, |
236 | (uint32_t)(psp->fw_pri_mc_addr >> 20)); |
237 | psp_gfxdrv_command_reg = bl_cmd; |
238 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_35, |
239 | psp_gfxdrv_command_reg); |
240 | |
241 | ret = psp_v13_0_wait_for_bootloader(psp); |
242 | |
243 | return ret; |
244 | } |
245 | |
246 | static int psp_v13_0_bootloader_load_kdb(struct psp_context *psp) |
247 | { |
248 | return psp_v13_0_bootloader_load_component(psp, bin_desc: &psp->kdb, bl_cmd: PSP_BL__LOAD_KEY_DATABASE); |
249 | } |
250 | |
251 | static int psp_v13_0_bootloader_load_spl(struct psp_context *psp) |
252 | { |
253 | return psp_v13_0_bootloader_load_component(psp, bin_desc: &psp->kdb, bl_cmd: PSP_BL__LOAD_TOS_SPL_TABLE); |
254 | } |
255 | |
256 | static int psp_v13_0_bootloader_load_sysdrv(struct psp_context *psp) |
257 | { |
258 | return psp_v13_0_bootloader_load_component(psp, bin_desc: &psp->sys, bl_cmd: PSP_BL__LOAD_SYSDRV); |
259 | } |
260 | |
261 | static int psp_v13_0_bootloader_load_soc_drv(struct psp_context *psp) |
262 | { |
263 | return psp_v13_0_bootloader_load_component(psp, bin_desc: &psp->soc_drv, bl_cmd: PSP_BL__LOAD_SOCDRV); |
264 | } |
265 | |
266 | static int psp_v13_0_bootloader_load_intf_drv(struct psp_context *psp) |
267 | { |
268 | return psp_v13_0_bootloader_load_component(psp, bin_desc: &psp->intf_drv, bl_cmd: PSP_BL__LOAD_INTFDRV); |
269 | } |
270 | |
271 | static int psp_v13_0_bootloader_load_dbg_drv(struct psp_context *psp) |
272 | { |
273 | return psp_v13_0_bootloader_load_component(psp, bin_desc: &psp->dbg_drv, bl_cmd: PSP_BL__LOAD_DBGDRV); |
274 | } |
275 | |
276 | static int psp_v13_0_bootloader_load_ras_drv(struct psp_context *psp) |
277 | { |
278 | return psp_v13_0_bootloader_load_component(psp, bin_desc: &psp->ras_drv, bl_cmd: PSP_BL__LOAD_RASDRV); |
279 | } |
280 | |
281 | static inline void psp_v13_0_init_sos_version(struct psp_context *psp) |
282 | { |
283 | struct amdgpu_device *adev = psp->adev; |
284 | |
285 | psp->sos.fw_version = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_58); |
286 | } |
287 | |
288 | static int psp_v13_0_bootloader_load_sos(struct psp_context *psp) |
289 | { |
290 | int ret; |
291 | unsigned int psp_gfxdrv_command_reg = 0; |
292 | struct amdgpu_device *adev = psp->adev; |
293 | |
294 | /* Check sOS sign of life register to confirm sys driver and sOS |
295 | * are already been loaded. |
296 | */ |
297 | if (psp_v13_0_is_sos_alive(psp)) { |
298 | psp_v13_0_init_sos_version(psp); |
299 | return 0; |
300 | } |
301 | |
302 | ret = psp_v13_0_wait_for_bootloader(psp); |
303 | if (ret) |
304 | return ret; |
305 | |
306 | memset(psp->fw_pri_buf, 0, PSP_1_MEG); |
307 | |
308 | /* Copy Secure OS binary to PSP memory */ |
309 | memcpy(psp->fw_pri_buf, psp->sos.start_addr, psp->sos.size_bytes); |
310 | |
311 | /* Provide the PSP secure OS to bootloader */ |
312 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_36, |
313 | (uint32_t)(psp->fw_pri_mc_addr >> 20)); |
314 | psp_gfxdrv_command_reg = PSP_BL__LOAD_SOSDRV; |
315 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_35, |
316 | psp_gfxdrv_command_reg); |
317 | |
318 | /* there might be handshake issue with hardware which needs delay */ |
319 | mdelay(20); |
320 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_81), |
321 | RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_81), |
322 | mask: 0, check_changed: true); |
323 | |
324 | if (!ret) |
325 | psp_v13_0_init_sos_version(psp); |
326 | |
327 | return ret; |
328 | } |
329 | |
330 | static int psp_v13_0_ring_stop(struct psp_context *psp, |
331 | enum psp_ring_type ring_type) |
332 | { |
333 | int ret = 0; |
334 | struct amdgpu_device *adev = psp->adev; |
335 | |
336 | if (amdgpu_sriov_vf(adev)) { |
337 | /* Write the ring destroy command*/ |
338 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_101, |
339 | GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING); |
340 | /* there might be handshake issue with hardware which needs delay */ |
341 | mdelay(20); |
342 | /* Wait for response flag (bit 31) */ |
343 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_101), |
344 | field_val: 0x80000000, mask: 0x80000000, check_changed: false); |
345 | } else { |
346 | /* Write the ring destroy command*/ |
347 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_64, |
348 | GFX_CTRL_CMD_ID_DESTROY_RINGS); |
349 | /* there might be handshake issue with hardware which needs delay */ |
350 | mdelay(20); |
351 | /* Wait for response flag (bit 31) */ |
352 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_64), |
353 | field_val: 0x80000000, mask: 0x80000000, check_changed: false); |
354 | } |
355 | |
356 | return ret; |
357 | } |
358 | |
359 | static int psp_v13_0_ring_create(struct psp_context *psp, |
360 | enum psp_ring_type ring_type) |
361 | { |
362 | int ret = 0; |
363 | unsigned int psp_ring_reg = 0; |
364 | struct psp_ring *ring = &psp->km_ring; |
365 | struct amdgpu_device *adev = psp->adev; |
366 | |
367 | if (amdgpu_sriov_vf(adev)) { |
368 | ret = psp_v13_0_ring_stop(psp, ring_type); |
369 | if (ret) { |
370 | DRM_ERROR("psp_v13_0_ring_stop_sriov failed!\n" ); |
371 | return ret; |
372 | } |
373 | |
374 | /* Write low address of the ring to C2PMSG_102 */ |
375 | psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr); |
376 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_102, psp_ring_reg); |
377 | /* Write high address of the ring to C2PMSG_103 */ |
378 | psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr); |
379 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_103, psp_ring_reg); |
380 | |
381 | /* Write the ring initialization command to C2PMSG_101 */ |
382 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_101, |
383 | GFX_CTRL_CMD_ID_INIT_GPCOM_RING); |
384 | |
385 | /* there might be handshake issue with hardware which needs delay */ |
386 | mdelay(20); |
387 | |
388 | /* Wait for response flag (bit 31) in C2PMSG_101 */ |
389 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_101), |
390 | field_val: 0x80000000, mask: 0x8000FFFF, check_changed: false); |
391 | |
392 | } else { |
393 | /* Wait for sOS ready for ring creation */ |
394 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_64), |
395 | field_val: 0x80000000, mask: 0x80000000, check_changed: false); |
396 | if (ret) { |
397 | DRM_ERROR("Failed to wait for trust OS ready for ring creation\n" ); |
398 | return ret; |
399 | } |
400 | |
401 | /* Write low address of the ring to C2PMSG_69 */ |
402 | psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr); |
403 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_69, psp_ring_reg); |
404 | /* Write high address of the ring to C2PMSG_70 */ |
405 | psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr); |
406 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_70, psp_ring_reg); |
407 | /* Write size of ring to C2PMSG_71 */ |
408 | psp_ring_reg = ring->ring_size; |
409 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_71, psp_ring_reg); |
410 | /* Write the ring initialization command to C2PMSG_64 */ |
411 | psp_ring_reg = ring_type; |
412 | psp_ring_reg = psp_ring_reg << 16; |
413 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_64, psp_ring_reg); |
414 | |
415 | /* there might be handshake issue with hardware which needs delay */ |
416 | mdelay(20); |
417 | |
418 | /* Wait for response flag (bit 31) in C2PMSG_64 */ |
419 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_64), |
420 | field_val: 0x80000000, mask: 0x8000FFFF, check_changed: false); |
421 | } |
422 | |
423 | return ret; |
424 | } |
425 | |
426 | static int psp_v13_0_ring_destroy(struct psp_context *psp, |
427 | enum psp_ring_type ring_type) |
428 | { |
429 | int ret = 0; |
430 | struct psp_ring *ring = &psp->km_ring; |
431 | struct amdgpu_device *adev = psp->adev; |
432 | |
433 | ret = psp_v13_0_ring_stop(psp, ring_type); |
434 | if (ret) |
435 | DRM_ERROR("Fail to stop psp ring\n" ); |
436 | |
437 | amdgpu_bo_free_kernel(bo: &adev->firmware.rbuf, |
438 | gpu_addr: &ring->ring_mem_mc_addr, |
439 | cpu_addr: (void **)&ring->ring_mem); |
440 | |
441 | return ret; |
442 | } |
443 | |
444 | static uint32_t psp_v13_0_ring_get_wptr(struct psp_context *psp) |
445 | { |
446 | uint32_t data; |
447 | struct amdgpu_device *adev = psp->adev; |
448 | |
449 | if (amdgpu_sriov_vf(adev)) |
450 | data = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_102); |
451 | else |
452 | data = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_67); |
453 | |
454 | return data; |
455 | } |
456 | |
457 | static void psp_v13_0_ring_set_wptr(struct psp_context *psp, uint32_t value) |
458 | { |
459 | struct amdgpu_device *adev = psp->adev; |
460 | |
461 | if (amdgpu_sriov_vf(adev)) { |
462 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_102, value); |
463 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_101, |
464 | GFX_CTRL_CMD_ID_CONSUME_CMD); |
465 | } else |
466 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_67, value); |
467 | } |
468 | |
469 | static int psp_v13_0_memory_training_send_msg(struct psp_context *psp, int msg) |
470 | { |
471 | int ret; |
472 | int i; |
473 | uint32_t data_32; |
474 | int max_wait; |
475 | struct amdgpu_device *adev = psp->adev; |
476 | |
477 | data_32 = (psp->mem_train_ctx.c2p_train_data_offset >> 20); |
478 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_36, data_32); |
479 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_35, msg); |
480 | |
481 | max_wait = MEM_TRAIN_SEND_MSG_TIMEOUT_US / adev->usec_timeout; |
482 | for (i = 0; i < max_wait; i++) { |
483 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_35), |
484 | field_val: 0x80000000, mask: 0x80000000, check_changed: false); |
485 | if (ret == 0) |
486 | break; |
487 | } |
488 | if (i < max_wait) |
489 | ret = 0; |
490 | else |
491 | ret = -ETIME; |
492 | |
493 | dev_dbg(adev->dev, "training %s %s, cost %d @ %d ms\n" , |
494 | (msg == PSP_BL__DRAM_SHORT_TRAIN) ? "short" : "long" , |
495 | (ret == 0) ? "succeed" : "failed" , |
496 | i, adev->usec_timeout/1000); |
497 | return ret; |
498 | } |
499 | |
500 | |
501 | static int psp_v13_0_memory_training(struct psp_context *psp, uint32_t ops) |
502 | { |
503 | struct psp_memory_training_context *ctx = &psp->mem_train_ctx; |
504 | uint32_t *pcache = (uint32_t *)ctx->sys_cache; |
505 | struct amdgpu_device *adev = psp->adev; |
506 | uint32_t [4]; |
507 | uint32_t sz; |
508 | void *buf; |
509 | int ret, idx; |
510 | |
511 | if (ctx->init == PSP_MEM_TRAIN_NOT_SUPPORT) { |
512 | dev_dbg(adev->dev, "Memory training is not supported.\n" ); |
513 | return 0; |
514 | } else if (ctx->init != PSP_MEM_TRAIN_INIT_SUCCESS) { |
515 | dev_err(adev->dev, "Memory training initialization failure.\n" ); |
516 | return -EINVAL; |
517 | } |
518 | |
519 | if (psp_v13_0_is_sos_alive(psp)) { |
520 | dev_dbg(adev->dev, "SOS is alive, skip memory training.\n" ); |
521 | return 0; |
522 | } |
523 | |
524 | amdgpu_device_vram_access(adev, pos: ctx->p2c_train_data_offset, buf: p2c_header, size: sizeof(p2c_header), write: false); |
525 | dev_dbg(adev->dev, "sys_cache[%08x,%08x,%08x,%08x] p2c_header[%08x,%08x,%08x,%08x]\n" , |
526 | pcache[0], pcache[1], pcache[2], pcache[3], |
527 | p2c_header[0], p2c_header[1], p2c_header[2], p2c_header[3]); |
528 | |
529 | if (ops & PSP_MEM_TRAIN_SEND_SHORT_MSG) { |
530 | dev_dbg(adev->dev, "Short training depends on restore.\n" ); |
531 | ops |= PSP_MEM_TRAIN_RESTORE; |
532 | } |
533 | |
534 | if ((ops & PSP_MEM_TRAIN_RESTORE) && |
535 | pcache[0] != MEM_TRAIN_SYSTEM_SIGNATURE) { |
536 | dev_dbg(adev->dev, "sys_cache[0] is invalid, restore depends on save.\n" ); |
537 | ops |= PSP_MEM_TRAIN_SAVE; |
538 | } |
539 | |
540 | if (p2c_header[0] == MEM_TRAIN_SYSTEM_SIGNATURE && |
541 | !(pcache[0] == MEM_TRAIN_SYSTEM_SIGNATURE && |
542 | pcache[3] == p2c_header[3])) { |
543 | dev_dbg(adev->dev, "sys_cache is invalid or out-of-date, need save training data to sys_cache.\n" ); |
544 | ops |= PSP_MEM_TRAIN_SAVE; |
545 | } |
546 | |
547 | if ((ops & PSP_MEM_TRAIN_SAVE) && |
548 | p2c_header[0] != MEM_TRAIN_SYSTEM_SIGNATURE) { |
549 | dev_dbg(adev->dev, "p2c_header[0] is invalid, save depends on long training.\n" ); |
550 | ops |= PSP_MEM_TRAIN_SEND_LONG_MSG; |
551 | } |
552 | |
553 | if (ops & PSP_MEM_TRAIN_SEND_LONG_MSG) { |
554 | ops &= ~PSP_MEM_TRAIN_SEND_SHORT_MSG; |
555 | ops |= PSP_MEM_TRAIN_SAVE; |
556 | } |
557 | |
558 | dev_dbg(adev->dev, "Memory training ops:%x.\n" , ops); |
559 | |
560 | if (ops & PSP_MEM_TRAIN_SEND_LONG_MSG) { |
561 | /* |
562 | * Long training will encroach a certain amount on the bottom of VRAM; |
563 | * save the content from the bottom of VRAM to system memory |
564 | * before training, and restore it after training to avoid |
565 | * VRAM corruption. |
566 | */ |
567 | sz = BIST_MEM_TRAINING_ENCROACHED_SIZE; |
568 | |
569 | if (adev->gmc.visible_vram_size < sz || !adev->mman.aper_base_kaddr) { |
570 | dev_err(adev->dev, "visible_vram_size %llx or aper_base_kaddr %p is not initialized.\n" , |
571 | adev->gmc.visible_vram_size, |
572 | adev->mman.aper_base_kaddr); |
573 | return -EINVAL; |
574 | } |
575 | |
576 | buf = vmalloc(size: sz); |
577 | if (!buf) { |
578 | dev_err(adev->dev, "failed to allocate system memory.\n" ); |
579 | return -ENOMEM; |
580 | } |
581 | |
582 | if (drm_dev_enter(dev: adev_to_drm(adev), idx: &idx)) { |
583 | memcpy_fromio(buf, adev->mman.aper_base_kaddr, sz); |
584 | ret = psp_v13_0_memory_training_send_msg(psp, msg: PSP_BL__DRAM_LONG_TRAIN); |
585 | if (ret) { |
586 | DRM_ERROR("Send long training msg failed.\n" ); |
587 | vfree(addr: buf); |
588 | drm_dev_exit(idx); |
589 | return ret; |
590 | } |
591 | |
592 | memcpy_toio(adev->mman.aper_base_kaddr, buf, sz); |
593 | adev->hdp.funcs->flush_hdp(adev, NULL); |
594 | vfree(addr: buf); |
595 | drm_dev_exit(idx); |
596 | } else { |
597 | vfree(addr: buf); |
598 | return -ENODEV; |
599 | } |
600 | } |
601 | |
602 | if (ops & PSP_MEM_TRAIN_SAVE) { |
603 | amdgpu_device_vram_access(adev: psp->adev, pos: ctx->p2c_train_data_offset, buf: ctx->sys_cache, size: ctx->train_data_size, write: false); |
604 | } |
605 | |
606 | if (ops & PSP_MEM_TRAIN_RESTORE) { |
607 | amdgpu_device_vram_access(adev: psp->adev, pos: ctx->c2p_train_data_offset, buf: ctx->sys_cache, size: ctx->train_data_size, write: true); |
608 | } |
609 | |
610 | if (ops & PSP_MEM_TRAIN_SEND_SHORT_MSG) { |
611 | ret = psp_v13_0_memory_training_send_msg(psp, msg: (amdgpu_force_long_training > 0) ? |
612 | PSP_BL__DRAM_LONG_TRAIN : PSP_BL__DRAM_SHORT_TRAIN); |
613 | if (ret) { |
614 | dev_err(adev->dev, "send training msg failed.\n" ); |
615 | return ret; |
616 | } |
617 | } |
618 | ctx->training_cnt++; |
619 | return 0; |
620 | } |
621 | |
622 | static int psp_v13_0_load_usbc_pd_fw(struct psp_context *psp, uint64_t fw_pri_mc_addr) |
623 | { |
624 | struct amdgpu_device *adev = psp->adev; |
625 | uint32_t reg_status; |
626 | int ret, i = 0; |
627 | |
628 | /* |
629 | * LFB address which is aligned to 1MB address and has to be |
630 | * right-shifted by 20 so that LFB address can be passed on a 32-bit C2P |
631 | * register |
632 | */ |
633 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_36, (fw_pri_mc_addr >> 20)); |
634 | |
635 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_35), |
636 | field_val: 0x80000000, mask: 0x80000000, check_changed: false); |
637 | if (ret) |
638 | return ret; |
639 | |
640 | /* Fireup interrupt so PSP can pick up the address */ |
641 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_35, (GFX_CMD_USB_PD_USE_LFB << 16)); |
642 | |
643 | /* FW load takes very long time */ |
644 | do { |
645 | msleep(msecs: 1000); |
646 | reg_status = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_35); |
647 | |
648 | if (reg_status & 0x80000000) |
649 | goto done; |
650 | |
651 | } while (++i < USBC_PD_POLLING_LIMIT_S); |
652 | |
653 | return -ETIME; |
654 | done: |
655 | |
656 | if ((reg_status & 0xFFFF) != 0) { |
657 | DRM_ERROR("Address load failed - MP0_SMN_C2PMSG_35.Bits [15:0] = %04x\n" , |
658 | reg_status & 0xFFFF); |
659 | return -EIO; |
660 | } |
661 | |
662 | return 0; |
663 | } |
664 | |
665 | static int psp_v13_0_read_usbc_pd_fw(struct psp_context *psp, uint32_t *fw_ver) |
666 | { |
667 | struct amdgpu_device *adev = psp->adev; |
668 | int ret; |
669 | |
670 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_35, C2PMSG_CMD_GFX_USB_PD_FW_VER); |
671 | |
672 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_35), |
673 | field_val: 0x80000000, mask: 0x80000000, check_changed: false); |
674 | if (!ret) |
675 | *fw_ver = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_36); |
676 | |
677 | return ret; |
678 | } |
679 | |
680 | static int psp_v13_0_exec_spi_cmd(struct psp_context *psp, int cmd) |
681 | { |
682 | uint32_t reg_status = 0, reg_val = 0; |
683 | struct amdgpu_device *adev = psp->adev; |
684 | int ret; |
685 | |
686 | /* clear MBX ready (MBOX_READY_MASK bit is 0) and set update command */ |
687 | reg_val |= (cmd << 16); |
688 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_115, reg_val); |
689 | |
690 | /* Ring the doorbell */ |
691 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_73, 1); |
692 | |
693 | if (cmd == C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE) |
694 | ret = psp_wait_for_spirom_update(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_115), |
695 | MBOX_READY_FLAG, MBOX_READY_MASK, PSP_SPIROM_UPDATE_TIMEOUT); |
696 | else |
697 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_115), |
698 | MBOX_READY_FLAG, MBOX_READY_MASK, check_changed: false); |
699 | if (ret) { |
700 | dev_err(adev->dev, "SPI cmd %x timed out, ret = %d" , cmd, ret); |
701 | return ret; |
702 | } |
703 | |
704 | reg_status = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_115); |
705 | if ((reg_status & 0xFFFF) != 0) { |
706 | dev_err(adev->dev, "SPI cmd %x failed, fail status = %04x\n" , |
707 | cmd, reg_status & 0xFFFF); |
708 | return -EIO; |
709 | } |
710 | |
711 | return 0; |
712 | } |
713 | |
714 | static int psp_v13_0_update_spirom(struct psp_context *psp, |
715 | uint64_t fw_pri_mc_addr) |
716 | { |
717 | struct amdgpu_device *adev = psp->adev; |
718 | int ret; |
719 | |
720 | /* Confirm PSP is ready to start */ |
721 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_115), |
722 | MBOX_READY_FLAG, MBOX_READY_MASK, check_changed: false); |
723 | if (ret) { |
724 | dev_err(adev->dev, "PSP Not ready to start processing, ret = %d" , ret); |
725 | return ret; |
726 | } |
727 | |
728 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_116, lower_32_bits(fw_pri_mc_addr)); |
729 | |
730 | ret = psp_v13_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_LO); |
731 | if (ret) |
732 | return ret; |
733 | |
734 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_116, upper_32_bits(fw_pri_mc_addr)); |
735 | |
736 | ret = psp_v13_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_HI); |
737 | if (ret) |
738 | return ret; |
739 | |
740 | psp->vbflash_done = true; |
741 | |
742 | ret = psp_v13_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE); |
743 | if (ret) |
744 | return ret; |
745 | |
746 | return 0; |
747 | } |
748 | |
749 | static int psp_v13_0_vbflash_status(struct psp_context *psp) |
750 | { |
751 | struct amdgpu_device *adev = psp->adev; |
752 | |
753 | return RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_115); |
754 | } |
755 | |
756 | static int psp_v13_0_fatal_error_recovery_quirk(struct psp_context *psp) |
757 | { |
758 | struct amdgpu_device *adev = psp->adev; |
759 | |
760 | if (amdgpu_ip_version(adev, ip: MP0_HWIP, inst: 0) == IP_VERSION(13, 0, 10)) { |
761 | uint32_t reg_data; |
762 | /* MP1 fatal error: trigger PSP dram read to unhalt PSP |
763 | * during MP1 triggered sync flood. |
764 | */ |
765 | reg_data = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_67); |
766 | WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_67, reg_data + 0x10); |
767 | |
768 | /* delay 1000ms for the mode1 reset for fatal error |
769 | * to be recovered back. |
770 | */ |
771 | msleep(msecs: 1000); |
772 | } |
773 | |
774 | return 0; |
775 | } |
776 | |
777 | static bool psp_v13_0_get_ras_capability(struct psp_context *psp) |
778 | { |
779 | struct amdgpu_device *adev = psp->adev; |
780 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
781 | u32 reg_data; |
782 | |
783 | /* query ras cap should be done from host side */ |
784 | if (amdgpu_sriov_vf(adev)) |
785 | return false; |
786 | |
787 | if (!con) |
788 | return false; |
789 | |
790 | if ((amdgpu_ip_version(adev, ip: MP0_HWIP, inst: 0) == IP_VERSION(13, 0, 6)) && |
791 | (!(adev->flags & AMD_IS_APU))) { |
792 | reg_data = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_127); |
793 | adev->ras_hw_enabled = (reg_data & GENMASK_ULL(23, 0)); |
794 | con->poison_supported = ((reg_data & GENMASK_ULL(24, 24)) >> 24) ? true : false; |
795 | return true; |
796 | } else { |
797 | return false; |
798 | } |
799 | } |
800 | |
801 | static const struct psp_funcs psp_v13_0_funcs = { |
802 | .init_microcode = psp_v13_0_init_microcode, |
803 | .wait_for_bootloader = psp_v13_0_wait_for_bootloader_steady_state, |
804 | .bootloader_load_kdb = psp_v13_0_bootloader_load_kdb, |
805 | .bootloader_load_spl = psp_v13_0_bootloader_load_spl, |
806 | .bootloader_load_sysdrv = psp_v13_0_bootloader_load_sysdrv, |
807 | .bootloader_load_soc_drv = psp_v13_0_bootloader_load_soc_drv, |
808 | .bootloader_load_intf_drv = psp_v13_0_bootloader_load_intf_drv, |
809 | .bootloader_load_dbg_drv = psp_v13_0_bootloader_load_dbg_drv, |
810 | .bootloader_load_ras_drv = psp_v13_0_bootloader_load_ras_drv, |
811 | .bootloader_load_sos = psp_v13_0_bootloader_load_sos, |
812 | .ring_create = psp_v13_0_ring_create, |
813 | .ring_stop = psp_v13_0_ring_stop, |
814 | .ring_destroy = psp_v13_0_ring_destroy, |
815 | .ring_get_wptr = psp_v13_0_ring_get_wptr, |
816 | .ring_set_wptr = psp_v13_0_ring_set_wptr, |
817 | .mem_training = psp_v13_0_memory_training, |
818 | .load_usbc_pd_fw = psp_v13_0_load_usbc_pd_fw, |
819 | .read_usbc_pd_fw = psp_v13_0_read_usbc_pd_fw, |
820 | .update_spirom = psp_v13_0_update_spirom, |
821 | .vbflash_stat = psp_v13_0_vbflash_status, |
822 | .fatal_error_recovery_quirk = psp_v13_0_fatal_error_recovery_quirk, |
823 | .get_ras_capability = psp_v13_0_get_ras_capability, |
824 | }; |
825 | |
826 | void psp_v13_0_set_psp_funcs(struct psp_context *psp) |
827 | { |
828 | psp->funcs = &psp_v13_0_funcs; |
829 | } |
830 | |