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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'amd-drm-next-7.1-2026-03-25' of https://gitlab.freedesktop.org/agd5f/linux into drm-next

amd-drm-next-7.1-2026-03-25:

amdgpu:
- DSC fix
- Module parameter parsing fix
- PASID reuse fix
- drm_edid leak fix
- SMU 13.x fixes
- SMU 14.x fix
- Fence fix in amdgpu_amdkfd_submit_ib()
- LVDS fixes
- GPU page fault fix for non-4K pages
- Misc cleanups
- UserQ fixes
- SMU 15.0.8 support
- RAS updates
- Devcoredump fixes
- GFX queue priority fixes
- DPIA fixes
- DCN 4.2 updates
- Add debugfs interface for pcie64 registers
- SMU 15.x fixes
- VCN reset fixes
- Documentation fixes

amdkfd:
- Ordering fix in kfd_ioctl_create_process()

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patch.msgid.link/20260325175012.4185721-1-alexander.deucher@amd.com

+4866 -944
+1
drivers/gpu/drm/amd/amdgpu/amdgpu.h
··· 690 690 AMDGPU_UID_TYPE_XCD, 691 691 AMDGPU_UID_TYPE_AID, 692 692 AMDGPU_UID_TYPE_SOC, 693 + AMDGPU_UID_TYPE_MID, 693 694 AMDGPU_UID_TYPE_MAX 694 695 }; 695 696
+2 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
··· 692 692 goto err_ib_sched; 693 693 } 694 694 695 - /* Drop the initial kref_init count (see drm_sched_main as example) */ 696 - dma_fence_put(f); 697 695 ret = dma_fence_wait(f, false); 696 + /* Drop the returned fence reference after the wait completes */ 697 + dma_fence_put(f); 698 698 699 699 err_ib_sched: 700 700 amdgpu_job_free(job);
+112
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
··· 618 618 } 619 619 620 620 /** 621 + * amdgpu_debugfs_regs_pcie64_read - Read from a 64-bit PCIE register 622 + * 623 + * @f: open file handle 624 + * @buf: User buffer to store read data in 625 + * @size: Number of bytes to read 626 + * @pos: Offset to seek to 627 + */ 628 + static ssize_t amdgpu_debugfs_regs_pcie64_read(struct file *f, char __user *buf, 629 + size_t size, loff_t *pos) 630 + { 631 + struct amdgpu_device *adev = file_inode(f)->i_private; 632 + ssize_t result = 0; 633 + int r; 634 + 635 + if (size & 0x7 || *pos & 0x7) 636 + return -EINVAL; 637 + 638 + r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 639 + if (r < 0) { 640 + pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 641 + return r; 642 + } 643 + 644 + r = amdgpu_virt_enable_access_debugfs(adev); 645 + if (r < 0) { 646 + pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 647 + return r; 648 + } 649 + 650 + while (size) { 651 + uint64_t value; 652 + 653 + value = RREG64_PCIE_EXT(*pos); 654 + 655 + r = put_user(value, (uint64_t *)buf); 656 + if (r) 657 + goto out; 658 + 659 + result += 8; 660 + buf += 8; 661 + *pos += 8; 662 + size -= 8; 663 + } 664 + 665 + r = result; 666 + out: 667 + pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 668 + amdgpu_virt_disable_access_debugfs(adev); 669 + return r; 670 + } 671 + 672 + /** 673 + * amdgpu_debugfs_regs_pcie64_write - Write to a 64-bit PCIE register 674 + * 675 + * @f: open file handle 676 + * @buf: User buffer to write data from 677 + * @size: Number of bytes to write 678 + * @pos: Offset to seek to 679 + */ 680 + static ssize_t amdgpu_debugfs_regs_pcie64_write(struct file *f, const char __user *buf, 681 + size_t size, loff_t *pos) 682 + { 683 + struct amdgpu_device *adev = file_inode(f)->i_private; 684 + ssize_t result = 0; 685 + int r; 686 + 687 + if (size & 0x7 || *pos & 0x7) 688 + return -EINVAL; 689 + 690 + r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 691 + if (r < 0) { 692 + pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 693 + return r; 694 + } 695 + 696 + r = amdgpu_virt_enable_access_debugfs(adev); 697 + if (r < 0) { 698 + pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 699 + return r; 700 + } 701 + 702 + while (size) { 703 + uint64_t value; 704 + 705 + r = get_user(value, (uint64_t *)buf); 706 + if (r) 707 + goto out; 708 + 709 + WREG64_PCIE_EXT(*pos, value); 710 + 711 + result += 8; 712 + buf += 8; 713 + *pos += 8; 714 + size -= 8; 715 + } 716 + 717 + r = result; 718 + out: 719 + pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 720 + amdgpu_virt_disable_access_debugfs(adev); 721 + return r; 722 + } 723 + 724 + /** 621 725 * amdgpu_debugfs_regs_didt_read - Read from a DIDT register 622 726 * 623 727 * @f: open file handle ··· 1629 1525 .write = amdgpu_debugfs_regs_pcie_write, 1630 1526 .llseek = default_llseek 1631 1527 }; 1528 + static const struct file_operations amdgpu_debugfs_regs_pcie64_fops = { 1529 + .owner = THIS_MODULE, 1530 + .read = amdgpu_debugfs_regs_pcie64_read, 1531 + .write = amdgpu_debugfs_regs_pcie64_write, 1532 + .llseek = default_llseek 1533 + }; 1632 1534 static const struct file_operations amdgpu_debugfs_regs_smc_fops = { 1633 1535 .owner = THIS_MODULE, 1634 1536 .read = amdgpu_debugfs_regs_smc_read, ··· 1697 1587 &amdgpu_debugfs_gprwave_fops, 1698 1588 &amdgpu_debugfs_regs_didt_fops, 1699 1589 &amdgpu_debugfs_regs_pcie_fops, 1590 + &amdgpu_debugfs_regs_pcie64_fops, 1700 1591 &amdgpu_debugfs_regs_smc_fops, 1701 1592 &amdgpu_debugfs_gca_config_fops, 1702 1593 &amdgpu_debugfs_sensors_fops, ··· 1715 1604 "amdgpu_gprwave", 1716 1605 "amdgpu_regs_didt", 1717 1606 "amdgpu_regs_pcie", 1607 + "amdgpu_regs_pcie64", 1718 1608 "amdgpu_regs_smc", 1719 1609 "amdgpu_gca_config", 1720 1610 "amdgpu_sensors",
+11 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 3498 3498 3499 3499 static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev) 3500 3500 { 3501 - char *input = amdgpu_lockup_timeout; 3501 + char buf[AMDGPU_MAX_TIMEOUT_PARAM_LENGTH]; 3502 + char *input = buf; 3502 3503 char *timeout_setting = NULL; 3503 3504 int index = 0; 3504 3505 long timeout; ··· 3509 3508 adev->gfx_timeout = adev->compute_timeout = adev->sdma_timeout = 3510 3509 adev->video_timeout = msecs_to_jiffies(2000); 3511 3510 3512 - if (!strnlen(input, AMDGPU_MAX_TIMEOUT_PARAM_LENGTH)) 3511 + if (!strnlen(amdgpu_lockup_timeout, AMDGPU_MAX_TIMEOUT_PARAM_LENGTH)) 3513 3512 return 0; 3513 + 3514 + /* 3515 + * strsep() destructively modifies its input by replacing delimiters 3516 + * with '\0'. Use a stack copy so the global module parameter buffer 3517 + * remains intact for multi-GPU systems where this function is called 3518 + * once per device. 3519 + */ 3520 + strscpy(buf, amdgpu_lockup_timeout, sizeof(buf)); 3514 3521 3515 3522 while ((timeout_setting = strsep(&input, ",")) && 3516 3523 strnlen(timeout_setting, AMDGPU_MAX_TIMEOUT_PARAM_LENGTH)) {
+20 -11
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
··· 324 324 ret = amdgpu_acpi_get_tmr_info(adev, &tmr_offset, &tmr_size); 325 325 if (ret) 326 326 return ret; 327 - adev->discovery.size = (u32)tmr_size; 327 + adev->discovery.size = DISCOVERY_TMR_SIZE; 328 328 adev->discovery.offset = tmr_offset + tmr_size - DISCOVERY_TMR_OFFSET; 329 329 } 330 330 } ··· 1394 1394 struct list_head *el, *tmp; 1395 1395 struct kset *die_kset; 1396 1396 1397 + if (!ip_top) 1398 + return; 1399 + 1397 1400 die_kset = &ip_top->die_kset; 1398 1401 spin_lock(&die_kset->list_lock); 1399 1402 list_for_each_prev_safe(el, tmp, &die_kset->list) { ··· 1421 1418 struct ip_hw_instance *ip_inst; 1422 1419 int i = 0, j; 1423 1420 1421 + if (!ip_top) 1422 + return; 1423 + 1424 1424 die_kset = &ip_top->die_kset; 1425 1425 1426 1426 drm_printf(p, "\nHW IP Discovery\n"); 1427 + 1427 1428 spin_lock(&die_kset->list_lock); 1428 1429 list_for_each(el_die, &die_kset->list) { 1429 1430 drm_printf(p, "die %d\n", i++); ··· 1984 1977 1985 1978 int amdgpu_discovery_get_nps_info(struct amdgpu_device *adev, 1986 1979 uint32_t *nps_type, 1987 - struct amdgpu_gmc_memrange **ranges, 1980 + struct amdgpu_gmc_memrange *ranges, 1988 1981 int *range_cnt, bool refresh) 1989 1982 { 1990 1983 uint8_t *discovery_bin = adev->discovery.bin; 1991 - struct amdgpu_gmc_memrange *mem_ranges; 1992 1984 struct table_info *info; 1993 1985 union nps_info *nps_info; 1994 1986 union nps_info nps_data; ··· 2025 2019 2026 2020 switch (le16_to_cpu(nps_info->v1.header.version_major)) { 2027 2021 case 1: 2028 - mem_ranges = kvzalloc_objs(*mem_ranges, nps_info->v1.count); 2029 - if (!mem_ranges) 2030 - return -ENOMEM; 2031 2022 *nps_type = nps_info->v1.nps_type; 2023 + if (*range_cnt < nps_info->v1.count) { 2024 + dev_dbg(adev->dev, 2025 + "not enough space for nps ranges: %d < %d\n", 2026 + *range_cnt, nps_info->v1.count); 2027 + return -ENOSPC; 2028 + } 2032 2029 *range_cnt = nps_info->v1.count; 2033 2030 for (i = 0; i < *range_cnt; i++) { 2034 - mem_ranges[i].base_address = 2031 + ranges[i].base_address = 2035 2032 nps_info->v1.instance_info[i].base_address; 2036 - mem_ranges[i].limit_address = 2033 + ranges[i].limit_address = 2037 2034 nps_info->v1.instance_info[i].limit_address; 2038 - mem_ranges[i].nid_mask = -1; 2039 - mem_ranges[i].flags = 0; 2035 + ranges[i].nid_mask = -1; 2036 + ranges[i].flags = 0; 2040 2037 } 2041 - *ranges = mem_ranges; 2042 2038 break; 2043 2039 default: 2044 2040 dev_err(adev->dev, "Unhandled NPS info table %d.%d\n", ··· 2342 2334 amdgpu_device_ip_block_add(adev, &smu_v14_0_ip_block); 2343 2335 break; 2344 2336 case IP_VERSION(15, 0, 0): 2337 + case IP_VERSION(15, 0, 8): 2345 2338 amdgpu_device_ip_block_add(adev, &smu_v15_0_ip_block); 2346 2339 break; 2347 2340 default:
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h
··· 46 46 47 47 int amdgpu_discovery_get_nps_info(struct amdgpu_device *adev, 48 48 uint32_t *nps_type, 49 - struct amdgpu_gmc_memrange **ranges, 49 + struct amdgpu_gmc_memrange *ranges, 50 50 int *range_cnt, bool refresh); 51 51 52 52 void amdgpu_discovery_dump(struct amdgpu_device *adev, struct drm_printer *p);
+15 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c
··· 64 64 container_of(evf_mgr, struct amdgpu_fpriv, evf_mgr); 65 65 struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr; 66 66 struct dma_fence *ev_fence; 67 + bool cookie; 67 68 68 69 mutex_lock(&uq_mgr->userq_mutex); 70 + 71 + /* 72 + * This is intentionally after taking the userq_mutex since we do 73 + * allocate memory while holding this lock, but only after ensuring that 74 + * the eviction fence is signaled. 75 + */ 76 + cookie = dma_fence_begin_signalling(); 77 + 69 78 ev_fence = amdgpu_evf_mgr_get_fence(evf_mgr); 70 - amdgpu_userq_evict(uq_mgr, !evf_mgr->shutdown); 79 + amdgpu_userq_evict(uq_mgr); 71 80 72 81 /* 73 82 * Signaling the eviction fence must be done while holding the ··· 84 75 * next fence. 85 76 */ 86 77 dma_fence_signal(ev_fence); 78 + dma_fence_end_signalling(cookie); 87 79 dma_fence_put(ev_fence); 80 + 81 + if (!evf_mgr->shutdown) 82 + schedule_delayed_work(&uq_mgr->resume_work, 0); 83 + 88 84 mutex_unlock(&uq_mgr->userq_mutex); 89 85 } 90 86
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
··· 438 438 * @ring: ring to init the fence driver on 439 439 * 440 440 * Init the fence driver for the requested ring (all asics). 441 - * Helper function for amdgpu_fence_driver_init(). 441 + * Helper function for amdgpu_fence_driver_sw_init(). 442 442 */ 443 443 int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring) 444 444 {
+40 -43
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
··· 30 30 #include <linux/pagemap.h> 31 31 #include <linux/pci.h> 32 32 #include <linux/dma-buf.h> 33 + #include <linux/dma-fence-unwrap.h> 33 34 34 35 #include <drm/amdgpu_drm.h> 35 36 #include <drm/drm_drv.h> ··· 107 106 *chain = dma_fence_chain_alloc(); 108 107 if (!*chain) { 109 108 drm_syncobj_put(*syncobj); 109 + *syncobj = NULL; 110 110 return -ENOMEM; 111 111 } 112 112 ··· 743 741 struct dma_fence *fence; 744 742 int r = 0; 745 743 746 - /* Always start from the VM's existing last update fence. */ 747 - fence = dma_fence_get(vm->last_update); 748 - 744 + /* If the VM is not ready return only a stub. */ 749 745 if (!amdgpu_vm_ready(vm)) 750 - return fence; 746 + return dma_fence_get_stub(); 747 + 751 748 752 749 /* 753 750 * First clean up any freed mappings in the VM. ··· 755 754 * schedules GPU work. If nothing needs clearing, @fence can remain as 756 755 * the original vm->last_update. 757 756 */ 758 - r = amdgpu_vm_clear_freed(adev, vm, &fence); 757 + r = amdgpu_vm_clear_freed(adev, vm, &vm->last_update); 759 758 if (r) 760 759 goto error; 761 760 ··· 772 771 if (r) 773 772 goto error; 774 773 775 - /* 776 - * Decide which fence best represents the last update: 777 - * 778 - * MAP/REPLACE: 779 - * - For always-valid mappings, use vm->last_update. 780 - * - Otherwise, export bo_va->last_pt_update. 781 - * 782 - * UNMAP/CLEAR: 783 - * Keep the fence returned by amdgpu_vm_clear_freed(). If no work was 784 - * needed, it can remain as vm->last_pt_update. 785 - * 786 - * The VM and BO update fences are always initialized to a valid value. 787 - * vm->last_update and bo_va->last_pt_update always start as valid fences. 788 - * and are never expected to be NULL. 789 - */ 790 - switch (operation) { 791 - case AMDGPU_VA_OP_MAP: 792 - case AMDGPU_VA_OP_REPLACE: 793 - /* 794 - * For MAP/REPLACE, return the page table update fence for the 795 - * mapping we just modified. bo_va is expected to be valid here. 796 - */ 797 - dma_fence_put(fence); 774 + if ((operation == AMDGPU_VA_OP_MAP || 775 + operation == AMDGPU_VA_OP_REPLACE) && 776 + !amdgpu_vm_is_bo_always_valid(vm, bo_va->base.bo)) { 798 777 799 - if (amdgpu_vm_is_bo_always_valid(vm, bo_va->base.bo)) 800 - fence = dma_fence_get(vm->last_update); 801 - else 802 - fence = dma_fence_get(bo_va->last_pt_update); 803 - break; 804 - case AMDGPU_VA_OP_UNMAP: 805 - case AMDGPU_VA_OP_CLEAR: 806 - default: 807 - /* keep @fence as returned by amdgpu_vm_clear_freed() */ 808 - break; 778 + /* 779 + * For MAP/REPLACE of non per-VM BOs we need to sync to both the 780 + * bo_va->last_pt_update and vm->last_update or otherwise we 781 + * potentially miss the PDE updates. 782 + */ 783 + fence = dma_fence_unwrap_merge(vm->last_update, 784 + bo_va->last_pt_update); 785 + if (!fence) { 786 + /* As fallback in OOM situations */ 787 + dma_fence_wait(vm->last_update, false); 788 + dma_fence_wait(bo_va->last_pt_update, false); 789 + fence = dma_fence_get_stub(); 790 + } 791 + } else { 792 + fence = dma_fence_get(vm->last_update); 809 793 } 794 + 795 + return fence; 810 796 811 797 error: 812 798 if (r && r != -ERESTARTSYS) 813 799 DRM_ERROR("Couldn't update BO_VA (%d)\n", r); 814 800 815 - return fence; 801 + return dma_fence_get(vm->last_update); 816 802 } 817 803 818 804 int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, ··· 820 832 struct amdgpu_bo_va *bo_va; 821 833 struct drm_syncobj *timeline_syncobj = NULL; 822 834 struct dma_fence_chain *timeline_chain = NULL; 823 - struct dma_fence *fence; 824 835 struct drm_exec exec; 825 836 uint64_t vm_size; 826 837 int r = 0; ··· 870 883 args->operation); 871 884 return -EINVAL; 872 885 } 886 + 887 + if (args->flags & AMDGPU_VM_DELAY_UPDATE && 888 + args->vm_timeline_syncobj_out) 889 + return -EINVAL; 873 890 874 891 if ((args->operation != AMDGPU_VA_OP_CLEAR) && 875 892 !(args->flags & AMDGPU_VM_PAGE_PRT)) { ··· 964 973 * that represents the last relevant update for this mapping. This 965 974 * fence can then be exported to the user-visible VM timeline. 966 975 */ 967 - if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) && !adev->debug_vm) { 976 + if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) && 977 + (!adev->debug_vm || timeline_syncobj)) { 978 + struct dma_fence *fence; 979 + 968 980 fence = amdgpu_gem_va_update_vm(adev, &fpriv->vm, bo_va, 969 981 args->operation); 970 - 971 - if (timeline_syncobj && fence) { 982 + if (timeline_syncobj) { 972 983 if (!args->vm_timeline_point) { 973 984 /* Replace the existing fence when no point is given. */ 974 985 drm_syncobj_replace_fence(timeline_syncobj, ··· 981 988 timeline_chain, 982 989 fence, 983 990 args->vm_timeline_point); 991 + timeline_chain = NULL; 984 992 } 985 993 } 986 994 dma_fence_put(fence); ··· 989 995 } 990 996 991 997 error: 998 + dma_fence_chain_free(timeline_chain); 999 + if (timeline_syncobj) 1000 + drm_syncobj_put(timeline_syncobj); 992 1001 drm_exec_fini(&exec); 993 1002 error_put_gobj: 994 1003 drm_gem_object_put(gobj);
+4 -6
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
··· 1374 1374 struct amdgpu_mem_partition_info *mem_ranges, 1375 1375 uint8_t *exp_ranges) 1376 1376 { 1377 - struct amdgpu_gmc_memrange *ranges; 1377 + struct amdgpu_gmc_memrange ranges[AMDGPU_MAX_MEM_RANGES]; 1378 1378 int range_cnt, ret, i, j; 1379 1379 uint32_t nps_type; 1380 1380 bool refresh; 1381 1381 1382 1382 if (!mem_ranges || !exp_ranges) 1383 1383 return -EINVAL; 1384 - 1384 + range_cnt = AMDGPU_MAX_MEM_RANGES; 1385 1385 refresh = (adev->init_lvl->level != AMDGPU_INIT_LEVEL_MINIMAL_XGMI) && 1386 1386 (adev->gmc.reset_flags & AMDGPU_GMC_INIT_RESET_NPS); 1387 - ret = amdgpu_discovery_get_nps_info(adev, &nps_type, &ranges, 1388 - &range_cnt, refresh); 1387 + ret = amdgpu_discovery_get_nps_info(adev, &nps_type, ranges, &range_cnt, 1388 + refresh); 1389 1389 1390 1390 if (ret) 1391 1391 return ret; ··· 1446 1446 if (!*exp_ranges) 1447 1447 *exp_ranges = range_cnt; 1448 1448 err: 1449 - kvfree(ranges); 1450 - 1451 1449 return ret; 1452 1450 } 1453 1451
+32 -13
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
··· 35 35 * PASIDs are global address space identifiers that can be shared 36 36 * between the GPU, an IOMMU and the driver. VMs on different devices 37 37 * may use the same PASID if they share the same address 38 - * space. Therefore PASIDs are allocated using a global IDA. VMs are 39 - * looked up from the PASID per amdgpu_device. 38 + * space. Therefore PASIDs are allocated using IDR cyclic allocator 39 + * (similar to kernel PID allocation) which naturally delays reuse. 40 + * VMs are looked up from the PASID per amdgpu_device. 40 41 */ 41 - static DEFINE_IDA(amdgpu_pasid_ida); 42 + 43 + static DEFINE_IDR(amdgpu_pasid_idr); 44 + static DEFINE_SPINLOCK(amdgpu_pasid_idr_lock); 42 45 43 46 /* Helper to free pasid from a fence callback */ 44 47 struct amdgpu_pasid_cb { ··· 53 50 * amdgpu_pasid_alloc - Allocate a PASID 54 51 * @bits: Maximum width of the PASID in bits, must be at least 1 55 52 * 56 - * Allocates a PASID of the given width while keeping smaller PASIDs 57 - * available if possible. 53 + * Uses kernel's IDR cyclic allocator (same as PID allocation). 54 + * Allocates sequentially with automatic wrap-around. 58 55 * 59 56 * Returns a positive integer on success. Returns %-EINVAL if bits==0. 60 57 * Returns %-ENOSPC if no PASID was available. Returns %-ENOMEM on ··· 62 59 */ 63 60 int amdgpu_pasid_alloc(unsigned int bits) 64 61 { 65 - int pasid = -EINVAL; 62 + int pasid; 66 63 67 - for (bits = min(bits, 31U); bits > 0; bits--) { 68 - pasid = ida_alloc_range(&amdgpu_pasid_ida, 1U << (bits - 1), 69 - (1U << bits) - 1, GFP_KERNEL); 70 - if (pasid != -ENOSPC) 71 - break; 72 - } 64 + if (bits == 0) 65 + return -EINVAL; 66 + 67 + spin_lock(&amdgpu_pasid_idr_lock); 68 + pasid = idr_alloc_cyclic(&amdgpu_pasid_idr, NULL, 1, 69 + 1U << bits, GFP_KERNEL); 70 + spin_unlock(&amdgpu_pasid_idr_lock); 73 71 74 72 if (pasid >= 0) 75 73 trace_amdgpu_pasid_allocated(pasid); ··· 85 81 void amdgpu_pasid_free(u32 pasid) 86 82 { 87 83 trace_amdgpu_pasid_freed(pasid); 88 - ida_free(&amdgpu_pasid_ida, pasid); 84 + 85 + spin_lock(&amdgpu_pasid_idr_lock); 86 + idr_remove(&amdgpu_pasid_idr, pasid); 87 + spin_unlock(&amdgpu_pasid_idr_lock); 89 88 } 90 89 91 90 static void amdgpu_pasid_free_cb(struct dma_fence *fence, ··· 622 615 dma_fence_put(id->pasid_mapping); 623 616 } 624 617 } 618 + } 619 + 620 + /** 621 + * amdgpu_pasid_mgr_cleanup - cleanup PASID manager 622 + * 623 + * Cleanup the IDR allocator. 624 + */ 625 + void amdgpu_pasid_mgr_cleanup(void) 626 + { 627 + spin_lock(&amdgpu_pasid_idr_lock); 628 + idr_destroy(&amdgpu_pasid_idr); 629 + spin_unlock(&amdgpu_pasid_idr_lock); 625 630 }
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h
··· 74 74 void amdgpu_pasid_free(u32 pasid); 75 75 void amdgpu_pasid_free_delayed(struct dma_resv *resv, 76 76 u32 pasid); 77 + void amdgpu_pasid_mgr_cleanup(void); 77 78 78 79 bool amdgpu_vmid_had_gpu_reset(struct amdgpu_device *adev, 79 80 struct amdgpu_vmid *id);
+1 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
··· 103 103 return -EINVAL; 104 104 } 105 105 106 - if (!amdgpu_ctx_priority_is_valid(args->in.priority)) { 107 - WARN(1, "Invalid context priority %d\n", args->in.priority); 106 + if (!amdgpu_ctx_priority_is_valid(args->in.priority)) 108 107 return -EINVAL; 109 - } 110 108 111 109 switch (args->in.op) { 112 110 case AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE:
+5 -24
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
··· 999 999 1000 1000 /* Resume all the queues for this process */ 1001 1001 xa_for_each(&uq_mgr->userq_xa, queue_id, queue) { 1002 - queue = amdgpu_userq_get(uq_mgr, queue_id); 1003 - if (!queue) 1004 - continue; 1005 1002 1006 1003 if (!amdgpu_userq_buffer_vas_mapped(queue)) { 1007 1004 drm_file_err(uq_mgr->file, 1008 1005 "trying restore queue without va mapping\n"); 1009 1006 queue->state = AMDGPU_USERQ_STATE_INVALID_VA; 1010 - amdgpu_userq_put(queue); 1011 1007 continue; 1012 1008 } 1013 1009 ··· 1011 1015 if (r) 1012 1016 ret = r; 1013 1017 1014 - amdgpu_userq_put(queue); 1015 1018 } 1016 1019 1017 1020 if (ret) ··· 1227 1232 } 1228 1233 1229 1234 ret = amdgpu_userq_restore_all(uq_mgr); 1230 - if (ret) { 1235 + if (ret) 1231 1236 drm_file_err(uq_mgr->file, "Failed to restore all queues\n"); 1232 - goto unlock; 1233 - } 1234 1237 1235 1238 unlock: 1236 1239 mutex_unlock(&uq_mgr->userq_mutex); ··· 1245 1252 amdgpu_userq_detect_and_reset_queues(uq_mgr); 1246 1253 /* Try to unmap all the queues in this process ctx */ 1247 1254 xa_for_each(&uq_mgr->userq_xa, queue_id, queue) { 1248 - queue = amdgpu_userq_get(uq_mgr, queue_id); 1249 - if (!queue) 1250 - continue; 1251 1255 r = amdgpu_userq_preempt_helper(queue); 1252 1256 if (r) 1253 1257 ret = r; 1254 - amdgpu_userq_put(queue); 1255 1258 } 1256 1259 1257 1260 if (ret) ··· 1280 1291 int ret; 1281 1292 1282 1293 xa_for_each(&uq_mgr->userq_xa, queue_id, queue) { 1283 - queue = amdgpu_userq_get(uq_mgr, queue_id); 1284 - if (!queue) 1285 - continue; 1286 - 1287 1294 struct dma_fence *f = queue->last_fence; 1288 1295 1289 - if (!f || dma_fence_is_signaled(f)) { 1290 - amdgpu_userq_put(queue); 1296 + if (!f || dma_fence_is_signaled(f)) 1291 1297 continue; 1292 - } 1298 + 1293 1299 ret = dma_fence_wait_timeout(f, true, msecs_to_jiffies(100)); 1294 1300 if (ret <= 0) { 1295 1301 drm_file_err(uq_mgr->file, "Timed out waiting for fence=%llu:%llu\n", 1296 1302 f->context, f->seqno); 1297 - amdgpu_userq_put(queue); 1303 + 1298 1304 return -ETIMEDOUT; 1299 1305 } 1300 - amdgpu_userq_put(queue); 1301 1306 } 1302 1307 1303 1308 return 0; 1304 1309 } 1305 1310 1306 1311 void 1307 - amdgpu_userq_evict(struct amdgpu_userq_mgr *uq_mgr, bool schedule_resume) 1312 + amdgpu_userq_evict(struct amdgpu_userq_mgr *uq_mgr) 1308 1313 { 1309 1314 struct amdgpu_device *adev = uq_mgr->adev; 1310 1315 int ret; ··· 1312 1329 if (ret) 1313 1330 dev_err(adev->dev, "Failed to evict userqueue\n"); 1314 1331 1315 - if (schedule_resume) 1316 - schedule_delayed_work(&uq_mgr->resume_work, 0); 1317 1332 } 1318 1333 1319 1334 int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct drm_file *file_priv,
+1 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
··· 133 133 void amdgpu_userq_destroy_object(struct amdgpu_userq_mgr *uq_mgr, 134 134 struct amdgpu_userq_obj *userq_obj); 135 135 136 - void amdgpu_userq_evict(struct amdgpu_userq_mgr *uq_mgr, 137 - bool schedule_resume); 136 + void amdgpu_userq_evict(struct amdgpu_userq_mgr *uq_mgr); 138 137 139 138 void amdgpu_userq_ensure_ev_fence(struct amdgpu_userq_mgr *userq_mgr, 140 139 struct amdgpu_eviction_fence_mgr *evf_mgr);
+29 -23
drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
··· 705 705 num_fences++; 706 706 } 707 707 708 - wait_info->num_fences = num_fences; 708 + wait_info->num_fences = min(num_fences, USHRT_MAX); 709 709 r = 0; 710 710 711 711 error_unlock: 712 712 /* Unlock all the GEM objects */ 713 713 drm_exec_fini(&exec); 714 714 return r; 715 + } 716 + 717 + static int 718 + amdgpu_userq_wait_add_fence(struct drm_amdgpu_userq_wait *wait_info, 719 + struct dma_fence **fences, unsigned int *num_fences, 720 + struct dma_fence *fence) 721 + { 722 + /* As fallback shouldn't userspace allocate enough space */ 723 + if (*num_fences >= wait_info->num_fences) 724 + return dma_fence_wait(fence, true); 725 + 726 + fences[(*num_fences)++] = dma_fence_get(fence); 727 + return 0; 715 728 } 716 729 717 730 static int ··· 770 757 goto free_fences; 771 758 772 759 dma_fence_unwrap_for_each(f, &iter, fence) { 773 - if (num_fences >= wait_info->num_fences) { 774 - r = -EINVAL; 760 + r = amdgpu_userq_wait_add_fence(wait_info, fences, 761 + &num_fences, f); 762 + if (r) { 775 763 dma_fence_put(fence); 776 764 goto free_fences; 777 765 } 778 - 779 - fences[num_fences++] = dma_fence_get(f); 780 766 } 781 767 782 768 dma_fence_put(fence); ··· 792 780 if (r) 793 781 goto free_fences; 794 782 795 - if (num_fences >= wait_info->num_fences) { 796 - dma_fence_put(fence); 797 - r = -EINVAL; 783 + r = amdgpu_userq_wait_add_fence(wait_info, fences, 784 + &num_fences, fence); 785 + dma_fence_put(fence); 786 + if (r) 798 787 goto free_fences; 799 - } 800 788 801 - /* Give the reference to the fence array */ 802 - fences[num_fences++] = fence; 803 789 } 804 790 805 791 /* Lock all the GEM objects */ ··· 827 817 828 818 dma_resv_for_each_fence(&resv_cursor, gobj_read[i]->resv, 829 819 DMA_RESV_USAGE_READ, fence) { 830 - if (num_fences >= wait_info->num_fences) { 831 - r = -EINVAL; 820 + r = amdgpu_userq_wait_add_fence(wait_info, fences, 821 + &num_fences, fence); 822 + if (r) 832 823 goto error_unlock; 833 - } 834 - 835 - fences[num_fences++] = dma_fence_get(fence); 836 824 } 837 825 } 838 826 ··· 841 833 842 834 dma_resv_for_each_fence(&resv_cursor, gobj_write[i]->resv, 843 835 DMA_RESV_USAGE_WRITE, fence) { 844 - if (num_fences >= wait_info->num_fences) { 845 - r = -EINVAL; 836 + r = amdgpu_userq_wait_add_fence(wait_info, fences, 837 + &num_fences, fence); 838 + if (r) 846 839 goto error_unlock; 847 - } 848 - 849 - fences[num_fences++] = dma_fence_get(fence); 850 840 } 851 841 } 852 842 ··· 967 961 } 968 962 969 963 num_read_bo_handles = wait_info->num_bo_read_handles; 970 - ptr = u64_to_user_ptr(wait_info->bo_read_handles), 964 + ptr = u64_to_user_ptr(wait_info->bo_read_handles); 971 965 r = drm_gem_objects_lookup(filp, ptr, num_read_bo_handles, &gobj_read); 972 966 if (r) 973 967 goto free_timeline_points; 974 968 975 969 num_write_bo_handles = wait_info->num_bo_write_handles; 976 - ptr = u64_to_user_ptr(wait_info->bo_write_handles), 970 + ptr = u64_to_user_ptr(wait_info->bo_write_handles); 977 971 r = drm_gem_objects_lookup(filp, ptr, num_write_bo_handles, 978 972 &gobj_write); 979 973 if (r)
+4 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 2916 2916 xa_destroy(&adev->vm_manager.pasids); 2917 2917 2918 2918 amdgpu_vmid_mgr_fini(adev); 2919 + amdgpu_pasid_mgr_cleanup(); 2919 2920 } 2920 2921 2921 2922 /** ··· 2992 2991 if (!root) 2993 2992 return false; 2994 2993 2995 - addr /= AMDGPU_GPU_PAGE_SIZE; 2996 - 2997 2994 if (is_compute_context && !svm_range_restore_pages(adev, pasid, vmid, 2998 - node_id, addr, ts, write_fault)) { 2995 + node_id, addr >> PAGE_SHIFT, ts, write_fault)) { 2999 2996 amdgpu_bo_unref(&root); 3000 2997 return true; 3001 2998 } 2999 + 3000 + addr /= AMDGPU_GPU_PAGE_SIZE; 3002 3001 3003 3002 r = amdgpu_bo_reserve(root, true); 3004 3003 if (r)
+1 -1
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
··· 6752 6752 /* set up default queue priority level 6753 6753 * 0x0 = low priority, 0x1 = high priority 6754 6754 */ 6755 - if (prop->hqd_pipe_priority == AMDGPU_GFX_PIPE_PRIO_HIGH) 6755 + if (prop->hqd_queue_priority == AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM) 6756 6756 priority = 1; 6757 6757 6758 6758 tmp = RREG32_SOC15(GC, 0, mmCP_GFX_HQD_QUEUE_PRIORITY);
+1 -1
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
··· 4088 4088 /* set up default queue priority level 4089 4089 * 0x0 = low priority, 0x1 = high priority 4090 4090 */ 4091 - if (prop->hqd_pipe_priority == AMDGPU_GFX_PIPE_PRIO_HIGH) 4091 + if (prop->hqd_queue_priority == AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM) 4092 4092 priority = 1; 4093 4093 4094 4094 tmp = regCP_GFX_HQD_QUEUE_PRIORITY_DEFAULT;
+1 -1
drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
··· 2227 2227 struct amdgpu_bo *meta_bo = NULL, *ctx_bo = NULL; 2228 2228 void *meta_ptr = NULL, *ctx_ptr = NULL; 2229 2229 u64 meta_gpu_addr, ctx_gpu_addr; 2230 - int size, i, r, pasid;; 2230 + int size, i, r, pasid; 2231 2231 2232 2232 pasid = amdgpu_pasid_alloc(16); 2233 2233 if (pasid < 0)
+18 -1
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
··· 134 134 return 0; 135 135 } 136 136 137 + static bool vcn_v4_0_3_is_psp_fw_reset_supported(struct amdgpu_device *adev) 138 + { 139 + uint32_t fw_ver = adev->psp.sos.fw_version; 140 + uint32_t pgm = (fw_ver >> 8) & 0xFF; 141 + 142 + /* 143 + * FWDEV-159155: PSP SOS FW must be >= 0x0036015f for program 0x01 144 + * before enabling VCN per-queue reset. 145 + */ 146 + if (pgm == 1) 147 + return fw_ver >= 0x0036015f; 148 + 149 + return true; 150 + } 151 + 137 152 static int vcn_v4_0_3_late_init(struct amdgpu_ip_block *ip_block) 138 153 { 139 154 struct amdgpu_device *adev = ip_block->adev; ··· 156 141 adev->vcn.supported_reset = 157 142 amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]); 158 143 159 - if (amdgpu_dpm_reset_vcn_is_supported(adev) && !amdgpu_sriov_vf(adev)) 144 + if (amdgpu_dpm_reset_vcn_is_supported(adev) && 145 + vcn_v4_0_3_is_psp_fw_reset_supported(adev) && 146 + !amdgpu_sriov_vf(adev)) 160 147 adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; 161 148 162 149 return 0;
+3 -3
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
··· 3170 3170 struct kfd_process *process; 3171 3171 int ret; 3172 3172 3173 - /* Each FD owns only one kfd_process */ 3174 - if (p->context_id != KFD_CONTEXT_ID_PRIMARY) 3173 + if (!filep->private_data || !p) 3175 3174 return -EINVAL; 3176 3175 3177 - if (!filep->private_data || !p) 3176 + /* Each FD owns only one kfd_process */ 3177 + if (p->context_id != KFD_CONTEXT_ID_PRIMARY) 3178 3178 return -EINVAL; 3179 3179 3180 3180 mutex_lock(&kfd_processes_mutex);
+16 -8
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 3994 3994 3995 3995 aconnector->dc_sink = sink; 3996 3996 dc_sink_retain(aconnector->dc_sink); 3997 + drm_edid_free(aconnector->drm_edid); 3998 + aconnector->drm_edid = NULL; 3997 3999 if (sink->dc_edid.length == 0) { 3998 - aconnector->drm_edid = NULL; 3999 4000 hdmi_cec_unset_edid(aconnector); 4000 4001 if (aconnector->dc_link->aux_mode) { 4001 4002 drm_dp_cec_unset_edid(&aconnector->dm_dp_aux.aux); ··· 5418 5417 caps = &dm->backlight_caps[aconnector->bl_idx]; 5419 5418 5420 5419 /* Only offer ABM property when non-OLED and user didn't turn off by module parameter */ 5421 - if (!caps->ext_caps->bits.oled && amdgpu_dm_abm_level < 0) 5420 + if (caps->ext_caps && !caps->ext_caps->bits.oled && amdgpu_dm_abm_level < 0) 5422 5421 drm_object_attach_property(&aconnector->base.base, 5423 5422 dm->adev->mode_info.abm_level_property, 5424 5423 ABM_SYSFS_CONTROL); ··· 9886 9885 } 9887 9886 9888 9887 /* Decrement skip count when SR is enabled and we're doing fast updates. */ 9889 - if (acrtc_state->update_type == UPDATE_TYPE_FAST && 9888 + if (acrtc_state->update_type <= UPDATE_TYPE_FAST && 9890 9889 (psr->psr_feature_enabled || pr->config.replay_supported)) { 9891 9890 if (aconn->sr_skip_count > 0) 9892 9891 aconn->sr_skip_count--; ··· 9899 9898 * a vblank event disable request to enable PSR/RP. PSR SU/RP 9900 9899 * can be enabled immediately once OS demonstrates an 9901 9900 * adequate number of fast atomic commits to notify KMD 9902 - * of update events. See `vblank_control_worker()`. 9901 + * of update events. 9902 + * See `amdgpu_dm_crtc_vblank_control_worker()`. 9903 9903 */ 9904 9904 if (!vrr_active && 9905 9905 acrtc_attach->dm_irq_params.allow_sr_entry && ··· 10068 10066 /* 10069 10067 * If the dirty regions changed, PSR-SU need to be disabled temporarily 10070 10068 * and enabled it again after dirty regions are stable to avoid video glitch. 10071 - * PSR-SU will be enabled in vblank_control_worker() if user pause the video 10072 - * during the PSR-SU was disabled. 10069 + * PSR-SU will be enabled in 10070 + * amdgpu_dm_crtc_vblank_control_worker() if user 10071 + * pause the video during the PSR-SU was disabled. 10073 10072 */ 10074 10073 if (acrtc_state->stream->link->psr_settings.psr_version >= DC_PSR_VERSION_SU_1 && 10075 10074 acrtc_attach->dm_irq_params.allow_sr_entry && ··· 10096 10093 * fast updates. 10097 10094 */ 10098 10095 if (crtc->state->async_flip && 10099 - (acrtc_state->update_type != UPDATE_TYPE_FAST || 10096 + (acrtc_state->update_type > UPDATE_TYPE_FAST || 10100 10097 get_mem_type(old_plane_state->fb) != get_mem_type(fb))) 10101 10098 drm_warn_once(state->dev, 10102 10099 "[PLANE:%d:%s] async flip with non-fast update\n", ··· 10104 10101 10105 10102 bundle->flip_addrs[planes_count].flip_immediate = 10106 10103 crtc->state->async_flip && 10107 - acrtc_state->update_type == UPDATE_TYPE_FAST && 10104 + acrtc_state->update_type <= UPDATE_TYPE_FAST && 10108 10105 get_mem_type(old_plane_state->fb) == get_mem_type(fb); 10109 10106 10110 10107 timestamp_ns = ktime_get_ns(); ··· 12531 12528 } 12532 12529 12533 12530 if (dc_resource_is_dsc_encoding_supported(dc)) { 12531 + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { 12532 + dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); 12533 + dm_new_crtc_state->mode_changed_independent_from_dsc = new_crtc_state->mode_changed; 12534 + } 12535 + 12534 12536 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { 12535 12537 if (drm_atomic_crtc_needs_modeset(new_crtc_state)) { 12536 12538 ret = add_affected_mst_dsc_crtcs(state, crtc);
+1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
··· 1005 1005 1006 1006 bool freesync_vrr_info_changed; 1007 1007 1008 + bool mode_changed_independent_from_dsc; 1008 1009 bool dsc_force_changed; 1009 1010 bool vrr_supported; 1010 1011 struct mod_freesync_config freesync_config;
-7
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
··· 812 812 unsigned long flags1; 813 813 bool forward_roi_change = false; 814 814 bool notify_ta = false; 815 - bool all_crc_ready = true; 816 815 struct dc_stream_state *stream_state; 817 816 int i; 818 817 ··· 935 936 continue; 936 937 } 937 938 938 - if (!crtc_ctx->crc_info.crc[i].crc_ready) 939 - all_crc_ready = false; 940 - 941 939 if (reset_crc_frame_count[i] || crtc_ctx->crc_info.crc[i].frame_count == UINT_MAX) 942 940 /* Reset the reference frame count after user update the ROI 943 941 * or it reaches the maximum value. ··· 944 948 crtc_ctx->crc_info.crc[i].frame_count += 1; 945 949 } 946 950 spin_unlock_irqrestore(&crtc_ctx->crc_info.lock, flags1); 947 - 948 - if (all_crc_ready) 949 - complete_all(&crtc_ctx->crc_info.completion); 950 951 } 951 952 952 953 void amdgpu_dm_crtc_secure_display_create_contexts(struct amdgpu_device *adev)
-1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
··· 70 70 71 71 struct crc_info { 72 72 struct crc_data crc[MAX_CRC_WINDOW_NUM]; 73 - struct completion completion; 74 73 spinlock_t lock; 75 74 }; 76 75
+1 -1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
··· 685 685 * pitch, the DCC state, rotation, etc. 686 686 */ 687 687 if (crtc_state->async_flip && 688 - dm_crtc_state->update_type != UPDATE_TYPE_FAST) { 688 + dm_crtc_state->update_type > UPDATE_TYPE_FAST) { 689 689 drm_dbg_atomic(crtc->dev, 690 690 "[CRTC:%d:%s] async flips are only supported for fast updates\n", 691 691 crtc->base.id, crtc->name);
+3 -1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
··· 1744 1744 int ind = find_crtc_index_in_state_by_stream(state, stream); 1745 1745 1746 1746 if (ind >= 0) { 1747 + struct dm_crtc_state *dm_new_crtc_state = to_dm_crtc_state(state->crtcs[ind].new_state); 1748 + 1747 1749 DRM_INFO_ONCE("%s:%d MST_DSC no mode changed for stream 0x%p\n", 1748 1750 __func__, __LINE__, stream); 1749 - state->crtcs[ind].new_state->mode_changed = 0; 1751 + dm_new_crtc_state->base.mode_changed = dm_new_crtc_state->mode_changed_independent_from_dsc; 1750 1752 } 1751 1753 } 1752 1754 }
+137 -126
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c
··· 291 291 if (should_set_clock(safe_to_lower, 292 292 new_clocks->dcfclk_deep_sleep_khz, clk_mgr_base->clks.dcfclk_deep_sleep_khz)) { 293 293 clk_mgr_base->clks.dcfclk_deep_sleep_khz = new_clocks->dcfclk_deep_sleep_khz; 294 + 295 + /* Clamp the requested clock to PMFW based on DCN limit. */ 296 + if (dc->debug.min_deep_sleep_dcfclk_khz > 0 && clk_mgr_base->clks.dcfclk_deep_sleep_khz < dc->debug.min_deep_sleep_dcfclk_khz) 297 + clk_mgr_base->clks.dcfclk_deep_sleep_khz = dc->debug.min_deep_sleep_dcfclk_khz; 298 + 294 299 dcn42_smu_set_min_deep_sleep_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_deep_sleep_khz); 295 300 } 296 301 ··· 474 469 DC_LOG_SMU("CLK1_CLK1_CURRENT_CNT,%d,dppclk\n", 475 470 internal.CLK8_CLK1_CURRENT_CNT); 476 471 472 + DC_LOG_SMU("CLK1_CLK4_CURRENT_CNT,%d,dtbclk\n", 473 + internal.CLK8_CLK4_CURRENT_CNT); 474 + 477 475 DC_LOG_SMU("CLK1_CLK3_BYPASS_CNTL,%d,dcfclk_bypass\n", 478 476 internal.CLK8_CLK3_BYPASS_CNTL); 479 477 ··· 577 569 { 578 570 struct clk_mgr_internal *clk_mgr_int = TO_CLK_MGR_INTERNAL(clk_mgr_base); 579 571 struct clk_mgr_dcn42 *clk_mgr = TO_CLK_MGR_DCN42(clk_mgr_int); 580 - struct dcn42_smu_dpm_clks smu_dpm_clks = { 0 }; 581 572 582 573 DC_LOGGER_INIT(clk_mgr_base->ctx->logger); 583 574 (void)dc_logger; ··· 594 587 dcn42_dump_clk_registers(&clk_mgr_base->boot_snapshot, clk_mgr); 595 588 596 589 clk_mgr_base->clks.ref_dtbclk_khz = clk_mgr_base->boot_snapshot.dtbclk * 10; 597 - if (clk_mgr_base->boot_snapshot.dtbclk > 59000) { 598 - /*dtbclk enabled based on*/ 599 - clk_mgr_base->clks.dtbclk_en = true; 600 - } 601 - 602 - if (clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dcfclk_levels != 0) { 603 - /*skip to get clock table and notify pmfw watermark range again*/ 604 - DC_LOG_SMU("skip to get dpm_clks from pmfw from resume and acr\n"); 605 - return; 606 - } 607 - 608 - smu_dpm_clks.dpm_clks = (DpmClocks_t_dcn42 *)dm_helpers_allocate_gpu_mem( 609 - clk_mgr_base->ctx, 610 - DC_MEM_ALLOC_TYPE_GART, 611 - sizeof(DpmClocks_t_dcn42), 612 - &smu_dpm_clks.mc_address.quad_part); 613 - 614 - ASSERT(smu_dpm_clks.dpm_clks); 615 - if (clk_mgr_base->ctx->dc->debug.pstate_enabled && clk_mgr_int->smu_present && smu_dpm_clks.mc_address.quad_part != 0) { 616 - int i; 617 - DpmClocks_t_dcn42 *dpm_clks = smu_dpm_clks.dpm_clks; 618 - 619 - dcn42_get_dpm_table_from_smu(clk_mgr_int, &smu_dpm_clks); 620 - DC_LOG_SMU("NumDcfClkLevelsEnabled: %d\n" 621 - "NumDispClkLevelsEnabled: %d\n" 622 - "NumSocClkLevelsEnabled: %d\n" 623 - "VcnClkLevelsEnabled: %d\n" 624 - "FClkLevelsEnabled: %d\n" 625 - "NumMemPstatesEnabled: %d\n" 626 - "MinGfxClk: %d\n" 627 - "MaxGfxClk: %d\n", 628 - dpm_clks->NumDcfClkLevelsEnabled, 629 - dpm_clks->NumDispClkLevelsEnabled, 630 - dpm_clks->NumSocClkLevelsEnabled, 631 - dpm_clks->VcnClkLevelsEnabled, 632 - dpm_clks->NumFclkLevelsEnabled, 633 - dpm_clks->NumMemPstatesEnabled, 634 - dpm_clks->MinGfxClk, 635 - dpm_clks->MaxGfxClk); 636 - 637 - for (i = 0; i < NUM_DCFCLK_DPM_LEVELS; i++) { 638 - DC_LOG_SMU("dpm_clks->DcfClocks[%d] = %d\n", 639 - i, 640 - dpm_clks->DcfClocks[i]); 641 - } 642 - for (i = 0; i < NUM_DISPCLK_DPM_LEVELS; i++) { 643 - DC_LOG_SMU("dpm_clks->DispClocks[%d] = %d\n", 644 - i, dpm_clks->DispClocks[i]); 645 - } 646 - for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++) { 647 - DC_LOG_SMU("dpm_clks->SocClocks[%d] = %d\n", 648 - i, dpm_clks->SocClocks[i]); 649 - } 650 - for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++) { 651 - DC_LOG_SMU("dpm_clks->FclkClocks_Freq[%d] = %d\n", 652 - i, dpm_clks->FclkClocks_Freq[i]); 653 - DC_LOG_SMU("dpm_clks->FclkClocks_Voltage[%d] = %d\n", 654 - i, dpm_clks->FclkClocks_Voltage[i]); 655 - } 656 - for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++) 657 - DC_LOG_SMU("dpm_clks->SocVoltage[%d] = %d\n", 658 - i, dpm_clks->SocVoltage[i]); 659 - 660 - for (i = 0; i < NUM_MEM_PSTATE_LEVELS; i++) { 661 - DC_LOG_SMU("dpm_clks.MemPstateTable[%d].UClk = %d\n" 662 - "dpm_clks->MemPstateTable[%d].MemClk= %d\n" 663 - "dpm_clks->MemPstateTable[%d].Voltage = %d\n", 664 - i, dpm_clks->MemPstateTable[i].UClk, 665 - i, dpm_clks->MemPstateTable[i].MemClk, 666 - i, dpm_clks->MemPstateTable[i].Voltage); 667 - } 668 - 669 - if (clk_mgr_base->ctx->dc_bios->integrated_info && clk_mgr_base->ctx->dc->config.use_default_clock_table == false) { 670 - /* DCFCLK */ 671 - dcn42_init_single_clock(&clk_mgr_base->bw_params->clk_table.entries[0].dcfclk_mhz, 672 - dpm_clks->DcfClocks, 673 - dpm_clks->NumDcfClkLevelsEnabled); 674 - clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dcfclk_levels = dpm_clks->NumDcfClkLevelsEnabled; 675 - 676 - /* SOCCLK */ 677 - dcn42_init_single_clock(&clk_mgr_base->bw_params->clk_table.entries[0].socclk_mhz, 678 - dpm_clks->SocClocks, 679 - dpm_clks->NumSocClkLevelsEnabled); 680 - clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_socclk_levels = dpm_clks->NumSocClkLevelsEnabled; 681 - 682 - /* DISPCLK */ 683 - dcn42_init_single_clock(&clk_mgr_base->bw_params->clk_table.entries[0].dispclk_mhz, 684 - dpm_clks->DispClocks, 685 - dpm_clks->NumDispClkLevelsEnabled); 686 - clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dispclk_levels = dpm_clks->NumDispClkLevelsEnabled; 687 - 688 - /* DPPCLK */ 689 - dcn42_init_single_clock(&clk_mgr_base->bw_params->clk_table.entries[0].dppclk_mhz, 690 - dpm_clks->DppClocks, 691 - dpm_clks->NumDispClkLevelsEnabled); 692 - clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dppclk_levels = dpm_clks->NumDispClkLevelsEnabled; 693 - 694 - /* FCLK */ 695 - dcn42_init_single_clock(&clk_mgr_base->bw_params->clk_table.entries[0].fclk_mhz, 696 - dpm_clks->FclkClocks_Freq, 697 - NUM_FCLK_DPM_LEVELS); 698 - clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_fclk_levels = dpm_clks->NumFclkLevelsEnabled; 699 - clk_mgr_base->bw_params->clk_table.num_entries = dpm_clks->NumFclkLevelsEnabled; 700 - 701 - /* Memory Pstate table is in reverse order*/ 702 - ASSERT(dpm_clks->NumMemPstatesEnabled <= NUM_MEM_PSTATE_LEVELS); 703 - if (dpm_clks->NumMemPstatesEnabled > NUM_MEM_PSTATE_LEVELS) 704 - dpm_clks->NumMemPstatesEnabled = NUM_MEM_PSTATE_LEVELS; 705 - for (i = 0; i < dpm_clks->NumMemPstatesEnabled; i++) { 706 - clk_mgr_base->bw_params->clk_table.entries[dpm_clks->NumMemPstatesEnabled - 1 - i].memclk_mhz = dpm_clks->MemPstateTable[i].UClk; 707 - clk_mgr_base->bw_params->clk_table.entries[dpm_clks->NumMemPstatesEnabled - 1 - i].wck_ratio = dcn42_convert_wck_ratio(dpm_clks->MemPstateTable[i].WckRatio) ; 708 - } 709 - clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels = dpm_clks->NumMemPstatesEnabled; 710 - 711 - /* DTBCLK*/ 712 - clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz = clk_mgr_base->clks.ref_dtbclk_khz / 1000; 713 - clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dtbclk_levels = 1; 714 - /* Refresh bounding box */ 715 - clk_mgr_base->ctx->dc->res_pool->funcs->update_bw_bounding_box( 716 - clk_mgr_base->ctx->dc, clk_mgr_base->bw_params); 717 - } 718 - } 719 - if (smu_dpm_clks.dpm_clks && smu_dpm_clks.mc_address.quad_part != 0) 720 - dm_helpers_free_gpu_mem(clk_mgr_base->ctx, DC_MEM_ALLOC_TYPE_GART, 721 - smu_dpm_clks.dpm_clks); 590 + clk_mgr_base->clks.dtbclk_en = clk_mgr_base->boot_snapshot.dtbclk > 59000; 722 591 } 723 592 724 593 static struct clk_bw_params dcn42_bw_params = { ··· 954 1071 return clk_mgr->smu_present; 955 1072 } 956 1073 1074 + static void dcn42_get_smu_clocks(struct clk_mgr_internal *clk_mgr_int) 1075 + { 1076 + struct clk_mgr *clk_mgr_base = &clk_mgr_int->base; 1077 + struct dcn42_smu_dpm_clks smu_dpm_clks = { 0 }; 1078 + 1079 + DC_LOGGER_INIT(clk_mgr_base->ctx->logger); 1080 + (void)dc_logger; 1081 + 1082 + smu_dpm_clks.dpm_clks = (DpmClocks_t_dcn42 *)dm_helpers_allocate_gpu_mem( 1083 + clk_mgr_base->ctx, 1084 + DC_MEM_ALLOC_TYPE_GART, 1085 + sizeof(DpmClocks_t_dcn42), 1086 + &smu_dpm_clks.mc_address.quad_part); 1087 + 1088 + ASSERT(smu_dpm_clks.dpm_clks); 1089 + if (clk_mgr_base->ctx->dc->debug.pstate_enabled && smu_dpm_clks.mc_address.quad_part != 0) { 1090 + int i; 1091 + DpmClocks_t_dcn42 *dpm_clks = smu_dpm_clks.dpm_clks; 1092 + 1093 + dcn42_get_dpm_table_from_smu(clk_mgr_int, &smu_dpm_clks); 1094 + DC_LOG_SMU("NumDcfClkLevelsEnabled: %d\n" 1095 + "NumDispClkLevelsEnabled: %d\n" 1096 + "NumSocClkLevelsEnabled: %d\n" 1097 + "VcnClkLevelsEnabled: %d\n" 1098 + "FClkLevelsEnabled: %d\n" 1099 + "NumMemPstatesEnabled: %d\n" 1100 + "MinGfxClk: %d\n" 1101 + "MaxGfxClk: %d\n", 1102 + dpm_clks->NumDcfClkLevelsEnabled, 1103 + dpm_clks->NumDispClkLevelsEnabled, 1104 + dpm_clks->NumSocClkLevelsEnabled, 1105 + dpm_clks->VcnClkLevelsEnabled, 1106 + dpm_clks->NumFclkLevelsEnabled, 1107 + dpm_clks->NumMemPstatesEnabled, 1108 + dpm_clks->MinGfxClk, 1109 + dpm_clks->MaxGfxClk); 1110 + 1111 + for (i = 0; i < NUM_DCFCLK_DPM_LEVELS; i++) { 1112 + DC_LOG_SMU("dpm_clks->DcfClocks[%d] = %d\n", 1113 + i, 1114 + dpm_clks->DcfClocks[i]); 1115 + } 1116 + for (i = 0; i < NUM_DISPCLK_DPM_LEVELS; i++) { 1117 + DC_LOG_SMU("dpm_clks->DispClocks[%d] = %d\n", 1118 + i, dpm_clks->DispClocks[i]); 1119 + } 1120 + for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++) { 1121 + DC_LOG_SMU("dpm_clks->SocClocks[%d] = %d\n", 1122 + i, dpm_clks->SocClocks[i]); 1123 + } 1124 + for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++) { 1125 + DC_LOG_SMU("dpm_clks->FclkClocks_Freq[%d] = %d\n", 1126 + i, dpm_clks->FclkClocks_Freq[i]); 1127 + DC_LOG_SMU("dpm_clks->FclkClocks_Voltage[%d] = %d\n", 1128 + i, dpm_clks->FclkClocks_Voltage[i]); 1129 + } 1130 + for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++) 1131 + DC_LOG_SMU("dpm_clks->SocVoltage[%d] = %d\n", 1132 + i, dpm_clks->SocVoltage[i]); 1133 + 1134 + for (i = 0; i < NUM_MEM_PSTATE_LEVELS; i++) { 1135 + DC_LOG_SMU("dpm_clks.MemPstateTable[%d].UClk = %d\n" 1136 + "dpm_clks->MemPstateTable[%d].MemClk= %d\n" 1137 + "dpm_clks->MemPstateTable[%d].Voltage = %d\n", 1138 + i, dpm_clks->MemPstateTable[i].UClk, 1139 + i, dpm_clks->MemPstateTable[i].MemClk, 1140 + i, dpm_clks->MemPstateTable[i].Voltage); 1141 + } 1142 + 1143 + if (clk_mgr_base->ctx->dc_bios->integrated_info && clk_mgr_base->ctx->dc->config.use_default_clock_table == false) { 1144 + /* DCFCLK */ 1145 + dcn42_init_single_clock(&clk_mgr_base->bw_params->clk_table.entries[0].dcfclk_mhz, 1146 + dpm_clks->DcfClocks, 1147 + dpm_clks->NumDcfClkLevelsEnabled); 1148 + clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dcfclk_levels = dpm_clks->NumDcfClkLevelsEnabled; 1149 + 1150 + /* SOCCLK */ 1151 + dcn42_init_single_clock(&clk_mgr_base->bw_params->clk_table.entries[0].socclk_mhz, 1152 + dpm_clks->SocClocks, 1153 + dpm_clks->NumSocClkLevelsEnabled); 1154 + clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_socclk_levels = dpm_clks->NumSocClkLevelsEnabled; 1155 + 1156 + /* DISPCLK */ 1157 + dcn42_init_single_clock(&clk_mgr_base->bw_params->clk_table.entries[0].dispclk_mhz, 1158 + dpm_clks->DispClocks, 1159 + dpm_clks->NumDispClkLevelsEnabled); 1160 + clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dispclk_levels = dpm_clks->NumDispClkLevelsEnabled; 1161 + 1162 + /* DPPCLK */ 1163 + dcn42_init_single_clock(&clk_mgr_base->bw_params->clk_table.entries[0].dppclk_mhz, 1164 + dpm_clks->DppClocks, 1165 + dpm_clks->NumDispClkLevelsEnabled); 1166 + clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dppclk_levels = dpm_clks->NumDispClkLevelsEnabled; 1167 + 1168 + /* FCLK */ 1169 + dcn42_init_single_clock(&clk_mgr_base->bw_params->clk_table.entries[0].fclk_mhz, 1170 + dpm_clks->FclkClocks_Freq, 1171 + NUM_FCLK_DPM_LEVELS); 1172 + clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_fclk_levels = dpm_clks->NumFclkLevelsEnabled; 1173 + clk_mgr_base->bw_params->clk_table.num_entries = dpm_clks->NumFclkLevelsEnabled; 1174 + 1175 + /* Memory Pstate table is in reverse order*/ 1176 + ASSERT(dpm_clks->NumMemPstatesEnabled <= NUM_MEM_PSTATE_LEVELS); 1177 + if (dpm_clks->NumMemPstatesEnabled > NUM_MEM_PSTATE_LEVELS) 1178 + dpm_clks->NumMemPstatesEnabled = NUM_MEM_PSTATE_LEVELS; 1179 + for (i = 0; i < dpm_clks->NumMemPstatesEnabled; i++) { 1180 + clk_mgr_base->bw_params->clk_table.entries[dpm_clks->NumMemPstatesEnabled - 1 - i].memclk_mhz = dpm_clks->MemPstateTable[i].MemClk; 1181 + clk_mgr_base->bw_params->clk_table.entries[dpm_clks->NumMemPstatesEnabled - 1 - i].wck_ratio = dcn42_convert_wck_ratio(dpm_clks->MemPstateTable[i].WckRatio) ; 1182 + } 1183 + clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels = dpm_clks->NumMemPstatesEnabled; 1184 + 1185 + /* DTBCLK*/ 1186 + clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz = 600; /* Fixed on platform */ 1187 + clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dtbclk_levels = 1; 1188 + } 1189 + } 1190 + if (smu_dpm_clks.dpm_clks && smu_dpm_clks.mc_address.quad_part != 0) 1191 + dm_helpers_free_gpu_mem(clk_mgr_base->ctx, DC_MEM_ALLOC_TYPE_GART, 1192 + smu_dpm_clks.dpm_clks); 1193 + } 1194 + 957 1195 static struct clk_mgr_funcs dcn42_funcs = { 958 1196 .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, 959 1197 .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz, ··· 1143 1139 dcn42_bw_params.num_channels = ctx->dc_bios->integrated_info->ma_channel_number ? ctx->dc_bios->integrated_info->ma_channel_number : 1; 1144 1140 clk_mgr->base.base.dprefclk_khz = dcn42_smu_get_dprefclk(&clk_mgr->base); 1145 1141 clk_mgr->base.base.clks.ref_dtbclk_khz = dcn42_smu_get_dtbclk(&clk_mgr->base); 1142 + 1143 + clk_mgr->base.base.bw_params = &dcn42_bw_params; 1144 + 1145 + if (clk_mgr->base.smu_present) 1146 + dcn42_get_smu_clocks(&clk_mgr->base); 1146 1147 } 1147 1148 /* in case we don't get a value from the BIOS, use default */ 1148 1149 if (clk_mgr->base.base.dentist_vco_freq_khz == 0) ··· 1162 1153 dcn42_read_ss_info_from_lut(&clk_mgr->base); 1163 1154 1164 1155 clk_mgr->base.base.bw_params = &dcn42_bw_params; 1156 + if (clk_mgr->base.smu_present) 1157 + dcn42_get_smu_clocks(&clk_mgr->base); 1165 1158 } 1166 1159 1167 1160 void dcn42_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr_int)
+201 -299
drivers/gpu/drm/amd/display/dc/core/dc.c
··· 2695 2695 static struct surface_update_descriptor get_plane_info_update_type(const struct dc_surface_update *u) 2696 2696 { 2697 2697 union surface_update_flags *update_flags = &u->surface->update_flags; 2698 - struct surface_update_descriptor update_type = { UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_NONE }; 2698 + struct surface_update_descriptor update_type = { UPDATE_TYPE_ADDR_ONLY, LOCK_DESCRIPTOR_NONE }; 2699 2699 2700 2700 if (!u->plane_info) 2701 2701 return update_type; ··· 2769 2769 2770 2770 if (memcmp(tiling, &u->surface->tiling_info, sizeof(*tiling)) != 0) { 2771 2771 update_flags->bits.swizzle_change = 1; 2772 - elevate_update_type(&update_type, UPDATE_TYPE_MED, LOCK_DESCRIPTOR_STREAM); 2773 2772 2774 - switch (tiling->gfxversion) { 2775 - case DcGfxVersion9: 2776 - case DcGfxVersion10: 2777 - case DcGfxVersion11: 2778 - if (tiling->gfx9.swizzle != DC_SW_LINEAR) { 2779 - update_flags->bits.bandwidth_change = 1; 2780 - elevate_update_type(&update_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 2781 - } 2782 - break; 2783 - case DcGfxAddr3: 2784 - if (tiling->gfx_addr3.swizzle != DC_ADDR3_SW_LINEAR) { 2785 - update_flags->bits.bandwidth_change = 1; 2786 - elevate_update_type(&update_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 2787 - } 2788 - break; 2789 - case DcGfxVersion7: 2790 - case DcGfxVersion8: 2791 - case DcGfxVersionUnknown: 2792 - default: 2793 - break; 2773 + if (tiling->flags.avoid_full_update_on_tiling_change) { 2774 + elevate_update_type(&update_type, UPDATE_TYPE_MED, LOCK_DESCRIPTOR_STREAM); 2775 + } else { 2776 + update_flags->bits.bandwidth_change = 1; 2777 + elevate_update_type(&update_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 2794 2778 } 2795 2779 } 2796 2780 ··· 2787 2803 const struct dc_surface_update *u) 2788 2804 { 2789 2805 union surface_update_flags *update_flags = &u->surface->update_flags; 2790 - struct surface_update_descriptor update_type = { UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_NONE }; 2806 + struct surface_update_descriptor update_type = { UPDATE_TYPE_ADDR_ONLY, LOCK_DESCRIPTOR_NONE }; 2791 2807 2792 2808 if (!u->scaling_info) 2793 2809 return update_type; ··· 2838 2854 return update_type; 2839 2855 } 2840 2856 2841 - static struct surface_update_descriptor det_surface_update( 2857 + static struct surface_update_descriptor check_update_surface( 2842 2858 const struct dc_check_config *check_config, 2843 2859 struct dc_surface_update *u) 2844 2860 { 2845 - struct surface_update_descriptor overall_type = { UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_NONE }; 2861 + struct surface_update_descriptor overall_type = { UPDATE_TYPE_ADDR_ONLY, LOCK_DESCRIPTOR_NONE }; 2846 2862 union surface_update_flags *update_flags = &u->surface->update_flags; 2847 2863 2848 2864 if (u->surface->force_full_update) { ··· 2862 2878 2863 2879 if (u->flip_addr) { 2864 2880 update_flags->bits.addr_update = 1; 2865 - elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 2881 + elevate_update_type(&overall_type, UPDATE_TYPE_ADDR_ONLY, LOCK_DESCRIPTOR_STREAM); 2866 2882 2867 2883 if (u->flip_addr->address.tmz_surface != u->surface->address.tmz_surface) { 2868 2884 update_flags->bits.tmz_changed = 1; ··· 2876 2892 2877 2893 if (u->input_csc_color_matrix) { 2878 2894 update_flags->bits.input_csc_change = 1; 2879 - elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 2895 + elevate_update_type(&overall_type, 2896 + check_config->enable_legacy_fast_update ? UPDATE_TYPE_MED : UPDATE_TYPE_FAST, 2897 + LOCK_DESCRIPTOR_STREAM); 2898 + } 2899 + 2900 + if (u->cursor_csc_color_matrix) { 2901 + elevate_update_type(&overall_type, 2902 + check_config->enable_legacy_fast_update ? UPDATE_TYPE_MED : UPDATE_TYPE_FAST, 2903 + LOCK_DESCRIPTOR_STREAM); 2880 2904 } 2881 2905 2882 2906 if (u->coeff_reduction_factor) { 2883 2907 update_flags->bits.coeff_reduction_change = 1; 2884 - elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 2908 + elevate_update_type(&overall_type, 2909 + check_config->enable_legacy_fast_update ? UPDATE_TYPE_MED : UPDATE_TYPE_FAST, 2910 + LOCK_DESCRIPTOR_STREAM); 2885 2911 } 2886 2912 2887 2913 if (u->gamut_remap_matrix) { 2888 2914 update_flags->bits.gamut_remap_change = 1; 2889 - elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 2915 + elevate_update_type(&overall_type, 2916 + check_config->enable_legacy_fast_update ? UPDATE_TYPE_MED : UPDATE_TYPE_FAST, 2917 + LOCK_DESCRIPTOR_STREAM); 2890 2918 } 2891 2919 2892 2920 if (u->cm || (u->gamma && dce_use_lut(u->plane_info ? u->plane_info->format : u->surface->format))) { 2893 2921 update_flags->bits.gamma_change = 1; 2894 - elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 2922 + elevate_update_type(&overall_type, 2923 + check_config->enable_legacy_fast_update ? UPDATE_TYPE_MED : UPDATE_TYPE_FAST, 2924 + LOCK_DESCRIPTOR_STREAM); 2895 2925 } 2896 2926 2897 2927 if (u->cm && (u->cm->flags.bits.lut3d_enable || u->surface->cm.flags.bits.lut3d_enable)) { 2898 2928 update_flags->bits.lut_3d = 1; 2899 - elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 2929 + elevate_update_type(&overall_type, 2930 + check_config->enable_legacy_fast_update ? UPDATE_TYPE_MED : UPDATE_TYPE_FAST, 2931 + LOCK_DESCRIPTOR_STREAM); 2900 2932 } 2901 2933 2902 2934 if (u->cm && u->cm->flags.bits.lut3d_dma_enable != u->surface->cm.flags.bits.lut3d_dma_enable && ··· 2928 2928 2929 2929 if (u->hdr_mult.value) 2930 2930 if (u->hdr_mult.value != u->surface->hdr_mult.value) { 2931 - // TODO: Should be fast? 2932 2931 update_flags->bits.hdr_mult = 1; 2933 - elevate_update_type(&overall_type, UPDATE_TYPE_MED, LOCK_DESCRIPTOR_STREAM); 2932 + elevate_update_type(&overall_type, 2933 + check_config->enable_legacy_fast_update ? UPDATE_TYPE_MED : UPDATE_TYPE_FAST, 2934 + LOCK_DESCRIPTOR_STREAM); 2934 2935 } 2935 2936 2936 2937 if (u->sdr_white_level_nits) ··· 2985 2984 int surface_count, 2986 2985 struct dc_stream_update *stream_update) 2987 2986 { 2988 - struct surface_update_descriptor overall_type = { UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_NONE }; 2987 + struct surface_update_descriptor overall_type = { UPDATE_TYPE_ADDR_ONLY, LOCK_DESCRIPTOR_NONE }; 2989 2988 2990 2989 /* When countdown finishes, promote this flip to full to trigger deferred final transition */ 2991 2990 if (check_config->deferred_transition_state && !check_config->transition_countdown_to_steady_state) { ··· 3052 3051 if (su_flags->raw) 3053 3052 elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 3054 3053 3055 - // Non-global cases 3054 + /* Non-global cases */ 3055 + if (stream_update->hdr_static_metadata || 3056 + stream_update->vrr_infopacket || 3057 + stream_update->vsc_infopacket || 3058 + stream_update->vsp_infopacket || 3059 + stream_update->hfvsif_infopacket || 3060 + stream_update->adaptive_sync_infopacket || 3061 + stream_update->vtem_infopacket || 3062 + stream_update->avi_infopacket) { 3063 + elevate_update_type(&overall_type, UPDATE_TYPE_MED, LOCK_DESCRIPTOR_STREAM); 3064 + } 3065 + 3056 3066 if (stream_update->output_csc_transform) { 3057 3067 su_flags->bits.out_csc = 1; 3058 3068 elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); ··· 3073 3061 su_flags->bits.out_tf = 1; 3074 3062 elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 3075 3063 } 3064 + 3065 + if (stream_update->periodic_interrupt) { 3066 + elevate_update_type(&overall_type, UPDATE_TYPE_MED, LOCK_DESCRIPTOR_STREAM); 3067 + } 3068 + 3069 + if (stream_update->dither_option) { 3070 + elevate_update_type(&overall_type, UPDATE_TYPE_MED, LOCK_DESCRIPTOR_STREAM); 3071 + } 3072 + 3073 + if (stream_update->cursor_position || stream_update->cursor_attributes) { 3074 + elevate_update_type(&overall_type, UPDATE_TYPE_MED, LOCK_DESCRIPTOR_STREAM); 3075 + } 3076 + 3077 + /* TODO - cleanup post blend CM */ 3078 + if (stream_update->func_shaper || stream_update->lut3d_func) { 3079 + elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 3080 + } 3081 + 3082 + if (stream_update->pending_test_pattern) { 3083 + elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 3084 + } 3076 3085 } 3077 3086 3078 3087 for (int i = 0 ; i < surface_count; i++) { 3079 3088 struct surface_update_descriptor inner_type = 3080 - det_surface_update(check_config, &updates[i]); 3089 + check_update_surface(check_config, &updates[i]); 3081 3090 3082 3091 elevate_update_type(&overall_type, inner_type.update_type, inner_type.lock_descriptor); 3083 3092 } ··· 3123 3090 updates[i].surface->update_flags.raw = 0; 3124 3091 3125 3092 return check_update_surfaces_for_stream(check_config, updates, surface_count, stream_update); 3093 + } 3094 + 3095 + /* 3096 + * check_update_state_and_surfaces_for_stream() - Determine update type (fast, med, or full) 3097 + * 3098 + * This function performs checks on the DC global state, and is therefore not re-entrant. It 3099 + * should not be called from DM. 3100 + * 3101 + * See :c:type:`enum surface_update_type <surface_update_type>` for explanation of update types 3102 + */ 3103 + static struct surface_update_descriptor check_update_state_and_surfaces_for_stream( 3104 + const struct dc *dc, 3105 + const struct dc_check_config *check_config, 3106 + const struct dc_stream_state *stream, 3107 + const struct dc_surface_update *updates, 3108 + const int surface_count, 3109 + const struct dc_stream_update *stream_update) 3110 + { 3111 + const struct dc_state *context = dc->current_state; 3112 + 3113 + struct surface_update_descriptor overall_type = { UPDATE_TYPE_ADDR_ONLY, LOCK_DESCRIPTOR_NONE}; 3114 + 3115 + if (updates) 3116 + for (int i = 0; i < surface_count; i++) 3117 + if (!is_surface_in_context(context, updates[i].surface)) 3118 + elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 3119 + 3120 + if (stream) { 3121 + const struct dc_stream_status *stream_status = dc_stream_get_status_const(stream); 3122 + if (stream_status == NULL || stream_status->plane_count != surface_count) 3123 + elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 3124 + } 3125 + if (dc->idle_optimizations_allowed) 3126 + elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 3127 + 3128 + if (dc_can_clear_cursor_limit(dc)) 3129 + elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 3130 + 3131 + return overall_type; 3132 + } 3133 + 3134 + /* 3135 + * dc_check_update_state_and_surfaces_for_stream() - Determine update type (fast, med, or full) 3136 + * 3137 + * This function performs checks on the DC global state, stream and surface update, and is 3138 + * therefore not re-entrant. It should not be called from DM. 3139 + * 3140 + * See :c:type:`enum surface_update_type <surface_update_type>` for explanation of update types 3141 + */ 3142 + static struct surface_update_descriptor dc_check_update_state_and_surfaces_for_stream( 3143 + const struct dc *dc, 3144 + const struct dc_check_config *check_config, 3145 + struct dc_stream_state *stream, 3146 + struct dc_surface_update *updates, 3147 + int surface_count, 3148 + struct dc_stream_update *stream_update) 3149 + { 3150 + /* check updates against the entire DC state (global) first */ 3151 + struct surface_update_descriptor overall_update_type = check_update_state_and_surfaces_for_stream( 3152 + dc, 3153 + check_config, 3154 + stream, 3155 + updates, 3156 + surface_count, 3157 + stream_update); 3158 + 3159 + /* check updates for stream and plane */ 3160 + struct surface_update_descriptor stream_update_type = dc_check_update_surfaces_for_stream( 3161 + check_config, 3162 + updates, 3163 + surface_count, 3164 + stream_update); 3165 + elevate_update_type(&overall_update_type, stream_update_type.update_type, stream_update_type.lock_descriptor); 3166 + 3167 + return overall_update_type; 3126 3168 } 3127 3169 3128 3170 static struct dc_stream_status *stream_get_status( ··· 3556 3448 } 3557 3449 } 3558 3450 3559 - static bool full_update_required_weak( 3560 - const struct dc *dc, 3561 - const struct dc_surface_update *srf_updates, 3562 - int surface_count, 3563 - const struct dc_stream_update *stream_update, 3564 - const struct dc_stream_state *stream); 3565 - 3566 3451 struct pipe_split_policy_backup { 3567 3452 bool dynamic_odm_policy; 3568 3453 bool subvp_policy; ··· 3625 3524 struct dc_surface_update *srf_updates, int surface_count, 3626 3525 struct dc_stream_state *stream, 3627 3526 struct dc_stream_update *stream_update, 3628 - enum surface_update_type *new_update_type, 3527 + struct surface_update_descriptor *update_descriptor, 3629 3528 struct dc_state **new_context) 3630 3529 { 3631 3530 struct dc_state *context; 3632 3531 int i, j; 3633 - enum surface_update_type update_type; 3634 3532 const struct dc_stream_status *stream_status; 3635 3533 struct dc_context *dc_ctx = dc->ctx; 3636 3534 ··· 3643 3543 } 3644 3544 3645 3545 context = dc->current_state; 3646 - update_type = dc_check_update_surfaces_for_stream( 3647 - &dc->check_config, srf_updates, surface_count, stream_update).update_type; 3648 - if (full_update_required_weak(dc, srf_updates, surface_count, stream_update, stream)) 3649 - update_type = UPDATE_TYPE_FULL; 3546 + *update_descriptor = dc_check_update_state_and_surfaces_for_stream( 3547 + dc, 3548 + &dc->check_config, 3549 + stream, 3550 + srf_updates, 3551 + surface_count, 3552 + stream_update); 3650 3553 3651 3554 /* It is possible to receive a flip for one plane while there are multiple flip_immediate planes in the same stream. 3652 3555 * E.g. Desktop and MPO plane are flip_immediate but only the MPO plane received a flip 3653 3556 * Force the other flip_immediate planes to flip so GSL doesn't wait for a flip that won't come. 3654 3557 */ 3655 3558 force_immediate_gsl_plane_flip(dc, srf_updates, surface_count); 3656 - if (update_type == UPDATE_TYPE_FULL) 3559 + if (update_descriptor->update_type == UPDATE_TYPE_FULL) 3657 3560 backup_planes_and_stream_state(&dc->scratch.current_state, stream); 3658 3561 3659 3562 /* update current stream with the new updates */ ··· 3682 3579 } 3683 3580 } 3684 3581 3685 - if (update_type == UPDATE_TYPE_FULL) { 3582 + if (update_descriptor->update_type == UPDATE_TYPE_FULL) { 3686 3583 if (stream_update) { 3687 3584 uint32_t dsc_changed = stream_update->stream->update_flags.bits.dsc_changed; 3688 3585 stream_update->stream->update_flags.raw = 0xFFFFFFFF; ··· 3692 3589 srf_updates[i].surface->update_flags.raw = 0xFFFFFFFF; 3693 3590 } 3694 3591 3695 - if (update_type >= update_surface_trace_level) 3592 + if (update_descriptor->update_type >= update_surface_trace_level) 3696 3593 update_surface_trace(dc, srf_updates, surface_count); 3697 3594 3698 3595 for (i = 0; i < surface_count; i++) 3699 3596 copy_surface_update_to_plane(srf_updates[i].surface, &srf_updates[i]); 3700 3597 3701 - if (update_type >= UPDATE_TYPE_FULL) { 3598 + if (update_descriptor->update_type >= UPDATE_TYPE_FULL) { 3702 3599 struct dc_plane_state *new_planes[MAX_SURFACES] = {0}; 3703 3600 3704 3601 for (i = 0; i < surface_count; i++) ··· 3736 3633 for (i = 0; i < surface_count; i++) { 3737 3634 struct dc_plane_state *surface = srf_updates[i].surface; 3738 3635 3739 - if (update_type != UPDATE_TYPE_MED) 3636 + if (update_descriptor->update_type != UPDATE_TYPE_MED) 3740 3637 continue; 3741 3638 if (surface->update_flags.bits.position_change) { 3742 3639 for (j = 0; j < dc->res_pool->pipe_count; j++) { ··· 3750 3647 } 3751 3648 } 3752 3649 3753 - if (update_type == UPDATE_TYPE_FULL) { 3650 + if (update_descriptor->update_type == UPDATE_TYPE_FULL) { 3754 3651 struct pipe_split_policy_backup policy; 3755 3652 bool minimize = false; 3756 3653 ··· 3779 3676 update_seamless_boot_flags(dc, context, surface_count, stream); 3780 3677 3781 3678 *new_context = context; 3782 - *new_update_type = update_type; 3783 - if (update_type == UPDATE_TYPE_FULL) 3679 + if (update_descriptor->update_type == UPDATE_TYPE_FULL) 3784 3680 backup_planes_and_stream_state(&dc->scratch.new_state, stream); 3785 3681 3786 3682 return true; ··· 3859 3757 program_cursor_position(dc, stream); 3860 3758 3861 3759 /* Full fe update*/ 3862 - if (update_type == UPDATE_TYPE_FAST) 3760 + if (update_type <= UPDATE_TYPE_FAST) 3863 3761 continue; 3864 3762 3865 3763 if (stream_update->dsc_config) ··· 4168 4066 struct pipe_ctx *top_pipe_to_program = NULL; 4169 4067 struct dc_stream_status *stream_status = NULL; 4170 4068 bool should_offload_fams2_flip = false; 4171 - bool should_lock_all_pipes = (update_type != UPDATE_TYPE_FAST); 4069 + bool should_lock_all_pipes = (update_type > UPDATE_TYPE_FAST); 4172 4070 4173 4071 if (should_lock_all_pipes) 4174 4072 determine_pipe_unlock_order(dc, context); ··· 4228 4126 continue; 4229 4127 4230 4128 pipe_ctx->plane_state->triplebuffer_flips = false; 4231 - if (update_type == UPDATE_TYPE_FAST && 4129 + if (update_type <= UPDATE_TYPE_FAST && 4232 4130 dc->hwss.program_triplebuffer != NULL && 4233 4131 !pipe_ctx->plane_state->flip_immediate && dc->debug.enable_tri_buf) { 4234 4132 /*triple buffer for VUpdate only*/ ··· 4285 4183 { 4286 4184 int i, j; 4287 4185 struct pipe_ctx *top_pipe_to_program = NULL; 4288 - bool should_lock_all_pipes = (update_type != UPDATE_TYPE_FAST); 4186 + bool should_lock_all_pipes = (update_type > UPDATE_TYPE_FAST); 4289 4187 bool subvp_prev_use = false; 4290 4188 bool subvp_curr_use = false; 4291 4189 uint8_t current_stream_mask = 0; ··· 4302 4200 if (update_type == UPDATE_TYPE_FULL && dc->optimized_required) 4303 4201 hwss_process_outstanding_hw_updates(dc, dc->current_state); 4304 4202 4305 - if (update_type != UPDATE_TYPE_FAST && dc->res_pool->funcs->prepare_mcache_programming) 4203 + if (update_type > UPDATE_TYPE_FAST && dc->res_pool->funcs->prepare_mcache_programming) 4306 4204 dc->res_pool->funcs->prepare_mcache_programming(dc, context); 4307 4205 4308 4206 for (i = 0; i < dc->res_pool->pipe_count; i++) { ··· 4364 4262 odm_pipe->ttu_regs.min_ttu_vblank = MAX_TTU; 4365 4263 } 4366 4264 4367 - if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) 4265 + if ((update_type > UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) 4368 4266 if (top_pipe_to_program && 4369 4267 top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { 4370 4268 if (should_use_dmub_inbox1_lock(dc, stream->link)) { ··· 4435 4333 } 4436 4334 dc->hwss.post_unlock_program_front_end(dc, context); 4437 4335 4438 - if (update_type != UPDATE_TYPE_FAST) 4336 + if (update_type > UPDATE_TYPE_FAST) 4439 4337 if (dc->hwss.commit_subvp_config) 4440 4338 dc->hwss.commit_subvp_config(dc, context); 4441 4339 ··· 4451 4349 return; 4452 4350 } 4453 4351 4454 - if (update_type != UPDATE_TYPE_FAST) { 4352 + if (update_type > UPDATE_TYPE_FAST) { 4455 4353 for (j = 0; j < dc->res_pool->pipe_count; j++) { 4456 4354 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; 4457 4355 ··· 4479 4377 if (!should_update_pipe_for_plane(context, pipe_ctx, plane_state)) 4480 4378 continue; 4481 4379 pipe_ctx->plane_state->triplebuffer_flips = false; 4482 - if (update_type == UPDATE_TYPE_FAST && 4380 + if (update_type <= UPDATE_TYPE_FAST && 4483 4381 dc->hwss.program_triplebuffer != NULL && 4484 4382 !pipe_ctx->plane_state->flip_immediate && dc->debug.enable_tri_buf) { 4485 4383 /*triple buffer for VUpdate only*/ ··· 4506 4404 continue; 4507 4405 4508 4406 /* Full fe update*/ 4509 - if (update_type == UPDATE_TYPE_FAST) 4407 + if (update_type <= UPDATE_TYPE_FAST) 4510 4408 continue; 4511 4409 4512 4410 stream_status = ··· 4525 4423 continue; 4526 4424 4527 4425 /* Full fe update*/ 4528 - if (update_type == UPDATE_TYPE_FAST) 4426 + if (update_type <= UPDATE_TYPE_FAST) 4529 4427 continue; 4530 4428 4531 4429 ASSERT(!pipe_ctx->plane_state->triplebuffer_flips); ··· 4536 4434 } 4537 4435 } 4538 4436 4539 - if (dc->hwss.program_front_end_for_ctx && update_type != UPDATE_TYPE_FAST) { 4437 + if (dc->hwss.program_front_end_for_ctx && update_type > UPDATE_TYPE_FAST) { 4540 4438 dc->hwss.program_front_end_for_ctx(dc, context); 4541 4439 4542 4440 //Pipe busy until some frame and line # ··· 4564 4462 } 4565 4463 4566 4464 // Update Type FAST, Surface updates 4567 - if (update_type == UPDATE_TYPE_FAST) { 4465 + if (update_type <= UPDATE_TYPE_FAST) { 4568 4466 if (dc->hwss.set_flip_control_gsl) 4569 4467 for (i = 0; i < surface_count; i++) { 4570 4468 struct dc_plane_state *plane_state = srf_updates[i].surface; ··· 4601 4499 srf_updates[i].cm->flags.bits.lut3d_enable && 4602 4500 srf_updates[i].cm->flags.bits.lut3d_dma_enable && 4603 4501 dc->hwss.trigger_3dlut_dma_load) 4604 - dc->hwss.trigger_3dlut_dma_load(dc, pipe_ctx); 4502 + dc->hwss.trigger_3dlut_dma_load(pipe_ctx); 4605 4503 4606 4504 /*program triple buffer after lock based on flip type*/ 4607 4505 if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) { ··· 4621 4519 dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false); 4622 4520 } 4623 4521 4624 - if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) 4522 + if ((update_type > UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) 4625 4523 if (top_pipe_to_program && 4626 4524 top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { 4627 4525 top_pipe_to_program->stream_res.tg->funcs->wait_for_state( ··· 4654 4552 /* If enabling subvp or transitioning from subvp->subvp, enable the 4655 4553 * phantom streams before we program front end for the phantom pipes. 4656 4554 */ 4657 - if (update_type != UPDATE_TYPE_FAST) { 4555 + if (update_type > UPDATE_TYPE_FAST) { 4658 4556 if (dc->hwss.enable_phantom_streams) 4659 4557 dc->hwss.enable_phantom_streams(dc, context); 4660 4558 } 4661 4559 } 4662 4560 4663 - if (update_type != UPDATE_TYPE_FAST) 4561 + if (update_type > UPDATE_TYPE_FAST) 4664 4562 dc->hwss.post_unlock_program_front_end(dc, context); 4665 4563 4666 4564 if (subvp_prev_use && !subvp_curr_use) { ··· 4673 4571 dc->hwss.disable_phantom_streams(dc, context); 4674 4572 } 4675 4573 4676 - if (update_type != UPDATE_TYPE_FAST) 4574 + if (update_type > UPDATE_TYPE_FAST) 4677 4575 if (dc->hwss.commit_subvp_config) 4678 4576 dc->hwss.commit_subvp_config(dc, context); 4679 4577 /* Since phantom pipe programming is moved to post_unlock_program_front_end, ··· 5145 5043 return true; 5146 5044 } 5147 5045 5148 - void populate_fast_updates(struct dc_fast_update *fast_update, 5149 - struct dc_surface_update *srf_updates, 5150 - int surface_count, 5151 - struct dc_stream_update *stream_update) 5152 - { 5153 - int i = 0; 5154 - 5155 - if (stream_update) { 5156 - fast_update[0].out_transfer_func = stream_update->out_transfer_func; 5157 - fast_update[0].output_csc_transform = stream_update->output_csc_transform; 5158 - } else { 5159 - fast_update[0].out_transfer_func = NULL; 5160 - fast_update[0].output_csc_transform = NULL; 5161 - } 5162 - 5163 - for (i = 0; i < surface_count; i++) { 5164 - fast_update[i].flip_addr = srf_updates[i].flip_addr; 5165 - fast_update[i].gamma = srf_updates[i].gamma; 5166 - fast_update[i].gamut_remap_matrix = srf_updates[i].gamut_remap_matrix; 5167 - fast_update[i].input_csc_color_matrix = srf_updates[i].input_csc_color_matrix; 5168 - fast_update[i].coeff_reduction_factor = srf_updates[i].coeff_reduction_factor; 5169 - fast_update[i].cursor_csc_color_matrix = srf_updates[i].cursor_csc_color_matrix; 5170 - fast_update[i].cm_hist_control = srf_updates[i].cm_hist_control; 5171 - } 5172 - } 5173 - 5174 - static bool fast_updates_exist(const struct dc_fast_update *fast_update, int surface_count) 5175 - { 5176 - int i; 5177 - 5178 - if (fast_update[0].out_transfer_func || 5179 - fast_update[0].output_csc_transform) 5180 - return true; 5181 - 5182 - for (i = 0; i < surface_count; i++) { 5183 - if (fast_update[i].flip_addr || 5184 - fast_update[i].gamma || 5185 - fast_update[i].gamut_remap_matrix || 5186 - fast_update[i].input_csc_color_matrix || 5187 - fast_update[i].cursor_csc_color_matrix || 5188 - fast_update[i].cm_hist_control || 5189 - fast_update[i].coeff_reduction_factor) 5190 - return true; 5191 - } 5192 - 5193 - return false; 5194 - } 5195 - 5196 - bool fast_nonaddr_updates_exist(struct dc_fast_update *fast_update, int surface_count) 5197 - { 5198 - int i; 5199 - 5200 - if (fast_update[0].out_transfer_func || 5201 - fast_update[0].output_csc_transform) 5202 - return true; 5203 - 5204 - for (i = 0; i < surface_count; i++) { 5205 - if (fast_update[i].input_csc_color_matrix || 5206 - fast_update[i].gamma || 5207 - fast_update[i].gamut_remap_matrix || 5208 - fast_update[i].coeff_reduction_factor || 5209 - fast_update[i].cm_hist_control || 5210 - fast_update[i].cursor_csc_color_matrix) 5211 - return true; 5212 - } 5213 - 5214 - return false; 5215 - } 5216 - 5217 - static bool full_update_required_weak( 5218 - const struct dc *dc, 5219 - const struct dc_surface_update *srf_updates, 5220 - int surface_count, 5221 - const struct dc_stream_update *stream_update, 5222 - const struct dc_stream_state *stream) 5223 - { 5224 - const struct dc_state *context = dc->current_state; 5225 - if (srf_updates) 5226 - for (int i = 0; i < surface_count; i++) 5227 - if (!is_surface_in_context(context, srf_updates[i].surface)) 5228 - return true; 5229 - 5230 - if (stream) { 5231 - const struct dc_stream_status *stream_status = dc_stream_get_status_const(stream); 5232 - if (stream_status == NULL || stream_status->plane_count != surface_count) 5233 - return true; 5234 - } 5235 - if (dc->idle_optimizations_allowed) 5236 - return true; 5237 - 5238 - if (dc_can_clear_cursor_limit(dc)) 5239 - return true; 5240 - 5241 - return false; 5242 - } 5243 - 5244 - static bool full_update_required( 5245 - const struct dc *dc, 5246 - const struct dc_surface_update *srf_updates, 5247 - int surface_count, 5248 - const struct dc_stream_update *stream_update, 5249 - const struct dc_stream_state *stream) 5250 - { 5251 - const union dc_plane_cm_flags blend_only_flags = { 5252 - .bits = { 5253 - .blend_enable = 1, 5254 - } 5255 - }; 5256 - 5257 - if (full_update_required_weak(dc, srf_updates, surface_count, stream_update, stream)) 5258 - return true; 5259 - 5260 - for (int i = 0; i < surface_count; i++) { 5261 - if (srf_updates && 5262 - (srf_updates[i].plane_info || 5263 - srf_updates[i].scaling_info || 5264 - (srf_updates[i].hdr_mult.value && 5265 - srf_updates[i].hdr_mult.value != srf_updates->surface->hdr_mult.value) || 5266 - (srf_updates[i].sdr_white_level_nits && 5267 - srf_updates[i].sdr_white_level_nits != srf_updates->surface->sdr_white_level_nits) || 5268 - srf_updates[i].in_transfer_func || 5269 - srf_updates[i].surface->force_full_update || 5270 - (srf_updates[i].flip_addr && 5271 - srf_updates[i].flip_addr->address.tmz_surface != srf_updates[i].surface->address.tmz_surface) || 5272 - (srf_updates[i].cm && 5273 - ((srf_updates[i].cm->flags.all != blend_only_flags.all && srf_updates[i].cm->flags.all != 0) || 5274 - (srf_updates[i].surface->cm.flags.all != blend_only_flags.all && srf_updates[i].surface->cm.flags.all != 0))))) 5275 - return true; 5276 - } 5277 - 5278 - if (stream_update && 5279 - (((stream_update->src.height != 0 && stream_update->src.width != 0) || 5280 - (stream_update->dst.height != 0 && stream_update->dst.width != 0) || 5281 - stream_update->integer_scaling_update) || 5282 - stream_update->hdr_static_metadata || 5283 - stream_update->abm_level || 5284 - stream_update->periodic_interrupt || 5285 - stream_update->vrr_infopacket || 5286 - stream_update->vsc_infopacket || 5287 - stream_update->vsp_infopacket || 5288 - stream_update->hfvsif_infopacket || 5289 - stream_update->vtem_infopacket || 5290 - stream_update->adaptive_sync_infopacket || 5291 - stream_update->avi_infopacket || 5292 - stream_update->dpms_off || 5293 - stream_update->allow_freesync || 5294 - stream_update->vrr_active_variable || 5295 - stream_update->vrr_active_fixed || 5296 - stream_update->gamut_remap || 5297 - stream_update->output_color_space || 5298 - stream_update->dither_option || 5299 - stream_update->wb_update || 5300 - stream_update->dsc_config || 5301 - stream_update->mst_bw_update || 5302 - stream_update->func_shaper || 5303 - stream_update->lut3d_func || 5304 - stream_update->pending_test_pattern || 5305 - stream_update->crtc_timing_adjust || 5306 - stream_update->scaler_sharpener_update || 5307 - stream_update->hw_cursor_req)) 5308 - return true; 5309 - 5310 - return false; 5311 - } 5312 - 5313 - static bool fast_update_only( 5314 - const struct dc *dc, 5315 - const struct dc_fast_update *fast_update, 5316 - const struct dc_surface_update *srf_updates, 5317 - int surface_count, 5318 - const struct dc_stream_update *stream_update, 5319 - const struct dc_stream_state *stream) 5320 - { 5321 - return fast_updates_exist(fast_update, surface_count) 5322 - && !full_update_required(dc, srf_updates, surface_count, stream_update, stream); 5323 - } 5324 - 5325 5046 static bool update_planes_and_stream_v2(struct dc *dc, 5326 5047 struct dc_surface_update *srf_updates, int surface_count, 5327 5048 struct dc_stream_state *stream, 5328 5049 struct dc_stream_update *stream_update) 5329 5050 { 5330 5051 struct dc_state *context; 5331 - enum surface_update_type update_type; 5332 - struct dc_fast_update fast_update[MAX_SURFACES] = {0}; 5333 5052 5334 5053 /* In cases where MPO and split or ODM are used transitions can 5335 5054 * cause underflow. Apply stream configuration with minimal pipe ··· 5158 5235 */ 5159 5236 bool force_minimal_pipe_splitting = 0; 5160 5237 bool is_plane_addition = 0; 5161 - bool is_fast_update_only; 5162 5238 5163 - populate_fast_updates(fast_update, srf_updates, surface_count, stream_update); 5164 - is_fast_update_only = fast_update_only(dc, fast_update, srf_updates, 5165 - surface_count, stream_update, stream); 5239 + struct surface_update_descriptor update_descriptor = {0}; 5240 + 5166 5241 force_minimal_pipe_splitting = could_mpcc_tree_change_for_active_pipes( 5167 5242 dc, 5168 5243 stream, ··· 5179 5258 surface_count, 5180 5259 stream, 5181 5260 stream_update, 5182 - &update_type, 5261 + &update_descriptor, 5183 5262 &context)) 5184 5263 return false; 5185 5264 ··· 5189 5268 dc_state_release(context); 5190 5269 return false; 5191 5270 } 5192 - update_type = UPDATE_TYPE_FULL; 5271 + elevate_update_type(&update_descriptor, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 5193 5272 } 5194 5273 5195 5274 if (dc->hwss.is_pipe_topology_transition_seamless && ··· 5198 5277 commit_minimal_transition_state_in_dc_update(dc, context, stream, 5199 5278 srf_updates, surface_count); 5200 5279 5201 - if (is_fast_update_only && !dc->check_config.enable_legacy_fast_update) { 5280 + if (update_descriptor.update_type <= UPDATE_TYPE_FAST) { 5202 5281 commit_planes_for_stream_fast(dc, 5203 5282 srf_updates, 5204 5283 surface_count, 5205 5284 stream, 5206 5285 stream_update, 5207 - update_type, 5286 + update_descriptor.update_type, 5208 5287 context); 5209 5288 } else { 5210 5289 if (!stream_update && ··· 5220 5299 surface_count, 5221 5300 stream, 5222 5301 stream_update, 5223 - update_type, 5302 + update_descriptor.update_type, 5224 5303 context); 5225 5304 } 5226 5305 if (dc->current_state != context) ··· 5234 5313 struct dc_stream_update *stream_update, 5235 5314 enum surface_update_type update_type) 5236 5315 { 5237 - struct dc_fast_update fast_update[MAX_SURFACES] = {0}; 5238 - 5239 5316 ASSERT(update_type < UPDATE_TYPE_FULL); 5240 - populate_fast_updates(fast_update, srf_updates, surface_count, 5241 - stream_update); 5242 - if (fast_update_only(dc, fast_update, srf_updates, surface_count, 5243 - stream_update, stream) && 5244 - !dc->check_config.enable_legacy_fast_update) 5317 + if (update_type <= UPDATE_TYPE_FAST) 5245 5318 commit_planes_for_stream_fast(dc, 5246 5319 srf_updates, 5247 5320 surface_count, ··· 5326 5411 struct dc_stream_update *stream_update) 5327 5412 { 5328 5413 struct dc_state *new_context; 5329 - enum surface_update_type update_type; 5414 + struct surface_update_descriptor update_descriptor = {0}; 5330 5415 5331 5416 /* 5332 5417 * When this function returns true and new_context is not equal to ··· 5338 5423 * replaced by a newer context. Refer to the use of 5339 5424 * swap_and_free_current_context below. 5340 5425 */ 5341 - if (!update_planes_and_stream_state(dc, srf_updates, surface_count, 5342 - stream, stream_update, &update_type, 5426 + if (!update_planes_and_stream_state(dc, 5427 + srf_updates, 5428 + surface_count, 5429 + stream, 5430 + stream_update, 5431 + &update_descriptor, 5343 5432 &new_context)) 5344 5433 return false; 5345 5434 5346 5435 if (new_context == dc->current_state) { 5347 5436 commit_planes_and_stream_update_on_current_context(dc, 5348 5437 srf_updates, surface_count, stream, 5349 - stream_update, update_type); 5438 + stream_update, update_descriptor.update_type); 5350 5439 5351 5440 if (dc->check_config.transition_countdown_to_steady_state) 5352 5441 dc->check_config.transition_countdown_to_steady_state--; 5353 5442 } else { 5354 5443 commit_planes_and_stream_update_with_new_context(dc, 5355 5444 srf_updates, surface_count, stream, 5356 - stream_update, update_type, new_context); 5445 + stream_update, update_descriptor.update_type, new_context); 5357 5446 } 5358 5447 5359 5448 return true; ··· 7131 7212 struct dc_stream_update *stream_update; 7132 7213 bool update_v3; 7133 7214 bool do_clear_update_flags; 7134 - enum surface_update_type update_type; 7215 + struct surface_update_descriptor update_descriptor; 7135 7216 struct dc_state *new_context; 7136 7217 enum update_v3_flow flow; 7137 7218 struct dc_state *backup_context; ··· 7214 7295 ASSERT(scratch->flow == UPDATE_V3_FLOW_INVALID); 7215 7296 dc_exit_ips_for_hw_access(scratch->dc); 7216 7297 7217 - /* HWSS path determination needs to be done prior to updating the surface and stream states. */ 7218 - struct dc_fast_update fast_update[MAX_SURFACES] = { 0 }; 7219 - 7220 - populate_fast_updates(fast_update, 7221 - scratch->surface_updates, 7222 - scratch->surface_count, 7223 - scratch->stream_update); 7224 - 7225 - const bool is_hwss_fast_path_only = 7226 - fast_update_only(scratch->dc, 7227 - fast_update, 7228 - scratch->surface_updates, 7229 - scratch->surface_count, 7230 - scratch->stream_update, 7231 - scratch->stream) && 7232 - !scratch->dc->check_config.enable_legacy_fast_update; 7233 - 7234 7298 if (!update_planes_and_stream_state( 7235 7299 scratch->dc, 7236 7300 scratch->surface_updates, 7237 7301 scratch->surface_count, 7238 7302 scratch->stream, 7239 7303 scratch->stream_update, 7240 - &scratch->update_type, 7304 + &scratch->update_descriptor, 7241 7305 &scratch->new_context 7242 7306 )) { 7243 7307 return false; 7244 7308 } 7245 7309 7246 7310 if (scratch->new_context == scratch->dc->current_state) { 7247 - ASSERT(scratch->update_type < UPDATE_TYPE_FULL); 7311 + ASSERT(scratch->update_descriptor.update_type < UPDATE_TYPE_FULL); 7248 7312 7249 - scratch->flow = is_hwss_fast_path_only 7313 + scratch->flow = scratch->update_descriptor.update_type <= UPDATE_TYPE_FAST 7250 7314 ? UPDATE_V3_FLOW_NO_NEW_CONTEXT_CONTEXT_FAST 7251 7315 : UPDATE_V3_FLOW_NO_NEW_CONTEXT_CONTEXT_FULL; 7252 7316 return true; 7253 7317 } 7254 7318 7255 - ASSERT(scratch->update_type >= UPDATE_TYPE_FULL); 7319 + ASSERT(scratch->update_descriptor.update_type >= UPDATE_TYPE_FULL); 7256 7320 7257 7321 const bool seamless = scratch->dc->hwss.is_pipe_topology_transition_seamless( 7258 7322 scratch->dc, ··· 7308 7406 intermediate_update ? scratch->intermediate_count : scratch->surface_count, 7309 7407 scratch->stream, 7310 7408 use_stream_update ? scratch->stream_update : NULL, 7311 - intermediate_context ? UPDATE_TYPE_FULL : scratch->update_type, 7409 + intermediate_context ? UPDATE_TYPE_FULL : scratch->update_descriptor.update_type, 7312 7410 // `dc->current_state` only used in `NO_NEW_CONTEXT`, where it is equal to `new_context` 7313 7411 intermediate_context ? scratch->intermediate_context : scratch->new_context 7314 7412 ); ··· 7326 7424 scratch->surface_count, 7327 7425 scratch->stream, 7328 7426 scratch->stream_update, 7329 - scratch->update_type, 7427 + scratch->update_descriptor.update_type, 7330 7428 scratch->new_context 7331 7429 ); 7332 7430 break;
+2 -2
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
··· 749 749 return NULL; 750 750 } 751 751 752 - static enum pixel_format convert_pixel_format_to_dalsurface( 752 + static enum dc_pixel_format convert_pixel_format_to_dalsurface( 753 753 enum surface_pixel_format surface_pixel_format) 754 754 { 755 - enum pixel_format dal_pixel_format = PIXEL_FORMAT_UNKNOWN; 755 + enum dc_pixel_format dal_pixel_format = PIXEL_FORMAT_UNKNOWN; 756 756 757 757 switch (surface_pixel_format) { 758 758 case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
+4 -26
drivers/gpu/drm/amd/display/dc/core/dc_stream.c
··· 33 33 #include "dc_dmub_srv.h" 34 34 #include "dc_state_priv.h" 35 35 #include "dc_stream_priv.h" 36 - #include "dce/dmub_hw_lock_mgr.h" 37 36 38 37 #define DC_LOGGER dc->ctx->logger 39 38 #ifndef MIN ··· 258 259 struct resource_context *res_ctx; 259 260 struct pipe_ctx *pipe_to_program = NULL; 260 261 bool enable_cursor_offload = dc_dmub_srv_is_cursor_offload_enabled(dc); 261 - bool unlock_dmub = false; 262 262 263 263 if (!stream) 264 264 return; ··· 276 278 if (enable_cursor_offload && dc->hwss.begin_cursor_offload_update) { 277 279 dc->hwss.begin_cursor_offload_update(dc, pipe_ctx); 278 280 } else { 279 - if (dc->hwss.dmub_hw_control_lock && pipe_ctx->stream && 280 - should_use_dmub_inbox0_lock_for_link(dc, pipe_ctx->stream->link)) { 281 - dc->hwss.dmub_hw_control_lock(dc, dc->current_state, true); 282 - unlock_dmub = true; 283 - } 284 - 285 281 dc->hwss.cursor_lock(dc, pipe_to_program, true); 286 282 if (pipe_to_program->next_odm_pipe) 287 283 dc->hwss.cursor_lock(dc, pipe_to_program->next_odm_pipe, true); ··· 298 306 dc->hwss.cursor_lock(dc, pipe_to_program, false); 299 307 if (pipe_to_program->next_odm_pipe) 300 308 dc->hwss.cursor_lock(dc, pipe_to_program->next_odm_pipe, false); 301 - 302 - if (unlock_dmub) 303 - dc->hwss.dmub_hw_control_lock(dc, dc->current_state, false); 304 309 } 305 310 } 306 311 } ··· 405 416 struct resource_context *res_ctx; 406 417 struct pipe_ctx *pipe_to_program = NULL; 407 418 bool enable_cursor_offload = dc_dmub_srv_is_cursor_offload_enabled(dc); 408 - bool unlock_dmub = false; 409 419 410 420 if (!stream) 411 421 return; ··· 424 436 if (!pipe_to_program) { 425 437 pipe_to_program = pipe_ctx; 426 438 427 - if (enable_cursor_offload && dc->hwss.begin_cursor_offload_update) { 439 + if (enable_cursor_offload && dc->hwss.begin_cursor_offload_update) 428 440 dc->hwss.begin_cursor_offload_update(dc, pipe_ctx); 429 - } else { 430 - if (dc->hwss.dmub_hw_control_lock && pipe_ctx->stream && 431 - should_use_dmub_inbox0_lock_for_link(dc, pipe_ctx->stream->link)) { 432 - dc->hwss.dmub_hw_control_lock(dc, dc->current_state, true); 433 - unlock_dmub = true; 434 - } 441 + else 435 442 dc->hwss.cursor_lock(dc, pipe_to_program, true); 436 - } 437 443 } 438 444 439 445 dc->hwss.set_cursor_position(pipe_ctx); ··· 439 457 } 440 458 441 459 if (pipe_to_program) { 442 - if (enable_cursor_offload && dc->hwss.commit_cursor_offload_update) { 460 + if (enable_cursor_offload && dc->hwss.commit_cursor_offload_update) 443 461 dc->hwss.commit_cursor_offload_update(dc, pipe_to_program); 444 - } else { 462 + else 445 463 dc->hwss.cursor_lock(dc, pipe_to_program, false); 446 - 447 - if (unlock_dmub) 448 - dc->hwss.dmub_hw_control_lock(dc, dc->current_state, false); 449 - } 450 464 } 451 465 } 452 466
+5 -20
drivers/gpu/drm/amd/display/dc/dc.h
··· 63 63 struct dcn_optc_reg_state; 64 64 struct dcn_dccg_reg_state; 65 65 66 - #define DC_VER "3.2.374" 66 + #define DC_VER "3.2.375" 67 67 68 68 /** 69 69 * MAX_SURFACES - representative of the upper bound of surfaces that can be piped to a single CRTC ··· 467 467 */ 468 468 469 469 enum surface_update_type { 470 + UPDATE_TYPE_ADDR_ONLY, /* only surface address is being updated, no other programming needed */ 470 471 UPDATE_TYPE_FAST, /* super fast, safe to execute in isr */ 471 472 UPDATE_TYPE_MED, /* ISR safe, most of programming needed, no bw/clk change*/ 472 473 UPDATE_TYPE_FULL, /* may need to shuffle resources */ ··· 563 562 bool frame_update_cmd_version2; 564 563 struct spl_sharpness_range dcn_sharpness_range; 565 564 struct spl_sharpness_range dcn_override_sharpness_range; 565 + bool no_native422_support; 566 566 }; 567 567 568 568 enum visual_confirm { ··· 988 986 * causing an issue or not. 989 987 */ 990 988 struct dc_debug_options { 991 - bool native422_support; 992 989 bool disable_dsc; 993 990 enum visual_confirm visual_confirm; 994 991 int visual_confirm_rect_height; ··· 1216 1215 bool enable_dmu_recovery; 1217 1216 unsigned int force_vmin_threshold; 1218 1217 bool enable_otg_frame_sync_pwa; 1218 + unsigned int min_deep_sleep_dcfclk_khz; 1219 1219 }; 1220 1220 1221 1221 ··· 1881 1879 struct scaling_taps scaling_quality; 1882 1880 }; 1883 1881 1884 - struct dc_fast_update { 1885 - const struct dc_flip_addrs *flip_addr; 1886 - const struct dc_gamma *gamma; 1887 - const struct colorspace_transform *gamut_remap_matrix; 1888 - const struct dc_csc_transform *input_csc_color_matrix; 1889 - const struct fixed31_32 *coeff_reduction_factor; 1890 - struct dc_transfer_func *out_transfer_func; 1891 - struct dc_csc_transform *output_csc_transform; 1892 - const struct dc_csc_transform *cursor_csc_color_matrix; 1893 - struct cm_hist_control *cm_hist_control; 1894 - }; 1895 - 1896 1882 struct dc_surface_update { 1897 1883 struct dc_plane_state *surface; 1898 1884 ··· 2019 2029 void get_audio_check(struct audio_info *aud_modes, 2020 2030 struct audio_check *aud_chk); 2021 2031 2022 - bool fast_nonaddr_updates_exist(struct dc_fast_update *fast_update, int surface_count); 2023 - void populate_fast_updates(struct dc_fast_update *fast_update, 2024 - struct dc_surface_update *srf_updates, 2025 - int surface_count, 2026 - struct dc_stream_update *stream_update); 2027 - /* 2032 + /* 2028 2033 * Set up streams and links associated to drive sinks 2029 2034 * The streams parameter is an absolute set of all active streams. 2030 2035 *
+1
drivers/gpu/drm/amd/display/dc/dc_dsc.h
··· 52 52 uint32_t max_target_bpp; 53 53 uint32_t min_target_bpp; 54 54 bool enable_dsc_when_not_needed; 55 + bool ycbcr422_simple; 55 56 }; 56 57 57 58 struct dc_dsc_config_options {
+5 -1
drivers/gpu/drm/amd/display/dc/dc_hw_types.h
··· 218 218 219 219 220 220 /* Pixel format */ 221 - enum pixel_format { 221 + enum dc_pixel_format { 222 222 /*graph*/ 223 223 PIXEL_FORMAT_UNINITIALIZED, 224 224 PIXEL_FORMAT_INDEX8, ··· 445 445 enum swizzle_mode_addr3_values swizzle; 446 446 } gfx_addr3;/*gfx with addr3 and above*/ 447 447 }; 448 + 449 + struct { 450 + bool avoid_full_update_on_tiling_change; 451 + } flags; 448 452 }; 449 453 450 454 /* Rotation angle */
+2 -1
drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
··· 63 63 inits->h_c = dc_fixpt_from_int_dy(spl_inits->h_filter_init_int_c, spl_inits->h_filter_init_frac_c >> 5, 0, 19); 64 64 inits->v_c = dc_fixpt_from_int_dy(spl_inits->v_filter_init_int_c, spl_inits->v_filter_init_frac_c >> 5, 0, 19); 65 65 } 66 - static void populate_splformat_from_format(enum spl_pixel_format *spl_pixel_format, const enum pixel_format pixel_format) 66 + static void populate_splformat_from_format(enum spl_pixel_format *spl_pixel_format, 67 + const enum dc_pixel_format pixel_format) 67 68 { 68 69 if (pixel_format < PIXEL_FORMAT_INVALID) 69 70 *spl_pixel_format = (enum spl_pixel_format)pixel_format;
+6 -2
drivers/gpu/drm/amd/display/dc/dc_types.h
··· 1144 1144 1145 1145 union replay_optimization { 1146 1146 struct { 1147 - //BIT[0-3]: Replay Teams Optimization 1147 + //BIT[0-1]: Replay Teams Optimization 1148 1148 unsigned int TEAMS_OPTIMIZATION_VER_1 :1; 1149 1149 unsigned int TEAMS_OPTIMIZATION_VER_2 :1; 1150 - unsigned int RESERVED_2_3 :2; 1150 + //BIT[2]: Replay Live Capture with CVT 1151 + unsigned int LIVE_CAPTURE_WITH_CVT :1; 1152 + unsigned int RESERVED_3 :1; 1151 1153 } bits; 1152 1154 1153 1155 unsigned int raw; ··· 1198 1196 bool frame_skip_supported; 1199 1197 /* Replay Received Frame Skipping Error HPD. */ 1200 1198 bool received_frame_skipping_error_hpd; 1199 + /* Live capture with CVT is activated */ 1200 + bool live_capture_with_cvt_activated; 1201 1201 }; 1202 1202 1203 1203 /* Replay feature flags*/
+1
drivers/gpu/drm/amd/display/dc/dccg/dcn42/dcn42_dccg.h
··· 122 122 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYBSYMCLK_ROOT_GATE_DISABLE, mask_sh),\ 123 123 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYCSYMCLK_ROOT_GATE_DISABLE, mask_sh),\ 124 124 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYDSYMCLK_ROOT_GATE_DISABLE, mask_sh),\ 125 + DCCG_SF(DCCG_GLOBAL_FGCG_REP_CNTL, DCCG_GLOBAL_FGCG_REP_DIS, mask_sh),\ 125 126 DCCG_SFII(OTG, PIXEL_RATE_CNTL, DP_DTO, ENABLE, 0, mask_sh),\ 126 127 DCCG_SFII(OTG, PIXEL_RATE_CNTL, DP_DTO, ENABLE, 1, mask_sh),\ 127 128 DCCG_SFII(OTG, PIXEL_RATE_CNTL, DP_DTO, ENABLE, 2, mask_sh),\
+16 -16
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
··· 202 202 return (num - remainder); 203 203 } 204 204 205 - static unsigned int dml_get_num_active_pipes(int unsigned num_planes, const struct core_display_cfg_support_info *cfg_support_info) 205 + static unsigned int dml_get_num_active_pipes(unsigned int num_planes, const struct core_display_cfg_support_info *cfg_support_info) 206 206 { 207 207 unsigned int num_active_pipes = 0; 208 208 ··· 546 546 return is_vert; 547 547 } 548 548 549 - static int unsigned dml_get_gfx_version(enum dml2_swizzle_mode sw_mode) 549 + static unsigned int dml_get_gfx_version(enum dml2_swizzle_mode sw_mode) 550 550 { 551 - int unsigned version = 0; 551 + unsigned int version = 0; 552 552 553 553 if (sw_mode == dml2_sw_linear || 554 554 sw_mode == dml2_sw_256b_2d || ··· 1761 1761 *p->PixelPTEBytesPerRow = (unsigned int)((double)*p->dpte_row_width_ub / (double)*p->PixelPTEReqWidth * *p->PTERequestSize); 1762 1762 1763 1763 // VBA_DELTA, VBA doesn't have programming value for pte row height linear. 1764 - *p->dpte_row_height_linear = (unsigned int)1 << (unsigned int)math_floor2(math_log((float)(p->PTEBufferSizeInRequests * PixelPTEReqWidth_linear / p->Pitch), 2.0), 1); 1764 + *p->dpte_row_height_linear = 1U << (unsigned int)math_floor2(math_log((float)(p->PTEBufferSizeInRequests * PixelPTEReqWidth_linear / p->Pitch), 2.0), 1); 1765 1765 if (*p->dpte_row_height_linear > 128) 1766 1766 *p->dpte_row_height_linear = 128; 1767 1767 ··· 3377 3377 DML_LOG_VERBOSE("DML::%s: cursor_bytes_per_line = %d\n", __func__, *cursor_bytes_per_line); 3378 3378 DML_LOG_VERBOSE("DML::%s: cursor_bytes_per_chunk = %d\n", __func__, *cursor_bytes_per_chunk); 3379 3379 DML_LOG_VERBOSE("DML::%s: cursor_bytes = %d\n", __func__, *cursor_bytes); 3380 - DML_LOG_VERBOSE("DML::%s: cursor_pitch = %d\n", __func__, cursor_bpp == 2 ? 256 : (unsigned int)1 << (unsigned int)math_ceil2(math_log((float)cursor_width, 2), 1)); 3380 + DML_LOG_VERBOSE("DML::%s: cursor_pitch = %d\n", __func__, cursor_bpp == 2 ? 256 : 1U << (unsigned int)math_ceil2(math_log((float)cursor_width, 2), 1)); 3381 3381 #endif 3382 3382 } 3383 3383 ··· 12205 12205 { 12206 12206 double refclk_freq_in_mhz = (display_cfg->overrides.hw.dlg_ref_clk_mhz > 0) ? (double)display_cfg->overrides.hw.dlg_ref_clk_mhz : mode_lib->soc.dchub_refclk_mhz; 12207 12207 12208 - wm_regs->fclk_pstate = (int unsigned)(mode_lib->mp.Watermark.FCLKChangeWatermark * refclk_freq_in_mhz); 12209 - wm_regs->sr_enter = (int unsigned)(mode_lib->mp.Watermark.StutterEnterPlusExitWatermark * refclk_freq_in_mhz); 12210 - wm_regs->sr_exit = (int unsigned)(mode_lib->mp.Watermark.StutterExitWatermark * refclk_freq_in_mhz); 12211 - wm_regs->sr_enter_z8 = (int unsigned)(mode_lib->mp.Watermark.Z8StutterEnterPlusExitWatermark * refclk_freq_in_mhz); 12212 - wm_regs->sr_exit_z8 = (int unsigned)(mode_lib->mp.Watermark.Z8StutterExitWatermark * refclk_freq_in_mhz); 12213 - wm_regs->temp_read_or_ppt = (int unsigned)(mode_lib->mp.Watermark.temp_read_or_ppt_watermark_us * refclk_freq_in_mhz); 12214 - wm_regs->uclk_pstate = (int unsigned)(mode_lib->mp.Watermark.DRAMClockChangeWatermark * refclk_freq_in_mhz); 12215 - wm_regs->urgent = (int unsigned)(mode_lib->mp.Watermark.UrgentWatermark * refclk_freq_in_mhz); 12216 - wm_regs->usr = (int unsigned)(mode_lib->mp.Watermark.USRRetrainingWatermark * refclk_freq_in_mhz); 12208 + wm_regs->fclk_pstate = (unsigned int)(mode_lib->mp.Watermark.FCLKChangeWatermark * refclk_freq_in_mhz); 12209 + wm_regs->sr_enter = (unsigned int)(mode_lib->mp.Watermark.StutterEnterPlusExitWatermark * refclk_freq_in_mhz); 12210 + wm_regs->sr_exit = (unsigned int)(mode_lib->mp.Watermark.StutterExitWatermark * refclk_freq_in_mhz); 12211 + wm_regs->sr_enter_z8 = (unsigned int)(mode_lib->mp.Watermark.Z8StutterEnterPlusExitWatermark * refclk_freq_in_mhz); 12212 + wm_regs->sr_exit_z8 = (unsigned int)(mode_lib->mp.Watermark.Z8StutterExitWatermark * refclk_freq_in_mhz); 12213 + wm_regs->temp_read_or_ppt = (unsigned int)(mode_lib->mp.Watermark.temp_read_or_ppt_watermark_us * refclk_freq_in_mhz); 12214 + wm_regs->uclk_pstate = (unsigned int)(mode_lib->mp.Watermark.DRAMClockChangeWatermark * refclk_freq_in_mhz); 12215 + wm_regs->urgent = (unsigned int)(mode_lib->mp.Watermark.UrgentWatermark * refclk_freq_in_mhz); 12216 + wm_regs->usr = (unsigned int)(mode_lib->mp.Watermark.USRRetrainingWatermark * refclk_freq_in_mhz); 12217 12217 wm_regs->refcyc_per_trip_to_mem = (unsigned int)(mode_lib->mp.UrgentLatency * refclk_freq_in_mhz); 12218 12218 wm_regs->refcyc_per_meta_trip_to_mem = (unsigned int)(mode_lib->mp.MetaTripToMemory * refclk_freq_in_mhz); 12219 12219 wm_regs->frac_urg_bw_flip = (unsigned int)(mode_lib->mp.FractionOfUrgentBandwidthImmediateFlip * 1000); ··· 12692 12692 disp_dlg_regs->refcyc_per_vm_req_flip = (unsigned int)(math_pow(2, 23) - 1); 12693 12693 12694 12694 12695 - DML_ASSERT(disp_dlg_regs->dst_y_after_scaler < (unsigned int)8); 12695 + DML_ASSERT(disp_dlg_regs->dst_y_after_scaler < 8U); 12696 12696 DML_ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int)math_pow(2, 13)); 12697 12697 12698 12698 if (disp_dlg_regs->dst_y_per_pte_row_nom_l >= (unsigned int)math_pow(2, 17)) { ··· 13248 13248 13249 13249 out->informative.misc.cstate_max_cap_mode = dml_get_cstate_max_cap_mode(mode_lib); 13250 13250 13251 - out->min_clocks.dcn4x.dpprefclk_khz = (int unsigned)dml_get_global_dppclk_khz(mode_lib); 13251 + out->min_clocks.dcn4x.dpprefclk_khz = (unsigned int)dml_get_global_dppclk_khz(mode_lib); 13252 13252 13253 13253 out->informative.qos.max_active_fclk_change_latency_supported = dml_get_fclk_change_latency(mode_lib); 13254 13254
+1 -1
drivers/gpu/drm/amd/display/dc/dml2_0/dml2_dc_resource_mgmt.c
··· 143 143 { 144 144 int i; 145 145 unsigned int num_found = 0; 146 - unsigned int plane_id_assigned_to_pipe = -1; 146 + unsigned int plane_id_assigned_to_pipe = UINT_MAX; 147 147 148 148 for (i = 0; i < ctx->config.dcn_pipe_count; i++) { 149 149 struct pipe_ctx *pipe = &state->res_ctx.pipe_ctx[i];
+3 -3
drivers/gpu/drm/amd/display/dc/dml2_0/dml2_translation_helper.c
··· 1174 1174 const struct dc_state *context, const struct dml_display_cfg_st *dml_dispcfg, unsigned int stream_id, int plane_index) 1175 1175 { 1176 1176 unsigned int plane_id; 1177 - int i = 0; 1178 - int location = -1; 1177 + unsigned int i = 0; 1178 + unsigned int location = UINT_MAX; 1179 1179 1180 1180 if (!get_plane_id(context->bw_ctx.dml2, context, plane, stream_id, plane_index, &plane_id)) { 1181 1181 ASSERT(false); 1182 - return -1; 1182 + return UINT_MAX; 1183 1183 } 1184 1184 1185 1185 for (i = 0; i < __DML2_WRAPPER_MAX_STREAMS_PLANES__; i++) {
+2 -2
drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp_dscl.c
··· 102 102 } 103 103 } 104 104 105 - static bool dpp1_dscl_is_video_format(enum pixel_format format) 105 + static bool dpp1_dscl_is_video_format(enum dc_pixel_format format) 106 106 { 107 107 if (format >= PIXEL_FORMAT_VIDEO_BEGIN 108 108 && format <= PIXEL_FORMAT_VIDEO_END) ··· 111 111 return false; 112 112 } 113 113 114 - static bool dpp1_dscl_is_420_format(enum pixel_format format) 114 + static bool dpp1_dscl_is_420_format(enum dc_pixel_format format) 115 115 { 116 116 if (format == PIXEL_FORMAT_420BPP8 || 117 117 format == PIXEL_FORMAT_420BPP10)
+2 -2
drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c
··· 94 94 } 95 95 } 96 96 97 - static bool dpp401_dscl_is_video_format(enum pixel_format format) 97 + static bool dpp401_dscl_is_video_format(enum dc_pixel_format format) 98 98 { 99 99 if (format >= PIXEL_FORMAT_VIDEO_BEGIN 100 100 && format <= PIXEL_FORMAT_VIDEO_END) ··· 103 103 return false; 104 104 } 105 105 106 - static bool dpp401_dscl_is_420_format(enum pixel_format format) 106 + static bool dpp401_dscl_is_420_format(enum dc_pixel_format format) 107 107 { 108 108 if (format == PIXEL_FORMAT_420BPP8 || 109 109 format == PIXEL_FORMAT_420BPP10)
+6 -7
drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
··· 680 680 } else { 681 681 build_dsc_enc_caps(dsc, dsc_enc_caps); 682 682 } 683 - 684 - if (dsc->ctx->dc->debug.native422_support) 685 - dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 1; 686 683 } 687 684 688 685 /* Returns 'false' if no intersection was found for at least one capability. ··· 1097 1100 branch_max_throughput_mps = dsc_sink_caps->branch_overall_throughput_0_mps; 1098 1101 break; 1099 1102 case PIXEL_ENCODING_YCBCR422: 1100 - is_dsc_possible = (bool)dsc_common_caps.color_formats.bits.YCBCR_NATIVE_422; 1101 - sink_per_slice_throughput_mps = dsc_sink_caps->throughput_mode_1_mps; 1102 - branch_max_throughput_mps = dsc_sink_caps->branch_overall_throughput_1_mps; 1103 - if (!is_dsc_possible) { 1103 + if (policy.ycbcr422_simple) { 1104 1104 is_dsc_possible = (bool)dsc_common_caps.color_formats.bits.YCBCR_SIMPLE_422; 1105 1105 dsc_cfg->ycbcr422_simple = is_dsc_possible; 1106 1106 sink_per_slice_throughput_mps = dsc_sink_caps->throughput_mode_0_mps; 1107 + } else { 1108 + is_dsc_possible = (bool)dsc_common_caps.color_formats.bits.YCBCR_NATIVE_422; 1109 + sink_per_slice_throughput_mps = dsc_sink_caps->throughput_mode_1_mps; 1110 + branch_max_throughput_mps = dsc_sink_caps->branch_overall_throughput_1_mps; 1107 1111 } 1108 1112 break; 1109 1113 case PIXEL_ENCODING_YCBCR420: ··· 1404 1406 policy->min_target_bpp = 8; 1405 1407 /* DP specs limits to 3 x bpc */ 1406 1408 policy->max_target_bpp = 3 * bpc; 1409 + policy->ycbcr422_simple = true; 1407 1410 break; 1408 1411 case PIXEL_ENCODING_YCBCR420: 1409 1412 /* DP specs limits to 6 */
+1 -1
drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.c
··· 100 100 dsc_enc_caps->color_formats.bits.RGB = 1; 101 101 dsc_enc_caps->color_formats.bits.YCBCR_444 = 1; 102 102 dsc_enc_caps->color_formats.bits.YCBCR_SIMPLE_422 = 1; 103 - dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 0; 103 + dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 1; 104 104 dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_420 = 1; 105 105 106 106 dsc_enc_caps->color_depth.bits.COLOR_DEPTH_8_BPC = 1;
+1 -1
drivers/gpu/drm/amd/display/dc/dsc/dcn35/dcn35_dsc.c
··· 128 128 dsc_enc_caps->color_formats.bits.RGB = 1; 129 129 dsc_enc_caps->color_formats.bits.YCBCR_444 = 1; 130 130 dsc_enc_caps->color_formats.bits.YCBCR_SIMPLE_422 = 1; 131 - dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 0; 131 + dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 1; 132 132 dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_420 = 1; 133 133 134 134 dsc_enc_caps->color_depth.bits.COLOR_DEPTH_8_BPC = 1;
+1 -1
drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c
··· 78 78 dsc_enc_caps->color_formats.bits.RGB = 1; 79 79 dsc_enc_caps->color_formats.bits.YCBCR_444 = 1; 80 80 dsc_enc_caps->color_formats.bits.YCBCR_SIMPLE_422 = 1; 81 - dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 0; 81 + dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 1; 82 82 dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_420 = 1; 83 83 84 84 dsc_enc_caps->color_depth.bits.COLOR_DEPTH_8_BPC = 1;
+49 -14
drivers/gpu/drm/amd/display/dc/hubbub/dcn42/dcn42_hubbub.c
··· 6 6 #include "dcn31/dcn31_hubbub.h" 7 7 #include "dcn32/dcn32_hubbub.h" 8 8 #include "dcn35/dcn35_hubbub.h" 9 + #include "dcn401/dcn401_hubbub.h" 9 10 #include "dcn42/dcn42_hubbub.h" 10 11 #include "dm_services.h" 11 12 #include "reg_helper.h" ··· 430 429 REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL, 431 430 DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, 0, 432 431 DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, !allow); 433 - 434 - if (!allow && hubbub->ctx->dc->debug.disable_stutter) {/*controlled by registry key*/ 435 - REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL, 436 - DCHUBBUB_ARB_ALLOW_DCFCLK_DEEP_SLEEP_FORCE_VALUE, 0, 437 - DCHUBBUB_ARB_ALLOW_DCFCLK_DEEP_SLEEP_FORCE_ENABLE, 1); 438 - REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL, 439 - DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0, 440 - DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1); 441 - } 442 432 } 443 433 static void hubbub42_set_sdp_control(struct hubbub *hubbub, bool dc_control) 444 434 { ··· 486 494 return wm_pending; 487 495 } 488 496 497 + static void hubbub42_set_request_limit(struct hubbub *hubbub, int memory_channel_count, int words_per_channel) 498 + { 499 + struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); 500 + uint32_t request_limit = 96; //MAX(12 * memory_channel_count, 96); 501 + 502 + REG_UPDATE(SDPIF_REQUEST_RATE_LIMIT, SDPIF_REQUEST_RATE_LIMIT, request_limit); 503 + } 504 + 505 + static bool dcn42_program_arbiter(struct hubbub *hubbub, struct dml2_display_arb_regs *arb_regs, 506 + bool safe_to_lower) 507 + { 508 + struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); 509 + 510 + bool wm_pending = false; 511 + uint32_t temp; 512 + 513 + /* request backpressure and outstanding return threshold (unused)*/ 514 + //REG_UPDATE(DCHUBBUB_TIMEOUT_DETECTION_CTRL1, DCHUBBUB_TIMEOUT_REQ_STALL_THRESHOLD, arb_regs->req_stall_threshold); 515 + 516 + /* 401 delta: do not update P-State stall threshold (handled by fw) */ 517 + // REG_UPDATE(DCHUBBUB_TIMEOUT_DETECTION_CTRL2, DCHUBBUB_TIMEOUT_PSTATE_STALL_THRESHOLD, arb_regs->pstate_stall_threshold); 518 + 519 + if (safe_to_lower || arb_regs->allow_sdpif_rate_limit_when_cstate_req > hubbub2->allow_sdpif_rate_limit_when_cstate_req) { 520 + hubbub2->allow_sdpif_rate_limit_when_cstate_req = arb_regs->allow_sdpif_rate_limit_when_cstate_req; 521 + 522 + /* only update the required bits */ 523 + REG_GET(DCHUBBUB_CTRL_STATUS, DCHUBBUB_HW_DEBUG, &temp); 524 + if (hubbub2->allow_sdpif_rate_limit_when_cstate_req) { 525 + temp |= (1 << 5); 526 + } else { 527 + temp &= ~(1 << 5); 528 + } 529 + REG_UPDATE(DCHUBBUB_CTRL_STATUS, DCHUBBUB_HW_DEBUG, temp); 530 + } else { 531 + wm_pending = true; 532 + } 533 + 534 + return wm_pending; 535 + } 536 + 489 537 static const struct hubbub_funcs hubbub42_funcs = { 490 538 .update_dchub = hubbub2_update_dchub, 491 539 .init_dchub_sys_ctx = hubbub31_init_dchub_sys_ctx, ··· 541 509 .force_wm_propagate_to_pipes = hubbub32_force_wm_propagate_to_pipes, 542 510 .force_pstate_change_control = hubbub3_force_pstate_change_control, 543 511 .init_watermarks = hubbub35_init_watermarks, 544 - .program_det_size = dcn32_program_det_size, 545 - .program_compbuf_size = dcn35_program_compbuf_size, 546 - .init_crb = dcn35_init_crb, 512 + .init_crb = dcn401_init_crb, 513 + .dchvm_init = dcn35_dchvm_init, 547 514 .hubbub_read_state = hubbub2_read_state, 548 515 .force_usr_retraining_allow = hubbub32_force_usr_retraining_allow, 549 - .dchubbub_init = hubbub35_init, 550 - .dchvm_init = dcn35_dchvm_init, 516 + .set_request_limit = hubbub42_set_request_limit, 517 + .program_det_segments = dcn401_program_det_segments, 518 + .program_compbuf_segments = dcn401_program_compbuf_segments, 519 + .wait_for_det_update = dcn401_wait_for_det_update, 520 + .program_arbiter = dcn42_program_arbiter, 521 + .hubbub_read_reg_state = hubbub3_read_reg_state 551 522 }; 552 523 553 524 void hubbub42_construct(struct dcn20_hubbub *hubbub2,
+34 -1
drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.c
··· 245 245 REFCYC_PER_VM_DMDATA, dlg_attr->refcyc_per_vm_dmdata); 246 246 } 247 247 248 + void hubp42_program_requestor( 249 + struct hubp *hubp, 250 + struct dml2_display_rq_regs *rq_regs) 251 + { 252 + struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); 253 + 254 + REG_UPDATE(HUBPRET_CONTROL, 255 + DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address); 256 + REG_SET_4(DCN_EXPANSION_MODE, 0, 257 + DRQ_EXPANSION_MODE, rq_regs->drq_expansion_mode, 258 + PRQ_EXPANSION_MODE, rq_regs->prq_expansion_mode, 259 + MRQ_EXPANSION_MODE, rq_regs->mrq_expansion_mode, 260 + CRQ_EXPANSION_MODE, rq_regs->crq_expansion_mode); 261 + REG_SET_8(DCHUBP_REQ_SIZE_CONFIG, 0, 262 + CHUNK_SIZE, rq_regs->rq_regs_l.chunk_size, 263 + MIN_CHUNK_SIZE, rq_regs->rq_regs_l.min_chunk_size, 264 + META_CHUNK_SIZE, rq_regs->rq_regs_l.meta_chunk_size, 265 + MIN_META_CHUNK_SIZE, rq_regs->rq_regs_l.min_meta_chunk_size, 266 + DPTE_GROUP_SIZE, rq_regs->rq_regs_l.dpte_group_size, 267 + VM_GROUP_SIZE, rq_regs->rq_regs_l.mpte_group_size, 268 + SWATH_HEIGHT, rq_regs->rq_regs_l.swath_height, 269 + PTE_ROW_HEIGHT_LINEAR, rq_regs->rq_regs_l.pte_row_height_linear); 270 + REG_SET_7(DCHUBP_REQ_SIZE_CONFIG_C, 0, 271 + CHUNK_SIZE_C, rq_regs->rq_regs_c.chunk_size, 272 + MIN_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_chunk_size, 273 + META_CHUNK_SIZE_C, rq_regs->rq_regs_c.meta_chunk_size, 274 + MIN_META_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_meta_chunk_size, 275 + DPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.dpte_group_size, 276 + SWATH_HEIGHT_C, rq_regs->rq_regs_c.swath_height, 277 + PTE_ROW_HEIGHT_LINEAR_C, rq_regs->rq_regs_c.pte_row_height_linear); 278 + } 279 + 280 + 248 281 void hubp42_setup( 249 282 struct hubp *hubp, 250 283 struct dml2_dchub_per_pipe_register_set *pipe_regs, ··· 288 255 * disable the requestors is not needed 289 256 */ 290 257 hubp401_vready_at_or_After_vsync(hubp, pipe_global_sync, timing); 291 - hubp401_program_requestor(hubp, &pipe_regs->rq_regs); 258 + hubp42_program_requestor(hubp, &pipe_regs->rq_regs); 292 259 hubp42_program_deadline(hubp, &pipe_regs->dlg_regs, &pipe_regs->ttu_regs); 293 260 } 294 261 static void hubp42_program_surface_config(
+6
drivers/gpu/drm/amd/display/dc/hubp/dcn42/dcn42_hubp.h
··· 48 48 HUBP_SF(CURSOR0_0_HUBP_3DLUT_ADDRESS_LOW, HUBP_3DLUT_ADDRESS_LOW, mask_sh),\ 49 49 HUBP_SF(CURSOR0_0_HUBP_3DLUT_DLG_PARAM, REFCYC_PER_3DLUT_GROUP, mask_sh) 50 50 51 + struct dml2_display_rq_regs; 52 + 51 53 bool hubp42_construct( 52 54 struct dcn20_hubp *hubp2, 53 55 struct dc_context *ctx, ··· 65 63 const struct dc_3dlut_dma *config); 66 64 67 65 void hubp42_read_state(struct hubp *hubp); 66 + 67 + void hubp42_program_requestor( 68 + struct hubp *hubp, 69 + struct dml2_display_rq_regs *rq_regs); 68 70 69 71 void hubp42_setup( 70 72 struct hubp *hubp,
+11 -6
drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
··· 757 757 { 758 758 struct dc_clocks *clocks = &dc->current_state->bw_ctx.bw.dcn.clk; 759 759 760 + if (!dc->clk_mgr || !dc->clk_mgr->bw_params || !dc->clk_mgr->funcs) 761 + return; 762 + 760 763 clocks->dcfclk_deep_sleep_khz = DCN3_2_DCFCLK_DS_INIT_KHZ; 761 764 clocks->dcfclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dcfclk_mhz * 1000; 762 765 clocks->socclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].socclk_mhz * 1000; ··· 768 765 clocks->ref_dtbclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dtbclk_mhz * 1000; 769 766 clocks->fclk_p_state_change_support = true; 770 767 clocks->p_state_change_support = true; 768 + 771 769 if (dc->debug.disable_boot_optimizations) { 772 770 clocks->dispclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dispclk_mhz * 1000; 773 - } else { 771 + } else if (dc->clk_mgr->funcs->get_dispclk_from_dentist) { 774 772 /* Even though DPG_EN = 1 for the connected display, it still requires the 775 773 * correct timing so we cannot set DISPCLK to min freq or it could cause 776 774 * audio corruption. Read current DISPCLK from DENTIST and request the same ··· 780 776 clocks->dispclk_khz = dc->clk_mgr->funcs->get_dispclk_from_dentist(dc->clk_mgr); 781 777 } 782 778 783 - dc->clk_mgr->funcs->update_clocks( 784 - dc->clk_mgr, 785 - dc->current_state, 786 - true); 779 + if (dc->clk_mgr->funcs->update_clocks) 780 + dc->clk_mgr->funcs->update_clocks(dc->clk_mgr, 781 + dc->current_state, 782 + true); 787 783 } 788 784 789 785 void dcn32_init_hw(struct dc *dc) ··· 1011 1007 DMUB_FW_VERSION(7, 0, 35)) { 1012 1008 /* FAMS2 is disabled */ 1013 1009 dc->debug.fams2_config.bits.enable = false; 1014 - if (dc->debug.using_dml2 && dc->res_pool->funcs->update_bw_bounding_box) { 1010 + if (dc->debug.using_dml2 && dc->res_pool->funcs->update_bw_bounding_box && 1011 + dc->clk_mgr && dc->clk_mgr->bw_params) { 1015 1012 /* update bounding box if FAMS2 disabled */ 1016 1013 dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params); 1017 1014 }
+63 -43
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
··· 369 369 } 370 370 } 371 371 372 - void dcn401_trigger_3dlut_dma_load(struct dc *dc, struct pipe_ctx *pipe_ctx) 372 + void dcn401_trigger_3dlut_dma_load(struct pipe_ctx *pipe_ctx) 373 373 { 374 - struct hubp *hubp = pipe_ctx->plane_res.hubp; 374 + const struct pipe_ctx *primary_dpp_pipe_ctx = resource_get_primary_dpp_pipe(pipe_ctx); 375 + struct hubp *primary_hubp = primary_dpp_pipe_ctx ? 376 + primary_dpp_pipe_ctx->plane_res.hubp : NULL; 375 377 376 - if (hubp->funcs->hubp_enable_3dlut_fl) { 377 - hubp->funcs->hubp_enable_3dlut_fl(hubp, true); 378 + if (primary_hubp && primary_hubp->funcs->hubp_enable_3dlut_fl) { 379 + primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true); 378 380 } 379 381 } 380 382 ··· 384 382 const struct dc_plane_state *plane_state) 385 383 { 386 384 struct dc *dc = pipe_ctx->plane_res.hubp->ctx->dc; 385 + const struct pipe_ctx *primary_dpp_pipe_ctx = resource_get_primary_dpp_pipe(pipe_ctx); 387 386 struct dpp *dpp_base = pipe_ctx->plane_res.dpp; 388 387 struct hubp *hubp = pipe_ctx->plane_res.hubp; 388 + struct hubp *primary_hubp = primary_dpp_pipe_ctx ? 389 + primary_dpp_pipe_ctx->plane_res.hubp : NULL; 389 390 const struct dc_plane_cm *cm = &plane_state->cm; 390 391 int mpcc_id = hubp->inst; 391 392 struct mpc *mpc = dc->res_pool->mpc; ··· 486 481 mpc->funcs->program_lut_read_write_control(mpc, MCM_LUT_3DLUT, lut_bank_a, 12, mpcc_id); 487 482 488 483 if (mpc->funcs->update_3dlut_fast_load_select) 489 - mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, hubp->inst); 484 + mpc->funcs->update_3dlut_fast_load_select(mpc, mpcc_id, primary_hubp->inst); 490 485 491 486 /* HUBP */ 492 - if (hubp->funcs->hubp_program_3dlut_fl_config) 493 - hubp->funcs->hubp_program_3dlut_fl_config(hubp, &cm->lut3d_dma); 487 + if (primary_hubp->inst == hubp->inst) { 488 + /* only program if this is the primary dpp pipe for the given plane */ 489 + if (hubp->funcs->hubp_program_3dlut_fl_config) 490 + hubp->funcs->hubp_program_3dlut_fl_config(hubp, &cm->lut3d_dma); 494 491 495 - if (hubp->funcs->hubp_program_3dlut_fl_crossbar) 496 - hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp, cm->lut3d_dma.format); 492 + if (hubp->funcs->hubp_program_3dlut_fl_crossbar) 493 + hubp->funcs->hubp_program_3dlut_fl_crossbar(hubp, cm->lut3d_dma.format); 497 494 498 - if (hubp->funcs->hubp_program_3dlut_fl_addr) 499 - hubp->funcs->hubp_program_3dlut_fl_addr(hubp, &cm->lut3d_dma.addr); 495 + if (hubp->funcs->hubp_program_3dlut_fl_addr) 496 + hubp->funcs->hubp_program_3dlut_fl_addr(hubp, &cm->lut3d_dma.addr); 500 497 501 - if (hubp->funcs->hubp_enable_3dlut_fl) { 502 - hubp->funcs->hubp_enable_3dlut_fl(hubp, true); 498 + if (hubp->funcs->hubp_enable_3dlut_fl) { 499 + hubp->funcs->hubp_enable_3dlut_fl(hubp, true); 500 + } else { 501 + /* GPU memory only supports fast load path */ 502 + BREAK_TO_DEBUGGER(); 503 + lut_enable = false; 504 + result = false; 505 + } 503 506 } else { 504 - /* GPU memory only supports fast load path */ 505 - BREAK_TO_DEBUGGER(); 506 - lut_enable = false; 507 - result = false; 507 + /* re-trigger priamry HUBP to load 3DLUT */ 508 + if (primary_hubp->funcs->hubp_enable_3dlut_fl) { 509 + primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true); 510 + } 511 + 512 + /* clear FL setup on this pipe's HUBP */ 513 + memset(&lut3d_dma, 0, sizeof(lut3d_dma)); 514 + if (hubp->funcs->hubp_program_3dlut_fl_config) 515 + hubp->funcs->hubp_program_3dlut_fl_config(hubp, &lut3d_dma); 516 + 517 + if (hubp->funcs->hubp_enable_3dlut_fl) 518 + hubp->funcs->hubp_enable_3dlut_fl(hubp, false); 508 519 } 509 520 } else { 510 521 /* Legacy (Host) Load Mode */ ··· 1830 1809 * This is meant to work around a known HW issue where VREADY will cancel the pending 3DLUT_ENABLE signal regardless 1831 1810 * of whether OTG lock is currently being held or not. 1832 1811 */ 1833 - struct pipe_ctx *wa_pipes[MAX_PIPES] = { NULL }; 1834 - struct pipe_ctx *odm_pipe, *mpc_pipe; 1835 - int i, wa_pipe_ct = 0; 1812 + const struct pipe_ctx *otg_master_pipe_ctx = resource_get_otg_master(pipe_ctx); 1813 + struct timing_generator *tg = otg_master_pipe_ctx ? 1814 + otg_master_pipe_ctx->stream_res.tg : NULL; 1815 + const struct pipe_ctx *primary_dpp_pipe_ctx = resource_is_pipe_type(pipe_ctx, DPP_PIPE) ? 1816 + resource_get_primary_dpp_pipe(pipe_ctx) : pipe_ctx; 1817 + struct hubp *primary_hubp = primary_dpp_pipe_ctx ? 1818 + primary_dpp_pipe_ctx->plane_res.hubp : NULL; 1836 1819 1837 - for (odm_pipe = pipe_ctx; odm_pipe != NULL; odm_pipe = odm_pipe->next_odm_pipe) { 1838 - for (mpc_pipe = odm_pipe; mpc_pipe != NULL; mpc_pipe = mpc_pipe->bottom_pipe) { 1839 - if (mpc_pipe->plane_state && 1840 - mpc_pipe->plane_state->cm.flags.bits.lut3d_enable && 1841 - mpc_pipe->plane_state->cm.flags.bits.lut3d_dma_enable) { 1842 - wa_pipes[wa_pipe_ct++] = mpc_pipe; 1843 - } 1844 - } 1820 + if (!otg_master_pipe_ctx && !tg) { 1821 + return; 1845 1822 } 1846 1823 1847 - if (wa_pipe_ct > 0) { 1848 - if (pipe_ctx->stream_res.tg->funcs->set_vupdate_keepout) 1849 - pipe_ctx->stream_res.tg->funcs->set_vupdate_keepout(pipe_ctx->stream_res.tg, true); 1824 + if (primary_dpp_pipe_ctx && 1825 + primary_dpp_pipe_ctx->plane_state && 1826 + primary_dpp_pipe_ctx->plane_state->cm.flags.bits.lut3d_enable && 1827 + primary_dpp_pipe_ctx->plane_state->cm.flags.bits.lut3d_dma_enable) { 1828 + if (tg->funcs->set_vupdate_keepout) 1829 + tg->funcs->set_vupdate_keepout(tg, true); 1850 1830 1851 - for (i = 0; i < wa_pipe_ct; ++i) { 1852 - if (wa_pipes[i]->plane_res.hubp->funcs->hubp_enable_3dlut_fl) 1853 - wa_pipes[i]->plane_res.hubp->funcs->hubp_enable_3dlut_fl(wa_pipes[i]->plane_res.hubp, true); 1831 + if (primary_hubp->funcs->hubp_enable_3dlut_fl) { 1832 + primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true); 1854 1833 } 1855 1834 1856 - pipe_ctx->stream_res.tg->funcs->unlock(pipe_ctx->stream_res.tg); 1857 - if (pipe_ctx->stream_res.tg->funcs->wait_update_lock_status) 1858 - pipe_ctx->stream_res.tg->funcs->wait_update_lock_status(pipe_ctx->stream_res.tg, false); 1835 + tg->funcs->unlock(tg); 1836 + if (tg->funcs->wait_update_lock_status) 1837 + tg->funcs->wait_update_lock_status(tg, false); 1859 1838 1860 - for (i = 0; i < wa_pipe_ct; ++i) { 1861 - if (wa_pipes[i]->plane_res.hubp->funcs->hubp_enable_3dlut_fl) 1862 - wa_pipes[i]->plane_res.hubp->funcs->hubp_enable_3dlut_fl(wa_pipes[i]->plane_res.hubp, true); 1839 + if (primary_hubp->funcs->hubp_enable_3dlut_fl) { 1840 + primary_hubp->funcs->hubp_enable_3dlut_fl(primary_hubp, true); 1863 1841 } 1864 1842 1865 - if (pipe_ctx->stream_res.tg->funcs->set_vupdate_keepout) 1866 - pipe_ctx->stream_res.tg->funcs->set_vupdate_keepout(pipe_ctx->stream_res.tg, false); 1843 + if (tg->funcs->set_vupdate_keepout) 1844 + tg->funcs->set_vupdate_keepout(tg, false); 1867 1845 } else { 1868 - pipe_ctx->stream_res.tg->funcs->unlock(pipe_ctx->stream_res.tg); 1846 + tg->funcs->unlock(tg); 1869 1847 } 1870 1848 } 1871 1849
+1 -2
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.h
··· 41 41 bool dcn401_set_output_transfer_func(struct dc *dc, 42 42 struct pipe_ctx *pipe_ctx, 43 43 const struct dc_stream_state *stream); 44 - void dcn401_trigger_3dlut_dma_load(struct dc *dc, 45 - struct pipe_ctx *pipe_ctx); 44 + void dcn401_trigger_3dlut_dma_load(struct pipe_ctx *pipe_ctx); 46 45 void dcn401_calculate_dccg_tmds_div_value(struct pipe_ctx *pipe_ctx, 47 46 unsigned int *tmds_div); 48 47 enum dc_status dcn401_enable_stream_timing(
+19 -8
drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c
··· 69 69 int edp_num; 70 70 uint32_t backlight = MAX_BACKLIGHT_LEVEL; 71 71 uint32_t user_level = MAX_BACKLIGHT_LEVEL; 72 + bool dchub_ref_freq_changed; 72 73 int current_dchub_ref_freq = 0; 73 74 74 75 if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->init_clocks) { ··· 204 203 for (i = 0; i < dc->link_count; i++) { 205 204 struct dc_link *link = dc->links[i]; 206 205 207 - if (link->link_enc->funcs->is_dig_enabled && 206 + if (link && link->link_enc && 207 + link->link_enc->funcs->is_dig_enabled && 208 208 link->link_enc->funcs->is_dig_enabled(link->link_enc) && 209 209 hws->funcs.power_down) { 210 210 hws->funcs.power_down(dc); ··· 262 260 if (dc->res_pool->hubbub->funcs->init_crb) 263 261 dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub); 264 262 265 - if (dc->res_pool->hubbub->funcs->set_request_limit && dc->config.sdpif_request_limit_words_per_umc > 0) 266 - dc->res_pool->hubbub->funcs->set_request_limit(dc->res_pool->hubbub, dc->clk_mgr->bw_params->num_channels, dc->config.sdpif_request_limit_words_per_umc); 263 + if (dc->res_pool->hubbub->funcs->set_request_limit && 264 + dc->clk_mgr && dc->clk_mgr->bw_params && 265 + dc->config.sdpif_request_limit_words_per_umc > 0) 266 + dc->res_pool->hubbub->funcs->set_request_limit(dc->res_pool->hubbub, 267 + dc->clk_mgr->bw_params->num_channels, 268 + dc->config.sdpif_request_limit_words_per_umc); 267 269 268 270 // Get DMCUB capabilities 269 271 if (dc->ctx->dmub_srv) { ··· 275 269 dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr; 276 270 dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver > 0; 277 271 dc->caps.dmub_caps.fams_ver = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver; 272 + 273 + /* sw and fw FAMS versions must match for support */ 278 274 dc->debug.fams2_config.bits.enable &= 279 - dc->caps.dmub_caps.fams_ver == dc->debug.fams_version.ver; // sw & fw fams versions must match for support 280 - if ((!dc->debug.fams2_config.bits.enable && dc->res_pool->funcs->update_bw_bounding_box) 281 - || res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000 != current_dchub_ref_freq) { 275 + dc->caps.dmub_caps.fams_ver == dc->debug.fams_version.ver; 276 + dchub_ref_freq_changed = 277 + res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000 != current_dchub_ref_freq; 278 + 279 + if ((!dc->debug.fams2_config.bits.enable || dchub_ref_freq_changed) && 280 + dc->res_pool->funcs->update_bw_bounding_box && 281 + dc->clk_mgr && dc->clk_mgr->bw_params) { 282 282 /* update bounding box if FAMS2 disabled, or if dchub clk has changed */ 283 - if (dc->clk_mgr) 284 - dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params); 283 + dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params); 285 284 } 286 285 } 287 286 if (dc->res_pool->pg_cntl) {
+1 -1
drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
··· 1120 1120 void (*program_output_csc)(struct dc *dc, struct pipe_ctx *pipe_ctx, 1121 1121 enum dc_color_space colorspace, 1122 1122 uint16_t *matrix, int opp_id); 1123 - void (*trigger_3dlut_dma_load)(struct dc *dc, struct pipe_ctx *pipe_ctx); 1123 + void (*trigger_3dlut_dma_load)(struct pipe_ctx *pipe_ctx); 1124 1124 1125 1125 /* VM Related */ 1126 1126 int (*init_sys_ctx)(struct dce_hwseq *hws,
+1 -1
drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
··· 256 256 enum dc_color_space out_color_space; 257 257 enum dc_color_space in_color_space; 258 258 enum dc_color_depth color_depth; 259 - enum pixel_format surface_pixel_format; 259 + enum dc_pixel_format surface_pixel_format; 260 260 enum graphics_csc_adjust_type csc_adjust_type; 261 261 bool force_hw_default; 262 262 };
+1 -1
drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
··· 160 160 struct scaling_ratios ratios; 161 161 struct scl_inits inits; 162 162 struct sharpness_adj sharpness; 163 - enum pixel_format format; 163 + enum dc_pixel_format format; 164 164 struct line_buffer_params lb_params; 165 165 // Below struct holds the scaler values to program hw registers 166 166 struct dscl_prog_data dscl_prog_data;
+5 -4
drivers/gpu/drm/amd/display/dc/pg/dcn42/dcn42_pg_cntl.c
··· 176 176 uint32_t pwr_status = power_on ? 0 : 2; 177 177 uint32_t org_ip_request_cntl; 178 178 bool block_enabled; 179 + bool skip_pg = pg_cntl->ctx->dc->debug.ignore_pg || 180 + pg_cntl->ctx->dc->debug.disable_hubp_power_gate || 181 + pg_cntl->ctx->dc->debug.disable_dpp_power_gate || 182 + pg_cntl->ctx->dc->idle_optimizations_allowed; 179 183 180 - if (pg_cntl->ctx->dc->debug.ignore_pg || 181 - pg_cntl->ctx->dc->debug.disable_hubp_power_gate || 182 - pg_cntl->ctx->dc->debug.disable_dpp_power_gate || 183 - pg_cntl->ctx->dc->idle_optimizations_allowed) 184 + if (skip_pg && !power_on) 184 185 return; 185 186 186 187 block_enabled = pg_cntl42_hubp_dpp_pg_status(pg_cntl, hubp_dpp_inst);
+2 -4
drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
··· 650 650 return &enc110->base; 651 651 } 652 652 653 - if (enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) 654 - return NULL; 655 - 656 653 link_regs_id = 657 654 map_transmitter_id_to_phy_instance(enc_init_data->transmitter); 658 655 ··· 658 661 &link_enc_feature, 659 662 &link_enc_regs[link_regs_id], 660 663 &link_enc_aux_regs[enc_init_data->channel - 1], 661 - &link_enc_hpd_regs[enc_init_data->hpd_source]); 664 + enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ? 665 + NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]); 662 666 return &enc110->base; 663 667 } 664 668
+3 -2
drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c
··· 671 671 kzalloc_obj(struct dce110_link_encoder); 672 672 int link_regs_id; 673 673 674 - if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) 674 + if (!enc110) 675 675 return NULL; 676 676 677 677 link_regs_id = ··· 682 682 &link_enc_feature, 683 683 &link_enc_regs[link_regs_id], 684 684 &link_enc_aux_regs[enc_init_data->channel - 1], 685 - &link_enc_hpd_regs[enc_init_data->hpd_source]); 685 + enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ? 686 + NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]); 686 687 return &enc110->base; 687 688 } 688 689
+3 -2
drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c
··· 632 632 kzalloc_obj(struct dce110_link_encoder); 633 633 int link_regs_id; 634 634 635 - if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) 635 + if (!enc110) 636 636 return NULL; 637 637 638 638 link_regs_id = ··· 643 643 &link_enc_feature, 644 644 &link_enc_regs[link_regs_id], 645 645 &link_enc_aux_regs[enc_init_data->channel - 1], 646 - &link_enc_hpd_regs[enc_init_data->hpd_source]); 646 + enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ? 647 + NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]); 647 648 return &enc110->base; 648 649 } 649 650
+3 -2
drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c
··· 716 716 kzalloc_obj(struct dce110_link_encoder); 717 717 int link_regs_id; 718 718 719 - if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) 719 + if (!enc110) 720 720 return NULL; 721 721 722 722 link_regs_id = ··· 727 727 &link_enc_feature, 728 728 &link_enc_regs[link_regs_id], 729 729 &link_enc_aux_regs[enc_init_data->channel - 1], 730 - &link_enc_hpd_regs[enc_init_data->hpd_source]); 730 + enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ? 731 + NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]); 731 732 732 733 return &enc110->base; 733 734 }
+6 -8
drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
··· 746 746 return &enc110->base; 747 747 } 748 748 749 - if (enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) 750 - return NULL; 751 - 752 749 link_regs_id = 753 750 map_transmitter_id_to_phy_instance(enc_init_data->transmitter); 754 751 755 752 dce60_link_encoder_construct(enc110, 756 - enc_init_data, 757 - &link_enc_feature, 758 - &link_enc_regs[link_regs_id], 759 - &link_enc_aux_regs[enc_init_data->channel - 1], 760 - &link_enc_hpd_regs[enc_init_data->hpd_source]); 753 + enc_init_data, 754 + &link_enc_feature, 755 + &link_enc_regs[link_regs_id], 756 + &link_enc_aux_regs[enc_init_data->channel - 1], 757 + enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ? 758 + NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]); 761 759 return &enc110->base; 762 760 } 763 761
+2 -4
drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
··· 752 752 return &enc110->base; 753 753 } 754 754 755 - if (enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) 756 - return NULL; 757 - 758 755 link_regs_id = 759 756 map_transmitter_id_to_phy_instance(enc_init_data->transmitter); 760 757 ··· 760 763 &link_enc_feature, 761 764 &link_enc_regs[link_regs_id], 762 765 &link_enc_aux_regs[enc_init_data->channel - 1], 763 - &link_enc_hpd_regs[enc_init_data->hpd_source]); 766 + enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ? 767 + NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]); 764 768 return &enc110->base; 765 769 } 766 770
+2
drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
··· 1963 1963 dc->config.use_pipe_ctx_sync_logic = true; 1964 1964 dc->config.disable_hbr_audio_dp2 = true; 1965 1965 1966 + dc->config.no_native422_support = true; 1967 + 1966 1968 /* read VBIOS LTTPR caps */ 1967 1969 { 1968 1970 if (ctx->dc_bios->funcs->get_lttpr_caps) {
+2
drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
··· 1925 1925 dc->caps.color.mpc.ogam_rom_caps.hlg = 0; 1926 1926 dc->caps.color.mpc.ocsc = 1; 1927 1927 1928 + dc->config.no_native422_support = true; 1929 + 1928 1930 /* read VBIOS LTTPR caps */ 1929 1931 { 1930 1932 if (ctx->dc_bios->funcs->get_lttpr_caps) {
+1 -1
drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
··· 1790 1790 } 1791 1791 } 1792 1792 1793 - static int dcn401_get_power_profile(const struct dc_state *context) 1793 + int dcn401_get_power_profile(const struct dc_state *context) 1794 1794 { 1795 1795 int uclk_mhz = context->bw_ctx.bw.dcn.clk.dramclk_khz / 1000; 1796 1796 int dpm_level = 0;
+1
drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h
··· 32 32 33 33 unsigned int dcn401_get_vstartup_for_pipe(struct pipe_ctx *pipe_ctx); 34 34 35 + int dcn401_get_power_profile(const struct dc_state *context); 35 36 /* Following are definitions for run time init of reg offsets */ 36 37 37 38 /* HUBP */
+4 -1
drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c
··· 760 760 .disable_z10 = false, 761 761 .ignore_pg = true, 762 762 .disable_stutter_for_wm_program = true, 763 + .min_deep_sleep_dcfclk_khz = 8000, 763 764 }; 764 765 765 766 static const struct dc_check_config config_defaults = { ··· 1791 1790 .calculate_mall_ways_from_bytes = dcn32_calculate_mall_ways_from_bytes, 1792 1791 .prepare_mcache_programming = dcn42_prepare_mcache_programming, 1793 1792 .build_pipe_pix_clk_params = dcn42_build_pipe_pix_clk_params, 1793 + .get_power_profile = dcn401_get_power_profile, 1794 1794 .get_vstartup_for_pipe = dcn401_get_vstartup_for_pipe, 1795 1795 .get_max_hw_cursor_size = dcn42_get_max_hw_cursor_size, 1796 + .get_default_tiling_info = dcn10_get_default_tiling_info 1796 1797 }; 1797 1798 1798 1799 static uint32_t read_pipe_fuses(struct dc_context *ctx) ··· 2018 2015 dc->config.dcn_override_sharpness_range.hdr_rgb_mid = 1500; 2019 2016 2020 2017 dc->config.use_pipe_ctx_sync_logic = true; 2021 - dc->config.dc_mode_clk_limit_support = true; 2018 + dc->config.dc_mode_clk_limit_support = false; 2022 2019 dc->config.enable_windowed_mpo_odm = true; 2023 2020 /* Use psp mailbox to enable assr */ 2024 2021 dc->config.use_assr_psp_message = true;
+3
drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.h
··· 481 481 SRI_ARR(OPTC_INPUT_CLOCK_CONTROL, ODM, inst), \ 482 482 SRI_ARR(OPTC_DATA_SOURCE_SELECT, ODM, inst), \ 483 483 SRI_ARR(OPTC_INPUT_GLOBAL_CONTROL, ODM, inst), \ 484 + SRI_ARR(OPTC_RSMU_UNDERFLOW, ODM, inst), \ 485 + SRI_ARR(OPTC_UNDERFLOW_THRESHOLD, ODM, inst), \ 484 486 SRI_ARR(CONTROL, VTG, inst), \ 485 487 SRI_ARR(OTG_VERT_SYNC_CONTROL, OTG, inst), \ 486 488 SRI_ARR(OTG_GSL_CONTROL, OTG, inst), \ ··· 586 584 enum dc_validate_mode validate_mode); 587 585 588 586 void dcn42_prepare_mcache_programming(struct dc *dc, struct dc_state *context); 587 + int dcn42_get_power_profile(const struct dc_state *context); 589 588 590 589 #endif /* _DCN42_RESOURCE_H_ */
+8
drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn42/dcn42_soc_and_ip_translator.c
··· 93 93 } 94 94 } 95 95 vmin_limit->dispclk_khz = min(dc_clk_table->entries[0].dispclk_mhz * 1000, vmin_limit->dispclk_khz); 96 + /* dispclk is always fine-grain */ 97 + dml_clk_table->dispclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dispclk_levels >= 2 ? 2 : 1; 98 + dml_clk_table->dispclk.clk_values_khz[0] = 0; 99 + dml_clk_table->dispclk.clk_values_khz[1] = dc_clk_table->entries[dc_clk_table->num_entries_per_clk.num_dispclk_levels - 1].dispclk_mhz * 1000; 96 100 } 97 101 98 102 /* dppclk */ ··· 109 105 dml_clk_table->dppclk.clk_values_khz[i] = 0; 110 106 } 111 107 } 108 + /* dppclk is always fine-grain */ 109 + dml_clk_table->dppclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dppclk_levels >= 2 ? 2 : 1; 110 + dml_clk_table->dppclk.clk_values_khz[0] = 0; 111 + dml_clk_table->dppclk.clk_values_khz[1] = dc_clk_table->entries[dc_clk_table->num_entries_per_clk.num_dppclk_levels - 1].dppclk_mhz * 1000; 112 112 } 113 113 114 114 /* dtbclk */
+1
drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
··· 4437 4437 REPLAY_GENERAL_CMD_VIDEO_CONFERENCING, 4438 4438 REPLAY_GENERAL_CMD_SET_CONTINUOUSLY_RESYNC, 4439 4439 REPLAY_GENERAL_CMD_SET_COASTING_VTOTAL_WITHOUT_FRAME_UPDATE, 4440 + REPLAY_GENERAL_CMD_LIVE_CAPTURE_WITH_CVT, 4440 4441 }; 4441 4442 4442 4443 struct dmub_alpm_auxless_data {
+4 -3
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn42.c
··· 39 39 void dmub_dcn42_enable_dmub_boot_options(struct dmub_srv *dmub, const struct dmub_srv_hw_params *params) 40 40 { 41 41 union dmub_fw_boot_options boot_options = {0}; 42 - union dmub_fw_boot_options cur_boot_options = {0}; 43 42 44 - cur_boot_options = dmub_dcn42_get_fw_boot_option(dmub); 43 + if (!dmub->dpia_supported) { 44 + dmub->dpia_supported = dmub_dcn42_get_fw_boot_option(dmub).bits.enable_dpia; 45 + } 45 46 46 47 boot_options.bits.z10_disable = params->disable_z10; 47 48 boot_options.bits.dpia_supported = params->dpia_supported; 48 - boot_options.bits.enable_dpia = cur_boot_options.bits.enable_dpia && !params->disable_dpia; 49 + boot_options.bits.enable_dpia = dmub->dpia_supported && !params->disable_dpia; 49 50 boot_options.bits.usb4_cm_version = params->usb4_cm_version; 50 51 boot_options.bits.dpia_hpd_int_enable_supported = params->dpia_hpd_int_enable_supported; 51 52 boot_options.bits.power_optimization = params->power_optimization;
+2
drivers/gpu/drm/amd/display/modules/color/color_gamma.c
··· 896 896 uint32_t hw_points_num, 897 897 const struct hw_x_point *coordinate_x) 898 898 { 899 + (void)coordinate_x; 899 900 uint32_t i; 900 901 struct fixed31_32 output; 901 902 struct fixed31_32 *de_pq_table = mod_color_get_table(type_de_pq_table); ··· 1340 1339 const struct dc_gamma *ramp, 1341 1340 struct dividers dividers) 1342 1341 { 1342 + (void)dividers; 1343 1343 uint32_t i; 1344 1344 struct fixed31_32 min = dc_fixpt_zero; 1345 1345 struct fixed31_32 max = dc_fixpt_one;
+6
drivers/gpu/drm/amd/display/modules/freesync/freesync.c
··· 114 114 const struct mod_vrr_params *in_vrr, 115 115 unsigned int v_total) 116 116 { 117 + (void)in_vrr; 117 118 unsigned int duration_in_us = 118 119 (unsigned int)(div64_u64(((unsigned long long)(v_total) 119 120 * 10000) * stream->timing.h_total, ··· 219 218 const struct dc_stream_state *stream, 220 219 struct mod_vrr_params *in_out_vrr) 221 220 { 221 + (void)core_freesync; 222 222 unsigned int v_total = 0; 223 223 unsigned int current_duration_in_us = 224 224 calc_duration_in_us_from_v_total( ··· 294 292 unsigned int last_render_time_in_us, 295 293 struct mod_vrr_params *in_out_vrr) 296 294 { 295 + (void)core_freesync; 297 296 unsigned int inserted_frame_duration_in_us = 0; 298 297 unsigned int mid_point_frames_ceil = 0; 299 298 unsigned int mid_point_frames_floor = 0; ··· 450 447 unsigned int last_render_time_in_us, 451 448 struct mod_vrr_params *in_out_vrr) 452 449 { 450 + (void)core_freesync; 453 451 bool update = false; 454 452 unsigned int max_render_time_in_us = in_out_vrr->max_duration_in_us; 455 453 ··· 549 545 unsigned int max_refresh_in_uhz, 550 546 struct mod_vrr_params *in_vrr) 551 547 { 548 + (void)core_freesync; 552 549 if (in_vrr->state != in_config->state) { 553 550 return true; 554 551 } else if (in_vrr->state == VRR_STATE_ACTIVE_FIXED && ··· 951 946 struct dc_info_packet *infopacket, 952 947 bool pack_sdp_v1_3) 953 948 { 949 + (void)mod_freesync; 954 950 /* SPD info packet for FreeSync 955 951 * VTEM info packet for HdmiVRR 956 952 * Check if Freesync is supported. Return if false. If true,
+1
drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h
··· 501 501 static inline void set_watchdog_in_ms(struct mod_hdcp *hdcp, uint16_t time, 502 502 struct mod_hdcp_output *output) 503 503 { 504 + (void)hdcp; 504 505 output->watchdog_timer_needed = 1; 505 506 output->watchdog_timer_delay = time; 506 507 }
+6
drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_4_2_0_offset.h
··· 9036 9036 // base address: 0x40 9037 9037 #define regODM1_OPTC_INPUT_GLOBAL_CONTROL 0x1ada 9038 9038 #define regODM1_OPTC_INPUT_GLOBAL_CONTROL_BASE_IDX 2 9039 + #define regODM1_OPTC_RSMU_UNDERFLOW 0x1adb 9040 + #define regODM1_OPTC_RSMU_UNDERFLOW_BASE_IDX 2 9039 9041 #define regODM1_OPTC_UNDERFLOW_THRESHOLD 0x1adc 9040 9042 #define regODM1_OPTC_UNDERFLOW_THRESHOLD_BASE_IDX 2 9041 9043 #define regODM1_OPTC_DATA_SOURCE_SELECT 0x1add ··· 9062 9060 // base address: 0x80 9063 9061 #define regODM2_OPTC_INPUT_GLOBAL_CONTROL 0x1aea 9064 9062 #define regODM2_OPTC_INPUT_GLOBAL_CONTROL_BASE_IDX 2 9063 + #define regODM2_OPTC_RSMU_UNDERFLOW 0x1aeb 9064 + #define regODM2_OPTC_RSMU_UNDERFLOW_BASE_IDX 2 9065 9065 #define regODM2_OPTC_UNDERFLOW_THRESHOLD 0x1aec 9066 9066 #define regODM2_OPTC_UNDERFLOW_THRESHOLD_BASE_IDX 2 9067 9067 #define regODM2_OPTC_DATA_SOURCE_SELECT 0x1aed ··· 9088 9084 // base address: 0xc0 9089 9085 #define regODM3_OPTC_INPUT_GLOBAL_CONTROL 0x1afa 9090 9086 #define regODM3_OPTC_INPUT_GLOBAL_CONTROL_BASE_IDX 2 9087 + #define regODM3_OPTC_RSMU_UNDERFLOW 0x1afb 9088 + #define regODM3_OPTC_RSMU_UNDERFLOW_BASE_IDX 2 9091 9089 #define regODM3_OPTC_UNDERFLOW_THRESHOLD 0x1afc 9092 9090 #define regODM3_OPTC_UNDERFLOW_THRESHOLD_BASE_IDX 2 9093 9091 #define regODM3_OPTC_DATA_SOURCE_SELECT 0x1afd
+67
drivers/gpu/drm/amd/include/kgd_pp_interface.h
··· 119 119 PP_ISPXCLK, 120 120 OD_SCLK, 121 121 OD_MCLK, 122 + OD_FCLK, 122 123 OD_VDDC_CURVE, 123 124 OD_RANGE, 124 125 OD_VDDGFX_OFFSET, ··· 209 208 enum PP_OD_DPM_TABLE_COMMAND { 210 209 PP_OD_EDIT_SCLK_VDDC_TABLE, 211 210 PP_OD_EDIT_MCLK_VDDC_TABLE, 211 + PP_OD_EDIT_FCLK_TABLE, 212 212 PP_OD_EDIT_CCLK_VDDC_TABLE, 213 213 PP_OD_EDIT_VDDC_CURVE, 214 214 PP_OD_RESTORE_DEFAULT_TABLE, ··· 587 585 AMDGPU_METRICS_ATTR_ID_GFX_LOW_UTILIZATION_ACC, 588 586 AMDGPU_METRICS_ATTR_ID_GFX_BELOW_HOST_LIMIT_TOTAL_ACC, 589 587 AMDGPU_METRICS_ATTR_ID_TEMPERATURE_HBM, 588 + AMDGPU_METRICS_ATTR_ID_TEMPERATURE_MID, 590 589 AMDGPU_METRICS_ATTR_ID_TEMPERATURE_AID, 591 590 AMDGPU_METRICS_ATTR_ID_TEMPERATURE_XCD, 591 + AMDGPU_METRICS_ATTR_ID_LABEL_VERSION, 592 + AMDGPU_METRICS_ATTR_ID_NODE_ID, 593 + AMDGPU_METRICS_ATTR_ID_NODE_TEMP_RETIMER, 594 + AMDGPU_METRICS_ATTR_ID_NODE_TEMP_IBC, 595 + AMDGPU_METRICS_ATTR_ID_NODE_TEMP_IBC_2, 596 + AMDGPU_METRICS_ATTR_ID_NODE_TEMP_VDD18_VR, 597 + AMDGPU_METRICS_ATTR_ID_NODE_TEMP_04_HBM_B_VR, 598 + AMDGPU_METRICS_ATTR_ID_NODE_TEMP_04_HBM_D_VR, 599 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDCR_SOCIO_A, 600 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDCR_SOCIO_C, 601 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDCR_X0, 602 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDCR_X1, 603 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDIO_HBM_B, 604 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDIO_HBM_D, 605 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDIO_04_HBM_B, 606 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDIO_04_HBM_D, 607 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDCR_HBM_B, 608 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDCR_HBM_D, 609 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDCR_075_HBM_B, 610 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDCR_075_HBM_D, 611 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDIO_11_GTA_A, 612 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDIO_11_GTA_C, 613 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDAN_075_GTA_A, 614 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDAN_075_GTA_C, 615 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDCR_075_UCIE, 616 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDIO_065_UCIEAA, 617 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDIO_065_UCIEAM_A, 618 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDIO_065_UCIEAM_C, 619 + AMDGPU_METRICS_ATTR_ID_VR_TEMP_VDDAN_075, 620 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_UBB_FPGA, 621 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_UBB_FRONT, 622 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_UBB_BACK, 623 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_UBB_OAM7, 624 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_UBB_IBC, 625 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_UBB_UFPGA, 626 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_UBB_OAM1, 627 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_OAM_0_1_HSC, 628 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_OAM_2_3_HSC, 629 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_OAM_4_5_HSC, 630 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_OAM_6_7_HSC, 631 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_UBB_FPGA_0V72_VR, 632 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_UBB_FPGA_3V3_VR, 633 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_RETIMER_0_1_2_3_1V2_VR, 634 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_RETIMER_4_5_6_7_1V2_VR, 635 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_RETIMER_0_1_0V9_VR, 636 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_RETIMER_4_5_0V9_VR, 637 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_RETIMER_2_3_0V9_VR, 638 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_RETIMER_6_7_0V9_VR, 639 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_OAM_0_1_2_3_3V3_VR, 640 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_OAM_4_5_6_7_3V3_VR, 641 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_IBC_HSC, 642 + AMDGPU_METRICS_ATTR_ID_SYSTEM_TEMP_IBC, 592 643 AMDGPU_METRICS_ATTR_ID_MAX, 593 644 }; 594 645 ··· 1892 1837 AMDGPU_XGMI_LINK_ACTIVE = 1, 1893 1838 /* Status not available */ 1894 1839 AMDGPU_XGMI_LINK_NA = 2, 1840 + }; 1841 + 1842 + struct amdgpu_gpuboard_temp_metrics_v1_1 { 1843 + struct metrics_table_header common_header; 1844 + int attr_count; 1845 + struct gpu_metrics_attr metrics_attrs[]; 1846 + }; 1847 + 1848 + struct amdgpu_baseboard_temp_metrics_v1_1 { 1849 + struct metrics_table_header common_header; 1850 + int attr_count; 1851 + struct gpu_metrics_attr metrics_attrs[]; 1895 1852 }; 1896 1853 1897 1854 #endif
+11 -7
drivers/gpu/drm/amd/pm/amdgpu_pm.c
··· 680 680 * - minimum(not available for Vega20 and Navi1x) and maximum memory 681 681 * clock labeled OD_MCLK 682 682 * 683 + * - minimum and maximum fabric clock labeled OD_FCLK (SMU13) 684 + * 683 685 * - three <frequency, voltage> points labeled OD_VDDC_CURVE. 684 686 * They can be used to calibrate the sclk voltage curve. This is 685 687 * available for Vega20 and NV1X. ··· 717 715 * - First select manual using power_dpm_force_performance_level 718 716 * 719 717 * - For clock frequency setting, enter a new value by writing a 720 - * string that contains "s/m index clock" to the file. The index 718 + * string that contains "s/m/f index clock" to the file. The index 721 719 * should be 0 if to set minimum clock. And 1 if to set maximum 722 720 * clock. E.g., "s 0 500" will update minimum sclk to be 500 MHz. 723 - * "m 1 800" will update maximum mclk to be 800Mhz. For core 721 + * "m 1 800" will update maximum mclk to be 800Mhz. "f 1 1600" will 722 + * update maximum fabric clock to be 1600Mhz. For core 724 723 * clocks on VanGogh, the string contains "p core index clock". 725 724 * E.g., "p 2 0 800" would set the minimum core clock on core 726 725 * 2 to 800Mhz. ··· 771 768 type = PP_OD_EDIT_CCLK_VDDC_TABLE; 772 769 else if (*buf == 'm') 773 770 type = PP_OD_EDIT_MCLK_VDDC_TABLE; 771 + else if (*buf == 'f') 772 + type = PP_OD_EDIT_FCLK_TABLE; 774 773 else if (*buf == 'r') 775 774 type = PP_OD_RESTORE_DEFAULT_TABLE; 776 775 else if (*buf == 'c') ··· 848 843 struct amdgpu_device *adev = drm_to_adev(ddev); 849 844 int size = 0; 850 845 int ret; 851 - enum pp_clock_type od_clocks[6] = { 846 + enum pp_clock_type od_clocks[] = { 852 847 OD_SCLK, 853 848 OD_MCLK, 849 + OD_FCLK, 854 850 OD_VDDC_CURVE, 855 851 OD_RANGE, 856 852 OD_VDDGFX_OFFSET, ··· 863 857 if (ret) 864 858 return ret; 865 859 866 - for (clk_index = 0 ; clk_index < 6 ; clk_index++) { 867 - ret = amdgpu_dpm_emit_clock_levels(adev, od_clocks[clk_index], buf, &size); 868 - if (ret) 869 - break; 860 + for (clk_index = 0 ; clk_index < ARRAY_SIZE(od_clocks) ; clk_index++) { 861 + amdgpu_dpm_emit_clock_levels(adev, od_clocks[clk_index], buf, &size); 870 862 } 871 863 872 864 if (size == 0)
+8
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
··· 47 47 #include "smu_v14_0_0_ppt.h" 48 48 #include "smu_v14_0_2_ppt.h" 49 49 #include "smu_v15_0_0_ppt.h" 50 + #include "smu_v15_0_8_ppt.h" 50 51 #include "amd_pcie.h" 51 52 52 53 /* ··· 802 801 break; 803 802 case IP_VERSION(15, 0, 0): 804 803 smu_v15_0_0_set_ppt_funcs(smu); 804 + break; 805 + case IP_VERSION(15, 0, 8): 806 + smu_v15_0_8_set_ppt_funcs(smu); 807 + smu->od_enabled = true; 805 808 break; 806 809 default: 807 810 return -EINVAL; ··· 2970 2965 case IP_VERSION(11, 0, 11): 2971 2966 case IP_VERSION(11, 0, 12): 2972 2967 case IP_VERSION(11, 0, 13): 2968 + case IP_VERSION(15, 0, 8): 2973 2969 ret = smu_get_asic_power_limits(smu, 2974 2970 &smu->current_power_limit, 2975 2971 NULL, NULL, NULL); ··· 3062 3056 clk_type = SMU_OD_SCLK; break; 3063 3057 case OD_MCLK: 3064 3058 clk_type = SMU_OD_MCLK; break; 3059 + case OD_FCLK: 3060 + clk_type = SMU_OD_FCLK; break; 3065 3061 case OD_VDDC_CURVE: 3066 3062 clk_type = SMU_OD_VDDC_CURVE; break; 3067 3063 case OD_RANGE:
+295
drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu15_driver_if_v15_0_8.h
··· 1 + /* 2 + * Copyright 2025 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 SMU_15_0_8_DRIVER_IF_H 24 + #define SMU_15_0_8_DRIVER_IF_H 25 + 26 + //I2C Interface 27 + #define NUM_I2C_CONTROLLERS 8 28 + #define I2C_CONTROLLER_ENABLED 1 29 + #define I2C_CONTROLLER_DISABLED 0 30 + 31 + #define MAX_SW_I2C_COMMANDS 24 32 + 33 + typedef enum { 34 + I2C_CONTROLLER_PORT_0, 35 + I2C_CONTROLLER_PORT_COUNT, 36 + } I2cControllerPort_e; 37 + 38 + typedef enum { 39 + /* 50 Kbits/s not supported anymore! */ 40 + UNSUPPORTED_1, 41 + /* 100 Kbits/s */ 42 + I2C_SPEED_STANDARD_100K, 43 + /* 400 Kbits/s */ 44 + I2C_SPEED_FAST_400K, 45 + /* 1 Mbits/s (in fast mode) */ 46 + I2C_SPEED_FAST_PLUS_1M, 47 + /* 1 Mbits/s (in high speed mode) not supported anymore!*/ 48 + UNSUPPORTED_2, 49 + /* 2.3 Mbits/s not supported anymore! */ 50 + UNSUPPORTED_3, 51 + I2C_SPEED_COUNT, 52 + } I2cSpeed_e; 53 + 54 + typedef enum { 55 + I2C_CMD_READ, 56 + I2C_CMD_WRITE, 57 + I2C_CMD_COUNT, 58 + } I2cCmdType_e; 59 + 60 + #define CMDCONFIG_STOP_BIT 0 61 + #define CMDCONFIG_RESTART_BIT 1 62 + /* bit should be 0 for read, 1 for write */ 63 + #define CMDCONFIG_READWRITE_BIT 2 64 + 65 + #define CMDCONFIG_STOP_MASK (1 << CMDCONFIG_STOP_BIT) 66 + #define CMDCONFIG_RESTART_MASK (1 << CMDCONFIG_RESTART_BIT) 67 + #define CMDCONFIG_READWRITE_MASK (1 << CMDCONFIG_READWRITE_BIT) 68 + 69 + /* 64 Bit register offsets for PPSMC_MSG_McaBankDumpDW, PPSMC_MSG_McaBankCeDumpDW messages 70 + * eg to read MCA_BANK_OFFSET_SYND for CE index, call PPSMC_MSG_McaBankCeDumpDW twice, 71 + * (index << 16 + MCA_BANK_OFFSET_SYND*8) argument for 1st DWORD, and 72 + * ((index << 16 ) + MCA_BANK_OFFSET_SYND*8 + 4) argument for 2nd DWORD */ 73 + typedef enum { 74 + MCA_BANK_OFFSET_CTL = 0, 75 + MCA_BANK_OFFSET_STATUS = 1, 76 + MCA_BANK_OFFSET_ADDR = 2, 77 + MCA_BANK_OFFSET_MISC = 3, 78 + MCA_BANK_OFFSET_IPID = 5, 79 + MCA_BANK_OFFSET_SYND = 6, 80 + MCA_BANK_OFFSET_MAX = 16, 81 + } MCA_BANK_OFFSET_e; 82 + 83 + /* Firmware MP1 AID MCA Error Codes stored in MCA_MP_MP1:MCMP1_SYNDT0 errorinformation */ 84 + typedef enum { 85 + /* MMHUB */ 86 + CODE_DAGB0 = 0, 87 + CODE_DAGB1 = 1, 88 + CODE_DAGB2 = 2, 89 + CODE_DAGB3 = 3, 90 + CODE_DAGB4 = 4, 91 + CODE_EA0 = 5, 92 + CODE_EA1 = 6, 93 + CODE_EA2 = 7, 94 + CODE_EA3 = 8, 95 + CODE_EA4 = 9, 96 + CODE_UTCL2_ROUTER = 10, 97 + CODE_VML2 = 11, 98 + CODE_VML2_WALKER = 12, 99 + CODE_MMCANE = 13, 100 + 101 + /* VCN VCPU */ 102 + CODE_VIDD = 14, 103 + CODE_VIDV = 15, 104 + /* VCN JPEG */ 105 + CODE_JPEG0S = 16, 106 + CODE_JPEG0D = 17, 107 + CODE_JPEG1S = 18, 108 + CODE_JPEG1D = 19, 109 + CODE_JPEG2S = 20, 110 + CODE_JPEG2D = 21, 111 + CODE_JPEG3S = 22, 112 + CODE_JPEG3D = 23, 113 + CODE_JPEG4S = 24, 114 + CODE_JPEG4D = 25, 115 + CODE_JPEG5S = 26, 116 + CODE_JPEG5D = 27, 117 + CODE_JPEG6S = 28, 118 + CODE_JPEG6D = 29, 119 + CODE_JPEG7S = 30, 120 + CODE_JPEG7D = 31, 121 + /* VCN MMSCH */ 122 + CODE_MMSCHD = 32, 123 + 124 + /* SDMA */ 125 + CODE_SDMA0 = 33, 126 + CODE_SDMA1 = 34, 127 + CODE_SDMA2 = 35, 128 + CODE_SDMA3 = 36, 129 + 130 + /* SOC */ 131 + CODE_HDP = 37, 132 + CODE_ATHUB = 38, 133 + CODE_IH = 39, 134 + CODE_XHUB_POISON = 40, 135 + CODE_SMN_SLVERR = 41, 136 + CODE_WDT = 42, 137 + 138 + CODE_UNKNOWN = 43, 139 + CODE_DMA = 44, 140 + CODE_COUNT = 45, 141 + } ERR_CODE_e; 142 + 143 + /* Firmware MP5 XCD MCA Error Codes stored in MCA_MP_MP5:MCMP5_SYNDT0 errorinformation */ 144 + typedef enum { 145 + /* SH POISON FED */ 146 + SH_FED_CODE = 0, 147 + /* GCEA Pin UE_ERR regs */ 148 + GCEA_CODE = 1, 149 + SQ_CODE = 2, 150 + LDS_CODE = 3, 151 + GDS_CODE = 4, 152 + SP0_CODE = 5, 153 + SP1_CODE = 6, 154 + TCC_CODE = 7, 155 + TCA_CODE = 8, 156 + TCX_CODE = 9, 157 + CPC_CODE = 10, 158 + CPF_CODE = 11, 159 + CPG_CODE = 12, 160 + SPI_CODE = 13, 161 + RLC_CODE = 14, 162 + /* GCEA Pin, UE_EDC regs */ 163 + SQC_CODE = 15, 164 + TA_CODE = 16, 165 + TD_CODE = 17, 166 + TCP_CODE = 18, 167 + TCI_CODE = 19, 168 + /* GC Router */ 169 + GC_ROUTER_CODE = 20, 170 + VML2_CODE = 21, 171 + VML2_WALKER_CODE = 22, 172 + ATCL2_CODE = 23, 173 + GC_CANE_CODE = 24, 174 + 175 + /* SOC error codes 41-43 are common with ERR_CODE_e */ 176 + MP5_CODE_SMN_SLVERR = CODE_SMN_SLVERR, 177 + MP5_CODE_UNKNOWN = CODE_UNKNOWN, 178 + } GC_ERROR_CODE_e; 179 + 180 + /* SW I2C Command Table */ 181 + typedef struct { 182 + /* Return data for read. Data to send for write*/ 183 + uint8_t ReadWriteData; 184 + /* Includes whether associated command should have a stop or restart command, 185 + * and is a read or write */ 186 + uint8_t CmdConfig; 187 + } SwI2cCmd_t; 188 + 189 + /* SW I2C Request Table */ 190 + typedef struct { 191 + /* CKSVII2C0(0) or //CKSVII2C1(1) */ 192 + uint8_t I2CcontrollerPort; 193 + /* Use I2cSpeed_e to indicate speed to select */ 194 + uint8_t I2CSpeed; 195 + /* Slave address of device */ 196 + uint8_t SlaveAddress; 197 + /* Number of commands */ 198 + uint8_t NumCmds; 199 + SwI2cCmd_t SwI2cCmds[MAX_SW_I2C_COMMANDS]; 200 + } SwI2cRequest_t; 201 + 202 + typedef struct { 203 + SwI2cRequest_t SwI2cRequest; 204 + uint32_t Spare[8]; 205 + /* SMU internal use */ 206 + uint32_t MmHubPadding[8]; 207 + } SwI2cRequestExternal_t; 208 + 209 + typedef enum { 210 + PPCLK_UCLK, 211 + PPCLK_COUNT, 212 + } PPCLK_e; 213 + 214 + typedef enum { 215 + GPIO_INT_POLARITY_ACTIVE_LOW, 216 + GPIO_INT_POLARITY_ACTIVE_HIGH, 217 + } GpioIntPolarity_e; 218 + 219 + /* TODO confirm if this is used in MI300 PPSMC_MSG_SetUclkDpmMode */ 220 + typedef enum { 221 + UCLK_DPM_MODE_BANDWIDTH, 222 + UCLK_DPM_MODE_LATENCY, 223 + } UCLK_DPM_MODE_e; 224 + 225 + typedef struct { 226 + /* 2 AVFS.PSM chains */ 227 + uint16_t AvgPsmCount_Chain0[13]; 228 + uint16_t AvgPsmCount_Chain1[15]; 229 + uint16_t MinPsmCount_Chain0[13]; 230 + uint16_t MinPsmCount_Chain1[15]; 231 + float MaxTemperature; 232 + 233 + /* For voltage conversions, these are the array indexes 234 + * 0:SOCIO 235 + * 1:065_UCIE 236 + * 2:075_UCIE 237 + * 3:11_GTA 238 + * 4:075_GTA */ 239 + float MinPsmVoltage[5]; 240 + float AvgPsmVoltage[5]; 241 + } AvfsDebugTableMid_t; 242 + 243 + typedef struct { 244 + /* 7 AVFS.PSM chains - not including TRO */ 245 + uint16_t AvgPsmCount_Chain0[15]; 246 + uint16_t AvgPsmCount_Chain1[15]; 247 + uint16_t AvgPsmCount_Chain2[13]; 248 + uint16_t AvgPsmCount_Chain3[13]; 249 + uint16_t AvgPsmCount_Chain4[15]; 250 + uint16_t AvgPsmCount_Chain5[15]; 251 + uint16_t AvgPsmCount_Chain6[5]; 252 + uint16_t MinPsmCount_Chain0[15]; 253 + uint16_t MinPsmCount_Chain1[15]; 254 + uint16_t MinPsmCount_Chain2[13]; 255 + uint16_t MinPsmCount_Chain3[13]; 256 + uint16_t MinPsmCount_Chain4[15]; 257 + uint16_t MinPsmCount_Chain5[15]; 258 + uint16_t MinPsmCount_Chain6[5]; 259 + float MaxTemperature; 260 + 261 + /* For voltage conversions, these are the array indexes 262 + * 0:VDDX */ 263 + float MinPsmVoltage; 264 + float AvgPsmVoltage; 265 + } AvfsDebugTableAid_t; 266 + 267 + typedef struct { 268 + /* 0-27 GFX, 28-29 SOC */ 269 + uint16_t avgPsmCount[30]; 270 + uint16_t minPsmCount[30]; 271 + float avgPsmVoltage[30]; 272 + float minPsmVoltage[30]; 273 + } AvfsDebugTableXcd_t; 274 + 275 + /* Defines used for IH-based thermal interrupts to GFX driver - A/X only */ 276 + #define IH_INTERRUPT_ID_TO_DRIVER 0xFE 277 + #define IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING 0x7 278 + #define IH_INTERRUPT_VFFLR_INT 0xA 279 + 280 + /* thermal over-temp mask defines for IH interrup to host */ 281 + #define THROTTLER_PROCHOT_BIT 0 282 + #define THROTTLER_RESERVED 1 283 + /* AID, XCD, CCD throttling */ 284 + #define THROTTLER_THERMAL_SOCKET_BIT 2 285 + /* VRHOT */ 286 + #define THROTTLER_THERMAL_VR_BIT 3 287 + #define THROTTLER_THERMAL_HBM_BIT 4 288 + /* UEs are always reported, set flag to 0 to prevent clearing of UEs */ 289 + #define ClearMcaOnRead_UE_FLAG_MASK 0x1 290 + /* Enable CE logging and clearing to driver */ 291 + #define ClearMcaOnRead_CE_POLL_MASK 0x2 292 + /* AID MMHUB client IP CE Logging and clearing */ 293 + #define ClearMcaOnRead_MMHUB_POLL_MASK 0x4 294 + 295 + #endif
+427
drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v15_0_8_pmfw.h
··· 1 + /* 2 + * Copyright 2025 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 SMU_15_0_8_PMFW_H 24 + #define SMU_15_0_8_PMFW_H 25 + 26 + #define NUM_VCLK_DPM_LEVELS 4 27 + #define NUM_DCLK_DPM_LEVELS 4 28 + #define NUM_SOCCLK_DPM_LEVELS 4 29 + #define NUM_LCLK_DPM_LEVELS 4 30 + #define NUM_UCLK_DPM_LEVELS 4 31 + #define NUM_FCLK_DPM_LEVELS 4 32 + #define NUM_XGMI_DPM_LEVELS 2 33 + #define NUM_PCIE_BITRATES 4 34 + #define NUM_XGMI_BITRATES 4 35 + #define NUM_XGMI_WIDTHS 3 36 + #define NUM_GFX_P2S_TABLES 8 37 + #define NUM_PSM_DIDT_THRESHOLDS 3 38 + #define NUM_XCD_XVMIN_VMIN_THRESHOLDS 3 39 + 40 + #define PRODUCT_MODEL_NUMBER_LEN 20 41 + #define PRODUCT_NAME_LEN 64 42 + #define PRODUCT_SERIAL_LEN 20 43 + #define PRODUCT_MANUFACTURER_NAME_LEN 32 44 + #define PRODUCT_FRU_ID_LEN 32 45 + 46 + //Feature ID list 47 + #define FEATURE_ID_DATA_CALCULATION 1 48 + #define FEATURE_ID_DPM_FCLK 2 49 + #define FEATURE_ID_DPM_GFXCLK 3 50 + #define FEATURE_ID_DPM_SPARE_4 4 51 + #define FEATURE_ID_DPM_SPARE_5 5 52 + #define FEATURE_ID_DPM_UCLK 6 53 + #define FEATURE_ID_DPM_SPARE_7 7 54 + #define FEATURE_ID_DPM_XGMI 8 55 + #define FEATURE_ID_DS_FCLK 9 56 + #define FEATURE_ID_DS_GFXCLK 10 57 + #define FEATURE_ID_DS_LCLK 11 58 + #define FEATURE_ID_DS_MP0CLK 12 59 + #define FEATURE_ID_DS_MP1CLK 13 60 + #define FEATURE_ID_DS_MPIOCLK 14 61 + #define FEATURE_ID_DS_SOCCLK 15 62 + #define FEATURE_ID_DS_VCN 16 63 + #define FEATURE_ID_PPT 17 64 + #define FEATURE_ID_TDC 18 65 + #define FEATURE_ID_THERMAL 19 66 + #define FEATURE_ID_SOC_PCC 20 67 + #define FEATURE_ID_PROCHOT 21 68 + #define FEATURE_ID_XVMIN0_VMIN_AID 22 69 + #define FEATURE_ID_XVMIN1_DD_AID 23 70 + #define FEATURE_ID_XVMIN0_VMIN_XCD 24 71 + #define FEATURE_ID_XVMIN1_DD_XCD 25 72 + #define FEATURE_ID_FW_CTF 26 73 + #define FEATURE_ID_MGCG 27 74 + #define FEATURE_ID_PSI7 28 75 + #define FEATURE_ID_XGMI_PER_LINK_PWR_DOWN 29 76 + #define FEATURE_ID_SOC_DC_RTC 30 77 + #define FEATURE_ID_GFX_DC_RTC 31 78 + #define FEATURE_ID_DVM_MIN_PSM 32 79 + #define FEATURE_ID_PRC 33 80 + #define FEATURE_ID_PSM_DIDT 34 81 + #define FEATURE_ID_PIT 35 82 + #define FEATURE_ID_DVO 36 83 + #define FEATURE_ID_XVMIN_CLKSTOP_DS 37 84 + #define FEATURE_ID_HBM_THROTTLE_CTRL 38 85 + #define FEATURE_ID_DPM_GL2CLK 39 86 + #define FEATURE_ID_GC_CAC_EDC 40 87 + #define FEATURE_ID_DS_DMABECLK 41 88 + #define FEATURE_ID_DS_MPIFOECLK 42 89 + #define FEATURE_ID_DS_MPRASCLK 43 90 + #define FEATURE_ID_DS_MPNHTCLK 44 91 + #define FEATURE_ID_DS_FIOCLK 45 92 + #define FEATURE_ID_DS_DXIOCLK 46 93 + #define FEATURE_ID_PCC 47 94 + #define FEATURE_ID_OCP 48 95 + #define FEATURE_ID_TRO 49 96 + #define FEATURE_ID_GL2_CAC_EDC 50 97 + #define FEATURE_ID_SPARE_51 51 98 + #define FEATURE_ID_GL2_CGCG 52 99 + #define FEATURE_ID_XCAC 53 100 + #define FEATURE_ID_DS_GL2CLK 54 101 + #define FEATURE_ID_FCS_VIN_PCC 55 102 + #define FEATURE_ID_FCS_VDDX_OCP_WARN 56 103 + #define FEATURE_ID_FCS_PWRBRK 57 104 + #define FEATURE_ID_DF_CSTATE 58 105 + #define FEATURE_ID_ARO 59 106 + #define FEATURE_ID_PS_PsPowerLimit 60 107 + #define FEATURE_ID_PS_PsPowerFloor 61 108 + #define FEATURE_ID_OCPWARNRC 62 109 + #define FEATURE_ID_XGMI_FOLDING 63 110 + #define FEATURE_ID_SMU_CG 64 111 + #define NUM_FEATURES 65 112 + 113 + //MGCG Feature ID List 114 + #define WAFL_CG 0 115 + #define SMU_FUSE_CG_DEEPSLEEP 1 116 + #define SMUIO_CG 2 117 + #define RSMU_MGCG 3 118 + #define SMU_CLK_MGCG 4 119 + #define MP5_CG 5 120 + #define UMC_CG 6 121 + #define WAFL0_CLK 7 122 + #define WAFL1_CLK 8 123 + #define VCN_MGCG 9 124 + #define GL2_MGCG 10 125 + #define MGCG_NUM_FEATURES 11 126 + 127 + /* enum for MPIO PCIe gen speed msgs */ 128 + typedef enum { 129 + PCIE_LINK_SPEED_INDEX_TABLE_GEN1, 130 + PCIE_LINK_SPEED_INDEX_TABLE_GEN2, 131 + PCIE_LINK_SPEED_INDEX_TABLE_GEN3, 132 + PCIE_LINK_SPEED_INDEX_TABLE_GEN4, 133 + PCIE_LINK_SPEED_INDEX_TABLE_GEN5, 134 + PCIE_LINK_SPEED_INDEX_TABLE_GEN6, 135 + PCIE_LINK_SPEED_INDEX_TABLE_GEN6_ESM, 136 + PCIE_LINK_SPEED_INDEX_TABLE_COUNT 137 + } PCIE_LINK_SPEED_INDEX_TABLE_e; 138 + 139 + typedef enum { 140 + GFX_GUARDBAND_OFFSET_0, 141 + GFX_GUARDBAND_OFFSET_1, 142 + GFX_GUARDBAND_OFFSET_2, 143 + GFX_GUARDBAND_OFFSET_3, 144 + GFX_GUARDBAND_OFFSET_4, 145 + GFX_GUARDBAND_OFFSET_5, 146 + GFX_GUARDBAND_OFFSET_6, 147 + GFX_GUARDBAND_OFFSET_7, 148 + GFX_GUARDBAND_OFFSET_COUNT 149 + } GFX_GUARDBAND_OFFSET_e; 150 + 151 + typedef enum { 152 + GFX_DVM_MARGINHI_0, 153 + GFX_DVM_MARGINHI_1, 154 + GFX_DVM_MARGINHI_2, 155 + GFX_DVM_MARGINHI_3, 156 + GFX_DVM_MARGINHI_4, 157 + GFX_DVM_MARGINHI_5, 158 + GFX_DVM_MARGINHI_6, 159 + GFX_DVM_MARGINHI_7, 160 + GFX_DVM_MARGINLO_0, 161 + GFX_DVM_MARGINLO_1, 162 + GFX_DVM_MARGINLO_2, 163 + GFX_DVM_MARGINLO_3, 164 + GFX_DVM_MARGINLO_4, 165 + GFX_DVM_MARGINLO_5, 166 + GFX_DVM_MARGINLO_6, 167 + GFX_DVM_MARGINLO_7, 168 + GFX_DVM_MARGIN_COUNT 169 + } GFX_DVM_MARGIN_e; 170 + 171 + typedef enum{ 172 + SYSTEM_TEMP_UBB_FPGA, 173 + SYSTEM_TEMP_UBB_FRONT, 174 + SYSTEM_TEMP_UBB_BACK, 175 + SYSTEM_TEMP_UBB_OAM7, 176 + SYSTEM_TEMP_UBB_IBC, 177 + SYSTEM_TEMP_UBB_UFPGA, 178 + SYSTEM_TEMP_UBB_OAM1, 179 + SYSTEM_TEMP_OAM_0_1_HSC, 180 + SYSTEM_TEMP_OAM_2_3_HSC, 181 + SYSTEM_TEMP_OAM_4_5_HSC, 182 + SYSTEM_TEMP_OAM_6_7_HSC, 183 + SYSTEM_TEMP_UBB_FPGA_0V72_VR, 184 + SYSTEM_TEMP_UBB_FPGA_3V3_VR, 185 + SYSTEM_TEMP_RETIMER_0_1_2_3_1V2_VR, 186 + SYSTEM_TEMP_RETIMER_4_5_6_7_1V2_VR, 187 + SYSTEM_TEMP_RETIMER_0_1_0V9_VR, 188 + SYSTEM_TEMP_RETIMER_4_5_0V9_VR, 189 + SYSTEM_TEMP_RETIMER_2_3_0V9_VR, 190 + SYSTEM_TEMP_RETIMER_6_7_0V9_VR, 191 + SYSTEM_TEMP_OAM_0_1_2_3_3V3_VR, 192 + SYSTEM_TEMP_OAM_4_5_6_7_3V3_VR, 193 + SYSTEM_TEMP_IBC_HSC, 194 + SYSTEM_TEMP_IBC, 195 + SYSTEM_TEMP_MAX_ENTRIES = 32 196 + } SYSTEM_TEMP_e; 197 + 198 + typedef enum{ 199 + NODE_TEMP_RETIMER, 200 + NODE_TEMP_IBC_TEMP, 201 + NODE_TEMP_IBC_2_TEMP, 202 + NODE_TEMP_VDD18_VR_TEMP, 203 + NODE_TEMP_04_HBM_B_VR_TEMP, 204 + NODE_TEMP_04_HBM_D_VR_TEMP, 205 + NODE_TEMP_MAX_TEMP_ENTRIES = 12 206 + } NODE_TEMP_e; 207 + 208 + typedef enum { 209 + SVI_PLANE_VDDCR_X0_TEMP, 210 + SVI_PLANE_VDDCR_X1_TEMP, 211 + 212 + SVI_PLANE_VDDIO_HBM_B_TEMP, 213 + SVI_PLANE_VDDIO_HBM_D_TEMP, 214 + SVI_PLANE_VDDIO_04_HBM_B_TEMP, 215 + SVI_PLANE_VDDIO_04_HBM_D_TEMP, 216 + SVI_PLANE_VDDCR_HBM_B_TEMP, 217 + SVI_PLANE_VDDCR_HBM_D_TEMP, 218 + SVI_PLANE_VDDCR_075_HBM_B_TEMP, 219 + SVI_PLANE_VDDCR_075_HBM_D_TEMP, 220 + 221 + SVI_PLANE_VDDIO_11_GTA_A_TEMP, 222 + SVI_PLANE_VDDIO_11_GTA_C_TEMP, 223 + SVI_PLANE_VDDAN_075_GTA_A_TEMP, 224 + SVI_PLANE_VDDAN_075_GTA_C_TEMP, 225 + 226 + SVI_PLANE_VDDCR_075_UCIE_TEMP, 227 + SVI_PLANE_VDDIO_065_UCIEAA_TEMP, 228 + SVI_PLANE_VDDIO_065_UCIEAM_A_TEMP, 229 + SVI_PLANE_VDDIO_065_UCIEAM_C_TEMP, 230 + 231 + SVI_PLANE_VDDCR_SOCIO_A_TEMP, 232 + SVI_PLANE_VDDCR_SOCIO_C_TEMP, 233 + 234 + SVI_PLANE_VDDAN_075_TEMP, 235 + SVI_MAX_TEMP_ENTRIES, //22 236 + } SVI_TEMP_e; 237 + 238 + typedef enum{ 239 + SYSTEM_POWER_UBB_POWER, 240 + SYSTEM_POWER_UBB_POWER_THRESHOLD, 241 + SYSTEM_POWER_MAX_ENTRIES_WO_RESERVED, 242 + SYSTEM_POWER_MAX_ENTRIES = 4 243 + } SYSTEM_POWER_e; 244 + 245 + #define SMU_METRICS_TABLE_VERSION 0xF 246 + 247 + typedef struct __attribute__((packed, aligned(4))) { 248 + uint64_t AccumulationCounter; 249 + 250 + //TEMPERATURE 251 + uint32_t MaxSocketTemperature; 252 + uint32_t MaxVrTemperature; 253 + uint32_t HbmTemperature[12]; 254 + uint64_t MaxSocketTemperatureAcc; 255 + uint64_t MaxVrTemperatureAcc; 256 + uint64_t HbmTemperatureAcc[12]; 257 + uint32_t MidTemperature[2]; 258 + uint32_t AidTemperature[2]; 259 + uint32_t XcdTemperature[8]; 260 + 261 + //POWER 262 + uint32_t SocketPowerLimit; 263 + uint32_t SocketPower; 264 + 265 + //ENERGY 266 + uint64_t Timestamp; 267 + uint64_t SocketEnergyAcc; 268 + uint64_t HbmEnergyAcc; 269 + 270 + //FREQUENCY 271 + uint32_t GfxclkFrequencyLimit; 272 + uint32_t FclkFrequency[2]; 273 + uint32_t UclkFrequency[2]; 274 + uint64_t GfxclkFrequencyAcc[8]; 275 + uint32_t GfxclkFrequency[8]; 276 + uint32_t SocclkFrequency[2]; 277 + uint32_t VclkFrequency[4]; 278 + uint32_t DclkFrequency[4]; 279 + uint32_t LclkFrequency[2]; 280 + 281 + //XGMI: 282 + uint32_t XgmiWidth; 283 + uint32_t XgmiBitrate; 284 + uint64_t XgmiReadBandwidthAcc; 285 + uint64_t XgmiWriteBandwidthAcc; 286 + 287 + //ACTIVITY: 288 + uint32_t SocketGfxBusy; 289 + uint32_t DramBandwidthUtilization; 290 + uint64_t SocketGfxBusyAcc; 291 + uint64_t DramBandwidthAcc; 292 + uint32_t MaxDramBandwidth; 293 + uint64_t DramBandwidthUtilizationAcc; 294 + uint64_t PcieBandwidthAcc[2]; 295 + 296 + //THROTTLERS 297 + uint64_t ProchotResidencyAcc; 298 + uint64_t PptResidencyAcc; 299 + uint64_t SocketThmResidencyAcc; 300 + uint64_t VrThmResidencyAcc; 301 + uint64_t HbmThmResidencyAcc; 302 + 303 + //PCIE BW Data and error count 304 + uint32_t PcieBandwidth[2]; 305 + uint64_t PCIeL0ToRecoveryCountAcc; 306 + uint64_t PCIenReplayAAcc; 307 + uint64_t PCIenReplayARolloverCountAcc; 308 + uint64_t PCIeNAKSentCountAcc; 309 + uint64_t PCIeNAKReceivedCountAcc; 310 + uint64_t PCIeOtherEndRecoveryAcc; // The Pcie counter itself is accumulated 311 + 312 + // VCN/JPEG ACTIVITY 313 + uint32_t VcnBusy[4]; 314 + uint32_t JpegBusy[40]; 315 + 316 + // PCIE LINK Speed and width 317 + uint32_t PCIeLinkSpeed; 318 + uint32_t PCIeLinkWidth; 319 + 320 + // PER XCD ACTIVITY 321 + uint32_t GfxBusy[8]; 322 + uint64_t GfxBusyAcc[8]; 323 + 324 + //NVML-Parity: Total App Clock Counter 325 + uint64_t GfxclkBelowHostLimitPptAcc[8]; 326 + uint64_t GfxclkBelowHostLimitThmAcc[8]; 327 + uint64_t GfxclkBelowHostLimitTotalAcc[8]; 328 + uint64_t GfxclkLowUtilizationAcc[8]; 329 + } MetricsTable_t; 330 + 331 + #define SMU_SYSTEM_METRICS_TABLE_VERSION 0x1 332 + 333 + #pragma pack(push, 4) 334 + typedef struct { 335 + uint64_t AccumulationCounter; // Last update timestamp 336 + uint16_t LabelVersion; //Defaults to 0. 337 + uint16_t NodeIdentifier; 338 + int16_t SystemTemperatures[SYSTEM_TEMP_MAX_ENTRIES]; // Signed integer temperature value in Celsius, unused fields are set to 0xFFFF 339 + int16_t NodeTemperatures[NODE_TEMP_MAX_TEMP_ENTRIES]; // Signed integer temperature value in Celsius, unused fields are set to 0xFFFF 340 + int16_t VrTemperatures[SVI_MAX_TEMP_ENTRIES]; // Signed integer temperature value in Celsius, 13 entries, 341 + int16_t spare[7]; 342 + 343 + //NPM: NODE POWER MANAGEMENT 344 + uint32_t NodePowerLimit; 345 + uint32_t NodePower; 346 + uint32_t GlobalPPTResidencyAcc; 347 + 348 + uint16_t SystemPower[SYSTEM_POWER_MAX_ENTRIES]; // UBB Current Power and Power Threshold 349 + } SystemMetricsTable_t; 350 + #pragma pack(pop) 351 + 352 + #define SMU_VF_METRICS_TABLE_VERSION 0x5 353 + 354 + typedef struct __attribute__((packed, aligned(4))) { 355 + uint32_t AccumulationCounter; 356 + uint32_t InstGfxclk_TargFreq; 357 + uint64_t AccGfxclk_TargFreq; 358 + uint64_t AccGfxRsmuDpm_Busy; 359 + uint64_t AccGfxclkBelowHostLimit; 360 + } VfMetricsTable_t; 361 + 362 + /* FRU product information */ 363 + typedef struct __attribute__((aligned(4))) { 364 + uint8_t ModelNumber[PRODUCT_MODEL_NUMBER_LEN]; 365 + uint8_t Name[PRODUCT_NAME_LEN]; 366 + uint8_t Serial[PRODUCT_SERIAL_LEN]; 367 + uint8_t ManufacturerName[PRODUCT_MANUFACTURER_NAME_LEN]; 368 + uint8_t FruId[PRODUCT_FRU_ID_LEN]; 369 + } FRUProductInfo_t; 370 + 371 + #define SMU_STATIC_METRICS_TABLE_VERSION 0x1 372 + 373 + #pragma pack(push, 4) 374 + typedef struct { 375 + //FRU PRODUCT INFO 376 + FRUProductInfo_t ProductInfo; //from i2c 377 + 378 + //POWER 379 + uint32_t MaxSocketPowerLimit; 380 + 381 + //FREQUENCY RANGE 382 + uint32_t MaxGfxclkFrequency; 383 + uint32_t MinGfxclkFrequency; 384 + uint32_t MaxFclkFrequency; 385 + uint32_t MinFclkFrequency; 386 + uint32_t MaxGl2clkFrequency; 387 + uint32_t MinGl2clkFrequency; 388 + uint32_t UclkFrequencyTable[4]; 389 + uint32_t SocclkFrequency; 390 + uint32_t LclkFrequency; 391 + uint32_t VclkFrequency; 392 + uint32_t DclkFrequency; 393 + 394 + //CTF limits 395 + uint32_t CTFLimit_MID; 396 + uint32_t CTFLimit_AID; 397 + uint32_t CTFLimit_XCD; 398 + uint32_t CTFLimit_HBM; 399 + 400 + //Thermal Throttling limits 401 + uint32_t ThermalLimit_MID; 402 + uint32_t ThermalLimit_AID; 403 + uint32_t ThermalLimit_XCD; 404 + uint32_t ThermalLimit_HBM; 405 + 406 + //PSNs 407 + uint64_t PublicSerialNumber_MID[2]; 408 + uint64_t PublicSerialNumber_AID[2]; 409 + uint64_t PublicSerialNumber_XCD[8]; 410 + 411 + //XGMI 412 + uint32_t MaxXgmiWidth; 413 + uint32_t MaxXgmiBitrate; 414 + 415 + // Telemetry 416 + uint32_t InputTelemetryVoltageInmV; 417 + 418 + // General info 419 + uint32_t pldmVersion[2]; 420 + 421 + uint32_t PPT1Max; 422 + uint32_t PPT1Min; 423 + uint32_t PPT1Default; 424 + } StaticMetricsTable_t; 425 + #pragma pack(pop) 426 + 427 + #endif
+100
drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v15_0_8_ppsmc.h
··· 1 + /* 2 + * Copyright 2025 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 SMU_15_0_8_PPSMC_H 24 + #define SMU_15_0_8_PPSMC_H 25 + 26 + /* SMU Response Codes */ 27 + #define PPSMC_Result_OK 0x1 28 + #define PPSMC_Result_Failed 0xFF 29 + #define PPSMC_Result_UnknownCmd 0xFE 30 + #define PPSMC_Result_CmdRejectedPrereq 0xFD 31 + #define PPSMC_Result_CmdRejectedBusy 0xFC 32 + 33 + /* Message Definitions */ 34 + #define PPSMC_MSG_TestMessage 0x1 35 + #define PPSMC_MSG_GetSmuVersion 0x2 36 + #define PPSMC_MSG_GfxDriverReset 0x3 37 + #define PPSMC_MSG_GetDriverIfVersion 0x4 38 + #define PPSMC_MSG_EnableAllSmuFeatures 0x5 39 + #define PPSMC_MSG_GetMetricsVersion 0x6 40 + #define PPSMC_MSG_GetMetricsTable 0x7 41 + #define PPSMC_MSG_GetEnabledSmuFeatures 0x8 42 + #define PPSMC_MSG_SetDriverDramAddr 0x9 //ARG0: low address, ARG1: high address 43 + #define PPSMC_MSG_SetToolsDramAddr 0xA //ARG0: low address, ARG1: high address 44 + //#define PPSMC_MSG_SetSystemVirtualDramAddr 0xB 45 + #define PPSMC_MSG_SetSoftMaxByFreq 0xC 46 + #define PPSMC_MSG_SetPptLimit 0xD 47 + #define PPSMC_MSG_GetPptLimit 0xE 48 + #define PPSMC_MSG_DramLogSetDramAddr 0xF //ARG0: low address, ARG1: high address, ARG2: size 49 + #define PPSMC_MSG_HeavySBR 0x10 50 + #define PPSMC_MSG_DFCstateControl 0x11 51 + #define PPSMC_MSG_GfxDriverResetRecovery 0x12 52 + #define PPSMC_MSG_TriggerVFFLR 0x13 53 + #define PPSMC_MSG_SetSoftMinGfxClk 0x14 54 + #define PPSMC_MSG_SetSoftMaxGfxClk 0x15 55 + #define PPSMC_MSG_PrepareForDriverUnload 0x16 56 + #define PPSMC_MSG_QueryValidMcaCount 0x17 57 + #define PPSMC_MSG_McaBankDumpDW 0x18 58 + #define PPSMC_MSG_ClearMcaOnRead 0x19 59 + #define PPSMC_MSG_QueryValidMcaCeCount 0x1A 60 + #define PPSMC_MSG_McaBankCeDumpDW 0x1B 61 + #define PPSMC_MSG_SelectPLPDMode 0x1C 62 + #define PPSMC_MSG_SetThrottlingPolicy 0x1D 63 + #define PPSMC_MSG_ResetSDMA 0x1E 64 + #define PPSMC_MSG_GetRasTableVersion 0x1F 65 + #define PPSMC_MSG_GetRmaStatus 0x20 66 + #define PPSMC_MSG_GetBadPageCount 0x21 67 + #define PPSMC_MSG_GetBadPageMcaAddress 0x22 68 + #define PPSMC_MSG_GetBadPagePaAddress 0x23 69 + #define PPSMC_MSG_SetTimestamp 0x24 70 + #define PPSMC_MSG_GetTimestamp 0x25 71 + #define PPSMC_MSG_GetRasPolicy 0x26 72 + #define PPSMC_MSG_GetBadPageIpIdLoHi 0x27 73 + #define PPSMC_MSG_EraseRasTable 0x28 74 + #define PPSMC_MSG_GetStaticMetricsTable 0x29 75 + #define PPSMC_MSG_ResetVfArbitersByIndex 0x2A 76 + #define PPSMC_MSG_GetBadPageSeverity 0x2B 77 + #define PPSMC_MSG_GetSystemMetricsTable 0x2C 78 + #define PPSMC_MSG_GetSystemMetricsVersion 0x2D 79 + #define PPSMC_MSG_ResetVCN 0x2E 80 + #define PPSMC_MSG_SetFastPptLimit 0x2F 81 + #define PPSMC_MSG_GetFastPptLimit 0x30 82 + #define PPSMC_MSG_SetSoftMinGl2clk 0x31 83 + #define PPSMC_MSG_SetSoftMaxGl2clk 0x32 84 + #define PPSMC_MSG_SetSoftMinFclk 0x33 85 + #define PPSMC_MSG_SetSoftMaxFclk 0x34 86 + #define PPSMC_Message_Count 0x35 87 + 88 + /* PSMC Reset Types for driver msg argument */ 89 + #define PPSMC_RESET_TYPE_DRIVER_MODE_1_RESET 0x1 90 + #define PPSMC_RESET_TYPE_DRIVER_MODE_2_RESET 0x2 91 + #define PPSMC_RESET_TYPE_DRIVER_MODE_3_RESET 0x3 92 + 93 + /* PLPD modes */ 94 + #define PPSMC_PLPD_MODE_DEFAULT 0x1 95 + #define PPSMC_PLPD_MODE_OPTIMIZED 0x2 96 + 97 + typedef uint32_t PPSMC_Result; 98 + typedef uint32_t PPSMC_MSG; 99 + 100 + #endif
+18 -1
drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h
··· 42 42 __SMU_DUMMY_MAP(SetPptLimit), \ 43 43 __SMU_DUMMY_MAP(SetDriverDramAddrHigh), \ 44 44 __SMU_DUMMY_MAP(SetDriverDramAddrLow), \ 45 + __SMU_DUMMY_MAP(SetDriverDramAddr), \ 45 46 __SMU_DUMMY_MAP(SetToolsDramAddrHigh), \ 46 47 __SMU_DUMMY_MAP(SetToolsDramAddrLow), \ 48 + __SMU_DUMMY_MAP(SetToolsDramAddr), \ 47 49 __SMU_DUMMY_MAP(TransferTableSmu2Dram), \ 48 50 __SMU_DUMMY_MAP(TransferTableDram2Smu), \ 49 51 __SMU_DUMMY_MAP(UseDefaultPPTable), \ ··· 294 292 __SMU_DUMMY_MAP(AllowZstates), \ 295 293 __SMU_DUMMY_MAP(GetSmartShiftStatus), \ 296 294 __SMU_DUMMY_MAP(EnableLSdma), \ 297 - __SMU_DUMMY_MAP(DisableLSdma), 295 + __SMU_DUMMY_MAP(DisableLSdma), \ 296 + __SMU_DUMMY_MAP(InitializeGfx), \ 297 + __SMU_DUMMY_MAP(SetSoftMaxFclk), \ 298 + __SMU_DUMMY_MAP(SetSoftMaxGl2clk), \ 299 + __SMU_DUMMY_MAP(SetSoftMinGl2clk), \ 300 + __SMU_DUMMY_MAP(GetSystemMetricsVersion), 298 301 299 302 #undef __SMU_DUMMY_MAP 300 303 #define __SMU_DUMMY_MAP(type) SMU_MSG_##type ··· 331 324 SMU_OD_CCLK, 332 325 SMU_OD_SCLK, 333 326 SMU_OD_MCLK, 327 + SMU_OD_FCLK, 334 328 SMU_OD_VDDC_CURVE, 335 329 SMU_OD_RANGE, 336 330 SMU_OD_VDDGFX_OFFSET, ··· 342 334 SMU_OD_FAN_MINIMUM_PWM, 343 335 SMU_OD_FAN_ZERO_RPM_ENABLE, 344 336 SMU_OD_FAN_ZERO_RPM_STOP_TEMP, 337 + SMU_GL2CLK, 345 338 SMU_CLK_COUNT, 346 339 }; 347 340 ··· 481 472 __SMU_DUMMY_MAP(GFX_DIDT_XVMIN), \ 482 473 __SMU_DUMMY_MAP(FAN_ABNORMAL), \ 483 474 __SMU_DUMMY_MAP(PIT), \ 475 + __SMU_DUMMY_MAP(DS_DMABECLK), \ 476 + __SMU_DUMMY_MAP(DS_MPIFOECLK), \ 477 + __SMU_DUMMY_MAP(DS_MPRASCLK), \ 478 + __SMU_DUMMY_MAP(DS_MPNHTCLK), \ 479 + __SMU_DUMMY_MAP(DS_FIOCLK), \ 480 + __SMU_DUMMY_MAP(DS_DXIOCLK), \ 481 + __SMU_DUMMY_MAP(DS_GL2CLK), \ 482 + __SMU_DUMMY_MAP(DPM_GL2CLK), \ 484 483 __SMU_DUMMY_MAP(HROM_EN), 485 484 486 485 #undef __SMU_DUMMY_MAP
+21 -34
drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h
··· 41 41 #define smnMP1_FIRMWARE_FLAGS 0x3010024 42 42 #define smnMP1_PUB_CTRL 0x3010d10 43 43 44 - #define MAX_DPM_LEVELS 16 44 + #define SMU15_DRIVER_IF_VERSION_SMU_V15_0_8 0x007D0000 45 + 46 + #define FEATURE_MASK(feature) (1ULL << feature) 47 + 45 48 #define MAX_PCIE_CONF 3 46 49 47 50 #define SMU15_TOOL_SIZE 0x19000 ··· 68 65 uint32_t soc_clock; 69 66 }; 70 67 71 - struct smu_15_0_dpm_clk_level { 72 - bool enabled; 73 - uint32_t value; 74 - }; 75 - 76 - struct smu_15_0_dpm_table { 77 - uint32_t min; /* MHz */ 78 - uint32_t max; /* MHz */ 79 - uint32_t count; 80 - bool is_fine_grained; 81 - struct smu_15_0_dpm_clk_level dpm_levels[MAX_DPM_LEVELS]; 82 - }; 83 - 84 - struct smu_15_0_pcie_table { 85 - uint8_t pcie_gen[MAX_PCIE_CONF]; 86 - uint8_t pcie_lane[MAX_PCIE_CONF]; 87 - uint16_t clk_freq[MAX_PCIE_CONF]; 88 - uint32_t num_of_link_levels; 89 - }; 90 - 91 68 struct smu_15_0_dpm_tables { 92 - struct smu_15_0_dpm_table soc_table; 93 - struct smu_15_0_dpm_table gfx_table; 94 - struct smu_15_0_dpm_table uclk_table; 95 - struct smu_15_0_dpm_table eclk_table; 96 - struct smu_15_0_dpm_table vclk_table; 97 - struct smu_15_0_dpm_table dclk_table; 98 - struct smu_15_0_dpm_table dcef_table; 99 - struct smu_15_0_dpm_table pixel_table; 100 - struct smu_15_0_dpm_table display_table; 101 - struct smu_15_0_dpm_table phy_table; 102 - struct smu_15_0_dpm_table fclk_table; 103 - struct smu_15_0_pcie_table pcie_table; 69 + struct smu_dpm_table soc_table; 70 + struct smu_dpm_table gfx_table; 71 + struct smu_dpm_table uclk_table; 72 + struct smu_dpm_table eclk_table; 73 + struct smu_dpm_table vclk_table; 74 + struct smu_dpm_table dclk_table; 75 + struct smu_dpm_table dcef_table; 76 + struct smu_dpm_table pixel_table; 77 + struct smu_dpm_table display_table; 78 + struct smu_dpm_table phy_table; 79 + struct smu_dpm_table fclk_table; 80 + struct smu_pcie_table pcie_table; 81 + struct smu_dpm_table gl2_table; 104 82 }; 105 83 106 84 struct smu_15_0_dpm_context { 107 85 struct smu_15_0_dpm_tables dpm_tables; 108 86 uint32_t workload_policy_mask; 109 87 uint32_t dcef_min_ds_clk; 88 + uint64_t caps; 89 + uint32_t board_volt; 110 90 }; 111 91 112 92 enum smu_15_0_power_state { ··· 104 118 uint32_t power_source; 105 119 uint8_t in_power_limit_boost_mode; 106 120 enum smu_15_0_power_state power_state; 121 + atomic_t throttle_status; 107 122 }; 108 123 109 124 #if defined(SWSMU_CODE_LAYER_L2) || defined(SWSMU_CODE_LAYER_L3) ··· 184 197 185 198 int smu_v15_0_set_single_dpm_table(struct smu_context *smu, 186 199 enum smu_clk_type clk_type, 187 - struct smu_15_0_dpm_table *single_dpm_table); 200 + struct smu_dpm_table *single_dpm_table); 188 201 189 202 int smu_v15_0_gfx_ulv_control(struct smu_context *smu, 190 203 bool enablement);
-1
drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
··· 262 262 "smu fw program = %d, version = 0x%08x (%d.%d.%d)\n", 263 263 smu->smc_driver_if_version, if_version, 264 264 smu_program, smu_version, smu_major, smu_minor, smu_debug); 265 - dev_info(smu->adev->dev, "SMU driver if version not matched\n"); 266 265 } 267 266 268 267 return ret;
-1
drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c
··· 101 101 "smu fw program = %d, smu fw version = 0x%08x (%d.%d.%d)\n", 102 102 smu->smc_driver_if_version, if_version, 103 103 smu_program, smu_version, smu_major, smu_minor, smu_debug); 104 - dev_info(smu->adev->dev, "SMU driver if version not matched\n"); 105 104 } 106 105 107 106 return ret;
+2
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
··· 2466 2466 pstate_table->uclk_pstate.custom.max = 0; 2467 2467 pstate_table->gfxclk_pstate.custom.min = 0; 2468 2468 pstate_table->gfxclk_pstate.custom.max = 0; 2469 + pstate_table->fclk_pstate.custom.min = 0; 2470 + pstate_table->fclk_pstate.custom.max = 0; 2469 2471 }
+32 -1
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
··· 59 59 60 60 #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c)) 61 61 62 + static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu, 63 + int od_feature_bit, 64 + int32_t *min, int32_t *max); 65 + 62 66 static const struct smu_feature_bits smu_v13_0_0_dpm_features = { 63 67 .bits = { 64 68 SMU_FEATURE_BIT_INIT(FEATURE_DPM_GFXCLK_BIT), ··· 1047 1043 PPTable_t *pptable = smu->smu_table.driver_pptable; 1048 1044 const OverDriveLimits_t * const overdrive_upperlimits = 1049 1045 &pptable->SkuTable.OverDriveLimitsBasicMax; 1046 + int32_t min_value, max_value; 1047 + bool feature_enabled; 1050 1048 1051 - return overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit); 1049 + switch (od_feature_bit) { 1050 + case PP_OD_FEATURE_FAN_CURVE_BIT: 1051 + feature_enabled = !!(overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit)); 1052 + if (feature_enabled) { 1053 + smu_v13_0_0_get_od_setting_limits(smu, PP_OD_FEATURE_FAN_CURVE_TEMP, 1054 + &min_value, &max_value); 1055 + if (!min_value && !max_value) { 1056 + feature_enabled = false; 1057 + goto out; 1058 + } 1059 + 1060 + smu_v13_0_0_get_od_setting_limits(smu, PP_OD_FEATURE_FAN_CURVE_PWM, 1061 + &min_value, &max_value); 1062 + if (!min_value && !max_value) { 1063 + feature_enabled = false; 1064 + goto out; 1065 + } 1066 + } 1067 + break; 1068 + default: 1069 + feature_enabled = !!(overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit)); 1070 + break; 1071 + } 1072 + 1073 + out: 1074 + return feature_enabled; 1052 1075 } 1053 1076 1054 1077 static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu,
+94 -10
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
··· 461 461 smu_v13_0_6_cap_set(smu, SMU_CAP(SDMA_RESET)); 462 462 463 463 if ((pgm == 0 && fw_ver >= 0x00558200) || 464 + (pgm == 4 && fw_ver >= 0x04557100) || 464 465 (pgm == 7 && fw_ver >= 0x07551400)) 465 466 smu_v13_0_6_cap_set(smu, SMU_CAP(VCN_RESET)); 466 467 } ··· 1200 1199 struct smu_dpm_table *gfx_table = &dpm_context->dpm_tables.gfx_table; 1201 1200 struct smu_dpm_table *mem_table = &dpm_context->dpm_tables.uclk_table; 1202 1201 struct smu_dpm_table *soc_table = &dpm_context->dpm_tables.soc_table; 1202 + struct smu_dpm_table *fclk_table = &dpm_context->dpm_tables.fclk_table; 1203 1203 struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; 1204 1204 1205 1205 pstate_table->gfxclk_pstate.min = SMU_DPM_TABLE_MIN(gfx_table); ··· 1217 1215 pstate_table->socclk_pstate.peak = SMU_DPM_TABLE_MAX(soc_table); 1218 1216 pstate_table->socclk_pstate.curr.min = SMU_DPM_TABLE_MIN(soc_table); 1219 1217 pstate_table->socclk_pstate.curr.max = SMU_DPM_TABLE_MAX(soc_table); 1218 + 1219 + pstate_table->fclk_pstate.min = SMU_DPM_TABLE_MIN(fclk_table); 1220 + pstate_table->fclk_pstate.peak = SMU_DPM_TABLE_MAX(fclk_table); 1221 + pstate_table->fclk_pstate.curr.min = SMU_DPM_TABLE_MIN(fclk_table); 1222 + pstate_table->fclk_pstate.curr.max = SMU_DPM_TABLE_MAX(fclk_table); 1223 + pstate_table->fclk_pstate.standard = SMU_DPM_TABLE_MIN(fclk_table); 1220 1224 1221 1225 if (gfx_table->count > SMU_13_0_6_UMD_PSTATE_GFXCLK_LEVEL && 1222 1226 mem_table->count > SMU_13_0_6_UMD_PSTATE_MCLK_LEVEL && ··· 1402 1394 break; 1403 1395 case SMU_OD_MCLK: 1404 1396 if (!smu_v13_0_6_cap_supported(smu, SMU_CAP(SET_UCLK_MAX))) 1405 - return 0; 1397 + return -EOPNOTSUPP; 1406 1398 1407 1399 size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK"); 1408 1400 size += sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMhz\n", 1409 1401 pstate_table->uclk_pstate.curr.min, 1410 1402 pstate_table->uclk_pstate.curr.max); 1411 1403 break; 1404 + case SMU_OD_FCLK: 1405 + if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_FCLK_BIT)) 1406 + return -EOPNOTSUPP; 1412 1407 1408 + size += sysfs_emit_at(buf, size, "%s:\n", "OD_FCLK"); 1409 + size += sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMhz\n", 1410 + pstate_table->fclk_pstate.curr.min, 1411 + pstate_table->fclk_pstate.curr.max); 1412 + break; 1413 1413 case SMU_SCLK: 1414 1414 case SMU_GFXCLK: 1415 1415 single_dpm_table = &(dpm_context->dpm_tables.gfx_table); ··· 2059 2043 int ret = 0; 2060 2044 2061 2045 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK && 2062 - clk_type != SMU_UCLK) 2046 + clk_type != SMU_UCLK && clk_type != SMU_FCLK) 2063 2047 return -EINVAL; 2064 2048 2065 2049 if ((smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) && ··· 2098 2082 smu, SMU_UCLK, 0, max, false); 2099 2083 if (!ret) 2100 2084 pstate_table->uclk_pstate.curr.max = max; 2085 + } 2086 + 2087 + if (clk_type == SMU_FCLK) { 2088 + if (max == pstate_table->fclk_pstate.curr.max) 2089 + return 0; 2090 + 2091 + ret = smu_v13_0_set_soft_freq_limited_range(smu, SMU_FCLK, 0, max, false); 2092 + if (!ret) 2093 + pstate_table->fclk_pstate.curr.max = max; 2101 2094 } 2102 2095 2103 2096 return ret; ··· 2150 2125 { 2151 2126 struct smu_dpm_context *smu_dpm = &(smu->smu_dpm); 2152 2127 struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context; 2128 + struct smu_dpm_table *uclk_table = &dpm_context->dpm_tables.uclk_table; 2129 + struct smu_dpm_table *fclk_table = &dpm_context->dpm_tables.fclk_table; 2153 2130 struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; 2154 2131 uint32_t min_clk; 2155 2132 uint32_t max_clk; ··· 2232 2205 pstate_table->uclk_pstate.custom.max = input[1]; 2233 2206 } 2234 2207 break; 2208 + case PP_OD_EDIT_FCLK_TABLE: 2209 + if (size != 2) { 2210 + dev_err(smu->adev->dev, 2211 + "Input parameter number not correct\n"); 2212 + return -EINVAL; 2213 + } 2214 + 2215 + if (!smu_cmn_feature_is_enabled(smu, 2216 + SMU_FEATURE_DPM_FCLK_BIT)) { 2217 + dev_warn(smu->adev->dev, 2218 + "FCLK limits setting not supported!\n"); 2219 + return -EOPNOTSUPP; 2220 + } 2221 + 2222 + max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.fclk_table); 2223 + if (input[0] == 0) { 2224 + dev_info(smu->adev->dev, 2225 + "Setting min FCLK level is not supported\n"); 2226 + return -EOPNOTSUPP; 2227 + } else if (input[0] == 1) { 2228 + if (input[1] > max_clk) { 2229 + dev_warn(smu->adev->dev, 2230 + "Maximum FCLK (%ld) MHz specified is greater than the maximum allowed (%d) MHz\n", 2231 + input[1], max_clk); 2232 + pstate_table->fclk_pstate.custom.max = 2233 + pstate_table->fclk_pstate.curr.max; 2234 + return -EINVAL; 2235 + } 2236 + 2237 + pstate_table->fclk_pstate.custom.max = input[1]; 2238 + } else { 2239 + return -EINVAL; 2240 + } 2241 + break; 2235 2242 2236 2243 case PP_OD_RESTORE_DEFAULT_TABLE: 2237 2244 if (size != 0) { ··· 2285 2224 if (ret) 2286 2225 return ret; 2287 2226 2288 - min_clk = SMU_DPM_TABLE_MIN( 2289 - &dpm_context->dpm_tables.uclk_table); 2290 - max_clk = SMU_DPM_TABLE_MAX( 2291 - &dpm_context->dpm_tables.uclk_table); 2292 - ret = smu_v13_0_6_set_soft_freq_limited_range( 2293 - smu, SMU_UCLK, min_clk, max_clk, false); 2294 - if (ret) 2295 - return ret; 2227 + if (SMU_DPM_TABLE_MAX(uclk_table) != 2228 + pstate_table->uclk_pstate.curr.max) { 2229 + min_clk = SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.uclk_table); 2230 + max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.uclk_table); 2231 + ret = smu_v13_0_6_set_soft_freq_limited_range(smu, 2232 + SMU_UCLK, min_clk, 2233 + max_clk, false); 2234 + if (ret) 2235 + return ret; 2236 + } 2237 + 2238 + if (SMU_DPM_TABLE_MAX(fclk_table) != 2239 + pstate_table->fclk_pstate.curr.max) { 2240 + max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.fclk_table); 2241 + min_clk = SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.fclk_table); 2242 + ret = smu_v13_0_6_set_soft_freq_limited_range(smu, 2243 + SMU_FCLK, min_clk, 2244 + max_clk, false); 2245 + if (ret) 2246 + return ret; 2247 + } 2296 2248 smu_v13_0_reset_custom_level(smu); 2297 2249 } 2298 2250 break; ··· 2331 2257 2332 2258 if (ret) 2333 2259 return ret; 2260 + 2261 + if (pstate_table->fclk_pstate.custom.max) { 2262 + min_clk = pstate_table->fclk_pstate.curr.min; 2263 + max_clk = pstate_table->fclk_pstate.custom.max; 2264 + ret = smu_v13_0_6_set_soft_freq_limited_range(smu, 2265 + SMU_FCLK, min_clk, 2266 + max_clk, false); 2267 + if (ret) 2268 + return ret; 2269 + } 2334 2270 2335 2271 if (!pstate_table->uclk_pstate.custom.max) 2336 2272 return 0;
+32 -1
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
··· 59 59 60 60 #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c)) 61 61 62 + static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu, 63 + int od_feature_bit, 64 + int32_t *min, int32_t *max); 65 + 62 66 static const struct smu_feature_bits smu_v13_0_7_dpm_features = { 63 67 .bits = { 64 68 SMU_FEATURE_BIT_INIT(FEATURE_DPM_GFXCLK_BIT), ··· 1057 1053 PPTable_t *pptable = smu->smu_table.driver_pptable; 1058 1054 const OverDriveLimits_t * const overdrive_upperlimits = 1059 1055 &pptable->SkuTable.OverDriveLimitsBasicMax; 1056 + int32_t min_value, max_value; 1057 + bool feature_enabled; 1060 1058 1061 - return overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit); 1059 + switch (od_feature_bit) { 1060 + case PP_OD_FEATURE_FAN_CURVE_BIT: 1061 + feature_enabled = !!(overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit)); 1062 + if (feature_enabled) { 1063 + smu_v13_0_7_get_od_setting_limits(smu, PP_OD_FEATURE_FAN_CURVE_TEMP, 1064 + &min_value, &max_value); 1065 + if (!min_value && !max_value) { 1066 + feature_enabled = false; 1067 + goto out; 1068 + } 1069 + 1070 + smu_v13_0_7_get_od_setting_limits(smu, PP_OD_FEATURE_FAN_CURVE_PWM, 1071 + &min_value, &max_value); 1072 + if (!min_value && !max_value) { 1073 + feature_enabled = false; 1074 + goto out; 1075 + } 1076 + } 1077 + break; 1078 + default: 1079 + feature_enabled = !!(overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit)); 1080 + break; 1081 + } 1082 + 1083 + out: 1084 + return feature_enabled; 1062 1085 } 1063 1086 1064 1087 static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu,
-1
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c
··· 284 284 "smu fw program = %d, smu fw version = 0x%08x (%d.%d.%d)\n", 285 285 smu->smc_driver_if_version, if_version, 286 286 smu_program, smu_version, smu_major, smu_minor, smu_debug); 287 - dev_info(adev->dev, "SMU driver if version not matched\n"); 288 287 } 289 288 290 289 return ret;
+32 -1
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
··· 56 56 57 57 #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c)) 58 58 59 + static void smu_v14_0_2_get_od_setting_limits(struct smu_context *smu, 60 + int od_feature_bit, 61 + int32_t *min, int32_t *max); 62 + 59 63 static const struct smu_feature_bits smu_v14_0_2_dpm_features = { 60 64 .bits = { SMU_FEATURE_BIT_INIT(FEATURE_DPM_GFXCLK_BIT), 61 65 SMU_FEATURE_BIT_INIT(FEATURE_DPM_UCLK_BIT), ··· 926 922 PPTable_t *pptable = smu->smu_table.driver_pptable; 927 923 const OverDriveLimits_t * const overdrive_upperlimits = 928 924 &pptable->SkuTable.OverDriveLimitsBasicMax; 925 + int32_t min_value, max_value; 926 + bool feature_enabled; 929 927 930 - return overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit); 928 + switch (od_feature_bit) { 929 + case PP_OD_FEATURE_FAN_CURVE_BIT: 930 + feature_enabled = !!(overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit)); 931 + if (feature_enabled) { 932 + smu_v14_0_2_get_od_setting_limits(smu, PP_OD_FEATURE_FAN_CURVE_TEMP, 933 + &min_value, &max_value); 934 + if (!min_value && !max_value) { 935 + feature_enabled = false; 936 + goto out; 937 + } 938 + 939 + smu_v14_0_2_get_od_setting_limits(smu, PP_OD_FEATURE_FAN_CURVE_PWM, 940 + &min_value, &max_value); 941 + if (!min_value && !max_value) { 942 + feature_enabled = false; 943 + goto out; 944 + } 945 + } 946 + break; 947 + default: 948 + feature_enabled = !!(overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit)); 949 + break; 950 + } 951 + 952 + out: 953 + return feature_enabled; 931 954 } 932 955 933 956 static void smu_v14_0_2_get_od_setting_limits(struct smu_context *smu,
+1 -1
drivers/gpu/drm/amd/pm/swsmu/smu15/Makefile
··· 23 23 # Makefile for the 'smu manager' sub-component of powerplay. 24 24 # It provides the smu management services for the driver. 25 25 26 - SMU15_MGR = smu_v15_0.o smu_v15_0_0_ppt.o 26 + SMU15_MGR = smu_v15_0.o smu_v15_0_0_ppt.o smu_v15_0_8_ppt.o 27 27 28 28 AMD_SWSMU_SMU15MGR = $(addprefix $(AMD_SWSMU_PATH)/smu15/,$(SMU15_MGR)) 29 29
+67 -93
drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c
··· 589 589 { 590 590 struct smu_table_context *smu_table = &smu->smu_table; 591 591 struct smu_table *memory_pool = &smu_table->memory_pool; 592 - int ret = 0; 593 - uint64_t address; 594 - uint32_t address_low, address_high; 592 + struct smu_msg_args args = { 593 + .msg = SMU_MSG_DramLogSetDramAddr, 594 + .num_args = 3, 595 + .num_out_args = 0, 596 + }; 595 597 596 598 if (memory_pool->size == 0 || memory_pool->cpu_addr == NULL) 597 - return ret; 599 + return 0; 598 600 599 - address = memory_pool->mc_address; 600 - address_high = (uint32_t)upper_32_bits(address); 601 - address_low = (uint32_t)lower_32_bits(address); 601 + /* SMU_MSG_DramLogSetDramAddr: ARG0=low, ARG1=high, ARG2=size */ 602 + args.args[0] = lower_32_bits(memory_pool->mc_address); 603 + args.args[1] = upper_32_bits(memory_pool->mc_address); 604 + args.args[2] = (u32)memory_pool->size; 602 605 603 - ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DramLogSetDramAddrHigh, 604 - address_high, NULL); 605 - if (ret) 606 - return ret; 607 - ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DramLogSetDramAddrLow, 608 - address_low, NULL); 609 - if (ret) 610 - return ret; 611 - ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DramLogSetDramSize, 612 - (uint32_t)memory_pool->size, NULL); 613 - if (ret) 614 - return ret; 615 - 616 - return ret; 606 + return smu->msg_ctl.ops->send_msg(&smu->msg_ctl, &args); 617 607 } 618 608 619 609 int smu_v15_0_set_driver_table_location(struct smu_context *smu) 620 610 { 621 611 struct smu_table *driver_table = &smu->smu_table.driver_table; 622 - int ret = 0; 612 + struct smu_msg_args args = { 613 + .msg = SMU_MSG_SetDriverDramAddr, 614 + .num_args = 2, 615 + .num_out_args = 0, 616 + }; 623 617 624 - if (driver_table->mc_address) { 625 - ret = smu_cmn_send_smc_msg_with_param(smu, 626 - SMU_MSG_SetDriverDramAddrHigh, 627 - upper_32_bits(driver_table->mc_address), 628 - NULL); 629 - if (!ret) 630 - ret = smu_cmn_send_smc_msg_with_param(smu, 631 - SMU_MSG_SetDriverDramAddrLow, 632 - lower_32_bits(driver_table->mc_address), 633 - NULL); 634 - } 618 + args.args[0] = lower_32_bits(driver_table->mc_address); 619 + args.args[1] = upper_32_bits(driver_table->mc_address); 635 620 636 - return ret; 621 + return smu->msg_ctl.ops->send_msg(&smu->msg_ctl, &args); 637 622 } 638 623 639 624 int smu_v15_0_set_tool_table_location(struct smu_context *smu) 640 625 { 641 - int ret = 0; 642 626 struct smu_table *tool_table = &smu->smu_table.tables[SMU_TABLE_PMSTATUSLOG]; 627 + struct smu_msg_args args = { 628 + .msg = SMU_MSG_SetToolsDramAddr, 629 + .num_args = 2, 630 + .num_out_args = 0, 631 + }; 643 632 644 - if (tool_table->mc_address) { 645 - ret = smu_cmn_send_smc_msg_with_param(smu, 646 - SMU_MSG_SetToolsDramAddrHigh, 647 - upper_32_bits(tool_table->mc_address), 648 - NULL); 649 - if (!ret) 650 - ret = smu_cmn_send_smc_msg_with_param(smu, 651 - SMU_MSG_SetToolsDramAddrLow, 652 - lower_32_bits(tool_table->mc_address), 653 - NULL); 654 - } 633 + /* SMU_MSG_SetToolsDramAddr: ARG0=low, ARG1=high */ 634 + args.args[0] = lower_32_bits(tool_table->mc_address); 635 + args.args[1] = upper_32_bits(tool_table->mc_address); 655 636 656 - return ret; 637 + return smu->msg_ctl.ops->send_msg(&smu->msg_ctl, &args); 657 638 } 658 639 659 640 int smu_v15_0_set_allowed_mask(struct smu_context *smu) ··· 681 700 return ret; 682 701 } 683 702 684 - int smu_v15_0_system_features_control(struct smu_context *smu, 685 - bool en) 703 + int smu_v15_0_system_features_control(struct smu_context *smu, bool en) 686 704 { 687 705 return smu_cmn_send_smc_msg(smu, (en ? SMU_MSG_EnableAllSmuFeatures : 688 706 SMU_MSG_DisableAllSmuFeatures), NULL); ··· 885 905 return ret; 886 906 } 887 907 888 - int smu_v15_0_wait_for_event(struct smu_context *smu, enum smu_event_type event, 908 + int smu_v15_0_wait_for_event(struct smu_context *smu, 909 + enum smu_event_type event, 889 910 uint64_t event_arg) 890 911 { 891 912 int ret = -EINVAL; ··· 1058 1077 { 1059 1078 struct smu_15_0_dpm_context *dpm_context = 1060 1079 smu->smu_dpm.dpm_context; 1061 - struct smu_15_0_dpm_table *gfx_table = 1062 - &dpm_context->dpm_tables.gfx_table; 1063 - struct smu_15_0_dpm_table *mem_table = 1064 - &dpm_context->dpm_tables.uclk_table; 1065 - struct smu_15_0_dpm_table *soc_table = 1066 - &dpm_context->dpm_tables.soc_table; 1067 - struct smu_15_0_dpm_table *vclk_table = 1068 - &dpm_context->dpm_tables.vclk_table; 1069 - struct smu_15_0_dpm_table *dclk_table = 1070 - &dpm_context->dpm_tables.dclk_table; 1071 - struct smu_15_0_dpm_table *fclk_table = 1072 - &dpm_context->dpm_tables.fclk_table; 1080 + struct smu_dpm_table *gfx_table = &dpm_context->dpm_tables.gfx_table; 1081 + struct smu_dpm_table *mem_table = &dpm_context->dpm_tables.uclk_table; 1082 + struct smu_dpm_table *soc_table = &dpm_context->dpm_tables.soc_table; 1083 + struct smu_dpm_table *vclk_table = &dpm_context->dpm_tables.vclk_table; 1084 + struct smu_dpm_table *dclk_table = &dpm_context->dpm_tables.dclk_table; 1085 + struct smu_dpm_table *fclk_table = &dpm_context->dpm_tables.fclk_table; 1073 1086 struct smu_umd_pstate_table *pstate_table = 1074 1087 &smu->pstate_table; 1075 1088 struct amdgpu_device *adev = smu->adev; ··· 1078 1103 1079 1104 switch (level) { 1080 1105 case AMD_DPM_FORCED_LEVEL_HIGH: 1081 - sclk_min = sclk_max = gfx_table->max; 1082 - mclk_min = mclk_max = mem_table->max; 1083 - socclk_min = socclk_max = soc_table->max; 1084 - vclk_min = vclk_max = vclk_table->max; 1085 - dclk_min = dclk_max = dclk_table->max; 1086 - fclk_min = fclk_max = fclk_table->max; 1106 + sclk_min = sclk_max = SMU_DPM_TABLE_MAX(gfx_table); 1107 + mclk_min = mclk_max = SMU_DPM_TABLE_MAX(mem_table); 1108 + socclk_min = socclk_max = SMU_DPM_TABLE_MAX(soc_table); 1109 + vclk_min = vclk_max = SMU_DPM_TABLE_MAX(vclk_table); 1110 + dclk_min = dclk_max = SMU_DPM_TABLE_MAX(dclk_table); 1111 + fclk_min = fclk_max = SMU_DPM_TABLE_MAX(fclk_table); 1087 1112 break; 1088 1113 case AMD_DPM_FORCED_LEVEL_LOW: 1089 - sclk_min = sclk_max = gfx_table->min; 1090 - mclk_min = mclk_max = mem_table->min; 1091 - socclk_min = socclk_max = soc_table->min; 1092 - vclk_min = vclk_max = vclk_table->min; 1093 - dclk_min = dclk_max = dclk_table->min; 1094 - fclk_min = fclk_max = fclk_table->min; 1114 + sclk_min = sclk_max = SMU_DPM_TABLE_MIN(gfx_table); 1115 + mclk_min = mclk_max = SMU_DPM_TABLE_MIN(mem_table); 1116 + socclk_min = socclk_max = SMU_DPM_TABLE_MIN(soc_table); 1117 + vclk_min = vclk_max = SMU_DPM_TABLE_MIN(vclk_table); 1118 + dclk_min = dclk_max = SMU_DPM_TABLE_MIN(dclk_table); 1119 + fclk_min = fclk_max = SMU_DPM_TABLE_MIN(fclk_table); 1095 1120 break; 1096 1121 case AMD_DPM_FORCED_LEVEL_AUTO: 1097 - sclk_min = gfx_table->min; 1098 - sclk_max = gfx_table->max; 1099 - mclk_min = mem_table->min; 1100 - mclk_max = mem_table->max; 1101 - socclk_min = soc_table->min; 1102 - socclk_max = soc_table->max; 1103 - vclk_min = vclk_table->min; 1104 - vclk_max = vclk_table->max; 1105 - dclk_min = dclk_table->min; 1106 - dclk_max = dclk_table->max; 1107 - fclk_min = fclk_table->min; 1108 - fclk_max = fclk_table->max; 1122 + sclk_min = SMU_DPM_TABLE_MIN(gfx_table); 1123 + sclk_max = SMU_DPM_TABLE_MAX(gfx_table); 1124 + mclk_min = SMU_DPM_TABLE_MIN(mem_table); 1125 + mclk_max = SMU_DPM_TABLE_MAX(mem_table); 1126 + socclk_min = SMU_DPM_TABLE_MIN(soc_table); 1127 + socclk_max = SMU_DPM_TABLE_MAX(soc_table); 1128 + vclk_min = SMU_DPM_TABLE_MIN(vclk_table); 1129 + vclk_max = SMU_DPM_TABLE_MAX(vclk_table); 1130 + dclk_min = SMU_DPM_TABLE_MIN(dclk_table); 1131 + dclk_max = SMU_DPM_TABLE_MAX(dclk_table); 1132 + fclk_min = SMU_DPM_TABLE_MIN(fclk_table); 1133 + fclk_max = SMU_DPM_TABLE_MAX(fclk_table); 1109 1134 auto_level = true; 1110 1135 break; 1111 1136 case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: ··· 1327 1352 1328 1353 int smu_v15_0_set_single_dpm_table(struct smu_context *smu, 1329 1354 enum smu_clk_type clk_type, 1330 - struct smu_15_0_dpm_table *single_dpm_table) 1355 + struct smu_dpm_table *single_dpm_table) 1331 1356 { 1332 1357 int ret = 0; 1333 1358 uint32_t clk; 1359 + bool is_fine_grained; 1334 1360 int i; 1335 1361 1336 1362 ret = smu_v15_0_get_dpm_level_count(smu, ··· 1344 1368 1345 1369 ret = smu_v15_0_get_fine_grained_status(smu, 1346 1370 clk_type, 1347 - &single_dpm_table->is_fine_grained); 1371 + &is_fine_grained); 1348 1372 if (ret) { 1349 1373 dev_err(smu->adev->dev, "[%s] failed to get fine grained status!\n", __func__); 1350 1374 return ret; 1351 1375 } 1376 + 1377 + if (is_fine_grained) 1378 + single_dpm_table->flags |= SMU_DPM_TABLE_FINE_GRAINED; 1352 1379 1353 1380 for (i = 0; i < single_dpm_table->count; i++) { 1354 1381 ret = smu_v15_0_get_dpm_freq_by_index(smu, ··· 1365 1386 1366 1387 single_dpm_table->dpm_levels[i].value = clk; 1367 1388 single_dpm_table->dpm_levels[i].enabled = true; 1368 - 1369 - if (i == 0) 1370 - single_dpm_table->min = clk; 1371 - else if (i == single_dpm_table->count - 1) 1372 - single_dpm_table->max = clk; 1373 1389 } 1374 1390 1375 1391 return 0;
+2270
drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c
··· 1 + /* 2 + * Copyright 2025 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 + 24 + #define SWSMU_CODE_LAYER_L2 25 + 26 + #include <linux/firmware.h> 27 + #include "amdgpu.h" 28 + #include "amdgpu_smu.h" 29 + #include "smu_v15_0_8_pmfw.h" 30 + #include "smu15_driver_if_v15_0_8.h" 31 + #include "smu_v15_0_8_ppsmc.h" 32 + #include "smu_v15_0_8_ppt.h" 33 + #include <linux/pci.h> 34 + #include "smu_cmn.h" 35 + #include "mp/mp_15_0_8_offset.h" 36 + #include "mp/mp_15_0_8_sh_mask.h" 37 + #include "smu_v15_0.h" 38 + #include "amdgpu_fru_eeprom.h" 39 + 40 + #undef MP1_Public 41 + 42 + /* address block */ 43 + #define MP1_Public 0x03b00000 44 + #define smnMP1_FIRMWARE_FLAGS_15_0_8 0x3010024 45 + /* 46 + * DO NOT use these for err/warn/info/debug messages. 47 + * Use dev_err, dev_warn, dev_info and dev_dbg instead. 48 + * They are more MGPU friendly. 49 + */ 50 + #undef pr_err 51 + #undef pr_warn 52 + #undef pr_info 53 + #undef pr_debug 54 + 55 + #define SMUQ10_TO_UINT(x) ((x) >> 10) 56 + #define SMUQ10_FRAC(x) ((x) & 0x3ff) 57 + #define SMUQ10_ROUND(x) ((SMUQ10_TO_UINT(x)) + ((SMUQ10_FRAC(x)) >= 0x200)) 58 + 59 + #define hbm_stack_mask_valid(umc_mask) \ 60 + (((umc_mask) & 0xF) == 0xF) 61 + 62 + #define for_each_hbm_stack(stack_idx, umc_mask) \ 63 + for ((stack_idx) = 0; (umc_mask); \ 64 + (umc_mask) >>= 4, (stack_idx)++) \ 65 + 66 + #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c)) 67 + 68 + #define SMU_15_0_8_FEA_MAP(smu_feature, smu_15_0_8_feature) \ 69 + [smu_feature] = { 1, (smu_15_0_8_feature) } 70 + 71 + #define FEATURE_MASK(feature) (1ULL << feature) 72 + 73 + static const struct smu_feature_bits smu_v15_0_8_dpm_features = { 74 + .bits = { SMU_FEATURE_BIT_INIT(FEATURE_ID_DATA_CALCULATION), 75 + SMU_FEATURE_BIT_INIT(FEATURE_ID_DPM_GFXCLK), 76 + SMU_FEATURE_BIT_INIT(FEATURE_ID_DPM_UCLK), 77 + SMU_FEATURE_BIT_INIT(FEATURE_ID_DPM_FCLK), 78 + SMU_FEATURE_BIT_INIT(FEATURE_ID_DPM_GL2CLK) } 79 + }; 80 + 81 + static const struct cmn2asic_msg_mapping smu_v15_0_8_message_map[SMU_MSG_MAX_COUNT] = { 82 + MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0), 83 + MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), 84 + MSG_MAP(GfxDeviceDriverReset, PPSMC_MSG_GfxDriverReset, SMU_MSG_RAS_PRI | SMU_MSG_NO_PRECHECK), 85 + MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 1), 86 + MSG_MAP(EnableAllSmuFeatures, PPSMC_MSG_EnableAllSmuFeatures, 0), 87 + MSG_MAP(GetMetricsVersion, PPSMC_MSG_GetMetricsVersion, 1), 88 + MSG_MAP(GetMetricsTable, PPSMC_MSG_GetMetricsTable, 1), 89 + MSG_MAP(GetEnabledSmuFeatures, PPSMC_MSG_GetEnabledSmuFeatures, 1), 90 + MSG_MAP(SetDriverDramAddr, PPSMC_MSG_SetDriverDramAddr, 1), 91 + MSG_MAP(SetToolsDramAddr, PPSMC_MSG_SetToolsDramAddr, 0), 92 + MSG_MAP(SetSoftMaxByFreq, PPSMC_MSG_SetSoftMaxByFreq, 1), 93 + MSG_MAP(SetPptLimit, PPSMC_MSG_SetPptLimit, 0), 94 + MSG_MAP(GetPptLimit, PPSMC_MSG_GetPptLimit, 1), 95 + MSG_MAP(DramLogSetDramAddr, PPSMC_MSG_DramLogSetDramAddr, 0), 96 + MSG_MAP(HeavySBR, PPSMC_MSG_HeavySBR, 0), 97 + MSG_MAP(DFCstateControl, PPSMC_MSG_DFCstateControl, 0), 98 + MSG_MAP(GfxDriverResetRecovery, PPSMC_MSG_GfxDriverResetRecovery, 0), 99 + MSG_MAP(SetSoftMinGfxclk, PPSMC_MSG_SetSoftMinGfxClk, 1), 100 + MSG_MAP(SetSoftMaxGfxClk, PPSMC_MSG_SetSoftMaxGfxClk, 1), 101 + MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareForDriverUnload, 0), 102 + MSG_MAP(QueryValidMcaCount, PPSMC_MSG_QueryValidMcaCount, SMU_MSG_RAS_PRI), 103 + MSG_MAP(McaBankDumpDW, PPSMC_MSG_McaBankDumpDW, SMU_MSG_RAS_PRI), 104 + MSG_MAP(ClearMcaOnRead, PPSMC_MSG_ClearMcaOnRead, 0), 105 + MSG_MAP(QueryValidMcaCeCount, PPSMC_MSG_QueryValidMcaCeCount, SMU_MSG_RAS_PRI), 106 + MSG_MAP(McaBankCeDumpDW, PPSMC_MSG_McaBankCeDumpDW, SMU_MSG_RAS_PRI), 107 + MSG_MAP(SelectPLPDMode, PPSMC_MSG_SelectPLPDMode, 0), 108 + MSG_MAP(SetThrottlingPolicy, PPSMC_MSG_SetThrottlingPolicy, 0), 109 + MSG_MAP(ResetSDMA, PPSMC_MSG_ResetSDMA, 0), 110 + MSG_MAP(GetRASTableVersion, PPSMC_MSG_GetRasTableVersion, 0), 111 + MSG_MAP(SetTimestamp, PPSMC_MSG_SetTimestamp, 0), 112 + MSG_MAP(GetTimestamp, PPSMC_MSG_GetTimestamp, 0), 113 + MSG_MAP(GetBadPageIpid, PPSMC_MSG_GetBadPageIpIdLoHi, 0), 114 + MSG_MAP(EraseRasTable, PPSMC_MSG_EraseRasTable, 0), 115 + MSG_MAP(GetStaticMetricsTable, PPSMC_MSG_GetStaticMetricsTable, 1), 116 + MSG_MAP(GetSystemMetricsTable, PPSMC_MSG_GetSystemMetricsTable, 1), 117 + MSG_MAP(GetSystemMetricsVersion, PPSMC_MSG_GetSystemMetricsVersion, 0), 118 + MSG_MAP(ResetVCN, PPSMC_MSG_ResetVCN, 0), 119 + MSG_MAP(SetFastPptLimit, PPSMC_MSG_SetFastPptLimit, 0), 120 + MSG_MAP(GetFastPptLimit, PPSMC_MSG_GetFastPptLimit, 0), 121 + MSG_MAP(SetSoftMinGl2clk, PPSMC_MSG_SetSoftMinGl2clk, 0), 122 + MSG_MAP(SetSoftMaxGl2clk, PPSMC_MSG_SetSoftMaxGl2clk, 0), 123 + MSG_MAP(SetSoftMinFclk, PPSMC_MSG_SetSoftMinFclk, 0), 124 + MSG_MAP(SetSoftMaxFclk, PPSMC_MSG_SetSoftMaxFclk, 0), 125 + }; 126 + 127 + /* TODO: Update the clk map once enum PPCLK is updated in smu15_driver_if_v15_0_8.h */ 128 + static struct cmn2asic_mapping smu_v15_0_8_clk_map[SMU_CLK_COUNT] = { 129 + CLK_MAP(UCLK, PPCLK_UCLK), 130 + }; 131 + 132 + static const struct cmn2asic_mapping smu_v15_0_8_feature_mask_map[SMU_FEATURE_COUNT] = { 133 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DATA_CALCULATIONS_BIT, FEATURE_ID_DATA_CALCULATION), 134 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DPM_GFXCLK_BIT, FEATURE_ID_DPM_GFXCLK), 135 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DPM_UCLK_BIT, FEATURE_ID_DPM_UCLK), 136 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DPM_FCLK_BIT, FEATURE_ID_DPM_FCLK), 137 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DPM_GL2CLK_BIT, FEATURE_ID_DPM_GL2CLK), 138 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_GFXCLK_BIT, FEATURE_ID_DS_GFXCLK), 139 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_SOCCLK_BIT, FEATURE_ID_DS_SOCCLK), 140 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_LCLK_BIT, FEATURE_ID_DS_LCLK), 141 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_FCLK_BIT, FEATURE_ID_DS_FCLK), 142 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_DMABECLK_BIT, FEATURE_ID_DS_DMABECLK), 143 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_MPIFOECLK_BIT, FEATURE_ID_DS_MPIFOECLK), 144 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_MPRASCLK_BIT, FEATURE_ID_DS_MPRASCLK), 145 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_MPNHTCLK_BIT, FEATURE_ID_DS_MPNHTCLK), 146 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_FIOCLK_BIT, FEATURE_ID_DS_FIOCLK), 147 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_DXIOCLK_BIT, FEATURE_ID_DS_DXIOCLK), 148 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_GL2CLK_BIT, FEATURE_ID_DS_GL2CLK), 149 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_PPT_BIT, FEATURE_ID_PPT), 150 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_TDC_BIT, FEATURE_ID_TDC), 151 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_MP1_CG_BIT, FEATURE_ID_SMU_CG), 152 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_FW_CTF_BIT, FEATURE_ID_FW_CTF), 153 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_THERMAL_BIT, FEATURE_ID_THERMAL), 154 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_SOC_PCC_BIT, FEATURE_ID_SOC_PCC), 155 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_XGMI_PER_LINK_PWR_DWN_BIT, FEATURE_ID_XGMI_PER_LINK_PWR_DOWN), 156 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_VCN_BIT, FEATURE_ID_DS_VCN), 157 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_MP1CLK_BIT, FEATURE_ID_DS_MP1CLK), 158 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_MPIOCLK_BIT, FEATURE_ID_DS_MPIOCLK), 159 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_MP0CLK_BIT, FEATURE_ID_DS_MP0CLK), 160 + SMU_15_0_8_FEA_MAP(SMU_FEATURE_PIT_BIT, FEATURE_ID_PIT), 161 + }; 162 + 163 + #define TABLE_PMSTATUSLOG 0 164 + #define TABLE_SMU_METRICS 1 165 + #define TABLE_I2C_COMMANDS 2 166 + #define TABLE_COUNT 3 167 + 168 + static const struct cmn2asic_mapping smu_v15_0_8_table_map[SMU_TABLE_COUNT] = { 169 + TAB_MAP(PMSTATUSLOG), 170 + TAB_MAP(SMU_METRICS), 171 + TAB_MAP(I2C_COMMANDS), 172 + }; 173 + 174 + static size_t smu_v15_0_8_get_system_metrics_size(void) 175 + { 176 + return sizeof(SystemMetricsTable_t); 177 + } 178 + 179 + static int smu_v15_0_8_tables_init(struct smu_context *smu) 180 + { 181 + struct smu_v15_0_8_baseboard_temp_metrics *baseboard_temp_metrics; 182 + struct smu_v15_0_8_gpuboard_temp_metrics *gpuboard_temp_metrics; 183 + struct smu_table_context *smu_table = &smu->smu_table; 184 + int ret, gpu_metrcs_size = sizeof(MetricsTable_t); 185 + struct smu_table *tables = smu_table->tables; 186 + struct smu_v15_0_8_gpu_metrics *gpu_metrics; 187 + void *driver_pptable __free(kfree) = NULL; 188 + void *metrics_table __free(kfree) = NULL; 189 + 190 + SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU15_TOOL_SIZE, 191 + PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 192 + 193 + SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, 194 + gpu_metrcs_size, 195 + PAGE_SIZE, 196 + AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT); 197 + SMU_TABLE_INIT(tables, SMU_TABLE_PMFW_SYSTEM_METRICS, 198 + smu_v15_0_8_get_system_metrics_size(), PAGE_SIZE, 199 + AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT); 200 + 201 + metrics_table = kzalloc(gpu_metrcs_size, GFP_KERNEL); 202 + if (!metrics_table) 203 + return -ENOMEM; 204 + 205 + smu_table->metrics_time = 0; 206 + 207 + driver_pptable = kzalloc(sizeof(PPTable_t), GFP_KERNEL); 208 + if (!driver_pptable) 209 + return -ENOMEM; 210 + 211 + ret = smu_driver_table_init(smu, SMU_DRIVER_TABLE_GPU_METRICS, 212 + sizeof(struct smu_v15_0_8_gpu_metrics), 213 + SMU_GPU_METRICS_CACHE_INTERVAL); 214 + if (ret) 215 + return ret; 216 + 217 + gpu_metrics = (struct smu_v15_0_8_gpu_metrics *)smu_driver_table_ptr(smu, 218 + SMU_DRIVER_TABLE_GPU_METRICS); 219 + smu_v15_0_8_gpu_metrics_init(gpu_metrics, 1, 9); 220 + 221 + ret = smu_table_cache_init(smu, SMU_TABLE_PMFW_SYSTEM_METRICS, 222 + smu_v15_0_8_get_system_metrics_size(), 5); 223 + 224 + if (ret) 225 + return ret; 226 + 227 + /* Initialize base board temperature metrics */ 228 + ret = smu_driver_table_init(smu, 229 + SMU_DRIVER_TABLE_BASEBOARD_TEMP_METRICS, 230 + sizeof(*baseboard_temp_metrics), 50); 231 + if (ret) 232 + return ret; 233 + baseboard_temp_metrics = (struct smu_v15_0_8_baseboard_temp_metrics *) 234 + smu_driver_table_ptr(smu, 235 + SMU_DRIVER_TABLE_BASEBOARD_TEMP_METRICS); 236 + smu_v15_0_8_baseboard_temp_metrics_init(baseboard_temp_metrics, 1, 1); 237 + /* Initialize GPU board temperature metrics */ 238 + ret = smu_driver_table_init(smu, SMU_DRIVER_TABLE_GPUBOARD_TEMP_METRICS, 239 + sizeof(*gpuboard_temp_metrics), 50); 240 + if (ret) { 241 + smu_table_cache_fini(smu, SMU_TABLE_PMFW_SYSTEM_METRICS); 242 + smu_driver_table_fini(smu, 243 + SMU_DRIVER_TABLE_BASEBOARD_TEMP_METRICS); 244 + return ret; 245 + } 246 + gpuboard_temp_metrics = (struct smu_v15_0_8_gpuboard_temp_metrics *) 247 + smu_driver_table_ptr(smu, 248 + SMU_DRIVER_TABLE_GPUBOARD_TEMP_METRICS); 249 + smu_v15_0_8_gpuboard_temp_metrics_init(gpuboard_temp_metrics, 1, 1); 250 + 251 + smu_table->metrics_table = no_free_ptr(metrics_table); 252 + smu_table->driver_pptable = no_free_ptr(driver_pptable); 253 + 254 + mutex_init(&smu_table->metrics_lock); 255 + 256 + return 0; 257 + } 258 + 259 + static int smu_v15_0_8_allocate_dpm_context(struct smu_context *smu) 260 + { 261 + struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 262 + 263 + smu_dpm->dpm_context = 264 + kzalloc(sizeof(struct smu_15_0_dpm_context), GFP_KERNEL); 265 + if (!smu_dpm->dpm_context) 266 + return -ENOMEM; 267 + smu_dpm->dpm_context_size = sizeof(struct smu_15_0_dpm_context); 268 + 269 + smu_dpm->dpm_policies = 270 + kzalloc(sizeof(struct smu_dpm_policy_ctxt), GFP_KERNEL); 271 + if (!smu_dpm->dpm_policies) { 272 + kfree(smu_dpm->dpm_context); 273 + return -ENOMEM; 274 + } 275 + 276 + return 0; 277 + } 278 + 279 + static int smu_v15_0_8_init_smc_tables(struct smu_context *smu) 280 + { 281 + int ret = 0; 282 + 283 + ret = smu_v15_0_8_tables_init(smu); 284 + if (ret) 285 + return ret; 286 + 287 + ret = smu_v15_0_8_allocate_dpm_context(smu); 288 + 289 + return ret; 290 + } 291 + 292 + static int smu_v15_0_8_tables_fini(struct smu_context *smu) 293 + { 294 + struct smu_table_context *smu_table = &smu->smu_table; 295 + 296 + smu_driver_table_fini(smu, SMU_DRIVER_TABLE_BASEBOARD_TEMP_METRICS); 297 + smu_driver_table_fini(smu, SMU_DRIVER_TABLE_GPUBOARD_TEMP_METRICS); 298 + smu_table_cache_fini(smu, SMU_TABLE_PMFW_SYSTEM_METRICS); 299 + mutex_destroy(&smu_table->metrics_lock); 300 + 301 + return 0; 302 + } 303 + 304 + static int smu_v15_0_8_fini_smc_tables(struct smu_context *smu) 305 + { 306 + int ret; 307 + 308 + ret = smu_v15_0_8_tables_fini(smu); 309 + if (ret) 310 + return ret; 311 + 312 + ret = smu_v15_0_fini_smc_tables(smu); 313 + if (ret) 314 + return ret; 315 + 316 + return ret; 317 + } 318 + 319 + static int smu_v15_0_8_init_allowed_features(struct smu_context *smu) 320 + { 321 + /* pptable will handle the features to enable */ 322 + smu_feature_list_set_all(smu, SMU_FEATURE_LIST_ALLOWED); 323 + 324 + return 0; 325 + } 326 + 327 + static int smu_v15_0_8_get_metrics_table_internal(struct smu_context *smu, uint32_t tmo, void *data) 328 + { 329 + struct smu_table_context *smu_table = &smu->smu_table; 330 + uint32_t table_size = smu_table->tables[SMU_TABLE_SMU_METRICS].size; 331 + struct smu_table *table = &smu_table->driver_table; 332 + struct amdgpu_device *adev = smu->adev; 333 + 334 + mutex_lock(&smu_table->metrics_lock); 335 + 336 + if (!tmo || !smu_table->metrics_time || 337 + time_after(jiffies, smu_table->metrics_time + msecs_to_jiffies(tmo))) { 338 + int ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetMetricsTable, NULL); 339 + if (ret) { 340 + dev_info(adev->dev, 341 + "Failed to export SMU metrics table!\n"); 342 + mutex_unlock(&smu_table->metrics_lock); 343 + return ret; 344 + } 345 + 346 + amdgpu_device_invalidate_hdp(smu->adev, NULL); 347 + memcpy(smu_table->metrics_table, table->cpu_addr, table_size); 348 + 349 + smu_table->metrics_time = jiffies; 350 + } 351 + 352 + if (data) 353 + memcpy(data, smu_table->metrics_table, table_size); 354 + mutex_unlock(&smu_table->metrics_lock); 355 + return 0; 356 + } 357 + 358 + static int smu_v15_0_8_get_smu_metrics_data(struct smu_context *smu, 359 + MetricsMember_t member, uint32_t *value) 360 + { 361 + struct smu_table_context *smu_table = &smu->smu_table; 362 + MetricsTable_t *metrics = (MetricsTable_t *)smu_table->metrics_table; 363 + struct amdgpu_device *adev = smu->adev; 364 + int ret, xcc_id; 365 + 366 + ret = smu_v15_0_8_get_metrics_table_internal(smu, 10, NULL); 367 + if (ret) 368 + return ret; 369 + 370 + switch (member) { 371 + case METRICS_CURR_GFXCLK: 372 + case METRICS_AVERAGE_GFXCLK: 373 + xcc_id = GET_INST(GC, 0); 374 + *value = SMUQ10_ROUND(metrics->GfxclkFrequency[xcc_id]); 375 + break; 376 + case METRICS_CURR_SOCCLK: 377 + case METRICS_AVERAGE_SOCCLK: 378 + *value = SMUQ10_ROUND(metrics->SocclkFrequency[0]); 379 + break; 380 + case METRICS_CURR_UCLK: 381 + case METRICS_AVERAGE_UCLK: 382 + *value = SMUQ10_ROUND(metrics->UclkFrequency[0]); 383 + break; 384 + case METRICS_CURR_VCLK: 385 + *value = SMUQ10_ROUND(metrics->VclkFrequency[0]); 386 + break; 387 + case METRICS_CURR_DCLK: 388 + *value = SMUQ10_ROUND(metrics->DclkFrequency[0]); 389 + break; 390 + case METRICS_CURR_FCLK: 391 + *value = SMUQ10_ROUND(metrics->FclkFrequency[0]); 392 + break; 393 + case METRICS_AVERAGE_GFXACTIVITY: 394 + *value = SMUQ10_ROUND(metrics->SocketGfxBusy); 395 + break; 396 + case METRICS_AVERAGE_MEMACTIVITY: 397 + *value = SMUQ10_ROUND(metrics->DramBandwidthUtilization); 398 + break; 399 + case METRICS_CURR_SOCKETPOWER: 400 + *value = SMUQ10_ROUND(metrics->SocketPower) << 8; 401 + break; 402 + case METRICS_TEMPERATURE_HOTSPOT: 403 + *value = SMUQ10_ROUND(metrics->MaxSocketTemperature) * 404 + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 405 + break; 406 + case METRICS_TEMPERATURE_MEM: 407 + { 408 + struct amdgpu_device *adev = smu->adev; 409 + u32 max_hbm_temp = 0; 410 + 411 + /* Find max temperature across all HBM stacks */ 412 + if (adev->umc.active_mask) { 413 + u64 mask = adev->umc.active_mask; 414 + int stack_idx; 415 + 416 + for_each_hbm_stack(stack_idx, mask) { 417 + u32 temp; 418 + 419 + if (!hbm_stack_mask_valid(mask)) 420 + continue; 421 + 422 + temp = SMUQ10_ROUND(metrics->HbmTemperature[stack_idx]); 423 + if (temp > max_hbm_temp) 424 + max_hbm_temp = temp; 425 + } 426 + } 427 + *value = max_hbm_temp * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 428 + break; 429 + } 430 + /* This is the max of all VRs and not just SOC VR. 431 + */ 432 + case METRICS_TEMPERATURE_VRSOC: 433 + *value = SMUQ10_ROUND(metrics->MaxVrTemperature) * 434 + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 435 + break; 436 + default: 437 + *value = UINT_MAX; 438 + break; 439 + } 440 + 441 + return 0; 442 + } 443 + 444 + static int smu_v15_0_8_get_current_clk_freq_by_table(struct smu_context *smu, 445 + enum smu_clk_type clk_type, 446 + uint32_t *value) 447 + { 448 + MetricsMember_t member_type; 449 + 450 + if (!value) 451 + return -EINVAL; 452 + 453 + switch (clk_type) { 454 + case SMU_GFXCLK: 455 + case SMU_SCLK: 456 + member_type = METRICS_CURR_GFXCLK; 457 + break; 458 + case SMU_UCLK: 459 + case SMU_MCLK: 460 + member_type = METRICS_CURR_UCLK; 461 + break; 462 + case SMU_SOCCLK: 463 + member_type = METRICS_CURR_SOCCLK; 464 + break; 465 + case SMU_VCLK: 466 + member_type = METRICS_CURR_VCLK; 467 + break; 468 + case SMU_DCLK: 469 + member_type = METRICS_CURR_DCLK; 470 + break; 471 + case SMU_FCLK: 472 + member_type = METRICS_CURR_FCLK; 473 + break; 474 + default: 475 + return -EINVAL; 476 + } 477 + 478 + return smu_v15_0_8_get_smu_metrics_data(smu, member_type, value); 479 + } 480 + 481 + static int smu_v15_0_8_get_current_activity_percent(struct smu_context *smu, 482 + enum amd_pp_sensors sensor, 483 + uint32_t *value) 484 + { 485 + int ret = 0; 486 + 487 + if (!value) 488 + return -EINVAL; 489 + 490 + switch (sensor) { 491 + case AMDGPU_PP_SENSOR_GPU_LOAD: 492 + ret = smu_v15_0_8_get_smu_metrics_data(smu, 493 + METRICS_AVERAGE_GFXACTIVITY, value); 494 + break; 495 + case AMDGPU_PP_SENSOR_MEM_LOAD: 496 + ret = smu_v15_0_8_get_smu_metrics_data(smu, 497 + METRICS_AVERAGE_MEMACTIVITY, value); 498 + break; 499 + default: 500 + dev_err(smu->adev->dev, 501 + "Invalid sensor for retrieving clock activity\n"); 502 + return -EINVAL; 503 + } 504 + 505 + return ret; 506 + } 507 + 508 + static int smu_v15_0_8_thermal_get_temperature(struct smu_context *smu, 509 + enum amd_pp_sensors sensor, 510 + uint32_t *value) 511 + { 512 + int ret = 0; 513 + 514 + if (!value) 515 + return -EINVAL; 516 + 517 + switch (sensor) { 518 + case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: 519 + ret = smu_v15_0_8_get_smu_metrics_data(smu, 520 + METRICS_TEMPERATURE_HOTSPOT, value); 521 + break; 522 + case AMDGPU_PP_SENSOR_MEM_TEMP: 523 + ret = smu_v15_0_8_get_smu_metrics_data(smu, 524 + METRICS_TEMPERATURE_MEM, value); 525 + break; 526 + default: 527 + dev_err(smu->adev->dev, "Invalid sensor for retrieving temp\n"); 528 + return -EINVAL; 529 + } 530 + 531 + return ret; 532 + } 533 + 534 + static int smu_v15_0_8_get_system_metrics_table(struct smu_context *smu) 535 + { 536 + struct smu_table_context *smu_table = &smu->smu_table; 537 + struct smu_table *table = &smu_table->driver_table; 538 + struct smu_table *tables = smu_table->tables; 539 + struct smu_table *sys_table; 540 + int ret; 541 + 542 + sys_table = &tables[SMU_TABLE_PMFW_SYSTEM_METRICS]; 543 + if (smu_table_cache_is_valid(sys_table)) 544 + return 0; 545 + 546 + ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetSystemMetricsTable, NULL); 547 + if (ret) { 548 + dev_info(smu->adev->dev, 549 + "Failed to export system metrics table!\n"); 550 + return ret; 551 + } 552 + 553 + amdgpu_hdp_invalidate(smu->adev, NULL); 554 + smu_table_cache_update_time(sys_table, jiffies); 555 + memcpy(sys_table->cache.buffer, table->cpu_addr, 556 + sizeof(SystemMetricsTable_t)); 557 + 558 + return 0; 559 + } 560 + 561 + static int smu_v15_0_8_get_npm_data(struct smu_context *smu, 562 + enum amd_pp_sensors sensor, 563 + uint32_t *value) 564 + { 565 + struct smu_table_context *smu_table = &smu->smu_table; 566 + struct smu_table *tables = smu_table->tables; 567 + SystemMetricsTable_t *metrics; 568 + struct smu_table *sys_table; 569 + int ret; 570 + 571 + if (sensor == AMDGPU_PP_SENSOR_MAXNODEPOWERLIMIT) { 572 + /*TBD as of now put 0 */ 573 + *value = 0; 574 + return 0; 575 + } 576 + 577 + ret = smu_v15_0_8_get_system_metrics_table(smu); 578 + if (ret) 579 + return ret; 580 + 581 + sys_table = &tables[SMU_TABLE_PMFW_SYSTEM_METRICS]; 582 + metrics = (SystemMetricsTable_t *)sys_table->cache.buffer; 583 + 584 + switch (sensor) { 585 + case AMDGPU_PP_SENSOR_NODEPOWERLIMIT: 586 + *value = SMUQ10_ROUND(metrics->NodePowerLimit); 587 + break; 588 + case AMDGPU_PP_SENSOR_NODEPOWER: 589 + *value = SMUQ10_ROUND(metrics->NodePower); 590 + break; 591 + case AMDGPU_PP_SENSOR_GPPTRESIDENCY: 592 + *value = SMUQ10_ROUND(metrics->GlobalPPTResidencyAcc); 593 + break; 594 + default: 595 + return -EINVAL; 596 + } 597 + 598 + return 0; 599 + } 600 + 601 + static int smu_v15_0_8_read_sensor(struct smu_context *smu, 602 + enum amd_pp_sensors sensor, void *data, 603 + uint32_t *size) 604 + { 605 + struct smu_15_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; 606 + int ret = 0; 607 + 608 + if (amdgpu_ras_intr_triggered()) 609 + return 0; 610 + 611 + if (!data || !size) 612 + return -EINVAL; 613 + 614 + switch (sensor) { 615 + case AMDGPU_PP_SENSOR_MEM_LOAD: 616 + case AMDGPU_PP_SENSOR_GPU_LOAD: 617 + ret = smu_v15_0_8_get_current_activity_percent(smu, sensor, 618 + (uint32_t *)data); 619 + *size = 4; 620 + break; 621 + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: 622 + ret = smu_v15_0_8_get_smu_metrics_data(smu, 623 + METRICS_CURR_SOCKETPOWER, 624 + (uint32_t *)data); 625 + *size = 4; 626 + break; 627 + case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: 628 + case AMDGPU_PP_SENSOR_MEM_TEMP: 629 + ret = smu_v15_0_8_thermal_get_temperature(smu, sensor, 630 + (uint32_t *)data); 631 + *size = 4; 632 + break; 633 + case AMDGPU_PP_SENSOR_GFX_MCLK: 634 + ret = smu_v15_0_8_get_current_clk_freq_by_table(smu, 635 + SMU_UCLK, (uint32_t *)data); 636 + /* the output clock frequency in 10K unit */ 637 + *(uint32_t *)data *= 100; 638 + *size = 4; 639 + break; 640 + case AMDGPU_PP_SENSOR_GFX_SCLK: 641 + ret = smu_v15_0_8_get_current_clk_freq_by_table(smu, 642 + SMU_GFXCLK, (uint32_t *)data); 643 + *(uint32_t *)data *= 100; 644 + *size = 4; 645 + break; 646 + case AMDGPU_PP_SENSOR_VDDBOARD: 647 + *(uint32_t *)data = dpm_context->board_volt; 648 + *size = 4; 649 + break; 650 + case AMDGPU_PP_SENSOR_NODEPOWERLIMIT: 651 + case AMDGPU_PP_SENSOR_NODEPOWER: 652 + case AMDGPU_PP_SENSOR_GPPTRESIDENCY: 653 + case AMDGPU_PP_SENSOR_MAXNODEPOWERLIMIT: 654 + ret = smu_v15_0_8_get_npm_data(smu, sensor, (uint32_t *)data); 655 + if (ret) 656 + return ret; 657 + *size = 4; 658 + break; 659 + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: 660 + default: 661 + ret = -EOPNOTSUPP; 662 + break; 663 + } 664 + 665 + return ret; 666 + } 667 + 668 + static int smu_v15_0_8_emit_clk_levels(struct smu_context *smu, 669 + enum smu_clk_type type, char *buf, 670 + int *offset) 671 + { 672 + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; 673 + struct smu_15_0_dpm_context *dpm_context; 674 + struct smu_dpm_table *single_dpm_table = NULL; 675 + struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 676 + int ret, now, size = *offset; 677 + 678 + if (amdgpu_ras_intr_triggered()) { 679 + sysfs_emit_at(buf, size, "unavailable\n"); 680 + return -EBUSY; 681 + } 682 + 683 + dpm_context = smu_dpm->dpm_context; 684 + 685 + switch (type) { 686 + case SMU_OD_SCLK: 687 + size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); 688 + size += sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMhz\n", 689 + pstate_table->gfxclk_pstate.curr.min, 690 + pstate_table->gfxclk_pstate.curr.max); 691 + break; 692 + case SMU_OD_MCLK: 693 + size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK"); 694 + size += sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMhz\n", 695 + pstate_table->uclk_pstate.curr.min, 696 + pstate_table->uclk_pstate.curr.max); 697 + break; 698 + case SMU_SCLK: 699 + case SMU_GFXCLK: 700 + single_dpm_table = &dpm_context->dpm_tables.gfx_table; 701 + break; 702 + case SMU_MCLK: 703 + case SMU_UCLK: 704 + single_dpm_table = &dpm_context->dpm_tables.uclk_table; 705 + break; 706 + case SMU_SOCCLK: 707 + single_dpm_table = &dpm_context->dpm_tables.soc_table; 708 + break; 709 + case SMU_FCLK: 710 + single_dpm_table = &dpm_context->dpm_tables.fclk_table; 711 + break; 712 + case SMU_VCLK: 713 + single_dpm_table = &dpm_context->dpm_tables.vclk_table; 714 + break; 715 + case SMU_DCLK: 716 + single_dpm_table = &dpm_context->dpm_tables.dclk_table; 717 + break; 718 + default: 719 + break; 720 + } 721 + 722 + if (single_dpm_table) { 723 + ret = smu_v15_0_8_get_current_clk_freq_by_table(smu, type, &now); 724 + if (ret) { 725 + dev_err(smu->adev->dev, 726 + "Attempt to get current clk Failed!"); 727 + return ret; 728 + } 729 + ret = smu_cmn_print_dpm_clk_levels(smu, single_dpm_table, now, 730 + buf, offset); 731 + if (ret < 0) 732 + return ret; 733 + 734 + return 0; 735 + } 736 + 737 + *offset = size; 738 + 739 + return 0; 740 + } 741 + 742 + static int smu_v15_0_8_get_dpm_ultimate_freq(struct smu_context *smu, 743 + enum smu_clk_type clk_type, 744 + uint32_t *min, uint32_t *max) 745 + { 746 + struct smu_15_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; 747 + struct smu_table_context *smu_table = &smu->smu_table; 748 + PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable; 749 + struct smu_dpm_table *dpm_table; 750 + uint32_t min_clk = 0, max_clk = 0; 751 + 752 + if (!pptable->init) 753 + return -EINVAL; 754 + 755 + /* Try cached DPM tables first */ 756 + if (dpm_context) { 757 + switch (clk_type) { 758 + case SMU_MCLK: 759 + case SMU_UCLK: 760 + dpm_table = &dpm_context->dpm_tables.uclk_table; 761 + break; 762 + case SMU_GFXCLK: 763 + case SMU_SCLK: 764 + dpm_table = &dpm_context->dpm_tables.gfx_table; 765 + break; 766 + case SMU_SOCCLK: 767 + dpm_table = &dpm_context->dpm_tables.soc_table; 768 + break; 769 + case SMU_FCLK: 770 + dpm_table = &dpm_context->dpm_tables.fclk_table; 771 + break; 772 + case SMU_GL2CLK: 773 + dpm_table = &dpm_context->dpm_tables.gl2_table; 774 + break; 775 + case SMU_VCLK: 776 + dpm_table = &dpm_context->dpm_tables.vclk_table; 777 + break; 778 + case SMU_DCLK: 779 + dpm_table = &dpm_context->dpm_tables.dclk_table; 780 + break; 781 + default: 782 + dpm_table = NULL; 783 + break; 784 + } 785 + 786 + if (dpm_table && dpm_table->count > 0) { 787 + min_clk = SMU_DPM_TABLE_MIN(dpm_table); 788 + max_clk = SMU_DPM_TABLE_MAX(dpm_table); 789 + 790 + if (min_clk && max_clk) { 791 + if (min) 792 + *min = min_clk; 793 + if (max) 794 + *max = max_clk; 795 + return 0; 796 + } 797 + } 798 + } 799 + 800 + /* Fall back to pptable */ 801 + switch (clk_type) { 802 + case SMU_GFXCLK: 803 + case SMU_SCLK: 804 + min_clk = pptable->MinGfxclkFrequency; 805 + max_clk = pptable->MaxGfxclkFrequency; 806 + break; 807 + case SMU_FCLK: 808 + min_clk = pptable->MinFclkFrequency; 809 + max_clk = pptable->MaxFclkFrequency; 810 + break; 811 + case SMU_GL2CLK: 812 + min_clk = pptable->MinGl2clkFrequency; 813 + max_clk = pptable->MaxGl2clkFrequency; 814 + break; 815 + case SMU_MCLK: 816 + case SMU_UCLK: 817 + min_clk = pptable->UclkFrequencyTable[0]; 818 + max_clk = pptable->UclkFrequencyTable[ARRAY_SIZE(pptable->UclkFrequencyTable) - 1]; 819 + break; 820 + case SMU_SOCCLK: 821 + min_clk = pptable->SocclkFrequency; 822 + max_clk = pptable->SocclkFrequency; 823 + break; 824 + case SMU_VCLK: 825 + min_clk = pptable->VclkFrequency; 826 + max_clk = pptable->VclkFrequency; 827 + break; 828 + case SMU_DCLK: 829 + min_clk = pptable->DclkFrequency; 830 + max_clk = pptable->DclkFrequency; 831 + break; 832 + default: 833 + return -EINVAL; 834 + } 835 + 836 + if (min) 837 + *min = min_clk; 838 + if (max) 839 + *max = max_clk; 840 + 841 + return 0; 842 + } 843 + 844 + static int smu_v15_0_8_set_dpm_table(struct smu_context *smu) 845 + { 846 + struct smu_table_context *smu_table = &smu->smu_table; 847 + struct smu_15_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; 848 + struct smu_dpm_table *dpm_table; 849 + PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable; 850 + int i, ret; 851 + uint32_t gfxclkmin, gfxclkmax; 852 + 853 + /* gfxclk dpm table setup - fine-grained */ 854 + dpm_table = &dpm_context->dpm_tables.gfx_table; 855 + dpm_table->clk_type = SMU_GFXCLK; 856 + dpm_table->flags = SMU_DPM_TABLE_FINE_GRAINED; 857 + if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT)) { 858 + ret = smu_v15_0_8_get_dpm_ultimate_freq(smu, SMU_GFXCLK, 859 + &gfxclkmin, &gfxclkmax); 860 + if (ret) 861 + return ret; 862 + 863 + dpm_table->count = 2; 864 + dpm_table->dpm_levels[0].value = gfxclkmin; 865 + dpm_table->dpm_levels[0].enabled = true; 866 + dpm_table->dpm_levels[1].value = gfxclkmax; 867 + dpm_table->dpm_levels[1].enabled = true; 868 + } else { 869 + dpm_table->count = 1; 870 + dpm_table->dpm_levels[0].value = pptable->MinGfxclkFrequency; 871 + dpm_table->dpm_levels[0].enabled = true; 872 + } 873 + 874 + /* fclk dpm table setup - fine-grained */ 875 + dpm_table = &dpm_context->dpm_tables.fclk_table; 876 + dpm_table->clk_type = SMU_FCLK; 877 + dpm_table->flags = SMU_DPM_TABLE_FINE_GRAINED; 878 + if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_FCLK_BIT)) { 879 + dpm_table->count = 2; 880 + dpm_table->dpm_levels[0].value = pptable->MinFclkFrequency; 881 + dpm_table->dpm_levels[0].enabled = true; 882 + dpm_table->dpm_levels[1].value = pptable->MaxFclkFrequency; 883 + dpm_table->dpm_levels[1].enabled = true; 884 + } else { 885 + dpm_table->count = 1; 886 + dpm_table->dpm_levels[0].value = pptable->MinFclkFrequency; 887 + dpm_table->dpm_levels[0].enabled = true; 888 + } 889 + 890 + /* gl2clk dpm table setup - fine-grained */ 891 + dpm_table = &dpm_context->dpm_tables.gl2_table; 892 + dpm_table->flags = SMU_DPM_TABLE_FINE_GRAINED; 893 + if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GL2CLK_BIT)) { 894 + dpm_table->count = 2; 895 + dpm_table->dpm_levels[0].value = pptable->MinGl2clkFrequency; 896 + dpm_table->dpm_levels[0].enabled = true; 897 + dpm_table->dpm_levels[1].value = pptable->MaxGl2clkFrequency; 898 + dpm_table->dpm_levels[1].enabled = true; 899 + } else { 900 + dpm_table->count = 1; 901 + dpm_table->dpm_levels[0].value = pptable->MinGl2clkFrequency; 902 + dpm_table->dpm_levels[0].enabled = true; 903 + } 904 + 905 + /* uclk dpm table setup - discrete levels */ 906 + dpm_table = &dpm_context->dpm_tables.uclk_table; 907 + dpm_table->clk_type = SMU_UCLK; 908 + dpm_table->flags = 0; 909 + if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) { 910 + dpm_table->count = ARRAY_SIZE(pptable->UclkFrequencyTable); 911 + for (i = 0; i < dpm_table->count; ++i) { 912 + dpm_table->dpm_levels[i].value = pptable->UclkFrequencyTable[i]; 913 + dpm_table->dpm_levels[i].enabled = true; 914 + } 915 + } else { 916 + dpm_table->count = 1; 917 + dpm_table->dpm_levels[0].value = pptable->UclkFrequencyTable[0]; 918 + dpm_table->dpm_levels[0].enabled = true; 919 + } 920 + 921 + /* socclk dpm table setup - single boot-time value */ 922 + dpm_table = &dpm_context->dpm_tables.soc_table; 923 + dpm_table->clk_type = SMU_SOCCLK; 924 + dpm_table->flags = 0; 925 + dpm_table->count = 1; 926 + dpm_table->dpm_levels[0].value = pptable->SocclkFrequency; 927 + dpm_table->dpm_levels[0].enabled = true; 928 + 929 + /* vclk dpm table setup - single boot-time value */ 930 + dpm_table = &dpm_context->dpm_tables.vclk_table; 931 + dpm_table->clk_type = SMU_VCLK; 932 + dpm_table->flags = 0; 933 + dpm_table->count = 1; 934 + dpm_table->dpm_levels[0].value = pptable->VclkFrequency; 935 + dpm_table->dpm_levels[0].enabled = true; 936 + 937 + /* dclk dpm table setup - single boot-time value */ 938 + dpm_table = &dpm_context->dpm_tables.dclk_table; 939 + dpm_table->clk_type = SMU_DCLK; 940 + dpm_table->flags = 0; 941 + dpm_table->count = 1; 942 + dpm_table->dpm_levels[0].value = pptable->DclkFrequency; 943 + dpm_table->dpm_levels[0].enabled = true; 944 + 945 + return 0; 946 + } 947 + 948 + static int smu_v15_0_8_setup_pptable(struct smu_context *smu) 949 + { 950 + struct smu_table_context *table_context = &smu->smu_table; 951 + 952 + /* TODO: PPTable is not available. 953 + * 1) Find an alternate way to get 'PPTable values' here. 954 + * 2) Check if there is SW CTF 955 + */ 956 + table_context->thermal_controller_type = 0; 957 + 958 + return 0; 959 + } 960 + 961 + static int smu_v15_0_8_check_fw_status(struct smu_context *smu) 962 + { 963 + struct amdgpu_device *adev = smu->adev; 964 + uint32_t mp1_fw_flags; 965 + 966 + mp1_fw_flags = RREG32_PCIE(MP1_Public | 967 + (smnMP1_FIRMWARE_FLAGS_15_0_8 & 0xffffffff)); 968 + 969 + if ((mp1_fw_flags & MP1_CRU1_MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >> 970 + MP1_CRU1_MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT) 971 + return 0; 972 + 973 + return -EIO; 974 + } 975 + 976 + static int smu_v15_0_8_get_static_metrics_table(struct smu_context *smu) 977 + { 978 + struct smu_table_context *smu_table = &smu->smu_table; 979 + uint32_t table_size = smu_table->tables[SMU_TABLE_SMU_METRICS].size; 980 + struct smu_table *table = &smu_table->driver_table; 981 + int ret; 982 + 983 + ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetStaticMetricsTable, NULL); 984 + if (ret) { 985 + dev_err(smu->adev->dev, 986 + "Failed to export static metrics table!\n"); 987 + return ret; 988 + } 989 + 990 + amdgpu_hdp_invalidate(smu->adev, NULL); 991 + memcpy(smu_table->metrics_table, table->cpu_addr, table_size); 992 + 993 + return 0; 994 + } 995 + 996 + static int smu_v15_0_8_fru_get_product_info(struct smu_context *smu, 997 + StaticMetricsTable_t *static_metrics) 998 + { 999 + struct amdgpu_fru_info *fru_info; 1000 + struct amdgpu_device *adev = smu->adev; 1001 + 1002 + if (!adev->fru_info) { 1003 + adev->fru_info = kzalloc(sizeof(*adev->fru_info), GFP_KERNEL); 1004 + if (!adev->fru_info) 1005 + return -ENOMEM; 1006 + } 1007 + 1008 + fru_info = adev->fru_info; 1009 + strscpy(fru_info->product_number, static_metrics->ProductInfo.ModelNumber, 1010 + sizeof(fru_info->product_number)); 1011 + strscpy(fru_info->product_name, static_metrics->ProductInfo.Name, 1012 + sizeof(fru_info->product_name)); 1013 + strscpy(fru_info->serial, static_metrics->ProductInfo.Serial, 1014 + sizeof(fru_info->serial)); 1015 + strscpy(fru_info->manufacturer_name, static_metrics->ProductInfo.ManufacturerName, 1016 + sizeof(fru_info->manufacturer_name)); 1017 + strscpy(fru_info->fru_id, static_metrics->ProductInfo.FruId, 1018 + sizeof(fru_info->fru_id)); 1019 + 1020 + return 0; 1021 + } 1022 + 1023 + static void smu_v15_0_8_init_xgmi_data(struct smu_context *smu, 1024 + StaticMetricsTable_t *static_metrics) 1025 + { 1026 + uint16_t max_speed; 1027 + uint8_t max_width; 1028 + 1029 + max_width = (uint8_t)static_metrics->MaxXgmiWidth; 1030 + max_speed = (uint16_t)static_metrics->MaxXgmiBitrate; 1031 + amgpu_xgmi_set_max_speed_width(smu->adev, max_speed, max_width); 1032 + } 1033 + 1034 + static int smu_v15_0_8_set_driver_pptable(struct smu_context *smu) 1035 + { 1036 + struct smu_15_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; 1037 + struct smu_table_context *smu_table = &smu->smu_table; 1038 + StaticMetricsTable_t *static_metrics = (StaticMetricsTable_t *)smu_table->metrics_table; 1039 + PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable; 1040 + int ret, i, n; 1041 + uint32_t table_version; 1042 + 1043 + if (!pptable->init) { 1044 + ret = smu_v15_0_8_get_static_metrics_table(smu); 1045 + if (ret) 1046 + return ret; 1047 + 1048 + ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetMetricsVersion, 1049 + &table_version); 1050 + if (ret) 1051 + return ret; 1052 + smu_table->tables[SMU_TABLE_SMU_METRICS].version = 1053 + table_version; 1054 + 1055 + pptable->MaxSocketPowerLimit = 1056 + SMUQ10_ROUND(static_metrics->MaxSocketPowerLimit); 1057 + pptable->MaxGfxclkFrequency = 1058 + SMUQ10_ROUND(static_metrics->MaxGfxclkFrequency); 1059 + pptable->MinGfxclkFrequency = 1060 + SMUQ10_ROUND(static_metrics->MinGfxclkFrequency); 1061 + pptable->MaxFclkFrequency = 1062 + SMUQ10_ROUND(static_metrics->MaxFclkFrequency); 1063 + pptable->MinFclkFrequency = 1064 + SMUQ10_ROUND(static_metrics->MinFclkFrequency); 1065 + pptable->MaxGl2clkFrequency = 1066 + SMUQ10_ROUND(static_metrics->MaxGl2clkFrequency); 1067 + pptable->MinGl2clkFrequency = 1068 + SMUQ10_ROUND(static_metrics->MinGl2clkFrequency); 1069 + 1070 + for (i = 0; i < ARRAY_SIZE(static_metrics->UclkFrequencyTable); ++i) 1071 + pptable->UclkFrequencyTable[i] = 1072 + SMUQ10_ROUND(static_metrics->UclkFrequencyTable[i]); 1073 + 1074 + pptable->SocclkFrequency = SMUQ10_ROUND(static_metrics->SocclkFrequency); 1075 + pptable->LclkFrequency = SMUQ10_ROUND(static_metrics->LclkFrequency); 1076 + pptable->VclkFrequency = SMUQ10_ROUND(static_metrics->VclkFrequency); 1077 + pptable->DclkFrequency = SMUQ10_ROUND(static_metrics->DclkFrequency); 1078 + 1079 + pptable->CTFLimitMID = SMUQ10_ROUND(static_metrics->CTFLimit_MID); 1080 + pptable->CTFLimitAID = SMUQ10_ROUND(static_metrics->CTFLimit_AID); 1081 + pptable->CTFLimitXCD = SMUQ10_ROUND(static_metrics->CTFLimit_XCD); 1082 + pptable->CTFLimitHBM = SMUQ10_ROUND(static_metrics->CTFLimit_HBM); 1083 + pptable->ThermalLimitMID = SMUQ10_ROUND(static_metrics->ThermalLimit_MID); 1084 + pptable->ThermalLimitAID = SMUQ10_ROUND(static_metrics->ThermalLimit_AID); 1085 + pptable->ThermalLimitXCD = SMUQ10_ROUND(static_metrics->ThermalLimit_XCD); 1086 + pptable->ThermalLimitHBM = SMUQ10_ROUND(static_metrics->ThermalLimit_HBM); 1087 + 1088 + /* use MID0 serial number by default */ 1089 + pptable->PublicSerialNumberMID = 1090 + static_metrics->PublicSerialNumber_MID[0]; 1091 + 1092 + amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_SOC, 1093 + 0, pptable->PublicSerialNumberMID); 1094 + pptable->PublicSerialNumberAID = 1095 + static_metrics->PublicSerialNumber_AID[0]; 1096 + pptable->PublicSerialNumberXCD = 1097 + static_metrics->PublicSerialNumber_XCD[0]; 1098 + n = ARRAY_SIZE(static_metrics->PublicSerialNumber_MID); 1099 + for (i = 0; i < n; i++) { 1100 + amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_MID, i, 1101 + static_metrics->PublicSerialNumber_MID[i]); 1102 + } 1103 + n = ARRAY_SIZE(static_metrics->PublicSerialNumber_AID); 1104 + for (i = 0; i < n; i++) { 1105 + amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_AID, i, 1106 + static_metrics->PublicSerialNumber_AID[i]); 1107 + } 1108 + n = ARRAY_SIZE(static_metrics->PublicSerialNumber_XCD); 1109 + for (i = 0; i < n; i++) { 1110 + amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_XCD, i, 1111 + static_metrics->PublicSerialNumber_XCD[i]); 1112 + } 1113 + 1114 + ret = smu_v15_0_8_fru_get_product_info(smu, static_metrics); 1115 + if (ret) 1116 + return ret; 1117 + pptable->PPT1Max = static_metrics->PPT1Max; 1118 + pptable->PPT1Min = static_metrics->PPT1Min; 1119 + pptable->PPT1Default = static_metrics->PPT1Default; 1120 + 1121 + if (static_metrics->pldmVersion[0] != 0xFFFFFFFF) 1122 + smu->adev->firmware.pldm_version = 1123 + static_metrics->pldmVersion[0]; 1124 + dpm_context->board_volt = static_metrics->InputTelemetryVoltageInmV; 1125 + smu_v15_0_8_init_xgmi_data(smu, static_metrics); 1126 + pptable->init = true; 1127 + } 1128 + 1129 + return 0; 1130 + } 1131 + 1132 + static int smu_v15_0_8_set_default_dpm_table(struct smu_context *smu) 1133 + { 1134 + int ret; 1135 + 1136 + ret = smu_v15_0_8_set_driver_pptable(smu); 1137 + if (ret) 1138 + return ret; 1139 + 1140 + ret = smu_v15_0_8_set_dpm_table(smu); 1141 + if (ret) 1142 + return ret; 1143 + 1144 + return 0; 1145 + } 1146 + 1147 + static int smu_v15_0_8_irq_process(struct amdgpu_device *adev, 1148 + struct amdgpu_irq_src *source, 1149 + struct amdgpu_iv_entry *entry) 1150 + { 1151 + struct smu_context *smu = adev->powerplay.pp_handle; 1152 + struct smu_power_context *smu_power = &smu->smu_power; 1153 + struct smu_15_0_power_context *power_context = smu_power->power_context; 1154 + uint32_t client_id = entry->client_id; 1155 + uint32_t ctxid = entry->src_data[0]; 1156 + uint32_t src_id = entry->src_id; 1157 + uint32_t data; 1158 + 1159 + if (client_id == SOC_V1_0_IH_CLIENTID_MP1) { 1160 + if (src_id == IH_INTERRUPT_ID_TO_DRIVER) { 1161 + /* ACK SMUToHost interrupt */ 1162 + data = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL); 1163 + data = REG_SET_FIELD(data, MP1_SMN_IH_SW_INT_CTRL, INT_ACK, 1); 1164 + WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, data); 1165 + /* 1166 + * ctxid is used to distinguish different events for SMCToHost 1167 + * interrupt. 1168 + */ 1169 + switch (ctxid) { 1170 + case IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING: 1171 + /* 1172 + * Increment the throttle interrupt counter 1173 + */ 1174 + atomic64_inc(&smu->throttle_int_counter); 1175 + 1176 + if (!atomic_read(&adev->throttling_logging_enabled)) 1177 + return 0; 1178 + 1179 + /* This uses the new method which fixes the 1180 + * incorrect throttling status reporting 1181 + * through metrics table. For older FWs, 1182 + * it will be ignored. 1183 + */ 1184 + if (__ratelimit(&adev->throttling_logging_rs)) { 1185 + atomic_set( 1186 + &power_context->throttle_status, 1187 + entry->src_data[1]); 1188 + schedule_work(&smu->throttling_logging_work); 1189 + } 1190 + break; 1191 + default: 1192 + dev_dbg(adev->dev, "Unhandled context id %d from client:%d!\n", 1193 + ctxid, client_id); 1194 + break; 1195 + } 1196 + } 1197 + } 1198 + 1199 + return 0; 1200 + } 1201 + 1202 + static int smu_v15_0_8_set_irq_state(struct amdgpu_device *adev, 1203 + struct amdgpu_irq_src *source, 1204 + unsigned type, 1205 + enum amdgpu_interrupt_state state) 1206 + { 1207 + uint32_t val = 0; 1208 + 1209 + switch (state) { 1210 + case AMDGPU_IRQ_STATE_DISABLE: 1211 + /* For MP1 SW irqs */ 1212 + val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL); 1213 + val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT_CTRL, INT_MASK, 1); 1214 + WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, val); 1215 + 1216 + break; 1217 + case AMDGPU_IRQ_STATE_ENABLE: 1218 + /* For MP1 SW irqs */ 1219 + val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT); 1220 + val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT, ID, 0xFE); 1221 + val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT, VALID, 0); 1222 + WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT, val); 1223 + 1224 + val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL); 1225 + val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT_CTRL, INT_MASK, 0); 1226 + WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, val); 1227 + 1228 + break; 1229 + default: 1230 + break; 1231 + } 1232 + 1233 + return 0; 1234 + } 1235 + 1236 + static const struct amdgpu_irq_src_funcs smu_v15_0_8_irq_funcs = { 1237 + .set = smu_v15_0_8_set_irq_state, 1238 + .process = smu_v15_0_8_irq_process, 1239 + }; 1240 + 1241 + static int smu_v15_0_8_register_irq_handler(struct smu_context *smu) 1242 + { 1243 + struct amdgpu_device *adev = smu->adev; 1244 + struct amdgpu_irq_src *irq_src = &smu->irq_source; 1245 + int ret = 0; 1246 + 1247 + if (amdgpu_sriov_vf(adev)) 1248 + return 0; 1249 + 1250 + irq_src->num_types = 1; 1251 + irq_src->funcs = &smu_v15_0_8_irq_funcs; 1252 + 1253 + ret = amdgpu_irq_add_id(adev, SOC_V1_0_IH_CLIENTID_MP1, 1254 + IH_INTERRUPT_ID_TO_DRIVER, 1255 + irq_src); 1256 + if (ret) 1257 + return ret; 1258 + 1259 + return ret; 1260 + } 1261 + 1262 + static int smu_v15_0_8_notify_unload(struct smu_context *smu) 1263 + { 1264 + if (amdgpu_in_reset(smu->adev)) 1265 + return 0; 1266 + 1267 + dev_dbg(smu->adev->dev, "Notify PMFW about driver unload"); 1268 + /* Ignore return, just intimate FW that driver is not going to be there */ 1269 + smu_cmn_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL); 1270 + 1271 + return 0; 1272 + } 1273 + 1274 + 1275 + static int smu_v15_0_8_system_features_control(struct smu_context *smu, 1276 + bool enable) 1277 + { 1278 + struct amdgpu_device *adev = smu->adev; 1279 + int ret = 0; 1280 + 1281 + if (amdgpu_sriov_vf(adev)) 1282 + return 0; 1283 + 1284 + if (enable) 1285 + ret = smu_v15_0_system_features_control(smu, enable); 1286 + else 1287 + smu_v15_0_8_notify_unload(smu); 1288 + 1289 + return ret; 1290 + } 1291 + 1292 + /** 1293 + * smu_v15_0_8_get_enabled_mask - Get enabled SMU features (128-bit) 1294 + * @smu: SMU context 1295 + * @feature_mask: feature mask structure 1296 + * 1297 + * SMU 15 returns all 128 feature bits in a single message via out_args[0..3]. 1298 + * For backward compatibility, this function returns only the first 64 bits. 1299 + * 1300 + * Return: 0 on success, negative errno on failure 1301 + */ 1302 + static int smu_v15_0_8_get_enabled_mask(struct smu_context *smu, 1303 + struct smu_feature_bits *feature_mask) 1304 + { 1305 + struct smu_msg_args args = { 1306 + .msg = SMU_MSG_GetEnabledSmuFeatures, 1307 + .num_args = 0, 1308 + .num_out_args = 2, 1309 + }; 1310 + int ret; 1311 + 1312 + if (!feature_mask) 1313 + return -EINVAL; 1314 + 1315 + ret = smu->msg_ctl.ops->send_msg(&smu->msg_ctl, &args); 1316 + 1317 + if (ret) 1318 + return ret; 1319 + 1320 + smu_feature_bits_from_arr32(feature_mask, args.out_args, 1321 + SMU_FEATURE_NUM_DEFAULT); 1322 + 1323 + return 0; 1324 + } 1325 + 1326 + static bool smu_v15_0_8_is_dpm_running(struct smu_context *smu) 1327 + { 1328 + int ret = 0; 1329 + struct smu_feature_bits feature_enabled; 1330 + 1331 + ret = smu_v15_0_8_get_enabled_mask(smu, &feature_enabled); 1332 + if (ret) 1333 + return false; 1334 + 1335 + return smu_feature_bits_test_mask(&feature_enabled, 1336 + smu_v15_0_8_dpm_features.bits); 1337 + } 1338 + 1339 + static ssize_t smu_v15_0_8_get_pm_metrics(struct smu_context *smu, 1340 + void *metrics, size_t max_size) 1341 + { 1342 + struct smu_table_context *smu_table = &smu->smu_table; 1343 + struct amdgpu_pm_metrics *pm_metrics = (struct amdgpu_pm_metrics *)metrics; 1344 + uint32_t table_version = smu_table->tables[SMU_TABLE_SMU_METRICS].version; 1345 + uint32_t table_size = smu_table->tables[SMU_TABLE_SMU_METRICS].size; 1346 + uint32_t pmfw_version; 1347 + int ret; 1348 + 1349 + if (!pm_metrics || !max_size) 1350 + return -EINVAL; 1351 + 1352 + if (max_size < (table_size + sizeof(pm_metrics->common_header))) 1353 + return -EOVERFLOW; 1354 + 1355 + /* Don't use cached metrics data */ 1356 + ret = smu_v15_0_8_get_metrics_table_internal(smu, 0, pm_metrics->data); 1357 + if (ret) 1358 + return ret; 1359 + 1360 + smu_cmn_get_smc_version(smu, NULL, &pmfw_version); 1361 + memset(&pm_metrics->common_header, 0, sizeof(pm_metrics->common_header)); 1362 + pm_metrics->common_header.mp1_ip_discovery_version = 1363 + amdgpu_ip_version(smu->adev, MP1_HWIP, 0); 1364 + pm_metrics->common_header.pmfw_version = pmfw_version; 1365 + pm_metrics->common_header.pmmetrics_version = table_version; 1366 + pm_metrics->common_header.structure_size = 1367 + sizeof(pm_metrics->common_header) + table_size; 1368 + 1369 + return pm_metrics->common_header.structure_size; 1370 + } 1371 + 1372 + static int smu_v15_0_8_mode2_reset(struct smu_context *smu) 1373 + { 1374 + struct smu_msg_ctl *ctl = &smu->msg_ctl; 1375 + struct amdgpu_device *adev = smu->adev; 1376 + int timeout = 10; 1377 + int ret = 0; 1378 + 1379 + mutex_lock(&ctl->lock); 1380 + 1381 + ret = smu_msg_send_async_locked(ctl, SMU_MSG_GfxDeviceDriverReset, 1382 + SMU_RESET_MODE_2); 1383 + 1384 + if (ret) 1385 + goto out; 1386 + 1387 + /* Reset takes a bit longer, wait for 200ms. */ 1388 + msleep(200); 1389 + 1390 + dev_dbg(adev->dev, "wait for reset ack\n"); 1391 + do { 1392 + ret = smu_msg_wait_response(ctl, 0); 1393 + /* Wait a bit more time for getting ACK */ 1394 + if (ret == -ETIME) { 1395 + --timeout; 1396 + usleep_range(500, 1000); 1397 + continue; 1398 + } 1399 + 1400 + if (ret) 1401 + goto out; 1402 + 1403 + } while (ret == -ETIME && timeout); 1404 + 1405 + out: 1406 + mutex_unlock(&ctl->lock); 1407 + 1408 + if (ret) 1409 + dev_err(adev->dev, "failed to send mode2 reset, error code %d", 1410 + ret); 1411 + 1412 + return ret; 1413 + } 1414 + 1415 + static bool smu_v15_0_8_is_temp_metrics_supported(struct smu_context *smu, 1416 + enum smu_temp_metric_type type) 1417 + { 1418 + switch (type) { 1419 + case SMU_TEMP_METRIC_BASEBOARD: 1420 + if (smu->adev->gmc.xgmi.physical_node_id == 0) 1421 + return true; 1422 + return false; 1423 + case SMU_TEMP_METRIC_GPUBOARD: 1424 + return true; 1425 + default: 1426 + return false; 1427 + } 1428 + } 1429 + 1430 + static void smu_v15_0_8_fill_baseboard_temp_metrics( 1431 + struct smu_v15_0_8_baseboard_temp_metrics *baseboard_temp_metrics, 1432 + const SystemMetricsTable_t *metrics) 1433 + { 1434 + baseboard_temp_metrics->accumulation_counter = metrics->AccumulationCounter; 1435 + baseboard_temp_metrics->label_version = metrics->LabelVersion; 1436 + baseboard_temp_metrics->node_id = metrics->NodeIdentifier; 1437 + 1438 + baseboard_temp_metrics->system_temp_ubb_fpga = 1439 + metrics->SystemTemperatures[SYSTEM_TEMP_UBB_FPGA]; 1440 + baseboard_temp_metrics->system_temp_ubb_front = 1441 + metrics->SystemTemperatures[SYSTEM_TEMP_UBB_FRONT]; 1442 + baseboard_temp_metrics->system_temp_ubb_back = 1443 + metrics->SystemTemperatures[SYSTEM_TEMP_UBB_BACK]; 1444 + baseboard_temp_metrics->system_temp_ubb_oam7 = 1445 + metrics->SystemTemperatures[SYSTEM_TEMP_UBB_OAM7]; 1446 + baseboard_temp_metrics->system_temp_ubb_ibc = 1447 + metrics->SystemTemperatures[SYSTEM_TEMP_UBB_IBC]; 1448 + baseboard_temp_metrics->system_temp_ubb_ufpga = 1449 + metrics->SystemTemperatures[SYSTEM_TEMP_UBB_UFPGA]; 1450 + baseboard_temp_metrics->system_temp_ubb_oam1 = 1451 + metrics->SystemTemperatures[SYSTEM_TEMP_UBB_OAM1]; 1452 + baseboard_temp_metrics->system_temp_oam_0_1_hsc = 1453 + metrics->SystemTemperatures[SYSTEM_TEMP_OAM_0_1_HSC]; 1454 + baseboard_temp_metrics->system_temp_oam_2_3_hsc = 1455 + metrics->SystemTemperatures[SYSTEM_TEMP_OAM_2_3_HSC]; 1456 + baseboard_temp_metrics->system_temp_oam_4_5_hsc = 1457 + metrics->SystemTemperatures[SYSTEM_TEMP_OAM_4_5_HSC]; 1458 + baseboard_temp_metrics->system_temp_oam_6_7_hsc = 1459 + metrics->SystemTemperatures[SYSTEM_TEMP_OAM_6_7_HSC]; 1460 + baseboard_temp_metrics->system_temp_ubb_fpga_0v72_vr = 1461 + metrics->SystemTemperatures[SYSTEM_TEMP_UBB_FPGA_0V72_VR]; 1462 + baseboard_temp_metrics->system_temp_ubb_fpga_3v3_vr = 1463 + metrics->SystemTemperatures[SYSTEM_TEMP_UBB_FPGA_3V3_VR]; 1464 + baseboard_temp_metrics->system_temp_retimer_0_1_2_3_1v2_vr = 1465 + metrics->SystemTemperatures[SYSTEM_TEMP_RETIMER_0_1_2_3_1V2_VR]; 1466 + baseboard_temp_metrics->system_temp_retimer_4_5_6_7_1v2_vr = 1467 + metrics->SystemTemperatures[SYSTEM_TEMP_RETIMER_4_5_6_7_1V2_VR]; 1468 + baseboard_temp_metrics->system_temp_retimer_0_1_0v9_vr = 1469 + metrics->SystemTemperatures[SYSTEM_TEMP_RETIMER_0_1_0V9_VR]; 1470 + baseboard_temp_metrics->system_temp_retimer_4_5_0v9_vr = 1471 + metrics->SystemTemperatures[SYSTEM_TEMP_RETIMER_4_5_0V9_VR]; 1472 + baseboard_temp_metrics->system_temp_retimer_2_3_0v9_vr = 1473 + metrics->SystemTemperatures[SYSTEM_TEMP_RETIMER_2_3_0V9_VR]; 1474 + baseboard_temp_metrics->system_temp_retimer_6_7_0v9_vr = 1475 + metrics->SystemTemperatures[SYSTEM_TEMP_RETIMER_6_7_0V9_VR]; 1476 + baseboard_temp_metrics->system_temp_oam_0_1_2_3_3v3_vr = 1477 + metrics->SystemTemperatures[SYSTEM_TEMP_OAM_0_1_2_3_3V3_VR]; 1478 + baseboard_temp_metrics->system_temp_oam_4_5_6_7_3v3_vr = 1479 + metrics->SystemTemperatures[SYSTEM_TEMP_OAM_4_5_6_7_3V3_VR]; 1480 + baseboard_temp_metrics->system_temp_ibc_hsc = 1481 + metrics->SystemTemperatures[SYSTEM_TEMP_IBC_HSC]; 1482 + baseboard_temp_metrics->system_temp_ibc = 1483 + metrics->SystemTemperatures[SYSTEM_TEMP_IBC]; 1484 + } 1485 + 1486 + static void smu_v15_0_8_fill_gpuboard_temp_metrics( 1487 + struct smu_v15_0_8_gpuboard_temp_metrics *gpuboard_temp_metrics, 1488 + const SystemMetricsTable_t *metrics) 1489 + { 1490 + gpuboard_temp_metrics->accumulation_counter = metrics->AccumulationCounter; 1491 + gpuboard_temp_metrics->label_version = metrics->LabelVersion; 1492 + gpuboard_temp_metrics->node_id = metrics->NodeIdentifier; 1493 + 1494 + gpuboard_temp_metrics->node_temp_retimer = 1495 + metrics->NodeTemperatures[NODE_TEMP_RETIMER]; 1496 + gpuboard_temp_metrics->node_temp_ibc = 1497 + metrics->NodeTemperatures[NODE_TEMP_IBC_TEMP]; 1498 + gpuboard_temp_metrics->node_temp_ibc_2 = 1499 + metrics->NodeTemperatures[NODE_TEMP_IBC_2_TEMP]; 1500 + gpuboard_temp_metrics->node_temp_vdd18_vr = 1501 + metrics->NodeTemperatures[NODE_TEMP_VDD18_VR_TEMP]; 1502 + gpuboard_temp_metrics->node_temp_04_hbm_b_vr = 1503 + metrics->NodeTemperatures[NODE_TEMP_04_HBM_B_VR_TEMP]; 1504 + gpuboard_temp_metrics->node_temp_04_hbm_d_vr = 1505 + metrics->NodeTemperatures[NODE_TEMP_04_HBM_D_VR_TEMP]; 1506 + 1507 + gpuboard_temp_metrics->vr_temp_vddcr_socio_a = 1508 + metrics->VrTemperatures[SVI_PLANE_VDDCR_SOCIO_A_TEMP]; 1509 + gpuboard_temp_metrics->vr_temp_vddcr_socio_c = 1510 + metrics->VrTemperatures[SVI_PLANE_VDDCR_SOCIO_C_TEMP]; 1511 + gpuboard_temp_metrics->vr_temp_vddcr_x0 = 1512 + metrics->VrTemperatures[SVI_PLANE_VDDCR_X0_TEMP]; 1513 + gpuboard_temp_metrics->vr_temp_vddcr_x1 = 1514 + metrics->VrTemperatures[SVI_PLANE_VDDCR_X1_TEMP]; 1515 + gpuboard_temp_metrics->vr_temp_vddio_hbm_b = 1516 + metrics->VrTemperatures[SVI_PLANE_VDDIO_HBM_B_TEMP]; 1517 + gpuboard_temp_metrics->vr_temp_vddio_hbm_d = 1518 + metrics->VrTemperatures[SVI_PLANE_VDDIO_HBM_D_TEMP]; 1519 + gpuboard_temp_metrics->vr_temp_vddio_04_hbm_b = 1520 + metrics->VrTemperatures[SVI_PLANE_VDDIO_04_HBM_B_TEMP]; 1521 + gpuboard_temp_metrics->vr_temp_vddio_04_hbm_d = 1522 + metrics->VrTemperatures[SVI_PLANE_VDDIO_04_HBM_D_TEMP]; 1523 + gpuboard_temp_metrics->vr_temp_vddcr_hbm_b = 1524 + metrics->VrTemperatures[SVI_PLANE_VDDCR_HBM_B_TEMP]; 1525 + gpuboard_temp_metrics->vr_temp_vddcr_hbm_d = 1526 + metrics->VrTemperatures[SVI_PLANE_VDDCR_HBM_D_TEMP]; 1527 + gpuboard_temp_metrics->vr_temp_vddcr_075_hbm_b = 1528 + metrics->VrTemperatures[SVI_PLANE_VDDCR_075_HBM_B_TEMP]; 1529 + gpuboard_temp_metrics->vr_temp_vddcr_075_hbm_d = 1530 + metrics->VrTemperatures[SVI_PLANE_VDDCR_075_HBM_D_TEMP]; 1531 + gpuboard_temp_metrics->vr_temp_vddio_11_gta_a = 1532 + metrics->VrTemperatures[SVI_PLANE_VDDIO_11_GTA_A_TEMP]; 1533 + gpuboard_temp_metrics->vr_temp_vddio_11_gta_c = 1534 + metrics->VrTemperatures[SVI_PLANE_VDDIO_11_GTA_C_TEMP]; 1535 + gpuboard_temp_metrics->vr_temp_vddan_075_gta_a = 1536 + metrics->VrTemperatures[SVI_PLANE_VDDAN_075_GTA_A_TEMP]; 1537 + gpuboard_temp_metrics->vr_temp_vddan_075_gta_c = 1538 + metrics->VrTemperatures[SVI_PLANE_VDDAN_075_GTA_C_TEMP]; 1539 + gpuboard_temp_metrics->vr_temp_vddcr_075_ucie = 1540 + metrics->VrTemperatures[SVI_PLANE_VDDCR_075_UCIE_TEMP]; 1541 + gpuboard_temp_metrics->vr_temp_vddio_065_ucieaa = 1542 + metrics->VrTemperatures[SVI_PLANE_VDDIO_065_UCIEAA_TEMP]; 1543 + gpuboard_temp_metrics->vr_temp_vddio_065_ucieam_a = 1544 + metrics->VrTemperatures[SVI_PLANE_VDDIO_065_UCIEAM_A_TEMP]; 1545 + gpuboard_temp_metrics->vr_temp_vddio_065_ucieam_c = 1546 + metrics->VrTemperatures[SVI_PLANE_VDDIO_065_UCIEAM_C_TEMP]; 1547 + gpuboard_temp_metrics->vr_temp_vddan_075 = 1548 + metrics->VrTemperatures[SVI_PLANE_VDDAN_075_TEMP]; 1549 + } 1550 + 1551 + static ssize_t smu_v15_0_8_get_temp_metrics(struct smu_context *smu, 1552 + enum smu_temp_metric_type type, 1553 + void *table) 1554 + { 1555 + struct smu_v15_0_8_baseboard_temp_metrics *baseboard_temp_metrics; 1556 + struct smu_v15_0_8_gpuboard_temp_metrics *gpuboard_temp_metrics; 1557 + struct smu_table_context *smu_table = &smu->smu_table; 1558 + struct smu_table *tables = smu_table->tables; 1559 + SystemMetricsTable_t *metrics; 1560 + struct smu_table *sys_table; 1561 + int ret; 1562 + 1563 + ret = smu_v15_0_8_get_system_metrics_table(smu); 1564 + if (ret) 1565 + return ret; 1566 + 1567 + sys_table = &tables[SMU_TABLE_PMFW_SYSTEM_METRICS]; 1568 + metrics = (SystemMetricsTable_t *)sys_table->cache.buffer; 1569 + 1570 + switch (type) { 1571 + case SMU_TEMP_METRIC_GPUBOARD: 1572 + gpuboard_temp_metrics = 1573 + (struct smu_v15_0_8_gpuboard_temp_metrics *) 1574 + smu_driver_table_ptr(smu, SMU_DRIVER_TABLE_GPUBOARD_TEMP_METRICS); 1575 + smu_driver_table_update_cache_time(smu, SMU_DRIVER_TABLE_GPUBOARD_TEMP_METRICS); 1576 + smu_v15_0_8_fill_gpuboard_temp_metrics(gpuboard_temp_metrics, 1577 + metrics); 1578 + memcpy(table, gpuboard_temp_metrics, sizeof(*gpuboard_temp_metrics)); 1579 + return sizeof(*gpuboard_temp_metrics); 1580 + case SMU_TEMP_METRIC_BASEBOARD: 1581 + baseboard_temp_metrics = 1582 + (struct smu_v15_0_8_baseboard_temp_metrics *) 1583 + smu_driver_table_ptr(smu, SMU_DRIVER_TABLE_BASEBOARD_TEMP_METRICS); 1584 + smu_driver_table_update_cache_time(smu, SMU_DRIVER_TABLE_BASEBOARD_TEMP_METRICS); 1585 + smu_v15_0_8_fill_baseboard_temp_metrics(baseboard_temp_metrics, 1586 + metrics); 1587 + memcpy(table, baseboard_temp_metrics, sizeof(*baseboard_temp_metrics)); 1588 + return sizeof(*baseboard_temp_metrics); 1589 + default: 1590 + return -EINVAL; 1591 + } 1592 + } 1593 + 1594 + static ssize_t smu_v15_0_8_get_gpu_metrics(struct smu_context *smu, void **table) 1595 + { 1596 + struct smu_table_context *smu_table = &smu->smu_table; 1597 + struct smu_v15_0_8_gpu_metrics *gpu_metrics; 1598 + struct amdgpu_device *adev = smu->adev; 1599 + int ret = 0, xcc_id, inst, i, j, idx; 1600 + uint32_t aid_mask = adev->aid_mask; 1601 + uint32_t mid_mask = adev->aid_mask; 1602 + MetricsTable_t *metrics; 1603 + 1604 + metrics = kzalloc(sizeof(MetricsTable_t), GFP_KERNEL); 1605 + 1606 + ret = smu_v15_0_8_get_metrics_table_internal(smu, 1, NULL); 1607 + if (ret) 1608 + return ret; 1609 + 1610 + metrics = (MetricsTable_t *)smu_table->metrics_table; 1611 + gpu_metrics = (struct smu_v15_0_8_gpu_metrics *)smu_driver_table_ptr(smu, 1612 + SMU_DRIVER_TABLE_GPU_METRICS); 1613 + 1614 + gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); 1615 + 1616 + gpu_metrics->temperature_hotspot = SMUQ10_ROUND(metrics->MaxSocketTemperature); 1617 + 1618 + /* Per-HBM stack temperatures */ 1619 + if (adev->umc.active_mask) { 1620 + u64 mask = adev->umc.active_mask; 1621 + int out_idx = 0; 1622 + int stack_idx; 1623 + 1624 + if (unlikely(hweight64(mask)/4 > SMU_15_0_8_MAX_HBM_STACKS)) 1625 + dev_warn(adev->dev, "Invalid umc mask %lld\n", mask); 1626 + else { 1627 + for_each_hbm_stack(stack_idx, mask) { 1628 + if (!hbm_stack_mask_valid(mask)) 1629 + continue; 1630 + gpu_metrics->temperature_hbm[out_idx++] = 1631 + SMUQ10_ROUND(metrics->HbmTemperature[stack_idx]); 1632 + } 1633 + } 1634 + } 1635 + 1636 + /* Reports max temperature of all voltage rails */ 1637 + gpu_metrics->temperature_vrsoc = SMUQ10_ROUND(metrics->MaxVrTemperature); 1638 + /* MID, AID, XCD temperatures */ 1639 + idx = 0; 1640 + for_each_inst(i, mid_mask) { 1641 + gpu_metrics->temperature_mid[idx] = SMUQ10_ROUND(metrics->MidTemperature[i]); 1642 + idx++; 1643 + } 1644 + 1645 + idx = 0; 1646 + for_each_inst(i, aid_mask) { 1647 + gpu_metrics->temperature_aid[idx] = SMUQ10_ROUND(metrics->AidTemperature[i]); 1648 + idx++; 1649 + } 1650 + 1651 + for (i = 0; i < NUM_XCC(adev->gfx.xcc_mask); ++i) { 1652 + xcc_id = GET_INST(GC, i); 1653 + if (xcc_id >= 0) 1654 + gpu_metrics->temperature_xcd[i] = SMUQ10_ROUND(metrics->XcdTemperature[xcc_id]); 1655 + } 1656 + /* Power */ 1657 + gpu_metrics->curr_socket_power = SMUQ10_ROUND(metrics->SocketPower); 1658 + 1659 + gpu_metrics->average_gfx_activity = SMUQ10_ROUND(metrics->SocketGfxBusy); 1660 + gpu_metrics->average_umc_activity = SMUQ10_ROUND(metrics->DramBandwidthUtilization); 1661 + gpu_metrics->mem_max_bandwidth = SMUQ10_ROUND(metrics->MaxDramBandwidth); 1662 + 1663 + /* Energy counter reported in 15.259uJ (2^-16) units */ 1664 + gpu_metrics->energy_accumulator = metrics->SocketEnergyAcc; 1665 + 1666 + for (i = 0; i < NUM_XCC(adev->gfx.xcc_mask); ++i) { 1667 + xcc_id = GET_INST(GC, i); 1668 + if (xcc_id >= 0) { 1669 + gpu_metrics->current_gfxclk[i] = 1670 + SMUQ10_ROUND(metrics->GfxclkFrequency[xcc_id]); 1671 + } 1672 + } 1673 + 1674 + /* Per-MID clocks */ 1675 + idx = 0; 1676 + for_each_inst(i, mid_mask) { 1677 + gpu_metrics->current_socclk[idx] = SMUQ10_ROUND(metrics->SocclkFrequency[i]); 1678 + idx++; 1679 + } 1680 + 1681 + /* Per-VCN clocks */ 1682 + for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 1683 + inst = GET_INST(VCN, i); 1684 + if (inst >= 0) { 1685 + gpu_metrics->current_vclk0[i] = SMUQ10_ROUND(metrics->VclkFrequency[inst]); 1686 + gpu_metrics->current_dclk0[i] = SMUQ10_ROUND(metrics->DclkFrequency[inst]); 1687 + } 1688 + } 1689 + 1690 + /* Per-AID clocks */ 1691 + idx = 0; 1692 + for_each_inst(i, aid_mask) { 1693 + gpu_metrics->current_uclk[idx] = SMUQ10_ROUND(metrics->UclkFrequency[i]); 1694 + idx++; 1695 + } 1696 + 1697 + /* Total accumulated cycle counter */ 1698 + gpu_metrics->accumulation_counter = metrics->AccumulationCounter; 1699 + 1700 + /* Accumulated throttler residencies */ 1701 + gpu_metrics->prochot_residency_acc = metrics->ProchotResidencyAcc; 1702 + gpu_metrics->ppt_residency_acc = metrics->PptResidencyAcc; 1703 + gpu_metrics->socket_thm_residency_acc = metrics->SocketThmResidencyAcc; 1704 + gpu_metrics->vr_thm_residency_acc = metrics->VrThmResidencyAcc; 1705 + gpu_metrics->hbm_thm_residency_acc = metrics->HbmThmResidencyAcc; 1706 + 1707 + gpu_metrics->gfx_activity_acc = SMUQ10_ROUND(metrics->SocketGfxBusyAcc); 1708 + gpu_metrics->mem_activity_acc = SMUQ10_ROUND(metrics->DramBandwidthUtilizationAcc); 1709 + 1710 + for (i = 0; i < NUM_XGMI_LINKS; i++) { 1711 + j = amdgpu_xgmi_get_ext_link(adev, i); 1712 + if (j < 0 || j >= NUM_XGMI_LINKS) 1713 + continue; 1714 + ret = amdgpu_get_xgmi_link_status(adev, i); 1715 + if (ret >= 0) 1716 + gpu_metrics->xgmi_link_status[j] = ret; 1717 + } 1718 + 1719 + gpu_metrics->xgmi_read_data_acc = SMUQ10_ROUND(metrics->XgmiReadBandwidthAcc); 1720 + gpu_metrics->xgmi_write_data_acc = SMUQ10_ROUND(metrics->XgmiWriteBandwidthAcc); 1721 + 1722 + for (i = 0; i < NUM_XCC(adev->gfx.xcc_mask); ++i) { 1723 + inst = GET_INST(GC, i); 1724 + gpu_metrics->gfx_busy_inst[i] = SMUQ10_ROUND(metrics->GfxBusy[inst]); 1725 + gpu_metrics->gfx_busy_acc[i] = SMUQ10_ROUND(metrics->GfxBusyAcc[inst]); 1726 + gpu_metrics->gfx_below_host_limit_ppt_acc[i] = 1727 + SMUQ10_ROUND(metrics->GfxclkBelowHostLimitPptAcc[inst]); 1728 + gpu_metrics->gfx_below_host_limit_thm_acc[i] = 1729 + SMUQ10_ROUND(metrics->GfxclkBelowHostLimitThmAcc[inst]); 1730 + gpu_metrics->gfx_low_utilization_acc[i] = 1731 + SMUQ10_ROUND(metrics->GfxclkLowUtilizationAcc[inst]); 1732 + gpu_metrics->gfx_below_host_limit_total_acc[i] = 1733 + SMUQ10_ROUND(metrics->GfxclkBelowHostLimitTotalAcc[inst]); 1734 + } 1735 + 1736 + gpu_metrics->xgmi_link_width = metrics->XgmiWidth; 1737 + gpu_metrics->xgmi_link_speed = metrics->XgmiBitrate; 1738 + 1739 + gpu_metrics->firmware_timestamp = metrics->Timestamp; 1740 + 1741 + *table = gpu_metrics; 1742 + 1743 + smu_driver_table_update_cache_time(smu, SMU_DRIVER_TABLE_GPU_METRICS); 1744 + 1745 + return sizeof(*gpu_metrics); 1746 + } 1747 + 1748 + static void smu_v15_0_8_get_unique_id(struct smu_context *smu) 1749 + { 1750 + struct amdgpu_device *adev = smu->adev; 1751 + struct smu_table_context *smu_table = &smu->smu_table; 1752 + PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable; 1753 + 1754 + adev->unique_id = pptable->PublicSerialNumberMID; 1755 + } 1756 + 1757 + static int smu_v15_0_8_get_power_limit(struct smu_context *smu, 1758 + uint32_t *current_power_limit, 1759 + uint32_t *default_power_limit, 1760 + uint32_t *max_power_limit, 1761 + uint32_t *min_power_limit) 1762 + { 1763 + struct smu_table_context *smu_table = &smu->smu_table; 1764 + PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable; 1765 + uint32_t power_limit = 0; 1766 + int ret; 1767 + 1768 + ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetPptLimit, &power_limit); 1769 + if (ret) { 1770 + dev_err(smu->adev->dev, "Couldn't get PPT limit"); 1771 + return -EINVAL; 1772 + } 1773 + 1774 + if (current_power_limit) 1775 + *current_power_limit = power_limit; 1776 + 1777 + if (default_power_limit) 1778 + *max_power_limit = pptable->MaxSocketPowerLimit; 1779 + 1780 + if (max_power_limit) 1781 + *max_power_limit = pptable->MaxSocketPowerLimit; 1782 + 1783 + if (min_power_limit) 1784 + *min_power_limit = 0; 1785 + 1786 + return 0; 1787 + } 1788 + 1789 + static int smu_v15_0_8_populate_umd_state_clk(struct smu_context *smu) 1790 + { 1791 + struct smu_15_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; 1792 + struct smu_dpm_table *gfx_table = &dpm_context->dpm_tables.gfx_table; 1793 + struct smu_dpm_table *mem_table = &dpm_context->dpm_tables.uclk_table; 1794 + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; 1795 + 1796 + pstate_table->gfxclk_pstate.curr.min = SMU_DPM_TABLE_MIN(gfx_table); 1797 + pstate_table->gfxclk_pstate.curr.max = SMU_DPM_TABLE_MAX(gfx_table); 1798 + 1799 + pstate_table->uclk_pstate.curr.min = SMU_DPM_TABLE_MIN(mem_table); 1800 + pstate_table->uclk_pstate.curr.max = SMU_DPM_TABLE_MAX(mem_table); 1801 + return 0; 1802 + } 1803 + 1804 + static int smu_v15_0_8_set_gfx_soft_freq_limited_range(struct smu_context *smu, 1805 + uint32_t min, 1806 + uint32_t max) 1807 + { 1808 + int ret; 1809 + 1810 + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk, 1811 + max & 0xffff, NULL); 1812 + if (ret) 1813 + return ret; 1814 + 1815 + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinGfxclk, 1816 + min & 0xffff, NULL); 1817 + 1818 + return ret; 1819 + } 1820 + 1821 + static int smu_v15_0_8_set_performance_level(struct smu_context *smu, 1822 + enum amd_dpm_forced_level level) 1823 + { 1824 + struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 1825 + struct smu_15_0_dpm_context *dpm_context = smu_dpm->dpm_context; 1826 + struct smu_dpm_table *gfx_table = &dpm_context->dpm_tables.gfx_table; 1827 + struct smu_dpm_table *uclk_table = &dpm_context->dpm_tables.uclk_table; 1828 + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; 1829 + int ret; 1830 + 1831 + switch (level) { 1832 + case AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM: 1833 + /* Determinism not supported on SMU v15.0.8 */ 1834 + ret = -EOPNOTSUPP; 1835 + break; 1836 + 1837 + case AMD_DPM_FORCED_LEVEL_AUTO: 1838 + /* Restore GFXCLK to default range */ 1839 + if ((SMU_DPM_TABLE_MIN(gfx_table) != 1840 + pstate_table->gfxclk_pstate.curr.min) || 1841 + (SMU_DPM_TABLE_MAX(gfx_table) != 1842 + pstate_table->gfxclk_pstate.curr.max)) { 1843 + ret = smu_v15_0_8_set_gfx_soft_freq_limited_range( 1844 + smu, SMU_DPM_TABLE_MIN(gfx_table), 1845 + SMU_DPM_TABLE_MAX(gfx_table)); 1846 + if (ret) 1847 + goto out; 1848 + 1849 + pstate_table->gfxclk_pstate.curr.min = 1850 + SMU_DPM_TABLE_MIN(gfx_table); 1851 + pstate_table->gfxclk_pstate.curr.max = 1852 + SMU_DPM_TABLE_MAX(gfx_table); 1853 + } 1854 + 1855 + /* Restore UCLK to default max */ 1856 + if (SMU_DPM_TABLE_MAX(uclk_table) != 1857 + pstate_table->uclk_pstate.curr.max) { 1858 + /* Min UCLK is not expected to be changed */ 1859 + ret = smu_v15_0_set_soft_freq_limited_range(smu, 1860 + SMU_UCLK, 0, 1861 + SMU_DPM_TABLE_MAX(uclk_table), 1862 + false); 1863 + if (ret) 1864 + goto out; 1865 + 1866 + pstate_table->uclk_pstate.curr.max = 1867 + SMU_DPM_TABLE_MAX(uclk_table); 1868 + } 1869 + 1870 + if (ret) 1871 + goto out; 1872 + 1873 + smu_cmn_reset_custom_level(smu); 1874 + 1875 + break; 1876 + case AMD_DPM_FORCED_LEVEL_MANUAL: 1877 + ret = 0; 1878 + break; 1879 + default: 1880 + ret = -EOPNOTSUPP; 1881 + break; 1882 + } 1883 + 1884 + out: 1885 + return ret; 1886 + } 1887 + 1888 + static int smu_v15_0_8_set_soft_freq_limited_range(struct smu_context *smu, 1889 + enum smu_clk_type clk_type, 1890 + uint32_t min, uint32_t max, 1891 + bool automatic) 1892 + { 1893 + struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 1894 + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; 1895 + int ret = 0; 1896 + 1897 + if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK && 1898 + clk_type != SMU_UCLK) 1899 + return -EINVAL; 1900 + 1901 + if (smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) 1902 + return -EINVAL; 1903 + 1904 + if (smu_dpm->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) { 1905 + if (min >= max) { 1906 + dev_err(smu->adev->dev, 1907 + "Minimum clk should be less than the maximum allowed clock\n"); 1908 + return -EINVAL; 1909 + } 1910 + 1911 + if (clk_type == SMU_GFXCLK || clk_type == SMU_SCLK) { 1912 + if ((min == pstate_table->gfxclk_pstate.curr.min) && 1913 + (max == pstate_table->gfxclk_pstate.curr.max)) 1914 + return 0; 1915 + 1916 + ret = smu_v15_0_8_set_gfx_soft_freq_limited_range(smu, 1917 + min, max); 1918 + if (!ret) { 1919 + pstate_table->gfxclk_pstate.curr.min = min; 1920 + pstate_table->gfxclk_pstate.curr.max = max; 1921 + } 1922 + } 1923 + 1924 + if (clk_type == SMU_UCLK) { 1925 + if (max == pstate_table->uclk_pstate.curr.max) 1926 + return 0; 1927 + 1928 + ret = smu_v15_0_set_soft_freq_limited_range(smu, 1929 + SMU_UCLK, 1930 + 0, max, 1931 + false); 1932 + if (!ret) 1933 + pstate_table->uclk_pstate.curr.max = max; 1934 + } 1935 + 1936 + return ret; 1937 + } 1938 + 1939 + return 0; 1940 + } 1941 + 1942 + static int smu_v15_0_8_od_edit_dpm_table(struct smu_context *smu, 1943 + enum PP_OD_DPM_TABLE_COMMAND type, 1944 + long input[], uint32_t size) 1945 + { 1946 + struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 1947 + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; 1948 + struct smu_15_0_dpm_context *dpm_context = smu_dpm->dpm_context; 1949 + uint32_t min_clk, max_clk; 1950 + int ret; 1951 + 1952 + /* Only allowed in manual mode */ 1953 + if (smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) 1954 + return -EINVAL; 1955 + 1956 + switch (type) { 1957 + case PP_OD_EDIT_SCLK_VDDC_TABLE: 1958 + if (size != 2) { 1959 + dev_err(smu->adev->dev, 1960 + "Input parameter number not correct\n"); 1961 + return -EINVAL; 1962 + } 1963 + min_clk = SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.gfx_table); 1964 + max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.gfx_table); 1965 + if (input[0] == 0) { 1966 + if (input[1] < min_clk) { 1967 + dev_warn(smu->adev->dev, 1968 + "Minimum GFX clk (%ld) MHz specified is less than the minimum allowed (%d) MHz\n", 1969 + input[1], min_clk); 1970 + pstate_table->gfxclk_pstate.custom.min = 1971 + pstate_table->gfxclk_pstate.curr.min; 1972 + return -EINVAL; 1973 + } 1974 + 1975 + pstate_table->gfxclk_pstate.custom.min = input[1]; 1976 + } else if (input[0] == 1) { 1977 + if (input[1] > max_clk) { 1978 + dev_warn(smu->adev->dev, 1979 + "Maximum GFX clk (%ld) MHz specified is greater than the maximum allowed (%d) MHz\n", 1980 + input[1], max_clk); 1981 + pstate_table->gfxclk_pstate.custom.max = 1982 + pstate_table->gfxclk_pstate.curr.max; 1983 + return -EINVAL; 1984 + } 1985 + 1986 + pstate_table->gfxclk_pstate.custom.max = input[1]; 1987 + } else { 1988 + return -EINVAL; 1989 + } 1990 + break; 1991 + case PP_OD_EDIT_MCLK_VDDC_TABLE: 1992 + if (size != 2) { 1993 + dev_err(smu->adev->dev, 1994 + "Input parameter number not correct\n"); 1995 + return -EINVAL; 1996 + } 1997 + 1998 + if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) { 1999 + dev_warn(smu->adev->dev, 2000 + "UCLK_LIMITS setting not supported!\n"); 2001 + return -EOPNOTSUPP; 2002 + } 2003 + max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.uclk_table); 2004 + if (input[0] == 0) { 2005 + dev_info(smu->adev->dev, 2006 + "Setting min UCLK level is not supported"); 2007 + return -EINVAL; 2008 + } else if (input[0] == 1) { 2009 + if (input[1] > max_clk) { 2010 + dev_warn(smu->adev->dev, 2011 + "Maximum UCLK (%ld) MHz specified is greater than the maximum allowed (%d) MHz\n", 2012 + input[1], max_clk); 2013 + pstate_table->uclk_pstate.custom.max = 2014 + pstate_table->uclk_pstate.curr.max; 2015 + 2016 + return -EINVAL; 2017 + } 2018 + 2019 + pstate_table->uclk_pstate.custom.max = input[1]; 2020 + } 2021 + break; 2022 + case PP_OD_RESTORE_DEFAULT_TABLE: 2023 + if (size != 0) { 2024 + dev_err(smu->adev->dev, 2025 + "Input parameter number not correct\n"); 2026 + return -EINVAL; 2027 + } 2028 + 2029 + /* Use the default frequencies for manual mode */ 2030 + min_clk = SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.gfx_table); 2031 + max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.gfx_table); 2032 + 2033 + ret = smu_v15_0_8_set_soft_freq_limited_range(smu, 2034 + SMU_GFXCLK, 2035 + min_clk, max_clk, 2036 + false); 2037 + if (ret) 2038 + return ret; 2039 + 2040 + min_clk = SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.uclk_table); 2041 + max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.uclk_table); 2042 + ret = smu_v15_0_8_set_soft_freq_limited_range(smu, 2043 + SMU_UCLK, 2044 + min_clk, max_clk, 2045 + false); 2046 + if (ret) 2047 + return ret; 2048 + 2049 + smu_cmn_reset_custom_level(smu); 2050 + break; 2051 + case PP_OD_COMMIT_DPM_TABLE: 2052 + if (size != 0) { 2053 + dev_err(smu->adev->dev, 2054 + "Input parameter number not correct\n"); 2055 + return -EINVAL; 2056 + } 2057 + 2058 + if (!pstate_table->gfxclk_pstate.custom.min) 2059 + pstate_table->gfxclk_pstate.custom.min = 2060 + pstate_table->gfxclk_pstate.curr.min; 2061 + 2062 + if (!pstate_table->gfxclk_pstate.custom.max) 2063 + pstate_table->gfxclk_pstate.custom.max = 2064 + pstate_table->gfxclk_pstate.curr.max; 2065 + 2066 + min_clk = pstate_table->gfxclk_pstate.custom.min; 2067 + max_clk = pstate_table->gfxclk_pstate.custom.max; 2068 + 2069 + ret = smu_v15_0_8_set_soft_freq_limited_range(smu, 2070 + SMU_GFXCLK, 2071 + min_clk, max_clk, 2072 + false); 2073 + if (ret) 2074 + return ret; 2075 + 2076 + /* Commit UCLK custom range (only max supported) */ 2077 + if (pstate_table->uclk_pstate.custom.max) { 2078 + min_clk = pstate_table->uclk_pstate.curr.min; 2079 + max_clk = pstate_table->uclk_pstate.custom.max; 2080 + ret = smu_v15_0_8_set_soft_freq_limited_range(smu, 2081 + SMU_UCLK, 2082 + min_clk, max_clk, 2083 + false); 2084 + if (ret) 2085 + return ret; 2086 + } 2087 + 2088 + break; 2089 + default: 2090 + return -ENOSYS; 2091 + } 2092 + 2093 + return 0; 2094 + } 2095 + 2096 + static int smu_v15_0_8_get_thermal_temperature_range(struct smu_context *smu, 2097 + struct smu_temperature_range *range) 2098 + { 2099 + struct smu_table_context *smu_table = &smu->smu_table; 2100 + PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable; 2101 + uint32_t max_ctf, max_thm; 2102 + 2103 + if (amdgpu_sriov_multi_vf_mode(smu->adev)) 2104 + return 0; 2105 + 2106 + if (!range) 2107 + return -EINVAL; 2108 + 2109 + /* CTF (Critical Temperature Fault) limits */ 2110 + max_ctf = max3(pptable->CTFLimitMID, pptable->CTFLimitXCD, 2111 + pptable->CTFLimitAID); 2112 + range->hotspot_emergency_max = max_ctf * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 2113 + 2114 + range->mem_emergency_max = pptable->CTFLimitHBM * 2115 + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 2116 + 2117 + /* Thermal throttling limits */ 2118 + max_thm = max3(pptable->ThermalLimitMID, pptable->ThermalLimitXCD, 2119 + pptable->ThermalLimitAID); 2120 + range->hotspot_crit_max = max_thm * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 2121 + 2122 + range->mem_crit_max = pptable->ThermalLimitHBM * 2123 + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 2124 + 2125 + return 0; 2126 + } 2127 + 2128 + static int smu_v15_0_8_set_power_limit(struct smu_context *smu, 2129 + enum smu_ppt_limit_type limit_type, 2130 + uint32_t limit) 2131 + { 2132 + struct smu_table_context *smu_table = &smu->smu_table; 2133 + PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable; 2134 + int ret; 2135 + 2136 + if (limit_type == SMU_FAST_PPT_LIMIT) { 2137 + if (!pptable->PPT1Max) 2138 + return -EOPNOTSUPP; 2139 + 2140 + if (limit > pptable->PPT1Max || limit < pptable->PPT1Min) { 2141 + dev_err(smu->adev->dev, 2142 + "New PPT1 limit (%d) should be between min %d and max %d\n", 2143 + limit, pptable->PPT1Min, pptable->PPT1Max); 2144 + return -EINVAL; 2145 + } 2146 + 2147 + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetFastPptLimit, 2148 + limit, NULL); 2149 + if (ret) 2150 + dev_err(smu->adev->dev, "Set fast PPT limit failed!\n"); 2151 + 2152 + return ret; 2153 + } 2154 + 2155 + return smu_v15_0_set_power_limit(smu, limit_type, limit); 2156 + } 2157 + 2158 + static int smu_v15_0_8_get_ppt_limit(struct smu_context *smu, 2159 + uint32_t *ppt_limit, 2160 + enum smu_ppt_limit_type type, 2161 + enum smu_ppt_limit_level level) 2162 + { 2163 + struct smu_table_context *smu_table = &smu->smu_table; 2164 + PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable; 2165 + int ret = 0; 2166 + 2167 + if (!ppt_limit) 2168 + return -EINVAL; 2169 + 2170 + if (type == SMU_FAST_PPT_LIMIT) { 2171 + if (!pptable->PPT1Max) 2172 + return -EOPNOTSUPP; 2173 + 2174 + switch (level) { 2175 + case SMU_PPT_LIMIT_MAX: 2176 + *ppt_limit = pptable->PPT1Max; 2177 + break; 2178 + case SMU_PPT_LIMIT_CURRENT: 2179 + ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetFastPptLimit, 2180 + ppt_limit); 2181 + if (ret) 2182 + dev_err(smu->adev->dev, 2183 + "Get fast PPT limit failed!\n"); 2184 + break; 2185 + case SMU_PPT_LIMIT_DEFAULT: 2186 + *ppt_limit = pptable->PPT1Default; 2187 + break; 2188 + case SMU_PPT_LIMIT_MIN: 2189 + *ppt_limit = pptable->PPT1Min; 2190 + break; 2191 + default: 2192 + return -EOPNOTSUPP; 2193 + } 2194 + return ret; 2195 + } 2196 + 2197 + return -EOPNOTSUPP; 2198 + } 2199 + 2200 + static const struct pptable_funcs smu_v15_0_8_ppt_funcs = { 2201 + .init_allowed_features = smu_v15_0_8_init_allowed_features, 2202 + .set_default_dpm_table = smu_v15_0_8_set_default_dpm_table, 2203 + .is_dpm_running = smu_v15_0_8_is_dpm_running, 2204 + .init_smc_tables = smu_v15_0_8_init_smc_tables, 2205 + .fini_smc_tables = smu_v15_0_8_fini_smc_tables, 2206 + .init_power = smu_v15_0_init_power, 2207 + .fini_power = smu_v15_0_fini_power, 2208 + .check_fw_status = smu_v15_0_8_check_fw_status, 2209 + .check_fw_version = smu_cmn_check_fw_version, 2210 + .set_driver_table_location = smu_v15_0_set_driver_table_location, 2211 + .set_tool_table_location = smu_v15_0_set_tool_table_location, 2212 + .notify_memory_pool_location = smu_v15_0_notify_memory_pool_location, 2213 + .system_features_control = smu_v15_0_8_system_features_control, 2214 + .get_enabled_mask = smu_v15_0_8_get_enabled_mask, 2215 + .feature_is_enabled = smu_cmn_feature_is_enabled, 2216 + .register_irq_handler = smu_v15_0_8_register_irq_handler, 2217 + .setup_pptable = smu_v15_0_8_setup_pptable, 2218 + .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, 2219 + .wait_for_event = smu_v15_0_wait_for_event, 2220 + .get_pm_metrics = smu_v15_0_8_get_pm_metrics, 2221 + .mode2_reset = smu_v15_0_8_mode2_reset, 2222 + .get_dpm_ultimate_freq = smu_v15_0_8_get_dpm_ultimate_freq, 2223 + .get_gpu_metrics = smu_v15_0_8_get_gpu_metrics, 2224 + .get_unique_id = smu_v15_0_8_get_unique_id, 2225 + .get_power_limit = smu_v15_0_8_get_power_limit, 2226 + .set_power_limit = smu_v15_0_8_set_power_limit, 2227 + .get_ppt_limit = smu_v15_0_8_get_ppt_limit, 2228 + .emit_clk_levels = smu_v15_0_8_emit_clk_levels, 2229 + .read_sensor = smu_v15_0_8_read_sensor, 2230 + .populate_umd_state_clk = smu_v15_0_8_populate_umd_state_clk, 2231 + .set_performance_level = smu_v15_0_8_set_performance_level, 2232 + .od_edit_dpm_table = smu_v15_0_8_od_edit_dpm_table, 2233 + .get_thermal_temperature_range = smu_v15_0_8_get_thermal_temperature_range, 2234 + }; 2235 + 2236 + static void smu_v15_0_8_init_msg_ctl(struct smu_context *smu, 2237 + const struct cmn2asic_msg_mapping *message_map) 2238 + { 2239 + struct amdgpu_device *adev = smu->adev; 2240 + struct smu_msg_ctl *ctl = &smu->msg_ctl; 2241 + 2242 + ctl->smu = smu; 2243 + mutex_init(&ctl->lock); 2244 + ctl->config.msg_reg = SOC15_REG_OFFSET(MP1, 0, regMP1_SMN_C2PMSG_40); 2245 + ctl->config.resp_reg = SOC15_REG_OFFSET(MP1, 0, regMP1_SMN_C2PMSG_41); 2246 + ctl->config.arg_regs[0] = SOC15_REG_OFFSET(MP1, 0, regMP1_SMN_C2PMSG_42); 2247 + ctl->config.arg_regs[1] = SOC15_REG_OFFSET(MP1, 0, regMP1_SMN_C2PMSG_43); 2248 + ctl->config.arg_regs[2] = SOC15_REG_OFFSET(MP1, 0, regMP1_SMN_C2PMSG_44); 2249 + ctl->config.arg_regs[3] = SOC15_REG_OFFSET(MP1, 0, regMP1_SMN_C2PMSG_45); 2250 + ctl->config.num_arg_regs = 4; 2251 + ctl->ops = &smu_msg_v1_ops; 2252 + ctl->default_timeout = adev->usec_timeout * 20; 2253 + ctl->message_map = message_map; 2254 + } 2255 + 2256 + static const struct smu_temp_funcs smu_v15_0_8_temp_funcs = { 2257 + .temp_metrics_is_supported = smu_v15_0_8_is_temp_metrics_supported, 2258 + .get_temp_metrics = smu_v15_0_8_get_temp_metrics, 2259 + }; 2260 + 2261 + void smu_v15_0_8_set_ppt_funcs(struct smu_context *smu) 2262 + { 2263 + smu->ppt_funcs = &smu_v15_0_8_ppt_funcs; 2264 + smu->clock_map = smu_v15_0_8_clk_map; 2265 + smu->feature_map = smu_v15_0_8_feature_mask_map; 2266 + smu->table_map = smu_v15_0_8_table_map; 2267 + smu_v15_0_8_init_msg_ctl(smu, smu_v15_0_8_message_map); 2268 + smu->smu_temp.temp_funcs = &smu_v15_0_8_temp_funcs; 2269 + smu->smc_driver_if_version = SMU15_DRIVER_IF_VERSION_SMU_V15_0_8; 2270 + }
+313
drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.h
··· 1 + /* 2 + * Copyright 2025 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 __SMU_15_0_8_PPT_H__ 24 + #define __SMU_15_0_8_PPT_H__ 25 + 26 + #define SMU_15_0_8_NUM_XGMI_LINKS 8 27 + #define SMU_15_0_8_MAX_GFX_CLKS 8 28 + #define SMU_15_0_8_MAX_CLKS 4 29 + #define SMU_15_0_8_MAX_XCC 8 30 + #define SMU_15_0_8_MAX_VCN 4 31 + #define SMU_15_0_8_MAX_JPEG 40 32 + #define SMU_15_0_8_MAX_AID 2 33 + #define SMU_15_0_8_MAX_MID 2 34 + #define SMU_15_0_8_MAX_HBM_STACKS 12 35 + extern void smu_v15_0_8_set_ppt_funcs(struct smu_context *smu); 36 + 37 + typedef struct { 38 + uint32_t MaxSocketPowerLimit; 39 + uint32_t MaxGfxclkFrequency; 40 + uint32_t MinGfxclkFrequency; 41 + uint32_t MaxFclkFrequency; 42 + uint32_t MinFclkFrequency; 43 + uint32_t MaxGl2clkFrequency; 44 + uint32_t MinGl2clkFrequency; 45 + uint32_t UclkFrequencyTable[4]; 46 + uint32_t SocclkFrequency; 47 + uint32_t LclkFrequency; 48 + uint32_t VclkFrequency; 49 + uint32_t DclkFrequency; 50 + uint32_t CTFLimitMID; 51 + uint32_t CTFLimitAID; 52 + uint32_t CTFLimitXCD; 53 + uint32_t CTFLimitHBM; 54 + uint32_t ThermalLimitMID; 55 + uint32_t ThermalLimitAID; 56 + uint32_t ThermalLimitXCD; 57 + uint32_t ThermalLimitHBM; 58 + uint64_t PublicSerialNumberMID; 59 + uint64_t PublicSerialNumberAID; 60 + uint64_t PublicSerialNumberXCD; 61 + uint32_t PPT1Max; 62 + uint32_t PPT1Min; 63 + uint32_t PPT1Default; 64 + bool init; 65 + } PPTable_t; 66 + 67 + #if defined(SWSMU_CODE_LAYER_L2) 68 + #include "smu_cmn.h" 69 + 70 + /* SMUv 15.0.8 GPU metrics*/ 71 + #define SMU_15_0_8_METRICS_FIELDS(SMU_SCALAR, SMU_ARRAY) \ 72 + SMU_SCALAR(SMU_MATTR(TEMPERATURE_HOTSPOT), SMU_MUNIT(TEMP_1), \ 73 + SMU_MTYPE(U16), temperature_hotspot); \ 74 + SMU_SCALAR(SMU_MATTR(TEMPERATURE_MEM), SMU_MUNIT(TEMP_1), \ 75 + SMU_MTYPE(U16), temperature_mem); \ 76 + SMU_SCALAR(SMU_MATTR(TEMPERATURE_VRSOC), SMU_MUNIT(TEMP_1), \ 77 + SMU_MTYPE(U16), temperature_vrsoc); \ 78 + SMU_ARRAY(SMU_MATTR(TEMPERATURE_HBM), SMU_MUNIT(TEMP_1), \ 79 + SMU_MTYPE(U16), temperature_hbm, \ 80 + SMU_15_0_8_MAX_HBM_STACKS); \ 81 + SMU_ARRAY(SMU_MATTR(TEMPERATURE_MID), SMU_MUNIT(TEMP_1), \ 82 + SMU_MTYPE(U16), temperature_mid, SMU_15_0_8_MAX_MID); \ 83 + SMU_ARRAY(SMU_MATTR(TEMPERATURE_AID), SMU_MUNIT(TEMP_1), \ 84 + SMU_MTYPE(U16), temperature_aid, SMU_15_0_8_MAX_AID); \ 85 + SMU_ARRAY(SMU_MATTR(TEMPERATURE_XCD), SMU_MUNIT(TEMP_1), \ 86 + SMU_MTYPE(U16), temperature_xcd, SMU_15_0_8_MAX_XCC); \ 87 + SMU_SCALAR(SMU_MATTR(CURR_SOCKET_POWER), SMU_MUNIT(POWER_1), \ 88 + SMU_MTYPE(U16), curr_socket_power); \ 89 + SMU_SCALAR(SMU_MATTR(AVERAGE_GFX_ACTIVITY), SMU_MUNIT(PERCENT), \ 90 + SMU_MTYPE(U16), average_gfx_activity); \ 91 + SMU_SCALAR(SMU_MATTR(AVERAGE_UMC_ACTIVITY), SMU_MUNIT(PERCENT), \ 92 + SMU_MTYPE(U16), average_umc_activity); \ 93 + SMU_SCALAR(SMU_MATTR(MEM_MAX_BANDWIDTH), SMU_MUNIT(BW_1), \ 94 + SMU_MTYPE(U64), mem_max_bandwidth); \ 95 + SMU_SCALAR(SMU_MATTR(ENERGY_ACCUMULATOR), SMU_MUNIT(NONE), \ 96 + SMU_MTYPE(U64), energy_accumulator); \ 97 + SMU_SCALAR(SMU_MATTR(SYSTEM_CLOCK_COUNTER), SMU_MUNIT(TIME_1), \ 98 + SMU_MTYPE(U64), system_clock_counter); \ 99 + SMU_SCALAR(SMU_MATTR(ACCUMULATION_COUNTER), SMU_MUNIT(NONE), \ 100 + SMU_MTYPE(U64), accumulation_counter); \ 101 + SMU_SCALAR(SMU_MATTR(PROCHOT_RESIDENCY_ACC), SMU_MUNIT(NONE), \ 102 + SMU_MTYPE(U64), prochot_residency_acc); \ 103 + SMU_SCALAR(SMU_MATTR(PPT_RESIDENCY_ACC), SMU_MUNIT(NONE), \ 104 + SMU_MTYPE(U64), ppt_residency_acc); \ 105 + SMU_SCALAR(SMU_MATTR(SOCKET_THM_RESIDENCY_ACC), SMU_MUNIT(NONE), \ 106 + SMU_MTYPE(U64), socket_thm_residency_acc); \ 107 + SMU_SCALAR(SMU_MATTR(VR_THM_RESIDENCY_ACC), SMU_MUNIT(NONE), \ 108 + SMU_MTYPE(U64), vr_thm_residency_acc); \ 109 + SMU_SCALAR(SMU_MATTR(HBM_THM_RESIDENCY_ACC), SMU_MUNIT(NONE), \ 110 + SMU_MTYPE(U64), hbm_thm_residency_acc); \ 111 + SMU_SCALAR(SMU_MATTR(GFXCLK_LOCK_STATUS), SMU_MUNIT(NONE), \ 112 + SMU_MTYPE(U32), gfxclk_lock_status); \ 113 + SMU_SCALAR(SMU_MATTR(PCIE_LINK_WIDTH), SMU_MUNIT(NONE), \ 114 + SMU_MTYPE(U16), pcie_link_width); \ 115 + SMU_SCALAR(SMU_MATTR(PCIE_LINK_SPEED), SMU_MUNIT(SPEED_2), \ 116 + SMU_MTYPE(U16), pcie_link_speed); \ 117 + SMU_SCALAR(SMU_MATTR(XGMI_LINK_WIDTH), SMU_MUNIT(NONE), \ 118 + SMU_MTYPE(U16), xgmi_link_width); \ 119 + SMU_SCALAR(SMU_MATTR(XGMI_LINK_SPEED), SMU_MUNIT(SPEED_1), \ 120 + SMU_MTYPE(U16), xgmi_link_speed); \ 121 + SMU_SCALAR(SMU_MATTR(GFX_ACTIVITY_ACC), SMU_MUNIT(NONE), \ 122 + SMU_MTYPE(U64), gfx_activity_acc); \ 123 + SMU_SCALAR(SMU_MATTR(MEM_ACTIVITY_ACC), SMU_MUNIT(NONE), \ 124 + SMU_MTYPE(U64), mem_activity_acc); \ 125 + SMU_ARRAY(SMU_MATTR(PCIE_BANDWIDTH_ACC), SMU_MUNIT(NONE), \ 126 + SMU_MTYPE(U64), pcie_bandwidth_acc, SMU_15_0_8_MAX_MID); \ 127 + SMU_ARRAY(SMU_MATTR(PCIE_BANDWIDTH_INST), SMU_MUNIT(BW_1), \ 128 + SMU_MTYPE(U32), pcie_bandwidth_inst, SMU_15_0_8_MAX_MID); \ 129 + SMU_SCALAR(SMU_MATTR(PCIE_L0_TO_RECOV_COUNT_ACC), SMU_MUNIT(NONE), \ 130 + SMU_MTYPE(U64), pcie_l0_to_recov_count_acc); \ 131 + SMU_SCALAR(SMU_MATTR(PCIE_REPLAY_COUNT_ACC), SMU_MUNIT(NONE), \ 132 + SMU_MTYPE(U64), pcie_replay_count_acc); \ 133 + SMU_SCALAR(SMU_MATTR(PCIE_REPLAY_ROVER_COUNT_ACC), SMU_MUNIT(NONE), \ 134 + SMU_MTYPE(U64), pcie_replay_rover_count_acc); \ 135 + SMU_SCALAR(SMU_MATTR(PCIE_NAK_SENT_COUNT_ACC), SMU_MUNIT(NONE), \ 136 + SMU_MTYPE(U64), pcie_nak_sent_count_acc); \ 137 + SMU_SCALAR(SMU_MATTR(PCIE_NAK_RCVD_COUNT_ACC), SMU_MUNIT(NONE), \ 138 + SMU_MTYPE(U64), pcie_nak_rcvd_count_acc); \ 139 + SMU_ARRAY(SMU_MATTR(XGMI_LINK_STATUS), SMU_MUNIT(NONE), \ 140 + SMU_MTYPE(U16), xgmi_link_status, \ 141 + SMU_15_0_8_NUM_XGMI_LINKS); \ 142 + SMU_SCALAR(SMU_MATTR(XGMI_READ_DATA_ACC), SMU_MUNIT(DATA_1), \ 143 + SMU_MTYPE(U64), xgmi_read_data_acc); \ 144 + SMU_SCALAR(SMU_MATTR(XGMI_WRITE_DATA_ACC), SMU_MUNIT(DATA_1), \ 145 + SMU_MTYPE(U64), xgmi_write_data_acc); \ 146 + SMU_SCALAR(SMU_MATTR(FIRMWARE_TIMESTAMP), SMU_MUNIT(TIME_2), \ 147 + SMU_MTYPE(U64), firmware_timestamp); \ 148 + SMU_ARRAY(SMU_MATTR(CURRENT_GFXCLK), SMU_MUNIT(CLOCK_1), \ 149 + SMU_MTYPE(U16), current_gfxclk, SMU_15_0_8_MAX_GFX_CLKS); \ 150 + SMU_ARRAY(SMU_MATTR(CURRENT_SOCCLK), SMU_MUNIT(CLOCK_1), \ 151 + SMU_MTYPE(U16), current_socclk, SMU_15_0_8_MAX_MID); \ 152 + SMU_ARRAY(SMU_MATTR(CURRENT_VCLK0), SMU_MUNIT(CLOCK_1), \ 153 + SMU_MTYPE(U16), current_vclk0, SMU_15_0_8_MAX_VCN); \ 154 + SMU_ARRAY(SMU_MATTR(CURRENT_DCLK0), SMU_MUNIT(CLOCK_1), \ 155 + SMU_MTYPE(U16), current_dclk0, SMU_15_0_8_MAX_VCN); \ 156 + SMU_ARRAY(SMU_MATTR(CURRENT_UCLK), SMU_MUNIT(CLOCK_1), \ 157 + SMU_MTYPE(U16), current_uclk, SMU_15_0_8_MAX_AID); \ 158 + SMU_SCALAR(SMU_MATTR(PCIE_LC_PERF_OTHER_END_RECOVERY), \ 159 + SMU_MUNIT(NONE), SMU_MTYPE(U64), \ 160 + pcie_lc_perf_other_end_recovery); \ 161 + SMU_ARRAY(SMU_MATTR(GFX_BUSY_INST), SMU_MUNIT(PERCENT), \ 162 + SMU_MTYPE(U32), gfx_busy_inst, SMU_15_0_8_MAX_XCC); \ 163 + SMU_ARRAY(SMU_MATTR(JPEG_BUSY), SMU_MUNIT(PERCENT), SMU_MTYPE(U16), \ 164 + jpeg_busy, SMU_15_0_8_MAX_JPEG); \ 165 + SMU_ARRAY(SMU_MATTR(VCN_BUSY), SMU_MUNIT(PERCENT), SMU_MTYPE(U16), \ 166 + vcn_busy, SMU_15_0_8_MAX_VCN); \ 167 + SMU_ARRAY(SMU_MATTR(GFX_BUSY_ACC), SMU_MUNIT(NONE), SMU_MTYPE(U64), \ 168 + gfx_busy_acc, SMU_15_0_8_MAX_XCC); \ 169 + SMU_ARRAY(SMU_MATTR(GFX_BELOW_HOST_LIMIT_PPT_ACC), SMU_MUNIT(NONE), \ 170 + SMU_MTYPE(U64), gfx_below_host_limit_ppt_acc, \ 171 + SMU_15_0_8_MAX_XCC); \ 172 + SMU_ARRAY(SMU_MATTR(GFX_BELOW_HOST_LIMIT_THM_ACC), SMU_MUNIT(NONE), \ 173 + SMU_MTYPE(U64), gfx_below_host_limit_thm_acc, \ 174 + SMU_15_0_8_MAX_XCC); \ 175 + SMU_ARRAY(SMU_MATTR(GFX_LOW_UTILIZATION_ACC), SMU_MUNIT(NONE), \ 176 + SMU_MTYPE(U64), gfx_low_utilization_acc, \ 177 + SMU_15_0_8_MAX_XCC); \ 178 + SMU_ARRAY(SMU_MATTR(GFX_BELOW_HOST_LIMIT_TOTAL_ACC), SMU_MUNIT(NONE), \ 179 + SMU_MTYPE(U64), gfx_below_host_limit_total_acc, \ 180 + SMU_15_0_8_MAX_XCC); 181 + 182 + DECLARE_SMU_METRICS_CLASS(smu_v15_0_8_gpu_metrics, SMU_15_0_8_METRICS_FIELDS); 183 + 184 + /* Maximum temperature sensor counts for system metrics */ 185 + #define SMU_15_0_8_MAX_SYSTEM_TEMP_ENTRIES 32 186 + #define SMU_15_0_8_MAX_NODE_TEMP_ENTRIES 12 187 + #define SMU_15_0_8_MAX_VR_TEMP_ENTRIES 22 188 + 189 + /* SMUv 15.0.8 GPU board temperature metrics */ 190 + #define SMU_15_0_8_GPUBOARD_TEMP_METRICS_FIELDS(SMU_SCALAR, SMU_ARRAY) \ 191 + SMU_SCALAR(SMU_MATTR(ACCUMULATION_COUNTER), SMU_MUNIT(NONE), \ 192 + SMU_MTYPE(U64), accumulation_counter); \ 193 + SMU_SCALAR(SMU_MATTR(LABEL_VERSION), SMU_MUNIT(NONE), \ 194 + SMU_MTYPE(U16), label_version); \ 195 + SMU_SCALAR(SMU_MATTR(NODE_ID), SMU_MUNIT(NONE), \ 196 + SMU_MTYPE(U16), node_id); \ 197 + SMU_SCALAR(SMU_MATTR(NODE_TEMP_RETIMER), SMU_MUNIT(TEMP_1), \ 198 + SMU_MTYPE(S16), node_temp_retimer); \ 199 + SMU_SCALAR(SMU_MATTR(NODE_TEMP_IBC), SMU_MUNIT(TEMP_1), \ 200 + SMU_MTYPE(S16), node_temp_ibc); \ 201 + SMU_SCALAR(SMU_MATTR(NODE_TEMP_IBC_2), SMU_MUNIT(TEMP_1), \ 202 + SMU_MTYPE(S16), node_temp_ibc_2); \ 203 + SMU_SCALAR(SMU_MATTR(NODE_TEMP_VDD18_VR), SMU_MUNIT(TEMP_1), \ 204 + SMU_MTYPE(S16), node_temp_vdd18_vr); \ 205 + SMU_SCALAR(SMU_MATTR(NODE_TEMP_04_HBM_B_VR), SMU_MUNIT(TEMP_1), \ 206 + SMU_MTYPE(S16), node_temp_04_hbm_b_vr); \ 207 + SMU_SCALAR(SMU_MATTR(NODE_TEMP_04_HBM_D_VR), SMU_MUNIT(TEMP_1), \ 208 + SMU_MTYPE(S16), node_temp_04_hbm_d_vr); \ 209 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDCR_SOCIO_A), SMU_MUNIT(TEMP_1), \ 210 + SMU_MTYPE(S16), vr_temp_vddcr_socio_a); \ 211 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDCR_SOCIO_C), SMU_MUNIT(TEMP_1), \ 212 + SMU_MTYPE(S16), vr_temp_vddcr_socio_c); \ 213 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDCR_X0), SMU_MUNIT(TEMP_1), \ 214 + SMU_MTYPE(S16), vr_temp_vddcr_x0); \ 215 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDCR_X1), SMU_MUNIT(TEMP_1), \ 216 + SMU_MTYPE(S16), vr_temp_vddcr_x1); \ 217 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDIO_HBM_B), SMU_MUNIT(TEMP_1), \ 218 + SMU_MTYPE(S16), vr_temp_vddio_hbm_b); \ 219 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDIO_HBM_D), SMU_MUNIT(TEMP_1), \ 220 + SMU_MTYPE(S16), vr_temp_vddio_hbm_d); \ 221 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDIO_04_HBM_B), SMU_MUNIT(TEMP_1), \ 222 + SMU_MTYPE(S16), vr_temp_vddio_04_hbm_b); \ 223 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDIO_04_HBM_D), SMU_MUNIT(TEMP_1), \ 224 + SMU_MTYPE(S16), vr_temp_vddio_04_hbm_d); \ 225 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDCR_HBM_B), SMU_MUNIT(TEMP_1), \ 226 + SMU_MTYPE(S16), vr_temp_vddcr_hbm_b); \ 227 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDCR_HBM_D), SMU_MUNIT(TEMP_1), \ 228 + SMU_MTYPE(S16), vr_temp_vddcr_hbm_d); \ 229 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDCR_075_HBM_B), SMU_MUNIT(TEMP_1), \ 230 + SMU_MTYPE(S16), vr_temp_vddcr_075_hbm_b); \ 231 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDCR_075_HBM_D), SMU_MUNIT(TEMP_1), \ 232 + SMU_MTYPE(S16), vr_temp_vddcr_075_hbm_d); \ 233 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDIO_11_GTA_A), SMU_MUNIT(TEMP_1), \ 234 + SMU_MTYPE(S16), vr_temp_vddio_11_gta_a); \ 235 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDIO_11_GTA_C), SMU_MUNIT(TEMP_1), \ 236 + SMU_MTYPE(S16), vr_temp_vddio_11_gta_c); \ 237 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDAN_075_GTA_A), SMU_MUNIT(TEMP_1), \ 238 + SMU_MTYPE(S16), vr_temp_vddan_075_gta_a); \ 239 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDAN_075_GTA_C), SMU_MUNIT(TEMP_1), \ 240 + SMU_MTYPE(S16), vr_temp_vddan_075_gta_c); \ 241 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDCR_075_UCIE), SMU_MUNIT(TEMP_1), \ 242 + SMU_MTYPE(S16), vr_temp_vddcr_075_ucie); \ 243 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDIO_065_UCIEAA), SMU_MUNIT(TEMP_1), \ 244 + SMU_MTYPE(S16), vr_temp_vddio_065_ucieaa); \ 245 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDIO_065_UCIEAM_A), SMU_MUNIT(TEMP_1), \ 246 + SMU_MTYPE(S16), vr_temp_vddio_065_ucieam_a); \ 247 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDIO_065_UCIEAM_C), SMU_MUNIT(TEMP_1), \ 248 + SMU_MTYPE(S16), vr_temp_vddio_065_ucieam_c); \ 249 + SMU_SCALAR(SMU_MATTR(VR_TEMP_VDDAN_075), SMU_MUNIT(TEMP_1), \ 250 + SMU_MTYPE(S16), vr_temp_vddan_075); 251 + 252 + DECLARE_SMU_METRICS_CLASS(smu_v15_0_8_gpuboard_temp_metrics, 253 + SMU_15_0_8_GPUBOARD_TEMP_METRICS_FIELDS); 254 + 255 + /* SMUv 15.0.8 Baseboard temperature metrics - ID-based approach */ 256 + #define SMU_15_0_8_BASEBOARD_TEMP_METRICS_FIELDS(SMU_SCALAR, SMU_ARRAY) \ 257 + SMU_SCALAR(SMU_MATTR(ACCUMULATION_COUNTER), SMU_MUNIT(NONE), \ 258 + SMU_MTYPE(U64), accumulation_counter); \ 259 + SMU_SCALAR(SMU_MATTR(LABEL_VERSION), SMU_MUNIT(NONE), \ 260 + SMU_MTYPE(U16), label_version); \ 261 + SMU_SCALAR(SMU_MATTR(NODE_ID), SMU_MUNIT(NONE), \ 262 + SMU_MTYPE(U16), node_id); \ 263 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_UBB_FPGA), SMU_MUNIT(TEMP_1), \ 264 + SMU_MTYPE(S16), system_temp_ubb_fpga); \ 265 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_UBB_FRONT), SMU_MUNIT(TEMP_1), \ 266 + SMU_MTYPE(S16), system_temp_ubb_front); \ 267 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_UBB_BACK), SMU_MUNIT(TEMP_1), \ 268 + SMU_MTYPE(S16), system_temp_ubb_back); \ 269 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_UBB_OAM7), SMU_MUNIT(TEMP_1), \ 270 + SMU_MTYPE(S16), system_temp_ubb_oam7); \ 271 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_UBB_IBC), SMU_MUNIT(TEMP_1), \ 272 + SMU_MTYPE(S16), system_temp_ubb_ibc); \ 273 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_UBB_UFPGA), SMU_MUNIT(TEMP_1), \ 274 + SMU_MTYPE(S16), system_temp_ubb_ufpga); \ 275 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_UBB_OAM1), SMU_MUNIT(TEMP_1), \ 276 + SMU_MTYPE(S16), system_temp_ubb_oam1); \ 277 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_OAM_0_1_HSC), SMU_MUNIT(TEMP_1), \ 278 + SMU_MTYPE(S16), system_temp_oam_0_1_hsc); \ 279 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_OAM_2_3_HSC), SMU_MUNIT(TEMP_1), \ 280 + SMU_MTYPE(S16), system_temp_oam_2_3_hsc); \ 281 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_OAM_4_5_HSC), SMU_MUNIT(TEMP_1), \ 282 + SMU_MTYPE(S16), system_temp_oam_4_5_hsc); \ 283 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_OAM_6_7_HSC), SMU_MUNIT(TEMP_1), \ 284 + SMU_MTYPE(S16), system_temp_oam_6_7_hsc); \ 285 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_UBB_FPGA_0V72_VR), SMU_MUNIT(TEMP_1), \ 286 + SMU_MTYPE(S16), system_temp_ubb_fpga_0v72_vr); \ 287 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_UBB_FPGA_3V3_VR), SMU_MUNIT(TEMP_1), \ 288 + SMU_MTYPE(S16), system_temp_ubb_fpga_3v3_vr); \ 289 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_RETIMER_0_1_2_3_1V2_VR), SMU_MUNIT(TEMP_1), \ 290 + SMU_MTYPE(S16), system_temp_retimer_0_1_2_3_1v2_vr); \ 291 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_RETIMER_4_5_6_7_1V2_VR), SMU_MUNIT(TEMP_1), \ 292 + SMU_MTYPE(S16), system_temp_retimer_4_5_6_7_1v2_vr); \ 293 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_RETIMER_0_1_0V9_VR), SMU_MUNIT(TEMP_1), \ 294 + SMU_MTYPE(S16), system_temp_retimer_0_1_0v9_vr); \ 295 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_RETIMER_4_5_0V9_VR), SMU_MUNIT(TEMP_1), \ 296 + SMU_MTYPE(S16), system_temp_retimer_4_5_0v9_vr); \ 297 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_RETIMER_2_3_0V9_VR), SMU_MUNIT(TEMP_1), \ 298 + SMU_MTYPE(S16), system_temp_retimer_2_3_0v9_vr); \ 299 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_RETIMER_6_7_0V9_VR), SMU_MUNIT(TEMP_1), \ 300 + SMU_MTYPE(S16), system_temp_retimer_6_7_0v9_vr); \ 301 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_OAM_0_1_2_3_3V3_VR), SMU_MUNIT(TEMP_1), \ 302 + SMU_MTYPE(S16), system_temp_oam_0_1_2_3_3v3_vr); \ 303 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_OAM_4_5_6_7_3V3_VR), SMU_MUNIT(TEMP_1), \ 304 + SMU_MTYPE(S16), system_temp_oam_4_5_6_7_3v3_vr); \ 305 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_IBC_HSC), SMU_MUNIT(TEMP_1), \ 306 + SMU_MTYPE(S16), system_temp_ibc_hsc); \ 307 + SMU_SCALAR(SMU_MATTR(SYSTEM_TEMP_IBC), SMU_MUNIT(TEMP_1), \ 308 + SMU_MTYPE(S16), system_temp_ibc); 309 + 310 + DECLARE_SMU_METRICS_CLASS(smu_v15_0_8_baseboard_temp_metrics, 311 + SMU_15_0_8_BASEBOARD_TEMP_METRICS_FIELDS); 312 + #endif 313 + #endif
+10 -4
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
··· 1057 1057 smu->smc_driver_if_version, if_version, 1058 1058 smu_program, smu_version, smu_major, smu_minor, smu_debug); 1059 1059 1060 - if (smu->smc_driver_if_version != SMU_IGNORE_IF_VERSION && 1061 - if_version != smu->smc_driver_if_version) 1062 - dev_info(adev->dev, "SMU driver if version not matched\n"); 1063 - 1064 1060 return 0; 1065 1061 } 1066 1062 ··· 1299 1303 1300 1304 *backend_workload_mask |= 1 << workload_type; 1301 1305 } 1306 + } 1307 + 1308 + void smu_cmn_reset_custom_level(struct smu_context *smu) 1309 + { 1310 + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; 1311 + 1312 + pstate_table->gfxclk_pstate.custom.min = 0; 1313 + pstate_table->gfxclk_pstate.custom.max = 0; 1314 + pstate_table->uclk_pstate.custom.min = 0; 1315 + pstate_table->uclk_pstate.custom.max = 0; 1302 1316 } 1303 1317 1304 1318 static inline bool smu_cmn_freqs_match(uint32_t freq1, uint32_t freq2)
+1
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
··· 204 204 struct smu_pcie_table *pcie_table, 205 205 uint32_t cur_gen, uint32_t cur_lane, 206 206 char *buf, int *offset); 207 + void smu_cmn_reset_custom_level(struct smu_context *smu); 207 208 208 209 int smu_cmn_dpm_pcie_gen_idx(int gen); 209 210 int smu_cmn_dpm_pcie_width_idx(int width);
+22
drivers/gpu/drm/amd/ras/rascore/ras_core.c
··· 69 69 int seconds_per_minute = 60; 70 70 int days, remaining_seconds; 71 71 72 + if (!tm) 73 + return -EINVAL; 74 + 72 75 days = div64_u64_rem(timestamp, seconds_per_day, &remainder); 73 76 /* remainder will always be less than seconds_per_day. */ 74 77 remaining_seconds = remainder; ··· 119 116 { 120 117 uint32_t status = 0; 121 118 119 + if (!ras_core) 120 + return false; 121 + 122 122 if (ras_core->sys_fn && 123 123 ras_core->sys_fn->check_gpu_status) 124 124 ras_core->sys_fn->check_gpu_status(ras_core, &status); ··· 132 126 bool ras_core_gpu_is_vf(struct ras_core_context *ras_core) 133 127 { 134 128 uint32_t status = 0; 129 + 130 + if (!ras_core) 131 + return false; 135 132 136 133 if (ras_core->sys_fn && 137 134 ras_core->sys_fn->check_gpu_status) ··· 279 270 { 280 271 struct ras_core_context *ras_core; 281 272 struct ras_core_config *config; 273 + 274 + if (!init_config) 275 + return NULL; 282 276 283 277 ras_core = kzalloc_obj(*ras_core); 284 278 if (!ras_core) ··· 491 479 492 480 uint32_t ras_core_get_curr_nps_mode(struct ras_core_context *ras_core) 493 481 { 482 + if (!ras_core) 483 + return 0; 484 + 494 485 if (ras_core->ras_nbio.ip_func && 495 486 ras_core->ras_nbio.ip_func->get_memory_partition_mode) 496 487 return ras_core->ras_nbio.ip_func->get_memory_partition_mode(ras_core); ··· 577 562 int ras_core_get_gpu_mem(struct ras_core_context *ras_core, 578 563 enum gpu_mem_type mem_type, struct gpu_mem_block *gpu_mem) 579 564 { 565 + if (!ras_core || !gpu_mem) 566 + return -EINVAL; 580 567 if (ras_core->sys_fn && ras_core->sys_fn->get_gpu_mem) 581 568 return ras_core->sys_fn->get_gpu_mem(ras_core, mem_type, gpu_mem); 582 569 ··· 589 572 int ras_core_put_gpu_mem(struct ras_core_context *ras_core, 590 573 enum gpu_mem_type mem_type, struct gpu_mem_block *gpu_mem) 591 574 { 575 + if (!ras_core || !gpu_mem) 576 + return -EINVAL; 592 577 if (ras_core->sys_fn && ras_core->sys_fn->put_gpu_mem) 593 578 return ras_core->sys_fn->put_gpu_mem(ras_core, mem_type, gpu_mem); 594 579 ··· 644 625 int ras_core_get_device_system_info(struct ras_core_context *ras_core, 645 626 struct device_system_info *dev_info) 646 627 { 628 + if (!dev_info) 629 + return -EINVAL; 630 + 647 631 if (ras_core && ras_core->sys_fn && 648 632 ras_core->sys_fn->get_device_system_info) 649 633 return ras_core->sys_fn->get_device_system_info(ras_core, dev_info);
+1 -1
drivers/gpu/drm/amd/ras/rascore/ras_umc.c
··· 222 222 mutex_lock(&ras_umc->pending_ecc_lock); 223 223 list_for_each_entry_safe(ecc_node, 224 224 tmp, &ras_umc->pending_ecc_list, node){ 225 - if (ecc_node && !ras_umc_log_bad_bank(ras_core, &ecc_node->ecc)) { 225 + if (!ras_umc_log_bad_bank(ras_core, &ecc_node->ecc)) { 226 226 list_del(&ecc_node->node); 227 227 kfree(ecc_node); 228 228 }