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-fixes-6.5-2023-06-30-1' of https://gitlab.freedesktop.org/agd5f/linux into drm-next

amd-drm-fixes-6.5-2023-06-30-1:

amdgpu:
- Misc cleanups
- GFX 9.4.3 fixes
- DEBUGFS build fix
- Fix LPDDR5 reporting
- ASPM fixes
- DCN 3.1.4 fixes
- DP MST fixes
- DCN 3.2.x fixes
- Display PSR TCON fixes
- SMU 13.x fixes
- RAS fixes
- Vega12/20 SMU fixes
- PSP flashing cleanup
- GFX9 MCBP fixes
- SR-IOV fixes
- GPUVM clear mappings fix for always valid BOs
- Add FAMS quirk for problematic monitor
- Fix possible UAF
- Better handle monentary temperature fluctuations
- SDMA 4.4.2 fixes
- Fencing fix

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

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230630175757.8128-1-alexander.deucher@amd.com

+1200 -310
+7 -3
drivers/gpu/drm/amd/amdgpu/amdgpu.h
··· 286 286 #define AMDGPU_SMARTSHIFT_MAX_BIAS (100) 287 287 #define AMDGPU_SMARTSHIFT_MIN_BIAS (-100) 288 288 289 + /* Extra time delay(in ms) to eliminate the influence of temperature momentary fluctuation */ 290 + #define AMDGPU_SWCTF_EXTRA_DELAY 50 291 + 289 292 struct amdgpu_xcp_mgr; 290 293 struct amdgpu_device; 291 294 struct amdgpu_irq_src; ··· 1280 1277 1281 1278 #define amdgpu_inc_vram_lost(adev) atomic_inc(&((adev)->vram_lost_counter)); 1282 1279 1283 - #define for_each_inst(i, inst_mask) \ 1284 - for (i = ffs(inst_mask) - 1; inst_mask; \ 1285 - inst_mask &= ~(1U << i), i = ffs(inst_mask) - 1) 1280 + #define BIT_MASK_UPPER(i) ((i) >= BITS_PER_LONG ? 0 : ~0UL << (i)) 1281 + #define for_each_inst(i, inst_mask) \ 1282 + for (i = ffs(inst_mask); i-- != 0; \ 1283 + i = ffs(inst_mask & BIT_MASK_UPPER(i + 1))) 1286 1284 1287 1285 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) 1288 1286
+9
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
··· 1791 1791 .attrs = amdgpu_vbios_version_attrs 1792 1792 }; 1793 1793 1794 + int amdgpu_atombios_sysfs_init(struct amdgpu_device *adev) 1795 + { 1796 + if (adev->mode_info.atom_context) 1797 + return devm_device_add_group(adev->dev, 1798 + &amdgpu_vbios_version_attr_group); 1799 + 1800 + return 0; 1801 + } 1802 + 1794 1803 /** 1795 1804 * amdgpu_atombios_fini - free the driver info and callbacks for atombios 1796 1805 *
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
··· 217 217 218 218 void amdgpu_atombios_fini(struct amdgpu_device *adev); 219 219 int amdgpu_atombios_init(struct amdgpu_device *adev); 220 + int amdgpu_atombios_sysfs_init(struct amdgpu_device *adev); 220 221 221 222 #endif
+12 -6
drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
··· 327 327 mem_channel_number = igp_info->v11.umachannelnumber; 328 328 if (!mem_channel_number) 329 329 mem_channel_number = 1; 330 - /* channel width is 64 */ 331 - if (vram_width) 332 - *vram_width = mem_channel_number * 64; 333 330 mem_type = igp_info->v11.memorytype; 331 + if (mem_type == LpDdr5MemType) 332 + mem_channel_width = 32; 333 + else 334 + mem_channel_width = 64; 335 + if (vram_width) 336 + *vram_width = mem_channel_number * mem_channel_width; 334 337 if (vram_type) 335 338 *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); 336 339 break; ··· 348 345 mem_channel_number = igp_info->v21.umachannelnumber; 349 346 if (!mem_channel_number) 350 347 mem_channel_number = 1; 351 - /* channel width is 64 */ 352 - if (vram_width) 353 - *vram_width = mem_channel_number * 64; 354 348 mem_type = igp_info->v21.memorytype; 349 + if (mem_type == LpDdr5MemType) 350 + mem_channel_width = 32; 351 + else 352 + mem_channel_width = 64; 353 + if (vram_width) 354 + *vram_width = mem_channel_number * mem_channel_width; 355 355 if (vram_type) 356 356 *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); 357 357 break;
+9 -8
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
··· 136 136 bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj)); 137 137 p->uf_entry.priority = 0; 138 138 p->uf_entry.tv.bo = &bo->tbo; 139 - /* One for TTM and two for the CS job */ 140 - p->uf_entry.tv.num_shared = 3; 141 - 142 139 drm_gem_object_put(gobj); 143 140 144 141 size = amdgpu_bo_size(bo); ··· 909 912 910 913 mutex_lock(&p->bo_list->bo_list_mutex); 911 914 912 - /* One for TTM and one for the CS job */ 915 + /* One for TTM and one for each CS job */ 913 916 amdgpu_bo_list_for_each_entry(e, p->bo_list) 914 - e->tv.num_shared = 2; 917 + e->tv.num_shared = 1 + p->gang_size; 918 + p->uf_entry.tv.num_shared = 1 + p->gang_size; 915 919 916 920 amdgpu_bo_list_get_list(p->bo_list, &p->validated); 917 921 918 922 INIT_LIST_HEAD(&duplicates); 919 923 amdgpu_vm_get_pd_bo(&fpriv->vm, &p->validated, &p->vm_pd); 924 + 925 + /* Two for VM updates, one for TTM and one for each CS job */ 926 + p->vm_pd.tv.num_shared = 3 + p->gang_size; 920 927 921 928 if (p->uf_entry.tv.bo && !ttm_to_amdgpu_bo(p->uf_entry.tv.bo)->parent) 922 929 list_add(&p->uf_entry.tv.head, &p->validated); ··· 1654 1653 continue; 1655 1654 1656 1655 r = dma_fence_wait_timeout(fence, true, timeout); 1656 + if (r > 0 && fence->error) 1657 + r = fence->error; 1658 + 1657 1659 dma_fence_put(fence); 1658 1660 if (r < 0) 1659 1661 return r; 1660 1662 1661 1663 if (r == 0) 1662 1664 break; 1663 - 1664 - if (fence->error) 1665 - return fence->error; 1666 1665 } 1667 1666 1668 1667 memset(wait, 0, sizeof(*wait));
+25 -4
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 2552 2552 adev->ip_blocks[i].status.hw = true; 2553 2553 2554 2554 /* right after GMC hw init, we create CSA */ 2555 - if (amdgpu_mcbp) { 2555 + if (adev->gfx.mcbp) { 2556 2556 r = amdgpu_allocate_static_csa(adev, &adev->virt.csa_obj, 2557 2557 AMDGPU_GEM_DOMAIN_VRAM | 2558 2558 AMDGPU_GEM_DOMAIN_GTT, ··· 3673 3673 NULL 3674 3674 }; 3675 3675 3676 + static void amdgpu_device_set_mcbp(struct amdgpu_device *adev) 3677 + { 3678 + if (amdgpu_mcbp == 1) 3679 + adev->gfx.mcbp = true; 3680 + 3681 + if ((adev->ip_versions[GC_HWIP][0] >= IP_VERSION(9, 0, 0)) && 3682 + (adev->ip_versions[GC_HWIP][0] < IP_VERSION(10, 0, 0)) && 3683 + adev->gfx.num_gfx_rings) 3684 + adev->gfx.mcbp = true; 3685 + 3686 + if (amdgpu_sriov_vf(adev)) 3687 + adev->gfx.mcbp = true; 3688 + 3689 + if (adev->gfx.mcbp) 3690 + DRM_INFO("MCBP is enabled\n"); 3691 + } 3692 + 3676 3693 /** 3677 3694 * amdgpu_device_init - initialize the driver 3678 3695 * ··· 3841 3824 DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)adev->rmmio_base); 3842 3825 DRM_INFO("register mmio size: %u\n", (unsigned)adev->rmmio_size); 3843 3826 3844 - if (amdgpu_mcbp) 3845 - DRM_INFO("MCBP is enabled\n"); 3846 - 3847 3827 /* 3848 3828 * Reset domain needs to be present early, before XGMI hive discovered 3849 3829 * (if any) and intitialized to use reset sem and in_gpu reset flag ··· 3865 3851 r = amdgpu_device_ip_early_init(adev); 3866 3852 if (r) 3867 3853 return r; 3854 + 3855 + amdgpu_device_set_mcbp(adev); 3868 3856 3869 3857 /* Get rid of things like offb */ 3870 3858 r = drm_aperture_remove_conflicting_pci_framebuffers(adev->pdev, &amdgpu_kms_driver); ··· 4033 4017 max_MBps = 8; /* Allow 8 MB/s. */ 4034 4018 /* Get a log2 for easy divisions. */ 4035 4019 adev->mm_stats.log2_max_MBps = ilog2(max(1u, max_MBps)); 4020 + 4021 + r = amdgpu_atombios_sysfs_init(adev); 4022 + if (r) 4023 + drm_err(&adev->ddev, 4024 + "registering atombios sysfs failed (%d).\n", r); 4036 4025 4037 4026 r = amdgpu_pm_sysfs_init(adev); 4038 4027 if (r)
+3 -5
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
··· 180 180 uint amdgpu_dc_debug_mask; 181 181 uint amdgpu_dc_visual_confirm; 182 182 int amdgpu_async_gfx_ring = 1; 183 - int amdgpu_mcbp; 183 + int amdgpu_mcbp = -1; 184 184 int amdgpu_discovery = -1; 185 185 int amdgpu_mes; 186 186 int amdgpu_mes_kiq; ··· 634 634 635 635 /** 636 636 * DOC: mcbp (int) 637 - * It is used to enable mid command buffer preemption. (0 = disabled (default), 1 = enabled) 637 + * It is used to enable mid command buffer preemption. (0 = disabled, 1 = enabled, -1 auto (default)) 638 638 */ 639 639 MODULE_PARM_DESC(mcbp, 640 - "Enable Mid-command buffer preemption (0 = disabled (default), 1 = enabled)"); 640 + "Enable Mid-command buffer preemption (0 = disabled, 1 = enabled), -1 = auto (default)"); 641 641 module_param_named(mcbp, amdgpu_mcbp, int, 0444); 642 642 643 643 /** ··· 2899 2899 2900 2900 extern const struct attribute_group amdgpu_vram_mgr_attr_group; 2901 2901 extern const struct attribute_group amdgpu_gtt_mgr_attr_group; 2902 - extern const struct attribute_group amdgpu_vbios_version_attr_group; 2903 2902 2904 2903 static const struct attribute_group *amdgpu_sysfs_groups[] = { 2905 2904 &amdgpu_vram_mgr_attr_group, 2906 2905 &amdgpu_gtt_mgr_attr_group, 2907 - &amdgpu_vbios_version_attr_group, 2908 2906 NULL, 2909 2907 }; 2910 2908
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
··· 434 434 uint16_t xcc_mask; 435 435 uint32_t num_xcc_per_xcp; 436 436 struct mutex partition_mutex; 437 + bool mcbp; /* mid command buffer preemption */ 437 438 }; 438 439 439 440 struct amdgpu_gfx_ras_reg_entry {
+2 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.c
··· 255 255 256 256 if (amdgpu_ras_is_supported(adev, ras_block->block)) { 257 257 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 258 - if (adev->jpeg.harvest_config & (1 << i)) 258 + if (adev->jpeg.harvest_config & (1 << i) || 259 + !adev->jpeg.inst[i].ras_poison_irq.funcs) 259 260 continue; 260 261 261 262 r = amdgpu_irq_get(adev, &adev->jpeg.inst[i].ras_poison_irq, 0);
+2 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
··· 805 805 dev_info->ids_flags = 0; 806 806 if (adev->flags & AMD_IS_APU) 807 807 dev_info->ids_flags |= AMDGPU_IDS_FLAGS_FUSION; 808 - if (amdgpu_mcbp) 808 + if (adev->gfx.mcbp) 809 809 dev_info->ids_flags |= AMDGPU_IDS_FLAGS_PREEMPTION; 810 810 if (amdgpu_is_tmz(adev)) 811 811 dev_info->ids_flags |= AMDGPU_IDS_FLAGS_TMZ; ··· 1247 1247 goto error_vm; 1248 1248 } 1249 1249 1250 - if (amdgpu_mcbp) { 1250 + if (adev->gfx.mcbp) { 1251 1251 uint64_t csa_addr = amdgpu_csa_vaddr(adev) & AMDGPU_GMC_HOLE_MASK; 1252 1252 1253 1253 r = amdgpu_map_static_csa(adev, &fpriv->vm, adev->virt.csa_obj,
+3 -5
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
··· 839 839 case IP_VERSION(11, 0, 9): 840 840 case IP_VERSION(11, 0, 7): 841 841 case IP_VERSION(13, 0, 2): 842 + case IP_VERSION(13, 0, 6): 842 843 case IP_VERSION(13, 0, 10): 843 844 return true; 844 845 default: ··· 2040 2039 psp_securedisplay_parse_resp_status(psp, securedisplay_cmd->status); 2041 2040 dev_err(psp->adev->dev, "SECUREDISPLAY: query securedisplay TA failed. ret 0x%x\n", 2042 2041 securedisplay_cmd->securedisplay_out_message.query_ta.query_cmd_ret); 2042 + /* don't try again */ 2043 + psp->securedisplay_context.context.bin_desc.size_bytes = 0; 2043 2044 } 2044 2045 2045 2046 return 0; ··· 3706 3703 int amdgpu_psp_sysfs_init(struct amdgpu_device *adev) 3707 3704 { 3708 3705 int ret = 0; 3709 - struct psp_context *psp = &adev->psp; 3710 3706 3711 3707 if (amdgpu_sriov_vf(adev)) 3712 3708 return -EINVAL; ··· 3714 3712 case IP_VERSION(13, 0, 0): 3715 3713 case IP_VERSION(13, 0, 7): 3716 3714 case IP_VERSION(13, 0, 10): 3717 - if (!psp->adev) { 3718 - psp->adev = adev; 3719 - psp_v13_0_set_psp_funcs(psp); 3720 - } 3721 3715 ret = sysfs_create_bin_file(&adev->dev->kobj, &psp_vbflash_bin_attr); 3722 3716 if (ret) 3723 3717 dev_err(adev->dev, "Failed to create device file psp_vbflash");
-2
drivers/gpu/drm/amd/amdgpu/amdgpu_rap.c
··· 116 116 117 117 void amdgpu_rap_debugfs_init(struct amdgpu_device *adev) 118 118 { 119 - #if defined(CONFIG_DEBUG_FS) 120 119 struct drm_minor *minor = adev_to_drm(adev)->primary; 121 120 122 121 if (!adev->psp.rap_context.context.initialized) ··· 123 124 124 125 debugfs_create_file("rap_test", S_IWUSR, minor->debugfs_root, 125 126 adev, &amdgpu_rap_debugfs_ops); 126 - #endif 127 127 }
+11
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
··· 2065 2065 ras->gpu_reset_flags &= ~AMDGPU_RAS_GPU_RESET_MODE2_RESET; 2066 2066 reset_context.method = AMD_RESET_METHOD_MODE2; 2067 2067 } 2068 + 2069 + /* Fatal error occurs in poison mode, mode1 reset is used to 2070 + * recover gpu. 2071 + */ 2072 + if (ras->gpu_reset_flags & AMDGPU_RAS_GPU_RESET_MODE1_RESET) { 2073 + ras->gpu_reset_flags &= ~AMDGPU_RAS_GPU_RESET_MODE1_RESET; 2074 + set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags); 2075 + } 2068 2076 } 2069 2077 2070 2078 amdgpu_device_gpu_recover(ras->adev, NULL, &reset_context); ··· 2963 2955 return; 2964 2956 2965 2957 if (atomic_cmpxchg(&amdgpu_ras_in_intr, 0, 1) == 0) { 2958 + struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); 2959 + 2966 2960 dev_info(adev->dev, "uncorrectable hardware error" 2967 2961 "(ERREVENT_ATHUB_INTERRUPT) detected!\n"); 2968 2962 2963 + ras->gpu_reset_flags |= AMDGPU_RAS_GPU_RESET_MODE1_RESET; 2969 2964 amdgpu_ras_reset_gpu(adev); 2970 2965 } 2971 2966 }
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
··· 340 340 #define AMDGPU_RAS_ERR_ADDRESS_VALID (1 << 2) 341 341 342 342 #define AMDGPU_RAS_GPU_RESET_MODE2_RESET (0x1 << 0) 343 + #define AMDGPU_RAS_GPU_RESET_MODE1_RESET (0x1 << 1) 343 344 344 345 struct amdgpu_ras_err_status_reg_entry { 345 346 uint32_t hwip;
+3
drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c
··· 423 423 struct amdgpu_ring_mux *mux = &adev->gfx.muxer; 424 424 unsigned offset; 425 425 426 + if (ring->hw_prio > AMDGPU_RING_PRIO_DEFAULT) 427 + return; 428 + 426 429 offset = ring->wptr & ring->buf_mask; 427 430 428 431 amdgpu_ring_mux_ib_mark_offset(mux, ring, offset, type);
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
··· 72 72 int r; 73 73 74 74 /* don't enable OS preemption on SDMA under SRIOV */ 75 - if (amdgpu_sriov_vf(adev) || vmid == 0 || !amdgpu_mcbp) 75 + if (amdgpu_sriov_vf(adev) || vmid == 0 || !adev->gfx.mcbp) 76 76 return 0; 77 77 78 78 if (ring->is_mes_queue) {
+2 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
··· 1198 1198 1199 1199 if (amdgpu_ras_is_supported(adev, ras_block->block)) { 1200 1200 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 1201 - if (adev->vcn.harvest_config & (1 << i)) 1201 + if (adev->vcn.harvest_config & (1 << i) || 1202 + !adev->vcn.inst[i].ras_poison_irq.funcs) 1202 1203 continue; 1203 1204 1204 1205 r = amdgpu_irq_get(adev, &adev->vcn.inst[i].ras_poison_irq, 0);
-3
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
··· 66 66 adev->cg_flags = 0; 67 67 adev->pg_flags = 0; 68 68 69 - /* enable mcbp for sriov */ 70 - amdgpu_mcbp = 1; 71 - 72 69 /* Reduce kcq number to 2 to reduce latency */ 73 70 if (amdgpu_num_kcq == -1) 74 71 amdgpu_num_kcq = 2;
+18 -6
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 1771 1771 1772 1772 /* Insert partial mapping before the range */ 1773 1773 if (!list_empty(&before->list)) { 1774 + struct amdgpu_bo *bo = before->bo_va->base.bo; 1775 + 1774 1776 amdgpu_vm_it_insert(before, &vm->va); 1775 1777 if (before->flags & AMDGPU_PTE_PRT) 1776 1778 amdgpu_vm_prt_get(adev); 1779 + 1780 + if (bo && bo->tbo.base.resv == vm->root.bo->tbo.base.resv && 1781 + !before->bo_va->base.moved) 1782 + amdgpu_vm_bo_moved(&before->bo_va->base); 1777 1783 } else { 1778 1784 kfree(before); 1779 1785 } 1780 1786 1781 1787 /* Insert partial mapping after the range */ 1782 1788 if (!list_empty(&after->list)) { 1789 + struct amdgpu_bo *bo = after->bo_va->base.bo; 1790 + 1783 1791 amdgpu_vm_it_insert(after, &vm->va); 1784 1792 if (after->flags & AMDGPU_PTE_PRT) 1785 1793 amdgpu_vm_prt_get(adev); 1794 + 1795 + if (bo && bo->tbo.base.resv == vm->root.bo->tbo.base.resv && 1796 + !after->bo_va->base.moved) 1797 + amdgpu_vm_bo_moved(&after->bo_va->base); 1786 1798 } else { 1787 1799 kfree(after); 1788 1800 } ··· 2245 2233 if (r) 2246 2234 return r; 2247 2235 2248 - /* Sanity checks */ 2249 - if (!amdgpu_vm_pt_is_root_clean(adev, vm)) { 2250 - r = -EINVAL; 2251 - goto unreserve_bo; 2252 - } 2253 - 2254 2236 /* Check if PD needs to be reinitialized and do it before 2255 2237 * changing any other state, in case it fails. 2256 2238 */ 2257 2239 if (pte_support_ats != vm->pte_support_ats) { 2240 + /* Sanity checks */ 2241 + if (!amdgpu_vm_pt_is_root_clean(adev, vm)) { 2242 + r = -EINVAL; 2243 + goto unreserve_bo; 2244 + } 2245 + 2258 2246 vm->pte_support_ats = pte_support_ats; 2259 2247 r = amdgpu_vm_pt_clear(adev, vm, to_amdgpu_bo_vm(vm->root.bo), 2260 2248 false);
+9 -4
drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c
··· 132 132 for (i = 0; i < MAX_XCP; ++i) 133 133 xcp_mgr->xcp[i].valid = false; 134 134 135 + /* This is needed for figuring out memory id of xcp */ 136 + xcp_mgr->num_xcp_per_mem_partition = num_xcps / xcp_mgr->adev->gmc.num_mem_partitions; 137 + 135 138 for (i = 0; i < num_xcps; ++i) { 136 139 for (j = AMDGPU_XCP_GFXHUB; j < AMDGPU_XCP_MAX_BLOCKS; ++j) { 137 140 ret = xcp_mgr->funcs->get_ip_details(xcp_mgr, i, j, ··· 160 157 xcp_mgr->num_xcps = num_xcps; 161 158 amdgpu_xcp_update_partition_sched_list(adev); 162 159 163 - xcp_mgr->num_xcp_per_mem_partition = num_xcps / xcp_mgr->adev->gmc.num_mem_partitions; 164 160 return 0; 165 161 } 166 162 ··· 234 232 235 233 ddev = adev_to_drm(adev); 236 234 237 - for (i = 0; i < MAX_XCP; i++) { 235 + /* xcp #0 shares drm device setting with adev */ 236 + adev->xcp_mgr->xcp->ddev = ddev; 237 + 238 + for (i = 1; i < MAX_XCP; i++) { 238 239 ret = amdgpu_xcp_drm_dev_alloc(&p_ddev); 239 240 if (ret) 240 241 return ret; ··· 327 322 if (!adev->xcp_mgr) 328 323 return 0; 329 324 330 - for (i = 0; i < MAX_XCP; i++) { 325 + for (i = 1; i < MAX_XCP; i++) { 331 326 ret = drm_dev_register(adev->xcp_mgr->xcp[i].ddev, ent->driver_data); 332 327 if (ret) 333 328 return ret; ··· 344 339 if (!adev->xcp_mgr) 345 340 return; 346 341 347 - for (i = 0; i < MAX_XCP; i++) { 342 + for (i = 1; i < MAX_XCP; i++) { 348 343 p_ddev = adev->xcp_mgr->xcp[i].ddev; 349 344 drm_dev_unplug(p_ddev); 350 345 p_ddev->render->dev = adev->xcp_mgr->xcp[i].rdev;
+2 -2
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
··· 8307 8307 8308 8308 control |= ib->length_dw | (vmid << 24); 8309 8309 8310 - if (amdgpu_mcbp && (ib->flags & AMDGPU_IB_FLAG_PREEMPT)) { 8310 + if (ring->adev->gfx.mcbp && (ib->flags & AMDGPU_IB_FLAG_PREEMPT)) { 8311 8311 control |= INDIRECT_BUFFER_PRE_ENB(1); 8312 8312 8313 8313 if (flags & AMDGPU_IB_PREEMPTED) ··· 8482 8482 { 8483 8483 uint32_t dw2 = 0; 8484 8484 8485 - if (amdgpu_mcbp) 8485 + if (ring->adev->gfx.mcbp) 8486 8486 gfx_v10_0_ring_emit_ce_meta(ring, 8487 8487 (!amdgpu_sriov_vf(ring->adev) && flags & AMDGPU_IB_PREEMPTED) ? true : false); 8488 8488
+1 -1
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
··· 5311 5311 5312 5312 control |= ib->length_dw | (vmid << 24); 5313 5313 5314 - if (amdgpu_mcbp && (ib->flags & AMDGPU_IB_FLAG_PREEMPT)) { 5314 + if (ring->adev->gfx.mcbp && (ib->flags & AMDGPU_IB_FLAG_PREEMPT)) { 5315 5315 control |= INDIRECT_BUFFER_PRE_ENB(1); 5316 5316 5317 5317 if (flags & AMDGPU_IB_PREEMPTED)
+35 -6
drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
··· 623 623 static int gfx_v9_4_3_switch_compute_partition(struct amdgpu_device *adev, 624 624 int num_xccs_per_xcp) 625 625 { 626 - int ret; 626 + int ret, i, num_xcc; 627 + u32 tmp = 0; 627 628 628 - ret = psp_spatial_partition(&adev->psp, NUM_XCC(adev->gfx.xcc_mask) / 629 - num_xccs_per_xcp); 630 - if (ret) 631 - return ret; 629 + if (adev->psp.funcs) { 630 + ret = psp_spatial_partition(&adev->psp, 631 + NUM_XCC(adev->gfx.xcc_mask) / 632 + num_xccs_per_xcp); 633 + if (ret) 634 + return ret; 635 + } else { 636 + num_xcc = NUM_XCC(adev->gfx.xcc_mask); 637 + 638 + for (i = 0; i < num_xcc; i++) { 639 + tmp = REG_SET_FIELD(tmp, CP_HYP_XCP_CTL, NUM_XCC_IN_XCP, 640 + num_xccs_per_xcp); 641 + tmp = REG_SET_FIELD(tmp, CP_HYP_XCP_CTL, VIRTUAL_XCC_ID, 642 + i % num_xccs_per_xcp); 643 + WREG32_SOC15(GC, GET_INST(GC, i), regCP_HYP_XCP_CTL, 644 + tmp); 645 + } 646 + ret = 0; 647 + } 632 648 633 649 adev->gfx.num_xcc_per_xcp = num_xccs_per_xcp; 634 650 ··· 1778 1762 ((struct v9_mqd_allocation *)mqd)->dynamic_cu_mask = 0xFFFFFFFF; 1779 1763 ((struct v9_mqd_allocation *)mqd)->dynamic_rb_mask = 0xFFFFFFFF; 1780 1764 mutex_lock(&adev->srbm_mutex); 1765 + if (amdgpu_sriov_vf(adev) && adev->in_suspend) 1766 + amdgpu_ring_clear_ring(ring); 1781 1767 soc15_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0, GET_INST(GC, xcc_id)); 1782 1768 gfx_v9_4_3_xcc_mqd_init(ring, xcc_id); 1783 1769 gfx_v9_4_3_xcc_kiq_init_register(ring, xcc_id); ··· 1978 1960 if (amdgpu_gfx_disable_kcq(adev, xcc_id)) 1979 1961 DRM_ERROR("XCD %d KCQ disable failed\n", xcc_id); 1980 1962 1963 + if (amdgpu_sriov_vf(adev)) { 1964 + /* must disable polling for SRIOV when hw finished, otherwise 1965 + * CPC engine may still keep fetching WB address which is already 1966 + * invalid after sw finished and trigger DMAR reading error in 1967 + * hypervisor side. 1968 + */ 1969 + WREG32_FIELD15_PREREG(GC, GET_INST(GC, xcc_id), CP_PQ_WPTR_POLL_CNTL, EN, 0); 1970 + return; 1971 + } 1972 + 1981 1973 /* Use deinitialize sequence from CAIL when unbinding device 1982 1974 * from driver, otherwise KIQ is hanging when binding back 1983 1975 */ ··· 2012 1984 int r; 2013 1985 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 2014 1986 2015 - gfx_v9_4_3_init_golden_registers(adev); 1987 + if (!amdgpu_sriov_vf(adev)) 1988 + gfx_v9_4_3_init_golden_registers(adev); 2016 1989 2017 1990 gfx_v9_4_3_constants_init(adev); 2018 1991
+8 -5
drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
··· 345 345 } 346 346 347 347 #define NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT 0x00000000 // off by default, no gains over L1 348 - #define NAVI10_PCIE__LC_L1_INACTIVITY_DEFAULT 0x00000009 // 1=1us, 9=1ms 349 - #define NAVI10_PCIE__LC_L1_INACTIVITY_TBT_DEFAULT 0x0000000E // 4ms 348 + #define NAVI10_PCIE__LC_L1_INACTIVITY_DEFAULT 0x0000000A // 1=1us, 9=1ms, 10=4ms 349 + #define NAVI10_PCIE__LC_L1_INACTIVITY_TBT_DEFAULT 0x0000000E // 400ms 350 350 351 351 static void nbio_v2_3_enable_aspm(struct amdgpu_device *adev, 352 352 bool enable) ··· 479 479 WREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP5, data); 480 480 481 481 def = data = RREG32_PCIE(smnPCIE_LC_CNTL); 482 - data &= ~PCIE_LC_CNTL__LC_L0S_INACTIVITY_MASK; 483 - data |= 0x9 << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT; 484 - data |= 0x1 << PCIE_LC_CNTL__LC_PMI_TO_L1_DIS__SHIFT; 482 + data |= NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT << PCIE_LC_CNTL__LC_L0S_INACTIVITY__SHIFT; 483 + if (pci_is_thunderbolt_attached(adev->pdev)) 484 + data |= NAVI10_PCIE__LC_L1_INACTIVITY_TBT_DEFAULT << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT; 485 + else 486 + data |= NAVI10_PCIE__LC_L1_INACTIVITY_DEFAULT << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT; 487 + data &= ~PCIE_LC_CNTL__LC_PMI_TO_L1_DIS_MASK; 485 488 if (def != data) 486 489 WREG32_PCIE(smnPCIE_LC_CNTL, data); 487 490
+9 -9
drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
··· 578 578 return; 579 579 } 580 580 581 + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) 582 + return; 583 + 581 584 for_each_inst(i, inst_mask) { 582 585 f32_cntl = RREG32_SDMA(i, regSDMA_F32_CNTL); 583 586 f32_cntl = REG_SET_FIELD(f32_cntl, SDMA_F32_CNTL, HALT, enable ? 0 : 1); ··· 902 899 WREG32_SDMA(i, regSDMA_CNTL, temp); 903 900 904 901 if (!amdgpu_sriov_vf(adev)) { 905 - ring = &adev->sdma.instance[i].ring; 906 - adev->nbio.funcs->sdma_doorbell_range(adev, i, 907 - ring->use_doorbell, ring->doorbell_index, 908 - adev->doorbell_index.sdma_doorbell_range); 909 - 910 - /* unhalt engine */ 911 - temp = RREG32_SDMA(i, regSDMA_F32_CNTL); 912 - temp = REG_SET_FIELD(temp, SDMA_F32_CNTL, HALT, 0); 913 - WREG32_SDMA(i, regSDMA_F32_CNTL, temp); 902 + if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { 903 + /* unhalt engine */ 904 + temp = RREG32_SDMA(i, regSDMA_F32_CNTL); 905 + temp = REG_SET_FIELD(temp, SDMA_F32_CNTL, HALT, 0); 906 + WREG32_SDMA(i, regSDMA_F32_CNTL, temp); 907 + } 914 908 } 915 909 } 916 910
+2
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
··· 1424 1424 */ 1425 1425 static void vcn_v4_0_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx) 1426 1426 { 1427 + struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__UNPAUSE}; 1427 1428 uint32_t tmp; 1428 1429 1430 + vcn_v4_0_pause_dpg_mode(adev, inst_idx, &state); 1429 1431 /* Wait for power status to be 1 */ 1430 1432 SOC15_WAIT_ON_RREG(VCN, inst_idx, regUVD_POWER_STATUS, 1, 1431 1433 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
+43 -1
drivers/gpu/drm/amd/amdkfd/kfd_device.c
··· 138 138 case IP_VERSION(9, 4, 0): /* VEGA20 */ 139 139 case IP_VERSION(9, 4, 1): /* ARCTURUS */ 140 140 case IP_VERSION(9, 4, 2): /* ALDEBARAN */ 141 - case IP_VERSION(9, 4, 3): /* GC 9.4.3 */ 142 141 kfd->device_info.event_interrupt_class = &event_interrupt_class_v9; 142 + break; 143 + case IP_VERSION(9, 4, 3): /* GC 9.4.3 */ 144 + kfd->device_info.event_interrupt_class = 145 + &event_interrupt_class_v9_4_3; 143 146 break; 144 147 case IP_VERSION(10, 3, 1): /* VANGOGH */ 145 148 case IP_VERSION(10, 3, 3): /* YELLOW_CARP */ ··· 521 518 && kfd->mec2_fw_version >= 0x30) || 522 519 (KFD_GC_VERSION(node) == IP_VERSION(9, 4, 2) 523 520 && kfd->mec2_fw_version >= 0x28) || 521 + (KFD_GC_VERSION(node) == IP_VERSION(9, 4, 3)) || 524 522 (KFD_GC_VERSION(node) >= IP_VERSION(10, 3, 0) 525 523 && KFD_GC_VERSION(node) < IP_VERSION(11, 0, 0) 526 524 && kfd->mec2_fw_version >= 0x6b)))) ··· 600 596 kfree(knode); 601 597 kfd->nodes[i] = NULL; 602 598 } 599 + } 600 + 601 + static void kfd_setup_interrupt_bitmap(struct kfd_node *node, 602 + unsigned int kfd_node_idx) 603 + { 604 + struct amdgpu_device *adev = node->adev; 605 + uint32_t xcc_mask = node->xcc_mask; 606 + uint32_t xcc, mapped_xcc; 607 + /* 608 + * Interrupt bitmap is setup for processing interrupts from 609 + * different XCDs and AIDs. 610 + * Interrupt bitmap is defined as follows: 611 + * 1. Bits 0-15 - correspond to the NodeId field. 612 + * Each bit corresponds to NodeId number. For example, if 613 + * a KFD node has interrupt bitmap set to 0x7, then this 614 + * KFD node will process interrupts with NodeId = 0, 1 and 2 615 + * in the IH cookie. 616 + * 2. Bits 16-31 - unused. 617 + * 618 + * Please note that the kfd_node_idx argument passed to this 619 + * function is not related to NodeId field received in the 620 + * IH cookie. 621 + * 622 + * In CPX mode, a KFD node will process an interrupt if: 623 + * - the Node Id matches the corresponding bit set in 624 + * Bits 0-15. 625 + * - AND VMID reported in the interrupt lies within the 626 + * VMID range of the node. 627 + */ 628 + for_each_inst(xcc, xcc_mask) { 629 + mapped_xcc = GET_INST(GC, xcc); 630 + node->interrupt_bitmap |= (mapped_xcc % 2 ? 5 : 3) << (4 * (mapped_xcc / 2)); 631 + } 632 + dev_info(kfd_device, "Node: %d, interrupt_bitmap: %x\n", kfd_node_idx, 633 + node->interrupt_bitmap); 603 634 } 604 635 605 636 bool kgd2kfd_device_init(struct kfd_dev *kfd, ··· 835 796 836 797 amdgpu_amdkfd_get_local_mem_info(kfd->adev, 837 798 &node->local_mem_info, node->xcp); 799 + 800 + if (KFD_GC_VERSION(kfd) == IP_VERSION(9, 4, 3)) 801 + kfd_setup_interrupt_bitmap(node, i); 838 802 839 803 /* Initialize the KFD node */ 840 804 if (kfd_init_node(node)) {
+29
drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c
··· 446 446 } 447 447 } 448 448 449 + static bool event_interrupt_isr_v9_4_3(struct kfd_node *node, 450 + const uint32_t *ih_ring_entry, 451 + uint32_t *patched_ihre, 452 + bool *patched_flag) 453 + { 454 + uint16_t node_id, vmid; 455 + 456 + /* 457 + * For GFX 9.4.3, process the interrupt if: 458 + * - NodeID field in IH entry matches the corresponding bit 459 + * set in interrupt_bitmap Bits 0-15. 460 + * OR 461 + * - If partition mode is CPX and interrupt came from 462 + * Node_id 0,4,8,12, then check if the Bit (16 + client id) 463 + * is set in interrupt bitmap Bits 16-31. 464 + */ 465 + node_id = SOC15_NODEID_FROM_IH_ENTRY(ih_ring_entry); 466 + vmid = SOC15_VMID_FROM_IH_ENTRY(ih_ring_entry); 467 + if (kfd_irq_is_from_node(node, node_id, vmid)) 468 + return event_interrupt_isr_v9(node, ih_ring_entry, 469 + patched_ihre, patched_flag); 470 + return false; 471 + } 472 + 449 473 const struct kfd_event_interrupt_class event_interrupt_class_v9 = { 450 474 .interrupt_isr = event_interrupt_isr_v9, 475 + .interrupt_wq = event_interrupt_wq_v9, 476 + }; 477 + 478 + const struct kfd_event_interrupt_class event_interrupt_class_v9_4_3 = { 479 + .interrupt_isr = event_interrupt_isr_v9_4_3, 451 480 .interrupt_wq = event_interrupt_wq_v9, 452 481 };
+1
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
··· 1444 1444 /* Events */ 1445 1445 extern const struct kfd_event_interrupt_class event_interrupt_class_cik; 1446 1446 extern const struct kfd_event_interrupt_class event_interrupt_class_v9; 1447 + extern const struct kfd_event_interrupt_class event_interrupt_class_v9_4_3; 1447 1448 extern const struct kfd_event_interrupt_class event_interrupt_class_v10; 1448 1449 extern const struct kfd_event_interrupt_class event_interrupt_class_v11; 1449 1450
+9
drivers/gpu/drm/amd/amdkfd/kfd_process.c
··· 2142 2142 int kfd_process_drain_interrupts(struct kfd_process_device *pdd) 2143 2143 { 2144 2144 uint32_t irq_drain_fence[8]; 2145 + uint8_t node_id = 0; 2145 2146 int r = 0; 2146 2147 2147 2148 if (!KFD_IS_SOC15(pdd->dev)) ··· 2154 2153 irq_drain_fence[0] = (KFD_IRQ_FENCE_SOURCEID << 8) | 2155 2154 KFD_IRQ_FENCE_CLIENTID; 2156 2155 irq_drain_fence[3] = pdd->process->pasid; 2156 + 2157 + /* 2158 + * For GFX 9.4.3, send the NodeId also in IH cookie DW[3] 2159 + */ 2160 + if (KFD_GC_VERSION(pdd->dev->kfd) == IP_VERSION(9, 4, 3)) { 2161 + node_id = ffs(pdd->dev->interrupt_bitmap) - 1; 2162 + irq_drain_fence[3] |= node_id << 16; 2163 + } 2157 2164 2158 2165 /* ensure stale irqs scheduled KFD interrupts and send drain fence. */ 2159 2166 if (amdgpu_amdkfd_send_close_event_drain_irq(pdd->dev->adev,
+23 -12
drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
··· 123 123 if (!gws && pdd->qpd.num_gws == 0) 124 124 return -EINVAL; 125 125 126 - if (gws) 127 - ret = amdgpu_amdkfd_add_gws_to_process(pdd->process->kgd_process_info, 128 - gws, &mem); 129 - else 130 - ret = amdgpu_amdkfd_remove_gws_from_process(pdd->process->kgd_process_info, 131 - pqn->q->gws); 132 - if (unlikely(ret)) 133 - return ret; 126 + if (KFD_GC_VERSION(dev) != IP_VERSION(9, 4, 3)) { 127 + if (gws) 128 + ret = amdgpu_amdkfd_add_gws_to_process(pdd->process->kgd_process_info, 129 + gws, &mem); 130 + else 131 + ret = amdgpu_amdkfd_remove_gws_from_process(pdd->process->kgd_process_info, 132 + pqn->q->gws); 133 + if (unlikely(ret)) 134 + return ret; 135 + pqn->q->gws = mem; 136 + } else { 137 + /* 138 + * Intentionally set GWS to a non-NULL value 139 + * for GFX 9.4.3. 140 + */ 141 + pqn->q->gws = gws ? ERR_PTR(-ENOMEM) : NULL; 142 + } 134 143 135 - pqn->q->gws = mem; 136 144 pdd->qpd.num_gws = gws ? dev->adev->gds.gws_size : 0; 137 145 138 146 return pqn->q->device->dqm->ops.update_queue(pqn->q->device->dqm, ··· 172 164 struct process_queue_node *pqn, *next; 173 165 174 166 list_for_each_entry_safe(pqn, next, &pqm->queues, process_queue_list) { 175 - if (pqn->q && pqn->q->gws) 167 + if (pqn->q && pqn->q->gws && 168 + KFD_GC_VERSION(pqn->q->device) != IP_VERSION(9, 4, 3)) 176 169 amdgpu_amdkfd_remove_gws_from_process(pqm->process->kgd_process_info, 177 170 pqn->q->gws); 178 171 kfd_procfs_del_queue(pqn->q); ··· 455 446 } 456 447 457 448 if (pqn->q->gws) { 458 - amdgpu_amdkfd_remove_gws_from_process(pqm->process->kgd_process_info, 459 - pqn->q->gws); 449 + if (KFD_GC_VERSION(pqn->q->device) != IP_VERSION(9, 4, 3)) 450 + amdgpu_amdkfd_remove_gws_from_process( 451 + pqm->process->kgd_process_info, 452 + pqn->q->gws); 460 453 pdd->qpd.num_gws = 0; 461 454 } 462 455
+4
drivers/gpu/drm/amd/amdkfd/kfd_topology.c
··· 2107 2107 if (KFD_IS_SVM_API_SUPPORTED(dev->gpu->adev)) 2108 2108 dev->node_props.capability |= HSA_CAP_SVMAPI_SUPPORTED; 2109 2109 2110 + if (dev->gpu->adev->gmc.is_app_apu || 2111 + dev->gpu->adev->gmc.xgmi.connected_to_cpu) 2112 + dev->node_props.capability |= HSA_CAP_FLAGS_COHERENTHOSTACCESS; 2113 + 2110 2114 kfd_debug_print_topology(); 2111 2115 2112 2116 kfd_notify_gpu_change(gpu_id, 1);
+1
drivers/gpu/drm/amd/amdkfd/soc15_int.h
··· 40 40 #define SOC15_VMID_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[0]) >> 24 & 0xf) 41 41 #define SOC15_VMID_TYPE_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[0]) >> 31 & 0x1) 42 42 #define SOC15_PASID_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[3]) & 0xffff) 43 + #define SOC15_NODEID_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[3]) >> 16 & 0xff) 43 44 #define SOC15_CONTEXT_ID0_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[4])) 44 45 #define SOC15_CONTEXT_ID1_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[5])) 45 46 #define SOC15_CONTEXT_ID2_FROM_IH_ENTRY(entry) (le32_to_cpu(entry[6]))
+5 -16
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 5063 5063 s32 y, s32 width, s32 height, 5064 5064 int *i, bool ffu) 5065 5065 { 5066 - if (*i > DC_MAX_DIRTY_RECTS) 5067 - return; 5068 - 5069 - if (*i == DC_MAX_DIRTY_RECTS) 5070 - goto out; 5066 + WARN_ON(*i >= DC_MAX_DIRTY_RECTS); 5071 5067 5072 5068 dirty_rect->x = x; 5073 5069 dirty_rect->y = y; ··· 5079 5083 "[PLANE:%d] PSR SU dirty rect at (%d, %d) size (%d, %d)", 5080 5084 plane->base.id, x, y, width, height); 5081 5085 5082 - out: 5083 5086 (*i)++; 5084 5087 } 5085 5088 ··· 5165 5170 5166 5171 *dirty_regions_changed = bb_changed; 5167 5172 5173 + if ((num_clips + (bb_changed ? 2 : 0)) > DC_MAX_DIRTY_RECTS) 5174 + goto ffu; 5175 + 5168 5176 if (bb_changed) { 5169 5177 fill_dc_dirty_rect(new_plane_state->plane, &dirty_rects[i], 5170 5178 new_plane_state->crtc_x, ··· 5196 5198 new_plane_state->crtc_w, 5197 5199 new_plane_state->crtc_h, &i, false); 5198 5200 } 5199 - 5200 - if (i > DC_MAX_DIRTY_RECTS) 5201 - goto ffu; 5202 5201 5203 5202 flip_addrs->dirty_rect_count = i; 5204 5203 return; ··· 7253 7258 drm_add_modes_noedid(connector, 1920, 1080); 7254 7259 } else { 7255 7260 amdgpu_dm_connector_ddc_get_modes(connector, edid); 7256 - /* most eDP supports only timings from its edid, 7257 - * usually only detailed timings are available 7258 - * from eDP edid. timings which are not from edid 7259 - * may damage eDP 7260 - */ 7261 - if (connector->connector_type != DRM_MODE_CONNECTOR_eDP) 7262 - amdgpu_dm_connector_add_common_modes(encoder, connector); 7261 + amdgpu_dm_connector_add_common_modes(encoder, connector); 7263 7262 amdgpu_dm_connector_add_freesync_modes(connector, edid); 7264 7263 } 7265 7264 amdgpu_dm_fbc_init(connector);
+155 -1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
··· 336 336 return size; 337 337 } 338 338 339 + static bool dp_mst_is_end_device(struct amdgpu_dm_connector *aconnector) 340 + { 341 + bool is_end_device = false; 342 + struct drm_dp_mst_topology_mgr *mgr = NULL; 343 + struct drm_dp_mst_port *port = NULL; 344 + 345 + if (aconnector->mst_root && aconnector->mst_root->mst_mgr.mst_state) { 346 + mgr = &aconnector->mst_root->mst_mgr; 347 + port = aconnector->mst_output_port; 348 + 349 + drm_modeset_lock(&mgr->base.lock, NULL); 350 + if (port->pdt == DP_PEER_DEVICE_SST_SINK || 351 + port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV) 352 + is_end_device = true; 353 + drm_modeset_unlock(&mgr->base.lock); 354 + } 355 + 356 + return is_end_device; 357 + } 358 + 359 + /* Change MST link setting 360 + * 361 + * valid lane count value: 1, 2, 4 362 + * valid link rate value: 363 + * 06h = 1.62Gbps per lane 364 + * 0Ah = 2.7Gbps per lane 365 + * 0Ch = 3.24Gbps per lane 366 + * 14h = 5.4Gbps per lane 367 + * 1Eh = 8.1Gbps per lane 368 + * 3E8h = 10.0Gbps per lane 369 + * 546h = 13.5Gbps per lane 370 + * 7D0h = 20.0Gbps per lane 371 + * 372 + * debugfs is located at /sys/kernel/debug/dri/0/DP-x/mst_link_settings 373 + * 374 + * for example, to force to 2 lane, 10.0GHz, 375 + * echo 2 0x3e8 > /sys/kernel/debug/dri/0/DP-x/mst_link_settings 376 + * 377 + * Valid input will trigger hotplug event to get new link setting applied 378 + * Invalid input will trigger training setting reset 379 + * 380 + * The usage can be referred to link_settings entry 381 + * 382 + */ 383 + static ssize_t dp_mst_link_setting(struct file *f, const char __user *buf, 384 + size_t size, loff_t *pos) 385 + { 386 + struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; 387 + struct dc_link *link = aconnector->dc_link; 388 + struct amdgpu_device *adev = drm_to_adev(aconnector->base.dev); 389 + struct dc *dc = (struct dc *)link->dc; 390 + struct dc_link_settings prefer_link_settings; 391 + char *wr_buf = NULL; 392 + const uint32_t wr_buf_size = 40; 393 + /* 0: lane_count; 1: link_rate */ 394 + int max_param_num = 2; 395 + uint8_t param_nums = 0; 396 + long param[2]; 397 + bool valid_input = true; 398 + 399 + if (!dp_mst_is_end_device(aconnector)) 400 + return -EINVAL; 401 + 402 + if (size == 0) 403 + return -EINVAL; 404 + 405 + wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL); 406 + if (!wr_buf) 407 + return -ENOSPC; 408 + 409 + if (parse_write_buffer_into_params(wr_buf, wr_buf_size, 410 + (long *)param, buf, 411 + max_param_num, 412 + &param_nums)) { 413 + kfree(wr_buf); 414 + return -EINVAL; 415 + } 416 + 417 + if (param_nums <= 0) { 418 + kfree(wr_buf); 419 + DRM_DEBUG_DRIVER("user data not be read\n"); 420 + return -EINVAL; 421 + } 422 + 423 + switch (param[0]) { 424 + case LANE_COUNT_ONE: 425 + case LANE_COUNT_TWO: 426 + case LANE_COUNT_FOUR: 427 + break; 428 + default: 429 + valid_input = false; 430 + break; 431 + } 432 + 433 + switch (param[1]) { 434 + case LINK_RATE_LOW: 435 + case LINK_RATE_HIGH: 436 + case LINK_RATE_RBR2: 437 + case LINK_RATE_HIGH2: 438 + case LINK_RATE_HIGH3: 439 + case LINK_RATE_UHBR10: 440 + case LINK_RATE_UHBR13_5: 441 + case LINK_RATE_UHBR20: 442 + break; 443 + default: 444 + valid_input = false; 445 + break; 446 + } 447 + 448 + if (!valid_input) { 449 + kfree(wr_buf); 450 + DRM_DEBUG_DRIVER("Invalid Input value No HW will be programmed\n"); 451 + mutex_lock(&adev->dm.dc_lock); 452 + dc_link_set_preferred_training_settings(dc, NULL, NULL, link, false); 453 + mutex_unlock(&adev->dm.dc_lock); 454 + return -EINVAL; 455 + } 456 + 457 + /* save user force lane_count, link_rate to preferred settings 458 + * spread spectrum will not be changed 459 + */ 460 + prefer_link_settings.link_spread = link->cur_link_settings.link_spread; 461 + prefer_link_settings.use_link_rate_set = false; 462 + prefer_link_settings.lane_count = param[0]; 463 + prefer_link_settings.link_rate = param[1]; 464 + 465 + /* skip immediate retrain, and train to new link setting after hotplug event triggered */ 466 + mutex_lock(&adev->dm.dc_lock); 467 + dc_link_set_preferred_training_settings(dc, &prefer_link_settings, NULL, link, true); 468 + mutex_unlock(&adev->dm.dc_lock); 469 + 470 + mutex_lock(&aconnector->base.dev->mode_config.mutex); 471 + aconnector->base.force = DRM_FORCE_OFF; 472 + mutex_unlock(&aconnector->base.dev->mode_config.mutex); 473 + drm_kms_helper_hotplug_event(aconnector->base.dev); 474 + 475 + msleep(100); 476 + 477 + mutex_lock(&aconnector->base.dev->mode_config.mutex); 478 + aconnector->base.force = DRM_FORCE_UNSPECIFIED; 479 + mutex_unlock(&aconnector->base.dev->mode_config.mutex); 480 + drm_kms_helper_hotplug_event(aconnector->base.dev); 481 + 482 + kfree(wr_buf); 483 + return size; 484 + } 485 + 339 486 /* function: get current DP PHY settings: voltage swing, pre-emphasis, 340 487 * post-cursor2 (defined by VESA DP specification) 341 488 * ··· 2815 2668 .llseek = default_llseek 2816 2669 }; 2817 2670 2671 + static const struct file_operations dp_mst_link_settings_debugfs_fops = { 2672 + .owner = THIS_MODULE, 2673 + .write = dp_mst_link_setting, 2674 + .llseek = default_llseek 2675 + }; 2676 + 2818 2677 static const struct { 2819 2678 char *name; 2820 2679 const struct file_operations *fops; ··· 2844 2691 {"dsc_disable_passthrough", &dp_dsc_disable_passthrough_debugfs_fops}, 2845 2692 {"is_mst_connector", &dp_is_mst_connector_fops}, 2846 2693 {"mst_progress_status", &dp_mst_progress_status_fops}, 2847 - {"is_dpia_link", &is_dpia_link_fops} 2694 + {"is_dpia_link", &is_dpia_link_fops}, 2695 + {"mst_link_settings", &dp_mst_link_settings_debugfs_fops} 2848 2696 }; 2849 2697 2850 2698 static const struct {
+26
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
··· 44 44 #include "dm_helpers.h" 45 45 #include "ddc_service_types.h" 46 46 47 + static u32 edid_extract_panel_id(struct edid *edid) 48 + { 49 + return (u32)edid->mfg_id[0] << 24 | 50 + (u32)edid->mfg_id[1] << 16 | 51 + (u32)EDID_PRODUCT_ID(edid); 52 + } 53 + 54 + static void apply_edid_quirks(struct edid *edid, struct dc_edid_caps *edid_caps) 55 + { 56 + uint32_t panel_id = edid_extract_panel_id(edid); 57 + 58 + switch (panel_id) { 59 + /* Workaround for some monitors which does not work well with FAMS */ 60 + case drm_edid_encode_panel_id('S', 'A', 'M', 0x0E5E): 61 + case drm_edid_encode_panel_id('S', 'A', 'M', 0x7053): 62 + case drm_edid_encode_panel_id('S', 'A', 'M', 0x71AC): 63 + DRM_DEBUG_DRIVER("Disabling FAMS on monitor with panel id %X\n", panel_id); 64 + edid_caps->panel_patch.disable_fams = true; 65 + break; 66 + default: 67 + return; 68 + } 69 + } 70 + 47 71 /* dm_helpers_parse_edid_caps 48 72 * 49 73 * Parse edid caps ··· 138 114 edid_caps->speaker_flags = sadb[0]; 139 115 else 140 116 edid_caps->speaker_flags = DEFAULT_SPEAKER_LOCATION; 117 + 118 + apply_edid_quirks(edid_buf, edid_caps); 141 119 142 120 kfree(sads); 143 121 kfree(sadb);
+2 -1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
··· 24 24 */ 25 25 26 26 #include "amdgpu_dm_psr.h" 27 + #include "dc_dmub_srv.h" 27 28 #include "dc.h" 28 29 #include "dm_helpers.h" 29 30 #include "amdgpu_dm.h" ··· 51 50 !link->dpcd_caps.psr_info.psr2_su_y_granularity_cap) 52 51 return false; 53 52 54 - return true; 53 + return dc_dmub_check_min_version(dc->ctx->dmub_srv->dmub); 55 54 } 56 55 57 56 /*
+37 -6
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
··· 541 541 clk_mgr_base->clks.p_state_change_support = p_state_change_support; 542 542 543 543 /* to disable P-State switching, set UCLK min = max */ 544 - if (!clk_mgr_base->clks.p_state_change_support) 545 - dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, 546 - clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1].memclk_mhz); 544 + if (!clk_mgr_base->clks.p_state_change_support) { 545 + if (dc->clk_mgr->dc_mode_softmax_enabled) { 546 + /* On DCN32x we will never have the functional UCLK min above the softmax 547 + * since we calculate mode support based on softmax being the max UCLK 548 + * frequency. 549 + */ 550 + dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, 551 + dc->clk_mgr->bw_params->dc_mode_softmax_memclk); 552 + } else { 553 + dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, dc->clk_mgr->bw_params->max_memclk_mhz); 554 + } 555 + } 547 556 } 548 557 549 558 /* Always update saved value, even if new value not set due to P-State switching unsupported. Also check safe_to_lower for FCLK */ ··· 817 808 if (!clk_mgr->smu_present) 818 809 return; 819 810 820 - dcn30_smu_set_hard_max_by_freq(clk_mgr, PPCLK_UCLK, 821 - clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1].memclk_mhz); 811 + dcn30_smu_set_hard_max_by_freq(clk_mgr, PPCLK_UCLK, clk_mgr_base->bw_params->max_memclk_mhz); 822 812 } 823 813 824 814 /* Get current memclk states, update bounding box */ ··· 835 827 &clk_mgr_base->bw_params->clk_table.entries[0].memclk_mhz, 836 828 &num_entries_per_clk->num_memclk_levels); 837 829 clk_mgr_base->bw_params->dc_mode_limit.memclk_mhz = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_UCLK); 830 + clk_mgr_base->bw_params->dc_mode_softmax_memclk = clk_mgr_base->bw_params->dc_mode_limit.memclk_mhz; 838 831 839 832 /* memclk must have at least one level */ 840 833 num_entries_per_clk->num_memclk_levels = num_entries_per_clk->num_memclk_levels ? num_entries_per_clk->num_memclk_levels : 1; ··· 850 841 } else { 851 842 num_levels = num_entries_per_clk->num_fclk_levels; 852 843 } 853 - 844 + clk_mgr_base->bw_params->max_memclk_mhz = 845 + clk_mgr_base->bw_params->clk_table.entries[num_entries_per_clk->num_memclk_levels - 1].memclk_mhz; 854 846 clk_mgr_base->bw_params->clk_table.num_entries = num_levels ? num_levels : 1; 855 847 856 848 if (clk_mgr->dpm_present && !num_levels) ··· 904 894 return clk_mgr->smu_present; 905 895 } 906 896 897 + static void dcn32_set_max_memclk(struct clk_mgr *clk_mgr_base, unsigned int memclk_mhz) 898 + { 899 + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); 900 + 901 + if (!clk_mgr->smu_present) 902 + return; 903 + 904 + dcn30_smu_set_hard_max_by_freq(clk_mgr, PPCLK_UCLK, memclk_mhz); 905 + } 906 + 907 + static void dcn32_set_min_memclk(struct clk_mgr *clk_mgr_base, unsigned int memclk_mhz) 908 + { 909 + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); 910 + 911 + if (!clk_mgr->smu_present) 912 + return; 913 + 914 + dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, memclk_mhz); 915 + } 907 916 908 917 static struct clk_mgr_funcs dcn32_funcs = { 909 918 .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, ··· 933 904 .notify_wm_ranges = dcn32_notify_wm_ranges, 934 905 .set_hard_min_memclk = dcn32_set_hard_min_memclk, 935 906 .set_hard_max_memclk = dcn32_set_hard_max_memclk, 907 + .set_max_memclk = dcn32_set_max_memclk, 908 + .set_min_memclk = dcn32_set_min_memclk, 936 909 .get_memclk_states_from_smu = dcn32_get_memclk_states_from_smu, 937 910 .are_clock_states_equal = dcn32_are_clock_states_equal, 938 911 .enable_pme_wa = dcn32_enable_pme_wa,
+135 -6
drivers/gpu/drm/amd/display/dc/core/dc.c
··· 1629 1629 return false; 1630 1630 } 1631 1631 1632 + if (dc->debug.force_odm_combine) 1633 + return false; 1634 + 1632 1635 /* Check for enabled DIG to identify enabled display */ 1633 1636 if (!link->link_enc->funcs->is_dig_enabled(link->link_enc)) 1634 1637 return false; ··· 3580 3577 hwss_execute_sequence(dc, 3581 3578 context->block_sequence, 3582 3579 context->block_sequence_steps); 3580 + /* Clear update flags so next flip doesn't have redundant programming 3581 + * (if there's no stream update, the update flags are not cleared). 3582 + */ 3583 + if (top_pipe_to_program->plane_state) 3584 + top_pipe_to_program->plane_state->update_flags.raw = 0; 3585 + if (top_pipe_to_program->stream) 3586 + top_pipe_to_program->stream->update_flags.raw = 0; 3583 3587 } 3584 3588 3585 3589 static void commit_planes_for_stream(struct dc *dc, ··· 4243 4233 } 4244 4234 } 4245 4235 4236 + static void populate_fast_updates(struct dc_fast_update *fast_update, 4237 + struct dc_surface_update *srf_updates, 4238 + int surface_count, 4239 + struct dc_stream_update *stream_update) 4240 + { 4241 + int i = 0; 4242 + 4243 + if (stream_update) { 4244 + fast_update[0].out_transfer_func = stream_update->out_transfer_func; 4245 + fast_update[0].output_csc_transform = stream_update->output_csc_transform; 4246 + } 4247 + 4248 + for (i = 0; i < surface_count; i++) { 4249 + fast_update[i].flip_addr = srf_updates[i].flip_addr; 4250 + fast_update[i].gamma = srf_updates[i].gamma; 4251 + fast_update[i].gamut_remap_matrix = srf_updates[i].gamut_remap_matrix; 4252 + fast_update[i].input_csc_color_matrix = srf_updates[i].input_csc_color_matrix; 4253 + fast_update[i].coeff_reduction_factor = srf_updates[i].coeff_reduction_factor; 4254 + } 4255 + } 4256 + 4257 + static bool fast_updates_exist(struct dc_fast_update *fast_update, int surface_count) 4258 + { 4259 + int i; 4260 + 4261 + if (fast_update[0].out_transfer_func || 4262 + fast_update[0].output_csc_transform) 4263 + return true; 4264 + 4265 + for (i = 0; i < surface_count; i++) { 4266 + if (fast_update[i].flip_addr || 4267 + fast_update[i].gamma || 4268 + fast_update[i].gamut_remap_matrix || 4269 + fast_update[i].input_csc_color_matrix || 4270 + fast_update[i].coeff_reduction_factor) 4271 + return true; 4272 + } 4273 + 4274 + return false; 4275 + } 4276 + 4277 + static bool full_update_required(struct dc_surface_update *srf_updates, 4278 + int surface_count, 4279 + struct dc_stream_update *stream_update, 4280 + struct dc_stream_state *stream) 4281 + { 4282 + 4283 + int i; 4284 + struct dc_stream_status *stream_status; 4285 + 4286 + for (i = 0; i < surface_count; i++) { 4287 + if (srf_updates && 4288 + (srf_updates[i].plane_info || 4289 + srf_updates[i].scaling_info || 4290 + (srf_updates[i].hdr_mult.value && 4291 + srf_updates[i].hdr_mult.value != srf_updates->surface->hdr_mult.value) || 4292 + srf_updates[i].in_transfer_func || 4293 + srf_updates[i].func_shaper || 4294 + srf_updates[i].lut3d_func || 4295 + srf_updates[i].blend_tf)) 4296 + return true; 4297 + } 4298 + 4299 + if (stream_update && 4300 + (((stream_update->src.height != 0 && stream_update->src.width != 0) || 4301 + (stream_update->dst.height != 0 && stream_update->dst.width != 0) || 4302 + stream_update->integer_scaling_update) || 4303 + stream_update->hdr_static_metadata || 4304 + stream_update->abm_level || 4305 + stream_update->periodic_interrupt || 4306 + stream_update->vrr_infopacket || 4307 + stream_update->vsc_infopacket || 4308 + stream_update->vsp_infopacket || 4309 + stream_update->hfvsif_infopacket || 4310 + stream_update->vtem_infopacket || 4311 + stream_update->adaptive_sync_infopacket || 4312 + stream_update->dpms_off || 4313 + stream_update->allow_freesync || 4314 + stream_update->vrr_active_variable || 4315 + stream_update->vrr_active_fixed || 4316 + stream_update->gamut_remap || 4317 + stream_update->output_color_space || 4318 + stream_update->dither_option || 4319 + stream_update->wb_update || 4320 + stream_update->dsc_config || 4321 + stream_update->mst_bw_update || 4322 + stream_update->func_shaper || 4323 + stream_update->lut3d_func || 4324 + stream_update->pending_test_pattern || 4325 + stream_update->crtc_timing_adjust)) 4326 + return true; 4327 + 4328 + if (stream) { 4329 + stream_status = dc_stream_get_status(stream); 4330 + if (stream_status == NULL || stream_status->plane_count != surface_count) 4331 + return true; 4332 + } 4333 + 4334 + return false; 4335 + } 4336 + 4337 + static bool fast_update_only(struct dc_fast_update *fast_update, 4338 + struct dc_surface_update *srf_updates, 4339 + int surface_count, 4340 + struct dc_stream_update *stream_update, 4341 + struct dc_stream_state *stream) 4342 + { 4343 + return fast_updates_exist(fast_update, surface_count) 4344 + && !full_update_required(srf_updates, surface_count, stream_update, stream); 4345 + } 4346 + 4246 4347 bool dc_update_planes_and_stream(struct dc *dc, 4247 4348 struct dc_surface_update *srf_updates, int surface_count, 4248 4349 struct dc_stream_state *stream, ··· 4363 4242 enum surface_update_type update_type; 4364 4243 int i; 4365 4244 struct mall_temp_config mall_temp_config; 4245 + struct dc_fast_update fast_update[MAX_SURFACES] = {0}; 4366 4246 4367 4247 /* In cases where MPO and split or ODM are used transitions can 4368 4248 * cause underflow. Apply stream configuration with minimal pipe ··· 4372 4250 bool force_minimal_pipe_splitting; 4373 4251 bool is_plane_addition; 4374 4252 4253 + populate_fast_updates(fast_update, srf_updates, surface_count, stream_update); 4375 4254 force_minimal_pipe_splitting = could_mpcc_tree_change_for_active_pipes( 4376 4255 dc, 4377 4256 stream, ··· 4423 4300 } 4424 4301 4425 4302 update_seamless_boot_flags(dc, context, surface_count, stream); 4426 - if (!dc->debug.enable_legacy_fast_update && update_type == UPDATE_TYPE_FAST) { 4303 + if (fast_update_only(fast_update, srf_updates, surface_count, stream_update, stream) && 4304 + !dc->debug.enable_legacy_fast_update) { 4427 4305 commit_planes_for_stream_fast(dc, 4428 4306 srf_updates, 4429 4307 surface_count, ··· 4481 4357 struct dc_state *context; 4482 4358 struct dc_context *dc_ctx = dc->ctx; 4483 4359 int i, j; 4360 + struct dc_fast_update fast_update[MAX_SURFACES] = {0}; 4484 4361 4362 + populate_fast_updates(fast_update, srf_updates, surface_count, stream_update); 4485 4363 stream_status = dc_stream_get_status(stream); 4486 4364 context = dc->current_state; 4487 4365 ··· 4569 4443 TRACE_DC_PIPE_STATE(pipe_ctx, i, MAX_PIPES); 4570 4444 4571 4445 update_seamless_boot_flags(dc, context, surface_count, stream); 4572 - if (!dc->debug.enable_legacy_fast_update && update_type == UPDATE_TYPE_FAST) { 4446 + if (fast_update_only(fast_update, srf_updates, surface_count, stream_update, stream) && 4447 + !dc->debug.enable_legacy_fast_update) { 4573 4448 commit_planes_for_stream_fast(dc, 4574 4449 srf_updates, 4575 4450 surface_count, ··· 4880 4753 */ 4881 4754 void dc_enable_dcmode_clk_limit(struct dc *dc, bool enable) 4882 4755 { 4883 - uint32_t hw_internal_rev = dc->ctx->asic_id.hw_internal_rev; 4884 - unsigned int softMax, maxDPM, funcMin; 4756 + unsigned int softMax = 0, maxDPM = 0, funcMin = 0, i; 4885 4757 bool p_state_change_support; 4886 4758 4887 - if (!ASICREV_IS_BEIGE_GOBY_P(hw_internal_rev)) 4759 + if (!dc->config.dc_mode_clk_limit_support) 4888 4760 return; 4889 4761 4890 4762 softMax = dc->clk_mgr->bw_params->dc_mode_softmax_memclk; 4891 - maxDPM = dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz; 4763 + for (i = 0; i < dc->clk_mgr->bw_params->clk_table.num_entries; i++) { 4764 + if (dc->clk_mgr->bw_params->clk_table.entries[i].memclk_mhz > maxDPM) 4765 + maxDPM = dc->clk_mgr->bw_params->clk_table.entries[i].memclk_mhz; 4766 + } 4892 4767 funcMin = (dc->clk_mgr->clks.dramclk_khz + 999) / 1000; 4893 4768 p_state_change_support = dc->clk_mgr->clks.p_state_change_support; 4894 4769
+1 -1
drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
··· 610 610 current_mpc_pipe = current_pipe; 611 611 612 612 while (current_mpc_pipe) { 613 - if (!current_mpc_pipe->bottom_pipe && !pipe_ctx->next_odm_pipe && 613 + if (!current_mpc_pipe->bottom_pipe && !current_mpc_pipe->next_odm_pipe && 614 614 current_mpc_pipe->stream && current_mpc_pipe->plane_state && 615 615 current_mpc_pipe->plane_state->update_flags.bits.addr_update && 616 616 !current_mpc_pipe->plane_state->skip_manual_trigger) {
+14 -2
drivers/gpu/drm/amd/display/dc/dc.h
··· 45 45 struct set_config_cmd_payload; 46 46 struct dmub_notification; 47 47 48 - #define DC_VER "3.2.239" 48 + #define DC_VER "3.2.241" 49 49 50 50 #define MAX_SURFACES 3 51 51 #define MAX_PLANES 6 ··· 416 416 uint8_t force_bios_fixed_vs; 417 417 int sdpif_request_limit_words_per_umc; 418 418 bool use_old_fixed_vs_sequence; 419 - bool disable_subvp_drr; 419 + bool dc_mode_clk_limit_support; 420 420 }; 421 421 422 422 enum visual_confirm { ··· 850 850 /* Enable dmub aux for legacy ddc */ 851 851 bool enable_dmub_aux_for_legacy_ddc; 852 852 bool disable_fams; 853 + bool disable_fams_gaming; 853 854 /* FEC/PSR1 sequence enable delay in 100us */ 854 855 uint8_t fec_enable_delay_in100us; 855 856 bool enable_driver_sequence_debug; ··· 1265 1264 struct scaling_taps scaling_quality; 1266 1265 }; 1267 1266 1267 + struct dc_fast_update { 1268 + const struct dc_flip_addrs *flip_addr; 1269 + const struct dc_gamma *gamma; 1270 + const struct colorspace_transform *gamut_remap_matrix; 1271 + const struct dc_csc_transform *input_csc_color_matrix; 1272 + const struct fixed31_32 *coeff_reduction_factor; 1273 + struct dc_transfer_func *out_transfer_func; 1274 + struct dc_csc_transform *output_csc_transform; 1275 + }; 1276 + 1268 1277 struct dc_surface_update { 1269 1278 struct dc_plane_state *surface; 1270 1279 ··· 1536 1525 bool dpia_forced_tbt3_mode; 1537 1526 bool dongle_mode_timing_override; 1538 1527 bool blank_stream_on_ocs_change; 1528 + bool read_dpcd204h_on_irq_hpd; 1539 1529 } wa_flags; 1540 1530 struct link_mst_stream_allocation_table mst_stream_alloc_table; 1541 1531
+7
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
··· 1011 1011 dm_execute_dmub_cmd_list(pCtx->stream->ctx, 2, cmd, DM_DMUB_WAIT_TYPE_WAIT); 1012 1012 } 1013 1013 } 1014 + 1015 + bool dc_dmub_check_min_version(struct dmub_srv *srv) 1016 + { 1017 + if (!srv->hw_funcs.is_psrsu_supported) 1018 + return true; 1019 + return srv->hw_funcs.is_psrsu_supported(srv); 1020 + }
+1
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
··· 86 86 void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv); 87 87 88 88 void dc_send_update_cursor_info_to_dmu(struct pipe_ctx *pCtx, uint8_t pipe_idx); 89 + bool dc_dmub_check_min_version(struct dmub_srv *srv); 89 90 #endif /* _DMUB_DC_SRV_H_ */
+28 -1
drivers/gpu/drm/amd/display/dc/dce/dce_abm.h
··· 266 266 type MASTER_COMM_INTERRUPT; \ 267 267 type MASTER_COMM_CMD_REG_BYTE0; \ 268 268 type MASTER_COMM_CMD_REG_BYTE1; \ 269 - type MASTER_COMM_CMD_REG_BYTE2 269 + type MASTER_COMM_CMD_REG_BYTE2; \ 270 + type ABM1_HG_BIN_33_40_SHIFT_INDEX; \ 271 + type ABM1_HG_BIN_33_64_SHIFT_FLAG; \ 272 + type ABM1_HG_BIN_41_48_SHIFT_INDEX; \ 273 + type ABM1_HG_BIN_49_56_SHIFT_INDEX; \ 274 + type ABM1_HG_BIN_57_64_SHIFT_INDEX; \ 275 + type ABM1_HG_RESULT_DATA; \ 276 + type ABM1_HG_RESULT_INDEX; \ 277 + type ABM1_ACE_SLOPE_DATA; \ 278 + type ABM1_ACE_OFFSET_DATA; \ 279 + type ABM1_ACE_OFFSET_SLOPE_INDEX; \ 280 + type ABM1_ACE_THRES_INDEX; \ 281 + type ABM1_ACE_IGNORE_MASTER_LOCK_EN; \ 282 + type ABM1_ACE_READBACK_DB_REG_VALUE_EN; \ 283 + type ABM1_ACE_DBUF_REG_UPDATE_PENDING; \ 284 + type ABM1_ACE_LOCK; \ 285 + type ABM1_ACE_THRES_DATA_1; \ 286 + type ABM1_ACE_THRES_DATA_2 270 287 271 288 struct dce_abm_shift { 272 289 ABM_REG_FIELD_LIST(uint8_t); ··· 305 288 uint32_t DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES; 306 289 uint32_t DC_ABM1_HGLS_REG_READ_PROGRESS; 307 290 uint32_t DC_ABM1_ACE_OFFSET_SLOPE_0; 291 + uint32_t DC_ABM1_ACE_OFFSET_SLOPE_DATA; 292 + uint32_t DC_ABM1_ACE_PWL_CNTL; 293 + uint32_t DC_ABM1_HG_BIN_33_40_SHIFT_INDEX; 294 + uint32_t DC_ABM1_HG_BIN_33_64_SHIFT_FLAG; 295 + uint32_t DC_ABM1_HG_BIN_41_48_SHIFT_INDEX; 296 + uint32_t DC_ABM1_HG_BIN_49_56_SHIFT_INDEX; 297 + uint32_t DC_ABM1_HG_BIN_57_64_SHIFT_INDEX; 298 + uint32_t DC_ABM1_HG_RESULT_DATA; 299 + uint32_t DC_ABM1_HG_RESULT_INDEX; 300 + uint32_t DC_ABM1_ACE_THRES_DATA; 308 301 uint32_t DC_ABM1_ACE_THRES_12; 309 302 uint32_t MASTER_COMM_CNTL_REG; 310 303 uint32_t MASTER_COMM_CMD_REG;
+6 -4
drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
··· 974 974 || dc_is_virtual_signal(pipe_ctx->stream->signal)) 975 975 pipe_ctx->clock_source = 976 976 dc->res_pool->dp_clock_source; 977 - else 978 - pipe_ctx->clock_source = find_matching_pll( 979 - &context->res_ctx, dc->res_pool, 980 - stream); 977 + else { 978 + if (stream && stream->link && stream->link->link_enc) 979 + pipe_ctx->clock_source = find_matching_pll( 980 + &context->res_ctx, dc->res_pool, 981 + stream); 982 + } 981 983 982 984 if (pipe_ctx->clock_source == NULL) 983 985 return DC_NO_CLOCK_SOURCE_RESOURCE;
+15 -4
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
··· 308 308 #define NUMBER_REGIONS 32 309 309 #define NUMBER_SW_SEGMENTS 16 310 310 311 - bool cm_helper_translate_curve_to_hw_format( 311 + #define DC_LOGGER \ 312 + ctx->logger 313 + 314 + bool cm_helper_translate_curve_to_hw_format(struct dc_context *ctx, 312 315 const struct dc_transfer_func *output_tf, 313 316 struct pwl_params *lut_params, bool fixpoint) 314 317 { ··· 485 482 rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); 486 483 rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue); 487 484 485 + 488 486 if (fixpoint == true) { 489 - rgb->delta_red_reg = dc_fixpt_clamp_u0d10(rgb->delta_red); 490 - rgb->delta_green_reg = dc_fixpt_clamp_u0d10(rgb->delta_green); 491 - rgb->delta_blue_reg = dc_fixpt_clamp_u0d10(rgb->delta_blue); 487 + uint32_t red_clamp = dc_fixpt_clamp_u0d14(rgb->delta_red); 488 + uint32_t green_clamp = dc_fixpt_clamp_u0d14(rgb->delta_green); 489 + uint32_t blue_clamp = dc_fixpt_clamp_u0d14(rgb->delta_blue); 490 + 491 + if (red_clamp >> 10 || green_clamp >> 10 || blue_clamp >> 10) 492 + DC_LOG_WARNING("Losing delta precision while programming shaper LUT."); 493 + 494 + rgb->delta_red_reg = red_clamp & 0x3ff; 495 + rgb->delta_green_reg = green_clamp & 0x3ff; 496 + rgb->delta_blue_reg = blue_clamp & 0x3ff; 492 497 rgb->red_reg = dc_fixpt_clamp_u0d14(rgb->red); 493 498 rgb->green_reg = dc_fixpt_clamp_u0d14(rgb->green); 494 499 rgb->blue_reg = dc_fixpt_clamp_u0d14(rgb->blue);
+1
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h
··· 106 106 bool fixpoint); 107 107 108 108 bool cm_helper_translate_curve_to_hw_format( 109 + struct dc_context *ctx, 109 110 const struct dc_transfer_func *output_tf, 110 111 struct pwl_params *lut_params, bool fixpoint); 111 112
+1 -1
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
··· 1843 1843 /* dcn10_translate_regamma_to_hw_format takes 750us, only do it when full 1844 1844 * update. 1845 1845 */ 1846 - else if (cm_helper_translate_curve_to_hw_format( 1846 + else if (cm_helper_translate_curve_to_hw_format(dc->ctx, 1847 1847 stream->out_transfer_func, 1848 1848 &dpp->regamma_params, false)) { 1849 1849 dpp->funcs->dpp_program_regamma_pwl(
+6 -5
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
··· 867 867 params = &stream->out_transfer_func->pwl; 868 868 else if (pipe_ctx->stream->out_transfer_func->type == 869 869 TF_TYPE_DISTRIBUTED_POINTS && 870 - cm_helper_translate_curve_to_hw_format( 870 + cm_helper_translate_curve_to_hw_format(dc->ctx, 871 871 stream->out_transfer_func, 872 872 &mpc->blender_params, false)) 873 873 params = &mpc->blender_params; ··· 896 896 if (plane_state->blend_tf->type == TF_TYPE_HWPWL) 897 897 blend_lut = &plane_state->blend_tf->pwl; 898 898 else if (plane_state->blend_tf->type == TF_TYPE_DISTRIBUTED_POINTS) { 899 - cm_helper_translate_curve_to_hw_format( 899 + cm_helper_translate_curve_to_hw_format(plane_state->ctx, 900 900 plane_state->blend_tf, 901 901 &dpp_base->regamma_params, false); 902 902 blend_lut = &dpp_base->regamma_params; ··· 918 918 if (plane_state->in_shaper_func->type == TF_TYPE_HWPWL) 919 919 shaper_lut = &plane_state->in_shaper_func->pwl; 920 920 else if (plane_state->in_shaper_func->type == TF_TYPE_DISTRIBUTED_POINTS) { 921 - cm_helper_translate_curve_to_hw_format( 921 + cm_helper_translate_curve_to_hw_format(plane_state->ctx, 922 922 plane_state->in_shaper_func, 923 923 &dpp_base->shaper_params, true); 924 924 shaper_lut = &dpp_base->shaper_params; ··· 1764 1764 hws->funcs.set_hdr_multiplier(pipe_ctx); 1765 1765 1766 1766 if (pipe_ctx->update_flags.bits.enable || 1767 - pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || 1768 - pipe_ctx->plane_state->update_flags.bits.gamma_change) 1767 + pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || 1768 + pipe_ctx->plane_state->update_flags.bits.gamma_change || 1769 + pipe_ctx->plane_state->update_flags.bits.lut_3d) 1769 1770 hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state); 1770 1771 1771 1772 /* dcn10_translate_regamma_to_hw_format takes 750us to finish
+1 -1
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c
··· 280 280 dwb_ogam_lut = kzalloc(sizeof(*dwb_ogam_lut), GFP_KERNEL); 281 281 282 282 if (dwb_ogam_lut) { 283 - cm_helper_translate_curve_to_hw_format( 283 + cm_helper_translate_curve_to_hw_format(dwbc->ctx, 284 284 in_transfer_func_dwb_ogam, 285 285 dwb_ogam_lut, false); 286 286
+1 -1
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
··· 106 106 if (stream->func_shaper->type == TF_TYPE_HWPWL) { 107 107 shaper_lut = &stream->func_shaper->pwl; 108 108 } else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) { 109 - cm_helper_translate_curve_to_hw_format(stream->func_shaper, 109 + cm_helper_translate_curve_to_hw_format(stream->ctx, stream->func_shaper, 110 110 &dpp_base->shaper_params, true); 111 111 shaper_lut = &dpp_base->shaper_params; 112 112 }
+3 -3
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
··· 725 725 .dwb_fi_phase = -1, // -1 = disable, 726 726 .dmub_command_table = true, 727 727 .use_max_lb = true, 728 - .exit_idle_opt_for_cursor_updates = true 728 + .exit_idle_opt_for_cursor_updates = true, 729 + .enable_legacy_fast_update = false, 729 730 }; 730 731 731 732 static const struct dc_panel_config panel_config_defaults = { ··· 1987 1986 if (!is_refresh_rate_support_mclk_switch_using_fw_based_vblank_stretch(context)) 1988 1987 return false; 1989 1988 1990 - // check if freesync enabled 1991 1989 if (!context->streams[0]->allow_freesync) 1992 1990 return false; 1993 1991 1994 - if (context->streams[0]->vrr_active_variable) 1992 + if (context->streams[0]->vrr_active_variable && dc->debug.disable_fams_gaming) 1995 1993 return false; 1996 1994 1997 1995 context->streams[0]->fpo_in_use = true;
+2 -1
drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
··· 95 95 .dwb_fi_phase = -1, // -1 = disable, 96 96 .dmub_command_table = true, 97 97 .use_max_lb = true, 98 - .exit_idle_opt_for_cursor_updates = true 98 + .exit_idle_opt_for_cursor_updates = true, 99 + .enable_legacy_fast_update = false, 99 100 }; 100 101 101 102 static const struct dc_panel_config panel_config_defaults = {
+1
drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
··· 1190 1190 1191 1191 dc->caps.dp_hdmi21_pcon_support = true; 1192 1192 1193 + dc->config.dc_mode_clk_limit_support = true; 1193 1194 /* read VBIOS LTTPR caps */ 1194 1195 if (ctx->dc_bios->funcs->get_lttpr_caps) { 1195 1196 enum bp_result bp_query_result;
+1 -1
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
··· 332 332 { 333 333 struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 334 334 335 - if (dccg->dpp_clock_gated[dpp_inst] == clock_on) 335 + if (dccg->dpp_clock_gated[dpp_inst] != clock_on) 336 336 return; 337 337 338 338 if (clock_on) {
+7 -23
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
··· 337 337 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); 338 338 } 339 339 340 - void dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div) 340 + unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div) 341 341 { 342 342 struct dc_stream_state *stream = pipe_ctx->stream; 343 + unsigned int odm_combine_factor = 0; 343 344 bool two_pix_per_container = false; 344 345 345 346 two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing); 346 - get_odm_config(pipe_ctx, NULL); 347 + odm_combine_factor = get_odm_config(pipe_ctx, NULL); 347 348 348 349 if (stream->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { 349 350 *k1_div = PIXEL_RATE_DIV_BY_1; ··· 362 361 } else { 363 362 *k1_div = PIXEL_RATE_DIV_BY_1; 364 363 *k2_div = PIXEL_RATE_DIV_BY_4; 364 + if (odm_combine_factor == 2) 365 + *k2_div = PIXEL_RATE_DIV_BY_2; 365 366 } 366 367 } 367 368 368 369 if ((*k1_div == PIXEL_RATE_DIV_NA) && (*k2_div == PIXEL_RATE_DIV_NA)) 369 370 ASSERT(false); 371 + 372 + return odm_combine_factor; 370 373 } 371 374 372 375 void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx) ··· 429 424 hws->ctx->dc->res_pool->dccg, dpp_inst, clock_on); 430 425 } 431 426 432 - void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on) 433 - { 434 - struct dc_context *ctx = hws->ctx; 435 - union dmub_rb_cmd cmd; 436 - 437 - if (hws->ctx->dc->debug.disable_hubp_power_gate) 438 - return; 439 - 440 - PERF_TRACE(); 441 - 442 - memset(&cmd, 0, sizeof(cmd)); 443 - cmd.domain_control.header.type = DMUB_CMD__VBIOS; 444 - cmd.domain_control.header.sub_type = DMUB_CMD__VBIOS_DOMAIN_CONTROL; 445 - cmd.domain_control.header.payload_bytes = sizeof(cmd.domain_control.data); 446 - cmd.domain_control.data.inst = hubp_inst; 447 - cmd.domain_control.data.power_gate = !power_on; 448 - 449 - dm_execute_dmub_cmd(ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT); 450 - 451 - PERF_TRACE(); 452 - } 453 427 static void apply_symclk_on_tx_off_wa(struct dc_link *link) 454 428 { 455 429 /* There are use cases where SYMCLK is referenced by OTG. For instance
+1 -3
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h
··· 37 37 38 38 void dcn314_enable_power_gating_plane(struct dce_hwseq *hws, bool enable); 39 39 40 - void dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div); 40 + unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div); 41 41 42 42 void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx); 43 43 44 44 void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context); 45 - 46 - void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on); 47 45 48 46 void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on); 49 47
+1 -1
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c
··· 139 139 .plane_atomic_power_down = dcn10_plane_atomic_power_down, 140 140 .enable_power_gating_plane = dcn314_enable_power_gating_plane, 141 141 .dpp_root_clock_control = dcn314_dpp_root_clock_control, 142 - .hubp_pg_control = dcn314_hubp_pg_control, 142 + .hubp_pg_control = dcn31_hubp_pg_control, 143 143 .program_all_writeback_pipes_in_tree = dcn30_program_all_writeback_pipes_in_tree, 144 144 .update_odm = dcn314_update_odm, 145 145 .dsc_pg_control = dcn314_dsc_pg_control,
+8 -7
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
··· 1883 1883 /* Use pipe context based otg sync logic */ 1884 1884 dc->config.use_pipe_ctx_sync_logic = true; 1885 1885 1886 - /* Disable pipe power gating when unsupported */ 1887 - if (ctx->asic_id.hw_internal_rev == 0x01 || 1888 - ctx->asic_id.hw_internal_rev == 0x80) { 1889 - dc->debug.disable_dpp_power_gate = true; 1890 - dc->debug.disable_hubp_power_gate = true; 1891 - } 1892 - 1893 1886 /* read VBIOS LTTPR caps */ 1894 1887 { 1895 1888 if (ctx->dc_bios->funcs->get_lttpr_caps) { ··· 1903 1910 dc->debug = debug_defaults_drv; 1904 1911 else 1905 1912 dc->debug = debug_defaults_diags; 1913 + 1914 + /* Disable pipe power gating */ 1915 + dc->debug.disable_dpp_power_gate = true; 1916 + dc->debug.disable_hubp_power_gate = true; 1917 + 1918 + /* Disable root clock optimization */ 1919 + dc->debug.root_clock_optimization.u32All = 0; 1920 + 1906 1921 // Init the vm_helper 1907 1922 if (dc->vm_helper) 1908 1923 vm_helper_init(dc->vm_helper, 16);
+1 -1
drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
··· 1610 1610 { 1611 1611 if (SourcePixelFormat == dm_444_64) 1612 1612 return 8; 1613 - else if (SourcePixelFormat == dm_444_16 || SourcePixelFormat == dm_444_16) 1613 + else if (SourcePixelFormat == dm_444_16) 1614 1614 return 2; 1615 1615 else if (SourcePixelFormat == dm_444_8) 1616 1616 return 1;
+1
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c
··· 179 179 .hubp_setup_interdependent = hubp2_setup_interdependent, 180 180 .hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings, 181 181 .set_blank = hubp2_set_blank, 182 + .set_blank_regs = hubp2_set_blank_regs, 182 183 .dcc_control = hubp3_dcc_control, 183 184 .mem_program_viewport = min_set_viewport, 184 185 .set_cursor_attributes = hubp32_cursor_set_attributes,
+9 -9
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
··· 448 448 if (stream->func_shaper->type == TF_TYPE_HWPWL) 449 449 shaper_lut = &stream->func_shaper->pwl; 450 450 else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) { 451 - cm_helper_translate_curve_to_hw_format( 451 + cm_helper_translate_curve_to_hw_format(stream->ctx, 452 452 stream->func_shaper, 453 453 &dpp_base->shaper_params, true); 454 454 shaper_lut = &dpp_base->shaper_params; ··· 484 484 if (plane_state->blend_tf->type == TF_TYPE_HWPWL) 485 485 lut_params = &plane_state->blend_tf->pwl; 486 486 else if (plane_state->blend_tf->type == TF_TYPE_DISTRIBUTED_POINTS) { 487 - cm_helper_translate_curve_to_hw_format( 487 + cm_helper_translate_curve_to_hw_format(plane_state->ctx, 488 488 plane_state->blend_tf, 489 489 &dpp_base->regamma_params, false); 490 490 lut_params = &dpp_base->regamma_params; ··· 499 499 else if (plane_state->in_shaper_func->type == TF_TYPE_DISTRIBUTED_POINTS) { 500 500 // TODO: dpp_base replace 501 501 ASSERT(false); 502 - cm_helper_translate_curve_to_hw_format( 502 + cm_helper_translate_curve_to_hw_format(plane_state->ctx, 503 503 plane_state->in_shaper_func, 504 504 &dpp_base->shaper_params, true); 505 505 lut_params = &dpp_base->shaper_params; ··· 1141 1141 } 1142 1142 } 1143 1143 1144 - void dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div) 1144 + unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div) 1145 1145 { 1146 1146 struct dc_stream_state *stream = pipe_ctx->stream; 1147 + unsigned int odm_combine_factor = 0; 1147 1148 bool two_pix_per_container = false; 1148 1149 1149 - // For phantom pipes, use the same programming as the main pipes 1150 - if (pipe_ctx->stream->mall_stream_config.type == SUBVP_PHANTOM) { 1151 - stream = pipe_ctx->stream->mall_stream_config.paired_stream; 1152 - } 1153 1150 two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing); 1151 + odm_combine_factor = get_odm_config(pipe_ctx, NULL); 1154 1152 1155 1153 if (stream->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { 1156 1154 *k1_div = PIXEL_RATE_DIV_BY_1; ··· 1166 1168 } else { 1167 1169 *k1_div = PIXEL_RATE_DIV_BY_1; 1168 1170 *k2_div = PIXEL_RATE_DIV_BY_4; 1169 - if (dcn32_is_dp_dig_pixel_rate_div_policy(pipe_ctx)) 1171 + if ((odm_combine_factor == 2) || dcn32_is_dp_dig_pixel_rate_div_policy(pipe_ctx)) 1170 1172 *k2_div = PIXEL_RATE_DIV_BY_2; 1171 1173 } 1172 1174 } 1173 1175 1174 1176 if ((*k1_div == PIXEL_RATE_DIV_NA) && (*k2_div == PIXEL_RATE_DIV_NA)) 1175 1177 ASSERT(false); 1178 + 1179 + return odm_combine_factor; 1176 1180 } 1177 1181 1178 1182 void dcn32_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx)
+1 -1
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h
··· 71 71 72 72 void dcn32_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx); 73 73 74 - void dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div); 74 + unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div); 75 75 76 76 void dcn32_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx); 77 77
+1
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c
··· 56 56 .enable_audio_stream = dce110_enable_audio_stream, 57 57 .disable_audio_stream = dce110_disable_audio_stream, 58 58 .disable_plane = dcn20_disable_plane, 59 + .disable_pixel_data = dcn20_disable_pixel_data, 59 60 .pipe_control_lock = dcn20_pipe_control_lock, 60 61 .interdependent_update_lock = dcn10_lock_all_pipes, 61 62 .cursor_lock = dcn10_cursor_lock,
+2
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
··· 732 732 .disable_dp_plus_plus_wa = true, 733 733 .fpo_vactive_min_active_margin_us = 200, 734 734 .fpo_vactive_max_blank_us = 1000, 735 + .enable_legacy_fast_update = false, 735 736 }; 736 737 737 738 static struct dce_aux *dcn32_aux_engine_create( ··· 2215 2214 /* Use pipe context based otg sync logic */ 2216 2215 dc->config.use_pipe_ctx_sync_logic = true; 2217 2216 2217 + dc->config.dc_mode_clk_limit_support = true; 2218 2218 /* read VBIOS LTTPR caps */ 2219 2219 { 2220 2220 if (ctx->dc_bios->funcs->get_lttpr_caps) {
+1 -2
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
··· 595 595 if (!is_refresh_rate_support_mclk_switch_using_fw_based_vblank_stretch(fpo_candidate_stream, fpo_vactive_margin_us)) 596 596 return NULL; 597 597 598 - // check if freesync enabled 599 598 if (!fpo_candidate_stream->allow_freesync) 600 599 return NULL; 601 600 602 - if (fpo_candidate_stream->vrr_active_variable) 601 + if (fpo_candidate_stream->vrr_active_variable && dc->debug.disable_fams_gaming) 603 602 return NULL; 604 603 605 604 return fpo_candidate_stream;
+3
drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
··· 730 730 .disable_subvp_high_refresh = false, 731 731 .fpo_vactive_min_active_margin_us = 200, 732 732 .fpo_vactive_max_blank_us = 1000, 733 + .enable_legacy_fast_update = false, 734 + .disable_dc_mode_overwrite = true, 733 735 }; 734 736 735 737 static struct dce_aux *dcn321_aux_engine_create( ··· 1756 1754 dc->caps.color.mpc.ogam_rom_caps.hlg = 0; 1757 1755 dc->caps.color.mpc.ocsc = 1; 1758 1756 1757 + dc->config.dc_mode_clk_limit_support = true; 1759 1758 /* read VBIOS LTTPR caps */ 1760 1759 { 1761 1760 if (ctx->dc_bios->funcs->get_lttpr_caps) {
+10 -6
drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
··· 4356 4356 locals->PSCL_FACTOR[k] / locals->ReturnBWPerState[i][0], 4357 4357 locals->EffectiveLBLatencyHidingSourceLinesLuma), 4358 4358 locals->SwathHeightYPerState[i][j][k]); 4359 - 4360 - locals->EffectiveDETLBLinesChroma = dml_floor(locals->LinesInDETChroma + dml_min( 4361 - locals->LinesInDETChroma * locals->RequiredDISPCLK[i][j] * locals->BytePerPixelInDETC[k] * 4362 - locals->PSCL_FACTOR_CHROMA[k] / locals->ReturnBWPerState[i][0], 4363 - locals->EffectiveLBLatencyHidingSourceLinesChroma), 4364 - locals->SwathHeightCPerState[i][j][k]); 4359 + if (locals->LinesInDETChroma) { 4360 + locals->EffectiveDETLBLinesChroma = dml_floor(locals->LinesInDETChroma + 4361 + dml_min(locals->LinesInDETChroma * locals->RequiredDISPCLK[i][j] * 4362 + locals->BytePerPixelInDETC[k] * 4363 + locals->PSCL_FACTOR_CHROMA[k] / locals->ReturnBWPerState[i][0], 4364 + locals->EffectiveLBLatencyHidingSourceLinesChroma), 4365 + locals->SwathHeightCPerState[i][j][k]); 4366 + } else { 4367 + locals->EffectiveDETLBLinesChroma = 0; 4368 + } 4365 4369 4366 4370 if (locals->BytePerPixelInDETC[k] == 0) { 4367 4371 locals->UrgentLatencySupportUsPerState[i][j][k] = locals->EffectiveDETLBLinesLuma * (locals->HTotal[k] / locals->PixelClock[k])
+1 -1
drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c
··· 33 33 #include "dml/display_mode_vba.h" 34 34 35 35 struct _vcs_dpi_ip_params_st dcn3_14_ip = { 36 - .VBlankNomDefaultUS = 800, 36 + .VBlankNomDefaultUS = 668, 37 37 .gpuvm_enable = 1, 38 38 .gpuvm_max_page_table_levels = 1, 39 39 .hostvm_enable = 1,
+84 -6
drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
··· 485 485 } 486 486 } 487 487 488 - void insert_entry_into_table_sorted(struct _vcs_dpi_voltage_scaling_st *table, 488 + static void insert_entry_into_table_sorted(struct _vcs_dpi_voltage_scaling_st *table, 489 489 unsigned int *num_entries, 490 490 struct _vcs_dpi_voltage_scaling_st *entry) 491 491 { 492 492 int i = 0; 493 493 int index = 0; 494 - float net_bw_of_new_state = 0; 495 494 496 495 dc_assert_fp_enabled(); 497 - 498 - get_optimal_ntuple(entry); 499 496 500 497 if (*num_entries == 0) { 501 498 table[0] = *entry; 502 499 (*num_entries)++; 503 500 } else { 504 - net_bw_of_new_state = calculate_net_bw_in_kbytes_sec(entry); 505 - while (net_bw_of_new_state > calculate_net_bw_in_kbytes_sec(&table[index])) { 501 + while (entry->net_bw_in_kbytes_sec > table[index].net_bw_in_kbytes_sec) { 506 502 index++; 507 503 if (index >= *num_entries) 508 504 break; ··· 2345 2349 bw_params->clk_table.entries[0].memclk_mhz = dcn3_2_soc.clock_limits[0].dram_speed_mts / 16; 2346 2350 } 2347 2351 2352 + static void swap_table_entries(struct _vcs_dpi_voltage_scaling_st *first_entry, 2353 + struct _vcs_dpi_voltage_scaling_st *second_entry) 2354 + { 2355 + struct _vcs_dpi_voltage_scaling_st temp_entry = *first_entry; 2356 + *first_entry = *second_entry; 2357 + *second_entry = temp_entry; 2358 + } 2359 + 2360 + /* 2361 + * sort_entries_with_same_bw - Sort entries sharing the same bandwidth by DCFCLK 2362 + */ 2363 + static void sort_entries_with_same_bw(struct _vcs_dpi_voltage_scaling_st *table, unsigned int *num_entries) 2364 + { 2365 + unsigned int start_index = 0; 2366 + unsigned int end_index = 0; 2367 + unsigned int current_bw = 0; 2368 + 2369 + for (int i = 0; i < (*num_entries - 1); i++) { 2370 + if (table[i].net_bw_in_kbytes_sec == table[i+1].net_bw_in_kbytes_sec) { 2371 + current_bw = table[i].net_bw_in_kbytes_sec; 2372 + start_index = i; 2373 + end_index = ++i; 2374 + 2375 + while ((i < (*num_entries - 1)) && (table[i+1].net_bw_in_kbytes_sec == current_bw)) 2376 + end_index = ++i; 2377 + } 2378 + 2379 + if (start_index != end_index) { 2380 + for (int j = start_index; j < end_index; j++) { 2381 + for (int k = start_index; k < end_index; k++) { 2382 + if (table[k].dcfclk_mhz > table[k+1].dcfclk_mhz) 2383 + swap_table_entries(&table[k], &table[k+1]); 2384 + } 2385 + } 2386 + } 2387 + 2388 + start_index = 0; 2389 + end_index = 0; 2390 + 2391 + } 2392 + } 2393 + 2394 + /* 2395 + * remove_inconsistent_entries - Ensure entries with the same bandwidth have MEMCLK and FCLK monotonically increasing 2396 + * and remove entries that do not 2397 + */ 2398 + static void remove_inconsistent_entries(struct _vcs_dpi_voltage_scaling_st *table, unsigned int *num_entries) 2399 + { 2400 + for (int i = 0; i < (*num_entries - 1); i++) { 2401 + if (table[i].net_bw_in_kbytes_sec == table[i+1].net_bw_in_kbytes_sec) { 2402 + if ((table[i].dram_speed_mts > table[i+1].dram_speed_mts) || 2403 + (table[i].fabricclk_mhz > table[i+1].fabricclk_mhz)) 2404 + remove_entry_from_table_at_index(table, num_entries, i); 2405 + } 2406 + } 2407 + } 2408 + 2348 2409 /* 2349 2410 * override_max_clk_values - Overwrite the max clock frequencies with the max DC mode timings 2350 2411 * Input: ··· 2533 2480 entry.fabricclk_mhz = 0; 2534 2481 entry.dram_speed_mts = 0; 2535 2482 2483 + get_optimal_ntuple(&entry); 2484 + entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&entry); 2536 2485 insert_entry_into_table_sorted(table, num_entries, &entry); 2537 2486 } 2538 2487 ··· 2543 2488 entry.fabricclk_mhz = 0; 2544 2489 entry.dram_speed_mts = 0; 2545 2490 2491 + get_optimal_ntuple(&entry); 2492 + entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&entry); 2546 2493 insert_entry_into_table_sorted(table, num_entries, &entry); 2547 2494 2548 2495 // Insert the UCLK DPMS ··· 2553 2496 entry.fabricclk_mhz = 0; 2554 2497 entry.dram_speed_mts = bw_params->clk_table.entries[i].memclk_mhz * 16; 2555 2498 2499 + get_optimal_ntuple(&entry); 2500 + entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&entry); 2556 2501 insert_entry_into_table_sorted(table, num_entries, &entry); 2557 2502 } 2558 2503 ··· 2565 2506 entry.fabricclk_mhz = bw_params->clk_table.entries[i].fclk_mhz; 2566 2507 entry.dram_speed_mts = 0; 2567 2508 2509 + get_optimal_ntuple(&entry); 2510 + entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&entry); 2568 2511 insert_entry_into_table_sorted(table, num_entries, &entry); 2569 2512 } 2570 2513 } ··· 2576 2515 entry.fabricclk_mhz = max_clk_data.fclk_mhz; 2577 2516 entry.dram_speed_mts = 0; 2578 2517 2518 + get_optimal_ntuple(&entry); 2519 + entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&entry); 2579 2520 insert_entry_into_table_sorted(table, num_entries, &entry); 2580 2521 } 2581 2522 ··· 2591 2528 table[i].fabricclk_mhz > max_clk_data.fclk_mhz || 2592 2529 table[i].dram_speed_mts > max_clk_data.memclk_mhz * 16) 2593 2530 remove_entry_from_table_at_index(table, num_entries, i); 2531 + } 2532 + 2533 + // Insert entry with all max dc limits without bandwidth matching 2534 + if (!disable_dc_mode_overwrite) { 2535 + struct _vcs_dpi_voltage_scaling_st max_dc_limits_entry = entry; 2536 + 2537 + max_dc_limits_entry.dcfclk_mhz = max_clk_data.dcfclk_mhz; 2538 + max_dc_limits_entry.fabricclk_mhz = max_clk_data.fclk_mhz; 2539 + max_dc_limits_entry.dram_speed_mts = max_clk_data.memclk_mhz * 16; 2540 + 2541 + max_dc_limits_entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&max_dc_limits_entry); 2542 + insert_entry_into_table_sorted(table, num_entries, &max_dc_limits_entry); 2543 + 2544 + sort_entries_with_same_bw(table, num_entries); 2545 + remove_inconsistent_entries(table, num_entries); 2594 2546 } 2595 2547 2596 2548 // At this point, the table only contains supported points of interest
-4
drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.h
··· 39 39 uint8_t dcn32_predict_pipe_split(struct dc_state *context, 40 40 display_e2e_pipe_params_st *pipe_e2e); 41 41 42 - void insert_entry_into_table_sorted(struct _vcs_dpi_voltage_scaling_st *table, 43 - unsigned int *num_entries, 44 - struct _vcs_dpi_voltage_scaling_st *entry); 45 - 46 42 void dcn32_set_phantom_stream_timing(struct dc *dc, 47 43 struct dc_state *context, 48 44 struct pipe_ctx *ref_pipe,
+91 -11
drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
··· 207 207 return limiting_bw_kbytes_sec; 208 208 } 209 209 210 - void dcn321_insert_entry_into_table_sorted(struct _vcs_dpi_voltage_scaling_st *table, 210 + static void dcn321_insert_entry_into_table_sorted(struct _vcs_dpi_voltage_scaling_st *table, 211 211 unsigned int *num_entries, 212 212 struct _vcs_dpi_voltage_scaling_st *entry) 213 213 { 214 214 int i = 0; 215 215 int index = 0; 216 - float net_bw_of_new_state = 0; 217 216 218 217 dc_assert_fp_enabled(); 219 - 220 - get_optimal_ntuple(entry); 221 218 222 219 if (*num_entries == 0) { 223 220 table[0] = *entry; 224 221 (*num_entries)++; 225 222 } else { 226 - net_bw_of_new_state = calculate_net_bw_in_kbytes_sec(entry); 227 - while (net_bw_of_new_state > calculate_net_bw_in_kbytes_sec(&table[index])) { 223 + while (entry->net_bw_in_kbytes_sec > table[index].net_bw_in_kbytes_sec) { 228 224 index++; 229 225 if (index >= *num_entries) 230 226 break; ··· 246 250 table[i] = table[i + 1]; 247 251 } 248 252 memset(&table[--(*num_entries)], 0, sizeof(struct _vcs_dpi_voltage_scaling_st)); 253 + } 254 + 255 + static void swap_table_entries(struct _vcs_dpi_voltage_scaling_st *first_entry, 256 + struct _vcs_dpi_voltage_scaling_st *second_entry) 257 + { 258 + struct _vcs_dpi_voltage_scaling_st temp_entry = *first_entry; 259 + *first_entry = *second_entry; 260 + *second_entry = temp_entry; 261 + } 262 + 263 + /* 264 + * sort_entries_with_same_bw - Sort entries sharing the same bandwidth by DCFCLK 265 + */ 266 + static void sort_entries_with_same_bw(struct _vcs_dpi_voltage_scaling_st *table, unsigned int *num_entries) 267 + { 268 + unsigned int start_index = 0; 269 + unsigned int end_index = 0; 270 + unsigned int current_bw = 0; 271 + 272 + for (int i = 0; i < (*num_entries - 1); i++) { 273 + if (table[i].net_bw_in_kbytes_sec == table[i+1].net_bw_in_kbytes_sec) { 274 + current_bw = table[i].net_bw_in_kbytes_sec; 275 + start_index = i; 276 + end_index = ++i; 277 + 278 + while ((i < (*num_entries - 1)) && (table[i+1].net_bw_in_kbytes_sec == current_bw)) 279 + end_index = ++i; 280 + } 281 + 282 + if (start_index != end_index) { 283 + for (int j = start_index; j < end_index; j++) { 284 + for (int k = start_index; k < end_index; k++) { 285 + if (table[k].dcfclk_mhz > table[k+1].dcfclk_mhz) 286 + swap_table_entries(&table[k], &table[k+1]); 287 + } 288 + } 289 + } 290 + 291 + start_index = 0; 292 + end_index = 0; 293 + 294 + } 295 + } 296 + 297 + /* 298 + * remove_inconsistent_entries - Ensure entries with the same bandwidth have MEMCLK and FCLK monotonically increasing 299 + * and remove entries that do not follow this order 300 + */ 301 + static void remove_inconsistent_entries(struct _vcs_dpi_voltage_scaling_st *table, unsigned int *num_entries) 302 + { 303 + for (int i = 0; i < (*num_entries - 1); i++) { 304 + if (table[i].net_bw_in_kbytes_sec == table[i+1].net_bw_in_kbytes_sec) { 305 + if ((table[i].dram_speed_mts > table[i+1].dram_speed_mts) || 306 + (table[i].fabricclk_mhz > table[i+1].fabricclk_mhz)) 307 + remove_entry_from_table_at_index(table, num_entries, i); 308 + } 309 + } 249 310 } 250 311 251 312 /* ··· 415 362 416 363 if (max_clk_data.fclk_mhz == 0) 417 364 max_clk_data.fclk_mhz = max_clk_data.dcfclk_mhz * 418 - dcn3_2_soc.pct_ideal_sdp_bw_after_urgent / 419 - dcn3_2_soc.pct_ideal_fabric_bw_after_urgent; 365 + dcn3_21_soc.pct_ideal_sdp_bw_after_urgent / 366 + dcn3_21_soc.pct_ideal_fabric_bw_after_urgent; 420 367 421 368 if (max_clk_data.phyclk_mhz == 0) 422 - max_clk_data.phyclk_mhz = dcn3_2_soc.clock_limits[0].phyclk_mhz; 369 + max_clk_data.phyclk_mhz = dcn3_21_soc.clock_limits[0].phyclk_mhz; 423 370 424 371 *num_entries = 0; 425 372 entry.dispclk_mhz = max_clk_data.dispclk_mhz; ··· 427 374 entry.dppclk_mhz = max_clk_data.dppclk_mhz; 428 375 entry.dtbclk_mhz = max_clk_data.dtbclk_mhz; 429 376 entry.phyclk_mhz = max_clk_data.phyclk_mhz; 430 - entry.phyclk_d18_mhz = dcn3_2_soc.clock_limits[0].phyclk_d18_mhz; 431 - entry.phyclk_d32_mhz = dcn3_2_soc.clock_limits[0].phyclk_d32_mhz; 377 + entry.phyclk_d18_mhz = dcn3_21_soc.clock_limits[0].phyclk_d18_mhz; 378 + entry.phyclk_d32_mhz = dcn3_21_soc.clock_limits[0].phyclk_d32_mhz; 432 379 433 380 // Insert all the DCFCLK STAs 434 381 for (i = 0; i < num_dcfclk_stas; i++) { ··· 436 383 entry.fabricclk_mhz = 0; 437 384 entry.dram_speed_mts = 0; 438 385 386 + get_optimal_ntuple(&entry); 387 + entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&entry); 439 388 dcn321_insert_entry_into_table_sorted(table, num_entries, &entry); 440 389 } 441 390 ··· 446 391 entry.fabricclk_mhz = 0; 447 392 entry.dram_speed_mts = 0; 448 393 394 + get_optimal_ntuple(&entry); 395 + entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&entry); 449 396 dcn321_insert_entry_into_table_sorted(table, num_entries, &entry); 450 397 451 398 // Insert the UCLK DPMS ··· 456 399 entry.fabricclk_mhz = 0; 457 400 entry.dram_speed_mts = bw_params->clk_table.entries[i].memclk_mhz * 16; 458 401 402 + get_optimal_ntuple(&entry); 403 + entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&entry); 459 404 dcn321_insert_entry_into_table_sorted(table, num_entries, &entry); 460 405 } 461 406 ··· 468 409 entry.fabricclk_mhz = bw_params->clk_table.entries[i].fclk_mhz; 469 410 entry.dram_speed_mts = 0; 470 411 412 + get_optimal_ntuple(&entry); 413 + entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&entry); 471 414 dcn321_insert_entry_into_table_sorted(table, num_entries, &entry); 472 415 } 473 416 } ··· 479 418 entry.fabricclk_mhz = max_clk_data.fclk_mhz; 480 419 entry.dram_speed_mts = 0; 481 420 421 + get_optimal_ntuple(&entry); 422 + entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&entry); 482 423 dcn321_insert_entry_into_table_sorted(table, num_entries, &entry); 483 424 } 484 425 ··· 495 432 table[i].dram_speed_mts > max_clk_data.memclk_mhz * 16) 496 433 remove_entry_from_table_at_index(table, num_entries, i); 497 434 } 435 + 436 + // Insert entry with all max dc limits without bandwitch matching 437 + if (!disable_dc_mode_overwrite) { 438 + struct _vcs_dpi_voltage_scaling_st max_dc_limits_entry = entry; 439 + 440 + max_dc_limits_entry.dcfclk_mhz = max_clk_data.dcfclk_mhz; 441 + max_dc_limits_entry.fabricclk_mhz = max_clk_data.fclk_mhz; 442 + max_dc_limits_entry.dram_speed_mts = max_clk_data.memclk_mhz * 16; 443 + 444 + max_dc_limits_entry.net_bw_in_kbytes_sec = calculate_net_bw_in_kbytes_sec(&max_dc_limits_entry); 445 + dcn321_insert_entry_into_table_sorted(table, num_entries, &max_dc_limits_entry); 446 + 447 + sort_entries_with_same_bw(table, num_entries); 448 + remove_inconsistent_entries(table, num_entries); 449 + } 450 + 451 + 498 452 499 453 // At this point, the table only contains supported points of interest 500 454 // it could be used as is, but some states may be redundant due to
-4
drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.h
··· 29 29 30 30 #include "dml/display_mode_vba.h" 31 31 32 - void dcn321_insert_entry_into_table_sorted(struct _vcs_dpi_voltage_scaling_st *table, 33 - unsigned int *num_entries, 34 - struct _vcs_dpi_voltage_scaling_st *entry); 35 - 36 32 void dcn321_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params); 37 33 38 34 #endif
+1
drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
··· 167 167 double phyclk_mhz; 168 168 double dppclk_mhz; 169 169 double dtbclk_mhz; 170 + float net_bw_in_kbytes_sec; 170 171 }; 171 172 172 173 /**
+1
drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
··· 230 230 unsigned int dram_channel_width_bytes; 231 231 unsigned int dispclk_vco_khz; 232 232 unsigned int dc_mode_softmax_memclk; 233 + unsigned int max_memclk_mhz; 233 234 struct clk_limit_table clk_table; 234 235 struct wm_table wm_table; 235 236 struct dummy_pstate_entry dummy_pstate_table[4];
+1 -1
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h
··· 156 156 void (*program_mall_pipe_config)(struct dc *dc, struct dc_state *context); 157 157 void (*update_force_pstate)(struct dc *dc, struct dc_state *context); 158 158 void (*update_mall_sel)(struct dc *dc, struct dc_state *context); 159 - void (*calculate_dccg_k1_k2_values)(struct pipe_ctx *pipe_ctx, 159 + unsigned int (*calculate_dccg_k1_k2_values)(struct pipe_ctx *pipe_ctx, 160 160 unsigned int *k1_div, 161 161 unsigned int *k2_div); 162 162 void (*set_pixels_per_cycle)(struct pipe_ctx *pipe_ctx);
+3 -1
drivers/gpu/drm/amd/display/dmub/dmub_srv.h
··· 367 367 368 368 bool (*is_supported)(struct dmub_srv *dmub); 369 369 370 + bool (*is_psrsu_supported)(struct dmub_srv *dmub); 371 + 370 372 bool (*is_hw_init)(struct dmub_srv *dmub); 371 373 372 374 void (*enable_dmub_boot_options)(struct dmub_srv *dmub, ··· 494 492 * of a firmware to know if feature or functionality is supported or present. 495 493 */ 496 494 #define DMUB_FW_VERSION(major, minor, revision) \ 497 - ((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | ((revision) & 0xFFFF)) 495 + ((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | (((revision) & 0xFF) << 8)) 498 496 499 497 /** 500 498 * dmub_srv_create() - creates the DMUB service.
+5
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
··· 302 302 return supported; 303 303 } 304 304 305 + bool dmub_dcn31_is_psrsu_supported(struct dmub_srv *dmub) 306 + { 307 + return dmub->fw_version >= DMUB_FW_VERSION(4, 0, 59); 308 + } 309 + 305 310 void dmub_dcn31_set_gpint(struct dmub_srv *dmub, 306 311 union dmub_gpint_data_register reg) 307 312 {
+2
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h
··· 221 221 222 222 bool dmub_dcn31_is_supported(struct dmub_srv *dmub); 223 223 224 + bool dmub_dcn31_is_psrsu_supported(struct dmub_srv *dmub); 225 + 224 226 void dmub_dcn31_set_gpint(struct dmub_srv *dmub, 225 227 union dmub_gpint_data_register reg); 226 228
+5
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn314.c
··· 60 60 { DMUB_DCN31_FIELDS() }, 61 61 #undef DMUB_SF 62 62 }; 63 + 64 + bool dmub_dcn314_is_psrsu_supported(struct dmub_srv *dmub) 65 + { 66 + return dmub->fw_version >= DMUB_FW_VERSION(8, 0, 16); 67 + }
+2
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn314.h
··· 30 30 31 31 extern const struct dmub_srv_dcn31_regs dmub_srv_dcn314_regs; 32 32 33 + bool dmub_dcn314_is_psrsu_supported(struct dmub_srv *dmub); 34 + 33 35 #endif /* _DMUB_DCN314_H_ */
+7 -4
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
··· 226 226 case DMUB_ASIC_DCN314: 227 227 case DMUB_ASIC_DCN315: 228 228 case DMUB_ASIC_DCN316: 229 - if (asic == DMUB_ASIC_DCN314) 229 + if (asic == DMUB_ASIC_DCN314) { 230 230 dmub->regs_dcn31 = &dmub_srv_dcn314_regs; 231 - else if (asic == DMUB_ASIC_DCN315) 231 + funcs->is_psrsu_supported = dmub_dcn314_is_psrsu_supported; 232 + } else if (asic == DMUB_ASIC_DCN315) { 232 233 dmub->regs_dcn31 = &dmub_srv_dcn315_regs; 233 - else if (asic == DMUB_ASIC_DCN316) 234 + } else if (asic == DMUB_ASIC_DCN316) { 234 235 dmub->regs_dcn31 = &dmub_srv_dcn316_regs; 235 - else 236 + } else { 236 237 dmub->regs_dcn31 = &dmub_srv_dcn31_regs; 238 + funcs->is_psrsu_supported = dmub_dcn31_is_psrsu_supported; 239 + } 237 240 funcs->reset = dmub_dcn31_reset; 238 241 funcs->reset_release = dmub_dcn31_reset_release; 239 242 funcs->backdoor_load = dmub_dcn31_backdoor_load;
+42 -39
drivers/gpu/drm/amd/pm/amdgpu_pm.c
··· 35 35 #include <linux/pm_runtime.h> 36 36 #include <asm/processor.h> 37 37 38 - static const struct cg_flag_name clocks[] = { 39 - {AMD_CG_SUPPORT_GFX_FGCG, "Graphics Fine Grain Clock Gating"}, 40 - {AMD_CG_SUPPORT_GFX_MGCG, "Graphics Medium Grain Clock Gating"}, 41 - {AMD_CG_SUPPORT_GFX_MGLS, "Graphics Medium Grain memory Light Sleep"}, 42 - {AMD_CG_SUPPORT_GFX_CGCG, "Graphics Coarse Grain Clock Gating"}, 43 - {AMD_CG_SUPPORT_GFX_CGLS, "Graphics Coarse Grain memory Light Sleep"}, 44 - {AMD_CG_SUPPORT_GFX_CGTS, "Graphics Coarse Grain Tree Shader Clock Gating"}, 45 - {AMD_CG_SUPPORT_GFX_CGTS_LS, "Graphics Coarse Grain Tree Shader Light Sleep"}, 46 - {AMD_CG_SUPPORT_GFX_CP_LS, "Graphics Command Processor Light Sleep"}, 47 - {AMD_CG_SUPPORT_GFX_RLC_LS, "Graphics Run List Controller Light Sleep"}, 48 - {AMD_CG_SUPPORT_GFX_3D_CGCG, "Graphics 3D Coarse Grain Clock Gating"}, 49 - {AMD_CG_SUPPORT_GFX_3D_CGLS, "Graphics 3D Coarse Grain memory Light Sleep"}, 50 - {AMD_CG_SUPPORT_MC_LS, "Memory Controller Light Sleep"}, 51 - {AMD_CG_SUPPORT_MC_MGCG, "Memory Controller Medium Grain Clock Gating"}, 52 - {AMD_CG_SUPPORT_SDMA_LS, "System Direct Memory Access Light Sleep"}, 53 - {AMD_CG_SUPPORT_SDMA_MGCG, "System Direct Memory Access Medium Grain Clock Gating"}, 54 - {AMD_CG_SUPPORT_BIF_MGCG, "Bus Interface Medium Grain Clock Gating"}, 55 - {AMD_CG_SUPPORT_BIF_LS, "Bus Interface Light Sleep"}, 56 - {AMD_CG_SUPPORT_UVD_MGCG, "Unified Video Decoder Medium Grain Clock Gating"}, 57 - {AMD_CG_SUPPORT_VCE_MGCG, "Video Compression Engine Medium Grain Clock Gating"}, 58 - {AMD_CG_SUPPORT_HDP_LS, "Host Data Path Light Sleep"}, 59 - {AMD_CG_SUPPORT_HDP_MGCG, "Host Data Path Medium Grain Clock Gating"}, 60 - {AMD_CG_SUPPORT_DRM_MGCG, "Digital Right Management Medium Grain Clock Gating"}, 61 - {AMD_CG_SUPPORT_DRM_LS, "Digital Right Management Light Sleep"}, 62 - {AMD_CG_SUPPORT_ROM_MGCG, "Rom Medium Grain Clock Gating"}, 63 - {AMD_CG_SUPPORT_DF_MGCG, "Data Fabric Medium Grain Clock Gating"}, 64 - {AMD_CG_SUPPORT_VCN_MGCG, "VCN Medium Grain Clock Gating"}, 65 - {AMD_CG_SUPPORT_HDP_DS, "Host Data Path Deep Sleep"}, 66 - {AMD_CG_SUPPORT_HDP_SD, "Host Data Path Shutdown"}, 67 - {AMD_CG_SUPPORT_IH_CG, "Interrupt Handler Clock Gating"}, 68 - {AMD_CG_SUPPORT_JPEG_MGCG, "JPEG Medium Grain Clock Gating"}, 69 - {AMD_CG_SUPPORT_REPEATER_FGCG, "Repeater Fine Grain Clock Gating"}, 70 - {AMD_CG_SUPPORT_GFX_PERF_CLK, "Perfmon Clock Gating"}, 71 - {AMD_CG_SUPPORT_ATHUB_MGCG, "Address Translation Hub Medium Grain Clock Gating"}, 72 - {AMD_CG_SUPPORT_ATHUB_LS, "Address Translation Hub Light Sleep"}, 73 - {0, NULL}, 74 - }; 75 - 76 38 static const struct hwmon_temp_label { 77 39 enum PP_HWMON_TEMP channel; 78 40 const char *label; ··· 2072 2110 case IP_VERSION(9, 4, 0): 2073 2111 case IP_VERSION(9, 4, 1): 2074 2112 case IP_VERSION(9, 4, 2): 2113 + case IP_VERSION(9, 4, 3): 2075 2114 case IP_VERSION(10, 3, 0): 2076 2115 case IP_VERSION(11, 0, 0): 2077 2116 case IP_VERSION(11, 0, 1): ··· 2083 2120 *states = ATTR_STATE_UNSUPPORTED; 2084 2121 } 2085 2122 } else if (DEVICE_ATTR_IS(pp_features)) { 2086 - if (adev->flags & AMD_IS_APU || gc_ver < IP_VERSION(9, 0, 0)) 2123 + if ((adev->flags & AMD_IS_APU && 2124 + gc_ver != IP_VERSION(9, 4, 3)) || 2125 + gc_ver < IP_VERSION(9, 0, 0)) 2087 2126 *states = ATTR_STATE_UNSUPPORTED; 2088 2127 } else if (DEVICE_ATTR_IS(gpu_metrics)) { 2089 2128 if (gc_ver < IP_VERSION(9, 1, 0)) ··· 3648 3683 3649 3684 return 0; 3650 3685 } 3686 + 3687 + static const struct cg_flag_name clocks[] = { 3688 + {AMD_CG_SUPPORT_GFX_FGCG, "Graphics Fine Grain Clock Gating"}, 3689 + {AMD_CG_SUPPORT_GFX_MGCG, "Graphics Medium Grain Clock Gating"}, 3690 + {AMD_CG_SUPPORT_GFX_MGLS, "Graphics Medium Grain memory Light Sleep"}, 3691 + {AMD_CG_SUPPORT_GFX_CGCG, "Graphics Coarse Grain Clock Gating"}, 3692 + {AMD_CG_SUPPORT_GFX_CGLS, "Graphics Coarse Grain memory Light Sleep"}, 3693 + {AMD_CG_SUPPORT_GFX_CGTS, "Graphics Coarse Grain Tree Shader Clock Gating"}, 3694 + {AMD_CG_SUPPORT_GFX_CGTS_LS, "Graphics Coarse Grain Tree Shader Light Sleep"}, 3695 + {AMD_CG_SUPPORT_GFX_CP_LS, "Graphics Command Processor Light Sleep"}, 3696 + {AMD_CG_SUPPORT_GFX_RLC_LS, "Graphics Run List Controller Light Sleep"}, 3697 + {AMD_CG_SUPPORT_GFX_3D_CGCG, "Graphics 3D Coarse Grain Clock Gating"}, 3698 + {AMD_CG_SUPPORT_GFX_3D_CGLS, "Graphics 3D Coarse Grain memory Light Sleep"}, 3699 + {AMD_CG_SUPPORT_MC_LS, "Memory Controller Light Sleep"}, 3700 + {AMD_CG_SUPPORT_MC_MGCG, "Memory Controller Medium Grain Clock Gating"}, 3701 + {AMD_CG_SUPPORT_SDMA_LS, "System Direct Memory Access Light Sleep"}, 3702 + {AMD_CG_SUPPORT_SDMA_MGCG, "System Direct Memory Access Medium Grain Clock Gating"}, 3703 + {AMD_CG_SUPPORT_BIF_MGCG, "Bus Interface Medium Grain Clock Gating"}, 3704 + {AMD_CG_SUPPORT_BIF_LS, "Bus Interface Light Sleep"}, 3705 + {AMD_CG_SUPPORT_UVD_MGCG, "Unified Video Decoder Medium Grain Clock Gating"}, 3706 + {AMD_CG_SUPPORT_VCE_MGCG, "Video Compression Engine Medium Grain Clock Gating"}, 3707 + {AMD_CG_SUPPORT_HDP_LS, "Host Data Path Light Sleep"}, 3708 + {AMD_CG_SUPPORT_HDP_MGCG, "Host Data Path Medium Grain Clock Gating"}, 3709 + {AMD_CG_SUPPORT_DRM_MGCG, "Digital Right Management Medium Grain Clock Gating"}, 3710 + {AMD_CG_SUPPORT_DRM_LS, "Digital Right Management Light Sleep"}, 3711 + {AMD_CG_SUPPORT_ROM_MGCG, "Rom Medium Grain Clock Gating"}, 3712 + {AMD_CG_SUPPORT_DF_MGCG, "Data Fabric Medium Grain Clock Gating"}, 3713 + {AMD_CG_SUPPORT_VCN_MGCG, "VCN Medium Grain Clock Gating"}, 3714 + {AMD_CG_SUPPORT_HDP_DS, "Host Data Path Deep Sleep"}, 3715 + {AMD_CG_SUPPORT_HDP_SD, "Host Data Path Shutdown"}, 3716 + {AMD_CG_SUPPORT_IH_CG, "Interrupt Handler Clock Gating"}, 3717 + {AMD_CG_SUPPORT_JPEG_MGCG, "JPEG Medium Grain Clock Gating"}, 3718 + {AMD_CG_SUPPORT_REPEATER_FGCG, "Repeater Fine Grain Clock Gating"}, 3719 + {AMD_CG_SUPPORT_GFX_PERF_CLK, "Perfmon Clock Gating"}, 3720 + {AMD_CG_SUPPORT_ATHUB_MGCG, "Address Translation Hub Medium Grain Clock Gating"}, 3721 + {AMD_CG_SUPPORT_ATHUB_LS, "Address Translation Hub Light Sleep"}, 3722 + {0, NULL}, 3723 + }; 3651 3724 3652 3725 static void amdgpu_parse_cg_state(struct seq_file *m, u64 flags) 3653 3726 {
+2
drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
··· 89 89 int max_mem_crit_temp; 90 90 /* memory max emergency(shutdown) temp */ 91 91 int max_mem_emergency_temp; 92 + /* SWCTF threshold */ 93 + int sw_ctf_threshold; 92 94 /* was last interrupt low to high or high to low */ 93 95 bool high_to_low; 94 96 /* interrupt source */
+48
drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
··· 26 26 #include <linux/gfp.h> 27 27 #include <linux/slab.h> 28 28 #include <linux/firmware.h> 29 + #include <linux/reboot.h> 29 30 #include "amd_shared.h" 30 31 #include "amd_powerplay.h" 31 32 #include "power_state.h" ··· 92 91 return 0; 93 92 } 94 93 94 + static void pp_swctf_delayed_work_handler(struct work_struct *work) 95 + { 96 + struct pp_hwmgr *hwmgr = 97 + container_of(work, struct pp_hwmgr, swctf_delayed_work.work); 98 + struct amdgpu_device *adev = hwmgr->adev; 99 + struct amdgpu_dpm_thermal *range = 100 + &adev->pm.dpm.thermal; 101 + uint32_t gpu_temperature, size; 102 + int ret; 103 + 104 + /* 105 + * If the hotspot/edge temperature is confirmed as below SW CTF setting point 106 + * after the delay enforced, nothing will be done. 107 + * Otherwise, a graceful shutdown will be performed to prevent further damage. 108 + */ 109 + if (range->sw_ctf_threshold && 110 + hwmgr->hwmgr_func->read_sensor) { 111 + ret = hwmgr->hwmgr_func->read_sensor(hwmgr, 112 + AMDGPU_PP_SENSOR_HOTSPOT_TEMP, 113 + &gpu_temperature, 114 + &size); 115 + /* 116 + * For some legacy ASICs, hotspot temperature retrieving might be not 117 + * supported. Check the edge temperature instead then. 118 + */ 119 + if (ret == -EOPNOTSUPP) 120 + ret = hwmgr->hwmgr_func->read_sensor(hwmgr, 121 + AMDGPU_PP_SENSOR_EDGE_TEMP, 122 + &gpu_temperature, 123 + &size); 124 + if (!ret && gpu_temperature / 1000 < range->sw_ctf_threshold) 125 + return; 126 + } 127 + 128 + dev_emerg(adev->dev, "ERROR: GPU over temperature range(SW CTF) detected!\n"); 129 + dev_emerg(adev->dev, "ERROR: System is going to shutdown due to GPU SW CTF!\n"); 130 + orderly_poweroff(true); 131 + } 132 + 95 133 static int pp_sw_init(void *handle) 96 134 { 97 135 struct amdgpu_device *adev = handle; ··· 140 100 ret = hwmgr_sw_init(hwmgr); 141 101 142 102 pr_debug("powerplay sw init %s\n", ret ? "failed" : "successfully"); 103 + 104 + if (!ret) 105 + INIT_DELAYED_WORK(&hwmgr->swctf_delayed_work, 106 + pp_swctf_delayed_work_handler); 143 107 144 108 return ret; 145 109 } ··· 178 134 { 179 135 struct amdgpu_device *adev = handle; 180 136 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 137 + 138 + cancel_delayed_work_sync(&hwmgr->swctf_delayed_work); 181 139 182 140 hwmgr_hw_fini(hwmgr); 183 141 ··· 266 220 { 267 221 struct amdgpu_device *adev = handle; 268 222 struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 223 + 224 + cancel_delayed_work_sync(&hwmgr->swctf_delayed_work); 269 225 270 226 return hwmgr_suspend(hwmgr); 271 227 }
+3 -1
drivers/gpu/drm/amd/pm/powerplay/hwmgr/hardwaremanager.c
··· 241 241 TEMP_RANGE_MAX, 242 242 TEMP_RANGE_MIN, 243 243 TEMP_RANGE_MAX, 244 - TEMP_RANGE_MAX}; 244 + TEMP_RANGE_MAX, 245 + 0}; 245 246 struct amdgpu_device *adev = hwmgr->adev; 246 247 247 248 if (!hwmgr->not_vf) ··· 266 265 adev->pm.dpm.thermal.min_mem_temp = range.mem_min; 267 266 adev->pm.dpm.thermal.max_mem_crit_temp = range.mem_crit_max; 268 267 adev->pm.dpm.thermal.max_mem_emergency_temp = range.mem_emergency_max; 268 + adev->pm.dpm.thermal.sw_ctf_threshold = range.sw_ctf_threshold; 269 269 270 270 return ret; 271 271 }
+2
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
··· 5432 5432 thermal_data->max = data->thermal_temp_setting.temperature_shutdown * 5433 5433 PP_TEMPERATURE_UNITS_PER_CENTIGRADES; 5434 5434 5435 + thermal_data->sw_ctf_threshold = thermal_data->max; 5436 + 5435 5437 return 0; 5436 5438 } 5437 5439
+9 -18
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c
··· 603 603 struct amdgpu_irq_src *source, 604 604 struct amdgpu_iv_entry *entry) 605 605 { 606 + struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; 606 607 uint32_t client_id = entry->client_id; 607 608 uint32_t src_id = entry->src_id; 608 609 609 610 if (client_id == AMDGPU_IRQ_CLIENTID_LEGACY) { 610 611 if (src_id == VISLANDS30_IV_SRCID_CG_TSS_THERMAL_LOW_TO_HIGH) { 611 - dev_emerg(adev->dev, "ERROR: GPU over temperature range(SW CTF) detected!\n"); 612 - /* 613 - * SW CTF just occurred. 614 - * Try to do a graceful shutdown to prevent further damage. 615 - */ 616 - dev_emerg(adev->dev, "ERROR: System is going to shutdown due to GPU SW CTF!\n"); 617 - orderly_poweroff(true); 618 - } else if (src_id == VISLANDS30_IV_SRCID_CG_TSS_THERMAL_HIGH_TO_LOW) 612 + schedule_delayed_work(&hwmgr->swctf_delayed_work, 613 + msecs_to_jiffies(AMDGPU_SWCTF_EXTRA_DELAY)); 614 + } else if (src_id == VISLANDS30_IV_SRCID_CG_TSS_THERMAL_HIGH_TO_LOW) { 619 615 dev_emerg(adev->dev, "ERROR: GPU under temperature range detected!\n"); 620 - else if (src_id == VISLANDS30_IV_SRCID_GPIO_19) { 616 + } else if (src_id == VISLANDS30_IV_SRCID_GPIO_19) { 621 617 dev_emerg(adev->dev, "ERROR: GPU HW Critical Temperature Fault(aka CTF) detected!\n"); 622 618 /* 623 619 * HW CTF just occurred. Shutdown to prevent further damage. ··· 622 626 orderly_poweroff(true); 623 627 } 624 628 } else if (client_id == SOC15_IH_CLIENTID_THM) { 625 - if (src_id == 0) { 626 - dev_emerg(adev->dev, "ERROR: GPU over temperature range(SW CTF) detected!\n"); 627 - /* 628 - * SW CTF just occurred. 629 - * Try to do a graceful shutdown to prevent further damage. 630 - */ 631 - dev_emerg(adev->dev, "ERROR: System is going to shutdown due to GPU SW CTF!\n"); 632 - orderly_poweroff(true); 633 - } else 629 + if (src_id == 0) 630 + schedule_delayed_work(&hwmgr->swctf_delayed_work, 631 + msecs_to_jiffies(AMDGPU_SWCTF_EXTRA_DELAY)); 632 + else 634 633 dev_emerg(adev->dev, "ERROR: GPU under temperature range detected!\n"); 635 634 } else if (client_id == SOC15_IH_CLIENTID_ROM_SMUIO) { 636 635 dev_emerg(adev->dev, "ERROR: GPU HW Critical Temperature Fault(aka CTF) detected!\n");
+10
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c
··· 5241 5241 { 5242 5242 struct vega10_hwmgr *data = hwmgr->backend; 5243 5243 PPTable_t *pp_table = &(data->smc_state_table.pp_table); 5244 + struct phm_ppt_v2_information *pp_table_info = 5245 + (struct phm_ppt_v2_information *)(hwmgr->pptable); 5246 + struct phm_tdp_table *tdp_table = pp_table_info->tdp_table; 5244 5247 5245 5248 memcpy(thermal_data, &SMU7ThermalWithDelayPolicy[0], sizeof(struct PP_TemperatureRange)); 5246 5249 ··· 5259 5256 PP_TEMPERATURE_UNITS_PER_CENTIGRADES; 5260 5257 thermal_data->mem_emergency_max = (pp_table->ThbmLimit + CTF_OFFSET_HBM)* 5261 5258 PP_TEMPERATURE_UNITS_PER_CENTIGRADES; 5259 + 5260 + if (tdp_table->usSoftwareShutdownTemp > pp_table->ThotspotLimit && 5261 + tdp_table->usSoftwareShutdownTemp < VEGA10_THERMAL_MAXIMUM_ALERT_TEMP) 5262 + thermal_data->sw_ctf_threshold = tdp_table->usSoftwareShutdownTemp; 5263 + else 5264 + thermal_data->sw_ctf_threshold = VEGA10_THERMAL_MAXIMUM_ALERT_TEMP; 5265 + thermal_data->sw_ctf_threshold *= PP_TEMPERATURE_UNITS_PER_CENTIGRADES; 5262 5266 5263 5267 return 0; 5264 5268 }
+4
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c
··· 2763 2763 static int vega12_get_thermal_temperature_range(struct pp_hwmgr *hwmgr, 2764 2764 struct PP_TemperatureRange *thermal_data) 2765 2765 { 2766 + struct phm_ppt_v3_information *pptable_information = 2767 + (struct phm_ppt_v3_information *)hwmgr->pptable; 2766 2768 struct vega12_hwmgr *data = 2767 2769 (struct vega12_hwmgr *)(hwmgr->backend); 2768 2770 PPTable_t *pp_table = &(data->smc_state_table.pp_table); ··· 2782 2780 thermal_data->mem_crit_max = pp_table->ThbmLimit * 2783 2781 PP_TEMPERATURE_UNITS_PER_CENTIGRADES; 2784 2782 thermal_data->mem_emergency_max = (pp_table->ThbmLimit + CTF_OFFSET_HBM)* 2783 + PP_TEMPERATURE_UNITS_PER_CENTIGRADES; 2784 + thermal_data->sw_ctf_threshold = pptable_information->us_software_shutdown_temp * 2785 2785 PP_TEMPERATURE_UNITS_PER_CENTIGRADES; 2786 2786 2787 2787 return 0;
+3 -1
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_thermal.c
··· 192 192 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1); 193 193 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, high); 194 194 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, low); 195 - val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK); 195 + val &= ~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK; 196 + val &= ~THM_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK; 197 + val &= ~THM_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK; 196 198 197 199 WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val); 198 200
+4
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
··· 4206 4206 static int vega20_get_thermal_temperature_range(struct pp_hwmgr *hwmgr, 4207 4207 struct PP_TemperatureRange *thermal_data) 4208 4208 { 4209 + struct phm_ppt_v3_information *pptable_information = 4210 + (struct phm_ppt_v3_information *)hwmgr->pptable; 4209 4211 struct vega20_hwmgr *data = 4210 4212 (struct vega20_hwmgr *)(hwmgr->backend); 4211 4213 PPTable_t *pp_table = &(data->smc_state_table.pp_table); ··· 4225 4223 thermal_data->mem_crit_max = pp_table->ThbmLimit * 4226 4224 PP_TEMPERATURE_UNITS_PER_CENTIGRADES; 4227 4225 thermal_data->mem_emergency_max = (pp_table->ThbmLimit + CTF_OFFSET_HBM)* 4226 + PP_TEMPERATURE_UNITS_PER_CENTIGRADES; 4227 + thermal_data->sw_ctf_threshold = pptable_information->us_software_shutdown_temp * 4228 4228 PP_TEMPERATURE_UNITS_PER_CENTIGRADES; 4229 4229 4230 4230 return 0;
+3 -1
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c
··· 263 263 val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1); 264 264 val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, high); 265 265 val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, low); 266 - val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK); 266 + val &= ~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK; 267 + val &= ~THM_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK; 268 + val &= ~THM_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK; 267 269 268 270 WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val); 269 271
+2
drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h
··· 811 811 bool gfxoff_state_changed_by_workload; 812 812 uint32_t pstate_sclk_peak; 813 813 uint32_t pstate_mclk_peak; 814 + 815 + struct delayed_work swctf_delayed_work; 814 816 }; 815 817 816 818 int hwmgr_early_init(struct pp_hwmgr *hwmgr);
+1
drivers/gpu/drm/amd/pm/powerplay/inc/power_state.h
··· 131 131 int mem_min; 132 132 int mem_crit_max; 133 133 int mem_emergency_max; 134 + int sw_ctf_threshold; 134 135 }; 135 136 136 137 struct PP_StateValidationBlock {
+34
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
··· 24 24 25 25 #include <linux/firmware.h> 26 26 #include <linux/pci.h> 27 + #include <linux/reboot.h> 27 28 28 29 #include "amdgpu.h" 29 30 #include "amdgpu_smu.h" ··· 1079 1078 smu->ppt_funcs->interrupt_work(smu); 1080 1079 } 1081 1080 1081 + static void smu_swctf_delayed_work_handler(struct work_struct *work) 1082 + { 1083 + struct smu_context *smu = 1084 + container_of(work, struct smu_context, swctf_delayed_work.work); 1085 + struct smu_temperature_range *range = 1086 + &smu->thermal_range; 1087 + struct amdgpu_device *adev = smu->adev; 1088 + uint32_t hotspot_tmp, size; 1089 + 1090 + /* 1091 + * If the hotspot temperature is confirmed as below SW CTF setting point 1092 + * after the delay enforced, nothing will be done. 1093 + * Otherwise, a graceful shutdown will be performed to prevent further damage. 1094 + */ 1095 + if (range->software_shutdown_temp && 1096 + smu->ppt_funcs->read_sensor && 1097 + !smu->ppt_funcs->read_sensor(smu, 1098 + AMDGPU_PP_SENSOR_HOTSPOT_TEMP, 1099 + &hotspot_tmp, 1100 + &size) && 1101 + hotspot_tmp / 1000 < range->software_shutdown_temp) 1102 + return; 1103 + 1104 + dev_emerg(adev->dev, "ERROR: GPU over temperature range(SW CTF) detected!\n"); 1105 + dev_emerg(adev->dev, "ERROR: System is going to shutdown due to GPU SW CTF!\n"); 1106 + orderly_poweroff(true); 1107 + } 1108 + 1082 1109 static int smu_sw_init(void *handle) 1083 1110 { 1084 1111 struct amdgpu_device *adev = (struct amdgpu_device *)handle; ··· 1148 1119 1149 1120 smu->smu_dpm.dpm_level = AMD_DPM_FORCED_LEVEL_AUTO; 1150 1121 smu->smu_dpm.requested_dpm_level = AMD_DPM_FORCED_LEVEL_AUTO; 1122 + 1123 + INIT_DELAYED_WORK(&smu->swctf_delayed_work, 1124 + smu_swctf_delayed_work_handler); 1151 1125 1152 1126 ret = smu_smc_table_sw_init(smu); 1153 1127 if (ret) { ··· 1631 1599 dev_err(adev->dev, "Fail to disable thermal alert!\n"); 1632 1600 return ret; 1633 1601 } 1602 + 1603 + cancel_delayed_work_sync(&smu->swctf_delayed_work); 1634 1604 1635 1605 ret = smu_disable_dpms(smu); 1636 1606 if (ret) {
+2
drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
··· 573 573 u32 debug_param_reg; 574 574 u32 debug_msg_reg; 575 575 u32 debug_resp_reg; 576 + 577 + struct delayed_work swctf_delayed_work; 576 578 }; 577 579 578 580 struct i2c_adapter;
+5 -5
drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
··· 1654 1654 enum smu_clk_type clk_type, uint32_t mask) 1655 1655 { 1656 1656 1657 - int ret = 0, size = 0; 1657 + int ret = 0; 1658 1658 uint32_t soft_min_level = 0, soft_max_level = 0, min_freq = 0, max_freq = 0; 1659 1659 1660 1660 soft_min_level = mask ? (ffs(mask) - 1) : 0; ··· 1675 1675 1676 1676 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, soft_min_level, &min_freq); 1677 1677 if (ret) 1678 - return size; 1678 + return 0; 1679 1679 1680 1680 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, soft_max_level, &max_freq); 1681 1681 if (ret) 1682 - return size; 1682 + return 0; 1683 1683 1684 1684 ret = smu_v11_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq); 1685 1685 if (ret) 1686 - return size; 1686 + return 0; 1687 1687 break; 1688 1688 case SMU_DCEFCLK: 1689 1689 dev_info(smu->adev->dev,"Setting DCEFCLK min/max dpm level is not supported!\n"); ··· 1693 1693 break; 1694 1694 } 1695 1695 1696 - return size; 1696 + return 0; 1697 1697 } 1698 1698 1699 1699 static int navi10_populate_umd_state_clk(struct smu_context *smu)
+2 -7
drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
··· 1412 1412 if (client_id == SOC15_IH_CLIENTID_THM) { 1413 1413 switch (src_id) { 1414 1414 case THM_11_0__SRCID__THM_DIG_THERM_L2H: 1415 - dev_emerg(adev->dev, "ERROR: GPU over temperature range(SW CTF) detected!\n"); 1416 - /* 1417 - * SW CTF just occurred. 1418 - * Try to do a graceful shutdown to prevent further damage. 1419 - */ 1420 - dev_emerg(adev->dev, "ERROR: System is going to shutdown due to GPU SW CTF!\n"); 1421 - orderly_poweroff(true); 1415 + schedule_delayed_work(&smu->swctf_delayed_work, 1416 + msecs_to_jiffies(AMDGPU_SWCTF_EXTRA_DELAY)); 1422 1417 break; 1423 1418 case THM_11_0__SRCID__THM_DIG_THERM_H2L: 1424 1419 dev_emerg(adev->dev, "ERROR: GPU under temperature range detected\n");
+2 -7
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
··· 1353 1353 if (client_id == SOC15_IH_CLIENTID_THM) { 1354 1354 switch (src_id) { 1355 1355 case THM_11_0__SRCID__THM_DIG_THERM_L2H: 1356 - dev_emerg(adev->dev, "ERROR: GPU over temperature range(SW CTF) detected!\n"); 1357 - /* 1358 - * SW CTF just occurred. 1359 - * Try to do a graceful shutdown to prevent further damage. 1360 - */ 1361 - dev_emerg(adev->dev, "ERROR: System is going to shutdown due to GPU SW CTF!\n"); 1362 - orderly_poweroff(true); 1356 + schedule_delayed_work(&smu->swctf_delayed_work, 1357 + msecs_to_jiffies(AMDGPU_SWCTF_EXTRA_DELAY)); 1363 1358 break; 1364 1359 case THM_11_0__SRCID__THM_DIG_THERM_H2L: 1365 1360 dev_emerg(adev->dev, "ERROR: GPU under temperature range detected\n");
+1
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
··· 1710 1710 range->mem_emergency_max = (pptable->SkuTable.TemperatureLimit[TEMP_MEM] + CTF_OFFSET_MEM)* 1711 1711 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 1712 1712 range->software_shutdown_temp = powerplay_table->software_shutdown_temp; 1713 + range->software_shutdown_temp_offset = pptable->SkuTable.FanAbnormalTempLimitOffset; 1713 1714 1714 1715 return 0; 1715 1716 }
+2 -2
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
··· 200 200 }; 201 201 202 202 #define SMUQ10_TO_UINT(x) ((x) >> 10) 203 - #define SMUQ16_TO_UINT(x) ((x) >> 16) 204 203 205 204 struct smu_v13_0_6_dpm_map { 206 205 enum smu_clk_type clk_type; ··· 1993 1994 1994 1995 gpu_metrics->average_socket_power = 1995 1996 SMUQ10_TO_UINT(metrics->SocketPower); 1997 + /* Energy is reported in 15.625mJ units */ 1996 1998 gpu_metrics->energy_accumulator = 1997 - SMUQ16_TO_UINT(metrics->SocketEnergyAcc); 1999 + SMUQ10_TO_UINT(metrics->SocketEnergyAcc); 1998 2000 1999 2001 gpu_metrics->current_gfxclk = 2000 2002 SMUQ10_TO_UINT(metrics->GfxclkFrequency[xcc0]);