0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
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
0139
0140
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 }