1 /* $NetBSD: amdgpu_cgs.c,v 1.7 2021/12/19 10:59:01 riastradh Exp $ */ 2 3 /* 4 * Copyright 2015 Advanced Micro Devices, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * 25 */ 26 #include <sys/cdefs.h> 27 __KERNEL_RCSID(0, "$NetBSD: amdgpu_cgs.c,v 1.7 2021/12/19 10:59:01 riastradh Exp $"); 28 29 #include <linux/list.h> 30 #include <linux/pci.h> 31 #include <linux/slab.h> 32 33 #include <linux/firmware.h> 34 #include <drm/amdgpu_drm.h> 35 #include "amdgpu.h" 36 #include "atom.h" 37 #include "amdgpu_ucode.h" 38 39 #include <linux/nbsd-namespace.h> 40 41 struct amdgpu_cgs_device { 42 struct cgs_device base; 43 struct amdgpu_device *adev; 44 }; 45 46 #define CGS_FUNC_ADEV \ 47 struct amdgpu_device *adev = \ 48 ((struct amdgpu_cgs_device *)cgs_device)->adev 49 50 51 static uint32_t amdgpu_cgs_read_register(struct cgs_device *cgs_device, unsigned offset) 52 { 53 CGS_FUNC_ADEV; 54 return RREG32(offset); 55 } 56 57 static void amdgpu_cgs_write_register(struct cgs_device *cgs_device, unsigned offset, 58 uint32_t value) 59 { 60 CGS_FUNC_ADEV; 61 WREG32(offset, value); 62 } 63 64 static uint32_t amdgpu_cgs_read_ind_register(struct cgs_device *cgs_device, 65 enum cgs_ind_reg space, 66 unsigned index) 67 { 68 CGS_FUNC_ADEV; 69 switch (space) { 70 case CGS_IND_REG__MMIO: 71 return RREG32_IDX(index); 72 case CGS_IND_REG__PCIE: 73 return RREG32_PCIE(index); 74 case CGS_IND_REG__SMC: 75 return RREG32_SMC(index); 76 case CGS_IND_REG__UVD_CTX: 77 return RREG32_UVD_CTX(index); 78 case CGS_IND_REG__DIDT: 79 return RREG32_DIDT(index); 80 case CGS_IND_REG_GC_CAC: 81 return RREG32_GC_CAC(index); 82 case CGS_IND_REG_SE_CAC: 83 return RREG32_SE_CAC(index); 84 case CGS_IND_REG__AUDIO_ENDPT: 85 DRM_ERROR("audio endpt register access not implemented.\n"); 86 return 0; 87 } 88 WARN(1, "Invalid indirect register space"); 89 return 0; 90 } 91 92 static void amdgpu_cgs_write_ind_register(struct cgs_device *cgs_device, 93 enum cgs_ind_reg space, 94 unsigned index, uint32_t value) 95 { 96 CGS_FUNC_ADEV; 97 switch (space) { 98 case CGS_IND_REG__MMIO: 99 return WREG32_IDX(index, value); 100 case CGS_IND_REG__PCIE: 101 return WREG32_PCIE(index, value); 102 case CGS_IND_REG__SMC: 103 return WREG32_SMC(index, value); 104 case CGS_IND_REG__UVD_CTX: 105 return WREG32_UVD_CTX(index, value); 106 case CGS_IND_REG__DIDT: 107 return WREG32_DIDT(index, value); 108 case CGS_IND_REG_GC_CAC: 109 return WREG32_GC_CAC(index, value); 110 case CGS_IND_REG_SE_CAC: 111 return WREG32_SE_CAC(index, value); 112 case CGS_IND_REG__AUDIO_ENDPT: 113 DRM_ERROR("audio endpt register access not implemented.\n"); 114 return; 115 } 116 WARN(1, "Invalid indirect register space"); 117 } 118 119 static uint32_t fw_type_convert(struct cgs_device *cgs_device, uint32_t fw_type) 120 { 121 CGS_FUNC_ADEV; 122 enum AMDGPU_UCODE_ID result = AMDGPU_UCODE_ID_MAXIMUM; 123 124 switch (fw_type) { 125 case CGS_UCODE_ID_SDMA0: 126 result = AMDGPU_UCODE_ID_SDMA0; 127 break; 128 case CGS_UCODE_ID_SDMA1: 129 result = AMDGPU_UCODE_ID_SDMA1; 130 break; 131 case CGS_UCODE_ID_CP_CE: 132 result = AMDGPU_UCODE_ID_CP_CE; 133 break; 134 case CGS_UCODE_ID_CP_PFP: 135 result = AMDGPU_UCODE_ID_CP_PFP; 136 break; 137 case CGS_UCODE_ID_CP_ME: 138 result = AMDGPU_UCODE_ID_CP_ME; 139 break; 140 case CGS_UCODE_ID_CP_MEC: 141 case CGS_UCODE_ID_CP_MEC_JT1: 142 result = AMDGPU_UCODE_ID_CP_MEC1; 143 break; 144 case CGS_UCODE_ID_CP_MEC_JT2: 145 /* for VI. JT2 should be the same as JT1, because: 146 1, MEC2 and MEC1 use exactly same FW. 147 2, JT2 is not pached but JT1 is. 148 */ 149 if (adev->asic_type >= CHIP_TOPAZ) 150 result = AMDGPU_UCODE_ID_CP_MEC1; 151 else 152 result = AMDGPU_UCODE_ID_CP_MEC2; 153 break; 154 case CGS_UCODE_ID_RLC_G: 155 result = AMDGPU_UCODE_ID_RLC_G; 156 break; 157 case CGS_UCODE_ID_STORAGE: 158 result = AMDGPU_UCODE_ID_STORAGE; 159 break; 160 default: 161 DRM_ERROR("Firmware type not supported\n"); 162 } 163 return result; 164 } 165 166 static uint16_t amdgpu_get_firmware_version(struct cgs_device *cgs_device, 167 enum cgs_ucode_id type) 168 { 169 CGS_FUNC_ADEV; 170 uint16_t fw_version = 0; 171 172 switch (type) { 173 case CGS_UCODE_ID_SDMA0: 174 fw_version = adev->sdma.instance[0].fw_version; 175 break; 176 case CGS_UCODE_ID_SDMA1: 177 fw_version = adev->sdma.instance[1].fw_version; 178 break; 179 case CGS_UCODE_ID_CP_CE: 180 fw_version = adev->gfx.ce_fw_version; 181 break; 182 case CGS_UCODE_ID_CP_PFP: 183 fw_version = adev->gfx.pfp_fw_version; 184 break; 185 case CGS_UCODE_ID_CP_ME: 186 fw_version = adev->gfx.me_fw_version; 187 break; 188 case CGS_UCODE_ID_CP_MEC: 189 fw_version = adev->gfx.mec_fw_version; 190 break; 191 case CGS_UCODE_ID_CP_MEC_JT1: 192 fw_version = adev->gfx.mec_fw_version; 193 break; 194 case CGS_UCODE_ID_CP_MEC_JT2: 195 fw_version = adev->gfx.mec_fw_version; 196 break; 197 case CGS_UCODE_ID_RLC_G: 198 fw_version = adev->gfx.rlc_fw_version; 199 break; 200 case CGS_UCODE_ID_STORAGE: 201 break; 202 default: 203 DRM_ERROR("firmware type %d do not have version\n", type); 204 break; 205 } 206 return fw_version; 207 } 208 209 static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, 210 enum cgs_ucode_id type, 211 struct cgs_firmware_info *info) 212 { 213 CGS_FUNC_ADEV; 214 215 if ((CGS_UCODE_ID_SMU != type) && (CGS_UCODE_ID_SMU_SK != type)) { 216 uint64_t gpu_addr; 217 uint32_t data_size; 218 const struct gfx_firmware_header_v1_0 *header; 219 enum AMDGPU_UCODE_ID id; 220 struct amdgpu_firmware_info *ucode; 221 222 id = fw_type_convert(cgs_device, type); 223 ucode = &adev->firmware.ucode[id]; 224 if (ucode->fw == NULL) 225 return -EINVAL; 226 227 gpu_addr = ucode->mc_addr; 228 header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; 229 data_size = le32_to_cpu(header->header.ucode_size_bytes); 230 231 if ((type == CGS_UCODE_ID_CP_MEC_JT1) || 232 (type == CGS_UCODE_ID_CP_MEC_JT2)) { 233 gpu_addr += ALIGN(le32_to_cpu(header->header.ucode_size_bytes), PAGE_SIZE); 234 data_size = le32_to_cpu(header->jt_size) << 2; 235 } 236 237 info->kptr = ucode->kaddr; 238 info->image_size = data_size; 239 info->mc_addr = gpu_addr; 240 info->version = (uint16_t)le32_to_cpu(header->header.ucode_version); 241 242 if (CGS_UCODE_ID_CP_MEC == type) 243 info->image_size = le32_to_cpu(header->jt_offset) << 2; 244 245 info->fw_version = amdgpu_get_firmware_version(cgs_device, type); 246 info->feature_version = (uint16_t)le32_to_cpu(header->ucode_feature_version); 247 } else { 248 char fw_name[30] = {0}; 249 int err = 0; 250 uint32_t ucode_size; 251 uint32_t ucode_start_address __unused; 252 const uint8_t *src; 253 const struct smc_firmware_header_v1_0 *hdr; 254 const struct common_firmware_header *header; 255 struct amdgpu_firmware_info *ucode = NULL; 256 257 if (!adev->pm.fw) { 258 switch (adev->asic_type) { 259 case CHIP_TAHITI: 260 strcpy(fw_name, "radeon/tahiti_smc.bin"); 261 break; 262 case CHIP_PITCAIRN: 263 if ((adev->pdev->revision == 0x81) && 264 ((adev->pdev->device == 0x6810) || 265 (adev->pdev->device == 0x6811))) { 266 info->is_kicker = true; 267 strcpy(fw_name, "radeon/pitcairn_k_smc.bin"); 268 } else { 269 strcpy(fw_name, "radeon/pitcairn_smc.bin"); 270 } 271 break; 272 case CHIP_VERDE: 273 if (((adev->pdev->device == 0x6820) && 274 ((adev->pdev->revision == 0x81) || 275 (adev->pdev->revision == 0x83))) || 276 ((adev->pdev->device == 0x6821) && 277 ((adev->pdev->revision == 0x83) || 278 (adev->pdev->revision == 0x87))) || 279 ((adev->pdev->revision == 0x87) && 280 ((adev->pdev->device == 0x6823) || 281 (adev->pdev->device == 0x682b)))) { 282 info->is_kicker = true; 283 strcpy(fw_name, "radeon/verde_k_smc.bin"); 284 } else { 285 strcpy(fw_name, "radeon/verde_smc.bin"); 286 } 287 break; 288 case CHIP_OLAND: 289 if (((adev->pdev->revision == 0x81) && 290 ((adev->pdev->device == 0x6600) || 291 (adev->pdev->device == 0x6604) || 292 (adev->pdev->device == 0x6605) || 293 (adev->pdev->device == 0x6610))) || 294 ((adev->pdev->revision == 0x83) && 295 (adev->pdev->device == 0x6610))) { 296 info->is_kicker = true; 297 strcpy(fw_name, "radeon/oland_k_smc.bin"); 298 } else { 299 strcpy(fw_name, "radeon/oland_smc.bin"); 300 } 301 break; 302 case CHIP_HAINAN: 303 if (((adev->pdev->revision == 0x81) && 304 (adev->pdev->device == 0x6660)) || 305 ((adev->pdev->revision == 0x83) && 306 ((adev->pdev->device == 0x6660) || 307 (adev->pdev->device == 0x6663) || 308 (adev->pdev->device == 0x6665) || 309 (adev->pdev->device == 0x6667)))) { 310 info->is_kicker = true; 311 strcpy(fw_name, "radeon/hainan_k_smc.bin"); 312 } else if ((adev->pdev->revision == 0xc3) && 313 (adev->pdev->device == 0x6665)) { 314 info->is_kicker = true; 315 strcpy(fw_name, "radeon/banks_k_2_smc.bin"); 316 } else { 317 strcpy(fw_name, "radeon/hainan_smc.bin"); 318 } 319 break; 320 case CHIP_BONAIRE: 321 if ((adev->pdev->revision == 0x80) || 322 (adev->pdev->revision == 0x81) || 323 (adev->pdev->device == 0x665f)) { 324 info->is_kicker = true; 325 strcpy(fw_name, "amdgpu/bonaire_k_smc.bin"); 326 } else { 327 strcpy(fw_name, "amdgpu/bonaire_smc.bin"); 328 } 329 break; 330 case CHIP_HAWAII: 331 if (adev->pdev->revision == 0x80) { 332 info->is_kicker = true; 333 strcpy(fw_name, "amdgpu/hawaii_k_smc.bin"); 334 } else { 335 strcpy(fw_name, "amdgpu/hawaii_smc.bin"); 336 } 337 break; 338 case CHIP_TOPAZ: 339 if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) || 340 ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) || 341 ((adev->pdev->device == 0x6907) && (adev->pdev->revision == 0x87)) || 342 ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD1)) || 343 ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD3))) { 344 info->is_kicker = true; 345 strcpy(fw_name, "amdgpu/topaz_k_smc.bin"); 346 } else 347 strcpy(fw_name, "amdgpu/topaz_smc.bin"); 348 break; 349 case CHIP_TONGA: 350 if (((adev->pdev->device == 0x6939) && (adev->pdev->revision == 0xf1)) || 351 ((adev->pdev->device == 0x6938) && (adev->pdev->revision == 0xf1))) { 352 info->is_kicker = true; 353 strcpy(fw_name, "amdgpu/tonga_k_smc.bin"); 354 } else 355 strcpy(fw_name, "amdgpu/tonga_smc.bin"); 356 break; 357 case CHIP_FIJI: 358 strcpy(fw_name, "amdgpu/fiji_smc.bin"); 359 break; 360 case CHIP_POLARIS11: 361 if (type == CGS_UCODE_ID_SMU) { 362 if (((adev->pdev->device == 0x67ef) && 363 ((adev->pdev->revision == 0xe0) || 364 (adev->pdev->revision == 0xe5))) || 365 ((adev->pdev->device == 0x67ff) && 366 ((adev->pdev->revision == 0xcf) || 367 (adev->pdev->revision == 0xef) || 368 (adev->pdev->revision == 0xff)))) { 369 info->is_kicker = true; 370 strcpy(fw_name, "amdgpu/polaris11_k_smc.bin"); 371 } else if ((adev->pdev->device == 0x67ef) && 372 (adev->pdev->revision == 0xe2)) { 373 info->is_kicker = true; 374 strcpy(fw_name, "amdgpu/polaris11_k2_smc.bin"); 375 } else { 376 strcpy(fw_name, "amdgpu/polaris11_smc.bin"); 377 } 378 } else if (type == CGS_UCODE_ID_SMU_SK) { 379 strcpy(fw_name, "amdgpu/polaris11_smc_sk.bin"); 380 } 381 break; 382 case CHIP_POLARIS10: 383 if (type == CGS_UCODE_ID_SMU) { 384 if (((adev->pdev->device == 0x67df) && 385 ((adev->pdev->revision == 0xe0) || 386 (adev->pdev->revision == 0xe3) || 387 (adev->pdev->revision == 0xe4) || 388 (adev->pdev->revision == 0xe5) || 389 (adev->pdev->revision == 0xe7) || 390 (adev->pdev->revision == 0xef))) || 391 ((adev->pdev->device == 0x6fdf) && 392 ((adev->pdev->revision == 0xef) || 393 (adev->pdev->revision == 0xff)))) { 394 info->is_kicker = true; 395 strcpy(fw_name, "amdgpu/polaris10_k_smc.bin"); 396 } else if ((adev->pdev->device == 0x67df) && 397 ((adev->pdev->revision == 0xe1) || 398 (adev->pdev->revision == 0xf7))) { 399 info->is_kicker = true; 400 strcpy(fw_name, "amdgpu/polaris10_k2_smc.bin"); 401 } else { 402 strcpy(fw_name, "amdgpu/polaris10_smc.bin"); 403 } 404 } else if (type == CGS_UCODE_ID_SMU_SK) { 405 strcpy(fw_name, "amdgpu/polaris10_smc_sk.bin"); 406 } 407 break; 408 case CHIP_POLARIS12: 409 if (((adev->pdev->device == 0x6987) && 410 ((adev->pdev->revision == 0xc0) || 411 (adev->pdev->revision == 0xc3))) || 412 ((adev->pdev->device == 0x6981) && 413 ((adev->pdev->revision == 0x00) || 414 (adev->pdev->revision == 0x01) || 415 (adev->pdev->revision == 0x10)))) { 416 info->is_kicker = true; 417 strcpy(fw_name, "amdgpu/polaris12_k_smc.bin"); 418 } else { 419 strcpy(fw_name, "amdgpu/polaris12_smc.bin"); 420 } 421 break; 422 case CHIP_VEGAM: 423 strcpy(fw_name, "amdgpu/vegam_smc.bin"); 424 break; 425 case CHIP_VEGA10: 426 if ((adev->pdev->device == 0x687f) && 427 ((adev->pdev->revision == 0xc0) || 428 (adev->pdev->revision == 0xc1) || 429 (adev->pdev->revision == 0xc3))) 430 strcpy(fw_name, "amdgpu/vega10_acg_smc.bin"); 431 else 432 strcpy(fw_name, "amdgpu/vega10_smc.bin"); 433 break; 434 case CHIP_VEGA12: 435 strcpy(fw_name, "amdgpu/vega12_smc.bin"); 436 break; 437 case CHIP_VEGA20: 438 strcpy(fw_name, "amdgpu/vega20_smc.bin"); 439 break; 440 default: 441 DRM_ERROR("SMC firmware not supported\n"); 442 return -EINVAL; 443 } 444 445 err = request_firmware(&adev->pm.fw, fw_name, adev->dev); 446 if (err) { 447 DRM_ERROR("Failed to request firmware\n"); 448 return err; 449 } 450 451 err = amdgpu_ucode_validate(adev->pm.fw); 452 if (err) { 453 DRM_ERROR("Failed to load firmware \"%s\"", fw_name); 454 release_firmware(adev->pm.fw); 455 adev->pm.fw = NULL; 456 return err; 457 } 458 459 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 460 ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC]; 461 ucode->ucode_id = AMDGPU_UCODE_ID_SMC; 462 ucode->fw = adev->pm.fw; 463 header = (const struct common_firmware_header *)ucode->fw->data; 464 adev->firmware.fw_size += 465 ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE); 466 } 467 } 468 469 hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data; 470 amdgpu_ucode_print_smc_hdr(&hdr->header); 471 adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version); 472 ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes); 473 ucode_start_address = le32_to_cpu(hdr->ucode_start_addr); 474 src = (const uint8_t *)(adev->pm.fw->data + 475 le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 476 477 info->version = adev->pm.fw_version; 478 info->image_size = ucode_size; 479 info->ucode_start_address = ucode_start_address; 480 info->kptr = (void *)__UNCONST(src); /* XXX used for? */ 481 } 482 return 0; 483 } 484 485 static const struct cgs_ops amdgpu_cgs_ops = { 486 .read_register = amdgpu_cgs_read_register, 487 .write_register = amdgpu_cgs_write_register, 488 .read_ind_register = amdgpu_cgs_read_ind_register, 489 .write_ind_register = amdgpu_cgs_write_ind_register, 490 .get_firmware_info = amdgpu_cgs_get_firmware_info, 491 }; 492 493 struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev) 494 { 495 struct amdgpu_cgs_device *cgs_device = 496 kmalloc(sizeof(*cgs_device), GFP_KERNEL); 497 498 if (!cgs_device) { 499 DRM_ERROR("Couldn't allocate CGS device structure\n"); 500 return NULL; 501 } 502 503 cgs_device->base.ops = &amdgpu_cgs_ops; 504 cgs_device->adev = adev; 505 506 return (struct cgs_device *)cgs_device; 507 } 508 509 void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device) 510 { 511 kfree(cgs_device); 512 } 513