drm-next-5.5-2019-10-25: amdgpu: - BACO support for CI and VI asics - Quick memory training support for navi - MSI-X support - RAS fixes - Display AVI infoframe fixes - Display ref clock fixes for renoir - Fix number of audio endpoints in renoir - Fix for discovery tables - Powerplay fixes - Documentation fixes - Misc cleanups radeon: - revert a PPC fix which broke x86
Unified · Split
| @@ -150,6 +150,7 @@ extern uint amdgpu_sdma_phase_quantum; · 149 unmodified lines | |||
| 150 | extern char *amdgpu_disable_cu; | 150 | extern char *amdgpu_disable_cu; |
| 151 | extern char *amdgpu_virtual_display; | 151 | extern char *amdgpu_virtual_display; |
| 152 | extern uint amdgpu_pp_feature_mask; | 152 | extern uint amdgpu_pp_feature_mask; |
| 153 | extern uint amdgpu_force_long_training; | ||
| 153 | extern int amdgpu_job_hang_limit; | 154 | extern int amdgpu_job_hang_limit; |
| 154 | extern int amdgpu_lbpw; | 155 | extern int amdgpu_lbpw; |
| 155 | extern int amdgpu_compute_multipipe; | 156 | extern int amdgpu_compute_multipipe; |
| @@ -288,6 +289,9 @@ struct amdgpu_ip_block_version { · 132 unmodified lines | |||
| 288 | const struct amd_ip_funcs *funcs; | 289 | const struct amd_ip_funcs *funcs; |
| 289 | }; | 290 | }; |
| 290 | 291 | ||
| 292 | #define HW_REV(_Major, _Minor, _Rev) \ | ||
| 293 | ((((uint32_t) (_Major)) << 16) | ((uint32_t) (_Minor) << 8) | ((uint32_t) (_Rev))) | ||
| 294 | |||
| 291 | struct amdgpu_ip_block { | 295 | struct amdgpu_ip_block { |
| 292 | struct amdgpu_ip_block_status status; | 296 | struct amdgpu_ip_block_status status; |
| 293 | const struct amdgpu_ip_block_version *version; | 297 | const struct amdgpu_ip_block_version *version; |
| @@ -627,6 +631,11 @@ struct amdgpu_fw_vram_usage { · 333 unmodified lines | |||
| 627 | u64 size; | 631 | u64 size; |
| 628 | struct amdgpu_bo *reserved_bo; | 632 | struct amdgpu_bo *reserved_bo; |
| 629 | void *va; | 633 | void *va; |
| 634 | |||
| 635 | /* Offset on the top of VRAM, used as c2p write buffer. | ||
| 636 | */ | ||
| 637 | u64 mem_train_fb_loc; | ||
| 638 | bool mem_train_support; | ||
| 630 | }; | 639 | }; |
| 631 | 640 | ||
| 632 | /* | 641 | /* |
| @@ -759,6 +768,7 @@ struct amdgpu_device { · 126 unmodified lines | |||
| 759 | uint8_t *bios; | 768 | uint8_t *bios; |
| 760 | uint32_t bios_size; | 769 | uint32_t bios_size; |
| 761 | struct amdgpu_bo *stolen_vga_memory; | 770 | struct amdgpu_bo *stolen_vga_memory; |
| 771 | struct amdgpu_bo *discovery_memory; | ||
| 762 | uint32_t bios_scratch_reg_offset; | 772 | uint32_t bios_scratch_reg_offset; |
| 763 | uint32_t bios_scratch[AMDGPU_BIOS_NUM_SCRATCH]; | 773 | uint32_t bios_scratch[AMDGPU_BIOS_NUM_SCRATCH]; |
| 764 | 774 | ||
| @@ -959,8 +969,6 @@ struct amdgpu_device { · 194 unmodified lines | |||
| 959 | int asic_reset_res; | 969 | int asic_reset_res; |
| 960 | struct work_struct xgmi_reset_work; | 970 | struct work_struct xgmi_reset_work; |
| 961 | 971 | ||
| 962 | bool in_baco_reset; | ||
| 963 | |||
| 964 | long gfx_timeout; | 972 | long gfx_timeout; |
| 965 | long sdma_timeout; | 973 | long sdma_timeout; |
| 966 | long video_timeout; | 974 | long video_timeout; |
| @@ -982,6 +990,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, · 15 unmodified lines | |||
| 982 | void amdgpu_device_fini(struct amdgpu_device *adev); | 990 | void amdgpu_device_fini(struct amdgpu_device *adev); |
| 983 | int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev); | 991 | int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev); |
| 984 | 992 | ||
| 993 | void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos, | ||
| 994 | uint32_t *buf, size_t size, bool write); | ||
| 985 | uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg, | 995 | uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg, |
| 986 | uint32_t acc_flags); | 996 | uint32_t acc_flags); |
| 987 | void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, | 997 | void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, |
| @@ -2038,6 +2038,11 @@ int amdgpu_atombios_init(struct amdgpu_device *adev) · 2037 unmodified lines | |||
| 2038 | if (adev->is_atom_fw) { | 2038 | if (adev->is_atom_fw) { |
| 2039 | amdgpu_atomfirmware_scratch_regs_init(adev); | 2039 | amdgpu_atomfirmware_scratch_regs_init(adev); |
| 2040 | amdgpu_atomfirmware_allocate_fb_scratch(adev); | 2040 | amdgpu_atomfirmware_allocate_fb_scratch(adev); |
| 2041 | ret = amdgpu_atomfirmware_get_mem_train_fb_loc(adev); | ||
| 2042 | if (ret) { | ||
| 2043 | DRM_ERROR("Failed to get mem train fb location.\n"); | ||
| 2044 | return ret; | ||
| 2045 | } | ||
| 2041 | } else { | 2046 | } else { |
| 2042 | amdgpu_atombios_scratch_regs_init(adev); | 2047 | amdgpu_atombios_scratch_regs_init(adev); |
| 2043 | amdgpu_atombios_allocate_fb_scratch(adev); | 2048 | amdgpu_atombios_allocate_fb_scratch(adev); |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | |||
| 27 | #include "amdgpu_atomfirmware.h" | 27 | #include "amdgpu_atomfirmware.h" |
| 28 | #include "atom.h" | 28 | #include "atom.h" |
| 29 | #include "atombios.h" | 29 | #include "atombios.h" |
| 30 | #include "soc15_hw_ip.h" | ||
| 30 | 31 | ||
| 31 | bool amdgpu_atomfirmware_gpu_supports_virtualization(struct amdgpu_device *adev) | 32 | bool amdgpu_atomfirmware_gpu_supports_virtualization(struct amdgpu_device *adev) |
| 32 | { | 33 | { |
| @@ -462,3 +463,138 @@ int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev) · 429 unmodified lines | |||
| 462 | } | 463 | } |
| 463 | return -EINVAL; | 464 | return -EINVAL; |
| 464 | } | 465 | } |
| 466 | |||
| 467 | /* | ||
| 468 | * Check if VBIOS supports GDDR6 training data save/restore | ||
| 469 | */ | ||
| 470 | static bool gddr6_mem_train_vbios_support(struct amdgpu_device *adev) | ||
| 471 | { | ||
| 472 | uint16_t data_offset; | ||
| 473 | int index; | ||
| 474 | |||
| 475 | index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, | ||
| 476 | firmwareinfo); | ||
| 477 | if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, NULL, | ||
| 478 | NULL, NULL, &data_offset)) { | ||
| 479 | struct atom_firmware_info_v3_1 *firmware_info = | ||
| 480 | (struct atom_firmware_info_v3_1 *)(adev->mode_info.atom_context->bios + | ||
| 481 | data_offset); | ||
| 482 | |||
| 483 | DRM_DEBUG("atom firmware capability:0x%08x.\n", | ||
| 484 | le32_to_cpu(firmware_info->firmware_capability)); | ||
| 485 | |||
| 486 | if (le32_to_cpu(firmware_info->firmware_capability) & | ||
| 487 | ATOM_FIRMWARE_CAP_ENABLE_2STAGE_BIST_TRAINING) | ||
| 488 | return true; | ||
| 489 | } | ||
| 490 | |||
| 491 | return false; | ||
| 492 | } | ||
| 493 | |||
| 494 | static int gddr6_mem_train_support(struct amdgpu_device *adev) | ||
| 495 | { | ||
| 496 | int ret; | ||
| 497 | uint32_t major, minor, revision, hw_v; | ||
| 498 | |||
| 499 | if (gddr6_mem_train_vbios_support(adev)) { | ||
| 500 | amdgpu_discovery_get_ip_version(adev, MP0_HWID, &major, &minor, &revision); | ||
| 501 | hw_v = HW_REV(major, minor, revision); | ||
| 502 | /* | ||
| 503 | * treat 0 revision as a special case since register for MP0 and MMHUB is missing | ||
| 504 | * for some Navi10 A0, preventing driver from discovering the hwip information since | ||
| 505 | * none of the functions will be initialized, it should not cause any problems | ||
| 506 | */ | ||
| 507 | switch (hw_v) { | ||
| 508 | case HW_REV(11, 0, 0): | ||
| 509 | case HW_REV(11, 0, 5): | ||
| 510 | ret = 1; | ||
| 511 | break; | ||
| 512 | default: | ||
| 513 | DRM_ERROR("memory training vbios supports but psp hw(%08x)" | ||
| 514 | " doesn't support!\n", hw_v); | ||
| 515 | ret = -1; | ||
| 516 | break; | ||
| 517 | } | ||
| 518 | } else { | ||
| 519 | ret = 0; | ||
| 520 | hw_v = -1; | ||
| 521 | } | ||
| 522 | |||
| 523 | |||
| 524 | DRM_DEBUG("mp0 hw_v %08x, ret:%d.\n", hw_v, ret); | ||
| 525 | return ret; | ||
| 526 | } | ||
| 527 | |||
| 528 | int amdgpu_atomfirmware_get_mem_train_fb_loc(struct amdgpu_device *adev) | ||
| 529 | { | ||
| 530 | struct atom_context *ctx = adev->mode_info.atom_context; | ||
| 531 | unsigned char *bios = ctx->bios; | ||
| 532 | struct vram_reserve_block *reserved_block; | ||
| 533 | int index, block_number; | ||
| 534 | uint8_t frev, crev; | ||
| 535 | uint16_t data_offset, size; | ||
| 536 | uint32_t start_address_in_kb; | ||
| 537 | uint64_t offset; | ||
| 538 | int ret; | ||
| 539 | |||
| 540 | adev->fw_vram_usage.mem_train_support = false; | ||
| 541 | |||
| 542 | if (adev->asic_type != CHIP_NAVI10 && | ||
| 543 | adev->asic_type != CHIP_NAVI14) | ||
| 544 | return 0; | ||
| 545 | |||
| 546 | if (amdgpu_sriov_vf(adev)) | ||
| 547 | return 0; | ||
| 548 | |||
| 549 | ret = gddr6_mem_train_support(adev); | ||
| 550 | if (ret == -1) | ||
| 551 | return -EINVAL; | ||
| 552 | else if (ret == 0) | ||
| 553 | return 0; | ||
| 554 | |||
| 555 | index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, | ||
| 556 | vram_usagebyfirmware); | ||
| 557 | ret = amdgpu_atom_parse_data_header(ctx, index, &size, &frev, &crev, | ||
| 558 | &data_offset); | ||
| 559 | if (ret == 0) { | ||
| 560 | DRM_ERROR("parse data header failed.\n"); | ||
| 561 | return -EINVAL; | ||
| 562 | } | ||
| 563 | |||
| 564 | DRM_DEBUG("atom firmware common table header size:0x%04x, frev:0x%02x," | ||
| 565 | " crev:0x%02x, data_offset:0x%04x.\n", size, frev, crev, data_offset); | ||
| 566 | /* only support 2.1+ */ | ||
| 567 | if (((uint16_t)frev << 8 | crev) < 0x0201) { | ||
| 568 | DRM_ERROR("frev:0x%02x, crev:0x%02x < 2.1 !\n", frev, crev); | ||
| 569 | return -EINVAL; | ||
| 570 | } | ||
| 571 | |||
| 572 | reserved_block = (struct vram_reserve_block *) | ||
| 573 | (bios + data_offset + sizeof(struct atom_common_table_header)); | ||
| 574 | block_number = ((unsigned int)size - sizeof(struct atom_common_table_header)) | ||
| 575 | / sizeof(struct vram_reserve_block); | ||
| 576 | reserved_block += (block_number > 0) ? block_number-1 : 0; | ||
| 577 | DRM_DEBUG("block_number:0x%04x, last block: 0x%08xkb sz, %dkb fw, %dkb drv.\n", | ||
| 578 | block_number, | ||
| 579 | le32_to_cpu(reserved_block->start_address_in_kb), | ||
| 580 | le16_to_cpu(reserved_block->used_by_firmware_in_kb), | ||
| 581 | le16_to_cpu(reserved_block->used_by_driver_in_kb)); | ||
| 582 | if (reserved_block->used_by_firmware_in_kb > 0) { | ||
| 583 | start_address_in_kb = le32_to_cpu(reserved_block->start_address_in_kb); | ||
| 584 | offset = (uint64_t)start_address_in_kb * ONE_KiB; | ||
| 585 | if ((offset & (ONE_MiB - 1)) < (4 * ONE_KiB + 1) ) { | ||
| 586 | offset -= ONE_MiB; | ||
| 587 | } | ||
| 588 | |||
| 589 | offset &= ~(ONE_MiB - 1); | ||
| 590 | adev->fw_vram_usage.mem_train_fb_loc = offset; | ||
| 591 | adev->fw_vram_usage.mem_train_support = true; | ||
| 592 | DRM_DEBUG("mem_train_fb_loc:0x%09llx.\n", offset); | ||
| 593 | ret = 0; | ||
| 594 | } else { | ||
| 595 | DRM_ERROR("used_by_firmware_in_kb is 0!\n"); | ||
| 596 | ret = -EINVAL; | ||
| 597 | } | ||
| 598 | |||
| 599 | return ret; | ||
| 600 | } | ||
| @@ -31,6 +31,7 @@ void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev); · 30 unmodified lines | |||
| 31 | int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev); | 31 | int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev); |
| 32 | int amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev, | 32 | int amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev, |
| 33 | int *vram_width, int *vram_type, int *vram_vendor); | 33 | int *vram_width, int *vram_type, int *vram_vendor); |
| 34 | int amdgpu_atomfirmware_get_mem_train_fb_loc(struct amdgpu_device *adev); | ||
| 34 | int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev); | 35 | int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev); |
| 35 | int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev); | 36 | int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev); |
| 36 | bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev); | 37 | bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev); |
| @@ -613,17 +613,7 @@ static bool amdgpu_atpx_detect(void) · 612 unmodified lines | |||
| 613 | bool d3_supported = false; | 613 | bool d3_supported = false; |
| 614 | struct pci_dev *parent_pdev; | 614 | struct pci_dev *parent_pdev; |
| 615 | 615 | ||
| 616 | while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { | 616 | while ((pdev = pci_get_class(PCI_BASE_CLASS_DISPLAY << 16, pdev)) != NULL) { |
| 617 | vga_count++; | ||
| 618 | |||
| 619 | has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true); | ||
| 620 | |||
| 621 | parent_pdev = pci_upstream_bridge(pdev); | ||
| 622 | d3_supported |= parent_pdev && parent_pdev->bridge_d3; | ||
| 623 | amdgpu_atpx_get_quirks(pdev); | ||
| 624 | } | ||
| 625 | |||
| 626 | while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) { | ||
| 627 | vga_count++; | 617 | vga_count++; |
| 628 | 618 | ||
| 629 | has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true); | 619 | has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true); |
| @@ -140,7 +140,12 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp, · 139 unmodified lines | |||
| 140 | return 0; | 140 | return 0; |
| 141 | 141 | ||
| 142 | error_free: | 142 | error_free: |
| 143 | while (i--) { | 143 | for (i = 0; i < last_entry; ++i) { |
| 144 | struct amdgpu_bo *bo = ttm_to_amdgpu_bo(array[i].tv.bo); | ||
| 145 | |||
| 146 | amdgpu_bo_unref(&bo); | ||
| 147 | } | ||
| 148 | for (i = first_userptr; i < num_entries; ++i) { | ||
| 144 | struct amdgpu_bo *bo = ttm_to_amdgpu_bo(array[i].tv.bo); | 149 | struct amdgpu_bo *bo = ttm_to_amdgpu_bo(array[i].tv.bo); |
| 145 | 150 | ||
| 146 | amdgpu_bo_unref(&bo); | 151 | amdgpu_bo_unref(&bo); |
| @@ -474,7 +474,6 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, · 473 unmodified lines | |||
| 474 | 474 | ||
| 475 | list_for_each_entry(lobj, validated, tv.head) { | 475 | list_for_each_entry(lobj, validated, tv.head) { |
| 476 | struct amdgpu_bo *bo = ttm_to_amdgpu_bo(lobj->tv.bo); | 476 | struct amdgpu_bo *bo = ttm_to_amdgpu_bo(lobj->tv.bo); |
| 477 | bool binding_userptr = false; | ||
| 478 | struct mm_struct *usermm; | 477 | struct mm_struct *usermm; |
| 479 | 478 | ||
| 480 | usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm); | 479 | usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm); |
| @@ -491,17 +490,14 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, · 10 unmodified lines | |||
| 491 | 490 | ||
| 492 | amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, | 491 | amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, |
| 493 | lobj->user_pages); | 492 | lobj->user_pages); |
| 494 | binding_userptr = true; | ||
| 495 | } | 493 | } |
| 496 | 494 | ||
| 497 | r = amdgpu_cs_validate(p, bo); | 495 | r = amdgpu_cs_validate(p, bo); |
| 498 | if (r) | 496 | if (r) |
| 499 | return r; | 497 | return r; |
| 500 | 498 | ||
| 501 | if (binding_userptr) { | 499 | kvfree(lobj->user_pages); |
| 502 | kvfree(lobj->user_pages); | 500 | lobj->user_pages = NULL; |
| 503 | lobj->user_pages = NULL; | ||
| 504 | } | ||
| 505 | } | 501 | } |
| 506 | return 0; | 502 | return 0; |
| 507 | } | 503 | } |
| @@ -153,6 +153,36 @@ bool amdgpu_device_is_px(struct drm_device *dev) · 152 unmodified lines | |||
| 153 | return false; | 153 | return false; |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | /** | ||
| 157 | * VRAM access helper functions. | ||
| 158 | * | ||
| 159 | * amdgpu_device_vram_access - read/write a buffer in vram | ||
| 160 | * | ||
| 161 | * @adev: amdgpu_device pointer | ||
| 162 | * @pos: offset of the buffer in vram | ||
| 163 | * @buf: virtual address of the buffer in system memory | ||
| 164 | * @size: read/write size, sizeof(@buf) must > @size | ||
| 165 | * @write: true - write to vram, otherwise - read from vram | ||
| 166 | */ | ||
| 167 | void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos, | ||
| 168 | uint32_t *buf, size_t size, bool write) | ||
| 169 | { | ||
| 170 | uint64_t last; | ||
| 171 | unsigned long flags; | ||
| 172 | |||
| 173 | last = size - 4; | ||
| 174 | for (last += pos; pos <= last; pos += 4) { | ||
| 175 | spin_lock_irqsave(&adev->mmio_idx_lock, flags); | ||
| 176 | WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x80000000); | ||
| 177 | WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31); | ||
| 178 | if (write) | ||
| 179 | WREG32_NO_KIQ(mmMM_DATA, *buf++); | ||
| 180 | else | ||
| 181 | *buf++ = RREG32_NO_KIQ(mmMM_DATA); | ||
| 182 | spin_unlock_irqrestore(&adev->mmio_idx_lock, flags); | ||
| 183 | } | ||
| 184 | } | ||
| 185 | |||
| 156 | /* | 186 | /* |
| 157 | * MMIO register access helper functions. | 187 | * MMIO register access helper functions. |
| 158 | */ | 188 | */ |
| @@ -2622,8 +2652,11 @@ static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev) · 2463 unmodified lines | |||
| 2622 | * There is only one value specified and | 2652 | * There is only one value specified and |
| 2623 | * it should apply to all non-compute jobs. | 2653 | * it should apply to all non-compute jobs. |
| 2624 | */ | 2654 | */ |
| 2625 | if (index == 1) | 2655 | if (index == 1) { |
| 2626 | adev->sdma_timeout = adev->video_timeout = adev->gfx_timeout; | 2656 | adev->sdma_timeout = adev->video_timeout = adev->gfx_timeout; |
| 2657 | if (amdgpu_sriov_vf(adev) || amdgpu_passthrough(adev)) | ||
| 2658 | adev->compute_timeout = adev->gfx_timeout; | ||
| 2659 | } | ||
| 2627 | } | 2660 | } |
| 2628 | 2661 | ||
| 2629 | return ret; | 2662 | return ret; |
| @@ -3168,15 +3201,11 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) · 538 unmodified lines | |||
| 3168 | */ | 3201 | */ |
| 3169 | amdgpu_bo_evict_vram(adev); | 3202 | amdgpu_bo_evict_vram(adev); |
| 3170 | 3203 | ||
| 3171 | pci_save_state(dev->pdev); | ||
| 3172 | if (suspend) { | 3204 | if (suspend) { |
| 3205 | pci_save_state(dev->pdev); | ||
| 3173 | /* Shut down the device */ | 3206 | /* Shut down the device */ |
| 3174 | pci_disable_device(dev->pdev); | 3207 | pci_disable_device(dev->pdev); |
| 3175 | pci_set_power_state(dev->pdev, PCI_D3hot); | 3208 | pci_set_power_state(dev->pdev, PCI_D3hot); |
| 3176 | } else { | ||
| 3177 | r = amdgpu_asic_reset(adev); | ||
| 3178 | if (r) | ||
| 3179 | DRM_ERROR("amdgpu asic reset failed\n"); | ||
| 3180 | } | 3209 | } |
| 3181 | 3210 | ||
| 3182 | return 0; | 3211 | return 0; |
| @@ -134,20 +134,10 @@ static int hw_id_map[MAX_HWIP] = { · 133 unmodified lines | |||
| 134 | 134 | ||
| 135 | static int amdgpu_discovery_read_binary(struct amdgpu_device *adev, uint8_t *binary) | 135 | static int amdgpu_discovery_read_binary(struct amdgpu_device *adev, uint8_t *binary) |
| 136 | { | 136 | { |
| 137 | uint32_t *p = (uint32_t *)binary; | ||
| 138 | uint64_t vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20; | 137 | uint64_t vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20; |
| 139 | uint64_t pos = vram_size - BINARY_MAX_SIZE; | 138 | uint64_t pos = vram_size - DISCOVERY_TMR_SIZE; |
| 140 | unsigned long flags; | ||
| 141 | |||
| 142 | while (pos < vram_size) { | ||
| 143 | spin_lock_irqsave(&adev->mmio_idx_lock, flags); | ||
| 144 | WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x80000000); | ||
| 145 | WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31); | ||
| 146 | *p++ = RREG32_NO_KIQ(mmMM_DATA); | ||
| 147 | spin_unlock_irqrestore(&adev->mmio_idx_lock, flags); | ||
| 148 | pos += 4; | ||
| 149 | } | ||
| 150 | 139 | ||
| 140 | amdgpu_device_vram_access(adev, pos, (uint32_t *)binary, DISCOVERY_TMR_SIZE, false); | ||
| 151 | return 0; | 141 | return 0; |
| 152 | } | 142 | } |
| 153 | 143 | ||
| @@ -179,7 +169,7 @@ int amdgpu_discovery_init(struct amdgpu_device *adev) · 25 unmodified lines | |||
| 179 | uint16_t checksum; | 169 | uint16_t checksum; |
| 180 | int r; | 170 | int r; |
| 181 | 171 | ||
| 182 | adev->discovery = kzalloc(BINARY_MAX_SIZE, GFP_KERNEL); | 172 | adev->discovery = kzalloc(DISCOVERY_TMR_SIZE, GFP_KERNEL); |
| 183 | if (!adev->discovery) | 173 | if (!adev->discovery) |
| 184 | return -ENOMEM; | 174 | return -ENOMEM; |
| 185 | 175 | ||
| @@ -333,7 +323,7 @@ int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev) · 147 unmodified lines | |||
| 333 | } | 323 | } |
| 334 | 324 | ||
| 335 | int amdgpu_discovery_get_ip_version(struct amdgpu_device *adev, int hw_id, | 325 | int amdgpu_discovery_get_ip_version(struct amdgpu_device *adev, int hw_id, |
| 336 | int *major, int *minor) | 326 | int *major, int *minor, int *revision) |
| 337 | { | 327 | { |
| 338 | struct binary_header *bhdr; | 328 | struct binary_header *bhdr; |
| 339 | struct ip_discovery_header *ihdr; | 329 | struct ip_discovery_header *ihdr; |
| @@ -369,6 +359,8 @@ int amdgpu_discovery_get_ip_version(struct amdgpu_device *adev, int hw_id, · 29 unmodified lines | |||
| 369 | *major = ip->major; | 359 | *major = ip->major; |
| 370 | if (minor) | 360 | if (minor) |
| 371 | *minor = ip->minor; | 361 | *minor = ip->minor; |
| 362 | if (revision) | ||
| 363 | *revision = ip->revision; | ||
| 372 | return 0; | 364 | return 0; |
| 373 | } | 365 | } |
| 374 | ip_offset += sizeof(*ip) + 4 * (ip->num_base_address - 1); | 366 | ip_offset += sizeof(*ip) + 4 * (ip->num_base_address - 1); |
| @@ -24,11 +24,13 @@ · 23 unmodified lines | |||
| 24 | #ifndef __AMDGPU_DISCOVERY__ | 24 | #ifndef __AMDGPU_DISCOVERY__ |
| 25 | #define __AMDGPU_DISCOVERY__ | 25 | #define __AMDGPU_DISCOVERY__ |
| 26 | 26 | ||
| 27 | #define DISCOVERY_TMR_SIZE (64 << 10) | ||
| 28 | |||
| 27 | int amdgpu_discovery_init(struct amdgpu_device *adev); | 29 | int amdgpu_discovery_init(struct amdgpu_device *adev); |
| 28 | void amdgpu_discovery_fini(struct amdgpu_device *adev); | 30 | void amdgpu_discovery_fini(struct amdgpu_device *adev); |
| 29 | int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev); | 31 | int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev); |
| 30 | int amdgpu_discovery_get_ip_version(struct amdgpu_device *adev, int hw_id, | 32 | int amdgpu_discovery_get_ip_version(struct amdgpu_device *adev, int hw_id, |
| 31 | int *major, int *minor); | 33 | int *major, int *minor, int *revision); |
| 32 | int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev); | 34 | int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev); |
| 33 | 35 | ||
| 34 | #endif /* __AMDGPU_DISCOVERY__ */ | 36 | #endif /* __AMDGPU_DISCOVERY__ */ |
| @@ -128,6 +128,7 @@ char *amdgpu_disable_cu = NULL; · 127 unmodified lines | |||
| 128 | char *amdgpu_virtual_display = NULL; | 128 | char *amdgpu_virtual_display = NULL; |
| 129 | /* OverDrive(bit 14) disabled by default*/ | 129 | /* OverDrive(bit 14) disabled by default*/ |
| 130 | uint amdgpu_pp_feature_mask = 0xffffbfff; | 130 | uint amdgpu_pp_feature_mask = 0xffffbfff; |
| 131 | uint amdgpu_force_long_training = 0; | ||
| 131 | int amdgpu_job_hang_limit = 0; | 132 | int amdgpu_job_hang_limit = 0; |
| 132 | int amdgpu_lbpw = -1; | 133 | int amdgpu_lbpw = -1; |
| 133 | int amdgpu_compute_multipipe = -1; | 134 | int amdgpu_compute_multipipe = -1; |
| @@ -250,9 +251,11 @@ module_param_named(msi, amdgpu_msi, int, 0444); · 116 unmodified lines | |||
| 250 | * By default(with no lockup_timeout settings), the timeout for all non-compute(GFX, SDMA and Video) | 251 | * By default(with no lockup_timeout settings), the timeout for all non-compute(GFX, SDMA and Video) |
| 251 | * jobs is 10000. And there is no timeout enforced on compute jobs. | 252 | * jobs is 10000. And there is no timeout enforced on compute jobs. |
| 252 | */ | 253 | */ |
| 253 | MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms (default: 10000 for non-compute jobs and infinity timeout for compute jobs." | 254 | MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms (default: for bare metal 10000 for non-compute jobs and infinity timeout for compute jobs; " |
| 255 | "for passthrough or sriov, 10000 for all jobs." | ||
| 254 | " 0: keep default value. negative: infinity timeout), " | 256 | " 0: keep default value. negative: infinity timeout), " |
| 255 | "format is [Non-Compute] or [GFX,Compute,SDMA,Video]"); | 257 | "format: for bare metal [Non-Compute] or [GFX,Compute,SDMA,Video]; " |
| 258 | "for passthrough or sriov [all jobs] or [GFX,Compute,SDMA,Video]."); | ||
| 256 | module_param_string(lockup_timeout, amdgpu_lockup_timeout, sizeof(amdgpu_lockup_timeout), 0444); | 259 | module_param_string(lockup_timeout, amdgpu_lockup_timeout, sizeof(amdgpu_lockup_timeout), 0444); |
| 257 | 260 | ||
| 258 | /** | 261 | /** |
| @@ -390,6 +393,14 @@ module_param_named(sched_hw_submission, amdgpu_sched_hw_submission, int, 0444); · 131 unmodified lines | |||
| 390 | MODULE_PARM_DESC(ppfeaturemask, "all power features enabled (default))"); | 393 | MODULE_PARM_DESC(ppfeaturemask, "all power features enabled (default))"); |
| 391 | module_param_named(ppfeaturemask, amdgpu_pp_feature_mask, uint, 0444); | 394 | module_param_named(ppfeaturemask, amdgpu_pp_feature_mask, uint, 0444); |
| 392 | 395 | ||
| 396 | /** | ||
| 397 | * DOC: forcelongtraining (uint) | ||
| 398 | * Force long memory training in resume. | ||
| 399 | * The default is zero, indicates short training in resume. | ||
| 400 | */ | ||
| 401 | MODULE_PARM_DESC(forcelongtraining, "force memory long training"); | ||
| 402 | module_param_named(forcelongtraining, amdgpu_force_long_training, uint, 0444); | ||
| 403 | |||
| 393 | /** | 404 | /** |
| 394 | * DOC: pcie_gen_cap (uint) | 405 | * DOC: pcie_gen_cap (uint) |
| 395 | * Override PCIE gen speed capabilities. See the CAIL flags in drivers/gpu/drm/amd/include/amd_pcie.h. | 406 | * Override PCIE gen speed capabilities. See the CAIL flags in drivers/gpu/drm/amd/include/amd_pcie.h. |
| @@ -1154,8 +1165,13 @@ static int amdgpu_pmops_resume(struct device *dev) · 758 unmodified lines | |||
| 1154 | static int amdgpu_pmops_freeze(struct device *dev) | 1165 | static int amdgpu_pmops_freeze(struct device *dev) |
| 1155 | { | 1166 | { |
| 1156 | struct drm_device *drm_dev = dev_get_drvdata(dev); | 1167 | struct drm_device *drm_dev = dev_get_drvdata(dev); |
| 1168 | struct amdgpu_device *adev = drm_dev->dev_private; | ||
| 1169 | int r; | ||
| 1157 | 1170 | ||
| 1158 | return amdgpu_device_suspend(drm_dev, false, true); | 1171 | r = amdgpu_device_suspend(drm_dev, false, true); |
| 1172 | if (r) | ||
| 1173 | return r; | ||
| 1174 | return amdgpu_asic_reset(adev); | ||
| 1159 | } | 1175 | } |
| 1160 | 1176 | ||
| 1161 | static int amdgpu_pmops_thaw(struct device *dev) | 1177 | static int amdgpu_pmops_thaw(struct device *dev) |
| @@ -67,6 +67,8 @@ struct amdgpu_nbio_funcs { · 66 unmodified lines | |||
| 67 | bool enable); | 67 | bool enable); |
| 68 | void (*ih_doorbell_range)(struct amdgpu_device *adev, | 68 | void (*ih_doorbell_range)(struct amdgpu_device *adev, |
| 69 | bool use_doorbell, int doorbell_index); | 69 | bool use_doorbell, int doorbell_index); |
| 70 | void (*enable_doorbell_interrupt)(struct amdgpu_device *adev, | ||
| 71 | bool enable); | ||
| 70 | void (*update_medium_grain_clock_gating)(struct amdgpu_device *adev, | 72 | void (*update_medium_grain_clock_gating)(struct amdgpu_device *adev, |
| 71 | bool enable); | 73 | bool enable); |
| 72 | void (*update_medium_grain_light_sleep)(struct amdgpu_device *adev, | 74 | void (*update_medium_grain_light_sleep)(struct amdgpu_device *adev, |
| @@ -517,7 +517,8 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, · 516 unmodified lines | |||
| 517 | .interruptible = (bp->type != ttm_bo_type_kernel), | 517 | .interruptible = (bp->type != ttm_bo_type_kernel), |
| 518 | .no_wait_gpu = bp->no_wait_gpu, | 518 | .no_wait_gpu = bp->no_wait_gpu, |
| 519 | .resv = bp->resv, | 519 | .resv = bp->resv, |
| 520 | .flags = TTM_OPT_FLAG_ALLOW_RES_EVICT | 520 | .flags = bp->type != ttm_bo_type_kernel ? |
| 521 | TTM_OPT_FLAG_ALLOW_RES_EVICT : 0 | ||
| 521 | }; | 522 | }; |
| 522 | struct amdgpu_bo *bo; | 523 | struct amdgpu_bo *bo; |
| 523 | unsigned long page_align, size = bp->size; | 524 | unsigned long page_align, size = bp->size; |
| @@ -88,6 +88,17 @@ static int psp_sw_init(void *handle) · 87 unmodified lines | |||
| 88 | return ret; | 88 | return ret; |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | ret = psp_mem_training_init(psp); | ||
| 92 | if (ret) { | ||
| 93 | DRM_ERROR("Failed to initliaze memory training!\n"); | ||
| 94 | return ret; | ||
| 95 | } | ||
| 96 | ret = psp_mem_training(psp, PSP_MEM_TRAIN_COLD_BOOT); | ||
| 97 | if (ret) { | ||
| 98 | DRM_ERROR("Failed to process memory training!\n"); | ||
| 99 | return ret; | ||
| 100 | } | ||
| 101 | |||
| 91 | return 0; | 102 | return 0; |
| 92 | } | 103 | } |
| 93 | 104 | ||
| @@ -95,6 +106,7 @@ static int psp_sw_fini(void *handle) · 1 unmodified line | |||
| 95 | { | 106 | { |
| 96 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 107 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 97 | 108 | ||
| 109 | psp_mem_training_fini(&adev->psp); | ||
| 98 | release_firmware(adev->psp.sos_fw); | 110 | release_firmware(adev->psp.sos_fw); |
| 99 | adev->psp.sos_fw = NULL; | 111 | adev->psp.sos_fw = NULL; |
| 100 | release_firmware(adev->psp.asd_fw); | 112 | release_firmware(adev->psp.asd_fw); |
| @@ -1608,6 +1620,12 @@ static int psp_resume(void *handle) · 1507 unmodified lines | |||
| 1608 | 1620 | ||
| 1609 | DRM_INFO("PSP is resuming...\n"); | 1621 | DRM_INFO("PSP is resuming...\n"); |
| 1610 | 1622 | ||
| 1623 | ret = psp_mem_training(psp, PSP_MEM_TRAIN_RESUME); | ||
| 1624 | if (ret) { | ||
| 1625 | DRM_ERROR("Failed to process memory training!\n"); | ||
| 1626 | return ret; | ||
| 1627 | } | ||
| 1628 | |||
| 1611 | mutex_lock(&adev->firmware.mutex); | 1629 | mutex_lock(&adev->firmware.mutex); |
| 1612 | 1630 | ||
| 1613 | ret = psp_hw_start(psp); | 1631 | ret = psp_hw_start(psp); |
| @@ -49,6 +49,8 @@ enum psp_bootloader_cmd { · 48 unmodified lines | |||
| 49 | PSP_BL__LOAD_SYSDRV = 0x10000, | 49 | PSP_BL__LOAD_SYSDRV = 0x10000, |
| 50 | PSP_BL__LOAD_SOSDRV = 0x20000, | 50 | PSP_BL__LOAD_SOSDRV = 0x20000, |
| 51 | PSP_BL__LOAD_KEY_DATABASE = 0x80000, | 51 | PSP_BL__LOAD_KEY_DATABASE = 0x80000, |
| 52 | PSP_BL__DRAM_LONG_TRAIN = 0x100000, | ||
| 53 | PSP_BL__DRAM_SHORT_TRAIN = 0x200000, | ||
| 52 | }; | 54 | }; |
| 53 | 55 | ||
| 54 | enum psp_ring_type | 56 | enum psp_ring_type |
| @@ -111,6 +113,9 @@ struct psp_funcs · 56 unmodified lines | |||
| 111 | struct ta_ras_trigger_error_input *info); | 113 | struct ta_ras_trigger_error_input *info); |
| 112 | int (*ras_cure_posion)(struct psp_context *psp, uint64_t *mode_ptr); | 114 | int (*ras_cure_posion)(struct psp_context *psp, uint64_t *mode_ptr); |
| 113 | int (*rlc_autoload_start)(struct psp_context *psp); | 115 | int (*rlc_autoload_start)(struct psp_context *psp); |
| 116 | int (*mem_training_init)(struct psp_context *psp); | ||
| 117 | void (*mem_training_fini)(struct psp_context *psp); | ||
| 118 | int (*mem_training)(struct psp_context *psp, uint32_t ops); | ||
| 114 | }; | 119 | }; |
| 115 | 120 | ||
| 116 | #define AMDGPU_XGMI_MAX_CONNECTED_NODES 64 | 121 | #define AMDGPU_XGMI_MAX_CONNECTED_NODES 64 |
| @@ -161,6 +166,49 @@ struct psp_dtm_context { · 44 unmodified lines | |||
| 161 | void *dtm_shared_buf; | 166 | void *dtm_shared_buf; |
| 162 | }; | 167 | }; |
| 163 | 168 | ||
| 169 | #define MEM_TRAIN_SYSTEM_SIGNATURE 0x54534942 | ||
| 170 | #define GDDR6_MEM_TRAINING_DATA_SIZE_IN_BYTES 0x1000 | ||
| 171 | #define GDDR6_MEM_TRAINING_OFFSET 0x8000 | ||
| 172 | |||
| 173 | enum psp_memory_training_init_flag { | ||
| 174 | PSP_MEM_TRAIN_NOT_SUPPORT = 0x0, | ||
| 175 | PSP_MEM_TRAIN_SUPPORT = 0x1, | ||
| 176 | PSP_MEM_TRAIN_INIT_FAILED = 0x2, | ||
| 177 | PSP_MEM_TRAIN_RESERVE_SUCCESS = 0x4, | ||
| 178 | PSP_MEM_TRAIN_INIT_SUCCESS = 0x8, | ||
| 179 | }; | ||
| 180 | |||
| 181 | enum psp_memory_training_ops { | ||
| 182 | PSP_MEM_TRAIN_SEND_LONG_MSG = 0x1, | ||
| 183 | PSP_MEM_TRAIN_SAVE = 0x2, | ||
| 184 | PSP_MEM_TRAIN_RESTORE = 0x4, | ||
| 185 | PSP_MEM_TRAIN_SEND_SHORT_MSG = 0x8, | ||
| 186 | PSP_MEM_TRAIN_COLD_BOOT = PSP_MEM_TRAIN_SEND_LONG_MSG, | ||
| 187 | PSP_MEM_TRAIN_RESUME = PSP_MEM_TRAIN_SEND_SHORT_MSG, | ||
| 188 | }; | ||
| 189 | |||
| 190 | struct psp_memory_training_context { | ||
| 191 | /*training data size*/ | ||
| 192 | u64 train_data_size; | ||
| 193 | /* | ||
| 194 | * sys_cache | ||
| 195 | * cpu virtual address | ||
| 196 | * system memory buffer that used to store the training data. | ||
| 197 | */ | ||
| 198 | void *sys_cache; | ||
| 199 | |||
| 200 | /*vram offset of the p2c training data*/ | ||
| 201 | u64 p2c_train_data_offset; | ||
| 202 | struct amdgpu_bo *p2c_bo; | ||
| 203 | |||
| 204 | /*vram offset of the c2p training data*/ | ||
| 205 | u64 c2p_train_data_offset; | ||
| 206 | struct amdgpu_bo *c2p_bo; | ||
| 207 | |||
| 208 | enum psp_memory_training_init_flag init; | ||
| 209 | u32 training_cnt; | ||
| 210 | }; | ||
| 211 | |||
| 164 | struct psp_context | 212 | struct psp_context |
| 165 | { | 213 | { |
| 166 | struct amdgpu_device *adev; | 214 | struct amdgpu_device *adev; |
| @@ -239,6 +287,7 @@ struct psp_context · 72 unmodified lines | |||
| 239 | struct psp_hdcp_context hdcp_context; | 287 | struct psp_hdcp_context hdcp_context; |
| 240 | struct psp_dtm_context dtm_context; | 288 | struct psp_dtm_context dtm_context; |
| 241 | struct mutex mutex; | 289 | struct mutex mutex; |
| 290 | struct psp_memory_training_context mem_train_ctx; | ||
| 242 | }; | 291 | }; |
| 243 | 292 | ||
| 244 | struct amdgpu_psp_funcs { | 293 | struct amdgpu_psp_funcs { |
| @@ -281,6 +330,12 @@ struct amdgpu_psp_funcs { · 36 unmodified lines | |||
| 281 | (psp)->funcs->xgmi_set_topology_info((psp), (num_device), (topology)) : -EINVAL) | 330 | (psp)->funcs->xgmi_set_topology_info((psp), (num_device), (topology)) : -EINVAL) |
| 282 | #define psp_rlc_autoload(psp) \ | 331 | #define psp_rlc_autoload(psp) \ |
| 283 | ((psp)->funcs->rlc_autoload_start ? (psp)->funcs->rlc_autoload_start((psp)) : 0) | 332 | ((psp)->funcs->rlc_autoload_start ? (psp)->funcs->rlc_autoload_start((psp)) : 0) |
| 333 | #define psp_mem_training_init(psp) \ | ||
| 334 | ((psp)->funcs->mem_training_init ? (psp)->funcs->mem_training_init((psp)) : 0) | ||
| 335 | #define psp_mem_training_fini(psp) \ | ||
| 336 | ((psp)->funcs->mem_training_fini ? (psp)->funcs->mem_training_fini((psp)) : 0) | ||
| 337 | #define psp_mem_training(psp, ops) \ | ||
| 338 | ((psp)->funcs->mem_training ? (psp)->funcs->mem_training((psp), (ops)) : 0) | ||
| 284 | 339 | ||
| 285 | #define amdgpu_psp_check_fw_loading_status(adev, i) (adev)->firmware.funcs->check_fw_loading_status((adev), (i)) | 340 | #define amdgpu_psp_check_fw_loading_status(adev, i) (adev)->firmware.funcs->check_fw_loading_status((adev), (i)) |
| 286 | 341 | ||
| @@ -71,6 +71,9 @@ const char *ras_block_string[] = { · 70 unmodified lines | |||
| 71 | 71 | ||
| 72 | atomic_t amdgpu_ras_in_intr = ATOMIC_INIT(0); | 72 | atomic_t amdgpu_ras_in_intr = ATOMIC_INIT(0); |
| 73 | 73 | ||
| 74 | static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev, | ||
| 75 | uint64_t addr); | ||
| 76 | |||
| 74 | static ssize_t amdgpu_ras_debugfs_read(struct file *f, char __user *buf, | 77 | static ssize_t amdgpu_ras_debugfs_read(struct file *f, char __user *buf, |
| 75 | size_t size, loff_t *pos) | 78 | size_t size, loff_t *pos) |
| 76 | { | 79 | { |
| @@ -215,11 +218,12 @@ static struct ras_manager *amdgpu_ras_find_obj(struct amdgpu_device *adev, · 138 unmodified lines | |||
| 215 | * value to the address. | 218 | * value to the address. |
| 216 | * | 219 | * |
| 217 | * Second member: struct ras_debug_if::op. | 220 | * Second member: struct ras_debug_if::op. |
| 218 | * It has three kinds of operations. | 221 | * It has four kinds of operations. |
| 219 | * | 222 | * |
| 220 | * - 0: disable RAS on the block. Take ::head as its data. | 223 | * - 0: disable RAS on the block. Take ::head as its data. |
| 221 | * - 1: enable RAS on the block. Take ::head as its data. | 224 | * - 1: enable RAS on the block. Take ::head as its data. |
| 222 | * - 2: inject errors on the block. Take ::inject as its data. | 225 | * - 2: inject errors on the block. Take ::inject as its data. |
| 226 | * - 3: reboot on unrecoverable error | ||
| 223 | * | 227 | * |
| 224 | * How to use the interface? | 228 | * How to use the interface? |
| 225 | * programs: | 229 | * programs: |
| @@ -228,13 +232,13 @@ static struct ras_manager *amdgpu_ras_find_obj(struct amdgpu_device *adev, · 2 unmodified lines | |||
| 228 | * | 232 | * |
| 229 | * .. code-block:: bash | 233 | * .. code-block:: bash |
| 230 | * | 234 | * |
| 231 | * echo op block [error [sub_blcok address value]] > .../ras/ras_ctrl | 235 | * echo op block [error [sub_block address value]] > .../ras/ras_ctrl |
| 232 | * | 236 | * |
| 233 | * op: disable, enable, inject | 237 | * op: disable, enable, inject |
| 234 | * disable: only block is needed | 238 | * disable: only block is needed |
| 235 | * enable: block and error are needed | 239 | * enable: block and error are needed |
| 236 | * inject: error, address, value are needed | 240 | * inject: error, address, value are needed |
| 237 | * block: umc, smda, gfx, ......... | 241 | * block: umc, sdma, gfx, ......... |
| 238 | * see ras_block_string[] for details | 242 | * see ras_block_string[] for details |
| 239 | * error: ue, ce | 243 | * error: ue, ce |
| 240 | * ue: multi_uncorrectable | 244 | * ue: multi_uncorrectable |
| @@ -290,6 +294,14 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f, const char __user * · 49 unmodified lines | |||
| 290 | break; | 294 | break; |
| 291 | } | 295 | } |
| 292 | 296 | ||
| 297 | /* umc ce/ue error injection for a bad page is not allowed */ | ||
| 298 | if ((data.head.block == AMDGPU_RAS_BLOCK__UMC) && | ||
| 299 | amdgpu_ras_check_bad_page(adev, data.inject.address)) { | ||
| 300 | DRM_WARN("RAS WARN: 0x%llx has been marked as bad before error injection!\n", | ||
| 301 | data.inject.address); | ||
| 302 | break; | ||
| 303 | } | ||
| 304 | |||
| 293 | /* data.inject.address is offset instead of absolute gpu address */ | 305 | /* data.inject.address is offset instead of absolute gpu address */ |
| 294 | ret = amdgpu_ras_error_inject(adev, &data.inject); | 306 | ret = amdgpu_ras_error_inject(adev, &data.inject); |
| 295 | break; | 307 | break; |
| @@ -1430,6 +1442,39 @@ out: · 1134 unmodified lines | |||
| 1430 | return ret; | 1442 | return ret; |
| 1431 | } | 1443 | } |
| 1432 | 1444 | ||
| 1445 | /* | ||
| 1446 | * check if an address belongs to bad page | ||
| 1447 | * | ||
| 1448 | * Note: this check is only for umc block | ||
| 1449 | */ | ||
| 1450 | static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev, | ||
| 1451 | uint64_t addr) | ||
| 1452 | { | ||
| 1453 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); | ||
| 1454 | struct ras_err_handler_data *data; | ||
| 1455 | int i; | ||
| 1456 | bool ret = false; | ||
| 1457 | |||
| 1458 | if (!con || !con->eh_data) | ||
| 1459 | return ret; | ||
| 1460 | |||
| 1461 | mutex_lock(&con->recovery_lock); | ||
| 1462 | data = con->eh_data; | ||
| 1463 | if (!data) | ||
| 1464 | goto out; | ||
| 1465 | |||
| 1466 | addr >>= AMDGPU_GPU_PAGE_SHIFT; | ||
| 1467 | for (i = 0; i < data->count; i++) | ||
| 1468 | if (addr == data->bps[i].retired_page) { | ||
| 1469 | ret = true; | ||
| 1470 | goto out; | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | out: | ||
| 1474 | mutex_unlock(&con->recovery_lock); | ||
| 1475 | return ret; | ||
| 1476 | } | ||
| 1477 | |||
| 1433 | /* called in gpu recovery/init */ | 1478 | /* called in gpu recovery/init */ |
| 1434 | int amdgpu_ras_reserve_bad_pages(struct amdgpu_device *adev) | 1479 | int amdgpu_ras_reserve_bad_pages(struct amdgpu_device *adev) |
| 1435 | { | 1480 | { |
| @@ -1843,6 +1888,12 @@ int amdgpu_ras_fini(struct amdgpu_device *adev) · 407 unmodified lines | |||
| 1843 | 1888 | ||
| 1844 | void amdgpu_ras_global_ras_isr(struct amdgpu_device *adev) | 1889 | void amdgpu_ras_global_ras_isr(struct amdgpu_device *adev) |
| 1845 | { | 1890 | { |
| 1891 | uint32_t hw_supported, supported; | ||
| 1892 | |||
| 1893 | amdgpu_ras_check_supported(adev, &hw_supported, &supported); | ||
| 1894 | if (!hw_supported) | ||
| 1895 | return; | ||
| 1896 | |||
| 1846 | if (atomic_cmpxchg(&amdgpu_ras_in_intr, 0, 1) == 0) { | 1897 | if (atomic_cmpxchg(&amdgpu_ras_in_intr, 0, 1) == 0) { |
| 1847 | DRM_WARN("RAS event of type ERREVENT_ATHUB_INTERRUPT detected!\n"); | 1898 | DRM_WARN("RAS event of type ERREVENT_ATHUB_INTERRUPT detected!\n"); |
| 1848 | 1899 | ||
| @@ -170,7 +170,7 @@ TRACE_EVENT(amdgpu_cs_ioctl, · 169 unmodified lines | |||
| 170 | __field(unsigned int, context) | 170 | __field(unsigned int, context) |
| 171 | __field(unsigned int, seqno) | 171 | __field(unsigned int, seqno) |
| 172 | __field(struct dma_fence *, fence) | 172 | __field(struct dma_fence *, fence) |
| 173 | __field(char *, ring_name) | 173 | __string(ring, to_amdgpu_ring(job->base.sched)->name) |
| 174 | __field(u32, num_ibs) | 174 | __field(u32, num_ibs) |
| 175 | ), | 175 | ), |
| 176 | 176 | ||
| @@ -179,12 +179,12 @@ TRACE_EVENT(amdgpu_cs_ioctl, · 2 unmodified lines | |||
| 179 | __assign_str(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job)) | 179 | __assign_str(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job)) |
| 180 | __entry->context = job->base.s_fence->finished.context; | 180 | __entry->context = job->base.s_fence->finished.context; |
| 181 | __entry->seqno = job->base.s_fence->finished.seqno; | 181 | __entry->seqno = job->base.s_fence->finished.seqno; |
| 182 | __entry->ring_name = to_amdgpu_ring(job->base.sched)->name; | 182 | __assign_str(ring, to_amdgpu_ring(job->base.sched)->name) |
| 183 | __entry->num_ibs = job->num_ibs; | 183 | __entry->num_ibs = job->num_ibs; |
| 184 | ), | 184 | ), |
| 185 | TP_printk("sched_job=%llu, timeline=%s, context=%u, seqno=%u, ring_name=%s, num_ibs=%u", | 185 | TP_printk("sched_job=%llu, timeline=%s, context=%u, seqno=%u, ring_name=%s, num_ibs=%u", |
| 186 | __entry->sched_job_id, __get_str(timeline), __entry->context, | 186 | __entry->sched_job_id, __get_str(timeline), __entry->context, |
| 187 | __entry->seqno, __entry->ring_name, __entry->num_ibs) | 187 | __entry->seqno, __get_str(ring), __entry->num_ibs) |
| 188 | ); | 188 | ); |
| 189 | 189 | ||
| 190 | TRACE_EVENT(amdgpu_sched_run_job, | 190 | TRACE_EVENT(amdgpu_sched_run_job, |
| @@ -195,7 +195,7 @@ TRACE_EVENT(amdgpu_sched_run_job, · 4 unmodified lines | |||
| 195 | __string(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job)) | 195 | __string(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job)) |
| 196 | __field(unsigned int, context) | 196 | __field(unsigned int, context) |
| 197 | __field(unsigned int, seqno) | 197 | __field(unsigned int, seqno) |
| 198 | __field(char *, ring_name) | 198 | __string(ring, to_amdgpu_ring(job->base.sched)->name) |
| 199 | __field(u32, num_ibs) | 199 | __field(u32, num_ibs) |
| 200 | ), | 200 | ), |
| 201 | 201 | ||
| @@ -204,12 +204,12 @@ TRACE_EVENT(amdgpu_sched_run_job, · 2 unmodified lines | |||
| 204 | __assign_str(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job)) | 204 | __assign_str(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job)) |
| 205 | __entry->context = job->base.s_fence->finished.context; | 205 | __entry->context = job->base.s_fence->finished.context; |
| 206 | __entry->seqno = job->base.s_fence->finished.seqno; | 206 | __entry->seqno = job->base.s_fence->finished.seqno; |
| 207 | __entry->ring_name = to_amdgpu_ring(job->base.sched)->name; | 207 | __assign_str(ring, to_amdgpu_ring(job->base.sched)->name) |
| 208 | __entry->num_ibs = job->num_ibs; | 208 | __entry->num_ibs = job->num_ibs; |
| 209 | ), | 209 | ), |
| 210 | TP_printk("sched_job=%llu, timeline=%s, context=%u, seqno=%u, ring_name=%s, num_ibs=%u", | 210 | TP_printk("sched_job=%llu, timeline=%s, context=%u, seqno=%u, ring_name=%s, num_ibs=%u", |
| 211 | __entry->sched_job_id, __get_str(timeline), __entry->context, | 211 | __entry->sched_job_id, __get_str(timeline), __entry->context, |
| 212 | __entry->seqno, __entry->ring_name, __entry->num_ibs) | 212 | __entry->seqno, __get_str(ring), __entry->num_ibs) |
| 213 | ); | 213 | ); |
| 214 | 214 | ||
| 215 | 215 | ||
| @@ -473,7 +473,7 @@ TRACE_EVENT(amdgpu_ib_pipe_sync, · 257 unmodified lines | |||
| 473 | TP_PROTO(struct amdgpu_job *sched_job, struct dma_fence *fence), | 473 | TP_PROTO(struct amdgpu_job *sched_job, struct dma_fence *fence), |
| 474 | TP_ARGS(sched_job, fence), | 474 | TP_ARGS(sched_job, fence), |
| 475 | TP_STRUCT__entry( | 475 | TP_STRUCT__entry( |
| 476 | __field(const char *,name) | 476 | __string(ring, sched_job->base.sched->name); |
| 477 | __field(uint64_t, id) | 477 | __field(uint64_t, id) |
| 478 | __field(struct dma_fence *, fence) | 478 | __field(struct dma_fence *, fence) |
| 479 | __field(uint64_t, ctx) | 479 | __field(uint64_t, ctx) |
| @@ -481,14 +481,14 @@ TRACE_EVENT(amdgpu_ib_pipe_sync, · 1 unmodified line | |||
| 481 | ), | 481 | ), |
| 482 | 482 | ||
| 483 | TP_fast_assign( | 483 | TP_fast_assign( |
| 484 | __entry->name = sched_job->base.sched->name; | 484 | __assign_str(ring, sched_job->base.sched->name) |
| 485 | __entry->id = sched_job->base.id; | 485 | __entry->id = sched_job->base.id; |
| 486 | __entry->fence = fence; | 486 | __entry->fence = fence; |
| 487 | __entry->ctx = fence->context; | 487 | __entry->ctx = fence->context; |
| 488 | __entry->seqno = fence->seqno; | 488 | __entry->seqno = fence->seqno; |
| 489 | ), | 489 | ), |
| 490 | TP_printk("job ring=%s, id=%llu, need pipe sync to fence=%p, context=%llu, seq=%u", | 490 | TP_printk("job ring=%s, id=%llu, need pipe sync to fence=%p, context=%llu, seq=%u", |
| 491 | __entry->name, __entry->id, | 491 | __get_str(ring), __entry->id, |
| 492 | __entry->fence, __entry->ctx, | 492 | __entry->fence, __entry->ctx, |
| 493 | __entry->seqno) | 493 | __entry->seqno) |
| 494 | ); | 494 | ); |
| @@ -1652,6 +1652,88 @@ static int amdgpu_ttm_fw_reserve_vram_init(struct amdgpu_device *adev) · 1651 unmodified lines | |||
| 1652 | &adev->fw_vram_usage.va); | 1652 | &adev->fw_vram_usage.va); |
| 1653 | } | 1653 | } |
| 1654 | 1654 | ||
| 1655 | /* | ||
| 1656 | * Memoy training reservation functions | ||
| 1657 | */ | ||
| 1658 | |||
| 1659 | /** | ||
| 1660 | * amdgpu_ttm_training_reserve_vram_fini - free memory training reserved vram | ||
| 1661 | * | ||
| 1662 | * @adev: amdgpu_device pointer | ||
| 1663 | * | ||
| 1664 | * free memory training reserved vram if it has been reserved. | ||
| 1665 | */ | ||
| 1666 | static int amdgpu_ttm_training_reserve_vram_fini(struct amdgpu_device *adev) | ||
| 1667 | { | ||
| 1668 | struct psp_memory_training_context *ctx = &adev->psp.mem_train_ctx; | ||
| 1669 | |||
| 1670 | ctx->init = PSP_MEM_TRAIN_NOT_SUPPORT; | ||
| 1671 | amdgpu_bo_free_kernel(&ctx->c2p_bo, NULL, NULL); | ||
| 1672 | ctx->c2p_bo = NULL; | ||
| 1673 | |||
| 1674 | amdgpu_bo_free_kernel(&ctx->p2c_bo, NULL, NULL); | ||
| 1675 | ctx->p2c_bo = NULL; | ||
| 1676 | |||
| 1677 | return 0; | ||
| 1678 | } | ||
| 1679 | |||
| 1680 | /** | ||
| 1681 | * amdgpu_ttm_training_reserve_vram_init - create bo vram reservation from memory training | ||
| 1682 | * | ||
| 1683 | * @adev: amdgpu_device pointer | ||
| 1684 | * | ||
| 1685 | * create bo vram reservation from memory training. | ||
| 1686 | */ | ||
| 1687 | static int amdgpu_ttm_training_reserve_vram_init(struct amdgpu_device *adev) | ||
| 1688 | { | ||
| 1689 | int ret; | ||
| 1690 | struct psp_memory_training_context *ctx = &adev->psp.mem_train_ctx; | ||
| 1691 | |||
| 1692 | memset(ctx, 0, sizeof(*ctx)); | ||
| 1693 | if (!adev->fw_vram_usage.mem_train_support) { | ||
| 1694 | DRM_DEBUG("memory training does not support!\n"); | ||
| 1695 | return 0; | ||
| 1696 | } | ||
| 1697 | |||
| 1698 | ctx->c2p_train_data_offset = adev->fw_vram_usage.mem_train_fb_loc; | ||
| 1699 | ctx->p2c_train_data_offset = (adev->gmc.mc_vram_size - GDDR6_MEM_TRAINING_OFFSET); | ||
| 1700 | ctx->train_data_size = GDDR6_MEM_TRAINING_DATA_SIZE_IN_BYTES; | ||
| 1701 | |||
| 1702 | DRM_DEBUG("train_data_size:%llx,p2c_train_data_offset:%llx,c2p_train_data_offset:%llx.\n", | ||
| 1703 | ctx->train_data_size, | ||
| 1704 | ctx->p2c_train_data_offset, | ||
| 1705 | ctx->c2p_train_data_offset); | ||
| 1706 | |||
| 1707 | ret = amdgpu_bo_create_kernel_at(adev, | ||
| 1708 | ctx->p2c_train_data_offset, | ||
| 1709 | ctx->train_data_size, | ||
| 1710 | AMDGPU_GEM_DOMAIN_VRAM, | ||
| 1711 | &ctx->p2c_bo, | ||
| 1712 | NULL); | ||
| 1713 | if (ret) { | ||
| 1714 | DRM_ERROR("alloc p2c_bo failed(%d)!\n", ret); | ||
| 1715 | goto Err_out; | ||
| 1716 | } | ||
| 1717 | |||
| 1718 | ret = amdgpu_bo_create_kernel_at(adev, | ||
| 1719 | ctx->c2p_train_data_offset, | ||
| 1720 | ctx->train_data_size, | ||
| 1721 | AMDGPU_GEM_DOMAIN_VRAM, | ||
| 1722 | &ctx->c2p_bo, | ||
| 1723 | NULL); | ||
| 1724 | if (ret) { | ||
| 1725 | DRM_ERROR("alloc c2p_bo failed(%d)!\n", ret); | ||
| 1726 | goto Err_out; | ||
| 1727 | } | ||
| 1728 | |||
| 1729 | ctx->init = PSP_MEM_TRAIN_RESERVE_SUCCESS; | ||
| 1730 | return 0; | ||
| 1731 | |||
| 1732 | Err_out: | ||
| 1733 | amdgpu_ttm_training_reserve_vram_fini(adev); | ||
| 1734 | return ret; | ||
| 1735 | } | ||
| 1736 | |||
| 1655 | /** | 1737 | /** |
| 1656 | * amdgpu_ttm_init - Init the memory management (ttm) as well as various | 1738 | * amdgpu_ttm_init - Init the memory management (ttm) as well as various |
| 1657 | * gtt/vram related fields. | 1739 | * gtt/vram related fields. |
| @@ -1726,6 +1808,14 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) · 68 unmodified lines | |||
| 1726 | return r; | 1808 | return r; |
| 1727 | } | 1809 | } |
| 1728 | 1810 | ||
| 1811 | /* | ||
| 1812 | *The reserved vram for memory training must be pinned to the specified | ||
| 1813 | *place on the VRAM, so reserve it early. | ||
| 1814 | */ | ||
| 1815 | r = amdgpu_ttm_training_reserve_vram_init(adev); | ||
| 1816 | if (r) | ||
| 1817 | return r; | ||
| 1818 | |||
| 1729 | /* allocate memory as required for VGA | 1819 | /* allocate memory as required for VGA |
| 1730 | * This is used for VGA emulation and pre-OS scanout buffers to | 1820 | * This is used for VGA emulation and pre-OS scanout buffers to |
| 1731 | * avoid display artifacts while transitioning between pre-OS | 1821 | * avoid display artifacts while transitioning between pre-OS |
| @@ -1736,6 +1826,20 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) · 4 unmodified lines | |||
| 1736 | NULL, &stolen_vga_buf); | 1826 | NULL, &stolen_vga_buf); |
| 1737 | if (r) | 1827 | if (r) |
| 1738 | return r; | 1828 | return r; |
| 1829 | |||
| 1830 | /* | ||
| 1831 | * reserve one TMR (64K) memory at the top of VRAM which holds | ||
| 1832 | * IP Discovery data and is protected by PSP. | ||
| 1833 | */ | ||
| 1834 | r = amdgpu_bo_create_kernel_at(adev, | ||
| 1835 | adev->gmc.real_vram_size - DISCOVERY_TMR_SIZE, | ||
| 1836 | DISCOVERY_TMR_SIZE, | ||
| 1837 | AMDGPU_GEM_DOMAIN_VRAM, | ||
| 1838 | &adev->discovery_memory, | ||
| 1839 | NULL); | ||
| 1840 | if (r) | ||
| 1841 | return r; | ||
| 1842 | |||
| 1739 | DRM_INFO("amdgpu: %uM of VRAM memory ready\n", | 1843 | DRM_INFO("amdgpu: %uM of VRAM memory ready\n", |
| 1740 | (unsigned) (adev->gmc.real_vram_size / (1024 * 1024))); | 1844 | (unsigned) (adev->gmc.real_vram_size / (1024 * 1024))); |
| 1741 | 1845 | ||
| @@ -1800,6 +1904,9 @@ void amdgpu_ttm_late_init(struct amdgpu_device *adev) · 58 unmodified lines | |||
| 1800 | void *stolen_vga_buf; | 1904 | void *stolen_vga_buf; |
| 1801 | /* return the VGA stolen memory (if any) back to VRAM */ | 1905 | /* return the VGA stolen memory (if any) back to VRAM */ |
| 1802 | amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, &stolen_vga_buf); | 1906 | amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, &stolen_vga_buf); |
| 1907 | |||
| 1908 | /* return the IP Discovery TMR memory back to VRAM */ | ||
| 1909 | amdgpu_bo_free_kernel(&adev->discovery_memory, NULL, NULL); | ||
| 1803 | } | 1910 | } |
| 1804 | 1911 | ||
| 1805 | /** | 1912 | /** |
| @@ -1811,6 +1918,7 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev) · 5 unmodified lines | |||
| 1811 | return; | 1918 | return; |
| 1812 | 1919 | ||
| 1813 | amdgpu_ttm_debugfs_fini(adev); | 1920 | amdgpu_ttm_debugfs_fini(adev); |
| 1921 | amdgpu_ttm_training_reserve_vram_fini(adev); | ||
| 1814 | amdgpu_ttm_fw_reserve_vram_fini(adev); | 1922 | amdgpu_ttm_fw_reserve_vram_fini(adev); |
| 1815 | if (adev->mman.aper_base_kaddr) | 1923 | if (adev->mman.aper_base_kaddr) |
| 1816 | iounmap(adev->mman.aper_base_kaddr); | 1924 | iounmap(adev->mman.aper_base_kaddr); |
| @@ -1907,10 +2015,7 @@ static int amdgpu_map_buffer(struct ttm_buffer_object *bo, · 90 unmodified lines | |||
| 1907 | *addr += (u64)window * AMDGPU_GTT_MAX_TRANSFER_SIZE * | 2015 | *addr += (u64)window * AMDGPU_GTT_MAX_TRANSFER_SIZE * |
| 1908 | AMDGPU_GPU_PAGE_SIZE; | 2016 | AMDGPU_GPU_PAGE_SIZE; |
| 1909 | 2017 | ||
| 1910 | num_dw = adev->mman.buffer_funcs->copy_num_dw; | 2018 | num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8); |
| 1911 | while (num_dw & 0x7) | ||
| 1912 | num_dw++; | ||
| 1913 | |||
| 1914 | num_bytes = num_pages * 8; | 2019 | num_bytes = num_pages * 8; |
| 1915 | 2020 | ||
| 1916 | r = amdgpu_job_alloc_with_ib(adev, num_dw * 4 + num_bytes, &job); | 2021 | r = amdgpu_job_alloc_with_ib(adev, num_dw * 4 + num_bytes, &job); |
| @@ -1970,11 +2075,7 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset, · 53 unmodified lines | |||
| 1970 | 2075 | ||
| 1971 | max_bytes = adev->mman.buffer_funcs->copy_max_bytes; | 2076 | max_bytes = adev->mman.buffer_funcs->copy_max_bytes; |
| 1972 | num_loops = DIV_ROUND_UP(byte_count, max_bytes); | 2077 | num_loops = DIV_ROUND_UP(byte_count, max_bytes); |
| 1973 | num_dw = num_loops * adev->mman.buffer_funcs->copy_num_dw; | 2078 | num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->copy_num_dw, 8); |
| 1974 | |||
| 1975 | /* for IB padding */ | ||
| 1976 | while (num_dw & 0x7) | ||
| 1977 | num_dw++; | ||
| 1978 | 2079 | ||
| 1979 | r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, &job); | 2080 | r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, &job); |
| 1980 | if (r) | 2081 | if (r) |
| @@ -80,6 +80,11 @@ MODULE_FIRMWARE(FIRMWARE_VEGA12); · 79 unmodified lines | |||
| 80 | MODULE_FIRMWARE(FIRMWARE_VEGA20); | 80 | MODULE_FIRMWARE(FIRMWARE_VEGA20); |
| 81 | 81 | ||
| 82 | static void amdgpu_vce_idle_work_handler(struct work_struct *work); | 82 | static void amdgpu_vce_idle_work_handler(struct work_struct *work); |
| 83 | static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, | ||
| 84 | struct amdgpu_bo *bo, | ||
| 85 | struct dma_fence **fence); | ||
| 86 | static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, | ||
| 87 | bool direct, struct dma_fence **fence); | ||
| 83 | 88 | ||
| 84 | /** | 89 | /** |
| 85 | * amdgpu_vce_init - allocate memory, load vce firmware | 90 | * amdgpu_vce_init - allocate memory, load vce firmware |
| @@ -428,14 +433,15 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp) · 342 unmodified lines | |||
| 428 | * | 433 | * |
| 429 | * Open up a stream for HW test | 434 | * Open up a stream for HW test |
| 430 | */ | 435 | */ |
| 431 | int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, | 436 | static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, |
| 432 | struct dma_fence **fence) | 437 | struct amdgpu_bo *bo, |
| 438 | struct dma_fence **fence) | ||
| 433 | { | 439 | { |
| 434 | const unsigned ib_size_dw = 1024; | 440 | const unsigned ib_size_dw = 1024; |
| 435 | struct amdgpu_job *job; | 441 | struct amdgpu_job *job; |
| 436 | struct amdgpu_ib *ib; | 442 | struct amdgpu_ib *ib; |
| 437 | struct dma_fence *f = NULL; | 443 | struct dma_fence *f = NULL; |
| 438 | uint64_t dummy; | 444 | uint64_t addr; |
| 439 | int i, r; | 445 | int i, r; |
| 440 | 446 | ||
| 441 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); | 447 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); |
| @@ -444,7 +450,7 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, · 2 unmodified lines | |||
| 444 | 450 | ||
| 445 | ib = &job->ibs[0]; | 451 | ib = &job->ibs[0]; |
| 446 | 452 | ||
| 447 | dummy = ib->gpu_addr + 1024; | 453 | addr = amdgpu_bo_gpu_offset(bo); |
| 448 | 454 | ||
| 449 | /* stitch together an VCE create msg */ | 455 | /* stitch together an VCE create msg */ |
| 450 | ib->length_dw = 0; | 456 | ib->length_dw = 0; |
| @@ -476,8 +482,8 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, · 25 unmodified lines | |||
| 476 | 482 | ||
| 477 | ib->ptr[ib->length_dw++] = 0x00000014; /* len */ | 483 | ib->ptr[ib->length_dw++] = 0x00000014; /* len */ |
| 478 | ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */ | 484 | ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */ |
| 479 | ib->ptr[ib->length_dw++] = upper_32_bits(dummy); | 485 | ib->ptr[ib->length_dw++] = upper_32_bits(addr); |
| 480 | ib->ptr[ib->length_dw++] = dummy; | 486 | ib->ptr[ib->length_dw++] = addr; |
| 481 | ib->ptr[ib->length_dw++] = 0x00000001; | 487 | ib->ptr[ib->length_dw++] = 0x00000001; |
| 482 | 488 | ||
| 483 | for (i = ib->length_dw; i < ib_size_dw; ++i) | 489 | for (i = ib->length_dw; i < ib_size_dw; ++i) |
| @@ -507,8 +513,8 @@ err: · 23 unmodified lines | |||
| 507 | * | 513 | * |
| 508 | * Close up a stream for HW test or if userspace failed to do so | 514 | * Close up a stream for HW test or if userspace failed to do so |
| 509 | */ | 515 | */ |
| 510 | int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, | 516 | static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, |
| 511 | bool direct, struct dma_fence **fence) | 517 | bool direct, struct dma_fence **fence) |
| 512 | { | 518 | { |
| 513 | const unsigned ib_size_dw = 1024; | 519 | const unsigned ib_size_dw = 1024; |
| 514 | struct amdgpu_job *job; | 520 | struct amdgpu_job *job; |
| @@ -1110,13 +1116,20 @@ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring) · 595 unmodified lines | |||
| 1110 | int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout) | 1116 | int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout) |
| 1111 | { | 1117 | { |
| 1112 | struct dma_fence *fence = NULL; | 1118 | struct dma_fence *fence = NULL; |
| 1119 | struct amdgpu_bo *bo = NULL; | ||
| 1113 | long r; | 1120 | long r; |
| 1114 | 1121 | ||
| 1115 | /* skip vce ring1/2 ib test for now, since it's not reliable */ | 1122 | /* skip vce ring1/2 ib test for now, since it's not reliable */ |
| 1116 | if (ring != &ring->adev->vce.ring[0]) | 1123 | if (ring != &ring->adev->vce.ring[0]) |
| 1117 | return 0; | 1124 | return 0; |
| 1118 | 1125 | ||
| 1119 | r = amdgpu_vce_get_create_msg(ring, 1, NULL); | 1126 | r = amdgpu_bo_create_reserved(ring->adev, 512, PAGE_SIZE, |
| 1127 | AMDGPU_GEM_DOMAIN_VRAM, | ||
| 1128 | &bo, NULL, NULL); | ||
| 1129 | if (r) | ||
| 1130 | return r; | ||
| 1131 | |||
| 1132 | r = amdgpu_vce_get_create_msg(ring, 1, bo, NULL); | ||
| 1120 | if (r) | 1133 | if (r) |
| 1121 | goto error; | 1134 | goto error; |
| 1122 | 1135 | ||
| @@ -1132,5 +1145,7 @@ int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout) · 9 unmodified lines | |||
| 1132 | 1145 | ||
| 1133 | error: | 1146 | error: |
| 1134 | dma_fence_put(fence); | 1147 | dma_fence_put(fence); |
| 1148 | amdgpu_bo_unreserve(bo); | ||
| 1149 | amdgpu_bo_unref(&bo); | ||
| 1135 | return r; | 1150 | return r; |
| 1136 | } | 1151 | } |
| @@ -58,10 +58,6 @@ int amdgpu_vce_sw_fini(struct amdgpu_device *adev); · 57 unmodified lines | |||
| 58 | int amdgpu_vce_entity_init(struct amdgpu_device *adev); | 58 | int amdgpu_vce_entity_init(struct amdgpu_device *adev); |
| 59 | int amdgpu_vce_suspend(struct amdgpu_device *adev); | 59 | int amdgpu_vce_suspend(struct amdgpu_device *adev); |
| 60 | int amdgpu_vce_resume(struct amdgpu_device *adev); | 60 | int amdgpu_vce_resume(struct amdgpu_device *adev); |
| 61 | int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, | ||
| 62 | struct dma_fence **fence); | ||
| 63 | int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, | ||
| 64 | bool direct, struct dma_fence **fence); | ||
| 65 | void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp); | 61 | void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp); |
| 66 | int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx); | 62 | int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx); |
| 67 | int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p, uint32_t ib_idx); | 63 | int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p, uint32_t ib_idx); |
| @@ -569,13 +569,14 @@ int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring) · 568 unmodified lines | |||
| 569 | } | 569 | } |
| 570 | 570 | ||
| 571 | static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, | 571 | static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, |
| 572 | struct dma_fence **fence) | 572 | struct amdgpu_bo *bo, |
| 573 | struct dma_fence **fence) | ||
| 573 | { | 574 | { |
| 574 | const unsigned ib_size_dw = 16; | 575 | const unsigned ib_size_dw = 16; |
| 575 | struct amdgpu_job *job; | 576 | struct amdgpu_job *job; |
| 576 | struct amdgpu_ib *ib; | 577 | struct amdgpu_ib *ib; |
| 577 | struct dma_fence *f = NULL; | 578 | struct dma_fence *f = NULL; |
| 578 | uint64_t dummy; | 579 | uint64_t addr; |
| 579 | int i, r; | 580 | int i, r; |
| 580 | 581 | ||
| 581 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); | 582 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); |
| @@ -583,14 +584,14 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t hand · 1 unmodified line | |||
| 583 | return r; | 584 | return r; |
| 584 | 585 | ||
| 585 | ib = &job->ibs[0]; | 586 | ib = &job->ibs[0]; |
| 586 | dummy = ib->gpu_addr + 1024; | 587 | addr = amdgpu_bo_gpu_offset(bo); |
| 587 | 588 | ||
| 588 | ib->length_dw = 0; | 589 | ib->length_dw = 0; |
| 589 | ib->ptr[ib->length_dw++] = 0x00000018; | 590 | ib->ptr[ib->length_dw++] = 0x00000018; |
| 590 | ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ | 591 | ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ |
| 591 | ib->ptr[ib->length_dw++] = handle; | 592 | ib->ptr[ib->length_dw++] = handle; |
| 592 | ib->ptr[ib->length_dw++] = upper_32_bits(dummy); | 593 | ib->ptr[ib->length_dw++] = upper_32_bits(addr); |
| 593 | ib->ptr[ib->length_dw++] = dummy; | 594 | ib->ptr[ib->length_dw++] = addr; |
| 594 | ib->ptr[ib->length_dw++] = 0x0000000b; | 595 | ib->ptr[ib->length_dw++] = 0x0000000b; |
| 595 | 596 | ||
| 596 | ib->ptr[ib->length_dw++] = 0x00000014; | 597 | ib->ptr[ib->length_dw++] = 0x00000014; |
| @@ -621,13 +622,14 @@ err: · 24 unmodified lines | |||
| 621 | } | 622 | } |
| 622 | 623 | ||
| 623 | static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, | 624 | static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, |
| 624 | struct dma_fence **fence) | 625 | struct amdgpu_bo *bo, |
| 626 | struct dma_fence **fence) | ||
| 625 | { | 627 | { |
| 626 | const unsigned ib_size_dw = 16; | 628 | const unsigned ib_size_dw = 16; |
| 627 | struct amdgpu_job *job; | 629 | struct amdgpu_job *job; |
| 628 | struct amdgpu_ib *ib; | 630 | struct amdgpu_ib *ib; |
| 629 | struct dma_fence *f = NULL; | 631 | struct dma_fence *f = NULL; |
| 630 | uint64_t dummy; | 632 | uint64_t addr; |
| 631 | int i, r; | 633 | int i, r; |
| 632 | 634 | ||
| 633 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); | 635 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); |
| @@ -635,14 +637,14 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han · 1 unmodified line | |||
| 635 | return r; | 637 | return r; |
| 636 | 638 | ||
| 637 | ib = &job->ibs[0]; | 639 | ib = &job->ibs[0]; |
| 638 | dummy = ib->gpu_addr + 1024; | 640 | addr = amdgpu_bo_gpu_offset(bo); |
| 639 | 641 | ||
| 640 | ib->length_dw = 0; | 642 | ib->length_dw = 0; |
| 641 | ib->ptr[ib->length_dw++] = 0x00000018; | 643 | ib->ptr[ib->length_dw++] = 0x00000018; |
| 642 | ib->ptr[ib->length_dw++] = 0x00000001; | 644 | ib->ptr[ib->length_dw++] = 0x00000001; |
| 643 | ib->ptr[ib->length_dw++] = handle; | 645 | ib->ptr[ib->length_dw++] = handle; |
| 644 | ib->ptr[ib->length_dw++] = upper_32_bits(dummy); | 646 | ib->ptr[ib->length_dw++] = upper_32_bits(addr); |
| 645 | ib->ptr[ib->length_dw++] = dummy; | 647 | ib->ptr[ib->length_dw++] = addr; |
| 646 | ib->ptr[ib->length_dw++] = 0x0000000b; | 648 | ib->ptr[ib->length_dw++] = 0x0000000b; |
| 647 | 649 | ||
| 648 | ib->ptr[ib->length_dw++] = 0x00000014; | 650 | ib->ptr[ib->length_dw++] = 0x00000014; |
| @@ -675,13 +677,20 @@ err: · 26 unmodified lines | |||
| 675 | int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) | 677 | int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) |
| 676 | { | 678 | { |
| 677 | struct dma_fence *fence = NULL; | 679 | struct dma_fence *fence = NULL; |
| 680 | struct amdgpu_bo *bo = NULL; | ||
| 678 | long r; | 681 | long r; |
| 679 | 682 | ||
| 680 | r = amdgpu_vcn_enc_get_create_msg(ring, 1, NULL); | 683 | r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE, |
| 684 | AMDGPU_GEM_DOMAIN_VRAM, | ||
| 685 | &bo, NULL, NULL); | ||
| 686 | if (r) | ||
| 687 | return r; | ||
| 688 | |||
| 689 | r = amdgpu_vcn_enc_get_create_msg(ring, 1, bo, NULL); | ||
| 681 | if (r) | 690 | if (r) |
| 682 | goto error; | 691 | goto error; |
| 683 | 692 | ||
| 684 | r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, &fence); | 693 | r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, bo, &fence); |
| 685 | if (r) | 694 | if (r) |
| 686 | goto error; | 695 | goto error; |
| 687 | 696 | ||
| @@ -693,6 +702,8 @@ int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) · 5 unmodified lines | |||
| 693 | 702 | ||
| 694 | error: | 703 | error: |
| 695 | dma_fence_put(fence); | 704 | dma_fence_put(fence); |
| 705 | amdgpu_bo_unreserve(bo); | ||
| 706 | amdgpu_bo_unref(&bo); | ||
| 696 | return r; | 707 | return r; |
| 697 | } | 708 | } |
| 698 | 709 | ||
| @@ -2971,6 +2971,16 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) · 2970 unmodified lines | |||
| 2971 | vm->pasid = 0; | 2971 | vm->pasid = 0; |
| 2972 | } | 2972 | } |
| 2973 | 2973 | ||
| 2974 | list_for_each_entry_safe(mapping, tmp, &vm->freed, list) { | ||
| 2975 | if (mapping->flags & AMDGPU_PTE_PRT && prt_fini_needed) { | ||
| 2976 | amdgpu_vm_prt_fini(adev, vm); | ||
| 2977 | prt_fini_needed = false; | ||
| 2978 | } | ||
| 2979 | |||
| 2980 | list_del(&mapping->list); | ||
| 2981 | amdgpu_vm_free_mapping(adev, vm, mapping, NULL); | ||
| 2982 | } | ||
| 2983 | |||
| 2974 | amdgpu_vm_free_pts(adev, vm, NULL); | 2984 | amdgpu_vm_free_pts(adev, vm, NULL); |
| 2975 | amdgpu_bo_unreserve(root); | 2985 | amdgpu_bo_unreserve(root); |
| 2976 | amdgpu_bo_unref(&root); | 2986 | amdgpu_bo_unref(&root); |
| @@ -2990,15 +3000,6 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) · 13 unmodified lines | |||
| 2990 | list_del(&mapping->list); | 3000 | list_del(&mapping->list); |
| 2991 | kfree(mapping); | 3001 | kfree(mapping); |
| 2992 | } | 3002 | } |
| 2993 | list_for_each_entry_safe(mapping, tmp, &vm->freed, list) { | ||
| 2994 | if (mapping->flags & AMDGPU_PTE_PRT && prt_fini_needed) { | ||
| 2995 | amdgpu_vm_prt_fini(adev, vm); | ||
| 2996 | prt_fini_needed = false; | ||
| 2997 | } | ||
| 2998 | |||
| 2999 | list_del(&mapping->list); | ||
| 3000 | amdgpu_vm_free_mapping(adev, vm, mapping, NULL); | ||
| 3001 | } | ||
| 3002 | 3003 | ||
| 3003 | dma_fence_put(vm->last_update); | 3004 | dma_fence_put(vm->last_update); |
| 3004 | for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) | 3005 | for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) |
| @@ -1270,15 +1270,15 @@ static int cik_gpu_pci_config_reset(struct amdgpu_device *adev) · 1269 unmodified lines | |||
| 1270 | } | 1270 | } |
| 1271 | 1271 | ||
| 1272 | /** | 1272 | /** |
| 1273 | * cik_asic_reset - soft reset GPU | 1273 | * cik_asic_pci_config_reset - soft reset GPU |
| 1274 | * | 1274 | * |
| 1275 | * @adev: amdgpu_device pointer | 1275 | * @adev: amdgpu_device pointer |
| 1276 | * | 1276 | * |
| 1277 | * Look up which blocks are hung and attempt | 1277 | * Use PCI Config method to reset the GPU. |
| 1278 | * to reset them. | 1278 | * |
| 1279 | * Returns 0 for success. | 1279 | * Returns 0 for success. |
| 1280 | */ | 1280 | */ |
| 1281 | static int cik_asic_reset(struct amdgpu_device *adev) | 1281 | static int cik_asic_pci_config_reset(struct amdgpu_device *adev) |
| 1282 | { | 1282 | { |
| 1283 | int r; | 1283 | int r; |
| 1284 | 1284 | ||
| @@ -1294,7 +1294,45 @@ static int cik_asic_reset(struct amdgpu_device *adev) · 9 unmodified lines | |||
| 1294 | static enum amd_reset_method | 1294 | static enum amd_reset_method |
| 1295 | cik_asic_reset_method(struct amdgpu_device *adev) | 1295 | cik_asic_reset_method(struct amdgpu_device *adev) |
| 1296 | { | 1296 | { |
| 1297 | return AMD_RESET_METHOD_LEGACY; | 1297 | bool baco_reset; |
| 1298 | |||
| 1299 | switch (adev->asic_type) { | ||
| 1300 | case CHIP_BONAIRE: | ||
| 1301 | case CHIP_HAWAII: | ||
| 1302 | /* disable baco reset until it works */ | ||
| 1303 | /* smu7_asic_get_baco_capability(adev, &baco_reset); */ | ||
| 1304 | baco_reset = false; | ||
| 1305 | break; | ||
| 1306 | default: | ||
| 1307 | baco_reset = false; | ||
| 1308 | break; | ||
| 1309 | } | ||
| 1310 | |||
| 1311 | if (baco_reset) | ||
| 1312 | return AMD_RESET_METHOD_BACO; | ||
| 1313 | else | ||
| 1314 | return AMD_RESET_METHOD_LEGACY; | ||
| 1315 | } | ||
| 1316 | |||
| 1317 | /** | ||
| 1318 | * cik_asic_reset - soft reset GPU | ||
| 1319 | * | ||
| 1320 | * @adev: amdgpu_device pointer | ||
| 1321 | * | ||
| 1322 | * Look up which blocks are hung and attempt | ||
| 1323 | * to reset them. | ||
| 1324 | * Returns 0 for success. | ||
| 1325 | */ | ||
| 1326 | static int cik_asic_reset(struct amdgpu_device *adev) | ||
| 1327 | { | ||
| 1328 | int r; | ||
| 1329 | |||
| 1330 | if (cik_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) | ||
| 1331 | r = smu7_asic_baco_reset(adev); | ||
| 1332 | else | ||
| 1333 | r = cik_asic_pci_config_reset(adev); | ||
| 1334 | |||
| 1335 | return r; | ||
| 1298 | } | 1336 | } |
| 1299 | 1337 | ||
| 1300 | static u32 cik_get_config_memsize(struct amdgpu_device *adev) | 1338 | static u32 cik_get_config_memsize(struct amdgpu_device *adev) |
| @@ -31,4 +31,7 @@ void cik_srbm_select(struct amdgpu_device *adev, · 30 unmodified lines | |||
| 31 | int cik_set_ip_blocks(struct amdgpu_device *adev); | 31 | int cik_set_ip_blocks(struct amdgpu_device *adev); |
| 32 | 32 | ||
| 33 | void legacy_doorbell_index_init(struct amdgpu_device *adev); | 33 | void legacy_doorbell_index_init(struct amdgpu_device *adev); |
| 34 | int smu7_asic_get_baco_capability(struct amdgpu_device *adev, bool *cap); | ||
| 35 | int smu7_asic_baco_reset(struct amdgpu_device *adev); | ||
| 36 | |||
| 34 | #endif | 37 | #endif |
| @@ -5283,15 +5283,12 @@ static void gfx_v10_0_set_rlc_funcs(struct amdgpu_device *adev) · 5282 unmodified lines | |||
| 5283 | 5283 | ||
| 5284 | static void gfx_v10_0_set_gds_init(struct amdgpu_device *adev) | 5284 | static void gfx_v10_0_set_gds_init(struct amdgpu_device *adev) |
| 5285 | { | 5285 | { |
| 5286 | /* init asic gds info */ | 5286 | unsigned total_cu = adev->gfx.config.max_cu_per_sh * |
| 5287 | switch (adev->asic_type) { | 5287 | adev->gfx.config.max_sh_per_se * |
| 5288 | case CHIP_NAVI10: | 5288 | adev->gfx.config.max_shader_engines; |
| 5289 | default: | ||
| 5290 | adev->gds.gds_size = 0x10000; | ||
| 5291 | adev->gds.gds_compute_max_wave_id = 0x4ff; | ||
| 5292 | break; | ||
| 5293 | } | ||
| 5294 | 5289 | ||
| 5290 | adev->gds.gds_size = 0x10000; | ||
| 5291 | adev->gds.gds_compute_max_wave_id = total_cu * 32 - 1; | ||
| 5295 | adev->gds.gws_size = 64; | 5292 | adev->gds.gws_size = 64; |
| 5296 | adev->gds.oa_size = 16; | 5293 | adev->gds.oa_size = 16; |
| 5297 | } | 5294 | } |
| @@ -131,6 +131,18 @@ MODULE_FIRMWARE("amdgpu/renoir_rlc.bin"); · 130 unmodified lines | |||
| 131 | #define mmTCP_CHAN_STEER_5_ARCT 0x0b0c | 131 | #define mmTCP_CHAN_STEER_5_ARCT 0x0b0c |
| 132 | #define mmTCP_CHAN_STEER_5_ARCT_BASE_IDX 0 | 132 | #define mmTCP_CHAN_STEER_5_ARCT_BASE_IDX 0 |
| 133 | 133 | ||
| 134 | struct ras_gfx_subblock_reg { | ||
| 135 | const char *name; | ||
| 136 | uint32_t hwip; | ||
| 137 | uint32_t inst; | ||
| 138 | uint32_t seg; | ||
| 139 | uint32_t reg_offset; | ||
| 140 | uint32_t sec_count_mask; | ||
| 141 | uint32_t sec_count_shift; | ||
| 142 | uint32_t ded_count_mask; | ||
| 143 | uint32_t ded_count_shift; | ||
| 144 | }; | ||
| 145 | |||
| 134 | enum ta_ras_gfx_subblock { | 146 | enum ta_ras_gfx_subblock { |
| 135 | /*CPC*/ | 147 | /*CPC*/ |
| 136 | TA_RAS_BLOCK__GFX_CPC_INDEX_START = 0, | 148 | TA_RAS_BLOCK__GFX_CPC_INDEX_START = 0, |
| @@ -3978,6 +3990,7 @@ static const struct soc15_reg_entry sec_ded_counter_registers[] = { · 3841 unmodified lines | |||
| 3978 | { SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 1, 16}, | 3990 | { SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 1, 16}, |
| 3979 | { SOC15_REG_ENTRY(GC, 0, mmTCP_ATC_EDC_GATCL1_CNT), 0, 4, 16}, | 3991 | { SOC15_REG_ENTRY(GC, 0, mmTCP_ATC_EDC_GATCL1_CNT), 0, 4, 16}, |
| 3980 | { SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT), 0, 4, 16}, | 3992 | { SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT), 0, 4, 16}, |
| 3993 | { SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 0, 4, 16}, | ||
| 3981 | { SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 0, 4, 16}, | 3994 | { SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 0, 4, 16}, |
| 3982 | { SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 0, 4, 6}, | 3995 | { SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 0, 4, 6}, |
| 3983 | { SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 0, 4, 16}, | 3996 | { SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 0, 4, 16}, |
| @@ -4274,16 +4287,14 @@ static void gfx_v9_0_update_gfx_cg_power_gating(struct amdgpu_device *adev, · 290 unmodified lines | |||
| 4274 | { | 4287 | { |
| 4275 | amdgpu_gfx_rlc_enter_safe_mode(adev); | 4288 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
| 4276 | 4289 | ||
| 4277 | if (is_support_sw_smu(adev) && !enable) | ||
| 4278 | smu_set_gfx_cgpg(&adev->smu, enable); | ||
| 4279 | |||
| 4280 | if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_PG) && enable) { | 4290 | if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_PG) && enable) { |
| 4281 | gfx_v9_0_enable_gfx_cg_power_gating(adev, true); | 4291 | gfx_v9_0_enable_gfx_cg_power_gating(adev, true); |
| 4282 | if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PIPELINE) | 4292 | if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PIPELINE) |
| 4283 | gfx_v9_0_enable_gfx_pipeline_powergating(adev, true); | 4293 | gfx_v9_0_enable_gfx_pipeline_powergating(adev, true); |
| 4284 | } else { | 4294 | } else { |
| 4285 | gfx_v9_0_enable_gfx_cg_power_gating(adev, false); | 4295 | gfx_v9_0_enable_gfx_cg_power_gating(adev, false); |
| 4286 | gfx_v9_0_enable_gfx_pipeline_powergating(adev, false); | 4296 | if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PIPELINE) |
| 4297 | gfx_v9_0_enable_gfx_pipeline_powergating(adev, false); | ||
| 4287 | } | 4298 | } |
| 4288 | 4299 | ||
| 4289 | amdgpu_gfx_rlc_exit_safe_mode(adev); | 4300 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
| @@ -4552,8 +4563,6 @@ static int gfx_v9_0_set_powergating_state(void *handle, · 262 unmodified lines | |||
| 4552 | gfx_v9_0_enable_cp_power_gating(adev, false); | 4563 | gfx_v9_0_enable_cp_power_gating(adev, false); |
| 4553 | 4564 | ||
| 4554 | /* update gfx cgpg state */ | 4565 | /* update gfx cgpg state */ |
| 4555 | if (is_support_sw_smu(adev) && enable) | ||
| 4556 | smu_set_gfx_cgpg(&adev->smu, enable); | ||
| 4557 | gfx_v9_0_update_gfx_cg_power_gating(adev, enable); | 4566 | gfx_v9_0_update_gfx_cg_power_gating(adev, enable); |
| 4558 | 4567 | ||
| 4559 | /* update mgcg state */ | 4568 | /* update mgcg state */ |
| @@ -5437,301 +5446,446 @@ static int gfx_v9_0_priv_inst_irq(struct amdgpu_device *adev, · 877 unmodified lines | |||
| 5437 | return 0; | 5446 | return 0; |
| 5438 | } | 5447 | } |
| 5439 | 5448 | ||
| 5440 | static const struct { | 5449 | |
| 5441 | const char *name; | 5450 | static const struct ras_gfx_subblock_reg ras_subblock_regs[] = { |
| 5442 | uint32_t ip; | 5451 | { "CPC_SCRATCH", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_SCRATCH_CNT), |
| 5443 | uint32_t inst; | 5452 | SOC15_REG_FIELD(CPC_EDC_SCRATCH_CNT, SEC_COUNT), |
| 5444 | uint32_t seg; | 5453 | SOC15_REG_FIELD(CPC_EDC_SCRATCH_CNT, DED_COUNT) |
| 5445 | uint32_t reg_offset; | 5454 | }, |
| 5446 | uint32_t per_se_instance; | 5455 | { "CPC_UCODE", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_UCODE_CNT), |
| 5447 | int32_t num_instance; | 5456 | SOC15_REG_FIELD(CPC_EDC_UCODE_CNT, SEC_COUNT), |
| 5448 | uint32_t sec_count_mask; | 5457 | SOC15_REG_FIELD(CPC_EDC_UCODE_CNT, DED_COUNT) |
| 5449 | uint32_t ded_count_mask; | 5458 | }, |
| 5450 | } gfx_ras_edc_regs[] = { | 5459 | { "CPF_ROQ_ME1", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT), |
| 5451 | { "CPC_SCRATCH", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_SCRATCH_CNT), 0, 1, | 5460 | SOC15_REG_FIELD(CPF_EDC_ROQ_CNT, COUNT_ME1), |
| 5452 | REG_FIELD_MASK(CPC_EDC_SCRATCH_CNT, SEC_COUNT), | 5461 | 0, 0 |
| 5453 | REG_FIELD_MASK(CPC_EDC_SCRATCH_CNT, DED_COUNT) }, | 5462 | }, |
| 5454 | { "CPC_UCODE", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_UCODE_CNT), 0, 1, | 5463 | { "CPF_ROQ_ME2", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT), |
| 5455 | REG_FIELD_MASK(CPC_EDC_UCODE_CNT, SEC_COUNT), | 5464 | SOC15_REG_FIELD(CPF_EDC_ROQ_CNT, COUNT_ME2), |
| 5456 | REG_FIELD_MASK(CPC_EDC_UCODE_CNT, DED_COUNT) }, | 5465 | 0, 0 |
| 5457 | { "CPF_ROQ_ME1", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT), 0, 1, | 5466 | }, |
| 5458 | REG_FIELD_MASK(CPF_EDC_ROQ_CNT, COUNT_ME1), 0 }, | 5467 | { "CPF_TAG", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_TAG_CNT), |
| 5459 | { "CPF_ROQ_ME2", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT), 0, 1, | 5468 | SOC15_REG_FIELD(CPF_EDC_TAG_CNT, SEC_COUNT), |
| 5460 | REG_FIELD_MASK(CPF_EDC_ROQ_CNT, COUNT_ME2), 0 }, | 5469 | SOC15_REG_FIELD(CPF_EDC_TAG_CNT, DED_COUNT) |
| 5461 | { "CPF_TAG", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_TAG_CNT), 0, 1, | 5470 | }, |
| 5462 | REG_FIELD_MASK(CPF_EDC_TAG_CNT, SEC_COUNT), | 5471 | { "CPG_DMA_ROQ", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_DMA_CNT), |
| 5463 | REG_FIELD_MASK(CPF_EDC_TAG_CNT, DED_COUNT) }, | 5472 | SOC15_REG_FIELD(CPG_EDC_DMA_CNT, ROQ_COUNT), |
| 5464 | { "CPG_DMA_ROQ", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_DMA_CNT), 0, 1, | 5473 | 0, 0 |
| 5465 | REG_FIELD_MASK(CPG_EDC_DMA_CNT, ROQ_COUNT), 0 }, | 5474 | }, |
| 5466 | { "CPG_DMA_TAG", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_DMA_CNT), 0, 1, | 5475 | { "CPG_DMA_TAG", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_DMA_CNT), |
| 5467 | REG_FIELD_MASK(CPG_EDC_DMA_CNT, TAG_SEC_COUNT), | 5476 | SOC15_REG_FIELD(CPG_EDC_DMA_CNT, TAG_SEC_COUNT), |
| 5468 | REG_FIELD_MASK(CPG_EDC_DMA_CNT, TAG_DED_COUNT) }, | 5477 | SOC15_REG_FIELD(CPG_EDC_DMA_CNT, TAG_DED_COUNT) |
| 5469 | { "CPG_TAG", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_TAG_CNT), 0, 1, | 5478 | }, |
| 5470 | REG_FIELD_MASK(CPG_EDC_TAG_CNT, SEC_COUNT), | 5479 | { "CPG_TAG", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_TAG_CNT), |
| 5471 | REG_FIELD_MASK(CPG_EDC_TAG_CNT, DED_COUNT) }, | 5480 | SOC15_REG_FIELD(CPG_EDC_TAG_CNT, SEC_COUNT), |
| 5472 | { "DC_CSINVOC", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_CSINVOC_CNT), 0, 1, | 5481 | SOC15_REG_FIELD(CPG_EDC_TAG_CNT, DED_COUNT) |
| 5473 | REG_FIELD_MASK(DC_EDC_CSINVOC_CNT, COUNT_ME1), 0 }, | 5482 | }, |
| 5474 | { "DC_RESTORE", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_RESTORE_CNT), 0, 1, | 5483 | { "DC_CSINVOC", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_CSINVOC_CNT), |
| 5475 | REG_FIELD_MASK(DC_EDC_RESTORE_CNT, COUNT_ME1), 0 }, | 5484 | SOC15_REG_FIELD(DC_EDC_CSINVOC_CNT, COUNT_ME1), |
| 5476 | { "DC_STATE", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_STATE_CNT), 0, 1, | 5485 | 0, 0 |
| 5477 | REG_FIELD_MASK(DC_EDC_STATE_CNT, COUNT_ME1), 0 }, | 5486 | }, |
| 5478 | { "GDS_MEM", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_CNT), 0, 1, | 5487 | { "DC_RESTORE", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_RESTORE_CNT), |
| 5479 | REG_FIELD_MASK(GDS_EDC_CNT, GDS_MEM_SEC), | 5488 | SOC15_REG_FIELD(DC_EDC_RESTORE_CNT, COUNT_ME1), |
| 5480 | REG_FIELD_MASK(GDS_EDC_CNT, GDS_MEM_DED) }, | 5489 | 0, 0 |
| 5481 | { "GDS_INPUT_QUEUE", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_CNT), 0, 1, | 5490 | }, |
| 5482 | REG_FIELD_MASK(GDS_EDC_CNT, GDS_INPUT_QUEUE_SED), 0 }, | 5491 | { "DC_STATE", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_STATE_CNT), |
| 5492 | SOC15_REG_FIELD(DC_EDC_STATE_CNT, COUNT_ME1), | ||
| 5493 | 0, 0 | ||
| 5494 | }, | ||
| 5495 | { "GDS_MEM", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_CNT), | ||
| 5496 | SOC15_REG_FIELD(GDS_EDC_CNT, GDS_MEM_SEC), | ||
| 5497 | SOC15_REG_FIELD(GDS_EDC_CNT, GDS_MEM_DED) | ||
| 5498 | }, | ||
| 5499 | { "GDS_INPUT_QUEUE", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_CNT), | ||
| 5500 | SOC15_REG_FIELD(GDS_EDC_CNT, GDS_INPUT_QUEUE_SED), | ||
| 5501 | 0, 0 | ||
| 5502 | }, | ||
| 5483 | { "GDS_ME0_CS_PIPE_MEM", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), | 5503 | { "GDS_ME0_CS_PIPE_MEM", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), |
| 5484 | 0, 1, REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_SEC), | 5504 | SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_SEC), |
| 5485 | REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_DED) }, | 5505 | SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_DED) |
| 5506 | }, | ||
| 5486 | { "GDS_OA_PHY_PHY_CMD_RAM_MEM", | 5507 | { "GDS_OA_PHY_PHY_CMD_RAM_MEM", |
| 5487 | SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), 0, 1, | 5508 | SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), |
| 5488 | REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_SEC), | 5509 | SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_SEC), |
| 5489 | REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_DED) }, | 5510 | SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_DED) |
| 5511 | }, | ||
| 5490 | { "GDS_OA_PHY_PHY_DATA_RAM_MEM", | 5512 | { "GDS_OA_PHY_PHY_DATA_RAM_MEM", |
| 5491 | SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), 0, 1, | 5513 | SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), |
| 5492 | REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, PHY_DATA_RAM_MEM_SED), 0 }, | 5514 | SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, PHY_DATA_RAM_MEM_SED), |
| 5515 | 0, 0 | ||
| 5516 | }, | ||
| 5493 | { "GDS_OA_PIPE_ME1_PIPE0_PIPE_MEM", | 5517 | { "GDS_OA_PIPE_ME1_PIPE0_PIPE_MEM", |
| 5494 | SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1, | 5518 | SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), |
| 5495 | REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_SEC), | 5519 | SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_SEC), |
| 5496 | REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_DED) }, | 5520 | SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_DED) |
| 5521 | }, | ||
| 5497 | { "GDS_OA_PIPE_ME1_PIPE1_PIPE_MEM", | 5522 | { "GDS_OA_PIPE_ME1_PIPE1_PIPE_MEM", |
| 5498 | SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1, | 5523 | SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), |
| 5499 | REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_SEC), | 5524 | SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_SEC), |
| 5500 | REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_DED) }, | 5525 | SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_DED) |
| 5526 | }, | ||
| 5501 | { "GDS_OA_PIPE_ME1_PIPE2_PIPE_MEM", | 5527 | { "GDS_OA_PIPE_ME1_PIPE2_PIPE_MEM", |
| 5502 | SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1, | 5528 | SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), |
| 5503 | REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_SEC), | 5529 | SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_SEC), |
| 5504 | REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_DED) }, | 5530 | SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_DED) |
| 5531 | }, | ||
| 5505 | { "GDS_OA_PIPE_ME1_PIPE3_PIPE_MEM", | 5532 | { "GDS_OA_PIPE_ME1_PIPE3_PIPE_MEM", |
| 5506 | SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1, | 5533 | SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), |
| 5507 | REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_SEC), | 5534 | SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_SEC), |
| 5508 | REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_DED) }, | 5535 | SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_DED) |
| 5509 | { "SPI_SR_MEM", SOC15_REG_ENTRY(GC, 0, mmSPI_EDC_CNT), 1, 1, | 5536 | }, |
| 5510 | REG_FIELD_MASK(SPI_EDC_CNT, SPI_SR_MEM_SED_COUNT), 0 }, | 5537 | { "SPI_SR_MEM", SOC15_REG_ENTRY(GC, 0, mmSPI_EDC_CNT), |
| 5511 | { "TA_FS_DFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16, | 5538 | SOC15_REG_FIELD(SPI_EDC_CNT, SPI_SR_MEM_SED_COUNT), |
| 5512 | REG_FIELD_MASK(TA_EDC_CNT, TA_FS_DFIFO_SEC_COUNT), | 5539 | 0, 0 |
| 5513 | REG_FIELD_MASK(TA_EDC_CNT, TA_FS_DFIFO_DED_COUNT) }, | 5540 | }, |
| 5514 | { "TA_FS_AFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16, | 5541 | { "TA_FS_DFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), |
| 5515 | REG_FIELD_MASK(TA_EDC_CNT, TA_FS_AFIFO_SED_COUNT), 0 }, | 5542 | SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_DFIFO_SEC_COUNT), |
| 5516 | { "TA_FL_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16, | 5543 | SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_DFIFO_DED_COUNT) |
| 5517 | REG_FIELD_MASK(TA_EDC_CNT, TA_FL_LFIFO_SED_COUNT), 0 }, | 5544 | }, |
| 5518 | { "TA_FX_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16, | 5545 | { "TA_FS_AFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), |
| 5519 | REG_FIELD_MASK(TA_EDC_CNT, TA_FX_LFIFO_SED_COUNT), 0 }, | 5546 | SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_AFIFO_SED_COUNT), |
| 5520 | { "TA_FS_CFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16, | 5547 | 0, 0 |
| 5521 | REG_FIELD_MASK(TA_EDC_CNT, TA_FS_CFIFO_SED_COUNT), 0 }, | 5548 | }, |
| 5522 | { "TCA_HOLE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT), 0, 2, | 5549 | { "TA_FL_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), |
| 5523 | REG_FIELD_MASK(TCA_EDC_CNT, HOLE_FIFO_SED_COUNT), 0 }, | 5550 | SOC15_REG_FIELD(TA_EDC_CNT, TA_FL_LFIFO_SED_COUNT), |
| 5524 | { "TCA_REQ_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT), 0, 2, | 5551 | 0, 0 |
| 5525 | REG_FIELD_MASK(TCA_EDC_CNT, REQ_FIFO_SED_COUNT), 0 }, | 5552 | }, |
| 5526 | { "TCC_CACHE_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | 5553 | { "TA_FX_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), |
| 5527 | REG_FIELD_MASK(TCC_EDC_CNT, CACHE_DATA_SEC_COUNT), | 5554 | SOC15_REG_FIELD(TA_EDC_CNT, TA_FX_LFIFO_SED_COUNT), |
| 5528 | REG_FIELD_MASK(TCC_EDC_CNT, CACHE_DATA_DED_COUNT) }, | 5555 | 0, 0 |
| 5529 | { "TCC_CACHE_DIRTY", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | 5556 | }, |
| 5530 | REG_FIELD_MASK(TCC_EDC_CNT, CACHE_DIRTY_SEC_COUNT), | 5557 | { "TA_FS_CFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), |
| 5531 | REG_FIELD_MASK(TCC_EDC_CNT, CACHE_DIRTY_DED_COUNT) }, | 5558 | SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_CFIFO_SED_COUNT), |
| 5532 | { "TCC_HIGH_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | 5559 | 0, 0 |
| 5533 | REG_FIELD_MASK(TCC_EDC_CNT, HIGH_RATE_TAG_SEC_COUNT), | 5560 | }, |
| 5534 | REG_FIELD_MASK(TCC_EDC_CNT, HIGH_RATE_TAG_DED_COUNT) }, | 5561 | { "TCA_HOLE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT), |
| 5535 | { "TCC_LOW_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | 5562 | SOC15_REG_FIELD(TCA_EDC_CNT, HOLE_FIFO_SED_COUNT), |
| 5536 | REG_FIELD_MASK(TCC_EDC_CNT, LOW_RATE_TAG_SEC_COUNT), | 5563 | 0, 0 |
| 5537 | REG_FIELD_MASK(TCC_EDC_CNT, LOW_RATE_TAG_DED_COUNT) }, | 5564 | }, |
| 5538 | { "TCC_SRC_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | 5565 | { "TCA_REQ_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT), |
| 5539 | REG_FIELD_MASK(TCC_EDC_CNT, SRC_FIFO_SEC_COUNT), | 5566 | SOC15_REG_FIELD(TCA_EDC_CNT, REQ_FIFO_SED_COUNT), |
| 5540 | REG_FIELD_MASK(TCC_EDC_CNT, SRC_FIFO_DED_COUNT) }, | 5567 | 0, 0 |
| 5541 | { "TCC_IN_USE_DEC", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | 5568 | }, |
| 5542 | REG_FIELD_MASK(TCC_EDC_CNT, IN_USE_DEC_SED_COUNT), 0 }, | 5569 | { "TCC_CACHE_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), |
| 5543 | { "TCC_IN_USE_TRANSFER", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | 5570 | SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DATA_SEC_COUNT), |
| 5544 | REG_FIELD_MASK(TCC_EDC_CNT, IN_USE_TRANSFER_SED_COUNT), 0 }, | 5571 | SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DATA_DED_COUNT) |
| 5545 | { "TCC_LATENCY_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | 5572 | }, |
| 5546 | REG_FIELD_MASK(TCC_EDC_CNT, LATENCY_FIFO_SED_COUNT), 0 }, | 5573 | { "TCC_CACHE_DIRTY", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), |
| 5547 | { "TCC_RETURN_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | 5574 | SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DIRTY_SEC_COUNT), |
| 5548 | REG_FIELD_MASK(TCC_EDC_CNT, RETURN_DATA_SED_COUNT), 0 }, | 5575 | SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DIRTY_DED_COUNT) |
| 5549 | { "TCC_RETURN_CONTROL", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | 5576 | }, |
| 5550 | REG_FIELD_MASK(TCC_EDC_CNT, RETURN_CONTROL_SED_COUNT), 0 }, | 5577 | { "TCC_HIGH_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), |
| 5551 | { "TCC_UC_ATOMIC_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | 5578 | SOC15_REG_FIELD(TCC_EDC_CNT, HIGH_RATE_TAG_SEC_COUNT), |
| 5552 | REG_FIELD_MASK(TCC_EDC_CNT, UC_ATOMIC_FIFO_SED_COUNT), 0 }, | 5579 | SOC15_REG_FIELD(TCC_EDC_CNT, HIGH_RATE_TAG_DED_COUNT) |
| 5553 | { "TCC_WRITE_RETURN", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, 16, | 5580 | }, |
| 5554 | REG_FIELD_MASK(TCC_EDC_CNT2, WRITE_RETURN_SED_COUNT), 0 }, | 5581 | { "TCC_LOW_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), |
| 5555 | { "TCC_WRITE_CACHE_READ", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, 16, | 5582 | SOC15_REG_FIELD(TCC_EDC_CNT, LOW_RATE_TAG_SEC_COUNT), |
| 5556 | REG_FIELD_MASK(TCC_EDC_CNT2, WRITE_CACHE_READ_SED_COUNT), 0 }, | 5583 | SOC15_REG_FIELD(TCC_EDC_CNT, LOW_RATE_TAG_DED_COUNT) |
| 5557 | { "TCC_SRC_FIFO_NEXT_RAM", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, | 5584 | }, |
| 5558 | 16, REG_FIELD_MASK(TCC_EDC_CNT2, SRC_FIFO_NEXT_RAM_SED_COUNT), 0 }, | 5585 | { "TCC_SRC_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), |
| 5586 | SOC15_REG_FIELD(TCC_EDC_CNT, SRC_FIFO_SEC_COUNT), | ||
| 5587 | SOC15_REG_FIELD(TCC_EDC_CNT, SRC_FIFO_DED_COUNT) | ||
| 5588 | }, | ||
| 5589 | { "TCC_IN_USE_DEC", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), | ||
| 5590 | SOC15_REG_FIELD(TCC_EDC_CNT, IN_USE_DEC_SED_COUNT), | ||
| 5591 | 0, 0 | ||
| 5592 | }, | ||
| 5593 | { "TCC_IN_USE_TRANSFER", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), | ||
| 5594 | SOC15_REG_FIELD(TCC_EDC_CNT, IN_USE_TRANSFER_SED_COUNT), | ||
| 5595 | 0, 0 | ||
| 5596 | }, | ||
| 5597 | { "TCC_LATENCY_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), | ||
| 5598 | SOC15_REG_FIELD(TCC_EDC_CNT, LATENCY_FIFO_SED_COUNT), | ||
| 5599 | 0, 0 | ||
| 5600 | }, | ||
| 5601 | { "TCC_RETURN_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), | ||
| 5602 | SOC15_REG_FIELD(TCC_EDC_CNT, RETURN_DATA_SED_COUNT), | ||
| 5603 | 0, 0 | ||
| 5604 | }, | ||
| 5605 | { "TCC_RETURN_CONTROL", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), | ||
| 5606 | SOC15_REG_FIELD(TCC_EDC_CNT, RETURN_CONTROL_SED_COUNT), | ||
| 5607 | 0, 0 | ||
| 5608 | }, | ||
| 5609 | { "TCC_UC_ATOMIC_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), | ||
| 5610 | SOC15_REG_FIELD(TCC_EDC_CNT, UC_ATOMIC_FIFO_SED_COUNT), | ||
| 5611 | 0, 0 | ||
| 5612 | }, | ||
| 5613 | { "TCC_WRITE_RETURN", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), | ||
| 5614 | SOC15_REG_FIELD(TCC_EDC_CNT2, WRITE_RETURN_SED_COUNT), | ||
| 5615 | 0, 0 | ||
| 5616 | }, | ||
| 5617 | { "TCC_WRITE_CACHE_READ", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), | ||
| 5618 | SOC15_REG_FIELD(TCC_EDC_CNT2, WRITE_CACHE_READ_SED_COUNT), | ||
| 5619 | 0, 0 | ||
| 5620 | }, | ||
| 5621 | { "TCC_SRC_FIFO_NEXT_RAM", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), | ||
| 5622 | SOC15_REG_FIELD(TCC_EDC_CNT2, SRC_FIFO_NEXT_RAM_SED_COUNT), | ||
| 5623 | 0, 0 | ||
| 5624 | }, | ||
| 5559 | { "TCC_LATENCY_FIFO_NEXT_RAM", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), | 5625 | { "TCC_LATENCY_FIFO_NEXT_RAM", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), |
| 5560 | 0, 16, REG_FIELD_MASK(TCC_EDC_CNT2, LATENCY_FIFO_NEXT_RAM_SED_COUNT), | 5626 | SOC15_REG_FIELD(TCC_EDC_CNT2, LATENCY_FIFO_NEXT_RAM_SED_COUNT), |
| 5561 | 0 }, | 5627 | 0, 0 |
| 5562 | { "TCC_CACHE_TAG_PROBE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, | 5628 | }, |
| 5563 | 16, REG_FIELD_MASK(TCC_EDC_CNT2, CACHE_TAG_PROBE_FIFO_SED_COUNT), 0 }, | 5629 | { "TCC_CACHE_TAG_PROBE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), |
| 5630 | SOC15_REG_FIELD(TCC_EDC_CNT2, CACHE_TAG_PROBE_FIFO_SED_COUNT), | ||
| 5631 | 0, 0 | ||
| 5632 | }, | ||
| 5564 | { "TCC_WRRET_TAG_WRITE_RETURN", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), | 5633 | { "TCC_WRRET_TAG_WRITE_RETURN", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), |
| 5565 | 0, 16, REG_FIELD_MASK(TCC_EDC_CNT2, WRRET_TAG_WRITE_RETURN_SED_COUNT), | 5634 | SOC15_REG_FIELD(TCC_EDC_CNT2, WRRET_TAG_WRITE_RETURN_SED_COUNT), |
| 5566 | 0 }, | 5635 | 0, 0 |
| 5567 | { "TCC_ATOMIC_RETURN_BUFFER", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, | 5636 | }, |
| 5568 | 16, REG_FIELD_MASK(TCC_EDC_CNT2, ATOMIC_RETURN_BUFFER_SED_COUNT), 0 }, | 5637 | { "TCC_ATOMIC_RETURN_BUFFER", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), |
| 5569 | { "TCI_WRITE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCI_EDC_CNT), 0, 72, | 5638 | SOC15_REG_FIELD(TCC_EDC_CNT2, ATOMIC_RETURN_BUFFER_SED_COUNT), |
| 5570 | REG_FIELD_MASK(TCI_EDC_CNT, WRITE_RAM_SED_COUNT), 0 }, | 5639 | 0, 0 |
| 5571 | { "TCP_CACHE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, | 5640 | }, |
| 5572 | REG_FIELD_MASK(TCP_EDC_CNT_NEW, CACHE_RAM_SEC_COUNT), | 5641 | { "TCI_WRITE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCI_EDC_CNT), |
| 5573 | REG_FIELD_MASK(TCP_EDC_CNT_NEW, CACHE_RAM_DED_COUNT) }, | 5642 | SOC15_REG_FIELD(TCI_EDC_CNT, WRITE_RAM_SED_COUNT), |
| 5574 | { "TCP_LFIFO_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, | 5643 | 0, 0 |
| 5575 | REG_FIELD_MASK(TCP_EDC_CNT_NEW, LFIFO_RAM_SEC_COUNT), | 5644 | }, |
| 5576 | REG_FIELD_MASK(TCP_EDC_CNT_NEW, LFIFO_RAM_DED_COUNT) }, | 5645 | { "TCP_CACHE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), |
| 5577 | { "TCP_CMD_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, | 5646 | SOC15_REG_FIELD(TCP_EDC_CNT_NEW, CACHE_RAM_SEC_COUNT), |
| 5578 | REG_FIELD_MASK(TCP_EDC_CNT_NEW, CMD_FIFO_SED_COUNT), 0 }, | 5647 | SOC15_REG_FIELD(TCP_EDC_CNT_NEW, CACHE_RAM_DED_COUNT) |
| 5579 | { "TCP_VM_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, | 5648 | }, |
| 5580 | REG_FIELD_MASK(TCP_EDC_CNT_NEW, VM_FIFO_SEC_COUNT), 0 }, | 5649 | { "TCP_LFIFO_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), |
| 5581 | { "TCP_DB_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, | 5650 | SOC15_REG_FIELD(TCP_EDC_CNT_NEW, LFIFO_RAM_SEC_COUNT), |
| 5582 | REG_FIELD_MASK(TCP_EDC_CNT_NEW, DB_RAM_SED_COUNT), 0 }, | 5651 | SOC15_REG_FIELD(TCP_EDC_CNT_NEW, LFIFO_RAM_DED_COUNT) |
| 5583 | { "TCP_UTCL1_LFIFO0", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, | 5652 | }, |
| 5584 | REG_FIELD_MASK(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_SEC_COUNT), | 5653 | { "TCP_CMD_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), |
| 5585 | REG_FIELD_MASK(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_DED_COUNT) }, | 5654 | SOC15_REG_FIELD(TCP_EDC_CNT_NEW, CMD_FIFO_SED_COUNT), |
| 5586 | { "TCP_UTCL1_LFIFO1", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, | 5655 | 0, 0 |
| 5587 | REG_FIELD_MASK(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_SEC_COUNT), | 5656 | }, |
| 5588 | REG_FIELD_MASK(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_DED_COUNT) }, | 5657 | { "TCP_VM_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), |
| 5589 | { "TD_SS_FIFO_LO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 1, 16, | 5658 | SOC15_REG_FIELD(TCP_EDC_CNT_NEW, VM_FIFO_SEC_COUNT), |
| 5590 | REG_FIELD_MASK(TD_EDC_CNT, SS_FIFO_LO_SEC_COUNT), | 5659 | 0, 0 |
| 5591 | REG_FIELD_MASK(TD_EDC_CNT, SS_FIFO_LO_DED_COUNT) }, | 5660 | }, |
| 5592 | { "TD_SS_FIFO_HI", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 1, 16, | 5661 | { "TCP_DB_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), |
| 5593 | REG_FIELD_MASK(TD_EDC_CNT, SS_FIFO_HI_SEC_COUNT), | 5662 | SOC15_REG_FIELD(TCP_EDC_CNT_NEW, DB_RAM_SED_COUNT), |
| 5594 | REG_FIELD_MASK(TD_EDC_CNT, SS_FIFO_HI_DED_COUNT) }, | 5663 | 0, 0 |
| 5595 | { "TD_CS_FIFO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 1, 16, | 5664 | }, |
| 5596 | REG_FIELD_MASK(TD_EDC_CNT, CS_FIFO_SED_COUNT), 0 }, | 5665 | { "TCP_UTCL1_LFIFO0", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), |
| 5597 | { "SQ_LDS_D", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, | 5666 | SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_SEC_COUNT), |
| 5598 | REG_FIELD_MASK(SQ_EDC_CNT, LDS_D_SEC_COUNT), | 5667 | SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_DED_COUNT) |
| 5599 | REG_FIELD_MASK(SQ_EDC_CNT, LDS_D_DED_COUNT) }, | 5668 | }, |
| 5600 | { "SQ_LDS_I", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, | 5669 | { "TCP_UTCL1_LFIFO1", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), |
| 5601 | REG_FIELD_MASK(SQ_EDC_CNT, LDS_I_SEC_COUNT), | 5670 | SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_SEC_COUNT), |
| 5602 | REG_FIELD_MASK(SQ_EDC_CNT, LDS_I_DED_COUNT) }, | 5671 | SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_DED_COUNT) |
| 5603 | { "SQ_SGPR", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, | 5672 | }, |
| 5604 | REG_FIELD_MASK(SQ_EDC_CNT, SGPR_SEC_COUNT), | 5673 | { "TD_SS_FIFO_LO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), |
| 5605 | REG_FIELD_MASK(SQ_EDC_CNT, SGPR_DED_COUNT) }, | 5674 | SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_LO_SEC_COUNT), |
| 5606 | { "SQ_VGPR0", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, | 5675 | SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_LO_DED_COUNT) |
| 5607 | REG_FIELD_MASK(SQ_EDC_CNT, VGPR0_SEC_COUNT), | 5676 | }, |
| 5608 | REG_FIELD_MASK(SQ_EDC_CNT, VGPR0_DED_COUNT) }, | 5677 | { "TD_SS_FIFO_HI", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), |
| 5609 | { "SQ_VGPR1", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, | 5678 | SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_HI_SEC_COUNT), |
| 5610 | REG_FIELD_MASK(SQ_EDC_CNT, VGPR1_SEC_COUNT), | 5679 | SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_HI_DED_COUNT) |
| 5611 | REG_FIELD_MASK(SQ_EDC_CNT, VGPR1_DED_COUNT) }, | 5680 | }, |
| 5612 | { "SQ_VGPR2", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, | 5681 | { "TD_CS_FIFO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), |
| 5613 | REG_FIELD_MASK(SQ_EDC_CNT, VGPR2_SEC_COUNT), | 5682 | SOC15_REG_FIELD(TD_EDC_CNT, CS_FIFO_SED_COUNT), |
| 5614 | REG_FIELD_MASK(SQ_EDC_CNT, VGPR2_DED_COUNT) }, | 5683 | 0, 0 |
| 5615 | { "SQ_VGPR3", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, | 5684 | }, |
| 5616 | REG_FIELD_MASK(SQ_EDC_CNT, VGPR3_SEC_COUNT), | 5685 | { "SQ_LDS_D", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), |
| 5617 | REG_FIELD_MASK(SQ_EDC_CNT, VGPR3_DED_COUNT) }, | 5686 | SOC15_REG_FIELD(SQ_EDC_CNT, LDS_D_SEC_COUNT), |
| 5687 | SOC15_REG_FIELD(SQ_EDC_CNT, LDS_D_DED_COUNT) | ||
| 5688 | }, | ||
| 5689 | { "SQ_LDS_I", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), | ||
| 5690 | SOC15_REG_FIELD(SQ_EDC_CNT, LDS_I_SEC_COUNT), | ||
| 5691 | SOC15_REG_FIELD(SQ_EDC_CNT, LDS_I_DED_COUNT) | ||
| 5692 | }, | ||
| 5693 | { "SQ_SGPR", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), | ||
| 5694 | SOC15_REG_FIELD(SQ_EDC_CNT, SGPR_SEC_COUNT), | ||
| 5695 | SOC15_REG_FIELD(SQ_EDC_CNT, SGPR_DED_COUNT) | ||
| 5696 | }, | ||
| 5697 | { "SQ_VGPR0", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), | ||
| 5698 | SOC15_REG_FIELD(SQ_EDC_CNT, VGPR0_SEC_COUNT), | ||
| 5699 | SOC15_REG_FIELD(SQ_EDC_CNT, VGPR0_DED_COUNT) | ||
| 5700 | }, | ||
| 5701 | { "SQ_VGPR1", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), | ||
| 5702 | SOC15_REG_FIELD(SQ_EDC_CNT, VGPR1_SEC_COUNT), | ||
| 5703 | SOC15_REG_FIELD(SQ_EDC_CNT, VGPR1_DED_COUNT) | ||
| 5704 | }, | ||
| 5705 | { "SQ_VGPR2", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), | ||
| 5706 | SOC15_REG_FIELD(SQ_EDC_CNT, VGPR2_SEC_COUNT), | ||
| 5707 | SOC15_REG_FIELD(SQ_EDC_CNT, VGPR2_DED_COUNT) | ||
| 5708 | }, | ||
| 5709 | { "SQ_VGPR3", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), | ||
| 5710 | SOC15_REG_FIELD(SQ_EDC_CNT, VGPR3_SEC_COUNT), | ||
| 5711 | SOC15_REG_FIELD(SQ_EDC_CNT, VGPR3_DED_COUNT) | ||
| 5712 | }, | ||
| 5618 | { "SQC_DATA_CU0_WRITE_DATA_BUF", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), | 5713 | { "SQC_DATA_CU0_WRITE_DATA_BUF", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), |
| 5619 | 1, 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU0_WRITE_DATA_BUF_SEC_COUNT), | 5714 | SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_WRITE_DATA_BUF_SEC_COUNT), |
| 5620 | REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU0_WRITE_DATA_BUF_DED_COUNT) }, | 5715 | SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_WRITE_DATA_BUF_DED_COUNT) |
| 5621 | { "SQC_DATA_CU0_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 1, | 5716 | }, |
| 5622 | 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU0_UTCL1_LFIFO_SEC_COUNT), | 5717 | { "SQC_DATA_CU0_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), |
| 5623 | REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU0_UTCL1_LFIFO_DED_COUNT) }, | 5718 | SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_UTCL1_LFIFO_SEC_COUNT), |
| 5719 | SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_UTCL1_LFIFO_DED_COUNT) | ||
| 5720 | }, | ||
| 5624 | { "SQC_DATA_CU1_WRITE_DATA_BUF", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), | 5721 | { "SQC_DATA_CU1_WRITE_DATA_BUF", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), |
| 5625 | 1, 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU1_WRITE_DATA_BUF_SEC_COUNT), | 5722 | SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_WRITE_DATA_BUF_SEC_COUNT), |
| 5626 | REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU1_WRITE_DATA_BUF_DED_COUNT) }, | 5723 | SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_WRITE_DATA_BUF_DED_COUNT) |
| 5627 | { "SQC_DATA_CU1_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 1, | 5724 | }, |
| 5628 | 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU1_UTCL1_LFIFO_SEC_COUNT), | 5725 | { "SQC_DATA_CU1_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), |
| 5629 | REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU1_UTCL1_LFIFO_DED_COUNT) }, | 5726 | SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_UTCL1_LFIFO_SEC_COUNT), |
| 5727 | SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_UTCL1_LFIFO_DED_COUNT) | ||
| 5728 | }, | ||
| 5630 | { "SQC_DATA_CU2_WRITE_DATA_BUF", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), | 5729 | { "SQC_DATA_CU2_WRITE_DATA_BUF", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), |
| 5631 | 1, 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU2_WRITE_DATA_BUF_SEC_COUNT), | 5730 | SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_WRITE_DATA_BUF_SEC_COUNT), |
| 5632 | REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU2_WRITE_DATA_BUF_DED_COUNT) }, | 5731 | SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_WRITE_DATA_BUF_DED_COUNT) |
| 5633 | { "SQC_DATA_CU2_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 1, | 5732 | }, |
| 5634 | 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_SEC_COUNT), | 5733 | { "SQC_DATA_CU2_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), |
| 5635 | REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_DED_COUNT) }, | 5734 | SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_SEC_COUNT), |
| 5636 | { "SQC_INST_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, | 5735 | SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_DED_COUNT) |
| 5637 | 6, REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_SEC_COUNT), | 5736 | }, |
| 5638 | REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_DED_COUNT) }, | 5737 | { "SQC_INST_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), |
| 5639 | { "SQC_INST_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, | 5738 | SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_SEC_COUNT), |
| 5640 | 6, REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_SEC_COUNT), | 5739 | SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_DED_COUNT) |
| 5641 | REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_DED_COUNT) }, | 5740 | }, |
| 5642 | { "SQC_DATA_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, | 5741 | { "SQC_INST_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), |
| 5643 | 6, REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_SEC_COUNT), | 5742 | SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_SEC_COUNT), |
| 5644 | REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_DED_COUNT) }, | 5743 | SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_DED_COUNT) |
| 5645 | { "SQC_DATA_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, | 5744 | }, |
| 5646 | 6, REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_SEC_COUNT), | 5745 | { "SQC_DATA_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), |
| 5647 | REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_DED_COUNT) }, | 5746 | SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_SEC_COUNT), |
| 5648 | { "SQC_INST_BANKA_UTCL1_MISS_FIFO", | 5747 | SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_DED_COUNT) |
| 5649 | SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 6, | 5748 | }, |
| 5650 | REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_UTCL1_MISS_FIFO_SED_COUNT), | 5749 | { "SQC_DATA_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), |
| 5651 | 0 }, | 5750 | SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_SEC_COUNT), |
| 5652 | { "SQC_INST_BANKA_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, | 5751 | SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_DED_COUNT) |
| 5653 | 6, REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_MISS_FIFO_SED_COUNT), 0 }, | 5752 | }, |
| 5654 | { "SQC_DATA_BANKA_HIT_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, | 5753 | { "SQC_INST_BANKA_UTCL1_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), |
| 5655 | 6, REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_HIT_FIFO_SED_COUNT), 0 }, | 5754 | SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_UTCL1_MISS_FIFO_SED_COUNT), |
| 5656 | { "SQC_DATA_BANKA_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, | 5755 | 0, 0 |
| 5657 | 6, REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_MISS_FIFO_SED_COUNT), 0 }, | 5756 | }, |
| 5658 | { "SQC_DATA_BANKA_DIRTY_BIT_RAM", | 5757 | { "SQC_INST_BANKA_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), |
| 5659 | SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 6, | 5758 | SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_MISS_FIFO_SED_COUNT), |
| 5660 | REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_DIRTY_BIT_RAM_SED_COUNT), 0 }, | 5759 | 0, 0 |
| 5661 | { "SQC_INST_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 6, | 5760 | }, |
| 5662 | REG_FIELD_MASK(SQC_EDC_CNT2, INST_UTCL1_LFIFO_SEC_COUNT), | 5761 | { "SQC_DATA_BANKA_HIT_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), |
| 5663 | REG_FIELD_MASK(SQC_EDC_CNT2, INST_UTCL1_LFIFO_DED_COUNT) }, | 5762 | SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_HIT_FIFO_SED_COUNT), |
| 5664 | { "SQC_INST_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, | 5763 | 0, 0 |
| 5665 | 6, REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_SEC_COUNT), | 5764 | }, |
| 5666 | REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_DED_COUNT) }, | 5765 | { "SQC_DATA_BANKA_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), |
| 5667 | { "SQC_INST_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, | 5766 | SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_MISS_FIFO_SED_COUNT), |
| 5668 | 6, REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_SEC_COUNT), | 5767 | 0, 0 |
| 5669 | REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_DED_COUNT) }, | 5768 | }, |
| 5670 | { "SQC_DATA_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, | 5769 | { "SQC_DATA_BANKA_DIRTY_BIT_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), |
| 5671 | 6, REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_SEC_COUNT), | 5770 | SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_DIRTY_BIT_RAM_SED_COUNT), |
| 5672 | REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_DED_COUNT) }, | 5771 | 0, 0 |
| 5673 | { "SQC_DATA_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, | 5772 | }, |
| 5674 | 6, REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_SEC_COUNT), | 5773 | { "SQC_INST_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), |
| 5675 | REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_DED_COUNT) }, | 5774 | SOC15_REG_FIELD(SQC_EDC_CNT2, INST_UTCL1_LFIFO_SEC_COUNT), |
| 5676 | { "SQC_INST_BANKB_UTCL1_MISS_FIFO", | 5775 | SOC15_REG_FIELD(SQC_EDC_CNT2, INST_UTCL1_LFIFO_DED_COUNT) |
| 5677 | SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, 6, | 5776 | }, |
| 5678 | REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_UTCL1_MISS_FIFO_SED_COUNT), | 5777 | { "SQC_INST_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), |
| 5679 | 0 }, | 5778 | SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_SEC_COUNT), |
| 5680 | { "SQC_INST_BANKB_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, | 5779 | SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_DED_COUNT) |
| 5681 | 6, REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_MISS_FIFO_SED_COUNT), 0 }, | 5780 | }, |
| 5682 | { "SQC_DATA_BANKB_HIT_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, | 5781 | { "SQC_INST_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), |
| 5683 | 6, REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_HIT_FIFO_SED_COUNT), 0 }, | 5782 | SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_SEC_COUNT), |
| 5684 | { "SQC_DATA_BANKB_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, | 5783 | SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_DED_COUNT) |
| 5685 | 6, REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_MISS_FIFO_SED_COUNT), 0 }, | 5784 | }, |
| 5686 | { "SQC_DATA_BANKB_DIRTY_BIT_RAM", | 5785 | { "SQC_DATA_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), |
| 5687 | SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, 6, | 5786 | SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_SEC_COUNT), |
| 5688 | REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_DIRTY_BIT_RAM_SED_COUNT), 0 }, | 5787 | SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_DED_COUNT) |
| 5689 | { "EA_DRAMRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | 5788 | }, |
| 5690 | REG_FIELD_MASK(GCEA_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT), | 5789 | { "SQC_DATA_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), |
| 5691 | REG_FIELD_MASK(GCEA_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT) }, | 5790 | SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_SEC_COUNT), |
| 5692 | { "EA_DRAMWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | 5791 | SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_DED_COUNT) |
| 5693 | REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_CMDMEM_SEC_COUNT), | 5792 | }, |
| 5694 | REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_CMDMEM_DED_COUNT) }, | 5793 | { "SQC_INST_BANKB_UTCL1_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), |
| 5695 | { "EA_DRAMWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | 5794 | SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_UTCL1_MISS_FIFO_SED_COUNT), |
| 5696 | REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_DATAMEM_SEC_COUNT), | 5795 | 0, 0 |
| 5697 | REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_DATAMEM_DED_COUNT) }, | 5796 | }, |
| 5698 | { "EA_RRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | 5797 | { "SQC_INST_BANKB_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), |
| 5699 | REG_FIELD_MASK(GCEA_EDC_CNT, RRET_TAGMEM_SEC_COUNT), | 5798 | SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_MISS_FIFO_SED_COUNT), |
| 5700 | REG_FIELD_MASK(GCEA_EDC_CNT, RRET_TAGMEM_DED_COUNT) }, | 5799 | 0, 0 |
| 5701 | { "EA_WRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | 5800 | }, |
| 5702 | REG_FIELD_MASK(GCEA_EDC_CNT, WRET_TAGMEM_SEC_COUNT), | 5801 | { "SQC_DATA_BANKB_HIT_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), |
| 5703 | REG_FIELD_MASK(GCEA_EDC_CNT, WRET_TAGMEM_DED_COUNT) }, | 5802 | SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_HIT_FIFO_SED_COUNT), |
| 5704 | { "EA_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | 5803 | 0, 0 |
| 5705 | REG_FIELD_MASK(GCEA_EDC_CNT, DRAMRD_PAGEMEM_SED_COUNT), 0 }, | 5804 | }, |
| 5706 | { "EA_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | 5805 | { "SQC_DATA_BANKB_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), |
| 5707 | REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_PAGEMEM_SED_COUNT), 0 }, | 5806 | SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_MISS_FIFO_SED_COUNT), |
| 5708 | { "EA_IORD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | 5807 | 0, 0 |
| 5709 | REG_FIELD_MASK(GCEA_EDC_CNT, IORD_CMDMEM_SED_COUNT), 0 }, | 5808 | }, |
| 5710 | { "EA_IOWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | 5809 | { "SQC_DATA_BANKB_DIRTY_BIT_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), |
| 5711 | REG_FIELD_MASK(GCEA_EDC_CNT, IOWR_CMDMEM_SED_COUNT), 0 }, | 5810 | SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_DIRTY_BIT_RAM_SED_COUNT), |
| 5712 | { "EA_IOWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | 5811 | 0, 0 |
| 5713 | REG_FIELD_MASK(GCEA_EDC_CNT, IOWR_DATAMEM_SED_COUNT), 0 }, | 5812 | }, |
| 5714 | { "GMIRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | 5813 | { "EA_DRAMRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), |
| 5715 | REG_FIELD_MASK(GCEA_EDC_CNT2, GMIRD_CMDMEM_SEC_COUNT), | 5814 | SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT), |
| 5716 | REG_FIELD_MASK(GCEA_EDC_CNT2, GMIRD_CMDMEM_DED_COUNT) }, | 5815 | SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT) |
| 5717 | { "GMIWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | 5816 | }, |
| 5718 | REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_CMDMEM_SEC_COUNT), | 5817 | { "EA_DRAMWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), |
| 5719 | REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_CMDMEM_DED_COUNT) }, | 5818 | SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_CMDMEM_SEC_COUNT), |
| 5720 | { "GMIWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | 5819 | SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_CMDMEM_DED_COUNT) |
| 5721 | REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_DATAMEM_SEC_COUNT), | 5820 | }, |
| 5722 | REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_DATAMEM_DED_COUNT) }, | 5821 | { "EA_DRAMWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), |
| 5723 | { "GMIRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | 5822 | SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_DATAMEM_SEC_COUNT), |
| 5724 | REG_FIELD_MASK(GCEA_EDC_CNT2, GMIRD_PAGEMEM_SED_COUNT), 0 }, | 5823 | SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_DATAMEM_DED_COUNT) |
| 5725 | { "GMIWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | 5824 | }, |
| 5726 | REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_PAGEMEM_SED_COUNT), 0 }, | 5825 | { "EA_RRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), |
| 5727 | { "MAM_D0MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | 5826 | SOC15_REG_FIELD(GCEA_EDC_CNT, RRET_TAGMEM_SEC_COUNT), |
| 5728 | REG_FIELD_MASK(GCEA_EDC_CNT2, MAM_D0MEM_SED_COUNT), 0 }, | 5827 | SOC15_REG_FIELD(GCEA_EDC_CNT, RRET_TAGMEM_DED_COUNT) |
| 5729 | { "MAM_D1MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | 5828 | }, |
| 5730 | REG_FIELD_MASK(GCEA_EDC_CNT2, MAM_D1MEM_SED_COUNT), 0 }, | 5829 | { "EA_WRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), |
| 5731 | { "MAM_D2MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | 5830 | SOC15_REG_FIELD(GCEA_EDC_CNT, WRET_TAGMEM_SEC_COUNT), |
| 5732 | REG_FIELD_MASK(GCEA_EDC_CNT2, MAM_D2MEM_SED_COUNT), 0 }, | 5831 | SOC15_REG_FIELD(GCEA_EDC_CNT, WRET_TAGMEM_DED_COUNT) |
| 5733 | { "MAM_D3MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | 5832 | }, |
| 5734 | REG_FIELD_MASK(GCEA_EDC_CNT2, MAM_D3MEM_SED_COUNT), 0 }, | 5833 | { "EA_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), |
| 5834 | SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMRD_PAGEMEM_SED_COUNT), | ||
| 5835 | 0, 0 | ||
| 5836 | }, | ||
| 5837 | { "EA_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), | ||
| 5838 | SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_PAGEMEM_SED_COUNT), | ||
| 5839 | 0, 0 | ||
| 5840 | }, | ||
| 5841 | { "EA_IORD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), | ||
| 5842 | SOC15_REG_FIELD(GCEA_EDC_CNT, IORD_CMDMEM_SED_COUNT), | ||
| 5843 | 0, 0 | ||
| 5844 | }, | ||
| 5845 | { "EA_IOWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), | ||
| 5846 | SOC15_REG_FIELD(GCEA_EDC_CNT, IOWR_CMDMEM_SED_COUNT), | ||
| 5847 | 0, 0 | ||
| 5848 | }, | ||
| 5849 | { "EA_IOWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), | ||
| 5850 | SOC15_REG_FIELD(GCEA_EDC_CNT, IOWR_DATAMEM_SED_COUNT), | ||
| 5851 | 0, 0 | ||
| 5852 | }, | ||
| 5853 | { "GMIRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), | ||
| 5854 | SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIRD_CMDMEM_SEC_COUNT), | ||
| 5855 | SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIRD_CMDMEM_DED_COUNT) | ||
| 5856 | }, | ||
| 5857 | { "GMIWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), | ||
| 5858 | SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_CMDMEM_SEC_COUNT), | ||
| 5859 | SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_CMDMEM_DED_COUNT) | ||
| 5860 | }, | ||
| 5861 | { "GMIWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), | ||
| 5862 | SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_DATAMEM_SEC_COUNT), | ||
| 5863 | SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_DATAMEM_DED_COUNT) | ||
| 5864 | }, | ||
| 5865 | { "GMIRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), | ||
| 5866 | SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIRD_PAGEMEM_SED_COUNT), | ||
| 5867 | 0, 0 | ||
| 5868 | }, | ||
| 5869 | { "GMIWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), | ||
| 5870 | SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_PAGEMEM_SED_COUNT), | ||
| 5871 | 0, 0 | ||
| 5872 | }, | ||
| 5873 | { "MAM_D0MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), | ||
| 5874 | SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D0MEM_SED_COUNT), | ||
| 5875 | 0, 0 | ||
| 5876 | }, | ||
| 5877 | { "MAM_D1MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), | ||
| 5878 | SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D1MEM_SED_COUNT), | ||
| 5879 | 0, 0 | ||
| 5880 | }, | ||
| 5881 | { "MAM_D2MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), | ||
| 5882 | SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D2MEM_SED_COUNT), | ||
| 5883 | 0, 0 | ||
| 5884 | }, | ||
| 5885 | { "MAM_D3MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), | ||
| 5886 | SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D3MEM_SED_COUNT), | ||
| 5887 | 0, 0 | ||
| 5888 | } | ||
| 5735 | }; | 5889 | }; |
| 5736 | 5890 | ||
| 5737 | static int gfx_v9_0_ras_error_inject(struct amdgpu_device *adev, | 5891 | static int gfx_v9_0_ras_error_inject(struct amdgpu_device *adev, |
| @@ -5780,14 +5934,217 @@ static int gfx_v9_0_ras_error_inject(struct amdgpu_device *adev, · 42 unmodified lines | |||
| 5780 | return ret; | 5934 | return ret; |
| 5781 | } | 5935 | } |
| 5782 | 5936 | ||
| 5937 | static const char *vml2_mems[] = { | ||
| 5938 | "UTC_VML2_BANK_CACHE_0_BIGK_MEM0", | ||
| 5939 | "UTC_VML2_BANK_CACHE_0_BIGK_MEM1", | ||
| 5940 | "UTC_VML2_BANK_CACHE_0_4K_MEM0", | ||
| 5941 | "UTC_VML2_BANK_CACHE_0_4K_MEM1", | ||
| 5942 | "UTC_VML2_BANK_CACHE_1_BIGK_MEM0", | ||
| 5943 | "UTC_VML2_BANK_CACHE_1_BIGK_MEM1", | ||
| 5944 | "UTC_VML2_BANK_CACHE_1_4K_MEM0", | ||
| 5945 | "UTC_VML2_BANK_CACHE_1_4K_MEM1", | ||
| 5946 | "UTC_VML2_BANK_CACHE_2_BIGK_MEM0", | ||
| 5947 | "UTC_VML2_BANK_CACHE_2_BIGK_MEM1", | ||
| 5948 | "UTC_VML2_BANK_CACHE_2_4K_MEM0", | ||
| 5949 | "UTC_VML2_BANK_CACHE_2_4K_MEM1", | ||
| 5950 | "UTC_VML2_BANK_CACHE_3_BIGK_MEM0", | ||
| 5951 | "UTC_VML2_BANK_CACHE_3_BIGK_MEM1", | ||
| 5952 | "UTC_VML2_BANK_CACHE_3_4K_MEM0", | ||
| 5953 | "UTC_VML2_BANK_CACHE_3_4K_MEM1", | ||
| 5954 | }; | ||
| 5955 | |||
| 5956 | static const char *vml2_walker_mems[] = { | ||
| 5957 | "UTC_VML2_CACHE_PDE0_MEM0", | ||
| 5958 | "UTC_VML2_CACHE_PDE0_MEM1", | ||
| 5959 | "UTC_VML2_CACHE_PDE1_MEM0", | ||
| 5960 | "UTC_VML2_CACHE_PDE1_MEM1", | ||
| 5961 | "UTC_VML2_CACHE_PDE2_MEM0", | ||
| 5962 | "UTC_VML2_CACHE_PDE2_MEM1", | ||
| 5963 | "UTC_VML2_RDIF_LOG_FIFO", | ||
| 5964 | }; | ||
| 5965 | |||
| 5966 | static const char *atc_l2_cache_2m_mems[] = { | ||
| 5967 | "UTC_ATCL2_CACHE_2M_BANK0_WAY0_MEM", | ||
| 5968 | "UTC_ATCL2_CACHE_2M_BANK0_WAY1_MEM", | ||
| 5969 | "UTC_ATCL2_CACHE_2M_BANK1_WAY0_MEM", | ||
| 5970 | "UTC_ATCL2_CACHE_2M_BANK1_WAY1_MEM", | ||
| 5971 | }; | ||
| 5972 | |||
| 5973 | static const char *atc_l2_cache_4k_mems[] = { | ||
| 5974 | "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM0", | ||
| 5975 | "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM1", | ||
| 5976 | "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM2", | ||
| 5977 | "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM3", | ||
| 5978 | "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM4", | ||
| 5979 | "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM5", | ||
| 5980 | "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM6", | ||
| 5981 | "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM7", | ||
| 5982 | "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM0", | ||
| 5983 | "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM1", | ||
| 5984 | "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM2", | ||
| 5985 | "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM3", | ||
| 5986 | "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM4", | ||
| 5987 | "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM5", | ||
| 5988 | "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM6", | ||
| 5989 | "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM7", | ||
| 5990 | "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM0", | ||
| 5991 | "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM1", | ||
| 5992 | "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM2", | ||
| 5993 | "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM3", | ||
| 5994 | "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM4", | ||
| 5995 | "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM5", | ||
| 5996 | "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM6", | ||
| 5997 | "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM7", | ||
| 5998 | "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM0", | ||
| 5999 | "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM1", | ||
| 6000 | "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM2", | ||
| 6001 | "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM3", | ||
| 6002 | "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM4", | ||
| 6003 | "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM5", | ||
| 6004 | "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM6", | ||
| 6005 | "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM7", | ||
| 6006 | }; | ||
| 6007 | |||
| 6008 | static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev, | ||
| 6009 | struct ras_err_data *err_data) | ||
| 6010 | { | ||
| 6011 | uint32_t i, data; | ||
| 6012 | uint32_t sec_count, ded_count; | ||
| 6013 | |||
| 6014 | WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_INDEX, 255); | ||
| 6015 | WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_CNT, 0); | ||
| 6016 | WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_INDEX, 255); | ||
| 6017 | WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_CNT, 0); | ||
| 6018 | WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_INDEX, 255); | ||
| 6019 | WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_CNT, 0); | ||
| 6020 | WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_INDEX, 255); | ||
| 6021 | WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_CNT, 0); | ||
| 6022 | |||
| 6023 | for (i = 0; i < 16; i++) { | ||
| 6024 | WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_INDEX, i); | ||
| 6025 | data = RREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_CNT); | ||
| 6026 | |||
| 6027 | sec_count = REG_GET_FIELD(data, VM_L2_MEM_ECC_CNT, SEC_COUNT); | ||
| 6028 | if (sec_count) { | ||
| 6029 | DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i, | ||
| 6030 | vml2_mems[i], sec_count); | ||
| 6031 | err_data->ce_count += sec_count; | ||
| 6032 | } | ||
| 6033 | |||
| 6034 | ded_count = REG_GET_FIELD(data, VM_L2_MEM_ECC_CNT, DED_COUNT); | ||
| 6035 | if (ded_count) { | ||
| 6036 | DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i, | ||
| 6037 | vml2_mems[i], ded_count); | ||
| 6038 | err_data->ue_count += ded_count; | ||
| 6039 | } | ||
| 6040 | } | ||
| 6041 | |||
| 6042 | for (i = 0; i < 7; i++) { | ||
| 6043 | WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_INDEX, i); | ||
| 6044 | data = RREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_CNT); | ||
| 6045 | |||
| 6046 | sec_count = REG_GET_FIELD(data, VM_L2_WALKER_MEM_ECC_CNT, | ||
| 6047 | SEC_COUNT); | ||
| 6048 | if (sec_count) { | ||
| 6049 | DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i, | ||
| 6050 | vml2_walker_mems[i], sec_count); | ||
| 6051 | err_data->ce_count += sec_count; | ||
| 6052 | } | ||
| 6053 | |||
| 6054 | ded_count = REG_GET_FIELD(data, VM_L2_WALKER_MEM_ECC_CNT, | ||
| 6055 | DED_COUNT); | ||
| 6056 | if (ded_count) { | ||
| 6057 | DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i, | ||
| 6058 | vml2_walker_mems[i], ded_count); | ||
| 6059 | err_data->ue_count += ded_count; | ||
| 6060 | } | ||
| 6061 | } | ||
| 6062 | |||
| 6063 | for (i = 0; i < 4; i++) { | ||
| 6064 | WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_INDEX, i); | ||
| 6065 | data = RREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_CNT); | ||
| 6066 | |||
| 6067 | sec_count = (data & 0x00006000L) >> 0xd; | ||
| 6068 | if (sec_count) { | ||
| 6069 | DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i, | ||
| 6070 | atc_l2_cache_2m_mems[i], sec_count); | ||
| 6071 | err_data->ce_count += sec_count; | ||
| 6072 | } | ||
| 6073 | } | ||
| 6074 | |||
| 6075 | for (i = 0; i < 32; i++) { | ||
| 6076 | WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_INDEX, i); | ||
| 6077 | data = RREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_CNT); | ||
| 6078 | |||
| 6079 | sec_count = (data & 0x00006000L) >> 0xd; | ||
| 6080 | if (sec_count) { | ||
| 6081 | DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i, | ||
| 6082 | atc_l2_cache_4k_mems[i], sec_count); | ||
| 6083 | err_data->ce_count += sec_count; | ||
| 6084 | } | ||
| 6085 | |||
| 6086 | ded_count = (data & 0x00018000L) >> 0xf; | ||
| 6087 | if (ded_count) { | ||
| 6088 | DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i, | ||
| 6089 | atc_l2_cache_4k_mems[i], ded_count); | ||
| 6090 | err_data->ue_count += ded_count; | ||
| 6091 | } | ||
| 6092 | } | ||
| 6093 | |||
| 6094 | WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_INDEX, 255); | ||
| 6095 | WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_INDEX, 255); | ||
| 6096 | WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_INDEX, 255); | ||
| 6097 | WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_INDEX, 255); | ||
| 6098 | |||
| 6099 | return 0; | ||
| 6100 | } | ||
| 6101 | |||
| 6102 | static int __get_ras_error_count(const struct soc15_reg_entry *reg, | ||
| 6103 | uint32_t se_id, uint32_t inst_id, uint32_t value, | ||
| 6104 | uint32_t *sec_count, uint32_t *ded_count) | ||
| 6105 | { | ||
| 6106 | uint32_t i; | ||
| 6107 | uint32_t sec_cnt, ded_cnt; | ||
| 6108 | |||
| 6109 | for (i = 0; i < ARRAY_SIZE(ras_subblock_regs); i++) { | ||
| 6110 | if(ras_subblock_regs[i].reg_offset != reg->reg_offset || | ||
| 6111 | ras_subblock_regs[i].seg != reg->seg || | ||
| 6112 | ras_subblock_regs[i].inst != reg->inst) | ||
| 6113 | continue; | ||
| 6114 | |||
| 6115 | sec_cnt = (value & | ||
| 6116 | ras_subblock_regs[i].sec_count_mask) >> | ||
| 6117 | ras_subblock_regs[i].sec_count_shift; | ||
| 6118 | if (sec_cnt) { | ||
| 6119 | DRM_INFO("GFX SubBlock %s, Instance[%d][%d], SEC %d\n", | ||
| 6120 | ras_subblock_regs[i].name, | ||
| 6121 | se_id, inst_id, | ||
| 6122 | sec_cnt); | ||
| 6123 | *sec_count += sec_cnt; | ||
| 6124 | } | ||
| 6125 | |||
| 6126 | ded_cnt = (value & | ||
| 6127 | ras_subblock_regs[i].ded_count_mask) >> | ||
| 6128 | ras_subblock_regs[i].ded_count_shift; | ||
| 6129 | if (ded_cnt) { | ||
| 6130 | DRM_INFO("GFX SubBlock %s, Instance[%d][%d], DED %d\n", | ||
| 6131 | ras_subblock_regs[i].name, | ||
| 6132 | se_id, inst_id, | ||
| 6133 | ded_cnt); | ||
| 6134 | *ded_count += ded_cnt; | ||
| 6135 | } | ||
| 6136 | } | ||
| 6137 | |||
| 6138 | return 0; | ||
| 6139 | } | ||
| 6140 | |||
| 5783 | static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev, | 6141 | static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev, |
| 5784 | void *ras_error_status) | 6142 | void *ras_error_status) |
| 5785 | { | 6143 | { |
| 5786 | struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status; | 6144 | struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status; |
| 5787 | uint32_t sec_count, ded_count; | 6145 | uint32_t sec_count = 0, ded_count = 0; |
| 5788 | uint32_t i; | 6146 | uint32_t i, j, k; |
| 5789 | uint32_t reg_value; | 6147 | uint32_t reg_value; |
| 5790 | uint32_t se_id, instance_id; | ||
| 5791 | 6148 | ||
| 5792 | if (adev->asic_type != CHIP_VEGA20) | 6149 | if (adev->asic_type != CHIP_VEGA20) |
| 5793 | return -EINVAL; | 6150 | return -EINVAL; |
| @@ -5796,52 +6153,29 @@ static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev, · 2 unmodified lines | |||
| 5796 | err_data->ce_count = 0; | 6153 | err_data->ce_count = 0; |
| 5797 | 6154 | ||
| 5798 | mutex_lock(&adev->grbm_idx_mutex); | 6155 | mutex_lock(&adev->grbm_idx_mutex); |
| 5799 | for (se_id = 0; se_id < adev->gfx.config.max_shader_engines; se_id++) { | ||
| 5800 | for (instance_id = 0; instance_id < 256; instance_id++) { | ||
| 5801 | for (i = 0; | ||
| 5802 | i < sizeof(gfx_ras_edc_regs) / sizeof(gfx_ras_edc_regs[0]); | ||
| 5803 | i++) { | ||
| 5804 | if (se_id != 0 && | ||
| 5805 | !gfx_ras_edc_regs[i].per_se_instance) | ||
| 5806 | continue; | ||
| 5807 | if (instance_id >= gfx_ras_edc_regs[i].num_instance) | ||
| 5808 | continue; | ||
| 5809 | |||
| 5810 | gfx_v9_0_select_se_sh(adev, se_id, 0, | ||
| 5811 | instance_id); | ||
| 5812 | |||
| 5813 | reg_value = RREG32( | ||
| 5814 | adev->reg_offset[gfx_ras_edc_regs[i].ip] | ||
| 5815 | [gfx_ras_edc_regs[i].inst] | ||
| 5816 | [gfx_ras_edc_regs[i].seg] + | ||
| 5817 | gfx_ras_edc_regs[i].reg_offset); | ||
| 5818 | sec_count = reg_value & | ||
| 5819 | gfx_ras_edc_regs[i].sec_count_mask; | ||
| 5820 | ded_count = reg_value & | ||
| 5821 | gfx_ras_edc_regs[i].ded_count_mask; | ||
| 5822 | if (sec_count) { | ||
| 5823 | DRM_INFO( | ||
| 5824 | "Instance[%d][%d]: SubBlock %s, SEC %d\n", | ||
| 5825 | se_id, instance_id, | ||
| 5826 | gfx_ras_edc_regs[i].name, | ||
| 5827 | sec_count); | ||
| 5828 | err_data->ce_count++; | ||
| 5829 | } | ||
| 5830 | 6156 | ||
| 5831 | if (ded_count) { | 6157 | for (i = 0; i < ARRAY_SIZE(sec_ded_counter_registers); i++) { |
| 5832 | DRM_INFO( | 6158 | for (j = 0; j < sec_ded_counter_registers[i].se_num; j++) { |
| 5833 | "Instance[%d][%d]: SubBlock %s, DED %d\n", | 6159 | for (k = 0; k < sec_ded_counter_registers[i].instance; k++) { |
| 5834 | se_id, instance_id, | 6160 | gfx_v9_0_select_se_sh(adev, j, 0, k); |
| 5835 | gfx_ras_edc_regs[i].name, | 6161 | reg_value = |
| 5836 | ded_count); | 6162 | RREG32(SOC15_REG_ENTRY_OFFSET(sec_ded_counter_registers[i])); |
| 5837 | err_data->ue_count++; | 6163 | if (reg_value) |
| 5838 | } | 6164 | __get_ras_error_count(&sec_ded_counter_registers[i], |
| 6165 | j, k, reg_value, | ||
| 6166 | &sec_count, &ded_count); | ||
| 5839 | } | 6167 | } |
| 5840 | } | 6168 | } |
| 5841 | } | 6169 | } |
| 6170 | |||
| 6171 | err_data->ce_count += sec_count; | ||
| 6172 | err_data->ue_count += ded_count; | ||
| 6173 | |||
| 5842 | gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); | 6174 | gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
| 5843 | mutex_unlock(&adev->grbm_idx_mutex); | 6175 | mutex_unlock(&adev->grbm_idx_mutex); |
| 5844 | 6176 | ||
| 6177 | gfx_v9_0_query_utc_edc_status(adev, err_data); | ||
| 6178 | |||
| 5845 | return 0; | 6179 | return 0; |
| 5846 | } | 6180 | } |
| 5847 | 6181 | ||
| @@ -1137,13 +1137,7 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev) · 1136 unmodified lines | |||
| 1137 | */ | 1137 | */ |
| 1138 | static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) | 1138 | static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) |
| 1139 | { | 1139 | { |
| 1140 | int r, i; | 1140 | int r; |
| 1141 | bool value; | ||
| 1142 | u32 tmp; | ||
| 1143 | |||
| 1144 | amdgpu_device_program_register_sequence(adev, | ||
| 1145 | golden_settings_vega10_hdp, | ||
| 1146 | ARRAY_SIZE(golden_settings_vega10_hdp)); | ||
| 1147 | 1141 | ||
| 1148 | if (adev->gart.bo == NULL) { | 1142 | if (adev->gart.bo == NULL) { |
| 1149 | dev_err(adev->dev, "No VRAM object for PCIE GART.\n"); | 1143 | dev_err(adev->dev, "No VRAM object for PCIE GART.\n"); |
| @@ -1153,15 +1147,6 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) · 3 unmodified lines | |||
| 1153 | if (r) | 1147 | if (r) |
| 1154 | return r; | 1148 | return r; |
| 1155 | 1149 | ||
| 1156 | switch (adev->asic_type) { | ||
| 1157 | case CHIP_RAVEN: | ||
| 1158 | /* TODO for renoir */ | ||
| 1159 | mmhub_v1_0_update_power_gating(adev, true); | ||
| 1160 | break; | ||
| 1161 | default: | ||
| 1162 | break; | ||
| 1163 | } | ||
| 1164 | |||
| 1165 | r = gfxhub_v1_0_gart_enable(adev); | 1150 | r = gfxhub_v1_0_gart_enable(adev); |
| 1166 | if (r) | 1151 | if (r) |
| 1167 | return r; | 1152 | return r; |
| @@ -1173,6 +1158,49 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) · 5 unmodified lines | |||
| 1173 | if (r) | 1158 | if (r) |
| 1174 | return r; | 1159 | return r; |
| 1175 | 1160 | ||
| 1161 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", | ||
| 1162 | (unsigned)(adev->gmc.gart_size >> 20), | ||
| 1163 | (unsigned long long)amdgpu_bo_gpu_offset(adev->gart.bo)); | ||
| 1164 | adev->gart.ready = true; | ||
| 1165 | return 0; | ||
| 1166 | } | ||
| 1167 | |||
| 1168 | static int gmc_v9_0_hw_init(void *handle) | ||
| 1169 | { | ||
| 1170 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
| 1171 | bool value; | ||
| 1172 | int r, i; | ||
| 1173 | u32 tmp; | ||
| 1174 | |||
| 1175 | /* The sequence of these two function calls matters.*/ | ||
| 1176 | gmc_v9_0_init_golden_registers(adev); | ||
| 1177 | |||
| 1178 | if (adev->mode_info.num_crtc) { | ||
| 1179 | if (adev->asic_type != CHIP_ARCTURUS) { | ||
| 1180 | /* Lockout access through VGA aperture*/ | ||
| 1181 | WREG32_FIELD15(DCE, 0, VGA_HDP_CONTROL, VGA_MEMORY_DISABLE, 1); | ||
| 1182 | |||
| 1183 | /* disable VGA render */ | ||
| 1184 | WREG32_FIELD15(DCE, 0, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0); | ||
| 1185 | } | ||
| 1186 | } | ||
| 1187 | |||
| 1188 | amdgpu_device_program_register_sequence(adev, | ||
| 1189 | golden_settings_vega10_hdp, | ||
| 1190 | ARRAY_SIZE(golden_settings_vega10_hdp)); | ||
| 1191 | |||
| 1192 | switch (adev->asic_type) { | ||
| 1193 | case CHIP_RAVEN: | ||
| 1194 | /* TODO for renoir */ | ||
| 1195 | mmhub_v1_0_update_power_gating(adev, true); | ||
| 1196 | break; | ||
| 1197 | case CHIP_ARCTURUS: | ||
| 1198 | WREG32_FIELD15(HDP, 0, HDP_MMHUB_CNTL, HDP_MMHUB_GCC, 1); | ||
| 1199 | break; | ||
| 1200 | default: | ||
| 1201 | break; | ||
| 1202 | } | ||
| 1203 | |||
| 1176 | WREG32_FIELD15(HDP, 0, HDP_MISC_CNTL, FLUSH_INVALIDATE_CACHE, 1); | 1204 | WREG32_FIELD15(HDP, 0, HDP_MISC_CNTL, FLUSH_INVALIDATE_CACHE, 1); |
| 1177 | 1205 | ||
| 1178 | tmp = RREG32_SOC15(HDP, 0, mmHDP_HOST_PATH_CNTL); | 1206 | tmp = RREG32_SOC15(HDP, 0, mmHDP_HOST_PATH_CNTL); |
| @@ -1201,31 +1229,6 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) · 22 unmodified lines | |||
| 1201 | if (adev->umc.funcs && adev->umc.funcs->init_registers) | 1229 | if (adev->umc.funcs && adev->umc.funcs->init_registers) |
| 1202 | adev->umc.funcs->init_registers(adev); | 1230 | adev->umc.funcs->init_registers(adev); |
| 1203 | 1231 | ||
| 1204 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", | ||
| 1205 | (unsigned)(adev->gmc.gart_size >> 20), | ||
| 1206 | (unsigned long long)amdgpu_bo_gpu_offset(adev->gart.bo)); | ||
| 1207 | adev->gart.ready = true; | ||
| 1208 | return 0; | ||
| 1209 | } | ||
| 1210 | |||
| 1211 | static int gmc_v9_0_hw_init(void *handle) | ||
| 1212 | { | ||
| 1213 | int r; | ||
| 1214 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
| 1215 | |||
| 1216 | /* The sequence of these two function calls matters.*/ | ||
| 1217 | gmc_v9_0_init_golden_registers(adev); | ||
| 1218 | |||
| 1219 | if (adev->mode_info.num_crtc) { | ||
| 1220 | if (adev->asic_type != CHIP_ARCTURUS) { | ||
| 1221 | /* Lockout access through VGA aperture*/ | ||
| 1222 | WREG32_FIELD15(DCE, 0, VGA_HDP_CONTROL, VGA_MEMORY_DISABLE, 1); | ||
| 1223 | |||
| 1224 | /* disable VGA render */ | ||
| 1225 | WREG32_FIELD15(DCE, 0, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0); | ||
| 1226 | } | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | r = gmc_v9_0_gart_enable(adev); | 1232 | r = gmc_v9_0_gart_enable(adev); |
| 1230 | 1233 | ||
| 1231 | return r; | 1234 | return r; |
| @@ -502,6 +502,13 @@ static void nbio_v7_4_query_ras_error_count(struct amdgpu_device *adev, · 501 unmodified lines | |||
| 502 | } | 502 | } |
| 503 | } | 503 | } |
| 504 | 504 | ||
| 505 | static void nbio_v7_4_enable_doorbell_interrupt(struct amdgpu_device *adev, | ||
| 506 | bool enable) | ||
| 507 | { | ||
| 508 | WREG32_FIELD15(NBIO, 0, BIF_DOORBELL_INT_CNTL, | ||
| 509 | DOORBELL_INTERRUPT_DISABLE, enable ? 0 : 1); | ||
| 510 | } | ||
| 511 | |||
| 505 | const struct amdgpu_nbio_funcs nbio_v7_4_funcs = { | 512 | const struct amdgpu_nbio_funcs nbio_v7_4_funcs = { |
| 506 | .get_hdp_flush_req_offset = nbio_v7_4_get_hdp_flush_req_offset, | 513 | .get_hdp_flush_req_offset = nbio_v7_4_get_hdp_flush_req_offset, |
| 507 | .get_hdp_flush_done_offset = nbio_v7_4_get_hdp_flush_done_offset, | 514 | .get_hdp_flush_done_offset = nbio_v7_4_get_hdp_flush_done_offset, |
| @@ -516,6 +523,7 @@ const struct amdgpu_nbio_funcs nbio_v7_4_funcs = { · 8 unmodified lines | |||
| 516 | .enable_doorbell_aperture = nbio_v7_4_enable_doorbell_aperture, | 523 | .enable_doorbell_aperture = nbio_v7_4_enable_doorbell_aperture, |
| 517 | .enable_doorbell_selfring_aperture = nbio_v7_4_enable_doorbell_selfring_aperture, | 524 | .enable_doorbell_selfring_aperture = nbio_v7_4_enable_doorbell_selfring_aperture, |
| 518 | .ih_doorbell_range = nbio_v7_4_ih_doorbell_range, | 525 | .ih_doorbell_range = nbio_v7_4_ih_doorbell_range, |
| 526 | .enable_doorbell_interrupt = nbio_v7_4_enable_doorbell_interrupt, | ||
| 519 | .update_medium_grain_clock_gating = nbio_v7_4_update_medium_grain_clock_gating, | 527 | .update_medium_grain_clock_gating = nbio_v7_4_update_medium_grain_clock_gating, |
| 520 | .update_medium_grain_light_sleep = nbio_v7_4_update_medium_grain_light_sleep, | 528 | .update_medium_grain_light_sleep = nbio_v7_4_update_medium_grain_light_sleep, |
| 521 | .get_clockgating_state = nbio_v7_4_get_clockgating_state, | 529 | .get_clockgating_state = nbio_v7_4_get_clockgating_state, |
| @@ -40,6 +40,9 @@ · 39 unmodified lines | |||
| 40 | MODULE_FIRMWARE("amdgpu/raven_asd.bin"); | 40 | MODULE_FIRMWARE("amdgpu/raven_asd.bin"); |
| 41 | MODULE_FIRMWARE("amdgpu/picasso_asd.bin"); | 41 | MODULE_FIRMWARE("amdgpu/picasso_asd.bin"); |
| 42 | MODULE_FIRMWARE("amdgpu/raven2_asd.bin"); | 42 | MODULE_FIRMWARE("amdgpu/raven2_asd.bin"); |
| 43 | MODULE_FIRMWARE("amdgpu/picasso_ta.bin"); | ||
| 44 | MODULE_FIRMWARE("amdgpu/raven2_ta.bin"); | ||
| 45 | MODULE_FIRMWARE("amdgpu/raven_ta.bin"); | ||
| 43 | 46 | ||
| 44 | static int psp_v10_0_init_microcode(struct psp_context *psp) | 47 | static int psp_v10_0_init_microcode(struct psp_context *psp) |
| 45 | { | 48 | { |
| @@ -58,6 +58,8 @@ MODULE_FIRMWARE("amdgpu/arcturus_ta.bin"); · 57 unmodified lines | |||
| 58 | #define mmRLC_GPM_UCODE_DATA_NV10 0x5b62 | 58 | #define mmRLC_GPM_UCODE_DATA_NV10 0x5b62 |
| 59 | #define mmSDMA0_UCODE_ADDR_NV10 0x5880 | 59 | #define mmSDMA0_UCODE_ADDR_NV10 0x5880 |
| 60 | #define mmSDMA0_UCODE_DATA_NV10 0x5881 | 60 | #define mmSDMA0_UCODE_DATA_NV10 0x5881 |
| 61 | /* memory training timeout define */ | ||
| 62 | #define MEM_TRAIN_SEND_MSG_TIMEOUT_US 3000000 | ||
| 61 | 63 | ||
| 62 | static int psp_v11_0_init_microcode(struct psp_context *psp) | 64 | static int psp_v11_0_init_microcode(struct psp_context *psp) |
| 63 | { | 65 | { |
| @@ -206,18 +208,26 @@ out: · 142 unmodified lines | |||
| 206 | return err; | 208 | return err; |
| 207 | } | 209 | } |
| 208 | 210 | ||
| 211 | static bool psp_v11_0_is_sos_alive(struct psp_context *psp) | ||
| 212 | { | ||
| 213 | struct amdgpu_device *adev = psp->adev; | ||
| 214 | uint32_t sol_reg; | ||
| 215 | |||
| 216 | sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); | ||
| 217 | |||
| 218 | return sol_reg != 0x0; | ||
| 219 | } | ||
| 220 | |||
| 209 | static int psp_v11_0_bootloader_load_kdb(struct psp_context *psp) | 221 | static int psp_v11_0_bootloader_load_kdb(struct psp_context *psp) |
| 210 | { | 222 | { |
| 211 | int ret; | 223 | int ret; |
| 212 | uint32_t psp_gfxdrv_command_reg = 0; | 224 | uint32_t psp_gfxdrv_command_reg = 0; |
| 213 | struct amdgpu_device *adev = psp->adev; | 225 | struct amdgpu_device *adev = psp->adev; |
| 214 | uint32_t sol_reg; | ||
| 215 | 226 | ||
| 216 | /* Check tOS sign of life register to confirm sys driver and sOS | 227 | /* Check tOS sign of life register to confirm sys driver and sOS |
| 217 | * are already been loaded. | 228 | * are already been loaded. |
| 218 | */ | 229 | */ |
| 219 | sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); | 230 | if (psp_v11_0_is_sos_alive(psp)) { |
| 220 | if (sol_reg) { | ||
| 221 | psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58); | 231 | psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58); |
| 222 | dev_info(adev->dev, "sos fw version = 0x%x.\n", psp->sos_fw_version); | 232 | dev_info(adev->dev, "sos fw version = 0x%x.\n", psp->sos_fw_version); |
| 223 | return 0; | 233 | return 0; |
| @@ -253,13 +263,11 @@ static int psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp) · 29 unmodified lines | |||
| 253 | int ret; | 263 | int ret; |
| 254 | uint32_t psp_gfxdrv_command_reg = 0; | 264 | uint32_t psp_gfxdrv_command_reg = 0; |
| 255 | struct amdgpu_device *adev = psp->adev; | 265 | struct amdgpu_device *adev = psp->adev; |
| 256 | uint32_t sol_reg; | ||
| 257 | 266 | ||
| 258 | /* Check sOS sign of life register to confirm sys driver and sOS | 267 | /* Check sOS sign of life register to confirm sys driver and sOS |
| 259 | * are already been loaded. | 268 | * are already been loaded. |
| 260 | */ | 269 | */ |
| 261 | sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); | 270 | if (psp_v11_0_is_sos_alive(psp)) { |
| 262 | if (sol_reg) { | ||
| 263 | psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58); | 271 | psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58); |
| 264 | dev_info(adev->dev, "sos fw version = 0x%x.\n", psp->sos_fw_version); | 272 | dev_info(adev->dev, "sos fw version = 0x%x.\n", psp->sos_fw_version); |
| 265 | return 0; | 273 | return 0; |
| @@ -297,13 +305,11 @@ static int psp_v11_0_bootloader_load_sos(struct psp_context *psp) · 31 unmodified lines | |||
| 297 | int ret; | 305 | int ret; |
| 298 | unsigned int psp_gfxdrv_command_reg = 0; | 306 | unsigned int psp_gfxdrv_command_reg = 0; |
| 299 | struct amdgpu_device *adev = psp->adev; | 307 | struct amdgpu_device *adev = psp->adev; |
| 300 | uint32_t sol_reg; | ||
| 301 | 308 | ||
| 302 | /* Check sOS sign of life register to confirm sys driver and sOS | 309 | /* Check sOS sign of life register to confirm sys driver and sOS |
| 303 | * are already been loaded. | 310 | * are already been loaded. |
| 304 | */ | 311 | */ |
| 305 | sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); | 312 | if (psp_v11_0_is_sos_alive(psp)) |
| 306 | if (sol_reg) | ||
| 307 | return 0; | 313 | return 0; |
| 308 | 314 | ||
| 309 | /* Wait for bootloader to signify that is ready having bit 31 of C2PMSG_35 set to 1 */ | 315 | /* Wait for bootloader to signify that is ready having bit 31 of C2PMSG_35 set to 1 */ |
| @@ -898,6 +904,162 @@ static int psp_v11_0_rlc_autoload_start(struct psp_context *psp) · 588 unmodified lines | |||
| 898 | return psp_rlc_autoload_start(psp); | 904 | return psp_rlc_autoload_start(psp); |
| 899 | } | 905 | } |
| 900 | 906 | ||
| 907 | static int psp_v11_0_memory_training_send_msg(struct psp_context *psp, int msg) | ||
| 908 | { | ||
| 909 | int ret; | ||
| 910 | int i; | ||
| 911 | uint32_t data_32; | ||
| 912 | int max_wait; | ||
| 913 | struct amdgpu_device *adev = psp->adev; | ||
| 914 | |||
| 915 | data_32 = (psp->mem_train_ctx.c2p_train_data_offset >> 20); | ||
| 916 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, data_32); | ||
| 917 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35, msg); | ||
| 918 | |||
| 919 | max_wait = MEM_TRAIN_SEND_MSG_TIMEOUT_US / adev->usec_timeout; | ||
| 920 | for (i = 0; i < max_wait; i++) { | ||
| 921 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35), | ||
| 922 | 0x80000000, 0x80000000, false); | ||
| 923 | if (ret == 0) | ||
| 924 | break; | ||
| 925 | } | ||
| 926 | if (i < max_wait) | ||
| 927 | ret = 0; | ||
| 928 | else | ||
| 929 | ret = -ETIME; | ||
| 930 | |||
| 931 | DRM_DEBUG("training %s %s, cost %d @ %d ms\n", | ||
| 932 | (msg == PSP_BL__DRAM_SHORT_TRAIN) ? "short" : "long", | ||
| 933 | (ret == 0) ? "succeed" : "failed", | ||
| 934 | i, adev->usec_timeout/1000); | ||
| 935 | return ret; | ||
| 936 | } | ||
| 937 | |||
| 938 | static void psp_v11_0_memory_training_fini(struct psp_context *psp) | ||
| 939 | { | ||
| 940 | struct psp_memory_training_context *ctx = &psp->mem_train_ctx; | ||
| 941 | |||
| 942 | ctx->init = PSP_MEM_TRAIN_NOT_SUPPORT; | ||
| 943 | kfree(ctx->sys_cache); | ||
| 944 | ctx->sys_cache = NULL; | ||
| 945 | } | ||
| 946 | |||
| 947 | static int psp_v11_0_memory_training_init(struct psp_context *psp) | ||
| 948 | { | ||
| 949 | int ret; | ||
| 950 | struct psp_memory_training_context *ctx = &psp->mem_train_ctx; | ||
| 951 | |||
| 952 | if (ctx->init != PSP_MEM_TRAIN_RESERVE_SUCCESS) { | ||
| 953 | DRM_DEBUG("memory training is not supported!\n"); | ||
| 954 | return 0; | ||
| 955 | } | ||
| 956 | |||
| 957 | ctx->sys_cache = kzalloc(ctx->train_data_size, GFP_KERNEL); | ||
| 958 | if (ctx->sys_cache == NULL) { | ||
| 959 | DRM_ERROR("alloc mem_train_ctx.sys_cache failed!\n"); | ||
| 960 | ret = -ENOMEM; | ||
| 961 | goto Err_out; | ||
| 962 | } | ||
| 963 | |||
| 964 | DRM_DEBUG("train_data_size:%llx,p2c_train_data_offset:%llx,c2p_train_data_offset:%llx.\n", | ||
| 965 | ctx->train_data_size, | ||
| 966 | ctx->p2c_train_data_offset, | ||
| 967 | ctx->c2p_train_data_offset); | ||
| 968 | ctx->init = PSP_MEM_TRAIN_INIT_SUCCESS; | ||
| 969 | return 0; | ||
| 970 | |||
| 971 | Err_out: | ||
| 972 | psp_v11_0_memory_training_fini(psp); | ||
| 973 | return ret; | ||
| 974 | } | ||
| 975 | |||
| 976 | /* | ||
| 977 | * save and restore proces | ||
| 978 | */ | ||
| 979 | static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops) | ||
| 980 | { | ||
| 981 | int ret; | ||
| 982 | uint32_t p2c_header[4]; | ||
| 983 | struct psp_memory_training_context *ctx = &psp->mem_train_ctx; | ||
| 984 | uint32_t *pcache = (uint32_t*)ctx->sys_cache; | ||
| 985 | |||
| 986 | if (ctx->init == PSP_MEM_TRAIN_NOT_SUPPORT) { | ||
| 987 | DRM_DEBUG("Memory training is not supported.\n"); | ||
| 988 | return 0; | ||
| 989 | } else if (ctx->init != PSP_MEM_TRAIN_INIT_SUCCESS) { | ||
| 990 | DRM_ERROR("Memory training initialization failure.\n"); | ||
| 991 | return -EINVAL; | ||
| 992 | } | ||
| 993 | |||
| 994 | if (psp_v11_0_is_sos_alive(psp)) { | ||
| 995 | DRM_DEBUG("SOS is alive, skip memory training.\n"); | ||
| 996 | return 0; | ||
| 997 | } | ||
| 998 | |||
| 999 | amdgpu_device_vram_access(psp->adev, ctx->p2c_train_data_offset, p2c_header, sizeof(p2c_header), false); | ||
| 1000 | DRM_DEBUG("sys_cache[%08x,%08x,%08x,%08x] p2c_header[%08x,%08x,%08x,%08x]\n", | ||
| 1001 | pcache[0], pcache[1], pcache[2], pcache[3], | ||
| 1002 | p2c_header[0], p2c_header[1], p2c_header[2], p2c_header[3]); | ||
| 1003 | |||
| 1004 | if (ops & PSP_MEM_TRAIN_SEND_SHORT_MSG) { | ||
| 1005 | DRM_DEBUG("Short training depends on restore.\n"); | ||
| 1006 | ops |= PSP_MEM_TRAIN_RESTORE; | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | if ((ops & PSP_MEM_TRAIN_RESTORE) && | ||
| 1010 | pcache[0] != MEM_TRAIN_SYSTEM_SIGNATURE) { | ||
| 1011 | DRM_DEBUG("sys_cache[0] is invalid, restore depends on save.\n"); | ||
| 1012 | ops |= PSP_MEM_TRAIN_SAVE; | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | if (p2c_header[0] == MEM_TRAIN_SYSTEM_SIGNATURE && | ||
| 1016 | !(pcache[0] == MEM_TRAIN_SYSTEM_SIGNATURE && | ||
| 1017 | pcache[3] == p2c_header[3])) { | ||
| 1018 | DRM_DEBUG("sys_cache is invalid or out-of-date, need save training data to sys_cache.\n"); | ||
| 1019 | ops |= PSP_MEM_TRAIN_SAVE; | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | if ((ops & PSP_MEM_TRAIN_SAVE) && | ||
| 1023 | p2c_header[0] != MEM_TRAIN_SYSTEM_SIGNATURE) { | ||
| 1024 | DRM_DEBUG("p2c_header[0] is invalid, save depends on long training.\n"); | ||
| 1025 | ops |= PSP_MEM_TRAIN_SEND_LONG_MSG; | ||
| 1026 | } | ||
| 1027 | |||
| 1028 | if (ops & PSP_MEM_TRAIN_SEND_LONG_MSG) { | ||
| 1029 | ops &= ~PSP_MEM_TRAIN_SEND_SHORT_MSG; | ||
| 1030 | ops |= PSP_MEM_TRAIN_SAVE; | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | DRM_DEBUG("Memory training ops:%x.\n", ops); | ||
| 1034 | |||
| 1035 | if (ops & PSP_MEM_TRAIN_SEND_LONG_MSG) { | ||
| 1036 | ret = psp_v11_0_memory_training_send_msg(psp, PSP_BL__DRAM_LONG_TRAIN); | ||
| 1037 | if (ret) { | ||
| 1038 | DRM_ERROR("Send long training msg failed.\n"); | ||
| 1039 | return ret; | ||
| 1040 | } | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | if (ops & PSP_MEM_TRAIN_SAVE) { | ||
| 1044 | amdgpu_device_vram_access(psp->adev, ctx->p2c_train_data_offset, ctx->sys_cache, ctx->train_data_size, false); | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | if (ops & PSP_MEM_TRAIN_RESTORE) { | ||
| 1048 | amdgpu_device_vram_access(psp->adev, ctx->c2p_train_data_offset, ctx->sys_cache, ctx->train_data_size, true); | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | if (ops & PSP_MEM_TRAIN_SEND_SHORT_MSG) { | ||
| 1052 | ret = psp_v11_0_memory_training_send_msg(psp, (amdgpu_force_long_training > 0) ? | ||
| 1053 | PSP_BL__DRAM_LONG_TRAIN : PSP_BL__DRAM_SHORT_TRAIN); | ||
| 1054 | if (ret) { | ||
| 1055 | DRM_ERROR("send training msg failed.\n"); | ||
| 1056 | return ret; | ||
| 1057 | } | ||
| 1058 | } | ||
| 1059 | ctx->training_cnt++; | ||
| 1060 | return 0; | ||
| 1061 | } | ||
| 1062 | |||
| 901 | static const struct psp_funcs psp_v11_0_funcs = { | 1063 | static const struct psp_funcs psp_v11_0_funcs = { |
| 902 | .init_microcode = psp_v11_0_init_microcode, | 1064 | .init_microcode = psp_v11_0_init_microcode, |
| 903 | .bootloader_load_kdb = psp_v11_0_bootloader_load_kdb, | 1065 | .bootloader_load_kdb = psp_v11_0_bootloader_load_kdb, |
| @@ -918,6 +1080,9 @@ static const struct psp_funcs psp_v11_0_funcs = { · 14 unmodified lines | |||
| 918 | .ras_trigger_error = psp_v11_0_ras_trigger_error, | 1080 | .ras_trigger_error = psp_v11_0_ras_trigger_error, |
| 919 | .ras_cure_posion = psp_v11_0_ras_cure_posion, | 1081 | .ras_cure_posion = psp_v11_0_ras_cure_posion, |
| 920 | .rlc_autoload_start = psp_v11_0_rlc_autoload_start, | 1082 | .rlc_autoload_start = psp_v11_0_rlc_autoload_start, |
| 1083 | .mem_training_init = psp_v11_0_memory_training_init, | ||
| 1084 | .mem_training_fini = psp_v11_0_memory_training_fini, | ||
| 1085 | .mem_training = psp_v11_0_memory_training, | ||
| 921 | }; | 1086 | }; |
| 922 | 1087 | ||
| 923 | void psp_v11_0_set_psp_funcs(struct psp_context *psp) | 1088 | void psp_v11_0_set_psp_funcs(struct psp_context *psp) |
| @@ -1792,7 +1792,7 @@ static int sdma_v4_0_hw_init(void *handle) · 1791 unmodified lines | |||
| 1792 | 1792 | ||
| 1793 | if ((adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs && | 1793 | if ((adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs && |
| 1794 | adev->powerplay.pp_funcs->set_powergating_by_smu) || | 1794 | adev->powerplay.pp_funcs->set_powergating_by_smu) || |
| 1795 | adev->asic_type == CHIP_RENOIR) | 1795 | (adev->asic_type == CHIP_RENOIR && !adev->in_gpu_reset)) |
| 1796 | amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, false); | 1796 | amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, false); |
| 1797 | 1797 | ||
| 1798 | if (!amdgpu_sriov_vf(adev)) | 1798 | if (!amdgpu_sriov_vf(adev)) |
| @@ -478,36 +478,58 @@ static int soc15_asic_mode1_reset(struct amdgpu_device *adev) · 477 unmodified lines | |||
| 478 | 478 | ||
| 479 | static int soc15_asic_get_baco_capability(struct amdgpu_device *adev, bool *cap) | 479 | static int soc15_asic_get_baco_capability(struct amdgpu_device *adev, bool *cap) |
| 480 | { | 480 | { |
| 481 | void *pp_handle = adev->powerplay.pp_handle; | 481 | if (is_support_sw_smu(adev)) { |
| 482 | const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; | 482 | struct smu_context *smu = &adev->smu; |
| 483 | 483 | ||
| 484 | if (!pp_funcs || !pp_funcs->get_asic_baco_capability) { | 484 | *cap = smu_baco_is_support(smu); |
| 485 | *cap = false; | 485 | return 0; |
| 486 | return -ENOENT; | 486 | } else { |
| 487 | } | 487 | void *pp_handle = adev->powerplay.pp_handle; |
| 488 | const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; | ||
| 488 | 489 | ||
| 489 | return pp_funcs->get_asic_baco_capability(pp_handle, cap); | 490 | if (!pp_funcs || !pp_funcs->get_asic_baco_capability) { |
| 491 | *cap = false; | ||
| 492 | return -ENOENT; | ||
| 493 | } | ||
| 494 | |||
| 495 | return pp_funcs->get_asic_baco_capability(pp_handle, cap); | ||
| 496 | } | ||
| 490 | } | 497 | } |
| 491 | 498 | ||
| 492 | static int soc15_asic_baco_reset(struct amdgpu_device *adev) | 499 | static int soc15_asic_baco_reset(struct amdgpu_device *adev) |
| 493 | { | 500 | { |
| 494 | void *pp_handle = adev->powerplay.pp_handle; | 501 | struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); |
| 495 | const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; | ||
| 496 | 502 | ||
| 497 | if (!pp_funcs ||!pp_funcs->get_asic_baco_state ||!pp_funcs->set_asic_baco_state) | 503 | /* avoid NBIF got stuck when do RAS recovery in BACO reset */ |
| 498 | return -ENOENT; | 504 | if (ras && ras->supported) |
| 505 | adev->nbio.funcs->enable_doorbell_interrupt(adev, false); | ||
| 499 | 506 | ||
| 500 | /* enter BACO state */ | 507 | dev_info(adev->dev, "GPU BACO reset\n"); |
| 501 | if (pp_funcs->set_asic_baco_state(pp_handle, 1)) | ||
| 502 | return -EIO; | ||
| 503 | 508 | ||
| 504 | /* exit BACO state */ | 509 | if (is_support_sw_smu(adev)) { |
| 505 | if (pp_funcs->set_asic_baco_state(pp_handle, 0)) | 510 | struct smu_context *smu = &adev->smu; |
| 506 | return -EIO; | ||
| 507 | 511 | ||
| 508 | dev_info(adev->dev, "GPU BACO reset\n"); | 512 | if (smu_baco_reset(smu)) |
| 513 | return -EIO; | ||
| 514 | } else { | ||
| 515 | void *pp_handle = adev->powerplay.pp_handle; | ||
| 516 | const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; | ||
| 517 | |||
| 518 | if (!pp_funcs ||!pp_funcs->get_asic_baco_state ||!pp_funcs->set_asic_baco_state) | ||
| 519 | return -ENOENT; | ||
| 520 | |||
| 521 | /* enter BACO state */ | ||
| 522 | if (pp_funcs->set_asic_baco_state(pp_handle, 1)) | ||
| 523 | return -EIO; | ||
| 524 | |||
| 525 | /* exit BACO state */ | ||
| 526 | if (pp_funcs->set_asic_baco_state(pp_handle, 0)) | ||
| 527 | return -EIO; | ||
| 528 | } | ||
| 509 | 529 | ||
| 510 | adev->in_baco_reset = 1; | 530 | /* re-enable doorbell interrupt after BACO exit */ |
| 531 | if (ras && ras->supported) | ||
| 532 | adev->nbio.funcs->enable_doorbell_interrupt(adev, true); | ||
| 511 | 533 | ||
| 512 | return 0; | 534 | return 0; |
| 513 | } | 535 | } |
| @@ -67,6 +67,8 @@ struct soc15_allowed_register_entry { · 66 unmodified lines | |||
| 67 | #define SOC15_REG_GOLDEN_VALUE(ip, inst, reg, and_mask, or_mask) \ | 67 | #define SOC15_REG_GOLDEN_VALUE(ip, inst, reg, and_mask, or_mask) \ |
| 68 | { ip##_HWIP, inst, reg##_BASE_IDX, reg, and_mask, or_mask } | 68 | { ip##_HWIP, inst, reg##_BASE_IDX, reg, and_mask, or_mask } |
| 69 | 69 | ||
| 70 | #define SOC15_REG_FIELD(reg, field) reg##__##field##_MASK, reg##__##field##__SHIFT | ||
| 71 | |||
| 70 | void soc15_grbm_select(struct amdgpu_device *adev, | 72 | void soc15_grbm_select(struct amdgpu_device *adev, |
| 71 | u32 me, u32 pipe, u32 queue, u32 vmid); | 73 | u32 me, u32 pipe, u32 queue, u32 vmid); |
| 72 | int soc15_set_ip_blocks(struct amdgpu_device *adev); | 74 | int soc15_set_ip_blocks(struct amdgpu_device *adev); |
| @@ -206,13 +206,14 @@ static int uvd_v6_0_enc_ring_test_ring(struct amdgpu_ring *ring) · 205 unmodified lines | |||
| 206 | * Open up a stream for HW test | 206 | * Open up a stream for HW test |
| 207 | */ | 207 | */ |
| 208 | static int uvd_v6_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, | 208 | static int uvd_v6_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, |
| 209 | struct amdgpu_bo *bo, | ||
| 209 | struct dma_fence **fence) | 210 | struct dma_fence **fence) |
| 210 | { | 211 | { |
| 211 | const unsigned ib_size_dw = 16; | 212 | const unsigned ib_size_dw = 16; |
| 212 | struct amdgpu_job *job; | 213 | struct amdgpu_job *job; |
| 213 | struct amdgpu_ib *ib; | 214 | struct amdgpu_ib *ib; |
| 214 | struct dma_fence *f = NULL; | 215 | struct dma_fence *f = NULL; |
| 215 | uint64_t dummy; | 216 | uint64_t addr; |
| 216 | int i, r; | 217 | int i, r; |
| 217 | 218 | ||
| 218 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); | 219 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); |
| @@ -220,15 +221,15 @@ static int uvd_v6_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle · 1 unmodified line | |||
| 220 | return r; | 221 | return r; |
| 221 | 222 | ||
| 222 | ib = &job->ibs[0]; | 223 | ib = &job->ibs[0]; |
| 223 | dummy = ib->gpu_addr + 1024; | 224 | addr = amdgpu_bo_gpu_offset(bo); |
| 224 | 225 | ||
| 225 | ib->length_dw = 0; | 226 | ib->length_dw = 0; |
| 226 | ib->ptr[ib->length_dw++] = 0x00000018; | 227 | ib->ptr[ib->length_dw++] = 0x00000018; |
| 227 | ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ | 228 | ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ |
| 228 | ib->ptr[ib->length_dw++] = handle; | 229 | ib->ptr[ib->length_dw++] = handle; |
| 229 | ib->ptr[ib->length_dw++] = 0x00010000; | 230 | ib->ptr[ib->length_dw++] = 0x00010000; |
| 230 | ib->ptr[ib->length_dw++] = upper_32_bits(dummy); | 231 | ib->ptr[ib->length_dw++] = upper_32_bits(addr); |
| 231 | ib->ptr[ib->length_dw++] = dummy; | 232 | ib->ptr[ib->length_dw++] = addr; |
| 232 | 233 | ||
| 233 | ib->ptr[ib->length_dw++] = 0x00000014; | 234 | ib->ptr[ib->length_dw++] = 0x00000014; |
| 234 | ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ | 235 | ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ |
| @@ -268,13 +269,14 @@ err: · 33 unmodified lines | |||
| 268 | */ | 269 | */ |
| 269 | static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, | 270 | static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, |
| 270 | uint32_t handle, | 271 | uint32_t handle, |
| 272 | struct amdgpu_bo *bo, | ||
| 271 | struct dma_fence **fence) | 273 | struct dma_fence **fence) |
| 272 | { | 274 | { |
| 273 | const unsigned ib_size_dw = 16; | 275 | const unsigned ib_size_dw = 16; |
| 274 | struct amdgpu_job *job; | 276 | struct amdgpu_job *job; |
| 275 | struct amdgpu_ib *ib; | 277 | struct amdgpu_ib *ib; |
| 276 | struct dma_fence *f = NULL; | 278 | struct dma_fence *f = NULL; |
| 277 | uint64_t dummy; | 279 | uint64_t addr; |
| 278 | int i, r; | 280 | int i, r; |
| 279 | 281 | ||
| 280 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); | 282 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); |
| @@ -282,15 +284,15 @@ static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, · 1 unmodified line | |||
| 282 | return r; | 284 | return r; |
| 283 | 285 | ||
| 284 | ib = &job->ibs[0]; | 286 | ib = &job->ibs[0]; |
| 285 | dummy = ib->gpu_addr + 1024; | 287 | addr = amdgpu_bo_gpu_offset(bo); |
| 286 | 288 | ||
| 287 | ib->length_dw = 0; | 289 | ib->length_dw = 0; |
| 288 | ib->ptr[ib->length_dw++] = 0x00000018; | 290 | ib->ptr[ib->length_dw++] = 0x00000018; |
| 289 | ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ | 291 | ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ |
| 290 | ib->ptr[ib->length_dw++] = handle; | 292 | ib->ptr[ib->length_dw++] = handle; |
| 291 | ib->ptr[ib->length_dw++] = 0x00010000; | 293 | ib->ptr[ib->length_dw++] = 0x00010000; |
| 292 | ib->ptr[ib->length_dw++] = upper_32_bits(dummy); | 294 | ib->ptr[ib->length_dw++] = upper_32_bits(addr); |
| 293 | ib->ptr[ib->length_dw++] = dummy; | 295 | ib->ptr[ib->length_dw++] = addr; |
| 294 | 296 | ||
| 295 | ib->ptr[ib->length_dw++] = 0x00000014; | 297 | ib->ptr[ib->length_dw++] = 0x00000014; |
| 296 | ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ | 298 | ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ |
| @@ -327,13 +329,20 @@ err: · 30 unmodified lines | |||
| 327 | static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) | 329 | static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) |
| 328 | { | 330 | { |
| 329 | struct dma_fence *fence = NULL; | 331 | struct dma_fence *fence = NULL; |
| 332 | struct amdgpu_bo *bo = NULL; | ||
| 330 | long r; | 333 | long r; |
| 331 | 334 | ||
| 332 | r = uvd_v6_0_enc_get_create_msg(ring, 1, NULL); | 335 | r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE, |
| 336 | AMDGPU_GEM_DOMAIN_VRAM, | ||
| 337 | &bo, NULL, NULL); | ||
| 338 | if (r) | ||
| 339 | return r; | ||
| 340 | |||
| 341 | r = uvd_v6_0_enc_get_create_msg(ring, 1, bo, NULL); | ||
| 333 | if (r) | 342 | if (r) |
| 334 | goto error; | 343 | goto error; |
| 335 | 344 | ||
| 336 | r = uvd_v6_0_enc_get_destroy_msg(ring, 1, &fence); | 345 | r = uvd_v6_0_enc_get_destroy_msg(ring, 1, bo, &fence); |
| 337 | if (r) | 346 | if (r) |
| 338 | goto error; | 347 | goto error; |
| 339 | 348 | ||
| @@ -345,6 +354,8 @@ static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) · 5 unmodified lines | |||
| 345 | 354 | ||
| 346 | error: | 355 | error: |
| 347 | dma_fence_put(fence); | 356 | dma_fence_put(fence); |
| 357 | amdgpu_bo_unreserve(bo); | ||
| 358 | amdgpu_bo_unref(&bo); | ||
| 348 | return r; | 359 | return r; |
| 349 | } | 360 | } |
| 350 | 361 | ||
| @@ -214,13 +214,14 @@ static int uvd_v7_0_enc_ring_test_ring(struct amdgpu_ring *ring) · 213 unmodified lines | |||
| 214 | * Open up a stream for HW test | 214 | * Open up a stream for HW test |
| 215 | */ | 215 | */ |
| 216 | static int uvd_v7_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, | 216 | static int uvd_v7_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, |
| 217 | struct amdgpu_bo *bo, | ||
| 217 | struct dma_fence **fence) | 218 | struct dma_fence **fence) |
| 218 | { | 219 | { |
| 219 | const unsigned ib_size_dw = 16; | 220 | const unsigned ib_size_dw = 16; |
| 220 | struct amdgpu_job *job; | 221 | struct amdgpu_job *job; |
| 221 | struct amdgpu_ib *ib; | 222 | struct amdgpu_ib *ib; |
| 222 | struct dma_fence *f = NULL; | 223 | struct dma_fence *f = NULL; |
| 223 | uint64_t dummy; | 224 | uint64_t addr; |
| 224 | int i, r; | 225 | int i, r; |
| 225 | 226 | ||
| 226 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); | 227 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); |
| @@ -228,15 +229,15 @@ static int uvd_v7_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle · 1 unmodified line | |||
| 228 | return r; | 229 | return r; |
| 229 | 230 | ||
| 230 | ib = &job->ibs[0]; | 231 | ib = &job->ibs[0]; |
| 231 | dummy = ib->gpu_addr + 1024; | 232 | addr = amdgpu_bo_gpu_offset(bo); |
| 232 | 233 | ||
| 233 | ib->length_dw = 0; | 234 | ib->length_dw = 0; |
| 234 | ib->ptr[ib->length_dw++] = 0x00000018; | 235 | ib->ptr[ib->length_dw++] = 0x00000018; |
| 235 | ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ | 236 | ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ |
| 236 | ib->ptr[ib->length_dw++] = handle; | 237 | ib->ptr[ib->length_dw++] = handle; |
| 237 | ib->ptr[ib->length_dw++] = 0x00000000; | 238 | ib->ptr[ib->length_dw++] = 0x00000000; |
| 238 | ib->ptr[ib->length_dw++] = upper_32_bits(dummy); | 239 | ib->ptr[ib->length_dw++] = upper_32_bits(addr); |
| 239 | ib->ptr[ib->length_dw++] = dummy; | 240 | ib->ptr[ib->length_dw++] = addr; |
| 240 | 241 | ||
| 241 | ib->ptr[ib->length_dw++] = 0x00000014; | 242 | ib->ptr[ib->length_dw++] = 0x00000014; |
| 242 | ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ | 243 | ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ |
| @@ -275,13 +276,14 @@ err: · 32 unmodified lines | |||
| 275 | * Close up a stream for HW test or if userspace failed to do so | 276 | * Close up a stream for HW test or if userspace failed to do so |
| 276 | */ | 277 | */ |
| 277 | static int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, | 278 | static int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, |
| 278 | struct dma_fence **fence) | 279 | struct amdgpu_bo *bo, |
| 280 | struct dma_fence **fence) | ||
| 279 | { | 281 | { |
| 280 | const unsigned ib_size_dw = 16; | 282 | const unsigned ib_size_dw = 16; |
| 281 | struct amdgpu_job *job; | 283 | struct amdgpu_job *job; |
| 282 | struct amdgpu_ib *ib; | 284 | struct amdgpu_ib *ib; |
| 283 | struct dma_fence *f = NULL; | 285 | struct dma_fence *f = NULL; |
| 284 | uint64_t dummy; | 286 | uint64_t addr; |
| 285 | int i, r; | 287 | int i, r; |
| 286 | 288 | ||
| 287 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); | 289 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); |
| @@ -289,15 +291,15 @@ static int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handl · 1 unmodified line | |||
| 289 | return r; | 291 | return r; |
| 290 | 292 | ||
| 291 | ib = &job->ibs[0]; | 293 | ib = &job->ibs[0]; |
| 292 | dummy = ib->gpu_addr + 1024; | 294 | addr = amdgpu_bo_gpu_offset(bo); |
| 293 | 295 | ||
| 294 | ib->length_dw = 0; | 296 | ib->length_dw = 0; |
| 295 | ib->ptr[ib->length_dw++] = 0x00000018; | 297 | ib->ptr[ib->length_dw++] = 0x00000018; |
| 296 | ib->ptr[ib->length_dw++] = 0x00000001; | 298 | ib->ptr[ib->length_dw++] = 0x00000001; |
| 297 | ib->ptr[ib->length_dw++] = handle; | 299 | ib->ptr[ib->length_dw++] = handle; |
| 298 | ib->ptr[ib->length_dw++] = 0x00000000; | 300 | ib->ptr[ib->length_dw++] = 0x00000000; |
| 299 | ib->ptr[ib->length_dw++] = upper_32_bits(dummy); | 301 | ib->ptr[ib->length_dw++] = upper_32_bits(addr); |
| 300 | ib->ptr[ib->length_dw++] = dummy; | 302 | ib->ptr[ib->length_dw++] = addr; |
| 301 | 303 | ||
| 302 | ib->ptr[ib->length_dw++] = 0x00000014; | 304 | ib->ptr[ib->length_dw++] = 0x00000014; |
| 303 | ib->ptr[ib->length_dw++] = 0x00000002; | 305 | ib->ptr[ib->length_dw++] = 0x00000002; |
| @@ -334,13 +336,20 @@ err: · 30 unmodified lines | |||
| 334 | static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) | 336 | static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) |
| 335 | { | 337 | { |
| 336 | struct dma_fence *fence = NULL; | 338 | struct dma_fence *fence = NULL; |
| 339 | struct amdgpu_bo *bo = NULL; | ||
| 337 | long r; | 340 | long r; |
| 338 | 341 | ||
| 339 | r = uvd_v7_0_enc_get_create_msg(ring, 1, NULL); | 342 | r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE, |
| 343 | AMDGPU_GEM_DOMAIN_VRAM, | ||
| 344 | &bo, NULL, NULL); | ||
| 345 | if (r) | ||
| 346 | return r; | ||
| 347 | |||
| 348 | r = uvd_v7_0_enc_get_create_msg(ring, 1, bo, NULL); | ||
| 340 | if (r) | 349 | if (r) |
| 341 | goto error; | 350 | goto error; |
| 342 | 351 | ||
| 343 | r = uvd_v7_0_enc_get_destroy_msg(ring, 1, &fence); | 352 | r = uvd_v7_0_enc_get_destroy_msg(ring, 1, bo, &fence); |
| 344 | if (r) | 353 | if (r) |
| 345 | goto error; | 354 | goto error; |
| 346 | 355 | ||
| @@ -352,6 +361,8 @@ static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) · 5 unmodified lines | |||
| 352 | 361 | ||
| 353 | error: | 362 | error: |
| 354 | dma_fence_put(fence); | 363 | dma_fence_put(fence); |
| 364 | amdgpu_bo_unreserve(bo); | ||
| 365 | amdgpu_bo_unref(&bo); | ||
| 355 | return r; | 366 | return r; |
| 356 | } | 367 | } |
| 357 | 368 | ||
| @@ -25,6 +25,7 @@ · 24 unmodified lines | |||
| 25 | 25 | ||
| 26 | #include "amdgpu.h" | 26 | #include "amdgpu.h" |
| 27 | #include "amdgpu_vcn.h" | 27 | #include "amdgpu_vcn.h" |
| 28 | #include "amdgpu_pm.h" | ||
| 28 | #include "soc15.h" | 29 | #include "soc15.h" |
| 29 | #include "soc15d.h" | 30 | #include "soc15d.h" |
| 30 | #include "vcn_v2_0.h" | 31 | #include "vcn_v2_0.h" |
| @@ -709,6 +710,9 @@ static int vcn_v2_5_start(struct amdgpu_device *adev) · 678 unmodified lines | |||
| 709 | uint32_t rb_bufsz, tmp; | 710 | uint32_t rb_bufsz, tmp; |
| 710 | int i, j, k, r; | 711 | int i, j, k, r; |
| 711 | 712 | ||
| 713 | if (adev->pm.dpm_enabled) | ||
| 714 | amdgpu_dpm_enable_uvd(adev, true); | ||
| 715 | |||
| 712 | for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { | 716 | for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { |
| 713 | if (adev->vcn.harvest_config & (1 << i)) | 717 | if (adev->vcn.harvest_config & (1 << i)) |
| 714 | continue; | 718 | continue; |
| @@ -939,6 +943,9 @@ static int vcn_v2_5_stop(struct amdgpu_device *adev) · 224 unmodified lines | |||
| 939 | ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); | 943 | ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); |
| 940 | } | 944 | } |
| 941 | 945 | ||
| 946 | if (adev->pm.dpm_enabled) | ||
| 947 | amdgpu_dpm_enable_uvd(adev, false); | ||
| 948 | |||
| 942 | return 0; | 949 | return 0; |
| 943 | } | 950 | } |
| 944 | 951 | ||
| @@ -689,16 +689,50 @@ static int vi_gpu_pci_config_reset(struct amdgpu_device *adev) · 688 unmodified lines | |||
| 689 | return -EINVAL; | 689 | return -EINVAL; |
| 690 | } | 690 | } |
| 691 | 691 | ||
| 692 | int smu7_asic_get_baco_capability(struct amdgpu_device *adev, bool *cap) | ||
| 693 | { | ||
| 694 | void *pp_handle = adev->powerplay.pp_handle; | ||
| 695 | const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; | ||
| 696 | |||
| 697 | if (!pp_funcs || !pp_funcs->get_asic_baco_capability) { | ||
| 698 | *cap = false; | ||
| 699 | return -ENOENT; | ||
| 700 | } | ||
| 701 | |||
| 702 | return pp_funcs->get_asic_baco_capability(pp_handle, cap); | ||
| 703 | } | ||
| 704 | |||
| 705 | int smu7_asic_baco_reset(struct amdgpu_device *adev) | ||
| 706 | { | ||
| 707 | void *pp_handle = adev->powerplay.pp_handle; | ||
| 708 | const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; | ||
| 709 | |||
| 710 | if (!pp_funcs ||!pp_funcs->get_asic_baco_state ||!pp_funcs->set_asic_baco_state) | ||
| 711 | return -ENOENT; | ||
| 712 | |||
| 713 | /* enter BACO state */ | ||
| 714 | if (pp_funcs->set_asic_baco_state(pp_handle, 1)) | ||
| 715 | return -EIO; | ||
| 716 | |||
| 717 | /* exit BACO state */ | ||
| 718 | if (pp_funcs->set_asic_baco_state(pp_handle, 0)) | ||
| 719 | return -EIO; | ||
| 720 | |||
| 721 | dev_info(adev->dev, "GPU BACO reset\n"); | ||
| 722 | |||
| 723 | return 0; | ||
| 724 | } | ||
| 725 | |||
| 692 | /** | 726 | /** |
| 693 | * vi_asic_reset - soft reset GPU | 727 | * vi_asic_pci_config_reset - soft reset GPU |
| 694 | * | 728 | * |
| 695 | * @adev: amdgpu_device pointer | 729 | * @adev: amdgpu_device pointer |
| 696 | * | 730 | * |
| 697 | * Look up which blocks are hung and attempt | 731 | * Use PCI Config method to reset the GPU. |
| 698 | * to reset them. | 732 | * |
| 699 | * Returns 0 for success. | 733 | * Returns 0 for success. |
| 700 | */ | 734 | */ |
| 701 | static int vi_asic_reset(struct amdgpu_device *adev) | 735 | static int vi_asic_pci_config_reset(struct amdgpu_device *adev) |
| 702 | { | 736 | { |
| 703 | int r; | 737 | int r; |
| 704 | 738 | ||
| @@ -714,7 +748,47 @@ static int vi_asic_reset(struct amdgpu_device *adev) · 9 unmodified lines | |||
| 714 | static enum amd_reset_method | 748 | static enum amd_reset_method |
| 715 | vi_asic_reset_method(struct amdgpu_device *adev) | 749 | vi_asic_reset_method(struct amdgpu_device *adev) |
| 716 | { | 750 | { |
| 717 | return AMD_RESET_METHOD_LEGACY; | 751 | bool baco_reset; |
| 752 | |||
| 753 | switch (adev->asic_type) { | ||
| 754 | case CHIP_FIJI: | ||
| 755 | case CHIP_TONGA: | ||
| 756 | case CHIP_POLARIS10: | ||
| 757 | case CHIP_POLARIS11: | ||
| 758 | case CHIP_POLARIS12: | ||
| 759 | case CHIP_TOPAZ: | ||
| 760 | smu7_asic_get_baco_capability(adev, &baco_reset); | ||
| 761 | break; | ||
| 762 | default: | ||
| 763 | baco_reset = false; | ||
| 764 | break; | ||
| 765 | } | ||
| 766 | |||
| 767 | if (baco_reset) | ||
| 768 | return AMD_RESET_METHOD_BACO; | ||
| 769 | else | ||
| 770 | return AMD_RESET_METHOD_LEGACY; | ||
| 771 | } | ||
| 772 | |||
| 773 | /** | ||
| 774 | * vi_asic_reset - soft reset GPU | ||
| 775 | * | ||
| 776 | * @adev: amdgpu_device pointer | ||
| 777 | * | ||
| 778 | * Look up which blocks are hung and attempt | ||
| 779 | * to reset them. | ||
| 780 | * Returns 0 for success. | ||
| 781 | */ | ||
| 782 | static int vi_asic_reset(struct amdgpu_device *adev) | ||
| 783 | { | ||
| 784 | int r; | ||
| 785 | |||
| 786 | if (vi_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) | ||
| 787 | r = smu7_asic_baco_reset(adev); | ||
| 788 | else | ||
| 789 | r = vi_asic_pci_config_reset(adev); | ||
| 790 | |||
| 791 | return r; | ||
| 718 | } | 792 | } |
| 719 | 793 | ||
| 720 | static u32 vi_get_config_memsize(struct amdgpu_device *adev) | 794 | static u32 vi_get_config_memsize(struct amdgpu_device *adev) |
| @@ -31,4 +31,7 @@ void vi_srbm_select(struct amdgpu_device *adev, · 30 unmodified lines | |||
| 31 | int vi_set_ip_blocks(struct amdgpu_device *adev); | 31 | int vi_set_ip_blocks(struct amdgpu_device *adev); |
| 32 | 32 | ||
| 33 | void legacy_doorbell_index_init(struct amdgpu_device *adev); | 33 | void legacy_doorbell_index_init(struct amdgpu_device *adev); |
| 34 | int smu7_asic_get_baco_capability(struct amdgpu_device *adev, bool *cap); | ||
| 35 | int smu7_asic_baco_reset(struct amdgpu_device *adev); | ||
| 36 | |||
| 34 | #endif | 37 | #endif |
| @@ -3396,7 +3396,8 @@ static void fill_stream_properties_from_drm_display_mode( · 3395 unmodified lines | |||
| 3396 | struct dc_crtc_timing *timing_out = &stream->timing; | 3396 | struct dc_crtc_timing *timing_out = &stream->timing; |
| 3397 | const struct drm_display_info *info = &connector->display_info; | 3397 | const struct drm_display_info *info = &connector->display_info; |
| 3398 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | 3398 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); |
| 3399 | memset(timing_out, 0, sizeof(struct dc_crtc_timing)); | 3399 | struct hdmi_vendor_infoframe hv_frame; |
| 3400 | struct hdmi_avi_infoframe avi_frame; | ||
| 3400 | 3401 | ||
| 3401 | timing_out->h_border_left = 0; | 3402 | timing_out->h_border_left = 0; |
| 3402 | timing_out->h_border_right = 0; | 3403 | timing_out->h_border_right = 0; |
| @@ -3433,6 +3434,13 @@ static void fill_stream_properties_from_drm_display_mode( · 30 unmodified lines | |||
| 3433 | timing_out->flags.VSYNC_POSITIVE_POLARITY = 1; | 3434 | timing_out->flags.VSYNC_POSITIVE_POLARITY = 1; |
| 3434 | } | 3435 | } |
| 3435 | 3436 | ||
| 3437 | if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) { | ||
| 3438 | drm_hdmi_avi_infoframe_from_display_mode(&avi_frame, (struct drm_connector *)connector, mode_in); | ||
| 3439 | timing_out->vic = avi_frame.video_code; | ||
| 3440 | drm_hdmi_vendor_infoframe_from_display_mode(&hv_frame, (struct drm_connector *)connector, mode_in); | ||
| 3441 | timing_out->hdmi_vic = hv_frame.vic; | ||
| 3442 | } | ||
| 3443 | |||
| 3436 | timing_out->h_addressable = mode_in->crtc_hdisplay; | 3444 | timing_out->h_addressable = mode_in->crtc_hdisplay; |
| 3437 | timing_out->h_total = mode_in->crtc_htotal; | 3445 | timing_out->h_total = mode_in->crtc_htotal; |
| 3438 | timing_out->h_sync_width = | 3446 | timing_out->h_sync_width = |
| @@ -3653,6 +3661,9 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, · 214 unmodified lines | |||
| 3653 | 3661 | ||
| 3654 | stream->dm_stream_context = aconnector; | 3662 | stream->dm_stream_context = aconnector; |
| 3655 | 3663 | ||
| 3664 | stream->timing.flags.LTE_340MCSC_SCRAMBLE = | ||
| 3665 | drm_connector->display_info.hdmi.scdc.scrambling.low_rates; | ||
| 3666 | |||
| 3656 | list_for_each_entry(preferred_mode, &aconnector->base.modes, head) { | 3667 | list_for_each_entry(preferred_mode, &aconnector->base.modes, head) { |
| 3657 | /* Search for preferred mode */ | 3668 | /* Search for preferred mode */ |
| 3658 | if (preferred_mode->type & DRM_MODE_TYPE_PREFERRED) { | 3669 | if (preferred_mode->type & DRM_MODE_TYPE_PREFERRED) { |
| @@ -3727,6 +3738,9 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, · 68 unmodified lines | |||
| 3727 | 3738 | ||
| 3728 | update_stream_signal(stream, sink); | 3739 | update_stream_signal(stream, sink); |
| 3729 | 3740 | ||
| 3741 | if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) | ||
| 3742 | mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket, false, false); | ||
| 3743 | |||
| 3730 | finish: | 3744 | finish: |
| 3731 | dc_sink_release(sink); | 3745 | dc_sink_release(sink); |
| 3732 | 3746 | ||
| @@ -122,11 +122,16 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, · 121 unmodified lines | |||
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | /* Configure dithering */ | 124 | /* Configure dithering */ |
| 125 | if (!dm_need_crc_dither(source)) | 125 | if (!dm_need_crc_dither(source)) { |
| 126 | dc_stream_set_dither_option(stream_state, DITHER_OPTION_TRUN8); | 126 | dc_stream_set_dither_option(stream_state, DITHER_OPTION_TRUN8); |
| 127 | else | 127 | dc_stream_set_dyn_expansion(stream_state->ctx->dc, stream_state, |
| 128 | DYN_EXPANSION_DISABLE); | ||
| 129 | } else { | ||
| 128 | dc_stream_set_dither_option(stream_state, | 130 | dc_stream_set_dither_option(stream_state, |
| 129 | DITHER_OPTION_DEFAULT); | 131 | DITHER_OPTION_DEFAULT); |
| 132 | dc_stream_set_dyn_expansion(stream_state->ctx->dc, stream_state, | ||
| 133 | DYN_EXPANSION_AUTO); | ||
| 134 | } | ||
| 130 | 135 | ||
| 131 | unlock: | 136 | unlock: |
| 132 | mutex_unlock(&adev->dm.dc_lock); | 137 | mutex_unlock(&adev->dm.dc_lock); |
| @@ -589,10 +589,9 @@ void pp_rv_set_wm_ranges(struct pp_smu *pp, · 588 unmodified lines | |||
| 589 | if (pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges) | 589 | if (pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges) |
| 590 | pp_funcs->set_watermarks_for_clocks_ranges(pp_handle, | 590 | pp_funcs->set_watermarks_for_clocks_ranges(pp_handle, |
| 591 | &wm_with_clock_ranges); | 591 | &wm_with_clock_ranges); |
| 592 | else if (adev->smu.funcs && | 592 | else |
| 593 | adev->smu.funcs->set_watermarks_for_clock_ranges) | ||
| 594 | smu_set_watermarks_for_clock_ranges(&adev->smu, | 593 | smu_set_watermarks_for_clock_ranges(&adev->smu, |
| 595 | &wm_with_clock_ranges); | 594 | &wm_with_clock_ranges); |
| 596 | } | 595 | } |
| 597 | 596 | ||
| 598 | void pp_rv_set_pme_wa_enable(struct pp_smu *pp) | 597 | void pp_rv_set_pme_wa_enable(struct pp_smu *pp) |
| @@ -665,7 +664,6 @@ enum pp_smu_status pp_nv_set_wm_ranges(struct pp_smu *pp, · 66 unmodified lines | |||
| 665 | { | 664 | { |
| 666 | const struct dc_context *ctx = pp->dm; | 665 | const struct dc_context *ctx = pp->dm; |
| 667 | struct amdgpu_device *adev = ctx->driver_context; | 666 | struct amdgpu_device *adev = ctx->driver_context; |
| 668 | struct smu_context *smu = &adev->smu; | ||
| 669 | struct dm_pp_wm_sets_with_clock_ranges_soc15 wm_with_clock_ranges; | 667 | struct dm_pp_wm_sets_with_clock_ranges_soc15 wm_with_clock_ranges; |
| 670 | struct dm_pp_clock_range_for_dmif_wm_set_soc15 *wm_dce_clocks = | 668 | struct dm_pp_clock_range_for_dmif_wm_set_soc15 *wm_dce_clocks = |
| 671 | wm_with_clock_ranges.wm_dmif_clocks_ranges; | 669 | wm_with_clock_ranges.wm_dmif_clocks_ranges; |
| @@ -708,15 +706,7 @@ enum pp_smu_status pp_nv_set_wm_ranges(struct pp_smu *pp, · 36 unmodified lines | |||
| 708 | ranges->writer_wm_sets[i].min_drain_clk_mhz * 1000; | 706 | ranges->writer_wm_sets[i].min_drain_clk_mhz * 1000; |
| 709 | } | 707 | } |
| 710 | 708 | ||
| 711 | if (!smu->funcs) | 709 | smu_set_watermarks_for_clock_ranges(&adev->smu, &wm_with_clock_ranges); |
| 712 | return PP_SMU_RESULT_UNSUPPORTED; | ||
| 713 | |||
| 714 | /* 0: successful or smu.funcs->set_watermarks_for_clock_ranges = NULL; | ||
| 715 | * 1: fail | ||
| 716 | */ | ||
| 717 | if (smu_set_watermarks_for_clock_ranges(&adev->smu, | ||
| 718 | &wm_with_clock_ranges)) | ||
| 719 | return PP_SMU_RESULT_UNSUPPORTED; | ||
| 720 | 710 | ||
| 721 | return PP_SMU_RESULT_OK; | 711 | return PP_SMU_RESULT_OK; |
| 722 | } | 712 | } |
| @@ -901,6 +891,90 @@ enum pp_smu_status pp_nv_get_uclk_dpm_states(struct pp_smu *pp, · 178 unmodified lines | |||
| 901 | return PP_SMU_RESULT_FAIL; | 891 | return PP_SMU_RESULT_FAIL; |
| 902 | } | 892 | } |
| 903 | 893 | ||
| 894 | #ifdef CONFIG_DRM_AMD_DC_DCN2_1 | ||
| 895 | enum pp_smu_status pp_rn_get_dpm_clock_table( | ||
| 896 | struct pp_smu *pp, struct dpm_clocks *clock_table) | ||
| 897 | { | ||
| 898 | const struct dc_context *ctx = pp->dm; | ||
| 899 | struct amdgpu_device *adev = ctx->driver_context; | ||
| 900 | struct smu_context *smu = &adev->smu; | ||
| 901 | |||
| 902 | if (!smu->ppt_funcs) | ||
| 903 | return PP_SMU_RESULT_UNSUPPORTED; | ||
| 904 | |||
| 905 | if (!smu->ppt_funcs->get_dpm_clock_table) | ||
| 906 | return PP_SMU_RESULT_UNSUPPORTED; | ||
| 907 | |||
| 908 | if (!smu->ppt_funcs->get_dpm_clock_table(smu, clock_table)) | ||
| 909 | return PP_SMU_RESULT_OK; | ||
| 910 | |||
| 911 | return PP_SMU_RESULT_FAIL; | ||
| 912 | } | ||
| 913 | |||
| 914 | enum pp_smu_status pp_rn_set_wm_ranges(struct pp_smu *pp, | ||
| 915 | struct pp_smu_wm_range_sets *ranges) | ||
| 916 | { | ||
| 917 | const struct dc_context *ctx = pp->dm; | ||
| 918 | struct amdgpu_device *adev = ctx->driver_context; | ||
| 919 | struct smu_context *smu = &adev->smu; | ||
| 920 | struct dm_pp_wm_sets_with_clock_ranges_soc15 wm_with_clock_ranges; | ||
| 921 | struct dm_pp_clock_range_for_dmif_wm_set_soc15 *wm_dce_clocks = | ||
| 922 | wm_with_clock_ranges.wm_dmif_clocks_ranges; | ||
| 923 | struct dm_pp_clock_range_for_mcif_wm_set_soc15 *wm_soc_clocks = | ||
| 924 | wm_with_clock_ranges.wm_mcif_clocks_ranges; | ||
| 925 | int32_t i; | ||
| 926 | |||
| 927 | if (!smu->funcs) | ||
| 928 | return PP_SMU_RESULT_UNSUPPORTED; | ||
| 929 | |||
| 930 | wm_with_clock_ranges.num_wm_dmif_sets = ranges->num_reader_wm_sets; | ||
| 931 | wm_with_clock_ranges.num_wm_mcif_sets = ranges->num_writer_wm_sets; | ||
| 932 | |||
| 933 | for (i = 0; i < wm_with_clock_ranges.num_wm_dmif_sets; i++) { | ||
| 934 | if (ranges->reader_wm_sets[i].wm_inst > 3) | ||
| 935 | wm_dce_clocks[i].wm_set_id = WM_SET_A; | ||
| 936 | else | ||
| 937 | wm_dce_clocks[i].wm_set_id = | ||
| 938 | ranges->reader_wm_sets[i].wm_inst; | ||
| 939 | |||
| 940 | wm_dce_clocks[i].wm_min_dcfclk_clk_in_khz = | ||
| 941 | ranges->reader_wm_sets[i].min_drain_clk_mhz; | ||
| 942 | |||
| 943 | wm_dce_clocks[i].wm_max_dcfclk_clk_in_khz = | ||
| 944 | ranges->reader_wm_sets[i].max_drain_clk_mhz; | ||
| 945 | |||
| 946 | wm_dce_clocks[i].wm_min_mem_clk_in_khz = | ||
| 947 | ranges->reader_wm_sets[i].min_fill_clk_mhz; | ||
| 948 | |||
| 949 | wm_dce_clocks[i].wm_max_mem_clk_in_khz = | ||
| 950 | ranges->reader_wm_sets[i].max_fill_clk_mhz; | ||
| 951 | } | ||
| 952 | |||
| 953 | for (i = 0; i < wm_with_clock_ranges.num_wm_mcif_sets; i++) { | ||
| 954 | if (ranges->writer_wm_sets[i].wm_inst > 3) | ||
| 955 | wm_soc_clocks[i].wm_set_id = WM_SET_A; | ||
| 956 | else | ||
| 957 | wm_soc_clocks[i].wm_set_id = | ||
| 958 | ranges->writer_wm_sets[i].wm_inst; | ||
| 959 | wm_soc_clocks[i].wm_min_socclk_clk_in_khz = | ||
| 960 | ranges->writer_wm_sets[i].min_fill_clk_mhz; | ||
| 961 | |||
| 962 | wm_soc_clocks[i].wm_max_socclk_clk_in_khz = | ||
| 963 | ranges->writer_wm_sets[i].max_fill_clk_mhz; | ||
| 964 | |||
| 965 | wm_soc_clocks[i].wm_min_mem_clk_in_khz = | ||
| 966 | ranges->writer_wm_sets[i].min_drain_clk_mhz; | ||
| 967 | |||
| 968 | wm_soc_clocks[i].wm_max_mem_clk_in_khz = | ||
| 969 | ranges->writer_wm_sets[i].max_drain_clk_mhz; | ||
| 970 | } | ||
| 971 | |||
| 972 | smu_set_watermarks_for_clock_ranges(&adev->smu, &wm_with_clock_ranges); | ||
| 973 | |||
| 974 | return PP_SMU_RESULT_OK; | ||
| 975 | } | ||
| 976 | #endif | ||
| 977 | |||
| 904 | void dm_pp_get_funcs( | 978 | void dm_pp_get_funcs( |
| 905 | struct dc_context *ctx, | 979 | struct dc_context *ctx, |
| 906 | struct pp_smu_funcs *funcs) | 980 | struct pp_smu_funcs *funcs) |
| @@ -945,6 +1019,15 @@ void dm_pp_get_funcs( · 38 unmodified lines | |||
| 945 | funcs->nv_funcs.set_pstate_handshake_support = pp_nv_set_pstate_handshake_support; | 1019 | funcs->nv_funcs.set_pstate_handshake_support = pp_nv_set_pstate_handshake_support; |
| 946 | break; | 1020 | break; |
| 947 | #endif | 1021 | #endif |
| 1022 | |||
| 1023 | #ifdef CONFIG_DRM_AMD_DC_DCN2_1 | ||
| 1024 | case DCN_VERSION_2_1: | ||
| 1025 | funcs->ctx.ver = PP_SMU_VER_RN; | ||
| 1026 | funcs->rn_funcs.pp_smu.dm = ctx; | ||
| 1027 | funcs->rn_funcs.set_wm_ranges = pp_rn_set_wm_ranges; | ||
| 1028 | funcs->rn_funcs.get_dpm_clock_table = pp_rn_get_dpm_clock_table; | ||
| 1029 | break; | ||
| 1030 | #endif | ||
| 948 | default: | 1031 | default: |
| 949 | DRM_ERROR("smu version is not supported !\n"); | 1032 | DRM_ERROR("smu version is not supported !\n"); |
| 950 | break; | 1033 | break; |
| @@ -2543,7 +2543,6 @@ static enum bp_result construct_integrated_info( · 2542 unmodified lines | |||
| 2543 | 2543 | ||
| 2544 | /* Sort voltage table from low to high*/ | 2544 | /* Sort voltage table from low to high*/ |
| 2545 | if (result == BP_RESULT_OK) { | 2545 | if (result == BP_RESULT_OK) { |
| 2546 | struct clock_voltage_caps temp = {0, 0}; | ||
| 2547 | uint32_t i; | 2546 | uint32_t i; |
| 2548 | uint32_t j; | 2547 | uint32_t j; |
| 2549 | 2548 | ||
| @@ -2553,10 +2552,8 @@ static enum bp_result construct_integrated_info( · 3 unmodified lines | |||
| 2553 | info->disp_clk_voltage[j].max_supported_clk < | 2552 | info->disp_clk_voltage[j].max_supported_clk < |
| 2554 | info->disp_clk_voltage[j-1].max_supported_clk) { | 2553 | info->disp_clk_voltage[j-1].max_supported_clk) { |
| 2555 | /* swap j and j - 1*/ | 2554 | /* swap j and j - 1*/ |
| 2556 | temp = info->disp_clk_voltage[j-1]; | 2555 | swap(info->disp_clk_voltage[j - 1], |
| 2557 | info->disp_clk_voltage[j-1] = | 2556 | info->disp_clk_voltage[j]); |
| 2558 | info->disp_clk_voltage[j]; | ||
| 2559 | info->disp_clk_voltage[j] = temp; | ||
| 2560 | } | 2557 | } |
| 2561 | } | 2558 | } |
| 2562 | } | 2559 | } |
| @@ -1613,8 +1613,6 @@ static enum bp_result construct_integrated_info( · 1612 unmodified lines | |||
| 1613 | 1613 | ||
| 1614 | struct atom_common_table_header *header; | 1614 | struct atom_common_table_header *header; |
| 1615 | struct atom_data_revision revision; | 1615 | struct atom_data_revision revision; |
| 1616 | |||
| 1617 | struct clock_voltage_caps temp = {0, 0}; | ||
| 1618 | uint32_t i; | 1616 | uint32_t i; |
| 1619 | uint32_t j; | 1617 | uint32_t j; |
| 1620 | 1618 | ||
| @@ -1644,10 +1642,8 @@ static enum bp_result construct_integrated_info( · 23 unmodified lines | |||
| 1644 | info->disp_clk_voltage[j-1].max_supported_clk | 1642 | info->disp_clk_voltage[j-1].max_supported_clk |
| 1645 | ) { | 1643 | ) { |
| 1646 | /* swap j and j - 1*/ | 1644 | /* swap j and j - 1*/ |
| 1647 | temp = info->disp_clk_voltage[j-1]; | 1645 | swap(info->disp_clk_voltage[j - 1], |
| 1648 | info->disp_clk_voltage[j-1] = | 1646 | info->disp_clk_voltage[j]); |
| 1649 | info->disp_clk_voltage[j]; | ||
| 1650 | info->disp_clk_voltage[j] = temp; | ||
| 1651 | } | 1647 | } |
| 1652 | } | 1648 | } |
| 1653 | } | 1649 | } |
| @@ -65,6 +65,31 @@ int clk_mgr_helper_get_active_display_cnt( · 64 unmodified lines | |||
| 65 | return display_count; | 65 | return display_count; |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr) | ||
| 69 | { | ||
| 70 | struct dc_link *edp_link = get_edp_link(dc); | ||
| 71 | |||
| 72 | if (dc->hwss.exit_optimized_pwr_state) | ||
| 73 | dc->hwss.exit_optimized_pwr_state(dc, dc->current_state); | ||
| 74 | |||
| 75 | if (edp_link) { | ||
| 76 | clk_mgr->psr_allow_active_cache = edp_link->psr_allow_active; | ||
| 77 | dc_link_set_psr_allow_active(edp_link, false, false); | ||
| 78 | } | ||
| 79 | |||
| 80 | } | ||
| 81 | |||
| 82 | void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr) | ||
| 83 | { | ||
| 84 | struct dc_link *edp_link = get_edp_link(dc); | ||
| 85 | |||
| 86 | if (edp_link) | ||
| 87 | dc_link_set_psr_allow_active(edp_link, clk_mgr->psr_allow_active_cache, false); | ||
| 88 | |||
| 89 | if (dc->hwss.optimize_pwr_state) | ||
| 90 | dc->hwss.optimize_pwr_state(dc, dc->current_state); | ||
| 91 | |||
| 92 | } | ||
| 68 | 93 | ||
| 69 | struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *pp_smu, struct dccg *dccg) | 94 | struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *pp_smu, struct dccg *dccg) |
| 70 | { | 95 | { |
| @@ -349,12 +349,36 @@ void dcn2_get_clock(struct clk_mgr *clk_mgr, · 348 unmodified lines | |||
| 349 | } | 349 | } |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | static bool dcn2_are_clock_states_equal(struct dc_clocks *a, | ||
| 353 | struct dc_clocks *b) | ||
| 354 | { | ||
| 355 | if (a->dispclk_khz != b->dispclk_khz) | ||
| 356 | return false; | ||
| 357 | else if (a->dppclk_khz != b->dppclk_khz) | ||
| 358 | return false; | ||
| 359 | else if (a->dcfclk_khz != b->dcfclk_khz) | ||
| 360 | return false; | ||
| 361 | else if (a->socclk_khz != b->socclk_khz) | ||
| 362 | return false; | ||
| 363 | else if (a->dcfclk_deep_sleep_khz != b->dcfclk_deep_sleep_khz) | ||
| 364 | return false; | ||
| 365 | else if (a->phyclk_khz != b->phyclk_khz) | ||
| 366 | return false; | ||
| 367 | else if (a->dramclk_khz != b->dramclk_khz) | ||
| 368 | return false; | ||
| 369 | else if (a->p_state_change_support != b->p_state_change_support) | ||
| 370 | return false; | ||
| 371 | |||
| 372 | return true; | ||
| 373 | } | ||
| 374 | |||
| 352 | static struct clk_mgr_funcs dcn2_funcs = { | 375 | static struct clk_mgr_funcs dcn2_funcs = { |
| 353 | .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, | 376 | .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, |
| 354 | .update_clocks = dcn2_update_clocks, | 377 | .update_clocks = dcn2_update_clocks, |
| 355 | .init_clocks = dcn2_init_clocks, | 378 | .init_clocks = dcn2_init_clocks, |
| 356 | .enable_pme_wa = dcn2_enable_pme_wa, | 379 | .enable_pme_wa = dcn2_enable_pme_wa, |
| 357 | .get_clock = dcn2_get_clock, | 380 | .get_clock = dcn2_get_clock, |
| 381 | .are_clock_states_equal = dcn2_are_clock_states_equal, | ||
| 358 | }; | 382 | }; |
| 359 | 383 | ||
| 360 | 384 | ||
| @@ -50,4 +50,5 @@ void dcn2_get_clock(struct clk_mgr *clk_mgr, · 49 unmodified lines | |||
| 50 | enum dc_clock_type clock_type, | 50 | enum dc_clock_type clock_type, |
| 51 | struct dc_clock_config *clock_cfg); | 51 | struct dc_clock_config *clock_cfg); |
| 52 | 52 | ||
| 53 | void dcn20_update_clocks_update_dentist(struct clk_mgr_internal *clk_mgr); | ||
| 53 | #endif //__DCN20_CLK_MGR_H__ | 54 | #endif //__DCN20_CLK_MGR_H__ |
| @@ -52,6 +52,45 @@ · 51 unmodified lines | |||
| 52 | #define REG(reg_name) \ | 52 | #define REG(reg_name) \ |
| 53 | (CLK_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) | 53 | (CLK_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) |
| 54 | 54 | ||
| 55 | |||
| 56 | /* TODO: evaluate how to lower or disable all dcn clocks in screen off case */ | ||
| 57 | int rn_get_active_display_cnt_wa( | ||
| 58 | struct dc *dc, | ||
| 59 | struct dc_state *context) | ||
| 60 | { | ||
| 61 | int i, display_count; | ||
| 62 | bool hdmi_present = false; | ||
| 63 | |||
| 64 | display_count = 0; | ||
| 65 | for (i = 0; i < context->stream_count; i++) { | ||
| 66 | const struct dc_stream_state *stream = context->streams[i]; | ||
| 67 | |||
| 68 | if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) | ||
| 69 | hdmi_present = true; | ||
| 70 | } | ||
| 71 | |||
| 72 | for (i = 0; i < dc->link_count; i++) { | ||
| 73 | const struct dc_link *link = dc->links[i]; | ||
| 74 | |||
| 75 | /* | ||
| 76 | * Only notify active stream or virtual stream. | ||
| 77 | * Need to notify virtual stream to work around | ||
| 78 | * headless case. HPD does not fire when system is in | ||
| 79 | * S0i2. | ||
| 80 | */ | ||
| 81 | /* abusing the fact that the dig and phy are coupled to see if the phy is enabled */ | ||
| 82 | if (link->connector_signal == SIGNAL_TYPE_VIRTUAL || | ||
| 83 | link->link_enc->funcs->is_dig_enabled(link->link_enc)) | ||
| 84 | display_count++; | ||
| 85 | } | ||
| 86 | |||
| 87 | /* WA for hang on HDMI after display off back back on*/ | ||
| 88 | if (display_count == 0 && hdmi_present) | ||
| 89 | display_count = 1; | ||
| 90 | |||
| 91 | return display_count; | ||
| 92 | } | ||
| 93 | |||
| 55 | void rn_update_clocks(struct clk_mgr *clk_mgr_base, | 94 | void rn_update_clocks(struct clk_mgr *clk_mgr_base, |
| 56 | struct dc_state *context, | 95 | struct dc_state *context, |
| 57 | bool safe_to_lower) | 96 | bool safe_to_lower) |
| @@ -62,17 +101,36 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base, · 4 unmodified lines | |||
| 62 | int display_count; | 101 | int display_count; |
| 63 | bool update_dppclk = false; | 102 | bool update_dppclk = false; |
| 64 | bool update_dispclk = false; | 103 | bool update_dispclk = false; |
| 65 | bool enter_display_off = false; | ||
| 66 | bool dpp_clock_lowered = false; | 104 | bool dpp_clock_lowered = false; |
| 67 | struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu; | ||
| 68 | 105 | ||
| 69 | display_count = clk_mgr_helper_get_active_display_cnt(dc, context); | 106 | struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu; |
| 70 | 107 | ||
| 71 | if (display_count == 0) | 108 | if (dc->work_arounds.skip_clock_update) |
| 72 | enter_display_off = true; | 109 | return; |
| 73 | 110 | ||
| 74 | if (enter_display_off == safe_to_lower) { | 111 | /* |
| 75 | rn_vbios_smu_set_display_count(clk_mgr, display_count); | 112 | * if it is safe to lower, but we are already in the lower state, we don't have to do anything |
| 113 | * also if safe to lower is false, we just go in the higher state | ||
| 114 | */ | ||
| 115 | if (safe_to_lower) { | ||
| 116 | /* check that we're not already in lower */ | ||
| 117 | if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_OPTIMIZED) { | ||
| 118 | |||
| 119 | display_count = rn_get_active_display_cnt_wa(dc, context); | ||
| 120 | /* if we can go lower, go lower */ | ||
| 121 | if (display_count == 0) { | ||
| 122 | rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_OPTIMIZED); | ||
| 123 | /* update power state */ | ||
| 124 | clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_OPTIMIZED; | ||
| 125 | } | ||
| 126 | } | ||
| 127 | } else { | ||
| 128 | /* check that we're not already in the normal state */ | ||
| 129 | if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_NORMAL) { | ||
| 130 | rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_NORMAL); | ||
| 131 | /* update power state */ | ||
| 132 | clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_NORMAL; | ||
| 133 | } | ||
| 76 | } | 134 | } |
| 77 | 135 | ||
| 78 | if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, clk_mgr_base->clks.phyclk_khz)) { | 136 | if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, clk_mgr_base->clks.phyclk_khz)) { |
| @@ -319,7 +377,7 @@ void rn_get_clk_states(struct clk_mgr *clk_mgr_base, struct clk_states *s) · 240 unmodified lines | |||
| 319 | 377 | ||
| 320 | rn_dump_clk_registers(&sb, clk_mgr_base, &log_info); | 378 | rn_dump_clk_registers(&sb, clk_mgr_base, &log_info); |
| 321 | 379 | ||
| 322 | s->dprefclk_khz = sb.dprefclk; | 380 | s->dprefclk_khz = sb.dprefclk * 1000; |
| 323 | } | 381 | } |
| 324 | 382 | ||
| 325 | void rn_enable_pme_wa(struct clk_mgr *clk_mgr_base) | 383 | void rn_enable_pme_wa(struct clk_mgr *clk_mgr_base) |
| @@ -329,10 +387,19 @@ void rn_enable_pme_wa(struct clk_mgr *clk_mgr_base) · 3 unmodified lines | |||
| 329 | rn_vbios_smu_enable_pme_wa(clk_mgr); | 387 | rn_vbios_smu_enable_pme_wa(clk_mgr); |
| 330 | } | 388 | } |
| 331 | 389 | ||
| 390 | void rn_init_clocks(struct clk_mgr *clk_mgr) | ||
| 391 | { | ||
| 392 | memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks)); | ||
| 393 | // Assumption is that boot state always supports pstate | ||
| 394 | clk_mgr->clks.p_state_change_support = true; | ||
| 395 | clk_mgr->clks.prev_p_state_change_support = true; | ||
| 396 | clk_mgr->clks.pwr_state = DCN_PWR_STATE_NORMAL; | ||
| 397 | } | ||
| 398 | |||
| 332 | static struct clk_mgr_funcs dcn21_funcs = { | 399 | static struct clk_mgr_funcs dcn21_funcs = { |
| 333 | .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, | 400 | .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, |
| 334 | .update_clocks = rn_update_clocks, | 401 | .update_clocks = rn_update_clocks, |
| 335 | .init_clocks = dcn2_init_clocks, | 402 | .init_clocks = rn_init_clocks, |
| 336 | .enable_pme_wa = rn_enable_pme_wa, | 403 | .enable_pme_wa = rn_enable_pme_wa, |
| 337 | /* .dump_clk_registers = rn_dump_clk_registers */ | 404 | /* .dump_clk_registers = rn_dump_clk_registers */ |
| 338 | }; | 405 | }; |
| @@ -405,7 +472,7 @@ struct clk_bw_params rn_bw_params = { · 66 unmodified lines | |||
| 405 | } | 472 | } |
| 406 | }; | 473 | }; |
| 407 | 474 | ||
| 408 | void build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_smu_wm_range_sets *ranges) | 475 | void rn_build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_smu_wm_range_sets *ranges) |
| 409 | { | 476 | { |
| 410 | int i, num_valid_sets; | 477 | int i, num_valid_sets; |
| 411 | 478 | ||
| @@ -462,23 +529,50 @@ void build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_smu_wm_ra · 50 unmodified lines | |||
| 462 | 529 | ||
| 463 | } | 530 | } |
| 464 | 531 | ||
| 465 | void clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params, struct dpm_clocks *clock_table, struct hw_asic_id *asic_id) | 532 | static unsigned int find_dcfclk_for_voltage(struct dpm_clocks *clock_table, unsigned int voltage) |
| 466 | { | 533 | { |
| 467 | int i; | 534 | int i; |
| 468 | 535 | ||
| 536 | for (i = 0; i < PP_SMU_NUM_DCFCLK_DPM_LEVELS; i++) { | ||
| 537 | if (clock_table->DcfClocks[i].Vol == voltage) | ||
| 538 | return clock_table->DcfClocks[i].Freq; | ||
| 539 | } | ||
| 540 | |||
| 541 | ASSERT(0); | ||
| 542 | return 0; | ||
| 543 | } | ||
| 544 | |||
| 545 | void rn_clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params, struct dpm_clocks *clock_table, struct hw_asic_id *asic_id) | ||
| 546 | { | ||
| 547 | int i, j = 0; | ||
| 548 | |||
| 549 | j = -1; | ||
| 550 | |||
| 469 | ASSERT(PP_SMU_NUM_FCLK_DPM_LEVELS <= MAX_NUM_DPM_LVL); | 551 | ASSERT(PP_SMU_NUM_FCLK_DPM_LEVELS <= MAX_NUM_DPM_LVL); |
| 470 | 552 | ||
| 471 | for (i = 0; i < PP_SMU_NUM_FCLK_DPM_LEVELS; i++) { | 553 | /* Find lowest DPM, FCLK is filled in reverse order*/ |
| 472 | if (clock_table->FClocks[i].Freq == 0) | 554 | |
| 555 | for (i = PP_SMU_NUM_FCLK_DPM_LEVELS - 1; i >= 0; i--) { | ||
| 556 | if (clock_table->FClocks[i].Freq != 0) { | ||
| 557 | j = i; | ||
| 473 | break; | 558 | break; |
| 559 | } | ||
| 560 | } | ||
| 561 | |||
| 562 | if (j == -1) { | ||
| 563 | /* clock table is all 0s, just use our own hardcode */ | ||
| 564 | ASSERT(0); | ||
| 565 | return; | ||
| 566 | } | ||
| 567 | |||
| 568 | bw_params->clk_table.num_entries = j + 1; | ||
| 474 | 569 | ||
| 475 | bw_params->clk_table.entries[i].dcfclk_mhz = clock_table->DcfClocks[i].Freq; | 570 | for (i = 0; i < bw_params->clk_table.num_entries; i++, j--) { |
| 476 | bw_params->clk_table.entries[i].fclk_mhz = clock_table->FClocks[i].Freq; | 571 | bw_params->clk_table.entries[i].fclk_mhz = clock_table->FClocks[j].Freq; |
| 477 | bw_params->clk_table.entries[i].memclk_mhz = clock_table->MemClocks[i].Freq; | 572 | bw_params->clk_table.entries[i].memclk_mhz = clock_table->MemClocks[j].Freq; |
| 478 | bw_params->clk_table.entries[i].socclk_mhz = clock_table->SocClocks[i].Freq; | 573 | bw_params->clk_table.entries[i].voltage = clock_table->FClocks[j].Vol; |
| 479 | bw_params->clk_table.entries[i].voltage = clock_table->FClocks[i].Vol; | 574 | bw_params->clk_table.entries[i].dcfclk_mhz = find_dcfclk_for_voltage(clock_table, clock_table->FClocks[j].Vol); |
| 480 | } | 575 | } |
| 481 | bw_params->clk_table.num_entries = i; | ||
| 482 | 576 | ||
| 483 | bw_params->vram_type = asic_id->vram_type; | 577 | bw_params->vram_type = asic_id->vram_type; |
| 484 | bw_params->num_channels = asic_id->vram_width / DDR4_DRAM_WIDTH; | 578 | bw_params->num_channels = asic_id->vram_width / DDR4_DRAM_WIDTH; |
| @@ -486,7 +580,7 @@ void clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params, struct d · 1 unmodified line | |||
| 486 | for (i = 0; i < WM_SET_COUNT; i++) { | 580 | for (i = 0; i < WM_SET_COUNT; i++) { |
| 487 | bw_params->wm_table.entries[i].wm_inst = i; | 581 | bw_params->wm_table.entries[i].wm_inst = i; |
| 488 | 582 | ||
| 489 | if (clock_table->FClocks[i].Freq == 0) { | 583 | if (i >= bw_params->clk_table.num_entries) { |
| 490 | bw_params->wm_table.entries[i].valid = false; | 584 | bw_params->wm_table.entries[i].valid = false; |
| 491 | continue; | 585 | continue; |
| 492 | } | 586 | } |
| @@ -547,25 +641,24 @@ void rn_clk_mgr_construct( · 54 unmodified lines | |||
| 547 | clk_mgr->dentist_vco_freq_khz = 3600000; | 641 | clk_mgr->dentist_vco_freq_khz = 3600000; |
| 548 | 642 | ||
| 549 | rn_dump_clk_registers(&s, &clk_mgr->base, &log_info); | 643 | rn_dump_clk_registers(&s, &clk_mgr->base, &log_info); |
| 550 | clk_mgr->base.dprefclk_khz = s.dprefclk; | 644 | /* Convert dprefclk units from MHz to KHz */ |
| 551 | 645 | /* Value already divided by 10, some resolution lost */ | |
| 552 | if (clk_mgr->base.dprefclk_khz != 600000) { | 646 | clk_mgr->base.dprefclk_khz = s.dprefclk * 1000; |
| 553 | clk_mgr->base.dprefclk_khz = 600000; | ||
| 554 | ASSERT(1); //TODO: Renoir follow up. | ||
| 555 | } | ||
| 556 | 647 | ||
| 557 | /* in case we don't get a value from the register, use default */ | 648 | /* in case we don't get a value from the register, use default */ |
| 558 | if (clk_mgr->base.dprefclk_khz == 0) | 649 | if (clk_mgr->base.dprefclk_khz == 0) { |
| 650 | ASSERT(clk_mgr->base.dprefclk_khz == 600000); | ||
| 559 | clk_mgr->base.dprefclk_khz = 600000; | 651 | clk_mgr->base.dprefclk_khz = 600000; |
| 652 | } | ||
| 560 | } | 653 | } |
| 561 | 654 | ||
| 562 | dce_clock_read_ss_info(clk_mgr); | 655 | dce_clock_read_ss_info(clk_mgr); |
| 563 | 656 | ||
| 564 | clk_mgr->base.bw_params = &rn_bw_params; | 657 | clk_mgr->base.bw_params = &rn_bw_params; |
| 565 | 658 | ||
| 566 | if (pp_smu) { | 659 | if (pp_smu && pp_smu->rn_funcs.get_dpm_clock_table) { |
| 567 | pp_smu->rn_funcs.get_dpm_clock_table(&pp_smu->rn_funcs.pp_smu, &clock_table); | 660 | pp_smu->rn_funcs.get_dpm_clock_table(&pp_smu->rn_funcs.pp_smu, &clock_table); |
| 568 | clk_mgr_helper_populate_bw_params(clk_mgr->base.bw_params, &clock_table, &ctx->asic_id); | 661 | rn_clk_mgr_helper_populate_bw_params(clk_mgr->base.bw_params, &clock_table, &ctx->asic_id); |
| 569 | } | 662 | } |
| 570 | 663 | ||
| 571 | /* | 664 | /* |
| @@ -576,15 +669,16 @@ void rn_clk_mgr_construct( · 4 unmodified lines | |||
| 576 | if (!debug->disable_pplib_wm_range) { | 669 | if (!debug->disable_pplib_wm_range) { |
| 577 | struct pp_smu_wm_range_sets ranges = {0}; | 670 | struct pp_smu_wm_range_sets ranges = {0}; |
| 578 | 671 | ||
| 579 | build_watermark_ranges(clk_mgr->base.bw_params, &ranges); | 672 | rn_build_watermark_ranges(clk_mgr->base.bw_params, &ranges); |
| 580 | 673 | ||
| 581 | /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */ | 674 | /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */ |
| 582 | if (pp_smu && pp_smu->rn_funcs.set_wm_ranges) | 675 | if (pp_smu && pp_smu->rn_funcs.set_wm_ranges) |
| 583 | pp_smu->rn_funcs.set_wm_ranges(&pp_smu->rn_funcs.pp_smu, &ranges); | 676 | pp_smu->rn_funcs.set_wm_ranges(&pp_smu->rn_funcs.pp_smu, &ranges); |
| 584 | } | 677 | } |
| 585 | 678 | ||
| 586 | /* enable powerfeatures when displaycount goes to 0 */ | 679 | if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment) && clk_mgr->smu_ver >= 0x00371500) { |
| 587 | if (!debug->disable_48mhz_pwrdwn) | 680 | /* enable powerfeatures when displaycount goes to 0 */ |
| 588 | rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(clk_mgr); | 681 | rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(clk_mgr, !debug->disable_48mhz_pwrdwn); |
| 682 | } | ||
| 589 | } | 683 | } |
| 590 | 684 | ||
| @@ -26,11 +26,20 @@ · 25 unmodified lines | |||
| 26 | #ifndef __RN_CLK_MGR_H__ | 26 | #ifndef __RN_CLK_MGR_H__ |
| 27 | #define __RN_CLK_MGR_H__ | 27 | #define __RN_CLK_MGR_H__ |
| 28 | 28 | ||
| 29 | #include "clk_mgr.h" | ||
| 30 | #include "dm_pp_smu.h" | ||
| 31 | |||
| 29 | struct rn_clk_registers { | 32 | struct rn_clk_registers { |
| 30 | uint32_t CLK1_CLK0_CURRENT_CNT; /* DPREFCLK */ | 33 | uint32_t CLK1_CLK0_CURRENT_CNT; /* DPREFCLK */ |
| 31 | }; | 34 | }; |
| 32 | 35 | ||
| 33 | 36 | void rn_build_watermark_ranges( | |
| 37 | struct clk_bw_params *bw_params, | ||
| 38 | struct pp_smu_wm_range_sets *ranges); | ||
| 39 | void rn_clk_mgr_helper_populate_bw_params( | ||
| 40 | struct clk_bw_params *bw_params, | ||
| 41 | struct dpm_clocks *clock_table, | ||
| 42 | struct hw_asic_id *asic_id); | ||
| 34 | void rn_clk_mgr_construct(struct dc_context *ctx, | 43 | void rn_clk_mgr_construct(struct dc_context *ctx, |
| 35 | struct clk_mgr_internal *clk_mgr, | 44 | struct clk_mgr_internal *clk_mgr, |
| 36 | struct pp_smu_funcs *pp_smu, | 45 | struct pp_smu_funcs *pp_smu, |
| @@ -33,7 +33,7 @@ · 32 unmodified lines | |||
| 33 | #include "mp/mp_12_0_0_sh_mask.h" | 33 | #include "mp/mp_12_0_0_sh_mask.h" |
| 34 | 34 | ||
| 35 | #define REG(reg_name) \ | 35 | #define REG(reg_name) \ |
| 36 | (MP1_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) | 36 | (MP0_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) |
| 37 | 37 | ||
| 38 | #define FN(reg_name, field) \ | 38 | #define FN(reg_name, field) \ |
| 39 | FD(reg_name##__##field) | 39 | FD(reg_name##__##field) |
| @@ -84,16 +84,12 @@ int rn_vbios_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dis · 44 unmodified lines | |||
| 84 | int actual_dispclk_set_mhz = -1; | 84 | int actual_dispclk_set_mhz = -1; |
| 85 | struct dc *core_dc = clk_mgr->base.ctx->dc; | 85 | struct dc *core_dc = clk_mgr->base.ctx->dc; |
| 86 | struct dmcu *dmcu = core_dc->res_pool->dmcu; | 86 | struct dmcu *dmcu = core_dc->res_pool->dmcu; |
| 87 | uint32_t clk = requested_dispclk_khz / 1000; | ||
| 88 | |||
| 89 | if (clk <= 100) | ||
| 90 | clk = 101; | ||
| 91 | 87 | ||
| 92 | /* Unit of SMU msg parameter is Mhz */ | 88 | /* Unit of SMU msg parameter is Mhz */ |
| 93 | actual_dispclk_set_mhz = rn_vbios_smu_send_msg_with_param( | 89 | actual_dispclk_set_mhz = rn_vbios_smu_send_msg_with_param( |
| 94 | clk_mgr, | 90 | clk_mgr, |
| 95 | VBIOSSMC_MSG_SetDispclkFreq, | 91 | VBIOSSMC_MSG_SetDispclkFreq, |
| 96 | clk); | 92 | requested_dispclk_khz / 1000); |
| 97 | 93 | ||
| 98 | if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) { | 94 | if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) { |
| 99 | if (dmcu && dmcu->funcs->is_dmcu_initialized(dmcu)) { | 95 | if (dmcu && dmcu->funcs->is_dmcu_initialized(dmcu)) { |
| @@ -124,7 +120,7 @@ int rn_vbios_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int reque · 24 unmodified lines | |||
| 124 | { | 120 | { |
| 125 | int actual_dcfclk_set_mhz = -1; | 121 | int actual_dcfclk_set_mhz = -1; |
| 126 | 122 | ||
| 127 | if (clk_mgr->smu_ver < 0xFFFFFFFF) | 123 | if (clk_mgr->smu_ver < 0x370c00) |
| 128 | return actual_dcfclk_set_mhz; | 124 | return actual_dcfclk_set_mhz; |
| 129 | 125 | ||
| 130 | actual_dcfclk_set_mhz = rn_vbios_smu_send_msg_with_param( | 126 | actual_dcfclk_set_mhz = rn_vbios_smu_send_msg_with_param( |
| @@ -139,7 +135,7 @@ int rn_vbios_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int · 8 unmodified lines | |||
| 139 | { | 135 | { |
| 140 | int actual_min_ds_dcfclk_mhz = -1; | 136 | int actual_min_ds_dcfclk_mhz = -1; |
| 141 | 137 | ||
| 142 | if (clk_mgr->smu_ver < 0xFFFFFFFF) | 138 | if (clk_mgr->smu_ver < 0x370c00) |
| 143 | return actual_min_ds_dcfclk_mhz; | 139 | return actual_min_ds_dcfclk_mhz; |
| 144 | 140 | ||
| 145 | actual_min_ds_dcfclk_mhz = rn_vbios_smu_send_msg_with_param( | 141 | actual_min_ds_dcfclk_mhz = rn_vbios_smu_send_msg_with_param( |
| @@ -162,33 +158,35 @@ int rn_vbios_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_ · 16 unmodified lines | |||
| 162 | { | 158 | { |
| 163 | int actual_dppclk_set_mhz = -1; | 159 | int actual_dppclk_set_mhz = -1; |
| 164 | 160 | ||
| 165 | uint32_t clk = requested_dpp_khz / 1000; | ||
| 166 | |||
| 167 | if (clk <= 100) | ||
| 168 | clk = 101; | ||
| 169 | |||
| 170 | actual_dppclk_set_mhz = rn_vbios_smu_send_msg_with_param( | 161 | actual_dppclk_set_mhz = rn_vbios_smu_send_msg_with_param( |
| 171 | clk_mgr, | 162 | clk_mgr, |
| 172 | VBIOSSMC_MSG_SetDppclkFreq, | 163 | VBIOSSMC_MSG_SetDppclkFreq, |
| 173 | clk); | 164 | requested_dpp_khz / 1000); |
| 174 | 165 | ||
| 175 | return actual_dppclk_set_mhz * 1000; | 166 | return actual_dppclk_set_mhz * 1000; |
| 176 | } | 167 | } |
| 177 | 168 | ||
| 178 | void rn_vbios_smu_set_display_count(struct clk_mgr_internal *clk_mgr, int display_count) | 169 | void rn_vbios_smu_set_dcn_low_power_state(struct clk_mgr_internal *clk_mgr, enum dcn_pwr_state state) |
| 179 | { | 170 | { |
| 171 | int disp_count; | ||
| 172 | |||
| 173 | if (state == DCN_PWR_STATE_OPTIMIZED) | ||
| 174 | disp_count = 0; | ||
| 175 | else | ||
| 176 | disp_count = 1; | ||
| 177 | |||
| 180 | rn_vbios_smu_send_msg_with_param( | 178 | rn_vbios_smu_send_msg_with_param( |
| 181 | clk_mgr, | 179 | clk_mgr, |
| 182 | VBIOSSMC_MSG_SetDisplayCount, | 180 | VBIOSSMC_MSG_SetDisplayCount, |
| 183 | display_count); | 181 | disp_count); |
| 184 | } | 182 | } |
| 185 | 183 | ||
| 186 | void rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr) | 184 | void rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable) |
| 187 | { | 185 | { |
| 188 | rn_vbios_smu_send_msg_with_param( | 186 | rn_vbios_smu_send_msg_with_param( |
| 189 | clk_mgr, | 187 | clk_mgr, |
| 190 | VBIOSSMC_MSG_EnableTmdp48MHzRefclkPwrDown, | 188 | VBIOSSMC_MSG_EnableTmdp48MHzRefclkPwrDown, |
| 191 | 0); | 189 | enable); |
| 192 | } | 190 | } |
| 193 | 191 | ||
| 194 | void rn_vbios_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr) | 192 | void rn_vbios_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr) |
| @@ -33,8 +33,8 @@ int rn_vbios_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int reque · 32 unmodified lines | |||
| 33 | int rn_vbios_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz); | 33 | int rn_vbios_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz); |
| 34 | void rn_vbios_smu_set_phyclk(struct clk_mgr_internal *clk_mgr, int requested_phyclk_khz); | 34 | void rn_vbios_smu_set_phyclk(struct clk_mgr_internal *clk_mgr, int requested_phyclk_khz); |
| 35 | int rn_vbios_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz); | 35 | int rn_vbios_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz); |
| 36 | void rn_vbios_smu_set_display_count(struct clk_mgr_internal *clk_mgr, int display_count); | 36 | void rn_vbios_smu_set_dcn_low_power_state(struct clk_mgr_internal *clk_mgr, int display_count); |
| 37 | void rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr); | 37 | void rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable); |
| 38 | void rn_vbios_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr); | 38 | void rn_vbios_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr); |
| 39 | 39 | ||
| 40 | #endif /* DAL_DC_DCN10_RV1_CLK_MGR_VBIOS_SMU_H_ */ | 40 | #endif /* DAL_DC_DCN10_RV1_CLK_MGR_VBIOS_SMU_H_ */ |
| @@ -411,6 +411,27 @@ bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream, · 410 unmodified lines | |||
| 411 | return false; | 411 | return false; |
| 412 | } | 412 | } |
| 413 | 413 | ||
| 414 | void dc_stream_set_dyn_expansion(struct dc *dc, struct dc_stream_state *stream, | ||
| 415 | enum dc_dynamic_expansion option) | ||
| 416 | { | ||
| 417 | /* OPP FMT dyn expansion updates*/ | ||
| 418 | int i = 0; | ||
| 419 | struct pipe_ctx *pipe_ctx; | ||
| 420 | |||
| 421 | for (i = 0; i < MAX_PIPES; i++) { | ||
| 422 | if (dc->current_state->res_ctx.pipe_ctx[i].stream | ||
| 423 | == stream) { | ||
| 424 | pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; | ||
| 425 | pipe_ctx->stream_res.opp->dyn_expansion = option; | ||
| 426 | pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion( | ||
| 427 | pipe_ctx->stream_res.opp, | ||
| 428 | COLOR_SPACE_YCBCR601, | ||
| 429 | stream->timing.display_color_depth, | ||
| 430 | stream->signal); | ||
| 431 | } | ||
| 432 | } | ||
| 433 | } | ||
| 434 | |||
| 414 | void dc_stream_set_dither_option(struct dc_stream_state *stream, | 435 | void dc_stream_set_dither_option(struct dc_stream_state *stream, |
| 415 | enum dc_dither_option option) | 436 | enum dc_dither_option option) |
| 416 | { | 437 | { |
| @@ -918,15 +939,11 @@ static void program_timing_sync( · 501 unmodified lines | |||
| 918 | 939 | ||
| 919 | /* set first pipe with plane as master */ | 940 | /* set first pipe with plane as master */ |
| 920 | for (j = 0; j < group_size; j++) { | 941 | for (j = 0; j < group_size; j++) { |
| 921 | struct pipe_ctx *temp; | ||
| 922 | |||
| 923 | if (pipe_set[j]->plane_state) { | 942 | if (pipe_set[j]->plane_state) { |
| 924 | if (j == 0) | 943 | if (j == 0) |
| 925 | break; | 944 | break; |
| 926 | 945 | ||
| 927 | temp = pipe_set[0]; | 946 | swap(pipe_set[0], pipe_set[j]); |
| 928 | pipe_set[0] = pipe_set[j]; | ||
| 929 | pipe_set[j] = temp; | ||
| 930 | break; | 947 | break; |
| 931 | } | 948 | } |
| 932 | } | 949 | } |
| @@ -983,6 +1000,10 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc, · 50 unmodified lines | |||
| 983 | struct dc_crtc_timing *crtc_timing) | 1000 | struct dc_crtc_timing *crtc_timing) |
| 984 | { | 1001 | { |
| 985 | struct timing_generator *tg; | 1002 | struct timing_generator *tg; |
| 1003 | struct stream_encoder *se = NULL; | ||
| 1004 | |||
| 1005 | struct dc_crtc_timing hw_crtc_timing = {0}; | ||
| 1006 | |||
| 986 | struct dc_link *link = sink->link; | 1007 | struct dc_link *link = sink->link; |
| 987 | unsigned int i, enc_inst, tg_inst = 0; | 1008 | unsigned int i, enc_inst, tg_inst = 0; |
| 988 | 1009 | ||
| @@ -1002,6 +1023,9 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc, · 13 unmodified lines | |||
| 1002 | 1023 | ||
| 1003 | for (i = 0; i < dc->res_pool->stream_enc_count; i++) { | 1024 | for (i = 0; i < dc->res_pool->stream_enc_count; i++) { |
| 1004 | if (dc->res_pool->stream_enc[i]->id == enc_inst) { | 1025 | if (dc->res_pool->stream_enc[i]->id == enc_inst) { |
| 1026 | |||
| 1027 | se = dc->res_pool->stream_enc[i]; | ||
| 1028 | |||
| 1005 | tg_inst = dc->res_pool->stream_enc[i]->funcs->dig_source_otg( | 1029 | tg_inst = dc->res_pool->stream_enc[i]->funcs->dig_source_otg( |
| 1006 | dc->res_pool->stream_enc[i]); | 1030 | dc->res_pool->stream_enc[i]); |
| 1007 | break; | 1031 | break; |
| @@ -1017,10 +1041,46 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc, · 9 unmodified lines | |||
| 1017 | 1041 | ||
| 1018 | tg = dc->res_pool->timing_generators[tg_inst]; | 1042 | tg = dc->res_pool->timing_generators[tg_inst]; |
| 1019 | 1043 | ||
| 1020 | if (!tg->funcs->is_matching_timing) | 1044 | if (!tg->funcs->get_hw_timing) |
| 1045 | return false; | ||
| 1046 | |||
| 1047 | if (!tg->funcs->get_hw_timing(tg, &hw_crtc_timing)) | ||
| 1048 | return false; | ||
| 1049 | |||
| 1050 | if (crtc_timing->h_total != hw_crtc_timing.h_total) | ||
| 1051 | return false; | ||
| 1052 | |||
| 1053 | if (crtc_timing->h_border_left != hw_crtc_timing.h_border_left) | ||
| 1054 | return false; | ||
| 1055 | |||
| 1056 | if (crtc_timing->h_addressable != hw_crtc_timing.h_addressable) | ||
| 1057 | return false; | ||
| 1058 | |||
| 1059 | if (crtc_timing->h_border_right != hw_crtc_timing.h_border_right) | ||
| 1021 | return false; | 1060 | return false; |
| 1022 | 1061 | ||
| 1023 | if (!tg->funcs->is_matching_timing(tg, crtc_timing)) | 1062 | if (crtc_timing->h_front_porch != hw_crtc_timing.h_front_porch) |
| 1063 | return false; | ||
| 1064 | |||
| 1065 | if (crtc_timing->h_sync_width != hw_crtc_timing.h_sync_width) | ||
| 1066 | return false; | ||
| 1067 | |||
| 1068 | if (crtc_timing->v_total != hw_crtc_timing.v_total) | ||
| 1069 | return false; | ||
| 1070 | |||
| 1071 | if (crtc_timing->v_border_top != hw_crtc_timing.v_border_top) | ||
| 1072 | return false; | ||
| 1073 | |||
| 1074 | if (crtc_timing->v_addressable != hw_crtc_timing.v_addressable) | ||
| 1075 | return false; | ||
| 1076 | |||
| 1077 | if (crtc_timing->v_border_bottom != hw_crtc_timing.v_border_bottom) | ||
| 1078 | return false; | ||
| 1079 | |||
| 1080 | if (crtc_timing->v_front_porch != hw_crtc_timing.v_front_porch) | ||
| 1081 | return false; | ||
| 1082 | |||
| 1083 | if (crtc_timing->v_sync_width != hw_crtc_timing.v_sync_width) | ||
| 1024 | return false; | 1084 | return false; |
| 1025 | 1085 | ||
| 1026 | if (dc_is_dp_signal(link->connector_signal)) { | 1086 | if (dc_is_dp_signal(link->connector_signal)) { |
| @@ -1033,6 +1093,20 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc, · 6 unmodified lines | |||
| 1033 | if (crtc_timing->pix_clk_100hz != pix_clk_100hz) | 1093 | if (crtc_timing->pix_clk_100hz != pix_clk_100hz) |
| 1034 | return false; | 1094 | return false; |
| 1035 | 1095 | ||
| 1096 | if (!se->funcs->dp_get_pixel_format) | ||
| 1097 | return false; | ||
| 1098 | |||
| 1099 | if (!se->funcs->dp_get_pixel_format( | ||
| 1100 | se, | ||
| 1101 | &hw_crtc_timing.pixel_encoding, | ||
| 1102 | &hw_crtc_timing.display_color_depth)) | ||
| 1103 | return false; | ||
| 1104 | |||
| 1105 | if (hw_crtc_timing.display_color_depth != crtc_timing->display_color_depth) | ||
| 1106 | return false; | ||
| 1107 | |||
| 1108 | if (hw_crtc_timing.pixel_encoding != crtc_timing->pixel_encoding) | ||
| 1109 | return false; | ||
| 1036 | } | 1110 | } |
| 1037 | 1111 | ||
| 1038 | return true; | 1112 | return true; |
| @@ -1660,8 +1734,16 @@ enum surface_update_type dc_check_update_surfaces_for_stream( · 621 unmodified lines | |||
| 1660 | updates[i].surface->update_flags.raw = 0xFFFFFFFF; | 1734 | updates[i].surface->update_flags.raw = 0xFFFFFFFF; |
| 1661 | } | 1735 | } |
| 1662 | 1736 | ||
| 1663 | if (type == UPDATE_TYPE_FAST && memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0) | 1737 | if (type == UPDATE_TYPE_FAST) { |
| 1664 | dc->optimized_required = true; | 1738 | // If there's an available clock comparator, we use that. |
| 1739 | if (dc->clk_mgr->funcs->are_clock_states_equal) { | ||
| 1740 | if (!dc->clk_mgr->funcs->are_clock_states_equal(&dc->clk_mgr->clks, &dc->current_state->bw_ctx.bw.dcn.clk)) | ||
| 1741 | dc->optimized_required = true; | ||
| 1742 | // Else we fallback to mem compare. | ||
| 1743 | } else if (memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0) { | ||
| 1744 | dc->optimized_required = true; | ||
| 1745 | } | ||
| 1746 | } | ||
| 1665 | 1747 | ||
| 1666 | return type; | 1748 | return type; |
| 1667 | } | 1749 | } |
| @@ -743,7 +743,8 @@ static bool wait_for_alt_mode(struct dc_link *link) · 742 unmodified lines | |||
| 743 | * This does not create remote sinks but will trigger DM | 743 | * This does not create remote sinks but will trigger DM |
| 744 | * to start MST detection if a branch is detected. | 744 | * to start MST detection if a branch is detected. |
| 745 | */ | 745 | */ |
| 746 | bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) | 746 | static bool dc_link_detect_helper(struct dc_link *link, |
| 747 | enum dc_detect_reason reason) | ||
| 747 | { | 748 | { |
| 748 | struct dc_sink_init_data sink_init_data = { 0 }; | 749 | struct dc_sink_init_data sink_init_data = { 0 }; |
| 749 | struct display_sink_capability sink_caps = { 0 }; | 750 | struct display_sink_capability sink_caps = { 0 }; |
| @@ -759,6 +760,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) · 9 unmodified lines | |||
| 759 | bool same_dpcd = true; | 760 | bool same_dpcd = true; |
| 760 | enum dc_connection_type new_connection_type = dc_connection_none; | 761 | enum dc_connection_type new_connection_type = dc_connection_none; |
| 761 | bool perform_dp_seamless_boot = false; | 762 | bool perform_dp_seamless_boot = false; |
| 763 | |||
| 762 | DC_LOGGER_INIT(link->ctx->logger); | 764 | DC_LOGGER_INIT(link->ctx->logger); |
| 763 | 765 | ||
| 764 | if (dc_is_virtual_signal(link->connector_signal)) | 766 | if (dc_is_virtual_signal(link->connector_signal)) |
| @@ -871,7 +873,8 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) · 106 unmodified lines | |||
| 871 | * empty which leads to allocate_mst_payload() has "0" | 873 | * empty which leads to allocate_mst_payload() has "0" |
| 872 | * pbn_per_slot value leading to exception on dc_fixpt_div() | 874 | * pbn_per_slot value leading to exception on dc_fixpt_div() |
| 873 | */ | 875 | */ |
| 874 | link->verified_link_cap = link->reported_link_cap; | 876 | dp_verify_mst_link_cap(link); |
| 877 | |||
| 875 | if (prev_sink != NULL) | 878 | if (prev_sink != NULL) |
| 876 | dc_sink_release(prev_sink); | 879 | dc_sink_release(prev_sink); |
| 877 | return false; | 880 | return false; |
| @@ -1065,6 +1068,23 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) · 187 unmodified lines | |||
| 1065 | dc_sink_release(prev_sink); | 1068 | dc_sink_release(prev_sink); |
| 1066 | 1069 | ||
| 1067 | return true; | 1070 | return true; |
| 1071 | |||
| 1072 | } | ||
| 1073 | |||
| 1074 | bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) | ||
| 1075 | { | ||
| 1076 | const struct dc *dc = link->dc; | ||
| 1077 | bool ret; | ||
| 1078 | |||
| 1079 | /* get out of low power state */ | ||
| 1080 | clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr); | ||
| 1081 | |||
| 1082 | ret = dc_link_detect_helper(link, reason); | ||
| 1083 | |||
| 1084 | /* Go back to power optimized state */ | ||
| 1085 | clk_mgr_optimize_pwr_state(dc, dc->clk_mgr); | ||
| 1086 | |||
| 1087 | return ret; | ||
| 1068 | } | 1088 | } |
| 1069 | 1089 | ||
| 1070 | bool dc_link_get_hpd_state(struct dc_link *dc_link) | 1090 | bool dc_link_get_hpd_state(struct dc_link *dc_link) |
| @@ -1510,7 +1530,7 @@ static enum dc_status enable_link_dp( · 439 unmodified lines | |||
| 1510 | 1530 | ||
| 1511 | pipe_ctx->stream_res.pix_clk_params.requested_sym_clk = | 1531 | pipe_ctx->stream_res.pix_clk_params.requested_sym_clk = |
| 1512 | link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ; | 1532 | link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ; |
| 1513 | if (!apply_seamless_boot_optimization) | 1533 | if (state->clk_mgr && !apply_seamless_boot_optimization) |
| 1514 | state->clk_mgr->funcs->update_clocks(state->clk_mgr, state, false); | 1534 | state->clk_mgr->funcs->update_clocks(state->clk_mgr, state, false); |
| 1515 | 1535 | ||
| 1516 | dp_enable_link_phy( | 1536 | dp_enable_link_phy( |
| @@ -2237,7 +2257,7 @@ static bool dp_active_dongle_validate_timing( · 720 unmodified lines | |||
| 2237 | break; | 2257 | break; |
| 2238 | } | 2258 | } |
| 2239 | 2259 | ||
| 2240 | if (dongle_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER || | 2260 | if (dpcd_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER || |
| 2241 | dongle_caps->extendedCapValid == false) | 2261 | dongle_caps->extendedCapValid == false) |
| 2242 | return true; | 2262 | return true; |
| 2243 | 2263 | ||
| @@ -2401,13 +2421,17 @@ bool dc_link_set_abm_disable(const struct dc_link *link) · 157 unmodified lines | |||
| 2401 | return true; | 2421 | return true; |
| 2402 | } | 2422 | } |
| 2403 | 2423 | ||
| 2404 | bool dc_link_set_psr_enable(const struct dc_link *link, bool enable, bool wait) | 2424 | bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool wait) |
| 2405 | { | 2425 | { |
| 2406 | struct dc *core_dc = link->ctx->dc; | 2426 | struct dc *core_dc = link->ctx->dc; |
| 2407 | struct dmcu *dmcu = core_dc->res_pool->dmcu; | 2427 | struct dmcu *dmcu = core_dc->res_pool->dmcu; |
| 2408 | 2428 | ||
| 2409 | if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_enabled) | 2429 | |
| 2410 | dmcu->funcs->set_psr_enable(dmcu, enable, wait); | 2430 | |
| 2431 | if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_feature_enabled) | ||
| 2432 | dmcu->funcs->set_psr_enable(dmcu, allow_active, wait); | ||
| 2433 | |||
| 2434 | link->psr_allow_active = allow_active; | ||
| 2411 | 2435 | ||
| 2412 | return true; | 2436 | return true; |
| 2413 | } | 2437 | } |
| @@ -2718,6 +2742,10 @@ void core_link_enable_stream( · 304 unmodified lines | |||
| 2718 | enum dc_status status; | 2742 | enum dc_status status; |
| 2719 | DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); | 2743 | DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); |
| 2720 | 2744 | ||
| 2745 | if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment) && | ||
| 2746 | dc_is_virtual_signal(pipe_ctx->stream->signal)) | ||
| 2747 | return; | ||
| 2748 | |||
| 2721 | if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) { | 2749 | if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) { |
| 2722 | stream->link->link_enc->funcs->setup( | 2750 | stream->link->link_enc->funcs->setup( |
| 2723 | stream->link->link_enc, | 2751 | stream->link->link_enc, |
| @@ -2860,6 +2888,10 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx) · 136 unmodified lines | |||
| 2860 | struct dc_stream_state *stream = pipe_ctx->stream; | 2888 | struct dc_stream_state *stream = pipe_ctx->stream; |
| 2861 | struct dc_link *link = stream->sink->link; | 2889 | struct dc_link *link = stream->sink->link; |
| 2862 | 2890 | ||
| 2891 | if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment) && | ||
| 2892 | dc_is_virtual_signal(pipe_ctx->stream->signal)) | ||
| 2893 | return; | ||
| 2894 | |||
| 2863 | #if defined(CONFIG_DRM_AMD_DC_HDCP) | 2895 | #if defined(CONFIG_DRM_AMD_DC_HDCP) |
| 2864 | update_psp_stream_config(pipe_ctx, true); | 2896 | update_psp_stream_config(pipe_ctx, true); |
| 2865 | #endif | 2897 | #endif |
| @@ -634,6 +634,20 @@ bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc, · 633 unmodified lines | |||
| 634 | return dce_aux_transfer_with_retries(ddc, payload); | 634 | return dce_aux_transfer_with_retries(ddc, payload); |
| 635 | } | 635 | } |
| 636 | 636 | ||
| 637 | |||
| 638 | enum dc_status dc_link_aux_configure_timeout(struct ddc_service *ddc, | ||
| 639 | uint32_t timeout) | ||
| 640 | { | ||
| 641 | enum dc_status status = DC_OK; | ||
| 642 | struct ddc *ddc_pin = ddc->ddc_pin; | ||
| 643 | |||
| 644 | if (ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout == NULL) | ||
| 645 | return DC_ERROR_UNEXPECTED; | ||
| 646 | if (!ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout(ddc, timeout)) | ||
| 647 | status = DC_ERROR_UNEXPECTED; | ||
| 648 | return status; | ||
| 649 | } | ||
| 650 | |||
| 637 | /*test only function*/ | 651 | /*test only function*/ |
| 638 | void dal_ddc_service_set_ddc_pin( | 652 | void dal_ddc_service_set_ddc_pin( |
| 639 | struct ddc_service *ddc_service, | 653 | struct ddc_service *ddc_service, |
| @@ -1409,6 +1409,9 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link) · 1408 unmodified lines | |||
| 1409 | if (link->link_enc->features.flags.bits.IS_HBR3_CAPABLE) | 1409 | if (link->link_enc->features.flags.bits.IS_HBR3_CAPABLE) |
| 1410 | max_link_cap.link_rate = LINK_RATE_HIGH3; | 1410 | max_link_cap.link_rate = LINK_RATE_HIGH3; |
| 1411 | 1411 | ||
| 1412 | if (link->link_enc->funcs->get_max_link_cap) | ||
| 1413 | link->link_enc->funcs->get_max_link_cap(link->link_enc, &max_link_cap); | ||
| 1414 | |||
| 1412 | /* Lower link settings based on sink's link cap */ | 1415 | /* Lower link settings based on sink's link cap */ |
| 1413 | if (link->reported_link_cap.lane_count < max_link_cap.lane_count) | 1416 | if (link->reported_link_cap.lane_count < max_link_cap.lane_count) |
| 1414 | max_link_cap.lane_count = | 1417 | max_link_cap.lane_count = |
| @@ -1653,11 +1656,14 @@ bool dp_verify_link_cap_with_retries( · 238 unmodified lines | |||
| 1653 | 1656 | ||
| 1654 | for (i = 0; i < attempts; i++) { | 1657 | for (i = 0; i < attempts; i++) { |
| 1655 | int fail_count = 0; | 1658 | int fail_count = 0; |
| 1656 | enum dc_connection_type type; | 1659 | enum dc_connection_type type = dc_connection_none; |
| 1657 | 1660 | ||
| 1658 | memset(&link->verified_link_cap, 0, | 1661 | memset(&link->verified_link_cap, 0, |
| 1659 | sizeof(struct dc_link_settings)); | 1662 | sizeof(struct dc_link_settings)); |
| 1660 | if (!dc_link_detect_sink(link, &type)) { | 1663 | if (!dc_link_detect_sink(link, &type) || type == dc_connection_none) { |
| 1664 | link->verified_link_cap.lane_count = LANE_COUNT_ONE; | ||
| 1665 | link->verified_link_cap.link_rate = LINK_RATE_LOW; | ||
| 1666 | link->verified_link_cap.link_spread = LINK_SPREAD_DISABLED; | ||
| 1661 | break; | 1667 | break; |
| 1662 | } else if (dp_verify_link_cap(link, | 1668 | } else if (dp_verify_link_cap(link, |
| 1663 | &link->reported_link_cap, | 1669 | &link->reported_link_cap, |
| @@ -1670,6 +1676,19 @@ bool dp_verify_link_cap_with_retries( · 6 unmodified lines | |||
| 1670 | return success; | 1676 | return success; |
| 1671 | } | 1677 | } |
| 1672 | 1678 | ||
| 1679 | bool dp_verify_mst_link_cap( | ||
| 1680 | struct dc_link *link) | ||
| 1681 | { | ||
| 1682 | struct dc_link_settings max_link_cap = {0}; | ||
| 1683 | |||
| 1684 | max_link_cap = get_max_link_cap(link); | ||
| 1685 | link->verified_link_cap = get_common_supported_link_settings( | ||
| 1686 | link->reported_link_cap, | ||
| 1687 | max_link_cap); | ||
| 1688 | |||
| 1689 | return true; | ||
| 1690 | } | ||
| 1691 | |||
| 1673 | static struct dc_link_settings get_common_supported_link_settings( | 1692 | static struct dc_link_settings get_common_supported_link_settings( |
| 1674 | struct dc_link_settings link_setting_a, | 1693 | struct dc_link_settings link_setting_a, |
| 1675 | struct dc_link_settings link_setting_b) | 1694 | struct dc_link_settings link_setting_b) |
| @@ -2057,11 +2076,11 @@ static bool allow_hpd_rx_irq(const struct dc_link *link) · 381 unmodified lines | |||
| 2057 | return false; | 2076 | return false; |
| 2058 | } | 2077 | } |
| 2059 | 2078 | ||
| 2060 | static bool handle_hpd_irq_psr_sink(const struct dc_link *link) | 2079 | static bool handle_hpd_irq_psr_sink(struct dc_link *link) |
| 2061 | { | 2080 | { |
| 2062 | union dpcd_psr_configuration psr_configuration; | 2081 | union dpcd_psr_configuration psr_configuration; |
| 2063 | 2082 | ||
| 2064 | if (!link->psr_enabled) | 2083 | if (!link->psr_feature_enabled) |
| 2065 | return false; | 2084 | return false; |
| 2066 | 2085 | ||
| 2067 | dm_helpers_dp_read_dpcd( | 2086 | dm_helpers_dp_read_dpcd( |
| @@ -2100,8 +2119,8 @@ static bool handle_hpd_irq_psr_sink(const struct dc_link *link) · 32 unmodified lines | |||
| 2100 | sizeof(psr_error_status.raw)); | 2119 | sizeof(psr_error_status.raw)); |
| 2101 | 2120 | ||
| 2102 | /* PSR error, disable and re-enable PSR */ | 2121 | /* PSR error, disable and re-enable PSR */ |
| 2103 | dc_link_set_psr_enable(link, false, true); | 2122 | dc_link_set_psr_allow_active(link, false, true); |
| 2104 | dc_link_set_psr_enable(link, true, true); | 2123 | dc_link_set_psr_allow_active(link, true, true); |
| 2105 | 2124 | ||
| 2106 | return true; | 2125 | return true; |
| 2107 | } else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS == | 2126 | } else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS == |
| @@ -2556,6 +2575,7 @@ static void get_active_converter_info( · 448 unmodified lines | |||
| 2556 | uint8_t data, struct dc_link *link) | 2575 | uint8_t data, struct dc_link *link) |
| 2557 | { | 2576 | { |
| 2558 | union dp_downstream_port_present ds_port = { .byte = data }; | 2577 | union dp_downstream_port_present ds_port = { .byte = data }; |
| 2578 | memset(&link->dpcd_caps.dongle_caps, 0, sizeof(link->dpcd_caps.dongle_caps)); | ||
| 2559 | 2579 | ||
| 2560 | /* decode converter info*/ | 2580 | /* decode converter info*/ |
| 2561 | if (!ds_port.fields.PORT_PRESENT) { | 2581 | if (!ds_port.fields.PORT_PRESENT) { |
| @@ -2702,6 +2722,7 @@ static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data, · 140 unmodified lines | |||
| 2702 | * keep receiver powered all the time.*/ | 2722 | * keep receiver powered all the time.*/ |
| 2703 | case DP_BRANCH_DEVICE_ID_0010FA: | 2723 | case DP_BRANCH_DEVICE_ID_0010FA: |
| 2704 | case DP_BRANCH_DEVICE_ID_0080E1: | 2724 | case DP_BRANCH_DEVICE_ID_0080E1: |
| 2725 | case DP_BRANCH_DEVICE_ID_00E04C: | ||
| 2705 | link->wa_flags.dp_keep_receiver_powered = true; | 2726 | link->wa_flags.dp_keep_receiver_powered = true; |
| 2706 | break; | 2727 | break; |
| 2707 | 2728 | ||
| @@ -423,10 +423,10 @@ bool dc_stream_add_writeback(struct dc *dc, · 422 unmodified lines | |||
| 423 | 423 | ||
| 424 | if (dwb->funcs->is_enabled(dwb)) { | 424 | if (dwb->funcs->is_enabled(dwb)) { |
| 425 | /* writeback pipe already enabled, only need to update */ | 425 | /* writeback pipe already enabled, only need to update */ |
| 426 | dc->hwss.update_writeback(dc, stream_status, wb_info); | 426 | dc->hwss.update_writeback(dc, stream_status, wb_info, dc->current_state); |
| 427 | } else { | 427 | } else { |
| 428 | /* Enable writeback pipe from scratch*/ | 428 | /* Enable writeback pipe from scratch*/ |
| 429 | dc->hwss.enable_writeback(dc, stream_status, wb_info); | 429 | dc->hwss.enable_writeback(dc, stream_status, wb_info, dc->current_state); |
| 430 | } | 430 | } |
| 431 | } | 431 | } |
| 432 | 432 | ||
| @@ -39,7 +39,7 @@ · 38 unmodified lines | |||
| 39 | #include "inc/hw/dmcu.h" | 39 | #include "inc/hw/dmcu.h" |
| 40 | #include "dml/display_mode_lib.h" | 40 | #include "dml/display_mode_lib.h" |
| 41 | 41 | ||
| 42 | #define DC_VER "3.2.51.1" | 42 | #define DC_VER "3.2.54" |
| 43 | 43 | ||
| 44 | #define MAX_SURFACES 3 | 44 | #define MAX_SURFACES 3 |
| 45 | #define MAX_PLANES 6 | 45 | #define MAX_PLANES 6 |
| @@ -111,6 +111,7 @@ struct dc_caps { · 65 unmodified lines | |||
| 111 | bool force_dp_tps4_for_cp2520; | 111 | bool force_dp_tps4_for_cp2520; |
| 112 | bool disable_dp_clk_share; | 112 | bool disable_dp_clk_share; |
| 113 | bool psp_setup_panel_mode; | 113 | bool psp_setup_panel_mode; |
| 114 | bool extended_aux_timeout_support; | ||
| 114 | #ifdef CONFIG_DRM_AMD_DC_DCN2_0 | 115 | #ifdef CONFIG_DRM_AMD_DC_DCN2_0 |
| 115 | bool hw_3d_lut; | 116 | bool hw_3d_lut; |
| 116 | #endif | 117 | #endif |
| @@ -220,6 +221,7 @@ struct dc_config { · 103 unmodified lines | |||
| 220 | bool power_down_display_on_boot; | 221 | bool power_down_display_on_boot; |
| 221 | bool edp_not_connected; | 222 | bool edp_not_connected; |
| 222 | bool forced_clocks; | 223 | bool forced_clocks; |
| 224 | bool disable_extended_timeout_support; // Used to disable extended timeout and lttpr feature as well | ||
| 223 | bool multi_mon_pp_mclk_switch; | 225 | bool multi_mon_pp_mclk_switch; |
| 224 | }; | 226 | }; |
| 225 | 227 | ||
| @@ -245,6 +247,18 @@ enum wm_report_mode { · 19 unmodified lines | |||
| 245 | WM_REPORT_DEFAULT = 0, | 247 | WM_REPORT_DEFAULT = 0, |
| 246 | WM_REPORT_OVERRIDE = 1, | 248 | WM_REPORT_OVERRIDE = 1, |
| 247 | }; | 249 | }; |
| 250 | enum dtm_pstate{ | ||
| 251 | dtm_level_p0 = 0,/*highest voltage*/ | ||
| 252 | dtm_level_p1, | ||
| 253 | dtm_level_p2, | ||
| 254 | dtm_level_p3, | ||
| 255 | dtm_level_p4,/*when active_display_count = 0*/ | ||
| 256 | }; | ||
| 257 | |||
| 258 | enum dcn_pwr_state { | ||
| 259 | DCN_PWR_STATE_OPTIMIZED = 0, | ||
| 260 | DCN_PWR_STATE_NORMAL = 1 | ||
| 261 | }; | ||
| 248 | 262 | ||
| 249 | /* | 263 | /* |
| 250 | * For any clocks that may differ per pipe | 264 | * For any clocks that may differ per pipe |
| @@ -260,12 +274,13 @@ struct dc_clocks { · 9 unmodified lines | |||
| 260 | int phyclk_khz; | 274 | int phyclk_khz; |
| 261 | int dramclk_khz; | 275 | int dramclk_khz; |
| 262 | bool p_state_change_support; | 276 | bool p_state_change_support; |
| 263 | 277 | enum dcn_pwr_state pwr_state; | |
| 264 | /* | 278 | /* |
| 265 | * Elements below are not compared for the purposes of | 279 | * Elements below are not compared for the purposes of |
| 266 | * optimization required | 280 | * optimization required |
| 267 | */ | 281 | */ |
| 268 | bool prev_p_state_change_support; | 282 | bool prev_p_state_change_support; |
| 283 | enum dtm_pstate dtm_level; | ||
| 269 | int max_supported_dppclk_khz; | 284 | int max_supported_dppclk_khz; |
| 270 | int max_supported_dispclk_khz; | 285 | int max_supported_dispclk_khz; |
| 271 | int bw_dppclk_khz; /*a copy of dppclk_khz*/ | 286 | int bw_dppclk_khz; /*a copy of dppclk_khz*/ |
| @@ -578,6 +578,11 @@ enum dc_quantization_range { · 577 unmodified lines | |||
| 578 | QUANTIZATION_RANGE_LIMITED | 578 | QUANTIZATION_RANGE_LIMITED |
| 579 | }; | 579 | }; |
| 580 | 580 | ||
| 581 | enum dc_dynamic_expansion { | ||
| 582 | DYN_EXPANSION_AUTO, | ||
| 583 | DYN_EXPANSION_DISABLE | ||
| 584 | }; | ||
| 585 | |||
| 581 | /* XFM */ | 586 | /* XFM */ |
| 582 | 587 | ||
| 583 | /* used in struct dc_plane_state */ | 588 | /* used in struct dc_plane_state */ |
| @@ -126,7 +126,8 @@ struct dc_link { · 125 unmodified lines | |||
| 126 | unsigned short chip_caps; | 126 | unsigned short chip_caps; |
| 127 | unsigned int dpcd_sink_count; | 127 | unsigned int dpcd_sink_count; |
| 128 | enum edp_revision edp_revision; | 128 | enum edp_revision edp_revision; |
| 129 | bool psr_enabled; | 129 | bool psr_feature_enabled; |
| 130 | bool psr_allow_active; | ||
| 130 | 131 | ||
| 131 | /* MST record stream using this link */ | 132 | /* MST record stream using this link */ |
| 132 | struct link_flags { | 133 | struct link_flags { |
| @@ -158,6 +159,18 @@ static inline struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_ · 25 unmodified lines | |||
| 158 | return dc->links[link_index]; | 159 | return dc->links[link_index]; |
| 159 | } | 160 | } |
| 160 | 161 | ||
| 162 | static inline struct dc_link *get_edp_link(const struct dc *dc) | ||
| 163 | { | ||
| 164 | int i; | ||
| 165 | |||
| 166 | // report any eDP links, even unconnected DDI's | ||
| 167 | for (i = 0; i < dc->link_count; i++) { | ||
| 168 | if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP) | ||
| 169 | return dc->links[i]; | ||
| 170 | } | ||
| 171 | return NULL; | ||
| 172 | } | ||
| 173 | |||
| 161 | /* Set backlight level of an embedded panel (eDP, LVDS). | 174 | /* Set backlight level of an embedded panel (eDP, LVDS). |
| 162 | * backlight_pwm_u16_16 is unsigned 32 bit with 16 bit integer | 175 | * backlight_pwm_u16_16 is unsigned 32 bit with 16 bit integer |
| 163 | * and 16 bit fractional, where 1.0 is max backlight value. | 176 | * and 16 bit fractional, where 1.0 is max backlight value. |
| @@ -170,7 +183,7 @@ int dc_link_get_backlight_level(const struct dc_link *dc_link); · 6 unmodified lines | |||
| 170 | 183 | ||
| 171 | bool dc_link_set_abm_disable(const struct dc_link *dc_link); | 184 | bool dc_link_set_abm_disable(const struct dc_link *dc_link); |
| 172 | 185 | ||
| 173 | bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable, bool wait); | 186 | bool dc_link_set_psr_allow_active(struct dc_link *dc_link, bool enable, bool wait); |
| 174 | 187 | ||
| 175 | bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state); | 188 | bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state); |
| 176 | 189 | ||
| @@ -451,6 +451,9 @@ void dc_stream_set_static_screen_events(struct dc *dc, · 450 unmodified lines | |||
| 451 | int num_streams, | 451 | int num_streams, |
| 452 | const struct dc_static_screen_events *events); | 452 | const struct dc_static_screen_events *events); |
| 453 | 453 | ||
| 454 | void dc_stream_set_dyn_expansion(struct dc *dc, struct dc_stream_state *stream, | ||
| 455 | enum dc_dynamic_expansion option); | ||
| 456 | |||
| 454 | void dc_stream_set_dither_option(struct dc_stream_state *stream, | 457 | void dc_stream_set_dither_option(struct dc_stream_state *stream, |
| 455 | enum dc_dither_option option); | 458 | enum dc_dither_option option); |
| 456 | 459 | ||
| @@ -77,6 +77,9 @@ static bool dce_abm_set_pipe(struct abm *abm, uint32_t controller_id) · 76 unmodified lines | |||
| 77 | /* notifyDMCUMsg */ | 77 | /* notifyDMCUMsg */ |
| 78 | REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); | 78 | REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); |
| 79 | 79 | ||
| 80 | REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, | ||
| 81 | 1, 80000); | ||
| 82 | |||
| 80 | return true; | 83 | return true; |
| 81 | } | 84 | } |
| 82 | 85 | ||
| @@ -42,6 +42,10 @@ · 41 unmodified lines | |||
| 42 | 42 | ||
| 43 | #include "reg_helper.h" | 43 | #include "reg_helper.h" |
| 44 | 44 | ||
| 45 | #undef FN | ||
| 46 | #define FN(reg_name, field_name) \ | ||
| 47 | aux110->shift->field_name, aux110->mask->field_name | ||
| 48 | |||
| 45 | #define FROM_AUX_ENGINE(ptr) \ | 49 | #define FROM_AUX_ENGINE(ptr) \ |
| 46 | container_of((ptr), struct aux_engine_dce110, base) | 50 | container_of((ptr), struct aux_engine_dce110, base) |
| 47 | 51 | ||
| @@ -55,6 +59,14 @@ enum { · 7 unmodified lines | |||
| 55 | AUX_TIMED_OUT_RETRY_COUNTER = 2, | 59 | AUX_TIMED_OUT_RETRY_COUNTER = 2, |
| 56 | AUX_DEFER_RETRY_COUNTER = 6 | 60 | AUX_DEFER_RETRY_COUNTER = 6 |
| 57 | }; | 61 | }; |
| 62 | |||
| 63 | #define TIME_OUT_INCREMENT 1016 | ||
| 64 | #define TIME_OUT_MULTIPLIER_8 8 | ||
| 65 | #define TIME_OUT_MULTIPLIER_16 16 | ||
| 66 | #define TIME_OUT_MULTIPLIER_32 32 | ||
| 67 | #define TIME_OUT_MULTIPLIER_64 64 | ||
| 68 | #define MAX_TIMEOUT_LENGTH 127 | ||
| 69 | |||
| 58 | static void release_engine( | 70 | static void release_engine( |
| 59 | struct dce_aux *engine) | 71 | struct dce_aux *engine) |
| 60 | { | 72 | { |
| @@ -198,7 +210,7 @@ static void submit_channel_request( · 137 unmodified lines | |||
| 198 | REG_UPDATE(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, 1); | 210 | REG_UPDATE(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, 1); |
| 199 | 211 | ||
| 200 | REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 0, | 212 | REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 0, |
| 201 | 10, aux110->timeout_period/10); | 213 | 10, aux110->polling_timeout_period/10); |
| 202 | 214 | ||
| 203 | /* set the delay and the number of bytes to write */ | 215 | /* set the delay and the number of bytes to write */ |
| 204 | 216 | ||
| @@ -327,7 +339,7 @@ static enum aux_channel_operation_result get_channel_status( · 122 unmodified lines | |||
| 327 | 339 | ||
| 328 | /* poll to make sure that SW_DONE is asserted */ | 340 | /* poll to make sure that SW_DONE is asserted */ |
| 329 | REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 1, | 341 | REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 1, |
| 330 | 10, aux110->timeout_period/10); | 342 | 10, aux110->polling_timeout_period/10); |
| 331 | 343 | ||
| 332 | value = REG_READ(AUX_SW_STATUS); | 344 | value = REG_READ(AUX_SW_STATUS); |
| 333 | /* in case HPD is LOW, exit AUX transaction */ | 345 | /* in case HPD is LOW, exit AUX transaction */ |
| @@ -414,20 +426,82 @@ void dce110_engine_destroy(struct dce_aux **engine) · 80 unmodified lines | |||
| 414 | *engine = NULL; | 426 | *engine = NULL; |
| 415 | 427 | ||
| 416 | } | 428 | } |
| 429 | |||
| 430 | static bool dce_aux_configure_timeout(struct ddc_service *ddc, | ||
| 431 | uint32_t timeout_in_us) | ||
| 432 | { | ||
| 433 | uint32_t multiplier = 0; | ||
| 434 | uint32_t length = 0; | ||
| 435 | uint32_t timeout = 0; | ||
| 436 | struct ddc *ddc_pin = ddc->ddc_pin; | ||
| 437 | struct dce_aux *aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]; | ||
| 438 | struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(aux_engine); | ||
| 439 | |||
| 440 | /* 1-Update polling timeout period */ | ||
| 441 | aux110->polling_timeout_period = timeout_in_us * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER; | ||
| 442 | |||
| 443 | /* 2-Update aux timeout period length and multiplier */ | ||
| 444 | if (timeout_in_us <= TIME_OUT_INCREMENT) { | ||
| 445 | multiplier = 0; | ||
| 446 | length = timeout_in_us/TIME_OUT_MULTIPLIER_8; | ||
| 447 | if (timeout_in_us % TIME_OUT_MULTIPLIER_8 != 0) | ||
| 448 | length++; | ||
| 449 | timeout = length * TIME_OUT_MULTIPLIER_8; | ||
| 450 | } else if (timeout_in_us <= 2 * TIME_OUT_INCREMENT) { | ||
| 451 | multiplier = 1; | ||
| 452 | length = timeout_in_us/TIME_OUT_MULTIPLIER_16; | ||
| 453 | if (timeout_in_us % TIME_OUT_MULTIPLIER_16 != 0) | ||
| 454 | length++; | ||
| 455 | timeout = length * TIME_OUT_MULTIPLIER_16; | ||
| 456 | } else if (timeout_in_us <= 4 * TIME_OUT_INCREMENT) { | ||
| 457 | multiplier = 2; | ||
| 458 | length = timeout_in_us/TIME_OUT_MULTIPLIER_32; | ||
| 459 | if (timeout_in_us % TIME_OUT_MULTIPLIER_32 != 0) | ||
| 460 | length++; | ||
| 461 | timeout = length * TIME_OUT_MULTIPLIER_32; | ||
| 462 | } else if (timeout_in_us > 4 * TIME_OUT_INCREMENT) { | ||
| 463 | multiplier = 3; | ||
| 464 | length = timeout_in_us/TIME_OUT_MULTIPLIER_64; | ||
| 465 | if (timeout_in_us % TIME_OUT_MULTIPLIER_64 != 0) | ||
| 466 | length++; | ||
| 467 | timeout = length * TIME_OUT_MULTIPLIER_64; | ||
| 468 | } | ||
| 469 | |||
| 470 | length = (length < MAX_TIMEOUT_LENGTH) ? length : MAX_TIMEOUT_LENGTH; | ||
| 471 | |||
| 472 | REG_UPDATE_SEQ_2(AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, length, AUX_RX_TIMEOUT_LEN_MUL, multiplier); | ||
| 473 | |||
| 474 | return true; | ||
| 475 | } | ||
| 476 | |||
| 477 | static struct dce_aux_funcs aux_functions = { | ||
| 478 | .configure_timeout = NULL, | ||
| 479 | .destroy = NULL, | ||
| 480 | }; | ||
| 481 | |||
| 417 | struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110, | 482 | struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110, |
| 418 | struct dc_context *ctx, | 483 | struct dc_context *ctx, |
| 419 | uint32_t inst, | 484 | uint32_t inst, |
| 420 | uint32_t timeout_period, | 485 | uint32_t timeout_period, |
| 421 | const struct dce110_aux_registers *regs) | 486 | const struct dce110_aux_registers *regs, |
| 487 | const struct dce110_aux_registers_mask *mask, | ||
| 488 | const struct dce110_aux_registers_shift *shift, | ||
| 489 | bool is_ext_aux_timeout_configurable) | ||
| 422 | { | 490 | { |
| 423 | aux_engine110->base.ddc = NULL; | 491 | aux_engine110->base.ddc = NULL; |
| 424 | aux_engine110->base.ctx = ctx; | 492 | aux_engine110->base.ctx = ctx; |
| 425 | aux_engine110->base.delay = 0; | 493 | aux_engine110->base.delay = 0; |
| 426 | aux_engine110->base.max_defer_write_retry = 0; | 494 | aux_engine110->base.max_defer_write_retry = 0; |
| 427 | aux_engine110->base.inst = inst; | 495 | aux_engine110->base.inst = inst; |
| 428 | aux_engine110->timeout_period = timeout_period; | 496 | aux_engine110->polling_timeout_period = timeout_period; |
| 429 | aux_engine110->regs = regs; | 497 | aux_engine110->regs = regs; |
| 430 | 498 | ||
| 499 | aux_engine110->mask = mask; | ||
| 500 | aux_engine110->shift = shift; | ||
| 501 | aux_engine110->base.funcs = &aux_functions; | ||
| 502 | if (is_ext_aux_timeout_configurable) | ||
| 503 | aux_engine110->base.funcs->configure_timeout = &dce_aux_configure_timeout; | ||
| 504 | |||
| 431 | return &aux_engine110->base; | 505 | return &aux_engine110->base; |
| 432 | } | 506 | } |
| 433 | 507 | ||
| @@ -475,7 +549,7 @@ int dce_aux_transfer_raw(struct ddc_service *ddc, · 41 unmodified lines | |||
| 475 | aux_req.action = i2caux_action_from_payload(payload); | 549 | aux_req.action = i2caux_action_from_payload(payload); |
| 476 | 550 | ||
| 477 | aux_req.address = payload->address; | 551 | aux_req.address = payload->address; |
| 478 | aux_req.delay = payload->defer_delay * 10; | 552 | aux_req.delay = 0; |
| 479 | aux_req.length = payload->length; | 553 | aux_req.length = payload->length; |
| 480 | aux_req.data = payload->data; | 554 | aux_req.data = payload->data; |
| 481 | 555 | ||
| @@ -544,8 +618,15 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc, · 62 unmodified lines | |||
| 544 | case AUX_TRANSACTION_REPLY_AUX_DEFER: | 618 | case AUX_TRANSACTION_REPLY_AUX_DEFER: |
| 545 | case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK: | 619 | case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK: |
| 546 | case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER: | 620 | case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER: |
| 547 | if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES) | 621 | if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES) { |
| 548 | goto fail; | 622 | goto fail; |
| 623 | } else { | ||
| 624 | if ((*payload->reply == AUX_TRANSACTION_REPLY_AUX_DEFER) || | ||
| 625 | (*payload->reply == AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER)) { | ||
| 626 | if (payload->defer_delay > 0) | ||
| 627 | msleep(payload->defer_delay); | ||
| 628 | } | ||
| 629 | } | ||
| 549 | break; | 630 | break; |
| 550 | 631 | ||
| 551 | case AUX_TRANSACTION_REPLY_I2C_DEFER: | 632 | case AUX_TRANSACTION_REPLY_I2C_DEFER: |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | |||
| 29 | #include "i2caux_interface.h" | 29 | #include "i2caux_interface.h" |
| 30 | #include "inc/hw/aux_engine.h" | 30 | #include "inc/hw/aux_engine.h" |
| 31 | 31 | ||
| 32 | |||
| 32 | #ifdef CONFIG_DRM_AMD_DC_DCN2_0 | 33 | #ifdef CONFIG_DRM_AMD_DC_DCN2_0 |
| 33 | #define AUX_COMMON_REG_LIST0(id)\ | 34 | #define AUX_COMMON_REG_LIST0(id)\ |
| 34 | SRI(AUX_CONTROL, DP_AUX, id), \ | 35 | SRI(AUX_CONTROL, DP_AUX, id), \ |
| @@ -36,6 +37,7 @@ · 1 unmodified line | |||
| 36 | SRI(AUX_SW_DATA, DP_AUX, id), \ | 37 | SRI(AUX_SW_DATA, DP_AUX, id), \ |
| 37 | SRI(AUX_SW_CONTROL, DP_AUX, id), \ | 38 | SRI(AUX_SW_CONTROL, DP_AUX, id), \ |
| 38 | SRI(AUX_INTERRUPT_CONTROL, DP_AUX, id), \ | 39 | SRI(AUX_INTERRUPT_CONTROL, DP_AUX, id), \ |
| 40 | SRI(AUX_DPHY_RX_CONTROL1, DP_AUX, id), \ | ||
| 39 | SRI(AUX_SW_STATUS, DP_AUX, id) | 41 | SRI(AUX_SW_STATUS, DP_AUX, id) |
| 40 | #endif | 42 | #endif |
| 41 | 43 | ||
| @@ -55,6 +57,7 @@ struct dce110_aux_registers { · 13 unmodified lines | |||
| 55 | uint32_t AUX_SW_DATA; | 57 | uint32_t AUX_SW_DATA; |
| 56 | uint32_t AUX_SW_CONTROL; | 58 | uint32_t AUX_SW_CONTROL; |
| 57 | uint32_t AUX_INTERRUPT_CONTROL; | 59 | uint32_t AUX_INTERRUPT_CONTROL; |
| 60 | uint32_t AUX_DPHY_RX_CONTROL1; | ||
| 58 | uint32_t AUX_SW_STATUS; | 61 | uint32_t AUX_SW_STATUS; |
| 59 | uint32_t AUXN_IMPCAL; | 62 | uint32_t AUXN_IMPCAL; |
| 60 | uint32_t AUXP_IMPCAL; | 63 | uint32_t AUXP_IMPCAL; |
| @@ -62,6 +65,156 @@ struct dce110_aux_registers { · 1 unmodified line | |||
| 62 | uint32_t AUX_RESET_MASK; | 65 | uint32_t AUX_RESET_MASK; |
| 63 | }; | 66 | }; |
| 64 | 67 | ||
| 68 | #define DCE_AUX_REG_FIELD_LIST(type)\ | ||
| 69 | type AUX_EN;\ | ||
| 70 | type AUX_RESET;\ | ||
| 71 | type AUX_RESET_DONE;\ | ||
| 72 | type AUX_REG_RW_CNTL_STATUS;\ | ||
| 73 | type AUX_SW_USE_AUX_REG_REQ;\ | ||
| 74 | type AUX_SW_DONE_USING_AUX_REG;\ | ||
| 75 | type AUX_SW_AUTOINCREMENT_DISABLE;\ | ||
| 76 | type AUX_SW_DATA_RW;\ | ||
| 77 | type AUX_SW_INDEX;\ | ||
| 78 | type AUX_SW_GO;\ | ||
| 79 | type AUX_SW_DATA;\ | ||
| 80 | type AUX_SW_REPLY_BYTE_COUNT;\ | ||
| 81 | type AUX_SW_DONE;\ | ||
| 82 | type AUX_SW_DONE_ACK;\ | ||
| 83 | type AUXN_IMPCAL_ENABLE;\ | ||
| 84 | type AUXP_IMPCAL_ENABLE;\ | ||
| 85 | type AUXN_IMPCAL_OVERRIDE_ENABLE;\ | ||
| 86 | type AUXP_IMPCAL_OVERRIDE_ENABLE;\ | ||
| 87 | type AUX_RX_TIMEOUT_LEN;\ | ||
| 88 | type AUX_RX_TIMEOUT_LEN_MUL;\ | ||
| 89 | type AUXN_CALOUT_ERROR_AK;\ | ||
| 90 | type AUXP_CALOUT_ERROR_AK;\ | ||
| 91 | type AUX_SW_START_DELAY;\ | ||
| 92 | type AUX_SW_WR_BYTES | ||
| 93 | |||
| 94 | #define DCE10_AUX_MASK_SH_LIST(mask_sh)\ | ||
| 95 | AUX_SF(AUX_CONTROL, AUX_EN, mask_sh),\ | ||
| 96 | AUX_SF(AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\ | ||
| 97 | AUX_SF(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\ | ||
| 98 | AUX_SF(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\ | ||
| 99 | AUX_SF(AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\ | ||
| 100 | AUX_SF(AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\ | ||
| 101 | AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ | ||
| 102 | AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ | ||
| 103 | AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\ | ||
| 104 | AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ | ||
| 105 | AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\ | ||
| 106 | AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ | ||
| 107 | AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\ | ||
| 108 | AUX_SF(AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\ | ||
| 109 | AUX_SF(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\ | ||
| 110 | AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\ | ||
| 111 | AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\ | ||
| 112 | AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\ | ||
| 113 | AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\ | ||
| 114 | AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\ | ||
| 115 | AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh) | ||
| 116 | |||
| 117 | #define DCE_AUX_MASK_SH_LIST(mask_sh)\ | ||
| 118 | AUX_SF(AUX_CONTROL, AUX_EN, mask_sh),\ | ||
| 119 | AUX_SF(AUX_CONTROL, AUX_RESET, mask_sh),\ | ||
| 120 | AUX_SF(AUX_CONTROL, AUX_RESET_DONE, mask_sh),\ | ||
| 121 | AUX_SF(AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\ | ||
| 122 | AUX_SF(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\ | ||
| 123 | AUX_SF(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\ | ||
| 124 | AUX_SF(AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\ | ||
| 125 | AUX_SF(AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\ | ||
| 126 | AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ | ||
| 127 | AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ | ||
| 128 | AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\ | ||
| 129 | AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ | ||
| 130 | AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\ | ||
| 131 | AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ | ||
| 132 | AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\ | ||
| 133 | AUX_SF(AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\ | ||
| 134 | AUX_SF(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\ | ||
| 135 | AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\ | ||
| 136 | AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\ | ||
| 137 | AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\ | ||
| 138 | AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\ | ||
| 139 | AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\ | ||
| 140 | AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh) | ||
| 141 | |||
| 142 | #define DCE12_AUX_MASK_SH_LIST(mask_sh)\ | ||
| 143 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\ | ||
| 144 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\ | ||
| 145 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\ | ||
| 146 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\ | ||
| 147 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\ | ||
| 148 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\ | ||
| 149 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\ | ||
| 150 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\ | ||
| 151 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ | ||
| 152 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ | ||
| 153 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\ | ||
| 154 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ | ||
| 155 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\ | ||
| 156 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ | ||
| 157 | AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\ | ||
| 158 | AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\ | ||
| 159 | AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\ | ||
| 160 | AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\ | ||
| 161 | AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\ | ||
| 162 | AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\ | ||
| 163 | AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\ | ||
| 164 | AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\ | ||
| 165 | AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh) | ||
| 166 | |||
| 167 | /* DCN10 MASK */ | ||
| 168 | #define DCN10_AUX_MASK_SH_LIST(mask_sh)\ | ||
| 169 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\ | ||
| 170 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\ | ||
| 171 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\ | ||
| 172 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\ | ||
| 173 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\ | ||
| 174 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\ | ||
| 175 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\ | ||
| 176 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\ | ||
| 177 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ | ||
| 178 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ | ||
| 179 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\ | ||
| 180 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ | ||
| 181 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\ | ||
| 182 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ | ||
| 183 | AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\ | ||
| 184 | AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\ | ||
| 185 | AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\ | ||
| 186 | AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\ | ||
| 187 | AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\ | ||
| 188 | AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\ | ||
| 189 | AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\ | ||
| 190 | AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\ | ||
| 191 | AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh) | ||
| 192 | |||
| 193 | /* for all other DCN */ | ||
| 194 | #define DCN_AUX_MASK_SH_LIST(mask_sh)\ | ||
| 195 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\ | ||
| 196 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\ | ||
| 197 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\ | ||
| 198 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\ | ||
| 199 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\ | ||
| 200 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\ | ||
| 201 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\ | ||
| 202 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\ | ||
| 203 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ | ||
| 204 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ | ||
| 205 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\ | ||
| 206 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ | ||
| 207 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\ | ||
| 208 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ | ||
| 209 | AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\ | ||
| 210 | AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\ | ||
| 211 | AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\ | ||
| 212 | AUX_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, mask_sh),\ | ||
| 213 | AUX_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN_MUL, mask_sh) | ||
| 214 | |||
| 215 | #define AUX_SF(reg_name, field_name, post_fix)\ | ||
| 216 | .field_name = reg_name ## __ ## field_name ## post_fix | ||
| 217 | |||
| 65 | enum { /* This is the timeout as defined in DP 1.2a, | 218 | enum { /* This is the timeout as defined in DP 1.2a, |
| 66 | * 2.3.4 "Detailed uPacket TX AUX CH State Description". | 219 | * 2.3.4 "Detailed uPacket TX AUX CH State Description". |
| 67 | */ | 220 | */ |
| @@ -97,20 +250,34 @@ struct dce_aux { · 29 unmodified lines | |||
| 97 | uint32_t max_defer_write_retry; | 250 | uint32_t max_defer_write_retry; |
| 98 | 251 | ||
| 99 | bool acquire_reset; | 252 | bool acquire_reset; |
| 253 | struct dce_aux_funcs *funcs; | ||
| 254 | }; | ||
| 255 | |||
| 256 | struct dce110_aux_registers_mask { | ||
| 257 | DCE_AUX_REG_FIELD_LIST(uint32_t); | ||
| 258 | }; | ||
| 259 | |||
| 260 | struct dce110_aux_registers_shift { | ||
| 261 | DCE_AUX_REG_FIELD_LIST(uint8_t); | ||
| 100 | }; | 262 | }; |
| 101 | 263 | ||
| 264 | |||
| 102 | struct aux_engine_dce110 { | 265 | struct aux_engine_dce110 { |
| 103 | struct dce_aux base; | 266 | struct dce_aux base; |
| 104 | const struct dce110_aux_registers *regs; | 267 | const struct dce110_aux_registers *regs; |
| 268 | const struct dce110_aux_registers_mask *mask; | ||
| 269 | const struct dce110_aux_registers_shift *shift; | ||
| 105 | struct { | 270 | struct { |
| 106 | uint32_t aux_control; | 271 | uint32_t aux_control; |
| 107 | uint32_t aux_arb_control; | 272 | uint32_t aux_arb_control; |
| 108 | uint32_t aux_sw_data; | 273 | uint32_t aux_sw_data; |
| 109 | uint32_t aux_sw_control; | 274 | uint32_t aux_sw_control; |
| 110 | uint32_t aux_interrupt_control; | 275 | uint32_t aux_interrupt_control; |
| 276 | uint32_t aux_dphy_rx_control1; | ||
| 277 | uint32_t aux_dphy_rx_control0; | ||
| 111 | uint32_t aux_sw_status; | 278 | uint32_t aux_sw_status; |
| 112 | } addr; | 279 | } addr; |
| 113 | uint32_t timeout_period; | 280 | uint32_t polling_timeout_period; |
| 114 | }; | 281 | }; |
| 115 | 282 | ||
| 116 | struct aux_engine_dce110_init_data { | 283 | struct aux_engine_dce110_init_data { |
| @@ -120,12 +287,15 @@ struct aux_engine_dce110_init_data { · 3 unmodified lines | |||
| 120 | const struct dce110_aux_registers *regs; | 287 | const struct dce110_aux_registers *regs; |
| 121 | }; | 288 | }; |
| 122 | 289 | ||
| 123 | struct dce_aux *dce110_aux_engine_construct( | 290 | struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110, |
| 124 | struct aux_engine_dce110 *aux_engine110, | ||
| 125 | struct dc_context *ctx, | 291 | struct dc_context *ctx, |
| 126 | uint32_t inst, | 292 | uint32_t inst, |
| 127 | uint32_t timeout_period, | 293 | uint32_t timeout_period, |
| 128 | const struct dce110_aux_registers *regs); | 294 | const struct dce110_aux_registers *regs, |
| 295 | |||
| 296 | const struct dce110_aux_registers_mask *mask, | ||
| 297 | const struct dce110_aux_registers_shift *shift, | ||
| 298 | bool is_ext_aux_timeout_configurable); | ||
| 129 | 299 | ||
| 130 | void dce110_engine_destroy(struct dce_aux **engine); | 300 | void dce110_engine_destroy(struct dce_aux **engine); |
| 131 | 301 | ||
| @@ -139,4 +309,13 @@ int dce_aux_transfer_raw(struct ddc_service *ddc, · 7 unmodified lines | |||
| 139 | 309 | ||
| 140 | bool dce_aux_transfer_with_retries(struct ddc_service *ddc, | 310 | bool dce_aux_transfer_with_retries(struct ddc_service *ddc, |
| 141 | struct aux_payload *cmd); | 311 | struct aux_payload *cmd); |
| 312 | |||
| 313 | struct dce_aux_funcs { | ||
| 314 | bool (*configure_timeout) | ||
| 315 | (struct ddc_service *ddc, | ||
| 316 | uint32_t timeout); | ||
| 317 | void (*destroy) | ||
| 318 | (struct aux_engine **ptr); | ||
| 319 | }; | ||
| 320 | |||
| 142 | #endif | 321 | #endif |
| @@ -679,6 +679,7 @@ struct dce_hwseq_registers { · 678 unmodified lines | |||
| 679 | HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \ | 679 | HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \ |
| 680 | HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \ | 680 | HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \ |
| 681 | HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ | 681 | HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ |
| 682 | HWSEQ_LVTMA_MASK_SH_LIST(mask_sh), \ | ||
| 682 | HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ | 683 | HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ |
| 683 | HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh) | 684 | HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh) |
| 684 | #endif | 685 | #endif |
| @@ -506,6 +506,14 @@ static const struct dce_mem_input_mask mi_masks = { · 505 unmodified lines | |||
| 506 | .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK | 506 | .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK |
| 507 | }; | 507 | }; |
| 508 | 508 | ||
| 509 | static const struct dce110_aux_registers_shift aux_shift = { | ||
| 510 | DCE10_AUX_MASK_SH_LIST(__SHIFT) | ||
| 511 | }; | ||
| 512 | |||
| 513 | static const struct dce110_aux_registers_mask aux_mask = { | ||
| 514 | DCE10_AUX_MASK_SH_LIST(_MASK) | ||
| 515 | }; | ||
| 516 | |||
| 509 | static struct mem_input *dce100_mem_input_create( | 517 | static struct mem_input *dce100_mem_input_create( |
| 510 | struct dc_context *ctx, | 518 | struct dc_context *ctx, |
| 511 | uint32_t inst) | 519 | uint32_t inst) |
| @@ -611,7 +619,10 @@ struct dce_aux *dce100_aux_engine_create( · 99 unmodified lines | |||
| 611 | 619 | ||
| 612 | dce110_aux_engine_construct(aux_engine, ctx, inst, | 620 | dce110_aux_engine_construct(aux_engine, ctx, inst, |
| 613 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, | 621 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, |
| 614 | &aux_engine_regs[inst]); | 622 | &aux_engine_regs[inst], |
| 623 | &aux_mask, | ||
| 624 | &aux_shift, | ||
| 625 | ctx->dc->caps.extended_aux_timeout_support); | ||
| 615 | 626 | ||
| 616 | return &aux_engine->base; | 627 | return &aux_engine->base; |
| 617 | } | 628 | } |
| @@ -997,6 +1008,8 @@ static bool construct( · 379 unmodified lines | |||
| 997 | dc->caps.max_cursor_size = 128; | 1008 | dc->caps.max_cursor_size = 128; |
| 998 | dc->caps.dual_link_dvi = true; | 1009 | dc->caps.dual_link_dvi = true; |
| 999 | dc->caps.disable_dp_clk_share = true; | 1010 | dc->caps.disable_dp_clk_share = true; |
| 1011 | dc->caps.extended_aux_timeout_support = false; | ||
| 1012 | |||
| 1000 | for (i = 0; i < pool->base.pipe_count; i++) { | 1013 | for (i = 0; i < pool->base.pipe_count; i++) { |
| 1001 | pool->base.timing_generators[i] = | 1014 | pool->base.timing_generators[i] = |
| 1002 | dce100_timing_generator_create( | 1015 | dce100_timing_generator_create( |
| @@ -1161,8 +1161,9 @@ static void build_audio_output( · 1160 unmodified lines | |||
| 1161 | } | 1161 | } |
| 1162 | } | 1162 | } |
| 1163 | 1163 | ||
| 1164 | if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT || | 1164 | if (state->clk_mgr && |
| 1165 | pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { | 1165 | (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT || |
| 1166 | pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)) { | ||
| 1166 | audio_output->pll_info.dp_dto_source_clock_in_khz = | 1167 | audio_output->pll_info.dp_dto_source_clock_in_khz = |
| 1167 | state->clk_mgr->funcs->get_dp_ref_clk_frequency( | 1168 | state->clk_mgr->funcs->get_dp_ref_clk_frequency( |
| 1168 | state->clk_mgr); | 1169 | state->clk_mgr); |
| @@ -1410,7 +1411,7 @@ static enum dc_status apply_single_controller_ctx_to_hw( · 241 unmodified lines | |||
| 1410 | 1411 | ||
| 1411 | pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; | 1412 | pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; |
| 1412 | 1413 | ||
| 1413 | pipe_ctx->stream->link->psr_enabled = false; | 1414 | pipe_ctx->stream->link->psr_feature_enabled = false; |
| 1414 | 1415 | ||
| 1415 | return DC_OK; | 1416 | return DC_OK; |
| 1416 | } | 1417 | } |
| @@ -1521,18 +1522,6 @@ static struct dc_stream_state *get_edp_stream(struct dc_state *context) · 104 unmodified lines | |||
| 1521 | return NULL; | 1522 | return NULL; |
| 1522 | } | 1523 | } |
| 1523 | 1524 | ||
| 1524 | static struct dc_link *get_edp_link(struct dc *dc) | ||
| 1525 | { | ||
| 1526 | int i; | ||
| 1527 | |||
| 1528 | // report any eDP links, even unconnected DDI's | ||
| 1529 | for (i = 0; i < dc->link_count; i++) { | ||
| 1530 | if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP) | ||
| 1531 | return dc->links[i]; | ||
| 1532 | } | ||
| 1533 | return NULL; | ||
| 1534 | } | ||
| 1535 | |||
| 1536 | static struct dc_link *get_edp_link_with_sink( | 1525 | static struct dc_link *get_edp_link_with_sink( |
| 1537 | struct dc *dc, | 1526 | struct dc *dc, |
| 1538 | struct dc_state *context) | 1527 | struct dc_state *context) |
| @@ -1826,7 +1815,7 @@ static bool should_enable_fbc(struct dc *dc, · 287 unmodified lines | |||
| 1826 | return false; | 1815 | return false; |
| 1827 | 1816 | ||
| 1828 | /* PSR should not be enabled */ | 1817 | /* PSR should not be enabled */ |
| 1829 | if (pipe_ctx->stream->link->psr_enabled) | 1818 | if (pipe_ctx->stream->link->psr_feature_enabled) |
| 1830 | return false; | 1819 | return false; |
| 1831 | 1820 | ||
| 1832 | /* Nothing to compress */ | 1821 | /* Nothing to compress */ |
| @@ -275,6 +275,14 @@ static const struct dce_stream_encoder_mask se_mask = { · 274 unmodified lines | |||
| 275 | SE_COMMON_MASK_SH_LIST_DCE110(_MASK) | 275 | SE_COMMON_MASK_SH_LIST_DCE110(_MASK) |
| 276 | }; | 276 | }; |
| 277 | 277 | ||
| 278 | static const struct dce110_aux_registers_shift aux_shift = { | ||
| 279 | DCE_AUX_MASK_SH_LIST(__SHIFT) | ||
| 280 | }; | ||
| 281 | |||
| 282 | static const struct dce110_aux_registers_mask aux_mask = { | ||
| 283 | DCE_AUX_MASK_SH_LIST(_MASK) | ||
| 284 | }; | ||
| 285 | |||
| 278 | #define opp_regs(id)\ | 286 | #define opp_regs(id)\ |
| 279 | [id] = {\ | 287 | [id] = {\ |
| 280 | OPP_DCE_110_REG_LIST(id),\ | 288 | OPP_DCE_110_REG_LIST(id),\ |
| @@ -657,7 +665,10 @@ struct dce_aux *dce110_aux_engine_create( · 376 unmodified lines | |||
| 657 | 665 | ||
| 658 | dce110_aux_engine_construct(aux_engine, ctx, inst, | 666 | dce110_aux_engine_construct(aux_engine, ctx, inst, |
| 659 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, | 667 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, |
| 660 | &aux_engine_regs[inst]); | 668 | &aux_engine_regs[inst], |
| 669 | &aux_mask, | ||
| 670 | &aux_shift, | ||
| 671 | ctx->dc->caps.extended_aux_timeout_support); | ||
| 661 | 672 | ||
| 662 | return &aux_engine->base; | 673 | return &aux_engine->base; |
| 663 | } | 674 | } |
| @@ -1293,6 +1304,7 @@ static bool construct( · 629 unmodified lines | |||
| 1293 | dc->caps.i2c_speed_in_khz = 100; | 1304 | dc->caps.i2c_speed_in_khz = 100; |
| 1294 | dc->caps.max_cursor_size = 128; | 1305 | dc->caps.max_cursor_size = 128; |
| 1295 | dc->caps.is_apu = true; | 1306 | dc->caps.is_apu = true; |
| 1307 | dc->caps.extended_aux_timeout_support = false; | ||
| 1296 | 1308 | ||
| 1297 | /************************************************* | 1309 | /************************************************* |
| 1298 | * Create resources * | 1310 | * Create resources * |
| @@ -172,6 +172,14 @@ static const struct dce_abm_mask abm_mask = { · 171 unmodified lines | |||
| 172 | ABM_MASK_SH_LIST_DCE110(_MASK) | 172 | ABM_MASK_SH_LIST_DCE110(_MASK) |
| 173 | }; | 173 | }; |
| 174 | 174 | ||
| 175 | static const struct dce110_aux_registers_shift aux_shift = { | ||
| 176 | DCE_AUX_MASK_SH_LIST(__SHIFT) | ||
| 177 | }; | ||
| 178 | |||
| 179 | static const struct dce110_aux_registers_mask aux_mask = { | ||
| 180 | DCE_AUX_MASK_SH_LIST(_MASK) | ||
| 181 | }; | ||
| 182 | |||
| 175 | #define ipp_regs(id)\ | 183 | #define ipp_regs(id)\ |
| 176 | [id] = {\ | 184 | [id] = {\ |
| 177 | IPP_DCE110_REG_LIST_DCE_BASE(id)\ | 185 | IPP_DCE110_REG_LIST_DCE_BASE(id)\ |
| @@ -630,7 +638,10 @@ struct dce_aux *dce112_aux_engine_create( · 452 unmodified lines | |||
| 630 | 638 | ||
| 631 | dce110_aux_engine_construct(aux_engine, ctx, inst, | 639 | dce110_aux_engine_construct(aux_engine, ctx, inst, |
| 632 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, | 640 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, |
| 633 | &aux_engine_regs[inst]); | 641 | &aux_engine_regs[inst], |
| 642 | &aux_mask, | ||
| 643 | &aux_shift, | ||
| 644 | ctx->dc->caps.extended_aux_timeout_support); | ||
| 634 | 645 | ||
| 635 | return &aux_engine->base; | 646 | return &aux_engine->base; |
| 636 | } | 647 | } |
| @@ -1163,7 +1174,7 @@ static bool construct( · 526 unmodified lines | |||
| 1163 | dc->caps.i2c_speed_in_khz = 100; | 1174 | dc->caps.i2c_speed_in_khz = 100; |
| 1164 | dc->caps.max_cursor_size = 128; | 1175 | dc->caps.max_cursor_size = 128; |
| 1165 | dc->caps.dual_link_dvi = true; | 1176 | dc->caps.dual_link_dvi = true; |
| 1166 | 1177 | dc->caps.extended_aux_timeout_support = false; | |
| 1167 | 1178 | ||
| 1168 | /************************************************* | 1179 | /************************************************* |
| 1169 | * Create resources * | 1180 | * Create resources * |
| @@ -293,6 +293,14 @@ static const struct dce_stream_encoder_mask se_mask = { · 292 unmodified lines | |||
| 293 | SE_COMMON_MASK_SH_LIST_DCE120(_MASK) | 293 | SE_COMMON_MASK_SH_LIST_DCE120(_MASK) |
| 294 | }; | 294 | }; |
| 295 | 295 | ||
| 296 | static const struct dce110_aux_registers_shift aux_shift = { | ||
| 297 | DCE12_AUX_MASK_SH_LIST(__SHIFT) | ||
| 298 | }; | ||
| 299 | |||
| 300 | static const struct dce110_aux_registers_mask aux_mask = { | ||
| 301 | DCE12_AUX_MASK_SH_LIST(_MASK) | ||
| 302 | }; | ||
| 303 | |||
| 296 | #define opp_regs(id)\ | 304 | #define opp_regs(id)\ |
| 297 | [id] = {\ | 305 | [id] = {\ |
| 298 | OPP_DCE_120_REG_LIST(id),\ | 306 | OPP_DCE_120_REG_LIST(id),\ |
| @@ -404,7 +412,10 @@ struct dce_aux *dce120_aux_engine_create( · 105 unmodified lines | |||
| 404 | 412 | ||
| 405 | dce110_aux_engine_construct(aux_engine, ctx, inst, | 413 | dce110_aux_engine_construct(aux_engine, ctx, inst, |
| 406 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, | 414 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, |
| 407 | &aux_engine_regs[inst]); | 415 | &aux_engine_regs[inst], |
| 416 | &aux_mask, | ||
| 417 | &aux_shift, | ||
| 418 | ctx->dc->caps.extended_aux_timeout_support); | ||
| 408 | 419 | ||
| 409 | return &aux_engine->base; | 420 | return &aux_engine->base; |
| 410 | } | 421 | } |
| @@ -1006,7 +1017,7 @@ static bool construct( · 595 unmodified lines | |||
| 1006 | dc->caps.max_cursor_size = 128; | 1017 | dc->caps.max_cursor_size = 128; |
| 1007 | dc->caps.dual_link_dvi = true; | 1018 | dc->caps.dual_link_dvi = true; |
| 1008 | dc->caps.psp_setup_panel_mode = true; | 1019 | dc->caps.psp_setup_panel_mode = true; |
| 1009 | 1020 | dc->caps.extended_aux_timeout_support = false; | |
| 1010 | dc->debug = debug_defaults; | 1021 | dc->debug = debug_defaults; |
| 1011 | 1022 | ||
| 1012 | /************************************************* | 1023 | /************************************************* |
| @@ -288,6 +288,14 @@ static const struct dce_opp_mask opp_mask = { · 287 unmodified lines | |||
| 288 | OPP_COMMON_MASK_SH_LIST_DCE_80(_MASK) | 288 | OPP_COMMON_MASK_SH_LIST_DCE_80(_MASK) |
| 289 | }; | 289 | }; |
| 290 | 290 | ||
| 291 | static const struct dce110_aux_registers_shift aux_shift = { | ||
| 292 | DCE10_AUX_MASK_SH_LIST(__SHIFT) | ||
| 293 | }; | ||
| 294 | |||
| 295 | static const struct dce110_aux_registers_mask aux_mask = { | ||
| 296 | DCE10_AUX_MASK_SH_LIST(_MASK) | ||
| 297 | }; | ||
| 298 | |||
| 291 | #define aux_engine_regs(id)\ | 299 | #define aux_engine_regs(id)\ |
| 292 | [id] = {\ | 300 | [id] = {\ |
| 293 | AUX_COMMON_REG_LIST(id), \ | 301 | AUX_COMMON_REG_LIST(id), \ |
| @@ -491,7 +499,10 @@ struct dce_aux *dce80_aux_engine_create( · 197 unmodified lines | |||
| 491 | 499 | ||
| 492 | dce110_aux_engine_construct(aux_engine, ctx, inst, | 500 | dce110_aux_engine_construct(aux_engine, ctx, inst, |
| 493 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, | 501 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, |
| 494 | &aux_engine_regs[inst]); | 502 | &aux_engine_regs[inst], |
| 503 | &aux_mask, | ||
| 504 | &aux_shift, | ||
| 505 | ctx->dc->caps.extended_aux_timeout_support); | ||
| 495 | 506 | ||
| 496 | return &aux_engine->base; | 507 | return &aux_engine->base; |
| 497 | } | 508 | } |
| @@ -895,6 +906,7 @@ static bool dce80_construct( · 397 unmodified lines | |||
| 895 | dc->caps.i2c_speed_in_khz = 40; | 906 | dc->caps.i2c_speed_in_khz = 40; |
| 896 | dc->caps.max_cursor_size = 128; | 907 | dc->caps.max_cursor_size = 128; |
| 897 | dc->caps.dual_link_dvi = true; | 908 | dc->caps.dual_link_dvi = true; |
| 909 | dc->caps.extended_aux_timeout_support = false; | ||
| 898 | 910 | ||
| 899 | /************************************************* | 911 | /************************************************* |
| 900 | * Create resources * | 912 | * Create resources * |
| @@ -129,7 +129,7 @@ void dpp_set_gamut_remap_bypass(struct dcn10_dpp *dpp) · 128 unmodified lines | |||
| 129 | 129 | ||
| 130 | #define IDENTITY_RATIO(ratio) (dc_fixpt_u2d19(ratio) == (1 << 19)) | 130 | #define IDENTITY_RATIO(ratio) (dc_fixpt_u2d19(ratio) == (1 << 19)) |
| 131 | 131 | ||
| 132 | static bool dpp_get_optimal_number_of_taps( | 132 | bool dpp1_get_optimal_number_of_taps( |
| 133 | struct dpp *dpp, | 133 | struct dpp *dpp, |
| 134 | struct scaler_data *scl_data, | 134 | struct scaler_data *scl_data, |
| 135 | const struct scaling_taps *in_taps) | 135 | const struct scaling_taps *in_taps) |
| @@ -521,7 +521,7 @@ static const struct dpp_funcs dcn10_dpp_funcs = { · 385 unmodified lines | |||
| 521 | .dpp_read_state = dpp_read_state, | 521 | .dpp_read_state = dpp_read_state, |
| 522 | .dpp_reset = dpp_reset, | 522 | .dpp_reset = dpp_reset, |
| 523 | .dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale, | 523 | .dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale, |
| 524 | .dpp_get_optimal_number_of_taps = dpp_get_optimal_number_of_taps, | 524 | .dpp_get_optimal_number_of_taps = dpp1_get_optimal_number_of_taps, |
| 525 | .dpp_set_gamut_remap = dpp1_cm_set_gamut_remap, | 525 | .dpp_set_gamut_remap = dpp1_cm_set_gamut_remap, |
| 526 | .dpp_set_csc_adjustment = dpp1_cm_set_output_csc_adjustment, | 526 | .dpp_set_csc_adjustment = dpp1_cm_set_output_csc_adjustment, |
| 527 | .dpp_set_csc_default = dpp1_cm_set_output_csc_default, | 527 | .dpp_set_csc_default = dpp1_cm_set_output_csc_default, |
| @@ -1504,6 +1504,11 @@ void dpp1_set_hdr_multiplier( · 1503 unmodified lines | |||
| 1504 | struct dpp *dpp_base, | 1504 | struct dpp *dpp_base, |
| 1505 | uint32_t multiplier); | 1505 | uint32_t multiplier); |
| 1506 | 1506 | ||
| 1507 | bool dpp1_get_optimal_number_of_taps( | ||
| 1508 | struct dpp *dpp, | ||
| 1509 | struct scaler_data *scl_data, | ||
| 1510 | const struct scaling_taps *in_taps); | ||
| 1511 | |||
| 1507 | void dpp1_construct(struct dcn10_dpp *dpp1, | 1512 | void dpp1_construct(struct dcn10_dpp *dpp1, |
| 1508 | struct dc_context *ctx, | 1513 | struct dc_context *ctx, |
| 1509 | uint32_t inst, | 1514 | uint32_t inst, |
| @@ -670,6 +670,10 @@ static void dcn10_bios_golden_init(struct dc *dc) · 669 unmodified lines | |||
| 670 | int i; | 670 | int i; |
| 671 | bool allow_self_fresh_force_enable = true; | 671 | bool allow_self_fresh_force_enable = true; |
| 672 | 672 | ||
| 673 | #if defined(CONFIG_DRM_AMD_DC_DCN2_1) | ||
| 674 | if (dc->hwss.s0i3_golden_init_wa && dc->hwss.s0i3_golden_init_wa(dc)) | ||
| 675 | return; | ||
| 676 | #endif | ||
| 673 | if (dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled) | 677 | if (dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled) |
| 674 | allow_self_fresh_force_enable = | 678 | allow_self_fresh_force_enable = |
| 675 | dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled(dc->res_pool->hubbub); | 679 | dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled(dc->res_pool->hubbub); |
| @@ -1452,15 +1456,15 @@ static void log_tf(struct dc_context *ctx, · 776 unmodified lines | |||
| 1452 | DC_LOG_ALL_TF_CHANNELS("Logging all channels..."); | 1456 | DC_LOG_ALL_TF_CHANNELS("Logging all channels..."); |
| 1453 | 1457 | ||
| 1454 | for (i = 0; i < hw_points_num; i++) { | 1458 | for (i = 0; i < hw_points_num; i++) { |
| 1455 | DC_LOG_GAMMA("R\t%d\t%llu\n", i, tf->tf_pts.red[i].value); | 1459 | DC_LOG_GAMMA("R\t%d\t%llu", i, tf->tf_pts.red[i].value); |
| 1456 | DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu\n", i, tf->tf_pts.green[i].value); | 1460 | DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu", i, tf->tf_pts.green[i].value); |
| 1457 | DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu\n", i, tf->tf_pts.blue[i].value); | 1461 | DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu", i, tf->tf_pts.blue[i].value); |
| 1458 | } | 1462 | } |
| 1459 | 1463 | ||
| 1460 | for (i = hw_points_num; i < MAX_NUM_HW_POINTS; i++) { | 1464 | for (i = hw_points_num; i < MAX_NUM_HW_POINTS; i++) { |
| 1461 | DC_LOG_ALL_GAMMA("R\t%d\t%llu\n", i, tf->tf_pts.red[i].value); | 1465 | DC_LOG_ALL_GAMMA("R\t%d\t%llu", i, tf->tf_pts.red[i].value); |
| 1462 | DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu\n", i, tf->tf_pts.green[i].value); | 1466 | DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu", i, tf->tf_pts.green[i].value); |
| 1463 | DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu\n", i, tf->tf_pts.blue[i].value); | 1467 | DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu", i, tf->tf_pts.blue[i].value); |
| 1464 | } | 1468 | } |
| 1465 | } | 1469 | } |
| 1466 | 1470 | ||
| @@ -2511,8 +2515,10 @@ static void program_all_pipe_in_tree( · 1044 unmodified lines | |||
| 2511 | pipe_ctx->stream_res.tg->funcs->set_vtg_params( | 2515 | pipe_ctx->stream_res.tg->funcs->set_vtg_params( |
| 2512 | pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing); | 2516 | pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing); |
| 2513 | 2517 | ||
| 2514 | dc->hwss.blank_pixel_data(dc, pipe_ctx, blank); | 2518 | if (dc->hwss.setup_vupdate_interrupt) |
| 2519 | dc->hwss.setup_vupdate_interrupt(pipe_ctx); | ||
| 2515 | 2520 | ||
| 2521 | dc->hwss.blank_pixel_data(dc, pipe_ctx, blank); | ||
| 2516 | } | 2522 | } |
| 2517 | 2523 | ||
| 2518 | if (pipe_ctx->plane_state != NULL) | 2524 | if (pipe_ctx->plane_state != NULL) |
| @@ -113,6 +113,20 @@ struct dcn10_link_enc_registers { · 112 unmodified lines | |||
| 113 | uint32_t DIG_LANE_ENABLE; | 113 | uint32_t DIG_LANE_ENABLE; |
| 114 | /* UNIPHY */ | 114 | /* UNIPHY */ |
| 115 | uint32_t CHANNEL_XBAR_CNTL; | 115 | uint32_t CHANNEL_XBAR_CNTL; |
| 116 | /* DPCS */ | ||
| 117 | uint32_t RDPCSTX_PHY_CNTL3; | ||
| 118 | uint32_t RDPCSTX_PHY_CNTL4; | ||
| 119 | uint32_t RDPCSTX_PHY_CNTL5; | ||
| 120 | uint32_t RDPCSTX_PHY_CNTL6; | ||
| 121 | uint32_t RDPCSTX_PHY_CNTL7; | ||
| 122 | uint32_t RDPCSTX_PHY_CNTL8; | ||
| 123 | uint32_t RDPCSTX_PHY_CNTL9; | ||
| 124 | uint32_t RDPCSTX_PHY_CNTL10; | ||
| 125 | uint32_t RDPCSTX_PHY_CNTL11; | ||
| 126 | uint32_t RDPCSTX_PHY_CNTL12; | ||
| 127 | uint32_t RDPCSTX_PHY_CNTL13; | ||
| 128 | uint32_t RDPCSTX_PHY_CNTL14; | ||
| 129 | uint32_t RDPCSTX_PHY_CNTL15; | ||
| 116 | /* indirect registers */ | 130 | /* indirect registers */ |
| 117 | uint32_t RAWLANE0_DIG_PCS_XF_RX_OVRD_IN_2; | 131 | uint32_t RAWLANE0_DIG_PCS_XF_RX_OVRD_IN_2; |
| 118 | uint32_t RAWLANE0_DIG_PCS_XF_RX_OVRD_IN_3; | 132 | uint32_t RAWLANE0_DIG_PCS_XF_RX_OVRD_IN_3; |
| @@ -250,6 +264,10 @@ struct dcn10_link_enc_registers { · 131 unmodified lines | |||
| 250 | type RDPCS_EXT_REFCLK_EN;\ | 264 | type RDPCS_EXT_REFCLK_EN;\ |
| 251 | type RDPCS_TX_FIFO_EN;\ | 265 | type RDPCS_TX_FIFO_EN;\ |
| 252 | type UNIPHY_LINK_ENABLE;\ | 266 | type UNIPHY_LINK_ENABLE;\ |
| 267 | type UNIPHY_CHANNEL0_XBAR_SOURCE;\ | ||
| 268 | type UNIPHY_CHANNEL1_XBAR_SOURCE;\ | ||
| 269 | type UNIPHY_CHANNEL2_XBAR_SOURCE;\ | ||
| 270 | type UNIPHY_CHANNEL3_XBAR_SOURCE;\ | ||
| 253 | type UNIPHY_CHANNEL0_INVERT;\ | 271 | type UNIPHY_CHANNEL0_INVERT;\ |
| 254 | type UNIPHY_CHANNEL1_INVERT;\ | 272 | type UNIPHY_CHANNEL1_INVERT;\ |
| 255 | type UNIPHY_CHANNEL2_INVERT;\ | 273 | type UNIPHY_CHANNEL2_INVERT;\ |
| @@ -337,16 +355,46 @@ struct dcn10_link_enc_registers { · 81 unmodified lines | |||
| 337 | type RDPCS_TX_FIFO_ERROR_MASK;\ | 355 | type RDPCS_TX_FIFO_ERROR_MASK;\ |
| 338 | type RDPCS_DPALT_DISABLE_TOGGLE_MASK;\ | 356 | type RDPCS_DPALT_DISABLE_TOGGLE_MASK;\ |
| 339 | type RDPCS_DPALT_4LANE_TOGGLE_MASK;\ | 357 | type RDPCS_DPALT_4LANE_TOGGLE_MASK;\ |
| 358 | type RDPCS_PHY_DPALT_DP4;\ | ||
| 340 | type RDPCS_PHY_DPALT_DISABLE;\ | 359 | type RDPCS_PHY_DPALT_DISABLE;\ |
| 341 | type RDPCS_PHY_DPALT_DISABLE_ACK;\ | 360 | type RDPCS_PHY_DPALT_DISABLE_ACK;\ |
| 342 | type RDPCS_PHY_DP_MPLLB_V2I;\ | 361 | type RDPCS_PHY_DP_MPLLB_V2I;\ |
| 343 | type RDPCS_PHY_DP_MPLLB_FREQ_VCO;\ | 362 | type RDPCS_PHY_DP_MPLLB_FREQ_VCO;\ |
| 363 | type RDPCS_PHY_DP_MPLLB_CP_INT_GS;\ | ||
| 364 | type RDPCS_PHY_RX_VREF_CTRL;\ | ||
| 344 | type RDPCS_PHY_DP_MPLLB_CP_INT;\ | 365 | type RDPCS_PHY_DP_MPLLB_CP_INT;\ |
| 345 | type RDPCS_PHY_DP_MPLLB_CP_PROP;\ | 366 | type RDPCS_PHY_DP_MPLLB_CP_PROP;\ |
| 346 | type RDPCS_PHY_RX_REF_LD_VAL;\ | 367 | type RDPCS_PHY_RX_REF_LD_VAL;\ |
| 347 | type RDPCS_PHY_RX_VCO_LD_VAL;\ | 368 | type RDPCS_PHY_RX_VCO_LD_VAL;\ |
| 348 | type DPCSTX_DEBUG_CONFIG; \ | 369 | type DPCSTX_DEBUG_CONFIG; \ |
| 349 | type RDPCSTX_DEBUG_CONFIG | 370 | type RDPCSTX_DEBUG_CONFIG; \ |
| 371 | type RDPCS_PHY_DP_TX0_EQ_MAIN;\ | ||
| 372 | type RDPCS_PHY_DP_TX0_EQ_PRE;\ | ||
| 373 | type RDPCS_PHY_DP_TX0_EQ_POST;\ | ||
| 374 | type RDPCS_PHY_DP_TX1_EQ_MAIN;\ | ||
| 375 | type RDPCS_PHY_DP_TX1_EQ_PRE;\ | ||
| 376 | type RDPCS_PHY_DP_TX1_EQ_POST;\ | ||
| 377 | type RDPCS_PHY_DP_TX2_EQ_MAIN;\ | ||
| 378 | type RDPCS_PHY_DP_MPLLB_CP_PROP_GS;\ | ||
| 379 | type RDPCS_PHY_DP_TX2_EQ_PRE;\ | ||
| 380 | type RDPCS_PHY_DP_TX2_EQ_POST;\ | ||
| 381 | type RDPCS_PHY_DP_TX3_EQ_MAIN;\ | ||
| 382 | type RDPCS_PHY_DCO_RANGE;\ | ||
| 383 | type RDPCS_PHY_DCO_FINETUNE;\ | ||
| 384 | type RDPCS_PHY_DP_TX3_EQ_PRE;\ | ||
| 385 | type RDPCS_PHY_DP_TX3_EQ_POST;\ | ||
| 386 | type RDPCS_PHY_SUP_PRE_HP;\ | ||
| 387 | type RDPCS_PHY_DP_TX0_VREGDRV_BYP;\ | ||
| 388 | type RDPCS_PHY_DP_TX1_VREGDRV_BYP;\ | ||
| 389 | type RDPCS_PHY_DP_TX2_VREGDRV_BYP;\ | ||
| 390 | type RDPCS_PHY_DP_TX3_VREGDRV_BYP;\ | ||
| 391 | type RDPCS_DMCU_DPALT_DIS_BLOCK_REG;\ | ||
| 392 | type UNIPHYA_SOFT_RESET;\ | ||
| 393 | type UNIPHYB_SOFT_RESET;\ | ||
| 394 | type UNIPHYC_SOFT_RESET;\ | ||
| 395 | type UNIPHYD_SOFT_RESET;\ | ||
| 396 | type UNIPHYE_SOFT_RESET;\ | ||
| 397 | type UNIPHYF_SOFT_RESET | ||
| 350 | 398 | ||
| 351 | #define DCN20_LINK_ENCODER_REG_FIELD_LIST(type) \ | 399 | #define DCN20_LINK_ENCODER_REG_FIELD_LIST(type) \ |
| 352 | type DIG_LANE0EN;\ | 400 | type DIG_LANE0EN;\ |
| @@ -240,6 +240,9 @@ void opp1_set_dyn_expansion( · 239 unmodified lines | |||
| 240 | FMT_DYNAMIC_EXP_EN, 0, | 240 | FMT_DYNAMIC_EXP_EN, 0, |
| 241 | FMT_DYNAMIC_EXP_MODE, 0); | 241 | FMT_DYNAMIC_EXP_MODE, 0); |
| 242 | 242 | ||
| 243 | if (opp->dyn_expansion == DYN_EXPANSION_DISABLE) | ||
| 244 | return; | ||
| 245 | |||
| 243 | /*00 - 10-bit -> 12-bit dynamic expansion*/ | 246 | /*00 - 10-bit -> 12-bit dynamic expansion*/ |
| 244 | /*01 - 8-bit -> 12-bit dynamic expansion*/ | 247 | /*01 - 8-bit -> 12-bit dynamic expansion*/ |
| 245 | if (signal == SIGNAL_TYPE_HDMI_TYPE_A || | 248 | if (signal == SIGNAL_TYPE_HDMI_TYPE_A || |
| @@ -1230,59 +1230,25 @@ bool optc1_is_stereo_left_eye(struct timing_generator *optc) · 1229 unmodified lines | |||
| 1230 | return ret; | 1230 | return ret; |
| 1231 | } | 1231 | } |
| 1232 | 1232 | ||
| 1233 | bool optc1_is_matching_timing(struct timing_generator *tg, | 1233 | bool optc1_get_hw_timing(struct timing_generator *tg, |
| 1234 | const struct dc_crtc_timing *otg_timing) | 1234 | struct dc_crtc_timing *hw_crtc_timing) |
| 1235 | { | 1235 | { |
| 1236 | struct dc_crtc_timing hw_crtc_timing = {0}; | ||
| 1237 | struct dcn_otg_state s = {0}; | 1236 | struct dcn_otg_state s = {0}; |
| 1238 | 1237 | ||
| 1239 | if (tg == NULL || otg_timing == NULL) | 1238 | if (tg == NULL || hw_crtc_timing == NULL) |
| 1240 | return false; | 1239 | return false; |
| 1241 | 1240 | ||
| 1242 | optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s); | 1241 | optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s); |
| 1243 | 1242 | ||
| 1244 | hw_crtc_timing.h_total = s.h_total + 1; | 1243 | hw_crtc_timing->h_total = s.h_total + 1; |
| 1245 | hw_crtc_timing.h_addressable = s.h_total - ((s.h_total - s.h_blank_start) + s.h_blank_end); | 1244 | hw_crtc_timing->h_addressable = s.h_total - ((s.h_total - s.h_blank_start) + s.h_blank_end); |
| 1246 | hw_crtc_timing.h_front_porch = s.h_total + 1 - s.h_blank_start; | 1245 | hw_crtc_timing->h_front_porch = s.h_total + 1 - s.h_blank_start; |
| 1247 | hw_crtc_timing.h_sync_width = s.h_sync_a_end - s.h_sync_a_start; | 1246 | hw_crtc_timing->h_sync_width = s.h_sync_a_end - s.h_sync_a_start; |
| 1248 | 1247 | ||
| 1249 | hw_crtc_timing.v_total = s.v_total + 1; | 1248 | hw_crtc_timing->v_total = s.v_total + 1; |
| 1250 | hw_crtc_timing.v_addressable = s.v_total - ((s.v_total - s.v_blank_start) + s.v_blank_end); | 1249 | hw_crtc_timing->v_addressable = s.v_total - ((s.v_total - s.v_blank_start) + s.v_blank_end); |
| 1251 | hw_crtc_timing.v_front_porch = s.v_total + 1 - s.v_blank_start; | 1250 | hw_crtc_timing->v_front_porch = s.v_total + 1 - s.v_blank_start; |
| 1252 | hw_crtc_timing.v_sync_width = s.v_sync_a_end - s.v_sync_a_start; | 1251 | hw_crtc_timing->v_sync_width = s.v_sync_a_end - s.v_sync_a_start; |
| 1253 | |||
| 1254 | if (otg_timing->h_total != hw_crtc_timing.h_total) | ||
| 1255 | return false; | ||
| 1256 | |||
| 1257 | if (otg_timing->h_border_left != hw_crtc_timing.h_border_left) | ||
| 1258 | return false; | ||
| 1259 | |||
| 1260 | if (otg_timing->h_addressable != hw_crtc_timing.h_addressable) | ||
| 1261 | return false; | ||
| 1262 | |||
| 1263 | if (otg_timing->h_border_right != hw_crtc_timing.h_border_right) | ||
| 1264 | return false; | ||
| 1265 | |||
| 1266 | if (otg_timing->h_front_porch != hw_crtc_timing.h_front_porch) | ||
| 1267 | return false; | ||
| 1268 | |||
| 1269 | if (otg_timing->h_sync_width != hw_crtc_timing.h_sync_width) | ||
| 1270 | return false; | ||
| 1271 | |||
| 1272 | if (otg_timing->v_total != hw_crtc_timing.v_total) | ||
| 1273 | return false; | ||
| 1274 | |||
| 1275 | if (otg_timing->v_border_top != hw_crtc_timing.v_border_top) | ||
| 1276 | return false; | ||
| 1277 | |||
| 1278 | if (otg_timing->v_addressable != hw_crtc_timing.v_addressable) | ||
| 1279 | return false; | ||
| 1280 | |||
| 1281 | if (otg_timing->v_border_bottom != hw_crtc_timing.v_border_bottom) | ||
| 1282 | return false; | ||
| 1283 | |||
| 1284 | if (otg_timing->v_sync_width != hw_crtc_timing.v_sync_width) | ||
| 1285 | return false; | ||
| 1286 | 1252 | ||
| 1287 | return true; | 1253 | return true; |
| 1288 | } | 1254 | } |
| @@ -1486,7 +1452,6 @@ static const struct timing_generator_funcs dcn10_tg_funcs = { · 197 unmodified lines | |||
| 1486 | .get_frame_count = optc1_get_vblank_counter, | 1452 | .get_frame_count = optc1_get_vblank_counter, |
| 1487 | .get_scanoutpos = optc1_get_crtc_scanoutpos, | 1453 | .get_scanoutpos = optc1_get_crtc_scanoutpos, |
| 1488 | .get_otg_active_size = optc1_get_otg_active_size, | 1454 | .get_otg_active_size = optc1_get_otg_active_size, |
| 1489 | .is_matching_timing = optc1_is_matching_timing, | ||
| 1490 | .set_early_control = optc1_set_early_control, | 1455 | .set_early_control = optc1_set_early_control, |
| 1491 | /* used by enable_timing_synchronization. Not need for FPGA */ | 1456 | /* used by enable_timing_synchronization. Not need for FPGA */ |
| 1492 | .wait_for_state = optc1_wait_for_state, | 1457 | .wait_for_state = optc1_wait_for_state, |
| @@ -1514,7 +1479,8 @@ static const struct timing_generator_funcs dcn10_tg_funcs = { · 21 unmodified lines | |||
| 1514 | .configure_crc = optc1_configure_crc, | 1479 | .configure_crc = optc1_configure_crc, |
| 1515 | .set_vtg_params = optc1_set_vtg_params, | 1480 | .set_vtg_params = optc1_set_vtg_params, |
| 1516 | .program_manual_trigger = optc1_program_manual_trigger, | 1481 | .program_manual_trigger = optc1_program_manual_trigger, |
| 1517 | .setup_manual_trigger = optc1_setup_manual_trigger | 1482 | .setup_manual_trigger = optc1_setup_manual_trigger, |
| 1483 | .get_hw_timing = optc1_get_hw_timing, | ||
| 1518 | }; | 1484 | }; |
| 1519 | 1485 | ||
| 1520 | void dcn10_timing_generator_init(struct optc *optc1) | 1486 | void dcn10_timing_generator_init(struct optc *optc1) |
| @@ -547,9 +547,8 @@ struct dcn_otg_state { · 546 unmodified lines | |||
| 547 | void optc1_read_otg_state(struct optc *optc1, | 547 | void optc1_read_otg_state(struct optc *optc1, |
| 548 | struct dcn_otg_state *s); | 548 | struct dcn_otg_state *s); |
| 549 | 549 | ||
| 550 | bool optc1_is_matching_timing( | 550 | bool optc1_get_hw_timing(struct timing_generator *tg, |
| 551 | struct timing_generator *tg, | 551 | struct dc_crtc_timing *hw_crtc_timing); |
| 552 | const struct dc_crtc_timing *otg_timing); | ||
| 553 | 552 | ||
| 554 | bool optc1_validate_timing( | 553 | bool optc1_validate_timing( |
| 555 | struct timing_generator *optc, | 554 | struct timing_generator *optc, |
| @@ -319,6 +319,14 @@ static const struct dcn10_link_enc_mask le_mask = { · 318 unmodified lines | |||
| 319 | LINK_ENCODER_MASK_SH_LIST_DCN10(_MASK) | 319 | LINK_ENCODER_MASK_SH_LIST_DCN10(_MASK) |
| 320 | }; | 320 | }; |
| 321 | 321 | ||
| 322 | static const struct dce110_aux_registers_shift aux_shift = { | ||
| 323 | DCN10_AUX_MASK_SH_LIST(__SHIFT) | ||
| 324 | }; | ||
| 325 | |||
| 326 | static const struct dce110_aux_registers_mask aux_mask = { | ||
| 327 | DCN10_AUX_MASK_SH_LIST(_MASK) | ||
| 328 | }; | ||
| 329 | |||
| 322 | #define ipp_regs(id)\ | 330 | #define ipp_regs(id)\ |
| 323 | [id] = {\ | 331 | [id] = {\ |
| 324 | IPP_REG_LIST_DCN10(id),\ | 332 | IPP_REG_LIST_DCN10(id),\ |
| @@ -642,7 +650,10 @@ struct dce_aux *dcn10_aux_engine_create( · 317 unmodified lines | |||
| 642 | 650 | ||
| 643 | dce110_aux_engine_construct(aux_engine, ctx, inst, | 651 | dce110_aux_engine_construct(aux_engine, ctx, inst, |
| 644 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, | 652 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, |
| 645 | &aux_engine_regs[inst]); | 653 | &aux_engine_regs[inst], |
| 654 | &aux_mask, | ||
| 655 | &aux_shift, | ||
| 656 | ctx->dc->caps.extended_aux_timeout_support); | ||
| 646 | 657 | ||
| 647 | return &aux_engine->base; | 658 | return &aux_engine->base; |
| 648 | } | 659 | } |
| @@ -1308,6 +1319,8 @@ static bool construct( · 659 unmodified lines | |||
| 1308 | dc->caps.max_slave_planes = 1; | 1319 | dc->caps.max_slave_planes = 1; |
| 1309 | dc->caps.is_apu = true; | 1320 | dc->caps.is_apu = true; |
| 1310 | dc->caps.post_blend_color_processing = false; | 1321 | dc->caps.post_blend_color_processing = false; |
| 1322 | dc->caps.extended_aux_timeout_support = false; | ||
| 1323 | |||
| 1311 | /* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */ | 1324 | /* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */ |
| 1312 | dc->caps.force_dp_tps4_for_cp2520 = true; | 1325 | dc->caps.force_dp_tps4_for_cp2520 = true; |
| 1313 | 1326 | ||
| @@ -1553,6 +1553,66 @@ unsigned int enc1_dig_source_otg( · 1552 unmodified lines | |||
| 1553 | return tg_inst; | 1553 | return tg_inst; |
| 1554 | } | 1554 | } |
| 1555 | 1555 | ||
| 1556 | bool enc1_stream_encoder_dp_get_pixel_format( | ||
| 1557 | struct stream_encoder *enc, | ||
| 1558 | enum dc_pixel_encoding *encoding, | ||
| 1559 | enum dc_color_depth *depth) | ||
| 1560 | { | ||
| 1561 | uint32_t hw_encoding = 0; | ||
| 1562 | uint32_t hw_depth = 0; | ||
| 1563 | struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); | ||
| 1564 | |||
| 1565 | if (enc == NULL || | ||
| 1566 | encoding == NULL || | ||
| 1567 | depth == NULL) | ||
| 1568 | return false; | ||
| 1569 | |||
| 1570 | REG_GET_2(DP_PIXEL_FORMAT, | ||
| 1571 | DP_PIXEL_ENCODING, &hw_encoding, | ||
| 1572 | DP_COMPONENT_DEPTH, &hw_depth); | ||
| 1573 | |||
| 1574 | switch (hw_depth) { | ||
| 1575 | case DP_COMPONENT_PIXEL_DEPTH_6BPC: | ||
| 1576 | *depth = COLOR_DEPTH_666; | ||
| 1577 | break; | ||
| 1578 | case DP_COMPONENT_PIXEL_DEPTH_8BPC: | ||
| 1579 | *depth = COLOR_DEPTH_888; | ||
| 1580 | break; | ||
| 1581 | case DP_COMPONENT_PIXEL_DEPTH_10BPC: | ||
| 1582 | *depth = COLOR_DEPTH_101010; | ||
| 1583 | break; | ||
| 1584 | case DP_COMPONENT_PIXEL_DEPTH_12BPC: | ||
| 1585 | *depth = COLOR_DEPTH_121212; | ||
| 1586 | break; | ||
| 1587 | case DP_COMPONENT_PIXEL_DEPTH_16BPC: | ||
| 1588 | *depth = COLOR_DEPTH_161616; | ||
| 1589 | break; | ||
| 1590 | default: | ||
| 1591 | *depth = COLOR_DEPTH_UNDEFINED; | ||
| 1592 | break; | ||
| 1593 | } | ||
| 1594 | |||
| 1595 | switch (hw_encoding) { | ||
| 1596 | case DP_PIXEL_ENCODING_TYPE_RGB444: | ||
| 1597 | *encoding = PIXEL_ENCODING_RGB; | ||
| 1598 | break; | ||
| 1599 | case DP_PIXEL_ENCODING_TYPE_YCBCR422: | ||
| 1600 | *encoding = PIXEL_ENCODING_YCBCR422; | ||
| 1601 | break; | ||
| 1602 | case DP_PIXEL_ENCODING_TYPE_YCBCR444: | ||
| 1603 | case DP_PIXEL_ENCODING_TYPE_Y_ONLY: | ||
| 1604 | *encoding = PIXEL_ENCODING_YCBCR444; | ||
| 1605 | break; | ||
| 1606 | case DP_PIXEL_ENCODING_TYPE_YCBCR420: | ||
| 1607 | *encoding = PIXEL_ENCODING_YCBCR420; | ||
| 1608 | break; | ||
| 1609 | default: | ||
| 1610 | *encoding = PIXEL_ENCODING_UNDEFINED; | ||
| 1611 | break; | ||
| 1612 | } | ||
| 1613 | return true; | ||
| 1614 | } | ||
| 1615 | |||
| 1556 | static const struct stream_encoder_funcs dcn10_str_enc_funcs = { | 1616 | static const struct stream_encoder_funcs dcn10_str_enc_funcs = { |
| 1557 | .dp_set_stream_attribute = | 1617 | .dp_set_stream_attribute = |
| 1558 | enc1_stream_encoder_dp_set_stream_attribute, | 1618 | enc1_stream_encoder_dp_set_stream_attribute, |
| @@ -1589,6 +1649,8 @@ static const struct stream_encoder_funcs dcn10_str_enc_funcs = { · 30 unmodified lines | |||
| 1589 | .dig_connect_to_otg = enc1_dig_connect_to_otg, | 1649 | .dig_connect_to_otg = enc1_dig_connect_to_otg, |
| 1590 | .hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute, | 1650 | .hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute, |
| 1591 | .dig_source_otg = enc1_dig_source_otg, | 1651 | .dig_source_otg = enc1_dig_source_otg, |
| 1652 | |||
| 1653 | .dp_get_pixel_format = enc1_stream_encoder_dp_get_pixel_format, | ||
| 1592 | }; | 1654 | }; |
| 1593 | 1655 | ||
| 1594 | void dcn10_stream_encoder_construct( | 1656 | void dcn10_stream_encoder_construct( |
| @@ -621,4 +621,9 @@ void get_audio_clock_info( · 620 unmodified lines | |||
| 621 | void enc1_reset_hdmi_stream_attribute( | 621 | void enc1_reset_hdmi_stream_attribute( |
| 622 | struct stream_encoder *enc); | 622 | struct stream_encoder *enc); |
| 623 | 623 | ||
| 624 | bool enc1_stream_encoder_dp_get_pixel_format( | ||
| 625 | struct stream_encoder *enc, | ||
| 626 | enum dc_pixel_encoding *encoding, | ||
| 627 | enum dc_color_depth *depth); | ||
| 628 | |||
| 624 | #endif /* __DC_STREAM_ENCODER_DCN10_H__ */ | 629 | #endif /* __DC_STREAM_ENCODER_DCN10_H__ */ |
| @@ -457,7 +457,7 @@ static struct dpp_funcs dcn20_dpp_funcs = { · 456 unmodified lines | |||
| 457 | .dpp_read_state = dpp20_read_state, | 457 | .dpp_read_state = dpp20_read_state, |
| 458 | .dpp_reset = dpp_reset, | 458 | .dpp_reset = dpp_reset, |
| 459 | .dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale, | 459 | .dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale, |
| 460 | .dpp_get_optimal_number_of_taps = dpp2_get_optimal_number_of_taps, | 460 | .dpp_get_optimal_number_of_taps = dpp1_get_optimal_number_of_taps, |
| 461 | .dpp_set_gamut_remap = dpp1_cm_set_gamut_remap, | 461 | .dpp_set_gamut_remap = dpp1_cm_set_gamut_remap, |
| 462 | .dpp_set_csc_adjustment = NULL, | 462 | .dpp_set_csc_adjustment = NULL, |
| 463 | .dpp_set_csc_default = NULL, | 463 | .dpp_set_csc_default = NULL, |
| @@ -705,11 +705,6 @@ void dpp2_set_hdr_multiplier( · 704 unmodified lines | |||
| 705 | struct dpp *dpp_base, | 705 | struct dpp *dpp_base, |
| 706 | uint32_t multiplier); | 706 | uint32_t multiplier); |
| 707 | 707 | ||
| 708 | bool dpp2_get_optimal_number_of_taps( | ||
| 709 | struct dpp *dpp, | ||
| 710 | struct scaler_data *scl_data, | ||
| 711 | const struct scaling_taps *in_taps); | ||
| 712 | |||
| 713 | bool dpp2_construct(struct dcn20_dpp *dpp2, | 708 | bool dpp2_construct(struct dcn20_dpp *dpp2, |
| 714 | struct dc_context *ctx, | 709 | struct dc_context *ctx, |
| 715 | uint32_t inst, | 710 | uint32_t inst, |
| @@ -1370,6 +1370,9 @@ static void dcn20_program_pipe( · 1369 unmodified lines | |||
| 1370 | 1370 | ||
| 1371 | pipe_ctx->stream_res.tg->funcs->set_vtg_params( | 1371 | pipe_ctx->stream_res.tg->funcs->set_vtg_params( |
| 1372 | pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing); | 1372 | pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing); |
| 1373 | |||
| 1374 | if (dc->hwss.setup_vupdate_interrupt) | ||
| 1375 | dc->hwss.setup_vupdate_interrupt(pipe_ctx); | ||
| 1373 | } | 1376 | } |
| 1374 | 1377 | ||
| 1375 | if (pipe_ctx->update_flags.bits.odm) | 1378 | if (pipe_ctx->update_flags.bits.odm) |
| @@ -1396,6 +1399,26 @@ static void dcn20_program_pipe( · 20 unmodified lines | |||
| 1396 | */ | 1399 | */ |
| 1397 | if (pipe_ctx->update_flags.bits.enable || pipe_ctx->stream->update_flags.bits.out_tf) | 1400 | if (pipe_ctx->update_flags.bits.enable || pipe_ctx->stream->update_flags.bits.out_tf) |
| 1398 | dc->hwss.set_output_transfer_func(pipe_ctx, pipe_ctx->stream); | 1401 | dc->hwss.set_output_transfer_func(pipe_ctx, pipe_ctx->stream); |
| 1402 | |||
| 1403 | /* If the pipe has been enabled or has a different opp, we | ||
| 1404 | * should reprogram the fmt. This deals with cases where | ||
| 1405 | * interation between mpc and odm combine on different streams | ||
| 1406 | * causes a different pipe to be chosen to odm combine with. | ||
| 1407 | */ | ||
| 1408 | if (pipe_ctx->update_flags.bits.enable | ||
| 1409 | || pipe_ctx->update_flags.bits.opp_changed) { | ||
| 1410 | |||
| 1411 | pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion( | ||
| 1412 | pipe_ctx->stream_res.opp, | ||
| 1413 | COLOR_SPACE_YCBCR601, | ||
| 1414 | pipe_ctx->stream->timing.display_color_depth, | ||
| 1415 | pipe_ctx->stream->signal); | ||
| 1416 | |||
| 1417 | pipe_ctx->stream_res.opp->funcs->opp_program_fmt( | ||
| 1418 | pipe_ctx->stream_res.opp, | ||
| 1419 | &pipe_ctx->stream->bit_depth_params, | ||
| 1420 | &pipe_ctx->stream->clamping); | ||
| 1421 | } | ||
| 1399 | } | 1422 | } |
| 1400 | 1423 | ||
| 1401 | static bool does_pipe_need_lock(struct pipe_ctx *pipe) | 1424 | static bool does_pipe_need_lock(struct pipe_ctx *pipe) |
| @@ -1510,6 +1533,10 @@ static void dcn20_program_front_end_for_ctx( · 108 unmodified lines | |||
| 1510 | msleep(1); | 1533 | msleep(1); |
| 1511 | } | 1534 | } |
| 1512 | } | 1535 | } |
| 1536 | |||
| 1537 | /* WA to apply WM setting*/ | ||
| 1538 | if (dc->hwseq->wa.DEGVIDCN21) | ||
| 1539 | dc->res_pool->hubbub->funcs->apply_DEDCN21_147_wa(dc->res_pool->hubbub); | ||
| 1513 | } | 1540 | } |
| 1514 | 1541 | ||
| 1515 | 1542 | ||
| @@ -1581,8 +1608,12 @@ bool dcn20_update_bandwidth( · 65 unmodified lines | |||
| 1581 | 1608 | ||
| 1582 | pipe_ctx->stream_res.tg->funcs->set_vtg_params( | 1609 | pipe_ctx->stream_res.tg->funcs->set_vtg_params( |
| 1583 | pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing); | 1610 | pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing); |
| 1611 | |||
| 1584 | if (pipe_ctx->prev_odm_pipe == NULL) | 1612 | if (pipe_ctx->prev_odm_pipe == NULL) |
| 1585 | dc->hwss.blank_pixel_data(dc, pipe_ctx, blank); | 1613 | dc->hwss.blank_pixel_data(dc, pipe_ctx, blank); |
| 1614 | |||
| 1615 | if (dc->hwss.setup_vupdate_interrupt) | ||
| 1616 | dc->hwss.setup_vupdate_interrupt(pipe_ctx); | ||
| 1586 | } | 1617 | } |
| 1587 | 1618 | ||
| 1588 | pipe_ctx->plane_res.hubp->funcs->hubp_setup( | 1619 | pipe_ctx->plane_res.hubp->funcs->hubp_setup( |
| @@ -1599,7 +1630,8 @@ bool dcn20_update_bandwidth( · 10 unmodified lines | |||
| 1599 | static void dcn20_enable_writeback( | 1630 | static void dcn20_enable_writeback( |
| 1600 | struct dc *dc, | 1631 | struct dc *dc, |
| 1601 | const struct dc_stream_status *stream_status, | 1632 | const struct dc_stream_status *stream_status, |
| 1602 | struct dc_writeback_info *wb_info) | 1633 | struct dc_writeback_info *wb_info, |
| 1634 | struct dc_state *context) | ||
| 1603 | { | 1635 | { |
| 1604 | struct dwbc *dwb; | 1636 | struct dwbc *dwb; |
| 1605 | struct mcif_wb *mcif_wb; | 1637 | struct mcif_wb *mcif_wb; |
| @@ -1616,7 +1648,7 @@ static void dcn20_enable_writeback( · 10 unmodified lines | |||
| 1616 | optc->funcs->set_dwb_source(optc, wb_info->dwb_pipe_inst); | 1648 | optc->funcs->set_dwb_source(optc, wb_info->dwb_pipe_inst); |
| 1617 | /* set MCIF_WB buffer and arbitration configuration */ | 1649 | /* set MCIF_WB buffer and arbitration configuration */ |
| 1618 | mcif_wb->funcs->config_mcif_buf(mcif_wb, &wb_info->mcif_buf_params, wb_info->dwb_params.dest_height); | 1650 | mcif_wb->funcs->config_mcif_buf(mcif_wb, &wb_info->mcif_buf_params, wb_info->dwb_params.dest_height); |
| 1619 | mcif_wb->funcs->config_mcif_arb(mcif_wb, &dc->current_state->bw_ctx.bw.dcn.bw_writeback.mcif_wb_arb[wb_info->dwb_pipe_inst]); | 1651 | mcif_wb->funcs->config_mcif_arb(mcif_wb, &context->bw_ctx.bw.dcn.bw_writeback.mcif_wb_arb[wb_info->dwb_pipe_inst]); |
| 1620 | /* Enable MCIF_WB */ | 1652 | /* Enable MCIF_WB */ |
| 1621 | mcif_wb->funcs->enable_mcif(mcif_wb); | 1653 | mcif_wb->funcs->enable_mcif(mcif_wb); |
| 1622 | /* Enable DWB */ | 1654 | /* Enable DWB */ |
| @@ -2181,8 +2213,10 @@ static void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) · 558 unmodified lines | |||
| 2181 | link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, | 2213 | link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, |
| 2182 | pipe_ctx->stream_res.stream_enc->id, true); | 2214 | pipe_ctx->stream_res.stream_enc->id, true); |
| 2183 | 2215 | ||
| 2184 | if (link->dc->hwss.program_dmdata_engine) | 2216 | if (pipe_ctx->plane_state && pipe_ctx->plane_state->flip_immediate != 1) { |
| 2185 | link->dc->hwss.program_dmdata_engine(pipe_ctx); | 2217 | if (link->dc->hwss.program_dmdata_engine) |
| 2218 | link->dc->hwss.program_dmdata_engine(pipe_ctx); | ||
| 2219 | } | ||
| 2186 | 2220 | ||
| 2187 | link->dc->hwss.update_info_frame(pipe_ctx); | 2221 | link->dc->hwss.update_info_frame(pipe_ctx); |
| 2188 | 2222 | ||
| @@ -91,6 +91,13 @@ struct mpll_cfg { · 90 unmodified lines | |||
| 91 | uint32_t ref_range; | 91 | uint32_t ref_range; |
| 92 | uint32_t ref_clk; | 92 | uint32_t ref_clk; |
| 93 | bool hdmimode_enable; | 93 | bool hdmimode_enable; |
| 94 | bool sup_pre_hp; | ||
| 95 | bool dp_tx0_vergdrv_byp; | ||
| 96 | bool dp_tx1_vergdrv_byp; | ||
| 97 | bool dp_tx2_vergdrv_byp; | ||
| 98 | bool dp_tx3_vergdrv_byp; | ||
| 99 | |||
| 100 | |||
| 94 | }; | 101 | }; |
| 95 | 102 | ||
| 96 | struct dpcssys_phy_seq_cfg { | 103 | struct dpcssys_phy_seq_cfg { |
| @@ -460,7 +460,7 @@ static struct timing_generator_funcs dcn20_tg_funcs = { · 459 unmodified lines | |||
| 460 | .set_vtg_params = optc1_set_vtg_params, | 460 | .set_vtg_params = optc1_set_vtg_params, |
| 461 | .program_manual_trigger = optc2_program_manual_trigger, | 461 | .program_manual_trigger = optc2_program_manual_trigger, |
| 462 | .setup_manual_trigger = optc2_setup_manual_trigger, | 462 | .setup_manual_trigger = optc2_setup_manual_trigger, |
| 463 | .is_matching_timing = optc1_is_matching_timing | 463 | .get_hw_timing = optc1_get_hw_timing, |
| 464 | }; | 464 | }; |
| 465 | 465 | ||
| 466 | void dcn20_timing_generator_init(struct optc *optc1) | 466 | void dcn20_timing_generator_init(struct optc *optc1) |
| @@ -581,11 +581,13 @@ static const struct dcn2_dpp_registers tf_regs[] = { · 580 unmodified lines | |||
| 581 | }; | 581 | }; |
| 582 | 582 | ||
| 583 | static const struct dcn2_dpp_shift tf_shift = { | 583 | static const struct dcn2_dpp_shift tf_shift = { |
| 584 | TF_REG_LIST_SH_MASK_DCN20(__SHIFT) | 584 | TF_REG_LIST_SH_MASK_DCN20(__SHIFT), |
| 585 | TF_DEBUG_REG_LIST_SH_DCN10 | ||
| 585 | }; | 586 | }; |
| 586 | 587 | ||
| 587 | static const struct dcn2_dpp_mask tf_mask = { | 588 | static const struct dcn2_dpp_mask tf_mask = { |
| 588 | TF_REG_LIST_SH_MASK_DCN20(_MASK) | 589 | TF_REG_LIST_SH_MASK_DCN20(_MASK), |
| 590 | TF_DEBUG_REG_LIST_MASK_DCN10 | ||
| 589 | }; | 591 | }; |
| 590 | 592 | ||
| 591 | #define dwbc_regs_dcn2(id)\ | 593 | #define dwbc_regs_dcn2(id)\ |
| @@ -732,6 +734,15 @@ static const struct dcn20_vmid_mask vmid_masks = { · 140 unmodified lines | |||
| 732 | DCN20_VMID_MASK_SH_LIST(_MASK) | 734 | DCN20_VMID_MASK_SH_LIST(_MASK) |
| 733 | }; | 735 | }; |
| 734 | 736 | ||
| 737 | static const struct dce110_aux_registers_shift aux_shift = { | ||
| 738 | DCN_AUX_MASK_SH_LIST(__SHIFT) | ||
| 739 | }; | ||
| 740 | |||
| 741 | static const struct dce110_aux_registers_mask aux_mask = { | ||
| 742 | DCN_AUX_MASK_SH_LIST(_MASK) | ||
| 743 | }; | ||
| 744 | |||
| 745 | |||
| 735 | #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT | 746 | #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT |
| 736 | #define dsc_regsDCN20(id)\ | 747 | #define dsc_regsDCN20(id)\ |
| 737 | [id] = {\ | 748 | [id] = {\ |
| @@ -922,7 +933,10 @@ struct dce_aux *dcn20_aux_engine_create( · 184 unmodified lines | |||
| 922 | 933 | ||
| 923 | dce110_aux_engine_construct(aux_engine, ctx, inst, | 934 | dce110_aux_engine_construct(aux_engine, ctx, inst, |
| 924 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, | 935 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, |
| 925 | &aux_engine_regs[inst]); | 936 | &aux_engine_regs[inst], |
| 937 | &aux_mask, | ||
| 938 | &aux_shift, | ||
| 939 | ctx->dc->caps.extended_aux_timeout_support); | ||
| 926 | 940 | ||
| 927 | return &aux_engine->base; | 941 | return &aux_engine->base; |
| 928 | } | 942 | } |
| @@ -1154,6 +1168,8 @@ static const struct resource_create_funcs res_create_maximus_funcs = { · 225 unmodified lines | |||
| 1154 | .create_hwseq = dcn20_hwseq_create, | 1168 | .create_hwseq = dcn20_hwseq_create, |
| 1155 | }; | 1169 | }; |
| 1156 | 1170 | ||
| 1171 | static void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu); | ||
| 1172 | |||
| 1157 | void dcn20_clock_source_destroy(struct clock_source **clk_src) | 1173 | void dcn20_clock_source_destroy(struct clock_source **clk_src) |
| 1158 | { | 1174 | { |
| 1159 | kfree(TO_DCE110_CLK_SRC(*clk_src)); | 1175 | kfree(TO_DCE110_CLK_SRC(*clk_src)); |
| @@ -1892,7 +1908,7 @@ int dcn20_populate_dml_pipes_from_context( · 732 unmodified lines | |||
| 1892 | break; | 1908 | break; |
| 1893 | case PIXEL_ENCODING_YCBCR420: | 1909 | case PIXEL_ENCODING_YCBCR420: |
| 1894 | pipes[pipe_cnt].dout.output_format = dm_420; | 1910 | pipes[pipe_cnt].dout.output_format = dm_420; |
| 1895 | pipes[pipe_cnt].dout.output_bpp = (output_bpc * 3) / 2; | 1911 | pipes[pipe_cnt].dout.output_bpp = (output_bpc * 3.0) / 2; |
| 1896 | break; | 1912 | break; |
| 1897 | case PIXEL_ENCODING_YCBCR422: | 1913 | case PIXEL_ENCODING_YCBCR422: |
| 1898 | if (true) /* todo */ | 1914 | if (true) /* todo */ |
| @@ -1906,6 +1922,11 @@ int dcn20_populate_dml_pipes_from_context( · 7 unmodified lines | |||
| 1906 | pipes[pipe_cnt].dout.output_bpp = output_bpc * 3; | 1922 | pipes[pipe_cnt].dout.output_bpp = output_bpc * 3; |
| 1907 | } | 1923 | } |
| 1908 | 1924 | ||
| 1925 | #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT | ||
| 1926 | if (res_ctx->pipe_ctx[i].stream->timing.flags.DSC) | ||
| 1927 | pipes[pipe_cnt].dout.output_bpp = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.bits_per_pixel / 16.0; | ||
| 1928 | #endif | ||
| 1929 | |||
| 1909 | /* todo: default max for now, until there is logic reflecting this in dc*/ | 1930 | /* todo: default max for now, until there is logic reflecting this in dc*/ |
| 1910 | pipes[pipe_cnt].dout.output_bpc = 12; | 1931 | pipes[pipe_cnt].dout.output_bpc = 12; |
| 1911 | /* | 1932 | /* |
| @@ -2202,7 +2223,8 @@ static struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc, · 290 unmodified lines | |||
| 2202 | */ | 2223 | */ |
| 2203 | if (secondary_pipe == NULL) { | 2224 | if (secondary_pipe == NULL) { |
| 2204 | for (j = dc->res_pool->pipe_count - 1; j >= 0; j--) { | 2225 | for (j = dc->res_pool->pipe_count - 1; j >= 0; j--) { |
| 2205 | if (dc->current_state->res_ctx.pipe_ctx[j].top_pipe == NULL) { | 2226 | if (dc->current_state->res_ctx.pipe_ctx[j].top_pipe == NULL |
| 2227 | && dc->current_state->res_ctx.pipe_ctx[j].prev_odm_pipe == NULL) { | ||
| 2206 | preferred_pipe_idx = j; | 2228 | preferred_pipe_idx = j; |
| 2207 | 2229 | ||
| 2208 | if (res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) { | 2230 | if (res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) { |
| @@ -2555,6 +2577,10 @@ void dcn20_calculate_wm( · 346 unmodified lines | |||
| 2555 | context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | 2577 | context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; |
| 2556 | context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | 2578 | context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; |
| 2557 | context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | 2579 | context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; |
| 2580 | #if defined(CONFIG_DRM_AMD_DC_DCN2_1) | ||
| 2581 | context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | ||
| 2582 | context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | ||
| 2583 | #endif | ||
| 2558 | 2584 | ||
| 2559 | if (vlevel < 2) { | 2585 | if (vlevel < 2) { |
| 2560 | pipes[0].clks_cfg.voltage = 2; | 2586 | pipes[0].clks_cfg.voltage = 2; |
| @@ -2566,6 +2592,10 @@ void dcn20_calculate_wm( · 5 unmodified lines | |||
| 2566 | context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | 2592 | context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; |
| 2567 | context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | 2593 | context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; |
| 2568 | context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | 2594 | context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; |
| 2595 | #if defined(CONFIG_DRM_AMD_DC_DCN2_1) | ||
| 2596 | context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | ||
| 2597 | context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | ||
| 2598 | #endif | ||
| 2569 | 2599 | ||
| 2570 | if (vlevel < 3) { | 2600 | if (vlevel < 3) { |
| 2571 | pipes[0].clks_cfg.voltage = 3; | 2601 | pipes[0].clks_cfg.voltage = 3; |
| @@ -2577,6 +2607,10 @@ void dcn20_calculate_wm( · 5 unmodified lines | |||
| 2577 | context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | 2607 | context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; |
| 2578 | context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | 2608 | context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; |
| 2579 | context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | 2609 | context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; |
| 2610 | #if defined(CONFIG_DRM_AMD_DC_DCN2_1) | ||
| 2611 | context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | ||
| 2612 | context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | ||
| 2613 | #endif | ||
| 2580 | 2614 | ||
| 2581 | pipes[0].clks_cfg.voltage = vlevel; | 2615 | pipes[0].clks_cfg.voltage = vlevel; |
| 2582 | pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz; | 2616 | pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz; |
| @@ -2586,6 +2620,10 @@ void dcn20_calculate_wm( · 3 unmodified lines | |||
| 2586 | context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | 2620 | context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; |
| 2587 | context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | 2621 | context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; |
| 2588 | context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | 2622 | context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; |
| 2623 | #if defined(CONFIG_DRM_AMD_DC_DCN2_1) | ||
| 2624 | context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | ||
| 2625 | context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; | ||
| 2626 | #endif | ||
| 2589 | } | 2627 | } |
| 2590 | 2628 | ||
| 2591 | void dcn20_calculate_dlg_params( | 2629 | void dcn20_calculate_dlg_params( |
| @@ -2922,7 +2960,7 @@ bool dcn20_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool) · 330 unmodified lines | |||
| 2922 | return true; | 2960 | return true; |
| 2923 | } | 2961 | } |
| 2924 | 2962 | ||
| 2925 | struct pp_smu_funcs *dcn20_pp_smu_create(struct dc_context *ctx) | 2963 | static struct pp_smu_funcs *dcn20_pp_smu_create(struct dc_context *ctx) |
| 2926 | { | 2964 | { |
| 2927 | struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL); | 2965 | struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL); |
| 2928 | 2966 | ||
| @@ -2937,7 +2975,7 @@ struct pp_smu_funcs *dcn20_pp_smu_create(struct dc_context *ctx) · 8 unmodified lines | |||
| 2937 | return pp_smu; | 2975 | return pp_smu; |
| 2938 | } | 2976 | } |
| 2939 | 2977 | ||
| 2940 | void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu) | 2978 | static void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu) |
| 2941 | { | 2979 | { |
| 2942 | if (pp_smu && *pp_smu) { | 2980 | if (pp_smu && *pp_smu) { |
| 2943 | kfree(*pp_smu); | 2981 | kfree(*pp_smu); |
| @@ -3322,6 +3360,7 @@ static bool construct( · 378 unmodified lines | |||
| 3322 | dc->caps.post_blend_color_processing = true; | 3360 | dc->caps.post_blend_color_processing = true; |
| 3323 | dc->caps.force_dp_tps4_for_cp2520 = true; | 3361 | dc->caps.force_dp_tps4_for_cp2520 = true; |
| 3324 | dc->caps.hw_3d_lut = true; | 3362 | dc->caps.hw_3d_lut = true; |
| 3363 | dc->caps.extended_aux_timeout_support = true; | ||
| 3325 | 3364 | ||
| 3326 | if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) { | 3365 | if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) { |
| 3327 | dc->debug = debug_defaults_drv; | 3366 | dc->debug = debug_defaults_drv; |
| @@ -95,9 +95,6 @@ struct display_stream_compressor *dcn20_dsc_create( · 94 unmodified lines | |||
| 95 | struct dc_context *ctx, uint32_t inst); | 95 | struct dc_context *ctx, uint32_t inst); |
| 96 | void dcn20_dsc_destroy(struct display_stream_compressor **dsc); | 96 | void dcn20_dsc_destroy(struct display_stream_compressor **dsc); |
| 97 | 97 | ||
| 98 | struct pp_smu_funcs *dcn20_pp_smu_create(struct dc_context *ctx); | ||
| 99 | void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu); | ||
| 100 | |||
| 101 | struct hubp *dcn20_hubp_create( | 98 | struct hubp *dcn20_hubp_create( |
| 102 | struct dc_context *ctx, | 99 | struct dc_context *ctx, |
| 103 | uint32_t inst); | 100 | uint32_t inst); |
| @@ -578,6 +578,10 @@ static const struct stream_encoder_funcs dcn20_str_enc_funcs = { · 577 unmodified lines | |||
| 578 | .set_avmute = enc1_stream_encoder_set_avmute, | 578 | .set_avmute = enc1_stream_encoder_set_avmute, |
| 579 | .dig_connect_to_otg = enc1_dig_connect_to_otg, | 579 | .dig_connect_to_otg = enc1_dig_connect_to_otg, |
| 580 | .dig_source_otg = enc1_dig_source_otg, | 580 | .dig_source_otg = enc1_dig_source_otg, |
| 581 | |||
| 582 | .dp_get_pixel_format = | ||
| 583 | enc1_stream_encoder_dp_get_pixel_format, | ||
| 584 | |||
| 581 | #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT | 585 | #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT |
| 582 | .enc_read_state = enc2_read_state, | 586 | .enc_read_state = enc2_read_state, |
| 583 | .dp_set_dsc_config = enc2_dp_set_dsc_config, | 587 | .dp_set_dsc_config = enc2_dp_set_dsc_config, |
| @@ -1,7 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # Makefile for DCN21. | 2 | # Makefile for DCN21. |
| 3 | 3 | ||
| 4 | DCN21 = dcn21_hubp.o dcn21_hubbub.o dcn21_resource.o | 4 | DCN21 = dcn21_hubp.o dcn21_hubbub.o dcn21_resource.o dcn21_hwseq.o dcn21_link_encoder.o |
| 5 | 5 | ||
| 6 | ifneq ($(call cc-option, -mpreferred-stack-boundary=4),) | 6 | ifneq ($(call cc-option, -mpreferred-stack-boundary=4),) |
| 7 | cc_stack_align := -mpreferred-stack-boundary=4 | 7 | cc_stack_align := -mpreferred-stack-boundary=4 |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | |||
| 22 | * Authors: AMD | 22 | * Authors: AMD |
| 23 | * | 23 | * |
| 24 | */ | 24 | */ |
| 25 | #include <linux/delay.h> | ||
| 25 | #include "dm_services.h" | 26 | #include "dm_services.h" |
| 26 | #include "dcn20/dcn20_hubbub.h" | 27 | #include "dcn20/dcn20_hubbub.h" |
| 27 | #include "dcn21_hubbub.h" | 28 | #include "dcn21_hubbub.h" |
| @@ -51,7 +52,7 @@ · 23 unmodified lines | |||
| 51 | #ifdef NUM_VMID | 52 | #ifdef NUM_VMID |
| 52 | #undef NUM_VMID | 53 | #undef NUM_VMID |
| 53 | #endif | 54 | #endif |
| 54 | #define NUM_VMID 1 | 55 | #define NUM_VMID 16 |
| 55 | 56 | ||
| 56 | static uint32_t convert_and_clamp( | 57 | static uint32_t convert_and_clamp( |
| 57 | uint32_t wm_ns, | 58 | uint32_t wm_ns, |
| @@ -71,56 +72,76 @@ static uint32_t convert_and_clamp( · 13 unmodified lines | |||
| 71 | void dcn21_dchvm_init(struct hubbub *hubbub) | 72 | void dcn21_dchvm_init(struct hubbub *hubbub) |
| 72 | { | 73 | { |
| 73 | struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); | 74 | struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); |
| 75 | uint32_t riommu_active; | ||
| 76 | int i; | ||
| 74 | 77 | ||
| 75 | //Init DCHVM block | 78 | //Init DCHVM block |
| 76 | REG_UPDATE(DCHVM_CTRL0, HOSTVM_INIT_REQ, 1); | 79 | REG_UPDATE(DCHVM_CTRL0, HOSTVM_INIT_REQ, 1); |
| 77 | 80 | ||
| 78 | //Poll until RIOMMU_ACTIVE = 1 | 81 | //Poll until RIOMMU_ACTIVE = 1 |
| 79 | //TODO: Figure out interval us and retry count | 82 | for (i = 0; i < 100; i++) { |
| 80 | REG_WAIT(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, 1, 5, 100); | 83 | REG_GET(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, &riommu_active); |
| 81 | 84 | ||
| 82 | //Reflect the power status of DCHUBBUB | 85 | if (riommu_active) |
| 83 | REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1); | 86 | break; |
| 87 | else | ||
| 88 | udelay(5); | ||
| 89 | } | ||
| 90 | |||
| 91 | if (riommu_active) { | ||
| 92 | //Reflect the power status of DCHUBBUB | ||
| 93 | REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1); | ||
| 84 | 94 | ||
| 85 | //Start rIOMMU prefetching | 95 | //Start rIOMMU prefetching |
| 86 | REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1); | 96 | REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1); |
| 87 | 97 | ||
| 88 | // Enable dynamic clock gating | 98 | // Enable dynamic clock gating |
| 89 | REG_UPDATE_4(DCHVM_CLK_CTRL, | 99 | REG_UPDATE_4(DCHVM_CLK_CTRL, |
| 90 | HVM_DISPCLK_R_GATE_DIS, 0, | 100 | HVM_DISPCLK_R_GATE_DIS, 0, |
| 91 | HVM_DISPCLK_G_GATE_DIS, 0, | 101 | HVM_DISPCLK_G_GATE_DIS, 0, |
| 92 | HVM_DCFCLK_R_GATE_DIS, 0, | 102 | HVM_DCFCLK_R_GATE_DIS, 0, |
| 93 | HVM_DCFCLK_G_GATE_DIS, 0); | 103 | HVM_DCFCLK_G_GATE_DIS, 0); |
| 94 | 104 | ||
| 95 | //Poll until HOSTVM_PREFETCH_DONE = 1 | 105 | //Poll until HOSTVM_PREFETCH_DONE = 1 |
| 96 | //TODO: Figure out interval us and retry count | 106 | REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100); |
| 97 | REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100); | 107 | } |
| 98 | } | 108 | } |
| 99 | 109 | ||
| 100 | static int hubbub21_init_dchub(struct hubbub *hubbub, | 110 | int hubbub21_init_dchub(struct hubbub *hubbub, |
| 101 | struct dcn_hubbub_phys_addr_config *pa_config) | 111 | struct dcn_hubbub_phys_addr_config *pa_config) |
| 102 | { | 112 | { |
| 103 | struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); | 113 | struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); |
| 114 | struct dcn_vmid_page_table_config phys_config; | ||
| 104 | 115 | ||
| 105 | REG_SET(DCN_VM_FB_LOCATION_BASE, 0, | 116 | REG_SET(DCN_VM_FB_LOCATION_BASE, 0, |
| 106 | FB_BASE, pa_config->system_aperture.fb_base); | 117 | FB_BASE, pa_config->system_aperture.fb_base >> 24); |
| 107 | REG_SET(DCN_VM_FB_LOCATION_TOP, 0, | 118 | REG_SET(DCN_VM_FB_LOCATION_TOP, 0, |
| 108 | FB_TOP, pa_config->system_aperture.fb_top); | 119 | FB_TOP, pa_config->system_aperture.fb_top >> 24); |
| 109 | REG_SET(DCN_VM_FB_OFFSET, 0, | 120 | REG_SET(DCN_VM_FB_OFFSET, 0, |
| 110 | FB_OFFSET, pa_config->system_aperture.fb_offset); | 121 | FB_OFFSET, pa_config->system_aperture.fb_offset >> 24); |
| 111 | REG_SET(DCN_VM_AGP_BOT, 0, | 122 | REG_SET(DCN_VM_AGP_BOT, 0, |
| 112 | AGP_BOT, pa_config->system_aperture.agp_bot); | 123 | AGP_BOT, pa_config->system_aperture.agp_bot >> 24); |
| 113 | REG_SET(DCN_VM_AGP_TOP, 0, | 124 | REG_SET(DCN_VM_AGP_TOP, 0, |
| 114 | AGP_TOP, pa_config->system_aperture.agp_top); | 125 | AGP_TOP, pa_config->system_aperture.agp_top >> 24); |
| 115 | REG_SET(DCN_VM_AGP_BASE, 0, | 126 | REG_SET(DCN_VM_AGP_BASE, 0, |
| 116 | AGP_BASE, pa_config->system_aperture.agp_base); | 127 | AGP_BASE, pa_config->system_aperture.agp_base >> 24); |
| 128 | |||
| 129 | if (pa_config->gart_config.page_table_start_addr != pa_config->gart_config.page_table_end_addr) { | ||
| 130 | phys_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr >> 12; | ||
| 131 | phys_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr >> 12; | ||
| 132 | phys_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr | 1; //Note: hack | ||
| 133 | phys_config.depth = 0; | ||
| 134 | phys_config.block_size = 0; | ||
| 135 | // Init VMID 0 based on PA config | ||
| 136 | dcn20_vmid_setup(&hubbub1->vmid[0], &phys_config); | ||
| 137 | } | ||
| 117 | 138 | ||
| 118 | dcn21_dchvm_init(hubbub); | 139 | dcn21_dchvm_init(hubbub); |
| 119 | 140 | ||
| 120 | return NUM_VMID; | 141 | return NUM_VMID; |
| 121 | } | 142 | } |
| 122 | 143 | ||
| 123 | static void hubbub21_program_urgent_watermarks( | 144 | void hubbub21_program_urgent_watermarks( |
| 124 | struct hubbub *hubbub, | 145 | struct hubbub *hubbub, |
| 125 | struct dcn_watermark_set *watermarks, | 146 | struct dcn_watermark_set *watermarks, |
| 126 | unsigned int refclk_mhz, | 147 | unsigned int refclk_mhz, |
| @@ -160,6 +181,13 @@ static void hubbub21_program_urgent_watermarks( · 33 unmodified lines | |||
| 160 | REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, 0, | 181 | REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, 0, |
| 161 | DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, watermarks->a.frac_urg_bw_nom); | 182 | DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, watermarks->a.frac_urg_bw_nom); |
| 162 | } | 183 | } |
| 184 | if (safe_to_lower || watermarks->a.urgent_latency_ns > hubbub1->watermarks.a.urgent_latency_ns) { | ||
| 185 | hubbub1->watermarks.a.urgent_latency_ns = watermarks->a.urgent_latency_ns; | ||
| 186 | prog_wm_value = convert_and_clamp(watermarks->a.urgent_latency_ns, | ||
| 187 | refclk_mhz, 0x1fffff); | ||
| 188 | REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, 0, | ||
| 189 | DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, prog_wm_value); | ||
| 190 | } | ||
| 163 | 191 | ||
| 164 | /* clock state B */ | 192 | /* clock state B */ |
| 165 | if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) { | 193 | if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) { |
| @@ -192,6 +220,14 @@ static void hubbub21_program_urgent_watermarks( · 26 unmodified lines | |||
| 192 | DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, watermarks->a.frac_urg_bw_nom); | 220 | DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, watermarks->a.frac_urg_bw_nom); |
| 193 | } | 221 | } |
| 194 | 222 | ||
| 223 | if (safe_to_lower || watermarks->b.urgent_latency_ns > hubbub1->watermarks.b.urgent_latency_ns) { | ||
| 224 | hubbub1->watermarks.b.urgent_latency_ns = watermarks->b.urgent_latency_ns; | ||
| 225 | prog_wm_value = convert_and_clamp(watermarks->b.urgent_latency_ns, | ||
| 226 | refclk_mhz, 0x1fffff); | ||
| 227 | REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, 0, | ||
| 228 | DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, prog_wm_value); | ||
| 229 | } | ||
| 230 | |||
| 195 | /* clock state C */ | 231 | /* clock state C */ |
| 196 | if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) { | 232 | if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) { |
| 197 | hubbub1->watermarks.c.urgent_ns = watermarks->c.urgent_ns; | 233 | hubbub1->watermarks.c.urgent_ns = watermarks->c.urgent_ns; |
| @@ -223,6 +259,14 @@ static void hubbub21_program_urgent_watermarks( · 25 unmodified lines | |||
| 223 | DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, watermarks->a.frac_urg_bw_nom); | 259 | DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, watermarks->a.frac_urg_bw_nom); |
| 224 | } | 260 | } |
| 225 | 261 | ||
| 262 | if (safe_to_lower || watermarks->c.urgent_latency_ns > hubbub1->watermarks.c.urgent_latency_ns) { | ||
| 263 | hubbub1->watermarks.c.urgent_latency_ns = watermarks->c.urgent_latency_ns; | ||
| 264 | prog_wm_value = convert_and_clamp(watermarks->c.urgent_latency_ns, | ||
| 265 | refclk_mhz, 0x1fffff); | ||
| 266 | REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, 0, | ||
| 267 | DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, prog_wm_value); | ||
| 268 | } | ||
| 269 | |||
| 226 | /* clock state D */ | 270 | /* clock state D */ |
| 227 | if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) { | 271 | if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) { |
| 228 | hubbub1->watermarks.d.urgent_ns = watermarks->d.urgent_ns; | 272 | hubbub1->watermarks.d.urgent_ns = watermarks->d.urgent_ns; |
| @@ -253,9 +297,17 @@ static void hubbub21_program_urgent_watermarks( · 24 unmodified lines | |||
| 253 | REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, 0, | 297 | REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, 0, |
| 254 | DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, watermarks->a.frac_urg_bw_nom); | 298 | DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, watermarks->a.frac_urg_bw_nom); |
| 255 | } | 299 | } |
| 300 | |||
| 301 | if (safe_to_lower || watermarks->d.urgent_latency_ns > hubbub1->watermarks.d.urgent_latency_ns) { | ||
| 302 | hubbub1->watermarks.d.urgent_latency_ns = watermarks->d.urgent_latency_ns; | ||
| 303 | prog_wm_value = convert_and_clamp(watermarks->d.urgent_latency_ns, | ||
| 304 | refclk_mhz, 0x1fffff); | ||
| 305 | REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, 0, | ||
| 306 | DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, prog_wm_value); | ||
| 307 | } | ||
| 256 | } | 308 | } |
| 257 | 309 | ||
| 258 | static void hubbub21_program_stutter_watermarks( | 310 | void hubbub21_program_stutter_watermarks( |
| 259 | struct hubbub *hubbub, | 311 | struct hubbub *hubbub, |
| 260 | struct dcn_watermark_set *watermarks, | 312 | struct dcn_watermark_set *watermarks, |
| 261 | unsigned int refclk_mhz, | 313 | unsigned int refclk_mhz, |
| @@ -389,7 +441,7 @@ static void hubbub21_program_stutter_watermarks( · 127 unmodified lines | |||
| 389 | } | 441 | } |
| 390 | } | 442 | } |
| 391 | 443 | ||
| 392 | static void hubbub21_program_pstate_watermarks( | 444 | void hubbub21_program_pstate_watermarks( |
| 393 | struct hubbub *hubbub, | 445 | struct hubbub *hubbub, |
| 394 | struct dcn_watermark_set *watermarks, | 446 | struct dcn_watermark_set *watermarks, |
| 395 | unsigned int refclk_mhz, | 447 | unsigned int refclk_mhz, |
| @@ -564,17 +616,26 @@ void hubbub21_wm_read_state(struct hubbub *hubbub, · 168 unmodified lines | |||
| 564 | DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, &s->dram_clk_chanage); | 616 | DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, &s->dram_clk_chanage); |
| 565 | } | 617 | } |
| 566 | 618 | ||
| 619 | void hubbub21_apply_DEDCN21_147_wa(struct hubbub *hubbub) | ||
| 620 | { | ||
| 621 | struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); | ||
| 622 | uint32_t prog_wm_value; | ||
| 623 | |||
| 624 | prog_wm_value = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A); | ||
| 625 | REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); | ||
| 626 | } | ||
| 567 | 627 | ||
| 568 | static const struct hubbub_funcs hubbub21_funcs = { | 628 | static const struct hubbub_funcs hubbub21_funcs = { |
| 569 | .update_dchub = hubbub2_update_dchub, | 629 | .update_dchub = hubbub2_update_dchub, |
| 570 | .init_dchub_sys_ctx = hubbub21_init_dchub, | 630 | .init_dchub_sys_ctx = hubbub21_init_dchub, |
| 571 | .init_vm_ctx = NULL, | 631 | .init_vm_ctx = hubbub2_init_vm_ctx, |
| 572 | .dcc_support_swizzle = hubbub2_dcc_support_swizzle, | 632 | .dcc_support_swizzle = hubbub2_dcc_support_swizzle, |
| 573 | .dcc_support_pixel_format = hubbub2_dcc_support_pixel_format, | 633 | .dcc_support_pixel_format = hubbub2_dcc_support_pixel_format, |
| 574 | .get_dcc_compression_cap = hubbub2_get_dcc_compression_cap, | 634 | .get_dcc_compression_cap = hubbub2_get_dcc_compression_cap, |
| 575 | .wm_read_state = hubbub21_wm_read_state, | 635 | .wm_read_state = hubbub21_wm_read_state, |
| 576 | .get_dchub_ref_freq = hubbub2_get_dchub_ref_freq, | 636 | .get_dchub_ref_freq = hubbub2_get_dchub_ref_freq, |
| 577 | .program_watermarks = hubbub21_program_watermarks, | 637 | .program_watermarks = hubbub21_program_watermarks, |
| 638 | .apply_DEDCN21_147_wa = hubbub21_apply_DEDCN21_147_wa, | ||
| 578 | }; | 639 | }; |
| 579 | 640 | ||
| 580 | void hubbub21_construct(struct dcn20_hubbub *hubbub, | 641 | void hubbub21_construct(struct dcn20_hubbub *hubbub, |
| @@ -592,4 +653,5 @@ void hubbub21_construct(struct dcn20_hubbub *hubbub, · 11 unmodified lines | |||
| 592 | hubbub->masks = hubbub_mask; | 653 | hubbub->masks = hubbub_mask; |
| 593 | 654 | ||
| 594 | hubbub->debug_test_index_pstate = 0xB; | 655 | hubbub->debug_test_index_pstate = 0xB; |
| 656 | hubbub->detile_buf_size = 164 * 1024; /* 164KB for DCN2.0 */ | ||
| 595 | } | 657 | } |
| @@ -36,6 +36,10 @@ · 35 unmodified lines | |||
| 36 | SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B),\ | 36 | SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B),\ |
| 37 | SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C),\ | 37 | SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C),\ |
| 38 | SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D),\ | 38 | SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D),\ |
| 39 | SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A),\ | ||
| 40 | SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B),\ | ||
| 41 | SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C),\ | ||
| 42 | SR(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D),\ | ||
| 39 | SR(DCHUBBUB_ARB_HOSTVM_CNTL), \ | 43 | SR(DCHUBBUB_ARB_HOSTVM_CNTL), \ |
| 40 | SR(DCHVM_CTRL0), \ | 44 | SR(DCHVM_CTRL0), \ |
| 41 | SR(DCHVM_MEM_CTRL), \ | 45 | SR(DCHVM_MEM_CTRL), \ |
| @@ -44,16 +48,9 @@ · 2 unmodified lines | |||
| 44 | SR(DCHVM_RIOMMU_STAT0) | 48 | SR(DCHVM_RIOMMU_STAT0) |
| 45 | 49 | ||
| 46 | #define HUBBUB_REG_LIST_DCN21()\ | 50 | #define HUBBUB_REG_LIST_DCN21()\ |
| 47 | HUBBUB_REG_LIST_DCN_COMMON(), \ | 51 | HUBBUB_REG_LIST_DCN20_COMMON(), \ |
| 48 | HUBBUB_SR_WATERMARK_REG_LIST(), \ | 52 | HUBBUB_SR_WATERMARK_REG_LIST(), \ |
| 49 | HUBBUB_HVM_REG_LIST(), \ | 53 | HUBBUB_HVM_REG_LIST() |
| 50 | SR(DCHUBBUB_CRC_CTRL), \ | ||
| 51 | SR(DCN_VM_FB_LOCATION_BASE),\ | ||
| 52 | SR(DCN_VM_FB_LOCATION_TOP),\ | ||
| 53 | SR(DCN_VM_FB_OFFSET),\ | ||
| 54 | SR(DCN_VM_AGP_BOT),\ | ||
| 55 | SR(DCN_VM_AGP_TOP),\ | ||
| 56 | SR(DCN_VM_AGP_BASE) | ||
| 57 | 54 | ||
| 58 | #define HUBBUB_MASK_SH_LIST_HVM(mask_sh) \ | 55 | #define HUBBUB_MASK_SH_LIST_HVM(mask_sh) \ |
| 59 | HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD, mask_sh), \ | 56 | HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD, mask_sh), \ |
| @@ -102,7 +99,7 @@ · 42 unmodified lines | |||
| 102 | HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, mask_sh) | 99 | HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, mask_sh) |
| 103 | 100 | ||
| 104 | #define HUBBUB_MASK_SH_LIST_DCN21(mask_sh)\ | 101 | #define HUBBUB_MASK_SH_LIST_DCN21(mask_sh)\ |
| 105 | HUBBUB_MASK_SH_LIST_HVM(mask_sh),\ | 102 | HUBBUB_MASK_SH_LIST_HVM(mask_sh), \ |
| 106 | HUBBUB_MASK_SH_LIST_DCN_COMMON(mask_sh), \ | 103 | HUBBUB_MASK_SH_LIST_DCN_COMMON(mask_sh), \ |
| 107 | HUBBUB_MASK_SH_LIST_STUTTER(mask_sh), \ | 104 | HUBBUB_MASK_SH_LIST_STUTTER(mask_sh), \ |
| 108 | HUBBUB_SF(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \ | 105 | HUBBUB_SF(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \ |
| @@ -114,11 +111,28 @@ · 5 unmodified lines | |||
| 114 | HUBBUB_SF(DCN_VM_AGP_BASE, AGP_BASE, mask_sh) | 111 | HUBBUB_SF(DCN_VM_AGP_BASE, AGP_BASE, mask_sh) |
| 115 | 112 | ||
| 116 | void dcn21_dchvm_init(struct hubbub *hubbub); | 113 | void dcn21_dchvm_init(struct hubbub *hubbub); |
| 114 | int hubbub21_init_dchub(struct hubbub *hubbub, | ||
| 115 | struct dcn_hubbub_phys_addr_config *pa_config); | ||
| 117 | void hubbub21_program_watermarks( | 116 | void hubbub21_program_watermarks( |
| 118 | struct hubbub *hubbub, | 117 | struct hubbub *hubbub, |
| 119 | struct dcn_watermark_set *watermarks, | 118 | struct dcn_watermark_set *watermarks, |
| 120 | unsigned int refclk_mhz, | 119 | unsigned int refclk_mhz, |
| 121 | bool safe_to_lower); | 120 | bool safe_to_lower); |
| 121 | void hubbub21_program_urgent_watermarks( | ||
| 122 | struct hubbub *hubbub, | ||
| 123 | struct dcn_watermark_set *watermarks, | ||
| 124 | unsigned int refclk_mhz, | ||
| 125 | bool safe_to_lower); | ||
| 126 | void hubbub21_program_stutter_watermarks( | ||
| 127 | struct hubbub *hubbub, | ||
| 128 | struct dcn_watermark_set *watermarks, | ||
| 129 | unsigned int refclk_mhz, | ||
| 130 | bool safe_to_lower); | ||
| 131 | void hubbub21_program_pstate_watermarks( | ||
| 132 | struct hubbub *hubbub, | ||
| 133 | struct dcn_watermark_set *watermarks, | ||
| 134 | unsigned int refclk_mhz, | ||
| 135 | bool safe_to_lower); | ||
| 122 | 136 | ||
| 123 | void hubbub21_wm_read_state(struct hubbub *hubbub, | 137 | void hubbub21_wm_read_state(struct hubbub *hubbub, |
| 124 | struct dcn_hubbub_wm *wm); | 138 | struct dcn_hubbub_wm *wm); |
| @@ -22,6 +22,8 @@ · 21 unmodified lines | |||
| 22 | * Authors: AMD | 22 | * Authors: AMD |
| 23 | * | 23 | * |
| 24 | */ | 24 | */ |
| 25 | |||
| 26 | #include "dcn10/dcn10_hubp.h" | ||
| 25 | #include "dcn21_hubp.h" | 27 | #include "dcn21_hubp.h" |
| 26 | 28 | ||
| 27 | #include "dm_services.h" | 29 | #include "dm_services.h" |
| @@ -202,7 +204,7 @@ static struct hubp_funcs dcn21_hubp_funcs = { · 174 unmodified lines | |||
| 202 | .hubp_enable_tripleBuffer = hubp2_enable_triplebuffer, | 204 | .hubp_enable_tripleBuffer = hubp2_enable_triplebuffer, |
| 203 | .hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled, | 205 | .hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled, |
| 204 | .hubp_program_surface_flip_and_addr = hubp2_program_surface_flip_and_addr, | 206 | .hubp_program_surface_flip_and_addr = hubp2_program_surface_flip_and_addr, |
| 205 | .hubp_program_surface_config = hubp2_program_surface_config, | 207 | .hubp_program_surface_config = hubp1_program_surface_config, |
| 206 | .hubp_is_flip_pending = hubp1_is_flip_pending, | 208 | .hubp_is_flip_pending = hubp1_is_flip_pending, |
| 207 | .hubp_setup = hubp21_setup, | 209 | .hubp_setup = hubp21_setup, |
| 208 | .hubp_setup_interdependent = hubp2_setup_interdependent, | 210 | .hubp_setup_interdependent = hubp2_setup_interdependent, |
| @@ -0,0 +1,122 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2016 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 | * Authors: AMD | ||
| 23 | * | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include "dm_services.h" | ||
| 27 | #include "dm_helpers.h" | ||
| 28 | #include "core_types.h" | ||
| 29 | #include "resource.h" | ||
| 30 | #include "dce/dce_hwseq.h" | ||
| 31 | #include "dcn20/dcn20_hwseq.h" | ||
| 32 | #include "vmid.h" | ||
| 33 | #include "reg_helper.h" | ||
| 34 | #include "hw/clk_mgr.h" | ||
| 35 | |||
| 36 | |||
| 37 | #define DC_LOGGER_INIT(logger) | ||
| 38 | |||
| 39 | #define CTX \ | ||
| 40 | hws->ctx | ||
| 41 | #define REG(reg)\ | ||
| 42 | hws->regs->reg | ||
| 43 | |||
| 44 | #undef FN | ||
| 45 | #define FN(reg_name, field_name) \ | ||
| 46 | hws->shifts->field_name, hws->masks->field_name | ||
| 47 | |||
| 48 | /* Temporary read settings, future will get values from kmd directly */ | ||
| 49 | static void mmhub_update_page_table_config(struct dcn_hubbub_phys_addr_config *config, | ||
| 50 | struct dce_hwseq *hws) | ||
| 51 | { | ||
| 52 | uint32_t page_table_base_hi; | ||
| 53 | uint32_t page_table_base_lo; | ||
| 54 | |||
| 55 | REG_GET(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, | ||
| 56 | PAGE_DIRECTORY_ENTRY_HI32, &page_table_base_hi); | ||
| 57 | REG_GET(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, | ||
| 58 | PAGE_DIRECTORY_ENTRY_LO32, &page_table_base_lo); | ||
| 59 | |||
| 60 | config->gart_config.page_table_base_addr = ((uint64_t)page_table_base_hi << 32) | page_table_base_lo; | ||
| 61 | |||
| 62 | } | ||
| 63 | |||
| 64 | static int dcn21_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_space_config *pa_config) | ||
| 65 | { | ||
| 66 | struct dcn_hubbub_phys_addr_config config; | ||
| 67 | |||
| 68 | config.system_aperture.fb_top = pa_config->system_aperture.fb_top; | ||
| 69 | config.system_aperture.fb_offset = pa_config->system_aperture.fb_offset; | ||
| 70 | config.system_aperture.fb_base = pa_config->system_aperture.fb_base; | ||
| 71 | config.system_aperture.agp_top = pa_config->system_aperture.agp_top; | ||
| 72 | config.system_aperture.agp_bot = pa_config->system_aperture.agp_bot; | ||
| 73 | config.system_aperture.agp_base = pa_config->system_aperture.agp_base; | ||
| 74 | config.gart_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr; | ||
| 75 | config.gart_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr; | ||
| 76 | config.gart_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr; | ||
| 77 | |||
| 78 | mmhub_update_page_table_config(&config, hws); | ||
| 79 | |||
| 80 | return dc->res_pool->hubbub->funcs->init_dchub_sys_ctx(dc->res_pool->hubbub, &config); | ||
| 81 | } | ||
| 82 | |||
| 83 | // work around for Renoir s0i3, if register is programmed, bypass golden init. | ||
| 84 | |||
| 85 | static bool dcn21_s0i3_golden_init_wa(struct dc *dc) | ||
| 86 | { | ||
| 87 | struct dce_hwseq *hws = dc->hwseq; | ||
| 88 | uint32_t value = 0; | ||
| 89 | |||
| 90 | value = REG_READ(MICROSECOND_TIME_BASE_DIV); | ||
| 91 | |||
| 92 | return value != 0x00120464; | ||
| 93 | } | ||
| 94 | |||
| 95 | void dcn21_exit_optimized_pwr_state( | ||
| 96 | const struct dc *dc, | ||
| 97 | struct dc_state *context) | ||
| 98 | { | ||
| 99 | dc->clk_mgr->funcs->update_clocks( | ||
| 100 | dc->clk_mgr, | ||
| 101 | context, | ||
| 102 | false); | ||
| 103 | } | ||
| 104 | |||
| 105 | void dcn21_optimize_pwr_state( | ||
| 106 | const struct dc *dc, | ||
| 107 | struct dc_state *context) | ||
| 108 | { | ||
| 109 | dc->clk_mgr->funcs->update_clocks( | ||
| 110 | dc->clk_mgr, | ||
| 111 | context, | ||
| 112 | true); | ||
| 113 | } | ||
| 114 | |||
| 115 | void dcn21_hw_sequencer_construct(struct dc *dc) | ||
| 116 | { | ||
| 117 | dcn20_hw_sequencer_construct(dc); | ||
| 118 | dc->hwss.init_sys_ctx = dcn21_init_sys_ctx; | ||
| 119 | dc->hwss.s0i3_golden_init_wa = dcn21_s0i3_golden_init_wa; | ||
| 120 | dc->hwss.optimize_pwr_state = dcn21_optimize_pwr_state; | ||
| 121 | dc->hwss.exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state; | ||
| 122 | } | ||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2016 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 | * Authors: AMD | ||
| 23 | * | ||
| 24 | */ | ||
| 25 | |||
| 26 | #ifndef __DC_HWSS_DCN21_H__ | ||
| 27 | #define __DC_HWSS_DCN21_H__ | ||
| 28 | |||
| 29 | struct dc; | ||
| 30 | |||
| 31 | void dcn21_hw_sequencer_construct(struct dc *dc); | ||
| 32 | |||
| 33 | #endif /* __DC_HWSS_DCN21_H__ */ | ||
| @@ -0,0 +1,470 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2012-15 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 | * Authors: AMD | ||
| 23 | * | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include "reg_helper.h" | ||
| 27 | |||
| 28 | #include <linux/delay.h> | ||
| 29 | #include "core_types.h" | ||
| 30 | #include "link_encoder.h" | ||
| 31 | #include "dcn21_link_encoder.h" | ||
| 32 | #include "stream_encoder.h" | ||
| 33 | |||
| 34 | #include "i2caux_interface.h" | ||
| 35 | #include "dc_bios_types.h" | ||
| 36 | |||
| 37 | #include "gpio_service_interface.h" | ||
| 38 | |||
| 39 | #define CTX \ | ||
| 40 | enc10->base.ctx | ||
| 41 | #define DC_LOGGER \ | ||
| 42 | enc10->base.ctx->logger | ||
| 43 | |||
| 44 | #define REG(reg)\ | ||
| 45 | (enc10->link_regs->reg) | ||
| 46 | |||
| 47 | #undef FN | ||
| 48 | #define FN(reg_name, field_name) \ | ||
| 49 | enc10->link_shift->field_name, enc10->link_mask->field_name | ||
| 50 | |||
| 51 | #define IND_REG(index) \ | ||
| 52 | (enc10->link_regs->index) | ||
| 53 | |||
| 54 | static struct mpll_cfg dcn21_mpll_cfg_ref[] = { | ||
| 55 | // RBR | ||
| 56 | { | ||
| 57 | .hdmimode_enable = 0, | ||
| 58 | .ref_range = 1, | ||
| 59 | .ref_clk_mpllb_div = 1, | ||
| 60 | .mpllb_ssc_en = 1, | ||
| 61 | .mpllb_div5_clk_en = 1, | ||
| 62 | .mpllb_multiplier = 238, | ||
| 63 | .mpllb_fracn_en = 0, | ||
| 64 | .mpllb_fracn_quot = 0, | ||
| 65 | .mpllb_fracn_rem = 0, | ||
| 66 | .mpllb_fracn_den = 1, | ||
| 67 | .mpllb_ssc_up_spread = 0, | ||
| 68 | .mpllb_ssc_peak = 44237, | ||
| 69 | .mpllb_ssc_stepsize = 59454, | ||
| 70 | .mpllb_div_clk_en = 0, | ||
| 71 | .mpllb_div_multiplier = 0, | ||
| 72 | .mpllb_hdmi_div = 0, | ||
| 73 | .mpllb_tx_clk_div = 2, | ||
| 74 | .tx_vboost_lvl = 5, | ||
| 75 | .mpllb_pmix_en = 1, | ||
| 76 | .mpllb_word_div2_en = 0, | ||
| 77 | .mpllb_ana_v2i = 2, | ||
| 78 | .mpllb_ana_freq_vco = 2, | ||
| 79 | .mpllb_ana_cp_int = 9, | ||
| 80 | .mpllb_ana_cp_prop = 15, | ||
| 81 | .hdmi_pixel_clk_div = 0, | ||
| 82 | }, | ||
| 83 | // HBR | ||
| 84 | { | ||
| 85 | .hdmimode_enable = 0, | ||
| 86 | .ref_range = 1, | ||
| 87 | .ref_clk_mpllb_div = 1, | ||
| 88 | .mpllb_ssc_en = 1, | ||
| 89 | .mpllb_div5_clk_en = 1, | ||
| 90 | .mpllb_multiplier = 192, | ||
| 91 | .mpllb_fracn_en = 1, | ||
| 92 | .mpllb_fracn_quot = 32768, | ||
| 93 | .mpllb_fracn_rem = 0, | ||
| 94 | .mpllb_fracn_den = 1, | ||
| 95 | .mpllb_ssc_up_spread = 0, | ||
| 96 | .mpllb_ssc_peak = 36864, | ||
| 97 | .mpllb_ssc_stepsize = 49545, | ||
| 98 | .mpllb_div_clk_en = 0, | ||
| 99 | .mpllb_div_multiplier = 0, | ||
| 100 | .mpllb_hdmi_div = 0, | ||
| 101 | .mpllb_tx_clk_div = 1, | ||
| 102 | .tx_vboost_lvl = 5, | ||
| 103 | .mpllb_pmix_en = 1, | ||
| 104 | .mpllb_word_div2_en = 0, | ||
| 105 | .mpllb_ana_v2i = 2, | ||
| 106 | .mpllb_ana_freq_vco = 3, | ||
| 107 | .mpllb_ana_cp_int = 9, | ||
| 108 | .mpllb_ana_cp_prop = 15, | ||
| 109 | .hdmi_pixel_clk_div = 0, | ||
| 110 | }, | ||
| 111 | //HBR2 | ||
| 112 | { | ||
| 113 | .hdmimode_enable = 0, | ||
| 114 | .ref_range = 1, | ||
| 115 | .ref_clk_mpllb_div = 1, | ||
| 116 | .mpllb_ssc_en = 1, | ||
| 117 | .mpllb_div5_clk_en = 1, | ||
| 118 | .mpllb_multiplier = 192, | ||
| 119 | .mpllb_fracn_en = 1, | ||
| 120 | .mpllb_fracn_quot = 32768, | ||
| 121 | .mpllb_fracn_rem = 0, | ||
| 122 | .mpllb_fracn_den = 1, | ||
| 123 | .mpllb_ssc_up_spread = 0, | ||
| 124 | .mpllb_ssc_peak = 36864, | ||
| 125 | .mpllb_ssc_stepsize = 49545, | ||
| 126 | .mpllb_div_clk_en = 0, | ||
| 127 | .mpllb_div_multiplier = 0, | ||
| 128 | .mpllb_hdmi_div = 0, | ||
| 129 | .mpllb_tx_clk_div = 0, | ||
| 130 | .tx_vboost_lvl = 5, | ||
| 131 | .mpllb_pmix_en = 1, | ||
| 132 | .mpllb_word_div2_en = 0, | ||
| 133 | .mpllb_ana_v2i = 2, | ||
| 134 | .mpllb_ana_freq_vco = 3, | ||
| 135 | .mpllb_ana_cp_int = 9, | ||
| 136 | .mpllb_ana_cp_prop = 15, | ||
| 137 | .hdmi_pixel_clk_div = 0, | ||
| 138 | }, | ||
| 139 | //HBR3 | ||
| 140 | { | ||
| 141 | .hdmimode_enable = 0, | ||
| 142 | .ref_range = 1, | ||
| 143 | .ref_clk_mpllb_div = 1, | ||
| 144 | .mpllb_ssc_en = 1, | ||
| 145 | .mpllb_div5_clk_en = 1, | ||
| 146 | .mpllb_multiplier = 304, | ||
| 147 | .mpllb_fracn_en = 1, | ||
| 148 | .mpllb_fracn_quot = 49152, | ||
| 149 | .mpllb_fracn_rem = 0, | ||
| 150 | .mpllb_fracn_den = 1, | ||
| 151 | .mpllb_ssc_up_spread = 0, | ||
| 152 | .mpllb_ssc_peak = 55296, | ||
| 153 | .mpllb_ssc_stepsize = 74318, | ||
| 154 | .mpllb_div_clk_en = 0, | ||
| 155 | .mpllb_div_multiplier = 0, | ||
| 156 | .mpllb_hdmi_div = 0, | ||
| 157 | .mpllb_tx_clk_div = 0, | ||
| 158 | .tx_vboost_lvl = 5, | ||
| 159 | .mpllb_pmix_en = 1, | ||
| 160 | .mpllb_word_div2_en = 0, | ||
| 161 | .mpllb_ana_v2i = 2, | ||
| 162 | .mpllb_ana_freq_vco = 1, | ||
| 163 | .mpllb_ana_cp_int = 7, | ||
| 164 | .mpllb_ana_cp_prop = 16, | ||
| 165 | .hdmi_pixel_clk_div = 0, | ||
| 166 | }, | ||
| 167 | }; | ||
| 168 | |||
| 169 | |||
| 170 | static bool update_cfg_data( | ||
| 171 | struct dcn10_link_encoder *enc10, | ||
| 172 | const struct dc_link_settings *link_settings, | ||
| 173 | struct dpcssys_phy_seq_cfg *cfg) | ||
| 174 | { | ||
| 175 | int i; | ||
| 176 | |||
| 177 | cfg->load_sram_fw = false; | ||
| 178 | cfg->use_calibration_setting = true; | ||
| 179 | |||
| 180 | //TODO: need to implement a proper lane mapping for Renoir. | ||
| 181 | for (i = 0; i < 4; i++) | ||
| 182 | cfg->lane_en[i] = true; | ||
| 183 | |||
| 184 | switch (link_settings->link_rate) { | ||
| 185 | case LINK_RATE_LOW: | ||
| 186 | cfg->mpll_cfg = dcn21_mpll_cfg_ref[0]; | ||
| 187 | break; | ||
| 188 | case LINK_RATE_HIGH: | ||
| 189 | cfg->mpll_cfg = dcn21_mpll_cfg_ref[1]; | ||
| 190 | break; | ||
| 191 | case LINK_RATE_HIGH2: | ||
| 192 | cfg->mpll_cfg = dcn21_mpll_cfg_ref[2]; | ||
| 193 | break; | ||
| 194 | case LINK_RATE_HIGH3: | ||
| 195 | cfg->mpll_cfg = dcn21_mpll_cfg_ref[3]; | ||
| 196 | break; | ||
| 197 | default: | ||
| 198 | DC_LOG_ERROR("%s: No supported link rate found %X!\n", | ||
| 199 | __func__, link_settings->link_rate); | ||
| 200 | return false; | ||
| 201 | } | ||
| 202 | |||
| 203 | return true; | ||
| 204 | } | ||
| 205 | |||
| 206 | void dcn21_link_encoder_get_max_link_cap(struct link_encoder *enc, | ||
| 207 | struct dc_link_settings *link_settings) | ||
| 208 | { | ||
| 209 | struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); | ||
| 210 | uint32_t value; | ||
| 211 | |||
| 212 | REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &value); | ||
| 213 | |||
| 214 | if (!value && link_settings->lane_count > LANE_COUNT_TWO) | ||
| 215 | link_settings->lane_count = LANE_COUNT_TWO; | ||
| 216 | } | ||
| 217 | |||
| 218 | bool dcn21_link_encoder_is_in_alt_mode(struct link_encoder *enc) | ||
| 219 | { | ||
| 220 | struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); | ||
| 221 | uint32_t value; | ||
| 222 | |||
| 223 | REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &value); | ||
| 224 | |||
| 225 | // if value == 1 alt mode is disabled, otherwise it is enabled | ||
| 226 | return !value; | ||
| 227 | } | ||
| 228 | |||
| 229 | bool dcn21_link_encoder_acquire_phy(struct link_encoder *enc) | ||
| 230 | { | ||
| 231 | struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); | ||
| 232 | int value; | ||
| 233 | |||
| 234 | if (enc->features.flags.bits.DP_IS_USB_C) { | ||
| 235 | REG_GET(RDPCSTX_PHY_CNTL6, | ||
| 236 | RDPCS_PHY_DPALT_DISABLE, &value); | ||
| 237 | |||
| 238 | if (value == 1) { | ||
| 239 | ASSERT(0); | ||
| 240 | return false; | ||
| 241 | } | ||
| 242 | REG_UPDATE(RDPCSTX_PHY_CNTL6, | ||
| 243 | RDPCS_PHY_DPALT_DISABLE_ACK, 0); | ||
| 244 | |||
| 245 | udelay(40); | ||
| 246 | |||
| 247 | REG_GET(RDPCSTX_PHY_CNTL6, | ||
| 248 | RDPCS_PHY_DPALT_DISABLE, &value); | ||
| 249 | if (value == 1) { | ||
| 250 | ASSERT(0); | ||
| 251 | REG_UPDATE(RDPCSTX_PHY_CNTL6, | ||
| 252 | RDPCS_PHY_DPALT_DISABLE_ACK, 1); | ||
| 253 | return false; | ||
| 254 | } | ||
| 255 | } | ||
| 256 | |||
| 257 | REG_UPDATE(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_REF_CLK_EN, 1); | ||
| 258 | |||
| 259 | return true; | ||
| 260 | } | ||
| 261 | |||
| 262 | |||
| 263 | |||
| 264 | static void dcn21_link_encoder_release_phy(struct link_encoder *enc) | ||
| 265 | { | ||
| 266 | struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); | ||
| 267 | |||
| 268 | if (enc->features.flags.bits.DP_IS_USB_C) { | ||
| 269 | REG_UPDATE(RDPCSTX_PHY_CNTL6, | ||
| 270 | RDPCS_PHY_DPALT_DISABLE_ACK, 1); | ||
| 271 | } | ||
| 272 | |||
| 273 | REG_UPDATE(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_REF_CLK_EN, 0); | ||
| 274 | |||
| 275 | } | ||
| 276 | |||
| 277 | void dcn21_link_encoder_enable_dp_output( | ||
| 278 | struct link_encoder *enc, | ||
| 279 | const struct dc_link_settings *link_settings, | ||
| 280 | enum clock_source_id clock_source) | ||
| 281 | { | ||
| 282 | struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); | ||
| 283 | struct dcn21_link_encoder *enc21 = (struct dcn21_link_encoder *) enc10; | ||
| 284 | struct dpcssys_phy_seq_cfg *cfg = &enc21->phy_seq_cfg; | ||
| 285 | |||
| 286 | if (!dcn21_link_encoder_acquire_phy(enc)) | ||
| 287 | return; | ||
| 288 | |||
| 289 | if (!enc->ctx->dc->debug.avoid_vbios_exec_table) { | ||
| 290 | dcn10_link_encoder_enable_dp_output(enc, link_settings, clock_source); | ||
| 291 | return; | ||
| 292 | } | ||
| 293 | |||
| 294 | if (!update_cfg_data(enc10, link_settings, cfg)) | ||
| 295 | return; | ||
| 296 | |||
| 297 | enc1_configure_encoder(enc10, link_settings); | ||
| 298 | |||
| 299 | dcn10_link_encoder_setup(enc, SIGNAL_TYPE_DISPLAY_PORT); | ||
| 300 | |||
| 301 | } | ||
| 302 | |||
| 303 | void dcn21_link_encoder_enable_dp_mst_output( | ||
| 304 | struct link_encoder *enc, | ||
| 305 | const struct dc_link_settings *link_settings, | ||
| 306 | enum clock_source_id clock_source) | ||
| 307 | { | ||
| 308 | if (!dcn21_link_encoder_acquire_phy(enc)) | ||
| 309 | return; | ||
| 310 | |||
| 311 | dcn10_link_encoder_enable_dp_mst_output(enc, link_settings, clock_source); | ||
| 312 | } | ||
| 313 | |||
| 314 | void dcn21_link_encoder_disable_output( | ||
| 315 | struct link_encoder *enc, | ||
| 316 | enum signal_type signal) | ||
| 317 | { | ||
| 318 | dcn10_link_encoder_disable_output(enc, signal); | ||
| 319 | |||
| 320 | if (dc_is_dp_signal(signal)) | ||
| 321 | dcn21_link_encoder_release_phy(enc); | ||
| 322 | } | ||
| 323 | |||
| 324 | |||
| 325 | static const struct link_encoder_funcs dcn21_link_enc_funcs = { | ||
| 326 | #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT | ||
| 327 | .read_state = link_enc2_read_state, | ||
| 328 | #endif | ||
| 329 | .validate_output_with_stream = | ||
| 330 | dcn10_link_encoder_validate_output_with_stream, | ||
| 331 | .hw_init = enc2_hw_init, | ||
| 332 | .setup = dcn10_link_encoder_setup, | ||
| 333 | .enable_tmds_output = dcn10_link_encoder_enable_tmds_output, | ||
| 334 | .enable_dp_output = dcn21_link_encoder_enable_dp_output, | ||
| 335 | .enable_dp_mst_output = dcn21_link_encoder_enable_dp_mst_output, | ||
| 336 | .disable_output = dcn21_link_encoder_disable_output, | ||
| 337 | .dp_set_lane_settings = dcn10_link_encoder_dp_set_lane_settings, | ||
| 338 | .dp_set_phy_pattern = dcn10_link_encoder_dp_set_phy_pattern, | ||
| 339 | .update_mst_stream_allocation_table = | ||
| 340 | dcn10_link_encoder_update_mst_stream_allocation_table, | ||
| 341 | .psr_program_dp_dphy_fast_training = | ||
| 342 | dcn10_psr_program_dp_dphy_fast_training, | ||
| 343 | .psr_program_secondary_packet = dcn10_psr_program_secondary_packet, | ||
| 344 | .connect_dig_be_to_fe = dcn10_link_encoder_connect_dig_be_to_fe, | ||
| 345 | .enable_hpd = dcn10_link_encoder_enable_hpd, | ||
| 346 | .disable_hpd = dcn10_link_encoder_disable_hpd, | ||
| 347 | .is_dig_enabled = dcn10_is_dig_enabled, | ||
| 348 | .destroy = dcn10_link_encoder_destroy, | ||
| 349 | .fec_set_enable = enc2_fec_set_enable, | ||
| 350 | .fec_set_ready = enc2_fec_set_ready, | ||
| 351 | .fec_is_active = enc2_fec_is_active, | ||
| 352 | .get_dig_frontend = dcn10_get_dig_frontend, | ||
| 353 | .is_in_alt_mode = dcn21_link_encoder_is_in_alt_mode, | ||
| 354 | .get_max_link_cap = dcn21_link_encoder_get_max_link_cap, | ||
| 355 | }; | ||
| 356 | |||
| 357 | void dcn21_link_encoder_construct( | ||
| 358 | struct dcn21_link_encoder *enc21, | ||
| 359 | const struct encoder_init_data *init_data, | ||
| 360 | const struct encoder_feature_support *enc_features, | ||
| 361 | const struct dcn10_link_enc_registers *link_regs, | ||
| 362 | const struct dcn10_link_enc_aux_registers *aux_regs, | ||
| 363 | const struct dcn10_link_enc_hpd_registers *hpd_regs, | ||
| 364 | const struct dcn10_link_enc_shift *link_shift, | ||
| 365 | const struct dcn10_link_enc_mask *link_mask) | ||
| 366 | { | ||
| 367 | struct bp_encoder_cap_info bp_cap_info = {0}; | ||
| 368 | const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs; | ||
| 369 | enum bp_result result = BP_RESULT_OK; | ||
| 370 | struct dcn10_link_encoder *enc10 = &enc21->enc10; | ||
| 371 | |||
| 372 | enc10->base.funcs = &dcn21_link_enc_funcs; | ||
| 373 | enc10->base.ctx = init_data->ctx; | ||
| 374 | enc10->base.id = init_data->encoder; | ||
| 375 | |||
| 376 | enc10->base.hpd_source = init_data->hpd_source; | ||
| 377 | enc10->base.connector = init_data->connector; | ||
| 378 | |||
| 379 | enc10->base.preferred_engine = ENGINE_ID_UNKNOWN; | ||
| 380 | |||
| 381 | enc10->base.features = *enc_features; | ||
| 382 | |||
| 383 | enc10->base.transmitter = init_data->transmitter; | ||
| 384 | |||
| 385 | /* set the flag to indicate whether driver poll the I2C data pin | ||
| 386 | * while doing the DP sink detect | ||
| 387 | */ | ||
| 388 | |||
| 389 | /* if (dal_adapter_service_is_feature_supported(as, | ||
| 390 | FEATURE_DP_SINK_DETECT_POLL_DATA_PIN)) | ||
| 391 | enc10->base.features.flags.bits. | ||
| 392 | DP_SINK_DETECT_POLL_DATA_PIN = true;*/ | ||
| 393 | |||
| 394 | enc10->base.output_signals = | ||
| 395 | SIGNAL_TYPE_DVI_SINGLE_LINK | | ||
| 396 | SIGNAL_TYPE_DVI_DUAL_LINK | | ||
| 397 | SIGNAL_TYPE_LVDS | | ||
| 398 | SIGNAL_TYPE_DISPLAY_PORT | | ||
| 399 | SIGNAL_TYPE_DISPLAY_PORT_MST | | ||
| 400 | SIGNAL_TYPE_EDP | | ||
| 401 | SIGNAL_TYPE_HDMI_TYPE_A; | ||
| 402 | |||
| 403 | /* For DCE 8.0 and 8.1, by design, UNIPHY is hardwired to DIG_BE. | ||
| 404 | * SW always assign DIG_FE 1:1 mapped to DIG_FE for non-MST UNIPHY. | ||
| 405 | * SW assign DIG_FE to non-MST UNIPHY first and MST last. So prefer | ||
| 406 | * DIG is per UNIPHY and used by SST DP, eDP, HDMI, DVI and LVDS. | ||
| 407 | * Prefer DIG assignment is decided by board design. | ||
| 408 | * For DCE 8.0, there are only max 6 UNIPHYs, we assume board design | ||
| 409 | * and VBIOS will filter out 7 UNIPHY for DCE 8.0. | ||
| 410 | * By this, adding DIGG should not hurt DCE 8.0. | ||
| 411 | * This will let DCE 8.1 share DCE 8.0 as much as possible | ||
| 412 | */ | ||
| 413 | |||
| 414 | enc10->link_regs = link_regs; | ||
| 415 | enc10->aux_regs = aux_regs; | ||
| 416 | enc10->hpd_regs = hpd_regs; | ||
| 417 | enc10->link_shift = link_shift; | ||
| 418 | enc10->link_mask = link_mask; | ||
| 419 | |||
| 420 | switch (enc10->base.transmitter) { | ||
| 421 | case TRANSMITTER_UNIPHY_A: | ||
| 422 | enc10->base.preferred_engine = ENGINE_ID_DIGA; | ||
| 423 | break; | ||
| 424 | case TRANSMITTER_UNIPHY_B: | ||
| 425 | enc10->base.preferred_engine = ENGINE_ID_DIGB; | ||
| 426 | break; | ||
| 427 | case TRANSMITTER_UNIPHY_C: | ||
| 428 | enc10->base.preferred_engine = ENGINE_ID_DIGC; | ||
| 429 | break; | ||
| 430 | case TRANSMITTER_UNIPHY_D: | ||
| 431 | enc10->base.preferred_engine = ENGINE_ID_DIGD; | ||
| 432 | break; | ||
| 433 | case TRANSMITTER_UNIPHY_E: | ||
| 434 | enc10->base.preferred_engine = ENGINE_ID_DIGE; | ||
| 435 | break; | ||
| 436 | case TRANSMITTER_UNIPHY_F: | ||
| 437 | enc10->base.preferred_engine = ENGINE_ID_DIGF; | ||
| 438 | break; | ||
| 439 | case TRANSMITTER_UNIPHY_G: | ||
| 440 | enc10->base.preferred_engine = ENGINE_ID_DIGG; | ||
| 441 | break; | ||
| 442 | default: | ||
| 443 | ASSERT_CRITICAL(false); | ||
| 444 | enc10->base.preferred_engine = ENGINE_ID_UNKNOWN; | ||
| 445 | } | ||
| 446 | |||
| 447 | /* default to one to mirror Windows behavior */ | ||
| 448 | enc10->base.features.flags.bits.HDMI_6GB_EN = 1; | ||
| 449 | |||
| 450 | result = bp_funcs->get_encoder_cap_info(enc10->base.ctx->dc_bios, | ||
| 451 | enc10->base.id, &bp_cap_info); | ||
| 452 | |||
| 453 | /* Override features with DCE-specific values */ | ||
| 454 | if (result == BP_RESULT_OK) { | ||
| 455 | enc10->base.features.flags.bits.IS_HBR2_CAPABLE = | ||
| 456 | bp_cap_info.DP_HBR2_EN; | ||
| 457 | enc10->base.features.flags.bits.IS_HBR3_CAPABLE = | ||
| 458 | bp_cap_info.DP_HBR3_EN; | ||
| 459 | enc10->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; | ||
| 460 | enc10->base.features.flags.bits.DP_IS_USB_C = | ||
| 461 | bp_cap_info.DP_IS_USB_C; | ||
| 462 | } else { | ||
| 463 | DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n", | ||
| 464 | __func__, | ||
| 465 | result); | ||
| 466 | } | ||
| 467 | if (enc10->base.ctx->dc->debug.hdmi20_disable) { | ||
| 468 | enc10->base.features.flags.bits.HDMI_6GB_EN = 0; | ||
| 469 | } | ||
| 470 | } | ||
| @@ -0,0 +1,61 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2012-15 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 | * Authors: AMD | ||
| 23 | * | ||
| 24 | */ | ||
| 25 | |||
| 26 | #ifndef __DC_LINK_ENCODER__DCN21_H__ | ||
| 27 | #define __DC_LINK_ENCODER__DCN21_H__ | ||
| 28 | |||
| 29 | #include "dcn20/dcn20_link_encoder.h" | ||
| 30 | |||
| 31 | struct dcn21_link_encoder { | ||
| 32 | struct dcn10_link_encoder enc10; | ||
| 33 | struct dpcssys_phy_seq_cfg phy_seq_cfg; | ||
| 34 | }; | ||
| 35 | |||
| 36 | #define LINK_ENCODER_MASK_SH_LIST_DCN21(mask_sh)\ | ||
| 37 | LINK_ENCODER_MASK_SH_LIST_DCN20(mask_sh),\ | ||
| 38 | LE_SF(UNIPHYA_CHANNEL_XBAR_CNTL, UNIPHY_CHANNEL0_XBAR_SOURCE, mask_sh),\ | ||
| 39 | LE_SF(UNIPHYA_CHANNEL_XBAR_CNTL, UNIPHY_CHANNEL1_XBAR_SOURCE, mask_sh),\ | ||
| 40 | LE_SF(UNIPHYA_CHANNEL_XBAR_CNTL, UNIPHY_CHANNEL2_XBAR_SOURCE, mask_sh),\ | ||
| 41 | LE_SF(UNIPHYA_CHANNEL_XBAR_CNTL, UNIPHY_CHANNEL3_XBAR_SOURCE, mask_sh), \ | ||
| 42 | SRI(RDPCSTX_PHY_FUSE2, RDPCSTX, id), \ | ||
| 43 | SRI(RDPCSTX_PHY_FUSE3, RDPCSTX, id), \ | ||
| 44 | SR(RDPCSTX0_RDPCSTX_SCRATCH) | ||
| 45 | |||
| 46 | void dcn21_link_encoder_enable_dp_output( | ||
| 47 | struct link_encoder *enc, | ||
| 48 | const struct dc_link_settings *link_settings, | ||
| 49 | enum clock_source_id clock_source); | ||
| 50 | |||
| 51 | void dcn21_link_encoder_construct( | ||
| 52 | struct dcn21_link_encoder *enc21, | ||
| 53 | const struct encoder_init_data *init_data, | ||
| 54 | const struct encoder_feature_support *enc_features, | ||
| 55 | const struct dcn10_link_enc_registers *link_regs, | ||
| 56 | const struct dcn10_link_enc_aux_registers *aux_regs, | ||
| 57 | const struct dcn10_link_enc_hpd_registers *hpd_regs, | ||
| 58 | const struct dcn10_link_enc_shift *link_shift, | ||
| 59 | const struct dcn10_link_enc_mask *link_mask); | ||
| 60 | |||
| 61 | #endif | ||
| @@ -23,8 +23,6 @@ · 22 unmodified lines | |||
| 23 | * | 23 | * |
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | #include <linux/slab.h> | ||
| 27 | |||
| 28 | #include "dm_services.h" | 26 | #include "dm_services.h" |
| 29 | #include "dc.h" | 27 | #include "dc.h" |
| 30 | 28 | ||
| @@ -42,11 +40,11 @@ · 11 unmodified lines | |||
| 42 | #include "irq/dcn21/irq_service_dcn21.h" | 40 | #include "irq/dcn21/irq_service_dcn21.h" |
| 43 | #include "dcn20/dcn20_dpp.h" | 41 | #include "dcn20/dcn20_dpp.h" |
| 44 | #include "dcn20/dcn20_optc.h" | 42 | #include "dcn20/dcn20_optc.h" |
| 45 | #include "dcn20/dcn20_hwseq.h" | 43 | #include "dcn21/dcn21_hwseq.h" |
| 46 | #include "dce110/dce110_hw_sequencer.h" | 44 | #include "dce110/dce110_hw_sequencer.h" |
| 47 | #include "dcn20/dcn20_opp.h" | 45 | #include "dcn20/dcn20_opp.h" |
| 48 | #include "dcn20/dcn20_dsc.h" | 46 | #include "dcn20/dcn20_dsc.h" |
| 49 | #include "dcn20/dcn20_link_encoder.h" | 47 | #include "dcn21/dcn21_link_encoder.h" |
| 50 | #include "dcn20/dcn20_stream_encoder.h" | 48 | #include "dcn20/dcn20_stream_encoder.h" |
| 51 | #include "dce/dce_clock_source.h" | 49 | #include "dce/dce_clock_source.h" |
| 52 | #include "dce/dce_audio.h" | 50 | #include "dce/dce_audio.h" |
| @@ -84,6 +82,7 @@ · 31 unmodified lines | |||
| 84 | 82 | ||
| 85 | 83 | ||
| 86 | struct _vcs_dpi_ip_params_st dcn2_1_ip = { | 84 | struct _vcs_dpi_ip_params_st dcn2_1_ip = { |
| 85 | .odm_capable = 1, | ||
| 87 | .gpuvm_enable = 0, | 86 | .gpuvm_enable = 0, |
| 88 | .hostvm_enable = 0, | 87 | .hostvm_enable = 0, |
| 89 | .gpuvm_max_page_table_levels = 1, | 88 | .gpuvm_max_page_table_levels = 1, |
| @@ -205,11 +204,11 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { · 115 unmodified lines | |||
| 205 | .state = 4, | 204 | .state = 4, |
| 206 | .dcfclk_mhz = 810.0, | 205 | .dcfclk_mhz = 810.0, |
| 207 | .fabricclk_mhz = 1600.0, | 206 | .fabricclk_mhz = 1600.0, |
| 208 | .dispclk_mhz = 1015.0, | 207 | .dispclk_mhz = 1395.0, |
| 209 | .dppclk_mhz = 1015.0, | 208 | .dppclk_mhz = 1285.0, |
| 210 | .phyclk_mhz = 810.0, | 209 | .phyclk_mhz = 1325.0, |
| 211 | .socclk_mhz = 953.0, | 210 | .socclk_mhz = 953.0, |
| 212 | .dscclk_mhz = 318.334, | 211 | .dscclk_mhz = 489.0, |
| 213 | .dram_speed_mts = 4266.0, | 212 | .dram_speed_mts = 4266.0, |
| 214 | }, | 213 | }, |
| 215 | /*Extra state, no dispclk ramping*/ | 214 | /*Extra state, no dispclk ramping*/ |
| @@ -217,18 +216,18 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { · 1 unmodified line | |||
| 217 | .state = 5, | 216 | .state = 5, |
| 218 | .dcfclk_mhz = 810.0, | 217 | .dcfclk_mhz = 810.0, |
| 219 | .fabricclk_mhz = 1600.0, | 218 | .fabricclk_mhz = 1600.0, |
| 220 | .dispclk_mhz = 1015.0, | 219 | .dispclk_mhz = 1395.0, |
| 221 | .dppclk_mhz = 1015.0, | 220 | .dppclk_mhz = 1285.0, |
| 222 | .phyclk_mhz = 810.0, | 221 | .phyclk_mhz = 1325.0, |
| 223 | .socclk_mhz = 953.0, | 222 | .socclk_mhz = 953.0, |
| 224 | .dscclk_mhz = 318.334, | 223 | .dscclk_mhz = 489.0, |
| 225 | .dram_speed_mts = 4266.0, | 224 | .dram_speed_mts = 4266.0, |
| 226 | }, | 225 | }, |
| 227 | 226 | ||
| 228 | }, | 227 | }, |
| 229 | 228 | ||
| 230 | .sr_exit_time_us = 9.0, | 229 | .sr_exit_time_us = 12.5, |
| 231 | .sr_enter_plus_exit_time_us = 11.0, | 230 | .sr_enter_plus_exit_time_us = 17.0, |
| 232 | .urgent_latency_us = 4.0, | 231 | .urgent_latency_us = 4.0, |
| 233 | .urgent_latency_pixel_data_only_us = 4.0, | 232 | .urgent_latency_pixel_data_only_us = 4.0, |
| 234 | .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, | 233 | .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, |
| @@ -350,6 +349,30 @@ static const struct bios_registers bios_regs = { · 115 unmodified lines | |||
| 350 | NBIO_SR(BIOS_SCRATCH_6) | 349 | NBIO_SR(BIOS_SCRATCH_6) |
| 351 | }; | 350 | }; |
| 352 | 351 | ||
| 352 | static const struct dce_dmcu_registers dmcu_regs = { | ||
| 353 | DMCU_DCN10_REG_LIST() | ||
| 354 | }; | ||
| 355 | |||
| 356 | static const struct dce_dmcu_shift dmcu_shift = { | ||
| 357 | DMCU_MASK_SH_LIST_DCN10(__SHIFT) | ||
| 358 | }; | ||
| 359 | |||
| 360 | static const struct dce_dmcu_mask dmcu_mask = { | ||
| 361 | DMCU_MASK_SH_LIST_DCN10(_MASK) | ||
| 362 | }; | ||
| 363 | |||
| 364 | static const struct dce_abm_registers abm_regs = { | ||
| 365 | ABM_DCN20_REG_LIST() | ||
| 366 | }; | ||
| 367 | |||
| 368 | static const struct dce_abm_shift abm_shift = { | ||
| 369 | ABM_MASK_SH_LIST_DCN20(__SHIFT) | ||
| 370 | }; | ||
| 371 | |||
| 372 | static const struct dce_abm_mask abm_mask = { | ||
| 373 | ABM_MASK_SH_LIST_DCN20(_MASK) | ||
| 374 | }; | ||
| 375 | |||
| 353 | #ifdef CONFIG_DRM_AMD_DC_DMUB | 376 | #ifdef CONFIG_DRM_AMD_DC_DMUB |
| 354 | static const struct dcn21_dmcub_registers dmcub_regs = { | 377 | static const struct dcn21_dmcub_registers dmcub_regs = { |
| 355 | DMCUB_REG_LIST_DCN() | 378 | DMCUB_REG_LIST_DCN() |
| @@ -628,6 +651,14 @@ static const struct dcn10_stream_enc_registers stream_enc_regs[] = { · 272 unmodified lines | |||
| 628 | stream_enc_regs(4), | 651 | stream_enc_regs(4), |
| 629 | }; | 652 | }; |
| 630 | 653 | ||
| 654 | static const struct dce110_aux_registers_shift aux_shift = { | ||
| 655 | DCN_AUX_MASK_SH_LIST(__SHIFT) | ||
| 656 | }; | ||
| 657 | |||
| 658 | static const struct dce110_aux_registers_mask aux_mask = { | ||
| 659 | DCN_AUX_MASK_SH_LIST(_MASK) | ||
| 660 | }; | ||
| 661 | |||
| 631 | static const struct dcn10_stream_encoder_shift se_shift = { | 662 | static const struct dcn10_stream_encoder_shift se_shift = { |
| 632 | SE_COMMON_MASK_SH_LIST_DCN20(__SHIFT) | 663 | SE_COMMON_MASK_SH_LIST_DCN20(__SHIFT) |
| 633 | }; | 664 | }; |
| @@ -636,6 +667,8 @@ static const struct dcn10_stream_encoder_mask se_mask = { · 2 unmodified lines | |||
| 636 | SE_COMMON_MASK_SH_LIST_DCN20(_MASK) | 667 | SE_COMMON_MASK_SH_LIST_DCN20(_MASK) |
| 637 | }; | 668 | }; |
| 638 | 669 | ||
| 670 | static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu); | ||
| 671 | |||
| 639 | static struct input_pixel_processor *dcn21_ipp_create( | 672 | static struct input_pixel_processor *dcn21_ipp_create( |
| 640 | struct dc_context *ctx, uint32_t inst) | 673 | struct dc_context *ctx, uint32_t inst) |
| 641 | { | 674 | { |
| @@ -683,7 +716,10 @@ static struct dce_aux *dcn21_aux_engine_create( · 41 unmodified lines | |||
| 683 | 716 | ||
| 684 | dce110_aux_engine_construct(aux_engine, ctx, inst, | 717 | dce110_aux_engine_construct(aux_engine, ctx, inst, |
| 685 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, | 718 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, |
| 686 | &aux_engine_regs[inst]); | 719 | &aux_engine_regs[inst], |
| 720 | &aux_mask, | ||
| 721 | &aux_shift, | ||
| 722 | ctx->dc->caps.extended_aux_timeout_support); | ||
| 687 | 723 | ||
| 688 | return &aux_engine->base; | 724 | return &aux_engine->base; |
| 689 | } | 725 | } |
| @@ -726,11 +762,12 @@ static const struct resource_caps res_cap_rn = { · 36 unmodified lines | |||
| 726 | .num_timing_generator = 4, | 762 | .num_timing_generator = 4, |
| 727 | .num_opp = 4, | 763 | .num_opp = 4, |
| 728 | .num_video_plane = 4, | 764 | .num_video_plane = 4, |
| 729 | .num_audio = 6, // 6 audio endpoints. 4 audio streams | 765 | .num_audio = 4, // 4 audio endpoints. 4 audio streams |
| 730 | .num_stream_encoder = 5, | 766 | .num_stream_encoder = 5, |
| 731 | .num_pll = 5, // maybe 3 because the last two used for USB-c | 767 | .num_pll = 5, // maybe 3 because the last two used for USB-c |
| 732 | .num_dwb = 1, | 768 | .num_dwb = 1, |
| 733 | .num_ddc = 5, | 769 | .num_ddc = 5, |
| 770 | .num_vmid = 1, | ||
| 734 | #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT | 771 | #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT |
| 735 | .num_dsc = 3, | 772 | .num_dsc = 3, |
| 736 | #endif | 773 | #endif |
| @@ -800,11 +837,11 @@ static const struct dc_debug_options debug_defaults_drv = { · 63 unmodified lines | |||
| 800 | .disable_dcc = DCC_ENABLE, | 837 | .disable_dcc = DCC_ENABLE, |
| 801 | .vsr_support = true, | 838 | .vsr_support = true, |
| 802 | .performance_trace = false, | 839 | .performance_trace = false, |
| 803 | .max_downscale_src_width = 5120,/*upto 5K*/ | 840 | .max_downscale_src_width = 3840, |
| 804 | .disable_pplib_wm_range = false, | 841 | .disable_pplib_wm_range = false, |
| 805 | .scl_reset_length10 = true, | 842 | .scl_reset_length10 = true, |
| 806 | .sanity_checks = true, | 843 | .sanity_checks = true, |
| 807 | .disable_48mhz_pwrdwn = true, | 844 | .disable_48mhz_pwrdwn = false, |
| 808 | }; | 845 | }; |
| 809 | 846 | ||
| 810 | static const struct dc_debug_options debug_defaults_diags = { | 847 | static const struct dc_debug_options debug_defaults_diags = { |
| @@ -939,7 +976,7 @@ static void destruct(struct dcn21_resource_pool *pool) · 128 unmodified lines | |||
| 939 | dcn_dccg_destroy(&pool->base.dccg); | 976 | dcn_dccg_destroy(&pool->base.dccg); |
| 940 | 977 | ||
| 941 | if (pool->base.pp_smu != NULL) | 978 | if (pool->base.pp_smu != NULL) |
| 942 | dcn20_pp_smu_destroy(&pool->base.pp_smu); | 979 | dcn21_pp_smu_destroy(&pool->base.pp_smu); |
| 943 | } | 980 | } |
| 944 | 981 | ||
| 945 | 982 | ||
| @@ -974,6 +1011,29 @@ static void calculate_wm_set_for_vlevel( · 28 unmodified lines | |||
| 974 | 1011 | ||
| 975 | } | 1012 | } |
| 976 | 1013 | ||
| 1014 | static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb) | ||
| 1015 | { | ||
| 1016 | kernel_fpu_begin(); | ||
| 1017 | if (dc->bb_overrides.sr_exit_time_ns) { | ||
| 1018 | bb->sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0; | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | if (dc->bb_overrides.sr_enter_plus_exit_time_ns) { | ||
| 1022 | bb->sr_enter_plus_exit_time_us = | ||
| 1023 | dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0; | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | if (dc->bb_overrides.urgent_latency_ns) { | ||
| 1027 | bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0; | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | if (dc->bb_overrides.dram_clock_change_latency_ns) { | ||
| 1031 | bb->dram_clock_change_latency_us = | ||
| 1032 | dc->bb_overrides.dram_clock_change_latency_ns / 1000.0; | ||
| 1033 | } | ||
| 1034 | kernel_fpu_end(); | ||
| 1035 | } | ||
| 1036 | |||
| 977 | void dcn21_calculate_wm( | 1037 | void dcn21_calculate_wm( |
| 978 | struct dc *dc, struct dc_state *context, | 1038 | struct dc *dc, struct dc_state *context, |
| 979 | display_e2e_pipe_params_st *pipes, | 1039 | display_e2e_pipe_params_st *pipes, |
| @@ -988,6 +1048,8 @@ void dcn21_calculate_wm( · 8 unmodified lines | |||
| 988 | 1048 | ||
| 989 | ASSERT(bw_params); | 1049 | ASSERT(bw_params); |
| 990 | 1050 | ||
| 1051 | patch_bounding_box(dc, &context->bw_ctx.dml.soc); | ||
| 1052 | |||
| 991 | for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { | 1053 | for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { |
| 992 | if (!context->res_ctx.pipe_ctx[i].stream) | 1054 | if (!context->res_ctx.pipe_ctx[i].stream) |
| 993 | continue; | 1055 | continue; |
| @@ -1278,7 +1340,6 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param · 284 unmodified lines | |||
| 1278 | dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator; | 1340 | dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator; |
| 1279 | dcn2_1_ip.max_num_dpp = pool->base.pipe_count; | 1341 | dcn2_1_ip.max_num_dpp = pool->base.pipe_count; |
| 1280 | dcn2_1_soc.num_chans = bw_params->num_channels; | 1342 | dcn2_1_soc.num_chans = bw_params->num_channels; |
| 1281 | dcn2_1_soc.num_states = 0; | ||
| 1282 | 1343 | ||
| 1283 | for (i = 0; i < clk_table->num_entries; i++) { | 1344 | for (i = 0; i < clk_table->num_entries; i++) { |
| 1284 | 1345 | ||
| @@ -1288,8 +1349,9 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param · 3 unmodified lines | |||
| 1288 | dcn2_1_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; | 1349 | dcn2_1_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; |
| 1289 | /* This is probably wrong, TODO: find correct calculation */ | 1350 | /* This is probably wrong, TODO: find correct calculation */ |
| 1290 | dcn2_1_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 16 / 1000; | 1351 | dcn2_1_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 16 / 1000; |
| 1291 | dcn2_1_soc.num_states++; | ||
| 1292 | } | 1352 | } |
| 1353 | dcn2_1_soc.clock_limits[i] = dcn2_1_soc.clock_limits[i - i]; | ||
| 1354 | dcn2_1_soc.num_states = i; | ||
| 1293 | } | 1355 | } |
| 1294 | 1356 | ||
| 1295 | /* Temporary Place holder until we can get them from fuse */ | 1357 | /* Temporary Place holder until we can get them from fuse */ |
| @@ -1317,32 +1379,42 @@ static struct dpm_clocks dummy_clocks = { · 21 unmodified lines | |||
| 1317 | 1379 | ||
| 1318 | }; | 1380 | }; |
| 1319 | 1381 | ||
| 1320 | enum pp_smu_status dummy_set_wm_ranges(struct pp_smu *pp, | 1382 | static enum pp_smu_status dummy_set_wm_ranges(struct pp_smu *pp, |
| 1321 | struct pp_smu_wm_range_sets *ranges) | 1383 | struct pp_smu_wm_range_sets *ranges) |
| 1322 | { | 1384 | { |
| 1323 | return PP_SMU_RESULT_OK; | 1385 | return PP_SMU_RESULT_OK; |
| 1324 | } | 1386 | } |
| 1325 | 1387 | ||
| 1326 | enum pp_smu_status dummy_get_dpm_clock_table(struct pp_smu *pp, | 1388 | static enum pp_smu_status dummy_get_dpm_clock_table(struct pp_smu *pp, |
| 1327 | struct dpm_clocks *clock_table) | 1389 | struct dpm_clocks *clock_table) |
| 1328 | { | 1390 | { |
| 1329 | *clock_table = dummy_clocks; | 1391 | *clock_table = dummy_clocks; |
| 1330 | return PP_SMU_RESULT_OK; | 1392 | return PP_SMU_RESULT_OK; |
| 1331 | } | 1393 | } |
| 1332 | 1394 | ||
| 1333 | struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx) | 1395 | static struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx) |
| 1334 | { | 1396 | { |
| 1335 | struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL); | 1397 | struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL); |
| 1336 | 1398 | ||
| 1337 | pp_smu->ctx.ver = PP_SMU_VER_RN; | 1399 | if (!pp_smu) |
| 1400 | return pp_smu; | ||
| 1401 | |||
| 1402 | if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment) || IS_DIAG_DC(ctx->dce_environment)) { | ||
| 1403 | pp_smu->ctx.ver = PP_SMU_VER_RN; | ||
| 1404 | pp_smu->rn_funcs.get_dpm_clock_table = dummy_get_dpm_clock_table; | ||
| 1405 | pp_smu->rn_funcs.set_wm_ranges = dummy_set_wm_ranges; | ||
| 1406 | } else { | ||
| 1338 | 1407 | ||
| 1339 | pp_smu->rn_funcs.get_dpm_clock_table = dummy_get_dpm_clock_table; | 1408 | dm_pp_get_funcs(ctx, pp_smu); |
| 1340 | pp_smu->rn_funcs.set_wm_ranges = dummy_set_wm_ranges; | 1409 | |
| 1410 | if (pp_smu->ctx.ver != PP_SMU_VER_RN) | ||
| 1411 | pp_smu = memset(pp_smu, 0, sizeof(struct pp_smu_funcs)); | ||
| 1412 | } | ||
| 1341 | 1413 | ||
| 1342 | return pp_smu; | 1414 | return pp_smu; |
| 1343 | } | 1415 | } |
| 1344 | 1416 | ||
| 1345 | void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu) | 1417 | static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu) |
| 1346 | { | 1418 | { |
| 1347 | if (pp_smu && *pp_smu) { | 1419 | if (pp_smu && *pp_smu) { |
| 1348 | kfree(*pp_smu); | 1420 | kfree(*pp_smu); |
| @@ -1400,6 +1472,7 @@ static struct dce_hwseq *dcn21_hwseq_create( · 51 unmodified lines | |||
| 1400 | hws->regs = &hwseq_reg; | 1472 | hws->regs = &hwseq_reg; |
| 1401 | hws->shifts = &hwseq_shift; | 1473 | hws->shifts = &hwseq_shift; |
| 1402 | hws->masks = &hwseq_mask; | 1474 | hws->masks = &hwseq_mask; |
| 1475 | hws->wa.DEGVIDCN21 = true; | ||
| 1403 | } | 1476 | } |
| 1404 | return hws; | 1477 | return hws; |
| 1405 | } | 1478 | } |
| @@ -1418,9 +1491,103 @@ static const struct resource_create_funcs res_create_maximus_funcs = { · 12 unmodified lines | |||
| 1418 | .create_hwseq = dcn21_hwseq_create, | 1491 | .create_hwseq = dcn21_hwseq_create, |
| 1419 | }; | 1492 | }; |
| 1420 | 1493 | ||
| 1494 | static const struct encoder_feature_support link_enc_feature = { | ||
| 1495 | .max_hdmi_deep_color = COLOR_DEPTH_121212, | ||
| 1496 | .max_hdmi_pixel_clock = 600000, | ||
| 1497 | .hdmi_ycbcr420_supported = true, | ||
| 1498 | .dp_ycbcr420_supported = true, | ||
| 1499 | .flags.bits.IS_HBR2_CAPABLE = true, | ||
| 1500 | .flags.bits.IS_HBR3_CAPABLE = true, | ||
| 1501 | .flags.bits.IS_TPS3_CAPABLE = true, | ||
| 1502 | .flags.bits.IS_TPS4_CAPABLE = true | ||
| 1503 | }; | ||
| 1504 | |||
| 1505 | |||
| 1506 | #define link_regs(id, phyid)\ | ||
| 1507 | [id] = {\ | ||
| 1508 | LE_DCN10_REG_LIST(id), \ | ||
| 1509 | UNIPHY_DCN2_REG_LIST(phyid), \ | ||
| 1510 | SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \ | ||
| 1511 | } | ||
| 1512 | |||
| 1513 | static const struct dcn10_link_enc_registers link_enc_regs[] = { | ||
| 1514 | link_regs(0, A), | ||
| 1515 | link_regs(1, B), | ||
| 1516 | link_regs(2, C), | ||
| 1517 | link_regs(3, D), | ||
| 1518 | link_regs(4, E), | ||
| 1519 | }; | ||
| 1520 | |||
| 1521 | #define aux_regs(id)\ | ||
| 1522 | [id] = {\ | ||
| 1523 | DCN2_AUX_REG_LIST(id)\ | ||
| 1524 | } | ||
| 1525 | |||
| 1526 | static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = { | ||
| 1527 | aux_regs(0), | ||
| 1528 | aux_regs(1), | ||
| 1529 | aux_regs(2), | ||
| 1530 | aux_regs(3), | ||
| 1531 | aux_regs(4) | ||
| 1532 | }; | ||
| 1533 | |||
| 1534 | #define hpd_regs(id)\ | ||
| 1535 | [id] = {\ | ||
| 1536 | HPD_REG_LIST(id)\ | ||
| 1537 | } | ||
| 1538 | |||
| 1539 | static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = { | ||
| 1540 | hpd_regs(0), | ||
| 1541 | hpd_regs(1), | ||
| 1542 | hpd_regs(2), | ||
| 1543 | hpd_regs(3), | ||
| 1544 | hpd_regs(4) | ||
| 1545 | }; | ||
| 1546 | |||
| 1547 | static const struct dcn10_link_enc_shift le_shift = { | ||
| 1548 | LINK_ENCODER_MASK_SH_LIST_DCN20(__SHIFT) | ||
| 1549 | }; | ||
| 1550 | |||
| 1551 | static const struct dcn10_link_enc_mask le_mask = { | ||
| 1552 | LINK_ENCODER_MASK_SH_LIST_DCN20(_MASK) | ||
| 1553 | }; | ||
| 1554 | |||
| 1555 | static struct link_encoder *dcn21_link_encoder_create( | ||
| 1556 | const struct encoder_init_data *enc_init_data) | ||
| 1557 | { | ||
| 1558 | struct dcn21_link_encoder *enc21 = | ||
| 1559 | kzalloc(sizeof(struct dcn21_link_encoder), GFP_KERNEL); | ||
| 1560 | |||
| 1561 | if (!enc21) | ||
| 1562 | return NULL; | ||
| 1563 | |||
| 1564 | dcn21_link_encoder_construct(enc21, | ||
| 1565 | enc_init_data, | ||
| 1566 | &link_enc_feature, | ||
| 1567 | &link_enc_regs[enc_init_data->transmitter], | ||
| 1568 | &link_enc_aux_regs[enc_init_data->channel - 1], | ||
| 1569 | &link_enc_hpd_regs[enc_init_data->hpd_source], | ||
| 1570 | &le_shift, | ||
| 1571 | &le_mask); | ||
| 1572 | |||
| 1573 | return &enc21->enc10.base; | ||
| 1574 | } | ||
| 1575 | #define CTX ctx | ||
| 1576 | |||
| 1577 | #define REG(reg_name) \ | ||
| 1578 | (DCN_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) | ||
| 1579 | |||
| 1580 | static uint32_t read_pipe_fuses(struct dc_context *ctx) | ||
| 1581 | { | ||
| 1582 | uint32_t value = REG_READ(CC_DC_PIPE_DIS); | ||
| 1583 | /* RV1 support max 4 pipes */ | ||
| 1584 | value = value & 0xf; | ||
| 1585 | return value; | ||
| 1586 | } | ||
| 1587 | |||
| 1421 | static struct resource_funcs dcn21_res_pool_funcs = { | 1588 | static struct resource_funcs dcn21_res_pool_funcs = { |
| 1422 | .destroy = dcn21_destroy_resource_pool, | 1589 | .destroy = dcn21_destroy_resource_pool, |
| 1423 | .link_enc_create = dcn20_link_encoder_create, | 1590 | .link_enc_create = dcn21_link_encoder_create, |
| 1424 | .validate_bandwidth = dcn21_validate_bandwidth, | 1591 | .validate_bandwidth = dcn21_validate_bandwidth, |
| 1425 | .add_stream_to_ctx = dcn20_add_stream_to_ctx, | 1592 | .add_stream_to_ctx = dcn20_add_stream_to_ctx, |
| 1426 | .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, | 1593 | .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, |
| @@ -1437,9 +1604,10 @@ static bool construct( · 10 unmodified lines | |||
| 1437 | struct dc *dc, | 1604 | struct dc *dc, |
| 1438 | struct dcn21_resource_pool *pool) | 1605 | struct dcn21_resource_pool *pool) |
| 1439 | { | 1606 | { |
| 1440 | int i; | 1607 | int i, j; |
| 1441 | struct dc_context *ctx = dc->ctx; | 1608 | struct dc_context *ctx = dc->ctx; |
| 1442 | struct irq_service_init_data init_data; | 1609 | struct irq_service_init_data init_data; |
| 1610 | uint32_t pipe_fuses = read_pipe_fuses(ctx); | ||
| 1443 | 1611 | ||
| 1444 | ctx->dc_bios->regs = &bios_regs; | 1612 | ctx->dc_bios->regs = &bios_regs; |
| 1445 | 1613 | ||
| @@ -1457,7 +1625,9 @@ static bool construct( · 11 unmodified lines | |||
| 1457 | *************************************************/ | 1625 | *************************************************/ |
| 1458 | pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; | 1626 | pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; |
| 1459 | 1627 | ||
| 1460 | pool->base.pipe_count = 4; | 1628 | /* max pipe num for ASIC before check pipe fuses */ |
| 1629 | pool->base.pipe_count = pool->base.res_cap->num_timing_generator; | ||
| 1630 | |||
| 1461 | dc->caps.max_downscale_ratio = 200; | 1631 | dc->caps.max_downscale_ratio = 200; |
| 1462 | dc->caps.i2c_speed_in_khz = 100; | 1632 | dc->caps.i2c_speed_in_khz = 100; |
| 1463 | dc->caps.max_cursor_size = 256; | 1633 | dc->caps.max_cursor_size = 256; |
| @@ -1467,6 +1637,7 @@ static bool construct( · 3 unmodified lines | |||
| 1467 | dc->caps.max_slave_planes = 1; | 1637 | dc->caps.max_slave_planes = 1; |
| 1468 | dc->caps.post_blend_color_processing = true; | 1638 | dc->caps.post_blend_color_processing = true; |
| 1469 | dc->caps.force_dp_tps4_for_cp2520 = true; | 1639 | dc->caps.force_dp_tps4_for_cp2520 = true; |
| 1640 | dc->caps.extended_aux_timeout_support = true; | ||
| 1470 | 1641 | ||
| 1471 | if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) | 1642 | if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) |
| 1472 | dc->debug = debug_defaults_drv; | 1643 | dc->debug = debug_defaults_drv; |
| @@ -1516,6 +1687,26 @@ static bool construct( · 43 unmodified lines | |||
| 1516 | goto create_fail; | 1687 | goto create_fail; |
| 1517 | } | 1688 | } |
| 1518 | 1689 | ||
| 1690 | pool->base.dmcu = dcn20_dmcu_create(ctx, | ||
| 1691 | &dmcu_regs, | ||
| 1692 | &dmcu_shift, | ||
| 1693 | &dmcu_mask); | ||
| 1694 | if (pool->base.dmcu == NULL) { | ||
| 1695 | dm_error("DC: failed to create dmcu!\n"); | ||
| 1696 | BREAK_TO_DEBUGGER(); | ||
| 1697 | goto create_fail; | ||
| 1698 | } | ||
| 1699 | |||
| 1700 | pool->base.abm = dce_abm_create(ctx, | ||
| 1701 | &abm_regs, | ||
| 1702 | &abm_shift, | ||
| 1703 | &abm_mask); | ||
| 1704 | if (pool->base.abm == NULL) { | ||
| 1705 | dm_error("DC: failed to create abm!\n"); | ||
| 1706 | BREAK_TO_DEBUGGER(); | ||
| 1707 | goto create_fail; | ||
| 1708 | } | ||
| 1709 | |||
| 1519 | #ifdef CONFIG_DRM_AMD_DC_DMUB | 1710 | #ifdef CONFIG_DRM_AMD_DC_DMUB |
| 1520 | pool->base.dmcub = dcn21_dmcub_create(ctx, | 1711 | pool->base.dmcub = dcn21_dmcub_create(ctx, |
| 1521 | &dmcub_regs, | 1712 | &dmcub_regs, |
| @@ -1537,8 +1728,15 @@ static bool construct( · 15 unmodified lines | |||
| 1537 | if (!pool->base.irqs) | 1728 | if (!pool->base.irqs) |
| 1538 | goto create_fail; | 1729 | goto create_fail; |
| 1539 | 1730 | ||
| 1731 | j = 0; | ||
| 1540 | /* mem input -> ipp -> dpp -> opp -> TG */ | 1732 | /* mem input -> ipp -> dpp -> opp -> TG */ |
| 1541 | for (i = 0; i < pool->base.pipe_count; i++) { | 1733 | for (i = 0; i < pool->base.pipe_count; i++) { |
| 1734 | /* if pipe is disabled, skip instance of HW pipe, | ||
| 1735 | * i.e, skip ASIC register instance | ||
| 1736 | */ | ||
| 1737 | if ((pipe_fuses & (1 << i)) != 0) | ||
| 1738 | continue; | ||
| 1739 | |||
| 1542 | pool->base.hubps[i] = dcn21_hubp_create(ctx, i); | 1740 | pool->base.hubps[i] = dcn21_hubp_create(ctx, i); |
| 1543 | if (pool->base.hubps[i] == NULL) { | 1741 | if (pool->base.hubps[i] == NULL) { |
| 1544 | BREAK_TO_DEBUGGER(); | 1742 | BREAK_TO_DEBUGGER(); |
| @@ -1562,6 +1760,23 @@ static bool construct( · 17 unmodified lines | |||
| 1562 | "DC: failed to create dpps!\n"); | 1760 | "DC: failed to create dpps!\n"); |
| 1563 | goto create_fail; | 1761 | goto create_fail; |
| 1564 | } | 1762 | } |
| 1763 | |||
| 1764 | pool->base.opps[i] = dcn21_opp_create(ctx, i); | ||
| 1765 | if (pool->base.opps[i] == NULL) { | ||
| 1766 | BREAK_TO_DEBUGGER(); | ||
| 1767 | dm_error( | ||
| 1768 | "DC: failed to create output pixel processor!\n"); | ||
| 1769 | goto create_fail; | ||
| 1770 | } | ||
| 1771 | |||
| 1772 | pool->base.timing_generators[i] = dcn21_timing_generator_create( | ||
| 1773 | ctx, i); | ||
| 1774 | if (pool->base.timing_generators[i] == NULL) { | ||
| 1775 | BREAK_TO_DEBUGGER(); | ||
| 1776 | dm_error("DC: failed to create tg!\n"); | ||
| 1777 | goto create_fail; | ||
| 1778 | } | ||
| 1779 | j++; | ||
| 1565 | } | 1780 | } |
| 1566 | 1781 | ||
| 1567 | for (i = 0; i < pool->base.res_cap->num_ddc; i++) { | 1782 | for (i = 0; i < pool->base.res_cap->num_ddc; i++) { |
| @@ -1582,27 +1797,9 @@ static bool construct( · 14 unmodified lines | |||
| 1582 | pool->base.sw_i2cs[i] = NULL; | 1797 | pool->base.sw_i2cs[i] = NULL; |
| 1583 | } | 1798 | } |
| 1584 | 1799 | ||
| 1585 | for (i = 0; i < pool->base.res_cap->num_opp; i++) { | 1800 | pool->base.timing_generator_count = j; |
| 1586 | pool->base.opps[i] = dcn21_opp_create(ctx, i); | 1801 | pool->base.pipe_count = j; |
| 1587 | if (pool->base.opps[i] == NULL) { | 1802 | pool->base.mpcc_count = j; |
| 1588 | BREAK_TO_DEBUGGER(); | ||
| 1589 | dm_error( | ||
| 1590 | "DC: failed to create output pixel processor!\n"); | ||
| 1591 | goto create_fail; | ||
| 1592 | } | ||
| 1593 | } | ||
| 1594 | |||
| 1595 | for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) { | ||
| 1596 | pool->base.timing_generators[i] = dcn21_timing_generator_create( | ||
| 1597 | ctx, i); | ||
| 1598 | if (pool->base.timing_generators[i] == NULL) { | ||
| 1599 | BREAK_TO_DEBUGGER(); | ||
| 1600 | dm_error("DC: failed to create tg!\n"); | ||
| 1601 | goto create_fail; | ||
| 1602 | } | ||
| 1603 | } | ||
| 1604 | |||
| 1605 | pool->base.timing_generator_count = i; | ||
| 1606 | 1803 | ||
| 1607 | pool->base.mpc = dcn21_mpc_create(ctx); | 1804 | pool->base.mpc = dcn21_mpc_create(ctx); |
| 1608 | if (pool->base.mpc == NULL) { | 1805 | if (pool->base.mpc == NULL) { |
| @@ -1645,7 +1842,7 @@ static bool construct( · 36 unmodified lines | |||
| 1645 | &res_create_funcs : &res_create_maximus_funcs))) | 1842 | &res_create_funcs : &res_create_maximus_funcs))) |
| 1646 | goto create_fail; | 1843 | goto create_fail; |
| 1647 | 1844 | ||
| 1648 | dcn20_hw_sequencer_construct(dc); | 1845 | dcn21_hw_sequencer_construct(dc); |
| 1649 | 1846 | ||
| 1650 | dc->caps.max_planes = pool->base.pipe_count; | 1847 | dc->caps.max_planes = pool->base.pipe_count; |
| 1651 | 1848 | ||
| @@ -249,12 +249,10 @@ struct pp_smu_funcs_nv { · 248 unmodified lines | |||
| 249 | }; | 249 | }; |
| 250 | #endif | 250 | #endif |
| 251 | 251 | ||
| 252 | #if defined(CONFIG_DRM_AMD_DC_DCN2_1) | ||
| 253 | |||
| 254 | #define PP_SMU_NUM_SOCCLK_DPM_LEVELS 8 | 252 | #define PP_SMU_NUM_SOCCLK_DPM_LEVELS 8 |
| 255 | #define PP_SMU_NUM_DCFCLK_DPM_LEVELS 4 | 253 | #define PP_SMU_NUM_DCFCLK_DPM_LEVELS 8 |
| 256 | #define PP_SMU_NUM_FCLK_DPM_LEVELS 4 | 254 | #define PP_SMU_NUM_FCLK_DPM_LEVELS 8 |
| 257 | #define PP_SMU_NUM_MEMCLK_DPM_LEVELS 4 | 255 | #define PP_SMU_NUM_MEMCLK_DPM_LEVELS 8 |
| 258 | 256 | ||
| 259 | struct dpm_clock { | 257 | struct dpm_clock { |
| 260 | uint32_t Freq; // In MHz | 258 | uint32_t Freq; // In MHz |
| @@ -288,7 +286,6 @@ struct pp_smu_funcs_rn { · 27 unmodified lines | |||
| 288 | enum pp_smu_status (*get_dpm_clock_table) (struct pp_smu *pp, | 286 | enum pp_smu_status (*get_dpm_clock_table) (struct pp_smu *pp, |
| 289 | struct dpm_clocks *clock_table); | 287 | struct dpm_clocks *clock_table); |
| 290 | }; | 288 | }; |
| 291 | #endif | ||
| 292 | 289 | ||
| 293 | struct pp_smu_funcs { | 290 | struct pp_smu_funcs { |
| 294 | struct pp_smu ctx; | 291 | struct pp_smu ctx; |
| @@ -65,6 +65,7 @@ typedef struct { · 64 unmodified lines | |||
| 65 | 65 | ||
| 66 | #define BPP_INVALID 0 | 66 | #define BPP_INVALID 0 |
| 67 | #define BPP_BLENDED_PIPE 0xffffffff | 67 | #define BPP_BLENDED_PIPE 0xffffffff |
| 68 | #define DCN21_MAX_DSC_IMAGE_WIDTH 5184 | ||
| 68 | 69 | ||
| 69 | static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib); | 70 | static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib); |
| 70 | static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation( | 71 | static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation( |
| @@ -3379,6 +3380,8 @@ static unsigned int TruncToValidBPP( · 3308 unmodified lines | |||
| 3379 | return 30; | 3380 | return 30; |
| 3380 | else if (DecimalBPP >= 24 && (DesiredBPP == 0 || DesiredBPP == 24)) | 3381 | else if (DecimalBPP >= 24 && (DesiredBPP == 0 || DesiredBPP == 24)) |
| 3381 | return 24; | 3382 | return 24; |
| 3383 | else if (DecimalBPP >= 18 && (DesiredBPP == 0 || DesiredBPP == 18)) | ||
| 3384 | return 18; | ||
| 3382 | else | 3385 | else |
| 3383 | return BPP_INVALID; | 3386 | return BPP_INVALID; |
| 3384 | } | 3387 | } |
| @@ -3936,6 +3939,10 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 551 unmodified lines | |||
| 3936 | mode_lib->vba.MaximumSwathWidthInLineBuffer); | 3939 | mode_lib->vba.MaximumSwathWidthInLineBuffer); |
| 3937 | } | 3940 | } |
| 3938 | for (i = 0; i <= mode_lib->vba.soc.num_states; i++) { | 3941 | for (i = 0; i <= mode_lib->vba.soc.num_states; i++) { |
| 3942 | double MaxMaxDispclkRoundedDown = RoundToDFSGranularityDown( | ||
| 3943 | mode_lib->vba.MaxDispclk[mode_lib->vba.soc.num_states], | ||
| 3944 | mode_lib->vba.DISPCLKDPPCLKVCOSpeed); | ||
| 3945 | |||
| 3939 | for (j = 0; j < 2; j++) { | 3946 | for (j = 0; j < 2; j++) { |
| 3940 | mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown( | 3947 | mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown( |
| 3941 | mode_lib->vba.MaxDispclk[i], | 3948 | mode_lib->vba.MaxDispclk[i], |
| @@ -3965,7 +3972,9 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 23 unmodified lines | |||
| 3965 | && i == mode_lib->vba.soc.num_states) | 3972 | && i == mode_lib->vba.soc.num_states) |
| 3966 | mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2 | 3973 | mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2 |
| 3967 | * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0); | 3974 | * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0); |
| 3968 | if (mode_lib->vba.ODMCapability == false || mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine <= mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) { | 3975 | if (mode_lib->vba.ODMCapability == false || |
| 3976 | (locals->PlaneRequiredDISPCLKWithoutODMCombine <= MaxMaxDispclkRoundedDown | ||
| 3977 | && (!locals->DSCEnabled[k] || locals->HActive[k] <= DCN21_MAX_DSC_IMAGE_WIDTH))) { | ||
| 3969 | locals->ODMCombineEnablePerState[i][k] = false; | 3978 | locals->ODMCombineEnablePerState[i][k] = false; |
| 3970 | mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine; | 3979 | mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine; |
| 3971 | } else { | 3980 | } else { |
| @@ -269,7 +269,7 @@ struct writeback_st { · 268 unmodified lines | |||
| 269 | 269 | ||
| 270 | struct _vcs_dpi_display_output_params_st { | 270 | struct _vcs_dpi_display_output_params_st { |
| 271 | int dp_lanes; | 271 | int dp_lanes; |
| 272 | int output_bpp; | 272 | double output_bpp; |
| 273 | int dsc_enable; | 273 | int dsc_enable; |
| 274 | int wb_enable; | 274 | int wb_enable; |
| 275 | int num_active_wb; | 275 | int num_active_wb; |
| @@ -434,6 +434,8 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) · 433 unmodified lines | |||
| 434 | dst->odm_combine; | 434 | dst->odm_combine; |
| 435 | mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] = | 435 | mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] = |
| 436 | (enum output_format_class) (dout->output_format); | 436 | (enum output_format_class) (dout->output_format); |
| 437 | mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] = | ||
| 438 | dout->output_bpp; | ||
| 437 | mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] = | 439 | mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] = |
| 438 | (enum output_encoder_class) (dout->output_type); | 440 | (enum output_encoder_class) (dout->output_type); |
| 439 | 441 | ||
| @@ -105,6 +105,9 @@ int dc_link_aux_transfer_raw(struct ddc_service *ddc, · 104 unmodified lines | |||
| 105 | bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc, | 105 | bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc, |
| 106 | struct aux_payload *payload); | 106 | struct aux_payload *payload); |
| 107 | 107 | ||
| 108 | enum dc_status dc_link_aux_configure_timeout(struct ddc_service *ddc, | ||
| 109 | uint32_t timeout); | ||
| 110 | |||
| 108 | void dal_ddc_service_write_scdc_data( | 111 | void dal_ddc_service_write_scdc_data( |
| 109 | struct ddc_service *ddc_service, | 112 | struct ddc_service *ddc_service, |
| 110 | uint32_t pix_clk, | 113 | uint32_t pix_clk, |
| @@ -28,6 +28,8 @@ · 27 unmodified lines | |||
| 28 | 28 | ||
| 29 | #define LINK_TRAINING_ATTEMPTS 4 | 29 | #define LINK_TRAINING_ATTEMPTS 4 |
| 30 | #define LINK_TRAINING_RETRY_DELAY 50 /* ms */ | 30 | #define LINK_TRAINING_RETRY_DELAY 50 /* ms */ |
| 31 | #define LINK_AUX_DEFAULT_EXTENDED_TIMEOUT_PERIOD 32000 /*us*/ | ||
| 32 | #define LINK_AUX_DEFAULT_TIMEOUT_PERIOD 400 /*us*/ | ||
| 31 | 33 | ||
| 32 | struct dc_link; | 34 | struct dc_link; |
| 33 | struct dc_stream_state; | 35 | struct dc_stream_state; |
| @@ -43,6 +45,9 @@ bool dp_verify_link_cap_with_retries( · 9 unmodified lines | |||
| 43 | struct dc_link_settings *known_limit_link_setting, | 45 | struct dc_link_settings *known_limit_link_setting, |
| 44 | int attempts); | 46 | int attempts); |
| 45 | 47 | ||
| 48 | bool dp_verify_mst_link_cap( | ||
| 49 | struct dc_link *link); | ||
| 50 | |||
| 46 | bool dp_validate_mode_timing( | 51 | bool dp_validate_mode_timing( |
| 47 | struct dc_link *link, | 52 | struct dc_link *link, |
| 48 | const struct dc_crtc_timing *timing); | 53 | const struct dc_crtc_timing *timing); |
| @@ -140,6 +140,9 @@ struct write_command_context { · 139 unmodified lines | |||
| 140 | 140 | ||
| 141 | 141 | ||
| 142 | struct aux_engine_funcs { | 142 | struct aux_engine_funcs { |
| 143 | bool (*configure_timeout)( | ||
| 144 | struct ddc_service *ddc, | ||
| 145 | uint32_t timeout); | ||
| 143 | void (*destroy)( | 146 | void (*destroy)( |
| 144 | struct aux_engine **ptr); | 147 | struct aux_engine **ptr); |
| 145 | bool (*acquire_engine)( | 148 | bool (*acquire_engine)( |
| @@ -47,7 +47,7 @@ · 46 unmodified lines | |||
| 47 | #ifdef CONFIG_DRM_AMD_DC_DCN2_1 | 47 | #ifdef CONFIG_DRM_AMD_DC_DCN2_1 |
| 48 | /* Will these bw structures be ASIC specific? */ | 48 | /* Will these bw structures be ASIC specific? */ |
| 49 | 49 | ||
| 50 | #define MAX_NUM_DPM_LVL 4 | 50 | #define MAX_NUM_DPM_LVL 8 |
| 51 | #define WM_SET_COUNT 4 | 51 | #define WM_SET_COUNT 4 |
| 52 | 52 | ||
| 53 | 53 | ||
| @@ -149,6 +149,7 @@ struct wm_table { · 95 unmodified lines | |||
| 149 | struct clk_bw_params { | 149 | struct clk_bw_params { |
| 150 | unsigned int vram_type; | 150 | unsigned int vram_type; |
| 151 | unsigned int num_channels; | 151 | unsigned int num_channels; |
| 152 | unsigned int dispclk_vco_khz; | ||
| 152 | struct clk_limit_table clk_table; | 153 | struct clk_limit_table clk_table; |
| 153 | struct wm_table wm_table; | 154 | struct wm_table wm_table; |
| 154 | }; | 155 | }; |
| @@ -180,12 +181,16 @@ struct clk_mgr_funcs { · 25 unmodified lines | |||
| 180 | struct dc_state *context, | 181 | struct dc_state *context, |
| 181 | enum dc_clock_type clock_type, | 182 | enum dc_clock_type clock_type, |
| 182 | struct dc_clock_config *clock_cfg); | 183 | struct dc_clock_config *clock_cfg); |
| 184 | |||
| 185 | bool (*are_clock_states_equal) (struct dc_clocks *a, | ||
| 186 | struct dc_clocks *b); | ||
| 183 | }; | 187 | }; |
| 184 | 188 | ||
| 185 | struct clk_mgr { | 189 | struct clk_mgr { |
| 186 | struct dc_context *ctx; | 190 | struct dc_context *ctx; |
| 187 | struct clk_mgr_funcs *funcs; | 191 | struct clk_mgr_funcs *funcs; |
| 188 | struct dc_clocks clks; | 192 | struct dc_clocks clks; |
| 193 | bool psr_allow_active_cache; | ||
| 189 | int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes | 194 | int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes |
| 190 | #ifdef CONFIG_DRM_AMD_DC_DCN2_1 | 195 | #ifdef CONFIG_DRM_AMD_DC_DCN2_1 |
| 191 | struct clk_bw_params *bw_params; | 196 | struct clk_bw_params *bw_params; |
| @@ -199,4 +204,8 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p · 7 unmodified lines | |||
| 199 | 204 | ||
| 200 | void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr); | 205 | void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr); |
| 201 | 206 | ||
| 207 | void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr); | ||
| 208 | |||
| 209 | void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr); | ||
| 210 | |||
| 202 | #endif /* __DAL_CLK_MGR_H__ */ | 211 | #endif /* __DAL_CLK_MGR_H__ */ |
| @@ -184,6 +184,21 @@ struct clk_mgr_registers { · 183 unmodified lines | |||
| 184 | uint32_t MP1_SMN_C2PMSG_91; | 184 | uint32_t MP1_SMN_C2PMSG_91; |
| 185 | }; | 185 | }; |
| 186 | 186 | ||
| 187 | enum clock_type { | ||
| 188 | clock_type_dispclk = 1, | ||
| 189 | clock_type_dcfclk, | ||
| 190 | clock_type_socclk, | ||
| 191 | clock_type_pixelclk, | ||
| 192 | clock_type_phyclk, | ||
| 193 | clock_type_dppclk, | ||
| 194 | clock_type_fclk, | ||
| 195 | clock_type_dcfdsclk, | ||
| 196 | clock_type_dscclk, | ||
| 197 | clock_type_uclk, | ||
| 198 | clock_type_dramclk, | ||
| 199 | }; | ||
| 200 | |||
| 201 | |||
| 187 | struct state_dependent_clocks { | 202 | struct state_dependent_clocks { |
| 188 | int display_clk_khz; | 203 | int display_clk_khz; |
| 189 | int pixel_clk_khz; | 204 | int pixel_clk_khz; |
| @@ -281,8 +296,14 @@ static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_cl · 91 unmodified lines | |||
| 281 | 296 | ||
| 282 | static inline bool should_update_pstate_support(bool safe_to_lower, bool calc_support, bool cur_support) | 297 | static inline bool should_update_pstate_support(bool safe_to_lower, bool calc_support, bool cur_support) |
| 283 | { | 298 | { |
| 284 | // Whenever we are transitioning pstate support, we always want to notify prior to committing state | 299 | if (cur_support != calc_support) { |
| 285 | return (calc_support != cur_support) ? !safe_to_lower : false; | 300 | if (calc_support == true && safe_to_lower) |
| 301 | return true; | ||
| 302 | else if (calc_support == false && !safe_to_lower) | ||
| 303 | return true; | ||
| 304 | } | ||
| 305 | |||
| 306 | return false; | ||
| 286 | } | 307 | } |
| 287 | 308 | ||
| 288 | int clk_mgr_helper_get_active_display_cnt( | 309 | int clk_mgr_helper_get_active_display_cnt( |
| @@ -147,6 +147,7 @@ struct hubbub_funcs { · 146 unmodified lines | |||
| 147 | bool (*is_allow_self_refresh_enabled)(struct hubbub *hubbub); | 147 | bool (*is_allow_self_refresh_enabled)(struct hubbub *hubbub); |
| 148 | void (*allow_self_refresh_control)(struct hubbub *hubbub, bool allow); | 148 | void (*allow_self_refresh_control)(struct hubbub *hubbub, bool allow); |
| 149 | 149 | ||
| 150 | void (*apply_DEDCN21_147_wa)(struct hubbub *hubbub); | ||
| 150 | }; | 151 | }; |
| 151 | 152 | ||
| 152 | struct hubbub { | 153 | struct hubbub { |
| @@ -184,6 +184,10 @@ struct link_encoder_funcs { · 183 unmodified lines | |||
| 184 | bool (*fec_is_active)(struct link_encoder *enc); | 184 | bool (*fec_is_active)(struct link_encoder *enc); |
| 185 | #endif | 185 | #endif |
| 186 | bool (*is_in_alt_mode) (struct link_encoder *enc); | 186 | bool (*is_in_alt_mode) (struct link_encoder *enc); |
| 187 | |||
| 188 | void (*get_max_link_cap)(struct link_encoder *enc, | ||
| 189 | struct dc_link_settings *link_settings); | ||
| 190 | |||
| 187 | enum signal_type (*get_dig_mode)( | 191 | enum signal_type (*get_dig_mode)( |
| 188 | struct link_encoder *enc); | 192 | struct link_encoder *enc); |
| 189 | }; | 193 | }; |
| @@ -43,6 +43,7 @@ struct dcn_watermarks { · 42 unmodified lines | |||
| 43 | #if defined(CONFIG_DRM_AMD_DC_DCN2_1) | 43 | #if defined(CONFIG_DRM_AMD_DC_DCN2_1) |
| 44 | uint32_t frac_urg_bw_nom; | 44 | uint32_t frac_urg_bw_nom; |
| 45 | uint32_t frac_urg_bw_flip; | 45 | uint32_t frac_urg_bw_flip; |
| 46 | int32_t urgent_latency_ns; | ||
| 46 | #endif | 47 | #endif |
| 47 | struct cstate_pstate_watermarks_st cstate_pstate; | 48 | struct cstate_pstate_watermarks_st cstate_pstate; |
| 48 | }; | 49 | }; |
| @@ -208,6 +208,7 @@ struct output_pixel_processor { · 207 unmodified lines | |||
| 208 | struct mpc_tree mpc_tree_params; | 208 | struct mpc_tree mpc_tree_params; |
| 209 | bool mpcc_disconnect_pending[MAX_PIPES]; | 209 | bool mpcc_disconnect_pending[MAX_PIPES]; |
| 210 | const struct opp_funcs *funcs; | 210 | const struct opp_funcs *funcs; |
| 211 | uint32_t dyn_expansion; | ||
| 211 | }; | 212 | }; |
| 212 | 213 | ||
| 213 | enum fmt_stereo_action { | 214 | enum fmt_stereo_action { |
| @@ -214,6 +214,11 @@ struct stream_encoder_funcs { · 213 unmodified lines | |||
| 214 | unsigned int (*dig_source_otg)( | 214 | unsigned int (*dig_source_otg)( |
| 215 | struct stream_encoder *enc); | 215 | struct stream_encoder *enc); |
| 216 | 216 | ||
| 217 | bool (*dp_get_pixel_format)( | ||
| 218 | struct stream_encoder *enc, | ||
| 219 | enum dc_pixel_encoding *encoding, | ||
| 220 | enum dc_color_depth *depth); | ||
| 221 | |||
| 217 | #if defined(CONFIG_DRM_AMD_DC_DCN2_0) | 222 | #if defined(CONFIG_DRM_AMD_DC_DCN2_0) |
| 218 | #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT | 223 | #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT |
| 219 | void (*enc_read_state)(struct stream_encoder *enc, struct enc_state *s); | 224 | void (*enc_read_state)(struct stream_encoder *enc, struct enc_state *s); |
| @@ -261,6 +261,8 @@ struct timing_generator_funcs { · 260 unmodified lines | |||
| 261 | 261 | ||
| 262 | void (*program_manual_trigger)(struct timing_generator *optc); | 262 | void (*program_manual_trigger)(struct timing_generator *optc); |
| 263 | void (*setup_manual_trigger)(struct timing_generator *optc); | 263 | void (*setup_manual_trigger)(struct timing_generator *optc); |
| 264 | bool (*get_hw_timing)(struct timing_generator *optc, | ||
| 265 | struct dc_crtc_timing *hw_crtc_timing); | ||
| 264 | 266 | ||
| 265 | void (*set_vtg_params)(struct timing_generator *optc, | 267 | void (*set_vtg_params)(struct timing_generator *optc, |
| 266 | const struct dc_crtc_timing *dc_crtc_timing); | 268 | const struct dc_crtc_timing *dc_crtc_timing); |
| @@ -232,6 +232,13 @@ struct hw_sequencer_funcs { · 231 unmodified lines | |||
| 232 | struct dc *dc, | 232 | struct dc *dc, |
| 233 | struct dc_state *context); | 233 | struct dc_state *context); |
| 234 | 234 | ||
| 235 | void (*exit_optimized_pwr_state)( | ||
| 236 | const struct dc *dc, | ||
| 237 | struct dc_state *context); | ||
| 238 | void (*optimize_pwr_state)( | ||
| 239 | const struct dc *dc, | ||
| 240 | struct dc_state *context); | ||
| 241 | |||
| 235 | #if defined(CONFIG_DRM_AMD_DC_DCN2_0) | 242 | #if defined(CONFIG_DRM_AMD_DC_DCN2_0) |
| 236 | bool (*update_bandwidth)( | 243 | bool (*update_bandwidth)( |
| 237 | struct dc *dc, | 244 | struct dc *dc, |
| @@ -324,10 +331,12 @@ struct hw_sequencer_funcs { · 86 unmodified lines | |||
| 324 | struct dc_state *context); | 331 | struct dc_state *context); |
| 325 | void (*update_writeback)(struct dc *dc, | 332 | void (*update_writeback)(struct dc *dc, |
| 326 | const struct dc_stream_status *stream_status, | 333 | const struct dc_stream_status *stream_status, |
| 327 | struct dc_writeback_info *wb_info); | 334 | struct dc_writeback_info *wb_info, |
| 335 | struct dc_state *context); | ||
| 328 | void (*enable_writeback)(struct dc *dc, | 336 | void (*enable_writeback)(struct dc *dc, |
| 329 | const struct dc_stream_status *stream_status, | 337 | const struct dc_stream_status *stream_status, |
| 330 | struct dc_writeback_info *wb_info); | 338 | struct dc_writeback_info *wb_info, |
| 339 | struct dc_state *context); | ||
| 331 | void (*disable_writeback)(struct dc *dc, | 340 | void (*disable_writeback)(struct dc *dc, |
| 332 | unsigned int dwb_pipe_inst); | 341 | unsigned int dwb_pipe_inst); |
| 333 | #endif | 342 | #endif |
| @@ -340,6 +349,9 @@ struct hw_sequencer_funcs { · 6 unmodified lines | |||
| 340 | enum dc_clock_type clock_type, | 349 | enum dc_clock_type clock_type, |
| 341 | struct dc_clock_config *clock_cfg); | 350 | struct dc_clock_config *clock_cfg); |
| 342 | 351 | ||
| 352 | #if defined(CONFIG_DRM_AMD_DC_DCN2_1) | ||
| 353 | bool (*s0i3_golden_init_wa)(struct dc *dc); | ||
| 354 | #endif | ||
| 343 | }; | 355 | }; |
| 344 | 356 | ||
| 345 | void color_space_to_black_color( | 357 | void color_space_to_black_color( |
| @@ -31,6 +31,8 @@ · 30 unmodified lines | |||
| 31 | #define DP_BRANCH_DEVICE_ID_0022B9 0x0022B9 | 31 | #define DP_BRANCH_DEVICE_ID_0022B9 0x0022B9 |
| 32 | #define DP_BRANCH_DEVICE_ID_00001A 0x00001A | 32 | #define DP_BRANCH_DEVICE_ID_00001A 0x00001A |
| 33 | #define DP_BRANCH_DEVICE_ID_0080E1 0x0080e1 | 33 | #define DP_BRANCH_DEVICE_ID_0080E1 0x0080e1 |
| 34 | #define DP_BRANCH_DEVICE_ID_90CC24 0x90CC24 | ||
| 35 | #define DP_BRANCH_DEVICE_ID_00E04C 0x00E04C | ||
| 34 | 36 | ||
| 35 | enum ddc_result { | 37 | enum ddc_result { |
| 36 | DDC_RESULT_UNKNOWN = 0, | 38 | DDC_RESULT_UNKNOWN = 0, |
| @@ -234,6 +234,10 @@ static void update_v_total_for_static_ramp( · 233 unmodified lines | |||
| 234 | current_duration_in_us) * (stream->timing.pix_clk_100hz / 10)), | 234 | current_duration_in_us) * (stream->timing.pix_clk_100hz / 10)), |
| 235 | stream->timing.h_total), 1000); | 235 | stream->timing.h_total), 1000); |
| 236 | 236 | ||
| 237 | /* v_total cannot be less than nominal */ | ||
| 238 | if (v_total < stream->timing.v_total) | ||
| 239 | v_total = stream->timing.v_total; | ||
| 240 | |||
| 237 | in_out_vrr->adjust.v_total_min = v_total; | 241 | in_out_vrr->adjust.v_total_min = v_total; |
| 238 | in_out_vrr->adjust.v_total_max = v_total; | 242 | in_out_vrr->adjust.v_total_max = v_total; |
| 239 | } | 243 | } |
| @@ -743,6 +747,10 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, · 503 unmodified lines | |||
| 743 | nominal_field_rate_in_uhz = | 747 | nominal_field_rate_in_uhz = |
| 744 | mod_freesync_calc_nominal_field_rate(stream); | 748 | mod_freesync_calc_nominal_field_rate(stream); |
| 745 | 749 | ||
| 750 | /* Rounded to the nearest Hz */ | ||
| 751 | nominal_field_rate_in_uhz = 1000000ULL * | ||
| 752 | div_u64(nominal_field_rate_in_uhz + 500000, 1000000); | ||
| 753 | |||
| 746 | min_refresh_in_uhz = in_config->min_refresh_in_uhz; | 754 | min_refresh_in_uhz = in_config->min_refresh_in_uhz; |
| 747 | max_refresh_in_uhz = in_config->max_refresh_in_uhz; | 755 | max_refresh_in_uhz = in_config->max_refresh_in_uhz; |
| 748 | 756 | ||
| @@ -998,14 +1006,13 @@ unsigned long long mod_freesync_calc_nominal_field_rate( · 249 unmodified lines | |||
| 998 | const struct dc_stream_state *stream) | 1006 | const struct dc_stream_state *stream) |
| 999 | { | 1007 | { |
| 1000 | unsigned long long nominal_field_rate_in_uhz = 0; | 1008 | unsigned long long nominal_field_rate_in_uhz = 0; |
| 1009 | unsigned int total = stream->timing.h_total * stream->timing.v_total; | ||
| 1001 | 1010 | ||
| 1002 | /* Calculate nominal field rate for stream */ | 1011 | /* Calculate nominal field rate for stream, rounded up to nearest integer */ |
| 1003 | nominal_field_rate_in_uhz = stream->timing.pix_clk_100hz / 10; | 1012 | nominal_field_rate_in_uhz = stream->timing.pix_clk_100hz / 10; |
| 1004 | nominal_field_rate_in_uhz *= 1000ULL * 1000ULL * 1000ULL; | 1013 | nominal_field_rate_in_uhz *= 1000ULL * 1000ULL * 1000ULL; |
| 1005 | nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz, | 1014 | |
| 1006 | stream->timing.h_total); | 1015 | nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz, total); |
| 1007 | nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz, | ||
| 1008 | stream->timing.v_total); | ||
| 1009 | 1016 | ||
| 1010 | return nominal_field_rate_in_uhz; | 1017 | return nominal_field_rate_in_uhz; |
| 1011 | } | 1018 | } |
| @@ -35,4 +35,7 @@ struct mod_vrr_params; · 34 unmodified lines | |||
| 35 | void mod_build_vsc_infopacket(const struct dc_stream_state *stream, | 35 | void mod_build_vsc_infopacket(const struct dc_stream_state *stream, |
| 36 | struct dc_info_packet *info_packet); | 36 | struct dc_info_packet *info_packet); |
| 37 | 37 | ||
| 38 | void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream, | ||
| 39 | struct dc_info_packet *info_packet, int ALLMEnabled, int ALLMValue); | ||
| 40 | |||
| 38 | #endif | 41 | #endif |
| @@ -31,6 +31,7 @@ · 30 unmodified lines | |||
| 31 | #include "dc.h" | 31 | #include "dc.h" |
| 32 | 32 | ||
| 33 | #define HDMI_INFOFRAME_TYPE_VENDOR 0x81 | 33 | #define HDMI_INFOFRAME_TYPE_VENDOR 0x81 |
| 34 | #define HF_VSIF_VERSION 1 | ||
| 34 | 35 | ||
| 35 | // VTEM Byte Offset | 36 | // VTEM Byte Offset |
| 36 | #define VTEM_PB0 0 | 37 | #define VTEM_PB0 0 |
| @@ -395,3 +396,100 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream, · 358 unmodified lines | |||
| 395 | 396 | ||
| 396 | } | 397 | } |
| 397 | 398 | ||
| 399 | /** | ||
| 400 | ***************************************************************************** | ||
| 401 | * Function: mod_build_hf_vsif_infopacket | ||
| 402 | * | ||
| 403 | * @brief | ||
| 404 | * Prepare HDMI Vendor Specific info frame. | ||
| 405 | * Follows HDMI Spec to build up Vendor Specific info frame | ||
| 406 | * | ||
| 407 | * @param [in] stream: contains data we may need to construct VSIF (i.e. timing_3d_format, etc.) | ||
| 408 | * @param [out] info_packet: output structure where to store VSIF | ||
| 409 | ***************************************************************************** | ||
| 410 | */ | ||
| 411 | void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream, | ||
| 412 | struct dc_info_packet *info_packet, int ALLMEnabled, int ALLMValue) | ||
| 413 | { | ||
| 414 | unsigned int length = 5; | ||
| 415 | bool hdmi_vic_mode = false; | ||
| 416 | uint8_t checksum = 0; | ||
| 417 | uint32_t i = 0; | ||
| 418 | enum dc_timing_3d_format format; | ||
| 419 | bool bALLM = (bool)ALLMEnabled; | ||
| 420 | bool bALLMVal = (bool)ALLMValue; | ||
| 421 | |||
| 422 | info_packet->valid = false; | ||
| 423 | format = stream->timing.timing_3d_format; | ||
| 424 | if (stream->view_format == VIEW_3D_FORMAT_NONE) | ||
| 425 | format = TIMING_3D_FORMAT_NONE; | ||
| 426 | |||
| 427 | if (stream->timing.hdmi_vic != 0 | ||
| 428 | && stream->timing.h_total >= 3840 | ||
| 429 | && stream->timing.v_total >= 2160 | ||
| 430 | && format == TIMING_3D_FORMAT_NONE) | ||
| 431 | hdmi_vic_mode = true; | ||
| 432 | |||
| 433 | if ((format == TIMING_3D_FORMAT_NONE) && !hdmi_vic_mode && !bALLM) | ||
| 434 | return; | ||
| 435 | |||
| 436 | info_packet->sb[1] = 0x03; | ||
| 437 | info_packet->sb[2] = 0x0C; | ||
| 438 | info_packet->sb[3] = 0x00; | ||
| 439 | |||
| 440 | if (bALLM) { | ||
| 441 | info_packet->sb[1] = 0xD8; | ||
| 442 | info_packet->sb[2] = 0x5D; | ||
| 443 | info_packet->sb[3] = 0xC4; | ||
| 444 | info_packet->sb[4] = HF_VSIF_VERSION; | ||
| 445 | } | ||
| 446 | |||
| 447 | if (format != TIMING_3D_FORMAT_NONE) | ||
| 448 | info_packet->sb[4] = (2 << 5); | ||
| 449 | |||
| 450 | else if (hdmi_vic_mode) | ||
| 451 | info_packet->sb[4] = (1 << 5); | ||
| 452 | |||
| 453 | switch (format) { | ||
| 454 | case TIMING_3D_FORMAT_HW_FRAME_PACKING: | ||
| 455 | case TIMING_3D_FORMAT_SW_FRAME_PACKING: | ||
| 456 | info_packet->sb[5] = (0x0 << 4); | ||
| 457 | break; | ||
| 458 | |||
| 459 | case TIMING_3D_FORMAT_SIDE_BY_SIDE: | ||
| 460 | case TIMING_3D_FORMAT_SBS_SW_PACKED: | ||
| 461 | info_packet->sb[5] = (0x8 << 4); | ||
| 462 | length = 6; | ||
| 463 | break; | ||
| 464 | |||
| 465 | case TIMING_3D_FORMAT_TOP_AND_BOTTOM: | ||
| 466 | case TIMING_3D_FORMAT_TB_SW_PACKED: | ||
| 467 | info_packet->sb[5] = (0x6 << 4); | ||
| 468 | break; | ||
| 469 | |||
| 470 | default: | ||
| 471 | break; | ||
| 472 | } | ||
| 473 | |||
| 474 | if (hdmi_vic_mode) | ||
| 475 | info_packet->sb[5] = stream->timing.hdmi_vic; | ||
| 476 | |||
| 477 | info_packet->hb0 = HDMI_INFOFRAME_TYPE_VENDOR; | ||
| 478 | info_packet->hb1 = 0x01; | ||
| 479 | info_packet->hb2 = (uint8_t) (length); | ||
| 480 | |||
| 481 | if (bALLM) | ||
| 482 | info_packet->sb[5] = (info_packet->sb[5] & ~0x02) | (bALLMVal << 1); | ||
| 483 | |||
| 484 | checksum += info_packet->hb0; | ||
| 485 | checksum += info_packet->hb1; | ||
| 486 | checksum += info_packet->hb2; | ||
| 487 | |||
| 488 | for (i = 1; i <= length; i++) | ||
| 489 | checksum += info_packet->sb[i]; | ||
| 490 | |||
| 491 | info_packet->sb[0] = (uint8_t) (0x100 - checksum); | ||
| 492 | |||
| 493 | info_packet->valid = true; | ||
| 494 | } | ||
| 495 | |||
| @@ -27,6 +27,7 @@ · 26 unmodified lines | |||
| 27 | #define mmMM_INDEX 0x0 | 27 | #define mmMM_INDEX 0x0 |
| 28 | #define mmMM_INDEX_HI 0x6 | 28 | #define mmMM_INDEX_HI 0x6 |
| 29 | #define mmMM_DATA 0x1 | 29 | #define mmMM_DATA 0x1 |
| 30 | #define mmCC_BIF_BX_FUSESTRAP0 0x14D7 | ||
| 30 | #define mmBUS_CNTL 0x1508 | 31 | #define mmBUS_CNTL 0x1508 |
| 31 | #define mmCONFIG_CNTL 0x1509 | 32 | #define mmCONFIG_CNTL 0x1509 |
| 32 | #define mmCONFIG_MEMSIZE 0x150a | 33 | #define mmCONFIG_MEMSIZE 0x150a |
| @@ -32,6 +32,8 @@ · 31 unmodified lines | |||
| 32 | #define MM_INDEX_HI__MM_OFFSET_HI__SHIFT 0x0 | 32 | #define MM_INDEX_HI__MM_OFFSET_HI__SHIFT 0x0 |
| 33 | #define MM_DATA__MM_DATA_MASK 0xffffffff | 33 | #define MM_DATA__MM_DATA_MASK 0xffffffff |
| 34 | #define MM_DATA__MM_DATA__SHIFT 0x0 | 34 | #define MM_DATA__MM_DATA__SHIFT 0x0 |
| 35 | #define CC_BIF_BX_FUSESTRAP0__STRAP_BIF_PX_CAPABLE_MASK 0x2 | ||
| 36 | #define CC_BIF_BX_FUSESTRAP0__STRAP_BIF_PX_CAPABLE__SHIFT 0x1 | ||
| 35 | #define BUS_CNTL__BIOS_ROM_WRT_EN_MASK 0x1 | 37 | #define BUS_CNTL__BIOS_ROM_WRT_EN_MASK 0x1 |
| 36 | #define BUS_CNTL__BIOS_ROM_WRT_EN__SHIFT 0x0 | 38 | #define BUS_CNTL__BIOS_ROM_WRT_EN__SHIFT 0x0 |
| 37 | #define BUS_CNTL__BIOS_ROM_DIS_MASK 0x2 | 39 | #define BUS_CNTL__BIOS_ROM_DIS_MASK 0x2 |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | |||
| 27 | #define mmMM_INDEX 0x0 | 27 | #define mmMM_INDEX 0x0 |
| 28 | #define mmMM_INDEX_HI 0x6 | 28 | #define mmMM_INDEX_HI 0x6 |
| 29 | #define mmMM_DATA 0x1 | 29 | #define mmMM_DATA 0x1 |
| 30 | #define mmCC_BIF_BX_FUSESTRAP0 0x14D7 | ||
| 30 | #define mmCC_BIF_BX_STRAP2 0x152A | 31 | #define mmCC_BIF_BX_STRAP2 0x152A |
| 31 | #define mmBIF_MM_INDACCESS_CNTL 0x1500 | 32 | #define mmBIF_MM_INDACCESS_CNTL 0x1500 |
| 32 | #define mmBIF_DOORBELL_APER_EN 0x1501 | 33 | #define mmBIF_DOORBELL_APER_EN 0x1501 |
| @@ -32,6 +32,8 @@ · 31 unmodified lines | |||
| 32 | #define MM_INDEX_HI__MM_OFFSET_HI__SHIFT 0x0 | 32 | #define MM_INDEX_HI__MM_OFFSET_HI__SHIFT 0x0 |
| 33 | #define MM_DATA__MM_DATA_MASK 0xffffffff | 33 | #define MM_DATA__MM_DATA_MASK 0xffffffff |
| 34 | #define MM_DATA__MM_DATA__SHIFT 0x0 | 34 | #define MM_DATA__MM_DATA__SHIFT 0x0 |
| 35 | #define CC_BIF_BX_FUSESTRAP0__STRAP_BIF_PX_CAPABLE_MASK 0x2 | ||
| 36 | #define CC_BIF_BX_FUSESTRAP0__STRAP_BIF_PX_CAPABLE__SHIFT 0x1 | ||
| 35 | #define BIF_MM_INDACCESS_CNTL__MM_INDACCESS_DIS_MASK 0x2 | 37 | #define BIF_MM_INDACCESS_CNTL__MM_INDACCESS_DIS_MASK 0x2 |
| 36 | #define BIF_MM_INDACCESS_CNTL__MM_INDACCESS_DIS__SHIFT 0x1 | 38 | #define BIF_MM_INDACCESS_CNTL__MM_INDACCESS_DIS__SHIFT 0x1 |
| 37 | #define BIF_DOORBELL_APER_EN__BIF_DOORBELL_APER_EN_MASK 0x1 | 39 | #define BIF_DOORBELL_APER_EN__BIF_DOORBELL_APER_EN_MASK 0x1 |
| @@ -9859,6 +9859,8 @@ · 9858 unmodified lines | |||
| 9859 | #define mmDP0_DP_STEER_FIFO_BASE_IDX 2 | 9859 | #define mmDP0_DP_STEER_FIFO_BASE_IDX 2 |
| 9860 | #define mmDP0_DP_MSA_MISC 0x210e | 9860 | #define mmDP0_DP_MSA_MISC 0x210e |
| 9861 | #define mmDP0_DP_MSA_MISC_BASE_IDX 2 | 9861 | #define mmDP0_DP_MSA_MISC_BASE_IDX 2 |
| 9862 | #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f | ||
| 9863 | #define mmDP0_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 | ||
| 9862 | #define mmDP0_DP_VID_TIMING 0x2110 | 9864 | #define mmDP0_DP_VID_TIMING 0x2110 |
| 9863 | #define mmDP0_DP_VID_TIMING_BASE_IDX 2 | 9865 | #define mmDP0_DP_VID_TIMING_BASE_IDX 2 |
| 9864 | #define mmDP0_DP_VID_N 0x2111 | 9866 | #define mmDP0_DP_VID_N 0x2111 |
| @@ -10187,6 +10189,8 @@ · 322 unmodified lines | |||
| 10187 | #define mmDP1_DP_STEER_FIFO_BASE_IDX 2 | 10189 | #define mmDP1_DP_STEER_FIFO_BASE_IDX 2 |
| 10188 | #define mmDP1_DP_MSA_MISC 0x220e | 10190 | #define mmDP1_DP_MSA_MISC 0x220e |
| 10189 | #define mmDP1_DP_MSA_MISC_BASE_IDX 2 | 10191 | #define mmDP1_DP_MSA_MISC_BASE_IDX 2 |
| 10192 | #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x220f | ||
| 10193 | #define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 | ||
| 10190 | #define mmDP1_DP_VID_TIMING 0x2210 | 10194 | #define mmDP1_DP_VID_TIMING 0x2210 |
| 10191 | #define mmDP1_DP_VID_TIMING_BASE_IDX 2 | 10195 | #define mmDP1_DP_VID_TIMING_BASE_IDX 2 |
| 10192 | #define mmDP1_DP_VID_N 0x2211 | 10196 | #define mmDP1_DP_VID_N 0x2211 |
| @@ -10515,6 +10519,8 @@ · 322 unmodified lines | |||
| 10515 | #define mmDP2_DP_STEER_FIFO_BASE_IDX 2 | 10519 | #define mmDP2_DP_STEER_FIFO_BASE_IDX 2 |
| 10516 | #define mmDP2_DP_MSA_MISC 0x230e | 10520 | #define mmDP2_DP_MSA_MISC 0x230e |
| 10517 | #define mmDP2_DP_MSA_MISC_BASE_IDX 2 | 10521 | #define mmDP2_DP_MSA_MISC_BASE_IDX 2 |
| 10522 | #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x230f | ||
| 10523 | #define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 | ||
| 10518 | #define mmDP2_DP_VID_TIMING 0x2310 | 10524 | #define mmDP2_DP_VID_TIMING 0x2310 |
| 10519 | #define mmDP2_DP_VID_TIMING_BASE_IDX 2 | 10525 | #define mmDP2_DP_VID_TIMING_BASE_IDX 2 |
| 10520 | #define mmDP2_DP_VID_N 0x2311 | 10526 | #define mmDP2_DP_VID_N 0x2311 |
| @@ -10843,6 +10849,8 @@ · 322 unmodified lines | |||
| 10843 | #define mmDP3_DP_STEER_FIFO_BASE_IDX 2 | 10849 | #define mmDP3_DP_STEER_FIFO_BASE_IDX 2 |
| 10844 | #define mmDP3_DP_MSA_MISC 0x240e | 10850 | #define mmDP3_DP_MSA_MISC 0x240e |
| 10845 | #define mmDP3_DP_MSA_MISC_BASE_IDX 2 | 10851 | #define mmDP3_DP_MSA_MISC_BASE_IDX 2 |
| 10852 | #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x240f | ||
| 10853 | #define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 | ||
| 10846 | #define mmDP3_DP_VID_TIMING 0x2410 | 10854 | #define mmDP3_DP_VID_TIMING 0x2410 |
| 10847 | #define mmDP3_DP_VID_TIMING_BASE_IDX 2 | 10855 | #define mmDP3_DP_VID_TIMING_BASE_IDX 2 |
| 10848 | #define mmDP3_DP_VID_N 0x2411 | 10856 | #define mmDP3_DP_VID_N 0x2411 |
| @@ -11171,6 +11179,8 @@ · 322 unmodified lines | |||
| 11171 | #define mmDP4_DP_STEER_FIFO_BASE_IDX 2 | 11179 | #define mmDP4_DP_STEER_FIFO_BASE_IDX 2 |
| 11172 | #define mmDP4_DP_MSA_MISC 0x250e | 11180 | #define mmDP4_DP_MSA_MISC 0x250e |
| 11173 | #define mmDP4_DP_MSA_MISC_BASE_IDX 2 | 11181 | #define mmDP4_DP_MSA_MISC_BASE_IDX 2 |
| 11182 | #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x250f | ||
| 11183 | #define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 | ||
| 11174 | #define mmDP4_DP_VID_TIMING 0x2510 | 11184 | #define mmDP4_DP_VID_TIMING 0x2510 |
| 11175 | #define mmDP4_DP_VID_TIMING_BASE_IDX 2 | 11185 | #define mmDP4_DP_VID_TIMING_BASE_IDX 2 |
| 11176 | #define mmDP4_DP_VID_N 0x2511 | 11186 | #define mmDP4_DP_VID_N 0x2511 |
| @@ -1146,7 +1146,14 @@ · 1145 unmodified lines | |||
| 1146 | #define mmATC_L2_MEM_POWER_LS_BASE_IDX 0 | 1146 | #define mmATC_L2_MEM_POWER_LS_BASE_IDX 0 |
| 1147 | #define mmATC_L2_CGTT_CLK_CTRL 0x080c | 1147 | #define mmATC_L2_CGTT_CLK_CTRL 0x080c |
| 1148 | #define mmATC_L2_CGTT_CLK_CTRL_BASE_IDX 0 | 1148 | #define mmATC_L2_CGTT_CLK_CTRL_BASE_IDX 0 |
| 1149 | 1149 | #define mmATC_L2_CACHE_4K_EDC_INDEX 0x080e | |
| 1150 | #define mmATC_L2_CACHE_4K_EDC_INDEX_BASE_IDX 0 | ||
| 1151 | #define mmATC_L2_CACHE_2M_EDC_INDEX 0x080f | ||
| 1152 | #define mmATC_L2_CACHE_2M_EDC_INDEX_BASE_IDX 0 | ||
| 1153 | #define mmATC_L2_CACHE_4K_EDC_CNT 0x0810 | ||
| 1154 | #define mmATC_L2_CACHE_4K_EDC_CNT_BASE_IDX 0 | ||
| 1155 | #define mmATC_L2_CACHE_2M_EDC_CNT 0x0811 | ||
| 1156 | #define mmATC_L2_CACHE_2M_EDC_CNT_BASE_IDX 0 | ||
| 1150 | 1157 | ||
| 1151 | // addressBlock: gc_utcl2_vml2pfdec | 1158 | // addressBlock: gc_utcl2_vml2pfdec |
| 1152 | // base address: 0xa100 | 1159 | // base address: 0xa100 |
| @@ -1206,7 +1213,14 @@ · 53 unmodified lines | |||
| 1206 | #define mmVM_L2_CACHE_PARITY_CNTL_BASE_IDX 0 | 1213 | #define mmVM_L2_CACHE_PARITY_CNTL_BASE_IDX 0 |
| 1207 | #define mmVM_L2_CGTT_CLK_CTRL 0x085e | 1214 | #define mmVM_L2_CGTT_CLK_CTRL 0x085e |
| 1208 | #define mmVM_L2_CGTT_CLK_CTRL_BASE_IDX 0 | 1215 | #define mmVM_L2_CGTT_CLK_CTRL_BASE_IDX 0 |
| 1209 | 1216 | #define mmVM_L2_MEM_ECC_INDEX 0x0860 | |
| 1217 | #define mmVM_L2_MEM_ECC_INDEX_BASE_IDX 0 | ||
| 1218 | #define mmVM_L2_WALKER_MEM_ECC_INDEX 0x0861 | ||
| 1219 | #define mmVM_L2_WALKER_MEM_ECC_INDEX_BASE_IDX 0 | ||
| 1220 | #define mmVM_L2_MEM_ECC_CNT 0x0862 | ||
| 1221 | #define mmVM_L2_MEM_ECC_CNT_BASE_IDX 0 | ||
| 1222 | #define mmVM_L2_WALKER_MEM_ECC_CNT 0x0863 | ||
| 1223 | #define mmVM_L2_WALKER_MEM_ECC_CNT_BASE_IDX 0 | ||
| 1210 | 1224 | ||
| 1211 | // addressBlock: gc_utcl2_vml2vcdec | 1225 | // addressBlock: gc_utcl2_vml2vcdec |
| 1212 | // base address: 0xa200 | 1226 | // base address: 0xa200 |
| @@ -6661,7 +6661,6 @@ · 6660 unmodified lines | |||
| 6661 | #define ATC_L2_CGTT_CLK_CTRL__SOFT_STALL_OVERRIDE_MASK 0x00FF0000L | 6661 | #define ATC_L2_CGTT_CLK_CTRL__SOFT_STALL_OVERRIDE_MASK 0x00FF0000L |
| 6662 | #define ATC_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK 0xFF000000L | 6662 | #define ATC_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK 0xFF000000L |
| 6663 | 6663 | ||
| 6664 | |||
| 6665 | // addressBlock: gc_utcl2_vml2pfdec | 6664 | // addressBlock: gc_utcl2_vml2pfdec |
| 6666 | //VM_L2_CNTL | 6665 | //VM_L2_CNTL |
| 6667 | #define VM_L2_CNTL__ENABLE_L2_CACHE__SHIFT 0x0 | 6666 | #define VM_L2_CNTL__ENABLE_L2_CACHE__SHIFT 0x0 |
| @@ -6991,7 +6990,22 @@ · 323 unmodified lines | |||
| 6991 | #define VM_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK 0x00008000L | 6990 | #define VM_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK 0x00008000L |
| 6992 | #define VM_L2_CGTT_CLK_CTRL__SOFT_STALL_OVERRIDE_MASK 0x00FF0000L | 6991 | #define VM_L2_CGTT_CLK_CTRL__SOFT_STALL_OVERRIDE_MASK 0x00FF0000L |
| 6993 | #define VM_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK 0xFF000000L | 6992 | #define VM_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK 0xFF000000L |
| 6994 | 6993 | //VM_L2_MEM_ECC_INDEX | |
| 6994 | #define VM_L2_MEM_ECC_INDEX__INDEX__SHIFT 0x0 | ||
| 6995 | #define VM_L2_MEM_ECC_INDEX__INDEX_MASK 0x000000FFL | ||
| 6996 | //VM_L2_WALKER_MEM_ECC_INDEX | ||
| 6997 | #define VM_L2_WALKER_MEM_ECC_INDEX__INDEX__SHIFT 0x0 | ||
| 6998 | #define VM_L2_WALKER_MEM_ECC_INDEX__INDEX_MASK 0x000000FFL | ||
| 6999 | //VM_L2_MEM_ECC_CNT | ||
| 7000 | #define VM_L2_MEM_ECC_CNT__SEC_COUNT__SHIFT 0xc | ||
| 7001 | #define VM_L2_MEM_ECC_CNT__DED_COUNT__SHIFT 0xe | ||
| 7002 | #define VM_L2_MEM_ECC_CNT__SEC_COUNT_MASK 0x00003000L | ||
| 7003 | #define VM_L2_MEM_ECC_CNT__DED_COUNT_MASK 0x0000C000L | ||
| 7004 | //VM_L2_WALKER_MEM_ECC_CNT | ||
| 7005 | #define VM_L2_WALKER_MEM_ECC_CNT__SEC_COUNT__SHIFT 0xc | ||
| 7006 | #define VM_L2_WALKER_MEM_ECC_CNT__DED_COUNT__SHIFT 0xe | ||
| 7007 | #define VM_L2_WALKER_MEM_ECC_CNT__SEC_COUNT_MASK 0x00003000L | ||
| 7008 | #define VM_L2_WALKER_MEM_ECC_CNT__DED_COUNT_MASK 0x0000C000L | ||
| 6995 | 7009 | ||
| 6996 | // addressBlock: gc_utcl2_vml2vcdec | 7010 | // addressBlock: gc_utcl2_vml2vcdec |
| 6997 | //VM_CONTEXT0_CNTL | 7011 | //VM_CONTEXT0_CNTL |
| @@ -49,6 +49,7 @@ · 48 unmodified lines | |||
| 49 | #define ixCG_SPLL_FUNC_CNTL_5 0xc0500150 | 49 | #define ixCG_SPLL_FUNC_CNTL_5 0xc0500150 |
| 50 | #define ixCG_SPLL_FUNC_CNTL_6 0xc0500154 | 50 | #define ixCG_SPLL_FUNC_CNTL_6 0xc0500154 |
| 51 | #define ixCG_SPLL_FUNC_CNTL_7 0xc0500158 | 51 | #define ixCG_SPLL_FUNC_CNTL_7 0xc0500158 |
| 52 | #define ixCG_SPLL_STATUS 0xC050015C | ||
| 52 | #define ixSPLL_CNTL_MODE 0xc0500160 | 53 | #define ixSPLL_CNTL_MODE 0xc0500160 |
| 53 | #define ixCG_SPLL_SPREAD_SPECTRUM 0xc0500164 | 54 | #define ixCG_SPLL_SPREAD_SPECTRUM 0xc0500164 |
| 54 | #define ixCG_SPLL_SPREAD_SPECTRUM_2 0xc0500168 | 55 | #define ixCG_SPLL_SPREAD_SPECTRUM_2 0xc0500168 |
| @@ -194,6 +194,8 @@ · 193 unmodified lines | |||
| 194 | #define CG_SPLL_FUNC_CNTL_6__SPLL_LF_CNTR__SHIFT 0x19 | 194 | #define CG_SPLL_FUNC_CNTL_6__SPLL_LF_CNTR__SHIFT 0x19 |
| 195 | #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL_MASK 0xfff | 195 | #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL_MASK 0xfff |
| 196 | #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL__SHIFT 0x0 | 196 | #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL__SHIFT 0x0 |
| 197 | #define CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK 0x2 | ||
| 198 | #define CG_SPLL_STATUS__SPLL_CHG_STATUS__SHIFT 0x1 | ||
| 197 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL_MASK 0x1 | 199 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL_MASK 0x1 |
| 198 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL__SHIFT 0x0 | 200 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL__SHIFT 0x0 |
| 199 | #define SPLL_CNTL_MODE__SPLL_LEGACY_PDIV_MASK 0x2 | 201 | #define SPLL_CNTL_MODE__SPLL_LEGACY_PDIV_MASK 0x2 |
| @@ -49,6 +49,7 @@ · 48 unmodified lines | |||
| 49 | #define ixCG_SPLL_FUNC_CNTL_5 0xc0500150 | 49 | #define ixCG_SPLL_FUNC_CNTL_5 0xc0500150 |
| 50 | #define ixCG_SPLL_FUNC_CNTL_6 0xc0500154 | 50 | #define ixCG_SPLL_FUNC_CNTL_6 0xc0500154 |
| 51 | #define ixCG_SPLL_FUNC_CNTL_7 0xc0500158 | 51 | #define ixCG_SPLL_FUNC_CNTL_7 0xc0500158 |
| 52 | #define ixCG_SPLL_STATUS 0xC050015C | ||
| 52 | #define ixSPLL_CNTL_MODE 0xc0500160 | 53 | #define ixSPLL_CNTL_MODE 0xc0500160 |
| 53 | #define ixCG_SPLL_SPREAD_SPECTRUM 0xc0500164 | 54 | #define ixCG_SPLL_SPREAD_SPECTRUM 0xc0500164 |
| 54 | #define ixCG_SPLL_SPREAD_SPECTRUM_2 0xc0500168 | 55 | #define ixCG_SPLL_SPREAD_SPECTRUM_2 0xc0500168 |
| @@ -194,6 +194,8 @@ · 193 unmodified lines | |||
| 194 | #define CG_SPLL_FUNC_CNTL_6__SPLL_LF_CNTR__SHIFT 0x19 | 194 | #define CG_SPLL_FUNC_CNTL_6__SPLL_LF_CNTR__SHIFT 0x19 |
| 195 | #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL_MASK 0xfff | 195 | #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL_MASK 0xfff |
| 196 | #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL__SHIFT 0x0 | 196 | #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL__SHIFT 0x0 |
| 197 | #define CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK 0x2 | ||
| 198 | #define CG_SPLL_STATUS__SPLL_CHG_STATUS__SHIFT 0x1 | ||
| 197 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL_MASK 0x1 | 199 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL_MASK 0x1 |
| 198 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL__SHIFT 0x0 | 200 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL__SHIFT 0x0 |
| 199 | #define SPLL_CNTL_MODE__SPLL_LEGACY_PDIV_MASK 0x2 | 201 | #define SPLL_CNTL_MODE__SPLL_LEGACY_PDIV_MASK 0x2 |
| @@ -52,6 +52,7 @@ · 51 unmodified lines | |||
| 52 | #define ixCG_SPLL_FUNC_CNTL_5 0xc0500150 | 52 | #define ixCG_SPLL_FUNC_CNTL_5 0xc0500150 |
| 53 | #define ixCG_SPLL_FUNC_CNTL_6 0xc0500154 | 53 | #define ixCG_SPLL_FUNC_CNTL_6 0xc0500154 |
| 54 | #define ixCG_SPLL_FUNC_CNTL_7 0xc0500158 | 54 | #define ixCG_SPLL_FUNC_CNTL_7 0xc0500158 |
| 55 | #define ixCG_SPLL_STATUS 0xC050015C | ||
| 55 | #define ixSPLL_CNTL_MODE 0xc0500160 | 56 | #define ixSPLL_CNTL_MODE 0xc0500160 |
| 56 | #define ixCG_SPLL_SPREAD_SPECTRUM 0xc0500164 | 57 | #define ixCG_SPLL_SPREAD_SPECTRUM 0xc0500164 |
| 57 | #define ixCG_SPLL_SPREAD_SPECTRUM_2 0xc0500168 | 58 | #define ixCG_SPLL_SPREAD_SPECTRUM_2 0xc0500168 |
| @@ -220,6 +220,8 @@ · 219 unmodified lines | |||
| 220 | #define CG_SPLL_FUNC_CNTL_6__SPLL_LF_CNTR__SHIFT 0x19 | 220 | #define CG_SPLL_FUNC_CNTL_6__SPLL_LF_CNTR__SHIFT 0x19 |
| 221 | #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL_MASK 0xfff | 221 | #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL_MASK 0xfff |
| 222 | #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL__SHIFT 0x0 | 222 | #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL__SHIFT 0x0 |
| 223 | #define CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK 0x2 | ||
| 224 | #define CG_SPLL_STATUS__SPLL_CHG_STATUS__SHIFT 0x1 | ||
| 223 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL_MASK 0x1 | 225 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL_MASK 0x1 |
| 224 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL__SHIFT 0x0 | 226 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL__SHIFT 0x0 |
| 225 | #define SPLL_CNTL_MODE__SPLL_LEGACY_PDIV_MASK 0x2 | 227 | #define SPLL_CNTL_MODE__SPLL_LEGACY_PDIV_MASK 0x2 |
| @@ -492,12 +492,13 @@ struct atom_firmware_info_v3_1 · 491 unmodified lines | |||
| 492 | /* Total 32bit cap indication */ | 492 | /* Total 32bit cap indication */ |
| 493 | enum atombios_firmware_capability | 493 | enum atombios_firmware_capability |
| 494 | { | 494 | { |
| 495 | ATOM_FIRMWARE_CAP_FIRMWARE_POSTED = 0x00000001, | 495 | ATOM_FIRMWARE_CAP_FIRMWARE_POSTED = 0x00000001, |
| 496 | ATOM_FIRMWARE_CAP_GPU_VIRTUALIZATION = 0x00000002, | 496 | ATOM_FIRMWARE_CAP_GPU_VIRTUALIZATION = 0x00000002, |
| 497 | ATOM_FIRMWARE_CAP_WMI_SUPPORT = 0x00000040, | 497 | ATOM_FIRMWARE_CAP_WMI_SUPPORT = 0x00000040, |
| 498 | ATOM_FIRMWARE_CAP_HWEMU_ENABLE = 0x00000080, | 498 | ATOM_FIRMWARE_CAP_HWEMU_ENABLE = 0x00000080, |
| 499 | ATOM_FIRMWARE_CAP_HWEMU_UMC_CFG = 0x00000100, | 499 | ATOM_FIRMWARE_CAP_HWEMU_UMC_CFG = 0x00000100, |
| 500 | ATOM_FIRMWARE_CAP_SRAM_ECC = 0x00000200, | 500 | ATOM_FIRMWARE_CAP_SRAM_ECC = 0x00000200, |
| 501 | ATOM_FIRMWARE_CAP_ENABLE_2STAGE_BIST_TRAINING = 0x00000400, | ||
| 501 | }; | 502 | }; |
| 502 | 503 | ||
| 503 | enum atom_cooling_solution_id{ | 504 | enum atom_cooling_solution_id{ |
| @@ -671,6 +672,20 @@ struct vram_usagebyfirmware_v2_1 · 167 unmodified lines | |||
| 671 | uint16_t used_by_driver_in_kb; | 672 | uint16_t used_by_driver_in_kb; |
| 672 | }; | 673 | }; |
| 673 | 674 | ||
| 675 | /* This is part of vram_usagebyfirmware_v2_1 */ | ||
| 676 | struct vram_reserve_block | ||
| 677 | { | ||
| 678 | uint32_t start_address_in_kb; | ||
| 679 | uint16_t used_by_firmware_in_kb; | ||
| 680 | uint16_t used_by_driver_in_kb; | ||
| 681 | }; | ||
| 682 | |||
| 683 | /* Definitions for constance */ | ||
| 684 | enum atomfirmware_internal_constants | ||
| 685 | { | ||
| 686 | ONE_KiB = 0x400, | ||
| 687 | ONE_MiB = 0x100000, | ||
| 688 | }; | ||
| 674 | 689 | ||
| 675 | /* | 690 | /* |
| 676 | *************************************************************************** | 691 | *************************************************************************** |
| @@ -25,7 +25,6 @@ · 24 unmodified lines | |||
| 25 | #define _DISCOVERY_H_ | 25 | #define _DISCOVERY_H_ |
| 26 | 26 | ||
| 27 | #define PSP_HEADER_SIZE 256 | 27 | #define PSP_HEADER_SIZE 256 |
| 28 | #define BINARY_MAX_SIZE (64 << 10) | ||
| 29 | #define BINARY_SIGNATURE 0x28211407 | 28 | #define BINARY_SIGNATURE 0x28211407 |
| 30 | #define DISCOVERY_TABLE_SIGNATURE 0x53445049 | 29 | #define DISCOVERY_TABLE_SIGNATURE 0x53445049 |
| 31 | 30 | ||
| @@ -179,6 +179,11 @@ enum pp_mp1_state { · 178 unmodified lines | |||
| 179 | PP_MP1_STATE_RESET, | 179 | PP_MP1_STATE_RESET, |
| 180 | }; | 180 | }; |
| 181 | 181 | ||
| 182 | enum pp_df_cstate { | ||
| 183 | DF_CSTATE_DISALLOW = 0, | ||
| 184 | DF_CSTATE_ALLOW, | ||
| 185 | }; | ||
| 186 | |||
| 182 | #define PP_GROUP_MASK 0xF0000000 | 187 | #define PP_GROUP_MASK 0xF0000000 |
| 183 | #define PP_GROUP_SHIFT 28 | 188 | #define PP_GROUP_SHIFT 28 |
| 184 | 189 | ||
| @@ -312,6 +317,7 @@ struct amd_pm_funcs { · 127 unmodified lines | |||
| 312 | int (*get_ppfeature_status)(void *handle, char *buf); | 317 | int (*get_ppfeature_status)(void *handle, char *buf); |
| 313 | int (*set_ppfeature_status)(void *handle, uint64_t ppfeature_masks); | 318 | int (*set_ppfeature_status)(void *handle, uint64_t ppfeature_masks); |
| 314 | int (*asic_reset_mode_2)(void *handle); | 319 | int (*asic_reset_mode_2)(void *handle); |
| 320 | int (*set_df_cstate)(void *handle, enum pp_df_cstate state); | ||
| 315 | }; | 321 | }; |
| 316 | 322 | ||
| 317 | #endif | 323 | #endif |
| @@ -169,6 +169,11 @@ static const struct IP_BASE NBIF0_BASE ={ { { { 0x00000000, 0x00000014, 0x00000D · 168 unmodified lines | |||
| 169 | { { 0, 0, 0, 0, 0 } }, | 169 | { { 0, 0, 0, 0, 0 } }, |
| 170 | { { 0, 0, 0, 0, 0 } }, | 170 | { { 0, 0, 0, 0, 0 } }, |
| 171 | { { 0, 0, 0, 0, 0 } } } }; | 171 | { { 0, 0, 0, 0, 0 } } } }; |
| 172 | static const struct IP_BASE DCN_BASE ={ { { { 0x00000012, 0x000000C0, 0x000034C0, 0, 0 } }, | ||
| 173 | { { 0, 0, 0, 0, 0 } }, | ||
| 174 | { { 0, 0, 0, 0, 0 } }, | ||
| 175 | { { 0, 0, 0, 0, 0 } }, | ||
| 176 | { { 0, 0, 0, 0, 0 } } } }; | ||
| 172 | static const struct IP_BASE OSSSYS_BASE ={ { { { 0x000010A0, 0x0240A000, 0, 0, 0 } }, | 177 | static const struct IP_BASE OSSSYS_BASE ={ { { { 0x000010A0, 0x0240A000, 0, 0, 0 } }, |
| 173 | { { 0, 0, 0, 0, 0 } }, | 178 | { { 0, 0, 0, 0, 0 } }, |
| 174 | { { 0, 0, 0, 0, 0 } }, | 179 | { { 0, 0, 0, 0, 0 } }, |
| @@ -1361,4 +1366,33 @@ static const struct IP_BASE UVD0_BASE ={ { { { 0x00007800, 0x00007E00, 0x0240300 · 1186 unmodified lines | |||
| 1361 | #define UVD0_BASE__INST6_SEG3 0 | 1366 | #define UVD0_BASE__INST6_SEG3 0 |
| 1362 | #define UVD0_BASE__INST6_SEG4 0 | 1367 | #define UVD0_BASE__INST6_SEG4 0 |
| 1363 | 1368 | ||
| 1369 | #define DCN_BASE__INST0_SEG0 0x00000012 | ||
| 1370 | #define DCN_BASE__INST0_SEG1 0x000000C0 | ||
| 1371 | #define DCN_BASE__INST0_SEG2 0x000034C0 | ||
| 1372 | #define DCN_BASE__INST0_SEG3 0 | ||
| 1373 | #define DCN_BASE__INST0_SEG4 0 | ||
| 1374 | |||
| 1375 | #define DCN_BASE__INST1_SEG0 0 | ||
| 1376 | #define DCN_BASE__INST1_SEG1 0 | ||
| 1377 | #define DCN_BASE__INST1_SEG2 0 | ||
| 1378 | #define DCN_BASE__INST1_SEG3 0 | ||
| 1379 | #define DCN_BASE__INST1_SEG4 0 | ||
| 1380 | |||
| 1381 | #define DCN_BASE__INST2_SEG0 0 | ||
| 1382 | #define DCN_BASE__INST2_SEG1 0 | ||
| 1383 | #define DCN_BASE__INST2_SEG2 0 | ||
| 1384 | #define DCN_BASE__INST2_SEG3 0 | ||
| 1385 | #define DCN_BASE__INST2_SEG4 0 | ||
| 1386 | |||
| 1387 | #define DCN_BASE__INST3_SEG0 0 | ||
| 1388 | #define DCN_BASE__INST3_SEG1 0 | ||
| 1389 | #define DCN_BASE__INST3_SEG2 0 | ||
| 1390 | #define DCN_BASE__INST3_SEG3 0 | ||
| 1391 | #define DCN_BASE__INST3_SEG4 0 | ||
| 1392 | |||
| 1393 | #define DCN_BASE__INST4_SEG0 0 | ||
| 1394 | #define DCN_BASE__INST4_SEG1 0 | ||
| 1395 | #define DCN_BASE__INST4_SEG2 0 | ||
| 1396 | #define DCN_BASE__INST4_SEG3 0 | ||
| 1397 | #define DCN_BASE__INST4_SEG4 0 | ||
| 1364 | #endif | 1398 | #endif |
| @@ -1421,6 +1421,7 @@ static int pp_get_asic_baco_capability(void *handle, bool *cap) · 1420 unmodified lines | |||
| 1421 | { | 1421 | { |
| 1422 | struct pp_hwmgr *hwmgr = handle; | 1422 | struct pp_hwmgr *hwmgr = handle; |
| 1423 | 1423 | ||
| 1424 | *cap = false; | ||
| 1424 | if (!hwmgr) | 1425 | if (!hwmgr) |
| 1425 | return -EINVAL; | 1426 | return -EINVAL; |
| 1426 | 1427 | ||
| @@ -1548,6 +1549,23 @@ static int pp_smu_i2c_bus_access(void *handle, bool acquire) · 121 unmodified lines | |||
| 1548 | return ret; | 1549 | return ret; |
| 1549 | } | 1550 | } |
| 1550 | 1551 | ||
| 1552 | static int pp_set_df_cstate(void *handle, enum pp_df_cstate state) | ||
| 1553 | { | ||
| 1554 | struct pp_hwmgr *hwmgr = handle; | ||
| 1555 | |||
| 1556 | if (!hwmgr) | ||
| 1557 | return -EINVAL; | ||
| 1558 | |||
| 1559 | if (!hwmgr->pm_en || !hwmgr->hwmgr_func->set_df_cstate) | ||
| 1560 | return 0; | ||
| 1561 | |||
| 1562 | mutex_lock(&hwmgr->smu_lock); | ||
| 1563 | hwmgr->hwmgr_func->set_df_cstate(hwmgr, state); | ||
| 1564 | mutex_unlock(&hwmgr->smu_lock); | ||
| 1565 | |||
| 1566 | return 0; | ||
| 1567 | } | ||
| 1568 | |||
| 1551 | static const struct amd_pm_funcs pp_dpm_funcs = { | 1569 | static const struct amd_pm_funcs pp_dpm_funcs = { |
| 1552 | .load_firmware = pp_dpm_load_fw, | 1570 | .load_firmware = pp_dpm_load_fw, |
| 1553 | .wait_for_fw_loading_complete = pp_dpm_fw_loading_complete, | 1571 | .wait_for_fw_loading_complete = pp_dpm_fw_loading_complete, |
| @@ -1606,4 +1624,5 @@ static const struct amd_pm_funcs pp_dpm_funcs = { · 52 unmodified lines | |||
| 1606 | .set_ppfeature_status = pp_set_ppfeature_status, | 1624 | .set_ppfeature_status = pp_set_ppfeature_status, |
| 1607 | .asic_reset_mode_2 = pp_asic_reset_mode_2, | 1625 | .asic_reset_mode_2 = pp_asic_reset_mode_2, |
| 1608 | .smu_i2c_bus_access = pp_smu_i2c_bus_access, | 1626 | .smu_i2c_bus_access = pp_smu_i2c_bus_access, |
| 1627 | .set_df_cstate = pp_set_df_cstate, | ||
| 1609 | }; | 1628 | }; |
| @@ -945,50 +945,6 @@ static int smu_fini_fb_allocations(struct smu_context *smu) · 944 unmodified lines | |||
| 945 | return 0; | 945 | return 0; |
| 946 | } | 946 | } |
| 947 | 947 | ||
| 948 | static int smu_override_pcie_parameters(struct smu_context *smu) | ||
| 949 | { | ||
| 950 | struct amdgpu_device *adev = smu->adev; | ||
| 951 | uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg; | ||
| 952 | int ret; | ||
| 953 | |||
| 954 | if (adev->flags & AMD_IS_APU) | ||
| 955 | return 0; | ||
| 956 | |||
| 957 | if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) | ||
| 958 | pcie_gen = 3; | ||
| 959 | else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) | ||
| 960 | pcie_gen = 2; | ||
| 961 | else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) | ||
| 962 | pcie_gen = 1; | ||
| 963 | else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1) | ||
| 964 | pcie_gen = 0; | ||
| 965 | |||
| 966 | /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1 | ||
| 967 | * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 | ||
| 968 | * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 | ||
| 969 | */ | ||
| 970 | if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) | ||
| 971 | pcie_width = 6; | ||
| 972 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) | ||
| 973 | pcie_width = 5; | ||
| 974 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) | ||
| 975 | pcie_width = 4; | ||
| 976 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) | ||
| 977 | pcie_width = 3; | ||
| 978 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) | ||
| 979 | pcie_width = 2; | ||
| 980 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) | ||
| 981 | pcie_width = 1; | ||
| 982 | |||
| 983 | smu_pcie_arg = (1 << 16) | (pcie_gen << 8) | pcie_width; | ||
| 984 | ret = smu_send_smc_msg_with_param(smu, | ||
| 985 | SMU_MSG_OverridePcieParameters, | ||
| 986 | smu_pcie_arg); | ||
| 987 | if (ret) | ||
| 988 | pr_err("[%s] Attempt to override pcie params failed!\n", __func__); | ||
| 989 | return ret; | ||
| 990 | } | ||
| 991 | |||
| 992 | static int smu_smc_table_hw_init(struct smu_context *smu, | 948 | static int smu_smc_table_hw_init(struct smu_context *smu, |
| 993 | bool initialize) | 949 | bool initialize) |
| 994 | { | 950 | { |
| @@ -1232,6 +1188,7 @@ static int smu_hw_init(void *handle) · 237 unmodified lines | |||
| 1232 | if (adev->flags & AMD_IS_APU) { | 1188 | if (adev->flags & AMD_IS_APU) { |
| 1233 | smu_powergate_sdma(&adev->smu, false); | 1189 | smu_powergate_sdma(&adev->smu, false); |
| 1234 | smu_powergate_vcn(&adev->smu, false); | 1190 | smu_powergate_vcn(&adev->smu, false); |
| 1191 | smu_set_gfx_cgpg(&adev->smu, true); | ||
| 1235 | } | 1192 | } |
| 1236 | 1193 | ||
| 1237 | if (!smu->pm_enabled) | 1194 | if (!smu->pm_enabled) |
| @@ -1394,6 +1351,11 @@ static int smu_resume(void *handle) · 156 unmodified lines | |||
| 1394 | if (ret) | 1351 | if (ret) |
| 1395 | goto failed; | 1352 | goto failed; |
| 1396 | 1353 | ||
| 1354 | if (smu->is_apu) | ||
| 1355 | smu_set_gfx_cgpg(&adev->smu, true); | ||
| 1356 | |||
| 1357 | smu->disable_uclk_switch = 0; | ||
| 1358 | |||
| 1397 | mutex_unlock(&smu->mutex); | 1359 | mutex_unlock(&smu->mutex); |
| 1398 | 1360 | ||
| 1399 | pr_info("SMU is resumed successfully!\n"); | 1361 | pr_info("SMU is resumed successfully!\n"); |
| @@ -1834,6 +1796,64 @@ int smu_set_mp1_state(struct smu_context *smu, · 434 unmodified lines | |||
| 1834 | return ret; | 1796 | return ret; |
| 1835 | } | 1797 | } |
| 1836 | 1798 | ||
| 1799 | int smu_set_df_cstate(struct smu_context *smu, | ||
| 1800 | enum pp_df_cstate state) | ||
| 1801 | { | ||
| 1802 | int ret = 0; | ||
| 1803 | |||
| 1804 | /* | ||
| 1805 | * The SMC is not fully ready. That may be | ||
| 1806 | * expected as the IP may be masked. | ||
| 1807 | * So, just return without error. | ||
| 1808 | */ | ||
| 1809 | if (!smu->pm_enabled) | ||
| 1810 | return 0; | ||
| 1811 | |||
| 1812 | if (!smu->ppt_funcs || !smu->ppt_funcs->set_df_cstate) | ||
| 1813 | return 0; | ||
| 1814 | |||
| 1815 | ret = smu->ppt_funcs->set_df_cstate(smu, state); | ||
| 1816 | if (ret) | ||
| 1817 | pr_err("[SetDfCstate] failed!\n"); | ||
| 1818 | |||
| 1819 | return ret; | ||
| 1820 | } | ||
| 1821 | |||
| 1822 | int smu_write_watermarks_table(struct smu_context *smu) | ||
| 1823 | { | ||
| 1824 | int ret = 0; | ||
| 1825 | struct smu_table_context *smu_table = &smu->smu_table; | ||
| 1826 | struct smu_table *table = NULL; | ||
| 1827 | |||
| 1828 | table = &smu_table->tables[SMU_TABLE_WATERMARKS]; | ||
| 1829 | |||
| 1830 | if (!table->cpu_addr) | ||
| 1831 | return -EINVAL; | ||
| 1832 | |||
| 1833 | ret = smu_update_table(smu, SMU_TABLE_WATERMARKS, 0, table->cpu_addr, | ||
| 1834 | true); | ||
| 1835 | |||
| 1836 | return ret; | ||
| 1837 | } | ||
| 1838 | |||
| 1839 | int smu_set_watermarks_for_clock_ranges(struct smu_context *smu, | ||
| 1840 | struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges) | ||
| 1841 | { | ||
| 1842 | int ret = 0; | ||
| 1843 | struct smu_table *watermarks = &smu->smu_table.tables[SMU_TABLE_WATERMARKS]; | ||
| 1844 | void *table = watermarks->cpu_addr; | ||
| 1845 | |||
| 1846 | if (!smu->disable_watermark && | ||
| 1847 | smu_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) && | ||
| 1848 | smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) { | ||
| 1849 | smu_set_watermarks_table(smu, table, clock_ranges); | ||
| 1850 | smu->watermarks_bitmap |= WATERMARKS_EXIST; | ||
| 1851 | smu->watermarks_bitmap &= ~WATERMARKS_LOADED; | ||
| 1852 | } | ||
| 1853 | |||
| 1854 | return ret; | ||
| 1855 | } | ||
| 1856 | |||
| 1837 | const struct amd_ip_funcs smu_ip_funcs = { | 1857 | const struct amd_ip_funcs smu_ip_funcs = { |
| 1838 | .name = "smu", | 1858 | .name = "smu", |
| 1839 | .early_init = smu_early_init, | 1859 | .early_init = smu_early_init, |
| @@ -1898,6 +1898,35 @@ static bool arcturus_is_dpm_running(struct smu_context *smu) · 1897 unmodified lines | |||
| 1898 | return !!(feature_enabled & SMC_DPM_FEATURE); | 1898 | return !!(feature_enabled & SMC_DPM_FEATURE); |
| 1899 | } | 1899 | } |
| 1900 | 1900 | ||
| 1901 | static int arcturus_dpm_set_uvd_enable(struct smu_context *smu, bool enable) | ||
| 1902 | { | ||
| 1903 | struct smu_power_context *smu_power = &smu->smu_power; | ||
| 1904 | struct smu_power_gate *power_gate = &smu_power->power_gate; | ||
| 1905 | int ret = 0; | ||
| 1906 | |||
| 1907 | if (enable) { | ||
| 1908 | if (!smu_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) { | ||
| 1909 | ret = smu_feature_set_enabled(smu, SMU_FEATURE_VCN_PG_BIT, 1); | ||
| 1910 | if (ret) { | ||
| 1911 | pr_err("[EnableVCNDPM] failed!\n"); | ||
| 1912 | return ret; | ||
| 1913 | } | ||
| 1914 | } | ||
| 1915 | power_gate->vcn_gated = false; | ||
| 1916 | } else { | ||
| 1917 | if (smu_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) { | ||
| 1918 | ret = smu_feature_set_enabled(smu, SMU_FEATURE_VCN_PG_BIT, 0); | ||
| 1919 | if (ret) { | ||
| 1920 | pr_err("[DisableVCNDPM] failed!\n"); | ||
| 1921 | return ret; | ||
| 1922 | } | ||
| 1923 | } | ||
| 1924 | power_gate->vcn_gated = true; | ||
| 1925 | } | ||
| 1926 | |||
| 1927 | return ret; | ||
| 1928 | } | ||
| 1929 | |||
| 1901 | static const struct pptable_funcs arcturus_ppt_funcs = { | 1930 | static const struct pptable_funcs arcturus_ppt_funcs = { |
| 1902 | /* translate smu index into arcturus specific index */ | 1931 | /* translate smu index into arcturus specific index */ |
| 1903 | .get_smu_msg_index = arcturus_get_smu_msg_index, | 1932 | .get_smu_msg_index = arcturus_get_smu_msg_index, |
| @@ -1936,6 +1965,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = { · 32 unmodified lines | |||
| 1936 | .dump_pptable = arcturus_dump_pptable, | 1965 | .dump_pptable = arcturus_dump_pptable, |
| 1937 | .get_power_limit = arcturus_get_power_limit, | 1966 | .get_power_limit = arcturus_get_power_limit, |
| 1938 | .is_dpm_running = arcturus_is_dpm_running, | 1967 | .is_dpm_running = arcturus_is_dpm_running, |
| 1968 | .dpm_set_uvd_enable = arcturus_dpm_set_uvd_enable, | ||
| 1939 | }; | 1969 | }; |
| 1940 | 1970 | ||
| 1941 | void arcturus_set_ppt_funcs(struct smu_context *smu) | 1971 | void arcturus_set_ppt_funcs(struct smu_context *smu) |
| @@ -36,7 +36,8 @@ HARDWARE_MGR = hwmgr.o processpptables.o \ · 35 unmodified lines | |||
| 36 | pp_overdriver.o smu_helper.o \ | 36 | pp_overdriver.o smu_helper.o \ |
| 37 | vega20_processpptables.o vega20_hwmgr.o vega20_powertune.o \ | 37 | vega20_processpptables.o vega20_hwmgr.o vega20_powertune.o \ |
| 38 | vega20_thermal.o common_baco.o vega10_baco.o vega20_baco.o \ | 38 | vega20_thermal.o common_baco.o vega10_baco.o vega20_baco.o \ |
| 39 | vega12_baco.o smu9_baco.o | 39 | vega12_baco.o smu9_baco.o tonga_baco.o polaris_baco.o fiji_baco.o \ |
| 40 | ci_baco.o smu7_baco.o | ||
| 40 | 41 | ||
| 41 | AMD_PP_HWMGR = $(addprefix $(AMD_PP_PATH)/hwmgr/,$(HARDWARE_MGR)) | 42 | AMD_PP_HWMGR = $(addprefix $(AMD_PP_PATH)/hwmgr/,$(HARDWARE_MGR)) |
| 42 | 43 | ||
| @@ -0,0 +1,195 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2019 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 | #include "amdgpu.h" | ||
| 24 | #include "ci_baco.h" | ||
| 25 | |||
| 26 | #include "gmc/gmc_7_1_d.h" | ||
| 27 | #include "gmc/gmc_7_1_sh_mask.h" | ||
| 28 | |||
| 29 | #include "bif/bif_4_1_d.h" | ||
| 30 | #include "bif/bif_4_1_sh_mask.h" | ||
| 31 | |||
| 32 | #include "dce/dce_8_0_d.h" | ||
| 33 | #include "dce/dce_8_0_sh_mask.h" | ||
| 34 | |||
| 35 | #include "smu/smu_7_0_1_d.h" | ||
| 36 | #include "smu/smu_7_0_1_sh_mask.h" | ||
| 37 | |||
| 38 | #include "gca/gfx_7_2_d.h" | ||
| 39 | #include "gca/gfx_7_2_sh_mask.h" | ||
| 40 | |||
| 41 | static const struct baco_cmd_entry gpio_tbl[] = | ||
| 42 | { | ||
| 43 | { CMD_WRITE, mmGPIOPAD_EN, 0, 0, 0, 0x0 }, | ||
| 44 | { CMD_WRITE, mmGPIOPAD_PD_EN, 0, 0, 0, 0x0 }, | ||
| 45 | { CMD_WRITE, mmGPIOPAD_PU_EN, 0, 0, 0, 0x0 }, | ||
| 46 | { CMD_WRITE, mmGPIOPAD_MASK, 0, 0, 0, 0xff77ffff }, | ||
| 47 | { CMD_WRITE, mmDC_GPIO_DVODATA_EN, 0, 0, 0, 0x0 }, | ||
| 48 | { CMD_WRITE, mmDC_GPIO_DVODATA_MASK, 0, 0, 0, 0xffffffff }, | ||
| 49 | { CMD_WRITE, mmDC_GPIO_GENERIC_EN, 0, 0, 0, 0x0 }, | ||
| 50 | { CMD_READMODIFYWRITE, mmDC_GPIO_GENERIC_MASK, 0, 0, 0, 0x03333333 }, | ||
| 51 | { CMD_WRITE, mmDC_GPIO_SYNCA_EN, 0, 0, 0, 0x0 }, | ||
| 52 | { CMD_READMODIFYWRITE, mmDC_GPIO_SYNCA_MASK, 0, 0, 0, 0x00001111 } | ||
| 53 | }; | ||
| 54 | |||
| 55 | static const struct baco_cmd_entry enable_fb_req_rej_tbl[] = | ||
| 56 | { | ||
| 57 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0300024 }, | ||
| 58 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 }, | ||
| 59 | { CMD_WRITE, mmBIF_FB_EN, 0, 0, 0, 0x0 } | ||
| 60 | }; | ||
| 61 | |||
| 62 | static const struct baco_cmd_entry use_bclk_tbl[] = | ||
| 63 | { | ||
| 64 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, | ||
| 65 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN_MASK, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN__SHIFT, 0, 0x1 }, | ||
| 66 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 }, | ||
| 67 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG__SHIFT, 0, 0x1 }, | ||
| 68 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_STATUS }, | ||
| 69 | { CMD_WAITFOR, mmGCK_SMC_IND_DATA, CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK, 0, 0xffffffff, 0x2 }, | ||
| 70 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 }, | ||
| 71 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG__SHIFT, 0, 0x0 }, | ||
| 72 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG__SHIFT, 0, 0x1 }, | ||
| 73 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_STATUS }, | ||
| 74 | { CMD_WAITFOR, mmGCK_SMC_IND_DATA, CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK, 0, 0xffffffff, 0x2 }, | ||
| 75 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 }, | ||
| 76 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG__SHIFT, 0, 0x0 }, | ||
| 77 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 }, | ||
| 78 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x4000000, 0x1a, 0, 0x1 }, | ||
| 79 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL }, | ||
| 80 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x2 }, | ||
| 81 | { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__MPLL_SW_DIR_CONTROL_MASK, MPLL_CNTL_MODE__MPLL_SW_DIR_CONTROL__SHIFT, 0, 0x1 }, | ||
| 82 | { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__MPLL_MCLK_SEL_MASK, MPLL_CNTL_MODE__MPLL_MCLK_SEL__SHIFT, 0, 0x0 } | ||
| 83 | }; | ||
| 84 | |||
| 85 | static const struct baco_cmd_entry turn_off_plls_tbl[] = | ||
| 86 | { | ||
| 87 | { CMD_READMODIFYWRITE, mmDISPPLL_BG_CNTL, DISPPLL_BG_CNTL__DISPPLL_BG_PDN_MASK, DISPPLL_BG_CNTL__DISPPLL_BG_PDN__SHIFT, 0, 0x1 }, | ||
| 88 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL_DC }, | ||
| 89 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL_DC__OSC_EN_MASK, CG_CLKPIN_CNTL_DC__OSC_EN__SHIFT, 0, 0x0 }, | ||
| 90 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL_DC__XTALIN_SEL_MASK, CG_CLKPIN_CNTL_DC__XTALIN_SEL__SHIFT, 0, 0x0 }, | ||
| 91 | { CMD_READMODIFYWRITE, mmPLL_CNTL, PLL_CNTL__PLL_RESET_MASK, PLL_CNTL__PLL_RESET__SHIFT, 0, 0x1 }, | ||
| 92 | { CMD_READMODIFYWRITE, mmPLL_CNTL, PLL_CNTL__PLL_POWER_DOWN_MASK, PLL_CNTL__PLL_POWER_DOWN__SHIFT, 0, 0x1 }, | ||
| 93 | { CMD_READMODIFYWRITE, mmPLL_CNTL, PLL_CNTL__PLL_BYPASS_CAL_MASK, PLL_CNTL__PLL_BYPASS_CAL__SHIFT, 0, 0x1 }, | ||
| 94 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, | ||
| 95 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_RESET_MASK, CG_SPLL_FUNC_CNTL__SPLL_RESET__SHIFT, 0, 0x1 }, | ||
| 96 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_PWRON_MASK, CG_SPLL_FUNC_CNTL__SPLL_PWRON__SHIFT, 0, 0x0 }, | ||
| 97 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 }, | ||
| 98 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x2000000, 0x19, 0, 0x1 }, | ||
| 99 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x8000000, 0x1b, 0, 0x0 }, | ||
| 100 | { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__GLOBAL_MPLL_RESET_MASK, MPLL_CNTL_MODE__GLOBAL_MPLL_RESET__SHIFT, 0, 0x1 }, | ||
| 101 | { CMD_WRITE, mmMPLL_CONTROL, 0, 0, 0, 0x00000006 }, | ||
| 102 | { CMD_WRITE, mmMC_IO_RXCNTL_DPHY0_D0, 0, 0, 0, 0x00007740 }, | ||
| 103 | { CMD_WRITE, mmMC_IO_RXCNTL_DPHY0_D1, 0, 0, 0, 0x00007740 }, | ||
| 104 | { CMD_WRITE, mmMC_IO_RXCNTL_DPHY1_D0, 0, 0, 0, 0x00007740 }, | ||
| 105 | { CMD_WRITE, mmMC_IO_RXCNTL_DPHY1_D1, 0, 0, 0, 0x00007740 }, | ||
| 106 | { CMD_READMODIFYWRITE, mmMCLK_PWRMGT_CNTL, MCLK_PWRMGT_CNTL__MRDCK0_PDNB_MASK, MCLK_PWRMGT_CNTL__MRDCK0_PDNB__SHIFT, 0, 0x0 }, | ||
| 107 | { CMD_READMODIFYWRITE, mmMCLK_PWRMGT_CNTL, MCLK_PWRMGT_CNTL__MRDCK1_PDNB_MASK, MCLK_PWRMGT_CNTL__MRDCK1_PDNB__SHIFT, 0, 0x0 }, | ||
| 108 | { CMD_READMODIFYWRITE, mmMC_SEQ_CNTL_2, MC_SEQ_CNTL_2__DRST_PU_MASK, MC_SEQ_CNTL_2__DRST_PU__SHIFT, 0, 0x0 }, | ||
| 109 | { CMD_READMODIFYWRITE, mmMC_SEQ_CNTL_2, MC_SEQ_CNTL_2__DRST_PD_MASK, MC_SEQ_CNTL_2__DRST_PD__SHIFT, 0, 0x0 }, | ||
| 110 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL_2 }, | ||
| 111 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN_MASK, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN__SHIFT, 0, 0x0 }, | ||
| 112 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL }, | ||
| 113 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x4 }, | ||
| 114 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMISC_CLK_CTRL }, | ||
| 115 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL_MASK, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL__SHIFT, 0, 0x2 }, | ||
| 116 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__ZCLK_SEL_MASK, MISC_CLK_CTRL__ZCLK_SEL__SHIFT, 0, 0x2 }, | ||
| 117 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__DFT_SMS_PG_CLK_SEL_MASK, MISC_CLK_CTRL__DFT_SMS_PG_CLK_SEL__SHIFT, 0, 0x2 }, | ||
| 118 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixTHM_CLK_CNTL }, | ||
| 119 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__CMON_CLK_SEL_MASK, THM_CLK_CNTL__CMON_CLK_SEL__SHIFT, 0, 0x2 }, | ||
| 120 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__TMON_CLK_SEL_MASK, THM_CLK_CNTL__TMON_CLK_SEL__SHIFT, 0, 0x2 } | ||
| 121 | }; | ||
| 122 | |||
| 123 | static const struct baco_cmd_entry enter_baco_tbl[] = | ||
| 124 | { | ||
| 125 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x01 }, | ||
| 126 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x01 }, | ||
| 127 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, 0, 5, 0x02 }, | ||
| 128 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x00 }, | ||
| 129 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, 0, 5, 0x00 }, | ||
| 130 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x00 }, | ||
| 131 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, 0, 5, 0x00 }, | ||
| 132 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x01 }, | ||
| 133 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, 0, 5, 0x08 }, | ||
| 134 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x40 } | ||
| 135 | }; | ||
| 136 | |||
| 137 | #define BACO_CNTL__PWRGOOD_MASK BACO_CNTL__PWRGOOD_GPIO_MASK+BACO_CNTL__PWRGOOD_MEM_MASK+BACO_CNTL__PWRGOOD_DVO_MASK | ||
| 138 | |||
| 139 | static const struct baco_cmd_entry exit_baco_tbl[] = | ||
| 140 | { | ||
| 141 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x01 }, | ||
| 142 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x00 }, | ||
| 143 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x00 }, | ||
| 144 | { CMD_DELAY_MS, 0, 0, 0, 20, 0 }, | ||
| 145 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_BF_MASK, 0, 0xffffffff, 0x20 }, | ||
| 146 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x01 }, | ||
| 147 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_MASK, 0, 5, 0x1c }, | ||
| 148 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x01 }, | ||
| 149 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x00 }, | ||
| 150 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__RCU_BIF_CONFIG_DONE_MASK, 0, 5, 0x10 }, | ||
| 151 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x00 }, | ||
| 152 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x00 } | ||
| 153 | }; | ||
| 154 | |||
| 155 | static const struct baco_cmd_entry clean_baco_tbl[] = | ||
| 156 | { | ||
| 157 | { CMD_WRITE, mmBIOS_SCRATCH_6, 0, 0, 0, 0 }, | ||
| 158 | { CMD_WRITE, mmCP_PFP_UCODE_ADDR, 0, 0, 0, 0 } | ||
| 159 | }; | ||
| 160 | |||
| 161 | int ci_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state) | ||
| 162 | { | ||
| 163 | enum BACO_STATE cur_state; | ||
| 164 | |||
| 165 | smu7_baco_get_state(hwmgr, &cur_state); | ||
| 166 | |||
| 167 | if (cur_state == state) | ||
| 168 | /* aisc already in the target state */ | ||
| 169 | return 0; | ||
| 170 | |||
| 171 | if (state == BACO_STATE_IN) { | ||
| 172 | baco_program_registers(hwmgr, gpio_tbl, ARRAY_SIZE(gpio_tbl)); | ||
| 173 | baco_program_registers(hwmgr, enable_fb_req_rej_tbl, | ||
| 174 | ARRAY_SIZE(enable_fb_req_rej_tbl)); | ||
| 175 | baco_program_registers(hwmgr, use_bclk_tbl, ARRAY_SIZE(use_bclk_tbl)); | ||
| 176 | baco_program_registers(hwmgr, turn_off_plls_tbl, | ||
| 177 | ARRAY_SIZE(turn_off_plls_tbl)); | ||
| 178 | if (baco_program_registers(hwmgr, enter_baco_tbl, | ||
| 179 | ARRAY_SIZE(enter_baco_tbl))) | ||
| 180 | return 0; | ||
| 181 | |||
| 182 | } else if (state == BACO_STATE_OUT) { | ||
| 183 | /* HW requires at least 20ms between regulator off and on */ | ||
| 184 | msleep(20); | ||
| 185 | /* Execute Hardware BACO exit sequence */ | ||
| 186 | if (baco_program_registers(hwmgr, exit_baco_tbl, | ||
| 187 | ARRAY_SIZE(exit_baco_tbl))) { | ||
| 188 | if (baco_program_registers(hwmgr, clean_baco_tbl, | ||
| 189 | ARRAY_SIZE(clean_baco_tbl))) | ||
| 190 | return 0; | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 194 | return -EINVAL; | ||
| 195 | } | ||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2019 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 | #ifndef __CI_BACO_H__ | ||
| 24 | #define __CI_BACO_H__ | ||
| 25 | #include "smu7_baco.h" | ||
| 26 | |||
| 27 | extern int ci_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state); | ||
| 28 | |||
| 29 | #endif | ||
| @@ -79,6 +79,25 @@ static bool baco_cmd_handler(struct pp_hwmgr *hwmgr, u32 command, u32 reg, u32 m · 78 unmodified lines | |||
| 79 | return ret; | 79 | return ret; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | bool baco_program_registers(struct pp_hwmgr *hwmgr, | ||
| 83 | const struct baco_cmd_entry *entry, | ||
| 84 | const u32 array_size) | ||
| 85 | { | ||
| 86 | u32 i, reg = 0; | ||
| 87 | |||
| 88 | for (i = 0; i < array_size; i++) { | ||
| 89 | if ((entry[i].cmd == CMD_WRITE) || | ||
| 90 | (entry[i].cmd == CMD_READMODIFYWRITE) || | ||
| 91 | (entry[i].cmd == CMD_WAITFOR)) | ||
| 92 | reg = entry[i].reg_offset; | ||
| 93 | if (!baco_cmd_handler(hwmgr, entry[i].cmd, reg, entry[i].mask, | ||
| 94 | entry[i].shift, entry[i].val, entry[i].timeout)) | ||
| 95 | return false; | ||
| 96 | } | ||
| 97 | |||
| 98 | return true; | ||
| 99 | } | ||
| 100 | |||
| 82 | bool soc15_baco_program_registers(struct pp_hwmgr *hwmgr, | 101 | bool soc15_baco_program_registers(struct pp_hwmgr *hwmgr, |
| 83 | const struct soc15_baco_cmd_entry *entry, | 102 | const struct soc15_baco_cmd_entry *entry, |
| 84 | const u32 array_size) | 103 | const u32 array_size) |
| @@ -33,6 +33,15 @@ enum baco_cmd_type { · 32 unmodified lines | |||
| 33 | CMD_DELAY_US, | 33 | CMD_DELAY_US, |
| 34 | }; | 34 | }; |
| 35 | 35 | ||
| 36 | struct baco_cmd_entry { | ||
| 37 | enum baco_cmd_type cmd; | ||
| 38 | uint32_t reg_offset; | ||
| 39 | uint32_t mask; | ||
| 40 | uint32_t shift; | ||
| 41 | uint32_t timeout; | ||
| 42 | uint32_t val; | ||
| 43 | }; | ||
| 44 | |||
| 36 | struct soc15_baco_cmd_entry { | 45 | struct soc15_baco_cmd_entry { |
| 37 | enum baco_cmd_type cmd; | 46 | enum baco_cmd_type cmd; |
| 38 | uint32_t hwip; | 47 | uint32_t hwip; |
| @@ -44,6 +53,10 @@ struct soc15_baco_cmd_entry { · 5 unmodified lines | |||
| 44 | uint32_t timeout; | 53 | uint32_t timeout; |
| 45 | uint32_t val; | 54 | uint32_t val; |
| 46 | }; | 55 | }; |
| 56 | |||
| 57 | extern bool baco_program_registers(struct pp_hwmgr *hwmgr, | ||
| 58 | const struct baco_cmd_entry *entry, | ||
| 59 | const u32 array_size); | ||
| 47 | extern bool soc15_baco_program_registers(struct pp_hwmgr *hwmgr, | 60 | extern bool soc15_baco_program_registers(struct pp_hwmgr *hwmgr, |
| 48 | const struct soc15_baco_cmd_entry *entry, | 61 | const struct soc15_baco_cmd_entry *entry, |
| 49 | const u32 array_size); | 62 | const u32 array_size); |
| @@ -0,0 +1,196 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2019 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 | #include "amdgpu.h" | ||
| 24 | #include "fiji_baco.h" | ||
| 25 | |||
| 26 | #include "gmc/gmc_8_1_d.h" | ||
| 27 | #include "gmc/gmc_8_1_sh_mask.h" | ||
| 28 | |||
| 29 | #include "bif/bif_5_0_d.h" | ||
| 30 | #include "bif/bif_5_0_sh_mask.h" | ||
| 31 | |||
| 32 | #include "dce/dce_10_0_d.h" | ||
| 33 | #include "dce/dce_10_0_sh_mask.h" | ||
| 34 | |||
| 35 | #include "smu/smu_7_1_3_d.h" | ||
| 36 | #include "smu/smu_7_1_3_sh_mask.h" | ||
| 37 | |||
| 38 | |||
| 39 | static const struct baco_cmd_entry gpio_tbl[] = | ||
| 40 | { | ||
| 41 | { CMD_WRITE, mmGPIOPAD_EN, 0, 0, 0, 0x0 }, | ||
| 42 | { CMD_WRITE, mmGPIOPAD_PD_EN, 0, 0, 0, 0x0 }, | ||
| 43 | { CMD_WRITE, mmGPIOPAD_PU_EN, 0, 0, 0, 0x0 }, | ||
| 44 | { CMD_WRITE, mmGPIOPAD_MASK, 0, 0, 0, 0xff77ffff }, | ||
| 45 | { CMD_WRITE, mmDC_GPIO_DVODATA_EN, 0, 0, 0, 0x0 }, | ||
| 46 | { CMD_WRITE, mmDC_GPIO_DVODATA_MASK, 0, 0, 0, 0xffffffff }, | ||
| 47 | { CMD_WRITE, mmDC_GPIO_GENERIC_EN, 0, 0, 0, 0x0 }, | ||
| 48 | { CMD_READMODIFYWRITE, mmDC_GPIO_GENERIC_MASK, 0, 0, 0, 0x03333333 }, | ||
| 49 | { CMD_WRITE, mmDC_GPIO_SYNCA_EN, 0, 0, 0, 0x0 }, | ||
| 50 | { CMD_READMODIFYWRITE, mmDC_GPIO_SYNCA_MASK, 0, 0, 0, 0x00001111 } | ||
| 51 | }; | ||
| 52 | |||
| 53 | static const struct baco_cmd_entry enable_fb_req_rej_tbl[] = | ||
| 54 | { | ||
| 55 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0300024 }, | ||
| 56 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 }, | ||
| 57 | { CMD_WRITE, mmBIF_FB_EN, 0, 0, 0, 0x0 } | ||
| 58 | }; | ||
| 59 | |||
| 60 | static const struct baco_cmd_entry use_bclk_tbl[] = | ||
| 61 | { | ||
| 62 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, | ||
| 63 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN_MASK, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN__SHIFT, 0, 0x1 }, | ||
| 64 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 }, | ||
| 65 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG__SHIFT, 0, 0x1 }, | ||
| 66 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_STATUS }, | ||
| 67 | { CMD_WAITFOR, mmGCK_SMC_IND_DATA, CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK, 0, 0xffffffff, 0x2 }, | ||
| 68 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 }, | ||
| 69 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG__SHIFT, 0, 0x0 }, | ||
| 70 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG__SHIFT, 0, 0x1 }, | ||
| 71 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_STATUS }, | ||
| 72 | { CMD_WAITFOR, mmGCK_SMC_IND_DATA, CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK, 0, 0xffffffff, 0x2 }, | ||
| 73 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 }, | ||
| 74 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG__SHIFT, 0, 0x0 }, | ||
| 75 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 }, | ||
| 76 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x4000000, 0x1a, 0, 0x1 }, | ||
| 77 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL }, | ||
| 78 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x2 } | ||
| 79 | }; | ||
| 80 | |||
| 81 | static const struct baco_cmd_entry turn_off_plls_tbl[] = | ||
| 82 | { | ||
| 83 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, | ||
| 84 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_RESET_MASK, CG_SPLL_FUNC_CNTL__SPLL_RESET__SHIFT, 0, 0x1 }, | ||
| 85 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_PWRON_MASK, CG_SPLL_FUNC_CNTL__SPLL_PWRON__SHIFT, 0, 0x0 }, | ||
| 86 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 }, | ||
| 87 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x2000000, 0x19, 0, 0x1 }, | ||
| 88 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x8000000, 0x1b, 0, 0x0 } | ||
| 89 | }; | ||
| 90 | |||
| 91 | static const struct baco_cmd_entry clk_req_b_tbl[] = | ||
| 92 | { | ||
| 93 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL_2 }, | ||
| 94 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN_MASK, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN__SHIFT, 0, 0x0 }, | ||
| 95 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL }, | ||
| 96 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x4 }, | ||
| 97 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMISC_CLK_CTRL }, | ||
| 98 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL_MASK, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL__SHIFT, 0, 0x1 }, | ||
| 99 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__ZCLK_SEL_MASK, MISC_CLK_CTRL__ZCLK_SEL__SHIFT, 0, 0x1 }, | ||
| 100 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL }, | ||
| 101 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL__BCLK_AS_XCLK_MASK, CG_CLKPIN_CNTL__BCLK_AS_XCLK__SHIFT, 0, 0x0 }, | ||
| 102 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixTHM_CLK_CNTL }, | ||
| 103 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__CMON_CLK_SEL_MASK, THM_CLK_CNTL__CMON_CLK_SEL__SHIFT, 0, 0x1 }, | ||
| 104 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__TMON_CLK_SEL_MASK, THM_CLK_CNTL__TMON_CLK_SEL__SHIFT, 0, 0x1 } | ||
| 105 | }; | ||
| 106 | |||
| 107 | static const struct baco_cmd_entry enter_baco_tbl[] = | ||
| 108 | { | ||
| 109 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x01 }, | ||
| 110 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x01 }, | ||
| 111 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, 0, 5, 0x40000 }, | ||
| 112 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x01 }, | ||
| 113 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, 0, 5, 0x02 }, | ||
| 114 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x00 }, | ||
| 115 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, 0, 5, 0x00 }, | ||
| 116 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x00 }, | ||
| 117 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, 0, 5, 0x00 }, | ||
| 118 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x01 }, | ||
| 119 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, 0, 5, 0x08 }, | ||
| 120 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x40 } | ||
| 121 | }; | ||
| 122 | |||
| 123 | #define BACO_CNTL__PWRGOOD_MASK BACO_CNTL__PWRGOOD_GPIO_MASK+BACO_CNTL__PWRGOOD_MEM_MASK+BACO_CNTL__PWRGOOD_DVO_MASK | ||
| 124 | |||
| 125 | static const struct baco_cmd_entry exit_baco_tbl[] = | ||
| 126 | { | ||
| 127 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x01 }, | ||
| 128 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x00 }, | ||
| 129 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x00 }, | ||
| 130 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_BF_MASK, 0, 0xffffffff, 0x200 }, | ||
| 131 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x01 }, | ||
| 132 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_MASK, 0, 5, 0x1c00 }, | ||
| 133 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x01 }, | ||
| 134 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x00 }, | ||
| 135 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x00 }, | ||
| 136 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__RCU_BIF_CONFIG_DONE_MASK, 0, 5, 0x100 }, | ||
| 137 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x00 }, | ||
| 138 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x00 } | ||
| 139 | }; | ||
| 140 | |||
| 141 | static const struct baco_cmd_entry clean_baco_tbl[] = | ||
| 142 | { | ||
| 143 | { CMD_WRITE, mmBIOS_SCRATCH_0, 0, 0, 0, 0 }, | ||
| 144 | { CMD_WRITE, mmBIOS_SCRATCH_1, 0, 0, 0, 0 }, | ||
| 145 | { CMD_WRITE, mmBIOS_SCRATCH_2, 0, 0, 0, 0 }, | ||
| 146 | { CMD_WRITE, mmBIOS_SCRATCH_3, 0, 0, 0, 0 }, | ||
| 147 | { CMD_WRITE, mmBIOS_SCRATCH_4, 0, 0, 0, 0 }, | ||
| 148 | { CMD_WRITE, mmBIOS_SCRATCH_5, 0, 0, 0, 0 }, | ||
| 149 | { CMD_WRITE, mmBIOS_SCRATCH_6, 0, 0, 0, 0 }, | ||
| 150 | { CMD_WRITE, mmBIOS_SCRATCH_7, 0, 0, 0, 0 }, | ||
| 151 | { CMD_WRITE, mmBIOS_SCRATCH_8, 0, 0, 0, 0 }, | ||
| 152 | { CMD_WRITE, mmBIOS_SCRATCH_9, 0, 0, 0, 0 }, | ||
| 153 | { CMD_WRITE, mmBIOS_SCRATCH_10, 0, 0, 0, 0 }, | ||
| 154 | { CMD_WRITE, mmBIOS_SCRATCH_11, 0, 0, 0, 0 }, | ||
| 155 | { CMD_WRITE, mmBIOS_SCRATCH_12, 0, 0, 0, 0 }, | ||
| 156 | { CMD_WRITE, mmBIOS_SCRATCH_13, 0, 0, 0, 0 }, | ||
| 157 | { CMD_WRITE, mmBIOS_SCRATCH_14, 0, 0, 0, 0 }, | ||
| 158 | { CMD_WRITE, mmBIOS_SCRATCH_15, 0, 0, 0, 0 } | ||
| 159 | }; | ||
| 160 | |||
| 161 | int fiji_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state) | ||
| 162 | { | ||
| 163 | enum BACO_STATE cur_state; | ||
| 164 | |||
| 165 | smu7_baco_get_state(hwmgr, &cur_state); | ||
| 166 | |||
| 167 | if (cur_state == state) | ||
| 168 | /* aisc already in the target state */ | ||
| 169 | return 0; | ||
| 170 | |||
| 171 | if (state == BACO_STATE_IN) { | ||
| 172 | baco_program_registers(hwmgr, gpio_tbl, ARRAY_SIZE(gpio_tbl)); | ||
| 173 | baco_program_registers(hwmgr, enable_fb_req_rej_tbl, | ||
| 174 | ARRAY_SIZE(enable_fb_req_rej_tbl)); | ||
| 175 | baco_program_registers(hwmgr, use_bclk_tbl, ARRAY_SIZE(use_bclk_tbl)); | ||
| 176 | baco_program_registers(hwmgr, turn_off_plls_tbl, | ||
| 177 | ARRAY_SIZE(turn_off_plls_tbl)); | ||
| 178 | baco_program_registers(hwmgr, clk_req_b_tbl, ARRAY_SIZE(clk_req_b_tbl)); | ||
| 179 | if (baco_program_registers(hwmgr, enter_baco_tbl, | ||
| 180 | ARRAY_SIZE(enter_baco_tbl))) | ||
| 181 | return 0; | ||
| 182 | |||
| 183 | } else if (state == BACO_STATE_OUT) { | ||
| 184 | /* HW requires at least 20ms between regulator off and on */ | ||
| 185 | msleep(20); | ||
| 186 | /* Execute Hardware BACO exit sequence */ | ||
| 187 | if (baco_program_registers(hwmgr, exit_baco_tbl, | ||
| 188 | ARRAY_SIZE(exit_baco_tbl))) { | ||
| 189 | if (baco_program_registers(hwmgr, clean_baco_tbl, | ||
| 190 | ARRAY_SIZE(clean_baco_tbl))) | ||
| 191 | return 0; | ||
| 192 | } | ||
| 193 | } | ||
| 194 | |||
| 195 | return -EINVAL; | ||
| 196 | } | ||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2019 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 | #ifndef __FIJI_BACO_H__ | ||
| 24 | #define __FIJI_BACO_H__ | ||
| 25 | #include "smu7_baco.h" | ||
| 26 | |||
| 27 | extern int fiji_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state); | ||
| 28 | |||
| 29 | #endif | ||
| @@ -0,0 +1,222 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2019 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 | #include "amdgpu.h" | ||
| 24 | #include "polaris_baco.h" | ||
| 25 | |||
| 26 | #include "gmc/gmc_8_1_d.h" | ||
| 27 | #include "gmc/gmc_8_1_sh_mask.h" | ||
| 28 | |||
| 29 | #include "bif/bif_5_0_d.h" | ||
| 30 | #include "bif/bif_5_0_sh_mask.h" | ||
| 31 | |||
| 32 | #include "dce/dce_11_0_d.h" | ||
| 33 | #include "dce/dce_11_0_sh_mask.h" | ||
| 34 | |||
| 35 | #include "smu/smu_7_1_3_d.h" | ||
| 36 | #include "smu/smu_7_1_3_sh_mask.h" | ||
| 37 | |||
| 38 | static const struct baco_cmd_entry gpio_tbl[] = | ||
| 39 | { | ||
| 40 | { CMD_WRITE, mmGPIOPAD_EN, 0, 0, 0, 0x0 }, | ||
| 41 | { CMD_WRITE, mmGPIOPAD_PD_EN, 0, 0, 0, 0x0 }, | ||
| 42 | { CMD_WRITE, mmGPIOPAD_PU_EN, 0, 0, 0, 0x0 }, | ||
| 43 | { CMD_WRITE, mmGPIOPAD_MASK, 0, 0, 0, 0xff77ffff }, | ||
| 44 | { CMD_WRITE, mmDC_GPIO_DVODATA_EN, 0, 0, 0, 0x0 }, | ||
| 45 | { CMD_WRITE, mmDC_GPIO_DVODATA_MASK, 0, 0, 0, 0xffffffff }, | ||
| 46 | { CMD_WRITE, mmDC_GPIO_GENERIC_EN, 0, 0, 0, 0x0 }, | ||
| 47 | { CMD_READMODIFYWRITE, mmDC_GPIO_GENERIC_MASK, 0, 0, 0, 0x03333333 }, | ||
| 48 | { CMD_WRITE, mmDC_GPIO_SYNCA_EN, 0, 0, 0, 0x0 }, | ||
| 49 | { CMD_READMODIFYWRITE, mmDC_GPIO_SYNCA_MASK, 0, 0, 0, 0x00001111 } | ||
| 50 | }; | ||
| 51 | |||
| 52 | static const struct baco_cmd_entry enable_fb_req_rej_tbl[] = | ||
| 53 | { | ||
| 54 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0300024 }, | ||
| 55 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 }, | ||
| 56 | { CMD_WRITE, mmBIF_FB_EN, 0, 0, 0, 0x0 } | ||
| 57 | }; | ||
| 58 | |||
| 59 | static const struct baco_cmd_entry use_bclk_tbl[] = | ||
| 60 | { | ||
| 61 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, | ||
| 62 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN_MASK, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN__SHIFT, 0, 0x1 }, | ||
| 63 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 }, | ||
| 64 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x4000000, 0x1a, 0, 0x1 }, | ||
| 65 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixGCK_DFS_BYPASS_CNTL }, | ||
| 66 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, GCK_DFS_BYPASS_CNTL__BYPASSACLK_MASK, GCK_DFS_BYPASS_CNTL__BYPASSACLK__SHIFT, 0, 0x1 }, | ||
| 67 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL }, | ||
| 68 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x2 }, | ||
| 69 | { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__MPLL_SW_DIR_CONTROL_MASK, MPLL_CNTL_MODE__MPLL_SW_DIR_CONTROL__SHIFT, 0, 0x1 }, | ||
| 70 | { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__MPLL_MCLK_SEL_MASK, MPLL_CNTL_MODE__MPLL_MCLK_SEL__SHIFT, 0, 0x0 } | ||
| 71 | }; | ||
| 72 | |||
| 73 | static const struct baco_cmd_entry turn_off_plls_tbl[] = | ||
| 74 | { | ||
| 75 | { CMD_READMODIFYWRITE, mmDC_GPIO_PAD_STRENGTH_1, DC_GPIO_PAD_STRENGTH_1__GENLK_STRENGTH_SP_MASK, DC_GPIO_PAD_STRENGTH_1__GENLK_STRENGTH_SP__SHIFT, 0, 0x1 }, | ||
| 76 | { CMD_DELAY_US, 0, 0, 0, 1, 0x0 }, | ||
| 77 | { CMD_READMODIFYWRITE, mmMC_SEQ_DRAM, MC_SEQ_DRAM__RST_CTL_MASK, MC_SEQ_DRAM__RST_CTL__SHIFT, 0, 0x1 }, | ||
| 78 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC05002B0 }, | ||
| 79 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x10, 0x4, 0, 0x1 }, | ||
| 80 | { CMD_WAITFOR, mmGCK_SMC_IND_DATA, 0x10, 0, 1, 0 }, | ||
| 81 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC050032C }, | ||
| 82 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x10, 0x4, 0, 0x1 }, | ||
| 83 | { CMD_WAITFOR, mmGCK_SMC_IND_DATA, 0x10, 0, 1, 0 }, | ||
| 84 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500080 }, | ||
| 85 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 }, | ||
| 86 | { CMD_READMODIFYWRITE, 0xda2, 0x40, 0x6, 0, 0x0 }, | ||
| 87 | { CMD_DELAY_US, 0, 0, 0, 3, 0x0 }, | ||
| 88 | { CMD_READMODIFYWRITE, 0xda2, 0x8, 0x3, 0, 0x0 }, | ||
| 89 | { CMD_READMODIFYWRITE, 0xda2, 0x3fff00, 0x8, 0, 0x32 }, | ||
| 90 | { CMD_DELAY_US, 0, 0, 0, 3, 0x0 }, | ||
| 91 | { CMD_READMODIFYWRITE, mmMPLL_FUNC_CNTL_2, MPLL_FUNC_CNTL_2__ISO_DIS_P_MASK, MPLL_FUNC_CNTL_2__ISO_DIS_P__SHIFT, 0, 0x0 }, | ||
| 92 | { CMD_DELAY_US, 0, 0, 0, 5, 0x0 } | ||
| 93 | }; | ||
| 94 | |||
| 95 | static const struct baco_cmd_entry clk_req_b_tbl[] = | ||
| 96 | { | ||
| 97 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixTHM_CLK_CNTL }, | ||
| 98 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__CMON_CLK_SEL_MASK, THM_CLK_CNTL__CMON_CLK_SEL__SHIFT, 0, 0x1 }, | ||
| 99 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__TMON_CLK_SEL_MASK, THM_CLK_CNTL__TMON_CLK_SEL__SHIFT, 0, 0x1 }, | ||
| 100 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMISC_CLK_CTRL }, | ||
| 101 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL_MASK, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL__SHIFT, 0, 0x1 }, | ||
| 102 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__ZCLK_SEL_MASK, MISC_CLK_CTRL__ZCLK_SEL__SHIFT, 0, 0x1 }, | ||
| 103 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL }, | ||
| 104 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL__BCLK_AS_XCLK_MASK, CG_CLKPIN_CNTL__BCLK_AS_XCLK__SHIFT, 0, 0x0 }, | ||
| 105 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL_2 }, | ||
| 106 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN_MASK, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN__SHIFT, 0, 0x0 }, | ||
| 107 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL }, | ||
| 108 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x4 } | ||
| 109 | }; | ||
| 110 | |||
| 111 | static const struct baco_cmd_entry enter_baco_tbl[] = | ||
| 112 | { | ||
| 113 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x01 }, | ||
| 114 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x01 }, | ||
| 115 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, 0, 5, 0x40000 }, | ||
| 116 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x01 }, | ||
| 117 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, 0, 5, 0x02 }, | ||
| 118 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x00 }, | ||
| 119 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, 0, 5, 0x00 }, | ||
| 120 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x00 }, | ||
| 121 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, 0, 5, 0x00 }, | ||
| 122 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x01 }, | ||
| 123 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, 0, 5, 0x08 }, | ||
| 124 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x40 } | ||
| 125 | }; | ||
| 126 | |||
| 127 | #define BACO_CNTL__PWRGOOD_MASK BACO_CNTL__PWRGOOD_GPIO_MASK+BACO_CNTL__PWRGOOD_MEM_MASK+BACO_CNTL__PWRGOOD_DVO_MASK | ||
| 128 | |||
| 129 | static const struct baco_cmd_entry exit_baco_tbl[] = | ||
| 130 | { | ||
| 131 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x01 }, | ||
| 132 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x00 }, | ||
| 133 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x00 }, | ||
| 134 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_BF_MASK, 0, 0xffffffff, 0x200 }, | ||
| 135 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x01 }, | ||
| 136 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_MASK, 0, 5, 0x1c00 }, | ||
| 137 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x01 }, | ||
| 138 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x00 }, | ||
| 139 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x00 }, | ||
| 140 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__RCU_BIF_CONFIG_DONE_MASK, 0, 5, 0x100 }, | ||
| 141 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x00 }, | ||
| 142 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x00 } | ||
| 143 | }; | ||
| 144 | |||
| 145 | static const struct baco_cmd_entry clean_baco_tbl[] = | ||
| 146 | { | ||
| 147 | { CMD_WRITE, mmBIOS_SCRATCH_6, 0, 0, 0, 0 }, | ||
| 148 | { CMD_WRITE, mmBIOS_SCRATCH_7, 0, 0, 0, 0 } | ||
| 149 | }; | ||
| 150 | |||
| 151 | static const struct baco_cmd_entry use_bclk_tbl_vg[] = | ||
| 152 | { | ||
| 153 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, | ||
| 154 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN_MASK, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN__SHIFT, 0, 0x1 }, | ||
| 155 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 }, | ||
| 156 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x4000000, 0x1a, 0, 0x1 }, | ||
| 157 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixGCK_DFS_BYPASS_CNTL }, | ||
| 158 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, GCK_DFS_BYPASS_CNTL__BYPASSACLK_MASK, GCK_DFS_BYPASS_CNTL__BYPASSACLK__SHIFT, 0, 0x1 }, | ||
| 159 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL }, | ||
| 160 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x2 } | ||
| 161 | }; | ||
| 162 | |||
| 163 | static const struct baco_cmd_entry turn_off_plls_tbl_vg[] = | ||
| 164 | { | ||
| 165 | { CMD_READMODIFYWRITE, mmDC_GPIO_PAD_STRENGTH_1, DC_GPIO_PAD_STRENGTH_1__GENLK_STRENGTH_SP_MASK, DC_GPIO_PAD_STRENGTH_1__GENLK_STRENGTH_SP__SHIFT, 0, 0x1 }, | ||
| 166 | { CMD_DELAY_US, 0, 0, 0, 1, 0x0 }, | ||
| 167 | { CMD_READMODIFYWRITE, mmMC_SEQ_DRAM, MC_SEQ_DRAM__RST_CTL_MASK, MC_SEQ_DRAM__RST_CTL__SHIFT, 0, 0x1 }, | ||
| 168 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC05002B0 }, | ||
| 169 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x10, 0x4, 0, 0x1 }, | ||
| 170 | { CMD_WAITFOR, mmGCK_SMC_IND_DATA, 0x10, 0, 1, 0 }, | ||
| 171 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC050032C }, | ||
| 172 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x10, 0x4, 0, 0x1 }, | ||
| 173 | { CMD_WAITFOR, mmGCK_SMC_IND_DATA, 0x10, 0, 1, 0 }, | ||
| 174 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500080 }, | ||
| 175 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 }, | ||
| 176 | { CMD_DELAY_US, 0, 0, 0, 3, 0x0 }, | ||
| 177 | { CMD_DELAY_US, 0, 0, 0, 3, 0x0 }, | ||
| 178 | { CMD_DELAY_US, 0, 0, 0, 5, 0x0 } | ||
| 179 | }; | ||
| 180 | |||
| 181 | int polaris_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state) | ||
| 182 | { | ||
| 183 | enum BACO_STATE cur_state; | ||
| 184 | |||
| 185 | smu7_baco_get_state(hwmgr, &cur_state); | ||
| 186 | |||
| 187 | if (cur_state == state) | ||
| 188 | /* aisc already in the target state */ | ||
| 189 | return 0; | ||
| 190 | |||
| 191 | if (state == BACO_STATE_IN) { | ||
| 192 | baco_program_registers(hwmgr, gpio_tbl, ARRAY_SIZE(gpio_tbl)); | ||
| 193 | baco_program_registers(hwmgr, enable_fb_req_rej_tbl, | ||
| 194 | ARRAY_SIZE(enable_fb_req_rej_tbl)); | ||
| 195 | if (hwmgr->chip_id == CHIP_VEGAM) { | ||
| 196 | baco_program_registers(hwmgr, use_bclk_tbl_vg, ARRAY_SIZE(use_bclk_tbl_vg)); | ||
| 197 | baco_program_registers(hwmgr, turn_off_plls_tbl_vg, | ||
| 198 | ARRAY_SIZE(turn_off_plls_tbl_vg)); | ||
| 199 | } else { | ||
| 200 | baco_program_registers(hwmgr, use_bclk_tbl, ARRAY_SIZE(use_bclk_tbl)); | ||
| 201 | baco_program_registers(hwmgr, turn_off_plls_tbl, | ||
| 202 | ARRAY_SIZE(turn_off_plls_tbl)); | ||
| 203 | } | ||
| 204 | baco_program_registers(hwmgr, clk_req_b_tbl, ARRAY_SIZE(clk_req_b_tbl)); | ||
| 205 | if (baco_program_registers(hwmgr, enter_baco_tbl, | ||
| 206 | ARRAY_SIZE(enter_baco_tbl))) | ||
| 207 | return 0; | ||
| 208 | |||
| 209 | } else if (state == BACO_STATE_OUT) { | ||
| 210 | /* HW requires at least 20ms between regulator off and on */ | ||
| 211 | msleep(20); | ||
| 212 | /* Execute Hardware BACO exit sequence */ | ||
| 213 | if (baco_program_registers(hwmgr, exit_baco_tbl, | ||
| 214 | ARRAY_SIZE(exit_baco_tbl))) { | ||
| 215 | if (baco_program_registers(hwmgr, clean_baco_tbl, | ||
| 216 | ARRAY_SIZE(clean_baco_tbl))) | ||
| 217 | return 0; | ||
| 218 | } | ||
| 219 | } | ||
| 220 | |||
| 221 | return -EINVAL; | ||
| 222 | } | ||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2019 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 | #ifndef __POLARIS_BACO_H__ | ||
| 24 | #define __POLARIS_BACO_H__ | ||
| 25 | #include "smu7_baco.h" | ||
| 26 | |||
| 27 | extern int polaris_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state); | ||
| 28 | |||
| 29 | #endif | ||
| @@ -0,0 +1,91 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2019 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 | #include "amdgpu.h" | ||
| 24 | #include "smu7_baco.h" | ||
| 25 | #include "tonga_baco.h" | ||
| 26 | #include "fiji_baco.h" | ||
| 27 | #include "polaris_baco.h" | ||
| 28 | #include "ci_baco.h" | ||
| 29 | |||
| 30 | #include "bif/bif_5_0_d.h" | ||
| 31 | #include "bif/bif_5_0_sh_mask.h" | ||
| 32 | |||
| 33 | #include "smu/smu_7_1_2_d.h" | ||
| 34 | #include "smu/smu_7_1_2_sh_mask.h" | ||
| 35 | |||
| 36 | int smu7_baco_get_capability(struct pp_hwmgr *hwmgr, bool *cap) | ||
| 37 | { | ||
| 38 | struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); | ||
| 39 | uint32_t reg; | ||
| 40 | |||
| 41 | *cap = false; | ||
| 42 | if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_BACO)) | ||
| 43 | return 0; | ||
| 44 | |||
| 45 | reg = RREG32(mmCC_BIF_BX_FUSESTRAP0); | ||
| 46 | |||
| 47 | if (reg & CC_BIF_BX_FUSESTRAP0__STRAP_BIF_PX_CAPABLE_MASK) | ||
| 48 | *cap = true; | ||
| 49 | |||
| 50 | return 0; | ||
| 51 | } | ||
| 52 | |||
| 53 | int smu7_baco_get_state(struct pp_hwmgr *hwmgr, enum BACO_STATE *state) | ||
| 54 | { | ||
| 55 | struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); | ||
| 56 | uint32_t reg; | ||
| 57 | |||
| 58 | reg = RREG32(mmBACO_CNTL); | ||
| 59 | |||
| 60 | if (reg & BACO_CNTL__BACO_MODE_MASK) | ||
| 61 | /* gfx has already entered BACO state */ | ||
| 62 | *state = BACO_STATE_IN; | ||
| 63 | else | ||
| 64 | *state = BACO_STATE_OUT; | ||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | |||
| 68 | int smu7_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state) | ||
| 69 | { | ||
| 70 | struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); | ||
| 71 | |||
| 72 | switch (adev->asic_type) { | ||
| 73 | case CHIP_TOPAZ: | ||
| 74 | case CHIP_TONGA: | ||
| 75 | return tonga_baco_set_state(hwmgr, state); | ||
| 76 | case CHIP_FIJI: | ||
| 77 | return fiji_baco_set_state(hwmgr, state); | ||
| 78 | case CHIP_POLARIS10: | ||
| 79 | case CHIP_POLARIS11: | ||
| 80 | case CHIP_POLARIS12: | ||
| 81 | case CHIP_VEGAM: | ||
| 82 | return polaris_baco_set_state(hwmgr, state); | ||
| 83 | #ifdef CONFIG_DRM_AMDGPU_CIK | ||
| 84 | case CHIP_BONAIRE: | ||
| 85 | case CHIP_HAWAII: | ||
| 86 | return ci_baco_set_state(hwmgr, state); | ||
| 87 | #endif | ||
| 88 | default: | ||
| 89 | return -EINVAL; | ||
| 90 | } | ||
| 91 | } | ||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2019 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 | #ifndef __SMU7_BACO_H__ | ||
| 24 | #define __SMU7_BACO_H__ | ||
| 25 | #include "hwmgr.h" | ||
| 26 | #include "common_baco.h" | ||
| 27 | |||
| 28 | extern int smu7_baco_get_capability(struct pp_hwmgr *hwmgr, bool *cap); | ||
| 29 | extern int smu7_baco_get_state(struct pp_hwmgr *hwmgr, enum BACO_STATE *state); | ||
| 30 | extern int smu7_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state); | ||
| 31 | |||
| 32 | #endif | ||
| @@ -48,6 +48,7 @@ · 47 unmodified lines | |||
| 48 | #include "smu7_clockpowergating.h" | 48 | #include "smu7_clockpowergating.h" |
| 49 | #include "processpptables.h" | 49 | #include "processpptables.h" |
| 50 | #include "pp_thermal.h" | 50 | #include "pp_thermal.h" |
| 51 | #include "smu7_baco.h" | ||
| 51 | 52 | ||
| 52 | #include "ivsrcid/ivsrcid_vislands30.h" | 53 | #include "ivsrcid/ivsrcid_vislands30.h" |
| 53 | 54 | ||
| @@ -1994,7 +1995,6 @@ static int smu7_sort_lookup_table(struct pp_hwmgr *hwmgr, · 1940 unmodified lines | |||
| 1994 | struct phm_ppt_v1_voltage_lookup_table *lookup_table) | 1995 | struct phm_ppt_v1_voltage_lookup_table *lookup_table) |
| 1995 | { | 1996 | { |
| 1996 | uint32_t table_size, i, j; | 1997 | uint32_t table_size, i, j; |
| 1997 | struct phm_ppt_v1_voltage_lookup_record tmp_voltage_lookup_record; | ||
| 1998 | table_size = lookup_table->count; | 1998 | table_size = lookup_table->count; |
| 1999 | 1999 | ||
| 2000 | PP_ASSERT_WITH_CODE(0 != lookup_table->count, | 2000 | PP_ASSERT_WITH_CODE(0 != lookup_table->count, |
| @@ -2005,9 +2005,8 @@ static int smu7_sort_lookup_table(struct pp_hwmgr *hwmgr, · 4 unmodified lines | |||
| 2005 | for (j = i + 1; j > 0; j--) { | 2005 | for (j = i + 1; j > 0; j--) { |
| 2006 | if (lookup_table->entries[j].us_vdd < | 2006 | if (lookup_table->entries[j].us_vdd < |
| 2007 | lookup_table->entries[j - 1].us_vdd) { | 2007 | lookup_table->entries[j - 1].us_vdd) { |
| 2008 | tmp_voltage_lookup_record = lookup_table->entries[j - 1]; | 2008 | swap(lookup_table->entries[j - 1], |
| 2009 | lookup_table->entries[j - 1] = lookup_table->entries[j]; | 2009 | lookup_table->entries[j]); |
| 2010 | lookup_table->entries[j] = tmp_voltage_lookup_record; | ||
| 2011 | } | 2010 | } |
| 2012 | } | 2011 | } |
| 2013 | } | 2012 | } |
| @@ -5145,6 +5144,9 @@ static const struct pp_hwmgr_func smu7_hwmgr_funcs = { · 3131 unmodified lines | |||
| 5145 | .get_power_profile_mode = smu7_get_power_profile_mode, | 5144 | .get_power_profile_mode = smu7_get_power_profile_mode, |
| 5146 | .set_power_profile_mode = smu7_set_power_profile_mode, | 5145 | .set_power_profile_mode = smu7_set_power_profile_mode, |
| 5147 | .get_performance_level = smu7_get_performance_level, | 5146 | .get_performance_level = smu7_get_performance_level, |
| 5147 | .get_asic_baco_capability = smu7_baco_get_capability, | ||
| 5148 | .get_asic_baco_state = smu7_baco_get_state, | ||
| 5149 | .set_asic_baco_state = smu7_baco_set_state, | ||
| 5148 | .power_off_asic = smu7_power_off_asic, | 5150 | .power_off_asic = smu7_power_off_asic, |
| 5149 | }; | 5151 | }; |
| 5150 | 5152 | ||
| @@ -0,0 +1,231 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2019 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 | #include "amdgpu.h" | ||
| 24 | #include "tonga_baco.h" | ||
| 25 | |||
| 26 | #include "gmc/gmc_8_1_d.h" | ||
| 27 | #include "gmc/gmc_8_1_sh_mask.h" | ||
| 28 | |||
| 29 | #include "bif/bif_5_0_d.h" | ||
| 30 | #include "bif/bif_5_0_sh_mask.h" | ||
| 31 | |||
| 32 | #include "dce/dce_10_0_d.h" | ||
| 33 | #include "dce/dce_10_0_sh_mask.h" | ||
| 34 | |||
| 35 | #include "smu/smu_7_1_2_d.h" | ||
| 36 | #include "smu/smu_7_1_2_sh_mask.h" | ||
| 37 | |||
| 38 | |||
| 39 | static const struct baco_cmd_entry gpio_tbl[] = | ||
| 40 | { | ||
| 41 | { CMD_WRITE, mmGPIOPAD_EN, 0, 0, 0, 0x0 }, | ||
| 42 | { CMD_WRITE, mmGPIOPAD_PD_EN, 0, 0, 0, 0x0 }, | ||
| 43 | { CMD_WRITE, mmGPIOPAD_PU_EN, 0, 0, 0, 0x0 }, | ||
| 44 | { CMD_WRITE, mmGPIOPAD_MASK, 0, 0, 0, 0xff77ffff }, | ||
| 45 | { CMD_WRITE, mmDC_GPIO_DVODATA_EN, 0, 0, 0, 0x0 }, | ||
| 46 | { CMD_WRITE, mmDC_GPIO_DVODATA_MASK, 0, 0, 0, 0xffffffff }, | ||
| 47 | { CMD_WRITE, mmDC_GPIO_GENERIC_EN, 0, 0, 0, 0x0 }, | ||
| 48 | { CMD_READMODIFYWRITE, mmDC_GPIO_GENERIC_MASK, 0, 0, 0, 0x03333333 }, | ||
| 49 | { CMD_WRITE, mmDC_GPIO_SYNCA_EN, 0, 0, 0, 0x0 }, | ||
| 50 | { CMD_READMODIFYWRITE, mmDC_GPIO_SYNCA_MASK, 0, 0, 0, 0x00001111 } | ||
| 51 | }; | ||
| 52 | |||
| 53 | static const struct baco_cmd_entry enable_fb_req_rej_tbl[] = | ||
| 54 | { | ||
| 55 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0300024 }, | ||
| 56 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 }, | ||
| 57 | { CMD_WRITE, mmBIF_FB_EN, 0, 0, 0, 0x0 } | ||
| 58 | }; | ||
| 59 | |||
| 60 | static const struct baco_cmd_entry use_bclk_tbl[] = | ||
| 61 | { | ||
| 62 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, | ||
| 63 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN_MASK, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN__SHIFT, 0, 0x1 }, | ||
| 64 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 }, | ||
| 65 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG__SHIFT, 0, 0x1 }, | ||
| 66 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_STATUS }, | ||
| 67 | { CMD_WAITFOR, mmGCK_SMC_IND_DATA, CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK, 0, 0xffffffff, 0x2 }, | ||
| 68 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 }, | ||
| 69 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_BYPASS_CHG__SHIFT, 0, 0x0 }, | ||
| 70 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG__SHIFT, 0, 0x1 }, | ||
| 71 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_STATUS }, | ||
| 72 | { CMD_WAITFOR, mmGCK_SMC_IND_DATA, CG_SPLL_STATUS__SPLL_CHG_STATUS_MASK, 0, 0xffffffff, 0x2 }, | ||
| 73 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 }, | ||
| 74 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG_MASK, CG_SPLL_FUNC_CNTL_2__SPLL_CTLREQ_CHG__SHIFT, 0, 0x0 }, | ||
| 75 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 }, | ||
| 76 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x4000000, 0x1a, 0, 0x1 }, | ||
| 77 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL }, | ||
| 78 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x2 }, | ||
| 79 | { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__MPLL_SW_DIR_CONTROL_MASK, MPLL_CNTL_MODE__MPLL_SW_DIR_CONTROL__SHIFT, 0, 0x1 }, | ||
| 80 | { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__MPLL_MCLK_SEL_MASK, MPLL_CNTL_MODE__MPLL_MCLK_SEL__SHIFT, 0, 0x0 } | ||
| 81 | }; | ||
| 82 | |||
| 83 | static const struct baco_cmd_entry turn_off_plls_tbl[] = | ||
| 84 | { | ||
| 85 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, | ||
| 86 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_RESET_MASK, CG_SPLL_FUNC_CNTL__SPLL_RESET__SHIFT, 0, 0x1 }, | ||
| 87 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_PWRON_MASK, CG_SPLL_FUNC_CNTL__SPLL_PWRON__SHIFT, 0, 0x0 }, | ||
| 88 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 }, | ||
| 89 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x2000000, 0x19, 0, 0x1 }, | ||
| 90 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x8000000, 0x1b, 0, 0x0 }, | ||
| 91 | { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__GLOBAL_MPLL_RESET_MASK, MPLL_CNTL_MODE__GLOBAL_MPLL_RESET__SHIFT, 0, 0x1 }, | ||
| 92 | { CMD_WRITE, mmMPLL_CONTROL, 0, 0, 0, 0x00000006 }, | ||
| 93 | { CMD_WRITE, mmMC_IO_RXCNTL_DPHY0_D0, 0, 0, 0, 0x00007740 }, | ||
| 94 | { CMD_WRITE, mmMC_IO_RXCNTL_DPHY0_D1, 0, 0, 0, 0x00007740 }, | ||
| 95 | { CMD_WRITE, mmMC_IO_RXCNTL_DPHY1_D0, 0, 0, 0, 0x00007740 }, | ||
| 96 | { CMD_WRITE, mmMC_IO_RXCNTL_DPHY1_D1, 0, 0, 0, 0x00007740 }, | ||
| 97 | { CMD_READMODIFYWRITE, mmMCLK_PWRMGT_CNTL, MCLK_PWRMGT_CNTL__MRDCK0_PDNB_MASK, MCLK_PWRMGT_CNTL__MRDCK0_PDNB__SHIFT, 0, 0x0 }, | ||
| 98 | { CMD_READMODIFYWRITE, mmMCLK_PWRMGT_CNTL, MCLK_PWRMGT_CNTL__MRDCK1_PDNB_MASK, MCLK_PWRMGT_CNTL__MRDCK1_PDNB__SHIFT, 0, 0x0 }, | ||
| 99 | { CMD_READMODIFYWRITE, mmMC_SEQ_CNTL_2, MC_SEQ_CNTL_2__DRST_PU_MASK, MC_SEQ_CNTL_2__DRST_PU__SHIFT, 0, 0x0 }, | ||
| 100 | { CMD_READMODIFYWRITE, mmMC_SEQ_CNTL_2, MC_SEQ_CNTL_2__DRST_PD_MASK, MC_SEQ_CNTL_2__DRST_PD__SHIFT, 0, 0x0 }, | ||
| 101 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL_2 }, | ||
| 102 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN_MASK, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN__SHIFT, 0, 0x0 }, | ||
| 103 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL }, | ||
| 104 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x4 }, | ||
| 105 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMISC_CLK_CTRL }, | ||
| 106 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL_MASK, MISC_CLK_CTRL__DEEP_SLEEP_CLK_SEL__SHIFT, 0, 0x1 }, | ||
| 107 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MISC_CLK_CTRL__ZCLK_SEL_MASK, MISC_CLK_CTRL__ZCLK_SEL__SHIFT, 0, 0x1 }, | ||
| 108 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL }, | ||
| 109 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL__BCLK_AS_XCLK_MASK, CG_CLKPIN_CNTL__BCLK_AS_XCLK__SHIFT, 0, 0x0 }, | ||
| 110 | { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixTHM_CLK_CNTL }, | ||
| 111 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__CMON_CLK_SEL_MASK, THM_CLK_CNTL__CMON_CLK_SEL__SHIFT, 0, 0x1 }, | ||
| 112 | { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__TMON_CLK_SEL_MASK, THM_CLK_CNTL__TMON_CLK_SEL__SHIFT, 0, 0x1 } | ||
| 113 | }; | ||
| 114 | |||
| 115 | static const struct baco_cmd_entry enter_baco_tbl[] = | ||
| 116 | { | ||
| 117 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x01 }, | ||
| 118 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x01 }, | ||
| 119 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, 0, 5, 0x40000 }, | ||
| 120 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x01 }, | ||
| 121 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, 0, 5, 0x02 }, | ||
| 122 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x00 }, | ||
| 123 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, 0, 5, 0x00 }, | ||
| 124 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x00 }, | ||
| 125 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, 0, 5, 0x00 }, | ||
| 126 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x01 }, | ||
| 127 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, 0, 5, 0x08 }, | ||
| 128 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x40 } | ||
| 129 | }; | ||
| 130 | |||
| 131 | #define BACO_CNTL__PWRGOOD_MASK BACO_CNTL__PWRGOOD_GPIO_MASK+BACO_CNTL__PWRGOOD_MEM_MASK+BACO_CNTL__PWRGOOD_DVO_MASK | ||
| 132 | |||
| 133 | static const struct baco_cmd_entry exit_baco_tbl[] = | ||
| 134 | { | ||
| 135 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x01 }, | ||
| 136 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x00 }, | ||
| 137 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x00 }, | ||
| 138 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_BF_MASK, 0, 0xffffffff, 0x200 }, | ||
| 139 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x01 }, | ||
| 140 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_MASK, 0, 5, 0x1c00 }, | ||
| 141 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x01 }, | ||
| 142 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x00 }, | ||
| 143 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x00 }, | ||
| 144 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__RCU_BIF_CONFIG_DONE_MASK, 0, 5, 0x100 }, | ||
| 145 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x00 }, | ||
| 146 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x00 } | ||
| 147 | }; | ||
| 148 | |||
| 149 | static const struct baco_cmd_entry clean_baco_tbl[] = | ||
| 150 | { | ||
| 151 | { CMD_WRITE, mmBIOS_SCRATCH_6, 0, 0, 0, 0 }, | ||
| 152 | { CMD_WRITE, mmBIOS_SCRATCH_7, 0, 0, 0, 0 } | ||
| 153 | }; | ||
| 154 | |||
| 155 | static const struct baco_cmd_entry gpio_tbl_iceland[] = | ||
| 156 | { | ||
| 157 | { CMD_WRITE, mmGPIOPAD_EN, 0, 0, 0, 0x0 }, | ||
| 158 | { CMD_WRITE, mmGPIOPAD_PD_EN, 0, 0, 0, 0x0 }, | ||
| 159 | { CMD_WRITE, mmGPIOPAD_PU_EN, 0, 0, 0, 0x0 }, | ||
| 160 | { CMD_WRITE, mmGPIOPAD_MASK, 0, 0, 0, 0xff77ffff } | ||
| 161 | }; | ||
| 162 | |||
| 163 | static const struct baco_cmd_entry exit_baco_tbl_iceland[] = | ||
| 164 | { | ||
| 165 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x01 }, | ||
| 166 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x00 }, | ||
| 167 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x00 }, | ||
| 168 | { CMD_DELAY_MS, 0, 0, 0, 20, 0 }, | ||
| 169 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_BF_MASK, 0, 0xffffffff, 0x200 }, | ||
| 170 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ISO_DIS_MASK, BACO_CNTL__BACO_ISO_DIS__SHIFT, 0, 0x01 }, | ||
| 171 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__PWRGOOD_MASK, 0, 5, 0x1c00 }, | ||
| 172 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_ANA_ISO_DIS_MASK, BACO_CNTL__BACO_ANA_ISO_DIS__SHIFT, 0, 0x01 }, | ||
| 173 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x00 }, | ||
| 174 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x00 }, | ||
| 175 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__RCU_BIF_CONFIG_DONE_MASK, 0, 5, 0x100 }, | ||
| 176 | { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x00 }, | ||
| 177 | { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x00 } | ||
| 178 | }; | ||
| 179 | |||
| 180 | static const struct baco_cmd_entry clean_baco_tbl_iceland[] = | ||
| 181 | { | ||
| 182 | { CMD_WRITE, mmBIOS_SCRATCH_7, 0, 0, 0, 0 } | ||
| 183 | }; | ||
| 184 | |||
| 185 | int tonga_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state) | ||
| 186 | { | ||
| 187 | enum BACO_STATE cur_state; | ||
| 188 | |||
| 189 | smu7_baco_get_state(hwmgr, &cur_state); | ||
| 190 | |||
| 191 | if (cur_state == state) | ||
| 192 | /* aisc already in the target state */ | ||
| 193 | return 0; | ||
| 194 | |||
| 195 | if (state == BACO_STATE_IN) { | ||
| 196 | if (hwmgr->chip_id == CHIP_TOPAZ) | ||
| 197 | baco_program_registers(hwmgr, gpio_tbl_iceland, ARRAY_SIZE(gpio_tbl_iceland)); | ||
| 198 | else | ||
| 199 | baco_program_registers(hwmgr, gpio_tbl, ARRAY_SIZE(gpio_tbl)); | ||
| 200 | baco_program_registers(hwmgr, enable_fb_req_rej_tbl, | ||
| 201 | ARRAY_SIZE(enable_fb_req_rej_tbl)); | ||
| 202 | baco_program_registers(hwmgr, use_bclk_tbl, ARRAY_SIZE(use_bclk_tbl)); | ||
| 203 | baco_program_registers(hwmgr, turn_off_plls_tbl, | ||
| 204 | ARRAY_SIZE(turn_off_plls_tbl)); | ||
| 205 | if (baco_program_registers(hwmgr, enter_baco_tbl, | ||
| 206 | ARRAY_SIZE(enter_baco_tbl))) | ||
| 207 | return 0; | ||
| 208 | |||
| 209 | } else if (state == BACO_STATE_OUT) { | ||
| 210 | /* HW requires at least 20ms between regulator off and on */ | ||
| 211 | msleep(20); | ||
| 212 | /* Execute Hardware BACO exit sequence */ | ||
| 213 | if (hwmgr->chip_id == CHIP_TOPAZ) { | ||
| 214 | if (baco_program_registers(hwmgr, exit_baco_tbl_iceland, | ||
| 215 | ARRAY_SIZE(exit_baco_tbl_iceland))) { | ||
| 216 | if (baco_program_registers(hwmgr, clean_baco_tbl_iceland, | ||
| 217 | ARRAY_SIZE(clean_baco_tbl_iceland))) | ||
| 218 | return 0; | ||
| 219 | } | ||
| 220 | } else { | ||
| 221 | if (baco_program_registers(hwmgr, exit_baco_tbl, | ||
| 222 | ARRAY_SIZE(exit_baco_tbl))) { | ||
| 223 | if (baco_program_registers(hwmgr, clean_baco_tbl, | ||
| 224 | ARRAY_SIZE(clean_baco_tbl))) | ||
| 225 | return 0; | ||
| 226 | } | ||
| 227 | } | ||
| 228 | } | ||
| 229 | |||
| 230 | return -EINVAL; | ||
| 231 | } | ||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2019 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 | #ifndef __TONGA_BACO_H__ | ||
| 24 | #define __TONGA_BACO_H__ | ||
| 25 | #include "smu7_baco.h" | ||
| 26 | |||
| 27 | extern int tonga_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state); | ||
| 28 | |||
| 29 | #endif | ||
| @@ -712,7 +712,6 @@ static int vega10_sort_lookup_table(struct pp_hwmgr *hwmgr, · 711 unmodified lines | |||
| 712 | struct phm_ppt_v1_voltage_lookup_table *lookup_table) | 712 | struct phm_ppt_v1_voltage_lookup_table *lookup_table) |
| 713 | { | 713 | { |
| 714 | uint32_t table_size, i, j; | 714 | uint32_t table_size, i, j; |
| 715 | struct phm_ppt_v1_voltage_lookup_record tmp_voltage_lookup_record; | ||
| 716 | 715 | ||
| 717 | PP_ASSERT_WITH_CODE(lookup_table && lookup_table->count, | 716 | PP_ASSERT_WITH_CODE(lookup_table && lookup_table->count, |
| 718 | "Lookup table is empty", return -EINVAL); | 717 | "Lookup table is empty", return -EINVAL); |
| @@ -724,9 +723,8 @@ static int vega10_sort_lookup_table(struct pp_hwmgr *hwmgr, · 5 unmodified lines | |||
| 724 | for (j = i + 1; j > 0; j--) { | 723 | for (j = i + 1; j > 0; j--) { |
| 725 | if (lookup_table->entries[j].us_vdd < | 724 | if (lookup_table->entries[j].us_vdd < |
| 726 | lookup_table->entries[j - 1].us_vdd) { | 725 | lookup_table->entries[j - 1].us_vdd) { |
| 727 | tmp_voltage_lookup_record = lookup_table->entries[j - 1]; | 726 | swap(lookup_table->entries[j - 1], |
| 728 | lookup_table->entries[j - 1] = lookup_table->entries[j]; | 727 | lookup_table->entries[j]); |
| 729 | lookup_table->entries[j] = tmp_voltage_lookup_record; | ||
| 730 | } | 728 | } |
| 731 | } | 729 | } |
| 732 | } | 730 | } |
| @@ -29,7 +29,7 @@ · 28 unmodified lines | |||
| 29 | #include "vega20_baco.h" | 29 | #include "vega20_baco.h" |
| 30 | #include "vega20_smumgr.h" | 30 | #include "vega20_smumgr.h" |
| 31 | 31 | ||
| 32 | 32 | #include "amdgpu_ras.h" | |
| 33 | 33 | ||
| 34 | static const struct soc15_baco_cmd_entry clean_baco_tbl[] = | 34 | static const struct soc15_baco_cmd_entry clean_baco_tbl[] = |
| 35 | { | 35 | { |
| @@ -74,6 +74,7 @@ int vega20_baco_get_state(struct pp_hwmgr *hwmgr, enum BACO_STATE *state) · 38 unmodified lines | |||
| 74 | int vega20_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state) | 74 | int vega20_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state) |
| 75 | { | 75 | { |
| 76 | struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); | 76 | struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); |
| 77 | struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); | ||
| 77 | enum BACO_STATE cur_state; | 78 | enum BACO_STATE cur_state; |
| 78 | uint32_t data; | 79 | uint32_t data; |
| 79 | 80 | ||
| @@ -84,13 +85,19 @@ int vega20_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state) · 4 unmodified lines | |||
| 84 | return 0; | 85 | return 0; |
| 85 | 86 | ||
| 86 | if (state == BACO_STATE_IN) { | 87 | if (state == BACO_STATE_IN) { |
| 87 | data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL); | 88 | if (!ras || !ras->supported) { |
| 88 | data |= 0x80000000; | 89 | data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL); |
| 89 | WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data); | 90 | data |= 0x80000000; |
| 90 | 91 | WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data); | |
| 91 | 92 | ||
| 92 | if(smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_EnterBaco, 0)) | 93 | if(smum_send_msg_to_smc_with_parameter(hwmgr, |
| 93 | return -EINVAL; | 94 | PPSMC_MSG_EnterBaco, 0)) |
| 95 | return -EINVAL; | ||
| 96 | } else { | ||
| 97 | if(smum_send_msg_to_smc_with_parameter(hwmgr, | ||
| 98 | PPSMC_MSG_EnterBaco, 1)) | ||
| 99 | return -EINVAL; | ||
| 100 | } | ||
| 94 | 101 | ||
| 95 | } else if (state == BACO_STATE_OUT) { | 102 | } else if (state == BACO_STATE_OUT) { |
| 96 | if (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ExitBaco)) | 103 | if (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ExitBaco)) |
| @@ -182,6 +182,9 @@ static int vega20_set_features_platform_caps(struct pp_hwmgr *hwmgr) · 181 unmodified lines | |||
| 182 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | 182 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, |
| 183 | PHM_PlatformCaps_TablelessHardwareInterface); | 183 | PHM_PlatformCaps_TablelessHardwareInterface); |
| 184 | 184 | ||
| 185 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | ||
| 186 | PHM_PlatformCaps_BACO); | ||
| 187 | |||
| 185 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | 188 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, |
| 186 | PHM_PlatformCaps_EnableSMU7ThermalManagement); | 189 | PHM_PlatformCaps_EnableSMU7ThermalManagement); |
| 187 | 190 | ||
| @@ -490,8 +493,8 @@ static int vega20_setup_asic_task(struct pp_hwmgr *hwmgr) · 302 unmodified lines | |||
| 490 | "Failed to init sclk threshold!", | 493 | "Failed to init sclk threshold!", |
| 491 | return ret); | 494 | return ret); |
| 492 | 495 | ||
| 493 | if (adev->in_baco_reset) { | 496 | if (adev->in_gpu_reset && |
| 494 | adev->in_baco_reset = 0; | 497 | (amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)) { |
| 495 | 498 | ||
| 496 | ret = vega20_baco_apply_vdci_flush_workaround(hwmgr); | 499 | ret = vega20_baco_apply_vdci_flush_workaround(hwmgr); |
| 497 | if (ret) | 500 | if (ret) |
| @@ -4155,6 +4158,24 @@ static int vega20_smu_i2c_bus_access(struct pp_hwmgr *hwmgr, bool acquire) · 3657 unmodified lines | |||
| 4155 | return res; | 4158 | return res; |
| 4156 | } | 4159 | } |
| 4157 | 4160 | ||
| 4161 | static int vega20_set_df_cstate(struct pp_hwmgr *hwmgr, | ||
| 4162 | enum pp_df_cstate state) | ||
| 4163 | { | ||
| 4164 | int ret; | ||
| 4165 | |||
| 4166 | /* PPSMC_MSG_DFCstateControl is supported with 40.50 and later fws */ | ||
| 4167 | if (hwmgr->smu_version < 0x283200) { | ||
| 4168 | pr_err("Df cstate control is supported with 40.50 and later SMC fw!\n"); | ||
| 4169 | return -EINVAL; | ||
| 4170 | } | ||
| 4171 | |||
| 4172 | ret = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DFCstateControl, state); | ||
| 4173 | if (ret) | ||
| 4174 | pr_err("SetDfCstate failed!\n"); | ||
| 4175 | |||
| 4176 | return ret; | ||
| 4177 | } | ||
| 4178 | |||
| 4158 | static const struct pp_hwmgr_func vega20_hwmgr_funcs = { | 4179 | static const struct pp_hwmgr_func vega20_hwmgr_funcs = { |
| 4159 | /* init/fini related */ | 4180 | /* init/fini related */ |
| 4160 | .backend_init = vega20_hwmgr_backend_init, | 4181 | .backend_init = vega20_hwmgr_backend_init, |
| @@ -4223,6 +4244,7 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = { · 62 unmodified lines | |||
| 4223 | .set_asic_baco_state = vega20_baco_set_state, | 4244 | .set_asic_baco_state = vega20_baco_set_state, |
| 4224 | .set_mp1_state = vega20_set_mp1_state, | 4245 | .set_mp1_state = vega20_set_mp1_state, |
| 4225 | .smu_i2c_bus_access = vega20_smu_i2c_bus_access, | 4246 | .smu_i2c_bus_access = vega20_smu_i2c_bus_access, |
| 4247 | .set_df_cstate = vega20_set_df_cstate, | ||
| 4226 | }; | 4248 | }; |
| 4227 | 4249 | ||
| 4228 | int vega20_hwmgr_init(struct pp_hwmgr *hwmgr) | 4250 | int vega20_hwmgr_init(struct pp_hwmgr *hwmgr) |
| @@ -468,6 +468,9 @@ struct pptable_funcs { · 467 unmodified lines | |||
| 468 | int (*get_power_limit)(struct smu_context *smu, uint32_t *limit, bool asic_default); | 468 | int (*get_power_limit)(struct smu_context *smu, uint32_t *limit, bool asic_default); |
| 469 | int (*get_dpm_clk_limited)(struct smu_context *smu, enum smu_clk_type clk_type, | 469 | int (*get_dpm_clk_limited)(struct smu_context *smu, enum smu_clk_type clk_type, |
| 470 | uint32_t dpm_level, uint32_t *freq); | 470 | uint32_t dpm_level, uint32_t *freq); |
| 471 | int (*set_df_cstate)(struct smu_context *smu, enum pp_df_cstate state); | ||
| 472 | int (*update_pcie_parameters)(struct smu_context *smu, uint32_t pcie_gen_cap, uint32_t pcie_width_cap); | ||
| 473 | int (*get_dpm_clock_table)(struct smu_context *smu, struct dpm_clocks *clock_table); | ||
| 471 | }; | 474 | }; |
| 472 | 475 | ||
| 473 | struct smu_funcs | 476 | struct smu_funcs |
| @@ -493,7 +496,6 @@ struct smu_funcs · 19 unmodified lines | |||
| 493 | int (*set_min_dcef_deep_sleep)(struct smu_context *smu); | 496 | int (*set_min_dcef_deep_sleep)(struct smu_context *smu); |
| 494 | int (*set_tool_table_location)(struct smu_context *smu); | 497 | int (*set_tool_table_location)(struct smu_context *smu); |
| 495 | int (*notify_memory_pool_location)(struct smu_context *smu); | 498 | int (*notify_memory_pool_location)(struct smu_context *smu); |
| 496 | int (*write_watermarks_table)(struct smu_context *smu); | ||
| 497 | int (*set_last_dcef_min_deep_sleep_clk)(struct smu_context *smu); | 499 | int (*set_last_dcef_min_deep_sleep_clk)(struct smu_context *smu); |
| 498 | int (*system_features_control)(struct smu_context *smu, bool en); | 500 | int (*system_features_control)(struct smu_context *smu, bool en); |
| 499 | int (*send_smc_msg)(struct smu_context *smu, uint16_t msg); | 501 | int (*send_smc_msg)(struct smu_context *smu, uint16_t msg); |
| @@ -531,8 +533,6 @@ struct smu_funcs · 31 unmodified lines | |||
| 531 | int (*get_current_shallow_sleep_clocks)(struct smu_context *smu, | 533 | int (*get_current_shallow_sleep_clocks)(struct smu_context *smu, |
| 532 | struct smu_clock_info *clocks); | 534 | struct smu_clock_info *clocks); |
| 533 | int (*notify_smu_enable_pwe)(struct smu_context *smu); | 535 | int (*notify_smu_enable_pwe)(struct smu_context *smu); |
| 534 | int (*set_watermarks_for_clock_ranges)(struct smu_context *smu, | ||
| 535 | struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges); | ||
| 536 | int (*conv_power_profile_to_pplib_workload)(int power_profile); | 536 | int (*conv_power_profile_to_pplib_workload)(int power_profile); |
| 537 | uint32_t (*get_fan_control_mode)(struct smu_context *smu); | 537 | uint32_t (*get_fan_control_mode)(struct smu_context *smu); |
| 538 | int (*set_fan_control_mode)(struct smu_context *smu, uint32_t mode); | 538 | int (*set_fan_control_mode)(struct smu_context *smu, uint32_t mode); |
| @@ -550,6 +550,7 @@ struct smu_funcs · 11 unmodified lines | |||
| 550 | int (*mode2_reset)(struct smu_context *smu); | 550 | int (*mode2_reset)(struct smu_context *smu); |
| 551 | int (*get_dpm_ultimate_freq)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t *min, uint32_t *max); | 551 | int (*get_dpm_ultimate_freq)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t *min, uint32_t *max); |
| 552 | int (*set_soft_freq_limited_range)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t min, uint32_t max); | 552 | int (*set_soft_freq_limited_range)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t min, uint32_t max); |
| 553 | int (*override_pcie_parameters)(struct smu_context *smu); | ||
| 553 | }; | 554 | }; |
| 554 | 555 | ||
| 555 | #define smu_init_microcode(smu) \ | 556 | #define smu_init_microcode(smu) \ |
| @@ -596,9 +597,6 @@ struct smu_funcs · 40 unmodified lines | |||
| 596 | ((smu)->funcs->notify_memory_pool_location ? (smu)->funcs->notify_memory_pool_location((smu)) : 0) | 597 | ((smu)->funcs->notify_memory_pool_location ? (smu)->funcs->notify_memory_pool_location((smu)) : 0) |
| 597 | #define smu_gfx_off_control(smu, enable) \ | 598 | #define smu_gfx_off_control(smu, enable) \ |
| 598 | ((smu)->funcs->gfx_off_control ? (smu)->funcs->gfx_off_control((smu), (enable)) : 0) | 599 | ((smu)->funcs->gfx_off_control ? (smu)->funcs->gfx_off_control((smu), (enable)) : 0) |
| 599 | |||
| 600 | #define smu_write_watermarks_table(smu) \ | ||
| 601 | ((smu)->funcs->write_watermarks_table ? (smu)->funcs->write_watermarks_table((smu)) : 0) | ||
| 602 | #define smu_set_last_dcef_min_deep_sleep_clk(smu) \ | 600 | #define smu_set_last_dcef_min_deep_sleep_clk(smu) \ |
| 603 | ((smu)->funcs->set_last_dcef_min_deep_sleep_clk ? (smu)->funcs->set_last_dcef_min_deep_sleep_clk((smu)) : 0) | 601 | ((smu)->funcs->set_last_dcef_min_deep_sleep_clk ? (smu)->funcs->set_last_dcef_min_deep_sleep_clk((smu)) : 0) |
| 604 | #define smu_system_features_control(smu, en) \ | 602 | #define smu_system_features_control(smu, en) \ |
| @@ -738,8 +736,6 @@ struct smu_funcs · 133 unmodified lines | |||
| 738 | ((smu)->funcs->get_current_shallow_sleep_clocks ? (smu)->funcs->get_current_shallow_sleep_clocks((smu), (clocks)) : 0) | 736 | ((smu)->funcs->get_current_shallow_sleep_clocks ? (smu)->funcs->get_current_shallow_sleep_clocks((smu), (clocks)) : 0) |
| 739 | #define smu_notify_smu_enable_pwe(smu) \ | 737 | #define smu_notify_smu_enable_pwe(smu) \ |
| 740 | ((smu)->funcs->notify_smu_enable_pwe ? (smu)->funcs->notify_smu_enable_pwe((smu)) : 0) | 738 | ((smu)->funcs->notify_smu_enable_pwe ? (smu)->funcs->notify_smu_enable_pwe((smu)) : 0) |
| 741 | #define smu_set_watermarks_for_clock_ranges(smu, clock_ranges) \ | ||
| 742 | ((smu)->funcs->set_watermarks_for_clock_ranges ? (smu)->funcs->set_watermarks_for_clock_ranges((smu), (clock_ranges)) : 0) | ||
| 743 | #define smu_dpm_set_uvd_enable(smu, enable) \ | 739 | #define smu_dpm_set_uvd_enable(smu, enable) \ |
| 744 | ((smu)->ppt_funcs->dpm_set_uvd_enable ? (smu)->ppt_funcs->dpm_set_uvd_enable((smu), (enable)) : 0) | 740 | ((smu)->ppt_funcs->dpm_set_uvd_enable ? (smu)->ppt_funcs->dpm_set_uvd_enable((smu), (enable)) : 0) |
| 745 | #define smu_dpm_set_vce_enable(smu, enable) \ | 741 | #define smu_dpm_set_vce_enable(smu, enable) \ |
| @@ -776,9 +772,16 @@ struct smu_funcs · 30 unmodified lines | |||
| 776 | ((smu)->ppt_funcs->dump_pptable ? (smu)->ppt_funcs->dump_pptable((smu)) : 0) | 772 | ((smu)->ppt_funcs->dump_pptable ? (smu)->ppt_funcs->dump_pptable((smu)) : 0) |
| 777 | #define smu_get_dpm_clk_limited(smu, clk_type, dpm_level, freq) \ | 773 | #define smu_get_dpm_clk_limited(smu, clk_type, dpm_level, freq) \ |
| 778 | ((smu)->ppt_funcs->get_dpm_clk_limited ? (smu)->ppt_funcs->get_dpm_clk_limited((smu), (clk_type), (dpm_level), (freq)) : -EINVAL) | 774 | ((smu)->ppt_funcs->get_dpm_clk_limited ? (smu)->ppt_funcs->get_dpm_clk_limited((smu), (clk_type), (dpm_level), (freq)) : -EINVAL) |
| 779 | |||
| 780 | #define smu_set_soft_freq_limited_range(smu, clk_type, min, max) \ | 775 | #define smu_set_soft_freq_limited_range(smu, clk_type, min, max) \ |
| 781 | ((smu)->funcs->set_soft_freq_limited_range ? (smu)->funcs->set_soft_freq_limited_range((smu), (clk_type), (min), (max)) : -EINVAL) | 776 | ((smu)->funcs->set_soft_freq_limited_range ? (smu)->funcs->set_soft_freq_limited_range((smu), (clk_type), (min), (max)) : -EINVAL) |
| 777 | #define smu_get_dpm_clock_table(smu, clock_table) \ | ||
| 778 | ((smu)->ppt_funcs->get_dpm_clock_table ? (smu)->ppt_funcs->get_dpm_clock_table((smu), (clock_table)) : -EINVAL) | ||
| 779 | |||
| 780 | #define smu_override_pcie_parameters(smu) \ | ||
| 781 | ((smu)->funcs->override_pcie_parameters ? (smu)->funcs->override_pcie_parameters((smu)) : 0) | ||
| 782 | |||
| 783 | #define smu_update_pcie_parameters(smu, pcie_gen_cap, pcie_width_cap) \ | ||
| 784 | ((smu)->ppt_funcs->update_pcie_parameters ? (smu)->ppt_funcs->update_pcie_parameters((smu), (pcie_gen_cap), (pcie_width_cap)) : 0) | ||
| 782 | 785 | ||
| 783 | extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table, | 786 | extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table, |
| 784 | uint16_t *size, uint8_t *frev, uint8_t *crev, | 787 | uint16_t *size, uint8_t *frev, uint8_t *crev, |
| @@ -812,6 +815,10 @@ int smu_sys_get_pp_table(struct smu_context *smu, void **table); · 27 unmodified lines | |||
| 812 | int smu_sys_set_pp_table(struct smu_context *smu, void *buf, size_t size); | 815 | int smu_sys_set_pp_table(struct smu_context *smu, void *buf, size_t size); |
| 813 | int smu_get_power_num_states(struct smu_context *smu, struct pp_states_info *state_info); | 816 | int smu_get_power_num_states(struct smu_context *smu, struct pp_states_info *state_info); |
| 814 | enum amd_pm_state_type smu_get_current_power_state(struct smu_context *smu); | 817 | enum amd_pm_state_type smu_get_current_power_state(struct smu_context *smu); |
| 818 | int smu_write_watermarks_table(struct smu_context *smu); | ||
| 819 | int smu_set_watermarks_for_clock_ranges( | ||
| 820 | struct smu_context *smu, | ||
| 821 | struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges); | ||
| 815 | 822 | ||
| 816 | /* smu to display interface */ | 823 | /* smu to display interface */ |
| 817 | extern int smu_display_configuration_change(struct smu_context *smu, const | 824 | extern int smu_display_configuration_change(struct smu_context *smu, const |
| @@ -850,5 +857,7 @@ int smu_force_clk_levels(struct smu_context *smu, · 32 unmodified lines | |||
| 850 | uint32_t mask); | 857 | uint32_t mask); |
| 851 | int smu_set_mp1_state(struct smu_context *smu, | 858 | int smu_set_mp1_state(struct smu_context *smu, |
| 852 | enum pp_mp1_state mp1_state); | 859 | enum pp_mp1_state mp1_state); |
| 860 | int smu_set_df_cstate(struct smu_context *smu, | ||
| 861 | enum pp_df_cstate state); | ||
| 853 | 862 | ||
| 854 | #endif | 863 | #endif |
| @@ -355,6 +355,7 @@ struct pp_hwmgr_func { · 354 unmodified lines | |||
| 355 | int (*set_mp1_state)(struct pp_hwmgr *hwmgr, enum pp_mp1_state mp1_state); | 355 | int (*set_mp1_state)(struct pp_hwmgr *hwmgr, enum pp_mp1_state mp1_state); |
| 356 | int (*asic_reset)(struct pp_hwmgr *hwmgr, enum SMU_ASIC_RESET_MODE mode); | 356 | int (*asic_reset)(struct pp_hwmgr *hwmgr, enum SMU_ASIC_RESET_MODE mode); |
| 357 | int (*smu_i2c_bus_access)(struct pp_hwmgr *hwmgr, bool aquire); | 357 | int (*smu_i2c_bus_access)(struct pp_hwmgr *hwmgr, bool aquire); |
| 358 | int (*set_df_cstate)(struct pp_hwmgr *hwmgr, enum pp_df_cstate state); | ||
| 358 | }; | 359 | }; |
| 359 | 360 | ||
| 360 | struct pp_table_func { | 361 | struct pp_table_func { |
| @@ -169,6 +169,7 @@ · 168 unmodified lines | |||
| 169 | __SMU_DUMMY_MAP(PowerGateAtHub), \ | 169 | __SMU_DUMMY_MAP(PowerGateAtHub), \ |
| 170 | __SMU_DUMMY_MAP(SetSoftMinJpeg), \ | 170 | __SMU_DUMMY_MAP(SetSoftMinJpeg), \ |
| 171 | __SMU_DUMMY_MAP(SetHardMinFclkByFreq), \ | 171 | __SMU_DUMMY_MAP(SetHardMinFclkByFreq), \ |
| 172 | __SMU_DUMMY_MAP(DFCstateControl), \ | ||
| 172 | 173 | ||
| 173 | #undef __SMU_DUMMY_MAP | 174 | #undef __SMU_DUMMY_MAP |
| 174 | #define __SMU_DUMMY_MAP(type) SMU_MSG_##type | 175 | #define __SMU_DUMMY_MAP(type) SMU_MSG_##type |
| @@ -120,7 +120,8 @@ · 119 unmodified lines | |||
| 120 | #define PPSMC_MSG_SetMGpuFanBoostLimitRpm 0x5D | 120 | #define PPSMC_MSG_SetMGpuFanBoostLimitRpm 0x5D |
| 121 | #define PPSMC_MSG_GetAVFSVoltageByDpm 0x5F | 121 | #define PPSMC_MSG_GetAVFSVoltageByDpm 0x5F |
| 122 | #define PPSMC_MSG_BacoWorkAroundFlushVDCI 0x60 | 122 | #define PPSMC_MSG_BacoWorkAroundFlushVDCI 0x60 |
| 123 | #define PPSMC_Message_Count 0x61 | 123 | #define PPSMC_MSG_DFCstateControl 0x63 |
| 124 | #define PPSMC_Message_Count 0x64 | ||
| 124 | 125 | ||
| 125 | typedef uint32_t PPSMC_Result; | 126 | typedef uint32_t PPSMC_Result; |
| 126 | typedef uint32_t PPSMC_Msg; | 127 | typedef uint32_t PPSMC_Msg; |
| @@ -328,40 +328,52 @@ navi10_get_allowed_feature_mask(struct smu_context *smu, · 327 unmodified lines | |||
| 328 | memset(feature_mask, 0, sizeof(uint32_t) * num); | 328 | memset(feature_mask, 0, sizeof(uint32_t) * num); |
| 329 | 329 | ||
| 330 | *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_PREFETCHER_BIT) | 330 | *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_PREFETCHER_BIT) |
| 331 | | FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT) | ||
| 332 | | FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT) | ||
| 333 | | FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT) | 331 | | FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT) |
| 334 | | FEATURE_MASK(FEATURE_DPM_LINK_BIT) | ||
| 335 | | FEATURE_MASK(FEATURE_GFX_ULV_BIT) | ||
| 336 | | FEATURE_MASK(FEATURE_RSMU_SMN_CG_BIT) | 332 | | FEATURE_MASK(FEATURE_RSMU_SMN_CG_BIT) |
| 337 | | FEATURE_MASK(FEATURE_DS_SOCCLK_BIT) | 333 | | FEATURE_MASK(FEATURE_DS_SOCCLK_BIT) |
| 338 | | FEATURE_MASK(FEATURE_PPT_BIT) | 334 | | FEATURE_MASK(FEATURE_PPT_BIT) |
| 339 | | FEATURE_MASK(FEATURE_TDC_BIT) | 335 | | FEATURE_MASK(FEATURE_TDC_BIT) |
| 340 | | FEATURE_MASK(FEATURE_GFX_EDC_BIT) | 336 | | FEATURE_MASK(FEATURE_GFX_EDC_BIT) |
| 337 | | FEATURE_MASK(FEATURE_APCC_PLUS_BIT) | ||
| 341 | | FEATURE_MASK(FEATURE_VR0HOT_BIT) | 338 | | FEATURE_MASK(FEATURE_VR0HOT_BIT) |
| 342 | | FEATURE_MASK(FEATURE_FAN_CONTROL_BIT) | 339 | | FEATURE_MASK(FEATURE_FAN_CONTROL_BIT) |
| 343 | | FEATURE_MASK(FEATURE_THERMAL_BIT) | 340 | | FEATURE_MASK(FEATURE_THERMAL_BIT) |
| 344 | | FEATURE_MASK(FEATURE_LED_DISPLAY_BIT) | 341 | | FEATURE_MASK(FEATURE_LED_DISPLAY_BIT) |
| 345 | | FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT) | 342 | | FEATURE_MASK(FEATURE_DS_LCLK_BIT) |
| 346 | | FEATURE_MASK(FEATURE_DS_GFXCLK_BIT) | ||
| 347 | | FEATURE_MASK(FEATURE_DS_DCEFCLK_BIT) | 343 | | FEATURE_MASK(FEATURE_DS_DCEFCLK_BIT) |
| 348 | | FEATURE_MASK(FEATURE_FW_DSTATE_BIT) | 344 | | FEATURE_MASK(FEATURE_FW_DSTATE_BIT) |
| 349 | | FEATURE_MASK(FEATURE_BACO_BIT) | 345 | | FEATURE_MASK(FEATURE_BACO_BIT) |
| 350 | | FEATURE_MASK(FEATURE_ACDC_BIT) | 346 | | FEATURE_MASK(FEATURE_ACDC_BIT) |
| 351 | | FEATURE_MASK(FEATURE_GFX_SS_BIT) | 347 | | FEATURE_MASK(FEATURE_GFX_SS_BIT) |
| 352 | | FEATURE_MASK(FEATURE_APCC_DFLL_BIT) | 348 | | FEATURE_MASK(FEATURE_APCC_DFLL_BIT) |
| 353 | | FEATURE_MASK(FEATURE_FW_CTF_BIT); | 349 | | FEATURE_MASK(FEATURE_FW_CTF_BIT) |
| 350 | | FEATURE_MASK(FEATURE_OUT_OF_BAND_MONITOR_BIT); | ||
| 351 | |||
| 352 | if (adev->pm.pp_feature & PP_SOCCLK_DPM_MASK) | ||
| 353 | *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT); | ||
| 354 | |||
| 355 | if (adev->pm.pp_feature & PP_SCLK_DPM_MASK) | ||
| 356 | *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT); | ||
| 357 | |||
| 358 | if (adev->pm.pp_feature & PP_PCIE_DPM_MASK) | ||
| 359 | *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_LINK_BIT); | ||
| 360 | |||
| 361 | if (adev->pm.pp_feature & PP_DCEFCLK_DPM_MASK) | ||
| 362 | *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT); | ||
| 354 | 363 | ||
| 355 | if (adev->pm.pp_feature & PP_MCLK_DPM_MASK) | 364 | if (adev->pm.pp_feature & PP_MCLK_DPM_MASK) |
| 356 | *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_UCLK_BIT) | 365 | *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_UCLK_BIT) |
| 357 | | FEATURE_MASK(FEATURE_MEM_VDDCI_SCALING_BIT) | 366 | | FEATURE_MASK(FEATURE_MEM_VDDCI_SCALING_BIT) |
| 358 | | FEATURE_MASK(FEATURE_MEM_MVDD_SCALING_BIT); | 367 | | FEATURE_MASK(FEATURE_MEM_MVDD_SCALING_BIT); |
| 359 | 368 | ||
| 360 | if (adev->pm.pp_feature & PP_GFXOFF_MASK) { | 369 | if (adev->pm.pp_feature & PP_ULV_MASK) |
| 370 | *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFX_ULV_BIT); | ||
| 371 | |||
| 372 | if (adev->pm.pp_feature & PP_SCLK_DEEP_SLEEP_MASK) | ||
| 373 | *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DS_GFXCLK_BIT); | ||
| 374 | |||
| 375 | if (adev->pm.pp_feature & PP_GFXOFF_MASK) | ||
| 361 | *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFXOFF_BIT); | 376 | *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFXOFF_BIT); |
| 362 | /* TODO: remove it once fw fix the bug */ | ||
| 363 | *(uint64_t *)feature_mask &= ~FEATURE_MASK(FEATURE_FW_DSTATE_BIT); | ||
| 364 | } | ||
| 365 | 377 | ||
| 366 | if (smu->adev->pg_flags & AMD_PG_SUPPORT_MMHUB) | 378 | if (smu->adev->pg_flags & AMD_PG_SUPPORT_MMHUB) |
| 367 | *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_MMHUB_PG_BIT); | 379 | *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_MMHUB_PG_BIT); |
| @@ -1452,18 +1464,47 @@ static int navi10_set_peak_clock_by_device(struct smu_context *smu) · 1084 unmodified lines | |||
| 1452 | uint32_t sclk_freq = 0, uclk_freq = 0; | 1464 | uint32_t sclk_freq = 0, uclk_freq = 0; |
| 1453 | uint32_t uclk_level = 0; | 1465 | uint32_t uclk_level = 0; |
| 1454 | 1466 | ||
| 1455 | switch (adev->pdev->revision) { | 1467 | switch (adev->asic_type) { |
| 1456 | case 0xf0: /* XTX */ | 1468 | case CHIP_NAVI10: |
| 1457 | case 0xc0: | 1469 | switch (adev->pdev->revision) { |
| 1458 | sclk_freq = NAVI10_PEAK_SCLK_XTX; | 1470 | case 0xf0: /* XTX */ |
| 1459 | break; | 1471 | case 0xc0: |
| 1460 | case 0xf1: /* XT */ | 1472 | sclk_freq = NAVI10_PEAK_SCLK_XTX; |
| 1461 | case 0xc1: | 1473 | break; |
| 1462 | sclk_freq = NAVI10_PEAK_SCLK_XT; | 1474 | case 0xf1: /* XT */ |
| 1475 | case 0xc1: | ||
| 1476 | sclk_freq = NAVI10_PEAK_SCLK_XT; | ||
| 1477 | break; | ||
| 1478 | default: /* XL */ | ||
| 1479 | sclk_freq = NAVI10_PEAK_SCLK_XL; | ||
| 1480 | break; | ||
| 1481 | } | ||
| 1463 | break; | 1482 | break; |
| 1464 | default: /* XL */ | 1483 | case CHIP_NAVI14: |
| 1465 | sclk_freq = NAVI10_PEAK_SCLK_XL; | 1484 | switch (adev->pdev->revision) { |
| 1485 | case 0xc7: /* XT */ | ||
| 1486 | case 0xf4: | ||
| 1487 | sclk_freq = NAVI14_UMD_PSTATE_PEAK_XT_GFXCLK; | ||
| 1488 | break; | ||
| 1489 | case 0xc1: /* XTM */ | ||
| 1490 | case 0xf2: | ||
| 1491 | sclk_freq = NAVI14_UMD_PSTATE_PEAK_XTM_GFXCLK; | ||
| 1492 | break; | ||
| 1493 | case 0xc3: /* XLM */ | ||
| 1494 | case 0xf3: | ||
| 1495 | sclk_freq = NAVI14_UMD_PSTATE_PEAK_XLM_GFXCLK; | ||
| 1496 | break; | ||
| 1497 | case 0xc5: /* XTX */ | ||
| 1498 | case 0xf6: | ||
| 1499 | sclk_freq = NAVI14_UMD_PSTATE_PEAK_XLM_GFXCLK; | ||
| 1500 | break; | ||
| 1501 | default: /* XL */ | ||
| 1502 | sclk_freq = NAVI14_UMD_PSTATE_PEAK_XL_GFXCLK; | ||
| 1503 | break; | ||
| 1504 | } | ||
| 1466 | break; | 1505 | break; |
| 1506 | default: | ||
| 1507 | return -EINVAL; | ||
| 1467 | } | 1508 | } |
| 1468 | 1509 | ||
| 1469 | ret = smu_get_dpm_level_count(smu, SMU_UCLK, &uclk_level); | 1510 | ret = smu_get_dpm_level_count(smu, SMU_UCLK, &uclk_level); |
| @@ -1486,10 +1527,6 @@ static int navi10_set_peak_clock_by_device(struct smu_context *smu) · 16 unmodified lines | |||
| 1486 | static int navi10_set_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level) | 1527 | static int navi10_set_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level) |
| 1487 | { | 1528 | { |
| 1488 | int ret = 0; | 1529 | int ret = 0; |
| 1489 | struct amdgpu_device *adev = smu->adev; | ||
| 1490 | |||
| 1491 | if (adev->asic_type != CHIP_NAVI10) | ||
| 1492 | return -EINVAL; | ||
| 1493 | 1530 | ||
| 1494 | switch (level) { | 1531 | switch (level) { |
| 1495 | case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: | 1532 | case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: |
| @@ -1592,6 +1629,28 @@ static int navi10_get_power_limit(struct smu_context *smu, · 96 unmodified lines | |||
| 1592 | return 0; | 1629 | return 0; |
| 1593 | } | 1630 | } |
| 1594 | 1631 | ||
| 1632 | static int navi10_update_pcie_parameters(struct smu_context *smu, | ||
| 1633 | uint32_t pcie_gen_cap, | ||
| 1634 | uint32_t pcie_width_cap) | ||
| 1635 | { | ||
| 1636 | PPTable_t *pptable = smu->smu_table.driver_pptable; | ||
| 1637 | int ret, i; | ||
| 1638 | uint32_t smu_pcie_arg; | ||
| 1639 | |||
| 1640 | for (i = 0; i < NUM_LINK_LEVELS; i++) { | ||
| 1641 | smu_pcie_arg = (i << 16) | | ||
| 1642 | ((pptable->PcieGenSpeed[i] <= pcie_gen_cap) ? (pptable->PcieGenSpeed[i] << 8) : | ||
| 1643 | (pcie_gen_cap << 8)) | ((pptable->PcieLaneCount[i] <= pcie_width_cap) ? | ||
| 1644 | pptable->PcieLaneCount[i] : pcie_width_cap); | ||
| 1645 | ret = smu_send_smc_msg_with_param(smu, | ||
| 1646 | SMU_MSG_OverridePcieParameters, | ||
| 1647 | smu_pcie_arg); | ||
| 1648 | } | ||
| 1649 | |||
| 1650 | return ret; | ||
| 1651 | } | ||
| 1652 | |||
| 1653 | |||
| 1595 | static const struct pptable_funcs navi10_ppt_funcs = { | 1654 | static const struct pptable_funcs navi10_ppt_funcs = { |
| 1596 | .tables_init = navi10_tables_init, | 1655 | .tables_init = navi10_tables_init, |
| 1597 | .alloc_dpm_context = navi10_allocate_dpm_context, | 1656 | .alloc_dpm_context = navi10_allocate_dpm_context, |
| @@ -1630,6 +1689,7 @@ static const struct pptable_funcs navi10_ppt_funcs = { · 32 unmodified lines | |||
| 1630 | .get_thermal_temperature_range = navi10_get_thermal_temperature_range, | 1689 | .get_thermal_temperature_range = navi10_get_thermal_temperature_range, |
| 1631 | .display_disable_memory_clock_switch = navi10_display_disable_memory_clock_switch, | 1690 | .display_disable_memory_clock_switch = navi10_display_disable_memory_clock_switch, |
| 1632 | .get_power_limit = navi10_get_power_limit, | 1691 | .get_power_limit = navi10_get_power_limit, |
| 1692 | .update_pcie_parameters = navi10_update_pcie_parameters, | ||
| 1633 | }; | 1693 | }; |
| 1634 | 1694 | ||
| 1635 | void navi10_set_ppt_funcs(struct smu_context *smu) | 1695 | void navi10_set_ppt_funcs(struct smu_context *smu) |
| @@ -27,6 +27,12 @@ · 26 unmodified lines | |||
| 27 | #define NAVI10_PEAK_SCLK_XT (1755) | 27 | #define NAVI10_PEAK_SCLK_XT (1755) |
| 28 | #define NAVI10_PEAK_SCLK_XL (1625) | 28 | #define NAVI10_PEAK_SCLK_XL (1625) |
| 29 | 29 | ||
| 30 | #define NAVI14_UMD_PSTATE_PEAK_XT_GFXCLK (1670) | ||
| 31 | #define NAVI14_UMD_PSTATE_PEAK_XTM_GFXCLK (1448) | ||
| 32 | #define NAVI14_UMD_PSTATE_PEAK_XLM_GFXCLK (1181) | ||
| 33 | #define NAVI14_UMD_PSTATE_PEAK_XTX_GFXCLK (1717) | ||
| 34 | #define NAVI14_UMD_PSTATE_PEAK_XL_GFXCLK (1448) | ||
| 35 | |||
| 30 | extern void navi10_set_ppt_funcs(struct smu_context *smu); | 36 | extern void navi10_set_ppt_funcs(struct smu_context *smu); |
| 31 | 37 | ||
| 32 | #endif | 38 | #endif |
| @@ -416,6 +416,40 @@ static int renoir_get_profiling_clk_mask(struct smu_context *smu, · 415 unmodified lines | |||
| 416 | return 0; | 416 | return 0; |
| 417 | } | 417 | } |
| 418 | 418 | ||
| 419 | /** | ||
| 420 | * This interface get dpm clock table for dc | ||
| 421 | */ | ||
| 422 | static int renoir_get_dpm_clock_table(struct smu_context *smu, struct dpm_clocks *clock_table) | ||
| 423 | { | ||
| 424 | DpmClocks_t *table = smu->smu_table.clocks_table; | ||
| 425 | int i; | ||
| 426 | |||
| 427 | if (!clock_table || !table) | ||
| 428 | return -EINVAL; | ||
| 429 | |||
| 430 | for (i = 0; i < NUM_DCFCLK_DPM_LEVELS; i++) { | ||
| 431 | clock_table->DcfClocks[i].Freq = table->DcfClocks[i].Freq; | ||
| 432 | clock_table->DcfClocks[i].Vol = table->DcfClocks[i].Vol; | ||
| 433 | } | ||
| 434 | |||
| 435 | for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++) { | ||
| 436 | clock_table->SocClocks[i].Freq = table->SocClocks[i].Freq; | ||
| 437 | clock_table->SocClocks[i].Vol = table->SocClocks[i].Vol; | ||
| 438 | } | ||
| 439 | |||
| 440 | for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++) { | ||
| 441 | clock_table->FClocks[i].Freq = table->FClocks[i].Freq; | ||
| 442 | clock_table->FClocks[i].Vol = table->FClocks[i].Vol; | ||
| 443 | } | ||
| 444 | |||
| 445 | for (i = 0; i< NUM_MEMCLK_DPM_LEVELS; i++) { | ||
| 446 | clock_table->MemClocks[i].Freq = table->MemClocks[i].Freq; | ||
| 447 | clock_table->MemClocks[i].Vol = table->MemClocks[i].Vol; | ||
| 448 | } | ||
| 449 | |||
| 450 | return 0; | ||
| 451 | } | ||
| 452 | |||
| 419 | static int renoir_force_clk_levels(struct smu_context *smu, | 453 | static int renoir_force_clk_levels(struct smu_context *smu, |
| 420 | enum smu_clk_type clk_type, uint32_t mask) | 454 | enum smu_clk_type clk_type, uint32_t mask) |
| 421 | { | 455 | { |
| @@ -546,6 +580,99 @@ static int renoir_set_performance_level(struct smu_context *smu, enum amd_dpm_fo · 124 unmodified lines | |||
| 546 | return ret; | 580 | return ret; |
| 547 | } | 581 | } |
| 548 | 582 | ||
| 583 | /* save watermark settings into pplib smu structure, | ||
| 584 | * also pass data to smu controller | ||
| 585 | */ | ||
| 586 | static int renoir_set_watermarks_table( | ||
| 587 | struct smu_context *smu, | ||
| 588 | void *watermarks, | ||
| 589 | struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges) | ||
| 590 | { | ||
| 591 | int i; | ||
| 592 | int ret = 0; | ||
| 593 | Watermarks_t *table = watermarks; | ||
| 594 | |||
| 595 | if (!table || !clock_ranges) | ||
| 596 | return -EINVAL; | ||
| 597 | |||
| 598 | if (clock_ranges->num_wm_dmif_sets > 4 || | ||
| 599 | clock_ranges->num_wm_mcif_sets > 4) | ||
| 600 | return -EINVAL; | ||
| 601 | |||
| 602 | /* save into smu->smu_table.tables[SMU_TABLE_WATERMARKS]->cpu_addr*/ | ||
| 603 | for (i = 0; i < clock_ranges->num_wm_dmif_sets; i++) { | ||
| 604 | table->WatermarkRow[WM_DCFCLK][i].MinClock = | ||
| 605 | cpu_to_le16((uint16_t) | ||
| 606 | (clock_ranges->wm_dmif_clocks_ranges[i].wm_min_dcfclk_clk_in_khz)); | ||
| 607 | table->WatermarkRow[WM_DCFCLK][i].MaxClock = | ||
| 608 | cpu_to_le16((uint16_t) | ||
| 609 | (clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz)); | ||
| 610 | table->WatermarkRow[WM_DCFCLK][i].MinMclk = | ||
| 611 | cpu_to_le16((uint16_t) | ||
| 612 | (clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz)); | ||
| 613 | table->WatermarkRow[WM_DCFCLK][i].MaxMclk = | ||
| 614 | cpu_to_le16((uint16_t) | ||
| 615 | (clock_ranges->wm_dmif_clocks_ranges[i].wm_max_mem_clk_in_khz)); | ||
| 616 | table->WatermarkRow[WM_DCFCLK][i].WmSetting = (uint8_t) | ||
| 617 | clock_ranges->wm_dmif_clocks_ranges[i].wm_set_id; | ||
| 618 | } | ||
| 619 | |||
| 620 | for (i = 0; i < clock_ranges->num_wm_mcif_sets; i++) { | ||
| 621 | table->WatermarkRow[WM_SOCCLK][i].MinClock = | ||
| 622 | cpu_to_le16((uint16_t) | ||
| 623 | (clock_ranges->wm_mcif_clocks_ranges[i].wm_min_socclk_clk_in_khz)); | ||
| 624 | table->WatermarkRow[WM_SOCCLK][i].MaxClock = | ||
| 625 | cpu_to_le16((uint16_t) | ||
| 626 | (clock_ranges->wm_mcif_clocks_ranges[i].wm_max_socclk_clk_in_khz)); | ||
| 627 | table->WatermarkRow[WM_SOCCLK][i].MinMclk = | ||
| 628 | cpu_to_le16((uint16_t) | ||
| 629 | (clock_ranges->wm_mcif_clocks_ranges[i].wm_min_mem_clk_in_khz)); | ||
| 630 | table->WatermarkRow[WM_SOCCLK][i].MaxMclk = | ||
| 631 | cpu_to_le16((uint16_t) | ||
| 632 | (clock_ranges->wm_mcif_clocks_ranges[i].wm_max_mem_clk_in_khz)); | ||
| 633 | table->WatermarkRow[WM_SOCCLK][i].WmSetting = (uint8_t) | ||
| 634 | clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id; | ||
| 635 | } | ||
| 636 | |||
| 637 | /* pass data to smu controller */ | ||
| 638 | ret = smu_write_watermarks_table(smu); | ||
| 639 | |||
| 640 | return ret; | ||
| 641 | } | ||
| 642 | |||
| 643 | static int renoir_get_power_profile_mode(struct smu_context *smu, | ||
| 644 | char *buf) | ||
| 645 | { | ||
| 646 | static const char *profile_name[] = { | ||
| 647 | "BOOTUP_DEFAULT", | ||
| 648 | "3D_FULL_SCREEN", | ||
| 649 | "POWER_SAVING", | ||
| 650 | "VIDEO", | ||
| 651 | "VR", | ||
| 652 | "COMPUTE", | ||
| 653 | "CUSTOM"}; | ||
| 654 | uint32_t i, size = 0; | ||
| 655 | int16_t workload_type = 0; | ||
| 656 | |||
| 657 | if (!smu->pm_enabled || !buf) | ||
| 658 | return -EINVAL; | ||
| 659 | |||
| 660 | for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) { | ||
| 661 | /* | ||
| 662 | * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT | ||
| 663 | * Not all profile modes are supported on arcturus. | ||
| 664 | */ | ||
| 665 | workload_type = smu_workload_get_type(smu, i); | ||
| 666 | if (workload_type < 0) | ||
| 667 | continue; | ||
| 668 | |||
| 669 | size += sprintf(buf + size, "%2d %14s%s\n", | ||
| 670 | i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " "); | ||
| 671 | } | ||
| 672 | |||
| 673 | return size; | ||
| 674 | } | ||
| 675 | |||
| 549 | static const struct pptable_funcs renoir_ppt_funcs = { | 676 | static const struct pptable_funcs renoir_ppt_funcs = { |
| 550 | .get_smu_msg_index = renoir_get_smu_msg_index, | 677 | .get_smu_msg_index = renoir_get_smu_msg_index, |
| 551 | .get_smu_table_index = renoir_get_smu_table_index, | 678 | .get_smu_table_index = renoir_get_smu_table_index, |
| @@ -562,6 +689,9 @@ static const struct pptable_funcs renoir_ppt_funcs = { · 10 unmodified lines | |||
| 562 | .force_clk_levels = renoir_force_clk_levels, | 689 | .force_clk_levels = renoir_force_clk_levels, |
| 563 | .set_power_profile_mode = renoir_set_power_profile_mode, | 690 | .set_power_profile_mode = renoir_set_power_profile_mode, |
| 564 | .set_performance_level = renoir_set_performance_level, | 691 | .set_performance_level = renoir_set_performance_level, |
| 692 | .get_dpm_clock_table = renoir_get_dpm_clock_table, | ||
| 693 | .set_watermarks_table = renoir_set_watermarks_table, | ||
| 694 | .get_power_profile_mode = renoir_get_power_profile_mode, | ||
| 565 | }; | 695 | }; |
| 566 | 696 | ||
| 567 | void renoir_set_ppt_funcs(struct smu_context *smu) | 697 | void renoir_set_ppt_funcs(struct smu_context *smu) |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | |||
| 35 | #include "vega20_ppt.h" | 35 | #include "vega20_ppt.h" |
| 36 | #include "arcturus_ppt.h" | 36 | #include "arcturus_ppt.h" |
| 37 | #include "navi10_ppt.h" | 37 | #include "navi10_ppt.h" |
| 38 | #include "amd_pcie.h" | ||
| 38 | 39 | ||
| 39 | #include "asic_reg/thm/thm_11_0_2_offset.h" | 40 | #include "asic_reg/thm/thm_11_0_2_offset.h" |
| 40 | #include "asic_reg/thm/thm_11_0_2_sh_mask.h" | 41 | #include "asic_reg/thm/thm_11_0_2_sh_mask.h" |
| @@ -770,23 +771,6 @@ static int smu_v11_0_write_pptable(struct smu_context *smu) · 729 unmodified lines | |||
| 770 | return ret; | 771 | return ret; |
| 771 | } | 772 | } |
| 772 | 773 | ||
| 773 | static int smu_v11_0_write_watermarks_table(struct smu_context *smu) | ||
| 774 | { | ||
| 775 | int ret = 0; | ||
| 776 | struct smu_table_context *smu_table = &smu->smu_table; | ||
| 777 | struct smu_table *table = NULL; | ||
| 778 | |||
| 779 | table = &smu_table->tables[SMU_TABLE_WATERMARKS]; | ||
| 780 | |||
| 781 | if (!table->cpu_addr) | ||
| 782 | return -EINVAL; | ||
| 783 | |||
| 784 | ret = smu_update_table(smu, SMU_TABLE_WATERMARKS, 0, table->cpu_addr, | ||
| 785 | true); | ||
| 786 | |||
| 787 | return ret; | ||
| 788 | } | ||
| 789 | |||
| 790 | static int smu_v11_0_set_deep_sleep_dcefclk(struct smu_context *smu, uint32_t clk) | 774 | static int smu_v11_0_set_deep_sleep_dcefclk(struct smu_context *smu, uint32_t clk) |
| 791 | { | 775 | { |
| 792 | int ret; | 776 | int ret; |
| @@ -1336,26 +1320,6 @@ failed: · 543 unmodified lines | |||
| 1336 | return ret; | 1320 | return ret; |
| 1337 | } | 1321 | } |
| 1338 | 1322 | ||
| 1339 | static int | ||
| 1340 | smu_v11_0_set_watermarks_for_clock_ranges(struct smu_context *smu, struct | ||
| 1341 | dm_pp_wm_sets_with_clock_ranges_soc15 | ||
| 1342 | *clock_ranges) | ||
| 1343 | { | ||
| 1344 | int ret = 0; | ||
| 1345 | struct smu_table *watermarks = &smu->smu_table.tables[SMU_TABLE_WATERMARKS]; | ||
| 1346 | void *table = watermarks->cpu_addr; | ||
| 1347 | |||
| 1348 | if (!smu->disable_watermark && | ||
| 1349 | smu_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) && | ||
| 1350 | smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) { | ||
| 1351 | smu_set_watermarks_table(smu, table, clock_ranges); | ||
| 1352 | smu->watermarks_bitmap |= WATERMARKS_EXIST; | ||
| 1353 | smu->watermarks_bitmap &= ~WATERMARKS_LOADED; | ||
| 1354 | } | ||
| 1355 | |||
| 1356 | return ret; | ||
| 1357 | } | ||
| 1358 | |||
| 1359 | static int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable) | 1323 | static int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable) |
| 1360 | { | 1324 | { |
| 1361 | int ret = 0; | 1325 | int ret = 0; |
| @@ -1792,6 +1756,48 @@ static int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu, enum s · 430 unmodified lines | |||
| 1792 | return ret; | 1756 | return ret; |
| 1793 | } | 1757 | } |
| 1794 | 1758 | ||
| 1759 | static int smu_v11_0_override_pcie_parameters(struct smu_context *smu) | ||
| 1760 | { | ||
| 1761 | struct amdgpu_device *adev = smu->adev; | ||
| 1762 | uint32_t pcie_gen = 0, pcie_width = 0; | ||
| 1763 | int ret; | ||
| 1764 | |||
| 1765 | if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) | ||
| 1766 | pcie_gen = 3; | ||
| 1767 | else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) | ||
| 1768 | pcie_gen = 2; | ||
| 1769 | else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) | ||
| 1770 | pcie_gen = 1; | ||
| 1771 | else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1) | ||
| 1772 | pcie_gen = 0; | ||
| 1773 | |||
| 1774 | /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1 | ||
| 1775 | * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 | ||
| 1776 | * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 | ||
| 1777 | */ | ||
| 1778 | if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) | ||
| 1779 | pcie_width = 6; | ||
| 1780 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) | ||
| 1781 | pcie_width = 5; | ||
| 1782 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) | ||
| 1783 | pcie_width = 4; | ||
| 1784 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) | ||
| 1785 | pcie_width = 3; | ||
| 1786 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) | ||
| 1787 | pcie_width = 2; | ||
| 1788 | else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) | ||
| 1789 | pcie_width = 1; | ||
| 1790 | |||
| 1791 | ret = smu_update_pcie_parameters(smu, pcie_gen, pcie_width); | ||
| 1792 | |||
| 1793 | if (ret) | ||
| 1794 | pr_err("[%s] Attempt to override pcie params failed!\n", __func__); | ||
| 1795 | |||
| 1796 | return ret; | ||
| 1797 | |||
| 1798 | } | ||
| 1799 | |||
| 1800 | |||
| 1795 | static const struct smu_funcs smu_v11_0_funcs = { | 1801 | static const struct smu_funcs smu_v11_0_funcs = { |
| 1796 | .init_microcode = smu_v11_0_init_microcode, | 1802 | .init_microcode = smu_v11_0_init_microcode, |
| 1797 | .load_microcode = smu_v11_0_load_microcode, | 1803 | .load_microcode = smu_v11_0_load_microcode, |
| @@ -1812,7 +1818,6 @@ static const struct smu_funcs smu_v11_0_funcs = { · 14 unmodified lines | |||
| 1812 | .parse_pptable = smu_v11_0_parse_pptable, | 1818 | .parse_pptable = smu_v11_0_parse_pptable, |
| 1813 | .populate_smc_tables = smu_v11_0_populate_smc_pptable, | 1819 | .populate_smc_tables = smu_v11_0_populate_smc_pptable, |
| 1814 | .write_pptable = smu_v11_0_write_pptable, | 1820 | .write_pptable = smu_v11_0_write_pptable, |
| 1815 | .write_watermarks_table = smu_v11_0_write_watermarks_table, | ||
| 1816 | .set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep, | 1821 | .set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep, |
| 1817 | .set_tool_table_location = smu_v11_0_set_tool_table_location, | 1822 | .set_tool_table_location = smu_v11_0_set_tool_table_location, |
| 1818 | .init_display_count = smu_v11_0_init_display_count, | 1823 | .init_display_count = smu_v11_0_init_display_count, |
| @@ -1828,7 +1833,6 @@ static const struct smu_funcs smu_v11_0_funcs = { · 9 unmodified lines | |||
| 1828 | .read_sensor = smu_v11_0_read_sensor, | 1833 | .read_sensor = smu_v11_0_read_sensor, |
| 1829 | .set_deep_sleep_dcefclk = smu_v11_0_set_deep_sleep_dcefclk, | 1834 | .set_deep_sleep_dcefclk = smu_v11_0_set_deep_sleep_dcefclk, |
| 1830 | .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request, | 1835 | .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request, |
| 1831 | .set_watermarks_for_clock_ranges = smu_v11_0_set_watermarks_for_clock_ranges, | ||
| 1832 | .get_fan_control_mode = smu_v11_0_get_fan_control_mode, | 1836 | .get_fan_control_mode = smu_v11_0_get_fan_control_mode, |
| 1833 | .set_fan_control_mode = smu_v11_0_set_fan_control_mode, | 1837 | .set_fan_control_mode = smu_v11_0_set_fan_control_mode, |
| 1834 | .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent, | 1838 | .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent, |
| @@ -1844,6 +1848,7 @@ static const struct smu_funcs smu_v11_0_funcs = { · 9 unmodified lines | |||
| 1844 | .baco_reset = smu_v11_0_baco_reset, | 1848 | .baco_reset = smu_v11_0_baco_reset, |
| 1845 | .get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq, | 1849 | .get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq, |
| 1846 | .set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range, | 1850 | .set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range, |
| 1851 | .override_pcie_parameters = smu_v11_0_override_pcie_parameters, | ||
| 1847 | }; | 1852 | }; |
| 1848 | 1853 | ||
| 1849 | void smu_v11_0_set_smu_funcs(struct smu_context *smu) | 1854 | void smu_v11_0_set_smu_funcs(struct smu_context *smu) |
| @@ -244,15 +244,6 @@ static int smu_v12_0_gfx_off_control(struct smu_context *smu, bool enable) · 243 unmodified lines | |||
| 244 | if (enable) { | 244 | if (enable) { |
| 245 | ret = smu_send_smc_msg(smu, SMU_MSG_AllowGfxOff); | 245 | ret = smu_send_smc_msg(smu, SMU_MSG_AllowGfxOff); |
| 246 | 246 | ||
| 247 | /* confirm gfx is back to "off" state, timeout is 5 seconds */ | ||
| 248 | while (!(smu_v12_0_get_gfxoff_status(smu) == 0)) { | ||
| 249 | msleep(10); | ||
| 250 | timeout--; | ||
| 251 | if (timeout == 0) { | ||
| 252 | DRM_ERROR("enable gfxoff timeout and failed!\n"); | ||
| 253 | break; | ||
| 254 | } | ||
| 255 | } | ||
| 256 | } else { | 247 | } else { |
| 257 | ret = smu_send_smc_msg(smu, SMU_MSG_DisallowGfxOff); | 248 | ret = smu_send_smc_msg(smu, SMU_MSG_DisallowGfxOff); |
| 258 | 249 | ||
| @@ -143,6 +143,7 @@ static struct smu_11_0_cmn2aisc_mapping vega20_message_map[SMU_MSG_MAX_COUNT] = · 142 unmodified lines | |||
| 143 | MSG_MAP(PrepareMp1ForShutdown), | 143 | MSG_MAP(PrepareMp1ForShutdown), |
| 144 | MSG_MAP(SetMGpuFanBoostLimitRpm), | 144 | MSG_MAP(SetMGpuFanBoostLimitRpm), |
| 145 | MSG_MAP(GetAVFSVoltageByDpm), | 145 | MSG_MAP(GetAVFSVoltageByDpm), |
| 146 | MSG_MAP(DFCstateControl), | ||
| 146 | }; | 147 | }; |
| 147 | 148 | ||
| 148 | static struct smu_11_0_cmn2aisc_mapping vega20_clk_map[SMU_CLK_COUNT] = { | 149 | static struct smu_11_0_cmn2aisc_mapping vega20_clk_map[SMU_CLK_COUNT] = { |
| @@ -3135,6 +3136,49 @@ static int vega20_get_thermal_temperature_range(struct smu_context *smu, · 2986 unmodified lines | |||
| 3135 | return 0; | 3136 | return 0; |
| 3136 | } | 3137 | } |
| 3137 | 3138 | ||
| 3139 | static int vega20_set_df_cstate(struct smu_context *smu, | ||
| 3140 | enum pp_df_cstate state) | ||
| 3141 | { | ||
| 3142 | uint32_t smu_version; | ||
| 3143 | int ret; | ||
| 3144 | |||
| 3145 | ret = smu_get_smc_version(smu, NULL, &smu_version); | ||
| 3146 | if (ret) { | ||
| 3147 | pr_err("Failed to get smu version!\n"); | ||
| 3148 | return ret; | ||
| 3149 | } | ||
| 3150 | |||
| 3151 | /* PPSMC_MSG_DFCstateControl is supported with 40.50 and later fws */ | ||
| 3152 | if (smu_version < 0x283200) { | ||
| 3153 | pr_err("Df cstate control is supported with 40.50 and later SMC fw!\n"); | ||
| 3154 | return -EINVAL; | ||
| 3155 | } | ||
| 3156 | |||
| 3157 | return smu_send_smc_msg_with_param(smu, SMU_MSG_DFCstateControl, state); | ||
| 3158 | } | ||
| 3159 | |||
| 3160 | static int vega20_update_pcie_parameters(struct smu_context *smu, | ||
| 3161 | uint32_t pcie_gen_cap, | ||
| 3162 | uint32_t pcie_width_cap) | ||
| 3163 | { | ||
| 3164 | PPTable_t *pptable = smu->smu_table.driver_pptable; | ||
| 3165 | int ret, i; | ||
| 3166 | uint32_t smu_pcie_arg; | ||
| 3167 | |||
| 3168 | for (i = 0; i < NUM_LINK_LEVELS; i++) { | ||
| 3169 | smu_pcie_arg = (i << 16) | | ||
| 3170 | ((pptable->PcieGenSpeed[i] <= pcie_gen_cap) ? (pptable->PcieGenSpeed[i] << 8) : | ||
| 3171 | (pcie_gen_cap << 8)) | ((pptable->PcieLaneCount[i] <= pcie_width_cap) ? | ||
| 3172 | pptable->PcieLaneCount[i] : pcie_width_cap); | ||
| 3173 | ret = smu_send_smc_msg_with_param(smu, | ||
| 3174 | SMU_MSG_OverridePcieParameters, | ||
| 3175 | smu_pcie_arg); | ||
| 3176 | } | ||
| 3177 | |||
| 3178 | return ret; | ||
| 3179 | } | ||
| 3180 | |||
| 3181 | |||
| 3138 | static const struct pptable_funcs vega20_ppt_funcs = { | 3182 | static const struct pptable_funcs vega20_ppt_funcs = { |
| 3139 | .tables_init = vega20_tables_init, | 3183 | .tables_init = vega20_tables_init, |
| 3140 | .alloc_dpm_context = vega20_allocate_dpm_context, | 3184 | .alloc_dpm_context = vega20_allocate_dpm_context, |
| @@ -3177,7 +3221,9 @@ static const struct pptable_funcs vega20_ppt_funcs = { · 36 unmodified lines | |||
| 3177 | .get_fan_speed_percent = vega20_get_fan_speed_percent, | 3221 | .get_fan_speed_percent = vega20_get_fan_speed_percent, |
| 3178 | .get_fan_speed_rpm = vega20_get_fan_speed_rpm, | 3222 | .get_fan_speed_rpm = vega20_get_fan_speed_rpm, |
| 3179 | .set_watermarks_table = vega20_set_watermarks_table, | 3223 | .set_watermarks_table = vega20_set_watermarks_table, |
| 3180 | .get_thermal_temperature_range = vega20_get_thermal_temperature_range | 3224 | .get_thermal_temperature_range = vega20_get_thermal_temperature_range, |
| 3225 | .set_df_cstate = vega20_set_df_cstate, | ||
| 3226 | .update_pcie_parameters = vega20_update_pcie_parameters | ||
| 3181 | }; | 3227 | }; |
| 3182 | 3228 | ||
| 3183 | void vega20_set_ppt_funcs(struct smu_context *smu) | 3229 | void vega20_set_ppt_funcs(struct smu_context *smu) |