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 | 150 | extern char *amdgpu_disable_cu; |
| 151 | 151 | extern char *amdgpu_virtual_display; |
| 152 | 152 | extern uint amdgpu_pp_feature_mask; |
| 153 | +extern uint amdgpu_force_long_training; | |
| 153 | 154 | extern int amdgpu_job_hang_limit; |
| 154 | 155 | extern int amdgpu_lbpw; |
| 155 | 156 | extern int amdgpu_compute_multipipe; |
| @@ -288,6 +289,9 @@ struct amdgpu_ip_block_version { · 132 unmodified lines | ||
| 288 | 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 | 295 | struct amdgpu_ip_block { |
| 292 | 296 | struct amdgpu_ip_block_status status; |
| 293 | 297 | const struct amdgpu_ip_block_version *version; |
| @@ -627,6 +631,11 @@ struct amdgpu_fw_vram_usage { · 333 unmodified lines | ||
| 627 | 631 | u64 size; |
| 628 | 632 | struct amdgpu_bo *reserved_bo; |
| 629 | 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 | 768 | uint8_t *bios; |
| 760 | 769 | uint32_t bios_size; |
| 761 | 770 | struct amdgpu_bo *stolen_vga_memory; |
| 771 | + struct amdgpu_bo *discovery_memory; | |
| 762 | 772 | uint32_t bios_scratch_reg_offset; |
| 763 | 773 | uint32_t bios_scratch[AMDGPU_BIOS_NUM_SCRATCH]; |
| 764 | 774 | |
| @@ -959,8 +969,6 @@ struct amdgpu_device { · 194 unmodified lines | ||
| 959 | 969 | int asic_reset_res; |
| 960 | 970 | struct work_struct xgmi_reset_work; |
| 961 | 971 | |
| 962 | − bool in_baco_reset; | |
| 963 | − | |
| 964 | 972 | long gfx_timeout; |
| 965 | 973 | long sdma_timeout; |
| 966 | 974 | long video_timeout; |
| @@ -982,6 +990,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, · 15 unmodified lines | ||
| 982 | 990 | void amdgpu_device_fini(struct amdgpu_device *adev); |
| 983 | 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 | 995 | uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg, |
| 986 | 996 | uint32_t acc_flags); |
| 987 | 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 | 2038 | if (adev->is_atom_fw) { |
| 2039 | 2039 | amdgpu_atomfirmware_scratch_regs_init(adev); |
| 2040 | 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 | 2046 | } else { |
| 2042 | 2047 | amdgpu_atombios_scratch_regs_init(adev); |
| 2043 | 2048 | amdgpu_atombios_allocate_fb_scratch(adev); |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | #include "amdgpu_atomfirmware.h" |
| 28 | 28 | #include "atom.h" |
| 29 | 29 | #include "atombios.h" |
| 30 | +#include "soc15_hw_ip.h" | |
| 30 | 31 | |
| 31 | 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 | 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 | 31 | int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev); |
| 32 | 32 | int amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev, |
| 33 | 33 | int *vram_width, int *vram_type, int *vram_vendor); |
| 34 | +int amdgpu_atomfirmware_get_mem_train_fb_loc(struct amdgpu_device *adev); | |
| 34 | 35 | int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev); |
| 35 | 36 | int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev); |
| 36 | 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 | 613 | bool d3_supported = false; |
| 614 | 614 | struct pci_dev *parent_pdev; |
| 615 | 615 | |
| 616 | − while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, 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) { | |
| 616 | + while ((pdev = pci_get_class(PCI_BASE_CLASS_DISPLAY << 16, pdev)) != NULL) { | |
| 627 | 617 | vga_count++; |
| 628 | 618 | |
| 629 | 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 | 140 | return 0; |
| 141 | 141 | |
| 142 | 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 | 149 | struct amdgpu_bo *bo = ttm_to_amdgpu_bo(array[i].tv.bo); |
| 145 | 150 | |
| 146 | 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 | 475 | list_for_each_entry(lobj, validated, tv.head) { |
| 476 | 476 | struct amdgpu_bo *bo = ttm_to_amdgpu_bo(lobj->tv.bo); |
| 477 | − bool binding_userptr = false; | |
| 478 | 477 | struct mm_struct *usermm; |
| 479 | 478 | |
| 480 | 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 | 491 | amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, |
| 493 | 492 | lobj->user_pages); |
| 494 | − binding_userptr = true; | |
| 495 | 493 | } |
| 496 | 494 | |
| 497 | 495 | r = amdgpu_cs_validate(p, bo); |
| 498 | 496 | if (r) |
| 499 | 497 | return r; |
| 500 | 498 | |
| 501 | − if (binding_userptr) { | |
| 502 | − kvfree(lobj->user_pages); | |
| 503 | − lobj->user_pages = NULL; | |
| 504 | − } | |
| 499 | + kvfree(lobj->user_pages); | |
| 500 | + lobj->user_pages = NULL; | |
| 505 | 501 | } |
| 506 | 502 | return 0; |
| 507 | 503 | } |
| @@ -153,6 +153,36 @@ bool amdgpu_device_is_px(struct drm_device *dev) · 152 unmodified lines | ||
| 153 | 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 | 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 | 2652 | * There is only one value specified and |
| 2623 | 2653 | * it should apply to all non-compute jobs. |
| 2624 | 2654 | */ |
| 2625 | − if (index == 1) | |
| 2655 | + if (index == 1) { | |
| 2626 | 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 | 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 | 3202 | amdgpu_bo_evict_vram(adev); |
| 3170 | 3203 | |
| 3171 | − pci_save_state(dev->pdev); | |
| 3172 | 3204 | if (suspend) { |
| 3205 | + pci_save_state(dev->pdev); | |
| 3173 | 3206 | /* Shut down the device */ |
| 3174 | 3207 | pci_disable_device(dev->pdev); |
| 3175 | 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 | 3211 | return 0; |
| @@ -134,20 +134,10 @@ static int hw_id_map[MAX_HWIP] = { · 133 unmodified lines | ||
| 134 | 134 | |
| 135 | 135 | static int amdgpu_discovery_read_binary(struct amdgpu_device *adev, uint8_t *binary) |
| 136 | 136 | { |
| 137 | − uint32_t *p = (uint32_t *)binary; | |
| 138 | 137 | uint64_t vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20; |
| 139 | − uint64_t pos = vram_size - BINARY_MAX_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 | − } | |
| 138 | + uint64_t pos = vram_size - DISCOVERY_TMR_SIZE; | |
| 150 | 139 | |
| 140 | + amdgpu_device_vram_access(adev, pos, (uint32_t *)binary, DISCOVERY_TMR_SIZE, false); | |
| 151 | 141 | return 0; |
| 152 | 142 | } |
| 153 | 143 | |
| @@ -179,7 +169,7 @@ int amdgpu_discovery_init(struct amdgpu_device *adev) · 25 unmodified lines | ||
| 179 | 169 | uint16_t checksum; |
| 180 | 170 | int r; |
| 181 | 171 | |
| 182 | − adev->discovery = kzalloc(BINARY_MAX_SIZE, GFP_KERNEL); | |
| 172 | + adev->discovery = kzalloc(DISCOVERY_TMR_SIZE, GFP_KERNEL); | |
| 183 | 173 | if (!adev->discovery) |
| 184 | 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 | 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 | 328 | struct binary_header *bhdr; |
| 339 | 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 | 359 | *major = ip->major; |
| 370 | 360 | if (minor) |
| 371 | 361 | *minor = ip->minor; |
| 362 | + if (revision) | |
| 363 | + *revision = ip->revision; | |
| 372 | 364 | return 0; |
| 373 | 365 | } |
| 374 | 366 | ip_offset += sizeof(*ip) + 4 * (ip->num_base_address - 1); |
| @@ -24,11 +24,13 @@ · 23 unmodified lines | ||
| 24 | 24 | #ifndef __AMDGPU_DISCOVERY__ |
| 25 | 25 | #define __AMDGPU_DISCOVERY__ |
| 26 | 26 | |
| 27 | +#define DISCOVERY_TMR_SIZE (64 << 10) | |
| 28 | + | |
| 27 | 29 | int amdgpu_discovery_init(struct amdgpu_device *adev); |
| 28 | 30 | void amdgpu_discovery_fini(struct amdgpu_device *adev); |
| 29 | 31 | int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev); |
| 30 | 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 | 34 | int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev); |
| 33 | 35 | |
| 34 | 36 | #endif /* __AMDGPU_DISCOVERY__ */ |
| @@ -128,6 +128,7 @@ char *amdgpu_disable_cu = NULL; · 127 unmodified lines | ||
| 128 | 128 | char *amdgpu_virtual_display = NULL; |
| 129 | 129 | /* OverDrive(bit 14) disabled by default*/ |
| 130 | 130 | uint amdgpu_pp_feature_mask = 0xffffbfff; |
| 131 | +uint amdgpu_force_long_training = 0; | |
| 131 | 132 | int amdgpu_job_hang_limit = 0; |
| 132 | 133 | int amdgpu_lbpw = -1; |
| 133 | 134 | int amdgpu_compute_multipipe = -1; |
| @@ -250,9 +251,11 @@ module_param_named(msi, amdgpu_msi, int, 0444); · 116 unmodified lines | ||
| 250 | 251 | * By default(with no lockup_timeout settings), the timeout for all non-compute(GFX, SDMA and Video) |
| 251 | 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 | 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 | 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 | 393 | MODULE_PARM_DESC(ppfeaturemask, "all power features enabled (default))"); |
| 391 | 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 | 405 | * DOC: pcie_gen_cap (uint) |
| 395 | 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 | 1165 | static int amdgpu_pmops_freeze(struct device *dev) |
| 1155 | 1166 | { |
| 1156 | 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 | 1177 | static int amdgpu_pmops_thaw(struct device *dev) |
| @@ -67,6 +67,8 @@ struct amdgpu_nbio_funcs { · 66 unmodified lines | ||
| 67 | 67 | bool enable); |
| 68 | 68 | void (*ih_doorbell_range)(struct amdgpu_device *adev, |
| 69 | 69 | bool use_doorbell, int doorbell_index); |
| 70 | + void (*enable_doorbell_interrupt)(struct amdgpu_device *adev, | |
| 71 | + bool enable); | |
| 70 | 72 | void (*update_medium_grain_clock_gating)(struct amdgpu_device *adev, |
| 71 | 73 | bool enable); |
| 72 | 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 | 517 | .interruptible = (bp->type != ttm_bo_type_kernel), |
| 518 | 518 | .no_wait_gpu = bp->no_wait_gpu, |
| 519 | 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 | 523 | struct amdgpu_bo *bo; |
| 523 | 524 | unsigned long page_align, size = bp->size; |
| @@ -88,6 +88,17 @@ static int psp_sw_init(void *handle) · 87 unmodified lines | ||
| 88 | 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 | 102 | return 0; |
| 92 | 103 | } |
| 93 | 104 | |
| @@ -95,6 +106,7 @@ static int psp_sw_fini(void *handle) · 1 unmodified line | ||
| 95 | 106 | { |
| 96 | 107 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 97 | 108 | |
| 109 | + psp_mem_training_fini(&adev->psp); | |
| 98 | 110 | release_firmware(adev->psp.sos_fw); |
| 99 | 111 | adev->psp.sos_fw = NULL; |
| 100 | 112 | release_firmware(adev->psp.asd_fw); |
| @@ -1608,6 +1620,12 @@ static int psp_resume(void *handle) · 1507 unmodified lines | ||
| 1608 | 1620 | |
| 1609 | 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 | 1629 | mutex_lock(&adev->firmware.mutex); |
| 1612 | 1630 | |
| 1613 | 1631 | ret = psp_hw_start(psp); |
| @@ -49,6 +49,8 @@ enum psp_bootloader_cmd { · 48 unmodified lines | ||
| 49 | 49 | PSP_BL__LOAD_SYSDRV = 0x10000, |
| 50 | 50 | PSP_BL__LOAD_SOSDRV = 0x20000, |
| 51 | 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 | 56 | enum psp_ring_type |
| @@ -111,6 +113,9 @@ struct psp_funcs · 56 unmodified lines | ||
| 111 | 113 | struct ta_ras_trigger_error_input *info); |
| 112 | 114 | int (*ras_cure_posion)(struct psp_context *psp, uint64_t *mode_ptr); |
| 113 | 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 | 121 | #define AMDGPU_XGMI_MAX_CONNECTED_NODES 64 |
| @@ -161,6 +166,49 @@ struct psp_dtm_context { · 44 unmodified lines | ||
| 161 | 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 | 212 | struct psp_context |
| 165 | 213 | { |
| 166 | 214 | struct amdgpu_device *adev; |
| @@ -239,6 +287,7 @@ struct psp_context · 72 unmodified lines | ||
| 239 | 287 | struct psp_hdcp_context hdcp_context; |
| 240 | 288 | struct psp_dtm_context dtm_context; |
| 241 | 289 | struct mutex mutex; |
| 290 | + struct psp_memory_training_context mem_train_ctx; | |
| 242 | 291 | }; |
| 243 | 292 | |
| 244 | 293 | struct amdgpu_psp_funcs { |
| @@ -281,6 +330,12 @@ struct amdgpu_psp_funcs { · 36 unmodified lines | ||
| 281 | 330 | (psp)->funcs->xgmi_set_topology_info((psp), (num_device), (topology)) : -EINVAL) |
| 282 | 331 | #define psp_rlc_autoload(psp) \ |
| 283 | 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 | 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 | 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 | 77 | static ssize_t amdgpu_ras_debugfs_read(struct file *f, char __user *buf, |
| 75 | 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 | 218 | * value to the address. |
| 216 | 219 | * |
| 217 | 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 | 223 | * - 0: disable RAS on the block. Take ::head as its data. |
| 221 | 224 | * - 1: enable RAS on the block. Take ::head as its data. |
| 222 | 225 | * - 2: inject errors on the block. Take ::inject as its data. |
| 226 | + * - 3: reboot on unrecoverable error | |
| 223 | 227 | * |
| 224 | 228 | * How to use the interface? |
| 225 | 229 | * programs: |
| @@ -228,13 +232,13 @@ static struct ras_manager *amdgpu_ras_find_obj(struct amdgpu_device *adev, · 2 unmodified lines | ||
| 228 | 232 | * |
| 229 | 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 | 237 | * op: disable, enable, inject |
| 234 | 238 | * disable: only block is needed |
| 235 | 239 | * enable: block and error are needed |
| 236 | 240 | * inject: error, address, value are needed |
| 237 | − * block: umc, smda, gfx, ......... | |
| 241 | + * block: umc, sdma, gfx, ......... | |
| 238 | 242 | * see ras_block_string[] for details |
| 239 | 243 | * error: ue, ce |
| 240 | 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 | 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 | 305 | /* data.inject.address is offset instead of absolute gpu address */ |
| 294 | 306 | ret = amdgpu_ras_error_inject(adev, &data.inject); |
| 295 | 307 | break; |
| @@ -1430,6 +1442,39 @@ out: · 1134 unmodified lines | ||
| 1430 | 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 | 1478 | /* called in gpu recovery/init */ |
| 1434 | 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 | 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 | 1897 | if (atomic_cmpxchg(&amdgpu_ras_in_intr, 0, 1) == 0) { |
| 1847 | 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 | 170 | __field(unsigned int, context) |
| 171 | 171 | __field(unsigned int, seqno) |
| 172 | 172 | __field(struct dma_fence *, fence) |
| 173 | − __field(char *, ring_name) | |
| 173 | + __string(ring, to_amdgpu_ring(job->base.sched)->name) | |
| 174 | 174 | __field(u32, num_ibs) |
| 175 | 175 | ), |
| 176 | 176 | |
| @@ -179,12 +179,12 @@ TRACE_EVENT(amdgpu_cs_ioctl, · 2 unmodified lines | ||
| 179 | 179 | __assign_str(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job)) |
| 180 | 180 | __entry->context = job->base.s_fence->finished.context; |
| 181 | 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 | 183 | __entry->num_ibs = job->num_ibs; |
| 184 | 184 | ), |
| 185 | 185 | TP_printk("sched_job=%llu, timeline=%s, context=%u, seqno=%u, ring_name=%s, num_ibs=%u", |
| 186 | 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 | 190 | TRACE_EVENT(amdgpu_sched_run_job, |
| @@ -195,7 +195,7 @@ TRACE_EVENT(amdgpu_sched_run_job, · 4 unmodified lines | ||
| 195 | 195 | __string(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job)) |
| 196 | 196 | __field(unsigned int, context) |
| 197 | 197 | __field(unsigned int, seqno) |
| 198 | − __field(char *, ring_name) | |
| 198 | + __string(ring, to_amdgpu_ring(job->base.sched)->name) | |
| 199 | 199 | __field(u32, num_ibs) |
| 200 | 200 | ), |
| 201 | 201 | |
| @@ -204,12 +204,12 @@ TRACE_EVENT(amdgpu_sched_run_job, · 2 unmodified lines | ||
| 204 | 204 | __assign_str(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job)) |
| 205 | 205 | __entry->context = job->base.s_fence->finished.context; |
| 206 | 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 | 208 | __entry->num_ibs = job->num_ibs; |
| 209 | 209 | ), |
| 210 | 210 | TP_printk("sched_job=%llu, timeline=%s, context=%u, seqno=%u, ring_name=%s, num_ibs=%u", |
| 211 | 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 | 473 | TP_PROTO(struct amdgpu_job *sched_job, struct dma_fence *fence), |
| 474 | 474 | TP_ARGS(sched_job, fence), |
| 475 | 475 | TP_STRUCT__entry( |
| 476 | − __field(const char *,name) | |
| 476 | + __string(ring, sched_job->base.sched->name); | |
| 477 | 477 | __field(uint64_t, id) |
| 478 | 478 | __field(struct dma_fence *, fence) |
| 479 | 479 | __field(uint64_t, ctx) |
| @@ -481,14 +481,14 @@ TRACE_EVENT(amdgpu_ib_pipe_sync, · 1 unmodified line | ||
| 481 | 481 | ), |
| 482 | 482 | |
| 483 | 483 | TP_fast_assign( |
| 484 | − __entry->name = sched_job->base.sched->name; | |
| 484 | + __assign_str(ring, sched_job->base.sched->name) | |
| 485 | 485 | __entry->id = sched_job->base.id; |
| 486 | 486 | __entry->fence = fence; |
| 487 | 487 | __entry->ctx = fence->context; |
| 488 | 488 | __entry->seqno = fence->seqno; |
| 489 | 489 | ), |
| 490 | 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 | 492 | __entry->fence, __entry->ctx, |
| 493 | 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 | 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 | 1738 | * amdgpu_ttm_init - Init the memory management (ttm) as well as various |
| 1657 | 1739 | * gtt/vram related fields. |
| @@ -1726,6 +1808,14 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) · 68 unmodified lines | ||
| 1726 | 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 | 1819 | /* allocate memory as required for VGA |
| 1730 | 1820 | * This is used for VGA emulation and pre-OS scanout buffers to |
| 1731 | 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 | 1826 | NULL, &stolen_vga_buf); |
| 1737 | 1827 | if (r) |
| 1738 | 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 | 1843 | DRM_INFO("amdgpu: %uM of VRAM memory ready\n", |
| 1740 | 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 | 1904 | void *stolen_vga_buf; |
| 1801 | 1905 | /* return the VGA stolen memory (if any) back to VRAM */ |
| 1802 | 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 | 1918 | return; |
| 1812 | 1919 | |
| 1813 | 1920 | amdgpu_ttm_debugfs_fini(adev); |
| 1921 | + amdgpu_ttm_training_reserve_vram_fini(adev); | |
| 1814 | 1922 | amdgpu_ttm_fw_reserve_vram_fini(adev); |
| 1815 | 1923 | if (adev->mman.aper_base_kaddr) |
| 1816 | 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 | 2015 | *addr += (u64)window * AMDGPU_GTT_MAX_TRANSFER_SIZE * |
| 1908 | 2016 | AMDGPU_GPU_PAGE_SIZE; |
| 1909 | 2017 | |
| 1910 | − num_dw = adev->mman.buffer_funcs->copy_num_dw; | |
| 1911 | − while (num_dw & 0x7) | |
| 1912 | − num_dw++; | |
| 1913 | − | |
| 2018 | + num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8); | |
| 1914 | 2019 | num_bytes = num_pages * 8; |
| 1915 | 2020 | |
| 1916 | 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 | 2076 | max_bytes = adev->mman.buffer_funcs->copy_max_bytes; |
| 1972 | 2077 | num_loops = DIV_ROUND_UP(byte_count, max_bytes); |
| 1973 | − num_dw = num_loops * adev->mman.buffer_funcs->copy_num_dw; | |
| 1974 | − | |
| 1975 | − /* for IB padding */ | |
| 1976 | − while (num_dw & 0x7) | |
| 1977 | − num_dw++; | |
| 2078 | + num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->copy_num_dw, 8); | |
| 1978 | 2079 | |
| 1979 | 2080 | r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, &job); |
| 1980 | 2081 | if (r) |
| @@ -80,6 +80,11 @@ MODULE_FIRMWARE(FIRMWARE_VEGA12); · 79 unmodified lines | ||
| 80 | 80 | MODULE_FIRMWARE(FIRMWARE_VEGA20); |
| 81 | 81 | |
| 82 | 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 | 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 | 434 | * Open up a stream for HW test |
| 430 | 435 | */ |
| 431 | −int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, | |
| 432 | − struct dma_fence **fence) | |
| 436 | +static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, | |
| 437 | + struct amdgpu_bo *bo, | |
| 438 | + struct dma_fence **fence) | |
| 433 | 439 | { |
| 434 | 440 | const unsigned ib_size_dw = 1024; |
| 435 | 441 | struct amdgpu_job *job; |
| 436 | 442 | struct amdgpu_ib *ib; |
| 437 | 443 | struct dma_fence *f = NULL; |
| 438 | − uint64_t dummy; | |
| 444 | + uint64_t addr; | |
| 439 | 445 | int i, r; |
| 440 | 446 | |
| 441 | 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 | 451 | ib = &job->ibs[0]; |
| 446 | 452 | |
| 447 | − dummy = ib->gpu_addr + 1024; | |
| 453 | + addr = amdgpu_bo_gpu_offset(bo); | |
| 448 | 454 | |
| 449 | 455 | /* stitch together an VCE create msg */ |
| 450 | 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 | 483 | ib->ptr[ib->length_dw++] = 0x00000014; /* len */ |
| 478 | 484 | ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */ |
| 479 | − ib->ptr[ib->length_dw++] = upper_32_bits(dummy); | |
| 480 | − ib->ptr[ib->length_dw++] = dummy; | |
| 485 | + ib->ptr[ib->length_dw++] = upper_32_bits(addr); | |
| 486 | + ib->ptr[ib->length_dw++] = addr; | |
| 481 | 487 | ib->ptr[ib->length_dw++] = 0x00000001; |
| 482 | 488 | |
| 483 | 489 | for (i = ib->length_dw; i < ib_size_dw; ++i) |
| @@ -507,8 +513,8 @@ err: · 23 unmodified lines | ||
| 507 | 513 | * |
| 508 | 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, | |
| 511 | − bool direct, struct dma_fence **fence) | |
| 516 | +static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, | |
| 517 | + bool direct, struct dma_fence **fence) | |
| 512 | 518 | { |
| 513 | 519 | const unsigned ib_size_dw = 1024; |
| 514 | 520 | struct amdgpu_job *job; |
| @@ -1110,13 +1116,20 @@ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring) · 595 unmodified lines | ||
| 1110 | 1116 | int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout) |
| 1111 | 1117 | { |
| 1112 | 1118 | struct dma_fence *fence = NULL; |
| 1119 | + struct amdgpu_bo *bo = NULL; | |
| 1113 | 1120 | long r; |
| 1114 | 1121 | |
| 1115 | 1122 | /* skip vce ring1/2 ib test for now, since it's not reliable */ |
| 1116 | 1123 | if (ring != &ring->adev->vce.ring[0]) |
| 1117 | 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 | 1133 | if (r) |
| 1121 | 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 | 1146 | error: |
| 1134 | 1147 | dma_fence_put(fence); |
| 1148 | + amdgpu_bo_unreserve(bo); | |
| 1149 | + amdgpu_bo_unref(&bo); | |
| 1135 | 1150 | return r; |
| 1136 | 1151 | } |
| @@ -58,10 +58,6 @@ int amdgpu_vce_sw_fini(struct amdgpu_device *adev); · 57 unmodified lines | ||
| 58 | 58 | int amdgpu_vce_entity_init(struct amdgpu_device *adev); |
| 59 | 59 | int amdgpu_vce_suspend(struct amdgpu_device *adev); |
| 60 | 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 | 61 | void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp); |
| 66 | 62 | int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx); |
| 67 | 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 | 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 | 575 | const unsigned ib_size_dw = 16; |
| 575 | 576 | struct amdgpu_job *job; |
| 576 | 577 | struct amdgpu_ib *ib; |
| 577 | 578 | struct dma_fence *f = NULL; |
| 578 | − uint64_t dummy; | |
| 579 | + uint64_t addr; | |
| 579 | 580 | int i, r; |
| 580 | 581 | |
| 581 | 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 | 584 | return r; |
| 584 | 585 | |
| 585 | 586 | ib = &job->ibs[0]; |
| 586 | − dummy = ib->gpu_addr + 1024; | |
| 587 | + addr = amdgpu_bo_gpu_offset(bo); | |
| 587 | 588 | |
| 588 | 589 | ib->length_dw = 0; |
| 589 | 590 | ib->ptr[ib->length_dw++] = 0x00000018; |
| 590 | 591 | ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ |
| 591 | 592 | ib->ptr[ib->length_dw++] = handle; |
| 592 | − ib->ptr[ib->length_dw++] = upper_32_bits(dummy); | |
| 593 | − ib->ptr[ib->length_dw++] = dummy; | |
| 593 | + ib->ptr[ib->length_dw++] = upper_32_bits(addr); | |
| 594 | + ib->ptr[ib->length_dw++] = addr; | |
| 594 | 595 | ib->ptr[ib->length_dw++] = 0x0000000b; |
| 595 | 596 | |
| 596 | 597 | ib->ptr[ib->length_dw++] = 0x00000014; |
| @@ -621,13 +622,14 @@ err: · 24 unmodified lines | ||
| 621 | 622 | } |
| 622 | 623 | |
| 623 | 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 | 628 | const unsigned ib_size_dw = 16; |
| 627 | 629 | struct amdgpu_job *job; |
| 628 | 630 | struct amdgpu_ib *ib; |
| 629 | 631 | struct dma_fence *f = NULL; |
| 630 | − uint64_t dummy; | |
| 632 | + uint64_t addr; | |
| 631 | 633 | int i, r; |
| 632 | 634 | |
| 633 | 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 | 637 | return r; |
| 636 | 638 | |
| 637 | 639 | ib = &job->ibs[0]; |
| 638 | − dummy = ib->gpu_addr + 1024; | |
| 640 | + addr = amdgpu_bo_gpu_offset(bo); | |
| 639 | 641 | |
| 640 | 642 | ib->length_dw = 0; |
| 641 | 643 | ib->ptr[ib->length_dw++] = 0x00000018; |
| 642 | 644 | ib->ptr[ib->length_dw++] = 0x00000001; |
| 643 | 645 | ib->ptr[ib->length_dw++] = handle; |
| 644 | − ib->ptr[ib->length_dw++] = upper_32_bits(dummy); | |
| 645 | − ib->ptr[ib->length_dw++] = dummy; | |
| 646 | + ib->ptr[ib->length_dw++] = upper_32_bits(addr); | |
| 647 | + ib->ptr[ib->length_dw++] = addr; | |
| 646 | 648 | ib->ptr[ib->length_dw++] = 0x0000000b; |
| 647 | 649 | |
| 648 | 650 | ib->ptr[ib->length_dw++] = 0x00000014; |
| @@ -675,13 +677,20 @@ err: · 26 unmodified lines | ||
| 675 | 677 | int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) |
| 676 | 678 | { |
| 677 | 679 | struct dma_fence *fence = NULL; |
| 680 | + struct amdgpu_bo *bo = NULL; | |
| 678 | 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 | 690 | if (r) |
| 682 | 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 | 694 | if (r) |
| 686 | 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 | 703 | error: |
| 695 | 704 | dma_fence_put(fence); |
| 705 | + amdgpu_bo_unreserve(bo); | |
| 706 | + amdgpu_bo_unref(&bo); | |
| 696 | 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 | 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 | 2984 | amdgpu_vm_free_pts(adev, vm, NULL); |
| 2975 | 2985 | amdgpu_bo_unreserve(root); |
| 2976 | 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 | 3000 | list_del(&mapping->list); |
| 2991 | 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 | 3004 | dma_fence_put(vm->last_update); |
| 3004 | 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 | 1275 | * @adev: amdgpu_device pointer |
| 1276 | 1276 | * |
| 1277 | − * Look up which blocks are hung and attempt | |
| 1278 | − * to reset them. | |
| 1277 | + * Use PCI Config method to reset the GPU. | |
| 1278 | + * | |
| 1279 | 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 | 1283 | int r; |
| 1284 | 1284 | |
| @@ -1294,7 +1294,45 @@ static int cik_asic_reset(struct amdgpu_device *adev) · 9 unmodified lines | ||
| 1294 | 1294 | static enum amd_reset_method |
| 1295 | 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 | 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 | 31 | int cik_set_ip_blocks(struct amdgpu_device *adev); |
| 32 | 32 | |
| 33 | 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 | 37 | #endif |
| @@ -5283,15 +5283,12 @@ static void gfx_v10_0_set_rlc_funcs(struct amdgpu_device *adev) · 5282 unmodified lines | ||
| 5283 | 5283 | |
| 5284 | 5284 | static void gfx_v10_0_set_gds_init(struct amdgpu_device *adev) |
| 5285 | 5285 | { |
| 5286 | − /* init asic gds info */ | |
| 5287 | − switch (adev->asic_type) { | |
| 5288 | − case CHIP_NAVI10: | |
| 5289 | − default: | |
| 5290 | − adev->gds.gds_size = 0x10000; | |
| 5291 | − adev->gds.gds_compute_max_wave_id = 0x4ff; | |
| 5292 | − break; | |
| 5293 | − } | |
| 5286 | + unsigned total_cu = adev->gfx.config.max_cu_per_sh * | |
| 5287 | + adev->gfx.config.max_sh_per_se * | |
| 5288 | + adev->gfx.config.max_shader_engines; | |
| 5294 | 5289 | |
| 5290 | + adev->gds.gds_size = 0x10000; | |
| 5291 | + adev->gds.gds_compute_max_wave_id = total_cu * 32 - 1; | |
| 5295 | 5292 | adev->gds.gws_size = 64; |
| 5296 | 5293 | adev->gds.oa_size = 16; |
| 5297 | 5294 | } |
| @@ -131,6 +131,18 @@ MODULE_FIRMWARE("amdgpu/renoir_rlc.bin"); · 130 unmodified lines | ||
| 131 | 131 | #define mmTCP_CHAN_STEER_5_ARCT 0x0b0c |
| 132 | 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 | 146 | enum ta_ras_gfx_subblock { |
| 135 | 147 | /*CPC*/ |
| 136 | 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 | 3990 | { SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 1, 16}, |
| 3979 | 3991 | { SOC15_REG_ENTRY(GC, 0, mmTCP_ATC_EDC_GATCL1_CNT), 0, 4, 16}, |
| 3980 | 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 | 3994 | { SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 0, 4, 16}, |
| 3982 | 3995 | { SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 0, 4, 6}, |
| 3983 | 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 | 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 | 4290 | if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_PG) && enable) { |
| 4281 | 4291 | gfx_v9_0_enable_gfx_cg_power_gating(adev, true); |
| 4282 | 4292 | if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PIPELINE) |
| 4283 | 4293 | gfx_v9_0_enable_gfx_pipeline_powergating(adev, true); |
| 4284 | 4294 | } else { |
| 4285 | 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 | 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 | 4563 | gfx_v9_0_enable_cp_power_gating(adev, false); |
| 4553 | 4564 | |
| 4554 | 4565 | /* update gfx cgpg state */ |
| 4555 | − if (is_support_sw_smu(adev) && enable) | |
| 4556 | − smu_set_gfx_cgpg(&adev->smu, enable); | |
| 4557 | 4566 | gfx_v9_0_update_gfx_cg_power_gating(adev, enable); |
| 4558 | 4567 | |
| 4559 | 4568 | /* update mgcg state */ |
| @@ -5437,301 +5446,446 @@ static int gfx_v9_0_priv_inst_irq(struct amdgpu_device *adev, · 877 unmodified lines | ||
| 5437 | 5446 | return 0; |
| 5438 | 5447 | } |
| 5439 | 5448 | |
| 5440 | −static const struct { | |
| 5441 | − const char *name; | |
| 5442 | − uint32_t ip; | |
| 5443 | − uint32_t inst; | |
| 5444 | − uint32_t seg; | |
| 5445 | − uint32_t reg_offset; | |
| 5446 | − uint32_t per_se_instance; | |
| 5447 | − int32_t num_instance; | |
| 5448 | − uint32_t sec_count_mask; | |
| 5449 | − uint32_t ded_count_mask; | |
| 5450 | −} gfx_ras_edc_regs[] = { | |
| 5451 | − { "CPC_SCRATCH", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_SCRATCH_CNT), 0, 1, | |
| 5452 | − REG_FIELD_MASK(CPC_EDC_SCRATCH_CNT, SEC_COUNT), | |
| 5453 | − REG_FIELD_MASK(CPC_EDC_SCRATCH_CNT, DED_COUNT) }, | |
| 5454 | − { "CPC_UCODE", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_UCODE_CNT), 0, 1, | |
| 5455 | − REG_FIELD_MASK(CPC_EDC_UCODE_CNT, SEC_COUNT), | |
| 5456 | − REG_FIELD_MASK(CPC_EDC_UCODE_CNT, DED_COUNT) }, | |
| 5457 | − { "CPF_ROQ_ME1", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT), 0, 1, | |
| 5458 | − REG_FIELD_MASK(CPF_EDC_ROQ_CNT, COUNT_ME1), 0 }, | |
| 5459 | − { "CPF_ROQ_ME2", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT), 0, 1, | |
| 5460 | − REG_FIELD_MASK(CPF_EDC_ROQ_CNT, COUNT_ME2), 0 }, | |
| 5461 | − { "CPF_TAG", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_TAG_CNT), 0, 1, | |
| 5462 | − REG_FIELD_MASK(CPF_EDC_TAG_CNT, SEC_COUNT), | |
| 5463 | − REG_FIELD_MASK(CPF_EDC_TAG_CNT, DED_COUNT) }, | |
| 5464 | − { "CPG_DMA_ROQ", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_DMA_CNT), 0, 1, | |
| 5465 | − REG_FIELD_MASK(CPG_EDC_DMA_CNT, ROQ_COUNT), 0 }, | |
| 5466 | − { "CPG_DMA_TAG", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_DMA_CNT), 0, 1, | |
| 5467 | − REG_FIELD_MASK(CPG_EDC_DMA_CNT, TAG_SEC_COUNT), | |
| 5468 | − REG_FIELD_MASK(CPG_EDC_DMA_CNT, TAG_DED_COUNT) }, | |
| 5469 | − { "CPG_TAG", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_TAG_CNT), 0, 1, | |
| 5470 | − REG_FIELD_MASK(CPG_EDC_TAG_CNT, SEC_COUNT), | |
| 5471 | − REG_FIELD_MASK(CPG_EDC_TAG_CNT, DED_COUNT) }, | |
| 5472 | − { "DC_CSINVOC", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_CSINVOC_CNT), 0, 1, | |
| 5473 | − REG_FIELD_MASK(DC_EDC_CSINVOC_CNT, COUNT_ME1), 0 }, | |
| 5474 | − { "DC_RESTORE", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_RESTORE_CNT), 0, 1, | |
| 5475 | − REG_FIELD_MASK(DC_EDC_RESTORE_CNT, COUNT_ME1), 0 }, | |
| 5476 | − { "DC_STATE", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_STATE_CNT), 0, 1, | |
| 5477 | − REG_FIELD_MASK(DC_EDC_STATE_CNT, COUNT_ME1), 0 }, | |
| 5478 | − { "GDS_MEM", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_CNT), 0, 1, | |
| 5479 | − REG_FIELD_MASK(GDS_EDC_CNT, GDS_MEM_SEC), | |
| 5480 | − REG_FIELD_MASK(GDS_EDC_CNT, GDS_MEM_DED) }, | |
| 5481 | − { "GDS_INPUT_QUEUE", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_CNT), 0, 1, | |
| 5482 | − REG_FIELD_MASK(GDS_EDC_CNT, GDS_INPUT_QUEUE_SED), 0 }, | |
| 5449 | + | |
| 5450 | +static const struct ras_gfx_subblock_reg ras_subblock_regs[] = { | |
| 5451 | + { "CPC_SCRATCH", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_SCRATCH_CNT), | |
| 5452 | + SOC15_REG_FIELD(CPC_EDC_SCRATCH_CNT, SEC_COUNT), | |
| 5453 | + SOC15_REG_FIELD(CPC_EDC_SCRATCH_CNT, DED_COUNT) | |
| 5454 | + }, | |
| 5455 | + { "CPC_UCODE", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_UCODE_CNT), | |
| 5456 | + SOC15_REG_FIELD(CPC_EDC_UCODE_CNT, SEC_COUNT), | |
| 5457 | + SOC15_REG_FIELD(CPC_EDC_UCODE_CNT, DED_COUNT) | |
| 5458 | + }, | |
| 5459 | + { "CPF_ROQ_ME1", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT), | |
| 5460 | + SOC15_REG_FIELD(CPF_EDC_ROQ_CNT, COUNT_ME1), | |
| 5461 | + 0, 0 | |
| 5462 | + }, | |
| 5463 | + { "CPF_ROQ_ME2", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT), | |
| 5464 | + SOC15_REG_FIELD(CPF_EDC_ROQ_CNT, COUNT_ME2), | |
| 5465 | + 0, 0 | |
| 5466 | + }, | |
| 5467 | + { "CPF_TAG", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_TAG_CNT), | |
| 5468 | + SOC15_REG_FIELD(CPF_EDC_TAG_CNT, SEC_COUNT), | |
| 5469 | + SOC15_REG_FIELD(CPF_EDC_TAG_CNT, DED_COUNT) | |
| 5470 | + }, | |
| 5471 | + { "CPG_DMA_ROQ", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_DMA_CNT), | |
| 5472 | + SOC15_REG_FIELD(CPG_EDC_DMA_CNT, ROQ_COUNT), | |
| 5473 | + 0, 0 | |
| 5474 | + }, | |
| 5475 | + { "CPG_DMA_TAG", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_DMA_CNT), | |
| 5476 | + SOC15_REG_FIELD(CPG_EDC_DMA_CNT, TAG_SEC_COUNT), | |
| 5477 | + SOC15_REG_FIELD(CPG_EDC_DMA_CNT, TAG_DED_COUNT) | |
| 5478 | + }, | |
| 5479 | + { "CPG_TAG", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_TAG_CNT), | |
| 5480 | + SOC15_REG_FIELD(CPG_EDC_TAG_CNT, SEC_COUNT), | |
| 5481 | + SOC15_REG_FIELD(CPG_EDC_TAG_CNT, DED_COUNT) | |
| 5482 | + }, | |
| 5483 | + { "DC_CSINVOC", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_CSINVOC_CNT), | |
| 5484 | + SOC15_REG_FIELD(DC_EDC_CSINVOC_CNT, COUNT_ME1), | |
| 5485 | + 0, 0 | |
| 5486 | + }, | |
| 5487 | + { "DC_RESTORE", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_RESTORE_CNT), | |
| 5488 | + SOC15_REG_FIELD(DC_EDC_RESTORE_CNT, COUNT_ME1), | |
| 5489 | + 0, 0 | |
| 5490 | + }, | |
| 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 | 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), | |
| 5485 | − REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_DED) }, | |
| 5504 | + SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_SEC), | |
| 5505 | + SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_DED) | |
| 5506 | + }, | |
| 5486 | 5507 | { "GDS_OA_PHY_PHY_CMD_RAM_MEM", |
| 5487 | − SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), 0, 1, | |
| 5488 | − REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_SEC), | |
| 5489 | − REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_DED) }, | |
| 5508 | + SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), | |
| 5509 | + SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_SEC), | |
| 5510 | + SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_DED) | |
| 5511 | + }, | |
| 5490 | 5512 | { "GDS_OA_PHY_PHY_DATA_RAM_MEM", |
| 5491 | − SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), 0, 1, | |
| 5492 | − REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, PHY_DATA_RAM_MEM_SED), 0 }, | |
| 5513 | + SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), | |
| 5514 | + SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, PHY_DATA_RAM_MEM_SED), | |
| 5515 | + 0, 0 | |
| 5516 | + }, | |
| 5493 | 5517 | { "GDS_OA_PIPE_ME1_PIPE0_PIPE_MEM", |
| 5494 | − SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1, | |
| 5495 | − REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_SEC), | |
| 5496 | − REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_DED) }, | |
| 5518 | + SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), | |
| 5519 | + SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_SEC), | |
| 5520 | + SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_DED) | |
| 5521 | + }, | |
| 5497 | 5522 | { "GDS_OA_PIPE_ME1_PIPE1_PIPE_MEM", |
| 5498 | − SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1, | |
| 5499 | − REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_SEC), | |
| 5500 | − REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_DED) }, | |
| 5523 | + SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), | |
| 5524 | + SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_SEC), | |
| 5525 | + SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_DED) | |
| 5526 | + }, | |
| 5501 | 5527 | { "GDS_OA_PIPE_ME1_PIPE2_PIPE_MEM", |
| 5502 | − SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1, | |
| 5503 | − REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_SEC), | |
| 5504 | − REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_DED) }, | |
| 5528 | + SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), | |
| 5529 | + SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_SEC), | |
| 5530 | + SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_DED) | |
| 5531 | + }, | |
| 5505 | 5532 | { "GDS_OA_PIPE_ME1_PIPE3_PIPE_MEM", |
| 5506 | − SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1, | |
| 5507 | − REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_SEC), | |
| 5508 | − REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_DED) }, | |
| 5509 | − { "SPI_SR_MEM", SOC15_REG_ENTRY(GC, 0, mmSPI_EDC_CNT), 1, 1, | |
| 5510 | − REG_FIELD_MASK(SPI_EDC_CNT, SPI_SR_MEM_SED_COUNT), 0 }, | |
| 5511 | − { "TA_FS_DFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16, | |
| 5512 | − REG_FIELD_MASK(TA_EDC_CNT, TA_FS_DFIFO_SEC_COUNT), | |
| 5513 | − REG_FIELD_MASK(TA_EDC_CNT, TA_FS_DFIFO_DED_COUNT) }, | |
| 5514 | − { "TA_FS_AFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16, | |
| 5515 | − REG_FIELD_MASK(TA_EDC_CNT, TA_FS_AFIFO_SED_COUNT), 0 }, | |
| 5516 | − { "TA_FL_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16, | |
| 5517 | − REG_FIELD_MASK(TA_EDC_CNT, TA_FL_LFIFO_SED_COUNT), 0 }, | |
| 5518 | − { "TA_FX_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16, | |
| 5519 | − REG_FIELD_MASK(TA_EDC_CNT, TA_FX_LFIFO_SED_COUNT), 0 }, | |
| 5520 | − { "TA_FS_CFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16, | |
| 5521 | − REG_FIELD_MASK(TA_EDC_CNT, TA_FS_CFIFO_SED_COUNT), 0 }, | |
| 5522 | − { "TCA_HOLE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT), 0, 2, | |
| 5523 | − REG_FIELD_MASK(TCA_EDC_CNT, HOLE_FIFO_SED_COUNT), 0 }, | |
| 5524 | − { "TCA_REQ_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT), 0, 2, | |
| 5525 | − REG_FIELD_MASK(TCA_EDC_CNT, REQ_FIFO_SED_COUNT), 0 }, | |
| 5526 | − { "TCC_CACHE_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | |
| 5527 | − REG_FIELD_MASK(TCC_EDC_CNT, CACHE_DATA_SEC_COUNT), | |
| 5528 | − REG_FIELD_MASK(TCC_EDC_CNT, CACHE_DATA_DED_COUNT) }, | |
| 5529 | − { "TCC_CACHE_DIRTY", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | |
| 5530 | − REG_FIELD_MASK(TCC_EDC_CNT, CACHE_DIRTY_SEC_COUNT), | |
| 5531 | − REG_FIELD_MASK(TCC_EDC_CNT, CACHE_DIRTY_DED_COUNT) }, | |
| 5532 | − { "TCC_HIGH_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | |
| 5533 | − REG_FIELD_MASK(TCC_EDC_CNT, HIGH_RATE_TAG_SEC_COUNT), | |
| 5534 | − REG_FIELD_MASK(TCC_EDC_CNT, HIGH_RATE_TAG_DED_COUNT) }, | |
| 5535 | − { "TCC_LOW_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | |
| 5536 | − REG_FIELD_MASK(TCC_EDC_CNT, LOW_RATE_TAG_SEC_COUNT), | |
| 5537 | − REG_FIELD_MASK(TCC_EDC_CNT, LOW_RATE_TAG_DED_COUNT) }, | |
| 5538 | − { "TCC_SRC_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | |
| 5539 | − REG_FIELD_MASK(TCC_EDC_CNT, SRC_FIFO_SEC_COUNT), | |
| 5540 | − REG_FIELD_MASK(TCC_EDC_CNT, SRC_FIFO_DED_COUNT) }, | |
| 5541 | − { "TCC_IN_USE_DEC", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | |
| 5542 | − REG_FIELD_MASK(TCC_EDC_CNT, IN_USE_DEC_SED_COUNT), 0 }, | |
| 5543 | − { "TCC_IN_USE_TRANSFER", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | |
| 5544 | − REG_FIELD_MASK(TCC_EDC_CNT, IN_USE_TRANSFER_SED_COUNT), 0 }, | |
| 5545 | − { "TCC_LATENCY_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | |
| 5546 | − REG_FIELD_MASK(TCC_EDC_CNT, LATENCY_FIFO_SED_COUNT), 0 }, | |
| 5547 | − { "TCC_RETURN_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | |
| 5548 | − REG_FIELD_MASK(TCC_EDC_CNT, RETURN_DATA_SED_COUNT), 0 }, | |
| 5549 | − { "TCC_RETURN_CONTROL", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | |
| 5550 | − REG_FIELD_MASK(TCC_EDC_CNT, RETURN_CONTROL_SED_COUNT), 0 }, | |
| 5551 | − { "TCC_UC_ATOMIC_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, | |
| 5552 | − REG_FIELD_MASK(TCC_EDC_CNT, UC_ATOMIC_FIFO_SED_COUNT), 0 }, | |
| 5553 | − { "TCC_WRITE_RETURN", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, 16, | |
| 5554 | − REG_FIELD_MASK(TCC_EDC_CNT2, WRITE_RETURN_SED_COUNT), 0 }, | |
| 5555 | − { "TCC_WRITE_CACHE_READ", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, 16, | |
| 5556 | − REG_FIELD_MASK(TCC_EDC_CNT2, WRITE_CACHE_READ_SED_COUNT), 0 }, | |
| 5557 | − { "TCC_SRC_FIFO_NEXT_RAM", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, | |
| 5558 | − 16, REG_FIELD_MASK(TCC_EDC_CNT2, SRC_FIFO_NEXT_RAM_SED_COUNT), 0 }, | |
| 5533 | + SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), | |
| 5534 | + SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_SEC), | |
| 5535 | + SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_DED) | |
| 5536 | + }, | |
| 5537 | + { "SPI_SR_MEM", SOC15_REG_ENTRY(GC, 0, mmSPI_EDC_CNT), | |
| 5538 | + SOC15_REG_FIELD(SPI_EDC_CNT, SPI_SR_MEM_SED_COUNT), | |
| 5539 | + 0, 0 | |
| 5540 | + }, | |
| 5541 | + { "TA_FS_DFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), | |
| 5542 | + SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_DFIFO_SEC_COUNT), | |
| 5543 | + SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_DFIFO_DED_COUNT) | |
| 5544 | + }, | |
| 5545 | + { "TA_FS_AFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), | |
| 5546 | + SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_AFIFO_SED_COUNT), | |
| 5547 | + 0, 0 | |
| 5548 | + }, | |
| 5549 | + { "TA_FL_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), | |
| 5550 | + SOC15_REG_FIELD(TA_EDC_CNT, TA_FL_LFIFO_SED_COUNT), | |
| 5551 | + 0, 0 | |
| 5552 | + }, | |
| 5553 | + { "TA_FX_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), | |
| 5554 | + SOC15_REG_FIELD(TA_EDC_CNT, TA_FX_LFIFO_SED_COUNT), | |
| 5555 | + 0, 0 | |
| 5556 | + }, | |
| 5557 | + { "TA_FS_CFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), | |
| 5558 | + SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_CFIFO_SED_COUNT), | |
| 5559 | + 0, 0 | |
| 5560 | + }, | |
| 5561 | + { "TCA_HOLE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT), | |
| 5562 | + SOC15_REG_FIELD(TCA_EDC_CNT, HOLE_FIFO_SED_COUNT), | |
| 5563 | + 0, 0 | |
| 5564 | + }, | |
| 5565 | + { "TCA_REQ_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT), | |
| 5566 | + SOC15_REG_FIELD(TCA_EDC_CNT, REQ_FIFO_SED_COUNT), | |
| 5567 | + 0, 0 | |
| 5568 | + }, | |
| 5569 | + { "TCC_CACHE_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), | |
| 5570 | + SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DATA_SEC_COUNT), | |
| 5571 | + SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DATA_DED_COUNT) | |
| 5572 | + }, | |
| 5573 | + { "TCC_CACHE_DIRTY", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), | |
| 5574 | + SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DIRTY_SEC_COUNT), | |
| 5575 | + SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DIRTY_DED_COUNT) | |
| 5576 | + }, | |
| 5577 | + { "TCC_HIGH_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), | |
| 5578 | + SOC15_REG_FIELD(TCC_EDC_CNT, HIGH_RATE_TAG_SEC_COUNT), | |
| 5579 | + SOC15_REG_FIELD(TCC_EDC_CNT, HIGH_RATE_TAG_DED_COUNT) | |
| 5580 | + }, | |
| 5581 | + { "TCC_LOW_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), | |
| 5582 | + SOC15_REG_FIELD(TCC_EDC_CNT, LOW_RATE_TAG_SEC_COUNT), | |
| 5583 | + SOC15_REG_FIELD(TCC_EDC_CNT, LOW_RATE_TAG_DED_COUNT) | |
| 5584 | + }, | |
| 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 | 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), | |
| 5561 | − 0 }, | |
| 5562 | − { "TCC_CACHE_TAG_PROBE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, | |
| 5563 | − 16, REG_FIELD_MASK(TCC_EDC_CNT2, CACHE_TAG_PROBE_FIFO_SED_COUNT), 0 }, | |
| 5626 | + SOC15_REG_FIELD(TCC_EDC_CNT2, LATENCY_FIFO_NEXT_RAM_SED_COUNT), | |
| 5627 | + 0, 0 | |
| 5628 | + }, | |
| 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 | 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), | |
| 5566 | − 0 }, | |
| 5567 | − { "TCC_ATOMIC_RETURN_BUFFER", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, | |
| 5568 | − 16, REG_FIELD_MASK(TCC_EDC_CNT2, ATOMIC_RETURN_BUFFER_SED_COUNT), 0 }, | |
| 5569 | − { "TCI_WRITE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCI_EDC_CNT), 0, 72, | |
| 5570 | − REG_FIELD_MASK(TCI_EDC_CNT, WRITE_RAM_SED_COUNT), 0 }, | |
| 5571 | − { "TCP_CACHE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, | |
| 5572 | − REG_FIELD_MASK(TCP_EDC_CNT_NEW, CACHE_RAM_SEC_COUNT), | |
| 5573 | − REG_FIELD_MASK(TCP_EDC_CNT_NEW, CACHE_RAM_DED_COUNT) }, | |
| 5574 | − { "TCP_LFIFO_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, | |
| 5575 | − REG_FIELD_MASK(TCP_EDC_CNT_NEW, LFIFO_RAM_SEC_COUNT), | |
| 5576 | − REG_FIELD_MASK(TCP_EDC_CNT_NEW, LFIFO_RAM_DED_COUNT) }, | |
| 5577 | − { "TCP_CMD_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, | |
| 5578 | − REG_FIELD_MASK(TCP_EDC_CNT_NEW, CMD_FIFO_SED_COUNT), 0 }, | |
| 5579 | − { "TCP_VM_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, | |
| 5580 | − REG_FIELD_MASK(TCP_EDC_CNT_NEW, VM_FIFO_SEC_COUNT), 0 }, | |
| 5581 | − { "TCP_DB_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, | |
| 5582 | − REG_FIELD_MASK(TCP_EDC_CNT_NEW, DB_RAM_SED_COUNT), 0 }, | |
| 5583 | − { "TCP_UTCL1_LFIFO0", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, | |
| 5584 | − REG_FIELD_MASK(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_SEC_COUNT), | |
| 5585 | − REG_FIELD_MASK(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_DED_COUNT) }, | |
| 5586 | − { "TCP_UTCL1_LFIFO1", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, | |
| 5587 | − REG_FIELD_MASK(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_SEC_COUNT), | |
| 5588 | − REG_FIELD_MASK(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_DED_COUNT) }, | |
| 5589 | − { "TD_SS_FIFO_LO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 1, 16, | |
| 5590 | − REG_FIELD_MASK(TD_EDC_CNT, SS_FIFO_LO_SEC_COUNT), | |
| 5591 | − REG_FIELD_MASK(TD_EDC_CNT, SS_FIFO_LO_DED_COUNT) }, | |
| 5592 | − { "TD_SS_FIFO_HI", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 1, 16, | |
| 5593 | − REG_FIELD_MASK(TD_EDC_CNT, SS_FIFO_HI_SEC_COUNT), | |
| 5594 | − REG_FIELD_MASK(TD_EDC_CNT, SS_FIFO_HI_DED_COUNT) }, | |
| 5595 | − { "TD_CS_FIFO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 1, 16, | |
| 5596 | − REG_FIELD_MASK(TD_EDC_CNT, CS_FIFO_SED_COUNT), 0 }, | |
| 5597 | − { "SQ_LDS_D", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, | |
| 5598 | − REG_FIELD_MASK(SQ_EDC_CNT, LDS_D_SEC_COUNT), | |
| 5599 | − REG_FIELD_MASK(SQ_EDC_CNT, LDS_D_DED_COUNT) }, | |
| 5600 | − { "SQ_LDS_I", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, | |
| 5601 | − REG_FIELD_MASK(SQ_EDC_CNT, LDS_I_SEC_COUNT), | |
| 5602 | − REG_FIELD_MASK(SQ_EDC_CNT, LDS_I_DED_COUNT) }, | |
| 5603 | − { "SQ_SGPR", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, | |
| 5604 | − REG_FIELD_MASK(SQ_EDC_CNT, SGPR_SEC_COUNT), | |
| 5605 | − REG_FIELD_MASK(SQ_EDC_CNT, SGPR_DED_COUNT) }, | |
| 5606 | − { "SQ_VGPR0", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, | |
| 5607 | − REG_FIELD_MASK(SQ_EDC_CNT, VGPR0_SEC_COUNT), | |
| 5608 | − REG_FIELD_MASK(SQ_EDC_CNT, VGPR0_DED_COUNT) }, | |
| 5609 | − { "SQ_VGPR1", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, | |
| 5610 | − REG_FIELD_MASK(SQ_EDC_CNT, VGPR1_SEC_COUNT), | |
| 5611 | − REG_FIELD_MASK(SQ_EDC_CNT, VGPR1_DED_COUNT) }, | |
| 5612 | − { "SQ_VGPR2", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, | |
| 5613 | − REG_FIELD_MASK(SQ_EDC_CNT, VGPR2_SEC_COUNT), | |
| 5614 | − REG_FIELD_MASK(SQ_EDC_CNT, VGPR2_DED_COUNT) }, | |
| 5615 | − { "SQ_VGPR3", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, | |
| 5616 | − REG_FIELD_MASK(SQ_EDC_CNT, VGPR3_SEC_COUNT), | |
| 5617 | − REG_FIELD_MASK(SQ_EDC_CNT, VGPR3_DED_COUNT) }, | |
| 5634 | + SOC15_REG_FIELD(TCC_EDC_CNT2, WRRET_TAG_WRITE_RETURN_SED_COUNT), | |
| 5635 | + 0, 0 | |
| 5636 | + }, | |
| 5637 | + { "TCC_ATOMIC_RETURN_BUFFER", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), | |
| 5638 | + SOC15_REG_FIELD(TCC_EDC_CNT2, ATOMIC_RETURN_BUFFER_SED_COUNT), | |
| 5639 | + 0, 0 | |
| 5640 | + }, | |
| 5641 | + { "TCI_WRITE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCI_EDC_CNT), | |
| 5642 | + SOC15_REG_FIELD(TCI_EDC_CNT, WRITE_RAM_SED_COUNT), | |
| 5643 | + 0, 0 | |
| 5644 | + }, | |
| 5645 | + { "TCP_CACHE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), | |
| 5646 | + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, CACHE_RAM_SEC_COUNT), | |
| 5647 | + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, CACHE_RAM_DED_COUNT) | |
| 5648 | + }, | |
| 5649 | + { "TCP_LFIFO_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), | |
| 5650 | + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, LFIFO_RAM_SEC_COUNT), | |
| 5651 | + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, LFIFO_RAM_DED_COUNT) | |
| 5652 | + }, | |
| 5653 | + { "TCP_CMD_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), | |
| 5654 | + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, CMD_FIFO_SED_COUNT), | |
| 5655 | + 0, 0 | |
| 5656 | + }, | |
| 5657 | + { "TCP_VM_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), | |
| 5658 | + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, VM_FIFO_SEC_COUNT), | |
| 5659 | + 0, 0 | |
| 5660 | + }, | |
| 5661 | + { "TCP_DB_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), | |
| 5662 | + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, DB_RAM_SED_COUNT), | |
| 5663 | + 0, 0 | |
| 5664 | + }, | |
| 5665 | + { "TCP_UTCL1_LFIFO0", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), | |
| 5666 | + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_SEC_COUNT), | |
| 5667 | + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_DED_COUNT) | |
| 5668 | + }, | |
| 5669 | + { "TCP_UTCL1_LFIFO1", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), | |
| 5670 | + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_SEC_COUNT), | |
| 5671 | + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_DED_COUNT) | |
| 5672 | + }, | |
| 5673 | + { "TD_SS_FIFO_LO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), | |
| 5674 | + SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_LO_SEC_COUNT), | |
| 5675 | + SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_LO_DED_COUNT) | |
| 5676 | + }, | |
| 5677 | + { "TD_SS_FIFO_HI", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), | |
| 5678 | + SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_HI_SEC_COUNT), | |
| 5679 | + SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_HI_DED_COUNT) | |
| 5680 | + }, | |
| 5681 | + { "TD_CS_FIFO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), | |
| 5682 | + SOC15_REG_FIELD(TD_EDC_CNT, CS_FIFO_SED_COUNT), | |
| 5683 | + 0, 0 | |
| 5684 | + }, | |
| 5685 | + { "SQ_LDS_D", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), | |
| 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 | 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), | |
| 5620 | − REG_FIELD_MASK(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, | |
| 5622 | − 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU0_UTCL1_LFIFO_SEC_COUNT), | |
| 5623 | − REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU0_UTCL1_LFIFO_DED_COUNT) }, | |
| 5714 | + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_WRITE_DATA_BUF_SEC_COUNT), | |
| 5715 | + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_WRITE_DATA_BUF_DED_COUNT) | |
| 5716 | + }, | |
| 5717 | + { "SQC_DATA_CU0_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), | |
| 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 | 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), | |
| 5626 | − REG_FIELD_MASK(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, | |
| 5628 | − 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU1_UTCL1_LFIFO_SEC_COUNT), | |
| 5629 | − REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU1_UTCL1_LFIFO_DED_COUNT) }, | |
| 5722 | + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_WRITE_DATA_BUF_SEC_COUNT), | |
| 5723 | + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_WRITE_DATA_BUF_DED_COUNT) | |
| 5724 | + }, | |
| 5725 | + { "SQC_DATA_CU1_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), | |
| 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 | 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), | |
| 5632 | − REG_FIELD_MASK(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, | |
| 5634 | − 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_SEC_COUNT), | |
| 5635 | − REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_DED_COUNT) }, | |
| 5636 | − { "SQC_INST_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, | |
| 5637 | − 6, REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_SEC_COUNT), | |
| 5638 | − REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_DED_COUNT) }, | |
| 5639 | − { "SQC_INST_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, | |
| 5640 | − 6, REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_SEC_COUNT), | |
| 5641 | − REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_DED_COUNT) }, | |
| 5642 | − { "SQC_DATA_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, | |
| 5643 | − 6, REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_SEC_COUNT), | |
| 5644 | − REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_DED_COUNT) }, | |
| 5645 | − { "SQC_DATA_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, | |
| 5646 | − 6, REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_SEC_COUNT), | |
| 5647 | − REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_DED_COUNT) }, | |
| 5648 | − { "SQC_INST_BANKA_UTCL1_MISS_FIFO", | |
| 5649 | − SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 6, | |
| 5650 | − REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_UTCL1_MISS_FIFO_SED_COUNT), | |
| 5651 | − 0 }, | |
| 5652 | − { "SQC_INST_BANKA_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, | |
| 5653 | − 6, REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_MISS_FIFO_SED_COUNT), 0 }, | |
| 5654 | − { "SQC_DATA_BANKA_HIT_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, | |
| 5655 | − 6, REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_HIT_FIFO_SED_COUNT), 0 }, | |
| 5656 | − { "SQC_DATA_BANKA_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, | |
| 5657 | − 6, REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_MISS_FIFO_SED_COUNT), 0 }, | |
| 5658 | − { "SQC_DATA_BANKA_DIRTY_BIT_RAM", | |
| 5659 | − SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 6, | |
| 5660 | − REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_DIRTY_BIT_RAM_SED_COUNT), 0 }, | |
| 5661 | − { "SQC_INST_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 6, | |
| 5662 | − REG_FIELD_MASK(SQC_EDC_CNT2, INST_UTCL1_LFIFO_SEC_COUNT), | |
| 5663 | − REG_FIELD_MASK(SQC_EDC_CNT2, INST_UTCL1_LFIFO_DED_COUNT) }, | |
| 5664 | − { "SQC_INST_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, | |
| 5665 | − 6, REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_SEC_COUNT), | |
| 5666 | − REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_DED_COUNT) }, | |
| 5667 | − { "SQC_INST_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, | |
| 5668 | − 6, REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_SEC_COUNT), | |
| 5669 | − REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_DED_COUNT) }, | |
| 5670 | − { "SQC_DATA_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, | |
| 5671 | − 6, REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_SEC_COUNT), | |
| 5672 | − REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_DED_COUNT) }, | |
| 5673 | − { "SQC_DATA_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, | |
| 5674 | − 6, REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_SEC_COUNT), | |
| 5675 | − REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_DED_COUNT) }, | |
| 5676 | − { "SQC_INST_BANKB_UTCL1_MISS_FIFO", | |
| 5677 | − SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, 6, | |
| 5678 | − REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_UTCL1_MISS_FIFO_SED_COUNT), | |
| 5679 | − 0 }, | |
| 5680 | − { "SQC_INST_BANKB_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, | |
| 5681 | − 6, REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_MISS_FIFO_SED_COUNT), 0 }, | |
| 5682 | − { "SQC_DATA_BANKB_HIT_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, | |
| 5683 | − 6, REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_HIT_FIFO_SED_COUNT), 0 }, | |
| 5684 | − { "SQC_DATA_BANKB_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, | |
| 5685 | − 6, REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_MISS_FIFO_SED_COUNT), 0 }, | |
| 5686 | − { "SQC_DATA_BANKB_DIRTY_BIT_RAM", | |
| 5687 | − SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, 6, | |
| 5688 | − REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_DIRTY_BIT_RAM_SED_COUNT), 0 }, | |
| 5689 | − { "EA_DRAMRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | |
| 5690 | − REG_FIELD_MASK(GCEA_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT), | |
| 5691 | − REG_FIELD_MASK(GCEA_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT) }, | |
| 5692 | − { "EA_DRAMWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | |
| 5693 | − REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_CMDMEM_SEC_COUNT), | |
| 5694 | − REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_CMDMEM_DED_COUNT) }, | |
| 5695 | − { "EA_DRAMWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | |
| 5696 | − REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_DATAMEM_SEC_COUNT), | |
| 5697 | − REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_DATAMEM_DED_COUNT) }, | |
| 5698 | − { "EA_RRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | |
| 5699 | − REG_FIELD_MASK(GCEA_EDC_CNT, RRET_TAGMEM_SEC_COUNT), | |
| 5700 | − REG_FIELD_MASK(GCEA_EDC_CNT, RRET_TAGMEM_DED_COUNT) }, | |
| 5701 | − { "EA_WRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | |
| 5702 | − REG_FIELD_MASK(GCEA_EDC_CNT, WRET_TAGMEM_SEC_COUNT), | |
| 5703 | − REG_FIELD_MASK(GCEA_EDC_CNT, WRET_TAGMEM_DED_COUNT) }, | |
| 5704 | − { "EA_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | |
| 5705 | − REG_FIELD_MASK(GCEA_EDC_CNT, DRAMRD_PAGEMEM_SED_COUNT), 0 }, | |
| 5706 | − { "EA_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | |
| 5707 | − REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_PAGEMEM_SED_COUNT), 0 }, | |
| 5708 | − { "EA_IORD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | |
| 5709 | − REG_FIELD_MASK(GCEA_EDC_CNT, IORD_CMDMEM_SED_COUNT), 0 }, | |
| 5710 | − { "EA_IOWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | |
| 5711 | − REG_FIELD_MASK(GCEA_EDC_CNT, IOWR_CMDMEM_SED_COUNT), 0 }, | |
| 5712 | − { "EA_IOWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, | |
| 5713 | − REG_FIELD_MASK(GCEA_EDC_CNT, IOWR_DATAMEM_SED_COUNT), 0 }, | |
| 5714 | − { "GMIRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | |
| 5715 | − REG_FIELD_MASK(GCEA_EDC_CNT2, GMIRD_CMDMEM_SEC_COUNT), | |
| 5716 | − REG_FIELD_MASK(GCEA_EDC_CNT2, GMIRD_CMDMEM_DED_COUNT) }, | |
| 5717 | − { "GMIWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | |
| 5718 | − REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_CMDMEM_SEC_COUNT), | |
| 5719 | − REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_CMDMEM_DED_COUNT) }, | |
| 5720 | − { "GMIWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | |
| 5721 | − REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_DATAMEM_SEC_COUNT), | |
| 5722 | − REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_DATAMEM_DED_COUNT) }, | |
| 5723 | − { "GMIRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | |
| 5724 | − REG_FIELD_MASK(GCEA_EDC_CNT2, GMIRD_PAGEMEM_SED_COUNT), 0 }, | |
| 5725 | − { "GMIWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | |
| 5726 | − REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_PAGEMEM_SED_COUNT), 0 }, | |
| 5727 | − { "MAM_D0MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | |
| 5728 | − REG_FIELD_MASK(GCEA_EDC_CNT2, MAM_D0MEM_SED_COUNT), 0 }, | |
| 5729 | − { "MAM_D1MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | |
| 5730 | − REG_FIELD_MASK(GCEA_EDC_CNT2, MAM_D1MEM_SED_COUNT), 0 }, | |
| 5731 | − { "MAM_D2MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | |
| 5732 | − REG_FIELD_MASK(GCEA_EDC_CNT2, MAM_D2MEM_SED_COUNT), 0 }, | |
| 5733 | − { "MAM_D3MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, | |
| 5734 | − REG_FIELD_MASK(GCEA_EDC_CNT2, MAM_D3MEM_SED_COUNT), 0 }, | |
| 5730 | + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_WRITE_DATA_BUF_SEC_COUNT), | |
| 5731 | + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_WRITE_DATA_BUF_DED_COUNT) | |
| 5732 | + }, | |
| 5733 | + { "SQC_DATA_CU2_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), | |
| 5734 | + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_SEC_COUNT), | |
| 5735 | + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_DED_COUNT) | |
| 5736 | + }, | |
| 5737 | + { "SQC_INST_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), | |
| 5738 | + SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_SEC_COUNT), | |
| 5739 | + SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_DED_COUNT) | |
| 5740 | + }, | |
| 5741 | + { "SQC_INST_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), | |
| 5742 | + SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_SEC_COUNT), | |
| 5743 | + SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_DED_COUNT) | |
| 5744 | + }, | |
| 5745 | + { "SQC_DATA_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), | |
| 5746 | + SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_SEC_COUNT), | |
| 5747 | + SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_DED_COUNT) | |
| 5748 | + }, | |
| 5749 | + { "SQC_DATA_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), | |
| 5750 | + SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_SEC_COUNT), | |
| 5751 | + SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_DED_COUNT) | |
| 5752 | + }, | |
| 5753 | + { "SQC_INST_BANKA_UTCL1_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), | |
| 5754 | + SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_UTCL1_MISS_FIFO_SED_COUNT), | |
| 5755 | + 0, 0 | |
| 5756 | + }, | |
| 5757 | + { "SQC_INST_BANKA_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), | |
| 5758 | + SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_MISS_FIFO_SED_COUNT), | |
| 5759 | + 0, 0 | |
| 5760 | + }, | |
| 5761 | + { "SQC_DATA_BANKA_HIT_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), | |
| 5762 | + SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_HIT_FIFO_SED_COUNT), | |
| 5763 | + 0, 0 | |
| 5764 | + }, | |
| 5765 | + { "SQC_DATA_BANKA_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), | |
| 5766 | + SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_MISS_FIFO_SED_COUNT), | |
| 5767 | + 0, 0 | |
| 5768 | + }, | |
| 5769 | + { "SQC_DATA_BANKA_DIRTY_BIT_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), | |
| 5770 | + SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_DIRTY_BIT_RAM_SED_COUNT), | |
| 5771 | + 0, 0 | |
| 5772 | + }, | |
| 5773 | + { "SQC_INST_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), | |
| 5774 | + SOC15_REG_FIELD(SQC_EDC_CNT2, INST_UTCL1_LFIFO_SEC_COUNT), | |
| 5775 | + SOC15_REG_FIELD(SQC_EDC_CNT2, INST_UTCL1_LFIFO_DED_COUNT) | |
| 5776 | + }, | |
| 5777 | + { "SQC_INST_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), | |
| 5778 | + SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_SEC_COUNT), | |
| 5779 | + SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_DED_COUNT) | |
| 5780 | + }, | |
| 5781 | + { "SQC_INST_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), | |
| 5782 | + SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_SEC_COUNT), | |
| 5783 | + SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_DED_COUNT) | |
| 5784 | + }, | |
| 5785 | + { "SQC_DATA_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), | |
| 5786 | + SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_SEC_COUNT), | |
| 5787 | + SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_DED_COUNT) | |
| 5788 | + }, | |
| 5789 | + { "SQC_DATA_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), | |
| 5790 | + SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_SEC_COUNT), | |
| 5791 | + SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_DED_COUNT) | |
| 5792 | + }, | |
| 5793 | + { "SQC_INST_BANKB_UTCL1_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), | |
| 5794 | + SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_UTCL1_MISS_FIFO_SED_COUNT), | |
| 5795 | + 0, 0 | |
| 5796 | + }, | |
| 5797 | + { "SQC_INST_BANKB_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), | |
| 5798 | + SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_MISS_FIFO_SED_COUNT), | |
| 5799 | + 0, 0 | |
| 5800 | + }, | |
| 5801 | + { "SQC_DATA_BANKB_HIT_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), | |
| 5802 | + SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_HIT_FIFO_SED_COUNT), | |
| 5803 | + 0, 0 | |
| 5804 | + }, | |
| 5805 | + { "SQC_DATA_BANKB_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), | |
| 5806 | + SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_MISS_FIFO_SED_COUNT), | |
| 5807 | + 0, 0 | |
| 5808 | + }, | |
| 5809 | + { "SQC_DATA_BANKB_DIRTY_BIT_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), | |
| 5810 | + SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_DIRTY_BIT_RAM_SED_COUNT), | |
| 5811 | + 0, 0 | |
| 5812 | + }, | |
| 5813 | + { "EA_DRAMRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), | |
| 5814 | + SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT), | |
| 5815 | + SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT) | |
| 5816 | + }, | |
| 5817 | + { "EA_DRAMWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), | |
| 5818 | + SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_CMDMEM_SEC_COUNT), | |
| 5819 | + SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_CMDMEM_DED_COUNT) | |
| 5820 | + }, | |
| 5821 | + { "EA_DRAMWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), | |
| 5822 | + SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_DATAMEM_SEC_COUNT), | |
| 5823 | + SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_DATAMEM_DED_COUNT) | |
| 5824 | + }, | |
| 5825 | + { "EA_RRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), | |
| 5826 | + SOC15_REG_FIELD(GCEA_EDC_CNT, RRET_TAGMEM_SEC_COUNT), | |
| 5827 | + SOC15_REG_FIELD(GCEA_EDC_CNT, RRET_TAGMEM_DED_COUNT) | |
| 5828 | + }, | |
| 5829 | + { "EA_WRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), | |
| 5830 | + SOC15_REG_FIELD(GCEA_EDC_CNT, WRET_TAGMEM_SEC_COUNT), | |
| 5831 | + SOC15_REG_FIELD(GCEA_EDC_CNT, WRET_TAGMEM_DED_COUNT) | |
| 5832 | + }, | |
| 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 | 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 | 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 | 6141 | static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev, |
| 5784 | 6142 | void *ras_error_status) |
| 5785 | 6143 | { |
| 5786 | 6144 | struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status; |
| 5787 | − uint32_t sec_count, ded_count; | |
| 5788 | − uint32_t i; | |
| 6145 | + uint32_t sec_count = 0, ded_count = 0; | |
| 6146 | + uint32_t i, j, k; | |
| 5789 | 6147 | uint32_t reg_value; |
| 5790 | − uint32_t se_id, instance_id; | |
| 5791 | 6148 | |
| 5792 | 6149 | if (adev->asic_type != CHIP_VEGA20) |
| 5793 | 6150 | return -EINVAL; |
| @@ -5796,52 +6153,29 @@ static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev, · 2 unmodified lines | ||
| 5796 | 6153 | err_data->ce_count = 0; |
| 5797 | 6154 | |
| 5798 | 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) { | |
| 5832 | − DRM_INFO( | |
| 5833 | − "Instance[%d][%d]: SubBlock %s, DED %d\n", | |
| 5834 | − se_id, instance_id, | |
| 5835 | − gfx_ras_edc_regs[i].name, | |
| 5836 | − ded_count); | |
| 5837 | − err_data->ue_count++; | |
| 5838 | − } | |
| 6157 | + for (i = 0; i < ARRAY_SIZE(sec_ded_counter_registers); i++) { | |
| 6158 | + for (j = 0; j < sec_ded_counter_registers[i].se_num; j++) { | |
| 6159 | + for (k = 0; k < sec_ded_counter_registers[i].instance; k++) { | |
| 6160 | + gfx_v9_0_select_se_sh(adev, j, 0, k); | |
| 6161 | + reg_value = | |
| 6162 | + RREG32(SOC15_REG_ENTRY_OFFSET(sec_ded_counter_registers[i])); | |
| 6163 | + if (reg_value) | |
| 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 | 6174 | gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); |
| 5843 | 6175 | mutex_unlock(&adev->grbm_idx_mutex); |
| 5844 | 6176 | |
| 6177 | + gfx_v9_0_query_utc_edc_status(adev, err_data); | |
| 6178 | + | |
| 5845 | 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 | 1138 | static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) |
| 1139 | 1139 | { |
| 1140 | − int r, i; | |
| 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)); | |
| 1140 | + int r; | |
| 1147 | 1141 | |
| 1148 | 1142 | if (adev->gart.bo == NULL) { |
| 1149 | 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 | 1147 | if (r) |
| 1154 | 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 | 1150 | r = gfxhub_v1_0_gart_enable(adev); |
| 1166 | 1151 | if (r) |
| 1167 | 1152 | return r; |
| @@ -1173,6 +1158,49 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) · 5 unmodified lines | ||
| 1173 | 1158 | if (r) |
| 1174 | 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 | 1204 | WREG32_FIELD15(HDP, 0, HDP_MISC_CNTL, FLUSH_INVALIDATE_CACHE, 1); |
| 1177 | 1205 | |
| 1178 | 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 | 1229 | if (adev->umc.funcs && adev->umc.funcs->init_registers) |
| 1202 | 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 | 1232 | r = gmc_v9_0_gart_enable(adev); |
| 1230 | 1233 | |
| 1231 | 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 | 512 | const struct amdgpu_nbio_funcs nbio_v7_4_funcs = { |
| 506 | 513 | .get_hdp_flush_req_offset = nbio_v7_4_get_hdp_flush_req_offset, |
| 507 | 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 | 523 | .enable_doorbell_aperture = nbio_v7_4_enable_doorbell_aperture, |
| 517 | 524 | .enable_doorbell_selfring_aperture = nbio_v7_4_enable_doorbell_selfring_aperture, |
| 518 | 525 | .ih_doorbell_range = nbio_v7_4_ih_doorbell_range, |
| 526 | + .enable_doorbell_interrupt = nbio_v7_4_enable_doorbell_interrupt, | |
| 519 | 527 | .update_medium_grain_clock_gating = nbio_v7_4_update_medium_grain_clock_gating, |
| 520 | 528 | .update_medium_grain_light_sleep = nbio_v7_4_update_medium_grain_light_sleep, |
| 521 | 529 | .get_clockgating_state = nbio_v7_4_get_clockgating_state, |
| @@ -40,6 +40,9 @@ · 39 unmodified lines | ||
| 40 | 40 | MODULE_FIRMWARE("amdgpu/raven_asd.bin"); |
| 41 | 41 | MODULE_FIRMWARE("amdgpu/picasso_asd.bin"); |
| 42 | 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 | 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 | 58 | #define mmRLC_GPM_UCODE_DATA_NV10 0x5b62 |
| 59 | 59 | #define mmSDMA0_UCODE_ADDR_NV10 0x5880 |
| 60 | 60 | #define mmSDMA0_UCODE_DATA_NV10 0x5881 |
| 61 | +/* memory training timeout define */ | |
| 62 | +#define MEM_TRAIN_SEND_MSG_TIMEOUT_US 3000000 | |
| 61 | 63 | |
| 62 | 64 | static int psp_v11_0_init_microcode(struct psp_context *psp) |
| 63 | 65 | { |
| @@ -206,18 +208,26 @@ out: · 142 unmodified lines | ||
| 206 | 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 | 221 | static int psp_v11_0_bootloader_load_kdb(struct psp_context *psp) |
| 210 | 222 | { |
| 211 | 223 | int ret; |
| 212 | 224 | uint32_t psp_gfxdrv_command_reg = 0; |
| 213 | 225 | struct amdgpu_device *adev = psp->adev; |
| 214 | − uint32_t sol_reg; | |
| 215 | 226 | |
| 216 | 227 | /* Check tOS sign of life register to confirm sys driver and sOS |
| 217 | 228 | * are already been loaded. |
| 218 | 229 | */ |
| 219 | − sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); | |
| 220 | − if (sol_reg) { | |
| 230 | + if (psp_v11_0_is_sos_alive(psp)) { | |
| 221 | 231 | psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58); |
| 222 | 232 | dev_info(adev->dev, "sos fw version = 0x%x.\n", psp->sos_fw_version); |
| 223 | 233 | return 0; |
| @@ -253,13 +263,11 @@ static int psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp) · 29 unmodified lines | ||
| 253 | 263 | int ret; |
| 254 | 264 | uint32_t psp_gfxdrv_command_reg = 0; |
| 255 | 265 | struct amdgpu_device *adev = psp->adev; |
| 256 | − uint32_t sol_reg; | |
| 257 | 266 | |
| 258 | 267 | /* Check sOS sign of life register to confirm sys driver and sOS |
| 259 | 268 | * are already been loaded. |
| 260 | 269 | */ |
| 261 | − sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); | |
| 262 | − if (sol_reg) { | |
| 270 | + if (psp_v11_0_is_sos_alive(psp)) { | |
| 263 | 271 | psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58); |
| 264 | 272 | dev_info(adev->dev, "sos fw version = 0x%x.\n", psp->sos_fw_version); |
| 265 | 273 | return 0; |
| @@ -297,13 +305,11 @@ static int psp_v11_0_bootloader_load_sos(struct psp_context *psp) · 31 unmodified lines | ||
| 297 | 305 | int ret; |
| 298 | 306 | unsigned int psp_gfxdrv_command_reg = 0; |
| 299 | 307 | struct amdgpu_device *adev = psp->adev; |
| 300 | − uint32_t sol_reg; | |
| 301 | 308 | |
| 302 | 309 | /* Check sOS sign of life register to confirm sys driver and sOS |
| 303 | 310 | * are already been loaded. |
| 304 | 311 | */ |
| 305 | − sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); | |
| 306 | − if (sol_reg) | |
| 312 | + if (psp_v11_0_is_sos_alive(psp)) | |
| 307 | 313 | return 0; |
| 308 | 314 | |
| 309 | 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 | 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 | 1063 | static const struct psp_funcs psp_v11_0_funcs = { |
| 902 | 1064 | .init_microcode = psp_v11_0_init_microcode, |
| 903 | 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 | 1080 | .ras_trigger_error = psp_v11_0_ras_trigger_error, |
| 919 | 1081 | .ras_cure_posion = psp_v11_0_ras_cure_posion, |
| 920 | 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 | 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 | 1793 | if ((adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs && |
| 1794 | 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 | 1796 | amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, false); |
| 1797 | 1797 | |
| 1798 | 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 | 479 | static int soc15_asic_get_baco_capability(struct amdgpu_device *adev, bool *cap) |
| 480 | 480 | { |
| 481 | − void *pp_handle = adev->powerplay.pp_handle; | |
| 482 | − const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; | |
| 481 | + if (is_support_sw_smu(adev)) { | |
| 482 | + struct smu_context *smu = &adev->smu; | |
| 483 | 483 | |
| 484 | − if (!pp_funcs || !pp_funcs->get_asic_baco_capability) { | |
| 485 | − *cap = false; | |
| 486 | − return -ENOENT; | |
| 487 | − } | |
| 484 | + *cap = smu_baco_is_support(smu); | |
| 485 | + return 0; | |
| 486 | + } else { | |
| 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 | 499 | static int soc15_asic_baco_reset(struct amdgpu_device *adev) |
| 493 | 500 | { |
| 494 | − void *pp_handle = adev->powerplay.pp_handle; | |
| 495 | − const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; | |
| 501 | + struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); | |
| 496 | 502 | |
| 497 | − if (!pp_funcs ||!pp_funcs->get_asic_baco_state ||!pp_funcs->set_asic_baco_state) | |
| 498 | − return -ENOENT; | |
| 503 | + /* avoid NBIF got stuck when do RAS recovery in BACO reset */ | |
| 504 | + if (ras && ras->supported) | |
| 505 | + adev->nbio.funcs->enable_doorbell_interrupt(adev, false); | |
| 499 | 506 | |
| 500 | − /* enter BACO state */ | |
| 501 | − if (pp_funcs->set_asic_baco_state(pp_handle, 1)) | |
| 502 | − return -EIO; | |
| 507 | + dev_info(adev->dev, "GPU BACO reset\n"); | |
| 503 | 508 | |
| 504 | − /* exit BACO state */ | |
| 505 | − if (pp_funcs->set_asic_baco_state(pp_handle, 0)) | |
| 506 | − return -EIO; | |
| 509 | + if (is_support_sw_smu(adev)) { | |
| 510 | + struct smu_context *smu = &adev->smu; | |
| 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 | 534 | return 0; |
| 513 | 535 | } |
| @@ -67,6 +67,8 @@ struct soc15_allowed_register_entry { · 66 unmodified lines | ||
| 67 | 67 | #define SOC15_REG_GOLDEN_VALUE(ip, inst, reg, and_mask, or_mask) \ |
| 68 | 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 | 72 | void soc15_grbm_select(struct amdgpu_device *adev, |
| 71 | 73 | u32 me, u32 pipe, u32 queue, u32 vmid); |
| 72 | 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 | 206 | * Open up a stream for HW test |
| 207 | 207 | */ |
| 208 | 208 | static int uvd_v6_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, |
| 209 | + struct amdgpu_bo *bo, | |
| 209 | 210 | struct dma_fence **fence) |
| 210 | 211 | { |
| 211 | 212 | const unsigned ib_size_dw = 16; |
| 212 | 213 | struct amdgpu_job *job; |
| 213 | 214 | struct amdgpu_ib *ib; |
| 214 | 215 | struct dma_fence *f = NULL; |
| 215 | − uint64_t dummy; | |
| 216 | + uint64_t addr; | |
| 216 | 217 | int i, r; |
| 217 | 218 | |
| 218 | 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 | 221 | return r; |
| 221 | 222 | |
| 222 | 223 | ib = &job->ibs[0]; |
| 223 | − dummy = ib->gpu_addr + 1024; | |
| 224 | + addr = amdgpu_bo_gpu_offset(bo); | |
| 224 | 225 | |
| 225 | 226 | ib->length_dw = 0; |
| 226 | 227 | ib->ptr[ib->length_dw++] = 0x00000018; |
| 227 | 228 | ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ |
| 228 | 229 | ib->ptr[ib->length_dw++] = handle; |
| 229 | 230 | ib->ptr[ib->length_dw++] = 0x00010000; |
| 230 | − ib->ptr[ib->length_dw++] = upper_32_bits(dummy); | |
| 231 | − ib->ptr[ib->length_dw++] = dummy; | |
| 231 | + ib->ptr[ib->length_dw++] = upper_32_bits(addr); | |
| 232 | + ib->ptr[ib->length_dw++] = addr; | |
| 232 | 233 | |
| 233 | 234 | ib->ptr[ib->length_dw++] = 0x00000014; |
| 234 | 235 | ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ |
| @@ -268,13 +269,14 @@ err: · 33 unmodified lines | ||
| 268 | 269 | */ |
| 269 | 270 | static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, |
| 270 | 271 | uint32_t handle, |
| 272 | + struct amdgpu_bo *bo, | |
| 271 | 273 | struct dma_fence **fence) |
| 272 | 274 | { |
| 273 | 275 | const unsigned ib_size_dw = 16; |
| 274 | 276 | struct amdgpu_job *job; |
| 275 | 277 | struct amdgpu_ib *ib; |
| 276 | 278 | struct dma_fence *f = NULL; |
| 277 | − uint64_t dummy; | |
| 279 | + uint64_t addr; | |
| 278 | 280 | int i, r; |
| 279 | 281 | |
| 280 | 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 | 284 | return r; |
| 283 | 285 | |
| 284 | 286 | ib = &job->ibs[0]; |
| 285 | − dummy = ib->gpu_addr + 1024; | |
| 287 | + addr = amdgpu_bo_gpu_offset(bo); | |
| 286 | 288 | |
| 287 | 289 | ib->length_dw = 0; |
| 288 | 290 | ib->ptr[ib->length_dw++] = 0x00000018; |
| 289 | 291 | ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ |
| 290 | 292 | ib->ptr[ib->length_dw++] = handle; |
| 291 | 293 | ib->ptr[ib->length_dw++] = 0x00010000; |
| 292 | − ib->ptr[ib->length_dw++] = upper_32_bits(dummy); | |
| 293 | − ib->ptr[ib->length_dw++] = dummy; | |
| 294 | + ib->ptr[ib->length_dw++] = upper_32_bits(addr); | |
| 295 | + ib->ptr[ib->length_dw++] = addr; | |
| 294 | 296 | |
| 295 | 297 | ib->ptr[ib->length_dw++] = 0x00000014; |
| 296 | 298 | ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ |
| @@ -327,13 +329,20 @@ err: · 30 unmodified lines | ||
| 327 | 329 | static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) |
| 328 | 330 | { |
| 329 | 331 | struct dma_fence *fence = NULL; |
| 332 | + struct amdgpu_bo *bo = NULL; | |
| 330 | 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 | 342 | if (r) |
| 334 | 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 | 346 | if (r) |
| 338 | 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 | 355 | error: |
| 347 | 356 | dma_fence_put(fence); |
| 357 | + amdgpu_bo_unreserve(bo); | |
| 358 | + amdgpu_bo_unref(&bo); | |
| 348 | 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 | 214 | * Open up a stream for HW test |
| 215 | 215 | */ |
| 216 | 216 | static int uvd_v7_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, |
| 217 | + struct amdgpu_bo *bo, | |
| 217 | 218 | struct dma_fence **fence) |
| 218 | 219 | { |
| 219 | 220 | const unsigned ib_size_dw = 16; |
| 220 | 221 | struct amdgpu_job *job; |
| 221 | 222 | struct amdgpu_ib *ib; |
| 222 | 223 | struct dma_fence *f = NULL; |
| 223 | − uint64_t dummy; | |
| 224 | + uint64_t addr; | |
| 224 | 225 | int i, r; |
| 225 | 226 | |
| 226 | 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 | 229 | return r; |
| 229 | 230 | |
| 230 | 231 | ib = &job->ibs[0]; |
| 231 | − dummy = ib->gpu_addr + 1024; | |
| 232 | + addr = amdgpu_bo_gpu_offset(bo); | |
| 232 | 233 | |
| 233 | 234 | ib->length_dw = 0; |
| 234 | 235 | ib->ptr[ib->length_dw++] = 0x00000018; |
| 235 | 236 | ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ |
| 236 | 237 | ib->ptr[ib->length_dw++] = handle; |
| 237 | 238 | ib->ptr[ib->length_dw++] = 0x00000000; |
| 238 | − ib->ptr[ib->length_dw++] = upper_32_bits(dummy); | |
| 239 | − ib->ptr[ib->length_dw++] = dummy; | |
| 239 | + ib->ptr[ib->length_dw++] = upper_32_bits(addr); | |
| 240 | + ib->ptr[ib->length_dw++] = addr; | |
| 240 | 241 | |
| 241 | 242 | ib->ptr[ib->length_dw++] = 0x00000014; |
| 242 | 243 | ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ |
| @@ -275,13 +276,14 @@ err: · 32 unmodified lines | ||
| 275 | 276 | * Close up a stream for HW test or if userspace failed to do so |
| 276 | 277 | */ |
| 277 | 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 | 282 | const unsigned ib_size_dw = 16; |
| 281 | 283 | struct amdgpu_job *job; |
| 282 | 284 | struct amdgpu_ib *ib; |
| 283 | 285 | struct dma_fence *f = NULL; |
| 284 | − uint64_t dummy; | |
| 286 | + uint64_t addr; | |
| 285 | 287 | int i, r; |
| 286 | 288 | |
| 287 | 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 | 291 | return r; |
| 290 | 292 | |
| 291 | 293 | ib = &job->ibs[0]; |
| 292 | − dummy = ib->gpu_addr + 1024; | |
| 294 | + addr = amdgpu_bo_gpu_offset(bo); | |
| 293 | 295 | |
| 294 | 296 | ib->length_dw = 0; |
| 295 | 297 | ib->ptr[ib->length_dw++] = 0x00000018; |
| 296 | 298 | ib->ptr[ib->length_dw++] = 0x00000001; |
| 297 | 299 | ib->ptr[ib->length_dw++] = handle; |
| 298 | 300 | ib->ptr[ib->length_dw++] = 0x00000000; |
| 299 | − ib->ptr[ib->length_dw++] = upper_32_bits(dummy); | |
| 300 | − ib->ptr[ib->length_dw++] = dummy; | |
| 301 | + ib->ptr[ib->length_dw++] = upper_32_bits(addr); | |
| 302 | + ib->ptr[ib->length_dw++] = addr; | |
| 301 | 303 | |
| 302 | 304 | ib->ptr[ib->length_dw++] = 0x00000014; |
| 303 | 305 | ib->ptr[ib->length_dw++] = 0x00000002; |
| @@ -334,13 +336,20 @@ err: · 30 unmodified lines | ||
| 334 | 336 | static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) |
| 335 | 337 | { |
| 336 | 338 | struct dma_fence *fence = NULL; |
| 339 | + struct amdgpu_bo *bo = NULL; | |
| 337 | 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 | 349 | if (r) |
| 341 | 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 | 353 | if (r) |
| 345 | 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 | 362 | error: |
| 354 | 363 | dma_fence_put(fence); |
| 364 | + amdgpu_bo_unreserve(bo); | |
| 365 | + amdgpu_bo_unref(&bo); | |
| 355 | 366 | return r; |
| 356 | 367 | } |
| 357 | 368 | |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | #include "amdgpu.h" |
| 27 | 27 | #include "amdgpu_vcn.h" |
| 28 | +#include "amdgpu_pm.h" | |
| 28 | 29 | #include "soc15.h" |
| 29 | 30 | #include "soc15d.h" |
| 30 | 31 | #include "vcn_v2_0.h" |
| @@ -709,6 +710,9 @@ static int vcn_v2_5_start(struct amdgpu_device *adev) · 678 unmodified lines | ||
| 709 | 710 | uint32_t rb_bufsz, tmp; |
| 710 | 711 | int i, j, k, r; |
| 711 | 712 | |
| 713 | + if (adev->pm.dpm_enabled) | |
| 714 | + amdgpu_dpm_enable_uvd(adev, true); | |
| 715 | + | |
| 712 | 716 | for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { |
| 713 | 717 | if (adev->vcn.harvest_config & (1 << i)) |
| 714 | 718 | continue; |
| @@ -939,6 +943,9 @@ static int vcn_v2_5_stop(struct amdgpu_device *adev) · 224 unmodified lines | ||
| 939 | 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 | 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 | 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 | 729 | * @adev: amdgpu_device pointer |
| 696 | 730 | * |
| 697 | − * Look up which blocks are hung and attempt | |
| 698 | − * to reset them. | |
| 731 | + * Use PCI Config method to reset the GPU. | |
| 732 | + * | |
| 699 | 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 | 737 | int r; |
| 704 | 738 | |
| @@ -714,7 +748,47 @@ static int vi_asic_reset(struct amdgpu_device *adev) · 9 unmodified lines | ||
| 714 | 748 | static enum amd_reset_method |
| 715 | 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 | 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 | 31 | int vi_set_ip_blocks(struct amdgpu_device *adev); |
| 32 | 32 | |
| 33 | 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 | 37 | #endif |
| @@ -3396,7 +3396,8 @@ static void fill_stream_properties_from_drm_display_mode( · 3395 unmodified lines | ||
| 3396 | 3396 | struct dc_crtc_timing *timing_out = &stream->timing; |
| 3397 | 3397 | const struct drm_display_info *info = &connector->display_info; |
| 3398 | 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 | 3402 | timing_out->h_border_left = 0; |
| 3402 | 3403 | timing_out->h_border_right = 0; |
| @@ -3433,6 +3434,13 @@ static void fill_stream_properties_from_drm_display_mode( · 30 unmodified lines | ||
| 3433 | 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 | 3444 | timing_out->h_addressable = mode_in->crtc_hdisplay; |
| 3437 | 3445 | timing_out->h_total = mode_in->crtc_htotal; |
| 3438 | 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 | 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 | 3667 | list_for_each_entry(preferred_mode, &aconnector->base.modes, head) { |
| 3657 | 3668 | /* Search for preferred mode */ |
| 3658 | 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 | 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 | 3744 | finish: |
| 3731 | 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 | 124 | /* Configure dithering */ |
| 125 | − if (!dm_need_crc_dither(source)) | |
| 125 | + if (!dm_need_crc_dither(source)) { | |
| 126 | 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 | 130 | dc_stream_set_dither_option(stream_state, |
| 129 | 131 | DITHER_OPTION_DEFAULT); |
| 132 | + dc_stream_set_dyn_expansion(stream_state->ctx->dc, stream_state, | |
| 133 | + DYN_EXPANSION_AUTO); | |
| 134 | + } | |
| 130 | 135 | |
| 131 | 136 | unlock: |
| 132 | 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 | 589 | if (pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges) |
| 590 | 590 | pp_funcs->set_watermarks_for_clocks_ranges(pp_handle, |
| 591 | 591 | &wm_with_clock_ranges); |
| 592 | − else if (adev->smu.funcs && | |
| 593 | − adev->smu.funcs->set_watermarks_for_clock_ranges) | |
| 592 | + else | |
| 594 | 593 | smu_set_watermarks_for_clock_ranges(&adev->smu, |
| 595 | − &wm_with_clock_ranges); | |
| 594 | + &wm_with_clock_ranges); | |
| 596 | 595 | } |
| 597 | 596 | |
| 598 | 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 | 665 | const struct dc_context *ctx = pp->dm; |
| 667 | 666 | struct amdgpu_device *adev = ctx->driver_context; |
| 668 | − struct smu_context *smu = &adev->smu; | |
| 669 | 667 | struct dm_pp_wm_sets_with_clock_ranges_soc15 wm_with_clock_ranges; |
| 670 | 668 | struct dm_pp_clock_range_for_dmif_wm_set_soc15 *wm_dce_clocks = |
| 671 | 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 | 706 | ranges->writer_wm_sets[i].min_drain_clk_mhz * 1000; |
| 709 | 707 | } |
| 710 | 708 | |
| 711 | − if (!smu->funcs) | |
| 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; | |
| 709 | + smu_set_watermarks_for_clock_ranges(&adev->smu, &wm_with_clock_ranges); | |
| 720 | 710 | |
| 721 | 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 | 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 | 978 | void dm_pp_get_funcs( |
| 905 | 979 | struct dc_context *ctx, |
| 906 | 980 | struct pp_smu_funcs *funcs) |
| @@ -945,6 +1019,15 @@ void dm_pp_get_funcs( · 38 unmodified lines | ||
| 945 | 1019 | funcs->nv_funcs.set_pstate_handshake_support = pp_nv_set_pstate_handshake_support; |
| 946 | 1020 | break; |
| 947 | 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 | 1031 | default: |
| 949 | 1032 | DRM_ERROR("smu version is not supported !\n"); |
| 950 | 1033 | break; |
| @@ -2543,7 +2543,6 @@ static enum bp_result construct_integrated_info( · 2542 unmodified lines | ||
| 2543 | 2543 | |
| 2544 | 2544 | /* Sort voltage table from low to high*/ |
| 2545 | 2545 | if (result == BP_RESULT_OK) { |
| 2546 | − struct clock_voltage_caps temp = {0, 0}; | |
| 2547 | 2546 | uint32_t i; |
| 2548 | 2547 | uint32_t j; |
| 2549 | 2548 | |
| @@ -2553,10 +2552,8 @@ static enum bp_result construct_integrated_info( · 3 unmodified lines | ||
| 2553 | 2552 | info->disp_clk_voltage[j].max_supported_clk < |
| 2554 | 2553 | info->disp_clk_voltage[j-1].max_supported_clk) { |
| 2555 | 2554 | /* swap j and j - 1*/ |
| 2556 | − temp = info->disp_clk_voltage[j-1]; | |
| 2557 | − info->disp_clk_voltage[j-1] = | |
| 2558 | − info->disp_clk_voltage[j]; | |
| 2559 | − info->disp_clk_voltage[j] = temp; | |
| 2555 | + swap(info->disp_clk_voltage[j - 1], | |
| 2556 | + info->disp_clk_voltage[j]); | |
| 2560 | 2557 | } |
| 2561 | 2558 | } |
| 2562 | 2559 | } |
| @@ -1613,8 +1613,6 @@ static enum bp_result construct_integrated_info( · 1612 unmodified lines | ||
| 1613 | 1613 | |
| 1614 | 1614 | struct atom_common_table_header *header; |
| 1615 | 1615 | struct atom_data_revision revision; |
| 1616 | − | |
| 1617 | − struct clock_voltage_caps temp = {0, 0}; | |
| 1618 | 1616 | uint32_t i; |
| 1619 | 1617 | uint32_t j; |
| 1620 | 1618 | |
| @@ -1644,10 +1642,8 @@ static enum bp_result construct_integrated_info( · 23 unmodified lines | ||
| 1644 | 1642 | info->disp_clk_voltage[j-1].max_supported_clk |
| 1645 | 1643 | ) { |
| 1646 | 1644 | /* swap j and j - 1*/ |
| 1647 | − temp = info->disp_clk_voltage[j-1]; | |
| 1648 | − info->disp_clk_voltage[j-1] = | |
| 1649 | − info->disp_clk_voltage[j]; | |
| 1650 | − info->disp_clk_voltage[j] = temp; | |
| 1645 | + swap(info->disp_clk_voltage[j - 1], | |
| 1646 | + info->disp_clk_voltage[j]); | |
| 1651 | 1647 | } |
| 1652 | 1648 | } |
| 1653 | 1649 | } |
| @@ -65,6 +65,31 @@ int clk_mgr_helper_get_active_display_cnt( · 64 unmodified lines | ||
| 65 | 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 | 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 | 375 | static struct clk_mgr_funcs dcn2_funcs = { |
| 353 | 376 | .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, |
| 354 | 377 | .update_clocks = dcn2_update_clocks, |
| 355 | 378 | .init_clocks = dcn2_init_clocks, |
| 356 | 379 | .enable_pme_wa = dcn2_enable_pme_wa, |
| 357 | 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 | 50 | enum dc_clock_type clock_type, |
| 51 | 51 | struct dc_clock_config *clock_cfg); |
| 52 | 52 | |
| 53 | +void dcn20_update_clocks_update_dentist(struct clk_mgr_internal *clk_mgr); | |
| 53 | 54 | #endif //__DCN20_CLK_MGR_H__ |
| @@ -52,6 +52,45 @@ · 51 unmodified lines | ||
| 52 | 52 | #define REG(reg_name) \ |
| 53 | 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 | 94 | void rn_update_clocks(struct clk_mgr *clk_mgr_base, |
| 56 | 95 | struct dc_state *context, |
| 57 | 96 | bool safe_to_lower) |
| @@ -62,17 +101,36 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base, · 4 unmodified lines | ||
| 62 | 101 | int display_count; |
| 63 | 102 | bool update_dppclk = false; |
| 64 | 103 | bool update_dispclk = false; |
| 65 | − bool enter_display_off = false; | |
| 66 | 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) | |
| 72 | − enter_display_off = true; | |
| 108 | + if (dc->work_arounds.skip_clock_update) | |
| 109 | + return; | |
| 73 | 110 | |
| 74 | − if (enter_display_off == safe_to_lower) { | |
| 75 | − rn_vbios_smu_set_display_count(clk_mgr, display_count); | |
| 111 | + /* | |
| 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 | 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 | 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 | 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 | 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 | 399 | static struct clk_mgr_funcs dcn21_funcs = { |
| 333 | 400 | .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, |
| 334 | 401 | .update_clocks = rn_update_clocks, |
| 335 | − .init_clocks = dcn2_init_clocks, | |
| 402 | + .init_clocks = rn_init_clocks, | |
| 336 | 403 | .enable_pme_wa = rn_enable_pme_wa, |
| 337 | 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 | 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 | 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 | 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++) { | |
| 472 | − if (clock_table->FClocks[i].Freq == 0) | |
| 553 | + /* Find lowest DPM, FCLK is filled in reverse order*/ | |
| 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 | 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; | |
| 476 | − bw_params->clk_table.entries[i].fclk_mhz = clock_table->FClocks[i].Freq; | |
| 477 | − bw_params->clk_table.entries[i].memclk_mhz = clock_table->MemClocks[i].Freq; | |
| 478 | − bw_params->clk_table.entries[i].socclk_mhz = clock_table->SocClocks[i].Freq; | |
| 479 | − bw_params->clk_table.entries[i].voltage = clock_table->FClocks[i].Vol; | |
| 570 | + for (i = 0; i < bw_params->clk_table.num_entries; i++, j--) { | |
| 571 | + bw_params->clk_table.entries[i].fclk_mhz = clock_table->FClocks[j].Freq; | |
| 572 | + bw_params->clk_table.entries[i].memclk_mhz = clock_table->MemClocks[j].Freq; | |
| 573 | + bw_params->clk_table.entries[i].voltage = clock_table->FClocks[j].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 | 577 | bw_params->vram_type = asic_id->vram_type; |
| 484 | 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 | 580 | for (i = 0; i < WM_SET_COUNT; i++) { |
| 487 | 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 | 584 | bw_params->wm_table.entries[i].valid = false; |
| 491 | 585 | continue; |
| 492 | 586 | } |
| @@ -547,25 +641,24 @@ void rn_clk_mgr_construct( · 54 unmodified lines | ||
| 547 | 641 | clk_mgr->dentist_vco_freq_khz = 3600000; |
| 548 | 642 | |
| 549 | 643 | rn_dump_clk_registers(&s, &clk_mgr->base, &log_info); |
| 550 | − clk_mgr->base.dprefclk_khz = s.dprefclk; | |
| 551 | − | |
| 552 | − if (clk_mgr->base.dprefclk_khz != 600000) { | |
| 553 | − clk_mgr->base.dprefclk_khz = 600000; | |
| 554 | − ASSERT(1); //TODO: Renoir follow up. | |
| 555 | − } | |
| 644 | + /* Convert dprefclk units from MHz to KHz */ | |
| 645 | + /* Value already divided by 10, some resolution lost */ | |
| 646 | + clk_mgr->base.dprefclk_khz = s.dprefclk * 1000; | |
| 556 | 647 | |
| 557 | 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 | 651 | clk_mgr->base.dprefclk_khz = 600000; |
| 652 | + } | |
| 560 | 653 | } |
| 561 | 654 | |
| 562 | 655 | dce_clock_read_ss_info(clk_mgr); |
| 563 | 656 | |
| 564 | 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 | 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 | 669 | if (!debug->disable_pplib_wm_range) { |
| 577 | 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 | 674 | /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */ |
| 582 | 675 | if (pp_smu && pp_smu->rn_funcs.set_wm_ranges) |
| 583 | 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 */ | |
| 587 | − if (!debug->disable_48mhz_pwrdwn) | |
| 588 | − rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(clk_mgr); | |
| 679 | + if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment) && clk_mgr->smu_ver >= 0x00371500) { | |
| 680 | + /* enable powerfeatures when displaycount goes to 0 */ | |
| 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 | 26 | #ifndef __RN_CLK_MGR_H__ |
| 27 | 27 | #define __RN_CLK_MGR_H__ |
| 28 | 28 | |
| 29 | +#include "clk_mgr.h" | |
| 30 | +#include "dm_pp_smu.h" | |
| 31 | + | |
| 29 | 32 | struct rn_clk_registers { |
| 30 | 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 | 43 | void rn_clk_mgr_construct(struct dc_context *ctx, |
| 35 | 44 | struct clk_mgr_internal *clk_mgr, |
| 36 | 45 | struct pp_smu_funcs *pp_smu, |
| @@ -33,7 +33,7 @@ · 32 unmodified lines | ||
| 33 | 33 | #include "mp/mp_12_0_0_sh_mask.h" |
| 34 | 34 | |
| 35 | 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 | 38 | #define FN(reg_name, field) \ |
| 39 | 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 | 84 | int actual_dispclk_set_mhz = -1; |
| 85 | 85 | struct dc *core_dc = clk_mgr->base.ctx->dc; |
| 86 | 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 | 88 | /* Unit of SMU msg parameter is Mhz */ |
| 93 | 89 | actual_dispclk_set_mhz = rn_vbios_smu_send_msg_with_param( |
| 94 | 90 | clk_mgr, |
| 95 | 91 | VBIOSSMC_MSG_SetDispclkFreq, |
| 96 | − clk); | |
| 92 | + requested_dispclk_khz / 1000); | |
| 97 | 93 | |
| 98 | 94 | if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) { |
| 99 | 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 | 121 | int actual_dcfclk_set_mhz = -1; |
| 126 | 122 | |
| 127 | − if (clk_mgr->smu_ver < 0xFFFFFFFF) | |
| 123 | + if (clk_mgr->smu_ver < 0x370c00) | |
| 128 | 124 | return actual_dcfclk_set_mhz; |
| 129 | 125 | |
| 130 | 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 | 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 | 139 | return actual_min_ds_dcfclk_mhz; |
| 144 | 140 | |
| 145 | 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 | 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 | 161 | actual_dppclk_set_mhz = rn_vbios_smu_send_msg_with_param( |
| 171 | 162 | clk_mgr, |
| 172 | 163 | VBIOSSMC_MSG_SetDppclkFreq, |
| 173 | − clk); | |
| 164 | + requested_dpp_khz / 1000); | |
| 174 | 165 | |
| 175 | 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 | 178 | rn_vbios_smu_send_msg_with_param( |
| 181 | − clk_mgr, | |
| 182 | − VBIOSSMC_MSG_SetDisplayCount, | |
| 183 | − display_count); | |
| 179 | + clk_mgr, | |
| 180 | + VBIOSSMC_MSG_SetDisplayCount, | |
| 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 | 186 | rn_vbios_smu_send_msg_with_param( |
| 189 | 187 | clk_mgr, |
| 190 | 188 | VBIOSSMC_MSG_EnableTmdp48MHzRefclkPwrDown, |
| 191 | − 0); | |
| 189 | + enable); | |
| 192 | 190 | } |
| 193 | 191 | |
| 194 | 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 | 33 | int rn_vbios_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz); |
| 34 | 34 | void rn_vbios_smu_set_phyclk(struct clk_mgr_internal *clk_mgr, int requested_phyclk_khz); |
| 35 | 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); | |
| 37 | −void rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr); | |
| 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, bool enable); | |
| 38 | 38 | void rn_vbios_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr); |
| 39 | 39 | |
| 40 | 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 | 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 | 435 | void dc_stream_set_dither_option(struct dc_stream_state *stream, |
| 415 | 436 | enum dc_dither_option option) |
| 416 | 437 | { |
| @@ -918,15 +939,11 @@ static void program_timing_sync( · 501 unmodified lines | ||
| 918 | 939 | |
| 919 | 940 | /* set first pipe with plane as master */ |
| 920 | 941 | for (j = 0; j < group_size; j++) { |
| 921 | − struct pipe_ctx *temp; | |
| 922 | − | |
| 923 | 942 | if (pipe_set[j]->plane_state) { |
| 924 | 943 | if (j == 0) |
| 925 | 944 | break; |
| 926 | 945 | |
| 927 | − temp = pipe_set[0]; | |
| 928 | − pipe_set[0] = pipe_set[j]; | |
| 929 | − pipe_set[j] = temp; | |
| 946 | + swap(pipe_set[0], pipe_set[j]); | |
| 930 | 947 | break; |
| 931 | 948 | } |
| 932 | 949 | } |
| @@ -983,6 +1000,10 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc, · 50 unmodified lines | ||
| 983 | 1000 | struct dc_crtc_timing *crtc_timing) |
| 984 | 1001 | { |
| 985 | 1002 | struct timing_generator *tg; |
| 1003 | + struct stream_encoder *se = NULL; | |
| 1004 | + | |
| 1005 | + struct dc_crtc_timing hw_crtc_timing = {0}; | |
| 1006 | + | |
| 986 | 1007 | struct dc_link *link = sink->link; |
| 987 | 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 | 1024 | for (i = 0; i < dc->res_pool->stream_enc_count; i++) { |
| 1004 | 1025 | if (dc->res_pool->stream_enc[i]->id == enc_inst) { |
| 1026 | + | |
| 1027 | + se = dc->res_pool->stream_enc[i]; | |
| 1028 | + | |
| 1005 | 1029 | tg_inst = dc->res_pool->stream_enc[i]->funcs->dig_source_otg( |
| 1006 | 1030 | dc->res_pool->stream_enc[i]); |
| 1007 | 1031 | break; |
| @@ -1017,10 +1041,46 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc, · 9 unmodified lines | ||
| 1017 | 1041 | |
| 1018 | 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 | 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 | 1084 | return false; |
| 1025 | 1085 | |
| 1026 | 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 | 1093 | if (crtc_timing->pix_clk_100hz != pix_clk_100hz) |
| 1034 | 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 | 1112 | return true; |
| @@ -1660,8 +1734,16 @@ enum surface_update_type dc_check_update_surfaces_for_stream( · 621 unmodified lines | ||
| 1660 | 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) | |
| 1664 | − dc->optimized_required = true; | |
| 1737 | + if (type == UPDATE_TYPE_FAST) { | |
| 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 | 1748 | return type; |
| 1667 | 1749 | } |
| @@ -743,7 +743,8 @@ static bool wait_for_alt_mode(struct dc_link *link) · 742 unmodified lines | ||
| 743 | 743 | * This does not create remote sinks but will trigger DM |
| 744 | 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 | 749 | struct dc_sink_init_data sink_init_data = { 0 }; |
| 749 | 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 | 760 | bool same_dpcd = true; |
| 760 | 761 | enum dc_connection_type new_connection_type = dc_connection_none; |
| 761 | 762 | bool perform_dp_seamless_boot = false; |
| 763 | + | |
| 762 | 764 | DC_LOGGER_INIT(link->ctx->logger); |
| 763 | 765 | |
| 764 | 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 | 873 | * empty which leads to allocate_mst_payload() has "0" |
| 872 | 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 | 878 | if (prev_sink != NULL) |
| 876 | 879 | dc_sink_release(prev_sink); |
| 877 | 880 | return false; |
| @@ -1065,6 +1068,23 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) · 187 unmodified lines | ||
| 1065 | 1068 | dc_sink_release(prev_sink); |
| 1066 | 1069 | |
| 1067 | 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 | 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 | 1531 | pipe_ctx->stream_res.pix_clk_params.requested_sym_clk = |
| 1512 | 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 | 1534 | state->clk_mgr->funcs->update_clocks(state->clk_mgr, state, false); |
| 1515 | 1535 | |
| 1516 | 1536 | dp_enable_link_phy( |
| @@ -2237,7 +2257,7 @@ static bool dp_active_dongle_validate_timing( · 720 unmodified lines | ||
| 2237 | 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 | 2261 | dongle_caps->extendedCapValid == false) |
| 2242 | 2262 | return true; |
| 2243 | 2263 | |
| @@ -2401,13 +2421,17 @@ bool dc_link_set_abm_disable(const struct dc_link *link) · 157 unmodified lines | ||
| 2401 | 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 | 2426 | struct dc *core_dc = link->ctx->dc; |
| 2407 | 2427 | struct dmcu *dmcu = core_dc->res_pool->dmcu; |
| 2408 | 2428 | |
| 2409 | − if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_enabled) | |
| 2410 | − dmcu->funcs->set_psr_enable(dmcu, enable, wait); | |
| 2429 | + | |
| 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 | 2436 | return true; |
| 2413 | 2437 | } |
| @@ -2718,6 +2742,10 @@ void core_link_enable_stream( · 304 unmodified lines | ||
| 2718 | 2742 | enum dc_status status; |
| 2719 | 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 | 2749 | if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) { |
| 2722 | 2750 | stream->link->link_enc->funcs->setup( |
| 2723 | 2751 | stream->link->link_enc, |
| @@ -2860,6 +2888,10 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx) · 136 unmodified lines | ||
| 2860 | 2888 | struct dc_stream_state *stream = pipe_ctx->stream; |
| 2861 | 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 | 2895 | #if defined(CONFIG_DRM_AMD_DC_HDCP) |
| 2864 | 2896 | update_psp_stream_config(pipe_ctx, true); |
| 2865 | 2897 | #endif |
| @@ -634,6 +634,20 @@ bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc, · 633 unmodified lines | ||
| 634 | 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 | 651 | /*test only function*/ |
| 638 | 652 | void dal_ddc_service_set_ddc_pin( |
| 639 | 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 | 1409 | if (link->link_enc->features.flags.bits.IS_HBR3_CAPABLE) |
| 1410 | 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 | 1415 | /* Lower link settings based on sink's link cap */ |
| 1413 | 1416 | if (link->reported_link_cap.lane_count < max_link_cap.lane_count) |
| 1414 | 1417 | max_link_cap.lane_count = |
| @@ -1653,11 +1656,14 @@ bool dp_verify_link_cap_with_retries( · 238 unmodified lines | ||
| 1653 | 1656 | |
| 1654 | 1657 | for (i = 0; i < attempts; i++) { |
| 1655 | 1658 | int fail_count = 0; |
| 1656 | − enum dc_connection_type type; | |
| 1659 | + enum dc_connection_type type = dc_connection_none; | |
| 1657 | 1660 | |
| 1658 | 1661 | memset(&link->verified_link_cap, 0, |
| 1659 | 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 | 1667 | break; |
| 1662 | 1668 | } else if (dp_verify_link_cap(link, |
| 1663 | 1669 | &link->reported_link_cap, |
| @@ -1670,6 +1676,19 @@ bool dp_verify_link_cap_with_retries( · 6 unmodified lines | ||
| 1670 | 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 | 1692 | static struct dc_link_settings get_common_supported_link_settings( |
| 1674 | 1693 | struct dc_link_settings link_setting_a, |
| 1675 | 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 | 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 | 2081 | union dpcd_psr_configuration psr_configuration; |
| 2063 | 2082 | |
| 2064 | − if (!link->psr_enabled) | |
| 2083 | + if (!link->psr_feature_enabled) | |
| 2065 | 2084 | return false; |
| 2066 | 2085 | |
| 2067 | 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 | 2119 | sizeof(psr_error_status.raw)); |
| 2101 | 2120 | |
| 2102 | 2121 | /* PSR error, disable and re-enable PSR */ |
| 2103 | − dc_link_set_psr_enable(link, false, true); | |
| 2104 | − dc_link_set_psr_enable(link, true, true); | |
| 2122 | + dc_link_set_psr_allow_active(link, false, true); | |
| 2123 | + dc_link_set_psr_allow_active(link, true, true); | |
| 2105 | 2124 | |
| 2106 | 2125 | return true; |
| 2107 | 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 | 2575 | uint8_t data, struct dc_link *link) |
| 2557 | 2576 | { |
| 2558 | 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 | 2580 | /* decode converter info*/ |
| 2561 | 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 | 2722 | * keep receiver powered all the time.*/ |
| 2703 | 2723 | case DP_BRANCH_DEVICE_ID_0010FA: |
| 2704 | 2724 | case DP_BRANCH_DEVICE_ID_0080E1: |
| 2725 | + case DP_BRANCH_DEVICE_ID_00E04C: | |
| 2705 | 2726 | link->wa_flags.dp_keep_receiver_powered = true; |
| 2706 | 2727 | break; |
| 2707 | 2728 | |
| @@ -423,10 +423,10 @@ bool dc_stream_add_writeback(struct dc *dc, · 422 unmodified lines | ||
| 423 | 423 | |
| 424 | 424 | if (dwb->funcs->is_enabled(dwb)) { |
| 425 | 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 | 427 | } else { |
| 428 | 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 | 39 | #include "inc/hw/dmcu.h" |
| 40 | 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 | 44 | #define MAX_SURFACES 3 |
| 45 | 45 | #define MAX_PLANES 6 |
| @@ -111,6 +111,7 @@ struct dc_caps { · 65 unmodified lines | ||
| 111 | 111 | bool force_dp_tps4_for_cp2520; |
| 112 | 112 | bool disable_dp_clk_share; |
| 113 | 113 | bool psp_setup_panel_mode; |
| 114 | + bool extended_aux_timeout_support; | |
| 114 | 115 | #ifdef CONFIG_DRM_AMD_DC_DCN2_0 |
| 115 | 116 | bool hw_3d_lut; |
| 116 | 117 | #endif |
| @@ -220,6 +221,7 @@ struct dc_config { · 103 unmodified lines | ||
| 220 | 221 | bool power_down_display_on_boot; |
| 221 | 222 | bool edp_not_connected; |
| 222 | 223 | bool forced_clocks; |
| 224 | + bool disable_extended_timeout_support; // Used to disable extended timeout and lttpr feature as well | |
| 223 | 225 | bool multi_mon_pp_mclk_switch; |
| 224 | 226 | }; |
| 225 | 227 | |
| @@ -245,6 +247,18 @@ enum wm_report_mode { · 19 unmodified lines | ||
| 245 | 247 | WM_REPORT_DEFAULT = 0, |
| 246 | 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 | 264 | * For any clocks that may differ per pipe |
| @@ -260,12 +274,13 @@ struct dc_clocks { · 9 unmodified lines | ||
| 260 | 274 | int phyclk_khz; |
| 261 | 275 | int dramclk_khz; |
| 262 | 276 | bool p_state_change_support; |
| 263 | − | |
| 277 | + enum dcn_pwr_state pwr_state; | |
| 264 | 278 | /* |
| 265 | 279 | * Elements below are not compared for the purposes of |
| 266 | 280 | * optimization required |
| 267 | 281 | */ |
| 268 | 282 | bool prev_p_state_change_support; |
| 283 | + enum dtm_pstate dtm_level; | |
| 269 | 284 | int max_supported_dppclk_khz; |
| 270 | 285 | int max_supported_dispclk_khz; |
| 271 | 286 | int bw_dppclk_khz; /*a copy of dppclk_khz*/ |
| @@ -578,6 +578,11 @@ enum dc_quantization_range { · 577 unmodified lines | ||
| 578 | 578 | QUANTIZATION_RANGE_LIMITED |
| 579 | 579 | }; |
| 580 | 580 | |
| 581 | +enum dc_dynamic_expansion { | |
| 582 | + DYN_EXPANSION_AUTO, | |
| 583 | + DYN_EXPANSION_DISABLE | |
| 584 | +}; | |
| 585 | + | |
| 581 | 586 | /* XFM */ |
| 582 | 587 | |
| 583 | 588 | /* used in struct dc_plane_state */ |
| @@ -126,7 +126,8 @@ struct dc_link { · 125 unmodified lines | ||
| 126 | 126 | unsigned short chip_caps; |
| 127 | 127 | unsigned int dpcd_sink_count; |
| 128 | 128 | enum edp_revision edp_revision; |
| 129 | − bool psr_enabled; | |
| 129 | + bool psr_feature_enabled; | |
| 130 | + bool psr_allow_active; | |
| 130 | 131 | |
| 131 | 132 | /* MST record stream using this link */ |
| 132 | 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 | 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 | 174 | /* Set backlight level of an embedded panel (eDP, LVDS). |
| 162 | 175 | * backlight_pwm_u16_16 is unsigned 32 bit with 16 bit integer |
| 163 | 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 | 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 | 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 | 451 | int num_streams, |
| 452 | 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 | 457 | void dc_stream_set_dither_option(struct dc_stream_state *stream, |
| 455 | 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 | 77 | /* notifyDMCUMsg */ |
| 78 | 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 | 83 | return true; |
| 81 | 84 | } |
| 82 | 85 | |
| @@ -42,6 +42,10 @@ · 41 unmodified lines | ||
| 42 | 42 | |
| 43 | 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 | 49 | #define FROM_AUX_ENGINE(ptr) \ |
| 46 | 50 | container_of((ptr), struct aux_engine_dce110, base) |
| 47 | 51 | |
| @@ -55,6 +59,14 @@ enum { · 7 unmodified lines | ||
| 55 | 59 | AUX_TIMED_OUT_RETRY_COUNTER = 2, |
| 56 | 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 | 70 | static void release_engine( |
| 59 | 71 | struct dce_aux *engine) |
| 60 | 72 | { |
| @@ -198,7 +210,7 @@ static void submit_channel_request( · 137 unmodified lines | ||
| 198 | 210 | REG_UPDATE(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, 1); |
| 199 | 211 | |
| 200 | 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 | 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 | 340 | /* poll to make sure that SW_DONE is asserted */ |
| 329 | 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 | 344 | value = REG_READ(AUX_SW_STATUS); |
| 333 | 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 | 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 | 482 | struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110, |
| 418 | 483 | struct dc_context *ctx, |
| 419 | 484 | uint32_t inst, |
| 420 | 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 | 491 | aux_engine110->base.ddc = NULL; |
| 424 | 492 | aux_engine110->base.ctx = ctx; |
| 425 | 493 | aux_engine110->base.delay = 0; |
| 426 | 494 | aux_engine110->base.max_defer_write_retry = 0; |
| 427 | 495 | aux_engine110->base.inst = inst; |
| 428 | − aux_engine110->timeout_period = timeout_period; | |
| 496 | + aux_engine110->polling_timeout_period = timeout_period; | |
| 429 | 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 | 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 | 549 | aux_req.action = i2caux_action_from_payload(payload); |
| 476 | 550 | |
| 477 | 551 | aux_req.address = payload->address; |
| 478 | − aux_req.delay = payload->defer_delay * 10; | |
| 552 | + aux_req.delay = 0; | |
| 479 | 553 | aux_req.length = payload->length; |
| 480 | 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 | 618 | case AUX_TRANSACTION_REPLY_AUX_DEFER: |
| 545 | 619 | case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK: |
| 546 | 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 | 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 | 630 | break; |
| 550 | 631 | |
| 551 | 632 | case AUX_TRANSACTION_REPLY_I2C_DEFER: |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include "i2caux_interface.h" |
| 30 | 30 | #include "inc/hw/aux_engine.h" |
| 31 | 31 | |
| 32 | + | |
| 32 | 33 | #ifdef CONFIG_DRM_AMD_DC_DCN2_0 |
| 33 | 34 | #define AUX_COMMON_REG_LIST0(id)\ |
| 34 | 35 | SRI(AUX_CONTROL, DP_AUX, id), \ |
| @@ -36,6 +37,7 @@ · 1 unmodified line | ||
| 36 | 37 | SRI(AUX_SW_DATA, DP_AUX, id), \ |
| 37 | 38 | SRI(AUX_SW_CONTROL, DP_AUX, id), \ |
| 38 | 39 | SRI(AUX_INTERRUPT_CONTROL, DP_AUX, id), \ |
| 40 | + SRI(AUX_DPHY_RX_CONTROL1, DP_AUX, id), \ | |
| 39 | 41 | SRI(AUX_SW_STATUS, DP_AUX, id) |
| 40 | 42 | #endif |
| 41 | 43 | |
| @@ -55,6 +57,7 @@ struct dce110_aux_registers { · 13 unmodified lines | ||
| 55 | 57 | uint32_t AUX_SW_DATA; |
| 56 | 58 | uint32_t AUX_SW_CONTROL; |
| 57 | 59 | uint32_t AUX_INTERRUPT_CONTROL; |
| 60 | + uint32_t AUX_DPHY_RX_CONTROL1; | |
| 58 | 61 | uint32_t AUX_SW_STATUS; |
| 59 | 62 | uint32_t AUXN_IMPCAL; |
| 60 | 63 | uint32_t AUXP_IMPCAL; |
| @@ -62,6 +65,156 @@ struct dce110_aux_registers { · 1 unmodified line | ||
| 62 | 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 | 218 | enum { /* This is the timeout as defined in DP 1.2a, |
| 66 | 219 | * 2.3.4 "Detailed uPacket TX AUX CH State Description". |
| 67 | 220 | */ |
| @@ -97,20 +250,34 @@ struct dce_aux { · 29 unmodified lines | ||
| 97 | 250 | uint32_t max_defer_write_retry; |
| 98 | 251 | |
| 99 | 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 | 265 | struct aux_engine_dce110 { |
| 103 | 266 | struct dce_aux base; |
| 104 | 267 | const struct dce110_aux_registers *regs; |
| 268 | + const struct dce110_aux_registers_mask *mask; | |
| 269 | + const struct dce110_aux_registers_shift *shift; | |
| 105 | 270 | struct { |
| 106 | 271 | uint32_t aux_control; |
| 107 | 272 | uint32_t aux_arb_control; |
| 108 | 273 | uint32_t aux_sw_data; |
| 109 | 274 | uint32_t aux_sw_control; |
| 110 | 275 | uint32_t aux_interrupt_control; |
| 276 | + uint32_t aux_dphy_rx_control1; | |
| 277 | + uint32_t aux_dphy_rx_control0; | |
| 111 | 278 | uint32_t aux_sw_status; |
| 112 | 279 | } addr; |
| 113 | − uint32_t timeout_period; | |
| 280 | + uint32_t polling_timeout_period; | |
| 114 | 281 | }; |
| 115 | 282 | |
| 116 | 283 | struct aux_engine_dce110_init_data { |
| @@ -120,12 +287,15 @@ struct aux_engine_dce110_init_data { · 3 unmodified lines | ||
| 120 | 287 | const struct dce110_aux_registers *regs; |
| 121 | 288 | }; |
| 122 | 289 | |
| 123 | −struct dce_aux *dce110_aux_engine_construct( | |
| 124 | − struct aux_engine_dce110 *aux_engine110, | |
| 290 | +struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110, | |
| 125 | 291 | struct dc_context *ctx, |
| 126 | 292 | uint32_t inst, |
| 127 | 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 | 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 | 310 | bool dce_aux_transfer_with_retries(struct ddc_service *ddc, |
| 141 | 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 | 321 | #endif |
| @@ -679,6 +679,7 @@ struct dce_hwseq_registers { · 678 unmodified lines | ||
| 679 | 679 | HWS_SF(, DOMAIN17_PG_STATUS, DOMAIN17_PGFSM_PWR_STATUS, mask_sh), \ |
| 680 | 680 | HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \ |
| 681 | 681 | HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ |
| 682 | + HWSEQ_LVTMA_MASK_SH_LIST(mask_sh), \ | |
| 682 | 683 | HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ |
| 683 | 684 | HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh) |
| 684 | 685 | #endif |
| @@ -506,6 +506,14 @@ static const struct dce_mem_input_mask mi_masks = { · 505 unmodified lines | ||
| 506 | 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 | 517 | static struct mem_input *dce100_mem_input_create( |
| 510 | 518 | struct dc_context *ctx, |
| 511 | 519 | uint32_t inst) |
| @@ -611,7 +619,10 @@ struct dce_aux *dce100_aux_engine_create( · 99 unmodified lines | ||
| 611 | 619 | |
| 612 | 620 | dce110_aux_engine_construct(aux_engine, ctx, inst, |
| 613 | 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 | 627 | return &aux_engine->base; |
| 617 | 628 | } |
| @@ -997,6 +1008,8 @@ static bool construct( · 379 unmodified lines | ||
| 997 | 1008 | dc->caps.max_cursor_size = 128; |
| 998 | 1009 | dc->caps.dual_link_dvi = true; |
| 999 | 1010 | dc->caps.disable_dp_clk_share = true; |
| 1011 | + dc->caps.extended_aux_timeout_support = false; | |
| 1012 | + | |
| 1000 | 1013 | for (i = 0; i < pool->base.pipe_count; i++) { |
| 1001 | 1014 | pool->base.timing_generators[i] = |
| 1002 | 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 || | |
| 1165 | − pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { | |
| 1164 | + if (state->clk_mgr && | |
| 1165 | + (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT || | |
| 1166 | + pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)) { | |
| 1166 | 1167 | audio_output->pll_info.dp_dto_source_clock_in_khz = |
| 1167 | 1168 | state->clk_mgr->funcs->get_dp_ref_clk_frequency( |
| 1168 | 1169 | state->clk_mgr); |
| @@ -1410,7 +1411,7 @@ static enum dc_status apply_single_controller_ctx_to_hw( · 241 unmodified lines | ||
| 1410 | 1411 | |
| 1411 | 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 | 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 | 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 | 1525 | static struct dc_link *get_edp_link_with_sink( |
| 1537 | 1526 | struct dc *dc, |
| 1538 | 1527 | struct dc_state *context) |
| @@ -1826,7 +1815,7 @@ static bool should_enable_fbc(struct dc *dc, · 287 unmodified lines | ||
| 1826 | 1815 | return false; |
| 1827 | 1816 | |
| 1828 | 1817 | /* PSR should not be enabled */ |
| 1829 | − if (pipe_ctx->stream->link->psr_enabled) | |
| 1818 | + if (pipe_ctx->stream->link->psr_feature_enabled) | |
| 1830 | 1819 | return false; |
| 1831 | 1820 | |
| 1832 | 1821 | /* Nothing to compress */ |
| @@ -275,6 +275,14 @@ static const struct dce_stream_encoder_mask se_mask = { · 274 unmodified lines | ||
| 275 | 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 | 286 | #define opp_regs(id)\ |
| 279 | 287 | [id] = {\ |
| 280 | 288 | OPP_DCE_110_REG_LIST(id),\ |
| @@ -657,7 +665,10 @@ struct dce_aux *dce110_aux_engine_create( · 376 unmodified lines | ||
| 657 | 665 | |
| 658 | 666 | dce110_aux_engine_construct(aux_engine, ctx, inst, |
| 659 | 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 | 673 | return &aux_engine->base; |
| 663 | 674 | } |
| @@ -1293,6 +1304,7 @@ static bool construct( · 629 unmodified lines | ||
| 1293 | 1304 | dc->caps.i2c_speed_in_khz = 100; |
| 1294 | 1305 | dc->caps.max_cursor_size = 128; |
| 1295 | 1306 | dc->caps.is_apu = true; |
| 1307 | + dc->caps.extended_aux_timeout_support = false; | |
| 1296 | 1308 | |
| 1297 | 1309 | /************************************************* |
| 1298 | 1310 | * Create resources * |
| @@ -172,6 +172,14 @@ static const struct dce_abm_mask abm_mask = { · 171 unmodified lines | ||
| 172 | 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 | 183 | #define ipp_regs(id)\ |
| 176 | 184 | [id] = {\ |
| 177 | 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 | 639 | dce110_aux_engine_construct(aux_engine, ctx, inst, |
| 632 | 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 | 646 | return &aux_engine->base; |
| 636 | 647 | } |
| @@ -1163,7 +1174,7 @@ static bool construct( · 526 unmodified lines | ||
| 1163 | 1174 | dc->caps.i2c_speed_in_khz = 100; |
| 1164 | 1175 | dc->caps.max_cursor_size = 128; |
| 1165 | 1176 | dc->caps.dual_link_dvi = true; |
| 1166 | − | |
| 1177 | + dc->caps.extended_aux_timeout_support = false; | |
| 1167 | 1178 | |
| 1168 | 1179 | /************************************************* |
| 1169 | 1180 | * Create resources * |
| @@ -293,6 +293,14 @@ static const struct dce_stream_encoder_mask se_mask = { · 292 unmodified lines | ||
| 293 | 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 | 304 | #define opp_regs(id)\ |
| 297 | 305 | [id] = {\ |
| 298 | 306 | OPP_DCE_120_REG_LIST(id),\ |
| @@ -404,7 +412,10 @@ struct dce_aux *dce120_aux_engine_create( · 105 unmodified lines | ||
| 404 | 412 | |
| 405 | 413 | dce110_aux_engine_construct(aux_engine, ctx, inst, |
| 406 | 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 | 420 | return &aux_engine->base; |
| 410 | 421 | } |
| @@ -1006,7 +1017,7 @@ static bool construct( · 595 unmodified lines | ||
| 1006 | 1017 | dc->caps.max_cursor_size = 128; |
| 1007 | 1018 | dc->caps.dual_link_dvi = true; |
| 1008 | 1019 | dc->caps.psp_setup_panel_mode = true; |
| 1009 | − | |
| 1020 | + dc->caps.extended_aux_timeout_support = false; | |
| 1010 | 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 | 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 | 299 | #define aux_engine_regs(id)\ |
| 292 | 300 | [id] = {\ |
| 293 | 301 | AUX_COMMON_REG_LIST(id), \ |
| @@ -491,7 +499,10 @@ struct dce_aux *dce80_aux_engine_create( · 197 unmodified lines | ||
| 491 | 499 | |
| 492 | 500 | dce110_aux_engine_construct(aux_engine, ctx, inst, |
| 493 | 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 | 507 | return &aux_engine->base; |
| 497 | 508 | } |
| @@ -895,6 +906,7 @@ static bool dce80_construct( · 397 unmodified lines | ||
| 895 | 906 | dc->caps.i2c_speed_in_khz = 40; |
| 896 | 907 | dc->caps.max_cursor_size = 128; |
| 897 | 908 | dc->caps.dual_link_dvi = true; |
| 909 | + dc->caps.extended_aux_timeout_support = false; | |
| 898 | 910 | |
| 899 | 911 | /************************************************* |
| 900 | 912 | * Create resources * |
| @@ -129,7 +129,7 @@ void dpp_set_gamut_remap_bypass(struct dcn10_dpp *dpp) · 128 unmodified lines | ||
| 129 | 129 | |
| 130 | 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 | 133 | struct dpp *dpp, |
| 134 | 134 | struct scaler_data *scl_data, |
| 135 | 135 | const struct scaling_taps *in_taps) |
| @@ -521,7 +521,7 @@ static const struct dpp_funcs dcn10_dpp_funcs = { · 385 unmodified lines | ||
| 521 | 521 | .dpp_read_state = dpp_read_state, |
| 522 | 522 | .dpp_reset = dpp_reset, |
| 523 | 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 | 525 | .dpp_set_gamut_remap = dpp1_cm_set_gamut_remap, |
| 526 | 526 | .dpp_set_csc_adjustment = dpp1_cm_set_output_csc_adjustment, |
| 527 | 527 | .dpp_set_csc_default = dpp1_cm_set_output_csc_default, |
| @@ -1504,6 +1504,11 @@ void dpp1_set_hdr_multiplier( · 1503 unmodified lines | ||
| 1504 | 1504 | struct dpp *dpp_base, |
| 1505 | 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 | 1512 | void dpp1_construct(struct dcn10_dpp *dpp1, |
| 1508 | 1513 | struct dc_context *ctx, |
| 1509 | 1514 | uint32_t inst, |
| @@ -670,6 +670,10 @@ static void dcn10_bios_golden_init(struct dc *dc) · 669 unmodified lines | ||
| 670 | 670 | int i; |
| 671 | 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 | 677 | if (dc->res_pool->hubbub->funcs->is_allow_self_refresh_enabled) |
| 674 | 678 | allow_self_fresh_force_enable = |
| 675 | 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 | 1456 | DC_LOG_ALL_TF_CHANNELS("Logging all channels..."); |
| 1453 | 1457 | |
| 1454 | 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); | |
| 1456 | − DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu\n", 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); | |
| 1459 | + DC_LOG_GAMMA("R\t%d\t%llu", i, tf->tf_pts.red[i].value); | |
| 1460 | + DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu", i, tf->tf_pts.green[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 | 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); | |
| 1462 | − DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu\n", 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); | |
| 1465 | + DC_LOG_ALL_GAMMA("R\t%d\t%llu", i, tf->tf_pts.red[i].value); | |
| 1466 | + DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu", i, tf->tf_pts.green[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 | 2515 | pipe_ctx->stream_res.tg->funcs->set_vtg_params( |
| 2512 | 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 | 2524 | if (pipe_ctx->plane_state != NULL) |
| @@ -113,6 +113,20 @@ struct dcn10_link_enc_registers { · 112 unmodified lines | ||
| 113 | 113 | uint32_t DIG_LANE_ENABLE; |
| 114 | 114 | /* UNIPHY */ |
| 115 | 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 | 130 | /* indirect registers */ |
| 117 | 131 | uint32_t RAWLANE0_DIG_PCS_XF_RX_OVRD_IN_2; |
| 118 | 132 | uint32_t RAWLANE0_DIG_PCS_XF_RX_OVRD_IN_3; |
| @@ -250,6 +264,10 @@ struct dcn10_link_enc_registers { · 131 unmodified lines | ||
| 250 | 264 | type RDPCS_EXT_REFCLK_EN;\ |
| 251 | 265 | type RDPCS_TX_FIFO_EN;\ |
| 252 | 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 | 271 | type UNIPHY_CHANNEL0_INVERT;\ |
| 254 | 272 | type UNIPHY_CHANNEL1_INVERT;\ |
| 255 | 273 | type UNIPHY_CHANNEL2_INVERT;\ |
| @@ -337,16 +355,46 @@ struct dcn10_link_enc_registers { · 81 unmodified lines | ||
| 337 | 355 | type RDPCS_TX_FIFO_ERROR_MASK;\ |
| 338 | 356 | type RDPCS_DPALT_DISABLE_TOGGLE_MASK;\ |
| 339 | 357 | type RDPCS_DPALT_4LANE_TOGGLE_MASK;\ |
| 358 | + type RDPCS_PHY_DPALT_DP4;\ | |
| 340 | 359 | type RDPCS_PHY_DPALT_DISABLE;\ |
| 341 | 360 | type RDPCS_PHY_DPALT_DISABLE_ACK;\ |
| 342 | 361 | type RDPCS_PHY_DP_MPLLB_V2I;\ |
| 343 | 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 | 365 | type RDPCS_PHY_DP_MPLLB_CP_INT;\ |
| 345 | 366 | type RDPCS_PHY_DP_MPLLB_CP_PROP;\ |
| 346 | 367 | type RDPCS_PHY_RX_REF_LD_VAL;\ |
| 347 | 368 | type RDPCS_PHY_RX_VCO_LD_VAL;\ |
| 348 | 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 | 399 | #define DCN20_LINK_ENCODER_REG_FIELD_LIST(type) \ |
| 352 | 400 | type DIG_LANE0EN;\ |
| @@ -240,6 +240,9 @@ void opp1_set_dyn_expansion( · 239 unmodified lines | ||
| 240 | 240 | FMT_DYNAMIC_EXP_EN, 0, |
| 241 | 241 | FMT_DYNAMIC_EXP_MODE, 0); |
| 242 | 242 | |
| 243 | + if (opp->dyn_expansion == DYN_EXPANSION_DISABLE) | |
| 244 | + return; | |
| 245 | + | |
| 243 | 246 | /*00 - 10-bit -> 12-bit dynamic expansion*/ |
| 244 | 247 | /*01 - 8-bit -> 12-bit dynamic expansion*/ |
| 245 | 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 | 1230 | return ret; |
| 1231 | 1231 | } |
| 1232 | 1232 | |
| 1233 | −bool optc1_is_matching_timing(struct timing_generator *tg, | |
| 1234 | − const struct dc_crtc_timing *otg_timing) | |
| 1233 | +bool optc1_get_hw_timing(struct timing_generator *tg, | |
| 1234 | + struct dc_crtc_timing *hw_crtc_timing) | |
| 1235 | 1235 | { |
| 1236 | − struct dc_crtc_timing hw_crtc_timing = {0}; | |
| 1237 | 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 | 1239 | return false; |
| 1241 | 1240 | |
| 1242 | 1241 | optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s); |
| 1243 | 1242 | |
| 1244 | − 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); | |
| 1246 | − 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; | |
| 1243 | + hw_crtc_timing->h_total = s.h_total + 1; | |
| 1244 | + hw_crtc_timing->h_addressable = s.h_total - ((s.h_total - s.h_blank_start) + s.h_blank_end); | |
| 1245 | + hw_crtc_timing->h_front_porch = s.h_total + 1 - s.h_blank_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; | |
| 1250 | − 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; | |
| 1252 | − 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; | |
| 1248 | + hw_crtc_timing->v_total = s.v_total + 1; | |
| 1249 | + hw_crtc_timing->v_addressable = s.v_total - ((s.v_total - s.v_blank_start) + s.v_blank_end); | |
| 1250 | + hw_crtc_timing->v_front_porch = s.v_total + 1 - s.v_blank_start; | |
| 1251 | + hw_crtc_timing->v_sync_width = s.v_sync_a_end - s.v_sync_a_start; | |
| 1286 | 1252 | |
| 1287 | 1253 | return true; |
| 1288 | 1254 | } |
| @@ -1486,7 +1452,6 @@ static const struct timing_generator_funcs dcn10_tg_funcs = { · 197 unmodified lines | ||
| 1486 | 1452 | .get_frame_count = optc1_get_vblank_counter, |
| 1487 | 1453 | .get_scanoutpos = optc1_get_crtc_scanoutpos, |
| 1488 | 1454 | .get_otg_active_size = optc1_get_otg_active_size, |
| 1489 | − .is_matching_timing = optc1_is_matching_timing, | |
| 1490 | 1455 | .set_early_control = optc1_set_early_control, |
| 1491 | 1456 | /* used by enable_timing_synchronization. Not need for FPGA */ |
| 1492 | 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 | 1479 | .configure_crc = optc1_configure_crc, |
| 1515 | 1480 | .set_vtg_params = optc1_set_vtg_params, |
| 1516 | 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 | 1486 | void dcn10_timing_generator_init(struct optc *optc1) |
| @@ -547,9 +547,8 @@ struct dcn_otg_state { · 546 unmodified lines | ||
| 547 | 547 | void optc1_read_otg_state(struct optc *optc1, |
| 548 | 548 | struct dcn_otg_state *s); |
| 549 | 549 | |
| 550 | −bool optc1_is_matching_timing( | |
| 551 | − struct timing_generator *tg, | |
| 552 | − const struct dc_crtc_timing *otg_timing); | |
| 550 | +bool optc1_get_hw_timing(struct timing_generator *tg, | |
| 551 | + struct dc_crtc_timing *hw_crtc_timing); | |
| 553 | 552 | |
| 554 | 553 | bool optc1_validate_timing( |
| 555 | 554 | struct timing_generator *optc, |
| @@ -319,6 +319,14 @@ static const struct dcn10_link_enc_mask le_mask = { · 318 unmodified lines | ||
| 319 | 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 | 330 | #define ipp_regs(id)\ |
| 323 | 331 | [id] = {\ |
| 324 | 332 | IPP_REG_LIST_DCN10(id),\ |
| @@ -642,7 +650,10 @@ struct dce_aux *dcn10_aux_engine_create( · 317 unmodified lines | ||
| 642 | 650 | |
| 643 | 651 | dce110_aux_engine_construct(aux_engine, ctx, inst, |
| 644 | 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 | 658 | return &aux_engine->base; |
| 648 | 659 | } |
| @@ -1308,6 +1319,8 @@ static bool construct( · 659 unmodified lines | ||
| 1308 | 1319 | dc->caps.max_slave_planes = 1; |
| 1309 | 1320 | dc->caps.is_apu = true; |
| 1310 | 1321 | dc->caps.post_blend_color_processing = false; |
| 1322 | + dc->caps.extended_aux_timeout_support = false; | |
| 1323 | + | |
| 1311 | 1324 | /* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */ |
| 1312 | 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 | 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 | 1616 | static const struct stream_encoder_funcs dcn10_str_enc_funcs = { |
| 1557 | 1617 | .dp_set_stream_attribute = |
| 1558 | 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 | 1649 | .dig_connect_to_otg = enc1_dig_connect_to_otg, |
| 1590 | 1650 | .hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute, |
| 1591 | 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 | 1656 | void dcn10_stream_encoder_construct( |
| @@ -621,4 +621,9 @@ void get_audio_clock_info( · 620 unmodified lines | ||
| 621 | 621 | void enc1_reset_hdmi_stream_attribute( |
| 622 | 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 | 629 | #endif /* __DC_STREAM_ENCODER_DCN10_H__ */ |
| @@ -457,7 +457,7 @@ static struct dpp_funcs dcn20_dpp_funcs = { · 456 unmodified lines | ||
| 457 | 457 | .dpp_read_state = dpp20_read_state, |
| 458 | 458 | .dpp_reset = dpp_reset, |
| 459 | 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 | 461 | .dpp_set_gamut_remap = dpp1_cm_set_gamut_remap, |
| 462 | 462 | .dpp_set_csc_adjustment = NULL, |
| 463 | 463 | .dpp_set_csc_default = NULL, |
| @@ -705,11 +705,6 @@ void dpp2_set_hdr_multiplier( · 704 unmodified lines | ||
| 705 | 705 | struct dpp *dpp_base, |
| 706 | 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 | 708 | bool dpp2_construct(struct dcn20_dpp *dpp2, |
| 714 | 709 | struct dc_context *ctx, |
| 715 | 710 | uint32_t inst, |
| @@ -1370,6 +1370,9 @@ static void dcn20_program_pipe( · 1369 unmodified lines | ||
| 1370 | 1370 | |
| 1371 | 1371 | pipe_ctx->stream_res.tg->funcs->set_vtg_params( |
| 1372 | 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 | 1378 | if (pipe_ctx->update_flags.bits.odm) |
| @@ -1396,6 +1399,26 @@ static void dcn20_program_pipe( · 20 unmodified lines | ||
| 1396 | 1399 | */ |
| 1397 | 1400 | if (pipe_ctx->update_flags.bits.enable || pipe_ctx->stream->update_flags.bits.out_tf) |
| 1398 | 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 | 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 | 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 | 1609 | pipe_ctx->stream_res.tg->funcs->set_vtg_params( |
| 1583 | 1610 | pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing); |
| 1611 | + | |
| 1584 | 1612 | if (pipe_ctx->prev_odm_pipe == NULL) |
| 1585 | 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 | 1619 | pipe_ctx->plane_res.hubp->funcs->hubp_setup( |
| @@ -1599,7 +1630,8 @@ bool dcn20_update_bandwidth( · 10 unmodified lines | ||
| 1599 | 1630 | static void dcn20_enable_writeback( |
| 1600 | 1631 | struct dc *dc, |
| 1601 | 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 | 1636 | struct dwbc *dwb; |
| 1605 | 1637 | struct mcif_wb *mcif_wb; |
| @@ -1616,7 +1648,7 @@ static void dcn20_enable_writeback( · 10 unmodified lines | ||
| 1616 | 1648 | optc->funcs->set_dwb_source(optc, wb_info->dwb_pipe_inst); |
| 1617 | 1649 | /* set MCIF_WB buffer and arbitration configuration */ |
| 1618 | 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 | 1652 | /* Enable MCIF_WB */ |
| 1621 | 1653 | mcif_wb->funcs->enable_mcif(mcif_wb); |
| 1622 | 1654 | /* Enable DWB */ |
| @@ -2181,8 +2213,10 @@ static void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) · 558 unmodified lines | ||
| 2181 | 2213 | link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, |
| 2182 | 2214 | pipe_ctx->stream_res.stream_enc->id, true); |
| 2183 | 2215 | |
| 2184 | − if (link->dc->hwss.program_dmdata_engine) | |
| 2185 | − link->dc->hwss.program_dmdata_engine(pipe_ctx); | |
| 2216 | + if (pipe_ctx->plane_state && pipe_ctx->plane_state->flip_immediate != 1) { | |
| 2217 | + if (link->dc->hwss.program_dmdata_engine) | |
| 2218 | + link->dc->hwss.program_dmdata_engine(pipe_ctx); | |
| 2219 | + } | |
| 2186 | 2220 | |
| 2187 | 2221 | link->dc->hwss.update_info_frame(pipe_ctx); |
| 2188 | 2222 | |
| @@ -91,6 +91,13 @@ struct mpll_cfg { · 90 unmodified lines | ||
| 91 | 91 | uint32_t ref_range; |
| 92 | 92 | uint32_t ref_clk; |
| 93 | 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 | 103 | struct dpcssys_phy_seq_cfg { |
| @@ -460,7 +460,7 @@ static struct timing_generator_funcs dcn20_tg_funcs = { · 459 unmodified lines | ||
| 460 | 460 | .set_vtg_params = optc1_set_vtg_params, |
| 461 | 461 | .program_manual_trigger = optc2_program_manual_trigger, |
| 462 | 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 | 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 | 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 | 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 | 593 | #define dwbc_regs_dcn2(id)\ |
| @@ -732,6 +734,15 @@ static const struct dcn20_vmid_mask vmid_masks = { · 140 unmodified lines | ||
| 732 | 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 | 746 | #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT |
| 736 | 747 | #define dsc_regsDCN20(id)\ |
| 737 | 748 | [id] = {\ |
| @@ -922,7 +933,10 @@ struct dce_aux *dcn20_aux_engine_create( · 184 unmodified lines | ||
| 922 | 933 | |
| 923 | 934 | dce110_aux_engine_construct(aux_engine, ctx, inst, |
| 924 | 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 | 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 | 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 | 1173 | void dcn20_clock_source_destroy(struct clock_source **clk_src) |
| 1158 | 1174 | { |
| 1159 | 1175 | kfree(TO_DCE110_CLK_SRC(*clk_src)); |
| @@ -1892,7 +1908,7 @@ int dcn20_populate_dml_pipes_from_context( · 732 unmodified lines | ||
| 1892 | 1908 | break; |
| 1893 | 1909 | case PIXEL_ENCODING_YCBCR420: |
| 1894 | 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 | 1912 | break; |
| 1897 | 1913 | case PIXEL_ENCODING_YCBCR422: |
| 1898 | 1914 | if (true) /* todo */ |
| @@ -1906,6 +1922,11 @@ int dcn20_populate_dml_pipes_from_context( · 7 unmodified lines | ||
| 1906 | 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 | 1930 | /* todo: default max for now, until there is logic reflecting this in dc*/ |
| 1910 | 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 | 2224 | if (secondary_pipe == NULL) { |
| 2204 | 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 | 2228 | preferred_pipe_idx = j; |
| 2207 | 2229 | |
| 2208 | 2230 | if (res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) { |
| @@ -2555,6 +2577,10 @@ void dcn20_calculate_wm( · 346 unmodified lines | ||
| 2555 | 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 | 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 | 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 | 2585 | if (vlevel < 2) { |
| 2560 | 2586 | pipes[0].clks_cfg.voltage = 2; |
| @@ -2566,6 +2592,10 @@ void dcn20_calculate_wm( · 5 unmodified lines | ||
| 2566 | 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 | 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 | 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 | 2600 | if (vlevel < 3) { |
| 2571 | 2601 | pipes[0].clks_cfg.voltage = 3; |
| @@ -2577,6 +2607,10 @@ void dcn20_calculate_wm( · 5 unmodified lines | ||
| 2577 | 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 | 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 | 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 | 2615 | pipes[0].clks_cfg.voltage = vlevel; |
| 2582 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 2980 | if (pp_smu && *pp_smu) { |
| 2943 | 2981 | kfree(*pp_smu); |
| @@ -3322,6 +3360,7 @@ static bool construct( · 378 unmodified lines | ||
| 3322 | 3360 | dc->caps.post_blend_color_processing = true; |
| 3323 | 3361 | dc->caps.force_dp_tps4_for_cp2520 = true; |
| 3324 | 3362 | dc->caps.hw_3d_lut = true; |
| 3363 | + dc->caps.extended_aux_timeout_support = true; | |
| 3325 | 3364 | |
| 3326 | 3365 | if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) { |
| 3327 | 3366 | dc->debug = debug_defaults_drv; |
| @@ -95,9 +95,6 @@ struct display_stream_compressor *dcn20_dsc_create( · 94 unmodified lines | ||
| 95 | 95 | struct dc_context *ctx, uint32_t inst); |
| 96 | 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 | 98 | struct hubp *dcn20_hubp_create( |
| 102 | 99 | struct dc_context *ctx, |
| 103 | 100 | uint32_t inst); |
| @@ -578,6 +578,10 @@ static const struct stream_encoder_funcs dcn20_str_enc_funcs = { · 577 unmodified lines | ||
| 578 | 578 | .set_avmute = enc1_stream_encoder_set_avmute, |
| 579 | 579 | .dig_connect_to_otg = enc1_dig_connect_to_otg, |
| 580 | 580 | .dig_source_otg = enc1_dig_source_otg, |
| 581 | + | |
| 582 | + .dp_get_pixel_format = | |
| 583 | + enc1_stream_encoder_dp_get_pixel_format, | |
| 584 | + | |
| 581 | 585 | #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT |
| 582 | 586 | .enc_read_state = enc2_read_state, |
| 583 | 587 | .dp_set_dsc_config = enc2_dp_set_dsc_config, |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | # |
| 2 | 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 | 6 | ifneq ($(call cc-option, -mpreferred-stack-boundary=4),) |
| 7 | 7 | cc_stack_align := -mpreferred-stack-boundary=4 |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | * Authors: AMD |
| 23 | 23 | * |
| 24 | 24 | */ |
| 25 | +#include <linux/delay.h> | |
| 25 | 26 | #include "dm_services.h" |
| 26 | 27 | #include "dcn20/dcn20_hubbub.h" |
| 27 | 28 | #include "dcn21_hubbub.h" |
| @@ -51,7 +52,7 @@ · 23 unmodified lines | ||
| 51 | 52 | #ifdef NUM_VMID |
| 52 | 53 | #undef NUM_VMID |
| 53 | 54 | #endif |
| 54 | −#define NUM_VMID 1 | |
| 55 | +#define NUM_VMID 16 | |
| 55 | 56 | |
| 56 | 57 | static uint32_t convert_and_clamp( |
| 57 | 58 | uint32_t wm_ns, |
| @@ -71,56 +72,76 @@ static uint32_t convert_and_clamp( · 13 unmodified lines | ||
| 71 | 72 | void dcn21_dchvm_init(struct hubbub *hubbub) |
| 72 | 73 | { |
| 73 | 74 | struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); |
| 75 | + uint32_t riommu_active; | |
| 76 | + int i; | |
| 74 | 77 | |
| 75 | 78 | //Init DCHVM block |
| 76 | 79 | REG_UPDATE(DCHVM_CTRL0, HOSTVM_INIT_REQ, 1); |
| 77 | 80 | |
| 78 | 81 | //Poll until RIOMMU_ACTIVE = 1 |
| 79 | − //TODO: Figure out interval us and retry count | |
| 80 | − REG_WAIT(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, 1, 5, 100); | |
| 82 | + for (i = 0; i < 100; i++) { | |
| 83 | + REG_GET(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, &riommu_active); | |
| 81 | 84 | |
| 82 | − //Reflect the power status of DCHUBBUB | |
| 83 | − REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1); | |
| 85 | + if (riommu_active) | |
| 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 | |
| 86 | − REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1); | |
| 95 | + //Start rIOMMU prefetching | |
| 96 | + REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1); | |
| 87 | 97 | |
| 88 | − // Enable dynamic clock gating | |
| 89 | − REG_UPDATE_4(DCHVM_CLK_CTRL, | |
| 90 | − HVM_DISPCLK_R_GATE_DIS, 0, | |
| 91 | − HVM_DISPCLK_G_GATE_DIS, 0, | |
| 92 | − HVM_DCFCLK_R_GATE_DIS, 0, | |
| 93 | − HVM_DCFCLK_G_GATE_DIS, 0); | |
| 98 | + // Enable dynamic clock gating | |
| 99 | + REG_UPDATE_4(DCHVM_CLK_CTRL, | |
| 100 | + HVM_DISPCLK_R_GATE_DIS, 0, | |
| 101 | + HVM_DISPCLK_G_GATE_DIS, 0, | |
| 102 | + HVM_DCFCLK_R_GATE_DIS, 0, | |
| 103 | + HVM_DCFCLK_G_GATE_DIS, 0); | |
| 94 | 104 | |
| 95 | − //Poll until HOSTVM_PREFETCH_DONE = 1 | |
| 96 | − //TODO: Figure out interval us and retry count | |
| 97 | − REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100); | |
| 105 | + //Poll until HOSTVM_PREFETCH_DONE = 1 | |
| 106 | + 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 | 111 | struct dcn_hubbub_phys_addr_config *pa_config) |
| 102 | 112 | { |
| 103 | 113 | struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); |
| 114 | + struct dcn_vmid_page_table_config phys_config; | |
| 104 | 115 | |
| 105 | 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 | 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 | 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 | 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 | 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 | 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 | 139 | dcn21_dchvm_init(hubbub); |
| 119 | 140 | |
| 120 | 141 | return NUM_VMID; |
| 121 | 142 | } |
| 122 | 143 | |
| 123 | −static void hubbub21_program_urgent_watermarks( | |
| 144 | +void hubbub21_program_urgent_watermarks( | |
| 124 | 145 | struct hubbub *hubbub, |
| 125 | 146 | struct dcn_watermark_set *watermarks, |
| 126 | 147 | unsigned int refclk_mhz, |
| @@ -160,6 +181,13 @@ static void hubbub21_program_urgent_watermarks( · 33 unmodified lines | ||
| 160 | 181 | REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, 0, |
| 161 | 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 | 192 | /* clock state B */ |
| 165 | 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 | 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 | 231 | /* clock state C */ |
| 196 | 232 | if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) { |
| 197 | 233 | hubbub1->watermarks.c.urgent_ns = watermarks->c.urgent_ns; |
| @@ -223,6 +259,14 @@ static void hubbub21_program_urgent_watermarks( · 25 unmodified lines | ||
| 223 | 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 | 270 | /* clock state D */ |
| 227 | 271 | if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) { |
| 228 | 272 | hubbub1->watermarks.d.urgent_ns = watermarks->d.urgent_ns; |
| @@ -253,9 +297,17 @@ static void hubbub21_program_urgent_watermarks( · 24 unmodified lines | ||
| 253 | 297 | REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, 0, |
| 254 | 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 | 311 | struct hubbub *hubbub, |
| 260 | 312 | struct dcn_watermark_set *watermarks, |
| 261 | 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 | 445 | struct hubbub *hubbub, |
| 394 | 446 | struct dcn_watermark_set *watermarks, |
| 395 | 447 | unsigned int refclk_mhz, |
| @@ -564,17 +616,26 @@ void hubbub21_wm_read_state(struct hubbub *hubbub, · 168 unmodified lines | ||
| 564 | 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 | 628 | static const struct hubbub_funcs hubbub21_funcs = { |
| 569 | 629 | .update_dchub = hubbub2_update_dchub, |
| 570 | 630 | .init_dchub_sys_ctx = hubbub21_init_dchub, |
| 571 | − .init_vm_ctx = NULL, | |
| 631 | + .init_vm_ctx = hubbub2_init_vm_ctx, | |
| 572 | 632 | .dcc_support_swizzle = hubbub2_dcc_support_swizzle, |
| 573 | 633 | .dcc_support_pixel_format = hubbub2_dcc_support_pixel_format, |
| 574 | 634 | .get_dcc_compression_cap = hubbub2_get_dcc_compression_cap, |
| 575 | 635 | .wm_read_state = hubbub21_wm_read_state, |
| 576 | 636 | .get_dchub_ref_freq = hubbub2_get_dchub_ref_freq, |
| 577 | 637 | .program_watermarks = hubbub21_program_watermarks, |
| 638 | + .apply_DEDCN21_147_wa = hubbub21_apply_DEDCN21_147_wa, | |
| 578 | 639 | }; |
| 579 | 640 | |
| 580 | 641 | void hubbub21_construct(struct dcn20_hubbub *hubbub, |
| @@ -592,4 +653,5 @@ void hubbub21_construct(struct dcn20_hubbub *hubbub, · 11 unmodified lines | ||
| 592 | 653 | hubbub->masks = hubbub_mask; |
| 593 | 654 | |
| 594 | 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 | 36 | SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B),\ |
| 37 | 37 | SR(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C),\ |
| 38 | 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 | 43 | SR(DCHUBBUB_ARB_HOSTVM_CNTL), \ |
| 40 | 44 | SR(DCHVM_CTRL0), \ |
| 41 | 45 | SR(DCHVM_MEM_CTRL), \ |
| @@ -44,16 +48,9 @@ · 2 unmodified lines | ||
| 44 | 48 | SR(DCHVM_RIOMMU_STAT0) |
| 45 | 49 | |
| 46 | 50 | #define HUBBUB_REG_LIST_DCN21()\ |
| 47 | − HUBBUB_REG_LIST_DCN_COMMON(), \ | |
| 51 | + HUBBUB_REG_LIST_DCN20_COMMON(), \ | |
| 48 | 52 | HUBBUB_SR_WATERMARK_REG_LIST(), \ |
| 49 | − 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) | |
| 53 | + HUBBUB_HVM_REG_LIST() | |
| 57 | 54 | |
| 58 | 55 | #define HUBBUB_MASK_SH_LIST_HVM(mask_sh) \ |
| 59 | 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 | 99 | HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, mask_sh) |
| 103 | 100 | |
| 104 | 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 | 103 | HUBBUB_MASK_SH_LIST_DCN_COMMON(mask_sh), \ |
| 107 | 104 | HUBBUB_MASK_SH_LIST_STUTTER(mask_sh), \ |
| 108 | 105 | HUBBUB_SF(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \ |
| @@ -114,11 +111,28 @@ · 5 unmodified lines | ||
| 114 | 111 | HUBBUB_SF(DCN_VM_AGP_BASE, AGP_BASE, mask_sh) |
| 115 | 112 | |
| 116 | 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 | 116 | void hubbub21_program_watermarks( |
| 118 | 117 | struct hubbub *hubbub, |
| 119 | 118 | struct dcn_watermark_set *watermarks, |
| 120 | 119 | unsigned int refclk_mhz, |
| 121 | 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 | 137 | void hubbub21_wm_read_state(struct hubbub *hubbub, |
| 124 | 138 | struct dcn_hubbub_wm *wm); |
| @@ -22,6 +22,8 @@ · 21 unmodified lines | ||
| 22 | 22 | * Authors: AMD |
| 23 | 23 | * |
| 24 | 24 | */ |
| 25 | + | |
| 26 | +#include "dcn10/dcn10_hubp.h" | |
| 25 | 27 | #include "dcn21_hubp.h" |
| 26 | 28 | |
| 27 | 29 | #include "dm_services.h" |
| @@ -202,7 +204,7 @@ static struct hubp_funcs dcn21_hubp_funcs = { · 174 unmodified lines | ||
| 202 | 204 | .hubp_enable_tripleBuffer = hubp2_enable_triplebuffer, |
| 203 | 205 | .hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled, |
| 204 | 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 | 208 | .hubp_is_flip_pending = hubp1_is_flip_pending, |
| 207 | 209 | .hubp_setup = hubp21_setup, |
| 208 | 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 | 26 | #include "dm_services.h" |
| 29 | 27 | #include "dc.h" |
| 30 | 28 | |
| @@ -42,11 +40,11 @@ · 11 unmodified lines | ||
| 42 | 40 | #include "irq/dcn21/irq_service_dcn21.h" |
| 43 | 41 | #include "dcn20/dcn20_dpp.h" |
| 44 | 42 | #include "dcn20/dcn20_optc.h" |
| 45 | −#include "dcn20/dcn20_hwseq.h" | |
| 43 | +#include "dcn21/dcn21_hwseq.h" | |
| 46 | 44 | #include "dce110/dce110_hw_sequencer.h" |
| 47 | 45 | #include "dcn20/dcn20_opp.h" |
| 48 | 46 | #include "dcn20/dcn20_dsc.h" |
| 49 | −#include "dcn20/dcn20_link_encoder.h" | |
| 47 | +#include "dcn21/dcn21_link_encoder.h" | |
| 50 | 48 | #include "dcn20/dcn20_stream_encoder.h" |
| 51 | 49 | #include "dce/dce_clock_source.h" |
| 52 | 50 | #include "dce/dce_audio.h" |
| @@ -84,6 +82,7 @@ · 31 unmodified lines | ||
| 84 | 82 | |
| 85 | 83 | |
| 86 | 84 | struct _vcs_dpi_ip_params_st dcn2_1_ip = { |
| 85 | + .odm_capable = 1, | |
| 87 | 86 | .gpuvm_enable = 0, |
| 88 | 87 | .hostvm_enable = 0, |
| 89 | 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 | 204 | .state = 4, |
| 206 | 205 | .dcfclk_mhz = 810.0, |
| 207 | 206 | .fabricclk_mhz = 1600.0, |
| 208 | − .dispclk_mhz = 1015.0, | |
| 209 | − .dppclk_mhz = 1015.0, | |
| 210 | − .phyclk_mhz = 810.0, | |
| 207 | + .dispclk_mhz = 1395.0, | |
| 208 | + .dppclk_mhz = 1285.0, | |
| 209 | + .phyclk_mhz = 1325.0, | |
| 211 | 210 | .socclk_mhz = 953.0, |
| 212 | − .dscclk_mhz = 318.334, | |
| 211 | + .dscclk_mhz = 489.0, | |
| 213 | 212 | .dram_speed_mts = 4266.0, |
| 214 | 213 | }, |
| 215 | 214 | /*Extra state, no dispclk ramping*/ |
| @@ -217,18 +216,18 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { · 1 unmodified line | ||
| 217 | 216 | .state = 5, |
| 218 | 217 | .dcfclk_mhz = 810.0, |
| 219 | 218 | .fabricclk_mhz = 1600.0, |
| 220 | − .dispclk_mhz = 1015.0, | |
| 221 | − .dppclk_mhz = 1015.0, | |
| 222 | − .phyclk_mhz = 810.0, | |
| 219 | + .dispclk_mhz = 1395.0, | |
| 220 | + .dppclk_mhz = 1285.0, | |
| 221 | + .phyclk_mhz = 1325.0, | |
| 223 | 222 | .socclk_mhz = 953.0, |
| 224 | − .dscclk_mhz = 318.334, | |
| 223 | + .dscclk_mhz = 489.0, | |
| 225 | 224 | .dram_speed_mts = 4266.0, |
| 226 | 225 | }, |
| 227 | 226 | |
| 228 | 227 | }, |
| 229 | 228 | |
| 230 | − .sr_exit_time_us = 9.0, | |
| 231 | − .sr_enter_plus_exit_time_us = 11.0, | |
| 229 | + .sr_exit_time_us = 12.5, | |
| 230 | + .sr_enter_plus_exit_time_us = 17.0, | |
| 232 | 231 | .urgent_latency_us = 4.0, |
| 233 | 232 | .urgent_latency_pixel_data_only_us = 4.0, |
| 234 | 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 | 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 | 376 | #ifdef CONFIG_DRM_AMD_DC_DMUB |
| 354 | 377 | static const struct dcn21_dmcub_registers dmcub_regs = { |
| 355 | 378 | DMCUB_REG_LIST_DCN() |
| @@ -628,6 +651,14 @@ static const struct dcn10_stream_enc_registers stream_enc_regs[] = { · 272 unmodified lines | ||
| 628 | 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 | 662 | static const struct dcn10_stream_encoder_shift se_shift = { |
| 632 | 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 | 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 | 672 | static struct input_pixel_processor *dcn21_ipp_create( |
| 640 | 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 | 717 | dce110_aux_engine_construct(aux_engine, ctx, inst, |
| 685 | 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 | 724 | return &aux_engine->base; |
| 689 | 725 | } |
| @@ -726,11 +762,12 @@ static const struct resource_caps res_cap_rn = { · 36 unmodified lines | ||
| 726 | 762 | .num_timing_generator = 4, |
| 727 | 763 | .num_opp = 4, |
| 728 | 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 | 766 | .num_stream_encoder = 5, |
| 731 | 767 | .num_pll = 5, // maybe 3 because the last two used for USB-c |
| 732 | 768 | .num_dwb = 1, |
| 733 | 769 | .num_ddc = 5, |
| 770 | + .num_vmid = 1, | |
| 734 | 771 | #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT |
| 735 | 772 | .num_dsc = 3, |
| 736 | 773 | #endif |
| @@ -800,11 +837,11 @@ static const struct dc_debug_options debug_defaults_drv = { · 63 unmodified lines | ||
| 800 | 837 | .disable_dcc = DCC_ENABLE, |
| 801 | 838 | .vsr_support = true, |
| 802 | 839 | .performance_trace = false, |
| 803 | − .max_downscale_src_width = 5120,/*upto 5K*/ | |
| 840 | + .max_downscale_src_width = 3840, | |
| 804 | 841 | .disable_pplib_wm_range = false, |
| 805 | 842 | .scl_reset_length10 = true, |
| 806 | 843 | .sanity_checks = true, |
| 807 | − .disable_48mhz_pwrdwn = true, | |
| 844 | + .disable_48mhz_pwrdwn = false, | |
| 808 | 845 | }; |
| 809 | 846 | |
| 810 | 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 | 976 | dcn_dccg_destroy(&pool->base.dccg); |
| 940 | 977 | |
| 941 | 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 | 1037 | void dcn21_calculate_wm( |
| 978 | 1038 | struct dc *dc, struct dc_state *context, |
| 979 | 1039 | display_e2e_pipe_params_st *pipes, |
| @@ -988,6 +1048,8 @@ void dcn21_calculate_wm( · 8 unmodified lines | ||
| 988 | 1048 | |
| 989 | 1049 | ASSERT(bw_params); |
| 990 | 1050 | |
| 1051 | + patch_bounding_box(dc, &context->bw_ctx.dml.soc); | |
| 1052 | + | |
| 991 | 1053 | for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { |
| 992 | 1054 | if (!context->res_ctx.pipe_ctx[i].stream) |
| 993 | 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 | 1340 | dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator; |
| 1279 | 1341 | dcn2_1_ip.max_num_dpp = pool->base.pipe_count; |
| 1280 | 1342 | dcn2_1_soc.num_chans = bw_params->num_channels; |
| 1281 | − dcn2_1_soc.num_states = 0; | |
| 1282 | 1343 | |
| 1283 | 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 | 1349 | dcn2_1_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; |
| 1289 | 1350 | /* This is probably wrong, TODO: find correct calculation */ |
| 1290 | 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 | 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 | 1383 | struct pp_smu_wm_range_sets *ranges) |
| 1322 | 1384 | { |
| 1323 | 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 | 1389 | struct dpm_clocks *clock_table) |
| 1328 | 1390 | { |
| 1329 | 1391 | *clock_table = dummy_clocks; |
| 1330 | 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 | 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; | |
| 1340 | − pp_smu->rn_funcs.set_wm_ranges = dummy_set_wm_ranges; | |
| 1408 | + dm_pp_get_funcs(ctx, pp_smu); | |
| 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 | 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 | 1419 | if (pp_smu && *pp_smu) { |
| 1348 | 1420 | kfree(*pp_smu); |
| @@ -1400,6 +1472,7 @@ static struct dce_hwseq *dcn21_hwseq_create( · 51 unmodified lines | ||
| 1400 | 1472 | hws->regs = &hwseq_reg; |
| 1401 | 1473 | hws->shifts = &hwseq_shift; |
| 1402 | 1474 | hws->masks = &hwseq_mask; |
| 1475 | + hws->wa.DEGVIDCN21 = true; | |
| 1403 | 1476 | } |
| 1404 | 1477 | return hws; |
| 1405 | 1478 | } |
| @@ -1418,9 +1491,103 @@ static const struct resource_create_funcs res_create_maximus_funcs = { · 12 unmodified lines | ||
| 1418 | 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 | 1588 | static struct resource_funcs dcn21_res_pool_funcs = { |
| 1422 | 1589 | .destroy = dcn21_destroy_resource_pool, |
| 1423 | − .link_enc_create = dcn20_link_encoder_create, | |
| 1590 | + .link_enc_create = dcn21_link_encoder_create, | |
| 1424 | 1591 | .validate_bandwidth = dcn21_validate_bandwidth, |
| 1425 | 1592 | .add_stream_to_ctx = dcn20_add_stream_to_ctx, |
| 1426 | 1593 | .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, |
| @@ -1437,9 +1604,10 @@ static bool construct( · 10 unmodified lines | ||
| 1437 | 1604 | struct dc *dc, |
| 1438 | 1605 | struct dcn21_resource_pool *pool) |
| 1439 | 1606 | { |
| 1440 | − int i; | |
| 1607 | + int i, j; | |
| 1441 | 1608 | struct dc_context *ctx = dc->ctx; |
| 1442 | 1609 | struct irq_service_init_data init_data; |
| 1610 | + uint32_t pipe_fuses = read_pipe_fuses(ctx); | |
| 1443 | 1611 | |
| 1444 | 1612 | ctx->dc_bios->regs = &bios_regs; |
| 1445 | 1613 | |
| @@ -1457,7 +1625,9 @@ static bool construct( · 11 unmodified lines | ||
| 1457 | 1625 | *************************************************/ |
| 1458 | 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 | 1631 | dc->caps.max_downscale_ratio = 200; |
| 1462 | 1632 | dc->caps.i2c_speed_in_khz = 100; |
| 1463 | 1633 | dc->caps.max_cursor_size = 256; |
| @@ -1467,6 +1637,7 @@ static bool construct( · 3 unmodified lines | ||
| 1467 | 1637 | dc->caps.max_slave_planes = 1; |
| 1468 | 1638 | dc->caps.post_blend_color_processing = true; |
| 1469 | 1639 | dc->caps.force_dp_tps4_for_cp2520 = true; |
| 1640 | + dc->caps.extended_aux_timeout_support = true; | |
| 1470 | 1641 | |
| 1471 | 1642 | if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) |
| 1472 | 1643 | dc->debug = debug_defaults_drv; |
| @@ -1516,6 +1687,26 @@ static bool construct( · 43 unmodified lines | ||
| 1516 | 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 | 1710 | #ifdef CONFIG_DRM_AMD_DC_DMUB |
| 1520 | 1711 | pool->base.dmcub = dcn21_dmcub_create(ctx, |
| 1521 | 1712 | &dmcub_regs, |
| @@ -1537,8 +1728,15 @@ static bool construct( · 15 unmodified lines | ||
| 1537 | 1728 | if (!pool->base.irqs) |
| 1538 | 1729 | goto create_fail; |
| 1539 | 1730 | |
| 1731 | + j = 0; | |
| 1540 | 1732 | /* mem input -> ipp -> dpp -> opp -> TG */ |
| 1541 | 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 | 1740 | pool->base.hubps[i] = dcn21_hubp_create(ctx, i); |
| 1543 | 1741 | if (pool->base.hubps[i] == NULL) { |
| 1544 | 1742 | BREAK_TO_DEBUGGER(); |
| @@ -1562,6 +1760,23 @@ static bool construct( · 17 unmodified lines | ||
| 1562 | 1760 | "DC: failed to create dpps!\n"); |
| 1563 | 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 | 1782 | for (i = 0; i < pool->base.res_cap->num_ddc; i++) { |
| @@ -1582,27 +1797,9 @@ static bool construct( · 14 unmodified lines | ||
| 1582 | 1797 | pool->base.sw_i2cs[i] = NULL; |
| 1583 | 1798 | } |
| 1584 | 1799 | |
| 1585 | − for (i = 0; i < pool->base.res_cap->num_opp; i++) { | |
| 1586 | − pool->base.opps[i] = dcn21_opp_create(ctx, i); | |
| 1587 | − if (pool->base.opps[i] == NULL) { | |
| 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; | |
| 1800 | + pool->base.timing_generator_count = j; | |
| 1801 | + pool->base.pipe_count = j; | |
| 1802 | + pool->base.mpcc_count = j; | |
| 1606 | 1803 | |
| 1607 | 1804 | pool->base.mpc = dcn21_mpc_create(ctx); |
| 1608 | 1805 | if (pool->base.mpc == NULL) { |
| @@ -1645,7 +1842,7 @@ static bool construct( · 36 unmodified lines | ||
| 1645 | 1842 | &res_create_funcs : &res_create_maximus_funcs))) |
| 1646 | 1843 | goto create_fail; |
| 1647 | 1844 | |
| 1648 | − dcn20_hw_sequencer_construct(dc); | |
| 1845 | + dcn21_hw_sequencer_construct(dc); | |
| 1649 | 1846 | |
| 1650 | 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 | 250 | #endif |
| 251 | 251 | |
| 252 | −#if defined(CONFIG_DRM_AMD_DC_DCN2_1) | |
| 253 | − | |
| 254 | 252 | #define PP_SMU_NUM_SOCCLK_DPM_LEVELS 8 |
| 255 | −#define PP_SMU_NUM_DCFCLK_DPM_LEVELS 4 | |
| 256 | −#define PP_SMU_NUM_FCLK_DPM_LEVELS 4 | |
| 257 | −#define PP_SMU_NUM_MEMCLK_DPM_LEVELS 4 | |
| 253 | +#define PP_SMU_NUM_DCFCLK_DPM_LEVELS 8 | |
| 254 | +#define PP_SMU_NUM_FCLK_DPM_LEVELS 8 | |
| 255 | +#define PP_SMU_NUM_MEMCLK_DPM_LEVELS 8 | |
| 258 | 256 | |
| 259 | 257 | struct dpm_clock { |
| 260 | 258 | uint32_t Freq; // In MHz |
| @@ -288,7 +286,6 @@ struct pp_smu_funcs_rn { · 27 unmodified lines | ||
| 288 | 286 | enum pp_smu_status (*get_dpm_clock_table) (struct pp_smu *pp, |
| 289 | 287 | struct dpm_clocks *clock_table); |
| 290 | 288 | }; |
| 291 | −#endif | |
| 292 | 289 | |
| 293 | 290 | struct pp_smu_funcs { |
| 294 | 291 | struct pp_smu ctx; |
| @@ -65,6 +65,7 @@ typedef struct { · 64 unmodified lines | ||
| 65 | 65 | |
| 66 | 66 | #define BPP_INVALID 0 |
| 67 | 67 | #define BPP_BLENDED_PIPE 0xffffffff |
| 68 | +#define DCN21_MAX_DSC_IMAGE_WIDTH 5184 | |
| 68 | 69 | |
| 69 | 70 | static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib); |
| 70 | 71 | static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation( |
| @@ -3379,6 +3380,8 @@ static unsigned int TruncToValidBPP( · 3308 unmodified lines | ||
| 3379 | 3380 | return 30; |
| 3380 | 3381 | else if (DecimalBPP >= 24 && (DesiredBPP == 0 || DesiredBPP == 24)) |
| 3381 | 3382 | return 24; |
| 3383 | + else if (DecimalBPP >= 18 && (DesiredBPP == 0 || DesiredBPP == 18)) | |
| 3384 | + return 18; | |
| 3382 | 3385 | else |
| 3383 | 3386 | return BPP_INVALID; |
| 3384 | 3387 | } |
| @@ -3936,6 +3939,10 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 551 unmodified lines | ||
| 3936 | 3939 | mode_lib->vba.MaximumSwathWidthInLineBuffer); |
| 3937 | 3940 | } |
| 3938 | 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 | 3946 | for (j = 0; j < 2; j++) { |
| 3940 | 3947 | mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown( |
| 3941 | 3948 | mode_lib->vba.MaxDispclk[i], |
| @@ -3965,7 +3972,9 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 23 unmodified lines | ||
| 3965 | 3972 | && i == mode_lib->vba.soc.num_states) |
| 3966 | 3973 | mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2 |
| 3967 | 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 | 3978 | locals->ODMCombineEnablePerState[i][k] = false; |
| 3970 | 3979 | mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine; |
| 3971 | 3980 | } else { |
| @@ -269,7 +269,7 @@ struct writeback_st { · 268 unmodified lines | ||
| 269 | 269 | |
| 270 | 270 | struct _vcs_dpi_display_output_params_st { |
| 271 | 271 | int dp_lanes; |
| 272 | − int output_bpp; | |
| 272 | + double output_bpp; | |
| 273 | 273 | int dsc_enable; |
| 274 | 274 | int wb_enable; |
| 275 | 275 | int num_active_wb; |
| @@ -434,6 +434,8 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) · 433 unmodified lines | ||
| 434 | 434 | dst->odm_combine; |
| 435 | 435 | mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] = |
| 436 | 436 | (enum output_format_class) (dout->output_format); |
| 437 | + mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] = | |
| 438 | + dout->output_bpp; | |
| 437 | 439 | mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] = |
| 438 | 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 | 105 | bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc, |
| 106 | 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 | 111 | void dal_ddc_service_write_scdc_data( |
| 109 | 112 | struct ddc_service *ddc_service, |
| 110 | 113 | uint32_t pix_clk, |
| @@ -28,6 +28,8 @@ · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | #define LINK_TRAINING_ATTEMPTS 4 |
| 30 | 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 | 34 | struct dc_link; |
| 33 | 35 | struct dc_stream_state; |
| @@ -43,6 +45,9 @@ bool dp_verify_link_cap_with_retries( · 9 unmodified lines | ||
| 43 | 45 | struct dc_link_settings *known_limit_link_setting, |
| 44 | 46 | int attempts); |
| 45 | 47 | |
| 48 | +bool dp_verify_mst_link_cap( | |
| 49 | + struct dc_link *link); | |
| 50 | + | |
| 46 | 51 | bool dp_validate_mode_timing( |
| 47 | 52 | struct dc_link *link, |
| 48 | 53 | const struct dc_crtc_timing *timing); |
| @@ -140,6 +140,9 @@ struct write_command_context { · 139 unmodified lines | ||
| 140 | 140 | |
| 141 | 141 | |
| 142 | 142 | struct aux_engine_funcs { |
| 143 | + bool (*configure_timeout)( | |
| 144 | + struct ddc_service *ddc, | |
| 145 | + uint32_t timeout); | |
| 143 | 146 | void (*destroy)( |
| 144 | 147 | struct aux_engine **ptr); |
| 145 | 148 | bool (*acquire_engine)( |
| @@ -47,7 +47,7 @@ · 46 unmodified lines | ||
| 47 | 47 | #ifdef CONFIG_DRM_AMD_DC_DCN2_1 |
| 48 | 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 | 51 | #define WM_SET_COUNT 4 |
| 52 | 52 | |
| 53 | 53 | |
| @@ -149,6 +149,7 @@ struct wm_table { · 95 unmodified lines | ||
| 149 | 149 | struct clk_bw_params { |
| 150 | 150 | unsigned int vram_type; |
| 151 | 151 | unsigned int num_channels; |
| 152 | + unsigned int dispclk_vco_khz; | |
| 152 | 153 | struct clk_limit_table clk_table; |
| 153 | 154 | struct wm_table wm_table; |
| 154 | 155 | }; |
| @@ -180,12 +181,16 @@ struct clk_mgr_funcs { · 25 unmodified lines | ||
| 180 | 181 | struct dc_state *context, |
| 181 | 182 | enum dc_clock_type clock_type, |
| 182 | 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 | 189 | struct clk_mgr { |
| 186 | 190 | struct dc_context *ctx; |
| 187 | 191 | struct clk_mgr_funcs *funcs; |
| 188 | 192 | struct dc_clocks clks; |
| 193 | + bool psr_allow_active_cache; | |
| 189 | 194 | int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes |
| 190 | 195 | #ifdef CONFIG_DRM_AMD_DC_DCN2_1 |
| 191 | 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 | 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 | 211 | #endif /* __DAL_CLK_MGR_H__ */ |
| @@ -184,6 +184,21 @@ struct clk_mgr_registers { · 183 unmodified lines | ||
| 184 | 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 | 202 | struct state_dependent_clocks { |
| 188 | 203 | int display_clk_khz; |
| 189 | 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 | 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 | |
| 285 | − return (calc_support != cur_support) ? !safe_to_lower : false; | |
| 299 | + if (cur_support != calc_support) { | |
| 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 | 309 | int clk_mgr_helper_get_active_display_cnt( |
| @@ -147,6 +147,7 @@ struct hubbub_funcs { · 146 unmodified lines | ||
| 147 | 147 | bool (*is_allow_self_refresh_enabled)(struct hubbub *hubbub); |
| 148 | 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 | 153 | struct hubbub { |
| @@ -184,6 +184,10 @@ struct link_encoder_funcs { · 183 unmodified lines | ||
| 184 | 184 | bool (*fec_is_active)(struct link_encoder *enc); |
| 185 | 185 | #endif |
| 186 | 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 | 191 | enum signal_type (*get_dig_mode)( |
| 188 | 192 | struct link_encoder *enc); |
| 189 | 193 | }; |
| @@ -43,6 +43,7 @@ struct dcn_watermarks { · 42 unmodified lines | ||
| 43 | 43 | #if defined(CONFIG_DRM_AMD_DC_DCN2_1) |
| 44 | 44 | uint32_t frac_urg_bw_nom; |
| 45 | 45 | uint32_t frac_urg_bw_flip; |
| 46 | + int32_t urgent_latency_ns; | |
| 46 | 47 | #endif |
| 47 | 48 | struct cstate_pstate_watermarks_st cstate_pstate; |
| 48 | 49 | }; |
| @@ -208,6 +208,7 @@ struct output_pixel_processor { · 207 unmodified lines | ||
| 208 | 208 | struct mpc_tree mpc_tree_params; |
| 209 | 209 | bool mpcc_disconnect_pending[MAX_PIPES]; |
| 210 | 210 | const struct opp_funcs *funcs; |
| 211 | + uint32_t dyn_expansion; | |
| 211 | 212 | }; |
| 212 | 213 | |
| 213 | 214 | enum fmt_stereo_action { |
| @@ -214,6 +214,11 @@ struct stream_encoder_funcs { · 213 unmodified lines | ||
| 214 | 214 | unsigned int (*dig_source_otg)( |
| 215 | 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 | 222 | #if defined(CONFIG_DRM_AMD_DC_DCN2_0) |
| 218 | 223 | #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT |
| 219 | 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 | 262 | void (*program_manual_trigger)(struct timing_generator *optc); |
| 263 | 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 | 267 | void (*set_vtg_params)(struct timing_generator *optc, |
| 266 | 268 | const struct dc_crtc_timing *dc_crtc_timing); |
| @@ -232,6 +232,13 @@ struct hw_sequencer_funcs { · 231 unmodified lines | ||
| 232 | 232 | struct dc *dc, |
| 233 | 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 | 242 | #if defined(CONFIG_DRM_AMD_DC_DCN2_0) |
| 236 | 243 | bool (*update_bandwidth)( |
| 237 | 244 | struct dc *dc, |
| @@ -324,10 +331,12 @@ struct hw_sequencer_funcs { · 86 unmodified lines | ||
| 324 | 331 | struct dc_state *context); |
| 325 | 332 | void (*update_writeback)(struct dc *dc, |
| 326 | 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 | 336 | void (*enable_writeback)(struct dc *dc, |
| 329 | 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 | 340 | void (*disable_writeback)(struct dc *dc, |
| 332 | 341 | unsigned int dwb_pipe_inst); |
| 333 | 342 | #endif |
| @@ -340,6 +349,9 @@ struct hw_sequencer_funcs { · 6 unmodified lines | ||
| 340 | 349 | enum dc_clock_type clock_type, |
| 341 | 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 | 357 | void color_space_to_black_color( |
| @@ -31,6 +31,8 @@ · 30 unmodified lines | ||
| 31 | 31 | #define DP_BRANCH_DEVICE_ID_0022B9 0x0022B9 |
| 32 | 32 | #define DP_BRANCH_DEVICE_ID_00001A 0x00001A |
| 33 | 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 | 37 | enum ddc_result { |
| 36 | 38 | DDC_RESULT_UNKNOWN = 0, |
| @@ -234,6 +234,10 @@ static void update_v_total_for_static_ramp( · 233 unmodified lines | ||
| 234 | 234 | current_duration_in_us) * (stream->timing.pix_clk_100hz / 10)), |
| 235 | 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 | 241 | in_out_vrr->adjust.v_total_min = v_total; |
| 238 | 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 | 747 | nominal_field_rate_in_uhz = |
| 744 | 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 | 754 | min_refresh_in_uhz = in_config->min_refresh_in_uhz; |
| 747 | 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 | 1006 | const struct dc_stream_state *stream) |
| 999 | 1007 | { |
| 1000 | 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 | 1012 | nominal_field_rate_in_uhz = stream->timing.pix_clk_100hz / 10; |
| 1004 | 1013 | nominal_field_rate_in_uhz *= 1000ULL * 1000ULL * 1000ULL; |
| 1005 | − nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz, | |
| 1006 | − stream->timing.h_total); | |
| 1007 | − nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz, | |
| 1008 | − stream->timing.v_total); | |
| 1014 | + | |
| 1015 | + nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz, total); | |
| 1009 | 1016 | |
| 1010 | 1017 | return nominal_field_rate_in_uhz; |
| 1011 | 1018 | } |
| @@ -35,4 +35,7 @@ struct mod_vrr_params; · 34 unmodified lines | ||
| 35 | 35 | void mod_build_vsc_infopacket(const struct dc_stream_state *stream, |
| 36 | 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 | 41 | #endif |
| @@ -31,6 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | #include "dc.h" |
| 32 | 32 | |
| 33 | 33 | #define HDMI_INFOFRAME_TYPE_VENDOR 0x81 |
| 34 | +#define HF_VSIF_VERSION 1 | |
| 34 | 35 | |
| 35 | 36 | // VTEM Byte Offset |
| 36 | 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 | 27 | #define mmMM_INDEX 0x0 |
| 28 | 28 | #define mmMM_INDEX_HI 0x6 |
| 29 | 29 | #define mmMM_DATA 0x1 |
| 30 | +#define mmCC_BIF_BX_FUSESTRAP0 0x14D7 | |
| 30 | 31 | #define mmBUS_CNTL 0x1508 |
| 31 | 32 | #define mmCONFIG_CNTL 0x1509 |
| 32 | 33 | #define mmCONFIG_MEMSIZE 0x150a |
| @@ -32,6 +32,8 @@ · 31 unmodified lines | ||
| 32 | 32 | #define MM_INDEX_HI__MM_OFFSET_HI__SHIFT 0x0 |
| 33 | 33 | #define MM_DATA__MM_DATA_MASK 0xffffffff |
| 34 | 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 | 37 | #define BUS_CNTL__BIOS_ROM_WRT_EN_MASK 0x1 |
| 36 | 38 | #define BUS_CNTL__BIOS_ROM_WRT_EN__SHIFT 0x0 |
| 37 | 39 | #define BUS_CNTL__BIOS_ROM_DIS_MASK 0x2 |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | #define mmMM_INDEX 0x0 |
| 28 | 28 | #define mmMM_INDEX_HI 0x6 |
| 29 | 29 | #define mmMM_DATA 0x1 |
| 30 | +#define mmCC_BIF_BX_FUSESTRAP0 0x14D7 | |
| 30 | 31 | #define mmCC_BIF_BX_STRAP2 0x152A |
| 31 | 32 | #define mmBIF_MM_INDACCESS_CNTL 0x1500 |
| 32 | 33 | #define mmBIF_DOORBELL_APER_EN 0x1501 |
| @@ -32,6 +32,8 @@ · 31 unmodified lines | ||
| 32 | 32 | #define MM_INDEX_HI__MM_OFFSET_HI__SHIFT 0x0 |
| 33 | 33 | #define MM_DATA__MM_DATA_MASK 0xffffffff |
| 34 | 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 | 37 | #define BIF_MM_INDACCESS_CNTL__MM_INDACCESS_DIS_MASK 0x2 |
| 36 | 38 | #define BIF_MM_INDACCESS_CNTL__MM_INDACCESS_DIS__SHIFT 0x1 |
| 37 | 39 | #define BIF_DOORBELL_APER_EN__BIF_DOORBELL_APER_EN_MASK 0x1 |
| @@ -9859,6 +9859,8 @@ · 9858 unmodified lines | ||
| 9859 | 9859 | #define mmDP0_DP_STEER_FIFO_BASE_IDX 2 |
| 9860 | 9860 | #define mmDP0_DP_MSA_MISC 0x210e |
| 9861 | 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 | 9864 | #define mmDP0_DP_VID_TIMING 0x2110 |
| 9863 | 9865 | #define mmDP0_DP_VID_TIMING_BASE_IDX 2 |
| 9864 | 9866 | #define mmDP0_DP_VID_N 0x2111 |
| @@ -10187,6 +10189,8 @@ · 322 unmodified lines | ||
| 10187 | 10189 | #define mmDP1_DP_STEER_FIFO_BASE_IDX 2 |
| 10188 | 10190 | #define mmDP1_DP_MSA_MISC 0x220e |
| 10189 | 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 | 10194 | #define mmDP1_DP_VID_TIMING 0x2210 |
| 10191 | 10195 | #define mmDP1_DP_VID_TIMING_BASE_IDX 2 |
| 10192 | 10196 | #define mmDP1_DP_VID_N 0x2211 |
| @@ -10515,6 +10519,8 @@ · 322 unmodified lines | ||
| 10515 | 10519 | #define mmDP2_DP_STEER_FIFO_BASE_IDX 2 |
| 10516 | 10520 | #define mmDP2_DP_MSA_MISC 0x230e |
| 10517 | 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 | 10524 | #define mmDP2_DP_VID_TIMING 0x2310 |
| 10519 | 10525 | #define mmDP2_DP_VID_TIMING_BASE_IDX 2 |
| 10520 | 10526 | #define mmDP2_DP_VID_N 0x2311 |
| @@ -10843,6 +10849,8 @@ · 322 unmodified lines | ||
| 10843 | 10849 | #define mmDP3_DP_STEER_FIFO_BASE_IDX 2 |
| 10844 | 10850 | #define mmDP3_DP_MSA_MISC 0x240e |
| 10845 | 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 | 10854 | #define mmDP3_DP_VID_TIMING 0x2410 |
| 10847 | 10855 | #define mmDP3_DP_VID_TIMING_BASE_IDX 2 |
| 10848 | 10856 | #define mmDP3_DP_VID_N 0x2411 |
| @@ -11171,6 +11179,8 @@ · 322 unmodified lines | ||
| 11171 | 11179 | #define mmDP4_DP_STEER_FIFO_BASE_IDX 2 |
| 11172 | 11180 | #define mmDP4_DP_MSA_MISC 0x250e |
| 11173 | 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 | 11184 | #define mmDP4_DP_VID_TIMING 0x2510 |
| 11175 | 11185 | #define mmDP4_DP_VID_TIMING_BASE_IDX 2 |
| 11176 | 11186 | #define mmDP4_DP_VID_N 0x2511 |
| @@ -1146,7 +1146,14 @@ · 1145 unmodified lines | ||
| 1146 | 1146 | #define mmATC_L2_MEM_POWER_LS_BASE_IDX 0 |
| 1147 | 1147 | #define mmATC_L2_CGTT_CLK_CTRL 0x080c |
| 1148 | 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 | 1158 | // addressBlock: gc_utcl2_vml2pfdec |
| 1152 | 1159 | // base address: 0xa100 |
| @@ -1206,7 +1213,14 @@ · 53 unmodified lines | ||
| 1206 | 1213 | #define mmVM_L2_CACHE_PARITY_CNTL_BASE_IDX 0 |
| 1207 | 1214 | #define mmVM_L2_CGTT_CLK_CTRL 0x085e |
| 1208 | 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 | 1225 | // addressBlock: gc_utcl2_vml2vcdec |
| 1212 | 1226 | // base address: 0xa200 |
| @@ -6661,7 +6661,6 @@ · 6660 unmodified lines | ||
| 6661 | 6661 | #define ATC_L2_CGTT_CLK_CTRL__SOFT_STALL_OVERRIDE_MASK 0x00FF0000L |
| 6662 | 6662 | #define ATC_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK 0xFF000000L |
| 6663 | 6663 | |
| 6664 | − | |
| 6665 | 6664 | // addressBlock: gc_utcl2_vml2pfdec |
| 6666 | 6665 | //VM_L2_CNTL |
| 6667 | 6666 | #define VM_L2_CNTL__ENABLE_L2_CACHE__SHIFT 0x0 |
| @@ -6991,7 +6990,22 @@ · 323 unmodified lines | ||
| 6991 | 6990 | #define VM_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK 0x00008000L |
| 6992 | 6991 | #define VM_L2_CGTT_CLK_CTRL__SOFT_STALL_OVERRIDE_MASK 0x00FF0000L |
| 6993 | 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 | 7010 | // addressBlock: gc_utcl2_vml2vcdec |
| 6997 | 7011 | //VM_CONTEXT0_CNTL |
| @@ -49,6 +49,7 @@ · 48 unmodified lines | ||
| 49 | 49 | #define ixCG_SPLL_FUNC_CNTL_5 0xc0500150 |
| 50 | 50 | #define ixCG_SPLL_FUNC_CNTL_6 0xc0500154 |
| 51 | 51 | #define ixCG_SPLL_FUNC_CNTL_7 0xc0500158 |
| 52 | +#define ixCG_SPLL_STATUS 0xC050015C | |
| 52 | 53 | #define ixSPLL_CNTL_MODE 0xc0500160 |
| 53 | 54 | #define ixCG_SPLL_SPREAD_SPECTRUM 0xc0500164 |
| 54 | 55 | #define ixCG_SPLL_SPREAD_SPECTRUM_2 0xc0500168 |
| @@ -194,6 +194,8 @@ · 193 unmodified lines | ||
| 194 | 194 | #define CG_SPLL_FUNC_CNTL_6__SPLL_LF_CNTR__SHIFT 0x19 |
| 195 | 195 | #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL_MASK 0xfff |
| 196 | 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 | 199 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL_MASK 0x1 |
| 198 | 200 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL__SHIFT 0x0 |
| 199 | 201 | #define SPLL_CNTL_MODE__SPLL_LEGACY_PDIV_MASK 0x2 |
| @@ -49,6 +49,7 @@ · 48 unmodified lines | ||
| 49 | 49 | #define ixCG_SPLL_FUNC_CNTL_5 0xc0500150 |
| 50 | 50 | #define ixCG_SPLL_FUNC_CNTL_6 0xc0500154 |
| 51 | 51 | #define ixCG_SPLL_FUNC_CNTL_7 0xc0500158 |
| 52 | +#define ixCG_SPLL_STATUS 0xC050015C | |
| 52 | 53 | #define ixSPLL_CNTL_MODE 0xc0500160 |
| 53 | 54 | #define ixCG_SPLL_SPREAD_SPECTRUM 0xc0500164 |
| 54 | 55 | #define ixCG_SPLL_SPREAD_SPECTRUM_2 0xc0500168 |
| @@ -194,6 +194,8 @@ · 193 unmodified lines | ||
| 194 | 194 | #define CG_SPLL_FUNC_CNTL_6__SPLL_LF_CNTR__SHIFT 0x19 |
| 195 | 195 | #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL_MASK 0xfff |
| 196 | 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 | 199 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL_MASK 0x1 |
| 198 | 200 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL__SHIFT 0x0 |
| 199 | 201 | #define SPLL_CNTL_MODE__SPLL_LEGACY_PDIV_MASK 0x2 |
| @@ -52,6 +52,7 @@ · 51 unmodified lines | ||
| 52 | 52 | #define ixCG_SPLL_FUNC_CNTL_5 0xc0500150 |
| 53 | 53 | #define ixCG_SPLL_FUNC_CNTL_6 0xc0500154 |
| 54 | 54 | #define ixCG_SPLL_FUNC_CNTL_7 0xc0500158 |
| 55 | +#define ixCG_SPLL_STATUS 0xC050015C | |
| 55 | 56 | #define ixSPLL_CNTL_MODE 0xc0500160 |
| 56 | 57 | #define ixCG_SPLL_SPREAD_SPECTRUM 0xc0500164 |
| 57 | 58 | #define ixCG_SPLL_SPREAD_SPECTRUM_2 0xc0500168 |
| @@ -220,6 +220,8 @@ · 219 unmodified lines | ||
| 220 | 220 | #define CG_SPLL_FUNC_CNTL_6__SPLL_LF_CNTR__SHIFT 0x19 |
| 221 | 221 | #define CG_SPLL_FUNC_CNTL_7__SPLL_BW_CNTRL_MASK 0xfff |
| 222 | 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 | 225 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL_MASK 0x1 |
| 224 | 226 | #define SPLL_CNTL_MODE__SPLL_SW_DIR_CONTROL__SHIFT 0x0 |
| 225 | 227 | #define SPLL_CNTL_MODE__SPLL_LEGACY_PDIV_MASK 0x2 |
| @@ -492,12 +492,13 @@ struct atom_firmware_info_v3_1 · 491 unmodified lines | ||
| 492 | 492 | /* Total 32bit cap indication */ |
| 493 | 493 | enum atombios_firmware_capability |
| 494 | 494 | { |
| 495 | − ATOM_FIRMWARE_CAP_FIRMWARE_POSTED = 0x00000001, | |
| 496 | − ATOM_FIRMWARE_CAP_GPU_VIRTUALIZATION = 0x00000002, | |
| 497 | − ATOM_FIRMWARE_CAP_WMI_SUPPORT = 0x00000040, | |
| 498 | − ATOM_FIRMWARE_CAP_HWEMU_ENABLE = 0x00000080, | |
| 499 | − ATOM_FIRMWARE_CAP_HWEMU_UMC_CFG = 0x00000100, | |
| 500 | − ATOM_FIRMWARE_CAP_SRAM_ECC = 0x00000200, | |
| 495 | + ATOM_FIRMWARE_CAP_FIRMWARE_POSTED = 0x00000001, | |
| 496 | + ATOM_FIRMWARE_CAP_GPU_VIRTUALIZATION = 0x00000002, | |
| 497 | + ATOM_FIRMWARE_CAP_WMI_SUPPORT = 0x00000040, | |
| 498 | + ATOM_FIRMWARE_CAP_HWEMU_ENABLE = 0x00000080, | |
| 499 | + ATOM_FIRMWARE_CAP_HWEMU_UMC_CFG = 0x00000100, | |
| 500 | + ATOM_FIRMWARE_CAP_SRAM_ECC = 0x00000200, | |
| 501 | + ATOM_FIRMWARE_CAP_ENABLE_2STAGE_BIST_TRAINING = 0x00000400, | |
| 501 | 502 | }; |
| 502 | 503 | |
| 503 | 504 | enum atom_cooling_solution_id{ |
| @@ -671,6 +672,20 @@ struct vram_usagebyfirmware_v2_1 · 167 unmodified lines | ||
| 671 | 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 | 25 | #define _DISCOVERY_H_ |
| 26 | 26 | |
| 27 | 27 | #define PSP_HEADER_SIZE 256 |
| 28 | −#define BINARY_MAX_SIZE (64 << 10) | |
| 29 | 28 | #define BINARY_SIGNATURE 0x28211407 |
| 30 | 29 | #define DISCOVERY_TABLE_SIGNATURE 0x53445049 |
| 31 | 30 | |
| @@ -179,6 +179,11 @@ enum pp_mp1_state { · 178 unmodified lines | ||
| 179 | 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 | 187 | #define PP_GROUP_MASK 0xF0000000 |
| 183 | 188 | #define PP_GROUP_SHIFT 28 |
| 184 | 189 | |
| @@ -312,6 +317,7 @@ struct amd_pm_funcs { · 127 unmodified lines | ||
| 312 | 317 | int (*get_ppfeature_status)(void *handle, char *buf); |
| 313 | 318 | int (*set_ppfeature_status)(void *handle, uint64_t ppfeature_masks); |
| 314 | 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 | 323 | #endif |
| @@ -169,6 +169,11 @@ static const struct IP_BASE NBIF0_BASE ={ { { { 0x00000000, 0x00000014, 0x00000D · 168 unmodified lines | ||
| 169 | 169 | { { 0, 0, 0, 0, 0 } }, |
| 170 | 170 | { { 0, 0, 0, 0, 0 } }, |
| 171 | 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 | 177 | static const struct IP_BASE OSSSYS_BASE ={ { { { 0x000010A0, 0x0240A000, 0, 0, 0 } }, |
| 173 | 178 | { { 0, 0, 0, 0, 0 } }, |
| 174 | 179 | { { 0, 0, 0, 0, 0 } }, |
| @@ -1361,4 +1366,33 @@ static const struct IP_BASE UVD0_BASE ={ { { { 0x00007800, 0x00007E00, 0x0240300 · 1186 unmodified lines | ||
| 1361 | 1366 | #define UVD0_BASE__INST6_SEG3 0 |
| 1362 | 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 | 1398 | #endif |
| @@ -1421,6 +1421,7 @@ static int pp_get_asic_baco_capability(void *handle, bool *cap) · 1420 unmodified lines | ||
| 1421 | 1421 | { |
| 1422 | 1422 | struct pp_hwmgr *hwmgr = handle; |
| 1423 | 1423 | |
| 1424 | + *cap = false; | |
| 1424 | 1425 | if (!hwmgr) |
| 1425 | 1426 | return -EINVAL; |
| 1426 | 1427 | |
| @@ -1548,6 +1549,23 @@ static int pp_smu_i2c_bus_access(void *handle, bool acquire) · 121 unmodified lines | ||
| 1548 | 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 | 1569 | static const struct amd_pm_funcs pp_dpm_funcs = { |
| 1552 | 1570 | .load_firmware = pp_dpm_load_fw, |
| 1553 | 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 | 1624 | .set_ppfeature_status = pp_set_ppfeature_status, |
| 1607 | 1625 | .asic_reset_mode_2 = pp_asic_reset_mode_2, |
| 1608 | 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 | 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 | 948 | static int smu_smc_table_hw_init(struct smu_context *smu, |
| 993 | 949 | bool initialize) |
| 994 | 950 | { |
| @@ -1232,6 +1188,7 @@ static int smu_hw_init(void *handle) · 237 unmodified lines | ||
| 1232 | 1188 | if (adev->flags & AMD_IS_APU) { |
| 1233 | 1189 | smu_powergate_sdma(&adev->smu, false); |
| 1234 | 1190 | smu_powergate_vcn(&adev->smu, false); |
| 1191 | + smu_set_gfx_cgpg(&adev->smu, true); | |
| 1235 | 1192 | } |
| 1236 | 1193 | |
| 1237 | 1194 | if (!smu->pm_enabled) |
| @@ -1394,6 +1351,11 @@ static int smu_resume(void *handle) · 156 unmodified lines | ||
| 1394 | 1351 | if (ret) |
| 1395 | 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 | 1359 | mutex_unlock(&smu->mutex); |
| 1398 | 1360 | |
| 1399 | 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 | 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 | 1857 | const struct amd_ip_funcs smu_ip_funcs = { |
| 1838 | 1858 | .name = "smu", |
| 1839 | 1859 | .early_init = smu_early_init, |
| @@ -1898,6 +1898,35 @@ static bool arcturus_is_dpm_running(struct smu_context *smu) · 1897 unmodified lines | ||
| 1898 | 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 | 1930 | static const struct pptable_funcs arcturus_ppt_funcs = { |
| 1902 | 1931 | /* translate smu index into arcturus specific index */ |
| 1903 | 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 | 1965 | .dump_pptable = arcturus_dump_pptable, |
| 1937 | 1966 | .get_power_limit = arcturus_get_power_limit, |
| 1938 | 1967 | .is_dpm_running = arcturus_is_dpm_running, |
| 1968 | + .dpm_set_uvd_enable = arcturus_dpm_set_uvd_enable, | |
| 1939 | 1969 | }; |
| 1940 | 1970 | |
| 1941 | 1971 | void arcturus_set_ppt_funcs(struct smu_context *smu) |
| @@ -36,7 +36,8 @@ HARDWARE_MGR = hwmgr.o processpptables.o \ · 35 unmodified lines | ||
| 36 | 36 | pp_overdriver.o smu_helper.o \ |
| 37 | 37 | vega20_processpptables.o vega20_hwmgr.o vega20_powertune.o \ |
| 38 | 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 | 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 | 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 | 101 | bool soc15_baco_program_registers(struct pp_hwmgr *hwmgr, |
| 83 | 102 | const struct soc15_baco_cmd_entry *entry, |
| 84 | 103 | const u32 array_size) |
| @@ -33,6 +33,15 @@ enum baco_cmd_type { · 32 unmodified lines | ||
| 33 | 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 | 45 | struct soc15_baco_cmd_entry { |
| 37 | 46 | enum baco_cmd_type cmd; |
| 38 | 47 | uint32_t hwip; |
| @@ -44,6 +53,10 @@ struct soc15_baco_cmd_entry { · 5 unmodified lines | ||
| 44 | 53 | uint32_t timeout; |
| 45 | 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 | 60 | extern bool soc15_baco_program_registers(struct pp_hwmgr *hwmgr, |
| 48 | 61 | const struct soc15_baco_cmd_entry *entry, |
| 49 | 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 | 48 | #include "smu7_clockpowergating.h" |
| 49 | 49 | #include "processpptables.h" |
| 50 | 50 | #include "pp_thermal.h" |
| 51 | +#include "smu7_baco.h" | |
| 51 | 52 | |
| 52 | 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 | 1995 | struct phm_ppt_v1_voltage_lookup_table *lookup_table) |
| 1995 | 1996 | { |
| 1996 | 1997 | uint32_t table_size, i, j; |
| 1997 | − struct phm_ppt_v1_voltage_lookup_record tmp_voltage_lookup_record; | |
| 1998 | 1998 | table_size = lookup_table->count; |
| 1999 | 1999 | |
| 2000 | 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 | 2005 | for (j = i + 1; j > 0; j--) { |
| 2006 | 2006 | if (lookup_table->entries[j].us_vdd < |
| 2007 | 2007 | lookup_table->entries[j - 1].us_vdd) { |
| 2008 | − tmp_voltage_lookup_record = lookup_table->entries[j - 1]; | |
| 2009 | − lookup_table->entries[j - 1] = lookup_table->entries[j]; | |
| 2010 | − lookup_table->entries[j] = tmp_voltage_lookup_record; | |
| 2008 | + swap(lookup_table->entries[j - 1], | |
| 2009 | + lookup_table->entries[j]); | |
| 2011 | 2010 | } |
| 2012 | 2011 | } |
| 2013 | 2012 | } |
| @@ -5145,6 +5144,9 @@ static const struct pp_hwmgr_func smu7_hwmgr_funcs = { · 3131 unmodified lines | ||
| 5145 | 5144 | .get_power_profile_mode = smu7_get_power_profile_mode, |
| 5146 | 5145 | .set_power_profile_mode = smu7_set_power_profile_mode, |
| 5147 | 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 | 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 | 712 | struct phm_ppt_v1_voltage_lookup_table *lookup_table) |
| 713 | 713 | { |
| 714 | 714 | uint32_t table_size, i, j; |
| 715 | − struct phm_ppt_v1_voltage_lookup_record tmp_voltage_lookup_record; | |
| 716 | 715 | |
| 717 | 716 | PP_ASSERT_WITH_CODE(lookup_table && lookup_table->count, |
| 718 | 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 | 723 | for (j = i + 1; j > 0; j--) { |
| 725 | 724 | if (lookup_table->entries[j].us_vdd < |
| 726 | 725 | lookup_table->entries[j - 1].us_vdd) { |
| 727 | − tmp_voltage_lookup_record = lookup_table->entries[j - 1]; | |
| 728 | − lookup_table->entries[j - 1] = lookup_table->entries[j]; | |
| 729 | − lookup_table->entries[j] = tmp_voltage_lookup_record; | |
| 726 | + swap(lookup_table->entries[j - 1], | |
| 727 | + lookup_table->entries[j]); | |
| 730 | 728 | } |
| 731 | 729 | } |
| 732 | 730 | } |
| @@ -29,7 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include "vega20_baco.h" |
| 30 | 30 | #include "vega20_smumgr.h" |
| 31 | 31 | |
| 32 | − | |
| 32 | +#include "amdgpu_ras.h" | |
| 33 | 33 | |
| 34 | 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 | 74 | int vega20_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state) |
| 75 | 75 | { |
| 76 | 76 | struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); |
| 77 | + struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); | |
| 77 | 78 | enum BACO_STATE cur_state; |
| 78 | 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 | 85 | return 0; |
| 85 | 86 | |
| 86 | 87 | if (state == BACO_STATE_IN) { |
| 87 | − data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL); | |
| 88 | − data |= 0x80000000; | |
| 89 | − WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data); | |
| 90 | − | |
| 91 | − | |
| 92 | − if(smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_EnterBaco, 0)) | |
| 93 | − return -EINVAL; | |
| 88 | + if (!ras || !ras->supported) { | |
| 89 | + data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL); | |
| 90 | + data |= 0x80000000; | |
| 91 | + WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data); | |
| 92 | + | |
| 93 | + if(smum_send_msg_to_smc_with_parameter(hwmgr, | |
| 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 | 102 | } else if (state == BACO_STATE_OUT) { |
| 96 | 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 | 182 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, |
| 183 | 183 | PHM_PlatformCaps_TablelessHardwareInterface); |
| 184 | 184 | |
| 185 | + phm_cap_set(hwmgr->platform_descriptor.platformCaps, | |
| 186 | + PHM_PlatformCaps_BACO); | |
| 187 | + | |
| 185 | 188 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, |
| 186 | 189 | PHM_PlatformCaps_EnableSMU7ThermalManagement); |
| 187 | 190 | |
| @@ -490,8 +493,8 @@ static int vega20_setup_asic_task(struct pp_hwmgr *hwmgr) · 302 unmodified lines | ||
| 490 | 493 | "Failed to init sclk threshold!", |
| 491 | 494 | return ret); |
| 492 | 495 | |
| 493 | − if (adev->in_baco_reset) { | |
| 494 | − adev->in_baco_reset = 0; | |
| 496 | + if (adev->in_gpu_reset && | |
| 497 | + (amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)) { | |
| 495 | 498 | |
| 496 | 499 | ret = vega20_baco_apply_vdci_flush_workaround(hwmgr); |
| 497 | 500 | if (ret) |
| @@ -4155,6 +4158,24 @@ static int vega20_smu_i2c_bus_access(struct pp_hwmgr *hwmgr, bool acquire) · 3657 unmodified lines | ||
| 4155 | 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 | 4179 | static const struct pp_hwmgr_func vega20_hwmgr_funcs = { |
| 4159 | 4180 | /* init/fini related */ |
| 4160 | 4181 | .backend_init = vega20_hwmgr_backend_init, |
| @@ -4223,6 +4244,7 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = { · 62 unmodified lines | ||
| 4223 | 4244 | .set_asic_baco_state = vega20_baco_set_state, |
| 4224 | 4245 | .set_mp1_state = vega20_set_mp1_state, |
| 4225 | 4246 | .smu_i2c_bus_access = vega20_smu_i2c_bus_access, |
| 4247 | + .set_df_cstate = vega20_set_df_cstate, | |
| 4226 | 4248 | }; |
| 4227 | 4249 | |
| 4228 | 4250 | int vega20_hwmgr_init(struct pp_hwmgr *hwmgr) |
| @@ -468,6 +468,9 @@ struct pptable_funcs { · 467 unmodified lines | ||
| 468 | 468 | int (*get_power_limit)(struct smu_context *smu, uint32_t *limit, bool asic_default); |
| 469 | 469 | int (*get_dpm_clk_limited)(struct smu_context *smu, enum smu_clk_type clk_type, |
| 470 | 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 | 476 | struct smu_funcs |
| @@ -493,7 +496,6 @@ struct smu_funcs · 19 unmodified lines | ||
| 493 | 496 | int (*set_min_dcef_deep_sleep)(struct smu_context *smu); |
| 494 | 497 | int (*set_tool_table_location)(struct smu_context *smu); |
| 495 | 498 | int (*notify_memory_pool_location)(struct smu_context *smu); |
| 496 | − int (*write_watermarks_table)(struct smu_context *smu); | |
| 497 | 499 | int (*set_last_dcef_min_deep_sleep_clk)(struct smu_context *smu); |
| 498 | 500 | int (*system_features_control)(struct smu_context *smu, bool en); |
| 499 | 501 | int (*send_smc_msg)(struct smu_context *smu, uint16_t msg); |
| @@ -531,8 +533,6 @@ struct smu_funcs · 31 unmodified lines | ||
| 531 | 533 | int (*get_current_shallow_sleep_clocks)(struct smu_context *smu, |
| 532 | 534 | struct smu_clock_info *clocks); |
| 533 | 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 | 536 | int (*conv_power_profile_to_pplib_workload)(int power_profile); |
| 537 | 537 | uint32_t (*get_fan_control_mode)(struct smu_context *smu); |
| 538 | 538 | int (*set_fan_control_mode)(struct smu_context *smu, uint32_t mode); |
| @@ -550,6 +550,7 @@ struct smu_funcs · 11 unmodified lines | ||
| 550 | 550 | int (*mode2_reset)(struct smu_context *smu); |
| 551 | 551 | int (*get_dpm_ultimate_freq)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t *min, uint32_t *max); |
| 552 | 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 | 556 | #define smu_init_microcode(smu) \ |
| @@ -596,9 +597,6 @@ struct smu_funcs · 40 unmodified lines | ||
| 596 | 597 | ((smu)->funcs->notify_memory_pool_location ? (smu)->funcs->notify_memory_pool_location((smu)) : 0) |
| 597 | 598 | #define smu_gfx_off_control(smu, enable) \ |
| 598 | 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 | 600 | #define smu_set_last_dcef_min_deep_sleep_clk(smu) \ |
| 603 | 601 | ((smu)->funcs->set_last_dcef_min_deep_sleep_clk ? (smu)->funcs->set_last_dcef_min_deep_sleep_clk((smu)) : 0) |
| 604 | 602 | #define smu_system_features_control(smu, en) \ |
| @@ -738,8 +736,6 @@ struct smu_funcs · 133 unmodified lines | ||
| 738 | 736 | ((smu)->funcs->get_current_shallow_sleep_clocks ? (smu)->funcs->get_current_shallow_sleep_clocks((smu), (clocks)) : 0) |
| 739 | 737 | #define smu_notify_smu_enable_pwe(smu) \ |
| 740 | 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 | 739 | #define smu_dpm_set_uvd_enable(smu, enable) \ |
| 744 | 740 | ((smu)->ppt_funcs->dpm_set_uvd_enable ? (smu)->ppt_funcs->dpm_set_uvd_enable((smu), (enable)) : 0) |
| 745 | 741 | #define smu_dpm_set_vce_enable(smu, enable) \ |
| @@ -776,9 +772,16 @@ struct smu_funcs · 30 unmodified lines | ||
| 776 | 772 | ((smu)->ppt_funcs->dump_pptable ? (smu)->ppt_funcs->dump_pptable((smu)) : 0) |
| 777 | 773 | #define smu_get_dpm_clk_limited(smu, clk_type, dpm_level, freq) \ |
| 778 | 774 | ((smu)->ppt_funcs->get_dpm_clk_limited ? (smu)->ppt_funcs->get_dpm_clk_limited((smu), (clk_type), (dpm_level), (freq)) : -EINVAL) |
| 779 | − | |
| 780 | 775 | #define smu_set_soft_freq_limited_range(smu, clk_type, min, max) \ |
| 781 | 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 | 786 | extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table, |
| 784 | 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 | 815 | int smu_sys_set_pp_table(struct smu_context *smu, void *buf, size_t size); |
| 813 | 816 | int smu_get_power_num_states(struct smu_context *smu, struct pp_states_info *state_info); |
| 814 | 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 | 823 | /* smu to display interface */ |
| 817 | 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 | 857 | uint32_t mask); |
| 851 | 858 | int smu_set_mp1_state(struct smu_context *smu, |
| 852 | 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 | 863 | #endif |
| @@ -355,6 +355,7 @@ struct pp_hwmgr_func { · 354 unmodified lines | ||
| 355 | 355 | int (*set_mp1_state)(struct pp_hwmgr *hwmgr, enum pp_mp1_state mp1_state); |
| 356 | 356 | int (*asic_reset)(struct pp_hwmgr *hwmgr, enum SMU_ASIC_RESET_MODE mode); |
| 357 | 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 | 361 | struct pp_table_func { |
| @@ -169,6 +169,7 @@ · 168 unmodified lines | ||
| 169 | 169 | __SMU_DUMMY_MAP(PowerGateAtHub), \ |
| 170 | 170 | __SMU_DUMMY_MAP(SetSoftMinJpeg), \ |
| 171 | 171 | __SMU_DUMMY_MAP(SetHardMinFclkByFreq), \ |
| 172 | + __SMU_DUMMY_MAP(DFCstateControl), \ | |
| 172 | 173 | |
| 173 | 174 | #undef __SMU_DUMMY_MAP |
| 174 | 175 | #define __SMU_DUMMY_MAP(type) SMU_MSG_##type |
| @@ -120,7 +120,8 @@ · 119 unmodified lines | ||
| 120 | 120 | #define PPSMC_MSG_SetMGpuFanBoostLimitRpm 0x5D |
| 121 | 121 | #define PPSMC_MSG_GetAVFSVoltageByDpm 0x5F |
| 122 | 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 | 126 | typedef uint32_t PPSMC_Result; |
| 126 | 127 | typedef uint32_t PPSMC_Msg; |
| @@ -328,40 +328,52 @@ navi10_get_allowed_feature_mask(struct smu_context *smu, · 327 unmodified lines | ||
| 328 | 328 | memset(feature_mask, 0, sizeof(uint32_t) * num); |
| 329 | 329 | |
| 330 | 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 | 331 | | FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT) |
| 334 | − | FEATURE_MASK(FEATURE_DPM_LINK_BIT) | |
| 335 | − | FEATURE_MASK(FEATURE_GFX_ULV_BIT) | |
| 336 | 332 | | FEATURE_MASK(FEATURE_RSMU_SMN_CG_BIT) |
| 337 | 333 | | FEATURE_MASK(FEATURE_DS_SOCCLK_BIT) |
| 338 | 334 | | FEATURE_MASK(FEATURE_PPT_BIT) |
| 339 | 335 | | FEATURE_MASK(FEATURE_TDC_BIT) |
| 340 | 336 | | FEATURE_MASK(FEATURE_GFX_EDC_BIT) |
| 337 | + | FEATURE_MASK(FEATURE_APCC_PLUS_BIT) | |
| 341 | 338 | | FEATURE_MASK(FEATURE_VR0HOT_BIT) |
| 342 | 339 | | FEATURE_MASK(FEATURE_FAN_CONTROL_BIT) |
| 343 | 340 | | FEATURE_MASK(FEATURE_THERMAL_BIT) |
| 344 | 341 | | FEATURE_MASK(FEATURE_LED_DISPLAY_BIT) |
| 345 | − | FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT) | |
| 346 | − | FEATURE_MASK(FEATURE_DS_GFXCLK_BIT) | |
| 342 | + | FEATURE_MASK(FEATURE_DS_LCLK_BIT) | |
| 347 | 343 | | FEATURE_MASK(FEATURE_DS_DCEFCLK_BIT) |
| 348 | 344 | | FEATURE_MASK(FEATURE_FW_DSTATE_BIT) |
| 349 | 345 | | FEATURE_MASK(FEATURE_BACO_BIT) |
| 350 | 346 | | FEATURE_MASK(FEATURE_ACDC_BIT) |
| 351 | 347 | | FEATURE_MASK(FEATURE_GFX_SS_BIT) |
| 352 | 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 | 364 | if (adev->pm.pp_feature & PP_MCLK_DPM_MASK) |
| 356 | 365 | *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_UCLK_BIT) |
| 357 | 366 | | FEATURE_MASK(FEATURE_MEM_VDDCI_SCALING_BIT) |
| 358 | 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 | 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 | 378 | if (smu->adev->pg_flags & AMD_PG_SUPPORT_MMHUB) |
| 367 | 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 | 1464 | uint32_t sclk_freq = 0, uclk_freq = 0; |
| 1453 | 1465 | uint32_t uclk_level = 0; |
| 1454 | 1466 | |
| 1455 | − switch (adev->pdev->revision) { | |
| 1456 | − case 0xf0: /* XTX */ | |
| 1457 | − case 0xc0: | |
| 1458 | − sclk_freq = NAVI10_PEAK_SCLK_XTX; | |
| 1459 | − break; | |
| 1460 | − case 0xf1: /* XT */ | |
| 1461 | − case 0xc1: | |
| 1462 | − sclk_freq = NAVI10_PEAK_SCLK_XT; | |
| 1467 | + switch (adev->asic_type) { | |
| 1468 | + case CHIP_NAVI10: | |
| 1469 | + switch (adev->pdev->revision) { | |
| 1470 | + case 0xf0: /* XTX */ | |
| 1471 | + case 0xc0: | |
| 1472 | + sclk_freq = NAVI10_PEAK_SCLK_XTX; | |
| 1473 | + break; | |
| 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 | 1482 | break; |
| 1464 | − default: /* XL */ | |
| 1465 | − sclk_freq = NAVI10_PEAK_SCLK_XL; | |
| 1483 | + case CHIP_NAVI14: | |
| 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 | 1505 | break; |
| 1506 | + default: | |
| 1507 | + return -EINVAL; | |
| 1467 | 1508 | } |
| 1468 | 1509 | |
| 1469 | 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 | 1527 | static int navi10_set_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level) |
| 1487 | 1528 | { |
| 1488 | 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 | 1531 | switch (level) { |
| 1495 | 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 | 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 | 1654 | static const struct pptable_funcs navi10_ppt_funcs = { |
| 1596 | 1655 | .tables_init = navi10_tables_init, |
| 1597 | 1656 | .alloc_dpm_context = navi10_allocate_dpm_context, |
| @@ -1630,6 +1689,7 @@ static const struct pptable_funcs navi10_ppt_funcs = { · 32 unmodified lines | ||
| 1630 | 1689 | .get_thermal_temperature_range = navi10_get_thermal_temperature_range, |
| 1631 | 1690 | .display_disable_memory_clock_switch = navi10_display_disable_memory_clock_switch, |
| 1632 | 1691 | .get_power_limit = navi10_get_power_limit, |
| 1692 | + .update_pcie_parameters = navi10_update_pcie_parameters, | |
| 1633 | 1693 | }; |
| 1634 | 1694 | |
| 1635 | 1695 | void navi10_set_ppt_funcs(struct smu_context *smu) |
| @@ -27,6 +27,12 @@ · 26 unmodified lines | ||
| 27 | 27 | #define NAVI10_PEAK_SCLK_XT (1755) |
| 28 | 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 | 36 | extern void navi10_set_ppt_funcs(struct smu_context *smu); |
| 31 | 37 | |
| 32 | 38 | #endif |
| @@ -416,6 +416,40 @@ static int renoir_get_profiling_clk_mask(struct smu_context *smu, · 415 unmodified lines | ||
| 416 | 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 | 453 | static int renoir_force_clk_levels(struct smu_context *smu, |
| 420 | 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 | 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 | 676 | static const struct pptable_funcs renoir_ppt_funcs = { |
| 550 | 677 | .get_smu_msg_index = renoir_get_smu_msg_index, |
| 551 | 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 | 689 | .force_clk_levels = renoir_force_clk_levels, |
| 563 | 690 | .set_power_profile_mode = renoir_set_power_profile_mode, |
| 564 | 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 | 697 | void renoir_set_ppt_funcs(struct smu_context *smu) |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | #include "vega20_ppt.h" |
| 36 | 36 | #include "arcturus_ppt.h" |
| 37 | 37 | #include "navi10_ppt.h" |
| 38 | +#include "amd_pcie.h" | |
| 38 | 39 | |
| 39 | 40 | #include "asic_reg/thm/thm_11_0_2_offset.h" |
| 40 | 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 | 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 | 774 | static int smu_v11_0_set_deep_sleep_dcefclk(struct smu_context *smu, uint32_t clk) |
| 791 | 775 | { |
| 792 | 776 | int ret; |
| @@ -1336,26 +1320,6 @@ failed: · 543 unmodified lines | ||
| 1336 | 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 | 1323 | static int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable) |
| 1360 | 1324 | { |
| 1361 | 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 | 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 | 1801 | static const struct smu_funcs smu_v11_0_funcs = { |
| 1796 | 1802 | .init_microcode = smu_v11_0_init_microcode, |
| 1797 | 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 | 1818 | .parse_pptable = smu_v11_0_parse_pptable, |
| 1813 | 1819 | .populate_smc_tables = smu_v11_0_populate_smc_pptable, |
| 1814 | 1820 | .write_pptable = smu_v11_0_write_pptable, |
| 1815 | − .write_watermarks_table = smu_v11_0_write_watermarks_table, | |
| 1816 | 1821 | .set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep, |
| 1817 | 1822 | .set_tool_table_location = smu_v11_0_set_tool_table_location, |
| 1818 | 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 | 1833 | .read_sensor = smu_v11_0_read_sensor, |
| 1829 | 1834 | .set_deep_sleep_dcefclk = smu_v11_0_set_deep_sleep_dcefclk, |
| 1830 | 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 | 1836 | .get_fan_control_mode = smu_v11_0_get_fan_control_mode, |
| 1833 | 1837 | .set_fan_control_mode = smu_v11_0_set_fan_control_mode, |
| 1834 | 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 | 1848 | .baco_reset = smu_v11_0_baco_reset, |
| 1845 | 1849 | .get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq, |
| 1846 | 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 | 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 | 244 | if (enable) { |
| 245 | 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 | 247 | } else { |
| 257 | 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 | 143 | MSG_MAP(PrepareMp1ForShutdown), |
| 144 | 144 | MSG_MAP(SetMGpuFanBoostLimitRpm), |
| 145 | 145 | MSG_MAP(GetAVFSVoltageByDpm), |
| 146 | + MSG_MAP(DFCstateControl), | |
| 146 | 147 | }; |
| 147 | 148 | |
| 148 | 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 | 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 | 3182 | static const struct pptable_funcs vega20_ppt_funcs = { |
| 3139 | 3183 | .tables_init = vega20_tables_init, |
| 3140 | 3184 | .alloc_dpm_context = vega20_allocate_dpm_context, |
| @@ -3177,7 +3221,9 @@ static const struct pptable_funcs vega20_ppt_funcs = { · 36 unmodified lines | ||
| 3177 | 3221 | .get_fan_speed_percent = vega20_get_fan_speed_percent, |
| 3178 | 3222 | .get_fan_speed_rpm = vega20_get_fan_speed_rpm, |
| 3179 | 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 | 3229 | void vega20_set_ppt_funcs(struct smu_context *smu) |