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