Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'drm-next-5.5-2019-10-25' of git://people.freedesktop.org/~agd5f/linux into drm-next

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

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexdeucher@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191025221020.203546-1-alexander.deucher@amd.com

+5791 -1034
+12 -2
drivers/gpu/drm/amd/amdgpu/amdgpu.h
··· 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 287 const u32 rev; 289 288 const struct amd_ip_funcs *funcs; 290 289 }; 290 + 291 + #define HW_REV(_Major, _Minor, _Rev) \ 292 + ((((uint32_t) (_Major)) << 16) | ((uint32_t) (_Minor) << 8) | ((uint32_t) (_Rev))) 291 293 292 294 struct amdgpu_ip_block { 293 295 struct amdgpu_ip_block_status status; ··· 631 627 u64 size; 632 628 struct amdgpu_bo *reserved_bo; 633 629 void *va; 630 + 631 + /* Offset on the top of VRAM, used as c2p write buffer. 632 + */ 633 + u64 mem_train_fb_loc; 634 + bool mem_train_support; 634 635 }; 635 636 636 637 /* ··· 768 759 uint8_t *bios; 769 760 uint32_t bios_size; 770 761 struct amdgpu_bo *stolen_vga_memory; 762 + struct amdgpu_bo *discovery_memory; 771 763 uint32_t bios_scratch_reg_offset; 772 764 uint32_t bios_scratch[AMDGPU_BIOS_NUM_SCRATCH]; 773 765 ··· 969 959 int asic_reset_res; 970 960 struct work_struct xgmi_reset_work; 971 961 972 - bool in_baco_reset; 973 - 974 962 long gfx_timeout; 975 963 long sdma_timeout; 976 964 long video_timeout; ··· 990 982 void amdgpu_device_fini(struct amdgpu_device *adev); 991 983 int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev); 992 984 985 + void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos, 986 + uint32_t *buf, size_t size, bool write); 993 987 uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg, 994 988 uint32_t acc_flags); 995 989 void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
+5
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
··· 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);
+136
drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
··· 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 461 463 462 } 464 463 return -EINVAL; 464 + } 465 + 466 + /* 467 + * Check if VBIOS supports GDDR6 training data save/restore 468 + */ 469 + static bool gddr6_mem_train_vbios_support(struct amdgpu_device *adev) 470 + { 471 + uint16_t data_offset; 472 + int index; 473 + 474 + index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 475 + firmwareinfo); 476 + if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, NULL, 477 + NULL, NULL, &data_offset)) { 478 + struct atom_firmware_info_v3_1 *firmware_info = 479 + (struct atom_firmware_info_v3_1 *)(adev->mode_info.atom_context->bios + 480 + data_offset); 481 + 482 + DRM_DEBUG("atom firmware capability:0x%08x.\n", 483 + le32_to_cpu(firmware_info->firmware_capability)); 484 + 485 + if (le32_to_cpu(firmware_info->firmware_capability) & 486 + ATOM_FIRMWARE_CAP_ENABLE_2STAGE_BIST_TRAINING) 487 + return true; 488 + } 489 + 490 + return false; 491 + } 492 + 493 + static int gddr6_mem_train_support(struct amdgpu_device *adev) 494 + { 495 + int ret; 496 + uint32_t major, minor, revision, hw_v; 497 + 498 + if (gddr6_mem_train_vbios_support(adev)) { 499 + amdgpu_discovery_get_ip_version(adev, MP0_HWID, &major, &minor, &revision); 500 + hw_v = HW_REV(major, minor, revision); 501 + /* 502 + * treat 0 revision as a special case since register for MP0 and MMHUB is missing 503 + * for some Navi10 A0, preventing driver from discovering the hwip information since 504 + * none of the functions will be initialized, it should not cause any problems 505 + */ 506 + switch (hw_v) { 507 + case HW_REV(11, 0, 0): 508 + case HW_REV(11, 0, 5): 509 + ret = 1; 510 + break; 511 + default: 512 + DRM_ERROR("memory training vbios supports but psp hw(%08x)" 513 + " doesn't support!\n", hw_v); 514 + ret = -1; 515 + break; 516 + } 517 + } else { 518 + ret = 0; 519 + hw_v = -1; 520 + } 521 + 522 + 523 + DRM_DEBUG("mp0 hw_v %08x, ret:%d.\n", hw_v, ret); 524 + return ret; 525 + } 526 + 527 + int amdgpu_atomfirmware_get_mem_train_fb_loc(struct amdgpu_device *adev) 528 + { 529 + struct atom_context *ctx = adev->mode_info.atom_context; 530 + unsigned char *bios = ctx->bios; 531 + struct vram_reserve_block *reserved_block; 532 + int index, block_number; 533 + uint8_t frev, crev; 534 + uint16_t data_offset, size; 535 + uint32_t start_address_in_kb; 536 + uint64_t offset; 537 + int ret; 538 + 539 + adev->fw_vram_usage.mem_train_support = false; 540 + 541 + if (adev->asic_type != CHIP_NAVI10 && 542 + adev->asic_type != CHIP_NAVI14) 543 + return 0; 544 + 545 + if (amdgpu_sriov_vf(adev)) 546 + return 0; 547 + 548 + ret = gddr6_mem_train_support(adev); 549 + if (ret == -1) 550 + return -EINVAL; 551 + else if (ret == 0) 552 + return 0; 553 + 554 + index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 555 + vram_usagebyfirmware); 556 + ret = amdgpu_atom_parse_data_header(ctx, index, &size, &frev, &crev, 557 + &data_offset); 558 + if (ret == 0) { 559 + DRM_ERROR("parse data header failed.\n"); 560 + return -EINVAL; 561 + } 562 + 563 + DRM_DEBUG("atom firmware common table header size:0x%04x, frev:0x%02x," 564 + " crev:0x%02x, data_offset:0x%04x.\n", size, frev, crev, data_offset); 565 + /* only support 2.1+ */ 566 + if (((uint16_t)frev << 8 | crev) < 0x0201) { 567 + DRM_ERROR("frev:0x%02x, crev:0x%02x < 2.1 !\n", frev, crev); 568 + return -EINVAL; 569 + } 570 + 571 + reserved_block = (struct vram_reserve_block *) 572 + (bios + data_offset + sizeof(struct atom_common_table_header)); 573 + block_number = ((unsigned int)size - sizeof(struct atom_common_table_header)) 574 + / sizeof(struct vram_reserve_block); 575 + reserved_block += (block_number > 0) ? block_number-1 : 0; 576 + DRM_DEBUG("block_number:0x%04x, last block: 0x%08xkb sz, %dkb fw, %dkb drv.\n", 577 + block_number, 578 + le32_to_cpu(reserved_block->start_address_in_kb), 579 + le16_to_cpu(reserved_block->used_by_firmware_in_kb), 580 + le16_to_cpu(reserved_block->used_by_driver_in_kb)); 581 + if (reserved_block->used_by_firmware_in_kb > 0) { 582 + start_address_in_kb = le32_to_cpu(reserved_block->start_address_in_kb); 583 + offset = (uint64_t)start_address_in_kb * ONE_KiB; 584 + if ((offset & (ONE_MiB - 1)) < (4 * ONE_KiB + 1) ) { 585 + offset -= ONE_MiB; 586 + } 587 + 588 + offset &= ~(ONE_MiB - 1); 589 + adev->fw_vram_usage.mem_train_fb_loc = offset; 590 + adev->fw_vram_usage.mem_train_support = true; 591 + DRM_DEBUG("mem_train_fb_loc:0x%09llx.\n", offset); 592 + ret = 0; 593 + } else { 594 + DRM_ERROR("used_by_firmware_in_kb is 0!\n"); 595 + ret = -EINVAL; 596 + } 597 + 598 + return ret; 465 599 }
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
··· 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);
+1 -11
drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
··· 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);
+6 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
··· 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);
+2 -6
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
··· 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); ··· 490 491 491 492 amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, 492 493 lobj->user_pages); 493 - binding_userptr = true; 494 494 } 495 495 496 496 r = amdgpu_cs_validate(p, bo); 497 497 if (r) 498 498 return r; 499 499 500 - if (binding_userptr) { 501 - kvfree(lobj->user_pages); 502 - lobj->user_pages = NULL; 503 - } 500 + kvfree(lobj->user_pages); 501 + lobj->user_pages = NULL; 504 502 } 505 503 return 0; 506 504 }
+35 -6
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 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 */ ··· 2652 2622 * There is only one value specified and 2653 2623 * it should apply to all non-compute jobs. 2654 2624 */ 2655 - if (index == 1) 2625 + if (index == 1) { 2656 2626 adev->sdma_timeout = adev->video_timeout = adev->gfx_timeout; 2627 + if (amdgpu_sriov_vf(adev) || amdgpu_passthrough(adev)) 2628 + adev->compute_timeout = adev->gfx_timeout; 2629 + } 2657 2630 } 2658 2631 2659 2632 return ret; ··· 3201 3168 */ 3202 3169 amdgpu_bo_evict_vram(adev); 3203 3170 3204 - pci_save_state(dev->pdev); 3205 3171 if (suspend) { 3172 + pci_save_state(dev->pdev); 3206 3173 /* Shut down the device */ 3207 3174 pci_disable_device(dev->pdev); 3208 3175 pci_set_power_state(dev->pdev, PCI_D3hot); 3209 - } else { 3210 - r = amdgpu_asic_reset(adev); 3211 - if (r) 3212 - DRM_ERROR("amdgpu asic reset failed\n"); 3213 3176 } 3214 3177 3215 3178 return 0;
+6 -14
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
··· 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; 138 + uint64_t pos = vram_size - DISCOVERY_TMR_SIZE; 141 139 142 - while (pos < vram_size) { 143 - spin_lock_irqsave(&adev->mmio_idx_lock, flags); 144 - WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x80000000); 145 - WREG32_NO_KIQ(mmMM_INDEX_HI, pos >> 31); 146 - *p++ = RREG32_NO_KIQ(mmMM_DATA); 147 - spin_unlock_irqrestore(&adev->mmio_idx_lock, flags); 148 - pos += 4; 149 - } 150 - 140 + amdgpu_device_vram_access(adev, pos, (uint32_t *)binary, DISCOVERY_TMR_SIZE, false); 151 141 return 0; 152 142 } 153 143 ··· 169 179 uint16_t checksum; 170 180 int r; 171 181 172 - adev->discovery = kzalloc(BINARY_MAX_SIZE, GFP_KERNEL); 182 + adev->discovery = kzalloc(DISCOVERY_TMR_SIZE, GFP_KERNEL); 173 183 if (!adev->discovery) 174 184 return -ENOMEM; 175 185 ··· 323 333 } 324 334 325 335 int amdgpu_discovery_get_ip_version(struct amdgpu_device *adev, int hw_id, 326 - int *major, int *minor) 336 + int *major, int *minor, int *revision) 327 337 { 328 338 struct binary_header *bhdr; 329 339 struct ip_discovery_header *ihdr; ··· 359 369 *major = ip->major; 360 370 if (minor) 361 371 *minor = ip->minor; 372 + if (revision) 373 + *revision = ip->revision; 362 374 return 0; 363 375 } 364 376 ip_offset += sizeof(*ip) + 4 * (ip->num_base_address - 1);
+3 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h
··· 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__ */
+19 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
··· 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; ··· 251 250 * By default(with no lockup_timeout settings), the timeout for all non-compute(GFX, SDMA and Video) 252 251 * jobs is 10000. And there is no timeout enforced on compute jobs. 253 252 */ 254 - MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms (default: 10000 for non-compute jobs and infinity timeout for compute jobs." 253 + 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; " 254 + "for passthrough or sriov, 10000 for all jobs." 255 255 " 0: keep default value. negative: infinity timeout), " 256 - "format is [Non-Compute] or [GFX,Compute,SDMA,Video]"); 256 + "format: for bare metal [Non-Compute] or [GFX,Compute,SDMA,Video]; " 257 + "for passthrough or sriov [all jobs] or [GFX,Compute,SDMA,Video]."); 257 258 module_param_string(lockup_timeout, amdgpu_lockup_timeout, sizeof(amdgpu_lockup_timeout), 0444); 258 259 259 260 /** ··· 392 389 */ 393 390 MODULE_PARM_DESC(ppfeaturemask, "all power features enabled (default))"); 394 391 module_param_named(ppfeaturemask, amdgpu_pp_feature_mask, uint, 0444); 392 + 393 + /** 394 + * DOC: forcelongtraining (uint) 395 + * Force long memory training in resume. 396 + * The default is zero, indicates short training in resume. 397 + */ 398 + MODULE_PARM_DESC(forcelongtraining, "force memory long training"); 399 + module_param_named(forcelongtraining, amdgpu_force_long_training, uint, 0444); 395 400 396 401 /** 397 402 * DOC: pcie_gen_cap (uint) ··· 1165 1154 static int amdgpu_pmops_freeze(struct device *dev) 1166 1155 { 1167 1156 struct drm_device *drm_dev = dev_get_drvdata(dev); 1157 + struct amdgpu_device *adev = drm_dev->dev_private; 1158 + int r; 1168 1159 1169 - return amdgpu_device_suspend(drm_dev, false, true); 1160 + r = amdgpu_device_suspend(drm_dev, false, true); 1161 + if (r) 1162 + return r; 1163 + return amdgpu_asic_reset(adev); 1170 1164 } 1171 1165 1172 1166 static int amdgpu_pmops_thaw(struct device *dev)
+2
drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
··· 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,
+2 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
··· 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;
+18
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
··· 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 ··· 106 95 { 107 96 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 108 97 98 + psp_mem_training_fini(&adev->psp); 109 99 release_firmware(adev->psp.sos_fw); 110 100 adev->psp.sos_fw = NULL; 111 101 release_firmware(adev->psp.asd_fw); ··· 1619 1607 struct psp_context *psp = &adev->psp; 1620 1608 1621 1609 DRM_INFO("PSP is resuming...\n"); 1610 + 1611 + ret = psp_mem_training(psp, PSP_MEM_TRAIN_RESUME); 1612 + if (ret) { 1613 + DRM_ERROR("Failed to process memory training!\n"); 1614 + return ret; 1615 + } 1622 1616 1623 1617 mutex_lock(&adev->firmware.mutex); 1624 1618
+55
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
··· 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 ··· 113 111 struct ta_ras_trigger_error_input *info); 114 112 int (*ras_cure_posion)(struct psp_context *psp, uint64_t *mode_ptr); 115 113 int (*rlc_autoload_start)(struct psp_context *psp); 114 + int (*mem_training_init)(struct psp_context *psp); 115 + void (*mem_training_fini)(struct psp_context *psp); 116 + int (*mem_training)(struct psp_context *psp, uint32_t ops); 116 117 }; 117 118 118 119 #define AMDGPU_XGMI_MAX_CONNECTED_NODES 64 ··· 164 159 struct amdgpu_bo *dtm_shared_bo; 165 160 uint64_t dtm_shared_mc_addr; 166 161 void *dtm_shared_buf; 162 + }; 163 + 164 + #define MEM_TRAIN_SYSTEM_SIGNATURE 0x54534942 165 + #define GDDR6_MEM_TRAINING_DATA_SIZE_IN_BYTES 0x1000 166 + #define GDDR6_MEM_TRAINING_OFFSET 0x8000 167 + 168 + enum psp_memory_training_init_flag { 169 + PSP_MEM_TRAIN_NOT_SUPPORT = 0x0, 170 + PSP_MEM_TRAIN_SUPPORT = 0x1, 171 + PSP_MEM_TRAIN_INIT_FAILED = 0x2, 172 + PSP_MEM_TRAIN_RESERVE_SUCCESS = 0x4, 173 + PSP_MEM_TRAIN_INIT_SUCCESS = 0x8, 174 + }; 175 + 176 + enum psp_memory_training_ops { 177 + PSP_MEM_TRAIN_SEND_LONG_MSG = 0x1, 178 + PSP_MEM_TRAIN_SAVE = 0x2, 179 + PSP_MEM_TRAIN_RESTORE = 0x4, 180 + PSP_MEM_TRAIN_SEND_SHORT_MSG = 0x8, 181 + PSP_MEM_TRAIN_COLD_BOOT = PSP_MEM_TRAIN_SEND_LONG_MSG, 182 + PSP_MEM_TRAIN_RESUME = PSP_MEM_TRAIN_SEND_SHORT_MSG, 183 + }; 184 + 185 + struct psp_memory_training_context { 186 + /*training data size*/ 187 + u64 train_data_size; 188 + /* 189 + * sys_cache 190 + * cpu virtual address 191 + * system memory buffer that used to store the training data. 192 + */ 193 + void *sys_cache; 194 + 195 + /*vram offset of the p2c training data*/ 196 + u64 p2c_train_data_offset; 197 + struct amdgpu_bo *p2c_bo; 198 + 199 + /*vram offset of the c2p training data*/ 200 + u64 c2p_train_data_offset; 201 + struct amdgpu_bo *c2p_bo; 202 + 203 + enum psp_memory_training_init_flag init; 204 + u32 training_cnt; 167 205 }; 168 206 169 207 struct psp_context ··· 287 239 struct psp_hdcp_context hdcp_context; 288 240 struct psp_dtm_context dtm_context; 289 241 struct mutex mutex; 242 + struct psp_memory_training_context mem_train_ctx; 290 243 }; 291 244 292 245 struct amdgpu_psp_funcs { ··· 330 281 (psp)->funcs->xgmi_set_topology_info((psp), (num_device), (topology)) : -EINVAL) 331 282 #define psp_rlc_autoload(psp) \ 332 283 ((psp)->funcs->rlc_autoload_start ? (psp)->funcs->rlc_autoload_start((psp)) : 0) 284 + #define psp_mem_training_init(psp) \ 285 + ((psp)->funcs->mem_training_init ? (psp)->funcs->mem_training_init((psp)) : 0) 286 + #define psp_mem_training_fini(psp) \ 287 + ((psp)->funcs->mem_training_fini ? (psp)->funcs->mem_training_fini((psp)) : 0) 288 + #define psp_mem_training(psp, ops) \ 289 + ((psp)->funcs->mem_training ? (psp)->funcs->mem_training((psp), (ops)) : 0) 333 290 334 291 #define amdgpu_psp_check_fw_loading_status(adev, i) (adev)->firmware.funcs->check_fw_loading_status((adev), (i)) 335 292
+54 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
··· 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 { ··· 218 215 * value to the address. 219 216 * 220 217 * Second member: struct ras_debug_if::op. 221 - * It has three kinds of operations. 218 + * It has four kinds of operations. 222 219 * 223 220 * - 0: disable RAS on the block. Take ::head as its data. 224 221 * - 1: enable RAS on the block. Take ::head as its data. 225 222 * - 2: inject errors on the block. Take ::inject as its data. 223 + * - 3: reboot on unrecoverable error 226 224 * 227 225 * How to use the interface? 228 226 * programs: ··· 232 228 * 233 229 * .. code-block:: bash 234 230 * 235 - * echo op block [error [sub_blcok address value]] > .../ras/ras_ctrl 231 + * echo op block [error [sub_block address value]] > .../ras/ras_ctrl 236 232 * 237 233 * op: disable, enable, inject 238 234 * disable: only block is needed 239 235 * enable: block and error are needed 240 236 * inject: error, address, value are needed 241 - * block: umc, smda, gfx, ......... 237 + * block: umc, sdma, gfx, ......... 242 238 * see ras_block_string[] for details 243 239 * error: ue, ce 244 240 * ue: multi_uncorrectable ··· 291 287 if ((data.inject.address >= adev->gmc.mc_vram_size) || 292 288 (data.inject.address >= RAS_UMC_INJECT_ADDR_LIMIT)) { 293 289 ret = -EINVAL; 290 + break; 291 + } 292 + 293 + /* umc ce/ue error injection for a bad page is not allowed */ 294 + if ((data.head.block == AMDGPU_RAS_BLOCK__UMC) && 295 + amdgpu_ras_check_bad_page(adev, data.inject.address)) { 296 + DRM_WARN("RAS WARN: 0x%llx has been marked as bad before error injection!\n", 297 + data.inject.address); 294 298 break; 295 299 } 296 300 ··· 1442 1430 return ret; 1443 1431 } 1444 1432 1433 + /* 1434 + * check if an address belongs to bad page 1435 + * 1436 + * Note: this check is only for umc block 1437 + */ 1438 + static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev, 1439 + uint64_t addr) 1440 + { 1441 + struct amdgpu_ras *con = amdgpu_ras_get_context(adev); 1442 + struct ras_err_handler_data *data; 1443 + int i; 1444 + bool ret = false; 1445 + 1446 + if (!con || !con->eh_data) 1447 + return ret; 1448 + 1449 + mutex_lock(&con->recovery_lock); 1450 + data = con->eh_data; 1451 + if (!data) 1452 + goto out; 1453 + 1454 + addr >>= AMDGPU_GPU_PAGE_SHIFT; 1455 + for (i = 0; i < data->count; i++) 1456 + if (addr == data->bps[i].retired_page) { 1457 + ret = true; 1458 + goto out; 1459 + } 1460 + 1461 + out: 1462 + mutex_unlock(&con->recovery_lock); 1463 + return ret; 1464 + } 1465 + 1445 1466 /* called in gpu recovery/init */ 1446 1467 int amdgpu_ras_reserve_bad_pages(struct amdgpu_device *adev) 1447 1468 { ··· 1888 1843 1889 1844 void amdgpu_ras_global_ras_isr(struct amdgpu_device *adev) 1890 1845 { 1846 + uint32_t hw_supported, supported; 1847 + 1848 + amdgpu_ras_check_supported(adev, &hw_supported, &supported); 1849 + if (!hw_supported) 1850 + return; 1851 + 1891 1852 if (atomic_cmpxchg(&amdgpu_ras_in_intr, 0, 1) == 0) { 1892 1853 DRM_WARN("RAS event of type ERREVENT_ATHUB_INTERRUPT detected!\n"); 1893 1854
+9 -9
drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
··· 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 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 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 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 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 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 );
+110 -9
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
··· 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. ··· 1808 1726 return r; 1809 1727 } 1810 1728 1729 + /* 1730 + *The reserved vram for memory training must be pinned to the specified 1731 + *place on the VRAM, so reserve it early. 1732 + */ 1733 + r = amdgpu_ttm_training_reserve_vram_init(adev); 1734 + if (r) 1735 + return r; 1736 + 1811 1737 /* allocate memory as required for VGA 1812 1738 * This is used for VGA emulation and pre-OS scanout buffers to 1813 1739 * avoid display artifacts while transitioning between pre-OS ··· 1826 1736 NULL, &stolen_vga_buf); 1827 1737 if (r) 1828 1738 return r; 1739 + 1740 + /* 1741 + * reserve one TMR (64K) memory at the top of VRAM which holds 1742 + * IP Discovery data and is protected by PSP. 1743 + */ 1744 + r = amdgpu_bo_create_kernel_at(adev, 1745 + adev->gmc.real_vram_size - DISCOVERY_TMR_SIZE, 1746 + DISCOVERY_TMR_SIZE, 1747 + AMDGPU_GEM_DOMAIN_VRAM, 1748 + &adev->discovery_memory, 1749 + NULL); 1750 + if (r) 1751 + return r; 1752 + 1829 1753 DRM_INFO("amdgpu: %uM of VRAM memory ready\n", 1830 1754 (unsigned) (adev->gmc.real_vram_size / (1024 * 1024))); 1831 1755 ··· 1904 1800 void *stolen_vga_buf; 1905 1801 /* return the VGA stolen memory (if any) back to VRAM */ 1906 1802 amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, &stolen_vga_buf); 1803 + 1804 + /* return the IP Discovery TMR memory back to VRAM */ 1805 + amdgpu_bo_free_kernel(&adev->discovery_memory, NULL, NULL); 1907 1806 } 1908 1807 1909 1808 /** ··· 1918 1811 return; 1919 1812 1920 1813 amdgpu_ttm_debugfs_fini(adev); 1814 + amdgpu_ttm_training_reserve_vram_fini(adev); 1921 1815 amdgpu_ttm_fw_reserve_vram_fini(adev); 1922 1816 if (adev->mman.aper_base_kaddr) 1923 1817 iounmap(adev->mman.aper_base_kaddr); ··· 2015 1907 *addr += (u64)window * AMDGPU_GTT_MAX_TRANSFER_SIZE * 2016 1908 AMDGPU_GPU_PAGE_SIZE; 2017 1909 2018 - num_dw = adev->mman.buffer_funcs->copy_num_dw; 2019 - while (num_dw & 0x7) 2020 - num_dw++; 2021 - 1910 + num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8); 2022 1911 num_bytes = num_pages * 8; 2023 1912 2024 1913 r = amdgpu_job_alloc_with_ib(adev, num_dw * 4 + num_bytes, &job); ··· 2075 1970 2076 1971 max_bytes = adev->mman.buffer_funcs->copy_max_bytes; 2077 1972 num_loops = DIV_ROUND_UP(byte_count, max_bytes); 2078 - num_dw = num_loops * adev->mman.buffer_funcs->copy_num_dw; 2079 - 2080 - /* for IB padding */ 2081 - while (num_dw & 0x7) 2082 - num_dw++; 1973 + num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->copy_num_dw, 8); 2083 1974 2084 1975 r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, &job); 2085 1976 if (r)
+24 -9
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
··· 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 ··· 433 428 * 434 429 * Open up a stream for HW test 435 430 */ 436 - int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, 437 - struct dma_fence **fence) 431 + static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, 432 + struct amdgpu_bo *bo, 433 + struct dma_fence **fence) 438 434 { 439 435 const unsigned ib_size_dw = 1024; 440 436 struct amdgpu_job *job; 441 437 struct amdgpu_ib *ib; 442 438 struct dma_fence *f = NULL; 443 - uint64_t dummy; 439 + uint64_t addr; 444 440 int i, r; 445 441 446 442 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); ··· 450 444 451 445 ib = &job->ibs[0]; 452 446 453 - dummy = ib->gpu_addr + 1024; 447 + addr = amdgpu_bo_gpu_offset(bo); 454 448 455 449 /* stitch together an VCE create msg */ 456 450 ib->length_dw = 0; ··· 482 476 483 477 ib->ptr[ib->length_dw++] = 0x00000014; /* len */ 484 478 ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */ 485 - ib->ptr[ib->length_dw++] = upper_32_bits(dummy); 486 - ib->ptr[ib->length_dw++] = dummy; 479 + ib->ptr[ib->length_dw++] = upper_32_bits(addr); 480 + ib->ptr[ib->length_dw++] = addr; 487 481 ib->ptr[ib->length_dw++] = 0x00000001; 488 482 489 483 for (i = ib->length_dw; i < ib_size_dw; ++i) ··· 513 507 * 514 508 * Close up a stream for HW test or if userspace failed to do so 515 509 */ 516 - int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, 517 - bool direct, struct dma_fence **fence) 510 + static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, 511 + bool direct, struct dma_fence **fence) 518 512 { 519 513 const unsigned ib_size_dw = 1024; 520 514 struct amdgpu_job *job; ··· 1116 1110 int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout) 1117 1111 { 1118 1112 struct dma_fence *fence = NULL; 1113 + struct amdgpu_bo *bo = NULL; 1119 1114 long r; 1120 1115 1121 1116 /* skip vce ring1/2 ib test for now, since it's not reliable */ 1122 1117 if (ring != &ring->adev->vce.ring[0]) 1123 1118 return 0; 1124 1119 1125 - r = amdgpu_vce_get_create_msg(ring, 1, NULL); 1120 + r = amdgpu_bo_create_reserved(ring->adev, 512, PAGE_SIZE, 1121 + AMDGPU_GEM_DOMAIN_VRAM, 1122 + &bo, NULL, NULL); 1123 + if (r) 1124 + return r; 1125 + 1126 + r = amdgpu_vce_get_create_msg(ring, 1, bo, NULL); 1126 1127 if (r) 1127 1128 goto error; 1128 1129 ··· 1145 1132 1146 1133 error: 1147 1134 dma_fence_put(fence); 1135 + amdgpu_bo_unreserve(bo); 1136 + amdgpu_bo_unref(&bo); 1148 1137 return r; 1149 1138 }
-4
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h
··· 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);
+23 -12
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
··· 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); ··· 584 583 return r; 585 584 586 585 ib = &job->ibs[0]; 587 - dummy = ib->gpu_addr + 1024; 586 + addr = amdgpu_bo_gpu_offset(bo); 588 587 589 588 ib->length_dw = 0; 590 589 ib->ptr[ib->length_dw++] = 0x00000018; 591 590 ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ 592 591 ib->ptr[ib->length_dw++] = handle; 593 - ib->ptr[ib->length_dw++] = upper_32_bits(dummy); 594 - ib->ptr[ib->length_dw++] = dummy; 592 + ib->ptr[ib->length_dw++] = upper_32_bits(addr); 593 + ib->ptr[ib->length_dw++] = addr; 595 594 ib->ptr[ib->length_dw++] = 0x0000000b; 596 595 597 596 ib->ptr[ib->length_dw++] = 0x00000014; ··· 622 621 } 623 622 624 623 static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, 625 - struct dma_fence **fence) 624 + struct amdgpu_bo *bo, 625 + struct dma_fence **fence) 626 626 { 627 627 const unsigned ib_size_dw = 16; 628 628 struct amdgpu_job *job; 629 629 struct amdgpu_ib *ib; 630 630 struct dma_fence *f = NULL; 631 - uint64_t dummy; 631 + uint64_t addr; 632 632 int i, r; 633 633 634 634 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); ··· 637 635 return r; 638 636 639 637 ib = &job->ibs[0]; 640 - dummy = ib->gpu_addr + 1024; 638 + addr = amdgpu_bo_gpu_offset(bo); 641 639 642 640 ib->length_dw = 0; 643 641 ib->ptr[ib->length_dw++] = 0x00000018; 644 642 ib->ptr[ib->length_dw++] = 0x00000001; 645 643 ib->ptr[ib->length_dw++] = handle; 646 - ib->ptr[ib->length_dw++] = upper_32_bits(dummy); 647 - ib->ptr[ib->length_dw++] = dummy; 644 + ib->ptr[ib->length_dw++] = upper_32_bits(addr); 645 + ib->ptr[ib->length_dw++] = addr; 648 646 ib->ptr[ib->length_dw++] = 0x0000000b; 649 647 650 648 ib->ptr[ib->length_dw++] = 0x00000014; ··· 677 675 int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) 678 676 { 679 677 struct dma_fence *fence = NULL; 678 + struct amdgpu_bo *bo = NULL; 680 679 long r; 681 680 682 - r = amdgpu_vcn_enc_get_create_msg(ring, 1, NULL); 681 + r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE, 682 + AMDGPU_GEM_DOMAIN_VRAM, 683 + &bo, NULL, NULL); 684 + if (r) 685 + return r; 686 + 687 + r = amdgpu_vcn_enc_get_create_msg(ring, 1, bo, NULL); 683 688 if (r) 684 689 goto error; 685 690 686 - r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, &fence); 691 + r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, bo, &fence); 687 692 if (r) 688 693 goto error; 689 694 ··· 702 693 703 694 error: 704 695 dma_fence_put(fence); 696 + amdgpu_bo_unreserve(bo); 697 + amdgpu_bo_unref(&bo); 705 698 return r; 706 699 } 707 700
+10 -9
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 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); ··· 2999 2989 */ 3000 2990 list_del(&mapping->list); 3001 2991 kfree(mapping); 3002 - } 3003 - list_for_each_entry_safe(mapping, tmp, &vm->freed, list) { 3004 - if (mapping->flags & AMDGPU_PTE_PRT && prt_fini_needed) { 3005 - amdgpu_vm_prt_fini(adev, vm); 3006 - prt_fini_needed = false; 3007 - } 3008 - 3009 - list_del(&mapping->list); 3010 - amdgpu_vm_free_mapping(adev, vm, mapping, NULL); 3011 2992 } 3012 2993 3013 2994 dma_fence_put(vm->last_update);
+43 -5
drivers/gpu/drm/amd/amdgpu/cik.c
··· 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 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)
+3
drivers/gpu/drm/amd/amdgpu/cik.h
··· 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
+5 -8
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
··· 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 }
+665 -331
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
··· 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, ··· 3990 3978 { SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 1, 16}, 3991 3979 { SOC15_REG_ENTRY(GC, 0, mmTCP_ATC_EDC_GATCL1_CNT), 0, 4, 16}, 3992 3980 { SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT), 0, 4, 16}, 3981 + { SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 0, 4, 16}, 3993 3982 { SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 0, 4, 16}, 3994 3983 { SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 0, 4, 6}, 3995 3984 { SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 0, 4, 16}, ··· 4287 4274 { 4288 4275 amdgpu_gfx_rlc_enter_safe_mode(adev); 4289 4276 4290 - if (is_support_sw_smu(adev) && !enable) 4291 - smu_set_gfx_cgpg(&adev->smu, enable); 4292 - 4293 4277 if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_PG) && enable) { 4294 4278 gfx_v9_0_enable_gfx_cg_power_gating(adev, true); 4295 4279 if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PIPELINE) 4296 4280 gfx_v9_0_enable_gfx_pipeline_powergating(adev, true); 4297 4281 } else { 4298 4282 gfx_v9_0_enable_gfx_cg_power_gating(adev, false); 4299 - gfx_v9_0_enable_gfx_pipeline_powergating(adev, false); 4283 + if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PIPELINE) 4284 + gfx_v9_0_enable_gfx_pipeline_powergating(adev, false); 4300 4285 } 4301 4286 4302 4287 amdgpu_gfx_rlc_exit_safe_mode(adev); ··· 4563 4552 gfx_v9_0_enable_cp_power_gating(adev, false); 4564 4553 4565 4554 /* update gfx cgpg state */ 4566 - if (is_support_sw_smu(adev) && enable) 4567 - smu_set_gfx_cgpg(&adev->smu, enable); 4568 4555 gfx_v9_0_update_gfx_cg_power_gating(adev, enable); 4569 4556 4570 4557 /* update mgcg state */ ··· 5446 5437 return 0; 5447 5438 } 5448 5439 5449 - static const struct { 5450 - const char *name; 5451 - uint32_t ip; 5452 - uint32_t inst; 5453 - uint32_t seg; 5454 - uint32_t reg_offset; 5455 - uint32_t per_se_instance; 5456 - int32_t num_instance; 5457 - uint32_t sec_count_mask; 5458 - uint32_t ded_count_mask; 5459 - } gfx_ras_edc_regs[] = { 5460 - { "CPC_SCRATCH", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_SCRATCH_CNT), 0, 1, 5461 - REG_FIELD_MASK(CPC_EDC_SCRATCH_CNT, SEC_COUNT), 5462 - REG_FIELD_MASK(CPC_EDC_SCRATCH_CNT, DED_COUNT) }, 5463 - { "CPC_UCODE", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_UCODE_CNT), 0, 1, 5464 - REG_FIELD_MASK(CPC_EDC_UCODE_CNT, SEC_COUNT), 5465 - REG_FIELD_MASK(CPC_EDC_UCODE_CNT, DED_COUNT) }, 5466 - { "CPF_ROQ_ME1", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT), 0, 1, 5467 - REG_FIELD_MASK(CPF_EDC_ROQ_CNT, COUNT_ME1), 0 }, 5468 - { "CPF_ROQ_ME2", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT), 0, 1, 5469 - REG_FIELD_MASK(CPF_EDC_ROQ_CNT, COUNT_ME2), 0 }, 5470 - { "CPF_TAG", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_TAG_CNT), 0, 1, 5471 - REG_FIELD_MASK(CPF_EDC_TAG_CNT, SEC_COUNT), 5472 - REG_FIELD_MASK(CPF_EDC_TAG_CNT, DED_COUNT) }, 5473 - { "CPG_DMA_ROQ", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_DMA_CNT), 0, 1, 5474 - REG_FIELD_MASK(CPG_EDC_DMA_CNT, ROQ_COUNT), 0 }, 5475 - { "CPG_DMA_TAG", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_DMA_CNT), 0, 1, 5476 - REG_FIELD_MASK(CPG_EDC_DMA_CNT, TAG_SEC_COUNT), 5477 - REG_FIELD_MASK(CPG_EDC_DMA_CNT, TAG_DED_COUNT) }, 5478 - { "CPG_TAG", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_TAG_CNT), 0, 1, 5479 - REG_FIELD_MASK(CPG_EDC_TAG_CNT, SEC_COUNT), 5480 - REG_FIELD_MASK(CPG_EDC_TAG_CNT, DED_COUNT) }, 5481 - { "DC_CSINVOC", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_CSINVOC_CNT), 0, 1, 5482 - REG_FIELD_MASK(DC_EDC_CSINVOC_CNT, COUNT_ME1), 0 }, 5483 - { "DC_RESTORE", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_RESTORE_CNT), 0, 1, 5484 - REG_FIELD_MASK(DC_EDC_RESTORE_CNT, COUNT_ME1), 0 }, 5485 - { "DC_STATE", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_STATE_CNT), 0, 1, 5486 - REG_FIELD_MASK(DC_EDC_STATE_CNT, COUNT_ME1), 0 }, 5487 - { "GDS_MEM", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_CNT), 0, 1, 5488 - REG_FIELD_MASK(GDS_EDC_CNT, GDS_MEM_SEC), 5489 - REG_FIELD_MASK(GDS_EDC_CNT, GDS_MEM_DED) }, 5490 - { "GDS_INPUT_QUEUE", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_CNT), 0, 1, 5491 - REG_FIELD_MASK(GDS_EDC_CNT, GDS_INPUT_QUEUE_SED), 0 }, 5440 + 5441 + static const struct ras_gfx_subblock_reg ras_subblock_regs[] = { 5442 + { "CPC_SCRATCH", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_SCRATCH_CNT), 5443 + SOC15_REG_FIELD(CPC_EDC_SCRATCH_CNT, SEC_COUNT), 5444 + SOC15_REG_FIELD(CPC_EDC_SCRATCH_CNT, DED_COUNT) 5445 + }, 5446 + { "CPC_UCODE", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_UCODE_CNT), 5447 + SOC15_REG_FIELD(CPC_EDC_UCODE_CNT, SEC_COUNT), 5448 + SOC15_REG_FIELD(CPC_EDC_UCODE_CNT, DED_COUNT) 5449 + }, 5450 + { "CPF_ROQ_ME1", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT), 5451 + SOC15_REG_FIELD(CPF_EDC_ROQ_CNT, COUNT_ME1), 5452 + 0, 0 5453 + }, 5454 + { "CPF_ROQ_ME2", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT), 5455 + SOC15_REG_FIELD(CPF_EDC_ROQ_CNT, COUNT_ME2), 5456 + 0, 0 5457 + }, 5458 + { "CPF_TAG", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_TAG_CNT), 5459 + SOC15_REG_FIELD(CPF_EDC_TAG_CNT, SEC_COUNT), 5460 + SOC15_REG_FIELD(CPF_EDC_TAG_CNT, DED_COUNT) 5461 + }, 5462 + { "CPG_DMA_ROQ", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_DMA_CNT), 5463 + SOC15_REG_FIELD(CPG_EDC_DMA_CNT, ROQ_COUNT), 5464 + 0, 0 5465 + }, 5466 + { "CPG_DMA_TAG", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_DMA_CNT), 5467 + SOC15_REG_FIELD(CPG_EDC_DMA_CNT, TAG_SEC_COUNT), 5468 + SOC15_REG_FIELD(CPG_EDC_DMA_CNT, TAG_DED_COUNT) 5469 + }, 5470 + { "CPG_TAG", SOC15_REG_ENTRY(GC, 0, mmCPG_EDC_TAG_CNT), 5471 + SOC15_REG_FIELD(CPG_EDC_TAG_CNT, SEC_COUNT), 5472 + SOC15_REG_FIELD(CPG_EDC_TAG_CNT, DED_COUNT) 5473 + }, 5474 + { "DC_CSINVOC", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_CSINVOC_CNT), 5475 + SOC15_REG_FIELD(DC_EDC_CSINVOC_CNT, COUNT_ME1), 5476 + 0, 0 5477 + }, 5478 + { "DC_RESTORE", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_RESTORE_CNT), 5479 + SOC15_REG_FIELD(DC_EDC_RESTORE_CNT, COUNT_ME1), 5480 + 0, 0 5481 + }, 5482 + { "DC_STATE", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_STATE_CNT), 5483 + SOC15_REG_FIELD(DC_EDC_STATE_CNT, COUNT_ME1), 5484 + 0, 0 5485 + }, 5486 + { "GDS_MEM", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_CNT), 5487 + SOC15_REG_FIELD(GDS_EDC_CNT, GDS_MEM_SEC), 5488 + SOC15_REG_FIELD(GDS_EDC_CNT, GDS_MEM_DED) 5489 + }, 5490 + { "GDS_INPUT_QUEUE", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_CNT), 5491 + SOC15_REG_FIELD(GDS_EDC_CNT, GDS_INPUT_QUEUE_SED), 5492 + 0, 0 5493 + }, 5492 5494 { "GDS_ME0_CS_PIPE_MEM", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), 5493 - 0, 1, REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_SEC), 5494 - REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_DED) }, 5495 + SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_SEC), 5496 + SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_DED) 5497 + }, 5495 5498 { "GDS_OA_PHY_PHY_CMD_RAM_MEM", 5496 - SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), 0, 1, 5497 - REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_SEC), 5498 - REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_DED) }, 5499 + SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), 5500 + SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_SEC), 5501 + SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_DED) 5502 + }, 5499 5503 { "GDS_OA_PHY_PHY_DATA_RAM_MEM", 5500 - SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), 0, 1, 5501 - REG_FIELD_MASK(GDS_EDC_OA_PHY_CNT, PHY_DATA_RAM_MEM_SED), 0 }, 5504 + SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), 5505 + SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, PHY_DATA_RAM_MEM_SED), 5506 + 0, 0 5507 + }, 5502 5508 { "GDS_OA_PIPE_ME1_PIPE0_PIPE_MEM", 5503 - SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1, 5504 - REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_SEC), 5505 - REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_DED) }, 5509 + SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 5510 + SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_SEC), 5511 + SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_DED) 5512 + }, 5506 5513 { "GDS_OA_PIPE_ME1_PIPE1_PIPE_MEM", 5507 - SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1, 5508 - REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_SEC), 5509 - REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_DED) }, 5514 + SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 5515 + SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_SEC), 5516 + SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_DED) 5517 + }, 5510 5518 { "GDS_OA_PIPE_ME1_PIPE2_PIPE_MEM", 5511 - SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1, 5512 - REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_SEC), 5513 - REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_DED) }, 5519 + SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 5520 + SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_SEC), 5521 + SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_DED) 5522 + }, 5514 5523 { "GDS_OA_PIPE_ME1_PIPE3_PIPE_MEM", 5515 - SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1, 5516 - REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_SEC), 5517 - REG_FIELD_MASK(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_DED) }, 5518 - { "SPI_SR_MEM", SOC15_REG_ENTRY(GC, 0, mmSPI_EDC_CNT), 1, 1, 5519 - REG_FIELD_MASK(SPI_EDC_CNT, SPI_SR_MEM_SED_COUNT), 0 }, 5520 - { "TA_FS_DFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16, 5521 - REG_FIELD_MASK(TA_EDC_CNT, TA_FS_DFIFO_SEC_COUNT), 5522 - REG_FIELD_MASK(TA_EDC_CNT, TA_FS_DFIFO_DED_COUNT) }, 5523 - { "TA_FS_AFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16, 5524 - REG_FIELD_MASK(TA_EDC_CNT, TA_FS_AFIFO_SED_COUNT), 0 }, 5525 - { "TA_FL_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16, 5526 - REG_FIELD_MASK(TA_EDC_CNT, TA_FL_LFIFO_SED_COUNT), 0 }, 5527 - { "TA_FX_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16, 5528 - REG_FIELD_MASK(TA_EDC_CNT, TA_FX_LFIFO_SED_COUNT), 0 }, 5529 - { "TA_FS_CFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 1, 16, 5530 - REG_FIELD_MASK(TA_EDC_CNT, TA_FS_CFIFO_SED_COUNT), 0 }, 5531 - { "TCA_HOLE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT), 0, 2, 5532 - REG_FIELD_MASK(TCA_EDC_CNT, HOLE_FIFO_SED_COUNT), 0 }, 5533 - { "TCA_REQ_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT), 0, 2, 5534 - REG_FIELD_MASK(TCA_EDC_CNT, REQ_FIFO_SED_COUNT), 0 }, 5535 - { "TCC_CACHE_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, 5536 - REG_FIELD_MASK(TCC_EDC_CNT, CACHE_DATA_SEC_COUNT), 5537 - REG_FIELD_MASK(TCC_EDC_CNT, CACHE_DATA_DED_COUNT) }, 5538 - { "TCC_CACHE_DIRTY", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, 5539 - REG_FIELD_MASK(TCC_EDC_CNT, CACHE_DIRTY_SEC_COUNT), 5540 - REG_FIELD_MASK(TCC_EDC_CNT, CACHE_DIRTY_DED_COUNT) }, 5541 - { "TCC_HIGH_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, 5542 - REG_FIELD_MASK(TCC_EDC_CNT, HIGH_RATE_TAG_SEC_COUNT), 5543 - REG_FIELD_MASK(TCC_EDC_CNT, HIGH_RATE_TAG_DED_COUNT) }, 5544 - { "TCC_LOW_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, 5545 - REG_FIELD_MASK(TCC_EDC_CNT, LOW_RATE_TAG_SEC_COUNT), 5546 - REG_FIELD_MASK(TCC_EDC_CNT, LOW_RATE_TAG_DED_COUNT) }, 5547 - { "TCC_SRC_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, 5548 - REG_FIELD_MASK(TCC_EDC_CNT, SRC_FIFO_SEC_COUNT), 5549 - REG_FIELD_MASK(TCC_EDC_CNT, SRC_FIFO_DED_COUNT) }, 5550 - { "TCC_IN_USE_DEC", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, 5551 - REG_FIELD_MASK(TCC_EDC_CNT, IN_USE_DEC_SED_COUNT), 0 }, 5552 - { "TCC_IN_USE_TRANSFER", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, 5553 - REG_FIELD_MASK(TCC_EDC_CNT, IN_USE_TRANSFER_SED_COUNT), 0 }, 5554 - { "TCC_LATENCY_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, 5555 - REG_FIELD_MASK(TCC_EDC_CNT, LATENCY_FIFO_SED_COUNT), 0 }, 5556 - { "TCC_RETURN_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, 5557 - REG_FIELD_MASK(TCC_EDC_CNT, RETURN_DATA_SED_COUNT), 0 }, 5558 - { "TCC_RETURN_CONTROL", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, 5559 - REG_FIELD_MASK(TCC_EDC_CNT, RETURN_CONTROL_SED_COUNT), 0 }, 5560 - { "TCC_UC_ATOMIC_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 16, 5561 - REG_FIELD_MASK(TCC_EDC_CNT, UC_ATOMIC_FIFO_SED_COUNT), 0 }, 5562 - { "TCC_WRITE_RETURN", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, 16, 5563 - REG_FIELD_MASK(TCC_EDC_CNT2, WRITE_RETURN_SED_COUNT), 0 }, 5564 - { "TCC_WRITE_CACHE_READ", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, 16, 5565 - REG_FIELD_MASK(TCC_EDC_CNT2, WRITE_CACHE_READ_SED_COUNT), 0 }, 5566 - { "TCC_SRC_FIFO_NEXT_RAM", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, 5567 - 16, REG_FIELD_MASK(TCC_EDC_CNT2, SRC_FIFO_NEXT_RAM_SED_COUNT), 0 }, 5524 + SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 5525 + SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_SEC), 5526 + SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_DED) 5527 + }, 5528 + { "SPI_SR_MEM", SOC15_REG_ENTRY(GC, 0, mmSPI_EDC_CNT), 5529 + SOC15_REG_FIELD(SPI_EDC_CNT, SPI_SR_MEM_SED_COUNT), 5530 + 0, 0 5531 + }, 5532 + { "TA_FS_DFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 5533 + SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_DFIFO_SEC_COUNT), 5534 + SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_DFIFO_DED_COUNT) 5535 + }, 5536 + { "TA_FS_AFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 5537 + SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_AFIFO_SED_COUNT), 5538 + 0, 0 5539 + }, 5540 + { "TA_FL_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 5541 + SOC15_REG_FIELD(TA_EDC_CNT, TA_FL_LFIFO_SED_COUNT), 5542 + 0, 0 5543 + }, 5544 + { "TA_FX_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 5545 + SOC15_REG_FIELD(TA_EDC_CNT, TA_FX_LFIFO_SED_COUNT), 5546 + 0, 0 5547 + }, 5548 + { "TA_FS_CFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 5549 + SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_CFIFO_SED_COUNT), 5550 + 0, 0 5551 + }, 5552 + { "TCA_HOLE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT), 5553 + SOC15_REG_FIELD(TCA_EDC_CNT, HOLE_FIFO_SED_COUNT), 5554 + 0, 0 5555 + }, 5556 + { "TCA_REQ_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT), 5557 + SOC15_REG_FIELD(TCA_EDC_CNT, REQ_FIFO_SED_COUNT), 5558 + 0, 0 5559 + }, 5560 + { "TCC_CACHE_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 5561 + SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DATA_SEC_COUNT), 5562 + SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DATA_DED_COUNT) 5563 + }, 5564 + { "TCC_CACHE_DIRTY", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 5565 + SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DIRTY_SEC_COUNT), 5566 + SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DIRTY_DED_COUNT) 5567 + }, 5568 + { "TCC_HIGH_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 5569 + SOC15_REG_FIELD(TCC_EDC_CNT, HIGH_RATE_TAG_SEC_COUNT), 5570 + SOC15_REG_FIELD(TCC_EDC_CNT, HIGH_RATE_TAG_DED_COUNT) 5571 + }, 5572 + { "TCC_LOW_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 5573 + SOC15_REG_FIELD(TCC_EDC_CNT, LOW_RATE_TAG_SEC_COUNT), 5574 + SOC15_REG_FIELD(TCC_EDC_CNT, LOW_RATE_TAG_DED_COUNT) 5575 + }, 5576 + { "TCC_SRC_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 5577 + SOC15_REG_FIELD(TCC_EDC_CNT, SRC_FIFO_SEC_COUNT), 5578 + SOC15_REG_FIELD(TCC_EDC_CNT, SRC_FIFO_DED_COUNT) 5579 + }, 5580 + { "TCC_IN_USE_DEC", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 5581 + SOC15_REG_FIELD(TCC_EDC_CNT, IN_USE_DEC_SED_COUNT), 5582 + 0, 0 5583 + }, 5584 + { "TCC_IN_USE_TRANSFER", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 5585 + SOC15_REG_FIELD(TCC_EDC_CNT, IN_USE_TRANSFER_SED_COUNT), 5586 + 0, 0 5587 + }, 5588 + { "TCC_LATENCY_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 5589 + SOC15_REG_FIELD(TCC_EDC_CNT, LATENCY_FIFO_SED_COUNT), 5590 + 0, 0 5591 + }, 5592 + { "TCC_RETURN_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 5593 + SOC15_REG_FIELD(TCC_EDC_CNT, RETURN_DATA_SED_COUNT), 5594 + 0, 0 5595 + }, 5596 + { "TCC_RETURN_CONTROL", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 5597 + SOC15_REG_FIELD(TCC_EDC_CNT, RETURN_CONTROL_SED_COUNT), 5598 + 0, 0 5599 + }, 5600 + { "TCC_UC_ATOMIC_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 5601 + SOC15_REG_FIELD(TCC_EDC_CNT, UC_ATOMIC_FIFO_SED_COUNT), 5602 + 0, 0 5603 + }, 5604 + { "TCC_WRITE_RETURN", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 5605 + SOC15_REG_FIELD(TCC_EDC_CNT2, WRITE_RETURN_SED_COUNT), 5606 + 0, 0 5607 + }, 5608 + { "TCC_WRITE_CACHE_READ", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 5609 + SOC15_REG_FIELD(TCC_EDC_CNT2, WRITE_CACHE_READ_SED_COUNT), 5610 + 0, 0 5611 + }, 5612 + { "TCC_SRC_FIFO_NEXT_RAM", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 5613 + SOC15_REG_FIELD(TCC_EDC_CNT2, SRC_FIFO_NEXT_RAM_SED_COUNT), 5614 + 0, 0 5615 + }, 5568 5616 { "TCC_LATENCY_FIFO_NEXT_RAM", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 5569 - 0, 16, REG_FIELD_MASK(TCC_EDC_CNT2, LATENCY_FIFO_NEXT_RAM_SED_COUNT), 5570 - 0 }, 5571 - { "TCC_CACHE_TAG_PROBE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, 5572 - 16, REG_FIELD_MASK(TCC_EDC_CNT2, CACHE_TAG_PROBE_FIFO_SED_COUNT), 0 }, 5617 + SOC15_REG_FIELD(TCC_EDC_CNT2, LATENCY_FIFO_NEXT_RAM_SED_COUNT), 5618 + 0, 0 5619 + }, 5620 + { "TCC_CACHE_TAG_PROBE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 5621 + SOC15_REG_FIELD(TCC_EDC_CNT2, CACHE_TAG_PROBE_FIFO_SED_COUNT), 5622 + 0, 0 5623 + }, 5573 5624 { "TCC_WRRET_TAG_WRITE_RETURN", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 5574 - 0, 16, REG_FIELD_MASK(TCC_EDC_CNT2, WRRET_TAG_WRITE_RETURN_SED_COUNT), 5575 - 0 }, 5576 - { "TCC_ATOMIC_RETURN_BUFFER", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, 5577 - 16, REG_FIELD_MASK(TCC_EDC_CNT2, ATOMIC_RETURN_BUFFER_SED_COUNT), 0 }, 5578 - { "TCI_WRITE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCI_EDC_CNT), 0, 72, 5579 - REG_FIELD_MASK(TCI_EDC_CNT, WRITE_RAM_SED_COUNT), 0 }, 5580 - { "TCP_CACHE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, 5581 - REG_FIELD_MASK(TCP_EDC_CNT_NEW, CACHE_RAM_SEC_COUNT), 5582 - REG_FIELD_MASK(TCP_EDC_CNT_NEW, CACHE_RAM_DED_COUNT) }, 5583 - { "TCP_LFIFO_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, 5584 - REG_FIELD_MASK(TCP_EDC_CNT_NEW, LFIFO_RAM_SEC_COUNT), 5585 - REG_FIELD_MASK(TCP_EDC_CNT_NEW, LFIFO_RAM_DED_COUNT) }, 5586 - { "TCP_CMD_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, 5587 - REG_FIELD_MASK(TCP_EDC_CNT_NEW, CMD_FIFO_SED_COUNT), 0 }, 5588 - { "TCP_VM_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, 5589 - REG_FIELD_MASK(TCP_EDC_CNT_NEW, VM_FIFO_SEC_COUNT), 0 }, 5590 - { "TCP_DB_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, 5591 - REG_FIELD_MASK(TCP_EDC_CNT_NEW, DB_RAM_SED_COUNT), 0 }, 5592 - { "TCP_UTCL1_LFIFO0", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, 5593 - REG_FIELD_MASK(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_SEC_COUNT), 5594 - REG_FIELD_MASK(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_DED_COUNT) }, 5595 - { "TCP_UTCL1_LFIFO1", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 1, 16, 5596 - REG_FIELD_MASK(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_SEC_COUNT), 5597 - REG_FIELD_MASK(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_DED_COUNT) }, 5598 - { "TD_SS_FIFO_LO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 1, 16, 5599 - REG_FIELD_MASK(TD_EDC_CNT, SS_FIFO_LO_SEC_COUNT), 5600 - REG_FIELD_MASK(TD_EDC_CNT, SS_FIFO_LO_DED_COUNT) }, 5601 - { "TD_SS_FIFO_HI", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 1, 16, 5602 - REG_FIELD_MASK(TD_EDC_CNT, SS_FIFO_HI_SEC_COUNT), 5603 - REG_FIELD_MASK(TD_EDC_CNT, SS_FIFO_HI_DED_COUNT) }, 5604 - { "TD_CS_FIFO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 1, 16, 5605 - REG_FIELD_MASK(TD_EDC_CNT, CS_FIFO_SED_COUNT), 0 }, 5606 - { "SQ_LDS_D", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, 5607 - REG_FIELD_MASK(SQ_EDC_CNT, LDS_D_SEC_COUNT), 5608 - REG_FIELD_MASK(SQ_EDC_CNT, LDS_D_DED_COUNT) }, 5609 - { "SQ_LDS_I", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, 5610 - REG_FIELD_MASK(SQ_EDC_CNT, LDS_I_SEC_COUNT), 5611 - REG_FIELD_MASK(SQ_EDC_CNT, LDS_I_DED_COUNT) }, 5612 - { "SQ_SGPR", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, 5613 - REG_FIELD_MASK(SQ_EDC_CNT, SGPR_SEC_COUNT), 5614 - REG_FIELD_MASK(SQ_EDC_CNT, SGPR_DED_COUNT) }, 5615 - { "SQ_VGPR0", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, 5616 - REG_FIELD_MASK(SQ_EDC_CNT, VGPR0_SEC_COUNT), 5617 - REG_FIELD_MASK(SQ_EDC_CNT, VGPR0_DED_COUNT) }, 5618 - { "SQ_VGPR1", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, 5619 - REG_FIELD_MASK(SQ_EDC_CNT, VGPR1_SEC_COUNT), 5620 - REG_FIELD_MASK(SQ_EDC_CNT, VGPR1_DED_COUNT) }, 5621 - { "SQ_VGPR2", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, 5622 - REG_FIELD_MASK(SQ_EDC_CNT, VGPR2_SEC_COUNT), 5623 - REG_FIELD_MASK(SQ_EDC_CNT, VGPR2_DED_COUNT) }, 5624 - { "SQ_VGPR3", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 1, 16, 5625 - REG_FIELD_MASK(SQ_EDC_CNT, VGPR3_SEC_COUNT), 5626 - REG_FIELD_MASK(SQ_EDC_CNT, VGPR3_DED_COUNT) }, 5625 + SOC15_REG_FIELD(TCC_EDC_CNT2, WRRET_TAG_WRITE_RETURN_SED_COUNT), 5626 + 0, 0 5627 + }, 5628 + { "TCC_ATOMIC_RETURN_BUFFER", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 5629 + SOC15_REG_FIELD(TCC_EDC_CNT2, ATOMIC_RETURN_BUFFER_SED_COUNT), 5630 + 0, 0 5631 + }, 5632 + { "TCI_WRITE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCI_EDC_CNT), 5633 + SOC15_REG_FIELD(TCI_EDC_CNT, WRITE_RAM_SED_COUNT), 5634 + 0, 0 5635 + }, 5636 + { "TCP_CACHE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 5637 + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, CACHE_RAM_SEC_COUNT), 5638 + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, CACHE_RAM_DED_COUNT) 5639 + }, 5640 + { "TCP_LFIFO_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 5641 + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, LFIFO_RAM_SEC_COUNT), 5642 + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, LFIFO_RAM_DED_COUNT) 5643 + }, 5644 + { "TCP_CMD_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 5645 + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, CMD_FIFO_SED_COUNT), 5646 + 0, 0 5647 + }, 5648 + { "TCP_VM_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 5649 + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, VM_FIFO_SEC_COUNT), 5650 + 0, 0 5651 + }, 5652 + { "TCP_DB_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 5653 + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, DB_RAM_SED_COUNT), 5654 + 0, 0 5655 + }, 5656 + { "TCP_UTCL1_LFIFO0", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 5657 + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_SEC_COUNT), 5658 + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_DED_COUNT) 5659 + }, 5660 + { "TCP_UTCL1_LFIFO1", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 5661 + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_SEC_COUNT), 5662 + SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_DED_COUNT) 5663 + }, 5664 + { "TD_SS_FIFO_LO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 5665 + SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_LO_SEC_COUNT), 5666 + SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_LO_DED_COUNT) 5667 + }, 5668 + { "TD_SS_FIFO_HI", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 5669 + SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_HI_SEC_COUNT), 5670 + SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_HI_DED_COUNT) 5671 + }, 5672 + { "TD_CS_FIFO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 5673 + SOC15_REG_FIELD(TD_EDC_CNT, CS_FIFO_SED_COUNT), 5674 + 0, 0 5675 + }, 5676 + { "SQ_LDS_D", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 5677 + SOC15_REG_FIELD(SQ_EDC_CNT, LDS_D_SEC_COUNT), 5678 + SOC15_REG_FIELD(SQ_EDC_CNT, LDS_D_DED_COUNT) 5679 + }, 5680 + { "SQ_LDS_I", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 5681 + SOC15_REG_FIELD(SQ_EDC_CNT, LDS_I_SEC_COUNT), 5682 + SOC15_REG_FIELD(SQ_EDC_CNT, LDS_I_DED_COUNT) 5683 + }, 5684 + { "SQ_SGPR", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 5685 + SOC15_REG_FIELD(SQ_EDC_CNT, SGPR_SEC_COUNT), 5686 + SOC15_REG_FIELD(SQ_EDC_CNT, SGPR_DED_COUNT) 5687 + }, 5688 + { "SQ_VGPR0", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 5689 + SOC15_REG_FIELD(SQ_EDC_CNT, VGPR0_SEC_COUNT), 5690 + SOC15_REG_FIELD(SQ_EDC_CNT, VGPR0_DED_COUNT) 5691 + }, 5692 + { "SQ_VGPR1", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 5693 + SOC15_REG_FIELD(SQ_EDC_CNT, VGPR1_SEC_COUNT), 5694 + SOC15_REG_FIELD(SQ_EDC_CNT, VGPR1_DED_COUNT) 5695 + }, 5696 + { "SQ_VGPR2", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 5697 + SOC15_REG_FIELD(SQ_EDC_CNT, VGPR2_SEC_COUNT), 5698 + SOC15_REG_FIELD(SQ_EDC_CNT, VGPR2_DED_COUNT) 5699 + }, 5700 + { "SQ_VGPR3", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 5701 + SOC15_REG_FIELD(SQ_EDC_CNT, VGPR3_SEC_COUNT), 5702 + SOC15_REG_FIELD(SQ_EDC_CNT, VGPR3_DED_COUNT) 5703 + }, 5627 5704 { "SQC_DATA_CU0_WRITE_DATA_BUF", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 5628 - 1, 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU0_WRITE_DATA_BUF_SEC_COUNT), 5629 - REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU0_WRITE_DATA_BUF_DED_COUNT) }, 5630 - { "SQC_DATA_CU0_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 1, 5631 - 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU0_UTCL1_LFIFO_SEC_COUNT), 5632 - REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU0_UTCL1_LFIFO_DED_COUNT) }, 5705 + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_WRITE_DATA_BUF_SEC_COUNT), 5706 + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_WRITE_DATA_BUF_DED_COUNT) 5707 + }, 5708 + { "SQC_DATA_CU0_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 5709 + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_UTCL1_LFIFO_SEC_COUNT), 5710 + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_UTCL1_LFIFO_DED_COUNT) 5711 + }, 5633 5712 { "SQC_DATA_CU1_WRITE_DATA_BUF", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 5634 - 1, 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU1_WRITE_DATA_BUF_SEC_COUNT), 5635 - REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU1_WRITE_DATA_BUF_DED_COUNT) }, 5636 - { "SQC_DATA_CU1_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 1, 5637 - 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU1_UTCL1_LFIFO_SEC_COUNT), 5638 - REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU1_UTCL1_LFIFO_DED_COUNT) }, 5713 + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_WRITE_DATA_BUF_SEC_COUNT), 5714 + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_WRITE_DATA_BUF_DED_COUNT) 5715 + }, 5716 + { "SQC_DATA_CU1_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 5717 + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_UTCL1_LFIFO_SEC_COUNT), 5718 + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_UTCL1_LFIFO_DED_COUNT) 5719 + }, 5639 5720 { "SQC_DATA_CU2_WRITE_DATA_BUF", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 5640 - 1, 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU2_WRITE_DATA_BUF_SEC_COUNT), 5641 - REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU2_WRITE_DATA_BUF_DED_COUNT) }, 5642 - { "SQC_DATA_CU2_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 1, 5643 - 6, REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_SEC_COUNT), 5644 - REG_FIELD_MASK(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_DED_COUNT) }, 5645 - { "SQC_INST_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 5646 - 6, REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_SEC_COUNT), 5647 - REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_DED_COUNT) }, 5648 - { "SQC_INST_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 5649 - 6, REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_SEC_COUNT), 5650 - REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_DED_COUNT) }, 5651 - { "SQC_DATA_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 5652 - 6, REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_SEC_COUNT), 5653 - REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_DED_COUNT) }, 5654 - { "SQC_DATA_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 5655 - 6, REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_SEC_COUNT), 5656 - REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_DED_COUNT) }, 5657 - { "SQC_INST_BANKA_UTCL1_MISS_FIFO", 5658 - SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 6, 5659 - REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_UTCL1_MISS_FIFO_SED_COUNT), 5660 - 0 }, 5661 - { "SQC_INST_BANKA_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 5662 - 6, REG_FIELD_MASK(SQC_EDC_CNT2, INST_BANKA_MISS_FIFO_SED_COUNT), 0 }, 5663 - { "SQC_DATA_BANKA_HIT_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 5664 - 6, REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_HIT_FIFO_SED_COUNT), 0 }, 5665 - { "SQC_DATA_BANKA_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 5666 - 6, REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_MISS_FIFO_SED_COUNT), 0 }, 5667 - { "SQC_DATA_BANKA_DIRTY_BIT_RAM", 5668 - SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 6, 5669 - REG_FIELD_MASK(SQC_EDC_CNT2, DATA_BANKA_DIRTY_BIT_RAM_SED_COUNT), 0 }, 5670 - { "SQC_INST_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 1, 6, 5671 - REG_FIELD_MASK(SQC_EDC_CNT2, INST_UTCL1_LFIFO_SEC_COUNT), 5672 - REG_FIELD_MASK(SQC_EDC_CNT2, INST_UTCL1_LFIFO_DED_COUNT) }, 5673 - { "SQC_INST_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, 5674 - 6, REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_SEC_COUNT), 5675 - REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_DED_COUNT) }, 5676 - { "SQC_INST_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, 5677 - 6, REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_SEC_COUNT), 5678 - REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_DED_COUNT) }, 5679 - { "SQC_DATA_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, 5680 - 6, REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_SEC_COUNT), 5681 - REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_DED_COUNT) }, 5682 - { "SQC_DATA_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, 5683 - 6, REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_SEC_COUNT), 5684 - REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_DED_COUNT) }, 5685 - { "SQC_INST_BANKB_UTCL1_MISS_FIFO", 5686 - SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, 6, 5687 - REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_UTCL1_MISS_FIFO_SED_COUNT), 5688 - 0 }, 5689 - { "SQC_INST_BANKB_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, 5690 - 6, REG_FIELD_MASK(SQC_EDC_CNT3, INST_BANKB_MISS_FIFO_SED_COUNT), 0 }, 5691 - { "SQC_DATA_BANKB_HIT_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, 5692 - 6, REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_HIT_FIFO_SED_COUNT), 0 }, 5693 - { "SQC_DATA_BANKB_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, 5694 - 6, REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_MISS_FIFO_SED_COUNT), 0 }, 5695 - { "SQC_DATA_BANKB_DIRTY_BIT_RAM", 5696 - SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 1, 6, 5697 - REG_FIELD_MASK(SQC_EDC_CNT3, DATA_BANKB_DIRTY_BIT_RAM_SED_COUNT), 0 }, 5698 - { "EA_DRAMRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, 5699 - REG_FIELD_MASK(GCEA_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT), 5700 - REG_FIELD_MASK(GCEA_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT) }, 5701 - { "EA_DRAMWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, 5702 - REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_CMDMEM_SEC_COUNT), 5703 - REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_CMDMEM_DED_COUNT) }, 5704 - { "EA_DRAMWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, 5705 - REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_DATAMEM_SEC_COUNT), 5706 - REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_DATAMEM_DED_COUNT) }, 5707 - { "EA_RRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, 5708 - REG_FIELD_MASK(GCEA_EDC_CNT, RRET_TAGMEM_SEC_COUNT), 5709 - REG_FIELD_MASK(GCEA_EDC_CNT, RRET_TAGMEM_DED_COUNT) }, 5710 - { "EA_WRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, 5711 - REG_FIELD_MASK(GCEA_EDC_CNT, WRET_TAGMEM_SEC_COUNT), 5712 - REG_FIELD_MASK(GCEA_EDC_CNT, WRET_TAGMEM_DED_COUNT) }, 5713 - { "EA_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, 5714 - REG_FIELD_MASK(GCEA_EDC_CNT, DRAMRD_PAGEMEM_SED_COUNT), 0 }, 5715 - { "EA_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, 5716 - REG_FIELD_MASK(GCEA_EDC_CNT, DRAMWR_PAGEMEM_SED_COUNT), 0 }, 5717 - { "EA_IORD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, 5718 - REG_FIELD_MASK(GCEA_EDC_CNT, IORD_CMDMEM_SED_COUNT), 0 }, 5719 - { "EA_IOWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, 5720 - REG_FIELD_MASK(GCEA_EDC_CNT, IOWR_CMDMEM_SED_COUNT), 0 }, 5721 - { "EA_IOWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 32, 5722 - REG_FIELD_MASK(GCEA_EDC_CNT, IOWR_DATAMEM_SED_COUNT), 0 }, 5723 - { "GMIRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, 5724 - REG_FIELD_MASK(GCEA_EDC_CNT2, GMIRD_CMDMEM_SEC_COUNT), 5725 - REG_FIELD_MASK(GCEA_EDC_CNT2, GMIRD_CMDMEM_DED_COUNT) }, 5726 - { "GMIWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, 5727 - REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_CMDMEM_SEC_COUNT), 5728 - REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_CMDMEM_DED_COUNT) }, 5729 - { "GMIWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, 5730 - REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_DATAMEM_SEC_COUNT), 5731 - REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_DATAMEM_DED_COUNT) }, 5732 - { "GMIRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, 5733 - REG_FIELD_MASK(GCEA_EDC_CNT2, GMIRD_PAGEMEM_SED_COUNT), 0 }, 5734 - { "GMIWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, 5735 - REG_FIELD_MASK(GCEA_EDC_CNT2, GMIWR_PAGEMEM_SED_COUNT), 0 }, 5736 - { "MAM_D0MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, 5737 - REG_FIELD_MASK(GCEA_EDC_CNT2, MAM_D0MEM_SED_COUNT), 0 }, 5738 - { "MAM_D1MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, 5739 - REG_FIELD_MASK(GCEA_EDC_CNT2, MAM_D1MEM_SED_COUNT), 0 }, 5740 - { "MAM_D2MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, 5741 - REG_FIELD_MASK(GCEA_EDC_CNT2, MAM_D2MEM_SED_COUNT), 0 }, 5742 - { "MAM_D3MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 32, 5743 - REG_FIELD_MASK(GCEA_EDC_CNT2, MAM_D3MEM_SED_COUNT), 0 }, 5721 + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_WRITE_DATA_BUF_SEC_COUNT), 5722 + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_WRITE_DATA_BUF_DED_COUNT) 5723 + }, 5724 + { "SQC_DATA_CU2_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 5725 + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_SEC_COUNT), 5726 + SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_DED_COUNT) 5727 + }, 5728 + { "SQC_INST_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 5729 + SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_SEC_COUNT), 5730 + SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_DED_COUNT) 5731 + }, 5732 + { "SQC_INST_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 5733 + SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_SEC_COUNT), 5734 + SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_DED_COUNT) 5735 + }, 5736 + { "SQC_DATA_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 5737 + SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_SEC_COUNT), 5738 + SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_DED_COUNT) 5739 + }, 5740 + { "SQC_DATA_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 5741 + SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_SEC_COUNT), 5742 + SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_DED_COUNT) 5743 + }, 5744 + { "SQC_INST_BANKA_UTCL1_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 5745 + SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_UTCL1_MISS_FIFO_SED_COUNT), 5746 + 0, 0 5747 + }, 5748 + { "SQC_INST_BANKA_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 5749 + SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_MISS_FIFO_SED_COUNT), 5750 + 0, 0 5751 + }, 5752 + { "SQC_DATA_BANKA_HIT_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 5753 + SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_HIT_FIFO_SED_COUNT), 5754 + 0, 0 5755 + }, 5756 + { "SQC_DATA_BANKA_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 5757 + SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_MISS_FIFO_SED_COUNT), 5758 + 0, 0 5759 + }, 5760 + { "SQC_DATA_BANKA_DIRTY_BIT_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 5761 + SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_DIRTY_BIT_RAM_SED_COUNT), 5762 + 0, 0 5763 + }, 5764 + { "SQC_INST_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 5765 + SOC15_REG_FIELD(SQC_EDC_CNT2, INST_UTCL1_LFIFO_SEC_COUNT), 5766 + SOC15_REG_FIELD(SQC_EDC_CNT2, INST_UTCL1_LFIFO_DED_COUNT) 5767 + }, 5768 + { "SQC_INST_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 5769 + SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_SEC_COUNT), 5770 + SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_DED_COUNT) 5771 + }, 5772 + { "SQC_INST_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 5773 + SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_SEC_COUNT), 5774 + SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_DED_COUNT) 5775 + }, 5776 + { "SQC_DATA_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 5777 + SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_SEC_COUNT), 5778 + SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_DED_COUNT) 5779 + }, 5780 + { "SQC_DATA_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 5781 + SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_SEC_COUNT), 5782 + SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_DED_COUNT) 5783 + }, 5784 + { "SQC_INST_BANKB_UTCL1_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 5785 + SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_UTCL1_MISS_FIFO_SED_COUNT), 5786 + 0, 0 5787 + }, 5788 + { "SQC_INST_BANKB_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 5789 + SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_MISS_FIFO_SED_COUNT), 5790 + 0, 0 5791 + }, 5792 + { "SQC_DATA_BANKB_HIT_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 5793 + SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_HIT_FIFO_SED_COUNT), 5794 + 0, 0 5795 + }, 5796 + { "SQC_DATA_BANKB_MISS_FIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 5797 + SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_MISS_FIFO_SED_COUNT), 5798 + 0, 0 5799 + }, 5800 + { "SQC_DATA_BANKB_DIRTY_BIT_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 5801 + SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_DIRTY_BIT_RAM_SED_COUNT), 5802 + 0, 0 5803 + }, 5804 + { "EA_DRAMRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 5805 + SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT), 5806 + SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT) 5807 + }, 5808 + { "EA_DRAMWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 5809 + SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_CMDMEM_SEC_COUNT), 5810 + SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_CMDMEM_DED_COUNT) 5811 + }, 5812 + { "EA_DRAMWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 5813 + SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_DATAMEM_SEC_COUNT), 5814 + SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_DATAMEM_DED_COUNT) 5815 + }, 5816 + { "EA_RRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 5817 + SOC15_REG_FIELD(GCEA_EDC_CNT, RRET_TAGMEM_SEC_COUNT), 5818 + SOC15_REG_FIELD(GCEA_EDC_CNT, RRET_TAGMEM_DED_COUNT) 5819 + }, 5820 + { "EA_WRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 5821 + SOC15_REG_FIELD(GCEA_EDC_CNT, WRET_TAGMEM_SEC_COUNT), 5822 + SOC15_REG_FIELD(GCEA_EDC_CNT, WRET_TAGMEM_DED_COUNT) 5823 + }, 5824 + { "EA_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 5825 + SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMRD_PAGEMEM_SED_COUNT), 5826 + 0, 0 5827 + }, 5828 + { "EA_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 5829 + SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_PAGEMEM_SED_COUNT), 5830 + 0, 0 5831 + }, 5832 + { "EA_IORD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 5833 + SOC15_REG_FIELD(GCEA_EDC_CNT, IORD_CMDMEM_SED_COUNT), 5834 + 0, 0 5835 + }, 5836 + { "EA_IOWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 5837 + SOC15_REG_FIELD(GCEA_EDC_CNT, IOWR_CMDMEM_SED_COUNT), 5838 + 0, 0 5839 + }, 5840 + { "EA_IOWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 5841 + SOC15_REG_FIELD(GCEA_EDC_CNT, IOWR_DATAMEM_SED_COUNT), 5842 + 0, 0 5843 + }, 5844 + { "GMIRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 5845 + SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIRD_CMDMEM_SEC_COUNT), 5846 + SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIRD_CMDMEM_DED_COUNT) 5847 + }, 5848 + { "GMIWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 5849 + SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_CMDMEM_SEC_COUNT), 5850 + SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_CMDMEM_DED_COUNT) 5851 + }, 5852 + { "GMIWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 5853 + SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_DATAMEM_SEC_COUNT), 5854 + SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_DATAMEM_DED_COUNT) 5855 + }, 5856 + { "GMIRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 5857 + SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIRD_PAGEMEM_SED_COUNT), 5858 + 0, 0 5859 + }, 5860 + { "GMIWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 5861 + SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_PAGEMEM_SED_COUNT), 5862 + 0, 0 5863 + }, 5864 + { "MAM_D0MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 5865 + SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D0MEM_SED_COUNT), 5866 + 0, 0 5867 + }, 5868 + { "MAM_D1MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 5869 + SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D1MEM_SED_COUNT), 5870 + 0, 0 5871 + }, 5872 + { "MAM_D2MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 5873 + SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D2MEM_SED_COUNT), 5874 + 0, 0 5875 + }, 5876 + { "MAM_D3MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 5877 + SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D3MEM_SED_COUNT), 5878 + 0, 0 5879 + } 5744 5880 }; 5745 5881 5746 5882 static int gfx_v9_0_ras_error_inject(struct amdgpu_device *adev, ··· 5934 5780 return ret; 5935 5781 } 5936 5782 5783 + static const char *vml2_mems[] = { 5784 + "UTC_VML2_BANK_CACHE_0_BIGK_MEM0", 5785 + "UTC_VML2_BANK_CACHE_0_BIGK_MEM1", 5786 + "UTC_VML2_BANK_CACHE_0_4K_MEM0", 5787 + "UTC_VML2_BANK_CACHE_0_4K_MEM1", 5788 + "UTC_VML2_BANK_CACHE_1_BIGK_MEM0", 5789 + "UTC_VML2_BANK_CACHE_1_BIGK_MEM1", 5790 + "UTC_VML2_BANK_CACHE_1_4K_MEM0", 5791 + "UTC_VML2_BANK_CACHE_1_4K_MEM1", 5792 + "UTC_VML2_BANK_CACHE_2_BIGK_MEM0", 5793 + "UTC_VML2_BANK_CACHE_2_BIGK_MEM1", 5794 + "UTC_VML2_BANK_CACHE_2_4K_MEM0", 5795 + "UTC_VML2_BANK_CACHE_2_4K_MEM1", 5796 + "UTC_VML2_BANK_CACHE_3_BIGK_MEM0", 5797 + "UTC_VML2_BANK_CACHE_3_BIGK_MEM1", 5798 + "UTC_VML2_BANK_CACHE_3_4K_MEM0", 5799 + "UTC_VML2_BANK_CACHE_3_4K_MEM1", 5800 + }; 5801 + 5802 + static const char *vml2_walker_mems[] = { 5803 + "UTC_VML2_CACHE_PDE0_MEM0", 5804 + "UTC_VML2_CACHE_PDE0_MEM1", 5805 + "UTC_VML2_CACHE_PDE1_MEM0", 5806 + "UTC_VML2_CACHE_PDE1_MEM1", 5807 + "UTC_VML2_CACHE_PDE2_MEM0", 5808 + "UTC_VML2_CACHE_PDE2_MEM1", 5809 + "UTC_VML2_RDIF_LOG_FIFO", 5810 + }; 5811 + 5812 + static const char *atc_l2_cache_2m_mems[] = { 5813 + "UTC_ATCL2_CACHE_2M_BANK0_WAY0_MEM", 5814 + "UTC_ATCL2_CACHE_2M_BANK0_WAY1_MEM", 5815 + "UTC_ATCL2_CACHE_2M_BANK1_WAY0_MEM", 5816 + "UTC_ATCL2_CACHE_2M_BANK1_WAY1_MEM", 5817 + }; 5818 + 5819 + static const char *atc_l2_cache_4k_mems[] = { 5820 + "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM0", 5821 + "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM1", 5822 + "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM2", 5823 + "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM3", 5824 + "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM4", 5825 + "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM5", 5826 + "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM6", 5827 + "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM7", 5828 + "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM0", 5829 + "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM1", 5830 + "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM2", 5831 + "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM3", 5832 + "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM4", 5833 + "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM5", 5834 + "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM6", 5835 + "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM7", 5836 + "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM0", 5837 + "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM1", 5838 + "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM2", 5839 + "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM3", 5840 + "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM4", 5841 + "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM5", 5842 + "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM6", 5843 + "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM7", 5844 + "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM0", 5845 + "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM1", 5846 + "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM2", 5847 + "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM3", 5848 + "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM4", 5849 + "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM5", 5850 + "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM6", 5851 + "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM7", 5852 + }; 5853 + 5854 + static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev, 5855 + struct ras_err_data *err_data) 5856 + { 5857 + uint32_t i, data; 5858 + uint32_t sec_count, ded_count; 5859 + 5860 + WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_INDEX, 255); 5861 + WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_CNT, 0); 5862 + WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_INDEX, 255); 5863 + WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_CNT, 0); 5864 + WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_INDEX, 255); 5865 + WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_CNT, 0); 5866 + WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_INDEX, 255); 5867 + WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_CNT, 0); 5868 + 5869 + for (i = 0; i < 16; i++) { 5870 + WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_INDEX, i); 5871 + data = RREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_CNT); 5872 + 5873 + sec_count = REG_GET_FIELD(data, VM_L2_MEM_ECC_CNT, SEC_COUNT); 5874 + if (sec_count) { 5875 + DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i, 5876 + vml2_mems[i], sec_count); 5877 + err_data->ce_count += sec_count; 5878 + } 5879 + 5880 + ded_count = REG_GET_FIELD(data, VM_L2_MEM_ECC_CNT, DED_COUNT); 5881 + if (ded_count) { 5882 + DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i, 5883 + vml2_mems[i], ded_count); 5884 + err_data->ue_count += ded_count; 5885 + } 5886 + } 5887 + 5888 + for (i = 0; i < 7; i++) { 5889 + WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_INDEX, i); 5890 + data = RREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_CNT); 5891 + 5892 + sec_count = REG_GET_FIELD(data, VM_L2_WALKER_MEM_ECC_CNT, 5893 + SEC_COUNT); 5894 + if (sec_count) { 5895 + DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i, 5896 + vml2_walker_mems[i], sec_count); 5897 + err_data->ce_count += sec_count; 5898 + } 5899 + 5900 + ded_count = REG_GET_FIELD(data, VM_L2_WALKER_MEM_ECC_CNT, 5901 + DED_COUNT); 5902 + if (ded_count) { 5903 + DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i, 5904 + vml2_walker_mems[i], ded_count); 5905 + err_data->ue_count += ded_count; 5906 + } 5907 + } 5908 + 5909 + for (i = 0; i < 4; i++) { 5910 + WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_INDEX, i); 5911 + data = RREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_CNT); 5912 + 5913 + sec_count = (data & 0x00006000L) >> 0xd; 5914 + if (sec_count) { 5915 + DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i, 5916 + atc_l2_cache_2m_mems[i], sec_count); 5917 + err_data->ce_count += sec_count; 5918 + } 5919 + } 5920 + 5921 + for (i = 0; i < 32; i++) { 5922 + WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_INDEX, i); 5923 + data = RREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_CNT); 5924 + 5925 + sec_count = (data & 0x00006000L) >> 0xd; 5926 + if (sec_count) { 5927 + DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i, 5928 + atc_l2_cache_4k_mems[i], sec_count); 5929 + err_data->ce_count += sec_count; 5930 + } 5931 + 5932 + ded_count = (data & 0x00018000L) >> 0xf; 5933 + if (ded_count) { 5934 + DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i, 5935 + atc_l2_cache_4k_mems[i], ded_count); 5936 + err_data->ue_count += ded_count; 5937 + } 5938 + } 5939 + 5940 + WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_INDEX, 255); 5941 + WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_INDEX, 255); 5942 + WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_INDEX, 255); 5943 + WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_INDEX, 255); 5944 + 5945 + return 0; 5946 + } 5947 + 5948 + static int __get_ras_error_count(const struct soc15_reg_entry *reg, 5949 + uint32_t se_id, uint32_t inst_id, uint32_t value, 5950 + uint32_t *sec_count, uint32_t *ded_count) 5951 + { 5952 + uint32_t i; 5953 + uint32_t sec_cnt, ded_cnt; 5954 + 5955 + for (i = 0; i < ARRAY_SIZE(ras_subblock_regs); i++) { 5956 + if(ras_subblock_regs[i].reg_offset != reg->reg_offset || 5957 + ras_subblock_regs[i].seg != reg->seg || 5958 + ras_subblock_regs[i].inst != reg->inst) 5959 + continue; 5960 + 5961 + sec_cnt = (value & 5962 + ras_subblock_regs[i].sec_count_mask) >> 5963 + ras_subblock_regs[i].sec_count_shift; 5964 + if (sec_cnt) { 5965 + DRM_INFO("GFX SubBlock %s, Instance[%d][%d], SEC %d\n", 5966 + ras_subblock_regs[i].name, 5967 + se_id, inst_id, 5968 + sec_cnt); 5969 + *sec_count += sec_cnt; 5970 + } 5971 + 5972 + ded_cnt = (value & 5973 + ras_subblock_regs[i].ded_count_mask) >> 5974 + ras_subblock_regs[i].ded_count_shift; 5975 + if (ded_cnt) { 5976 + DRM_INFO("GFX SubBlock %s, Instance[%d][%d], DED %d\n", 5977 + ras_subblock_regs[i].name, 5978 + se_id, inst_id, 5979 + ded_cnt); 5980 + *ded_count += ded_cnt; 5981 + } 5982 + } 5983 + 5984 + return 0; 5985 + } 5986 + 5937 5987 static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev, 5938 5988 void *ras_error_status) 5939 5989 { 5940 5990 struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status; 5941 - uint32_t sec_count, ded_count; 5942 - uint32_t i; 5991 + uint32_t sec_count = 0, ded_count = 0; 5992 + uint32_t i, j, k; 5943 5993 uint32_t reg_value; 5944 - uint32_t se_id, instance_id; 5945 5994 5946 5995 if (adev->asic_type != CHIP_VEGA20) 5947 5996 return -EINVAL; ··· 6153 5796 err_data->ce_count = 0; 6154 5797 6155 5798 mutex_lock(&adev->grbm_idx_mutex); 6156 - for (se_id = 0; se_id < adev->gfx.config.max_shader_engines; se_id++) { 6157 - for (instance_id = 0; instance_id < 256; instance_id++) { 6158 - for (i = 0; 6159 - i < sizeof(gfx_ras_edc_regs) / sizeof(gfx_ras_edc_regs[0]); 6160 - i++) { 6161 - if (se_id != 0 && 6162 - !gfx_ras_edc_regs[i].per_se_instance) 6163 - continue; 6164 - if (instance_id >= gfx_ras_edc_regs[i].num_instance) 6165 - continue; 6166 5799 6167 - gfx_v9_0_select_se_sh(adev, se_id, 0, 6168 - instance_id); 6169 - 6170 - reg_value = RREG32( 6171 - adev->reg_offset[gfx_ras_edc_regs[i].ip] 6172 - [gfx_ras_edc_regs[i].inst] 6173 - [gfx_ras_edc_regs[i].seg] + 6174 - gfx_ras_edc_regs[i].reg_offset); 6175 - sec_count = reg_value & 6176 - gfx_ras_edc_regs[i].sec_count_mask; 6177 - ded_count = reg_value & 6178 - gfx_ras_edc_regs[i].ded_count_mask; 6179 - if (sec_count) { 6180 - DRM_INFO( 6181 - "Instance[%d][%d]: SubBlock %s, SEC %d\n", 6182 - se_id, instance_id, 6183 - gfx_ras_edc_regs[i].name, 6184 - sec_count); 6185 - err_data->ce_count++; 6186 - } 6187 - 6188 - if (ded_count) { 6189 - DRM_INFO( 6190 - "Instance[%d][%d]: SubBlock %s, DED %d\n", 6191 - se_id, instance_id, 6192 - gfx_ras_edc_regs[i].name, 6193 - ded_count); 6194 - err_data->ue_count++; 6195 - } 5800 + for (i = 0; i < ARRAY_SIZE(sec_ded_counter_registers); i++) { 5801 + for (j = 0; j < sec_ded_counter_registers[i].se_num; j++) { 5802 + for (k = 0; k < sec_ded_counter_registers[i].instance; k++) { 5803 + gfx_v9_0_select_se_sh(adev, j, 0, k); 5804 + reg_value = 5805 + RREG32(SOC15_REG_ENTRY_OFFSET(sec_ded_counter_registers[i])); 5806 + if (reg_value) 5807 + __get_ras_error_count(&sec_ded_counter_registers[i], 5808 + j, k, reg_value, 5809 + &sec_count, &ded_count); 6196 5810 } 6197 5811 } 6198 5812 } 5813 + 5814 + err_data->ce_count += sec_count; 5815 + err_data->ue_count += ded_count; 5816 + 6199 5817 gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); 6200 5818 mutex_unlock(&adev->grbm_idx_mutex); 5819 + 5820 + gfx_v9_0_query_utc_edc_status(adev, err_data); 6201 5821 6202 5822 return 0; 6203 5823 }
+44 -41
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
··· 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"); ··· 1146 1152 r = amdgpu_gart_table_vram_pin(adev); 1147 1153 if (r) 1148 1154 return r; 1149 - 1150 - switch (adev->asic_type) { 1151 - case CHIP_RAVEN: 1152 - /* TODO for renoir */ 1153 - mmhub_v1_0_update_power_gating(adev, true); 1154 - break; 1155 - default: 1156 - break; 1157 - } 1158 1155 1159 1156 r = gfxhub_v1_0_gart_enable(adev); 1160 1157 if (r) ··· 1157 1172 r = mmhub_v1_0_gart_enable(adev); 1158 1173 if (r) 1159 1174 return r; 1175 + 1176 + DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", 1177 + (unsigned)(adev->gmc.gart_size >> 20), 1178 + (unsigned long long)amdgpu_bo_gpu_offset(adev->gart.bo)); 1179 + adev->gart.ready = true; 1180 + return 0; 1181 + } 1182 + 1183 + static int gmc_v9_0_hw_init(void *handle) 1184 + { 1185 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1186 + bool value; 1187 + int r, i; 1188 + u32 tmp; 1189 + 1190 + /* The sequence of these two function calls matters.*/ 1191 + gmc_v9_0_init_golden_registers(adev); 1192 + 1193 + if (adev->mode_info.num_crtc) { 1194 + if (adev->asic_type != CHIP_ARCTURUS) { 1195 + /* Lockout access through VGA aperture*/ 1196 + WREG32_FIELD15(DCE, 0, VGA_HDP_CONTROL, VGA_MEMORY_DISABLE, 1); 1197 + 1198 + /* disable VGA render */ 1199 + WREG32_FIELD15(DCE, 0, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0); 1200 + } 1201 + } 1202 + 1203 + amdgpu_device_program_register_sequence(adev, 1204 + golden_settings_vega10_hdp, 1205 + ARRAY_SIZE(golden_settings_vega10_hdp)); 1206 + 1207 + switch (adev->asic_type) { 1208 + case CHIP_RAVEN: 1209 + /* TODO for renoir */ 1210 + mmhub_v1_0_update_power_gating(adev, true); 1211 + break; 1212 + case CHIP_ARCTURUS: 1213 + WREG32_FIELD15(HDP, 0, HDP_MMHUB_CNTL, HDP_MMHUB_GCC, 1); 1214 + break; 1215 + default: 1216 + break; 1217 + } 1160 1218 1161 1219 WREG32_FIELD15(HDP, 0, HDP_MISC_CNTL, FLUSH_INVALIDATE_CACHE, 1); 1162 1220 ··· 1228 1200 1229 1201 if (adev->umc.funcs && adev->umc.funcs->init_registers) 1230 1202 adev->umc.funcs->init_registers(adev); 1231 - 1232 - DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", 1233 - (unsigned)(adev->gmc.gart_size >> 20), 1234 - (unsigned long long)amdgpu_bo_gpu_offset(adev->gart.bo)); 1235 - adev->gart.ready = true; 1236 - return 0; 1237 - } 1238 - 1239 - static int gmc_v9_0_hw_init(void *handle) 1240 - { 1241 - int r; 1242 - struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1243 - 1244 - /* The sequence of these two function calls matters.*/ 1245 - gmc_v9_0_init_golden_registers(adev); 1246 - 1247 - if (adev->mode_info.num_crtc) { 1248 - if (adev->asic_type != CHIP_ARCTURUS) { 1249 - /* Lockout access through VGA aperture*/ 1250 - WREG32_FIELD15(DCE, 0, VGA_HDP_CONTROL, VGA_MEMORY_DISABLE, 1); 1251 - 1252 - /* disable VGA render */ 1253 - WREG32_FIELD15(DCE, 0, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0); 1254 - } 1255 - } 1256 1203 1257 1204 r = gmc_v9_0_gart_enable(adev); 1258 1205
+8
drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
··· 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, ··· 523 516 .enable_doorbell_aperture = nbio_v7_4_enable_doorbell_aperture, 524 517 .enable_doorbell_selfring_aperture = nbio_v7_4_enable_doorbell_selfring_aperture, 525 518 .ih_doorbell_range = nbio_v7_4_ih_doorbell_range, 519 + .enable_doorbell_interrupt = nbio_v7_4_enable_doorbell_interrupt, 526 520 .update_medium_grain_clock_gating = nbio_v7_4_update_medium_grain_clock_gating, 527 521 .update_medium_grain_light_sleep = nbio_v7_4_update_medium_grain_light_sleep, 528 522 .get_clockgating_state = nbio_v7_4_get_clockgating_state,
+3
drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
··· 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 {
+174 -9
drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
··· 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 { ··· 208 206 return err; 209 207 } 210 208 209 + static bool psp_v11_0_is_sos_alive(struct psp_context *psp) 210 + { 211 + struct amdgpu_device *adev = psp->adev; 212 + uint32_t sol_reg; 213 + 214 + sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); 215 + 216 + return sol_reg != 0x0; 217 + } 218 + 211 219 static int psp_v11_0_bootloader_load_kdb(struct psp_context *psp) 212 220 { 213 221 int ret; 214 222 uint32_t psp_gfxdrv_command_reg = 0; 215 223 struct amdgpu_device *adev = psp->adev; 216 - uint32_t sol_reg; 217 224 218 225 /* Check tOS sign of life register to confirm sys driver and sOS 219 226 * are already been loaded. 220 227 */ 221 - sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); 222 - if (sol_reg) { 228 + if (psp_v11_0_is_sos_alive(psp)) { 223 229 psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58); 224 230 dev_info(adev->dev, "sos fw version = 0x%x.\n", psp->sos_fw_version); 225 231 return 0; ··· 263 253 int ret; 264 254 uint32_t psp_gfxdrv_command_reg = 0; 265 255 struct amdgpu_device *adev = psp->adev; 266 - uint32_t sol_reg; 267 256 268 257 /* Check sOS sign of life register to confirm sys driver and sOS 269 258 * are already been loaded. 270 259 */ 271 - sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); 272 - if (sol_reg) { 260 + if (psp_v11_0_is_sos_alive(psp)) { 273 261 psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58); 274 262 dev_info(adev->dev, "sos fw version = 0x%x.\n", psp->sos_fw_version); 275 263 return 0; ··· 305 297 int ret; 306 298 unsigned int psp_gfxdrv_command_reg = 0; 307 299 struct amdgpu_device *adev = psp->adev; 308 - uint32_t sol_reg; 309 300 310 301 /* Check sOS sign of life register to confirm sys driver and sOS 311 302 * are already been loaded. 312 303 */ 313 - sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); 314 - if (sol_reg) 304 + if (psp_v11_0_is_sos_alive(psp)) 315 305 return 0; 316 306 317 307 /* Wait for bootloader to signify that is ready having bit 31 of C2PMSG_35 set to 1 */ ··· 904 898 return psp_rlc_autoload_start(psp); 905 899 } 906 900 901 + static int psp_v11_0_memory_training_send_msg(struct psp_context *psp, int msg) 902 + { 903 + int ret; 904 + int i; 905 + uint32_t data_32; 906 + int max_wait; 907 + struct amdgpu_device *adev = psp->adev; 908 + 909 + data_32 = (psp->mem_train_ctx.c2p_train_data_offset >> 20); 910 + WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, data_32); 911 + WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35, msg); 912 + 913 + max_wait = MEM_TRAIN_SEND_MSG_TIMEOUT_US / adev->usec_timeout; 914 + for (i = 0; i < max_wait; i++) { 915 + ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35), 916 + 0x80000000, 0x80000000, false); 917 + if (ret == 0) 918 + break; 919 + } 920 + if (i < max_wait) 921 + ret = 0; 922 + else 923 + ret = -ETIME; 924 + 925 + DRM_DEBUG("training %s %s, cost %d @ %d ms\n", 926 + (msg == PSP_BL__DRAM_SHORT_TRAIN) ? "short" : "long", 927 + (ret == 0) ? "succeed" : "failed", 928 + i, adev->usec_timeout/1000); 929 + return ret; 930 + } 931 + 932 + static void psp_v11_0_memory_training_fini(struct psp_context *psp) 933 + { 934 + struct psp_memory_training_context *ctx = &psp->mem_train_ctx; 935 + 936 + ctx->init = PSP_MEM_TRAIN_NOT_SUPPORT; 937 + kfree(ctx->sys_cache); 938 + ctx->sys_cache = NULL; 939 + } 940 + 941 + static int psp_v11_0_memory_training_init(struct psp_context *psp) 942 + { 943 + int ret; 944 + struct psp_memory_training_context *ctx = &psp->mem_train_ctx; 945 + 946 + if (ctx->init != PSP_MEM_TRAIN_RESERVE_SUCCESS) { 947 + DRM_DEBUG("memory training is not supported!\n"); 948 + return 0; 949 + } 950 + 951 + ctx->sys_cache = kzalloc(ctx->train_data_size, GFP_KERNEL); 952 + if (ctx->sys_cache == NULL) { 953 + DRM_ERROR("alloc mem_train_ctx.sys_cache failed!\n"); 954 + ret = -ENOMEM; 955 + goto Err_out; 956 + } 957 + 958 + DRM_DEBUG("train_data_size:%llx,p2c_train_data_offset:%llx,c2p_train_data_offset:%llx.\n", 959 + ctx->train_data_size, 960 + ctx->p2c_train_data_offset, 961 + ctx->c2p_train_data_offset); 962 + ctx->init = PSP_MEM_TRAIN_INIT_SUCCESS; 963 + return 0; 964 + 965 + Err_out: 966 + psp_v11_0_memory_training_fini(psp); 967 + return ret; 968 + } 969 + 970 + /* 971 + * save and restore proces 972 + */ 973 + static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops) 974 + { 975 + int ret; 976 + uint32_t p2c_header[4]; 977 + struct psp_memory_training_context *ctx = &psp->mem_train_ctx; 978 + uint32_t *pcache = (uint32_t*)ctx->sys_cache; 979 + 980 + if (ctx->init == PSP_MEM_TRAIN_NOT_SUPPORT) { 981 + DRM_DEBUG("Memory training is not supported.\n"); 982 + return 0; 983 + } else if (ctx->init != PSP_MEM_TRAIN_INIT_SUCCESS) { 984 + DRM_ERROR("Memory training initialization failure.\n"); 985 + return -EINVAL; 986 + } 987 + 988 + if (psp_v11_0_is_sos_alive(psp)) { 989 + DRM_DEBUG("SOS is alive, skip memory training.\n"); 990 + return 0; 991 + } 992 + 993 + amdgpu_device_vram_access(psp->adev, ctx->p2c_train_data_offset, p2c_header, sizeof(p2c_header), false); 994 + DRM_DEBUG("sys_cache[%08x,%08x,%08x,%08x] p2c_header[%08x,%08x,%08x,%08x]\n", 995 + pcache[0], pcache[1], pcache[2], pcache[3], 996 + p2c_header[0], p2c_header[1], p2c_header[2], p2c_header[3]); 997 + 998 + if (ops & PSP_MEM_TRAIN_SEND_SHORT_MSG) { 999 + DRM_DEBUG("Short training depends on restore.\n"); 1000 + ops |= PSP_MEM_TRAIN_RESTORE; 1001 + } 1002 + 1003 + if ((ops & PSP_MEM_TRAIN_RESTORE) && 1004 + pcache[0] != MEM_TRAIN_SYSTEM_SIGNATURE) { 1005 + DRM_DEBUG("sys_cache[0] is invalid, restore depends on save.\n"); 1006 + ops |= PSP_MEM_TRAIN_SAVE; 1007 + } 1008 + 1009 + if (p2c_header[0] == MEM_TRAIN_SYSTEM_SIGNATURE && 1010 + !(pcache[0] == MEM_TRAIN_SYSTEM_SIGNATURE && 1011 + pcache[3] == p2c_header[3])) { 1012 + DRM_DEBUG("sys_cache is invalid or out-of-date, need save training data to sys_cache.\n"); 1013 + ops |= PSP_MEM_TRAIN_SAVE; 1014 + } 1015 + 1016 + if ((ops & PSP_MEM_TRAIN_SAVE) && 1017 + p2c_header[0] != MEM_TRAIN_SYSTEM_SIGNATURE) { 1018 + DRM_DEBUG("p2c_header[0] is invalid, save depends on long training.\n"); 1019 + ops |= PSP_MEM_TRAIN_SEND_LONG_MSG; 1020 + } 1021 + 1022 + if (ops & PSP_MEM_TRAIN_SEND_LONG_MSG) { 1023 + ops &= ~PSP_MEM_TRAIN_SEND_SHORT_MSG; 1024 + ops |= PSP_MEM_TRAIN_SAVE; 1025 + } 1026 + 1027 + DRM_DEBUG("Memory training ops:%x.\n", ops); 1028 + 1029 + if (ops & PSP_MEM_TRAIN_SEND_LONG_MSG) { 1030 + ret = psp_v11_0_memory_training_send_msg(psp, PSP_BL__DRAM_LONG_TRAIN); 1031 + if (ret) { 1032 + DRM_ERROR("Send long training msg failed.\n"); 1033 + return ret; 1034 + } 1035 + } 1036 + 1037 + if (ops & PSP_MEM_TRAIN_SAVE) { 1038 + amdgpu_device_vram_access(psp->adev, ctx->p2c_train_data_offset, ctx->sys_cache, ctx->train_data_size, false); 1039 + } 1040 + 1041 + if (ops & PSP_MEM_TRAIN_RESTORE) { 1042 + amdgpu_device_vram_access(psp->adev, ctx->c2p_train_data_offset, ctx->sys_cache, ctx->train_data_size, true); 1043 + } 1044 + 1045 + if (ops & PSP_MEM_TRAIN_SEND_SHORT_MSG) { 1046 + ret = psp_v11_0_memory_training_send_msg(psp, (amdgpu_force_long_training > 0) ? 1047 + PSP_BL__DRAM_LONG_TRAIN : PSP_BL__DRAM_SHORT_TRAIN); 1048 + if (ret) { 1049 + DRM_ERROR("send training msg failed.\n"); 1050 + return ret; 1051 + } 1052 + } 1053 + ctx->training_cnt++; 1054 + return 0; 1055 + } 1056 + 907 1057 static const struct psp_funcs psp_v11_0_funcs = { 908 1058 .init_microcode = psp_v11_0_init_microcode, 909 1059 .bootloader_load_kdb = psp_v11_0_bootloader_load_kdb, ··· 1080 918 .ras_trigger_error = psp_v11_0_ras_trigger_error, 1081 919 .ras_cure_posion = psp_v11_0_ras_cure_posion, 1082 920 .rlc_autoload_start = psp_v11_0_rlc_autoload_start, 921 + .mem_training_init = psp_v11_0_memory_training_init, 922 + .mem_training_fini = psp_v11_0_memory_training_fini, 923 + .mem_training = psp_v11_0_memory_training, 1083 924 }; 1084 925 1085 926 void psp_v11_0_set_psp_funcs(struct psp_context *psp)
+1 -1
drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
··· 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))
+42 -20
drivers/gpu/drm/amd/amdgpu/soc15.c
··· 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; 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; 489 + 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); 487 496 } 488 - 489 - return pp_funcs->get_asic_baco_capability(pp_handle, cap); 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; 499 - 500 - /* enter BACO state */ 501 - if (pp_funcs->set_asic_baco_state(pp_handle, 1)) 502 - return -EIO; 503 - 504 - /* exit BACO state */ 505 - if (pp_funcs->set_asic_baco_state(pp_handle, 0)) 506 - return -EIO; 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); 507 506 508 507 dev_info(adev->dev, "GPU BACO reset\n"); 509 508 510 - adev->in_baco_reset = 1; 509 + if (is_support_sw_smu(adev)) { 510 + struct smu_context *smu = &adev->smu; 511 + 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 + } 529 + 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 }
+2
drivers/gpu/drm/amd/amdgpu/soc15.h
··· 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);
+21 -10
drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
··· 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); ··· 221 220 return r; 222 221 223 222 ib = &job->ibs[0]; 224 - dummy = ib->gpu_addr + 1024; 223 + addr = amdgpu_bo_gpu_offset(bo); 225 224 226 225 ib->length_dw = 0; 227 226 ib->ptr[ib->length_dw++] = 0x00000018; 228 227 ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ 229 228 ib->ptr[ib->length_dw++] = handle; 230 229 ib->ptr[ib->length_dw++] = 0x00010000; 231 - ib->ptr[ib->length_dw++] = upper_32_bits(dummy); 232 - ib->ptr[ib->length_dw++] = dummy; 230 + ib->ptr[ib->length_dw++] = upper_32_bits(addr); 231 + ib->ptr[ib->length_dw++] = addr; 233 232 234 233 ib->ptr[ib->length_dw++] = 0x00000014; 235 234 ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ ··· 269 268 */ 270 269 static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, 271 270 uint32_t handle, 271 + struct amdgpu_bo *bo, 272 272 struct dma_fence **fence) 273 273 { 274 274 const unsigned ib_size_dw = 16; 275 275 struct amdgpu_job *job; 276 276 struct amdgpu_ib *ib; 277 277 struct dma_fence *f = NULL; 278 - uint64_t dummy; 278 + uint64_t addr; 279 279 int i, r; 280 280 281 281 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); ··· 284 282 return r; 285 283 286 284 ib = &job->ibs[0]; 287 - dummy = ib->gpu_addr + 1024; 285 + addr = amdgpu_bo_gpu_offset(bo); 288 286 289 287 ib->length_dw = 0; 290 288 ib->ptr[ib->length_dw++] = 0x00000018; 291 289 ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ 292 290 ib->ptr[ib->length_dw++] = handle; 293 291 ib->ptr[ib->length_dw++] = 0x00010000; 294 - ib->ptr[ib->length_dw++] = upper_32_bits(dummy); 295 - ib->ptr[ib->length_dw++] = dummy; 292 + ib->ptr[ib->length_dw++] = upper_32_bits(addr); 293 + ib->ptr[ib->length_dw++] = addr; 296 294 297 295 ib->ptr[ib->length_dw++] = 0x00000014; 298 296 ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ ··· 329 327 static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) 330 328 { 331 329 struct dma_fence *fence = NULL; 330 + struct amdgpu_bo *bo = NULL; 332 331 long r; 333 332 334 - r = uvd_v6_0_enc_get_create_msg(ring, 1, NULL); 333 + r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE, 334 + AMDGPU_GEM_DOMAIN_VRAM, 335 + &bo, NULL, NULL); 336 + if (r) 337 + return r; 338 + 339 + r = uvd_v6_0_enc_get_create_msg(ring, 1, bo, NULL); 335 340 if (r) 336 341 goto error; 337 342 338 - r = uvd_v6_0_enc_get_destroy_msg(ring, 1, &fence); 343 + r = uvd_v6_0_enc_get_destroy_msg(ring, 1, bo, &fence); 339 344 if (r) 340 345 goto error; 341 346 ··· 354 345 355 346 error: 356 347 dma_fence_put(fence); 348 + amdgpu_bo_unreserve(bo); 349 + amdgpu_bo_unref(&bo); 357 350 return r; 358 351 } 359 352
+22 -11
drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
··· 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); ··· 229 228 return r; 230 229 231 230 ib = &job->ibs[0]; 232 - dummy = ib->gpu_addr + 1024; 231 + addr = amdgpu_bo_gpu_offset(bo); 233 232 234 233 ib->length_dw = 0; 235 234 ib->ptr[ib->length_dw++] = 0x00000018; 236 235 ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ 237 236 ib->ptr[ib->length_dw++] = handle; 238 237 ib->ptr[ib->length_dw++] = 0x00000000; 239 - ib->ptr[ib->length_dw++] = upper_32_bits(dummy); 240 - ib->ptr[ib->length_dw++] = dummy; 238 + ib->ptr[ib->length_dw++] = upper_32_bits(addr); 239 + ib->ptr[ib->length_dw++] = addr; 241 240 242 241 ib->ptr[ib->length_dw++] = 0x00000014; 243 242 ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ ··· 276 275 * Close up a stream for HW test or if userspace failed to do so 277 276 */ 278 277 static int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, 279 - struct dma_fence **fence) 278 + struct amdgpu_bo *bo, 279 + struct dma_fence **fence) 280 280 { 281 281 const unsigned ib_size_dw = 16; 282 282 struct amdgpu_job *job; 283 283 struct amdgpu_ib *ib; 284 284 struct dma_fence *f = NULL; 285 - uint64_t dummy; 285 + uint64_t addr; 286 286 int i, r; 287 287 288 288 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); ··· 291 289 return r; 292 290 293 291 ib = &job->ibs[0]; 294 - dummy = ib->gpu_addr + 1024; 292 + addr = amdgpu_bo_gpu_offset(bo); 295 293 296 294 ib->length_dw = 0; 297 295 ib->ptr[ib->length_dw++] = 0x00000018; 298 296 ib->ptr[ib->length_dw++] = 0x00000001; 299 297 ib->ptr[ib->length_dw++] = handle; 300 298 ib->ptr[ib->length_dw++] = 0x00000000; 301 - ib->ptr[ib->length_dw++] = upper_32_bits(dummy); 302 - ib->ptr[ib->length_dw++] = dummy; 299 + ib->ptr[ib->length_dw++] = upper_32_bits(addr); 300 + ib->ptr[ib->length_dw++] = addr; 303 301 304 302 ib->ptr[ib->length_dw++] = 0x00000014; 305 303 ib->ptr[ib->length_dw++] = 0x00000002; ··· 336 334 static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) 337 335 { 338 336 struct dma_fence *fence = NULL; 337 + struct amdgpu_bo *bo = NULL; 339 338 long r; 340 339 341 - r = uvd_v7_0_enc_get_create_msg(ring, 1, NULL); 340 + r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE, 341 + AMDGPU_GEM_DOMAIN_VRAM, 342 + &bo, NULL, NULL); 343 + if (r) 344 + return r; 345 + 346 + r = uvd_v7_0_enc_get_create_msg(ring, 1, bo, NULL); 342 347 if (r) 343 348 goto error; 344 349 345 - r = uvd_v7_0_enc_get_destroy_msg(ring, 1, &fence); 350 + r = uvd_v7_0_enc_get_destroy_msg(ring, 1, bo, &fence); 346 351 if (r) 347 352 goto error; 348 353 ··· 361 352 362 353 error: 363 354 dma_fence_put(fence); 355 + amdgpu_bo_unreserve(bo); 356 + amdgpu_bo_unref(&bo); 364 357 return r; 365 358 } 366 359
+7
drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
··· 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" ··· 710 709 uint32_t rb_bufsz, tmp; 711 710 int i, j, k, r; 712 711 712 + if (adev->pm.dpm_enabled) 713 + amdgpu_dpm_enable_uvd(adev, true); 714 + 713 715 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 714 716 if (adev->vcn.harvest_config & (1 << i)) 715 717 continue; ··· 942 938 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, 943 939 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK); 944 940 } 941 + 942 + if (adev->pm.dpm_enabled) 943 + amdgpu_dpm_enable_uvd(adev, false); 945 944 946 945 return 0; 947 946 }
+79 -5
drivers/gpu/drm/amd/amdgpu/vi.c
··· 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 ··· 748 714 static enum amd_reset_method 749 715 vi_asic_reset_method(struct amdgpu_device *adev) 750 716 { 751 - return AMD_RESET_METHOD_LEGACY; 717 + bool baco_reset; 718 + 719 + switch (adev->asic_type) { 720 + case CHIP_FIJI: 721 + case CHIP_TONGA: 722 + case CHIP_POLARIS10: 723 + case CHIP_POLARIS11: 724 + case CHIP_POLARIS12: 725 + case CHIP_TOPAZ: 726 + smu7_asic_get_baco_capability(adev, &baco_reset); 727 + break; 728 + default: 729 + baco_reset = false; 730 + break; 731 + } 732 + 733 + if (baco_reset) 734 + return AMD_RESET_METHOD_BACO; 735 + else 736 + return AMD_RESET_METHOD_LEGACY; 737 + } 738 + 739 + /** 740 + * vi_asic_reset - soft reset GPU 741 + * 742 + * @adev: amdgpu_device pointer 743 + * 744 + * Look up which blocks are hung and attempt 745 + * to reset them. 746 + * Returns 0 for success. 747 + */ 748 + static int vi_asic_reset(struct amdgpu_device *adev) 749 + { 750 + int r; 751 + 752 + if (vi_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) 753 + r = smu7_asic_baco_reset(adev); 754 + else 755 + r = vi_asic_pci_config_reset(adev); 756 + 757 + return r; 752 758 } 753 759 754 760 static u32 vi_get_config_memsize(struct amdgpu_device *adev)
+3
drivers/gpu/drm/amd/amdgpu/vi.h
··· 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
+15 -1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 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; ··· 3432 3431 timing_out->flags.HSYNC_POSITIVE_POLARITY = 1; 3433 3432 if (mode_in->flags & DRM_MODE_FLAG_PVSYNC) 3434 3433 timing_out->flags.VSYNC_POSITIVE_POLARITY = 1; 3434 + } 3435 + 3436 + if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) { 3437 + drm_hdmi_avi_infoframe_from_display_mode(&avi_frame, (struct drm_connector *)connector, mode_in); 3438 + timing_out->vic = avi_frame.video_code; 3439 + drm_hdmi_vendor_infoframe_from_display_mode(&hv_frame, (struct drm_connector *)connector, mode_in); 3440 + timing_out->hdmi_vic = hv_frame.vic; 3435 3441 } 3436 3442 3437 3443 timing_out->h_addressable = mode_in->crtc_hdisplay; ··· 3661 3653 3662 3654 stream->dm_stream_context = aconnector; 3663 3655 3656 + stream->timing.flags.LTE_340MCSC_SCRAMBLE = 3657 + drm_connector->display_info.hdmi.scdc.scrambling.low_rates; 3658 + 3664 3659 list_for_each_entry(preferred_mode, &aconnector->base.modes, head) { 3665 3660 /* Search for preferred mode */ 3666 3661 if (preferred_mode->type & DRM_MODE_TYPE_PREFERRED) { ··· 3737 3726 sink); 3738 3727 3739 3728 update_stream_signal(stream, sink); 3729 + 3730 + if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) 3731 + mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket, false, false); 3740 3732 3741 3733 finish: 3742 3734 dc_sink_release(sink);
+7 -2
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
··· 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);
+96 -13
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
··· 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) ··· 664 665 { 665 666 const struct dc_context *ctx = pp->dm; 666 667 struct amdgpu_device *adev = ctx->driver_context; 667 - struct smu_context *smu = &adev->smu; 668 668 struct dm_pp_wm_sets_with_clock_ranges_soc15 wm_with_clock_ranges; 669 669 struct dm_pp_clock_range_for_dmif_wm_set_soc15 *wm_dce_clocks = 670 670 wm_with_clock_ranges.wm_dmif_clocks_ranges; ··· 706 708 ranges->writer_wm_sets[i].min_drain_clk_mhz * 1000; 707 709 } 708 710 709 - if (!smu->funcs) 710 - return PP_SMU_RESULT_UNSUPPORTED; 711 - 712 - /* 0: successful or smu.funcs->set_watermarks_for_clock_ranges = NULL; 713 - * 1: fail 714 - */ 715 - if (smu_set_watermarks_for_clock_ranges(&adev->smu, 716 - &wm_with_clock_ranges)) 717 - return PP_SMU_RESULT_UNSUPPORTED; 711 + smu_set_watermarks_for_clock_ranges(&adev->smu, &wm_with_clock_ranges); 718 712 719 713 return PP_SMU_RESULT_OK; 720 714 } ··· 891 901 return PP_SMU_RESULT_FAIL; 892 902 } 893 903 904 + #ifdef CONFIG_DRM_AMD_DC_DCN2_1 905 + enum pp_smu_status pp_rn_get_dpm_clock_table( 906 + struct pp_smu *pp, struct dpm_clocks *clock_table) 907 + { 908 + const struct dc_context *ctx = pp->dm; 909 + struct amdgpu_device *adev = ctx->driver_context; 910 + struct smu_context *smu = &adev->smu; 911 + 912 + if (!smu->ppt_funcs) 913 + return PP_SMU_RESULT_UNSUPPORTED; 914 + 915 + if (!smu->ppt_funcs->get_dpm_clock_table) 916 + return PP_SMU_RESULT_UNSUPPORTED; 917 + 918 + if (!smu->ppt_funcs->get_dpm_clock_table(smu, clock_table)) 919 + return PP_SMU_RESULT_OK; 920 + 921 + return PP_SMU_RESULT_FAIL; 922 + } 923 + 924 + enum pp_smu_status pp_rn_set_wm_ranges(struct pp_smu *pp, 925 + struct pp_smu_wm_range_sets *ranges) 926 + { 927 + const struct dc_context *ctx = pp->dm; 928 + struct amdgpu_device *adev = ctx->driver_context; 929 + struct smu_context *smu = &adev->smu; 930 + struct dm_pp_wm_sets_with_clock_ranges_soc15 wm_with_clock_ranges; 931 + struct dm_pp_clock_range_for_dmif_wm_set_soc15 *wm_dce_clocks = 932 + wm_with_clock_ranges.wm_dmif_clocks_ranges; 933 + struct dm_pp_clock_range_for_mcif_wm_set_soc15 *wm_soc_clocks = 934 + wm_with_clock_ranges.wm_mcif_clocks_ranges; 935 + int32_t i; 936 + 937 + if (!smu->funcs) 938 + return PP_SMU_RESULT_UNSUPPORTED; 939 + 940 + wm_with_clock_ranges.num_wm_dmif_sets = ranges->num_reader_wm_sets; 941 + wm_with_clock_ranges.num_wm_mcif_sets = ranges->num_writer_wm_sets; 942 + 943 + for (i = 0; i < wm_with_clock_ranges.num_wm_dmif_sets; i++) { 944 + if (ranges->reader_wm_sets[i].wm_inst > 3) 945 + wm_dce_clocks[i].wm_set_id = WM_SET_A; 946 + else 947 + wm_dce_clocks[i].wm_set_id = 948 + ranges->reader_wm_sets[i].wm_inst; 949 + 950 + wm_dce_clocks[i].wm_min_dcfclk_clk_in_khz = 951 + ranges->reader_wm_sets[i].min_drain_clk_mhz; 952 + 953 + wm_dce_clocks[i].wm_max_dcfclk_clk_in_khz = 954 + ranges->reader_wm_sets[i].max_drain_clk_mhz; 955 + 956 + wm_dce_clocks[i].wm_min_mem_clk_in_khz = 957 + ranges->reader_wm_sets[i].min_fill_clk_mhz; 958 + 959 + wm_dce_clocks[i].wm_max_mem_clk_in_khz = 960 + ranges->reader_wm_sets[i].max_fill_clk_mhz; 961 + } 962 + 963 + for (i = 0; i < wm_with_clock_ranges.num_wm_mcif_sets; i++) { 964 + if (ranges->writer_wm_sets[i].wm_inst > 3) 965 + wm_soc_clocks[i].wm_set_id = WM_SET_A; 966 + else 967 + wm_soc_clocks[i].wm_set_id = 968 + ranges->writer_wm_sets[i].wm_inst; 969 + wm_soc_clocks[i].wm_min_socclk_clk_in_khz = 970 + ranges->writer_wm_sets[i].min_fill_clk_mhz; 971 + 972 + wm_soc_clocks[i].wm_max_socclk_clk_in_khz = 973 + ranges->writer_wm_sets[i].max_fill_clk_mhz; 974 + 975 + wm_soc_clocks[i].wm_min_mem_clk_in_khz = 976 + ranges->writer_wm_sets[i].min_drain_clk_mhz; 977 + 978 + wm_soc_clocks[i].wm_max_mem_clk_in_khz = 979 + ranges->writer_wm_sets[i].max_drain_clk_mhz; 980 + } 981 + 982 + smu_set_watermarks_for_clock_ranges(&adev->smu, &wm_with_clock_ranges); 983 + 984 + return PP_SMU_RESULT_OK; 985 + } 986 + #endif 987 + 894 988 void dm_pp_get_funcs( 895 989 struct dc_context *ctx, 896 990 struct pp_smu_funcs *funcs) ··· 1017 943 /*todo compare data with window driver */ 1018 944 funcs->nv_funcs.get_uclk_dpm_states = pp_nv_get_uclk_dpm_states; 1019 945 funcs->nv_funcs.set_pstate_handshake_support = pp_nv_set_pstate_handshake_support; 946 + break; 947 + #endif 948 + 949 + #ifdef CONFIG_DRM_AMD_DC_DCN2_1 950 + case DCN_VERSION_2_1: 951 + funcs->ctx.ver = PP_SMU_VER_RN; 952 + funcs->rn_funcs.pp_smu.dm = ctx; 953 + funcs->rn_funcs.set_wm_ranges = pp_rn_set_wm_ranges; 954 + funcs->rn_funcs.get_dpm_clock_table = pp_rn_get_dpm_clock_table; 1020 955 break; 1021 956 #endif 1022 957 default:
+2 -5
drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
··· 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 ··· 2552 2553 info->disp_clk_voltage[j].max_supported_clk < 2553 2554 info->disp_clk_voltage[j-1].max_supported_clk) { 2554 2555 /* swap j and j - 1*/ 2555 - temp = info->disp_clk_voltage[j-1]; 2556 - info->disp_clk_voltage[j-1] = 2557 - info->disp_clk_voltage[j]; 2558 - info->disp_clk_voltage[j] = temp; 2556 + swap(info->disp_clk_voltage[j - 1], 2557 + info->disp_clk_voltage[j]); 2559 2558 } 2560 2559 } 2561 2560 }
+2 -6
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
··· 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 ··· 1642 1644 info->disp_clk_voltage[j-1].max_supported_clk 1643 1645 ) { 1644 1646 /* swap j and j - 1*/ 1645 - temp = info->disp_clk_voltage[j-1]; 1646 - info->disp_clk_voltage[j-1] = 1647 - info->disp_clk_voltage[j]; 1648 - info->disp_clk_voltage[j] = temp; 1647 + swap(info->disp_clk_voltage[j - 1], 1648 + info->disp_clk_voltage[j]); 1649 1649 } 1650 1650 } 1651 1651 }
+25
drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
··· 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 {
+24
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
··· 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
+1
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h
··· 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__
+127 -33
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
··· 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) ··· 101 62 int display_count; 102 63 bool update_dppclk = false; 103 64 bool update_dispclk = false; 104 - bool enter_display_off = false; 105 65 bool dpp_clock_lowered = false; 66 + 106 67 struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu; 107 68 108 - display_count = clk_mgr_helper_get_active_display_cnt(dc, context); 69 + if (dc->work_arounds.skip_clock_update) 70 + return; 109 71 110 - if (display_count == 0) 111 - enter_display_off = true; 72 + /* 73 + * if it is safe to lower, but we are already in the lower state, we don't have to do anything 74 + * also if safe to lower is false, we just go in the higher state 75 + */ 76 + if (safe_to_lower) { 77 + /* check that we're not already in lower */ 78 + if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_OPTIMIZED) { 112 79 113 - if (enter_display_off == safe_to_lower) { 114 - rn_vbios_smu_set_display_count(clk_mgr, display_count); 80 + display_count = rn_get_active_display_cnt_wa(dc, context); 81 + /* if we can go lower, go lower */ 82 + if (display_count == 0) { 83 + rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_OPTIMIZED); 84 + /* update power state */ 85 + clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_OPTIMIZED; 86 + } 87 + } 88 + } else { 89 + /* check that we're not already in the normal state */ 90 + if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_NORMAL) { 91 + rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_NORMAL); 92 + /* update power state */ 93 + clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_NORMAL; 94 + } 115 95 } 116 96 117 97 if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, clk_mgr_base->clks.phyclk_khz)) { ··· 377 319 378 320 rn_dump_clk_registers(&sb, clk_mgr_base, &log_info); 379 321 380 - s->dprefclk_khz = sb.dprefclk; 322 + s->dprefclk_khz = sb.dprefclk * 1000; 381 323 } 382 324 383 325 void rn_enable_pme_wa(struct clk_mgr *clk_mgr_base) ··· 387 329 rn_vbios_smu_enable_pme_wa(clk_mgr); 388 330 } 389 331 332 + void rn_init_clocks(struct clk_mgr *clk_mgr) 333 + { 334 + memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks)); 335 + // Assumption is that boot state always supports pstate 336 + clk_mgr->clks.p_state_change_support = true; 337 + clk_mgr->clks.prev_p_state_change_support = true; 338 + clk_mgr->clks.pwr_state = DCN_PWR_STATE_NORMAL; 339 + } 340 + 390 341 static struct clk_mgr_funcs dcn21_funcs = { 391 342 .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, 392 343 .update_clocks = rn_update_clocks, 393 - .init_clocks = dcn2_init_clocks, 344 + .init_clocks = rn_init_clocks, 394 345 .enable_pme_wa = rn_enable_pme_wa, 395 346 /* .dump_clk_registers = rn_dump_clk_registers */ 396 347 }; ··· 472 405 } 473 406 }; 474 407 475 - void build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_smu_wm_range_sets *ranges) 408 + void rn_build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_smu_wm_range_sets *ranges) 476 409 { 477 410 int i, num_valid_sets; 478 411 ··· 529 462 530 463 } 531 464 532 - void clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params, struct dpm_clocks *clock_table, struct hw_asic_id *asic_id) 465 + static unsigned int find_dcfclk_for_voltage(struct dpm_clocks *clock_table, unsigned int voltage) 533 466 { 534 467 int i; 535 468 469 + for (i = 0; i < PP_SMU_NUM_DCFCLK_DPM_LEVELS; i++) { 470 + if (clock_table->DcfClocks[i].Vol == voltage) 471 + return clock_table->DcfClocks[i].Freq; 472 + } 473 + 474 + ASSERT(0); 475 + return 0; 476 + } 477 + 478 + 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) 479 + { 480 + int i, j = 0; 481 + 482 + j = -1; 483 + 536 484 ASSERT(PP_SMU_NUM_FCLK_DPM_LEVELS <= MAX_NUM_DPM_LVL); 537 485 538 - for (i = 0; i < PP_SMU_NUM_FCLK_DPM_LEVELS; i++) { 539 - if (clock_table->FClocks[i].Freq == 0) 540 - break; 486 + /* Find lowest DPM, FCLK is filled in reverse order*/ 541 487 542 - bw_params->clk_table.entries[i].dcfclk_mhz = clock_table->DcfClocks[i].Freq; 543 - bw_params->clk_table.entries[i].fclk_mhz = clock_table->FClocks[i].Freq; 544 - bw_params->clk_table.entries[i].memclk_mhz = clock_table->MemClocks[i].Freq; 545 - bw_params->clk_table.entries[i].socclk_mhz = clock_table->SocClocks[i].Freq; 546 - bw_params->clk_table.entries[i].voltage = clock_table->FClocks[i].Vol; 488 + for (i = PP_SMU_NUM_FCLK_DPM_LEVELS - 1; i >= 0; i--) { 489 + if (clock_table->FClocks[i].Freq != 0) { 490 + j = i; 491 + break; 492 + } 547 493 } 548 - bw_params->clk_table.num_entries = i; 494 + 495 + if (j == -1) { 496 + /* clock table is all 0s, just use our own hardcode */ 497 + ASSERT(0); 498 + return; 499 + } 500 + 501 + bw_params->clk_table.num_entries = j + 1; 502 + 503 + for (i = 0; i < bw_params->clk_table.num_entries; i++, j--) { 504 + bw_params->clk_table.entries[i].fclk_mhz = clock_table->FClocks[j].Freq; 505 + bw_params->clk_table.entries[i].memclk_mhz = clock_table->MemClocks[j].Freq; 506 + bw_params->clk_table.entries[i].voltage = clock_table->FClocks[j].Vol; 507 + bw_params->clk_table.entries[i].dcfclk_mhz = find_dcfclk_for_voltage(clock_table, clock_table->FClocks[j].Vol); 508 + } 549 509 550 510 bw_params->vram_type = asic_id->vram_type; 551 511 bw_params->num_channels = asic_id->vram_width / DDR4_DRAM_WIDTH; ··· 580 486 for (i = 0; i < WM_SET_COUNT; i++) { 581 487 bw_params->wm_table.entries[i].wm_inst = i; 582 488 583 - if (clock_table->FClocks[i].Freq == 0) { 489 + if (i >= bw_params->clk_table.num_entries) { 584 490 bw_params->wm_table.entries[i].valid = false; 585 491 continue; 586 492 } ··· 641 547 clk_mgr->dentist_vco_freq_khz = 3600000; 642 548 643 549 rn_dump_clk_registers(&s, &clk_mgr->base, &log_info); 644 - clk_mgr->base.dprefclk_khz = s.dprefclk; 645 - 646 - if (clk_mgr->base.dprefclk_khz != 600000) { 647 - clk_mgr->base.dprefclk_khz = 600000; 648 - ASSERT(1); //TODO: Renoir follow up. 649 - } 550 + /* Convert dprefclk units from MHz to KHz */ 551 + /* Value already divided by 10, some resolution lost */ 552 + clk_mgr->base.dprefclk_khz = s.dprefclk * 1000; 650 553 651 554 /* in case we don't get a value from the register, use default */ 652 - if (clk_mgr->base.dprefclk_khz == 0) 555 + if (clk_mgr->base.dprefclk_khz == 0) { 556 + ASSERT(clk_mgr->base.dprefclk_khz == 600000); 653 557 clk_mgr->base.dprefclk_khz = 600000; 558 + } 654 559 } 655 560 656 561 dce_clock_read_ss_info(clk_mgr); 657 562 658 563 clk_mgr->base.bw_params = &rn_bw_params; 659 564 660 - if (pp_smu) { 565 + if (pp_smu && pp_smu->rn_funcs.get_dpm_clock_table) { 661 566 pp_smu->rn_funcs.get_dpm_clock_table(&pp_smu->rn_funcs.pp_smu, &clock_table); 662 - clk_mgr_helper_populate_bw_params(clk_mgr->base.bw_params, &clock_table, &ctx->asic_id); 567 + rn_clk_mgr_helper_populate_bw_params(clk_mgr->base.bw_params, &clock_table, &ctx->asic_id); 663 568 } 664 569 665 570 /* ··· 669 576 if (!debug->disable_pplib_wm_range) { 670 577 struct pp_smu_wm_range_sets ranges = {0}; 671 578 672 - build_watermark_ranges(clk_mgr->base.bw_params, &ranges); 579 + rn_build_watermark_ranges(clk_mgr->base.bw_params, &ranges); 673 580 674 581 /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */ 675 582 if (pp_smu && pp_smu->rn_funcs.set_wm_ranges) 676 583 pp_smu->rn_funcs.set_wm_ranges(&pp_smu->rn_funcs.pp_smu, &ranges); 677 584 } 678 585 679 - /* enable powerfeatures when displaycount goes to 0 */ 680 - if (!debug->disable_48mhz_pwrdwn) 681 - rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(clk_mgr); 586 + if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment) && clk_mgr->smu_ver >= 0x00371500) { 587 + /* enable powerfeatures when displaycount goes to 0 */ 588 + rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(clk_mgr, !debug->disable_48mhz_pwrdwn); 589 + } 682 590 } 683 591
+10 -1
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h
··· 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,
+18 -20
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c
··· 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 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)) { ··· 120 124 { 121 125 int actual_dcfclk_set_mhz = -1; 122 126 123 - if (clk_mgr->smu_ver < 0xFFFFFFFF) 127 + if (clk_mgr->smu_ver < 0x370c00) 124 128 return actual_dcfclk_set_mhz; 125 129 126 130 actual_dcfclk_set_mhz = rn_vbios_smu_send_msg_with_param( ··· 135 139 { 136 140 int actual_min_ds_dcfclk_mhz = -1; 137 141 138 - if (clk_mgr->smu_ver < 0xFFFFFFFF) 142 + if (clk_mgr->smu_ver < 0x370c00) 139 143 return actual_min_ds_dcfclk_mhz; 140 144 141 145 actual_min_ds_dcfclk_mhz = rn_vbios_smu_send_msg_with_param( ··· 158 162 { 159 163 int actual_dppclk_set_mhz = -1; 160 164 161 - uint32_t clk = requested_dpp_khz / 1000; 162 - 163 - if (clk <= 100) 164 - clk = 101; 165 - 166 165 actual_dppclk_set_mhz = rn_vbios_smu_send_msg_with_param( 167 166 clk_mgr, 168 167 VBIOSSMC_MSG_SetDppclkFreq, 169 - clk); 168 + requested_dpp_khz / 1000); 170 169 171 170 return actual_dppclk_set_mhz * 1000; 172 171 } 173 172 174 - void rn_vbios_smu_set_display_count(struct clk_mgr_internal *clk_mgr, int display_count) 173 + void rn_vbios_smu_set_dcn_low_power_state(struct clk_mgr_internal *clk_mgr, enum dcn_pwr_state state) 175 174 { 175 + int disp_count; 176 + 177 + if (state == DCN_PWR_STATE_OPTIMIZED) 178 + disp_count = 0; 179 + else 180 + disp_count = 1; 181 + 176 182 rn_vbios_smu_send_msg_with_param( 177 - clk_mgr, 178 - VBIOSSMC_MSG_SetDisplayCount, 179 - display_count); 183 + clk_mgr, 184 + VBIOSSMC_MSG_SetDisplayCount, 185 + disp_count); 180 186 } 181 187 182 - void rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr) 188 + void rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable) 183 189 { 184 190 rn_vbios_smu_send_msg_with_param( 185 191 clk_mgr, 186 192 VBIOSSMC_MSG_EnableTmdp48MHzRefclkPwrDown, 187 - 0); 193 + enable); 188 194 } 189 195 190 196 void rn_vbios_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr)
+2 -2
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.h
··· 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_ */
+91 -9
drivers/gpu/drm/amd/display/dc/core/dc.c
··· 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 { ··· 939 918 940 919 /* set first pipe with plane as master */ 941 920 for (j = 0; j < group_size; j++) { 942 - struct pipe_ctx *temp; 943 - 944 921 if (pipe_set[j]->plane_state) { 945 922 if (j == 0) 946 923 break; 947 924 948 - temp = pipe_set[0]; 949 - pipe_set[0] = pipe_set[j]; 950 - pipe_set[j] = temp; 925 + swap(pipe_set[0], pipe_set[j]); 951 926 break; 952 927 } 953 928 } ··· 1000 983 struct dc_crtc_timing *crtc_timing) 1001 984 { 1002 985 struct timing_generator *tg; 986 + struct stream_encoder *se = NULL; 987 + 988 + struct dc_crtc_timing hw_crtc_timing = {0}; 989 + 1003 990 struct dc_link *link = sink->link; 1004 991 unsigned int i, enc_inst, tg_inst = 0; 1005 992 ··· 1023 1002 1024 1003 for (i = 0; i < dc->res_pool->stream_enc_count; i++) { 1025 1004 if (dc->res_pool->stream_enc[i]->id == enc_inst) { 1005 + 1006 + se = dc->res_pool->stream_enc[i]; 1007 + 1026 1008 tg_inst = dc->res_pool->stream_enc[i]->funcs->dig_source_otg( 1027 1009 dc->res_pool->stream_enc[i]); 1028 1010 break; ··· 1041 1017 1042 1018 tg = dc->res_pool->timing_generators[tg_inst]; 1043 1019 1044 - if (!tg->funcs->is_matching_timing) 1020 + if (!tg->funcs->get_hw_timing) 1045 1021 return false; 1046 1022 1047 - if (!tg->funcs->is_matching_timing(tg, crtc_timing)) 1023 + if (!tg->funcs->get_hw_timing(tg, &hw_crtc_timing)) 1024 + return false; 1025 + 1026 + if (crtc_timing->h_total != hw_crtc_timing.h_total) 1027 + return false; 1028 + 1029 + if (crtc_timing->h_border_left != hw_crtc_timing.h_border_left) 1030 + return false; 1031 + 1032 + if (crtc_timing->h_addressable != hw_crtc_timing.h_addressable) 1033 + return false; 1034 + 1035 + if (crtc_timing->h_border_right != hw_crtc_timing.h_border_right) 1036 + return false; 1037 + 1038 + if (crtc_timing->h_front_porch != hw_crtc_timing.h_front_porch) 1039 + return false; 1040 + 1041 + if (crtc_timing->h_sync_width != hw_crtc_timing.h_sync_width) 1042 + return false; 1043 + 1044 + if (crtc_timing->v_total != hw_crtc_timing.v_total) 1045 + return false; 1046 + 1047 + if (crtc_timing->v_border_top != hw_crtc_timing.v_border_top) 1048 + return false; 1049 + 1050 + if (crtc_timing->v_addressable != hw_crtc_timing.v_addressable) 1051 + return false; 1052 + 1053 + if (crtc_timing->v_border_bottom != hw_crtc_timing.v_border_bottom) 1054 + return false; 1055 + 1056 + if (crtc_timing->v_front_porch != hw_crtc_timing.v_front_porch) 1057 + return false; 1058 + 1059 + if (crtc_timing->v_sync_width != hw_crtc_timing.v_sync_width) 1048 1060 return false; 1049 1061 1050 1062 if (dc_is_dp_signal(link->connector_signal)) { ··· 1093 1033 if (crtc_timing->pix_clk_100hz != pix_clk_100hz) 1094 1034 return false; 1095 1035 1036 + if (!se->funcs->dp_get_pixel_format) 1037 + return false; 1038 + 1039 + if (!se->funcs->dp_get_pixel_format( 1040 + se, 1041 + &hw_crtc_timing.pixel_encoding, 1042 + &hw_crtc_timing.display_color_depth)) 1043 + return false; 1044 + 1045 + if (hw_crtc_timing.display_color_depth != crtc_timing->display_color_depth) 1046 + return false; 1047 + 1048 + if (hw_crtc_timing.pixel_encoding != crtc_timing->pixel_encoding) 1049 + return false; 1096 1050 } 1097 1051 1098 1052 return true; ··· 1734 1660 updates[i].surface->update_flags.raw = 0xFFFFFFFF; 1735 1661 } 1736 1662 1737 - 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) 1738 - dc->optimized_required = true; 1663 + if (type == UPDATE_TYPE_FAST) { 1664 + // If there's an available clock comparator, we use that. 1665 + if (dc->clk_mgr->funcs->are_clock_states_equal) { 1666 + if (!dc->clk_mgr->funcs->are_clock_states_equal(&dc->clk_mgr->clks, &dc->current_state->bw_ctx.bw.dcn.clk)) 1667 + dc->optimized_required = true; 1668 + // Else we fallback to mem compare. 1669 + } 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) { 1670 + dc->optimized_required = true; 1671 + } 1672 + } 1739 1673 1740 1674 return type; 1741 1675 }
+39 -7
drivers/gpu/drm/amd/display/dc/core/dc_link.c
··· 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 }; ··· 760 759 bool same_dpcd = true; 761 760 enum dc_connection_type new_connection_type = dc_connection_none; 762 761 bool perform_dp_seamless_boot = false; 762 + 763 763 DC_LOGGER_INIT(link->ctx->logger); 764 764 765 765 if (dc_is_virtual_signal(link->connector_signal)) ··· 873 871 * empty which leads to allocate_mst_payload() has "0" 874 872 * pbn_per_slot value leading to exception on dc_fixpt_div() 875 873 */ 876 - link->verified_link_cap = link->reported_link_cap; 874 + dp_verify_mst_link_cap(link); 875 + 877 876 if (prev_sink != NULL) 878 877 dc_sink_release(prev_sink); 879 878 return false; ··· 1068 1065 dc_sink_release(prev_sink); 1069 1066 1070 1067 return true; 1068 + 1069 + } 1070 + 1071 + bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) 1072 + { 1073 + const struct dc *dc = link->dc; 1074 + bool ret; 1075 + 1076 + /* get out of low power state */ 1077 + clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr); 1078 + 1079 + ret = dc_link_detect_helper(link, reason); 1080 + 1081 + /* Go back to power optimized state */ 1082 + clk_mgr_optimize_pwr_state(dc, dc->clk_mgr); 1083 + 1084 + return ret; 1071 1085 } 1072 1086 1073 1087 bool dc_link_get_hpd_state(struct dc_link *dc_link) ··· 1530 1510 1531 1511 pipe_ctx->stream_res.pix_clk_params.requested_sym_clk = 1532 1512 link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ; 1533 - if (!apply_seamless_boot_optimization) 1513 + if (state->clk_mgr && !apply_seamless_boot_optimization) 1534 1514 state->clk_mgr->funcs->update_clocks(state->clk_mgr, state, false); 1535 1515 1536 1516 dp_enable_link_phy( ··· 2257 2237 break; 2258 2238 } 2259 2239 2260 - if (dongle_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER || 2240 + if (dpcd_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER || 2261 2241 dongle_caps->extendedCapValid == false) 2262 2242 return true; 2263 2243 ··· 2421 2401 return true; 2422 2402 } 2423 2403 2424 - bool dc_link_set_psr_enable(const struct dc_link *link, bool enable, bool wait) 2404 + bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool wait) 2425 2405 { 2426 2406 struct dc *core_dc = link->ctx->dc; 2427 2407 struct dmcu *dmcu = core_dc->res_pool->dmcu; 2428 2408 2429 - if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_enabled) 2430 - dmcu->funcs->set_psr_enable(dmcu, enable, wait); 2409 + 2410 + 2411 + if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_feature_enabled) 2412 + dmcu->funcs->set_psr_enable(dmcu, allow_active, wait); 2413 + 2414 + link->psr_allow_active = allow_active; 2431 2415 2432 2416 return true; 2433 2417 } ··· 2742 2718 enum dc_status status; 2743 2719 DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); 2744 2720 2721 + if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment) && 2722 + dc_is_virtual_signal(pipe_ctx->stream->signal)) 2723 + return; 2724 + 2745 2725 if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) { 2746 2726 stream->link->link_enc->funcs->setup( 2747 2727 stream->link->link_enc, ··· 2887 2859 struct dc *core_dc = pipe_ctx->stream->ctx->dc; 2888 2860 struct dc_stream_state *stream = pipe_ctx->stream; 2889 2861 struct dc_link *link = stream->sink->link; 2862 + 2863 + if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment) && 2864 + dc_is_virtual_signal(pipe_ctx->stream->signal)) 2865 + return; 2890 2866 2891 2867 #if defined(CONFIG_DRM_AMD_DC_HDCP) 2892 2868 update_psp_stream_config(pipe_ctx, true);
+2 -2
drivers/gpu/drm/amd/display/dc/core/dc_stream.c
··· 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
+17 -2
drivers/gpu/drm/amd/display/dc/dc.h
··· 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 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 ··· 221 220 bool power_down_display_on_boot; 222 221 bool edp_not_connected; 223 222 bool forced_clocks; 223 + bool disable_extended_timeout_support; // Used to disable extended timeout and lttpr feature as well 224 224 bool multi_mon_pp_mclk_switch; 225 225 }; 226 226 ··· 247 245 WM_REPORT_DEFAULT = 0, 248 246 WM_REPORT_OVERRIDE = 1, 249 247 }; 248 + enum dtm_pstate{ 249 + dtm_level_p0 = 0,/*highest voltage*/ 250 + dtm_level_p1, 251 + dtm_level_p2, 252 + dtm_level_p3, 253 + dtm_level_p4,/*when active_display_count = 0*/ 254 + }; 255 + 256 + enum dcn_pwr_state { 257 + DCN_PWR_STATE_OPTIMIZED = 0, 258 + DCN_PWR_STATE_NORMAL = 1 259 + }; 250 260 251 261 /* 252 262 * For any clocks that may differ per pipe ··· 274 260 int phyclk_khz; 275 261 int dramclk_khz; 276 262 bool p_state_change_support; 277 - 263 + enum dcn_pwr_state pwr_state; 278 264 /* 279 265 * Elements below are not compared for the purposes of 280 266 * optimization required 281 267 */ 282 268 bool prev_p_state_change_support; 269 + enum dtm_pstate dtm_level; 283 270 int max_supported_dppclk_khz; 284 271 int max_supported_dispclk_khz; 285 272 int bw_dppclk_khz; /*a copy of dppclk_khz*/
+5
drivers/gpu/drm/amd/display/dc/dc_hw_types.h
··· 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 */
+15 -2
drivers/gpu/drm/amd/display/dc/dc_link.h
··· 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 { ··· 159 158 return dc->links[link_index]; 160 159 } 161 160 161 + static inline struct dc_link *get_edp_link(const struct dc *dc) 162 + { 163 + int i; 164 + 165 + // report any eDP links, even unconnected DDI's 166 + for (i = 0; i < dc->link_count; i++) { 167 + if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP) 168 + return dc->links[i]; 169 + } 170 + return NULL; 171 + } 172 + 162 173 /* Set backlight level of an embedded panel (eDP, LVDS). 163 174 * backlight_pwm_u16_16 is unsigned 32 bit with 16 bit integer 164 175 * and 16 bit fractional, where 1.0 is max backlight value. ··· 183 170 184 171 bool dc_link_set_abm_disable(const struct dc_link *dc_link); 185 172 186 - bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable, bool wait); 173 + bool dc_link_set_psr_allow_active(struct dc_link *dc_link, bool enable, bool wait); 187 174 188 175 bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state); 189 176
+3
drivers/gpu/drm/amd/display/dc/dc_stream.h
··· 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
+3
drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
··· 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
+87 -6
drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
··· 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 ··· 59 55 AUX_TIMED_OUT_RETRY_COUNTER = 2, 60 56 AUX_DEFER_RETRY_COUNTER = 6 61 57 }; 58 + 59 + #define TIME_OUT_INCREMENT 1016 60 + #define TIME_OUT_MULTIPLIER_8 8 61 + #define TIME_OUT_MULTIPLIER_16 16 62 + #define TIME_OUT_MULTIPLIER_32 32 63 + #define TIME_OUT_MULTIPLIER_64 64 64 + #define MAX_TIMEOUT_LENGTH 127 65 + 62 66 static void release_engine( 63 67 struct dce_aux *engine) 64 68 { ··· 210 198 REG_UPDATE(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, 1); 211 199 212 200 REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 0, 213 - 10, aux110->timeout_period/10); 201 + 10, aux110->polling_timeout_period/10); 214 202 215 203 /* set the delay and the number of bytes to write */ 216 204 ··· 339 327 340 328 /* poll to make sure that SW_DONE is asserted */ 341 329 REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 1, 342 - 10, aux110->timeout_period/10); 330 + 10, aux110->polling_timeout_period/10); 343 331 344 332 value = REG_READ(AUX_SW_STATUS); 345 333 /* in case HPD is LOW, exit AUX transaction */ ··· 426 414 *engine = NULL; 427 415 428 416 } 417 + 418 + static bool dce_aux_configure_timeout(struct ddc_service *ddc, 419 + uint32_t timeout_in_us) 420 + { 421 + uint32_t multiplier = 0; 422 + uint32_t length = 0; 423 + uint32_t timeout = 0; 424 + struct ddc *ddc_pin = ddc->ddc_pin; 425 + struct dce_aux *aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]; 426 + struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(aux_engine); 427 + 428 + /* 1-Update polling timeout period */ 429 + aux110->polling_timeout_period = timeout_in_us * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER; 430 + 431 + /* 2-Update aux timeout period length and multiplier */ 432 + if (timeout_in_us <= TIME_OUT_INCREMENT) { 433 + multiplier = 0; 434 + length = timeout_in_us/TIME_OUT_MULTIPLIER_8; 435 + if (timeout_in_us % TIME_OUT_MULTIPLIER_8 != 0) 436 + length++; 437 + timeout = length * TIME_OUT_MULTIPLIER_8; 438 + } else if (timeout_in_us <= 2 * TIME_OUT_INCREMENT) { 439 + multiplier = 1; 440 + length = timeout_in_us/TIME_OUT_MULTIPLIER_16; 441 + if (timeout_in_us % TIME_OUT_MULTIPLIER_16 != 0) 442 + length++; 443 + timeout = length * TIME_OUT_MULTIPLIER_16; 444 + } else if (timeout_in_us <= 4 * TIME_OUT_INCREMENT) { 445 + multiplier = 2; 446 + length = timeout_in_us/TIME_OUT_MULTIPLIER_32; 447 + if (timeout_in_us % TIME_OUT_MULTIPLIER_32 != 0) 448 + length++; 449 + timeout = length * TIME_OUT_MULTIPLIER_32; 450 + } else if (timeout_in_us > 4 * TIME_OUT_INCREMENT) { 451 + multiplier = 3; 452 + length = timeout_in_us/TIME_OUT_MULTIPLIER_64; 453 + if (timeout_in_us % TIME_OUT_MULTIPLIER_64 != 0) 454 + length++; 455 + timeout = length * TIME_OUT_MULTIPLIER_64; 456 + } 457 + 458 + length = (length < MAX_TIMEOUT_LENGTH) ? length : MAX_TIMEOUT_LENGTH; 459 + 460 + REG_UPDATE_SEQ_2(AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, length, AUX_RX_TIMEOUT_LEN_MUL, multiplier); 461 + 462 + return true; 463 + } 464 + 465 + static struct dce_aux_funcs aux_functions = { 466 + .configure_timeout = NULL, 467 + .destroy = NULL, 468 + }; 469 + 429 470 struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110, 430 471 struct dc_context *ctx, 431 472 uint32_t inst, 432 473 uint32_t timeout_period, 433 - const struct dce110_aux_registers *regs) 474 + const struct dce110_aux_registers *regs, 475 + const struct dce110_aux_registers_mask *mask, 476 + const struct dce110_aux_registers_shift *shift, 477 + bool is_ext_aux_timeout_configurable) 434 478 { 435 479 aux_engine110->base.ddc = NULL; 436 480 aux_engine110->base.ctx = ctx; 437 481 aux_engine110->base.delay = 0; 438 482 aux_engine110->base.max_defer_write_retry = 0; 439 483 aux_engine110->base.inst = inst; 440 - aux_engine110->timeout_period = timeout_period; 484 + aux_engine110->polling_timeout_period = timeout_period; 441 485 aux_engine110->regs = regs; 486 + 487 + aux_engine110->mask = mask; 488 + aux_engine110->shift = shift; 489 + aux_engine110->base.funcs = &aux_functions; 490 + if (is_ext_aux_timeout_configurable) 491 + aux_engine110->base.funcs->configure_timeout = &dce_aux_configure_timeout; 442 492 443 493 return &aux_engine110->base; 444 494 } ··· 549 475 aux_req.action = i2caux_action_from_payload(payload); 550 476 551 477 aux_req.address = payload->address; 552 - aux_req.delay = payload->defer_delay * 10; 478 + aux_req.delay = 0; 553 479 aux_req.length = payload->length; 554 480 aux_req.data = payload->data; 555 481 ··· 618 544 case AUX_TRANSACTION_REPLY_AUX_DEFER: 619 545 case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK: 620 546 case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER: 621 - if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES) 547 + if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES) { 622 548 goto fail; 549 + } else { 550 + if ((*payload->reply == AUX_TRANSACTION_REPLY_AUX_DEFER) || 551 + (*payload->reply == AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER)) { 552 + if (payload->defer_delay > 0) 553 + msleep(payload->defer_delay); 554 + } 555 + } 623 556 break; 624 557 625 558 case AUX_TRANSACTION_REPLY_I2C_DEFER:
+183 -4
drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
··· 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), \ ··· 37 36 SRI(AUX_SW_DATA, DP_AUX, id), \ 38 37 SRI(AUX_SW_CONTROL, DP_AUX, id), \ 39 38 SRI(AUX_INTERRUPT_CONTROL, DP_AUX, id), \ 39 + SRI(AUX_DPHY_RX_CONTROL1, DP_AUX, id), \ 40 40 SRI(AUX_SW_STATUS, DP_AUX, id) 41 41 #endif 42 42 ··· 57 55 uint32_t AUX_SW_DATA; 58 56 uint32_t AUX_SW_CONTROL; 59 57 uint32_t AUX_INTERRUPT_CONTROL; 58 + uint32_t AUX_DPHY_RX_CONTROL1; 60 59 uint32_t AUX_SW_STATUS; 61 60 uint32_t AUXN_IMPCAL; 62 61 uint32_t AUXP_IMPCAL; 63 62 64 63 uint32_t AUX_RESET_MASK; 65 64 }; 65 + 66 + #define DCE_AUX_REG_FIELD_LIST(type)\ 67 + type AUX_EN;\ 68 + type AUX_RESET;\ 69 + type AUX_RESET_DONE;\ 70 + type AUX_REG_RW_CNTL_STATUS;\ 71 + type AUX_SW_USE_AUX_REG_REQ;\ 72 + type AUX_SW_DONE_USING_AUX_REG;\ 73 + type AUX_SW_AUTOINCREMENT_DISABLE;\ 74 + type AUX_SW_DATA_RW;\ 75 + type AUX_SW_INDEX;\ 76 + type AUX_SW_GO;\ 77 + type AUX_SW_DATA;\ 78 + type AUX_SW_REPLY_BYTE_COUNT;\ 79 + type AUX_SW_DONE;\ 80 + type AUX_SW_DONE_ACK;\ 81 + type AUXN_IMPCAL_ENABLE;\ 82 + type AUXP_IMPCAL_ENABLE;\ 83 + type AUXN_IMPCAL_OVERRIDE_ENABLE;\ 84 + type AUXP_IMPCAL_OVERRIDE_ENABLE;\ 85 + type AUX_RX_TIMEOUT_LEN;\ 86 + type AUX_RX_TIMEOUT_LEN_MUL;\ 87 + type AUXN_CALOUT_ERROR_AK;\ 88 + type AUXP_CALOUT_ERROR_AK;\ 89 + type AUX_SW_START_DELAY;\ 90 + type AUX_SW_WR_BYTES 91 + 92 + #define DCE10_AUX_MASK_SH_LIST(mask_sh)\ 93 + AUX_SF(AUX_CONTROL, AUX_EN, mask_sh),\ 94 + AUX_SF(AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\ 95 + AUX_SF(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\ 96 + AUX_SF(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\ 97 + AUX_SF(AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\ 98 + AUX_SF(AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\ 99 + AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ 100 + AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ 101 + AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\ 102 + AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ 103 + AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\ 104 + AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ 105 + AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\ 106 + AUX_SF(AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\ 107 + AUX_SF(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\ 108 + AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\ 109 + AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\ 110 + AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\ 111 + AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\ 112 + AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\ 113 + AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh) 114 + 115 + #define DCE_AUX_MASK_SH_LIST(mask_sh)\ 116 + AUX_SF(AUX_CONTROL, AUX_EN, mask_sh),\ 117 + AUX_SF(AUX_CONTROL, AUX_RESET, mask_sh),\ 118 + AUX_SF(AUX_CONTROL, AUX_RESET_DONE, mask_sh),\ 119 + AUX_SF(AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\ 120 + AUX_SF(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\ 121 + AUX_SF(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\ 122 + AUX_SF(AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\ 123 + AUX_SF(AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\ 124 + AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ 125 + AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ 126 + AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\ 127 + AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ 128 + AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\ 129 + AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ 130 + AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\ 131 + AUX_SF(AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\ 132 + AUX_SF(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\ 133 + AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\ 134 + AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\ 135 + AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\ 136 + AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\ 137 + AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\ 138 + AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh) 139 + 140 + #define DCE12_AUX_MASK_SH_LIST(mask_sh)\ 141 + AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\ 142 + AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\ 143 + AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\ 144 + AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\ 145 + AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\ 146 + AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\ 147 + AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\ 148 + AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\ 149 + AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ 150 + AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ 151 + AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, 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_INDEX, mask_sh),\ 154 + AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ 155 + AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\ 156 + AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\ 157 + AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\ 158 + AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\ 159 + AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\ 160 + AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\ 161 + AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\ 162 + AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\ 163 + AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh) 164 + 165 + /* DCN10 MASK */ 166 + #define DCN10_AUX_MASK_SH_LIST(mask_sh)\ 167 + AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\ 168 + AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\ 169 + AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\ 170 + AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\ 171 + AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\ 172 + AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\ 173 + AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\ 174 + AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\ 175 + AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ 176 + AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ 177 + AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, 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_INDEX, mask_sh),\ 180 + AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ 181 + AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\ 182 + AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\ 183 + AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\ 184 + AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\ 185 + AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\ 186 + AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\ 187 + AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\ 188 + AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\ 189 + AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh) 190 + 191 + /* for all other DCN */ 192 + #define DCN_AUX_MASK_SH_LIST(mask_sh)\ 193 + AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\ 194 + AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\ 195 + AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\ 196 + AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\ 197 + AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\ 198 + AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\ 199 + AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\ 200 + AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\ 201 + AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ 202 + AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ 203 + AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, 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_INDEX, mask_sh),\ 206 + AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ 207 + AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\ 208 + AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\ 209 + AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\ 210 + AUX_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, mask_sh),\ 211 + AUX_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN_MUL, mask_sh) 212 + 213 + #define AUX_SF(reg_name, field_name, post_fix)\ 214 + .field_name = reg_name ## __ ## field_name ## post_fix 66 215 67 216 enum { /* This is the timeout as defined in DP 1.2a, 68 217 * 2.3.4 "Detailed uPacket TX AUX CH State Description". ··· 250 97 uint32_t max_defer_write_retry; 251 98 252 99 bool acquire_reset; 100 + struct dce_aux_funcs *funcs; 253 101 }; 102 + 103 + struct dce110_aux_registers_mask { 104 + DCE_AUX_REG_FIELD_LIST(uint32_t); 105 + }; 106 + 107 + struct dce110_aux_registers_shift { 108 + DCE_AUX_REG_FIELD_LIST(uint8_t); 109 + }; 110 + 254 111 255 112 struct aux_engine_dce110 { 256 113 struct dce_aux base; 257 114 const struct dce110_aux_registers *regs; 115 + const struct dce110_aux_registers_mask *mask; 116 + const struct dce110_aux_registers_shift *shift; 258 117 struct { 259 118 uint32_t aux_control; 260 119 uint32_t aux_arb_control; 261 120 uint32_t aux_sw_data; 262 121 uint32_t aux_sw_control; 263 122 uint32_t aux_interrupt_control; 123 + uint32_t aux_dphy_rx_control1; 124 + uint32_t aux_dphy_rx_control0; 264 125 uint32_t aux_sw_status; 265 126 } addr; 266 - uint32_t timeout_period; 127 + uint32_t polling_timeout_period; 267 128 }; 268 129 269 130 struct aux_engine_dce110_init_data { ··· 287 120 const struct dce110_aux_registers *regs; 288 121 }; 289 122 290 - struct dce_aux *dce110_aux_engine_construct( 291 - struct aux_engine_dce110 *aux_engine110, 123 + struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110, 292 124 struct dc_context *ctx, 293 125 uint32_t inst, 294 126 uint32_t timeout_period, 295 - const struct dce110_aux_registers *regs); 127 + const struct dce110_aux_registers *regs, 128 + 129 + const struct dce110_aux_registers_mask *mask, 130 + const struct dce110_aux_registers_shift *shift, 131 + bool is_ext_aux_timeout_configurable); 296 132 297 133 void dce110_engine_destroy(struct dce_aux **engine); 298 134 ··· 309 139 310 140 bool dce_aux_transfer_with_retries(struct ddc_service *ddc, 311 141 struct aux_payload *cmd); 142 + 143 + struct dce_aux_funcs { 144 + bool (*configure_timeout) 145 + (struct ddc_service *ddc, 146 + uint32_t timeout); 147 + void (*destroy) 148 + (struct aux_engine **ptr); 149 + }; 150 + 312 151 #endif
+1
drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
··· 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
+14 -1
drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
··· 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) ··· 619 611 620 612 dce110_aux_engine_construct(aux_engine, ctx, inst, 621 613 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, 622 - &aux_engine_regs[inst]); 614 + &aux_engine_regs[inst], 615 + &aux_mask, 616 + &aux_shift, 617 + ctx->dc->caps.extended_aux_timeout_support); 623 618 624 619 return &aux_engine->base; 625 620 } ··· 1008 997 dc->caps.max_cursor_size = 128; 1009 998 dc->caps.dual_link_dvi = true; 1010 999 dc->caps.disable_dp_clk_share = true; 1000 + dc->caps.extended_aux_timeout_support = false; 1001 + 1011 1002 for (i = 0; i < pool->base.pipe_count; i++) { 1012 1003 pool->base.timing_generators[i] = 1013 1004 dce100_timing_generator_create(
+5 -16
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
··· 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); ··· 1411 1410 1412 1411 pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 1413 1412 1414 - pipe_ctx->stream->link->psr_enabled = false; 1413 + pipe_ctx->stream->link->psr_feature_enabled = false; 1415 1414 1416 1415 return DC_OK; 1417 1416 } ··· 1518 1517 for (i = 0; i < context->stream_count; i++) { 1519 1518 if (context->streams[i]->signal == SIGNAL_TYPE_EDP) 1520 1519 return context->streams[i]; 1521 - } 1522 - return NULL; 1523 - } 1524 - 1525 - static struct dc_link *get_edp_link(struct dc *dc) 1526 - { 1527 - int i; 1528 - 1529 - // report any eDP links, even unconnected DDI's 1530 - for (i = 0; i < dc->link_count; i++) { 1531 - if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP) 1532 - return dc->links[i]; 1533 1520 } 1534 1521 return NULL; 1535 1522 } ··· 1815 1826 return false; 1816 1827 1817 1828 /* PSR should not be enabled */ 1818 - if (pipe_ctx->stream->link->psr_enabled) 1829 + if (pipe_ctx->stream->link->psr_feature_enabled) 1819 1830 return false; 1820 1831 1821 1832 /* Nothing to compress */
+13 -1
drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
··· 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),\ ··· 665 657 666 658 dce110_aux_engine_construct(aux_engine, ctx, inst, 667 659 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, 668 - &aux_engine_regs[inst]); 660 + &aux_engine_regs[inst], 661 + &aux_mask, 662 + &aux_shift, 663 + ctx->dc->caps.extended_aux_timeout_support); 669 664 670 665 return &aux_engine->base; 671 666 } ··· 1304 1293 dc->caps.i2c_speed_in_khz = 100; 1305 1294 dc->caps.max_cursor_size = 128; 1306 1295 dc->caps.is_apu = true; 1296 + dc->caps.extended_aux_timeout_support = false; 1307 1297 1308 1298 /************************************************* 1309 1299 * Create resources *
+13 -2
drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
··· 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)\ ··· 638 630 639 631 dce110_aux_engine_construct(aux_engine, ctx, inst, 640 632 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, 641 - &aux_engine_regs[inst]); 633 + &aux_engine_regs[inst], 634 + &aux_mask, 635 + &aux_shift, 636 + ctx->dc->caps.extended_aux_timeout_support); 642 637 643 638 return &aux_engine->base; 644 639 } ··· 1174 1163 dc->caps.i2c_speed_in_khz = 100; 1175 1164 dc->caps.max_cursor_size = 128; 1176 1165 dc->caps.dual_link_dvi = true; 1177 - 1166 + dc->caps.extended_aux_timeout_support = false; 1178 1167 1179 1168 /************************************************* 1180 1169 * Create resources *
+13 -2
drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
··· 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),\ ··· 412 404 413 405 dce110_aux_engine_construct(aux_engine, ctx, inst, 414 406 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, 415 - &aux_engine_regs[inst]); 407 + &aux_engine_regs[inst], 408 + &aux_mask, 409 + &aux_shift, 410 + ctx->dc->caps.extended_aux_timeout_support); 416 411 417 412 return &aux_engine->base; 418 413 } ··· 1017 1006 dc->caps.max_cursor_size = 128; 1018 1007 dc->caps.dual_link_dvi = true; 1019 1008 dc->caps.psp_setup_panel_mode = true; 1020 - 1009 + dc->caps.extended_aux_timeout_support = false; 1021 1010 dc->debug = debug_defaults; 1022 1011 1023 1012 /*************************************************
+13 -1
drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
··· 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), \ ··· 499 491 500 492 dce110_aux_engine_construct(aux_engine, ctx, inst, 501 493 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, 502 - &aux_engine_regs[inst]); 494 + &aux_engine_regs[inst], 495 + &aux_mask, 496 + &aux_shift, 497 + ctx->dc->caps.extended_aux_timeout_support); 503 498 504 499 return &aux_engine->base; 505 500 } ··· 906 895 dc->caps.i2c_speed_in_khz = 40; 907 896 dc->caps.max_cursor_size = 128; 908 897 dc->caps.dual_link_dvi = true; 898 + dc->caps.extended_aux_timeout_support = false; 909 899 910 900 /************************************************* 911 901 * Create resources *
+2 -2
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
··· 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 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,
+5
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
··· 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,
+13 -7
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
··· 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); ··· 1456 1452 DC_LOG_ALL_TF_CHANNELS("Logging all channels..."); 1457 1453 1458 1454 for (i = 0; i < hw_points_num; i++) { 1459 - DC_LOG_GAMMA("R\t%d\t%llu\n", i, tf->tf_pts.red[i].value); 1460 - DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu\n", i, tf->tf_pts.green[i].value); 1461 - DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu\n", i, tf->tf_pts.blue[i].value); 1455 + DC_LOG_GAMMA("R\t%d\t%llu", i, tf->tf_pts.red[i].value); 1456 + DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu", i, tf->tf_pts.green[i].value); 1457 + DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu", i, tf->tf_pts.blue[i].value); 1462 1458 } 1463 1459 1464 1460 for (i = hw_points_num; i < MAX_NUM_HW_POINTS; i++) { 1465 - DC_LOG_ALL_GAMMA("R\t%d\t%llu\n", i, tf->tf_pts.red[i].value); 1466 - DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu\n", i, tf->tf_pts.green[i].value); 1467 - DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu\n", i, tf->tf_pts.blue[i].value); 1461 + DC_LOG_ALL_GAMMA("R\t%d\t%llu", i, tf->tf_pts.red[i].value); 1462 + DC_LOG_ALL_TF_CHANNELS("G\t%d\t%llu", i, tf->tf_pts.green[i].value); 1463 + DC_LOG_ALL_TF_CHANNELS("B\t%d\t%llu", i, tf->tf_pts.blue[i].value); 1468 1464 } 1469 1465 } 1470 1466 ··· 2515 2511 pipe_ctx->stream_res.tg->funcs->set_vtg_params( 2516 2512 pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing); 2517 2513 2518 - dc->hwss.blank_pixel_data(dc, pipe_ctx, blank); 2514 + if (dc->hwss.setup_vupdate_interrupt) 2515 + dc->hwss.setup_vupdate_interrupt(pipe_ctx); 2519 2516 2517 + dc->hwss.blank_pixel_data(dc, pipe_ctx, blank); 2520 2518 } 2521 2519 2522 2520 if (pipe_ctx->plane_state != NULL)
+3
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
··· 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 ||
+13 -47
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
··· 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 } ··· 1452 1486 .get_frame_count = optc1_get_vblank_counter, 1453 1487 .get_scanoutpos = optc1_get_crtc_scanoutpos, 1454 1488 .get_otg_active_size = optc1_get_otg_active_size, 1455 - .is_matching_timing = optc1_is_matching_timing, 1456 1489 .set_early_control = optc1_set_early_control, 1457 1490 /* used by enable_timing_synchronization. Not need for FPGA */ 1458 1491 .wait_for_state = optc1_wait_for_state, ··· 1479 1514 .configure_crc = optc1_configure_crc, 1480 1515 .set_vtg_params = optc1_set_vtg_params, 1481 1516 .program_manual_trigger = optc1_program_manual_trigger, 1482 - .setup_manual_trigger = optc1_setup_manual_trigger 1517 + .setup_manual_trigger = optc1_setup_manual_trigger, 1518 + .get_hw_timing = optc1_get_hw_timing, 1483 1519 }; 1484 1520 1485 1521 void dcn10_timing_generator_init(struct optc *optc1)
+2 -3
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
··· 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,
+14 -1
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
··· 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),\ ··· 650 642 651 643 dce110_aux_engine_construct(aux_engine, ctx, inst, 652 644 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, 653 - &aux_engine_regs[inst]); 645 + &aux_engine_regs[inst], 646 + &aux_mask, 647 + &aux_shift, 648 + ctx->dc->caps.extended_aux_timeout_support); 654 649 655 650 return &aux_engine->base; 656 651 } ··· 1319 1308 dc->caps.max_slave_planes = 1; 1320 1309 dc->caps.is_apu = true; 1321 1310 dc->caps.post_blend_color_processing = false; 1311 + dc->caps.extended_aux_timeout_support = false; 1312 + 1322 1313 /* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */ 1323 1314 dc->caps.force_dp_tps4_for_cp2520 = true; 1324 1315
+62
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
··· 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, ··· 1649 1589 .dig_connect_to_otg = enc1_dig_connect_to_otg, 1650 1590 .hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute, 1651 1591 .dig_source_otg = enc1_dig_source_otg, 1592 + 1593 + .dp_get_pixel_format = enc1_stream_encoder_dp_get_pixel_format, 1652 1594 }; 1653 1595 1654 1596 void dcn10_stream_encoder_construct(
+5
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
··· 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__ */
+1 -1
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c
··· 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,
-5
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h
··· 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,
+38 -4
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
··· 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) ··· 1399 1396 */ 1400 1397 if (pipe_ctx->update_flags.bits.enable || pipe_ctx->stream->update_flags.bits.out_tf) 1401 1398 dc->hwss.set_output_transfer_func(pipe_ctx, pipe_ctx->stream); 1399 + 1400 + /* If the pipe has been enabled or has a different opp, we 1401 + * should reprogram the fmt. This deals with cases where 1402 + * interation between mpc and odm combine on different streams 1403 + * causes a different pipe to be chosen to odm combine with. 1404 + */ 1405 + if (pipe_ctx->update_flags.bits.enable 1406 + || pipe_ctx->update_flags.bits.opp_changed) { 1407 + 1408 + pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion( 1409 + pipe_ctx->stream_res.opp, 1410 + COLOR_SPACE_YCBCR601, 1411 + pipe_ctx->stream->timing.display_color_depth, 1412 + pipe_ctx->stream->signal); 1413 + 1414 + pipe_ctx->stream_res.opp->funcs->opp_program_fmt( 1415 + pipe_ctx->stream_res.opp, 1416 + &pipe_ctx->stream->bit_depth_params, 1417 + &pipe_ctx->stream->clamping); 1418 + } 1402 1419 } 1403 1420 1404 1421 static bool does_pipe_need_lock(struct pipe_ctx *pipe) ··· 1533 1510 msleep(1); 1534 1511 } 1535 1512 } 1513 + 1514 + /* WA to apply WM setting*/ 1515 + if (dc->hwseq->wa.DEGVIDCN21) 1516 + dc->res_pool->hubbub->funcs->apply_DEDCN21_147_wa(dc->res_pool->hubbub); 1536 1517 } 1537 1518 1538 1519 ··· 1608 1581 1609 1582 pipe_ctx->stream_res.tg->funcs->set_vtg_params( 1610 1583 pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing); 1584 + 1611 1585 if (pipe_ctx->prev_odm_pipe == NULL) 1612 1586 dc->hwss.blank_pixel_data(dc, pipe_ctx, blank); 1587 + 1588 + if (dc->hwss.setup_vupdate_interrupt) 1589 + dc->hwss.setup_vupdate_interrupt(pipe_ctx); 1613 1590 } 1614 1591 1615 1592 pipe_ctx->plane_res.hubp->funcs->hubp_setup( ··· 1630 1599 static void dcn20_enable_writeback( 1631 1600 struct dc *dc, 1632 1601 const struct dc_stream_status *stream_status, 1633 - struct dc_writeback_info *wb_info) 1602 + struct dc_writeback_info *wb_info, 1603 + struct dc_state *context) 1634 1604 { 1635 1605 struct dwbc *dwb; 1636 1606 struct mcif_wb *mcif_wb; ··· 1648 1616 optc->funcs->set_dwb_source(optc, wb_info->dwb_pipe_inst); 1649 1617 /* set MCIF_WB buffer and arbitration configuration */ 1650 1618 mcif_wb->funcs->config_mcif_buf(mcif_wb, &wb_info->mcif_buf_params, wb_info->dwb_params.dest_height); 1651 - 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]); 1619 + mcif_wb->funcs->config_mcif_arb(mcif_wb, &context->bw_ctx.bw.dcn.bw_writeback.mcif_wb_arb[wb_info->dwb_pipe_inst]); 1652 1620 /* Enable MCIF_WB */ 1653 1621 mcif_wb->funcs->enable_mcif(mcif_wb); 1654 1622 /* Enable DWB */ ··· 2213 2181 link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, 2214 2182 pipe_ctx->stream_res.stream_enc->id, true); 2215 2183 2216 - if (link->dc->hwss.program_dmdata_engine) 2217 - link->dc->hwss.program_dmdata_engine(pipe_ctx); 2184 + if (pipe_ctx->plane_state && pipe_ctx->plane_state->flip_immediate != 1) { 2185 + if (link->dc->hwss.program_dmdata_engine) 2186 + link->dc->hwss.program_dmdata_engine(pipe_ctx); 2187 + } 2218 2188 2219 2189 link->dc->hwss.update_info_frame(pipe_ctx); 2220 2190
+1 -1
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
··· 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)
+46 -7
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
··· 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)\ ··· 733 731 static const struct dcn20_vmid_mask vmid_masks = { 734 732 DCN20_VMID_MASK_SH_LIST(_MASK) 735 733 }; 734 + 735 + static const struct dce110_aux_registers_shift aux_shift = { 736 + DCN_AUX_MASK_SH_LIST(__SHIFT) 737 + }; 738 + 739 + static const struct dce110_aux_registers_mask aux_mask = { 740 + DCN_AUX_MASK_SH_LIST(_MASK) 741 + }; 742 + 736 743 737 744 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT 738 745 #define dsc_regsDCN20(id)\ ··· 933 922 934 923 dce110_aux_engine_construct(aux_engine, ctx, inst, 935 924 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, 936 - &aux_engine_regs[inst]); 925 + &aux_engine_regs[inst], 926 + &aux_mask, 927 + &aux_shift, 928 + ctx->dc->caps.extended_aux_timeout_support); 937 929 938 930 return &aux_engine->base; 939 931 } ··· 1167 1153 .create_stream_encoder = NULL, 1168 1154 .create_hwseq = dcn20_hwseq_create, 1169 1155 }; 1156 + 1157 + static void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu); 1170 1158 1171 1159 void dcn20_clock_source_destroy(struct clock_source **clk_src) 1172 1160 { ··· 1908 1892 break; 1909 1893 case PIXEL_ENCODING_YCBCR420: 1910 1894 pipes[pipe_cnt].dout.output_format = dm_420; 1911 - pipes[pipe_cnt].dout.output_bpp = (output_bpc * 3) / 2; 1895 + pipes[pipe_cnt].dout.output_bpp = (output_bpc * 3.0) / 2; 1912 1896 break; 1913 1897 case PIXEL_ENCODING_YCBCR422: 1914 1898 if (true) /* todo */ ··· 1921 1905 pipes[pipe_cnt].dout.output_format = dm_444; 1922 1906 pipes[pipe_cnt].dout.output_bpp = output_bpc * 3; 1923 1907 } 1908 + 1909 + #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT 1910 + if (res_ctx->pipe_ctx[i].stream->timing.flags.DSC) 1911 + pipes[pipe_cnt].dout.output_bpp = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.bits_per_pixel / 16.0; 1912 + #endif 1924 1913 1925 1914 /* todo: default max for now, until there is logic reflecting this in dc*/ 1926 1915 pipes[pipe_cnt].dout.output_bpc = 12; ··· 2223 2202 */ 2224 2203 if (secondary_pipe == NULL) { 2225 2204 for (j = dc->res_pool->pipe_count - 1; j >= 0; j--) { 2226 - if (dc->current_state->res_ctx.pipe_ctx[j].top_pipe == NULL) { 2205 + if (dc->current_state->res_ctx.pipe_ctx[j].top_pipe == NULL 2206 + && dc->current_state->res_ctx.pipe_ctx[j].prev_odm_pipe == NULL) { 2227 2207 preferred_pipe_idx = j; 2228 2208 2229 2209 if (res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) { ··· 2577 2555 context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; 2578 2556 context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; 2579 2557 context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; 2558 + #if defined(CONFIG_DRM_AMD_DC_DCN2_1) 2559 + context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; 2560 + 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; 2561 + #endif 2580 2562 2581 2563 if (vlevel < 2) { 2582 2564 pipes[0].clks_cfg.voltage = 2; ··· 2592 2566 context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; 2593 2567 context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; 2594 2568 context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; 2569 + #if defined(CONFIG_DRM_AMD_DC_DCN2_1) 2570 + context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; 2571 + 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; 2572 + #endif 2595 2573 2596 2574 if (vlevel < 3) { 2597 2575 pipes[0].clks_cfg.voltage = 3; ··· 2607 2577 context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; 2608 2578 context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; 2609 2579 context->bw_ctx.bw.dcn.watermarks.d.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.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; 2582 + 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; 2583 + #endif 2610 2584 2611 2585 pipes[0].clks_cfg.voltage = vlevel; 2612 2586 pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz; ··· 2620 2586 context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; 2621 2587 context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; 2622 2588 context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; 2589 + #if defined(CONFIG_DRM_AMD_DC_DCN2_1) 2590 + context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; 2591 + 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; 2592 + #endif 2623 2593 } 2624 2594 2625 2595 void dcn20_calculate_dlg_params( ··· 2960 2922 return true; 2961 2923 } 2962 2924 2963 - struct pp_smu_funcs *dcn20_pp_smu_create(struct dc_context *ctx) 2925 + static struct pp_smu_funcs *dcn20_pp_smu_create(struct dc_context *ctx) 2964 2926 { 2965 2927 struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL); 2966 2928 ··· 2975 2937 return pp_smu; 2976 2938 } 2977 2939 2978 - void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu) 2940 + static void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu) 2979 2941 { 2980 2942 if (pp_smu && *pp_smu) { 2981 2943 kfree(*pp_smu); ··· 3360 3322 dc->caps.post_blend_color_processing = true; 3361 3323 dc->caps.force_dp_tps4_for_cp2520 = true; 3362 3324 dc->caps.hw_3d_lut = true; 3325 + dc->caps.extended_aux_timeout_support = true; 3363 3326 3364 3327 if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) { 3365 3328 dc->debug = debug_defaults_drv;
-3
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
··· 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);
+4
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
··· 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 -1
drivers/gpu/drm/amd/display/dc/dcn21/Makefile
··· 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
+89 -27
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c
··· 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" ··· 52 51 #ifdef NUM_VMID 53 52 #undef NUM_VMID 54 53 #endif 55 - #define NUM_VMID 1 54 + #define NUM_VMID 16 56 55 57 56 static uint32_t convert_and_clamp( 58 57 uint32_t wm_ns, ··· 72 71 void dcn21_dchvm_init(struct hubbub *hubbub) 73 72 { 74 73 struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 74 + uint32_t riommu_active; 75 + int i; 75 76 76 77 //Init DCHVM block 77 78 REG_UPDATE(DCHVM_CTRL0, HOSTVM_INIT_REQ, 1); 78 79 79 80 //Poll until RIOMMU_ACTIVE = 1 80 - //TODO: Figure out interval us and retry count 81 - REG_WAIT(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, 1, 5, 100); 81 + for (i = 0; i < 100; i++) { 82 + REG_GET(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, &riommu_active); 82 83 83 - //Reflect the power status of DCHUBBUB 84 - REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1); 84 + if (riommu_active) 85 + break; 86 + else 87 + udelay(5); 88 + } 85 89 86 - //Start rIOMMU prefetching 87 - REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1); 90 + if (riommu_active) { 91 + //Reflect the power status of DCHUBBUB 92 + REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1); 88 93 89 - // Enable dynamic clock gating 90 - REG_UPDATE_4(DCHVM_CLK_CTRL, 91 - HVM_DISPCLK_R_GATE_DIS, 0, 92 - HVM_DISPCLK_G_GATE_DIS, 0, 93 - HVM_DCFCLK_R_GATE_DIS, 0, 94 - HVM_DCFCLK_G_GATE_DIS, 0); 94 + //Start rIOMMU prefetching 95 + REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1); 95 96 96 - //Poll until HOSTVM_PREFETCH_DONE = 1 97 - //TODO: Figure out interval us and retry count 98 - REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100); 97 + // Enable dynamic clock gating 98 + REG_UPDATE_4(DCHVM_CLK_CTRL, 99 + HVM_DISPCLK_R_GATE_DIS, 0, 100 + HVM_DISPCLK_G_GATE_DIS, 0, 101 + HVM_DCFCLK_R_GATE_DIS, 0, 102 + HVM_DCFCLK_G_GATE_DIS, 0); 103 + 104 + //Poll until HOSTVM_PREFETCH_DONE = 1 105 + REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100); 106 + } 99 107 } 100 108 101 - static int hubbub21_init_dchub(struct hubbub *hubbub, 109 + int hubbub21_init_dchub(struct hubbub *hubbub, 102 110 struct dcn_hubbub_phys_addr_config *pa_config) 103 111 { 104 112 struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 113 + struct dcn_vmid_page_table_config phys_config; 105 114 106 115 REG_SET(DCN_VM_FB_LOCATION_BASE, 0, 107 - FB_BASE, pa_config->system_aperture.fb_base); 116 + FB_BASE, pa_config->system_aperture.fb_base >> 24); 108 117 REG_SET(DCN_VM_FB_LOCATION_TOP, 0, 109 - FB_TOP, pa_config->system_aperture.fb_top); 118 + FB_TOP, pa_config->system_aperture.fb_top >> 24); 110 119 REG_SET(DCN_VM_FB_OFFSET, 0, 111 - FB_OFFSET, pa_config->system_aperture.fb_offset); 120 + FB_OFFSET, pa_config->system_aperture.fb_offset >> 24); 112 121 REG_SET(DCN_VM_AGP_BOT, 0, 113 - AGP_BOT, pa_config->system_aperture.agp_bot); 122 + AGP_BOT, pa_config->system_aperture.agp_bot >> 24); 114 123 REG_SET(DCN_VM_AGP_TOP, 0, 115 - AGP_TOP, pa_config->system_aperture.agp_top); 124 + AGP_TOP, pa_config->system_aperture.agp_top >> 24); 116 125 REG_SET(DCN_VM_AGP_BASE, 0, 117 - AGP_BASE, pa_config->system_aperture.agp_base); 126 + AGP_BASE, pa_config->system_aperture.agp_base >> 24); 127 + 128 + if (pa_config->gart_config.page_table_start_addr != pa_config->gart_config.page_table_end_addr) { 129 + phys_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr >> 12; 130 + phys_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr >> 12; 131 + phys_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr | 1; //Note: hack 132 + phys_config.depth = 0; 133 + phys_config.block_size = 0; 134 + // Init VMID 0 based on PA config 135 + dcn20_vmid_setup(&hubbub1->vmid[0], &phys_config); 136 + } 118 137 119 138 dcn21_dchvm_init(hubbub); 120 139 121 140 return NUM_VMID; 122 141 } 123 142 124 - static void hubbub21_program_urgent_watermarks( 143 + void hubbub21_program_urgent_watermarks( 125 144 struct hubbub *hubbub, 126 145 struct dcn_watermark_set *watermarks, 127 146 unsigned int refclk_mhz, ··· 181 160 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, 0, 182 161 DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, watermarks->a.frac_urg_bw_nom); 183 162 } 163 + if (safe_to_lower || watermarks->a.urgent_latency_ns > hubbub1->watermarks.a.urgent_latency_ns) { 164 + hubbub1->watermarks.a.urgent_latency_ns = watermarks->a.urgent_latency_ns; 165 + prog_wm_value = convert_and_clamp(watermarks->a.urgent_latency_ns, 166 + refclk_mhz, 0x1fffff); 167 + REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, 0, 168 + DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, prog_wm_value); 169 + } 184 170 185 171 /* clock state B */ 186 172 if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) { ··· 218 190 219 191 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, 0, 220 192 DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, watermarks->a.frac_urg_bw_nom); 193 + } 194 + 195 + if (safe_to_lower || watermarks->b.urgent_latency_ns > hubbub1->watermarks.b.urgent_latency_ns) { 196 + hubbub1->watermarks.b.urgent_latency_ns = watermarks->b.urgent_latency_ns; 197 + prog_wm_value = convert_and_clamp(watermarks->b.urgent_latency_ns, 198 + refclk_mhz, 0x1fffff); 199 + REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, 0, 200 + DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, prog_wm_value); 221 201 } 222 202 223 203 /* clock state C */ ··· 259 223 DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, watermarks->a.frac_urg_bw_nom); 260 224 } 261 225 226 + if (safe_to_lower || watermarks->c.urgent_latency_ns > hubbub1->watermarks.c.urgent_latency_ns) { 227 + hubbub1->watermarks.c.urgent_latency_ns = watermarks->c.urgent_latency_ns; 228 + prog_wm_value = convert_and_clamp(watermarks->c.urgent_latency_ns, 229 + refclk_mhz, 0x1fffff); 230 + REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, 0, 231 + DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, prog_wm_value); 232 + } 233 + 262 234 /* clock state D */ 263 235 if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) { 264 236 hubbub1->watermarks.d.urgent_ns = watermarks->d.urgent_ns; ··· 297 253 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, 0, 298 254 DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, watermarks->a.frac_urg_bw_nom); 299 255 } 256 + 257 + if (safe_to_lower || watermarks->d.urgent_latency_ns > hubbub1->watermarks.d.urgent_latency_ns) { 258 + hubbub1->watermarks.d.urgent_latency_ns = watermarks->d.urgent_latency_ns; 259 + prog_wm_value = convert_and_clamp(watermarks->d.urgent_latency_ns, 260 + refclk_mhz, 0x1fffff); 261 + REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, 0, 262 + DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, prog_wm_value); 263 + } 300 264 } 301 265 302 - static void hubbub21_program_stutter_watermarks( 266 + void hubbub21_program_stutter_watermarks( 303 267 struct hubbub *hubbub, 304 268 struct dcn_watermark_set *watermarks, 305 269 unsigned int refclk_mhz, ··· 441 389 } 442 390 } 443 391 444 - static void hubbub21_program_pstate_watermarks( 392 + void hubbub21_program_pstate_watermarks( 445 393 struct hubbub *hubbub, 446 394 struct dcn_watermark_set *watermarks, 447 395 unsigned int refclk_mhz, ··· 616 564 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, &s->dram_clk_chanage); 617 565 } 618 566 567 + void hubbub21_apply_DEDCN21_147_wa(struct hubbub *hubbub) 568 + { 569 + struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 570 + uint32_t prog_wm_value; 571 + 572 + prog_wm_value = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A); 573 + REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); 574 + } 619 575 620 576 static const struct hubbub_funcs hubbub21_funcs = { 621 577 .update_dchub = hubbub2_update_dchub, 622 578 .init_dchub_sys_ctx = hubbub21_init_dchub, 623 - .init_vm_ctx = NULL, 579 + .init_vm_ctx = hubbub2_init_vm_ctx, 624 580 .dcc_support_swizzle = hubbub2_dcc_support_swizzle, 625 581 .dcc_support_pixel_format = hubbub2_dcc_support_pixel_format, 626 582 .get_dcc_compression_cap = hubbub2_get_dcc_compression_cap, 627 583 .wm_read_state = hubbub21_wm_read_state, 628 584 .get_dchub_ref_freq = hubbub2_get_dchub_ref_freq, 629 585 .program_watermarks = hubbub21_program_watermarks, 586 + .apply_DEDCN21_147_wa = hubbub21_apply_DEDCN21_147_wa, 630 587 }; 631 588 632 589 void hubbub21_construct(struct dcn20_hubbub *hubbub, ··· 653 592 hubbub->masks = hubbub_mask; 654 593 655 594 hubbub->debug_test_index_pstate = 0xB; 595 + hubbub->detile_buf_size = 164 * 1024; /* 164KB for DCN2.0 */ 656 596 }
+24 -10
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.h
··· 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), \ ··· 48 44 SR(DCHVM_RIOMMU_STAT0) 49 45 50 46 #define HUBBUB_REG_LIST_DCN21()\ 51 - HUBBUB_REG_LIST_DCN_COMMON(), \ 47 + HUBBUB_REG_LIST_DCN20_COMMON(), \ 52 48 HUBBUB_SR_WATERMARK_REG_LIST(), \ 53 - HUBBUB_HVM_REG_LIST(), \ 54 - SR(DCHUBBUB_CRC_CTRL), \ 55 - SR(DCN_VM_FB_LOCATION_BASE),\ 56 - SR(DCN_VM_FB_LOCATION_TOP),\ 57 - SR(DCN_VM_FB_OFFSET),\ 58 - SR(DCN_VM_AGP_BOT),\ 59 - SR(DCN_VM_AGP_TOP),\ 60 - SR(DCN_VM_AGP_BASE) 49 + HUBBUB_HVM_REG_LIST() 61 50 62 51 #define HUBBUB_MASK_SH_LIST_HVM(mask_sh) \ 63 52 HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD, mask_sh), \ ··· 99 102 HUBBUB_SF(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, mask_sh) 100 103 101 104 #define HUBBUB_MASK_SH_LIST_DCN21(mask_sh)\ 102 - HUBBUB_MASK_SH_LIST_HVM(mask_sh),\ 105 + HUBBUB_MASK_SH_LIST_HVM(mask_sh), \ 103 106 HUBBUB_MASK_SH_LIST_DCN_COMMON(mask_sh), \ 104 107 HUBBUB_MASK_SH_LIST_STUTTER(mask_sh), \ 105 108 HUBBUB_SF(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \ ··· 111 114 HUBBUB_SF(DCN_VM_AGP_BASE, AGP_BASE, mask_sh) 112 115 113 116 void dcn21_dchvm_init(struct hubbub *hubbub); 117 + int hubbub21_init_dchub(struct hubbub *hubbub, 118 + struct dcn_hubbub_phys_addr_config *pa_config); 114 119 void hubbub21_program_watermarks( 120 + struct hubbub *hubbub, 121 + struct dcn_watermark_set *watermarks, 122 + unsigned int refclk_mhz, 123 + bool safe_to_lower); 124 + void hubbub21_program_urgent_watermarks( 125 + struct hubbub *hubbub, 126 + struct dcn_watermark_set *watermarks, 127 + unsigned int refclk_mhz, 128 + bool safe_to_lower); 129 + void hubbub21_program_stutter_watermarks( 130 + struct hubbub *hubbub, 131 + struct dcn_watermark_set *watermarks, 132 + unsigned int refclk_mhz, 133 + bool safe_to_lower); 134 + void hubbub21_program_pstate_watermarks( 115 135 struct hubbub *hubbub, 116 136 struct dcn_watermark_set *watermarks, 117 137 unsigned int refclk_mhz,
+3 -1
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c
··· 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" ··· 204 202 .hubp_enable_tripleBuffer = hubp2_enable_triplebuffer, 205 203 .hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled, 206 204 .hubp_program_surface_flip_and_addr = hubp2_program_surface_flip_and_addr, 207 - .hubp_program_surface_config = hubp2_program_surface_config, 205 + .hubp_program_surface_config = hubp1_program_surface_config, 208 206 .hubp_is_flip_pending = hubp1_is_flip_pending, 209 207 .hubp_setup = hubp21_setup, 210 208 .hubp_setup_interdependent = hubp2_setup_interdependent,
+122
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
··· 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 + }
+33
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.h
··· 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__ */
+250 -53
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
··· 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 ··· 40 42 #include "irq/dcn21/irq_service_dcn21.h" 41 43 #include "dcn20/dcn20_dpp.h" 42 44 #include "dcn20/dcn20_optc.h" 43 - #include "dcn20/dcn20_hwseq.h" 45 + #include "dcn21/dcn21_hwseq.h" 44 46 #include "dce110/dce110_hw_sequencer.h" 45 47 #include "dcn20/dcn20_opp.h" 46 48 #include "dcn20/dcn20_dsc.h" 47 - #include "dcn20/dcn20_link_encoder.h" 49 + #include "dcn21/dcn21_link_encoder.h" 48 50 #include "dcn20/dcn20_stream_encoder.h" 49 51 #include "dce/dce_clock_source.h" 50 52 #include "dce/dce_audio.h" ··· 82 84 83 85 84 86 struct _vcs_dpi_ip_params_st dcn2_1_ip = { 87 + .odm_capable = 1, 85 88 .gpuvm_enable = 0, 86 89 .hostvm_enable = 0, 87 90 .gpuvm_max_page_table_levels = 1, ··· 204 205 .state = 4, 205 206 .dcfclk_mhz = 810.0, 206 207 .fabricclk_mhz = 1600.0, 207 - .dispclk_mhz = 1015.0, 208 - .dppclk_mhz = 1015.0, 209 - .phyclk_mhz = 810.0, 208 + .dispclk_mhz = 1395.0, 209 + .dppclk_mhz = 1285.0, 210 + .phyclk_mhz = 1325.0, 210 211 .socclk_mhz = 953.0, 211 - .dscclk_mhz = 318.334, 212 + .dscclk_mhz = 489.0, 212 213 .dram_speed_mts = 4266.0, 213 214 }, 214 215 /*Extra state, no dispclk ramping*/ ··· 216 217 .state = 5, 217 218 .dcfclk_mhz = 810.0, 218 219 .fabricclk_mhz = 1600.0, 219 - .dispclk_mhz = 1015.0, 220 - .dppclk_mhz = 1015.0, 221 - .phyclk_mhz = 810.0, 220 + .dispclk_mhz = 1395.0, 221 + .dppclk_mhz = 1285.0, 222 + .phyclk_mhz = 1325.0, 222 223 .socclk_mhz = 953.0, 223 - .dscclk_mhz = 318.334, 224 + .dscclk_mhz = 489.0, 224 225 .dram_speed_mts = 4266.0, 225 226 }, 226 227 227 228 }, 228 229 229 - .sr_exit_time_us = 9.0, 230 - .sr_enter_plus_exit_time_us = 11.0, 230 + .sr_exit_time_us = 12.5, 231 + .sr_enter_plus_exit_time_us = 17.0, 231 232 .urgent_latency_us = 4.0, 232 233 .urgent_latency_pixel_data_only_us = 4.0, 233 234 .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, ··· 347 348 static const struct bios_registers bios_regs = { 348 349 NBIO_SR(BIOS_SCRATCH_3), 349 350 NBIO_SR(BIOS_SCRATCH_6) 351 + }; 352 + 353 + static const struct dce_dmcu_registers dmcu_regs = { 354 + DMCU_DCN10_REG_LIST() 355 + }; 356 + 357 + static const struct dce_dmcu_shift dmcu_shift = { 358 + DMCU_MASK_SH_LIST_DCN10(__SHIFT) 359 + }; 360 + 361 + static const struct dce_dmcu_mask dmcu_mask = { 362 + DMCU_MASK_SH_LIST_DCN10(_MASK) 363 + }; 364 + 365 + static const struct dce_abm_registers abm_regs = { 366 + ABM_DCN20_REG_LIST() 367 + }; 368 + 369 + static const struct dce_abm_shift abm_shift = { 370 + ABM_MASK_SH_LIST_DCN20(__SHIFT) 371 + }; 372 + 373 + static const struct dce_abm_mask abm_mask = { 374 + ABM_MASK_SH_LIST_DCN20(_MASK) 350 375 }; 351 376 352 377 #ifdef CONFIG_DRM_AMD_DC_DMUB ··· 651 628 stream_enc_regs(4), 652 629 }; 653 630 631 + static const struct dce110_aux_registers_shift aux_shift = { 632 + DCN_AUX_MASK_SH_LIST(__SHIFT) 633 + }; 634 + 635 + static const struct dce110_aux_registers_mask aux_mask = { 636 + DCN_AUX_MASK_SH_LIST(_MASK) 637 + }; 638 + 654 639 static const struct dcn10_stream_encoder_shift se_shift = { 655 640 SE_COMMON_MASK_SH_LIST_DCN20(__SHIFT) 656 641 }; ··· 666 635 static const struct dcn10_stream_encoder_mask se_mask = { 667 636 SE_COMMON_MASK_SH_LIST_DCN20(_MASK) 668 637 }; 638 + 639 + static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu); 669 640 670 641 static struct input_pixel_processor *dcn21_ipp_create( 671 642 struct dc_context *ctx, uint32_t inst) ··· 716 683 717 684 dce110_aux_engine_construct(aux_engine, ctx, inst, 718 685 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, 719 - &aux_engine_regs[inst]); 686 + &aux_engine_regs[inst], 687 + &aux_mask, 688 + &aux_shift, 689 + ctx->dc->caps.extended_aux_timeout_support); 720 690 721 691 return &aux_engine->base; 722 692 } ··· 762 726 .num_timing_generator = 4, 763 727 .num_opp = 4, 764 728 .num_video_plane = 4, 765 - .num_audio = 6, // 6 audio endpoints. 4 audio streams 729 + .num_audio = 4, // 4 audio endpoints. 4 audio streams 766 730 .num_stream_encoder = 5, 767 731 .num_pll = 5, // maybe 3 because the last two used for USB-c 768 732 .num_dwb = 1, 769 733 .num_ddc = 5, 734 + .num_vmid = 1, 770 735 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT 771 736 .num_dsc = 3, 772 737 #endif ··· 837 800 .disable_dcc = DCC_ENABLE, 838 801 .vsr_support = true, 839 802 .performance_trace = false, 840 - .max_downscale_src_width = 5120,/*upto 5K*/ 803 + .max_downscale_src_width = 3840, 841 804 .disable_pplib_wm_range = false, 842 805 .scl_reset_length10 = true, 843 806 .sanity_checks = true, 844 - .disable_48mhz_pwrdwn = true, 807 + .disable_48mhz_pwrdwn = false, 845 808 }; 846 809 847 810 static const struct dc_debug_options debug_defaults_diags = { ··· 976 939 dcn_dccg_destroy(&pool->base.dccg); 977 940 978 941 if (pool->base.pp_smu != NULL) 979 - dcn20_pp_smu_destroy(&pool->base.pp_smu); 942 + dcn21_pp_smu_destroy(&pool->base.pp_smu); 980 943 } 981 944 982 945 ··· 1011 974 1012 975 } 1013 976 977 + static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb) 978 + { 979 + kernel_fpu_begin(); 980 + if (dc->bb_overrides.sr_exit_time_ns) { 981 + bb->sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0; 982 + } 983 + 984 + if (dc->bb_overrides.sr_enter_plus_exit_time_ns) { 985 + bb->sr_enter_plus_exit_time_us = 986 + dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0; 987 + } 988 + 989 + if (dc->bb_overrides.urgent_latency_ns) { 990 + bb->urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0; 991 + } 992 + 993 + if (dc->bb_overrides.dram_clock_change_latency_ns) { 994 + bb->dram_clock_change_latency_us = 995 + dc->bb_overrides.dram_clock_change_latency_ns / 1000.0; 996 + } 997 + kernel_fpu_end(); 998 + } 999 + 1014 1000 void dcn21_calculate_wm( 1015 1001 struct dc *dc, struct dc_state *context, 1016 1002 display_e2e_pipe_params_st *pipes, ··· 1047 987 struct clk_bw_params *bw_params = dc->clk_mgr->bw_params; 1048 988 1049 989 ASSERT(bw_params); 990 + 991 + patch_bounding_box(dc, &context->bw_ctx.dml.soc); 1050 992 1051 993 for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { 1052 994 if (!context->res_ctx.pipe_ctx[i].stream) ··· 1340 1278 dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator; 1341 1279 dcn2_1_ip.max_num_dpp = pool->base.pipe_count; 1342 1280 dcn2_1_soc.num_chans = bw_params->num_channels; 1343 - dcn2_1_soc.num_states = 0; 1344 1281 1345 1282 for (i = 0; i < clk_table->num_entries; i++) { 1346 1283 ··· 1349 1288 dcn2_1_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; 1350 1289 /* This is probably wrong, TODO: find correct calculation */ 1351 1290 dcn2_1_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 16 / 1000; 1352 - dcn2_1_soc.num_states++; 1353 1291 } 1292 + dcn2_1_soc.clock_limits[i] = dcn2_1_soc.clock_limits[i - i]; 1293 + dcn2_1_soc.num_states = i; 1354 1294 } 1355 1295 1356 1296 /* Temporary Place holder until we can get them from fuse */ ··· 1379 1317 1380 1318 }; 1381 1319 1382 - enum pp_smu_status dummy_set_wm_ranges(struct pp_smu *pp, 1320 + static enum pp_smu_status dummy_set_wm_ranges(struct pp_smu *pp, 1383 1321 struct pp_smu_wm_range_sets *ranges) 1384 1322 { 1385 1323 return PP_SMU_RESULT_OK; 1386 1324 } 1387 1325 1388 - enum pp_smu_status dummy_get_dpm_clock_table(struct pp_smu *pp, 1326 + static enum pp_smu_status dummy_get_dpm_clock_table(struct pp_smu *pp, 1389 1327 struct dpm_clocks *clock_table) 1390 1328 { 1391 1329 *clock_table = dummy_clocks; 1392 1330 return PP_SMU_RESULT_OK; 1393 1331 } 1394 1332 1395 - struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx) 1333 + static struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx) 1396 1334 { 1397 1335 struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL); 1398 1336 1399 - pp_smu->ctx.ver = PP_SMU_VER_RN; 1337 + if (!pp_smu) 1338 + return pp_smu; 1400 1339 1401 - pp_smu->rn_funcs.get_dpm_clock_table = dummy_get_dpm_clock_table; 1402 - pp_smu->rn_funcs.set_wm_ranges = dummy_set_wm_ranges; 1340 + if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment) || IS_DIAG_DC(ctx->dce_environment)) { 1341 + pp_smu->ctx.ver = PP_SMU_VER_RN; 1342 + pp_smu->rn_funcs.get_dpm_clock_table = dummy_get_dpm_clock_table; 1343 + pp_smu->rn_funcs.set_wm_ranges = dummy_set_wm_ranges; 1344 + } else { 1345 + 1346 + dm_pp_get_funcs(ctx, pp_smu); 1347 + 1348 + if (pp_smu->ctx.ver != PP_SMU_VER_RN) 1349 + pp_smu = memset(pp_smu, 0, sizeof(struct pp_smu_funcs)); 1350 + } 1403 1351 1404 1352 return pp_smu; 1405 1353 } 1406 1354 1407 - void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu) 1355 + static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu) 1408 1356 { 1409 1357 if (pp_smu && *pp_smu) { 1410 1358 kfree(*pp_smu); ··· 1472 1400 hws->regs = &hwseq_reg; 1473 1401 hws->shifts = &hwseq_shift; 1474 1402 hws->masks = &hwseq_mask; 1403 + hws->wa.DEGVIDCN21 = true; 1475 1404 } 1476 1405 return hws; 1477 1406 } ··· 1491 1418 .create_hwseq = dcn21_hwseq_create, 1492 1419 }; 1493 1420 1421 + static const struct encoder_feature_support link_enc_feature = { 1422 + .max_hdmi_deep_color = COLOR_DEPTH_121212, 1423 + .max_hdmi_pixel_clock = 600000, 1424 + .hdmi_ycbcr420_supported = true, 1425 + .dp_ycbcr420_supported = true, 1426 + .flags.bits.IS_HBR2_CAPABLE = true, 1427 + .flags.bits.IS_HBR3_CAPABLE = true, 1428 + .flags.bits.IS_TPS3_CAPABLE = true, 1429 + .flags.bits.IS_TPS4_CAPABLE = true 1430 + }; 1431 + 1432 + 1433 + #define link_regs(id, phyid)\ 1434 + [id] = {\ 1435 + LE_DCN10_REG_LIST(id), \ 1436 + UNIPHY_DCN2_REG_LIST(phyid), \ 1437 + SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \ 1438 + } 1439 + 1440 + static const struct dcn10_link_enc_registers link_enc_regs[] = { 1441 + link_regs(0, A), 1442 + link_regs(1, B), 1443 + link_regs(2, C), 1444 + link_regs(3, D), 1445 + link_regs(4, E), 1446 + }; 1447 + 1448 + #define aux_regs(id)\ 1449 + [id] = {\ 1450 + DCN2_AUX_REG_LIST(id)\ 1451 + } 1452 + 1453 + static const struct dcn10_link_enc_aux_registers link_enc_aux_regs[] = { 1454 + aux_regs(0), 1455 + aux_regs(1), 1456 + aux_regs(2), 1457 + aux_regs(3), 1458 + aux_regs(4) 1459 + }; 1460 + 1461 + #define hpd_regs(id)\ 1462 + [id] = {\ 1463 + HPD_REG_LIST(id)\ 1464 + } 1465 + 1466 + static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = { 1467 + hpd_regs(0), 1468 + hpd_regs(1), 1469 + hpd_regs(2), 1470 + hpd_regs(3), 1471 + hpd_regs(4) 1472 + }; 1473 + 1474 + static const struct dcn10_link_enc_shift le_shift = { 1475 + LINK_ENCODER_MASK_SH_LIST_DCN20(__SHIFT) 1476 + }; 1477 + 1478 + static const struct dcn10_link_enc_mask le_mask = { 1479 + LINK_ENCODER_MASK_SH_LIST_DCN20(_MASK) 1480 + }; 1481 + 1482 + static struct link_encoder *dcn21_link_encoder_create( 1483 + const struct encoder_init_data *enc_init_data) 1484 + { 1485 + struct dcn21_link_encoder *enc21 = 1486 + kzalloc(sizeof(struct dcn21_link_encoder), GFP_KERNEL); 1487 + 1488 + if (!enc21) 1489 + return NULL; 1490 + 1491 + dcn21_link_encoder_construct(enc21, 1492 + enc_init_data, 1493 + &link_enc_feature, 1494 + &link_enc_regs[enc_init_data->transmitter], 1495 + &link_enc_aux_regs[enc_init_data->channel - 1], 1496 + &link_enc_hpd_regs[enc_init_data->hpd_source], 1497 + &le_shift, 1498 + &le_mask); 1499 + 1500 + return &enc21->enc10.base; 1501 + } 1502 + #define CTX ctx 1503 + 1504 + #define REG(reg_name) \ 1505 + (DCN_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) 1506 + 1507 + static uint32_t read_pipe_fuses(struct dc_context *ctx) 1508 + { 1509 + uint32_t value = REG_READ(CC_DC_PIPE_DIS); 1510 + /* RV1 support max 4 pipes */ 1511 + value = value & 0xf; 1512 + return value; 1513 + } 1514 + 1494 1515 static struct resource_funcs dcn21_res_pool_funcs = { 1495 1516 .destroy = dcn21_destroy_resource_pool, 1496 - .link_enc_create = dcn20_link_encoder_create, 1517 + .link_enc_create = dcn21_link_encoder_create, 1497 1518 .validate_bandwidth = dcn21_validate_bandwidth, 1498 1519 .add_stream_to_ctx = dcn20_add_stream_to_ctx, 1499 1520 .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, ··· 1604 1437 struct dc *dc, 1605 1438 struct dcn21_resource_pool *pool) 1606 1439 { 1607 - int i; 1440 + int i, j; 1608 1441 struct dc_context *ctx = dc->ctx; 1609 1442 struct irq_service_init_data init_data; 1443 + uint32_t pipe_fuses = read_pipe_fuses(ctx); 1610 1444 1611 1445 ctx->dc_bios->regs = &bios_regs; 1612 1446 ··· 1625 1457 *************************************************/ 1626 1458 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE; 1627 1459 1628 - pool->base.pipe_count = 4; 1460 + /* max pipe num for ASIC before check pipe fuses */ 1461 + pool->base.pipe_count = pool->base.res_cap->num_timing_generator; 1462 + 1629 1463 dc->caps.max_downscale_ratio = 200; 1630 1464 dc->caps.i2c_speed_in_khz = 100; 1631 1465 dc->caps.max_cursor_size = 256; ··· 1637 1467 dc->caps.max_slave_planes = 1; 1638 1468 dc->caps.post_blend_color_processing = true; 1639 1469 dc->caps.force_dp_tps4_for_cp2520 = true; 1470 + dc->caps.extended_aux_timeout_support = true; 1640 1471 1641 1472 if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) 1642 1473 dc->debug = debug_defaults_drv; ··· 1687 1516 goto create_fail; 1688 1517 } 1689 1518 1519 + pool->base.dmcu = dcn20_dmcu_create(ctx, 1520 + &dmcu_regs, 1521 + &dmcu_shift, 1522 + &dmcu_mask); 1523 + if (pool->base.dmcu == NULL) { 1524 + dm_error("DC: failed to create dmcu!\n"); 1525 + BREAK_TO_DEBUGGER(); 1526 + goto create_fail; 1527 + } 1528 + 1529 + pool->base.abm = dce_abm_create(ctx, 1530 + &abm_regs, 1531 + &abm_shift, 1532 + &abm_mask); 1533 + if (pool->base.abm == NULL) { 1534 + dm_error("DC: failed to create abm!\n"); 1535 + BREAK_TO_DEBUGGER(); 1536 + goto create_fail; 1537 + } 1538 + 1690 1539 #ifdef CONFIG_DRM_AMD_DC_DMUB 1691 1540 pool->base.dmcub = dcn21_dmcub_create(ctx, 1692 1541 &dmcub_regs, ··· 1728 1537 if (!pool->base.irqs) 1729 1538 goto create_fail; 1730 1539 1540 + j = 0; 1731 1541 /* mem input -> ipp -> dpp -> opp -> TG */ 1732 1542 for (i = 0; i < pool->base.pipe_count; i++) { 1543 + /* if pipe is disabled, skip instance of HW pipe, 1544 + * i.e, skip ASIC register instance 1545 + */ 1546 + if ((pipe_fuses & (1 << i)) != 0) 1547 + continue; 1548 + 1733 1549 pool->base.hubps[i] = dcn21_hubp_create(ctx, i); 1734 1550 if (pool->base.hubps[i] == NULL) { 1735 1551 BREAK_TO_DEBUGGER(); ··· 1760 1562 "DC: failed to create dpps!\n"); 1761 1563 goto create_fail; 1762 1564 } 1565 + 1566 + pool->base.opps[i] = dcn21_opp_create(ctx, i); 1567 + if (pool->base.opps[i] == NULL) { 1568 + BREAK_TO_DEBUGGER(); 1569 + dm_error( 1570 + "DC: failed to create output pixel processor!\n"); 1571 + goto create_fail; 1572 + } 1573 + 1574 + pool->base.timing_generators[i] = dcn21_timing_generator_create( 1575 + ctx, i); 1576 + if (pool->base.timing_generators[i] == NULL) { 1577 + BREAK_TO_DEBUGGER(); 1578 + dm_error("DC: failed to create tg!\n"); 1579 + goto create_fail; 1580 + } 1581 + j++; 1763 1582 } 1764 1583 1765 1584 for (i = 0; i < pool->base.res_cap->num_ddc; i++) { ··· 1797 1582 pool->base.sw_i2cs[i] = NULL; 1798 1583 } 1799 1584 1800 - for (i = 0; i < pool->base.res_cap->num_opp; i++) { 1801 - pool->base.opps[i] = dcn21_opp_create(ctx, i); 1802 - if (pool->base.opps[i] == NULL) { 1803 - BREAK_TO_DEBUGGER(); 1804 - dm_error( 1805 - "DC: failed to create output pixel processor!\n"); 1806 - goto create_fail; 1807 - } 1808 - } 1809 - 1810 - for (i = 0; i < pool->base.res_cap->num_timing_generator; i++) { 1811 - pool->base.timing_generators[i] = dcn21_timing_generator_create( 1812 - ctx, i); 1813 - if (pool->base.timing_generators[i] == NULL) { 1814 - BREAK_TO_DEBUGGER(); 1815 - dm_error("DC: failed to create tg!\n"); 1816 - goto create_fail; 1817 - } 1818 - } 1819 - 1820 - pool->base.timing_generator_count = i; 1585 + pool->base.timing_generator_count = j; 1586 + pool->base.pipe_count = j; 1587 + pool->base.mpcc_count = j; 1821 1588 1822 1589 pool->base.mpc = dcn21_mpc_create(ctx); 1823 1590 if (pool->base.mpc == NULL) { ··· 1842 1645 &res_create_funcs : &res_create_maximus_funcs))) 1843 1646 goto create_fail; 1844 1647 1845 - dcn20_hw_sequencer_construct(dc); 1648 + dcn21_hw_sequencer_construct(dc); 1846 1649 1847 1650 dc->caps.max_planes = pool->base.pipe_count; 1848 1651
+3 -6
drivers/gpu/drm/amd/display/dc/dm_pp_smu.h
··· 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 ··· 286 288 enum pp_smu_status (*get_dpm_clock_table) (struct pp_smu *pp, 287 289 struct dpm_clocks *clock_table); 288 290 }; 289 - #endif 290 291 291 292 struct pp_smu_funcs { 292 293 struct pp_smu ctx;
+10 -1
drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
··· 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( ··· 3380 3379 return 30; 3381 3380 else if (DecimalBPP >= 24 && (DesiredBPP == 0 || DesiredBPP == 24)) 3382 3381 return 24; 3382 + else if (DecimalBPP >= 18 && (DesiredBPP == 0 || DesiredBPP == 18)) 3383 + return 18; 3383 3384 else 3384 3385 return BPP_INVALID; 3385 3386 } ··· 3939 3936 mode_lib->vba.MaximumSwathWidthInLineBuffer); 3940 3937 } 3941 3938 for (i = 0; i <= mode_lib->vba.soc.num_states; i++) { 3939 + double MaxMaxDispclkRoundedDown = RoundToDFSGranularityDown( 3940 + mode_lib->vba.MaxDispclk[mode_lib->vba.soc.num_states], 3941 + mode_lib->vba.DISPCLKDPPCLKVCOSpeed); 3942 + 3942 3943 for (j = 0; j < 2; j++) { 3943 3944 mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown( 3944 3945 mode_lib->vba.MaxDispclk[i], ··· 3972 3965 && i == mode_lib->vba.soc.num_states) 3973 3966 mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2 3974 3967 * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0); 3975 - if (mode_lib->vba.ODMCapability == false || mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine <= mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) { 3968 + if (mode_lib->vba.ODMCapability == false || 3969 + (locals->PlaneRequiredDISPCLKWithoutODMCombine <= MaxMaxDispclkRoundedDown 3970 + && (!locals->DSCEnabled[k] || locals->HActive[k] <= DCN21_MAX_DSC_IMAGE_WIDTH))) { 3976 3971 locals->ODMCombineEnablePerState[i][k] = false; 3977 3972 mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine; 3978 3973 } else {
+1 -1
drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
··· 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;
+2
drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
··· 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
+3
drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h
··· 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)(
+10 -1
drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
··· 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 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 }; ··· 181 180 struct dc_state *context, 182 181 enum dc_clock_type clock_type, 183 182 struct dc_clock_config *clock_cfg); 183 + 184 + bool (*are_clock_states_equal) (struct dc_clocks *a, 185 + struct dc_clocks *b); 184 186 }; 185 187 186 188 struct clk_mgr { 187 189 struct dc_context *ctx; 188 190 struct clk_mgr_funcs *funcs; 189 191 struct dc_clocks clks; 192 + bool psr_allow_active_cache; 190 193 int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes 191 194 #ifdef CONFIG_DRM_AMD_DC_DCN2_1 192 195 struct clk_bw_params *bw_params; ··· 203 198 struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *pp_smu, struct dccg *dccg); 204 199 205 200 void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr); 201 + 202 + void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr); 203 + 204 + void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr); 206 205 207 206 #endif /* __DAL_CLK_MGR_H__ */
+23 -2
drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
··· 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; ··· 296 281 297 282 static inline bool should_update_pstate_support(bool safe_to_lower, bool calc_support, bool cur_support) 298 283 { 299 - // Whenever we are transitioning pstate support, we always want to notify prior to committing state 300 - return (calc_support != cur_support) ? !safe_to_lower : false; 284 + if (cur_support != calc_support) { 285 + if (calc_support == true && safe_to_lower) 286 + return true; 287 + else if (calc_support == false && !safe_to_lower) 288 + return true; 289 + } 290 + 291 + return false; 301 292 } 302 293 303 294 int clk_mgr_helper_get_active_display_cnt(
+1
drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
··· 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 {
+1
drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
··· 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 };
+1
drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
··· 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 {
+5
drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
··· 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);
+2
drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
··· 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);
+14 -2
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
··· 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, ··· 331 324 struct dc_state *context); 332 325 void (*update_writeback)(struct dc *dc, 333 326 const struct dc_stream_status *stream_status, 334 - struct dc_writeback_info *wb_info); 327 + struct dc_writeback_info *wb_info, 328 + struct dc_state *context); 335 329 void (*enable_writeback)(struct dc *dc, 336 330 const struct dc_stream_status *stream_status, 337 - struct dc_writeback_info *wb_info); 331 + struct dc_writeback_info *wb_info, 332 + struct dc_state *context); 338 333 void (*disable_writeback)(struct dc *dc, 339 334 unsigned int dwb_pipe_inst); 340 335 #endif ··· 349 340 enum dc_clock_type clock_type, 350 341 struct dc_clock_config *clock_cfg); 351 342 343 + #if defined(CONFIG_DRM_AMD_DC_DCN2_1) 344 + bool (*s0i3_golden_init_wa)(struct dc *dc); 345 + #endif 352 346 }; 353 347 354 348 void color_space_to_black_color(
+2
drivers/gpu/drm/amd/display/include/ddc_service_types.h
··· 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,
+12 -5
drivers/gpu/drm/amd/display/modules/freesync/freesync.c
··· 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 } ··· 747 743 nominal_field_rate_in_uhz = 748 744 mod_freesync_calc_nominal_field_rate(stream); 749 745 746 + /* Rounded to the nearest Hz */ 747 + nominal_field_rate_in_uhz = 1000000ULL * 748 + div_u64(nominal_field_rate_in_uhz + 500000, 1000000); 749 + 750 750 min_refresh_in_uhz = in_config->min_refresh_in_uhz; 751 751 max_refresh_in_uhz = in_config->max_refresh_in_uhz; 752 752 ··· 1006 998 const struct dc_stream_state *stream) 1007 999 { 1008 1000 unsigned long long nominal_field_rate_in_uhz = 0; 1001 + unsigned int total = stream->timing.h_total * stream->timing.v_total; 1009 1002 1010 - /* Calculate nominal field rate for stream */ 1003 + /* Calculate nominal field rate for stream, rounded up to nearest integer */ 1011 1004 nominal_field_rate_in_uhz = stream->timing.pix_clk_100hz / 10; 1012 1005 nominal_field_rate_in_uhz *= 1000ULL * 1000ULL * 1000ULL; 1013 - nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz, 1014 - stream->timing.h_total); 1015 - nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz, 1016 - stream->timing.v_total); 1006 + 1007 + nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz, total); 1017 1008 1018 1009 return nominal_field_rate_in_uhz; 1019 1010 }
+3
drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h
··· 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
+98
drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
··· 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 ··· 394 393 info_packet->sb[18] = 0; 395 394 } 396 395 396 + } 397 + 398 + /** 399 + ***************************************************************************** 400 + * Function: mod_build_hf_vsif_infopacket 401 + * 402 + * @brief 403 + * Prepare HDMI Vendor Specific info frame. 404 + * Follows HDMI Spec to build up Vendor Specific info frame 405 + * 406 + * @param [in] stream: contains data we may need to construct VSIF (i.e. timing_3d_format, etc.) 407 + * @param [out] info_packet: output structure where to store VSIF 408 + ***************************************************************************** 409 + */ 410 + void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream, 411 + struct dc_info_packet *info_packet, int ALLMEnabled, int ALLMValue) 412 + { 413 + unsigned int length = 5; 414 + bool hdmi_vic_mode = false; 415 + uint8_t checksum = 0; 416 + uint32_t i = 0; 417 + enum dc_timing_3d_format format; 418 + bool bALLM = (bool)ALLMEnabled; 419 + bool bALLMVal = (bool)ALLMValue; 420 + 421 + info_packet->valid = false; 422 + format = stream->timing.timing_3d_format; 423 + if (stream->view_format == VIEW_3D_FORMAT_NONE) 424 + format = TIMING_3D_FORMAT_NONE; 425 + 426 + if (stream->timing.hdmi_vic != 0 427 + && stream->timing.h_total >= 3840 428 + && stream->timing.v_total >= 2160 429 + && format == TIMING_3D_FORMAT_NONE) 430 + hdmi_vic_mode = true; 431 + 432 + if ((format == TIMING_3D_FORMAT_NONE) && !hdmi_vic_mode && !bALLM) 433 + return; 434 + 435 + info_packet->sb[1] = 0x03; 436 + info_packet->sb[2] = 0x0C; 437 + info_packet->sb[3] = 0x00; 438 + 439 + if (bALLM) { 440 + info_packet->sb[1] = 0xD8; 441 + info_packet->sb[2] = 0x5D; 442 + info_packet->sb[3] = 0xC4; 443 + info_packet->sb[4] = HF_VSIF_VERSION; 444 + } 445 + 446 + if (format != TIMING_3D_FORMAT_NONE) 447 + info_packet->sb[4] = (2 << 5); 448 + 449 + else if (hdmi_vic_mode) 450 + info_packet->sb[4] = (1 << 5); 451 + 452 + switch (format) { 453 + case TIMING_3D_FORMAT_HW_FRAME_PACKING: 454 + case TIMING_3D_FORMAT_SW_FRAME_PACKING: 455 + info_packet->sb[5] = (0x0 << 4); 456 + break; 457 + 458 + case TIMING_3D_FORMAT_SIDE_BY_SIDE: 459 + case TIMING_3D_FORMAT_SBS_SW_PACKED: 460 + info_packet->sb[5] = (0x8 << 4); 461 + length = 6; 462 + break; 463 + 464 + case TIMING_3D_FORMAT_TOP_AND_BOTTOM: 465 + case TIMING_3D_FORMAT_TB_SW_PACKED: 466 + info_packet->sb[5] = (0x6 << 4); 467 + break; 468 + 469 + default: 470 + break; 471 + } 472 + 473 + if (hdmi_vic_mode) 474 + info_packet->sb[5] = stream->timing.hdmi_vic; 475 + 476 + info_packet->hb0 = HDMI_INFOFRAME_TYPE_VENDOR; 477 + info_packet->hb1 = 0x01; 478 + info_packet->hb2 = (uint8_t) (length); 479 + 480 + if (bALLM) 481 + info_packet->sb[5] = (info_packet->sb[5] & ~0x02) | (bALLMVal << 1); 482 + 483 + checksum += info_packet->hb0; 484 + checksum += info_packet->hb1; 485 + checksum += info_packet->hb2; 486 + 487 + for (i = 1; i <= length; i++) 488 + checksum += info_packet->sb[i]; 489 + 490 + info_packet->sb[0] = (uint8_t) (0x100 - checksum); 491 + 492 + info_packet->valid = true; 397 493 } 398 494
+1
drivers/gpu/drm/amd/include/asic_reg/bif/bif_4_1_d.h
··· 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
+2
drivers/gpu/drm/amd/include/asic_reg/bif/bif_4_1_sh_mask.h
··· 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
+1
drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_0_d.h
··· 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
+2
drivers/gpu/drm/amd/include/asic_reg/bif/bif_5_0_sh_mask.h
··· 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
+10
drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_2_1_0_offset.h
··· 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 ··· 10189 10187 #define mmDP1_DP_STEER_FIFO_BASE_IDX 2 10190 10188 #define mmDP1_DP_MSA_MISC 0x220e 10191 10189 #define mmDP1_DP_MSA_MISC_BASE_IDX 2 10190 + #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x220f 10191 + #define mmDP1_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 10192 10192 #define mmDP1_DP_VID_TIMING 0x2210 10193 10193 #define mmDP1_DP_VID_TIMING_BASE_IDX 2 10194 10194 #define mmDP1_DP_VID_N 0x2211 ··· 10519 10515 #define mmDP2_DP_STEER_FIFO_BASE_IDX 2 10520 10516 #define mmDP2_DP_MSA_MISC 0x230e 10521 10517 #define mmDP2_DP_MSA_MISC_BASE_IDX 2 10518 + #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x230f 10519 + #define mmDP2_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 10522 10520 #define mmDP2_DP_VID_TIMING 0x2310 10523 10521 #define mmDP2_DP_VID_TIMING_BASE_IDX 2 10524 10522 #define mmDP2_DP_VID_N 0x2311 ··· 10849 10843 #define mmDP3_DP_STEER_FIFO_BASE_IDX 2 10850 10844 #define mmDP3_DP_MSA_MISC 0x240e 10851 10845 #define mmDP3_DP_MSA_MISC_BASE_IDX 2 10846 + #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x240f 10847 + #define mmDP3_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 10852 10848 #define mmDP3_DP_VID_TIMING 0x2410 10853 10849 #define mmDP3_DP_VID_TIMING_BASE_IDX 2 10854 10850 #define mmDP3_DP_VID_N 0x2411 ··· 11179 11171 #define mmDP4_DP_STEER_FIFO_BASE_IDX 2 11180 11172 #define mmDP4_DP_MSA_MISC 0x250e 11181 11173 #define mmDP4_DP_MSA_MISC_BASE_IDX 2 11174 + #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x250f 11175 + #define mmDP4_DP_DPHY_INTERNAL_CTRL_BASE_IDX 2 11182 11176 #define mmDP4_DP_VID_TIMING 0x2510 11183 11177 #define mmDP4_DP_VID_TIMING_BASE_IDX 2 11184 11178 #define mmDP4_DP_VID_N 0x2511
+16 -2
drivers/gpu/drm/amd/include/asic_reg/gc/gc_9_0_offset.h
··· 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 ··· 1213 1206 #define mmVM_L2_CACHE_PARITY_CNTL_BASE_IDX 0 1214 1207 #define mmVM_L2_CGTT_CLK_CTRL 0x085e 1215 1208 #define mmVM_L2_CGTT_CLK_CTRL_BASE_IDX 0 1216 - 1209 + #define mmVM_L2_MEM_ECC_INDEX 0x0860 1210 + #define mmVM_L2_MEM_ECC_INDEX_BASE_IDX 0 1211 + #define mmVM_L2_WALKER_MEM_ECC_INDEX 0x0861 1212 + #define mmVM_L2_WALKER_MEM_ECC_INDEX_BASE_IDX 0 1213 + #define mmVM_L2_MEM_ECC_CNT 0x0862 1214 + #define mmVM_L2_MEM_ECC_CNT_BASE_IDX 0 1215 + #define mmVM_L2_WALKER_MEM_ECC_CNT 0x0863 1216 + #define mmVM_L2_WALKER_MEM_ECC_CNT_BASE_IDX 0 1217 1217 1218 1218 // addressBlock: gc_utcl2_vml2vcdec 1219 1219 // base address: 0xa200
+16 -2
drivers/gpu/drm/amd/include/asic_reg/gc/gc_9_0_sh_mask.h
··· 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 ··· 6990 6991 #define VM_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK 0x00008000L 6991 6992 #define VM_L2_CGTT_CLK_CTRL__SOFT_STALL_OVERRIDE_MASK 0x00FF0000L 6992 6993 #define VM_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK 0xFF000000L 6993 - 6994 + //VM_L2_MEM_ECC_INDEX 6995 + #define VM_L2_MEM_ECC_INDEX__INDEX__SHIFT 0x0 6996 + #define VM_L2_MEM_ECC_INDEX__INDEX_MASK 0x000000FFL 6997 + //VM_L2_WALKER_MEM_ECC_INDEX 6998 + #define VM_L2_WALKER_MEM_ECC_INDEX__INDEX__SHIFT 0x0 6999 + #define VM_L2_WALKER_MEM_ECC_INDEX__INDEX_MASK 0x000000FFL 7000 + //VM_L2_MEM_ECC_CNT 7001 + #define VM_L2_MEM_ECC_CNT__SEC_COUNT__SHIFT 0xc 7002 + #define VM_L2_MEM_ECC_CNT__DED_COUNT__SHIFT 0xe 7003 + #define VM_L2_MEM_ECC_CNT__SEC_COUNT_MASK 0x00003000L 7004 + #define VM_L2_MEM_ECC_CNT__DED_COUNT_MASK 0x0000C000L 7005 + //VM_L2_WALKER_MEM_ECC_CNT 7006 + #define VM_L2_WALKER_MEM_ECC_CNT__SEC_COUNT__SHIFT 0xc 7007 + #define VM_L2_WALKER_MEM_ECC_CNT__DED_COUNT__SHIFT 0xe 7008 + #define VM_L2_WALKER_MEM_ECC_CNT__SEC_COUNT_MASK 0x00003000L 7009 + #define VM_L2_WALKER_MEM_ECC_CNT__DED_COUNT_MASK 0x0000C000L 6994 7010 6995 7011 // addressBlock: gc_utcl2_vml2vcdec 6996 7012 //VM_CONTEXT0_CNTL
+1
drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_0_1_d.h
··· 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
+2
drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_0_1_sh_mask.h
··· 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
+1
drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_1_2_d.h
··· 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
+2
drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_1_2_sh_mask.h
··· 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
+1
drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_1_3_d.h
··· 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
+2
drivers/gpu/drm/amd/include/asic_reg/smu/smu_7_1_3_sh_mask.h
··· 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
+21 -6
drivers/gpu/drm/amd/include/atomfirmware.h
··· 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{ ··· 672 671 uint16_t used_by_driver_in_kb; 673 672 }; 674 673 674 + /* This is part of vram_usagebyfirmware_v2_1 */ 675 + struct vram_reserve_block 676 + { 677 + uint32_t start_address_in_kb; 678 + uint16_t used_by_firmware_in_kb; 679 + uint16_t used_by_driver_in_kb; 680 + }; 681 + 682 + /* Definitions for constance */ 683 + enum atomfirmware_internal_constants 684 + { 685 + ONE_KiB = 0x400, 686 + ONE_MiB = 0x100000, 687 + }; 675 688 676 689 /* 677 690 ***************************************************************************
-1
drivers/gpu/drm/amd/include/discovery.h
··· 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
+6
drivers/gpu/drm/amd/include/kgd_pp_interface.h
··· 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 ··· 317 312 int (*get_ppfeature_status)(void *handle, char *buf); 318 313 int (*set_ppfeature_status)(void *handle, uint64_t ppfeature_masks); 319 314 int (*asic_reset_mode_2)(void *handle); 315 + int (*set_df_cstate)(void *handle, enum pp_df_cstate state); 320 316 }; 321 317 322 318 #endif
+34
drivers/gpu/drm/amd/include/renoir_ip_offset.h
··· 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 } }, ··· 1366 1361 #define UVD0_BASE__INST6_SEG3 0 1367 1362 #define UVD0_BASE__INST6_SEG4 0 1368 1363 1364 + #define DCN_BASE__INST0_SEG0 0x00000012 1365 + #define DCN_BASE__INST0_SEG1 0x000000C0 1366 + #define DCN_BASE__INST0_SEG2 0x000034C0 1367 + #define DCN_BASE__INST0_SEG3 0 1368 + #define DCN_BASE__INST0_SEG4 0 1369 + 1370 + #define DCN_BASE__INST1_SEG0 0 1371 + #define DCN_BASE__INST1_SEG1 0 1372 + #define DCN_BASE__INST1_SEG2 0 1373 + #define DCN_BASE__INST1_SEG3 0 1374 + #define DCN_BASE__INST1_SEG4 0 1375 + 1376 + #define DCN_BASE__INST2_SEG0 0 1377 + #define DCN_BASE__INST2_SEG1 0 1378 + #define DCN_BASE__INST2_SEG2 0 1379 + #define DCN_BASE__INST2_SEG3 0 1380 + #define DCN_BASE__INST2_SEG4 0 1381 + 1382 + #define DCN_BASE__INST3_SEG0 0 1383 + #define DCN_BASE__INST3_SEG1 0 1384 + #define DCN_BASE__INST3_SEG2 0 1385 + #define DCN_BASE__INST3_SEG3 0 1386 + #define DCN_BASE__INST3_SEG4 0 1387 + 1388 + #define DCN_BASE__INST4_SEG0 0 1389 + #define DCN_BASE__INST4_SEG1 0 1390 + #define DCN_BASE__INST4_SEG2 0 1391 + #define DCN_BASE__INST4_SEG3 0 1392 + #define DCN_BASE__INST4_SEG4 0 1369 1393 #endif
+19
drivers/gpu/drm/amd/powerplay/amd_powerplay.c
··· 1421 1421 { 1422 1422 struct pp_hwmgr *hwmgr = handle; 1423 1423 1424 + *cap = false; 1424 1425 if (!hwmgr) 1425 1426 return -EINVAL; 1426 1427 ··· 1549 1548 return ret; 1550 1549 } 1551 1550 1551 + static int pp_set_df_cstate(void *handle, enum pp_df_cstate state) 1552 + { 1553 + struct pp_hwmgr *hwmgr = handle; 1554 + 1555 + if (!hwmgr) 1556 + return -EINVAL; 1557 + 1558 + if (!hwmgr->pm_en || !hwmgr->hwmgr_func->set_df_cstate) 1559 + return 0; 1560 + 1561 + mutex_lock(&hwmgr->smu_lock); 1562 + hwmgr->hwmgr_func->set_df_cstate(hwmgr, state); 1563 + mutex_unlock(&hwmgr->smu_lock); 1564 + 1565 + return 0; 1566 + } 1567 + 1552 1568 static const struct amd_pm_funcs pp_dpm_funcs = { 1553 1569 .load_firmware = pp_dpm_load_fw, 1554 1570 .wait_for_fw_loading_complete = pp_dpm_fw_loading_complete, ··· 1624 1606 .set_ppfeature_status = pp_set_ppfeature_status, 1625 1607 .asic_reset_mode_2 = pp_asic_reset_mode_2, 1626 1608 .smu_i2c_bus_access = pp_smu_i2c_bus_access, 1609 + .set_df_cstate = pp_set_df_cstate, 1627 1610 };
+64 -44
drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
··· 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 { ··· 1188 1232 if (adev->flags & AMD_IS_APU) { 1189 1233 smu_powergate_sdma(&adev->smu, false); 1190 1234 smu_powergate_vcn(&adev->smu, false); 1235 + smu_set_gfx_cgpg(&adev->smu, true); 1191 1236 } 1192 1237 1193 1238 if (!smu->pm_enabled) ··· 1350 1393 ret = smu_start_thermal_control(smu); 1351 1394 if (ret) 1352 1395 goto failed; 1396 + 1397 + if (smu->is_apu) 1398 + smu_set_gfx_cgpg(&adev->smu, true); 1399 + 1400 + smu->disable_uclk_switch = 0; 1353 1401 1354 1402 mutex_unlock(&smu->mutex); 1355 1403 ··· 1792 1830 ret = smu_send_smc_msg(smu, msg); 1793 1831 if (ret) 1794 1832 pr_err("[PrepareMp1] Failed!\n"); 1833 + 1834 + return ret; 1835 + } 1836 + 1837 + int smu_set_df_cstate(struct smu_context *smu, 1838 + enum pp_df_cstate state) 1839 + { 1840 + int ret = 0; 1841 + 1842 + /* 1843 + * The SMC is not fully ready. That may be 1844 + * expected as the IP may be masked. 1845 + * So, just return without error. 1846 + */ 1847 + if (!smu->pm_enabled) 1848 + return 0; 1849 + 1850 + if (!smu->ppt_funcs || !smu->ppt_funcs->set_df_cstate) 1851 + return 0; 1852 + 1853 + ret = smu->ppt_funcs->set_df_cstate(smu, state); 1854 + if (ret) 1855 + pr_err("[SetDfCstate] failed!\n"); 1856 + 1857 + return ret; 1858 + } 1859 + 1860 + int smu_write_watermarks_table(struct smu_context *smu) 1861 + { 1862 + int ret = 0; 1863 + struct smu_table_context *smu_table = &smu->smu_table; 1864 + struct smu_table *table = NULL; 1865 + 1866 + table = &smu_table->tables[SMU_TABLE_WATERMARKS]; 1867 + 1868 + if (!table->cpu_addr) 1869 + return -EINVAL; 1870 + 1871 + ret = smu_update_table(smu, SMU_TABLE_WATERMARKS, 0, table->cpu_addr, 1872 + true); 1873 + 1874 + return ret; 1875 + } 1876 + 1877 + int smu_set_watermarks_for_clock_ranges(struct smu_context *smu, 1878 + struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges) 1879 + { 1880 + int ret = 0; 1881 + struct smu_table *watermarks = &smu->smu_table.tables[SMU_TABLE_WATERMARKS]; 1882 + void *table = watermarks->cpu_addr; 1883 + 1884 + if (!smu->disable_watermark && 1885 + smu_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) && 1886 + smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) { 1887 + smu_set_watermarks_table(smu, table, clock_ranges); 1888 + smu->watermarks_bitmap |= WATERMARKS_EXIST; 1889 + smu->watermarks_bitmap &= ~WATERMARKS_LOADED; 1890 + } 1795 1891 1796 1892 return ret; 1797 1893 }
+30
drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
··· 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, ··· 1965 1936 .dump_pptable = arcturus_dump_pptable, 1966 1937 .get_power_limit = arcturus_get_power_limit, 1967 1938 .is_dpm_running = arcturus_is_dpm_running, 1939 + .dpm_set_uvd_enable = arcturus_dpm_set_uvd_enable, 1968 1940 }; 1969 1941 1970 1942 void arcturus_set_ppt_funcs(struct smu_context *smu)
+2 -1
drivers/gpu/drm/amd/powerplay/hwmgr/Makefile
··· 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
+195
drivers/gpu/drm/amd/powerplay/hwmgr/ci_baco.c
··· 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 + }
+29
drivers/gpu/drm/amd/powerplay/hwmgr/ci_baco.h
··· 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
+19
drivers/gpu/drm/amd/powerplay/hwmgr/common_baco.c
··· 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)
+13
drivers/gpu/drm/amd/powerplay/hwmgr/common_baco.h
··· 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; ··· 53 44 uint32_t timeout; 54 45 uint32_t val; 55 46 }; 47 + 48 + extern bool baco_program_registers(struct pp_hwmgr *hwmgr, 49 + const struct baco_cmd_entry *entry, 50 + const u32 array_size); 56 51 extern bool soc15_baco_program_registers(struct pp_hwmgr *hwmgr, 57 52 const struct soc15_baco_cmd_entry *entry, 58 53 const u32 array_size);
+196
drivers/gpu/drm/amd/powerplay/hwmgr/fiji_baco.c
··· 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 + }
+29
drivers/gpu/drm/amd/powerplay/hwmgr/fiji_baco.h
··· 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
+222
drivers/gpu/drm/amd/powerplay/hwmgr/polaris_baco.c
··· 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 + }
+29
drivers/gpu/drm/amd/powerplay/hwmgr/polaris_baco.h
··· 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
+91
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_baco.c
··· 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 + }
+32
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_baco.h
··· 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
+6 -4
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
··· 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 ··· 1995 1994 struct phm_ppt_v1_voltage_lookup_table *lookup_table) 1996 1995 { 1997 1996 uint32_t table_size, i, j; 1998 - struct phm_ppt_v1_voltage_lookup_record tmp_voltage_lookup_record; 1999 1997 table_size = lookup_table->count; 2000 1998 2001 1999 PP_ASSERT_WITH_CODE(0 != lookup_table->count, ··· 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 } ··· 5144 5145 .get_power_profile_mode = smu7_get_power_profile_mode, 5145 5146 .set_power_profile_mode = smu7_set_power_profile_mode, 5146 5147 .get_performance_level = smu7_get_performance_level, 5148 + .get_asic_baco_capability = smu7_baco_get_capability, 5149 + .get_asic_baco_state = smu7_baco_get_state, 5150 + .set_asic_baco_state = smu7_baco_set_state, 5147 5151 .power_off_asic = smu7_power_off_asic, 5148 5152 }; 5149 5153
+231
drivers/gpu/drm/amd/powerplay/hwmgr/tonga_baco.c
··· 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 + }
+29
drivers/gpu/drm/amd/powerplay/hwmgr/tonga_baco.h
··· 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
+2 -4
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
··· 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); ··· 723 724 for (j = i + 1; j > 0; j--) { 724 725 if (lookup_table->entries[j].us_vdd < 725 726 lookup_table->entries[j - 1].us_vdd) { 726 - tmp_voltage_lookup_record = lookup_table->entries[j - 1]; 727 - lookup_table->entries[j - 1] = lookup_table->entries[j]; 728 - lookup_table->entries[j] = tmp_voltage_lookup_record; 727 + swap(lookup_table->entries[j - 1], 728 + lookup_table->entries[j]); 729 729 } 730 730 } 731 731 }
+14 -7
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.c
··· 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 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 ··· 85 84 return 0; 86 85 87 86 if (state == BACO_STATE_IN) { 88 - data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL); 89 - data |= 0x80000000; 90 - WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data); 87 + if (!ras || !ras->supported) { 88 + data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL); 89 + data |= 0x80000000; 90 + WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data); 91 91 92 - 93 - if(smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_EnterBaco, 0)) 94 - return -EINVAL; 92 + if(smum_send_msg_to_smc_with_parameter(hwmgr, 93 + PPSMC_MSG_EnterBaco, 0)) 94 + return -EINVAL; 95 + } else { 96 + if(smum_send_msg_to_smc_with_parameter(hwmgr, 97 + PPSMC_MSG_EnterBaco, 1)) 98 + return -EINVAL; 99 + } 95 100 96 101 } else if (state == BACO_STATE_OUT) { 97 102 if (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ExitBaco))
+24 -2
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
··· 183 183 PHM_PlatformCaps_TablelessHardwareInterface); 184 184 185 185 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 186 + PHM_PlatformCaps_BACO); 187 + 188 + phm_cap_set(hwmgr->platform_descriptor.platformCaps, 186 189 PHM_PlatformCaps_EnableSMU7ThermalManagement); 187 190 188 191 if (adev->pg_flags & AMD_PG_SUPPORT_UVD) ··· 493 490 "Failed to init sclk threshold!", 494 491 return ret); 495 492 496 - if (adev->in_baco_reset) { 497 - adev->in_baco_reset = 0; 493 + if (adev->in_gpu_reset && 494 + (amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)) { 498 495 499 496 ret = vega20_baco_apply_vdci_flush_workaround(hwmgr); 500 497 if (ret) ··· 4158 4155 return res; 4159 4156 } 4160 4157 4158 + static int vega20_set_df_cstate(struct pp_hwmgr *hwmgr, 4159 + enum pp_df_cstate state) 4160 + { 4161 + int ret; 4162 + 4163 + /* PPSMC_MSG_DFCstateControl is supported with 40.50 and later fws */ 4164 + if (hwmgr->smu_version < 0x283200) { 4165 + pr_err("Df cstate control is supported with 40.50 and later SMC fw!\n"); 4166 + return -EINVAL; 4167 + } 4168 + 4169 + ret = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DFCstateControl, state); 4170 + if (ret) 4171 + pr_err("SetDfCstate failed!\n"); 4172 + 4173 + return ret; 4174 + } 4175 + 4161 4176 static const struct pp_hwmgr_func vega20_hwmgr_funcs = { 4162 4177 /* init/fini related */ 4163 4178 .backend_init = vega20_hwmgr_backend_init, ··· 4244 4223 .set_asic_baco_state = vega20_baco_set_state, 4245 4224 .set_mp1_state = vega20_set_mp1_state, 4246 4225 .smu_i2c_bus_access = vega20_smu_i2c_bus_access, 4226 + .set_df_cstate = vega20_set_df_cstate, 4247 4227 }; 4248 4228 4249 4229 int vega20_hwmgr_init(struct pp_hwmgr *hwmgr)
+18 -9
drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
··· 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 ··· 496 493 int (*set_min_dcef_deep_sleep)(struct smu_context *smu); 497 494 int (*set_tool_table_location)(struct smu_context *smu); 498 495 int (*notify_memory_pool_location)(struct smu_context *smu); 499 - int (*write_watermarks_table)(struct smu_context *smu); 500 496 int (*set_last_dcef_min_deep_sleep_clk)(struct smu_context *smu); 501 497 int (*system_features_control)(struct smu_context *smu, bool en); 502 498 int (*send_smc_msg)(struct smu_context *smu, uint16_t msg); ··· 533 531 int (*get_current_shallow_sleep_clocks)(struct smu_context *smu, 534 532 struct smu_clock_info *clocks); 535 533 int (*notify_smu_enable_pwe)(struct smu_context *smu); 536 - int (*set_watermarks_for_clock_ranges)(struct smu_context *smu, 537 - struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges); 538 534 int (*conv_power_profile_to_pplib_workload)(int power_profile); 539 535 uint32_t (*get_fan_control_mode)(struct smu_context *smu); 540 536 int (*set_fan_control_mode)(struct smu_context *smu, uint32_t mode); ··· 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) \ ··· 597 596 ((smu)->funcs->notify_memory_pool_location ? (smu)->funcs->notify_memory_pool_location((smu)) : 0) 598 597 #define smu_gfx_off_control(smu, enable) \ 599 598 ((smu)->funcs->gfx_off_control ? (smu)->funcs->gfx_off_control((smu), (enable)) : 0) 600 - 601 - #define smu_write_watermarks_table(smu) \ 602 - ((smu)->funcs->write_watermarks_table ? (smu)->funcs->write_watermarks_table((smu)) : 0) 603 599 #define smu_set_last_dcef_min_deep_sleep_clk(smu) \ 604 600 ((smu)->funcs->set_last_dcef_min_deep_sleep_clk ? (smu)->funcs->set_last_dcef_min_deep_sleep_clk((smu)) : 0) 605 601 #define smu_system_features_control(smu, en) \ ··· 736 738 ((smu)->funcs->get_current_shallow_sleep_clocks ? (smu)->funcs->get_current_shallow_sleep_clocks((smu), (clocks)) : 0) 737 739 #define smu_notify_smu_enable_pwe(smu) \ 738 740 ((smu)->funcs->notify_smu_enable_pwe ? (smu)->funcs->notify_smu_enable_pwe((smu)) : 0) 739 - #define smu_set_watermarks_for_clock_ranges(smu, clock_ranges) \ 740 - ((smu)->funcs->set_watermarks_for_clock_ranges ? (smu)->funcs->set_watermarks_for_clock_ranges((smu), (clock_ranges)) : 0) 741 741 #define smu_dpm_set_uvd_enable(smu, enable) \ 742 742 ((smu)->ppt_funcs->dpm_set_uvd_enable ? (smu)->ppt_funcs->dpm_set_uvd_enable((smu), (enable)) : 0) 743 743 #define smu_dpm_set_vce_enable(smu, enable) \ ··· 772 776 ((smu)->ppt_funcs->dump_pptable ? (smu)->ppt_funcs->dump_pptable((smu)) : 0) 773 777 #define smu_get_dpm_clk_limited(smu, clk_type, dpm_level, freq) \ 774 778 ((smu)->ppt_funcs->get_dpm_clk_limited ? (smu)->ppt_funcs->get_dpm_clk_limited((smu), (clk_type), (dpm_level), (freq)) : -EINVAL) 775 - 776 779 #define smu_set_soft_freq_limited_range(smu, clk_type, min, max) \ 777 780 ((smu)->funcs->set_soft_freq_limited_range ? (smu)->funcs->set_soft_freq_limited_range((smu), (clk_type), (min), (max)) : -EINVAL) 781 + #define smu_get_dpm_clock_table(smu, clock_table) \ 782 + ((smu)->ppt_funcs->get_dpm_clock_table ? (smu)->ppt_funcs->get_dpm_clock_table((smu), (clock_table)) : -EINVAL) 783 + 784 + #define smu_override_pcie_parameters(smu) \ 785 + ((smu)->funcs->override_pcie_parameters ? (smu)->funcs->override_pcie_parameters((smu)) : 0) 786 + 787 + #define smu_update_pcie_parameters(smu, pcie_gen_cap, pcie_width_cap) \ 788 + ((smu)->ppt_funcs->update_pcie_parameters ? (smu)->ppt_funcs->update_pcie_parameters((smu), (pcie_gen_cap), (pcie_width_cap)) : 0) 778 789 779 790 extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table, 780 791 uint16_t *size, uint8_t *frev, uint8_t *crev, ··· 815 812 int smu_sys_set_pp_table(struct smu_context *smu, void *buf, size_t size); 816 813 int smu_get_power_num_states(struct smu_context *smu, struct pp_states_info *state_info); 817 814 enum amd_pm_state_type smu_get_current_power_state(struct smu_context *smu); 815 + int smu_write_watermarks_table(struct smu_context *smu); 816 + int smu_set_watermarks_for_clock_ranges( 817 + struct smu_context *smu, 818 + struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges); 818 819 819 820 /* smu to display interface */ 820 821 extern int smu_display_configuration_change(struct smu_context *smu, const ··· 857 850 uint32_t mask); 858 851 int smu_set_mp1_state(struct smu_context *smu, 859 852 enum pp_mp1_state mp1_state); 853 + int smu_set_df_cstate(struct smu_context *smu, 854 + enum pp_df_cstate state); 860 855 861 856 #endif
+1
drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
··· 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 {
+1
drivers/gpu/drm/amd/powerplay/inc/smu_types.h
··· 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
+2 -1
drivers/gpu/drm/amd/powerplay/inc/vega20_ppsmc.h
··· 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;
+85 -25
drivers/gpu/drm/amd/powerplay/navi10_ppt.c
··· 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); ··· 1464 1452 uint32_t sclk_freq = 0, uclk_freq = 0; 1465 1453 uint32_t uclk_level = 0; 1466 1454 1467 - switch (adev->pdev->revision) { 1468 - case 0xf0: /* XTX */ 1469 - case 0xc0: 1470 - sclk_freq = NAVI10_PEAK_SCLK_XTX; 1455 + switch (adev->asic_type) { 1456 + case CHIP_NAVI10: 1457 + switch (adev->pdev->revision) { 1458 + case 0xf0: /* XTX */ 1459 + case 0xc0: 1460 + sclk_freq = NAVI10_PEAK_SCLK_XTX; 1461 + break; 1462 + case 0xf1: /* XT */ 1463 + case 0xc1: 1464 + sclk_freq = NAVI10_PEAK_SCLK_XT; 1465 + break; 1466 + default: /* XL */ 1467 + sclk_freq = NAVI10_PEAK_SCLK_XL; 1468 + break; 1469 + } 1471 1470 break; 1472 - case 0xf1: /* XT */ 1473 - case 0xc1: 1474 - sclk_freq = NAVI10_PEAK_SCLK_XT; 1471 + case CHIP_NAVI14: 1472 + switch (adev->pdev->revision) { 1473 + case 0xc7: /* XT */ 1474 + case 0xf4: 1475 + sclk_freq = NAVI14_UMD_PSTATE_PEAK_XT_GFXCLK; 1476 + break; 1477 + case 0xc1: /* XTM */ 1478 + case 0xf2: 1479 + sclk_freq = NAVI14_UMD_PSTATE_PEAK_XTM_GFXCLK; 1480 + break; 1481 + case 0xc3: /* XLM */ 1482 + case 0xf3: 1483 + sclk_freq = NAVI14_UMD_PSTATE_PEAK_XLM_GFXCLK; 1484 + break; 1485 + case 0xc5: /* XTX */ 1486 + case 0xf6: 1487 + sclk_freq = NAVI14_UMD_PSTATE_PEAK_XLM_GFXCLK; 1488 + break; 1489 + default: /* XL */ 1490 + sclk_freq = NAVI14_UMD_PSTATE_PEAK_XL_GFXCLK; 1491 + break; 1492 + } 1475 1493 break; 1476 - default: /* XL */ 1477 - sclk_freq = NAVI10_PEAK_SCLK_XL; 1478 - break; 1494 + default: 1495 + return -EINVAL; 1479 1496 } 1480 1497 1481 1498 ret = smu_get_dpm_level_count(smu, SMU_UCLK, &uclk_level); ··· 1527 1486 static int navi10_set_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level) 1528 1487 { 1529 1488 int ret = 0; 1530 - struct amdgpu_device *adev = smu->adev; 1531 - 1532 - if (adev->asic_type != CHIP_NAVI10) 1533 - return -EINVAL; 1534 1489 1535 1490 switch (level) { 1536 1491 case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: ··· 1629 1592 return 0; 1630 1593 } 1631 1594 1595 + static int navi10_update_pcie_parameters(struct smu_context *smu, 1596 + uint32_t pcie_gen_cap, 1597 + uint32_t pcie_width_cap) 1598 + { 1599 + PPTable_t *pptable = smu->smu_table.driver_pptable; 1600 + int ret, i; 1601 + uint32_t smu_pcie_arg; 1602 + 1603 + for (i = 0; i < NUM_LINK_LEVELS; i++) { 1604 + smu_pcie_arg = (i << 16) | 1605 + ((pptable->PcieGenSpeed[i] <= pcie_gen_cap) ? (pptable->PcieGenSpeed[i] << 8) : 1606 + (pcie_gen_cap << 8)) | ((pptable->PcieLaneCount[i] <= pcie_width_cap) ? 1607 + pptable->PcieLaneCount[i] : pcie_width_cap); 1608 + ret = smu_send_smc_msg_with_param(smu, 1609 + SMU_MSG_OverridePcieParameters, 1610 + smu_pcie_arg); 1611 + } 1612 + 1613 + return ret; 1614 + } 1615 + 1616 + 1632 1617 static const struct pptable_funcs navi10_ppt_funcs = { 1633 1618 .tables_init = navi10_tables_init, 1634 1619 .alloc_dpm_context = navi10_allocate_dpm_context, ··· 1689 1630 .get_thermal_temperature_range = navi10_get_thermal_temperature_range, 1690 1631 .display_disable_memory_clock_switch = navi10_display_disable_memory_clock_switch, 1691 1632 .get_power_limit = navi10_get_power_limit, 1633 + .update_pcie_parameters = navi10_update_pcie_parameters, 1692 1634 }; 1693 1635 1694 1636 void navi10_set_ppt_funcs(struct smu_context *smu)
+6
drivers/gpu/drm/amd/powerplay/navi10_ppt.h
··· 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
+130
drivers/gpu/drm/amd/powerplay/renoir_ppt.c
··· 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 { ··· 580 546 return ret; 581 547 } 582 548 549 + /* save watermark settings into pplib smu structure, 550 + * also pass data to smu controller 551 + */ 552 + static int renoir_set_watermarks_table( 553 + struct smu_context *smu, 554 + void *watermarks, 555 + struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges) 556 + { 557 + int i; 558 + int ret = 0; 559 + Watermarks_t *table = watermarks; 560 + 561 + if (!table || !clock_ranges) 562 + return -EINVAL; 563 + 564 + if (clock_ranges->num_wm_dmif_sets > 4 || 565 + clock_ranges->num_wm_mcif_sets > 4) 566 + return -EINVAL; 567 + 568 + /* save into smu->smu_table.tables[SMU_TABLE_WATERMARKS]->cpu_addr*/ 569 + for (i = 0; i < clock_ranges->num_wm_dmif_sets; i++) { 570 + table->WatermarkRow[WM_DCFCLK][i].MinClock = 571 + cpu_to_le16((uint16_t) 572 + (clock_ranges->wm_dmif_clocks_ranges[i].wm_min_dcfclk_clk_in_khz)); 573 + table->WatermarkRow[WM_DCFCLK][i].MaxClock = 574 + cpu_to_le16((uint16_t) 575 + (clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz)); 576 + table->WatermarkRow[WM_DCFCLK][i].MinMclk = 577 + cpu_to_le16((uint16_t) 578 + (clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz)); 579 + table->WatermarkRow[WM_DCFCLK][i].MaxMclk = 580 + cpu_to_le16((uint16_t) 581 + (clock_ranges->wm_dmif_clocks_ranges[i].wm_max_mem_clk_in_khz)); 582 + table->WatermarkRow[WM_DCFCLK][i].WmSetting = (uint8_t) 583 + clock_ranges->wm_dmif_clocks_ranges[i].wm_set_id; 584 + } 585 + 586 + for (i = 0; i < clock_ranges->num_wm_mcif_sets; i++) { 587 + table->WatermarkRow[WM_SOCCLK][i].MinClock = 588 + cpu_to_le16((uint16_t) 589 + (clock_ranges->wm_mcif_clocks_ranges[i].wm_min_socclk_clk_in_khz)); 590 + table->WatermarkRow[WM_SOCCLK][i].MaxClock = 591 + cpu_to_le16((uint16_t) 592 + (clock_ranges->wm_mcif_clocks_ranges[i].wm_max_socclk_clk_in_khz)); 593 + table->WatermarkRow[WM_SOCCLK][i].MinMclk = 594 + cpu_to_le16((uint16_t) 595 + (clock_ranges->wm_mcif_clocks_ranges[i].wm_min_mem_clk_in_khz)); 596 + table->WatermarkRow[WM_SOCCLK][i].MaxMclk = 597 + cpu_to_le16((uint16_t) 598 + (clock_ranges->wm_mcif_clocks_ranges[i].wm_max_mem_clk_in_khz)); 599 + table->WatermarkRow[WM_SOCCLK][i].WmSetting = (uint8_t) 600 + clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id; 601 + } 602 + 603 + /* pass data to smu controller */ 604 + ret = smu_write_watermarks_table(smu); 605 + 606 + return ret; 607 + } 608 + 609 + static int renoir_get_power_profile_mode(struct smu_context *smu, 610 + char *buf) 611 + { 612 + static const char *profile_name[] = { 613 + "BOOTUP_DEFAULT", 614 + "3D_FULL_SCREEN", 615 + "POWER_SAVING", 616 + "VIDEO", 617 + "VR", 618 + "COMPUTE", 619 + "CUSTOM"}; 620 + uint32_t i, size = 0; 621 + int16_t workload_type = 0; 622 + 623 + if (!smu->pm_enabled || !buf) 624 + return -EINVAL; 625 + 626 + for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) { 627 + /* 628 + * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT 629 + * Not all profile modes are supported on arcturus. 630 + */ 631 + workload_type = smu_workload_get_type(smu, i); 632 + if (workload_type < 0) 633 + continue; 634 + 635 + size += sprintf(buf + size, "%2d %14s%s\n", 636 + i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " "); 637 + } 638 + 639 + return size; 640 + } 641 + 583 642 static const struct pptable_funcs renoir_ppt_funcs = { 584 643 .get_smu_msg_index = renoir_get_smu_msg_index, 585 644 .get_smu_table_index = renoir_get_smu_table_index, ··· 689 562 .force_clk_levels = renoir_force_clk_levels, 690 563 .set_power_profile_mode = renoir_set_power_profile_mode, 691 564 .set_performance_level = renoir_set_performance_level, 565 + .get_dpm_clock_table = renoir_get_dpm_clock_table, 566 + .set_watermarks_table = renoir_set_watermarks_table, 567 + .get_power_profile_mode = renoir_get_power_profile_mode, 692 568 }; 693 569 694 570 void renoir_set_ppt_funcs(struct smu_context *smu)
+44 -39
drivers/gpu/drm/amd/powerplay/smu_v11_0.c
··· 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" ··· 771 770 return ret; 772 771 } 773 772 774 - static int smu_v11_0_write_watermarks_table(struct smu_context *smu) 775 - { 776 - int ret = 0; 777 - struct smu_table_context *smu_table = &smu->smu_table; 778 - struct smu_table *table = NULL; 779 - 780 - table = &smu_table->tables[SMU_TABLE_WATERMARKS]; 781 - 782 - if (!table->cpu_addr) 783 - return -EINVAL; 784 - 785 - ret = smu_update_table(smu, SMU_TABLE_WATERMARKS, 0, table->cpu_addr, 786 - true); 787 - 788 - return ret; 789 - } 790 - 791 773 static int smu_v11_0_set_deep_sleep_dcefclk(struct smu_context *smu, uint32_t clk) 792 774 { 793 775 int ret; ··· 1320 1336 return ret; 1321 1337 } 1322 1338 1323 - static int 1324 - smu_v11_0_set_watermarks_for_clock_ranges(struct smu_context *smu, struct 1325 - dm_pp_wm_sets_with_clock_ranges_soc15 1326 - *clock_ranges) 1327 - { 1328 - int ret = 0; 1329 - struct smu_table *watermarks = &smu->smu_table.tables[SMU_TABLE_WATERMARKS]; 1330 - void *table = watermarks->cpu_addr; 1331 - 1332 - if (!smu->disable_watermark && 1333 - smu_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) && 1334 - smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) { 1335 - smu_set_watermarks_table(smu, table, clock_ranges); 1336 - smu->watermarks_bitmap |= WATERMARKS_EXIST; 1337 - smu->watermarks_bitmap &= ~WATERMARKS_LOADED; 1338 - } 1339 - 1340 - return ret; 1341 - } 1342 - 1343 1339 static int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable) 1344 1340 { 1345 1341 int ret = 0; ··· 1756 1792 return ret; 1757 1793 } 1758 1794 1795 + static int smu_v11_0_override_pcie_parameters(struct smu_context *smu) 1796 + { 1797 + struct amdgpu_device *adev = smu->adev; 1798 + uint32_t pcie_gen = 0, pcie_width = 0; 1799 + int ret; 1800 + 1801 + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) 1802 + pcie_gen = 3; 1803 + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) 1804 + pcie_gen = 2; 1805 + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) 1806 + pcie_gen = 1; 1807 + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1) 1808 + pcie_gen = 0; 1809 + 1810 + /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1 1811 + * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 1812 + * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 1813 + */ 1814 + if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) 1815 + pcie_width = 6; 1816 + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) 1817 + pcie_width = 5; 1818 + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) 1819 + pcie_width = 4; 1820 + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) 1821 + pcie_width = 3; 1822 + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) 1823 + pcie_width = 2; 1824 + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) 1825 + pcie_width = 1; 1826 + 1827 + ret = smu_update_pcie_parameters(smu, pcie_gen, pcie_width); 1828 + 1829 + if (ret) 1830 + pr_err("[%s] Attempt to override pcie params failed!\n", __func__); 1831 + 1832 + return ret; 1833 + 1834 + } 1835 + 1836 + 1759 1837 static const struct smu_funcs smu_v11_0_funcs = { 1760 1838 .init_microcode = smu_v11_0_init_microcode, 1761 1839 .load_microcode = smu_v11_0_load_microcode, ··· 1818 1812 .parse_pptable = smu_v11_0_parse_pptable, 1819 1813 .populate_smc_tables = smu_v11_0_populate_smc_pptable, 1820 1814 .write_pptable = smu_v11_0_write_pptable, 1821 - .write_watermarks_table = smu_v11_0_write_watermarks_table, 1822 1815 .set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep, 1823 1816 .set_tool_table_location = smu_v11_0_set_tool_table_location, 1824 1817 .init_display_count = smu_v11_0_init_display_count, ··· 1833 1828 .read_sensor = smu_v11_0_read_sensor, 1834 1829 .set_deep_sleep_dcefclk = smu_v11_0_set_deep_sleep_dcefclk, 1835 1830 .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request, 1836 - .set_watermarks_for_clock_ranges = smu_v11_0_set_watermarks_for_clock_ranges, 1837 1831 .get_fan_control_mode = smu_v11_0_get_fan_control_mode, 1838 1832 .set_fan_control_mode = smu_v11_0_set_fan_control_mode, 1839 1833 .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent, ··· 1848 1844 .baco_reset = smu_v11_0_baco_reset, 1849 1845 .get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq, 1850 1846 .set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range, 1847 + .override_pcie_parameters = smu_v11_0_override_pcie_parameters, 1851 1848 }; 1852 1849 1853 1850 void smu_v11_0_set_smu_funcs(struct smu_context *smu)
-9
drivers/gpu/drm/amd/powerplay/smu_v12_0.c
··· 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
+47 -1
drivers/gpu/drm/amd/powerplay/vega20_ppt.c
··· 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] = { ··· 3136 3135 return 0; 3137 3136 } 3138 3137 3138 + static int vega20_set_df_cstate(struct smu_context *smu, 3139 + enum pp_df_cstate state) 3140 + { 3141 + uint32_t smu_version; 3142 + int ret; 3143 + 3144 + ret = smu_get_smc_version(smu, NULL, &smu_version); 3145 + if (ret) { 3146 + pr_err("Failed to get smu version!\n"); 3147 + return ret; 3148 + } 3149 + 3150 + /* PPSMC_MSG_DFCstateControl is supported with 40.50 and later fws */ 3151 + if (smu_version < 0x283200) { 3152 + pr_err("Df cstate control is supported with 40.50 and later SMC fw!\n"); 3153 + return -EINVAL; 3154 + } 3155 + 3156 + return smu_send_smc_msg_with_param(smu, SMU_MSG_DFCstateControl, state); 3157 + } 3158 + 3159 + static int vega20_update_pcie_parameters(struct smu_context *smu, 3160 + uint32_t pcie_gen_cap, 3161 + uint32_t pcie_width_cap) 3162 + { 3163 + PPTable_t *pptable = smu->smu_table.driver_pptable; 3164 + int ret, i; 3165 + uint32_t smu_pcie_arg; 3166 + 3167 + for (i = 0; i < NUM_LINK_LEVELS; i++) { 3168 + smu_pcie_arg = (i << 16) | 3169 + ((pptable->PcieGenSpeed[i] <= pcie_gen_cap) ? (pptable->PcieGenSpeed[i] << 8) : 3170 + (pcie_gen_cap << 8)) | ((pptable->PcieLaneCount[i] <= pcie_width_cap) ? 3171 + pptable->PcieLaneCount[i] : pcie_width_cap); 3172 + ret = smu_send_smc_msg_with_param(smu, 3173 + SMU_MSG_OverridePcieParameters, 3174 + smu_pcie_arg); 3175 + } 3176 + 3177 + return ret; 3178 + } 3179 + 3180 + 3139 3181 static const struct pptable_funcs vega20_ppt_funcs = { 3140 3182 .tables_init = vega20_tables_init, 3141 3183 .alloc_dpm_context = vega20_allocate_dpm_context, ··· 3221 3177 .get_fan_speed_percent = vega20_get_fan_speed_percent, 3222 3178 .get_fan_speed_rpm = vega20_get_fan_speed_rpm, 3223 3179 .set_watermarks_table = vega20_set_watermarks_table, 3224 - .get_thermal_temperature_range = vega20_get_thermal_temperature_range 3180 + .get_thermal_temperature_range = vega20_get_thermal_temperature_range, 3181 + .set_df_cstate = vega20_set_df_cstate, 3182 + .update_pcie_parameters = vega20_update_pcie_parameters 3225 3183 }; 3226 3184 3227 3185 void vega20_set_ppt_funcs(struct smu_context *smu)