]> Git Repo - linux.git/blob - drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
Merge tag 'mmc-v4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
[linux.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_psp.c
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         release_firmware(adev->psp.ta_fw);
94         adev->psp.ta_fw = NULL;
95         return 0;
96 }
97
98 int psp_wait_for(struct psp_context *psp, uint32_t reg_index,
99                  uint32_t reg_val, uint32_t mask, bool check_changed)
100 {
101         uint32_t val;
102         int i;
103         struct amdgpu_device *adev = psp->adev;
104
105         for (i = 0; i < adev->usec_timeout; i++) {
106                 val = RREG32(reg_index);
107                 if (check_changed) {
108                         if (val != reg_val)
109                                 return 0;
110                 } else {
111                         if ((val & mask) == reg_val)
112                                 return 0;
113                 }
114                 udelay(1);
115         }
116
117         return -ETIME;
118 }
119
120 static int
121 psp_cmd_submit_buf(struct psp_context *psp,
122                    struct amdgpu_firmware_info *ucode,
123                    struct psp_gfx_cmd_resp *cmd, uint64_t fence_mc_addr)
124 {
125         int ret;
126         int index;
127
128         memset(psp->cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE);
129
130         memcpy(psp->cmd_buf_mem, cmd, sizeof(struct psp_gfx_cmd_resp));
131
132         index = atomic_inc_return(&psp->fence_value);
133         ret = psp_cmd_submit(psp, ucode, psp->cmd_buf_mc_addr,
134                              fence_mc_addr, index);
135         if (ret) {
136                 atomic_dec(&psp->fence_value);
137                 return ret;
138         }
139
140         while (*((unsigned int *)psp->fence_buf) != index)
141                 msleep(1);
142
143         /* the status field must be 0 after FW is loaded */
144         if (ucode && psp->cmd_buf_mem->resp.status) {
145                 DRM_ERROR("failed loading with status (%d) and ucode id (%d)\n",
146                           psp->cmd_buf_mem->resp.status, ucode->ucode_id);
147                 return -EINVAL;
148         }
149
150         if (ucode) {
151                 ucode->tmr_mc_addr_lo = psp->cmd_buf_mem->resp.fw_addr_lo;
152                 ucode->tmr_mc_addr_hi = psp->cmd_buf_mem->resp.fw_addr_hi;
153         }
154
155         return ret;
156 }
157
158 bool psp_support_vmr_ring(struct psp_context *psp)
159 {
160         if (amdgpu_sriov_vf(psp->adev) && psp->sos_fw_version > 0x80045)
161                 return true;
162         else
163                 return false;
164 }
165
166 static void psp_prep_tmr_cmd_buf(struct psp_context *psp,
167                                  struct psp_gfx_cmd_resp *cmd,
168                                  uint64_t tmr_mc, uint32_t size)
169 {
170         if (psp_support_vmr_ring(psp))
171                 cmd->cmd_id = GFX_CMD_ID_SETUP_VMR;
172         else
173                 cmd->cmd_id = GFX_CMD_ID_SETUP_TMR;
174         cmd->cmd.cmd_setup_tmr.buf_phy_addr_lo = lower_32_bits(tmr_mc);
175         cmd->cmd.cmd_setup_tmr.buf_phy_addr_hi = upper_32_bits(tmr_mc);
176         cmd->cmd.cmd_setup_tmr.buf_size = size;
177 }
178
179 /* Set up Trusted Memory Region */
180 static int psp_tmr_init(struct psp_context *psp)
181 {
182         int ret;
183
184         /*
185          * Allocate 3M memory aligned to 1M from Frame Buffer (local
186          * physical).
187          *
188          * Note: this memory need be reserved till the driver
189          * uninitializes.
190          */
191         ret = amdgpu_bo_create_kernel(psp->adev, PSP_TMR_SIZE, 0x100000,
192                                       AMDGPU_GEM_DOMAIN_VRAM,
193                                       &psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf);
194
195         return ret;
196 }
197
198 static int psp_tmr_load(struct psp_context *psp)
199 {
200         int ret;
201         struct psp_gfx_cmd_resp *cmd;
202
203         cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
204         if (!cmd)
205                 return -ENOMEM;
206
207         psp_prep_tmr_cmd_buf(psp, cmd, psp->tmr_mc_addr, PSP_TMR_SIZE);
208         DRM_INFO("reserve 0x%x from 0x%llx for PSP TMR SIZE\n",
209                         PSP_TMR_SIZE, psp->tmr_mc_addr);
210
211         ret = psp_cmd_submit_buf(psp, NULL, cmd,
212                                  psp->fence_buf_mc_addr);
213         if (ret)
214                 goto failed;
215
216         kfree(cmd);
217
218         return 0;
219
220 failed:
221         kfree(cmd);
222         return ret;
223 }
224
225 static void psp_prep_asd_cmd_buf(struct psp_gfx_cmd_resp *cmd,
226                                  uint64_t asd_mc, uint64_t asd_mc_shared,
227                                  uint32_t size, uint32_t shared_size)
228 {
229         cmd->cmd_id = GFX_CMD_ID_LOAD_ASD;
230         cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(asd_mc);
231         cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(asd_mc);
232         cmd->cmd.cmd_load_ta.app_len = size;
233
234         cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(asd_mc_shared);
235         cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(asd_mc_shared);
236         cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size;
237 }
238
239 static int psp_asd_init(struct psp_context *psp)
240 {
241         int ret;
242
243         /*
244          * Allocate 16k memory aligned to 4k from Frame Buffer (local
245          * physical) for shared ASD <-> Driver
246          */
247         ret = amdgpu_bo_create_kernel(psp->adev, PSP_ASD_SHARED_MEM_SIZE,
248                                       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
249                                       &psp->asd_shared_bo,
250                                       &psp->asd_shared_mc_addr,
251                                       &psp->asd_shared_buf);
252
253         return ret;
254 }
255
256 static int psp_asd_load(struct psp_context *psp)
257 {
258         int ret;
259         struct psp_gfx_cmd_resp *cmd;
260
261         /* If PSP version doesn't match ASD version, asd loading will be failed.
262          * add workaround to bypass it for sriov now.
263          * TODO: add version check to make it common
264          */
265         if (amdgpu_sriov_vf(psp->adev))
266                 return 0;
267
268         cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
269         if (!cmd)
270                 return -ENOMEM;
271
272         memset(psp->fw_pri_buf, 0, PSP_1_MEG);
273         memcpy(psp->fw_pri_buf, psp->asd_start_addr, psp->asd_ucode_size);
274
275         psp_prep_asd_cmd_buf(cmd, psp->fw_pri_mc_addr, psp->asd_shared_mc_addr,
276                              psp->asd_ucode_size, PSP_ASD_SHARED_MEM_SIZE);
277
278         ret = psp_cmd_submit_buf(psp, NULL, cmd,
279                                  psp->fence_buf_mc_addr);
280
281         kfree(cmd);
282
283         return ret;
284 }
285
286 static void psp_prep_xgmi_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd,
287                                           uint64_t xgmi_ta_mc, uint64_t xgmi_mc_shared,
288                                           uint32_t xgmi_ta_size, uint32_t shared_size)
289 {
290         cmd->cmd_id = GFX_CMD_ID_LOAD_TA;
291         cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(xgmi_ta_mc);
292         cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(xgmi_ta_mc);
293         cmd->cmd.cmd_load_ta.app_len = xgmi_ta_size;
294
295         cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(xgmi_mc_shared);
296         cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(xgmi_mc_shared);
297         cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size;
298 }
299
300 static int psp_xgmi_init_shared_buf(struct psp_context *psp)
301 {
302         int ret;
303
304         /*
305          * Allocate 16k memory aligned to 4k from Frame Buffer (local
306          * physical) for xgmi ta <-> Driver
307          */
308         ret = amdgpu_bo_create_kernel(psp->adev, PSP_XGMI_SHARED_MEM_SIZE,
309                                       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
310                                       &psp->xgmi_context.xgmi_shared_bo,
311                                       &psp->xgmi_context.xgmi_shared_mc_addr,
312                                       &psp->xgmi_context.xgmi_shared_buf);
313
314         return ret;
315 }
316
317 static int psp_xgmi_load(struct psp_context *psp)
318 {
319         int ret;
320         struct psp_gfx_cmd_resp *cmd;
321
322         /*
323          * TODO: bypass the loading in sriov for now
324          */
325         if (amdgpu_sriov_vf(psp->adev))
326                 return 0;
327
328         cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
329         if (!cmd)
330                 return -ENOMEM;
331
332         memset(psp->fw_pri_buf, 0, PSP_1_MEG);
333         memcpy(psp->fw_pri_buf, psp->ta_xgmi_start_addr, psp->ta_xgmi_ucode_size);
334
335         psp_prep_xgmi_ta_load_cmd_buf(cmd, psp->fw_pri_mc_addr,
336                                       psp->xgmi_context.xgmi_shared_mc_addr,
337                                       psp->ta_xgmi_ucode_size, PSP_XGMI_SHARED_MEM_SIZE);
338
339         ret = psp_cmd_submit_buf(psp, NULL, cmd,
340                                  psp->fence_buf_mc_addr);
341
342         if (!ret) {
343                 psp->xgmi_context.initialized = 1;
344                 psp->xgmi_context.session_id = cmd->resp.session_id;
345         }
346
347         kfree(cmd);
348
349         return ret;
350 }
351
352 static void psp_prep_xgmi_ta_unload_cmd_buf(struct psp_gfx_cmd_resp *cmd,
353                                             uint32_t xgmi_session_id)
354 {
355         cmd->cmd_id = GFX_CMD_ID_UNLOAD_TA;
356         cmd->cmd.cmd_unload_ta.session_id = xgmi_session_id;
357 }
358
359 static int psp_xgmi_unload(struct psp_context *psp)
360 {
361         int ret;
362         struct psp_gfx_cmd_resp *cmd;
363
364         /*
365          * TODO: bypass the unloading in sriov for now
366          */
367         if (amdgpu_sriov_vf(psp->adev))
368                 return 0;
369
370         cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
371         if (!cmd)
372                 return -ENOMEM;
373
374         psp_prep_xgmi_ta_unload_cmd_buf(cmd, psp->xgmi_context.session_id);
375
376         ret = psp_cmd_submit_buf(psp, NULL, cmd,
377                                  psp->fence_buf_mc_addr);
378
379         kfree(cmd);
380
381         return ret;
382 }
383
384 static void psp_prep_xgmi_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd,
385                                             uint32_t ta_cmd_id,
386                                             uint32_t xgmi_session_id)
387 {
388         cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD;
389         cmd->cmd.cmd_invoke_cmd.session_id = xgmi_session_id;
390         cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id;
391         /* Note: cmd_invoke_cmd.buf is not used for now */
392 }
393
394 int psp_xgmi_invoke(struct psp_context *psp, uint32_t ta_cmd_id)
395 {
396         int ret;
397         struct psp_gfx_cmd_resp *cmd;
398
399         /*
400          * TODO: bypass the loading in sriov for now
401         */
402         if (amdgpu_sriov_vf(psp->adev))
403                 return 0;
404
405         cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
406         if (!cmd)
407                 return -ENOMEM;
408
409         psp_prep_xgmi_ta_invoke_cmd_buf(cmd, ta_cmd_id,
410                                         psp->xgmi_context.session_id);
411
412         ret = psp_cmd_submit_buf(psp, NULL, cmd,
413                                  psp->fence_buf_mc_addr);
414
415         kfree(cmd);
416
417         return ret;
418 }
419
420 static int psp_xgmi_terminate(struct psp_context *psp)
421 {
422         int ret;
423
424         if (!psp->xgmi_context.initialized)
425                 return 0;
426
427         ret = psp_xgmi_unload(psp);
428         if (ret)
429                 return ret;
430
431         psp->xgmi_context.initialized = 0;
432
433         /* free xgmi shared memory */
434         amdgpu_bo_free_kernel(&psp->xgmi_context.xgmi_shared_bo,
435                         &psp->xgmi_context.xgmi_shared_mc_addr,
436                         &psp->xgmi_context.xgmi_shared_buf);
437
438         return 0;
439 }
440
441 static int psp_xgmi_initialize(struct psp_context *psp)
442 {
443         struct ta_xgmi_shared_memory *xgmi_cmd;
444         int ret;
445
446         if (!psp->xgmi_context.initialized) {
447                 ret = psp_xgmi_init_shared_buf(psp);
448                 if (ret)
449                         return ret;
450         }
451
452         /* Load XGMI TA */
453         ret = psp_xgmi_load(psp);
454         if (ret)
455                 return ret;
456
457         /* Initialize XGMI session */
458         xgmi_cmd = (struct ta_xgmi_shared_memory *)(psp->xgmi_context.xgmi_shared_buf);
459         memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory));
460         xgmi_cmd->cmd_id = TA_COMMAND_XGMI__INITIALIZE;
461
462         ret = psp_xgmi_invoke(psp, xgmi_cmd->cmd_id);
463
464         return ret;
465 }
466
467 static int psp_hw_start(struct psp_context *psp)
468 {
469         struct amdgpu_device *adev = psp->adev;
470         int ret;
471
472         if (!amdgpu_sriov_vf(adev) || !adev->in_gpu_reset) {
473                 ret = psp_bootloader_load_sysdrv(psp);
474                 if (ret)
475                         return ret;
476
477                 ret = psp_bootloader_load_sos(psp);
478                 if (ret)
479                         return ret;
480         }
481
482         ret = psp_ring_create(psp, PSP_RING_TYPE__KM);
483         if (ret)
484                 return ret;
485
486         ret = psp_tmr_load(psp);
487         if (ret)
488                 return ret;
489
490         ret = psp_asd_load(psp);
491         if (ret)
492                 return ret;
493
494         if (adev->gmc.xgmi.num_physical_nodes > 1) {
495                 ret = psp_xgmi_initialize(psp);
496                 /* Warning the XGMI seesion initialize failure
497                  * Instead of stop driver initialization
498                  */
499                 if (ret)
500                         dev_err(psp->adev->dev,
501                                 "XGMI: Failed to initialize XGMI session\n");
502         }
503         return 0;
504 }
505
506 static int psp_np_fw_load(struct psp_context *psp)
507 {
508         int i, ret;
509         struct amdgpu_firmware_info *ucode;
510         struct amdgpu_device* adev = psp->adev;
511
512         for (i = 0; i < adev->firmware.max_ucodes; i++) {
513                 ucode = &adev->firmware.ucode[i];
514                 if (!ucode->fw)
515                         continue;
516
517                 if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC &&
518                     psp_smu_reload_quirk(psp))
519                         continue;
520                 if (amdgpu_sriov_vf(adev) &&
521                    (ucode->ucode_id == AMDGPU_UCODE_ID_SDMA0
522                     || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1
523                     || ucode->ucode_id == AMDGPU_UCODE_ID_RLC_G))
524                         /*skip ucode loading in SRIOV VF */
525                         continue;
526
527                 ret = psp_prep_cmd_buf(ucode, psp->cmd);
528                 if (ret)
529                         return ret;
530
531                 ret = psp_cmd_submit_buf(psp, ucode, psp->cmd,
532                                          psp->fence_buf_mc_addr);
533                 if (ret)
534                         return ret;
535
536 #if 0
537                 /* check if firmware loaded sucessfully */
538                 if (!amdgpu_psp_check_fw_loading_status(adev, i))
539                         return -EINVAL;
540 #endif
541         }
542
543         return 0;
544 }
545
546 static int psp_load_fw(struct amdgpu_device *adev)
547 {
548         int ret;
549         struct psp_context *psp = &adev->psp;
550
551         if (amdgpu_sriov_vf(adev) && adev->in_gpu_reset) {
552                 psp_ring_destroy(psp, PSP_RING_TYPE__KM);
553                 goto skip_memalloc;
554         }
555
556         psp->cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
557         if (!psp->cmd)
558                 return -ENOMEM;
559
560         ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG,
561                                         AMDGPU_GEM_DOMAIN_GTT,
562                                         &psp->fw_pri_bo,
563                                         &psp->fw_pri_mc_addr,
564                                         &psp->fw_pri_buf);
565         if (ret)
566                 goto failed;
567
568         ret = amdgpu_bo_create_kernel(adev, PSP_FENCE_BUFFER_SIZE, PAGE_SIZE,
569                                         AMDGPU_GEM_DOMAIN_VRAM,
570                                         &psp->fence_buf_bo,
571                                         &psp->fence_buf_mc_addr,
572                                         &psp->fence_buf);
573         if (ret)
574                 goto failed_mem2;
575
576         ret = amdgpu_bo_create_kernel(adev, PSP_CMD_BUFFER_SIZE, PAGE_SIZE,
577                                       AMDGPU_GEM_DOMAIN_VRAM,
578                                       &psp->cmd_buf_bo, &psp->cmd_buf_mc_addr,
579                                       (void **)&psp->cmd_buf_mem);
580         if (ret)
581                 goto failed_mem1;
582
583         memset(psp->fence_buf, 0, PSP_FENCE_BUFFER_SIZE);
584
585         ret = psp_ring_init(psp, PSP_RING_TYPE__KM);
586         if (ret)
587                 goto failed_mem;
588
589         ret = psp_tmr_init(psp);
590         if (ret)
591                 goto failed_mem;
592
593         ret = psp_asd_init(psp);
594         if (ret)
595                 goto failed_mem;
596
597 skip_memalloc:
598         ret = psp_hw_start(psp);
599         if (ret)
600                 goto failed_mem;
601
602         ret = psp_np_fw_load(psp);
603         if (ret)
604                 goto failed_mem;
605
606         return 0;
607
608 failed_mem:
609         amdgpu_bo_free_kernel(&psp->cmd_buf_bo,
610                               &psp->cmd_buf_mc_addr,
611                               (void **)&psp->cmd_buf_mem);
612 failed_mem1:
613         amdgpu_bo_free_kernel(&psp->fence_buf_bo,
614                               &psp->fence_buf_mc_addr, &psp->fence_buf);
615 failed_mem2:
616         amdgpu_bo_free_kernel(&psp->fw_pri_bo,
617                               &psp->fw_pri_mc_addr, &psp->fw_pri_buf);
618 failed:
619         kfree(psp->cmd);
620         psp->cmd = NULL;
621         return ret;
622 }
623
624 static int psp_hw_init(void *handle)
625 {
626         int ret;
627         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
628
629
630         if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
631                 return 0;
632
633         mutex_lock(&adev->firmware.mutex);
634         /*
635          * This sequence is just used on hw_init only once, no need on
636          * resume.
637          */
638         ret = amdgpu_ucode_init_bo(adev);
639         if (ret)
640                 goto failed;
641
642         ret = psp_load_fw(adev);
643         if (ret) {
644                 DRM_ERROR("PSP firmware loading failed\n");
645                 goto failed;
646         }
647
648         mutex_unlock(&adev->firmware.mutex);
649         return 0;
650
651 failed:
652         adev->firmware.load_type = AMDGPU_FW_LOAD_DIRECT;
653         mutex_unlock(&adev->firmware.mutex);
654         return -EINVAL;
655 }
656
657 static int psp_hw_fini(void *handle)
658 {
659         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
660         struct psp_context *psp = &adev->psp;
661
662         if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
663                 return 0;
664
665         if (adev->gmc.xgmi.num_physical_nodes > 1 &&
666             psp->xgmi_context.initialized == 1)
667                 psp_xgmi_terminate(psp);
668
669         psp_ring_destroy(psp, PSP_RING_TYPE__KM);
670
671         amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf);
672         amdgpu_bo_free_kernel(&psp->fw_pri_bo,
673                               &psp->fw_pri_mc_addr, &psp->fw_pri_buf);
674         amdgpu_bo_free_kernel(&psp->fence_buf_bo,
675                               &psp->fence_buf_mc_addr, &psp->fence_buf);
676         amdgpu_bo_free_kernel(&psp->asd_shared_bo, &psp->asd_shared_mc_addr,
677                               &psp->asd_shared_buf);
678         amdgpu_bo_free_kernel(&psp->cmd_buf_bo, &psp->cmd_buf_mc_addr,
679                               (void **)&psp->cmd_buf_mem);
680
681         kfree(psp->cmd);
682         psp->cmd = NULL;
683
684         return 0;
685 }
686
687 static int psp_suspend(void *handle)
688 {
689         int ret;
690         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
691         struct psp_context *psp = &adev->psp;
692
693         if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
694                 return 0;
695
696         if (adev->gmc.xgmi.num_physical_nodes > 1 &&
697             psp->xgmi_context.initialized == 1) {
698                 ret = psp_xgmi_terminate(psp);
699                 if (ret) {
700                         DRM_ERROR("Failed to terminate xgmi ta\n");
701                         return ret;
702                 }
703         }
704
705         ret = psp_ring_stop(psp, PSP_RING_TYPE__KM);
706         if (ret) {
707                 DRM_ERROR("PSP ring stop failed\n");
708                 return ret;
709         }
710
711         return 0;
712 }
713
714 static int psp_resume(void *handle)
715 {
716         int ret;
717         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
718         struct psp_context *psp = &adev->psp;
719
720         if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
721                 return 0;
722
723         DRM_INFO("PSP is resuming...\n");
724
725         mutex_lock(&adev->firmware.mutex);
726
727         ret = psp_hw_start(psp);
728         if (ret)
729                 goto failed;
730
731         ret = psp_np_fw_load(psp);
732         if (ret)
733                 goto failed;
734
735         mutex_unlock(&adev->firmware.mutex);
736
737         return 0;
738
739 failed:
740         DRM_ERROR("PSP resume failed\n");
741         mutex_unlock(&adev->firmware.mutex);
742         return ret;
743 }
744
745 int psp_gpu_reset(struct amdgpu_device *adev)
746 {
747         if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
748                 return 0;
749
750         return psp_mode1_reset(&adev->psp);
751 }
752
753 static bool psp_check_fw_loading_status(struct amdgpu_device *adev,
754                                         enum AMDGPU_UCODE_ID ucode_type)
755 {
756         struct amdgpu_firmware_info *ucode = NULL;
757
758         if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
759                 DRM_INFO("firmware is not loaded by PSP\n");
760                 return true;
761         }
762
763         if (!adev->firmware.fw_size)
764                 return false;
765
766         ucode = &adev->firmware.ucode[ucode_type];
767         if (!ucode->fw || !ucode->ucode_size)
768                 return false;
769
770         return psp_compare_sram_data(&adev->psp, ucode, ucode_type);
771 }
772
773 static int psp_set_clockgating_state(void *handle,
774                                      enum amd_clockgating_state state)
775 {
776         return 0;
777 }
778
779 static int psp_set_powergating_state(void *handle,
780                                      enum amd_powergating_state state)
781 {
782         return 0;
783 }
784
785 const struct amd_ip_funcs psp_ip_funcs = {
786         .name = "psp",
787         .early_init = psp_early_init,
788         .late_init = NULL,
789         .sw_init = psp_sw_init,
790         .sw_fini = psp_sw_fini,
791         .hw_init = psp_hw_init,
792         .hw_fini = psp_hw_fini,
793         .suspend = psp_suspend,
794         .resume = psp_resume,
795         .is_idle = NULL,
796         .check_soft_reset = NULL,
797         .wait_for_idle = NULL,
798         .soft_reset = NULL,
799         .set_clockgating_state = psp_set_clockgating_state,
800         .set_powergating_state = psp_set_powergating_state,
801 };
802
803 static const struct amdgpu_psp_funcs psp_funcs = {
804         .check_fw_loading_status = psp_check_fw_loading_status,
805 };
806
807 static void psp_set_funcs(struct amdgpu_device *adev)
808 {
809         if (NULL == adev->firmware.funcs)
810                 adev->firmware.funcs = &psp_funcs;
811 }
812
813 const struct amdgpu_ip_block_version psp_v3_1_ip_block =
814 {
815         .type = AMD_IP_BLOCK_TYPE_PSP,
816         .major = 3,
817         .minor = 1,
818         .rev = 0,
819         .funcs = &psp_ip_funcs,
820 };
821
822 const struct amdgpu_ip_block_version psp_v10_0_ip_block =
823 {
824         .type = AMD_IP_BLOCK_TYPE_PSP,
825         .major = 10,
826         .minor = 0,
827         .rev = 0,
828         .funcs = &psp_ip_funcs,
829 };
830
831 const struct amdgpu_ip_block_version psp_v11_0_ip_block =
832 {
833         .type = AMD_IP_BLOCK_TYPE_PSP,
834         .major = 11,
835         .minor = 0,
836         .rev = 0,
837         .funcs = &psp_ip_funcs,
838 };
This page took 0.086851 seconds and 4 git commands to generate.