diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 109 |
1 files changed, 51 insertions, 58 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index f55f72a37ca8..7b33867036e7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | |||
| @@ -277,6 +277,7 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type) | |||
| 277 | case CHIP_PITCAIRN: | 277 | case CHIP_PITCAIRN: |
| 278 | case CHIP_VERDE: | 278 | case CHIP_VERDE: |
| 279 | case CHIP_OLAND: | 279 | case CHIP_OLAND: |
| 280 | case CHIP_HAINAN: | ||
| 280 | return AMDGPU_FW_LOAD_DIRECT; | 281 | return AMDGPU_FW_LOAD_DIRECT; |
| 281 | #endif | 282 | #endif |
| 282 | #ifdef CONFIG_DRM_AMDGPU_CIK | 283 | #ifdef CONFIG_DRM_AMDGPU_CIK |
| @@ -296,19 +297,15 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type) | |||
| 296 | case CHIP_POLARIS11: | 297 | case CHIP_POLARIS11: |
| 297 | case CHIP_POLARIS12: | 298 | case CHIP_POLARIS12: |
| 298 | case CHIP_VEGAM: | 299 | case CHIP_VEGAM: |
| 299 | if (!load_type) | 300 | return AMDGPU_FW_LOAD_SMU; |
| 300 | return AMDGPU_FW_LOAD_DIRECT; | ||
| 301 | else | ||
| 302 | return AMDGPU_FW_LOAD_SMU; | ||
| 303 | case CHIP_VEGA10: | 301 | case CHIP_VEGA10: |
| 304 | case CHIP_RAVEN: | 302 | case CHIP_RAVEN: |
| 305 | case CHIP_VEGA12: | 303 | case CHIP_VEGA12: |
| 304 | case CHIP_VEGA20: | ||
| 306 | if (!load_type) | 305 | if (!load_type) |
| 307 | return AMDGPU_FW_LOAD_DIRECT; | 306 | return AMDGPU_FW_LOAD_DIRECT; |
| 308 | else | 307 | else |
| 309 | return AMDGPU_FW_LOAD_PSP; | 308 | return AMDGPU_FW_LOAD_PSP; |
| 310 | case CHIP_VEGA20: | ||
| 311 | return AMDGPU_FW_LOAD_DIRECT; | ||
| 312 | default: | 309 | default: |
| 313 | DRM_ERROR("Unknown firmware load type\n"); | 310 | DRM_ERROR("Unknown firmware load type\n"); |
| 314 | } | 311 | } |
| @@ -322,6 +319,7 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev, | |||
| 322 | { | 319 | { |
| 323 | const struct common_firmware_header *header = NULL; | 320 | const struct common_firmware_header *header = NULL; |
| 324 | const struct gfx_firmware_header_v1_0 *cp_hdr = NULL; | 321 | const struct gfx_firmware_header_v1_0 *cp_hdr = NULL; |
| 322 | const struct dmcu_firmware_header_v1_0 *dmcu_hdr = NULL; | ||
| 325 | 323 | ||
| 326 | if (NULL == ucode->fw) | 324 | if (NULL == ucode->fw) |
| 327 | return 0; | 325 | return 0; |
| @@ -333,8 +331,8 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev, | |||
| 333 | return 0; | 331 | return 0; |
| 334 | 332 | ||
| 335 | header = (const struct common_firmware_header *)ucode->fw->data; | 333 | header = (const struct common_firmware_header *)ucode->fw->data; |
| 336 | |||
| 337 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; | 334 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; |
| 335 | dmcu_hdr = (const struct dmcu_firmware_header_v1_0 *)ucode->fw->data; | ||
| 338 | 336 | ||
| 339 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP || | 337 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP || |
| 340 | (ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1 && | 338 | (ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1 && |
| @@ -343,7 +341,9 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev, | |||
| 343 | ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2_JT && | 341 | ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2_JT && |
| 344 | ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL && | 342 | ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL && |
| 345 | ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM && | 343 | ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM && |
| 346 | ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM)) { | 344 | ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM && |
| 345 | ucode->ucode_id != AMDGPU_UCODE_ID_DMCU_ERAM && | ||
| 346 | ucode->ucode_id != AMDGPU_UCODE_ID_DMCU_INTV)) { | ||
| 347 | ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes); | 347 | ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes); |
| 348 | 348 | ||
| 349 | memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + | 349 | memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + |
| @@ -365,6 +365,20 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev, | |||
| 365 | le32_to_cpu(header->ucode_array_offset_bytes) + | 365 | le32_to_cpu(header->ucode_array_offset_bytes) + |
| 366 | le32_to_cpu(cp_hdr->jt_offset) * 4), | 366 | le32_to_cpu(cp_hdr->jt_offset) * 4), |
| 367 | ucode->ucode_size); | 367 | ucode->ucode_size); |
| 368 | } else if (ucode->ucode_id == AMDGPU_UCODE_ID_DMCU_ERAM) { | ||
| 369 | ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes) - | ||
| 370 | le32_to_cpu(dmcu_hdr->intv_size_bytes); | ||
| 371 | |||
| 372 | memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + | ||
| 373 | le32_to_cpu(header->ucode_array_offset_bytes)), | ||
| 374 | ucode->ucode_size); | ||
| 375 | } else if (ucode->ucode_id == AMDGPU_UCODE_ID_DMCU_INTV) { | ||
| 376 | ucode->ucode_size = le32_to_cpu(dmcu_hdr->intv_size_bytes); | ||
| 377 | |||
| 378 | memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + | ||
| 379 | le32_to_cpu(header->ucode_array_offset_bytes) + | ||
| 380 | le32_to_cpu(dmcu_hdr->intv_offset_bytes)), | ||
| 381 | ucode->ucode_size); | ||
| 368 | } else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL) { | 382 | } else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL) { |
| 369 | ucode->ucode_size = adev->gfx.rlc.save_restore_list_cntl_size_bytes; | 383 | ucode->ucode_size = adev->gfx.rlc.save_restore_list_cntl_size_bytes; |
| 370 | memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_cntl, | 384 | memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_cntl, |
| @@ -406,32 +420,41 @@ static int amdgpu_ucode_patch_jt(struct amdgpu_firmware_info *ucode, | |||
| 406 | return 0; | 420 | return 0; |
| 407 | } | 421 | } |
| 408 | 422 | ||
| 409 | int amdgpu_ucode_init_bo(struct amdgpu_device *adev) | 423 | int amdgpu_ucode_create_bo(struct amdgpu_device *adev) |
| 410 | { | 424 | { |
| 411 | uint64_t fw_offset = 0; | 425 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_DIRECT) { |
| 412 | int i, err; | 426 | amdgpu_bo_create_kernel(adev, adev->firmware.fw_size, PAGE_SIZE, |
| 413 | struct amdgpu_firmware_info *ucode = NULL; | 427 | amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT, |
| 414 | const struct common_firmware_header *header = NULL; | 428 | &adev->firmware.fw_buf, |
| 415 | 429 | &adev->firmware.fw_buf_mc, | |
| 416 | if (!adev->firmware.fw_size) { | 430 | &adev->firmware.fw_buf_ptr); |
| 417 | dev_warn(adev->dev, "No ip firmware need to load\n"); | 431 | if (!adev->firmware.fw_buf) { |
| 418 | return 0; | ||
| 419 | } | ||
| 420 | |||
| 421 | if (!adev->in_gpu_reset) { | ||
| 422 | err = amdgpu_bo_create_kernel(adev, adev->firmware.fw_size, PAGE_SIZE, | ||
| 423 | amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT, | ||
| 424 | &adev->firmware.fw_buf, | ||
| 425 | &adev->firmware.fw_buf_mc, | ||
| 426 | &adev->firmware.fw_buf_ptr); | ||
| 427 | if (err) { | ||
| 428 | dev_err(adev->dev, "failed to create kernel buffer for firmware.fw_buf\n"); | 432 | dev_err(adev->dev, "failed to create kernel buffer for firmware.fw_buf\n"); |
| 429 | goto failed; | 433 | return -ENOMEM; |
| 434 | } else if (amdgpu_sriov_vf(adev)) { | ||
| 435 | memset(adev->firmware.fw_buf_ptr, 0, adev->firmware.fw_size); | ||
| 430 | } | 436 | } |
| 431 | } | 437 | } |
| 438 | return 0; | ||
| 439 | } | ||
| 432 | 440 | ||
| 433 | memset(adev->firmware.fw_buf_ptr, 0, adev->firmware.fw_size); | 441 | void amdgpu_ucode_free_bo(struct amdgpu_device *adev) |
| 442 | { | ||
| 443 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_DIRECT) | ||
| 444 | amdgpu_bo_free_kernel(&adev->firmware.fw_buf, | ||
| 445 | &adev->firmware.fw_buf_mc, | ||
| 446 | &adev->firmware.fw_buf_ptr); | ||
| 447 | } | ||
| 448 | |||
| 449 | int amdgpu_ucode_init_bo(struct amdgpu_device *adev) | ||
| 450 | { | ||
| 451 | uint64_t fw_offset = 0; | ||
| 452 | int i; | ||
| 453 | struct amdgpu_firmware_info *ucode = NULL; | ||
| 434 | 454 | ||
| 455 | /* for baremetal, the ucode is allocated in gtt, so don't need to fill the bo when reset/suspend */ | ||
| 456 | if (!amdgpu_sriov_vf(adev) && (adev->in_gpu_reset || adev->in_suspend)) | ||
| 457 | return 0; | ||
| 435 | /* | 458 | /* |
| 436 | * if SMU loaded firmware, it needn't add SMC, UVD, and VCE | 459 | * if SMU loaded firmware, it needn't add SMC, UVD, and VCE |
| 437 | * ucode info here | 460 | * ucode info here |
| @@ -448,7 +471,6 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev) | |||
| 448 | for (i = 0; i < adev->firmware.max_ucodes; i++) { | 471 | for (i = 0; i < adev->firmware.max_ucodes; i++) { |
| 449 | ucode = &adev->firmware.ucode[i]; | 472 | ucode = &adev->firmware.ucode[i]; |
| 450 | if (ucode->fw) { | 473 | if (ucode->fw) { |
| 451 | header = (const struct common_firmware_header *)ucode->fw->data; | ||
| 452 | amdgpu_ucode_init_single_fw(adev, ucode, adev->firmware.fw_buf_mc + fw_offset, | 474 | amdgpu_ucode_init_single_fw(adev, ucode, adev->firmware.fw_buf_mc + fw_offset, |
| 453 | adev->firmware.fw_buf_ptr + fw_offset); | 475 | adev->firmware.fw_buf_ptr + fw_offset); |
| 454 | if (i == AMDGPU_UCODE_ID_CP_MEC1 && | 476 | if (i == AMDGPU_UCODE_ID_CP_MEC1 && |
| @@ -463,33 +485,4 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev) | |||
| 463 | } | 485 | } |
| 464 | } | 486 | } |
| 465 | return 0; | 487 | return 0; |
| 466 | |||
| 467 | failed: | ||
| 468 | if (err) | ||
| 469 | adev->firmware.load_type = AMDGPU_FW_LOAD_DIRECT; | ||
| 470 | |||
| 471 | return err; | ||
| 472 | } | ||
