Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2015 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  *
0023  */
0024 #include <linux/list.h>
0025 #include <linux/pci.h>
0026 #include <linux/slab.h>
0027 
0028 #include <linux/firmware.h>
0029 #include <drm/amdgpu_drm.h>
0030 #include "amdgpu.h"
0031 #include "atom.h"
0032 #include "amdgpu_ucode.h"
0033 
0034 struct amdgpu_cgs_device {
0035     struct cgs_device base;
0036     struct amdgpu_device *adev;
0037 };
0038 
0039 #define CGS_FUNC_ADEV                           \
0040     struct amdgpu_device *adev =                    \
0041         ((struct amdgpu_cgs_device *)cgs_device)->adev
0042 
0043 
0044 static uint32_t amdgpu_cgs_read_register(struct cgs_device *cgs_device, unsigned offset)
0045 {
0046     CGS_FUNC_ADEV;
0047     return RREG32(offset);
0048 }
0049 
0050 static void amdgpu_cgs_write_register(struct cgs_device *cgs_device, unsigned offset,
0051                       uint32_t value)
0052 {
0053     CGS_FUNC_ADEV;
0054     WREG32(offset, value);
0055 }
0056 
0057 static uint32_t amdgpu_cgs_read_ind_register(struct cgs_device *cgs_device,
0058                          enum cgs_ind_reg space,
0059                          unsigned index)
0060 {
0061     CGS_FUNC_ADEV;
0062     switch (space) {
0063     case CGS_IND_REG__PCIE:
0064         return RREG32_PCIE(index);
0065     case CGS_IND_REG__SMC:
0066         return RREG32_SMC(index);
0067     case CGS_IND_REG__UVD_CTX:
0068         return RREG32_UVD_CTX(index);
0069     case CGS_IND_REG__DIDT:
0070         return RREG32_DIDT(index);
0071     case CGS_IND_REG_GC_CAC:
0072         return RREG32_GC_CAC(index);
0073     case CGS_IND_REG_SE_CAC:
0074         return RREG32_SE_CAC(index);
0075     case CGS_IND_REG__AUDIO_ENDPT:
0076         DRM_ERROR("audio endpt register access not implemented.\n");
0077         return 0;
0078     default:
0079         BUG();
0080     }
0081     WARN(1, "Invalid indirect register space");
0082     return 0;
0083 }
0084 
0085 static void amdgpu_cgs_write_ind_register(struct cgs_device *cgs_device,
0086                       enum cgs_ind_reg space,
0087                       unsigned index, uint32_t value)
0088 {
0089     CGS_FUNC_ADEV;
0090     switch (space) {
0091     case CGS_IND_REG__PCIE:
0092         return WREG32_PCIE(index, value);
0093     case CGS_IND_REG__SMC:
0094         return WREG32_SMC(index, value);
0095     case CGS_IND_REG__UVD_CTX:
0096         return WREG32_UVD_CTX(index, value);
0097     case CGS_IND_REG__DIDT:
0098         return WREG32_DIDT(index, value);
0099     case CGS_IND_REG_GC_CAC:
0100         return WREG32_GC_CAC(index, value);
0101     case CGS_IND_REG_SE_CAC:
0102         return WREG32_SE_CAC(index, value);
0103     case CGS_IND_REG__AUDIO_ENDPT:
0104         DRM_ERROR("audio endpt register access not implemented.\n");
0105         return;
0106     default:
0107         BUG();
0108     }
0109     WARN(1, "Invalid indirect register space");
0110 }
0111 
0112 static uint32_t fw_type_convert(struct cgs_device *cgs_device, uint32_t fw_type)
0113 {
0114     CGS_FUNC_ADEV;
0115     enum AMDGPU_UCODE_ID result = AMDGPU_UCODE_ID_MAXIMUM;
0116 
0117     switch (fw_type) {
0118     case CGS_UCODE_ID_SDMA0:
0119         result = AMDGPU_UCODE_ID_SDMA0;
0120         break;
0121     case CGS_UCODE_ID_SDMA1:
0122         result = AMDGPU_UCODE_ID_SDMA1;
0123         break;
0124     case CGS_UCODE_ID_CP_CE:
0125         result = AMDGPU_UCODE_ID_CP_CE;
0126         break;
0127     case CGS_UCODE_ID_CP_PFP:
0128         result = AMDGPU_UCODE_ID_CP_PFP;
0129         break;
0130     case CGS_UCODE_ID_CP_ME:
0131         result = AMDGPU_UCODE_ID_CP_ME;
0132         break;
0133     case CGS_UCODE_ID_CP_MEC:
0134     case CGS_UCODE_ID_CP_MEC_JT1:
0135         result = AMDGPU_UCODE_ID_CP_MEC1;
0136         break;
0137     case CGS_UCODE_ID_CP_MEC_JT2:
0138         /* for VI. JT2 should be the same as JT1, because:
0139             1, MEC2 and MEC1 use exactly same FW.
0140             2, JT2 is not pached but JT1 is.
0141         */
0142         if (adev->asic_type >= CHIP_TOPAZ)
0143             result = AMDGPU_UCODE_ID_CP_MEC1;
0144         else
0145             result = AMDGPU_UCODE_ID_CP_MEC2;
0146         break;
0147     case CGS_UCODE_ID_RLC_G:
0148         result = AMDGPU_UCODE_ID_RLC_G;
0149         break;
0150     case CGS_UCODE_ID_STORAGE:
0151         result = AMDGPU_UCODE_ID_STORAGE;
0152         break;
0153     default:
0154         DRM_ERROR("Firmware type not supported\n");
0155     }
0156     return result;
0157 }
0158 
0159 static uint16_t amdgpu_get_firmware_version(struct cgs_device *cgs_device,
0160                     enum cgs_ucode_id type)
0161 {
0162     CGS_FUNC_ADEV;
0163     uint16_t fw_version = 0;
0164 
0165     switch (type) {
0166         case CGS_UCODE_ID_SDMA0:
0167             fw_version = adev->sdma.instance[0].fw_version;
0168             break;
0169         case CGS_UCODE_ID_SDMA1:
0170             fw_version = adev->sdma.instance[1].fw_version;
0171             break;
0172         case CGS_UCODE_ID_CP_CE:
0173             fw_version = adev->gfx.ce_fw_version;
0174             break;
0175         case CGS_UCODE_ID_CP_PFP:
0176             fw_version = adev->gfx.pfp_fw_version;
0177             break;
0178         case CGS_UCODE_ID_CP_ME:
0179             fw_version = adev->gfx.me_fw_version;
0180             break;
0181         case CGS_UCODE_ID_CP_MEC:
0182             fw_version = adev->gfx.mec_fw_version;
0183             break;
0184         case CGS_UCODE_ID_CP_MEC_JT1:
0185             fw_version = adev->gfx.mec_fw_version;
0186             break;
0187         case CGS_UCODE_ID_CP_MEC_JT2:
0188             fw_version = adev->gfx.mec_fw_version;
0189             break;
0190         case CGS_UCODE_ID_RLC_G:
0191             fw_version = adev->gfx.rlc_fw_version;
0192             break;
0193         case CGS_UCODE_ID_STORAGE:
0194             break;
0195         default:
0196             DRM_ERROR("firmware type %d do not have version\n", type);
0197             break;
0198     }
0199     return fw_version;
0200 }
0201 
0202 static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
0203                     enum cgs_ucode_id type,
0204                     struct cgs_firmware_info *info)
0205 {
0206     CGS_FUNC_ADEV;
0207 
0208     if ((CGS_UCODE_ID_SMU != type) && (CGS_UCODE_ID_SMU_SK != type)) {
0209         uint64_t gpu_addr;
0210         uint32_t data_size;
0211         const struct gfx_firmware_header_v1_0 *header;
0212         enum AMDGPU_UCODE_ID id;
0213         struct amdgpu_firmware_info *ucode;
0214 
0215         id = fw_type_convert(cgs_device, type);
0216         ucode = &adev->firmware.ucode[id];
0217         if (ucode->fw == NULL)
0218             return -EINVAL;
0219 
0220         gpu_addr  = ucode->mc_addr;
0221         header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
0222         data_size = le32_to_cpu(header->header.ucode_size_bytes);
0223 
0224         if ((type == CGS_UCODE_ID_CP_MEC_JT1) ||
0225             (type == CGS_UCODE_ID_CP_MEC_JT2)) {
0226             gpu_addr += ALIGN(le32_to_cpu(header->header.ucode_size_bytes), PAGE_SIZE);
0227             data_size = le32_to_cpu(header->jt_size) << 2;
0228         }
0229 
0230         info->kptr = ucode->kaddr;
0231         info->image_size = data_size;
0232         info->mc_addr = gpu_addr;
0233         info->version = (uint16_t)le32_to_cpu(header->header.ucode_version);
0234 
0235         if (CGS_UCODE_ID_CP_MEC == type)
0236             info->image_size = le32_to_cpu(header->jt_offset) << 2;
0237 
0238         info->fw_version = amdgpu_get_firmware_version(cgs_device, type);
0239         info->feature_version = (uint16_t)le32_to_cpu(header->ucode_feature_version);
0240     } else {
0241         char fw_name[30] = {0};
0242         int err = 0;
0243         uint32_t ucode_size;
0244         uint32_t ucode_start_address;
0245         const uint8_t *src;
0246         const struct smc_firmware_header_v1_0 *hdr;
0247         const struct common_firmware_header *header;
0248         struct amdgpu_firmware_info *ucode = NULL;
0249 
0250         if (!adev->pm.fw) {
0251             switch (adev->asic_type) {
0252             case CHIP_TAHITI:
0253                 strcpy(fw_name, "radeon/tahiti_smc.bin");
0254                 break;
0255             case CHIP_PITCAIRN:
0256                 if ((adev->pdev->revision == 0x81) &&
0257                     ((adev->pdev->device == 0x6810) ||
0258                     (adev->pdev->device == 0x6811))) {
0259                     info->is_kicker = true;
0260                     strcpy(fw_name, "radeon/pitcairn_k_smc.bin");
0261                 } else {
0262                     strcpy(fw_name, "radeon/pitcairn_smc.bin");
0263                 }
0264                 break;
0265             case CHIP_VERDE:
0266                 if (((adev->pdev->device == 0x6820) &&
0267                     ((adev->pdev->revision == 0x81) ||
0268                     (adev->pdev->revision == 0x83))) ||
0269                     ((adev->pdev->device == 0x6821) &&
0270                     ((adev->pdev->revision == 0x83) ||
0271                     (adev->pdev->revision == 0x87))) ||
0272                     ((adev->pdev->revision == 0x87) &&
0273                     ((adev->pdev->device == 0x6823) ||
0274                     (adev->pdev->device == 0x682b)))) {
0275                     info->is_kicker = true;
0276                     strcpy(fw_name, "radeon/verde_k_smc.bin");
0277                 } else {
0278                     strcpy(fw_name, "radeon/verde_smc.bin");
0279                 }
0280                 break;
0281             case CHIP_OLAND:
0282                 if (((adev->pdev->revision == 0x81) &&
0283                     ((adev->pdev->device == 0x6600) ||
0284                     (adev->pdev->device == 0x6604) ||
0285                     (adev->pdev->device == 0x6605) ||
0286                     (adev->pdev->device == 0x6610))) ||
0287                     ((adev->pdev->revision == 0x83) &&
0288                     (adev->pdev->device == 0x6610))) {
0289                     info->is_kicker = true;
0290                     strcpy(fw_name, "radeon/oland_k_smc.bin");
0291                 } else {
0292                     strcpy(fw_name, "radeon/oland_smc.bin");
0293                 }
0294                 break;
0295             case CHIP_HAINAN:
0296                 if (((adev->pdev->revision == 0x81) &&
0297                     (adev->pdev->device == 0x6660)) ||
0298                     ((adev->pdev->revision == 0x83) &&
0299                     ((adev->pdev->device == 0x6660) ||
0300                     (adev->pdev->device == 0x6663) ||
0301                     (adev->pdev->device == 0x6665) ||
0302                      (adev->pdev->device == 0x6667)))) {
0303                     info->is_kicker = true;
0304                     strcpy(fw_name, "radeon/hainan_k_smc.bin");
0305                 } else if ((adev->pdev->revision == 0xc3) &&
0306                      (adev->pdev->device == 0x6665)) {
0307                     info->is_kicker = true;
0308                     strcpy(fw_name, "radeon/banks_k_2_smc.bin");
0309                 } else {
0310                     strcpy(fw_name, "radeon/hainan_smc.bin");
0311                 }
0312                 break;
0313             case CHIP_BONAIRE:
0314                 if ((adev->pdev->revision == 0x80) ||
0315                     (adev->pdev->revision == 0x81) ||
0316                     (adev->pdev->device == 0x665f)) {
0317                     info->is_kicker = true;
0318                     strcpy(fw_name, "amdgpu/bonaire_k_smc.bin");
0319                 } else {
0320                     strcpy(fw_name, "amdgpu/bonaire_smc.bin");
0321                 }
0322                 break;
0323             case CHIP_HAWAII:
0324                 if (adev->pdev->revision == 0x80) {
0325                     info->is_kicker = true;
0326                     strcpy(fw_name, "amdgpu/hawaii_k_smc.bin");
0327                 } else {
0328                     strcpy(fw_name, "amdgpu/hawaii_smc.bin");
0329                 }
0330                 break;
0331             case CHIP_TOPAZ:
0332                 if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) ||
0333                     ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) ||
0334                     ((adev->pdev->device == 0x6907) && (adev->pdev->revision == 0x87)) ||
0335                     ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD1)) ||
0336                     ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD3))) {
0337                     info->is_kicker = true;
0338                     strcpy(fw_name, "amdgpu/topaz_k_smc.bin");
0339                 } else
0340                     strcpy(fw_name, "amdgpu/topaz_smc.bin");
0341                 break;
0342             case CHIP_TONGA:
0343                 if (((adev->pdev->device == 0x6939) && (adev->pdev->revision == 0xf1)) ||
0344                     ((adev->pdev->device == 0x6938) && (adev->pdev->revision == 0xf1))) {
0345                     info->is_kicker = true;
0346                     strcpy(fw_name, "amdgpu/tonga_k_smc.bin");
0347                 } else
0348                     strcpy(fw_name, "amdgpu/tonga_smc.bin");
0349                 break;
0350             case CHIP_FIJI:
0351                 strcpy(fw_name, "amdgpu/fiji_smc.bin");
0352                 break;
0353             case CHIP_POLARIS11:
0354                 if (type == CGS_UCODE_ID_SMU) {
0355                     if (ASICID_IS_P21(adev->pdev->device, adev->pdev->revision)) {
0356                         info->is_kicker = true;
0357                         strcpy(fw_name, "amdgpu/polaris11_k_smc.bin");
0358                     } else if (ASICID_IS_P31(adev->pdev->device, adev->pdev->revision)) {
0359                         info->is_kicker = true;
0360                         strcpy(fw_name, "amdgpu/polaris11_k2_smc.bin");
0361                     } else {
0362                         strcpy(fw_name, "amdgpu/polaris11_smc.bin");
0363                     }
0364                 } else if (type == CGS_UCODE_ID_SMU_SK) {
0365                     strcpy(fw_name, "amdgpu/polaris11_smc_sk.bin");
0366                 }
0367                 break;
0368             case CHIP_POLARIS10:
0369                 if (type == CGS_UCODE_ID_SMU) {
0370                     if (ASICID_IS_P20(adev->pdev->device, adev->pdev->revision)) {
0371                         info->is_kicker = true;
0372                         strcpy(fw_name, "amdgpu/polaris10_k_smc.bin");
0373                     } else if (ASICID_IS_P30(adev->pdev->device, adev->pdev->revision)) {
0374                         info->is_kicker = true;
0375                         strcpy(fw_name, "amdgpu/polaris10_k2_smc.bin");
0376                     } else {
0377                         strcpy(fw_name, "amdgpu/polaris10_smc.bin");
0378                     }
0379                 } else if (type == CGS_UCODE_ID_SMU_SK) {
0380                     strcpy(fw_name, "amdgpu/polaris10_smc_sk.bin");
0381                 }
0382                 break;
0383             case CHIP_POLARIS12:
0384                 if (ASICID_IS_P23(adev->pdev->device, adev->pdev->revision)) {
0385                     info->is_kicker = true;
0386                     strcpy(fw_name, "amdgpu/polaris12_k_smc.bin");
0387                 } else {
0388                     strcpy(fw_name, "amdgpu/polaris12_smc.bin");
0389                 }
0390                 break;
0391             case CHIP_VEGAM:
0392                 strcpy(fw_name, "amdgpu/vegam_smc.bin");
0393                 break;
0394             case CHIP_VEGA10:
0395                 if ((adev->pdev->device == 0x687f) &&
0396                     ((adev->pdev->revision == 0xc0) ||
0397                     (adev->pdev->revision == 0xc1) ||
0398                     (adev->pdev->revision == 0xc3)))
0399                     strcpy(fw_name, "amdgpu/vega10_acg_smc.bin");
0400                 else
0401                     strcpy(fw_name, "amdgpu/vega10_smc.bin");
0402                 break;
0403             case CHIP_VEGA12:
0404                 strcpy(fw_name, "amdgpu/vega12_smc.bin");
0405                 break;
0406             case CHIP_VEGA20:
0407                 strcpy(fw_name, "amdgpu/vega20_smc.bin");
0408                 break;
0409             default:
0410                 DRM_ERROR("SMC firmware not supported\n");
0411                 return -EINVAL;
0412             }
0413 
0414             err = request_firmware(&adev->pm.fw, fw_name, adev->dev);
0415             if (err) {
0416                 DRM_ERROR("Failed to request firmware\n");
0417                 return err;
0418             }
0419 
0420             err = amdgpu_ucode_validate(adev->pm.fw);
0421             if (err) {
0422                 DRM_ERROR("Failed to load firmware \"%s\"", fw_name);
0423                 release_firmware(adev->pm.fw);
0424                 adev->pm.fw = NULL;
0425                 return err;
0426             }
0427 
0428             if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
0429                 ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC];
0430                 ucode->ucode_id = AMDGPU_UCODE_ID_SMC;
0431                 ucode->fw = adev->pm.fw;
0432                 header = (const struct common_firmware_header *)ucode->fw->data;
0433                 adev->firmware.fw_size +=
0434                     ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
0435             }
0436         }
0437 
0438         hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data;
0439         amdgpu_ucode_print_smc_hdr(&hdr->header);
0440         adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version);
0441         ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
0442         ucode_start_address = le32_to_cpu(hdr->ucode_start_addr);
0443         src = (const uint8_t *)(adev->pm.fw->data +
0444                le32_to_cpu(hdr->header.ucode_array_offset_bytes));
0445 
0446         info->version = adev->pm.fw_version;
0447         info->image_size = ucode_size;
0448         info->ucode_start_address = ucode_start_address;
0449         info->kptr = (void *)src;
0450     }
0451     return 0;
0452 }
0453 
0454 static const struct cgs_ops amdgpu_cgs_ops = {
0455     .read_register = amdgpu_cgs_read_register,
0456     .write_register = amdgpu_cgs_write_register,
0457     .read_ind_register = amdgpu_cgs_read_ind_register,
0458     .write_ind_register = amdgpu_cgs_write_ind_register,
0459     .get_firmware_info = amdgpu_cgs_get_firmware_info,
0460 };
0461 
0462 struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev)
0463 {
0464     struct amdgpu_cgs_device *cgs_device =
0465         kmalloc(sizeof(*cgs_device), GFP_KERNEL);
0466 
0467     if (!cgs_device) {
0468         DRM_ERROR("Couldn't allocate CGS device structure\n");
0469         return NULL;
0470     }
0471 
0472     cgs_device->base.ops = &amdgpu_cgs_ops;
0473     cgs_device->adev = adev;
0474 
0475     return (struct cgs_device *)cgs_device;
0476 }
0477 
0478 void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device)
0479 {
0480     kfree(cgs_device);
0481 }