xref: /openbmc/linux/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c (revision 05cf4fe738242183f1237f1b3a28b4479348c0a1)
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 <drm/drmP.h>
28 #include "amdgpu.h"
29 #include "amdgpu_psp.h"
30 #include "amdgpu_ucode.h"
31 #include "soc15_common.h"
32 #include "psp_v3_1.h"
33 #include "psp_v10_0.h"
34 #include "psp_v11_0.h"
35 
36 static void psp_set_funcs(struct amdgpu_device *adev);
37 
38 static int psp_early_init(void *handle)
39 {
40 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
41 
42 	psp_set_funcs(adev);
43 
44 	return 0;
45 }
46 
47 static int psp_sw_init(void *handle)
48 {
49 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
50 	struct psp_context *psp = &adev->psp;
51 	int ret;
52 
53 	switch (adev->asic_type) {
54 	case CHIP_VEGA10:
55 	case CHIP_VEGA12:
56 		psp_v3_1_set_psp_funcs(psp);
57 		break;
58 	case CHIP_RAVEN:
59 		psp_v10_0_set_psp_funcs(psp);
60 		break;
61 	case CHIP_VEGA20:
62 		psp_v11_0_set_psp_funcs(psp);
63 		break;
64 	default:
65 		return -EINVAL;
66 	}
67 
68 	psp->adev = adev;
69 
70 	if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
71 		return 0;
72 
73 	ret = psp_init_microcode(psp);
74 	if (ret) {
75 		DRM_ERROR("Failed to load psp firmware!\n");
76 		return ret;
77 	}
78 
79 	return 0;
80 }
81 
82 static int psp_sw_fini(void *handle)
83 {
84 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
85 
86 	if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
87 		return 0;
88 
89 	release_firmware(adev->psp.sos_fw);
90 	adev->psp.sos_fw = NULL;
91 	release_firmware(adev->psp.asd_fw);
92 	adev->psp.asd_fw = NULL;
93 	return 0;
94 }
95 
96 int psp_wait_for(struct psp_context *psp, uint32_t reg_index,
97 		 uint32_t reg_val, uint32_t mask, bool check_changed)
98 {
99 	uint32_t val;
100 	int i;
101 	struct amdgpu_device *adev = psp->adev;
102 
103 	for (i = 0; i < adev->usec_timeout; i++) {
104 		val = RREG32(reg_index);
105 		if (check_changed) {
106 			if (val != reg_val)
107 				return 0;
108 		} else {
109 			if ((val & mask) == reg_val)
110 				return 0;
111 		}
112 		udelay(1);
113 	}
114 
115 	return -ETIME;
116 }
117 
118 static int
119 psp_cmd_submit_buf(struct psp_context *psp,
120 		   struct amdgpu_firmware_info *ucode,
121 		   struct psp_gfx_cmd_resp *cmd, uint64_t fence_mc_addr,
122 		   int index)
123 {
124 	int ret;
125 
126 	memset(psp->cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE);
127 
128 	memcpy(psp->cmd_buf_mem, cmd, sizeof(struct psp_gfx_cmd_resp));
129 
130 	ret = psp_cmd_submit(psp, ucode, psp->cmd_buf_mc_addr,
131 			     fence_mc_addr, index);
132 
133 	while (*((unsigned int *)psp->fence_buf) != index) {
134 		msleep(1);
135 	}
136 
137 	/* the status field must be 0 after FW is loaded */
138 	if (ucode && psp->cmd_buf_mem->resp.status) {
139 		DRM_ERROR("failed loading with status (%d) and ucode id (%d)\n",
140 			  psp->cmd_buf_mem->resp.status, ucode->ucode_id);
141 		return -EINVAL;
142 	}
143 
144 	if (ucode) {
145 		ucode->tmr_mc_addr_lo = psp->cmd_buf_mem->resp.fw_addr_lo;
146 		ucode->tmr_mc_addr_hi = psp->cmd_buf_mem->resp.fw_addr_hi;
147 	}
148 
149 	return ret;
150 }
151 
152 static void psp_prep_tmr_cmd_buf(struct psp_gfx_cmd_resp *cmd,
153 				 uint64_t tmr_mc, uint32_t size)
154 {
155 	cmd->cmd_id = GFX_CMD_ID_SETUP_TMR;
156 	cmd->cmd.cmd_setup_tmr.buf_phy_addr_lo = lower_32_bits(tmr_mc);
157 	cmd->cmd.cmd_setup_tmr.buf_phy_addr_hi = upper_32_bits(tmr_mc);
158 	cmd->cmd.cmd_setup_tmr.buf_size = size;
159 }
160 
161 /* Set up Trusted Memory Region */
162 static int psp_tmr_init(struct psp_context *psp)
163 {
164 	int ret;
165 
166 	/*
167 	 * Allocate 3M memory aligned to 1M from Frame Buffer (local
168 	 * physical).
169 	 *
170 	 * Note: this memory need be reserved till the driver
171 	 * uninitializes.
172 	 */
173 	ret = amdgpu_bo_create_kernel(psp->adev, PSP_TMR_SIZE, 0x100000,
174 				      AMDGPU_GEM_DOMAIN_VRAM,
175 				      &psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf);
176 
177 	return ret;
178 }
179 
180 static int psp_tmr_load(struct psp_context *psp)
181 {
182 	int ret;
183 	struct psp_gfx_cmd_resp *cmd;
184 
185 	cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
186 	if (!cmd)
187 		return -ENOMEM;
188 
189 	psp_prep_tmr_cmd_buf(cmd, psp->tmr_mc_addr, PSP_TMR_SIZE);
190 	DRM_INFO("reserve 0x%x from 0x%llx for PSP TMR SIZE\n",
191 			PSP_TMR_SIZE, psp->tmr_mc_addr);
192 
193 	ret = psp_cmd_submit_buf(psp, NULL, cmd,
194 				 psp->fence_buf_mc_addr, 1);
195 	if (ret)
196 		goto failed;
197 
198 	kfree(cmd);
199 
200 	return 0;
201 
202 failed:
203 	kfree(cmd);
204 	return ret;
205 }
206 
207 static void psp_prep_asd_cmd_buf(struct psp_gfx_cmd_resp *cmd,
208 				 uint64_t asd_mc, uint64_t asd_mc_shared,
209 				 uint32_t size, uint32_t shared_size)
210 {
211 	cmd->cmd_id = GFX_CMD_ID_LOAD_ASD;
212 	cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(asd_mc);
213 	cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(asd_mc);
214 	cmd->cmd.cmd_load_ta.app_len = size;
215 
216 	cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(asd_mc_shared);
217 	cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(asd_mc_shared);
218 	cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size;
219 }
220 
221 static int psp_asd_init(struct psp_context *psp)
222 {
223 	int ret;
224 
225 	/*
226 	 * Allocate 16k memory aligned to 4k from Frame Buffer (local
227 	 * physical) for shared ASD <-> Driver
228 	 */
229 	ret = amdgpu_bo_create_kernel(psp->adev, PSP_ASD_SHARED_MEM_SIZE,
230 				      PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
231 				      &psp->asd_shared_bo,
232 				      &psp->asd_shared_mc_addr,
233 				      &psp->asd_shared_buf);
234 
235 	return ret;
236 }
237 
238 static int psp_asd_load(struct psp_context *psp)
239 {
240 	int ret;
241 	struct psp_gfx_cmd_resp *cmd;
242 
243 	/* If PSP version doesn't match ASD version, asd loading will be failed.
244 	 * add workaround to bypass it for sriov now.
245 	 * TODO: add version check to make it common
246 	 */
247 	if (amdgpu_sriov_vf(psp->adev))
248 		return 0;
249 
250 	cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
251 	if (!cmd)
252 		return -ENOMEM;
253 
254 	memset(psp->fw_pri_buf, 0, PSP_1_MEG);
255 	memcpy(psp->fw_pri_buf, psp->asd_start_addr, psp->asd_ucode_size);
256 
257 	psp_prep_asd_cmd_buf(cmd, psp->fw_pri_mc_addr, psp->asd_shared_mc_addr,
258 			     psp->asd_ucode_size, PSP_ASD_SHARED_MEM_SIZE);
259 
260 	ret = psp_cmd_submit_buf(psp, NULL, cmd,
261 				 psp->fence_buf_mc_addr, 2);
262 
263 	kfree(cmd);
264 
265 	return ret;
266 }
267 
268 static int psp_hw_start(struct psp_context *psp)
269 {
270 	struct amdgpu_device *adev = psp->adev;
271 	int ret;
272 
273 	if (!amdgpu_sriov_vf(adev) || !adev->in_gpu_reset) {
274 		ret = psp_bootloader_load_sysdrv(psp);
275 		if (ret)
276 			return ret;
277 
278 		ret = psp_bootloader_load_sos(psp);
279 		if (ret)
280 			return ret;
281 	}
282 
283 	ret = psp_ring_create(psp, PSP_RING_TYPE__KM);
284 	if (ret)
285 		return ret;
286 
287 	ret = psp_tmr_load(psp);
288 	if (ret)
289 		return ret;
290 
291 	ret = psp_asd_load(psp);
292 	if (ret)
293 		return ret;
294 
295 	return 0;
296 }
297 
298 static int psp_np_fw_load(struct psp_context *psp)
299 {
300 	int i, ret;
301 	struct amdgpu_firmware_info *ucode;
302 	struct amdgpu_device* adev = psp->adev;
303 
304 	for (i = 0; i < adev->firmware.max_ucodes; i++) {
305 		ucode = &adev->firmware.ucode[i];
306 		if (!ucode->fw)
307 			continue;
308 
309 		if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC &&
310 		    psp_smu_reload_quirk(psp))
311 			continue;
312 		if (amdgpu_sriov_vf(adev) &&
313 		   (ucode->ucode_id == AMDGPU_UCODE_ID_SDMA0
314 		    || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1
315 		    || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_G))
316 			/*skip ucode loading in SRIOV VF */
317 			continue;
318 
319 		ret = psp_prep_cmd_buf(ucode, psp->cmd);
320 		if (ret)
321 			return ret;
322 
323 		ret = psp_cmd_submit_buf(psp, ucode, psp->cmd,
324 					 psp->fence_buf_mc_addr, i + 3);
325 		if (ret)
326 			return ret;
327 
328 #if 0
329 		/* check if firmware loaded sucessfully */
330 		if (!amdgpu_psp_check_fw_loading_status(adev, i))
331 			return -EINVAL;
332 #endif
333 	}
334 
335 	return 0;
336 }
337 
338 static int psp_load_fw(struct amdgpu_device *adev)
339 {
340 	int ret;
341 	struct psp_context *psp = &adev->psp;
342 
343 	if (amdgpu_sriov_vf(adev) && adev->in_gpu_reset != 0)
344 		goto skip_memalloc;
345 
346 	psp->cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
347 	if (!psp->cmd)
348 		return -ENOMEM;
349 
350 	ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG,
351 					AMDGPU_GEM_DOMAIN_GTT,
352 					&psp->fw_pri_bo,
353 					&psp->fw_pri_mc_addr,
354 					&psp->fw_pri_buf);
355 	if (ret)
356 		goto failed;
357 
358 	ret = amdgpu_bo_create_kernel(adev, PSP_FENCE_BUFFER_SIZE, PAGE_SIZE,
359 					AMDGPU_GEM_DOMAIN_VRAM,
360 					&psp->fence_buf_bo,
361 					&psp->fence_buf_mc_addr,
362 					&psp->fence_buf);
363 	if (ret)
364 		goto failed_mem2;
365 
366 	ret = amdgpu_bo_create_kernel(adev, PSP_CMD_BUFFER_SIZE, PAGE_SIZE,
367 				      AMDGPU_GEM_DOMAIN_VRAM,
368 				      &psp->cmd_buf_bo, &psp->cmd_buf_mc_addr,
369 				      (void **)&psp->cmd_buf_mem);
370 	if (ret)
371 		goto failed_mem1;
372 
373 	memset(psp->fence_buf, 0, PSP_FENCE_BUFFER_SIZE);
374 
375 	ret = psp_ring_init(psp, PSP_RING_TYPE__KM);
376 	if (ret)
377 		goto failed_mem;
378 
379 	ret = psp_tmr_init(psp);
380 	if (ret)
381 		goto failed_mem;
382 
383 	ret = psp_asd_init(psp);
384 	if (ret)
385 		goto failed_mem;
386 
387 skip_memalloc:
388 	ret = psp_hw_start(psp);
389 	if (ret)
390 		goto failed_mem;
391 
392 	ret = psp_np_fw_load(psp);
393 	if (ret)
394 		goto failed_mem;
395 
396 	return 0;
397 
398 failed_mem:
399 	amdgpu_bo_free_kernel(&psp->cmd_buf_bo,
400 			      &psp->cmd_buf_mc_addr,
401 			      (void **)&psp->cmd_buf_mem);
402 failed_mem1:
403 	amdgpu_bo_free_kernel(&psp->fence_buf_bo,
404 			      &psp->fence_buf_mc_addr, &psp->fence_buf);
405 failed_mem2:
406 	amdgpu_bo_free_kernel(&psp->fw_pri_bo,
407 			      &psp->fw_pri_mc_addr, &psp->fw_pri_buf);
408 failed:
409 	kfree(psp->cmd);
410 	psp->cmd = NULL;
411 	return ret;
412 }
413 
414 static int psp_hw_init(void *handle)
415 {
416 	int ret;
417 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
418 
419 
420 	if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
421 		return 0;
422 
423 	mutex_lock(&adev->firmware.mutex);
424 	/*
425 	 * This sequence is just used on hw_init only once, no need on
426 	 * resume.
427 	 */
428 	ret = amdgpu_ucode_init_bo(adev);
429 	if (ret)
430 		goto failed;
431 
432 	ret = psp_load_fw(adev);
433 	if (ret) {
434 		DRM_ERROR("PSP firmware loading failed\n");
435 		goto failed;
436 	}
437 
438 	mutex_unlock(&adev->firmware.mutex);
439 	return 0;
440 
441 failed:
442 	adev->firmware.load_type = AMDGPU_FW_LOAD_DIRECT;
443 	mutex_unlock(&adev->firmware.mutex);
444 	return -EINVAL;
445 }
446 
447 static int psp_hw_fini(void *handle)
448 {
449 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
450 	struct psp_context *psp = &adev->psp;
451 
452 	if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
453 		return 0;
454 
455 	psp_ring_destroy(psp, PSP_RING_TYPE__KM);
456 
457 	amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf);
458 	amdgpu_bo_free_kernel(&psp->fw_pri_bo,
459 			      &psp->fw_pri_mc_addr, &psp->fw_pri_buf);
460 	amdgpu_bo_free_kernel(&psp->fence_buf_bo,
461 			      &psp->fence_buf_mc_addr, &psp->fence_buf);
462 	amdgpu_bo_free_kernel(&psp->asd_shared_bo, &psp->asd_shared_mc_addr,
463 			      &psp->asd_shared_buf);
464 	amdgpu_bo_free_kernel(&psp->cmd_buf_bo, &psp->cmd_buf_mc_addr,
465 			      (void **)&psp->cmd_buf_mem);
466 
467 	kfree(psp->cmd);
468 	psp->cmd = NULL;
469 
470 	return 0;
471 }
472 
473 static int psp_suspend(void *handle)
474 {
475 	int ret;
476 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
477 	struct psp_context *psp = &adev->psp;
478 
479 	if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
480 		return 0;
481 
482 	ret = psp_ring_stop(psp, PSP_RING_TYPE__KM);
483 	if (ret) {
484 		DRM_ERROR("PSP ring stop failed\n");
485 		return ret;
486 	}
487 
488 	return 0;
489 }
490 
491 static int psp_resume(void *handle)
492 {
493 	int ret;
494 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
495 	struct psp_context *psp = &adev->psp;
496 
497 	if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
498 		return 0;
499 
500 	DRM_INFO("PSP is resuming...\n");
501 
502 	mutex_lock(&adev->firmware.mutex);
503 
504 	ret = psp_hw_start(psp);
505 	if (ret)
506 		goto failed;
507 
508 	ret = psp_np_fw_load(psp);
509 	if (ret)
510 		goto failed;
511 
512 	mutex_unlock(&adev->firmware.mutex);
513 
514 	return 0;
515 
516 failed:
517 	DRM_ERROR("PSP resume failed\n");
518 	mutex_unlock(&adev->firmware.mutex);
519 	return ret;
520 }
521 
522 int psp_gpu_reset(struct amdgpu_device *adev)
523 {
524 	if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
525 		return 0;
526 
527 	return psp_mode1_reset(&adev->psp);
528 }
529 
530 static bool psp_check_fw_loading_status(struct amdgpu_device *adev,
531 					enum AMDGPU_UCODE_ID ucode_type)
532 {
533 	struct amdgpu_firmware_info *ucode = NULL;
534 
535 	if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
536 		DRM_INFO("firmware is not loaded by PSP\n");
537 		return true;
538 	}
539 
540 	if (!adev->firmware.fw_size)
541 		return false;
542 
543 	ucode = &adev->firmware.ucode[ucode_type];
544 	if (!ucode->fw || !ucode->ucode_size)
545 		return false;
546 
547 	return psp_compare_sram_data(&adev->psp, ucode, ucode_type);
548 }
549 
550 static int psp_set_clockgating_state(void *handle,
551 				     enum amd_clockgating_state state)
552 {
553 	return 0;
554 }
555 
556 static int psp_set_powergating_state(void *handle,
557 				     enum amd_powergating_state state)
558 {
559 	return 0;
560 }
561 
562 const struct amd_ip_funcs psp_ip_funcs = {
563 	.name = "psp",
564 	.early_init = psp_early_init,
565 	.late_init = NULL,
566 	.sw_init = psp_sw_init,
567 	.sw_fini = psp_sw_fini,
568 	.hw_init = psp_hw_init,
569 	.hw_fini = psp_hw_fini,
570 	.suspend = psp_suspend,
571 	.resume = psp_resume,
572 	.is_idle = NULL,
573 	.check_soft_reset = NULL,
574 	.wait_for_idle = NULL,
575 	.soft_reset = NULL,
576 	.set_clockgating_state = psp_set_clockgating_state,
577 	.set_powergating_state = psp_set_powergating_state,
578 };
579 
580 static const struct amdgpu_psp_funcs psp_funcs = {
581 	.check_fw_loading_status = psp_check_fw_loading_status,
582 };
583 
584 static void psp_set_funcs(struct amdgpu_device *adev)
585 {
586 	if (NULL == adev->firmware.funcs)
587 		adev->firmware.funcs = &psp_funcs;
588 }
589 
590 const struct amdgpu_ip_block_version psp_v3_1_ip_block =
591 {
592 	.type = AMD_IP_BLOCK_TYPE_PSP,
593 	.major = 3,
594 	.minor = 1,
595 	.rev = 0,
596 	.funcs = &psp_ip_funcs,
597 };
598 
599 const struct amdgpu_ip_block_version psp_v10_0_ip_block =
600 {
601 	.type = AMD_IP_BLOCK_TYPE_PSP,
602 	.major = 10,
603 	.minor = 0,
604 	.rev = 0,
605 	.funcs = &psp_ip_funcs,
606 };
607 
608 const struct amdgpu_ip_block_version psp_v11_0_ip_block =
609 {
610 	.type = AMD_IP_BLOCK_TYPE_PSP,
611 	.major = 11,
612 	.minor = 0,
613 	.rev = 0,
614 	.funcs = &psp_ip_funcs,
615 };
616