xref: /dragonfly/sys/dev/drm/amd/amdgpu/amdgpu_cgs.c (revision 809f38025e6f424cb8960d509d59de3ddc7d6b98)
1 /*
2  * Copyright 2015 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  */
24 #include <linux/list.h>
25 #include <linux/slab.h>
26 #include <drm/drmP.h>
27 #include <linux/firmware.h>
28 #include <drm/amdgpu_drm.h>
29 #include "amdgpu.h"
30 #include "atom.h"
31 #include "amdgpu_ucode.h"
32 
33 struct amdgpu_cgs_device {
34           struct cgs_device base;
35           struct amdgpu_device *adev;
36 };
37 
38 #define CGS_FUNC_ADEV                                                                     \
39           struct amdgpu_device *adev =                                          \
40                     ((struct amdgpu_cgs_device *)cgs_device)->adev
41 
42 
amdgpu_cgs_read_register(struct cgs_device * cgs_device,unsigned offset)43 static uint32_t amdgpu_cgs_read_register(struct cgs_device *cgs_device, unsigned offset)
44 {
45           CGS_FUNC_ADEV;
46           return RREG32(offset);
47 }
48 
amdgpu_cgs_write_register(struct cgs_device * cgs_device,unsigned offset,uint32_t value)49 static void amdgpu_cgs_write_register(struct cgs_device *cgs_device, unsigned offset,
50                                               uint32_t value)
51 {
52           CGS_FUNC_ADEV;
53           WREG32(offset, value);
54 }
55 
amdgpu_cgs_read_ind_register(struct cgs_device * cgs_device,enum cgs_ind_reg space,unsigned index)56 static uint32_t amdgpu_cgs_read_ind_register(struct cgs_device *cgs_device,
57                                                        enum cgs_ind_reg space,
58                                                        unsigned index)
59 {
60           CGS_FUNC_ADEV;
61           switch (space) {
62           case CGS_IND_REG__MMIO:
63                     return RREG32_IDX(index);
64           case CGS_IND_REG__PCIE:
65                     return RREG32_PCIE(index);
66           case CGS_IND_REG__SMC:
67                     return RREG32_SMC(index);
68           case CGS_IND_REG__UVD_CTX:
69                     return RREG32_UVD_CTX(index);
70           case CGS_IND_REG__DIDT:
71                     return RREG32_DIDT(index);
72           case CGS_IND_REG_GC_CAC:
73                     return RREG32_GC_CAC(index);
74           case CGS_IND_REG_SE_CAC:
75                     return RREG32_SE_CAC(index);
76           case CGS_IND_REG__AUDIO_ENDPT:
77                     DRM_ERROR("audio endpt register access not implemented.\n");
78                     return 0;
79           }
80           WARN(1, "Invalid indirect register space");
81           return 0;
82 }
83 
amdgpu_cgs_write_ind_register(struct cgs_device * cgs_device,enum cgs_ind_reg space,unsigned index,uint32_t value)84 static void amdgpu_cgs_write_ind_register(struct cgs_device *cgs_device,
85                                                     enum cgs_ind_reg space,
86                                                     unsigned index, uint32_t value)
87 {
88           CGS_FUNC_ADEV;
89           switch (space) {
90           case CGS_IND_REG__MMIO:
91                     return WREG32_IDX(index, value);
92           case CGS_IND_REG__PCIE:
93                     return WREG32_PCIE(index, value);
94           case CGS_IND_REG__SMC:
95                     return WREG32_SMC(index, value);
96           case CGS_IND_REG__UVD_CTX:
97                     return WREG32_UVD_CTX(index, value);
98           case CGS_IND_REG__DIDT:
99                     return WREG32_DIDT(index, value);
100           case CGS_IND_REG_GC_CAC:
101                     return WREG32_GC_CAC(index, value);
102           case CGS_IND_REG_SE_CAC:
103                     return WREG32_SE_CAC(index, value);
104           case CGS_IND_REG__AUDIO_ENDPT:
105                     DRM_ERROR("audio endpt register access not implemented.\n");
106                     return;
107           }
108           WARN(1, "Invalid indirect register space");
109 }
110 
fw_type_convert(struct cgs_device * cgs_device,uint32_t fw_type)111 static uint32_t fw_type_convert(struct cgs_device *cgs_device, uint32_t fw_type)
112 {
113           CGS_FUNC_ADEV;
114           enum AMDGPU_UCODE_ID result = AMDGPU_UCODE_ID_MAXIMUM;
115 
116           switch (fw_type) {
117           case CGS_UCODE_ID_SDMA0:
118                     result = AMDGPU_UCODE_ID_SDMA0;
119                     break;
120           case CGS_UCODE_ID_SDMA1:
121                     result = AMDGPU_UCODE_ID_SDMA1;
122                     break;
123           case CGS_UCODE_ID_CP_CE:
124                     result = AMDGPU_UCODE_ID_CP_CE;
125                     break;
126           case CGS_UCODE_ID_CP_PFP:
127                     result = AMDGPU_UCODE_ID_CP_PFP;
128                     break;
129           case CGS_UCODE_ID_CP_ME:
130                     result = AMDGPU_UCODE_ID_CP_ME;
131                     break;
132           case CGS_UCODE_ID_CP_MEC:
133           case CGS_UCODE_ID_CP_MEC_JT1:
134                     result = AMDGPU_UCODE_ID_CP_MEC1;
135                     break;
136           case CGS_UCODE_ID_CP_MEC_JT2:
137                     /* for VI. JT2 should be the same as JT1, because:
138                               1, MEC2 and MEC1 use exactly same FW.
139                               2, JT2 is not pached but JT1 is.
140                     */
141                     if (adev->asic_type >= CHIP_TOPAZ)
142                               result = AMDGPU_UCODE_ID_CP_MEC1;
143                     else
144                               result = AMDGPU_UCODE_ID_CP_MEC2;
145                     break;
146           case CGS_UCODE_ID_RLC_G:
147                     result = AMDGPU_UCODE_ID_RLC_G;
148                     break;
149           case CGS_UCODE_ID_STORAGE:
150                     result = AMDGPU_UCODE_ID_STORAGE;
151                     break;
152           default:
153                     DRM_ERROR("Firmware type not supported\n");
154           }
155           return result;
156 }
157 
amdgpu_get_firmware_version(struct cgs_device * cgs_device,enum cgs_ucode_id type)158 static uint16_t amdgpu_get_firmware_version(struct cgs_device *cgs_device,
159                                                   enum cgs_ucode_id type)
160 {
161           CGS_FUNC_ADEV;
162           uint16_t fw_version = 0;
163 
164           switch (type) {
165                     case CGS_UCODE_ID_SDMA0:
166                               fw_version = adev->sdma.instance[0].fw_version;
167                               break;
168                     case CGS_UCODE_ID_SDMA1:
169                               fw_version = adev->sdma.instance[1].fw_version;
170                               break;
171                     case CGS_UCODE_ID_CP_CE:
172                               fw_version = adev->gfx.ce_fw_version;
173                               break;
174                     case CGS_UCODE_ID_CP_PFP:
175                               fw_version = adev->gfx.pfp_fw_version;
176                               break;
177                     case CGS_UCODE_ID_CP_ME:
178                               fw_version = adev->gfx.me_fw_version;
179                               break;
180                     case CGS_UCODE_ID_CP_MEC:
181                               fw_version = adev->gfx.mec_fw_version;
182                               break;
183                     case CGS_UCODE_ID_CP_MEC_JT1:
184                               fw_version = adev->gfx.mec_fw_version;
185                               break;
186                     case CGS_UCODE_ID_CP_MEC_JT2:
187                               fw_version = adev->gfx.mec_fw_version;
188                               break;
189                     case CGS_UCODE_ID_RLC_G:
190                               fw_version = adev->gfx.rlc_fw_version;
191                               break;
192                     case CGS_UCODE_ID_STORAGE:
193                               break;
194                     default:
195                               DRM_ERROR("firmware type %d do not have version\n", type);
196                               break;
197           }
198           return fw_version;
199 }
200 
amdgpu_cgs_get_firmware_info(struct cgs_device * cgs_device,enum cgs_ucode_id type,struct cgs_firmware_info * info)201 static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
202                                                   enum cgs_ucode_id type,
203                                                   struct cgs_firmware_info *info)
204 {
205           CGS_FUNC_ADEV;
206 
207           if ((CGS_UCODE_ID_SMU != type) && (CGS_UCODE_ID_SMU_SK != type)) {
208                     uint64_t gpu_addr;
209                     uint32_t data_size;
210                     const struct gfx_firmware_header_v1_0 *header;
211                     enum AMDGPU_UCODE_ID id;
212                     struct amdgpu_firmware_info *ucode;
213 
214                     id = fw_type_convert(cgs_device, type);
215                     ucode = &adev->firmware.ucode[id];
216                     if (ucode->fw == NULL)
217                               return -EINVAL;
218 
219                     gpu_addr  = ucode->mc_addr;
220                     header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
221                     data_size = le32_to_cpu(header->header.ucode_size_bytes);
222 
223                     if ((type == CGS_UCODE_ID_CP_MEC_JT1) ||
224                         (type == CGS_UCODE_ID_CP_MEC_JT2)) {
225                               gpu_addr += ALIGN(le32_to_cpu(header->header.ucode_size_bytes), PAGE_SIZE);
226                               data_size = le32_to_cpu(header->jt_size) << 2;
227                     }
228 
229                     info->kptr = ucode->kaddr;
230                     info->image_size = data_size;
231                     info->mc_addr = gpu_addr;
232                     info->version = (uint16_t)le32_to_cpu(header->header.ucode_version);
233 
234                     if (CGS_UCODE_ID_CP_MEC == type)
235                               info->image_size = le32_to_cpu(header->jt_offset) << 2;
236 
237                     info->fw_version = amdgpu_get_firmware_version(cgs_device, type);
238                     info->feature_version = (uint16_t)le32_to_cpu(header->ucode_feature_version);
239           } else {
240                     char fw_name[30] = {0};
241                     int err = 0;
242                     uint32_t ucode_size;
243                     uint32_t ucode_start_address;
244                     const uint8_t *src;
245                     const struct smc_firmware_header_v1_0 *hdr;
246                     const struct common_firmware_header *header;
247                     struct amdgpu_firmware_info *ucode = NULL;
248 
249                     if (!adev->pm.fw) {
250                               switch (adev->asic_type) {
251                               case CHIP_TAHITI:
252                                         strcpy(fw_name, "radeon/tahiti_smc.bin");
253                                         break;
254                               case CHIP_PITCAIRN:
255                                         if ((adev->pdev->revision == 0x81) &&
256                                             ((adev->pdev->device == 0x6810) ||
257                                             (adev->pdev->device == 0x6811))) {
258                                                   info->is_kicker = true;
259                                                   strcpy(fw_name, "radeon/pitcairn_k_smc.bin");
260                                         } else {
261                                                   strcpy(fw_name, "radeon/pitcairn_smc.bin");
262                                         }
263                                         break;
264                               case CHIP_VERDE:
265                                         if (((adev->pdev->device == 0x6820) &&
266                                                   ((adev->pdev->revision == 0x81) ||
267                                                   (adev->pdev->revision == 0x83))) ||
268                                             ((adev->pdev->device == 0x6821) &&
269                                                   ((adev->pdev->revision == 0x83) ||
270                                                   (adev->pdev->revision == 0x87))) ||
271                                             ((adev->pdev->revision == 0x87) &&
272                                                   ((adev->pdev->device == 0x6823) ||
273                                                   (adev->pdev->device == 0x682b)))) {
274                                                   info->is_kicker = true;
275                                                   strcpy(fw_name, "radeon/verde_k_smc.bin");
276                                         } else {
277                                                   strcpy(fw_name, "radeon/verde_smc.bin");
278                                         }
279                                         break;
280                               case CHIP_OLAND:
281                                         if (((adev->pdev->revision == 0x81) &&
282                                                   ((adev->pdev->device == 0x6600) ||
283                                                   (adev->pdev->device == 0x6604) ||
284                                                   (adev->pdev->device == 0x6605) ||
285                                                   (adev->pdev->device == 0x6610))) ||
286                                             ((adev->pdev->revision == 0x83) &&
287                                                   (adev->pdev->device == 0x6610))) {
288                                                   info->is_kicker = true;
289                                                   strcpy(fw_name, "radeon/oland_k_smc.bin");
290                                         } else {
291                                                   strcpy(fw_name, "radeon/oland_smc.bin");
292                                         }
293                                         break;
294                               case CHIP_HAINAN:
295                                         if (((adev->pdev->revision == 0x81) &&
296                                                   (adev->pdev->device == 0x6660)) ||
297                                             ((adev->pdev->revision == 0x83) &&
298                                                   ((adev->pdev->device == 0x6660) ||
299                                                   (adev->pdev->device == 0x6663) ||
300                                                   (adev->pdev->device == 0x6665) ||
301                                                    (adev->pdev->device == 0x6667)))) {
302                                                   info->is_kicker = true;
303                                                   strcpy(fw_name, "radeon/hainan_k_smc.bin");
304                                         } else if ((adev->pdev->revision == 0xc3) &&
305                                                    (adev->pdev->device == 0x6665)) {
306                                                   info->is_kicker = true;
307                                                   strcpy(fw_name, "radeon/banks_k_2_smc.bin");
308                                         } else {
309                                                   strcpy(fw_name, "radeon/hainan_smc.bin");
310                                         }
311                                         break;
312                               case CHIP_BONAIRE:
313                                         if ((adev->pdev->revision == 0x80) ||
314                                                   (adev->pdev->revision == 0x81) ||
315                                                   (adev->pdev->device == 0x665f)) {
316                                                   info->is_kicker = true;
317                                                   strcpy(fw_name, "amdgpufw_bonaire_k_smc");
318                                         } else {
319                                                   strcpy(fw_name, "amdgpufw_bonaire_smc");
320                                         }
321                                         break;
322                               case CHIP_HAWAII:
323                                         if (adev->pdev->revision == 0x80) {
324                                                   info->is_kicker = true;
325                                                   strcpy(fw_name, "amdgpufw_hawaii_k_smc");
326                                         } else {
327                                                   strcpy(fw_name, "amdgpufw_hawaii_smc");
328                                         }
329                                         break;
330                               case CHIP_TOPAZ:
331                                         if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) ||
332                                             ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) ||
333                                             ((adev->pdev->device == 0x6907) && (adev->pdev->revision == 0x87)) ||
334                                             ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD1)) ||
335                                             ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD3))) {
336                                                   info->is_kicker = true;
337                                                   strcpy(fw_name, "amdgpufw_topaz_k_smc");
338                                         } else
339                                                   strcpy(fw_name, "amdgpufw_topaz_smc");
340                                         break;
341                               case CHIP_TONGA:
342                                         if (((adev->pdev->device == 0x6939) && (adev->pdev->revision == 0xf1)) ||
343                                             ((adev->pdev->device == 0x6938) && (adev->pdev->revision == 0xf1))) {
344                                                   info->is_kicker = true;
345                                                   strcpy(fw_name, "amdgpufw_tonga_k_smc");
346                                         } else
347                                                   strcpy(fw_name, "amdgpufw_tonga_smc");
348                                         break;
349                               case CHIP_FIJI:
350                                         strcpy(fw_name, "amdgpufw_fiji_smc");
351                                         break;
352                               case CHIP_POLARIS11:
353                                         if (type == CGS_UCODE_ID_SMU) {
354                                                   if (((adev->pdev->device == 0x67ef) &&
355                                                        ((adev->pdev->revision == 0xe0) ||
356                                                         (adev->pdev->revision == 0xe5))) ||
357                                                       ((adev->pdev->device == 0x67ff) &&
358                                                        ((adev->pdev->revision == 0xcf) ||
359                                                         (adev->pdev->revision == 0xef) ||
360                                                         (adev->pdev->revision == 0xff)))) {
361                                                             info->is_kicker = true;
362                                                             strcpy(fw_name, "amdgpufw_polaris11_k_smc");
363                                                   } else if ((adev->pdev->device == 0x67ef) &&
364                                                                (adev->pdev->revision == 0xe2)) {
365                                                             info->is_kicker = true;
366                                                             strcpy(fw_name, "amdgpufw_polaris11_k2_smc");
367                                                   } else {
368                                                             strcpy(fw_name, "amdgpufw_polaris11_smc");
369                                                   }
370                                         } else if (type == CGS_UCODE_ID_SMU_SK) {
371                                                   strcpy(fw_name, "amdgpufw_polaris11_smc_sk");
372                                         }
373                                         break;
374                               case CHIP_POLARIS10:
375                                         if (type == CGS_UCODE_ID_SMU) {
376                                                   if (((adev->pdev->device == 0x67df) &&
377                                                        ((adev->pdev->revision == 0xe0) ||
378                                                         (adev->pdev->revision == 0xe3) ||
379                                                         (adev->pdev->revision == 0xe4) ||
380                                                         (adev->pdev->revision == 0xe5) ||
381                                                         (adev->pdev->revision == 0xe7) ||
382                                                         (adev->pdev->revision == 0xef))) ||
383                                                       ((adev->pdev->device == 0x6fdf) &&
384                                                        ((adev->pdev->revision == 0xef) ||
385                                                         (adev->pdev->revision == 0xff)))) {
386                                                             info->is_kicker = true;
387                                                             strcpy(fw_name, "amdgpufw_polaris10_k_smc");
388                                                   } else if ((adev->pdev->device == 0x67df) &&
389                                                                ((adev->pdev->revision == 0xe1) ||
390                                                                 (adev->pdev->revision == 0xf7))) {
391                                                             info->is_kicker = true;
392                                                             strcpy(fw_name, "amdgpufw_polaris10_k2_smc");
393                                                   } else {
394                                                             strcpy(fw_name, "amdgpufw_polaris10_smc");
395                                                   }
396                                         } else if (type == CGS_UCODE_ID_SMU_SK) {
397                                                   strcpy(fw_name, "amdgpufw_polaris10_smc_sk");
398                                         }
399                                         break;
400                               case CHIP_POLARIS12:
401                                         if (((adev->pdev->device == 0x6987) &&
402                                              ((adev->pdev->revision == 0xc0) ||
403                                               (adev->pdev->revision == 0xc3))) ||
404                                             ((adev->pdev->device == 0x6981) &&
405                                              ((adev->pdev->revision == 0x00) ||
406                                               (adev->pdev->revision == 0x01) ||
407                                               (adev->pdev->revision == 0x10)))) {
408                                                   info->is_kicker = true;
409                                                   strcpy(fw_name, "amdgpufw_polaris12_k_smc");
410                                         } else {
411                                                   strcpy(fw_name, "amdgpufw_polaris12_smc");
412                                         }
413                                         break;
414                               case CHIP_VEGAM:
415                                         strcpy(fw_name, "amdgpufw_vegam_smc");
416                                         break;
417                               case CHIP_VEGA10:
418                                         if ((adev->pdev->device == 0x687f) &&
419                                                   ((adev->pdev->revision == 0xc0) ||
420                                                   (adev->pdev->revision == 0xc1) ||
421                                                   (adev->pdev->revision == 0xc3)))
422                                                   strcpy(fw_name, "amdgpufw_vega10_acg_smc");
423                                         else
424                                                   strcpy(fw_name, "amdgpufw_vega10_smc");
425                                         break;
426                               case CHIP_VEGA12:
427                                         strcpy(fw_name, "amdgpufw_vega12_smc");
428                                         break;
429                               case CHIP_VEGA20:
430                                         strcpy(fw_name, "amdgpufw_vega20_smc");
431                                         break;
432                               default:
433                                         DRM_ERROR("SMC firmware not supported\n");
434                                         return -EINVAL;
435                               }
436 
437                               err = request_firmware(&adev->pm.fw, fw_name, adev->dev);
438                               if (err) {
439                                         DRM_ERROR("Failed to request firmware\n");
440                                         return err;
441                               }
442 
443                               err = amdgpu_ucode_validate(adev->pm.fw);
444                               if (err) {
445                                         DRM_ERROR("Failed to load firmware \"%s\"", fw_name);
446                                         release_firmware(adev->pm.fw);
447                                         adev->pm.fw = NULL;
448                                         return err;
449                               }
450 
451                               if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
452                                         ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC];
453                                         ucode->ucode_id = AMDGPU_UCODE_ID_SMC;
454                                         ucode->fw = adev->pm.fw;
455                                         header = (const struct common_firmware_header *)ucode->fw->data;
456                                         adev->firmware.fw_size +=
457                                                   ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
458                               }
459                     }
460 
461                     hdr = (const struct smc_firmware_header_v1_0 *)   adev->pm.fw->data;
462                     amdgpu_ucode_print_smc_hdr(&hdr->header);
463                     adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version);
464                     ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
465                     ucode_start_address = le32_to_cpu(hdr->ucode_start_addr);
466                     src = (const uint8_t *)(adev->pm.fw->data +
467                            le32_to_cpu(hdr->header.ucode_array_offset_bytes));
468 
469                     info->version = adev->pm.fw_version;
470                     info->image_size = ucode_size;
471                     info->ucode_start_address = ucode_start_address;
472                     info->kptr = (void *)src;
473           }
474           return 0;
475 }
476 
477 static const struct cgs_ops amdgpu_cgs_ops = {
478           .read_register = amdgpu_cgs_read_register,
479           .write_register = amdgpu_cgs_write_register,
480           .read_ind_register = amdgpu_cgs_read_ind_register,
481           .write_ind_register = amdgpu_cgs_write_ind_register,
482           .get_firmware_info = amdgpu_cgs_get_firmware_info,
483 };
484 
amdgpu_cgs_create_device(struct amdgpu_device * adev)485 struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev)
486 {
487           struct amdgpu_cgs_device *cgs_device =
488                     kmalloc(sizeof(*cgs_device), M_DRM, GFP_KERNEL);
489 
490           if (!cgs_device) {
491                     DRM_ERROR("Couldn't allocate CGS device structure\n");
492                     return NULL;
493           }
494 
495           cgs_device->base.ops = &amdgpu_cgs_ops;
496           cgs_device->adev = adev;
497 
498           return (struct cgs_device *)cgs_device;
499 }
500 
amdgpu_cgs_destroy_device(struct cgs_device * cgs_device)501 void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device)
502 {
503           kfree(cgs_device);
504 }
505